27 #include <VirtualRobot/MathTools.h>
29 #include "VisualServoGroupStatechartContext.generated.h"
32 using namespace VisualServoGroup;
48 bool tcpTargetPoseSet = in.isTcpTargetPoseSet();
49 bool tcpTargetPositionSet = in.isTcpTargetPositionSet();
50 bool tcpTargetOrientationSet = in.isTCPTargetOrientationSet();
51 if (!tcpTargetPoseSet && !tcpTargetPositionSet)
53 ARMARX_ERROR <<
"Either TcpTargetPose or TcpTargetPosition has to be set for VisualServo, "
59 VisualServoGroupStatechartContext* context = getContext<VisualServoGroupStatechartContext>();
70 tcpTargetPose = in.getTcpTargetPose();
71 tcpTargetPoseEigen = tcpTargetPose->toGlobal(robot)->toEigen();
73 else if (tcpTargetPositionSet && !tcpTargetOrientationSet)
75 tcpTargetPoseEigen = handPoseEigen;
76 tcpTargetPoseEigen.block<3, 1>(0, 3) =
77 in.getTcpTargetPosition()->toGlobal(robot)->toEigen();
80 else if (tcpTargetPositionSet && tcpTargetOrientationSet)
82 tcpTargetPoseEigen.block<3, 3>(0, 0) =
83 in.getTCPTargetOrientation()->toGlobal(robot)->toEigen();
84 tcpTargetPoseEigen.block<3, 1>(0, 3) =
85 in.getTcpTargetPosition()->toGlobal(robot)->toEigen();
89 const float baseSpeedFactor = in.getBaseVelocityFactor();
90 const float maxSpeed = baseSpeedFactor * in.getMaxVelocityTranslation();
91 const float maxRotationSpeed =
92 baseSpeedFactor * in.getMaxVelocityRotation();
93 const float baseAngleRelativeSpeedFactor = 10;
97 Eigen::Vector3f diffPos =
98 tcpTargetPoseEigen.block<3, 1>(0, 3) - handPoseEigen.block<3, 1>(0, 3);
99 ARMARX_INFO << in.getKinematicChainName() <<
" : difference to target " << diffPos;
100 const float distanceToTarget = diffPos.norm();
106 float sig =
sigmoid(diffPos.norm(), 1.0);
108 diffPos = baseSpeedFactor * diffPos * sig;
109 float minSpeedPerc = in.getMinimumSpeedPercentage();
111 if (diffPos.norm() < maxSpeed * minSpeedPerc)
113 diffPos = diffPos.normalized() * (maxSpeed * minSpeedPerc);
116 if (diffPos.norm() > maxSpeed)
118 diffPos = diffPos.normalized() * (maxSpeed);
124 Eigen::Vector3f angles(0, 0, 0);
125 std::stringstream distanceStr;
126 distanceStr << distanceToTarget <<
" mm";
128 if (tcpTargetPoseSet || (tcpTargetPositionSet && tcpTargetOrientationSet))
132 tcpTargetPoseEigen.block<3, 3>(0, 0) * handPoseEigen.block<3, 3>(0, 0).inverse();
137 diffRot4.block<3, 3>(0, 0) = diffRot;
138 VirtualRobot::MathTools::eigen4f2rpy(diffRot4, angles);
142 diffPose.block<3, 3>(0, 0) = diffRot;
143 Eigen::Vector3f axis;
144 VirtualRobot::MathTools::eigen4f2axisangle(diffPose, axis, axisRot);
146 distanceStr <<
", " << axisRot * 180 /
M_PI <<
" deg";
148 float angleRelativeSpeedFactor = baseAngleRelativeSpeedFactor;
149 if (distanceToTarget < in.getPositionalAccuracy())
151 angleRelativeSpeedFactor *= 1.5f;
154 angles = angleRelativeSpeedFactor * baseSpeedFactor * angles;
155 if (angles.norm() > maxRotationSpeed)
159 angles *= maxRotationSpeed / angles.norm();
165 std::string kinematicChainName = getInput<std::string>(
"KinematicChainName");
167 ARMARX_VERBOSE <<
"Angle motion (" << angles(0) <<
", " << angles(1) <<
", " << angles(2)
179 setOutput(
"HandPose", handPose);
181 float accuracyFactor = 1.0;
182 float elapsed = in.getStartTimeRef()->getDataField(
"elapsedMs")->getInt();
183 float timeout = in.getAccuracyIncreaseTimeout();
185 if (timeout > 0 && elapsed < timeout)
187 accuracyFactor = 0.5 + pow(elapsed / timeout, 2);
190 accuracyFactor =
std::min(1.0f, accuracyFactor);
191 ARMARX_IMPORTANT <<
"Distance to target: " << distanceStr.str() <<
", Elapsed time: " << elapsed
192 <<
"\nCurrent Thresholds: " << in.getPositionalAccuracy() * accuracyFactor
194 << (in.getOrientationalAccuracyRad() * accuracyFactor) * 180.0f /
M_PI
199 if (context->getWorkingMemory()
200 ->getAgentInstancesSegment() )
203 auto globalHandPose = handPose->toGlobal(robot);
204 auto globalTargetPose = tcpTargetPose->toGlobal(robot);
206 auto chainName = in.getKinematicChainName();
207 context->getEntityDrawerTopic()->updateObjectPose(
208 "VisualServoHandVisu",
"tcpTarget_" + chainName, globalTargetPose);
210 context->getDebugDrawerTopic()->setSphereVisu(
"VisualServo",
211 "tcpTargetPoseAccuracy_" + chainName,
212 globalTargetPose->position,
213 DrawColor{1, 1, 0, 0.5},
214 in.getPositionalAccuracy() * accuracyFactor);
215 context->getDebugDrawerTopic()->setLineVisu(
"VisualServo",
216 "Distance to target_" + chainName,
217 globalHandPose->position,
218 globalTargetPose->position,
220 DrawColor{1, 1, 1, 1});
221 context->getDebugDrawerTopic()->setTextVisu(
"VisualServo",
222 "Distance_" + chainName,
224 globalTargetPose->position,
225 DrawColor{1, 0, 0, 1},
231 if ((distanceToTarget < in.getPositionalAccuracy() * accuracyFactor &&
232 axisRot < in.getOrientationalAccuracyRad() * accuracyFactor) ||
233 (elapsed > in.getTimeout() && distanceToTarget < in.getPositionalAccuracy() * 3 &&
234 axisRot < in.getOrientationalAccuracyRad() * 3))
241 else if (elapsed > in.getTimeout())
243 ARMARX_ERROR <<
"Could not reach object in time " << in.getTimeout()
244 <<
"ms - Remaining error: " << distanceToTarget <<
"mm and "
245 << axisRot * 180 /
M_PI <<
"deg";
252 context->getTCPControlUnit()->setTCPVelocity(
253 kinematicChainName,
"", cartesianVelocity, angleVelocity);
255 << (IceUtil::Time::now() - start).toMilliSeconds() <<
" ms";
257 emitTCPVelocitySet();
262 SetTCPVelocity::onBreak()
278 return 1 / (1 + pow(M_E, -t / 5.f + offset));
284 VisualServoGroupStatechartContext* context = getContext<VisualServoGroupStatechartContext>();
287 context->getRobot()->getRootNode()->getName(),
288 context->getRobot()->getName());
291 context->getRobot()->getRootNode()->getName(),
292 context->getRobot()->getName());
294 std::string kinematicChainName = getInput<std::string>(
"KinematicChainName");
296 context->getTCPControlUnit()->setTCPVelocity(
297 kinematicChainName,
"", cartesianVelocity, angleVelocity);
306 return "SetTCPVelocity";
319 VisualServoGroupStatechartContext* context = getContext<VisualServoGroupStatechartContext>();
320 context->getDebugDrawerTopic()->removeTextDebugLayerVisu(
"Distance");
321 context->getDebugDrawerTopic()->removeLineDebugLayerVisu(
"Distance to target");
322 context->getDebugDrawerTopic()->removePoseDebugLayerVisu(
"tcpTargetPose");
323 context->getDebugDrawerTopic()->removeSphereDebugLayerVisu(
"tcpTargetPoseAccuracy");