La fusión de odometría (EKF) no trata a todos los sensores por igual: los pondera según su fiabilidad. Ese peso es la covarianza. Ajustándola por sensor se obtienen perfiles de odometría —recetas de confianza— que se adaptan a cada ambiente: una sala con paredes, un pasillo largo, un espacio abierto o un suelo resbaladizo. Este estudio define el mecanismo, la fuerza de cada sensor por entorno, y un conjunto de perfiles listos para configurar.
1 El peso es la covarianza
En un filtro de Kalman, cada medida entra con una covarianza que expresa cuánta incertidumbre tiene. El filtro calcula la ganancia de Kalman, que reparte la corrección de forma inversa a la covarianza: menos covarianza → más confianza → más peso; más covarianza → se ignora casi.
peso ∝ 1covarianzabajar la covarianza de un sensor = subir su fader en la mezcla
No hay un parámetro literal llamado «peso»: se sube o baja el fader ajustando la covarianza de cada fuente. Es exactamente una mesa de mezclas donde cada sensor es un canal.
2 Las palancas que ofrece robot_localization
El EKF del robocar (robot_localization) da cuatro palancas para ponderar, de la más gruesa a la más fina:
Covarianza de la medida. La que trae cada mensaje (la del /imu, la que fija el adaptador del encoder, la que publica rf2o). Es el fader principal de cada canal.
Matriz de configuración por eje. Para cada fuente se eligen qué componentes se fusionan (x, y, yaw, vx, vyaw…). Permite algo muy potente: usar solo parte de un sensor — p. ej. fusionar el yaw del láser pero no su avance longitudinal en un pasillo.
Umbral de rechazo (Mahalanobis)...._rejection_threshold descarta medidas que se apartan demasiado de la predicción: un cortafuegos contra saltos (un derrape, un mal emparejamiento del láser).
Ruido de proceso (Q). Cuánto se fía el filtro de su propio modelo frente a las medidas. Sube la agilidad o la suavidad global.
El truco por eje
La matriz de configuración es la clave para adaptar a entornos difíciles. En un pasillo largo el láser estima mal el avance (todo se ve igual a lo largo), pero sigue estimando bien el giro y la posición lateral. Solución: fusionar del láser solo yaw y y, dejar el avance x al encoder. No es todo-o-nada.
3 Fuerza de cada sensor según el entorno
Antes de recetar perfiles, qué sensor brilla y cuál falla en cada situación:
Sensor
Mide
Fuerte en
Débil en
Encoder
velocidad de rueda
suelo con agarre, avance recto
patinaje arranques, suelo resbaladizo
IMU · giróscopo
velocidad de giro
casi todo inmune al patinaje
deriva de bias en giros muy largos
Láser (rf2o)
desplazamiento vs entorno
salas con estructura paredes, esquinas
pasillos/espacios abiertos geometría pobre; CPU
Dirección
v·tanδ/L
marcha normal, redundancia de yaw
derrape deslizamiento; ángulo comandado
Dos ejes de fallo dominan: el deslizamiento (hunde encoder y dirección; giróscopo y láser aguantan) y la pobreza geométrica del entorno (hunde el láser; encoder y giróscopo aguantan). Los perfiles se construyen para que en cada ambiente pesen los sensores que no fallan ahí.
4 Perfiles de odometría
Cada perfil es una receta de pesos (faders) por sensor, pensada para un ambiente. El nivel es la confianza: a más nivel, menos covarianza.
Nivel de confianza: OFF bajo medio alto
Interior estructurado
Sala / mapeo
EncoderMEDIO
GiróscopoALTO
LáserALTO
DirecciónBAJO
Por qué: con paredes y esquinas el láser es preciso e inmune al patinaje; el giróscopo fija el rumbo. El encoder aporta escala; la dirección, redundancia menor. Es el perfil por defecto para mapear con Cartographer.
Geometría degenerada
Pasillo largo
EncoderALTO
GiróscopoALTO
Láser (yaw+lat.)PARCIAL
DirecciónMEDIO
Por qué: a lo largo del pasillo el láser no distingue el avance → se le desactiva la componente x y se conserva solo yaw y y. El encoder lleva el avance; el giróscopo, el rumbo.
Espacio abierto
Nave / exterior
EncoderALTO
GiróscopoALTO
LáserOFF
DirecciónMEDIO
Por qué: sin paredes en rango el láser no ve nada útil → se apaga para no meter ruido. Queda dead-reckoning: encoder + giróscopo (+ dirección como refuerzo cinemático). Cuidado con la deriva a largo plazo.
Baja tracción
Suelo resbaladizo
EncoderBAJO
GiróscopoALTO
LáserALTO
DirecciónOFF
Por qué: el patinaje engaña a encoder y dirección → se bajan mucho. El láser (mide contra el entorno) y el giróscopo (mide el giro real) son inmunes al resbalón y sostienen la estimación. Es el perfil anti-derrape.
Marcha normal
Equilibrado
EncoderMEDIO
GiróscopoALTO
LáserMEDIO
DirecciónMEDIO
Por qué: sin condiciones adversas, todos aportan. Punto de partida seguro y base desde la que derivar los demás perfiles. El giróscopo siempre alto (es el más fiable para el rumbo).
Adaptativo (futuro)
Cambio automático
Detección—
Idea: en vez de elegir el perfil a mano, detectar el contexto y ajustar las covarianzas en caliente: si la aceleración comandada es alta → inflar la del encoder (arranque); si el láser da poca cobertura → bajarlo. Es el paso siguiente a los perfiles fijos.
5 Cómo se configura en la práctica
Dos formas de materializar los perfiles, de menor a mayor sofisticación:
Ficheros de perfil (recomendado para empezar). Un ekf.yaml por escenario (ekf_sala.yaml, ekf_pasillo.yaml…) que cambian las covarianzas y las matrices de configuración por eje. Se elige al lanzar con un argumento: ros2 launch … profile:=pasillo.
Escalado en caliente. Exponer un multiplicador de covarianza por sensor como parámetro ROS, ajustable con ros2 param set sin reiniciar. Base para el perfil adaptativo.
La ponderación por eje se expresa en la matriz de configuración de cada fuente (15 booleanos: x y z roll pitch yaw vx vy vz vroll vpitch vyaw ax ay az). Por ejemplo, el láser en el perfil «pasillo», fusionando solo giro y lateral, no el avance:
# ekf_pasillo.yaml — odom del laser: yaw + y, SIN x
odom0: /odom_laser
odom0_config: [false, true, false, # x, y, z
false, false, true, # roll, pitch, yaw
false, false, false,
false, false, false,
false, false, false]
odom0_differential: true
odom0_pose_rejection_threshold: 2.0 # cortafuegos anti-salto
Requisitos y honestidad
Estos perfiles asumen que las fuentes existen en el EKF. Hoy están el encoder y el giróscopo; el láser (rf2o) y la dirección son mejoras pendientes (tareas 67 y 66). Los perfiles con láser/dirección se activan cuando esas fuentes estén integradas. El estudio deja el mecanismo y las recetas listas para ese momento.
6 Adaptación en caliente
Los perfiles anteriores son fijos, pero el peso puede cambiar sobre la marcha según el contexto — por ejemplo, en función de la velocidad o la aceleración del robot. La cuestión decisiva es dónde se cambia.
Dónde vive la adaptación
En robot_localization la covarianza de cada medida viene en el propio mensaje, no en un parámetro que se cambie fácilmente en caliente. Por eso la adaptación no se hace en el EKF, sino aguas arriba, en los nodos adaptadores (como wheel_twistcov_node), que ya estampan la covarianza. Basta con que esa covarianza sea una función del contexto: se recalcula en cada mensaje y el peso varía de forma continua, sin reiniciar nada.
Continua frente a por saltos
Modulación continua
Perfil discreto
Qué
cov = f(v, a): función suave de la señal
un supervisor conmuta perfiles por umbrales
Dónde
en los adaptadores, por mensaje
un nodo que reconfigura
Ventaja
sin saltos · sin relanzar
perfiles claros y legibles
Riesgo
—
saltos de pose al conmutar → histéresis
La continua es preferible: adapta sin discontinuidades y no necesita lógica de conmutación ni relanzar el filtro.
Ejemplo: pesos en función de la velocidad
Arranque / baja velocidad. Es cuando las ruedas patinan → inflar la covarianza del encoder (bajar su peso). Ley típica:
covencoder = covbase · ( 1 + k · |acomandada| )
al pisar gas fuerte, el encoder pesa menos automáticamente
Alta velocidad. El scan-matching del láser degrada (menos solape entre barridos, más riesgo de derrape) → subir su covarianza y apoyarse más en el giróscopo.
Muy baja velocidad / parado. El giróscopo puede quedar bajo su propio ruido; encoder y láser mandan.
El bucle que hay que evitar
Cuidado con de dónde sacas la velocidad para calcular los pesos. Si usas la salida del propio EKF (/odometry/filtered) para ponderar sus entradas, creas un bucle de realimentación que puede volverse inestable. Usa una señal independiente: la velocidad comandada (/cmd_vel) o su derivada, o la velocidad cruda del encoder. Así la adaptación no se muerde la cola.
Arquitectura
El EKF se queda igual (configuración estática); toda la inteligencia adaptativa vive en los adaptadores, aguas arriba:
# una señal independiente gobierna la covarianza, no la salida del EKF
/cmd_vel (v, a comandadas)
│
▼
[adaptador] cov = f(v, a) /wheel_speed
│ │
└──────────► /wheel_speed_cov ◄────┘ (covarianza adaptada)
│
▼
EKF (config fija) ──► /odometry/filtered
7 Síntesis
El peso de cada sensor es su covarianza: la fusión es una mesa de mezclas, no un interruptor.
Dos fallos gobiernan la elección: el deslizamiento (baja encoder/dirección) y la pobreza geométrica (baja láser). Cada perfil sube los sensores que no fallan en ese ambiente.
La palanca fina —fusionar por eje— evita el todo-o-nada: aprovechar el yaw del láser en un pasillo aunque su avance no valga.
El giróscopo es la constante: alto en casi todos los perfiles, porque mide el giro real sin depender de ruedas ni entorno.
Camino natural: perfiles fijos por fichero → escalado por parámetro → perfil adaptativo que detecta el contexto y reajusta solo.