BulletSim: remove friction calcuation from BSMotor and move linear and
angular friction computation into linear and angular movement code. The friction wasn't being applied properly. This will make it so vehicles don't drift as much and the drift is tunable by changing the friction timescales.user_profiles
parent
bf31896983
commit
045aaa838a
|
@ -118,7 +118,6 @@ public class BSActorAvatarMove : BSActor
|
|||
m_velocityMotor = new BSVMotor("BSCharacter.Velocity",
|
||||
0.2f, // time scale
|
||||
BSMotor.Infinite, // decay time scale
|
||||
BSMotor.InfiniteVector, // friction timescale
|
||||
1f // efficiency
|
||||
);
|
||||
// _velocityMotor.PhysicsScene = PhysicsScene; // DEBUG DEBUG so motor will output detail log messages.
|
||||
|
|
|
@ -102,7 +102,6 @@ public class BSActorHover : BSActor
|
|||
m_hoverMotor = new BSFMotor("BSActorHover",
|
||||
m_controllingPrim.HoverTau, // timeScale
|
||||
BSMotor.Infinite, // decay time scale
|
||||
BSMotor.Infinite, // friction timescale
|
||||
1f // efficiency
|
||||
);
|
||||
m_hoverMotor.SetTarget(ComputeCurrentHoverHeight());
|
||||
|
|
|
@ -105,7 +105,6 @@ public class BSActorMoveToTarget : BSActor
|
|||
m_targetMotor = new BSVMotor("BSActorMoveToTargget.Activate",
|
||||
m_controllingPrim.MoveToTargetTau, // timeScale
|
||||
BSMotor.Infinite, // decay time scale
|
||||
BSMotor.InfiniteVector, // friction timescale
|
||||
1f // efficiency
|
||||
);
|
||||
m_targetMotor.PhysicsScene = m_physicsScene; // DEBUG DEBUG so motor will output detail log messages.
|
||||
|
|
|
@ -101,7 +101,7 @@ public class BSActorSetForce : BSActor
|
|||
if (m_forceMotor == null)
|
||||
{
|
||||
// A fake motor that might be used someday
|
||||
m_forceMotor = new BSFMotor("setForce", 1f, 1f, 1f, 1f);
|
||||
m_forceMotor = new BSFMotor("setForce", 1f, 1f, 1f);
|
||||
|
||||
m_physicsScene.BeforeStep += Mover;
|
||||
}
|
||||
|
|
|
@ -101,7 +101,7 @@ public class BSActorSetTorque : BSActor
|
|||
if (m_torqueMotor == null)
|
||||
{
|
||||
// A fake motor that might be used someday
|
||||
m_torqueMotor = new BSFMotor("setTorque", 1f, 1f, 1f, 1f);
|
||||
m_torqueMotor = new BSFMotor("setTorque", 1f, 1f, 1f);
|
||||
|
||||
m_physicsScene.BeforeStep += Mover;
|
||||
}
|
||||
|
|
|
@ -235,7 +235,6 @@ namespace OpenSim.Region.Physics.BulletSPlugin
|
|||
// set all of the components to the same value
|
||||
case Vehicle.ANGULAR_FRICTION_TIMESCALE:
|
||||
m_angularFrictionTimescale = new Vector3(pValue, pValue, pValue);
|
||||
m_angularMotor.FrictionTimescale = m_angularFrictionTimescale;
|
||||
break;
|
||||
case Vehicle.ANGULAR_MOTOR_DIRECTION:
|
||||
m_angularMotorDirection = new Vector3(pValue, pValue, pValue);
|
||||
|
@ -244,7 +243,6 @@ namespace OpenSim.Region.Physics.BulletSPlugin
|
|||
break;
|
||||
case Vehicle.LINEAR_FRICTION_TIMESCALE:
|
||||
m_linearFrictionTimescale = new Vector3(pValue, pValue, pValue);
|
||||
m_linearMotor.FrictionTimescale = m_linearFrictionTimescale;
|
||||
break;
|
||||
case Vehicle.LINEAR_MOTOR_DIRECTION:
|
||||
m_linearMotorDirection = new Vector3(pValue, pValue, pValue);
|
||||
|
@ -265,7 +263,6 @@ namespace OpenSim.Region.Physics.BulletSPlugin
|
|||
{
|
||||
case Vehicle.ANGULAR_FRICTION_TIMESCALE:
|
||||
m_angularFrictionTimescale = new Vector3(pValue.X, pValue.Y, pValue.Z);
|
||||
m_angularMotor.FrictionTimescale = m_angularFrictionTimescale;
|
||||
break;
|
||||
case Vehicle.ANGULAR_MOTOR_DIRECTION:
|
||||
// Limit requested angular speed to 2 rps= 4 pi rads/sec
|
||||
|
@ -278,7 +275,6 @@ namespace OpenSim.Region.Physics.BulletSPlugin
|
|||
break;
|
||||
case Vehicle.LINEAR_FRICTION_TIMESCALE:
|
||||
m_linearFrictionTimescale = new Vector3(pValue.X, pValue.Y, pValue.Z);
|
||||
m_linearMotor.FrictionTimescale = m_linearFrictionTimescale;
|
||||
break;
|
||||
case Vehicle.LINEAR_MOTOR_DIRECTION:
|
||||
m_linearMotorDirection = new Vector3(pValue.X, pValue.Y, pValue.Z);
|
||||
|
@ -559,14 +555,10 @@ namespace OpenSim.Region.Physics.BulletSPlugin
|
|||
break;
|
||||
}
|
||||
|
||||
m_linearMotor = new BSVMotor("LinearMotor", m_linearMotorTimescale,
|
||||
m_linearMotorDecayTimescale, m_linearFrictionTimescale,
|
||||
1f);
|
||||
m_linearMotor = new BSVMotor("LinearMotor", m_linearMotorTimescale, m_linearMotorDecayTimescale, 1f);
|
||||
m_linearMotor.PhysicsScene = m_physicsScene; // DEBUG DEBUG DEBUG (enables detail logging)
|
||||
|
||||
m_angularMotor = new BSVMotor("AngularMotor", m_angularMotorTimescale,
|
||||
m_angularMotorDecayTimescale, m_angularFrictionTimescale,
|
||||
1f);
|
||||
m_angularMotor = new BSVMotor("AngularMotor", m_angularMotorTimescale, m_angularMotorDecayTimescale, 1f);
|
||||
m_angularMotor.PhysicsScene = m_physicsScene; // DEBUG DEBUG DEBUG (enables detail logging)
|
||||
|
||||
/* Not implemented
|
||||
|
@ -574,7 +566,6 @@ namespace OpenSim.Region.Physics.BulletSPlugin
|
|||
BSMotor.Infinite, BSMotor.InfiniteVector,
|
||||
m_verticalAttractionEfficiency);
|
||||
// Z goes away and we keep X and Y
|
||||
m_verticalAttractionMotor.FrictionTimescale = new Vector3(BSMotor.Infinite, BSMotor.Infinite, 0.1f);
|
||||
m_verticalAttractionMotor.PhysicsScene = PhysicsScene; // DEBUG DEBUG DEBUG (enables detail logging)
|
||||
*/
|
||||
|
||||
|
@ -1050,8 +1041,13 @@ namespace OpenSim.Region.Physics.BulletSPlugin
|
|||
// Add this correction to the velocity to make it faster/slower.
|
||||
VehicleVelocity += linearMotorVelocityW;
|
||||
|
||||
VDetailLog("{0}, MoveLinear,velocity,origVelW={1},velV={2},correctV={3},correctW={4},newVelW={5}",
|
||||
ControllingPrim.LocalID, origVelW, currentVelV, linearMotorCorrectionV, linearMotorVelocityW, VehicleVelocity);
|
||||
// Friction reduces vehicle motion
|
||||
Vector3 frictionFactor = ComputeFrictionFactor(m_linearFrictionTimescale, pTimestep);
|
||||
VehicleVelocity -= (VehicleVelocity * frictionFactor);
|
||||
|
||||
VDetailLog("{0}, MoveLinear,velocity,origVelW={1},velV={2},correctV={3},correctW={4},newVelW={5},fricFact={6}",
|
||||
ControllingPrim.LocalID, origVelW, currentVelV, linearMotorCorrectionV,
|
||||
linearMotorVelocityW, VehicleVelocity, frictionFactor);
|
||||
}
|
||||
|
||||
public void ComputeLinearTerrainHeightCorrection(float pTimestep)
|
||||
|
@ -1342,6 +1338,11 @@ namespace OpenSim.Region.Physics.BulletSPlugin
|
|||
// }
|
||||
|
||||
VehicleRotationalVelocity += angularMotorContributionV * VehicleOrientation;
|
||||
|
||||
// Reduce any velocity by friction.
|
||||
Vector3 frictionFactor = ComputeFrictionFactor(m_angularFrictionTimescale, pTimestep);
|
||||
VehicleRotationalVelocity -= (VehicleRotationalVelocity * frictionFactor);
|
||||
|
||||
VDetailLog("{0}, MoveAngular,angularTurning,angularMotorContrib={1}", ControllingPrim.LocalID, angularMotorContributionV);
|
||||
}
|
||||
|
||||
|
@ -1629,6 +1630,23 @@ namespace OpenSim.Region.Physics.BulletSPlugin
|
|||
|
||||
}
|
||||
|
||||
// Given a friction vector (reduction in seconds) and a timestep, return the factor to reduce
|
||||
// some value by to apply this friction.
|
||||
private Vector3 ComputeFrictionFactor(Vector3 friction, float pTimestep)
|
||||
{
|
||||
Vector3 frictionFactor = Vector3.Zero;
|
||||
if (friction != BSMotor.InfiniteVector)
|
||||
{
|
||||
// frictionFactor = (Vector3.One / FrictionTimescale) * timeStep;
|
||||
// Individual friction components can be 'infinite' so compute each separately.
|
||||
frictionFactor.X = (friction.X == BSMotor.Infinite) ? 0f : (1f / friction.X);
|
||||
frictionFactor.Y = (friction.Y == BSMotor.Infinite) ? 0f : (1f / friction.Y);
|
||||
frictionFactor.Z = (friction.Z == BSMotor.Infinite) ? 0f : (1f / friction.Z);
|
||||
frictionFactor *= pTimestep;
|
||||
}
|
||||
return frictionFactor;
|
||||
}
|
||||
|
||||
private float ClampInRange(float low, float val, float high)
|
||||
{
|
||||
return Math.Max(low, Math.Min(val, high));
|
||||
|
|
|
@ -65,13 +65,11 @@ public abstract class BSMotor
|
|||
}
|
||||
|
||||
// Motor which moves CurrentValue to TargetValue over TimeScale seconds.
|
||||
// The TargetValue decays in TargetValueDecayTimeScale and
|
||||
// the CurrentValue will be held back by FrictionTimeScale.
|
||||
// The TargetValue decays in TargetValueDecayTimeScale.
|
||||
// This motor will "zero itself" over time in that the targetValue will
|
||||
// decay to zero and the currentValue will follow it to that zero.
|
||||
// The overall effect is for the returned correction value to go from large
|
||||
// values (the total difference between current and target minus friction)
|
||||
// to small and eventually zero values.
|
||||
// values to small and eventually zero values.
|
||||
// TimeScale and TargetDelayTimeScale may be 'infinite' which means no decay.
|
||||
|
||||
// For instance, if something is moving at speed X and the desired speed is Y,
|
||||
|
@ -88,7 +86,6 @@ public class BSVMotor : BSMotor
|
|||
|
||||
public virtual float TimeScale { get; set; }
|
||||
public virtual float TargetValueDecayTimeScale { get; set; }
|
||||
public virtual Vector3 FrictionTimescale { get; set; }
|
||||
public virtual float Efficiency { get; set; }
|
||||
|
||||
public virtual float ErrorZeroThreshold { get; set; }
|
||||
|
@ -111,16 +108,14 @@ public class BSVMotor : BSMotor
|
|||
{
|
||||
TimeScale = TargetValueDecayTimeScale = BSMotor.Infinite;
|
||||
Efficiency = 1f;
|
||||
FrictionTimescale = BSMotor.InfiniteVector;
|
||||
CurrentValue = TargetValue = Vector3.Zero;
|
||||
ErrorZeroThreshold = 0.001f;
|
||||
}
|
||||
public BSVMotor(string useName, float timeScale, float decayTimeScale, Vector3 frictionTimeScale, float efficiency)
|
||||
public BSVMotor(string useName, float timeScale, float decayTimeScale, float efficiency)
|
||||
: this(useName)
|
||||
{
|
||||
TimeScale = timeScale;
|
||||
TargetValueDecayTimeScale = decayTimeScale;
|
||||
FrictionTimescale = frictionTimeScale;
|
||||
Efficiency = efficiency;
|
||||
CurrentValue = TargetValue = Vector3.Zero;
|
||||
}
|
||||
|
@ -165,26 +160,11 @@ public class BSVMotor : BSMotor
|
|||
TargetValue *= (1f - decayFactor);
|
||||
}
|
||||
|
||||
// The amount we can correct the error is reduced by the friction
|
||||
Vector3 frictionFactor = Vector3.Zero;
|
||||
if (FrictionTimescale != BSMotor.InfiniteVector)
|
||||
{
|
||||
// frictionFactor = (Vector3.One / FrictionTimescale) * timeStep;
|
||||
// Individual friction components can be 'infinite' so compute each separately.
|
||||
frictionFactor.X = (FrictionTimescale.X == BSMotor.Infinite) ? 0f : (1f / FrictionTimescale.X);
|
||||
frictionFactor.Y = (FrictionTimescale.Y == BSMotor.Infinite) ? 0f : (1f / FrictionTimescale.Y);
|
||||
frictionFactor.Z = (FrictionTimescale.Z == BSMotor.Infinite) ? 0f : (1f / FrictionTimescale.Z);
|
||||
frictionFactor *= timeStep;
|
||||
CurrentValue *= (Vector3.One - frictionFactor);
|
||||
}
|
||||
|
||||
MDetailLog("{0}, BSVMotor.Step,nonZero,{1},origCurr={2},origTarget={3},timeStep={4},err={5},corr={6}",
|
||||
BSScene.DetailLogZero, UseName, origCurrVal, origTarget,
|
||||
timeStep, error, correction);
|
||||
MDetailLog("{0}, BSVMotor.Step,nonZero,{1},tgtDecayTS={2},decayFact={3},frictTS={4},frictFact={5},tgt={6},curr={7}",
|
||||
BSScene.DetailLogZero, UseName,
|
||||
TargetValueDecayTimeScale, decayFactor, FrictionTimescale, frictionFactor,
|
||||
TargetValue, CurrentValue);
|
||||
MDetailLog("{0}, BSVMotor.Step,nonZero,{1},tgtDecayTS={2},decayFact={3},tgt={4},curr={5}",
|
||||
BSScene.DetailLogZero, UseName, TargetValueDecayTimeScale, decayFactor, TargetValue, CurrentValue);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -235,9 +215,9 @@ public class BSVMotor : BSMotor
|
|||
// maximum number of outputs to generate.
|
||||
int maxOutput = 50;
|
||||
MDetailLog("{0},BSVMotor.Test,{1},===================================== BEGIN Test Output", BSScene.DetailLogZero, UseName);
|
||||
MDetailLog("{0},BSVMotor.Test,{1},timeScale={2},targDlyTS={3},frictTS={4},eff={5},curr={6},tgt={7}",
|
||||
MDetailLog("{0},BSVMotor.Test,{1},timeScale={2},targDlyTS={3},eff={4},curr={5},tgt={6}",
|
||||
BSScene.DetailLogZero, UseName,
|
||||
TimeScale, TargetValueDecayTimeScale, FrictionTimescale, Efficiency,
|
||||
TimeScale, TargetValueDecayTimeScale, Efficiency,
|
||||
CurrentValue, TargetValue);
|
||||
|
||||
LastError = BSMotor.InfiniteVector;
|
||||
|
@ -254,8 +234,8 @@ public class BSVMotor : BSMotor
|
|||
|
||||
public override string ToString()
|
||||
{
|
||||
return String.Format("<{0},curr={1},targ={2},lastErr={3},decayTS={4},frictTS={5}>",
|
||||
UseName, CurrentValue, TargetValue, LastError, TargetValueDecayTimeScale, FrictionTimescale);
|
||||
return String.Format("<{0},curr={1},targ={2},lastErr={3},decayTS={4}>",
|
||||
UseName, CurrentValue, TargetValue, LastError, TargetValueDecayTimeScale);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -265,7 +245,6 @@ public class BSFMotor : BSMotor
|
|||
{
|
||||
public virtual float TimeScale { get; set; }
|
||||
public virtual float TargetValueDecayTimeScale { get; set; }
|
||||
public virtual float FrictionTimescale { get; set; }
|
||||
public virtual float Efficiency { get; set; }
|
||||
|
||||
public virtual float ErrorZeroThreshold { get; set; }
|
||||
|
@ -283,12 +262,11 @@ public class BSFMotor : BSMotor
|
|||
return (err >= -ErrorZeroThreshold && err <= ErrorZeroThreshold);
|
||||
}
|
||||
|
||||
public BSFMotor(string useName, float timeScale, float decayTimescale, float friction, float efficiency)
|
||||
public BSFMotor(string useName, float timeScale, float decayTimescale, float efficiency)
|
||||
: base(useName)
|
||||
{
|
||||
TimeScale = TargetValueDecayTimeScale = BSMotor.Infinite;
|
||||
Efficiency = 1f;
|
||||
FrictionTimescale = BSMotor.Infinite;
|
||||
CurrentValue = TargetValue = 0f;
|
||||
ErrorZeroThreshold = 0.01f;
|
||||
}
|
||||
|
@ -331,24 +309,11 @@ public class BSFMotor : BSMotor
|
|||
TargetValue *= (1f - decayFactor);
|
||||
}
|
||||
|
||||
// The amount we can correct the error is reduced by the friction
|
||||
float frictionFactor = 0f;
|
||||
if (FrictionTimescale != BSMotor.Infinite)
|
||||
{
|
||||
// frictionFactor = (Vector3.One / FrictionTimescale) * timeStep;
|
||||
// Individual friction components can be 'infinite' so compute each separately.
|
||||
frictionFactor = 1f / FrictionTimescale;
|
||||
frictionFactor *= timeStep;
|
||||
CurrentValue *= (1f - frictionFactor);
|
||||
}
|
||||
|
||||
MDetailLog("{0}, BSFMotor.Step,nonZero,{1},origCurr={2},origTarget={3},timeStep={4},err={5},corr={6}",
|
||||
BSScene.DetailLogZero, UseName, origCurrVal, origTarget,
|
||||
timeStep, error, correction);
|
||||
MDetailLog("{0}, BSFMotor.Step,nonZero,{1},tgtDecayTS={2},decayFact={3},frictTS={4},frictFact={5},tgt={6},curr={7}",
|
||||
BSScene.DetailLogZero, UseName,
|
||||
TargetValueDecayTimeScale, decayFactor, FrictionTimescale, frictionFactor,
|
||||
TargetValue, CurrentValue);
|
||||
MDetailLog("{0}, BSFMotor.Step,nonZero,{1},tgtDecayTS={2},decayFact={3},tgt={4},curr={5}",
|
||||
BSScene.DetailLogZero, UseName, TargetValueDecayTimeScale, decayFactor, TargetValue, CurrentValue);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -390,8 +355,8 @@ public class BSFMotor : BSMotor
|
|||
|
||||
public override string ToString()
|
||||
{
|
||||
return String.Format("<{0},curr={1},targ={2},lastErr={3},decayTS={4},frictTS={5}>",
|
||||
UseName, CurrentValue, TargetValue, LastError, TargetValueDecayTimeScale, FrictionTimescale);
|
||||
return String.Format("<{0},curr={1},targ={2},lastErr={3},decayTS={4}>",
|
||||
UseName, CurrentValue, TargetValue, LastError, TargetValueDecayTimeScale);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue