5 #include <VirtualRobot/Nodes/RobotNode.h>
6 #include <VirtualRobot/math/Helpers.h>
15 #include <RobotAPI/interface/visualization/DebugDrawerInterface.h>
23 for (
size_t i = 0; i < vec.size(); i++)
35 operator<<(std::ostream& out,
const CartesianNaturalPositionControllerConfig& cfg)
37 out <<
"maxPositionAcceleration " << cfg.maxPositionAcceleration <<
'\n'
38 <<
"maxOrientationAcceleration " << cfg.maxOrientationAcceleration <<
'\n'
39 <<
"maxNullspaceAcceleration " << cfg.maxNullspaceAcceleration <<
'\n'
41 <<
"KpPos " << cfg.KpPos <<
'\n'
42 <<
"KpOri " << cfg.KpOri <<
'\n'
43 <<
"maxTcpPosVel " << cfg.maxTcpPosVel <<
'\n'
44 <<
"maxTcpOriVel " << cfg.maxTcpOriVel <<
'\n'
45 <<
"maxElpPosVel " << cfg.maxElbPosVel <<
'\n'
47 <<
"maxJointVelocity " <<
vec2str(cfg.maxJointVelocity) <<
'\n'
48 <<
"maxNullspaceVelocity " <<
vec2str(cfg.maxNullspaceVelocity) <<
'\n'
49 <<
"jointCosts " <<
vec2str(cfg.jointCosts) <<
'\n'
51 <<
"jointLimitAvoidanceKp " << cfg.jointLimitAvoidanceKp <<
'\n'
52 <<
"elbowKp " << cfg.elbowKp <<
'\n'
53 <<
"nullspaceTargetKp " << cfg.nullspaceTargetKp <<
'\n'
59 NJointControllerRegistration<NJointCartesianNaturalPositionController>
61 "NJointCartesianNaturalPositionController");
66 return "NJointCartesianNaturalPositionController";
71 const NJointCartesianNaturalPositionControllerConfigPtr& config,
84 _rtRns = _rtRobot->getRobotNodeSet(config->rns);
86 _rtTcp = _rtRns->getTCP();
88 _rtElbow = _rtRobot->getRobotNode(config->elbowNode);
91 _rtRobotRoot = _rtRobot->getRootNode();
97 if (!config->ftName.empty())
99 const auto svalFT = useSensorValue<SensorValueForceTorque>(config->ftName);
101 _rtForceSensor = &(svalFT->force);
102 _rtTorqueSensor = &(svalFT->force);
107 const auto reportFrameName = sdev->getReportingFrame();
109 <<
VAROUT(sdev->getReportingFrame());
111 _rtFT = _rtRobot->getRobotNode(reportFrameName);
113 <<
"No sensor report frame '" << reportFrameName <<
"' in robot";
119 _rtJointVelocityFeedbackBuffer =
120 Eigen::VectorXf::Zero(
static_cast<int>(_rtRns->getSize()));
122 _rtPosController = std::make_unique<CartesianNaturalPositionController>(
125 config->runCfg.maxPositionAcceleration,
126 config->runCfg.maxOrientationAcceleration,
127 config->runCfg.maxNullspaceAcceleration);
129 _rtPosController->setConfig(config->runCfg);
132 for (
size_t i = 0; i < _rtRns->getSize(); ++i)
134 std::string jointName = _rtRns->getNode(i)->getName();
135 auto ct = useControlTarget<ControlTarget1DoFActuatorVelocity>(
136 jointName, ControlModes::Velocity1DoF);
137 auto sv = useSensorValue<SensorValue1DoFActuatorVelocity>(jointName);
141 _rtVelTargets.emplace_back(&(ct->velocity));
142 _rtVelSensors.emplace_back(&(sv->velocity));
146 _rtFFvelMaxAgeMS = config->feedforwardVelocityTTLms;
148 _rtFTHistory.resize(config->ftHistorySize, FTval());
165 _publish.errorPos = 0;
166 _publish.errorOri = 0;
167 _publish.errorPosMax = 0;
168 _publish.errorOriMax = 0;
169 _publish.tcpPosVel = 0;
170 _publish.tcpOriVel = 0;
171 _publish.elbPosVel = 0;
174 _rtPosController->setTarget(_rtTcp->getPoseInRootFrame(),
175 _rtElbow->getPositionInRootFrame());
191 _rtPosController->setConfig(r.cfg);
202 _rtSetOrientation = r.setOrientation;
203 _rtPosController->setTarget(r.tcpTarget, r.elbowTarget);
204 _rtStopConditionReached =
false;
205 _publishIsAtForceLimit =
false;
215 if (r.clearRequested)
217 _rtPosController->clearNullspaceTarget();
222 _rtPosController->setNullspaceTarget(r.nullspaceTarget);
224 r.clearRequested =
false;
230 _rtFFvelLastUpdateMS = sensorValuesTimestamp.toMilliSeconds();
239 if (_rtFTlimit.force < 0 && _rtFTlimit.torque < 0)
241 _publishIsAtForceLimit =
false;
266 ft.force = *_rtForceSensor;
267 ft.torque = *_rtTorqueSensor;
271 ft.force = _rtFTfake.force;
272 ft.torque = _rtFTfake.torque;
276 _rtFTHistory.at(_rtFTHistoryIndex) = ft;
277 _rtFTHistoryIndex = (_rtFTHistoryIndex + 1) % _rtFTHistory.size();
280 for (
size_t i = 0; i < _rtFTHistory.size(); i++)
282 ftAvg.force += _rtFTHistory.at(i).force;
283 ftAvg.torque += _rtFTHistory.at(i).torque;
285 ftAvg.force = ftAvg.force / _rtFTHistory.size();
286 ftAvg.torque = ftAvg.torque / _rtFTHistory.size();
289 rt2nonrtBuf.currentFT = ft;
290 rt2nonrtBuf.averageFT = ftAvg;
292 if ((_rtFTlimit.force > 0 && ft.force.norm() > _rtFTlimit.force) ||
293 (_rtFTlimit.torque > 0 && ft.torque.norm() > _rtFTlimit.torque))
295 _rtStopConditionReached =
true;
296 _publishIsAtForceLimit =
true;
322 rt2nonrtBuf.rootPose = _rtRobot->getGlobalPose();
323 rt2nonrtBuf.tcp = _rtTcp->getPoseInRootFrame();
324 rt2nonrtBuf.elb = _rtElbow->getPoseInRootFrame();
325 rt2nonrtBuf.tcpTarg = _rtPosController->getCurrentTarget();
326 rt2nonrtBuf.elbTarg = ::math::Helpers::CreatePose(_rtPosController->getCurrentElbowTarget(),
330 if (_rtStopConditionReached)
338 _rtPosController->setNullSpaceControl(_nullspaceControlEnabled);
342 if (_rtFFvelLastUpdateMS + _rtFFvelMaxAgeMS >
343 sensorValuesTimestamp.toMilliSeconds())
345 _rtPosController->setFeedForwardVelocity(_rtFFvel.feedForwardVelocity);
350 _rtFFvel.use =
false;
354 const Eigen::VectorXf& goal =
355 _rtPosController->calculate(timeSinceLastIteration.toSecondsDouble(), mode);
357 const Eigen::VectorXf actualTcpVel = _rtPosController->actualTcpVel(goal);
358 const Eigen::VectorXf actualElbVel = _rtPosController->actualElbVel(goal);
360 _publish.tcpPosVel = actualTcpVel.block<3, 1>(0, 0).
norm();
361 _publish.tcpOriVel = actualTcpVel.block<3, 1>(3, 0).
norm();
362 _publish.elbPosVel = actualElbVel.block<3, 1>(0, 0).
norm();
366 for (std::size_t idx = 0; idx < _rtVelTargets.size(); ++idx)
368 float* ptr = _rtVelTargets[idx];
382 const CartesianNaturalPositionControllerConfig& cfg,
385 std::lock_guard g{_mutexSetTripBuf};
395 const Eigen::Vector3f& elbowTarget,
399 std::lock_guard g{_mutexSetTripBuf};
401 w.tcpTarget = tcpTarget;
402 w.elbowTarget = elbowTarget;
403 w.setOrientation = setOrientation;
407 << tcpTarget <<
"\nelbow: " << elbowTarget.transpose();
413 const Eigen::Vector3f& elbowTarget,
418 std::lock_guard g{_mutexSetTripBuf};
421 w.tcpTarget = tcpTarget;
422 w.elbowTarget = elbowTarget;
423 w.setOrientation = setOrientation;
428 w.feedForwardVelocity = ffVel;
439 std::lock_guard g{_mutexSetTripBuf};
441 w.feedForwardVelocity = vel;
451 std::lock_guard g{_mutexSetTripBuf};
453 w.feedForwardVelocity = Eigen::Vector6f::Zero();
461 NJointCartesianNaturalPositionController::setNullVelocity()
463 for (
auto ptr : _rtVelTargets)
480 std::lock_guard g{_tripFakeRobotGPWriteMutex};
488 std::lock_guard g{_tripFakeRobotGPWriteMutex};
496 _stopNowRequested =
true;
501 const Ice::FloatSeq& nullspaceTarget,
504 std::lock_guard g{_mutexSetTripBuf};
506 w.nullspaceTarget = nullspaceTarget;
507 w.clearRequested =
false;
516 std::lock_guard g{_mutexSetTripBuf};
518 w.clearRequested =
true;
528 _nullspaceControlEnabled =
enabled;
532 NJointCartesianNaturalPositionController::frost(
const FTval& ft)
536 r.torque = ft.torque;
543 std::lock_guard g{_tripRt2NonRtMutex};
550 std::lock_guard g{_tripRt2NonRtMutex};
558 std::lock_guard g{_mutexSetTripBuf};
560 w.force = offset.force;
561 w.torque = offset.torque;
565 << offset.force.transpose() <<
"\n"
566 << offset.torque.transpose();
572 std::lock_guard g{_mutexSetTripBuf};
574 w.force = Eigen::Vector3f::Zero();
575 w.torque = Eigen::Vector3f::Zero();
586 std::lock_guard g{_mutexSetTripBuf};
598 std::lock_guard g{_mutexSetTripBuf};
611 std::lock_guard g{_mutexSetTripBuf};
613 w.force = ftValue.force;
614 w.torque = ftValue.torque;
619 << ftValue.force.transpose() <<
"\n"
620 << ftValue.torque.transpose();
626 std::lock_guard g{_mutexSetTripBuf};
628 w.force = Eigen::Vector3f::Zero();
629 w.torque = Eigen::Vector3f::Zero();
640 return _publishIsAtForceLimit;
648 const float errorPos = _publish.errorPos;
649 const float errorOri = _publish.errorOri;
650 const float errorPosMax = _publish.errorPosMax;
651 const float errorOriMax = _publish.errorOriMax;
654 const float tcpPosVel = _publish.tcpPosVel;
655 const float tcpOriVel = _publish.tcpOriVel;
656 const float elbPosVel = _publish.elbPosVel;
661 datafields[
"errorPos"] =
new Variant(errorPos);
662 datafields[
"errorOri"] =
new Variant(errorOri);
663 datafields[
"errorPosMax"] =
new Variant(errorPosMax);
664 datafields[
"errorOriMax"] =
new Variant(errorOriMax);
666 datafields[
"tcpPosVel"] =
new Variant(tcpPosVel);
667 datafields[
"tcpOriVel"] =
new Variant(tcpOriVel);
668 datafields[
"elbPosVel"] =
new Variant(elbPosVel);
677 << errorPosMax <<
", oerror " << errorOri <<
" / " << errorOriMax <<
')';
680 std::lock_guard g{_tripRt2NonRtMutex};
686 if (buf.tcp != buf.tcpTarg)
692 drawer->setPoseVisu(
getName(),
"tcp",
new Pose(gtcp));
693 drawer->setPoseVisu(
getName(),
"tcptarg",
new Pose(gtcptarg));
696 new Vector3(Eigen::Vector3f{gtcp.topRightCorner<3, 1>()}),
697 new Vector3(Eigen::Vector3f{gtcptarg.topRightCorner<3, 1>()}),
702 new Vector3(Eigen::Vector3f{gelb.topRightCorner<3, 1>()}),
703 new Vector3(Eigen::Vector3f{gelbtarg.topRightCorner<3, 1>()}),
709 drawer->removePoseVisu(
getName(),
"tcp");
710 drawer->removePoseVisu(
getName(),
"tcptarg");
711 drawer->removeLineVisu(
getName(),
"tcp2targ");