visit
ROSbots is a ROS + OpenCV robot kit for Makers. We recently which is based off the Raspberry Pi 3. The kit includes a camera, wheel encoders, two rechargeable lithium battery power sources, and even an Arduino-compatible UNO board for hardware PWM, interrupt, and ADC support. Hardware is fun, but more importantly, we want to use hardware to apply robotics concepts. That requires learning software and the know-how to implement these robotics concepts with modern software tools like and . As the 1st post from a multi-part series, we plan on publishing about concepts learned from the course and applying them to the ROSbots robot using ROS. The Control of Mobile Robots course sets the foundation to understand mobile — how to control your robot predictably and how to use sensor data to estimate pose and have your robot understand its surroundings. (Update 3/24/2018: — has been published.) Upon completing our multi-part series, you will have a working understanding of robotics control theory and ROS.
(Follow @rosbots for updates. Follow us on and too!)
If you have your own , we welcome you to follow along. Hands-on doing with your own ROSbots kit will add that more more color to what we write than simply reading this post. In this post, we’ll be prepping to implement the control models described in week 1 of Control of Mobile Robots. Specifically we’ll be doing the following in this post:L9110 mounted on the ROSbots robot and another one shown right side up. There are 2 input control pins per channel — IA and IB — that “drive” the 2 output pins — OA and OB connected to the ROSbots robot’s motors. Hence there are 4 input pins and 4 output pins total. There is a set of IA/IB/OA/OB pins for one channel A (which is connected to our left motor/wheel) and another for channel B (which is connected to the right motor/wheel). IA is what we PWM to modulate the motor speed. The IB pin controls motor direction. The L9110 pin table summarizes the input/output behavior:
L9110 input and output pin table Want a quick show-and-tell with your ROSbots robot?
We will drive the L9110 with the UNO board on our ROSbots robot by writing a ROS-capable Arduino Sketch for it. The (don’t forget to star and follow!). Let’s skip over a bunch of ROS specific code and jump directly to this block around line 16 onwards.
Notice that the right wheel’s IA (PWM) and IB (direction) pins are connected to the pins 5 and 4 respectively on the UNO board; left wheel’s IA and IB are connected to pins 6 and 7. Next let’s look at the block of code that actually drives the pins to turn the wheels.
Ignore the debug code in the comments
In the turnWheel(…) function, we clamp the input variable wheel_power between -1.0 (full reverse) and 1.0 (full forward). That modulates the PWM voltages that output to the respective L9110’s IA pin (aka pwm_pin ) and the digital voltage output to the IB pin (aka fr_pin, as in fwd-reverse).
The simple math during the analogWrite(…) linearly adjusts the PWM pulse width according to the direction specified by the sign of wheel_power — positive means forward, negative means reverse.
As the wheel_power goes from -1.0 to 1.0, you can see the pwm_pin and fr_pin transition from full reverse, to stop, to full forward as described by the L9110 pin table in the beginning of this post.
Let’s compile and upload this sketch code to our UNO board to see it in action. ROSbots uses to compile and upload ROS-Arduino sketch codes to the UNO board.~/$ upload_firmware ~/gitspace/rosbots_driver/platformio/rosbots_firmware/examples/motor_driver
(all one line)On our RPi, type rosnode list
to get a list of ROS nodes running — you should see the following:
Type rostopic list
to get a list of ROS topics being published or subscribed to — you should see the following:
In our example here, we wrote some Arduino sketch code to be a ROS node that subscribes to two topics — wheel_power_right and wheel_power_left. The message on these channels will be Float32 types (versus “images” in the hypothetical example above).
Take a look at this piece of the Arduino sketch code you compiled and uploaded:
You’ll notice that our UNO board subscribing to the two topic channels— wheel_power_right and wheel_power_left — with these 2 blocks of code.
When we get a message on either of these topics, we call the rightWheelCb(…) and leftWheelCb(…) callback respectively. That callback, if you recall, implemented the code to drive the L9110’s input pins.
If you recall typing rostopic list
the topic names wheel_power_right and wheel_power_left were listed.
If you recall again, when you typed rosnode list
, you saw an /uno_serial_node listed as one of the running ROS nodes. In order for ROS to be able to talk “serial port”, we need a bridge that serializes the ROS messages into serial port packets sent to our UNO to process. This bridge application is the ROS node known as — we named the node /uno_serial_node.
The /uno_serial_node’s job is to open a serial port connection to the UNO board and then serialize/deserialize ROS messages to and from the UNO board.
Type rostopic info /wheel_power_left
and you’ll see /uno_serial_node as the subscriber. Why doesn’t it say our UNO code?
Well remember our UNO board cannot talk to the ROS system directly — it only can talk with the /uno_serial_node via the serial port. Our UNO code does specify to the /uno_serial_node that it wants to subscribe to the /wheel_power_left topic and the /uno_serial_node subscribes to that topic on the UNO’s behalf. You can think of the rosserial /uno_serial_node as the mediator between the ROS world and the Arduino Sketch world.
OK — the UNO is a subscriber to topics /wheel_power_left and /wheel_power_right (via rosserial /uno_serial_node) which will drive the wheels depending on the Float32 message received. But who is the publisher?
No one for now. Instead we will use the ROS rostopic
tool to manually publish some ROS messages on these topic channels to drive the wheels.
rostopic pub -1 /wheel_power_left std_msgs/Float32 '{data: 1.0}'
— your left wheel should spin forwardrostopic pub -1 /wheel_power_left std_msgs/Float32 '{data: 0.0}'
— your left wheel should stoprostopic pub -1 /wheel_power_left std_msgs/Float32 '{data: -1.0}'
— your left wheel should spin backwardsrostopic pub -1 /wheel_power_left std_msgs/Float32 '{data: -0.5}'
— your left wheel should spin backwards slower.The rostopic pub
command tells ROS we want to publish. If you type rostopic pub --help
you’ll see a couple of options. The -1
option says just publish a message once versus continuously. The next option is the topic channel name. std_msgs/Float32
is the message type. '{data: 1.0}'
is the actual payload data. It’s in a JSON-like curly brace syntax because ROS generalizes messages as data structures. So the Float32 ROS message type defined from a bunch of standard (notice Float32 listed in the link). The is actually a data structure of one entity, a 32-bit float.
Congrats — you just successfully published your first set of ROS messages on a topic and wrote code to implement a ROS node that subscribes to and processes that message. Feel free to try the same exercise for the right wheel.
If you have questions, post them on with the subject “ROSbots question: whatever your question is” and tag the post with “rosbots”. We’ll be monitoring the forum and answer accordingly.
How does all this relate back to Coursera’s Control of Mobile Robots course? We are effectively building the components to turn the . Then we will add the feedback from the ROSbots’ wheel encoders to implement a PID controller for wheel velocity which will be able to allow us to estimate pose — position and orientation — of our robot. The final post in this series will completely implement the coding project described in the course. But instead of using Matlab, we will use ROS and our ROSbots robot! Follow @rosbots on Medium for updates. Follow us on and too!Feel free to comment here. But if you have technical questions, please post them on answers.ros.org (subject “ROSbots question: blahblah”, tag “rosbots”).
Don’t hesitate to reach out with general feedback, if you want to collaborate, or just to say hello. And if you haven’t already done so, to follow along.