ObjectCollisionAvoidance.cpp
Go to the documentation of this file.
2
3#include <simox/control/dynamics/RBDLModel.h>
4
6
8{
10 const simox::control::robot::NodeSetInterface* nodeSet) :
12 {
13 controllerHierarchy.reserve(4); // number of torque types to consider
14 }
15
16 void
18 const common::control_law::arondto::ObjectCollisionAvoidanceConfig& c,
19 RtStatusForSafetyStrategy& rtStatus) const
20 {
21 rtStatus.objectCollNullSpace.setIdentity();
22
25
27 rtStatus.objectCollK1 = rtStatus.objectCollisionNullSpaceWeights(0);
28 rtStatus.objectCollK2 = rtStatus.objectCollisionNullSpaceWeights(1);
29 rtStatus.objectCollK3 = rtStatus.objectCollisionNullSpaceWeights(2);
30 rtStatus.objectCollK4 = rtStatus.objectCollisionNullSpaceWeights(3);
31
33
34 for (unsigned int i = rtStatus.objectCollDataIndex; i < rtStatus.activeCollPairsNum; i++)
35 {
36 auto& active = rtStatus.collDataVec[i];
37
38 /// get desired null space value based on proximity to collision
39 if (active.minDistance < c.objectCollActivatorZ1)
40 {
41 /// full locking in direction of collision
42 rtStatus.desiredNullSpace = 0.0f;
43 }
44 else if (c.objectCollActivatorZ1 <= active.minDistance &&
45 active.minDistance <= c.objectCollActivatorZ2)
46 {
47 /// in transition state
48 rtStatus.desiredNullSpace =
49 rtStatus.objectCollK1 * std::pow(active.minDistance, 3) +
50 rtStatus.objectCollK2 * std::pow(active.minDistance, 2) +
51 rtStatus.objectCollK3 * active.minDistance + rtStatus.objectCollK4;
52 if (rtStatus.desiredNullSpace > 1.0f)
53 {
54 ARMARX_WARNING << "desired null space value should not be higher than 1.0, was "
55 << rtStatus.desiredNullSpace
56 << ", in collision null space calulation, weights: "
57 << rtStatus.objectCollK1 << ", " << rtStatus.objectCollK2 << ", "
58 << rtStatus.objectCollK3 << ", " << rtStatus.objectCollK4;
59 }
60 }
61 else
62 {
63 /// unrestricted movement in direction of collision
64 rtStatus.desiredNullSpace = 1.0f;
65 }
66
67 active.desiredNSColl = rtStatus.desiredNullSpace;
68 rtStatus.desiredNullSpace = std::clamp(rtStatus.desiredNullSpace, 0.0f, 1.0f);
70 /// normalize projected Jacobian
71 rtStatus.objectCollNormalizedJacT = active.projectedJacT.normalized();
72
74
77 (rtStatus.objectCollNormalizedJacT * (1.0f - rtStatus.desiredNullSpace) *
78 rtStatus.objectCollNormalizedJacT.transpose());
79
80 if (c.onlyLimitCollDirection)
81 {
82 /// check, whether impedance joint torque acts against the collision direction
83 ARMARX_CHECK_EQUAL(active.projectedJacT.rows(),
84 rtStatus.impedanceJointTorque.rows());
85 for (int i = 0; i < rtStatus.impedanceJointTorque.rows(); ++i)
86 {
87 if ((active.projectedJacT(i) < 0.0f and
88 rtStatus.impedanceJointTorque(i) < 0.0f) ||
89 (active.projectedJacT(i) > 0.0f and
90 rtStatus.impedanceJointTorque(i) > 0.0f))
91 {
92 // if both have the same sign (both negative or both positive), do not limit DoF
93 rtStatus.objectCollTempNullSpaceMatrix(i, i) = 1.0f;
94 }
95 }
96 }
97 /// project desired null space in corresponding direction via the Norm-Jacobian
99 // todo: clamp the diagonal values between 0 and 1
100 }
101 }
102
103 void
105 const Config& c,
107 RecoveryState& rState,
108 const DistanceResults& externalCollisionPairs,
109 const CollisionRobotIndices& collisionRobotIndices,
110 const Eigen::VectorXf& qvelFiltered,
111 double deltaT) const
112 {
113
114 /// collision avoidance algorithm following the methods in Dietrich et al. (2012):
115 ///
116 /// A. Dietrich, T. Wimbock, A. Albu-Schaffer and G. Hirzinger, "Integration of Reactive,
117 /// Torque-Based Self-Collision Avoidance Into a Task Hierarchy," in IEEE Transactions on
118 /// Robotics, vol. 28, no. 6, pp. 1278-1293, Dec. 2012, doi: 10.1109/TRO.2012.2208667.
119 ///
120 /// see: https://ieeexplore.ieee.org/document/6255795
121 ///
122 /// method:
123 ///
124 /// computes the joint torques to avoid collisions -> collisionJointTorque
125
126 if (externalCollisionPairs.empty())
127 {
128 return;
129 }
130
131 /// clear values before new cycle
132 rts.objectCollisionJointTorque.setZero();
133
134 if (!c.enableSelfCollisionAvoidance)
135 {
136 rts.objectCollDataIndex = 0;
137 rts.activeCollPairsNum = 0;
138 }
139
140 // clear values before new cycle, starting from object collision data index
141 for (size_t i = rts.objectCollDataIndex; i < rts.collDataVec.size(); ++i)
142 {
143 rts.collDataVec[i].clearValues();
144 }
145
146 /// when collDistanceThresholdInit is smaller than recoveryDistanceElapseMeter
147 /// (usually means it is zero), we need to initilize it to the smallest collision distance
148 /// plus a recoveryDistanceElapseMeter.
149 float& thresholdInit = rState.collDistanceThresholdInit;
150 if (c.enableCollisionRecoveryOnStartup and (thresholdInit < c.recoveryDistanceElapseMeter))
151 {
152 thresholdInit = c.objectDistanceThreshold;
153 for (const DistanceResult& collisionPair : externalCollisionPairs)
154 {
155 float minDist = static_cast<float>(collisionPair.minDistance);
156 if (minDist < thresholdInit)
157 {
158 thresholdInit = std::max(minDist, 0.0f);
159 }
160 }
161 thresholdInit =
162 std::min(c.objectDistanceThreshold, thresholdInit + c.recoveryDistanceElapseMeter);
163 }
164
165 rState.update(c, rts, deltaT);
166
167
168 /// handling of external collision pairs
169 for (const DistanceResult& collisionPair : externalCollisionPairs)
170 {
171
172 if (rts.activeCollPairsNum >= rts.collDataVec.size())
173 {
175 "CollisionAvoidanceController",
176 "Number of active collision pairs exceeds the allocated memory");
177 break;
178 }
179
180 if (static_cast<float>(collisionPair.minDistance) >= rState.collDistanceThreshold)
181 {
182 continue;
183 }
184
185 /// only node1 is on the robot
186 if (collisionRobotIndices.count(collisionPair.node1) == 0)
187 {
188 continue;
189 }
190
191 ARMARX_CHECK(collisionPair.hasPoints());
192
193 auto& externalCollDataVec = rts.collDataVec[rts.activeCollPairsNum++];
194
195 externalCollDataVec.minDistance = static_cast<float>(collisionPair.minDistance);
196
197 externalCollDataVec.node1 = collisionPair.node1;
198 externalCollDataVec.node2 = collisionPair.node2;
199 externalCollDataVec.point1 = collisionPair.point1->cast<float>();
200 externalCollDataVec.point2 = collisionPair.point2->cast<float>();
201 auto node1Type = collisionPair.node1Type;
202 // auto node2Type = collisionPair.node2Type;
203
204 // direction is pointing away from collision
205 externalCollDataVec.direction = externalCollDataVec.point1 - externalCollDataVec.point2;
206
207 if (externalCollDataVec.minDistance < 0.0f)
208 {
209 externalCollDataVec.minDistance = 0.0f;
210
211 // check for overlapping objects (returned points are exactly the same)
212 if (externalCollDataVec.point1.isApprox(externalCollDataVec.point2, 1e-8) and
213 collisionPair.normalVec != std::nullopt)
214 {
215 /// if the points are the same, normalVec comes with a value
216
217 // todo: how to make sure the normalVec is always pointing away from the
218 // collision, in normally the vector points out from the contact point within
219 // the sphere
220 // issue: if the arm is modeled with a sphere, it will point towards the collision
221 // No faulty behavior has been detected so far, however there is the possibility
222 // to get a direction vector pointing towards the collision
223
224 // solution: check if the node is a sphere, if the repulsive force is
225 // suppose to apply on the sphere, use the negative normal direction
226 if (node1Type == hpp::fcl::NODE_TYPE::GEOM_SPHERE)
227 {
228 externalCollDataVec.direction =
229 -1.0 * collisionPair.normalVec->cast<float>();
230 }
231 else
232 {
233 externalCollDataVec.direction = collisionPair.normalVec->cast<float>();
234 }
235 }
236 else
237 {
238 externalCollDataVec.direction *= -1.0f;
239 }
240 }
241
242 externalCollDataVec.direction.normalize();
243
245 externalCollDataVec,
246 c,
247 rts,
248 collisionRobotIndices,
249 qvelFiltered,
251 c.objectDistanceThreshold,
252 rState.collDistanceThreshold);
253 }
254 }
255
256 /// --------------------------------- main rt-loop ------------------------------------------
257
258 void
261 RecoveryState& rStateSelfColl,
262 RecoveryState& rStateObjColl,
263 const DistanceResults& collisionPairs,
264 const DistanceResults& externalCollisionPairs,
265 const CollisionRobotIndices& collisionRobotIndices,
266 DynamicsModel& dynamicsModel,
267 float torqueLimit,
268 float jointVelLimit,
269 TSCtrlRtStatus& rts)
270 {
271 /// run in rt thread
272 /// ----------------------------- inertia calculations --------------------------------------------------
273 dynamicsModel.getInertiaMatrix(rts.jointPosition.cast<double>(), rtStatus.inertia);
274 rts.inertia = rtStatus.inertia;
275
276 // rtStatus.inertiaInverse = rtStatus.inertia.cast<float>().inverse();
277 // inertia is positive definite matrix
278 rtStatus.inertiaInverse = rtStatus.inertia.cast<float>().llt().solve(getIdentityMat());
279
280 /// ----------------------------- safety constraints --------------------------------------------------
281 if (c.enableSelfCollisionAvoidance)
282 {
283 // calculation of self-collision avoidance torque
284 const double timeMeasure = IceUtil::Time::now().toMicroSecondsDouble();
286 rtStatus,
287 rStateSelfColl,
288 collisionPairs,
289 collisionRobotIndices,
290 rts.qvelFiltered,
291 rts.deltaT);
292 rtStatus.collisionTorqueTime =
293 IceUtil::Time::now().toMicroSecondsDouble() - timeMeasure;
294 }
295 if (c.enableObjectCollisionAvoidance)
296 {
297 // calculation of external collision avoidance torque
298 const double timeMeasure = IceUtil::Time::now().toMicroSecondsDouble();
300 rtStatus,
301 rStateObjColl,
302 externalCollisionPairs,
303 collisionRobotIndices,
304 rts.qvelFiltered,
305 rts.deltaT);
306 rtStatus.collisionTorqueTime +=
307 IceUtil::Time::now().toMicroSecondsDouble() - timeMeasure;
308 }
309 if (c.enableJointLimitAvoidance)
310 {
311 // calculation of joint limit avoidance torque
312 const double timeMeasure = IceUtil::Time::now().toMicroSecondsDouble();
314 rtStatus.jointLimitTorqueTime =
315 IceUtil::Time::now().toMicroSecondsDouble() - timeMeasure;
316 }
317
318 if (!c.samePriority)
319 {
320 if (c.enableSelfCollisionAvoidance)
321 {
322 // calculation of null space matrix for self-collision avoidance
323 const double timeMeasure = IceUtil::Time::now().toMicroSecondsDouble();
325 rtStatus.selfCollNullspaceTime =
326 IceUtil::Time::now().toMicroSecondsDouble() - timeMeasure;
327 }
328 if (c.enableObjectCollisionAvoidance)
329 {
330 // calculation of null space matrix for external collision avoidance
331 const double timeMeasure = IceUtil::Time::now().toMicroSecondsDouble();
333 rtStatus.objectCollNullspaceTime =
334 IceUtil::Time::now().toMicroSecondsDouble() - timeMeasure;
335 }
336 if (c.enableJointLimitAvoidance)
337 {
338 // calculation of null space matrix for joint limit avoidance
339 const double timeMeasure = IceUtil::Time::now().toMicroSecondsDouble();
341 rtStatus.jointLimitNullspaceTime =
342 IceUtil::Time::now().toMicroSecondsDouble() - timeMeasure;
343 }
344 }
346
347 /// --------------------------- apply EMA low pass filter -----------------------------------------------
348 if (c.filterSafetyValues)
349 {
350 /// filter safety constraint values using EMA low pass filter
351 for (int i = 0; i < rtStatus.selfCollisionJointTorque.size(); ++i)
352 {
353 rtStatus.selfCollisionTorqueFiltered(i) =
354 (1 - c.safetyValFilter) * rtStatus.selfCollisionTorqueFiltered(i) +
355 c.safetyValFilter * rtStatus.selfCollisionJointTorque(i);
356 }
357 for (int i = 0; i < rtStatus.objectCollisionJointTorque.size(); ++i)
358 {
360 (1 - c.safetyValFilter) * rtStatus.objectCollisionTorqueFiltered(i) +
361 c.safetyValFilter * rtStatus.objectCollisionJointTorque(i);
362 }
363 for (int i = 0; i < rtStatus.jointLimitJointTorque.size(); ++i)
364 {
365 rtStatus.jointLimitTorqueFiltered(i) =
366 (1 - c.safetyValFilter) * rtStatus.jointLimitTorqueFiltered(i) +
367 c.safetyValFilter * rtStatus.jointLimitJointTorque(i);
368 }
369
370 for (int i = 0; i < rtStatus.selfCollNullSpace.diagonalSize(); ++i)
371 {
372 // the computed values are only on the diagonal, so only these need to be filtered
373 rtStatus.selfCollNullSpaceFiltered(i, i) =
374 (1 - c.safetyValFilter) * rtStatus.selfCollNullSpaceFiltered(i, i) +
375 c.safetyValFilter * rtStatus.selfCollNullSpace(i, i);
376 }
377 for (int i = 0; i < rtStatus.objectCollNullSpace.diagonalSize(); ++i)
378 {
379 // the computed values are only on the diagonal, so only these need to be filtered
380 rtStatus.objectCollNullSpaceFiltered(i, i) =
381 (1 - c.safetyValFilter) * rtStatus.objectCollNullSpaceFiltered(i, i) +
382 c.safetyValFilter * rtStatus.objectCollNullSpace(i, i);
383 }
384 for (int i = 0; i < rtStatus.jointLimNullSpace.diagonalSize(); ++i)
385 {
386 // the computed values are only on the diagonal, so only these need to be filtered
387 rtStatus.jointLimNullSpaceFiltered(i, i) =
388 (1 - c.safetyValFilter) * rtStatus.jointLimNullSpaceFiltered(i, i) +
389 c.safetyValFilter * rtStatus.jointLimNullSpace(i, i);
390 }
391 /// assign filtered values
396
399 }
400
402 /// ----------------------------- hierarchical control --------------------------------------------------
403 /// The following control hierarchies are considered:
404 ///
405 /// there are 4 components generating torque:
406 /// - SelfCollisionAvoidance
407 /// - ObjectCollisionAvoidance
408 /// - JointLimitAvoidance
409 /// - Impedance
410 ///
411 /// For each of the enabled components a priority is loaded from the config.
412 /// The impedance component is always enabled.
413 ///
414 /// The components are processed in descending order from
415 /// low priority (high priority value) ===> high priority (low priority value)
416 ///
417 /// If two components a and b have the same priority value their torques are added and
418 /// their null spaces combined:
419 /// torque_combined = torque_a + torque_b
420 /// null_space_combined = null_space_a * null_space_b
421 ///
422 /// The torques of two component groups a and b (with a representing all components with a higher priority value
423 /// than priority_b and b representing all components with a priority value of priority_b) are calculated like this:
424 /// torque_combined = torque_b + (null_space_b * torque_a)
425 ///
426 /// Iteratively all torques are combined this way.
427
428 // ARMARX_INFO << VAROUT(c.samePriority);
429 controllerHierarchy.clear();
430
431 if (c.enableSelfCollisionAvoidance)
432 {
433 if (rtStatus.selfColAdmInterface.active)
434 {
435 rtStatus.selfColAdmInterface.run(
436 rtStatus.selfCollisionJointTorque, jointVelLimit, rts);
437 controllerHierarchy.emplace_back(c.selfCollisionAvoidancePriority,
438 std::ref(rtStatus.selfColAdmInterface.jointVel),
439 std::ref(rtStatus.selfCollNullSpace));
440 }
441 else
442 {
443 controllerHierarchy.emplace_back(c.selfCollisionAvoidancePriority,
444 std::ref(rtStatus.selfCollisionJointTorque),
445 std::ref(rtStatus.selfCollNullSpace));
446 }
447 }
448 if (c.enableObjectCollisionAvoidance)
449 {
450 if (rtStatus.objColAdmInterface.active)
451 {
452 rtStatus.objColAdmInterface.run(
453 rtStatus.objectCollisionJointTorque, jointVelLimit, rts);
454 controllerHierarchy.emplace_back(c.objectCollisionAvoidancePriority,
455 std::ref(rtStatus.objColAdmInterface.jointVel),
456 std::ref(rtStatus.objectCollNullSpace));
457 }
458 else
459 {
460 controllerHierarchy.emplace_back(c.objectCollisionAvoidancePriority,
461 std::ref(rtStatus.objectCollisionJointTorque),
462 std::ref(rtStatus.objectCollNullSpace));
463 }
464 }
465 if (c.enableJointLimitAvoidance)
466 {
467 if (rtStatus.jointLimAdmInterface.active)
468 {
469 rtStatus.jointLimAdmInterface.run(
470 rtStatus.jointLimitJointTorque, jointVelLimit, rts);
471 controllerHierarchy.emplace_back(c.jointLimitAvoidancePriority,
472 std::ref(rtStatus.jointLimAdmInterface.jointVel),
473 std::ref(rtStatus.jointLimNullSpace));
474 }
475 else
476 {
477 controllerHierarchy.emplace_back(c.jointLimitAvoidancePriority,
478 std::ref(rtStatus.jointLimitJointTorque),
479 std::ref(rtStatus.jointLimNullSpace));
480 }
481 }
482
483 // TODO find a better way to check velocity mode
484 if (rtStatus.selfColAdmInterface.active)
485 {
486 controllerHierarchy.emplace_back(c.impedancePriority,
487 std::ref(rts.desiredJointVelocity),
488 std::ref(rtStatus.impedanceNullSpace));
489 }
490 else
491 {
492 controllerHierarchy.emplace_back(c.impedancePriority,
493 std::ref(rts.desiredJointTorque),
494 std::ref(rtStatus.impedanceNullSpace));
495 }
496
497 // sort inplace according to priority
498 sortHierarchy();
499
500
501 uint32_t index = 0;
502
503 // TODO rename the finalTorque ... variables
504 rtStatus.finalTorque.setZero();
505
506 while (index < controllerHierarchy.size())
507 {
508 auto& [priority, torque, nullspace] = controllerHierarchy[index];
509 rtStatus.nullSpaceAcc = nullspace.get();
510 rtStatus.torqueAcc = torque.get();
511
512 index++;
513 /// If two tasks have the exact same priority, combine them
514 while ((index < controllerHierarchy.size()) &&
515 (std::get<0>(controllerHierarchy[index]) == priority))
516 {
517 rtStatus.nullSpaceAcc *= std::get<2>(controllerHierarchy[index]).get();
518 rtStatus.torqueAcc += std::get<1>(controllerHierarchy[index]).get();
519 index++;
520 }
521
522 /// Otherwise, do the nullspace projection
523 rtStatus.finalTorque =
524 (rtStatus.torqueAcc + (rtStatus.nullSpaceAcc * rtStatus.finalTorque));
525 }
526
527 if (rtStatus.selfColAdmInterface.active)
528 {
529 rts.desiredJointVelocity = rtStatus.finalTorque;
530 /// ----------------------------- write torque target --------------------------------------------------
531 for (int i = 0; i < rts.desiredJointVelocity.rows(); ++i)
532 {
533 rts.desiredJointVelocity(i) =
534 std::clamp(rts.desiredJointVelocity(i), -jointVelLimit, jointVelLimit);
535 }
536 // rtStatus.desiredJointVel = rtStatus.finalTorque;
537 // /// ----------------------------- write torque target --------------------------------------------------
538 // for (int i = 0; i < rtStatus.desiredJointVel.rows(); ++i)
539 // {
540 // rtStatus.desiredJointVel(i) =
541 // std::clamp(rtStatus.desiredJointVel(i), -jointVelLimit, jointVelLimit);
542 // }
543 }
544 else
545 {
546 rts.desiredJointTorque = rtStatus.finalTorque;
547 /// ----------------------------- write torque target --------------------------------------------------
548 for (int i = 0; i < rts.desiredJointTorque.rows(); ++i)
549 {
550 rts.desiredJointTorque(i) =
551 std::clamp(rts.desiredJointTorque(i), -torqueLimit, torqueLimit);
552 }
553 // rtStatus.desiredJointTorques = rtStatus.finalTorque;
554 // /// ----------------------------- write torque target --------------------------------------------------
555 // for (int i = 0; i < rtStatus.desiredJointTorques.rows(); ++i)
556 // {
557 // rtStatus.desiredJointTorques(i) =
558 // std::clamp(rtStatus.desiredJointTorques(i), -torqueLimit, torqueLimit);
559 // }
560 }
562
563 /// ------------------------- write impedance forces to buffer -----------------------------------------
564 // this section is purely for visualization purposes in the viewer
565 // rtStatus.dirErrorImp = rtStatus.poseErrorImp.head<3>().normalized();
566 // rtStatus.totalForceImpedance = rtStatus.forceImpedance.head<3>().norm();
567 // rtStatus.projForceImpedance = rtStatus.jtpinv * rtStatus.projImpedanceJointTorque;
568 // rtStatus.projTotalForceImpedance = rtStatus.projForceImpedance.head<3>().norm();
569 // rtStatus.impForceRatio = rtStatus.projTotalForceImpedance / rtStatus.totalForceImpedance;
570 // rtStatus.impTorqueRatio =
571 // rtStatus.projImpedanceJointTorque.norm() / rtStatus.impedanceJointTorque.norm();
572 }
573
574 void
575 ObjectCollisionAvoidanceController::sortHierarchy()
576 {
577 /// This sorts the controllerHierarchy vector in Descending Order based on the
578 /// priority value (integer). This means controllers with Lower Priority are
579 /// placed at the beginning
580 ///
581 for (size_t i = 1; i < controllerHierarchy.size(); i++)
582 {
583 auto element = controllerHierarchy[i];
584 const unsigned int priority = std::get<0>(element);
585
586 int j = i - 1;
587 while (j >= 0 && std::get<0>(controllerHierarchy[j]) < priority)
588 {
589 controllerHierarchy[j + 1] = controllerHierarchy[j];
590 j--;
591 }
592 controllerHierarchy[j + 1] = element;
593 }
594 }
595
596} // namespace armarx::control::common::control_law
#define ARMARX_RT_LOGF_WARN(...)
uint8_t index
constexpr T c
internal status of the controller, containing intermediate variables, mutable targets
Eigen::MatrixXf selfCollNullSpace
intermediate null space matrices ((self-)collision and joint limit avoidance)
void calculateJointLimitNullspace(const Config &c, RtStatusForSafetyStrategy &rtStatus, const Eigen::VectorXf &qpos) const
::simox::control::environment::DistanceResult DistanceResult
void calculateJointLimitTorque(const Config &c, RtStatusForSafetyStrategy &rtStatus, const Eigen::VectorXf &qpos, const Eigen::VectorXf &qvelFiltered) const
void calculateSelfCollisionNullspace(const Config &c, RtStatusForSafetyStrategy &rtStatus) const
caclulate null spaces
CollisionAvoidanceController(const simox::control::robot::NodeSetInterface *nodeSet)
std::unordered_map< unsigned int, const simox::control::robot::NodeInterface * > CollisionRobotIndices
void calculateCollisionTorque(CollisionData &collDataVec, const Config &c, RtStatusForSafetyStrategy &rts, const CollisionRobotIndices &collisionRobotIndices, const Eigen::VectorXf &qvelFiltered, Eigen::VectorXf &jointTorque, float distanceThresholdRaw, float distanceThreshold) const
void calculateSelfCollisionTorque(const Config &c, RtStatusForSafetyStrategy &rtStatus, RecoveryState &rState, const DistanceResults &collisionPairs, const CollisionRobotIndices &collisionRobotIndices, const Eigen::VectorXf &qvelFiltered, double deltaT) const
avoidance torque methods
void calculateObjectCollisionNullspace(const Config &c, RtStatusForSafetyStrategy &rtStatus) const
ObjectCollisionAvoidanceController(const simox::control::robot::NodeSetInterface *nodeSet)
common::control_law::arondto::ObjectCollisionAvoidanceConfig Config
void run(const Config &c, RtStatusForSafetyStrategy &robotStatus, RecoveryState &rStateSelfColl, RecoveryState &rStateObjColl, const DistanceResults &collisionPairs, const DistanceResults &externalCollisionPairs, const CollisionRobotIndices &collisionRobotIndices, DynamicsModel &dynamicsModel, float torqueLimit, float jointVelLimit, TSCtrlRtStatus &rts)
------------------------------— main rt-loop ---------------------------------------—
void calculateExternalCollisionTorque(const Config &c, RtStatusForSafetyStrategy &rts, RecoveryState &rState, const DistanceResults &externalCollisionPairs, const CollisionRobotIndices &collisionRobotIndices, const Eigen::VectorXf &qvelFiltered, double deltaT) const
#define ARMARX_CHECK(expression)
Shortcut for ARMARX_CHECK_EXPRESSION.
#define ARMARX_CHECK_NONNEGATIVE(number)
Check whether number is nonnegative (>= 0).
#define ARMARX_CHECK_EQUAL(lhs, rhs)
This macro evaluates whether lhs is equal (==) rhs and if it turns out to be false it will throw an E...
#define ARMARX_WARNING
The logging level for unexpected behaviour, but not a serious problem.
Definition Logging.h:191
void run(Eigen::VectorXf &jointTorque, float jointVelLimit, const TSCtrlRtStatus &rts)
void update(const Config &c, RtStatusForSafetyStrategy &rtStatus, double deltaT)
Eigen::VectorXf qvelFiltered
for velocity control
Definition common.h:78
Eigen::MatrixXd inertia
inertia Note, the inertia variables are only used for collision avoidance controllers,...
Definition common.h:104
#define ARMARX_TRACE_LITE
Definition trace.h:96