Getting Started
This manual introduces the main functionality by means of some examples. Exact class descriptions can be found in the module descriptions.
CommonRoad XML-files consist of a Scenario
and a PlanningProblemSet
. A Scenario
represents the environment including a LaneletNetwork
and a set of DynamicObstacle
and StaticObstacle
. A LaneletNetwork
is built from lane segments (Lanelet
), that can be connected arbitrarily, traffic signs (TrafficSign
), traffic lights (TrafficLight
), and intersections (Intersection
).
A PlanningProblemSet
contains one PlanningProblem
for every ego vehicle in the Scenario
, consisting of an initial State
and a GoalRegion
that has to be reached.
For detailed information, see XML CommonRoad Documentation.
Reading Files
Description: commonroad.common.file_reader
.
The CommonRoadFileReader
reads the Scenario
and the PlanningProblemSet
from a CommonRoad XML-file:
import os
import matplotlib.pyplot as plt
from commonroad.common.file_reader import CommonRoadFileReader
from commonroad.visualization.mp_renderer import MPRenderer
file_path = os.path.join(os.getcwd(), 'scenarios/NGSIM/Lankershim/USA_Lanker-1_1_T-1.xml')
scenario, planning_problem_set = CommonRoadFileReader(file_path).open()
rnd = MPRenderer()
scenario.draw(rnd)
planning_problem_set.draw(rnd)
rnd.render(show=True)
Per default, the first time step of the scenario is plotted. Please note that within all modules of CommonRoad the time is discretized and only discrete time steps are used. To plot the scenario at another time index, draw parameters can be defined:
rnd = MPRenderer()
rnd.draw_params.time_begin = 10
scenario.draw(rnd)
planning_problem_set.draw(rnd)
rnd.render(show=True)
For more details on plotting options see Visualization Manual.
Scenario
Description: commonroad.scenario.scenario
.
Reading a CommonRoad XML-file with the CommonRoadFileReader
returns an instance of class Scenario
. This instance contains all information about the road network and surrounding obstacles.
Additionally, the scenario can be modified or new scenarios can be created.
E.g. scenarios can be translated and rotated:
import numpy as np
translation = np.array([0.0, 0.0])
angle = np.pi/2
scenario.translate_rotate(translation, angle)
planning_problem_set.translate_rotate(translation, angle)
plt.figure(figsize=(25, 10))
draw_object(scenario)
draw_object(planning_problem_set)
plt.gca().set_aspect('equal')
plt.show()
Note that all other objects (obstacles, lanelets, planning problems, goal regions, occupancies, trajectories, …) can be translated and rotated as well.
Other useful methods for trajectory planning are:
Lanelet Network
Description: commonroad.scenario.lanelet
.
Each Lanelet
stores its left and right boundary and its center by a polyline (a list of vertices).
If a lanelet A is the successor of another lanelet B, the first (center/left/right) point of A coincides with the last (center/left/right) point of B. More necessary conditions on lanelets can be found in the XML CommonRoad Documentation.
Useful methods for trajectory planning are:
Description: commonroad.scenario.trafficSign
.
Each TrafficSign
stores several traffic sign elements (TrafficSignElement
) for one position. A traffic sign element represents a traffic sign with a country-specific ID.
If the attribute TrafficSign.virtual
is set to false, the traffic sign is not located at this position in real world.
A traffic sign can be valid starting from the beginning or end of a lanelet. Traffic signs valid from the beginning are maintained in the list TRAFFIC_SIGN_VALIDITY_START.
A traffic sign is always valid for the complete lanelet.
A traffic sign can be referenced by successor lanelets of its first occurrence, e.g., a speed limit sign.
Description: commonroad.scenario.trafficLight
.
Each TrafficLight
has a cycle (TrafficLightCycleElement
) with the current state and duration of each phase.
Description: commonroad.scenario.intersection
.
A Intersection
stores the incoming lanelets (IntersectionIncomingElement
) of an intersection.
Obstacles
Description: commonroad.scenario.obstacle
Obstacles in CommonRoad have an unique ID, an ObstacleRole
(static or dynamic), an ObstacleType
(e.g. car, pedestrian, parked vehicle, construction zone, …), a Shape
(e.g. rectangle, polygon, …), and an initial State
.
While a StaticObstacle
is only described by those attributes, a DynamicObstacle
has additionally a prediction
that defines its predicted dynamic behavior.
Useful methods for trajectory planning are:
Dynamic Obstacle Prediction
Description: commonroad.prediction.prediction
.
Every DynamicObstacle
has a TrajectoryPrediction
or a SetBasedPrediction
.
Each prediction contains an Occupancy
set that represents the two-dimensional occupancy of the obstacle over time.
Each of the given XML scenarios provides exactly one type of prediction for all dynamic obstacles.
Trajectory Prediction
Description: TrajectoryPrediction
.
This prediction corresponds to the most likely trajectory of the obstacle. The Trajectory
consists of a list of State
and an initial time step.
The occupancy is calculated by forwarding the shape
of the Obstacle
along the Trajectory
.
Set Based Prediction
Description: SetBasedPrediction
.
This prediction stores the occupied area of the obstacle over time as bounded sets.
Planning Problems
Description: PlanningProblem
.
To solve a scenario, one has to find solutions to all problems in the PlanningProblemSet
. Every PlanningProblem
corresponds to one ego vehicle.
It consists of an initial state for the ego vehicle and a GoalRegion
which the ego vehicle has to reach.
A GoalRegion
is a collection of different goal states (e.g. position region in form of an arbitrary Shape
or a list of Lanelet
objects, velocity interval, time interval, orientation interval,…).
Checking if a GoalRegion
is reached works as follows:
from commonroad.planning.goal import GoalRegion
from commonroad.common.util import Interval, AngleInterval
from commonroad.scenario.trajectory import State
# define example goal region
goal_state_1 = State(time_step=Interval(3, 5), orientation=AngleInterval(0.1, 1), velocity=Interval(20, 30.5))
goal_state_2 = State(time_step=Interval(3, 6), orientation=AngleInterval(0.1, 1), velocity=Interval(15, 25.5))
goal_region = GoalRegion([goal_state_1, goal_state_2])
# state of the ego vehicle
state = State(time_step=3, orientation=0.5, velocity=25)
# check if the state is inside of the goal region
goal_region.is_reached(state)
Other useful methods:
Writing Files
Description: commonroad.common.file_writer
.
The CommonRoadFileWriter
writes a Scenario
and a PlanningProblemSet
to a CommonRoad XML-file:
from commonroad.common.file_writer import CommonRoadFileWriter
from commonroad.common.file_writer import OverwriteExistingFile
fw = CommonRoadFileWriter(scenario, planning_problem_set, "author", "affiliation", "source", "tags")
filename = "filename.xml"
fw.write_to_file(filename, OverwriteExistingFile.ALWAYS)
Solution Writer
Description: commonroad.common.solution
.
To upload a solution to https://commonroad.in.tum.de/ one can either submit data in form of a Trajectory
or as a list of control inputs.
The CommonRoadSolutionWriter
creates an XML file according to the given XML schema definition including an attribute with the correct benchmark ID. In order to do so, the scenario ID, the VehicleType
, the VehicleModel
, and the CostFunction
have to be given.
A solution (trajectory or control input vector) can be written as XML file in the following way:
import time
from commonroad.common.solution import CommonRoadSolutionWriter, Solution, PlanningProblemSolution, VehicleModel, VehicleType, CostFunction
from commonroad.scenario.trajectory import Trajectory, State
# prepare trajectory
t_0 = time.time()
pm_state_list = list()
for i in range(10):
pm_state_list.append(State(**{'position': np.array([i, -i]), 'velocity': i*.2, 'velocity_y': i*0.001, 'time_step': i}))
# stop 'computation time'
t_c = time.time() - t_0
trajectory_pm = Trajectory(0, pm_state_list)
# create solution object for benchmark
pps = PlanningProblemSolution(planning_problem_id=1215,
vehicle_type=VehicleType.BMW_320i,
vehicle_model=VehicleModel.PM,
cost_function=CostFunction.JB1,
trajectory=trajectory_pm)
solution = Solution(scenario.benchmark_id, '2020a', [pps], computation_time=t_c)
# write solution to a xml file
csw = CommonRoadSolutionWriter(solution)
csw.write_to_file()