-
Notifications
You must be signed in to change notification settings - Fork 1
1: OLD_PROJECT: Noviembre 2022
El Principio de dirección de Ackerman define la geometría que se aplica a todos los vehículos (dos o cuatro ruedas motrices) para permitir que se genere el ángulo de giro correcto de los volantes al tomar una esquina o una curva. ¿Cómo funciona? Para el correcto funcionamiento de la dirección, cada rueda delantera tiene que tener un ángulo concreto de tal manera que las rectas perpendiculares a cada rueda se corten en un mismo punto C, que pasará a ser el centro de giro. Es importante que las ruedas delanteras no sean paralelas ya si ambas ruedas giraran en la misma cantidad, la rueda interior se deslizaría y disminuiría la efectividad de la dirección.
Para simular el vehículo vamos a usar el simulador Gazebo.
Como primera toma de contacto, voy a tratar de hacer funcionar el mundo de citySim.
Para usarlo:
Nos descargamos el repositorio de citySim
Dentro del directorio raíz del repositorio hacemos:
mkdir build
cd build
cmake ..
make install
Tras tratar de compilar el repositorio, falla con este error:
CMake Error at CMakeLists.txt:29 (find_package):
Could not find a configuration file for package "gazebo" that is compatible
with requested version "9".
The following configuration files were considered but not accepted:
/usr/lib/x86_64-linux-gnu/cmake/gazebo/gazebo-config.cmake, version: 11.10.2
/lib/x86_64-linux-gnu/cmake/gazebo/gazebo-config.cmake, version: 11.10.2
Como vemos, citySim requiere de tener gazebo version 9 instalado. Parece no aceptar gazebo 11 (instalado).
Antes de instalar gazebo 9, he tratado de modificar la parte del CMakeLists.txt en la cual se establece la versión requerida de Gazebo. Cambiando find_package(gazebo 9 REQUIRED) por find_package(gazebo 11 REQUIRED)
El resultado es:
/home/vidi/tfg/citysim/plugins/TrafficLightsGUIPlugin.cc: In member function ‘void gazebo::TrafficLightsGUIPlugin::OnKeyPress(ConstAnyPtr&)’:
/home/vidi/tfg/citysim/plugins/TrafficLightsGUIPlugin.cc:80:52: error: incomplete type ‘gazebo::common::Color’ used in nested name specifier
80 | auto red = std::make_pair(gazebo::common::Color::Red, "red");
No compila. Gazebo 11 no sigue la sintaxis debida. Para solucionar esto, hay que modificar el código de citysim.
Para actualizar el mundo de ejemplo, ejecutamos el generador del mundo:
cd worlds
erb simple_city.world.erb > simple_city.world
Solo el Toyota de CitySim
Como el fallo, en principio, lo da en el plugin del semáforo, voy a intentar hacer funcionar el paquete del coche sin más. Este paquete es muy viejo (Se hizo para ubuntu 16.04 y Ros1 Kinetic). En principio la demo corre en un docker. El nvidia-docker que requiere, además está deprecated. Hay que modificarlo:
- Necesito la descripción del modelo: Se encuentra en /prius_description (Además tiene los modelos de cada parte por separado)
- Necesito un plugin que sea capaz de leer de un topic un cierto formato de mensaje M que mueva en el mundo de gazebo cada joint: En principio, hay uno en /car_demo/plugins (Habrá que extraerlo de ahí y aprender a usarlo/modificarlo para gazebo11 y ros2).
- Necesito el formato de mensaje M: Este se encuentra en /prius_msgs.
- Necesito un launcher que lanze tanto el modelo del coche, como los plugins necesarios.
El reto aquí reside en conseguir hacer funcionar un paquete bastante antiguo, en Ubuntu 22.04 ROS2 Humble y gazebo11. (Todo actualizado).
Para crear el nuevo paquete, he usado esta fuente y fuente para hacerme a la idea de cómo es un paquete bien estructurado en ROS2.
Creamos el paquete de ROS2 con:
ros2 pkg create "car_sim2" --dependencies rclcpp"
Un gran reto es conseguir mover el coche en gazebo11 usando los topics de ROS2.
El plugin existente está hecho para ROS1 y es extenso. Además usa la API de gazebo9.
Para convertir un .urdf a .sdf sudo gz sdf -p prius.urdf > prius.sdf
para que me lo admita gazebo: models/nombres/
model.sdf model.config https://github.com/NovoG93/car_demo
De momento he necesitado bajarme Xacro https://github.com/ros/xacro/tree/hydro-devel Esto si funciona a la primera. No he necesitado hacer el vcs import.
Problema: El robot no aparece en gazebo y muchos errores: Traceback (most recent call last): File "/opt/ros/humble/lib/python3.10/site-packages/launch/actions/execute_local.py", line 545, in __execute_process transport, self._subprocess_protocol = await async_execute_process( File "/opt/ros/humble/lib/python3.10/site-packages/osrf_pycommon/process_utils/async_execute_process_asyncio/impl.py", line 139, in async_execute_process transport, protocol = await _async_execute_process_nopty( File "/opt/ros/humble/lib/python3.10/site-packages/osrf_pycommon/process_utils/async_execute_process_asyncio/impl.py", line 45, in _async_execute_process_nopty transport, protocol = await loop.subprocess_exec( File "/usr/lib/python3.10/asyncio/base_events.py", line 1667, in subprocess_exec transport = await self._make_subprocess_transport( File "/usr/lib/python3.10/asyncio/unix_events.py", line 207, in _make_subprocess_transport transp = _UnixSubprocessTransport(self, protocol, args, shell, File "/usr/lib/python3.10/asyncio/base_subprocess.py", line 36, in init self._start(args=args, shell=shell, stdin=stdin, stdout=stdout, File "/usr/lib/python3.10/asyncio/unix_events.py", line 799, in _start self._proc = subprocess.Popen( File "/usr/lib/python3.10/subprocess.py", line 969, in init self._execute_child(args, executable, preexec_fn, close_fds, File "/usr/lib/python3.10/subprocess.py", line 1845, in _execute_child raise child_exception_type(errno_num, err_msg, err_filename) FileNotFoundError: [Errno 2] No such file or directory: 'xterm'
Problemas de links [rviz2-2] at line 93 in ./src/buffer_core.cpp [rviz2-2] Warning: Invalid frame ID "front_right_wheel" passed to canTransform argument source_frame - frame does not exist [rviz2-2] at line 93 in ./src/buffer_core.cpp [rviz2-2] Warning: Invalid frame ID "rear_left_wheel" passed to canTransform argument source_frame - frame does not exist [rviz2-2] at line 93 in ./src/buffer_core.cpp [rviz2-2] Warning: Invalid frame ID "rear_right_wheel" passed to canTransform argument source_frame - frame does not exist [rviz2-2] at line 93 in ./src/buffer_core.cpp [rviz2-2] Warning: Invalid frame ID "steering_wheel" passed to canTransform argument source_frame - frame does not exist [rviz2-2] at line 93 in ./src/buffer_core.cpp
cosas aprendidas: No usar repos antiguos desactualizados y abandonados
Volví a arrancarlo y arrancó...
Ahora quiero ver como mover el robot mediante topics: Node( package="car_demo", executable="prius_teleop_keyboard.py", name="prius_teleop", prefix=["xterm -hold -e"], output="screen", ),
veo esta parte en el launch. Este programa en python sirve para teleoperarlo mediante las teclas. Voy a ver como funciona.
Formato del mensaje: std_msgs/Header header
Range 0 to 1, 1 is max throttle float64 throttle Range 0 to 1, 1 is max brake float64 brake Range -1 to +1, +1 is maximum left turn float64 steer
uint8 NO_COMMAND=0 uint8 NEUTRAL=1 uint8 FORWARD=2 uint8 REVERSE=3
uint8 shift_gears
4 adelante y 4 atrás. Sólo "ven" aquello por delante y por detrás del coche a una distancia máxima de 4m. Al ser de tipo sonar, tienen un cono de detección.
Posee 3 sensores. De los cuales solo parece funcionar el centerLaser. Este es un lidar 360º. Pero tiene puntos ciegos: El haz del láser parece provenir del techo del vehículo. Esto hace que el techo haga cierta oclusión de los objetos más cercanos al vehículo. Situación real aparcamiento: Visión del lidar: Para coches puede valer. Pero si el obstáculo es más bajo, no lo puede detectar. Además no tiene sónar laterales. ¿Debería incorporarlos? Los únicos sensores que sí lo ven son las cámaras de los espejos. ¿Por medio de visión y YOLO o similares será capaz de detectar obstáculos bajos a los laterales?
4 cámaras: Frontal, trasera, retrovisor derecho, retrovisor izquierdo.
Este paquete, tiene un plugin que toma los mensajes del topic /prius/control y hace mover el modelo en el simulador. Es decir, para controlar el coche, necesitamos publicar mensajes en ese topic. Los mensajes de control tienen los siguientes campos:
Acelerador: valores de 0 a 1
float64 throttle
Freno: valores de 0 a 1
float64 brake
Dirección: valores de -1 a 1 . 1 es girado al máximo a la izquierda
float64 steer
Caja de cambios, puede tener diferentes valores:
- NO_COMMAND no cambiamos nada
- NEUTRAL punto muerto
- FORWARD marcha adelante
- REVERSE marcha atrás
uint8 shift_gears
El software debe comprenderse de varios módulos:
- Uno que convierta los datos de los sensores en información relevante para el sistema. (Percepción)
- Uno que en función de lo conocido planifique las maniobras. (Deliberación)
- Uno que se encargue de orquestar los actuadores obedeciendo al módulo deliberativo (Actuación)