When getting started in robotics, you’ll often hear the term ROS (Robot Operating System). In case you aren’t familiar, ROS is an Open-Source framework that allows you to interconnect different components of a robot with the goal of autonomous operation. At a high-level, ROS uses a graph-like structure to perform peer-to-peer communication. As with any software, ROS also has different distributions depending on the year of release. To make ROS more compatible with industry standards, a newer version was released starting in 2017 called ROS2 with the following series of distributions (https://docs.ros.org/en/dashing/Releases.html).
Understanding which distro you’ll use is very important. For the purposes of this blog, explanations will be done with ROS2 Dashing, currently supported by Ubuntu 18.04 which is the OS running on the QCar.
Entering the ROS ecosystem:
Prior to starting your ROS application, try to break down the task into the individual components you’ll need. Next, define the kind of information that’s required for each component. In ROS, individual components can be thought of as nodes. Nodes can send or receive information depending on how they’re configured. The continuous transfer of information is done with a publisher and a subscriber structure. The connection between two nodes is done via a topic which has a unique name.
Visually, this is what the flow of information could look like:
Topics are configured using a specific message definition. A message definition will include data, the type(s) required (float64, string, uint32, etc..), and a corresponding label. Keep in mind ROS has predefined message definitions for publishing topics that describe attributes such as a robot’s pose, sensor information, navigation information, etc. You also have the flexibility of creating your own message definition if your application requires it.
Let’s Publish a Topic
In the case of the QCar, we have defined a publisher which is continuously broadcasting the (Inertial Measurement Unit) IMU information at a specified frequency. Since IMUs fall under the category of sensors, we can use the sensor_msgs.msg definition to configure our topic. In practice, this is how our message is defined:
The imu_callback() function is used to populate each component of the Imu() message definition. The function Imu() comes from ROS’ sensor_msgs.msg package.
Next, we specify the topic name and frequency used to publish the data. Looking once again at the QCar this is how our IMU topic is defined:
Within ROS2, we get access to “rcply” which contains the function create_publisher(). Our next step is to define the msg definition (Imu), the topic name ‘/qcar/ imu’, and queue size. We use create_timer() to periodically call the imu_callback() function at a specified rate. A similar process is performed for additional sensors on the QCar. For a more complex breakdown of the nodes created for our QCar platform, I recommend you stay tuned for the upcoming update to the QCar’s ROS offering. We will be porting over the QCar package into ROS2.
Subscribing to topics:
Now that we’ve quickly looked at publishing let’s do the reverse and look at how we can subscribe to a topic. In this example, we will focus on a topic that is used to publish a linear velocity command and steering angle setpoint. Like publishing data, to subscribe to a topic, we need to know the name as well as the message definition used. Our subscriber is defined as:
Where we utilize the “rcply” package to create a subscription using the create_subscription() function, which expects the message definition (vector3Stamped), the topic name ‘/qcar/user_command’, a callback function self.process_cmd(), and a queue size. We use the callback function process_cmd() to save the user commands in the variable self.command:
You’ll notice we did not have to create a timer function for the subscriber. In ROS1 and ROS2, when a subscription is initiated, the data is only read by a subscriber when a new packet is available from the publisher. In turn, if there are bottlenecks in your publisher, your subscriber will also lag. For data with high bandwidth requirements such as video, the image size, format, and publish rate are important to consider.
You may be asking, what can you do with the topic we’ve subscribed to? We can use it for some interesting image processing applications!
Figure x. above show’s how we use the steering command to define the region of interest prior to performing a canny edge detection. Useful for self-driving applications, don’t you think?
As you can see, it’s very straightforward to integrate a Quanser device to communicate using the ROS infrastructure. You’ll need to keep in mind the limitations that are present when you incorporate different ROS packages, but this should give you an idea of how to start your research with a platform like the QCar.