24 #include <VirtualRobot/RobotNodeSet.h>
29 #include <RobotAPI/interface/units/KinematicUnitInterface.h>
38 std::string relRobFile,
40 std::map<std::string, ActuatorData>&& newDevs,
41 std::vector<std::set<std::string>> controlDeviceHardwareControlModeGrps,
42 std::set<std::string> controlDeviceHardwareControlModeGrpsMerged,
45 std::lock_guard<std::mutex> guard{dataMutex};
51 robot->setUpdateCollisionModel(
false);
52 robot->setUpdateVisualization(
false);
53 robot->setThreadsafe(
false);
57 robotUnit = newRobotUnit;
61 relativeRobotFile = relRobFile;
63 devs = std::move(newDevs);
64 controlDeviceHardwareControlModeGroups = controlDeviceHardwareControlModeGrps;
65 controlDeviceHardwareControlModeGroupsMerged = controlDeviceHardwareControlModeGrpsMerged;
67 auto nodes = robot->getRobotNodes();
68 for (
auto& node : nodes)
70 if (node->isJoint() && !devs.count(node->getName()))
72 sensorLessJoints.push_back(node);
92 std::lock_guard<std::mutex> guard{dataMutex};
93 bool ctrlModesAValueChanged =
false;
94 bool angAValueChanged =
false;
95 bool velAValueChanged =
false;
96 bool accAValueChanged =
false;
97 bool torAValueChanged =
false;
98 bool motorCurrentAValueChanged =
false;
99 bool motorTemperaturesAValueChanged =
false;
100 bool statusesAvalueChanged =
false;
103 std::set<NJointControllerBase*> nJointCtrls{
c.nJointControllers.begin(),
104 c.nJointControllers.end()};
105 std::vector<std::string> actuatorsWithoutSensor;
106 actuatorsWithoutSensor.reserve(devs.size());
107 for (
const auto& name2actuatorData : devs)
109 const ActuatorData& actuatorData = name2actuatorData.second;
110 const auto& name = actuatorData.
name;
113 ControlMode
c = eUnknown;
114 if (actuatorData.
ctrlPos && nJointCtrls.count(actuatorData.
ctrlPos.get()))
116 c = ePositionControl;
118 if (actuatorData.
ctrlVel && nJointCtrls.count(actuatorData.
ctrlVel.get()))
121 c = eVelocityControl;
123 if (actuatorData.
ctrlTor && nJointCtrls.count(actuatorData.
ctrlTor.get()))
128 ctrlModesAValueChanged =
129 ctrlModesAValueChanged || !ctrlModes.count(name) || (ctrlModes.at(name) !=
c);
135 UpdateNameValueMap<
float,
136 SensorValue1DoFActuatorPosition,
137 &SensorValue1DoFActuatorPosition::position>(
138 ang, name,
s, angAValueChanged);
139 UpdateNameValueMap<
float,
140 SensorValue1DoFActuatorVelocity,
141 &SensorValue1DoFActuatorVelocity::velocity>(
142 vel, name,
s, velAValueChanged);
143 UpdateNameValueMap<
float,
144 SensorValue1DoFActuatorAcceleration,
145 &SensorValue1DoFActuatorAcceleration::acceleration>(
146 acc, name,
s, accAValueChanged);
147 UpdateNameValueMap<
float,
148 SensorValue1DoFActuatorTorque,
149 &SensorValue1DoFActuatorTorque::torque>(
150 tor, name,
s, torAValueChanged);
151 UpdateNameValueMap<
float,
152 SensorValue1DoFActuatorCurrent,
153 &SensorValue1DoFActuatorCurrent::motorCurrent>(
154 motorCurrents, name,
s, motorCurrentAValueChanged);
155 UpdateNameValueMap<
float,
156 SensorValue1DoFActuatorMotorTemperature,
157 &SensorValue1DoFActuatorMotorTemperature::motorTemperature>(
158 motorTemperatures, name,
s, motorTemperaturesAValueChanged);
159 UpdateNameValueMap<JointStatus,
162 statuses, name,
s, statusesAvalueChanged);
166 actuatorsWithoutSensor.emplace_back(name);
169 if (!actuatorsWithoutSensor.empty())
172 << actuatorsWithoutSensor;
176 robot->setJointValues(ang);
177 auto nodes = robot->getRobotNodes();
178 for (
auto& node : nodes)
180 node->updatePose(
false);
182 for (
auto& node : sensorLessJoints)
184 ang[node->getName()] = node->getJointValue();
190 <<
" \tcontrol modes (updated = " << ctrlModesAValueChanged <<
")\n"
191 << ang.size() <<
" \tjoint angles (updated = " << angAValueChanged <<
")\n"
192 << vel.size() <<
" \tjoint velocities (updated = " << velAValueChanged <<
")\n"
193 << acc.size() <<
" \tjoint accelerations (updated = " << accAValueChanged <<
")\n"
194 << tor.size() <<
" \tjoint torques (updated = " << torAValueChanged <<
")\n"
195 << motorCurrents.size()
196 <<
" \tmotor currents (updated = " << motorCurrentAValueChanged <<
")\n"
197 << motorTemperatures.size()
198 <<
" \tmotor temperatures (updated = " << motorTemperaturesAValueChanged <<
")\n";
199 auto prx = listenerPrx->ice_batchOneway();
200 prx->reportJointAngles(ang, timestamp, angAValueChanged);
201 prx->reportJointVelocities(vel, timestamp, velAValueChanged);
202 prx->reportJointTorques(tor, timestamp, torAValueChanged);
203 if (reportSkipper.checkFrequency(
"Meta"))
205 prx->reportJointAccelerations(acc, timestamp, accAValueChanged);
206 if (!motorCurrents.empty())
208 prx->reportJointCurrents(motorCurrents, timestamp, motorCurrentAValueChanged);
210 if (!motorTemperatures.empty())
212 prx->reportJointMotorTemperatures(
213 motorTemperatures, timestamp, motorTemperaturesAValueChanged);
215 if (!statuses.empty())
217 prx->reportJointStatuses(statuses, timestamp, statusesAvalueChanged);
219 prx->reportControlModeChanged(ctrlModes, timestamp, ctrlModesAValueChanged);
221 prx->ice_flushBatchRequests();
239 std::lock_guard<std::mutex> guard{dataMutex};
240 for (
const auto& n2v : angles)
242 if (devs.count(n2v.first))
244 if (devs.at(n2v.first).ctrlPos)
246 devs.at(n2v.first).ctrlPos->set(n2v.second);
256 std::lock_guard<std::mutex> guard{dataMutex};
257 for (
const auto& n2v : velocities)
259 if (devs.count(n2v.first))
261 if (devs.at(n2v.first).ctrlVel)
263 devs.at(n2v.first).ctrlVel->set(n2v.second);
272 std::lock_guard<std::mutex> guard{dataMutex};
273 for (
const auto& n2v : torques)
275 if (devs.count(n2v.first))
277 if (devs.at(n2v.first).ctrlTor)
279 devs.at(n2v.first).ctrlTor->set(n2v.second);
289 std::map<std::string, NJointControllerBasePtr> toActivate;
291 std::lock_guard<std::mutex> guard{dataMutex};
292 for (
const auto& n2c : ncm)
294 const std::string& name = n2c.first;
295 ControlMode mode = n2c.second;
296 if (!devs.count(name))
300 <<
"' for nonexistent device '" << name
301 <<
"'. (ignoring this device)";
304 NJointKinematicUnitPassThroughControllerPtr ctrl =
305 NJointKinematicUnitPassThroughControllerPtr::dynamicCast(
306 devs.at(name).getController(mode));
311 << name <<
"'. (ignoring this device)";
314 if (ctrl->isControllerActive())
319 toActivate[name] = std::move(ctrl);
323 for (
const auto& elem : toActivate)
325 out <<
" '" << elem.first <<
"' -> '" << elem.second->getInstanceName() <<
"'\n";
328 ARMARX_DEBUG <<
"switching control modes requests these NJointControllers (without "
329 "consideration of ControlDeviceHardwareControlModeGroups):\n"
331 for (
const auto& n2NJointCtrl : toActivate)
333 const auto& name = n2NJointCtrl.first;
335 const NJointControllerBasePtr& nJointCtrl = n2NJointCtrl.second;
336 if (!controlDeviceHardwareControlModeGroupsMerged.count(name))
341 const std::set<std::string>* group =
nullptr;
342 for (
const auto& grp : controlDeviceHardwareControlModeGroups)
351 const auto jointCtrl = nJointCtrl->getControlDevicesUsedJointController().at(name);
352 const auto hwMode = jointCtrl->getHardwareControlMode();
354 for (
const auto& other : *group)
360 if (!devs.count(other))
365 if (toActivate.count(other))
367 const auto otherJointCtrl =
368 toActivate.at(other)->getControlDevicesUsedJointController().at(other);
369 const auto otherHwMode = otherJointCtrl->getHardwareControlMode();
370 if (otherHwMode != hwMode)
372 std::stringstream strstr;
373 strstr <<
"The hardware control mode for two control devices with "
374 "requested control mode changein the same group does not match!\n"
375 <<
"Device 1: '" << name <<
"' mode "
376 <<
"'" << jointCtrl->getControlMode() <<
"' hw mode '" << hwMode
378 <<
"Device 2: '" << other <<
"' mode "
379 <<
"'" << otherJointCtrl->getControlMode() <<
"' hw mode '"
380 << otherHwMode <<
"'\n";
382 throw InvalidArgumentException{strstr.str()};
388 const auto otherNJointCtrl = devs.at(other).getActiveController();
389 const auto otherJointCtrl =
391 ? otherNJointCtrl->getControlDevicesUsedJointController().at(other)
393 const auto otherHwMode =
394 otherJointCtrl ? otherJointCtrl->getHardwareControlMode() :
"";
395 if (hwMode != otherHwMode)
397 toActivate[other] = std::move(devs.at(other).getController(ncm.at(name)));
400 ->getControlDevicesUsedJointController()
402 ->getHardwareControlMode() == hwMode);
404 <<
"' caused activation of '"
405 << toActivate.at(name)->getInstanceName() <<
"'";
409 ARMARX_DEBUG <<
"checking group of '" << name <<
"'...done!";
411 ARMARX_DEBUG <<
"switching control modes requests these NJointControllers (with "
412 "consideration of ControlDeviceHardwareControlModeGroups):\n"
417 if (!toActivate.empty())
419 robotUnit->activateNJointControllers(
getMapValues(toActivate));
435 armarx::NameControlModeMap
438 std::lock_guard<std::mutex> guard{dataMutex};
445 std::lock_guard<std::mutex> guard{dataMutex};
452 std::lock_guard<std::mutex> guard{dataMutex};
459 std::lock_guard<std::mutex> guard{dataMutex};
466 std::lock_guard<std::mutex> guard{dataMutex};
468 armarx::DebugInfo debugInfo{.jointModes = ctrlModes,
470 .jointVelocities = vel,
471 .jointAccelerations = acc,
473 .jointCurrents = motorCurrents,
474 .jointMotorTemperatures = motorTemperatures,
475 .jointStatus = statuses};
485 case ePositionVelocityControl:
487 case ePositionControl:
489 case eVelocityControl:
501 if (ctrlPos->isControllerActive())
505 if (ctrlVel->isControllerActive())
509 if (ctrlTor->isControllerActive())