31 using namespace CoupledInteractionGroup;
49 std::vector<Vector3Ptr> platformVelMeanFilter;
51 if (local.isPlatformVelMeanFilterSet())
53 platformVelMeanFilter = local.getPlatformVelMeanFilter();
59 std::string leftTcpName = in.getLeftHandName();
60 std::string rightTcpName = in.getRightHandName();
65 duration = now - in.getCurrentTimestamp()->toTime();
66 int counter = in.getcounter();
69 FramedPosePtr desiredLeftTcpPose = in.getDesiredLeftTcpPose();
70 FramedPosePtr desiredRightTcpPose = in.getDesiredRightTcpPose();
71 float leftForceAmplifier = 2.0;
72 float rightForceAmplifier = 1.2;
73 float forceThreshold = in.getForceThreshhold();
74 float desiredDistance = (desiredLeftTcpPose->toEigen() - desiredRightTcpPose->toEigen()).
norm();
75 float accGain = 120.0;
77 float maxVelocity = 50.0;
78 float torqueThreshold = in.getTorqueThreshhold();
79 float oriAccGain = 4.0;
80 float oriDccGain = 1.0;
81 float maxOriAcc = 1.0;
82 float maxOriVelocity = 0.1;
83 float stiffness = 0.5 * accGain;
84 float damping = 1.0 / (2.0 *
sqrt(stiffness));
86 if (torqueThreshold == 0.0)
91 if (forceThreshold == 0.0)
98 Eigen::Matrix4f leftTcpPoseBase = context->
getRobot()->getRobotNode(in.getLeftHandName())->getPoseInRootFrame();
99 Eigen::Matrix4f rightTcpPoseBase = context->
getRobot()->getRobotNode(in.getRightHandName())->getPoseInRootFrame();
101 Eigen::Vector3f currentLeftRPY;
102 VirtualRobot::MathTools::eigen4f2rpy(leftTcpPoseBase, currentLeftRPY);
103 Eigen::Vector3f currentRightRPY;
104 VirtualRobot::MathTools::eigen4f2rpy(rightTcpPoseBase, currentRightRPY);
108 Eigen::Matrix4f deltaLeftTcpPose = desiredLeftTcpPose->toEigen() * leftTcpPoseBase.inverse();
109 Eigen::Matrix4f deltaRightTcpPose = desiredRightTcpPose->toEigen() * rightTcpPoseBase.inverse();
111 Eigen::Vector3f deltaLeftRPY;
112 VirtualRobot::MathTools::eigen4f2rpy(deltaLeftTcpPose, deltaLeftRPY);
113 Eigen::Vector3f deltaRightRPY;
114 VirtualRobot::MathTools::eigen4f2rpy(deltaRightTcpPose, deltaRightRPY);
141 ARMARX_INFO <<
"Measuring forces in frame: " << curForceLeft->frame;
142 Eigen::Vector3f newVelLeft(3);
143 Eigen::Vector3f newAccLeft(3);
144 Eigen::Vector3f newVelRight(3);
145 Eigen::Vector3f newAccRight(3);
146 Eigen::Vector3f curForceRightVec = curForceRight->
toEigen();
147 Eigen::Vector3f curForceLeftVec = curForceLeft->
toEigen();
148 Eigen::Vector3f curTorqueRightVec = curTorqueRight->
toEigen();
149 Eigen::Vector3f curTorqueLeftVec = curTorqueLeft->
toEigen();
150 ARMARX_INFO <<
"current Force right hand " << curForceRightVec(0) <<
" " << curForceRightVec(1) <<
" " << curForceRightVec(2);
152 curForceRightVec = curForceRightVec * rightForceAmplifier;
153 curForceLeftVec = curForceLeftVec * leftForceAmplifier;
155 ARMARX_INFO <<
"current Force right hand wo init " << curForceRightVec(0) <<
" " << curForceRightVec(1) <<
" " << curForceRightVec(2);
156 ARMARX_INFO <<
"current Force left hand wo init " << curForceLeftVec(0) <<
" " << curForceLeftVec(1) <<
" " << curForceLeftVec(2);
173 out.setcounter(counter);
176 curForceRightVec(1) = 2 * curForceRightVec(1);
177 curForceLeftVec(1) = 2 * curForceLeftVec(1);
179 curForceRightVec(2) = 0.0;
180 curForceLeftVec(2) = 0.0;
181 Eigen::Vector3f leftToRightVec;
182 leftToRightVec(0) = rightTcpPoseBase(0, 3) - leftTcpPoseBase(0, 3);
183 leftToRightVec(1) = rightTcpPoseBase(1, 3) - leftTcpPoseBase(1, 3);
184 leftToRightVec(2) = rightTcpPoseBase(2, 3) - leftTcpPoseBase(2, 3);
185 Eigen::Vector3f forceLeftToRightVec;
186 forceLeftToRightVec(0) = 2.0 * forceThreshold + curForceRightVec(0) - curForceLeftVec(0);
187 forceLeftToRightVec(1) = curForceRightVec(1) - curForceLeftVec(1);
188 forceLeftToRightVec(2) = 0.0;
189 Eigen::Vector3f meanForceVec = 0.5 * (curForceLeftVec + curForceRightVec);
190 Eigen::Vector3f platformAccVec;
191 Eigen::Vector3f curPlatformVel = in.getCurrentPlatformVelocity()->toEigen();
192 bool useCurrentVel =
false;
193 Eigen::Vector3f meanForceVec2 = meanForceVec;
194 meanForceVec2(2) = 0;
196 if (meanForceVec2.norm() < forceThreshold)
201 if (curPlatformVel.norm() > 0)
203 platformAccVec(0) = -0.5 * curPlatformVel(0) / (duration.toMilliSecondsDouble() * 0.001);
204 platformAccVec(1) = -0.5 * curPlatformVel(1) / (duration.toMilliSecondsDouble() * 0.001);
205 platformAccVec(2) = -0.5 * curPlatformVel(2) / (duration.toMilliSecondsDouble() * 0.001);
206 useCurrentVel =
true;
210 platformAccVec(0) = 0.0;
211 platformAccVec(1) = 0.0;
212 platformAccVec(2) = 0.0;
216 if (!in.getinitialForcesReset())
224 out.setinitialForcesReset(
true);
230 ARMARX_INFO <<
"forceLeftToRightVec " << forceThreshold <<
" " << forceLeftToRightVec(0) <<
" " << forceLeftToRightVec(1) <<
" " << forceLeftToRightVec(2);
231 float xangle =
std::min(
std::max(forceLeftToRightVec(0) /
std::sqrt(forceLeftToRightVec(0) * forceLeftToRightVec(0) + forceLeftToRightVec(1) * forceLeftToRightVec(1)), -1.f), 1.f);
232 float yangle =
std::min(
std::max(forceLeftToRightVec(1) /
std::sqrt(forceLeftToRightVec(0) * forceLeftToRightVec(0) + forceLeftToRightVec(1) * forceLeftToRightVec(1)), -1.f), 1.f);
233 float angle = acos(xangle);
235 if (acos(yangle) > 0.5 *
M_PI)
240 float forceAccGain = 1.0;
242 platformAccVec(0) = meanForceVec(0) * forceAccGain * accGain;
243 platformAccVec(1) = meanForceVec(1) * forceAccGain * accGain;
244 platformAccVec(2) =
angle * forceAccGain * oriAccGain;
246 out.setinitialForcesReset(
false);
249 Eigen::Vector3f platformVelVec = platformAccVec * duration.toMilliSecondsDouble() * 0.001;
253 platformVelVec += curPlatformVel;
258 float velForceGain = 1.0;
260 curForceLeftVec = curForceLeftVec - velForceGain * meanForceVec;
261 curForceRightVec = curForceRightVec - velForceGain * meanForceVec;
265 stiffness = 1.5 * accGain;
266 damping = (2.0 *
sqrt(stiffness));
267 Eigen::Vector3f centerForceLeftVec;
268 centerForceLeftVec(0) = stiffness * ((desiredLeftTcpPose->toEigen())(0, 3) - leftTcpPoseBase(0, 3)) - damping * curVelLeft->x;
269 centerForceLeftVec(1) = stiffness * ((desiredLeftTcpPose->toEigen())(1, 3) - leftTcpPoseBase(1, 3)) - damping * curVelLeft->y;
270 centerForceLeftVec(2) = stiffness * ((desiredLeftTcpPose->toEigen())(2, 3) - leftTcpPoseBase(2, 3)) - damping * curVelLeft->z;
273 Eigen::Vector3f centerForceRightVec;
274 centerForceRightVec(0) = stiffness * ((desiredRightTcpPose->toEigen())(0, 3) - rightTcpPoseBase(0, 3)) - damping * curVelRight->x;
275 centerForceRightVec(1) = stiffness * ((desiredRightTcpPose->toEigen())(1, 3) - rightTcpPoseBase(1, 3)) - damping * curVelRight->y;
276 centerForceRightVec(2) = stiffness * ((desiredRightTcpPose->toEigen())(2, 3) - rightTcpPoseBase(2, 3)) - damping * curVelRight->z;
281 damping = (2.0 *
sqrt(stiffness));
282 Eigen::Vector3f coupledForceLeftVec;
283 coupledForceLeftVec(0) = stiffness * ((leftToRightVec(0) / leftToRightVec.norm()) * (leftToRightVec.norm() - desiredDistance)) - damping * curVelLeft->x;;
284 coupledForceLeftVec(1) = stiffness * ((leftToRightVec(0) / leftToRightVec.norm()) * (leftToRightVec.norm() - desiredDistance)) - damping * curVelLeft->y;
285 coupledForceLeftVec(2) = stiffness * ((leftToRightVec(0) / leftToRightVec.norm()) * (leftToRightVec.norm() - desiredDistance)) - damping * curVelLeft->z;
287 Eigen::Vector3f coupledForceRightVec;
289 coupledForceRightVec(0) = stiffness * ((-leftToRightVec(0) / leftToRightVec.norm()) * (leftToRightVec.norm() - desiredDistance)) - damping * curVelRight->x;
290 coupledForceRightVec(1) = stiffness * ((-leftToRightVec(1) / leftToRightVec.norm()) * (leftToRightVec.norm() - desiredDistance)) - damping * curVelRight->y;;
291 coupledForceRightVec(2) = stiffness * ((-leftToRightVec(2) / leftToRightVec.norm()) * (leftToRightVec.norm() - desiredDistance)) - damping * curVelRight->z;;
292 centerForceRightVec = centerForceRightVec + coupledForceRightVec;
293 centerForceLeftVec = centerForceLeftVec + coupledForceLeftVec;
295 ARMARX_INFO <<
"desired left tcp pose " << *desiredLeftTcpPose;
296 ARMARX_INFO <<
"desired right tcp pose " << *desiredRightTcpPose;
298 ARMARX_INFO <<
"Forces pulling TCP L to center " << centerForceLeftVec(0) <<
" " << centerForceLeftVec(1) <<
" " << centerForceLeftVec(2);
299 ARMARX_INFO <<
"Forces pulling TCP R to center " << centerForceRightVec(0) <<
" " << centerForceRightVec(1) <<
" " << centerForceRightVec(2);
300 ARMARX_INFO <<
"Forces acting on TCP L " << curForceLeftVec(0) * accGain <<
" " << curForceLeftVec(1) * accGain <<
" " << curForceLeftVec(2) * accGain;
301 ARMARX_INFO <<
"Forces acting on TCP R " << curForceRightVec(0) * accGain <<
" " << curForceRightVec(1) * accGain <<
" " << curForceRightVec(2) * accGain;
303 if (curForceLeftVec.norm() > forceThreshold)
305 newAccLeft = curForceLeftVec * accGain + centerForceLeftVec;
307 else if (curVelLeft->toEigen().norm() > 0)
310 newAccLeft = -decGain * curVelLeft->toEigen().normalized() + centerForceLeftVec;
314 newAccLeft = Eigen::Vector3f::Zero() + centerForceLeftVec;
317 if (curForceRightVec.norm() > forceThreshold)
319 newAccRight = curForceRightVec * accGain + centerForceRightVec;
321 else if (curVelRight->toEigen().norm() > 0)
324 newAccRight = -decGain * curVelRight->toEigen().normalized() + centerForceRightVec;
328 newAccRight = Eigen::Vector3f::Zero() + centerForceRightVec;
333 newVelLeft = curVelLeft->toEigen() + newAccLeft * duration.toMilliSecondsDouble() * 0.001;
335 if (newVelLeft.norm() > maxVelocity)
337 newVelLeft = newVelLeft.normalized() * maxVelocity;
340 newVelRight = curVelRight->toEigen() + newAccRight * duration.toMilliSecondsDouble() * 0.001;
342 if (newVelRight.norm() > maxVelocity)
344 newVelRight = newVelRight.normalized() * maxVelocity;
348 Eigen::Vector3f newOriVelLeft(3);
349 Eigen::Vector3f newOriAccLeft(3);
352 if (curTorqueLeftVec.norm() > torqueThreshold)
354 newOriAccLeft = curTorqueLeftVec * oriAccGain;
356 else if (curVelOriLeft->toEigen().norm() > 0)
359 newOriAccLeft = -oriDccGain * curVelOriLeft->toEigen().normalized();
363 newOriAccLeft = Eigen::Vector3f::Zero();
368 Eigen::Vector3f velOriLeftDelta = newOriAccLeft * duration.toMilliSecondsDouble() * 0.001;
370 if (velOriLeftDelta.norm() > maxOriAcc)
372 velOriLeftDelta = velOriLeftDelta.normalized() * maxOriAcc;
375 newOriVelLeft = curVelOriLeft->toEigen() + velOriLeftDelta;
377 if (newOriVelLeft.norm() > maxOriVelocity)
379 newOriVelLeft = newOriVelLeft.normalized() * maxOriVelocity;
390 Eigen::Vector3f newOriVelRight(3);
391 Eigen::Vector3f newOriAccRight(3);
393 if (curTorqueRightVec.norm() > torqueThreshold)
396 newOriAccRight = curTorqueRightVec * oriAccGain;
398 else if (curVelOriRight->toEigen().norm() > 0)
401 newOriAccRight = -oriDccGain * curVelOriRight->toEigen().normalized();
405 newOriAccRight = Eigen::Vector3f::Zero();
408 ARMARX_INFO <<
"New Ori Acc Right " << newOriAccRight(0) <<
" " << newOriAccRight(1) <<
" " << newOriAccRight(2);
411 Eigen::Vector3f velOriRightDelta = newOriAccRight * duration.toMilliSecondsDouble() * 0.001;
413 if (velOriRightDelta.norm() > maxOriAcc)
415 velOriRightDelta = velOriRightDelta.normalized() * maxOriAcc;
418 newOriVelRight = curVelOriRight->toEigen() + velOriRightDelta;
420 if (newOriVelRight.norm() > maxOriVelocity)
422 newOriVelRight = newOriVelRight.normalized() * maxOriVelocity;
425 ARMARX_INFO <<
"New Ori Vel Right " << newOriVelRight(0) <<
" " << newOriVelRight(1) <<
" " << newOriVelRight(2);
429 float maxVelocityTrans = 60.0;
430 float maxVelocityRot = 0.2;
435 assert(kernelSize >= 0);
436 if (platformVelMeanFilter.size() ==
static_cast<std::size_t
>(kernelSize))
438 platformVelMeanFilter.erase(platformVelMeanFilter.begin(), platformVelMeanFilter.begin() + 1);
441 platformVelMeanFilter.push_back(platformVelPtr);
447 for (std::size_t i = 0; i < platformVelMeanFilter.size(); i++)
465 Eigen::Vector4f temp;
467 for (
int i = 0; i < 3; i++)
469 temp(i) = newVelLeft(i);
473 temp = platformTransformation.inverse() * temp;
475 for (
int i = 0; i < 3; i++)
477 newVelLeft(i) = temp(i);
480 for (
int i = 0; i < 3; i++)
482 temp(i) = newOriVelLeft(i);
486 temp = platformTransformation.inverse() * temp;
488 for (
int i = 0; i < 3; i++)
490 newOriVelLeft(i) = oriAccGain * deltaLeftRPY(i);
493 for (
int i = 0; i < 3; i++)
495 temp(i) = newVelRight(i);
499 temp = platformTransformation.inverse() * temp;
501 for (
int i = 0; i < 3; i++)
503 newVelRight(i) = temp(i);
506 for (
int i = 0; i < 3; i++)
508 temp(i) = newOriVelRight(i);
512 temp = platformTransformation.inverse() * temp;
514 for (
int i = 0; i < 3; i++)
516 newOriVelRight(i) = oriAccGain * deltaRightRPY(i);
519 ARMARX_INFO <<
"New Vel right pos " << newVelRight(0) <<
" " << newVelRight(1) <<
" " << newVelRight(2);
520 ARMARX_INFO <<
"New Vel right ori " << newOriVelRight(0) <<
" " << newOriVelRight(1) <<
" " << newOriVelRight(2);
521 ARMARX_INFO <<
"New Vel right pos " << newVelRight(0) <<
" " << newVelRight(1) <<
" " << newVelRight(2);
522 ARMARX_INFO <<
"New Vel left ori " << newOriVelLeft(0) <<
" " << newOriVelLeft(1) <<
" " << newOriVelLeft(2);
524 VirtualRobot::MathTools::rpy2eigen4f(in.getDesiredLeftTcpOrientation()->toEigen()(0),
525 in.getDesiredLeftTcpOrientation()->toEigen()(1),
526 in.getDesiredLeftTcpOrientation()->toEigen()(2), targetLeft);
527 targetLeft(0, 3) = leftTcpPoseBase(0, 3);
528 targetLeft(1, 3) = leftTcpPoseBase(1, 3);
529 targetLeft(2, 3) = leftTcpPoseBase(2, 3);
531 VirtualRobot::MathTools::rpy2eigen4f(in.getDesiredRightTcpOrientation()->toEigen()(0),
532 in.getDesiredRightTcpOrientation()->toEigen()(1),
533 in.getDesiredRightTcpOrientation()->toEigen()(2), targetright);
534 targetright(0, 3) = rightTcpPoseBase(0, 3);
535 targetright(1, 3) = rightTcpPoseBase(1, 3);
536 targetright(2, 3) = rightTcpPoseBase(2, 3);
537 ARMARX_INFO <<
"target RPY right " << currentRightRPY(0) <<
" " << currentRightRPY(1) <<
" " << currentRightRPY(2);
538 ARMARX_INFO <<
"target RPY left " << currentLeftRPY(0) <<
" " << currentLeftRPY(1) <<
" " << currentLeftRPY(2);
539 ARMARX_INFO <<
"target RPY right " << (in.getDesiredRightTcpOrientation()->toEigen())(0) <<
" " << (in.getDesiredRightTcpOrientation()->toEigen())(1) <<
" " << (in.getDesiredRightTcpOrientation()->toEigen())(2);
540 ARMARX_INFO <<
"target RPY left " << (in.getDesiredLeftTcpOrientation()->toEigen())(0) <<
" " << (in.getDesiredLeftTcpOrientation()->toEigen())(1) <<
" " << (in.getDesiredLeftTcpOrientation()->toEigen())(2);
542 debugDrawer->setPoseVisu(
"leftHandTCP",
"leftHandTCP",
FramedPose(leftTcpPoseBase,
"Armar3_Base",
"Armar3").toGlobal(context->
getRobot()));
543 debugDrawer->setPoseVisu(
"leftTargetTCP",
"leftTargetTCP",
FramedPose(targetLeft,
"Armar3_Base",
"Armar3").toGlobal(context->
getRobot()));
544 debugDrawer->setPoseVisu(
"rightHandTCP",
"rightHandTCP",
FramedPose(rightTcpPoseBase,
"Armar3_Base",
"Armar3").toGlobal(context->
getRobot()));
545 debugDrawer->setPoseVisu(
"rightTargetTCP",
"rightTargetTCP",
FramedPose(targetright,
"Armar3_Base",
"Armar3").toGlobal(context->
getRobot()));
550 out.setLeftTcpTargetPosVelocity(
new FramedDirection(newVelLeft, curVelLeft->frame, curVelLeft->agent));
551 out.setLeftTcpTargetOriVelocity(
new FramedDirection(newOriVelLeft,
"Armar3_Base",
"Armar3"));
552 out.setRightTcpTargetPosVelocity(
new FramedDirection(newVelRight, curVelRight->frame, curVelRight->agent));
553 out.setRightTcpTargetOriVelocity(
new FramedDirection(newOriVelRight,
"Armar3_Base",
"Armar3"));
557 local.setPlatformVelMeanFilter(platformVelMeanFilter);
566 bool noChange =
false;
585 getContext<CoupledInteractionGroupStatechartContext>();
604 return "CalculateForceControlRobotPose";