AnimatLab  2
Test
BlMotorizedJoint.cpp
Go to the documentation of this file.
1 
7 #include "StdAfx.h"
8 #include "BlJoint.h"
9 #include "BlMotorizedJoint.h"
10 #include "BlRigidBody.h"
11 #include "BlSimulator.h"
12 
13 namespace BulletAnimatSim
14 {
15  namespace Environment
16  {
17 
18 BlMotorizedJoint::BlMotorizedJoint()
19 {
20  m_lpThisMotorJoint = NULL;
21  m_bMotorOn = false;
22  m_bJointLocked = false;
23  m_fltPredictedPos = 0;
24  m_fltNextPredictedPos = 0;
25 }
26 
27 BlMotorizedJoint::~BlMotorizedJoint()
28 {
29 }
30 
31 void BlMotorizedJoint::SetThisPointers()
32 {
33  BlJoint::SetThisPointers();
34 
35  m_lpThisMotorJoint = dynamic_cast<MotorizedJoint *>(this);
36  if(!m_lpThisMotorJoint)
37  THROW_TEXT_ERROR(Bl_Err_lThisPointerNotDefined, Bl_Err_strThisPointerNotDefined, "m_lpThisMotorJoint, " + m_lpThisAB->Name());
38 
39  m_lpThisMotorJoint->PhysicsMotorJoint(this);
40 }
41 
42 //If this is a servo motor then the "velocity" signal is not really a velocity signal in this case.
43 //It is the desired position and we must convert it to the velocity needed to reach and maintian that position.
44 void BlMotorizedJoint::CalculateServoVelocity()
45 {
46  if(!m_btJoint)
47  return;
48 
49  float fltTargetPos = m_lpThisJoint->GetPositionWithinLimits(m_lpThisMotorJoint->DesiredPosition());
50  //For calculating the error we need to get the actual current position of the joint, not the value that was obtained last
51  //time it called CollectData. If the motor is being synched with the robot for sim then this could be delayed. However, in the
52  //real system this type of error correction would be taking place within the actual servo's motor loop.
53  float fltError = fltTargetPos - GetCurrentBtPositionScaled();
54  m_lpThisMotorJoint->SetPosition(fltTargetPos);
55 
57  //int i=5;
58  //if(Std_ToLower(m_lpThisMotorJoint->ID()) == "c868a91a-285d-4d00-91b2-6410aead9fe8" && GetSimulator()->Time() >= 1.2) // && fabs(fltTargetPos) > 0
59  // i=6;
60 
61  AnimatSim::Environment::eJointMotorType MotorType = m_lpThisMotorJoint->MotorType();
62  if((MotorType == eJointMotorType::PositionControl || MotorType == eJointMotorType::PositionVelocityControl) && m_lpThisMotorJoint->ReachedSetPosition() )
63  {
64  //Lock this joint position.
65  m_lpThisMotorJoint->DesiredVelocity(0);
66  }
67  else if(MotorType == eJointMotorType::PositionVelocityControl)
68  {
69  //If we set the desired velocity and position then make sure the desired velocity is in the right direction
70  float fltDesiredVel = fabs(m_lpThisMotorJoint->DesiredVelocity()) * Std_Sign(fltError);
71 
72  float fltPosError = fabs(fltError);
73  if(fltPosError > 0 && fltPosError < 0.05)
74  {
75  float fltDesiredVel2 = fltDesiredVel * (fabs(fltError)*m_lpThisMotorJoint->ServoGain());
76  //Only do this if the new desired velocity is less than the original one to slow it down. Never speed it up.
77  if(fabs(fltDesiredVel2) <= fabs(fltDesiredVel))
78  fltDesiredVel = fltDesiredVel2;
79  }
80 
81  m_lpThisMotorJoint->DesiredVelocity(fltDesiredVel);
82 
83  if(fabs(fltError) < 1e-4)
84  m_lpThisMotorJoint->ReachedSetPosition(true);
85  }
86  else if(MotorType == eJointMotorType::PositionControl)
87  {
88  if(m_lpThisJoint->EnableLimits())
89  {
90  float fltProp = fltError / m_lpThisJoint->GetLimitRange();
91  m_lpThisMotorJoint->DesiredVelocity(fltProp * m_lpThisMotorJoint->ServoGain());
92  }
93  else
94  m_lpThisMotorJoint->DesiredVelocity(fltError * m_lpThisMotorJoint->MaxVelocity());
95  }
96 }
97 
98 void BlMotorizedJoint::Physics_SetVelocityToDesired()
99 {
100  if(m_lpThisMotorJoint->EnableMotor())
101  {
102  AnimatSim::Environment::eJointMotorType MotorType = m_lpThisMotorJoint->MotorType();
103  if(MotorType == eJointMotorType::PositionControl ||MotorType == eJointMotorType::PositionVelocityControl)
104  CalculateServoVelocity();
105 
106  float fltDesiredVel = m_lpThisMotorJoint->DesiredVelocity();
107  float fltMaxVel = m_lpThisMotorJoint->MaxVelocity();
108  float fltMaxForce = m_lpThisMotorJoint->MaxForce();
109 
110  if(fltDesiredVel>fltMaxVel)
111  fltDesiredVel = fltMaxVel;
112 
113  if(fltDesiredVel < -fltMaxVel)
114  fltDesiredVel = -fltMaxVel;
115 
116  float fltSetVelocity = fltDesiredVel;
117 
118  m_lpThisMotorJoint->SetVelocity(fltSetVelocity);
119  m_lpThisMotorJoint->DesiredVelocity(0);
120  m_lpThisMotorJoint->DesiredPosition(0);
121 
122  float fltHalfPercVel = fabs(fltSetVelocity * 0.01);
123  //If the actual velocity matches the set velocity within 1% then lets set the predicted position based on
124  //current position going forward. If we are not neear the set velocity then continue to use predicted positions.
125  //if(fabs(fltSetVelocity - m_lpThisJoint->JointVelocity()) < fltHalfPercVel)
126  //{
127  // m_fltPredictedPos = m_lpThisJoint->JointPosition();
128  // m_fltNextPredictedPos = m_fltPredictedPos + (fltSetVelocity*m_lpThisAB->GetSimulator()->PhysicsTimeStep());
129  //}
130  //else
131  {
132  m_fltPredictedPos = m_fltNextPredictedPos;
133  m_fltNextPredictedPos = m_fltPredictedPos + (fltSetVelocity*m_lpThisAB->GetSimulator()->PhysicsTimeStep());
134  }
135 
136  float fltJointVel = m_lpThisJoint->JointVelocity();
137 
138  if(!m_lpThisJoint->UsesRadians())
139  fltJointVel *= m_lpThisAB->GetSimulator()->InverseDistanceUnits();;
140 
141  float fltVelDiff = fabs(fltJointVel - fltSetVelocity);
142 
143  //Only do anything if the velocity value has changed
144  if(m_btJoint && fltVelDiff > 1e-4)
145  {
146  if(fabs(fltSetVelocity) > 1e-4 && m_btJoint)
147  Physics_EnableMotor(true, fltSetVelocity, fltMaxForce, false);
148  else if(!m_bJointLocked)
149  Physics_EnableLock(true, GetCurrentBtPosition(), fltMaxForce);
150  }
151 
152  m_lpThisMotorJoint->PrevVelocity(fltSetVelocity);
153  }
154 }
155 
156 void BlMotorizedJoint::Physics_CollectExtraData()
157 {
158  OsgSimulator *lpSim = GetOsgSimulator();
159  if(m_btJoint && lpSim && m_lpThisMotorJoint && m_lpThisJoint && m_lpThisJoint->NeedsRobotSynch())
160  {
161  float fDisUnits = m_lpThisAB->GetSimulator()->DistanceUnits();
162  float fMassUnits = m_lpThisAB->GetSimulator()->MassUnits();
163  CStdFPoint vVal, vAssist;
164 
165  float fltRatio = fMassUnits * fDisUnits;
166  vAssist = m_lpThisMotorJoint->MotorAssistForceToAReport();
167  vVal[0] = (m_btJointFeedback.m_appliedForceBodyA[0] * fltRatio) + vAssist[0];
168  vVal[1] = (m_btJointFeedback.m_appliedForceBodyA[1] * fltRatio) + vAssist[1];
169  vVal[2] = (m_btJointFeedback.m_appliedForceBodyA[2] * fltRatio) + vAssist[2];
170  m_lpThisMotorJoint->MotorForceToA(vVal);
171 
172  vAssist = m_lpThisMotorJoint->MotorAssistForceToBReport();
173  vVal[0] = (m_btJointFeedback.m_appliedForceBodyB[0] * fltRatio) + vAssist[0];
174  vVal[1] = (m_btJointFeedback.m_appliedForceBodyB[1] * fltRatio) + vAssist[0];
175  vVal[2] = (m_btJointFeedback.m_appliedForceBodyB[2] * fltRatio) + vAssist[0];
176  m_lpThisMotorJoint->MotorForceToB(vVal);
177 
178  fltRatio = fMassUnits * fDisUnits * fDisUnits;
179  vAssist = m_lpThisMotorJoint->MotorAssistTorqueToAReport();
180  vVal[0] = (m_btJointFeedback.m_appliedTorqueBodyA[0] * fltRatio) + vAssist[0];
181  vVal[1] = (m_btJointFeedback.m_appliedTorqueBodyA[1] * fltRatio) + vAssist[0];
182  vVal[2] = (m_btJointFeedback.m_appliedTorqueBodyA[2] * fltRatio) + vAssist[0];
183  m_lpThisMotorJoint->MotorTorqueToA(vVal);
184 
185  vAssist = m_lpThisMotorJoint->MotorAssistTorqueToBReport();
186  vVal[0] = (m_btJointFeedback.m_appliedTorqueBodyB[0] * fltRatio) + vAssist[0];
187  vVal[1] = (m_btJointFeedback.m_appliedTorqueBodyB[1] * fltRatio) + vAssist[0];
188  vVal[2] = (m_btJointFeedback.m_appliedTorqueBodyB[2] * fltRatio) + vAssist[0];
189  m_lpThisMotorJoint->MotorTorqueToB(vVal);
190  }
191 }
192 
193 
194  } // Environment
195 } //BulletAnimatSim
int Std_Sign(float fltVal)
Determines the sign of a number.
Classes for implementing the cm-labs vortex physics engine for AnimatLab.
eJointMotorType
The motor control type for this joint.