metadriverse / metadrive

MetaDrive: Open-source driving simulator
https://metadriverse.github.io/metadrive/
Apache License 2.0
789 stars 111 forks source link

Vehicle's data are not correctly updated #102

Closed rondey closed 3 years ago

rondey commented 3 years ago

Hello, I'm trying to get the data of the vehicle using this code:

    """
    Please feel free to run this script to enjoy a journey by keyboard!
    Remember to press H to see help message!
    Note: This script require rendering, please following the installation instruction to setup a proper
    environment that allows popping up an window.
    """
    import argparse
    import random

    import numpy as np

    from metadrive import MetaDriveEnv
    from metadrive.constants import HELP_MESSAGE

    if __name__ == "__main__":
        config = dict(
            # controller="joystick",
            use_render=True,
            manual_control=True,
            traffic_density=0.1,
            environment_num=100,
            random_agent_model=True,
            random_lane_width=True,
            random_lane_num=True,
            map=4,  # seven block
            start_seed=random.randint(0, 1000),
        )
        parser = argparse.ArgumentParser()
        parser.add_argument("--observation", type=str, default="lidar", choices=["lidar", "rgb_camera"])
        args = parser.parse_args()
        if args.observation == "rgb_camera":
            config.update(dict(offscreen_render=True))
        env = MetaDriveEnv(config)
        try:
            o = env.reset()
            print(HELP_MESSAGE)
            env.vehicle.expert_takeover = True
            if args.observation == "rgb_camera":
                assert isinstance(o, dict)
                print("The observation is a dict with numpy arrays as values: ", {k: v.shape for k, v in o.items()})
            else:
                assert isinstance(o, np.ndarray)
                print("The observation is an numpy array with shape: ", o.shape)

            vehicle = env.vehicle
            for i in range(1, 1000000000):
                o, r, d, info = env.step([0, 0])
                vehicle_data = dict(
                    speed=vehicle.speed,
                    throttle_brake=vehicle.throttle_brake,
                    steering=vehicle.steering,
                    last_position=vehicle.last_position,
                    dist_to_left_side=vehicle.dist_to_left_side,
                    dist_to_right_side=vehicle.dist_to_right_side,
                    energy_consumption=vehicle.energy_consumption,
                )
                env.render(
                    text={
                        "Auto-Drive (Switch mode: T)": "on" if env.current_track_vehicle.expert_takeover else "off",
                        "Speed": vehicle_data["speed"],
                        "Throttle": vehicle_data["throttle_brake"],
                        "Steering": vehicle_data["steering"],
                        "Position": vehicle_data["last_position"],
                        "Distance left side": vehicle_data["dist_to_left_side"],
                        "Distance right side": vehicle_data["dist_to_right_side"],
                        "Energy consumption": vehicle_data["energy_consumption"],
                    }
                )
                if d and info["arrive_dest"]:
                    env.reset()
                    #env.current_track_vehicle.expert_takeover = True
        except:
            pass
        finally:
            env.close()

This code shows on the screen the vehicle's data in real time and works in the first simulation. However when the second simulation starts, the data are no more updated. The vehicle speed data is updated but is completely wrong with the respect of the actual speed of the car.

On the other hand, in PGDrive using this code:

    """
    Please feel free to run this script to enjoy a journey by keyboard!
    Remember to press H to see help message!
    Note: This script require rendering, please following the installation instruction to setup a proper
    environment that allows popping up an window.
    """
    import random

    from pgdrive import PGDriveEnv

    if __name__ == "__main__":
        env = PGDriveEnv(
            dict(
                use_render=True,
                #use_saver=True,
                controller="keyboard",
                manual_control=True,
                traffic_density=0.2,
                environment_num=100,
                map=7,
                start_seed=random.randint(0, 1000)
            )
        )
        env.reset()
        vehicle = env.vehicle
        for i in range(1, 100000):
            o, r, d, info = env.step([0, 0])
            env.render()

            vehicle_data = dict(
                speed=vehicle.speed,
                throttle_brake=vehicle.throttle_brake,
                steering=vehicle.steering,
                last_position=vehicle.last_position,
                # dist_to_left_side=vehicle.dist_to_left_side,
                # dist_to_right_side=vehicle.dist_to_right_side,
                # energy_consumption=vehicle.energy_consumption,
            )
            env.render(
                text={
                    #"Auto-Drive (Switch mode: T)": "on" if env.current_track_vehicle.expert_takeover else "off",
                    "Speed": vehicle_data["speed"],
                    "Throttle": vehicle_data["throttle_brake"],
                    "Steering": vehicle_data["steering"],
                    "Position": vehicle_data["last_position"],
                    # "Distance left side": vehicle_data["dist_to_left_side"],
                    # "Distance right side": vehicle_data["dist_to_right_side"],
                    # "Energy consumption": vehicle_data["energy_consumption"],
                }
            )
            if d and info["arrive_dest"]:
                env.reset()
        env.close()

In the first and subsequent simulations the vehicle's data are correctly updated. What could be the problem?

QuanyiLi commented 3 years ago

Hi, rondey. It is not a bug but a feature of MetaDrive. In the beginning of each episode, the simulation engine will clear and recycle all objects in the scene and place them into a buffer for next time use. In your case, vehicle = env.vehicle indicates the vehicle is the vehicle generating in the first episode, but after the reset() is called, vehicle will be removed from the scene and inactive. And the object which env.vehiclerepresents in second episode changes to a new one. So you have to update your code to, for example,

speed=env.vehicle.speed,

to retrieve the current tracked vehicle information instead of

speed=vehicle.speed
rondey commented 3 years ago

Thank you! Problem solved!