30#include <opencv2/core/eigen.hpp>
31#include <opencv2/core/mat.hpp>
32#include <opencv2/core/types.hpp>
33#include <opencv2/imgproc.hpp>
35#include <VirtualRobot/BoundingBox.h>
36#include <VirtualRobot/CollisionDetection/CollisionModel.h>
37#include <VirtualRobot/Random.h>
38#include <VirtualRobot/Robot.h>
39#include <VirtualRobot/SceneObjectSet.h>
40#include <VirtualRobot/VirtualRobot.h>
41#include <VirtualRobot/Workspace/WorkspaceGrid.h>
54#include <range/v3/algorithm/for_each.hpp>
55#include <range/v3/view/zip.hpp>
63 const std::vector<VirtualRobot::RobotPtr>& articulatedObjects,
65 const std::vector<Room>&
rooms,
67 const bool restrictToRooms)
77 for (
const auto& room :
rooms)
79 for (
const auto& point : room.polygon)
81 bounds.
min.x() = std::min(point.x(), bounds.
min.x());
82 bounds.
min.y() = std::min(point.y(), bounds.
min.y());
83 bounds.
max.x() = std::max(point.x(), bounds.
max.x());
84 bounds.
max.y() = std::max(point.y(), bounds.
max.y());
96 ARMARX_CHECK((not obstacles->getCollisionModels().empty()) or
97 (not articulatedObjects.empty()));
99 const auto expandBounds = [&bounds](
const VirtualRobot::BoundingBox&& bb)
101 bounds.
min.x() = std::min(bb.getMin().x(), bounds.
min.x());
102 bounds.
min.y() = std::min(bb.getMin().y(), bounds.
min.y());
103 bounds.
max.x() = std::max(bb.getMax().x(), bounds.
max.x());
104 bounds.
max.y() = std::max(bb.getMax().y(), bounds.
max.y());
108 for (
const auto& colModel : obstacles->getCollisionModels())
110 expandBounds(colModel->getBoundingBox());
113 ARMARX_VERBOSE <<
"non-articulated objects: scene bounds: " << bounds.
min <<
" and "
117 for (
const auto& articulatedObject : articulatedObjects)
119 if (articulatedObject->getCollisionModels().empty())
121 ARMARX_WARNING <<
"The articulated object `" << articulatedObject->getType()
122 <<
"/" << articulatedObject->getName()
123 <<
"` does not provide any collision model!";
126 ARMARX_DEBUG <<
"Articulated object `" << articulatedObject->getType() <<
"/"
127 << articulatedObject->getName();
129 for (
const auto& colModel : articulatedObject->getCollisionModels())
131 expandBounds(colModel->getBoundingBox());
133 <<
VAROUT(colModel->getBoundingBox().getMax());
143 bounds.
min.x() -= margin;
144 bounds.
min.y() -= margin;
145 bounds.
max.x() += margin;
146 bounds.
max.y() += margin;
158 for (
const auto& point : points)
160 bounds.
min.x() = std::min(point.x(), bounds.
min.x());
161 bounds.
min.y() = std::min(point.y(), bounds.
min.y());
162 bounds.
max.x() = std::max(point.x(), bounds.
max.x());
163 bounds.
max.y() = std::max(point.y(), bounds.
max.y());
167 bounds.
min.x() -= margin;
168 bounds.
min.y() -= margin;
169 bounds.
max.x() += margin;
170 bounds.
max.y() += margin;
178 return {.min = Eigen::Vector2f{extends.minX, extends.minY},
179 .max = Eigen::Vector2f{extends.maxX, extends.maxY}};
183 merge(
const std::vector<SceneBounds>& sceneBounds)
187 const auto expandBounds = [&bounds](
const SceneBounds& sb)
189 bounds.
min.x() = std::min(bounds.
min.x(), sb.min.x());
190 bounds.
min.y() = std::min(bounds.
min.y(), sb.min.y());
192 bounds.
max.x() = std::max(bounds.
max.x(), sb.max.x());
193 bounds.
max.y() = std::max(bounds.
max.y(), sb.max.y());
198 ranges::for_each(sceneBounds, expandBounds);
204 toCostmap(
const VirtualRobot::WorkspaceGrid& workspaceGrid)
206 const Costmap::Grid grid(workspaceGrid.getCells().x, workspaceGrid.getCells().y);
210 .cellSize = workspaceGrid.getDiscretizeSize()};
212 return {grid, parameters, sceneBounds};
299 ranges::for_each(costmaps, assertSameSize);
312 const std::vector<float> weights(costmaps.size(), 1.F / costmaps.size());
317 costmaps.front().params());
328 ARMARX_CHECK(
false) <<
"This case should already be handled.";
341 ranges::for_each(costmaps,
342 [&mergedCostmap, &addMode](
const auto&
costmap)
345 return mergedCostmap;
349 mergeAligned(
const std::vector<Costmap>& costmaps,
const std::vector<float>& weights)
357 costmaps.front().params());
362 ranges::for_each(ranges::views::zip(costmaps, weights),
363 [&mergedCostmap](
const auto& p)
365 const auto& [
costmap, weight] = p;
369 return mergedCostmap;
375 const float scale =
costmap.params().cellSize / cellSize;
379 cv::eigen2cv(
costmap.getGrid(), src);
382 cv::resize(src, dst, cv::Size{0, 0}, scale, scale);
384 Eigen::MatrixXf scaledGrid;
385 cv::cv2eigen(dst, scaledGrid);
388 std::optional<Costmap::Mask> scaledMask;
389 if (
costmap.getMask().has_value())
396 constexpr int someInt = 100;
399 someInt *
costmap.getMask().value().cast<std::uint8_t>();
402 cv::eigen2cv(mask, maskMat);
405 cv::resize(maskMat, maskScaled, cv::Size{0, 0}, scale, scale);
411 Eigen::MatrixXi scaledMaskInt;
412 cv::cv2eigen(maskScaled, scaledMaskInt);
420 <<
costmap.getGrid().cols() <<
")";
421 ARMARX_VERBOSE <<
"Resized to (" << scaledGrid.rows() <<
", " << scaledGrid.cols() <<
")";
430 std::optional<core::Pose2D>
433 const auto sizeX =
costmap.getGrid().cols();
434 const auto sizeY =
costmap.getGrid().rows();
436 constexpr std::size_t maxIterations = 1000;
440 for (std::size_t iteration = 0; iteration < maxIterations; iteration++)
442 const float iX = VirtualRobot::RandomFloat() *
static_cast<float>(sizeX);
443 const float iY = VirtualRobot::RandomFloat() *
static_cast<float>(sizeY);
453 pose.translation() =
costmap.toPositionGlobal(idx);
462 invalidateOutsideRoomsImpl(
463 const std::vector<Room>&
rooms,
467 const std::size_t c_x = mask.rows();
468 const std::size_t c_y = mask.cols();
470 const auto isInsideRoom = [&
rooms](
const Eigen::Vector2f& pos) ->
bool
472 return std::any_of(
rooms.begin(),
474 [&pos](
const Room& room) ->
bool { return room.isInside(pos); });
477 for (
unsigned int x = 0;
x < c_x;
x++)
479 for (
unsigned int y = 0; y < c_y; y++)
484 if (not isInsideRoom(position))
496 invalidateOutsideRoomsImpl(
499 costmap.getMutableMask().value());
504 static_cast<int>(std::max(
505 1.F,
costmap.params().sceneBoundsMargin /
costmap.params().cellSize)));
512 invalidateOutsideRoomsImpl(
515 costmap.getMutableMask().value());
522 cv::eigen2cv(mask, cvMask);
524 cv::Mat kernel = cv::getStructuringElement(cv::MORPH_RECT, cv::Size(3, 3));
525 cv::dilate(cvMask, cvMask, kernel, cv::Point(-1, -1), numIterations);
528 cv::cv2eigen(cvMask, dst);
#define ARMARX_CHECK_NOT_EMPTY(c)
static Eigen::MatrixXf createUniformGrid(const SceneBounds &sceneBounds, const Costmap::Parameters ¶meters)
static Costmap WithSameDimsAs(const Costmap &other, const Grid &grid, const std::optional< Mask > &mask=std::nullopt)
Create a costmap with the same dimensions and parameters as the given one.
Eigen::Matrix< bool, Eigen::Dynamic, Eigen::Dynamic > Mask
bool add(const Costmap &other, float weight=1.0)
#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_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_INFO
The normal logging level.
#define ARMARX_ERROR
The logging level for unexpected behaviour, that must be fixed.
#define ARMARX_DEBUG
The logging level for output that is only interesting while debugging.
#define ARMARX_WARNING
The logging level for unexpected behaviour, but not a serious problem.
#define ARMARX_VERBOSE
The logging level for verbose information.
This file is part of ArmarX.
This file is part of ArmarX.
Costmap::Mask dilateMask(const Costmap::Mask &mask, int numIterations)
Costmap toCostmap(const VirtualRobot::WorkspaceGrid &workspaceGrid)
SceneBounds merge(const std::vector< SceneBounds > &sceneBounds)
Costmap scaleCostmap(const Costmap &costmap, float cellSize)
std::optional< core::Pose2D > sampleValidPositionInMap(const algorithms::Costmap &costmap)
CostmapMergeMode
Defines how the.
SceneBounds computeSceneBounds(const VirtualRobot::SceneObjectSetPtr &obstacles, const std::vector< VirtualRobot::RobotPtr > &articulatedObjects, const SceneBounds &init, const std::vector< Room > &rooms, const float margin, const bool restrictToRooms)
SceneBounds toSceneBounds(const VirtualRobot::WorkspaceGrid::Extends &extends)
void invalidateOutsideRooms(const std::vector< Room > &rooms, Costmap &costmap)
Costmap mergeAligned(const std::vector< Costmap > &costmaps, CostmapMergeMode mode)
void checkSameSize(const std::vector< Costmap > &costmaps)
This file offers overloads of toIce() and fromIce() functions for STL container types.