Lab 5 Lane Controller


The goal of this lab is for you to produce a node that keeps your Duckiebot in its lane. Note that this node already exists in the Duckietown code repo: feel free to look at it for inspiration but make sure that the node you turn in is your own. You do NOT need to perform any state checking in your node, you only need to accept the lane position message and publish the command message as described below. To accomplish this:

  1. Inspect the lane_controller_node as it runs in the Duckietown lane following demo. What does it subscribe to? What does it publish to? Which of these topics are necessary for control?
  2. Create a node that uses at least one PID controller (other controllers may be used if desired and some gains may be 0, see tips below) to keep the robot in its lane. It should subscribe and publish to topics found in the previous step as necessary to control the robot.
  3. Tune the gains for your controller(s) as needed. See tips below.
  4. Test your robot to see how many laps it can complete autonomously.


  1. The lane_pose topic provides two measures that may be of interest in controlling the robot: one to measure position within the lane and the other to measure angle relative to the lane. It is best to use error values for EACH of these dimensions in their own PID controllers and add them together to produce your final control signal.
  2. Think carefully about the signal received by the robot and the error you need to use for your controller.
  3. Think carefully about what you should control. Does the speed of your vehicle matter for lane following? Does the angular velocity?
  4. Your PID controller(s) may only use the P or PI components. If it works with fewer components it will still satisfy the requirements of this lab.
  5. This is a real robot with real hardware, so there will be errors in sensing. You may want to threshold (limit) the maximum/minimum errors given to your controller and/or the maximum control signal you will send. Be patient and work out what your robot is telling you versus what it should be doing.
  6. It is highly recommended to use ROS parameters to control the gains in your PID code. This way you can update the gains as the vehicle runs.
  7. Start your testing at the simplest part of your track: the straight sections. Tune your robot to work here first, then work on the turns.
  8. Take a look at the lane following demo launch file to see how Duckietown launch files are created. You will need a similar launch file here. You will need to turn off the Duckietown controller functionality but leave everything else on (see the line in red below). Optionally, you can also turn off the line detector, as in Lab 4, and run your Lab 4 code instead (blue line below). It should look something like this:

    <arg name="veh" default="$(env VEHICLE_NAME)"/>
    <arg name="ai_trafo_mode" default="cb" doc="'cb' for colo balance only; 'both' for color balance and linear trafo"/>
    <arg name="ai_interval" default="5" doc="interval with which the linear trafo gets updated. color balance is performed every second."/>
    <arg name="verbose" default="false"/>

    <!-- start Duckietown nodes -->
    <arg name="demo_name" value="lane_following"/>

    <!-- start basic args -->
    <include file="$(find duckietown_demos)/launch/master.launch">

        <!-- Basic arguments -->
        <arg name="veh" value="$(arg veh)"/>
        <arg name="demo_name" value="$(arg demo_name)"/>
        <arg name="param_file_name" value="default" />
        <arg name="visualization" value="true" />

        <!-- Finite state machine -->
        <arg name="fsm" value="true"/>
        <arg name="/fsm/logic_gate" value="false"/>

        <!-- Camera and anti intagram -->
        <arg name="/camera/raw" value="false" />
        <arg name="anti_instagram" value="true" />

        <!-- Lane Following stack -->
        <arg name="lane_following" value="true"/>
        <arg name="/lane_following/line_detection" value="false"/>
        <arg name="line_detector_param_file_name" value="default" />
        <arg name="/lane_following/ground_projection" value="true"/>
        <arg name="/lane_following/lane_filter" value="true"/>
        <arg name="/lane_following/lane_controller" value="false"/>


    <group ns="$(env VEHICLE_NAME)">


Submission Instructions

Submit to #demonstrations on Slack: A link to a video of your best lane following attempt.

Turn in to blackboard:

  1. A link to your repo and the tag that corresponds to this code.
  2. A link to a screen recording of your code running. Show that no lane controller code is running beforehand (you can use rqt_graph or rosnode list to show this) and use a custom message in the terminal to prove your code is running, as in previous labs. Show the output of the camera through the dashboard or rqt_image_view as it runs. Cut this video such that it only contains the demonstration of your code.
  3. A link to a video of your best lane following attempt recorded from an overhead perspective. This should be from the same run as the step above but does not need to be time synced. Cut this video such that it only contains the demonstration of your code.
  4. A short description of what you choose to control (input and output signals) and why. What final PID gain values did you use?
  5. A description of any issues you had with this assignment.


  • Algorithm: 30 points
  • Implementation: 30 points
    • Reasonable tuning parameters: 10 points
    • ROS package setup: 5 points
    • ROS node implementation: 15 points
  • Accuracy (scaled to your peers): 10 points
  • Demo video: 20 points (submitted to Blackboard and slack)
  • Answers to submission questions: 10 points