LaserBasedProximity.cpp
Go to the documentation of this file.
2
3#include <algorithm>
4#include <cmath>
5#include <cstddef>
6#include <cstdlib>
7#include <functional>
8#include <limits>
9#include <optional>
10#include <string>
11#include <utility>
12#include <vector>
13
14#include <boost/geometry.hpp>
15#include <boost/geometry/algorithms/append.hpp>
16#include <boost/geometry/geometries/multi_point.hpp>
17
18#include <Eigen/Core>
19#include <Eigen/Geometry>
20
21#include <range/v3/algorithm/all_of.hpp>
22#include <range/v3/algorithm/min.hpp>
23#include <range/v3/all.hpp>
24#include <range/v3/range/conversion.hpp>
25#include <range/v3/view/enumerate.hpp>
26#include <range/v3/view/filter.hpp>
27#include <range/v3/view/reverse.hpp>
28#include <range/v3/view/transform.hpp>
29#include <range/v3/view/zip_with.hpp>
30
31#include <SimoxUtility/color/Color.h>
32#include <SimoxUtility/color/cmaps/colormaps.h>
33#include <SimoxUtility/shapes/OrientedBox.h>
34#include <VirtualRobot/Nodes/RobotNode.h>
35#include <VirtualRobot/Robot.h>
36
40
47
55#include <armarx/navigation/safety_guard/aron/LaserBasedProximityParams.aron.generated.h>
59
60namespace rv = ::ranges::views;
61
63{
64
65 namespace
66 {
67
68 inline core::TwistLimits
69 mergeSafetyLimits(const std::vector<std::optional<core::TwistLimits>>& resultsAll)
70 {
71 const auto isValidFn =
72 [](const std::optional<core::TwistLimits>& result) noexcept -> bool
73 { return result.has_value(); };
74
75 const std::vector<core::TwistLimits> validResults =
76 resultsAll | rv::filter(isValidFn) |
77 rv::transform(
78 [](const std::optional<core::TwistLimits>& result) noexcept -> core::TwistLimits
79 { return result.value(); }) |
80 ranges::to_vector;
81
82
83 if (validResults.empty())
84 {
86 }
87
88 const std::vector<float> linearLimits =
89 validResults |
90 rv::transform([](const core::TwistLimits& result) noexcept -> float
91 { return result.linear; }) |
92 ranges::to_vector;
93
94 const std::vector<float> angularLimits =
95 validResults |
96 rv::transform([](const core::TwistLimits& result) noexcept -> float
97 { return result.angular; }) |
98 ranges::to_vector;
99
100 const core::TwistLimits combinedResult{.linear = ranges::min(linearLimits),
101 .angular = ranges::min(angularLimits)};
102
103 return combinedResult;
104 }
105
106
107 } // namespace
108
114
117 {
118 arondto::LaserBasedProximityParams dto;
119
121
122 return dto.toAron();
123 }
124
127 {
128 arondto::LaserBasedProximityParams dto;
129 dto.fromAron(dict);
130
132 fromAron(dto, bo);
133
134 return bo;
135 }
136
138 const core::GeneralConfig& generalConfig,
139 const core::Scene& scene,
140 const Context& ctx) :
141 SafetyGuard(scene, ctx),
142 params(params),
143 generalConfig(generalConfig),
144 humanColorMap_(simox::color::cmaps::BuPu().reversed()),
145 laserColorMap_(simox::color::cmaps::OrRd().reversed())
146 {
147 }
148
150 LaserBasedProximity::computeSafetyLimits(const Eigen::Vector2f& global_V_movement)
151 {
152 ARMARX_CHECK(scene.dynamicScene.has_value());
153
154 auto layer = viz.layer("safety_guard");
155
156 const std::optional<core::TwistLimits> resultHumans = safetyLimitsHumans(layer);
157 const std::optional<core::TwistLimits> resultLaserScanners =
158 safetyLimitsLaserScanners(layer, global_V_movement);
159
160 // Commit always. This ensures that objects eventually will be cleared.
161 viz.commit(layer);
162
163 const core::TwistLimits combinedResult =
164 mergeSafetyLimits({resultHumans, resultLaserScanners});
165 ARMARX_VERBOSE << "Safety limits: " << VAROUT(combinedResult.linear)
166 << VAROUT(combinedResult.angular);
167
168 return SafetyGuardResult{.twistLimits = combinedResult};
169 }
170
171 std::optional<core::TwistLimits>
172 LaserBasedProximity::safetyLimitsLaserScanners(viz::Layer& layer,
173 const Eigen::Vector2f& global_V_movement) const
174 {
176 {
177 return std::nullopt;
178 }
179
180 if (scene.dynamicScene->laserScannerFeatures.empty())
181 {
182 ARMARX_INFO << deactivateSpam(5) << "No laser scanner features for SafetyGuard";
183
184 return std::nullopt;
185 }
186
188 auto& debugObserver = *context.debugObserver;
189
190 debugObserver.setDebugObserverDatafield("numLaserScannerFeatures",
191 scene.dynamicScene->laserScannerFeatures.size());
192 debugObserver.setDebugObserverDatafield(
193 "numFirstLaserScannerFeatures",
194 scene.dynamicScene->laserScannerFeatures.front().features.size());
195
196 ARMARX_VERBOSE << VAROUT(scene.dynamicScene->laserScannerFeatures.size());
197 ARMARX_VERBOSE << VAROUT(scene.dynamicScene->laserScannerFeatures.front().features.size());
198
199 const core::Pose global_T_robot{scene.robot->getGlobalPose()};
200
201 ARMARX_VERBOSE << VAROUT(global_T_robot.translation());
202
203 const core::Pose robot_T_global{global_T_robot.inverse()};
204
205 // compute distance based on convex hull of robot
206 util::geometry::polygon_type robotConvexHull;
207 {
208 boost::geometry::model::multi_point<util::geometry::point_type> robotNodes;
209 for (const auto& node : scene.robot->getRobotNodes())
210 {
211 Eigen::Vector2f pos2d = conv::to2D(core::Pose(node->getGlobalPose())).translation();
212 boost::geometry::append(robotNodes,
213 util::geometry::point_type(pos2d.x(), pos2d.y()));
214 }
215 boost::geometry::convex_hull(robotNodes, robotConvexHull);
216 }
217
218 // Compute the minimal distance to the robot for a set of features (point clusters)
219 const auto minDistanceFn =
220 [this, &robotConvexHull, &robot_T_global](const memory::LaserScannerFeatures& features)
221 -> std::vector<DistanceAndClosestPoint>
222 {
223 const core::Pose& global_T_sensor = features.frameGlobalPose;
224
225 // Compute the minimal distance to the robot for a single feature (point cluster)
226 const auto minDistanceFnInner =
227 [this, &robotConvexHull, &global_T_sensor, &robot_T_global](
228 const memory::LaserScannerFeature& feature) -> DistanceAndClosestPoint
229 {
230 // transform points to 3D global frame
231 const std::vector<Eigen::Vector3f> points3dGlobal =
232 feature.points |
233 rv::transform([&global_T_sensor](const Eigen::Vector2f& pt) -> Eigen::Vector3f
234 { return global_T_sensor * conv::to3D(pt); }) |
235 ranges::to_vector;
236
237 return calculateMinDistance(robotConvexHull, robot_T_global, points3dGlobal);
238 };
239
240 // Compute the minimal distance to the robot for all features (point clusters)
241 ARMARX_VERBOSE << VAROUT(features.features.size());
242 const std::vector<DistanceAndClosestPoint> distances =
243 features.features | rv::transform(minDistanceFnInner) | ranges::to_vector;
244
245 return distances;
246 };
247
248 laserScannerFeatureHistory_.push_back(scene.dynamicScene->laserScannerFeatures);
249
250 const std::vector<memory::LaserScannerFeatures> accumulatedLaserScannerFeatures =
251 laserScannerFeatureHistory_ | ranges::views::join |
252 ranges::to<std::vector<memory::LaserScannerFeatures>>;
253
254 const std::vector<DistanceAndClosestPoint> minDistanceToObstacles =
255 accumulatedLaserScannerFeatures | rv::transform(minDistanceFn) | ranges::views::join |
256 ranges::to_vector;
257
258 const auto result = [&]() -> std::optional<InternalVelocityLimitResult>
259 {
260 switch (params.laserScannerProximityField.mode)
261 {
263 return std::nullopt;
265 return velocityLimitsDirectionDependent(
266 global_V_movement, minDistanceToObstacles, global_T_robot);
268 return velocityLimitsDirectionIndependent(minDistanceToObstacles);
269 }
270
271 ARMARX_ERROR << "Unknown ProximityFieldParams::Mode: "
272 << static_cast<int>(params.laserScannerProximityField.mode);
273 return std::nullopt;
274 }();
275
276 layer.clear();
277
278 // visualize robot and obstacle-independent information (always)
279 {
280 // visualize convex hull of robot
281 simox::color::Color color = simox::Color::blue();
282 viz::Polygon vizPoly("robot_convex_hull");
283 for (const auto& p : rv::reverse(robotConvexHull.outer()))
284 {
285 Eigen::Vector2f pt(p.x(), p.y());
286 vizPoly.addPoint(conv::to3D(pt));
287 }
288 layer.add(vizPoly.color(color).lineColor(color));
289
290 // visualize movement direction
291 layer.add(viz::Line("robot_movement_Dir")
292 .fromTo(global_T_robot.translation(),
293 global_T_robot.translation() +
294 conv::to3D(global_V_movement).normalized() * 1000)
295 .lineWidth(10.F)
296 .color(simox::Color::blue()));
297
298 // visualize ignored regions
299 for (const auto& [i, region] : ranges::views::enumerate(params.ignoredRegions))
300 {
301 viz::Polygon vizRegion("ignored_region_" + std::to_string(i));
302 vizRegion.addPoint(Eigen::Vector3f(region.min().x(), region.min().y(), 15));
303 vizRegion.addPoint(Eigen::Vector3f(region.max().x(), region.min().y(), 15));
304 vizRegion.addPoint(Eigen::Vector3f(region.max().x(), region.max().y(), 15));
305 vizRegion.addPoint(Eigen::Vector3f(region.min().x(), region.max().y(), 15));
306 layer.add(vizRegion.color(simox::Color::magenta()));
307 }
308
309 // visualize attached objects
310 for (const auto& [i, obj] :
311 ranges::views::enumerate(scene.dynamicScene->attachedObjects))
312 {
313 const auto& oobb = obj->oobbGlobal();
314 ARMARX_CHECK(oobb.has_value());
315
316 simox::OrientedBoxf inflatedOobb{
317 oobb->transformation_centered(),
318 oobb->dimensions() + Eigen::Vector3f::Ones() * params.attachedObjectsInflation};
319
320 viz::Box vizObj("attached_object_" + std::to_string(i));
321 vizObj.set(inflatedOobb);
322 layer.add(vizObj.color(simox::Color::magenta()));
323 }
324 }
325
326 if (not result.has_value())
327 {
328 return std::nullopt;
329 }
330
331 // visualize the obstacle that leads to the calculated safety limits and the corresponding velocity limits
332 if (result->closestPoint.has_value())
333 {
334 // increase transparency with increased distance, but never make fully transparent
335 const auto color = laserColorMap_.at(
336 std::abs(result->twistLimits.linear), 0, generalConfig.maxVel.linear);
337
338 layer.add(
339 viz::Line("nearest_obstacle")
340 .fromTo(global_T_robot.translation(), conv::to3D(result->closestPoint.value()))
341 .lineWidth(50.F)
342 .color(color));
343 }
344
345 return result->twistLimits;
346 }
347
348 std::optional<core::TwistLimits>
349 LaserBasedProximity::safetyLimitsHumans(viz::Layer& layer) const
350 {
351 if (not params.enableHumans)
352 {
353 return std::nullopt;
354 }
355
356 const core::Pose global_T_robot{scene.robot->getGlobalPose()};
357
358 // Compute the minimal distance to the robot for a human
359 // TODO(utetg): is minimum distance = distance to robot center or robot edge
360 const auto minimalSegmentDistanceToRobot =
361 [&global_T_robot](const human::Human& human) -> float
362 {
363 const Eigen::Isometry3f global_T_human = conv::to3D(human.pose);
364 const Eigen::Isometry3f robot_T_human = global_T_robot.inverse() * global_T_human;
365
366 // TODO extension: if also human keypoints are available, use them to compute the minimal distance
367 return robot_T_human.translation().norm();
368 };
369
370 if (scene.dynamicScene->humans.empty())
371 {
372 ARMARX_VERBOSE << "No humans";
373 return std::nullopt;
374 }
375
376 const auto distanceRobotToHumans = scene.dynamicScene->humans |
377 rv::transform(minimalSegmentDistanceToRobot) |
378 ranges::to_vector;
379
380 const std::optional<float> minDistanceToHumans = scene.dynamicScene->humans.empty()
381 ? std::optional<float>{std::nullopt}
382 : ranges::min(distanceRobotToHumans);
383
384 // handle if no humans are detected
385 if (not minDistanceToHumans.has_value())
386 {
388 }
389
390 const auto result =
391 evaluateProximityField(params.humanProximityField, minDistanceToHumans.value());
392
393 {
394 // increase transparency with increased distance, but never make fully transparent
395 const auto color = humanColorMap_(result.second).with_alpha(1 - result.second + 0.1);
396
397 layer.add(viz::Cylinder("distance_humans")
398 .position(global_T_robot.translation() + Eigen::Vector3f{0, 0, 10})
399 .direction(Eigen::Vector3f::UnitZ())
400 .radius(minDistanceToHumans.value())
401 .height(10)
402 .color(color));
403 }
404
405 return result.first;
406 }
407
408 LaserBasedProximity::DistanceAndClosestPoint
409 LaserBasedProximity::calculateMinDistance(
410 const util::geometry::polygon_type& convexHull,
411 const core::Pose& robot_T_global,
412 const std::vector<Eigen::Vector3f>& globalPoints) const
413 {
414 // Compute the minimal distance to the robot for a list of points
415
416 // transform points to 2D global frame
417 const std::vector<Eigen::Vector2f> points2dGlobal =
418 globalPoints |
419 rv::transform([](const Eigen::Vector3f& pt) -> Eigen::Vector2f
420 { return conv::to2D(pt); }) |
421 ranges::to_vector;
422
423 if (isFeatureIgnored(globalPoints, points2dGlobal) or globalPoints.empty())
424 {
425 ARMARX_VERBOSE << "Global points empty or ignored";
426 return {.distance = std::numeric_limits<float>::max(),
427 .closestPoint = Eigen::Vector2f::Zero(),
428 .clusterSize = 0};
429 }
430
431 // calculate distance to robot center
432 const std::vector<float> pointsDistanceRobotCenter =
433 globalPoints |
434 rv::transform([&robot_T_global](const Eigen::Vector3f& pt) -> float
435 { return conv::to2D(robot_T_global * pt).norm(); }) |
436 ranges::to_vector;
437
438 // if (params.enableLaserScannerFiltering &&
439 // globalPoints.size() <= static_cast<std::size_t>(params.laserScannerFilteringThreshold))
440 // {
441 // // this is a small feature
442 // ARMARX_VERBOSE << "Small feature with " << globalPoints.size()
443 // << " points. Distances to robot center: " << pointsDistanceRobotCenter;
444
445 // if (ranges::all_of(pointsDistanceRobotCenter,
446 // [&](float distanceToCenter) noexcept
447 // {
448 // return std::max(distanceToCenter - params.robotRadius, 0.F) <
449 // params.laserScannerMaxFilteringDistance;
450 // }))
451 // {
452 // // the feature is close to the robot
453 // // -> it should be filtered out
454 // return {.distance = std::numeric_limits<float>::max(),
455 // .closestPoint = Eigen::Vector2f::Zero(),
456 // .clusterSize = 0};
457 // }
458 // }
459
460 const auto distancesAndClosestPoint =
461 rv::zip_with(
462 [this, &convexHull, &globalPoints](
463 const Eigen::Vector2f& pt, float distanceToCenter) -> DistanceAndClosestPoint
464 {
465 const auto distanceToRobotConvexHull =
466 static_cast<float>(boost::geometry::distance(
467 util::geometry::point_type(pt.x(), pt.y()), convexHull));
468
469 const float distanceUsingRobotRadius =
470 std::max(distanceToCenter - params.robotRadius, 0.F);
471
472 return {.distance =
473 std::min(distanceToRobotConvexHull, distanceUsingRobotRadius),
474 .closestPoint = pt,
475 .clusterSize = globalPoints.size()};
476 },
477 points2dGlobal,
478 pointsDistanceRobotCenter) |
479 ranges::to_vector;
480
481 return ranges::min(
482 distancesAndClosestPoint, std::less{}, &DistanceAndClosestPoint::distance);
483 }
484
485 std::pair<core::TwistLimits, float>
486 LaserBasedProximity::evaluateProximityField(const ProximityFieldParams& proximityField,
487 float minDistance) const
488 {
489 if (minDistance < proximityField.safetyDistance)
490 {
491 return {core::TwistLimits::ZeroLimits(), 0.F};
492 }
493
494 if (minDistance > proximityField.influenceDistance)
495 {
496 return {core::TwistLimits::NoLimits(), 1.F};
497 }
498
499
500 const float proximityRange =
501 proximityField.influenceDistance - proximityField.safetyDistance;
502 const float clippedDistance =
503 std::min(minDistance, proximityField.influenceDistance) - proximityField.safetyDistance;
504
505 const float fractionalDistance = std::clamp(clippedDistance / proximityRange, 0.F, 1.F);
506
507 if (not proximityField.reduceVelocity)
508 {
509 return {core::TwistLimits::NoLimits(), fractionalDistance};
510 }
511
512 const float d_s = std::pow(1 - fractionalDistance, proximityField.k);
513
514 const auto permissibleVelocity = [&proximityField](const float d_s,
515 const float v_max) -> float
516 { return v_max / (1 + proximityField.lambda * d_s); };
517
518 const core::TwistLimits result{
519 .linear = permissibleVelocity(d_s, generalConfig.maxVel.linear),
520 .angular = permissibleVelocity(d_s, generalConfig.maxVel.angular)};
521
522 return {result, fractionalDistance};
523 }
524
525 template <class T, class Func>
526 static bool
527 allPointsInside(const std::vector<T>& points, Func isInsideFunc)
528 {
529 for (const auto& p : points)
530 {
531 if (not isInsideFunc(p))
532 {
533 // this point is not inside
534 return false;
535 }
536 }
537 return true;
538 }
539
540 bool
541 LaserBasedProximity::isFeatureIgnored(
542 const std::vector<Eigen::Vector3f>& featurePoints3DGlobal,
543 const std::vector<Eigen::Vector2f>& featurePoints2DGlobal) const
544 {
545 // return false; // FIXME: enable this again after testing, currently disabled to not filter out any features while testing the new safety guard implementation
546
547 const std::size_t numMinPointsInCluster = 20; // FIXME param
548
549 if (featurePoints3DGlobal.size() < numMinPointsInCluster)
550 {
551 return true;
552 }
553
554 return false; // FIXME REMOVE
555
556 // first check against ignored regions
557 for (const auto& region : params.ignoredRegions)
558 {
559 ARMARX_CHECK(not region.isEmpty());
560
561 if (allPointsInside(featurePoints2DGlobal,
562 [&region](const Eigen::Vector2f& p) { return region.contains(p); }))
563 {
564 // the feature lies fully inside this region -> it is ignored
565 return true;
566 }
567 }
568
569 // then check against attached objects
570 for (const auto* o : scene.dynamicScene->attachedObjects)
571 {
572 const auto& oobbGlobal = o->oobbGlobal();
573 ARMARX_CHECK(oobbGlobal.has_value());
574
575 simox::OrientedBoxf inflatedOobb{oobbGlobal->transformation_centered(),
576 oobbGlobal->dimensions() +
577 Eigen::Vector3f::Ones() *
578 params.attachedObjectsInflation};
579
580 if (allPointsInside(featurePoints3DGlobal,
581 [&inflatedOobb](const Eigen::Vector3f& p)
582 { return inflatedOobb.contains(p); }))
583 {
584 // the feature lies fully inside the objects oobb -> it is ignored
585 return true;
586 }
587 }
588
589 return false;
590 }
591
592 LaserBasedProximity::InternalVelocityLimitResult
593 LaserBasedProximity::velocityLimitsDirectionDependent(
594 const Eigen::Vector2f& global_V_movement,
595 const std::vector<DistanceAndClosestPoint>& minDistanceToObstacles,
596 const Eigen::Isometry3f& global_T_robot) const
597 {
598
599 float maxPermissibleRelativeVelocityLinear = generalConfig.maxVel.linear;
600
601 std::optional<Eigen::Vector2f> minPoint = std::nullopt;
602 std::optional<float> minDistance = std::nullopt;
603
604 const Eigen::Isometry3f robot_T_global = global_T_robot.inverse();
605
606 ARMARX_CHECK_NOT_NULL(context.debugObserver);
607 auto& debugObserver = *context.debugObserver;
608
609 debugObserver.setDebugObserverDatafield("numObstacles", minDistanceToObstacles.size());
610
611 std::size_t closestClusterSize = 0;
612 // ARMARX_VERBOSE << VAROUT(minDistanceToObstacles.size());
613
614 for (const auto& [distance, global_P_obstacle_pt, clusterSize] : minDistanceToObstacles)
615 {
616 const float ds = params.laserScannerProximityField.safetyDistance;
617 const float di = params.laserScannerProximityField.influenceDistance;
618 const float d = distance;
619
620 // too far away
621 if (d >= di)
622 {
623 continue;
624 }
625
626 float velocity_damper = generalConfig.maxVel.linear * (d - ds) / (di - ds);
627
628 ARMARX_VERBOSE << VAROUT(velocity_damper);
629
630 const Eigen::Vector2f minPointGlobal = global_P_obstacle_pt;
631
632 ARMARX_VERBOSE << VAROUT(minPointGlobal);
633 ARMARX_VERBOSE << VAROUT(robot_T_global.translation().head<2>());
634
635 const Eigen::Vector2f directionRobotToObstacle =
636 (minPointGlobal - global_T_robot.translation().head<2>()).normalized();
637
638 ARMARX_VERBOSE << VAROUT(directionRobotToObstacle);
639
640 // Cases:
641 // 1) > 0: approaching object
642 // 2) < 0: moving away from object
643 const float relativeVelocityScaling =
644 directionRobotToObstacle.dot(global_V_movement.normalized());
645
647 ARMARX_VERBOSE << VAROUT(relativeVelocityScaling);
648
649 // moving away from obstacle?
650 if (relativeVelocityScaling < 0)
651 {
652 continue;
653 }
654
655 if (d <= ds) // we must stop, if an obstacle is too close
656 {
657 maxPermissibleRelativeVelocityLinear = 0;
658 minPoint = minPointGlobal;
659 minDistance = d;
660 closestClusterSize = clusterSize;
661 continue;
662 }
663
664 // if not exactly tangential
665 if (std::abs(relativeVelocityScaling) > 1e-4)
666 {
667 const float thisMaxPermissibileRelVelLinear =
668 velocity_damper / relativeVelocityScaling;
669 ARMARX_VERBOSE << VAROUT(thisMaxPermissibileRelVelLinear);
670
671 if (thisMaxPermissibileRelVelLinear < maxPermissibleRelativeVelocityLinear)
672 {
673 maxPermissibleRelativeVelocityLinear = thisMaxPermissibileRelVelLinear;
674 minPoint = minPointGlobal;
675 minDistance = d;
676 closestClusterSize = clusterSize;
677 }
678 }
679 }
680
681 debugObserver.setDebugObserverDatafield("maxPermissibleRelativeVelocityLinear",
682 maxPermissibleRelativeVelocityLinear);
683
684 if (minDistance.has_value())
685 {
686 debugObserver.setDebugObserverDatafield("minDistance", minDistance.value());
687 debugObserver.setDebugObserverDatafield("closestClusterSize", closestClusterSize);
688 }
689
690 core::TwistLimits result{.linear = std::max<float>(0, maxPermissibleRelativeVelocityLinear),
691 .angular = generalConfig.maxVel.angular};
692 return {.twistLimits = result, .minDistance = minDistance, .closestPoint = minPoint};
693 }
694
695 LaserBasedProximity::InternalVelocityLimitResult
696 LaserBasedProximity::velocityLimitsDirectionIndependent(
697 const std::vector<DistanceAndClosestPoint>& minDistanceToObstacles) const
698 {
699 const DistanceAndClosestPoint minDistance =
700 ranges::min(minDistanceToObstacles, std::less{}, &DistanceAndClosestPoint::distance);
701
702 const auto result =
703 evaluateProximityField(params.laserScannerProximityField, minDistance.distance);
704
705 return {.twistLimits = result.first,
706 .minDistance = minDistance.distance,
707 .closestPoint = minDistance.closestPoint};
708 }
709} // namespace armarx::navigation::safety_guard
SpamFilterDataPtr deactivateSpam(SpamFilterDataPtr const &spamFilter, float deactivationDurationSec, const std::string &identifier, bool deactivate)
Definition Logging.cpp:75
#define VAROUT(x)
SafetyGuardResult computeSafetyLimits(const Eigen::Vector2f &global_V_movement) override
LaserBasedProximity(const Params &params, const core::GeneralConfig &generalConfig, const core::Scene &scene, const Context &ctx)
SafetyGuard(const core::Scene &scene, const Context &ctx)
#define ARMARX_CHECK(expression)
Shortcut for ARMARX_CHECK_EXPRESSION.
#define ARMARX_CHECK_NOT_NULL(ptr)
This macro evaluates whether ptr is not null and if it turns out to be false it will throw an Express...
#define ARMARX_INFO
The normal logging level.
Definition Logging.h:181
#define ARMARX_ERROR
The logging level for unexpected behaviour, that must be fixed.
Definition Logging.h:196
#define ARMARX_VERBOSE
The logging level for verbose information.
Definition Logging.h:187
std::shared_ptr< Dict > DictPtr
Definition Dict.h:42
std::vector< Eigen::Vector2f > to2D(const std::vector< Eigen::Vector3f > &v)
Definition eigen.cpp:29
std::vector< Eigen::Vector3f > to3D(const std::vector< Eigen::Vector2f > &v)
Definition eigen.cpp:14
Eigen::Isometry3f Pose
Definition basic_types.h:31
This file is part of ArmarX.
Definition fwd.h:55
void fromAron(const arondto::ProximityFieldParams &dto, ProximityFieldParams &bo)
void toAron(arondto::ProximityFieldParams &dto, const ProximityFieldParams &bo)
boost::geometry::model::d2::point_xy< float > point_type
Definition geometry.h:35
boost::geometry::model::polygon< point_type > polygon_type
Definition geometry.h:36
This file is part of ArmarX.
Definition Impl.cpp:41
double distance(const Point &a, const Point &b)
Definition point.hpp:95
VirtualRobot::RobotPtr robot
Definition types.h:73
std::optional< core::DynamicScene > dynamicScene
Definition types.h:71
static TwistLimits ZeroLimits()
Definition types.h:99
static TwistLimits NoLimits()
Definition types.h:92
static LaserBasedProximityParams FromAron(const aron::data::DictPtr &dict)
std::experimental::observer_ptr< DebugObserverComponentPluginUser > debugObserver
Definition SafetyGuard.h:81
void add(ElementT const &element)
Definition Layer.h:31