VelocityController.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 2024
19 * @copyright http://www.gnu.org/licenses/gpl-2.0.txt
20 * GNU General Public License
21 */
22
23#include "VelocityController.h"
24
25#include <VirtualRobot/MathTools.h>
26#include <VirtualRobot/RobotNodeSet.h>
27
29#include <ArmarXCore/core/PackagePath.h> // for GUI
33
37
41
43{
44 NJointControllerRegistration<NJointTaskspaceVelocityController>
46 "NJointTaskspaceVelocityController");
47
48 void
49 NJointTaskspaceVelocityController::limbInit(const std::string nodeSetName,
50 ArmPtr& arm,
51 Config& cfg,
52 VirtualRobot::RobotPtr& nonRtRobotPtr)
53 {
54 arm->kinematicChainName = nodeSetName;
55 VirtualRobot::RobotNodeSetPtr rtRns =
56 rtGetRobot()->getRobotNodeSet(arm->kinematicChainName);
57 VirtualRobot::RobotNodeSetPtr nonRtRns =
58 nonRtRobotPtr->getRobotNodeSet(arm->kinematicChainName);
59 ARMARX_CHECK_EXPRESSION(rtRns) << arm->kinematicChainName;
60 ARMARX_CHECK_EXPRESSION(nonRtRns) << arm->kinematicChainName;
61 ARMARX_IMPORTANT << "Creating Taskspace Impedance controller with kinematic chain: "
62 << arm->kinematicChainName << " with num of joints: (RT robot) "
63 << rtRns->getSize() << ", and (non-RT robot) " << nonRtRns->getSize();
64
65 arm->controller.initialize(nonRtRns, rtRns);
66 arm->controller.ftsensor.initialize(rtRns, robotUnit, cfg.ftConfig);
67 arm->jointNames.clear();
68 std::vector<size_t> jointIDTorqueMode;
69 std::vector<size_t> jointIDVelocityMode;
70 for (size_t i = 0; i < rtRns->getSize(); ++i)
71 {
72 std::string jointName = rtRns->getNode(i)->getName();
73 arm->jointNames.push_back(jointName);
74
75 ControlTargetBase* ct = useControlTarget(jointName, ControlModes::Velocity1DoF);
77 auto* casted_ct = ct->asA<ControlTarget1DoFActuatorVelocity>();
78 ARMARX_CHECK_EXPRESSION(casted_ct);
79 arm->targetsVel.push_back(casted_ct);
80
81 const SensorValueBase* sv = useSensorValue(jointName);
83 arm->sensorDevices.append(sv, jointName);
84 jointIDVelocityMode.push_back(i);
85 };
86
87 validateConfigData(cfg, arm);
88 arm->rtConfig = cfg;
89 arm->nonRtConfig = cfg;
90
91 auto nDoF = rtRns->getSize();
92 arm->rtStatus.reset(nDoF, jointIDTorqueMode, jointIDVelocityMode);
93 }
94
97 const NJointControllerConfigPtr& config,
100 {
102
103 ConfigPtrT cfg = ConfigPtrT::dynamicCast(config);
105 userConfig.fromAron(cfg->config);
106
108 nonRtRobot = robotUnit->cloneRobot();
109 robotUnit->updateVirtualRobot(nonRtRobot);
110
111 for (auto& pair : userConfig.limbs)
112 {
113 limb.emplace(pair.first, std::make_unique<ArmData>());
114 limbInit(pair.first, limb.at(pair.first), pair.second, nonRtRobot);
115 controllableNodeSets.emplace(pair.first, nonRtRobot->getRobotNodeSet(pair.first));
116 }
117
118 if (not userConfig.hands.empty())
119 {
120 hands =
121 std::make_shared<core::HandControlBase>(robotUnit, nonRtRobot, userConfig.hands);
122 for (auto& pair : userConfig.hands)
123 {
124 ARMARX_INFO << "construction of hand "
125 << hands->hands.at(pair.first)->kinematicChainName;
126 controllableNodeSets.emplace(pair.first, nonRtRobot->getRobotNodeSet(pair.first));
127 }
128 }
129 }
130
131 std::string
133 {
134 return "NJointTaskspaceVelocityController";
135 }
136
137 void
139 {
140 std::string taskName = getClassName() + "AdditionalTask";
141 runTask(taskName,
142 [&]
143 {
145 4); // please don't set this to 0 as it is the rtRun/control thread
148
149 CycleUtil c(1);
150 getObjectScheduler()->waitForObjectStateMinimum(eManagedIceObjectStarted);
151 ARMARX_IMPORTANT << "Create a new thread for " << getClassName();
152 while (getState() == eManagedIceObjectStarted)
153 {
154 if (isControllerActive())
155 {
157 }
158 c.waitForCycleDuration();
159 }
160 });
161 }
162
163 void
165 {
166 arm->bufferConfigNonRtToRt.getWriteBuffer() = arm->nonRtConfig;
167 arm->bufferConfigNonRtToRt.commitWrite();
168 }
169
170 void
172 {
173 auto [rtTargetSafe, ftSafe] = additionalTaskUpdateStatus();
175 if (not rtTargetSafe)
176 {
178 }
179 }
180
181 std::tuple<bool, bool>
183 {
184 robotUnit->updateVirtualRobot(nonRtRobot);
185 bool rtSafe = true;
186 bool rtTargetSafe = true;
187 bool forceTorqueSafe = true;
188 for (auto& pair : limb)
189 {
190 auto& arm = pair.second;
191 arm->nonRtConfig = arm->bufferConfigUserToNonRt.getUpToDateReadBuffer();
192 arm->rtStatusInNonRT = arm->bufferRtStatusToNonRt.getUpToDateReadBuffer();
193 rtSafe = rtSafe and pair.second->rtStatusInNonRT.rtSafe;
194 rtTargetSafe = rtTargetSafe and pair.second->rtStatusInNonRT.rtTargetSafe;
195 forceTorqueSafe = forceTorqueSafe and pair.second->rtStatusInNonRT.forceTorqueSafe;
196 }
197 if (hands)
198 {
199 hands->nonRTUpdateStatus();
200 }
201 return std::make_tuple(rtTargetSafe, forceTorqueSafe);
202 }
203
204 void
206 {
207 for (auto& pair : limb)
208 {
209 limbNonRT(pair.second);
210 }
211 if (hands)
212 {
213 hands->nonRTSetTarget();
214 }
215 }
216
217 void
219 {
220 for (auto& pair : limb)
221 {
222 if (not pair.second->rtReady)
223 continue;
224
225 if (not pair.second->rtStatusInNonRT.rtTargetSafe)
226 {
228 pair.second->rtStatusInNonRT.currentPose,
229 pair.second->rtStatusInNonRT.desiredPoseUnsafe,
230 "current pose",
231 "desired pose");
232 }
233 }
234 }
235
236 /// -------------------------------- Real time cotnrol -----------------------------------------
237 void
239 {
240 arm->rtConfig = arm->bufferConfigNonRtToRt.getUpToDateReadBuffer();
241 arm->rtStatus.deltaT = deltaT;
242 arm->rtStatus.accumulateTime += deltaT;
243
244 arm->controller.ftsensor.updateStatus(arm->rtConfig.ftConfig,
245 arm->rtStatus.currentForceTorque,
246 arm->rtStatus.deltaT,
247 arm->rtFirstRun.load());
248 arm->rtStatus.safeFTGuardOffset.head<3>() =
249 arm->controller.ftsensor.getSafeGuardForceOffset();
250
251 arm->sensorDevices.updateJointValues(
252 arm->rtStatus.jointPosition, arm->rtStatus.jointVelocity, arm->rtStatus.jointTorque);
253
254
255 arm->bufferRtStatusToNonRt.getWriteBuffer() = arm->rtStatus;
256 arm->bufferRtStatusToNonRt.commitWrite();
257 arm->bufferRtStatusToUser.getWriteBuffer() = arm->rtStatus;
258 arm->bufferRtStatusToUser.commitWrite();
259 }
260
261 void
263 const Eigen::VectorXf& targetVelocity)
264 {
265 for (unsigned int i = 0; i < targetVelocity.size(); i++)
266 {
267 arm->targetsVel.at(i)->velocity = targetVelocity(i);
268 if (!arm->targetsVel.at(i)->isValid())
269 {
270 arm->targetsVel.at(i)->velocity = 0;
271 }
272 }
273 arm->bufferRtStatusToOnPublish.getWriteBuffer() = arm->rtStatus;
274 arm->bufferRtStatusToOnPublish.commitWrite();
275
276 arm->bufferConfigRtToOnPublish.getWriteBuffer() = arm->rtConfig;
277 arm->bufferConfigRtToOnPublish.commitWrite();
278
279 arm->bufferConfigRtToUser.getWriteBuffer() = arm->rtConfig;
280 arm->bufferConfigRtToUser.commitWrite();
281
282 if (arm->rtFirstRun.load())
283 {
284 arm->rtFirstRun.store(false);
285 arm->rtReady.store(true);
286 }
287 }
288
289 void
291 {
292 double time_measure = IceUtil::Time::now().toMicroSecondsDouble();
293 // limbRTUpdateStatus(arm, deltaT);
294 // double time_update_status = IceUtil::Time::now().toMicroSecondsDouble() - time_measure;
295
296 arm->controller.run(arm->rtConfig, arm->rtStatus);
297 double time_run_rt = IceUtil::Time::now().toMicroSecondsDouble() - time_measure;
298
299 limbRTSetTarget(arm, arm->rtStatus.desiredJointVelocity);
300
301 double time_set_target = IceUtil::Time::now().toMicroSecondsDouble() - time_measure;
302 time_measure = IceUtil::Time::now().toMicroSecondsDouble() - time_measure;
303
304 if (time_measure > 200)
305 {
306 ARMARX_RT_LOGF_WARN("---- rt too slow: "
307 "run_rt_limb: %.2f\n"
308 "set_target_limb: %.2f\n"
309 "time all: %.2f\n",
310 time_run_rt - time_measure, //
311 time_set_target - time_run_rt, //
312 time_measure)
313 .deactivateSpam(1.0f); // 0-1 us
314 }
315 }
316
317 void
318 NJointTaskspaceVelocityController::rtRun(const IceUtil::Time& /*sensorValuesTimestamp*/,
319 const IceUtil::Time& timeSinceLastIteration)
320 {
321 double deltaT = timeSinceLastIteration.toSecondsDouble();
322 for (auto& pair : limb)
323 {
324 limbRTUpdateStatus(pair.second, deltaT);
325 }
326
327 // rtRunCoordinator(deltaT);
328
329 for (auto& pair : limb)
330 {
331 limbRT(pair.second, deltaT);
332 }
333 if (hands)
334 {
335 hands->updateRTStatus(deltaT);
336 }
337 }
338
339 /// ------------------------------ update/get config -------------------------------------------
340 void
341 NJointTaskspaceVelocityController::updateConfig(const ::armarx::aron::data::dto::DictPtr& dto,
342 const Ice::Current& iceCurrent)
343 {
344 auto prevCfg = userConfig;
345 userConfig.fromAron(dto);
346
347 for (auto& pair : userConfig.limbs)
348 {
349 validateConfigData(pair.second, limb.at(pair.first));
350 bool desiredPoseFrameModeSame = prevCfg.limbs.at(pair.first).desiredPoseFrameMode ==
351 pair.second.desiredPoseFrameMode;
352 if (desiredPoseFrameModeSame and common::detectAndReportPoseDeviationWarning(
353 pair.second.desiredPose,
354 prevCfg.limbs.at(pair.first).desiredPose,
355 "new desired pose",
356 "previous desired pose",
357 pair.second.safeDistanceMMToGoal,
358 pair.second.safeRotAngleDegreeToGoal,
359 "updateConfig_" + pair.first))
360 {
361 ARMARX_INFO << "use the existing target pose";
362 pair.second.desiredPose = prevCfg.limbs.at(pair.first).desiredPose;
363 }
364 limb.at(pair.first)->bufferConfigUserToNonRt.getWriteBuffer() = pair.second;
365 limb.at(pair.first)->bufferConfigUserToNonRt.commitWrite();
366 }
367 if (hands)
368 {
369 hands->updateConfig(userConfig.hands);
370 }
371 }
372
374 NJointTaskspaceVelocityController::getConfig(const Ice::Current& iceCurrent)
375 {
376 for (auto& pair : limb)
377 {
378 userConfig.limbs.at(pair.first) =
379 pair.second->bufferConfigRtToUser.getUpToDateReadBuffer();
380 }
381 if (hands)
382 {
383 hands->getConfig(userConfig.hands);
384 }
385 return userConfig.toAronDTO();
386 }
387
388 void
390 const bool forceGuard,
391 const bool torqueGuard,
392 const Ice::Current& iceCurrent)
393 {
394 auto it = userConfig.limbs.find(nodeSetName);
395 if (it != userConfig.limbs.end())
396 {
397 it->second.ftConfig.enableSafeGuardForce = forceGuard;
398 it->second.ftConfig.enableSafeGuardTorque = torqueGuard;
399 limb.at(nodeSetName)->controller.ftsensor.enableSafeGuard(forceGuard, torqueGuard);
401 << "reset safe guard with force torque sensors: safe? "
402 << limb.at(nodeSetName)->controller.ftsensor.isSafe(it->second.ftConfig);
403 limb.at(nodeSetName)->bufferConfigUserToNonRt.getWriteBuffer() = it->second;
404 limb.at(nodeSetName)->bufferConfigUserToNonRt.commitWrite();
405 }
406 else
407 {
408 ARMARX_WARNING << "no robot node set with name " << nodeSetName
409 << " found in the controllers.";
410 }
411 }
412
413 /// -------------------------------- Other interaces -------------------------------------------
414 bool
416 const Ice::Current& iceCurrent)
417 {
418 auto it = userConfig.limbs.find(nodeSetName);
419 if (it != userConfig.limbs.end())
420 {
421 return limb.at(nodeSetName)->controller.ftsensor.ftSafe.load();
422 }
423
424 ARMARX_WARNING << "no robot node set with name " << nodeSetName
425 << " found in the controllers.";
426 return false;
427 }
428
429 Ice::FloatSeq
431 const Ice::Current& iceCurrent)
432 {
433 std::vector<float> tcpVel;
434 auto& arm = limb.at(rns);
435 auto s = arm->bufferRtStatusToUser.getUpToDateReadBuffer();
436 for (int i = 0; i < s.currentTwist.size(); i++)
437 {
438 tcpVel.push_back(s.currentTwist[i]);
439 }
440 return tcpVel;
441 }
442
443 bool
445 const TargetPoseMap& targetPoseMap,
446 const TargetNullspaceMap& targetNullspaceMap,
447 const Ice::Current& iceCurrent)
448 {
449 for (auto& pair : userConfig.limbs)
450 {
451 for (size_t i = 0; i < 4; ++i)
452 {
453 for (int j = 0; j < 4; ++j)
454 {
455 pair.second.desiredPose(i, j) = targetPoseMap.at(pair.first)[i][j];
456 }
457 }
458 if (targetNullspaceMap.at(pair.first).size() > 0)
459 {
460 const size_t nDoF = pair.second.desiredNullspaceJointAngles.value().size();
461 ARMARX_CHECK_EQUAL(targetNullspaceMap.at(pair.first).size(), nDoF)
462 << "the joint numbers does not match";
463 for (size_t i = 0; i < nDoF; ++i)
464 {
465 pair.second.desiredNullspaceJointAngles.value()(i) =
466 targetNullspaceMap.at(pair.first)[i];
467 }
468 }
469 limb.at(pair.first)->bufferConfigUserToNonRt.getWriteBuffer() = pair.second;
470 limb.at(pair.first)->bufferConfigUserToNonRt.commitWrite();
471 }
472 return true;
473 }
474
475 void
477 {
478 const auto nDoF = arm->jointNames.size();
479
480 const auto checkSize = [nDoF](const auto& v) { ARMARX_CHECK_EQUAL(v.rows(), nDoF); };
481 const auto checkNonNegative = [](const auto& v) { ARMARX_CHECK((v.array() >= 0).all()); };
482
483 if (!configData.desiredNullspaceJointAngles.has_value())
484 {
485 if (!isControllerActive())
486 {
487 ARMARX_INFO << "No user defined nullspace target, reset to zero with "
488 << VAROUT(nDoF);
489 configData.desiredNullspaceJointAngles = Eigen::VectorXf::Zero(nDoF);
490 arm->reInitPreActivate.store(true);
491 }
492 else
493 {
494 auto currentValue =
495 arm->bufferConfigRtToUser.getUpToDateReadBuffer().desiredNullspaceJointAngles;
497 << "Controller is active, but no user defined nullspace target. \n"
498 "You should first get up-to-date config of this controller and then update "
499 "it:\n"
500 " auto cfg = ctrl->getConfig(); \n"
501 " cfg.desiredPose = xxx;\n"
502 " ctrl->updateConfig(cfg);\n"
503 "Now, I decide by myself to use the existing values of nullspace target\n"
504 << currentValue.value();
505 configData.desiredNullspaceJointAngles = currentValue;
506 }
507 }
508 ARMARX_CHECK_GREATER(configData.safeDistanceMMToGoal, 100.0f);
509 checkSize(configData.desiredNullspaceJointAngles.value());
510 checkSize(configData.kdNullspaceVel);
511 checkSize(configData.kpNullspaceVel);
512
513 checkNonNegative(configData.kdNullspaceVel);
514 checkNonNegative(configData.kpNullspaceVel);
515 checkNonNegative(configData.kpNullspaceVel);
516 checkNonNegative(configData.kdNullspaceVel);
517 }
518
519 void
521 const DebugObserverInterfacePrx& debugObs)
522 {
523 StringVariantBaseMap datafields;
524 auto rtData = arm->bufferConfigRtToOnPublish.getUpToDateReadBuffer();
525 auto rtStatus = arm->bufferRtStatusToOnPublish.getUpToDateReadBuffer();
526
527
528 common::debugEigenPose(datafields, "current_pose", rtStatus.currentPose);
529 common::debugEigenPose(datafields, "desired_pose", rtStatus.desiredPose);
530 common::debugEigenVec(datafields, "desired_twist", rtData.desiredTwist);
531 common::debugEigenVec(datafields, "kpCartVel", rtData.kpCartesianVel);
532 common::debugEigenVec(datafields, "kdCartVel", rtData.kdCartesianVel);
533
534 common::debugEigenVec(datafields, "currentForceTorque", rtStatus.currentForceTorque);
535
536 float currentForceNorm = rtStatus.currentForceTorque.head<3>().norm();
537 float currentTorqueNorm = rtStatus.currentForceTorque.tail<3>().norm();
538 float safeForceGuardOffsetNorm = rtStatus.safeFTGuardOffset.head<3>().norm();
539 float safeTorqueGuardOffsetNorm = rtStatus.safeFTGuardOffset.tail<3>().norm();
540 datafields["currentForceTorqueNorm"] = new Variant(currentForceNorm);
541 datafields["currentTorqueTorqueNorm"] = new Variant(currentTorqueNorm);
542 datafields["safeForceGuardOffsetNorm"] = new Variant(safeForceGuardOffsetNorm);
543 datafields["safeTorqueGuardOffsetNorm"] = new Variant(safeTorqueGuardOffsetNorm);
544 datafields["safeForceGuardDifference"] =
545 new Variant(currentForceNorm - safeForceGuardOffsetNorm);
546 datafields["safeTorqueGuardDifference"] =
547 new Variant(currentTorqueNorm - safeTorqueGuardOffsetNorm);
548 datafields["safeForceGuardThreshold"] =
549 new Variant(rtData.ftConfig.safeGuardForceThreshold);
550 datafields["safeTorqueGuardThreshold"] =
551 new Variant(rtData.ftConfig.safeGuardTorqueThreshold);
552
553 common::debugEigenVec(datafields, "cartesianVelTarget", rtStatus.cartesianVelTarget);
554 common::debugEigenVec(datafields, "nullspaceVel", rtStatus.nullspaceVelocity);
556 datafields, "nullspaceTarget", rtData.desiredNullspaceJointAngles.value());
557 common::debugEigenVec(datafields, "desiredJointVel", rtStatus.desiredJointVelocity);
558 debugObs->setDebugChannel(getClassName() + "_" + arm->kinematicChainName, datafields);
559 }
560
561 void
564 const DebugObserverInterfacePrx& debugObs)
565 {
566 for (auto& pair : limb)
567 {
568 if (not pair.second->rtReady.load())
569 continue;
570 limbPublish(pair.second, debugObs);
571 }
572 if (hands)
573 {
574 hands->onPublish(debugObs);
575 }
576 }
577
578 void
580 {
581 for (auto& pair : limb)
582 {
583 pair.second->rtReady.store(false);
584 }
585 }
586
587 void
589 {
590 VirtualRobot::RobotNodeSetPtr rns = rtGetRobot()->getRobotNodeSet(arm->kinematicChainName);
591 Eigen::Matrix4f currentPose = rns->getTCP()->getPoseInRootFrame();
592 auto quat = VirtualRobot::MathTools::eigen4f2quat(currentPose);
593 ARMARX_RT_LOGF_INFO("rt preactivate controller with target pose\n\n "
594 "[ %.2f, %.2f, %.2f, %.2f, %.2f, %.2f, %.2f ].",
595 currentPose(0, 3),
596 currentPose(1, 3),
597 currentPose(2, 3),
598 quat.w,
599 quat.x,
600 quat.y,
601 quat.z);
602
603 if (arm->reInitPreActivate.load())
604 {
605 arm->rtConfig.desiredNullspaceJointAngles.value() = rns->getJointValuesEigen();
606 arm->rtConfig.desiredPose = currentPose;
607
608 arm->bufferConfigUserToNonRt.reinitAllBuffers(arm->rtConfig);
609 arm->reInitPreActivate.store(false);
610 }
611 {
612 arm->nonRtConfig = arm->rtConfig;
613 arm->bufferConfigNonRtToRt.reinitAllBuffers(arm->rtConfig);
614 arm->bufferConfigRtToOnPublish.reinitAllBuffers(arm->rtConfig);
615 arm->bufferConfigRtToUser.reinitAllBuffers(arm->rtConfig);
616 }
617 {
618 arm->sensorDevices.updateJointValues(arm->rtStatus.jointPosition,
619 arm->rtStatus.jointVelocity,
620 arm->rtStatus.jointTorque);
621 arm->rtStatus.rtPreActivate(currentPose);
622
623 arm->rtStatusInNonRT = arm->rtStatus;
624 arm->nonRTDeltaT = 0.0;
625 arm->nonRTAccumulateTime = 0.0;
626 arm->bufferRtStatusToOnPublish.reinitAllBuffers(arm->rtStatus);
627 arm->bufferRtStatusToNonRt.reinitAllBuffers(arm->rtStatus);
628 arm->bufferRtStatusToUser.reinitAllBuffers(arm->rtStatus);
629 }
630
631 arm->controller.preactivateInit(rns);
632 }
633
634 void
636 {
637 for (auto& pair : limb)
638 {
639 ARMARX_RT_LOGF_INFO("rtPreActivateController for %s", pair.first.c_str());
640 limbReInit(pair.second);
641 userConfig.limbs.at(pair.first) = pair.second->rtConfig;
642 }
643 if (hands)
644 {
645 hands->rtPreActivate();
646 }
647 }
648
649 void
651 {
652 // for (auto& pair : limb)
653 // {
654 // pair.second->controller.isInitialized.store(false);
655 // }
656 // if (hands)
657 // {
658 // hands->rtPostDeactivate();
659 // }
660 }
661
662 /// ----------------------------------- GUI Widget ---------------------------------------------
665 const VirtualRobot::RobotPtr& robot,
666 const std::map<std::string, ConstControlDevicePtr>& controlDevices,
667 const std::map<std::string, ConstSensorDevicePtr>&)
668 {
669 using namespace armarx::WidgetDescription;
670 HBoxLayoutPtr layout = new HBoxLayout;
671
672
673 ::armarx::WidgetDescription::WidgetSeq widgets;
674
675 /// select default config
676 LabelPtr label = new Label;
677 label->text = "select a controller config";
678
679 StringComboBoxPtr cfgBox = new StringComboBox;
680 cfgBox->name = "config_box";
681 cfgBox->defaultIndex = 0;
682 cfgBox->multiSelect = false;
683
684 cfgBox->options = std::vector<std::string>{
685 "default", "default_right", "default_a7_right", "default_a6_right"};
687
688 layout->children.emplace_back(label);
689 layout->children.emplace_back(cfgBox);
691
692 layout->children.insert(layout->children.end(), widgets.begin(), widgets.end());
693 ARMARX_INFO_S << "Layout done";
694 return layout;
695 }
696
699 const StringVariantBaseMap& values)
700 {
701 auto cfgName = values.at("config_box")->getString();
702 const armarx::PackagePath configPath(
703 "armarx_control",
704 "controller_config/NJointTaskspaceVelocityController/" + cfgName + ".json");
705 ARMARX_INFO_S << "Loading config from " << configPath.toSystemPath();
706 ARMARX_CHECK(std::filesystem::exists(configPath.toSystemPath()));
707
708 auto cfgDTO = armarx::readFromJson<ConfigDict>(configPath.toSystemPath());
709
711 return new ConfigurableNJointControllerConfig{cfgDTO.toAronDTO()};
712 }
713
714} // namespace armarx::control::njoint_controller::task_space
#define ARMARX_RT_LOGF_WARN(...)
#define ARMARX_RT_LOGF_INFO(...)
#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
const SensorValueBase * useSensorValue(const std::string &sensorDeviceName) const
Get a const ptr to the given SensorDevice's SensorValue.
void runTask(const std::string &taskName, Task &&task)
Executes a given task in a separate thread from the Application ThreadPool.
const VirtualRobot::RobotPtr & useSynchronizedRtRobot(bool updateCollisionModel=false)
Requests a VirtualRobot for use in rtRun *.
const VirtualRobot::RobotPtr & rtGetRobot()
TODO make protected and use attorneys.
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
std::map< std::string, VirtualRobot::RobotNodeSetPtr > controllableNodeSets
void onPublish(const SensorAndControl &, const DebugDrawerInterfacePrx &, const DebugObserverInterfacePrx &) override
static WidgetDescription::WidgetPtr GenerateConfigDescription(const VirtualRobot::RobotPtr &, const std::map< std::string, ConstControlDevicePtr > &, const std::map< std::string, ConstSensorDevicePtr > &)
--------------------------------— GUI Widget ------------------------------------------—
::armarx::aron::data::dto::DictPtr getConfig(const Ice::Current &iceCurrent=Ice::emptyCurrent) override
Ice::FloatSeq getTCPVel(const std::string &rns, const Ice::Current &iceCurrent=Ice::emptyCurrent) override
bool isSafeForceTorque(const std::string &nodeSetName, const Ice::Current &iceCurrent=Ice::emptyCurrent) override
-----------------------------— Other interaces ----------------------------------------—
void limbRTSetTarget(ArmPtr &arm, const Eigen::VectorXf &targetVelocity)
void enableSafeGuardForceTorque(const std::string &nodeSetName, const bool forceGuard, const bool torqueGuard, const Ice::Current &iceCurrent=Ice::emptyCurrent) override
static ConfigPtrT GenerateConfigFromVariants(const StringVariantBaseMap &values)
void rtPostDeactivateController() override
This function is called after the controller is deactivated.
void rtRun(const IceUtil::Time &sensorValuesTimestamp, const IceUtil::Time &timeSinceLastIteration) override
TODO make protected and use attorneys.
void limbInit(const std::string nodeSetName, ArmPtr &arm, Config &cfg, VirtualRobot::RobotPtr &nonRtRobotPtr)
void updateConfig(const ::armarx::aron::data::dto::DictPtr &dto, const Ice::Current &iceCurrent=Ice::emptyCurrent) override
NJointController interface.
bool updateTargetPose(const TargetPoseMap &targetPoseMap, const TargetNullspaceMap &targetNullspaceMap, const Ice::Current &=Ice::emptyCurrent) override
NJointTaskspaceVelocityController(const RobotUnitPtr &robotUnit, const NJointControllerConfigPtr &config, const VirtualRobot::RobotPtr &)
void limbPublish(ArmPtr &arm, const DebugObserverInterfacePrx &debugObs)
void rtPreActivateController() override
This function is called before the controller is activated.
void limbRTUpdateStatus(ArmPtr &arm, const double deltaT)
-----------------------------— Real time cotnrol --------------------------------------—
#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_INFO_S
Definition Logging.h:202
#define ARMARX_WARNING
The logging level for unexpected behaviour, but not a serious problem.
Definition Logging.h:193
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
void debugEigenVec(StringVariantBaseMap &datafields, const std::string &name, Eigen::VectorXf vec)
Definition utils.cpp:190
void debugEigenPose(StringVariantBaseMap &datafields, const std::string &name, Eigen::Matrix4f pose)
Definition utils.cpp:140
NJointControllerRegistration< NJointTaskspaceVelocityController > registrationControllerNJointTaskspaceVelocityController("NJointTaskspaceVelocityController")
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
#define ARMARX_TRACE
Definition trace.h:77