ROS与Navigation-编写自定义A*算法全局路径规划教程
向ROS中添加一个新的全局路径规划器,新的路径规划器必须遵守nav_core包中定义的nav_core::BaseGlobalPlanner的C++接口。一旦编写了全局路径规划器,它必须作为插件添加到ROS中,以便它可以被move_base包使用。本例程以turtlebot作为机器人平台,部署A*路径规划算法。
1.创建新的package
cd catkin_ws/src
catkin_create_pkg relaxed_astar nav_core roscpp rospy std_msgs
2.进入catkin_ws/src/relaxed_astar/src目录下,创建RAstar_ros.h文件以及RAstar_ros.cpp文件(代码源文件地址为https://github.com/coins-lab/relaxed_astar 下面我也会给出)
该目录下打开终端,输入编辑命令
gedit RAstar_ros.h
将以下代码复制到文件中
/* iPath: A C++ Library of Intelligent Global Path Planners for Mobile Robots with ROS Integration.
* Website: http://www.iroboapp.org/index.php?title=IPath
* Contact:
*
* Copyright (c) 2014
* Owners: Al-Imam University/King AbdulAziz Center for Science and Technology (KACST)/Prince Sultan University
* All rights reserved.
*
* License Type: GNU GPL
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netdb.h>
#include <string>
/** include ros libraries**********************/
#include <ros/ros.h>
#include <actionlib/client/simple_action_client.h>
#include <move_base_msgs/MoveBaseAction.h>
#include <geometry_msgs/Twist.h>
#include <geometry_msgs/PoseStamped.h>
#include <geometry_msgs/PoseWithCovarianceStamped.h>
#include <move_base_msgs/MoveBaseGoal.h>
#include <move_base_msgs/MoveBaseActionGoal.h>
#include "sensor_msgs/LaserScan.h"
#include "sensor_msgs/PointCloud2.h"
#include <nav_msgs/Odometry.h>
#include <nav_msgs/OccupancyGrid.h>
#include <nav_msgs/Path.h>
#include <nav_msgs/GetPlan.h>
#include <tf/tf.h>
#include <tf/transform_datatypes.h>
#include <tf/transform_listener.h>
/** ********************************************/
#include <boost/foreach.hpp>
//#define forEach BOOST_FOREACH
/** for global path planner interface */
#include <costmap_2d/costmap_2d_ros.h>
#include <costmap_2d/costmap_2d.h>
#include <nav_core/base_global_planner.h>
#include <geometry_msgs/PoseStamped.h>
#include <angles/angles.h>
//#include <pcl_conversions/pcl_conversions.h>
#include <base_local_planner/world_model.h>
#include <base_local_planner/costmap_model.h>
#include <set>
using namespace std;
using std::string;
#ifndef RASTAR_ROS_CPP
#define RASTAR_ROS_CPP
/**
* @struct cells
* @brief A struct that represents a cell and its fCost.
*/
struct cells {
int currentCell;
float fCost;
};
namespace RAstar_planner {
class RAstarPlannerROS : public nav_core::BaseGlobalPlanner {
public:
RAstarPlannerROS (ros::NodeHandle &); //this constructor is may be not needed
RAstarPlannerROS ();
RAstarPlannerROS(std::string name, costmap_2d::Costmap2DROS* costmap_ros);
ros::NodeHandle ROSNodeHandle;
/** overriden classes from interface nav_core::BaseGlobalPlanner **/
void initialize(std::string name, costmap_2d::Costmap2DROS* costmap_ros);
bool makePlan(const geometry_msgs::PoseStamped& start,
const geometry_msgs::PoseStamped& goal,
std::vector<geometry_msgs::PoseStamped>& plan
);
void getCorrdinate (float& x, float& y);
int convertToCellIndex (float x, float y);
void convertToCoordinate(int index, float& x, float& y);
bool isCellInsideMap(float x, float y);
void mapToWorld(double mx, double my, double& wx, double& wy);
vector<int> RAstarPlanner(int startCell, int goalCell);
vector<int> findPath(int startCell, int goalCell, float g_score[]);
vector<int> constructPath(int startCell, int goalCell, float g_score[]);
float calculateHCost(int cellID, int goalCell){
int x1=getCellRowID(goalCell);
int y1=getCellColID(goalCell);
int x2=getCellRowID(cellID);
int y2=getCellColID(cellID);
return abs(x1-x2)+abs(y1-y2);
//return min(abs(x1-x2),abs(y1-y2))*sqrt(2) + max(abs(x1-x2),abs(y1-y2))-min(abs(x1-x2),abs(y1-y2));
}
void addNeighborCellToOpenList(multiset<cells> & OPL, int neighborCell, int goalCell, float g_score[]);
vector <int> findFreeNeighborCell (int CellID);
bool isStartAndGoalCellsValid(int startCell,int goalCell);
float getMoveCost(int CellID1, int CellID2);
float getMoveCost(int i1, int j1, int i2, int j2);
bool isFree(int CellID); //returns true if the cell is Free
bool isFree(int i, int j);
int getCellIndex(int i,int j) //get the index of the cell to be used in Path
{
return (i*width)+j;
}
int getCellRowID(int index)//get the row ID from cell index
{
return index/width;
}
int getCellColID(int index)//get colunm ID from cell index
{
return index%width;
}
float originX;
float originY;
float resolution;
costmap_2d::Costmap2DROS* costmap_ros_;
double step_size_, min_dist_from_robot_;
costmap_2d::Costmap2D* costmap_;
//base_local_planner::WorldModel* world_model_;
bool initialized_;
int width;
int height;
};
};
#endif
重新输入编辑命令:
gedit RAstar_ros.cpp
复制如下代码到该文件中:
/* iPath: A C++ Library of Intelligent Global Path Planners for Mobile Robots with ROS Integration.
* Website: http://www.iroboapp.org/index.php?title=IPath
* Contact:
*
* Copyright (c) 2014
* Owners: Al-Imam University/King AbdulAziz Center for Science and Technology (KACST)/Prince Sultan University
* All rights reserved.
*
* License Type: G