25 #include <VirtualRobot/MathTools.h>
39 NJointControllerRegistration<NJointTaskspaceVelocityController>
41 "NJointTaskspaceVelocityController");
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<ControlTarget1DoFActuatorVelocity>();
72 arm->targetsVel.push_back(casted_ct);
76 arm->sensorDevices.append(sv, jointName);
81 arm->nonRtConfig = cfg;
82 arm->rtStatus.reset(rtRns->getSize());
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 "NJointTaskspaceVelocityController";
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(arm->rtConfig.ftConfig,
237 arm->rtStatus.currentForceTorque,
238 arm->rtStatus.deltaT,
239 arm->rtFirstRun.load());
241 arm->sensorDevices.updateJointValues(
242 arm->rtStatus.jointPos, arm->rtStatus.jointVel, arm->rtStatus.jointTor);
245 arm->bufferRtStatusToNonRt.getWriteBuffer() = arm->rtStatus;
246 arm->bufferRtStatusToNonRt.commitWrite();
247 arm->bufferRtStatusToUser.getWriteBuffer() = arm->rtStatus;
248 arm->bufferRtStatusToUser.commitWrite();
254 const Eigen::VectorXf& targetVelocity)
256 for (
unsigned int i = 0; i < targetVelocity.size(); i++)
258 arm->targetsVel.at(i)->velocity = targetVelocity(i);
259 if (!arm->targetsVel.at(i)->isValid())
261 arm->targetsVel.at(i)->velocity = 0;
264 arm->bufferRtStatusToOnPublish.getWriteBuffer() = arm->rtStatus;
265 arm->bufferRtStatusToOnPublish.commitWrite();
267 arm->bufferConfigRtToOnPublish.getWriteBuffer() = arm->rtConfig;
268 arm->bufferConfigRtToOnPublish.commitWrite();
270 arm->bufferConfigRtToUser.getWriteBuffer() = arm->rtConfig;
271 arm->bufferConfigRtToUser.commitWrite();
273 if (arm->rtFirstRun.load())
275 arm->rtFirstRun.store(
false);
276 arm->rtReady.store(
true);
283 double time_measure = IceUtil::Time::now().toMicroSecondsDouble();
285 double time_update_status = IceUtil::Time::now().toMicroSecondsDouble() - time_measure;
287 arm->controller.run(arm->rtConfig, arm->rtStatus);
288 double time_run_rt = IceUtil::Time::now().toMicroSecondsDouble() - time_measure;
292 double time_set_target = IceUtil::Time::now().toMicroSecondsDouble() - time_measure;
293 time_measure = IceUtil::Time::now().toMicroSecondsDouble() - time_measure;
295 if (time_measure > 200)
298 "time_update_status: %.2f\n"
299 "run_rt_limb: %.2f\n"
300 "set_target_limb: %.2f\n"
303 time_run_rt - time_update_status,
304 time_set_target - time_run_rt,
306 .deactivateSpam(1.0f);
315 double deltaT = timeSinceLastIteration.toSecondsDouble();
316 for (
auto& pair :
limb)
318 limbRT(pair.second, deltaT);
322 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 std::string& nodeSetName,
376 const bool forceGuard,
377 const bool torqueGuard,
378 const Ice::Current& iceCurrent)
383 it->second.ftConfig.enableSafeGuardForce = forceGuard;
384 it->second.ftConfig.enableSafeGuardTorque = torqueGuard;
385 limb.at(nodeSetName)->controller.ftsensor.enableSafeGuard(forceGuard, torqueGuard);
387 <<
"reset safe guard with force torque sensors: safe? "
388 <<
limb.at(nodeSetName)->controller.ftsensor.isSafe(it->second.ftConfig);
389 limb.at(nodeSetName)->bufferConfigUserToNonRt.getWriteBuffer() = it->second;
390 limb.at(nodeSetName)->bufferConfigUserToNonRt.commitWrite();
395 <<
" found in the controllers.";
402 const std::string& nodeSetName,
403 const Ice::Current& iceCurrent)
408 return limb.at(nodeSetName)->controller.ftsensor.ftSafe.load();
413 <<
" found in the controllers.";
420 const Ice::Current& iceCurrent)
422 std::vector<float> tcpVel;
423 auto& arm =
limb.at(rns);
424 auto s = arm->bufferRtStatusToUser.getUpToDateReadBuffer();
425 for (
int i = 0; i <
s.currentTwist.size(); i++)
427 tcpVel.push_back(
s.currentTwist[i]);
436 const Ice::Current& iceCurrent)
440 for (
size_t i = 0; i < 4; ++i)
442 for (
int j = 0; j < 4; ++j)
444 pair.second.desiredPose(i, j) = targetPoseMap.at(pair.first)[i][j];
447 if (targetNullspaceMap.at(pair.first).size() > 0)
449 const size_t nDoF = pair.second.desiredNullspaceJointAngles.value().size();
451 <<
"the joint numbers does not match";
452 for (
size_t i = 0; i < nDoF; ++i)
454 pair.second.desiredNullspaceJointAngles.value()(i) =
455 targetNullspaceMap.at(pair.first)[i];
458 limb.at(pair.first)->bufferConfigUserToNonRt.getWriteBuffer() = pair.second;
459 limb.at(pair.first)->bufferConfigUserToNonRt.commitWrite();
468 const auto nDoF = arm->controller.numOfJoints;
471 const auto checkNonNegative = [](
const auto&
v) {
ARMARX_CHECK((
v.array() >= 0).all()); };
473 if (!configData.desiredNullspaceJointAngles.has_value())
477 ARMARX_INFO <<
"No user defined nullspace target, reset to zero with "
479 configData.desiredNullspaceJointAngles = Eigen::VectorXf::Zero(nDoF);
480 arm->reInitPreActivate.store(
true);
485 arm->bufferConfigRtToUser.getUpToDateReadBuffer().desiredNullspaceJointAngles;
487 <<
"Controller is active, but no user defined nullspace target. \n"
488 "You should first get up-to-date config of this controller and then update "
490 " auto cfg = ctrl->getConfig(); \n"
491 " cfg.desiredPose = xxx;\n"
492 " ctrl->updateConfig(cfg);\n"
493 "Now, I decide by myself to use the existing values of nullspace target\n"
494 << currentValue.value();
495 configData.desiredNullspaceJointAngles = currentValue;
499 checkSize(configData.desiredNullspaceJointAngles.value());
500 checkSize(configData.kdNullspaceVel);
501 checkSize(configData.kpNullspaceVel);
503 checkNonNegative(configData.kdNullspaceVel);
504 checkNonNegative(configData.kpNullspaceVel);
505 checkNonNegative(configData.kpNullspaceVel);
506 checkNonNegative(configData.kdNullspaceVel);
515 auto rtData = arm->bufferConfigRtToOnPublish.getUpToDateReadBuffer();
516 auto rtStatus = arm->bufferRtStatusToOnPublish.getUpToDateReadBuffer();
530 debugObs->setDebugChannel(
getClassName() +
"_" + arm->kinematicChainName, datafields);
539 for (
auto& pair :
limb)
541 if (not pair.second->rtReady.load())
550 for (
auto& pair :
limb)
552 pair.second->rtReady.store(
false);
559 VirtualRobot::RobotNodeSetPtr rns =
rtGetRobot()->getRobotNodeSet(arm->kinematicChainName);
561 auto quat = VirtualRobot::MathTools::eigen4f2quat(currentPose);
563 "[ %.2f, %.2f, %.2f, %.2f, %.2f, %.2f, %.2f ].",
572 if (arm->reInitPreActivate.load())
574 arm->rtConfig.desiredNullspaceJointAngles.value() = rns->getJointValuesEigen();
575 arm->rtConfig.desiredPose = currentPose;
577 arm->bufferConfigUserToNonRt.reinitAllBuffers(arm->rtConfig);
578 arm->reInitPreActivate.store(
false);
581 arm->nonRtConfig = arm->rtConfig;
582 arm->bufferConfigNonRtToRt.reinitAllBuffers(arm->rtConfig);
583 arm->bufferConfigRtToOnPublish.reinitAllBuffers(arm->rtConfig);
584 arm->bufferConfigRtToUser.reinitAllBuffers(arm->rtConfig);
587 arm->sensorDevices.updateJointValues(
588 arm->rtStatus.jointPos, arm->rtStatus.jointVel, arm->rtStatus.jointTor);
589 arm->rtStatus.rtPreActivate(currentPose);
591 arm->rtStatusInNonRT = arm->rtStatus;
592 arm->bufferRtStatusToOnPublish.reinitAllBuffers(arm->rtStatus);
593 arm->bufferRtStatusToNonRt.reinitAllBuffers(arm->rtStatus);
594 arm->bufferRtStatusToUser.reinitAllBuffers(arm->rtStatus);
597 arm->controller.preactivateInit(rns);
603 for (
auto& pair :
limb)
607 userConfig.limbs.at(pair.first) = pair.second->rtConfig;
611 hands->rtPreActivate();
628 const std::map<std::string, ConstControlDevicePtr>& controlDevices,
629 const std::map<std::string, ConstSensorDevicePtr>&)
635 ::armarx::WidgetDescription::WidgetSeq widgets;
638 LabelPtr label =
new Label;
639 label->text =
"select a controller config";
641 StringComboBoxPtr cfgBox =
new StringComboBox;
642 cfgBox->name =
"config_box";
643 cfgBox->defaultIndex = 0;
644 cfgBox->multiSelect =
false;
646 cfgBox->options = std::vector<std::string>{
"default",
"default_right",
"default_right_a7"};
649 layout->children.emplace_back(label);
650 layout->children.emplace_back(cfgBox);
653 layout->children.insert(layout->children.end(), widgets.begin(), widgets.end());
662 auto cfgName =
values.at(
"config_box")->getString();
665 "controller_config/NJointTaskspaceVelocityController/" + cfgName +
670 auto cfgDTO = armarx::readFromJson<ConfigDict>(configPath.
toSystemPath());
673 return new ConfigurableNJointControllerConfig{cfgDTO.toAronDTO()};