28 #include <SimoxUtility/algorithm/string/string_tools.h>
29 #include <VirtualRobot/IK/GazeIK.h>
30 #include <VirtualRobot/LinkedCoordinate.h>
31 #include <VirtualRobot/RobotNodeSet.h>
32 #include <VirtualRobot/XML/RobotIO.h>
48 std::unique_lock lock(accessMutex);
50 usingProxy(getProperty<std::string>(
"KinematicUnitName").getValue());
51 usingProxy(getProperty<std::string>(
"RobotStateComponentName").getValue());
54 cycleTime = getProperty<int>(
"CycleTime").getValue();
56 offeringTopic(getProperty<std::string>(
"HeadIKUnitTopicName").getValue());
62 std::unique_lock lock(accessMutex);
64 drawer = getTopic<DebugDrawerInterfacePrx>(
"DebugDrawerUpdates");
66 kinematicUnitPrx = getProxy<KinematicUnitInterfacePrx>(
67 getProperty<std::string>(
"KinematicUnitName").getValue());
68 robotStateComponentPrx = getProxy<RobotStateComponentInterfacePrx>(
69 getProperty<std::string>(
"RobotStateComponentName").getValue());
74 robotStateComponentPrx, VirtualRobot::RobotIO::RobotDescription::eStructure);
78 headIKUnitListener = getTopic<armarx::HeadIKUnitListenerPrx>(
79 getProperty<std::string>(
"HeadIKUnitTopicName").getValue());
95 this, &HeadIKUnit::periodicExec, cycleTime,
false,
"HeadIKCalculator");
96 execTask->setDelayWarningTolerance(300);
108 drawer->removeSphereDebugLayerVisu(
"HeadViewTarget");
109 drawer->removeSphereDebugLayerVisu(
"HeadViewTargetSolution");
127 std::unique_lock lock(accessMutex);
129 cycleTime = milliseconds;
133 execTask->changeInterval(cycleTime);
139 const FramedPositionBasePtr& targetPosition,
140 const Ice::Current&
c)
142 std::unique_lock lock(accessMutex);
144 this->robotNodeSetNames =
armarx::Split(robotNodeSetName,
",");
145 for (
auto&
setName : robotNodeSetNames)
149 this->targetPosition->x = targetPosition->x;
150 this->targetPosition->y = targetPosition->y;
151 this->targetPosition->z = targetPosition->z;
152 this->targetPosition->frame = targetPosition->frame;
155 FramedPositionPtr::dynamicCast(targetPosition)
156 ->toGlobal(robotStateComponentPrx->getSynchronizedRobot());
158 if (drawer && getProperty<bool>(
"VisualizeIKTarget").getValue())
160 drawer->setSphereDebugLayerVisu(
161 "HeadViewTarget", globalTarget, DrawColor{1, 0, 0, 0.7}, 15);
164 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;
208 std::unique_lock lock(accessMutex);
219 this, &HeadIKUnit::periodicExec, cycleTime,
false,
"TCPVelocityCalculator");
227 std::unique_lock lock(accessMutex);
234 drawer->removeSphereDebugLayerVisu(
"HeadViewTarget");
235 drawer->removeSphereDebugLayerVisu(
"HeadViewTargetSolution");
252 HeadIKUnit::periodicExec()
254 bool doCalculation =
false;
257 std::unique_lock lock(accessMutex, std::defer_lock);
261 doCalculation = requested && newTargetSet;
262 newTargetSet =
false;
273 std::unique_lock lock(accessMutex);
275 VirtualRobot::RobotNodeSetPtr kinematicChain;
276 bool foundSolution =
false;
278 NameControlModeMap controlModes;
279 std::set<std::string> possiblyInvolvedJointNames;
281 for (
auto robotNodeSetName : robotNodeSetNames)
283 kinematicChain = localRobot->getRobotNodeSet(robotNodeSetName);
284 for (
unsigned int i = 0; i < kinematicChain->getSize(); i++)
286 possiblyInvolvedJointNames.insert(kinematicChain->getNode(i)->getName());
296 std::string selectedRobotNodeSetName;
297 for (
auto robotNodeSetName : robotNodeSetNames)
301 kinematicChain = localRobot->getRobotNodeSet(robotNodeSetName);
302 auto tcpNode = kinematicChain->getTCP();
303 VirtualRobot::RobotNodePrismaticPtr virtualPrismaticJoint;
305 virtualPrismaticJoint =
306 std::dynamic_pointer_cast<VirtualRobot::RobotNodePrismatic>(tcpNode);
307 if (!virtualPrismaticJoint)
310 <<
"Head IK Kinematic Chain TCP is not a prismatic joint! "
311 "skipping joint set";
316 for (
auto& nodeName : possiblyInvolvedJointNames)
318 if (!kinematicChain->hasRobotNode(nodeName))
320 localRobot->getRobotNode(nodeName)->setJointValue(0.0f);
321 targetJointAngles[nodeName] = 0.0f;
322 controlModes[nodeName] = ePositionControl;
327 <<
VAROUT(kinematicChain->getName());
328 VirtualRobot::GazeIK ikSolver(kinematicChain, virtualPrismaticJoint);
329 ikSolver.enableJointLimitAvoidance(
true);
330 ikSolver.setup(10, 30, 20);
333 globalPos = targetPosition->toGlobal(localRobot);
334 ARMARX_DEBUG <<
"Calculating IK for target position " << globalPos->output();
335 auto start = IceUtil::Time::now();
336 bool solutionFound = ikSolver.solve(globalPos->toEigen());
337 auto duration = (IceUtil::Time::now() -
start);
339 if (duration.toMilliSeconds() > 500)
341 ARMARX_INFO <<
"Calculating Gaze IK took " << duration.toMilliSeconds()
344 Eigen::Vector3f position =
345 globalPos->toEigen() -
346 kinematicChain->getTCP()->getGlobalPose().block(0, 3, 3, 1);
347 error = position.norm();
353 foundSolution =
true;
354 selectedRobotNodeSetName = robotNodeSetName;
355 ARMARX_INFO <<
"IKSolver found no solution! applying best solution with "
356 << error <<
"mm error";
362 foundSolution =
true;
363 selectedRobotNodeSetName = robotNodeSetName;
369 ARMARX_WARNING <<
"IKSolver found no solution! " << error <<
"mm error";
372 ARMARX_DEBUG <<
"Solution found with " << selectedRobotNodeSetName
373 <<
" - remaining error: " << error <<
" mm";
375 if (drawer && localRobot->hasRobotNode(
"Cameras") &&
376 getProperty<bool>(
"VisualizeIKTarget").getValue())
379 new Vector3(localRobot->getRobotNode(
"Cameras")->getGlobalPose());
380 drawer->setSphereDebugLayerVisu(
381 "HeadViewTargetSolution", startPos, DrawColor{0, 1, 1, 0.2}, 17);
383 auto tcpNode = kinematicChain->getTCP();
384 for (
int i = 0; i < (
signed int)kinematicChain->getSize(); i++)
386 if (kinematicChain->getNode(i) != tcpNode)
388 targetJointAngles[kinematicChain->getNode(i)->getName()] =
389 kinematicChain->getNode(i)->getJointValue();
390 controlModes[kinematicChain->getNode(i)->getName()] = ePositionControl;
393 ARMARX_DEBUG << kinematicChain->getNode(i)->getName() <<
": "
394 << kinematicChain->getNode(i)->getJointValue();
398 if (headIKUnitListener)
400 headIKUnitListener->reportHeadTargetChanged(targetJointAngles, globalPos);
405 kinematicUnitPrx->switchControlMode(controlModes);
406 ARMARX_DEBUG <<
"setting new joint angles" << targetJointAngles;
407 kinematicUnitPrx->setJointAngles(targetJointAngles);