aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region/PhysicsModules/BulletS/BSMotors.cs
diff options
context:
space:
mode:
authorDavid Walter Seikel2016-11-03 21:44:39 +1000
committerDavid Walter Seikel2016-11-03 21:44:39 +1000
commit134f86e8d5c414409631b25b8c6f0ee45fbd8631 (patch)
tree216b89d3fb89acfb81be1e440c25c41ab09fa96d /OpenSim/Region/PhysicsModules/BulletS/BSMotors.cs
parentMore changing to production grid. Double oops. (diff)
downloadopensim-SC_OLD-134f86e8d5c414409631b25b8c6f0ee45fbd8631.zip
opensim-SC_OLD-134f86e8d5c414409631b25b8c6f0ee45fbd8631.tar.gz
opensim-SC_OLD-134f86e8d5c414409631b25b8c6f0ee45fbd8631.tar.bz2
opensim-SC_OLD-134f86e8d5c414409631b25b8c6f0ee45fbd8631.tar.xz
Initial update to OpenSim 0.8.2.1 source code.
Diffstat (limited to '')
-rwxr-xr-xOpenSim/Region/PhysicsModules/BulletS/BSMotors.cs (renamed from OpenSim/Region/Physics/BulletSPlugin/BSMotors.cs)246
1 files changed, 175 insertions, 71 deletions
diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSMotors.cs b/OpenSim/Region/PhysicsModules/BulletS/BSMotors.cs
index 817a5f7..2faf2d4 100755
--- a/OpenSim/Region/Physics/BulletSPlugin/BSMotors.cs
+++ b/OpenSim/Region/PhysicsModules/BulletS/BSMotors.cs
@@ -31,7 +31,7 @@ using System.Text;
31using OpenMetaverse; 31using OpenMetaverse;
32using OpenSim.Framework; 32using OpenSim.Framework;
33 33
34namespace OpenSim.Region.Physics.BulletSPlugin 34namespace OpenSim.Region.PhysicsModule.BulletS
35{ 35{
36public abstract class BSMotor 36public abstract class BSMotor
37{ 37{
@@ -59,22 +59,17 @@ public abstract class BSMotor
59 { 59 {
60 if (PhysicsScene != null) 60 if (PhysicsScene != null)
61 { 61 {
62 if (PhysicsScene.VehicleLoggingEnabled) 62 PhysicsScene.DetailLog(msg, parms);
63 {
64 PhysicsScene.DetailLog(msg, parms);
65 }
66 } 63 }
67 } 64 }
68} 65}
69 66
70// Motor which moves CurrentValue to TargetValue over TimeScale seconds. 67// Motor which moves CurrentValue to TargetValue over TimeScale seconds.
71// The TargetValue decays in TargetValueDecayTimeScale and 68// The TargetValue decays in TargetValueDecayTimeScale.
72// the CurrentValue will be held back by FrictionTimeScale.
73// This motor will "zero itself" over time in that the targetValue will 69// This motor will "zero itself" over time in that the targetValue will
74// decay to zero and the currentValue will follow it to that zero. 70// decay to zero and the currentValue will follow it to that zero.
75// The overall effect is for the returned correction value to go from large 71// The overall effect is for the returned correction value to go from large
76// values (the total difference between current and target minus friction) 72// values to small and eventually zero values.
77// to small and eventually zero values.
78// TimeScale and TargetDelayTimeScale may be 'infinite' which means no decay. 73// TimeScale and TargetDelayTimeScale may be 'infinite' which means no decay.
79 74
80// For instance, if something is moving at speed X and the desired speed is Y, 75// For instance, if something is moving at speed X and the desired speed is Y,
@@ -91,7 +86,6 @@ public class BSVMotor : BSMotor
91 86
92 public virtual float TimeScale { get; set; } 87 public virtual float TimeScale { get; set; }
93 public virtual float TargetValueDecayTimeScale { get; set; } 88 public virtual float TargetValueDecayTimeScale { get; set; }
94 public virtual Vector3 FrictionTimescale { get; set; }
95 public virtual float Efficiency { get; set; } 89 public virtual float Efficiency { get; set; }
96 90
97 public virtual float ErrorZeroThreshold { get; set; } 91 public virtual float ErrorZeroThreshold { get; set; }
@@ -100,10 +94,13 @@ public class BSVMotor : BSMotor
100 public virtual Vector3 CurrentValue { get; protected set; } 94 public virtual Vector3 CurrentValue { get; protected set; }
101 public virtual Vector3 LastError { get; protected set; } 95 public virtual Vector3 LastError { get; protected set; }
102 96
103 public virtual bool ErrorIsZero 97 public virtual bool ErrorIsZero()
104 { get { 98 {
105 return (LastError == Vector3.Zero || LastError.LengthSquared() <= ErrorZeroThreshold); 99 return ErrorIsZero(LastError);
106 } 100 }
101 public virtual bool ErrorIsZero(Vector3 err)
102 {
103 return (err == Vector3.Zero || err.ApproxEquals(Vector3.Zero, ErrorZeroThreshold));
107 } 104 }
108 105
109 public BSVMotor(string useName) 106 public BSVMotor(string useName)
@@ -111,16 +108,14 @@ public class BSVMotor : BSMotor
111 { 108 {
112 TimeScale = TargetValueDecayTimeScale = BSMotor.Infinite; 109 TimeScale = TargetValueDecayTimeScale = BSMotor.Infinite;
113 Efficiency = 1f; 110 Efficiency = 1f;
114 FrictionTimescale = BSMotor.InfiniteVector;
115 CurrentValue = TargetValue = Vector3.Zero; 111 CurrentValue = TargetValue = Vector3.Zero;
116 ErrorZeroThreshold = 0.001f; 112 ErrorZeroThreshold = 0.001f;
117 } 113 }
118 public BSVMotor(string useName, float timeScale, float decayTimeScale, Vector3 frictionTimeScale, float efficiency) 114 public BSVMotor(string useName, float timeScale, float decayTimeScale, float efficiency)
119 : this(useName) 115 : this(useName)
120 { 116 {
121 TimeScale = timeScale; 117 TimeScale = timeScale;
122 TargetValueDecayTimeScale = decayTimeScale; 118 TargetValueDecayTimeScale = decayTimeScale;
123 FrictionTimescale = frictionTimeScale;
124 Efficiency = efficiency; 119 Efficiency = efficiency;
125 CurrentValue = TargetValue = Vector3.Zero; 120 CurrentValue = TargetValue = Vector3.Zero;
126 } 121 }
@@ -138,7 +133,8 @@ public class BSVMotor : BSMotor
138 CurrentValue = TargetValue = Vector3.Zero; 133 CurrentValue = TargetValue = Vector3.Zero;
139 } 134 }
140 135
141 // Compute the next step and return the new current value 136 // Compute the next step and return the new current value.
137 // Returns the correction needed to move 'current' to 'target'.
142 public virtual Vector3 Step(float timeStep) 138 public virtual Vector3 Step(float timeStep)
143 { 139 {
144 if (!Enabled) return TargetValue; 140 if (!Enabled) return TargetValue;
@@ -148,9 +144,9 @@ public class BSVMotor : BSMotor
148 144
149 Vector3 correction = Vector3.Zero; 145 Vector3 correction = Vector3.Zero;
150 Vector3 error = TargetValue - CurrentValue; 146 Vector3 error = TargetValue - CurrentValue;
151 if (!error.ApproxEquals(Vector3.Zero, ErrorZeroThreshold)) 147 if (!ErrorIsZero(error))
152 { 148 {
153 correction = Step(timeStep, error); 149 correction = StepError(timeStep, error);
154 150
155 CurrentValue += correction; 151 CurrentValue += correction;
156 152
@@ -163,44 +159,43 @@ public class BSVMotor : BSMotor
163 TargetValue *= (1f - decayFactor); 159 TargetValue *= (1f - decayFactor);
164 } 160 }
165 161
166 // The amount we can correct the error is reduced by the friction
167 Vector3 frictionFactor = Vector3.Zero;
168 if (FrictionTimescale != BSMotor.InfiniteVector)
169 {
170 // frictionFactor = (Vector3.One / FrictionTimescale) * timeStep;
171 // Individual friction components can be 'infinite' so compute each separately.
172 frictionFactor.X = (FrictionTimescale.X == BSMotor.Infinite) ? 0f : (1f / FrictionTimescale.X);
173 frictionFactor.Y = (FrictionTimescale.Y == BSMotor.Infinite) ? 0f : (1f / FrictionTimescale.Y);
174 frictionFactor.Z = (FrictionTimescale.Z == BSMotor.Infinite) ? 0f : (1f / FrictionTimescale.Z);
175 frictionFactor *= timeStep;
176 CurrentValue *= (Vector3.One - frictionFactor);
177 }
178
179 MDetailLog("{0}, BSVMotor.Step,nonZero,{1},origCurr={2},origTarget={3},timeStep={4},err={5},corr={6}", 162 MDetailLog("{0}, BSVMotor.Step,nonZero,{1},origCurr={2},origTarget={3},timeStep={4},err={5},corr={6}",
180 BSScene.DetailLogZero, UseName, origCurrVal, origTarget, 163 BSScene.DetailLogZero, UseName, origCurrVal, origTarget,
181 timeStep, error, correction); 164 timeStep, error, correction);
182 MDetailLog("{0}, BSVMotor.Step,nonZero,{1},tgtDecayTS={2},decayFact={3},frictTS={4},frictFact={5},tgt={6},curr={7}", 165 MDetailLog("{0}, BSVMotor.Step,nonZero,{1},tgtDecayTS={2},decayFact={3},tgt={4},curr={5}",
183 BSScene.DetailLogZero, UseName, 166 BSScene.DetailLogZero, UseName, TargetValueDecayTimeScale, decayFactor, TargetValue, CurrentValue);
184 TargetValueDecayTimeScale, decayFactor, FrictionTimescale, frictionFactor,
185 TargetValue, CurrentValue);
186 } 167 }
187 else 168 else
188 { 169 {
189 // Difference between what we have and target is small. Motor is done. 170 // Difference between what we have and target is small. Motor is done.
171 if (TargetValue.ApproxEquals(Vector3.Zero, ErrorZeroThreshold))
172 {
173 // The target can step down to nearly zero but not get there. If close to zero
174 // it is really zero.
175 TargetValue = Vector3.Zero;
176 }
190 CurrentValue = TargetValue; 177 CurrentValue = TargetValue;
191 MDetailLog("{0}, BSVMotor.Step,zero,{1},origTgt={2},origCurr={3},ret={4}", 178 MDetailLog("{0}, BSVMotor.Step,zero,{1},origTgt={2},origCurr={3},currTgt={4},currCurr={5}",
192 BSScene.DetailLogZero, UseName, origCurrVal, origTarget, CurrentValue); 179 BSScene.DetailLogZero, UseName, origCurrVal, origTarget, TargetValue, CurrentValue);
193 } 180 }
181 LastError = error;
194 182
195 return CurrentValue; 183 return correction;
184 }
185 // version of step that sets the current value before doing the step
186 public virtual Vector3 Step(float timeStep, Vector3 current)
187 {
188 CurrentValue = current;
189 return Step(timeStep);
196 } 190 }
197 public virtual Vector3 Step(float timeStep, Vector3 error) 191 // Given and error, computer a correction for this step.
192 // Simple scaling of the error by the timestep.
193 public virtual Vector3 StepError(float timeStep, Vector3 error)
198 { 194 {
199 if (!Enabled) return Vector3.Zero; 195 if (!Enabled) return Vector3.Zero;
200 196
201 LastError = error;
202 Vector3 returnCorrection = Vector3.Zero; 197 Vector3 returnCorrection = Vector3.Zero;
203 if (!error.ApproxEquals(Vector3.Zero, ErrorZeroThreshold)) 198 if (!ErrorIsZero(error))
204 { 199 {
205 // correction = error / secondsItShouldTakeToCorrect 200 // correction = error / secondsItShouldTakeToCorrect
206 Vector3 correctionAmount; 201 Vector3 correctionAmount;
@@ -222,57 +217,155 @@ public class BSVMotor : BSMotor
222 // maximum number of outputs to generate. 217 // maximum number of outputs to generate.
223 int maxOutput = 50; 218 int maxOutput = 50;
224 MDetailLog("{0},BSVMotor.Test,{1},===================================== BEGIN Test Output", BSScene.DetailLogZero, UseName); 219 MDetailLog("{0},BSVMotor.Test,{1},===================================== BEGIN Test Output", BSScene.DetailLogZero, UseName);
225 MDetailLog("{0},BSVMotor.Test,{1},timeScale={2},targDlyTS={3},frictTS={4},eff={5},curr={6},tgt={7}", 220 MDetailLog("{0},BSVMotor.Test,{1},timeScale={2},targDlyTS={3},eff={4},curr={5},tgt={6}",
226 BSScene.DetailLogZero, UseName, 221 BSScene.DetailLogZero, UseName,
227 TimeScale, TargetValueDecayTimeScale, FrictionTimescale, Efficiency, 222 TimeScale, TargetValueDecayTimeScale, Efficiency,
228 CurrentValue, TargetValue); 223 CurrentValue, TargetValue);
229 224
230 LastError = BSMotor.InfiniteVector; 225 LastError = BSMotor.InfiniteVector;
231 while (maxOutput-- > 0 && !LastError.ApproxEquals(Vector3.Zero, ErrorZeroThreshold)) 226 while (maxOutput-- > 0 && !ErrorIsZero())
232 { 227 {
233 Vector3 lastStep = Step(timeStep); 228 Vector3 lastStep = Step(timeStep);
234 MDetailLog("{0},BSVMotor.Test,{1},cur={2},tgt={3},lastError={4},lastStep={5}", 229 MDetailLog("{0},BSVMotor.Test,{1},cur={2},tgt={3},lastError={4},lastStep={5}",
235 BSScene.DetailLogZero, UseName, CurrentValue, TargetValue, LastError, lastStep); 230 BSScene.DetailLogZero, UseName, CurrentValue, TargetValue, LastError, lastStep);
236 } 231 }
237 MDetailLog("{0},BSVMotor.Test,{1},===================================== END Test Output", BSScene.DetailLogZero, UseName); 232 MDetailLog("{0},BSVMotor.Test,{1},===================================== END Test Output", BSScene.DetailLogZero, UseName);
238 233
239 234
240 } 235 }
241 236
242 public override string ToString() 237 public override string ToString()
243 { 238 {
244 return String.Format("<{0},curr={1},targ={2},lastErr={3},decayTS={4},frictTS={5}>", 239 return String.Format("<{0},curr={1},targ={2},lastErr={3},decayTS={4}>",
245 UseName, CurrentValue, TargetValue, LastError, TargetValueDecayTimeScale, FrictionTimescale); 240 UseName, CurrentValue, TargetValue, LastError, TargetValueDecayTimeScale);
246 } 241 }
247} 242}
248 243
244// ============================================================================
245// ============================================================================
249public class BSFMotor : BSMotor 246public class BSFMotor : BSMotor
250{ 247{
251 public float TimeScale { get; set; } 248 public virtual float TimeScale { get; set; }
252 public float DecayTimeScale { get; set; } 249 public virtual float TargetValueDecayTimeScale { get; set; }
253 public float Friction { get; set; } 250 public virtual float Efficiency { get; set; }
254 public float Efficiency { get; set; } 251
252 public virtual float ErrorZeroThreshold { get; set; }
253
254 public virtual float TargetValue { get; protected set; }
255 public virtual float CurrentValue { get; protected set; }
256 public virtual float LastError { get; protected set; }
255 257
256 public float Target { get; private set; } 258 public virtual bool ErrorIsZero()
257 public float CurrentValue { get; private set; } 259 {
260 return ErrorIsZero(LastError);
261 }
262 public virtual bool ErrorIsZero(float err)
263 {
264 return (err >= -ErrorZeroThreshold && err <= ErrorZeroThreshold);
265 }
258 266
259 public BSFMotor(string useName, float timeScale, float decayTimescale, float friction, float efficiency) 267 public BSFMotor(string useName, float timeScale, float decayTimescale, float efficiency)
260 : base(useName) 268 : base(useName)
261 { 269 {
270 TimeScale = TargetValueDecayTimeScale = BSMotor.Infinite;
271 Efficiency = 1f;
272 CurrentValue = TargetValue = 0f;
273 ErrorZeroThreshold = 0.01f;
262 } 274 }
263 public void SetCurrent(float target) 275 public void SetCurrent(float current)
264 { 276 {
277 CurrentValue = current;
265 } 278 }
266 public void SetTarget(float target) 279 public void SetTarget(float target)
267 { 280 {
281 TargetValue = target;
282 }
283 public override void Zero()
284 {
285 base.Zero();
286 CurrentValue = TargetValue = 0f;
268 } 287 }
288
269 public virtual float Step(float timeStep) 289 public virtual float Step(float timeStep)
270 { 290 {
271 return 0f; 291 if (!Enabled) return TargetValue;
292
293 float origTarget = TargetValue; // DEBUG
294 float origCurrVal = CurrentValue; // DEBUG
295
296 float correction = 0f;
297 float error = TargetValue - CurrentValue;
298 if (!ErrorIsZero(error))
299 {
300 correction = StepError(timeStep, error);
301
302 CurrentValue += correction;
303
304 // The desired value reduces to zero which also reduces the difference with current.
305 // If the decay time is infinite, don't decay at all.
306 float decayFactor = 0f;
307 if (TargetValueDecayTimeScale != BSMotor.Infinite)
308 {
309 decayFactor = (1.0f / TargetValueDecayTimeScale) * timeStep;
310 TargetValue *= (1f - decayFactor);
311 }
312
313 MDetailLog("{0}, BSFMotor.Step,nonZero,{1},origCurr={2},origTarget={3},timeStep={4},err={5},corr={6}",
314 BSScene.DetailLogZero, UseName, origCurrVal, origTarget,
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);
318 }
319 else
320 {
321 // Difference between what we have and target is small. Motor is done.
322 if (Util.InRange<float>(TargetValue, -ErrorZeroThreshold, ErrorZeroThreshold))
323 {
324 // The target can step down to nearly zero but not get there. If close to zero
325 // it is really zero.
326 TargetValue = 0f;
327 }
328 CurrentValue = TargetValue;
329 MDetailLog("{0}, BSFMotor.Step,zero,{1},origTgt={2},origCurr={3},ret={4}",
330 BSScene.DetailLogZero, UseName, origCurrVal, origTarget, CurrentValue);
331 }
332 LastError = error;
333
334 return CurrentValue;
272 } 335 }
336
337 public virtual float StepError(float timeStep, float error)
338 {
339 if (!Enabled) return 0f;
340
341 float returnCorrection = 0f;
342 if (!ErrorIsZero(error))
343 {
344 // correction = error / secondsItShouldTakeToCorrect
345 float correctionAmount;
346 if (TimeScale == 0f || TimeScale == BSMotor.Infinite)
347 correctionAmount = error * timeStep;
348 else
349 correctionAmount = error / TimeScale * timeStep;
350
351 returnCorrection = correctionAmount;
352 MDetailLog("{0}, BSFMotor.Step,nonZero,{1},timeStep={2},timeScale={3},err={4},corr={5}",
353 BSScene.DetailLogZero, UseName, timeStep, TimeScale, error, correctionAmount);
354 }
355 return returnCorrection;
356 }
357
358 public override string ToString()
359 {
360 return String.Format("<{0},curr={1},targ={2},lastErr={3},decayTS={4}>",
361 UseName, CurrentValue, TargetValue, LastError, TargetValueDecayTimeScale);
362 }
363
273} 364}
274 365
275// Proportional, Integral, Derivitive Motor 366// ============================================================================
367// ============================================================================
368// Proportional, Integral, Derivitive ("PID") Motor
276// Good description at http://www.answers.com/topic/pid-controller . Includes processes for choosing p, i and d factors. 369// Good description at http://www.answers.com/topic/pid-controller . Includes processes for choosing p, i and d factors.
277public class BSPIDVMotor : BSVMotor 370public class BSPIDVMotor : BSVMotor
278{ 371{
@@ -281,6 +374,11 @@ public class BSPIDVMotor : BSVMotor
281 public Vector3 integralFactor { get; set; } 374 public Vector3 integralFactor { get; set; }
282 public Vector3 derivFactor { get; set; } 375 public Vector3 derivFactor { get; set; }
283 376
377 // The factors are vectors for the three dimensions. This is the proportional of each
378 // that is applied. This could be multiplied through the actual factors but it
379 // is sometimes easier to manipulate the factors and their mix separately.
380 public Vector3 FactorMix;
381
284 // Arbritrary factor range. 382 // Arbritrary factor range.
285 // EfficiencyHigh means move quickly to the correct number. EfficiencyLow means might over correct. 383 // EfficiencyHigh means move quickly to the correct number. EfficiencyLow means might over correct.
286 public float EfficiencyHigh = 0.4f; 384 public float EfficiencyHigh = 0.4f;
@@ -295,6 +393,7 @@ public class BSPIDVMotor : BSVMotor
295 proportionFactor = new Vector3(1.00f, 1.00f, 1.00f); 393 proportionFactor = new Vector3(1.00f, 1.00f, 1.00f);
296 integralFactor = new Vector3(1.00f, 1.00f, 1.00f); 394 integralFactor = new Vector3(1.00f, 1.00f, 1.00f);
297 derivFactor = 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);
298 RunningIntegration = Vector3.Zero; 397 RunningIntegration = Vector3.Zero;
299 LastError = Vector3.Zero; 398 LastError = Vector3.Zero;
300 } 399 }
@@ -310,20 +409,24 @@ public class BSPIDVMotor : BSVMotor
310 set 409 set
311 { 410 {
312 base.Efficiency = Util.Clamp(value, 0f, 1f); 411 base.Efficiency = Util.Clamp(value, 0f, 1f);
412
313 // Compute factors based on efficiency. 413 // Compute factors based on efficiency.
314 // If efficiency is high (1f), use a factor value that moves the error value to zero with little overshoot. 414 // If efficiency is high (1f), use a factor value that moves the error value to zero with little overshoot.
315 // If efficiency is low (0f), use a factor value that overcorrects. 415 // If efficiency is low (0f), use a factor value that overcorrects.
316 // TODO: might want to vary contribution of different factor depending on efficiency. 416 // TODO: might want to vary contribution of different factor depending on efficiency.
317 float factor = ((1f - this.Efficiency) * EfficiencyHigh + EfficiencyLow) / 3f; 417 // float factor = ((1f - this.Efficiency) * EfficiencyHigh + EfficiencyLow) / 3f;
318 // float factor = (1f - this.Efficiency) * EfficiencyHigh + EfficiencyLow; 418 float factor = (1f - this.Efficiency) * EfficiencyHigh + EfficiencyLow;
419
319 proportionFactor = new Vector3(factor, factor, factor); 420 proportionFactor = new Vector3(factor, factor, factor);
320 integralFactor = new Vector3(factor, factor, factor); 421 integralFactor = new Vector3(factor, factor, factor);
321 derivFactor = new Vector3(factor, factor, factor); 422 derivFactor = new Vector3(factor, factor, factor);
423
424 MDetailLog("{0}, BSPIDVMotor.setEfficiency,eff={1},factor={2}", BSScene.DetailLogZero, Efficiency, factor);
322 } 425 }
323 } 426 }
324 427
325 // Ignore Current and Target Values and just advance the PID computation on this error. 428 // Advance the PID computation on this error.
326 public override Vector3 Step(float timeStep, Vector3 error) 429 public override Vector3 StepError(float timeStep, Vector3 error)
327 { 430 {
328 if (!Enabled) return Vector3.Zero; 431 if (!Enabled) return Vector3.Zero;
329 432
@@ -331,15 +434,16 @@ public class BSPIDVMotor : BSVMotor
331 RunningIntegration += error * timeStep; 434 RunningIntegration += error * timeStep;
332 435
333 // A simple derivitive is the rate of change from the last error. 436 // A simple derivitive is the rate of change from the last error.
334 Vector3 derivFactor = (error - LastError) * timeStep; 437 Vector3 derivitive = (error - LastError) * timeStep;
335 LastError = error; 438
439 // Correction = (proportionOfPresentError + accumulationOfPastError + rateOfChangeOfError)
440 Vector3 ret = error / TimeScale * timeStep * proportionFactor * FactorMix.X
441 + RunningIntegration / TimeScale * integralFactor * FactorMix.Y
442 + derivitive / TimeScale * derivFactor * FactorMix.Z
443 ;
336 444
337 // Correction = -(proportionOfPresentError + accumulationOfPastError + rateOfChangeOfError) 445 MDetailLog("{0}, BSPIDVMotor.step,ts={1},err={2},lerr={3},runnInt={4},deriv={5},ret={6}",
338 Vector3 ret = -( 446 BSScene.DetailLogZero, timeStep, error, LastError, RunningIntegration, derivitive, ret);
339 error * proportionFactor
340 + RunningIntegration * integralFactor
341 + derivFactor * derivFactor
342 );
343 447
344 return ret; 448 return ret;
345 } 449 }