3 #include <SimoxUtility/math/convert/mat4f_to_quat.h>
4 #include <VirtualRobot/MathTools.h>
9 #include <simox/control/robot/NodeInterface.h>
16 const VirtualRobot::RobotNodeSetPtr& rtRns,
21 rtTCP = rtRns->getTCP();
23 ik.reset(
new VirtualRobot::DifferentialIK(
24 rtRns, rtRns->getRobot()->getRootNode(), VirtualRobot::JacobiProvider::eSVDDamped));
28 simoxNodeSet = simoxControlRobot->getSubNodeSet(rns->getName());
45 calculateTransitionWeights(
c.selfCollActivatorZ1,
c.selfCollActivatorZ2);
51 for (
size_t i = 0; i < rns->getSize(); ++i)
54 rtStatus.
jointLimitData[i].isLimitless = rns->getNode(i)->isLimitless();
58 rtStatus.
jointLimitData[i].qLimLow = rns->getNode(i)->getJointLimitLow();
59 rtStatus.
jointLimitData[i].qLimHigh = rns->getNode(i)->getJointLimitHigh();
66 if (not joint.isLimitless)
69 float qRange = joint.qLimHigh - joint.qLimLow;
70 joint.thresholdRange =
c.jointRangeBufferZone * qRange;
71 joint.qposThresholdLow = joint.qLimLow + joint.thresholdRange;
72 joint.qposThresholdHigh = joint.qLimHigh - joint.thresholdRange;
73 float qposZ1 =
c.jointRangeBufferZoneZ1 * qRange;
74 float qposZ2 =
c.jointRangeBufferZoneZ2 * qRange;
75 joint.qposZ1Low = joint.qLimLow + qposZ1;
76 joint.qposZ2Low = joint.qLimLow + qposZ2;
77 joint.qposZ1High = joint.qLimHigh - qposZ1;
78 joint.qposZ2High = joint.qLimHigh - qposZ2;
79 joint.jointLimitNullSpaceWeightsLow =
80 calculateTransitionWeights(joint.qposZ1Low, joint.qposZ2Low);
81 joint.jointLimitNullSpaceWeightsHigh =
82 calculateTransitionWeights(joint.qposZ1High, joint.qposZ2High);
164 SafetyTaskspaceImpedanceController::calculateSelfCollisionTorque(
167 std::shared_ptr<std::vector<::simox::control::environment::DistanceResult>> collisionPairs,
168 std::shared_ptr<std::vector<int>> pointsOnArm,
169 int pointsOnArmIndex,
170 std::vector<std::string> selfCollisionNodes)
187 rts.selfCollisionJointTorque.setZero();
189 for (
auto&
data : rts.selfCollDataVec)
194 for (
auto&
data : rts.evalData)
203 for (
int i = 0; i < pointsOnArmIndex; ++i)
208 rts.activeDistPair.node1 = collisionPairs->at(pointsOnArm->at(i)).node1;
209 rts.activeDistPair.node2 = collisionPairs->at(pointsOnArm->at(i)).node2;
210 rts.activeDistPair.point1 = collisionPairs->at(pointsOnArm->at(i)).point1;
211 rts.activeDistPair.point2 = collisionPairs->at(pointsOnArm->at(i)).point2;
212 rts.activeDistPair.normalVec = collisionPairs->at(pointsOnArm->at(i)).normalVec;
213 rts.activeDistPair.minDistance = collisionPairs->at(pointsOnArm->at(i)).minDistance;
216 rts.node1OnArm =
false;
217 rts.node2OnArm =
false;
219 if (std::find(selfCollisionNodes.begin(),
220 selfCollisionNodes.end(),
221 rts.activeDistPair.node1) != selfCollisionNodes.end())
223 rts.node1OnArm =
true;
225 if (std::find(selfCollisionNodes.begin(),
226 selfCollisionNodes.end(),
227 rts.activeDistPair.node2) != selfCollisionNodes.end())
229 rts.node2OnArm =
true;
234 if (
static_cast<float>(rts.activeDistPair.minDistance) <
c.distanceThreshold)
236 if (rts.node1OnArm and rts.node2OnArm)
240 rts.node1Index = simoxNodeSet->getNodeIndex(rts.activeDistPair.node1);
241 rts.node2Index = simoxNodeSet->getNodeIndex(rts.activeDistPair.node2);
242 if (rts.node1Index < rts.node2Index)
245 rts.node1OnArm =
false;
250 rts.node2OnArm =
false;
257 rts.selfCollDataVec[i].nodeName = rts.activeDistPair.node1;
258 rts.selfCollDataVec[i].otherName = rts.activeDistPair.node2;
259 rts.selfCollDataVec[i].minDistance =
260 static_cast<float>(rts.activeDistPair.minDistance);
261 rts.selfCollDataVec[i].point.x() =
262 static_cast<float>(rts.activeDistPair.point1->x());
263 rts.selfCollDataVec[i].point.y() =
264 static_cast<float>(rts.activeDistPair.point1->y());
265 rts.selfCollDataVec[i].point.z() =
266 static_cast<float>(rts.activeDistPair.point1->z());
270 rts.node = simoxNodeSet->getNode(rts.activeDistPair.node1);
273 rts.localTransformation.translation() =
274 rts.node->getGlobalPose().inverse() * rts.activeDistPair.point1.value();
276 rts.selfCollDataVec[i].jacobian =
278 ->computeJacobian(*rts.node,
279 simox::control::robot::JacobianParams{
280 .mode = simox::control::utils::CartesianSelection::Position,
281 .localTransformation = rts.localTransformation})
290 rts.selfCollDataVec[i].direction =
291 (rts.activeDistPair.point1.value() - rts.activeDistPair.point2.value())
294 else if (rts.node2OnArm)
298 rts.selfCollDataVec[i].nodeName = rts.activeDistPair.node2;
299 rts.selfCollDataVec[i].otherName = rts.activeDistPair.node1;
300 rts.selfCollDataVec[i].minDistance =
301 static_cast<float>(rts.activeDistPair.minDistance);
303 rts.selfCollDataVec[i].point.x() =
304 static_cast<float>(rts.activeDistPair.point2->x());
305 rts.selfCollDataVec[i].point.y() =
306 static_cast<float>(rts.activeDistPair.point2->y());
307 rts.selfCollDataVec[i].point.z() =
308 static_cast<float>(rts.activeDistPair.point2->z());
312 rts.node = simoxNodeSet->getNode(rts.activeDistPair.node2);
315 rts.localTransformation.translation() =
316 rts.node->getGlobalPose().inverse() * rts.activeDistPair.point1.value();
318 rts.selfCollDataVec[i].jacobian =
320 ->computeJacobian(*rts.node,
321 simox::control::robot::JacobianParams{
322 .mode = simox::control::utils::CartesianSelection::Position,
323 .localTransformation = rts.localTransformation})
333 rts.selfCollDataVec[i].direction =
334 (rts.activeDistPair.point2.value() - rts.activeDistPair.point1.value())
340 "The indeces in the pointsOnArm vector must correspond"
341 "to a contact point pair, where at least one node is "
342 "located on the arm. \n There is a problem in the preFilter"
343 "method in the rtRun method.")
344 .deactivateSpam(1.0);
350 if (rts.selfCollDataVec[i].minDistance < 0.0f)
352 rts.selfCollDataVec[i].direction *= -1.0f;
353 rts.selfCollDataVec[i].minDistance = 0.0f;
356 if (rts.activeDistPair.point1->isApprox(*rts.activeDistPair.point2, 1e-8) and
357 rts.activeDistPair.normalVec != std::nullopt)
369 rts.selfCollDataVec[i].direction.x() =
370 static_cast<float>(rts.activeDistPair.normalVec->x());
371 rts.selfCollDataVec[i].direction.y() =
372 static_cast<float>(rts.activeDistPair.normalVec->y());
373 rts.selfCollDataVec[i].direction.z() =
374 static_cast<float>(rts.activeDistPair.normalVec->z());
377 rts.selfCollDataVec[i].direction.normalize();
383 rts.selfCollDataVec[i].repulsiveForce =
384 c.maxRepulsiveForce / std::pow(
c.distanceThreshold, 2) *
385 std::pow(rts.selfCollDataVec[i].minDistance -
c.distanceThreshold, 2);
386 rts.selfCollDataVec[i].localStiffness =
387 -2.0 *
c.maxRepulsiveForce / std::pow(
c.distanceThreshold, 2) *
388 (rts.selfCollDataVec[i].minDistance -
c.distanceThreshold);
391 rts.selfCollDataVec[i].repulsiveForce =
392 std::clamp(rts.selfCollDataVec[i].repulsiveForce, 0.0f,
c.maxRepulsiveForce);
398 rts.selfCollDataVec[i].projectedJacT =
399 (rts.selfCollDataVec[i].direction.transpose() * rts.selfCollDataVec[i].jacobian)
406 rts.selfCollDataVec[i].distanceVelocity =
407 rts.selfCollDataVec[i].projectedJacT.transpose() * rts.qvelFiltered;
412 rts.selfCollDataVec[i].projectedMass =
413 1 / (rts.selfCollDataVec[i].projectedJacT.transpose() * rts.inertiaInverse *
414 rts.selfCollDataVec[i].projectedJacT);
418 rts.selfCollDataVec[i].damping =
419 2 *
std::sqrt(rts.selfCollDataVec[i].localStiffness) *
420 std::sqrt(rts.selfCollDataVec[i].projectedMass) *
c.dampingFactor;
424 rts.selfCollisionJointTorque +=
425 rts.selfCollDataVec[i].projectedJacT *
426 (rts.selfCollDataVec[i].repulsiveForce -
427 rts.selfCollDataVec[i].damping * rts.selfCollDataVec[i].distanceVelocity);
435 if (
c.testConfig == 1)
438 if (rts.activeDistPair.node1 ==
"ArmL8_Wri2" and rts.activeDistPair.node2 ==
"root")
440 rts.evalData[0].setDistValues(
441 rts.activeDistPair.node1,
442 rts.activeDistPair.node2,
443 static_cast<float>(rts.activeDistPair.minDistance));
444 if (rts.evalData[0].minDistance <
c.distanceThreshold)
446 rts.evalData[0].setCalcValues(rts.selfCollDataVec[i].jacobian,
447 rts.selfCollDataVec[i].repulsiveForce,
448 rts.selfCollDataVec[i].localStiffness,
449 rts.selfCollDataVec[i].projectedJacT,
450 rts.selfCollDataVec[i].distanceVelocity,
451 rts.selfCollDataVec[i].direction,
452 rts.selfCollDataVec[i].point,
453 rts.selfCollDataVec[i].damping,
454 rts.selfCollDataVec[i].projectedMass,
455 rts.selfCollDataVec[i].desiredNSColl);
458 else if (rts.activeDistPair.node2 ==
"ArmL8_Wri2" and
459 rts.activeDistPair.node1 ==
"root")
461 rts.evalData[0].setDistValues(
462 rts.activeDistPair.node2,
463 rts.activeDistPair.node1,
464 static_cast<float>(rts.activeDistPair.minDistance));
465 if (rts.evalData[0].minDistance <
c.distanceThreshold)
467 rts.evalData[0].setCalcValues(rts.selfCollDataVec[i].jacobian,
468 rts.selfCollDataVec[i].repulsiveForce,
469 rts.selfCollDataVec[i].localStiffness,
470 rts.selfCollDataVec[i].projectedJacT,
471 rts.selfCollDataVec[i].distanceVelocity,
472 rts.selfCollDataVec[i].direction,
473 rts.selfCollDataVec[i].point,
474 rts.selfCollDataVec[i].damping,
475 rts.selfCollDataVec[i].projectedMass,
476 rts.selfCollDataVec[i].desiredNSColl);
479 if (rts.activeDistPair.node1 ==
"ArmL8_Wri2" and
480 rts.activeDistPair.node2 ==
"ArmR8_Wri2")
482 rts.evalData[1].setDistValues(
483 rts.activeDistPair.node1,
484 rts.activeDistPair.node2,
485 static_cast<float>(rts.activeDistPair.minDistance));
486 if (rts.evalData[1].minDistance <
c.distanceThreshold)
488 rts.evalData[1].setCalcValues(rts.selfCollDataVec[i].jacobian,
489 rts.selfCollDataVec[i].repulsiveForce,
490 rts.selfCollDataVec[i].localStiffness,
491 rts.selfCollDataVec[i].projectedJacT,
492 rts.selfCollDataVec[i].distanceVelocity,
493 rts.selfCollDataVec[i].direction,
494 rts.selfCollDataVec[i].point,
495 rts.selfCollDataVec[i].damping,
496 rts.selfCollDataVec[i].projectedMass,
497 rts.selfCollDataVec[i].desiredNSColl);
500 else if (rts.activeDistPair.node2 ==
"ArmL8_Wri2" and
501 rts.activeDistPair.node1 ==
"ArmR8_Wri2")
503 rts.evalData[1].setDistValues(
504 rts.activeDistPair.node2,
505 rts.activeDistPair.node1,
506 static_cast<float>(rts.activeDistPair.minDistance));
507 if (rts.evalData[1].minDistance <
c.distanceThreshold)
509 rts.evalData[1].setCalcValues(rts.selfCollDataVec[i].jacobian,
510 rts.selfCollDataVec[i].repulsiveForce,
511 rts.selfCollDataVec[i].localStiffness,
512 rts.selfCollDataVec[i].projectedJacT,
513 rts.selfCollDataVec[i].distanceVelocity,
514 rts.selfCollDataVec[i].direction,
515 rts.selfCollDataVec[i].point,
516 rts.selfCollDataVec[i].damping,
517 rts.selfCollDataVec[i].projectedMass,
518 rts.selfCollDataVec[i].desiredNSColl);
521 if (rts.activeDistPair.node1 ==
"ArmL7_Wri1" and
522 rts.activeDistPair.node2 ==
"ArmR8_Wri2")
524 rts.evalData[2].setDistValues(
525 rts.activeDistPair.node1,
526 rts.activeDistPair.node2,
527 static_cast<float>(rts.activeDistPair.minDistance));
528 if (rts.evalData[2].minDistance <
c.distanceThreshold)
530 rts.evalData[2].setCalcValues(rts.selfCollDataVec[i].jacobian,
531 rts.selfCollDataVec[i].repulsiveForce,
532 rts.selfCollDataVec[i].localStiffness,
533 rts.selfCollDataVec[i].projectedJacT,
534 rts.selfCollDataVec[i].distanceVelocity,
535 rts.selfCollDataVec[i].direction,
536 rts.selfCollDataVec[i].point,
537 rts.selfCollDataVec[i].damping,
538 rts.selfCollDataVec[i].projectedMass,
539 rts.selfCollDataVec[i].desiredNSColl);
542 else if (rts.activeDistPair.node2 ==
"ArmL7_Wri1" and
543 rts.activeDistPair.node1 ==
"ArmR8_Wri2")
545 rts.evalData[2].setDistValues(
546 rts.activeDistPair.node2,
547 rts.activeDistPair.node1,
548 static_cast<float>(rts.activeDistPair.minDistance));
549 if (rts.evalData[2].minDistance <
c.distanceThreshold)
551 rts.evalData[2].setCalcValues(rts.selfCollDataVec[i].jacobian,
552 rts.selfCollDataVec[i].repulsiveForce,
553 rts.selfCollDataVec[i].localStiffness,
554 rts.selfCollDataVec[i].projectedJacT,
555 rts.selfCollDataVec[i].distanceVelocity,
556 rts.selfCollDataVec[i].direction,
557 rts.selfCollDataVec[i].point,
558 rts.selfCollDataVec[i].damping,
559 rts.selfCollDataVec[i].projectedMass,
560 rts.selfCollDataVec[i].desiredNSColl);
563 if (rts.activeDistPair.node1 ==
"ArmL8_Wri2" and
564 rts.activeDistPair.node2 ==
"ArmR7_Wri1")
566 rts.evalData[3].setDistValues(
567 rts.activeDistPair.node1,
568 rts.activeDistPair.node2,
569 static_cast<float>(rts.activeDistPair.minDistance));
570 if (rts.evalData[3].minDistance <
c.distanceThreshold)
572 rts.evalData[3].setCalcValues(rts.selfCollDataVec[i].jacobian,
573 rts.selfCollDataVec[i].repulsiveForce,
574 rts.selfCollDataVec[i].localStiffness,
575 rts.selfCollDataVec[i].projectedJacT,
576 rts.selfCollDataVec[i].distanceVelocity,
577 rts.selfCollDataVec[i].direction,
578 rts.selfCollDataVec[i].point,
579 rts.selfCollDataVec[i].damping,
580 rts.selfCollDataVec[i].projectedMass,
581 rts.selfCollDataVec[i].desiredNSColl);
584 else if (rts.activeDistPair.node2 ==
"ArmL8_Wri2" and
585 rts.activeDistPair.node1 ==
"ArmR7_Wri1")
587 rts.evalData[3].setDistValues(
588 rts.activeDistPair.node2,
589 rts.activeDistPair.node1,
590 static_cast<float>(rts.activeDistPair.minDistance));
591 if (rts.evalData[3].minDistance <
c.distanceThreshold)
593 rts.evalData[3].setCalcValues(rts.selfCollDataVec[i].jacobian,
594 rts.selfCollDataVec[i].repulsiveForce,
595 rts.selfCollDataVec[i].localStiffness,
596 rts.selfCollDataVec[i].projectedJacT,
597 rts.selfCollDataVec[i].distanceVelocity,
598 rts.selfCollDataVec[i].direction,
599 rts.selfCollDataVec[i].point,
600 rts.selfCollDataVec[i].damping,
601 rts.selfCollDataVec[i].projectedMass,
602 rts.selfCollDataVec[i].desiredNSColl);
605 if (rts.activeDistPair.node1 ==
"ArmL8_Wri2" and
606 rts.activeDistPair.node2 ==
"Neck_2_Pitch")
608 rts.evalData[4].setDistValues(
609 rts.activeDistPair.node1,
610 rts.activeDistPair.node2,
611 static_cast<float>(rts.activeDistPair.minDistance));
612 if (rts.evalData[4].minDistance <
c.distanceThreshold)
614 rts.evalData[4].setCalcValues(rts.selfCollDataVec[i].jacobian,
615 rts.selfCollDataVec[i].repulsiveForce,
616 rts.selfCollDataVec[i].localStiffness,
617 rts.selfCollDataVec[i].projectedJacT,
618 rts.selfCollDataVec[i].distanceVelocity,
619 rts.selfCollDataVec[i].direction,
620 rts.selfCollDataVec[i].point,
621 rts.selfCollDataVec[i].damping,
622 rts.selfCollDataVec[i].projectedMass,
623 rts.selfCollDataVec[i].desiredNSColl);
626 else if (rts.activeDistPair.node2 ==
"ArmL8_Wri2" and
627 rts.activeDistPair.node1 ==
"Neck_2_Pitch")
629 rts.evalData[4].setDistValues(
630 rts.activeDistPair.node2,
631 rts.activeDistPair.node1,
632 static_cast<float>(rts.activeDistPair.minDistance));
633 if (rts.evalData[4].minDistance <
c.distanceThreshold)
635 rts.evalData[4].setCalcValues(rts.selfCollDataVec[i].jacobian,
636 rts.selfCollDataVec[i].repulsiveForce,
637 rts.selfCollDataVec[i].localStiffness,
638 rts.selfCollDataVec[i].projectedJacT,
639 rts.selfCollDataVec[i].distanceVelocity,
640 rts.selfCollDataVec[i].direction,
641 rts.selfCollDataVec[i].point,
642 rts.selfCollDataVec[i].damping,
643 rts.selfCollDataVec[i].projectedMass,
644 rts.selfCollDataVec[i].desiredNSColl);
647 if (rts.activeDistPair.node1 ==
"ArmL8_Wri2" and
648 rts.activeDistPair.node2 ==
"TorsoJoint")
650 rts.evalData[5].setDistValues(
651 rts.activeDistPair.node1,
652 rts.activeDistPair.node2,
653 static_cast<float>(rts.activeDistPair.minDistance));
654 if (rts.evalData[5].minDistance <
c.distanceThreshold)
656 rts.evalData[5].setCalcValues(rts.selfCollDataVec[i].jacobian,
657 rts.selfCollDataVec[i].repulsiveForce,
658 rts.selfCollDataVec[i].localStiffness,
659 rts.selfCollDataVec[i].projectedJacT,
660 rts.selfCollDataVec[i].distanceVelocity,
661 rts.selfCollDataVec[i].direction,
662 rts.selfCollDataVec[i].point,
663 rts.selfCollDataVec[i].damping,
664 rts.selfCollDataVec[i].projectedMass,
665 rts.selfCollDataVec[i].desiredNSColl);
668 else if (rts.activeDistPair.node2 ==
"ArmL8_Wri2" and
669 rts.activeDistPair.node1 ==
"TorsoJoint")
671 rts.evalData[5].setDistValues(
672 rts.activeDistPair.node2,
673 rts.activeDistPair.node1,
674 static_cast<float>(rts.activeDistPair.minDistance));
675 if (rts.evalData[5].minDistance <
c.distanceThreshold)
677 rts.evalData[5].setCalcValues(rts.selfCollDataVec[i].jacobian,
678 rts.selfCollDataVec[i].repulsiveForce,
679 rts.selfCollDataVec[i].localStiffness,
680 rts.selfCollDataVec[i].projectedJacT,
681 rts.selfCollDataVec[i].distanceVelocity,
682 rts.selfCollDataVec[i].direction,
683 rts.selfCollDataVec[i].point,
684 rts.selfCollDataVec[i].damping,
685 rts.selfCollDataVec[i].projectedMass,
686 rts.selfCollDataVec[i].desiredNSColl);
689 if (rts.activeDistPair.node1 ==
"ArmL5_Elb1" and
690 rts.activeDistPair.node2 ==
"TorsoJoint")
692 rts.evalData[6].setDistValues(
693 rts.activeDistPair.node1,
694 rts.activeDistPair.node2,
695 static_cast<float>(rts.activeDistPair.minDistance));
696 if (rts.evalData[6].minDistance <
c.distanceThreshold)
698 rts.evalData[6].setCalcValues(rts.selfCollDataVec[i].jacobian,
699 rts.selfCollDataVec[i].repulsiveForce,
700 rts.selfCollDataVec[i].localStiffness,
701 rts.selfCollDataVec[i].projectedJacT,
702 rts.selfCollDataVec[i].distanceVelocity,
703 rts.selfCollDataVec[i].direction,
704 rts.selfCollDataVec[i].point,
705 rts.selfCollDataVec[i].damping,
706 rts.selfCollDataVec[i].projectedMass,
707 rts.selfCollDataVec[i].desiredNSColl);
710 else if (rts.activeDistPair.node2 ==
"ArmL5_Elb1" and
711 rts.activeDistPair.node1 ==
"TorsoJoint")
713 rts.evalData[6].setDistValues(
714 rts.activeDistPair.node2,
715 rts.activeDistPair.node1,
716 static_cast<float>(rts.activeDistPair.minDistance));
717 if (rts.evalData[6].minDistance <
c.distanceThreshold)
719 rts.evalData[6].setCalcValues(rts.selfCollDataVec[i].jacobian,
720 rts.selfCollDataVec[i].repulsiveForce,
721 rts.selfCollDataVec[i].localStiffness,
722 rts.selfCollDataVec[i].projectedJacT,
723 rts.selfCollDataVec[i].distanceVelocity,
724 rts.selfCollDataVec[i].direction,
725 rts.selfCollDataVec[i].point,
726 rts.selfCollDataVec[i].damping,
727 rts.selfCollDataVec[i].projectedMass,
728 rts.selfCollDataVec[i].desiredNSColl);
736 SafetyTaskspaceImpedanceController::calculateJointLimitTorque(Config&
c, RtStatus& rts)
742 rts.jointLimitJointTorque.setZero();
750 for (
size_t i = 0; i < rts.jointLimitData.size(); ++i)
752 if (rts.jointLimitData[i].isLimitless)
755 auto& joint = rts.jointLimitData[i];
756 rts.jointInertia = rts.inertia(i, i);
757 if (rts.qpos[i] < rts.jointLimitData[i].qposThresholdLow)
759 joint.repulsiveTorque =
760 c.maxRepulsiveTorque / std::pow(rts.jointLimitData[i].thresholdRange, 2) *
761 std::pow(rts.jointLimitData[i].qposThresholdLow - rts.qpos[i], 2);
763 joint.repulsiveTorque =
764 std::clamp(joint.repulsiveTorque, 0.0f,
c.maxRepulsiveTorque);
766 rts.localStiffnessJointLim = 2 *
c.maxRepulsiveTorque /
767 std::pow(rts.jointLimitData[i].thresholdRange, 2) *
768 (rts.jointLimitData[i].qposThresholdLow - rts.qpos[i]);
771 rts.dampingJointLim = 2 *
std::sqrt(rts.jointInertia) *
772 std::sqrt(rts.localStiffnessJointLim) *
c.dampingFactor;
775 joint.totalDamping = rts.dampingJointLim * rts.qvelFiltered[i];
776 rts.jointLimitJointTorque(i) =
777 joint.repulsiveTorque - rts.dampingJointLim * rts.qvelFiltered[i];
781 else if (rts.qpos[i] > rts.jointLimitData[i].qposThresholdHigh)
783 joint.repulsiveTorque =
784 c.maxRepulsiveTorque / std::pow(rts.jointLimitData[i].thresholdRange, 2) *
785 std::pow(rts.qpos[i] - rts.jointLimitData[i].qposThresholdHigh, 2);
788 joint.repulsiveTorque =
789 std::clamp(joint.repulsiveTorque, 0.0f,
c.maxRepulsiveTorque);
791 rts.localStiffnessJointLim =
792 2 *
c.maxRepulsiveTorque / std::pow(rts.jointLimitData[i].thresholdRange, 2) *
793 (rts.qpos[i] - rts.jointLimitData[i].qposThresholdHigh);
796 rts.dampingJointLim = 2 *
std::sqrt(rts.jointInertia) *
797 std::sqrt(rts.localStiffnessJointLim) *
c.dampingFactor;
799 joint.totalDamping = rts.dampingJointLim * rts.qvelFiltered[i];
800 rts.jointLimitJointTorque(i) =
801 -(joint.repulsiveTorque + rts.dampingJointLim * rts.qvelFiltered[i]);
808 SafetyTaskspaceImpedanceController::calculateSelfCollisionNullspace(Config&
c, RtStatus& rts)
810 rts.selfCollNullSpace.setIdentity();
816 rts.k1 = rts.selfCollisionNullSpaceWeights(0);
817 rts.k2 = rts.selfCollisionNullSpaceWeights(1);
818 rts.k3 = rts.selfCollisionNullSpaceWeights(2);
819 rts.k4 = rts.selfCollisionNullSpaceWeights(3);
823 for (
auto& active : rts.selfCollDataVec)
826 if (active.minDistance <
c.selfCollActivatorZ1)
829 rts.desiredNullSpace = 0.0f;
831 else if (
c.selfCollActivatorZ1 <= active.minDistance &&
832 active.minDistance <=
c.selfCollActivatorZ2)
835 rts.desiredNullSpace = rts.k1 * std::pow(active.minDistance, 3) +
836 rts.k2 * std::pow(active.minDistance, 2) +
837 rts.k3 * active.minDistance + rts.k4;
838 if (rts.desiredNullSpace > 1.0f)
841 <<
"desired null space value should not be higher than 1.0, was "
842 << rts.desiredNullSpace
843 <<
", in self-collision null space calulation, weights: " << rts.k1 <<
", "
844 << rts.k2 <<
", " << rts.k3 <<
", " << rts.k4;
850 rts.desiredNullSpace = 1.0f;
854 active.desiredNSColl = rts.desiredNullSpace;
855 rts.desiredNullSpace =
std::clamp(rts.desiredNullSpace, 0.0f, 1.0f);
858 rts.normalizedJacT = active.projectedJacT.normalized();
864 rts.tempNullSpaceMatrix = I - (rts.normalizedJacT * (1.0f - rts.desiredNullSpace) *
865 rts.normalizedJacT.transpose());
867 if (
c.onlyLimitCollDirection)
871 for (
int i = 0; i < rts.impedanceJointTorque.rows(); ++i)
873 if ((active.projectedJacT(i) < 0.0f and rts.impedanceJointTorque(i) < 0.0f) ||
874 (active.projectedJacT(i) > 0.0f and rts.impedanceJointTorque(i) > 0.0f))
877 rts.tempNullSpaceMatrix(i, i) = 1.0f;
883 rts.selfCollNullSpace *= rts.tempNullSpaceMatrix;
887 if (
c.testConfig == 1)
889 if (active.nodeName ==
"ArmL8_Wri2")
891 rts.evalData[0].desiredNSColl = active.desiredNSColl;
892 rts.evalData[1].desiredNSColl = active.desiredNSColl;
893 rts.evalData[3].desiredNSColl = active.desiredNSColl;
894 rts.evalData[4].desiredNSColl = active.desiredNSColl;
896 else if (active.nodeName ==
"ArmL7_Wri1")
898 rts.evalData[2].desiredNSColl = active.desiredNSColl;
905 SafetyTaskspaceImpedanceController::calculateJointLimitNullspace(Config&
c, RtStatus& rts)
908 rts.jointLimNullSpace.setIdentity();
915 for (
size_t i = 0; i < rts.jointLimitData.size(); ++i)
917 auto& joint = rts.jointLimitData[i];
920 rts.k1Lo = joint.jointLimitNullSpaceWeightsLow(0);
921 rts.k2Lo = joint.jointLimitNullSpaceWeightsLow(1);
922 rts.k3Lo = joint.jointLimitNullSpaceWeightsLow(2);
923 rts.k4Lo = joint.jointLimitNullSpaceWeightsLow(3);
924 rts.k1Hi = joint.jointLimitNullSpaceWeightsHigh(0);
925 rts.k2Hi = joint.jointLimitNullSpaceWeightsHigh(1);
926 rts.k3Hi = joint.jointLimitNullSpaceWeightsHigh(2);
927 rts.k4Hi = joint.jointLimitNullSpaceWeightsHigh(3);
931 if (not joint.isLimitless)
934 if (rts.qpos[i] < joint.qposZ1Low)
937 rts.desiredNullSpace = 0.0f;
939 else if (joint.qposZ1Low <= rts.qpos[i] && rts.qpos[i] <= joint.qposZ2Low)
942 rts.desiredNullSpace = rts.k1Lo * std::pow(rts.qpos[i], 3) +
943 rts.k2Lo * std::pow(rts.qpos[i], 2) +
944 rts.k3Lo * rts.qpos[i] + rts.k4Lo;
945 if (rts.desiredNullSpace > 1.0f)
948 <<
"desired null space value should not be higher than 1.0, was "
949 << rts.desiredNullSpace
950 <<
", approaching lower joint limit, weights: " << rts.k1Lo <<
", "
951 << rts.k2Lo <<
", " << rts.k3Lo <<
", " << rts.k4Lo;
954 else if (joint.qposZ2High <= rts.qpos[i] && rts.qpos[i] <= joint.qposZ1High)
957 rts.desiredNullSpace = rts.k1Hi * std::pow(rts.qpos[i], 3) +
958 rts.k2Hi * std::pow(rts.qpos[i], 2) +
959 rts.k3Hi * rts.qpos[i] + rts.k4Hi;
960 if (rts.desiredNullSpace > 1.0f)
963 <<
"desired null space value should not be higher than 1.0, was "
964 << rts.desiredNullSpace
965 <<
", approaching upper joint limit, weights: " << rts.k1Hi <<
", "
966 << rts.k2Hi <<
", " << rts.k3Hi <<
", " << rts.k4Hi;
969 else if (joint.qposZ1High < rts.qpos[i])
972 rts.desiredNullSpace = 0.0f;
977 rts.desiredNullSpace = 1.0f;
981 joint.desiredNSjointLim = rts.desiredNullSpace;
982 rts.desiredNullSpace =
std::clamp(rts.desiredNullSpace, 0.0f, 1.0f);
986 rts.jointLimNullSpace(i, i) = 1.0f - (1.0f - rts.desiredNullSpace);
994 SafetyTaskspaceImpedanceController::calculateTransitionWeights(
float z1,
float z2)
1007 constraintMatrix << std::pow(z1, 3), std::pow(z1, 2), z1, 1, std::pow(z2, 3),
1008 std::pow(z2, 2), z2, 1, 3 * std::pow(z1, 2), 2 * z1, 1, 0, 3 * std::pow(z2, 2), 2 * z2,
1016 return constraintMatrix.colPivHouseholderQr().solve(b);
1025 std::shared_ptr<std::vector<::simox::control::environment::DistanceResult>>& collisionPairs,
1026 std::shared_ptr<std::vector<int>>& pointsOnArm,
1027 int pointsOnArmIndex,
1028 std::shared_ptr<simox::control::geodesics::metric::Inertia>& inertiaInstance,
1029 std::vector<std::string>& selfCollisionNodes)
1044 else if ((rtStatus.
currentPose.block<3, 1>(0, 3) -
c.desiredPose.block<3, 1>(0, 3)).norm() >
1045 c.safeDistanceMMToGoal)
1058 ik->getJacobianMatrix(
rtTCP, VirtualRobot::IKSolver::CartesianSelection::All);
1065 ik->computePseudoInverseJacobianMatrix(rtStatus.
jacobi.transpose(), lambda);
1095 if (
c.splitImpedanceForce)
1112 c.kpNullspace.cwiseProduct(
c.desiredNullspaceJointAngles.value() - rtStatus.
qpos) -
1120 if (
c.splitImpedanceForce)
1129 Eigen::VectorXd qposXd = rtStatus.
qpos.cast<
double>();
1130 rtStatus.
inertia = inertiaInstance->compute_metric(rtStatus.
qpos.cast<
double>(),
false)
1131 .metric.cast<
float>();
1137 if (
c.enableSelfCollisionAvoidance)
1140 double timeMeasure = IceUtil::Time::now().toMicroSecondsDouble();
1141 calculateSelfCollisionTorque(
1142 c, rtStatus, collisionPairs, pointsOnArm, pointsOnArmIndex, selfCollisionNodes);
1144 IceUtil::Time::now().toMicroSecondsDouble() - timeMeasure;
1146 if (
c.enableJointLimitAvoidance)
1149 double timeMeasure = IceUtil::Time::now().toMicroSecondsDouble();
1150 calculateJointLimitTorque(
c, rtStatus);
1152 IceUtil::Time::now().toMicroSecondsDouble() - timeMeasure;
1154 if (!
c.samePriority)
1156 if (
c.enableSelfCollisionAvoidance)
1159 double timeMeasure = IceUtil::Time::now().toMicroSecondsDouble();
1160 calculateSelfCollisionNullspace(
c, rtStatus);
1162 IceUtil::Time::now().toMicroSecondsDouble() - timeMeasure;
1164 if (
c.enableJointLimitAvoidance)
1167 double timeMeasure = IceUtil::Time::now().toMicroSecondsDouble();
1168 calculateJointLimitNullspace(
c, rtStatus);
1170 IceUtil::Time::now().toMicroSecondsDouble() - timeMeasure;
1176 if (
c.filterSafetyValues)
1257 else if (
c.enableSelfCollisionAvoidance and
c.enableJointLimitAvoidance)
1261 if (
c.topPrioritySelfCollisionAvoidance)
1287 else if (
c.topPriorityJointLimitAvoidance)
1334 else if (
c.enableSelfCollisionAvoidance)
1352 else if (
c.enableJointLimitAvoidance)