Я пытаюсь использовать RRT Connect в пространстве состояний Оуэна с использованием библиотеки OMPL.
RRT Connect — это метод поиска, основанный на RRT, который вместо того, чтобы получать одну начальную точку для достижения цели с помощью растущих деревьев, он выращивает деревья как от начала, так и от цели, ожидая, что оба будут соединяться в середине.
Пространство состояний Оуэна — это пространство состояний, которое заставляет движение между точками следовать по путям Дубина, которые представляют собой минимальные кривые, позволяющие перемещаться между двумя позами (позиция+ориентация).
По какой-то причине в моем коде я получаю внезапный поворот на 180° в месте пересечения начальной и целевой ветвей.
Я думаю, что это может быть проблема, при которой можно бежать назад. В моем случае это невозможно. Я пытался убедиться, что валидатор движения использует проверку Оуэнса, поскольку она не должна разрешать движение назад, но это ничего не меняет.
Я бы искал что-то вроде этого
В приведенном выше примере путь непрерывен, без каких-либо резких поворотов или движения назад в любом сегмент. Я получил его, используя RRT* вместо RRT Connect. Однако в качестве демонстрации я хотел также запустить код для этого второго алгоритма.
Как правильно запустить Dubins Paths в алгоритме RRT Connect с использованием библиотеки OMPL?
Этот код выполнен на C++ с использованием ROS2.
Кроме того, это не совсем актуально, но для препятствий используются ограничивающие рамки, а для карты — библиотека GridMapGeo. б/у.
Я пытаюсь использовать RRT Connect в пространстве состояний Оуэна с использованием библиотеки OMPL. RRT Connect — это метод поиска, основанный на RRT, который вместо того, чтобы получать одну начальную точку для достижения цели с помощью растущих деревьев, он выращивает деревья как от начала, так и от цели, ожидая, что оба будут [b]соединяться[/b] в середине. Пространство состояний Оуэна — это пространство состояний, которое заставляет движение между точками следовать по путям Дубина, которые представляют собой минимальные кривые, позволяющие перемещаться между двумя позами (позиция+ориентация). По какой-то причине в моем коде я получаю внезапный поворот на 180° в месте пересечения начальной и целевой ветвей. [img]https://i.sstatic.net/BOF4rYSz.png[/img] [img]https://i.sstatic.net/nSbTBdqP.png[/img]
Я думаю, что это может быть проблема, при которой можно бежать назад. В моем случае это невозможно. Я пытался убедиться, что валидатор движения использует проверку Оуэнса, поскольку она не должна разрешать движение назад, но это ничего не меняет. Я бы искал что-то вроде этого [img]https://i.sstatic.net/6HQ0loLB.png[/img] В приведенном выше примере путь непрерывен, без каких-либо резких поворотов или движения назад в любом сегмент. Я получил его, используя RRT* вместо RRT Connect. Однако в качестве демонстрации я хотел также запустить код для этого второго алгоритма. Как правильно запустить Dubins Paths в алгоритме RRT Connect с использованием библиотеки OMPL? Этот код выполнен на C++ с использованием ROS2. Кроме того, это не совсем актуально, но для препятствий используются ограничивающие рамки, а для карты — библиотека GridMapGeo. б/у. [code]#include #include #include
/** * @brief Constructor * @param map GridMap of the area, may include layers to show maximum and minimum allowable height (see param setLayers) * @param start Start position * @param goal Goal position * @param setLayers false if GridMap already comes with bounding layers, true if it doesn't */ OMPL_Planner(const grid_map::GridMap &map, geometry_msgs::msg::PoseStamped start, geometry_msgs::msg::PoseStamped goal, bool setLayers = false);
/** * @brief Constructor * @param range Desired range of the planner * @param width width of the map (X coordinates) * @param height height of the map (Y coordinates), not to mistake with elevation * @param start Start position * @param goal Goal position */ OMPL_Planner(double range, int width, int height, geometry_msgs::msg::PoseStamped start, geometry_msgs::msg::PoseStamped goal);
~OMPL_Planner() { }
/** * @brief Path planning function using gridmap */ nav_msgs::msg::Path pathPlanner(double time = 1.0);
/** * @brief Set Start * @param poseMsg start position as a ROS2 message */ void setStart(geometry_msgs::msg::PoseStamped poseMsg);
/** * @brief Set Goal * @param poseMsg start position as a ROS2 message */ void setGoal(geometry_msgs::msg::PoseStamped poseMsg);
/** * @brief Set Obstacles * @param obstacles_ Pointer to the list of obstacles as a BoundingBox3DArray */ void setObstacles(const vision_msgs::msg::BoundingBox3DArray &obstacles_);
// Constructor OMPL_Planner::OMPL_Planner(double range, int width, int height, geometry_msgs::msg::PoseStamped start, geometry_msgs::msg::PoseStamped goal) { Range = range; setBounds(-range * width / 2, range * width / 2, -range * height / 2, range * height / 2, 0.0, Max_wave + Cord); setStart(start); setGoal(goal); }
// Path planning function using gridmap nav_msgs::msg::Path OMPL_Planner::pathPlanner(double time) { std::shared_ptr space; // In here it is stated to use owen paths std::shared_ptr terrain_map; // Uses GridMapGeo for the map auto si(std::make_shared(space));
// It is possible for obstacles to exist, composed of bounding boxes if (obstaclesSet) { validity_checker = std::make_shared(si, terrain_map->getGridMap(), Path); si->setStateValidityChecker(ob::StateValidityCheckerPtr(validity_checker)); }
// If there are no obstacles else { validity_checker = std::make_shared(si, terrain_map->getGridMap(), Path, Obstacles); si->setStateValidityChecker(ob::StateValidityCheckerPtr(validity_checker)); } si->setMotionValidator(std::make_shared(si));
auto probDef(std::make_shared(si)); probDef->setStartAndGoalStates(*start, *goal); probDef->setOptimizationObjective(getOptObj(si));
auto planner(std::make_shared(si));// In here it is stated to use RRTConnect planner->setRange(Range); // planner->setTreePruning(false); // planner->setDelayCC(true); planner->setProblemDefinition(probDef); planner->setup(); printf("..................PLANNER HAS THE FOLLOWING SETTINGS..................\n"); si->printSettings(std::cout); printf("......................................................................\n"); probDef->print(std::cout); printf("......................................................................\n");
namespace ompl { class PathValidityChecker : public base::StateValidityChecker { public: /** * @brief Constructor of the owen validity checker * @param Map Map of the area as a GridMap */ PathValidityChecker(const base::SpaceInformationPtr &space_info, const grid_map::GridMap &map_, const std::vector Path) : base::StateValidityChecker(space_info), gridmap(map_), path(Path) {}
/** * @brief Constructor of the owen validity checker including obstacles * @param Map Map of the area as a GridMap * @param Obstacles List of obstacles as an array */ PathValidityChecker(const base::SpaceInformationPtr &space_info, const grid_map::GridMap &map_, const std::vector Path, const std::vector Obstacles) : base::StateValidityChecker(space_info), gridmap(map_), path(Path), obstacle_list(Obstacles) { existObstacles = true; }
/** * @brief Check if state is valid * @param state * @return true if state is valid * @return false if state is not valid */ virtual bool isValid(const base::State *state) const override;
/** * @brief Check if that position is in collision * @param state Position as an eigen 3D vector * @return true if there is collision * @return false if there is no collision */ bool checkCollision(const Eigen::Vector3d state) const;
/** * @brief Check if that position is in collision * @param state Position as a Pose * @return true if there is collision * @return false if there is no collision */ bool checkCollision(const Pose state) const;
/** * @brief Check minimum distance from current state to the path * @return Minimum distance to the path */ double clearance(const base::State *s) const;