Assignment 1

Due Date: 17 May 24 May (See “Submission and Demonstration”)

Introduction

The purpose of this assignment is to gain familiarity with ROS and test a very simple algorithm for gradient ascent.  The assumption is that you will be completing this assignment using ROS Kinetic in EN-1049.  More information on installing ROS on your own machine will be posted.

ROS Tutorials

Complete the beginner level tutorials at http://www.ros.org/wiki/ROS/Tutorials.  It is highly recommended for you to execute all commands, as opposed to just reading your way through the tutorials.  You can skip tutorials 11 and 14 which deal with C++.  For the tasks below you will need to create Python scripts similar to those that are created in tutorials 12 and 15.

If you haven’t programmed in Python before (or if you need a refresher) the official Python tutorial is recommended.  Chapters 1-4 of the tutorial will probably suffice for now, although you may want to skim chapter 6 which discusses the import statement.

Painting a Scalar Field

A scalar field is an association between points in space and a scalar value.  We will use the turtlesim turtle to paint a greyscale pattern as a scalar field.  This pattern will be sensed by the gradient ascent algorithm created below.

First, refer to ROS tutorial 3 and create a new package called a1.  Make sure that you specify rospy and turtlesim as dependencies.  Also, the catkin_create_pkg command should be executed within ~/catkin_ws/src.  Change to the ~/catkin_ws directory and execute catkin_make to build your empty package.

Create a launch subdirectory within your package (within ~/catkin_ws/src/a1 execute mkdir launch).  Paste the following text into a file called start.launch:

This launch file runs the turtlesim_node and turtle_teleop_key nodes from the turtlesim package.  Execute as follows:

  roslaunch a1 start.launch

You should now have the turtlesim window open and be able to pilot the turtle around using the arrow keys (make sure the terminal from which roslaunch was executed is selected).  You can kill all launched nodes (and the ROS master) by hitting Ctrl-C in the terminal.

Create a scripts directory in your package.  In the steps below you will create new Python scripts in this directory.  Each such script must be made executable (chmod +x script_name) and you must execute catkin_make in ~/catkin_ws/src prior to actually running a new script.

Paint Node

Create a node script called paint.py in your scripts directory.  A template is provided below:

Your job is to replace all of the “???” sections with code that satisfies the requirements of the paint node.  This node’s purpose is to set the turtle’s pen to a colour that is governed by its distance from the centre of its environment (5.5444, 5.5444).  The ‘pose_callback’ function should be filled in to set the pen’s r, g, and b values to a single intensity.  This intensity should be inversely proportional to the Euclidean distance between the turtle’s current position (pose.x, pose.y) and the centre position.  It should have a maximum value of 255 (white) at the centre and a minimum of 0 (black) at (0, 0).  Set the pen’s width to 20.

To test the paint node, run the launch file created above.  Then, in a new terminal, execute rosrun a1 paint.py.  Now activate the terminal from which the launch file was executed and drive the turtle around the arena.  The result should look something like this:

paint_example

Driving the turtle around manually is obviously an inefficient way of filling in the scalar field.  So instead we introduce the teleporter node.

Teleporter Node

Teleportation hasn’t yet been perfected in robotics, but turtles have been doing it forever.  Your next task is to create a new script called teleporter.py which moves the turtle around the screen in an outward spiral.  We rely on the paint node to do the actual painting.  You can assume that the turtle begins at the centre of the arena.  A template is provided below:

You should use the /turtle1/teleport_relative service.  Please be aware that for long-distance teleports the colour of the pen remains unchanged, which can create undesirable stripes across the scalar field.  Aim to produce a scalar field such as this:

pattern

Take note of the pattern of a discrete spiral.  You should be able to teleport the turtle along such a path.

spiral

The length of each step should be 0.44 to reproduce the scalar field shown above.  You should call rate.sleep() after each teleport.  The turtlesim node has its own main loop that runs concurrently.  This loop will handle all teleport requests that occurred since the last iteration and only then publish the turtle’s pose.  This means that for multiple teleports only one call to the paint node’s callback would occur.  This situation can create undesirable changes in the scalar field (try modifying the argument to rospy.Rate and see!).

Create a launch file called create_scalar_field.launch that starts up the turtlesim, paint, and teleporter nodes.  The teleop node used in start.launch is not needed.  Test by executing roslaunch a1 create_scalar_field.launch.

Homer Node

The objective here is to implement a very simple algorithm that should move the turtle towards the highest point on the scalar field, which happens to be the centre.  Obviously, we could subscribe to the robot’s pose and then just move towards the known centre point.  However, the goal here is to get to the centre by relying only on the color sensor.  The algorithm works like this:

  • Read the current color intensity beneath the turtle and compare it to the value from the previous iteration
  • If the intensity is the same, keep moving in the previously selected direction
  • If the intensity has risen, set the turtle’s velocity to move forwards
  • If the intensity has fallen, initiate a left turn while continuing forwards

This algorithm will not take the most efficient route, but it will bring the turtle close to the centre and then start oscillating around it.  The idea is inspired by certain species of bacteria (e.g. E. coli) which perform a behaviour called chemotaxis where they swim in the direction of increasing concentration of some desirable chemical.  They sample this concentration and if it is increasing, they keep going forwards.  If not, they tumble randomly.  The same process is used to escape toxins in their environment.

Start with the following template code for homer.py:

In order to test the homer node we will need to kill the paint node and turn off the pen.  Execute the following commands on the command-line:

  rosnode kill /paint
  rosservice call /turtle1/set_pen 0 0 0 0 1

Now execute the following and shift the turtle to an arbitrary position.

  rosrun turtlesim turtle_teleop_key

Hit ctrl-C to kill the teleop_key node, then execute the homer node:

  rosrun a1 homer.py

Wait and see if the turtle finds its way home.  Note that the algorithm suggested will not guide the robot exactly to the centre and won’t cause the turtle to stop.  The idea is just to return to the vicinity of the centre and oscillate around it.  Then hit ctrl-C and launch the teleop_key node again to try a new starting position.  Repeat several times to make sure the algorithm works throughout the arena (we can’t expect it to work from very near the boundaries).

Submission and Demonstration

Submit the three scripts: paint.py, teleporter.py, and homer.py as well as the launch file create_scalar_field.launch.  Submit using Desire2Learn.  Enter the system by going to online.mun.ca and entering your regular MUN user name and password.  You should see a link to COMP 4766 or 6912 (if you don’t then you may not be properly registered for the course).  Click on “Assessments” then “Dropbox”.  You should now see a link to Assignment 1 that allows you to upload the files mentioned above.

You must submit through D2L by 9:00 a.m. on May 17 May 24 (yes, prior to the start of the lab—first thing in the morning).  You must also demonstrate your working code in the lab (EN-1049) during the lab session.  So you must come to the lab by 9:00 a.m. (and have your submission to D2L completed beforehand).