5 #include <VirtualRobot/math/Helpers.h>
14 #include <RobotAPI/interface/visualization/DebugDrawerInterface.h>
22 for (
size_t i = 0; i < vec.size(); i++)
34 operator<<(std::ostream& out,
const CartesianNaturalPositionControllerConfig& cfg)
36 out <<
"maxPositionAcceleration " << cfg.maxPositionAcceleration <<
'\n'
37 <<
"maxOrientationAcceleration " << cfg.maxOrientationAcceleration <<
'\n'
38 <<
"maxNullspaceAcceleration " << cfg.maxNullspaceAcceleration <<
'\n'
40 <<
"KpPos " << cfg.KpPos <<
'\n'
41 <<
"KpOri " << cfg.KpOri <<
'\n'
42 <<
"maxTcpPosVel " << cfg.maxTcpPosVel <<
'\n'
43 <<
"maxTcpOriVel " << cfg.maxTcpOriVel <<
'\n'
44 <<
"maxElpPosVel " << cfg.maxElbPosVel <<
'\n'
46 <<
"maxJointVelocity " <<
vec2str(cfg.maxJointVelocity) <<
'\n'
47 <<
"maxNullspaceVelocity " <<
vec2str(cfg.maxNullspaceVelocity) <<
'\n'
48 <<
"jointCosts " <<
vec2str(cfg.jointCosts) <<
'\n'
50 <<
"jointLimitAvoidanceKp " << cfg.jointLimitAvoidanceKp <<
'\n'
51 <<
"elbowKp " << cfg.elbowKp <<
'\n'
52 <<
"nullspaceTargetKp " << cfg.nullspaceTargetKp <<
'\n'
58 NJointControllerRegistration<NJointCartesianNaturalPositionController>
60 "NJointCartesianNaturalPositionController");
65 return "NJointCartesianNaturalPositionController";
70 const NJointCartesianNaturalPositionControllerConfigPtr& config,
83 _rtRns = _rtRobot->getRobotNodeSet(config->rns);
85 _rtTcp = _rtRns->getTCP();
87 _rtElbow = _rtRobot->getRobotNode(config->elbowNode);
90 _rtRobotRoot = _rtRobot->getRootNode();
96 if (!config->ftName.empty())
98 const auto svalFT = useSensorValue<SensorValueForceTorque>(config->ftName);
100 _rtForceSensor = &(svalFT->force);
101 _rtTorqueSensor = &(svalFT->force);
106 const auto reportFrameName = sdev->getReportingFrame();
108 <<
VAROUT(sdev->getReportingFrame());
110 _rtFT = _rtRobot->getRobotNode(reportFrameName);
112 <<
"No sensor report frame '" << reportFrameName <<
"' in robot";
118 _rtJointVelocityFeedbackBuffer =
119 Eigen::VectorXf::Zero(
static_cast<int>(_rtRns->getSize()));
121 _rtPosController = std::make_unique<CartesianNaturalPositionController>(
124 config->runCfg.maxPositionAcceleration,
125 config->runCfg.maxOrientationAcceleration,
126 config->runCfg.maxNullspaceAcceleration);
128 _rtPosController->setConfig(config->runCfg);
131 for (
size_t i = 0; i < _rtRns->getSize(); ++i)
133 std::string jointName = _rtRns->getNode(i)->getName();
134 auto ct = useControlTarget<ControlTarget1DoFActuatorVelocity>(
135 jointName, ControlModes::Velocity1DoF);
136 auto sv = useSensorValue<SensorValue1DoFActuatorVelocity>(jointName);
140 _rtVelTargets.emplace_back(&(ct->velocity));
141 _rtVelSensors.emplace_back(&(sv->velocity));
145 _rtFFvelMaxAgeMS = config->feedforwardVelocityTTLms;
147 _rtFTHistory.resize(config->ftHistorySize, FTval());
164 _publish.errorPos = 0;
165 _publish.errorOri = 0;
166 _publish.errorPosMax = 0;
167 _publish.errorOriMax = 0;
168 _publish.tcpPosVel = 0;
169 _publish.tcpOriVel = 0;
170 _publish.elbPosVel = 0;
173 _rtPosController->setTarget(_rtTcp->getPoseInRootFrame(),
174 _rtElbow->getPositionInRootFrame());
190 _rtPosController->setConfig(r.cfg);
201 _rtSetOrientation = r.setOrientation;
202 _rtPosController->setTarget(r.tcpTarget, r.elbowTarget);
203 _rtStopConditionReached =
false;
204 _publishIsAtForceLimit =
false;
214 if (r.clearRequested)
216 _rtPosController->clearNullspaceTarget();
221 _rtPosController->setNullspaceTarget(r.nullspaceTarget);
223 r.clearRequested =
false;
229 _rtFFvelLastUpdateMS = sensorValuesTimestamp.toMilliSeconds();
238 if (_rtFTlimit.force < 0 && _rtFTlimit.torque < 0)
240 _publishIsAtForceLimit =
false;
265 ft.force = *_rtForceSensor;
266 ft.torque = *_rtTorqueSensor;
270 ft.force = _rtFTfake.force;
271 ft.torque = _rtFTfake.torque;
275 _rtFTHistory.at(_rtFTHistoryIndex) = ft;
276 _rtFTHistoryIndex = (_rtFTHistoryIndex + 1) % _rtFTHistory.size();
279 for (
size_t i = 0; i < _rtFTHistory.size(); i++)
281 ftAvg.force += _rtFTHistory.at(i).force;
282 ftAvg.torque += _rtFTHistory.at(i).torque;
284 ftAvg.force = ftAvg.force / _rtFTHistory.size();
285 ftAvg.torque = ftAvg.torque / _rtFTHistory.size();
288 rt2nonrtBuf.currentFT = ft;
289 rt2nonrtBuf.averageFT = ftAvg;
291 if ((_rtFTlimit.force > 0 && ft.force.norm() > _rtFTlimit.force) ||
292 (_rtFTlimit.torque > 0 && ft.torque.norm() > _rtFTlimit.torque))
294 _rtStopConditionReached =
true;
295 _publishIsAtForceLimit =
true;
321 rt2nonrtBuf.rootPose = _rtRobot->getGlobalPose();
322 rt2nonrtBuf.tcp = _rtTcp->getPoseInRootFrame();
323 rt2nonrtBuf.elb = _rtElbow->getPoseInRootFrame();
324 rt2nonrtBuf.tcpTarg = _rtPosController->getCurrentTarget();
325 rt2nonrtBuf.elbTarg = ::math::Helpers::CreatePose(_rtPosController->getCurrentElbowTarget(),
329 if (_rtStopConditionReached)
337 _rtPosController->setNullSpaceControl(_nullspaceControlEnabled);
341 if (_rtFFvelLastUpdateMS + _rtFFvelMaxAgeMS >
342 sensorValuesTimestamp.toMilliSeconds())
344 _rtPosController->setFeedForwardVelocity(_rtFFvel.feedForwardVelocity);
349 _rtFFvel.use =
false;
353 const Eigen::VectorXf& goal =
354 _rtPosController->calculate(timeSinceLastIteration.toSecondsDouble(), mode);
356 const Eigen::VectorXf actualTcpVel = _rtPosController->actualTcpVel(goal);
357 const Eigen::VectorXf actualElbVel = _rtPosController->actualElbVel(goal);
359 _publish.tcpPosVel = actualTcpVel.block<3, 1>(0, 0).
norm();
360 _publish.tcpOriVel = actualTcpVel.block<3, 1>(3, 0).
norm();
361 _publish.elbPosVel = actualElbVel.block<3, 1>(0, 0).
norm();
365 for (std::size_t idx = 0; idx < _rtVelTargets.size(); ++idx)
367 float* ptr = _rtVelTargets[idx];
381 const CartesianNaturalPositionControllerConfig& cfg,
384 std::lock_guard g{_mutexSetTripBuf};
394 const Eigen::Vector3f& elbowTarget,
398 std::lock_guard g{_mutexSetTripBuf};
400 w.tcpTarget = tcpTarget;
401 w.elbowTarget = elbowTarget;
402 w.setOrientation = setOrientation;
406 << tcpTarget <<
"\nelbow: " << elbowTarget.transpose();
412 const Eigen::Vector3f& elbowTarget,
417 std::lock_guard g{_mutexSetTripBuf};
420 w.tcpTarget = tcpTarget;
421 w.elbowTarget = elbowTarget;
422 w.setOrientation = setOrientation;
427 w.feedForwardVelocity = ffVel;
438 std::lock_guard g{_mutexSetTripBuf};
440 w.feedForwardVelocity = vel;
450 std::lock_guard g{_mutexSetTripBuf};
452 w.feedForwardVelocity = Eigen::Vector6f::Zero();
460 NJointCartesianNaturalPositionController::setNullVelocity()
462 for (
auto ptr : _rtVelTargets)
479 std::lock_guard g{_tripFakeRobotGPWriteMutex};
487 std::lock_guard g{_tripFakeRobotGPWriteMutex};
495 _stopNowRequested =
true;
500 const Ice::FloatSeq& nullspaceTarget,
503 std::lock_guard g{_mutexSetTripBuf};
505 w.nullspaceTarget = nullspaceTarget;
506 w.clearRequested =
false;
515 std::lock_guard g{_mutexSetTripBuf};
517 w.clearRequested =
true;
527 _nullspaceControlEnabled =
enabled;
531 NJointCartesianNaturalPositionController::frost(
const FTval& ft)
535 r.torque = ft.torque;
542 std::lock_guard g{_tripRt2NonRtMutex};
549 std::lock_guard g{_tripRt2NonRtMutex};
557 std::lock_guard g{_mutexSetTripBuf};
559 w.force = offset.force;
560 w.torque = offset.torque;
564 << offset.force.transpose() <<
"\n"
565 << offset.torque.transpose();
571 std::lock_guard g{_mutexSetTripBuf};
573 w.force = Eigen::Vector3f::Zero();
574 w.torque = Eigen::Vector3f::Zero();
585 std::lock_guard g{_mutexSetTripBuf};
597 std::lock_guard g{_mutexSetTripBuf};
610 std::lock_guard g{_mutexSetTripBuf};
612 w.force = ftValue.force;
613 w.torque = ftValue.torque;
618 << ftValue.force.transpose() <<
"\n"
619 << ftValue.torque.transpose();
625 std::lock_guard g{_mutexSetTripBuf};
627 w.force = Eigen::Vector3f::Zero();
628 w.torque = Eigen::Vector3f::Zero();
639 return _publishIsAtForceLimit;
647 const float errorPos = _publish.errorPos;
648 const float errorOri = _publish.errorOri;
649 const float errorPosMax = _publish.errorPosMax;
650 const float errorOriMax = _publish.errorOriMax;
653 const float tcpPosVel = _publish.tcpPosVel;
654 const float tcpOriVel = _publish.tcpOriVel;
655 const float elbPosVel = _publish.elbPosVel;
660 datafields[
"errorPos"] =
new Variant(errorPos);
661 datafields[
"errorOri"] =
new Variant(errorOri);
662 datafields[
"errorPosMax"] =
new Variant(errorPosMax);
663 datafields[
"errorOriMax"] =
new Variant(errorOriMax);
665 datafields[
"tcpPosVel"] =
new Variant(tcpPosVel);
666 datafields[
"tcpOriVel"] =
new Variant(tcpOriVel);
667 datafields[
"elbPosVel"] =
new Variant(elbPosVel);
676 << errorPosMax <<
", oerror " << errorOri <<
" / " << errorOriMax <<
')';
679 std::lock_guard g{_tripRt2NonRtMutex};
685 if (buf.tcp != buf.tcpTarg)
691 drawer->setPoseVisu(
getName(),
"tcp",
new Pose(gtcp));
692 drawer->setPoseVisu(
getName(),
"tcptarg",
new Pose(gtcptarg));
695 new Vector3(Eigen::Vector3f{gtcp.topRightCorner<3, 1>()}),
696 new Vector3(Eigen::Vector3f{gtcptarg.topRightCorner<3, 1>()}),
701 new Vector3(Eigen::Vector3f{gelb.topRightCorner<3, 1>()}),
702 new Vector3(Eigen::Vector3f{gelbtarg.topRightCorner<3, 1>()}),
708 drawer->removePoseVisu(
getName(),
"tcp");
709 drawer->removePoseVisu(
getName(),
"tcptarg");
710 drawer->removeLineVisu(
getName(),
"tcp2targ");