Minitask 1 - RobotTeaching/COMP4034 GitHub Wiki
In this mini-task, you'll create your first ROS package and write your first program. Resources are provided at the bottom of the page, so feel free to refer to them as needed.
Task 1: Creating a ROS package
Open a terminal and navigate to your catkin_ws/src
directory:
cd ~/catkin_ws/src
Use catkin_create_pkg
command to create a new ROS package:
# catkin_create_pkg <package_name> [dependencies]
catkin_create_pkg minitask1 std_msgs geometry_msgs rospy
Catkin is a workspace manager and build tool that we will use to create, build, and manage our ROS packages. You can find out more about catkin and this command in Resource 1 at the bottom of the page.
Once you've created your package, return to the catkin_ws
directory by typing cd ~/catkin_ws
in your terminal.
Build your package by running
catkin_make
.
Once built, re-source your workspace by running
. ~/catkin_ws/devel/setup.bash
.
This ensures that any new environment variables, paths, or package information set by catkin_make are applied to your current shell session. In other words, it sets up your environment with the paths and variables required for ROS to find and use your packages. If you don’t source it, your terminal won’t recognize the changes (like new packages or updates).
You will need to run catkin_make
and re-source your workspace whenever you make a change to your package.
You'll need to source your workspace like this in any fresh terminal unless you modified your .bashrc
file to do it automatically for you.
Task 2: Exploring the /cmd_vel topic
From the lectures, remember that ROS uses a publisher/subscriber model where nodes communicate via topics, each with a specific message type. In this task, you'll explore the /cmd_vel topic.
In Minitask 0, you simulated a robot and drove it around while echoing the /odom topic. In this task, you'll follow similar steps, but this time you'll echo the /cmd_vel
topic:
- In your terminal, run
roslaunch turtlebot3_gazebo turtlebot3_world.launch
- In a new terminal tab, run
roslaunch turtlebot3_teleop turtlebot3_teleop_key.launch
- Open a new terminal and run
rostopic echo /cmd_vel
The last terminal will show messages with components showing 0.0 - how does this change as you drive your TurtleBot? (Refocus the teleop window to drive the robot).
Upon closer inspection, you'll notice that /cmd_vel
messages are of type Twist
. Check Resource 2 to learn what a Twist
message contains.
Task 3: Publishing messages using the command line
n Resource 2, you’ll see that a Twist
message contains two Vector3
components. You can find more information about these components linked at the bottom of the resource page. This knowledge will be useful for the next step, where you'll publish commands to the robot using the command line.
First, stop the terminals running the teleop
and rostopic echo
. You can use one of these terminals or open a new one for the following steps (just remember to source your workspace if you do!).
Resource 3 has information on how to use rostopic pub
to publish a message to a topic. Use this resource, along with your understanding of Twist
messages, to publish a Twist command to /cmd_vel
.
Task 4: Writing a publisher to move the robot
This link provides example code to create a basic ROS publisher. Inside the package you created earlier, move into the src
folder and create a file called mover.py
(in your terminal, touch mover.py
) and make it executable by running chmod +x mover.py
in your terminal. Study the code from the link and once you understand it, copy it into this file.
NOTE: If you get an error like 'python' no such file or directory
check the top line of your code. It should be #!/usr/bin/env python3
. You should always be using python3.
You can use Resource 4 to help you understand this code - and make sure you fully grasp it! Next, you'll modify this code to move your robot by publishing Twist
messages. Here are some hints:
- Change all instances of
talker
tomover
- The line
pub = rospy.Publisher...
needs to be changed.rospy.Publisher
takes in a topic, a message type, and a queue length (which you can leave as 10). - Since you need to drive the robot, which topic should you publish to? Consider where the robot expects to receive movement commands.
- After identifying the correct topic, you'll need to create a
Twist
message to publish. ATwist
containslinear (x, y, z)
andangular (x, y, z)
components, which control the robot's movements. You'll need to set these components as appropriate. These act like structs, so to change the linear x, you must change thelinear.x
property of yourTwist()
message. - Your robot only has linear motion in the x-axis, and angular rotation on the z-axis. Why do you think that is?
- Don't forget to add an import for
Twist
fromgeometry_msgs.msg
at the beginning of your file.
When you are ready to try running your code, remember that you need to return to the catkin_ws
directory and execute catkin_make
. Then, in your terminal, use rosrun minitask1 mover.py
to run your code. rosrun
takes in a package name and a script name.
Note: if, on your own install, you get an error about being unable to find Python, run the command sudo apt install python-is-python3
in your terminal and try again.
Task 5a: Driving around in a square (easy mode)
Now that you can publish Twist
messages in your code, you will need to edit your code so your robot drives around in a square. You should publish two Twist
messages, one after the other, until the program is terminated - one to move the robot forwards, and one to turn.
Your code is already in a loop while not rospy.is_shutdown()
which repeats 10 times a second, so you can use the rospy.Time
library to check how much time has passed in the loop. You'll need to start with rospy.Time.now().to_sec()
to get the current time. You will need to figure out how long to drive your robot forwards for, and how long (and fast!) to turn for to get to 90 degrees.
Task 5b: Driving around in a square (hard mode)
Your robot should now drive around in a roughly square shape now. But simply timing your actions won’t give you an accurate square in the real world (think of the wheels slipping on sand!). A better approach is to adjust the robot’s actions based on how far it has actually moved. For that, the robot needs to know its position. The easiest way to get this info with the Turtlebot is by using odometry
data, which estimates the robot's position and orientation by tracking wheel movement over time.
We’ll implement this by modifying your mover.py
script. Start by opening it in your preferred editor. First, add an import statement for Pose
from geometry_msgs.msg
. Then, under where you created the publisher, define a subscriber to the /odom
topic:
rospy.Subscriber("odom", Odometry, odom_callback)
The three parameters in this constructor are the topic name, the message type, and the name of the callback function. So, you need to implement a callback function. Define one called odom_callback
with a parameter called msg
, which will hold the Odometry
data your subscriber listens to.
Hint: you'll need to import Odometry
from nav_msgs.msg
, and you'll need to import tf
for the below code to work.
In this function, to extract the (x, y)
position of the robot and its rotation (theta)
, we will need to convert the orientation in the Odometry
message from a quaternion to Euler angles. You can use the code below to do so:
# Get (x, y, theta) specification from odometry topic
quaternion = [msg.pose.pose.orientation.x,msg.pose.pose.orientation.y, msg.pose.pose.orientation.z, msg.pose.pose.orientation.w]
(roll, pitch, yaw) = tf.transformations.euler_from_quaternion(quaternion)
self.pose.theta = yaw
self.pose.x = msg.pose.pose.position.x
self.pose.y = msg.pose.pose.position.y
You can find out more about quaternions using Resource 6, but for now you can just accept that they're a different way of representing space. Make sure you understand the above code snippet though.
Note: to use self
in a Python class, you'll need an __init__
method. This is left as an exercise for you, to get you more familiar with Python.
Now, you can use the odometry data to implement the following steps, so that your robot attempts to move in a more robust square:
1. Initialise current `pose(x,y,theta)` of the robot and select a desired `pose(x*,y*,theta*)`. The `x*` and `y*` should be set as the first corner coordinates of the 1m-edge square you will traverse. `theta*` should be current `theta` plus 90 degrees
2. Move forward and accumulate the travelled distance.
3. Stop if the total distance is greater than 1m. This is the end of your first edge.
4. Now set the desired orientation as `theta* = theta*+PI/2`
5. Rotate in place (remember the `Twist` message) until the accumulated orientation is greater than `PI/2`
6. Pause
7. Repeat until the square is complete.
Resources:
Resource 1 - Creating a catkin package
Resource 2 - Twist message
Resource 3 - rostopic pub
Resource 4 - ROS tutorial on writing a simple Publisher and Subscriber in Python
Resource 5 - Pose message
Resource 6 - Quaternions