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);
62 std::unique_lock lock(accessMutex);
74 robotStateComponentPrx, VirtualRobot::RobotIO::RobotDescription::eStructure);
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());
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") &&
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);
std::string getConfigIdentifier()
Retrieve config identifier for this component as set in constructor.
Property< PropertyType > getProperty(const std::string &name)
The FramedPosition class.
void onInitComponent() override
Pure virtual hook for the subclass.
void start(const Ice::Current &c=Ice::emptyCurrent) override
void release(const Ice::Current &c=Ice::emptyCurrent) override
UnitExecutionState getExecutionState(const Ice::Current &c=Ice::emptyCurrent) override
void onDisconnectComponent() override
Hook for subclass.
void init(const Ice::Current &c=Ice::emptyCurrent) override
void setCycleTime(Ice::Int milliseconds, const Ice::Current &c=Ice::emptyCurrent) override
void stop(const Ice::Current &c=Ice::emptyCurrent) override
void setHeadTarget(const std::string &robotNodeSetName, const FramedPositionBasePtr &targetPosition, const Ice::Current &c=Ice::emptyCurrent) override
void onConnectComponent() override
Pure virtual hook for the subclass.
void request(const Ice::Current &c=Ice::emptyCurrent) override
PropertyDefinitionsPtr createPropertyDefinitions() override
void onExitComponent() override
Hook for subclass.
SpamFilterDataPtr deactivateSpam(float deactivationDurationSec=10.0f, const std::string &identifier="", bool deactivate=true) const
disables the logging for the current line for the given amount of seconds.
void offeringTopic(const std::string &name)
Registers a topic for retrival after initialization.
TopicProxyType getTopic(const std::string &name)
Returns a proxy of the specified topic.
bool usingProxy(const std::string &name, const std::string &endpoints="")
Registers a proxy for retrieval after initialization and adds it to the dependency list.
Ice::ObjectPrx getProxy(long timeoutMs=0, bool waitForScheduler=true) const
Returns the proxy of this object (optionally it waits for the proxy)
int getState() const
Retrieve current state of the ManagedIceObject.
void setName(std::string name)
Override name of well-known object.
The periodic task executes one thread method repeatedly using the time period specified in the constr...
Property< PropertyType > getProperty(const std::string &name)
Property creation and retrieval.
static VirtualRobot::RobotPtr createLocalCloneFromFile(RobotStateComponentInterfacePrx robotStatePrx, VirtualRobot::RobotIO::RobotDescription loadMode=VirtualRobot::RobotIO::eFull)
This is a convenience function for createLocalClone, which automatically gets the filename from the R...
static bool synchronizeLocalClone(VirtualRobot::RobotPtr robot, RobotStateComponentInterfacePrx robotStatePrx)
#define ARMARX_INFO
The normal logging level.
#define ARMARX_IMPORTANT
The logging level for always important information, but expected behaviour (in contrast to ARMARX_WAR...
#define ARMARX_DEBUG
The logging level for output that is only interesting while debugging.
#define ARMARX_WARNING
The logging level for unexpected behaviour, but not a serious problem.
This file offers overloads of toIce() and fromIce() functions for STL container types.
IceInternal::Handle< Vector3 > Vector3Ptr
std::vector< std::string > Split(const std::string &source, const std::string &splitBy, bool trimElements=false, bool removeEmptyElements=false)
IceUtil::Handle< class PropertyDefinitionContainer > PropertyDefinitionsPtr
PropertyDefinitions smart pointer type.
IceInternal::Handle< FramedPosition > FramedPositionPtr