27 #include "VisualServoGroupStatechartContext.generated.h"
29 #include <VirtualRobot/MathTools.h>
32 using namespace VisualServoGroup;
50 bool tcpTargetPoseSet = in.isTcpTargetPoseSet();
51 bool tcpTargetPositionSet = in.isTcpTargetPositionSet();
52 bool tcpTargetOrientationSet = in.isTCPTargetOrientationSet();
53 if (!tcpTargetPoseSet && !tcpTargetPositionSet)
55 ARMARX_ERROR <<
"Either TcpTargetPose or TcpTargetPosition has to be set for VisualServo, but none is set.";
60 VisualServoGroupStatechartContext* context = getContext<VisualServoGroupStatechartContext>();
71 tcpTargetPose = in.getTcpTargetPose();
72 tcpTargetPoseEigen = tcpTargetPose->toGlobal(robot)->toEigen();
74 else if (tcpTargetPositionSet && !tcpTargetOrientationSet)
76 tcpTargetPoseEigen = handPoseEigen;
77 tcpTargetPoseEigen.block<3, 1>(0, 3) = in.getTcpTargetPosition()->toGlobal(robot)->toEigen();
80 else if (tcpTargetPositionSet && tcpTargetOrientationSet)
82 tcpTargetPoseEigen.block<3, 3>(0, 0) = in.getTCPTargetOrientation()->toGlobal(robot)->toEigen();
83 tcpTargetPoseEigen.block<3, 1>(0, 3) = in.getTcpTargetPosition()->toGlobal(robot)->toEigen();
87 const float baseSpeedFactor = in.getBaseVelocityFactor();
88 const float maxSpeed = baseSpeedFactor * in.getMaxVelocityTranslation();
89 const float maxRotationSpeed = baseSpeedFactor * in.getMaxVelocityRotation();
90 const float baseAngleRelativeSpeedFactor = 10;
94 Eigen::Vector3f diffPos = tcpTargetPoseEigen.block<3, 1>(0, 3) - handPoseEigen.block<3, 1>(0, 3);
95 ARMARX_INFO << in.getKinematicChainName() <<
" : difference to target " << diffPos;
96 const float distanceToTarget = diffPos.norm();
102 float sig =
sigmoid(diffPos.norm(), 1.0);
104 diffPos = baseSpeedFactor * diffPos * sig;
105 float minSpeedPerc = in.getMinimumSpeedPercentage();
107 if (diffPos.norm() < maxSpeed * minSpeedPerc)
109 diffPos = diffPos.normalized() * (maxSpeed * minSpeedPerc);
112 if (diffPos.norm() > maxSpeed)
114 diffPos = diffPos.normalized() * (maxSpeed);
120 Eigen::Vector3f angles(0, 0, 0);
121 std::stringstream distanceStr;
122 distanceStr << distanceToTarget <<
" mm";
124 if (tcpTargetPoseSet || (tcpTargetPositionSet && tcpTargetOrientationSet))
127 Eigen::Matrix3f diffRot = tcpTargetPoseEigen.block<3, 3>(0, 0) * handPoseEigen.block<3, 3>(0, 0).inverse();
132 diffRot4.block<3, 3>(0, 0) = diffRot;
133 VirtualRobot::MathTools::eigen4f2rpy(diffRot4, angles);
137 diffPose.block<3, 3>(0, 0) = diffRot;
138 Eigen::Vector3f axis;
139 VirtualRobot::MathTools::eigen4f2axisangle(diffPose, axis, axisRot);
141 distanceStr <<
", " << axisRot * 180 /
M_PI <<
" deg";
143 float angleRelativeSpeedFactor = baseAngleRelativeSpeedFactor;
144 if (distanceToTarget < in.getPositionalAccuracy())
146 angleRelativeSpeedFactor *= 1.5f;
149 angles = angleRelativeSpeedFactor * baseSpeedFactor * angles;
150 if (angles.norm() > maxRotationSpeed)
153 angles *= maxRotationSpeed / angles.norm();
159 std::string kinematicChainName = getInput<std::string>(
"KinematicChainName");
161 ARMARX_VERBOSE <<
"Angle motion (" << angles(0) <<
", " << angles(1) <<
", " << angles(2) <<
")";
172 setOutput(
"HandPose", handPose);
174 float accuracyFactor = 1.0;
175 float elapsed = in.getStartTimeRef()->getDataField(
"elapsedMs")->getInt();
176 float timeout = in.getAccuracyIncreaseTimeout();
178 if (timeout > 0 && elapsed < timeout)
180 accuracyFactor = 0.5 + pow(elapsed / timeout, 2);
183 accuracyFactor =
std::min(1.0f, accuracyFactor);
184 ARMARX_IMPORTANT <<
"Distance to target: " << distanceStr.str() <<
", Elapsed time: " << elapsed <<
185 "\nCurrent Thresholds: " << in.getPositionalAccuracy() * accuracyFactor <<
"mm, " << (in.getOrientationalAccuracyRad() * accuracyFactor) * 180.0f /
M_PI <<
"deg";
189 if (context->getWorkingMemory()->getAgentInstancesSegment() )
192 auto globalHandPose = handPose->toGlobal(robot);
193 auto globalTargetPose = tcpTargetPose->toGlobal(robot);
195 auto chainName = in.getKinematicChainName();
196 context->getEntityDrawerTopic()->updateObjectPose(
"VisualServoHandVisu",
"tcpTarget_" + chainName, globalTargetPose);
198 context->getDebugDrawerTopic()->setSphereVisu(
"VisualServo",
"tcpTargetPoseAccuracy_" + chainName,
199 globalTargetPose->position,
200 DrawColor {1, 1, 0, 0.5},
201 in.getPositionalAccuracy() * accuracyFactor);
202 context->getDebugDrawerTopic()->setLineVisu(
"VisualServo",
"Distance to target_" + chainName,
203 globalHandPose->position,
204 globalTargetPose->position, 5, DrawColor {1, 1, 1, 1});
205 context->getDebugDrawerTopic()->setTextVisu(
"VisualServo",
"Distance_" + chainName, distanceStr.str(), globalTargetPose->position,
206 DrawColor {1, 0, 0, 1}, 15);
212 if ((distanceToTarget < in.getPositionalAccuracy() * accuracyFactor && axisRot < in.getOrientationalAccuracyRad() * accuracyFactor)
213 || (elapsed > in.getTimeout() && distanceToTarget < in.getPositionalAccuracy() * 3 && axisRot < in.getOrientationalAccuracyRad() * 3))
220 else if (elapsed > in.getTimeout())
222 ARMARX_ERROR <<
"Could not reach object in time " << in.getTimeout() <<
"ms - Remaining error: " << distanceToTarget <<
"mm and " << axisRot * 180 /
M_PI <<
"deg" ;
229 context->getTCPControlUnit()->setTCPVelocity(kinematicChainName,
"", cartesianVelocity, angleVelocity);
230 ARMARX_VERBOSE <<
"Time for SetHandVelocity - hand IK: " << (IceUtil::Time::now() - start).toMilliSeconds() <<
" ms";
232 emitTCPVelocitySet();
242 void SetTCPVelocity::onBreak()
258 return 1 / (1 + pow(M_E, -t / 5.f + offset));
263 VisualServoGroupStatechartContext* context = getContext<VisualServoGroupStatechartContext>();
264 FramedDirectionPtr cartesianVelocity =
new FramedDirection(Eigen::Vector3f::Zero(), context->getRobot()->getRootNode()->getName(), context->getRobot()->getName());
267 std::string kinematicChainName = getInput<std::string>(
"KinematicChainName");
269 context->getTCPControlUnit()->setTCPVelocity(kinematicChainName,
"", cartesianVelocity, angleVelocity);
279 return "SetTCPVelocity";
292 VisualServoGroupStatechartContext* context = getContext<VisualServoGroupStatechartContext>();
293 context->getDebugDrawerTopic()->removeTextDebugLayerVisu(
"Distance");
294 context->getDebugDrawerTopic()->removeLineDebugLayerVisu(
"Distance to target");
295 context->getDebugDrawerTopic()->removePoseDebugLayerVisu(
"tcpTargetPose");
296 context->getDebugDrawerTopic()->removeSphereDebugLayerVisu(
"tcpTargetPoseAccuracy");