28 #include <VirtualRobot/VirtualRobot.h>
29 #include <VirtualRobot/XML/RobotIO.h>
30 #include <VirtualRobot/RobotNodeSet.h>
31 #include <VirtualRobot/Nodes/RobotNode.h>
32 #include <VirtualRobot/VirtualRobotException.h>
36 #include <RobotAPI/interface/units/KinematicUnitInterface.h>
47 defineOptionalProperty<int>(
"IntervalMs", 10,
"The time in milliseconds between two calls to the simulation method.");
48 defineOptionalProperty<float>(
"Noise", 0.0f,
"Gaussian noise is added to the velocity. Value in Degree");
49 defineOptionalProperty<bool>(
"UsePDControllerForJointControl",
true,
"If true a PD controller is also used in Position Mode instead of setting the joint angles instantly");
50 defineOptionalProperty<float>(
"Kp", 3,
"proportional gain of the PID position controller.");
51 defineOptionalProperty<float>(
"Ki", 0.001f,
"integral gain of the PID position controller.");
52 defineOptionalProperty<float>(
"Kd", 0.0,
"derivative gain of the PID position controller.");
62 for (std::vector<VirtualRobot::RobotNodePtr>::iterator it =
robotNodes.begin(); it !=
robotNodes.end(); it++)
64 std::string jointName = (*it)->getName();
65 jointInfos[jointName].limitLo = (*it)->getJointLimitLo();
66 jointInfos[jointName].limitHi = (*it)->getJointLimitHi();
68 if ((*it)->isRotationalJoint())
84 for (std::vector<VirtualRobot::RobotNodePtr>::iterator it =
robotNodes.begin(); it !=
robotNodes.end(); it++)
86 std::string jointName = (*it)->getName();
90 getProperty<float>(
"Kp").getValue(),
91 getProperty<float>(
"Ki").getValue(),
92 getProperty<float>(
"Kd").getValue()));
96 noise = getProperty<float>(
"Noise").getValue() / 180.f *
M_PI;
102 intervalMs = getProperty<int>(
"IntervalMs").getValue();
131 bool aPosValueChanged =
false;
132 bool aVelValueChanged =
false;
133 auto signedMin = [](
float newValue,
float minAbsValue)
135 return std::copysign(std::min<float>(fabs(newValue), fabs(minAbsValue)), newValue);
142 for (KinematicUnitSimulationJointStates::iterator it =
jointStates.begin(); it !=
jointStates.end(); it++)
145 float newAngle = 0.0f;
146 float newVelocity = 0.0f;
149 if (it->second.controlMode == eVelocityControl)
151 double change = (it->second.velocity * timeDeltaInSeconds);
152 newVelocity = it->second.velocity;
156 change *= 1 + randomNoiseValue;
158 newAngle = it->second.angle + change;
162 aVelValueChanged =
true;
165 else if (it->second.controlMode == ePositionControl)
169 newAngle = it->second.angle;
176 float velValue = (it->second.velocity != 0.0f ?
signedMin(pid->getControlValue(), it->second.velocity) : pid->getControlValue());
182 pid->update(it->second.angle);
183 newAngle = it->second.angle +
188 aVelValueChanged =
true;
190 it->second.velocityActual = newVelocity = velValue;
201 newAngle = std::max<float>(newAngle, minAngle);
202 newAngle = std::min<float>(newAngle, maxAngle);
210 aPosValueChanged = aVelValueChanged =
true;
216 aPosValueChanged =
true;
218 it->second.angle = newAngle;
249 bool aValueChanged =
false;
250 NameControlModeMap changedControlModes;
254 for (NameControlModeMap::const_iterator it = targetJointModes.begin(); it != targetJointModes.end(); it++)
257 std::string targetJointName = it->first;
258 ControlMode targetControlMode = it->second;
260 KinematicUnitSimulationJointStates::iterator iterJoints =
jointStates.find(targetJointName);
265 if (iterJoints->second.controlMode != targetControlMode)
267 aValueChanged =
true;
270 iterJoints->second.controlMode = targetControlMode;
271 changedControlModes.insert(*it);
275 ARMARX_WARNING <<
"Could not find joint with name " << targetJointName;
290 bool aValueChanged =
false;
292 for (NameValueMap::const_iterator it = targetJointAngles.begin(); it != targetJointAngles.end(); it++)
295 std::string targetJointName = it->first;
296 float targetJointAngle = it->second;
299 KinematicUnitSimulationJointStates::iterator iterJoints =
jointStates.find(targetJointName);
303 if (fabs(iterJoints->second.angle - targetJointAngle) > 0)
305 aValueChanged =
true;
310 targetJointAngle = std::max<float>(targetJointAngle, jointInfo.
limitLo);
311 targetJointAngle = std::min<float>(targetJointAngle, jointInfo.
limitHi);
316 iterJoints->second.angle = targetJointAngle;
317 actualJointAngles[targetJointName] = iterJoints->second.angle;
327 float delta = targetJointAngle - iterJoints->second.angle;
328 float signedSmallestDelta = atan2(sin(delta), cos(delta));
329 targetJointAngle = iterJoints->second.angle + signedSmallestDelta;
332 pid->setTarget(targetJointAngle);
354 bool aValueChanged =
false;
356 for (NameValueMap::const_iterator it = targetJointVelocities.begin(); it != targetJointVelocities.end(); it++)
359 std::string targetJointName = it->first;
360 float targetJointVelocity = it->second;
362 KinematicUnitSimulationJointStates::iterator iterJoints =
jointStates.find(targetJointName);
367 if (fabs(iterJoints->second.velocity - targetJointVelocity) > 0)
369 aValueChanged =
true;
372 iterJoints->second.velocity = targetJointVelocity;
373 actualJointVelocities[targetJointName] = iterJoints->second.velocity;
387 bool aValueChanged =
false;
389 for (NameValueMap::const_iterator it = targetJointTorques.begin(); it != targetJointTorques.end(); it++)
392 std::string targetJointName = it->first;
393 float targetJointTorque = it->second;
395 KinematicUnitSimulationJointStates::iterator iterJoints =
jointStates.find(targetJointName);
400 if (fabs(iterJoints->second.torque - targetJointTorque) > 0)
402 aValueChanged =
true;
405 iterJoints->second.torque = targetJointTorque;
406 actualJointTorques[targetJointName] = iterJoints->second.torque;
418 NameControlModeMap result;
420 for (KinematicUnitSimulationJointStates::iterator it =
jointStates.begin(); it !=
jointStates.end(); it++)
422 result[it->first] = it->second.controlMode;
430 (void) targetJointAccelerations;
435 (void) targetJointDecelerations;
443 for (KinematicUnitSimulationJointStates::iterator it =
jointStates.begin(); it !=
jointStates.end(); it++)
445 it->second.velocity = 0;
483 debugInfo.jointAngles[jointName] = info.angle;
484 debugInfo.jointVelocities[jointName] = info.velocity;
486 debugInfo.jointMotorTemperatures[jointName] = info.temperature;
488 debugInfo.jointTorques[jointName] = info.torque;
489 debugInfo.jointModes[jointName] = info.controlMode;
497 bool mapEntryEqualsString(std::pair<std::string, KinematicUnitSimulationJointState> iter, std::string compareString)
499 return (iter.first == compareString);