2 minute read

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):

Velocidad de giro

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.