ROS中make_plan服务的使用

路径规划:从一个点到另一个点,规划出最优的路线。用到service :make_plan (nav_msgs/GetPlan) 
服务名为move_base_node/make_plan 
nav_msgs/GetPlan api:

 # Get a plan from the current position to the goal Pose 

# The start pose for the plan
geometry_msgs/PoseStamped start

# The final pose of the goal position
geometry_msgs/PoseStamped goal

# If the goal is obstructed, how many meters the planner can 
# relax the constraint in x and y before failing. 
float32 tolerance
---
nav_msgs/Path plan

Compact Message Definition
geometry_msgs/PoseStamped start
geometry_msgs/PoseStamped goal
float32 tolerance
nav_msgs/Path plan

现在学习如何使用 
在工作空间新建package navigation_example

cd ~/catkin_ws/src
catkin_create_pkg navigation_example std_msgs rospy roscpp tf actionlib

CMakeList.txt 中的find_package如下

find_package(catkin REQUIRED COMPONENTS
  actionlib
  roscpp
  rospy
  std_msgs
  tf
)

在src目录下新建make_plan.cpp

/*
 * make_plan.cpp
 *
 *  Created on: Aug 10, 2016
 *      Author: unicorn
 */
//路线规划代码
#include <ros/ros.h>
#include <nav_msgs/GetPlan.h>
#include <geometry_msgs/PoseStamped.h>
#include <string>
#include <boost/foreach.hpp>
#define forEach BOOST_FOREACH
void fillPathRequest(nav_msgs::GetPlan::Request &request)
{
request.start.header.frame_id ="map";
request.start.pose.position.x = 12.378;//初始位置x坐标
request.start.pose.position.y = 28.638;//初始位置y坐标
request.start.pose.orientation.w = 1.0;//方向
request.goal.header.frame_id = "map";
request.goal.pose.position.x = 18.792;//终点坐标
request.goal.pose.position.y = 29.544;
request.goal.pose.orientation.w = 1.0;
request.tolerance = 0.5;//如果不能到达目标,最近可到的约束
}
//路线规划结果回调
void callPlanningService(ros::ServiceClient &serviceClient, nav_msgs::GetPlan &srv)
{
// Perform the actual path planner call
//执行实际路径规划器
if (serviceClient.call(srv)) {
//srv.response.plan.poses 为保存结果的容器,遍历取出
if (!srv.response.plan.poses.empty()) {
forEach(const geometry_msgs::PoseStamped &p, srv.response.plan.poses) {
ROS_INFO("x = %f, y = %f", p.pose.position.x, p.pose.position.y);
}
}
else {
ROS_WARN("Got empty plan");
}
}
else {
ROS_ERROR("Failed to call service %s - is the robot moving?",
serviceClient.getService().c_str());
}
}

int main(int argc, char** argv)
{
ros::init(argc, argv, "make_plan_node");
ros::NodeHandle nh;
// Init service query for make plan
//初始化路径规划服务,服务名称为"move_base_node/make_plan"
std::string service_name = "move_base_node/make_plan";
//等待服务空闲,如果已经在运行这个服务,会等到运行结束。
while (!ros::service::waitForService(service_name, ros::Duration(3.0))) {
ROS_INFO("Waiting for service move_base/make_plan to become available");
}
/*初始化客户端,(nav_msgs/GetPlan)
Allows an external user to ask for a plan to a given pose from move_base without causing move_base to execute that plan.
允许用户从move_base 请求一个plan,并不会导致move_base 执行此plan
*/ 
ros::ServiceClient serviceClient = nh.serviceClient<nav_msgs::GetPlan>(service_name, true);
if (!serviceClient) {
ROS_FATAL("Could not initialize get plan service from %s",
serviceClient.getService().c_str());
return -1;
}
nav_msgs::GetPlan srv;
//请求服务:规划路线
fillPathRequest(srv.request);
if (!serviceClient) {
ROS_FATAL("Persistent service connection to %s failed",
serviceClient.getService().c_str());
return -1;
}
ROS_INFO("conntect to %s",serviceClient.getService().c_str());
callPlanningService(serviceClient, srv);
}

CMakeList中添加

add_executable(make_plan src/make_plan.cpp)
 target_link_libraries(make_plan
   ${catkin_LIBRARIES}
 )

编译运行:

cd ~/catkin_ws
catkin_make
source devel/setup.bash
rosrun navigation_example make_plan

运行结果:

1.

2.

 参考:

https://blog.csdn.net/yiranhaiziqi/article/details/52891312

https://blog.csdn.net/u013158492/article/details/50483123

https://blog.csdn.net/jack_20/article/details/80292601

http://ask.zol.com.cn/x/5428696.html

原文地址:https://www.cnblogs.com/sea-stream/p/11129987.html