30 #include <SimoxUtility/algorithm/string/string_tools.h>
31 #include <VirtualRobot/IK/DifferentialIK.h>
32 #include <VirtualRobot/MathTools.h>
33 #include <VirtualRobot/RobotConfig.h>
34 #include <VirtualRobot/RobotNodeSet.h>
35 #include <VirtualRobot/XML/RobotIO.h>
44 using namespace Eigen;
48 TCPControlUnit::TCPControlUnit() :
49 maxJointVelocity(30.f / 180 * 3.141),
52 calculationRunning(false)
59 topicName =
getName() +
"State";
60 usingProxy(getProperty<std::string>(
"KinematicUnitName").getValue());
61 usingProxy(getProperty<std::string>(
"RobotStateComponentName").getValue());
64 usingTopic(getProperty<std::string>(
"RobotStateTopicName").getValue());
66 cycleTime = getProperty<int>(
"CycleTime").getValue();
67 maxJointVelocity = getProperty<float>(
"MaxJointVelocity").getValue();
73 std::unique_lock lock(dataMutex);
75 debugObs = getTopic<DebugObserverInterfacePrx>(
"DebugObserver");
76 kinematicUnitPrx = getProxy<KinematicUnitInterfacePrx>(
77 getProperty<std::string>(
"KinematicUnitName").getValue());
78 robotStateComponentPrx = getProxy<RobotStateComponentInterfacePrx>(
79 getProperty<std::string>(
"RobotStateComponentName").getValue());
83 robotName = robotStateComponentPrx->getRobotName();
85 robotStateComponentPrx->getRobotFilename(),
86 robotStateComponentPrx->getArmarXPackages());
87 jointExistenceCheckRobot =
89 robotStateComponentPrx->getRobotFilename(),
90 robotStateComponentPrx->getArmarXPackages());
92 localReportRobot = localRobot->clone(localRobot->getName());
94 std::string nodesetsString = getProperty<std::string>(
"TCPsToReport").getValue();
95 nodesToReport.clear();
96 if (!nodesetsString.empty())
98 if (nodesetsString ==
"*")
100 auto nodesets = localReportRobot->getRobotNodeSets();
102 for (RobotNodeSetPtr&
set : nodesets)
106 nodesToReport.push_back(
set->getTCP());
114 for (
auto& name : nodesetNames)
116 auto node = localReportRobot->getRobotNode(name);
120 nodesToReport.push_back(node);
124 ARMARX_ERROR <<
"Could not find node with name: " << name;
130 std::vector<RobotNodePtr> nodes = localRobot->getRobotNodes();
132 for (
unsigned int i = 0; i < nodes.size(); i++)
138 listener = getTopic<TCPControlUnitListenerPrx>(topicName);
148 this, &TCPControlUnit::periodicExec, cycleTime,
false,
"TCPVelocityCalculator");
150 execTask->setDelayWarningTolerance(100);
161 catch (std::exception& e)
180 std::unique_lock lock(taskMutex);
181 cycleTime = milliseconds;
185 execTask->changeInterval(cycleTime);
191 const std::string& tcpName,
192 const FramedDirectionBasePtr& translationVelocity,
193 const FramedDirectionBasePtr& orientationVelocityRPY,
194 const Ice::Current&
c)
198 ARMARX_WARNING <<
"Implicitly requesting TCPControlUnit! Please call request before "
199 "setting TCPVelocities!";
203 std::unique_lock lock(dataMutex);
205 <<
"The robot does not have the node set: " + nodeSetName;
208 if (translationVelocity)
210 ARMARX_DEBUG <<
"Setting new Velocity for " << nodeSetName <<
" in frame "
211 << translationVelocity->frame <<
":\n"
212 << FramedDirectionPtr::dynamicCast(translationVelocity)->toEigen();
215 if (orientationVelocityRPY)
217 ARMARX_DEBUG <<
"Orientation Velo in frame " << orientationVelocityRPY->frame <<
": \n"
218 << FramedDirectionPtr::dynamicCast(orientationVelocityRPY)->toEigen();
221 TCPVelocityData
data;
222 data.nodeSetName = nodeSetName;
223 data.translationVelocity = FramedDirectionPtr::dynamicCast(translationVelocity);
224 data.orientationVelocity = FramedDirectionPtr::dynamicCast(orientationVelocityRPY);
229 jointExistenceCheckRobot->getRobotNodeSet(nodeSetName)->getTCP()->getName();
234 <<
"The robot does not have the node: " + tcpName;
236 data.tcpName = tcpName;
239 tcpVelocitiesMap[
data.tcpName] =
data;
262 case eManagedIceObjectStarted:
265 case eManagedIceObjectInitialized:
266 case eManagedIceObjectStarting:
267 return eUnitInitialized;
269 case eManagedIceObjectExiting:
270 case eManagedIceObjectExited:
274 return eUnitConstructed;
292 std::unique_lock lock(dataMutex);
296 this, &TCPControlUnit::periodicExec, cycleTime,
false,
"TCPVelocityCalculator");
298 execTask->setDelayWarningTolerance(100);
306 std::unique_lock lock(dataMutex);
313 tcpVelocitiesMap.clear();
314 localTcpVelocitiesMap.clear();
328 TCPControlUnit::periodicExec()
330 std::unique_lock lock(dataMutex, std::defer_lock);
336 localTcpVelocitiesMap.clear();
337 TCPVelocityDataMap::iterator it = tcpVelocitiesMap.begin();
339 for (; it != tcpVelocitiesMap.end(); it++)
341 localTcpVelocitiesMap[it->first] = it->second;
345 DIKMap::iterator itDIK = dIKMap.begin();
347 for (; itDIK != dIKMap.end(); itDIK++)
349 localDIKMap[itDIK->first] = itDIK->second;
368 TCPVelocityDataMap::iterator it = localTcpVelocitiesMap.begin();
370 for (; it != localTcpVelocitiesMap.end(); it++)
372 const TCPVelocityData&
data = it->second;
373 RobotNodeSetPtr nodeSet = localRobot->getRobotNodeSet(
data.nodeSetName);
375 DIKMap::iterator itDIK = localDIKMap.find(
data.nodeSetName);
377 if (itDIK == localDIKMap.end())
380 nodeSet, localRobot->getRootNode(), VirtualRobot::JacobiProvider::eSVDDamped));
381 float lambda = getProperty<float>(
"LambdaDampedSVD").getValue();
382 dIk->setDampedSvdLambda(lambda);
383 localDIKMap[
data.nodeSetName] = dIk;
386 auto dIk = std::dynamic_pointer_cast<EDifferentialIK>(localDIKMap[
data.nodeSetName]);
390 using namespace Eigen;
392 it = localTcpVelocitiesMap.begin();
394 for (; it != localTcpVelocitiesMap.end(); it++)
397 TCPVelocityData&
data = it->second;
399 std::string refFrame = localRobot->getRootNode()->getName();
402 if (
data.translationVelocity &&
data.orientationVelocity)
404 mode = IKSolver::All;
407 else if (
data.translationVelocity && !
data.orientationVelocity)
411 else if (!
data.translationVelocity &&
data.orientationVelocity)
421 RobotNodePtr tcpNode = localRobot->getRobotNode(
data.tcpName);
425 if (
data.orientationVelocity)
429 Eigen::AngleAxisf(
data.orientationVelocity->z * cycleTime * 0.001,
430 Eigen::Vector3f::UnitZ()) *
431 Eigen::AngleAxisf(
data.orientationVelocity->y * cycleTime * 0.001,
432 Eigen::Vector3f::UnitY()) *
433 Eigen::AngleAxisf(
data.orientationVelocity->x * cycleTime * 0.001,
434 Eigen::Vector3f::UnitX());
436 if (
data.orientationVelocity->frame != refFrame)
442 trafoOriginalFrameToGlobal =
443 localRobot->getRobotNode(
data.orientationVelocity->frame)
451 trafoRefFrameToGlobal = localRobot->getRobotNode(refFrame)->getGlobalPose();
455 trafoRefFrameToGlobal.inverse() * trafoOriginalFrameToGlobal;
456 rotInRefFrame = trafoOriginalToRef.block<3, 3>(0, 0) * rotInOriginalFrame *
457 trafoOriginalToRef.block<3, 3>(0, 0).inverse();
461 rotInRefFrame = rotInOriginalFrame;
464 m.block(0, 0, 3, 3) = rotInRefFrame * (tcpNode->getGlobalPose().block(0, 0, 3, 3));
472 if (
data.translationVelocity)
474 data.translationVelocity =
477 <<
data.translationVelocity->toEigen();
479 m.block<3, 1>(0, 3) = tcpNode->getGlobalPose().block<3, 1>(0, 3) +
480 data.translationVelocity->toEigen() * cycleTime * 0.001;
484 DifferentialIKPtr dIK = localDIKMap[
data.nodeSetName];
489 <<
"DiffIK is NULL for robot node set: " <<
data.nodeSetName;
503 dIK->setGoal(m, tcpNode, mode, 0.001, 0.001 / 180.0f * 3.14159);
510 NameControlModeMap controlModes;
511 DIKMap::iterator itDIK = localDIKMap.begin();
513 for (; itDIK != localDIKMap.end(); itDIK++)
515 RobotNodeSetPtr robotNodeSet = localRobot->getRobotNodeSet(itDIK->first);
517 auto dIK = std::dynamic_pointer_cast<EDifferentialIK>(itDIK->second);
520 Eigen::VectorXf jointDelta;
525 jointDelta /= (cycleTime * 0.001);
527 jointDelta = applyMaxJointVelocity(jointDelta, maxJointVelocity);
529 lastTCPPose = robotNodeSet->getTCP()->getGlobalPose();
533 const std::vector<VirtualRobot::RobotNodePtr> nodes = robotNodeSet->getAllRobotNodes();
534 std::vector<VirtualRobot::RobotNodePtr>::const_iterator iter = nodes.begin();
537 while (iter != nodes.end() && i < jointDelta.rows())
539 if (targetVelocities.find((*iter)->getName()) != targetVelocities.end())
543 <<
" is set from two joint delta calculations - overwriting first value";
546 targetVelocities.insert(std::make_pair((*iter)->getName(), jointDelta(i)));
548 controlModes.insert(std::make_pair((*iter)->getName(), eVelocityControl));
555 kinematicUnitPrx->switchControlMode(controlModes);
556 kinematicUnitPrx->setJointVelocities(targetVelocities);
560 TCPControlUnit::ContinuousAngles(
const Eigen::AngleAxisf& oldAngle,
561 Eigen::AngleAxisf& newAngle,
565 const Eigen::Vector3f& v1 = oldAngle.axis();
566 const Eigen::Vector3f& v2 = newAngle.axis();
567 const Eigen::Vector3f& v2i = newAngle.axis() * -1;
568 double angle = acos(v1.dot(v2) / (v1.norm() * v2.norm()));
569 double angleInv = acos(v1.dot(v2i) / (v1.norm() * v2i.norm()));
574 if (
angle > angleInv)
577 newAngle = Eigen::AngleAxisf(2.0 *
M_PI - newAngle.angle(), newAngle.axis() * -1);
582 if (fabs(newAngle.angle() + offset - oldAngle.angle()) >
583 fabs(newAngle.angle() + offset - (oldAngle.angle() +
M_PI * 2)))
587 else if (fabs(newAngle.angle() + offset - oldAngle.angle()) >
588 fabs((newAngle.angle() +
M_PI * 2 + offset) - oldAngle.angle()))
593 newAngle.angle() += offset;
598 const Eigen::MatrixXf& jacobian,
599 const Eigen::MatrixXf& jacobianInverse,
600 Eigen::VectorXf desiredJointValues)
602 std::vector<VirtualRobot::RobotNodePtr> nodes = robotNodeSet->getAllRobotNodes();
603 Eigen::VectorXf actualJointValues(nodes.size());
605 if (desiredJointValues.rows() == 0)
608 desiredJointValues.resize(nodes.size());
610 for (
unsigned int i = 0; i < nodes.size(); i++)
612 VirtualRobot::RobotNodePtr node = nodes.at(i);
613 desiredJointValues(i) =
614 (node->getJointLimitHigh() - node->getJointLimitLow()) * 0.5f +
615 node->getJointLimitLow();
620 Eigen::VectorXf jointCompensationDeltas(desiredJointValues.rows());
622 for (
unsigned int i = 0; i < desiredJointValues.rows(); i++)
624 VirtualRobot::RobotNodePtr node = nodes.at(i);
625 actualJointValues(i) = node->getJointValue();
626 jointCompensationDeltas(i) = (node->getJointValue() - desiredJointValues(i)) /
627 (node->getJointLimitHigh() - node->getJointLimitLow());
628 jointCompensationDeltas(i) =
629 -pow(jointCompensationDeltas(i), 3) * pow(nodes.size() - i, 2);
639 const Eigen::MatrixXf& jacobian,
640 const Eigen::MatrixXf& jacobianInverse)
642 Eigen::MatrixXf I(jacobianInverse.rows(), jacobian.cols());
645 Eigen::MatrixXf nullspaceProjection = I - jacobianInverse * jacobian;
647 Eigen::VectorXf delta = nullspaceProjection * desiredJointDeltas;
652 TCPControlUnit::applyMaxJointVelocity(
const Eigen::VectorXf& jointVelocity,
653 float maxJointVelocity)
657 for (
unsigned int i = 0; i < jointVelocity.rows(); i++)
660 std::max(
static_cast<double>(
std::abs(jointVelocity(i))), currentMaxJointVel);
663 if (currentMaxJointVel > maxJointVelocity)
666 <<
"max joint velocity too high: " << currentMaxJointVel
667 <<
" allowed: " << maxJointVelocity;
668 return jointVelocity * (maxJointVelocity / currentMaxJointVel);
672 return jointVelocity;
684 RobotNodePtr coordSystem,
685 JacobiProvider::InverseJacobiMethod invJacMethod) :
686 DifferentialIK(rns, coordSystem, invJacMethod)
698 size_t nDoF = nodes.size();
700 using namespace Eigen;
701 MatrixXf Jacobian(nRows, nDoF);
705 for (
size_t i = 0; i < tcp_set.size(); i++)
709 if (this->targets.find(tcp) != this->targets.end())
712 MatrixXf partJacobian = this->getJacobianMatrix(tcp, mode);
713 Jacobian.block(
index, 0, partJacobian.rows(), nDoF) = partJacobian;
729 tolerancePosition.clear();
730 toleranceRotation.clear();
738 this->coordSystem = coordSystem;
745 float tolerancePosition,
746 float toleranceRotation,
749 if (mode <= IKSolver::Z)
752 <<
"The tcpWeight vector must be of size 1";
757 <<
"The tcpWeight vector must be of size 3";
759 else if (mode == IKSolver::All)
762 <<
"The tcpWeight vector must be of size 6";
766 DifferentialIK::setGoal(goal, tcp, mode, tolerancePosition, toleranceRotation);
780 jointDelta, stepSize, mininumChange, maxNStep, &DifferentialIK::computeStep);
796 VR_ASSERT(nodes.size() == rns->getSize());
800 std::vector<float> jv(nodes.size(), 0.0f);
801 std::vector<float> jvBest = rns->getJointValues();
805 std::vector<std::pair<float, VectorXf>> jointDeltaIterations;
806 float lastDist = FLT_MAX;
807 VectorXf oldJointValues;
808 rns->getJointValues(oldJointValues);
811 resultJointDelta.resize(nodes.size());
812 resultJointDelta.setZero();
816 VectorXf dTheta = (this->*computeFunction)(stepSize);
824 for (
unsigned int i = 0; i < nodes.size(); i++)
827 jv[i] = (nodes[i]->getJointValue() + dTheta[i]);
829 if (std::isnan(jv[i]) || std::isinf(jv[i]))
839 robot->setJointValues(rns, jv);
841 VectorXf newJointValues;
842 rns->getJointValues(newJointValues);
843 resultJointDelta = newJointValues - oldJointValues;
849 if (checkTolerances())
859 float d = dTheta.norm();
860 float posDist = getMeanErrorPosition();
861 float oriErr = getErrorRotation(rns->getTCP());
863 if (dTheta.norm() < mininumChange)
867 <<
"Could not improve result any more (dTheta.norm()=" << d
868 <<
"), loop:" << step <<
" Resulting error: pos " << posDist
869 <<
" orientation: " << oriErr << std::endl;
873 if (checkImprovement && posDist > lastDist)
877 <<
"Could not improve result any more (current position error="
878 << posDist <<
", last loop's error:" << lastDist <<
"), loop:" << step
880 robot->setJointValues(rns, jvBest);
888 jointDeltaIterations.push_back(std::make_pair(
getWeightedError(), resultJointDelta));
889 }
while (step < maxNStep);
894 for (
unsigned int i = 0; i < jointDeltaIterations.size(); i++)
896 if (jointDeltaIterations.at(i).first < bestJVError)
898 bestJVError = jointDeltaIterations.at(i).first;
899 resultJointDelta = jointDeltaIterations.at(i).second;
903 robot->setJointValues(rns, oldJointValues + resultJointDelta);
913 if (step >= maxNStep && verbose)
934 size_t nDoF = nodes.size();
936 MatrixXf Jacobian(nRows, nDoF);
937 VectorXf error(nRows);
940 for (
size_t i = 0; i < tcp_set.size(); i++)
944 if (this->targets.find(tcp) != this->targets.end())
946 Eigen::VectorXf delta = getDeltaToGoal(tcp);
949 MatrixXf partJacobian = this->getJacobianMatrix(tcp, mode);
952 Jacobian.block(
index, 0, partJacobian.rows(), nDoF) = partJacobian;
953 Vector3f position = delta.head(3);
954 position *= stepSize;
956 if (mode & IKSolver::X)
958 error(
index) = position(0);
962 if (mode & IKSolver::Y)
964 error(
index) = position(1);
968 if (mode & IKSolver::Z)
970 error(
index) = position(2);
976 error.segment(
index, 3) = delta.tail(3) * stepSize;
988 MatrixXf pseudo = computePseudoInverseJacobianMatrix(Jacobian);
991 return pseudo * error;
1002 size_t nDoF = nodes.size();
1004 std::map<float, MatrixXf> partJacobians;
1006 VectorXf thetaSum(nDoF);
1010 for (
size_t i = 0; i < tcp_set.size(); i++)
1014 if (this->targets.find(tcp) != this->targets.end())
1016 Eigen::VectorXf delta = getDeltaToGoal(tcp);
1018 MatrixXf partJacobian = this->getJacobianMatrix(tcp, mode);
1024 if (mode <= IKSolver::Z)
1032 else if (mode == IKSolver::All)
1038 VectorXf partError(tcpDOF);
1039 Vector3f position = delta.head(3);
1041 position *= stepSize;
1043 if (mode & IKSolver::X)
1045 partError(
index) = position(0);
1049 if (mode & IKSolver::Y)
1051 partError(
index) = position(1);
1055 if (mode & IKSolver::Z)
1057 partError(
index) = position(2);
1063 partError.segment(
index, 3) = delta.tail(3) * stepSize;
1075 MatrixXf pseudo = computePseudoInverseJacobianMatrix(partJacobian);
1078 std::map<VirtualRobot::SceneObjectPtr, Eigen::VectorXf>::iterator it =
1090 if (mode <= IKSolver::Z)
1098 else if (mode == IKSolver::All)
1103 Eigen::VectorXf tmptcpWeightVec(size);
1104 tmptcpWeightVec.setOnes();
1113 weightMat.setIdentity();
1117 pseudo = pseudo * weightMat;
1123 <<
"Wrong dimension of tcp weights: " <<
tcpWeightVec.rows()
1124 <<
", but should be: " << pseudo.cols();
1128 thetaSum += pseudo * partError;
1143 bool useAlternativeOnFail)
1145 Eigen::VectorXf jointValuesBefore;
1146 rns->getJointValues(jointValuesBefore);
1147 Eigen::VectorXf resultJointDelta;
1148 Eigen::VectorXf jointDeltaAlternative;
1149 bool result =
computeSteps(resultJointDelta, stepSize, minChange, maxSteps);
1152 if (useAlternativeOnFail && error > 5)
1163 resultJointDelta = jointDeltaAlternative;
1175 weightMat.setIdentity();
1179 Jacobian = Jacobian * weightMat;
1188 std::map<VirtualRobot::SceneObjectPtr, Eigen::VectorXf>::iterator it =
tcpWeights.find(tcp);
1198 weightMat.setIdentity();
1201 partJacobian = weightMat * partJacobian;
1207 <<
"Wrong dimension of tcp weights: " <<
tcpWeightVec.rows()
1208 <<
", but should be: " << partJacobian.rows();
1217 for (
size_t i = 0; i < tcp_set.size(); i++)
1219 std::map<VirtualRobot::SceneObjectPtr, Eigen::VectorXf>::iterator it =
1224 Eigen::VectorXf& tmptcpWeightVec = it->second;
1228 if (oldVec.rows() > 0)
1233 tcpWeightVec.tail(tmptcpWeightVec.rows()) = tmptcpWeightVec;
1240 if (mode <= IKSolver::Z)
1248 else if (mode == IKSolver::All)
1256 if (oldVec.rows() > 0)
1261 Eigen::VectorXf tmptcpWeightVec(size);
1262 tmptcpWeightVec.setOnes();
1271 weightMat.setIdentity();
1275 invJacobian = invJacobian * weightMat;
1281 <<
"Wrong dimension of tcp weights: " <<
tcpWeightVec.rows()
1282 <<
", but should be: " << invJacobian.cols();
1289 float result = 0.0f;
1290 float positionOrientationRatio = 3.f / 180.f *
M_PI;
1292 for (
size_t i = 0; i < tcp_set.size(); i++)
1312 tcp = getDefaultTCP();
1315 Vector3f position = targets[tcp].block(0, 3, 3, 1) - tcp->getGlobalPose().block(0, 3, 3, 1);
1318 float result = 0.0f;
1319 Eigen::VectorXf tcpWeight(3);
1327 tcpWeight.setOnes();
1330 int weightIndex = 0;
1332 if (modes[tcp] & IKSolver::X)
1335 result += position(0) * position(0) * tcpWeight(weightIndex++);
1338 if (modes[tcp] & IKSolver::Y)
1341 result += position(1) * position(1) * tcpWeight(weightIndex++);
1344 if (modes[tcp] & IKSolver::Z)
1347 result += position(2) * position(2) * tcpWeight(weightIndex++);
1350 return sqrtf(result);
1356 if (
dofWeights.rows() != plannedJointDeltas.rows())
1358 dofWeights.resize(plannedJointDeltas.rows());
1362 bool result =
false;
1364 for (
unsigned int i = 0; i < nodes.size(); i++)
1366 float angle = nodes[i]->getJointValue() + plannedJointDeltas[i] * 0.1;
1368 if (
angle > nodes[i]->getJointLimitHi() ||
angle < nodes[i]->getJointLimitLo())
1371 <<
" joint deactivated because of joint limit";
1387 const Ice::Current&)
1395 const Ice::Current&)
1397 std::unique_lock lock(reportMutex);
1399 std::string rootFrame = localReportRobot->getRootNode()->getName();
1408 tempMap.erase(
"timestamp");
1409 localReportRobot->setJointValues(tempMap);
1411 for (
unsigned int i = 0; i < nodesToReport.size(); i++)
1413 RobotNodePtr& node = nodesToReport.at(i);
1414 const std::string& tcpName = node->getName();
1416 tcpPoses[tcpName] =
new FramedPose(currentPose, rootFrame, robotName);
1419 listener->reportTCPPose(tcpPoses);
1426 const Ice::Current&)
1434 std::unique_lock lock(reportMutex);
1436 if (!localVelReportRobot)
1438 localVelReportRobot = localReportRobot->clone(robotName);
1442 FramedDirectionMap tcpTranslationVelocities;
1443 FramedDirectionMap tcpOrientationVelocities;
1444 std::string rootFrame = localReportRobot->getRootNode()->getName();
1445 NameValueMap tempJointAngles = localReportRobot->getConfig()->getRobotNodeJointValueMap();
1448 for (
unsigned int i = 0; i < nodesToReport.size(); i++)
1450 RobotNodePtr node = nodesToReport.at(i);
1451 const std::string& tcpName = node->getName();
1453 tcpPoses[tcpName] =
new FramedPose(currentPose, rootFrame, robotName);
1456 double tDelta = 0.001;
1458 for (NameValueMap::iterator it = tempJointAngles.begin(); it != tempJointAngles.end(); it++)
1460 NameValueMap::const_iterator itSrc = jointVel.find(it->first);
1461 if (itSrc != jointVel.end())
1463 if (itSrc->first ==
"timestamp")
1467 it->second += itSrc->second * tDelta;
1471 localVelReportRobot->setJointValues(tempJointAngles);
1473 for (
unsigned int i = 0; i < nodesToReport.size(); i++)
1475 RobotNodePtr node = localVelReportRobot->getRobotNode(nodesToReport.at(i)->getName());
1476 const std::string& tcpName = node->getName();
1480 FramedPosePtr lastPose = FramedPosePtr::dynamicCast(tcpPoses[tcpName]);
1483 (currentPose.block(0, 3, 3, 1) - lastPose->toEigen().block(0, 3, 3, 1)) / tDelta,
1485 localReportRobot->getName());
1487 const Eigen::Matrix4f mat = currentPose * lastPose->toEigen().inverse();
1489 Eigen::Vector3f rpy;
1490 VirtualRobot::MathTools::eigen4f2rpy(mat, rpy);
1493 tcpOrientationVelocities[tcpName] =
new FramedDirection(rpy / tDelta, rootFrame, robotName);
1496 listener->reportTCPVelocities(tcpTranslationVelocities, tcpOrientationVelocities);
1503 const Ice::Current&)
1511 const Ice::Current&
c)
1519 const Ice::Current&)
1527 const Ice::Current&)
1535 const Ice::Current&)