Base.cpp
Go to the documentation of this file.
1/*
2 * This file is part of ArmarX.
3 *
4 * ArmarX is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License version 2 as
6 * published by the Free Software Foundation.
7 *
8 * ArmarX is distributed in the hope that it will be useful, but
9 * WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
12 *
13 * You should have received a copy of the GNU General Public License
14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
15 *
16 * @package ...
17 * @author Jianfeng Gao ( jianfeng dot gao at kit dot edu )
18 * @date 2025
19 * @copyright http://www.gnu.org/licenses/gpl-2.0.txt
20 * GNU General Public License
21 */
22
23#include "Base.h"
24
25#include <SimoxUtility/color/Color.h>
26#include <VirtualRobot/MathTools.h>
27#include <VirtualRobot/RobotNodeSet.h>
28
32
35// #include <RobotAPI/components/units/RobotUnit/NJointControllers/NJointController.h>
38// #include <RobotAPI/libraries/RobotAPIComponentPlugins/ArVizComponentPlugin.h>
39
42
43/// for GUI
44#include <ArmarXCore/core/PackagePath.h> // for GUI
46
48
49/// HandUnit
50//#include <RobotAPI/interface/units/HandUnitInterface.h>
51
53{
54
55 template <typename NJointTaskspaceControllerType>
56 void
58 const std::string& nodeSetName,
59 ArmPtr& arm,
60 Config& cfg,
61 VirtualRobot::RobotPtr& nonRtRobotPtr)
62 {
63 arm->kinematicChainName = nodeSetName;
64 VirtualRobot::RobotNodeSetPtr rtRns =
65 rtGetRobot()->getRobotNodeSet(arm->kinematicChainName);
66 VirtualRobot::RobotNodeSetPtr nonRtRns =
67 nonRtRobotPtr->getRobotNodeSet(arm->kinematicChainName);
68 ARMARX_CHECK_EXPRESSION(rtRns) << arm->kinematicChainName;
69 ARMARX_CHECK_EXPRESSION(nonRtRns) << arm->kinematicChainName;
70 ARMARX_IMPORTANT << "--> Creating Taskspace controller with kinematic chain: "
71 << arm->kinematicChainName << " with num of joints: (RT robot) "
72 << rtRns->getSize() << ", and (non-RT robot) " << nonRtRns->getSize();
73
74 std::vector<size_t> jointIDTorqueMode;
75 std::vector<size_t> jointIDVelocityMode;
76 arm->jointNames.clear();
77 for (size_t i = 0; i < rtRns->getSize(); ++i)
78 {
79 std::string jointName = rtRns->getNode(i)->getName();
80 arm->jointNames.push_back(jointName);
81
82 bool foundControlDevice = false;
83 auto it = std::find(
84 cfg.jointNameListTorque.begin(), cfg.jointNameListTorque.end(), jointName);
85 if (it != cfg.jointNameListTorque.end())
86 {
87 ControlTargetBase* ct = useControlTarget(jointName, ControlModes::Torque1DoF);
89 auto* casted_ct = ct->asA<ControlTarget1DoFActuatorTorque>();
90 ARMARX_CHECK_EXPRESSION(casted_ct);
91 arm->targetsTorque.push_back(casted_ct);
92 jointIDTorqueMode.push_back(i);
93 foundControlDevice = true;
94 }
95
96 it = std::find(
97 cfg.jointNameListVelocity.begin(), cfg.jointNameListVelocity.end(), jointName);
98 if (it != cfg.jointNameListVelocity.end())
99 {
100 ControlTargetBase* ct = useControlTarget(jointName, ControlModes::Velocity1DoF);
102 auto* casted_ct = ct->asA<ControlTarget1DoFActuatorVelocity>();
103 ARMARX_CHECK_EXPRESSION(casted_ct);
104 arm->targetsVel.push_back(casted_ct);
105 jointIDVelocityMode.push_back(i);
106 foundControlDevice = true;
107 }
108 if (not foundControlDevice)
109 {
110 auto namesTorque = armarx::control::common::sVecToString(cfg.jointNameListTorque);
111 auto namesVelocity =
112 armarx::control::common::sVecToString(cfg.jointNameListVelocity);
113 ARMARX_ERROR << "Does not found valid control device for joint name: " << jointName
114 << "Please check torque controlled joints: [" << namesTorque
115 << "] and velocity controlled joints: [" << namesVelocity << "].";
117
118 const SensorValueBase* sv = useSensorValue(jointName);
120 arm->sensorDevices.append(sv, jointName);
121 };
122 ARMARX_DEBUG << "Number of torque controlled joints " << jointIDTorqueMode.size();
123 ARMARX_DEBUG << "Number of velocity controlled joints " << jointIDVelocityMode.size();
124 ARMARX_CHECK_EQUAL(rtRns->getNodeNames().size(),
125 jointIDTorqueMode.size() + jointIDVelocityMode.size());
126
127 arm->controller.initialize(nonRtRns, rtRns);
128 arm->controller.ftsensor.initialize(rtRns, robotUnit, cfg.ftConfig);
130 validateConfigData(cfg, arm);
131 arm->rtConfig = cfg;
132 arm->nonRtConfig = cfg;
133 arm->rtStatus.reset(rtRns->getSize(), jointIDTorqueMode, jointIDVelocityMode);
134 ARMARX_INFO << "<-- Limb " << arm->kinematicChainName << " created";
136
137 template <typename NJointTaskspaceControllerType>
140 const NJointControllerConfigPtr& config,
141 const VirtualRobot::RobotPtr&) :
144 ARMARX_INFO << "================ creating controller ============================";
146
147 // // Type: ::armarx::HandUnitInterfacePrx
148 // // auto handUnit = robotUnit->getUnitPrx<::armarx::HandUnitInterface>();
149 // auto handUnit = robotUnit->getUnit<::armarx::HandUnitInterface>();
150 // auto jointValues = handUnit->getCurrentJointValues();
151 // for (auto& pair : jointValues)
152 // {
153 // ARMARX_INFO << " --- joint: " << pair.first << ": " << pair.second;
154 // }
155 // // handUnit->setJointAngles();
156 // // Hand_L_EEF_NJointKITHandV2ShapeController
157 // // Hand_R_EEF_NJointKITHandV2ShapeController
158 // // NJointKITHandV2ShapeController
159
160
161 ConfigPtrT cfg = ConfigPtrT::dynamicCast(config);
163 userConfig.fromAron(cfg->config);
164
166 nonRtRobot = robotUnit->cloneRobot();
167 robotUnit->updateVirtualRobot(nonRtRobot);
168 }
170 template <typename NJointTaskspaceControllerType>
171 void
174 for (auto& pair : userConfig.limbs)
176 limb.emplace(pair.first, std::make_unique<ArmData>());
177 limbInit(pair.first, limb.at(pair.first), pair.second, nonRtRobot);
178 controllableNodeSets.emplace(pair.first, nonRtRobot->getRobotNodeSet(pair.first));
180
181 if (not userConfig.hands.empty())
183 createHands();
186
187 template <typename NJointTaskspaceControllerType>
188 void
189 NJointTaskspaceController<NJointTaskspaceControllerType>::createHands()
190 {
192 hands = std::make_shared<core::HandControlBase>(robotUnit, nonRtRobot, userConfig.hands);
193 for (auto& [name, hand_cfg] : userConfig.hands)
195 ARMARX_INFO << "-- Creating hand: " << hands->hands.at(name)->kinematicChainName;
196 controllableNodeSets.emplace(name, nonRtRobot->getRobotNodeSet(name));
197 }
198 }
200 template <typename NJointTaskspaceControllerType>
201 void
203 {
204 std::string taskName = getClassName() + "AdditionalTask";
205 runTask(taskName,
206 [&]
207 {
209 4); // please don't set this to 0 as it is the rtRun/control thread
212
213 CycleUtil c(1);
214 getObjectScheduler()->waitForObjectStateMinimum(eManagedIceObjectStarted);
215 ARMARX_IMPORTANT << "Create a new thread for " << getClassName();
216 while (getState() == eManagedIceObjectStarted)
217 {
218 if (isControllerActive())
219 {
221 }
222 c.waitForCycleDuration();
223 }
224 });
225 }
226
227 template <typename NJointTaskspaceControllerType>
228 void
230 {
231 arm->bufferConfigNonRtToRt.getWriteBuffer() = arm->nonRtConfig;
232 arm->bufferConfigNonRtToRt.commitWrite();
235 template <typename NJointTaskspaceControllerType>
236 void
238 {
239 // bool rtSafe = additionalTaskUpdateStatus();
240 auto [rtTargetSafe, ftSafe] = additionalTaskUpdateStatus();
242 if (not rtTargetSafe)
243 {
245 }
246 }
247
248 template <typename NJointTaskspaceControllerType>
249 std::tuple<bool, bool>
251 {
252 robotUnit->updateVirtualRobot(nonRtRobot);
253 bool rtSafe = true;
254 bool rtTargetSafe = true;
255 bool forceTorqueSafe = true;
256 for (auto& pair : limb)
257 {
258 auto& arm = pair.second;
259 arm->nonRtConfig = arm->bufferConfigUserToNonRt.getUpToDateReadBuffer();
260 arm->rtStatusInNonRT = arm->bufferRtStatusToNonRt.getUpToDateReadBuffer();
261 rtSafe = rtSafe and pair.second->rtStatusInNonRT.rtSafe;
262 rtTargetSafe = rtTargetSafe and pair.second->rtStatusInNonRT.rtTargetSafe;
263 forceTorqueSafe = forceTorqueSafe and pair.second->rtStatusInNonRT.forceTorqueSafe;
264 }
265 if (hands)
266 {
267 hands->nonRTUpdateStatus();
268 }
269 return std::make_tuple(rtTargetSafe, forceTorqueSafe);
270 }
271
272 template <typename NJointTaskspaceControllerType>
273 bool
275 {
276 bool rtDesiredPoseSafe = true;
277 for (auto& [_, arm] : limb)
278 {
279 rtDesiredPoseSafe = rtDesiredPoseSafe and arm->rtStatusInNonRT.rtTargetSafe;
280 }
281 return rtDesiredPoseSafe;
282 }
283
284 template <typename NJointTaskspaceControllerType>
285 bool
287 NJointTaskspaceControllerType>::rtGetDesiredPoseSafeStatusOnActivation()
288 {
289 bool rtDesiredPoseSafe = true;
290 for (auto& [_, arm] : limb)
291 {
292 rtDesiredPoseSafe = rtDesiredPoseSafe and arm->desiredPoseSafeOnActivation.load();
293 }
294 return rtDesiredPoseSafe;
295 }
296
297 template <typename NJointTaskspaceControllerType>
298 void
300 {
301 for (auto& [_, arm] : limb)
302 {
303 limbNonRT(arm);
304 }
305 if (hands)
306 {
307 hands->nonRTSetTarget();
308 }
309 }
310
311 template <typename NJointTaskspaceControllerType>
312 void
314 {
315 for (auto& pair : limb)
316 {
317 if (not pair.second->rtReady)
318 {
319 continue;
320 }
321
322 if (not pair.second->rtStatusInNonRT.rtTargetSafe)
323 {
325 pair.second->rtStatusInNonRT.currentPose,
326 pair.second->rtStatusInNonRT.desiredPoseUnsafe,
327 "current pose",
328 "desired pose");
329 }
330 }
331 }
332
333 /// -------------------------------- Real time cotnrol -----------------------------------------
334 template <typename NJointTaskspaceControllerType>
335 void
337 ArmPtr& arm,
338 const double deltaT)
339 {
340 arm->rtConfig = arm->bufferConfigNonRtToRt.getUpToDateReadBuffer();
341 arm->rtStatus.deltaT = deltaT;
342 arm->rtStatus.accumulateTime += deltaT;
343 arm->rtStatus.globalPose = rtGetRobot()->getGlobalPose();
344
345 arm->controller.ftsensor.updateStatus(arm->rtConfig.ftConfig,
346 arm->rtStatus.currentForceTorque,
347 arm->rtStatus.deltaT,
348 arm->rtFirstRun.load());
349 arm->rtStatus.safeFTGuardOffset.template head<3>() =
350 arm->controller.ftsensor.getSafeGuardForceOffset();
351
352 arm->sensorDevices.updateJointValues(
353 arm->rtStatus.jointPosition, arm->rtStatus.jointVelocity, arm->rtStatus.jointTorque);
354 // rtGetRobot()->getRobotNodeSet(arm->kinematicChainName)
355
356
357 arm->bufferRtStatusToNonRt.getWriteBuffer() = arm->rtStatus;
358 arm->bufferRtStatusToNonRt.commitWrite();
359 arm->bufferRtStatusToUser.getWriteBuffer() = arm->rtStatus;
360 arm->bufferRtStatusToUser.commitWrite();
361 }
362
363 template <typename NJointTaskspaceControllerType>
364 void
366 ArmPtr& arm,
367 const size_t nDoFTorque,
368 const size_t nDoFVelocity,
369 const Eigen::VectorXf& targetTorque,
370 const Eigen::VectorXf& targetVelocity)
371 {
372 for (size_t i = 0; i < nDoFTorque; i++)
373 {
374
375 auto jointIdx = arm->rtStatus.jointIDTorqueMode[i];
376 arm->targetsTorque.at(i)->torque = targetTorque(jointIdx);
377 if (!arm->targetsTorque.at(i)->isValid())
378 {
379 arm->targetsTorque.at(i)->torque = 0;
380 }
381 }
382 for (size_t i = 0; i < nDoFVelocity; i++)
383 {
384 auto jointIdx = arm->rtStatus.jointIDVelocityMode[i];
385 arm->targetsVel.at(i)->velocity = targetVelocity(jointIdx);
386 // if (!targets.at(i)->isValid() || fabs(targets.at(i)->velocity) > cfg->maxJointVelocity)
387 if (!arm->targetsVel.at(i)->isValid())
388 {
389 arm->targetsVel.at(i)->velocity = 0;
390 }
391 }
392 arm->bufferRtStatusToOnPublish.getWriteBuffer() = arm->rtStatus;
393 arm->bufferRtStatusToOnPublish.commitWrite();
394
395 arm->bufferConfigRtToOnPublish.getWriteBuffer() = arm->rtConfig;
396 arm->bufferConfigRtToOnPublish.commitWrite();
397
398 arm->bufferConfigRtToUser.getWriteBuffer() = arm->rtConfig;
399 arm->bufferConfigRtToUser.commitWrite();
400
401 if (arm->rtFirstRun.load())
402 {
403 arm->rtFirstRun.store(false);
404 arm->rtReady.store(true);
405 }
406 }
407
408 template <typename NJointTaskspaceControllerType>
409 void
411 const double /*deltaT*/)
412 {
413 double time_measure = IceUtil::Time::now().toMicroSecondsDouble();
414 // limbRTUpdateStatus(arm, deltaT);
415 // double time_update_status = IceUtil::Time::now().toMicroSecondsDouble() - time_measure;
416
417 arm->controller.run(arm->rtConfig, arm->rtStatus);
418 double time_run_rt = IceUtil::Time::now().toMicroSecondsDouble() - time_measure;
419
420 limbRTSetTarget(arm,
421 arm->rtStatus.nDoFTorque,
422 arm->rtStatus.nDoFVelocity,
423 arm->rtStatus.desiredJointTorque,
424 arm->rtStatus.desiredJointVelocity);
425
426 double time_set_target = IceUtil::Time::now().toMicroSecondsDouble() - time_measure;
427 time_measure = IceUtil::Time::now().toMicroSecondsDouble() - time_measure;
428
429 if (time_measure > 200)
430 {
431 ARMARX_RT_LOGF_WARN("---- rt too slow: "
432 "run_rt_limb: %.2f\n"
433 "set_target_limb: %.2f\n"
434 "time all: %.2f\n",
435 time_run_rt - time_measure, //
436 time_set_target - time_run_rt, //
437 time_measure)
438 .deactivateSpam(1.0f); // 0-1 us
439 }
440 }
441
442 /// some method for coordinator
443 template <typename NJointTaskspaceControllerType>
444 void
446 const std::string& key,
447 const Eigen::Matrix4f& targetPose,
448 const PoseFrameMode& targetPoseMode,
449 const Eigen::Matrix4f& pose,
450 const Eigen::Vector6f& vel,
451 const Eigen::Vector6f& ft,
452 const Eigen::Vector6f& stiffness)
453 {
454 if (coordinatorInputData.find(key) != coordinatorInputData.end())
455 {
456 // Update existing InputData
457 auto& data = coordinatorInputData.at(key);
458 data.pose = pose;
459 data.targetPose = targetPose;
460 data.targetPoseMode = targetPoseMode;
461 data.vel = vel;
462 data.ft = ft;
463 data.stiffness = stiffness;
464 }
465 else
466 {
467 coordinatorInputData.emplace(key,
469 targetPose, targetPoseMode, pose, vel, ft, stiffness));
470 }
471 }
472
473 template <typename NJointTaskspaceControllerType>
474 void
476 {
477 if (not coordinatorEnabled.load() or not coordinator)
478 {
479 return;
480 }
481
482 bool rtReady = false;
483 for (const auto& nodeset : coordinator->getNodesetList())
484 {
485 auto& rts = limb.at(nodeset)->rtStatus;
486 auto& rtc = limb.at(nodeset)->rtConfig;
487 rtReady = limb.at(nodeset)->rtReady.load();
488 /// TODO, fix this for vel controller, as it does not have kpImpedance
489 if constexpr (NJointTaskspaceControllerType::IsCompliant)
490 {
491 updateInputData(nodeset,
492 rtc.desiredPose,
493 rtc.desiredPoseFrameMode,
494 rts.currentPose,
495 rts.currentTwist,
496 rts.currentForceTorque,
497 rtc.kpImpedance);
498 }
499 else
500 {
501 ARMARX_WARNING << "Not implemented yet for controller types without kpImpedance";
502 return;
503 }
504 }
505 if (not rtReady)
506 {
507 return;
508 }
509 coordinator->runRT(coordinatorInputData, deltaT);
510 for (const auto& nodeset : coordinator->getNodesetList())
511 {
512 limb.at(nodeset)->rtConfig.desiredPose = coordinatorInputData.at(nodeset).targetPose;
513 limb.at(nodeset)->rtConfig.desiredPoseFrameMode = PoseFrameMode::root;
514 }
515 }
516
517 template <typename NJointTaskspaceControllerType>
518 void
520 const IceUtil::Time& /*sensorValuesTimestamp*/,
521 const IceUtil::Time& timeSinceLastIteration)
522 {
523 double deltaT = timeSinceLastIteration.toSecondsDouble();
524 for (auto& pair : limb)
525 {
526 limbRTUpdateStatus(pair.second, deltaT);
527 }
528
529 rtRunCoordinator(deltaT);
530
531 for (auto& pair : limb)
532 {
533 limbRT(pair.second, deltaT);
534 }
535 if (hands)
536 {
537 hands->updateRTStatus(deltaT);
538 // hands->setTargets();
539 }
540 }
541
542 /// ------------------------------ update/get config -------------------------------------------
543 template <typename NJointTaskspaceControllerType>
544 void
546 const ::armarx::aron::data::dto::DictPtr& dto,
547 const Ice::Current& /*iceCurrent*/)
548 {
549 auto prevCfg = userConfig;
550 userConfig.fromAron(dto);
551
552 for (auto& pair : userConfig.limbs)
553 {
554 auto& arm = limb.at(pair.first);
555 validateConfigData(pair.second, arm);
556 bool desiredPoseFrameModeSame = prevCfg.limbs.at(pair.first).desiredPoseFrameMode ==
557 pair.second.desiredPoseFrameMode;
558 if (desiredPoseFrameModeSame and common::detectAndReportPoseDeviationWarning(
559 pair.second.desiredPose,
560 prevCfg.limbs.at(pair.first).desiredPose,
561 "new desired pose",
562 "previous desired pose",
563 pair.second.safeDistanceMMToGoal,
564 pair.second.safeRotAngleDegreeToGoal,
565 "updateConfig_" + pair.first))
566 {
567 ARMARX_INFO << deactivateSpam(2) << "-- use the existing target pose.";
568 pair.second.desiredPose = prevCfg.limbs.at(pair.first).desiredPose;
569 }
570 arm->bufferConfigUserToNonRt.getWriteBuffer() = pair.second;
571 if (not isControllerActive())
572 {
573 arm->nonRtConfig = arm->bufferConfigUserToNonRt.getWriteBuffer();
574 }
575 arm->bufferConfigUserToNonRt.commitWrite();
576
577 /// When user updates the controller config before the controller is activated, we need
578 /// to copy the userconfig to rt data struct directly, as upon activation, the rtConfig
579 /// will be validated and used to reinitialize all buffers.
580 if (not isControllerActive())
581 {
582 arm->rtConfig = arm->nonRtConfig;
583 }
584 }
585
586 if (hands)
587 {
588 hands->updateConfig(userConfig.hands);
589 }
590 else
591 {
592 if (not userConfig.hands.empty())
593 {
594 createHands();
595 }
596 }
597 }
598
599 template <typename NJointTaskspaceControllerType>
602 const Ice::Current& /*iceCurrent*/)
603 {
604 for (auto& pair : limb)
605 {
606 userConfig.limbs.at(pair.first) =
607 pair.second->bufferConfigRtToUser.getUpToDateReadBuffer();
608 }
609 if (hands)
610 {
611 hands->getConfig(userConfig.hands);
612 }
613 return userConfig.toAronDTO();
614 }
615
616 template <typename NJointTaskspaceControllerType>
619 const Ice::Current& /*iceCurrent*/)
620 {
621 for (auto& pair : limb)
622 {
623 userConfig.limbs.at(pair.first) =
624 pair.second->bufferConfigRtToUser.getUpToDateReadBuffer();
625 }
626 if (hands)
627 {
628 hands->getConfig(userConfig.hands);
629 }
630 return userConfig.toAronDTO();
631 }
632
633 template <typename NJointTaskspaceControllerType>
634 void
636 const std::string& nodeSetName,
637 const bool forceGuard,
638 const bool torqueGuard,
639 const Ice::Current& /*iceCurrent*/)
640 {
641 auto it = userConfig.limbs.find(nodeSetName);
642 if (it != userConfig.limbs.end())
643 {
644 it->second.ftConfig.enableSafeGuardForce = forceGuard;
645 it->second.ftConfig.enableSafeGuardTorque = torqueGuard;
646 limb.at(nodeSetName)->controller.ftsensor.enableSafeGuard(forceGuard, torqueGuard);
648 << "reset safe guard with force torque sensors: safe? "
649 << limb.at(nodeSetName)->controller.ftsensor.isSafe(it->second.ftConfig);
650 limb.at(nodeSetName)->bufferConfigUserToNonRt.getWriteBuffer() = it->second;
651 limb.at(nodeSetName)->bufferConfigUserToNonRt.commitWrite();
652 }
653 else
654 {
655 ARMARX_WARNING << "no robot node set with name " << nodeSetName
656 << " found in the controllers.";
657 }
658 }
659
660 /// -------------------------------- Other interaces -------------------------------------------
661 template <typename NJointTaskspaceControllerType>
662 bool
664 const std::string& nodeSetName,
665 const Ice::Current& /*iceCurrent*/)
666 {
667 auto it = userConfig.limbs.find(nodeSetName);
668 if (it != userConfig.limbs.end())
669 {
670 return limb.at(nodeSetName)->controller.ftsensor.ftSafe.load();
671 }
672
673 ARMARX_WARNING << "no robot node set with name " << nodeSetName
674 << " found in the controllers.";
675 return false;
676 }
677
678 template <typename NJointTaskspaceControllerType>
679 bool
681 const std::string& nodeSetName,
682 const Ice::Current& /*iceCurrent*/)
683 {
684 auto it = userConfig.limbs.find(nodeSetName);
685 if (it != userConfig.limbs.end())
686 {
687 return limb.at(nodeSetName)->controller.ftsensor.ftWasNotSafe.load();
688 }
689
690 ARMARX_WARNING << "no robot node set with name " << nodeSetName
691 << " found in the controllers.";
692 return false;
693 }
694
695 template <typename NJointTaskspaceControllerType>
696 Ice::FloatSeq
698 const std::string& rns,
699 const Ice::Current& /*iceCurrent*/)
700 {
701 std::vector<float> tcpVel;
702 auto& arm = limb.at(rns);
703 auto s = arm->bufferRtStatusToUser.getUpToDateReadBuffer();
704 tcpVel.reserve(s.currentTwist.size());
705 for (int i = 0; i < s.currentTwist.size(); i++)
706 {
707 tcpVel.push_back(s.currentTwist[i]);
708 }
709 return tcpVel;
710 }
711
712 template <typename NJointTaskspaceControllerType>
713 Ice::DoubleSeq
715 const std::string& nodeSetName,
716 const Ice::Current& /*iceCurrent*/)
717 {
718 auto search = limb.find(nodeSetName);
719 if (search == limb.end())
720 {
721 ARMARX_WARNING << "requested node set " << nodeSetName
722 << "does not exist in the controller";
723 return std::vector<double>{};
724 }
725
726 auto& arm = limb.at(nodeSetName);
727 auto currentPose = arm->bufferRtStatusToOnPublish.getUpToDateReadBuffer().currentPose;
728 ARMARX_DEBUG << "returning current pose" << VAROUT(currentPose);
729 return common::mat4ToDVec(currentPose);
730 }
731
732 template <typename NJointTaskspaceControllerType>
733 bool
735 const TargetPoseMap& targetPoseMap,
736 const TargetNullspaceMap& targetNullspaceMap,
737 const Ice::Current& /*iceCurrent*/)
738 {
739 for (auto& pair : userConfig.limbs)
740 {
741 for (size_t i = 0; i < 4; ++i)
742 {
743 for (int j = 0; j < 4; ++j)
744 {
745 pair.second.desiredPose(i, j) = targetPoseMap.at(pair.first)[i][j];
746 }
747 }
748 if (targetNullspaceMap.at(pair.first).size() > 0)
749 {
750 const size_t nDoF = pair.second.desiredNullspaceJointAngles.value().size();
751 ARMARX_CHECK_EQUAL(targetNullspaceMap.at(pair.first).size(), nDoF)
752 << "the joint numbers does not match";
753 for (size_t i = 0; i < nDoF; ++i)
754 {
755 pair.second.desiredNullspaceJointAngles.value()(i) =
756 targetNullspaceMap.at(pair.first)[i];
757 }
758 }
759 limb.at(pair.first)->bufferConfigUserToNonRt.getWriteBuffer() = pair.second;
760 limb.at(pair.first)->bufferConfigUserToNonRt.commitWrite();
761 }
762 return true;
763 }
764
765 template <typename NJointTaskspaceControllerType>
766 void
768 ArmPtr& arm)
769 {
770 const auto nDoF = arm->jointNames.size();
771 if (!configData.desiredNullspaceJointAngles.has_value())
772 {
773 if (!isControllerActive())
774 {
775 ARMARX_INFO << "-- No user defined nullspace target, reset to zero with "
776 << VAROUT(nDoF);
777 configData.desiredNullspaceJointAngles = Eigen::VectorXf::Zero(nDoF);
778 arm->reInitPreActivate.store(true);
779 }
780 else
781 {
782 auto currentValue =
783 arm->bufferConfigRtToUser.getUpToDateReadBuffer().desiredNullspaceJointAngles;
785 << "Controller is active, but no user defined nullspace target. \n"
786 "You should first get up-to-date config of this controller and then "
787 "update "
788 "it:\n"
789 " auto cfg = ctrl->getConfig(); \n"
790 " cfg.desiredPose = xxx;\n"
791 " ctrl->updateConfig(cfg);\n"
792 "Now, I decide by myself to use the existing values of nullspace "
793 "target\n"
794 << currentValue.value();
795 configData.desiredNullspaceJointAngles = currentValue;
796 }
797 }
798 ARMARX_CHECK_GREATER(configData.safeDistanceMMToGoal, 100.0f);
799 validateConfigDataCheckSize(configData, arm);
800 }
801
802 template <typename NJointTaskspaceControllerType>
803 void
805 ArmPtr& arm,
806 const DebugObserverInterfacePrx& debugObs)
807 {
808 StringVariantBaseMap datafields;
809 auto rtStatus = arm->bufferRtStatusToOnPublish.getUpToDateReadBuffer();
810 auto cfgNonRt = arm->bufferConfigNonRtToPublish.getUpToDateReadBuffer();
811
812 limbPublishConfig(datafields, arm);
813
814 datafields["nDoFTorque"] = new Variant(rtStatus.nDoFTorque);
815 datafields["nDoFVelocity"] = new Variant(rtStatus.nDoFVelocity);
816
817 common::debugEigenVec(datafields, "jointPosition", rtStatus.jointPosition);
818 common::debugEigenVec(datafields, "jointVelocity", rtStatus.jointVelocity);
819 common::debugEigenVec(datafields, "qvelFiltered", rtStatus.qvelFiltered);
820
821 common::debugEigenPose(datafields, "current_pose", rtStatus.currentPose);
822 common::debugEigenPose(datafields, "desired_pose", rtStatus.desiredPose);
823 common::debugEigenPose(datafields, "desired_pose_user", cfgNonRt.desiredPose);
824
825 datafields["cfg.velocity_limit"] = new Variant(cfgNonRt.velocityLimit);
826 datafields["cfg.torque_limit"] = new Variant(cfgNonRt.torqueLimit);
827 datafields["ft.safeGuardForceThreshold"] =
828 new Variant(cfgNonRt.ftConfig.safeGuardForceThreshold);
829 datafields["ft.safeGuardTorqueThreshold"] =
830 new Variant(cfgNonRt.ftConfig.safeGuardTorqueThreshold);
831
832
833 float positionError =
834 (common::getPos(rtStatus.currentPose) - common::getPos(rtStatus.desiredPose)).norm();
835 float angleError =
836 common::getDeltaAngleBetweenPose(rtStatus.currentPose, rtStatus.desiredPose);
837 datafields["poseError_position"] = new Variant(positionError);
838 datafields["poseError_angle"] = new Variant(angleError);
839
840 common::debugEigenVec(datafields, "current_twist", rtStatus.currentTwist);
841 common::debugEigenVec(datafields, "poseErrorImp", rtStatus.poseErrorImp);
842
843 common::debugEigenVec(datafields, "currentForceTorque", rtStatus.currentForceTorque);
844 common::debugEigenVec(datafields, "safeFTGuardOffset", rtStatus.safeFTGuardOffset);
845
846 /// admittance interface
847 common::debugEigenMat(datafields, "inertia", rtStatus.inertia);
848 common::debugEigenMat(datafields, "inertiaVelCtrlJoints", rtStatus.inertiaVelCtrlJoints);
850 datafields, "inertiaInvVelCtrlJoints", rtStatus.inertiaInvVelCtrlJoints);
851 common::debugEigenVec(datafields, "qdVel", rtStatus.qdVel);
852 common::debugEigenVec(datafields, "qdAcc", rtStatus.qdAcc);
853 common::debugEigenVec(datafields, "qTemp", rtStatus.qTemp);
854
855 float currentForceNorm = rtStatus.currentForceTorque.template head<3>().norm();
856 float currentTorqueNorm = rtStatus.currentForceTorque.template tail<3>().norm();
857 float safeForceGuardOffsetNorm = rtStatus.safeFTGuardOffset.template head<3>().norm();
858 float safeTorqueGuardOffsetNorm = rtStatus.safeFTGuardOffset.template tail<3>().norm();
859 datafields["currentForceNorm"] = new Variant(currentForceNorm);
860 datafields["currentTorqueNorm"] = new Variant(currentTorqueNorm);
861 datafields["safeForceGuardOffsetNorm"] = new Variant(safeForceGuardOffsetNorm);
862 datafields["safeTorqueGuardOffsetNorm"] = new Variant(safeTorqueGuardOffsetNorm);
863 datafields["safeForceGuardDifference"] =
864 new Variant(currentForceNorm - safeForceGuardOffsetNorm);
865 datafields["safeTorqueGuardDifference"] =
866 new Variant(currentTorqueNorm - safeTorqueGuardOffsetNorm);
867
868 datafields["rtSafe"] = new Variant(rtStatus.rtSafe * 1.0);
869 datafields["rtTargetSafe"] = new Variant(rtStatus.rtTargetSafe * 1.0);
870 bool forceTrigger = (not rtStatus.rtSafe) and rtStatus.rtTargetSafe;
871 datafields["forceTrigger"] = new Variant(forceTrigger * 1.0);
872 datafields["forceTorqueSafe"] = new Variant(rtStatus.forceTorqueSafe * 1.0);
873
874 common::debugEigenVec(datafields, "forceImpedance", rtStatus.forceImpedance);
875 common::debugEigenVec(datafields, "cartesianVelTarget", rtStatus.cartesianVelTarget);
876
877 common::debugEigenVec(datafields, "desiredJointTorques", rtStatus.desiredJointTorque);
878 common::debugEigenVec(datafields, "desiredJointVelocity", rtStatus.desiredJointVelocity);
879 common::debugEigenVec(datafields, "nullspaceTorque", rtStatus.nullspaceTorque);
880 common::debugEigenVec(datafields, "nullspaceVelocity", rtStatus.nullspaceVelocity);
881 debugObs->setDebugChannel(getClassName() + "_" + arm->kinematicChainName, datafields);
882 }
883
884 template <typename NJointTaskspaceControllerType>
885 void
887 const SensorAndControl& /*unused*/,
888 const DebugDrawerInterfacePrx& /*unused*/,
889 const DebugObserverInterfacePrx& debugObs)
890 {
891 for (auto& pair : limb)
892 {
893 if (not pair.second->rtReady.load())
894 {
895 continue;
896 }
897 limbPublish(pair.second, debugObs);
898 }
899 if (hands)
900 {
901 hands->onPublish(debugObs);
902 }
903 onPublishCoordinator(debugObs);
904
905 if (++skipStepCountArviz_ >= skipStepsArviz_)
906 {
907 skipStepCountArviz_ = 0;
908 commitArviz();
909 }
910 }
911
912 template <typename NJointTaskspaceControllerType>
913 void
915 const DebugObserverInterfacePrx& debugObs)
916 {
917 if (!coordinator)
918 {
919 return;
920 }
921 StringVariantBaseMap datafields;
922 auto& cfg = coordinator->bufferUserCfgToPublish.getUpToDateReadBuffer();
923 auto data = coordinator->bufferDataRtToPublish.getUpToDateReadBuffer();
924 common::debugEigenPose(datafields, "current_pose", data.currentPose);
925 common::debugEigenPose(datafields, "virtualPose", data.virtualPose);
926 common::debugEigenPose(datafields, "targetPose", data.targetPose);
927 common::debugEigenVec(datafields, "currentFT", data.currentFT);
928 common::debugEigenVec(datafields, "pose_error", data.poseError);
929 common::debugEigenVec(datafields, "tempAcc", data.tempAcc);
930 common::debugEigenVec(datafields, "virtualVel", data.virtualVel);
931 common::debugEigenVec(datafields, "virtualAcc", data.virtualAcc);
932 // ARMARX_INFO << VAROUT(data.obj2TcpInMeterL) << VAROUT(data.obj2TcpInMeterL);
933
934 using namespace armarx::control::common::coordination::arondto;
935 auto followerIsolation = cfg.followerConnectionMode == ConnectionMode::follower_isolated;
936 auto leftAsLeader = cfg.leadershipMode == LeadershipMode::left_as_leader;
937 auto rightAsLeader = cfg.leadershipMode == LeadershipMode::right_as_leader;
938 auto followerInLeaderLocalFrame =
939 cfg.followerFrameMode == common::arondto::PoseFrameMode::leader;
940 datafields["followerIsolation"] = new Variant(followerIsolation);
941 datafields["leftAsLeader"] = new Variant(leftAsLeader);
942 datafields["rightAsLeader"] = new Variant(rightAsLeader);
943 datafields["followerInLeaderLocalFrame"] = new Variant(followerInLeaderLocalFrame);
944
945 debugObs->setDebugChannel("SyncModeCoordinator", datafields);
946 }
947
948 template <typename NJointTaskspaceControllerType>
949 void
951 {
952 if (scopedArviz.has_value())
953 {
954 viz::StagedCommit stage = scopedArviz->stage();
955 if (resetArviz)
956 {
957 resetArviz = false;
958 scopedArviz->clear();
959 storedArvizLayers.clear();
960 }
961 collectArviz(stage);
962 scopedArviz->commit(stage);
963 }
964 }
965
966 template <typename NJointTaskspaceControllerType>
967 void
969 viz::StagedCommit& stage) const
970 {
971 if (not scopedArviz.has_value())
972 {
973 return;
974 }
975
976 const double arrowWidth = 2.5F;
977 if (coordinator)
978 {
979 const auto& rtStatus = coordinator->bufferDataRtToPublish.getUpToDateReadBuffer();
980 const Eigen::Matrix4f globalPose = Eigen::Matrix4f::Identity(); // FIXME
981 {
982 viz::Layer layer = scopedArviz->layer("Pose_coordinator");
983 layer.add(
984 viz::Pose("targetPose").pose(globalPose * rtStatus.targetPose).scale(1.5f));
985 layer.add(
986 viz::Pose("virtualPose").pose(globalPose * rtStatus.virtualPose).scale(1.25f));
987 layer.add(
988 viz::Pose("currentPose").pose(globalPose * rtStatus.currentPose).scale(1.0f));
989 stage.add(layer);
990 }
991
992 const auto objCenter = common::getPos(globalPose * rtStatus.currentPose);
993 {
994 viz::Layer layer = scopedArviz->layer("Status_coordinator");
995 layer.add(
996 viz::Arrow("object_vel")
997 .fromTo(objCenter, objCenter + 1000.0f * rtStatus.virtualVel.head<3>())
998 .color(simox::Color::blue())
999 .width(arrowWidth));
1000 layer.add(viz::Arrow("object_pose_error")
1001 .fromTo(objCenter, objCenter + 1000.0f * rtStatus.poseError.head<3>())
1002 .color(simox::Color::black())
1003 .width(arrowWidth));
1004 stage.add(layer);
1005 }
1006 {
1007 viz::Layer layer = scopedArviz->layer("FT_coordinator");
1008 layer.add(viz::Arrow("object_force")
1009 .fromTo(objCenter, objCenter + 100.0f * rtStatus.currentFT.head<3>())
1010 .color(simox::Color::yellow())
1011 .width(arrowWidth));
1012 layer.add(viz::Arrow("object_torque")
1013 .fromTo(objCenter, objCenter + 100.0f * rtStatus.currentFT.tail<3>())
1014 .color(simox::Color::green())
1015 .width(arrowWidth));
1016 stage.add(layer);
1017 }
1018 }
1019 else
1020 {
1021 for (const auto& [_, arm] : limb)
1022 {
1023 const auto& cfgNonRt = arm->bufferConfigNonRtToPublish.getUpToDateReadBuffer();
1024 const auto& rtStatus = arm->bufferRtStatusToOnPublish.getUpToDateReadBuffer();
1025
1026 const Eigen::Matrix4f& globalPose = rtStatus.globalPose;
1027 auto addPose = [&](viz::Layer& layer, const std::string& suffix = "")
1028 {
1029 layer.add(viz::Pose("targetPose" + suffix)
1030 .pose(globalPose * rtStatus.desiredPose)
1031 .scale(1.5f));
1032 layer.add(viz::Pose("currentPose" + suffix)
1033 .pose(globalPose * rtStatus.currentPose)
1034 .scale(1.0f));
1035
1036 const float positionError = (common::getPos(rtStatus.currentPose) -
1037 common::getPos(rtStatus.desiredPose))
1038 .norm();
1039 const float positionErrorNormalized =
1040 std::fmin((positionError / cfgNonRt.safeDistanceMMToGoal), 1.);
1041 layer.add(viz::Arrow("positionError" + suffix)
1042 .fromTo(common::getPos(globalPose * rtStatus.currentPose),
1043 common::getPos(globalPose * rtStatus.desiredPose))
1044 .color(simox::Color(positionErrorNormalized,
1045 1.0f - positionErrorNormalized,
1046 0.0f))
1047 .width(arrowWidth));
1048 };
1049
1050 {
1051 viz::Layer layer = scopedArviz->layer("Pose_" + arm->kinematicChainName);
1052 addPose(layer);
1053 stage.add(layer);
1054 }
1055 const bool enableTrajVisualization = false;
1056 if (enableTrajVisualization)
1057 {
1058 const std::string name = "Traj_" + arm->kinematicChainName;
1059 if (storedArvizLayers.count(name) == 0)
1060 {
1061 storedArvizLayers[name] = scopedArviz->layer(name);
1062 }
1063 viz::Layer& layer = storedArvizLayers.at(name);
1064 int index = layer.size() / 3;
1065 addPose(layer, std::to_string(index));
1066 stage.add(layer);
1067 }
1068 {
1069 viz::Layer layer = scopedArviz->layer("Status_" + arm->kinematicChainName);
1070 layer.add(viz::Arrow("tsImpForce")
1071 .fromTo(common::getPos(globalPose * rtStatus.currentPose),
1072 common::getPos(globalPose * rtStatus.currentPose) +
1073 rtStatus.forceImpedance.template head<3>() * 5.0)
1074 .color(simox::Color::cyan())
1075 .width(arrowWidth));
1076 stage.add(layer);
1077 }
1078 // {
1079 // viz::Layer layer = scopedArviz->layer("FT_" + arm->kinematicChainName);
1080 // const auto curentPos = common::getPos(globalPose * rtStatus.currentPose);
1081 // layer.add(
1082 // viz::Arrow("TCP force")
1083 // .fromTo(curentPos,
1084 // curentPos +
1085 // 100.0f * rtStatus.currentForceTorque.template head<3>())
1086 // .color(simox::Color::yellow())
1087 // .width(arrowWidth));
1088 // layer.add(
1089 // viz::Arrow("TCP torque")
1090 // .fromTo(curentPos,
1091 // curentPos +
1092 // 100.0f * rtStatus.currentForceTorque.template tail<3>())
1093 // .color(simox::Color::green())
1094 // .width(arrowWidth));
1095 // stage.add(layer);
1096 // }
1097 }
1098 }
1099 }
1100
1101 template <typename NJointTaskspaceControllerType>
1102 void
1104 {
1105 for (auto& pair : limb)
1106 {
1107 pair.second->rtReady.store(false);
1108 }
1109 }
1110
1111 template <typename NJointTaskspaceControllerType>
1112 void
1114 const std::string& type,
1115 const ::armarx::aron::data::dto::DictPtr& dto,
1116 const Ice::Current& /*unused*/)
1117 {
1118 ARMARX_INFO << "Adding coordinator of type " << type;
1119 /// TODO think about other types of coordinators
1120 if (!coordinator)
1121 {
1122 /// TODO add check if the current controller has all robotNodeSets
1123 /// that the coordinator requires. currently, use check below.
1124 coordinator = std::make_shared<common::coordination::SyncCoordination>(dto);
1125 }
1126 else
1127 {
1128 coordinator->updateConfig(dto);
1129 }
1130
1131 for (const auto& nodeset : coordinator->getNodesetList())
1132 {
1133 if (limb.find(nodeset) == limb.end())
1134 {
1135 coordinatorEnabled.store(false);
1136 ARMARX_WARNING << "The requested nodeset by coordinator " << nodeset
1137 << " does not exist in the current controller, disable coordinator";
1138 return;
1139 }
1140 }
1141
1142 // for (auto& pair : limb)
1143 // {
1144 // enableSafeGuardForceTorque(pair.first, false, false);
1145 // // pair.second->controller.setForceTorqueGuard(false, false);
1146 // pair.second->controller.ftsensor.enableSafeGuard(false, false);
1147 // }
1148 for (const auto& nodeset : coordinator->getNodesetList())
1149 {
1150 enableSafeGuardForceTorque(nodeset, false, false);
1151 // pair.second->controller.setForceTorqueGuard(false, false);
1152 // pair.second->controller.ftsensor.enableSafeGuard(false, false);
1153 }
1154 coordinatorEnabled.store(true);
1155 // std::map<std::string, Eigen::Matrix4f> initPose;
1156 // for (const auto& nodeset: coord->getNodesetList())
1157 // {
1158 // auto buff = limb.at(nodeset)->bufferConfigRtToUser.getUpToDateReadBuffer();
1159 // initPose[nodeset] = buff.desiredPose;
1160 // ARMARX_INFO << "using node set " << nodeset << " with pose " << buff.desiredPose;
1161 // }
1162 // coord->reset(initPose);
1163 }
1164
1165 template <typename NJointTaskspaceControllerType>
1166 void
1168 const Ice::Current& /*unused*/)
1169 {
1170 ARMARX_INFO << "Disabling coordinator!";
1171 if (not coordinator)
1172 {
1173 ARMARX_INFO << "Coordinator is not created yet, use `useCoordinator` to create!!";
1174 return;
1175 }
1176 for (const auto& nodeset : coordinator->getNodesetList())
1177 {
1178 auto& arm = limb.at(nodeset);
1179 auto& cfgRT = arm->bufferConfigRtToUser.getUpToDateReadBuffer();
1180 arm->bufferConfigUserToNonRt.getWriteBuffer().desiredPose = cfgRT.desiredPose;
1181 arm->bufferConfigUserToNonRt.commitWrite();
1182 usleep(2000);
1183 }
1184 coordinatorEnabled.store(false);
1185 ARMARX_VERBOSE << "Coordinator is disabled!!";
1186 }
1187
1188 template <typename NJointTaskspaceControllerType>
1189 void
1191 {
1192 /// Note: this function will always be called once ctrl_proxy->activateController() is called.
1193 /// For situations where heavy objects are hold in hands in torque control mode, user has
1194 /// to check if this controller is already activated, and only call acitvateContgroller
1195 /// when it is not active.
1196 /// Or you can use the controllerBuilder wrapper, which handles this automatically
1197 ARMARX_RT_LOGF_INFO("--> rtPreActivateController for %s", arm->kinematicChainName.c_str());
1198 VirtualRobot::RobotNodeSetPtr rns = rtGetRobot()->getRobotNodeSet(arm->kinematicChainName);
1199 Eigen::Matrix4f currentPose = rns->getTCP()->getPoseInRootFrame();
1200 auto quat = VirtualRobot::MathTools::eigen4f2quat(currentPose);
1201 ARMARX_RT_LOGF_INFO("-- rt preactivate controller with target pose\n\n "
1202 "[ %.2f, %.2f, %.2f, %.2f, %.2f, %.2f, %.2f ].",
1203 currentPose(0, 3),
1204 currentPose(1, 3),
1205 currentPose(2, 3),
1206 quat.w,
1207 quat.x,
1208 quat.y,
1209 quat.z);
1210
1211 arm->desiredPoseSafeOnActivation =
1212 not common::poseDeviationTooLarge(currentPose,
1213 arm->rtConfig.desiredPose,
1214 arm->rtConfig.safeDistanceMMToGoal,
1215 arm->rtConfig.safeRotAngleDegreeToGoal);
1216
1217 /// Is there a case where using current pose to initialize the RT desired pose is not suitable?
1218 if (arm->reInitPreActivate.load())
1219 {
1220 // arm->nonRtConfig.desiredNullspaceJointAngles = rns->getJointValuesEigen();
1221 // arm->nonRtConfig.desiredPose = currentPose;
1222
1223 // arm->bufferConfigUserToNonRt.reinitAllBuffers(arm->nonRtConfig);
1224
1225 arm->rtConfig.desiredNullspaceJointAngles = rns->getJointValuesEigen();
1226
1227 arm->reInitPreActivate.store(false);
1228 }
1229 {
1230 // arm->rtConfig = arm->nonRtConfig;
1231 arm->rtConfig.desiredPose = currentPose;
1232 arm->nonRtConfig = arm->rtConfig;
1233
1234 arm->bufferConfigUserToNonRt.reinitAllBuffers(arm->rtConfig);
1235 arm->bufferConfigNonRtToRt.reinitAllBuffers(arm->rtConfig);
1236 arm->bufferConfigRtToOnPublish.reinitAllBuffers(arm->rtConfig);
1237 arm->bufferConfigNonRtToPublish.reinitAllBuffers(arm->rtConfig);
1238 arm->bufferConfigRtToUser.reinitAllBuffers(arm->rtConfig);
1239 }
1240 {
1241 arm->sensorDevices.updateJointValues(arm->rtStatus.jointPosition,
1242 arm->rtStatus.jointVelocity,
1243 arm->rtStatus.jointTorque);
1244 arm->rtStatus.rtPreActivate(currentPose);
1245 arm->rtStatus.globalPose = rtGetRobot()->getGlobalPose();
1246 arm->rtStatusInNonRT = arm->rtStatus;
1247 arm->nonRTDeltaT = 0.0;
1248 arm->nonRTAccumulateTime = 0.0;
1249 arm->bufferRtStatusToOnPublish.reinitAllBuffers(arm->rtStatus);
1250 arm->bufferRtStatusToNonRt.reinitAllBuffers(arm->rtStatus);
1251 arm->bufferRtStatusToUser.reinitAllBuffers(arm->rtStatus);
1252 }
1253
1254 // arm->controller.preactivateInit(rns);
1255 ARMARX_RT_LOGF_INFO("<-- done.");
1256 }
1257
1258 template <typename NJointTaskspaceControllerType>
1259 void
1261 const Ice::Current& current)
1262 {
1264 << "NJointTaskspaceController<NJointTaskspaceControllerType>::activateController";
1265
1266 if (not scopedArviz.has_value())
1267 {
1268 scopedArviz.emplace(createArVizClient());
1269 scopedArviz->updateComponentName("NJointTaskspaceController");
1270 }
1271 resetArviz = true;
1272
1273 if (hands)
1274 {
1275 ARMARX_VERBOSE << "Calling hands->nonRtActivateController()";
1276 hands->nonRtActivateController();
1277 }
1279 }
1280
1281 template <typename NJointTaskspaceControllerType>
1282 void
1284 const Ice::Current& current)
1285 {
1287 << "NJointTaskspaceController<NJointTaskspaceControllerType>::deactivateController";
1288
1290
1291 resetArviz = true;
1292 }
1293
1294 template <typename NJointTaskspaceControllerType>
1295 void
1297 {
1298 ARMARX_RT_LOGF_IMPORTANT("--> rtPreActivateController");
1299 for (auto& pair : limb)
1300 {
1301
1302 limbReInit(pair.second);
1303 userConfig.limbs.at(pair.first) = pair.second->rtConfig;
1304 }
1305 if (hands)
1306 {
1307 hands->rtPreActivate();
1308 }
1309 ARMARX_RT_LOGF_IMPORTANT("<-- Done");
1310 }
1311
1312 template <typename NJointTaskspaceControllerType>
1313 void
1315 {
1316 for (auto& pair : userConfig.limbs)
1317 {
1318 limb.at(pair.first)->rtPostDeactivate();
1319 }
1320 if (hands)
1321 {
1322 hands->rtPostDeactivate(userConfig.hands);
1323 }
1324
1325 /// @Andre Meixner: introduced the following line, which contradicts the use case where you
1326 /// disabled the controller during a coordination mode and reactivtion will not automatically
1327 /// activate the coordination mode again.
1328 coordinatorEnabled.store(false);
1329 }
1330
1331 template <typename NJointTaskspaceControllerType>
1332 void
1342
1343 /// ----------------------------------- GUI Widget ---------------------------------------------
1344 template <typename NJointTaskspaceControllerType>
1347 const VirtualRobot::RobotPtr& /*robot*/,
1348 const std::map<std::string, ConstControlDevicePtr>& /*controlDevices*/,
1349 const std::map<std::string, ConstSensorDevicePtr>&)
1350 {
1351 using namespace armarx::WidgetDescription;
1352 HBoxLayoutPtr layout = new HBoxLayout;
1353
1354
1355 ::armarx::WidgetDescription::WidgetSeq widgets;
1356
1357 /// select default config
1358 LabelPtr label = new Label;
1359 label->text = "select a controller config";
1360
1361 StringComboBoxPtr cfgBox = new StringComboBox;
1362 cfgBox->name = "config_box";
1363 cfgBox->defaultIndex = 0;
1364 cfgBox->multiSelect = false;
1365
1366 cfgBox->options = std::vector<std::string>{
1367 "default_a7_with_hands",
1368 "default_a7_left",
1369 "default_a7_right",
1370 "default_a7_zero_torque",
1371 "default_a6_left",
1372 "default_a6_with_hands",
1373 "default_a6_right",
1374 "default_a6_zero_torque",
1375 };
1377
1378 layout->children.emplace_back(label);
1379 layout->children.emplace_back(cfgBox);
1381
1382 layout->children.insert(layout->children.end(), widgets.begin(), widgets.end());
1383 ARMARX_VERBOSE_S << "Layout done";
1384 return layout;
1385 }
1386
1387 template <typename NJointTaskspaceControllerType>
1390 const StringVariantBaseMap& values)
1391 {
1392 auto cfgName = values.at("config_box")->getString();
1393 const armarx::PackagePath configPath(
1394 "armarx_control",
1395 "controller_config/" + std::string(NJointTaskspaceControllerType::TypeName) + "/" +
1396 cfgName + ".json");
1397 ARMARX_INFO_S << "Loading config from " << configPath.toSystemPath();
1398 ARMARX_CHECK(std::filesystem::exists(configPath.toSystemPath()));
1399
1400 auto cfgDTO = armarx::readFromJson<ConfigDict>(configPath.toSystemPath());
1401
1403 return new ConfigurableNJointControllerConfig{cfgDTO.toAronDTO()};
1404 }
1405
1406 /////////
1408
1411
1413 const RobotUnitPtr& robotUnit,
1414 const NJointControllerConfigPtr& config,
1415 const VirtualRobot::RobotPtr& robot) :
1416 NJointTaskspaceController<law::TSMixImpVelController>(robotUnit, config, robot)
1417 {
1418 createLimbs();
1419 }
1420
1421 std::string
1423 {
1424 return "TSMixImpVel";
1425 }
1426
1427 void
1429 {
1430 const auto nDoF = static_cast<Eigen::Index>(arm->jointNames.size());
1431
1432 const auto checkSize = [nDoF](const auto& v) { ARMARX_CHECK_EQUAL(v.rows(), nDoF); };
1433 const auto checkNonNegative = [](const auto& v) { ARMARX_CHECK((v.array() >= 0).all()); };
1434 checkSize(configData.desiredNullspaceJointAngles.value());
1435 checkSize(configData.kdNullspaceTorque);
1436 checkSize(configData.kpNullspaceTorque);
1437 checkSize(configData.kdNullspaceVel);
1438 checkSize(configData.kpNullspaceVel);
1439
1440 checkNonNegative(configData.kdNullspaceTorque);
1441 checkNonNegative(configData.kpNullspaceTorque);
1442 checkNonNegative(configData.kpNullspaceVel);
1443 checkNonNegative(configData.kdNullspaceVel);
1444 checkNonNegative(configData.kdImpedance);
1445 checkNonNegative(configData.kpImpedance);
1446 }
1447
1448 void
1450 {
1451 auto cfg = arm->bufferConfigRtToOnPublish.getUpToDateReadBuffer();
1452 common::debugEigenVec(datafields, "kpImpedance", cfg.kpImpedance);
1453 common::debugEigenVec(datafields, "kdImpedance", cfg.kdImpedance);
1454 common::debugEigenVec(datafields, "kpCartesianVel", cfg.kpCartesianVel);
1455 common::debugEigenVec(datafields, "kdCartesianVel", cfg.kdCartesianVel);
1456 if (cfg.desiredNullspaceJointAngles.has_value())
1457 {
1459 datafields, "desiredNullspaceJointAngles", cfg.desiredNullspaceJointAngles.value());
1460 }
1461
1462 datafields["poseError_threshold_position"] = new Variant(cfg.safeDistanceMMToGoal);
1463 datafields["poseError_threshold_angle"] = new Variant(cfg.safeRotAngleDegreeToGoal);
1464 datafields["safeForceGuardThreshold"] = new Variant(cfg.ftConfig.safeGuardForceThreshold);
1465 datafields["safeTorqueGuardThreshold"] = new Variant(cfg.ftConfig.safeGuardTorqueThreshold);
1466 }
1467
1468 /// ================================== TSImp ==================================
1470
1473
1475 const NJointControllerConfigPtr& config,
1476 const VirtualRobot::RobotPtr& robot) :
1477 NJointTaskspaceController<law::TSImpController>(robotUnit, config, robot)
1478 {
1479 createLimbs();
1480 }
1481
1482 std::string
1483 NJointTSImpController::getClassName(const Ice::Current&) const
1484 {
1485 return "TSImp";
1486 }
1487
1488 void
1490 {
1492 const auto nDoF = static_cast<Eigen::Index>(arm->jointNames.size());
1493
1494 const auto checkSize = [nDoF](const auto& v) { ARMARX_CHECK_EQUAL(v.rows(), nDoF); };
1495 const auto checkNonNegative = [](const auto& v) { ARMARX_CHECK((v.array() >= 0).all()); };
1496 checkSize(configData.desiredNullspaceJointAngles.value());
1497 checkSize(configData.kdNullspaceTorque);
1498 checkSize(configData.kpNullspaceTorque);
1499
1500 checkNonNegative(configData.kdNullspaceTorque);
1501 checkNonNegative(configData.kpNullspaceTorque);
1502 checkNonNegative(configData.kdImpedance);
1503 checkNonNegative(configData.kpImpedance);
1504 }
1505
1506 void
1508 {
1509 auto cfg = arm->bufferConfigRtToOnPublish.getUpToDateReadBuffer();
1510 common::debugEigenVec(datafields, "kpImpedance", cfg.kpImpedance);
1511 common::debugEigenVec(datafields, "kdImpedance", cfg.kdImpedance);
1512 if (cfg.desiredNullspaceJointAngles.has_value())
1513 {
1515 datafields, "desiredNullspaceJointAngles", cfg.desiredNullspaceJointAngles.value());
1516 }
1517
1518 datafields["poseError_threshold_position"] = new Variant(cfg.safeDistanceMMToGoal);
1519 datafields["poseError_threshold_angle"] = new Variant(cfg.safeRotAngleDegreeToGoal);
1520 datafields["safeForceGuardThreshold"] = new Variant(cfg.ftConfig.safeGuardForceThreshold);
1521 datafields["safeTorqueGuardThreshold"] = new Variant(cfg.ftConfig.safeGuardTorqueThreshold);
1522 }
1523
1524 /// ================================== TSAdm ==================================
1526
1529
1531 const NJointControllerConfigPtr& config,
1532 const VirtualRobot::RobotPtr& robot) :
1533 NJointTaskspaceController<law::TSAdmController>(robotUnit, config, robot)
1534 {
1535 createLimbs();
1536 }
1537
1538 std::string
1539 NJointTSAdmController::getClassName(const Ice::Current&) const
1540 {
1541 return "TSAdm";
1542 }
1543
1544 void
1546 {
1548 const auto nDoF = static_cast<Eigen::Index>(arm->jointNames.size());
1549
1550 const auto checkSize = [nDoF](const auto& v) { ARMARX_CHECK_EQUAL(v.rows(), nDoF); };
1551 const auto checkNonNegative = [](const auto& v) { ARMARX_CHECK((v.array() >= 0).all()); };
1552 checkSize(configData.desiredNullspaceJointAngles.value());
1553 checkSize(configData.kdNullspaceTorque);
1554 checkSize(configData.kpNullspaceTorque);
1555
1556 checkNonNegative(configData.kdNullspaceTorque);
1557 checkNonNegative(configData.kpNullspaceTorque);
1558 checkNonNegative(configData.kdImpedance);
1559 checkNonNegative(configData.kpImpedance);
1560 }
1561
1562 void
1564 {
1565 auto cfg = arm->bufferConfigRtToOnPublish.getUpToDateReadBuffer();
1566 common::debugEigenVec(datafields, "kpImpedance", cfg.kpImpedance);
1567 common::debugEigenVec(datafields, "kdImpedance", cfg.kdImpedance);
1568 if (cfg.desiredNullspaceJointAngles.has_value())
1569 {
1571 datafields, "desiredNullspaceJointAngles", cfg.desiredNullspaceJointAngles.value());
1572 }
1573
1574 datafields["poseError_threshold_position"] = new Variant(cfg.safeDistanceMMToGoal);
1575 datafields["poseError_threshold_angle"] = new Variant(cfg.safeRotAngleDegreeToGoal);
1576 datafields["safeForceGuardThreshold"] = new Variant(cfg.ftConfig.safeGuardForceThreshold);
1577 datafields["safeTorqueGuardThreshold"] = new Variant(cfg.ftConfig.safeGuardTorqueThreshold);
1578 }
1579
1580 /// ================================== TSVel ==================================
1582
1585
1587 const NJointControllerConfigPtr& config,
1588 const VirtualRobot::RobotPtr& robot) :
1589 NJointTaskspaceController<law::TSVelController>(robotUnit, config, robot)
1590 {
1591 createLimbs();
1592 }
1593
1594 std::string
1595 NJointTSVelController::getClassName(const Ice::Current&) const
1596 {
1597 return "TSVel";
1598 }
1599
1600 void
1602 {
1603 const auto nDoF = static_cast<Eigen::Index>(arm->jointNames.size());
1604
1605 const auto checkSize = [nDoF](const auto& v) { ARMARX_CHECK_EQUAL(v.rows(), nDoF); };
1606 const auto checkNonNegative = [](const auto& v) { ARMARX_CHECK((v.array() >= 0).all()); };
1607 checkSize(configData.desiredNullspaceJointAngles.value());
1608 checkSize(configData.kdNullspaceVel);
1609 checkSize(configData.kpNullspaceVel);
1610
1611 checkNonNegative(configData.kpNullspaceVel);
1612 checkNonNegative(configData.kdNullspaceVel);
1613 }
1614
1615 void
1617 {
1618 auto cfg = arm->bufferConfigRtToOnPublish.getUpToDateReadBuffer();
1619 common::debugEigenVec(datafields, "kpCartesianVel", cfg.kpCartesianVel);
1620 common::debugEigenVec(datafields, "kdCartesianVel", cfg.kdCartesianVel);
1621 if (cfg.desiredNullspaceJointAngles.has_value())
1622 {
1624 datafields, "desiredNullspaceJointAngles", cfg.desiredNullspaceJointAngles.value());
1625 }
1626
1627 datafields["poseError_threshold_position"] = new Variant(cfg.safeDistanceMMToGoal);
1628 datafields["poseError_threshold_angle"] = new Variant(cfg.safeRotAngleDegreeToGoal);
1629 datafields["safeForceGuardThreshold"] = new Variant(cfg.ftConfig.safeGuardForceThreshold);
1630 datafields["safeTorqueGuardThreshold"] = new Variant(cfg.ftConfig.safeGuardTorqueThreshold);
1631 }
1632} // namespace armarx::control::njoint_controller::task_space
#define ARMARX_RT_LOGF_IMPORTANT(...)
#define ARMARX_RT_LOGF_WARN(...)
#define ARMARX_RT_LOGF_INFO(...)
uint8_t index
SpamFilterDataPtr deactivateSpam(SpamFilterDataPtr const &spamFilter, float deactivationDurationSec, const std::string &identifier, bool deactivate)
Definition Logging.cpp:75
#define VAROUT(x)
constexpr T c
Brief description of class JointControlTargetBase.
This util class helps with keeping a cycle time during a control cycle.
Definition CycleUtil.h:41
ArmarXObjectSchedulerPtr getObjectScheduler() const
int getState() const
Retrieve current state of the ManagedIceObject.
bool isControllerActive(const Ice::Current &=Ice::emptyCurrent) const final override
void runTask(const std::string &taskName, Task &&task)
Executes a given task in a separate thread from the Application ThreadPool.
std::string getClassName(const Ice::Current &=Ice::emptyCurrent) const override=0
void deactivateController(const Ice::Current &=Ice::emptyCurrent) override
const VirtualRobot::RobotPtr & useSynchronizedRtRobot(bool updateCollisionModel=false)
Requests a VirtualRobot for use in rtRun *.
const VirtualRobot::RobotPtr & rtGetRobot()
TODO make protected and use attorneys.
void activateController(const Ice::Current &=Ice::emptyCurrent) override
ControlTargetBase * useControlTarget(const std::string &deviceName, const std::string &controlMode)
Declares to calculate the ControlTarget for the given ControlDevice in the given ControlMode when rtR...
static std::filesystem::path toSystemPath(const data::PackagePath &pp)
The SensorValueBase class.
The Variant class is described here: Variants.
Definition Variant.h:224
static bool pinThreadToCPU(unsigned int cpu)
Pins the calling thread to the CPU with the given id.
Definition RTUtility.cpp:52
static bool elevateThreadPriority(int priority)
Elevate the thread priority of the calling thread to the given priority.
Definition RTUtility.cpp:17
static constexpr int RT_THREAD_PRIORITY
The thread priority for rt-threads.
Definition RTUtility.h:24
std::string getClassName(const Ice::Current &=Ice::emptyCurrent) const override
Definition Base.cpp:1539
void limbPublishConfig(StringVariantBaseMap &datafields, ArmPtr &arm) override
Definition Base.cpp:1563
void validateConfigDataCheckSize(Config &configData, ArmPtr &arm) override
Definition Base.cpp:1545
NJointTSAdmController(const RobotUnitPtr &robotUnit, const NJointControllerConfigPtr &config, const VirtualRobot::RobotPtr &robot)
Definition Base.cpp:1530
std::string getClassName(const Ice::Current &=Ice::emptyCurrent) const override
================================== TSImp ==================================
Definition Base.cpp:1483
NJointTSImpController(const RobotUnitPtr &robotUnit, const NJointControllerConfigPtr &config, const VirtualRobot::RobotPtr &robot)
Definition Base.cpp:1474
void limbPublishConfig(StringVariantBaseMap &datafields, ArmPtr &arm) override
Definition Base.cpp:1507
void validateConfigDataCheckSize(Config &configData, ArmPtr &arm) override
Definition Base.cpp:1489
std::string getClassName(const Ice::Current &=Ice::emptyCurrent) const override
================================== TSMixImpVel ==================================
Definition Base.cpp:1422
NJointTSMixImpVelController(const RobotUnitPtr &robotUnit, const NJointControllerConfigPtr &config, const VirtualRobot::RobotPtr &robot)
Definition Base.cpp:1412
void limbPublishConfig(StringVariantBaseMap &datafields, ArmPtr &arm) override
Definition Base.cpp:1449
void validateConfigDataCheckSize(Config &configData, ArmPtr &arm) override
Definition Base.cpp:1428
std::string getClassName(const Ice::Current &=Ice::emptyCurrent) const override
Definition Base.cpp:1595
NJointTSVelController(const RobotUnitPtr &robotUnit, const NJointControllerConfigPtr &config, const VirtualRobot::RobotPtr &robot)
Definition Base.cpp:1586
void limbPublishConfig(StringVariantBaseMap &datafields, ArmPtr &arm) override
Definition Base.cpp:1616
void validateConfigDataCheckSize(Config &configData, ArmPtr &arm) override
Definition Base.cpp:1601
Brief description of class NJointTaskspaceController.
Definition Base.h:59
std::map< std::string, VirtualRobot::RobotNodeSetPtr > controllableNodeSets
Definition Base.h:220
void onPublish(const SensorAndControl &, const DebugDrawerInterfacePrx &, const DebugObserverInterfacePrx &) override
Definition Base.cpp:886
static WidgetDescription::WidgetPtr GenerateConfigDescription(const VirtualRobot::RobotPtr &, const std::map< std::string, ConstControlDevicePtr > &, const std::map< std::string, ConstSensorDevicePtr > &)
--------------------------------— GUI Widget ------------------------------------------—
Definition Base.cpp:1346
Ice::DoubleSeq getCurrentTCPPose(const std::string &nodeSetName, const Ice::Current &iceCurrent=Ice::emptyCurrent) override
Definition Base.cpp:714
std::shared_ptr< common::coordination::SyncCoordination > coordinator
Definition Base.h:224
void onPublishCoordinator(const DebugObserverInterfacePrx &debugObs)
Definition Base.cpp:914
::armarx::aron::data::dto::DictPtr getConfig(const Ice::Current &iceCurrent=Ice::emptyCurrent) override
Definition Base.cpp:601
virtual void collectArviz(viz::StagedCommit &stage) const
Definition Base.cpp:968
NJointTaskspaceController(const RobotUnitPtr &robotUnit, const NJointControllerConfigPtr &config, const VirtualRobot::RobotPtr &)
Definition Base.cpp:138
Ice::FloatSeq getTCPVel(const std::string &rns, const Ice::Current &iceCurrent=Ice::emptyCurrent) override
Definition Base.cpp:697
void useCoordinator(const std::string &type, const ::armarx::aron::data::dto::DictPtr &dto, const Ice::Current &iceCurrent=Ice::emptyCurrent) override
Definition Base.cpp:1113
bool isSafeForceTorque(const std::string &nodeSetName, const Ice::Current &iceCurrent=Ice::emptyCurrent) override
-----------------------------— Other interaces ----------------------------------------—
Definition Base.cpp:663
typename NJointTaskspaceControllerType::Config Config
Definition Base.h:63
bool wasNotSafeForceTorque(const std::string &nodeSetName, const Ice::Current &iceCurrent=Ice::emptyCurrent) override
Definition Base.cpp:680
void limbRTSetTarget(ArmPtr &arm, const size_t nDoFTorque, const size_t nDoFVelocity, const Eigen::VectorXf &targetTorque, const Eigen::VectorXf &targetVelocity)
Definition Base.cpp:365
void enableSafeGuardForceTorque(const std::string &nodeSetName, const bool forceGuard, const bool torqueGuard, const Ice::Current &iceCurrent=Ice::emptyCurrent) override
Definition Base.cpp:635
void rtPostDeactivateController() override
This function is called after the controller is deactivated.
Definition Base.cpp:1314
void updateInputData(const std::string &key, const Eigen::Matrix4f &targetPose, const PoseFrameMode &targetPoseMode, const Eigen::Matrix4f &pose, const Eigen::Vector6f &vel, const Eigen::Vector6f &ft, const Eigen::Vector6f &stiffness)
some method for coordinator
Definition Base.cpp:445
void rtRun(const IceUtil::Time &sensorValuesTimestamp, const IceUtil::Time &timeSinceLastIteration) override
TODO make protected and use attorneys.
Definition Base.cpp:519
void activateController(const Ice::Current &current=Ice::emptyCurrent) final
NJointControllerBase interface.
Definition Base.cpp:1260
std::map< std::string, common::coordination::InputData > coordinatorInputData
Definition Base.h:225
void updateConfig(const ::armarx::aron::data::dto::DictPtr &dto, const Ice::Current &iceCurrent=Ice::emptyCurrent) override
NJointController interface.
Definition Base.cpp:545
virtual void validateConfigDataCheckSize(Config &configData, ArmPtr &arm)=0
bool updateTargetPose(const TargetPoseMap &targetPoseMap, const TargetNullspaceMap &targetNullspaceMap, const Ice::Current &=Ice::emptyCurrent) override
Definition Base.cpp:734
static ConfigPtrT GenerateConfigFromVariants(const StringVariantBaseMap &values)
Definition Base.cpp:1389
virtual void limbPublishConfig(StringVariantBaseMap &datafields, ArmPtr &arm)=0
void limbPublish(ArmPtr &arm, const DebugObserverInterfacePrx &debugObs)
Definition Base.cpp:804
armarx::control::common::arondto::PoseFrameMode PoseFrameMode
Definition Base.h:67
void deactivateController(const Ice::Current &current=Ice::emptyCurrent) final
Definition Base.cpp:1283
void rtPreActivateController() override
This function is called before the controller is activated.
Definition Base.cpp:1296
void limbRTUpdateStatus(ArmPtr &arm, const double deltaT)
-----------------------------— Real time cotnrol --------------------------------------—
Definition Base.cpp:336
void limbInit(const std::string &nodeSetName, ArmPtr &arm, Config &cfg, VirtualRobot::RobotPtr &nonRtRobotPtr)
Definition Base.cpp:57
DerivedT & color(Color color)
Definition ElementOps.h:218
DerivedT & scale(Eigen::Vector3f scale)
Definition ElementOps.h:254
#define ARMARX_CHECK_GREATER(lhs, rhs)
This macro evaluates whether lhs is greater (>) than rhs and if it turns out to be false it will thro...
#define ARMARX_CHECK_EXPRESSION(expression)
This macro evaluates the expression and if it turns out to be false it will throw an ExpressionExcept...
#define ARMARX_CHECK(expression)
Shortcut for ARMARX_CHECK_EXPRESSION.
#define ARMARX_CHECK_EQUAL(lhs, rhs)
This macro evaluates whether lhs is equal (==) rhs and if it turns out to be false it will throw an E...
#define ARMARX_INFO
The normal logging level.
Definition Logging.h:181
#define ARMARX_IMPORTANT
The logging level for always important information, but expected behaviour (in contrast to ARMARX_WAR...
Definition Logging.h:190
#define ARMARX_ERROR
The logging level for unexpected behaviour, that must be fixed.
Definition Logging.h:196
#define ARMARX_INFO_S
Definition Logging.h:202
#define ARMARX_VERBOSE_S
Definition Logging.h:207
#define ARMARX_DEBUG
The logging level for output that is only interesting while debugging.
Definition Logging.h:184
#define ARMARX_WARNING
The logging level for unexpected behaviour, but not a serious problem.
Definition Logging.h:193
#define ARMARX_VERBOSE
The logging level for verbose information.
Definition Logging.h:187
armarx::aron::data::dto::Dict getRTStatus()
Matrix< float, 6, 1 > Vector6f
std::shared_ptr< class Robot > RobotPtr
Definition Bus.h:19
::IceInternal::Handle<::armarx::WidgetDescription::Widget > WidgetPtr
::IceInternal::Handle< Dict > DictPtr
void reportPoseDeviationWarning(const std::string &who, const Eigen::Matrix4f &pose1, const Eigen::Matrix4f &pose2, const std::string &namePose1, const std::string &namePose2)
Definition utils.cpp:754
bool detectAndReportPoseDeviationWarning(const Eigen::Matrix4f &pose1, const Eigen::Matrix4f &pose2, const std::string &namePose1, const std::string &namePose2, float positionThrMM, float angleThrDeg, const std::string &who)
Definition utils.cpp:773
bool poseDeviationTooLarge(const Eigen::Matrix4f &currentPose, const Eigen::Matrix4f &desiredPose, float positionThrMM, float angleThrDeg)
Definition utils.cpp:742
void debugEigenVec(StringVariantBaseMap &datafields, const std::string &name, Eigen::VectorXf vec)
Definition utils.cpp:190
float getDeltaAngleBetweenPose(const Eigen::Matrix4f &pose1, const Eigen::Matrix4f &pose2)
Definition utils.cpp:736
void debugEigenPose(StringVariantBaseMap &datafields, const std::string &name, Eigen::Matrix4f pose)
Definition utils.cpp:140
DVec mat4ToDVec(const Eigen::Matrix4f &mat)
convert Eigen:Matrix4f to 7D double vector.
Definition utils.cpp:359
void debugEigenMat(StringVariantBaseMap &datafields, const std::string &name, const Eigen::MatrixXd &mat)
Definition utils.cpp:152
std::string sVecToString(const std::vector< std::string > &vec, const std::string &delimiter)
Definition utils.cpp:439
Eigen::Block< Eigen::Matrix4f, 3, 1 > getPos(Eigen::Matrix4f &matrix)
Definition utils.cpp:301
NJointControllerRegistration< NJointTSAdmController > registrationControllerNJointTSAdmController("TSAdm")
NJointControllerRegistration< NJointTSImpController > registrationControllerNJointTSImpController("TSImp")
NJointControllerRegistration< NJointTSMixImpVelController > registrationControllerNJointTSMixImpVelController("TSMixImpVel")
NJointControllerRegistration< NJointTSVelController > registrationControllerNJointTSVelController("TSVel")
dictionary< string, Ice::FloatSeq > TargetNullspaceMap
dictionary< string, FloatSeqSeq > TargetPoseMap
::IceInternal::ProxyHandle<::IceProxy::armarx::DebugObserverInterface > DebugObserverInterfacePrx
std::map< std::string, VariantBasePtr > StringVariantBaseMap
AronDTO readFromJson(const std::filesystem::path &filename)
IceUtil::Handle< class RobotUnit > RobotUnitPtr
Definition FTSensor.h:34
::IceInternal::ProxyHandle<::IceProxy::armarx::DebugDrawerInterface > DebugDrawerInterfacePrx
detail::ControlThreadOutputBufferEntry SensorAndControl
double norm(const Point &a)
Definition point.hpp:102
Arrow & width(float w)
Definition Elements.h:211
std::size_t size() const noexcept
Definition Layer.h:52
void add(ElementT const &element)
Definition Layer.h:31
A staged commit prepares multiple layers to be committed.
Definition Client.h:30
void add(Layer const &layer)
Stage a layer to be committed later via client.apply(*this)
Definition Client.h:36
#define ARMARX_TRACE
Definition trace.h:77