By now you should have read chapters 1 and 2 of AGIR (see resources page). These chapters will expose you to the basic concepts of ROS and help you learn the basic ROS "jargon" (topics, nodes, etc.). You should have also done some basic analysis of the topics that the Neato uses. As we continue our journey to becoming a ROS boss, here we will focus primarily on ROS tools and techniques that will be useful for debugging the robotics programs that you will write throughout this course. At the end of this assignment we will write our first programs to control the Neatos.
You may work on this assignment with one other person from the class. However, please make sure that *both* of your repositories contain a final copy of the assignment. The best way to do this is to create a new Github repo specifically for this assignment and then add it as a submodule to your comprobo fork. See this page for details. The low tech way is just to push the final code to both repositories separately.
You should turn in your assignment by pushing your code, screenshots, and writeup to Github. The repository you use for this class should be a fork off of my comprobo repository (for details see the Setting Up Your Environment page).
To get started on the assignment, you should create a ROS package to hold your getting familiar with ROS assignment. Using catkin_create_pkg
(see this tutorial for more information), create a package in the src subdirectory of your comprobo fork called getting_familiar
. You should now have the following files inside the src
subdirectory of your comprobo repository:
./getting_familiar/CMakeLists.txt
./getting_familiar/package.xml
./getting_familiar/src
Probably the most important tool for debugging in this class will be rviz. You can think of rviz as a specially tuned debugger for robots. Consider the case of debugging a typical program. One way you might go about this is to instrument your program with print statements. These print statements may give you useful information as to the state (e.g. values of variables) of your program, and ultimately, help you find logic errors in your code. This approach breaks down when you work on robots with high bandwidth sensors (like the Neato). The Neato sensory data consists of hundreds of thousands of numbers generated each second. Visualizing all these numbers using print statements is infeasible.
Rviz contains visualization tools for common sensory data. Further, there are some general purpose visualization messages that you can customize for your purposes. In this portion of the assignment, you will get familiar with using rviz with the Neato, and write a simple program to visualize arbitrary geometric shapes.
Part 1
For part 1 you will be using rviz to visualize the data from the Neatos. Grab a Neato and connect to it. Read through the documentation for rviz and perform the following steps:
Save your rviz configuration as all_sensors.rviz
in a subdirectory of your getting_famliar
package called rviz. Your getting_familiar
package should now look like this:
./getting_familiar/CMakeLists.txt
./getting_familiar/package.xml
./getting_familiar/src
./getting_familiar/rviz/all_sensors.rviz
Part 2
Write a ROS node that publishes 10 times a second a message of type visualization_messages/Marker
. The marker message you publish should specify to rviz to create a sphere at position x=1m and y=2m in the Neato's odometry coordinate system (odom). It is up to you how large and what color to make the sphere (how's that for autonomy during week 1)! Create a screenshot of rviz that demonstrates that your code works. Information on the visualization_messages/Marker
message can be found here. Place your screenshot in a subdirectory called screenshots.
Optionally, explore other types of visualization markers (lines will be particularly useful in the next assignment).
Your getting_familiar
package should now look like this:
./getting_familiar/CMakeLists.txt
./getting_familiar/package.xml
./getting_familiar/src
./getting_familiar/rviz/all_sensors.rviz
./getting_familiar/screenshots/screenshot_001.png
Create a bag file of you driving the Neato around! Be careful not to record the /camera/image_raw
topic (this topic is an uncompressed image which is surprisingly large). In order to avoid recording the /camera/image_raw
topic you can either explicitly enumerate the topics you'd like to record or else use the -x switch (to explicitly exclude a topic). See this page for details on using the command line tool rosbag. Once you have recorded your bag file, play it back and visualize the results in rviz. Be very careful about the system clock when using rosbag. You want ROS to use the time stamps as they were recorded in the bag file, so be sure to specify the --clock argument when playing back your bagfile. Also, you will need to restart rviz for it to use the clock from the bag file as opposed to the system time.
For this part there is no code to turn (also there is no need to check in your bag file). I'd like you to include the answers to the following questions in your writeup for this assignment:
Please put the answers to these questions in a file called writeup.txt
in the root directory of your getting_familiar
package. The package should now look like this:
./getting_familiar/CMakeLists.txt
./getting_familiar/package.xml
./getting_familiar/src
./getting_familiar/rviz/all_sensors.rviz
./getting_familiar/screenshots/screenshot_001.png
./writeup.txt
Part 1
Do the five TF tutorials. If I were doing this assignment, I'd check in the code for the tutorials into your getting_familiar package
, but I won't be formally evaluating these so it is not required.
Part 2
Connect to a Neato and explore the coordinate frames that the Neato utilizes. Do this by first creating a graph that shows the coordinate frames and their relationships. While you are connected to the Neato, run:
rosrun tf view_frames
evince frames.pdf
Next, visualize the coordinate frames using rviz. To do this, simply add a display of type tf
. As you drive the Neato around you will see how the coordinate systems shift. If you currently have the base_frame set to odom
change it to a different value. Continue to drive the robot around. Does the new behavior make sense? Add your answers to your writeup.txt
file.
Part 3
Write a ROS node to publish a visualization marker of a sphere that always rides 1m in front of the Neato. There are three ways to do this, the easy way, the hard way, and the super hard way! You must turn in screenshots that show at least one of these working (as before, put your screenshots in the screenshots directory of your getting_familiar
package).
Easy way: use the base_link
coordinate frame to express the position of the sphere.
Hard way: transform the desired position of the sphere in the base_link
coordinate frame to the odom
coordinate frame and then publish that position for your marker.
Super hard way: avoid using the tf
module. For this method, listen directly to the odom
topic, do some trigonometry to compute the appropriate position, and then publish the visualization marker in the odom
frame. If you choose to do the super hard method (i.e. to build character), you may find the following helper function to be useful.
from tf.transformations import euler_from_quaternion
def convert_pose_to_xy_and_theta(pose):
""" Convert pose (geometry_msgs.Pose) to a (x,y,yaw) tuple """
orientation_tuple = (pose.orientation.x, pose.orientation.y, pose.orientation.z, pose.orientation.w)
angles = euler_from_quaternion(orientation_tuple)
return pose.position.x, pose.position.y, angles[2]
Robot Teleop
Write code to teleoperate your robot using the keyboard. If you get really ambitious you can try using a gamepad or the mouse.
Non-blocking keyboard input is surprisingly hard to do. To help, here is a skeleton program for getting the next key pressed when the focus is on the window where your program is running. The cryptic code '\x03' refers to control-c (which will exit the program).
import tty
import select
import sys
import termios
def getKey():
tty.setraw(sys.stdin.fileno())
select.select([sys.stdin], [], [], 0)
key = sys.stdin.read(1)
termios.tcsetattr(sys.stdin, termios.TCSADRAIN, settings)
return key
settings = termios.tcgetattr(sys.stdin)
key = None
while key != '\x03':
key = getKey()
print key
Put your teleop code in a nodes
subdirectory of your package. For consistency, please put your code in a file named teleop.py
. Your package directory should now look like this:
./getting_familiar/CMakeLists.txt
./getting_familiar/package.xml
./getting_familiar/src
./getting_familiar/rviz/all_sensors.rviz
./getting_familiar/screenshots/screenshot_001.png
./getting_familiar/screenshots/screenshot_002.png
./writeup.txt
./nodes/teleop.py
Your First Autonomous Robot Program!
Write a ROS Node to move the Neato through a 1m by 1m square path. The two ways to do this are using timing and by using the odometry. I'll leave it to you which one to try (although using timing is significantly easier). Put your code in the nodes
subdirectory in a file called drive_square.py
.
You should make sure you have pushed your getting_familiar
package to Github. It should contain the following files:
./getting_familiar/CMakeLists.txt
./getting_familiar/package.xml
./getting_familiar/src
These are auto-generated, you should not need to touch them.
./getting_familiar/rviz/all_sensors.rviz
Your rviz configuration file that shows all of the Neato's sensor data.
./getting_familiar/screenshots/screenshot_001.png
A screenshot showing a marker at position 1m,2m in rviz.
./getting_familiar/screenshots/screenshot_002.png
A screenshot showing a marker riding 1m directly in front of the Neato.
./writeup.txt
Your answers to the questions posed in this assignment.
./nodes/teleop.py
Your keyboard (or other input device) teleoperation node.
./nodes/drive_square.py
Your code for driving the Neato in a 1m by 1m square.
The grade for this assignment will be 60% for code and 40% for writeup (where writeup also includes any screenshots that you have to generate). The coding rubric can be found here. The rubric for the writeup is:
100%: All sections present. A sincere attempt was made to answer all questions posed in the assignment (it is okay if you don't have exactly the right answers, just make sure to provide evidence that you have thought about them). Writing is clear and the document is appropriately organized.
80%: Some aspects of the writeup are missing. The writing may be unclear or not well-organized.
60%: Writing is unclear. Significant components of the writeup may be missing.
.... (don't go below this line!)