Uso práctico de ROS en la Raspberry Pi - Parte 3

Buenas tardes, queridos lectores de Habr!

Continúo una serie de artículos sobre el uso práctico de ROS en la Raspberry Pi ( primer artículo , segundo artículo ).
En este artículo, utilizaremos el paquete teleop_twist_keyboard de la pila ros-teleop para controlar el robot presionando las teclas del teclado. La pila ros-teleop incluye, además de este paquete, varios paquetes más para varios métodos de control, por ejemplo, usando el joystick. ¿Quién está listo para comenzar a estudiar teleop_twist_keyboard, por favor, bajo cat.

Multiterminal con tmux


Mientras tanto, quiero contarte un truco que te permite trabajar de forma remota en Raspberry Pi a través de SSH al mismo tiempo en varias terminales. Para hacer esto, instale la utilidad tmux en RPi.

$ sudo apt-get install tmux

Después de eso, ejecute la utilidad:

$ tmux

Debe aparecer una barra verde en la parte inferior de la ventana de terminal con el número de ventana 0. 0.
tmux es un administrador de ventana de terminal muy conveniente que le permite crear cualquier cantidad de ventanas en una ventana de terminal colocándolas de varias maneras diferentes (ventana de terminal (ventana), panel de ventana ( panel)) y es conveniente cambiar entre ellos.

Presione Ctrl + B y C. en el teclado. Debería aparecer otra ventana con el número 1. Pruebe también la combinación de Ctrl + B y%. La ventana de terminal actual se dividirá en el medio por una franja verde vertical en dos ventanas (panel). Si presiona la combinación Ctrl + B,: e ingresa “ventana dividida”, la ventana se dividirá horizontalmente en dos ventanas idénticas. Para eliminar un panel (panel) use la combinación Ctrl + B, X y luego presione Y. Para cambiar a otro panel en la misma ventana, use la combinación Ctrl + B, O. Para cambiar entre las ventanas de terminal por el número de ventana, use la combinación Ctrl + B, <número de ventana>.

Ahora agregue el inicio del programa al archivo ~ / .bashrc para que se inicie automáticamente cuando abra un nuevo terminal. Agregue las siguientes líneas al archivo:

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


Trabajando con teleop_twist_keyboard


Ahora vamos a familiarizarnos con el paquete teleop_twist_keyboard.
Ejecute el script teleop_twist_keyboard.py desde el paquete teleop_twist_keyboard como un nodo ROS normal:

$ roscore
$ rosrun teleop_twist_keyboard teleop_twist_keyboard.py

Tenemos una conclusión como esta:

Reading from the keyboard  and Publishing to Twist!
---------------------------
Moving around:
   u    i    o
   j    k    l
   m    ,    .

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 : stop

CTRL-C to quit

Enumeramos todos los temas actualmente activos:

$ rostopic list

El tema / cmd_vel debería aparecer en la lista. Sobre este tema, el nodo teleop_twist_keyboard publica mensajes cada vez que se presiona una tecla en el teclado.
Mostramos el resultado de los mensajes publicados en el tema / cmd_vel:

$ rostopic echo cmd_vel

Ejecute rqt_graph para representar el gráfico calculado ROS en forma gráfica. El diagrama del gráfico computacional muestra todos los nodos activos y temas que los conectan.

$ rosrun rqt_graph rqt_graph

imagen

Aquí vemos que el nodo teleop_twist_keyboard publica mensajes en el tema / cmd_vel, y el nodo rostopic se suscribe a este tema (comando rostopic echo).
Veamos qué tipo de mensajes se publican en el tema / cmd_vel:

$ rostopic type /cmd_vel

El comando generará la línea:

geometry_msgs/Twist

Esto significa que los mensajes son del tipo Twist del paquete estándar ROS geometry_msgs.
También podemos obtener información sobre la estructura del mensaje con el comando rosmsg:

$ rosmsg show geometry_msgs/Twist


geometry_msgs/Vector3 linear
  float64 x
  float64 y
  float64 z
geometry_msgs/Vector3 angular
  float64 x
  float64 y
  float64 z

El campo 'lineal' es responsable de la velocidad lineal, 'angular' es para la velocidad angular.
Presione la tecla 'i', la salida será así (asociada con avanzar):

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

Presione la tecla 'k', la salida será así (detener):

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

Presione la tecla 'u', la salida será así (gire a la izquierda):

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

Y finalmente, cuando presiona la tecla 'o', obtenemos el siguiente resultado (gire a la derecha):

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

Las teclas 'j' y 'l' son responsables de girar a la izquierda y a la derecha en su lugar (sin avanzar).

Control de robot de teclado con teleop_twist_keyboard


Ya he escrito el boceto rosserial para controlar el robot presionando las teclas. Simplemente nos suscribimos al tema / cmd_vel y, dependiendo del valor recibido de cada una de las velocidades, le damos el comando necesario al controlador de movimiento (avanzar, parar, girar a la izquierda o derecha). El boceto se puede descargar desde aquí .
Analicemos el código del boceto con más detalle.
Al comienzo del archivo, además del archivo de encabezado ros.h estándar, conectamos dos archivos adicionales con los tipos de mensaje geometry_msgs / Twist.h y geometry_msgs / Vector3.h:

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

Declaramos un manejador de nodo ros :: NodeHandle:

ros::NodeHandle nh;

El valor principal es el método messageCb:

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(); }
}

En este método, procesamos el mensaje recibido del tema cmd_vel. En la variable forward_vel mantenemos la velocidad lineal, en la variable angular - angular. La velocidad lineal nos permite rastrear el comando de parada (valor 0). La velocidad angular determina la dirección de rotación (si es mayor que 0, luego gire a la izquierda, menor que 0 - a la derecha, si 0 - avance).
Cree un suscriptor para el tema / cmd_vel:

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

con una referencia al método de procesamiento de mensajes (messageCb) y al tipo de mensaje recibido: geometry_msgs :: Twist.
Al final del script, siguen los métodos de boceto estándar para rosserial_arduino:

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

Ejecute el servidor rosserial_arduino:

$ rosrun rosserial_python serial_node _port:=/dev/ttyACM0

y suba el boceto a la placa Arduino.

Cambie a la terminal donde se está ejecutando el nodo teleop_twist_keyboard, intente presionar las teclas 'u', 'i', 'o' y 'k' y verifique la salida del servidor rosserial en la terminal.

Por lo tanto, utilizando el paquete teleop_twist_keyboard, ahora podemos realizar un control remoto simple del robot mediante la transmisión de comandos de movimiento: avanzar, parar, girar a la izquierda o la derecha. En el futuro, aprenderemos cómo controlar el robot usando el joystick, lo cual es mucho más conveniente usando otro paquete en ROS. Pero más sobre eso en el próximo artículo.

Source: https://habr.com/ru/post/es390851/


All Articles