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";