Práctica 1 — Localización de Markov: RHINO se despierta en el museo
Cada mañana encendían a RHINO en algún lugar del museo sin decirle dónde estaba. En esta práctica vamos a ver cómo se ubicaba solo, con la localización de Markov de la clase, y después la misma idea con partículas.
Es una práctica demostrativa: no hay que programar. Se ejecutan los mundos, se observa y se cambian algunos parámetros para entender qué hace cada parte.
Montaje
Sección titulada «Montaje»- Instale el simulador de RHINO y abra
worlds/museo.wbt. - Tenga a mano las diapositivas del bloque Localización de Markov.
Paso a Paso
Sección titulada «Paso a Paso»Paso 1 — RHINO y su Lidar
Abra worlds/museo.wbt y ejecútelo. RHINO arranca en recorrido automático; detenga el recorrido con T y manéjelo con las flechas.
La pantalla muestra el mapa del museo (en negro, como la Fig. 4 del artículo) y, en rojo, los ecos del Lidar dibujados desde la pose real de RHINO.
Preguntas para orientarse:
- ¿Los ecos rojos caen sobre los obstáculos negros? ¿Hay ecos que caen en espacio libre? ¿De dónde salen?
- En algunas direcciones no hay eco. ¿Por qué? (Pista: el alcance del Lidar es de 10 m.)
- Párese en un pasillo entre dos vitrinas iguales. ¿Podría saber dónde está con una sola lectura del Lidar si no supiera la pose?
Paso 2 — La creencia uniforme y la primera lectura
Abra worlds/markov.wbt. RHINO arranca sin saber dónde está: la creencia es igual en todas las celdas libres. La grilla es la de RHINO: celdas de 15 cm y capas de 5° de orientación, más de 1.3 millones de estados.
Ejecute la simulación y páusela (⏸) apenas aparezcan los primeros grises:

Los grises son la probabilidad de cada celda sumando todas las orientaciones: entre más oscuro, más probable. El círculo azul es la pose real y el rojo la celda más probable.
Esto es la regla de Bayes: la creencia uniforme se multiplicó por , la probabilidad de la lectura del Lidar estando en cada celda. En controllers/markov/markov.py, la función percibir hace exactamente eso:
logp[t] += campo[...] # log P(eco | celda), sumado sobre los rayosbel = bel * np.exp(logp) # Bayesreturn bel / bel.sum() # normalizarcampo es el modelo del sensor: para cada punto del mapa, qué tan probable es que un eco caiga ahí. Es alto cerca de los obstáculos y bajo en el espacio libre.
Preguntas para orientarse:
- ¿En qué zonas quedó gris oscuro? ¿Por qué esas zonas se parecen al lugar donde está RHINO?
- ¿Por qué hay celdas blancas pegadas a los obstáculos, aunque el resto esté gris?
Paso 3 — Moverse y mirar
Continúe la simulación unos segundos. Cada vez que RHINO avanza 15 cm o gira 5°, la creencia se actualiza dos veces: se mueve con los encoders y se corrige con el Lidar.


En la imagen de la izquierda (actualización 10) hay dos picos: uno en la pose real y otro, más fuerte, en un lugar parecido. Es la misma situación de la Fig. 4 del artículo. Diez actualizaciones después (derecha), solo queda el correcto.
La función mover es la suma total: corre cada capa de orientación lo que dicen los encoders y después la difumina con un filtro gaussiano, porque los encoders se equivocan.
Preguntas para orientarse:
- ¿Por qué el pico falso desaparece? ¿Qué tuvo que pasar para que la lectura del Lidar dejara de “parecerse”?
- La consola imprime cuánto tarda cada actualización. ¿Cuánto tardaría con celdas de 2°, como el RHINO real?
- Después de ubicarse, ¿cuánto se equivoca RHINO? Compare con el tamaño de la celda.
Paso 4 — Experimentos con la grilla
Los parámetros están al inicio de markov.py. Cambie uno a la vez, guarde y reinicie con Ctrl+Shift+T:
| Parámetro | Valor inicial | Pruebe con |
|---|---|---|
RAYOS | 8 | 36 y 2 |
SIGMA_SENSOR | 0.20 | 0.05 y 1.0 |
ERROR_AVANCE y ERROR_GIRO | 0.10 | 0.0 |
Preguntas para orientarse:
- Con 36 rayos, ¿cuántas actualizaciones necesita para ubicarse? ¿Y con 2? ¿Por qué más rayos no es siempre mejor? (Pista: piense en las personas que tapaban el láser.)
- Con
SIGMA_SENSORmuy pequeño, RHINO puede perderse. ¿Por qué un modelo del sensor “muy exigente” es peligroso, si el mapa y la grilla no son perfectos? - Sin error de movimiento, ¿qué pasa con la creencia después de varias vueltas?
Paso 5 — Localización con partículas
Abra worlds/particulas.wbt. Ahora la creencia no es una grilla sino una nube de partículas (en rojo): cada una es una hipótesis . En cada actualización:
- Acción: cada partícula se mueve con los encoders, más un error al azar distinto para cada una.
- Percepción: cada partícula recibe un peso, , con el mismo modelo del sensor de la grilla.
- Remuestreo: se sacan partículas nuevas, con más copias de las que pesan más.


Mientras RHINO está perdido usa 30 000 partículas; cuando la nube mide menos de 1 m, baja a 2000. El círculo verde es la media de las partículas.
Preguntas para orientarse:
- ¿Por qué hacen falta tantas partículas al principio? Calcule cuántas caen, en promedio, a menos de 30 cm y 10° de la pose real si se reparten 3000 en 250 m².
- Compare el tiempo por actualización con el de la grilla. ¿Dónde está el ahorro?
- A veces la nube se va a un lugar equivocado y unos segundos después aparece en el correcto. Lea la consola: ¿cómo se dio cuenta RHINO?
Paso 6 — El robot secuestrado
Con RHINO ya ubicado, haga clic en la vista 3D y presione S (o use el botón Secuestrar de la ventana del robot): RHINO aparece en otro punto del recorrido sin saberlo.

Las partículas siguen donde estaba antes, y la lectura del Lidar deja de cuadrar. La calidad de la lectura (tercera línea de la pantalla) mide qué tan bien explica la lectura la mejor partícula: cerca de 0 es bien. Cuando baja de PERDIDO = -0.5, el programa reparte partículas por todo el museo y vuelve a empezar.
Preguntas para orientarse:
- ¿Cuánto tarda RHINO en darse cuenta del secuestro? ¿Y en volver a ubicarse?
- ¿Qué pasaría sin esa regla, con solo 2000 partículas concentradas en el lugar viejo?
- ¿La grilla de Markov del paso 2 tendría el mismo problema? (Pista: ¿alguna celda llega a tener probabilidad exactamente 0?)
Paso 7 (opcional) — Personas en el museo
worlds/particulas.wbt trae un ejemplo comentado de una persona (Pedestrian) que camina de ida y vuelta por el recorrido de RHINO. Abra el archivo .wbt en un editor de texto y quite el # de dos líneas: la de EXTERNPROTO ... Pedestrian.proto al inicio y la de Pedestrian { ... } al final. Guarde y abra el mundo en Webots.
Copie la línea Pedestrian para agregar más personas, cada una con un name distinto y su propia --trajectory (puntos x y en metros, separados por comas).
Preguntas para orientarse:
- ¿Qué le pasa a la calidad de la lectura cuando una persona pasa frente a RHINO? ¿Se pierde?
- RHINO usaba un filtro de entropía: solo aceptaba las lecturas que lo dejaban más seguro de su posición. ¿Cómo lo agregaría a
log_peso?