Plataforma popular para robots en ROS

El artículo está escrito solo para aquellos que son parte del propio ROS y que necesitan construir un robot real para entrenar o realizar tareas reales.







Cuando empiezas a aprender ROS, normalmente quieres trabajar con plataformas físicas y no con modelos en un simulador. De hecho, Gazebo es suficiente para estudiar solo algoritmos de movimiento o simplemente enseñar ROS, pero trabajar con una plataforma real permite comprender en la práctica todos los problemas con el movimiento de las ruedas. Bueno, ya menudo la plataforma se necesita simplemente como un requisito previo para el proyecto.



Para el futuro, es mejor comenzar con una ronda, porque por razones obvias, dicha configuración puede girar alrededor del eje sin tener en cuenta el tamaño de la parte que sobresale. El rectángulo de giro en U es mucho menos conveniente, por ejemplo, en pasillos estrechos; a veces es necesario desplegar 3 o más trucos, creo que los automovilistas lo entenderán.



Comprar plataformas prefabricadas



No hay muchas plataformas listas para usar en el mercado, se enumeran en el sitio web de ROS .



Al mismo tiempo, su costo en Rusia es lo suficientemente alto como para comenzar a trabajar; la opción más barata es Turtlebot Burger 3 - $ 549. Encontramos revendedores directamente en Rusia por unos 90.000 rublos.







En China, se puede comprar por 45-50 tr ... En cualquier caso, serán plataformas de pequeño tamaño y capacidad de carga, no capaces de realizar tareas reales.



Puede construir la plataforma usted mismo, hay muchas guías y configuraciones diferentes. Pero en promedio, resulta algo como:



  • Lidar clase Slamtech A1-A2
  • Ruedas económicas basadas en motores de colector con reductores
  • , PWM , UART + rosserial.
  • Single Board Computer — Raspberry, Jetson Nano
  • 2
  • gmapping + amcl/rosbot_ekf + move_base






No nos gustaron los motores de colector porque son ruidosos, tienen un consumo elevado y se necesita una caja de cambios. Aquí debo decir que las plataformas se consideran bastante pesadas, es decir, cajas de engranajes entrelazadas + motores algo como el motor de la foto no funcionará.



En consecuencia, se eligieron motores de rueda BLDC como motores. La opción más asequible en este momento son las ruedas de hoverboard 6.5. Solo queda gestionarlos desde ROS.



Pero luego surgió un problema: incluso cuando se trabajaba con robots de golf , se notó un problema significativo con la rotación de dicha plataforma a baja velocidad: el robot se giró bastante bruscamente.



Las razones de este comportamiento son simples: las fuerzas de fricción por deslizamiento juegan un papel importante en la resistencia al movimiento en el giro. Y tienen una peculiaridad: la resistencia depende de la masa y la naturaleza de las superficies en sí mismas, es por eso que un pequeño perno sostiene estructuras grandes con las primeras 2-3 vueltas.



Por lo tanto, hacer que las ruedas se estrechen en el centro para que giren se vuelve bastante inútil: la resistencia cambiará muy poco. La rueda de goma roza contra la hierba y el suelo, que no son en absoluto uniformes y la fuerza puede cambiar drásticamente, como resultado, se hizo algo así como una caja de cambios: a baja velocidad controlamos el momento en la rueda y con movimiento directo, la velocidad en sí.





Parecería que al conducir sobre parquet o linóleo, la situación debería ser mejor, pero, por desgracia, el coeficiente de fricción es casi el mismo (recuerde que los zapatos antideslizantes también están hechos de goma).







Como resultado, un robot que pesa entre 10 y 15 kilogramos ya está comenzando a desplegarse con sacudidas tangibles.



La segunda parte del problema es añadida por el paquete ROS diff_drive en combinación con placas SBC bastante débiles.



Aquí hay una lista de lo que logré entender



La gestión se lleva a cabo utilizando una implementación en tiempo real, pero no tiene en cuenta que otros paquetes deberían esperar este enfoque cuando se trabaja con la gestión.



Aquí debemos recordar que el tiempo real no es una reacción instantánea a un evento, sino una garantía de que el evento será procesado a intervalos garantizados de tiempo físico. Aquellos. La central hidroeléctrica condicional, regulada cada minuto (necesariamente cada) es también un sistema en tiempo real.

Existe la posibilidad de que los mensajes obstruyan los temas del planificador de rutas, y para los subsistemas de planificación de rutas y posicionamiento, este comportamiento generalmente conduce a detener y reiniciar el procesamiento de flujo, o a intentos de ajustar el proceso sobre la marcha.







Como resultado, en SBC débiles , surge una situación con un recálculo continuo de la ruta, o la búsqueda de localización consume un tiempo de procesador bastante grande, y cuantos más intentos se hacen para mantenerse al día con el componente RT, más tiempo se acumula. En su forma pura, retroalimentación positiva, que en este caso no es necesaria en absoluto.



Además de esto, gmapping no comienza a funcionar muy rápidamente con cambios abruptos en la posición de la plataforma y un lidar débil: se observaron pausas de hasta medio segundo, lo que también desconcierta enormemente al planificador de rutas.



Los motores se controlan por separado, por lo que cuando se utiliza SBC y la implementación ingenua de controladores, las ruedas se controlarán con cierta demora.



Aquí el problema es aún más simple: necesitamos controlar de 2 a 4 ruedas a través del canal de comunicación, que. En consecuencia, las señales de control se alinean y comienzan a transmitirse una tras otra: rueda izquierda, rueda derecha, rueda izquierda, rueda derecha.



Como resultado, las propias ruedas, y peor aún, las posiciones de las ruedas de los codificadores comienzan a contribuir a la formación del PIC entre la planificación del camino y el control de los motores.



La odometría incorporada es muy simplista.



Como no buscábamos una forma sencilla de sincronizar el comando y el retorno de la odometría, no pude encontrarlo. La sincronización siempre está asociada con la espera de algunos comandos en la entrada, pero no son regulares en el tiempo y, como resultado, la odometría comienza a demorarse en la salida. Quizás los lectores sugieran una manera fácil: aquí no nos consideramos un gurú en ROS.



No logramos que tal asamblea se comportara bien. Más precisamente, fue posible subestimar la aceleración del desplazamiento a 0.05-0.1 m / s ^ 2 y la velocidad angular a 0.03 rad / s.



Pensé que sería bueno tener:



  • Plataforma barata
  • Dirección de rueda síncrona
  • Cálculo de odometría basado en el comportamiento y manejo de la rueda
  • Modos de movimiento por giro con diferentes controles
  • Diferentes restricciones en diferentes modos.


Que pasó al final



El controlador se tomó de los tableros de gyro-scooter y el control de la rueda se escribió de tal manera que se usa el control de par al iniciar el movimiento y girar. Y si el carro va recto y acelera a una cierta velocidad, entonces se activa el modo de control de velocidad. En ambos modos, los datos de los codificadores se procesan dentro del controlador, teniendo en cuenta la velocidad y el modo, y los datos se emiten con alguna predicción antes de 10-15 ms.



Los codificadores siempre se leen en el controlador, se acumulan en un búfer de 2-3 elementos y se transmiten con retraso. La conclusión es que cuando se recibe el control, la respuesta se produce solo después de que se ejecuta el comando, es decir, el búfer se bloquea hasta que se reciben los valores del codificador modificados. Pero la odometría se está emitiendo, solo usa el último valor ya transmitido.



Porque Todos los problemas anteriores se redujeron al hecho de que, en cualquier caso, es necesario sincronizar el control sobre la recepción y transmisión síncrona desde el puerto UART, entonces consideramos irrazonable introducir un sincronizador forzado en el paquete diff_drive, por lo que escribimos nuestro propio paquete de control.



Se encuentra aquí github.com/Shadowru/hoverboard_driver y actualmente se está finalizando activamente:



el paquete se incluye en el archivo de inicio como:



<node name="hoverboard_driver" pkg="hoverboard_driver" type="node" output="screen">
        <param name="uart" value="{ }"/>
        <param name="baudrate" value="115200"/>
        <param name="wheel_radius" value="0.116"/>
        <param name="base_width”  value="0.43"/>
        <param name="odom_frame”  value="odom"/>
        <param name="base_frame”  value="base_link"/>
    </node>
      
      





El puerto uart en sí debe tener los derechos de acceso adecuados, en algunas plataformas no siempre tiene acceso para el usuario. Como ejemplo, para el Jetson Nano en el directorio hoverboard_driver / scripts / jetson_nano_serial.sh, se adjunta un script que asigna derechos al inicio del SO.



El paquete en sí contiene leer el flujo de datos del controlador y emitir la información relevante a los temas:



hoverboard_driver / hoverboard_msg con un paquete como hoverboard_msg



La estructura del mensaje es la siguiente:



int16 state1 - información interna en la rueda 1

int16 state2 - información interna en la rueda 2

int16 speed1 - velocidad instantánea de la rueda 1

int16 speed2 - velocidad instantánea de la rueda 2

int16 batVoltage - voltaje de la batería

int16 boardTemp - temperatura del controlador

int16 error1 - error de rueda 1

int16 error2 - error de rueda 2

int32 pulseCount1 - contador de codificador de rueda 1

int32 pulseCount2 - contador de codificador de rueda 2



Además, el tema hoverboard_driver / odometry recibe un mensaje típico nav_msgs :: Odometry La



posición se calcula de la siguiente manera:



Basado en los parámetros wheel_radius - radio ruedas en metros, base_width - la distancia entre los centros de las ruedas, calculamos cuánto se ha movido cada rueda durante el tiempo entre la posición anterior y la leída.



double curr_wheel_L_ang_pos = getAngularPos((double) feedback.pulseCount1);
double curr_wheel_R_ang_pos = getAngularPos((double) feedback.pulseCount2);

double dtime = (current_time - last_time).toSec();

double delta_L_ang_pos = curr_wheel_L_ang_pos - raw_wheel_L_ang_pos;
double delta_R_ang_pos = -1.0 * (curr_wheel_R_ang_pos - raw_wheel_R_ang_pos);
      
      





Luego calculamos la aceleración de cada una de las ruedas



wheel_L_ang_vel = delta_L_ang_pos / (dtime);
wheel_R_ang_vel = delta_R_ang_pos / (dtime);
      
      





A continuación, calculamos la aceleración lineal del robot a lo largo de cada uno de los ejes



robot_angular_vel = (((wheel_R_ang_pos - wheel_L_ang_pos) * wheel_radius / base_width) - robot_angular_pos) / dtime;
robot_angular_pos = (wheel_R_ang_pos - wheel_L_ang_pos) * wheel_radius / base_width;

robot_x_vel = ((wheel_L_ang_vel * wheel_radius + robot_angular_vel * (base_width / 2.0)) * cos(robot_angular_pos));
robot_y_vel = ((wheel_L_ang_vel * wheel_radius + robot_angular_vel * (base_width / 2.0)) * sin(robot_angular_pos));
      
      





Como resultado, se obtiene un conjunto completo: aceleración lineal, aceleración angular y, multiplicándolos por tiempo, el desplazamiento de la posición del robot.



robot_x_pos = robot_x_pos + robot_x_vel * dtime;
robot_y_pos = robot_y_pos + robot_y_vel * dtime;
      
      





Después de eso, se envía el mensaje de odometría, más una traducción tf entre el marco de odometría y la base.



El controlador de entrada está controlado por un paquete con 2 parámetros: velocidad y giro, el paquete se traduce de giro casi de forma nativa, la velocidad se divide por la circunferencia y se obtienen los giros.



double v = vel.linear.x;
double rps = v / rpm_per_meter;
double rpm = rps * 60;
int16_t speed = static_cast(rpm);

      
      





y la aceleración angular se convierte en la diferencia de velocidades de las ruedas en forma de multiplicación por un coeficiente, se agregarán nuevos cálculos teniendo en cuenta la distancia entre ejes, pero en la práctica esto solo es necesario para robots suficientemente grandes y pesados.



double w = vel.angular.z;
int16_t steer = static_cast<int>(-1 * w * 30);

      
      





Como resultado, fue posible lograr un control de carro muy estable con componentes baratos.







Creamos robots, como la gran mayoría de ustedes. Tenemos nuestro producto principal, que estamos desarrollando activamente. Probado piloto y listo para producción. Este es un robot para recolectar pelotas de golf.



Desarrollamos robots a medida y soluciones derivadas. A veces, se trata de un trabajo desde la asignación técnica y el boceto hasta el producto terminado, a veces parte del trabajo.







En la mayoría de los casos, el robot necesita ruedas para interactuar con el mundo exterior. La mayoría de las veces, estos son motores sin escobillas, debido a la capacidad de controlar con precisión la velocidad y la posición.



Para los robots pequeños, a menudo se usan ruedas de un giroscopio, esto se justifica debido a la producción en masa y al precio de esta solución. Cualquiera que haya visto la lista de precios de los motores rusos comprende la importancia de la producción en masa.







En cuanto al controlador, la mayoría de las veces se trata de modelos esc, vesc, odrive, BLD-300B o soluciones caseras.



Para entrar fácilmente en la creación de robots reales y romper la maldición de Gazebo, la mayoría de los desarrolladores necesitan una ballena para entrar fácilmente. Gran parte del mundo real es diferente del ideal.



A veces suceden cosas impredecibles, los sensores son ruidosos, en tiempo real, se desbordan el búfer. En este dispositivo de video, que probamos previamente con un contactor y un kilswitch remoto.





Ofrecemos algo que nos ayudaría a ahorrar nervios a su debido tiempo, este es un kit para armar la caja (paralelepípedo y cilindro), dos motor-ruedas, una batería, un cargador y un controlador flasheado que da odometría y funciona con nuestro paquete ROS listo para usar. 19.000 frotar. Es más barato que el fresado, el costo del material compuesto, los sujetadores y una rueda giratoria acolchada.







Llámenos o solicite una plataforma para ROS en línea . Hagamos robots juntos. Te contaremos



más sobre la plataforma en la reunión de Robot Operating System el 5 de diciembre. La inscripción para los participantes ya está abierta.



→ Registro para espectadores



All Articles