Skip to content

Commit

Permalink
Merge pull request ai-winter#53 from omigeft/master
Browse files Browse the repository at this point in the history
add s_theta_star planner
  • Loading branch information
ai-winter authored Mar 13, 2024
2 parents 444d56e + be435b9 commit d211d0d
Show file tree
Hide file tree
Showing 10 changed files with 285 additions and 26 deletions.
6 changes: 5 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -57,4 +57,8 @@ qtcreator-*
.#*

# Catkin custom files
CATKIN_IGNORE
CATKIN_IGNORE

# osqp
osqp/
osqp-eigen/
13 changes: 7 additions & 6 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -171,8 +171,8 @@ For the efficient operation of the motion planning system, we provide a series o

### Global Planner

| Planner | Version | Animation | Papers
|:-------:|:-------:|:---------:|:---------:|
| Planner | Version | Animation | Papers
|:----------------:|:---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------:|:----------------------------------------------------------:|:---------:|
| **GBFS** | [![Status](https://img.shields.io/badge/done-v1.0-brightgreen)](https://github.com/ai-winter/ros_motion_planning/blob/master/src/core/global_planner/graph_planner/src/a_star.cpp) | ![gbfs_ros.gif](assets/gbfs_ros.gif) |-
| **Dijkstra** | [![Status](https://img.shields.io/badge/done-v1.0-brightgreen)](https://github.com/ai-winter/ros_motion_planning/blob/master/src/core/global_planner/graph_planner/src/a_star.cpp) | ![dijkstra_ros.gif](assets/dijkstra_ros.gif) |-
| **A\*** | [![Status](https://img.shields.io/badge/done-v1.1-brightgreen)](https://github.com/ai-winter/ros_motion_planning/blob/master/src/core/global_planner/graph_planner/src/a_star.cpp) | ![a_star_ros.gif](assets/a_star_ros.gif) |[A Formal Basis for the heuristic Determination of Minimum Cost Paths](https://ieeexplore.ieee.org/document/4082128)
Expand All @@ -183,14 +183,15 @@ For the efficient operation of the motion planning system, we provide a series o
| **Voronoi** | [![Status](https://img.shields.io/badge/done-v1.0-brightgreen)]((https://github.com/ai-winter/ros_motion_planning/blob/master/src/core/global_planner/graph_planner/src/voronoi.cpp)) | ![voronoi_ros.gif](assets/voronoi_ros.gif) |-
| **Theta\*** | [![Status](https://img.shields.io/badge/done-v1.0-brightgreen)]((https://github.com/ai-winter/ros_motion_planning/blob/master/src/core/global_planner/graph_planner/src/theta_star.cpp)) | ![theta_star_ros.gif](assets/theta_star_ros.gif) |[Theta*: Any-Angle Path Planning on Grids](https://www.jair.org/index.php/jair/article/view/10676), [Any-angle path planning on non-uniform costmaps](https://ieeexplore.ieee.org/abstract/document/5979769)
| **Lazy Theta\*** | [![Status](https://img.shields.io/badge/done-v1.0-brightgreen)]((https://github.com/ai-winter/ros_motion_planning/blob/master/src/core/global_planner/graph_planner/src/lazy_theta_star.cpp)) | ![lazy_theta_star_ros.gif](assets/lazy_theta_star_ros.gif) |[Lazy Theta*: Any-Angle Path Planning and Path Length Analysis in 3D](https://ojs.aaai.org/index.php/AAAI/article/view/7566)
| **Hybrid A\*** | [![Status](https://img.shields.io/badge/done-v1.0-brightgreen)]((https://github.com/ai-winter/ros_motion_planning/blob/master/src/core/global_planner/graph_planner/src/hybrid_astar.cpp)) | ![hybrid_astar_ros.gif](assets/hybrid_astar_ros.gif) |[Practical search techniques in path planning for autonomous driving](https://ai.stanford.edu/~ddolgov/papers/dolgov_gpp_stair08.pdf)
| **S-Theta\*** | [![Status](https://img.shields.io/badge/done-v1.0-brightgreen)]((https://github.com/ai-winter/ros_motion_planning/blob/master/src/core/global_planner/graph_planner/src/s_theta_star.cpp)) | ![s_theta_star_ros.gif](assets/s_theta_star_ros.gif) |[S-Theta*: low steering path-planning algorithm](https://link.springer.com/chapter/10.1007/978-1-4471-4739-8_8)
| **Hybrid A\*** | [![Status](https://img.shields.io/badge/done-v1.0-brightgreen)]((https://github.com/ai-winter/ros_motion_planning/blob/master/src/core/global_planner/graph_planner/src/hybrid_astar.cpp)) | ![hybrid_astar_ros.gif](assets/hybrid_astar_ros.gif) |[Practical search techniques in path planning for autonomous driving](https://ai.stanford.edu/~ddolgov/papers/dolgov_gpp_stair08.pdf)
| **RRT** | [![Status](https://img.shields.io/badge/done-v1.1-brightgreen)](https://github.com/ai-winter/ros_motion_planning/blob/master/src/core/global_planner/sample_planner/src/rrt.cpp) | ![rrt_ros.gif](assets/rrt_ros.gif) |[Rapidly-Exploring Random Trees: A New Tool for Path Planning](http://msl.cs.uiuc.edu/~lavalle/papers/Lav98c.pdf)
| **RRT\*** | [![Status](https://img.shields.io/badge/done-v1.0-brightgreen)](https://github.com/ai-winter/ros_motion_planning/blob/master/src/core/global_planner/sample_planner/src/rrt_star.cpp) | ![rrt_star_ros.gif](assets/rrt_star_ros.gif) |[Sampling-based algorithms for optimal motion planning](https://journals.sagepub.com/doi/abs/10.1177/0278364911406761)
| **Informed RRT** | [![Status](https://img.shields.io/badge/done-v1.0-brightgreen)](https://github.com/ai-winter/ros_motion_planning/blob/master/src/core/global_planner/sample_planner/src/informed_rrt.cpp) | ![informed_rrt_ros.gif](assets/informed_rrt_ros.gif) |[Optimal Sampling-based Path Planning Focused via Direct Sampling of an Admissible Ellipsoidal heuristic](https://arxiv.org/abs/1404.2334)
| **RRT-Connect** | [![Status](https://img.shields.io/badge/done-v1.0-brightgreen)](https://github.com/ai-winter/ros_motion_planning/blob/master/src/core/global_planner/sample_planner/src/rrt_connect.cpp) | ![rrt_connect_ros.gif](assets/rrt_connect_ros.gif) |[RRT-Connect: An Efficient Approach to Single-Query Path Planning](http://www-cgi.cs.cmu.edu/afs/cs/academic/class/15494-s12/readings/kuffner_icra2000.pdf)
| **ACO** | [![Status](https://img.shields.io/badge/done-v1.0-brightgreen)](https://github.com/ai-winter/ros_motion_planning/blob/master/src/core/global_planner/evolutionary_planner/src/aco.cpp) | ![aco_ros.gif](assets/aco_ros.gif) |[Ant Colony Optimization: A New Meta-Heuristic](http://www.cs.yale.edu/homes/lans/readings/routing/dorigo-ants-1999.pdf)
| **GA** | [![Status](https://img.shields.io/badge/done-v1.0-brightgreen)](https://github.com/ai-winter/ros_motion_planning/blob/master/src/core/global_planner/evolutionary_planner/src/ga.cpp) | ![ga_ros.gif](assets/ga_ros.gif) |[Adaptation in Natural and Artificial Systems](https://ieeexplore.ieee.org/book/6267401)
| **PSO** | [![Status](https://img.shields.io/badge/done-v1.0-brightgreen)](https://github.com/ai-winter/ros_motion_planning/blob/master/src/core/global_planner/evolutionary_planner/src/pso.cpp) | ![pso_ros.gif](assets/pso_ros.gif) |[Particle Swarm Optimization](https://ieeexplore.ieee.org/document/488968)
| **ACO** | [![Status](https://img.shields.io/badge/done-v1.0-brightgreen)](https://github.com/ai-winter/ros_motion_planning/blob/master/src/core/global_planner/evolutionary_planner/src/aco.cpp) | ![aco_ros.gif](assets/aco_ros.gif) |[Ant Colony Optimization: A New Meta-Heuristic](http://www.cs.yale.edu/homes/lans/readings/routing/dorigo-ants-1999.pdf)
| **GA** | [![Status](https://img.shields.io/badge/done-v1.0-brightgreen)](https://github.com/ai-winter/ros_motion_planning/blob/master/src/core/global_planner/evolutionary_planner/src/ga.cpp) | ![ga_ros.gif](assets/ga_ros.gif) |[Adaptation in Natural and Artificial Systems](https://ieeexplore.ieee.org/book/6267401)
| **PSO** | [![Status](https://img.shields.io/badge/done-v1.0-brightgreen)](https://github.com/ai-winter/ros_motion_planning/blob/master/src/core/global_planner/evolutionary_planner/src/pso.cpp) | ![pso_ros.gif](assets/pso_ros.gif) |[Particle Swarm Optimization](https://ieeexplore.ieee.org/document/488968)

### Local Planner

Expand Down
1 change: 1 addition & 0 deletions src/core/global_planner/graph_planner/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ add_library(${PROJECT_NAME}
src/voronoi.cpp
src/theta_star.cpp
src/lazy_theta_star.cpp
src/s_theta_star.cpp
src/hybrid_a_star.cpp
)

Expand Down
18 changes: 2 additions & 16 deletions src/core/global_planner/graph_planner/include/lazy_theta_star.h
Original file line number Diff line number Diff line change
@@ -1,17 +1,3 @@
/***********************************************************
*
* @file: lazy_theta_star.h
* @breif: Contains the lazy Theta* planner class
* @author: Wu Maojia, Yang Haodong
* @update: 2023-10-1
* @version: 1.3
*
* Copyright (c) 2023, Wu Maojia
* All rights reserved.
* --------------------------------------------------------
*
**********************************************************/

/**
* *********************************************************
*
Expand All @@ -21,9 +7,9 @@
* @date: 2023-10-01
* @version: 1.3
*
* Copyright (c) 2024, Wu Maojia, Yang Haodong.
* Copyright (c) 2024, Wu Maojia, Yang Haodong.
* All rights reserved.
*
*
* --------------------------------------------------------
*
* ********************************************************
Expand Down
82 changes: 82 additions & 0 deletions src/core/global_planner/graph_planner/include/s_theta_star.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
/**
* *********************************************************
*
* @file: s_theta_star.h
* @brief: Contains the S-Theta* planner class
* @author: Wu Maojia
* @date: 2024-3-9
* @version: 1.0
*
* Copyright (c) 2024, Wu Maojia, Yang Haodong.
* All rights reserved.
*
* --------------------------------------------------------
*
* ********************************************************
*/
#ifndef S_THETA_STAR_H
#define S_THETA_STAR_H

#include <vector>
#include <queue>
#include "theta_star.h"

namespace global_planner
{
/**
* @brief Class for objects that plan using the S-Theta* algorithm
*/
class SThetaStar : public ThetaStar
{
public:
/**
* @brief Construct a new SThetaStar object
* @param nx pixel number in costmap x direction
* @param ny pixel number in costmap y direction
* @param resolution costmap resolution
*/
SThetaStar(int nx, int ny, double resolution);

/**
* @brief S-Theta* implementation
* @param global_costmap global costmap
* @param start start node
* @param goal goal node
* @param path optimal path consists of Node
* @param expand containing the node been search during the process
* @return true if path found, else false
*/
bool plan(const unsigned char* global_costmap, const Node& start, const Node& goal, std::vector<Node>& path,
std::vector<Node>& expand);

protected:
/**
* @brief update the g value of child node
* @param parent
* @param child
* @param alpha
*/
void _updateVertex(const Node& parent, Node& child, const double alpha);

/**
* @brief Get the deviation cost
* @param parent
* @param child
* @param goal
* @return deviation cost
*/
double _alpha(const Node& parent, const Node& child, const Node& goal);

/**
* @brief Get the Euclidean distance between two nodes
* @param node current node
* @param goal goal node
* @return Euclidean distance
*/
double _getDistance(const Node& node, const Node& goal);

private:
const double pi_ = std::acos(-1); // pi
};
} // namespace global_planner
#endif
3 changes: 3 additions & 0 deletions src/core/global_planner/graph_planner/src/graph_planner.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@
#include "voronoi.h"
#include "theta_star.h"
#include "lazy_theta_star.h"
#include "s_theta_star.h"
#include "hybrid_a_star.h"

PLUGINLIB_EXPORT_CLASS(graph_planner::GraphPlanner, nav_core::BaseGlobalPlanner)
Expand Down Expand Up @@ -127,6 +128,8 @@ void GraphPlanner::initialize(std::string name)
g_planner_ = new global_planner::ThetaStar(nx_, ny_, resolution_);
else if (planner_name_ == "lazy_theta_star")
g_planner_ = new global_planner::LazyThetaStar(nx_, ny_, resolution_);
else if (planner_name_ == "s_theta_star")
g_planner_ = new global_planner::SThetaStar(nx_, ny_, resolution_);
else if (planner_name_ == "hybrid_a_star")
{
bool is_reverse; // whether reverse operation is allowed
Expand Down
179 changes: 179 additions & 0 deletions src/core/global_planner/graph_planner/src/s_theta_star.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,179 @@
/**
* *********************************************************
*
* @file: s_theta_star.cpp
* @brief: Contains the S-Theta* planner class
* @author: Wu Maojia
* @date: 2024-3-9
* @version: 1.0
*
* Copyright (c) 2024, Wu Maojia, Yang Haodong.
* All rights reserved.
*
* --------------------------------------------------------
*
* ********************************************************
*/
#include "s_theta_star.h"

namespace global_planner
{
/**
* @brief Construct a new SThetaStar object
* @param nx pixel number in costmap x direction
* @param ny pixel number in costmap y direction
* @param resolution costmap resolution
*/
SThetaStar::SThetaStar(int nx, int ny, double resolution) : ThetaStar(nx, ny, resolution)
{
factor_ = 0.35;
};

/**
* @brief S-Theta* implementation
* @param global_costmap global costmap
* @param start start node
* @param goal goal node
* @param path optimal path consists of Node
* @param expand containing the node been search during the process
* @return true if path found, else false
*/
bool SThetaStar::plan(const unsigned char* global_costmap, const Node& start, const Node& goal, std::vector<Node>& path,
std::vector<Node>& expand)
{
// initialize
costs_ = global_costmap;
path.clear();
expand.clear();

// closed list

// open list and closed list
std::priority_queue<Node, std::vector<Node>, Node::compare_cost> open_list;
std::unordered_map<int, Node> closed_list;

open_list.push(start);

// get all possible motions
const std::vector<Node> motion = Node::getMotion();

// main process
while (!open_list.empty())
{
// pop current node from open list
Node current = open_list.top();
open_list.pop();

// current node does not exist in closed list
if (closed_list.find(current.id_) != closed_list.end())
continue;

closed_list.insert(std::make_pair(current.id_, current));
expand.push_back(current);

// goal found
if (current == goal)
{
path = _convertClosedListToPath(closed_list, start, goal);
return true;
}

// explore neighbor of current node
for (const auto& m : motion)
{
// explore a new node
// path 1

Node node_new = current + m; // add the x_, y_, g_
node_new.h_ = _getDistance(node_new, goal);
node_new.id_ = grid2Index(node_new.x_, node_new.y_);
node_new.pid_ = current.id_;

// current node do not exist in closed list
if (closed_list.find(node_new.id_) != closed_list.end())
continue;

double alpha = 0.0;

// get the coordinate of parent node
Node parent;
parent.id_ = current.pid_;
index2Grid(parent.id_, parent.x_, parent.y_);

// update g value
auto find_parent = closed_list.find(parent.id_);
if (find_parent != closed_list.end())
{
parent = find_parent->second;
alpha = _alpha(parent, node_new, goal);
// update g
node_new.g_ = current.g_ + _getDistance(parent, node_new) + alpha;
}

// next node hit the boundary or obstacle
if ((node_new.id_ < 0) || (node_new.id_ >= ns_)
|| (costs_[node_new.id_] >= lethal_cost_ * factor_ && costs_[node_new.id_] >= costs_[current.id_]))
continue;

if (find_parent != closed_list.end())
{
_updateVertex(parent, node_new, alpha);
}

// add node to open list
open_list.push(node_new);
}
}

return false;
}

/**
* @brief update the g value of child node
* @param parent
* @param child
* @param alpha
*/
void SThetaStar::_updateVertex(const Node& parent, Node& child, const double alpha){
// if (alpha == 0 || _lineOfSight(parent, child)){ // "alpha == 0" will cause penetration of obstacles
if (_lineOfSight(parent, child)){
// path 2
double new_g = parent.g_ + _getDistance(parent, child) + alpha;
if (new_g < child.g_){
child.g_ = new_g;
child.pid_ = parent.id_;
}
}
}

/**
* @brief Get the deviation cost
* @param parent
* @param child
* @param goal
* @return deviation cost
*/
double SThetaStar::_alpha(const Node& parent, const Node& child, const Node& goal)
{
double d_qt = _getDistance(parent, child);
double d_qg = _getDistance(parent, goal);
double d_tg = _getDistance(child, goal);
double cost;
double value = (d_qt * d_qt + d_qg * d_qg - d_tg * d_tg) / (2 * d_qt * d_qg);
if (value <= -1.0) cost = pi_;
else if (value >= 1.0) cost = 0.0;
else cost = std::acos(value);
return cost;
}

/**
* @brief Get the Euclidean distance between two nodes
* @param node current node
* @param goal goal node
* @return Euclidean distance
*/
double SThetaStar::_getDistance(const Node& node, const Node& goal)
{
return std::hypot(node.x_ - goal.x_, node.y_ - goal.y_);
}
} // namespace global_planner
3 changes: 3 additions & 0 deletions src/sim_env/launch/include/navigation/move_base.launch.xml
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@
or arg('global_planner')=='d_star_lite'
or arg('global_planner')=='theta_star'
or arg('global_planner')=='lazy_theta_star'
or arg('global_planner')=='s_theta_star'
or arg('global_planner')=='hybrid_a_star'
)" />
<param name="GraphPlanner/planner_name" value="$(arg global_planner)"
Expand All @@ -53,6 +54,7 @@
or arg('global_planner')=='d_star_lite'
or arg('global_planner')=='theta_star'
or arg('global_planner')=='lazy_theta_star'
or arg('global_planner')=='s_theta_star'
or arg('global_planner')=='hybrid_a_star'
)" />
<rosparam file="$(find sim_env)/config/planner/graph_planner_params.yaml" command="load"
Expand All @@ -66,6 +68,7 @@
or arg('global_planner')=='d_star_lite'
or arg('global_planner')=='theta_star'
or arg('global_planner')=='lazy_theta_star'
or arg('global_planner')=='s_theta_star'
or arg('global_planner')=='hybrid_a_star'
)" />

Expand Down
4 changes: 2 additions & 2 deletions src/sim_env/launch/include/robots/start_robots.launch.xml
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,8 @@
<arg name="agent_number" default="1" />
<arg name="agent_id" default="1" />
<arg name="robot1_type" value="turtlebot3_waffle" />
<arg name="robot1_global_planner" value="a_star" />
<arg name="robot1_local_planner" value="mpc" />
<arg name="robot1_global_planner" value="s_theta_star" />
<arg name="robot1_local_planner" value="pid" />
<arg name="robot1_x_pos" value="0.0" />
<arg name="robot1_y_pos" value="0.0" />
<arg name="robot1_z_pos" value="0.0" />
Expand Down
Loading

0 comments on commit d211d0d

Please sign in to comment.