From 479546569c594b321671e9062727894a22f4dc35 Mon Sep 17 00:00:00 2001 From: Fabian Reister <fabian.reister@kit.edu> Date: Mon, 10 Jan 2022 20:55:41 +0100 Subject: [PATCH 01/11] costmap stuff --- CMakeLists.txt | 1 + .../navigation/algorithms/CMakeLists.txt | 8 +- .../armarx/navigation/algorithms/Costmap.cpp | 67 +++++ source/armarx/navigation/algorithms/Costmap.h | 63 +++++ .../navigation/algorithms/CostmapBuilder.cpp | 211 +++++++++++++++ .../navigation/algorithms/CostmapBuilder.h | 56 ++++ .../algorithms/NavigationCostMap.cpp | 243 ------------------ .../navigation/algorithms/NavigationCostMap.h | 92 ------- .../algorithms/astar/AStarPlanner.cpp | 2 +- .../spfa/ShortestPathFasterAlgorithm.cpp | 6 +- .../spfa/ShortestPathFasterAlgorithm.h | 6 +- .../algorithms/test/algorithms_spfa_test.cpp | 45 +++- source/armarx/navigation/algorithms/types.h | 35 +++ source/armarx/navigation/algorithms/util.cpp | 55 ++++ source/armarx/navigation/algorithms/util.h | 34 +++ .../components/Navigator/Navigator.cpp | 31 ++- source/armarx/navigation/core/StaticScene.h | 2 + 17 files changed, 593 insertions(+), 364 deletions(-) create mode 100644 source/armarx/navigation/algorithms/Costmap.cpp create mode 100644 source/armarx/navigation/algorithms/Costmap.h create mode 100644 source/armarx/navigation/algorithms/CostmapBuilder.cpp create mode 100644 source/armarx/navigation/algorithms/CostmapBuilder.h delete mode 100644 source/armarx/navigation/algorithms/NavigationCostMap.cpp delete mode 100644 source/armarx/navigation/algorithms/NavigationCostMap.h create mode 100644 source/armarx/navigation/algorithms/types.h create mode 100644 source/armarx/navigation/algorithms/util.cpp create mode 100644 source/armarx/navigation/algorithms/util.h diff --git a/CMakeLists.txt b/CMakeLists.txt index 1fdc9b99..9420d8af 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -46,6 +46,7 @@ armarx_find_package(PUBLIC OpenCV QUIET) # Required as RobotAPI is a legacy pro # ) # FetchContent_MakeAvailable(inotify_cpp) +add_definitions("-Werror=init-self -Werror=uninitialized") add_subdirectory(source) diff --git a/source/armarx/navigation/algorithms/CMakeLists.txt b/source/armarx/navigation/algorithms/CMakeLists.txt index d9ff3588..4b408d87 100644 --- a/source/armarx/navigation/algorithms/CMakeLists.txt +++ b/source/armarx/navigation/algorithms/CMakeLists.txt @@ -9,7 +9,9 @@ armarx_add_library(algorithms OpenCV SOURCES ./algorithms.cpp - ./NavigationCostMap.cpp + ./Costmap.cpp + ./CostmapBuilder.cpp + ./util.cpp # A* ./astar/AStarPlanner.cpp ./astar/Node.cpp @@ -22,7 +24,9 @@ armarx_add_library(algorithms ./smoothing/CircularPathSmoothing.cpp HEADERS ./algorithms.h - ./NavigationCostMap.h + ./Costmap.h + ./CostmapBuilder.h + ./util.h # A* ./astar/AStarPlanner.h ./astar/Node.h diff --git a/source/armarx/navigation/algorithms/Costmap.cpp b/source/armarx/navigation/algorithms/Costmap.cpp new file mode 100644 index 00000000..74bc8aa2 --- /dev/null +++ b/source/armarx/navigation/algorithms/Costmap.cpp @@ -0,0 +1,67 @@ +#include "Costmap.h" + +#include <algorithm> +#include <cmath> +#include <limits> + +#include <boost/geometry.hpp> +#include <boost/geometry/algorithms/detail/intersects/interface.hpp> + +#include <Eigen/Geometry> + +#include <IceUtil/Time.h> + +#include <VirtualRobot/BoundingBox.h> +#include <VirtualRobot/CollisionDetection/CollisionChecker.h> +#include <VirtualRobot/CollisionDetection/CollisionModel.h> +#include <VirtualRobot/Visualization/CoinVisualization/CoinVisualizationFactory.h> +#include <VirtualRobot/XML/ObjectIO.h> + +#include <ArmarXCore/core/exceptions/local/ExpressionException.h> +#include <ArmarXCore/core/logging/Logging.h> + +#include "armarx/navigation/algorithms/types.h" +#include "armarx/navigation/algorithms/util.h" +#include <armarx/navigation/conversions/eigen.h> + + +namespace armarx::navigation::algorithms +{ + + Costmap::Position + Costmap::toPosition(const Costmap::Index& index) const + { + 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; + + return pos; + } + + Costmap::Vertex + Costmap::toVertex(const Eigen::Vector2f& v) const + { + const float vX = + (v.x() - parameters.cellSize / 2 - sceneBounds.min.x()) / parameters.cellSize; + const float vY = + (v.y() - parameters.cellSize / 2 - sceneBounds.min.y()) / parameters.cellSize; + + ARMARX_CHECK(vX >= 0.F); + ARMARX_CHECK(vY >= 0.F); + + ARMARX_CHECK(vX <= (grid.rows() - 1)); + ARMARX_CHECK(vY <= (grid.cols() - 1)); + + return Vertex{.index = Index{static_cast<int>(vX), static_cast<int>(vY)}, .position = v}; + } + + bool + Costmap::isInCollision(const Position& p) const + { + const auto v = toVertex(p); + return grid(v.index.x(), v.index.y()) == 0.F; + } + + + +} // namespace armarx::navigation::algorithms diff --git a/source/armarx/navigation/algorithms/Costmap.h b/source/armarx/navigation/algorithms/Costmap.h new file mode 100644 index 00000000..b8e8a4cc --- /dev/null +++ b/source/armarx/navigation/algorithms/Costmap.h @@ -0,0 +1,63 @@ +#pragma once + +#include <Eigen/Core> + +#include <armarx/navigation/algorithms/types.h> + +namespace armarx::navigation::algorithms +{ + + class Costmap + { + public: + EIGEN_MAKE_ALIGNED_OPERATOR_NEW + + friend class CostmapBuilder; + + struct Parameters + { + // if set to false, distance to obstacles will be computed and not only a binary collision check + bool binaryGrid{false}; + + /// How big each cell is in the uniform grid. + float cellSize = 100.f; + }; + + + using Index = Eigen::Array2i; + using Position = Eigen::Vector2f; + using Grid = Eigen::MatrixXf; + + + Costmap(const Grid& grid, const Parameters& parameters, const SceneBounds& sceneBounds) : + grid(grid), sceneBounds(sceneBounds), parameters(parameters) + { + } + + struct Vertex + { + Index index; // row corresponds to y; column corresponds to x + Position position; + }; + + Position toPosition(const Index& index) const; + Vertex toVertex(const Position& v) const; + + const Grid& + getGrid() const + { + return grid; + } + + bool isInCollision(const Position& p) const; + + private: + Grid grid; + + const SceneBounds sceneBounds; + + const Parameters parameters; + }; + + +} // namespace armarx::navigation::algorithms diff --git a/source/armarx/navigation/algorithms/CostmapBuilder.cpp b/source/armarx/navigation/algorithms/CostmapBuilder.cpp new file mode 100644 index 00000000..50980e0a --- /dev/null +++ b/source/armarx/navigation/algorithms/CostmapBuilder.cpp @@ -0,0 +1,211 @@ +/** + * This file is part of ArmarX. + * + * ArmarX is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * ArmarX is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + * + * @author Fabian Reister ( fabian dot reister at kit dot edu ) + * @date 2022 + * @copyright http://www.gnu.org/licenses/gpl-2.0.txt + * GNU General Public License + */ + +#include "CostmapBuilder.h" + +#include <cstddef> + +#include <VirtualRobot/CollisionDetection/CollisionChecker.h> +#include <VirtualRobot/Robot.h> + +#include "ArmarXCore/core/exceptions/local/ExpressionException.h" +#include "ArmarXCore/core/logging/Logging.h" +#include "ArmarXCore/util/CPPUtility/trace.h" + +#include "armarx/navigation/algorithms/types.h" +#include "armarx/navigation/algorithms/util.h" +#include "armarx/navigation/conversions/eigen.h" +#include "armarx/navigation/core/basic_types.h" + +namespace armarx::navigation::algorithms +{ + + + CostmapBuilder::CostmapBuilder(const VirtualRobot::RobotPtr& robot, + const VirtualRobot::SceneObjectSetPtr& obstacles, + const Costmap::Parameters& parameters, + const std::string& robotCollisonModelName) : + robot(robot), + obstacles(obstacles), + parameters(parameters), + robotCollisionModelName(robotCollisonModelName) + { + ARMARX_CHECK_NOT_NULL(robot) << "Robot must be set"; + ARMARX_CHECK_NOT_NULL(obstacles); + ARMARX_CHECK(robot->hasRobotNode(robotCollisionModelName)); + } + + Costmap + CostmapBuilder::create() + { + + const auto sceneBounds = computeSceneBounds(obstacles); + const auto grid = createUniformGrid(sceneBounds, parameters); + + ARMARX_INFO << "Creating grid"; + Costmap costmap(grid, parameters, sceneBounds); + + ARMARX_INFO << "Filling grid"; + fillGridCosts(costmap); + ARMARX_INFO << "Filled grid"; + + return costmap; + } + + + Eigen::MatrixXf + CostmapBuilder::createUniformGrid(const SceneBounds& sceneBounds, + const Costmap::Parameters& parameters) + { + ARMARX_TRACE; + + ARMARX_INFO << "Scene bounds are " << sceneBounds.min << " and " << sceneBounds.max; + + //+1 for explicit rounding up + size_t c_x = (sceneBounds.max.x() - sceneBounds.min.x()) / parameters.cellSize + 1; + size_t c_y = (sceneBounds.max.y() - sceneBounds.min.y()) / parameters.cellSize + 1; + + ARMARX_INFO << "Grid size: " << c_y << ", " << c_x; + + ARMARX_INFO << "Resetting grid"; + return Eigen::MatrixXf(c_x, c_y); + } + + + float + CostmapBuilder::computeCost(const Costmap::Position& position, + VirtualRobot::RobotPtr& collisionRobot, + const VirtualRobot::CollisionModelPtr& robotCollisionModel) + { + ARMARX_TRACE; + ARMARX_CHECK_NOT_NULL(collisionRobot); + ARMARX_CHECK_NOT_NULL(robotCollisionModel); + ARMARX_CHECK_NOT_NULL(VirtualRobot::CollisionChecker::getGlobalCollisionChecker()); + ARMARX_CHECK_NOT_NULL(obstacles); + + const core::Pose globalPose(Eigen::Translation3f(conv::to3D(position))); + collisionRobot->setGlobalPose(globalPose.matrix()); + + const float distance = + VirtualRobot::CollisionChecker::getGlobalCollisionChecker()->calculateDistance( + robotCollisionModel, obstacles); + + return distance; + + + // Eigen::Vector3f P1; + // Eigen::Vector3f P2; + // int id1, id2; + + // float minDistance = std::numeric_limits<float>::max(); + + // // TODO omp... + // for (size_t i = 0; i < obstacles->getSize(); i++) + // { + // // cheap collision check + // // VirtualRobot::BoundingBox obstacleBbox = + // // obstacles->getSceneObject(i)->getCollisionModel()->getBoundingBox(true); + // // if (not intersects(robotBbox, obstacleBbox)) + // // { + // // continue; + // // } + + // // precise collision check + // const float dist = + // VirtualRobot::CollisionChecker::getGlobalCollisionChecker()->calculateDistance( + // robotCollisionModel, + // obstacles->getSceneObject(i)->getCollisionModel(), + // P1, + // P2, + // &id1, + // &id2); + + // // check if objects collide + // if ((dist <= parameters.cellSize / 2) or + // VirtualRobot::CollisionChecker::getGlobalCollisionChecker()->checkCollision( + // robotCollisionModel, obstacles->getSceneObject(i)->getCollisionModel())) + // { + // minDistance = 0; + // break; + // } + + // minDistance = std::min(minDistance, dist); + // } + // // return n->position.x() >= sceneBounds.min.x() && n->position.x() <= sceneBounds.max.x() && + // // n->position.y() >= sceneBounds.min.y() && n->position.y() <= sceneBounds.max.y(); + + // return minDistance; + } + + + void + CostmapBuilder::fillGridCosts(Costmap& costmap) + { + + VirtualRobot::RobotPtr collisionRobot; + VirtualRobot::CollisionModelPtr robotCollisionModel; + + const std::size_t c_x = costmap.grid.rows(); + const std::size_t c_y = costmap.grid.cols(); + + robot->setUpdateVisualization(false); + +#pragma omp parallel for schedule(static) private(collisionRobot,robotCollisionModel) default(shared) + for (unsigned int x = 0; x < c_x; x++) + { + // initialize if needed + if (collisionRobot == nullptr) + { +#pragma omp critical + { + ARMARX_DEBUG << "Copying robot"; + ARMARX_CHECK_NOT_NULL(robot); + collisionRobot = robot->clone("collision_robot_" + std::to_string(omp_get_thread_num())); + collisionRobot->setUpdateVisualization(false); + ARMARX_DEBUG << "Copying done"; + } + + ARMARX_CHECK_NOT_NULL(collisionRobot); + ARMARX_CHECK(collisionRobot->hasRobotNode(robotCollisionModelName)); + + ARMARX_CHECK(collisionRobot); + const auto collisionRobotNode = + collisionRobot->getRobotNode(robotCollisionModelName); + ARMARX_CHECK_NOT_NULL(collisionRobotNode); + + robotCollisionModel = collisionRobotNode->getCollisionModel(); + } + + ARMARX_CHECK_NOT_NULL(collisionRobot); + ARMARX_CHECK_NOT_NULL(robotCollisionModel); + + for (unsigned int y = 0; y < c_y; y++) + { + const Costmap::Index index{x, y}; + const Costmap::Position position = costmap.toPosition(index); + + costmap.grid(x, y) = computeCost(position, collisionRobot, robotCollisionModel); + } + } + } + + +} // namespace armarx::navigation::algorithms diff --git a/source/armarx/navigation/algorithms/CostmapBuilder.h b/source/armarx/navigation/algorithms/CostmapBuilder.h new file mode 100644 index 00000000..674e1615 --- /dev/null +++ b/source/armarx/navigation/algorithms/CostmapBuilder.h @@ -0,0 +1,56 @@ +/** + * This file is part of ArmarX. + * + * ArmarX is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * ArmarX is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + * + * @author Fabian Reister ( fabian dot reister at kit dot edu ) + * @date 2022 + * @copyright http://www.gnu.org/licenses/gpl-2.0.txt + * GNU General Public License + */ + +#pragma once + +#include <VirtualRobot/VirtualRobot.h> +#include <armarx/navigation/algorithms/Costmap.h> + +namespace armarx::navigation::algorithms +{ + + class CostmapBuilder + { + public: + CostmapBuilder(const VirtualRobot::RobotPtr& robot, + const VirtualRobot::SceneObjectSetPtr& obstacles, + const Costmap::Parameters& parameters, + const std::string& robotCollisonModelName); + + Costmap create(); + + private: + Eigen::MatrixXf createUniformGrid(const SceneBounds& sceneBounds, + const Costmap::Parameters& parameters); + + float computeCost(const Costmap::Position& position, + VirtualRobot::RobotPtr& collisionRobot, + const VirtualRobot::CollisionModelPtr& robotCollisionModel); + + void fillGridCosts(Costmap& costmap); + + const VirtualRobot::RobotPtr robot; + const VirtualRobot::SceneObjectSetPtr obstacles; + const Costmap::Parameters parameters; + const std::string robotCollisionModelName; + }; + +} // namespace armarx::navigation::algorithms diff --git a/source/armarx/navigation/algorithms/NavigationCostMap.cpp b/source/armarx/navigation/algorithms/NavigationCostMap.cpp deleted file mode 100644 index 9d994ecb..00000000 --- a/source/armarx/navigation/algorithms/NavigationCostMap.cpp +++ /dev/null @@ -1,243 +0,0 @@ -#include "NavigationCostMap.h" - -#include <algorithm> -#include <cmath> -#include <limits> - -#include <boost/geometry.hpp> -#include <boost/geometry/algorithms/detail/intersects/interface.hpp> - -#include <Eigen/Geometry> - -#include <IceUtil/Time.h> - -#include <VirtualRobot/BoundingBox.h> -#include <VirtualRobot/CollisionDetection/CollisionChecker.h> -#include <VirtualRobot/CollisionDetection/CollisionModel.h> -#include <VirtualRobot/Visualization/CoinVisualization/CoinVisualizationFactory.h> -#include <VirtualRobot/XML/ObjectIO.h> - -#include <ArmarXCore/core/exceptions/local/ExpressionException.h> -#include <ArmarXCore/core/logging/Logging.h> - -#include <armarx/navigation/conversions/eigen.h> - -namespace bg = boost::geometry; - -namespace armarx::navigation::algorithm -{ - - NavigationCostMap::NavigationCostMap(VirtualRobot::RobotPtr robot, - VirtualRobot::SceneObjectSetPtr obstacles, - const Parameters& parameters) : - robot(robot), obstacles(obstacles), parameters(parameters) - { - } - - NavigationCostMap::Position - NavigationCostMap::toPosition(const NavigationCostMap::Index& index) const - { - Eigen::Vector2f pos; - // TODO check if x and y must be switched - pos.x() = sceneBoundsMin.x() + index.x() * parameters.cellSize + parameters.cellSize / 2; - pos.y() = sceneBoundsMin.y() + index.y() * parameters.cellSize + parameters.cellSize / 2; - - return pos; - } - - void - NavigationCostMap::createUniformGrid() - { - ARMARX_TRACE; - - if (obstacles) - { - for (size_t i = 0; i < obstacles->getCollisionModels().size(); i++) - { - VirtualRobot::BoundingBox bb = obstacles->getCollisionModels()[i]->getBoundingBox(); - sceneBoundsMin.x() = std::min(bb.getMin().x(), sceneBoundsMin.x()); - sceneBoundsMin.y() = std::min(bb.getMin().y(), sceneBoundsMin.y()); - sceneBoundsMax.x() = std::max(bb.getMax().x(), sceneBoundsMax.x()); - sceneBoundsMax.y() = std::max(bb.getMax().y(), sceneBoundsMax.y()); - } - } - - ARMARX_INFO << "Scene bounds are " << sceneBoundsMin << " and " << sceneBoundsMax; - - //+1 for explicit rounding up - c_x = (sceneBoundsMax.x() - sceneBoundsMin.x()) / parameters.cellSize + 1; - c_y = (sceneBoundsMax.y() - sceneBoundsMin.y()) / parameters.cellSize + 1; - - ARMARX_INFO << "Grid size: " << c_y << ", " << c_x; - - ARMARX_INFO << "Resetting grid"; - grid = Eigen::MatrixXf(c_x, c_y); //.array(); - // grid = Eigen::ArrayXf(); //(c_x, c_y); - // grid->resize(c_x, c_y); - - ARMARX_INFO << "done."; - } - - - float - NavigationCostMap::computeCost(const NavigationCostMap::Position& position) - { - ARMARX_TRACE; - ARMARX_CHECK_NOT_NULL(robotCollisionModel); - ARMARX_CHECK_NOT_NULL(VirtualRobot::CollisionChecker::getGlobalCollisionChecker()); - ARMARX_CHECK_NOT_NULL(obstacles); - - const core::Pose globalPose = Eigen::Translation3f(conv::to3D(position)) * - Eigen::AngleAxisf(M_PI_2f32, Eigen::Vector3f::UnitX()); - - // auto colModel = robotCollisionModel->clone(); - // colModel->setGlobalPose(globalPose.matrix()); - - robotCollisionModel->setGlobalPose(globalPose.matrix()); - - // Unused. - if (false) - { - VirtualRobot::BoundingBox robotBbox = robotCollisionModel->getBoundingBox(true); - (void) robotBbox; - } - - Eigen::Vector3f P1; - Eigen::Vector3f P2; - int id1, id2; - - float minDistance = std::numeric_limits<float>::max(); - - // TODO omp... - for (size_t i = 0; i < obstacles->getSize(); i++) - { - // cheap collision check - // VirtualRobot::BoundingBox obstacleBbox = - // obstacles->getSceneObject(i)->getCollisionModel()->getBoundingBox(true); - // if (not intersects(robotBbox, obstacleBbox)) - // { - // continue; - // } - - // precise collision check - const float dist = - VirtualRobot::CollisionChecker::getGlobalCollisionChecker()->calculateDistance( - robotCollisionModel, - obstacles->getSceneObject(i)->getCollisionModel(), - P1, - P2, - &id1, - &id2); - - // check if objects collide - if ((dist <= parameters.cellSize / 2) or - VirtualRobot::CollisionChecker::getGlobalCollisionChecker()->checkCollision( - robotCollisionModel, obstacles->getSceneObject(i)->getCollisionModel())) - { - minDistance = 0; - break; - } - - minDistance = std::min(minDistance, dist); - } - // return n->position.x() >= sceneBoundsMin.x() && n->position.x() <= sceneBoundsMax.x() && - // n->position.y() >= sceneBoundsMin.y() && n->position.y() <= sceneBoundsMax.y(); - - return minDistance; - } - - NavigationCostMap::Vertex - NavigationCostMap::toVertex(const Eigen::Vector2f& v) const - { - const float v_x = (v.x() - parameters.cellSize / 2 - sceneBoundsMin.x()) / parameters.cellSize; - const float v_y = (v.y() - parameters.cellSize / 2 - sceneBoundsMin.y()) / parameters.cellSize; - - ARMARX_CHECK(v_x >= 0.F); - ARMARX_CHECK(v_y >= 0.F); - - ARMARX_CHECK(v_x <= (c_x - 1)); - ARMARX_CHECK(v_y <= (c_y - 1)); - - return Vertex{.index = Index{static_cast<int>(v_x), static_cast<int>(v_y)}, .position = v}; - } - - bool NavigationCostMap::isInCollision(const Position& p) const - { - const auto v = toVertex(p); - - return grid.value()(v.index.x(), v.index.y()) == 0.F; - } - - - void - NavigationCostMap::createCostmap() - { - ARMARX_TRACE; - std::vector<Eigen::Vector2f> result; - - ARMARX_CHECK_NOT_NULL(robot) << "Robot must be set"; - - - VirtualRobot::CoinVisualizationFactory factory; - const auto cylinder = factory.createCylinder(1500.F / 2, 2000.F); - - VirtualRobot::CollisionModelPtr collisionModel(new VirtualRobot::CollisionModel(cylinder)); - - - robotCollisionModel = collisionModel; - - - ARMARX_CHECK_NOT_NULL(robotCollisionModel) << "Collision model must be set!"; - - // ARMARX_CHECK(robot->hasRobotNode(robotColModelName)) << "No robot node " << robotColModelName; - // ARMARX_CHECK(robot->getRobotNode(robotColModelName)->getCollisionModel()) - // << "No collision model for robot node " << robotColModelName; - - // robotCollisionModel = robot->getRobotNode(robotColModelName)->getCollisionModel()->clone(); - robotCollisionModel->setGlobalPose(robot->getGlobalPose()); - - // static auto cylinder = VirtualRobot::ObjectIO::loadObstacle("/home/fabi/cylinder.xml"); - // ARMARX_CHECK_NOT_NULL(cylinder); - // cylinder->setGlobalPose(robot->getGlobalPose()); - - // robotCollisionModel = cylinder->getCollisionModel(); - - ARMARX_CHECK_NOT_NULL(robotCollisionModel); - - ARMARX_INFO << "Creating grid"; - createUniformGrid(); - - ARMARX_INFO << "Filling grid"; - fillGridCosts(); - - ARMARX_INFO << "Filled grid"; - } - - void - NavigationCostMap::setRobotCollisionModel(const VirtualRobot::CollisionModelPtr& collisionModel) - { - robotCollisionModel = collisionModel; - } - - void - NavigationCostMap::fillGridCosts() - { - int i = 0; - - for (unsigned int x = 0; x < c_x; x++) - { - for (unsigned int y = 0; y < c_y; y++) - { - const Index index{x, y}; - const Position position = toPosition(index); - - grid.value()(x, y) = computeCost(position); - - i++; - - ARMARX_INFO << i << "/" << c_x * c_y; - } - } - } - -} // namespace armarx::navigation::algorithm::astar diff --git a/source/armarx/navigation/algorithms/NavigationCostMap.h b/source/armarx/navigation/algorithms/NavigationCostMap.h deleted file mode 100644 index 75328ef4..00000000 --- a/source/armarx/navigation/algorithms/NavigationCostMap.h +++ /dev/null @@ -1,92 +0,0 @@ -#pragma once - -#include <cstddef> - -#include <Eigen/Core> - -#include <VirtualRobot/CollisionDetection/CollisionModel.h> - - -namespace armarx::navigation::algorithm -{ - - /** - * The A* planner - */ - class NavigationCostMap - { - public: - EIGEN_MAKE_ALIGNED_OPERATOR_NEW - - struct Parameters - { - // if set to false, distance to obstacles will be computed and not only a binary collision check - bool binaryGrid{false}; - - /// How big each cell is in the uniform grid. - float cellSize = 100.f; - }; - - - using Index = Eigen::Array2i; - using Position = Eigen::Vector2f; - using Grid = Eigen::MatrixXf; - - NavigationCostMap(VirtualRobot::RobotPtr robot, - VirtualRobot::SceneObjectSetPtr obstacles, - const Parameters& parameters); - - NavigationCostMap(const Grid& grid, - const Parameters& parameters, - const Eigen::Vector2f& sceneBoundsMin) : - grid(grid), sceneBoundsMin(sceneBoundsMin), parameters(parameters) - { - } - - void createCostmap(); - - void setRobotCollisionModel(const VirtualRobot::CollisionModelPtr& collisionModel); - - - struct Vertex - { - Index index; // row corresponds to y; column corresponds to x - Position position; - }; - - Position toPosition(const Index& index) const; - - const Grid& - getGrid() const - { - return grid.value(); - } - - Vertex toVertex(const Position& v) const; - - bool isInCollision(const Position& p) const; - - - private: - void createUniformGrid(); - float computeCost(const NavigationCostMap::Position& position); - - void fillGridCosts(); - - private: - std::optional<Grid> grid; - - size_t c_x = 0; - size_t c_y = 0; - - VirtualRobot::RobotPtr robot; - VirtualRobot::SceneObjectSetPtr obstacles; - - VirtualRobot::CollisionModelPtr robotCollisionModel; - - Eigen::Vector2f sceneBoundsMin; - Eigen::Vector2f sceneBoundsMax; - - const Parameters parameters; - }; -} // namespace armarx::navigation::algorithm diff --git a/source/armarx/navigation/algorithms/astar/AStarPlanner.cpp b/source/armarx/navigation/algorithms/astar/AStarPlanner.cpp index 3bb7aad4..5452be0d 100644 --- a/source/armarx/navigation/algorithms/astar/AStarPlanner.cpp +++ b/source/armarx/navigation/algorithms/astar/AStarPlanner.cpp @@ -116,7 +116,7 @@ namespace armarx::navigation::algorithm::astar pos.x() = sceneBoundsMin.x() + c * cellSize + cellSize / 2; pos.y() = sceneBoundsMin.y() + r * cellSize + cellSize / 2; - const float obstacleDistance = computeObstacleDistance(pos, robot); + const float obstacleDistance = computeObstacleDistance(pos, collisionRobot); grid[r][c] = std::make_shared<Node>(pos, obstacleDistance); } diff --git a/source/armarx/navigation/algorithms/spfa/ShortestPathFasterAlgorithm.cpp b/source/armarx/navigation/algorithms/spfa/ShortestPathFasterAlgorithm.cpp index 8fd47283..72b981ec 100644 --- a/source/armarx/navigation/algorithms/spfa/ShortestPathFasterAlgorithm.cpp +++ b/source/armarx/navigation/algorithms/spfa/ShortestPathFasterAlgorithm.cpp @@ -51,7 +51,7 @@ namespace armarx::navigation::algorithms::spfa } ShortestPathFasterAlgorithm::ShortestPathFasterAlgorithm( - const algorithm::NavigationCostMap& grid, + const Costmap& grid, const Parameters& params) : grid(grid), params(params) { @@ -64,7 +64,7 @@ namespace armarx::navigation::algorithms::spfa ARMARX_CHECK(not grid.isInCollision(start)) << "Start is in collision"; ARMARX_CHECK(not grid.isInCollision(goal)) << "Goal is in collision"; - const algorithm::NavigationCostMap::Vertex startVertex = grid.toVertex(start); + const Costmap::Vertex startVertex = grid.toVertex(start); const auto goalVertex = Eigen::Vector2i{grid.toVertex(goal).index}; ARMARX_INFO << "Planning from " << startVertex.index << " to " << goalVertex; @@ -252,7 +252,7 @@ namespace armarx::navigation::algorithms::spfa { continue; } - + output_parents.at(row).at(col) = unravel(parents[u], num_cols); } } diff --git a/source/armarx/navigation/algorithms/spfa/ShortestPathFasterAlgorithm.h b/source/armarx/navigation/algorithms/spfa/ShortestPathFasterAlgorithm.h index d0c22c09..de25ace9 100644 --- a/source/armarx/navigation/algorithms/spfa/ShortestPathFasterAlgorithm.h +++ b/source/armarx/navigation/algorithms/spfa/ShortestPathFasterAlgorithm.h @@ -25,7 +25,7 @@ #include <Eigen/Core> -#include <armarx/navigation/algorithms/NavigationCostMap.h> +#include <armarx/navigation/algorithms/Costmap.h> namespace armarx::navigation::algorithms::spfa @@ -39,7 +39,7 @@ namespace armarx::navigation::algorithms::spfa bool obstacleDistanceCosts{true}; }; - ShortestPathFasterAlgorithm(const algorithm::NavigationCostMap& grid, + ShortestPathFasterAlgorithm(const Costmap& grid, const Parameters& params); struct Result @@ -65,7 +65,7 @@ namespace armarx::navigation::algorithms::spfa private: - const algorithm::NavigationCostMap grid; + const Costmap grid; const Parameters params; }; diff --git a/source/armarx/navigation/algorithms/test/algorithms_spfa_test.cpp b/source/armarx/navigation/algorithms/test/algorithms_spfa_test.cpp index 97c57f6b..bea64e74 100644 --- a/source/armarx/navigation/algorithms/test/algorithms_spfa_test.cpp +++ b/source/armarx/navigation/algorithms/test/algorithms_spfa_test.cpp @@ -42,7 +42,8 @@ #include "ArmarXCore/core/system/ArmarXDataPath.h" #include <ArmarXCore/core/logging/Logging.h> -#include "armarx/navigation/algorithms/NavigationCostMap.h" +#include "armarx/navigation/algorithms/Costmap.h" +#include "armarx/navigation/algorithms/types.h" #include <armarx/navigation/Test.h> #include <armarx/navigation/algorithms/spfa/ShortestPathFasterAlgorithm.h> @@ -51,15 +52,19 @@ BOOST_AUTO_TEST_CASE(testSPFA) const int rows = 100; const int cols = 200; + const int cellSize = 100; + Eigen::Vector2i start{50, 130}; Eigen::Vector2i goal{50, 100}; Eigen::MatrixXf obstacleDistances(rows, cols); obstacleDistances.setOnes(); - const armarx::navigation::algorithm::NavigationCostMap::Parameters params; - const armarx::navigation::algorithm::NavigationCostMap costmap( - obstacleDistances, params, Eigen::Vector2f::Zero()); + const armarx::navigation::algorithms::SceneBounds sceneBounds{ + .min = Eigen::Vector2f::Zero(), .max = Eigen::Vector2f{rows * cellSize, cols * cellSize}}; + + const armarx::navigation::algorithms::Costmap::Parameters params; + const armarx::navigation::algorithms::Costmap costmap(obstacleDistances, params, sceneBounds); ARMARX_INFO << "computing ..."; @@ -110,9 +115,11 @@ BOOST_AUTO_TEST_CASE(testSPFAPlan) Eigen::MatrixXf obstacleDistances(rows, cols); obstacleDistances.setOnes(); - const armarx::navigation::algorithm::NavigationCostMap::Parameters params{.cellSize = cellSize}; - const armarx::navigation::algorithm::NavigationCostMap costmap( - obstacleDistances, params, Eigen::Vector2f::Zero()); + const armarx::navigation::algorithms::SceneBounds sceneBounds{ + .min = Eigen::Vector2f::Zero(), .max = Eigen::Vector2f{rows * cellSize, cols * cellSize}}; + + const armarx::navigation::algorithms::Costmap::Parameters params{.cellSize = cellSize}; + const armarx::navigation::algorithms::Costmap costmap(obstacleDistances, params, sceneBounds); ARMARX_INFO << "computing ..."; armarx::navigation::algorithms::spfa::ShortestPathFasterAlgorithm::Parameters spfaParams{ @@ -152,9 +159,15 @@ BOOST_AUTO_TEST_CASE(testGrid) BOOST_REQUIRE_GT(cellSize, 0); std::vector<float> sceneBoundsMinV(j["scene_bounds"]["min"]); + std::vector<float> sceneBoundsMaxV(j["scene_bounds"]["max"]); BOOST_REQUIRE_EQUAL(sceneBoundsMinV.size(), 2); + BOOST_REQUIRE_EQUAL(sceneBoundsMaxV.size(), 2); const Eigen::Vector2f sceneBoundsMin{sceneBoundsMinV.at(0), sceneBoundsMinV.at(1)}; + const Eigen::Vector2f sceneBoundsMax{sceneBoundsMaxV.at(0), sceneBoundsMaxV.at(1)}; + + const armarx::navigation::algorithms::SceneBounds sceneBounds{.min = sceneBoundsMin, + .max = sceneBoundsMax}; BOOST_REQUIRE(std::filesystem::exists(testExrFilename)); @@ -163,9 +176,9 @@ BOOST_AUTO_TEST_CASE(testGrid) Eigen::MatrixXf obstacleDistances; cv::cv2eigen(mat, obstacleDistances); - const armarx::navigation::algorithm::NavigationCostMap::Parameters params{.cellSize = cellSize}; - const armarx::navigation::algorithm::NavigationCostMap costmap( - obstacleDistances, params, sceneBoundsMin); + + const armarx::navigation::algorithms::Costmap::Parameters params{.cellSize = cellSize}; + const armarx::navigation::algorithms::Costmap costmap(obstacleDistances, params, sceneBounds); Eigen::Vector2f start{1500, 0}; @@ -200,9 +213,15 @@ BOOST_AUTO_TEST_CASE(testSPFAPlanWObstacleDistance) BOOST_REQUIRE_GT(cellSize, 0); std::vector<float> sceneBoundsMinV(j["scene_bounds"]["min"]); + std::vector<float> sceneBoundsMaxV(j["scene_bounds"]["max"]); BOOST_REQUIRE_EQUAL(sceneBoundsMinV.size(), 2); + BOOST_REQUIRE_EQUAL(sceneBoundsMaxV.size(), 2); const Eigen::Vector2f sceneBoundsMin{sceneBoundsMinV.at(0), sceneBoundsMinV.at(1)}; + const Eigen::Vector2f sceneBoundsMax{sceneBoundsMaxV.at(0), sceneBoundsMaxV.at(1)}; + + const armarx::navigation::algorithms::SceneBounds sceneBounds{.min = sceneBoundsMin, + .max = sceneBoundsMax}; BOOST_REQUIRE(std::filesystem::exists(testExrFilename)); @@ -212,9 +231,8 @@ BOOST_AUTO_TEST_CASE(testSPFAPlanWObstacleDistance) cv::cv2eigen(mat, obstacleDistances); obstacleDistances = obstacleDistances.transpose(); - const armarx::navigation::algorithm::NavigationCostMap::Parameters params{.cellSize = cellSize}; - const armarx::navigation::algorithm::NavigationCostMap costmap( - obstacleDistances, params, sceneBoundsMin); + const armarx::navigation::algorithms::Costmap::Parameters params{.cellSize = cellSize}; + const armarx::navigation::algorithms::Costmap costmap(obstacleDistances, params, sceneBounds); ARMARX_INFO << "computing ..."; armarx::navigation::algorithms::spfa::ShortestPathFasterAlgorithm::Parameters spfaParams{ @@ -228,5 +246,4 @@ BOOST_AUTO_TEST_CASE(testSPFAPlanWObstacleDistance) ARMARX_INFO << "done."; BOOST_CHECK(not path.empty()); - } diff --git a/source/armarx/navigation/algorithms/types.h b/source/armarx/navigation/algorithms/types.h new file mode 100644 index 00000000..4e685859 --- /dev/null +++ b/source/armarx/navigation/algorithms/types.h @@ -0,0 +1,35 @@ +/** + * This file is part of ArmarX. + * + * ArmarX is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * ArmarX is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + * + * @author Fabian Reister ( fabian dot reister at kit dot edu ) + * @date 2022 + * @copyright http://www.gnu.org/licenses/gpl-2.0.txt + * GNU General Public License + */ + +#pragma once + +#include <Eigen/Core> + +namespace armarx::navigation::algorithms +{ + + struct SceneBounds + { + Eigen::Vector2f min = Eigen::Vector2f::Zero(); + Eigen::Vector2f max = Eigen::Vector2f::Zero(); + }; + +} // namespace armarx::navigation::algorithms diff --git a/source/armarx/navigation/algorithms/util.cpp b/source/armarx/navigation/algorithms/util.cpp new file mode 100644 index 00000000..53a3aafa --- /dev/null +++ b/source/armarx/navigation/algorithms/util.cpp @@ -0,0 +1,55 @@ +/** + * This file is part of ArmarX. + * + * ArmarX is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * ArmarX is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + * + * @author Fabian Reister ( fabian dot reister at kit dot edu ) + * @date 2022 + * @copyright http://www.gnu.org/licenses/gpl-2.0.txt + * GNU General Public License + */ + +#include "util.h" + +#include <VirtualRobot/BoundingBox.h> +#include <VirtualRobot/CollisionDetection/CollisionModel.h> +#include <VirtualRobot/SceneObjectSet.h> + +#include "ArmarXCore/core/exceptions/local/ExpressionException.h" + +namespace armarx::navigation::algorithms +{ + + + SceneBounds + computeSceneBounds(const VirtualRobot::SceneObjectSetPtr& obstacles) + { + SceneBounds bounds; + + ARMARX_CHECK_NOT_NULL(obstacles); + ARMARX_CHECK(not obstacles->getCollisionModels().empty()); + + for (size_t i = 0; i < obstacles->getCollisionModels().size(); i++) + { + VirtualRobot::BoundingBox bb = obstacles->getCollisionModels()[i]->getBoundingBox(); + bounds.min.x() = std::min(bb.getMin().x(), bounds.min.x()); + bounds.min.y() = std::min(bb.getMin().y(), bounds.min.y()); + bounds.max.x() = std::max(bb.getMax().x(), bounds.max.x()); + bounds.max.y() = std::max(bb.getMax().y(), bounds.max.y()); + } + + return bounds; + } + + +} // namespace armarx::navigation::algorithms diff --git a/source/armarx/navigation/algorithms/util.h b/source/armarx/navigation/algorithms/util.h new file mode 100644 index 00000000..add037fc --- /dev/null +++ b/source/armarx/navigation/algorithms/util.h @@ -0,0 +1,34 @@ + +/** + * This file is part of ArmarX. + * + * ArmarX is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * ArmarX is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + * + * @author Fabian Reister ( fabian dot reister at kit dot edu ) + * @date 2022 + * @copyright http://www.gnu.org/licenses/gpl-2.0.txt + * GNU General Public License + */ + +#pragma once + +#include <VirtualRobot/VirtualRobot.h> + +#include <armarx/navigation/algorithms/types.h> + +namespace armarx::navigation::algorithms +{ + + SceneBounds computeSceneBounds(const VirtualRobot::SceneObjectSetPtr& obstacles); + +} // namespace armarx::navigation::algorithms diff --git a/source/armarx/navigation/components/Navigator/Navigator.cpp b/source/armarx/navigation/components/Navigator/Navigator.cpp index fb665e71..8a36f658 100644 --- a/source/armarx/navigation/components/Navigator/Navigator.cpp +++ b/source/armarx/navigation/components/Navigator/Navigator.cpp @@ -56,7 +56,8 @@ #include "RobotAPI/libraries/armem_vision/client/occupancy_grid/Reader.h" #include <RobotAPI/libraries/core/remoterobot/RemoteRobot.h> -#include <armarx/navigation/algorithms/NavigationCostMap.h> +#include "armarx/navigation/algorithms/CostmapBuilder.h" +#include <armarx/navigation/algorithms/Costmap.h> #include <armarx/navigation/algorithms/astar/util.h> #include <armarx/navigation/client/NavigationStackConfig.h> #include <armarx/navigation/client/PathBuilder.h> @@ -444,7 +445,25 @@ namespace armarx::navigation::components ARMARX_TRACE; const objpose::ObjectPoseSeq objectPoses = ObjectPoseClientPluginUser::getObjectPoses(); - core::StaticScene scene{.objects = util::asSceneObjects(objectPoses)}; + const auto objects = util::asSceneObjects(objectPoses); + + ARMARX_INFO << "Creating costmap"; + + algorithms::CostmapBuilder costmapBuilder( + getRobot(), + objects, + algorithms::Costmap::Parameters{.binaryGrid = false, .cellSize = 100}, + "Platform-navigation-colmodel"); + + const auto costmap = costmapBuilder.create(); + + ARMARX_INFO << "Done"; + + ARMARX_TRACE; + const auto grid = costmap.getGrid(); + + core::StaticScene scene{.objects = objects, + .costmap = std::make_unique<algorithms::Costmap>(costmap)}; ARMARX_INFO << "The object scene consists of " << scene.objects->getSize() << " objects"; @@ -482,13 +501,13 @@ namespace armarx::navigation::components ARMARX_INFO << "Creating costmap"; - algorithm::NavigationCostMap costmap( + algorithms::CostmapBuilder costmapBuilder( getRobot(), scene.objects, - algorithm::NavigationCostMap::Parameters{.binaryGrid = false, - .cellSize = 100}); + algorithms::Costmap::Parameters{.binaryGrid = false, .cellSize = 100}, + "Platform-navigation-colmodel"); - costmap.createCostmap(); + const auto costmap = costmapBuilder.create(); ARMARX_INFO << "Done"; diff --git a/source/armarx/navigation/core/StaticScene.h b/source/armarx/navigation/core/StaticScene.h index 4d05a2fe..f70a2451 100644 --- a/source/armarx/navigation/core/StaticScene.h +++ b/source/armarx/navigation/core/StaticScene.h @@ -25,6 +25,7 @@ #include <memory> #include <VirtualRobot/VirtualRobot.h> +#include <armarx/navigation/algorithms/Costmap.h> namespace armarx::navigation::core { @@ -32,6 +33,7 @@ namespace armarx::navigation::core struct StaticScene { VirtualRobot::SceneObjectSetPtr objects; + std::unique_ptr<algorithms::Costmap> costmap; }; using StaticScenePtr = std::shared_ptr<StaticScene>; -- GitLab From 264c8d27601d8f40ea930e672f389a3a357c26cb Mon Sep 17 00:00:00 2001 From: Fabian Reister <fabian.reister@kit.edu> Date: Mon, 10 Jan 2022 21:54:48 +0100 Subject: [PATCH 02/11] a star planner now using gridmap --- .../navigation/algorithms/CostmapBuilder.cpp | 11 +- .../algorithms/astar/AStarPlanner.cpp | 141 ++++-------------- .../algorithms/astar/AStarPlanner.h | 17 +-- .../components/Navigator/Navigator.cpp | 12 +- .../navigation/global_planning/AStar.cpp | 10 +- 5 files changed, 51 insertions(+), 140 deletions(-) diff --git a/source/armarx/navigation/algorithms/CostmapBuilder.cpp b/source/armarx/navigation/algorithms/CostmapBuilder.cpp index 50980e0a..2e9b9b1f 100644 --- a/source/armarx/navigation/algorithms/CostmapBuilder.cpp +++ b/source/armarx/navigation/algorithms/CostmapBuilder.cpp @@ -63,7 +63,8 @@ namespace armarx::navigation::algorithms ARMARX_INFO << "Creating grid"; Costmap costmap(grid, parameters, sceneBounds); - ARMARX_INFO << "Filling grid"; + ARMARX_INFO << "Filling grid with size (" << costmap.getGrid().rows() << "/" + << costmap.getGrid().cols() << ")"; fillGridCosts(costmap); ARMARX_INFO << "Filled grid"; @@ -83,7 +84,7 @@ namespace armarx::navigation::algorithms size_t c_x = (sceneBounds.max.x() - sceneBounds.min.x()) / parameters.cellSize + 1; size_t c_y = (sceneBounds.max.y() - sceneBounds.min.y()) / parameters.cellSize + 1; - ARMARX_INFO << "Grid size: " << c_y << ", " << c_x; + ARMARX_INFO << "Grid size: " << c_x << ", " << c_y; ARMARX_INFO << "Resetting grid"; return Eigen::MatrixXf(c_x, c_y); @@ -168,7 +169,8 @@ namespace armarx::navigation::algorithms robot->setUpdateVisualization(false); -#pragma omp parallel for schedule(static) private(collisionRobot,robotCollisionModel) default(shared) +#pragma omp parallel for schedule(static) private(collisionRobot, \ + robotCollisionModel) default(shared) for (unsigned int x = 0; x < c_x; x++) { // initialize if needed @@ -178,7 +180,8 @@ namespace armarx::navigation::algorithms { ARMARX_DEBUG << "Copying robot"; ARMARX_CHECK_NOT_NULL(robot); - collisionRobot = robot->clone("collision_robot_" + std::to_string(omp_get_thread_num())); + collisionRobot = + robot->clone("collision_robot_" + std::to_string(omp_get_thread_num())); collisionRobot->setUpdateVisualization(false); ARMARX_DEBUG << "Copying done"; } diff --git a/source/armarx/navigation/algorithms/astar/AStarPlanner.cpp b/source/armarx/navigation/algorithms/astar/AStarPlanner.cpp index 5452be0d..2b4a2d4e 100644 --- a/source/armarx/navigation/algorithms/astar/AStarPlanner.cpp +++ b/source/armarx/navigation/algorithms/astar/AStarPlanner.cpp @@ -43,12 +43,8 @@ namespace armarx::navigation::algorithm::astar return bg::intersects(box1, box2); } - AStarPlanner::AStarPlanner(VirtualRobot::RobotPtr robot, - VirtualRobot::SceneObjectSetPtr obstacles, - float cellSize) : - Planner2D(robot, obstacles), cellSize(cellSize) + AStarPlanner::AStarPlanner(const algorithms::Costmap& costmap) : costmap(costmap) { - ARMARX_CHECK_GREATER_EQUAL(static_cast<int>(obstacles->getSize()), 0); } float @@ -57,72 +53,34 @@ namespace armarx::navigation::algorithm::astar return (1.F - obstacleDistanceWeightFactor) * (n1->position - n2->position).norm(); } - float - AStarPlanner::computeObstacleDistance(const Eigen::Vector2f& pos, - VirtualRobot::RobotPtr& robot) const - { - - core::Pose global_T_robot = core::Pose::Identity(); - global_T_robot.translation().head<2>() = pos; - robot->setGlobalPose(global_T_robot.matrix()); - - const auto robotCollisionModel = - robot->getRobotNode(robotColModelName)->getCollisionModel(); - - const float distance = - VirtualRobot::CollisionChecker::getGlobalCollisionChecker()->calculateDistance( - robotCollisionModel, obstacles); - - return distance; - } - void AStarPlanner::createUniformGrid() { ARMARX_TRACE; - ARMARX_VERBOSE << "Scene bounds are " << sceneBoundsMin << " and " << sceneBoundsMax; - - //+1 for explicit rounding up - cols = (sceneBoundsMax.x() - sceneBoundsMin.x()) / cellSize + 1; - rows = (sceneBoundsMax.y() - sceneBoundsMin.y()) / cellSize + 1; - - ARMARX_VERBOSE << "Grid size: " << rows << ", " << cols; + const size_t rows = costmap.getGrid().rows(); + const size_t cols = costmap.getGrid().cols(); // create the grid with the correct size + ARMARX_INFO << "Creating grid"; for (size_t r = 0; r < rows; r++) { grid.push_back(std::vector<NodePtr>(cols)); } - ARMARX_INFO << "Using " << omp_get_num_threads() << " threads to build grid"; - - VirtualRobot::RobotPtr collisionRobot; - -#pragma omp parallel for schedule(static) private(collisionRobot) default(shared) + // intitializing grid for (size_t r = 0; r < rows; r++) { - // initialize if needed - if (collisionRobot == nullptr) - { - collisionRobot = - robot->clone("collision_robot_" + std::to_string(omp_get_thread_num())); - collisionRobot->setUpdateVisualization(false); - } - for (size_t c = 0; c < cols; c++) { - Eigen::Vector2f pos; - pos.x() = sceneBoundsMin.x() + c * cellSize + cellSize / 2; - pos.y() = sceneBoundsMin.y() + r * cellSize + cellSize / 2; - - const float obstacleDistance = computeObstacleDistance(pos, collisionRobot); - + const auto pos = costmap.toPosition({r, c}); + const float obstacleDistance = costmap.getGrid()(r, c); + grid[r][c] = std::make_shared<Node>(pos, obstacleDistance); } } - ARMARX_INFO << "Finished initialization of grid"; + ARMARX_INFO << "Creating graph"; // Init successors for (size_t r = 0; r < rows; r++) @@ -140,24 +98,26 @@ namespace armarx::navigation::algorithm::astar { for (int nC = -1; nC <= 1; nC++) { - const int neighborIndexX = c + nC; - const int neighborIndexY = r + nR; - if (neighborIndexX < 0 || neighborIndexY < 0 || (nR == 0 && nC == 0)) + const int neighborIndexC = c + nC; + const int neighborIndexR = r + nR; + if (neighborIndexC < 0 || neighborIndexR < 0 || (nR == 0 && nC == 0)) { continue; } - if (neighborIndexY >= static_cast<int>(rows) || - neighborIndexX >= static_cast<int>(cols)) + if (neighborIndexR >= static_cast<int>(rows) || + neighborIndexC >= static_cast<int>(cols)) { continue; } - grid[neighborIndexY][neighborIndexX]->successors.push_back(candidate); + grid[neighborIndexR][neighborIndexC]->successors.push_back(candidate); } } } } + + ARMARX_INFO << "Done."; } bool @@ -165,51 +125,24 @@ namespace armarx::navigation::algorithm::astar { ARMARX_TRACE; ARMARX_CHECK_NOT_NULL(n); - ARMARX_CHECK_NOT_NULL(robotCollisionModel); - ARMARX_CHECK_NOT_NULL(VirtualRobot::CollisionChecker::getGlobalCollisionChecker()); - ARMARX_CHECK_NOT_NULL(obstacles); - - const core::Pose globalPose(Eigen::Translation3f(conv::to3D(n->position))); //* - //Eigen::AngleAxisf(M_PI_2f32, Eigen::Vector3f::UnitX()); - - robotCollisionModel->setGlobalPose(globalPose.matrix()); - - VirtualRobot::BoundingBox robotBbox = robotCollisionModel->getBoundingBox(true); - Eigen::Vector3f P1, P2; - for (size_t i = 0; i < obstacles->getSize(); i++) - { - // cheap collision check - VirtualRobot::BoundingBox obstacleBbox = - obstacles->getSceneObject(i)->getCollisionModel()->getBoundingBox(true); - if (not intersects(robotBbox, obstacleBbox)) - { - continue; - } - - // precise collision check - bool collision = - VirtualRobot::CollisionChecker::getGlobalCollisionChecker()->checkCollision( - robotCollisionModel, obstacles->getSceneObject(i)->getCollisionModel()); - - if (collision) - { - return false; - } - } - return n->position.x() >= sceneBoundsMin.x() && n->position.x() <= sceneBoundsMax.x() && - n->position.y() >= sceneBoundsMin.y() && n->position.y() <= sceneBoundsMax.y(); + return not costmap.isInCollision(n->position); } NodePtr AStarPlanner::closestNode(const Eigen::Vector2f& v) { - float r = (v.y() - cellSize / 2 - sceneBoundsMin.y()) / cellSize; - float c = (v.x() - cellSize / 2 - sceneBoundsMin.x()) / cellSize; + const auto vertex = costmap.toVertex(v); + + const int r = vertex.index.x(); + const int c = vertex.index.y(); ARMARX_CHECK_GREATER_EQUAL(r, 0.F); ARMARX_CHECK_GREATER_EQUAL(c, 0.F); + const size_t rows = costmap.getGrid().rows(); + const size_t cols = costmap.getGrid().cols(); + ARMARX_CHECK_LESS_EQUAL(r, rows - 1); ARMARX_CHECK_LESS_EQUAL(c, cols - 1); @@ -223,23 +156,6 @@ namespace armarx::navigation::algorithm::astar grid.clear(); std::vector<Eigen::Vector2f> result; - ARMARX_CHECK_NOT_NULL(robot); - - // ARMARX_CHECK(robot->hasRobotNode(robotColModelName)) << "No robot node " << robotColModelName; - // ARMARX_CHECK(robot->getRobotNode(robotColModelName)->getCollisionModel()) - // << "No collision model for robot node " << robotColModelName; - - // robotCollisionModel = robot->getRobotNode(robotColModelName)->getCollisionModel()->clone(); - ARMARX_CHECK_NOT_NULL(robotCollisionModel); - robotCollisionModel->setGlobalPose(robot->getGlobalPose()); - - // static auto cylinder = VirtualRobot::ObjectIO::loadObstacle("/home/fabi/cylinder.xml"); - // ARMARX_CHECK_NOT_NULL(cylinder); - // cylinder->setGlobalPose(robot->getGlobalPose()); - - // robotCollisionModel = cylinder->getCollisionModel(); - - createUniformGrid(); ARMARX_DEBUG << "Setting start node for position " << start; NodePtr nodeStart = closestNode(start); @@ -315,13 +231,6 @@ namespace armarx::navigation::algorithm::astar return result; } - void - AStarPlanner::setRobotCollisionModel(const std::string& collisionModelNodeName) - { - robotColModelName = collisionModelNodeName; - robotCollisionModel = robot->getRobotNode(collisionModelNodeName)->getCollisionModel(); - } - float AStarPlanner::costs(const NodePtr& n1, const NodePtr& n2) const { diff --git a/source/armarx/navigation/algorithms/astar/AStarPlanner.h b/source/armarx/navigation/algorithms/astar/AStarPlanner.h index 5737f628..9f6e7496 100644 --- a/source/armarx/navigation/algorithms/astar/AStarPlanner.h +++ b/source/armarx/navigation/algorithms/astar/AStarPlanner.h @@ -6,6 +6,7 @@ #include "Node.h" #include "Planner2D.h" +#include "armarx/navigation/algorithms/Costmap.h" namespace armarx::navigation::algorithm::astar { @@ -13,18 +14,14 @@ namespace armarx::navigation::algorithm::astar /** * The A* planner */ - class AStarPlanner : public Planner2D + class AStarPlanner //: public Planner2D { public: EIGEN_MAKE_ALIGNED_OPERATOR_NEW - AStarPlanner(VirtualRobot::RobotPtr robot, - VirtualRobot::SceneObjectSetPtr obstacles = {}, - float cellSize = 100.f); + AStarPlanner(const algorithms::Costmap& costmap); - std::vector<Eigen::Vector2f> plan(const Eigen::Vector2f& start, const Eigen::Vector2f& goal) override; - - void setRobotCollisionModel(const std::string& collisionModelNodeName); + std::vector<Eigen::Vector2f> plan(const Eigen::Vector2f& start, const Eigen::Vector2f& goal) /* override */; private: float heuristic(const NodePtr& n1, const NodePtr& n2); @@ -36,14 +33,10 @@ namespace armarx::navigation::algorithm::astar float computeObstacleDistance(const Eigen::Vector2f& pos, VirtualRobot::RobotPtr& robot) const; private: - /// How big each cell is in the uniform grid. - float cellSize; + const algorithms::Costmap costmap; std::vector<std::vector<NodePtr>> grid; - size_t cols = 0; - size_t rows = 0; - const float obstacleDistanceWeightFactor = 0.5; const float maxObstacleDistance = 1500; // [mm] diff --git a/source/armarx/navigation/components/Navigator/Navigator.cpp b/source/armarx/navigation/components/Navigator/Navigator.cpp index 8a36f658..14430f5e 100644 --- a/source/armarx/navigation/components/Navigator/Navigator.cpp +++ b/source/armarx/navigation/components/Navigator/Navigator.cpp @@ -31,6 +31,8 @@ #include <utility> #include <Eigen/Geometry> +#include <opencv2/core/eigen.hpp> +#include <opencv2/imgcodecs.hpp> #include <Ice/Current.h> @@ -216,7 +218,15 @@ namespace armarx::navigation::components { std::lock_guard g{scene.staticSceneMtx}; - scene.staticScene = staticScene(); + + if (not scene.staticScene.has_value()) + { + scene.staticScene = staticScene(); + + cv::Mat1f mat; + cv::eigen2cv(scene.staticScene->costmap->getGrid(), mat); + cv::imwrite("/tmp/grid.exr", mat); + } } // TODO dynamic scene diff --git a/source/armarx/navigation/global_planning/AStar.cpp b/source/armarx/navigation/global_planning/AStar.cpp index 641492e1..16ca1777 100644 --- a/source/armarx/navigation/global_planning/AStar.cpp +++ b/source/armarx/navigation/global_planning/AStar.cpp @@ -159,13 +159,9 @@ namespace armarx::navigation::global_planning ARMARX_TRACE; std::lock_guard g{scene.staticSceneMtx}; - algorithm::astar::AStarPlanner planner(scene.robot, scene.staticScene->objects, 100.F); - // planner.setRobotColModel("Platform-colmodel"); - - // planner.setRobotColModel("Platform-colmodel"); - //planner.setRobotCollisionModel(robotCollisionModel()); - planner.setRobotCollisionModel("Platform-navigation-colmodel"); - + // FIXME check if costmap is available + algorithm::astar::AStarPlanner planner(*scene.staticScene->costmap); + const Eigen::Vector2f goalPos = conv::to2D(goal.translation()); const auto timeStart = IceUtil::Time::now(); -- GitLab From 2444e56b80d8e3e8f6f18a5f45faa7d1a34b8d4f Mon Sep 17 00:00:00 2001 From: Fabian Reister <fabian.reister@kit.edu> Date: Tue, 11 Jan 2022 13:54:53 +0100 Subject: [PATCH 03/11] spfa wrapper --- source/armarx/navigation/algorithms/Costmap.h | 5 + .../algorithms/astar/AStarPlanner.cpp | 4 +- .../spfa/ShortestPathFasterAlgorithm.cpp | 41 ++-- .../spfa/ShortestPathFasterAlgorithm.h | 5 +- .../components/Navigator/Navigator.cpp | 74 ++++++ .../components/Navigator/Navigator.h | 1 + .../factories/GlobalPlannerFactory.cpp | 9 +- .../navigation/global_planning/CMakeLists.txt | 3 + .../navigation/global_planning/SPFA.cpp | 231 ++++++++++++++++++ .../armarx/navigation/global_planning/SPFA.h | 71 ++++++ .../global_planning/aron/SPFAParams.xml | 25 ++ .../global_planning/aron_conversions.cpp | 23 ++ .../global_planning/aron_conversions.h | 5 + .../armarx/navigation/global_planning/core.h | 1 + 14 files changed, 477 insertions(+), 21 deletions(-) create mode 100644 source/armarx/navigation/global_planning/SPFA.cpp create mode 100644 source/armarx/navigation/global_planning/SPFA.h create mode 100644 source/armarx/navigation/global_planning/aron/SPFAParams.xml diff --git a/source/armarx/navigation/algorithms/Costmap.h b/source/armarx/navigation/algorithms/Costmap.h index b8e8a4cc..ffd4edee 100644 --- a/source/armarx/navigation/algorithms/Costmap.h +++ b/source/armarx/navigation/algorithms/Costmap.h @@ -51,6 +51,11 @@ namespace armarx::navigation::algorithms bool isInCollision(const Position& p) const; + const Parameters& params() const noexcept + { + return parameters; + } + private: Grid grid; diff --git a/source/armarx/navigation/algorithms/astar/AStarPlanner.cpp b/source/armarx/navigation/algorithms/astar/AStarPlanner.cpp index 2b4a2d4e..bddc5157 100644 --- a/source/armarx/navigation/algorithms/astar/AStarPlanner.cpp +++ b/source/armarx/navigation/algorithms/astar/AStarPlanner.cpp @@ -140,8 +140,8 @@ namespace armarx::navigation::algorithm::astar ARMARX_CHECK_GREATER_EQUAL(r, 0.F); ARMARX_CHECK_GREATER_EQUAL(c, 0.F); - const size_t rows = costmap.getGrid().rows(); - const size_t cols = costmap.getGrid().cols(); + const int rows = static_cast<int>(costmap.getGrid().rows()); + const int cols = static_cast<int>(costmap.getGrid().cols()); ARMARX_CHECK_LESS_EQUAL(r, rows - 1); ARMARX_CHECK_LESS_EQUAL(c, cols - 1); diff --git a/source/armarx/navigation/algorithms/spfa/ShortestPathFasterAlgorithm.cpp b/source/armarx/navigation/algorithms/spfa/ShortestPathFasterAlgorithm.cpp index 72b981ec..8ba7681d 100644 --- a/source/armarx/navigation/algorithms/spfa/ShortestPathFasterAlgorithm.cpp +++ b/source/armarx/navigation/algorithms/spfa/ShortestPathFasterAlgorithm.cpp @@ -28,6 +28,8 @@ #include "ArmarXCore/core/exceptions/local/ExpressionException.h" #include "ArmarXCore/core/logging/Logging.h" +#include "armarx/navigation/algorithms/Costmap.h" + namespace armarx::navigation::algorithms::spfa { @@ -50,26 +52,26 @@ namespace armarx::navigation::algorithms::spfa return p; } - ShortestPathFasterAlgorithm::ShortestPathFasterAlgorithm( - const Costmap& grid, - const Parameters& params) : - grid(grid), params(params) + ShortestPathFasterAlgorithm::ShortestPathFasterAlgorithm(const Costmap& grid, + const Parameters& params) : + costmap(grid), params(params) { - ARMARX_INFO << "Grid with size (" << grid.getGrid().rows() << ", " << grid.getGrid().cols() << ")."; + ARMARX_INFO << "Grid with size (" << grid.getGrid().rows() << ", " << grid.getGrid().cols() + << ")."; } std::vector<Eigen::Vector2f> ShortestPathFasterAlgorithm::plan(const Eigen::Vector2f& start, const Eigen::Vector2f& goal) { - ARMARX_CHECK(not grid.isInCollision(start)) << "Start is in collision"; - ARMARX_CHECK(not grid.isInCollision(goal)) << "Goal is in collision"; + ARMARX_CHECK(not costmap.isInCollision(start)) << "Start is in collision"; + ARMARX_CHECK(not costmap.isInCollision(goal)) << "Goal is in collision"; - const Costmap::Vertex startVertex = grid.toVertex(start); - const auto goalVertex = Eigen::Vector2i{grid.toVertex(goal).index}; + const Costmap::Vertex startVertex = costmap.toVertex(start); + const auto goalVertex = Eigen::Vector2i{costmap.toVertex(goal).index}; ARMARX_INFO << "Planning from " << startVertex.index << " to " << goalVertex; - const Result result = spfa(grid.getGrid(), Eigen::Vector2i{startVertex.index}); + const Result result = spfa(costmap.getGrid(), Eigen::Vector2i{startVertex.index}); const auto isStart = [&startVertex](const Eigen::Vector2i& v) { return (v.array() == startVertex.index.array()).all(); }; @@ -101,7 +103,7 @@ namespace armarx::navigation::algorithms::spfa break; } - path.push_back(grid.toPosition(parent.array())); + path.push_back(costmap.toPosition(parent.array())); pt = &parent; } @@ -115,6 +117,12 @@ namespace armarx::navigation::algorithms::spfa return path; } + ShortestPathFasterAlgorithm::Result + ShortestPathFasterAlgorithm::spfa(const Eigen::Vector2f& start) + { + return spfa(costmap.getGrid(), costmap.toVertex(start).index); + } + ShortestPathFasterAlgorithm::Result ShortestPathFasterAlgorithm::spfa(const Eigen::MatrixXf& inputMap, @@ -177,14 +185,15 @@ namespace armarx::navigation::algorithms::spfa continue; - const float obstacleDistance1 = inputMap(row, col); - const float obstacleDistance2 = inputMap(ip, jp); + const float obstacleDistance1 = std::min(inputMap(row, col), 1000.F); + const float obstacleDistance2 = std::min(inputMap(ip, jp), 1000.F); const float travelCost = dir_lengths[k]; - const float obstacleDistanceCost = obstacleDistance1 - obstacleDistance2; + // const float obstacleDistanceCost = std::max(obstacleDistance1 - obstacleDistance2, 0.F) / costmap.params().cellSize; + const float targetDistanceCost = 3* (1000.F - obstacleDistance2) / 1000.F; const float edgeCost = params.obstacleDistanceCosts - ? travelCost + obstacleDistanceCost + ? travelCost + targetDistanceCost : travelCost; int e = ravel(v, edge_counts[v], max_edges_per_vert); @@ -248,7 +257,7 @@ namespace armarx::navigation::algorithms::spfa int u = ravel(row, col, num_cols); output_dists(row, col) = (dists[u] < inf - eps) * dists[u]; - if(parents[u] == -1) // no parent + if (parents[u] == -1) // no parent { continue; } diff --git a/source/armarx/navigation/algorithms/spfa/ShortestPathFasterAlgorithm.h b/source/armarx/navigation/algorithms/spfa/ShortestPathFasterAlgorithm.h index de25ace9..85909558 100644 --- a/source/armarx/navigation/algorithms/spfa/ShortestPathFasterAlgorithm.h +++ b/source/armarx/navigation/algorithms/spfa/ShortestPathFasterAlgorithm.h @@ -53,6 +53,9 @@ namespace armarx::navigation::algorithms::spfa const Eigen::Vector2f& goal); + + Result spfa(const Eigen::Vector2f& start); + // protected: /** * @brief Implementation highly inspired by github.com:jimmyyhwu/spatial-action-maps @@ -65,7 +68,7 @@ namespace armarx::navigation::algorithms::spfa private: - const Costmap grid; + const Costmap costmap; const Parameters params; }; diff --git a/source/armarx/navigation/components/Navigator/Navigator.cpp b/source/armarx/navigation/components/Navigator/Navigator.cpp index 14430f5e..db4c14da 100644 --- a/source/armarx/navigation/components/Navigator/Navigator.cpp +++ b/source/armarx/navigation/components/Navigator/Navigator.cpp @@ -26,20 +26,25 @@ #include <algorithm> #include <cmath> #include <cstddef> +#include <cstdint> #include <iterator> #include <memory> #include <utility> #include <Eigen/Geometry> + #include <opencv2/core/eigen.hpp> #include <opencv2/imgcodecs.hpp> #include <Ice/Current.h> +#include <SimoxUtility/color/ColorMap.h> +#include <SimoxUtility/color/cmaps/colormaps.h> #include <SimoxUtility/math/convert/rpy_to_mat3f.h> #include <VirtualRobot/MathTools.h> #include <VirtualRobot/Robot.h> +#include "ArmarXCore/core/Component.h" #include <ArmarXCore/core/exceptions/LocalException.h> #include <ArmarXCore/core/logging/LogSender.h> #include <ArmarXCore/core/logging/Logging.h> @@ -50,8 +55,10 @@ #include "ArmarXGui/libraries/RemoteGui/Client/Widgets.h" +#include "RobotAPI/components/ArViz/Client/Client.h" #include "RobotAPI/components/ArViz/Client/Elements.h" #include "RobotAPI/components/ArViz/Client/elements/Color.h" +#include "RobotAPI/interface/ArViz/Elements.h" #include "RobotAPI/libraries/armem/core/MemoryID.h" #include "RobotAPI/libraries/armem/core/Time.h" #include "RobotAPI/libraries/armem_vision/OccupancyGridHelper.h" @@ -59,6 +66,9 @@ #include <RobotAPI/libraries/core/remoterobot/RemoteRobot.h> #include "armarx/navigation/algorithms/CostmapBuilder.h" +#include "armarx/navigation/algorithms/spfa/ShortestPathFasterAlgorithm.h" +#include "armarx/navigation/algorithms/util.h" +#include "armarx/navigation/conversions/eigen.h" #include <armarx/navigation/algorithms/Costmap.h> #include <armarx/navigation/algorithms/astar/util.h> #include <armarx/navigation/client/NavigationStackConfig.h> @@ -323,6 +333,7 @@ namespace armarx::navigation::components << "Navigator config for caller `" << callerId << "` not registered!"; updateContext(); + visualizeSPFA(); navigators.at(callerId).moveTo(wps, core::NavigationFrameNames.from_name(navigationMode)); // navigators.at(callerId).moveTo() @@ -449,6 +460,47 @@ namespace armarx::navigation::components return def; } + void + visualize(const algorithms::Costmap& costmap, viz::Client& arviz, const std::string& name) + { + const auto cmap = simox::color::cmaps::viridis(); + const float vmax = costmap.getGrid().array().maxCoeff(); + + const auto asColor = [&cmap, &vmax](const float distance) -> viz::data::Color + { + const auto color = cmap.at(distance, 0.F, vmax); + return {color.a, color.r, color.g, color.b}; + }; + + auto layer = arviz.layer("costmap_" + name); + + const std::int64_t cols = costmap.getGrid().cols(); + const std::int64_t rows = costmap.getGrid().rows(); + + auto mesh = viz::Mesh(""); + + std::vector<std::vector<Eigen::Vector3f>> vertices; + std::vector<std::vector<viz::data::Color>> colors; + + for (int r = 0; r < rows; r++) + { + auto& verticesRow = vertices.emplace_back(cols); + auto& colorsRow = colors.emplace_back(cols); + + for (int c = 0; c < cols; c++) + { + verticesRow.at(c) = conv::to3D(costmap.toPosition({r, c})); + colorsRow.at(c) = asColor(costmap.getGrid()(r, c)); + } + } + + mesh.grid2D(vertices, colors); + + layer.add(mesh); + + arviz.commit(layer); + } + core::StaticScene components::Navigator::staticScene() { @@ -477,6 +529,10 @@ namespace armarx::navigation::components ARMARX_INFO << "The object scene consists of " << scene.objects->getSize() << " objects"; + + visualize(costmap, arviz, "distance"); + + const armem::vision::occupancy_grid::client::Reader::Result result = occupancyGridReader.query(armem::vision::occupancy_grid::client::Reader::Query{ .providerName = "CartographerMappingAndLocalization", @@ -538,6 +594,24 @@ namespace armarx::navigation::components return scene; } + void components::Navigator::visualizeSPFA() + { + algorithms::spfa::ShortestPathFasterAlgorithm::Parameters spfaParams{.obstacleDistanceCosts = + true}; + + ARMARX_INFO << "spfa..."; + algorithms::spfa::ShortestPathFasterAlgorithm spfa(*scene.staticScene->costmap, spfaParams); + const auto result123 = spfa.spfa(getRobot()->getGlobalPosition().head<2>()); + ARMARX_INFO << "spfa done..."; + + const auto sceneBounds = algorithms::computeSceneBounds(scene.staticScene->objects); + + ARMARX_INFO << "Costmap SPFA"; + algorithms::Costmap cm(result123.distances, algorithms::Costmap::Parameters{}, sceneBounds); + visualize(cm, arviz, "spfa"); + ARMARX_INFO << "Done."; + } + VirtualRobot::RobotPtr components::Navigator::getRobot() { diff --git a/source/armarx/navigation/components/Navigator/Navigator.h b/source/armarx/navigation/components/Navigator/Navigator.h index 2d7411d8..45785e2e 100644 --- a/source/armarx/navigation/components/Navigator/Navigator.h +++ b/source/armarx/navigation/components/Navigator/Navigator.h @@ -161,6 +161,7 @@ namespace armarx::navigation::components server::Navigator* activeNavigator(); private: + void visualizeSPFA(); // TODO update context periodically // TODO: Remove dependency to PlatformUnit. This component is generally diff --git a/source/armarx/navigation/factories/GlobalPlannerFactory.cpp b/source/armarx/navigation/factories/GlobalPlannerFactory.cpp index 757b56e8..98a07a52 100644 --- a/source/armarx/navigation/factories/GlobalPlannerFactory.cpp +++ b/source/armarx/navigation/factories/GlobalPlannerFactory.cpp @@ -5,6 +5,7 @@ #include <RobotAPI/libraries/aron/core/data/variant/container/Dict.h> #include <RobotAPI/libraries/aron/core/data/variant/primitive/String.h> +#include "armarx/navigation/global_planning/SPFA.h" #include <armarx/navigation/core/constants.h> #include <armarx/navigation/global_planning/AStar.h> #include <armarx/navigation/global_planning/Point2Point.h> @@ -38,8 +39,12 @@ namespace armarx::navigation::fac switch (algo) { case global_planning::Algorithms::AStar: - globalPlanner = std::make_shared<global_planning::AStar>( - global_planning::AStarParams::FromAron(algoParams), ctx); + // globalPlanner = std::make_shared<global_planning::AStar>( + // global_planning::AStarParams::FromAron(algoParams), ctx); + // break; + case global_planning::Algorithms::SPFA: + globalPlanner = std::make_shared<global_planning::SPFA>( + global_planning::SPFAParams::FromAron(algoParams), ctx); break; case global_planning::Algorithms::Point2Point: globalPlanner = std::make_shared<global_planning::Point2Point>( diff --git a/source/armarx/navigation/global_planning/CMakeLists.txt b/source/armarx/navigation/global_planning/CMakeLists.txt index 7100ea90..b3b248d6 100644 --- a/source/armarx/navigation/global_planning/CMakeLists.txt +++ b/source/armarx/navigation/global_planning/CMakeLists.txt @@ -3,6 +3,7 @@ armarx_add_aron_library(global_planning_aron aron/GlobalPlannerParams.xml aron/Point2PointParams.xml aron/AStarParams.xml + aron/SPFAParams.xml ) armarx_add_library(global_planning @@ -20,12 +21,14 @@ armarx_add_library(global_planning SOURCES ./GlobalPlanner.cpp ./AStar.cpp + ./SPFA.cpp ./Point2Point.cpp ./aron_conversions.cpp ./optimization/OrientationOptimizer.cpp HEADERS ./GlobalPlanner.h ./AStar.h + ./SPFA.h ./Point2Point.h ./aron_conversions.h ./optimization/OrientationOptimizer.h diff --git a/source/armarx/navigation/global_planning/SPFA.cpp b/source/armarx/navigation/global_planning/SPFA.cpp new file mode 100644 index 00000000..65efe579 --- /dev/null +++ b/source/armarx/navigation/global_planning/SPFA.cpp @@ -0,0 +1,231 @@ +#include "SPFA.h" + +#include <algorithm> +#include <mutex> +#include <optional> + +#include <Eigen/Geometry> + +#include <VirtualRobot/Robot.h> +#include <VirtualRobot/RobotNodeSet.h> +#include <VirtualRobot/Visualization/CoinVisualization/CoinVisualizationFactory.h> + +#include <ArmarXCore/core/exceptions/LocalException.h> +#include <ArmarXCore/core/exceptions/local/ExpressionException.h> +#include <ArmarXCore/core/logging/Logging.h> + +#include <RobotAPI/libraries/aron/core/data/variant/container/Dict.h> +#include <RobotAPI/libraries/aron/core/data/variant/primitive/String.h> + +#include "armarx/navigation/algorithms/spfa/ShortestPathFasterAlgorithm.h" +#include <armarx/navigation/algorithms/smoothing/ChainApproximation.h> +#include <armarx/navigation/algorithms/smoothing/CircularPathSmoothing.h> +#include <armarx/navigation/conversions/eigen.h> +#include <armarx/navigation/core/Trajectory.h> +#include <armarx/navigation/core/constants.h> +#include <armarx/navigation/global_planning/GlobalPlanner.h> +#include <armarx/navigation/global_planning/aron/SPFAParams.aron.generated.h> +#include <armarx/navigation/global_planning/aron_conversions.h> +#include <armarx/navigation/global_planning/core.h> +#include <armarx/navigation/global_planning/optimization/OrientationOptimizer.h> + + +namespace armarx::navigation::global_planning +{ + + // SPFAParams + + Algorithms + SPFAParams::algorithm() const + { + return Algorithms::SPFA; + } + + aron::data::DictPtr + SPFAParams::toAron() const + { + arondto::SPFAParams dto; + + SPFAParams bo; + aron_conv::toAron(dto, bo); + + return dto.toAron(); + } + + SPFAParams + SPFAParams::FromAron(const aron::data::DictPtr& dict) + { + ARMARX_CHECK_NOT_NULL(dict); + + // ARMARX_DEBUG << dict->getAllKeysAsString(); + + arondto::SPFAParams dto; + dto.fromAron(dict); + + SPFAParams bo; + aron_conv::fromAron(dto, bo); + + return bo; + } + + // SPFA + + SPFA::SPFA(const SPFAParams& params, const core::Scene& ctx) : + GlobalPlanner(ctx), params(params) + { + } + + + + std::optional<GlobalPlannerResult> + SPFA::plan(const core::Pose& goal) + { + const core::Pose start(scene.robot->getGlobalPose()); + return plan(start, goal); + } + + std::optional<GlobalPlannerResult> + SPFA::plan(const core::Pose& start, const core::Pose& goal) + { + ARMARX_TRACE; + + std::lock_guard g{scene.staticSceneMtx}; + // FIXME check if costmap is available + + algorithms::spfa::ShortestPathFasterAlgorithm::Parameters spfaParams; + algorithms::spfa::ShortestPathFasterAlgorithm planner(*scene.staticScene->costmap, spfaParams); + + const Eigen::Vector2f goalPos = conv::to2D(goal.translation()); + + const auto timeStart = IceUtil::Time::now(); + + std::vector<Eigen::Vector2f> plan; + try + { + plan = planner.plan(conv::to2D(start.translation()), goalPos); + } + catch (...) + { + ARMARX_INFO << "Could not plan collision-free path from" + << "(" << start.translation().x() << "," << start.translation().y() << ")" + << " to " + << "(" << goal.translation().x() << "," << goal.translation().y() << ")" + << " due to exception " << GetHandledExceptionString(); + + return std::nullopt; + } + const auto timeEnd = IceUtil::Time::now(); + + ARMARX_IMPORTANT << "A* planning took " << (timeEnd - timeStart).toMilliSeconds() << " ms"; + ARMARX_IMPORTANT << "Path contains " << plan.size() << " points"; + + if (plan.size() < 2) // failure + { + ARMARX_INFO << "Could not plan collision-free path from" + << "(" << start.translation().x() << "," << start.translation().y() << ")" + << " to " + << "(" << goal.translation().x() << "," << goal.translation().y() << ")"; + return std::nullopt; + } + + ARMARX_DEBUG << "The plan consists of the following positions:"; + for (const auto& position : plan) + { + ARMARX_DEBUG << position; + } + + const core::Pose startPose(Eigen::Translation3f(conv::to3D(plan.front()))); + const core::Pose goalPose(Eigen::Translation3f(conv::to3D(plan.back()))); + + const auto plan3d = conv::to3D(plan); + + std::vector<core::Position> wpts; + for (size_t i = 1; i < (plan3d.size() - 1); i++) + { + wpts.push_back(plan3d.at(i)); + } + + ARMARX_TRACE; + auto smoothPlan = postProcessPath(plan); + ARMARX_IMPORTANT << "Smooth path contains " << smoothPlan.size() << " points"; + + ARMARX_TRACE; + // we need to strip the first and the last points from the plan as they encode the start and goal position + smoothPlan.erase(smoothPlan.begin()); + smoothPlan.pop_back(); + + ARMARX_TRACE; + auto trajectory = + core::Trajectory::FromPath(start, conv::to3D(smoothPlan), goal, params.linearVelocity); + + // TODO(fabian.reister): resampling of trajectory + + // FIXME param + std::optional<core::Trajectory> resampledTrajectory; + + try + { + resampledTrajectory = trajectory.resample(params.resampleDistance); + } + catch (...) + { + ARMARX_INFO << "Caught exception during resampling: " << GetHandledExceptionString(); + // return std::nullopt; + resampledTrajectory = trajectory; + } + + ARMARX_IMPORTANT << "Resampled trajectory contains " << resampledTrajectory->points().size() + << " points"; + + resampledTrajectory->setMaxVelocity(params.linearVelocity); + + + // ARMARX_CHECK(resampledTrajectory.hasMaxDistanceBetweenWaypoints(params.resampleDistance)); + + if (resampledTrajectory->points().size() == 2) + { + ARMARX_INFO << "Only start and goal provided. Not optimizing orientation"; + ARMARX_TRACE; + return GlobalPlannerResult{.trajectory = resampledTrajectory.value()}; + } + + ARMARX_TRACE; + OrientationOptimizer optimizer(resampledTrajectory.value(), OrientationOptimizer::Params{}); + const auto result = optimizer.optimize(); + + if (not result) + { + ARMARX_ERROR << "Optimizer failure"; + return std::nullopt; + } + + // TODO circular path smoothing should be done now + + algorithm::CircularPathSmoothing smoothing; + auto smoothTrajectory = smoothing.smooth(result.trajectory.value()); + smoothTrajectory.setMaxVelocity(params.linearVelocity); + + ARMARX_TRACE; + return GlobalPlannerResult{.trajectory = result.trajectory.value()}; + } + + + std::vector<Eigen::Vector2f> + SPFA::postProcessPath(const std::vector<Eigen::Vector2f>& path) + { + /// chain approximation + algorithm::ChainApproximation approx( + path, algorithm::ChainApproximation::Params{.distanceTh = 200.F}); + approx.approximate(); + const auto p = approx.approximatedChain(); + + // visualizePath(p, "approximated", simox::Color::green()); + + // algo::CircularPathSmoothing smoothing; + // const auto points = smoothing.smooth(p); + + return p; + } + + +} // namespace armarx::navigation::global_planning diff --git a/source/armarx/navigation/global_planning/SPFA.h b/source/armarx/navigation/global_planning/SPFA.h new file mode 100644 index 00000000..b3af4fc1 --- /dev/null +++ b/source/armarx/navigation/global_planning/SPFA.h @@ -0,0 +1,71 @@ +/** + * This file is part of ArmarX. + * + * ArmarX is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * ArmarX is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + * + * @author Fabian Reister ( fabian dot reister at kit dot edu ) + * @author Christian R. G. Dreher ( c dot dreher at kit dot edu ) + * @date 2021 + * @copyright http://www.gnu.org/licenses/gpl-2.0.txt + * GNU General Public License + */ + +#pragma once + +#include "GlobalPlanner.h" +#include <armarx/navigation/core/types.h> + +namespace armarx::navigation::global_planning +{ + + /** + * @brief Parameters for AStar + * + */ + struct SPFAParams : public GlobalPlannerParams + { + float linearVelocity{500}; + float resampleDistance{500}; + + Algorithms algorithm() const override; + aron::data::DictPtr toAron() const override; + + static SPFAParams FromAron(const aron::data::DictPtr& dict); + }; + + /** + * @class AStar + * @ingroup Library-GlobalPlanner + * + * Implements the A* algorithm + */ + class SPFA : public GlobalPlanner + { + public: + using Params = SPFAParams; + + SPFA(const Params& params, const core::Scene& ctx); + ~SPFA() override = default; + + std::optional<GlobalPlannerResult> plan(const core::Pose& goal) override; + std::optional<GlobalPlannerResult> plan(const core::Pose& start, + const core::Pose& goal) override; + + protected: + std::vector<Eigen::Vector2f> postProcessPath(const std::vector<Eigen::Vector2f>& path); + + private: + Params params; + }; + +} // namespace armarx::navigation::global_planning diff --git a/source/armarx/navigation/global_planning/aron/SPFAParams.xml b/source/armarx/navigation/global_planning/aron/SPFAParams.xml new file mode 100644 index 00000000..b1a34a4d --- /dev/null +++ b/source/armarx/navigation/global_planning/aron/SPFAParams.xml @@ -0,0 +1,25 @@ +<?xml version="1.0" encoding="UTF-8" ?> +<AronTypeDefinition> + <CodeIncludes> + <Include include="<armarx/navigation/global_planning/aron/GlobalPlannerParams.aron.generated.h>" /> + </CodeIncludes> + <AronIncludes> + <Include include="GlobalPlannerParams.xml" /> + </AronIncludes> + + <GenerateTypes> + + <Object name='armarx::navigation::global_planning::arondto::SPFAParams'> + <!-- <Object name='armarx::navigation::global_planning::arondto::SPFAParams' extends="armarx::navigation::global_planning::arondto::GlobalPlannerParams"> --> + <ObjectChild key='linearVelocity'> + <float /> + </ObjectChild> + <ObjectChild key='resampleDistance'> + <float /> + </ObjectChild> + + </Object> + + + </GenerateTypes> +</AronTypeDefinition> diff --git a/source/armarx/navigation/global_planning/aron_conversions.cpp b/source/armarx/navigation/global_planning/aron_conversions.cpp index 84ec219a..358efefc 100644 --- a/source/armarx/navigation/global_planning/aron_conversions.cpp +++ b/source/armarx/navigation/global_planning/aron_conversions.cpp @@ -7,9 +7,11 @@ #include <armarx/navigation/global_planning/AStar.h> #include <armarx/navigation/global_planning/GlobalPlanner.h> #include <armarx/navigation/global_planning/Point2Point.h> +#include <armarx/navigation/global_planning/SPFA.h> #include <armarx/navigation/global_planning/aron/AStarParams.aron.generated.h> #include <armarx/navigation/global_planning/aron/GlobalPlannerParams.aron.generated.h> #include <armarx/navigation/global_planning/aron/Point2PointParams.aron.generated.h> +#include <armarx/navigation/global_planning/aron/SPFAParams.aron.generated.h> namespace armarx::navigation::global_planning::aron_conv { @@ -58,4 +60,25 @@ namespace armarx::navigation::global_planning::aron_conv aron::fromAron(dto.linearVelocity, bo.linearVelocity); aron::fromAron(dto.resampleDistance, bo.resampleDistance); } + + void + toAron(arondto::SPFAParams& dto, const SPFAParams& bo) + { + // toAron(static_cast<arondto::GlobalPlannerParams&>(dto), + // static_cast<const GlobalPlannerParams&>(bo)); + + aron::toAron(dto.linearVelocity, bo.linearVelocity); + aron::toAron(dto.resampleDistance, bo.resampleDistance); + } + + void + fromAron(const arondto::SPFAParams& dto, SPFAParams& bo) + { + // fromAron(static_cast<const arondto::GlobalPlannerParams&>(dto), + // static_cast<GlobalPlannerParams&>(bo)); + + aron::fromAron(dto.linearVelocity, bo.linearVelocity); + aron::fromAron(dto.resampleDistance, bo.resampleDistance); + } + } // namespace armarx::navigation::global_planning::aron_conv diff --git a/source/armarx/navigation/global_planning/aron_conversions.h b/source/armarx/navigation/global_planning/aron_conversions.h index a27a6b02..d5b14e9d 100644 --- a/source/armarx/navigation/global_planning/aron_conversions.h +++ b/source/armarx/navigation/global_planning/aron_conversions.h @@ -5,12 +5,14 @@ namespace armarx::navigation::global_planning struct GlobalPlannerParams; struct Point2PointParams; struct AStarParams; + struct SPFAParams; namespace arondto { struct GlobalPlannerParams; struct Point2PointParams; struct AStarParams; + struct SPFAParams; } // namespace arondto @@ -27,4 +29,7 @@ namespace armarx::navigation::global_planning::aron_conv void toAron(arondto::AStarParams& dto, const AStarParams& bo); void fromAron(const arondto::AStarParams& dto, AStarParams& bo); + void toAron(arondto::SPFAParams& dto, const SPFAParams& bo); + void fromAron(const arondto::SPFAParams& dto, SPFAParams& bo); + } // namespace armarx::navigation::global_planning::aron_conv diff --git a/source/armarx/navigation/global_planning/core.h b/source/armarx/navigation/global_planning/core.h index 792e7b6f..1e21cbc2 100644 --- a/source/armarx/navigation/global_planning/core.h +++ b/source/armarx/navigation/global_planning/core.h @@ -38,6 +38,7 @@ namespace armarx::navigation::global_planning enum class Algorithms { AStar, ///< see AStar + SPFA, Point2Point ///< see Point2Point }; -- GitLab From d49c2a85d8a8e69ee2c400929c6e7080b0d75860 Mon Sep 17 00:00:00 2001 From: Fabian Reister <fabian.reister@kit.edu> Date: Tue, 11 Jan 2022 14:55:55 +0100 Subject: [PATCH 04/11] formatting files --- source/armarx/navigation/algorithms/Costmap.cpp | 1 - source/armarx/navigation/algorithms/Costmap.h | 3 ++- source/armarx/navigation/algorithms/CostmapBuilder.h | 3 ++- .../navigation/algorithms/astar/AStarPlanner.cpp | 2 +- .../armarx/navigation/algorithms/astar/AStarPlanner.h | 7 +++++-- source/armarx/navigation/algorithms/astar/Planner2D.h | 3 ++- .../algorithms/spfa/ShortestPathFasterAlgorithm.cpp | 8 +++----- .../algorithms/spfa/ShortestPathFasterAlgorithm.h | 4 +--- .../armarx/navigation/client/NavigationStackConfig.cpp | 4 ++-- .../navigation/client/services/MemorySubscriber.h | 2 +- .../components/GraphImportExport/GraphImportExport.cpp | 2 +- .../components/NavigationMemory/NavigationMemory.cpp | 2 +- .../navigation/components/NavigationMemory/Visu.cpp | 2 +- .../navigation/components/Navigator/Navigator.cpp | 9 +++++---- source/armarx/navigation/core/StaticScene.h | 1 + source/armarx/navigation/core/Trajectory.cpp | 8 ++++---- source/armarx/navigation/core/json_conversions.cpp | 8 +++++--- source/armarx/navigation/core/json_conversions.h | 2 +- source/armarx/navigation/core/test/coreTest.cpp | 4 ++-- source/armarx/navigation/core/types.h | 2 +- .../navigation/factories/GlobalPlannerFactory.cpp | 9 +++------ .../armarx/navigation/factories/GlobalPlannerFactory.h | 4 ++-- .../navigation/factories/LocalPlannerFactory.cpp | 9 +++------ .../navigation/factories/NavigationStackFactory.cpp | 6 ++---- .../navigation/factories/NavigationStackFactory.h | 3 +-- .../navigation/factories/SafetyControllerFactory.cpp | 9 +++------ .../navigation/factories/SafetyControllerFactory.h | 4 ++-- .../factories/TrajectoryControllerFactory.cpp | 9 +++------ .../navigation/factories/TrajectoryControllerFactory.h | 4 ++-- .../armarx/navigation/factories/test/factoriesTest.cpp | 4 ++-- source/armarx/navigation/global_planning/AStar.cpp | 2 +- source/armarx/navigation/global_planning/SPFA.cpp | 6 +++--- source/armarx/navigation/global_planning/core.h | 2 +- .../navigation/global_planning/optimization/math.h | 2 +- .../LocationGraphEditor/WidgetController.cpp | 2 +- .../gui-plugins/LocationGraphEditor/WidgetController.h | 2 +- .../armarx/navigation/memory/client/graph/Reader.cpp | 2 +- source/armarx/navigation/memory/client/graph/Reader.h | 2 +- .../memory/client/parameterization/Writer.cpp | 7 +++---- .../navigation/memory/client/parameterization/Writer.h | 3 +-- .../navigation/safety_control/LaserBasedProximity.h | 3 +-- .../server/introspection/ArvizIntrospector.h | 3 +-- .../server/introspection/MemoryIntrospector.h | 4 ++-- .../navigation/server/monitoring/GoalReachedMonitor.h | 2 +- .../parameterization/MemoryParameterizationService.cpp | 3 +-- source/armarx/navigation/server/test/serverTest.cpp | 10 +++++----- .../trajectory_control/TrajectoryFollowingController.h | 3 +-- source/armarx/navigation/util/util.cpp | 5 +++-- source/armarx/navigation/util/util.h | 5 +++-- 49 files changed, 96 insertions(+), 110 deletions(-) diff --git a/source/armarx/navigation/algorithms/Costmap.cpp b/source/armarx/navigation/algorithms/Costmap.cpp index 74bc8aa2..67fde2b8 100644 --- a/source/armarx/navigation/algorithms/Costmap.cpp +++ b/source/armarx/navigation/algorithms/Costmap.cpp @@ -63,5 +63,4 @@ namespace armarx::navigation::algorithms } - } // namespace armarx::navigation::algorithms diff --git a/source/armarx/navigation/algorithms/Costmap.h b/source/armarx/navigation/algorithms/Costmap.h index ffd4edee..503ca9fb 100644 --- a/source/armarx/navigation/algorithms/Costmap.h +++ b/source/armarx/navigation/algorithms/Costmap.h @@ -51,7 +51,8 @@ namespace armarx::navigation::algorithms bool isInCollision(const Position& p) const; - const Parameters& params() const noexcept + const Parameters& + params() const noexcept { return parameters; } diff --git a/source/armarx/navigation/algorithms/CostmapBuilder.h b/source/armarx/navigation/algorithms/CostmapBuilder.h index 674e1615..565ad526 100644 --- a/source/armarx/navigation/algorithms/CostmapBuilder.h +++ b/source/armarx/navigation/algorithms/CostmapBuilder.h @@ -22,6 +22,7 @@ #pragma once #include <VirtualRobot/VirtualRobot.h> + #include <armarx/navigation/algorithms/Costmap.h> namespace armarx::navigation::algorithms @@ -40,7 +41,7 @@ namespace armarx::navigation::algorithms private: Eigen::MatrixXf createUniformGrid(const SceneBounds& sceneBounds, const Costmap::Parameters& parameters); - + float computeCost(const Costmap::Position& position, VirtualRobot::RobotPtr& collisionRobot, const VirtualRobot::CollisionModelPtr& robotCollisionModel); diff --git a/source/armarx/navigation/algorithms/astar/AStarPlanner.cpp b/source/armarx/navigation/algorithms/astar/AStarPlanner.cpp index bddc5157..10d338ec 100644 --- a/source/armarx/navigation/algorithms/astar/AStarPlanner.cpp +++ b/source/armarx/navigation/algorithms/astar/AStarPlanner.cpp @@ -75,7 +75,7 @@ namespace armarx::navigation::algorithm::astar { const auto pos = costmap.toPosition({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/astar/AStarPlanner.h b/source/armarx/navigation/algorithms/astar/AStarPlanner.h index 9f6e7496..87256085 100644 --- a/source/armarx/navigation/algorithms/astar/AStarPlanner.h +++ b/source/armarx/navigation/algorithms/astar/AStarPlanner.h @@ -21,7 +21,8 @@ namespace armarx::navigation::algorithm::astar AStarPlanner(const algorithms::Costmap& costmap); - std::vector<Eigen::Vector2f> plan(const Eigen::Vector2f& start, const Eigen::Vector2f& goal) /* override */; + std::vector<Eigen::Vector2f> plan(const Eigen::Vector2f& start, + const Eigen::Vector2f& goal) /* override */; private: float heuristic(const NodePtr& n1, const NodePtr& n2); @@ -31,7 +32,9 @@ namespace armarx::navigation::algorithm::astar float costs(const NodePtr& a, const NodePtr& b) const; - float computeObstacleDistance(const Eigen::Vector2f& pos, VirtualRobot::RobotPtr& robot) const; + float computeObstacleDistance(const Eigen::Vector2f& pos, + VirtualRobot::RobotPtr& robot) const; + private: const algorithms::Costmap costmap; diff --git a/source/armarx/navigation/algorithms/astar/Planner2D.h b/source/armarx/navigation/algorithms/astar/Planner2D.h index 5fb3b7e6..cd7b0540 100644 --- a/source/armarx/navigation/algorithms/astar/Planner2D.h +++ b/source/armarx/navigation/algorithms/astar/Planner2D.h @@ -26,7 +26,8 @@ namespace armarx::navigation::algorithm::astar virtual ~Planner2D() = default; // planners implement this method - virtual std::vector<Eigen::Vector2f> plan(const Eigen::Vector2f& start, const Eigen::Vector2f& goal) = 0; + virtual std::vector<Eigen::Vector2f> plan(const Eigen::Vector2f& start, + const Eigen::Vector2f& goal) = 0; /// Update obstacles void setObstacles(VirtualRobot::SceneObjectSetPtr obstacles); diff --git a/source/armarx/navigation/algorithms/spfa/ShortestPathFasterAlgorithm.cpp b/source/armarx/navigation/algorithms/spfa/ShortestPathFasterAlgorithm.cpp index 8ba7681d..692eec77 100644 --- a/source/armarx/navigation/algorithms/spfa/ShortestPathFasterAlgorithm.cpp +++ b/source/armarx/navigation/algorithms/spfa/ShortestPathFasterAlgorithm.cpp @@ -190,11 +190,10 @@ namespace armarx::navigation::algorithms::spfa const float travelCost = dir_lengths[k]; // const float obstacleDistanceCost = std::max(obstacleDistance1 - obstacleDistance2, 0.F) / costmap.params().cellSize; - const float targetDistanceCost = 3* (1000.F - obstacleDistance2) / 1000.F; + const float targetDistanceCost = 3 * (1000.F - obstacleDistance2) / 1000.F; - const float edgeCost = params.obstacleDistanceCosts - ? travelCost + targetDistanceCost - : travelCost; + const float edgeCost = + params.obstacleDistanceCosts ? travelCost + targetDistanceCost : travelCost; int e = ravel(v, edge_counts[v], max_edges_per_vert); edges[e] = vp; @@ -277,7 +276,6 @@ namespace armarx::navigation::algorithms::spfa ARMARX_INFO << "Done."; return Result{.distances = output_dists, .parents = output_parents}; - // return py::make_tuple(output_dists, output_parents); } diff --git a/source/armarx/navigation/algorithms/spfa/ShortestPathFasterAlgorithm.h b/source/armarx/navigation/algorithms/spfa/ShortestPathFasterAlgorithm.h index 85909558..9bfa9eec 100644 --- a/source/armarx/navigation/algorithms/spfa/ShortestPathFasterAlgorithm.h +++ b/source/armarx/navigation/algorithms/spfa/ShortestPathFasterAlgorithm.h @@ -39,8 +39,7 @@ namespace armarx::navigation::algorithms::spfa bool obstacleDistanceCosts{true}; }; - ShortestPathFasterAlgorithm(const Costmap& grid, - const Parameters& params); + ShortestPathFasterAlgorithm(const Costmap& grid, const Parameters& params); struct Result { @@ -53,7 +52,6 @@ namespace armarx::navigation::algorithms::spfa const Eigen::Vector2f& goal); - Result spfa(const Eigen::Vector2f& start); // protected: diff --git a/source/armarx/navigation/client/NavigationStackConfig.cpp b/source/armarx/navigation/client/NavigationStackConfig.cpp index 6acdc7f0..bfaaf93b 100644 --- a/source/armarx/navigation/client/NavigationStackConfig.cpp +++ b/source/armarx/navigation/client/NavigationStackConfig.cpp @@ -10,7 +10,6 @@ #include <RobotAPI/libraries/aron/core/data/variant/container/Dict.h> #include <RobotAPI/libraries/aron/core/data/variant/primitive/String.h> - #include <armarx/navigation/core/constants.h> #include <armarx/navigation/core/types.h> @@ -24,7 +23,8 @@ namespace armarx::navigation::client return element; } - aron::data::dto::DictPtr NavigationStackConfig::toAron() const + aron::data::dto::DictPtr + NavigationStackConfig::toAron() const { ARMARX_CHECK(isValid()) << "The NavigationStackConfig is not valid as some elements are not set!"; diff --git a/source/armarx/navigation/client/services/MemorySubscriber.h b/source/armarx/navigation/client/services/MemorySubscriber.h index 059305dd..c7d79e14 100644 --- a/source/armarx/navigation/client/services/MemorySubscriber.h +++ b/source/armarx/navigation/client/services/MemorySubscriber.h @@ -41,7 +41,7 @@ namespace armarx::navigation::client void onEntityUpdate(const armem::MemoryID& subscriptionID, const std::vector<armem::MemoryID>& snapshotIDs); - + private: const std::string callerId; armem::client::MemoryNameSystem& memoryNameSystem; diff --git a/source/armarx/navigation/components/GraphImportExport/GraphImportExport.cpp b/source/armarx/navigation/components/GraphImportExport/GraphImportExport.cpp index e10c6e3f..bf2bb976 100644 --- a/source/armarx/navigation/components/GraphImportExport/GraphImportExport.cpp +++ b/source/armarx/navigation/components/GraphImportExport/GraphImportExport.cpp @@ -37,9 +37,9 @@ #include <MemoryX/libraries/memorytypes/MemoryXTypesObjectFactories.h> #include <armarx/navigation/core/Graph.h> #include <armarx/navigation/core/aron/Graph.aron.generated.h> +#include <armarx/navigation/core/aron/Location.aron.generated.h> #include <armarx/navigation/graph/Visu.h> #include <armarx/navigation/graph/constants.h> -#include <armarx/navigation/core/aron/Location.aron.generated.h> #include <armarx/navigation/location/constants.h> diff --git a/source/armarx/navigation/components/NavigationMemory/NavigationMemory.cpp b/source/armarx/navigation/components/NavigationMemory/NavigationMemory.cpp index 292b497c..799c5604 100644 --- a/source/armarx/navigation/components/NavigationMemory/NavigationMemory.cpp +++ b/source/armarx/navigation/components/NavigationMemory/NavigationMemory.cpp @@ -36,10 +36,10 @@ #include "Visu.h" #include <armarx/navigation/core/Graph.h> #include <armarx/navigation/core/aron/Graph.aron.generated.h> +#include <armarx/navigation/core/aron/Location.aron.generated.h> #include <armarx/navigation/core/aron/Trajectory.aron.generated.h> #include <armarx/navigation/core/aron/Twist.aron.generated.h> #include <armarx/navigation/graph/constants.h> -#include <armarx/navigation/core/aron/Location.aron.generated.h> #include <armarx/navigation/location/constants.h> diff --git a/source/armarx/navigation/components/NavigationMemory/Visu.cpp b/source/armarx/navigation/components/NavigationMemory/Visu.cpp index 328e21ce..07f364bc 100644 --- a/source/armarx/navigation/components/NavigationMemory/Visu.cpp +++ b/source/armarx/navigation/components/NavigationMemory/Visu.cpp @@ -26,8 +26,8 @@ #include <armarx/navigation/core/Graph.h> #include <armarx/navigation/core/aron/Graph.aron.generated.h> -#include <armarx/navigation/graph/Visu.h> #include <armarx/navigation/core/aron/Location.aron.generated.h> +#include <armarx/navigation/graph/Visu.h> namespace armarx::navigation::memory diff --git a/source/armarx/navigation/components/Navigator/Navigator.cpp b/source/armarx/navigation/components/Navigator/Navigator.cpp index db4c14da..13718710 100644 --- a/source/armarx/navigation/components/Navigator/Navigator.cpp +++ b/source/armarx/navigation/components/Navigator/Navigator.cpp @@ -594,11 +594,12 @@ namespace armarx::navigation::components return scene; } - void components::Navigator::visualizeSPFA() + void + components::Navigator::visualizeSPFA() { - algorithms::spfa::ShortestPathFasterAlgorithm::Parameters spfaParams{.obstacleDistanceCosts = - true}; - + algorithms::spfa::ShortestPathFasterAlgorithm::Parameters spfaParams{ + .obstacleDistanceCosts = true}; + ARMARX_INFO << "spfa..."; algorithms::spfa::ShortestPathFasterAlgorithm spfa(*scene.staticScene->costmap, spfaParams); const auto result123 = spfa.spfa(getRobot()->getGlobalPosition().head<2>()); diff --git a/source/armarx/navigation/core/StaticScene.h b/source/armarx/navigation/core/StaticScene.h index f70a2451..1f4ad33a 100644 --- a/source/armarx/navigation/core/StaticScene.h +++ b/source/armarx/navigation/core/StaticScene.h @@ -25,6 +25,7 @@ #include <memory> #include <VirtualRobot/VirtualRobot.h> + #include <armarx/navigation/algorithms/Costmap.h> namespace armarx::navigation::core diff --git a/source/armarx/navigation/core/Trajectory.cpp b/source/armarx/navigation/core/Trajectory.cpp index 9f5679a0..e7bf3ea1 100644 --- a/source/armarx/navigation/core/Trajectory.cpp +++ b/source/armarx/navigation/core/Trajectory.cpp @@ -589,11 +589,11 @@ namespace armarx::navigation::core return 0; // FIXME } - bool Trajectory::isValid() const noexcept + bool + Trajectory::isValid() const noexcept { - const auto isValid = [](const TrajectoryPoint& pt) -> bool { - return std::isfinite(pt.velocity) and pt.velocity < 3000; - }; + const auto isValid = [](const TrajectoryPoint& pt) -> bool + { return std::isfinite(pt.velocity) and pt.velocity < 3000; }; return std::all_of(pts.begin(), pts.end(), isValid); } diff --git a/source/armarx/navigation/core/json_conversions.cpp b/source/armarx/navigation/core/json_conversions.cpp index 30b8a70f..661331fb 100644 --- a/source/armarx/navigation/core/json_conversions.cpp +++ b/source/armarx/navigation/core/json_conversions.cpp @@ -21,21 +21,23 @@ #include "json_conversions.h" -#include <RobotAPI/libraries/aron/core/data/rw/writer/nlohmannJSON/NlohmannJSONWriter.h> #include <RobotAPI/libraries/aron/core/data/rw/reader/nlohmannJSON/NlohmannJSONReader.h> +#include <RobotAPI/libraries/aron/core/data/rw/writer/nlohmannJSON/NlohmannJSONWriter.h> namespace armarx::navigation::core { - void arondto::to_json(nlohmann::json& j, const Edge& bo) + void + arondto::to_json(nlohmann::json& j, const Edge& bo) { armarx::aron::data::writer::NlohmannJSONWriter writer; j = bo.write(writer); } - void arondto::from_json(const nlohmann::json& j, Edge& bo) + void + arondto::from_json(const nlohmann::json& j, Edge& bo) { armarx::aron::data::reader::NlohmannJSONReader reader; bo.read<armarx::aron::data::reader::NlohmannJSONReader::InputType>(reader, j); diff --git a/source/armarx/navigation/core/json_conversions.h b/source/armarx/navigation/core/json_conversions.h index 57cee75d..a8fd2caa 100644 --- a/source/armarx/navigation/core/json_conversions.h +++ b/source/armarx/navigation/core/json_conversions.h @@ -33,4 +33,4 @@ namespace armarx::navigation::core::arondto void from_json(const nlohmann::json& j, arondto::Edge& bo); -} // namespace armarx::navigation::graph +} // namespace armarx::navigation::core::arondto diff --git a/source/armarx/navigation/core/test/coreTest.cpp b/source/armarx/navigation/core/test/coreTest.cpp index 8e323a97..c62597ce 100644 --- a/source/armarx/navigation/core/test/coreTest.cpp +++ b/source/armarx/navigation/core/test/coreTest.cpp @@ -24,11 +24,11 @@ #include <algorithm> #include <vector> +#include <range/v3/view/zip.hpp> + #include <ArmarXCore/core/exceptions/local/ExpressionException.h> #include <ArmarXCore/core/logging/Logging.h> -#include <range/v3/view/zip.hpp> - #include <SemanticObjectRelations/Shapes/Shape.h> #include <armarx/navigation/core/Graph.h> #include <armarx/navigation/core/Trajectory.h> diff --git a/source/armarx/navigation/core/types.h b/source/armarx/navigation/core/types.h index 464966df..0e5b96fa 100644 --- a/source/armarx/navigation/core/types.h +++ b/source/armarx/navigation/core/types.h @@ -80,7 +80,7 @@ namespace armarx::navigation::core { mutable std::mutex staticSceneMtx; std::optional<core::StaticScene> staticScene = std::nullopt; - + mutable std::mutex dynamicSceneMtx; std::optional<core::DynamicScene> dynamicScene = std::nullopt; // TopologicMapPtr topologicMap; diff --git a/source/armarx/navigation/factories/GlobalPlannerFactory.cpp b/source/armarx/navigation/factories/GlobalPlannerFactory.cpp index 98a07a52..f6e20580 100644 --- a/source/armarx/navigation/factories/GlobalPlannerFactory.cpp +++ b/source/armarx/navigation/factories/GlobalPlannerFactory.cpp @@ -14,8 +14,7 @@ namespace armarx::navigation::fac { global_planning::GlobalPlannerPtr - GlobalPlannerFactory::create(const aron::data::DictPtr& params, - const core::Scene& ctx) + GlobalPlannerFactory::create(const aron::data::DictPtr& params, const core::Scene& ctx) { namespace layer = global_planning; @@ -25,14 +24,12 @@ namespace armarx::navigation::fac } // algo name - const auto algoName = - aron::data::String::DynamicCast(params->getElement(core::NAME_KEY)); + const auto algoName = aron::data::String::DynamicCast(params->getElement(core::NAME_KEY)); ARMARX_CHECK_NOT_NULL(algoName); const layer::Algorithms algo = layer::AlgorithmNames.from_name(algoName->getValue()); // algo params - const auto algoParams = - aron::data::Dict::DynamicCast(params->getElement(core::PARAMS_KEY)); + const auto algoParams = aron::data::Dict::DynamicCast(params->getElement(core::PARAMS_KEY)); ARMARX_CHECK_NOT_NULL(algoParams); global_planning::GlobalPlannerPtr globalPlanner; diff --git a/source/armarx/navigation/factories/GlobalPlannerFactory.h b/source/armarx/navigation/factories/GlobalPlannerFactory.h index 4ef9a823..da60c839 100644 --- a/source/armarx/navigation/factories/GlobalPlannerFactory.h +++ b/source/armarx/navigation/factories/GlobalPlannerFactory.h @@ -36,8 +36,8 @@ namespace armarx::navigation::fac class GlobalPlannerFactory { public: - static global_planning::GlobalPlannerPtr - create(const aron::data::DictPtr& params, const core::Scene& ctx); + static global_planning::GlobalPlannerPtr create(const aron::data::DictPtr& params, + const core::Scene& ctx); }; } // namespace armarx::navigation::fac diff --git a/source/armarx/navigation/factories/LocalPlannerFactory.cpp b/source/armarx/navigation/factories/LocalPlannerFactory.cpp index e386f55d..aed7f192 100644 --- a/source/armarx/navigation/factories/LocalPlannerFactory.cpp +++ b/source/armarx/navigation/factories/LocalPlannerFactory.cpp @@ -11,8 +11,7 @@ namespace armarx::navigation::fac { loc_plan::LocalPlannerPtr - LocalPlannerFactory::create(const aron::data::DictPtr& params, - const core::Scene& ctx) + LocalPlannerFactory::create(const aron::data::DictPtr& params, const core::Scene& ctx) { namespace layer = loc_plan; @@ -22,14 +21,12 @@ namespace armarx::navigation::fac } // algo name - const auto algoName = - aron::data::String::DynamicCast(params->getElement(core::NAME_KEY)); + const auto algoName = aron::data::String::DynamicCast(params->getElement(core::NAME_KEY)); ARMARX_CHECK_NOT_NULL(algoName); const layer::Algorithms algo = layer::AlgorithmNames.from_name(algoName->getValue()); // algo params - const auto algoParams = - aron::data::Dict::DynamicCast(params->getElement(core::PARAMS_KEY)); + const auto algoParams = aron::data::Dict::DynamicCast(params->getElement(core::PARAMS_KEY)); ARMARX_CHECK_NOT_NULL(algoParams); loc_plan::LocalPlannerPtr localPlanner; diff --git a/source/armarx/navigation/factories/NavigationStackFactory.cpp b/source/armarx/navigation/factories/NavigationStackFactory.cpp index e6c90a5c..665bfecb 100644 --- a/source/armarx/navigation/factories/NavigationStackFactory.cpp +++ b/source/armarx/navigation/factories/NavigationStackFactory.cpp @@ -14,13 +14,11 @@ namespace armarx::navigation::fac { server::NavigationStack - NavigationStackFactory::create(const aron::data::DictPtr& params, - const core::Scene& ctx) + NavigationStackFactory::create(const aron::data::DictPtr& params, const core::Scene& ctx) { using aron::data::Dict; - const auto getElementOrNull = - [¶ms](const core::StackLayer& layer) -> Dict::PointerType + const auto getElementOrNull = [¶ms](const core::StackLayer& layer) -> Dict::PointerType { const std::string key = core::StackLayerNames.to_name(layer); diff --git a/source/armarx/navigation/factories/NavigationStackFactory.h b/source/armarx/navigation/factories/NavigationStackFactory.h index f0ee4e19..abd6be41 100644 --- a/source/armarx/navigation/factories/NavigationStackFactory.h +++ b/source/armarx/navigation/factories/NavigationStackFactory.h @@ -22,11 +22,10 @@ #pragma once -#include <armarx/navigation/server/NavigationStack.h> - #include <RobotAPI/libraries/aron/core/data/variant/forward_declarations.h> #include <armarx/navigation/core/fwd.h> +#include <armarx/navigation/server/NavigationStack.h> namespace armarx::navigation::fac { diff --git a/source/armarx/navigation/factories/SafetyControllerFactory.cpp b/source/armarx/navigation/factories/SafetyControllerFactory.cpp index 8dec9fb3..a4173c42 100644 --- a/source/armarx/navigation/factories/SafetyControllerFactory.cpp +++ b/source/armarx/navigation/factories/SafetyControllerFactory.cpp @@ -13,8 +13,7 @@ namespace armarx::navigation::fac { safe_ctrl::SafetyControllerPtr - SafetyControllerFactory::create(const aron::data::DictPtr& params, - const core::Scene& ctx) + SafetyControllerFactory::create(const aron::data::DictPtr& params, const core::Scene& ctx) { namespace layer = safe_ctrl; @@ -24,14 +23,12 @@ namespace armarx::navigation::fac } // algo name - const auto algoName = - aron::data::String::DynamicCast(params->getElement(core::NAME_KEY)); + const auto algoName = aron::data::String::DynamicCast(params->getElement(core::NAME_KEY)); ARMARX_CHECK_NOT_NULL(algoName); const layer::Algorithms algo = layer::AlgorithmNames.from_name(algoName->getValue()); // algo params - const auto algoParams = - aron::data::Dict::DynamicCast(params->getElement(core::PARAMS_KEY)); + const auto algoParams = aron::data::Dict::DynamicCast(params->getElement(core::PARAMS_KEY)); ARMARX_CHECK_NOT_NULL(algoParams); safe_ctrl::SafetyControllerPtr controller; diff --git a/source/armarx/navigation/factories/SafetyControllerFactory.h b/source/armarx/navigation/factories/SafetyControllerFactory.h index 023a7624..02c427c9 100644 --- a/source/armarx/navigation/factories/SafetyControllerFactory.h +++ b/source/armarx/navigation/factories/SafetyControllerFactory.h @@ -37,8 +37,8 @@ namespace armarx::navigation::fac class SafetyControllerFactory { public: - static safe_ctrl::SafetyControllerPtr - create(const aron::data::DictPtr& params, const core::Scene& ctx); + static safe_ctrl::SafetyControllerPtr create(const aron::data::DictPtr& params, + const core::Scene& ctx); protected: private: diff --git a/source/armarx/navigation/factories/TrajectoryControllerFactory.cpp b/source/armarx/navigation/factories/TrajectoryControllerFactory.cpp index c30fe546..277d277d 100644 --- a/source/armarx/navigation/factories/TrajectoryControllerFactory.cpp +++ b/source/armarx/navigation/factories/TrajectoryControllerFactory.cpp @@ -12,8 +12,7 @@ namespace armarx::navigation::fac { traj_ctrl::TrajectoryControllerPtr - TrajectoryControllerFactory::create(const aron::data::DictPtr& params, - const core::Scene& ctx) + TrajectoryControllerFactory::create(const aron::data::DictPtr& params, const core::Scene& ctx) { namespace layer = traj_ctrl; @@ -23,14 +22,12 @@ namespace armarx::navigation::fac } // algo name - const auto algoName = - aron::data::String::DynamicCast(params->getElement(core::NAME_KEY)); + const auto algoName = aron::data::String::DynamicCast(params->getElement(core::NAME_KEY)); ARMARX_CHECK_NOT_NULL(algoName); const layer::Algorithms algo = layer::AlgorithmNames.from_name(algoName->getValue()); // algo params - const auto algoParams = - aron::data::Dict::DynamicCast(params->getElement(core::PARAMS_KEY)); + const auto algoParams = aron::data::Dict::DynamicCast(params->getElement(core::PARAMS_KEY)); ARMARX_CHECK_NOT_NULL(algoParams); traj_ctrl::TrajectoryControllerPtr controller; diff --git a/source/armarx/navigation/factories/TrajectoryControllerFactory.h b/source/armarx/navigation/factories/TrajectoryControllerFactory.h index eb603d5f..16328e1c 100644 --- a/source/armarx/navigation/factories/TrajectoryControllerFactory.h +++ b/source/armarx/navigation/factories/TrajectoryControllerFactory.h @@ -38,8 +38,8 @@ namespace armarx::navigation::fac class TrajectoryControllerFactory { public: - static traj_ctrl::TrajectoryControllerPtr - create(const aron::data::DictPtr& params, const core::Scene& ctx); + static traj_ctrl::TrajectoryControllerPtr create(const aron::data::DictPtr& params, + const core::Scene& ctx); protected: private: diff --git a/source/armarx/navigation/factories/test/factoriesTest.cpp b/source/armarx/navigation/factories/test/factoriesTest.cpp index adb15278..2e7d7fdb 100644 --- a/source/armarx/navigation/factories/test/factoriesTest.cpp +++ b/source/armarx/navigation/factories/test/factoriesTest.cpp @@ -66,8 +66,8 @@ BOOST_AUTO_TEST_CASE(testStackCreation) BOOST_CHECK(navStack.globalPlanner.get() != nullptr); BOOST_CHECK(navStack.trajectoryControl.get() != nullptr); - BOOST_CHECK(dynamic_cast<armarx::navigation::global_planning::AStar*>(navStack.globalPlanner.get()) != - nullptr); + BOOST_CHECK(dynamic_cast<armarx::navigation::global_planning::AStar*>( + navStack.globalPlanner.get()) != nullptr); BOOST_CHECK(dynamic_cast<armarx::navigation::traj_ctrl::TrajectoryFollowingController*>( navStack.trajectoryControl.get()) != nullptr); } diff --git a/source/armarx/navigation/global_planning/AStar.cpp b/source/armarx/navigation/global_planning/AStar.cpp index 16ca1777..dde26d2f 100644 --- a/source/armarx/navigation/global_planning/AStar.cpp +++ b/source/armarx/navigation/global_planning/AStar.cpp @@ -161,7 +161,7 @@ namespace armarx::navigation::global_planning std::lock_guard g{scene.staticSceneMtx}; // FIXME check if costmap is available algorithm::astar::AStarPlanner planner(*scene.staticScene->costmap); - + const Eigen::Vector2f goalPos = conv::to2D(goal.translation()); const auto timeStart = IceUtil::Time::now(); diff --git a/source/armarx/navigation/global_planning/SPFA.cpp b/source/armarx/navigation/global_planning/SPFA.cpp index 65efe579..26363016 100644 --- a/source/armarx/navigation/global_planning/SPFA.cpp +++ b/source/armarx/navigation/global_planning/SPFA.cpp @@ -75,7 +75,6 @@ namespace armarx::navigation::global_planning { } - std::optional<GlobalPlannerResult> SPFA::plan(const core::Pose& goal) @@ -93,8 +92,9 @@ namespace armarx::navigation::global_planning // FIXME check if costmap is available algorithms::spfa::ShortestPathFasterAlgorithm::Parameters spfaParams; - algorithms::spfa::ShortestPathFasterAlgorithm planner(*scene.staticScene->costmap, spfaParams); - + algorithms::spfa::ShortestPathFasterAlgorithm planner(*scene.staticScene->costmap, + spfaParams); + const Eigen::Vector2f goalPos = conv::to2D(goal.translation()); const auto timeStart = IceUtil::Time::now(); diff --git a/source/armarx/navigation/global_planning/core.h b/source/armarx/navigation/global_planning/core.h index 1e21cbc2..f8b6eaf7 100644 --- a/source/armarx/navigation/global_planning/core.h +++ b/source/armarx/navigation/global_planning/core.h @@ -37,7 +37,7 @@ namespace armarx::navigation::global_planning */ enum class Algorithms { - AStar, ///< see AStar + AStar, ///< see AStar SPFA, Point2Point ///< see Point2Point }; diff --git a/source/armarx/navigation/global_planning/optimization/math.h b/source/armarx/navigation/global_planning/optimization/math.h index 2007edb3..c8854e1f 100644 --- a/source/armarx/navigation/global_planning/optimization/math.h +++ b/source/armarx/navigation/global_planning/optimization/math.h @@ -61,7 +61,7 @@ namespace armarx::navigation::global_planning::optimization 1 - ceres::pow(ceres::sin(a) * ceres::sin(b) + ceres::cos(a) * ceres::cos(b), 2); // prevent division by 0 - if(denomSquared < 0.001) + if (denomSquared < 0.001) { return 0.; } diff --git a/source/armarx/navigation/gui-plugins/LocationGraphEditor/WidgetController.cpp b/source/armarx/navigation/gui-plugins/LocationGraphEditor/WidgetController.cpp index b4487009..894b527d 100644 --- a/source/armarx/navigation/gui-plugins/LocationGraphEditor/WidgetController.cpp +++ b/source/armarx/navigation/gui-plugins/LocationGraphEditor/WidgetController.cpp @@ -41,9 +41,9 @@ #include "widgets/graph_scene/Widget.h" #include "widgets/utils.h" #include <armarx/navigation/core/aron/Graph.aron.generated.h> +#include <armarx/navigation/core/aron/Location.aron.generated.h> #include <armarx/navigation/graph/constants.h> #include <armarx/navigation/gui-plugins/LocationGraphEditor/ui_LocationGraphEditorWidget.h> -#include <armarx/navigation/core/aron/Location.aron.generated.h> #include <armarx/navigation/location/constants.h> // Qt headers diff --git a/source/armarx/navigation/gui-plugins/LocationGraphEditor/WidgetController.h b/source/armarx/navigation/gui-plugins/LocationGraphEditor/WidgetController.h index f06f0bde..080b9617 100644 --- a/source/armarx/navigation/gui-plugins/LocationGraphEditor/WidgetController.h +++ b/source/armarx/navigation/gui-plugins/LocationGraphEditor/WidgetController.h @@ -40,8 +40,8 @@ #include "Visu.h" #include "widgets/graph_scene.h" #include <armarx/navigation/core/Graph.h> -#include <armarx/navigation/gui-plugins/LocationGraphEditor/ui_LocationGraphEditorWidget.h> #include <armarx/navigation/core/aron/Location.aron.generated.h> +#include <armarx/navigation/gui-plugins/LocationGraphEditor/ui_LocationGraphEditorWidget.h> class QDialog; diff --git a/source/armarx/navigation/memory/client/graph/Reader.cpp b/source/armarx/navigation/memory/client/graph/Reader.cpp index 7d3513a1..98049272 100644 --- a/source/armarx/navigation/memory/client/graph/Reader.cpp +++ b/source/armarx/navigation/memory/client/graph/Reader.cpp @@ -14,8 +14,8 @@ #include <armarx/navigation/core/Graph.h> #include <armarx/navigation/core/aron/Graph.aron.generated.h> -#include <armarx/navigation/graph/constants.h> #include <armarx/navigation/core/aron/Location.aron.generated.h> +#include <armarx/navigation/graph/constants.h> #include <armarx/navigation/location/constants.h> namespace armarx::navigation::mem::client::graph diff --git a/source/armarx/navigation/memory/client/graph/Reader.h b/source/armarx/navigation/memory/client/graph/Reader.h index 9a65ed9f..a61bc7c6 100644 --- a/source/armarx/navigation/memory/client/graph/Reader.h +++ b/source/armarx/navigation/memory/client/graph/Reader.h @@ -24,8 +24,8 @@ #include <RobotAPI/libraries/armem/client/util/SimpleReaderBase.h> #include <armarx/navigation/core/Graph.h> -#include <armarx/navigation/core/types.h> #include <armarx/navigation/core/aron/Location.aron.generated.h> +#include <armarx/navigation/core/types.h> namespace armarx::navigation::mem::client::graph { diff --git a/source/armarx/navigation/memory/client/parameterization/Writer.cpp b/source/armarx/navigation/memory/client/parameterization/Writer.cpp index d40f300f..b1b8610d 100644 --- a/source/armarx/navigation/memory/client/parameterization/Writer.cpp +++ b/source/armarx/navigation/memory/client/parameterization/Writer.cpp @@ -8,10 +8,9 @@ namespace armarx::navigation::mem::client::param { bool - Writer::store( - const std::unordered_map<core::StackLayer, aron::data::DictPtr>& stack, - const std::string& clientID, - const core::TimestampUs& timestamp) + Writer::store(const std::unordered_map<core::StackLayer, aron::data::DictPtr>& stack, + const std::string& clientID, + const core::TimestampUs& timestamp) { ARMARX_CHECK(not stack.empty()); diff --git a/source/armarx/navigation/memory/client/parameterization/Writer.h b/source/armarx/navigation/memory/client/parameterization/Writer.h index d48c3e80..eda0e83e 100644 --- a/source/armarx/navigation/memory/client/parameterization/Writer.h +++ b/source/armarx/navigation/memory/client/parameterization/Writer.h @@ -36,8 +36,7 @@ namespace armarx::navigation::mem::client::param using armem::client::util::SimpleWriterBase::SimpleWriterBase; - bool store(const std::unordered_map<core::StackLayer, - aron::data::DictPtr>& stack, + bool store(const std::unordered_map<core::StackLayer, aron::data::DictPtr>& stack, const std::string& clientID, const core::TimestampUs& timestamp); diff --git a/source/armarx/navigation/safety_control/LaserBasedProximity.h b/source/armarx/navigation/safety_control/LaserBasedProximity.h index 94108ade..1f1cf519 100644 --- a/source/armarx/navigation/safety_control/LaserBasedProximity.h +++ b/source/armarx/navigation/safety_control/LaserBasedProximity.h @@ -33,8 +33,7 @@ namespace armarx::navigation::safe_ctrl Algorithms algorithm() const override; aron::data::DictPtr toAron() const override; - static LaserBasedProximityParams - FromAron(const aron::data::DictPtr& dict); + static LaserBasedProximityParams FromAron(const aron::data::DictPtr& dict); }; class LaserBasedProximity : virtual public SafetyController diff --git a/source/armarx/navigation/server/introspection/ArvizIntrospector.h b/source/armarx/navigation/server/introspection/ArvizIntrospector.h index 1cd9cf12..39d45649 100644 --- a/source/armarx/navigation/server/introspection/ArvizIntrospector.h +++ b/source/armarx/navigation/server/introspection/ArvizIntrospector.h @@ -59,7 +59,7 @@ namespace armarx::navigation::server void onSafetyControllerResult(const safe_ctrl::SafetyControllerResult& result) override; void onGoal(const core::Pose& goal) override; - + void success(); void failure(); @@ -68,7 +68,6 @@ namespace armarx::navigation::server void onGlobalGraph(const core::Graph& graph) override; - // // Non-API ArvizIntrospector(ArvizIntrospector&& other) noexcept; ArvizIntrospector& operator=(ArvizIntrospector&&) noexcept; diff --git a/source/armarx/navigation/server/introspection/MemoryIntrospector.h b/source/armarx/navigation/server/introspection/MemoryIntrospector.h index c153b521..18ecf769 100644 --- a/source/armarx/navigation/server/introspection/MemoryIntrospector.h +++ b/source/armarx/navigation/server/introspection/MemoryIntrospector.h @@ -46,8 +46,8 @@ namespace armarx::navigation::server void onGoal(const core::Pose& goal) override; - void success() override {}; - void failure() override {}; + void success() override{}; + void failure() override{}; void onGlobalShortestPath(const std::vector<core::Pose>& path) override diff --git a/source/armarx/navigation/server/monitoring/GoalReachedMonitor.h b/source/armarx/navigation/server/monitoring/GoalReachedMonitor.h index 9382cbae..34f9e49d 100644 --- a/source/armarx/navigation/server/monitoring/GoalReachedMonitor.h +++ b/source/armarx/navigation/server/monitoring/GoalReachedMonitor.h @@ -33,7 +33,7 @@ namespace armarx::navigation::server struct GoalReachedMonitorConfig { - float posTh{70.F}; // [mm] + float posTh{70.F}; // [mm] float oriTh{VirtualRobot::MathTools::deg2rad(5.F)}; // [rad] float linearVelTh{100.F}; // [mm/s] diff --git a/source/armarx/navigation/server/parameterization/MemoryParameterizationService.cpp b/source/armarx/navigation/server/parameterization/MemoryParameterizationService.cpp index 94bbd51b..68067ad9 100644 --- a/source/armarx/navigation/server/parameterization/MemoryParameterizationService.cpp +++ b/source/armarx/navigation/server/parameterization/MemoryParameterizationService.cpp @@ -19,8 +19,7 @@ namespace armarx::navigation::server using aron::data::Dict; - const auto getElementOrNull = - [¶ms](const core::StackLayer& layer) -> Dict::PointerType + const auto getElementOrNull = [¶ms](const core::StackLayer& layer) -> Dict::PointerType { const std::string key = core::StackLayerNames.to_name(layer); diff --git a/source/armarx/navigation/server/test/serverTest.cpp b/source/armarx/navigation/server/test/serverTest.cpp index 7bcfcc6d..5fb6ce92 100644 --- a/source/armarx/navigation/server/test/serverTest.cpp +++ b/source/armarx/navigation/server/test/serverTest.cpp @@ -55,11 +55,11 @@ BOOST_AUTO_TEST_CASE(testNavigator) scene.robot->setGlobalPose(Eigen::Matrix4f::Identity(), false); // TODO create static shared ctor - server::NavigationStack stack{ - .globalPlanner = - std::make_shared<global_planning::Point2Point>(global_planning::Point2PointParams(), scene), - .trajectoryControl = std::make_shared<traj_ctrl::TrajectoryFollowingController>( - traj_ctrl::TrajectoryFollowingControllerParams(), scene)}; + server::NavigationStack stack{.globalPlanner = std::make_shared<global_planning::Point2Point>( + global_planning::Point2PointParams(), scene), + .trajectoryControl = + std::make_shared<traj_ctrl::TrajectoryFollowingController>( + traj_ctrl::TrajectoryFollowingControllerParams(), scene)}; // Executor. server::DummyExecutor executor{scene.robot, server::DummyExecutor::Params()}; diff --git a/source/armarx/navigation/trajectory_control/TrajectoryFollowingController.h b/source/armarx/navigation/trajectory_control/TrajectoryFollowingController.h index 064de2fc..a9a8a94c 100644 --- a/source/armarx/navigation/trajectory_control/TrajectoryFollowingController.h +++ b/source/armarx/navigation/trajectory_control/TrajectoryFollowingController.h @@ -40,8 +40,7 @@ namespace armarx::navigation::traj_ctrl Algorithms algorithm() const override; aron::data::DictPtr toAron() const override; - static TrajectoryFollowingControllerParams - FromAron(const aron::data::DictPtr& dict); + static TrajectoryFollowingControllerParams FromAron(const aron::data::DictPtr& dict); }; class TrajectoryFollowingController : virtual public TrajectoryController diff --git a/source/armarx/navigation/util/util.cpp b/source/armarx/navigation/util/util.cpp index ba409ab3..3438ce67 100644 --- a/source/armarx/navigation/util/util.cpp +++ b/source/armarx/navigation/util/util.cpp @@ -37,9 +37,9 @@ #include <ArmarXCore/core/exceptions/local/ExpressionException.h> -#include <RobotAPI/libraries/core/FramedPose.h> #include <RobotAPI/libraries/ArmarXObjects/ObjectFinder.h> #include <RobotAPI/libraries/armem_vision/OccupancyGridHelper.h> +#include <RobotAPI/libraries/core/FramedPose.h> namespace armarx::navigation::util { @@ -63,7 +63,8 @@ namespace armarx::navigation::util } VirtualRobot::SceneObjectSetPtr - asSceneObjects(const armem::OccupancyGrid& occupancyGrid, const OccupancyGridHelper::Params& params) + asSceneObjects(const armem::OccupancyGrid& occupancyGrid, + const OccupancyGridHelper::Params& params) { const OccupancyGridHelper ocHelper(occupancyGrid, params); const auto obstacles = ocHelper.obstacles(); diff --git a/source/armarx/navigation/util/util.h b/source/armarx/navigation/util/util.h index c15487f1..805b7f7c 100644 --- a/source/armarx/navigation/util/util.h +++ b/source/armarx/navigation/util/util.h @@ -25,13 +25,14 @@ #include <VirtualRobot/VirtualRobot.h> #include <RobotAPI/libraries/ArmarXObjects/ObjectPose.h> -#include <RobotAPI/libraries/armem_vision/types.h> #include <RobotAPI/libraries/armem_vision/OccupancyGridHelper.h> +#include <RobotAPI/libraries/armem_vision/types.h> namespace armarx::navigation::util { VirtualRobot::SceneObjectSetPtr asSceneObjects(const objpose::ObjectPoseSeq& objectPoses); - VirtualRobot::SceneObjectSetPtr asSceneObjects(const armem::OccupancyGrid& occupancyGrid, const OccupancyGridHelper::Params& params); + VirtualRobot::SceneObjectSetPtr asSceneObjects(const armem::OccupancyGrid& occupancyGrid, + const OccupancyGridHelper::Params& params); } // namespace armarx::navigation::util -- GitLab From 9d4053129e8e0c9f5fbe39b8aa9fbafb18c26bf5 Mon Sep 17 00:00:00 2001 From: Fabian Reister <fabian.reister@kit.edu> Date: Tue, 11 Jan 2022 18:56:42 +0100 Subject: [PATCH 05/11] util stuff --- source/armarx/navigation/algorithms/Costmap.h | 6 +++++ .../navigation/algorithms/CostmapBuilder.cpp | 2 ++ .../navigation/algorithms/CostmapBuilder.h | 2 +- .../spfa/ShortestPathFasterAlgorithm.h | 2 +- source/armarx/navigation/algorithms/util.cpp | 23 +++++++++++++++++++ source/armarx/navigation/algorithms/util.h | 10 +++++++- 6 files changed, 42 insertions(+), 3 deletions(-) diff --git a/source/armarx/navigation/algorithms/Costmap.h b/source/armarx/navigation/algorithms/Costmap.h index 503ca9fb..730a7175 100644 --- a/source/armarx/navigation/algorithms/Costmap.h +++ b/source/armarx/navigation/algorithms/Costmap.h @@ -57,6 +57,12 @@ namespace armarx::navigation::algorithms return parameters; } + const SceneBounds& + getSceneBounds() const noexcept + { + return sceneBounds; + } + private: Grid grid; diff --git a/source/armarx/navigation/algorithms/CostmapBuilder.cpp b/source/armarx/navigation/algorithms/CostmapBuilder.cpp index 2e9b9b1f..9c40a93d 100644 --- a/source/armarx/navigation/algorithms/CostmapBuilder.cpp +++ b/source/armarx/navigation/algorithms/CostmapBuilder.cpp @@ -195,6 +195,8 @@ namespace armarx::navigation::algorithms ARMARX_CHECK_NOT_NULL(collisionRobotNode); robotCollisionModel = collisionRobotNode->getCollisionModel(); + ARMARX_CHECK(robotCollisionModel) << "Collision model not available. " + "Make sure that you load the robot correctly!"; } ARMARX_CHECK_NOT_NULL(collisionRobot); diff --git a/source/armarx/navigation/algorithms/CostmapBuilder.h b/source/armarx/navigation/algorithms/CostmapBuilder.h index 565ad526..ff6ef9d2 100644 --- a/source/armarx/navigation/algorithms/CostmapBuilder.h +++ b/source/armarx/navigation/algorithms/CostmapBuilder.h @@ -36,7 +36,7 @@ namespace armarx::navigation::algorithms const Costmap::Parameters& parameters, const std::string& robotCollisonModelName); - Costmap create(); + [[nodiscard]] Costmap create(); private: Eigen::MatrixXf createUniformGrid(const SceneBounds& sceneBounds, diff --git a/source/armarx/navigation/algorithms/spfa/ShortestPathFasterAlgorithm.h b/source/armarx/navigation/algorithms/spfa/ShortestPathFasterAlgorithm.h index 9bfa9eec..65a458c3 100644 --- a/source/armarx/navigation/algorithms/spfa/ShortestPathFasterAlgorithm.h +++ b/source/armarx/navigation/algorithms/spfa/ShortestPathFasterAlgorithm.h @@ -39,7 +39,7 @@ namespace armarx::navigation::algorithms::spfa bool obstacleDistanceCosts{true}; }; - ShortestPathFasterAlgorithm(const Costmap& grid, const Parameters& params); + ShortestPathFasterAlgorithm(const Costmap& costmap, const Parameters& params); struct Result { diff --git a/source/armarx/navigation/algorithms/util.cpp b/source/armarx/navigation/algorithms/util.cpp index 53a3aafa..843d40eb 100644 --- a/source/armarx/navigation/algorithms/util.cpp +++ b/source/armarx/navigation/algorithms/util.cpp @@ -24,6 +24,7 @@ #include <VirtualRobot/BoundingBox.h> #include <VirtualRobot/CollisionDetection/CollisionModel.h> #include <VirtualRobot/SceneObjectSet.h> +#include <VirtualRobot/Workspace/WorkspaceGrid.h> #include "ArmarXCore/core/exceptions/local/ExpressionException.h" @@ -52,4 +53,26 @@ namespace armarx::navigation::algorithms } + armarx::navigation::algorithms::SceneBounds + toSceneBounds(const VirtualRobot::WorkspaceGrid::Extends& extends) + { + return {.min = Eigen::Vector2f{extends.minX, extends.minY}, + .max = Eigen::Vector2f{extends.maxX, extends.maxY}}; + } + + armarx::navigation::algorithms::Costmap + toCostmap(const VirtualRobot::WorkspaceGrid& workspaceGrid) + { + const armarx::navigation::algorithms::Costmap::Grid grid(workspaceGrid.getCells().x, + workspaceGrid.getCells().y); + const armarx::navigation::algorithms::SceneBounds sceneBounds = + toSceneBounds(workspaceGrid.getExtends()); + + const armarx::navigation::algorithms::Costmap::Parameters parameters{ + .binaryGrid = false, .cellSize = workspaceGrid.getDiscretizeSize()}; + + return {grid, parameters, sceneBounds}; + } + + } // namespace armarx::navigation::algorithms diff --git a/source/armarx/navigation/algorithms/util.h b/source/armarx/navigation/algorithms/util.h index add037fc..cee91e0c 100644 --- a/source/armarx/navigation/algorithms/util.h +++ b/source/armarx/navigation/algorithms/util.h @@ -23,12 +23,20 @@ #pragma once #include <VirtualRobot/VirtualRobot.h> +#include <VirtualRobot/Workspace/WorkspaceGrid.h> +#include <armarx/navigation/algorithms/Costmap.h> #include <armarx/navigation/algorithms/types.h> + namespace armarx::navigation::algorithms { - SceneBounds computeSceneBounds(const VirtualRobot::SceneObjectSetPtr& obstacles); + armarx::navigation::algorithms::SceneBounds + toSceneBounds(const VirtualRobot::WorkspaceGrid::Extends& extends); + + armarx::navigation::algorithms::Costmap + toCostmap(const VirtualRobot::WorkspaceGrid& workspaceGrid); + } // namespace armarx::navigation::algorithms -- GitLab From eefd681bdf9adc57e19752a84f993a3b064241ee Mon Sep 17 00:00:00 2001 From: Fabian Reister <fabian.reister@kit.edu> Date: Tue, 11 Jan 2022 21:41:35 +0100 Subject: [PATCH 06/11] clang-tidy: ignore cppcoreguidelines-narrowing-conversions --- .clang-tidy | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.clang-tidy b/.clang-tidy index 6e80b902..2a651563 100644 --- a/.clang-tidy +++ b/.clang-tidy @@ -26,7 +26,8 @@ Checks: ' -cppcoreguidelines-pro-bounds-array-to-pointer-decay, -cppcoreguidelines-pro-type-member-init, -cppcoreguidelines-special-member-functions, - -cppcoreguidelines-owning-memory + -cppcoreguidelines-owning-memory, + -cppcoreguidelines-narrowing-conversions ' HeaderFilterRegex: '^.*(source|include).*$' CheckOptions: -- GitLab From b364d60ae0ebac183b8f715b7894efbb0912598d Mon Sep 17 00:00:00 2001 From: Fabian Reister <fabian.reister@kit.edu> Date: Tue, 11 Jan 2022 21:41:58 +0100 Subject: [PATCH 07/11] replacing magic numbers --- .../algorithms/spfa/ShortestPathFasterAlgorithm.cpp | 6 +++--- .../algorithms/spfa/ShortestPathFasterAlgorithm.h | 7 +++++-- 2 files changed, 8 insertions(+), 5 deletions(-) diff --git a/source/armarx/navigation/algorithms/spfa/ShortestPathFasterAlgorithm.cpp b/source/armarx/navigation/algorithms/spfa/ShortestPathFasterAlgorithm.cpp index 692eec77..c7ad4ea4 100644 --- a/source/armarx/navigation/algorithms/spfa/ShortestPathFasterAlgorithm.cpp +++ b/source/armarx/navigation/algorithms/spfa/ShortestPathFasterAlgorithm.cpp @@ -185,12 +185,12 @@ namespace armarx::navigation::algorithms::spfa continue; - const float obstacleDistance1 = std::min(inputMap(row, col), 1000.F); - const float obstacleDistance2 = std::min(inputMap(ip, jp), 1000.F); + // const float obstacleDistance1 = std::min(inputMap(row, col), 1000.F); + const float obstacleDistance2 = std::min(inputMap(ip, jp), params.obstacleMaxDistance); const float travelCost = dir_lengths[k]; // const float obstacleDistanceCost = std::max(obstacleDistance1 - obstacleDistance2, 0.F) / costmap.params().cellSize; - const float targetDistanceCost = 3 * (1000.F - obstacleDistance2) / 1000.F; + const float targetDistanceCost = params.obstacleDistanceWeight * (params.obstacleMaxDistance - obstacleDistance2) / params.obstacleMaxDistance; const float edgeCost = params.obstacleDistanceCosts ? travelCost + targetDistanceCost : travelCost; diff --git a/source/armarx/navigation/algorithms/spfa/ShortestPathFasterAlgorithm.h b/source/armarx/navigation/algorithms/spfa/ShortestPathFasterAlgorithm.h index 65a458c3..810783e4 100644 --- a/source/armarx/navigation/algorithms/spfa/ShortestPathFasterAlgorithm.h +++ b/source/armarx/navigation/algorithms/spfa/ShortestPathFasterAlgorithm.h @@ -36,7 +36,10 @@ namespace armarx::navigation::algorithms::spfa public: struct Parameters { - bool obstacleDistanceCosts{true}; + bool obstacleDistanceCosts = true; + float obstacleMaxDistance = 1000.F; + + float obstacleDistanceWeight = 3.F; }; ShortestPathFasterAlgorithm(const Costmap& costmap, const Parameters& params); @@ -54,7 +57,7 @@ namespace armarx::navigation::algorithms::spfa Result spfa(const Eigen::Vector2f& start); - // protected: + // protected: /** * @brief Implementation highly inspired by github.com:jimmyyhwu/spatial-action-maps * -- GitLab From 1e9a6a4cc75f75f81e2e9dd69fbef5c080c69c3c Mon Sep 17 00:00:00 2001 From: Fabian Reister <fabian.reister@kit.edu> Date: Tue, 11 Jan 2022 21:42:24 +0100 Subject: [PATCH 08/11] cmake: using range-v3::range-v3 target instead of range-v3 only --- CMakeLists.txt | 30 ++++++++++++++----- .../GraphImportExport/CMakeLists.txt | 7 ----- source/armarx/navigation/core/CMakeLists.txt | 4 +-- .../navigation/global_planning/CMakeLists.txt | 2 +- .../navigation/local_planning/CMakeLists.txt | 9 ------ .../armarx/navigation/server/CMakeLists.txt | 2 +- 6 files changed, 26 insertions(+), 28 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 9420d8af..25e2b850 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,4 +1,4 @@ -cmake_minimum_required(VERSION 3.10) +cmake_minimum_required(VERSION 3.18) # default settings set(ARMARX_ENABLE_DEPENDENCY_VERSION_CHECK_DEFAULT FALSE) @@ -11,17 +11,19 @@ armarx_enable_modern_cmake_project() armarx_project(navigation NAMESPACE armarx) # Specify each ArmarX Package dependency with the following macro -armarx_find_package(PUBLIC ArmarXGui) + +# - required armarx_find_package(PUBLIC RobotAPI REQUIRED) + +# - optional +armarx_find_package(PUBLIC ArmarXGui) armarx_find_package(PUBLIC MemoryX QUIET) armarx_find_package(PUBLIC VisionX QUIET) -add_subdirectory(etc) -add_subdirectory(external) - -# Required dependencies +# System dependencies +# - required -# Optional dependencies +# - optional armarx_find_package(PUBLIC OpenMP QUIET) armarx_find_package(PUBLIC Ceres QUIET) armarx_find_package(PUBLIC VTK QUIET) @@ -29,6 +31,14 @@ armarx_find_package(PUBLIC SemanticObjectRelations QUIET) armarx_find_package(PUBLIC OpenCV QUIET) # Required as RobotAPI is a legacy project. +add_subdirectory(etc) + +set(RANGES_VERBOSE_BUILD OFF) +set(RANGES_RELEASE_BUILD ON) +set(RANGES_CXX_STD 17) +add_subdirectory(external) + + #include(FetchContent) #FetchContent_Declare( @@ -46,7 +56,11 @@ armarx_find_package(PUBLIC OpenCV QUIET) # Required as RobotAPI is a legacy pro # ) # FetchContent_MakeAvailable(inotify_cpp) -add_definitions("-Werror=init-self -Werror=uninitialized") +add_definitions(-Werror=init-self) +add_definitions(-Werror=uninitialized) +add_definitions(-Werror=missing-field-initializers) +add_definitions(-Werror=reorder) +add_definitions(-Werror=narrowing) add_subdirectory(source) diff --git a/source/armarx/navigation/components/GraphImportExport/CMakeLists.txt b/source/armarx/navigation/components/GraphImportExport/CMakeLists.txt index ec6c529d..123769e2 100644 --- a/source/armarx/navigation/components/GraphImportExport/CMakeLists.txt +++ b/source/armarx/navigation/components/GraphImportExport/CMakeLists.txt @@ -1,10 +1,3 @@ -#find_package(MemoryX QUIET) -#armarx_build_if(MemoryX_FOUND "MemoryX not available") -#if(MemoryX_FOUND) -# target_include_directories(${LIB_NAME} PUBLIC ${MemoryX_INCLUDE_DIRS}) -#endif() - - armarx_add_component(GraphImportExport DEPENDENCIES # ArmarXCore diff --git a/source/armarx/navigation/core/CMakeLists.txt b/source/armarx/navigation/core/CMakeLists.txt index ec1598c6..ca477220 100644 --- a/source/armarx/navigation/core/CMakeLists.txt +++ b/source/armarx/navigation/core/CMakeLists.txt @@ -45,7 +45,7 @@ armarx_add_library(core Simox::VirtualRobot armarx_navigation::core_aron PRIVATE - range-v3 + range-v3::range-v3 ) @@ -57,5 +57,5 @@ armarx_add_test(core_test ArmarXCore armarx_navigation::core PRIVATE - range-v3 + range-v3::range-v3 ) diff --git a/source/armarx/navigation/global_planning/CMakeLists.txt b/source/armarx/navigation/global_planning/CMakeLists.txt index b3b248d6..ca9fcf74 100644 --- a/source/armarx/navigation/global_planning/CMakeLists.txt +++ b/source/armarx/navigation/global_planning/CMakeLists.txt @@ -17,7 +17,7 @@ armarx_add_library(global_planning armarx_navigation::algorithms armarx_navigation::global_planning_aron PRIVATE - range-v3 + range-v3::range-v3 SOURCES ./GlobalPlanner.cpp ./AStar.cpp diff --git a/source/armarx/navigation/local_planning/CMakeLists.txt b/source/armarx/navigation/local_planning/CMakeLists.txt index 5894b6af..78a91fc0 100644 --- a/source/armarx/navigation/local_planning/CMakeLists.txt +++ b/source/armarx/navigation/local_planning/CMakeLists.txt @@ -9,12 +9,3 @@ armarx_add_library(local_planning HEADERS ./LocalPlanner.h ./TimedElasticBands.h ) - - -# find_package(MyLib QUIET) armarx_build_if(MyLib_FOUND "MyLib not available") -# all target_include_directories must be guarded by if(Xyz_FOUND) for multiple -# libraries write: if(X_FOUND AND Y_FOUND).... if(MyLib_FOUND) -# target_include_directories(local_planning PUBLIC ${MyLib_INCLUDE_DIRS}) -# endif() - -# add unit tests add_subdirectory(test) diff --git a/source/armarx/navigation/server/CMakeLists.txt b/source/armarx/navigation/server/CMakeLists.txt index 51cd9bae..b9f7a261 100644 --- a/source/armarx/navigation/server/CMakeLists.txt +++ b/source/armarx/navigation/server/CMakeLists.txt @@ -47,7 +47,7 @@ armarx_add_library(server armarx_navigation::safety_control armarx_navigation::memory PRIVATE - range-v3 + range-v3::range-v3 ) armarx_add_test(server_test -- GitLab From 0a5f98fcea70fdc29a630defc30c5b07d4662972 Mon Sep 17 00:00:00 2001 From: Fabian Reister <fabian.reister@kit.edu> Date: Wed, 12 Jan 2022 09:19:02 +0100 Subject: [PATCH 09/11] implementing merging of costmaps / grids --- .../armarx/navigation/algorithms/Costmap.cpp | 33 +++++ source/armarx/navigation/algorithms/Costmap.h | 32 ++++- .../navigation/algorithms/CostmapBuilder.cpp | 5 +- .../navigation/algorithms/CostmapBuilder.h | 6 +- source/armarx/navigation/algorithms/util.cpp | 113 ++++++++++++++++-- source/armarx/navigation/algorithms/util.h | 15 ++- 6 files changed, 185 insertions(+), 19 deletions(-) diff --git a/source/armarx/navigation/algorithms/Costmap.cpp b/source/armarx/navigation/algorithms/Costmap.cpp index 67fde2b8..3cb10124 100644 --- a/source/armarx/navigation/algorithms/Costmap.cpp +++ b/source/armarx/navigation/algorithms/Costmap.cpp @@ -62,5 +62,38 @@ namespace armarx::navigation::algorithms return grid(v.index.x(), v.index.y()) == 0.F; } + bool + Costmap::add(const Costmap& other) + { + const auto startIdx = toVertex(other.sceneBounds.min); + + // merge other grid into this one => use max costs + + // TODO if one of both matrices has mask, it has to be considered. + ARMARX_TRACE; + grid.block(startIdx.index.x(), startIdx.index.y(), other.grid.rows(), other.grid.cols()) = + grid.block(startIdx.index.x(), startIdx.index.y(), other.grid.rows(), other.grid.cols()) + .cwiseMax(other.grid); + + if(other.mask.has_value()) + { + if(not mask.has_value()) + { + mask = Mask(grid.rows(), grid.cols()); + mask->setOnes(); + } + + // union of masks + ARMARX_TRACE; + mask = mask->cwiseMin(other.mask->value()); + + // apply mask to grid => all invalid points will be 0 + ARMARX_TRACE; + grid = grid.cwiseProduct(mask->cast<float>()); + } + + return true; + } + } // namespace armarx::navigation::algorithms diff --git a/source/armarx/navigation/algorithms/Costmap.h b/source/armarx/navigation/algorithms/Costmap.h index 730a7175..4e94697d 100644 --- a/source/armarx/navigation/algorithms/Costmap.h +++ b/source/armarx/navigation/algorithms/Costmap.h @@ -1,6 +1,8 @@ #pragma once #include <Eigen/Core> +#include <Eigen/src/Core/util/Constants.h> +#include "ArmarXCore/core/exceptions/local/ExpressionException.h" #include <armarx/navigation/algorithms/types.h> @@ -28,10 +30,20 @@ namespace armarx::navigation::algorithms using Position = Eigen::Vector2f; using Grid = Eigen::MatrixXf; + // if 0, the cell is invalid + using Mask = Eigen::Matrix<bool, Eigen::Dynamic, Eigen::Dynamic>; - Costmap(const Grid& grid, const Parameters& parameters, const SceneBounds& sceneBounds) : - grid(grid), sceneBounds(sceneBounds), parameters(parameters) + Costmap(const Grid& grid, + const Parameters& parameters, + const SceneBounds& sceneBounds, + const std::optional<Mask>& mask = std::nullopt) : + grid(grid), mask(mask), sceneBounds(sceneBounds), parameters(parameters) { + if(mask.has_value()) + { + ARMARX_CHECK_EQUAL(grid.rows(), mask->rows()); + ARMARX_CHECK_EQUAL(grid.cols(), mask->cols()); + } } struct Vertex @@ -57,14 +69,28 @@ namespace armarx::navigation::algorithms return parameters; } - const SceneBounds& + const SceneBounds& getSceneBounds() const noexcept { return sceneBounds; } + Index + minIndex() const noexcept + { + Grid::Index row = 0; + Grid::Index col = 0; + + getGrid().minCoeff(&row, &col); + + return Index{row, col}; + } + + bool add(const Costmap& other); + private: Grid grid; + std::optional<Mask> mask; const SceneBounds sceneBounds; diff --git a/source/armarx/navigation/algorithms/CostmapBuilder.cpp b/source/armarx/navigation/algorithms/CostmapBuilder.cpp index 9c40a93d..4fe02e87 100644 --- a/source/armarx/navigation/algorithms/CostmapBuilder.cpp +++ b/source/armarx/navigation/algorithms/CostmapBuilder.cpp @@ -87,7 +87,10 @@ namespace armarx::navigation::algorithms ARMARX_INFO << "Grid size: " << c_x << ", " << c_y; ARMARX_INFO << "Resetting grid"; - return Eigen::MatrixXf(c_x, c_y); + Eigen::MatrixXf grid(c_x, c_y); + grid.setZero(); + + return grid; } diff --git a/source/armarx/navigation/algorithms/CostmapBuilder.h b/source/armarx/navigation/algorithms/CostmapBuilder.h index ff6ef9d2..3e1e4237 100644 --- a/source/armarx/navigation/algorithms/CostmapBuilder.h +++ b/source/armarx/navigation/algorithms/CostmapBuilder.h @@ -38,10 +38,10 @@ namespace armarx::navigation::algorithms [[nodiscard]] Costmap create(); - private: - Eigen::MatrixXf createUniformGrid(const SceneBounds& sceneBounds, - const Costmap::Parameters& parameters); + static Eigen::MatrixXf createUniformGrid(const SceneBounds& sceneBounds, + const Costmap::Parameters& parameters); + private: float computeCost(const Costmap::Position& position, VirtualRobot::RobotPtr& collisionRobot, const VirtualRobot::CollisionModelPtr& robotCollisionModel); diff --git a/source/armarx/navigation/algorithms/util.cpp b/source/armarx/navigation/algorithms/util.cpp index 843d40eb..a991a3d3 100644 --- a/source/armarx/navigation/algorithms/util.cpp +++ b/source/armarx/navigation/algorithms/util.cpp @@ -21,6 +21,13 @@ #include "util.h" +#include <algorithm> +#include <iterator> + +#include <opencv2/core/eigen.hpp> +#include <opencv2/imgproc.hpp> + +#include <SimoxUtility/algorithm/apply.hpp> #include <VirtualRobot/BoundingBox.h> #include <VirtualRobot/CollisionDetection/CollisionModel.h> #include <VirtualRobot/SceneObjectSet.h> @@ -28,6 +35,10 @@ #include "ArmarXCore/core/exceptions/local/ExpressionException.h" +#include "armarx/navigation/algorithms/Costmap.h" +#include "armarx/navigation/algorithms/CostmapBuilder.h" +#include "armarx/navigation/algorithms/types.h" + namespace armarx::navigation::algorithms { @@ -53,26 +64,112 @@ namespace armarx::navigation::algorithms } - armarx::navigation::algorithms::SceneBounds + SceneBounds toSceneBounds(const VirtualRobot::WorkspaceGrid::Extends& extends) { return {.min = Eigen::Vector2f{extends.minX, extends.minY}, .max = Eigen::Vector2f{extends.maxX, extends.maxY}}; } - armarx::navigation::algorithms::Costmap + SceneBounds + merge(const std::vector<SceneBounds>& sceneBounds) + { + SceneBounds bounds; + + const auto expandBounds = [&bounds](const SceneBounds& sb) + { + bounds.min.x() = std::min(bounds.min.x(), sb.min.x()); + bounds.min.y() = std::min(bounds.min.y(), sb.min.y()); + + bounds.max.x() = std::max(bounds.max.x(), sb.max.x()); + bounds.max.y() = std::max(bounds.max.y(), sb.max.y()); + + return bounds; + }; + + std::for_each(sceneBounds.begin(), sceneBounds.end(), expandBounds); + + return bounds; + } + + + Costmap toCostmap(const VirtualRobot::WorkspaceGrid& workspaceGrid) { - const armarx::navigation::algorithms::Costmap::Grid grid(workspaceGrid.getCells().x, - workspaceGrid.getCells().y); - const armarx::navigation::algorithms::SceneBounds sceneBounds = - toSceneBounds(workspaceGrid.getExtends()); + const Costmap::Grid grid(workspaceGrid.getCells().x, workspaceGrid.getCells().y); + const SceneBounds sceneBounds = toSceneBounds(workspaceGrid.getExtends()); - const armarx::navigation::algorithms::Costmap::Parameters parameters{ - .binaryGrid = false, .cellSize = workspaceGrid.getDiscretizeSize()}; + const Costmap::Parameters parameters{.binaryGrid = false, + .cellSize = workspaceGrid.getDiscretizeSize()}; return {grid, parameters, sceneBounds}; } + Costmap + mergeUnaligned(const std::vector<Costmap>& costmaps, + const std::vector<float>& weights, + float cellSize) + { + ARMARX_CHECK_EQUAL(costmaps.size(), weights.size()); + + // if unset, use the smallest cell size + if (cellSize < 0) + { + const auto compCellSize = [](const Costmap& a, const Costmap& b) -> bool + { return a.params().cellSize < b.params().cellSize; }; + + cellSize = + std::min_element(costmaps.begin(), costmaps.end(), compCellSize)->params().cellSize; + } + + // scale each costmap + std::vector<Costmap> scaledCostmaps = simox::alg::apply( + costmaps, + [&cellSize](const Costmap& costmap) -> Costmap { return scaleCostmap(costmap, cellSize); }); + + // merge costmaps into one + + // - combine scene bounds + std::vector<SceneBounds> sceneBoundsAll = simox::alg::apply( + scaledCostmaps, [](const Costmap& costmap) { return costmap.getSceneBounds(); }); + + const SceneBounds sceneBounds = merge(sceneBoundsAll); + + // - create grid + const auto largeGrid = CostmapBuilder::createUniformGrid( + sceneBounds, Costmap::Parameters{.binaryGrid = false, .cellSize = cellSize}); + + Costmap largeCostmap( + largeGrid, Costmap::Parameters{.binaryGrid = false, .cellSize = cellSize}, sceneBounds); + + // - add all costmaps to this one + std::for_each(scaledCostmaps.begin(), + scaledCostmaps.end(), + [&largeCostmap](const Costmap& costmap) { largeCostmap.add(costmap); }); + + // return merged grid + return largeCostmap; + } + + Costmap + scaleCostmap(const Costmap& costmap, float cellSize) + { + const float scale = cellSize / costmap.params().cellSize; + + cv::Mat src; + cv::eigen2cv(costmap.getGrid(), src); + + cv::Mat dst; + cv::resize(src, dst, cv::Size{0, 0}, scale, scale); + + Eigen::MatrixXf scaledGrid; + cv::cv2eigen(dst, scaledGrid); + + return {scaledGrid, + Costmap::Parameters{.binaryGrid = false, .cellSize = cellSize}, + costmap.getSceneBounds()}; + } + + } // namespace armarx::navigation::algorithms diff --git a/source/armarx/navigation/algorithms/util.h b/source/armarx/navigation/algorithms/util.h index cee91e0c..1a4d1d0e 100644 --- a/source/armarx/navigation/algorithms/util.h +++ b/source/armarx/navigation/algorithms/util.h @@ -33,10 +33,17 @@ namespace armarx::navigation::algorithms { SceneBounds computeSceneBounds(const VirtualRobot::SceneObjectSetPtr& obstacles); - armarx::navigation::algorithms::SceneBounds - toSceneBounds(const VirtualRobot::WorkspaceGrid::Extends& extends); + SceneBounds toSceneBounds(const VirtualRobot::WorkspaceGrid::Extends& extends); - armarx::navigation::algorithms::Costmap - toCostmap(const VirtualRobot::WorkspaceGrid& workspaceGrid); + SceneBounds merge(const std::vector<SceneBounds>& sceneBounds); + + + Costmap toCostmap(const VirtualRobot::WorkspaceGrid& workspaceGrid); + + Costmap mergeUnaligned(const std::vector<Costmap>& costmaps, + const std::vector<float>& weights, + float cellSize = -1); + + Costmap scaleCostmap(const Costmap& costmap, float cellSize); } // namespace armarx::navigation::algorithms -- GitLab From bc9d6b28a00d0b788c91beaada2cada4f89a6d2f Mon Sep 17 00:00:00 2001 From: Fabian Reister <fabian.reister@kit.edu> Date: Wed, 12 Jan 2022 16:23:51 +0100 Subject: [PATCH 10/11] navigation simulation scenario update --- .../HandUnitDynamicSimulationApp.LeftHand.cfg | 23 +++++++++++++++++++ ...HandUnitDynamicSimulationApp.RightHand.cfg | 23 +++++++++++++++++++ .../config/LongtermMemory.cfg | 16 ------------- .../config/PriorKnowledge.cfg | 8 ------- .../config/WorkingMemory.cfg | 8 ------- 5 files changed, 46 insertions(+), 32 deletions(-) diff --git a/scenarios/NavigationSimulation/config/HandUnitDynamicSimulationApp.LeftHand.cfg b/scenarios/NavigationSimulation/config/HandUnitDynamicSimulationApp.LeftHand.cfg index 18e2d2db..ddfb9cce 100644 --- a/scenarios/NavigationSimulation/config/HandUnitDynamicSimulationApp.LeftHand.cfg +++ b/scenarios/NavigationSimulation/config/HandUnitDynamicSimulationApp.LeftHand.cfg @@ -76,6 +76,14 @@ ArmarX.ApplicationName = LeftHandUnitApp # ArmarX.EnableProfiling = false +# ArmarX.HandUnitDynamicSimulation.ArVizTopicName: Name of the ArViz topic +# Attributes: +# - Default: ArVizTopic +# - Case sensitivity: yes +# - Required: no +# ArmarX.HandUnitDynamicSimulation.ArVizTopicName = ArVizTopic + + # ArmarX.HandUnitDynamicSimulation.EnableProfiling: enable profiler which is used for logging performance events # Attributes: # - Default: false @@ -131,6 +139,13 @@ ArmarX.HandUnitDynamicSimulation.ObjectName = LeftHandUnit # ArmarX.HandUnitDynamicSimulation.RobotStateComponentName = RobotStateComponent +# ArmarX.HandUnitDynamicSimulation.Side: Name of the hand (left, right) +# Attributes: +# - Case sensitivity: yes +# - Required: yes +# ArmarX.HandUnitDynamicSimulation.Side = ::_NOT_SET_:: + + # ArmarX.HandUnitDynamicSimulation.SimulatorProxyName: Name of the simulator proxy to use. # Attributes: # - Default: Simulator @@ -139,6 +154,14 @@ ArmarX.HandUnitDynamicSimulation.ObjectName = LeftHandUnit # ArmarX.HandUnitDynamicSimulation.SimulatorProxyName = Simulator +# ArmarX.HandUnitDynamicSimulation.WorkingMemoryName: Name of the working memory that should be used +# Attributes: +# - Default: WorkingMemory +# - Case sensitivity: yes +# - Required: no +# ArmarX.HandUnitDynamicSimulation.WorkingMemoryName = WorkingMemory + + # ArmarX.HandUnitDynamicSimulation.inheritFrom: No Description # Attributes: # - Default: RobotConfig diff --git a/scenarios/NavigationSimulation/config/HandUnitDynamicSimulationApp.RightHand.cfg b/scenarios/NavigationSimulation/config/HandUnitDynamicSimulationApp.RightHand.cfg index 85cc4345..cf952e6f 100644 --- a/scenarios/NavigationSimulation/config/HandUnitDynamicSimulationApp.RightHand.cfg +++ b/scenarios/NavigationSimulation/config/HandUnitDynamicSimulationApp.RightHand.cfg @@ -76,6 +76,14 @@ ArmarX.ApplicationName = RightHandUnitApp # ArmarX.EnableProfiling = false +# ArmarX.HandUnitDynamicSimulation.ArVizTopicName: Name of the ArViz topic +# Attributes: +# - Default: ArVizTopic +# - Case sensitivity: yes +# - Required: no +# ArmarX.HandUnitDynamicSimulation.ArVizTopicName = ArVizTopic + + # ArmarX.HandUnitDynamicSimulation.EnableProfiling: enable profiler which is used for logging performance events # Attributes: # - Default: false @@ -131,6 +139,13 @@ ArmarX.HandUnitDynamicSimulation.ObjectName = RightHandUnit # ArmarX.HandUnitDynamicSimulation.RobotStateComponentName = RobotStateComponent +# ArmarX.HandUnitDynamicSimulation.Side: Name of the hand (left, right) +# Attributes: +# - Case sensitivity: yes +# - Required: yes +# ArmarX.HandUnitDynamicSimulation.Side = ::_NOT_SET_:: + + # ArmarX.HandUnitDynamicSimulation.SimulatorProxyName: Name of the simulator proxy to use. # Attributes: # - Default: Simulator @@ -139,6 +154,14 @@ ArmarX.HandUnitDynamicSimulation.ObjectName = RightHandUnit # ArmarX.HandUnitDynamicSimulation.SimulatorProxyName = Simulator +# ArmarX.HandUnitDynamicSimulation.WorkingMemoryName: Name of the working memory that should be used +# Attributes: +# - Default: WorkingMemory +# - Case sensitivity: yes +# - Required: no +# ArmarX.HandUnitDynamicSimulation.WorkingMemoryName = WorkingMemory + + # ArmarX.HandUnitDynamicSimulation.inheritFrom: No Description # Attributes: # - Default: RobotConfig diff --git a/scenarios/NavigationSimulation/config/LongtermMemory.cfg b/scenarios/NavigationSimulation/config/LongtermMemory.cfg index 0eae3f1a..e323230d 100644 --- a/scenarios/NavigationSimulation/config/LongtermMemory.cfg +++ b/scenarios/NavigationSimulation/config/LongtermMemory.cfg @@ -100,14 +100,6 @@ MemoryX.LongtermMemory.ClassCollections = memdb.Longterm_Objects -# MemoryX.LongtermMemory.CommonStorageName: Name of common storage. -# Attributes: -# - Default: CommonStorage -# - Case sensitivity: yes -# - Required: no -# MemoryX.LongtermMemory.CommonStorageName = CommonStorage - - # MemoryX.LongtermMemory.DatabaseName: Mongo database to store LTM data # Attributes: # - Case sensitivity: yes @@ -173,14 +165,6 @@ MemoryX.LongtermMemory.DatabaseName = CeBITdb # MemoryX.LongtermMemory.PredictionDataCollection = ltm_predictiondata -# MemoryX.LongtermMemory.PriorKnowledgeName: Name of prior knowledge. -# Attributes: -# - Default: PriorKnowledge -# - Case sensitivity: yes -# - Required: no -# MemoryX.LongtermMemory.PriorKnowledgeName = PriorKnowledge - - # MemoryX.LongtermMemory.ProfilerDataCollection: Mongo collection for storing Profiler data # Attributes: # - Default: ltm_profilerdata diff --git a/scenarios/NavigationSimulation/config/PriorKnowledge.cfg b/scenarios/NavigationSimulation/config/PriorKnowledge.cfg index d2a8fe85..c44a2b83 100644 --- a/scenarios/NavigationSimulation/config/PriorKnowledge.cfg +++ b/scenarios/NavigationSimulation/config/PriorKnowledge.cfg @@ -99,14 +99,6 @@ MemoryX.PriorKnowledge.ClassCollections = CeBITdb.Prior_CeBIT -# MemoryX.PriorKnowledge.CommonStorageName: Name of common storage. -# Attributes: -# - Default: CommonStorage -# - Case sensitivity: yes -# - Required: no -# MemoryX.PriorKnowledge.CommonStorageName = CommonStorage - - # MemoryX.PriorKnowledge.EnableProfiling: enable profiler which is used for logging performance events # Attributes: # - Default: false diff --git a/scenarios/NavigationSimulation/config/WorkingMemory.cfg b/scenarios/NavigationSimulation/config/WorkingMemory.cfg index a6115c9f..f33e4b8b 100644 --- a/scenarios/NavigationSimulation/config/WorkingMemory.cfg +++ b/scenarios/NavigationSimulation/config/WorkingMemory.cfg @@ -272,14 +272,6 @@ MemoryX.ObjectLocalizationMemoryUpdater.WorkingMemoryName = "WorkingMemory" # MemoryX.Verbosity = Info -# MemoryX.WorkingMemory.CommonStorageName: Name of common storage. -# Attributes: -# - Default: CommonStorage -# - Case sensitivity: yes -# - Required: no -# MemoryX.WorkingMemory.CommonStorageName = CommonStorage - - # MemoryX.WorkingMemory.EnableProfiling: enable profiler which is used for logging performance events # Attributes: # - Default: false -- GitLab From 927ae4f29a3a4d3fb99a39611375b5b64429a8e4 Mon Sep 17 00:00:00 2001 From: Fabian Reister <fabian.reister@kit.edu> Date: Wed, 12 Jan 2022 16:24:26 +0100 Subject: [PATCH 11/11] using mask; fix: robot only with collision model (visu model sucks -> segfaults ...) --- .../armarx/navigation/algorithms/Costmap.cpp | 90 +++++++++++++++++-- source/armarx/navigation/algorithms/Costmap.h | 41 ++------- .../spfa/ShortestPathFasterAlgorithm.cpp | 16 +++- .../components/Navigator/Navigator.cpp | 2 +- 4 files changed, 101 insertions(+), 48 deletions(-) diff --git a/source/armarx/navigation/algorithms/Costmap.cpp b/source/armarx/navigation/algorithms/Costmap.cpp index 3cb10124..bf9cad97 100644 --- a/source/armarx/navigation/algorithms/Costmap.cpp +++ b/source/armarx/navigation/algorithms/Costmap.cpp @@ -7,6 +7,7 @@ #include <boost/geometry.hpp> #include <boost/geometry/algorithms/detail/intersects/interface.hpp> +#include <Eigen/Core> #include <Eigen/Geometry> #include <IceUtil/Time.h> @@ -28,6 +29,19 @@ 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) + { + if (mask.has_value()) + { + ARMARX_CHECK_EQUAL(grid.rows(), mask->rows()); + ARMARX_CHECK_EQUAL(grid.cols(), mask->cols()); + } + } + Costmap::Position Costmap::toPosition(const Costmap::Index& index) const { @@ -46,13 +60,75 @@ namespace armarx::navigation::algorithms const float vY = (v.y() - parameters.cellSize / 2 - sceneBounds.min.y()) / parameters.cellSize; - ARMARX_CHECK(vX >= 0.F); - ARMARX_CHECK(vY >= 0.F); + const int iX = std::round(vX); + const int iY = std::round(vY); + + const int iXSan = std::clamp<int>(iX, 0, grid.rows() - 1); + const int iYSan = std::clamp<int>(iY, 0, grid.cols() - 1); + + // FIXME accept one cell off + + // ARMARX_CHECK_GREATER(iX, 0); + // ARMARX_CHECK_GREATER(iY, 0); + + // ARMARX_CHECK_LESS_EQUAL(iX, grid.rows() - 1); + // ARMARX_CHECK_LESS_EQUAL(iY, grid.cols() - 1); + + return Vertex{.index = Index{iXSan, iYSan}, .position = v}; + } + + const SceneBounds& + Costmap::getSceneBounds() const noexcept + { + return sceneBounds; + } + + Costmap::Index + Costmap::minIndex() const noexcept + { + // index of the min element + Grid::Index row = 0; + Grid::Index col = 0; + + // value of the min element + float minVal = std::numeric_limits<float>::max(); + + for (int r = 0; r < grid.rows(); r++) + { + for (int c = 0; c < grid.cols(); c++) + { + if (mask.has_value()) + { + if (not mask.value()(r, c)) // skip invalid cells + { + continue; + } + + const float currentVal = grid(r, c); + if (currentVal >= minVal) + { + minVal = currentVal; + row = r; + col = c; + } + } + } + } + - ARMARX_CHECK(vX <= (grid.rows() - 1)); - ARMARX_CHECK(vY <= (grid.cols() - 1)); + return Index{row, col}; + } - return Vertex{.index = Index{static_cast<int>(vX), static_cast<int>(vY)}, .position = v}; + const Costmap::Parameters& + Costmap::params() const noexcept + { + return parameters; + } + + const Costmap::Grid& + Costmap::getGrid() const + { + return grid; } bool @@ -75,9 +151,9 @@ namespace armarx::navigation::algorithms grid.block(startIdx.index.x(), startIdx.index.y(), other.grid.rows(), other.grid.cols()) .cwiseMax(other.grid); - if(other.mask.has_value()) + if (other.mask.has_value()) { - if(not mask.has_value()) + if (not mask.has_value()) { mask = Mask(grid.rows(), grid.cols()); mask->setOnes(); diff --git a/source/armarx/navigation/algorithms/Costmap.h b/source/armarx/navigation/algorithms/Costmap.h index 4e94697d..d35e7781 100644 --- a/source/armarx/navigation/algorithms/Costmap.h +++ b/source/armarx/navigation/algorithms/Costmap.h @@ -1,8 +1,6 @@ #pragma once #include <Eigen/Core> -#include <Eigen/src/Core/util/Constants.h> -#include "ArmarXCore/core/exceptions/local/ExpressionException.h" #include <armarx/navigation/algorithms/types.h> @@ -36,15 +34,7 @@ namespace armarx::navigation::algorithms Costmap(const Grid& grid, const Parameters& parameters, const SceneBounds& sceneBounds, - const std::optional<Mask>& mask = std::nullopt) : - grid(grid), mask(mask), sceneBounds(sceneBounds), parameters(parameters) - { - if(mask.has_value()) - { - ARMARX_CHECK_EQUAL(grid.rows(), mask->rows()); - ARMARX_CHECK_EQUAL(grid.cols(), mask->cols()); - } - } + const std::optional<Mask>& mask = std::nullopt); struct Vertex { @@ -55,36 +45,15 @@ namespace armarx::navigation::algorithms Position toPosition(const Index& index) const; Vertex toVertex(const Position& v) const; - const Grid& - getGrid() const - { - return grid; - } + const Grid& getGrid() const; bool isInCollision(const Position& p) const; - const Parameters& - params() const noexcept - { - return parameters; - } - - const SceneBounds& - getSceneBounds() const noexcept - { - return sceneBounds; - } - - Index - minIndex() const noexcept - { - Grid::Index row = 0; - Grid::Index col = 0; + const Parameters& params() const noexcept; - getGrid().minCoeff(&row, &col); + const SceneBounds& getSceneBounds() const noexcept; - return Index{row, col}; - } + Index minIndex() const noexcept; bool add(const Costmap& other); diff --git a/source/armarx/navigation/algorithms/spfa/ShortestPathFasterAlgorithm.cpp b/source/armarx/navigation/algorithms/spfa/ShortestPathFasterAlgorithm.cpp index c7ad4ea4..248db17d 100644 --- a/source/armarx/navigation/algorithms/spfa/ShortestPathFasterAlgorithm.cpp +++ b/source/armarx/navigation/algorithms/spfa/ShortestPathFasterAlgorithm.cpp @@ -22,6 +22,7 @@ #include "ShortestPathFasterAlgorithm.h" #include <algorithm> +#include <numeric> #include <Eigen/Core> @@ -128,6 +129,8 @@ namespace armarx::navigation::algorithms::spfa ShortestPathFasterAlgorithm::spfa(const Eigen::MatrixXf& inputMap, const Eigen::Vector2i& source) const { + ARMARX_CHECK_GREATER(inputMap(source.x(), source.y()), 0.F) << "Start must not be in collision"; + const float eps = 1e-6; const int num_dirs = 8; @@ -160,9 +163,8 @@ namespace armarx::navigation::algorithms::spfa float* dists = new float[max_num_verts]; for (int i = 0; i < max_num_verts; ++i) dists[i] = inf; - int* parents = new int[max_num_verts](); - for (int i = 0; i < max_num_verts; ++i) - parents[i] = -1; + + std::vector<int> parents(max_num_verts, -1); // Build graph ARMARX_INFO << "Build graph"; @@ -249,6 +251,8 @@ namespace armarx::navigation::algorithms::spfa Eigen::Vector2i{-1, -1})); } + int invalids = 0; + for (int row = 0; row < num_rows; ++row) { for (int col = 0; col < num_cols; ++col) @@ -258,6 +262,7 @@ namespace armarx::navigation::algorithms::spfa if (parents[u] == -1) // no parent { + invalids++; continue; } @@ -265,6 +270,10 @@ namespace armarx::navigation::algorithms::spfa } } + + ARMARX_INFO << "Fraction of invalid cells: (" << invalids << "/" << parents.size() << ")"; + + // Free memory delete[] edges; delete[] edge_counts; @@ -272,7 +281,6 @@ namespace armarx::navigation::algorithms::spfa delete[] in_queue; delete[] weights; delete[] dists; - delete[] parents; ARMARX_INFO << "Done."; return Result{.distances = output_dists, .parents = output_parents}; diff --git a/source/armarx/navigation/components/Navigator/Navigator.cpp b/source/armarx/navigation/components/Navigator/Navigator.cpp index 13718710..2ec54dc2 100644 --- a/source/armarx/navigation/components/Navigator/Navigator.cpp +++ b/source/armarx/navigation/components/Navigator/Navigator.cpp @@ -619,7 +619,7 @@ namespace armarx::navigation::components ARMARX_TRACE; auto robot = RemoteRobot::createLocalCloneFromFile( - getRobotStateComponent(), VirtualRobot::RobotIO::RobotDescription::eFull); + getRobotStateComponent(), VirtualRobot::RobotIO::RobotDescription::eCollisionModel); // auto robot = RemoteRobot::createLocalClone(getRobotStateComponent()); ARMARX_CHECK_NOT_NULL(robot); -- GitLab