Velocidad de giro
Nuevo controlador con la velocidad de giro como variable intermedia
Esta semana hemos creado un nuevo controlador para teleoperar un vehículo simulado en Carla con el objetivo de mejorar nuestro dataset. Esta vez, nos centramos en el steering y, para ello, hemos seguido la idea con la que trabajamos la anterior semana: crear una variable intermedia entre teclas y actuadores. Nos vamos a enfocar, para probar cómo aprende nuestro modelo de redes neuronales, en la velocidad de giro (steer_rate).
El target representa la intención de giro del conductor (o del sistema), y se obtiene a partir de la entrada por teclado: pulsar la tecla A genera un target negativo (giro a la izquierda) y la tecla D genera un target positivo (giro a la derecha). Si no hay entrada, el target es cero. Este target no corresponde al ángulo del volante, sino a una velocidad deseada de giro (steer_rate_cmd).
Para evitar cambios bruscos e irreales, el comando de velocidad se somete a un filtro de primer orden:
- steer_rate : es la velocidad real del volante
- steer_rate_cmd : es la velocidad objetivo
- ALPHA_STEER : parámetro de suavizado para hacer más gradual el aumento/disminución de la velocidad. Es la inercia del sistema del volante.
steer_rate = (1 - ALPHA_STEER) * steer_rate + ALPHA_STEER * steer_rate_cmd
A partir de esta velocidad de giro del volante, obtenemos el ángulo o el desplazamiento de giro del volante (steer_real), que es el que irá directamente al actuador de steer:
steer_real += steer_rate * dt
A continuación, se muestra el código completo del controlador del vehículo:
# Parámetros del volante
STEER_RATE_MAX = 1 # velocidad máxima de giro
ALPHA_STEER = 0.2 # suavizado
def control(vehicle):
global steer_real, steer_rate, last_time, throttle
control = carla.VehicleControl()
keys = pygame.key.get_pressed()
now = time.time()
dt = now - last_time
last_time = now
# Velocidad objetivo según el giro izquierda(A)/derecha(D)
if keys[pygame.K_a]:
steer_rate_cmd = -STEER_RATE_MAX
elif keys[pygame.K_d]:
steer_rate_cmd = STEER_RATE_MAX
else:
steer_rate_cmd = 0.0
steer_real = 0.0
# Velocidad real de giro del volante
steer_rate = (1 - ALPHA_STEER) * steer_rate + ALPHA_STEER * steer_rate_cmd
# Cálculo de Steer
steer_real += steer_rate * dt
# Limitar ángulo de giro
steer_real = max(-1.0, min(1.0, steer_real))
control.steer = steer_real
velocidad_giro.append(steer_rate)
tiempo.append(now)
# W throttle
if keys[pygame.K_w]:
throttle = min(throttle + 0.25, 1.0)
else:
throttle = max(throttle - 0.25, 0.0)
control.throttle = throttle
# S freno
if keys[pygame.K_s]:
control.brake = 1.0
else:
control.brake = 0.0
vehicle.apply_control(control)
print(
"| steer_rate:", round(steer_rate, 3),
"| steer:", round(steer_real, 3),
"| throttle:", round(control.throttle, 2)
)
return steer_rate, control.throttle, control.steer, control.brake
Para comprobar que los progresos fueran por “buen camino”, se ha ido representando la evolución de la velocidad del volante en función del tiempo en varias simulaciones. A continuación, se muestra una figura en que se pueden observar varios picos positivos, que indican giros a la derecha (botón D) y un pico negativo, que es un giro a la izquierda (botón A):
Se ha relizado una captura de unos pocos minutos de una simulación mientras se teleopera el coche con este nuevo controlador. A continuación, el enlace del vídeo: https://youtu.be/XJHhS1smjVQ
Conclusiones
Esta semana hemos creado un nuevo controlador para obtener un parámetro intermedio (entre botón y actuador), la velocidad de giro del volante, con el que vamos a generar un nuevo dataset como único parámetro.
La próxima semana, el objetivo será el de crear un dataset con dicho parámetro como label y estudiar cómo mejora el entrenamiento y aprendizaje de nuestro modelo de redes neuronales.