Homework 1 will introduce you to the tools we will use in this course. Most of the commands are specified for you in the linked instructions or below. At the end of this assignment, you should have a working system for future assignments and a basic understanding of ROS topics and nodes.


  1. First, set up your system: Setting Up Your Environment
  2. Make sure you are in your repo directory, then use dts to build your docker image:
    $ dts devel build --pull

    This command will build your Dockerfile into an image that you can run as needed. It needs to be run when there are big changes, like when you update the template to your repo or when some Duckietown images are changed. We will discuss this more as the semester progresses. The “pull” option tells dts to check for any updates to other dependency images when it runs.

    NOTE: This command may take several minutes, especially at step 10/57, the first time it runs. If you worry that it is not working, you can first download the biggest pre-requisite docker image by running the command below.
    !!!Optional command below!!!

    $ docker pull duckietown/dt-core:daffy-amd64
  3. You can now run your image as a docker container using dts:
    $ dts devel run -M -X --cmd bash

    Let’s take a deeper look at this command:

    1. “dts devel run” will start a Duckietown-based container (like what is in the class repo you used as a template) with a configuration that lets it run like Docker images will run on your robot. This saves us from writing a very long docker run command with many options. Proper documentation on this tool is still forthcoming, but some information can be gleaned from looking over this tutorial if you are interested in deeper understanding: https://docs.duckietown.org/daffy/duckietown-robotics-development/out/dt_infrastructure.html This tutorial is NOT required for HW1.
    2. The -M option mounts the current project to the working directory of the docker container. This allows us to write code outside of the container and run it inside, which can be handy depending on which text editor you prefer. It also lets us use git to store code as we write it. We won’t actually use this in HW1 but it will be our method for future homework/labs.
    3. The -X option allows us to run graphical interfaces. You generally want to use this for homework assignments but it may not always work on the robot for labs.
    4. The cmd option tells dts to run a bash shell (likely the same command line terminal as you are using) after starting the container so that you can type commands.
  4. If you run “ls” inside this container you should see the contents of your repo here. These files are shared with your computer right now, so when you make changes on your computer they will also be changed in docker and vice versa.
  5. We need to build the current ROS environment inside this container. This is largely done for us in Duckietown containers, but it is always good practice to double check. Run:
    $ cd /code/catkin_ws/
    $ source devel/setup.bash
    $ catkin build
    $ source devel/setup.bash

    These commands allow you to use the correct environment for ROS and build everything in that environment. You will have to run these commands every time you change code or create new packages. For this assignment, once is enough.

  6. Time to start a ROS node! First, let’s start roscore:
    $ roscore
  7. This will run so that you cannot do anything else in this terminal until it is time to end roscore. Let’s start another terminal and connect it with your docker container. First, start a new terminal window, then change directory to your git repo and run:
    $ dts devel run attach

    This will give you a new command line interface to your running docker container.

  8. You need to source your environment in this new terminal so that we can use all of the ROS-specific commands:
    $ source /code/catkin_ws/devel/setup.bash
  9. Now you can start the ROS node we will use in HW1:
    $ rosrun mystery_package mystery_node.py
  10. This command will also consume your terminal, so let’s start up a third shell (step 7) and source our environment (step 8). In this one, let’s use ROS tools to see what is running:
    $ rosnode list

    You should see “mystery_node” here.

  11. This seems like a lot of terminals just to run a node and see what’s going on. Good news! There is a better way! We can start roscore and launch an arbitrary number of nodes using a single launch file and roslaunch. Press ctrl-c in each of these three terminals to end their current process. From any of the terminals you used in the last step, run:
    $ roslaunch mystery_package launch_mystery.launch

    This will print some debug text to the screen and then stop printing information.

  12. From either other terminal from step 4, run:
    $ rosnode list

    This shows all of the nodes that are currently running. You should see the same node you saw before as well as one more.

  13. In any terminal you set up in step 5, run:
    $ rostopic list

    This shows all active topics. Two topics, “/rosout” and “/rosout_agg” are almost always shown and we can ignore them for this assignment. We will focus on the two topics that are part of this mystery node.

  14. Let’s figure out what is going on with this ROS node so we can use it. Use the rostopic info tool for all mystery node topics. Record the publisher and subscriber for each one as well as the message type.
    $ rostopic info <topic>
  15. One topic will say that it has a subscriber but no publisher. This means that the ROS node mystery_node is listening (subscribing) to this topic. The other two topics will have a publisher but no subscriber. This means mystery_node is talking (publishing) over them. We can listen to the output of the ROS node using a command line tool. This is very useful for debugging. Run this command:
    $ rostopic echo <topic>

    For one of the topics that you think is being sent by the mystery_node node. Leave this command running.

  16. You shouldn’t see any output right now because the node is not publishing anything. Usually, that means the node is waiting for some input. Let’s give it that input. You will need the name of the topic you decided the node is listening to as well as the type of the message. Run this in another terminal:
    $ rostopic pub -1 <topic> <message_type> <value>

    HINT: the value is just a number in this case. Pass any number you like.
    NOTE: that is a “dash one” (1) after the command. Some fonts are clearer than others. It makes rostopic pub send the message exactly once and exit.

  17. You should see some output on the terminal running rostopic echo. Send a few different values and see what happens. Record the inputs and outputs for multiple values without restarting the launch file. Do the same for the other output topic. What do you think this mystery node is doing?
  18. You can end all of the above processes (ctrl-c) and quit any docker containers (type “exit” in their terminal windows).
  19. Back in your Linux system (not in the container started with dts), we can now submit your code. We need to give this commit a tag so that the instructor knows which commit to grade. First, let’s make sure you haven’t made any changes to the code. Run:
    $ git status

    And confirm that it says “nothing to commit”. If there is anything to commit, refer to the commit and push commands in the setup instructions.

  20. Now we need to apply a tag. Tags should generally be HW# for homework and L# for labs. To tag this assignment, run the following in your repo directory:
    $ git tag hw1
    $ git push origin hw1

    Remember to do this for each assignment you turn in!


To complete this assignment, submit a PDF to blackboard with the following information:

  1. The tag used for the code component of this assignment (4 points)
  2. The URL of your repository, your username on whichever site it is, and the name of your repository ( 10 points)
  3. List the name of the two topics published by the mystery node and the message types they had. (8 points)
  4. What was the name of the topic that the mystery node listened to? What type did it have? (6 points)
  5. What is the mystery node doing between the input and the output? What were the inputs/outputs you used? (12 points)