9 #include "BlMotorizedJoint.h"
10 #include "BlRigidBody.h"
12 #include "BlHingeLimit.h"
14 #include "BlSimulator.h"
34 m_fltChildMassWithChildren = 0;
69 {
Std_TraceMsg(0,
"Caught Error in desctructor of BlHinge\r\n",
"", -1,
false,
true);}
74 Hinge::EnableLimits(bVal);
79 void BlHinge::SetLimitValues()
83 GetLimitsFromRelaxations(m_vLowerLinear, m_vUpperLinear, m_vLowerAngular, m_vUpperAngular);
85 float fltErp = 0, fltCfm=0;
89 m_bJointLocked =
false;
104 m_bJointLocked =
false;
107 m_vLowerAngular[0] = 1;
108 m_vUpperAngular[0] = -1;
114 m_btHinge->getRotationalLimitMotor(0)->m_bounce = fltBounce;
116 m_btHinge->setLinearLowerLimit(m_vLowerLinear);
117 m_btHinge->setLinearUpperLimit(m_vUpperLinear);
118 m_btHinge->setAngularLowerLimit(m_vLowerAngular);
119 m_btHinge->setAngularUpperLimit(m_vUpperAngular);
130 void BlHinge::SetAlpha()
143 void BlHinge::DeleteJointGraphics()
145 OsgHingeLimit *lpUpperLimit =
dynamic_cast<OsgHingeLimit *
>(
m_lpUpperLimit);
146 OsgHingeLimit *lpLowerLimit =
dynamic_cast<OsgHingeLimit *
>(
m_lpLowerLimit);
147 OsgHingeLimit *lpPosFlap =
dynamic_cast<OsgHingeLimit *
>(
m_lpPosFlap);
149 OsgHinge::DeleteHingeGraphics(m_osgJointMT, lpUpperLimit, lpLowerLimit, lpPosFlap);
156 void BlHinge::CreateJointGraphics()
158 OsgHingeLimit *lpUpperLimit =
dynamic_cast<OsgHingeLimit *
>(
m_lpUpperLimit);
159 OsgHingeLimit *lpLowerLimit =
dynamic_cast<OsgHingeLimit *
>(
m_lpLowerLimit);
160 OsgHingeLimit *lpPosFlap =
dynamic_cast<OsgHingeLimit *
>(
m_lpPosFlap);
162 float fltLimitPos = Hinge::JointPosition();
166 m_osgJointMT, lpUpperLimit, lpLowerLimit, lpPosFlap);
170 void BlHinge::Physics_UpdateAbsolutePosition()
173 CStdFPoint vPos = OsgMovableItem::GetOSGWorldCoords();
174 vPos.ClearNearZero();
175 m_lpThisMI->AbsolutePosition(vPos.x, vPos.y, vPos.z);
178 void BlHinge::SetupPhysics()
181 DeletePhysics(
false);
185 btTransform mtJointRelParent, mtJointRelChild;
186 CalculateRelativeJointMatrices(mtJointRelParent, mtJointRelChild);
190 m_btHinge->setDbgDrawSize(btScalar(5.f));
192 GetBlSimulator()->DynamicsWorld()->addConstraint(
m_btHinge,
true);
204 m_btHinge->getRotationalLimitMotor(0)->m_currentPosition = 0;
211 if(m_lpBlParent && m_lpBlParent->Part())
213 m_lpBlParent->Part()->setSleepingThresholds(0, 0);
214 m_lpBlParent->Part()->setActivationState(DISABLE_DEACTIVATION);
217 if(m_lpBlChild && m_lpBlChild->Part())
219 m_lpBlChild->Part()->setSleepingThresholds(0, 0);
220 m_lpBlChild->Part()->setActivationState(DISABLE_DEACTIVATION);
223 m_btHinge->setJointFeedback(&m_btJointFeedback);
226 BlJoint::Initialize();
228 m_fltChildMassWithChildren =
m_lpChild->MassWithChildren();
229 m_fltChildMassWithChildren *= (m_lpThisAB->GetSimulator()->MassUnits());
238 #pragma region DataAccesMethods
240 float *BlHinge::GetDataPointer(
const std::string &strDataType)
245 if(strType ==
"JOINTROTATION")
247 else if(strType ==
"JOINTPOSITION")
249 else if(strType ==
"JOINTACTUALVELOCITY")
251 else if(strType ==
"JOINTFORCE")
253 else if(strType ==
"JOINTROTATIONDEG")
255 else if(strType ==
"JOINTDESIREDPOSITION")
257 else if(strType ==
"JOINTDESIREDPOSITIONDEG")
259 else if(strType ==
"JOINTSETPOSITION")
261 else if(strType ==
"JOINTDESIREDVELOCITY")
263 else if(strType ==
"JOINTSETVELOCITY")
265 else if(strType ==
"ENABLE")
267 else if(strType ==
"CONTACTCOUNT")
268 THROW_PARAM_ERROR(Al_Err_lMustBeContactBodyToGetCount, Al_Err_strMustBeContactBodyToGetCount,
"JointID",
m_strName);
271 lpData = BlMotorizedJoint::Physics_GetDataPointer(strType);
272 if(lpData)
return lpData;
274 lpData = Hinge::GetDataPointer(strType);
275 if(lpData)
return lpData;
277 THROW_TEXT_ERROR(Al_Err_lInvalidDataType, Al_Err_strInvalidDataType,
"JointID: " + STR(
m_strName) +
" DataType: " + strDataType);
283 bool BlHinge::SetData(
const std::string &strDataType,
const std::string &strValue,
bool bThrowError)
285 if(BlJoint::Physics_SetData(strDataType, strValue))
288 if(Hinge::SetData(strDataType, strValue,
false))
293 THROW_PARAM_ERROR(Al_Err_lInvalidDataType, Al_Err_strInvalidDataType,
"Data Type", strDataType);
298 void BlHinge::QueryProperties(CStdPtrArray<TypeProperty> &aryProperties)
300 BlJoint::Physics_QueryProperties(aryProperties);
301 Hinge::QueryProperties(aryProperties);
303 aryProperties.Add(
new TypeProperty(
"JointRotation", AnimatPropertyType::Float, AnimatPropertyDirection::Get));
304 aryProperties.Add(
new TypeProperty(
"JointPosition", AnimatPropertyType::Float, AnimatPropertyDirection::Get));
305 aryProperties.Add(
new TypeProperty(
"JointActualVelocity", AnimatPropertyType::Float, AnimatPropertyDirection::Get));
306 aryProperties.Add(
new TypeProperty(
"JointForce", AnimatPropertyType::Float, AnimatPropertyDirection::Get));
307 aryProperties.Add(
new TypeProperty(
"JointRotationDeg", AnimatPropertyType::Float, AnimatPropertyDirection::Get));
308 aryProperties.Add(
new TypeProperty(
"JointDesiredPosition", AnimatPropertyType::Float, AnimatPropertyDirection::Get));
309 aryProperties.Add(
new TypeProperty(
"JointDesiredPositionDeg", AnimatPropertyType::Float, AnimatPropertyDirection::Get));
310 aryProperties.Add(
new TypeProperty(
"JointSetPosition", AnimatPropertyType::Float, AnimatPropertyDirection::Get));
311 aryProperties.Add(
new TypeProperty(
"JointDesiredVelocity", AnimatPropertyType::Float, AnimatPropertyDirection::Get));
312 aryProperties.Add(
new TypeProperty(
"JointSetVelocity", AnimatPropertyType::Float, AnimatPropertyDirection::Get));
313 aryProperties.Add(
new TypeProperty(
"Enable", AnimatPropertyType::Boolean, AnimatPropertyDirection::Get));
330 bool BlHinge::JointIsLocked()
332 btVector3 vLower, vUpper;
335 if( (vLower[0] == vUpper[0]) || (vLower[0] > vUpper[0]) )
341 void BlHinge::Physics_EnableLock(
bool bOn,
float fltPosition,
float fltMaxLockForce)
347 m_bJointLocked =
true;
349 m_vLowerAngular[0] = m_vUpperAngular[0] = fltPosition;
351 m_btHinge->setAngularLowerLimit(m_vLowerAngular);
352 m_btHinge->setAngularUpperLimit(m_vUpperAngular);
355 m_btHinge->getRotationalLimitMotor(0)->m_enableMotor =
true;
356 m_btHinge->getRotationalLimitMotor(0)->m_targetVelocity = 0;
357 m_btHinge->getRotationalLimitMotor(0)->m_maxMotorForce = fltMaxLockForce;
360 Physics_EnableMotor(
true, 0, fltMaxLockForce,
false);
366 void BlHinge::Physics_EnableMotor(
bool bOn,
float fltDesiredVelocity,
float fltMaxForce,
bool bForceWakeup)
372 if(!m_bMotorOn || bForceWakeup || m_bJointLocked || JointIsLocked())
374 m_fltNextPredictedPos = m_lpThisJoint->JointPosition();
375 m_fltPredictedPos = m_fltNextPredictedPos;
382 m_lpThisJoint->WakeDynamics();
386 m_btHinge->getRotationalLimitMotor(0)->m_enableMotor =
true;
387 m_btHinge->getRotationalLimitMotor(0)->m_targetVelocity = fltDesiredVelocity;
388 m_btHinge->getRotationalLimitMotor(0)->m_maxMotorForce = fltMaxForce;
394 if(m_bMotorOn || bForceWakeup || m_bJointLocked || JointIsLocked())
398 m_lpThisJoint->WakeDynamics();
407 void BlHinge::Physics_MaxForce(
float fltVal)
410 m_btHinge->getRotationalLimitMotor(0)->m_maxMotorForce = fltVal;
413 float BlHinge::GetCurrentBtPosition()
416 return m_btHinge->getRotationalLimitMotor(0)->m_currentPosition;
421 void BlHinge::TurnMotorOff()
436 float maxMotorImpulse =
m_lpFriction->
Coefficient()*0.032f*(m_lpThisAB->GetSimulator()->InverseMassUnits() * m_lpThisAB->GetSimulator()->InverseDistanceUnits());
438 m_btHinge->getRotationalLimitMotor(0)->m_enableMotor =
true;
439 m_btHinge->getRotationalLimitMotor(0)->m_targetVelocity = 0;
440 m_btHinge->getRotationalLimitMotor(0)->m_maxMotorForce = maxMotorImpulse;
445 m_btHinge->getRotationalLimitMotor(0)->m_enableMotor =
false;
448 m_btHinge->getRotationalLimitMotor(0)->m_accumulatedImpulse = 0;
449 m_btHinge->getRotationalLimitMotor(0)->m_currentLimit = 0;
450 m_btHinge->getRotationalLimitMotor(0)->m_currentLimitError = 0;
451 m_btHinge->getRotationalLimitMotor(0)->m_targetVelocity = 0;
455 void BlHinge::AxisConstraintSpringEnableChanged(
bool bEnabled)
461 void BlHinge::SetConstraintFriction()
469 Hinge::ResetSimulation();
471 for(
int iIdx=0; iIdx<3; iIdx++)
473 m_btHinge->getRotationalLimitMotor(iIdx)->m_currentPosition = 0;
474 m_btHinge->getRotationalLimitMotor(iIdx)->m_accumulatedImpulse = 0;
475 m_btHinge->getRotationalLimitMotor(iIdx)->m_currentLimit = 0;
476 m_btHinge->getRotationalLimitMotor(iIdx)->m_currentLimitError = 0;
477 m_btHinge->getRotationalLimitMotor(iIdx)->m_targetVelocity = 0;
480 m_btHinge->getTranslationalLimitMotor()->m_currentLinearDiff = btVector3(0, 0, 0);
481 m_btHinge->getTranslationalLimitMotor()->m_accumulatedImpulse = btVector3(0, 0, 0);
482 m_btHinge->getTranslationalLimitMotor()->m_targetVelocity = btVector3(0, 0, 0);
483 m_btHinge->getTranslationalLimitMotor()->m_currentLimit[0] = 0;
484 m_btHinge->getTranslationalLimitMotor()->m_currentLimit[1] = 0;
485 m_btHinge->getTranslationalLimitMotor()->m_currentLimit[2] = 0;
486 m_btHinge->getTranslationalLimitMotor()->m_currentLimitError = btVector3(0, 0, 0);
496 bool BlHinge::NeedApplyAssist()
505 float fltPos =
m_btHinge->getRotationalLimitMotor(0)->m_currentPosition;
506 float fltLow =
m_btHinge->getRotationalLimitMotor(0)->m_loLimit;
507 float fltHigh =
m_btHinge->getRotationalLimitMotor(0)->m_hiLimit;
509 float fltLow1Perc = fabs(fltLow)*0.001;
510 float fltHigh1Perc = fabs(fltHigh)*0.001;
513 if(fltSetVel > 0 && fabs(fltHigh-fltPos)>=fltHigh1Perc)
517 if(fltSetVel < 0 && fabs(fltPos-fltLow)>=fltLow1Perc)
531 if(NeedApplyAssist())
535 float fDisUnits = m_lpThisAB->GetSimulator()->InverseDistanceUnits();
536 float fMassUnits = m_lpThisAB->GetSimulator()->InverseMassUnits();
537 float fltRatio = fMassUnits * fDisUnits;
540 float fltSetPoint = m_fltPredictedPos;
541 float fltInput = m_lpThisJoint->JointPosition();
543 float fltVelDiffSign = (fltSetVel-m_lpThisJoint->JointVelocity());
553 btVector3 vbtMotorAxis =
m_btHinge->GetAngularForceAxis(0);
555 CStdFPoint vMotorAxis(vbtMotorAxis[0], vbtMotorAxis[1], vbtMotorAxis[2]);
556 CStdFPoint vBodyA = m_lpThisJoint->Parent()->AbsolutePosition();
557 CStdFPoint vBodyB = m_lpThisJoint->Child()->AbsolutePosition();
558 CStdFPoint vHinge = m_lpThisJoint->AbsolutePosition();
560 CStdFPoint vBodyAxisA = (vHinge - vBodyA);
561 vBodyAxisA.Normalize();
562 vBodyAxisA = vMotorAxis ^ vBodyAxisA;
564 CStdFPoint vBodyAxisB = (vHinge - vBodyB);
565 vBodyAxisB.Normalize();
566 vBodyAxisB = vMotorAxis ^ vBodyAxisB;
568 CStdFPoint vBodyAForceReport = vBodyAxisA * -fltForceMag;
569 CStdFPoint vBodyBForceReport = vBodyAxisB * fltForceMag;
570 CStdFPoint vBodyAForce = vBodyAForceReport * fltRatio;
571 CStdFPoint vBodyBForce = vBodyBForceReport * fltRatio;
579 btVector3 vbtMotorAForce(vBodyAForce.x, vBodyAForce.y, vBodyAForce.z);
580 btVector3 vbtMotorBForce(vBodyBForce.x, vBodyBForce.y, vBodyBForce.z);
582 m_btParent->applyCentralForce(vbtMotorAForce);
583 m_btChild->applyCentralForce(vbtMotorBForce);
float CylinderHeight()
Gets the height of the cylinder used to display the hinge in the environment.
virtual void PhysicsTimeStep(float fltVal)
Sets the integration time step for the physics engine.
virtual void ApplyMotorAssist()
Applies the motor assist.
float m_fltMaxForceNotScaled
The un=scaled maximum force.
Declares the vortex hinge class.
virtual float LimitPos()
Gets the limit position.
virtual float Restitution()
Gets the restitution coefficient of the constraint.
virtual void StepSimulation()
Step the simulation for this object.
virtual void Alpha(float fltA)=0
Sets the alpha color value for this constraint.
virtual void CreateJoint()
Creates the joint.
CStdFPoint m_vMotorAssistForceToAReport
Force vector that the motor assist is applying to body A. (un-scaled units).
float m_fltEnabled
This is used for reporting the enabled state in a GetDataPointer call.
virtual float Coefficient()
Gets the Coefficient of friction for this constraint.
PidControl * m_lpAssistPid
The PID controller for the motor assist system.
ConstraintFriction * m_lpFriction
The friction for this joint.
ConstraintLimit * m_lpUpperLimit
Upper limit constring pointer.
CStdFPoint m_vMotorAssistForceToA
Force vector that the motor assist is applying to body A. (scaled units).
virtual void EnableFeedback()
Enables joint feedback.
int Std_Sign(float fltVal)
Determines the sign of a number.
virtual Simulator * GetSimulator()
Gets the simulator pointer.
virtual void ResetSimulation()
Resets the simulation back to time 0.
virtual void IsShowPosition(bool bVal)
Sets whether this contstraint is actually just being used to show the current position of the joint...
Classes for implementing the cm-labs vortex physics engine for AnimatLab.
osg::ref_ptr< osg::StateSet > m_osgCylinderSS
The osg cylinder state set.
virtual bool Enabled()
Tells whether this node is enabled.
virtual ~BlHinge()
Destructor.
float m_fltRotationDeg
The rotation of the hinge in degrees.
BlConstraintRelaxation * m_aryBlRelaxations[6]
The bullet relaxation for the primary displacement relaxation.
float CylinderRadius()
Gets the radius cylinder of the cylinder used to display the hinge in the environment.
float m_fltDesiredPositionDeg
The desired rotation of the hinge in degrees.
virtual bool EnableMotor()
Tells if the motor is enabled.
CStdFPoint m_vMotorAssistForceToBReport
Force vector that the motor assist is applying to body B. (un-scaled units).
RigidBody * m_lpChild
The child rigid body for this joint.
bool m_bEnableLimits
If true then any ConstraintLimits for this joint are enabled.
CStdFPoint m_vMotorAssistForceToB
Force vector that the motor assist is applying to body B. (scaled units).
ConstraintLimit * m_lpLowerLimit
Lower limit constring pointer.
void Std_TraceMsg(const int iLevel, std::string strMessage, std::string strSourceFile, int iSourceLine, bool bLogToFile, bool bPrintHeader)
Traces a message to the debugger window.
BlHinge()
Default constructor.
float m_fltForce
The current force being applied to the joint by the motor.
virtual bool Enabled()
Tells whether this node is enabled.
btAnimatGeneric6DofConstraint * m_btHinge
The bullet hinge class.
bool m_bEnabled
Tells if this item is enabled or not. If it is not enabled then it is not run.
float m_fltReportSetPosition
This is the variable that is reported to AnimatLab on what the set position was.
osg::ref_ptr< osg::Material > m_osgCylinderMat
The osg cylinder material.
virtual bool Enabled()
Tells whether this item is enabled or not. This is not actually used for all objects, only specific ones. I am putting it in the base class though to prevent numerous duplications.
ConstraintLimit * m_lpPosFlap
Pointer to a constraint that is used to represent the position flap.
float m_fltMotorAssistMagnitudeReport
The reportable motor assist Force magnitude.
float m_fltAlpha
The current alpha transparency for this body part.
float m_fltReportSetVelocity
This is the variable that is reported to AnimatLab on what the set veloicty was.
virtual void SetVelocityToDesired()
Sets the desired velocity to use for the motor.
virtual float JointPosition()
Gets the joint position.
virtual void DeleteGraphics()=0
Deletes up the graphics for the constraint.
virtual void Color(float fltR, float fltG, float fltB, float fltA)
Sets the color to use when displaying this contraint.
virtual void IsLowerLimit(bool bVal)
Sets whether this is a lower limit or not..
std::string Std_CheckString(std::string strVal)
Converts a string to upper case and trims it.
float FlapWidth()
Gets the width of the flaps used to display the hinge in the environment.
virtual float SetVelocity()
Gets the velocity that is actually set using the physics method.
virtual void ClearAssistForces()
Clears the assist forces.
virtual void UpdateData()
Called to collect any body data for this part.
virtual bool EnableLimits()
Tells if ConstraintLimits are enabled.
float m_fltMotorAssistMagnitude
The motor assist Force magnitude.
ConstraintRelaxation * m_aryRelaxations[6]
The relaxations for the constraints.
std::string m_strName
The name for this object.