ROS Resources: Documentation | Support | Discussion Forum | Index | Service Status | ros @ Robotics Stack Exchange
Ask Your Question

Revision history [back]

As Dimitri said, move_base uses three states PLANNING, CONTROLLING, and CLEARING. In the planning state, move_base invokes the global planner to get a valid plan, and in the controlling state, it passes the global plan to local planners to actuate controllers.

In my opinion there is no reason why the local planner can't use the last valid global plan to continue local motion while the global planner makes new global plan which is already happening continuously in another thread (controlled by planner_frequency). The mutual exclusion of state seems to be a self-imposed constraint.

I had the same problem, and my solution is this one-line hack in move_base.cpp:

//the move_base state machine, handles the control logic for navigation
switch(state_){
  //if we are in a planning state, then we'll attempt to make a plan
  case PLANNING:
    {
      boost::mutex::scoped_lock lock(planner_mutex_);
      runPlanner_ = true;
      planner_cond_.notify_one();
    }
    ROS_DEBUG_NAMED("move_base","Waiting for plan, in the planning state.");
    break;

  //if we're controlling, we'll attempt to find valid velocity commands
  case CONTROLLING:

Remove break;. This let the switch fall through to controlling when it's nominally in the planning state. In the controlling block, it executes according to the last global plan, which is what you need.

I tested this patch with Navfn and Carrot. This is definitely not an elegant solution. It is probably not even correct on the whole. But it works, and might be a good start to properly patch move_base to make the global and local planner truly work in parallel.

Btw, you can reduce the number of goals you send to move_base by thresholding with distance and time from last goal.