3 #include <SimoxUtility/math/convert/mat4f_to_quat.h>
4 #include <VirtualRobot/MathTools.h>
9 #include <simox/control/robot/NodeInterface.h>
15 const VirtualRobot::RobotNodeSetPtr& rtRns)
25 ARMARX_INFO <<
"Destruction of CollisionAvoidanceController";
33 simoxNodeSet = simoxControlRobot->getSubNodeSet(
rtRNS->getName());
135 CollisionAvoidanceController::calculateSelfCollisionTorque(
137 RtStatusForSafetyStrategy& rts,
138 DistanceResultsPtr collisionPairs,
139 std::shared_ptr<std::vector<int>> pointsOnArm,
140 int pointsOnArmIndex,
141 std::vector<std::string> selfCollisionNodes,
142 Eigen::VectorXf& qvelFiltered)
159 rts.selfCollisionJointTorque.setZero();
161 for (
auto&
data : rts.selfCollDataVec)
166 for (
auto&
data : rts.evalData)
175 for (
int i = 0; i < pointsOnArmIndex; ++i)
180 rts.activeDistPair.node1 = collisionPairs->at(pointsOnArm->at(i)).node1;
181 rts.activeDistPair.node2 = collisionPairs->at(pointsOnArm->at(i)).node2;
182 rts.activeDistPair.point1 = collisionPairs->at(pointsOnArm->at(i)).point1;
183 rts.activeDistPair.point2 = collisionPairs->at(pointsOnArm->at(i)).point2;
184 rts.activeDistPair.normalVec = collisionPairs->at(pointsOnArm->at(i)).normalVec;
185 rts.activeDistPair.minDistance = collisionPairs->at(pointsOnArm->at(i)).minDistance;
188 rts.node1OnArm =
false;
189 rts.node2OnArm =
false;
191 if (std::find(selfCollisionNodes.begin(),
192 selfCollisionNodes.end(),
193 rts.activeDistPair.node1) != selfCollisionNodes.end())
195 rts.node1OnArm =
true;
197 if (std::find(selfCollisionNodes.begin(),
198 selfCollisionNodes.end(),
199 rts.activeDistPair.node2) != selfCollisionNodes.end())
201 rts.node2OnArm =
true;
206 if (
static_cast<float>(rts.activeDistPair.minDistance) <
c.distanceThreshold)
208 if (rts.node1OnArm and rts.node2OnArm)
212 rts.node1Index = simoxNodeSet->getNodeIndex(rts.activeDistPair.node1);
213 rts.node2Index = simoxNodeSet->getNodeIndex(rts.activeDistPair.node2);
214 if (rts.node1Index < rts.node2Index)
217 rts.node1OnArm =
false;
222 rts.node2OnArm =
false;
229 rts.selfCollDataVec[i].nodeName = rts.activeDistPair.node1;
230 rts.selfCollDataVec[i].otherName = rts.activeDistPair.node2;
231 rts.selfCollDataVec[i].minDistance =
232 static_cast<float>(rts.activeDistPair.minDistance);
233 rts.selfCollDataVec[i].point.x() =
234 static_cast<float>(rts.activeDistPair.point1->x());
235 rts.selfCollDataVec[i].point.y() =
236 static_cast<float>(rts.activeDistPair.point1->y());
237 rts.selfCollDataVec[i].point.z() =
238 static_cast<float>(rts.activeDistPair.point1->z());
242 rts.node = simoxNodeSet->getNode(rts.activeDistPair.node1);
245 rts.localTransformation.translation() =
246 rts.node->getGlobalPose().inverse() * rts.activeDistPair.point1.value();
248 rts.selfCollDataVec[i].jacobian =
250 ->computeJacobian(*rts.node,
251 simox::control::robot::JacobianParams{
252 .mode = simox::control::utils::CartesianSelection::Position,
253 .localTransformation = rts.localTransformation})
262 rts.selfCollDataVec[i].direction =
263 (rts.activeDistPair.point1.value() - rts.activeDistPair.point2.value())
266 else if (rts.node2OnArm)
270 rts.selfCollDataVec[i].nodeName = rts.activeDistPair.node2;
271 rts.selfCollDataVec[i].otherName = rts.activeDistPair.node1;
272 rts.selfCollDataVec[i].minDistance =
273 static_cast<float>(rts.activeDistPair.minDistance);
275 rts.selfCollDataVec[i].point.x() =
276 static_cast<float>(rts.activeDistPair.point2->x());
277 rts.selfCollDataVec[i].point.y() =
278 static_cast<float>(rts.activeDistPair.point2->y());
279 rts.selfCollDataVec[i].point.z() =
280 static_cast<float>(rts.activeDistPair.point2->z());
284 rts.node = simoxNodeSet->getNode(rts.activeDistPair.node2);
287 rts.localTransformation.translation() =
288 rts.node->getGlobalPose().inverse() * rts.activeDistPair.point1.value();
290 rts.selfCollDataVec[i].jacobian =
292 ->computeJacobian(*rts.node,
293 simox::control::robot::JacobianParams{
294 .mode = simox::control::utils::CartesianSelection::Position,
295 .localTransformation = rts.localTransformation})
305 rts.selfCollDataVec[i].direction =
306 (rts.activeDistPair.point2.value() - rts.activeDistPair.point1.value())
312 "The indeces in the pointsOnArm vector must correspond"
313 "to a contact point pair, where at least one node is "
314 "located on the arm. \n There is a problem in the preFilter"
315 "method in the rtRun method.")
316 .deactivateSpam(1.0);
322 if (rts.selfCollDataVec[i].minDistance < 0.0f)
324 rts.selfCollDataVec[i].direction *= -1.0f;
325 rts.selfCollDataVec[i].minDistance = 0.0f;
328 if (rts.activeDistPair.point1->isApprox(*rts.activeDistPair.point2, 1e-8) and
329 rts.activeDistPair.normalVec != std::nullopt)
341 rts.selfCollDataVec[i].direction.x() =
342 static_cast<float>(rts.activeDistPair.normalVec->x());
343 rts.selfCollDataVec[i].direction.y() =
344 static_cast<float>(rts.activeDistPair.normalVec->y());
345 rts.selfCollDataVec[i].direction.z() =
346 static_cast<float>(rts.activeDistPair.normalVec->z());
349 rts.selfCollDataVec[i].direction.normalize();
355 rts.selfCollDataVec[i].repulsiveForce =
356 c.maxRepulsiveForce / std::pow(
c.distanceThreshold, 2) *
357 std::pow(rts.selfCollDataVec[i].minDistance -
c.distanceThreshold, 2);
358 rts.selfCollDataVec[i].localStiffness =
359 -2.0 *
c.maxRepulsiveForce / std::pow(
c.distanceThreshold, 2) *
360 (rts.selfCollDataVec[i].minDistance -
c.distanceThreshold);
363 rts.selfCollDataVec[i].repulsiveForce =
364 std::clamp(rts.selfCollDataVec[i].repulsiveForce, 0.0f,
c.maxRepulsiveForce);
370 rts.selfCollDataVec[i].projectedJacT =
371 (rts.selfCollDataVec[i].direction.transpose() * rts.selfCollDataVec[i].jacobian)
378 rts.selfCollDataVec[i].distanceVelocity =
379 rts.selfCollDataVec[i].projectedJacT.transpose() * qvelFiltered;
384 rts.selfCollDataVec[i].projectedMass =
385 1 / (rts.selfCollDataVec[i].projectedJacT.transpose() * rts.inertiaInverse *
386 rts.selfCollDataVec[i].projectedJacT);
390 rts.selfCollDataVec[i].damping =
391 2 *
std::sqrt(rts.selfCollDataVec[i].localStiffness) *
392 std::sqrt(rts.selfCollDataVec[i].projectedMass) *
c.dampingFactor;
396 rts.selfCollisionJointTorque +=
397 rts.selfCollDataVec[i].projectedJacT *
398 (rts.selfCollDataVec[i].repulsiveForce -
399 rts.selfCollDataVec[i].damping * rts.selfCollDataVec[i].distanceVelocity);
407 if (
c.testConfig == 1)
410 if (rts.activeDistPair.node1 ==
"ArmL8_Wri2" and rts.activeDistPair.node2 ==
"root")
412 rts.evalData[0].setDistValues(
413 rts.activeDistPair.node1,
414 rts.activeDistPair.node2,
415 static_cast<float>(rts.activeDistPair.minDistance));
416 if (rts.evalData[0].minDistance <
c.distanceThreshold)
418 rts.evalData[0].setCalcValues(rts.selfCollDataVec[i].jacobian,
419 rts.selfCollDataVec[i].repulsiveForce,
420 rts.selfCollDataVec[i].localStiffness,
421 rts.selfCollDataVec[i].projectedJacT,
422 rts.selfCollDataVec[i].distanceVelocity,
423 rts.selfCollDataVec[i].direction,
424 rts.selfCollDataVec[i].point,
425 rts.selfCollDataVec[i].damping,
426 rts.selfCollDataVec[i].projectedMass,
427 rts.selfCollDataVec[i].desiredNSColl);
430 else if (rts.activeDistPair.node2 ==
"ArmL8_Wri2" and
431 rts.activeDistPair.node1 ==
"root")
433 rts.evalData[0].setDistValues(
434 rts.activeDistPair.node2,
435 rts.activeDistPair.node1,
436 static_cast<float>(rts.activeDistPair.minDistance));
437 if (rts.evalData[0].minDistance <
c.distanceThreshold)
439 rts.evalData[0].setCalcValues(rts.selfCollDataVec[i].jacobian,
440 rts.selfCollDataVec[i].repulsiveForce,
441 rts.selfCollDataVec[i].localStiffness,
442 rts.selfCollDataVec[i].projectedJacT,
443 rts.selfCollDataVec[i].distanceVelocity,
444 rts.selfCollDataVec[i].direction,
445 rts.selfCollDataVec[i].point,
446 rts.selfCollDataVec[i].damping,
447 rts.selfCollDataVec[i].projectedMass,
448 rts.selfCollDataVec[i].desiredNSColl);
451 if (rts.activeDistPair.node1 ==
"ArmL8_Wri2" and
452 rts.activeDistPair.node2 ==
"ArmR8_Wri2")
454 rts.evalData[1].setDistValues(
455 rts.activeDistPair.node1,
456 rts.activeDistPair.node2,
457 static_cast<float>(rts.activeDistPair.minDistance));
458 if (rts.evalData[1].minDistance <
c.distanceThreshold)
460 rts.evalData[1].setCalcValues(rts.selfCollDataVec[i].jacobian,
461 rts.selfCollDataVec[i].repulsiveForce,
462 rts.selfCollDataVec[i].localStiffness,
463 rts.selfCollDataVec[i].projectedJacT,
464 rts.selfCollDataVec[i].distanceVelocity,
465 rts.selfCollDataVec[i].direction,
466 rts.selfCollDataVec[i].point,
467 rts.selfCollDataVec[i].damping,
468 rts.selfCollDataVec[i].projectedMass,
469 rts.selfCollDataVec[i].desiredNSColl);
472 else if (rts.activeDistPair.node2 ==
"ArmL8_Wri2" and
473 rts.activeDistPair.node1 ==
"ArmR8_Wri2")
475 rts.evalData[1].setDistValues(
476 rts.activeDistPair.node2,
477 rts.activeDistPair.node1,
478 static_cast<float>(rts.activeDistPair.minDistance));
479 if (rts.evalData[1].minDistance <
c.distanceThreshold)
481 rts.evalData[1].setCalcValues(rts.selfCollDataVec[i].jacobian,
482 rts.selfCollDataVec[i].repulsiveForce,
483 rts.selfCollDataVec[i].localStiffness,
484 rts.selfCollDataVec[i].projectedJacT,
485 rts.selfCollDataVec[i].distanceVelocity,
486 rts.selfCollDataVec[i].direction,
487 rts.selfCollDataVec[i].point,
488 rts.selfCollDataVec[i].damping,
489 rts.selfCollDataVec[i].projectedMass,
490 rts.selfCollDataVec[i].desiredNSColl);
493 if (rts.activeDistPair.node1 ==
"ArmL7_Wri1" and
494 rts.activeDistPair.node2 ==
"ArmR8_Wri2")
496 rts.evalData[2].setDistValues(
497 rts.activeDistPair.node1,
498 rts.activeDistPair.node2,
499 static_cast<float>(rts.activeDistPair.minDistance));
500 if (rts.evalData[2].minDistance <
c.distanceThreshold)
502 rts.evalData[2].setCalcValues(rts.selfCollDataVec[i].jacobian,
503 rts.selfCollDataVec[i].repulsiveForce,
504 rts.selfCollDataVec[i].localStiffness,
505 rts.selfCollDataVec[i].projectedJacT,
506 rts.selfCollDataVec[i].distanceVelocity,
507 rts.selfCollDataVec[i].direction,
508 rts.selfCollDataVec[i].point,
509 rts.selfCollDataVec[i].damping,
510 rts.selfCollDataVec[i].projectedMass,
511 rts.selfCollDataVec[i].desiredNSColl);
514 else if (rts.activeDistPair.node2 ==
"ArmL7_Wri1" and
515 rts.activeDistPair.node1 ==
"ArmR8_Wri2")
517 rts.evalData[2].setDistValues(
518 rts.activeDistPair.node2,
519 rts.activeDistPair.node1,
520 static_cast<float>(rts.activeDistPair.minDistance));
521 if (rts.evalData[2].minDistance <
c.distanceThreshold)
523 rts.evalData[2].setCalcValues(rts.selfCollDataVec[i].jacobian,
524 rts.selfCollDataVec[i].repulsiveForce,
525 rts.selfCollDataVec[i].localStiffness,
526 rts.selfCollDataVec[i].projectedJacT,
527 rts.selfCollDataVec[i].distanceVelocity,
528 rts.selfCollDataVec[i].direction,
529 rts.selfCollDataVec[i].point,
530 rts.selfCollDataVec[i].damping,
531 rts.selfCollDataVec[i].projectedMass,
532 rts.selfCollDataVec[i].desiredNSColl);
535 if (rts.activeDistPair.node1 ==
"ArmL8_Wri2" and
536 rts.activeDistPair.node2 ==
"ArmR7_Wri1")
538 rts.evalData[3].setDistValues(
539 rts.activeDistPair.node1,
540 rts.activeDistPair.node2,
541 static_cast<float>(rts.activeDistPair.minDistance));
542 if (rts.evalData[3].minDistance <
c.distanceThreshold)
544 rts.evalData[3].setCalcValues(rts.selfCollDataVec[i].jacobian,
545 rts.selfCollDataVec[i].repulsiveForce,
546 rts.selfCollDataVec[i].localStiffness,
547 rts.selfCollDataVec[i].projectedJacT,
548 rts.selfCollDataVec[i].distanceVelocity,
549 rts.selfCollDataVec[i].direction,
550 rts.selfCollDataVec[i].point,
551 rts.selfCollDataVec[i].damping,
552 rts.selfCollDataVec[i].projectedMass,
553 rts.selfCollDataVec[i].desiredNSColl);
556 else if (rts.activeDistPair.node2 ==
"ArmL8_Wri2" and
557 rts.activeDistPair.node1 ==
"ArmR7_Wri1")
559 rts.evalData[3].setDistValues(
560 rts.activeDistPair.node2,
561 rts.activeDistPair.node1,
562 static_cast<float>(rts.activeDistPair.minDistance));
563 if (rts.evalData[3].minDistance <
c.distanceThreshold)
565 rts.evalData[3].setCalcValues(rts.selfCollDataVec[i].jacobian,
566 rts.selfCollDataVec[i].repulsiveForce,
567 rts.selfCollDataVec[i].localStiffness,
568 rts.selfCollDataVec[i].projectedJacT,
569 rts.selfCollDataVec[i].distanceVelocity,
570 rts.selfCollDataVec[i].direction,
571 rts.selfCollDataVec[i].point,
572 rts.selfCollDataVec[i].damping,
573 rts.selfCollDataVec[i].projectedMass,
574 rts.selfCollDataVec[i].desiredNSColl);
577 if (rts.activeDistPair.node1 ==
"ArmL8_Wri2" and
578 rts.activeDistPair.node2 ==
"Neck_2_Pitch")
580 rts.evalData[4].setDistValues(
581 rts.activeDistPair.node1,
582 rts.activeDistPair.node2,
583 static_cast<float>(rts.activeDistPair.minDistance));
584 if (rts.evalData[4].minDistance <
c.distanceThreshold)
586 rts.evalData[4].setCalcValues(rts.selfCollDataVec[i].jacobian,
587 rts.selfCollDataVec[i].repulsiveForce,
588 rts.selfCollDataVec[i].localStiffness,
589 rts.selfCollDataVec[i].projectedJacT,
590 rts.selfCollDataVec[i].distanceVelocity,
591 rts.selfCollDataVec[i].direction,
592 rts.selfCollDataVec[i].point,
593 rts.selfCollDataVec[i].damping,
594 rts.selfCollDataVec[i].projectedMass,
595 rts.selfCollDataVec[i].desiredNSColl);
598 else if (rts.activeDistPair.node2 ==
"ArmL8_Wri2" and
599 rts.activeDistPair.node1 ==
"Neck_2_Pitch")
601 rts.evalData[4].setDistValues(
602 rts.activeDistPair.node2,
603 rts.activeDistPair.node1,
604 static_cast<float>(rts.activeDistPair.minDistance));
605 if (rts.evalData[4].minDistance <
c.distanceThreshold)
607 rts.evalData[4].setCalcValues(rts.selfCollDataVec[i].jacobian,
608 rts.selfCollDataVec[i].repulsiveForce,
609 rts.selfCollDataVec[i].localStiffness,
610 rts.selfCollDataVec[i].projectedJacT,
611 rts.selfCollDataVec[i].distanceVelocity,
612 rts.selfCollDataVec[i].direction,
613 rts.selfCollDataVec[i].point,
614 rts.selfCollDataVec[i].damping,
615 rts.selfCollDataVec[i].projectedMass,
616 rts.selfCollDataVec[i].desiredNSColl);
619 if (rts.activeDistPair.node1 ==
"ArmL8_Wri2" and
620 rts.activeDistPair.node2 ==
"TorsoJoint")
622 rts.evalData[5].setDistValues(
623 rts.activeDistPair.node1,
624 rts.activeDistPair.node2,
625 static_cast<float>(rts.activeDistPair.minDistance));
626 if (rts.evalData[5].minDistance <
c.distanceThreshold)
628 rts.evalData[5].setCalcValues(rts.selfCollDataVec[i].jacobian,
629 rts.selfCollDataVec[i].repulsiveForce,
630 rts.selfCollDataVec[i].localStiffness,
631 rts.selfCollDataVec[i].projectedJacT,
632 rts.selfCollDataVec[i].distanceVelocity,
633 rts.selfCollDataVec[i].direction,
634 rts.selfCollDataVec[i].point,
635 rts.selfCollDataVec[i].damping,
636 rts.selfCollDataVec[i].projectedMass,
637 rts.selfCollDataVec[i].desiredNSColl);
640 else if (rts.activeDistPair.node2 ==
"ArmL8_Wri2" and
641 rts.activeDistPair.node1 ==
"TorsoJoint")
643 rts.evalData[5].setDistValues(
644 rts.activeDistPair.node2,
645 rts.activeDistPair.node1,
646 static_cast<float>(rts.activeDistPair.minDistance));
647 if (rts.evalData[5].minDistance <
c.distanceThreshold)
649 rts.evalData[5].setCalcValues(rts.selfCollDataVec[i].jacobian,
650 rts.selfCollDataVec[i].repulsiveForce,
651 rts.selfCollDataVec[i].localStiffness,
652 rts.selfCollDataVec[i].projectedJacT,
653 rts.selfCollDataVec[i].distanceVelocity,
654 rts.selfCollDataVec[i].direction,
655 rts.selfCollDataVec[i].point,
656 rts.selfCollDataVec[i].damping,
657 rts.selfCollDataVec[i].projectedMass,
658 rts.selfCollDataVec[i].desiredNSColl);
661 if (rts.activeDistPair.node1 ==
"ArmL5_Elb1" and
662 rts.activeDistPair.node2 ==
"TorsoJoint")
664 rts.evalData[6].setDistValues(
665 rts.activeDistPair.node1,
666 rts.activeDistPair.node2,
667 static_cast<float>(rts.activeDistPair.minDistance));
668 if (rts.evalData[6].minDistance <
c.distanceThreshold)
670 rts.evalData[6].setCalcValues(rts.selfCollDataVec[i].jacobian,
671 rts.selfCollDataVec[i].repulsiveForce,
672 rts.selfCollDataVec[i].localStiffness,
673 rts.selfCollDataVec[i].projectedJacT,
674 rts.selfCollDataVec[i].distanceVelocity,
675 rts.selfCollDataVec[i].direction,
676 rts.selfCollDataVec[i].point,
677 rts.selfCollDataVec[i].damping,
678 rts.selfCollDataVec[i].projectedMass,
679 rts.selfCollDataVec[i].desiredNSColl);
682 else if (rts.activeDistPair.node2 ==
"ArmL5_Elb1" and
683 rts.activeDistPair.node1 ==
"TorsoJoint")
685 rts.evalData[6].setDistValues(
686 rts.activeDistPair.node2,
687 rts.activeDistPair.node1,
688 static_cast<float>(rts.activeDistPair.minDistance));
689 if (rts.evalData[6].minDistance <
c.distanceThreshold)
691 rts.evalData[6].setCalcValues(rts.selfCollDataVec[i].jacobian,
692 rts.selfCollDataVec[i].repulsiveForce,
693 rts.selfCollDataVec[i].localStiffness,
694 rts.selfCollDataVec[i].projectedJacT,
695 rts.selfCollDataVec[i].distanceVelocity,
696 rts.selfCollDataVec[i].direction,
697 rts.selfCollDataVec[i].point,
698 rts.selfCollDataVec[i].damping,
699 rts.selfCollDataVec[i].projectedMass,
700 rts.selfCollDataVec[i].desiredNSColl);
708 CollisionAvoidanceController::calculateJointLimitTorque(Config&
c,
709 RtStatusForSafetyStrategy& rts,
710 Eigen::VectorXf& qpos,
711 Eigen::VectorXf& qvelFiltered)
717 rts.jointLimitJointTorque.setZero();
725 for (
size_t i = 0; i < rts.jointLimitData.size(); ++i)
727 if (rts.jointLimitData[i].isLimitless)
730 auto& joint = rts.jointLimitData[i];
731 rts.jointInertia = rts.inertia(i, i);
732 if (qpos[i] < rts.jointLimitData[i].qposThresholdLow)
734 joint.repulsiveTorque =
735 c.maxRepulsiveTorque / std::pow(rts.jointLimitData[i].thresholdRange, 2) *
736 std::pow(rts.jointLimitData[i].qposThresholdLow - qpos[i], 2);
738 joint.repulsiveTorque =
739 std::clamp(joint.repulsiveTorque, 0.0f,
c.maxRepulsiveTorque);
741 rts.localStiffnessJointLim = 2 *
c.maxRepulsiveTorque /
742 std::pow(rts.jointLimitData[i].thresholdRange, 2) *
743 (rts.jointLimitData[i].qposThresholdLow - qpos[i]);
746 rts.dampingJointLim = 2 *
std::sqrt(rts.jointInertia) *
747 std::sqrt(rts.localStiffnessJointLim) *
c.dampingFactor;
750 joint.totalDamping = rts.dampingJointLim * qvelFiltered[i];
751 rts.jointLimitJointTorque(i) =
752 joint.repulsiveTorque - rts.dampingJointLim * qvelFiltered[i];
756 else if (qpos[i] > rts.jointLimitData[i].qposThresholdHigh)
758 joint.repulsiveTorque =
759 c.maxRepulsiveTorque / std::pow(rts.jointLimitData[i].thresholdRange, 2) *
760 std::pow(qpos[i] - rts.jointLimitData[i].qposThresholdHigh, 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 (qpos[i] - rts.jointLimitData[i].qposThresholdHigh);
771 rts.dampingJointLim = 2 *
std::sqrt(rts.jointInertia) *
772 std::sqrt(rts.localStiffnessJointLim) *
c.dampingFactor;
774 joint.totalDamping = rts.dampingJointLim * qvelFiltered[i];
775 rts.jointLimitJointTorque(i) =
776 -(joint.repulsiveTorque + rts.dampingJointLim * qvelFiltered[i]);
783 CollisionAvoidanceController::calculateSelfCollisionNullspace(Config&
c,
784 RtStatusForSafetyStrategy& rts)
786 rts.selfCollNullSpace.setIdentity();
792 rts.k1 = rts.selfCollisionNullSpaceWeights(0);
793 rts.k2 = rts.selfCollisionNullSpaceWeights(1);
794 rts.k3 = rts.selfCollisionNullSpaceWeights(2);
795 rts.k4 = rts.selfCollisionNullSpaceWeights(3);
799 for (
auto& active : rts.selfCollDataVec)
802 if (active.minDistance <
c.selfCollActivatorZ1)
805 rts.desiredNullSpace = 0.0f;
807 else if (
c.selfCollActivatorZ1 <= active.minDistance &&
808 active.minDistance <=
c.selfCollActivatorZ2)
811 rts.desiredNullSpace = rts.k1 * std::pow(active.minDistance, 3) +
812 rts.k2 * std::pow(active.minDistance, 2) +
813 rts.k3 * active.minDistance + rts.k4;
814 if (rts.desiredNullSpace > 1.0f)
817 <<
"desired null space value should not be higher than 1.0, was "
818 << rts.desiredNullSpace
819 <<
", in self-collision null space calulation, weights: " << rts.k1 <<
", "
820 << rts.k2 <<
", " << rts.k3 <<
", " << rts.k4;
826 rts.desiredNullSpace = 1.0f;
830 active.desiredNSColl = rts.desiredNullSpace;
831 rts.desiredNullSpace =
std::clamp(rts.desiredNullSpace, 0.0f, 1.0f);
834 rts.normalizedJacT = active.projectedJacT.normalized();
840 rts.tempNullSpaceMatrix = I - (rts.normalizedJacT * (1.0f - rts.desiredNullSpace) *
841 rts.normalizedJacT.transpose());
843 if (
c.onlyLimitCollDirection)
847 for (
int i = 0; i < rts.impedanceJointTorque.rows(); ++i)
849 if ((active.projectedJacT(i) < 0.0f and rts.impedanceJointTorque(i) < 0.0f) ||
850 (active.projectedJacT(i) > 0.0f and rts.impedanceJointTorque(i) > 0.0f))
853 rts.tempNullSpaceMatrix(i, i) = 1.0f;
859 rts.selfCollNullSpace *= rts.tempNullSpaceMatrix;
863 if (
c.testConfig == 1)
865 if (active.nodeName ==
"ArmL8_Wri2")
867 rts.evalData[0].desiredNSColl = active.desiredNSColl;
868 rts.evalData[1].desiredNSColl = active.desiredNSColl;
869 rts.evalData[3].desiredNSColl = active.desiredNSColl;
870 rts.evalData[4].desiredNSColl = active.desiredNSColl;
872 else if (active.nodeName ==
"ArmL7_Wri1")
874 rts.evalData[2].desiredNSColl = active.desiredNSColl;
881 CollisionAvoidanceController::calculateJointLimitNullspace(Config&
c,
882 RtStatusForSafetyStrategy& rts,
883 Eigen::VectorXf& qpos)
886 rts.jointLimNullSpace.setIdentity();
893 for (
size_t i = 0; i < rts.jointLimitData.size(); ++i)
895 auto& joint = rts.jointLimitData[i];
898 rts.k1Lo = joint.jointLimitNullSpaceWeightsLow(0);
899 rts.k2Lo = joint.jointLimitNullSpaceWeightsLow(1);
900 rts.k3Lo = joint.jointLimitNullSpaceWeightsLow(2);
901 rts.k4Lo = joint.jointLimitNullSpaceWeightsLow(3);
902 rts.k1Hi = joint.jointLimitNullSpaceWeightsHigh(0);
903 rts.k2Hi = joint.jointLimitNullSpaceWeightsHigh(1);
904 rts.k3Hi = joint.jointLimitNullSpaceWeightsHigh(2);
905 rts.k4Hi = joint.jointLimitNullSpaceWeightsHigh(3);
909 if (not joint.isLimitless)
912 if (qpos[i] < joint.qposZ1Low)
915 rts.desiredNullSpace = 0.0f;
917 else if (joint.qposZ1Low <= qpos[i] && qpos[i] <= joint.qposZ2Low)
920 rts.desiredNullSpace = rts.k1Lo * std::pow(qpos[i], 3) +
921 rts.k2Lo * std::pow(qpos[i], 2) + rts.k3Lo * qpos[i] +
923 if (rts.desiredNullSpace > 1.0f)
926 <<
"desired null space value should not be higher than 1.0, was "
927 << rts.desiredNullSpace
928 <<
", approaching lower joint limit, weights: " << rts.k1Lo <<
", "
929 << rts.k2Lo <<
", " << rts.k3Lo <<
", " << rts.k4Lo;
932 else if (joint.qposZ2High <= qpos[i] && qpos[i] <= joint.qposZ1High)
935 rts.desiredNullSpace = rts.k1Hi * std::pow(qpos[i], 3) +
936 rts.k2Hi * std::pow(qpos[i], 2) + rts.k3Hi * qpos[i] +
938 if (rts.desiredNullSpace > 1.0f)
941 <<
"desired null space value should not be higher than 1.0, was "
942 << rts.desiredNullSpace
943 <<
", approaching upper joint limit, weights: " << rts.k1Hi <<
", "
944 << rts.k2Hi <<
", " << rts.k3Hi <<
", " << rts.k4Hi;
947 else if (joint.qposZ1High < qpos[i])
950 rts.desiredNullSpace = 0.0f;
955 rts.desiredNullSpace = 1.0f;
959 joint.desiredNSjointLim = rts.desiredNullSpace;
960 rts.desiredNullSpace =
std::clamp(rts.desiredNullSpace, 0.0f, 1.0f);
964 rts.jointLimNullSpace(i, i) = 1.0f - (1.0f - rts.desiredNullSpace);
984 constraintMatrix << std::pow(z1, 3), std::pow(z1, 2), z1, 1, std::pow(z2, 3),
985 std::pow(z2, 2), z2, 1, 3 * std::pow(z1, 2), 2 * z1, 1, 0, 3 * std::pow(z2, 2), 2 * z2,
993 return constraintMatrix.colPivHouseholderQr().solve(b);
1003 std::shared_ptr<std::vector<int>>& pointsOnArm,
1004 int pointsOnArmIndex,
1005 std::shared_ptr<simox::control::geodesics::metric::Inertia>& inertiaInstance,
1006 std::vector<std::string>& selfCollisionNodes,
1007 Eigen::VectorXf& qpos,
1008 Eigen::VectorXf& qvelFiltered,
1114 Eigen::VectorXd qposXd = qpos.cast<
double>();
1116 inertiaInstance->compute_metric(qpos.cast<
double>(),
false).metric.cast<
float>();
1122 if (
c.enableSelfCollisionAvoidance)
1125 double timeMeasure = IceUtil::Time::now().toMicroSecondsDouble();
1126 calculateSelfCollisionTorque(
c,
1134 IceUtil::Time::now().toMicroSecondsDouble() - timeMeasure;
1136 if (
c.enableJointLimitAvoidance)
1139 double timeMeasure = IceUtil::Time::now().toMicroSecondsDouble();
1140 calculateJointLimitTorque(
c, rtStatus, qpos, qvelFiltered);
1142 IceUtil::Time::now().toMicroSecondsDouble() - timeMeasure;
1144 if (!
c.samePriority)
1146 if (
c.enableSelfCollisionAvoidance)
1149 double timeMeasure = IceUtil::Time::now().toMicroSecondsDouble();
1150 calculateSelfCollisionNullspace(
c, rtStatus);
1152 IceUtil::Time::now().toMicroSecondsDouble() - timeMeasure;
1154 if (
c.enableJointLimitAvoidance)
1157 double timeMeasure = IceUtil::Time::now().toMicroSecondsDouble();
1158 calculateJointLimitNullspace(
c, rtStatus, qpos);
1160 IceUtil::Time::now().toMicroSecondsDouble() - timeMeasure;
1166 if (
c.filterSafetyValues)
1247 else if (
c.enableSelfCollisionAvoidance and
c.enableJointLimitAvoidance)
1251 if (
c.topPrioritySelfCollisionAvoidance)
1277 else if (
c.topPriorityJointLimitAvoidance)
1324 else if (
c.enableSelfCollisionAvoidance)
1342 else if (
c.enableJointLimitAvoidance)
1393 const unsigned int nDoF,
1394 const unsigned int maxCollisionPairs,
1395 VirtualRobot::RobotNodeSetPtr& rns)
1452 Eigen::Vector3d point1(0.0, 0.0, 0.0);
1453 Eigen::Vector3d point2(0.0, 0.0, 0.0);
1454 Eigen::Vector3d
norm(0.0, 0.0, 0.0);
1477 CollisionAvoidanceController::RtStatusForSafetyStrategy::initJointLimtDataVec(
c, nDoF, rns);
1512 CollisionAvoidanceController::RtStatusForSafetyStrategy::initJointLimtDataVec(
1514 const unsigned int nDoF,
1515 VirtualRobot::RobotNodeSetPtr& rns)
1520 localStiffnessJointLim = 0.0;
1521 dampingJointLim = 0.0;
1532 jointLimitData.resize(nDoF);
1535 for (
size_t i = 0; i < nDoF; ++i)
1537 jointLimitData[i].jointName = rns->getNode(i)->getName();
1538 jointLimitData[i].isLimitless = rns->getNode(i)->isLimitless();
1540 if (not jointLimitData[i].isLimitless)
1542 jointLimitData[i].qLimLow = rns->getNode(i)->getJointLimitLow();
1543 jointLimitData[i].qLimHigh = rns->getNode(i)->getJointLimitHigh();
1548 for (
auto& joint : jointLimitData)
1550 if (not joint.isLimitless)
1553 float qRange = joint.qLimHigh - joint.qLimLow;
1554 joint.thresholdRange =
c.jointRangeBufferZone * qRange;
1555 joint.qposThresholdLow = joint.qLimLow + joint.thresholdRange;
1556 joint.qposThresholdHigh = joint.qLimHigh - joint.thresholdRange;
1557 float qposZ1 =
c.jointRangeBufferZoneZ1 * qRange;
1558 float qposZ2 =
c.jointRangeBufferZoneZ2 * qRange;
1559 joint.qposZ1Low = joint.qLimLow + qposZ1;
1560 joint.qposZ2Low = joint.qLimLow + qposZ2;
1561 joint.qposZ1High = joint.qLimHigh - qposZ1;
1562 joint.qposZ2High = joint.qLimHigh - qposZ2;
1563 joint.jointLimitNullSpaceWeightsLow =
1565 joint.jointLimitNullSpaceWeightsHigh =
1641 if (cfg.topPrioritySelfCollisionAvoidance)
1645 (cfg.topPrioritySelfCollisionAvoidance == !cfg.topPriorityJointLimitAvoidance));
1647 if (cfg.topPriorityJointLimitAvoidance)
1651 (cfg.topPrioritySelfCollisionAvoidance == !cfg.topPriorityJointLimitAvoidance));