diff --git a/source/armarx/navigation/algorithms/Costmap.cpp b/source/armarx/navigation/algorithms/Costmap.cpp index 6e4b244896edd253cca6da33b22c5c41e62fa2de..0a6c5a32c36fc4fa110f55bd037132e96b21b824 100644 --- a/source/armarx/navigation/algorithms/Costmap.cpp +++ b/source/armarx/navigation/algorithms/Costmap.cpp @@ -31,11 +31,17 @@ namespace armarx::navigation::algorithms { + Costmap::Costmap(const Grid& grid, const Parameters& parameters, const SceneBounds& sceneBounds, - const std::optional<Mask>& mask) : - grid(grid), mask(mask), sceneBounds(sceneBounds), parameters(parameters) + const std::optional<Mask>& mask, + const core::Pose2D& origin) : + grid(grid), + mask(mask), + sceneBounds(sceneBounds), + parameters(parameters), + global_T_costmap(origin) { validateSizes(); } @@ -51,15 +57,24 @@ namespace armarx::navigation::algorithms } Costmap::Position - Costmap::toPosition(const Costmap::Index& index) const + Costmap::toPositionLocal(const Index& index) const { ARMARX_TRACE; - Eigen::Vector2f pos; - pos.x() = sceneBounds.min.x() + index.x() * parameters.cellSize + parameters.cellSize / 2; - pos.y() = sceneBounds.min.y() + index.y() * parameters.cellSize + parameters.cellSize / 2; + Eigen::Vector2f posLocal; + posLocal.x() = + sceneBounds.min.x() + index.x() * parameters.cellSize + parameters.cellSize / 2; + posLocal.y() = + sceneBounds.min.y() + index.y() * parameters.cellSize + parameters.cellSize / 2; - return pos; + return posLocal; + } + + Costmap::Position + Costmap::toPositionGlobal(const Costmap::Index& index) const + { + const Costmap::Position costmap_P_pos = toPositionLocal(index); + return global_T_costmap * costmap_P_pos; } bool @@ -85,12 +100,14 @@ namespace armarx::navigation::algorithms Costmap::Vertex - Costmap::toVertex(const Eigen::Vector2f& v) const + Costmap::toVertex(const Eigen::Vector2f& globalPosition) const { + const auto localPosition = global_T_costmap.inverse() * globalPosition; + const float vX = - (v.x() - parameters.cellSize / 2 - sceneBounds.min.x()) / parameters.cellSize; + (localPosition.x() - parameters.cellSize / 2 - sceneBounds.min.x()) / parameters.cellSize; const float vY = - (v.y() - parameters.cellSize / 2 - sceneBounds.min.y()) / parameters.cellSize; + (localPosition.y() - parameters.cellSize / 2 - sceneBounds.min.y()) / parameters.cellSize; const int iX = std::round(vX - 0.01); const int iY = std::round(vY - 0.01); @@ -106,11 +123,11 @@ namespace armarx::navigation::algorithms // ARMARX_CHECK_LESS_EQUAL(iX, grid.rows() - 1); // ARMARX_CHECK_LESS_EQUAL(iY, grid.cols() - 1); - return Vertex{.index = Index{iXSan, iYSan}, .position = v}; + return Vertex{.index = Index{iXSan, iYSan}, .position = globalPosition}; } const SceneBounds& - Costmap::getSceneBounds() const noexcept + Costmap::getLocalSceneBounds() const noexcept { return sceneBounds; } @@ -155,7 +172,7 @@ namespace armarx::navigation::algorithms } } - return {.value = minVal, .index = {row, col}, .position = toPosition({row, col})}; + return {.value = minVal, .index = {row, col}, .position = toPositionGlobal({row, col})}; } const Costmap::Parameters& @@ -364,8 +381,8 @@ namespace armarx::navigation::algorithms { ARMARX_CHECK_EQUAL(costmaps.size() + 1, weights.size()); - const std::vector<float> costmapWeights(weights.begin(), weights.end()-1); - ARMARX_CHECK_EQUAL(costmapWeights.size(), costmaps.size()); + const std::vector<float> costmapWeights(weights.begin(), weights.end() - 1); + ARMARX_CHECK_EQUAL(costmapWeights.size(), costmaps.size()); ARMARX_INFO << "Merging into with weights " << weights; @@ -378,7 +395,7 @@ namespace armarx::navigation::algorithms for (int y = 0; y < mergedCostmap.getGrid().cols(); y++) { ARMARX_TRACE; - const Costmap::Position position = mergedCostmap.toPosition(Index{x, y}); + const Costmap::Position position = mergedCostmap.toPositionGlobal(Index{x, y}); // merge masks for (const auto& costmap : costmaps) @@ -391,7 +408,8 @@ namespace armarx::navigation::algorithms if (mergedCostmap.isValid(Index{x, y})) { float newVal = 0; - for (const auto& [weight, costmap] : ranges::views::zip(costmapWeights, costmaps)) + for (const auto& [weight, costmap] : + ranges::views::zip(costmapWeights, costmaps)) { const auto otherCostmapVal = costmap.value(position); ARMARX_CHECK(otherCostmapVal.has_value()); @@ -401,7 +419,8 @@ namespace armarx::navigation::algorithms newVal += weights.back() * mergedCostmap.grid(x, y); mergedCostmap.grid(x, y) = newVal; - }else + } + else { mergedCostmap.grid(x, y) = 0; } diff --git a/source/armarx/navigation/algorithms/Costmap.h b/source/armarx/navigation/algorithms/Costmap.h index a59626f0f6d9daa0e2e8b1bbd6f7446223846842..c880109d486986c611c11095a9b8442918316a88 100644 --- a/source/armarx/navigation/algorithms/Costmap.h +++ b/source/armarx/navigation/algorithms/Costmap.h @@ -4,6 +4,7 @@ #include <Eigen/Core> +#include <armarx/navigation/core/basic_types.h> #include <armarx/navigation/algorithms/types.h> namespace armarx::navigation::algorithms @@ -36,7 +37,8 @@ namespace armarx::navigation::algorithms Costmap(const Grid& grid, const Parameters& parameters, const SceneBounds& sceneBounds, - const std::optional<Mask>& mask = std::nullopt); + const std::optional<Mask>& mask = std::nullopt, + const core::Pose2D& origin = core::Pose2D::Identity()); struct Vertex { @@ -44,8 +46,9 @@ namespace armarx::navigation::algorithms Position position; }; - Position toPosition(const Index& index) const; - Vertex toVertex(const Position& v) const; + Position toPositionLocal(const Index& index) const; + Position toPositionGlobal(const Index& index) const; + Vertex toVertex(const Position& globalPosition) const; const Grid& getGrid() const; Grid& getMutableGrid(){ return grid; } @@ -54,7 +57,8 @@ namespace armarx::navigation::algorithms const Parameters& params() const noexcept; - const SceneBounds& getSceneBounds() const noexcept; + // get the scene bounds in the costmap's base frame (aka 'origin') + const SceneBounds& getLocalSceneBounds() const noexcept; struct Optimum { @@ -89,6 +93,16 @@ namespace armarx::navigation::algorithms Costmap mergeInto(const std::vector<Costmap>& costmaps, const std::vector<float>& weights) const; + const core::Pose2D& origin() const + { + return global_T_costmap; + } + + void setOrigin(const core::Pose2D& globalPose) + { + global_T_costmap = globalPose; + } + private: void validateSizes() const; @@ -98,6 +112,8 @@ namespace armarx::navigation::algorithms const SceneBounds sceneBounds; const Parameters parameters; + + core::Pose2D global_T_costmap = core::Pose2D::Identity(); }; diff --git a/source/armarx/navigation/algorithms/CostmapBuilder.cpp b/source/armarx/navigation/algorithms/CostmapBuilder.cpp index 47ec3ef47a45acd13e189675c64f71538b18ab2a..6321398e3f5b198852fd9ba7df475e653a011c05 100644 --- a/source/armarx/navigation/algorithms/CostmapBuilder.cpp +++ b/source/armarx/navigation/algorithms/CostmapBuilder.cpp @@ -219,7 +219,7 @@ namespace armarx::navigation::algorithms for (unsigned int y = 0; y < c_y; y++) { const Costmap::Index index{x, y}; - const Costmap::Position position = costmap.toPosition(index); + const Costmap::Position position = costmap.toPositionGlobal(index); costmap.grid(x, y) = computeCost(position, collisionRobot, robotCollisionModel); } diff --git a/source/armarx/navigation/algorithms/aron_conversions.cpp b/source/armarx/navigation/algorithms/aron_conversions.cpp index 24cfb351e6e91e4320e876a880f7d477a0aa9e0b..155ae33296bce7073c845a7c28793fe5d09f020d 100644 --- a/source/armarx/navigation/algorithms/aron_conversions.cpp +++ b/source/armarx/navigation/algorithms/aron_conversions.cpp @@ -46,7 +46,8 @@ namespace armarx::navigation::algorithms dto.cellSize = bo.params().cellSize; dto.frame = armarx::GlobalFrame; - dto.origin = conv::to3D(bo.getSceneBounds().min); + // FIXME: integrate costmap origin + dto.origin = conv::to3D(bo.getLocalSceneBounds().min); auto arn = dto.toAron(); arn->addElement("mask", toAron(bo.getMask())); diff --git a/source/armarx/navigation/algorithms/astar/AStarPlanner.cpp b/source/armarx/navigation/algorithms/astar/AStarPlanner.cpp index e211e635dceeb0f5040d8321fdc19bf9d1ae8787..5d3c7ad0d354e7fc9323f17a86cd6bec6fc313d5 100644 --- a/source/armarx/navigation/algorithms/astar/AStarPlanner.cpp +++ b/source/armarx/navigation/algorithms/astar/AStarPlanner.cpp @@ -74,7 +74,7 @@ namespace armarx::navigation::algorithm::astar { for (size_t c = 0; c < cols; c++) { - const auto pos = costmap.toPosition({r, c}); + const auto pos = costmap.toPositionGlobal({r, c}); const float obstacleDistance = costmap.getGrid()(r, c); grid[r][c] = std::make_shared<Node>(pos, obstacleDistance); diff --git a/source/armarx/navigation/algorithms/persistence.cpp b/source/armarx/navigation/algorithms/persistence.cpp index e0f9713285c9df3992fd619acd32a0fb19039914..7b55a46efc652ede1c85aa5012c574d33ca7077f 100644 --- a/source/armarx/navigation/algorithms/persistence.cpp +++ b/source/armarx/navigation/algorithms/persistence.cpp @@ -119,10 +119,10 @@ namespace armarx::navigation::algorithms // scene bounds { auto& jSceneBounds = j["scene_bounds"]; - jSceneBounds["min"] = std::vector<float>{costmap.getSceneBounds().min.x(), - costmap.getSceneBounds().min.y()}; - jSceneBounds["max"] = std::vector<float>{costmap.getSceneBounds().max.x(), - costmap.getSceneBounds().max.y()}; + jSceneBounds["min"] = std::vector<float>{costmap.getLocalSceneBounds().min.x(), + costmap.getLocalSceneBounds().min.y()}; + jSceneBounds["max"] = std::vector<float>{costmap.getLocalSceneBounds().max.x(), + costmap.getLocalSceneBounds().max.y()}; } // grid diff --git a/source/armarx/navigation/algorithms/spfa/ShortestPathFasterAlgorithm.cpp b/source/armarx/navigation/algorithms/spfa/ShortestPathFasterAlgorithm.cpp index cbf80d2b664475113e50dcb2d3b9f4af116dc7bc..f0064691b02cb1fd18713592a81bd09bc6f37851 100644 --- a/source/armarx/navigation/algorithms/spfa/ShortestPathFasterAlgorithm.cpp +++ b/source/armarx/navigation/algorithms/spfa/ShortestPathFasterAlgorithm.cpp @@ -118,7 +118,7 @@ namespace armarx::navigation::algorithms::spfa break; } - path.push_back(costmap.toPosition(parent.array())); + path.push_back(costmap.toPositionGlobal(parent.array())); pt = &parent; } diff --git a/source/armarx/navigation/algorithms/util.cpp b/source/armarx/navigation/algorithms/util.cpp index 0b3956df956e7fcda1789cc62176edb686cffa8e..2918d94b55b3784c905a4e9eaeec5ed13e95ac7c 100644 --- a/source/armarx/navigation/algorithms/util.cpp +++ b/source/armarx/navigation/algorithms/util.cpp @@ -214,10 +214,10 @@ namespace armarx::navigation::algorithms return mergeAligned(costmaps, weights); } - const auto grid = CostmapBuilder::createUniformGrid(costmaps.front().getSceneBounds(), + const auto grid = CostmapBuilder::createUniformGrid(costmaps.front().getLocalSceneBounds(), costmaps.front().params()); - Costmap mergedCostmap(grid, costmaps.front().params(), costmaps.front().getSceneBounds()); + Costmap mergedCostmap(grid, costmaps.front().params(), costmaps.front().getLocalSceneBounds()); const auto addMode = [&]() -> Costmap::AddMode { @@ -254,10 +254,10 @@ namespace armarx::navigation::algorithms checkSameSize(costmaps); - const auto grid = CostmapBuilder::createUniformGrid(costmaps.front().getSceneBounds(), + const auto grid = CostmapBuilder::createUniformGrid(costmaps.front().getLocalSceneBounds(), costmaps.front().params()); - Costmap mergedCostmap(grid, costmaps.front().params(), costmaps.front().getSceneBounds()); + Costmap mergedCostmap(grid, costmaps.front().params(), costmaps.front().getLocalSceneBounds()); // foreach pair (costmap, weight): add it to there merged costmap ranges::for_each(ranges::views::zip(costmaps, weights), @@ -323,7 +323,7 @@ namespace armarx::navigation::algorithms return {scaledGrid, Costmap::Parameters{.binaryGrid = false, .cellSize = cellSize}, - costmap.getSceneBounds(), + costmap.getLocalSceneBounds(), scaledMask}; } diff --git a/source/armarx/navigation/components/Navigator/Navigator.cpp b/source/armarx/navigation/components/Navigator/Navigator.cpp index 890ffc259c094f90e8398051aa68ddb815b22911..10f866548c0a334d30cf94f3f844a1dbd5d468bf 100644 --- a/source/armarx/navigation/components/Navigator/Navigator.cpp +++ b/source/armarx/navigation/components/Navigator/Navigator.cpp @@ -505,7 +505,7 @@ namespace armarx::navigation::components for (int c = 0; c < cols; c++) { - verticesRow.at(c) = conv::to3D(costmap.toPosition({r, c})); + verticesRow.at(c) = conv::to3D(costmap.toPositionGlobal({r, c})); colorsRow.at(c) = asColor(costmap.getGrid()(r, c)); } } diff --git a/source/armarx/navigation/components/dynamic_distance_to_obstacle_costmap_provider/Component.cpp b/source/armarx/navigation/components/dynamic_distance_to_obstacle_costmap_provider/Component.cpp index ba64540867445c73a4fa61208630e1fdce431f2a..9e034e13c78bc9de9eb81fa238438a2c5c6dd1b8 100644 --- a/source/armarx/navigation/components/dynamic_distance_to_obstacle_costmap_provider/Component.cpp +++ b/source/armarx/navigation/components/dynamic_distance_to_obstacle_costmap_provider/Component.cpp @@ -250,7 +250,7 @@ namespace armarx::navigation::components::dynamic_distance_to_obstacle_costmap_p for (int c = 0; c < costmap.getGrid().cols(); c++) { algorithms::Costmap::Index idx(r, c); - const auto pos = costmap.toPosition(idx); + const auto pos = costmap.toPositionGlobal(idx); // if(costmap.getMask().has_value()) // { @@ -320,7 +320,7 @@ namespace armarx::navigation::components::dynamic_distance_to_obstacle_costmap_p for (int c = 0; c < cols; c++) { verticesRow.at(c) = - armarx::navigation::conv::to3D(costmap.toPosition({r, c})) + heightOffsetV; + armarx::navigation::conv::to3D(costmap.toPositionGlobal({r, c})) + heightOffsetV; colorsRow.at(c) = [&]() { @@ -423,7 +423,7 @@ namespace armarx::navigation::components::dynamic_distance_to_obstacle_costmap_p const armarx::navigation::algorithms::Costmap navigationPlanningCostmap( result.distances, obstacleDistancesCostmap.params(), - obstacleDistancesCostmap.getSceneBounds(), + obstacleDistancesCostmap.getLocalSceneBounds(), result.reachable); return navigationPlanningCostmap; diff --git a/source/armarx/navigation/conversions/eigen.cpp b/source/armarx/navigation/conversions/eigen.cpp index 164dd57cd84e81d48a94490b61c31d8e8a85ff95..8cbc14e6ccc9b88645ab1c04bc42db06f10dfc89 100644 --- a/source/armarx/navigation/conversions/eigen.cpp +++ b/source/armarx/navigation/conversions/eigen.cpp @@ -2,6 +2,8 @@ #include <algorithm> +#include <SimoxUtility/math/convert/mat3f_to_rpy.h> + namespace armarx::navigation::conv { @@ -20,4 +22,19 @@ namespace armarx::navigation::conv return v3; } + core::Pose2D + to2D(const core::Pose& p3) + { + core::Pose2D p2 = armarx::navigation::core::Pose2D::Identity(); + p2.translation() = p3.translation().head<2>(); + + const auto rotatedVec = p3.rotation() * Eigen::Vector3f::UnitX(); + const float yaw = std::atan2(rotatedVec.y(), rotatedVec.x()); + + p2.linear() = Eigen::Rotation2Df(yaw).toRotationMatrix(); + + return p2; + } + + } // namespace armarx::navigation::conv diff --git a/source/armarx/navigation/conversions/eigen.h b/source/armarx/navigation/conversions/eigen.h index 3c99d617417f287d7579c7fba41135024ee823d4..1e9071111f115478b7738c92df7588893ae95781 100644 --- a/source/armarx/navigation/conversions/eigen.h +++ b/source/armarx/navigation/conversions/eigen.h @@ -24,6 +24,7 @@ #include <vector> +#include <armarx/navigation/core/basic_types.h> #include <armarx/navigation/core/types.h> namespace armarx::navigation::conv @@ -35,6 +36,8 @@ namespace armarx::navigation::conv return Eigen::Vector2f{v2.x(), v2.y()}; } + core::Pose2D to2D(const core::Pose& p3); + inline Eigen::Vector3f to3D(const Eigen::Vector2f& v2) {