Building Agents

Create An Autonomous Racing Agent

Creating An Agent

To build your own agent create a class that inherits from aci.interface.AssettoCorsaInterface. This requires you to define three methods behaviour(), termination_condition() and teardown(). For simplicity we will start with an agent that doesn’t require clean up operations and executes forever:

from aci.interface import AssettoCorsaInterface

class MyAgent(AssettoCorsaInterface):
    def termination_condition(self, obsevration:Dict) -> bool:
        return False

    def teardown(self):
        pass

behaviour() is called by the harness as often as possible when new state information becomes available from the simulation. It will receive as input a dictionary containing state information extracted from the simulator. The harness expects a np.array that represents the input commands to be applied to the simulation in the order: [steering angle, throttle, brake]. Steering angles are between -1.0 left-lock and 1.0 right-lock. Both throttle and brake are between [0.0, 1.0] where 0.0 is no input and 1.0 is maximum input. Let’s add behaviour to our agent that ignore the game state and produces a random action:

from typing import Dict

import numpy as np

from aci.interface import AssettoCorsaInterface

class MyAgent(AssettoCorsaInterface):
    def behaviour(self, observation: Dict) -> np.array:
        # Randomly generate an action [steering_angle, brake, throttle]
        action = np.random.rand(3)
        # Rescale steering angle to be between [-1., 1]
        action[0] = (action[0] - 0.5) * 2
        return action

    def termination_condition(self, obsevration:Dict) -> bool:
        return False

    def teardown(self):
        pass

To test our agent we need to provide a configuration and call the inbuilt run() method. Here is an example of a default configuration and running the agent:

if __name__=="__main__":
    config = {}
    config["race.ini"] = {
        "RACE": {
            "TRACK": "monza",
            "CONFIG_TRACK": "",
        }
    }
    config["capture"] = {
        "images": {
            "wait_for_new_frames": True,
        }
        "state":{
            "use_state_dicts": True,
        }
    }
    agent = MyAgent(config)
    agent.run()

Calling agent.run() will automatically open Assetto Corsa and begin the agent action loops until you terminate the process using crt+c on the commandline. This will trigger the clean up of the harness and any code you write in the teardown() function.

For more information on configuration refer to simulation configuration and interface configuration.