Skip to content
Tom Howard edited this page Jul 5, 2021 · 10 revisions

Sensors and Control

Quick Links

Getting Started

If it isn't currently running then launch your WSL-ROS environment using the WSL-ROS shortcut in the Windows Start Menu. Once ready this will open up the Windows Terminal and an Ubuntu terminal instance (which we'll refer to as TERMINAL 1).

Restoring your Environment

If you happen to have changed to a different university machine since Part 1 then you may wish to restore the work that you did in the earlier session. You should have run the rosbackup.sh to backup all your work before, so you should now be able to restore this by running the following command in TERMINAL 1:

[TERMINAL 1] $ rosrestore.sh

Launching the Robot Simulation

  1. In the terminal enter the following command to launch a simulation of a TurtleBot3 Waffle in an empty world:

     [TERMINAL 1] $ roslaunch turtlebot3_gazebo turtlebot3_empty_world.launch
    

    A Gazebo simulation window should open and within this you should see a TurtleBot3 Waffle in empty space:

Robot Position and Velocity

Recall from the Introducing the Robots Section of this Wiki that the TurtleBot3 Waffles that we are working with here have the following sensors and actuators on-board to allow them to navigate:

  • Two independently controlled wheel motors (a differential drive configuration)
  • An Inertial Measurement Unit (IMU) to detect motion & orientation
  • A 360° laser displacement sensor (LiDAR) to detect its environment

Two types of Velocity Command can be issued to any ROS Robot to make it move:

  • Linear Velocity: The velocity at which the robot moves forwards or backwards in one of its axes
  • Angular Velocity: The velocity at which the robot rotates about one of its axes

The TurtleBot3's principal axes are defined as follows:

The TurtleBot3 robot has a differential drive configuration, so it can only move linearly in the x axis. In order to move to the left or right, it must first rotate to face the desired direction before moving forward. In addition to this, the robot can only rotate about its z (yaw) axis.

It's also worth noting that the robot has the following maximum velocity limits:

  • A maximum linear velocity of 0.26 m/s,
  • A maximum angular velocity of 1.82 rad/s.

In the previous session you learnt how to list all the topics that are currently active on a ROS system. Open up a new terminal instance (TERMINAL 2) and use what you learnt here to list all of the topics that are active on your ROS system now, as a result of you launching the Gazebo simulation in the step above.

Which topic in the list do you think could be used to control the velocity of the robot? Use the rostopic info command on the topic to find out more about it.

The topic you have identified should use a message of the geometry_msgs/Twist type. You will have to send messages of this type to this topic in order to make the robot move. Use the rosmsg command as you did earlier to find out more about the format of this message.

As we learnt above, the TurtleBot3 can only generate linear velocity in the x axis and angular velocity in the z axis. As a result, only velocity commands issued to the linear.x or angular.z sections of this message will have any effect.

Exercise 1: Interpreting Odometry data

Another topic that should have appeared when you ran the rostopic list command above is /odom. This topic contains Odometry data, which is also essential for robot navigation and is a basic feedback signal, allowing a robot to approximate its location.

  1. In TERMINAL 2 use the rostopic echo command to display the odometry data currently being published by our simulated robot:

     [TERMINAL 2] $ rostopic echo -c /odom
    

    Expand the terminal window as necessary so that you can see the whole topic message (it starts with header and ends with ---). What does the -c option in the command above actually do?

  2. Now, you need to launch a new terminal window, but so that you can still view TERMINAL 2, so press the "New Tab" button whilst pressing the Alt key, to launch the new terminal in a "Split View" (we'll call this one TERMINAL 2b).

  3. In TERMINAL 2b launch the keyboard_teleop node as you did last week:

     [TERMINAL 2b] $ roslaunch turtlebot3_teleop turtlebot3_teleop_key.launch
    
  4. In TERMINAL 2b enter A a couple of times to make the robot rotate on the spot. Observe how the odometry data changes (in TERMINAL 2). Is there anything in the twist part of the /odom message that corresponds to the angular vel that you are setting in TERMINAL 2b?

  5. Now press the S key to halt the robot, then press W a couple of times to make the robot drive forwards. How does the twist part of the message now correspond to the linear vel setting in TERMINAL 2b?

  6. Now press D a couple of times and your robot should start to move in a circle. What linear and angular velocities are you requesting in TERMINAL 2b and how are these represented in the twist part of the /odom message? What about the pose part of the message? How is this data changing as your robot moves in a circular path, what do you think this tells you?

  7. Press S in TERMINAL 2b to halt the robot (but leave the keyboard teleop node running). Then, press Ctrl+C in TERMINAL 2 to shutdown the rostopic echo node.

  8. Next, with the robot stationary, use rosrun to run a Python node that takes a snapshot of the robot's current odometry data:

     [TERMINAL 2] $ rosrun com2009_odometry_example robot_start_pose.py
    

    Consider the output of this node and what this tells you about what the node is actually doing.

  9. Now (using the keyboard teleop node in TERMINAL 2b), drive your robot back to the origin of its world (where the blue, green and red lines meet).

  10. Now, open a new terminal window (TERMINAL 3), to run another Python node to take another snapshot of the robot's current odometry data. This node will now also compare this to the data obtained by the robot_start_pose node that was launched earlier:

     [TERMINAL 3] $ rosrun com2009_odometry_example robot_end_pose.py
    

    The output of this node should provide you with a summary of how the robot's odometry has just changed in between running the two com2009_odometry_example nodes. The start and end columns provide a summary of the odometry data that was obtained before and after the robot was moved and the delta column shows the difference between the two. Which odometry parameters haven't changed, and is this as you would expect (considering the robot's principal axes as illustrated above)?

  11. Press Ctrl+C in TERMINAL 2, 3 and 2a, to stop the robot_start_pose, robot_end_pose and turtlebot3_teleop nodes. Then, in TERMINAL 2 (the one currently in Split View mode), press the "Close tab" button to close TERMINAL 2 and 2a, so only TERMINAL 1 and 3 remain open.

What is Odometry?

We can learn more about Odometry data by using the rostopic info command:

$ rostopic info /odom

This provides information about the type of message used on this topic:

Type: nav_msgs/Odometry  

We can find out more about this using the rosmsg info command:

rosmsg info nav_msgs/Odometry

Which tells us that the nav_msgs/Odometry message contains four base elements:

  1. header
  2. child_frame_id
  3. pose
  4. twist

pose tells us the position and orientation of the robot relative to an arbitrary reference point (typically where the robot was when it was turned on). The pose is determined from:

  • Data from the Inertial Measurement Unit (IMU) onboard the OpenCR board
  • Data from both the left and right wheel encoders
  • An estimation of the distance travelled by the robot from its pre-defined reference point (using dead-reckoning)

Position data is important for determining the movement of our robot, and from this we can estimate its location in 3-dimensional space.

Orientation is expressed in units of Quaternions, and needs to be converted into angles (in degrees) about the principal axes. Fortunately, there are functions within the ROS tf library to do that for us, which we can use in any Python node as follows:

from tf.transformations import euler_from_quaternion

(roll, pitch, yaw) = euler_from_quaternion([orientation.x, 
                     orientation.y, orientation.z, orientation.w], 
                     'sxyz')

Our TurtleBot3 robot can only move in a 2D plane and so, actually, its pose can be fully represented by (x,y,θz), where x and y are the 2D coordinates of the robot in the X-Y plane, and θz is the angle of the robot about the z (yaw) axis. You should have noticed this in the exercise above, where the linear_z, theta_x and theta_y values in the delta column should all have read 0.0.

twist tells us the current linear and angular velocities of the robot, and this data comes directly from the wheel encoders.

All this data is defined in terms of the principal axes illustrated in the figure above.

Exercise 2: Processing Odometry data

Last week you learnt how to create a package and build simple nodes in Python to publish and subscribe to messages on a topic.

  1. Navigate to the src directory of the ros_training package that you created earlier:

     [TERMINAL 3] $ roscd ros_training/src
    
  2. The subscriber.py code that you used earlier can be used as a template for creating an odometry subscriber now. First, create a new file in your src directory (~/catkin_ws/src/ros_training/src) called odom_subscriber.py:

     [TERMINAL 3] $ touch odom_subscriber.py
    
  3. In the same way as last time, make this file executable using the Linux chmod command.

  4. Launch Atom ($ atm), open the odom_subscriber.py file and copy the basic subscriber code.

  5. Now, edit the code to subscribe to and print out odometry data to the terminal:

    • You will need to make sure that you are importing the correct message type at the start of your code so that you can work with the Odometry data (be aware that the Odometry message is part of the nav_msgs library. If you need help, have a look at this explainer).
    • Your Python node should convert the raw odometry data to a (x,y,θz) format using the euler_from_quaternion function from the tf.transformations library (remember that θz is the same as Yaw). If you aren't sure how to do this, why not have a look at the source code for the com2009_odometry_example nodes that you used in Exercise 1. Remember that you can navigate to this package using the roscd command, and then locate the source code contained with it.
  6. Launch your node using rosrun. Observe how the output of your node (the formatted odometry data) changes whilst you move the robot around again using the turtlebot3_teleop node in a new terminal instance (TERMINAL 4).

  7. Stop your subscriber.py node in TERMINAL 3 and the turtlebot3_teleop node in TERMINAL 4 by entering Ctrl+C in each of the terminals.

Basic Navigation: Open-loop Velocity Control

Exercise 3: Moving a robot from the command line

Note: Make sure that you have stopped the turtlebot3_teleop node running in TERMINAL 4 (by entering Ctrl+C) before starting this exercise.

We can use the rostopic pub command to publish data to a topic from within a terminal by using the command in the following way:

rostopic pub [topic_name] [message_type] [data]

As we discovered earlier, the /cmd_vel topic is expecting linear and angular data, each with an x, y and z component. We can get further help with formatting this message by using the autocomplete functionality within the terminal. Type the following into TERMINAL 4 (copying and pasting won't work):

[TERMINAL 4] rostopic pub /cmd_vel geometry_msgs/Twist[SPACE][TAB][TAB]
  1. Use this to help you enter velocity commands in the terminal. Enter values to make the robot rotate on the spot. Make a note of the command that you used.
  2. Enter Ctrl+C in TERMINAL 4 to stop the message from being published.
  3. Next, enter a command in TERMINAL 4 to make the robot move in a circle. Again, make a note of the command that you used.
  4. Enter Ctrl+C in TERMINAL 4 to again stop the message from being published.
  5. Finally, enter a command to stop the TurtleBot and make a note of this too.
  6. Enter Ctrl+C in TERMINAL 4 to stop this final message from being published.

Exercise 4: Creating a velocity controller node

You will now create another node to control the motion of your TurtleBot3 by publishing messages to the /cmd_vel topic. You created a publisher node last week, and you can use this as a starting point.

  1. In TERMINAL 3, ensure that you are still located within the src folder of your nav_exercise package. You could use pwd to check your current working directory, where the output should look like this:

     /home/student/catkin_ws/src/nav_exercise/src  
    

    If you aren't located here then navigate to this directory using cd.

  2. Create a new file called move_circle.py:

     [TERMINAL 3] $ touch move_circle.py
    

    And make this file executable using the chmod command.

  3. Open up this file with Atom to edit it. Copy and paste the contents of the publisher node from last week into the new move_circle.py file to get you started, if you want to. Then edit the code to achieve the following:

    • Make your TurtleBot3 move in a circle with a path radius of approximately 0.5m.
    • The Python node needs to publish Twist messages to the /cmd_vel topic in order to make the TurtleBot move. Have a look at a usage example here.
    • Remember (as mentioned earlier) that for our robots, the maximum linear velocity (linear.x) is 0.26 m/s, and the maximum angular velocity (angular.z) is 1.82 rad/s.
    • Make sure that you code your shutdown_function() correctly so that the robot stops moving when the node is shutdown (via Ctrl+C in the terminal that launched it).
  4. Create a launch file to launch this and your odom_subscriber.py node simultaneously with a single roslaunch command. Refer to the launch file that you created last week for a reminder on how to do this.

Saving your work

Once again, save the work you have done here by running the following script in any idle WSL-ROS Terminal Instance (incase you need to restore it later):

$ rosbackup.sh

Navigating This Wiki:
← Part 1: Getting to Grips with ROS (and Linux) | Part 3: Robot Arms and the MoveIt Library →