2018-04-09 17:02:07 +08:00
Benchmarking your Agent
2018-04-07 17:00:35 +08:00
---------------------------
2018-04-12 21:05:05 +08:00
In this tutorial we show:
* [How to define a trivial agent with a forward going policy. ](#defining-the-agent )
* [How to define a basic experiment suite. ](#defining-the-experiment-suite )
#### Introduction
![Benchmark_structure ](img/benchmark_diagram_small.png )
2018-04-07 17:00:35 +08:00
2018-04-10 16:40:08 +08:00
The driving benchmark is associated with other two modules.
2018-04-12 21:05:05 +08:00
The *agent* module, that is a controller which performs in
another module: the *experiment suite* .
2018-04-07 17:00:35 +08:00
Both modules are abstract classes that must be redefined by
the user.
2018-04-09 22:47:20 +08:00
The following code excerpt is
2018-04-10 20:55:03 +08:00
an example of how to apply a driving benchmark;
2018-04-07 17:00:35 +08:00
2018-04-11 00:19:05 +08:00
# We instantiate a forward agent, a simple policy that just set
# acceleration as 0.9 and steering as zero
agent = ForwardAgent()
# We instantiate an experiment suite. Basically a set of experiments
# that are going to be evaluated on this benchmark.
experiment_suite = BasicExperimentSuite(city_name)
# Now actually run the driving_benchmark
# Besides the agent and experiment suite we should send
# the city name ( Town01, Town02) the log
run_driving_benchmark(agent, experiment_suite, city_name,
log_name, continue_experiment,
host, port)
2018-04-07 17:00:35 +08:00
2018-04-10 16:40:08 +08:00
Following this excerpt, there are two classes to be defined.
2018-04-12 21:05:05 +08:00
The ForwardAgent() and the BasicExperimentSuite().
2018-04-17 20:54:18 +08:00
After that, the benchmark can ne run with the "run_driving_benchmark" function.
2018-04-12 21:05:05 +08:00
The summary of the execution, the [performance metrics ](benchmark_metrics.md ), are stored
in a json file and printed to the screen.
2018-04-11 00:19:05 +08:00
2018-04-07 17:00:35 +08:00
2018-04-10 01:42:06 +08:00
#### Defining the Agent
2018-04-07 17:00:35 +08:00
2018-04-09 17:02:07 +08:00
The tested agent must inherit the base *Agent* class.
2018-04-17 20:54:18 +08:00
Let's start by deriving a simple forward agent:
2018-04-07 17:00:35 +08:00
from carla.agent.agent import Agent
from carla.client import VehicleControl
2018-04-10 01:27:15 +08:00
class ForwardAgent(Agent):
2018-04-07 17:00:35 +08:00
2018-04-10 20:55:03 +08:00
To have its performance evaluated, the ForwardAgent derived class _must_
redefine the *run_step* function as it is done in the following excerpt:
2018-04-07 17:00:35 +08:00
def run_step(self, measurements, sensor_data, directions, target):
"""
Function to run a control step in the CARLA vehicle.
"""
control = VehicleControl()
control.throttle = 0.9
return control
2018-04-09 17:02:07 +08:00
This function receives the following parameters:
* [Measurements ](measurements.md ): the entire state of the world received
by the client from the CARLA Simulator. These measurements contains agent position, orientation,
dynamic objects information, etc.
2018-04-10 20:55:03 +08:00
* [Sensor Data ](cameras_and_sensors.md ): The measured data from defined sensors,
such as Lidars or RGB cameras.
2018-04-09 17:02:07 +08:00
* Directions: Information from the high level planner. Currently the planner sends
2018-04-17 20:54:18 +08:00
a high level command from the follwoing set: STRAIGHT, RIGHT, LEFT, NOTHING.
2018-04-09 17:02:07 +08:00
* Target Position: The position and orientation of the target.
With all this information, the *run_step* function is expected
2018-04-12 21:05:05 +08:00
to return a [vehicle control message ](measurements.md ), containing:
2018-04-09 17:02:07 +08:00
steering value, throttle value, brake value, etc.
2018-04-07 17:00:35 +08:00
2018-04-10 01:42:06 +08:00
#### Defining the Experiment Suite
2018-04-07 17:00:35 +08:00
2018-04-09 22:47:20 +08:00
To create a Experiment Suite class you need to perform
the following steps:
* Create your custom class by inheriting the ExperimentSuite base class.
* Define the test and train weather conditions to be used.
2018-04-12 21:05:05 +08:00
* Build the *Experiment* objects .
2018-04-09 22:47:20 +08:00
2018-04-10 01:42:06 +08:00
##### Definition
2018-04-09 22:47:20 +08:00
2018-04-09 17:02:07 +08:00
The defined set of experiments must derive the *ExperimentSuite* class
2018-04-12 21:05:05 +08:00
as in the following code excerpt:
2018-04-07 17:00:35 +08:00
2018-04-09 17:02:07 +08:00
from carla.agent_benchmark.experiment import Experiment
from carla.sensor import Camera
from carla.settings import CarlaSettings
from .experiment_suite import ExperimentSuite
2018-04-12 21:05:05 +08:00
class BasicExperimentSuite(ExperimentSuite):
2018-04-09 17:02:07 +08:00
2018-04-12 21:05:05 +08:00
##### Define test and train weather conditions
2018-04-09 22:47:20 +08:00
The user must select the weathers to be used. One should select the set
2018-04-09 17:02:07 +08:00
of test weathers and the set of train weathers. This is defined as a
2018-04-10 20:55:03 +08:00
class property as in the following example:
2018-04-07 17:00:35 +08:00
2018-04-09 17:02:07 +08:00
@property
def train_weathers(self):
return [1]
@property
def test_weathers(self):
return [1]
2018-04-07 17:00:35 +08:00
2018-04-09 22:47:20 +08:00
##### Building Experiments
2018-04-07 17:00:35 +08:00
2018-04-09 22:47:20 +08:00
The [experiments are composed by a *task* that is defined by a set of *poses* ](benchmark_structure.md ).
2018-04-17 20:54:18 +08:00
Let's start by selecting poses for one of the cities, let's take Town01, for instance.
2018-04-12 21:05:05 +08:00
First of all, we need to see all the possible positions, for that, with
a CARLA simulator running in a terminal, run:
2018-04-09 22:47:20 +08:00
python view_start_positions.py
2018-04-10 20:55:03 +08:00
![town01_positions ](img/town01_positions.png )
2018-04-09 22:47:20 +08:00
2018-04-17 20:54:18 +08:00
Now let's choose, for instance, 140 as start position and 134
2018-04-12 21:05:05 +08:00
as the end position. This two positions can be visualized by running:
2018-04-09 22:47:20 +08:00
2018-04-17 20:54:18 +08:00
python view_start_positions.py --pos 140,134 --no-labels
2018-04-09 22:47:20 +08:00
2018-04-17 20:54:18 +08:00
![town01_positions ](img/town01_140_134.png )
2018-04-09 22:47:20 +08:00
2018-04-17 20:54:18 +08:00
Let's choose two more poses, one for going straight, other one for one simple turn.
Also, let's also choose three poses for Town02:
2018-04-09 22:47:20 +08:00
![town01_positions ](img/initial_positions.png )
2018-04-17 20:54:18 +08:00
>Figure: The poses used on this basic *Experiment Suite* example. Poses are
2018-04-09 22:47:20 +08:00
a tuple of start and end position of a goal-directed episode. Start positions are
shown in Blue, end positions in Red. Left: Straight poses,
where the goal is just straight away from the start position. Middle: One turn
2018-04-17 20:54:18 +08:00
episode, where the goal is one turn away from the start point. Right: arbitrary position,
2018-04-09 22:47:20 +08:00
the goal is far away from the start position, usually more than one turn.
2018-04-17 20:54:18 +08:00
We define each of these poses as a task. Plus, we also set
2018-04-09 22:47:20 +08:00
the number of dynamic objects for each of these tasks and repeat
the arbitrary position task to have it also defined with dynamic
2018-04-12 21:05:05 +08:00
objects. In the following code excerpt we show the final
2018-04-17 20:54:18 +08:00
defined positions and the number of dynamic objects for each task:
2018-04-09 22:47:20 +08:00
2018-04-17 20:54:18 +08:00
# Define the start/end position below as tasks
poses_task0 = [[7, 3]]
2018-04-12 21:05:05 +08:00
poses_task1 = [[138, 17]]
2018-04-17 20:54:18 +08:00
poses_task2 = [[140, 134]]
poses_task3 = [[140, 134]]
2018-04-12 21:05:05 +08:00
# Concatenate all the tasks
2018-04-17 20:54:18 +08:00
poses_tasks = [poses_task0, poses_task1 , poses_task1 , poses_task3]
# Add dynamic objects to tasks
2018-04-09 22:47:20 +08:00
vehicles_tasks = [0, 0, 0, 20]
pedestrians_tasks = [0, 0, 0, 50]
Finally by using the defined tasks we can build the experiments
vector as we show in the following code excerpt:
2018-04-07 17:00:35 +08:00
2018-04-12 21:05:05 +08:00
experiments_vector = []
# The used weathers is the union between test and train weathers
for weather in used_weathers:
for iteration in range(len(poses_tasks)):
poses = poses_tasks[iteration]
vehicles = vehicles_tasks[iteration]
pedestrians = pedestrians_tasks[iteration]
conditions = CarlaSettings()
conditions.set(
SendNonPlayerAgentsInfo=True,
NumberOfVehicles=vehicles,
NumberOfPedestrians=pedestrians,
WeatherId=weather
)
# Add all the cameras that were set for this experiments
conditions.add_sensor(camera)
experiment = Experiment()
experiment.set(
Conditions=conditions,
Poses=poses,
Task=iteration,
Repetitions=1
)
experiments_vector.append(experiment)
2018-04-07 17:00:35 +08:00
2018-04-09 17:02:07 +08:00
2018-04-19 22:34:16 +08:00
The full code could be found at [basic_experiment_suite.py ](https://github.com/carla-simulator/carla/blob/master/PythonClient/carla/driving_benchmark/experiment_suites/basic_experiment_suite.py )
2018-04-09 17:02:07 +08:00
2018-04-10 01:27:15 +08:00
#### Expected Results
2018-04-19 22:05:59 +08:00
First you need a CARLA Simulator running with [fixed time-step ](configuring_the_simulation/#fixed-time-step )
, so the results you will obtain will be more or less reproducible.
For that you should run the CARLA simulator as:
2018-04-19 21:11:29 +08:00
2018-04-19 22:05:59 +08:00
./CarlaUE4.sh /Game/Maps/< Town_name > -windowed -world-port=2000 -benchmark -fps=10
2018-04-19 21:11:29 +08:00
2018-04-19 22:05:59 +08:00
The example presented in this tutorial can be executed for Town01 as:
2018-04-10 01:27:15 +08:00
./driving_benchmark_example.py -c Town01
2018-04-17 20:54:18 +08:00
You should expect these results: [town01_basic_forward_results ](benchmark_basic_results_town01 )
2018-04-10 01:27:15 +08:00
For Town02:
./driving_benchmark_example.py -c Town02
2018-04-17 20:54:18 +08:00
You should expect these results: [town01_basic_forward_results ](benchmark_basic_results_town02 )
2018-04-10 01:27:15 +08:00
2018-04-07 17:00:35 +08:00