26 #include <VirtualRobot/MathTools.h> 
   34 using namespace CoupledInteractionGroup;
 
   37 CalculateForceControlRobotPose::SubClassRegistry
 
   53         getContext<CoupledInteractionGroupStatechartContext>();
 
   55     std::vector<Vector3Ptr> platformVelMeanFilter;
 
   57     if (local.isPlatformVelMeanFilterSet())
 
   59         platformVelMeanFilter = local.getPlatformVelMeanFilter();
 
   65     std::string leftTcpName = in.getLeftHandName();
 
   66     std::string rightTcpName = in.getRightHandName();
 
   71     duration = now - in.getCurrentTimestamp()->toTime();
 
   72     int counter = in.getcounter();
 
   75     FramedPosePtr desiredLeftTcpPose = in.getDesiredLeftTcpPose();
 
   76     FramedPosePtr desiredRightTcpPose = in.getDesiredRightTcpPose();
 
   77     float leftForceAmplifier = 2.0;
 
   78     float rightForceAmplifier = 1.2;
 
   79     float forceThreshold = in.getForceThreshhold();
 
   80     float desiredDistance = (desiredLeftTcpPose->toEigen() - desiredRightTcpPose->toEigen()).
norm();
 
   81     float accGain = 120.0;
 
   83     float maxVelocity = 50.0;
 
   84     float torqueThreshold = in.getTorqueThreshhold();
 
   85     float oriAccGain = 4.0;
 
   86     float oriDccGain = 1.0;
 
   87     float maxOriAcc = 1.0;
 
   88     float maxOriVelocity = 0.1;
 
   89     float stiffness = 0.5 * accGain;
 
   90     float damping = 1.0 / (2.0 * 
sqrt(stiffness));
 
   92     if (torqueThreshold == 0.0)
 
   97     if (forceThreshold == 0.0)
 
  105         context->
getRobot()->getRobotNode(in.getLeftHandName())->getPoseInRootFrame();
 
  107         context->
getRobot()->getRobotNode(in.getRightHandName())->getPoseInRootFrame();
 
  109     Eigen::Vector3f currentLeftRPY;
 
  110     VirtualRobot::MathTools::eigen4f2rpy(leftTcpPoseBase, currentLeftRPY);
 
  111     Eigen::Vector3f currentRightRPY;
 
  112     VirtualRobot::MathTools::eigen4f2rpy(rightTcpPoseBase, currentRightRPY);
 
  115     Eigen::Matrix4f deltaLeftTcpPose = desiredLeftTcpPose->toEigen() * leftTcpPoseBase.inverse();
 
  116     Eigen::Matrix4f deltaRightTcpPose = desiredRightTcpPose->toEigen() * rightTcpPoseBase.inverse();
 
  118     Eigen::Vector3f deltaLeftRPY;
 
  119     VirtualRobot::MathTools::eigen4f2rpy(deltaLeftTcpPose, deltaLeftRPY);
 
  120     Eigen::Vector3f deltaRightRPY;
 
  121     VirtualRobot::MathTools::eigen4f2rpy(deltaRightTcpPose, deltaRightRPY);
 
  157     ARMARX_INFO << 
"Measuring forces in frame: " << curForceLeft->frame;
 
  158     Eigen::Vector3f newVelLeft(3);
 
  159     Eigen::Vector3f newAccLeft(3);
 
  160     Eigen::Vector3f newVelRight(3);
 
  161     Eigen::Vector3f newAccRight(3);
 
  162     Eigen::Vector3f curForceRightVec = curForceRight->
toEigen();
 
  163     Eigen::Vector3f curForceLeftVec = curForceLeft->
toEigen();
 
  164     Eigen::Vector3f curTorqueRightVec = curTorqueRight->
toEigen();
 
  165     Eigen::Vector3f curTorqueLeftVec = curTorqueLeft->
toEigen();
 
  166     ARMARX_INFO << 
"current Force right hand " << curForceRightVec(0) << 
" " << curForceRightVec(1)
 
  167                 << 
" " << curForceRightVec(2);
 
  169     curForceRightVec = curForceRightVec * rightForceAmplifier;
 
  170     curForceLeftVec = curForceLeftVec * leftForceAmplifier;
 
  172     ARMARX_INFO << 
"current Force right hand wo init " << curForceRightVec(0) << 
" " 
  173                 << curForceRightVec(1) << 
" " << curForceRightVec(2);
 
  174     ARMARX_INFO << 
"current Force left hand wo init " << curForceLeftVec(0) << 
" " 
  175                 << curForceLeftVec(1) << 
" " << curForceLeftVec(2);
 
  192     out.setcounter(counter);
 
  195     curForceRightVec(1) = 2 * curForceRightVec(1);
 
  196     curForceLeftVec(1) = 2 * curForceLeftVec(1);
 
  198     curForceRightVec(2) = 0.0; 
 
  199     curForceLeftVec(2) = 0.0; 
 
  200     Eigen::Vector3f leftToRightVec;
 
  201     leftToRightVec(0) = rightTcpPoseBase(0, 3) - leftTcpPoseBase(0, 3);
 
  202     leftToRightVec(1) = rightTcpPoseBase(1, 3) - leftTcpPoseBase(1, 3);
 
  203     leftToRightVec(2) = rightTcpPoseBase(2, 3) - leftTcpPoseBase(2, 3);
 
  204     Eigen::Vector3f forceLeftToRightVec;
 
  205     forceLeftToRightVec(0) = 2.0 * forceThreshold + curForceRightVec(0) - curForceLeftVec(0);
 
  206     forceLeftToRightVec(1) = curForceRightVec(1) - curForceLeftVec(1);
 
  207     forceLeftToRightVec(2) = 0.0; 
 
  208     Eigen::Vector3f meanForceVec = 0.5 * (curForceLeftVec + curForceRightVec);
 
  209     Eigen::Vector3f platformAccVec;
 
  210     Eigen::Vector3f curPlatformVel = in.getCurrentPlatformVelocity()->toEigen();
 
  211     bool useCurrentVel = 
false;
 
  212     Eigen::Vector3f meanForceVec2 = meanForceVec;
 
  213     meanForceVec2(2) = 0;
 
  215     if (meanForceVec2.norm() <
 
  221         if (curPlatformVel.norm() > 0)
 
  224                 -0.5 * curPlatformVel(0) / (duration.toMilliSecondsDouble() * 0.001);
 
  226                 -0.5 * curPlatformVel(1) / (duration.toMilliSecondsDouble() * 0.001);
 
  228                 -0.5 * curPlatformVel(2) / (duration.toMilliSecondsDouble() * 0.001);
 
  229             useCurrentVel = 
true;
 
  233             platformAccVec(0) = 0.0;
 
  234             platformAccVec(1) = 0.0;
 
  235             platformAccVec(2) = 0.0;
 
  238         if (!in.getinitialForcesReset())
 
  246         out.setinitialForcesReset(
true);
 
  251         ARMARX_INFO << 
"forceLeftToRightVec " << forceThreshold << 
" " << forceLeftToRightVec(0)
 
  252                     << 
" " << forceLeftToRightVec(1) << 
" " << forceLeftToRightVec(2);
 
  255                                   std::sqrt(forceLeftToRightVec(0) * forceLeftToRightVec(0) +
 
  256                                             forceLeftToRightVec(1) * forceLeftToRightVec(1)),
 
  261                                   std::sqrt(forceLeftToRightVec(0) * forceLeftToRightVec(0) +
 
  262                                             forceLeftToRightVec(1) * forceLeftToRightVec(1)),
 
  265         float angle = acos(xangle);
 
  267         if (acos(yangle) > 0.5 * 
M_PI)
 
  272         float forceAccGain = 1.0; 
 
  274         platformAccVec(0) = meanForceVec(0) * forceAccGain * accGain;
 
  275         platformAccVec(1) = meanForceVec(1) * forceAccGain * accGain;
 
  276         platformAccVec(2) = 
angle * forceAccGain * oriAccGain;
 
  278         out.setinitialForcesReset(
false);
 
  281     Eigen::Vector3f platformVelVec = platformAccVec * duration.toMilliSecondsDouble() * 0.001;
 
  285         platformVelVec += curPlatformVel;
 
  290     float velForceGain = 1.0; 
 
  292     curForceLeftVec = curForceLeftVec - velForceGain * meanForceVec;
 
  293     curForceRightVec = curForceRightVec - velForceGain * meanForceVec;
 
  297     stiffness = 1.5 * accGain;
 
  298     damping = (2.0 * 
sqrt(stiffness));
 
  299     Eigen::Vector3f centerForceLeftVec;
 
  300     centerForceLeftVec(0) =
 
  301         stiffness * ((desiredLeftTcpPose->toEigen())(0, 3) - leftTcpPoseBase(0, 3)) -
 
  302         damping * curVelLeft->x;
 
  303     centerForceLeftVec(1) =
 
  304         stiffness * ((desiredLeftTcpPose->toEigen())(1, 3) - leftTcpPoseBase(1, 3)) -
 
  305         damping * curVelLeft->y;
 
  306     centerForceLeftVec(2) =
 
  307         stiffness * ((desiredLeftTcpPose->toEigen())(2, 3) - leftTcpPoseBase(2, 3)) -
 
  308         damping * curVelLeft->z;
 
  311     Eigen::Vector3f centerForceRightVec;
 
  312     centerForceRightVec(0) =
 
  313         stiffness * ((desiredRightTcpPose->toEigen())(0, 3) - rightTcpPoseBase(0, 3)) -
 
  314         damping * curVelRight->x; 
 
  315     centerForceRightVec(1) =
 
  316         stiffness * ((desiredRightTcpPose->toEigen())(1, 3) - rightTcpPoseBase(1, 3)) -
 
  317         damping * curVelRight->y;
 
  318     centerForceRightVec(2) =
 
  319         stiffness * ((desiredRightTcpPose->toEigen())(2, 3) - rightTcpPoseBase(2, 3)) -
 
  320         damping * curVelRight->z; 
 
  325     damping = (2.0 * 
sqrt(stiffness));
 
  326     Eigen::Vector3f coupledForceLeftVec;
 
  327     coupledForceLeftVec(0) = stiffness * ((leftToRightVec(0) / leftToRightVec.norm()) *
 
  328                                           (leftToRightVec.norm() - desiredDistance)) -
 
  329                              damping * curVelLeft->x;
 
  331     coupledForceLeftVec(1) =
 
  332         stiffness * ((leftToRightVec(0) / leftToRightVec.norm()) *
 
  333                      (leftToRightVec.norm() - desiredDistance)) -
 
  334         damping * curVelLeft->y; 
 
  335     coupledForceLeftVec(2) =
 
  336         stiffness * ((leftToRightVec(0) / leftToRightVec.norm()) *
 
  337                      (leftToRightVec.norm() - desiredDistance)) -
 
  338         damping * curVelLeft->z; 
 
  340     Eigen::Vector3f coupledForceRightVec;
 
  342     coupledForceRightVec(0) = stiffness * ((-leftToRightVec(0) / leftToRightVec.norm()) *
 
  343                                            (leftToRightVec.norm() - desiredDistance)) -
 
  344                               damping * curVelRight->x;
 
  345     coupledForceRightVec(1) = stiffness * ((-leftToRightVec(1) / leftToRightVec.norm()) *
 
  346                                            (leftToRightVec.norm() - desiredDistance)) -
 
  347                               damping * curVelRight->y;
 
  349     coupledForceRightVec(2) = stiffness * ((-leftToRightVec(2) / leftToRightVec.norm()) *
 
  350                                            (leftToRightVec.norm() - desiredDistance)) -
 
  351                               damping * curVelRight->z;
 
  353     centerForceRightVec = centerForceRightVec + coupledForceRightVec;
 
  354     centerForceLeftVec = centerForceLeftVec + coupledForceLeftVec;
 
  356     ARMARX_INFO << 
"desired left tcp pose " << *desiredLeftTcpPose;
 
  357     ARMARX_INFO << 
"desired right tcp pose " << *desiredRightTcpPose;
 
  359     ARMARX_INFO << 
"Forces pulling TCP L to center " << centerForceLeftVec(0) << 
" " 
  360                 << centerForceLeftVec(1) << 
" " << centerForceLeftVec(2);
 
  361     ARMARX_INFO << 
"Forces pulling TCP R to center " << centerForceRightVec(0) << 
" " 
  362                 << centerForceRightVec(1) << 
" " << centerForceRightVec(2);
 
  363     ARMARX_INFO << 
"Forces acting on TCP L " << curForceLeftVec(0) * accGain << 
" " 
  364                 << curForceLeftVec(1) * accGain << 
" " << curForceLeftVec(2) * accGain;
 
  365     ARMARX_INFO << 
"Forces acting on TCP R " << curForceRightVec(0) * accGain << 
" " 
  366                 << curForceRightVec(1) * accGain << 
" " << curForceRightVec(2) * accGain;
 
  368     if (curForceLeftVec.norm() > forceThreshold)
 
  370         newAccLeft = curForceLeftVec * accGain + centerForceLeftVec;
 
  372     else if (curVelLeft->toEigen().norm() > 0)
 
  375         newAccLeft = -decGain * curVelLeft->toEigen().normalized() + centerForceLeftVec;
 
  379         newAccLeft = Eigen::Vector3f::Zero() + centerForceLeftVec;
 
  382     if (curForceRightVec.norm() > forceThreshold)
 
  384         newAccRight = curForceRightVec * accGain + centerForceRightVec;
 
  386     else if (curVelRight->toEigen().norm() > 0)
 
  389         newAccRight = -decGain * curVelRight->toEigen().normalized() + centerForceRightVec;
 
  393         newAccRight = Eigen::Vector3f::Zero() + centerForceRightVec;
 
  398     newVelLeft = curVelLeft->toEigen() + newAccLeft * duration.toMilliSecondsDouble() * 0.001;
 
  400     if (newVelLeft.norm() > maxVelocity)
 
  402         newVelLeft = newVelLeft.normalized() * maxVelocity;
 
  405     newVelRight = curVelRight->toEigen() + newAccRight * duration.toMilliSecondsDouble() * 0.001;
 
  407     if (newVelRight.norm() > maxVelocity)
 
  409         newVelRight = newVelRight.normalized() * maxVelocity;
 
  413     Eigen::Vector3f newOriVelLeft(3);
 
  414     Eigen::Vector3f newOriAccLeft(3);
 
  417     if (curTorqueLeftVec.norm() > torqueThreshold)
 
  419         newOriAccLeft = curTorqueLeftVec * oriAccGain;
 
  421     else if (curVelOriLeft->toEigen().norm() > 0)
 
  424         newOriAccLeft = -oriDccGain * curVelOriLeft->toEigen().normalized();
 
  428         newOriAccLeft = Eigen::Vector3f::Zero();
 
  433     Eigen::Vector3f velOriLeftDelta = newOriAccLeft * duration.toMilliSecondsDouble() * 0.001;
 
  435     if (velOriLeftDelta.norm() > maxOriAcc)
 
  437         velOriLeftDelta = velOriLeftDelta.normalized() * maxOriAcc;
 
  440     newOriVelLeft = curVelOriLeft->toEigen() + velOriLeftDelta;
 
  442     if (newOriVelLeft.norm() > maxOriVelocity)
 
  444         newOriVelLeft = newOriVelLeft.normalized() * maxOriVelocity;
 
  454     Eigen::Vector3f newOriVelRight(3);
 
  455     Eigen::Vector3f newOriAccRight(3);
 
  457     if (curTorqueRightVec.norm() > torqueThreshold)
 
  460         newOriAccRight = curTorqueRightVec * oriAccGain;
 
  462     else if (curVelOriRight->toEigen().norm() > 0)
 
  465         newOriAccRight = -oriDccGain * curVelOriRight->toEigen().normalized();
 
  469         newOriAccRight = Eigen::Vector3f::Zero();
 
  472     ARMARX_INFO << 
"New Ori Acc Right " << newOriAccRight(0) << 
" " << newOriAccRight(1) << 
" " 
  473                 << newOriAccRight(2);
 
  476     Eigen::Vector3f velOriRightDelta = newOriAccRight * duration.toMilliSecondsDouble() * 0.001;
 
  478     if (velOriRightDelta.norm() > maxOriAcc)
 
  480         velOriRightDelta = velOriRightDelta.normalized() * maxOriAcc;
 
  483     newOriVelRight = curVelOriRight->toEigen() + velOriRightDelta;
 
  485     if (newOriVelRight.norm() > maxOriVelocity)
 
  487         newOriVelRight = newOriVelRight.normalized() * maxOriVelocity;
 
  490     ARMARX_INFO << 
"New Ori Vel Right " << newOriVelRight(0) << 
" " << newOriVelRight(1) << 
" " 
  491                 << newOriVelRight(2);
 
  495     float maxVelocityTrans = 60.0;
 
  496     float maxVelocityRot = 0.2;
 
  501     assert(kernelSize >= 0);
 
  502     if (platformVelMeanFilter.size() == 
static_cast<std::size_t
>(kernelSize))
 
  504         platformVelMeanFilter.erase(platformVelMeanFilter.begin(),
 
  505                                     platformVelMeanFilter.begin() + 1);
 
  508     platformVelMeanFilter.push_back(platformVelPtr);
 
  514     for (std::size_t i = 0; i < platformVelMeanFilter.size(); i++)
 
  531         sin(
platformVelocity.z), cos(
platformVelocity.z), 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0,
 
  533     Eigen::Vector4f temp;
 
  535     for (
int i = 0; i < 3; i++)
 
  537         temp(i) = newVelLeft(i);
 
  541     temp = platformTransformation.inverse() * temp;
 
  543     for (
int i = 0; i < 3; i++)
 
  545         newVelLeft(i) = temp(i);
 
  548     for (
int i = 0; i < 3; i++)
 
  550         temp(i) = newOriVelLeft(i);
 
  554     temp = platformTransformation.inverse() * temp;
 
  556     for (
int i = 0; i < 3; i++)
 
  564     for (
int i = 0; i < 3; i++)
 
  566         temp(i) = newVelRight(i);
 
  570     temp = platformTransformation.inverse() * temp;
 
  572     for (
int i = 0; i < 3; i++)
 
  574         newVelRight(i) = temp(i);
 
  577     for (
int i = 0; i < 3; i++)
 
  579         temp(i) = newOriVelRight(i);
 
  583     temp = platformTransformation.inverse() * temp;
 
  585     for (
int i = 0; i < 3; i++)
 
  593     ARMARX_INFO << 
"New Vel right pos " << newVelRight(0) << 
" " << newVelRight(1) << 
" " 
  595     ARMARX_INFO << 
"New Vel right ori " << newOriVelRight(0) << 
" " << newOriVelRight(1) << 
" " 
  596                 << newOriVelRight(2);
 
  597     ARMARX_INFO << 
"New Vel right pos " << newVelRight(0) << 
" " << newVelRight(1) << 
" " 
  599     ARMARX_INFO << 
"New Vel left ori " << newOriVelLeft(0) << 
" " << newOriVelLeft(1) << 
" " 
  602     VirtualRobot::MathTools::rpy2eigen4f(in.getDesiredLeftTcpOrientation()->toEigen()(0),
 
  603                                          in.getDesiredLeftTcpOrientation()->toEigen()(1),
 
  604                                          in.getDesiredLeftTcpOrientation()->toEigen()(2),
 
  606     targetLeft(0, 3) = leftTcpPoseBase(0, 3);
 
  607     targetLeft(1, 3) = leftTcpPoseBase(1, 3);
 
  608     targetLeft(2, 3) = leftTcpPoseBase(2, 3);
 
  610     VirtualRobot::MathTools::rpy2eigen4f(in.getDesiredRightTcpOrientation()->toEigen()(0),
 
  611                                          in.getDesiredRightTcpOrientation()->toEigen()(1),
 
  612                                          in.getDesiredRightTcpOrientation()->toEigen()(2),
 
  614     targetright(0, 3) = rightTcpPoseBase(0, 3);
 
  615     targetright(1, 3) = rightTcpPoseBase(1, 3);
 
  616     targetright(2, 3) = rightTcpPoseBase(2, 3);
 
  617     ARMARX_INFO << 
"target RPY right " << currentRightRPY(0) << 
" " << currentRightRPY(1) << 
" " 
  618                 << currentRightRPY(2);
 
  619     ARMARX_INFO << 
"target RPY left " << currentLeftRPY(0) << 
" " << currentLeftRPY(1) << 
" " 
  620                 << currentLeftRPY(2);
 
  621     ARMARX_INFO << 
"target RPY right " << (in.getDesiredRightTcpOrientation()->toEigen())(0) << 
" " 
  622                 << (in.getDesiredRightTcpOrientation()->toEigen())(1) << 
" " 
  623                 << (in.getDesiredRightTcpOrientation()->toEigen())(2);
 
  624     ARMARX_INFO << 
"target RPY left " << (in.getDesiredLeftTcpOrientation()->toEigen())(0) << 
" " 
  625                 << (in.getDesiredLeftTcpOrientation()->toEigen())(1) << 
" " 
  626                 << (in.getDesiredLeftTcpOrientation()->toEigen())(2);
 
  628     debugDrawer->setPoseVisu(
 
  632     debugDrawer->setPoseVisu(
 
  636     debugDrawer->setPoseVisu(
 
  640     debugDrawer->setPoseVisu(
 
  648     out.setLeftTcpTargetPosVelocity(
 
  649         new FramedDirection(newVelLeft, curVelLeft->frame, curVelLeft->agent));
 
  650     out.setLeftTcpTargetOriVelocity(
new FramedDirection(newOriVelLeft, 
"Armar3_Base", 
"Armar3"));
 
  651     out.setRightTcpTargetPosVelocity(
 
  652         new FramedDirection(newVelRight, curVelRight->frame, curVelRight->agent));
 
  653     out.setRightTcpTargetOriVelocity(
new FramedDirection(newOriVelRight, 
"Armar3_Base", 
"Armar3"));
 
  658     local.setPlatformVelMeanFilter(platformVelMeanFilter);
 
  667     bool noChange = 
false;
 
  703     return "CalculateForceControlRobotPose";