29 using System.Collections.Generic;
32 using OpenSim.Framework;
34 namespace OpenSim.
Region.PhysicsModule.BulletS
39 public const float Infinite = 12345.6f;
48 public virtual bool Enabled {
get; set; }
50 public virtual void Zero() { }
54 public string UseName {
get;
private set; }
58 protected void MDetailLog(
string msg, params Object[] parms)
60 if (PhysicsScene != null)
62 PhysicsScene.DetailLog(msg, parms);
87 public virtual float TimeScale {
get; set; }
88 public virtual float TargetValueDecayTimeScale {
get; set; }
89 public virtual float Efficiency {
get; set; }
91 public virtual float ErrorZeroThreshold {
get; set; }
93 public virtual Vector3 TargetValue {
get;
protected set; }
94 public virtual Vector3 CurrentValue {
get;
protected set; }
95 public virtual Vector3 LastError {
get;
protected set; }
99 return ErrorIsZero(LastError);
103 return (err == Vector3.Zero || err.ApproxEquals(Vector3.Zero, ErrorZeroThreshold));
109 TimeScale = TargetValueDecayTimeScale = BSMotor.Infinite;
111 CurrentValue = TargetValue = Vector3.Zero;
112 ErrorZeroThreshold = 0.001f;
114 public BSVMotor(
string useName,
float timeScale,
float decayTimeScale,
float efficiency)
117 TimeScale = timeScale;
118 TargetValueDecayTimeScale = decayTimeScale;
119 Efficiency = efficiency;
120 CurrentValue = TargetValue = Vector3.Zero;
124 CurrentValue = current;
128 TargetValue = target;
133 CurrentValue = TargetValue = Vector3.Zero;
138 public virtual Vector3
Step(
float timeStep)
140 if (!Enabled)
return TargetValue;
142 Vector3 origTarget = TargetValue;
143 Vector3 origCurrVal = CurrentValue;
145 Vector3 correction = Vector3.Zero;
146 Vector3 error = TargetValue - CurrentValue;
147 if (!ErrorIsZero(error))
149 correction = StepError(timeStep, error);
151 CurrentValue += correction;
155 float decayFactor = 0f;
158 decayFactor = (1.0f / TargetValueDecayTimeScale) * timeStep;
159 TargetValue *= (1f - decayFactor);
162 MDetailLog(
"{0}, BSVMotor.Step,nonZero,{1},origCurr={2},origTarget={3},timeStep={4},err={5},corr={6}",
164 timeStep, error, correction);
165 MDetailLog(
"{0}, BSVMotor.Step,nonZero,{1},tgtDecayTS={2},decayFact={3},tgt={4},curr={5}",
166 BSScene.
DetailLogZero, UseName, TargetValueDecayTimeScale, decayFactor, TargetValue, CurrentValue);
171 if (TargetValue.ApproxEquals(Vector3.Zero, ErrorZeroThreshold))
175 TargetValue = Vector3.Zero;
177 CurrentValue = TargetValue;
178 MDetailLog(
"{0}, BSVMotor.Step,zero,{1},origTgt={2},origCurr={3},currTgt={4},currCurr={5}",
186 public virtual Vector3
Step(
float timeStep, Vector3 current)
188 CurrentValue = current;
189 return Step(timeStep);
193 public virtual Vector3
StepError(
float timeStep, Vector3 error)
195 if (!Enabled)
return Vector3.Zero;
197 Vector3 returnCorrection = Vector3.Zero;
198 if (!ErrorIsZero(error))
201 Vector3 correctionAmount;
203 correctionAmount = error * timeStep;
205 correctionAmount = error / TimeScale * timeStep;
207 returnCorrection = correctionAmount;
208 MDetailLog(
"{0}, BSVMotor.Step,nonZero,{1},timeStep={2},timeScale={3},err={4},corr={5}",
211 return returnCorrection;
219 MDetailLog(
"{0},BSVMotor.Test,{1},===================================== BEGIN Test Output",
BSScene.
DetailLogZero, UseName);
220 MDetailLog(
"{0},BSVMotor.Test,{1},timeScale={2},targDlyTS={3},eff={4},curr={5},tgt={6}",
222 TimeScale, TargetValueDecayTimeScale, Efficiency,
223 CurrentValue, TargetValue);
225 LastError = BSMotor.InfiniteVector;
226 while (maxOutput-- > 0 && !ErrorIsZero())
228 Vector3 lastStep = Step(timeStep);
229 MDetailLog(
"{0},BSVMotor.Test,{1},cur={2},tgt={3},lastError={4},lastStep={5}",
232 MDetailLog(
"{0},BSVMotor.Test,{1},===================================== END Test Output",
BSScene.
DetailLogZero, UseName);
239 return String.Format(
"<{0},curr={1},targ={2},lastErr={3},decayTS={4}>",
240 UseName, CurrentValue, TargetValue, LastError, TargetValueDecayTimeScale);
248 public virtual float TimeScale {
get; set; }
249 public virtual float TargetValueDecayTimeScale {
get; set; }
250 public virtual float Efficiency {
get; set; }
252 public virtual float ErrorZeroThreshold {
get; set; }
254 public virtual float TargetValue {
get;
protected set; }
255 public virtual float CurrentValue {
get;
protected set; }
256 public virtual float LastError {
get;
protected set; }
260 return ErrorIsZero(LastError);
264 return (err >= -ErrorZeroThreshold && err <= ErrorZeroThreshold);
267 public BSFMotor(
string useName,
float timeScale,
float decayTimescale,
float efficiency)
270 TimeScale = TargetValueDecayTimeScale = BSMotor.Infinite;
272 CurrentValue = TargetValue = 0f;
273 ErrorZeroThreshold = 0.01f;
277 CurrentValue = current;
281 TargetValue = target;
286 CurrentValue = TargetValue = 0f;
289 public virtual float Step(
float timeStep)
291 if (!Enabled)
return TargetValue;
293 float origTarget = TargetValue;
294 float origCurrVal = CurrentValue;
296 float correction = 0f;
297 float error = TargetValue - CurrentValue;
298 if (!ErrorIsZero(error))
300 correction = StepError(timeStep, error);
302 CurrentValue += correction;
306 float decayFactor = 0f;
309 decayFactor = (1.0f / TargetValueDecayTimeScale) * timeStep;
310 TargetValue *= (1f - decayFactor);
313 MDetailLog(
"{0}, BSFMotor.Step,nonZero,{1},origCurr={2},origTarget={3},timeStep={4},err={5},corr={6}",
315 timeStep, error, correction);
316 MDetailLog(
"{0}, BSFMotor.Step,nonZero,{1},tgtDecayTS={2},decayFact={3},tgt={4},curr={5}",
317 BSScene.
DetailLogZero, UseName, TargetValueDecayTimeScale, decayFactor, TargetValue, CurrentValue);
322 if (Util.InRange<
float>(TargetValue, -ErrorZeroThreshold, ErrorZeroThreshold))
328 CurrentValue = TargetValue;
329 MDetailLog(
"{0}, BSFMotor.Step,zero,{1},origTgt={2},origCurr={3},ret={4}",
337 public virtual float StepError(
float timeStep,
float error)
339 if (!Enabled)
return 0f;
341 float returnCorrection = 0f;
342 if (!ErrorIsZero(error))
345 float correctionAmount;
347 correctionAmount = error * timeStep;
349 correctionAmount = error / TimeScale * timeStep;
351 returnCorrection = correctionAmount;
352 MDetailLog(
"{0}, BSFMotor.Step,nonZero,{1},timeStep={2},timeScale={3},err={4},corr={5}",
355 return returnCorrection;
360 return String.Format(
"<{0},curr={1},targ={2},lastErr={3},decayTS={4}>",
361 UseName, CurrentValue, TargetValue, LastError, TargetValueDecayTimeScale);
373 public Vector3 proportionFactor {
get; set; }
374 public Vector3 integralFactor {
get; set; }
375 public Vector3 derivFactor {
get; set; }
384 public float EfficiencyHigh = 0.4f;
385 public float EfficiencyLow = 4.0f;
388 Vector3 RunningIntegration {
get; set; }
393 proportionFactor =
new Vector3(1.00f, 1.00f, 1.00f);
394 integralFactor =
new Vector3(1.00f, 1.00f, 1.00f);
395 derivFactor =
new Vector3(1.00f, 1.00f, 1.00f);
396 FactorMix =
new Vector3(0.5f, 0.25f, 0.25f);
397 RunningIntegration = Vector3.Zero;
398 LastError = Vector3.Zero;
406 public override float Efficiency
408 get {
return base.Efficiency; }
411 base.Efficiency = Util.Clamp(value, 0f, 1f);
418 float factor = (1f - this.Efficiency) * EfficiencyHigh + EfficiencyLow;
420 proportionFactor =
new Vector3(factor, factor, factor);
421 integralFactor =
new Vector3(factor, factor, factor);
422 derivFactor =
new Vector3(factor, factor, factor);
424 MDetailLog(
"{0}, BSPIDVMotor.setEfficiency,eff={1},factor={2}",
BSScene.
DetailLogZero, Efficiency, factor);
429 public override Vector3
StepError(
float timeStep, Vector3 error)
431 if (!Enabled)
return Vector3.Zero;
434 RunningIntegration += error * timeStep;
437 Vector3 derivitive = (error - LastError) * timeStep;
440 Vector3 ret = error / TimeScale * timeStep * proportionFactor * FactorMix.X
441 + RunningIntegration / TimeScale * integralFactor * FactorMix.Y
442 + derivitive / TimeScale * derivFactor * FactorMix.Z
445 MDetailLog(
"{0}, BSPIDVMotor.step,ts={1},err={2},lerr={3},runnInt={4},deriv={5},ret={6}",
void SetTarget(float target)
virtual bool ErrorIsZero(float err)
virtual float Step(float timeStep)
virtual float StepError(float timeStep, float error)
virtual Vector3 Step(float timeStep, Vector3 current)
virtual bool ErrorIsZero(Vector3 err)
virtual Vector3 Step(float timeStep)
override void GenerateTestOutput(float timeStep)
void SetCurrent(Vector3 current)
void MDetailLog(string msg, params Object[] parms)
virtual bool ErrorIsZero()
virtual void GenerateTestOutput(float timeStep)
override string ToString()
override Vector3 StepError(float timeStep, Vector3 error)
BSFMotor(string useName, float timeScale, float decayTimescale, float efficiency)
BSPIDVMotor(string useName)
void SetCurrent(float current)
virtual bool ErrorIsZero()
virtual Vector3 StepError(float timeStep, Vector3 error)
const string DetailLogZero
BSVMotor(string useName, float timeScale, float decayTimeScale, float efficiency)
void SetTarget(Vector3 target)
override string ToString()