Home Robotics Practical use of ROS on Raspberry Pi – part 3

Practical use of ROS on Raspberry Pi – part 3

by admin

Good afternoon, dear Habra readers!
I am continuing a series of articles on the practical use of ROS on Raspberry Pi ( first article , second article ).
In this article we will use the teleop_twist_keyboard package from the ros-teleop to control the robot by pressing keys on the keyboard.The ros-teleop stack includes in addition to this package several more packages for different ways of controlling, for example with a joystick. If you are ready to learn teleop_twist_keyboard, please follow this link.

Multiterminal with tmux

In between, I want to tell you about a technique that allows you to work remotely on your Raspberry Pi via SSH in multiple terminals simultaneously. To do this, you need to install the tmux utility on the RPi.

$ sudo apt-get install tmux

After that we run the utility :

$ tmux

A green bar should appear at the bottom of the terminal window with the window number – 0.
tmux is a very handy terminal window manager which allows you to create any number of windows in one terminal window, placing them in several different ways (separate window-terminals, window pane) and switching between them conveniently.
Press Ctrl + B and C on your keyboard. Another window with the number 1 should open. Also try the combination Ctrl + B and %. The current terminal window will be divided in the middle by a vertical green bar into two windows (pane). If you press combination Ctrl + B, : and type "split window" the window will be split horizontally into two identical windows. To delete a pane use Ctrl + B, X and then press Y. To switch to another pane in the same window use combination Ctrl + B, O. To switch between terminal windows by window number use combination Ctrl + B, <window number> .
Now let’s add the program to the ~/.bashrc file to run automatically when a new terminal is opened. Add the following lines to the file :

[[ $TERM != "screen" ]] exec tmux

Working with teleop_twist_keyboard package

Now let’s get to know the teleop_twist_keyboard package.
Let’s run the teleop_twist_keyboard.py script from the teleop_twist_keyboard package as a normal ROS node:

$ roscore$ rosrun teleop_twist_keyboard teleop_twist_keyboard.py

We get an output of this form :

Reading from the keyboard and Publishing to Twist!---------------------------Moving around:u i oj k lm , .q/z : increase/decrease max speeds by 10%w/x : increase/decrease only linear speed by 10%e/c : increase/decrease only angular speed by 10%anything else : stopCTRL-C to quit

Display a list of all currently active topics :

$ rostopic list

The /cmd_vel topic should appear in the list. The teleop_twist_keyboard node publishes messages to this top every time a key was pressed on the keyboard.
Let’s show the output of messages published to the /cmd_vel topic:

$ rostopic echo cmd_vel

Let’s run rqt_graph to represent the ROS computational graph graph graphically. A schematic of the computational graph shows all active nodes and the tops that connect them.

$ rosrun rqt_graph rqt_graph

Practical use of ROS on Raspberry Pi - part 3
Here we see that the teleop_twist_keyboard node publishes messages to the /cmd_vel topic and the rostopic node subscribes to that topic (rostopic echo command).
Let’s find out what kind of messages are published to /cmd_vel:

$ rostopic type /cmd_vel

The command will print the string :

geometry_msgs/Twist

This means that the messages are of type Twist from the standard ROS package geometry_msgs.
We can also get information about the message structure with the command rosmsg:

$ rosmsg show geometry_msgs/Twist

geometry_msgs/Vector3 linearfloat64 xfloat64 yfloat64 zgeometry_msgs/Vector3 angularfloat64 xfloat64 yfloat64 z

The ‘linear’ field is for linear speed, the ‘angular’ field is for angular speed.
Press the ‘i’ key, the output will be like this (associated with forward motion):

linear:x: 0.5y: 0.0z: 0.0angular:x: 0.0y: 0.0z: 0.0---

Press the ‘k’ key, the output will be this (stop):

linear:x: 0.0y: 0.0z: 0.0angular:x: 0.0y: 0.0z: 0.0---

Press the ‘u’ key, the output will be like this (turn left):

linear:x: 0.5y: 0.0z: 0.0angular:x: 0.0y: 0.0z: 1.0---

And finally when you press the ‘o’ key you get this output (turn to the right):

linear:x: 0.5y: 0.0z: 0.0angular:x: 0.0y: 0.0z: -1.0---

The ‘j’ and ‘l’ keys are responsible for turning left and right on the spot (without moving forward).

Controlling the robot with the teleop_twist_keyboard

I have already written a rosserial sketch to control the robot by pressing keys. We just subscribe to /cmd_vel and depending on the value we get for each of the speeds we give the necessary command to the motion controller (move forward, stop, turn left or right). You can download the following sketch from here
Let’s take a closer look at the sketch code.
At the beginning of the file we include besides the standard header file ros.h two additional files with message types geometry_msgs/Twist.h and geometry_msgs/Vector3.h:

#include <geometry_msgs/Twist.h>#include <geometry_msgs/Vector3.h>

We declare a node handler ros::NodeHandle:

ros::NodeHandle nh;

The messageCb method is of primary importance:

void messageCb(const geometry_msgs::Twist message){geometry_msgs::Vector3 linear = message.linear;float forward_vel = float(linear.x);if(forward_vel == 0) { stop(); return; }geometry_msgs::Vector3 angular = message.angular;float ang_vel = float(angular.z);if(ang_vel > 0) { turnLeft(); }else if(ang_vel < 0) { turnRight(); }else { goForward(); }}

In this method we process the message we receive from the cmd_vel topic. In the forward_vel variable we store the linear velocity, and in the angular variable we store the angular velocity. The linear velocity allows us to track the stop command (value 0). The angular velocity determines the direction of the turn (if it is more than 0 then we turn left, if it is less than 0 then we turn right, if it is 0 then we go forward).
Create a subscribe to /cmd_vel topic:

ros::Subscriber<geometry_msgs::Twist> sub("/cmd_vel", messageCb);

with a reference to the message processing method (messageCb) and the type of message to receive – geometry_msgs::Twist.
At the end of the script follow the standard sketch methods for rosserial_arduino:

nh.initNode();nh.subscribe(sub);Serial.begin(57600);

Start the rosserial_arduino server :

$ rosrun rosserial_python serial_node _port:=/dev/ttyACM0

and upload the sketch to the Arduino board.
Switch to a terminal where the teleop_twist_keyboard node is running, try pressing the ‘u’, ‘i’, ‘o’ and ‘k’ keys and check the output of the rosserial server in the terminal.
So with the teleop_twist_keyboard package we can now do a simple remote control of the robot by sending motion commands: move forward, stop, turn left or right. Later we will learn how to use a joystick to control the robot which is much more comfortable with another package in ROS. But more about that in the next article.

You may also like