Objectives

Part I

The goal of this lab is for you to write code to control your Duckiebot. In Part I, your robot should follow one of the signs that come with the Duckiebot kit. Specifically, you should:

  1. Start the Apriltag Detector Demo using $ roslaunch duckietown_demos apriltag_detector.launch and put a sign in front of the robot. Any Duckietown sign with the AR tag will do. Watch the output of tag_detections as you move the sign in front of the robot. Try a different sign and see what changes.
  2. Write a PID controller that keeps your robot pointed at the sign as it moves around. This will only control the angular velocity of the robot, not the speed. The robot should not move forwards or backwards.
  3. Now add another PID controller to move your robot towards the sign. Make it stop 10cm in front of the sign. Move the sign around and ensure your robot can follow it consistently through at least a circle.

Part II (EECE.5560 only)

Part II requires you to transform your Part I node into a new 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.

Tips

Part I

  1. Your Duckiebot identifies signs using April Tags, the black and white patterns beneath the normal road sign. You should have received several signs with your Duckiebot. If not, you can borrow them from the lab.
    You can start the sign detector by running:
    $ roslaunch duckietown_demos apriltag_detector.launch
    from inside a docker container on your robot, like when you ran the lane following demo. It does not matter if the sign is actually on a signpost or propped up some other way.
  2. Think about the coordinate frame apriltag_demo is using when it publishes the position of the sign. How can you use it to control the robot?
  3. Your two PID controllers are decoupled, which means you can tune them independently. Make sure the turning control is tuned before moving on to the distance controller.

Part II

  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. Remember error = desired – actual
  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. Even 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 3, and run your Lab 3 code instead (blue line below). It should look something like this:
<launch>

    <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"/>

    <include file="$(find led_emitter)/launch/led_emitter_node.launch"> 
        <arg name="veh" value="$(env VEHICLE_NAME)"/> 
    </include>
    <!-- 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"/>

    </include>

    <group ns="$(env VEHICLE_NAME)">
        YOUR NODE/PARAMS/ETC GO HERE
    </group>

</launch>

Submission Instructions

Part I:

DEMONSTRATE your code in class/office hours and turn in to blackboard:

  1. A link to your repo and the tag that corresponds to this code.
  2. A short description of what you choose to control (input and output signals) and why. What final PID gain values did you use?
  3. A description of any issues you had with this assignment.

Part II:

Turn in to blackboard:

  1. A link to your repo and the tag that corresponds to this code (can be the same as Part I).
  2. A short description of what you choose to control (input and output signals) and why. What final PID gain values did you use?
  3. A description of any issues you had with this assignment.

Rubric

Part I

  • 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): 20 points
  • Demo: 10 points
  • Answers to submission questions: 10 points

Part II

  • Implementation: 15 points
    • Reasonable tuning parameters: 5 points
    • ROS node implementation: 10 points
  • Accuracy (scaled to your peers): 20 points
  • Demo: 10 points
  • Answers to submission questions: 5 points