[NO_BUILD] Traffic Manager Updates (#4368)

* Updated name of spanw_npc script

* Traffic manager updates for large maps, generate traffic and deterministic mode.

* Changed reference to back spawn_npc for generate data tutorial as it specifies that it is based on carla 0.9.8

* Corrected min respawn distance
This commit is contained in:
Corinne 2021-07-15 10:56:45 +02:00 committed by GitHub
parent 54616a0240
commit 458fddb9b8
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
11 changed files with 642 additions and 551 deletions

View File

@ -94,9 +94,9 @@ python3 run_synchronization.py <SUMOCFG FILE> --tls-manager carla --sumo-gui
The co-simulation with SUMO makes for an additional feature. Vehicles can be spawned in CARLA through SUMO, and managed by the later as the Traffi Manager would do. The co-simulation with SUMO makes for an additional feature. Vehicles can be spawned in CARLA through SUMO, and managed by the later as the Traffi Manager would do.
The script `spawn_npc_sumo.py` is almost equivalent to the already-known `spawn_npc.py`. This script automatically generates a SUMO network in a temporal folder, based on the active town in CARLA. The script will create random routes and let the vehicles roam around. The script `spawn_npc_sumo.py` is almost equivalent to the already-known `generate_traffic.py`. This script automatically generates a SUMO network in a temporal folder, based on the active town in CARLA. The script will create random routes and let the vehicles roam around.
As the script runs a synchronous simulation, and spawns vehicles in it, the arguments are the same that appear in `run_synchronization.py` and `spawn_npc.py`. As the script runs a synchronous simulation, and spawns vehicles in it, the arguments are the same that appear in `run_synchronization.py` and `generate_traffic.py`.
* __`--host`__ *(default: 127.0.0.1)* — IP of the host server. * __`--host`__ *(default: 127.0.0.1)* — IP of the host server.
* __`--port`__ *(default: 2000)* — TCP port to listen to. * __`--port`__ *(default: 2000)* — TCP port to listen to.

View File

@ -1,228 +1,271 @@
# Traffic Manager # Traffic Manager
* [__What is it?__](#what-is-it)
* [__Architecture__](#architecture) - [__What is the Traffic Manager?__](#what-is-the-traffic-manager)
* [ALSM](#alsm) - [Structured design](#structured-design)
* [Command array](#command-array) - [User customization](#user-customization)
* [Control loop](#control-loop) - [__Architecture__](#architecture)
* [In-Memory Map](#in-memory-map) - [Overview](#overview)
* [PBVT](#pbvt) - [ALSM](#alsm)
* [PID controller](#pid-controller) - [Vehicle registry](#vehicle-registry)
* [Simulation state](#simulation-state) - [Simulation state](#simulation-state)
* [Stages](#stages) - [Control loop](#control-loop)
* [Vehicle registry](#vehicle-registry) - [In-Memory Map](#in-memory-map)
* [__Using the Traffic Manager__](#using-the-traffic-manager) - [PBVT](#pbvt)
* [General considerations](#general-considerations) - [PID controller](#pid-controller)
* [Creating a Traffic Manager](#creating-a-traffic-manager) - [Command array](#command-array)
* [Setting a Traffic Manager](#setting-a-traffic-manager) - [Stages of the Control Loop](#stages-of-the-control-loop)
* [Stopping a Traffic Manager](#stopping-a-traffic-manager) - [__Using the Traffic Manager__](#using-the-traffic-manager)
* [__Deterministic mode__](#deterministic-mode) - [Vehicle behavior considerations](#vehicle-behavior-considerations)
* [__Hybrid physics mode__](#hybrid-physics-mode) - [Creating a Traffic Manager](#creating-a-traffic-manager)
* [__Running multiple Traffic Managers__](#running-multiple-traffic-managers) - [Configuring autopilot behavior](#configuring-autopilot-behavior)
* [Definitions](#definitions) - [Stopping a Traffic Manager](#stopping-a-traffic-manager)
* [Multiclient](#multiclient) - [__Deterministic mode__](#deterministic-mode)
* [MultiTM](#multitm) - [__Hybrid physics mode__](#hybrid-physics-mode)
* [Multisimulation](#multisimulation) - [__Running multiple Traffic Managers__](#running-multiple-traffic-managers)
* [__Other considerations__](#other-considerations) - [Traffic Manager servers and clients](#traffic-manager-servers-and-clients)
* [Synchronous mode](#synchronous-mode) - [Multi-client simulations](#multi-client-simulations)
* [__Summary__](#summary) - [Multi-TM simulations](#multi-tm-simulations)
- [Multi-simulation](#multi-simulation)
- [__Synchronous mode__](#synchronous-mode)
- [__Traffic manager in large maps__](#traffic-manager-in-large-maps)
--- ---
## What is it? ## What is the Traffic Manager?
The Traffic Manager, TM for short, is the module in charge of controlling vehicles inside the simulation. It is built on top of the CARLA API in C++. Its goal is to populate the simulation with realistic urban traffic conditions. Users can customize some behaviours, for example to set specific learning circumstances. Every TM controls vehicles registered to it by setting autopilot to true, and accounts for the rest by considering them unregistered. The Traffic Manager (TM) is the module that controls vehicles in autopilot mode in a simulation. Its goal is to populate a simulation with realistic urban traffic conditions. Users can customize some behaviors, for example, to set specific learning circumstances.
### Structured design ### Structured design
The TM is built on the client-side of the CARLA architecture. It replaces the server-side autopilot. The execution flow is divided in __stages__ with independent operations and goals. This facilitates the development of phase-related functionalities and data structures, while also improving computational efficiency. Each stage runs on a different thread. Communication with the rest is managed through synchronous messaging between stages. Information flows only in one direction.
TM is built on CARLA's client-side. The execution flow is divided into __stages__, each with independent operations and goals. This facilitates the development of phase-related functionalities and data structures while improving computational efficiency. Each stage runs on a different thread. Communication with other stages is managed through synchronous messaging. Information flows in one direction.
### User customization ### User customization
Users have some control over the traffic flow by setting parameters that allow, force or encourage specific behaviours. Users can change the traffic behaviour as they prefer, both online and offline. For example they could allow a car to ignore the speed limits or force a lane change. Being able to play around with behaviours is a must when trying to simulate reality. It is necessary to train driving systems under specific and atypical circumstances. Users have some control over the traffic flow by setting parameters that allow, force, or encourage specific behaviors. Users can change the traffic behavior as they prefer, both online and offline. For example, cars can be allowed to ignore the speed limits or force a lane change. Being able to play around with behaviors is indispensable when trying to simulate reality. Driving systems need to be trained under specific and atypical circumstances.
--- ---
## Architecture ## Architecture
### Overview
![Architecture](img/tm_2_architecture.jpg) ![Architecture](img/tm_2_architecture.jpg)
The above diagram is a representation of the internal architecture of the TM. The C++ code for each component can be found in `LibCarla/source/carla/trafficmanager`. Each component is explained in detail in the following sections. A simplified overview of the logic is as follows:
__1. Store and update the current state of the simulation.__
- The [Agent Lifecycle & State Management](#alsm) (ALSM) scans the world to keep track of all the vehicles and walkers present and to clean up entries for those that no longer exist. All the data is retrieved from the server and is passed through several [stages](#stages-of-the-control-loop). The ALSM is the only component that makes calls to the server.
- The [vehicle registry](#vehicle-registry) contains an array of vehicles on autopilot (controlled by the TM) and a list of pedestrians and vehicles not on autopilot (not controlled by the TM).
- The [simulation state](#simulation-state) is a cache store of the position, velocity, and additional information of all the vehicles and pedestrians in the simulation.
The previous diagram is a summary of the internal architecture of the Traffic Manager. The inner structure of the TM can be easily translated to code, and each relevant component has its equivalent in the C++ code (.cpp files) inside `LibCarla/source/carla/trafficmanager`. The functions and relations of these components are explained in the detail in the following sections. A simplified overview of the logic is as follows: __2. Calculate the movement of every autopilot vehicle.__
__1. Store and update the current state of the simulation.__ The TM generates viable commands for all vehicles in the [vehicle registry](#vehicle-registry) according to the [simulation state](#simulation-state). Calculations for each vehicle are done separately. These calculations are divided into different [stages](#stages-of-the-control-loop). The [control loop](#control-loop) makes sure that all calculations are consistent by creating __synchronization barriers__ between stages. No vehicle moves to the next stage before calculations are finished for all vehicles in the current stage. Each vehicle goes through the following stages:
First of all, the [ALSM](#alsm) (Agent Lifecycle & State Management) scans the world to keep track of all the vehicles and walkers present and to clean up entries for those that no longer exist. All the data is retrieved from the server, and then passed to the [stages](#stages). In such way, calls to the server are isolated in the ALSM, and this information can be easily accessible onwards. The [vehicle registry](#vehicle-registry) contains an array with the registered vehicles, and a list with the rest of vehicles and pedestrians. The [simulation state](#simulation-state) stores in cache the position and velocity and some additional information of all the cars and walkers.
__2. Calculate the movement of every registered vehicle.__ >__2.1 - [Localization Stage](#stage-1-localization-stage).__
The main goal of the TM is to generate viable commands for all the vehicles in the [vehicle registry](#vehicle-registry), according to the [simulation state](#simulation-state). The calculations for each vehicle are done separately. These calculations are divided in different [stages](#stages). The [control loop](#control-loop) makes sure that all the calculations are consistent by creating __synchronization barriers__ in between stages. No one moves to the following stage before the calculations for all the vehicles are finished in the current one. Each vehicle has to go through the following stages:
>__2.1 - [Localization Stage](#stage-1-localization-stage).__ >Paths are created dynamically using a list of nearby waypoints collected from the [In-Memory Map](#in-memory-map), a simplification of the simulation map as a grid of waypoints. Directions at junctions are chosen randomly. Each vehicle's path is stored and maintained by the [Path Buffers & Vehicle Tracking](#pbvt) (PBVT) component for easy access and modification in future stages.
TM vehicles do not have a predefined route, and path choices are taken randomly at junctions. Having this in mind, the [In-Memory Map](#in-memory-map) simplifies the map as a grid of waypoints, and a near-future path to follow is created as a list of waypoints ahead. The path of every vehicle will be stored by the [PBVT](#pbvt) component (Path Buffers & Vehicle Tracking), so that these can be accessed easily and modified in future stages.
>__2.2 - [Collision Stage](#stage-2-collision-stage).__
During this stage, bounding boxes are extended over the path of each vehicle to identify potential collision hazards, which are then managed when necessary.
>__2.3 - [Traffic Light Stage](#stage-3-traffic-light-stage).__
Similar to the Collision Stage, this stage identifies potential hazards that affect the path of the vehicle according to traffic light influence, stop signs, and junction priority.
>__2.4 - [Motion Planner Stage](#stage-4-motion-planner-stage).__
Once a path has been defined, this stage computes vehicle movement. A [PID controller](#pid-controller) is used to determine how to reach the target values. This movement is then translated into an actual CARLA command to be applied.
__3. Apply the commands in the simulation.__ >__2.2 - [Collision Stage](#stage-2-collision-stage).__
Finally, the TM has calculated the next command for every vehicle, and now it is only a matter of applying them. All the commands are gathered by the [command array](#command-array), and sent to the CARLA server in a batch so that they are applied in the same frame.
And thus the cycle is concluded. The TM follows this logic on every step of the simulation. For a better understanding of the role that each component plays, this section includes an in-depth description of each of them. >Bounding boxes are extended over each vehicle's path to identify and navigate potential collision hazards.
>__2.3 - [Traffic Light Stage](#stage-3-traffic-light-stage).__
>Similar to the Collision Stage, potential hazards that affect each vehicle's path due to traffic light influence, stop signs, and junction priority are identified.
>__2.4 - [Motion Planner Stage](#stage-4-motion-planner-stage).__
>Vehicle movement is computed based on the defined path. A [PID controller](#pid-controller) determines how to reach the target waypoints. This is then translated into a CARLA command for application in the next step.
__3. Apply the commands in the simulation.__
Commands generated in the previous step are collected into the [command array](#command-array) and sent to the CARLA server in a batch to be applied in the same frame.
The following sections will explain each component and stage in the TM logic described above in more detail.
### ALSM ### ALSM
ALSM stands for __Agent Lifecycle and State Management__. First step in the logic cycle. Provides context over the current state of the simulation. ALSM stands for __Agent Lifecycle and State Management__. It is the first step in the TM logic cycle and provides context of the simulation's current state.
* Scans the world to keep track of all the vehicles and walkers in it, their positions and velocities. If physics are enabled, the velocity is retrieved by [Vehicle.get_velocity()](python_api.md#carla.Vehicle). Instead, if physics are disabled, the velocity is computed using the history of position updates over time. The ALSM component:
* Stores the position, velocity and additional information (traffic light influence, bounding boxes, etc) of every vehicle and walker in the [simulation state](#simulation-state) module.
* Updates the list of registered vehicles stored by the [vehicle registry](#vehicle-registry).
* Updates entries in the [control loop](#control-loop) and [PBVT](#pbvt) modules to match the list of registered vehicles.
__Related .cpp files:__ `ALSM.h`, `ALSM.cpp`. - Scans the world to keep track of all vehicles and pedestrians, their positions and velocities. If physics are enabled, the velocity is retrieved by [Vehicle.get_velocity()](python_api.md#carla.Vehicle). Otherwise, the velocity is calculated using the history of position updates over time.
- Stores the position, velocity, and additional information (traffic light influence, bounding boxes, etc) of every vehicle and pedestrian in the [simulation state](#simulation-state) component.
- Updates the list of TM-controlled vehicles in the [vehicle registry](#vehicle-registry).
- Updates entries in the [control loop](#control-loop) and [PBVT](#pbvt) components to match the vehicle registry.
### Command array __Related .cpp files:__ `ALSM.h`, `ALSM.cpp`.
Last step in the TM logic cycle. Receives commands for all the registered vehicles and applies them.
* Receives a series of [carla.VehicleControl](python_api.md#carla.VehicleControl) from the [Motion Planner Stage](#stage-4-motion-planner-stage).
* Constructs a batch for all the commands to be applied during the same frame.
* Sends the batch to the CARLA server. Either __apply_batch()__ or __apply_batch_synch()__ in [carla.Client](../python_api/#carla.Client) will be called, depending if the simulation is running in asynchronous or synchronous mode, respectively.
__Related .cpp files:__ `TrafficManagerLocal.cpp`.
### Control loop
Manages the process of calculating the next command for all the registered vehicles, so that these are done in synchrony.
* Receives from the [vehicle registry](#vehicle-registry) an array of the vehicles registered to the TM.
* Loops over said array, performing calculations per vehicle separately.
* These calculations are divided into a series of [stages](#stages).
* Synchronization barriers are placed between stages so that consistency is guaranteed. Calculations for all vehicles must finish before any of them moves to the next stage, ensuring that all vehicles are updated in the same frame.
* Coordinates the transition between [stages](#stages) so that all the calculations are done in sync.
* When the last stage ([Motion Planner Stage](#stage-4-motion-planner-stage)) finishes, the [command array](#command-array) is sent to the server. In this way, there are no frame delays between the calculations of the control loop, and the commands being applied.
__Related .cpp files:__ `TrafficManagerLocal.cpp`.
### In-Memory Map
Helper module contained by the [PBVT](#pbvt) and used during the [Localization Stage](#stage-1-localization-stage).
* Discretizes the map into a grid of waypoints.
* Includes waypoints in a specific data structure with more information to connect waypoints and identify roads, junctions, etc.
* Identifies these structures with an ID that is used to quickly spot vehicles in nearby areas.
__Related .cpp files:__ `InMemoryMap.cpp` and `SimpleWaypoint.cpp`.
### PBVT
PBVT stands for __Path Buffer and Vehicle Tracking__. This data structure contains the expected path for every vehicle so that it can be easily accessible during the [control loop](#control-loop).
* Contains a map of deque objects with one entry per vehicle.
* For each vehicle, contains a set of waypoints describing its current location and near-future path.
* Contains the [In-Memory Map](#in-memory-map) that will be used by the [Localization Stage](#stage-1-localization-stage) to relate every vehicle to the nearest waypoint and possible overlapping paths.
### PID controller
Helper module that performs calculations during the [Motion Planner Stage](#stage-4-motion-planner-stage).
* Using the information gathered by the [Motion Planner Stage](#stage-4-motion-planner-stage), estimates the throttle, brake and steering input needed to reach a target value.
* The adjustment is made depending on the specific parameterization of the controller, which can be modified if desired. Read more about [PID controllers](https://en.wikipedia.org/wiki/PID_controller) to learn how to do it.
__Related .cpp files:__ `PIDController.cpp`.
### Simulation state
Stores information about the vehicles in the world so that it can be easily accessed during the whole process.
* Receives the current state of all vehicles and walkers in the world from the [ALSM](#alsm), including their position, velocity and some additional information (such as traffic light influence and state). It also stores some additional information such as whether these vehicles are under the influence of a traffic light and what the current state of that traffic light is.
* Stores in cache all the information so that no additional calls to the server are needed during the [control loop](#control-loop).
__Related .cpp files:__ `SimulationState.cpp`, `SimulationState.h`.
### Stages
##### Stage 1- Localization Stage
First stage in the [control loop](#control-loop). Defines a near-future path for registered vehicles.
* Obtains the position and velocity of all the vehicles from the [simulation state](#simulation-state).
* Using the [In-Memory Map](#in-memory-map), relates every vehicle with a list of waypoints that describes its current location and near-future path, according to its trajectory. The faster the vehicle goes, the larger the list will be.
* The path is updated according to planning decisions such as lane changes, speed limit, distance to leading vehicle parameterization, etc.
* The [PBVT](#pbvt) module stores the path for all the vehicles.
* These paths are compared with each other, in order to estimate possible collision situations. Results are passed to the Colllision Stage.
__Related .cpp files:__ `LocalizationStage.cpp` and `LocalizationUtils.cpp`.
##### Stage 2- Collision Stage
Second stage in the [control loop](#control-loop). Triggers collision hazards.
* Receives a list of pairs of vehicles with possible overlapping paths from the Localization Stage.
* For every pair, extends bounding boxes along the path ahead (geodesic boundaries), to check if they actually overlap and the risk of collision is real.
* Hazards for all the possible collisions will be sent to the [Motion Planner Stage](#stage-4-motion-planner-stage) to modify the path accordingly.
__Related .cpp files:__ `CollisionStage.cpp`.
##### Stage 3- Traffic Light Stage
Third stage in the [control loop](#control-loop). Triggers hazards to follow traffic regulations such as traffic lights, stop signs, and priority at junctions.
* If the vehicle is under the influence of a yellow or red traffic light or a stop sign, sets a traffic hazard.
* If the vehicle is in a non-signalized junction, a bounding box is extended along its path. Vehicles with overlapping paths follow a FIFO order to move and waits are set to a fixed time.
__Related .cpp files:__ `TrafficLightStage.cpp`.
##### Stage 4- Motion Planner Stage
Fourth and last stage in the [control loop](#control-loop). Generates the CARLA command that will be applied to the vehicle.
* Gathers all the information so far: position and velocity of the vehicles ([simulation state](#simulation-state)), their path ([PBVT](#pbvt)) and hazards ([Collision Stage](#stage-2-collision-stage) and [Traffic Light Stage](#stage-3-traffic-light-stage)).
* Makes high-level decisions about how the vehicle should move, for example, computing the brake needed to prevent a collision hazard. A [PID controller](#pid-controller) is used to estimate behaviors according to target values.
* Translates the desired movement to a [carla.VehicleControl](python_api.md#carla.VehicleControl) that can be applied to the vehicle.
* Sends the resulting CARLA commands to the [command array](#command-array).
__Related .cpp files:__ `MotionPlannerStage.cpp`.
### Vehicle registry ### Vehicle registry
Keeps track of all the vehicles and walkers in the simulation. The vehicle registry keeps track of all vehicles and pedestrians in the simulation.
* The [ALSM](#alsm) scans the world and passes an updated list of walkers and vehicles. The vehicle registry:
* Vehicles registered to the TM are stored in a separated array that will be iterated on during the [control loop](#control-loop).
__Related .cpp files:__ `MotionPlannerStage.cpp`. - Is passed an updated list of vehicles and pedestrians from the [ALSM](#alsm).
- Stores vehicles registered to the TM in a separate array for iteration during the [control loop](#control-loop).
__Related .cpp files:__ `MotionPlannerStage.cpp`.
### Simulation state
The simulation state stores information about all vehicles in the simulation for easy access and modification in later stages.
The simulation state:
- Receives data from the [ALSM](#alsm) including current actor position, velocity, traffic light influence, traffic light state, etc.
- Stores all information in cache, avoiding subsequent calls to the server during the [control loop](#control-loop).
__Related .cpp files:__ `SimulationState.cpp`, `SimulationState.h`.
### Control loop
The control loop manages the calculations of the next command for all autopilot vehicles so they are performed synchronously. The control loop consists of four different [stages](#stages-of-the-control-loop); localization, collision, traffic light, and motion planner.
The control loop:
- Receives an array of TM-controlled vehicles from the [vehicle registry](#vehicle-registry).
- Performs calculations for each vehicle separately by looping over the array.
- Divides calculations into a series of [stages](#stages-of-the-control-loop).
- Creates synchronization barriers between stages to guarantee consistency. Calculations for all vehicles are finished before any of them move to the next stage, ensuring all vehicles are updated in the same frame.
- Coordinates the transition between [stages](#stages-of-the-control-loop) so all calculations are done in sync.
- Sends the [command array](#command-array) to the server when the last stage ([Motion Planner Stage](#stage-4-motion-planner-stage)) finishes so there are no frame delays between the command calculations and the command application.
__Related .cpp files:__ `TrafficManagerLocal.cpp`.
### In-Memory Map
The In-Memory Map is a helper module contained within the [PBVT](#pbvt) and is used during the [Localization Stage](#stage-1-localization-stage).
The In-Memory Map:
- Converts the map into a grid of discrete waypoints.
- Includes waypoints in a specific data structure with more information to connect waypoints and identify roads, junctions, etc.
- Identifies these structures with an ID used to locate vehicles in nearby areas quickly.
__Related .cpp files:__ `InMemoryMap.cpp` and `SimpleWaypoint.cpp`.
### PBVT
PBVT stands for __Path Buffer and Vehicle Tracking__. The PBVT is a data structure that contains the expected path for every vehicle and allows easy access to data during the [control loop](#control-loop).
The PBVT:
- Contains a map of deque objects with one entry per vehicle.
- Contains a set of waypoints for each vehicle describing its current location and near-future path.
- Contains the [In-Memory Map](#in-memory-map) used by the [Localization Stage](#stage-1-localization-stage) to relate every vehicle to the nearest waypoint and possible overlapping paths.
### PID controller
The PID controller is a helper module that performs calculations during the [Motion Planner Stage](#stage-4-motion-planner-stage).
The PID controller:
- Estimates the throttle, brake, and steering input needed to reach a target value using the information gathered by the [Motion Planner Stage](#stage-4-motion-planner-stage).
- Makes adjustments depending on the specific parameterization of the controller. Parameters can be modified if desired. Read more about [PID controllers](https://en.wikipedia.org/wiki/PID_controller) to learn how to make modifications.
__Related .cpp files:__ `PIDController.cpp`.
### Command Array
The Command Array represents the last step in the TM logic cycle. It receives commands for all the registered vehicles and applies them.
The Command Array:
- Receives a series of [carla.VehicleControl](python_api.md#carla.VehicleControl)'s from the [Motion Planner Stage](#stage-4-motion-planner-stage).
- Batches all commands to be applied during the same frame.
- Sends the batch to the CARLA server calling either __apply_batch()__ or __apply_batch_synch()__ in [carla.Client](../python_api/#carla.Client) depending on whether the simulation is running in asynchronous or synchronous mode, respectively.
__Related .cpp files:__ `TrafficManagerLocal.cpp`.
### Stages of the Control Loop
##### Stage 1- Localization Stage
The Localization Stage defines a near-future path for vehicles controlled by the TM.
The Localization Stage:
- Obtains the position and velocity of all vehicles from the [simulation state](#simulation-state).
- Uses the [In-Memory Map](#in-memory-map) to relate every vehicle with a list of waypoints that describes its current location and near-future path according to its trajectory. The faster the vehicle goes, the longer the list will be.
- Updates the path according to planning decisions such as lane changes, speed limit, distance to leading vehicle parameterization, etc.
- Stores the path for all vehicles in the [PBVT](#pbvt) module.
- Compares paths with each other to estimate possible collision situations. Results are passed to the Collision Stage.
__Related .cpp files:__ `LocalizationStage.cpp` and `LocalizationUtils.cpp`.
##### Stage 2- Collision Stage
The Collision Stage triggers collision hazards.
The Collision Stage:
- Receives from the [Localization Stage](#stage-1-localization-stage) a list of vehicle pairs whose paths could potentially overlap.
- Extends bounding boxes along the path ahead (geodesic boundaries) for each vehicle pair to check if they actually overlap and determine whether the risk of collision is real.
- Sends hazards for all possible collisions to the [Motion Planner Stage](#stage-4-motion-planner-stage) to modify the path accordingly.
__Related .cpp files:__ `CollisionStage.cpp`.
##### Stage 3- Traffic Light Stage
The Traffic Light stage triggers hazards due to traffic regulators such as traffic lights, stop signs, and priority at junctions.
The Traffic Light stage:
- Sets a traffic hazard if a vehicle is under the influence of a yellow or red traffic light or a stop sign.
- Extends a bounding box along a vehicle's path if it is in an unsignaled junction. Vehicles with overlapping paths follow a "First-In-First-Out" order to move. Wait times are set to a fixed value.
__Related .cpp files:__ `TrafficLightStage.cpp`.
##### Stage 4- Motion Planner Stage
The Motion Planner Stage generates the CARLA commands to be applied to vehicles.
The Motion Planner Stage:
- Gathers a vehicle's position and velocity ([simulation state](#simulation-state)), path ([PBVT](#pbvt)), and hazards ([Collision Stage](#stage-2-collision-stage) and [Traffic Light Stage](#stage-3-traffic-light-stage)).
- Makes high-level decisions about how a vehicle should move, for example, computing the brake needed to prevent a collision hazard. A [PID controller](#pid-controller) is used to estimate behaviors according to target values.
- Translates the desired movement to a [carla.VehicleControl](python_api.md#carla.VehicleControl) for application to the vehicle.
- Sends the resulting CARLA commands to the [Command Array](#command-array).
__Related .cpp files:__ `MotionPlannerStage.cpp`.
--- ---
## Using the Traffic Manager ## Using the Traffic Manager
### General considerations ### Vehicle behavior considerations
First of all there are some general behaviour patterns the TM will generate that should be understood beforehand. These statements are inherent to the way the TM is implemented: The TM implements general behavior patterns that must be taken into consideration when you set vehicles to autopilot:
* __Vehicles are not goal-oriented,__ they follow a trajectory and whenever approaching a junction, choose a path randomly. Their path is endless and they will never stop roaming around the city. - __Vehicles are not goal-oriented,__ they follow a dynamically produced trajectory and choose a path randomly when approaching a junction. Their path is endless.
* __Vehicles' target speed is 70% their current speed limit,__ unless any other value is set. - __Vehicles' target speed is 70% of their current speed limit__ unless any other value is set.
* __Junction priority does not follow traffic regulations.__ The TM uses its own priority system while junction complexity is solved. This may cause some issues such as a vehicle inside a roundabout yielding to a vehicle trying to get in. - __Junction priority does not follow traffic regulations.__ The TM uses its own priority system at junctions. The resolution of this restriction is a work in progress. In the meantime, some issues may arise, for example, vehicles inside a roundabout yielding to a vehicle trying to get in.
TM behavior can be adjusted through the Python API. For specific methods, see the TM section of the Python API [documentation](../python_api/#carla.TrafficManager). Below is a general summary of what is possible through the API:
| Topic | Description |
| ----- | ----------- |
| **General:** | - Create a TM instance connected to a port. <br> - Retrieve the port where a TM is connected. |
| **Safety conditions:** | - Set a minimum distance between stopped vehicles (for a single vehicle or for all vehicles). This will affect the minimum moving distance. <br> - Set the desired speed as a percentage of the current speed limit (for a single vehicle or for all vehicles). <br> - Reset traffic lights. |
| **Collision managing:** | - Enable/Disable collisions between a vehicle and a specific actor. <br> - Make a vehicle ignore all other vehicles. <br> - Make a vehicle ignore all walkers. <br> - Make a vehicle ignore all traffic lights. |
| **Lane changes:** | - Force a lane change, ignoring possible collisions. <br> - Enable/Disable lane changes for a vehicle. |
| **Hybrid physics mode:** | - Enable/Disable hybrid physics mode. <br> - Change the radius in which physics is enabled. |
The TM provides a set of possibilities so the user can establish specific behaviours. All the methods accessible from the Python API are listed in the [documentation](../python_api/#carla.TrafficManager). Here is a general summary of what the current possibilities are.
| Topic | Description |
| ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| **General:** | <br> **1\.** Use a carla.Client to create a TM instance connected to a port.<br> **2\.** Retrieve the port where a TM is connected. |
| **Safety conditions:** | <br> **1\.** Set a minimum distance between stopped vehicles (for a single vehicle or for all of them). This will affect the minimum moving distance. <br> **2\.** Set an intended speed regarding current speed limitation (for a single vehicle or for all of them). <br> **3\.** Reset traffic lights. |
| **Collision managing:** | <br> **1\.** Enable/Disable collisions between a vehicle and a specific actor. <br> **2\.** Make a vehicle ignore all other vehicles. <br> **3\.** Make a vehicle ignore all walkers. <br>**4\.** Make a vehicle ignore all traffic lights. |
| **Lane changes:** | <br> **1\.** Force a lane change disregarding possible collisions. <br> **2\.** Enable/Disable lane changes for a vehicle. |
| **Hybrid physics mode:** | <br> **1\.** Enable/Disable the hybrid physics mode. <br> **2\.** Change the radius where physics are enabled. |
<br>
<br>
### Creating a Traffic Manager ### Creating a Traffic Manager
A TM instance can be created by any [carla.Client](python_api.md#carla.Client) specifying the port that will be used. The default port is `8000`. !!! Note
TM is designed to work in synchronous mode. Using TM in asynchronous mode can lead to unexpected and undesirable results. Read more in the section [__Synchronous mode__](#synchronous-mode).
A TM instance is created by a [`carla.Client`](python_api.md#carla.Client), passing the port to be used. The default port is `8000`.
To create a TM instance:
```python ```python
tm = client.get_trafficmanager(port) tm = client.get_trafficmanager(port)
``` ```
Now the TM needs some vehicles to be in charge of. In order to do so, enable the autopilot mode for the set of vehicles to be managed. Retrieve the port of the TM object that has been created. If no port is provided, it will try to connect to a TM in the default port, `8000`. If the TM does not exist, it will create it. To enable autopilot for a set of vehicles, retrieve the port of the TM instance and set `set_autopilot` to `True`, passing the TM port at the same time. If no port is provided, it will try to connect to a TM in the default port (`8000`). If the TM does not exist, it will create one:
```python ```python
tm_port = tm.get_port() tm_port = tm.get_port()
@ -230,9 +273,9 @@ tm_port = tm.get_port()
v.set_autopilot(True,tm_port) v.set_autopilot(True,tm_port)
``` ```
!!! Note !!! Note
In multiclient situations, creating or connecting to a TM is not that straightforward. Take a look at the [*Running multiple Traffic Managers*](#running-multiple-traffic-managers) section to learn more about this. Creating or connecting to a TM in multi-client situations is different from the above example. Learn more in the section [__Running multiple Traffic Managers__](#running-multiple-traffic-managers).
The script `spawn_npc.py` in `/PythonAPI/examples` creates a TM instance in the port passed as an argument and registers every vehicle spawned to it by setting the autopilot to True on a batch. The `generate_traffic.py` script in `/PythonAPI/examples` provides an example of how to create a TM instance using a port passed as a script argument and register every vehicle spawned to it by setting the autopilot to `True` in a batch:
```py ```py
traffic_manager = client.get_trafficmanager(args.tm-port) traffic_manager = client.get_trafficmanager(args.tm-port)
@ -243,9 +286,9 @@ batch.append(SpawnActor(blueprint, transform).then(SetAutopilot(FutureActor, Tru
traffic_manager.global_percentage_speed_difference(30.0) traffic_manager.global_percentage_speed_difference(30.0)
``` ```
### Setting a Traffic Manager ### Configuring autopilot behavior
The following example creates an instance of the TM and sets a dangerous behaviour for a specific car that will ignore all traffic lights, leave no safety distance with the rest and drive at 120% its current speed limit. The following example creates a TM instance and configures dangerous behavior for a specific vehicle so it will ignore all traffic lights, leave no safety distance from other vehicles, and drive 20% faster than the current speed limit:
```python ```python
tm = client.get_trafficmanager(port) tm = client.get_trafficmanager(port)
@ -258,7 +301,8 @@ tm.distance_to_leading_vehicle(danger_car,0)
tm.vehicle_percentage_speed_difference(danger_car,-20) tm.vehicle_percentage_speed_difference(danger_car,-20)
``` ```
Now, here is an example that registers that same list of vehicles but instead is set to conduct them with a moderate behaviour. The vehicles will drive at 80% their current speed limit, leaving at least 5 meters between them and never perform a lane change. The example below sets the same list of vehicles to autopilot but instead configures them with moderate driving behavior. The vehicles drive 80% slower than the current speed limit, leaving at least 5 meters between themselves and other vehicles, and never perform lane changes:
```python ```python
tm = client.get_trafficmanager(port) tm = client.get_trafficmanager(port)
tm_port = tm.get_port() tm_port = tm.get_port()
@ -273,56 +317,65 @@ for v in my_vehicles:
### Stopping a Traffic Manager ### Stopping a Traffic Manager
The TM is not an actor that needs to be destroyed, it will stop when the corresponding client stops. This is automatically managed by the API so the user does not have to take care of it. The TM is not an actor that needs to be destroyed; it will stop when the client that created it stops. This is automatically managed by the API, the user does not have to do anything. However, when shutting down a TM, the user must destroy the vehicles controlled by it, otherwise they will remain immobile on the map. The script `generate_traffic.py` does this automatically:
However, it is important that when shutting down a TM, the vehicles registered to it are destroyed. Otherwise, they will stop in place, as no one will be conducting them. The script `spawn_npc.py` does this automatically.
!!! Warning ```py
Shutting down a __TM-Server__ will shut down the __TM-Clients__ connecting to it. To learn the difference between a __TM-Server__ and a __TM-Client__ read about [*Running multiple Traffic Managers*](#running-multiple-traffic-managers). client.apply_batch([carla.command.DestroyActor(x) for x in vehicles_list])
```
!!! Warning
Shutting down a __TM-Server__ will shut down the __TM-Clients__ connecting to it. To learn the difference between a __TM-Server__ and a __TM-Client__, read about [__Running multiple Traffic Managers__](#running-multiple-traffic-managers).
--- ---
## Deterministic mode ## Deterministic mode
In deterministic mode, the Traffic Manager will always produce the same results and behaviours under the same conditions. Do not mistake determinism with the recorder. While the recorder allows you to store the log of a simulation to play it back, determinism ensures that Traffic Manager will always have the same output over different executions of a script, if the same conditions are maintained. In deterministic mode, the TM will produce the same results and behaviors under the same conditions. Do not mistake determinism with the recorder. While the recorder allows you to store the log of a simulation to play it back, determinism ensures that the TM will always have the same output over different executions of a script as long as the same conditions are maintained.
Deterministic mode is meant to be used __in synchronous mode only__. In asynchronous mode, there is much less control over the simulation, and determinism cannot be achieved. Read the considerations to run [TM in synchronous mode](#synchronous-mode) before using it. Deterministic mode is available __in synchronous mode only__. In asynchronous mode, there is less control over the simulation and determinism cannot be achieved. Read more in the section [__"Synchronous mode"__](#synchronous-mode) before starting.
To enable deterministic mode, use the following method:
To enable deterministic mode, simply call the following method in your script.
```py ```py
my_tm.set_random_device_seed(seed_value) my_tm.set_random_device_seed(seed_value)
``` ```
`seed_value` is an `int` number from which all the random numbers will be generated. The value is not relevant itself, but the same value will always result in the same output. Two simulations, with the same conditions, that use the same seed value, will be deterministic. `seed_value` is an `int` number from which random numbers will be generated. The value itself is not relevant, but the same value will always result in the same output. Two simulations, with the same conditions, that use the same seed value, will be deterministic.
The deterministic mode can be tested when using the `spawn_npc.py` example script, using a simple argument. The following example sets the seed to `9` for no specific reason. To maintain determinism over multiple simulation runs, __the seed must be set for every simulation__. For example, each time the world is [reloaded](python_api.md#carla.Client.reload_world), the seed must be set again:
```py
client.reload_world()
my_tm.set_random_device_seed(seed_value)
```
Deterministic mode can be tested in the `generate_traffic.py` example script by passing a seed value as an argument. The following example populates a map with 50 autopilot actors in synchronous mode and sets the seed to an arbitrary value of `9`:
```sh ```sh
cd PythonAPI/examples cd PythonAPI/examples
python3 spawn_npc.py -n 50 --sync --seed 9 python3 generate_traffic.py -n 50 --seed 9
``` ```
!!! Warning !!! Warning
Make sure to set both the world and the TM to synchronous mode before enabling deterministic mode. The CARLA server and the TM must be in synchronous mode before enabling deterministic mode. Read more [here](#synchronous-mode) about synchronous mode in TM.
--- ---
## Hybrid physics mode ## Hybrid physics mode
In hybrid mode, either all vehicle physics can be disabled, or enabled only in a radius around an ego vehicle with the tag `hero`. This feature removes the vehicle physics bottleneck from the simulator. Since vehicle physics are not active, all cars move by teleportation. This feature relies on [Actor.set_simulate_physics()](https://carla.readthedocs.io/en/latest/python_api/#carla.Actor.set_simulate_physics). However, not all the physics are disregarded. Basic calculations for a linear acceleration are maintained. By doing so, the position update, and vehicle speed still look realistic. This guarantees that when a vehicle enables or disables its physics, the transition is fluid. Hybrid mode allows users to disable most physics calculations for all autopilot vehicles, or for autopilot vehicles outside of a certain radius of a vehicle tagged with `hero`. This removes the vehicle physics bottleneck from a simulation. Vehicles whose physics are disabled will move by teleportation. Basic calculations for linear acceleration are maintained to ensure position updates and vehicle speed remain realistic and the toggling of physics calculations on vehicles is fluid.
The hybrid mode is disabled by default. There are two ways to enable it: Hybrid mode uses the [`Actor.set_simulate_physics()`](https://carla.readthedocs.io/en/latest/python_api/#carla.Actor.set_simulate_physics) method to toggle physics calculations. It is disabled by default. There are two options to enable it:
* [__TrafficManager.set_hybrid_physics_mode(True)__](https://carla.readthedocs.io/en/latest/python_api/#carla.TrafficManager.set_hybrid_physics_mode) — This method will enable the hybrid mode for the Traffic Manager object calling it. * [__`TrafficManager.set_hybrid_physics_mode(True)`__](https://carla.readthedocs.io/en/latest/python_api/#carla.TrafficManager.set_hybrid_physics_mode) — This method enables hybrid mode for the TM object calling it.
* __Running `spawn_npc.py` with the flag `--hybrid`__ — The vehicles spawned will be registered to a Traffic Manager stated inside the script, and this will run with the hybrid physics on. * __Running `generate_traffic.py` with the flag `--hybrid`__ — This example script creates a TM and spawns vehicles in autopilot. It then sets these vehicles to hybrid mode when the `--hybrid` flag is passed as a script argument.
There are two parameters ruling the hybrid mode: To modify the behavior of hybrid mode, use the following two parameters:
* __Radius__ *(default = 50 meters)*States the proximity area around the ego vehicle where physics are enabled. The value can be changed via [traffic_manager.set_hybrid_physics_radius(r)](python_api.md#carla.TrafficManager.set_hybrid_physics_radius). * __Radius__ *(default = 50 meters)*The radius is relative to vehicles tagged with `hero`. All vehicles inside this radius will have physics enabled; vehicles outside of the radius will have physics disabled. The size of the radius is modified using [`traffic_manager.set_hybrid_physics_radius(r)`](python_api.md#carla.TrafficManager.set_hybrid_physics_radius).
* __Ego vehicle__ — A vehicle tagged with `role_name='hero'` that will act as the center of the radius. * __Hero vehicle__ — A vehicle tagged with `role_name='hero'` that acts as the center of the radius.
* __If there is none,__ all the vehicles will disable physics. * __If there is no hero vehicle,__ all vehicles' physics will be disabled.
* __If there are many,__ the radius will be considered for all of them. That will create different areas of influence with physics enabled. * __If there is more than one hero vehicle,__ the radius will be considered for them all, creating different areas of influence with physics enabled.
The following example shows how the physics are enabled and disabled when hybrid mode is on. The __ego vehicle__ is tagged with a __red square__. Vehicles with __physics disabled__ are tagged with a __blue square__. When inside the area of influence stated by the radius, __physics are enabled and the tag becomes green__. The clip below shows how physics is enabled and disabled when hybrid mode is active. The __hero vehicle__ is tagged with a __red square__. Vehicles with __physics disabled__ are tagged with a __blue square__. When inside the hero vehicle's radius of influence, __physics are enabled and the tag becomes green__.
![Welcome to CARLA](img/tm_hybrid.gif) ![Welcome to CARLA](img/tm_hybrid.gif)
@ -330,14 +383,15 @@ The following example shows how the physics are enabled and disabled when hybrid
--- ---
## Running multiple Traffic Managers ## Running multiple Traffic Managers
### Definitions ### Traffic Manager servers and clients
When working with different clients containing different TMs, understanding the inner implementation of the TM in the client-server architecture becomes especially relevant. There is one key to ruling these scenarios: __the port__. A CARLA client creates a TM by specifying to the server which port to use. If a port is not specified, the default `8000` will be used. If further TMs are created on the same port, they will become __TM-Clients__ and the original TM will become a __TM-Server__. These titles define how a TM behaves within a simulation.
A client creates a TM by communicating with the server and passing the intended port to be used for that purpose. The port can either be stated or not, using the default of `8000`. ###### TM-Server
A TM-Server is created if it was the first TM to connect to a free port and then other TMs (TM-Clients) connected to the same port it was running on. __The TM-Server will dictate the behavior of all the TM-Clients__, e.g., if the TM-Server is stopped, all TM-Clients will stop.
* __TM-Server__ — The port is free. This type of TM is in charge of its own logic, managed in `TrafficManagerLocal.cpp`. The following code creates two TM-Servers. Each one connects to a different port, not previously used. The following code creates two TM-Servers. Each one connects to a different, unused port:
```py ```py
tm01 = client01.get_trafficmanager() # tm01 --> tm01 (p=8000) tm01 = client01.get_trafficmanager() # tm01 --> tm01 (p=8000)
@ -346,65 +400,64 @@ tm01 = client01.get_trafficmanager() # tm01 --> tm01 (p=8000)
tm02 = client02.get_trafficmanager(5000) # tm02(p=5000) --> tm02 (p=5000) tm02 = client02.get_trafficmanager(5000) # tm02(p=5000) --> tm02 (p=5000)
``` ```
* __TM-Client__ — The port is occupied by another TM. These instances are not in charge of their own logic. Instead, they ask for changes in the parameters of the __TM-Server__ they are connected to in `TrafficManagerRemote.cpp`. The following code creates two TM-Clients, that connect with the TM-Servers previously created. ###### TM-Client
```py A TM-Client is created when a TM connects to a port occupied by another TM (TM-Server). The TM-Client behavior will be dictated by the TM-Server.
The following code creates two TM-Clients, each one connecting with the TM-Servers created in the section above.
```py
tm03 = client03.get_trafficmanager() # tm03 --> tm01 (p=8000). tm03 = client03.get_trafficmanager() # tm03 --> tm01 (p=8000).
``` ```
```py ```py
tm04 = client04.get_trafficmanager(5000) # tm04(p=5000) --> tm02 (p=5000) tm04 = client04.get_trafficmanager(5000) # tm04(p=5000) --> tm02 (p=5000)
``` ```
!!! Important The CARLA server keeps a register of all TM instances by storing the port and the client IP (hidden to the user) that link to them. There is currently no way to check the TM instances that have been created so far. A connection will always be attempted when trying to create an instance and it will either create a new __TM-Server__ or a __TM-Client__.
Note how the default creation of a TM uses always `port=8000`, and so, only the first time a __TM-Server__ is created. The rest will be __TM-Clients__ connecting to it.
The CARLA server keeps a register of all the TM instances internally by storing the port and the client IP (hidden to the user) that link to them. Right now there is no way to check the TM instances that have been created so far. A connection will always be attempted when trying to create an instance and it will either create a new __TM-Server__ or a __TM-Client__. ### Multi-client simulations
!!! Note In a multi-client simulation, multiple TMs are created on the same port. The first TM will be a TM-Server and the rest will be TM-Clients connecting to it. The TM-Server will dictate the behavior of all the TM instances:
The class `TrafficManager.cpp` acts as a central hub managing all the different TM instances.
### Multiclient
More than one TM instances created with the same port. The first will be a TM-Server. The rest will be TM-Clients connecting to it.
```py ```py
terminal 1: ./CarlaUE4.sh -carla-rpc-port=4000 terminal 1: ./CarlaUE4.sh -carla-rpc-port=4000
terminal 2: python3 spawn_npc.py --port 4000 --tm-port 4050 # TM-Server terminal 2: python3 generate_traffic.py --port 4000 --tm-port 4050 # TM-Server
terminal 3: python3 spawn_npc.py --port 4000 --tm-port 4050 # TM-Client terminal 3: python3 generate_traffic.py --port 4000 --tm-port 4050 # TM-Client
``` ```
### MultiTM ### Multi-TM simulations
In a multi-TM simulation, multiple TM instances are created on distinct ports. Each TM instance will control its own behavior:
Different TM instances with different ports assigned.
```py ```py
terminal 1: ./CarlaUE4.sh -carla-rpc-port=4000 terminal 1: ./CarlaUE4.sh -carla-rpc-port=4000
terminal 2: python3 spawn_npc.py --port 4000 --tm-port 4050 # TM-Server A terminal 2: python3 generate_traffic.py --port 4000 --tm-port 4050 # TM-Server A
terminal 3: python3 spawn_npc.py --port 4000 --tm-port 4550 # TM-Server B terminal 3: python3 generate_traffic.py --port 4000 --tm-port 4550 # TM-Server B
``` ```
### Multisimulation ### Multi-simulation
Multisimulation is when there are more than one CARLA server running at the same time. The TM declaration is not relevant. As long as the computational power allows for it, the TM can run multiple simulations at a time without any problems. Multi-simulation is when more than one CARLA server is running at the same time. The TM needs to connect to the relevant CARLA server port. As long as the computational power allows for it, the TM can run multiple simulations at a time without any problems:
```py ```py
terminal 1: ./CarlaUE4.sh -carla-rpc-port=4000 # simulation A terminal 1: ./CarlaUE4.sh -carla-rpc-port=4000 # simulation A
terminal 2: ./CarlaUE4.sh -carla-rpc-port=5000 # simulation B terminal 2: ./CarlaUE4.sh -carla-rpc-port=5000 # simulation B
terminal 3: python3 spawn_npc.py --port 4000 --tm-port 4050 # TM-Server A connected to simulation A terminal 3: python3 generate_traffic.py --port 4000 --tm-port 4050 # TM-Server A connected to simulation A
terminal 4: python3 spawn_npc.py --port 5000 --tm-port 5050 # TM-Server B connected to simulation B terminal 4: python3 generate_traffic.py --port 5000 --tm-port 5050 # TM-Server B connected to simulation B
``` ```
The concept of multisimulation is independent from the Traffic Manager itself. The example above runs two CARLA simulations in parallel, A and B. In each of them, a TM-Server is created independently from the other. Simulation A could run a Multiclient TM while simulation B is running a MultiTM, or no TM at all. The concept of multi-simulation is independent of the TM itself. The example above runs two CARLA simulations in parallel, A and B. In each of them, a TM-Server is created independently from the other. Simulation A could run a multi-client TM while simulation B is running a multi-TM or no TM at all.
The only possible issue arising from this is a client trying to connect to an already existing TM which is not running on the selected simulation. In case this happens, an error message will appear and the connection will be aborted to prevent interferences between simulations. The most likely issue arising from the above set-up is a client trying to connect to an already existing TM that is not running on the selected simulation. If this happens, an error message will appear and the connection will be aborted to prevent interferences between simulations.
--- ---
## Other considerations ## Synchronous mode
The TM is a module constantly evolving and trying to adapt the range of possibilities that it presents. For instance, in order to get more realistic behaviours we can have many clients with different TM in charge of sets of vehicles with specific and distinct behaviours. This range of possibilities also makes for a lot of different configurations that can get really complex and specific. For this reason, the following are considerations that should be taken into account when working with the TM: TM is designed to work in synchronous mode. Both the CARLA server and TM should be set to synchronous in order to function properly. __Using TM in asynchronous mode can lead to unexpected and undesirable results,__ however, if asynchronous mode is required, the simulation should run at 20-30 fps at least.
### Synchronous mode The script below demonstrates how to set both the server and TM to synchronous mode:
If the CARLA server is set to synchronous mode, the Traffic Manager must be set to synchronous mode too. To do so, your script should be similar to the following:
```py ```py
... ...
@ -412,7 +465,7 @@ If the CARLA server is set to synchronous mode, the Traffic Manager must be set
init_settings = world.get_settings() init_settings = world.get_settings()
settings = world.get_settings() settings = world.get_settings()
settings.synchronous_mode = True settings.synchronous_mode = True
# Right after that, set the Traffic Manager to sync mode # After that, set the TM to sync mode
my_tm.set_synchronous_mode(True) my_tm.set_synchronous_mode(True)
... ...
@ -422,37 +475,74 @@ world.apply_settings(init_settings)
world.tick() world.tick()
... ...
# Disable the sync mode always, before the script ends # Always disable sync mode before the script ends to prevent the server blocking whilst waiting for a tick
settings.synchronous_mode = False settings.synchronous_mode = False
my_tm.set_synchronous_mode(False) my_tm.set_synchronous_mode(False)
``` ```
When using the `spawn_npc.py` example script, the TM can be set to synchronous mode just by passing an argument. The `generate_traffic.py` example script starts a TM and populates the map with vehicles and pedestrians. It automatically sets the TM and the CARLA server to synchronous mode:
```sh ```sh
cd PythonAPI/examples cd PythonAPI/examples
python3 spawn_npc.py -n 50 --sync python3 generate_traffic.py -n 50
``` ```
If more than one Traffic Manager is set to synchronous mode, the synchrony will fail. Follow these general guidelines to avoid issues. If asynchronous mode is required, use the `--async` flag when running the above command.
* In a __[multiclient](#multiclient)__ situation, only the __TM-Server__ must be set to synchronous mode. If more than one TM is set to synchronous mode, synchrony will fail. Follow these guidelines to avoid issues:
* In a __[multiTM](#multitm)__ situation, only __one of the TM-Server__ must be set to synchronous mode.
* The __[ScenarioRunner module](https://carla-scenariorunner.readthedocs.io/en/latest/)__, already runs a TM. In this case, the TM inside ScenarioRunner will be the one set to sync mode. - In a __[multiclient](#multiclient)__ situation, only the __TM-Server__ should be set to synchronous mode.
- In a __[multiTM](#multitm)__ situation, only __one TM-Server__ should be set to synchronous mode.
- The __[ScenarioRunner module](https://carla-scenariorunner.readthedocs.io/en/latest/)__ runs a TM automatically. The TM inside ScenarioRunner will automatically be the one set to sync mode.
!!! Warning !!! Warning
Disable the synchronous mode (both, world and TM sync mode) in the script doing the ticks before it finishes. Otherwise, the server will be blocked, waiting forever for a tick. Disable synchronous mode (for both the world and TM) in your script managing ticks before it finishes to prevent the server blocking, waiting forever for a tick.
--- ---
## Summary
## Traffic manager in large maps
The Traffic Manager is one of the most complex features in CARLA and so, one that is prone to all kind of unexpected and really specific issues. The CARLA forum is open to everybody to post any doubts or suggestions, and it is the best way to keep track of issues and help the CARLA community to become greater. Feel free to login and join the community. To understand how the TM works on large maps, make sure to first familiarise yourself with how large maps work by reading the documentation [here](large_map_overview.md).
The behavior of autopilot vehicles in large maps depends on whether or not there is a hero vehicle present:
__Hero vehicle not present__
All autopilot vehicles will be considered dormant actors. The dormant autopilot actors will be moved around the map as in hybrid mode. The vehicles will not be rendered since there is no hero vehicle to trigger map tile streaming.
__Hero vehicle present__
Autopilot vehicles will become dormant when they exceed the value defined by `actor_active_distance`. To set this value, use the Python API:
```py
settings = world.get_settings()
# Actors will become dormant 2km away from the ego vehicle
settings.actor_active_distance = 2000
world.apply_settings(settings)
```
In the TM, dormant actors can be configured to continually respawn around the hero vehicle instead of remaining dormant on other parts of the map. This option can be configured using the `set_respawn_dormant_vehicles` method in the Python API. Vehicles will be respawned within a user-definable distance of the hero vehicle. The upper and lower boundaries of the respawnable distance can be set using the `set_boundaries_respawn_dormant_vehicles` method. Note that the upper distance will not be bigger than the tile streaming distance of the large map and the minimum lower distance is 20m.
To enable respawning of dormant vehicles within 25 and 700 meters of the hero vehicle:
```py
my_tm.set_respawn_dormant_vehicles(True)
my_tm.set_boundaries_respawn_dormant_vehicles(25,700)
```
If collisions prevent a dormant actor from being respawned, the TM will retry on the next simulation step.
If dormant vehicles are not respawned, their behavior will depend on whether hybrid mode is enabled. If hybrid mode has been enabled, then the dormant actors will be teleported around the map. If hybrid mode is not enabled, then dormant actor's physics will not be computed and they will stay in place until they are no longer dormant.
---
If you have any questions about the TM, then you can ask in the [forum](https://github.com/carla-simulator/carla/discussions).
<div class="build-buttons"> <div class="build-buttons">
<!-- Latest release button -->
<p> <p>
<a href="https://github.com/carla-simulator/carla/discussions/" target="_blank" class="btn btn-neutral" title="Go to the latest CARLA release"> <a href="https://github.com/carla-simulator/carla/discussions" target="_blank" class="btn btn-neutral" title="Go to the CARLA forum">
CARLA forum</a> CARLA forum</a>
</p> </p>
</div> </div>

View File

@ -225,7 +225,7 @@ Test the simulator using the example scripts inside `PythonAPI\examples`. With
# Terminal A # Terminal A
cd PythonAPI/examples cd PythonAPI/examples
python3 -m pip install -r requirements.txt python3 -m pip install -r requirements.txt
python3 spawn_npc.py python3 generate_traffic.py
# Terminal B # Terminal B
cd PythonAPI/examples cd PythonAPI/examples
@ -321,10 +321,10 @@ make launch
# Terminal A # Terminal A
cd PythonAPI/examples cd PythonAPI/examples
python3 -m pip install -r requirements.txt python3 -m pip install -r requirements.txt
python3 spawn_npc.py python3 generate_traffic.py
# Terminal B # Terminal B
cd PythonAPI/examples cd PythonAPI/examples
python3 spawn_npc.py python3 generate_traffic.py
python3 dynamic_weather.py python3 dynamic_weather.py
# Optionally, to compile the PythonAPI for Python2 # Optionally, to compile the PythonAPI for Python2

View File

@ -206,7 +206,7 @@ Test the simulator using the example scripts inside `PythonAPI\examples`. With
# Terminal A # Terminal A
cd PythonAPI\examples cd PythonAPI\examples
pip install -r requirements.txt pip install -r requirements.txt
python3 spawn_npc.py python3 generate_traffic.py
# Terminal B # Terminal B
cd PythonAPI\examples cd PythonAPI\examples
@ -274,7 +274,7 @@ make launch
# Terminal A # Terminal A
cd PythonAPI\examples cd PythonAPI\examples
pip install -r requirements.txt pip install -r requirements.txt
python3 spawn_npc.py python3 generate_traffic.py
# Terminal B # Terminal B
cd PythonAPI\examples cd PythonAPI\examples
python3 dynamic_weather.py python3 dynamic_weather.py

View File

@ -123,10 +123,11 @@ Here is a list of options available for visualization. Additional elements may s
* `/stop_sign` — Show the map's stop signs in the visualization window. * `/stop_sign` — Show the map's stop signs in the visualization window.
Try to spawn some actors. These will be automatically updated in the visualization window. Try to spawn some actors. These will be automatically updated in the visualization window.
```sh ```sh
cd PythonAPI/examples cd PythonAPI/examples
python3 spawn_npc.py -n 10 -w 5 # Spawns actors in a synchronous mode simulation
python3 generate_traffic.py -n 10 -w 5
``` ```
![carlaviz_full](img/plugins_carlaviz_full.jpg) ![carlaviz_full](img/plugins_carlaviz_full.jpg)

View File

@ -413,11 +413,11 @@ Client constructor.
- `port` (_int_) TCP port where the CARLA Simulator instance is running. Default are 2000 and the subsequent 2001. - `port` (_int_) TCP port where the CARLA Simulator instance is running. Default are 2000 and the subsequent 2001.
- `worker_threads` (_int_) Number of working threads used for background updates. If 0, use all available concurrency. - `worker_threads` (_int_) Number of working threads used for background updates. If 0, use all available concurrency.
- <a name="carla.Client.apply_batch"></a>**<font color="#7fb800">apply_batch</font>**(<font color="#00a6ed">**self**</font>, <font color="#00a6ed">**commands**</font>) - <a name="carla.Client.apply_batch"></a>**<font color="#7fb800">apply_batch</font>**(<font color="#00a6ed">**self**</font>, <font color="#00a6ed">**commands**</font>)
Executes a list of commands on a single simulation step and retrieves no information. If you need information about the response of each command, use the __<font color="#7fb800">apply_batch_sync()</font>__ method. [Here](https://github.com/carla-simulator/carla/blob/10c5f6a482a21abfd00220c68c7f12b4110b7f63/PythonAPI/examples/spawn_npc.py#L126) is an example on how to delete the actors that appear in [carla.ActorList](#carla.ActorList) all at once. Executes a list of commands on a single simulation step and retrieves no information. If you need information about the response of each command, use the __<font color="#7fb800">apply_batch_sync()</font>__ method. [Here](https://github.com/carla-simulator/carla/blob/master/PythonAPI/examples/generate_traffic.py) is an example on how to delete the actors that appear in [carla.ActorList](#carla.ActorList) all at once.
- **Parameters:** - **Parameters:**
- `commands` (_list_) A list of commands to execute in batch. Each command is different and has its own parameters. They appear listed at the bottom of this page. - `commands` (_list_) A list of commands to execute in batch. Each command is different and has its own parameters. They appear listed at the bottom of this page.
- <a name="carla.Client.apply_batch_sync"></a>**<font color="#7fb800">apply_batch_sync</font>**(<font color="#00a6ed">**self**</font>, <font color="#00a6ed">**commands**</font>, <font color="#00a6ed">**due_tick_cue**=False</font>)<button class="SnipetButton" id="carla.Client.apply_batch_sync-snipet_button">snippet &rarr;</button> - <a name="carla.Client.apply_batch_sync"></a>**<font color="#7fb800">apply_batch_sync</font>**(<font color="#00a6ed">**self**</font>, <font color="#00a6ed">**commands**</font>, <font color="#00a6ed">**due_tick_cue**=False</font>)<button class="SnipetButton" id="carla.Client.apply_batch_sync-snipet_button">snippet &rarr;</button>
Executes a list of commands on a single simulation step, blocks until the commands are linked, and returns a list of <b>command.Response</b> that can be used to determine whether a single command succeeded or not. [Here](https://github.com/carla-simulator/carla/blob/10c5f6a482a21abfd00220c68c7f12b4110b7f63/PythonAPI/examples/spawn_npc.py#L112-L116) is an example of it being used to spawn actors. Executes a list of commands on a single simulation step, blocks until the commands are linked, and returns a list of <b>command.Response</b> that can be used to determine whether a single command succeeded or not. [Here](https://github.com/carla-simulator/carla/blob/master/PythonAPI/examples/generate_traffic.py) is an example of it being used to spawn actors.
- **Parameters:** - **Parameters:**
- `commands` (_list_) A list of commands to execute in batch. The commands available are listed right above, in the method **<font color="#7fb800">apply_batch()</font>**. - `commands` (_list_) A list of commands to execute in batch. The commands available are listed right above, in the method **<font color="#7fb800">apply_batch()</font>**.
- `due_tick_cue` (_bool_) A boolean parameter to specify whether or not to perform a [carla.World.tick](#carla.World.tick) after applying the batch in _synchronous mode_. It is __False__ by default. - `due_tick_cue` (_bool_) A boolean parameter to specify whether or not to perform a [carla.World.tick](#carla.World.tick) after applying the batch in _synchronous mode_. It is __False__ by default.
@ -3010,7 +3010,7 @@ Asks the server for the XODR containing the map file, and returns this parsed as
- **Warning:** <font color="#ED2F2F">_This method does call the simulation. It is expensive, and should only be called once. - **Warning:** <font color="#ED2F2F">_This method does call the simulation. It is expensive, and should only be called once.
_</font> _</font>
- <a name="carla.World.get_random_location_from_navigation"></a>**<font color="#7fb800">get_random_location_from_navigation</font>**(<font color="#00a6ed">**self**</font>) - <a name="carla.World.get_random_location_from_navigation"></a>**<font color="#7fb800">get_random_location_from_navigation</font>**(<font color="#00a6ed">**self**</font>)
This can only be used with walkers. It retrieves a random location to be used as a destination using the __<font color="#7fb800">go_to_location()</font>__ method in [carla.WalkerAIController](#carla.WalkerAIController). This location will be part of a sidewalk. Roads, crosswalks and grass zones are excluded. The method does not take into consideration locations of existing actors so if a collision happens when trying to spawn an actor, it will return an error. Take a look at [`spawn_npc.py`](https://github.com/carla-simulator/carla/blob/e73ad54d182e743b50690ca00f1709b08b16528c/PythonAPI/examples/spawn_npc.py#L179) for an example. This can only be used with walkers. It retrieves a random location to be used as a destination using the __<font color="#7fb800">go_to_location()</font>__ method in [carla.WalkerAIController](#carla.WalkerAIController). This location will be part of a sidewalk. Roads, crosswalks and grass zones are excluded. The method does not take into consideration locations of existing actors so if a collision happens when trying to spawn an actor, it will return an error. Take a look at [`generate_traffic.py`](https://github.com/carla-simulator/carla/blob/master/PythonAPI/examples/generate_traffic.py) for an example.
- **Return:** _[carla.Location](#carla.Location)_ - **Return:** _[carla.Location](#carla.Location)_
- <a name="carla.World.get_settings"></a>**<font color="#7fb800">get_settings</font>**(<font color="#00a6ed">**self**</font>) - <a name="carla.World.get_settings"></a>**<font color="#7fb800">get_settings</font>**(<font color="#00a6ed">**self**</font>)
Returns an object containing some data about the simulation such as synchrony between client and server or rendering mode. Returns an object containing some data about the simulation such as synchrony between client and server or rendering mode.
@ -3470,37 +3470,146 @@ world.load_map_layer(carla.MapLayer.ParkedVehicles)
</div> </div>
<div id ="carla.ActorBlueprint.set_attribute-snipet" style="display: none;"> <div id ="carla.World.unload_map_layer-snipet" style="display: none;">
<p class="SnipetFont"> <p class="SnipetFont">
Snippet for carla.ActorBlueprint.set_attribute Snippet for carla.World.unload_map_layer
</p> </p>
<div id="carla.ActorBlueprint.set_attribute-code" class="SnipetContent"> <div id="carla.World.unload_map_layer-code" class="SnipetContent">
```py
# This recipe toggles off several layers in our "_Opt" maps
# Load town one with minimum layout (roads, sidewalks, traffic lights and traffic signs)
# as well as buildings and parked vehicles
world = client.load_world('Town01_Opt', carla.MapLayer.Buildings | carla.MapLayer.ParkedVehicles)
# Toggle all buildings off
world.unload_map_layer(carla.MapLayer.Buildings)
# Toggle all parked vehicles off
world.unload_map_layer(carla.MapLayer.ParkedVehicles)
```
<button id="button1" class="CopyScript" onclick="CopyToClipboard('carla.World.unload_map_layer-code')">Copy snippet</button>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<button id="button1" class="CloseSnipet" onclick="CloseSnipet()">Close snippet</button><br><br>
</div>
<div id ="carla.Map.get_waypoint-snipet" style="display: none;">
<p class="SnipetFont">
Snippet for carla.Map.get_waypoint
</p>
<div id="carla.Map.get_waypoint-code" class="SnipetContent">
```py ```py
# This recipe changes attributes of different type of blueprint actors. # This recipe shows the current traffic rules affecting the vehicle.
# Shows the current lane type and if a lane change can be done in the actual lane or the surrounding ones.
# ... # ...
walker_bp = world.get_blueprint_library().filter('walker.pedestrian.0002') waypoint = world.get_map().get_waypoint(vehicle.get_location(),project_to_road=True, lane_type=(carla.LaneType.Driving | carla.LaneType.Shoulder | carla.LaneType.Sidewalk))
walker_bp.set_attribute('is_invincible', True) print("Current lane type: " + str(waypoint.lane_type))
# Check current lane change allowed
# ... print("Current Lane change: " + str(waypoint.lane_change))
# Changes attribute randomly by the recommended value # Left and Right lane markings
vehicle_bp = wolrd.get_blueprint_library().filter('vehicle.bmw.*') print("L lane marking type: " + str(waypoint.left_lane_marking.type))
color = random.choice(vehicle_bp.get_attribute('color').recommended_values) print("L lane marking change: " + str(waypoint.left_lane_marking.lane_change))
vehicle_bp.set_attribute('color', color) print("R lane marking type: " + str(waypoint.right_lane_marking.type))
print("R lane marking change: " + str(waypoint.right_lane_marking.lane_change))
# ...
camera_bp = world.get_blueprint_library().filter('sensor.camera.rgb')
camera_bp.set_attribute('image_size_x', 600)
camera_bp.set_attribute('image_size_y', 600)
# ... # ...
``` ```
<button id="button1" class="CopyScript" onclick="CopyToClipboard('carla.ActorBlueprint.set_attribute-code')">Copy snippet</button>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<button id="button1" class="CloseSnipet" onclick="CloseSnipet()">Close snippet</button><br><br> <button id="button1" class="CopyScript" onclick="CopyToClipboard('carla.Map.get_waypoint-code')">Copy snippet</button>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<button id="button1" class="CloseSnipet" onclick="CloseSnipet()">Close snippet</button><br><br>
<img src="/img/snipets_images/carla.Map.get_waypoint.jpg">
</div>
<div id ="carla.World.get_spectator-snipet" style="display: none;">
<p class="SnipetFont">
Snippet for carla.World.get_spectator
</p>
<div id="carla.World.get_spectator-code" class="SnipetContent">
```py
# This recipe spawns an actor and the spectator camera at the actor's location.
# ...
world = client.get_world()
spectator = world.get_spectator()
vehicle_bp = random.choice(world.get_blueprint_library().filter('vehicle.bmw.*'))
transform = random.choice(world.get_map().get_spawn_points())
vehicle = world.try_spawn_actor(vehicle_bp, transform)
# Wait for world to get the vehicle actor
world.tick()
world_snapshot = world.wait_for_tick()
actor_snapshot = world_snapshot.find(vehicle.id)
# Set spectator at given transform (vehicle transform)
spectator.set_transform(actor_snapshot.get_transform())
# ...
```
<button id="button1" class="CopyScript" onclick="CopyToClipboard('carla.World.get_spectator-code')">Copy snippet</button>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<button id="button1" class="CloseSnipet" onclick="CloseSnipet()">Close snippet</button><br><br>
</div>
<div id ="carla.WalkerAIController.stop-snipet" style="display: none;">
<p class="SnipetFont">
Snippet for carla.WalkerAIController.stop
</p>
<div id="carla.WalkerAIController.stop-code" class="SnipetContent">
```py
#To destroy the pedestrians, stop them from the navigation, and then destroy the objects (actor and controller).
# stop pedestrians (list is [controller, actor, controller, actor ...])
for i in range(0, len(all_id), 2):
all_actors[i].stop()
# destroy pedestrian (actor and controller)
client.apply_batch([carla.command.DestroyActor(x) for x in all_id])
```
<button id="button1" class="CopyScript" onclick="CopyToClipboard('carla.WalkerAIController.stop-code')">Copy snippet</button>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<button id="button1" class="CloseSnipet" onclick="CloseSnipet()">Close snippet</button><br><br>
</div>
<div id ="carla.World.spawn_actor-snipet" style="display: none;">
<p class="SnipetFont">
Snippet for carla.World.spawn_actor
</p>
<div id="carla.World.spawn_actor-code" class="SnipetContent">
```py
# This recipe attaches different camera / sensors to a vehicle with different attachments.
# ...
camera = world.spawn_actor(rgb_camera_bp, transform, attach_to=vehicle, attachment_type=Attachment.Rigid)
# Default attachment: Attachment.Rigid
gnss_sensor = world.spawn_actor(sensor_gnss_bp, transform, attach_to=vehicle)
collision_sensor = world.spawn_actor(sensor_collision_bp, transform, attach_to=vehicle)
lane_invasion_sensor = world.spawn_actor(sensor_lane_invasion_bp, transform, attach_to=vehicle)
# ...
```
<button id="button1" class="CopyScript" onclick="CopyToClipboard('carla.World.spawn_actor-code')">Copy snippet</button>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<button id="button1" class="CloseSnipet" onclick="CloseSnipet()">Close snippet</button><br><br>
</div> </div>
@ -3577,27 +3686,112 @@ for i in range(0, len(all_actors), 2):
</div> </div>
<div id ="carla.WalkerAIController.stop-snipet" style="display: none;"> <div id ="carla.ActorBlueprint.set_attribute-snipet" style="display: none;">
<p class="SnipetFont"> <p class="SnipetFont">
Snippet for carla.WalkerAIController.stop Snippet for carla.ActorBlueprint.set_attribute
</p> </p>
<div id="carla.WalkerAIController.stop-code" class="SnipetContent"> <div id="carla.ActorBlueprint.set_attribute-code" class="SnipetContent">
```py ```py
#To destroy the pedestrians, stop them from the navigation, and then destroy the objects (actor and controller). # This recipe changes attributes of different type of blueprint actors.
# stop pedestrians (list is [controller, actor, controller, actor ...]) # ...
for i in range(0, len(all_id), 2): walker_bp = world.get_blueprint_library().filter('walker.pedestrian.0002')
all_actors[i].stop() walker_bp.set_attribute('is_invincible', True)
# destroy pedestrian (actor and controller) # ...
client.apply_batch([carla.command.DestroyActor(x) for x in all_id]) # Changes attribute randomly by the recommended value
vehicle_bp = wolrd.get_blueprint_library().filter('vehicle.bmw.*')
color = random.choice(vehicle_bp.get_attribute('color').recommended_values)
vehicle_bp.set_attribute('color', color)
# ...
camera_bp = world.get_blueprint_library().filter('sensor.camera.rgb')
camera_bp.set_attribute('image_size_x', 600)
camera_bp.set_attribute('image_size_y', 600)
# ...
``` ```
<button id="button1" class="CopyScript" onclick="CopyToClipboard('carla.WalkerAIController.stop-code')">Copy snippet</button>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<button id="button1" class="CloseSnipet" onclick="CloseSnipet()">Close snippet</button><br><br> <button id="button1" class="CopyScript" onclick="CopyToClipboard('carla.ActorBlueprint.set_attribute-code')">Copy snippet</button>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<button id="button1" class="CloseSnipet" onclick="CloseSnipet()">Close snippet</button><br><br>
</div>
<div id ="carla.DebugHelper.draw_box-snipet" style="display: none;">
<p class="SnipetFont">
Snippet for carla.DebugHelper.draw_box
</p>
<div id="carla.DebugHelper.draw_box-code" class="SnipetContent">
```py
# This recipe shows how to draw traffic light actor bounding boxes from a world snapshot.
# ....
debug = world.debug
world_snapshot = world.get_snapshot()
for actor_snapshot in world_snapshot:
actual_actor = world.get_actor(actor_snapshot.id)
if actual_actor.type_id == 'traffic.traffic_light':
debug.draw_box(carla.BoundingBox(actor_snapshot.get_transform().location,carla.Vector3D(0.5,0.5,2)),actor_snapshot.get_transform().rotation, 0.05, carla.Color(255,0,0,0),0)
# ...
```
<button id="button1" class="CopyScript" onclick="CopyToClipboard('carla.DebugHelper.draw_box-code')">Copy snippet</button>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<button id="button1" class="CloseSnipet" onclick="CloseSnipet()">Close snippet</button><br><br>
<img src="/img/snipets_images/carla.DebugHelper.draw_box.jpg">
</div>
<div id ="carla.Sensor.listen-snipet" style="display: none;">
<p class="SnipetFont">
Snippet for carla.Sensor.listen
</p>
<div id="carla.Sensor.listen-code" class="SnipetContent">
```py
# This recipe applies a color conversion to the image taken by a camera sensor,
# so it is converted to a semantic segmentation image.
# ...
camera_bp = world.get_blueprint_library().filter('sensor.camera.semantic_segmentation')
# ...
cc = carla.ColorConverter.CityScapesPalette
camera.listen(lambda image: image.save_to_disk('output/%06d.png' % image.frame, cc))
# ...
```
<button id="button1" class="CopyScript" onclick="CopyToClipboard('carla.Sensor.listen-code')">Copy snippet</button>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<button id="button1" class="CloseSnipet" onclick="CloseSnipet()">Close snippet</button><br><br>
</div>
<div id ="carla.Vehicle.set_wheel_steer_direction-snipet" style="display: none;">
<p class="SnipetFont">
Snippet for carla.Vehicle.set_wheel_steer_direction
</p>
<div id="carla.Vehicle.set_wheel_steer_direction-code" class="SnipetContent">
```py
# Sets the appearance of the vehicles front wheels to 40°. Vehicle physics will not be affected.
vehicle.set_wheel_steer_direction(carla.VehicleWheelLocation.FR_Wheel, 40.0)
vehicle.set_wheel_steer_direction(carla.VehicleWheelLocation.FL_Wheel, 40.0)
```
<button id="button1" class="CopyScript" onclick="CopyToClipboard('carla.Vehicle.set_wheel_steer_direction-code')">Copy snippet</button>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<button id="button1" class="CloseSnipet" onclick="CloseSnipet()">Close snippet</button><br><br>
</div> </div>
@ -3640,36 +3834,78 @@ while True:
</div> </div>
<div id ="carla.Map.get_waypoint-snipet" style="display: none;"> <div id ="carla.World.enable_environment_objects-snipet" style="display: none;">
<p class="SnipetFont"> <p class="SnipetFont">
Snippet for carla.Map.get_waypoint Snippet for carla.World.enable_environment_objects
</p> </p>
<div id="carla.Map.get_waypoint-code" class="SnipetContent"> <div id="carla.World.enable_environment_objects-code" class="SnipetContent">
```py
# This recipe turn visibility off and on for two specifc buildings on the map
# Get the buildings in the world
world = client.get_world()
env_objs = world.get_environment_objects(carla.CityObjectLabel.Buildings)
# Access individual building IDs and save in a set
building_01 = env_objs[0]
building_02 = env_objs[1]
objects_to_toggle = {building_01.id, building_02.id}
# Toggle buildings off
world.enable_environment_objects(objects_to_toggle, False)
# Toggle buildings on
world.enable_environment_objects(objects_to_toggle, True)
```
<button id="button1" class="CopyScript" onclick="CopyToClipboard('carla.World.enable_environment_objects-code')">Copy snippet</button>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<button id="button1" class="CloseSnipet" onclick="CloseSnipet()">Close snippet</button><br><br>
</div>
<div id ="carla.Client.__init__-snipet" style="display: none;">
<p class="SnipetFont">
Snippet for carla.Client.__init__
</p>
<div id="carla.Client.__init__-code" class="SnipetContent">
```py ```py
# This recipe shows the current traffic rules affecting the vehicle. # This recipe shows in every script provided in PythonAPI/Examples
# Shows the current lane type and if a lane change can be done in the actual lane or the surrounding ones. # and it is used to parse the client creation arguments when running the script.
argparser = argparse.ArgumentParser(
description=__doc__)
argparser.add_argument(
'--host',
metavar='H',
default='127.0.0.1',
help='IP of the host server (default: 127.0.0.1)')
argparser.add_argument(
'-p', '--port',
metavar='P',
default=2000,
type=int,
help='TCP port to listen to (default: 2000)')
argparser.add_argument(
'-s', '--speed',
metavar='FACTOR',
default=1.0,
type=float,
help='rate at which the weather changes (default: 1.0)')
args = argparser.parse_args()
speed_factor = args.speed
update_freq = 0.1 / speed_factor
client = carla.Client(args.host, args.port)
# ...
waypoint = world.get_map().get_waypoint(vehicle.get_location(),project_to_road=True, lane_type=(carla.LaneType.Driving | carla.LaneType.Shoulder | carla.LaneType.Sidewalk))
print("Current lane type: " + str(waypoint.lane_type))
# Check current lane change allowed
print("Current Lane change: " + str(waypoint.lane_change))
# Left and Right lane markings
print("L lane marking type: " + str(waypoint.left_lane_marking.type))
print("L lane marking change: " + str(waypoint.left_lane_marking.lane_change))
print("R lane marking type: " + str(waypoint.right_lane_marking.type))
print("R lane marking change: " + str(waypoint.right_lane_marking.lane_change))
# ...
``` ```
<button id="button1" class="CopyScript" onclick="CopyToClipboard('carla.Map.get_waypoint-code')">Copy snippet</button>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<button id="button1" class="CloseSnipet" onclick="CloseSnipet()">Close snippet</button><br><br> <button id="button1" class="CopyScript" onclick="CopyToClipboard('carla.Client.__init__-code')">Copy snippet</button>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<button id="button1" class="CloseSnipet" onclick="CloseSnipet()">Close snippet</button><br><br>
<img src="/img/snipets_images/carla.Map.get_waypoint.jpg">
</div> </div>
@ -3719,242 +3955,6 @@ if vehicle_actor.is_at_traffic_light():
</div> </div>
<div id ="carla.World.unload_map_layer-snipet" style="display: none;">
<p class="SnipetFont">
Snippet for carla.World.unload_map_layer
</p>
<div id="carla.World.unload_map_layer-code" class="SnipetContent">
```py
# This recipe toggles off several layers in our "_Opt" maps
# Load town one with minimum layout (roads, sidewalks, traffic lights and traffic signs)
# as well as buildings and parked vehicles
world = client.load_world('Town01_Opt', carla.MapLayer.Buildings | carla.MapLayer.ParkedVehicles)
# Toggle all buildings off
world.unload_map_layer(carla.MapLayer.Buildings)
# Toggle all parked vehicles off
world.unload_map_layer(carla.MapLayer.ParkedVehicles)
```
<button id="button1" class="CopyScript" onclick="CopyToClipboard('carla.World.unload_map_layer-code')">Copy snippet</button>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<button id="button1" class="CloseSnipet" onclick="CloseSnipet()">Close snippet</button><br><br>
</div>
<div id ="carla.DebugHelper.draw_box-snipet" style="display: none;">
<p class="SnipetFont">
Snippet for carla.DebugHelper.draw_box
</p>
<div id="carla.DebugHelper.draw_box-code" class="SnipetContent">
```py
# This recipe shows how to draw traffic light actor bounding boxes from a world snapshot.
# ....
debug = world.debug
world_snapshot = world.get_snapshot()
for actor_snapshot in world_snapshot:
actual_actor = world.get_actor(actor_snapshot.id)
if actual_actor.type_id == 'traffic.traffic_light':
debug.draw_box(carla.BoundingBox(actor_snapshot.get_transform().location,carla.Vector3D(0.5,0.5,2)),actor_snapshot.get_transform().rotation, 0.05, carla.Color(255,0,0,0),0)
# ...
```
<button id="button1" class="CopyScript" onclick="CopyToClipboard('carla.DebugHelper.draw_box-code')">Copy snippet</button>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<button id="button1" class="CloseSnipet" onclick="CloseSnipet()">Close snippet</button><br><br>
<img src="/img/snipets_images/carla.DebugHelper.draw_box.jpg">
</div>
<div id ="carla.Client.__init__-snipet" style="display: none;">
<p class="SnipetFont">
Snippet for carla.Client.__init__
</p>
<div id="carla.Client.__init__-code" class="SnipetContent">
```py
# This recipe shows in every script provided in PythonAPI/Examples
# and it is used to parse the client creation arguments when running the script.
argparser = argparse.ArgumentParser(
description=__doc__)
argparser.add_argument(
'--host',
metavar='H',
default='127.0.0.1',
help='IP of the host server (default: 127.0.0.1)')
argparser.add_argument(
'-p', '--port',
metavar='P',
default=2000,
type=int,
help='TCP port to listen to (default: 2000)')
argparser.add_argument(
'-s', '--speed',
metavar='FACTOR',
default=1.0,
type=float,
help='rate at which the weather changes (default: 1.0)')
args = argparser.parse_args()
speed_factor = args.speed
update_freq = 0.1 / speed_factor
client = carla.Client(args.host, args.port)
```
<button id="button1" class="CopyScript" onclick="CopyToClipboard('carla.Client.__init__-code')">Copy snippet</button>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<button id="button1" class="CloseSnipet" onclick="CloseSnipet()">Close snippet</button><br><br>
</div>
<div id ="carla.Vehicle.set_wheel_steer_direction-snipet" style="display: none;">
<p class="SnipetFont">
Snippet for carla.Vehicle.set_wheel_steer_direction
</p>
<div id="carla.Vehicle.set_wheel_steer_direction-code" class="SnipetContent">
```py
# Sets the appearance of the vehicles front wheels to 40°. Vehicle physics will not be affected.
vehicle.set_wheel_steer_direction(carla.VehicleWheelLocation.FR_Wheel, 40.0)
vehicle.set_wheel_steer_direction(carla.VehicleWheelLocation.FL_Wheel, 40.0)
```
<button id="button1" class="CopyScript" onclick="CopyToClipboard('carla.Vehicle.set_wheel_steer_direction-code')">Copy snippet</button>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<button id="button1" class="CloseSnipet" onclick="CloseSnipet()">Close snippet</button><br><br>
</div>
<div id ="carla.Sensor.listen-snipet" style="display: none;">
<p class="SnipetFont">
Snippet for carla.Sensor.listen
</p>
<div id="carla.Sensor.listen-code" class="SnipetContent">
```py
# This recipe applies a color conversion to the image taken by a camera sensor,
# so it is converted to a semantic segmentation image.
# ...
camera_bp = world.get_blueprint_library().filter('sensor.camera.semantic_segmentation')
# ...
cc = carla.ColorConverter.CityScapesPalette
camera.listen(lambda image: image.save_to_disk('output/%06d.png' % image.frame, cc))
# ...
```
<button id="button1" class="CopyScript" onclick="CopyToClipboard('carla.Sensor.listen-code')">Copy snippet</button>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<button id="button1" class="CloseSnipet" onclick="CloseSnipet()">Close snippet</button><br><br>
</div>
<div id ="carla.World.enable_environment_objects-snipet" style="display: none;">
<p class="SnipetFont">
Snippet for carla.World.enable_environment_objects
</p>
<div id="carla.World.enable_environment_objects-code" class="SnipetContent">
```py
# This recipe turn visibility off and on for two specifc buildings on the map
# Get the buildings in the world
world = client.get_world()
env_objs = world.get_environment_objects(carla.CityObjectLabel.Buildings)
# Access individual building IDs and save in a set
building_01 = env_objs[0]
building_02 = env_objs[1]
objects_to_toggle = {building_01.id, building_02.id}
# Toggle buildings off
world.enable_environment_objects(objects_to_toggle, False)
# Toggle buildings on
world.enable_environment_objects(objects_to_toggle, True)
```
<button id="button1" class="CopyScript" onclick="CopyToClipboard('carla.World.enable_environment_objects-code')">Copy snippet</button>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<button id="button1" class="CloseSnipet" onclick="CloseSnipet()">Close snippet</button><br><br>
</div>
<div id ="carla.World.spawn_actor-snipet" style="display: none;">
<p class="SnipetFont">
Snippet for carla.World.spawn_actor
</p>
<div id="carla.World.spawn_actor-code" class="SnipetContent">
```py
# This recipe attaches different camera / sensors to a vehicle with different attachments.
# ...
camera = world.spawn_actor(rgb_camera_bp, transform, attach_to=vehicle, attachment_type=Attachment.Rigid)
# Default attachment: Attachment.Rigid
gnss_sensor = world.spawn_actor(sensor_gnss_bp, transform, attach_to=vehicle)
collision_sensor = world.spawn_actor(sensor_collision_bp, transform, attach_to=vehicle)
lane_invasion_sensor = world.spawn_actor(sensor_lane_invasion_bp, transform, attach_to=vehicle)
# ...
```
<button id="button1" class="CopyScript" onclick="CopyToClipboard('carla.World.spawn_actor-code')">Copy snippet</button>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<button id="button1" class="CloseSnipet" onclick="CloseSnipet()">Close snippet</button><br><br>
</div>
<div id ="carla.World.get_spectator-snipet" style="display: none;">
<p class="SnipetFont">
Snippet for carla.World.get_spectator
</p>
<div id="carla.World.get_spectator-code" class="SnipetContent">
```py
# This recipe spawns an actor and the spectator camera at the actor's location.
# ...
world = client.get_world()
spectator = world.get_spectator()
vehicle_bp = random.choice(world.get_blueprint_library().filter('vehicle.bmw.*'))
transform = random.choice(world.get_map().get_spawn_points())
vehicle = world.try_spawn_actor(vehicle_bp, transform)
# Wait for world to get the vehicle actor
world.tick()
world_snapshot = world.wait_for_tick()
actor_snapshot = world_snapshot.find(vehicle.id)
# Set spectator at given transform (vehicle transform)
spectator.set_transform(actor_snapshot.get_transform())
# ...
```
<button id="button1" class="CopyScript" onclick="CopyToClipboard('carla.World.get_spectator-code')">Copy snippet</button>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<button id="button1" class="CloseSnipet" onclick="CloseSnipet()">Close snippet</button><br><br>
</div>
</div> </div>

View File

@ -23,7 +23,7 @@ Let's start by adding some live to the city, open a new terminal window and
execute execute
```sh ```sh
./spawn_npc.py -n 80 ./generate_traffic.py -n 80
``` ```
This adds 80 vehicles to the world driving in "autopilot" mode. Back to the This adds 80 vehicles to the world driving in "autopilot" mode. Back to the

View File

@ -137,7 +137,7 @@ This is the server simulator which is now running and waiting for a client to co
python3 -m pip install -r requirements.txt # Support for Python2 is provided in the CARLA release packages python3 -m pip install -r requirements.txt # Support for Python2 is provided in the CARLA release packages
python3 spawn_npc.py python3 generate_traffic.py
# Terminal B # Terminal B
cd PythonAPI\examples cd PythonAPI\examples
@ -210,7 +210,7 @@ CarlaUE4.exe
# Run a script to test CARLA. # Run a script to test CARLA.
cd PythonAPI/examples cd PythonAPI/examples
python3 -m pip install -r requirements.txt python3 -m pip install -r requirements.txt
python3 spawn_npc.py # Support for Python 2 is provided in the CARLA release packages python3 generate_traffic.py # Support for Python 2 is provided in the CARLA release packages
``` ```

View File

@ -199,7 +199,7 @@ python3 spawn_npc.py -n 50 -w 50 --safe
--filterv PATTERN vehicles filter (default: "vehicle.*") --filterv PATTERN vehicles filter (default: "vehicle.*")
--filterw PATTERN pedestrians filter (default: "walker.pedestrian.*") --filterw PATTERN pedestrians filter (default: "walker.pedestrian.*")
-tm_p P, --tm-port P port to communicate with TM (default: 8000) -tm_p P, --tm-port P port to communicate with TM (default: 8000)
--sync Synchronous mode execution --async Asynchronous mode execution
``` ```
</details> </details>
<br> <br>

View File

@ -43,7 +43,7 @@
A list of commands to execute in batch. Each command is different and has its own parameters. They appear listed at the bottom of this page. A list of commands to execute in batch. Each command is different and has its own parameters. They appear listed at the bottom of this page.
doc: > doc: >
Executes a list of commands on a single simulation step and retrieves no information. If you need information about the response of each command, use the __<font color="#7fb800">apply_batch_sync()</font>__ method. Executes a list of commands on a single simulation step and retrieves no information. If you need information about the response of each command, use the __<font color="#7fb800">apply_batch_sync()</font>__ method.
[Here](https://github.com/carla-simulator/carla/blob/10c5f6a482a21abfd00220c68c7f12b4110b7f63/PythonAPI/examples/spawn_npc.py#L126) is an example on how to delete the actors that appear in carla.ActorList all at once. [Here](https://github.com/carla-simulator/carla/blob/master/PythonAPI/examples/generate_traffic.py) is an example on how to delete the actors that appear in carla.ActorList all at once.
# -------------------------------------- # --------------------------------------
- def_name: apply_batch_sync - def_name: apply_batch_sync
params: params:
@ -58,7 +58,7 @@
A boolean parameter to specify whether or not to perform a carla.World.tick after applying the batch in _synchronous mode_. It is __False__ by default. A boolean parameter to specify whether or not to perform a carla.World.tick after applying the batch in _synchronous mode_. It is __False__ by default.
return: list(command.Response) return: list(command.Response)
doc: > doc: >
Executes a list of commands on a single simulation step, blocks until the commands are linked, and returns a list of <b>command.Response</b> that can be used to determine whether a single command succeeded or not. [Here](https://github.com/carla-simulator/carla/blob/10c5f6a482a21abfd00220c68c7f12b4110b7f63/PythonAPI/examples/spawn_npc.py#L112-L116) is an example of it being used to spawn actors. Executes a list of commands on a single simulation step, blocks until the commands are linked, and returns a list of <b>command.Response</b> that can be used to determine whether a single command succeeded or not. [Here](https://github.com/carla-simulator/carla/blob/master/PythonAPI/examples/generate_traffic.py) is an example of it being used to spawn actors.
# -------------------------------------- # --------------------------------------
- def_name: generate_opendrive_world - def_name: generate_opendrive_world
params: params:

View File

@ -510,7 +510,7 @@
- def_name: get_random_location_from_navigation - def_name: get_random_location_from_navigation
return: carla.Location return: carla.Location
doc: > doc: >
This can only be used with walkers. It retrieves a random location to be used as a destination using the __<font color="#7fb800">go_to_location()</font>__ method in carla.WalkerAIController. This location will be part of a sidewalk. Roads, crosswalks and grass zones are excluded. The method does not take into consideration locations of existing actors so if a collision happens when trying to spawn an actor, it will return an error. Take a look at [`spawn_npc.py`](https://github.com/carla-simulator/carla/blob/e73ad54d182e743b50690ca00f1709b08b16528c/PythonAPI/examples/spawn_npc.py#L179) for an example. This can only be used with walkers. It retrieves a random location to be used as a destination using the __<font color="#7fb800">go_to_location()</font>__ method in carla.WalkerAIController. This location will be part of a sidewalk. Roads, crosswalks and grass zones are excluded. The method does not take into consideration locations of existing actors so if a collision happens when trying to spawn an actor, it will return an error. Take a look at [`generate_traffic.py`](https://github.com/carla-simulator/carla/blob/master/PythonAPI/examples/generate_traffic.py) for an example.
# -------------------------------------- # --------------------------------------
- def_name: get_settings - def_name: get_settings
return: carla.WorldSettings return: carla.WorldSettings