25 #include <VirtualRobot/MathTools.h>
39 NJointControllerRegistration<NJointTaskspaceImpedanceController>
41 "NJointTaskspaceImpedanceController");
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 "NJointTaskspaceImpedanceController";
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 arm->controller.ftsensor.updateStatus(
237 arm->rtConfig.ftConfig, arm->rtStatus.currentForceTorque, arm->rtStatus.deltaT, arm->rtFirstRun.load());
239 arm->sensorDevices.updateJointValues(
240 arm->rtStatus.jointPos, arm->rtStatus.jointVel, arm->rtStatus.jointTor);
243 arm->bufferRtStatusToNonRt.getWriteBuffer() = arm->rtStatus;
244 arm->bufferRtStatusToNonRt.commitWrite();
245 arm->bufferRtStatusToUser.getWriteBuffer() = arm->rtStatus;
246 arm->bufferRtStatusToUser.commitWrite();
251 const Eigen::VectorXf& targetTorque)
253 for (
unsigned int i = 0; i < targetTorque.size(); i++)
255 arm->targets.at(i)->torque = targetTorque(i);
256 if (!arm->targets.at(i)->isValid())
258 arm->targets.at(i)->torque = 0;
261 arm->bufferRtStatusToOnPublish.getWriteBuffer() = arm->rtStatus;
262 arm->bufferRtStatusToOnPublish.commitWrite();
264 arm->bufferConfigRtToOnPublish.getWriteBuffer() = arm->rtConfig;
265 arm->bufferConfigRtToOnPublish.commitWrite();
267 arm->bufferConfigRtToUser.getWriteBuffer() = arm->rtConfig;
268 arm->bufferConfigRtToUser.commitWrite();
270 if (arm->rtFirstRun.load())
272 arm->rtFirstRun.store(
false);
273 arm->rtReady.store(
true);
280 double time_measure = IceUtil::Time::now().toMicroSecondsDouble();
282 double time_update_status = IceUtil::Time::now().toMicroSecondsDouble() - time_measure;
284 arm->controller.run(arm->rtConfig, arm->rtStatus);
285 double time_run_rt = IceUtil::Time::now().toMicroSecondsDouble() - time_measure;
289 double time_set_target = IceUtil::Time::now().toMicroSecondsDouble() - time_measure;
290 time_measure = IceUtil::Time::now().toMicroSecondsDouble() - time_measure;
292 if (time_measure > 100)
295 "time_update_status: %.2f\n"
296 "run_rt_limb: %.2f\n"
297 "set_target_limb: %.2f\n"
300 time_run_rt - time_update_status,
301 time_set_target - time_run_rt,
303 .deactivateSpam(1.0f);
311 double deltaT = timeSinceLastIteration.toSecondsDouble();
312 for (
auto& pair :
limb)
314 limbRT(pair.second, deltaT);
318 hands->updateRTStatus(deltaT);
326 const Ice::Current& iceCurrent)
335 prevCfg.limbs.at(pair.first).desiredPose,
336 "new desired pose",
"previous desired pose",
337 pair.second.safeDistanceMMToGoal,
338 pair.second.safeRotAngleDegreeToGoal,
339 "updateConfig_" + pair.first))
342 pair.second.desiredPose = prevCfg.limbs.at(pair.first).desiredPose;
344 limb.at(pair.first)->bufferConfigUserToNonRt.getWriteBuffer() = pair.second;
345 limb.at(pair.first)->bufferConfigUserToNonRt.commitWrite();
356 for (
auto& pair :
limb)
359 pair.second->bufferConfigRtToUser.getUpToDateReadBuffer();
370 const bool forceGuard,
371 const bool torqueGuard,
372 const Ice::Current& iceCurrent)
377 it->second.ftConfig.enableSafeGuardForce = forceGuard;
378 it->second.ftConfig.enableSafeGuardTorque = torqueGuard;
379 limb.at(nodeSetName)->controller.ftsensor.enableSafeGuard(forceGuard, torqueGuard);
381 <<
"reset safe guard with force torque sensors: safe? "
382 <<
limb.at(nodeSetName)->controller.ftsensor.isSafe(it->second.ftConfig);
383 limb.at(nodeSetName)->bufferConfigUserToNonRt.getWriteBuffer() = it->second;
384 limb.at(nodeSetName)->bufferConfigUserToNonRt.commitWrite();
389 <<
" found in the controllers.";
396 const Ice::Current& iceCurrent)
401 return limb.at(nodeSetName)->controller.ftsensor.ftSafe.load();
406 <<
" found in the controllers.";
413 const Ice::Current& iceCurrent)
415 std::vector<float> tcpVel;
416 auto& arm =
limb.at(rns);
417 auto s = arm->bufferRtStatusToUser.getUpToDateReadBuffer();
418 for (
int i = 0; i <
s.currentTwist.size(); i++)
420 tcpVel.push_back(
s.currentTwist[i]);
429 const Ice::Current& iceCurrent)
433 for (
size_t i = 0; i < 4; ++i)
435 for (
int j = 0; j < 4; ++j)
437 pair.second.desiredPose(i, j) = targetPoseMap.at(pair.first)[i][j];
440 if (targetNullspaceMap.at(pair.first).size() > 0)
442 const size_t nDoF = pair.second.desiredNullspaceJointAngles.value().size();
444 <<
"the joint numbers does not match";
445 for (
size_t i = 0; i < nDoF; ++i)
447 pair.second.desiredNullspaceJointAngles.value()(i) =
448 targetNullspaceMap.at(pair.first)[i];
451 limb.at(pair.first)->bufferConfigUserToNonRt.getWriteBuffer() = pair.second;
452 limb.at(pair.first)->bufferConfigUserToNonRt.commitWrite();
460 const auto nDoF = arm->controller.numOfJoints;
463 const auto checkNonNegative = [](
const auto&
v) {
ARMARX_CHECK((
v.array() >= 0).all()); };
465 if (!configData.desiredNullspaceJointAngles.has_value())
469 ARMARX_INFO <<
"No user defined nullspace target, reset to zero with "
471 configData.desiredNullspaceJointAngles = Eigen::VectorXf::Zero(nDoF);
472 arm->reInitPreActivate.store(
true);
477 arm->bufferConfigRtToUser.getUpToDateReadBuffer().desiredNullspaceJointAngles;
479 <<
"Controller is active, but no user defined nullspace target. \n"
480 "You should first get up-to-date config of this controller and then update "
482 " auto cfg = ctrl->getConfig(); \n"
483 " cfg.desiredPose = xxx;\n"
484 " ctrl->updateConfig(cfg);\n"
485 "Now, I decide by myself to use the existing values of nullspace target\n"
486 << currentValue.value();
487 configData.desiredNullspaceJointAngles = currentValue;
491 checkSize(configData.desiredNullspaceJointAngles.value());
492 checkSize(configData.kdNullspace);
493 checkSize(configData.kpNullspace);
495 checkNonNegative(configData.kdNullspace);
496 checkNonNegative(configData.kpNullspace);
497 checkNonNegative(configData.kdImpedance);
498 checkNonNegative(configData.kpImpedance);
506 auto rtData = arm->bufferConfigRtToOnPublish.getUpToDateReadBuffer();
507 auto rtStatus = arm->bufferRtStatusToOnPublish.getUpToDateReadBuffer();
521 datafields[
"safeDistanceToGoalThr"] =
new Variant(rtData.safeDistanceMMToGoal);
522 debugObs->setDebugChannel(
getClassName() +
"_" + arm->kinematicChainName, datafields);
530 for (
auto& pair :
limb)
532 if (not pair.second->rtReady.load())
541 for (
auto& pair :
limb)
543 pair.second->rtReady.store(
false);
550 VirtualRobot::RobotNodeSetPtr rns =
rtGetRobot()->getRobotNodeSet(arm->kinematicChainName);
552 auto quat = VirtualRobot::MathTools::eigen4f2quat(currentPose);
554 "[ %.2f, %.2f, %.2f, %.2f, %.2f, %.2f, %.2f ].",
563 if (arm->reInitPreActivate.load())
565 arm->rtConfig.desiredNullspaceJointAngles.value() = rns->getJointValuesEigen();
566 arm->rtConfig.desiredPose = currentPose;
568 arm->bufferConfigUserToNonRt.reinitAllBuffers(arm->rtConfig);
569 arm->reInitPreActivate.store(
false);
572 arm->nonRtConfig = arm->rtConfig;
573 arm->bufferConfigNonRtToRt.reinitAllBuffers(arm->rtConfig);
574 arm->bufferConfigRtToOnPublish.reinitAllBuffers(arm->rtConfig);
575 arm->bufferConfigRtToUser.reinitAllBuffers(arm->rtConfig);
578 arm->sensorDevices.updateJointValues(
579 arm->rtStatus.jointPos, arm->rtStatus.jointVel, arm->rtStatus.jointTor);
580 arm->rtStatus.rtPreActivate(currentPose);
582 arm->rtStatusInNonRT = arm->rtStatus;
583 arm->bufferRtStatusToOnPublish.reinitAllBuffers(arm->rtStatus);
584 arm->bufferRtStatusToNonRt.reinitAllBuffers(arm->rtStatus);
585 arm->bufferRtStatusToUser.reinitAllBuffers(arm->rtStatus);
588 arm->controller.preactivateInit(rns);
594 for (
auto& pair :
limb)
598 userConfig.limbs.at(pair.first) = pair.second->rtConfig;
602 hands->rtPreActivate();
615 hands->rtPostDeactivate();
623 const std::map<std::string, ConstControlDevicePtr>& controlDevices,
624 const std::map<std::string, ConstSensorDevicePtr>&)
630 ::armarx::WidgetDescription::WidgetSeq widgets;
633 LabelPtr label =
new Label;
634 label->text =
"select a controller config";
636 StringComboBoxPtr cfgBox =
new StringComboBox;
637 cfgBox->name =
"config_box";
638 cfgBox->defaultIndex = 0;
639 cfgBox->multiSelect =
false;
641 cfgBox->options = std::vector<std::string>{
"default",
"default_right",
"default_a7_right"};
644 layout->children.emplace_back(label);
645 layout->children.emplace_back(cfgBox);
648 layout->children.insert(layout->children.end(), widgets.begin(), widgets.end());
657 auto cfgName =
values.at(
"config_box")->getString();
660 "controller_config/NJointTaskspaceImpedanceController/" + cfgName +
".json");
664 auto cfgDTO = armarx::readFromJson<ConfigDict>(configPath.
toSystemPath());
667 return new ConfigurableNJointControllerConfig{cfgDTO.toAronDTO()};