25 #include <VirtualRobot/MathTools.h>
39 NJointControllerRegistration<NJointTaskspaceMixedImpedanceVelocityController>
41 "NJointTaskspaceMixedImpedanceVelocityController");
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 std::vector<size_t> jointIDTorqueMode;
61 std::vector<size_t> jointIDVelocityMode;
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);
68 bool foundControlDevice =
false;
70 cfg.jointNameListTorque.begin(), cfg.jointNameListTorque.end(), jointName);
71 if (it != cfg.jointNameListTorque.end())
75 auto* casted_ct = ct->
asA<ControlTarget1DoFActuatorTorque>();
77 arm->targetsTorque.push_back(casted_ct);
78 jointIDTorqueMode.push_back(i);
79 foundControlDevice =
true;
83 cfg.jointNameListVelocity.begin(), cfg.jointNameListVelocity.end(), jointName);
84 if (it != cfg.jointNameListVelocity.end())
88 auto* casted_ct = ct->
asA<ControlTarget1DoFActuatorVelocity>();
90 arm->targetsVel.push_back(casted_ct);
91 jointIDVelocityMode.push_back(i);
92 foundControlDevice =
true;
94 if (not foundControlDevice)
99 ARMARX_ERROR <<
"Does not found valid control device for joint name: " << jointName
100 <<
"Please check torque controlled joints: [" << namesTorque
101 <<
"] and velocity controlled joints: [" << namesVelocity <<
"].";
106 arm->sensorDevices.append(sv, jointName);
108 ARMARX_DEBUG <<
"Number of torque controlled joints " << jointIDTorqueMode.size();
109 ARMARX_DEBUG <<
"Number of velocity controlled joints " << jointIDVelocityMode.size();
111 jointIDTorqueMode.size() + jointIDVelocityMode.size());
113 arm->controller.initialize(nonRtRns, rtRns, jointIDTorqueMode, jointIDVelocityMode);
114 arm->controller.ftsensor.initialize(rtRns,
robotUnit, cfg.ftConfig);
118 arm->nonRtConfig = cfg;
119 arm->rtStatus.reset(rtRns->getSize(), jointIDTorqueMode.size(), jointIDVelocityMode.size());
124 const NJointControllerConfigPtr& config,
130 ConfigPtrT cfg = ConfigPtrT::dynamicCast(config);
140 limb.emplace(pair.first, std::make_unique<ArmData>());
150 for (
auto& jointName :
hands->hands.at(pair.first)->jointNames)
152 hands->appendDevice(pair.first,
158 <<
hands->hands.at(pair.first)->kinematicChainName;
167 return "NJointTaskspaceMixedImpedanceVelocityController";
173 std::string taskName =
getClassName() +
"AdditionalTask";
185 while (
getState() == eManagedIceObjectStarted)
191 c.waitForCycleDuration();
199 arm->bufferConfigNonRtToRt.getWriteBuffer() = arm->nonRtConfig;
200 arm->bufferConfigNonRtToRt.commitWrite();
219 for (
auto& pair :
limb)
221 auto& arm = pair.second;
222 arm->nonRtConfig = arm->bufferConfigUserToNonRt.getUpToDateReadBuffer();
223 arm->rtStatusInNonRT = arm->bufferRtStatusToNonRt.getUpToDateReadBuffer();
224 rtSafe = rtSafe and pair.second->rtStatusInNonRT.rtSafe;
228 hands->nonRTUpdateStatus();
236 for (
auto& pair :
limb)
242 hands->nonRTSetTarget();
249 for (
auto& pair :
limb)
251 if (not pair.second->rtReady)
254 if (not pair.second->rtStatusInNonRT.rtTargetSafe)
256 pair.second->rtStatusInNonRT =
257 pair.second->bufferRtStatusToNonRt.getUpToDateReadBuffer();
259 pair.second->rtStatusInNonRT.currentPose,
260 pair.second->nonRtConfig.desiredPose,
261 "current pose",
"desired pose");
271 arm->rtConfig = arm->bufferConfigNonRtToRt.getUpToDateReadBuffer();
272 arm->rtStatus.deltaT = deltaT;
274 arm->controller.ftsensor.updateStatus(arm->rtConfig.ftConfig,
275 arm->rtStatus.currentForceTorque,
276 arm->rtStatus.deltaT,
277 arm->rtFirstRun.load());
279 arm->sensorDevices.updateJointValues(
280 arm->rtStatus.jointPos, arm->rtStatus.jointVel, arm->rtStatus.jointTor);
283 arm->bufferRtStatusToNonRt.getWriteBuffer() = arm->rtStatus;
284 arm->bufferRtStatusToNonRt.commitWrite();
285 arm->bufferRtStatusToUser.getWriteBuffer() = arm->rtStatus;
286 arm->bufferRtStatusToUser.commitWrite();
292 const size_t nDoFTorque,
293 const size_t nDoFVelocity,
294 const Eigen::VectorXf& targetTorque,
295 const Eigen::VectorXf& targetVelocity)
297 for (
size_t i = 0; i < nDoFTorque; i++)
299 auto jointIdx = arm->controller.jointIDTorqueMode[i];
300 arm->targetsTorque.at(i)->torque = targetTorque(jointIdx);
301 if (!arm->targetsTorque.at(i)->isValid())
303 arm->targetsTorque.at(i)->torque = 0;
306 for (
size_t i = 0; i < nDoFVelocity; i++)
308 auto jointIdx = arm->controller.jointIDVelocityMode[i];
309 arm->targetsVel.at(i)->velocity = targetVelocity(jointIdx);
311 if (!arm->targetsVel.at(i)->isValid())
313 arm->targetsVel.at(i)->velocity = 0;
316 arm->bufferRtStatusToOnPublish.getWriteBuffer() = arm->rtStatus;
317 arm->bufferRtStatusToOnPublish.commitWrite();
319 arm->bufferConfigRtToOnPublish.getWriteBuffer() = arm->rtConfig;
320 arm->bufferConfigRtToOnPublish.commitWrite();
322 arm->bufferConfigRtToUser.getWriteBuffer() = arm->rtConfig;
323 arm->bufferConfigRtToUser.commitWrite();
325 if (arm->rtFirstRun.load())
327 arm->rtFirstRun.store(
false);
328 arm->rtReady.store(
true);
335 double time_measure = IceUtil::Time::now().toMicroSecondsDouble();
337 double time_update_status = IceUtil::Time::now().toMicroSecondsDouble() - time_measure;
339 arm->controller.run(arm->rtConfig, arm->rtStatus);
340 double time_run_rt = IceUtil::Time::now().toMicroSecondsDouble() - time_measure;
343 arm->rtStatus.nDoFTorque,
344 arm->rtStatus.nDoFVelocity,
345 arm->rtStatus.desiredJointTorques,
346 arm->rtStatus.desiredJointVelocity);
348 double time_set_target = IceUtil::Time::now().toMicroSecondsDouble() - time_measure;
349 time_measure = IceUtil::Time::now().toMicroSecondsDouble() - time_measure;
351 if (time_measure > 200)
354 "time_update_status: %.2f\n"
355 "run_rt_limb: %.2f\n"
356 "set_target_limb: %.2f\n"
359 time_run_rt - time_update_status,
360 time_set_target - time_run_rt,
362 .deactivateSpam(1.0f);
371 double deltaT = timeSinceLastIteration.toSecondsDouble();
372 for (
auto& pair :
limb)
374 limbRT(pair.second, deltaT);
378 hands->updateRTStatus(deltaT);
387 const Ice::Current& iceCurrent)
396 prevCfg.limbs.at(pair.first).desiredPose,
397 "new desired pose",
"previous desired pose",
398 pair.second.safeDistanceMMToGoal,
399 pair.second.safeRotAngleDegreeToGoal,
400 "updateConfig_" + pair.first))
403 pair.second.desiredPose = prevCfg.limbs.at(pair.first).desiredPose;
405 limb.at(pair.first)->bufferConfigUserToNonRt.getWriteBuffer() = pair.second;
406 limb.at(pair.first)->bufferConfigUserToNonRt.commitWrite();
417 for (
auto& pair :
limb)
420 pair.second->bufferConfigRtToUser.getUpToDateReadBuffer();
431 const std::string& nodeSetName,
432 const bool forceGuard,
433 const bool torqueGuard,
434 const Ice::Current& iceCurrent)
439 it->second.ftConfig.enableSafeGuardForce = forceGuard;
440 it->second.ftConfig.enableSafeGuardTorque = torqueGuard;
441 limb.at(nodeSetName)->controller.ftsensor.enableSafeGuard(forceGuard, torqueGuard);
443 <<
"reset safe guard with force torque sensors: safe? "
444 <<
limb.at(nodeSetName)->controller.ftsensor.isSafe(it->second.ftConfig);
445 limb.at(nodeSetName)->bufferConfigUserToNonRt.getWriteBuffer() = it->second;
446 limb.at(nodeSetName)->bufferConfigUserToNonRt.commitWrite();
451 <<
" found in the controllers.";
458 const std::string& nodeSetName,
459 const Ice::Current& iceCurrent)
464 return limb.at(nodeSetName)->controller.ftsensor.ftSafe.load();
469 <<
" found in the controllers.";
476 const Ice::Current& iceCurrent)
478 std::vector<float> tcpVel;
479 auto& arm =
limb.at(rns);
480 auto s = arm->bufferRtStatusToUser.getUpToDateReadBuffer();
481 for (
int i = 0; i <
s.currentTwist.size(); i++)
483 tcpVel.push_back(
s.currentTwist[i]);
492 const Ice::Current& iceCurrent)
496 for (
size_t i = 0; i < 4; ++i)
498 for (
int j = 0; j < 4; ++j)
500 pair.second.desiredPose(i, j) = targetPoseMap.at(pair.first)[i][j];
503 if (targetNullspaceMap.at(pair.first).size() > 0)
505 const size_t nDoF = pair.second.desiredNullspaceJointAngles.value().size();
507 <<
"the joint numbers does not match";
508 for (
size_t i = 0; i < nDoF; ++i)
510 pair.second.desiredNullspaceJointAngles.value()(i) =
511 targetNullspaceMap.at(pair.first)[i];
514 limb.at(pair.first)->bufferConfigUserToNonRt.getWriteBuffer() = pair.second;
515 limb.at(pair.first)->bufferConfigUserToNonRt.commitWrite();
524 const auto nDoF = arm->controller.numOfJoints;
527 const auto checkNonNegative = [](
const auto&
v) {
ARMARX_CHECK((
v.array() >= 0).all()); };
529 if (!configData.desiredNullspaceJointAngles.has_value())
533 ARMARX_INFO <<
"No user defined nullspace target, reset to zero with "
535 configData.desiredNullspaceJointAngles = Eigen::VectorXf::Zero(nDoF);
536 arm->reInitPreActivate.store(
true);
541 arm->bufferConfigRtToUser.getUpToDateReadBuffer().desiredNullspaceJointAngles;
543 <<
"Controller is active, but no user defined nullspace target. \n"
544 "You should first get up-to-date config of this controller and then update "
546 " auto cfg = ctrl->getConfig(); \n"
547 " cfg.desiredPose = xxx;\n"
548 " ctrl->updateConfig(cfg);\n"
549 "Now, I decide by myself to use the existing values of nullspace target\n"
550 << currentValue.value();
551 configData.desiredNullspaceJointAngles = currentValue;
555 checkSize(configData.desiredNullspaceJointAngles.value());
556 checkSize(configData.kdNullspaceTorque);
557 checkSize(configData.kpNullspaceTorque);
558 checkSize(configData.kdNullspaceVel);
559 checkSize(configData.kpNullspaceVel);
561 checkNonNegative(configData.kdNullspaceTorque);
562 checkNonNegative(configData.kpNullspaceTorque);
563 checkNonNegative(configData.kpNullspaceVel);
564 checkNonNegative(configData.kdNullspaceVel);
565 checkNonNegative(configData.kdImpedance);
566 checkNonNegative(configData.kpImpedance);
575 auto rtData = arm->bufferConfigRtToOnPublish.getUpToDateReadBuffer();
576 auto rtStatus = arm->bufferRtStatusToOnPublish.getUpToDateReadBuffer();
590 debugObs->setDebugChannel(
getClassName() +
"_" + arm->kinematicChainName, datafields);
599 for (
auto& pair :
limb)
601 if (not pair.second->rtReady.load())
610 for (
auto& pair :
limb)
612 pair.second->rtReady.store(
false);
619 VirtualRobot::RobotNodeSetPtr rns =
rtGetRobot()->getRobotNodeSet(arm->kinematicChainName);
621 auto quat = VirtualRobot::MathTools::eigen4f2quat(currentPose);
623 "[ %.2f, %.2f, %.2f, %.2f, %.2f, %.2f, %.2f ].",
632 if (arm->reInitPreActivate.load())
634 arm->rtConfig.desiredNullspaceJointAngles.value() = rns->getJointValuesEigen();
635 arm->rtConfig.desiredPose = currentPose;
637 arm->bufferConfigUserToNonRt.reinitAllBuffers(arm->rtConfig);
638 arm->reInitPreActivate.store(
false);
641 arm->nonRtConfig = arm->rtConfig;
642 arm->bufferConfigNonRtToRt.reinitAllBuffers(arm->rtConfig);
643 arm->bufferConfigRtToOnPublish.reinitAllBuffers(arm->rtConfig);
644 arm->bufferConfigRtToUser.reinitAllBuffers(arm->rtConfig);
647 arm->sensorDevices.updateJointValues(
648 arm->rtStatus.jointPos, arm->rtStatus.jointVel, arm->rtStatus.jointTor);
649 arm->rtStatus.rtPreActivate(currentPose);
651 arm->rtStatusInNonRT = arm->rtStatus;
652 arm->bufferRtStatusToOnPublish.reinitAllBuffers(arm->rtStatus);
653 arm->bufferRtStatusToNonRt.reinitAllBuffers(arm->rtStatus);
654 arm->bufferRtStatusToUser.reinitAllBuffers(arm->rtStatus);
657 arm->controller.preactivateInit(rns);
663 for (
auto& pair :
limb)
667 userConfig.limbs.at(pair.first) = pair.second->rtConfig;
671 hands->rtPreActivate();
688 const std::map<std::string, ConstControlDevicePtr>& controlDevices,
689 const std::map<std::string, ConstSensorDevicePtr>&)
695 ::armarx::WidgetDescription::WidgetSeq widgets;
698 LabelPtr label =
new Label;
699 label->text =
"select a controller config";
701 StringComboBoxPtr cfgBox =
new StringComboBox;
702 cfgBox->name =
"config_box";
703 cfgBox->defaultIndex = 0;
704 cfgBox->multiSelect =
false;
706 cfgBox->options = std::vector<std::string>{
"default",
"default_right",
"default_right_a7"};
709 layout->children.emplace_back(label);
710 layout->children.emplace_back(cfgBox);
713 layout->children.insert(layout->children.end(), widgets.begin(), widgets.end());
722 auto cfgName =
values.at(
"config_box")->getString();
725 "controller_config/NJointTaskspaceMixedImpedanceVelocityController/" + cfgName +
730 auto cfgDTO = armarx::readFromJson<ConfigDict>(configPath.
toSystemPath());
733 return new ConfigurableNJointControllerConfig{cfgDTO.toAronDTO()};