Home - miguelvmonroy/Unmanned-Surface-Vehicle GitHub Wiki

🚤 Lancha Autónoma — Wiki

ES: Wiki del proyecto Lancha Autónoma (USV — Unmanned Surface Vehicle).

EN: Wiki of the Autonomous Boat (USV — Unmanned Surface Vehicle) project.


🎯 Objetivo / Objective

ES: Desarrollar una lancha autónoma para navegación en entornos acuáticos, implementando sistemas de control y navegación autónoma, validando algoritmos en simulación (VRX) y desplegando en hardware real.

EN: Develop an autonomous boat for navigation in aquatic environments, implementing control and autonomous navigation systems, validating algorithms in simulation (VRX), and deploying to real hardware.


🛠️ Tecnologías / Technologies

Tecnología Versión Propósito
ROS 2 Jazzy Framework de robótica
Gazebo Harmonic Simulador 3D
VRX Última Simulador USV
Python 3.12 Scripts de control
C++ 17 Nodos ROS 2

📊 Estado del Proyecto / Project Status

Módulo Estado Progreso
Simulación VRX ✅ 100%
Control Manual ✅ 100%
Monitoreo de Sensores ✅ 100%
Navegación Autónoma 🔄 40%
Pruebas de Hardware ⏳ 0%

🖥️ Hardware

Componente Especificación
Portátil ASUS TUF Gaming F15 (FX506HC)
CPU Intel Core i5-11400H
RAM 32 GB
GPU NVIDIA GeForce RTX 3050 Mobile

Distribución de discos:

  • nvme0n1 (512 GB) — Windows 11
  • nvme1n1 (1 TB) — Ubuntu + Backup

🔧 Instalación / Installation

Requisitos

  • Windows 11 con WSL2 (o Ubuntu nativo)
  • 20 GB de disco disponible
  • 8 GB RAM mínimo (16 GB recomendado)

Pasos principales

1. WSL2 + Ubuntu 24.04

wsl --install -d Ubuntu-24.04

2. Gazebo Harmonic

sudo apt install gz-harmonic -y

3. ROS 2 Jazzy

sudo apt install ros-jazzy-desktop-full -y
echo "source /opt/ros/jazzy/setup.bash" >> ~/.bashrc

4. VRX (compilado desde fuente)

mkdir -p ~/vrx_ws/src && cd ~/vrx_ws/src
git clone https://github.com/osrf/vrx.git -b jazzy
cd ~/vrx_ws && rosdep install --from-paths src --ignore-src -r -y
colcon build --merge-install --symlink-install
echo "source ~/vrx_ws/install/setup.bash" >> ~/.bashrc

Verificación

ros2 -h
gz sim --help
ros2 pkg list | grep vrx

⚠️ Nota: En WSL2 se requiere export LIBGL_ALWAYS_SOFTWARE=1 para evitar fallos de OpenGL. En Ubuntu nativo con GPU NVIDIA se puede habilitar D3D12 para aceleración.


🎮 Control del WAM-V / WAM-V Control

Script de control manual

cd ~/vrx_ws/src/vrx/scripts
python3 teleop_wamv.py

Controles

Tecla Acción Descripción
i ⬆️ Avanzar Ambos propulsores avanzan
k ⏹️ Detener Ambos propulsores se detienen
j ⬅️ Girar izquierda Derecho avanza, izquierdo retrocede
l ➡️ Girar derecha Izquierdo avanza, derecho retrocede
q 💪 Aumentar potencia +10% empuje
z 💪 Reducir potencia -10% empuje
Ctrl+C ❌ Salir Detiene y cierra

Control directo por tópicos

# Avanzar (50%)
ros2 topic pub /wamv/thrusters/left/thrust std_msgs/msg/Float64 "{data: 50.0}" --once
ros2 topic pub /wamv/thrusters/right/thrust std_msgs/msg/Float64 "{data: 50.0}" --once

# Girar izquierda
ros2 topic pub /wamv/thrusters/left/thrust std_msgs/msg/Float64 "{data: -50.0}" --once
ros2 topic pub /wamv/thrusters/right/thrust std_msgs/msg/Float64 "{data: 50.0}" --once

# Detener
ros2 topic pub /wamv/thrusters/left/thrust std_msgs/msg/Float64 "{data: 0.0}" --once
ros2 topic pub /wamv/thrusters/right/thrust std_msgs/msg/Float64 "{data: 0.0}" --once

Movimiento según propulsores

Izquierdo Derecho Movimiento
300 300 Recto hacia adelante
500 200 Girar a la derecha
200 500 Girar a la izquierda
-300 -300 Reversa
300 -300 Girar en el lugar

🎯 Navegación Autónoma A→B / Autonomous A→B Navigation

Descripción

Controlador proporcional que navega el WAM-V desde su posición actual (punto A) hasta un destino (punto B) sin intervención manual.

Características:

  • Lee la pose del WAM-V desde Gazebo (/world/sydney_regatta/dynamic_pose/info)
  • Calcula distancia y rumbo (usando cuaterniones)
  • Publica comandos a los propulsores con corrección de rumbo
  • Se detiene automáticamente al llegar (< 3 m del destino)

Ubicación: ~/vrx_ws/src/vrx/scripts/controlador_ab.py

Lanzamiento (4 terminales)

Terminal 1 — Gazebo + VRX:

cd ~/vrx_ws
source install/setup.bash
ros2 launch vrx_gz competition.launch.py world:=sydney_regatta

Terminal 2 — Visualizador v6 (opcional):

source ~/vrx_ws/install/setup.bash
python3 ~/vrx_ws/src/vrx/scripts/visualizar_trayectoria_v6.py

Terminal 3 — RViz2 (opcional):

source ~/vrx_ws/install/setup.bash
rviz2

Terminal 4 — Controlador A→B:

source ~/vrx_ws/install/setup.bash
python3 ~/vrx_ws/src/vrx/scripts/controlador_ab.py

Parámetros

Parámetro Descripción Valor por defecto
PUNTO_B Coordenadas de destino (x, y) (-500.0, 200.0)
DISTANCIA_LLEGADA Umbral para "llegado" 3.0 m
POTENCIA_MAX Potencia máxima 400
GANANCIA_ANGULO Kp para corrección de rumbo 1.5
DISTANCIA_FRENADO Distancia de frenado 10.0 m

Cambiar destino

sed -i 's/PUNTO_B = (-500.0, 200.0)/PUNTO_B = (-480.0, 150.0)/' \
~/vrx_ws/src/vrx/scripts/controlador_ab.py

Diferencias WSL2 vs Ubuntu Nativo

Aspecto WSL2 Ubuntu Nativo
Entorno WSL2 con .wslconfig Ubuntu 24.04 nativo
Mundo waypoint_race.sdf sydney_regatta.sdf
Puntos A/B Boyas físicas Coordenadas en script
Control Solo posición Rumbo real (cuaterniones)
Parser gz model -m wamv -p gz topic -e dynamic_pose/info
Frecuencia ~2 Hz ~20 Hz
Rutas validadas 1 2

🎯 Controlador Proporcional Puro (P) / Pure Proportional Controller

Concepto

Un controlador proporcional (P) es el tipo más simple de lazo cerrado:

$$u(t) = K_p \cdot e(t)$$

Donde el error es la distancia euclidiana al goal:

$$e = \sqrt{(X - X_G)^2 + (Y - Y_G)^2}$$

Características:

  • Sin término integral (I): no elimina error en estado estacionario
  • Sin término derivativo (D): no amortigua oscilaciones
  • Fácil de implementar: solo una ganancia
  • Respuesta rápida

Limitación conocida: un P puro sobre distancia no corrige el rumbo. Si el WAM-V arranca con un heading que no apunta al goal, se desviará.

Resultados experimentales (Kp = 1.0)

Métrica Valor
Duración 793.1 s (~13 min)
Muestras 15,860 @ 20 Hz
Error inicial 30.21 m
Error final 243.74 m ⚠️
Posición inicial (-532.26, 161.96)
Posición final (-407.56, 340.18)
Goal (B) (-560.00, 150.00)
¿Llegó? ❌ No

Observaciones:

  • El error creció en lugar de disminuir
  • El WAM-V se alejó del goal — navegó en dirección opuesta
  • La señal u siguió la ecuación — u = Kp·e se cumplió en cada muestra
  • La saturación se alcanzó cuando e > 400

Análisis

El controlador P puro sobre distancia no corrige el rumbo del WAM-V. Cuando el heading inicial no apunta hacia el goal, el WAM-V avanza en la dirección de su proa y se aleja del destino.

Esto NO es un error del código — es una limitación estructural del control P puro sobre distancia. La ecuación se cumple perfectamente en cada muestra (15,860 registros verificados), pero el comportamiento del sistema no es el deseado para navegación autónoma.

Conclusión

  1. Se implementó correctamente el controlador P puro ($u = K_p \cdot e$)
  2. Se verificó empíricamente la ecuación de control en cada muestra
  3. Se descubrió una limitación importante: el control P puro sobre distancia no navega autónomamente
  4. El WAM-V se aleja del goal cuando su heading inicial no apunta hacia el destino
  5. Se motiva la siguiente fase: añadir un segundo lazo P sobre el error de rumbo

📡 Visualizador de Trayectoria del WAM-V

Descripción

Script de Python que:

  • Lee /world/sydney_regatta/dynamic_pose/info desde Gazebo usando gz topic -e
  • Parsea la posición del WAM-V usando regex
  • Publica un Marker LINE_STRIP en /trayectoria_wamv
  • RViz2 lo renderiza en tiempo real

Ubicación: ~/vrx_ws/src/vrx/scripts/visualizar_trayectoria_v6.py

Configuración de RViz2 (primera vez)

  1. Fixed Frame: wamv/wamv/base_link
  2. Add → By topic → /trayectoria_wamv → Marker
  3. Target Frame: wamv/wamv/base_link
  4. Distance: 30
  5. Focal Point: X=0, Y=0, Z=0

Verificación

# Frecuencia de pose (esperado ~95 Hz)
timeout 10 ros2 topic hz /wamv/pose

# Frecuencia del visualizador (esperado ~20 Hz)
timeout 10 ros2 topic hz /trayectoria_wamv

🎮 Sistema Completo — 5 Terminales

Terminal 1: Gazebo + VRX

cd ~/vrx_ws
source install/setup.bash
ros2 launch vrx_gz competition.launch.py world:=sydney_regatta

⏳ Esperar ~45 segundos para que cargue Gazebo.

Terminal 2: Visualizador v6

source ~/vrx_ws/install/setup.bash
python3 ~/vrx_ws/src/vrx/scripts/visualizar_trayectoria_v6.py

✅ Esperar mensaje: "Visualizador v6 iniciado".

Terminal 3: RViz2

source ~/vrx_ws/install/setup.bash
rviz2

Terminal 4: Propulsor Izquierdo

source ~/vrx_ws/install/setup.bash
ros2 topic pub -r 20 /wamv/thrusters/left/thrust std_msgs/msg/Float64 "data: 300.0"

Terminal 5: Propulsor Derecho

source ~/vrx_ws/install/setup.bash
ros2 topic pub -r 20 /wamv/thrusters/right/thrust std_msgs/msg/Float64 "data: 300.0"

Resultado esperado

  • Gazebo: WAM-V moviéndose sobre el agua
  • Terminal 2: Punto 50 | (-532.05, 162.03) cada ~8 seg
  • RViz2: Trayectoria naranja dibujándose en curva

Detener todo

pkill -9 -f "gz sim"
pkill -9 -f "ros2 launch"
pkill -9 -f "parameter_bridge"
pkill -9 -f "visualizar_trayectoria"
pkill -9 -f "rviz2"
pkill -9 -f "ros2 topic pub"

Problemas comunes

Problema Solución
WAM-V no aparece en Gazebo Esperar otros 45 segundos
Visualizador sin puntos Lanzar Terminales 4 y 5
RViz2 no dibuja trayectoria Verificar Fixed Frame = wamv/wamv/base_link
Tópicos no existen Ejecutar source ~/vrx_ws/install/setup.bash

🚀 Aceleración por GPU en WSL2

Objetivo

Mejorar los FPS de ~10 a ~60+ migrando de renderizado por software (llvmpipe) a D3D12 con GPU NVIDIA.

Requisitos

  • Windows 11 (22H2+)
  • WSL2 con Ubuntu 24.04
  • GPU NVIDIA (RTX 3050+)
  • Driver NVIDIA 570+ en Windows

Verificación

ls -la /dev/dxg
glxinfo -B
nvidia-smi
ls -la /usr/lib/wsl/lib/libd3d12*

Configuración en ~/.bashrc

# GPU NVIDIA para WSL2 (D3D12)
export GALLIUM_DRIVER=d3d12
export MESA_D3D12_DEFAULT_ADAPTER_NAME=NVIDIA
export LIBGL_ALWAYS_SOFTWARE=0
export LD_LIBRARY_PATH=/usr/lib/wsl/lib:$LD_LIBRARY_PATH

# ROS 2 Jazzy + VRX
source /opt/ros/jazzy/setup.bash
source ~/vrx_ws/install/setup.bash

Verificación final

glxinfo -B | grep -E "renderer|Accelerated|Device"

Salida esperada:

Device: D3D12 (NVIDIA GeForce RTX 3050 Laptop GPU)
Accelerated: yes
OpenGL renderer string: D3D12 (NVIDIA GeForce RTX 3050 Laptop GPU)

📈 Cifras Finales / Final Figures

Métrica WSL2 (antes) Ubuntu Nativo (ahora) Objetivo
Frecuencia de pose 5 Hz 95 Hz ≥ 50 Hz
Latencia ~430 ms ~10 ms ≤ 20 ms
Estado ❌ ✅ margen 2x —

🐛 Problemas Resueltos / Resolved Issues

  1. WSL2 con alta latencia → Migrar a Ubuntu nativo
  2. El instalador de Xubuntu falla → Usar debootstrap (CLI)
  3. BitLocker bloquea el acceso → Suspender BitLocker primero
  4. fstab vacío causó modo de solo lectura → Escribir usando UUIDs
  5. /wamv/pose devuelve datos del sensor, no la pose mundial → Usar /world/sydney_regatta/dynamic_pose/info
  6. RViz2 descarta el Marker → frame_id = "wamv/wamv/base_link"

🤝 Contribuciones / Contributions

ES: Las contribuciones son bienvenidas. Sigue estos pasos:

  1. Haz un fork del proyecto
  2. Crea tu rama: git checkout -b feature/AmazingFeature
  3. Commit: git commit -m 'Add some AmazingFeature'
  4. Push: git push origin feature/AmazingFeature
  5. Abre un Pull Request

Consulta la Guía de Contribución para más detalles.

EN: Contributions are welcome. Please follow these steps:

  1. Fork the project
  2. Create your feature branch: git checkout -b feature/AmazingFeature
  3. Commit your changes: git commit -m 'Add some AmazingFeature'
  4. Push to the branch: git push origin feature/AmazingFeature
  5. Open a Pull Request

Check the Contribution Guide for more details.


📄 Licencia / License

ES: Este proyecto está bajo la Licencia MIT — consulta el archivo LICENSE para más detalles.

EN: This project is licensed under the MIT License — see the LICENSE file for details.


📞 Contacto / Contact


⭐ ES: Si te gusta este proyecto, ¡no olvides darle una estrella en GitHub!

⭐ EN: If you like this project, don't forget to star it on GitHub!


Última actualización / Last update: Septiembre 2026 / September 2026