Merge branch 'dev'

This commit is contained in:
bernat 2020-09-25 21:24:18 +02:00
commit c7b20769fb
194 changed files with 5488 additions and 2195 deletions

View File

@ -5,10 +5,10 @@ view the contribution guidelines, then fill out the blanks below.
Checklist:
- [ ] Your branch is up-to-date with the `master` branch and tested with latest changes
- [ ] Your branch is up-to-date with the `dev` branch and tested with latest changes
- [ ] Extended the README / documentation, if necessary
- [ ] Code compiles correctly
- [ ] All tests passing with `make check`
- [ ] All tests passing with `make check` (only Linux)
- [ ] If relevant, update CHANGELOG.md with your changes
-->

View File

@ -1,51 +1,76 @@
## CARLA 0.9.10
* Added PythonAPI `carla.Osm2Odr.convert()` function and `calra.Osm2OdrSettings` class to support Open Street Maps to OpenDRIVE conversions
* Upgraded to AD RSS v4.0.1 supporting unstructured scenes and pedestrians, and fixed spdlog to v1.7.0
* Fixed a bug in `spawn_npc_sumo` script computing not allowed routes for a given vehicle class
* Fixed a bug where `get_traffic_light` would always return `None`
* Added retrieval of bounding boxes for all the elements of the level
* Added deterministic mode for Traffic Manager
* Added support in Traffic Manager for dead-end roads
* Upgraded CARLA Docker image to Ubuntu 18.04
* Upgraded to AD RSS v4.1.0 supporting unstructured scenes and pedestrians, and fixed spdlog to v1.7.0
* Changed frozen behavior for traffic lights. It now affects to all traffic lights at the same time
* Added API function `freeze_all_traffic_lights` and `reset_group`
* Fixed recorder determinism problems
* Added function to stop the replayer
* Added Light ids
* Added vehicle light and street light data to recorder
* Added API function `add_angular_impulse()` to add angular impulse to any actor
* Fixed rain drop spawn issues when spawning camera sensors
* Fixed assets import pipeline
* Fixed Update.sh from failing when the root folder contains a space on it
* Fixed colors of lane markings when importing a map, they were reversed (white and yellow)
* Fixed missing include directive in file **WheelPhysicsControl.h**
* Fixed gravity measurement bug from IMU sensor
* All sensors are now multi-stream, that means that the same sensor can be listened from different clients
* Fixed point cloud of LiDAR. Now the points are given correctly in the sensor's coordinate system
* Fixed light intensity and camera parameters to match
* New Lidar sensor ('lidar.ray_cast_semantic') that returns the point cloud with information regarding to the object that have collided: incident angle, idx of collided actor and it semantic tag
* Added `opend3D.py`, a more friendly LiDAR visualizer
* Exposed matrix form of transformation to the client and Python API
* Added new pedestrian models
* API changes:
- Renamed `actor.set_velocity()` to `actor.set_target_velocity()`
- Renamed `actor.set_angular_velocity()` to `actor.set_target_velocity()`
- RGB cameras `exposure_mode` is now set to `histogram` by default
* API extensions:
- Added `carla.Osm2Odr.convert()` function and `carla.Osm2OdrSettings` class to support Open Street Maps to OpenDRIVE conversion
- Added `world.freeze_all_traffic_lights()` and `traffic_light.reset_group()`
- Added `client.stop_replayer()` to stop the replayer
- Added `world.get_vehicles_light_states()` to get all the car light states at once
- Added constant velocity mode (`actor.enable_constant_velocity()` / `actor.disable_constant_velocity()`)
- Added function `actor.add_angular_impulse()` to add angular impulse to any actor
- Added `actor.add_force()` and `actor.add_torque()`
- Added functions `transform.get_right_vector()` and `transform.get_up_vector()`
- Added command to set multiple car light states at once
- Added 4-matrix form of transformations
* Added new semantic segmentation tags: `RailTrack`, `GuardRail`, `TrafficLight`, `Static`, `Dynamic`, `Water` and `Terrain`
* Added fixed ids for street and building lights
* Added vehicle light and street light data to the recorder
* Improved the colliders and physics for all vehicles
* All sensors are now multi-stream, the same sensor can be listened from different clients
* New semantic LiDAR sensor (`lidar.ray_cast_semantic`)
* Added `open3D_lidar.py`, a more friendly LiDAR visualizer
* Added make command to download contributions as plugins (`make plugins`)
* Added PythonAPI command to set multiple car light states at once
* Added PythonAPI `carla.world.get_vehicles_light_states` to get all the car light states at once
* OpenDRIVE ingestion bugfixes
* Added a warning if the user tries to use the SpringArm exactly in the 'z' axis of the attached actor
* Improved the LiDAR and Radar sensors with a parallel implentation of the raycasting
* Added a warning when using SpringArm exactly in the 'z' axis of the attached actor
* Improved performance of raycast-based sensors through parallelization
* Added an approximation of the intensity of each point of the cloud in the LiDAR sensor
* Added Dynamic Vision Sensor (DVS) camera based on ESIM simulation http://rpg.ifi.uzh.ch/esim.html
* Improved LiDAR and radar to better match the shape of the vehicles
* Added support for additional TraCI clients in Sumo co-simulation
* Added script example to syncronize the gathering of sensor data in client
* Added API functions `get_right_vector` and `get_up_vector`
* Added script example to synchronize the gathering of sensor data in client
* Added default values and a warning message for lanes missing the width parameter in OpenDRIVE
* Added parameter to enable/disable pedestrian navigation in standalone mode
* Improved mesh split in standalone mode
* Fixed delay in the tcp communication from server to client, improving performance in synchronous mode in linux systems
* Fixed large RAM usage when loading polinomial geometry from OpenDRIVE
* Fixed collision issues when debug draw(debug.draw_line) is called
* Fixed Gyroscope sensor to properly give angular velocity readings in local frame
* Improved mesh partition in standalone mode
* Added Renderdoc plugin to the Unreal project
* Added configurable noise to Lidar sensor
* Replace deprectated `platform.dist()` with recommended `distro.linux_distribution()`
* Improved the performance on capture sensors.
* Added configurable noise to LiDAR sensor
* Replace deprecated `platform.dist()` with recommended `distro.linux_distribution()`
* Improved the performance of capture sensors
* Fixed the center of mass for vehicles
* Fixed a number of OpenDRIVE parsing bugs
* Fixed vehicles' bounding boxes, now they are automatic
* Fixed a map change error when Traffic Manager is in synchronous mode
* Fixes add entry issue for applying parameters more than once in Traffic Manager
* Fixes std::numeric_limits<float>::epsilon error in Traffic Manager
* Fixed memory leak on `manual_control.py` scripts (sensor listening was not stopped before destroying)
* Fixed a bug in `spawn_npc_sumo.py` script computing not allowed routes for a given vehicle class
* Fixed a bug where `get_traffic_light()` would always return `None`
* Fixed recorder determinism problems
* Fixed several untagged and mistagged objects
* Fixed rain drop spawn issues when spawning camera sensors
* Fixed semantic tags in the asset import pipeline
* Fixed `Update.sh` from failing when the root folder contains a space on it
* Fixed dynamic meshes not moving to the initial position when replaying
* Fixed colors of lane markings when importing a map, they were reversed (white and yellow)
* Fixed missing include directive in file `WheelPhysicsControl.h`
* Fixed gravity measurement bug from IMU sensor
* Fixed LiDARs point cloud reference frame
* Fixed light intensity and camera parameters to match
* Fixed and improved auto-exposure camera (`histogram` exposure mode)
* Fixed delay in the TCP communication from server to the client in synchronous mode for Linux
* Fixed large RAM usage when loading polynomial geometry from OpenDRIVE
* Fixed collision issues when `debug.draw_line()` is called
* Fixed gyroscope sensor to properly give angular velocity readings in the local frame
* Fixed minor typo in the introduction section of the documentation
* Fixed a bug at the local planner when changing the route, causing it to maintain the first part of the previous one. This was only relevant when using very large buffer sizes
## CARLA 0.9.9

View File

@ -94,7 +94,7 @@ class CarlaSimulation(object):
vehicle.set_transform(transform)
if velocity is not None:
vehicle.set_velocity(velocity)
vehicle.set_target_velocity(velocity)
if lights is not None:
vehicle.set_light_state(carla.VehicleLightState(lights))

View File

@ -276,7 +276,7 @@ if __name__ == '__main__':
metavar='P',
default=None,
type=int,
help='TCP port to liston to (default: 8813)')
help='TCP port to listen to (default: 8813)')
argparser.add_argument('--sumo-gui', action='store_true', help='run the gui version of sumo')
argparser.add_argument('--step-length',
default=0.05,

View File

@ -116,8 +116,8 @@ def main(args):
sumo_net = sumolib.net.readNet(net_file)
sumo_simulation = SumoSimulation(cfg_file,
args.step_length,
host=None,
port=None,
host=args.sumo_host,
port=args.sumo_port,
sumo_gui=args.sumo_gui,
client_order=args.client_order)
@ -218,6 +218,13 @@ if __name__ == '__main__':
default=2000,
type=int,
help='TCP port to listen to (default: 2000)')
argparser.add_argument('--sumo-host',
default=None,
help='IP of the sumo host server (default: None)')
argparser.add_argument('--sumo-port',
default=None,
type=int,
help='TCP port to listen to (default: None)')
argparser.add_argument('-n',
'--number-of-vehicles',
metavar='N',

View File

@ -2,14 +2,14 @@
This feature allows to record and reenact a previous simulation. All the events happened are registered in the [recorder file](ref_recorder_binary_file_format.md). There are some high-level queries to trace and study those events.
* [__Recording__](#recording)
* [__Simulation playback__](#simulation-playback)
* [Setting a time factor](#setting-a-time-factor)
* [__Recorded file__](#recorded-file)
* [__Queries__](#queries)
* [Collisions](#collisions)
* [Blocked actors](#blocked-actors)
* [__Sample Python scripts__](#sample-python-scripts)
* [__Recording__](#recording)
* [__Simulation playback__](#simulation-playback)
* [Setting a time factor](#setting-a-time-factor)
* [__Recorded file__](#recorded-file)
* [__Queries__](#queries)
* [Collisions](#collisions)
* [Blocked actors](#blocked-actors)
* [__Sample Python scripts__](#sample-python-scripts)
---
## Recording

View File

@ -2,15 +2,15 @@
There are few details to take into account at the time of configuring a simulation. This page covers the more important ones.
* [__Graphics quality__](#graphics-quality)
* Vulkan vs OpenGL
* Quality levels
* [__No-rendering mode__](#no-rendering-mode)
* [__Off-screen mode__](#off-screen-mode)
* Off-screen Vs no-rendering
* [__Running off-screen using a preferred GPU__](#running-off-screen-using-a-preferred-gpu)
* Docker: recommended approach
* Deprecated: emulate the virtual display
* [__Graphics quality__](#graphics-quality)
* [Vulkan vs OpenGL](#vulkan-vs-opengl)
* [Quality levels](#quality-levels)
* [__No-rendering mode__](#no-rendering-mode)
* [__Off-screen mode__](#off-screen-mode)
* [Off-screen Vs no-rendering](#off-screen-vs-no-rendering)
* [__Running off-screen using a preferred GPU__](#running-off-screen-using-a-preferred-gpu)
* [Docker - recommended approach](#docker-recommended-approach)
* [Deprecated - emulate the virtual display](#deprecated-emulate-the-virtual-display)
!!! Important
@ -76,15 +76,15 @@ world.apply_settings(settings)
```
And here is an example on how to disable and then enable rendering using the `config.py`.
```sh
cd PythonAPI/util && ./config.py --no-rendering
cd PythonAPI/util && python3 config.py --no-rendering
```
```sh
cd PythonAPI/util && ./config.py --rendering
cd PythonAPI/util && python3 config.py --rendering
```
The script `PythonAPI/examples/no_rendering_mode.py` will enable no-rendering mode, and use __Pygame__ to create an aerial view using simple graphics.
```sh
cd PythonAPI/examples && ./no_rendering_mode.py
cd PythonAPI/examples && python3 no_rendering_mode.py
```
!!! Warning
@ -117,16 +117,19 @@ DISPLAY= ./CarlaUE4.sh -opengl
---
## Running off-screen using a preferred GPU
### Docker: recommended approach
### Docker - recommended approach
The best way to run a headless CARLA and select the GPU is to [__run CARLA in a Docker__](build_docker.md).
This section contains an alternative tutorial, but this method is deprecated and performance is much worse. It is here only for those who Docker is not an option.
### Deprecated - emulate the virtual display
<details>
<summary><h4 style="display:inline">
Deprecated: emulate the virtual display
</h4></summary>
<summary>
Show deprecated tutorial on how to emulate the virtual display
</summary>
!!! Warning
This tutorial is deprecated. To run headless CARLA, please [__run CARLA in a Docker__](build_docker.md).

View File

@ -2,13 +2,13 @@
CARLA integrates the [C++ Library for Responsibility Sensitive Safety](https://github.com/intel/ad-rss-lib) in the client library. This feature allows users to investigate behaviours of RSS without having to implement anything. CARLA will take care of providing the input, and applying the output to the AD systems on the fly.
* [__Overview__](#overview)
* [__Compilation__](#compilation)
* [Dependencies](#dependencies)
* [Build](#build)
* [__Overview__](#overview)
* [__Compilation__](#compilation)
* [Dependencies](#dependencies)
* [Build](#build)
* [__Current state__](#current-state)
* [RssSensor](#rsssensor)
* [RssRestrictor](#rssrestrictor)
* [RssSensor](#rsssensor)
* [RssRestrictor](#rssrestrictor)
!!! Important
This feature is a work in progress. Right now, it is only available for the Linux build.
@ -56,7 +56,7 @@ There are additional prerequisites required for building RSS and its dependencie
Dependencies provided by Ubunutu (>= 16.04).
```sh
sudo apt-get install libgtest-dev libpython-dev libpugixml-dev libproj-dev libtbb-dev
sudo apt-get install libgtest-dev libpython-dev libpugixml-dev libtbb-dev
```
The dependencies are built using [colcon](https://colcon.readthedocs.io/en/released/user/installation.html), so it has to be installed.
@ -67,8 +67,7 @@ pip3 install --user -U colcon-common-extensions
There are some additional dependencies for the Python bindings.
```sh
sudo apt-get install castxml
pip install --user pygccxml
pip install --user https://bitbucket.org/ompl/pyplusplus/get/1.8.1.zip
pip3 install --user pygccxml pyplusplus
```
### Build

View File

@ -27,13 +27,13 @@ Run a CARLA simulation with __Town04__.
cd ~/carla
./CarlaUE4.sh
cd PythonAPI/util
python config.py --map Town04
python3 config.py --map Town04
```
Then, run the SUMO co-simulation example.
```sh
cd ~/carla/Co-Simulation/Sumo
python run_synchronization.py examples/Town04.sumocfg --sumo-gui
python3 run_synchronization.py examples/Town04.sumocfg --sumo-gui
```
!!! Important
@ -83,7 +83,7 @@ Once a simulation is ready and saved as a `.sumocfg`, it is ready to run. There
* __`--tls-manager`__ *(default: none)* — Choose which simulator should manage the traffic lights. The other will update those accordingly. The options are `carla`, `sumo`, and `none`. If `none` is chosen, traffic lights will not be synchronized. Each vehicle would only obey the traffic lights in the simulator that spawn it.
```sh
python run_synchronization.py <SUMOCFG FILE> --tls-manager carla --sumo-gui
python3 run_synchronization.py <SUMOCFG FILE> --tls-manager carla --sumo-gui
```
!!! Warning
@ -114,7 +114,7 @@ As the script runs a synchronous simulation, and spawns vehicles in it, the argu
# Spawn 10 vehicles, that will be managed by SUMO instead of Traffic Manager.
# CARLA in charge of traffic lights.
# Open a window for SUMO visualization.
python spawn_sumo_npc.py -n 10 --tls-manager carla --sumo-gui
python3 spawn_sumo_npc.py -n 10 --tls-manager carla --sumo-gui
```
---

View File

@ -2,15 +2,15 @@
This section deals with two fundamental concepts in CARLA. Their configuration defines how does time go by in the simulation, and how does the server make the simulation move forward.
* [__Simulation time-step__](#simulation-time-step)
* Variable time-step
* Fixed time-step
* Tips when recording the simulation
* Time-step limitations
* [__Client-server synchrony__](#client-server-synchrony)
* Setting synchronous mode
* Using synchronous mode
* [__Possible configurations__](#possible-configurations)
* [__Simulation time-step__](#simulation-time-step)
* [Variable time-step](#variable-time-step)
* [Fixed time-step](#fixed-time-step)
* [Tips when recording the simulation](#tips-when-recording-the-simulation)
* [Time-step limitations](#time-step-limitations)
* [__Client-server synchrony__](#client-server-synchrony)
* [Setting synchronous mode](#setting-synchronous-mode)
* [Using synchronous mode](#using-synchronous-mode)
* [__Possible configurations__](#possible-configurations)
---
## Simulation time-step
@ -35,7 +35,7 @@ world.apply_settings(settings)
```
`PythonAPI/util/config.py` sets the time-step using an argument. Zero equals variable time-step.
```sh
cd PythonAPI/util && ./config.py --delta-seconds 0
cd PythonAPI/util && python3 config.py --delta-seconds 0
```
### Fixed time-step
@ -52,7 +52,7 @@ world.apply_settings(settings)
This can also be set using the provided script `PythonAPI/util/config.py`.
```sh
cd PythonAPI/util && ./config.py --delta-seconds 0.05
cd PythonAPI/util && python3 config.py --delta-seconds 0.05
```
### Tips when recording the simulation
@ -74,7 +74,7 @@ CARLA has a [recorder feature](adv_recorder.md) that allows a simulation to be r
Physics must be computed within very low time steps to be precise. The more time goes by, the more variables and chaos come to place, and the more defective the simulation will be.
CARLA uses up to 6 substeps to compute physics in every step, each with a maximum delta time of 0.016667s.
To know how many of these are needed, the time-step used gets divided by the maximum delta time a substep can use `number_of_substeps = time_step/0.016667`. Being these a maximum of 6, `6*0.016667 = 0.1`. If the time-step is greater than `0.1``, there will not be enough physical substeps. Physics will not be in synchrony with the delta time.
To know how many of these are needed, the time-step used gets divided by the maximum delta time a substep can use `number_of_substeps = time_step/0.016667`. Being these a maximum of 6, `6*0.016667 = 0.1`. If the time-step is greater than `0.1`, there will not be enough physical substeps. Physics will not be in synchrony with the delta time.
!!! Warning
__Do not use a time-step greater than 0.1s.__<br>
@ -101,7 +101,7 @@ world.apply_settings(settings)
To disable synchronous mode just set the variable to false or use the script `PythonAPI/util/config.py`.
```sh
cd PythonAPI/util && ./config.py --no-sync # Disables synchronous mode
cd PythonAPI/util && python3 config.py --no-sync # Disables synchronous mode
```
Synchronous mode cannot be enabled using the script, only disabled. Enabling the synchronous mode makes the server wait for a client tick. Using this script, the user cannot send ticks when desired.

View File

@ -1,9 +1,9 @@
# Running CARLA in a Docker
* [__Docker installation__](#docker-installation)
* Docker CE
* NVIDIA-Docker2
* [__Running CARLA container__](#running-carla-container)
* [__Docker installation__](#docker-installation)
* [Docker CE](#docker-ce)
* [NVIDIA-Docker2](#nvidia-docker2)
* [__Running CARLA container__](#running-carla-container)
This tutorial is designed for:

View File

@ -104,6 +104,63 @@ make PythonAPI.docs
</details>
<!-- ======================================================================= -->
<details>
<summary><h5 style="display:inline">
Cannot run example scripts or "RuntimeError: rpc::rpc_error during call in function version"
</h5></summary>
![faq_rpc_error](img/faq_rpc_error.jpg)
If running a script returns an output similar to this, there is a problem with the `.egg` file in the PythonAPI.
First of all, open `<root_carla>/PythonAPI/carla/dist`. There should be an `.egg` file for the corresponding CARLA and Python version you are using (similar to `carla-0.X.X-pyX.X-linux-x86_64.egg`). Make sure the file matches the Python version you are using. To check your Python version use the following command.
```sh
python3 --version # CARLA no longer provides support for Python2, so we are dismissing it here
```
If either the file is missing or you think it could be corrupted, try rebuilding again.
```sh
make clean
make PythonAPI
make launch
```
Now try one of the example scripts again.
```sh
cd PythonAPI/examples
python3 dynamic_weather.py
```
If the error persists, the problem is probably related with your PythonPATH. These scripts automatically look for the `.egg` file associated with the build, so maybe there is any other `.egg` file in your PythonPATH interfering with the process. Show the content of the PythonPATH with the following command.
```sh
echo $PYTHONPATH
```
Look up in the output for other instances of `.egg` files in a route similar to `PythonAPI/carla/dist`, and get rid of these. They probably belong to other instances of CARLA installations. For example, if you also installed CARLA via *apt-get*, you can remove it with the following command, and the PythonPATH will be cleaned too.
```sh
sudo apt-get purge carla-simulator
```
Ultimately there is the option to add the `.egg` file of your build to the PythonPATH using the `~/.bashrc`. This is not the recommended way. It would be better to have a clear PythonPATH and simply add the path to the necessary `.egg` files in the scripts.
First, open the `~/.bashrc`.
```sh
gedit ~/.bashrc
```
Add the following lines to the `~/.bashrc`. These store the path to the build `.egg` file, so that Python can automatically find it. Save the file, and reset the terminal for changes to be effective.
```
export PYTHONPATH=$PYTHONPATH:"${CARLA_ROOT}/PythonAPI/carla/dist/$(ls ${CARLA_ROOT}/PythonAPI/carla/dist | grep py3.)"
export PYTHONPATH=$PYTHONPATH:${CARLA_ROOT}/PythonAPI/carla
```
After cleaning the PythonPATH or adding the path to the build `.egg` file, all the example scripts should work properly.
</details>
---
## Windows build
@ -238,7 +295,7 @@ Go to `Edit/Editor Preferences/Performance` in the editor preferences, and disab
Some scripts have requirements. These are listed in files named __Requirements.txt__, in the same path as the script itself. Be sure to check these in order to run the script. The majority of them can be installed with a simple `pip` command.
Sometimes on Windows, scripts cannot run with just `> script_name.py`. Try adding `> python script_name.py`, and make sure to be in the right directory.
Sometimes on Windows, scripts cannot run with just `> script_name.py`. Try adding `> python3 script_name.py`, and make sure to be in the right directory.
</details>

View File

@ -1,25 +1,18 @@
# Linux build
* [__Linux build command summary__](#linux-build-command-summary)
* [__Requirements__](#requirements)
* [System specifics](#system-specifics)
* [Dependencies](#dependencies)
* [__GitHub__](#github)
* [__Unreal Engine__](#unreal-engine)
* [__CARLA build__](#carla-build)
* [Clone repository](#clone-repository)
* [Get assets](#get-assets)
* [Set the environment variable](#set-the-environment-variable)
* [make CARLA](#make-carla)
* [__Linux build command summary__](#linux-build-command-summary)
* [__Requirements__](#requirements)
* [System specifics](#system-specifics)
* [Dependencies](#dependencies)
* [__GitHub__](#github)
* [__Unreal Engine__](#unreal-engine)
* [__CARLA build__](#carla-build)
* [Clone repository](#clone-repository)
* [Get assets](#get-assets)
* [Set the environment variable](#set-the-environment-variable)
* [make CARLA](#make-carla)
The build process can be quite long and tedious. The **[F.A.Q.](build_faq.md)** section contains the most common issues and solutions that appear during the installation. However, the CARLA forum is open for anybody to post unexpected issues, doubts or suggestions. There is a specific section for installation issues on Linux. Feel free to login and become part of the community.
<div class="build-buttons">
<p>
<a href="https://forum.carla.org/" target="_blank" class="btn btn-neutral" title="Go to the CARLA forum">
CARLA forum</a>
</p>
</div>
The build process can be quite long and tedious. The **[F.A.Q.](build_faq.md)** page offers solution for the most common complications. Alternatively, use the [CARLA forum](https://forum.carla.org/c/installation-issues/linux) to post any unexpected issues that may occur.
---
## Linux build command summary
@ -28,9 +21,10 @@ CARLA forum</a>
<summary> Show command lines to build on Linux</summary>
```sh
# Make sure to meet the minimum requirements and read the documentation to understand each step.
# Make sure to meet the minimum requirements
# Read the complete documentation to understand each step
# Install dependencies.
# Install dependencies
sudo apt-get update &&
sudo apt-get install wget software-properties-common &&
sudo add-apt-repository ppa:ubuntu-toolchain-r/test &&
@ -38,57 +32,67 @@ wget -O - https://apt.llvm.org/llvm-snapshot.gpg.key|sudo apt-key add - &&
sudo apt-add-repository "deb http://apt.llvm.org/$(lsb_release -c --short)/ llvm-toolchain-$(lsb_release -c --short)-8 main" &&
sudo apt-get update
# Additional dependencies for Ubuntu 18.04.
# Additional dependencies for Ubuntu 18.04
sudo apt-get install build-essential clang-8 lld-8 g++-7 cmake ninja-build libvulkan1 python python-pip python-dev python3-dev python3-pip libpng-dev libtiff5-dev libjpeg-dev tzdata sed curl unzip autoconf libtool rsync libxml2-dev libxerces-c-dev &&
pip2 install --user setuptools &&
pip3 install --user -Iv setuptools==47.3.1
# Additional dependencies for previous Ubuntu versions.
# Additional dependencies for previous Ubuntu versions
sudo apt-get install build-essential clang-8 lld-8 g++-7 cmake ninja-build libvulkan1 python python-pip python-dev python3-dev python3-pip libpng16-dev libtiff5-dev libjpeg-dev tzdata sed curl unzip autoconf libtool rsync libxml2-dev libxerces-c-dev &&
pip2 install --user setuptools &&
pip3 install --user -Iv setuptools==47.3.1 &&
pip2 install --user distro &&
pip3 install --user distro
# Change default clang version.
# Change default clang version
sudo update-alternatives --install /usr/bin/clang++ clang++ /usr/lib/llvm-8/bin/clang++ 180 &&
sudo update-alternatives --install /usr/bin/clang clang /usr/lib/llvm-8/bin/clang 180
# Get a GitHub and a UE account, and link both.
# Install git.
# Get a GitHub and a UE account, and link both
# Install git
# Download Unreal Engine 4.24.
# Download Unreal Engine 4.24
git clone --depth=1 -b 4.24 https://github.com/EpicGames/UnrealEngine.git ~/UnrealEngine_4.24
cd ~/UnrealEngine_4.24
# Download and install the UE patch
wget https://carla-releases.s3.eu-west-3.amazonaws.com/Linux/UE_Patch/430667-13636743-patch.txt ~/430667-13636743-patch.txt
patch --strip=4 < ~/430667-13636743-patch.txt
wget https://carla-releases.s3.eu-west-3.amazonaws.com/Linux/UE_Patch/430667-13636743-patch.txt 430667-13636743-patch.txt
patch --strip=4 < 430667-13636743-patch.txt
# Build UE
./Setup.sh && ./GenerateProjectFiles.sh && make
# Open the UE Editor to check everything works properly.
# Open the UE Editor to check everything works properly
cd ~/UnrealEngine_4.24/Engine/Binaries/Linux && ./UE4Editor
# Clone the CARLA repository.
# Clone the CARLA repository
git clone https://github.com/carla-simulator/carla
# Get the CARLA assets.
# Get the CARLA assets
cd ~/carla
./Update.sh
# Set the environment variable.
# Set the environment variable
export UE4_ROOT=~/UnrealEngine_4.24
# make the CARLA server and the CARLA client.
make launch
# make the CARLA client and the CARLA server
make PythonAPI
make launch
# Press play in the Editor to initialize the server, and run an example script to test CARLA.
# Press play in the Editor to initialize the server
# Run example scripts to test CARLA
# Terminal A
cd PythonAPI/examples
python3 spawn_npc.py
# Terminal B
cd PythonAPI/examples
python3 spawn_npc.py # Support for Python2 was provided until 0.9.10 (not included)
python3 dynamic_weather.py # Support for Python2 was provided until 0.9.10 (not included)
# Optionally, to compile the PythonAPI for Python2, run the following command in the root CARLA directory
make PythonAPI ARGS="--python-version=2"
```
</details>
---
@ -96,8 +100,8 @@ python3 spawn_npc.py
### System specifics
* __Ubuntu 18.04.__ CARLA provides support for previous Ubuntu versions up to 16.04. **However** proper compilers are needed for UE to work properly. The required dependencies for both Ubuntu 18.04 and previous versions are listed below. Make sure to install the ones corresponding to the system.
* __30GB disk space.__ Installing all the software needed and CARLA itself will require quite a lot of space, especially Unreal Engine. Make sure to have around 30/50GB of free disk space.
* __Ubuntu 18.04.__ CARLA provides support for previous Ubuntu versions up to 16.04. **However** proper compilers are needed for UE to work properly. Dependencies for Ubuntu 18.04 and previous versions are listed separatedly below. Make sure to install the ones corresponding to your system.
* __30GB disk space.__ The complete build will require quite a lot of space, especially Unreal Engine. Make sure to have around 30/50GB of free disk space.
* __An adequate GPU.__ CARLA aims for realistic simulations, so the server needs at least a 4GB GPU. A dedicated GPU is highly recommended for machine learning.
* __Two TCP ports and good internet connection.__ 2000 and 2001 by default. Be sure neither the firewall nor any other application block these.
@ -115,8 +119,8 @@ sudo apt-add-repository "deb http://apt.llvm.org/xenial/ llvm-toolchain-xenial-8
sudo apt-get update
```
!!! Important
The following commands differ depending on the Ubuntu version. While the only change is `libpng16-dev` becoming `libpng-dev`, the full set of commands is here twice to ease the copy.
!!! Warning
The following commands depend on your Ubuntu version. Make sure to choose accordingly.
__Ubuntu 18.04__.
```sh
@ -135,7 +139,8 @@ pip2 install --user distro &&
pip3 install --user distro
```
To avoid compatibility issues between Unreal Engine and the CARLA dependencies, it is recommended to use the same compiler version and C++ runtime library to compile everything. The CARLA team uses clang-8 and LLVM's libc++. Change the default clang version to compile Unreal Engine and the CARLA dependencies.
__All Ubuntu systems__.
To avoid compatibility issues between Unreal Engine and the CARLA dependencies, use the same compiler version and C++ runtime library to compile everything. The CARLA team uses clang-8 and LLVM's libc++. Change the default clang version to compile Unreal Engine and the CARLA dependencies.
```sh
sudo update-alternatives --install /usr/bin/clang++ clang++ /usr/lib/llvm-8/bin/clang++ 180 &&
@ -145,9 +150,13 @@ sudo update-alternatives --install /usr/bin/clang clang /usr/lib/llvm-8/bin/clan
---
## GitHub
A [GitHub](https://github.com/) account will be needed, as CARLA content is organized in different repositories in there. Also, [git](https://git-scm.com/book/en/v2/Getting-Started-Installing-Git) will be used in this build guide when facilitating commands to be run in terminal.
__1.__ Create a [GitHub](https://github.com/) account. CARLA is organized in different GitHub repositories, so an account will be needed to clone said repositories.
In order to access the Unreal Engine repositories, which are set to private, create an [Unreal Engine](https://www.unrealengine.com/en-US/feed) account and connect it to a GitHub account. To do so, there is a section in Unreal Engine's profile settings under the name of __Connected accounts__. [Here](https://www.unrealengine.com/en-US/blog/updated-authentication-process-for-connecting-epic-github-accounts) is a brief explanation just in case.
__2.__ Install [git](https://git-scm.com/book/en/v2/Getting-Started-Installing-Git) to manage the repositories via terminal.
__3.__ Create an [Unreal Engine](https://www.unrealengine.com/en-US/feed) account to access the Unreal Engine repositories, which are set to private.
__4.__ Connect both your GitHub and Unreal Engine accounts. Go to your personal settings in there is a section in [Unreal Engine](https://www.unrealengine.com/en-US/)'s website. Click on `Connections > Accounts`, and link both accounts. [Here](https://www.unrealengine.com/en-US/blog/updated-authentication-process-for-connecting-epic-github-accounts) is a brief explanation just in case.
!!! Warning
New Unreal Engine accounts need activation. After creating the account, a verification mail will be sent. Check it out, or the UE repository will be shown as non-existent in the following steps.
@ -155,40 +164,41 @@ In order to access the Unreal Engine repositories, which are set to private, cre
---
## Unreal Engine
The current version of CARLA runs on __Unreal Engine 4.24__ only. The path is irrelevant, but for the sake of this tutorial, installation will be done under `~/UnrealEngine_4.24`. If the path chosen differs, remember to change it accordingly when running the commands on terminal.
The current version of CARLA runs on __Unreal Engine 4.24__ only. In this guide, the installation will be done in `~/UnrealEngine_4.24`, but the path can be changed. If your path is different, change the following commands accordingly.
!!! Note
Alternatively, there is this [guide](https://docs.unrealengine.com/en-US/Platforms/Linux/BeginnerLinuxDeveloper/SettingUpAnUnrealWorkflow/index.html) to build UE on Linux. When consulting it, remember that CARLA will need the __4.24 release__, not the latest.
Alternatively to this section, there is another [guide](https://docs.unrealengine.com/en-US/Platforms/Linux/BeginnerLinuxDeveloper/SettingUpAnUnrealWorkflow/index.html) to build UE on Linux. When consulting it, remember that CARLA will need the __4.24 release__, not the latest.
Clone the content for Unreal Engine 4.24 in a local computer.
__1.__ Clone the content for Unreal Engine 4.24 in your local computer.
```sh
git clone --depth=1 -b 4.24 https://github.com/EpicGames/UnrealEngine.git ~/UnrealEngine_4.24
```
Get into said folder. Remember, this is the path where UE4.24 has been cloned.
__2.__ Get into the directory where UE4.24 has been cloned.
```sh
cd ~/UnrealEngine_4.24
```
Get a patch for Unreal Engine. The patch fixes some Vulkan visualization issues that may occur when changing the map. Download and install it with the following commands.
__3.__ Download a patch for Unreal Engine. This patch fixes some Vulkan visualization issues that may occur when changing the map. Download and install it with the following commands.
```sh
wget https://carla-releases.s3.eu-west-3.amazonaws.com/Linux/UE_Patch/430667-13636743-patch.txt ~/430667-13636743-patch.txt
patch --strip=4 < ~/430667-13636743-patch.txt
wget https://carla-releases.s3.eu-west-3.amazonaws.com/Linux/UE_Patch/430667-13636743-patch.txt 430667-13636743-patch.txt
patch --strip=4 < 430667-13636743-patch.txt
```
Make the build.
!!! Warning
If UE has already been built, install the patch, and make the build again.
__4.__ Make the build. This may take an hour or two depending on your system.
```sh
./Setup.sh && ./GenerateProjectFiles.sh && make
```
!!! Warning
If UE has already been built, install the patch and make the build again.
Unreal Engine should be installed in the system. Run `Engine/Binaries/Linux/UE4Editor.sh` to open the Editor and check it out.
__5.__ Open the Editor to check that UE has been properly installed.
```sh
cd ~/UnrealEngine_4.24/Engine/Binaries/Linux && ./UE4Editor
```
In case something went wrong, it is related with Unreal Engine There is not much CARLA can do about it. However, the [build documentation](https://github.com/EpicGames/UnrealEngine/blob/release/Engine/Build/BatchFiles/Linux/README.md) provided by Unreal Engine may be helpful.
Any issues this far are related with Unreal Engine. There is not much CARLA can do about it. However, the [build documentation](https://github.com/EpicGames/UnrealEngine/blob/release/Engine/Build/BatchFiles/Linux/README.md) provided by Unreal Engine may be helpful.
---
## CARLA build
@ -210,31 +220,33 @@ The system should be ready to start building CARLA. Just for clarity, a brief su
<span class="icon icon-github"></span> CARLA repository</a>
</p>
</div>
The official repository of the project. Either download and extract it or clone it using the following command line.
The official repository of the project. Either download and extract it, or clone the repository with the following command line.
```sh
git clone https://github.com/carla-simulator/carla
```
Now the latest content for the project, known as `master` branch in the repository, has been copied in local.
Now the latest state of the simulator, known as `master` branch in the repository, has been copied in local. Here is brief introduction to the most relevant branches of the repository. Remember that you can change and check your branches with the command `git branch`.
* __`master` branch__ — Latest fixes and features that have been tested. These will be featured in the next CARLA release.
* __`dev` branch__ — Latest fixes and features still in development and testing. This branch will be merged with `master` when the time for a new release comes.
* __`stable` branch__ — Latest version of CARLA tagged as stable. Previous CARLA versions also have their own branch.
!!! Note
The `master` branch contains the latest fixes and features. Stable code is inside the `stable` and previous CARLA versions have their own branch. Always remember to check the current branch in git with the command `git branch`.
### Get assets
Only the assets package is yet to be donwloaded. These are stored separately to make the repository a bit lighter. CARLA cannot be built without the assets. There is a script that downloads and extracts the latest content version. The package is >3GB, so downloading it may take some time.
Download the assets, as they are necessary to run CARLA. These are stored in a separated package to reduce the size of the build. A script downloads and extracts the latest stable assets automatically. The package is >3GB, so the download may take some time.
Get into the root carla folder. The path should correspond with the repository just cloned:
__1.__ Get into your root carla directory. The path should correspond with the repository just cloned.
```sh
cd ~/carla
```
Run the script to get the assets.
__2.__ Run the script to get the assets.
```sh
./Update.sh
```
!!! Important
To get the assets currently in development, visit [Update CARLA](build_update.md#get-development-assets) and read __Get development assets__.
To download the assets currently in development, visit [Update CARLA](build_update.md#get-development-assets) and read __Get development assets__.
### Set the environment variable
@ -245,30 +257,60 @@ This is necessary for CARLA to find the Unreal Engine 4.24 installation folder.
export UE4_ROOT=~/UnrealEngine_4.24
```
The variable should be added to `~/.bashrc` or `~/.profile` to be set persistently session-wide. Otherwise, it will only be accessible from the current shell.
The variable should be added to `~/.bashrc` or `~/.profile` to be set persistently session-wide. Otherwise, it will only be accessible from the current shell. To do this, follow these steps.
__1.__ Open `~/.bashrc`.
```sh
gedit ~/.bashrc
```
__2.__ Write the environment variable in the `~/.bashrc` file: `export UE4_ROOT=~/UnrealEngine_4.24`
__3.__ Save the file and reset the terminal.
### make CARLA
The last step is to finally build CARLA. There are different `make` commands to build the different modules. All of them run in the root CARLA folder.
!!! Warning
Make sure to run `make launch` to prepare the server and `make PythonAPI` for the client.
Make sure to run `make PythonAPI` to prepare the client and `make launch` for the server.
Alternatively `make LibCarla` will prepare the CARLA library to be imported anywhere.
* __make PythonAPI__ compiles the API client, necessary to grant control over the simulation. It is only needed the first time. Remember to run it again when updating CARLA. Scripts will be able to run after this command is executed.
```sh
make PythonAPI
```
* __make launch__ compiles the server simulator and launches Unreal Engine. Press **Play** to start the spectator view and close the editor window to exit. Camera can be moved with `WASD` keys and rotated by clicking the scene while moving the mouse around.
```sh
make launch
```
The project may ask to build other instances such as `UE4Editor-Carla.dll` the first time. Agree in order to open the project. During the first launch, the editor may show warnings regarding shaders and mesh distance fields. These take some time to be loaded and the city will not show properly until then.
* __make PythonAPI__ compiles the API client, necessary to grant control over the simulation. It is only needed the first time. Remember to run it again when updating CARLA. Scripts will be able to run after this command is executed. The following example will spawn some life into the town.
Finally, let's test the simulator. Inside `PythonAPI/examples` and `PythonAPI/util` there are some example scripts that may be especially useful for starters. The following commands will spawn some life into the town, and create a weather cycle. Each script should be run in one terminal
```sh
make PythonAPI && cd PythonAPI/examples && python3 spawn_npc.py
# Support for Python2 was provided until 0.9.10 (not included)
# Terminal A
cd PythonAPI/examples
python3 spawn_npc.py
# Terminal B
cd PythonAPI/examples
python3 dynamic_weather.py
```
!!! Important
If the simulation is running at very low FPS rates, go to `Edit/Editor preferences/Performance` in the UE editor and disable __Use less CPU when in background__.
Optionally, to compile the PythonAPI for Python2, run the following command in the root CARLA directory.
```sh
make PythonAPI ARGS="--python-version=2"
```
Now CARLA is ready to go. Here is a brief summary of the most useful `make` commands available.
<table class ="defTable">
@ -298,21 +340,25 @@ Now CARLA is ready to go. Here is a brief summary of the most useful `make` comm
</tr>
<tr>
<td><code>make rebuild</code></td>
<td>make clean and make launch both in one command.</td>
<td><code>make clean</code> and <code>make launch</code> both in one command.</td>
</tbody>
</table>
---
<br>
Keep reading this section to learn how to update the build or take some first steps in CARLA.
Read the **[F.A.Q.](build_faq.md)** page or post in the [CARLA forum](https://forum.carla.org/c/installation-issues/linux) for any issues regarding this guide.
Some recommendations after finishing the build. Learn how to update the CARLA build or take your first steps in the simulation, and learn some core concepts.
<div class="build-buttons">
<p>
<a href="../core_concepts" target="_blank" class="btn btn-neutral" title="Learn about CARLA core concepts">
Go to __First steps__</a>
</p>
<p>
<a href="../build_update" target="_blank" class="btn btn-neutral" title="Learn how to update the build">
Update CARLA</a>
</p>
<p>
<a href="../core_concepts" target="_blank" class="btn btn-neutral" title="Learn about CARLA core concepts">
First steps</a>
</p>
</div>

View File

@ -1,13 +1,13 @@
# Update CARLA
* [__Update commands summary__](#update-commands-summary)
* [__Get the lastest binary release__](#get-latest-binary-release)
* [__Update Linux and Windows build__](#update-linux-and-windows-build)
* Clean the build
* Pull from origin
* Download the assets
* Launch the server
* [__Get development assets__](#get-development-assets)
* [__Update commands summary__](#update-commands-summary)
* [__Get the lastest binary release__](#get-latest-binary-release)
* [__Update Linux and Windows build__](#update-linux-and-windows-build)
* [Clean the build](#clean-the-build)
* [Pull from origin](#pull-from-origin)
* [Download the assets](#download-the-assets)
* [Launch the server](#launch-the-server)
* [__Get development assets__](#get-development-assets)
To post unexpected issues, doubts or suggestions, feel free to login in the CARLA forum.

View File

@ -1,38 +1,33 @@
# Windows build
* [__Windows build command summary__](#windows-build-command-summary)
* [__Requirements__](#requirements)
* System specifics
* [__Necessary software__](#necessary-software)
* Minor installations: CMake, git, make, Python3 x64
* Visual Studio 2017
* Unreal Engine 4.24
* [__CARLA build__](#carla-build)
* Clone repository
* Get assets
* Set the environment variable
* make CARLA
* [__Windows build command summary__](#windows-build-command-summary)
* [__Requirements__](#requirements)
* [System specifics](#system-specifics)
* [__Necessary software__](#necessary-software)
* [Minor installations (CMake, git, make, Python3 x64)](#minor-installations)
* [Visual Studio 2017](#visual-studio-2017)
* [Unreal Engine (4.24)](#unreal-engine)
* [__CARLA build__](#carla-build)
* [Clone repository](#clone-repository)
* [Get assets](#get-assets)
* [Set the environment variable](#set-the-environment-variable)
* [make CARLA](#make-carla)
The build process can be quite long and tedious. The **[F.A.Q.](build_faq.md)** section contains the most common issues and solutions that appear during the installation. However, the CARLA forum is open for anybody to post unexpected issues, doubts or suggestions. There is a specific section for installation issues on Linux. Feel free to login and become part of the community.
<div class="build-buttons">
<p>
<a href="https://forum.carla.org/" target="_blank" class="btn btn-neutral" title="Go to the CARLA forum">
CARLA forum</a>
</p>
</div>
The build process can be quite long and tedious. The **[F.A.Q.](build_faq.md)** page offers solution for the most common complications. Alternatively, use the [CARLA forum](https://forum.carla.org/c/installation-issues/linux) to post any unexpected issues that may occur.
---
## Windows build command summary
<details>
<summary> Show command lines to build on Windows</summary>
<br>
To execute the <code>make</code> commands below, you <b>must</b> use the Visual Studio 2017 native console x64 <b>with</b> administrator rights, otherwise you may be getting permission errors.
!!! Important
To execute the ```make``` commands below, you **must** use the Visual Studio 2017 native console x64 **with** administrator rights, otherwise you may be getting permission errors.
```sh
# Make sure to meet the minimum requirements.
# Make sure to meet the minimum requirements
# Necessary software:
# CMake
@ -40,19 +35,28 @@ CARLA forum</a>
# Make
# Python3 x64
# Unreal Engine 4.24
# Visual Studio 2017 with Windows 8.1 SDK and x64 Visual C++ Toolset.
# Visual Studio 2017 with Windows 8.1 SDK and x64 Visual C++ Toolset
# Set environment variables for the software
# Clone the CARLA repository
git clone https://github.com/carla-simulator/carla
# make the CARLA server and the CARLA client
make launch
# make the CARLA client and the CARLA server
make PythonAPI
make launch
# Press play in the Editor to initialize the server
# Run example scripts to test CARLA
# Terminal A
cd PythonAPI/examples
python3 spawn_npc.py
# Terminal B
cd PythonAPI/examples
python3 dynamic_weather.py
# The PythonAPI will be built based on the installed Python version
# The docs will use Python3, as support for Python2 was provided until 0.9.10 (not included)
# Press play in the Editor to initialize the server, and run an example script to test CARLA.
cd PythonAPI/Examples && python3 spawn_npc.py
```
</details>
@ -89,7 +93,7 @@ Get the 2017 version from [here](https://developerinsider.co/download-visual-stu
!!! Important
Other Visual Studio versions may cause conflict. Even if these have been uninstalled, some registers may persist. To completely clean Visual Studio from the computer, go to `Program Files (x86)\Microsoft Visual Studio\Installer\resources\app\layout` and run `.\InstallCleanup.exe -full`
### Unreal Engine 4.24
### Unreal Engine
Go to [Unreal Engine](https://www.unrealengine.com/download) and download the _Epic Games Launcher_. In `Engine versions/Library`, download __Unreal Engine 4.24.x__. Make sure to run it in order to check that everything was properly installed.
@ -137,25 +141,40 @@ __2. On the `Advanced` panel__ open `Environment Variables...`.
__3. Click `New...`__ to create the variable.
__4. Name the variable as `UE4_ROOT`__ and choose the path to the installation folder of the desire UE4 installation.
### make CARLA
The last step is to finally build CARLA. There are different `make` commands to build the different modules. All of them run in the root CARLA folder.
!!! Warning
Make sure to run `make launch` to prepare the server and `make PythonAPI` for the client.
Make sure to run `make PythonAPI` to prepare the client and `make launch` for the server.
Alternatively `make LibCarla` will prepare the CARLA library to be imported anywhere.
* __make PythonAPI__ compiles the API client, necessary to grant control over the simulation. It is only needed the first time. Remember to run it again when updating CARLA. Scripts will be able to run after this command is executed.
```sh
make PythonAPI
```
* __make launch__ compiles the server simulator and launches Unreal Engine. Press **Play** to start the spectator view and close the editor window to exit. Camera can be moved with `WASD` keys and rotated by clicking the scene while moving the mouse around.
```sh
make launch
```
The project may ask to build other instances such as `UE4Editor-Carla.dll` the first time. Agree in order to open the project. During the first launch, the editor may show warnings regarding shaders and mesh distance fields. These take some time to be loaded and the city will not show properly until then.
* __make PythonAPI__ compiles the API client, necessary to grant control over the simulation. It is only needed the first time. Remember to run it again when updating CARLA. Scripts will be able to run after this command is executed. The following example will spawn some life into the town.
Finally, let's test the simulator. Inside `PythonAPI/examples` and `PythonAPI/util` there are some example scripts that may be especially useful for starters. The following commands will spawn some life into the town, and create a weather cycle. Each script should be run in one terminal
```sh
make PythonAPI && cd PythonAPI/examples && python3 spawn_npc.py
# Terminal A
cd PythonAPI/examples
python3 spawn_npc.py
# Terminal B
cd PythonAPI/examples
python3 dynamic_weather.py
# The PythonAPI will be built based on the installed Python version
# The docs will use Python3, as support for Python2 was provided until 0.9.10 (not included)
```
!!! Important
If the simulation is running at very low FPS rates, go to `Edit/Editor preferences/Performance` in the UE editor and disable __Use less CPU when in background__.
@ -167,8 +186,7 @@ Now CARLA is ready to go. Here is a brief summary of the most useful `make` comm
<th>Description</th>
</thead>
<tbody>
<td>
<code>make help</code> </td>
<td><code>make help</code> </td>
<td>Prints all available commands.</td>
</tr>
<tr>
@ -189,25 +207,28 @@ Now CARLA is ready to go. Here is a brief summary of the most useful `make` comm
</tr>
<tr>
<td><code>make rebuild</code></td>
<td>make clean and make launch both in one command.</td>
<td><code>make clean</code> and <code>make launch</code> both in one command.</td>
</tbody>
</table>
---
<br>
Keep reading this section to learn how to update the build or take some first steps in CARLA.
Read the **[F.A.Q.](build_faq.md)** page or post in the [CARLA forum](https://forum.carla.org/c/installation-issues/linux) for any issues regarding this guide.
Some recommendations after finishing the build. Learn how to update the CARLA build or take your first steps in the simulation, and learn some core concepts.
<div class="build-buttons">
<p>
<a href="../core_concepts" target="_blank" class="btn btn-neutral" title="Learn about CARLA core concepts">
Go to __First steps__</a>
</p>
<p>
<a href="../build_update" target="_blank" class="btn btn-neutral" title="Learn how to update the build">
Update CARLA</a>
</p>
<p>
<a href="../core_concepts" target="_blank" class="btn btn-neutral" title="Learn about CARLA core concepts">
First steps</a>
</p>
</div>

View File

@ -1,5 +1,12 @@
# Contributor Covenant Code of Conduct
* [__Our pledge__](#our-pledge)
* [__Our standards__](#our-standards)
* [__Our responsibilities__](#our-responsibilities)
* [__Scope__](#scope)
* [__Enforcement__](#enforcement)
* [__Attribution__](#attribution)
---
## Our Pledge

View File

@ -1,5 +1,9 @@
# Coding standard
* [__General__](#general)
* [__Python__](#python)
* [__C++__](#c++)
---
## General

View File

@ -1,124 +1,139 @@
# Contributing to CARLA
We are more than happy to accept contributions!
The CARLA team is glad to accept contributions from anybody willing to collaborate. There are different ways to contribute to the project, depending on the capabilities of the contributor. The team will work as much as possible so that contributions are successfully integrated in CARLA.
How can I contribute?
Take a look and don't hesitate!
* Reporting bugs
* Feature requests
* Improving documentation
* Code contributions
* [__Report bugs__](#report-bugs)
* [__Request features__](#request-features)
* [__Code contributions__](#code-contributions)
* [Learn about Unreal Engine](#learn-about-unreal-engine)
* [Before getting started](#before-getting-started)
* [Coding standard](#coding-standard)
* [Submission](#submission)
* [Checklist](#checklist)
* [__Art contributions__](#art-contributions)
* [__Docs contributions__](#docs-contributions)
---
## Reporting bugs
## Report bugs
Use our [issue section][issueslink] on GitHub. Please check before that the
issue is not already reported, and make sure you have read our
[Documentation][docslink] and [FAQ][faqlink].
Issues can be reported in the [issue section][issueslink] on GitHub. Before reporting a new bug, make sure to do some checkups.
__1. Check if the bug has been reported.__ Look it up in that same issue section on GitHub.
__2. Read the docs.__ Make sure that the issue is a bug, not a misunderstanding on how is CARLA supposed to work. Read the pages related to the issue in the [Documentation][docslink] and take a look at the [FAQ][faqlink] page.
[issueslink]: https://github.com/carla-simulator/carla/issues
[docslink]: http://carla.readthedocs.io
[faqlink]: build_faq.md
---
## Feature requests
## Request features
Please check first the list of [feature requests][frlink]. If it is not there
and you think is a feature that might be interesting for users, please submit
your request as a new issue.
Ideas for new features are also a great way to contribute. Any suggestion that could improve the users' experience can be submitted in the corresponding GitHub section [here][frlink].
[frlink]: https://github.com/carla-simulator/carla/issues?q=is%3Aissue+is%3Aopen+label%3A%22feature+request%22+sort%3Acomments-desc
---
## Improving documentation
If you feel something is missing in the documentation, please don't hesitate to
open an issue to let us know. Even better, if you think you can improve it
yourself, it would be a great contribution to the community!
We build our documentation with [MkDocs](http://www.mkdocs.org/) based on the
Markdown files inside the `Docs` folder. You can either directly modify them on
GitHub or locally in your machine.
To update Python API docs, instead of directly modifying the Markdown you need to edit the
corresponding YAML files inside [`carla/PythonAPI/docs/`][fileslink] and run [`doc_gen.py`][scriptlink]
or `make PythonAPI.docs`.
This will re-generate the respective Markdown files inside `carla/Docs/`,
which can then be fed into `mkdocs`.
[fileslink]: https://github.com/carla-simulator/carla/tree/master/PythonAPI/docs
[scriptlink]: https://github.com/carla-simulator/carla/blob/master/PythonAPI/docs/doc_gen.py
Once you are done with your changes, please submit a pull-request.
!!! tip
You can build and serve it locally (at <http://127.0.0.1:8000>) by running `mkdocs`
in the project's main folder.
```sh
> sudo pip install mkdocs
> mkdocs serve
```
---
## Code contributions
So you are considering making a code contribution, great! We love to have
contributions from the community.
Before starting hands-on on coding, please check out the [issue board][issueboard] to check what is the team already working on, to avoid overlapping. In case of doubt or to discuss how to proceed, please contact one of us (or send an email to <carla.simulator@gmail.com>).
Before starting hands-on on coding, please check out our
[issue board][issueboard] to see if we are already working on that, it would
be a pity putting an effort into something just to discover that someone else
was already working on that. In case of doubt or to discuss how to proceed,
please contact one of us (or send an email to <carla.simulator@gmail.com>).
In order to start working, [fork the CARLA repository](https://docs.github.com/en/enterprise/2.13/user/articles/fork-a-repo), and clone said fork in your computer. Remember to [keep your fork in sync](https://docs.github.com/en/enterprise/2.13/user/articles/syncing-a-fork) with the original repository.
[issueboard]: https://github.com/carla-simulator/carla/issues
#### Where can I learn more about Unreal Engine?
### Learn about Unreal Engine
A basic introduction to C++ programming with UE4 can be found at Unreal's
[C++ Programming Tutorials][ue4tutorials]. Then, if you want to dive into UE4
C++ development there are few paying options online. The
[Unreal C++ Course at Udemy][ue4course] it's pretty complete and there are
usually offers that make it very affordable.
A basic introduction to C++ programming with UE4 can be found at Unreal's [C++ Programming Tutorials][ue4tutorials]. There are other options online, some of them not free of charge. The [Unreal C++ Course at Udemy][ue4course] it's pretty complete and there are usually offers that make it very affordable.
[ue4tutorials]: https://docs.unrealengine.com/latest/INT/Programming/Tutorials/
[ue4course]: https://www.udemy.com/unrealcourse/
#### What should I know before I get started?
### Before getting started
Check out the ["CARLA Design"](index.md)<!-- @todo --> document to get an idea
on the different modules that compose CARLA, and chose the most appropriate one
to hold the new feature. We are aware the developers documentation is still
scarce, please ask us in case of doubt, and of course don't hesitate to improve
the current documentation if you feel confident enough.
Check out the [CARLA Design](index.md)<!-- @todo --> document to get an idea on the different modules that compose CARLA. Choose the most appropriate one
to hold the new feature. Feel free to contact the team in the [Discord server](https://discord.com/invite/8kqACuC) in case any doubt arises during the process.
#### Coding standard
### Coding standard
Please follow the current [coding standard](cont_coding_standard.md) when submitting
new code.
Follow the current [coding standard](cont_coding_standard.md) when submitting new code.
#### Pull-requests
### Submission
Once you think your contribution is ready to be added to CARLA, please submit a
pull-request.
Contributions and new features are not merged directly to the `master` branch, but to an intermediate branch named `dev`. This [Gitflow](https://nvie.com/posts/a-successful-git-branching-model/) branching model makes it easier to maintain a stable master branch. This model requires a specific workflow for contributions.
Try to be as descriptive as possible when filling the pull-request description.
Adding images and gifs may help people to understand your changes or new
features.
* Always keep your `dev` branch updated with the lastest changes.
* Develop the contribution in child branch from `dev` named as `username/name_of_the_contribution`.
* Once the contribution is ready, submit a pull-request from your branch to `dev`. Try to be as descriptive as possible when filling the description. Note that there are some checks that the new code is required to pass before merging. The checks are automatically run by the continuous integration system. A green tick mark will appear if the checks are successful. If a red mark, please correct the code accordingly.
Please note that there are some checks that the new code is required to pass
before we can do the merge. The checks are automatically run by the continuous
integration system, you will see a green tick mark if all the checks succeeded.
If you see a red mark, please correct your code accordingly.
Once the contribution is merged in `dev`, it can be tested with the rest of new features. By the time of the next release, the `dev` branch will be merged to `master`, and the contribution will be available and announced.
###### Checklist
### Checklist
<!--
If you modify this list please keep it up-to-date with pull_request_template.md
-->
* [ ] Your branch is up-to-date with the `dev` branch and tested with latest changes.
* [ ] Extended the README/documentation, if necessary.
* [ ] Code compiles correctly.
* [ ] All tests passing with `make check`.
- [ ] Your branch is up-to-date with the `master` branch and tested with latest changes
- [ ] Extended the README / documentation, if necessary
- [ ] Code compiles correctly
- [ ] All tests passing with `make check`
---
## Art contributions
Art contributions include vehicles, walkers, maps or any other type of assets to be used in CARLA. These are stored in a BitBucket repository, which has some account space limitations. For said reason, the contributor will have to get in touch with the CARLA team, and ask them to create a branch on the content repository for the contributions.
__1. Create a BitBucket account.__ Visit the [Bitbucket page](https://bitbucket.org).
__2. Contact the art team to get access to the content repository.__ Join the [Discord server](https://discord.com/invite/8kqACuC). Go to the __Contributors__ channel and request for access to the content repostory.
__3. A branch will be created for each contributor.__ The branch will be named as `contributors/contributor_name`. All the contributions made by said user should be made in that corresponding branch.
__4. Build CARLA.__ In order to contribute, a CARLA build is necessary. Follow the instructions to build either in [Linux](https://carla.readthedocs.io/en/latest/build_linux/) or [Windows](https://carla.readthedocs.io/en/latest/build_windows/).
__5. Download the content repository.__ Follow the instructions to update the content in [here](https://carla.readthedocs.io/en/latest/build_update/#get-development-assets).
__6. Update the branch to be in sync with master.__ The branch should always be updated with the latest changes in master.
__7. Upload the contribution.__ Do the corresponding changes and push the branch to origin.
__8. Wait for the art team to check it up.__ Once the contribution is uploaded, the team will check that everything is prepared to be merged with master.
---
## Docs contributions
If some documentation is missing, vague or imprecise, it can be reported as with any other bug (read the previous section on [how to report bugs](#report-bugs)). However, users can contribute by writing documentation.
The documentation is written with a mix of [Markdown](https://www.markdownguide.org/) and HTML tags, with a some extra CSS code for features such as tables or the [town slider](https://carla.readthedocs.io/en/latest/core_map/#carla-maps). Follow the steps below to start writing documentation.
!!! Important
To submit docs contributions, follow the same workflow explained right above in [code contributions](#submission). To sum up, contributions are made in a child branch from `dev` and merged to said branch.
__1. Build CARLA from source.__ Follow the steps in the docs to build on [Linux](build_linux.md) or [Windows](build_windows.md).
__2. Install [MkDocs](http://www.mkdocs.org/).__ MkDocs is a static site generator used to build documentation.
```sh
sudo pip install mkdocs
```
__3. Visualize the docs.__ In the main CARLA folder, run the following command and click the link that appears in the terminal (http://127.0.0.1:8000) to open a local visualization of the documentation.
```sh
mkdocs serve
```
__4. Create a git branch.__ Make sure to be in the `dev` branch (updated to latest changes) when creating a new one.
```sh
git checkout -b <contributor_name>/<branch_name>
```
__5. Write the docs.__ Edit the files following the guidelines in the [documentation standard](cont_doc_standard.md) page.
__6. Submit the changes.__ Create a pull request in the GitHub repository, and add one of the suggested reviewers. Try to be as descriptive as possible when filling the pull-request description.
__7. Wait for review.__ The team will check if everything is ready to be merged or any changes are needed.
!!! Warning
The local repository must be updated with the latest updates in the `dev` branch.

View File

@ -1,30 +1,36 @@
# Documentation Standard
This document will serve as a guide and example of some rules that need to be
followed in order to contribute to the documentation.
This document will serve as a guide and example of some rules that need to be followed in order to contribute to the documentation.
We use a mix of markdown and HTML tags to customize the documentation along with an
[`extra.css`](https://github.com/carla-simulator/carla/tree/master/Docs/extra.css) file.
* [__Docs structure__](#docs-structure)
* [__Rules__](#rules)
* [__Exceptions__](#exceptions)
---
## Docs structure
We use a mix of markdown and HTML tags to customize the documentation along with an [`extra.css`](https://github.com/carla-simulator/carla/tree/master/Docs/extra.css) file.
To update Python API docs, instead of directly modifying the Markdown you need to edit the corresponding YAML files inside [`carla/PythonAPI/docs/`][fileslink] and run [`doc_gen.py`][scriptlink] or `make PythonAPI.docs`.
This will re-generate the respective Markdown files inside `carla/Docs/`, which can then be fed into `mkdocs`.
[fileslink]: https://github.com/carla-simulator/carla/tree/master/PythonAPI/docs
[scriptlink]: https://github.com/carla-simulator/carla/blob/master/PythonAPI/docs/doc_gen.py
---
## Rules
* Leave always an empty line between sections and at the end of the document.
* Writting should not exceed `100` columns, except for HTML related content, markdown tables,
code snipets and referenced links.
* If an inline link exceeds the limit, use referenced `[name][reference_link]` markdown notation
`[reference_link]: https://` rather than `[name](https://)`.
* Use `<br>` to make inline jumps rather than leaving two spaces at the end of a line.
* Use `<h1>Title</h1>` at the beggining of a new page in order to make a Title or
`<hx>Heading<hx>` to make a heading that **won't show** on the navigation bar.
* Use `------` underlining a Heading or `#` hierarchy to make headings and show them in the
navigation bar.
* Leave always an empty line between sections and at the end of the document.
* Writting should not exceed `100` columns, except for HTML related content, markdown tables, code snipets and referenced links.
* If an inline link exceeds the limit, use referenced `[name][reference_link]` markdown notation `[reference_link]: https://` rather than `[name](https://)`.
* Use `<br>` to make inline jumps rather than leaving two spaces at the end of a line.
* Use `<h1>Title</h1>` at the beggining of a new page in order to make a Title or `<hx>Heading<hx>` to make a heading that **won't show** on the navigation bar.
* Use `------` underlining a Heading or `#` hierarchy to make headings and show them in the navigation bar.
---
## Exceptions
* Documentation generated via python scripts like PythonAPI reference
* Documentation generated via Python scripts like PythonAPI reference
Handy markdown [cheatsheet][cheatlink].

View File

@ -78,6 +78,9 @@ transform = Transform(Location(x=230, y=195, z=40), Rotation(yaw=180))
actor = world.spawn_actor(blueprint, transform)
```
!!! Important
CARLA uses the [Unreal Engine coordinates system](https://carla.readthedocs.io/en/latest/python_api/#carlarotation). Remember that [`carla.Rotation`](https://carla.readthedocs.io/en/latest/python_api/#carlarotation) constructor is defined as `(pitch, yaw, roll)`, that differs from Unreal Engine Editor `(roll, pitch, yaw)`.
The actor will not be spawned in case of collision at the specified location. No matter if this happens with a static object or another actor. It is possible to try avoiding these undesired spawning collisions.
* `map.get_spawn_points()` __for vehicles__. Returns a list of recommended spawning points.

View File

@ -86,7 +86,7 @@ waypoints_junc = my_junction.get_waypoints()
### Waypoints
A [__carla.Waypoint__](python_api.md#carla.Waypoint) is a 3D-directed point. These are prepared to mediate between the world and the openDRIVE definition of the road.
A [__carla.Waypoint__](python_api.md#carla.Waypoint) is a 3D-directed point. These are prepared to mediate between the world and the openDRIVE definition of the road. Everything related with waypoints happens on the client-side, so there no communication with the server is needed.
Each waypoint contains a [carla.Transform](python_api.md#carla.Transform). This states its location on the map and the orientation of the lane containing it. The variables `road_id`,`section_id`,`lane_id` and `s` translate this transform to the OpenDRIVE road. These combined, create the `id` of the waypoint.
@ -105,6 +105,11 @@ right_lm_color = waypoint.right_lane_marking.color
---
## Navigation in CARLA
Navigation in CARLA is managed via the waypoint API. This consists of a summary of methods in [carla.Waypoint](python_api.md#carla.Waypoint) and [carla.Map](python_api.md#carla.Map).
All the queries happen on the client-side. The client only communicates with the server when retrieving the map object that will be used for the queries. There is no need to retrieve the map (`world.get_map()`) more than once.
### Navigating through waypoints
Waypoints have a set of methods to connect with others and create a road flow. All of these methods follow traffic rules to determine only places where the vehicle can go.
@ -127,6 +132,8 @@ while True:
The instance of the map is provided by the world. It will be useful to create routes and make vehicles roam around the city and reach goal destinations.
The following method asks the server for the XODR map file, and parses it to a [carla.Map](python_api.md#carla.Map) object. It only needs to be calle once. Maps can be quite heavy, and successive calls are unnecessary and expensive.
```py
map = world.get_map()
```

View File

@ -9,21 +9,13 @@
- [CARLA Nightly Build (Linux)](https://carla-releases.s3.eu-west-3.amazonaws.com/Linux/Dev/CARLA_Latest.tar.gz)
- [CARLA Nightly Build (Windows)](https://carla-releases.s3.eu-west-3.amazonaws.com/Windows/Dev/CARLA_Latest.zip)
### Pre-Release 0.9.10
- `[Ubuntu 16.04]` [CARLA_0.9.10-Pre_Ubuntu16.tar.gz](https://carla-releases.s3.eu-west-3.amazonaws.com/Linux/CARLA_0.9.10-Pre_Ubuntu16.tar.gz)
- `[Ubuntu 16.04]` [AdditionalMaps_0.9.10-Pre_Ubuntu16.tar.gz](https://carla-releases.s3.eu-west-3.amazonaws.com/Linux/AdditionalMaps_0.9.10-Pre_Ubuntu16.tar.gz)
- `[Ubuntu 18.04]` [CARLA_0.9.10-Pre_Ubuntu18.tar.gz](https://carla-releases.s3.eu-west-3.amazonaws.com/Linux/CARLA_0.9.10-Pre_Ubuntu18.tar.gz)
- `[Ubuntu 18.04]` [AdditionalMaps_0.9.10-Pre_Ubuntu18.tar.gz](https://carla-releases.s3.eu-west-3.amazonaws.com/Linux/AdditionalMaps_0.9.10-Pre_Ubuntu18.tar.gz)
- `[Windows x64]` [CARLA_0.9.10-Pre_Win.zip](https://carla-releases.s3.eu-west-3.amazonaws.com/Windows/CARLA_0.9.10-Pre_Win.zip)
- `[Windows x64]` [AdditionalMaps_0.9.10-Pre_Win.zip](https://carla-releases.s3.eu-west-3.amazonaws.com/Windows/AdditionalMaps_0.9.10-Pre_Win.zip)
### Development [[Documentation](https://carla.readthedocs.io/en/latest/)]
> These are the version of CARLA, more frequently updated and with the latest
> features. Keep in mind that the API and features in this channel can (and
> probably will) change.
- [CARLA 0.9.10](https://github.com/carla-simulator/carla/releases/tag/0.9.10)
- [CARLA 0.9.9](https://github.com/carla-simulator/carla/releases/tag/0.9.9)
- [CARLA 0.9.8](https://github.com/carla-simulator/carla/releases/tag/0.9.8)
- [CARLA 0.9.7](https://github.com/carla-simulator/carla/releases/tag/0.9.7)

BIN
Docs/img/faq_rpc_error.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 640 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 75 KiB

After

Width:  |  Height:  |  Size: 97 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 58 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 41 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 31 KiB

View File

@ -143,10 +143,12 @@ CARLA forum</a>
— Add new content to CARLA.
[__Create a sensor__](tuto_D_create_sensor.md)
— Develop a new sensor to be used in CARLA.
[__Customize vehicle suspension__](tuto_D_customize_vehicle_suspension.md)
— Modify the suspension system of a vehicle.
[__Make a release__](tuto_D_make_release.md)
— For developers who want to publish a release.
[__Generate detailed colliders__](tuto_D_generate_colliders.md)
— Created detailed colliders for vehicles.
— Create detailed colliders for vehicles.
[__Generate pedestrian navigation__](tuto_D_generate_pedestrian_navigation.md)
— Obtain the information needed for walkers to move around.
</p>

View File

@ -2,12 +2,12 @@
The carlaviz plugin is used to visualize the simulation in a web browser. A windows with some basic representation of the scene is created. Actors are updated on-the-fly, sensor data can be retrieved, and additional text, lines and polylines can be drawn in the scene.
* [__General information__](#general-information)
* [Support](#support)
* [__Get carlaviz__](#get-carlaviz)
* [Prerequisites](#prerequisites)
* [Download the plugin](#download-the-plugin)
* [__Utilities__](#utilities)
* [__General information__](#general-information)
* [Support](#support)
* [__Get carlaviz__](#get-carlaviz)
* [Prerequisites](#prerequisites)
* [Download the plugin](#download-the-plugin)
* [__Utilities__](#utilities)
---
## General information

File diff suppressed because it is too large Load Diff

View File

@ -7,6 +7,17 @@ which is divided into those in which the recipe is centered, and those that need
There are more recipes to come!
* [__Actor Spectator Recipe__](#actor-spectator-recipe)
* [__Attach Sensors Recipe__](#attach-sensors-recipe)
* [__Actor Attribute Recipe__](#actor-attribute-recipe)
* [__Converted Image Recipe__](#converted-image-recipe)
* [__Lanes Recipe__](#lanes-recipe)
* [__Debug Bounding Box Recipe__](#debug-bounding-box-recipe)
* [__Debug Vehicle Trail Recipe__](#debug-vehicle-trail-recipe)
* [__Parsing Client Arguments Recipe__](#parsing-client-arguments-recipe)
* [__Traffic Light Recipe__](#traffic-light-recipe)
* [__Walker Batch Recipe__](#walker-batch-recipe)
---
## Actor Spectator Recipe
@ -222,7 +233,7 @@ path it was following and the speed at each waypoint.
![debug_trail_recipe](img/recipe_debug_trail.jpg)
---
## Parse client creation arguments
## Parsing Client Arguments Recipe
This recipe shows in every script provided in `PythonAPI/Examples` and it is used to parse the client creation arguments when running the script.
@ -261,7 +272,7 @@ Used:<br>
```
---
## Traffic lights Recipe
## Traffic Light Recipe
This recipe changes from red to green the traffic light that affects the vehicle.
This is done by detecting if the vehicle actor is at a traffic light.
@ -286,7 +297,7 @@ if vehicle_actor.is_at_traffic_light():
![tl_recipe](img/tl_recipe.gif)
---
## Walker batch recipe
## Walker Batch Recipe
```py
# 0. Choose a blueprint fo the walkers

View File

@ -2,6 +2,23 @@
The recorder system saves all the info needed to replay the simulation in a binary file,
using little endian byte order for the multibyte values.
* [__1- Strings in binary__](#1-strings-in-binary)
* [__2- Info header__](#2-info-header)
* [__3- Packets__](#3-packets)
* [Packet 0 - Frame Start](#packet-0-frame-start)
* [Packet 1 - Frame End](#packet-1-frame-end)
* [Packet 2 - Event Add](#packet-2-event-add)
* [Packet 3 - Event Del](#packet-3-event-del)
* [Packet 4 - Event Parent](#packet-4-event-parent)
* [Packet 5 - Event Collision](#packet-5-event-collision)
* [Packet 6 - Position](#packet-6-position)
* [Packet 7 - TrafficLight](#packet-7-trafficlight)
* [Packet 8 - Vehicle Animation](#packet-8-vehicle-animation)
* [Packet 9 - Walker Animation](#packet-9-walker-animation)
* [__4- Frame Layout__](#4-frame-layout)
* [__5- File Layout__](#5-file-layout)
In the next image representing the file format, we can get a quick view of all the detailed
information. Each part that is visualized in the image will be explained in the following sections:
@ -14,7 +31,7 @@ In summary, the file format has a small header with general info
![global file format](img/RecorderFileFormat3.jpg)
---
## 1. Strings in binary
## 1- Strings in binary
Strings are encoded first with the length of it, followed by its characters without null
character ending. For example, the string 'Town06' will be saved
@ -23,7 +40,7 @@ as hex values: 06 00 54 6f 77 6e 30 36
![binary dynamic string](img/RecorderString.jpg)
---
## 2. Info header
## 2- Info header
The info header has general information about the recorded file. Basically, it contains the version
and a magic string to identify the file as a recorder file. If the header changes then the version
@ -37,7 +54,7 @@ A sample info header is:
![info header sample](img/RecorderHeader.jpg)
---
## 3. Packets
## 3- Packets
Each packet starts with a little header of two fields (5 bytes):
@ -64,7 +81,7 @@ The types of packets are:
We suggest to use **id** over 100 for user custom packets, because this list will keep growing in
the future.
### 3.1 Packet 0: Frame Start
### Packet 0 - Frame Start
This packet marks the start of a new frame, and it will be the first one to start each frame.
All packets need to be placed between a **Frame Start** and a **Frame End**.
@ -73,7 +90,7 @@ All packets need to be placed between a **Frame Start** and a **Frame End**.
So, elapsed + durationThis = elapsed time for next frame
### 3.2 Packet 1: Frame End
### Packet 1 - Frame End
This frame has no data and it only marks the end of the current frame. That helps the replayer
to know the end of each frame just before the new one starts.
@ -81,7 +98,7 @@ Usually, the next frame should be a Frame Start packet to start a new frame.
![frame end](img/RecorderFrameEnd.jpg)
### 3.3 Packet 2: Event Add
### Packet 2 - Event Add
This packet says how many actors we need to create at current frame.
@ -110,7 +127,7 @@ The number of attributes is variable and should look similar to this:
* color = 79,33,85
* role_name = autopilot
### 3.4 Packet 3: Event Del
### Packet 3 - Event Del
This packet says how many actors need to be destroyed this frame.
@ -128,7 +145,7 @@ the next 16 bytes and will be directly to the start of the next packet.
The next 3 says the total records that follows, and each record is the id of the actor to remove.
So, we need to remove at this frame the actors 100, 101 and 120.
### 3.5 Packet 4: Event Parent
### Packet 4 - Event Parent
This packet says which actor is the child of another (the parent).
@ -136,7 +153,7 @@ This packet says which actor is the child of another (the parent).
The first id is the child actor, and the second one will be the parent actor.
### 3.6 Packet 5: Event Collision
### Packet 5 - Event Collision
If a collision happens between two actors, it will be registered in this packet. Currently only
actors with a collision sensor will report collisions, so currently only hero vehicles have that
@ -148,28 +165,28 @@ The **id** is just a sequence to identify each collision internally.
Several collisions between the same pair of actors can happen in the same frame, because physics
frame rate is fixed and usually there are several physics substeps in the same rendered frame.
### 3.7 Packet 6: Position
### Packet 6 - Position
This packet records the position and orientation of all actors of type **vehicle** and
**walker** that exist in the scene.
![position](img/RecorderPosition.jpg)
### 3.8 Packet 7: TrafficLight
### Packet 7 - TrafficLight
This packet records the state of all **traffic lights** in the scene. Which means that it
stores the state (red, orange or green) and the time it is waiting to change to a new state.
![state](img/RecorderTrafficLight.jpg)
### 3.9 Packet 8: Vehicle animation
### Packet 8 - Vehicle animation
This packet records the animation of the vehicles, bikes and cycles. This packet stores the
**throttle**, **sterring**, **brake**, **handbrake** and **gear** inputs, and then set them at playback.
![state](img/RecorderVehicle.jpg)
### 3.10 Packet 9: Walker animation
### Packet 9 - Walker animation
This packet records the animation of the walker. It just saves the **speed** of the walker
that is used in the animation.
@ -177,7 +194,7 @@ that is used in the animation.
![state](img/RecorderWalker.jpg)
---
## 4. Frame Layout
## 4- Frame Layout
A frame consists of several packets, where all of them are optional, except the ones that
have the **start** and **end** in that frame, that must be there always.
@ -195,7 +212,7 @@ The **animation** packets are also optional, but by default they are recorded. T
are animated and also the vehicle wheels follow the direction of the vehicles.
---
## 5. File Layout
## 5- File Layout
The layout of the file starts with the **info header** and then follows a collection of packets in
groups. The first in each group is the **Frame Start** packet, and the last in the group is

View File

@ -80,6 +80,12 @@ in_meters = 1000 * normalized
The output [carla.Image](python_api.md#carla.Image) should then be saved to disk using a [carla.colorConverter](python_api.md#carla.ColorConverter) that will turn the distance stored in RGB channels into a __[0,1]__ float containing the distance and then translate this to grayscale.
There are two options in [carla.colorConverter](python_api.md#carla.ColorConverter) to get a depth view: __Depth__ and __Logaritmic depth__. The precision is milimetric in both, but the logarithmic approach provides better results for closer objects.
```py
...
raw_image.save_to_disk("path/to/save/converted/image",carla.Depth)
```
![ImageDepth](img/ref_sensors_depth.jpg)
@ -495,7 +501,7 @@ For a better realism, points in the cloud can be dropped off. This is an easy wa
Additionally, the `noise_stddev` attribute makes for a noise model to simulate unexpected deviations that appear in real-life sensors. For positive values, each point is randomly perturbed along the vector of the laser ray. The result is a LIDAR sensor with perfect angular positioning, but noisy distance measurement.
The rotation of the LIDAR can be tuned to cover a specific angle on every simulation step (using a [fixed time-step](adv_synchrony_timestep.md)). For example, to rotate once per step (full circle output, as in the picture below), the rotation frequency and the simulated FPS should be equal. <br> __1.__ Set the sensor's frequency `sensors_bp['lidar'][0].set_attribute('rotation_frequency','10')`. <br> __2.__ Run the simulation using `python config.py --fps=10`.
The rotation of the LIDAR can be tuned to cover a specific angle on every simulation step (using a [fixed time-step](adv_synchrony_timestep.md)). For example, to rotate once per step (full circle output, as in the picture below), the rotation frequency and the simulated FPS should be equal. <br> __1.__ Set the sensor's frequency `sensors_bp['lidar'][0].set_attribute('rotation_frequency','10')`. <br> __2.__ Run the simulation using `python3 config.py --fps=10`.
![LidarPointCloud](img/lidar_point_cloud.jpg)
@ -843,7 +849,7 @@ A value of 1.5 means that we want the sensor to capture data each second and a h
<tr>
<td><code>fstop</code></td>
<td>float</td>
<td>8.0</td>
<td>1.4</td>
<td>Opening of the camera lens. Aperture is <code>1/fstop</code> with typical lens going down to f/1.2 (larger opening). Larger numbers will reduce the Depth of Field effect.</td>
<tr>
<td><code>image_size_x</code></td>
@ -858,7 +864,7 @@ A value of 1.5 means that we want the sensor to capture data each second and a h
<tr>
<td><code>iso</code></td>
<td>float</td>
<td>200.0</td>
<td>100.0</td>
<td>The camera sensor sensitivity.</td>
<tr>
<td><code>gamma</code></td>
@ -959,22 +965,22 @@ Since these effects are provided by UE, please make sure to check their document
<tr>
<td><code>exposure_mode</code> </td>
<td>str</td>
<td><code>manual</code></td>
<td><code>histogram</code></td>
<td>Can be <code>manual</code> or <code>histogram</code>. More in <a href="https://docs.unrealengine.com/en-US/Engine/Rendering/PostProcessEffects/AutomaticExposure/index.html">UE4 docs</a>.</td>
<tr>
<td><code>exposure_compensation</code> </td>
<td>float</td>
<td>-2.2</td>
<td><b>Linux:</b> -1.5<br><b>Windows:</b> 0.0</td>
<td>Logarithmic adjustment for the exposure. 0: no adjustment, -1:2x darker, -2:4 darker, 1:2x brighter, 2:4x brighter.</td>
<tr>
<td><code>exposure_min_bright</code> </td>
<td>float</td>
<td>0.1</td>
<td>7.0</td>
<td>In <code>exposure_mode: "histogram"</code>. Minimum brightness for auto exposure. The lowest the eye can adapt within. Must be greater than 0 and less than or equal to <code>exposure_max_bright</code>.</td>
<tr>
<td><code>exposure_max_bright</code> </td>
<td>float</td>
<td>2.0</td>
<td>9.0</td>
<td>In `exposure_mode: "histogram"`. Maximum brightness for auto exposure. The highestthe eye can adapt within. Must be greater than 0 and greater than or equal to `exposure_min_bright`.</td>
<tr>
<td><code>exposure_speed_up</code> </td>
@ -1329,7 +1335,7 @@ for detection in semantic_lidar_measurement:
The rotation of the LIDAR can be tuned to cover a specific angle on every simulation step (using a [fixed time-step](adv_synchrony_timestep.md)). For example, to rotate once per step (full circle output, as in the picture below), the rotation frequency and the simulated FPS should be equal. <br>
__1.__ Set the sensor's frequency `sensors_bp['lidar'][0].set_attribute('rotation_frequency','10')`. <br>
__2.__ Run the simulation using `python config.py --fps=10`.
__2.__ Run the simulation using `python3 config.py --fps=10`.
![LidarPointCloud](img/semantic_lidar_point_cloud.jpg)
@ -1435,8 +1441,16 @@ __2.__ Run the simulation using `python config.py --fps=10`.
This camera classifies every object in sight by displaying it in a different color according to its tags (e.g., pedestrians in a different color than vehicles).
When the simulation starts, every element in scene is created with a tag. So it happens when an actor is spawned. The objects are classified by their relative file path in the project. For example, meshes stored in `Unreal/CarlaUE4/Content/Static/Pedestrians` are tagged as `Pedestrian`.
![ImageSemanticSegmentation](img/ref_sensors_semantic.jpg)
The server provides an image with the tag information __encoded in the red channel__: A pixel with a red value of `x` belongs to an object with tag `x`.
This raw [carla.Image](python_api.md#carla.Image) can be stored and converted it with the help of __CityScapesPalette__ in [carla.ColorConverter](python_api.md#carla.ColorConverter) to apply the tags information and show picture with the semantic segmentation.
```py
...
raw_image.save_to_disk("path/to/save/converted/image",carla.cityScapesPalette)
```
The following tags are currently available:
<table class ="defTable">
@ -1444,59 +1458,123 @@ The following tags are currently available:
<th>Value</th>
<th>Tag</th>
<th>Converted color</th>
<th>Description</th>
</thead>
<tbody>
<td><code>0</code> </td>
<td>Unlabeled</td>
<td>( 0, 0, 0)</td>
<td><code>(0, 0, 0)</code></td>
<td>Elements that have not been categorized are considered <code>Unlabeled</code>. This category is meant to be empty or at least contain elements with no collisions.</td>
<tr>
<td><code>1</code> </td>
<td>Building</td>
<td>( 70, 70, 70)</td>
<td><code>(70, 70, 70)</code></td>
<td>Buildings like houses, skyscrapers,... and the elements attached to them. <br> E.g. air conditioners, scaffolding, awning or ladders and much more.</td>
<tr>
<td><code>2</code> </td>
<td>Fence</td>
<td>(190, 153, 153)</td>
<td><code>(100, 40, 40)</code></td>
<td>Barriers, railing, or other upright structures. Basically wood or wire assemblies that enclose an area of ground.</td>
<tr>
<td><code>3</code> </td>
<td>Other</td>
<td>(250, 170, 160)</td>
<td><code>(55, 90, 80)</code></td>
<td> Everything that does not belong to any other category.</td>
<tr>
<td><code>4</code> </td>
<td>Pedestrian</td>
<td>(220, 20, 60)</td>
<td><code>(220, 20, 60)</code></td>
<td>Humans that walk or ride/drive any kind of vehicle or mobility system. <br> E.g. bicycles or scooters, skateboards, horses, roller-blades, wheel-chairs, etc.</td>
<tr>
<td><code>5</code> </td>
<td>Pole</td>
<td>(153, 153, 153)</td>
<td><code>(153, 153, 153)</code></td>
<td>Small mainly vertically oriented pole. If the pole has a horizontal part (often for traffic light poles) this is also considered pole. <br> E.g. sign pole, traffic light poles.</td>
<tr>
<td><code>6</code> </td>
<td>Road line</td>
<td>(157, 234, 50)</td>
<td>RoadLine</td>
<td><code>(157, 234, 50)</code></td>
<td>The markings on the road.</td>
<tr>
<td><code>7</code> </td>
<td>Road</td>
<td>(128, 64, 128)</td>
<td><code>(128, 64, 128)</code></td>
<td>Part of ground on which cars usually drive. <br> E.g. lanes in any directions, and streets.</td>
<tr>
<td><code>8</code> </td>
<td>Sidewalk</td>
<td>(244, 35, 232)</td>
<td>SideWalk</td>
<td><code>(244, 35, 232)</code></td>
<td>Part of ground designated for pedestrians or cyclists. Delimited from the road by some obstacle (such as curbs or poles), not only by markings. This label includes a possibly delimiting curb, traffic islands (the walkable part), and pedestrian zones.</td>
<tr>
<td><code>9</code> </td>
<td>Vegetation</td>
<td>(107, 142, 35)</td>
<td><code>(107, 142, 35)</code></td>
<td> Trees, hedges, all kinds of vertical vegetation. Ground-level vegetation is considered <code>Terrain</code>.</td>
<tr>
<td><code>10</code> </td>
<td>Car</td>
<td>( 0, 0, 142)</td>
<td>Vehicles</td>
<td><code>(0, 0, 142)</code></td>
<td>Cars, vans, trucks, motorcycles, bikes, buses, trains.</td>
<tr>
<td><code>11</code> </td>
<td>Wall</td>
<td>(102, 102, 156)</td>
<td><code>(102, 102, 156)</code></td>
<td>Individual standing walls. Not part of a building.</td>
<tr>
<td><code>12</code> </td>
<td>Traffic sign</td>
<td>(220, 220, 0)</td>
<td>TrafficSign</td>
<td><code>(220, 220, 0)</code></td>
<td>Signs installed by the state/city authority, usually for traffic regulation. This category does not include the poles where signs are attached to. <br> E.g. traffic- signs, parking signs, direction signs...</td>
<tr>
<td><code>13</code> </td>
<td>Sky</td>
<td><code>(70, 130, 180)</code></td>
<td>Open sky. Includes clouds and the sun.</td>
<tr>
<td><code>14</code> </td>
<td>Ground</td>
<td><code>(81, 0, 81)</code></td>
<td>Any horizontal ground-level structures that does not match any other category. For example areas shared by vehicles and pedestrians, or flat roundabouts delimited from the road by a curb.</td>
<tr>
<td><code>15</code> </td>
<td>Bridge</td>
<td><code>(150, 100, 100)</code></td>
<td>Only the structure of the bridge. Fences, people, vehicles, an other elements on top of it are labeled separately.</td>
<tr>
<td><code>16</code> </td>
<td>RailTrack</td>
<td><code>(230, 150, 140)</code></td>
<td>All kind of rail tracks that are non-drivable by cars. <br> E.g. subway and train rail tracks.</td>
<tr>
<td><code>17</code> </td>
<td>GuardRail</td>
<td><code>(180, 165, 180)</code></td>
<td>All types of guard rails/crash barriers.</td>
<tr>
<td><code>18</code> </td>
<td>TrafficLight</td>
<td><code>(250, 170, 30)</code></td>
<td>Traffic light boxes without their poles.</td>
<tr>
<td><code>19</code> </td>
<td>Static</td>
<td><code>(110, 190, 160)</code></td>
<td>Elements in the scene and props that are immovable. <br> E.g. fire hydrants, fixed benches, fountains, bus stops, etc.</td>
<tr>
<td><code>20</code> </td>
<td>Dynamic</td>
<td><code>(170, 120, 50)</code></td>
<td>Elements whose position is susceptible to change over time. <br> E.g. Movable trash bins, buggies, bags, wheelchairs, animals, etc.</td>
<tr>
<td><code>21</code> </td>
<td>Water</td>
<td><code>(45, 60, 150)</code></td>
<td>Horizontal water surfaces. <br> E.g. Lakes, sea, rivers.</td>
<tr>
<td><code>22</code> </td>
<td>Terrain</td>
<td><code>(145, 170, 100)</code></td>
<td>Grass, ground-level vegetation, soil or sand. These areas are not meant to be driven on. This label includes a possibly delimiting curb.</td>
</tbody>
</table>
<br>
@ -1505,8 +1583,6 @@ The following tags are currently available:
**Adding new tags**:
It requires some C++ coding. Add a new label to the `ECityObjectLabel` enum in "Tagger.h", and its corresponding filepath check inside `GetLabelByFolderName()` function in "Tagger.cpp".
![ImageSemanticSegmentation](img/ref_sensors_semantic.jpg)
#### Basic camera attributes
<table class ="defTable">

View File

@ -1,55 +1,74 @@
# ROS bridge installation
* [__Requirements__](#requirements)
* [__Bridge installation__](#bridge-installation)
* a) using apt repository
* b) using source repository
* [__Run the ROS bridge__](#run-the-ros-bridge)
* [__Setting CARLA__](#setting-carla)
The ROS bridge enables two-way communication between ROS and CARLA. The information from the CARLA server is translated to ROS topics. In the same way, the messages sent between nodes in ROS get translated to commands to be applied in CARLA.
---
## Requirements
### ROS Kinetic/Melodic
* __ROS Kinetic/Melodic.__ Install ROS [Melodic](http://wiki.ros.org/melodic/Installation/Ubuntu), for Ubuntu 18.04, or [Kinetic](http://wiki.ros.org/kinetic/Installation), for Ubuntu 16.04. ROS packages may be required, depending on the user needs. [rviz](http://wiki.ros.org/rviz) to visualize ROS data.
* __CARLA 0.9.7 or later.__ Previous versions are not compatible with the ROS bridge. Follow the [quick start installation](start_quickstart.md) or make the build for the corresponding platform.
* [__Requirements__](#requirements)
* [Python2](#python2)
* [__Bridge installation__](#bridge-installation)
* [A. Using Debian repository](#a-using-debian-repository)
* [B. Using source repository](#b-using-source-repository)
* [__Run the ROS bridge__](#run-the-ros-bridge)
* [__Setting CARLA__](#setting-carla)
!!! Important
Make sure that both CARLA and ROS work properly before continuing with the installation.
ROS is still [experimental](http://wiki.ros.org/noetic/Installation) for Windows, so the ROS bridge has only been tested for Linux systems.
---
## Requirements
Make sure that both requirements work properly before continuing with the installation.
* __ROS Kinetic/Melodic__ — Install the ROS version corresponding to your system. Additional ROS packages may be required, depending on the user needs. [rviz](http://wiki.ros.org/rviz) is highly recommended to visualize ROS data.
* [__ROS Melodic__](http://wiki.ros.org/melodic/Installation/Ubuntu) — For Ubuntu 16.04 (Xenial).
* [__ROS Kinetic__](http://wiki.ros.org/kinetic/Installation) — For Ubuntu 18.04 (Bionic).
* [__ROS Noetic__](http://wiki.ros.org/noetic#Installation) — For Ubuntu 20.04 (Focal).
* __CARLA 0.9.7 or later__ — Previous versions are not compatible with the ROS bridge. Follow the [quick start installation](start_quickstart.md) or make the build for [Linux](build_linux.md).
### Python
The version of Python needed to run the ROS bridge depends on the ROS version being used.
* __ROS Melodic__ and __ROS Kinetic__ — Python2.
* __ROS Noetic__ — Python3.
All the CARLA releases provide support for Python3, so ROS Noetic users do not need more preparation. However, ROS Melodic/Kinetic users cannot use the latest CARLA release packages. Since 0.9.10 (included), CARLA does not provide support for Python2, so users will have to make the [build from source](build_linux.md), and compile the PythonAPI for Python2.
* Run the following command in the root CARLA directory of your Linux build to compile the PythonAPI for Python2.
```sh
make PythonAPI ARGS="--python-version=2"
```
---
## Bridge installation
### a) Using apt repository
!!! Important
To install ROS bridge versions prior to 0.9.10, change to a previous version of the documentation using the pannel in the bottom right corner of the window, and follow the old instructions.
Add the apt repository.
### A. Using Debian repository
* __Bridge for ROS Melodic.__
Set up the Debian repository in the system.
```sh
sudo apt-key adv --keyserver keyserver.ubuntu.com --recv-keys 81061A1A042F527D &&
sudo add-apt-repository "deb [arch=amd64 trusted=yes] http://dist.carla.org/carla-ros-bridge-melodic/ bionic main"
sudo apt-key adv --keyserver keyserver.ubuntu.com --recv-keys 1AF1527DE64CB8D9
sudo add-apt-repository "deb [arch=amd64] http://dist.carla.org/carla $(lsb_release -sc) main"
```
Install the ROS bridge, and check for the installation in the `/opt/` folder.
```sh
sudo apt-get update # Update the Debian package index
sudo apt-get install carla-ros-bridge # Install the latest ROS bridge version, or update the current installation
```
* __Bridge for ROS Kinetic.__
This repository contains features from CARLA 0.9.10 and later versions. To install a specific version add the version tag to the installation command.
```sh
sudo apt-key adv --keyserver keyserver.ubuntu.com --recv-keys 9BE2A0CDC0161D6C &&
sudo add-apt-repository "deb [arch=amd64 trusted=yes] http://dist.carla.org/carla-ros-bridge-kinetic xenial main"
sudo apt-get install carla-ros-bridge=0.9.10-1 # In this case, "0.9.10" refers to the ROS bridge version, and "1" to the Debian revision
```
Install the ROS bridge.
```sh
sudo apt update &&
sudo apt install carla-ros-bridge-<melodic or kinetic>
```
### b) Using source repository
### B. Using source repository
A catkin workspace is needed to use the ROS bridge. It should be cloned and built in there. The following code creates a new workspace, and clones the repository in there.
```sh
#setup folder structure
# Setup folder structure
mkdir -p ~/carla-ros-bridge/catkin_ws/src
cd ~/carla-ros-bridge
git clone https://github.com/carla-simulator/ros-bridge.git
@ -57,14 +76,14 @@ cd ros-bridge
git submodule update --init
cd ../catkin_ws/src
ln -s ../../ros-bridge
source /opt/ros/kinetic/setup.bash #Watch out, this sets ROS Kinetic.
source /opt/ros/kinetic/setup.bash # Watch out, this sets ROS Kinetic
cd ..
#install required ros-dependencies
# Install required ros-dependencies
rosdep update
rosdep install --from-paths src --ignore-src -r
#build
# Build
catkin_make
```
@ -74,7 +93,7 @@ catkin_make
__1) Run CARLA.__ The way to do so depends on the CARLA installation.
* __Quick start/release package.__ `./CarlaUE4.sh` in `carla/`.
* __apt installation.__ `./CarlaUE4.sh` in `opt/carla/bin/`.
* __Debian installation.__ `./CarlaUE4.sh` in `opt/carla-simulator/`.
* __Build installation.__ `make launch` in `carla/`.
__2) Add the source path.__ The source path for the workspace has to be added, so that the ROS bridge can be used from a terminal.
@ -111,7 +130,7 @@ roslaunch carla_ros_bridge carla_ros_bridge_with_example_ego_vehicle.launch
</summary>
The path to CARLA Python is missing. The apt installation does this automatically, but it may be missing for other installations. Execute the following command with the complete path to the <i>.egg</i> file (included). Use the one supported by the Python version installed.
<br>
<br><br>
<i><small><b>Note: </b>.egg files may be either in `/PythonAPI/` or `/PythonAPI/dist/` depending on the CARLA installation.</small></i>
```sh
@ -120,7 +139,7 @@ The path to CARLA Python is missing. The apt installation does this automaticall
Import CARLA from Python and wait for a sucess message to check the installation.
```sh
python -c 'import carla;print("Success")'
python3 -c 'import carla;print("Success")'
```
</details>

View File

@ -14,7 +14,7 @@ In order to smooth the process of developing, training and validating driving sy
## The simulator
The CARLA simulator consists of a scalable client-server architecture.
The server is responsible of everything related with the simulation itself: sensor rendering, computation of physics, updates on the world-state and its actors and much more. As it aims for realistic results, the best fit would be running the server with a dedicated GPU, especially when dealing with machine learning.
The server is responsible for everything related with the simulation itself: sensor rendering, computation of physics, updates on the world-state and its actors and much more. As it aims for realistic results, the best fit would be running the server with a dedicated GPU, especially when dealing with machine learning.
The client side consists of a sum of client modules controlling the logic of actors on scene and setting world conditions. This is achieved by leveraging the CARLA API (in Python or C++), a layer that mediates between server and client that is constantly evolving to provide new functionalities.
![CARLA Modules](img/carla_modules.png)

View File

@ -3,11 +3,11 @@
* __[Installation summary](#installation-summary)__
* __[Requirements](#requirements)__
* __[CARLA installation](#carla-installation)__
* a) deb CARLA installation
* b) GitHub repository installation
* [A. Debian CARLA installation](#a-debian-carla-installation)
* [B. Package installation](#b-package-installation)
* __[Import additional assets](#import-additional-assets)__
* __[Running CARLA](#running-carla)__
* Command-line options
* [Command-line options](#command-line-options)
* __[Updating CARLA](#updating-carla)__
* __[Follow-up](#follow-up)__
@ -20,44 +20,36 @@
</summary>
```sh
# Install required modules Pygame and Numpy.
# Install required modules Pygame and Numpy
pip install --user pygame numpy
# Option A) deb package installation of CARLA 0.9.9 (only Linux)
sudo apt-key adv --keyserver keyserver.ubuntu.com --recv-keys 92635A407F7A020C
sudo add-apt-repository "deb [arch=amd64 trusted=yes] http://dist.carla.org/carla-0.9.9/ all main"
# There are two different ways to install CARLA
# Option A) Debian package installation
# This repository contains CARLA 0.9.10 and later. To install previous CARLA versions, change to a previous version of the docs using the pannel in the bottom right part of the window
sudo apt-key adv --keyserver keyserver.ubuntu.com --recv-keys 1AF1527DE64CB8D9
sudo add-apt-repository "deb [arch=amd64] http://dist.carla.org/carla $(lsb_release -sc) main"
sudo apt-get update
sudo apt-get install carla-simulator
cd /opt/carla-simulator/bin
./CarlaUE4.sh
# To install CARLA 0.9.8 instead
sudo apt-key adv --keyserver keyserver.ubuntu.com --recv-keys 304F9BC29914A77D &&
sudo add-apt-repository "deb [arch=amd64 trusted=yes] http://dist.carla.org/carla-0.9.8/ all main"
sudo apt-get update
sudo apt-get install carla-simulator
cd /opt/carla-simulator/bin
./CarlaUE4.sh
# To install CARLA 0.9.7 instead
sudo apt-key adv --keyserver keyserver.ubuntu.com --recv-keys DB53A429E64554FC &&
sudo add-apt-repository "deb [arch=amd64 trusted=yes] http://dist.carla.org/carla-0.9.7/ all main"
sudo apt-get update
sudo apt-get install carla-simulator
cd /opt/carla-simulator/bin
sudo apt-get install carla-simulator # Install the latest CARLA version or update the current installation
sudo apt-get install carla-simulator=0.9.10-1 # install a specific CARLA version
cd /opt/carla-simulator
./CarlaUE4.sh
# Option B) GitHub repository installation
# Option B) Package installation
# Go to: https://github.com/carla-simulator/carla/blob/master/Docs/download.md
# Download the desired package and additional assets.
# Extract the package.
# Download the desired package and additional assets
# Extract the package
# Extract the additional assets in `/Import`
# Run CARLA (Linux)
# Run CARLA (Linux).
./CarlaUE.sh
# Run CARLA (Windows)
> CarlaUE4.exe
# Run a script to test CARLA
# Run a script to test CARLA.
cd PythonAPI/examples
python3 spawn_npc.py
python3 spawn_npc.py # Support for Python2 was provided until 0.9.10 (not included)
# The PythonAPI can be compiled for Python2 when using a Linux build from source
```
</details>
@ -80,24 +72,32 @@ To install both modules using [pip](https://pip.pypa.io/en/stable/installing/),
---
## CARLA installation
The __deb installation__ is the easiest way to get the latest release in Linux.
The __Debian installation__ is the easiest way to get the latest release in Linux.
__Download the GitHub repository__ to get either a specific release or the Windows version of CARLA.
### a) deb CARLA installation
### A. Debian CARLA installation
Add the CARLA 0.9.9 repository to the system.
Set up the Debian repository in the system.
```sh
sudo apt-key adv --keyserver keyserver.ubuntu.com --recv-keys 92635A407F7A020C
sudo add-apt-repository "deb [arch=amd64 trusted=yes] http://dist.carla.org/carla-0.9.9/ all main"
sudo apt-key adv --keyserver keyserver.ubuntu.com --recv-keys 1AF1527DE64CB8D9
sudo add-apt-repository "deb [arch=amd64] http://dist.carla.org/carla $(lsb_release -sc) main"
```
Install CARLA and check for the installation in the `/opt/` folder.
```sh
sudo apt-get update
sudo apt-get install carla-simulator
cd /opt/carla-simulator
sudo apt-get update # Update the Debian package index
sudo apt-get install carla-simulator # Install the latest CARLA version, or update the current installation
cd /opt/carla-simulator # Open the folder where CARLA is installed
```
### b) Package installation
This repository contains CARLA 0.9.10 and later versions. To install a specific version add the version tag to the installation command.
```sh
sudo apt-get install carla-simulator=0.9.10-1 # In this case, "0.9.10" refers to a CARLA version, and "1" to the Debian revision
```
!!! Important
To install CARLA versions prior to 0.9.10, change to a previous version of the documentation using the pannel in the bottom right corner of the window, and follow the old instructions.
### B. Package installation
<div class="build-buttons">
<p>
@ -148,8 +148,13 @@ Now it is time to start running scripts. The following example will spawn some l
# Go to the folder containing example scripts
> cd PythonAPI/examples
> python3 spawn_npc.py
> python3 spawn_npc.py # Support for Python2 was provided until 0.9.10 (not included)
```
!!! Note
The PythonAPI can be compiled for Python2 when using a [Linux build from source](build_linux.md).
#### Command-line options
There are some configuration options available when launching CARLA.
@ -170,7 +175,7 @@ The script `PythonAPI/util/config.py` provides for more configuration options.
> ./config.py --map Town05 # Change map
> ./config.py --weather ClearNoon # Change weather
> ./config.py --help # Check all the available configuration options.
> ./config.py --help # Check all the available configuration options
```
---

View File

@ -85,7 +85,7 @@ chmod 777 input_folder
__2. Run the script to cook the map.__ In the folder `~/carla/Util/Docker` there is a script that connects with the Docker image previously created, and makes the ingestion automatically. It only needs the path for the input and output files, and the name of the package to be ingested. If no `.json` is provided, the name must be `map_package`.
```sh
python docker_tools.py --input ~/path_to_input_folder --output ~/path_to_output_folder --packages map_package
python3 docker_tools.py --input ~/path_to_input_folder --output ~/path_to_output_folder --packages map_package
```
!!! Warning
If the argument `--package <package_name>` is not provided, the Docker will make a package of CARLA.

View File

@ -57,22 +57,30 @@ __Props__ need the following parameters.
* `medium`
* `big`
* `huge`
* __tag__ value for the semantic segmentation. If the tag is misspelled, it will be read as `None`.
* `None`
* `Buildings`
* `Fences`
* `Pedestrians`
* __tag__ value for the semantic segmentation. If the tag is misspelled, it will be read as `Unlabeled`.
* `Bridge`
* `Building`
* `Dynamic`
* `Fence`
* `Ground`
* `GuardRail`
* `Other`
* `Pedestrian`
* `Pole`
* `Props`
* `RailTrack`
* `Road`
* `RoadLines`
* `Sidewalk`
* `RoadLine`
* `SideWalk`
* `Sky`
* `Static`
* `Terrain`
* `TrafficSigns`
* `TrafficLight`
* `TrafficSign`
* `Unlabeled`
* `Vegetation`
* `Vehicles`
* `Walls`
* `Wall`
* `Water`
In the end, the `.json` should look similar to the one below.
@ -111,7 +119,7 @@ __1. Build a Docker image of Unreal Engine.__ Follow [these instructions](https:
__2. Run the script to cook the props.__ In the folder `~/carla/Util/Docker` there is a script that connects with the Docker image previously created, and makes the ingestion automatically. It only needs the path for the input and output files, and the name of the package to be ingested.
```sh
python docker_tools.py --input ~/path_to_package --output ~/path_for_output_assets --package=Package01
python3 docker_tools.py --input ~/path_to_package --output ~/path_for_output_assets --package=Package01
```
__3. Locate the package__. The Docker should have generated the package `Package01.tar.gz` in the output path. This is the standalone package for the assets.

View File

@ -111,7 +111,7 @@ __4. Export the result__. Select all the meshes and the base of the skeleton a
* __11. Test the vehicle__. Launch CARLA, open a terminal in `PythonAPI/examples` and run the following command.
```sh
python manual_control.py --filter <model_name> # The name used in step 10.2
python3 manual_control.py --filter <model_name> # The name used in step 10.2
```
---

View File

@ -2,8 +2,8 @@
It is a common practice in CARLA to manage assets with standalone packages. Keeping them aside allows to reduce the size of the build. These asset packages can be easily imported into a CARLA package anytime. They also become really useful to easily distribute assets in an organized way.
* [__Export a package from the UE4 Editor__](#export-a-package-from-the-ue4-editor)
* [__Import assets into a CARLA package__](#import-assets-into-a-carla-package)
* [__Export a package from the UE4 Editor__](#export-a-package-from-the-ue4-editor)
* [__Import assets into a CARLA package__](#import-assets-into-a-carla-package)
---
## Export a package from the UE4 Editor

View File

@ -1,9 +1,16 @@
# How to model vehicles
* [__4-wheeled Vehicles__](#4-wheeled-vehicles)
* [Modelling](#modelling)
* [Naming materials](#naming-materials)
* [Texturing](#texturing)
* [Rigging](#rigging)
* [LODs](#lods)
---
## 4-Wheeled Vehicles
#### Modelling
### Modelling
Vehicles must have a minimum of 10.000 and a maximum of 17.000 Tris
approximately. We model the vehicles using the size and scale of actual cars.
@ -36,7 +43,7 @@ The vehicle must be divided in 6 materials:
Put a rectangular plane with this size 29-12 cm, for the licence Plate.
We assign the license plate texture.
#### Nomenclature of Material
### Naming materials
* M(Material)_"CarName"_Bodywork(part of car)
@ -50,7 +57,7 @@ The vehicle must be divided in 6 materials:
* M_"CarName"_LicencePlate
#### Textures
### Texturing
The size of the textures is 2048x2048.
@ -71,7 +78,7 @@ TEXTURES
MATERIAL
* M_Tesla3_BodyWork
#### RIG
### Rigging
The easiest way is to copy the "General4WheeledVehicleSkeleton" present in our project,
either by exporting it and copying it to your model or by creating your skeleton

View File

@ -5,6 +5,19 @@ the necessary steps to implement a sensor in Unreal Engine 4 (UE4) and expose
its data via CARLA's Python API. We'll follow all the steps by creating a new
sensor as an example.
* [__Prerequisites__](#prerequisites)
* [__Introduction__](#introduction)
* [__Creating a new sensor__](#creating-a-new-sensor)
* [1- Sensor actor](#1-sensor-actor)
* [2- Sensor data serializer](#2-sensor-data-serializer)
* [3- Sensor data object](#3-sensor-data-object)
* [4- Register your sensor](#4-register-your-sensor)
* [5- Usage example](#5-usage-example)
* [__Appendix__](#appendix)
* [Reusing buffers](#reusing-buffers)
* [Sending data asynchronously](#sending-data-asynchronously)
* [Client-side sensors](#client-side-sensors)
---
## Prerequisites
@ -71,8 +84,7 @@ _For the sake of simplicity we're not going to take into account all the edge
cases, nor it will be implemented in the most efficient way. This is just an
illustrative example._
---
### 1. The sensor actor
### 1- Sensor actor
This is the most complicated class we're going to create. Here we're running
inside Unreal Engine framework, knowledge of UE4 API will be very helpful but
@ -295,8 +307,7 @@ that, the data is going to travel through several layers. First of them will be
the serializer that we have to create next. We'll fully understand this part
once we have completed the `Serialize` function in the next section.
---
### 2. The sensor data serializer
### 2- Sensor data serializer
This class is actually rather simple, it's only required to have two static
methods, `Serialize` and `Deserialize`. We'll add two files for it, this time to
@ -365,8 +376,8 @@ SharedPtr<SensorData> SafeDistanceSerializer::Deserialize(RawData &&data) {
except for the fact that we haven't defined yet what's a `SafeDistanceEvent`.
---
### 3. The sensor data object
### 3- Sensor data object
We need to create a data object for the users of this sensor, representing the
data of a _safe distance event_. We'll add this file to
@ -431,8 +442,7 @@ What we're doing here is exposing some C++ methods in Python. Just with this,
the Python API will be able to recognise our new event and it'll behave similar
to an array in Python, except that cannot be modified.
---
### 4. Register your sensor
### 4- Register your sensor
Now that the pipeline is complete, we're ready to register our new sensor. We do
so in _LibCarla/source/carla/sensor/SensorRegistry.h_. Follow the instruction in
@ -454,8 +464,7 @@ be a bit cryptic.
make rebuild
```
---
### 5. Usage example
### 5- Usage example
Finally, we have the sensor included and we have finished recompiling, our
sensor by now should be available in Python.
@ -493,7 +502,9 @@ Vehicle too close: vehicle.mercedes-benz.coupe
That's it, we have a new sensor working!
---
## Appendix: Reusing buffers
## Appendix
### Reusing buffers
In order to optimize memory usage, we can use the fact that each sensor sends
buffers of similar size; in particularly, in the case of cameras, the size of
@ -530,8 +541,7 @@ buffer.reset(512u); // (size 512 bytes, capacity 1024 bytes)
buffer.reset(2048u); // (size 2048 bytes, capacity 2048 bytes) -> allocates
```
---
## Appendix: Sending data asynchronously
### Sending data asynchronously
Some sensors may require to send data asynchronously, either for performance or
because the data is generated in a different thread, for instance, camera sensors send
@ -554,8 +564,7 @@ void MySensor::Tick(float DeltaSeconds)
}
```
---
## Appendix: Client-side sensors
### Client-side sensors
Some sensors do not require the simulator to do their measurements, those
sensors may run completely in the client-side freeing the simulator from extra

View File

@ -0,0 +1,237 @@
# Customize vehicle suspension
This tutorial covers the basics of the suspension system for CARLA vehicles, and how are these implemented for the different vehicles available. Use this information to access the suspension parameterization of a vehicle in Unreal Engine, and customize it at will.
* [__Basics of the suspension system__](#basics-of-the-suspension-system)
* [__Suspension groups__](#suspension-groups)
* [Coupe](#coupe)
* [Off-road](#off-road)
* [Truck](#truck)
* [Urban](#urban)
* [Van](#van)
---
## Basics of the suspension system
The suspension system of a vehicle is defined by the wheels of said vehicle. Each wheel has an independent blueprint with some parameterization, which includes the suspension system.
These blueprints can be found in `Content/Carla/Blueprints/Vehicles/<vehicle_name>`. They are named such as: `BP_<vehicle_name>_<F/R><R/L>W`.
* `F` or `R` is used for front or rear wheels correspondingly.
* `R` or `L` is used for right or left wheels correspondingly.
![tuto_suspension_blueprints](img/tuto_suspension_blueprints.jpg)
<div style="text-align: right"><i>In this example, the blueprint of the front left wheel of the Audi A2 is named as <code>BP_AudiA2_FLW</code>.</i></div>
`shape_radius` for the wheel to rest over the road, neither hovering nor inside of it.
Inside the blueprint, there is a section with some parameterization regarding the suspension of the wheel. Here are their definitions as described in Unreal Engine.
* `Suspension Force Offset` — Vertical offset from where suspension forces are applied (along Z axis).
* `Suspension Max Raise` — How far the wheel can go above the resting position.
* `Suspension Max Drop` — How far the wheel can drop below the resting position.
* `Suspension Natural Frequency` — Oscillation frequency of the suspension. Standard cars have values between `5` and `10`.
* `Suspension Damping Ratio` — The rate at which energy is dissipated from the spring. Standard cars have values between `0.8` and `1.2`. Values `<1` are more sluggish, values `>1` are more twitchy.
* `Sweep Type` — Wether wheel suspension considers simple, complex or both.
![tuto_suspension_parameterization](img/tuto_suspension_parameterization.jpg)
<div style="text-align: right"><i>The Suspension panel inside a wheel blueprint.</i></div>
!!! Note
By default, all the wheels of a vehicle have the same parameterization in CARLA. The following explanations will be covered per vehicle, instead of per wheel.
---
## Suspension groups
According to their system suspension, vehicles in CARLA can be classified in five groups. All the vehicles in a group have the same parameterization, as they are expected to have a similar behaviour on the road. The suspension of a vehicle can be modified at will, and is no subject to these five groups. However understanding these, and observing their behaviour in the simulation can be of great use to define a custom suspension.
The five groups are: *Coupe*, *Off-road*, *Truck*, *Urban*, and *Van*. In closer observation, the parameterization of these groups follows a specific pattern.
<table class ="defTable">
<tbody>
<td><b>Stiff suspension</b></td>
<td>Coupe</td>
<td>Urban</td>
<td>Van</td>
<td>Off-road</td>
<td>Truck</td>
<td><b>Soft suspension</b></td>
</tbody>
</table>
<br>
When moving from a soft to a stiff suspension, there are some clear tendencies in the parameterization.
* __Decrease__ of `Suspension Max Raise` and `Suspension Max Drop` — Stiff vehicles are meant to drive over plane roads with no bumps. For the sake of aerodynamics, the chassis is not supposed to move greatly, but remain constantly close to the ground.
* __Increase__ of `Suspension Damping Ratio` — The absortion of the bouncing by the dampers is greater for stiff vehicles.
### Coupe
Vehicles with the stiffest suspension.
<table class ="defTable">
<thead>
<th>Parameterization</th>
<th>Vehicles</th>
</thead>
<tbody>
<td>
<code>Suspension Force Offset</code><code>0.0</code><br>
<code>Suspension Max Raise</code><code>7.5</code><br>
<code>Suspension Max Drop</code><code>7.5</code><br>
<code>Suspension Natural Frequency</code><code>9.5</code><br>
<code>Suspension Damping Ratio</code><code>1.0</code><br>
<code>Sweep Type</code><code>SimpleAndComplex</code><br>
</td>
<td>
<code>vehicle.audi.tt</code><br>
<code>vehicle.lincoln.mkz2017</code><br>
<code>vehicle.mercedes-benz.coupe</code><br>
<code>vehicle.seat.leon</code><br>
<code>vehicle.tesla.model3</code><br>
</td>
</tbody>
</table>
<br>
### Off-road
Vehicles with a soft suspension.
<table class ="defTable">
<thead>
<th>Parameterization</th>
<th>Vehicles</th>
</thead>
<tbody>
<td>
<code>Suspension Force Offset</code><code>0.0</code><br>
<code>Suspension Max Raise</code><code>15.0</code><br>
<code>Suspension Max Drop</code><code>15.0</code><br>
<code>Suspension Natural Frequency</code><code>7.0</code><br>
<code>Suspension Damping Ratio</code><code>0.5</code><br>
<code>Sweep Type</code><code>SimpleAndComplex</code><br>
</td>
<td>
<code>vehicle.audi.etron</code><br>
<code>vehicle.jeep.wrangler_rubicon</code><br>
<code>vehicle.nissan.patrol</code><br>
<code>vehicle.tesla.cybertruck</code><br>
</td>
</tbody>
</table>
<br>
### Truck
Vehicles with the softest suspension.
<table class ="defTable">
<thead>
<th>Parameterization</th>
<th>Vehicles</th>
</thead>
<tbody>
<td>
<code>Suspension Force Offset</code><code>0.0</code><br>
<code>Suspension Max Raise</code><code>17.0</code><br>
<code>Suspension Max Drop</code><code>17.0</code><br>
<code>Suspension Natural Frequency</code><code>6.0</code><br>
<code>Suspension Damping Ratio</code><code>0.4</code><br>
<code>Sweep Type</code><code>SimpleAndComplex</code><br>
</td>
<td>
<code>vehicle.carlamotors.carlacola</code><br>
</td>
</tbody>
</table>
<br>
### Urban
Vehicles with a soft suspension.
<table class ="defTable">
<thead>
<th>Parameterization</th>
<th>Vehicles</th>
</thead>
<tbody>
<td>
<code>Suspension Force Offset</code><code>0.0</code><br>
<code>Suspension Max Raise</code><code>8.0</code><br>
<code>Suspension Max Drop</code><code>8.0</code><br>
<code>Suspension Natural Frequency</code><code>9.0</code><br>
<code>Suspension Damping Ratio</code><code>0.8</code><br>
<code>Sweep Type</code><code>SimpleAndComplex</code><br>
</td>
<td>
<code>vehicle.audi.a2</code><br>
<code>vehicle.bmw.grandtourer</code><br>
<code>vehicle.chevrolet.impala</code><br>
<code>vehicle.citroen.c3</code><br>
<code>vehicle.dodge_charger.police</code><br>
<code>vehicle.mini.cooperst</code><br>
<code>vehicle.mustang.mustang</code><br>
<code>vehicle.nissan.micra</code><br>
<code>vehicle.toyota.prius</code><br>
</td>
</tbody>
</table>
<br>
### Van
Vehicles with a middle-ground suspension.
<table class ="defTable">
<thead>
<th>Parameterization</th>
<th>Vehicles</th>
</thead>
<tbody>
<td>
<code>Suspension Force Offset</code><code>0.0</code><br>
<code>Suspension Max Raise</code><code>9.0</code><br>
<code>Suspension Max Drop</code><code>9.0</code><br>
<code>Suspension Natural Frequency</code><code>8.0</code><br>
<code>Suspension Damping Ratio</code><code>0.8</code><br>
<code>Sweep Type</code><code>SimpleAndComplex</code><br>
</td>
<td>
<code>vehicle.volkswagen.t2</code><br>
</td>
</tbody>
</table>
<br>
---
Use the forum to post any doubts, issues or suggestions regarding this topic.
<div class="build-buttons">
<p>
<a href="https://forum.carla.org/" target="_blank" class="btn btn-neutral" title="Go to the CARLA forum">
CARLA forum</a>
</p>
</div>
Here are some advised readings after this one.
<div class="build-buttons">
<p>
<a href="../tuto_G_control_vehicle_physics" target="_blank" class="btn btn-neutral" title= "Set runtime changes on a vehicle physics.">
Control vehicle physics</a>
</p>
<p>
<a href="../tuto_G_add_friction_triggers" target="_blank" class="btn btn-neutral" title= "Define dynamic box triggers for wheels.">
Add friction triggers</a>
</p>
<p>
<a href="../tuto_D_generate_colliders" target="_blank" class="btn btn-neutral" title="Create detailed colliders for vehicles">
Generate detailed colliders</a>
</p>
</div>

View File

@ -1,8 +1,5 @@
# How to generate the pedestrian navigation info
---
## Introduction
The pedestrians to walk need information about the map in a specific format. That file that describes the map for navigation is a binary file with extension `.BIN`, and they are saved in the **Nav** folder of the map. Each map needs a `.BIN` file with the same name that the map, so automatically can be loaded with the map.
This `.BIN` file is generated from the Recast & Detour library and has all the information that allows pathfinding and crow management.
@ -18,13 +15,34 @@ If we need to generate this `.BIN` file for a custom map, we need to follow this
We have several types of meshes for navigation. The meshes need to be identified as one of those types, using specific nomenclature.
| Type | Start with | Description |
|-----------|------------|-------------|
| Ground | `Road_Sidewalk` | Pedestrians can walk over these meshes freely (sidewalks...). |
| Grass | `Road_Crosswalk` | Pedestrians can walk over these meshes but as a second option if no ground is found. |
| Road | `Road_Grass` | Pedestrians won't be allowed to walk on it unless we specify some percentage of pedestrians that will be allowed. |
| Crosswalk | `Road_Road`, `Road_Curb`, `Road_Gutter` or `Road_Marking` | Pedestrians can cross the roads only through these meshes. |
| Block | any other name | Pedestrians will avoid these meshes always (are obstacles like traffic lights, trees, houses...). |
<table class ="defTable">
<thead>
<th>Type</th>
<th>Start with</th>
<th>Description</th>
</thead>
<tbody>
<td>Ground</td>
<td><code>Road_Sidewalk</code></td>
<td>Pedestrians can walk over these meshes freely (sidewalks...).</td>
<tr>
<td>Grass</td>
<td><code>Road_Crosswalk</code></td>
<td>Pedestrians can walk over these meshes but as a second option if no ground is found.</td>
<tr>
<td>Road</td>
<td><code>Road_Grass</code></td>
<td>Pedestrians won't be allowed to walk on it unless we specify some percentage of pedestrians that will be allowed.</td>
<tr>
<td>Crosswalk</td>
<td><code>Road_Road</code>, <code>Road_Curb</code>, <code>Road_Gutter</code>, <code>Road_Marking</code></td>
<td>Pedestrians can cross the roads only through these meshes.</td>
<tr>
<td>Block</td>
<td>Any other name</td>
<td>Pedestrians will avoid these meshes always (are obstacles like traffic lights, trees, houses...).</td>
</tbody>
</table>
<br>

View File

@ -5,6 +5,12 @@ skeletons of walkers from the CARLA Python API. The reference of
all classes and methods available can be found at
[Python API reference](python_api.md).
* [__Walker skeleton structure__](#walker-skeleton-structure)
* [__Manually control walker bones__](#manually-control-walker-bones)
* [Connect to the simulator](#connect-to-the-simulator)
* [Spawn a walker](#spawn-a-walker)
* [Control walker skeletons](#control-walker-skeletons)
!!! note
**This document assumes the user is familiar with the Python API**. <br>
The user should read the first steps tutorial before reading this document.
@ -86,12 +92,12 @@ crl_root
```
---
## How to manually control a walker's bones
## Manually control walker bones
Following is a detailed step-by-step example of how to change the bone transforms of a walker
from the CARLA Python API
#### Connecting to the simulator
### Connect to the simulator
Import neccessary libraries used in this example
@ -107,7 +113,7 @@ client = carla.Client('127.0.0.1', 2000)
client.set_timeout(2.0)
```
#### Spawning a walker
### Spawn a walker
Spawn a random walker at one of the map's spawn points
@ -119,7 +125,7 @@ spawn_point = random.choice(spawn_points) if spawn_points else carla.Transform()
world.try_spawn_actor(blueprint, spawn_point)
```
#### Controlling a walker's skeleton
### Control walker skeletons
A walker's skeleton can be modified by passing an instance of the WalkerBoneControl class
to the walker's apply_control function. The WalkerBoneControl class contains the transforms

View File

@ -91,15 +91,18 @@ world = client.generate_opendrive_world(
__b) Using `config.py`__ — The script can load an OpenStreetMap file directly into CARLA using a new argument.
```
config.py --osm-file=/path/to/OSM/file
python3 config.py --osm-file=/path/to/OSM/file
```
!!! Warning
!!! Important
[client.generate_opendrive_world()](python_api.md#carla.Client.generate_opendrive_world) requires the __content of the OpenDRIVE file parsed as string__, and allows parameterization. On the contrary, __`config.py`__ script needs __the path to the `.xodr` file__ and always uses default parameters.
Either way, the map should be ingested automatically in CARLA and the result should be similar to this.
![opendrive_meshissue](img/tuto_g_osm_carla.jpg)
<div style="text-align: right"><i>Outcome of the CARLA map generation using OpenStreetMap.</i></div>
!!! Warning
The roads generated end abruptly in the borders of the map. This will cause the TM to crash when vehicles are not able to find the next waypoint. To avoid this, the OSM mode is set to __True__ by default ([set_osm_mode()](python_api.md#carlatrafficmanager)). This will show a warning, and destroy vehicles when necessary.
---
That is all there is to know about how to use OpenStreetMap to generate CARLA maps.

View File

@ -4,39 +4,39 @@ Learning an efficient way to retrieve simulation data is essential in CARLA. Thi
First, the simulation is initialized with custom settings and traffic. An ego vehicle is set to roam around the city, optionally with some basic sensors. The simulation is recorded, so that later it can be queried to find the highlights. After that, the original simulation is played back, and exploited to the limit. New sensors can be added to retrieve consistent data. The weather conditions can be changed. The recorder can even be used to test specific scenarios with different outputs.
* [__Overview__](#overview)
* [__Set the simulation__](#set-the-simulation)
* [Map setting](#map-setting)
* [Weather setting](#weather-setting)
* [__Set traffic__](#set-traffic)
* [CARLA traffic and pedestrians](#carla-traffic-and-pedestrians)
* [SUMO co-simulation traffic](#sumo-co-simulation-traffic)
* [__Set the ego vehicle__](#set-the-ego-vehicle)
* [Spawn the ego vehicle](#spawn-the-ego-vehicle)
* [Place the spectator](#place-the-spectator)
* [__Set basic sensors__](#set-basic-sensors)
* [RGB camera](#rgb-camera)
* [Detectors](#detectors)
* [Other sensors](#other-sensors)
* [__Set advanced sensors__](#set-advanced-sensors)
* [Depth camera](#depth-camera)
* [Semantic segmentation camera](#semantic-segmentation-camera)
* [LIDAR raycast sensor](#lidar-raycast-sensor)
* [Radar sensor](#radar-sensor)
* [__No-rendering-mode__](#no-rendering-mode)
* [Simulate at a fast pace](#simulate-at-a-fast-pace)
* [Manual control without rendering](#manual-control-without-rendering)
* [__Record and retrieve data__](#record-and-retrieve-data)
* [Start recording](#start-recording)
* [Capture and record](#capture-and-record)
* [Stop recording](#stop-recording)
* [__Exploit the recording__](#exploit-the-recording)
* [Query the events](#query-the-events)
* [Choose a fragment](#choose-a-fragment)
* [Retrieve more data](#retrieve-more-data)
* [Change the weather](#change-the-weather)
* [Try new outcomes](#try-new-outcomes)
* [__Tutorial scripts__](#tutorial-scripts)
* [__Overview__](#overview)
* [__Set the simulation__](#set-the-simulation)
* [Map setting](#map-setting)
* [Weather setting](#weather-setting)
* [__Set traffic__](#set-traffic)
* [CARLA traffic and pedestrians](#carla-traffic-and-pedestrians)
* [SUMO co-simulation traffic](#sumo-co-simulation-traffic)
* [__Set the ego vehicle__](#set-the-ego-vehicle)
* [Spawn the ego vehicle](#spawn-the-ego-vehicle)
* [Place the spectator](#place-the-spectator)
* [__Set basic sensors__](#set-basic-sensors)
* [RGB camera](#rgb-camera)
* [Detectors](#detectors)
* [Other sensors](#other-sensors)
* [__Set advanced sensors__](#set-advanced-sensors)
* [Depth camera](#depth-camera)
* [Semantic segmentation camera](#semantic-segmentation-camera)
* [LIDAR raycast sensor](#lidar-raycast-sensor)
* [Radar sensor](#radar-sensor)
* [__No-rendering-mode__](#no-rendering-mode)
* [Simulate at a fast pace](#simulate-at-a-fast-pace)
* [Manual control without rendering](#manual-control-without-rendering)
* [__Record and retrieve data__](#record-and-retrieve-data)
* [Start recording](#start-recording)
* [Capture and record](#capture-and-record)
* [Stop recording](#stop-recording)
* [__Exploit the recording__](#exploit-the-recording)
* [Query the events](#query-the-events)
* [Choose a fragment](#choose-a-fragment)
* [Retrieve more data](#retrieve-more-data)
* [Change the weather](#change-the-weather)
* [Try new outcomes](#try-new-outcomes)
* [__Tutorial scripts__](#tutorial-scripts)
---
## Overview
@ -87,7 +87,7 @@ Open a new terminal. Change the map using the __config.py__ script.
```
cd /opt/carla/PythonAPI/utils
./config.py --map Town01
python3 config.py --map Town01
```
This script can enable different settings. Some of them will be mentioned during the tutorial, others will not. Hereunder there is a brief summary.
@ -133,14 +133,14 @@ Each town is loaded with a specific weather that fits it, however this can be se
```sh
cd /opt/carla/PythonAPI/examples
python dynamic_weather.py --speed 1.0
python3 dynamic_weather.py --speed 1.0
```
* __To set custom conditions__. Use the script __environment.py__. There are quite a lot of possible settings. Take a look at the optional arguments, and the documentation for [carla.WeatherParameters](python_api.md#carla.WeatherParameters).
```sh
cd /opt/carla/PythonAPI/util
python environment.py --clouds 100 --rain 80 --wetness 100 --puddles 60 --wind 80 --fog 50
python3 environment.py --clouds 100 --rain 80 --wetness 100 --puddles 60 --wind 80 --fog 50
```
<details>
@ -182,7 +182,7 @@ Open a new terminal, and run __spawn_npc.py__ to spawn vehicles and walkers. Let
```sh
cd /opt/carla/PythonAPI/examples
python spawn_npc.py -n 50 -w 50 --safe
python3 spawn_npc.py -n 50 -w 50 --safe
```
<details>
<summary> Optional arguments in <b>spawn_npc.py</b> </summary>
@ -228,7 +228,7 @@ echo "export SUMO_HOME=/usr/share/sumo" >> ~/.bashrc && source ~/.bashrc
* With the CARLA server on, run the [SUMO-CARLA synchrony script](https://github.com/carla-simulator/carla/blob/master/Co-Simulation/Sumo/run_synchronization.py).
```sh
cd ~/carla/Co-Simulation/Sumo
python run_synchronization.py examples/Town01.sumocfg --sumo-gui
python3 run_synchronization.py examples/Town01.sumocfg --sumo-gui
```
* A SUMO window should have opened. __Press Play__ in order to start traffic in both simulations.
```
@ -632,7 +632,7 @@ The same `config.py` used to [set the map](#map-setting) can disable rendering,
```
cd /opt/carla/PythonAPI/utils
./config.py --no-rendering --delta-seconds 0.05 # Never greater than 0.1s
python3 config.py --no-rendering --delta-seconds 0.05 # Never greater than 0.1s
```
!!! Warning
@ -644,12 +644,12 @@ The script `PythonAPI/examples/no_rendering_mode.py` provides an overview of the
```
cd /opt/carla/PythonAPI/examples
python manual_control.py
python3 manual_control.py
```
```
cd /opt/carla/PythonAPI/examples
python no_rendering_mode.py --no-rendering
python3 no_rendering_mode.py --no-rendering
```
<details>
@ -712,7 +712,7 @@ while True:
```
cd /opt/carla/PythonAPI/examples
python manual_control.py
python3 manual_control.py
```
!!! Note
@ -742,7 +742,7 @@ It is time to run a new simulation.
To reenact the simulation, [choose a fragment](#choose-a-fragment) and run the script containing the code for the playback.
```sh
python tuto_replay.py
python3 tuto_replay.py
```
### Query the events

70
Jenkinsfile vendored
View File

@ -43,7 +43,7 @@ pipeline
{
steps
{
sh 'make setup ARGS="--python3-version=3.7"'
sh 'make setup ARGS="--python-version=3.7"'
}
}
stage('ubuntu build')
@ -51,7 +51,7 @@ pipeline
steps
{
sh 'make LibCarla'
sh 'make PythonAPI ARGS="--python3-version=3.7"'
sh 'make PythonAPI ARGS="--python-version=3.7"'
sh 'make CarlaUE4Editor'
sh 'make examples'
}
@ -68,7 +68,7 @@ pipeline
{
steps
{
sh 'make check ARGS="--all --xml --python3-version=3.7"'
sh 'make check ARGS="--all --xml --python-version=3.7"'
}
post
{
@ -90,8 +90,8 @@ pipeline
{
steps
{
sh 'make package ARGS="--python3-version=3.7"'
sh 'make package ARGS="--packages=AdditionalMaps --clean-intermediate --python3-version=3.7"'
sh 'make package ARGS="--python-version=3.7"'
sh 'make package ARGS="--packages=AdditionalMaps --clean-intermediate --python-version=3.7"'
sh 'make examples ARGS="localhost 3654"'
}
post
@ -102,9 +102,64 @@ pipeline
stash includes: 'Dist/CARLA*.tar.gz', name: 'ubuntu_package'
stash includes: 'Examples/', name: 'ubuntu_examples'
}
success
{
node('master')
{
script
{
JOB_ID = "${env.BUILD_TAG}"
jenkinsLib = load("/home/jenkins/jenkins.groovy")
jenkinsLib.CreateUbuntuTestNode(JOB_ID)
}
}
}
}
}
stage('ubuntu deploy')
stage('ubuntu smoke tests')
{
agent { label "ubuntu && gpu && ${JOB_ID}" }
steps
{
unstash name: 'ubuntu_eggs'
unstash name: 'ubuntu_package'
unstash name: 'ubuntu_examples'
sh 'tar -xvzf Dist/CARLA*.tar.gz -C Dist/'
sh 'DISPLAY= ./Dist/CarlaUE4.sh -opengl --carla-rpc-port=3654 --carla-streaming-port=0 -nosound > CarlaUE4.log &'
sh 'make smoke_tests ARGS="--xml --python-version=3.7"'
sh 'make run-examples ARGS="localhost 3654"'
}
post
{
always
{
archiveArtifacts 'CarlaUE4.log'
junit 'Build/test-results/smoke-tests-*.xml'
deleteDir()
node('master')
{
script
{
JOB_ID = "${env.BUILD_TAG}"
jenkinsLib = load("/home/jenkins/jenkins.groovy")
jenkinsLib.DeleteUbuntuTestNode(JOB_ID)
}
}
}
}
}
stage('ubuntu deploy dev')
{
when { branch "dev"; }
steps
{
sh 'git checkout .'
sh 'make deploy ARGS="--replace-latest"'
}
}
stage('ubuntu deploy master')
{
when { anyOf { branch "master"; buildingTag() } }
steps
@ -121,6 +176,7 @@ pipeline
sh 'rm -rf ~/carla-simulator.github.io/Doxygen'
sh '''
cd ~/carla-simulator.github.io
git remote set-url origin git@github.com:carla-simulator/carla-simulator.github.io.git
git fetch
git checkout -B master origin/master
'''
@ -237,7 +293,7 @@ pipeline
}
stage('windows deploy')
{
when { anyOf { branch "master"; buildingTag() } }
when { anyOf { branch "master"; branch "dev"; buildingTag() } }
steps {
bat """
call ../setEnv64.bat

View File

@ -75,6 +75,11 @@ if (WIN32)
# Install zlib lib.
file(GLOB libpng_libraries "${LIBPNG_LIB_PATH}/*")
install(FILES ${libpng_libraries} DESTINATION lib)
else ()
# Install libpng library
install(DIRECTORY "${LIBPNG_INCLUDE_PATH}" DESTINATION include/system)
file(GLOB libcarla_carla_libpnglib "${LIBPNG_LIB_PATH}/*.*")
install(FILES ${libcarla_carla_libpnglib} DESTINATION lib)
endif (WIN32)
# Add sources.
@ -257,7 +262,8 @@ if (LIBCARLA_BUILD_RELEASE)
target_include_directories(carla_client${carla_target_postfix} SYSTEM PRIVATE
"${BOOST_INCLUDE_PATH}"
"${RPCLIB_INCLUDE_PATH}"
"${RECAST_INCLUDE_PATH}")
"${RECAST_INCLUDE_PATH}"
"${LIBPNG_INCLUDE_PATH}")
if (BUILD_RSS_VARIANT)
target_compile_definitions(carla_client${carla_target_postfix} PRIVATE RSS_ENABLED RSS_USE_TBB)
@ -296,7 +302,8 @@ if (LIBCARLA_BUILD_DEBUG)
target_include_directories(carla_client${carla_target_postfix}_debug SYSTEM PRIVATE
"${BOOST_INCLUDE_PATH}"
"${RPCLIB_INCLUDE_PATH}"
"${RECAST_INCLUDE_PATH}")
"${RECAST_INCLUDE_PATH}"
"${LIBPNG_INCLUDE_PATH}")
if (BUILD_RSS_VARIANT)
target_compile_definitions(carla_client${carla_target_postfix}_debug PRIVATE RSS_ENABLED RSS_USE_TBB)

View File

@ -48,7 +48,8 @@ foreach(target ${build_targets})
target_include_directories(${target} SYSTEM PRIVATE
"${BOOST_INCLUDE_PATH}"
"${RPCLIB_INCLUDE_PATH}"
"${GTEST_INCLUDE_PATH}")
"${GTEST_INCLUDE_PATH}"
"${LIBPNG_INCLUDE_PATH}")
target_include_directories(${target} PRIVATE
"${libcarla_source_path}/test")

View File

@ -12,6 +12,7 @@
#include "carla/Time.h"
#include <boost/asio/io_context.hpp>
#include <boost/asio/post.hpp>
#include <future>
#include <thread>
@ -40,7 +41,7 @@ namespace carla {
std::future<ResultT> Post(FunctorT &&functor) {
auto task = std::packaged_task<ResultT()>(std::forward<FunctorT>(functor));
auto future = task.get_future();
_io_context.post(carla::MoveHandler(task));
boost::asio::post(_io_context, carla::MoveHandler(task));
return future;
}

View File

@ -40,22 +40,46 @@ namespace client {
GetEpisode().Lock()->SetActorTransform(*this, transform);
}
void Actor::SetVelocity(const geom::Vector3D &vector) {
GetEpisode().Lock()->SetActorVelocity(*this, vector);
void Actor::SetTargetVelocity(const geom::Vector3D &vector) {
GetEpisode().Lock()->SetActorTargetVelocity(*this, vector);
}
void Actor::SetAngularVelocity(const geom::Vector3D &vector) {
GetEpisode().Lock()->SetActorAngularVelocity(*this, vector);
void Actor::SetTargetAngularVelocity(const geom::Vector3D &vector) {
GetEpisode().Lock()->SetActorTargetAngularVelocity(*this, vector);
}
void Actor::AddImpulse(const geom::Vector3D &vector) {
GetEpisode().Lock()->AddActorImpulse(*this, vector);
void Actor::EnableConstantVelocity(const geom::Vector3D &vector) {
GetEpisode().Lock()->EnableActorConstantVelocity(*this, vector);
}
void Actor::DisableConstantVelocity() {
GetEpisode().Lock()->DisableActorConstantVelocity(*this);
}
void Actor::AddImpulse(const geom::Vector3D &impulse) {
GetEpisode().Lock()->AddActorImpulse(*this, impulse);
}
void Actor::AddImpulse(const geom::Vector3D &impulse, const geom::Vector3D &location) {
GetEpisode().Lock()->AddActorImpulse(*this, impulse, location);
}
void Actor::AddForce(const geom::Vector3D &force) {
GetEpisode().Lock()->AddActorForce(*this, force);
}
void Actor::AddForce(const geom::Vector3D &force, const geom::Vector3D &location) {
GetEpisode().Lock()->AddActorForce(*this, force, location);
}
void Actor::AddAngularImpulse(const geom::Vector3D &vector) {
GetEpisode().Lock()->AddActorAngularImpulse(*this, vector);
}
void Actor::AddTorque(const geom::Vector3D &torque) {
GetEpisode().Lock()->AddActorTorque(*this, torque);
}
void Actor::SetSimulatePhysics(const bool enabled) {
GetEpisode().Lock()->SetActorSimulatePhysics(*this, enabled);
}

View File

@ -64,18 +64,36 @@ namespace client {
/// Teleport and rotate the actor to @a transform.
void SetTransform(const geom::Transform &transform);
/// Set the actor velocity.
void SetVelocity(const geom::Vector3D &vector);
/// Set the actor velocity before applying physics.
void SetTargetVelocity(const geom::Vector3D &vector);
/// Set the angular velocity of the actor
void SetAngularVelocity(const geom::Vector3D &vector);
/// Set the angular velocity of the actor before applying physics.
void SetTargetAngularVelocity(const geom::Vector3D &vector);
/// Add impulse to the actor.
/// Enable a constant velocity mode
void EnableConstantVelocity(const geom::Vector3D &vector);
/// Disable the constant velocity mode
void DisableConstantVelocity();
/// Add impulse to the actor at its center of mass.
void AddImpulse(const geom::Vector3D &vector);
/// Add impulse to the actor at certain location.
void AddImpulse(const geom::Vector3D &impulse, const geom::Vector3D &location);
/// Add force to the actor at its center of mass.
void AddForce(const geom::Vector3D &force);
/// Add force to the actor at certain location.
void AddForce(const geom::Vector3D &force, const geom::Vector3D &location);
/// Add angular impulse to the actor.
void AddAngularImpulse(const geom::Vector3D &vector);
/// Add a torque to the actor.
void AddTorque(const geom::Vector3D &vector);
/// Enable or disable physics simulation on this actor.
void SetSimulatePhysics(bool enabled = true);

View File

@ -151,7 +151,6 @@ namespace client {
}
auto episode = GetEpisode().Lock();
SharedPtr<Map> map = episode->GetCurrentMap();
auto cb = std::make_shared<LaneInvasionCallback>(
*vehicle,

View File

@ -11,8 +11,6 @@
#include <exception>
#include <exception>
namespace carla {
namespace client {

View File

@ -150,6 +150,10 @@ namespace client {
return nullptr;
}
void World::ResetAllTrafficLights() {
_episode.Lock()->ResetAllTrafficLights();
}
SharedPtr<LightManager> World::GetLightManager() const {
return _episode.Lock()->GetLightManager();
}
@ -158,5 +162,9 @@ namespace client {
_episode.Lock()->FreezeAllTrafficLights(frozen);
}
std::vector<geom::BoundingBox> World::GetLevelBBs(uint8_t queried_tag) const {
return _episode.Lock()->GetLevelBBs(queried_tag);
}
} // namespace client
} // namespace carla

View File

@ -138,6 +138,8 @@ namespace client {
SharedPtr<Actor> GetTrafficLight(const Landmark& landmark) const;
void ResetAllTrafficLights();
SharedPtr<LightManager> GetLightManager() const;
DebugHelper MakeDebugHelper() const {
@ -150,6 +152,9 @@ namespace client {
void FreezeAllTrafficLights(bool frozen);
/// Returns all the BBs of all the elements of the level
std::vector<geom::BoundingBox> GetLevelBBs(uint8_t queried_tag) const;
private:
detail::EpisodeProxy _episode;

View File

@ -264,22 +264,46 @@ namespace detail {
_pimpl->AsyncCall("set_actor_transform", actor, transform);
}
void Client::SetActorVelocity(rpc::ActorId actor, const geom::Vector3D &vector) {
_pimpl->AsyncCall("set_actor_velocity", actor, vector);
void Client::SetActorTargetVelocity(rpc::ActorId actor, const geom::Vector3D &vector) {
_pimpl->AsyncCall("set_actor_target_velocity", actor, vector);
}
void Client::SetActorAngularVelocity(rpc::ActorId actor, const geom::Vector3D &vector) {
_pimpl->AsyncCall("set_actor_angular_velocity", actor, vector);
void Client::SetActorTargetAngularVelocity(rpc::ActorId actor, const geom::Vector3D &vector) {
_pimpl->AsyncCall("set_actor_target_angular_velocity", actor, vector);
}
void Client::AddActorImpulse(rpc::ActorId actor, const geom::Vector3D &vector) {
_pimpl->AsyncCall("add_actor_impulse", actor, vector);
void Client::EnableActorConstantVelocity(rpc::ActorId actor, const geom::Vector3D &vector) {
_pimpl->AsyncCall("enable_actor_constant_velocity", actor, vector);
}
void Client::DisableActorConstantVelocity(rpc::ActorId actor) {
_pimpl->AsyncCall("disable_actor_constant_velocity", actor);
}
void Client::AddActorImpulse(rpc::ActorId actor, const geom::Vector3D &impulse) {
_pimpl->AsyncCall("add_actor_impulse", actor, impulse);
}
void Client::AddActorImpulse(rpc::ActorId actor, const geom::Vector3D &impulse, const geom::Vector3D &location) {
_pimpl->AsyncCall("add_actor_impulse_at_location", actor, impulse, location);
}
void Client::AddActorForce(rpc::ActorId actor, const geom::Vector3D &force) {
_pimpl->AsyncCall("add_actor_force", actor, force);
}
void Client::AddActorForce(rpc::ActorId actor, const geom::Vector3D &force, const geom::Vector3D &location) {
_pimpl->AsyncCall("add_actor_force_at_location", actor, force, location);
}
void Client::AddActorAngularImpulse(rpc::ActorId actor, const geom::Vector3D &vector) {
_pimpl->AsyncCall("add_actor_angular_impulse", actor, vector);
}
void Client::AddActorTorque(rpc::ActorId actor, const geom::Vector3D &vector) {
_pimpl->AsyncCall("add_actor_torque", actor, vector);
}
void Client::SetActorSimulatePhysics(rpc::ActorId actor, const bool enabled) {
_pimpl->AsyncCall("set_actor_simulate_physics", actor, enabled);
}
@ -326,6 +350,10 @@ namespace detail {
_pimpl->AsyncCall("reset_traffic_light_group", traffic_light);
}
void Client::ResetAllTrafficLights() {
_pimpl->CallAndWait<void>("reset_all_traffic_lights");
}
void Client::FreezeAllTrafficLights(bool frozen) {
_pimpl->AsyncCall("freeze_all_traffic_lights", frozen);
}
@ -413,6 +441,11 @@ namespace detail {
_pimpl->AsyncCall("update_lights_state", _pimpl->endpoint, std::move(lights), discard_client);
}
std::vector<geom::BoundingBox> Client::GetLevelBBs(uint8_t queried_tag) const {
using return_t = std::vector<geom::BoundingBox>;
return _pimpl->CallAndWait<return_t>("get_all_level_BBs", queried_tag);
}
} // namespace detail
} // namespace client
} // namespace carla

View File

@ -146,22 +146,47 @@ namespace detail {
rpc::ActorId actor,
const geom::Transform &transform);
void SetActorVelocity(
void SetActorTargetVelocity(
rpc::ActorId actor,
const geom::Vector3D &vector);
void SetActorAngularVelocity(
void SetActorTargetAngularVelocity(
rpc::ActorId actor,
const geom::Vector3D &vector);
void EnableActorConstantVelocity(
rpc::ActorId actor,
const geom::Vector3D &vector);
void DisableActorConstantVelocity(
rpc::ActorId actor);
void AddActorImpulse(
rpc::ActorId actor,
const geom::Vector3D &vector);
const geom::Vector3D &impulse);
void AddActorImpulse(
rpc::ActorId actor,
const geom::Vector3D &impulse,
const geom::Vector3D &location);
void AddActorForce(
rpc::ActorId actor,
const geom::Vector3D &force);
void AddActorForce(
rpc::ActorId actor,
const geom::Vector3D &force,
const geom::Vector3D &location);
void AddActorAngularImpulse(
rpc::ActorId actor,
const geom::Vector3D &vector);
void AddActorTorque(
rpc::ActorId actor,
const geom::Vector3D &vector);
void SetActorSimulatePhysics(
rpc::ActorId actor,
bool enabled);
@ -205,6 +230,8 @@ namespace detail {
void ResetTrafficLightGroup(
rpc::ActorId traffic_light);
void ResetAllTrafficLights();
void FreezeAllTrafficLights(bool frozen);
/// Returns a list of pairs where the firts element is the vehicle ID
@ -256,6 +283,9 @@ namespace detail {
std::vector<rpc::LightState>& lights,
bool discard_client = false) const;
/// Returns all the BBs of all the elements of the level
std::vector<geom::BoundingBox> GetLevelBBs(uint8_t queried_tag) const;
private:
class Pimpl;

View File

@ -226,6 +226,11 @@ namespace detail {
return _client.GetVehicleLightState(vehicle.GetId());
}
/// Returns all the BBs of all the elements of the level
std::vector<geom::BoundingBox> GetLevelBBs(uint8_t queried_tag) const {
return _client.GetLevelBBs(queried_tag);
}
/// @}
// =========================================================================
/// @name AI
@ -314,26 +319,49 @@ namespace detail {
return GetActorSnapshot(actor).velocity;
}
void SetActorVelocity(const Actor &actor, const geom::Vector3D &vector) {
_client.SetActorVelocity(actor.GetId(), vector);
void SetActorTargetVelocity(const Actor &actor, const geom::Vector3D &vector) {
_client.SetActorTargetVelocity(actor.GetId(), vector);
}
geom::Vector3D GetActorAngularVelocity(const Actor &actor) const {
return GetActorSnapshot(actor).angular_velocity;
}
void SetActorAngularVelocity(const Actor &actor, const geom::Vector3D &vector) {
_client.SetActorAngularVelocity(actor.GetId(), vector);
void SetActorTargetAngularVelocity(const Actor &actor, const geom::Vector3D &vector) {
_client.SetActorTargetAngularVelocity(actor.GetId(), vector);
}
void EnableActorConstantVelocity(const Actor &actor, const geom::Vector3D &vector) {
_client.EnableActorConstantVelocity(actor.GetId(), vector);
}
void AddActorImpulse(const Actor &actor, const geom::Vector3D &vector) {
_client.AddActorImpulse(actor.GetId(), vector);
void DisableActorConstantVelocity(const Actor &actor) {
_client.DisableActorConstantVelocity(actor.GetId());
}
void AddActorImpulse(const Actor &actor, const geom::Vector3D &impulse) {
_client.AddActorImpulse(actor.GetId(), impulse);
}
void AddActorImpulse(const Actor &actor, const geom::Vector3D &impulse, const geom::Vector3D &location) {
_client.AddActorImpulse(actor.GetId(), impulse, location);
}
void AddActorForce(const Actor &actor, const geom::Vector3D &force) {
_client.AddActorForce(actor.GetId(), force);
}
void AddActorForce(const Actor &actor, const geom::Vector3D &force, const geom::Vector3D &location) {
_client.AddActorForce(actor.GetId(), force, location);
}
void AddActorAngularImpulse(const Actor &actor, const geom::Vector3D &vector) {
_client.AddActorAngularImpulse(actor.GetId(), vector);
}
void AddActorTorque(const Actor &actor, const geom::Vector3D &torque) {
_client.AddActorAngularImpulse(actor.GetId(), torque);
}
geom::Vector3D GetActorAcceleration(const Actor &actor) const {
return GetActorSnapshot(actor).acceleration;
}
@ -468,6 +496,10 @@ namespace detail {
_client.ResetTrafficLightGroup(trafficLight.GetId());
}
void ResetAllTrafficLights() {
_client.ResetAllTrafficLights();
}
std::vector<ActorId> GetGroupTrafficLights(TrafficLight &trafficLight) {
return _client.GetGroupTrafficLights(trafficLight.GetId());
}

View File

@ -30,6 +30,11 @@ namespace geom {
// -- Constructors ---------------------------------------------------------
// =========================================================================
explicit BoundingBox(const Location &in_location, const Vector3D &in_extent, const Rotation &in_rotation)
: location(in_location),
extent(in_extent),
rotation(in_rotation) {}
explicit BoundingBox(const Location &in_location, const Vector3D &in_extent)
: location(in_location),
extent(in_extent) {}
@ -38,7 +43,8 @@ namespace geom {
: extent(in_extent) {}
Location location; ///< Center of the BoundingBox in local space
Vector3D extent; ///< Half the size of the BoundingBox in local space
Vector3D extent; ///< Half the size of the BoundingBox in local space
Rotation rotation; ///< Rotation of the BoundingBox in local space
// =========================================================================
// -- Other methods --------------------------------------------------------
@ -63,15 +69,16 @@ namespace geom {
* Returns the positions of the 8 vertices of this BoundingBox in local space.
*/
std::array<Location, 8> GetLocalVertices() const {
return {{
location + Location(-extent.x,-extent.y,-extent.z),
location + Location(-extent.x,-extent.y, extent.z),
location + Location(-extent.x, extent.y,-extent.z),
location + Location(-extent.x, extent.y, extent.z),
location + Location( extent.x,-extent.y,-extent.z),
location + Location( extent.x,-extent.y, extent.z),
location + Location( extent.x, extent.y,-extent.z),
location + Location( extent.x, extent.y, extent.z)
location + Location(rotation.RotateVector({-extent.x,-extent.y,-extent.z})),
location + Location(rotation.RotateVector({-extent.x,-extent.y, extent.z})),
location + Location(rotation.RotateVector({-extent.x, extent.y,-extent.z})),
location + Location(rotation.RotateVector({-extent.x, extent.y, extent.z})),
location + Location(rotation.RotateVector({ extent.x,-extent.y,-extent.z})),
location + Location(rotation.RotateVector({ extent.x,-extent.y, extent.z})),
location + Location(rotation.RotateVector({ extent.x, extent.y,-extent.z})),
location + Location(rotation.RotateVector({ extent.x, extent.y, extent.z}))
}};
}
@ -92,7 +99,7 @@ namespace geom {
// =========================================================================
bool operator==(const BoundingBox &rhs) const {
return (location == rhs.location) && (extent == rhs.extent);
return (location == rhs.location) && (extent == rhs.extent) && (rotation == rhs.rotation);
}
bool operator!=(const BoundingBox &rhs) const {
@ -107,11 +114,12 @@ namespace geom {
BoundingBox(const FBoundingBox &Box)
: location(Box.Origin),
extent(1e-2f * Box.Extent.X, 1e-2f * Box.Extent.Y, 1e-2f * Box.Extent.Z) {}
extent(1e-2f * Box.Extent.X, 1e-2f * Box.Extent.Y, 1e-2f * Box.Extent.Z),
rotation(Box.Rotation) {}
#endif // LIBCARLA_INCLUDED_FROM_UE4
MSGPACK_DEFINE_ARRAY(location, extent);
MSGPACK_DEFINE_ARRAY(location, extent, rotation);
};
} // namespace geom

View File

@ -193,6 +193,12 @@ namespace geom {
Normal = Normal.GetSafeNormal(.0001f);
if (Normal != FVector::ZeroVector)
{
// fix to prevent ugly x-fighting in geometries with very large curvatures,
// ensures that all road geometry is facing upwards
if (FVector::DotProduct(Normal, FVector(0,0,1)) < 0)
{
Normal = -Normal;
}
Mesh.Normals[Triangle.v0] = Normal;
Mesh.Normals[Triangle.v1] = Normal;
Mesh.Normals[Triangle.v2] = Normal;

View File

@ -87,6 +87,12 @@ namespace geom {
in_point = out_point;
}
Vector3D RotateVector(const Vector3D& in_point) const {
Vector3D out_point = in_point;
RotateVector(out_point);
return out_point;
}
void InverseRotateVector(Vector3D &in_point) const {
// Applies the transposed of the matrix used in RotateVector function,
// which is the rotation inverse.

View File

@ -20,20 +20,27 @@ namespace detail {
uint8_t CITYSCAPES_PALETTE_MAP[][3u] = {
{ 0u, 0u, 0u}, // unlabeled = 0u,
{ 70u, 70u, 70u}, // building = 1u,
{190u, 153u, 153u}, // fence = 2u,
{250u, 170u, 160u}, // other = 3u,
{100u, 40u, 40u}, // fence = 2u,
{ 55u, 90u, 80u}, // other = 3u,
{220u, 20u, 60u}, // pedestrian = 4u,
{153u, 153u, 153u}, // pole = 5u,
{157u, 234u, 50u}, // road line = 6u,
{128u, 64u, 128u}, // road = 7u,
{244u, 35u, 232u}, // sidewalk = 8u,
{107u, 142u, 35u}, // vegetation = 9u,
{ 0u, 0u, 142u}, // car = 10u,
{ 0u, 0u, 142u}, // vehicle = 10u,
{102u, 102u, 156u}, // wall = 11u,
{220u, 220u, 0u}, // traffic sign = 12u,
{ 70u, 130u, 180u}, // sky = 13u,
{ 81u, 0u, 81u}, // ground = 14u,
{150u, 100u, 100u}, // bridge = 15u,
{230u, 150u, 140u}, // rail track = 16u,
{180u, 165u, 180u}, // guard rail = 17u,
{250u, 170u, 30u}, // traffic light = 18u,
{110u, 190u, 160u}, // static = 19u,
{170u, 120u, 50u}, // dynamic = 20u,
{ 45u, 60u, 150u}, // water = 21u,
{145u, 170u, 100u}, // terrain = 22u,
// { 0u, 0u, 70u}, // truck
// { 0u, 0u, 90u}, // caravan
// { 0u, 0u, 110u}, // trailer
@ -41,14 +48,9 @@ namespace detail {
// { 0u, 0u, 230u}, // motorcycle
// { 0u, 60u, 100u}, // bus
// { 0u, 80u, 100u}, // train
// {111u, 74u, 0u}, // dynamic
// {119u, 11u, 32u}, // bicycle
// {150u, 120u, 90u}, // tunnel
// {152u, 251u, 152u}, // terrain
// {153u, 153u, 153u}, // polegroup
// {180u, 165u, 180u}, // guard rail
// {230u, 150u, 140u}, // rail track
// {250u, 170u, 30u}, // traffic light
// {250u, 170u, 160u}, // parking
// {255u, 0u, 0u}, // rider
};

View File

@ -102,9 +102,9 @@ namespace rpc {
MSGPACK_DEFINE_ARRAY(actor, transform, speed);
};
struct ApplyVelocity : CommandBase<ApplyVelocity> {
ApplyVelocity() = default;
ApplyVelocity(ActorId id, const geom::Vector3D &value)
struct ApplyTargetVelocity : CommandBase<ApplyTargetVelocity> {
ApplyTargetVelocity() = default;
ApplyTargetVelocity(ActorId id, const geom::Vector3D &value)
: actor(id),
velocity(value) {}
ActorId actor;
@ -112,9 +112,9 @@ namespace rpc {
MSGPACK_DEFINE_ARRAY(actor, velocity);
};
struct ApplyAngularVelocity : CommandBase<ApplyAngularVelocity> {
ApplyAngularVelocity() = default;
ApplyAngularVelocity(ActorId id, const geom::Vector3D &value)
struct ApplyTargetAngularVelocity : CommandBase<ApplyTargetAngularVelocity> {
ApplyTargetAngularVelocity() = default;
ApplyTargetAngularVelocity(ActorId id, const geom::Vector3D &value)
: actor(id),
angular_velocity(value) {}
ActorId actor;
@ -132,6 +132,16 @@ namespace rpc {
MSGPACK_DEFINE_ARRAY(actor, impulse);
};
struct ApplyForce : CommandBase<ApplyForce> {
ApplyForce() = default;
ApplyForce(ActorId id, const geom::Vector3D &value)
: actor(id),
force(value) {}
ActorId actor;
geom::Vector3D force;
MSGPACK_DEFINE_ARRAY(actor, force);
};
struct ApplyAngularImpulse : CommandBase<ApplyAngularImpulse> {
ApplyAngularImpulse() = default;
ApplyAngularImpulse(ActorId id, const geom::Vector3D &value)
@ -142,6 +152,16 @@ namespace rpc {
MSGPACK_DEFINE_ARRAY(actor, impulse);
};
struct ApplyTorque : CommandBase<ApplyTorque> {
ApplyTorque() = default;
ApplyTorque(ActorId id, const geom::Vector3D &value)
: actor(id),
torque(value) {}
ActorId actor;
geom::Vector3D torque;
MSGPACK_DEFINE_ARRAY(actor, torque);
};
struct SetSimulatePhysics : CommandBase<SetSimulatePhysics> {
SetSimulatePhysics() = default;
SetSimulatePhysics(ActorId id, bool value)
@ -186,10 +206,12 @@ namespace rpc {
ApplyWalkerControl,
ApplyTransform,
ApplyWalkerState,
ApplyVelocity,
ApplyAngularVelocity,
ApplyTargetVelocity,
ApplyTargetAngularVelocity,
ApplyImpulse,
ApplyForce,
ApplyAngularImpulse,
ApplyTorque,
SetSimulatePhysics,
SetAutopilot,
SetVehicleLightState>;

View File

@ -0,0 +1,45 @@
// Copyright (c) 2020 Computer Vision Center (CVC) at the Universitat Autonoma
// de Barcelona (UAB).
//
// This work is licensed under the terms of the MIT license.
// For a copy, see <https://opensource.org/licenses/MIT>.
#pragma once
#include "carla/MsgPack.h"
#include <cstdint>
namespace carla {
namespace rpc {
enum class CityObjectLabel : uint8_t {
None = 0u,
Buildings = 1u,
Fences = 2u,
Other = 3u,
Pedestrians = 4u,
Poles = 5u,
RoadLines = 6u,
Roads = 7u,
Sidewalks = 8u,
TrafficSigns = 12u,
Vegetation = 9u,
Vehicles = 10u,
Walls = 11u,
Sky = 13u,
Ground = 14u,
Bridge = 15u,
RailTrack = 16u,
GuardRail = 17u,
TrafficLight = 18u,
Static = 19u,
Dynamic = 20u,
Water = 21u,
Terrain = 22u,
};
} // namespace rpc
} // namespace carla
MSGPACK_ADD_ENUM(carla::rpc::CityObjectLabel);

View File

@ -12,6 +12,7 @@
#include "carla/rpc/Response.h"
#include <boost/asio/io_context.hpp>
#include <boost/asio/post.hpp>
#include <rpc/server.h>
@ -107,12 +108,12 @@ namespace detail {
});
if (metadata.IsResponseIgnored()) {
// Post task and ignore result.
io.post(MoveHandler(task));
boost::asio::post(io, MoveHandler(task));
return R();
} else {
// Post task and wait for result.
auto result = task.get_future();
io.post(MoveHandler(task));
boost::asio::post(io, MoveHandler(task));
return result.get();
}
};

View File

@ -131,6 +131,7 @@ RssCheck::RssCheck(float maximum_steering_angle)
_timing_logger->set_level(spdlog::level::off);
SetLogLevel(spdlog::level::warn);
SetMapLogLevel(spdlog::level::warn);
_default_actor_constellation_callback_ego_vehicle_dynamics = GetDefaultVehicleDynamics();
_default_actor_constellation_callback_other_vehicle_dynamics = GetDefaultVehicleDynamics();
@ -208,6 +209,7 @@ RssCheck::RssCheck(float maximum_steering_angle,
_timing_logger->set_level(spdlog::level::off);
SetLogLevel(spdlog::level::warn);
SetMapLogLevel(spdlog::level::warn);
_carla_rss_state.ego_match_object = GetMatchObject(carla_ego_actor, ::ad::physics::Distance(2.0));
UpdateDefaultRssDynamics(_carla_rss_state);
@ -220,8 +222,11 @@ RssCheck::~RssCheck() {}
void RssCheck::SetLogLevel(const spdlog::level::level_enum &log_level) {
spdlog::set_level(log_level);
_logger->set_level(log_level);
::ad::map::access::getLogger()->set_level(log_level);
::ad::rss::map::getLogger()->set_level(log_level);
}
void RssCheck::SetMapLogLevel(const spdlog::level::level_enum &map_log_level) {
::ad::map::access::getLogger()->set_level(map_log_level);
::ad::rss::map::getLogger()->set_level(map_log_level);
}
const ::ad::rss::world::RssDynamics &RssCheck::GetDefaultActorConstellationCallbackEgoVehicleDynamics() const {
@ -337,7 +342,7 @@ bool RssCheck::CheckObjects(carla::client::Timestamp const &timestamp,
_carla_rss_state.ego_match_object = ego_match_object;
_logger->debug("MapMatch:: {}", _carla_rss_state.ego_match_object);
_logger->trace("MapMatch:: {}", _carla_rss_state.ego_match_object);
#if DEBUG_TIMING
t_end = std::chrono::high_resolution_clock::now();
@ -471,7 +476,7 @@ bool RssCheck::CheckObjects(carla::client::Timestamp const &timestamp,
}
void RssCheck::UpdateRoute(CarlaRssState &carla_rss_state) {
_logger->debug("Update route start: {}", carla_rss_state.ego_route);
_logger->trace("Update route start: {}", carla_rss_state.ego_route);
// remove the parts of the route already taken, try to prepend route sections
// (i.e. when driving backwards)
@ -588,7 +593,7 @@ void RssCheck::UpdateRoute(CarlaRssState &carla_rss_state) {
}
}
_logger->debug("Update route result: {}", carla_rss_state.ego_route);
_logger->trace("Update route result: {}", carla_rss_state.ego_route);
}
EgoDynamicsOnRoute RssCheck::CalculateEgoDynamicsOnRoute(
@ -819,7 +824,7 @@ void RssCheck::RssObjectChecker::operator()(
try {
auto other_match_object = _rss_check.GetMatchObject(other_traffic_participant, ::ad::physics::Distance(2.0));
_rss_check._logger->debug("OtherVehicleMapMatching: {} {}", other_traffic_participant->GetId(),
_rss_check._logger->trace("OtherVehicleMapMatching: {} {}", other_traffic_participant->GetId(),
other_match_object.mapMatchedBoundingBox);
carla::SharedPtr<ActorConstellationData> actor_constellation_data{new ActorConstellationData{
@ -1005,7 +1010,7 @@ void RssCheck::AnalyseCheckResults(CarlaRssState &carla_rss_state) const {
carla_rss_state.ego_dynamics_on_route.crossing_border = true;
}
_logger->debug("RouteResponse: {}", carla_rss_state.proper_response);
_logger->trace("RouteResponse: {}", carla_rss_state.proper_response);
}
} // namespace rss

View File

@ -175,6 +175,9 @@ public:
/// @brief sets the current log level
void SetLogLevel(const spdlog::level::level_enum &log_level);
/// @brief sets the current log level
void SetMapLogLevel(const spdlog::level::level_enum &map_log_level);
/// @returns the current mode for respecting the road boundaries (@see also
/// RssSensor::GetRoadBoundariesMode())
const ::carla::rss::RoadBoundariesMode &GetRoadBoundariesMode() const;

View File

@ -119,6 +119,17 @@ void RssSensor::SetLogLevel(const uint8_t &log_level) {
}
}
void RssSensor::SetMapLogLevel(const uint8_t &map_log_level) {
if (!bool(_rss_check)) {
log_error(GetDisplayId(), ": not yet listening. SetMapLogLevel has no effect.");
return;
}
if (map_log_level < spdlog::level::n_levels) {
_rss_check->SetMapLogLevel(spdlog::level::level_enum(map_log_level));
}
}
const ::ad::rss::world::RssDynamics &RssSensor::GetEgoVehicleDynamics() const {
static auto default_vehicle_dynamics = rss::RssCheck::GetDefaultVehicleDynamics();
if (!bool(_rss_check)) {

View File

@ -77,6 +77,9 @@ public:
/// @brief sets the current log level
void SetLogLevel(const uint8_t &log_level);
/// @brief sets the current map log level
void SetMapLogLevel(const uint8_t &map_log_level);
/// @returns the currently used dynamics of the ego vehicle (@see also
/// RssCheck::GetEgoVehicleDynamics())
const ::ad::rss::world::RssDynamics &GetEgoVehicleDynamics() const;

View File

@ -15,6 +15,8 @@
#include <boost/asio/connect.hpp>
#include <boost/asio/read.hpp>
#include <boost/asio/write.hpp>
#include <boost/asio/post.hpp>
#include <boost/asio/bind_executor.hpp>
#include <exception>
@ -84,7 +86,7 @@ namespace tcp {
void Client::Connect() {
auto self = shared_from_this();
_strand.post([this, self]() {
boost::asio::post(_strand, [this, self]() {
if (_done) {
return;
}
@ -111,7 +113,11 @@ namespace tcp {
boost::asio::async_write(
_socket,
boost::asio::buffer(&stream_id, sizeof(stream_id)),
_strand.wrap([=](error_code ec, size_t DEBUG_ONLY(bytes)) {
boost::asio::bind_executor(_strand, [=](error_code ec, size_t DEBUG_ONLY(bytes)) {
// Ensures to stop the execution once the connection has been stopped.
if (_done) {
return;
}
if (!ec) {
DEBUG_ASSERT_EQ(bytes, sizeof(stream_id));
// If succeeded start reading data.
@ -129,14 +135,14 @@ namespace tcp {
};
log_debug("streaming client: connecting to", ep);
_socket.async_connect(ep, _strand.wrap(handle_connect));
_socket.async_connect(ep, boost::asio::bind_executor(_strand, handle_connect));
});
}
void Client::Stop() {
_connection_timer.cancel();
auto self = shared_from_this();
_strand.post([this, self]() {
boost::asio::post(_strand, [this, self]() {
_done = true;
if (_socket.is_open()) {
_socket.close();
@ -156,7 +162,7 @@ namespace tcp {
void Client::ReadData() {
auto self = shared_from_this();
_strand.post([this, self]() {
boost::asio::post(_strand, [this, self]() {
if (_done) {
return;
}
@ -173,7 +179,7 @@ namespace tcp {
// Move the buffer to the callback function and start reading the next
// piece of data.
// log_debug("streaming client: success reading data, calling the callback");
_strand.context().post([self, message]() { self->_callback(message->pop()); });
boost::asio::post(_strand, [self, message]() { self->_callback(message->pop()); });
ReadData();
} else {
// As usual, if anything fails start over from the very top.
@ -196,7 +202,7 @@ namespace tcp {
boost::asio::async_read(
_socket,
message->buffer(),
_strand.wrap(handle_read_data));
boost::asio::bind_executor(_strand, handle_read_data));
} else {
log_info("streaming client: failed to read header:", ec.message());
DEBUG_ONLY(log_debug("size = ", message->size()));
@ -209,7 +215,7 @@ namespace tcp {
boost::asio::async_read(
_socket,
message->size_as_buffer(),
_strand.wrap(handle_read_header));
boost::asio::bind_executor(_strand, handle_read_header));
});
}

View File

@ -6,6 +6,8 @@
#include "carla/streaming/detail/tcp/Server.h"
#include <boost/asio/post.hpp>
#include "carla/Logging.h"
#include <memory>
@ -38,7 +40,7 @@ namespace tcp {
_acceptor.async_accept(session->_socket, [=](error_code ec) {
// Handle query and open a new session immediately.
_io_context.post([=]() { handle_query(ec); });
boost::asio::post(_io_context, [=]() { handle_query(ec); });
OpenSession(timeout, on_opened, on_closed);
});
}

View File

@ -12,6 +12,7 @@
#include <boost/asio/io_context.hpp>
#include <boost/asio/ip/tcp.hpp>
#include <boost/asio/post.hpp>
#include <atomic>
@ -45,7 +46,7 @@ namespace tcp {
/// is closed.
template <typename FunctorT1, typename FunctorT2>
void Listen(FunctorT1 on_session_opened, FunctorT2 on_session_closed) {
_io_context.post([=]() {
boost::asio::post(_io_context, [=]() {
OpenSession(
_timeout,
std::move(on_session_opened),

View File

@ -11,6 +11,8 @@
#include <boost/asio/read.hpp>
#include <boost/asio/write.hpp>
#include <boost/asio/bind_executor.hpp>
#include <boost/asio/post.hpp>
#include <atomic>
@ -45,7 +47,7 @@ namespace tcp {
StartTimer();
auto self = shared_from_this(); // To keep myself alive.
_strand.post([=]() {
boost::asio::post(_strand, [=]() {
auto handle_query = [this, self, callback=std::move(on_opened)](
const boost::system::error_code &ec,
@ -53,7 +55,7 @@ namespace tcp {
if (!ec) {
DEBUG_ASSERT_EQ(bytes_received, sizeof(_stream_id));
log_debug("session", _session_id, "for stream", _stream_id, " started");
_strand.context().post([=]() { callback(self); });
boost::asio::post(_strand.context(), [=]() { callback(self); });
} else {
log_error("session", _session_id, ": error retrieving stream id :", ec.message());
CloseNow();
@ -65,7 +67,7 @@ namespace tcp {
boost::asio::async_read(
_socket,
boost::asio::buffer(&_stream_id, sizeof(_stream_id)),
_strand.wrap(handle_query));
boost::asio::bind_executor(_strand, handle_query));
});
}
@ -73,7 +75,7 @@ namespace tcp {
DEBUG_ASSERT(message != nullptr);
DEBUG_ASSERT(!message->empty());
auto self = shared_from_this();
_strand.post([=]() {
boost::asio::post(_strand, [=]() {
if (!_socket.is_open()) {
return;
}
@ -100,12 +102,12 @@ namespace tcp {
boost::asio::async_write(
_socket,
message->GetBufferSequence(),
_strand.wrap(handle_sent));
boost::asio::bind_executor(_strand, handle_sent));
});
}
void ServerSession::Close() {
_strand.post([self=shared_from_this()]() { self->CloseNow(); });
boost::asio::post(_strand, [self=shared_from_this()]() { self->CloseNow(); });
}
void ServerSession::StartTimer() {
@ -129,7 +131,7 @@ namespace tcp {
if (_socket.is_open()) {
_socket.close();
}
_strand.context().post([self=shared_from_this()]() {
boost::asio::post(_strand.context(), [self=shared_from_this()]() {
DEBUG_ASSERT(self->_on_closed);
self->_on_closed(self);
});

View File

@ -46,12 +46,14 @@ namespace low_level {
}
}
/// @warning cannot subscribe twice to the same stream (even if it's a
/// MultiStream).
template <typename Functor>
void Subscribe(
boost::asio::io_context &io_context,
token_type token,
Functor &&callback) {
DEBUG_ASSERT_EQ(_clients.find(token.get_stream_id()), _clients.end());
if (!token.has_address()) {
token.set_address(_fallback_address);
}
@ -64,15 +66,10 @@ namespace low_level {
}
void UnSubscribe(token_type token) {
auto id = token.get_stream_id();
for (auto it=_clients.begin(); it!=_clients.end(); ) {
if (it->first == id) {
log_info("Unsubscribing from stream:", id);
it->second->Stop();
it = _clients.erase(it);
} else {
++it;
}
auto it = _clients.find(token.get_stream_id());
if (it != _clients.end()) {
it->second->Stop();
_clients.erase(it);
}
}
@ -80,7 +77,7 @@ namespace low_level {
boost::asio::ip::address _fallback_address;
std::unordered_multimap<
std::unordered_map<
detail::stream_id_type,
std::shared_ptr<underlying_client>> _clients;
};

View File

@ -18,6 +18,7 @@ ALSM::ALSM(
AtomicActorSet &registered_vehicles,
BufferMap &buffer_map,
TrackTraffic &track_traffic,
std::vector<ActorId>& marked_for_removal,
const Parameters &parameters,
const cc::World &world,
const LocalMapPtr &local_map,
@ -25,10 +26,12 @@ ALSM::ALSM(
LocalizationStage &localization_stage,
CollisionStage &collision_stage,
TrafficLightStage &traffic_light_stage,
MotionPlanStage &motion_plan_stage)
MotionPlanStage &motion_plan_stage,
RandomGeneratorMap &random_devices)
: registered_vehicles(registered_vehicles),
buffer_map(buffer_map),
track_traffic(track_traffic),
marked_for_removal(marked_for_removal),
parameters(parameters),
world(world),
local_map(local_map),
@ -36,7 +39,8 @@ ALSM::ALSM(
localization_stage(localization_stage),
collision_stage(collision_stage),
traffic_light_stage(traffic_light_stage),
motion_plan_stage(motion_plan_stage) {}
motion_plan_stage(motion_plan_stage),
random_devices(random_devices) {}
void ALSM::Update() {
@ -106,6 +110,15 @@ void ALSM::Update() {
elapsed_last_actor_destruction = current_timestamp.elapsed_seconds;
}
// Destorying vehicles for marked for removal by stages.
if (parameters.GetOSMMode()) {
for (const ActorId& actor_id: marked_for_removal) {
registered_vehicles.Destroy(actor_id);
RemoveActor(actor_id, true);
}
marked_for_removal.clear();
}
// Update dynamic state and static attributes for unregistered actors.
UpdateUnregisteredActorsData();
}
@ -302,7 +315,7 @@ void ALSM::UpdateIdleTime(std::pair<ActorId, double>& max_idle_time, const Actor
double &idle_duration = idle_time.at(actor_id);
TrafficLightState tl_state = simulation_state.GetTLS(actor_id);
if (simulation_state.GetVelocity(actor_id).SquaredLength() > SQUARE(STOPPED_VELOCITY_THRESHOLD)
|| (tl_state.at_traffic_light && tl_state.tl_state != TLS::Green)) {
|| (tl_state.at_traffic_light && tl_state.tl_state != TLS::Green && tl_state.tl_state != TLS::Off)) {
idle_duration = current_timestamp.elapsed_seconds;
}
@ -328,6 +341,7 @@ void ALSM::RemoveActor(const ActorId actor_id, const bool registered_actor) {
registered_vehicles.Remove({actor_id});
buffer_map.erase(actor_id);
idle_time.erase(actor_id);
random_devices.erase(actor_id);
localization_stage.RemoveActor(actor_id);
collision_stage.RemoveActor(actor_id);
traffic_light_stage.RemoveActor(actor_id);

View File

@ -15,6 +15,7 @@
#include "carla/trafficmanager/LocalizationStage.h"
#include "carla/trafficmanager/MotionPlanStage.h"
#include "carla/trafficmanager/Parameters.h"
#include "carla/trafficmanager/RandomGenerator.h"
#include "carla/trafficmanager/SimulationState.h"
#include "carla/trafficmanager/TrafficLightStage.h"
@ -48,6 +49,8 @@ private:
// Structure containing vehicles with attribute role_name with value hero.
ActorMap hero_actors;
TrackTraffic &track_traffic;
// Array of vehicles marked by stages for removal.
std::vector<ActorId>& marked_for_removal;
const Parameters &parameters;
const cc::World &world;
const LocalMapPtr &local_map;
@ -59,6 +62,8 @@ private:
// Time elapsed since last vehicle destruction due to being idle for too long.
double elapsed_last_actor_destruction {0.0};
cc::Timestamp current_timestamp;
// Random devices.
RandomGeneratorMap &random_devices;
// Updates the duration for which a registered vehicle is stuck at a location.
void UpdateIdleTime(std::pair<ActorId, double>& max_idle_time, const ActorId& actor_id);
@ -66,10 +71,6 @@ private:
// Method to determine if a vehicle is stuck at a place for too long.
bool IsVehicleStuck(const ActorId& actor_id);
// Removes an actor from traffic manager and performs clean up of associated data
// from various stages tracking the said vehicle.
void RemoveActor(const ActorId actor_id, const bool registered_actor);
using ActorVector = std::vector<ActorPtr>;
// Method to identify actors newly spawned in the simulation since last tick.
ActorVector IdentifyNewActors(const ActorList &actor_list);
@ -88,6 +89,7 @@ public:
ALSM(AtomicActorSet &registered_vehicles,
BufferMap &buffer_map,
TrackTraffic &track_traffic,
std::vector<ActorId>& marked_for_removal,
const Parameters &parameters,
const cc::World &world,
const LocalMapPtr &local_map,
@ -95,10 +97,15 @@ public:
LocalizationStage &localization_stage,
CollisionStage &collision_stage,
TrafficLightStage &traffic_light_stage,
MotionPlanStage &motion_plan_stage);
MotionPlanStage &motion_plan_stage,
RandomGeneratorMap &random_devices);
void Update();
// Removes an actor from traffic manager and performs clean up of associated data
// from various stages tracking the said vehicle.
void RemoveActor(const ActorId actor_id, const bool registered_actor);
void Reset();
};

View File

@ -27,7 +27,12 @@ namespace traffic_manager {
void AddEntry(const std::pair<Key, Value> &entry) {
std::lock_guard<std::mutex> lock(map_mutex);
map.insert(entry);
const Key& key = entry.first;
if (map.find(key) != map.end()) {
map.at(key) = entry.second;
} else {
map.insert(entry);
}
}
bool Contains(const Key &key) const {

View File

@ -22,14 +22,16 @@ CollisionStage::CollisionStage(
const TrackTraffic &track_traffic,
const Parameters &parameters,
CollisionFrame &output_array,
cc::DebugHelper &debug_helper)
cc::DebugHelper &debug_helper,
RandomGeneratorMap &random_devices)
: vehicle_id_list(vehicle_id_list),
simulation_state(simulation_state),
buffer_map(buffer_map),
track_traffic(track_traffic),
parameters(parameters),
output_array(output_array),
debug_helper(debug_helper) {}
debug_helper(debug_helper),
random_devices(random_devices) {}
void CollisionStage::Update(const unsigned long index) {
ActorId obstacle_id = 0u;
@ -81,9 +83,9 @@ void CollisionStage::Update(const unsigned long index) {
look_ahead_index);
if (negotiation_result.first) {
if ((other_actor_type == ActorType::Vehicle
&& parameters.GetPercentageIgnoreVehicles(ego_actor_id) <= pgen.next())
&& parameters.GetPercentageIgnoreVehicles(ego_actor_id) <= random_devices.at(ego_actor_id).next())
|| (other_actor_type == ActorType::Pedestrian
&& parameters.GetPercentageIgnoreWalkers(ego_actor_id) <= pgen.next())) {
&& parameters.GetPercentageIgnoreWalkers(ego_actor_id) <= random_devices.at(ego_actor_id).next())) {
collision_hazard = true;
obstacle_id = other_actor_id;
available_distance_margin = negotiation_result.second;
@ -143,7 +145,7 @@ LocationVector CollisionStage::GetBoundary(const ActorId actor_id) {
float bbox_y = dimensions.y;
const cg::Vector3D x_boundary_vector = heading_vector * (bbox_x + forward_extension);
const auto perpendicular_vector = cg::Vector3D(-heading_vector.y, heading_vector.x, 0.0f).MakeUnitVector();
const auto perpendicular_vector = cg::Vector3D(-heading_vector.y, heading_vector.x, 0.0f).MakeSafeUnitVector(EPSILON);
const cg::Vector3D y_boundary_vector = perpendicular_vector * (bbox_y + forward_extension);
// Four corners of the vehicle in top view clockwise order (left-handed system).
@ -199,7 +201,7 @@ LocationVector CollisionStage::GetGeodesicBoundary(const ActorId actor_id) {
const cg::Vector3D heading_vector = current_point->GetForwardVector();
const cg::Location location = current_point->GetLocation();
cg::Vector3D perpendicular_vector = cg::Vector3D(-heading_vector.y, heading_vector.x, 0.0f);
perpendicular_vector = perpendicular_vector.MakeUnitVector();
perpendicular_vector = perpendicular_vector.MakeSafeUnitVector(EPSILON);
// Direction determined for the left-handed system.
const cg::Vector3D scaled_perpendicular = perpendicular_vector * width;
left_boundary.push_back(location + cg::Location(scaled_perpendicular));
@ -304,15 +306,14 @@ std::pair<bool, float> CollisionStage::NegotiateCollision(const ActorId referenc
// Ego and other vehicle heading.
const cg::Vector3D reference_heading = simulation_state.GetHeading(reference_vehicle_id);
// Vector from ego position to position of the other vehicle.
const float vector_magnitude_epsilon = 2.0f * std::numeric_limits<float>::epsilon();
cg::Vector3D reference_to_other = other_location - reference_location;
reference_to_other = reference_to_other.MakeSafeUnitVector(vector_magnitude_epsilon);
reference_to_other = reference_to_other.MakeSafeUnitVector(EPSILON);
// Other vehicle heading.
const cg::Vector3D other_heading = simulation_state.GetHeading(other_actor_id);
// Vector from other vehicle position to ego position.
cg::Vector3D other_to_reference = reference_location - other_location;
other_to_reference = other_to_reference.MakeSafeUnitVector(vector_magnitude_epsilon);
other_to_reference = other_to_reference.MakeSafeUnitVector(EPSILON);
float reference_vehicle_length = simulation_state.GetDimensions(reference_vehicle_id).x * SQUARE_ROOT_OF_TWO;
float other_vehicle_length = simulation_state.GetDimensions(other_actor_id).x * SQUARE_ROOT_OF_TWO;
@ -335,7 +336,7 @@ std::pair<bool, float> CollisionStage::NegotiateCollision(const ActorId referenc
bool ego_inside_junction = closest_point->CheckJunction();
TrafficLightState reference_tl_state = simulation_state.GetTLS(reference_vehicle_id);
bool ego_at_traffic_light = reference_tl_state.at_traffic_light;
bool ego_stopped_by_light = reference_tl_state.tl_state != TLS::Green;
bool ego_stopped_by_light = reference_tl_state.tl_state != TLS::Green && reference_tl_state.tl_state != TLS::Off;
SimpleWaypointPtr look_ahead_point = reference_vehicle_buffer.at(reference_junction_look_ahead_index);
bool ego_at_junction_entrance = !closest_point->CheckJunction() && look_ahead_point->CheckJunction();

View File

@ -60,7 +60,7 @@ private:
// to avoid repeated computation within a cycle.
GeometryComparisonMap geometry_cache;
GeodesicBoundaryMap geodesic_boundary_map;
RandomGenerator<> pgen;
RandomGeneratorMap &random_devices;
// Method to determine if a vehicle is on a collision path to another.
std::pair<bool, float> NegotiateCollision(const ActorId reference_vehicle_id,
@ -93,7 +93,8 @@ public:
const TrackTraffic &track_traffic,
const Parameters &parameters,
CollisionFrame &output_array,
cc::DebugHelper& debug_helper);
cc::DebugHelper& debug_helper,
RandomGeneratorMap &random_devices);
void Update (const unsigned long index) override;

View File

@ -28,8 +28,9 @@ static const double DELTA_TIME_BETWEEN_DESTRUCTIONS = 10.0;
} // namespace VehicleRemoval
namespace HybridMode {
static const float HYBRID_MODE_DT = 0.05f;
static const float INV_HYBRID_DT = 1.0f / HYBRID_MODE_DT;
static const float HYBRID_MODE_DT_FL = 0.05f;
static const double HYBRID_MODE_DT = 0.05;
static const double INV_HYBRID_DT = 1.0 / HYBRID_MODE_DT;
static const float PHYSICS_RADIUS = 50.0f;
} // namespace HybridMode
@ -78,6 +79,7 @@ static const float MAX_LOCKING_EXTENSION = 10.0f;
static const float WALKER_TIME_EXTENSION = 1.5f;
static const float SQUARE_ROOT_OF_TWO = 1.414f;
static const float VERTICAL_OVERLAP_THRESHOLD = 4.0f;
static const float EPSILON = 2.0f * std::numeric_limits<float>::epsilon();
} // namespace Collision
namespace FrameMemory {
@ -126,7 +128,6 @@ static const uint64_t BUFFER_STEP_THROUGH = 10;
static const float INV_BUFFER_STEP_THROUGH = 0.1f;
} // namespace TrackTraffic
} // namespace constants
} // namespace traffic_manager
} // namespace carla

View File

@ -60,7 +60,7 @@ struct ActuationSignal {
/// Structure to hold the controller state.
struct StateEntry {
TimeInstance time_instance;
cc::Timestamp time_instance;
float deviation;
float velocity;
float deviation_integral;

View File

@ -17,16 +17,20 @@ LocalizationStage::LocalizationStage(
TrackTraffic &track_traffic,
const LocalMapPtr &local_map,
Parameters &parameters,
std::vector<ActorId>& marked_for_removal,
LocalizationFrame &output_array,
cc::DebugHelper &debug_helper)
cc::DebugHelper &debug_helper,
RandomGeneratorMap &random_devices)
: vehicle_id_list(vehicle_id_list),
buffer_map(buffer_map),
simulation_state(simulation_state),
track_traffic(track_traffic),
local_map(local_map),
parameters(parameters),
marked_for_removal(marked_for_removal),
output_array(output_array),
debug_helper(debug_helper) {}
debug_helper(debug_helper),
random_devices(random_devices) {}
void LocalizationStage::Update(const unsigned long index) {
@ -103,7 +107,7 @@ void LocalizationStage::Update(const unsigned long index) {
if (!force_lane_change) {
float perc_keep_right = parameters.GetKeepRightPercentage(actor_id);
if (perc_keep_right >= 0.0f && perc_keep_right >= pgen.next()) {
if (perc_keep_right >= 0.0f && perc_keep_right >= random_devices.at(actor_id).next()) {
force_lane_change = true;
lane_change_direction = true;
}
@ -145,22 +149,34 @@ void LocalizationStage::Update(const unsigned long index) {
// Populating the buffer.
while (waypoint_buffer.back()->DistanceSquared(waypoint_buffer.front()) <= horizon_square) {
std::vector<SimpleWaypointPtr> next_waypoints = waypoint_buffer.back()->GetNextWaypoint();
SimpleWaypointPtr furthest_waypoint = waypoint_buffer.back();
std::vector<SimpleWaypointPtr> next_waypoints = furthest_waypoint->GetNextWaypoint();
uint64_t selection_index = 0u;
// Pseudo-randomized path selection if found more than one choice.
if (next_waypoints.size() > 1) {
selection_index = static_cast<uint64_t>(pgen.next()) % next_waypoints.size();
}
SimpleWaypointPtr next_wp = next_waypoints.at(selection_index);
if (next_wp == nullptr) {
for (auto &wp : next_waypoints) {
if (wp != nullptr) {
next_wp = wp;
break;
}
// Arranging selection points from right to left.
std::sort(next_waypoints.begin(), next_waypoints.end(),
[&furthest_waypoint](const SimpleWaypointPtr &a, const SimpleWaypointPtr &b) {
float a_x_product = DeviationCrossProduct(furthest_waypoint->GetLocation(),
furthest_waypoint->GetForwardVector(),
a->GetLocation());
float b_x_product = DeviationCrossProduct(furthest_waypoint->GetLocation(),
furthest_waypoint->GetForwardVector(),
b->GetLocation());
return a_x_product < b_x_product;
});
double r_sample = random_devices.at(actor_id).next();
double s_bucket = 100.0 / next_waypoints.size();
selection_index = static_cast<uint64_t>(std::floor(r_sample/s_bucket));
} else if (next_waypoints.size() == 0) {
if (!parameters.GetOSMMode()) {
std::cout << "This map has dead-end roads, please change the set_open_street_map parameter to true" << std::endl;
}
marked_for_removal.push_back(actor_id);
break;
}
PushWaypoint(actor_id, track_traffic, waypoint_buffer, next_wp);
SimpleWaypointPtr next_wp_selection = next_waypoints.at(selection_index);
PushWaypoint(actor_id, track_traffic, waypoint_buffer, next_wp_selection);
}
ExtendAndFindSafeSpace(actor_id, is_at_junction_entrance, waypoint_buffer);

View File

@ -34,13 +34,15 @@ private:
TrackTraffic &track_traffic;
const LocalMapPtr &local_map;
Parameters &parameters;
// Array of vehicles marked by stages for removal.
std::vector<ActorId>& marked_for_removal;
LocalizationFrame &output_array;
cc::DebugHelper &debug_helper;
LaneChangeLocationMap last_lane_change_location;
ActorIdSet vehicles_at_junction;
using SimpleWaypointPair = std::pair<SimpleWaypointPtr, SimpleWaypointPtr>;
std::unordered_map<ActorId, SimpleWaypointPair> vehicles_at_junction_entrance;
RandomGenerator<> pgen;
RandomGeneratorMap &random_devices;
SimpleWaypointPtr AssignLaneChange(const ActorId actor_id,
const cg::Location vehicle_location,
@ -60,8 +62,10 @@ public:
TrackTraffic &track_traffic,
const LocalMapPtr &local_map,
Parameters &parameters,
std::vector<ActorId>& marked_for_removal,
LocalizationFrame &output_array,
cc::DebugHelper &debug_helper);
cc::DebugHelper &debug_helper,
RandomGeneratorMap &random_devices);
void Update(const unsigned long index) override;

View File

@ -5,16 +5,19 @@
// For a copy, see <https://opensource.org/licenses/MIT>.
#include "carla/trafficmanager/LocalizationUtils.h"
#include "carla/trafficmanager/Constants.h"
namespace carla {
namespace traffic_manager {
using constants::Collision::EPSILON;
float DeviationCrossProduct(const cg::Location &reference_location,
const cg::Vector3D &heading_vector,
const cg::Location &target_location) {
cg::Vector3D next_vector = target_location - reference_location;
float vector_magnitude_epsilon = 2.0f * std::numeric_limits<float>::epsilon();
next_vector = next_vector.MakeSafeUnitVector(vector_magnitude_epsilon);
next_vector = next_vector.MakeSafeUnitVector(EPSILON);
const float cross_z = heading_vector.x * next_vector.y - heading_vector.y * next_vector.x;
return cross_z;
}
@ -23,11 +26,10 @@ float DeviationDotProduct(const cg::Location &reference_location,
const cg::Vector3D &heading_vector,
const cg::Location &target_location) {
cg::Vector3D next_vector = target_location - reference_location;
float vector_magnitude_epsilon = 2.0f * std::numeric_limits<float>::epsilon();
next_vector.z = 0.0f;
next_vector = next_vector.MakeSafeUnitVector(vector_magnitude_epsilon);
next_vector = next_vector.MakeSafeUnitVector(EPSILON);
cg::Vector3D heading_vector_flat(heading_vector.x, heading_vector.y, 0);
heading_vector_flat = heading_vector_flat.MakeSafeUnitVector(vector_magnitude_epsilon);
heading_vector_flat = heading_vector_flat.MakeSafeUnitVector(EPSILON);
const float dot_product = cg::Math::Dot(next_vector, heading_vector_flat);
return dot_product;
}

View File

@ -12,6 +12,7 @@ using namespace constants::WaypointSelection;
using namespace constants::SpeedThreshold;
using constants::HybridMode::HYBRID_MODE_DT;
using constants::HybridMode::HYBRID_MODE_DT_FL;
MotionPlanStage::MotionPlanStage(
const std::vector<ActorId> &vehicle_id_list,
@ -26,6 +27,7 @@ MotionPlanStage::MotionPlanStage(
const LocalizationFrame &localization_frame,
const CollisionFrame&collision_frame,
const TLFrame &tl_frame,
const cc::World &world,
ControlFrame &output_array)
: vehicle_id_list(vehicle_id_list),
simulation_state(simulation_state),
@ -39,6 +41,7 @@ MotionPlanStage::MotionPlanStage(
localization_frame(localization_frame),
collision_frame(collision_frame),
tl_frame(tl_frame),
world(world),
output_array(output_array) {}
void MotionPlanStage::Update(const unsigned long index) {
@ -64,10 +67,11 @@ void MotionPlanStage::Update(const unsigned long index) {
dot_product *= -1.0f;
}
const float current_deviation = dot_product;
current_timestamp = world.GetSnapshot().GetTimestamp();
// If previous state for vehicle not found, initialize state entry.
if (pid_state_map.find(actor_id) == pid_state_map.end()) {
const auto initial_state = StateEntry{chr::system_clock::now(), 0.0f, 0.0f, 0.0f, 0.0f};
const auto initial_state = StateEntry{current_timestamp, 0.0f, 0.0f, 0.0f, 0.0f};
pid_state_map.insert({actor_id, initial_state});
}
@ -96,7 +100,6 @@ void MotionPlanStage::Update(const unsigned long index) {
bool collision_emergency_stop = collision_response.first;
float dynamic_target_velocity = collision_response.second;
// Don't enter junction if there isn't enough free space after the junction.
bool safe_after_junction = SafeAfterJunction(localization, tl_hazard, collision_emergency_stop);
@ -107,13 +110,12 @@ void MotionPlanStage::Update(const unsigned long index) {
cg::Transform teleportation_transform;
// If physics is enabled for the vehicle, use PID controller.
const auto current_time = chr::system_clock::now();
StateEntry current_state;
if (ego_physics_enabled) {
// State update for vehicle.
current_state = PID::StateUpdate(previous_state, ego_speed, dynamic_target_velocity,
current_deviation, current_time);
current_deviation, current_timestamp);
// Controller actuation.
actuation_signal = PID::RunStep(current_state, previous_state,
@ -130,23 +132,23 @@ void MotionPlanStage::Update(const unsigned long index) {
// For physics-less vehicles, determine position and orientation for teleportation.
else {
// Flushing controller state for vehicle.
current_state = {chr::system_clock::now(),
current_state = {current_timestamp,
0.0f, 0.0f,
0.0f, 0.0f};
// Add entry to teleportation duration clock table if not present.
if (teleportation_instance.find(actor_id) == teleportation_instance.end()) {
teleportation_instance.insert({actor_id, chr::system_clock::now()});
teleportation_instance.insert({actor_id, current_timestamp});
}
// Measuring time elapsed since last teleportation for the vehicle.
chr::duration<float> elapsed_time = current_time - teleportation_instance.at(actor_id);
double elapsed_time = current_timestamp.elapsed_seconds - teleportation_instance.at(actor_id).elapsed_seconds;
// Find a location ahead of the vehicle for teleportation to achieve intended velocity.
if (!emergency_stop && (parameters.GetSynchronousMode() || elapsed_time.count() > HYBRID_MODE_DT)) {
if (!emergency_stop && (parameters.GetSynchronousMode() || elapsed_time > HYBRID_MODE_DT)) {
// Target displacement magnitude to achieve target velocity.
const float target_displacement = dynamic_target_velocity * HYBRID_MODE_DT;
const float target_displacement = dynamic_target_velocity * HYBRID_MODE_DT_FL;
const SimpleWaypointPtr teleport_target_waypoint = GetTargetWaypoint(waypoint_buffer, target_displacement).first;
// Construct target transform to accurately achieve desired velocity.

View File

@ -29,12 +29,14 @@ private:
const LocalizationFrame &localization_frame;
const CollisionFrame &collision_frame;
const TLFrame &tl_frame;
const cc::World &world;
// Structure holding the controller state for registered vehicles.
std::unordered_map<ActorId, StateEntry> pid_state_map;
// Structure to keep track of duration between teleportation
// in hybrid physics mode.
std::unordered_map<ActorId, TimeInstance> teleportation_instance;
std::unordered_map<ActorId, cc::Timestamp> teleportation_instance;
ControlFrame &output_array;
cc::Timestamp current_timestamp;
std::pair<bool, float> CollisionHandling(const CollisionHazardData &collision_hazard,
const bool tl_hazard,
@ -59,6 +61,7 @@ public:
const LocalizationFrame &localization_frame,
const CollisionFrame &collision_frame,
const TLFrame &tl_frame,
const cc::World &world,
ControlFrame &output_array);
void Update(const unsigned long index);

View File

@ -28,7 +28,7 @@ StateEntry StateUpdate(StateEntry previous_state,
float current_velocity,
float target_velocity,
float angular_deviation,
TimeInstance current_time) {
cc::Timestamp current_time) {
StateEntry current_state = {
current_time,
angular_deviation,

View File

@ -133,6 +133,10 @@ void Parameters::SetHybridPhysicsRadius(const float radius) {
hybrid_physics_radius.store(new_radius);
}
void Parameters::SetOSMMode(const bool mode_switch) {
osm_mode.store(mode_switch);
}
//////////////////////////////////// GETTERS //////////////////////////////////
float Parameters::GetHybridPhysicsRadius() const {
@ -269,5 +273,10 @@ bool Parameters::GetHybridPhysicsMode() const {
return hybrid_physics_mode.load();
}
bool Parameters::GetOSMMode() const {
return osm_mode.load();
}
} // namespace traffic_manager
} // namespace carla

View File

@ -64,6 +64,8 @@ private:
std::atomic<bool> hybrid_physics_mode{false};
/// Hybrid physics radius.
std::atomic<float> hybrid_physics_radius {70.0};
/// Parameter specifying Open Street Map mode.
std::atomic<bool> osm_mode {true};
public:
Parameters();
@ -126,6 +128,9 @@ public:
/// Method to set hybrid physics radius.
void SetHybridPhysicsRadius(const float radius);
/// Method to set Open Street Map mode.
void SetOSMMode(const bool mode_switch);
///////////////////////////////// GETTERS /////////////////////////////////////
/// Method to retrieve hybrid physics radius.
@ -170,6 +175,9 @@ public:
/// Method to retrieve hybrid physics mode.
bool GetHybridPhysicsMode() const;
/// Method to get Open Street Map mode.
bool GetOSMMode() const;
/// Synchronous mode time out variable.
std::chrono::duration<double, std::milli> synchronous_time_out;
};

View File

@ -1,20 +1,24 @@
#pragma once
#include <random>
#include <unordered_map>
#include "carla/rpc/ActorId.h"
namespace carla {
namespace traffic_manager {
template<class T = double,
class = std::enable_if_t<std::is_floating_point<T>::value>
> class RandomGenerator {
class RandomGenerator {
public:
RandomGenerator(): mt{std::random_device{}()}, dist(0.0, 100.0) {}
T next() { return dist(mt); }
RandomGenerator(const uint64_t seed): mt(std::mt19937(seed)), dist(0.0, 100.0) {}
double next() { return dist(mt); }
private:
std::mt19937 mt;
std::uniform_real_distribution<T> dist;
std::uniform_real_distribution<double> dist;
};
using RandomGeneratorMap = std::unordered_map<carla::rpc::ActorId, RandomGenerator>;
} // namespace traffic_manager
} // namespace carla

View File

@ -7,7 +7,6 @@
namespace carla {
namespace traffic_manager {
using constants::TrafficLight::NO_SIGNAL_PASSTHROUGH_INTERVAL;
using constants::TrafficLight::DOUBLE_NO_SIGNAL_PASSTHROUGH_INTERVAL;
using constants::WaypointSelection::JUNCTION_LOOK_AHEAD;
@ -16,12 +15,16 @@ TrafficLightStage::TrafficLightStage(
const SimulationState &simulation_state,
const BufferMap &buffer_map,
const Parameters &parameters,
TLFrame &output_array)
const cc::World &world,
TLFrame &output_array,
RandomGeneratorMap &random_devices)
: vehicle_id_list(vehicle_id_list),
simulation_state(simulation_state),
buffer_map(buffer_map),
parameters(parameters),
output_array(output_array) {}
world(world),
output_array(output_array),
random_devices(random_devices) {}
void TrafficLightStage::Update(const unsigned long index) {
bool traffic_light_hazard = false;
@ -31,7 +34,7 @@ void TrafficLightStage::Update(const unsigned long index) {
const SimpleWaypointPtr look_ahead_point = GetTargetWaypoint(waypoint_buffer, JUNCTION_LOOK_AHEAD).first;
const JunctionID junction_id = look_ahead_point->GetWaypoint()->GetJunctionId();
const TimeInstance current_time = chr::system_clock::now();
current_timestamp = world.GetSnapshot().GetTimestamp();
const TrafficLightState tl_state = simulation_state.GetTLS(ego_actor_id);
const TLS traffic_light_state = tl_state.tl_state;
@ -41,24 +44,26 @@ void TrafficLightStage::Update(const unsigned long index) {
// junction and there is a red or yellow light.
if (is_at_traffic_light &&
traffic_light_state != TLS::Green &&
parameters.GetPercentageRunningLight(ego_actor_id) <= pgen.next()) {
traffic_light_state != TLS::Off &&
parameters.GetPercentageRunningLight(ego_actor_id) <= random_devices.at(ego_actor_id).next()) {
traffic_light_hazard = true;
}
// Handle entry negotiation at non-signalised junction.
else if (look_ahead_point->CheckJunction()
&& !is_at_traffic_light
&& traffic_light_state != TLS::Green
&& parameters.GetPercentageRunningSign(ego_actor_id) <= pgen.next()) {
else if (look_ahead_point->CheckJunction() &&
!is_at_traffic_light &&
traffic_light_state != TLS::Green &&
traffic_light_state != TLS::Off &&
parameters.GetPercentageRunningSign(ego_actor_id) <= random_devices.at(ego_actor_id).next()) {
traffic_light_hazard = HandleNonSignalisedJunction(ego_actor_id, junction_id, current_time);
traffic_light_hazard = HandleNonSignalisedJunction(ego_actor_id, junction_id, current_timestamp);
}
output_array.at(index) = traffic_light_hazard;
}
bool TrafficLightStage::HandleNonSignalisedJunction(const ActorId ego_actor_id, const JunctionID junction_id,
const TimeInstance current_time) {
cc::Timestamp timestamp) {
bool traffic_light_hazard = false;
@ -78,9 +83,9 @@ bool TrafficLightStage::HandleNonSignalisedJunction(const ActorId ego_actor_id,
need_to_issue_new_ticket = true;
} else {
const TimeInstance &previous_ticket = vehicle_last_ticket.at(ego_actor_id);
const chr::duration<double> diff = current_time - previous_ticket;
if (diff.count() > DOUBLE_NO_SIGNAL_PASSTHROUGH_INTERVAL) {
const cc::Timestamp &previous_ticket = vehicle_last_ticket.at(ego_actor_id);
const double diff = timestamp.elapsed_seconds - previous_ticket.elapsed_seconds;
if (diff > DOUBLE_NO_SIGNAL_PASSTHROUGH_INTERVAL) {
need_to_issue_new_ticket = true;
}
}
@ -91,16 +96,17 @@ bool TrafficLightStage::HandleNonSignalisedJunction(const ActorId ego_actor_id,
if (need_to_issue_new_ticket) {
if (junction_last_ticket.find(junction_id) != junction_last_ticket.end()) {
TimeInstance &last_ticket = junction_last_ticket.at(junction_id);
const chr::duration<double> diff = current_time - last_ticket;
if (diff.count() > 0.0) {
last_ticket = current_time + chr::seconds(NO_SIGNAL_PASSTHROUGH_INTERVAL);
cc::Timestamp &last_ticket = junction_last_ticket.at(junction_id);
const double diff = timestamp.elapsed_seconds - last_ticket.elapsed_seconds;
if (diff > 0.0) {
last_ticket.elapsed_seconds = timestamp.elapsed_seconds + DOUBLE_NO_SIGNAL_PASSTHROUGH_INTERVAL;
} else {
last_ticket += chr::seconds(NO_SIGNAL_PASSTHROUGH_INTERVAL);
last_ticket.elapsed_seconds += DOUBLE_NO_SIGNAL_PASSTHROUGH_INTERVAL;
}
} else {
junction_last_ticket.insert({junction_id, current_time +
chr::seconds(NO_SIGNAL_PASSTHROUGH_INTERVAL)});
cc::Timestamp &new_ticket = timestamp;
new_ticket.elapsed_seconds += DOUBLE_NO_SIGNAL_PASSTHROUGH_INTERVAL;
junction_last_ticket.insert({junction_id, new_ticket});
}
if (vehicle_last_ticket.find(ego_actor_id) != vehicle_last_ticket.end()) {
vehicle_last_ticket.at(ego_actor_id) = junction_last_ticket.at(junction_id);
@ -111,9 +117,9 @@ bool TrafficLightStage::HandleNonSignalisedJunction(const ActorId ego_actor_id,
}
// If current time is behind ticket time, then do not enter junction.
const TimeInstance &current_ticket = vehicle_last_ticket.at(ego_actor_id);
const chr::duration<double> diff = current_ticket - current_time;
if (diff.count() > 0.0) {
const cc::Timestamp current_ticket = vehicle_last_ticket.at(ego_actor_id);
const double diff = current_ticket.elapsed_seconds - timestamp.elapsed_seconds;
if (diff > 0.0) {
traffic_light_hazard = true;
}

View File

@ -18,24 +18,28 @@ private:
const SimulationState &simulation_state;
const BufferMap &buffer_map;
const Parameters &parameters;
const cc::World &world;
/// Map containing the time ticket issued for vehicles.
std::unordered_map<ActorId, TimeInstance> vehicle_last_ticket;
std::unordered_map<ActorId, cc::Timestamp> vehicle_last_ticket;
/// Map containing the previous time ticket issued for junctions.
std::unordered_map<JunctionID, TimeInstance> junction_last_ticket;
std::unordered_map<JunctionID, cc::Timestamp> junction_last_ticket;
/// Map containing the previous junction visited by a vehicle.
std::unordered_map<ActorId, JunctionID> vehicle_last_junction;
TLFrame &output_array;
RandomGenerator<> pgen;
RandomGeneratorMap &random_devices;
cc::Timestamp current_timestamp;
bool HandleNonSignalisedJunction(const ActorId ego_actor_id, const JunctionID junction_id,
const TimeInstance current_time);
cc::Timestamp timestamp);
public:
TrafficLightStage(const std::vector<ActorId> &vehicle_id_list,
const SimulationState &Simulation_state,
const BufferMap &buffer_map,
const Parameters &parameters,
TLFrame &output_array);
const cc::World &world,
TLFrame &output_array,
RandomGeneratorMap &random_devices);
void Update(const unsigned long index) override;

View File

@ -57,6 +57,14 @@ public:
return (_port > 1023);
}
/// Method to set Open Street Map mode.
void SetOSMMode(const bool mode_switch) {
TrafficManagerBase* tm_ptr = GetTM(_port);
if (tm_ptr != nullptr) {
tm_ptr->SetOSMMode(mode_switch);
}
}
/// This method sets the hybrid physics mode.
void SetHybridPhysicsMode(const bool mode_switch) {
TrafficManagerBase* tm_ptr = GetTM(_port);
@ -222,6 +230,14 @@ public:
}
}
/// Method to set randomization seed.
void SetRandomDeviceSeed(const uint64_t seed) {
TrafficManagerBase* tm_ptr = GetTM(_port);
if(tm_ptr != nullptr){
tm_ptr->SetRandomDeviceSeed(seed);
}
}
private:
void CreateTrafficManagerServer(
@ -237,7 +253,6 @@ private:
std::lock_guard<std::mutex> lock(_mutex);
auto it = _tm_map.find(port);
if (it != _tm_map.end()) {
_mutex.unlock();
return it->second;
}
return nullptr;

View File

@ -104,6 +104,11 @@ public:
/// Method to set hybrid physics radius.
virtual void SetHybridPhysicsRadius(const float radius) = 0;
/// Method to set randomization seed.
virtual void SetRandomDeviceSeed(const uint64_t seed) = 0;
/// Method to set Open Street Map mode.
virtual void SetOSMMode(const bool mode_switch) = 0;
protected:
};

View File

@ -193,6 +193,18 @@ public:
_client->call("set_hybrid_physics_radius", radius);
}
/// Method to set randomization seed.
void SetRandomDeviceSeed(const uint64_t seed) {
DEBUG_ASSERT(_client != nullptr);
_client->call("set_random_device_seed", seed);
}
/// Method to set Open Street Map mode.
void SetOSMMode(const bool mode_switch) {
DEBUG_ASSERT(_client != nullptr);
_client->call("set_osm_mode", mode_switch);
}
private:
/// RPC client.

View File

@ -37,8 +37,10 @@ TrafficManagerLocal::TrafficManagerLocal(
track_traffic,
local_map,
parameters,
marked_for_removal,
localization_frame,
debug_helper)),
debug_helper,
random_devices)),
collision_stage(CollisionStage(vehicle_id_list,
simulation_state,
@ -46,13 +48,16 @@ TrafficManagerLocal::TrafficManagerLocal(
track_traffic,
parameters,
collision_frame,
debug_helper)),
debug_helper,
random_devices)),
traffic_light_stage(TrafficLightStage(vehicle_id_list,
simulation_state,
buffer_map,
parameters,
tl_frame)),
world,
tl_frame,
random_devices)),
motion_plan_stage(MotionPlanStage(vehicle_id_list,
simulation_state,
@ -66,11 +71,13 @@ TrafficManagerLocal::TrafficManagerLocal(
localization_frame,
collision_frame,
tl_frame,
world,
control_frame)),
alsm(ALSM(registered_vehicles,
buffer_map,
track_traffic,
marked_for_removal,
parameters,
world,
local_map,
@ -78,7 +85,8 @@ TrafficManagerLocal::TrafficManagerLocal(
localization_stage,
collision_stage,
traffic_light_stage,
motion_plan_stage)),
motion_plan_stage,
random_devices)),
server(TrafficManagerServer(RPCportTM, static_cast<carla::traffic_manager::TrafficManagerBase *>(this))) {
@ -123,7 +131,7 @@ void TrafficManagerLocal::Run() {
// Wait for external trigger to initiate cycle in synchronous mode.
if (synchronous_mode) {
std::unique_lock<std::mutex> lock(step_execution_mutex);
step_begin_trigger.wait(lock, [this]() {return step_begin.load();});
step_begin_trigger.wait(lock, [this]() {return step_begin.load() || !run_traffic_manger.load();});
step_begin.store(false);
}
@ -131,9 +139,9 @@ void TrafficManagerLocal::Run() {
if (!synchronous_mode && hybrid_physics_mode) {
TimePoint current_instance = chr::system_clock::now();
chr::duration<float> elapsed_time = current_instance - previous_update_instance;
float time_to_wait = HYBRID_MODE_DT - elapsed_time.count();
if (time_to_wait > 0.0f) {
std::this_thread::sleep_for(chr::duration<float>(time_to_wait));
chr::duration<float> time_to_wait = chr::duration<float>(HYBRID_MODE_DT) - elapsed_time;
if (time_to_wait > chr::duration<float>(0.0f)) {
std::this_thread::sleep_for(time_to_wait);
}
previous_update_instance = current_instance;
}
@ -218,6 +226,9 @@ bool TrafficManagerLocal::SynchronousTick() {
void TrafficManagerLocal::Stop() {
run_traffic_manger.store(false);
if (parameters.GetSynchronousMode()) {
step_begin_trigger.notify_one();
}
if (worker_thread) {
if (worker_thread->joinable()) {
@ -232,6 +243,7 @@ void TrafficManagerLocal::Stop() {
track_traffic.Clear();
previous_update_instance = chr::system_clock::now();
current_reserved_capacity = 0u;
random_devices.clear();
simulation_state.Reset();
localization_stage.Reset();
@ -268,15 +280,17 @@ void TrafficManagerLocal::Reset() {
void TrafficManagerLocal::RegisterVehicles(const std::vector<ActorPtr> &vehicle_list) {
registered_vehicles.Insert(vehicle_list);
for (const ActorPtr &vehicle: vehicle_list) {
random_devices.insert({vehicle->GetId(), RandomGenerator(seed)});
}
}
void TrafficManagerLocal::UnregisterVehicles(const std::vector<ActorPtr> &actor_list) {
std::vector<ActorId> actor_id_list;
for (auto &actor : actor_list) {
actor_id_list.push_back(actor->GetId());
alsm.RemoveActor(actor->GetId(), true);
}
registered_vehicles.Remove(actor_id_list);
}
void TrafficManagerLocal::SetPercentageSpeedDifference(const ActorPtr &actor, const float percentage) {
@ -335,6 +349,10 @@ void TrafficManagerLocal::SetHybridPhysicsRadius(const float radius) {
parameters.SetHybridPhysicsRadius(radius);
}
void TrafficManagerLocal::SetOSMMode(const bool mode_switch) {
parameters.SetOSMMode(mode_switch);
}
bool TrafficManagerLocal::CheckAllFrozen(TLGroup tl_to_freeze) {
for (auto &elem : tl_to_freeze) {
if (!elem->IsFrozen() || elem->GetState() != TLS::Red) {
@ -345,44 +363,32 @@ bool TrafficManagerLocal::CheckAllFrozen(TLGroup tl_to_freeze) {
}
void TrafficManagerLocal::ResetAllTrafficLights() {
// Filter based on wildcard pattern.
const auto world_traffic_lights = world.GetActors()->Filter("*traffic_light*");
std::vector<TLGroup> list_of_all_groups;
TLGroup tl_to_freeze;
std::vector<carla::ActorId> list_of_ids;
for (auto iter = world_traffic_lights->begin(); iter != world_traffic_lights->end(); iter++) {
auto tl = *iter;
if (!(std::find(list_of_ids.begin(), list_of_ids.end(), tl->GetId()) != list_of_ids.end())) {
const TLGroup tl_group = boost::static_pointer_cast<cc::TrafficLight>(tl)->GetGroupTrafficLights();
list_of_all_groups.push_back(tl_group);
for (uint64_t i = 0u; i < tl_group.size(); i++) {
list_of_ids.push_back(tl_group.at(i).get()->GetId());
if (i != 0u) {
tl_to_freeze.push_back(tl_group.at(i));
}
}
}
}
for (TLGroup &tl_group : list_of_all_groups) {
tl_group.front()->SetState(TLS::Green);
std::for_each(
tl_group.begin() + 1, tl_group.end(),
[](auto &tl) { tl->SetState(TLS::Red); });
}
while (!CheckAllFrozen(tl_to_freeze)) {
for (auto &tln : tl_to_freeze) {
tln->SetState(TLS::Red);
tln->Freeze(true);
}
tl_group.front()->ResetGroup();
}
}
void TrafficManagerLocal::SetSynchronousMode(bool mode) {
const bool previous_mode = parameters.GetSynchronousMode();
parameters.SetSynchronousMode(mode);
if (previous_mode && !mode) {
step_begin.store(true);
step_begin_trigger.notify_one();
}
}
void TrafficManagerLocal::SetSynchronousModeTimeOutInMiliSecond(double time) {
@ -397,5 +403,10 @@ std::vector<ActorId> TrafficManagerLocal::GetRegisteredVehiclesIDs() {
return registered_vehicles.GetIDList();
}
void TrafficManagerLocal::SetRandomDeviceSeed(const uint64_t _seed) {
seed = _seed;
ResetAllTrafficLights();
}
} // namespace traffic_manager
} // namespace carla

View File

@ -21,6 +21,7 @@
#include "carla/trafficmanager/AtomicActorSet.h"
#include "carla/trafficmanager/InMemoryMap.h"
#include "carla/trafficmanager/Parameters.h"
#include "carla/trafficmanager/RandomGenerator.h"
#include "carla/trafficmanager/SimulationState.h"
#include "carla/trafficmanager/TrackTraffic.h"
#include "carla/trafficmanager/TrafficManagerBase.h"
@ -109,6 +110,11 @@ private:
std::condition_variable step_end_trigger;
/// Single worker thread for sequential execution of sub-components.
std::unique_ptr<std::thread> worker_thread;
/// Structure holding random devices per vehicle.
RandomGeneratorMap random_devices;
/// Randomization seed.
uint64_t seed {static_cast<uint64_t>(time(NULL))};
std::vector<ActorId> marked_for_removal;
/// Method to check if all traffic lights are frozen in a group.
bool CheckAllFrozen(TLGroup tl_to_freeze);
@ -148,7 +154,7 @@ public:
void RegisterVehicles(const std::vector<ActorPtr> &actor_list);
/// This method unregisters a vehicle from traffic manager.
void UnregisterVehicles(const std::vector<ActorPtr> &actor_list);
void UnregisterVehicles(const std::vector<ActorPtr> &actor_list);
/// Method to set a vehicle's % decrease in velocity with respect to the speed limit.
/// If less than 0, it's a % increase.
@ -196,6 +202,9 @@ public:
/// Method to reset all traffic light groups to the initial stage.
void ResetAllTrafficLights();
/// Method to start all traffic light groups to the initial stage.
void StartAllTrafficLights();
/// Get CARLA episode information.
carla::client::detail::EpisodeProxy &GetEpisodeProxy();
@ -214,6 +223,12 @@ public:
/// Method to set hybrid physics radius.
void SetHybridPhysicsRadius(const float radius);
/// Method to set randomization seed.
void SetRandomDeviceSeed(const uint64_t _seed);
/// Method to set Open Street Map mode.
void SetOSMMode(const bool mode_switch);
};
} // namespace traffic_manager

View File

@ -181,6 +181,10 @@ void TrafficManagerRemote::SetHybridPhysicsRadius(const float radius) {
client.SetHybridPhysicsRadius(radius);
}
void TrafficManagerRemote::SetOSMMode(const bool mode_switch) {
client.SetOSMMode(mode_switch);
}
void TrafficManagerRemote::ResetAllTrafficLights() {
client.ResetAllTrafficLights();
}
@ -205,5 +209,9 @@ carla::client::detail::EpisodeProxy& TrafficManagerRemote::GetEpisodeProxy() {
return episodeProxyTM;
}
void TrafficManagerRemote::SetRandomDeviceSeed(const uint64_t seed) {
client.SetRandomDeviceSeed(seed);
}
} // namespace traffic_manager
} // namespace carla

Some files were not shown because too many files have changed in this diff Show More