Final Project

A MuSHR car drives through a hallway with a path planned in front of it.

Before you get started, please view # Setting Jetson Performance in the lab guide for information on maximizing the performance of the Jetson Orin. Note that this will drain the battery faster.

Overview

Throughout this quarter, you’ve implemented each part of the sense, plan, act paradigm for autonomous robotic control. This final project will be a stress test of sorts involving all the work you’ve done so far. You’ll need to test your car’s ability to localize, plan, and follow paths in a new environment. If your previous projects were implemented efficiently and correctly, this project will likely not require any adjustments to your code.

Please complete this assignment with the same groups from projects 1-4.

Demo Due: Lab Section on June 5, 2025.

Writeup Due: 11:59 PM on June 6, 2025.

Getting Started

You’ll need to update a few files to easily get started on this project, which can be obtained by pulling from our starter repository. If you followed the instructions in Project 3 to add an upstream remote, then you can just run the following:

$ git pull upstream main

Your Task

We are providing you with code to enable planning between multiple waypoints. Your job will be to make your car follow a multi-waypoint path we provide.

How To: Driving with Multiple Waypoints

You can use similar instructions from Project 4 to run each part of your code on the car, also specifying the number of waypoints. These commands are below. Run each of these commands on the car in a separate terminal for each one.

As with previous projects, we’ve compiled all the commands to run in a tmux session. Instead of running each roslaunch command, you can use tmux with the following script on the car.
You will still need to open the visualizer in Rviz on your workstation manually.

$ cd ~
$ cd catkin_ws/src/mushr478/final
$ ./1_car_launch_ros_session.sh

Below we go through the commands that are ran in the .sh file with additional instructions.
Note: You will need to change the .sh shell script to test out your implementations.

$ roslaunch mushr_base teleop.launch
$ rosrun map_server map_server $(rospack find cse478)/maps/002.yaml
$ roslaunch localization particle_filter_sim.launch use_namespace:=true publish_tf:=true tf_prefix:="car/"
$ roslaunch control controller.launch type:=mpc tf_prefix:="car/"
$ roslaunch planning planner_car.launch num_vertices:=1000 connection_radius:=20 curvature:=1 num_goals:=8
$ # For extra credit only: See details below
$ rosparam load $(rospack find control)/config/costmap_params.yaml /costmap_node/costmap && rosrun costmap_2d costmap_2d_node _name:=costmap_node

Then, on your workstation computer, run the following commands to start RViz and connect it to your car.

$ export ROS_MASTER_URI=http://<robot_hostname>:11311
$ rviz

Now, place your car at the start point (marked with tape in 002) and use the 2d Pose Estimate button to initialize your particle filter. Finally, after ensuring that your roadmap has finished construction, run the command below to specify a target for your car. Hold down the right bumper on your controller to allow the car to be controlled autonomously.

$ roscd planning && cd src/planning && python3 multi_goal_pub.py

Hints

Below are some suggestions that can help you if you get stuck.

Processing Power

One of the limitations with the car is its small, low-powered computer. Some tasks, such as planning long paths, might take unreasonably long for the car to complete. Take a look at the parameters you use when running the planner node to help speed up the planning process. As an alternative option, you can run some nodes on the workstation instead of the car. Teleop, localization, and controller should be run directly on the car, but others can be offloaded to the workstation (note that these will not work from a virtual machine due to the networking issues discussed earlier, and may suffer from network reliability issues).

Hardware Tuning

You may find that your car’s motions don’t match up with the controls that are sent to it. To fix this, you can do some hardware tuning to make the car’s motion line up better with expected values. There is a simple process for tuning these values, and a tutorial is available on the MuSHR website.

Launch File

There are a lot of things that need to be run repeatedly on the car. If you want, you can simplify the process of starting all your code by creating a launch file that will run all the nodes you need at once. Use the existing launch files as a template to include all the launch files you need. Place your launch file in any package’s launch/ directory. Use the roslaunch docs as a reference for additional details on launch file syntax.

Additional Parameters

You may find that some parameters should be changed beyond the parameters included in our parameters.yaml files. For example, some controller types have additional parameters which are found in the get_ros_params() function of controller_ros.py. These parameters currently use a default value, but you can override them by adding the parameter into your parameters.yaml file.

Extra Credit Sp25: Avoiding Unmapped Static obstacles

So far in this class, you’ve been able to run the robot using an MPC controller. However, we have only been using it to avoid obstacles in the mapped environment. Take some time to think about what is missing and how we can make it avoid obstacles that are unmapped! (Spoiler below)

Your MPC controller takes in a static map, more specifically an Occupancy Grid you provided through the map_server, to compute your collision costs.

To avoid obstacles that are unmapped, we will need to change the map to one that updates with new observations. More specifically, we will be using an existing ROS package costmap_2d that converts your LiDAR scans to be part of your occupancy grid.

We’ve already included the costmap_2d node in ./1_car_launch_ros_session. To make your MPC controller use the updating costmap, simply change the use_costmap parameter to true in control/config/parameters.yaml. We’ve already implemented a listener to listen to updates on the costmap for you.

You will need to tune the parameters in control/config/costmap_params.yaml. The total cost of a cell in a costmap is calculated from a set of layers that, together, define the whole costmap. The three layers that are most common (and used in the default parameters) and the associated documentation of all parameters are:

Note: Your controller by default should only compute collision costs with permissible areas (free space), everywhere else on the map has an equal collision cost. You may change the implementation such that the collision costs are weighted depending on the layer.

You may visualize the costmap in RViz as well. For reference, here is an example screenshot:

Costmap visualization in RViz

You will, of course, also have to tune the previous components to make sure your car is reactive enough to avoid all the obstacles.

To receive extra credit, you must complete the above multi-goal navigation task with obstacles in the scene. These obstacles will be placed at (approximately) same spot every time and your task is to finish the path without colliding with any obstacles.

We will also have a time trial competition between the teams. The teams that beat the best time so far while avoiding all obstacles receives a special prize (while supplies last & terms and conditions apply TM).

Tip: To increase the speed, change max_speed in planning/launch/planner_car.launch. The speed is in meters per seconds (m/s).

Note that the car is further restricted by the ERPM gains in the VESC settings.

vim ./catkin_ws/src/mushr/mushr_base/vesc/vesc_main/config/racecar-uw-nano/vesc.yaml

Relevant paramters:

speed_to_erpm_gain:
  speed_min:
  speed_max:

Consult a TA before you change these parameters

Deliverables

Using GitLab, you will submit a bag file of your car completing the assigned task, as well as a writeup answering a few short questions. Use the command below to record your bag file. You should start the bag file recording before you set the 2d Nav Goal in RViz.

$ rosbag record /map /car/scan /car/particle_filter/inferred_pose /car/particle_filter/particles /tf /car/controller/path/poses /car/controller/real_path/poses /move_base_simple/goal /car/teleop/joy

Answer the following questions in final/README.md. Include your video and bag files in the final/ directory.

  1. What controller type did you choose to use for path following with multiple waypoints (pid, pp, mpc)? Why did you choose this controller type?
  2. What roadmap parameters did you use for planning (num_vertices, connection_radius, curvature)? Why did you choose these parameters?
  3. What was the most difficult part of making your code work with multiple waypoints?

Submission

As with the previous projects, you will use Git to submit your project (code, writeup and plots).

From your mushr478 directory, add any writeup files and changed code files. Commit those changes, then create a Git tag called submit-final. Pushing the tag is how we’ll know when your project is ready for grading.

$ cd ~/mushr_ws/src/mushr478/
$ git diff                             # See all your changes
$ git add .                            # Add all the changed files
$ git commit -m 'Finished Final Project!'  # Or write a more descriptive commit message
$ git push                             # Push changes to your GitLab repository
$ git tag submit-final                 # Create a tag named submit-final
$ git push --tags                      # Push the submit-final tag to GitLab