KinematicUnitDynamicSimulation.cpp
Go to the documentation of this file.
1 /*
2  * This file is part of ArmarX.
3  *
4  * Copyright (C) 2013-2016, High Performance Humanoid Technologies (H2T), Karlsruhe Institute of Technology (KIT), all rights reserved.
5  *
6  * ArmarX is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License version 2 as
8  * published by the Free Software Foundation.
9  *
10  * ArmarX is distributed in the hope that it will be useful, but
11  * WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13  * GNU General Public License for more details.
14  *
15  * You should have received a copy of the GNU General Public License
16  * along with this program. If not, see <http://www.gnu.org/licenses/>.
17  *
18  * @package ArmarXSimulation::ArmarXObjects::KinematicUnitDynamicSimulation
19  * @author Nikolaus ( vahrenkamp at kit dot edu )
20  * @date 2013
21  * @copyright http://www.gnu.org/licenses/gpl-2.0.txt
22  * GNU General Public License
23  */
24 
26 
27 #include <VirtualRobot/VirtualRobot.h>
28 #include <VirtualRobot/XML/RobotIO.h>
29 #include <VirtualRobot/RobotNodeSet.h>
30 #include <VirtualRobot/Nodes/RobotNode.h>
31 #include <VirtualRobot/VirtualRobotException.h>
33 
34 #include <algorithm>
35 
36 using namespace armarx;
37 
38 
40 {
41  ARMARX_VERBOSE << "Init with RNS " << robotNodeSetName << std::endl;
42 
43  for (auto& robotNode : robotNodes)
44  {
45  std::string jointName = robotNode->getName();
46  ARMARX_VERBOSE << "* " << jointName << flush;
47  nodeNames.insert(jointName);
48  }
49 
50  if (robot)
51  {
52  robotTopicName = "Simulator_Robot_";
53  robotName = hasProperty("RobotName") ? getProperty<std::string>("RobotName") : robot->getName();
55  ARMARX_INFO << "Simulator Robot topic: " << robotTopicName << std::endl;
57  }
58  else
59  {
60  ARMARX_WARNING << "No robot loaded..." << std::endl;
61  }
62 
63  mapVelToPosVel = getProperty<bool>("MapVelocityToPositionVelocity").getValue();
64 
65  simulatorPrxName = getProperty<std::string>("SimulatorName").getValue();
67 }
68 
70 {
71  // subscribe topic in order to receive the simulator reports
72  ARMARX_INFO << "Using simulator proxy: " << simulatorPrxName << flush;
73  simulatorPrx = getProxy<SimulatorInterfacePrx>(simulatorPrxName);
74 
75  // periodic task setup
76  cycleTime = 1000.f / getProperty<float>("ControlFrequency").getValue();
77 
78  if (execTask)
79  {
80  execTask->stop();
81  }
82 
84  execTask->start();
85  execTask->setDelayWarningTolerance(100);
86 }
87 
88 
90 {
91  if (execTask)
92  {
93  execTask->stop();
94  }
95 }
96 
97 void KinematicUnitDynamicSimulation::reportState(SimulatedRobotState const& state, const Ice::Current&)
98 {
99  NameValueMap angleValues;
100  NameValueMap velocitiyValues;
101  NameValueMap torqueValues;
102 
103  {
104  // Calculate results with lock, publish later without lock
105  std::scoped_lock scoped_lock(accessMutex);
106 
107  // Joint angles
108  if (state.jointAngles.size() > 0)
109  {
110  // check which joints are covered
111  for (const auto& actualJointAngle : state.jointAngles)
112  {
113  if (nodeNames.find(actualJointAngle.first) != nodeNames.end())
114  {
115  angleValues[actualJointAngle.first] = actualJointAngle.second;
116  }
117 
118  currentJointValues[actualJointAngle.first] = actualJointAngle.second;
119  }
120 
121 
122  }
123 
124  // Joint velocities
125  // check which jonts are covered
126  for (const auto& actualVelocity : state.jointVelocities)
127  {
128  if (nodeNames.find(actualVelocity.first) != nodeNames.end())
129  {
130  velocitiyValues[actualVelocity.first] = actualVelocity.second;
131  }
132  }
133 
134  // Joint torques
135  // check which jonts are covered
136  for (const auto& actualJointTorque : state.jointTorques)
137  {
138  if (nodeNames.find(actualJointTorque.first) != nodeNames.end())
139  {
140  torqueValues[actualJointTorque.first] = actualJointTorque.second;
141  }
142  }
143  }
144 
145  // FIXME: Use Ice batching to optimize
146  if (angleValues.size() > 0)
147  {
148  listenerPrx->reportJointAngles(angleValues, state.timestampInMicroSeconds, true);
149  }
150  if (velocitiyValues.size() > 0)
151  {
152  listenerPrx->reportJointVelocities(velocitiyValues, state.timestampInMicroSeconds, true);
153  }
154  if (torqueValues.size() > 0)
155  {
156  listenerPrx->reportJointTorques(torqueValues, state.timestampInMicroSeconds, true);
157  }
158 }
159 
160 NameControlModeMap KinematicUnitDynamicSimulation::getControlModes(const Ice::Current& c)
161 {
162  NameControlModeMap result;
163 
164  for (const auto& nodeName : nodeNames)
165  {
166  auto c = currentControlModes.find(nodeName);
167 
168  // if not specified, we assume position control
169  if (c == currentControlModes.end())
170  {
171  result[nodeName] = ePositionControl;
172  }
173  else
174  {
175  result[nodeName] = c->second;
176  }
177  }
178 
179  return result;
180 }
181 
182 
183 void KinematicUnitDynamicSimulation::switchControlMode(const NameControlModeMap& targetJointModes, const Ice::Current& c)
184 {
185  std::scoped_lock scoped_lock(accessMutex);
186 
187  //currentControlModes = targetJointModes;
188  NameControlModeMap::const_iterator itAng = targetJointModes.begin();
189 
190  while (itAng != targetJointModes.end())
191  {
192  currentControlModes[itAng->first] = itAng->second;
193  itAng++;
194  }
195 
196  listenerPrx->reportControlModeChanged(targetJointModes, IceUtil::Time::now().toMicroSeconds(), true);
197 
198 }
199 
200 void KinematicUnitDynamicSimulation::setJointAngles(const NameValueMap& targetJointAngles, const Ice::Current& c)
201 {
202  std::scoped_lock scoped_lock(accessMutex);
203 
204 
205 
206  // store current joint angles
207  NameValueMap::const_iterator itAng = targetJointAngles.begin();
208 
209  while (itAng != targetJointAngles.end())
210  {
211  currentJointTargets[itAng->first] = itAng->second;
212  itAng++;
213  }
214 }
215 
216 void KinematicUnitDynamicSimulation::setJointVelocities(const NameValueMap& targetJointVelocities, const Ice::Current& c)
217 {
218  std::scoped_lock scoped_lock(accessMutex);
219  NameValueMap::const_iterator itVel = targetJointVelocities.begin();
220 
221  while (itVel != targetJointVelocities.end())
222  {
223  currentJointVelTargets[itVel->first] = itVel->second;
224  itVel++;
225  }
226 }
227 
228 void KinematicUnitDynamicSimulation::setJointTorques(const NameValueMap& targetJointTorques, const Ice::Current& c)
229 {
230  std::scoped_lock scoped_lock(accessMutex);
231 
232  // store current joint torques
233  NameValueMap::const_iterator itAng = targetJointTorques.begin();
234 
235  while (itAng != targetJointTorques.end())
236  {
237  currentJointTorqueTargets[itAng->first] = itAng->second;
238  itAng++;
239  }
240 }
241 
242 void KinematicUnitDynamicSimulation::setJointAccelerations(const NameValueMap& targetJointAccelerations, const Ice::Current& c)
243 {
244 }
245 
246 void KinematicUnitDynamicSimulation::setJointDecelerations(const NameValueMap& targetJointDecelerations, const Ice::Current& c)
247 {
248 }
249 
250 
251 
252 void KinematicUnitDynamicSimulation::requestJoints(const Ice::StringSeq& joints, const Ice::Current& c)
253 {
254  std::scoped_lock scoped_lock(accessMutex);
255 
256  // if one of the joints belongs to this unit, lock access to this unit for other components except for the requesting one
257  for (const auto& joint : joints)
258  {
259  if (nodeNames.find(joint) != nodeNames.end())
260  {
262  return;
263  }
264  }
265 }
266 
267 void KinematicUnitDynamicSimulation::releaseJoints(const Ice::StringSeq& joints, const Ice::Current& c)
268 {
269  std::scoped_lock scoped_lock(accessMutex);
270 
271  // if one of the joints belongs to this unit, unlock access
272  for (const auto& joint : joints)
273  {
274  if (nodeNames.find(joint) != nodeNames.end())
275  {
277  return;
278  }
279  }
280 
281 }
282 
283 
285 {
286  if (!simulatorPrx)
287  {
288  return;
289  }
290 
291  float loopTime = (float)execTask->getInterval() / 1000.0f; // in s
292  float factorLoopTime = 1.1f;
293 
294  {
295  std::scoped_lock lock(accessMutex);
296 
297  NameValueMap applyPosMap;
298  NameValueMap applyVelMap;
299  NameValueMap applyPosVelMap_pos;
300  NameValueMap applyPosVelMap_vel;
301  NameValueMap applyTorMap;
302  NameControlModeMap::const_iterator itMode = currentControlModes.begin();
303 
304  while (itMode != currentControlModes.end())
305  {
306  switch (itMode->second)
307  {
308  case ePositionControl:
309  if (currentJointTargets.find(itMode->first) != currentJointTargets.end())
310  {
311  applyPosMap[itMode->first] = currentJointTargets.find(itMode->first)->second;
312  }
313 
314  break;
315 
316  case eVelocityControl:
317  {
318  auto it = currentJointVelTargets.find(itMode->first);
319  if (it != currentJointVelTargets.end())
320  {
321  if (mapVelToPosVel)
322  {
323  // compute pos
324  if (currentJointValues.find(itMode->first) != currentJointValues.end())
325  {
326  float posTarget = currentJointValues[itMode->first] + it->second * loopTime * factorLoopTime;
327  applyPosVelMap_pos[itMode->first] = posTarget;
328  applyPosVelMap_vel[itMode->first] = it->second;
329  }
330  }
331  else
332  {
333  // just use velocity
334  applyVelMap[itMode->first] = currentJointVelTargets.find(itMode->first)->second;
335  }
336  }
337  }
338 
339  break;
340 
341  case eTorqueControl:
342  if (currentJointTorqueTargets.find(itMode->first) != currentJointTorqueTargets.end())
343  {
344  applyTorMap[itMode->first] = currentJointTorqueTargets.find(itMode->first)->second;
345  }
346 
347  break;
348 
349  case ePositionVelocityControl:
350  if (currentJointVelTargets.find(itMode->first) != currentJointVelTargets.end() &&
351  currentJointTargets.find(itMode->first) != currentJointTargets.end())
352  {
353  applyPosVelMap_pos[itMode->first] = currentJointTargets.find(itMode->first)->second;
354  applyPosVelMap_vel[itMode->first] = currentJointVelTargets.find(itMode->first)->second;
355  }
356 
357  break;
358 
359  case eUnknown:
360  case eDisabled:
361  default:
362  // do nothing
363  ;
364  }
365 
366  itMode++;
367  }
368  auto batchPrx = simulatorPrx->ice_batchOneway();
369  if (applyPosMap.size() > 0)
370  {
371  batchPrx->actuateRobotJointsPos(robotName, applyPosMap);
372  }
373 
374  if (applyVelMap.size() > 0)
375  {
376  batchPrx->actuateRobotJointsVel(robotName, applyVelMap);
377  }
378 
379  if (applyTorMap.size() > 0)
380  {
381  batchPrx->actuateRobotJointsTorque(robotName, applyTorMap);
382  }
383 
384  if (applyPosVelMap_pos.size() > 0)
385  {
386  batchPrx->actuateRobotJoints(robotName, applyPosVelMap_pos, applyPosVelMap_vel);
387  }
388  batchPrx->ice_flushBatchRequests();
389 
390  // command only once
391  if (!mapVelToPosVel) // dont clear this in pos-velo mode because it is needed to calculate next position target
392  {
393  currentJointVelTargets.clear();
394  }
395  currentJointTargets.clear();
397  }
398 }
399 
400 
401 armarx::DebugInfo
403 {
404  const ::armarx::SimulatedRobotState robotState = simulatorPrx->getRobotState(robotName);
405 
406  ::armarx::NameStatusMap jointStatus;
407  for (const auto& [jointName, _] : currentControlModes)
408  {
409  jointStatus[jointName] = {
410  .operation = eOnline,
411  .error = eOk,
412  .enabled = true,
413  .emergencyStop = false // TODO: implement
414  };
415  }
416 
417  return {.jointModes = currentControlModes,
418  .jointAngles = robotState.jointAngles,
419  .jointVelocities = robotState.jointVelocities,
420  .jointAccelerations = {}, // not available
421  .jointTorques = robotState.jointTorques,
422  .jointCurrents = {}, // not available
423  .jointMotorTemperatures = {}, // not available
424  .jointStatus = jointStatus};
425 }
ARMARX_VERBOSE
#define ARMARX_VERBOSE
Definition: Logging.h:180
armarx::KinematicUnitDynamicSimulation::execTask
PeriodicTask< KinematicUnitDynamicSimulation >::pointer_type execTask
Definition: KinematicUnitDynamicSimulation.h:116
armarx::KinematicUnitDynamicSimulation::currentControlModes
NameControlModeMap currentControlModes
Definition: KinematicUnitDynamicSimulation.h:138
armarx::KinematicUnitDynamicSimulation::periodicExec
void periodicExec()
Definition: KinematicUnitDynamicSimulation.cpp:284
armarx::KinematicUnitDynamicSimulation::currentJointTargets
NameValueMap currentJointTargets
Definition: KinematicUnitDynamicSimulation.h:135
armarx::SensorActorUnit::release
void release(const Ice::Current &c=Ice::emptyCurrent) override
Release exclusive access to current unit.
Definition: SensorActorUnit.cpp:141
armarx::KinematicUnitDynamicSimulation::mapVelToPosVel
bool mapVelToPosVel
Definition: KinematicUnitDynamicSimulation.h:144
armarx::KinematicUnit::robotNodeSetName
std::string robotNodeSetName
Definition: KinematicUnit.h:145
armarx::KinematicUnitDynamicSimulation::robotTopicName
std::string robotTopicName
Definition: KinematicUnitDynamicSimulation.h:132
armarx::KinematicUnitDynamicSimulation::onExitKinematicUnit
void onExitKinematicUnit() override
Definition: KinematicUnitDynamicSimulation.cpp:89
armarx::SensorActorUnit::request
void request(const Ice::Current &c=Ice::emptyCurrent) override
Request exclusive access to current unit.
Definition: SensorActorUnit.cpp:123
armarx::KinematicUnitDynamicSimulation::onStartKinematicUnit
void onStartKinematicUnit() override
Definition: KinematicUnitDynamicSimulation.cpp:69
c
constexpr T c
Definition: UnscentedKalmanFilterTest.cpp:43
armarx::KinematicUnitDynamicSimulation::currentJointValues
NameValueMap currentJointValues
Definition: KinematicUnitDynamicSimulation.h:142
armarx::KinematicUnitDynamicSimulation::accessMutex
std::recursive_mutex accessMutex
Definition: KinematicUnitDynamicSimulation.h:146
armarx::PropertyUser::hasProperty
bool hasProperty(const std::string &name)
Definition: PropertyUser.cpp:243
armarx::KinematicUnitDynamicSimulation::simulatorPrx
SimulatorInterfacePrx simulatorPrx
Definition: KinematicUnitDynamicSimulation.h:148
KinematicUnitDynamicSimulation.h
armarx::KinematicUnitDynamicSimulation::requestJoints
void requestJoints(const Ice::StringSeq &joints, const Ice::Current &c=Ice::emptyCurrent) override
Definition: KinematicUnitDynamicSimulation.cpp:252
armarx::KinematicUnitDynamicSimulation::setJointAngles
void setJointAngles(const NameValueMap &targetJointAngles, const Ice::Current &c=Ice::emptyCurrent) override
Definition: KinematicUnitDynamicSimulation.cpp:200
armarx::KinematicUnitDynamicSimulation::getDebugInfo
DebugInfo getDebugInfo(const Ice::Current &c=Ice::emptyCurrent) const override
Definition: KinematicUnitDynamicSimulation.cpp:402
armarx::KinematicUnitDynamicSimulation::currentJointTorqueTargets
NameValueMap currentJointTorqueTargets
Definition: KinematicUnitDynamicSimulation.h:137
armarx::KinematicUnitDynamicSimulation::setJointAccelerations
void setJointAccelerations(const NameValueMap &targetJointAccelerations, const Ice::Current &c=Ice::emptyCurrent) override
Definition: KinematicUnitDynamicSimulation.cpp:242
armarx::KinematicUnitDynamicSimulation::switchControlMode
void switchControlMode(const NameControlModeMap &targetJointModes, const Ice::Current &c=Ice::emptyCurrent) override
Definition: KinematicUnitDynamicSimulation.cpp:183
armarx::KinematicUnitDynamicSimulation::currentJointVelTargets
NameValueMap currentJointVelTargets
Definition: KinematicUnitDynamicSimulation.h:136
armarx::flush
const LogSender::manipulator flush
Definition: LogSender.h:251
armarx::KinematicUnitDynamicSimulation::releaseJoints
void releaseJoints(const Ice::StringSeq &joints, const Ice::Current &c=Ice::emptyCurrent) override
Definition: KinematicUnitDynamicSimulation.cpp:267
armarx::KinematicUnitDynamicSimulation::setJointDecelerations
void setJointDecelerations(const NameValueMap &targetJointDecelerations, const Ice::Current &c=Ice::emptyCurrent) override
Definition: KinematicUnitDynamicSimulation.cpp:246
armarx::KinematicUnitDynamicSimulation::simulatorPrxName
std::string simulatorPrxName
Definition: KinematicUnitDynamicSimulation.h:133
armarx::KinematicUnit::robotNodes
std::vector< VirtualRobot::RobotNodePtr > robotNodes
Definition: KinematicUnit.h:147
armarx::KinematicUnitDynamicSimulation::robotName
std::string robotName
Definition: KinematicUnitDynamicSimulation.h:131
armarx::KinematicUnitDynamicSimulation::cycleTime
int cycleTime
Definition: KinematicUnitDynamicSimulation.h:140
armarx::control::njoint_controller::platform::platform_follower_controller::NameValueMap
std::map< std::string, float > NameValueMap
Definition: PlatformFollowerController.h:91
armarx::ManagedIceObject::usingTopic
void usingTopic(const std::string &name, bool orderedPublishing=false)
Registers a proxy for subscription after initialization.
Definition: ManagedIceObject.cpp:248
armarx::KinematicUnitDynamicSimulation::setJointVelocities
void setJointVelocities(const NameValueMap &targetJointVelocities, const Ice::Current &c=Ice::emptyCurrent) override
Definition: KinematicUnitDynamicSimulation.cpp:216
armarx::KinematicUnit::listenerPrx
KinematicUnitListenerPrx listenerPrx
Definition: KinematicUnit.h:141
float
#define float
Definition: 16_Level.h:22
ARMARX_INFO
#define ARMARX_INFO
Definition: Logging.h:174
armarx::KinematicUnitDynamicSimulation::getControlModes
NameControlModeMap getControlModes(const Ice::Current &c=Ice::emptyCurrent) override
Definition: KinematicUnitDynamicSimulation.cpp:160
armarx::KinematicUnitDynamicSimulation::onInitKinematicUnit
void onInitKinematicUnit() override
Definition: KinematicUnitDynamicSimulation.cpp:39
armarx::PeriodicTask
Definition: ArmarXManager.h:70
ARMARX_WARNING
#define ARMARX_WARNING
Definition: Logging.h:186
ArmarXDataPath.h
armarx::KinematicUnitDynamicSimulation::nodeNames
std::set< std::string > nodeNames
Definition: KinematicUnitDynamicSimulation.h:130
armarx::ManagedIceObject::usingProxy
bool usingProxy(const std::string &name, const std::string &endpoints="")
Registers a proxy for retrieval after initialization and adds it to the dependency list.
Definition: ManagedIceObject.cpp:151
armarx::KinematicUnit::robot
VirtualRobot::RobotPtr robot
Definition: KinematicUnit.h:144
armarx
This file offers overloads of toIce() and fromIce() functions for STL container types.
Definition: ArmarXTimeserver.cpp:28
armarx::KinematicUnitDynamicSimulation::reportState
void reportState(SimulatedRobotState const &state, const Ice::Current &) override
Definition: KinematicUnitDynamicSimulation.cpp:97
armarx::KinematicUnitDynamicSimulation::setJointTorques
void setJointTorques(const NameValueMap &targetJointTorques, const Ice::Current &c=Ice::emptyCurrent) override
Definition: KinematicUnitDynamicSimulation.cpp:228