25 #include <VirtualRobot/MathTools.h>
26 #include <VirtualRobot/Nodes/RobotNode.h>
27 #include <VirtualRobot/RobotNodeSet.h>
45 NJointControllerRegistration<NJointTaskspaceImpedanceController>
47 "NJointTaskspaceImpedanceController");
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 "NJointTaskspaceImpedanceController";
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 arm->controller.ftsensor.updateStatus(arm->rtConfig.ftConfig,
245 arm->rtStatus.currentForceTorque,
246 arm->rtStatus.deltaT,
247 arm->rtFirstRun.load());
249 arm->sensorDevices.updateJointValues(
250 arm->rtStatus.jointPos, arm->rtStatus.jointVel, arm->rtStatus.jointTor);
253 arm->bufferRtStatusToNonRt.getWriteBuffer() = arm->rtStatus;
254 arm->bufferRtStatusToNonRt.commitWrite();
255 arm->bufferRtStatusToUser.getWriteBuffer() = arm->rtStatus;
256 arm->bufferRtStatusToUser.commitWrite();
261 const Eigen::VectorXf& targetTorque)
263 for (
unsigned int i = 0; i < targetTorque.size(); i++)
265 arm->targets.at(i)->torque = targetTorque(i);
266 if (!arm->targets.at(i)->isValid())
268 arm->targets.at(i)->torque = 0;
271 arm->bufferRtStatusToOnPublish.getWriteBuffer() = arm->rtStatus;
272 arm->bufferRtStatusToOnPublish.commitWrite();
274 arm->bufferConfigRtToOnPublish.getWriteBuffer() = arm->rtConfig;
275 arm->bufferConfigRtToOnPublish.commitWrite();
277 arm->bufferConfigRtToUser.getWriteBuffer() = arm->rtConfig;
278 arm->bufferConfigRtToUser.commitWrite();
280 if (arm->rtFirstRun.load())
282 arm->rtFirstRun.store(
false);
283 arm->rtReady.store(
true);
290 double time_measure = IceUtil::Time::now().toMicroSecondsDouble();
292 double time_update_status = IceUtil::Time::now().toMicroSecondsDouble() - time_measure;
294 arm->controller.run(arm->rtConfig, arm->rtStatus);
295 double time_run_rt = IceUtil::Time::now().toMicroSecondsDouble() - time_measure;
299 double time_set_target = IceUtil::Time::now().toMicroSecondsDouble() - time_measure;
300 time_measure = IceUtil::Time::now().toMicroSecondsDouble() - time_measure;
302 if (time_measure > 200)
305 "time_update_status: %.2f\n"
306 "run_rt_limb: %.2f\n"
307 "set_target_limb: %.2f\n"
310 time_run_rt - time_update_status,
311 time_set_target - time_run_rt,
313 .deactivateSpam(1.0f);
321 double deltaT = timeSinceLastIteration.toSecondsDouble();
322 for (
auto& pair :
limb)
324 limbRT(pair.second, deltaT);
328 hands->updateRTStatus(deltaT);
336 const Ice::Current& iceCurrent)
345 pair.second.desiredPose,
346 prevCfg.limbs.at(pair.first).desiredPose,
348 "previous desired pose",
349 pair.second.safeDistanceMMToGoal,
350 pair.second.safeRotAngleDegreeToGoal,
351 "updateConfig_" + pair.first))
354 pair.second.desiredPose = prevCfg.limbs.at(pair.first).desiredPose;
356 limb.at(pair.first)->bufferConfigUserToNonRt.getWriteBuffer() = pair.second;
357 limb.at(pair.first)->bufferConfigUserToNonRt.commitWrite();
368 for (
auto& pair :
limb)
371 pair.second->bufferConfigRtToUser.getUpToDateReadBuffer();
382 const bool forceGuard,
383 const bool torqueGuard,
384 const Ice::Current& iceCurrent)
389 it->second.ftConfig.enableSafeGuardForce = forceGuard;
390 it->second.ftConfig.enableSafeGuardTorque = torqueGuard;
391 limb.at(nodeSetName)->controller.ftsensor.enableSafeGuard(forceGuard, torqueGuard);
393 <<
"reset safe guard with force torque sensors: safe? "
394 <<
limb.at(nodeSetName)->controller.ftsensor.isSafe(it->second.ftConfig);
395 limb.at(nodeSetName)->bufferConfigUserToNonRt.getWriteBuffer() = it->second;
396 limb.at(nodeSetName)->bufferConfigUserToNonRt.commitWrite();
401 <<
" found in the controllers.";
408 const Ice::Current& iceCurrent)
413 return limb.at(nodeSetName)->controller.ftsensor.ftSafe.load();
417 <<
" found in the controllers.";
423 const Ice::Current& iceCurrent)
425 std::vector<float> tcpVel;
426 auto& arm =
limb.at(rns);
427 auto s = arm->bufferRtStatusToUser.getUpToDateReadBuffer();
428 for (
int i = 0; i <
s.currentTwist.size(); i++)
430 tcpVel.push_back(
s.currentTwist[i]);
439 const Ice::Current& iceCurrent)
443 for (
size_t i = 0; i < 4; ++i)
445 for (
int j = 0; j < 4; ++j)
447 pair.second.desiredPose(i, j) = targetPoseMap.at(pair.first)[i][j];
450 if (targetNullspaceMap.at(pair.first).size() > 0)
452 const size_t nDoF = pair.second.desiredNullspaceJointAngles.value().size();
454 <<
"the joint numbers does not match";
455 for (
size_t i = 0; i < nDoF; ++i)
457 pair.second.desiredNullspaceJointAngles.value()(i) =
458 targetNullspaceMap.at(pair.first)[i];
461 limb.at(pair.first)->bufferConfigUserToNonRt.getWriteBuffer() = pair.second;
462 limb.at(pair.first)->bufferConfigUserToNonRt.commitWrite();
470 const auto nDoF = arm->controller.numOfJoints;
473 const auto checkNonNegative = [](
const auto&
v) {
ARMARX_CHECK((
v.array() >= 0).all()); };
475 if (!configData.desiredNullspaceJointAngles.has_value())
479 ARMARX_INFO <<
"No user defined nullspace target, reset to zero with "
481 configData.desiredNullspaceJointAngles = Eigen::VectorXf::Zero(nDoF);
482 arm->reInitPreActivate.store(
true);
487 arm->bufferConfigRtToUser.getUpToDateReadBuffer().desiredNullspaceJointAngles;
489 <<
"Controller is active, but no user defined nullspace target. \n"
490 "You should first get up-to-date config of this controller and then update "
492 " auto cfg = ctrl->getConfig(); \n"
493 " cfg.desiredPose = xxx;\n"
494 " ctrl->updateConfig(cfg);\n"
495 "Now, I decide by myself to use the existing values of nullspace target\n"
496 << currentValue.value();
497 configData.desiredNullspaceJointAngles = currentValue;
501 checkSize(configData.desiredNullspaceJointAngles.value());
502 checkSize(configData.kdNullspace);
503 checkSize(configData.kpNullspace);
505 checkNonNegative(configData.kdNullspace);
506 checkNonNegative(configData.kpNullspace);
507 checkNonNegative(configData.kdImpedance);
508 checkNonNegative(configData.kpImpedance);
516 auto rtData = arm->bufferConfigRtToOnPublish.getUpToDateReadBuffer();
517 auto rtStatus = arm->bufferRtStatusToOnPublish.getUpToDateReadBuffer();
521 if (rtData.desiredNullspaceJointAngles.has_value())
524 "desiredNullspaceJointAngles",
525 rtData.desiredNullspaceJointAngles.value());
535 datafields[
"safeDistanceToGoalThr"] =
new Variant(rtData.safeDistanceMMToGoal);
536 debugObs->setDebugChannel(
getClassName() +
"_" + arm->kinematicChainName, datafields);
544 for (
auto& pair :
limb)
546 if (not pair.second->rtReady.load())
552 hands->onPublish(debugObs);
559 for (
auto& pair :
limb)
561 pair.second->rtReady.store(
false);
568 VirtualRobot::RobotNodeSetPtr rns =
rtGetRobot()->getRobotNodeSet(arm->kinematicChainName);
570 auto quat = VirtualRobot::MathTools::eigen4f2quat(currentPose);
572 "[ %.2f, %.2f, %.2f, %.2f, %.2f, %.2f, %.2f ].",
581 if (arm->reInitPreActivate.load())
583 arm->rtConfig.desiredNullspaceJointAngles.value() = rns->getJointValuesEigen();
584 arm->rtConfig.desiredPose = currentPose;
586 arm->bufferConfigUserToNonRt.reinitAllBuffers(arm->rtConfig);
587 arm->reInitPreActivate.store(
false);
590 arm->nonRtConfig = arm->rtConfig;
591 arm->bufferConfigNonRtToRt.reinitAllBuffers(arm->rtConfig);
592 arm->bufferConfigRtToOnPublish.reinitAllBuffers(arm->rtConfig);
593 arm->bufferConfigRtToUser.reinitAllBuffers(arm->rtConfig);
596 arm->sensorDevices.updateJointValues(
597 arm->rtStatus.jointPos, arm->rtStatus.jointVel, arm->rtStatus.jointTor);
598 arm->rtStatus.rtPreActivate(currentPose);
600 arm->rtStatusInNonRT = arm->rtStatus;
601 arm->nonRTDeltaT = 0.0;
602 arm->nonRTAccumulateTime = 0.0;
603 arm->bufferRtStatusToOnPublish.reinitAllBuffers(arm->rtStatus);
604 arm->bufferRtStatusToNonRt.reinitAllBuffers(arm->rtStatus);
605 arm->bufferRtStatusToUser.reinitAllBuffers(arm->rtStatus);
608 arm->controller.preactivateInit(rns);
614 for (
auto& pair :
limb)
618 userConfig.limbs.at(pair.first) = pair.second->rtConfig;
622 hands->rtPreActivate();
635 hands->rtPostDeactivate();
643 const std::map<std::string, ConstControlDevicePtr>& controlDevices,
644 const std::map<std::string, ConstSensorDevicePtr>&)
650 ::armarx::WidgetDescription::WidgetSeq widgets;
653 LabelPtr label =
new Label;
654 label->text =
"select a controller config";
656 StringComboBoxPtr cfgBox =
new StringComboBox;
657 cfgBox->name =
"config_box";
658 cfgBox->defaultIndex = 0;
659 cfgBox->multiSelect =
false;
661 cfgBox->options = std::vector<std::string>{
"default",
"default_right",
"default_a7_right"};
664 layout->children.emplace_back(label);
665 layout->children.emplace_back(cfgBox);
668 layout->children.insert(layout->children.end(), widgets.begin(), widgets.end());
677 auto cfgName =
values.at(
"config_box")->getString();
680 "controller_config/NJointTaskspaceImpedanceController/" + cfgName +
".json");
684 auto cfgDTO = armarx::readFromJson<ConfigDict>(configPath.
toSystemPath());
687 return new ConfigurableNJointControllerConfig{cfgDTO.toAronDTO()};