25 #include <VirtualRobot/MathTools.h>
26 #include <VirtualRobot/Nodes/RobotNode.h>
27 #include <VirtualRobot/RobotNodeSet.h>
47 NJointControllerRegistration<NJointTaskspaceMixedImpedanceVelocityController>
49 "NJointTaskspaceMixedImpedanceVelocityController");
57 arm->kinematicChainName = nodeSetName;
58 VirtualRobot::RobotNodeSetPtr rtRns =
59 rtGetRobot()->getRobotNodeSet(arm->kinematicChainName);
60 VirtualRobot::RobotNodeSetPtr nonRtRns =
61 nonRtRobotPtr->getRobotNodeSet(arm->kinematicChainName);
64 ARMARX_IMPORTANT <<
"Creating Taskspace Impedance controller with kinematic chain: "
65 << arm->kinematicChainName <<
" with num of joints: (RT robot) "
66 << rtRns->getSize() <<
", and (non-RT robot) " << nonRtRns->getSize();
68 std::vector<size_t> jointIDTorqueMode;
69 std::vector<size_t> jointIDVelocityMode;
70 arm->jointNames.clear();
71 for (
size_t i = 0; i < rtRns->getSize(); ++i)
73 std::string jointName = rtRns->getNode(i)->getName();
74 arm->jointNames.push_back(jointName);
76 bool foundControlDevice =
false;
78 cfg.jointNameListTorque.begin(), cfg.jointNameListTorque.end(), jointName);
79 if (it != cfg.jointNameListTorque.end())
83 auto* casted_ct = ct->
asA<ControlTarget1DoFActuatorTorque>();
85 arm->targetsTorque.push_back(casted_ct);
86 jointIDTorqueMode.push_back(i);
87 foundControlDevice =
true;
91 cfg.jointNameListVelocity.begin(), cfg.jointNameListVelocity.end(), jointName);
92 if (it != cfg.jointNameListVelocity.end())
96 auto* casted_ct = ct->
asA<ControlTarget1DoFActuatorVelocity>();
98 arm->targetsVel.push_back(casted_ct);
99 jointIDVelocityMode.push_back(i);
100 foundControlDevice =
true;
102 if (not foundControlDevice)
107 ARMARX_ERROR <<
"Does not found valid control device for joint name: " << jointName
108 <<
"Please check torque controlled joints: [" << namesTorque
109 <<
"] and velocity controlled joints: [" << namesVelocity <<
"].";
114 arm->sensorDevices.append(sv, jointName);
116 ARMARX_DEBUG <<
"Number of torque controlled joints " << jointIDTorqueMode.size();
117 ARMARX_DEBUG <<
"Number of velocity controlled joints " << jointIDVelocityMode.size();
119 jointIDTorqueMode.size() + jointIDVelocityMode.size());
121 arm->controller.initialize(nonRtRns, rtRns, jointIDTorqueMode, jointIDVelocityMode);
122 arm->controller.ftsensor.initialize(rtRns,
robotUnit, cfg.ftConfig);
126 arm->nonRtConfig = cfg;
127 arm->rtStatus.reset(rtRns->getSize(), jointIDTorqueMode.size(), jointIDVelocityMode.size());
132 const NJointControllerConfigPtr& config,
138 ConfigPtrT cfg = ConfigPtrT::dynamicCast(config);
148 limb.emplace(pair.first, std::make_unique<ArmData>());
158 for (
auto& jointName :
hands->hands.at(pair.first)->jointNames)
160 hands->appendDevice(pair.first,
166 <<
hands->hands.at(pair.first)->kinematicChainName;
175 return "NJointTaskspaceMixedImpedanceVelocityController";
181 std::string taskName =
getClassName() +
"AdditionalTask";
193 while (
getState() == eManagedIceObjectStarted)
199 c.waitForCycleDuration();
207 arm->bufferConfigNonRtToRt.getWriteBuffer() = arm->nonRtConfig;
208 arm->bufferConfigNonRtToRt.commitWrite();
227 for (
auto& pair :
limb)
229 auto& arm = pair.second;
230 arm->nonRtConfig = arm->bufferConfigUserToNonRt.getUpToDateReadBuffer();
231 arm->rtStatusInNonRT = arm->bufferRtStatusToNonRt.getUpToDateReadBuffer();
232 rtSafe = rtSafe and pair.second->rtStatusInNonRT.rtSafe;
236 hands->nonRTUpdateStatus();
244 for (
auto& pair :
limb)
250 hands->nonRTSetTarget();
257 for (
auto& pair :
limb)
259 if (not pair.second->rtReady)
262 if (not pair.second->rtStatusInNonRT.rtTargetSafe)
264 pair.second->rtStatusInNonRT =
265 pair.second->bufferRtStatusToNonRt.getUpToDateReadBuffer();
267 pair.second->rtStatusInNonRT.currentPose,
268 pair.second->nonRtConfig.desiredPose,
280 arm->rtConfig = arm->bufferConfigNonRtToRt.getUpToDateReadBuffer();
281 arm->rtStatus.deltaT = deltaT;
282 arm->rtStatus.accumulateTime += deltaT;
284 arm->controller.ftsensor.updateStatus(arm->rtConfig.ftConfig,
285 arm->rtStatus.currentForceTorque,
286 arm->rtStatus.deltaT,
287 arm->rtFirstRun.load());
288 arm->rtStatus.safeFTGuardOffset.head<3>() =
289 arm->controller.ftsensor.getSafeGuardForceOffset();
291 arm->sensorDevices.updateJointValues(
292 arm->rtStatus.jointPos, arm->rtStatus.jointVel, arm->rtStatus.jointTor);
296 arm->bufferRtStatusToNonRt.getWriteBuffer() = arm->rtStatus;
297 arm->bufferRtStatusToNonRt.commitWrite();
298 arm->bufferRtStatusToUser.getWriteBuffer() = arm->rtStatus;
299 arm->bufferRtStatusToUser.commitWrite();
305 const size_t nDoFTorque,
306 const size_t nDoFVelocity,
307 const Eigen::VectorXf& targetTorque,
308 const Eigen::VectorXf& targetVelocity)
310 for (
size_t i = 0; i < nDoFTorque; i++)
312 auto jointIdx = arm->controller.jointIDTorqueMode[i];
313 arm->targetsTorque.at(i)->torque = targetTorque(jointIdx);
314 if (!arm->targetsTorque.at(i)->isValid())
316 arm->targetsTorque.at(i)->torque = 0;
319 for (
size_t i = 0; i < nDoFVelocity; i++)
321 auto jointIdx = arm->controller.jointIDVelocityMode[i];
322 arm->targetsVel.at(i)->velocity = targetVelocity(jointIdx);
324 if (!arm->targetsVel.at(i)->isValid())
326 arm->targetsVel.at(i)->velocity = 0;
329 arm->bufferRtStatusToOnPublish.getWriteBuffer() = arm->rtStatus;
330 arm->bufferRtStatusToOnPublish.commitWrite();
332 arm->bufferConfigRtToOnPublish.getWriteBuffer() = arm->rtConfig;
333 arm->bufferConfigRtToOnPublish.commitWrite();
335 arm->bufferConfigRtToUser.getWriteBuffer() = arm->rtConfig;
336 arm->bufferConfigRtToUser.commitWrite();
338 if (arm->rtFirstRun.load())
340 arm->rtFirstRun.store(
false);
341 arm->rtReady.store(
true);
348 double time_measure = IceUtil::Time::now().toMicroSecondsDouble();
350 double time_update_status = IceUtil::Time::now().toMicroSecondsDouble() - time_measure;
352 arm->controller.run(arm->rtConfig, arm->rtStatus);
353 double time_run_rt = IceUtil::Time::now().toMicroSecondsDouble() - time_measure;
356 arm->rtStatus.nDoFTorque,
357 arm->rtStatus.nDoFVelocity,
358 arm->rtStatus.desiredJointTorques,
359 arm->rtStatus.desiredJointVelocity);
361 double time_set_target = IceUtil::Time::now().toMicroSecondsDouble() - time_measure;
362 time_measure = IceUtil::Time::now().toMicroSecondsDouble() - time_measure;
364 if (time_measure > 200)
367 "time_update_status: %.2f\n"
368 "run_rt_limb: %.2f\n"
369 "set_target_limb: %.2f\n"
372 time_run_rt - time_update_status,
373 time_set_target - time_run_rt,
375 .deactivateSpam(1.0f);
384 double deltaT = timeSinceLastIteration.toSecondsDouble();
385 for (
auto& pair :
limb)
387 limbRT(pair.second, deltaT);
391 hands->updateRTStatus(deltaT);
400 const Ice::Current& iceCurrent)
409 pair.second.desiredPose,
410 prevCfg.limbs.at(pair.first).desiredPose,
412 "previous desired pose",
413 pair.second.safeDistanceMMToGoal,
414 pair.second.safeRotAngleDegreeToGoal,
415 "updateConfig_" + pair.first))
418 pair.second.desiredPose = prevCfg.limbs.at(pair.first).desiredPose;
420 limb.at(pair.first)->bufferConfigUserToNonRt.getWriteBuffer() = pair.second;
421 limb.at(pair.first)->bufferConfigUserToNonRt.commitWrite();
432 for (
auto& pair :
limb)
435 pair.second->bufferConfigRtToUser.getUpToDateReadBuffer();
446 const std::string& nodeSetName,
447 const bool forceGuard,
448 const bool torqueGuard,
449 const Ice::Current& iceCurrent)
454 it->second.ftConfig.enableSafeGuardForce = forceGuard;
455 it->second.ftConfig.enableSafeGuardTorque = torqueGuard;
456 limb.at(nodeSetName)->controller.ftsensor.enableSafeGuard(forceGuard, torqueGuard);
458 <<
"reset safe guard with force torque sensors: safe? "
459 <<
limb.at(nodeSetName)->controller.ftsensor.isSafe(it->second.ftConfig);
460 limb.at(nodeSetName)->bufferConfigUserToNonRt.getWriteBuffer() = it->second;
461 limb.at(nodeSetName)->bufferConfigUserToNonRt.commitWrite();
466 <<
" found in the controllers.";
473 const std::string& nodeSetName,
474 const Ice::Current& iceCurrent)
479 return limb.at(nodeSetName)->controller.ftsensor.ftSafe.load();
483 <<
" found in the controllers.";
489 const Ice::Current& iceCurrent)
491 std::vector<float> tcpVel;
492 auto& arm =
limb.at(rns);
493 auto s = arm->bufferRtStatusToUser.getUpToDateReadBuffer();
494 for (
int i = 0; i <
s.currentTwist.size(); i++)
496 tcpVel.push_back(
s.currentTwist[i]);
505 const Ice::Current& iceCurrent)
509 for (
size_t i = 0; i < 4; ++i)
511 for (
int j = 0; j < 4; ++j)
513 pair.second.desiredPose(i, j) = targetPoseMap.at(pair.first)[i][j];
516 if (targetNullspaceMap.at(pair.first).size() > 0)
518 const size_t nDoF = pair.second.desiredNullspaceJointAngles.value().size();
520 <<
"the joint numbers does not match";
521 for (
size_t i = 0; i < nDoF; ++i)
523 pair.second.desiredNullspaceJointAngles.value()(i) =
524 targetNullspaceMap.at(pair.first)[i];
527 limb.at(pair.first)->bufferConfigUserToNonRt.getWriteBuffer() = pair.second;
528 limb.at(pair.first)->bufferConfigUserToNonRt.commitWrite();
537 const auto nDoF = arm->controller.numOfJoints;
540 const auto checkNonNegative = [](
const auto&
v) {
ARMARX_CHECK((
v.array() >= 0).all()); };
542 if (!configData.desiredNullspaceJointAngles.has_value())
546 ARMARX_INFO <<
"No user defined nullspace target, reset to zero with "
548 configData.desiredNullspaceJointAngles = Eigen::VectorXf::Zero(nDoF);
549 arm->reInitPreActivate.store(
true);
554 arm->bufferConfigRtToUser.getUpToDateReadBuffer().desiredNullspaceJointAngles;
556 <<
"Controller is active, but no user defined nullspace target. \n"
557 "You should first get up-to-date config of this controller and then update "
559 " auto cfg = ctrl->getConfig(); \n"
560 " cfg.desiredPose = xxx;\n"
561 " ctrl->updateConfig(cfg);\n"
562 "Now, I decide by myself to use the existing values of nullspace target\n"
563 << currentValue.value();
564 configData.desiredNullspaceJointAngles = currentValue;
568 checkSize(configData.desiredNullspaceJointAngles.value());
569 checkSize(configData.kdNullspaceTorque);
570 checkSize(configData.kpNullspaceTorque);
571 checkSize(configData.kdNullspaceVel);
572 checkSize(configData.kpNullspaceVel);
574 checkNonNegative(configData.kdNullspaceTorque);
575 checkNonNegative(configData.kpNullspaceTorque);
576 checkNonNegative(configData.kpNullspaceVel);
577 checkNonNegative(configData.kdNullspaceVel);
578 checkNonNegative(configData.kdImpedance);
579 checkNonNegative(configData.kpImpedance);
588 auto rtData = arm->bufferConfigRtToOnPublish.getUpToDateReadBuffer();
589 auto rtStatus = arm->bufferRtStatusToOnPublish.getUpToDateReadBuffer();
593 if (rtData.desiredNullspaceJointAngles.has_value())
596 "desiredNullspaceJointAngles",
597 rtData.desiredNullspaceJointAngles.value());
606 float positionError =
610 datafields[
"poseError_position"] =
new Variant(positionError);
611 datafields[
"poseError_angle"] =
new Variant(angleError);
612 datafields[
"poseError_threshold_position"] =
new Variant(rtData.safeDistanceMMToGoal);
613 datafields[
"poseError_threshold_angle"] =
new Variant(rtData.safeRotAngleDegreeToGoal);
621 float currentForceNorm = rtStatus.currentForceTorque.head<3>().
norm();
622 float currentTorqueNorm = rtStatus.currentForceTorque.tail<3>().
norm();
623 float safeForceGuardOffsetNorm = rtStatus.safeFTGuardOffset.head<3>().
norm();
624 float safeTorqueGuardOffsetNorm = rtStatus.safeFTGuardOffset.tail<3>().
norm();
625 datafields[
"currentForceTorqueNorm"] =
new Variant(currentForceNorm);
626 datafields[
"currentTorqueTorqueNorm"] =
new Variant(currentTorqueNorm);
627 datafields[
"safeForceGuardOffsetNorm"] =
new Variant(safeForceGuardOffsetNorm);
628 datafields[
"safeTorqueGuardOffsetNorm"] =
new Variant(safeTorqueGuardOffsetNorm);
629 datafields[
"safeForceGuardDifference"] =
630 new Variant(currentForceNorm - safeForceGuardOffsetNorm);
631 datafields[
"safeTorqueGuardDifference"] =
632 new Variant(currentTorqueNorm - safeTorqueGuardOffsetNorm);
633 datafields[
"safeForceGuardThreshold"] =
634 new Variant(rtData.ftConfig.safeGuardForceThreshold);
635 datafields[
"safeTorqueGuardThreshold"] =
636 new Variant(rtData.ftConfig.safeGuardTorqueThreshold);
645 debugObs->setDebugChannel(
getClassName() +
"_" + arm->kinematicChainName, datafields);
651 rtStatus.forceImpedance.head<3>() * 5.0)
662 for (
auto& pair :
limb)
664 if (not pair.second->rtReady.load())
673 for (
auto& pair :
limb)
675 pair.second->rtReady.store(
false);
682 VirtualRobot::RobotNodeSetPtr rns =
rtGetRobot()->getRobotNodeSet(arm->kinematicChainName);
684 auto quat = VirtualRobot::MathTools::eigen4f2quat(currentPose);
686 "[ %.2f, %.2f, %.2f, %.2f, %.2f, %.2f, %.2f ].",
695 if (arm->reInitPreActivate.load())
697 arm->rtConfig.desiredNullspaceJointAngles.value() = rns->getJointValuesEigen();
698 arm->rtConfig.desiredPose = currentPose;
700 arm->bufferConfigUserToNonRt.reinitAllBuffers(arm->rtConfig);
701 arm->reInitPreActivate.store(
false);
704 arm->nonRtConfig = arm->rtConfig;
705 arm->bufferConfigNonRtToRt.reinitAllBuffers(arm->rtConfig);
706 arm->bufferConfigRtToOnPublish.reinitAllBuffers(arm->rtConfig);
707 arm->bufferConfigRtToUser.reinitAllBuffers(arm->rtConfig);
710 arm->sensorDevices.updateJointValues(
711 arm->rtStatus.jointPos, arm->rtStatus.jointVel, arm->rtStatus.jointTor);
712 arm->rtStatus.rtPreActivate(currentPose);
714 arm->rtStatusInNonRT = arm->rtStatus;
715 arm->nonRTDeltaT = 0.0;
716 arm->nonRTAccumulateTime = 0.0;
717 arm->bufferRtStatusToOnPublish.reinitAllBuffers(arm->rtStatus);
718 arm->bufferRtStatusToNonRt.reinitAllBuffers(arm->rtStatus);
719 arm->bufferRtStatusToUser.reinitAllBuffers(arm->rtStatus);
722 arm->controller.preactivateInit(rns);
728 for (
auto& pair :
limb)
732 userConfig.limbs.at(pair.first) = pair.second->rtConfig;
736 hands->rtPreActivate();
753 const std::map<std::string, ConstControlDevicePtr>& controlDevices,
754 const std::map<std::string, ConstSensorDevicePtr>&)
760 ::armarx::WidgetDescription::WidgetSeq widgets;
763 LabelPtr label =
new Label;
764 label->text =
"select a controller config";
766 StringComboBoxPtr cfgBox =
new StringComboBox;
767 cfgBox->name =
"config_box";
768 cfgBox->defaultIndex = 0;
769 cfgBox->multiSelect =
false;
771 cfgBox->options = std::vector<std::string>{
"default",
"default_right",
"default_right_a7"};
774 layout->children.emplace_back(label);
775 layout->children.emplace_back(cfgBox);
778 layout->children.insert(layout->children.end(), widgets.begin(), widgets.end());
787 auto cfgName =
values.at(
"config_box")->getString();
790 "controller_config/NJointTaskspaceMixedImpedanceVelocityController/" + cfgName +
795 auto cfgDTO = armarx::readFromJson<ConfigDict>(configPath.
toSystemPath());
798 return new ConfigurableNJointControllerConfig{cfgDTO.toAronDTO()};