Autonomous Navigation

Initialize and operate MuSHRs out-of-the-box autonomous navigation stack!

Intermediate Tutorial | Expected duration is 30 minutes

By: Markus Schiffer & Sidharth Talia



This tutorial will teach you how to set up and operate MuSHR’s baseline autonomous navigation stack. By the end of the tutorial, the car should be able to autonomously navigate around known obstacles on a known map.


Note on dependecies:

This tutorial is designed for the python3 ROS noetic image. It assumes that this accounts for any dependencies needed.

If you are operating in simulation and use the particle filter for localization, we do not recommend testing with the sandbox.yaml default map as the localization system struggles in an open environment (all positions look the same!). See the quickstart tutorial for how to change maps.

At the highest level MuSHR’s navigation stack consists of three principal components:

  1. Receding Horizon Controller (RHC) Node: This node is responsible for motion planning and generating controls(steering, speed) for the car. The implementation shipped with the car uses a Model Predictive Controller (MPC) to generate control signals which are sent to the car’s motor controller (VESC).

  2. Localization Node: In order for the controller to know where it is, and therefore also whether it is in the proximity of known obstacles in the map, it must know its location. Solving this problem is called “localization”. The Localization Node is implemented using a method called Particle Filtering which relies primarily on a data stream from the laser scanner.

  3. Planner Node This node generates a plan that the RHC controller will follow. The planner does not consider dynamic obstacles when constructing its plan; rather it uses a static map of the environment. It chains the car’s motion primitives together into a plan, using a search algorithm (such as A*).

This tutorial does not cover either the theory or the inner workings of the Model Predictive Control, Particle Filter, and A* search.

Installing the Navigation Stack

Note: The docker container may already have the required packages pre-installed. These instructions have been provided in case you need to reinstall the packages from scratch (for example, you need to reset environment).

If you’re setting up autonomous navigation on the MuSHR car (not just the sim), ensure the on-board computer (either a jetson nano or a jetson Xavier NX) is connected to the internet. You may have to connect your system to a monitor to do this as the default setting is for the on-board computer to act as a hotspot. Once you’ve connected your system to the internet, you’ll need to find the IP address of the car,

On the car’s computer, run the following command:

$ ifconfig

Find the inet addr line:

wlp0s20f3 Link encap:Ethernet  HWaddr ABCDCEGFJOSDHOHSOGHOS  
          inet addr: --> This is the RACECAR_IP

From your desktop/laptop, SSH into your racecar.

$ ssh robot@RACECAR_IP

If you prefer, these steps can also be done with a mouse, keyboard, and monitor plugged into the MuSHR car, using the Ubuntu UI.

Download the packages for the RHC, Particle Filter and Global Planner:

Note: You also need to download all dependencies for the mush_rhc.

# Go to your catkin workspace
$ cd ~/catkin_ws/src
# Clone the RHC node
$ git clone
# Clone the Particle Filter node
$ git clone
# Install [SBPL]( for the global planner
$ sudo apt-get install ros-noetic-sbpl
# Install the Global Planner (this is for Jetson Xavier NX or sim use)
$ git clone
# If you're using the jetson nano, use the mushr_gprm planner:
$ git clone
# Make
$ cd ~/catkin_ws && catkin_make


The reason why there are two planners (mushr_gp and mushr_gprm) is because mushr_gp is too resource intensive to be run on the jetson nano 4GB variant. However, if the desktop/laptop computer remains connected and in range of the MuSHR car, you can run mushr_gp on the computer instead as they share the same ROS master. If you need the planner to run on the jetson nano, we recommend using the mushr_gprm package. For the Jetson Xavier NX or when running on the sim exclusively, mushr_gp will work. Both repositories contain ROS packages that reproduce the desired functionality. You need only concern yourself with each package’s launch files to use them effectively. You can find the launch files in each package’s launch directory.

Starting the navigation stack

We will now launch the navigation stack on the robot. To learn more about effective operation and experimentation strategies with the MuSHR car, visit the workflow tutorial. We suggest using tmux to manage multiple ROSlaunch sessions. tmux allows operating multiple tabs within the same ssh connection.

Starting the docker image:

Note: If you’re operating on the robot, you’ll need to SSH into it. If you’re operating in sim, you can just open a new terminal and skip the tmux related commands.

As we are running the entire system from docker, the first thing to do is to start the docker image. To do this, execute:

$ mushr_noetic

Once you’ve ssh’d into your robot and started the docker image, activate tmux:

$ tmux

Then, to create two vertical panes, type ctrl+b (ctrl and b) then % (or alternatively " to split horizontally). You can use ctrl+b then your left and right arrow keys to switch between windows. We will need four panes for this tutorial on the real car, and three on the simulator.

Note: If the map you are using is very large map (>100x100 meters)–size inclusive of the unknown region–then the controller will be stuck sampling points. Save yourself the headache and shrink/crop your map before you begin. (Gimp is a good tool for this job.

You can navigate tmux panes by typing ctrl+b then [arrow key] (or simply make new terminal tabs and avoid tmux altogether if you’re doing this in sim).

If you’re using seperate tabs instead of tmux, make sure they are all connected to the running docker image. You can do this with the following steps: First, we need the docker’s CONTAINER ID. Execute the following command:

$ docker ps

Expected output:

CONTAINER ID   IMAGE                COMMAND   CREATED          STATUS          PORTS     NAMES
189781eba455   mushr/mushr:x86_64   "bash"    52 minutes ago   Up 52 minutes             install_mushr_noetic_run_a85227ee45d5

the CONTAINER ID can now be used to enter the docker from a new tab with the following command:

docker exec -it CONTAINER_ID bash    
where you’ll replace CONTAINER_ID with your container ID.

Starting the system

Any autonomy related task will require data from sensors and some way of sending the control commands to the hardware. In addition, manual control may also be required for safety reasons, or for the purposes of generating a map of an area via manual operation of the car. All these basic features are handled by a single launch file called teleop.launch

On the MuSHR car:

$ roslaunch mushr_base teleop.launch

Now launch the map_server:

# Make sure mushr/mushr_base/mushr_base/mushr_base/maps has your map 
# and mushr_base/launch/includes/map_server.launch is set to your map
$ roslaunch mushr_base map_server.launch

Now, we will launch the localization node:

$ roslaunch mushr_pf real.launch
Wait for the node to initialize:

$ Vesc callback called for first time....
$ Initialization complete

Then activate the RHC node,

$ roslaunch mushr_rhc real.launch

Wait for the code to initialize

Control Node Initialized

Finally, launch the global planner node (use the planner appropriate for your system):

$ roslaunch mushr_gp real.launch
Or alternatively
$ roslaunch mushr_gprm real.launch

Wait for it to initialize:

[ INFO] [1658309032.479218601]: Planner ROS node constructed. Need to initialize state
[ INFO] [1658309032.644907822]: Resizing the map
[ INFO] [1658309033.229219658]: Environment initialized
[ INFO] [1658309033.261994212]: Updated costmap

In simulation:

When running in simulation, the steps are more or less the same as those for the real car, with the difference being that

  1. We use the mushr_sim package to start the teleop.launch
  2. Absence of the particle filter (not necessary in simulation)
  3. Differences in the names of the launch files (instead of real.launch we use sim.launch)
$ roslaunch mushr_sim teleop.launch

Then activate the RHC node,

$ roslaunch mushr_rhc sim.launch

Wait for the code to initialize

Control Node Initialized

Finally, launch the global planner node (use the planner appropriate for your system):

$ roslaunch mushr_gp sim.launch
Or alternatively
$ roslaunch mushr_gprm sim.launch

Wait for it to initialize:

[ INFO] [1658309032.479218601]: Planner ROS node constructed. Need to initialize state
[ INFO] [1658309032.644907822]: Resizing the map
[ INFO] [1658309033.229219658]: Environment initialized
[ INFO] [1658309033.261994212]: Updated costmap

Running the navigation stack

To operate the navigation stack, we will use foxglove to send pose targets to the vehicle. The quickstart tutorial tutorial goes over how to use foxglove with the MuSHR stack. When operating in the real world, the pose estimate of the car may be incorrect. You can correct this by providing the particle filter with the correct pose estimate using the Set Pose Estimate button on the bottom right of the foxglove window and then using the button to publish clicked points.

Note: When publishing a pose, the pose will correspond to the pose at the tip of the arrow and not the base of the arrow. Set the pose accordingly.

In simulation, you may want to set the starting pose of the car at a certain point. To do this, click the Set Pose button on the bottom right of the foxglove window and use “Publish point” to publish a point or “Publish Pose” to publish a pose for the car.:

To set a pose target, click on ‘Set Goal’ button on the bottom right of the foxglove window and use “Publish pose” to publish a goal pose for the car:

The following video demonstrates the process of starting and running the stack in sim. In the real world, the difference would be the launch files being executed, and possibly the requirement to set the initial pose estimate.

That’s it, now you have basic autonomous navigation!


If you plan to use any part of the the MuSHR platform (including tutorials, codebase, or hardware instructions) for a project or paper, please cite MuSHR: A Low-Cost, Open-Source Robotic Racecar for Education and Research.

 title={{MuSHR}: A Low-Cost, Open-Source Robotic Racecar for Education and Research},
 author={Srinivasa, Siddhartha S. and Lancaster, Patrick and Michalove, Johan and Schmittle, Matt and Summers, Colin and Rockett, Matthew and Smith, Joshua R. and Chouhury, Sanjiban and Mavrogiannis, Christoforos and Sadeghi, Fereshteh},