25 #include <VirtualRobot/MathTools.h>
26 #include <VirtualRobot/Nodes/RobotNode.h>
27 #include <VirtualRobot/RobotNodeSet.h>
47 "NJointTaskspaceAdmittanceController");
55 arm->kinematicChainName = nodeSetName;
56 VirtualRobot::RobotNodeSetPtr rtRns =
57 rtGetRobot()->getRobotNodeSet(arm->kinematicChainName);
58 VirtualRobot::RobotNodeSetPtr nonRtRns =
59 nonRtRobotPtr->getRobotNodeSet(arm->kinematicChainName);
62 ARMARX_IMPORTANT <<
"Creating Taskspace Impedance controller with kinematic chain: "
63 << arm->kinematicChainName <<
" with num of joints: (RT robot) "
64 << rtRns->getSize() <<
", and (non-RT robot) " << nonRtRns->getSize();
66 arm->controller.initialize(nonRtRns, rtRns);
67 arm->controller.ftsensor.initialize(rtRns,
robotUnit, cfg.ftConfig);
68 arm->jointNames.clear();
69 for (
size_t i = 0; i < rtRns->getSize(); ++i)
71 std::string jointName = rtRns->getNode(i)->getName();
72 arm->jointNames.push_back(jointName);
76 auto* casted_ct = ct->
asA<ControlTarget1DoFActuatorTorque>();
78 arm->targets.push_back(casted_ct);
82 arm->sensorDevices.append(sv, jointName);
87 arm->nonRtConfig = cfg;
88 arm->rtStatus.reset(rtRns->getSize());
93 const NJointControllerConfigPtr& config,
99 ConfigPtrT cfg = ConfigPtrT::dynamicCast(config);
109 limb.emplace(pair.first, std::make_unique<ArmData>());
119 for (
auto& jointName :
hands->hands.at(pair.first)->jointNames)
121 hands->appendDevice(pair.first,
127 <<
hands->hands.at(pair.first)->kinematicChainName;
136 return "NJointTaskspaceAdmittanceController";
142 std::string taskName =
getClassName() +
"AdditionalTask";
154 while (
getState() == eManagedIceObjectStarted)
160 c.waitForCycleDuration();
168 arm->bufferConfigNonRtToRt.getWriteBuffer() = arm->nonRtConfig;
169 arm->bufferConfigNonRtToRt.commitWrite();
188 for (
auto& pair :
limb)
190 auto& arm = pair.second;
191 arm->nonRtConfig = arm->bufferConfigUserToNonRt.getUpToDateReadBuffer();
192 arm->rtStatusInNonRT = arm->bufferRtStatusToNonRt.getUpToDateReadBuffer();
193 rtSafe = rtSafe and pair.second->rtStatusInNonRT.rtSafe;
197 hands->nonRTUpdateStatus();
205 for (
auto& pair :
limb)
211 hands->nonRTSetTarget();
218 for (
auto& pair :
limb)
220 if (not pair.second->rtReady)
223 if (not pair.second->rtStatusInNonRT.rtTargetSafe)
225 pair.second->rtStatusInNonRT =
226 pair.second->bufferRtStatusToNonRt.getUpToDateReadBuffer();
228 pair.second->rtStatusInNonRT.currentPose,
229 pair.second->nonRtConfig.desiredPose,
240 arm->rtConfig = arm->bufferConfigNonRtToRt.getUpToDateReadBuffer();
241 arm->rtStatus.deltaT = deltaT;
242 arm->rtStatus.accumulateTime += deltaT;
244 if (arm->rtFirstRun.load())
246 arm->controller.firstRun();
249 arm->controller.ftsensor.updateStatus(arm->rtConfig.ftConfig,
250 arm->rtStatus.currentForceTorque,
251 arm->rtStatus.deltaT,
252 arm->rtFirstRun.load());
254 arm->sensorDevices.updateJointValues(
255 arm->rtStatus.jointPos, arm->rtStatus.jointVel, arm->rtStatus.jointTor);
258 arm->bufferRtStatusToNonRt.getWriteBuffer() = arm->rtStatus;
259 arm->bufferRtStatusToNonRt.commitWrite();
260 arm->bufferRtStatusToUser.getWriteBuffer() = arm->rtStatus;
261 arm->bufferRtStatusToUser.commitWrite();
266 const Eigen::VectorXf& targetTorque)
268 for (
unsigned int i = 0; i < targetTorque.size(); i++)
270 arm->targets.at(i)->torque = targetTorque(i);
271 if (!arm->targets.at(i)->isValid())
273 arm->targets.at(i)->torque = 0;
276 arm->bufferRtStatusToOnPublish.getWriteBuffer() = arm->rtStatus;
277 arm->bufferRtStatusToOnPublish.commitWrite();
279 arm->bufferConfigRtToOnPublish.getWriteBuffer() = arm->rtConfig;
280 arm->bufferConfigRtToOnPublish.commitWrite();
282 arm->bufferConfigRtToUser.getWriteBuffer() = arm->rtConfig;
283 arm->bufferConfigRtToUser.commitWrite();
285 if (arm->rtFirstRun.load())
287 arm->rtFirstRun.store(
false);
288 arm->rtReady.store(
true);
295 double time_measure = IceUtil::Time::now().toMicroSecondsDouble();
297 double time_update_status = IceUtil::Time::now().toMicroSecondsDouble() - time_measure;
299 arm->controller.run(arm->rtConfig, arm->rtStatus);
300 double time_run_rt = IceUtil::Time::now().toMicroSecondsDouble() - time_measure;
304 double time_set_target = IceUtil::Time::now().toMicroSecondsDouble() - time_measure;
305 time_measure = IceUtil::Time::now().toMicroSecondsDouble() - time_measure;
307 if (time_measure > 100)
310 "time_update_status: %.2f\n"
311 "run_rt_limb: %.2f\n"
312 "set_target_limb: %.2f\n"
315 time_run_rt - time_update_status,
316 time_set_target - time_run_rt,
318 .deactivateSpam(1.0f);
326 double deltaT = timeSinceLastIteration.toSecondsDouble();
327 for (
auto& pair :
limb)
329 limbRT(pair.second, deltaT);
333 hands->updateRTStatus(deltaT);
341 const Ice::Current& iceCurrent)
350 pair.second.desiredPose,
351 prevCfg.limbs.at(pair.first).desiredPose,
353 "previous desired pose",
354 pair.second.safeDistanceMMToGoal,
355 pair.second.safeRotAngleDegreeToGoal,
356 "updateConfig_" + pair.first))
359 pair.second.desiredPose = prevCfg.limbs.at(pair.first).desiredPose;
361 limb.at(pair.first)->bufferConfigUserToNonRt.getWriteBuffer() = pair.second;
362 limb.at(pair.first)->bufferConfigUserToNonRt.commitWrite();
373 for (
auto& pair :
limb)
376 pair.second->bufferConfigRtToUser.getUpToDateReadBuffer();
387 const bool forceGuard,
388 const bool torqueGuard,
389 const Ice::Current& iceCurrent)
394 it->second.ftConfig.enableSafeGuardForce = forceGuard;
395 it->second.ftConfig.enableSafeGuardTorque = torqueGuard;
396 limb.at(nodeSetName)->controller.ftsensor.enableSafeGuard(forceGuard, torqueGuard);
398 <<
"reset safe guard with force torque sensors: safe? "
399 <<
limb.at(nodeSetName)->controller.ftsensor.isSafe(it->second.ftConfig);
400 limb.at(nodeSetName)->bufferConfigUserToNonRt.getWriteBuffer() = it->second;
401 limb.at(nodeSetName)->bufferConfigUserToNonRt.commitWrite();
406 <<
" found in the controllers.";
413 const Ice::Current& iceCurrent)
418 return limb.at(nodeSetName)->controller.ftsensor.ftSafe.load();
423 <<
" found in the controllers.";
430 const Ice::Current& iceCurrent)
432 std::vector<float> tcpVel;
433 auto& arm =
limb.at(rns);
434 auto s = arm->bufferRtStatusToUser.getUpToDateReadBuffer();
435 for (
int i = 0; i <
s.currentTwist.size(); i++)
437 tcpVel.push_back(
s.currentTwist[i]);
446 const Ice::Current& iceCurrent)
450 for (
size_t i = 0; i < 4; ++i)
452 for (
int j = 0; j < 4; ++j)
454 pair.second.desiredPose(i, j) = targetPoseMap.at(pair.first)[i][j];
457 if (targetNullspaceMap.at(pair.first).size() > 0)
459 const size_t nDoF = pair.second.desiredNullspaceJointAngles.value().size();
461 <<
"the joint numbers does not match";
462 for (
size_t i = 0; i < nDoF; ++i)
464 pair.second.desiredNullspaceJointAngles.value()(i) =
465 targetNullspaceMap.at(pair.first)[i];
468 limb.at(pair.first)->bufferConfigUserToNonRt.getWriteBuffer() = pair.second;
469 limb.at(pair.first)->bufferConfigUserToNonRt.commitWrite();
477 const auto nDoF = arm->controller.numOfJoints;
480 const auto checkNonNegative = [](
const auto&
v) {
ARMARX_CHECK((
v.array() >= 0).all()); };
482 if (!configData.desiredNullspaceJointAngles.has_value())
486 ARMARX_INFO <<
"No user defined nullspace target, reset to zero with "
488 configData.desiredNullspaceJointAngles = Eigen::VectorXf::Zero(nDoF);
489 arm->reInitPreActivate.store(
true);
494 arm->bufferConfigRtToUser.getUpToDateReadBuffer().desiredNullspaceJointAngles;
496 <<
"Controller is active, but no user defined nullspace target. \n"
497 "You should first get up-to-date config of this controller and then update "
499 " auto cfg = ctrl->getConfig(); \n"
500 " cfg.desiredPose = xxx;\n"
501 " ctrl->updateConfig(cfg);\n"
502 "Now, I decide by myself to use the existing values of nullspace target\n"
503 << currentValue.value();
504 configData.desiredNullspaceJointAngles = currentValue;
508 checkSize(configData.desiredNullspaceJointAngles.value());
509 checkSize(configData.kdNullspace);
510 checkSize(configData.kpNullspace);
512 checkNonNegative(configData.kdNullspace);
513 checkNonNegative(configData.kpNullspace);
514 checkNonNegative(configData.kdImpedance);
515 checkNonNegative(configData.kpImpedance);
523 auto rtData = arm->bufferConfigRtToOnPublish.getUpToDateReadBuffer();
524 auto rtStatus = arm->bufferRtStatusToOnPublish.getUpToDateReadBuffer();
540 debugObs->setDebugChannel(
getClassName() +
"_" + arm->kinematicChainName, datafields);
548 for (
auto& pair :
limb)
550 if (not pair.second->rtReady.load())
559 for (
auto& pair :
limb)
561 pair.second->rtReady.store(
false);
569 for (
auto& pair :
limb)
571 pair.second->rtReady.store(
false);
578 VirtualRobot::RobotNodeSetPtr rns =
rtGetRobot()->getRobotNodeSet(arm->kinematicChainName);
579 const auto& currentPose = rns->getTCP()->getPoseInRootFrame();
580 auto quat = VirtualRobot::MathTools::eigen4f2quat(currentPose);
582 "[ %.2f, %.2f, %.2f, %.2f, %.2f, %.2f, %.2f ].",
591 if (arm->reInitPreActivate.load())
593 arm->rtConfig.desiredNullspaceJointAngles.value() = rns->getJointValuesEigen();
594 arm->rtConfig.desiredPose = currentPose;
596 arm->bufferConfigUserToNonRt.reinitAllBuffers(arm->rtConfig);
597 arm->reInitPreActivate.store(
false);
600 arm->nonRtConfig = arm->rtConfig;
601 arm->bufferConfigNonRtToRt.reinitAllBuffers(arm->rtConfig);
602 arm->bufferConfigRtToOnPublish.reinitAllBuffers(arm->rtConfig);
603 arm->bufferConfigRtToUser.reinitAllBuffers(arm->rtConfig);
606 arm->sensorDevices.updateJointValues(
607 arm->rtStatus.jointPos, arm->rtStatus.jointVel, arm->rtStatus.jointTor);
608 arm->rtStatus.rtPreActivate(currentPose);
610 arm->rtStatusInNonRT = arm->rtStatus;
611 arm->nonRTDeltaT = 0.0;
612 arm->nonRTAccumulateTime = 0.0;
613 arm->bufferRtStatusToOnPublish.reinitAllBuffers(arm->rtStatus);
614 arm->bufferRtStatusToNonRt.reinitAllBuffers(arm->rtStatus);
615 arm->bufferRtStatusToUser.reinitAllBuffers(arm->rtStatus);
618 arm->controller.preactivateInit(rns);
624 for (
auto& pair :
limb)
628 userConfig.limbs.at(pair.first) = pair.second->rtConfig;
632 hands->rtPreActivate();
649 const std::map<std::string, ConstControlDevicePtr>& controlDevices,
650 const std::map<std::string, ConstSensorDevicePtr>&)
656 ::armarx::WidgetDescription::WidgetSeq widgets;
659 LabelPtr label =
new Label;
660 label->text =
"select a controller config";
662 StringComboBoxPtr cfgBox =
new StringComboBox;
663 cfgBox->name =
"config_box";
664 cfgBox->defaultIndex = 0;
665 cfgBox->multiSelect =
false;
667 cfgBox->options = std::vector<std::string>{
"default",
"default_right",
"default_right_a7"};
670 layout->children.emplace_back(label);
671 layout->children.emplace_back(cfgBox);
674 layout->children.insert(layout->children.end(), widgets.begin(), widgets.end());
683 auto cfgName =
values.at(
"config_box")->getString();
686 "controller_config/NJointTaskspaceAdmittanceController/" + cfgName +
".json");
690 auto cfgDTO = armarx::readFromJson<ConfigDict>(configPath.
toSystemPath());
693 return new ConfigurableNJointControllerConfig{cfgDTO.toAronDTO()};