32 #include <VirtualRobot/CollisionDetection/CollisionChecker.h>
33 #include <VirtualRobot/CollisionDetection/CollisionModel.h>
34 #include <VirtualRobot/Nodes/RobotNode.h>
35 #include <VirtualRobot/Robot.h>
36 #include <VirtualRobot/SceneObjectSet.h>
37 #include <VirtualRobot/VirtualRobot.h>
57 const VirtualRobot::SceneObjectSetPtr& obstacles,
59 const std::vector<Room>&
rooms,
61 const std::string& robotCollisonModelName,
67 parameters(parameters),
68 robotCollisionModelName(robotCollisonModelName),
69 builderParameters(builderParameters)
73 ARMARX_CHECK(robot->hasRobotNode(robotCollisionModelName));
81 {
ARMARX_INFO <<
"Creating costmap took " << duration; });
89 {
ARMARX_INFO <<
"Filling costmap took " << duration; });
92 << costmap.
getGrid().cols() <<
") and resolution "
98 extendGridCosts(costmap,
rooms);
102 extendGridCosts(costmap, {});
119 {
ARMARX_INFO <<
"Creating costmap took " << duration; });
121 ARMARX_INFO << articulatedObjects.size() <<
" articulated objects";
133 Costmap costmap(grid, parameters, sceneBounds);
137 initializeEmptyMask(costmap);
141 for (
const auto& room :
rooms)
148 ARMARX_VERBOSE <<
"Restricted to rooms. Fraction of valid elements: "
149 << costmap.mask->cast<
float>().sum() / costmap.mask->size();
155 {
ARMARX_INFO <<
"Filling costmap took " << duration; });
158 << costmap.
getGrid().cols() <<
") and resolution "
160 fillGridCosts(costmap);
173 costmap.mask = costmap.grid.array() > 0.F;
175 ARMARX_VERBOSE <<
"Initializing mask: Fraction of valid elements: "
176 << costmap.mask->cast<
float>().sum() / costmap.mask->size();
180 CostmapBuilder::initializeEmptyMask(
Costmap& costmap)
182 costmap.mask = costmap.grid.array() >= -42.F;
183 costmap.mask->setOnes();
185 ARMARX_VERBOSE <<
"Initializing empty mask: Fraction of valid elements: "
186 << costmap.mask->cast<
float>().sum() / costmap.mask->size();
198 size_t c_x = (sceneBounds.
max.x() - sceneBounds.
min.x()) / parameters.
cellSize + 1;
199 size_t c_y = (sceneBounds.
max.y() - sceneBounds.
min.y()) / parameters.
cellSize + 1;
204 Eigen::MatrixXf grid(c_x, c_y);
213 const VirtualRobot::CollisionModelPtr& robotCollisionModel)
223 collisionRobot->setGlobalPose(globalPose.matrix());
227 if (obstacles->getSize() > 0)
229 distanceNonArticulated =
230 VirtualRobot::CollisionChecker::getGlobalCollisionChecker()->calculateDistance(
231 robotCollisionModel, obstacles);
236 for (
const auto& articulatedObject : articulatedObjects)
238 for (
const auto& colModel : articulatedObject->getCollisionModels())
240 const float distanceArticulated =
241 VirtualRobot::CollisionChecker::getGlobalCollisionChecker()->calculateDistance(
242 robotCollisionModel, colModel);
243 distanceArticulatedMin =
std::min(distanceArticulated, distanceArticulatedMin);
247 return std::min(distanceNonArticulated, distanceArticulatedMin);
295 CostmapBuilder::fillGridCosts(Costmap& costmap)
297 applyFnToCostmap(costmap,
299 VirtualRobot::CollisionModelPtr& robotCollisionModel,
300 const std::optional<float> maskOpt,
304 const auto position = costmap.toPositionGlobal(
index);
307 if (maskOpt.has_value())
309 if (not maskOpt.value())
315 return computeCost(position, collisionRobot, robotCollisionModel);
320 CostmapBuilder::extendGridCosts(Costmap& costmap,
const std::vector<Room>& rooms)
322 applyFnToCostmap(costmap,
324 VirtualRobot::CollisionModelPtr& robotCollisionModel,
325 const std::optional<float> maskOpt,
327 const Costmap::Index&
index) ->
float
329 const auto position = costmap.toPositionGlobal(
index);
332 if (maskOpt.has_value())
334 if (not maskOpt.value())
336 return std::min(0.F, costmap.grid(index.x(), index.y()));
345 if (not rooms.empty())
347 if (std::none_of(rooms.begin(),
349 [&position](const Room& room) -> bool
350 { return room.isInside(position); }))
357 cost, computeCost(position, collisionRobot, robotCollisionModel));
362 CostmapBuilder::applyFnToCostmap(Costmap& costmap,
364 VirtualRobot::CollisionModelPtr&,
365 const std::optional<float>,
367 const Costmap::Index&)>& fn)
370 VirtualRobot::CollisionModelPtr robotCollisionModel;
372 if (costmap.mask.has_value())
377 const std::size_t c_x = costmap.grid.rows();
378 const std::size_t c_y = costmap.grid.cols();
380 robot->setUpdateVisualization(
false);
382 #pragma omp parallel for schedule(static) private(collisionRobot, \
383 robotCollisionModel) default(shared)
384 for (
unsigned int x = 0; x < c_x; x++)
387 if (collisionRobot ==
nullptr)
394 robot->clone(
"collision_robot_" +
std::to_string(omp_get_thread_num()));
397 collisionRobot->setPrimitiveApproximationModel({
"navigation"},
false);
399 collisionRobot->setUpdateVisualization(
false);
404 ARMARX_CHECK(collisionRobot->hasRobotNode(robotCollisionModelName));
407 const auto collisionRobotNode =
408 collisionRobot->getRobotNode(robotCollisionModelName);
411 robotCollisionModel = collisionRobotNode->getCollisionModel();
412 ARMARX_CHECK(robotCollisionModel) <<
"Collision model not available. "
413 "Make sure that you load the robot correctly!";
416 robotCollisionModel->scale(builderParameters.collisionModelScaleFactor);
422 for (
unsigned int y = 0; y < c_y; y++)
424 const Costmap::Index
index{x, y};
426 const auto maskVal = costmap.mask.has_value()
427 ? std::make_optional(costmap.mask.value()(x, y))
430 fn(collisionRobot, robotCollisionModel, maskVal, costmap.grid(x, y),
index);