@ -0,0 +1,18 @@
|
|||||||
|
{
|
||||||
|
"configurations": [
|
||||||
|
{
|
||||||
|
"name": "Linux",
|
||||||
|
"browse": {
|
||||||
|
"databaseFilename": "",
|
||||||
|
"limitSymbolsToIncludedHeaders": true
|
||||||
|
},
|
||||||
|
"includePath": [
|
||||||
|
"${workspaceFolder}/**",
|
||||||
|
"/opt/ros/melodic/include",
|
||||||
|
"/opt/ros/melodic/include/ompl-1.4"
|
||||||
|
]
|
||||||
|
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"version": 4
|
||||||
|
}
|
||||||
@ -0,0 +1,73 @@
|
|||||||
|
{
|
||||||
|
"python.autoComplete.extraPaths": [
|
||||||
|
"/home/dengpw/catkin_ws/devel/lib/python2.7/dist-packages",
|
||||||
|
"/opt/ros/melodic/lib/python2.7/dist-packages"
|
||||||
|
],
|
||||||
|
"files.associations": {
|
||||||
|
"cctype": "cpp",
|
||||||
|
"clocale": "cpp",
|
||||||
|
"cmath": "cpp",
|
||||||
|
"csignal": "cpp",
|
||||||
|
"cstdarg": "cpp",
|
||||||
|
"cstddef": "cpp",
|
||||||
|
"cstdio": "cpp",
|
||||||
|
"cstdlib": "cpp",
|
||||||
|
"cstring": "cpp",
|
||||||
|
"ctime": "cpp",
|
||||||
|
"cwchar": "cpp",
|
||||||
|
"cwctype": "cpp",
|
||||||
|
"array": "cpp",
|
||||||
|
"atomic": "cpp",
|
||||||
|
"strstream": "cpp",
|
||||||
|
"*.tcc": "cpp",
|
||||||
|
"bitset": "cpp",
|
||||||
|
"chrono": "cpp",
|
||||||
|
"complex": "cpp",
|
||||||
|
"cstdint": "cpp",
|
||||||
|
"deque": "cpp",
|
||||||
|
"list": "cpp",
|
||||||
|
"unordered_map": "cpp",
|
||||||
|
"unordered_set": "cpp",
|
||||||
|
"vector": "cpp",
|
||||||
|
"exception": "cpp",
|
||||||
|
"hash_map": "cpp",
|
||||||
|
"hash_set": "cpp",
|
||||||
|
"fstream": "cpp",
|
||||||
|
"functional": "cpp",
|
||||||
|
"initializer_list": "cpp",
|
||||||
|
"iomanip": "cpp",
|
||||||
|
"iosfwd": "cpp",
|
||||||
|
"iostream": "cpp",
|
||||||
|
"istream": "cpp",
|
||||||
|
"limits": "cpp",
|
||||||
|
"new": "cpp",
|
||||||
|
"ostream": "cpp",
|
||||||
|
"numeric": "cpp",
|
||||||
|
"ratio": "cpp",
|
||||||
|
"sstream": "cpp",
|
||||||
|
"stdexcept": "cpp",
|
||||||
|
"streambuf": "cpp",
|
||||||
|
"system_error": "cpp",
|
||||||
|
"thread": "cpp",
|
||||||
|
"cfenv": "cpp",
|
||||||
|
"cinttypes": "cpp",
|
||||||
|
"tuple": "cpp",
|
||||||
|
"type_traits": "cpp",
|
||||||
|
"utility": "cpp",
|
||||||
|
"typeindex": "cpp",
|
||||||
|
"typeinfo": "cpp",
|
||||||
|
"algorithm": "cpp",
|
||||||
|
"iterator": "cpp",
|
||||||
|
"map": "cpp",
|
||||||
|
"memory": "cpp",
|
||||||
|
"memory_resource": "cpp",
|
||||||
|
"optional": "cpp",
|
||||||
|
"random": "cpp",
|
||||||
|
"set": "cpp",
|
||||||
|
"string": "cpp",
|
||||||
|
"string_view": "cpp",
|
||||||
|
"*.ipp": "cpp",
|
||||||
|
"*.txx": "cpp",
|
||||||
|
"valarray": "cpp"
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,66 @@
|
|||||||
|
cmake_minimum_required(VERSION 3.0.2)
|
||||||
|
project(hybrid_astar_planner)
|
||||||
|
|
||||||
|
set(CMAKE_CXX_STANDARD 11)
|
||||||
|
set(CMAKE_CXX_COMPILER "g++")
|
||||||
|
|
||||||
|
# add_subdirectory(test_the_plugin)
|
||||||
|
|
||||||
|
find_package(catkin REQUIRED COMPONENTS
|
||||||
|
geometry_msgs
|
||||||
|
pluginlib
|
||||||
|
costmap_2d
|
||||||
|
roscpp
|
||||||
|
nav_core
|
||||||
|
tf2_ros
|
||||||
|
ompl
|
||||||
|
)
|
||||||
|
|
||||||
|
catkin_package(
|
||||||
|
INCLUDE_DIRS include
|
||||||
|
LIBRARIES ${PROJECT_NAME}
|
||||||
|
geometry_msgs
|
||||||
|
pluginlib
|
||||||
|
roscpp
|
||||||
|
nav_core
|
||||||
|
tf2_ros
|
||||||
|
ompl
|
||||||
|
)
|
||||||
|
|
||||||
|
include_directories(
|
||||||
|
include
|
||||||
|
test_the_plugin/include
|
||||||
|
${catkin_INCLUDE_DIRS}
|
||||||
|
${OMPL_INCLUDE_DIRS}
|
||||||
|
)
|
||||||
|
|
||||||
|
# find_package(ompl REQUIRED)
|
||||||
|
|
||||||
|
# if(NOT OMPL_FOUND)
|
||||||
|
# message(AUTHOR_WARNING,"Open Motion Planning Library not found")
|
||||||
|
# endif(NOT OMPL_FOUND)
|
||||||
|
|
||||||
|
|
||||||
|
add_executable(test_planner test_the_plugin/src/test.cpp test_the_plugin/src/test_plugins.cpp)
|
||||||
|
target_link_libraries(test_planner ${catkin_LIBRARIES})
|
||||||
|
|
||||||
|
add_executable(tf_test_broadcaster test_the_plugin/src/tf_broadcaster.cpp)
|
||||||
|
target_link_libraries(tf_test_broadcaster ${catkin_LIBRARIES})
|
||||||
|
|
||||||
|
add_library(${PROJECT_NAME}
|
||||||
|
src/planner_core.cpp
|
||||||
|
src/hybrid_astar.cpp
|
||||||
|
src/node2d.cpp
|
||||||
|
src/a_start.cpp
|
||||||
|
src/visualize.cpp
|
||||||
|
src/node3d.cpp
|
||||||
|
src/hybrid_astar.cpp
|
||||||
|
src/algorithm.cpp
|
||||||
|
src/dubins.cpp
|
||||||
|
src/ReedsShepp.cpp
|
||||||
|
)
|
||||||
|
target_link_libraries(${PROJECT_NAME} ${OMPL_LIBRARIES})
|
||||||
|
|
||||||
|
install(FILES bgp_plugin.xml
|
||||||
|
DESTINATION ${CATKIN_PACKAGE_SHARE_DESTINATION}
|
||||||
|
)
|
||||||
@ -0,0 +1,29 @@
|
|||||||
|
BSD 3-Clause License
|
||||||
|
|
||||||
|
Copyright (c) 2021, dengpw
|
||||||
|
All rights reserved.
|
||||||
|
|
||||||
|
Redistribution and use in source and binary forms, with or without
|
||||||
|
modification, are permitted provided that the following conditions are met:
|
||||||
|
|
||||||
|
1. Redistributions of source code must retain the above copyright notice, this
|
||||||
|
list of conditions and the following disclaimer.
|
||||||
|
|
||||||
|
2. Redistributions in binary form must reproduce the above copyright notice,
|
||||||
|
this list of conditions and the following disclaimer in the documentation
|
||||||
|
and/or other materials provided with the distribution.
|
||||||
|
|
||||||
|
3. Neither the name of the copyright holder nor the names of its
|
||||||
|
contributors may be used to endorse or promote products derived from
|
||||||
|
this software without specific prior written permission.
|
||||||
|
|
||||||
|
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||||
|
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||||
|
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||||
|
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
|
||||||
|
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||||
|
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||||
|
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||||
|
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||||
|
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||||
|
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
@ -0,0 +1,41 @@
|
|||||||
|
# hybrid_astar_planner
|
||||||
|
|
||||||
|
This is a global planner plugin of ROS move_base package.
|
||||||
|
|
||||||
|
## Introduction
|
||||||
|
Traditional robot navigation algorithms (such as the logistics storage robot used by Jingdong or Amazon)
|
||||||
|
mostly use a * algorithm or Dijkstra search algorithm to planning its trajectory after the map is gridded.
|
||||||
|
Most of them are differential models. Obviously, this kind of path is still difficult to realize for traditional
|
||||||
|
four-wheel vehicles whitch has nonholonomic constraint (vehicles with Ackerman steering mechanism).
|
||||||
|
So I designed a hybrid a * plug-in for ROS as my graduation project
|
||||||
|
|
||||||
|
## How to Use
|
||||||
|
|
||||||
|
### <a name="dependencies"></a>Dependencies
|
||||||
|
Install all dependencies
|
||||||
|
* [Open Motion Planning Library (OMPL)](http://ompl.kavrakilab.org/)
|
||||||
|
* [ros_map_server](http://wiki.ros.org/map_server)
|
||||||
|
|
||||||
|
### <a name="setup"></a><font color=Darkorange size=5 >Setup</font>
|
||||||
|
|
||||||
|
Run the following command to clone, build, and launch the package (requires a sources ROS environment):
|
||||||
|
|
||||||
|
```
|
||||||
|
sudo apt install libompl-dev \
|
||||||
|
&& mkdir -p ~/catkin_ws/src \
|
||||||
|
&& cd ~/catkin_ws/src \
|
||||||
|
&& git clone https://github.com/dengpw/hybrid_astar_planner.git \
|
||||||
|
&& cd .. \
|
||||||
|
&& catkin_make \
|
||||||
|
&& source devel/setup.bash \
|
||||||
|
&& rospack profile \
|
||||||
|
```
|
||||||
|
|
||||||
|
You can run the folling command to test whether the plug-in is install propely
|
||||||
|
```
|
||||||
|
&& roslaunch hybrid_astar_planner test.launch
|
||||||
|
```
|
||||||
|
It can run a static teajectory planner using hybrid A*
|
||||||
|
If everything run fine,you can use this plugin in ROS naviagation package by making a special declaration before starting the launch file:
|
||||||
|
< `param name="base_global_planner" value="global_planner/GlobalPlanner"` / >
|
||||||
|
< `param name="base_local_planner" value="teb_local_planner/TebLocalPlannerROS"` / >
|
||||||
@ -0,0 +1,7 @@
|
|||||||
|
<library path="lib/libhybrid_astar_planner">
|
||||||
|
<class name="hybrid_astar_planner/HybridAStarPlanner" type="hybrid_astar_planner::HybridAStarPlanner" base_class_type="nav_core::BaseGlobalPlanner">
|
||||||
|
<description>
|
||||||
|
A implementation of a based planner using Hybrid A*
|
||||||
|
</description>
|
||||||
|
</class>
|
||||||
|
</library>
|
||||||
@ -0,0 +1,90 @@
|
|||||||
|
/*********************************************************************
|
||||||
|
*
|
||||||
|
* Software License Agreement (BSD License)
|
||||||
|
*
|
||||||
|
* Copyright (c) 2016, Guan-Horng Liu.
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions
|
||||||
|
* are met:
|
||||||
|
*
|
||||||
|
* * Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
* * Redistributions in binary form must reproduce the above
|
||||||
|
* copyright notice, this list of conditions and the following
|
||||||
|
* disclaimer in the documentation and/or other materials provided
|
||||||
|
* with the distribution.
|
||||||
|
* * Neither the name of the the copyright holder nor the names of its
|
||||||
|
* contributors may be used to endorse or promote products derived
|
||||||
|
* from this software without specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
|
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||||
|
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||||
|
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||||
|
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||||
|
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||||
|
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||||
|
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||||
|
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||||
|
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
|
||||||
|
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||||
|
* POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*
|
||||||
|
* Author: Guan-Horng Liu
|
||||||
|
*********************************************************************/
|
||||||
|
|
||||||
|
#ifndef SPACES_REEDS_SHEPP_STATE_SPACE_
|
||||||
|
#define SPACES_REEDS_SHEPP_STATE_SPACE_
|
||||||
|
|
||||||
|
#include <boost/math/constants/constants.hpp>
|
||||||
|
#include <cassert>
|
||||||
|
|
||||||
|
class ReedsSheppStateSpace
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
|
||||||
|
/** \brief The Reeds-Shepp path segment types */
|
||||||
|
enum ReedsSheppPathSegmentType { RS_NOP=0, RS_LEFT=1, RS_STRAIGHT=2, RS_RIGHT=3 };
|
||||||
|
|
||||||
|
/** \brief Reeds-Shepp path types */
|
||||||
|
static const ReedsSheppPathSegmentType reedsSheppPathType[18][5];
|
||||||
|
|
||||||
|
/** \brief Complete description of a ReedsShepp path */
|
||||||
|
class ReedsSheppPath
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
ReedsSheppPath(const ReedsSheppPathSegmentType* type=reedsSheppPathType[0],
|
||||||
|
double t=std::numeric_limits<double>::max(), double u=0., double v=0.,
|
||||||
|
double w=0., double x=0.);
|
||||||
|
|
||||||
|
double length() const { return totalLength_; }
|
||||||
|
|
||||||
|
/** Path segment types */
|
||||||
|
const ReedsSheppPathSegmentType* type_;
|
||||||
|
/** Path segment lengths */
|
||||||
|
double length_[5];
|
||||||
|
/** Total length */
|
||||||
|
double totalLength_;
|
||||||
|
};
|
||||||
|
|
||||||
|
ReedsSheppStateSpace(double turningRadius) : rho_(turningRadius) {}
|
||||||
|
|
||||||
|
double distance(double q0[3], double q1[3]);
|
||||||
|
|
||||||
|
std::vector<ReedsSheppPathSegmentType> type(double q0[3], double q1[3]);
|
||||||
|
|
||||||
|
void sample(double q0[3], double q1[3], double step_size, double &length, std::vector<std::vector<double> > &points);
|
||||||
|
|
||||||
|
/** \brief Return the shortest Reeds-Shepp path from SE(2) state state1 to SE(2) state state2 */
|
||||||
|
ReedsSheppPath reedsShepp(double q0[3], double q1[3]);
|
||||||
|
|
||||||
|
protected:
|
||||||
|
void interpolate(double q0[3], ReedsSheppPath &path, double seg, double s[3]);
|
||||||
|
|
||||||
|
/** \brief Turning radius */
|
||||||
|
double rho_;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
||||||
@ -0,0 +1,32 @@
|
|||||||
|
#ifndef _ALGORITHM_H
|
||||||
|
#define _ALGORITHM_H
|
||||||
|
|
||||||
|
#include <ompl/base/spaces/ReedsSheppStateSpace.h>
|
||||||
|
#include <ompl/base/spaces/DubinsStateSpace.h>
|
||||||
|
#include <ompl/base/spaces/SE2StateSpace.h>
|
||||||
|
#include <ompl/base/State.h>
|
||||||
|
#include <ompl/base/State.h>
|
||||||
|
#include "node3d.h"
|
||||||
|
#include "node2d.h"
|
||||||
|
#include <boost/heap/binomial_heap.hpp>
|
||||||
|
#include <costmap_2d/costmap_2d.h>
|
||||||
|
#include <geometry_msgs/PoseStamped.h>
|
||||||
|
typedef ompl::base::SE2StateSpace::StateType State;
|
||||||
|
namespace hybrid_astar_planner {
|
||||||
|
// OPEN LIST AS BOOST IMPLEMENTATION
|
||||||
|
struct CompareNodes {
|
||||||
|
// Sorting 3D nodes by increasing C value - the total estimated cost
|
||||||
|
bool operator()(const Node3D* lhs, const Node3D* rhs) const {
|
||||||
|
return lhs->getF() > rhs->getF();
|
||||||
|
}
|
||||||
|
// Sorting 2D nodes by increasing C value - the total estimated cost
|
||||||
|
bool operator()(const Node2D* lhs, const Node2D* rhs) const {
|
||||||
|
return lhs->getF() > rhs->getF();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
Node3D* dubinsShot(Node3D& start, Node3D& goal, costmap_2d::Costmap2D* costmap);
|
||||||
|
Node3D* reedsSheppShot(Node3D& start, Node3D& goal, costmap_2d::Costmap2D* costmap);
|
||||||
|
void updateH(Node3D& start, const Node3D& goal, Node2D* nodes2D, float* dubinsLookup, int width, int height, float inspireAstar);
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif //end of algorithm.h
|
||||||
@ -0,0 +1,58 @@
|
|||||||
|
#ifndef _ASTAR_H
|
||||||
|
#define _ASTAR_H
|
||||||
|
|
||||||
|
#include <vector>
|
||||||
|
#include "algorithm.h"
|
||||||
|
#include "expander.h"
|
||||||
|
#include "node2d.h"
|
||||||
|
#include <visualization_msgs/MarkerArray.h>
|
||||||
|
#include <ros/publisher.h>
|
||||||
|
namespace hybrid_astar_planner {
|
||||||
|
class Index {
|
||||||
|
public:
|
||||||
|
Index(int a,float b) {
|
||||||
|
i = a;
|
||||||
|
cost = b;
|
||||||
|
}
|
||||||
|
int i;
|
||||||
|
float cost;
|
||||||
|
};
|
||||||
|
|
||||||
|
class astar : public Expander
|
||||||
|
{
|
||||||
|
|
||||||
|
public:
|
||||||
|
astar(std::string frame_id, costmap_2d::Costmap2D* _costmap)
|
||||||
|
:Expander(frame_id, _costmap) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Find the path between the start pose and goal pose
|
||||||
|
* @param start the reference of start pose
|
||||||
|
* @param goal the reference of goal pose
|
||||||
|
* @param cells_x the number of the cells of the costmap in x axis
|
||||||
|
* @param cells_y the number of the cells of the costmap in y axis
|
||||||
|
* @param plan the refrence of plan;
|
||||||
|
* @return true if a valid plan was found.
|
||||||
|
*/
|
||||||
|
bool calculatePath(const geometry_msgs::PoseStamped& start, const geometry_msgs::PoseStamped& goal,
|
||||||
|
int cells_x, int cells_y, std::vector<geometry_msgs::PoseStamped>& plan ,ros::Publisher& pub, visualization_msgs::MarkerArray& pathNodes );
|
||||||
|
~astar(){ }
|
||||||
|
private:
|
||||||
|
|
||||||
|
std::vector<Node2D*> gatAdjacentPoints(int cells_x, int cells_y, const unsigned char* charMap, Node2D* pathNode2D, Node2D *point );
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief transform the 2Dnode to geometry_msgs::PoseStamped
|
||||||
|
* @param node the ptr of node
|
||||||
|
* @param plan the refrence of plan
|
||||||
|
*/
|
||||||
|
void nodeToPlan(Node2D* node, std::vector<geometry_msgs::PoseStamped>& plan);
|
||||||
|
/* data */
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
}//end of namespace hybrid_astar_planner
|
||||||
|
|
||||||
|
#endif //the end of astar.h
|
||||||
@ -0,0 +1,35 @@
|
|||||||
|
#ifndef _EXPANDER_H
|
||||||
|
#define _EXPANDER_H
|
||||||
|
#include <vector>
|
||||||
|
#include <geometry_msgs/Point.h>
|
||||||
|
#include <costmap_2d/costmap_2d.h>
|
||||||
|
#include <geometry_msgs/PoseStamped.h>
|
||||||
|
#include <boost/heap/binomial_heap.hpp>
|
||||||
|
#include <ros/publisher.h>
|
||||||
|
#include <visualization_msgs/MarkerArray.h>
|
||||||
|
namespace hybrid_astar_planner {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief the base class of astar or hybrid astar planner
|
||||||
|
*/
|
||||||
|
class Expander
|
||||||
|
{
|
||||||
|
|
||||||
|
public:
|
||||||
|
Expander(std::string frame_id, costmap_2d::Costmap2D* _costmap)
|
||||||
|
:frame_id_(frame_id), costmap(_costmap) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual bool calculatePath(const geometry_msgs::PoseStamped& start, const geometry_msgs::PoseStamped& goal,
|
||||||
|
int cells_x, int cells_y, std::vector<geometry_msgs::PoseStamped>& plan ,ros::Publisher& pub, visualization_msgs::MarkerArray& pathNodes) = 0;
|
||||||
|
virtual ~Expander() {}
|
||||||
|
protected:
|
||||||
|
std::string frame_id_;
|
||||||
|
costmap_2d::Costmap2D* costmap;
|
||||||
|
/* data */
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
} //end of namespace hybrid_astar_planner
|
||||||
|
#endif //end of expander.h
|
||||||
@ -0,0 +1,89 @@
|
|||||||
|
#ifndef _HYBRID_ASTAR_H
|
||||||
|
#define _HYBRID_ASTAR_H
|
||||||
|
|
||||||
|
#include <vector>
|
||||||
|
#include "algorithm.h"
|
||||||
|
#include "expander.h"
|
||||||
|
#include "node3d.h"
|
||||||
|
#include <visualization_msgs/MarkerArray.h>
|
||||||
|
#include <ros/publisher.h>
|
||||||
|
// #define TEST
|
||||||
|
#define point_accuracy 0.5
|
||||||
|
#define theta_accuracy 2
|
||||||
|
namespace hybrid_astar_planner {
|
||||||
|
|
||||||
|
class hybridAstar : public Expander
|
||||||
|
{
|
||||||
|
|
||||||
|
public:
|
||||||
|
/**
|
||||||
|
* @brief Default constructor for the HybridAStarPlanner object
|
||||||
|
*/
|
||||||
|
hybridAstar(std::string frame_id, costmap_2d::Costmap2D* _costmap)
|
||||||
|
:Expander(frame_id, _costmap) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Find the path between the start pose and goal pose
|
||||||
|
* @param start the reference of start pose
|
||||||
|
* @param goal the reference of goal pose
|
||||||
|
* @param cells_x the number of the cells of the costmap in x axis
|
||||||
|
* @param cells_y the number of the cells of the costmap in y axis
|
||||||
|
* @param plan the refrence of plan;
|
||||||
|
* @return true if a valid plan was found.
|
||||||
|
*/
|
||||||
|
bool calculatePath(
|
||||||
|
const geometry_msgs::PoseStamped& start,
|
||||||
|
const geometry_msgs::PoseStamped& goal,
|
||||||
|
int cellsX, int cellsY, std::vector<geometry_msgs::PoseStamped>& plan,
|
||||||
|
ros::Publisher& pub, visualization_msgs::MarkerArray& pathNodes);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Default deconstructor for the HybridAStarPlanner object
|
||||||
|
*/
|
||||||
|
~hybridAstar(){ }
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Get the adjacent pose of a given pose
|
||||||
|
* @param cells_x the number of the cells of the costmap in x axis
|
||||||
|
* @param cells_y the number of the cells of the costmap in y axis
|
||||||
|
* @param charMap
|
||||||
|
*/
|
||||||
|
std::vector<Node3D*> gatAdjacentPoints(int dir, int cells_x, int cells_y, const unsigned char* charMap, Node3D *point);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief judge whether is reach the goal pose
|
||||||
|
* @param node the refrence of the node
|
||||||
|
* @param goalPose the goal of the planner
|
||||||
|
* @return true if reach the goal
|
||||||
|
*/
|
||||||
|
bool reachGoal(Node3D* node, Node3D* goalPose);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief get the index of node
|
||||||
|
* @param x the x position axis of the node
|
||||||
|
* @param y the y position axis of the node
|
||||||
|
* @param cells_x the scale of cells in x axis
|
||||||
|
* @param t the depth of the 3D nodes
|
||||||
|
* @return the index of node
|
||||||
|
*/
|
||||||
|
int calcIndix(float x, float y, int cells_x, float t);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief transform the 2Dnode to geometry_msgs::PoseStamped
|
||||||
|
* @param node the ptr of node
|
||||||
|
* @param plan the refrence of plan
|
||||||
|
*/
|
||||||
|
void nodeToPlan(Node3D* node, std::vector<geometry_msgs::PoseStamped>& plan);
|
||||||
|
std::unique_ptr<GridSearch> grid_a_star_heuristic_generator_;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
}//end of namespace hybrid_astar_planner
|
||||||
|
|
||||||
|
#endif //the end of astar.h
|
||||||
@ -0,0 +1,99 @@
|
|||||||
|
#ifndef _NODE2D_H
|
||||||
|
#define _NODE2D_H
|
||||||
|
|
||||||
|
#include <cmath>
|
||||||
|
#include <unordered_map>
|
||||||
|
#include <costmap_2d/costmap_2d.h>
|
||||||
|
namespace hybrid_astar_planner {
|
||||||
|
|
||||||
|
class Node2D
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
Node2D(): Node2D(0, 0, 999, 0, nullptr) {}
|
||||||
|
Node2D(int _x , int _y, float _g = 999, float _h = 0, Node2D* _perd = nullptr):
|
||||||
|
x(_x), y(_y), g(_g), h(_h), perd(_perd), o(false), c(false)
|
||||||
|
{
|
||||||
|
index = -1;
|
||||||
|
}
|
||||||
|
~Node2D(){}
|
||||||
|
|
||||||
|
void setX(int _x) { x = _x; }
|
||||||
|
void setY(int _y) { y = _y; }
|
||||||
|
void setCost(unsigned int C) { cost = C; }
|
||||||
|
void setG(float _g) { g = _g; }
|
||||||
|
void setH(float _h) { h = _h; }
|
||||||
|
void setClosedSet() { c = true; o = false; }
|
||||||
|
void setOpenSet() { o = true; }
|
||||||
|
void setPerd(Node2D* _perd) { perd = _perd; }
|
||||||
|
void setPerd_(std::shared_ptr<Node2D> _perd) { perd_node = _perd; }
|
||||||
|
int getX(void) { return x; }
|
||||||
|
int getY(void) { return y; }
|
||||||
|
float getF(void) const { return g + h; }
|
||||||
|
float calcG(Node2D const *partent);
|
||||||
|
float getG() const { return g; }
|
||||||
|
float calcH(Node2D const *goal);
|
||||||
|
int getindex(int width) { return (y * width + x); }
|
||||||
|
int getCost() {return cost;}
|
||||||
|
bool isOpenSet() { return o; }
|
||||||
|
bool isClosedSet() { return c; }
|
||||||
|
Node2D* getPerd() { return perd; }
|
||||||
|
void SetPathCost(const float path_cost) {
|
||||||
|
g = path_cost;
|
||||||
|
}
|
||||||
|
private:
|
||||||
|
// float cost_ = 999;
|
||||||
|
/// the x position
|
||||||
|
int x;
|
||||||
|
/// the y position
|
||||||
|
int y;
|
||||||
|
/// the cost of current node
|
||||||
|
unsigned int cost;
|
||||||
|
/// the cost-so-far
|
||||||
|
float g;
|
||||||
|
/// the cost-to-go
|
||||||
|
float h;
|
||||||
|
/// the index of the node in the 2D array
|
||||||
|
int index;
|
||||||
|
/// the open value
|
||||||
|
bool o;
|
||||||
|
/// the closed value
|
||||||
|
bool c;
|
||||||
|
/// the discovered value
|
||||||
|
bool d;
|
||||||
|
/// the predecessor pointer
|
||||||
|
Node2D* perd;
|
||||||
|
std::shared_ptr<Node2D> perd_node = nullptr;
|
||||||
|
};
|
||||||
|
|
||||||
|
class GridSearch {
|
||||||
|
public:
|
||||||
|
GridSearch()
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
~GridSearch()
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
std::vector<std::shared_ptr<Node2D>> getAdjacentPoints(int cells_x,
|
||||||
|
int cells_y, const unsigned char* charMap, std::shared_ptr<Node2D> point);
|
||||||
|
|
||||||
|
std::unordered_map<int, std::shared_ptr<Node2D>> GenerateDpMap(
|
||||||
|
const double goal_x, const double goal_y,
|
||||||
|
costmap_2d::Costmap2D* costmap);
|
||||||
|
// std::unordered_map<int, std::shared_ptr<Node2D>> dp_map_;
|
||||||
|
private:
|
||||||
|
|
||||||
|
// std::unordered_map<int, std::shared_ptr<Node2D>> dp_map_;
|
||||||
|
struct cmp {
|
||||||
|
// Sorting 3D nodes by increasing C value - the total estimated cost
|
||||||
|
bool operator()(const std::pair<int, double>& left,
|
||||||
|
const std::pair<int, double>& right) const {
|
||||||
|
return left.second >= right.second;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
}//end of namespace hybrid_astar_planner
|
||||||
|
|
||||||
|
#endif //end of node2d.h
|
||||||
@ -0,0 +1,87 @@
|
|||||||
|
#ifndef _NODE3D_H
|
||||||
|
#define _NODE3D_H
|
||||||
|
#include "constants.h"
|
||||||
|
#include <cmath>
|
||||||
|
namespace hybrid_astar_planner {
|
||||||
|
class Node3D
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
Node3D(): Node3D(0, 0, 0, 999, 0, false, nullptr) {}
|
||||||
|
Node3D(float _x , float _y, float t, float _g = 999, float _h = 0, bool _reverse = false, Node3D* _perd = nullptr):
|
||||||
|
x(_x), y(_y), g(_g), h(_h), reverse(_reverse), perd(_perd), o(false), c(false)
|
||||||
|
{
|
||||||
|
setT(t);
|
||||||
|
index = -1;
|
||||||
|
}
|
||||||
|
~Node3D(){}
|
||||||
|
|
||||||
|
void setX(float _x) { x = _x; }
|
||||||
|
void setY(float _y) { y = _y; }
|
||||||
|
void setCost(unsigned int C) { cost = C; }
|
||||||
|
void setT(float _t);
|
||||||
|
void setG(float _g) { g = _g; }
|
||||||
|
void setH(float _h) { h = _h; }
|
||||||
|
void setClosedSet() { c = true; o = false; }
|
||||||
|
void setOpenSet() { o = true; }
|
||||||
|
void setPerd(Node3D* _perd) { perd = _perd; }
|
||||||
|
void setReverse(bool r) { reverse = r; }
|
||||||
|
float getX(void) const { return x; }
|
||||||
|
float getY(void) const { return y; }
|
||||||
|
float getT(void) const { return t * Constants::deltaHeadingRad; }
|
||||||
|
float getTheta(void) const { return theta; }
|
||||||
|
float getF(void) const { return g + h; }
|
||||||
|
int getCost() {return cost;}
|
||||||
|
/**
|
||||||
|
* @brief caculate the G value of the node
|
||||||
|
* @return the G value of the node
|
||||||
|
* G值为状态空间中从初始节点到当前此节点的实际代价
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
float calcG(void);
|
||||||
|
float getG() const { return g; }
|
||||||
|
float calcH(Node3D const *goal);
|
||||||
|
int getindex(int width, int depth, float resolution, unsigned int dx, unsigned int dy) { this->index = (int(x/resolution + dx) * width + int(y/resolution + dy))*depth + t; return index;}//这里的resolution变动了
|
||||||
|
bool isOpenSet() { return o; }
|
||||||
|
bool isClosedSet() { return c; }
|
||||||
|
bool isReverse() { return reverse; }
|
||||||
|
Node3D* getPerd() { return perd; }
|
||||||
|
// RANGE CHECKING
|
||||||
|
/// Determines whether it is appropriate to find a analytical solution.
|
||||||
|
bool isInRange(const Node3D& goal) const;//检测是否可以分析方法找到解
|
||||||
|
|
||||||
|
// CUSTOM OPERATORS
|
||||||
|
/// Custom operator to compare nodes. Nodes are equal if their x and y position as well as heading is similar.
|
||||||
|
bool operator == (const Node3D& rhs) const;//位置相同且朝向相似则认为是同一节点
|
||||||
|
|
||||||
|
private:
|
||||||
|
/// the x position
|
||||||
|
float x;
|
||||||
|
/// the y position
|
||||||
|
float y;
|
||||||
|
/// the t position
|
||||||
|
int t;
|
||||||
|
/// the cost of this node in costmap
|
||||||
|
unsigned int cost;
|
||||||
|
/// the theta of this node
|
||||||
|
float theta;
|
||||||
|
/// the cost-so-far
|
||||||
|
float g;
|
||||||
|
/// the cost-to-go
|
||||||
|
float h;
|
||||||
|
/// the index of the node in the 3D array
|
||||||
|
int index;
|
||||||
|
/// the open value
|
||||||
|
bool o;
|
||||||
|
/// the closed value
|
||||||
|
bool c;
|
||||||
|
/// the discovered value
|
||||||
|
bool d;
|
||||||
|
/// the flag of node,Indicates whether the vehicle is in reverse
|
||||||
|
bool reverse;
|
||||||
|
/// the predecessor pointer
|
||||||
|
Node3D* perd;
|
||||||
|
};
|
||||||
|
|
||||||
|
}//end of namespace hybrid_astar_planner
|
||||||
|
|
||||||
|
#endif //end of node3d.h
|
||||||
@ -0,0 +1,142 @@
|
|||||||
|
#ifndef _PLANNERCORE_H
|
||||||
|
#define _PLANNERCORE_H
|
||||||
|
/*********************************************************************
|
||||||
|
*
|
||||||
|
* BSD 3-Clause License
|
||||||
|
*
|
||||||
|
* Copyright (c) 2021, dengpw
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions
|
||||||
|
* are met:
|
||||||
|
*
|
||||||
|
* 1 Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
* 2 Redistributions in binary form must reproduce the above
|
||||||
|
* copyright notice, this list of conditions and the following
|
||||||
|
* disclaimer in the documentation and/or other materials provided
|
||||||
|
* with the distribution.
|
||||||
|
* 3 Neither the name of the copyright holder nor the names of its
|
||||||
|
* contributors may be used to endorse or promote products derived from
|
||||||
|
* this software without specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
|
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||||
|
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||||
|
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||||
|
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||||
|
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||||
|
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||||
|
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||||
|
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||||
|
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
|
||||||
|
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||||
|
* POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*
|
||||||
|
*********************************************************************/
|
||||||
|
// #define POT_HIGH 1.0e10 // unassigned cell potential
|
||||||
|
#include <vector>
|
||||||
|
#include <nav_msgs/GetPlan.h>
|
||||||
|
#include <pluginlib/class_list_macros.h>
|
||||||
|
#include <nav_core/base_global_planner.h>
|
||||||
|
#include <visualization_msgs/MarkerArray.h>
|
||||||
|
#include "node2d.h"
|
||||||
|
#include "node3d.h"
|
||||||
|
namespace hybrid_astar_planner {
|
||||||
|
//类插件实现的多态的时候,若在头文件中定义了函数,那么就必须有这个函数的实现,否则会报错!!!
|
||||||
|
/**
|
||||||
|
* @class HybridAStarPlanner
|
||||||
|
* @brief Provides a ROS wrapper for the HybridAStarPlanner planner which runs a fast, interpolated navigation function on a costmap.
|
||||||
|
*/
|
||||||
|
|
||||||
|
class HybridAStarPlanner : public nav_core::BaseGlobalPlanner {
|
||||||
|
public:
|
||||||
|
/**
|
||||||
|
* @brief Default constructor for the HybridAStarPlanner object
|
||||||
|
*/
|
||||||
|
HybridAStarPlanner();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Default deconstructor for the HybridAStarPlanner object
|
||||||
|
*/
|
||||||
|
~HybridAStarPlanner();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Initialization function for the HybridAStarPlanner
|
||||||
|
* @param name The name of this planner
|
||||||
|
* @param costmap_ros A pointer to the ROS wrapper of the costmap to use for planning.And the costmap is get from the topic name /map
|
||||||
|
*/
|
||||||
|
void initialize(std::string name, costmap_2d::Costmap2DROS* costmap_ros);
|
||||||
|
|
||||||
|
void initialize(std::string name, costmap_2d::Costmap2D* costmap, std::string frame_id);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Given a goal pose in the world, compute a plan
|
||||||
|
* @param start The start pose
|
||||||
|
* @param goal The goal pose
|
||||||
|
* @param plan The plan... filled by the planner
|
||||||
|
* @return True if a valid plan was found, false otherwise
|
||||||
|
*/
|
||||||
|
bool makePlan(const geometry_msgs::PoseStamped& start, const geometry_msgs::PoseStamped& goal,
|
||||||
|
std::vector<geometry_msgs::PoseStamped>& plan);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Publish the plan to RVIZ
|
||||||
|
* @param path the vector contain the path
|
||||||
|
*/
|
||||||
|
void publishPlan(const std::vector<geometry_msgs::PoseStamped>& path);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Publish the path node to RVIZ
|
||||||
|
* @param path the vector contain the path
|
||||||
|
*/
|
||||||
|
void publishPathNodes(const std::vector<geometry_msgs::PoseStamped>& path);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief The call back function of makeplan service
|
||||||
|
* @param req
|
||||||
|
* @param resp the plan the planner made
|
||||||
|
* @return True if a valid plan was found, false otherwise
|
||||||
|
*/
|
||||||
|
bool makePlanService(nav_msgs::GetPlan::Request& req, nav_msgs::GetPlan::Response& resp);
|
||||||
|
protected:
|
||||||
|
|
||||||
|
bool initialized_;
|
||||||
|
std::string frame_id_;
|
||||||
|
ros::Publisher plan_pub_;
|
||||||
|
ros::Publisher path_vehicles_pub_;//用于在路径上发布车子位置
|
||||||
|
costmap_2d::Costmap2D* costmap;
|
||||||
|
|
||||||
|
private:
|
||||||
|
/**
|
||||||
|
* @brief Clarn the visualization_msgs::Marker 清理可视化信息的标记点
|
||||||
|
*/
|
||||||
|
void clearPathNodes(void);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Check whethe the start pose is available
|
||||||
|
* @param start A reference to start pose
|
||||||
|
* @return True if the start pose is available
|
||||||
|
*/
|
||||||
|
bool checkStartPose(const geometry_msgs::PoseStamped &start);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Check whethe the goal pose is available
|
||||||
|
* @param goal A reference to goal pose
|
||||||
|
* @return True if the goal pose is available
|
||||||
|
*/
|
||||||
|
bool checkgoalPose(const geometry_msgs::PoseStamped &goal);
|
||||||
|
visualization_msgs::MarkerArray pathNodes;//节点数据结构,用于可视化
|
||||||
|
double resolution;
|
||||||
|
ros::ServiceServer make_plan_srv_;
|
||||||
|
bool use_hybrid_astar;
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
} //end namespace hybrid_astar_planner
|
||||||
|
|
||||||
|
#endif
|
||||||
@ -0,0 +1,10 @@
|
|||||||
|
#ifndef _VISUALIZE_H
|
||||||
|
#define _VISUALIZE_H
|
||||||
|
#include "node3d.h"
|
||||||
|
#include <visualization_msgs/MarkerArray.h>
|
||||||
|
#include <ros/publisher.h>
|
||||||
|
namespace hybrid_astar_planner {
|
||||||
|
void publishSearchNodes(Node3D node,ros::Publisher& pub, visualization_msgs::MarkerArray& pathNodes, int i);
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif//end of visualize,h
|
||||||
@ -0,0 +1,49 @@
|
|||||||
|
<?xml version="1.0"?>
|
||||||
|
<package format="2">
|
||||||
|
<name>hybrid_astar_planner</name>
|
||||||
|
<version>1.1.2</version>
|
||||||
|
<description>A hybrid_astar_planner package for move_base</description>
|
||||||
|
<maintainer email="dengpw@qq.com">dengpw</maintainer>
|
||||||
|
|
||||||
|
|
||||||
|
<!-- One license tag required, multiple allowed, one license per tag -->
|
||||||
|
<!-- Commonly used license strings: -->
|
||||||
|
<!-- BSD, MIT, Boost Software License, GPLv2, GPLv3, LGPLv2.1, LGPLv3 -->
|
||||||
|
<license>BSD</license>
|
||||||
|
|
||||||
|
|
||||||
|
<!-- Url tags are optional, but multiple are allowed, one per tag -->
|
||||||
|
<!-- Optional attribute type can be: website, bugtracker, or repository -->
|
||||||
|
|
||||||
|
|
||||||
|
<buildtool_depend>catkin</buildtool_depend>
|
||||||
|
<build_depend>pluginlib</build_depend>
|
||||||
|
<build_export_depend>pluginlib</build_export_depend>
|
||||||
|
<exec_depend>pluginlib</exec_depend>
|
||||||
|
|
||||||
|
|
||||||
|
<build_depend>nav_core</build_depend>
|
||||||
|
<build_depend>roscpp</build_depend>
|
||||||
|
<build_depend>rospy</build_depend>
|
||||||
|
<build_depend>std_msgs</build_depend>
|
||||||
|
<build_depend>visualization_msgs</build_depend>
|
||||||
|
<build_depend>tf</build_depend>
|
||||||
|
<build_depend>ompl</build_depend>
|
||||||
|
<build_depend>map_server</build_depend>
|
||||||
|
|
||||||
|
<exec_depend>nav_core</exec_depend>
|
||||||
|
<exec_depend>roscpp</exec_depend>
|
||||||
|
<exec_depend>rospy</exec_depend>
|
||||||
|
<exec_depend>std_msgs</exec_depend>
|
||||||
|
<exec_depend>visualization_msgs</exec_depend>
|
||||||
|
<exec_depend>tf</exec_depend>
|
||||||
|
<exec_depend>ompl</exec_depend>
|
||||||
|
<exec_depend>map_server</exec_depend>
|
||||||
|
|
||||||
|
<!-- The export tag contains other, unspecified, tags -->
|
||||||
|
<export>
|
||||||
|
<nav_core plugin="${prefix}/hybrid_astar_planner_plugin.xml" />
|
||||||
|
</export>
|
||||||
|
|
||||||
|
|
||||||
|
</package>
|
||||||
@ -0,0 +1,623 @@
|
|||||||
|
/*********************************************************************
|
||||||
|
*
|
||||||
|
* Software License Agreement (BSD License)
|
||||||
|
*
|
||||||
|
* Copyright (c) 2016, Guan-Horng Liu.
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions
|
||||||
|
* are met:
|
||||||
|
*
|
||||||
|
* * Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
* * Redistributions in binary form must reproduce the above
|
||||||
|
* copyright notice, this list of conditions and the following
|
||||||
|
* disclaimer in the documentation and/or other materials provided
|
||||||
|
* with the distribution.
|
||||||
|
* * Neither the name of the the copyright holder nor the names of its
|
||||||
|
* contributors may be used to endorse or promote products derived
|
||||||
|
* from this software without specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
|
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||||
|
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||||
|
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||||
|
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||||
|
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||||
|
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||||
|
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||||
|
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||||
|
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
|
||||||
|
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||||
|
* POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*
|
||||||
|
* Author: Guan-Horng Liu
|
||||||
|
*********************************************************************/
|
||||||
|
|
||||||
|
|
||||||
|
#include "ReedsShepp.h"
|
||||||
|
#include <boost/math/constants/constants.hpp>
|
||||||
|
|
||||||
|
|
||||||
|
namespace
|
||||||
|
{
|
||||||
|
// The comments, variable names, etc. use the nomenclature from the Reeds & Shepp paper.
|
||||||
|
|
||||||
|
const double pi = boost::math::constants::pi<double>();
|
||||||
|
const double twopi = 2. * pi;
|
||||||
|
const double RS_EPS = 1e-6;
|
||||||
|
const double ZERO = 10*std::numeric_limits<double>::epsilon();
|
||||||
|
|
||||||
|
inline double mod2pi(double x)
|
||||||
|
{
|
||||||
|
double v = fmod(x, twopi);
|
||||||
|
if (v < -pi)
|
||||||
|
v += twopi;
|
||||||
|
else
|
||||||
|
if (v > pi)
|
||||||
|
v -= twopi;
|
||||||
|
return v;
|
||||||
|
}
|
||||||
|
inline void polar(double x, double y, double &r, double &theta)
|
||||||
|
{
|
||||||
|
r = sqrt(x*x + y*y);
|
||||||
|
theta = atan2(y, x);
|
||||||
|
}
|
||||||
|
inline void tauOmega(double u, double v, double xi, double eta, double phi, double &tau, double &omega)
|
||||||
|
{
|
||||||
|
double delta = mod2pi(u-v), A = sin(u) - sin(delta), B = cos(u) - cos(delta) - 1.;
|
||||||
|
double t1 = atan2(eta*A - xi*B, xi*A + eta*B), t2 = 2. * (cos(delta) - cos(v) - cos(u)) + 3;
|
||||||
|
tau = (t2<0) ? mod2pi(t1+pi) : mod2pi(t1);
|
||||||
|
omega = mod2pi(tau - u + v - phi) ;
|
||||||
|
}
|
||||||
|
|
||||||
|
// formula 8.1 in Reeds-Shepp paper
|
||||||
|
inline bool LpSpLp(double x, double y, double phi, double &t, double &u, double &v)
|
||||||
|
{
|
||||||
|
polar(x - sin(phi), y - 1. + cos(phi), u, t);
|
||||||
|
if (t >= -ZERO)
|
||||||
|
{
|
||||||
|
v = mod2pi(phi - t);
|
||||||
|
if (v >= -ZERO)
|
||||||
|
{
|
||||||
|
assert(fabs(u*cos(t) + sin(phi) - x) < RS_EPS);
|
||||||
|
assert(fabs(u*sin(t) - cos(phi) + 1 - y) < RS_EPS);
|
||||||
|
assert(fabs(mod2pi(t+v - phi)) < RS_EPS);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
// formula 8.2
|
||||||
|
inline bool LpSpRp(double x, double y, double phi, double &t, double &u, double &v)
|
||||||
|
{
|
||||||
|
double t1, u1;
|
||||||
|
polar(x + sin(phi), y - 1. - cos(phi), u1, t1);
|
||||||
|
u1 = u1*u1;
|
||||||
|
if (u1 >= 4.)
|
||||||
|
{
|
||||||
|
double theta;
|
||||||
|
u = sqrt(u1 - 4.);
|
||||||
|
theta = atan2(2., u);
|
||||||
|
t = mod2pi(t1 + theta);
|
||||||
|
v = mod2pi(t - phi);
|
||||||
|
assert(fabs(2*sin(t) + u*cos(t) - sin(phi) - x) < RS_EPS);
|
||||||
|
assert(fabs(-2*cos(t) + u*sin(t) + cos(phi) + 1 - y) < RS_EPS);
|
||||||
|
assert(fabs(mod2pi(t-v - phi)) < RS_EPS);
|
||||||
|
return t>=-ZERO && v>=-ZERO;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
void CSC(double x, double y, double phi, ReedsSheppStateSpace::ReedsSheppPath &path)
|
||||||
|
{
|
||||||
|
double t, u, v, Lmin = path.length(), L;
|
||||||
|
if (LpSpLp(x, y, phi, t, u, v) && Lmin > (L = fabs(t) + fabs(u) + fabs(v)))
|
||||||
|
{
|
||||||
|
path = ReedsSheppStateSpace::ReedsSheppPath(
|
||||||
|
ReedsSheppStateSpace::reedsSheppPathType[14], t, u, v);
|
||||||
|
Lmin = L;
|
||||||
|
}
|
||||||
|
if (LpSpLp(-x, y, -phi, t, u, v) && Lmin > (L = fabs(t) + fabs(u) + fabs(v))) // timeflip
|
||||||
|
{
|
||||||
|
path = ReedsSheppStateSpace::ReedsSheppPath(
|
||||||
|
ReedsSheppStateSpace::reedsSheppPathType[14], -t, -u, -v);
|
||||||
|
Lmin = L;
|
||||||
|
}
|
||||||
|
if (LpSpLp(x, -y, -phi, t, u, v) && Lmin > (L = fabs(t) + fabs(u) + fabs(v))) // reflect
|
||||||
|
{
|
||||||
|
path = ReedsSheppStateSpace::ReedsSheppPath(
|
||||||
|
ReedsSheppStateSpace::reedsSheppPathType[15], t, u, v);
|
||||||
|
Lmin = L;
|
||||||
|
}
|
||||||
|
if (LpSpLp(-x, -y, phi, t, u, v) && Lmin > (L = fabs(t) + fabs(u) + fabs(v))) // timeflip + reflect
|
||||||
|
{
|
||||||
|
path = ReedsSheppStateSpace::ReedsSheppPath(
|
||||||
|
ReedsSheppStateSpace::reedsSheppPathType[15], -t, -u, -v);
|
||||||
|
Lmin = L;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (LpSpRp(x, y, phi, t, u, v) && Lmin > (L = fabs(t) + fabs(u) + fabs(v)))
|
||||||
|
{
|
||||||
|
path = ReedsSheppStateSpace::ReedsSheppPath(
|
||||||
|
ReedsSheppStateSpace::reedsSheppPathType[12], t, u, v);
|
||||||
|
Lmin = L;
|
||||||
|
}
|
||||||
|
if (LpSpRp(-x, y, -phi, t, u, v) && Lmin > (L = fabs(t) + fabs(u) + fabs(v))) // timeflip
|
||||||
|
{
|
||||||
|
path = ReedsSheppStateSpace::ReedsSheppPath(
|
||||||
|
ReedsSheppStateSpace::reedsSheppPathType[12], -t, -u, -v);
|
||||||
|
Lmin = L;
|
||||||
|
}
|
||||||
|
if (LpSpRp(x, -y, -phi, t, u, v) && Lmin > (L = fabs(t) + fabs(u) + fabs(v))) // reflect
|
||||||
|
{
|
||||||
|
path = ReedsSheppStateSpace::ReedsSheppPath(
|
||||||
|
ReedsSheppStateSpace::reedsSheppPathType[13], t, u, v);
|
||||||
|
Lmin = L;
|
||||||
|
}
|
||||||
|
if (LpSpRp(-x, -y, phi, t, u, v) && Lmin > (L = fabs(t) + fabs(u) + fabs(v))) // timeflip + reflect
|
||||||
|
path = ReedsSheppStateSpace::ReedsSheppPath(
|
||||||
|
ReedsSheppStateSpace::reedsSheppPathType[13], -t, -u, -v);
|
||||||
|
}
|
||||||
|
// formula 8.3 / 8.4 *** TYPO IN PAPER ***
|
||||||
|
inline bool LpRmL(double x, double y, double phi, double &t, double &u, double &v)
|
||||||
|
{
|
||||||
|
double xi = x - sin(phi), eta = y - 1. + cos(phi), u1, theta;
|
||||||
|
polar(xi, eta, u1, theta);
|
||||||
|
if (u1 <= 4.)
|
||||||
|
{
|
||||||
|
u = -2.*asin(.25 * u1);
|
||||||
|
t = mod2pi(theta + .5 * u + pi);
|
||||||
|
v = mod2pi(phi - t + u);
|
||||||
|
assert(fabs(2*(sin(t) - sin(t-u)) + sin(phi) - x) < RS_EPS);
|
||||||
|
assert(fabs(2*(-cos(t) + cos(t-u)) - cos(phi) + 1 - y) < RS_EPS);
|
||||||
|
assert(fabs(mod2pi(t-u+v - phi)) < RS_EPS);
|
||||||
|
return t>=-ZERO && u<=ZERO;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
void CCC(double x, double y, double phi, ReedsSheppStateSpace::ReedsSheppPath &path)
|
||||||
|
{
|
||||||
|
double t, u, v, Lmin = path.length(), L;
|
||||||
|
if (LpRmL(x, y, phi, t, u, v) && Lmin > (L = fabs(t) + fabs(u) + fabs(v)))
|
||||||
|
{
|
||||||
|
path = ReedsSheppStateSpace::ReedsSheppPath(
|
||||||
|
ReedsSheppStateSpace::reedsSheppPathType[0], t, u, v);
|
||||||
|
Lmin = L;
|
||||||
|
}
|
||||||
|
if (LpRmL(-x, y, -phi, t, u, v) && Lmin > (L = fabs(t) + fabs(u) + fabs(v))) // timeflip
|
||||||
|
{
|
||||||
|
path = ReedsSheppStateSpace::ReedsSheppPath(
|
||||||
|
ReedsSheppStateSpace::reedsSheppPathType[0], -t, -u, -v);
|
||||||
|
Lmin = L;
|
||||||
|
}
|
||||||
|
if (LpRmL(x, -y, -phi, t, u, v) && Lmin > (L = fabs(t) + fabs(u) + fabs(v))) // reflect
|
||||||
|
{
|
||||||
|
path = ReedsSheppStateSpace::ReedsSheppPath(
|
||||||
|
ReedsSheppStateSpace::reedsSheppPathType[1], t, u, v);
|
||||||
|
Lmin = L;
|
||||||
|
}
|
||||||
|
if (LpRmL(-x, -y, phi, t, u, v) && Lmin > (L = fabs(t) + fabs(u) + fabs(v))) // timeflip + reflect
|
||||||
|
{
|
||||||
|
path = ReedsSheppStateSpace::ReedsSheppPath(
|
||||||
|
ReedsSheppStateSpace::reedsSheppPathType[1], -t, -u, -v);
|
||||||
|
Lmin = L;
|
||||||
|
}
|
||||||
|
|
||||||
|
// backwards
|
||||||
|
double xb = x*cos(phi) + y*sin(phi), yb = x*sin(phi) - y*cos(phi);
|
||||||
|
if (LpRmL(xb, yb, phi, t, u, v) && Lmin > (L = fabs(t) + fabs(u) + fabs(v)))
|
||||||
|
{
|
||||||
|
path = ReedsSheppStateSpace::ReedsSheppPath(
|
||||||
|
ReedsSheppStateSpace::reedsSheppPathType[0], v, u, t);
|
||||||
|
Lmin = L;
|
||||||
|
}
|
||||||
|
if (LpRmL(-xb, yb, -phi, t, u, v) && Lmin > (L = fabs(t) + fabs(u) + fabs(v))) // timeflip
|
||||||
|
{
|
||||||
|
path = ReedsSheppStateSpace::ReedsSheppPath(
|
||||||
|
ReedsSheppStateSpace::reedsSheppPathType[0], -v, -u, -t);
|
||||||
|
Lmin = L;
|
||||||
|
}
|
||||||
|
if (LpRmL(xb, -yb, -phi, t, u, v) && Lmin > (L = fabs(t) + fabs(u) + fabs(v))) // reflect
|
||||||
|
{
|
||||||
|
path = ReedsSheppStateSpace::ReedsSheppPath(
|
||||||
|
ReedsSheppStateSpace::reedsSheppPathType[1], v, u, t);
|
||||||
|
Lmin = L;
|
||||||
|
}
|
||||||
|
if (LpRmL(-xb, -yb, phi, t, u, v) && Lmin > (L = fabs(t) + fabs(u) + fabs(v))) // timeflip + reflect
|
||||||
|
path = ReedsSheppStateSpace::ReedsSheppPath(
|
||||||
|
ReedsSheppStateSpace::reedsSheppPathType[1], -v, -u, -t);
|
||||||
|
}
|
||||||
|
// formula 8.7
|
||||||
|
inline bool LpRupLumRm(double x, double y, double phi, double &t, double &u, double &v)
|
||||||
|
{
|
||||||
|
double xi = x + sin(phi), eta = y - 1. - cos(phi), rho = .25 * (2. + sqrt(xi*xi + eta*eta));
|
||||||
|
if (rho <= 1.)
|
||||||
|
{
|
||||||
|
u = acos(rho);
|
||||||
|
tauOmega(u, -u, xi, eta, phi, t, v);
|
||||||
|
assert(fabs(2*(sin(t)-sin(t-u)+sin(t-2*u))-sin(phi) - x) < RS_EPS);
|
||||||
|
assert(fabs(2*(-cos(t)+cos(t-u)-cos(t-2*u))+cos(phi)+1 - y) < RS_EPS);
|
||||||
|
assert(fabs(mod2pi(t-2*u-v - phi)) < RS_EPS);
|
||||||
|
return t>=-ZERO && v<=ZERO;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
// formula 8.8
|
||||||
|
inline bool LpRumLumRp(double x, double y, double phi, double &t, double &u, double &v)
|
||||||
|
{
|
||||||
|
double xi = x + sin(phi), eta = y - 1. - cos(phi), rho = (20. - xi*xi - eta*eta) / 16.;
|
||||||
|
if (rho>=0 && rho<=1)
|
||||||
|
{
|
||||||
|
u = -acos(rho);
|
||||||
|
if (u >= -.5 * pi)
|
||||||
|
{
|
||||||
|
tauOmega(u, u, xi, eta, phi, t, v);
|
||||||
|
assert(fabs(4*sin(t)-2*sin(t-u)-sin(phi) - x) < RS_EPS);
|
||||||
|
assert(fabs(-4*cos(t)+2*cos(t-u)+cos(phi)+1 - y) < RS_EPS);
|
||||||
|
assert(fabs(mod2pi(t-v - phi)) < RS_EPS);
|
||||||
|
return t>=-ZERO && v>=-ZERO;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
void CCCC(double x, double y, double phi, ReedsSheppStateSpace::ReedsSheppPath &path)
|
||||||
|
{
|
||||||
|
double t, u, v, Lmin = path.length(), L;
|
||||||
|
if (LpRupLumRm(x, y, phi, t, u, v) && Lmin > (L = fabs(t) + 2.*fabs(u) + fabs(v)))
|
||||||
|
{
|
||||||
|
path = ReedsSheppStateSpace::ReedsSheppPath(
|
||||||
|
ReedsSheppStateSpace::reedsSheppPathType[2], t, u, -u, v);
|
||||||
|
Lmin = L;
|
||||||
|
}
|
||||||
|
if (LpRupLumRm(-x, y, -phi, t, u, v) && Lmin > (L = fabs(t) + 2.*fabs(u) + fabs(v))) // timeflip
|
||||||
|
{
|
||||||
|
path = ReedsSheppStateSpace::ReedsSheppPath(
|
||||||
|
ReedsSheppStateSpace::reedsSheppPathType[2], -t, -u, u, -v);
|
||||||
|
Lmin = L;
|
||||||
|
}
|
||||||
|
if (LpRupLumRm(x, -y, -phi, t, u, v) && Lmin > (L = fabs(t) + 2.*fabs(u) + fabs(v))) // reflect
|
||||||
|
{
|
||||||
|
path = ReedsSheppStateSpace::ReedsSheppPath(
|
||||||
|
ReedsSheppStateSpace::reedsSheppPathType[3], t, u, -u, v);
|
||||||
|
Lmin = L;
|
||||||
|
}
|
||||||
|
if (LpRupLumRm(-x, -y, phi, t, u, v) && Lmin > (L = fabs(t) + 2.*fabs(u) + fabs(v))) // timeflip + reflect
|
||||||
|
{
|
||||||
|
path = ReedsSheppStateSpace::ReedsSheppPath(
|
||||||
|
ReedsSheppStateSpace::reedsSheppPathType[3], -t, -u, u, -v);
|
||||||
|
Lmin = L;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (LpRumLumRp(x, y, phi, t, u, v) && Lmin > (L = fabs(t) + 2.*fabs(u) + fabs(v)))
|
||||||
|
{
|
||||||
|
path = ReedsSheppStateSpace::ReedsSheppPath(
|
||||||
|
ReedsSheppStateSpace::reedsSheppPathType[2], t, u, u, v);
|
||||||
|
Lmin = L;
|
||||||
|
}
|
||||||
|
if (LpRumLumRp(-x, y, -phi, t, u, v) && Lmin > (L = fabs(t) + 2.*fabs(u) + fabs(v))) // timeflip
|
||||||
|
{
|
||||||
|
path = ReedsSheppStateSpace::ReedsSheppPath(
|
||||||
|
ReedsSheppStateSpace::reedsSheppPathType[2], -t, -u, -u, -v);
|
||||||
|
Lmin = L;
|
||||||
|
}
|
||||||
|
if (LpRumLumRp(x, -y, -phi, t, u, v) && Lmin > (L = fabs(t) + 2.*fabs(u) + fabs(v))) // reflect
|
||||||
|
{
|
||||||
|
path = ReedsSheppStateSpace::ReedsSheppPath(
|
||||||
|
ReedsSheppStateSpace::reedsSheppPathType[3], t, u, u, v);
|
||||||
|
Lmin = L;
|
||||||
|
}
|
||||||
|
if (LpRumLumRp(-x, -y, phi, t, u, v) && Lmin > (L = fabs(t) + 2.*fabs(u) + fabs(v))) // timeflip + reflect
|
||||||
|
path = ReedsSheppStateSpace::ReedsSheppPath(
|
||||||
|
ReedsSheppStateSpace::reedsSheppPathType[3], -t, -u, -u, -v);
|
||||||
|
}
|
||||||
|
// formula 8.9
|
||||||
|
inline bool LpRmSmLm(double x, double y, double phi, double &t, double &u, double &v)
|
||||||
|
{
|
||||||
|
double xi = x - sin(phi), eta = y - 1. + cos(phi), rho, theta;
|
||||||
|
polar(xi, eta, rho, theta);
|
||||||
|
if (rho >= 2.)
|
||||||
|
{
|
||||||
|
double r = sqrt(rho*rho - 4.);
|
||||||
|
u = 2. - r;
|
||||||
|
t = mod2pi(theta + atan2(r, -2.));
|
||||||
|
v = mod2pi(phi - .5*pi - t);
|
||||||
|
assert(fabs(2*(sin(t)-cos(t))-u*sin(t)+sin(phi) - x) < RS_EPS);
|
||||||
|
assert(fabs(-2*(sin(t)+cos(t))+u*cos(t)-cos(phi)+1 - y) < RS_EPS);
|
||||||
|
assert(fabs(mod2pi(t+pi/2+v-phi)) < RS_EPS);
|
||||||
|
return t>=-ZERO && u<=ZERO && v<=ZERO;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
// formula 8.10
|
||||||
|
inline bool LpRmSmRm(double x, double y, double phi, double &t, double &u, double &v)
|
||||||
|
{
|
||||||
|
double xi = x + sin(phi), eta = y - 1. - cos(phi), rho, theta;
|
||||||
|
polar(-eta, xi, rho, theta);
|
||||||
|
if (rho >= 2.)
|
||||||
|
{
|
||||||
|
t = theta;
|
||||||
|
u = 2. - rho;
|
||||||
|
v = mod2pi(t + .5*pi - phi);
|
||||||
|
assert(fabs(2*sin(t)-cos(t-v)-u*sin(t) - x) < RS_EPS);
|
||||||
|
assert(fabs(-2*cos(t)-sin(t-v)+u*cos(t)+1 - y) < RS_EPS);
|
||||||
|
assert(fabs(mod2pi(t+pi/2-v-phi)) < RS_EPS);
|
||||||
|
return t>=-ZERO && u<=ZERO && v<=ZERO;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
void CCSC(double x, double y, double phi, ReedsSheppStateSpace::ReedsSheppPath &path)
|
||||||
|
{
|
||||||
|
double t, u, v, Lmin = path.length() - .5*pi, L;
|
||||||
|
if (LpRmSmLm(x, y, phi, t, u, v) && Lmin > (L = fabs(t) + fabs(u) + fabs(v)))
|
||||||
|
{
|
||||||
|
path = ReedsSheppStateSpace::ReedsSheppPath(
|
||||||
|
ReedsSheppStateSpace::reedsSheppPathType[4], t, -.5*pi, u, v);
|
||||||
|
Lmin = L;
|
||||||
|
}
|
||||||
|
if (LpRmSmLm(-x, y, -phi, t, u, v) && Lmin > (L = fabs(t) + fabs(u) + fabs(v))) // timeflip
|
||||||
|
{
|
||||||
|
path = ReedsSheppStateSpace::ReedsSheppPath(
|
||||||
|
ReedsSheppStateSpace::reedsSheppPathType[4], -t, .5*pi, -u, -v);
|
||||||
|
Lmin = L;
|
||||||
|
}
|
||||||
|
if (LpRmSmLm(x, -y, -phi, t, u, v) && Lmin > (L = fabs(t) + fabs(u) + fabs(v))) // reflect
|
||||||
|
{
|
||||||
|
path = ReedsSheppStateSpace::ReedsSheppPath(
|
||||||
|
ReedsSheppStateSpace::reedsSheppPathType[5], t, -.5*pi, u, v);
|
||||||
|
Lmin = L;
|
||||||
|
}
|
||||||
|
if (LpRmSmLm(-x, -y, phi, t, u, v) && Lmin > (L = fabs(t) + fabs(u) + fabs(v))) // timeflip + reflect
|
||||||
|
{
|
||||||
|
path = ReedsSheppStateSpace::ReedsSheppPath(
|
||||||
|
ReedsSheppStateSpace::reedsSheppPathType[5], -t, .5*pi, -u, -v);
|
||||||
|
Lmin = L;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (LpRmSmRm(x, y, phi, t, u, v) && Lmin > (L = fabs(t) + fabs(u) + fabs(v)))
|
||||||
|
{
|
||||||
|
path = ReedsSheppStateSpace::ReedsSheppPath(
|
||||||
|
ReedsSheppStateSpace::reedsSheppPathType[8], t, -.5*pi, u, v);
|
||||||
|
Lmin = L;
|
||||||
|
}
|
||||||
|
if (LpRmSmRm(-x, y, -phi, t, u, v) && Lmin > (L = fabs(t) + fabs(u) + fabs(v))) // timeflip
|
||||||
|
{
|
||||||
|
path = ReedsSheppStateSpace::ReedsSheppPath(
|
||||||
|
ReedsSheppStateSpace::reedsSheppPathType[8], -t, .5*pi, -u, -v);
|
||||||
|
Lmin = L;
|
||||||
|
}
|
||||||
|
if (LpRmSmRm(x, -y, -phi, t, u, v) && Lmin > (L = fabs(t) + fabs(u) + fabs(v))) // reflect
|
||||||
|
{
|
||||||
|
path = ReedsSheppStateSpace::ReedsSheppPath(
|
||||||
|
ReedsSheppStateSpace::reedsSheppPathType[9], t, -.5*pi, u, v);
|
||||||
|
Lmin = L;
|
||||||
|
}
|
||||||
|
if (LpRmSmRm(-x, -y, phi, t, u, v) && Lmin > (L = fabs(t) + fabs(u) + fabs(v))) // timeflip + reflect
|
||||||
|
{
|
||||||
|
path = ReedsSheppStateSpace::ReedsSheppPath(
|
||||||
|
ReedsSheppStateSpace::reedsSheppPathType[9], -t, .5*pi, -u, -v);
|
||||||
|
Lmin = L;
|
||||||
|
}
|
||||||
|
|
||||||
|
// backwards
|
||||||
|
double xb = x*cos(phi) + y*sin(phi), yb = x*sin(phi) - y*cos(phi);
|
||||||
|
if (LpRmSmLm(xb, yb, phi, t, u, v) && Lmin > (L = fabs(t) + fabs(u) + fabs(v)))
|
||||||
|
{
|
||||||
|
path = ReedsSheppStateSpace::ReedsSheppPath(
|
||||||
|
ReedsSheppStateSpace::reedsSheppPathType[6], v, u, -.5*pi, t);
|
||||||
|
Lmin = L;
|
||||||
|
}
|
||||||
|
if (LpRmSmLm(-xb, yb, -phi, t, u, v) && Lmin > (L = fabs(t) + fabs(u) + fabs(v))) // timeflip
|
||||||
|
{
|
||||||
|
path = ReedsSheppStateSpace::ReedsSheppPath(
|
||||||
|
ReedsSheppStateSpace::reedsSheppPathType[6], -v, -u, .5*pi, -t);
|
||||||
|
Lmin = L;
|
||||||
|
}
|
||||||
|
if (LpRmSmLm(xb, -yb, -phi, t, u, v) && Lmin > (L = fabs(t) + fabs(u) + fabs(v))) // reflect
|
||||||
|
{
|
||||||
|
path = ReedsSheppStateSpace::ReedsSheppPath(
|
||||||
|
ReedsSheppStateSpace::reedsSheppPathType[7], v, u, -.5*pi, t);
|
||||||
|
Lmin = L;
|
||||||
|
}
|
||||||
|
if (LpRmSmLm(-xb, -yb, phi, t, u, v) && Lmin > (L = fabs(t) + fabs(u) + fabs(v))) // timeflip + reflect
|
||||||
|
{
|
||||||
|
path = ReedsSheppStateSpace::ReedsSheppPath(
|
||||||
|
ReedsSheppStateSpace::reedsSheppPathType[7], -v, -u, .5*pi, -t);
|
||||||
|
Lmin = L;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (LpRmSmRm(xb, yb, phi, t, u, v) && Lmin > (L = fabs(t) + fabs(u) + fabs(v)))
|
||||||
|
{
|
||||||
|
path = ReedsSheppStateSpace::ReedsSheppPath(
|
||||||
|
ReedsSheppStateSpace::reedsSheppPathType[10], v, u, -.5*pi, t);
|
||||||
|
Lmin = L;
|
||||||
|
}
|
||||||
|
if (LpRmSmRm(-xb, yb, -phi, t, u, v) && Lmin > (L = fabs(t) + fabs(u) + fabs(v))) // timeflip
|
||||||
|
{
|
||||||
|
path = ReedsSheppStateSpace::ReedsSheppPath(
|
||||||
|
ReedsSheppStateSpace::reedsSheppPathType[10], -v, -u, .5*pi, -t);
|
||||||
|
Lmin = L;
|
||||||
|
}
|
||||||
|
if (LpRmSmRm(xb, -yb, -phi, t, u, v) && Lmin > (L = fabs(t) + fabs(u) + fabs(v))) // reflect
|
||||||
|
{
|
||||||
|
path = ReedsSheppStateSpace::ReedsSheppPath(
|
||||||
|
ReedsSheppStateSpace::reedsSheppPathType[11], v, u, -.5*pi, t);
|
||||||
|
Lmin = L;
|
||||||
|
}
|
||||||
|
if (LpRmSmRm(-xb, -yb, phi, t, u, v) && Lmin > (L = fabs(t) + fabs(u) + fabs(v))) // timeflip + reflect
|
||||||
|
path = ReedsSheppStateSpace::ReedsSheppPath(
|
||||||
|
ReedsSheppStateSpace::reedsSheppPathType[11], -v, -u, .5*pi, -t);
|
||||||
|
}
|
||||||
|
// formula 8.11 *** TYPO IN PAPER ***
|
||||||
|
inline bool LpRmSLmRp(double x, double y, double phi, double &t, double &u, double &v)
|
||||||
|
{
|
||||||
|
double xi = x + sin(phi), eta = y - 1. - cos(phi), rho, theta;
|
||||||
|
polar(xi, eta, rho, theta);
|
||||||
|
if (rho >= 2.)
|
||||||
|
{
|
||||||
|
u = 4. - sqrt(rho*rho - 4.);
|
||||||
|
if (u <= ZERO)
|
||||||
|
{
|
||||||
|
t = mod2pi(atan2((4-u)*xi -2*eta, -2*xi + (u-4)*eta));
|
||||||
|
v = mod2pi(t - phi);
|
||||||
|
assert(fabs(4*sin(t)-2*cos(t)-u*sin(t)-sin(phi) - x) < RS_EPS);
|
||||||
|
assert(fabs(-4*cos(t)-2*sin(t)+u*cos(t)+cos(phi)+1 - y) < RS_EPS);
|
||||||
|
assert(fabs(mod2pi(t-v-phi)) < RS_EPS);
|
||||||
|
return t>=-ZERO && v>=-ZERO;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
void CCSCC(double x, double y, double phi, ReedsSheppStateSpace::ReedsSheppPath &path)
|
||||||
|
{
|
||||||
|
double t, u, v, Lmin = path.length() - pi, L;
|
||||||
|
if (LpRmSLmRp(x, y, phi, t, u, v) && Lmin > (L = fabs(t) + fabs(u) + fabs(v)))
|
||||||
|
{
|
||||||
|
path = ReedsSheppStateSpace::ReedsSheppPath(
|
||||||
|
ReedsSheppStateSpace::reedsSheppPathType[16], t, -.5*pi, u, -.5*pi, v);
|
||||||
|
Lmin = L;
|
||||||
|
}
|
||||||
|
if (LpRmSLmRp(-x, y, -phi, t, u, v) && Lmin > (L = fabs(t) + fabs(u) + fabs(v))) // timeflip
|
||||||
|
{
|
||||||
|
path = ReedsSheppStateSpace::ReedsSheppPath(
|
||||||
|
ReedsSheppStateSpace::reedsSheppPathType[16], -t, .5*pi, -u, .5*pi, -v);
|
||||||
|
Lmin = L;
|
||||||
|
}
|
||||||
|
if (LpRmSLmRp(x, -y, -phi, t, u, v) && Lmin > (L = fabs(t) + fabs(u) + fabs(v))) // reflect
|
||||||
|
{
|
||||||
|
path = ReedsSheppStateSpace::ReedsSheppPath(
|
||||||
|
ReedsSheppStateSpace::reedsSheppPathType[17], t, -.5*pi, u, -.5*pi, v);
|
||||||
|
Lmin = L;
|
||||||
|
}
|
||||||
|
if (LpRmSLmRp(-x, -y, phi, t, u, v) && Lmin > (L = fabs(t) + fabs(u) + fabs(v))) // timeflip + reflect
|
||||||
|
path = ReedsSheppStateSpace::ReedsSheppPath(
|
||||||
|
ReedsSheppStateSpace::reedsSheppPathType[17], -t, .5*pi, -u, .5*pi, -v);
|
||||||
|
}
|
||||||
|
|
||||||
|
ReedsSheppStateSpace::ReedsSheppPath reedsShepp(double x, double y, double phi)
|
||||||
|
{
|
||||||
|
ReedsSheppStateSpace::ReedsSheppPath path;
|
||||||
|
CSC(x, y, phi, path);
|
||||||
|
CCC(x, y, phi, path);
|
||||||
|
CCCC(x, y, phi, path);
|
||||||
|
CCSC(x, y, phi, path);
|
||||||
|
CCSCC(x, y, phi, path);
|
||||||
|
return path;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const ReedsSheppStateSpace::ReedsSheppPathSegmentType
|
||||||
|
ReedsSheppStateSpace::reedsSheppPathType[18][5] = {
|
||||||
|
{ RS_LEFT, RS_RIGHT, RS_LEFT, RS_NOP, RS_NOP }, // 0
|
||||||
|
{ RS_RIGHT, RS_LEFT, RS_RIGHT, RS_NOP, RS_NOP }, // 1
|
||||||
|
{ RS_LEFT, RS_RIGHT, RS_LEFT, RS_RIGHT, RS_NOP }, // 2
|
||||||
|
{ RS_RIGHT, RS_LEFT, RS_RIGHT, RS_LEFT, RS_NOP }, // 3
|
||||||
|
{ RS_LEFT, RS_RIGHT, RS_STRAIGHT, RS_LEFT, RS_NOP }, // 4
|
||||||
|
{ RS_RIGHT, RS_LEFT, RS_STRAIGHT, RS_RIGHT, RS_NOP }, // 5
|
||||||
|
{ RS_LEFT, RS_STRAIGHT, RS_RIGHT, RS_LEFT, RS_NOP }, // 6
|
||||||
|
{ RS_RIGHT, RS_STRAIGHT, RS_LEFT, RS_RIGHT, RS_NOP }, // 7
|
||||||
|
{ RS_LEFT, RS_RIGHT, RS_STRAIGHT, RS_RIGHT, RS_NOP }, // 8
|
||||||
|
{ RS_RIGHT, RS_LEFT, RS_STRAIGHT, RS_LEFT, RS_NOP }, // 9
|
||||||
|
{ RS_RIGHT, RS_STRAIGHT, RS_RIGHT, RS_LEFT, RS_NOP }, // 10
|
||||||
|
{ RS_LEFT, RS_STRAIGHT, RS_LEFT, RS_RIGHT, RS_NOP }, // 11
|
||||||
|
{ RS_LEFT, RS_STRAIGHT, RS_RIGHT, RS_NOP, RS_NOP }, // 12
|
||||||
|
{ RS_RIGHT, RS_STRAIGHT, RS_LEFT, RS_NOP, RS_NOP }, // 13
|
||||||
|
{ RS_LEFT, RS_STRAIGHT, RS_LEFT, RS_NOP, RS_NOP }, // 14
|
||||||
|
{ RS_RIGHT, RS_STRAIGHT, RS_RIGHT, RS_NOP, RS_NOP }, // 15
|
||||||
|
{ RS_LEFT, RS_RIGHT, RS_STRAIGHT, RS_LEFT, RS_RIGHT }, // 16
|
||||||
|
{ RS_RIGHT, RS_LEFT, RS_STRAIGHT, RS_RIGHT, RS_LEFT } // 17
|
||||||
|
};
|
||||||
|
|
||||||
|
ReedsSheppStateSpace::ReedsSheppPath::ReedsSheppPath(const ReedsSheppPathSegmentType* type,
|
||||||
|
double t, double u, double v, double w, double x)
|
||||||
|
: type_(type)
|
||||||
|
{
|
||||||
|
length_[0] = t; length_[1] = u; length_[2] = v; length_[3] = w; length_[4] = x;
|
||||||
|
totalLength_ = fabs(t) + fabs(u) + fabs(v) + fabs(w) + fabs(x);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
double ReedsSheppStateSpace::distance(double q0[3], double q1[3])
|
||||||
|
{
|
||||||
|
return rho_ * reedsShepp(q0, q1).length();
|
||||||
|
}
|
||||||
|
|
||||||
|
ReedsSheppStateSpace::ReedsSheppPath ReedsSheppStateSpace::reedsShepp(double q0[3], double q1[3])
|
||||||
|
{
|
||||||
|
double dx = q1[0] - q0[0], dy = q1[1] - q0[1], dth = q1[2] - q0[2];
|
||||||
|
double c = cos(q0[2]), s = sin(q0[2]);
|
||||||
|
double x = c*dx + s*dy, y = -s*dx + c*dy;
|
||||||
|
return ::reedsShepp(x/rho_, y/rho_, dth);
|
||||||
|
}
|
||||||
|
|
||||||
|
std::vector<ReedsSheppStateSpace::ReedsSheppPathSegmentType> ReedsSheppStateSpace::type(double q0[3], double q1[3])
|
||||||
|
{
|
||||||
|
ReedsSheppPath path = reedsShepp(q0, q1);
|
||||||
|
std::vector<ReedsSheppStateSpace::ReedsSheppPathSegmentType> type_list;
|
||||||
|
for (int i=0;i<5;++i)
|
||||||
|
type_list.push_back(path.type_[i]);
|
||||||
|
return type_list;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ReedsSheppStateSpace::sample(double q0[3], double q1[3], double step_size, double &length, std::vector<std::vector<double> > &points)
|
||||||
|
{
|
||||||
|
ReedsSheppPath path = reedsShepp(q0, q1);
|
||||||
|
length = rho_ * path.length();
|
||||||
|
|
||||||
|
for (double seg=0.0; seg<=length; seg+=step_size) {
|
||||||
|
double qnew[3] = {};
|
||||||
|
interpolate(q0, path, seg/rho_, qnew);
|
||||||
|
std::vector<double> v(qnew, qnew + sizeof qnew / sizeof qnew[0]);
|
||||||
|
points.push_back(v);
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ReedsSheppStateSpace::interpolate(double q0[3], ReedsSheppPath &path, double seg, double s[3])
|
||||||
|
{
|
||||||
|
|
||||||
|
if (seg < 0.0) seg = 0.0;
|
||||||
|
if (seg > path.length()) seg = path.length();
|
||||||
|
|
||||||
|
double phi, v;
|
||||||
|
|
||||||
|
s[0] = s[1] = 0.0;
|
||||||
|
s[2] = q0[2];
|
||||||
|
|
||||||
|
for (unsigned int i=0; i<5 && seg>0; ++i)
|
||||||
|
{
|
||||||
|
if (path.length_[i]<0)
|
||||||
|
{
|
||||||
|
v = std::max(-seg, path.length_[i]);
|
||||||
|
seg += v;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
v = std::min(seg, path.length_[i]);
|
||||||
|
seg -= v;
|
||||||
|
}
|
||||||
|
phi = s[2];
|
||||||
|
switch(path.type_[i])
|
||||||
|
{
|
||||||
|
case RS_LEFT:
|
||||||
|
s[0] += ( sin(phi+v) - sin(phi));
|
||||||
|
s[1] += (-cos(phi+v) + cos(phi));
|
||||||
|
s[2] = phi + v;
|
||||||
|
break;
|
||||||
|
case RS_RIGHT:
|
||||||
|
s[0] += (-sin(phi-v) + sin(phi));
|
||||||
|
s[1] += ( cos(phi-v) - cos(phi));
|
||||||
|
s[2] = phi - v;
|
||||||
|
break;
|
||||||
|
case RS_STRAIGHT:
|
||||||
|
s[0] += (v * cos(phi));
|
||||||
|
s[1] += (v * sin(phi));
|
||||||
|
break;
|
||||||
|
case RS_NOP:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
s[0] = s[0] * rho_ + q0[0];
|
||||||
|
s[1] = s[1] * rho_ + q0[1];
|
||||||
|
}
|
||||||
@ -0,0 +1,133 @@
|
|||||||
|
/*********************************************************************
|
||||||
|
*
|
||||||
|
* BSD 3-Clause License
|
||||||
|
*
|
||||||
|
* Copyright (c) 2021, dengpw
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions
|
||||||
|
* are met:
|
||||||
|
*
|
||||||
|
* 1 Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
* 2 Redistributions in binary form must reproduce the above
|
||||||
|
* copyright notice, this list of conditions and the following
|
||||||
|
* disclaimer in the documentation and/or other materials provided
|
||||||
|
* with the distribution.
|
||||||
|
* 3 Neither the name of the copyright holder nor the names of its
|
||||||
|
* contributors may be used to endorse or promote products derived from
|
||||||
|
* this software without specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
|
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||||
|
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||||
|
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||||
|
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||||
|
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||||
|
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||||
|
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||||
|
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||||
|
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
|
||||||
|
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||||
|
* POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*
|
||||||
|
* Author: dengpw
|
||||||
|
*********************************************************************/
|
||||||
|
#include "node2d.h"
|
||||||
|
#include <iostream>
|
||||||
|
namespace hybrid_astar_planner {
|
||||||
|
|
||||||
|
float Node2D::calcG(Node2D const *partent) {
|
||||||
|
float g;
|
||||||
|
if((abs(x - partent->x) + abs(y - partent->y)) == 2) {
|
||||||
|
g = 1.4142;
|
||||||
|
}
|
||||||
|
else g = 1;
|
||||||
|
return g + partent->getG() + 0.1*cost;
|
||||||
|
}
|
||||||
|
|
||||||
|
float Node2D::calcH(Node2D const *goal) {
|
||||||
|
float dx, dy;
|
||||||
|
dx = abs(x - goal->x);
|
||||||
|
dy = abs(y - goal->y);
|
||||||
|
h = dx + dy;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::unordered_map<int, std::shared_ptr<Node2D>> GridSearch::GenerateDpMap(
|
||||||
|
const double goal_x, const double goal_y,
|
||||||
|
costmap_2d::Costmap2D* costmap) {
|
||||||
|
const unsigned char* charMap = costmap->getCharMap();
|
||||||
|
int counter = 0;
|
||||||
|
int cells_x, cells_y;
|
||||||
|
cells_x = costmap->getSizeInCellsX();
|
||||||
|
cells_y = costmap->getSizeInCellsY();
|
||||||
|
float resolution = costmap->getResolution();
|
||||||
|
std::priority_queue<std::pair<int, double>,
|
||||||
|
std::vector<std::pair<int, double>>, cmp>
|
||||||
|
open_pq;
|
||||||
|
std::unordered_map<int, std::shared_ptr<Node2D>> open_set;
|
||||||
|
std::unordered_map<int, std::shared_ptr<Node2D>> dp_map_;
|
||||||
|
std::shared_ptr<Node2D> goal_node = std::make_shared<Node2D>(goal_x, goal_y);
|
||||||
|
goal_node->setX( goal_x );
|
||||||
|
goal_node->setY( goal_y );
|
||||||
|
goal_node->setG(0);
|
||||||
|
open_set.emplace(goal_node->getindex(cells_x), goal_node );
|
||||||
|
open_pq.emplace(goal_node->getindex(cells_x), goal_node->getG());
|
||||||
|
while(!open_pq.empty()) {
|
||||||
|
++counter;
|
||||||
|
int id = open_pq.top().first;
|
||||||
|
open_pq.pop();
|
||||||
|
std::shared_ptr<Node2D> current_node = open_set[id];
|
||||||
|
dp_map_.emplace(current_node->getindex(cells_x), current_node);
|
||||||
|
std::vector<std::shared_ptr<Node2D>> adjacent_nodes =
|
||||||
|
getAdjacentPoints(cells_x, cells_y, charMap, current_node );
|
||||||
|
for (std::vector<std::shared_ptr<Node2D>>::iterator
|
||||||
|
it = adjacent_nodes.begin(); it != adjacent_nodes.end(); ++it) {
|
||||||
|
std::shared_ptr<Node2D> next_node = *it;
|
||||||
|
if (dp_map_.find(next_node->getindex(cells_x)) != dp_map_.end()) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (open_set.find(next_node->getindex(cells_x)) != open_set.end()) {
|
||||||
|
if (open_set[next_node->getindex(cells_x)]->getG() > next_node->getG()) {
|
||||||
|
open_set[next_node->getindex(cells_x)]->setCost(next_node->getG());
|
||||||
|
open_set[next_node->getindex(cells_x)]->setPerd_(current_node);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// ++counter;
|
||||||
|
next_node->setPerd_(current_node);
|
||||||
|
open_set.emplace(next_node->getindex(cells_x), next_node );
|
||||||
|
open_pq.emplace(next_node->getindex(cells_x), next_node->getG());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// printf("X %d y %d explored node num is : %d \n", cells_x, cells_y, counter);
|
||||||
|
return dp_map_;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::vector<std::shared_ptr<Node2D>> GridSearch::getAdjacentPoints(int cells_x,
|
||||||
|
int cells_y, const unsigned char* charMap, std::shared_ptr<Node2D> point) {
|
||||||
|
std::vector<std::shared_ptr<Node2D>> adjacentNodes;
|
||||||
|
float g = 0;
|
||||||
|
// std::cout << "the cost-so-far of this node" << point->getG() << std::endl;
|
||||||
|
for (int x = point->getX() - 1; x <= point->getX() + 1; ++x) {
|
||||||
|
for (int y = point->getY() - 1; y <= point->getY() + 1; ++y) {
|
||||||
|
if (charMap[x + y* cells_x] < 250 &&x < cells_x && y < cells_y
|
||||||
|
&& x > 0 && y > 0) {
|
||||||
|
std::shared_ptr<Node2D> node = std::make_shared<Node2D>(x,y);
|
||||||
|
if((abs(x - point->getX()) + abs(y - point->getY())) == 2) {
|
||||||
|
g = 1.4142;
|
||||||
|
} else {
|
||||||
|
g = 1;
|
||||||
|
}
|
||||||
|
node->SetPathCost(point->getG() + 0.1*charMap[x + y* cells_x] + g);
|
||||||
|
node->setX(x);
|
||||||
|
node->setY(y);
|
||||||
|
adjacentNodes.emplace_back(node);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}//end of for
|
||||||
|
return adjacentNodes;
|
||||||
|
}
|
||||||
|
|
||||||
|
}//namespace hybrid_astar_planner
|
||||||
@ -0,0 +1,139 @@
|
|||||||
|
/*********************************************************************
|
||||||
|
*
|
||||||
|
* BSD 3-Clause License
|
||||||
|
*
|
||||||
|
* Copyright (c) 2021, dengpw
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions
|
||||||
|
* are met:
|
||||||
|
*
|
||||||
|
* 1 Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
* 2 Redistributions in binary form must reproduce the above
|
||||||
|
* copyright notice, this list of conditions and the following
|
||||||
|
* disclaimer in the documentation and/or other materials provided
|
||||||
|
* with the distribution.
|
||||||
|
* 3 Neither the name of the copyright holder nor the names of its
|
||||||
|
* contributors may be used to endorse or promote products derived from
|
||||||
|
* this software without specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
|
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||||
|
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||||
|
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||||
|
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||||
|
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||||
|
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||||
|
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||||
|
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||||
|
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
|
||||||
|
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||||
|
* POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*
|
||||||
|
* Author: dengpw
|
||||||
|
*********************************************************************/
|
||||||
|
#include "planner_core.h"
|
||||||
|
#include "node3d.h"
|
||||||
|
#include <tf/transform_datatypes.h>
|
||||||
|
namespace hybrid_astar_planner {
|
||||||
|
|
||||||
|
void HybridAStarPlanner::publishPlan(const std::vector<geometry_msgs::PoseStamped>& path) {
|
||||||
|
if (!initialized_) {
|
||||||
|
ROS_ERROR(
|
||||||
|
"This planner has not been initialized yet, but it is being used, please call initialize() before use");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
//create a message for the plan
|
||||||
|
geometry_msgs::PoseStamped transform_path;
|
||||||
|
nav_msgs::Path gui_path;
|
||||||
|
int size = path.size();
|
||||||
|
gui_path.poses.resize(size);
|
||||||
|
|
||||||
|
gui_path.header.frame_id = frame_id_;
|
||||||
|
gui_path.header.stamp = ros::Time::now();
|
||||||
|
|
||||||
|
// Extract the plan in world co-ordinates, we assume the path is all in the same frame
|
||||||
|
for (unsigned int i = 0; i < size; i++) {
|
||||||
|
transform_path.pose.position = path[i].pose.position;
|
||||||
|
gui_path.poses[i] = transform_path;//
|
||||||
|
}
|
||||||
|
|
||||||
|
plan_pub_.publish(gui_path);
|
||||||
|
// ROS_INFO("Publish the path to Rviz");
|
||||||
|
|
||||||
|
}//end of publishPlan
|
||||||
|
|
||||||
|
|
||||||
|
void HybridAStarPlanner::publishPathNodes(const std::vector<geometry_msgs::PoseStamped>& path) {
|
||||||
|
if (!initialized_) {
|
||||||
|
ROS_ERROR(
|
||||||
|
"This planner has not been initialized yet, but it is being used, please call initialize() before use");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
visualization_msgs::Marker pathVehicle;
|
||||||
|
int nodeSize = path.size();
|
||||||
|
pathVehicle.header.stamp = ros::Time(0);
|
||||||
|
pathVehicle.color.r = 52.f / 255.f;
|
||||||
|
pathVehicle.color.g = 250.f / 255.f;
|
||||||
|
pathVehicle.color.b = 52.f / 255.f;
|
||||||
|
pathVehicle.type = visualization_msgs::Marker::ARROW;
|
||||||
|
pathVehicle.header.frame_id = frame_id_;
|
||||||
|
pathVehicle.scale.x = 0.22;
|
||||||
|
pathVehicle.scale.y = 0.18;
|
||||||
|
pathVehicle.scale.z = 0.12;
|
||||||
|
pathVehicle.color.a = 0.1;
|
||||||
|
// 转化节点,并同时加上时间戳等信息
|
||||||
|
for(int i = 0; i<nodeSize; i++) {
|
||||||
|
pathVehicle.header.stamp = ros::Time(0);
|
||||||
|
pathVehicle.pose = path[i].pose;
|
||||||
|
pathVehicle.id = i;
|
||||||
|
pathNodes.markers.push_back(pathVehicle);
|
||||||
|
}
|
||||||
|
// 发布这些车辆位置标记点
|
||||||
|
path_vehicles_pub_.publish(pathNodes);
|
||||||
|
|
||||||
|
}//end of publishPathNodes
|
||||||
|
|
||||||
|
void HybridAStarPlanner::clearPathNodes() {
|
||||||
|
// 初始化并配置节点为全清空模式
|
||||||
|
visualization_msgs::Marker node;
|
||||||
|
pathNodes.markers.clear();
|
||||||
|
node.action = visualization_msgs::Marker::DELETEALL;
|
||||||
|
node.header.frame_id = frame_id_;
|
||||||
|
node.header.stamp = ros::Time(0);
|
||||||
|
node.id = 0;
|
||||||
|
node.action = 3;
|
||||||
|
pathNodes.markers.push_back(node);
|
||||||
|
path_vehicles_pub_.publish(pathNodes);
|
||||||
|
// ROS_INFO("Clean the path nodes");
|
||||||
|
}
|
||||||
|
|
||||||
|
void publishSearchNodes(Node3D node,ros::Publisher& pub,
|
||||||
|
visualization_msgs::MarkerArray& pathNodes, int i) {
|
||||||
|
visualization_msgs::Marker pathVehicle;
|
||||||
|
pathVehicle.header.stamp = ros::Time(0);
|
||||||
|
pathVehicle.color.r = 250.f / 255.f;
|
||||||
|
pathVehicle.color.g = 250.f / 255.f;
|
||||||
|
pathVehicle.color.b = 52.f / 255.f;
|
||||||
|
pathVehicle.type = visualization_msgs::Marker::ARROW;
|
||||||
|
pathVehicle.header.frame_id = "map";
|
||||||
|
pathVehicle.scale.x = 0.22;
|
||||||
|
pathVehicle.scale.y = 0.18;
|
||||||
|
pathVehicle.scale.z = 0.12;
|
||||||
|
pathVehicle.color.a = 0.1;
|
||||||
|
// 转化节点,并同时加上时间戳等信息
|
||||||
|
pathVehicle.header.stamp = ros::Time(0);
|
||||||
|
pathVehicle.pose.position.x = node.getX();
|
||||||
|
pathVehicle.pose.position.y = node.getY();
|
||||||
|
pathVehicle.pose.position.z = 0;
|
||||||
|
pathVehicle.pose.orientation = tf::createQuaternionMsgFromYaw(node.getT());
|
||||||
|
pathVehicle.id = i;
|
||||||
|
pathNodes.markers.push_back(pathVehicle);
|
||||||
|
|
||||||
|
// 发布这些车辆位置标记点
|
||||||
|
pub.publish(pathNodes);
|
||||||
|
|
||||||
|
}//end of publishPathNodes
|
||||||
|
}
|
||||||
@ -0,0 +1,221 @@
|
|||||||
|
Panels:
|
||||||
|
- Class: rviz/Displays
|
||||||
|
Help Height: 78
|
||||||
|
Name: Displays
|
||||||
|
Property Tree Widget:
|
||||||
|
Expanded:
|
||||||
|
- /Global Options1
|
||||||
|
- /Map2
|
||||||
|
- /Path1
|
||||||
|
- /MarkerArray3
|
||||||
|
Splitter Ratio: 0.5
|
||||||
|
Tree Height: 300
|
||||||
|
- Class: rviz/Selection
|
||||||
|
Name: Selection
|
||||||
|
- Class: rviz/Tool Properties
|
||||||
|
Expanded:
|
||||||
|
- /2D Pose Estimate1
|
||||||
|
- /2D Nav Goal1
|
||||||
|
- /Publish Point1
|
||||||
|
Name: Tool Properties
|
||||||
|
Splitter Ratio: 0.5886790156364441
|
||||||
|
- Class: rviz/Views
|
||||||
|
Expanded:
|
||||||
|
- /Current View1
|
||||||
|
Name: Views
|
||||||
|
Splitter Ratio: 0.5
|
||||||
|
- Class: rviz/Time
|
||||||
|
Experimental: false
|
||||||
|
Name: Time
|
||||||
|
SyncMode: 0
|
||||||
|
SyncSource: ""
|
||||||
|
Preferences:
|
||||||
|
PromptSaveOnExit: true
|
||||||
|
Toolbars:
|
||||||
|
toolButtonStyle: 2
|
||||||
|
Visualization Manager:
|
||||||
|
Class: ""
|
||||||
|
Displays:
|
||||||
|
- Alpha: 0.5
|
||||||
|
Cell Size: 1
|
||||||
|
Class: rviz/Grid
|
||||||
|
Color: 160; 160; 164
|
||||||
|
Enabled: true
|
||||||
|
Line Style:
|
||||||
|
Line Width: 0.029999999329447746
|
||||||
|
Value: Lines
|
||||||
|
Name: Grid
|
||||||
|
Normal Cell Count: 0
|
||||||
|
Offset:
|
||||||
|
X: 0
|
||||||
|
Y: 0
|
||||||
|
Z: 0
|
||||||
|
Plane: XY
|
||||||
|
Plane Cell Count: 10
|
||||||
|
Reference Frame: <Fixed Frame>
|
||||||
|
Value: true
|
||||||
|
- Alpha: 0.699999988079071
|
||||||
|
Class: rviz/Map
|
||||||
|
Color Scheme: map
|
||||||
|
Draw Behind: false
|
||||||
|
Enabled: true
|
||||||
|
Name: Map
|
||||||
|
Topic: /map
|
||||||
|
Unreliable: false
|
||||||
|
Use Timestamp: false
|
||||||
|
Value: true
|
||||||
|
- Alpha: 1
|
||||||
|
Axes Length: 1
|
||||||
|
Axes Radius: 0.10000000149011612
|
||||||
|
Class: rviz/Pose
|
||||||
|
Color: 255; 25; 0
|
||||||
|
Enabled: true
|
||||||
|
Head Length: 0.30000001192092896
|
||||||
|
Head Radius: 0.10000000149011612
|
||||||
|
Name: Pose
|
||||||
|
Shaft Length: 1
|
||||||
|
Shaft Radius: 0.05000000074505806
|
||||||
|
Shape: Arrow
|
||||||
|
Topic: /move_base_simple/goal
|
||||||
|
Unreliable: false
|
||||||
|
Value: true
|
||||||
|
- Alpha: 1
|
||||||
|
Axes Length: 1
|
||||||
|
Axes Radius: 0.10000000149011612
|
||||||
|
Class: rviz/Pose
|
||||||
|
Color: 255; 25; 0
|
||||||
|
Enabled: true
|
||||||
|
Head Length: 0.30000001192092896
|
||||||
|
Head Radius: 0.10000000149011612
|
||||||
|
Name: Pose
|
||||||
|
Shaft Length: 1
|
||||||
|
Shaft Radius: 0.05000000074505806
|
||||||
|
Shape: Arrow
|
||||||
|
Topic: /move_base_simple/start
|
||||||
|
Unreliable: false
|
||||||
|
Value: true
|
||||||
|
- Class: rviz/MarkerArray
|
||||||
|
Enabled: true
|
||||||
|
Marker Topic: /sPathNodes
|
||||||
|
Name: MarkerArray
|
||||||
|
Namespaces:
|
||||||
|
{}
|
||||||
|
Queue Size: 100
|
||||||
|
Value: true
|
||||||
|
- Class: rviz/MarkerArray
|
||||||
|
Enabled: true
|
||||||
|
Marker Topic: /sPathVehicle
|
||||||
|
Name: MarkerArray
|
||||||
|
Namespaces:
|
||||||
|
{}
|
||||||
|
Queue Size: 100
|
||||||
|
Value: true
|
||||||
|
- Class: rviz/Axes
|
||||||
|
Enabled: true
|
||||||
|
Length: 1
|
||||||
|
Name: Axes
|
||||||
|
Radius: 0.10000000149011612
|
||||||
|
Reference Frame: base_link
|
||||||
|
Value: true
|
||||||
|
- Alpha: 0.699999988079071
|
||||||
|
Class: rviz/Map
|
||||||
|
Color Scheme: costmap
|
||||||
|
Draw Behind: false
|
||||||
|
Enabled: true
|
||||||
|
Name: Map
|
||||||
|
Topic: /move_base/global_costmap/costmap
|
||||||
|
Unreliable: false
|
||||||
|
Use Timestamp: false
|
||||||
|
Value: true
|
||||||
|
- Alpha: 1
|
||||||
|
Buffer Length: 1
|
||||||
|
Class: rviz/Path
|
||||||
|
Color: 25; 255; 0
|
||||||
|
Enabled: true
|
||||||
|
Head Diameter: 0.30000001192092896
|
||||||
|
Head Length: 0.20000000298023224
|
||||||
|
Length: 0.30000001192092896
|
||||||
|
Line Style: Lines
|
||||||
|
Line Width: 0.029999999329447746
|
||||||
|
Name: Path
|
||||||
|
Offset:
|
||||||
|
X: 0
|
||||||
|
Y: 0
|
||||||
|
Z: 0
|
||||||
|
Pose Color: 255; 85; 255
|
||||||
|
Pose Style: None
|
||||||
|
Radius: 0.029999999329447746
|
||||||
|
Shaft Diameter: 0.10000000149011612
|
||||||
|
Shaft Length: 0.10000000149011612
|
||||||
|
Topic: /move_base/HybridAStarPlanner/plan
|
||||||
|
Unreliable: false
|
||||||
|
Value: true
|
||||||
|
- Class: rviz/MarkerArray
|
||||||
|
Enabled: true
|
||||||
|
Marker Topic: /move_base/HybridAStarPlanner/pathVehicle
|
||||||
|
Name: MarkerArray
|
||||||
|
Namespaces:
|
||||||
|
{}
|
||||||
|
Queue Size: 100
|
||||||
|
Value: true
|
||||||
|
Enabled: true
|
||||||
|
Global Options:
|
||||||
|
Background Color: 48; 48; 48
|
||||||
|
Default Light: true
|
||||||
|
Fixed Frame: map
|
||||||
|
Frame Rate: 30
|
||||||
|
Name: root
|
||||||
|
Tools:
|
||||||
|
- Class: rviz/Interact
|
||||||
|
Hide Inactive Objects: true
|
||||||
|
- Class: rviz/MoveCamera
|
||||||
|
- Class: rviz/Select
|
||||||
|
- Class: rviz/FocusCamera
|
||||||
|
- Class: rviz/Measure
|
||||||
|
- Class: rviz/SetInitialPose
|
||||||
|
Theta std deviation: 0.2617993950843811
|
||||||
|
Topic: /initialpose
|
||||||
|
X std deviation: 0.5
|
||||||
|
Y std deviation: 0.5
|
||||||
|
- Class: rviz/SetGoal
|
||||||
|
Topic: /move_base_simple/goal
|
||||||
|
- Class: rviz/PublishPoint
|
||||||
|
Single click: true
|
||||||
|
Topic: /clicked_point
|
||||||
|
Value: true
|
||||||
|
Views:
|
||||||
|
Current:
|
||||||
|
Angle: 0.019999396055936813
|
||||||
|
Class: rviz/TopDownOrtho
|
||||||
|
Enable Stereo Rendering:
|
||||||
|
Stereo Eye Separation: 0.05999999865889549
|
||||||
|
Stereo Focal Distance: 1
|
||||||
|
Swap Stereo Eyes: false
|
||||||
|
Value: false
|
||||||
|
Invert Z Axis: false
|
||||||
|
Name: Current View
|
||||||
|
Near Clip Distance: 0.009999999776482582
|
||||||
|
Scale: 78.33514404296875
|
||||||
|
Target Frame: <Fixed Frame>
|
||||||
|
Value: TopDownOrtho (rviz)
|
||||||
|
X: 2.5319337844848633
|
||||||
|
Y: 1.5114061832427979
|
||||||
|
Saved: ~
|
||||||
|
Window Geometry:
|
||||||
|
Displays:
|
||||||
|
collapsed: false
|
||||||
|
Height: 597
|
||||||
|
Hide Left Dock: false
|
||||||
|
Hide Right Dock: false
|
||||||
|
QMainWindow State: 000000ff00000000fd000000040000000000000156000001b7fc0200000008fb0000001200530065006c0065006300740069006f006e00000001e10000009b0000005c00fffffffb0000001e0054006f006f006c002000500072006f007000650072007400690065007302000001ed000001df00000185000000a3fb000000120056006900650077007300200054006f006f02000001df000002110000018500000122fb000000200054006f006f006c002000500072006f0070006500720074006900650073003203000002880000011d000002210000017afb000000100044006900730070006c006100790073010000003d000001b7000000c900fffffffb0000002000730065006c0065006300740069006f006e00200062007500660066006500720200000138000000aa0000023a00000294fb00000014005700690064006500530074006500720065006f02000000e6000000d2000003ee0000030bfb0000000c004b0069006e0065006300740200000186000001060000030c00000261000000010000010f000001b7fc0200000003fb0000001e0054006f006f006c002000500072006f00700065007200740069006500730100000041000000780000000000000000fb0000000a00560069006500770073010000003d000001b7000000a400fffffffb0000001200530065006c0065006300740069006f006e010000025a000000b200000000000000000000000200000490000000a9fc0100000001fb0000000a00560069006500770073030000004e00000080000002e10000019700000003000004e40000003efc0100000002fb0000000800540069006d00650100000000000004e4000002eb00fffffffb0000000800540069006d0065010000000000000450000000000000000000000273000001b700000004000000040000000800000008fc0000000100000002000000010000000a0054006f006f006c00730100000000ffffffff0000000000000000
|
||||||
|
Selection:
|
||||||
|
collapsed: false
|
||||||
|
Time:
|
||||||
|
collapsed: false
|
||||||
|
Tool Properties:
|
||||||
|
collapsed: false
|
||||||
|
Views:
|
||||||
|
collapsed: false
|
||||||
|
Width: 1252
|
||||||
|
X: 317
|
||||||
|
Y: 27
|
||||||
@ -0,0 +1,18 @@
|
|||||||
|
<launch>
|
||||||
|
<node name="move_base" pkg="hybrid_astar_planner" type="test_planner" output="screen">
|
||||||
|
<!-- <node pkg="move_base" type="move_base" respawn="false" name="move_base" output="screen"> -->
|
||||||
|
<rosparam file="$(find hybrid_astar_planner)/test_the_plugin/param/costmap_common_params.yaml" command="load" ns="global_costmap" />
|
||||||
|
<rosparam file="$(find hybrid_astar_planner)/test_the_plugin/param/costmap_common_params.yaml" command="load" ns="local_costmap" />
|
||||||
|
<rosparam file="$(find hybrid_astar_planner)/test_the_plugin/param/local_costmap_params.yaml" command="load" />
|
||||||
|
<rosparam file="$(find hybrid_astar_planner)/test_the_plugin/param/global_costmap_params.yaml" command="load" />
|
||||||
|
<rosparam file="$(find hybrid_astar_planner)/test_the_plugin/param/base_local_planner_params.yaml" command="load" />
|
||||||
|
<rosparam file="$(find hybrid_astar_planner)/test_the_plugin/param/move_base_params.yaml" command="load" />
|
||||||
|
<rosparam file="$(find hybrid_astar_planner)/test_the_plugin/param/plugins.yaml" command="load" ns="/costmap_node/costmap"/>
|
||||||
|
<param name="base_global_planner" value="global_planner/GlobalPlanner" /><!--这个标志是选择使用特定的全局规划器-->
|
||||||
|
<param name="base_local_planner" value="teb_local_planner/TebLocalPlannerROS" />
|
||||||
|
<param name="use_hybrid_astar" value="true" />
|
||||||
|
</node>
|
||||||
|
<node name="tf_broadcaster" pkg="hybrid_astar_planner" type="tf_test_broadcaster" output="screen" />
|
||||||
|
<node name="map_server" pkg="map_server" type="map_server" args="$(find hybrid_astar_planner)/test_the_plugin/maps/mymap2077.yaml" />
|
||||||
|
<node name="rviz" pkg="rviz" type="rviz" args="-d $(find hybrid_astar_planner)/test_the_plugin/launch/config.rviz" />
|
||||||
|
</launch>
|
||||||
@ -0,0 +1,8 @@
|
|||||||
|
image: map_demo.png
|
||||||
|
resolution: 1
|
||||||
|
origin: [0.0, 0.0, 0.0]
|
||||||
|
occupied_thresh: 0.1
|
||||||
|
free_thresh: 0.05
|
||||||
|
negate: 0
|
||||||
|
|
||||||
|
|
||||||
|
After Width: | Height: | Size: 584 B |
File diff suppressed because one or more lines are too long
@ -0,0 +1,7 @@
|
|||||||
|
image: mm.pgm
|
||||||
|
resolution: 0.050000
|
||||||
|
origin: [-1.000000, -12.200000, 0.000000]
|
||||||
|
negate: 0
|
||||||
|
occupied_thresh: 0.65
|
||||||
|
free_thresh: 0.196
|
||||||
|
|
||||||
File diff suppressed because one or more lines are too long
@ -0,0 +1,7 @@
|
|||||||
|
image: mymap.pgm
|
||||||
|
resolution: 0.050000
|
||||||
|
origin: [-50.000000, -50.000000, 0.000000]
|
||||||
|
negate: 0
|
||||||
|
occupied_thresh: 0.65
|
||||||
|
free_thresh: 0.196
|
||||||
|
|
||||||
File diff suppressed because one or more lines are too long
@ -0,0 +1,7 @@
|
|||||||
|
image: mymap2077.pgm
|
||||||
|
resolution: 0.050000
|
||||||
|
origin: [-7.000000, -7.000000, 0.000000]
|
||||||
|
negate: 0
|
||||||
|
occupied_thresh: 0.65
|
||||||
|
free_thresh: 0.196
|
||||||
|
|
||||||
File diff suppressed because one or more lines are too long
@ -0,0 +1,7 @@
|
|||||||
|
image: mymap2088.pgm
|
||||||
|
resolution: 0.050000
|
||||||
|
origin: [-7.000000, -7.000000, 0.000000]
|
||||||
|
negate: 0
|
||||||
|
occupied_thresh: 0.65
|
||||||
|
free_thresh: 0.196
|
||||||
|
|
||||||
File diff suppressed because one or more lines are too long
@ -0,0 +1,7 @@
|
|||||||
|
image: mymap4.pgm
|
||||||
|
resolution: 0.050000
|
||||||
|
origin: [-50.000000, -50.000000, 0.000000]
|
||||||
|
negate: 0
|
||||||
|
occupied_thresh: 0.65
|
||||||
|
free_thresh: 0.196
|
||||||
|
|
||||||
File diff suppressed because one or more lines are too long
@ -0,0 +1,7 @@
|
|||||||
|
image: mymap5.pgm
|
||||||
|
resolution: 0.050000
|
||||||
|
origin: [-12.200000, -1.000000, 0.000000]
|
||||||
|
negate: 0
|
||||||
|
occupied_thresh: 0.65
|
||||||
|
free_thresh: 0.196
|
||||||
|
|
||||||
@ -0,0 +1,22 @@
|
|||||||
|
obstacle_range: 2.5
|
||||||
|
raytrace_range: 3.5
|
||||||
|
# footprint: [[-0.08, -0.15], [-0.08, 0.15],[0.42, 0.15], [0.42, -0.15]]
|
||||||
|
robot_radius: 0.1
|
||||||
|
inflation_radius: 0.5
|
||||||
|
transform_tolerance: 0.6
|
||||||
|
observation_sources: scan
|
||||||
|
# obstacles:
|
||||||
|
# observation_sources: scan
|
||||||
|
# scan: {data_type: LaserScan, topic: /scan, marking: true, clearing: true, expected_update_rate: 0}
|
||||||
|
map:
|
||||||
|
data_type: LaserScan
|
||||||
|
topic: /map
|
||||||
|
marking: true
|
||||||
|
clearing: true
|
||||||
|
scan:
|
||||||
|
data_type: LaserScan
|
||||||
|
topic: scan
|
||||||
|
marking: true
|
||||||
|
clearing: true
|
||||||
|
|
||||||
|
map_type: costmap
|
||||||
@ -0,0 +1,23 @@
|
|||||||
|
这些参数设置了代价图中的障碍物信息的阈值。
|
||||||
|
obstacle_range: 2.5 #此参数确定了最大范围传感器读数,在此范围内的障碍物将会被标记并放入代价图中
|
||||||
|
raytrace_range: 3.5 #这个范围内不存在的障碍物都会被清除
|
||||||
|
# footprint: [[-0.08, -0.15], [-0.08, 0.15],[0.42, 0.15], [0.42, -0.15]]
|
||||||
|
robot_radius: 0.15
|
||||||
|
inflation_radius: 0.8
|
||||||
|
transform_tolerance: 0.6
|
||||||
|
observation_sources: scan
|
||||||
|
# obstacles:
|
||||||
|
# observation_sources: scan
|
||||||
|
# scan: {data_type: LaserScan, topic: /scan, marking: true, clearing: true, expected_update_rate: 0}
|
||||||
|
map:
|
||||||
|
data_type: LaserScan
|
||||||
|
topic: /map
|
||||||
|
marking: true
|
||||||
|
clearing: true
|
||||||
|
scan:
|
||||||
|
data_type: LaserScan
|
||||||
|
topic: scan
|
||||||
|
marking: true
|
||||||
|
clearing: true
|
||||||
|
|
||||||
|
map_type: costmap
|
||||||
@ -0,0 +1,16 @@
|
|||||||
|
global_costmap:
|
||||||
|
global_frame: map
|
||||||
|
robot_base_frame: base_link
|
||||||
|
update_frequency: 1.0
|
||||||
|
publish_frequency: 0.5
|
||||||
|
static_map: true
|
||||||
|
transform_tolerance: 0.5
|
||||||
|
cost_scaling_factor: 10.0
|
||||||
|
# inflation_radius: 0.4
|
||||||
|
resolution: 1.0
|
||||||
|
plugins:
|
||||||
|
- {name: static_map, type: "costmap_2d::StaticLayer"}
|
||||||
|
- {name: obstacles, type: "costmap_2d::VoxelLayer"}
|
||||||
|
- {name: inflation_layer, type: "costmap_2d::InflationLayer"}
|
||||||
|
|
||||||
|
|
||||||
@ -0,0 +1,13 @@
|
|||||||
|
local_costmap:
|
||||||
|
global_frame: map
|
||||||
|
robot_base_frame: base_link
|
||||||
|
update_frequency: 5.0
|
||||||
|
publish_frequency: 2.0
|
||||||
|
static_map: false
|
||||||
|
rolling_window: true
|
||||||
|
width: 5
|
||||||
|
height: 5
|
||||||
|
resolution: 0.05
|
||||||
|
transform_tolerance: 0.5
|
||||||
|
cost_scaling_factor: 5
|
||||||
|
# inflation_radius: 0.3
|
||||||
@ -0,0 +1,13 @@
|
|||||||
|
shutdown_costmaps: false
|
||||||
|
|
||||||
|
controller_frequency: 5.0
|
||||||
|
controller_patience: 3.0
|
||||||
|
|
||||||
|
planner_frequency: 0.5
|
||||||
|
planner_patience: 5.0
|
||||||
|
|
||||||
|
oscillation_timeout: 10.0
|
||||||
|
oscillation_distance: 0.2
|
||||||
|
|
||||||
|
conservative_reset_dist: 0.1
|
||||||
|
|
||||||
@ -0,0 +1,5 @@
|
|||||||
|
plugins: []
|
||||||
|
plugins:
|
||||||
|
- {name: static_map, type: "costmap_2d::StaticLayer"}
|
||||||
|
- {name: obstacles, type: "costmap_2d::VoxelLayer"}
|
||||||
|
- {name: inflation_layer, type: "costmap_2d::InflationLayer"}
|
||||||
Loading…
Reference in new issue