25 #include <VirtualRobot/MathTools.h>
41 "NJointTaskspaceAdmittanceController");
49 arm->kinematicChainName = nodeSetName;
50 VirtualRobot::RobotNodeSetPtr rtRns =
51 rtGetRobot()->getRobotNodeSet(arm->kinematicChainName);
52 VirtualRobot::RobotNodeSetPtr nonRtRns =
53 nonRtRobotPtr->getRobotNodeSet(arm->kinematicChainName);
56 ARMARX_IMPORTANT <<
"Creating Taskspace Impedance controller with kinematic chain: "
57 << arm->kinematicChainName <<
" with num of joints: (RT robot) "
58 << rtRns->getSize() <<
", and (non-RT robot) " << nonRtRns->getSize();
60 arm->controller.initialize(nonRtRns, rtRns);
61 arm->controller.ftsensor.initialize(rtRns,
robotUnit, cfg.ftConfig);
62 arm->jointNames.clear();
63 for (
size_t i = 0; i < rtRns->getSize(); ++i)
65 std::string jointName = rtRns->getNode(i)->getName();
66 arm->jointNames.push_back(jointName);
70 auto* casted_ct = ct->
asA<ControlTarget1DoFActuatorTorque>();
72 arm->targets.push_back(casted_ct);
76 arm->sensorDevices.append(sv, jointName);
81 arm->nonRtConfig = cfg;
82 arm->rtStatus.reset(rtRns->getSize());
86 const RobotUnitPtr& robotUnit,
87 const NJointControllerConfigPtr& config,
93 ConfigPtrT cfg = ConfigPtrT::dynamicCast(config);
103 limb.emplace(pair.first, std::make_unique<ArmData>());
113 for (
auto& jointName :
hands->hands.at(pair.first)->jointNames)
115 hands->appendDevice(pair.first,
121 <<
hands->hands.at(pair.first)->kinematicChainName;
130 return "NJointTaskspaceAdmittanceController";
136 std::string taskName =
getClassName() +
"AdditionalTask";
148 while (
getState() == eManagedIceObjectStarted)
154 c.waitForCycleDuration();
162 arm->bufferConfigNonRtToRt.getWriteBuffer() = arm->nonRtConfig;
163 arm->bufferConfigNonRtToRt.commitWrite();
182 for (
auto& pair :
limb)
184 auto& arm = pair.second;
185 arm->nonRtConfig = arm->bufferConfigUserToNonRt.getUpToDateReadBuffer();
186 arm->rtStatusInNonRT = arm->bufferRtStatusToNonRt.getUpToDateReadBuffer();
187 rtSafe = rtSafe and pair.second->rtStatusInNonRT.rtSafe;
191 hands->nonRTUpdateStatus();
199 for (
auto& pair :
limb)
205 hands->nonRTSetTarget();
212 for (
auto& pair :
limb)
214 if (not pair.second->rtReady)
217 if (not pair.second->rtStatusInNonRT.rtTargetSafe)
219 pair.second->rtStatusInNonRT =
220 pair.second->bufferRtStatusToNonRt.getUpToDateReadBuffer();
222 pair.second->rtStatusInNonRT.currentPose,
223 pair.second->nonRtConfig.desiredPose,
224 "current pose",
"desired pose");
233 arm->rtConfig = arm->bufferConfigNonRtToRt.getUpToDateReadBuffer();
234 arm->rtStatus.deltaT = deltaT;
236 if (arm->rtFirstRun.load())
238 arm->controller.firstRun();
241 arm->controller.ftsensor.updateStatus(
242 arm->rtConfig.ftConfig, arm->rtStatus.currentForceTorque, arm->rtStatus.deltaT, arm->rtFirstRun.load());
244 arm->sensorDevices.updateJointValues(
245 arm->rtStatus.jointPos, arm->rtStatus.jointVel, arm->rtStatus.jointTor);
248 arm->bufferRtStatusToNonRt.getWriteBuffer() = arm->rtStatus;
249 arm->bufferRtStatusToNonRt.commitWrite();
250 arm->bufferRtStatusToUser.getWriteBuffer() = arm->rtStatus;
251 arm->bufferRtStatusToUser.commitWrite();
256 const Eigen::VectorXf& targetTorque)
258 for (
unsigned int i = 0; i < targetTorque.size(); i++)
260 arm->targets.at(i)->torque = targetTorque(i);
261 if (!arm->targets.at(i)->isValid())
263 arm->targets.at(i)->torque = 0;
266 arm->bufferRtStatusToOnPublish.getWriteBuffer() = arm->rtStatus;
267 arm->bufferRtStatusToOnPublish.commitWrite();
269 arm->bufferConfigRtToOnPublish.getWriteBuffer() = arm->rtConfig;
270 arm->bufferConfigRtToOnPublish.commitWrite();
272 arm->bufferConfigRtToUser.getWriteBuffer() = arm->rtConfig;
273 arm->bufferConfigRtToUser.commitWrite();
275 if (arm->rtFirstRun.load())
277 arm->rtFirstRun.store(
false);
278 arm->rtReady.store(
true);
285 double time_measure = IceUtil::Time::now().toMicroSecondsDouble();
287 double time_update_status = IceUtil::Time::now().toMicroSecondsDouble() - time_measure;
289 arm->controller.run(arm->rtConfig, arm->rtStatus);
290 double time_run_rt = IceUtil::Time::now().toMicroSecondsDouble() - time_measure;
294 double time_set_target = IceUtil::Time::now().toMicroSecondsDouble() - time_measure;
295 time_measure = IceUtil::Time::now().toMicroSecondsDouble() - time_measure;
297 if (time_measure > 100)
300 "time_update_status: %.2f\n"
301 "run_rt_limb: %.2f\n"
302 "set_target_limb: %.2f\n"
305 time_run_rt - time_update_status,
306 time_set_target - time_run_rt,
308 .deactivateSpam(1.0f);
316 double deltaT = timeSinceLastIteration.toSecondsDouble();
317 for (
auto& pair :
limb)
319 limbRT(pair.second, deltaT);
323 hands->updateRTStatus(deltaT);
331 const Ice::Current& iceCurrent)
340 prevCfg.limbs.at(pair.first).desiredPose,
341 "new desired pose",
"previous desired pose",
342 pair.second.safeDistanceMMToGoal,
343 pair.second.safeRotAngleDegreeToGoal,
344 "updateConfig_" + pair.first))
347 pair.second.desiredPose = prevCfg.limbs.at(pair.first).desiredPose;
349 limb.at(pair.first)->bufferConfigUserToNonRt.getWriteBuffer() = pair.second;
350 limb.at(pair.first)->bufferConfigUserToNonRt.commitWrite();
361 for (
auto& pair :
limb)
364 pair.second->bufferConfigRtToUser.getUpToDateReadBuffer();
375 const bool forceGuard,
376 const bool torqueGuard,
377 const Ice::Current& iceCurrent)
382 it->second.ftConfig.enableSafeGuardForce = forceGuard;
383 it->second.ftConfig.enableSafeGuardTorque = torqueGuard;
384 limb.at(nodeSetName)->controller.ftsensor.enableSafeGuard(forceGuard, torqueGuard);
386 <<
"reset safe guard with force torque sensors: safe? "
387 <<
limb.at(nodeSetName)->controller.ftsensor.isSafe(it->second.ftConfig);
388 limb.at(nodeSetName)->bufferConfigUserToNonRt.getWriteBuffer() = it->second;
389 limb.at(nodeSetName)->bufferConfigUserToNonRt.commitWrite();
394 <<
" found in the controllers.";
401 const Ice::Current& iceCurrent)
406 return limb.at(nodeSetName)->controller.ftsensor.ftSafe.load();
411 <<
" found in the controllers.";
418 const Ice::Current& iceCurrent)
420 std::vector<float> tcpVel;
421 auto& arm =
limb.at(rns);
422 auto s = arm->bufferRtStatusToUser.getUpToDateReadBuffer();
423 for (
int i = 0; i <
s.currentTwist.size(); i++)
425 tcpVel.push_back(
s.currentTwist[i]);
434 const Ice::Current& iceCurrent)
438 for (
size_t i = 0; i < 4; ++i)
440 for (
int j = 0; j < 4; ++j)
442 pair.second.desiredPose(i, j) = targetPoseMap.at(pair.first)[i][j];
445 if (targetNullspaceMap.at(pair.first).size() > 0)
447 const size_t nDoF = pair.second.desiredNullspaceJointAngles.value().size();
449 <<
"the joint numbers does not match";
450 for (
size_t i = 0; i < nDoF; ++i)
452 pair.second.desiredNullspaceJointAngles.value()(i) =
453 targetNullspaceMap.at(pair.first)[i];
456 limb.at(pair.first)->bufferConfigUserToNonRt.getWriteBuffer() = pair.second;
457 limb.at(pair.first)->bufferConfigUserToNonRt.commitWrite();
465 const auto nDoF = arm->controller.numOfJoints;
468 const auto checkNonNegative = [](
const auto&
v) {
ARMARX_CHECK((
v.array() >= 0).all()); };
470 if (!configData.desiredNullspaceJointAngles.has_value())
474 ARMARX_INFO <<
"No user defined nullspace target, reset to zero with "
476 configData.desiredNullspaceJointAngles = Eigen::VectorXf::Zero(nDoF);
477 arm->reInitPreActivate.store(
true);
482 arm->bufferConfigRtToUser.getUpToDateReadBuffer().desiredNullspaceJointAngles;
484 <<
"Controller is active, but no user defined nullspace target. \n"
485 "You should first get up-to-date config of this controller and then update "
487 " auto cfg = ctrl->getConfig(); \n"
488 " cfg.desiredPose = xxx;\n"
489 " ctrl->updateConfig(cfg);\n"
490 "Now, I decide by myself to use the existing values of nullspace target\n"
491 << currentValue.value();
492 configData.desiredNullspaceJointAngles = currentValue;
496 checkSize(configData.desiredNullspaceJointAngles.value());
497 checkSize(configData.kdNullspace);
498 checkSize(configData.kpNullspace);
500 checkNonNegative(configData.kdNullspace);
501 checkNonNegative(configData.kpNullspace);
502 checkNonNegative(configData.kdImpedance);
503 checkNonNegative(configData.kpImpedance);
511 auto rtData = arm->bufferConfigRtToOnPublish.getUpToDateReadBuffer();
512 auto rtStatus = arm->bufferRtStatusToOnPublish.getUpToDateReadBuffer();
528 debugObs->setDebugChannel(
getClassName() +
"_" + arm->kinematicChainName, datafields);
536 for (
auto& pair :
limb)
538 if (not pair.second->rtReady.load())
547 for (
auto& pair :
limb)
549 pair.second->rtReady.store(
false);
557 for (
auto& pair :
limb)
559 pair.second->rtReady.store(
false);
566 VirtualRobot::RobotNodeSetPtr rns =
rtGetRobot()->getRobotNodeSet(arm->kinematicChainName);
567 const auto& currentPose = rns->getTCP()->getPoseInRootFrame();
568 auto quat = VirtualRobot::MathTools::eigen4f2quat(currentPose);
570 "[ %.2f, %.2f, %.2f, %.2f, %.2f, %.2f, %.2f ].",
579 if (arm->reInitPreActivate.load())
581 arm->rtConfig.desiredNullspaceJointAngles.value() = rns->getJointValuesEigen();
582 arm->rtConfig.desiredPose = currentPose;
584 arm->bufferConfigUserToNonRt.reinitAllBuffers(arm->rtConfig);
585 arm->reInitPreActivate.store(
false);
588 arm->nonRtConfig = arm->rtConfig;
589 arm->bufferConfigNonRtToRt.reinitAllBuffers(arm->rtConfig);
590 arm->bufferConfigRtToOnPublish.reinitAllBuffers(arm->rtConfig);
591 arm->bufferConfigRtToUser.reinitAllBuffers(arm->rtConfig);
594 arm->sensorDevices.updateJointValues(
595 arm->rtStatus.jointPos, arm->rtStatus.jointVel, arm->rtStatus.jointTor);
596 arm->rtStatus.rtPreActivate(currentPose);
598 arm->rtStatusInNonRT = arm->rtStatus;
599 arm->bufferRtStatusToOnPublish.reinitAllBuffers(arm->rtStatus);
600 arm->bufferRtStatusToNonRt.reinitAllBuffers(arm->rtStatus);
601 arm->bufferRtStatusToUser.reinitAllBuffers(arm->rtStatus);
604 arm->controller.preactivateInit(rns);
610 for (
auto& pair :
limb)
614 userConfig.limbs.at(pair.first) = pair.second->rtConfig;
618 hands->rtPreActivate();
635 const std::map<std::string, ConstControlDevicePtr>& controlDevices,
636 const std::map<std::string, ConstSensorDevicePtr>&)
642 ::armarx::WidgetDescription::WidgetSeq widgets;
645 LabelPtr label =
new Label;
646 label->text =
"select a controller config";
648 StringComboBoxPtr cfgBox =
new StringComboBox;
649 cfgBox->name =
"config_box";
650 cfgBox->defaultIndex = 0;
651 cfgBox->multiSelect =
false;
653 cfgBox->options = std::vector<std::string>{
"default",
"default_right",
"default_right_a7"};
656 layout->children.emplace_back(label);
657 layout->children.emplace_back(cfgBox);
660 layout->children.insert(layout->children.end(), widgets.begin(), widgets.end());
669 auto cfgName =
values.at(
"config_box")->getString();
672 "controller_config/NJointTaskspaceAdmittanceController/" + cfgName +
".json");
676 auto cfgDTO = armarx::readFromJson<ConfigDict>(configPath.
toSystemPath());
679 return new ConfigurableNJointControllerConfig{cfgDTO.toAronDTO()};