25 #include <VirtualRobot/MathTools.h>
38 NJointControllerRegistration<NJointTaskspaceZeroTorqueOrVelocityController>
40 "NJointTaskspaceZeroTorqueOrVelocityController");
48 arm->kinematicChainName = nodeSetName;
49 VirtualRobot::RobotNodeSetPtr rtRns =
50 rtGetRobot()->getRobotNodeSet(arm->kinematicChainName);
51 VirtualRobot::RobotNodeSetPtr nonRtRns =
52 nonRtRobotPtr->getRobotNodeSet(arm->kinematicChainName);
56 <<
"Creating Taskspace Zero Torque or Velocity Controller with kinematic chain: "
57 << arm->kinematicChainName <<
" with num of joints: (RT robot) " << rtRns->getSize()
58 <<
", and (non-RT robot) " << nonRtRns->getSize();
60 std::vector<size_t> jointIDTorqueMode;
61 std::vector<size_t> jointIDVelocityMode;
62 arm->jointNames.clear();
63 for (
size_t i = 0; i < rtRns->getSize(); ++i)
66 std::string jointName = rtRns->getNode(i)->getName();
67 arm->jointNames.push_back(jointName);
69 bool foundControlDevice =
false;
71 cfg.jointNameListTorque.begin(), cfg.jointNameListTorque.end(), jointName);
72 if (it != cfg.jointNameListTorque.end())
76 auto* casted_ct = ct->
asA<ControlTarget1DoFActuatorZeroTorque>();
78 arm->targetsTorque.push_back(casted_ct);
79 jointIDTorqueMode.push_back(i);
80 foundControlDevice =
true;
84 cfg.jointNameListVelocity.begin(), cfg.jointNameListVelocity.end(), jointName);
85 if (it != cfg.jointNameListVelocity.end())
89 auto* casted_ct = ct->
asA<ControlTarget1DoFActuatorZeroVelocity>();
91 arm->targetsVel.push_back(casted_ct);
92 jointIDVelocityMode.push_back(i);
93 foundControlDevice =
true;
95 if (not foundControlDevice)
97 ARMARX_INFO << jointName <<
" is not selected for " << arm->kinematicChainName;
101 ARMARX_INFO <<
"Robot node set '" << arm->kinematicChainName
102 <<
"' has torque controlled joints [" << namesTorque
103 <<
"] and velocity controlled joints [" << namesVelocity <<
"].";
107 const auto* torqueSensor = sv->
asA<SensorValue1DoFActuatorTorque>();
108 const auto* velocitySensor = sv->
asA<SensorValue1DoFActuatorVelocity>();
109 const auto* positionSensor = sv->
asA<SensorValue1DoFActuatorPosition>();
111 if (torqueSensor ==
nullptr)
115 if (velocitySensor ==
nullptr)
117 ARMARX_WARNING <<
"No velocity sensor available for " << jointName;
119 if (positionSensor ==
nullptr)
121 ARMARX_WARNING <<
"No position sensor available for " << jointName;
125 arm->sensorDevices.torqueSensors.push_back(torqueSensor);
126 arm->sensorDevices.velocitySensors.push_back(velocitySensor);
127 arm->sensorDevices.positionSensors.push_back(positionSensor);
129 ARMARX_DEBUG <<
"Number of torque controlled joints " << jointIDTorqueMode.size();
130 ARMARX_DEBUG <<
"Number of velocity controlled joints " << jointIDVelocityMode.size();
134 arm->controller.initialize(nonRtRns, rtRns, jointIDTorqueMode, jointIDVelocityMode);
135 arm->controller.ftsensor.initialize(rtRns,
robotUnit, cfg.ftConfig);
139 arm->nonRtConfig = cfg;
143 const RobotUnitPtr& robotUnit,
144 const NJointControllerConfigPtr& config,
150 ConfigPtrT cfg = ConfigPtrT::dynamicCast(config);
152 userConfig = ::armarx::fromAronDict<ConfigDict, ConfigDict>(cfg->config);
160 limb.emplace(pair.first, std::make_unique<ArmData>());
168 return "NJointTaskspaceZeroTorqueOrVelocityController";
179 double timeMeasure = IceUtil::Time::now().toMicroSecondsDouble();
180 arm->rtConfig = arm->bufferNonRtToRt.getUpToDateReadBuffer();
181 double time_update_non_rt_buffer =
182 IceUtil::Time::now().toMicroSecondsDouble() - timeMeasure;
184 if (arm->rtFirstRun.load())
186 arm->rtFirstRun.store(
false);
187 arm->rtReady.store(
true);
189 arm->controller.ftsensor.updateStatus(
190 arm->rtConfig.ftConfig, arm->rtStatus.currentForceTorque, arm->rtStatus.deltaT, arm->rtFirstRun.load());
192 double time_update_ft = IceUtil::Time::now().toMicroSecondsDouble() - timeMeasure;
194 size_t nDoF = arm->sensorDevices.positionSensors.size();
195 double time_update_size = IceUtil::Time::now().toMicroSecondsDouble() - timeMeasure;
196 for (
size_t i = 0; i < nDoF; ++i)
198 arm->rtStatus.jointPosition[i] = arm->sensorDevices.positionSensors[i]->position;
199 arm->rtStatus.jointVelocity[i] = arm->sensorDevices.velocitySensors[i]->velocity;
200 arm->rtStatus.jointTorque[i] = arm->sensorDevices.torqueSensors[i]->torque;
203 double time_update_js = IceUtil::Time::now().toMicroSecondsDouble() - timeMeasure;
204 arm->rtStatus.deltaT = deltaT;
205 double time_update_rt_status = IceUtil::Time::now().toMicroSecondsDouble() - timeMeasure;
207 arm->bufferRtToNonRt.getWriteBuffer() = arm->rtStatus;
208 arm->bufferRtToNonRt.commitWrite();
209 arm->bufferRtStatusToUser.getWriteBuffer() = arm->rtStatus;
210 arm->bufferRtStatusToUser.commitWrite();
211 double time_write_rt_buffer = IceUtil::Time::now().toMicroSecondsDouble() - timeMeasure;
213 arm->controller.run(arm->rtConfig, arm->rtStatus);
214 double time_run_rt = IceUtil::Time::now().toMicroSecondsDouble() - timeMeasure;
216 for (
unsigned int i = 0; i < arm->rtStatus.nDoFTorque; i++)
218 auto jointIdx = arm->controller.jointIDTorqueMode[i];
219 arm->targetsTorque.at(i)->torque = arm->rtStatus.desiredJointTorques(jointIdx);
220 if (!arm->targetsTorque.at(i)->isValid())
222 arm->targetsTorque.at(i)->torque = 0;
225 for (
unsigned int i = 0; i < arm->rtStatus.nDoFVelocity; i++)
227 auto jointIdx = arm->controller.jointIDVelocityMode[i];
228 arm->targetsVel.at(i)->velocity = arm->rtStatus.desiredJointVelocity(jointIdx);
230 if (!arm->targetsVel.at(i)->isValid())
232 arm->targetsVel.at(i)->velocity = 0;
235 arm->bufferRtStatusToOnPublish.getWriteBuffer() = arm->rtStatus;
236 arm->bufferRtStatusToOnPublish.commitWrite();
238 arm->bufferRtConfigToOnPublish.getWriteBuffer() = arm->rtConfig;
239 arm->bufferRtConfigToOnPublish.commitWrite();
241 arm->bufferRtConfigToUser.getWriteBuffer() = arm->rtConfig;
242 arm->bufferRtConfigToUser.commitWrite();
243 double time_rt_status_buffer = IceUtil::Time::now().toMicroSecondsDouble() - timeMeasure;
244 timeMeasure = IceUtil::Time::now().toMicroSecondsDouble() - timeMeasure;
246 if (timeMeasure > 100)
249 "update_non_rt_buffer: %.2f\n"
251 "update_size: %.2f\n"
253 "update_rt_status: %.2f\n"
254 "write_rt_buffer: %.2f\n"
256 "rt_status_buffer: %.2f\n"
258 time_update_non_rt_buffer,
259 time_update_ft - time_update_non_rt_buffer,
260 time_update_size - time_update_ft,
261 time_update_js - time_update_size,
262 time_update_rt_status - time_update_non_rt_buffer,
263 time_write_rt_buffer - time_update_rt_status,
264 time_run_rt - time_write_rt_buffer,
265 time_rt_status_buffer - time_run_rt,
275 double deltaT = timeSinceLastIteration.toSecondsDouble();
276 for (
auto& pair :
limb)
278 limbRT(pair.second, deltaT);
285 const Ice::Current& iceCurrent)
293 limb.at(pair.first)->bufferUserToNonRt.getWriteBuffer() = pair.second;
294 limb.at(pair.first)->bufferUserToNonRt.commitWrite();
301 for (
auto& pair :
limb)
304 pair.second->bufferRtConfigToUser.getUpToDateReadBuffer();
313 const auto checkNonNegative = [](
const auto&
v) {
ARMARX_CHECK(
v >= 0); };
314 const auto checkVecNonNegative = [](
const auto&
v)
317 checkVecNonNegative(configData.kpCartesianVel);
318 checkVecNonNegative(configData.kdCartesianVel);
320 checkNonNegative(configData.torqueLimit);
321 checkNonNegative(configData.velocityLimit);
322 checkNonNegative(configData.qvelFilter);
323 checkNonNegative(configData.cartesianLinearVelLimit);
324 checkNonNegative(configData.cartesianAngularVelLimit);
333 auto rtConfig = arm->bufferRtConfigToOnPublish.getUpToDateReadBuffer();
334 auto rtStatus = arm->bufferRtStatusToOnPublish.getUpToDateReadBuffer();
339 datafields[
"velocityLimit"] =
new Variant(rtConfig.velocityLimit);
342 debugObs->setDebugChannel(
"ZT-ZV_" + arm->kinematicChainName, datafields);
351 for (
auto& pair :
limb)
360 for (
auto& pair :
limb)
362 pair.second->rtReady.store(
false);
369 VirtualRobot::RobotNodeSetPtr rns =
rtGetRobot()->getRobotNodeSet(arm->kinematicChainName);
371 arm->bufferUserToNonRt.reinitAllBuffers(arm->rtConfig);
373 arm->nonRtConfig = arm->rtConfig;
374 arm->bufferNonRtToRt.reinitAllBuffers(arm->rtConfig);
375 arm->bufferRtConfigToOnPublish.reinitAllBuffers(arm->rtConfig);
376 arm->bufferRtConfigToUser.reinitAllBuffers(arm->rtConfig);
379 const auto nDoF = rns->getSize();
380 const auto nDoFTorque = arm->controller.jointIDTorqueMode.size();
381 const auto nDoFVelocity = arm->controller.jointIDVelocityMode.size();
383 arm->rtStatus.nDoFTorque = nDoFTorque;
384 arm->rtStatus.nDoFVelocity = nDoFVelocity;
385 arm->rtStatus.numJoints = nDoF;
386 arm->rtStatus.desiredJointTorques.setZero(nDoF);
387 arm->rtStatus.desiredJointVelocity.setZero(nDoF);
388 arm->rtStatus.cartesianVelTarget.setZero();
390 arm->rtStatus.jointPosition.resize(nDoF, 0.);
391 arm->rtStatus.jointVelocity.resize(nDoF, 0.);
392 arm->rtStatus.jointTorque.resize(nDoF, 0.);
393 for (
size_t i = 0; i < nDoF; ++i)
395 arm->rtStatus.jointPosition[i] = arm->sensorDevices.positionSensors[i]->position;
396 arm->rtStatus.jointVelocity[i] = arm->sensorDevices.velocitySensors[i]->velocity;
397 arm->rtStatus.jointTorque[i] = arm->sensorDevices.torqueSensors[i]->torque;
400 arm->rtStatus.qpos = rns->getJointValuesEigen();
401 arm->rtStatus.qvel.setZero(nDoF);
402 arm->rtStatus.qvelFiltered.setZero(nDoF);
404 arm->rtStatus.currentTwist.setZero();
405 arm->rtStatus.jacobi.setZero(6, nDoF);
407 arm->rtStatus.deltaT = 0.0;
408 arm->rtStatus.rtSafe =
false;
410 arm->rtStatus.currentForceTorque.setZero();
412 arm->rtStatusInNonRT = arm->rtStatus;
413 arm->bufferRtStatusToOnPublish.reinitAllBuffers(arm->rtStatus);
414 arm->bufferRtToNonRt.reinitAllBuffers(arm->rtStatus);
415 arm->bufferRtStatusToUser.reinitAllBuffers(arm->rtStatus);
418 arm->controller.preactivateInit(rns);
424 for (
auto& pair :
limb)
426 ARMARX_INFO <<
"rtPreActivateController for " << pair.first;
428 userConfig.limbs.at(pair.first) = pair.second->rtConfig;
444 const std::map<std::string, ConstControlDevicePtr>& controlDevices,
445 const std::map<std::string, ConstSensorDevicePtr>&)
451 ::armarx::WidgetDescription::WidgetSeq widgets;
452 auto addSlider = [&](
const std::string& label,
float min,
float max,
float defaultValue)
454 widgets.emplace_back(
new Label(
false, label));
459 c_x->defaultValue = defaultValue;
461 widgets.emplace_back(c_x);
466 LabelPtr label =
new Label;
467 label->text =
"ZeroTorque (L/R)";
469 StringComboBoxPtr boxZeroTorqueLeft =
new StringComboBox;
470 boxZeroTorqueLeft->name =
"ZeroTorqueLeft";
471 boxZeroTorqueLeft->defaultIndex = 0;
472 boxZeroTorqueLeft->multiSelect =
true;
474 StringComboBoxPtr boxZeroTorqueRight =
new StringComboBox;
475 boxZeroTorqueRight->name =
"ZeroTorqueRight";
476 boxZeroTorqueRight->defaultIndex = 0;
477 boxZeroTorqueRight->multiSelect =
true;
480 LabelPtr labelZVMode =
new Label;
481 labelZVMode->text =
"ZeroVelocity (L/R)";
483 StringComboBoxPtr boxZeroVelocityLeft =
new StringComboBox;
484 boxZeroVelocityLeft->name =
"ZeroVelocityLeft";
485 boxZeroVelocityLeft->defaultIndex = 0;
486 boxZeroVelocityLeft->multiSelect =
true;
488 StringComboBoxPtr boxZeroVelocityRight =
new StringComboBox;
489 boxZeroVelocityRight->name =
"ZeroVelocityRight";
490 boxZeroVelocityRight->defaultIndex = 0;
491 boxZeroVelocityRight->multiSelect =
true;
495 std::map<std::string, StringComboBoxPtr> boxes;
496 boxes.insert({
"zv_left", boxZeroVelocityLeft});
497 boxes.insert({
"zv_right", boxZeroVelocityRight});
498 boxes.insert({
"zt_left", boxZeroTorqueLeft});
499 boxes.insert({
"zt_right", boxZeroTorqueRight});
502 for (
auto&
c : controlDevices)
505 if (
c.first.find(
"ArmL") != std::string::npos)
509 else if (
c.first.find(
"ArmR") != std::string::npos)
518 if (
c.second->hasJointController(ControlModes::ZeroTorque1DoF))
520 boxes.at(
"zt_" + mode)->options.push_back(
c.first);
522 else if (
c.second->hasJointController(ControlModes::ZeroVelocity1DoF))
524 boxes.at(
"zv_" + mode)->options.push_back(
c.first);
529 layout->children.emplace_back(label);
530 layout->children.emplace_back(boxZeroTorqueLeft);
531 layout->children.emplace_back(boxZeroTorqueRight);
532 layout->children.emplace_back(labelZVMode);
533 layout->children.emplace_back(boxZeroVelocityLeft);
534 layout->children.emplace_back(boxZeroVelocityRight);
536 addSlider(
"maxTorque", 0, 100, 10);
537 addSlider(
"maxVeloicty", 0, 3.14, 2.0);
540 layout->children.insert(layout->children.end(), widgets.begin(), widgets.end());
551 "controller_config/NJointTaskspaceZeroTorqueOrVelocityController/default.json");
553 auto cfgDTO = armarx::readFromJson<ConfigDict>(configPath.
toSystemPath());
555 ARMARX_WARNING_S <<
"Left arm of armar7 is not yet calibrated, the default is set to "
556 "RightArm for safety reason!";
558 auto varZTLeft = VariantPtr::dynamicCast(
values.at(
"ZeroTorqueLeft"));
559 auto varZTRight = VariantPtr::dynamicCast(
values.at(
"ZeroTorqueRight"));
560 auto varZVLeft = VariantPtr::dynamicCast(
values.at(
"ZeroVelocityLeft"));
561 auto varZVRight = VariantPtr::dynamicCast(
values.at(
"ZeroVelocityRight"));
567 cfgDTO.limbs.at(
"RightArm").jointNameListTorque =
569 cfgDTO.limbs.at(
"RightArm").jointNameListVelocity =
571 cfgDTO.limbs.at(
"RightArm").torqueLimit =
values.at(
"maxTorque")->getFloat();
572 cfgDTO.limbs.at(
"RightArm").velocityLimit =
values.at(
"maxVeloicty")->getFloat();
578 if (cfgDTO.limbs.at(
"RightArm").jointNameListTorque.size() > 0)
580 ARMARX_INFO_S <<
"'RightArm' has torque controlled joints [" << namesTorque <<
"].";
582 if (cfgDTO.limbs.at(
"RightArm").jointNameListVelocity.size() > 0)
584 ARMARX_INFO_S <<
"'RightArm' has velocity controlled joints [" << namesVelocity <<
"].";
587 ARMARX_INFO_S <<
"torque limit: " << cfgDTO.limbs.at(
"RightArm").torqueLimit
588 <<
"velocity limit: " << cfgDTO.limbs.at(
"RightArm").velocityLimit;
591 return new ConfigurableNJointControllerConfig{cfgDTO.toAronDTO()};