Ask Your Question

Is it possible for the global planner in move_base to copy an already made plan?

asked 2021-06-27 02:33:28 -0500

jmyazbeck gravatar image

updated 2021-06-28 09:32:25 -0500

I understand from the nav_core::BaseGlobalPLanner class that MakePlan() needs a goal, and a starting point and will fill the plan accordingly to whatever algorithm is being used.

In my case, I have an already made plan that is being sent from the other framework I am working with (Isaac SDK) that I would like to pass on to move_base so it can be, in the end, processed by the local planner. Is there a way to give the global planner an already made plan or have MakePlan() copy the plan available by Isaac?

I am mainly interested in using only the local planner.

A step by step to the answer can be found here.

edit retag flag offensive close merge delete

1 Answer

Sort by » oldest newest most voted

answered 2021-06-27 03:28:16 -0500

ParkerRobert gravatar image

You are actually right. The MakePlan() inside the nav_core::BaseGlobalPLanner is a virtual function which means that it expects the global planner plug in to override this function with its own MakePlan() function.

This is apparent if you look at the MakePlan() function in GlobalPlanner which is the default planner for ROS1:

If you examine the plan you will notice that it returns std::vector<geometry_msgs::PoseStamped>& planwhich is effectively a container of geometry_msgs::PoseStamped messages. PoseStamped messages contain headers, position and orientation information, The usual move_base/global_plan that is published is of type nav_msgs::Plan,, which are effectively these PoseStamped data arrows with a header. In layman terms, they are a bunch of arrows on the map which then constitute a global plan.

Therefore, to answer your question, as long as you are able to obtain a set of poses from the Isaac SDK you can package each pose into geometry_msgs::PoseStamped and and then further package all the poses of type geometry_msgs::PoseStamped into nav_msgs::Path. All other aspects of Move_base or even external packages will be able to work with the nav_msgs::Path data that you have published as the global plan. Cheers!

edit flag offensive delete link more


What I am able to do through Isaac is generate the plan as nav_msgs::Path. Is there a way to just send that to the local_planner directly (or through the global planner which should just copy it and send it)? If not I can try converting the plan to a std::vector<geometry_msgs::PoseStamped>... but then I don't really see how MakePlan() would just copy it

jmyazbeck gravatar image jmyazbeck  ( 2021-06-27 09:18:55 -0500 )edit

One suggestion would be to subscribe to the node that outputs the std::vector<geometry_msgs::posestamped> from the Isaac SDK, and set plan = the data of type std::vector<geometry_msgs::posestamped>. As you would see in move_base, the call to planner_->makePlan(), this happens 3 times.

In those instances, you can set the third argument, which is "global_plan" in 2 of the instances and just "plan" in one of the instances to be equal to the the data of type std::vector<geometry_msgs::posestamped> directly from the Isaac SDK.

I am personally not sure of how Isaac SDK interfaces with ROS but the most elegant way would be to make a service call to the Isaac SDK to obtain the data of type std::vector<geometry_msgs::posestamped> instead of using planner_->make_plan() in those 3 instances. In this way you override the usual way of making plans and use Isaac SDK's way instead

ParkerRobert gravatar image ParkerRobert  ( 2021-06-27 09:45:57 -0500 )edit

Mainly what happens is, Isaac appears as a node in ros that publishes and subscribes to topics... So I would have /plan coming from Isaac. When you say that you'd subscribe to the topic published by Isaac, which you recommend to be of type std::vector<geometry_msgs::PoseStamped> ... you're suggesting of doing that by editting the move_base code where the call planner_->makePlan() is happening? If I choose this way what would happen to the global_planner? Would it be bypassed? Or would I need to implement a global_planner of my own.

Regarding the more elegant suggestion, please if you could explain what you mean by "making a service call". Sorry, I am quite new to ROS in general, I really appreciate your guidance.

jmyazbeck gravatar image jmyazbeck  ( 2021-06-27 10:28:00 -0500 )edit

The how to is well explained here!

jmyazbeck gravatar image jmyazbeck  ( 2021-06-28 09:26:51 -0500 )edit

Yep it is well explained! The solution in this case shows you how to edit the global planner source code, so that when planner_->makePlan() is called the service call to your Isaac node is made

  1. Edit the header of the source code of the global_planner package (this is the default global planner used in ROS 1), to add the name of your service. For example in line 186, add ros::ServiceClient isaac_plan_client; At the top of this same file write: #​include <custom_package custom_serv.h="">
  2. Edit the cpp file to declare the service client, for example line 150 isaac_plan_client = n.serviceClient<custom_serv>("make_plan_isaac
ParkerRobert gravatar image ParkerRobert  ( 2021-06-28 10:22:36 -0500 )edit
  1. call the service: by putting these 3 lines. custom_package::custom_serv variable; = true;, returned_plan); Use returned_plan as the global plan. Here returned_plan should be of type std::vector<geometry_msgs::posestamped>
  2. In your Isaac node, create the service server with the same name "make_plan_isaac" and return the std::vector<geometry_msgs::posestamped> plan
ParkerRobert gravatar image ParkerRobert  ( 2021-06-28 10:33:35 -0500 )edit

I am almost done implementing it. I am getting this error if you have any idea what's happening

jmyazbeck gravatar image jmyazbeck  ( 2021-06-29 10:56:55 -0500 )edit

Your Answer

Please start posting anonymously - your entry will be published after you log in or create a new account.

Add Answer

Question Tools



Asked: 2021-06-27 02:33:28 -0500

Seen: 77 times

Last updated: Jun 28