30 #include <VirtualRobot/XML/RobotIO.h>
31 #include <VirtualRobot/IK/GazeIK.h>
32 #include <VirtualRobot/LinkedCoordinate.h>
34 #include <SimoxUtility/algorithm/string/string_tools.h>
52 std::unique_lock lock(accessMutex);
54 usingProxy(getProperty<std::string>(
"KinematicUnitName").getValue());
55 usingProxy(getProperty<std::string>(
"RobotStateComponentName").getValue());
59 cycleTime = getProperty<int>(
"CycleTime").getValue();
61 offeringTopic(getProperty<std::string>(
"HeadIKUnitTopicName").getValue());
67 std::unique_lock lock(accessMutex);
69 drawer = getTopic<DebugDrawerInterfacePrx>(
"DebugDrawerUpdates");
71 kinematicUnitPrx = getProxy<KinematicUnitInterfacePrx>(getProperty<std::string>(
"KinematicUnitName").getValue());
72 robotStateComponentPrx = getProxy<RobotStateComponentInterfacePrx>(getProperty<std::string>(
"RobotStateComponentName").getValue());
80 headIKUnitListener = getTopic<armarx::HeadIKUnitListenerPrx>(getProperty<std::string>(
"HeadIKUnitTopicName").getValue());
96 execTask->setDelayWarningTolerance(300);
108 drawer->removeSphereDebugLayerVisu(
"HeadViewTarget");
109 drawer->removeSphereDebugLayerVisu(
"HeadViewTargetSolution");
128 std::unique_lock lock(accessMutex);
130 cycleTime = milliseconds;
134 execTask->changeInterval(cycleTime);
141 std::unique_lock lock(accessMutex);
143 this->robotNodeSetNames =
armarx::Split(robotNodeSetName,
",");
144 for (
auto&
setName : robotNodeSetNames)
148 this->targetPosition->x = targetPosition->x;
149 this->targetPosition->y = targetPosition->y;
150 this->targetPosition->z = targetPosition->z;
151 this->targetPosition->frame = targetPosition->frame;
153 FramedPositionPtr globalTarget = FramedPositionPtr::dynamicCast(targetPosition)->toGlobal(robotStateComponentPrx->getSynchronizedRobot());
155 if (drawer && getProperty<bool>(
"VisualizeIKTarget").getValue())
157 drawer->setSphereDebugLayerVisu(
"HeadViewTarget",
159 DrawColor {1, 0, 0, 0.7},
165 ARMARX_DEBUG <<
"new Head target set: " << *globalTarget <<
" for " << robotNodeSetName;
189 case eManagedIceObjectStarted:
192 case eManagedIceObjectInitialized:
193 case eManagedIceObjectStarting:
194 return eUnitInitialized;
196 case eManagedIceObjectExiting:
197 case eManagedIceObjectExited:
201 return eUnitConstructed;
210 std::unique_lock lock(accessMutex);
220 execTask =
new PeriodicTask<HeadIKUnit>(
this, &HeadIKUnit::periodicExec, cycleTime,
false,
"TCPVelocityCalculator");
230 std::unique_lock lock(accessMutex);
237 drawer->removeSphereDebugLayerVisu(
"HeadViewTarget");
238 drawer->removeSphereDebugLayerVisu(
"HeadViewTargetSolution");
257 void HeadIKUnit::periodicExec()
259 bool doCalculation =
false;
262 std::unique_lock lock(accessMutex, std::defer_lock);
266 doCalculation = requested && newTargetSet;
267 newTargetSet =
false;
278 std::unique_lock lock(accessMutex);
280 VirtualRobot::RobotNodeSetPtr kinematicChain;
281 bool foundSolution =
false;
283 NameControlModeMap controlModes;
284 std::set<std::string> possiblyInvolvedJointNames;
286 for (
auto robotNodeSetName : robotNodeSetNames)
288 kinematicChain = localRobot->getRobotNodeSet(robotNodeSetName);
289 for (
unsigned int i = 0; i < kinematicChain->getSize(); i++)
291 possiblyInvolvedJointNames.insert(kinematicChain->getNode(i)->getName());
301 std::string selectedRobotNodeSetName;
302 for (
auto robotNodeSetName : robotNodeSetNames)
306 kinematicChain = localRobot->getRobotNodeSet(robotNodeSetName);
307 auto tcpNode = kinematicChain->getTCP();
308 VirtualRobot::RobotNodePrismaticPtr virtualPrismaticJoint;
310 virtualPrismaticJoint = std::dynamic_pointer_cast<VirtualRobot::RobotNodePrismatic>(tcpNode);
311 if (!virtualPrismaticJoint)
318 for (
auto& nodeName : possiblyInvolvedJointNames)
320 if (!kinematicChain->hasRobotNode(nodeName))
322 localRobot->getRobotNode(nodeName)->setJointValue(0.0f);
323 targetJointAngles[nodeName] = 0.0f;
324 controlModes[nodeName] = ePositionControl;
329 VirtualRobot::GazeIK ikSolver(kinematicChain, virtualPrismaticJoint);
330 ikSolver.enableJointLimitAvoidance(
true);
331 ikSolver.setup(10, 30, 20);
334 globalPos = targetPosition->toGlobal(localRobot);
335 ARMARX_DEBUG <<
"Calculating IK for target position " << globalPos->output();
336 auto start = IceUtil::Time::now();
337 bool solutionFound = ikSolver.solve(globalPos->toEigen());
338 auto duration = (IceUtil::Time::now() -
start);
340 if (duration.toMilliSeconds() > 500)
342 ARMARX_INFO <<
"Calculating Gaze IK took " << duration.toMilliSeconds() <<
" ms";
344 Eigen::Vector3f position = globalPos->toEigen() - kinematicChain->getTCP()->getGlobalPose().block(0, 3, 3, 1);
345 error = position.norm();
351 foundSolution =
true;
352 selectedRobotNodeSetName = robotNodeSetName;
353 ARMARX_INFO <<
"IKSolver found no solution! applying best solution with " << error <<
"mm error";
359 foundSolution =
true;
360 selectedRobotNodeSetName = robotNodeSetName;
366 ARMARX_WARNING <<
"IKSolver found no solution! " << error <<
"mm error";
369 ARMARX_DEBUG <<
"Solution found with " << selectedRobotNodeSetName <<
" - remaining error: " << error <<
" mm";
371 if (drawer && localRobot->hasRobotNode(
"Cameras") && getProperty<bool>(
"VisualizeIKTarget").getValue())
373 Vector3Ptr startPos =
new Vector3(localRobot->getRobotNode(
"Cameras")->getGlobalPose());
374 drawer->setSphereDebugLayerVisu(
"HeadViewTargetSolution",
376 DrawColor {0, 1, 1, 0.2},
379 auto tcpNode = kinematicChain->getTCP();
380 for (
int i = 0; i < (
signed int)kinematicChain->getSize(); i++)
382 if (kinematicChain->getNode(i) != tcpNode)
384 targetJointAngles[kinematicChain->getNode(i)->getName()] = kinematicChain->getNode(i)->getJointValue();
385 controlModes[kinematicChain->getNode(i)->getName()] = ePositionControl;
388 ARMARX_DEBUG << kinematicChain->getNode(i)->getName() <<
": " << kinematicChain->getNode(i)->getJointValue();
393 if (headIKUnitListener)
395 headIKUnitListener->reportHeadTargetChanged(targetJointAngles, globalPos);
400 kinematicUnitPrx->switchControlMode(controlModes);
401 ARMARX_DEBUG <<
"setting new joint angles" << targetJointAngles;
402 kinematicUnitPrx->setJointAngles(targetJointAngles);