diff --git a/.github/pull_request_template.md b/.github/pull_request_template.md index 20309c23d..fcf482fb7 100644 --- a/.github/pull_request_template.md +++ b/.github/pull_request_template.md @@ -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 --> diff --git a/CHANGELOG.md b/CHANGELOG.md index 25900160e..4dccd5989 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -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::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 LiDAR’s 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 diff --git a/Co-Simulation/PTV-Vissim/vissim_integration/carla_simulation.py b/Co-Simulation/PTV-Vissim/vissim_integration/carla_simulation.py index f7f1b1eab..1d82bef17 100644 --- a/Co-Simulation/PTV-Vissim/vissim_integration/carla_simulation.py +++ b/Co-Simulation/PTV-Vissim/vissim_integration/carla_simulation.py @@ -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)) diff --git a/Co-Simulation/Sumo/run_synchronization.py b/Co-Simulation/Sumo/run_synchronization.py index b5b28d9af..1ded68872 100644 --- a/Co-Simulation/Sumo/run_synchronization.py +++ b/Co-Simulation/Sumo/run_synchronization.py @@ -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, diff --git a/Co-Simulation/Sumo/spawn_npc_sumo.py b/Co-Simulation/Sumo/spawn_npc_sumo.py index 9448bb9ac..1dd28d947 100644 --- a/Co-Simulation/Sumo/spawn_npc_sumo.py +++ b/Co-Simulation/Sumo/spawn_npc_sumo.py @@ -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', diff --git a/Docs/adv_ptv.md b/Docs/adv_ptv.md index 376e77373..0fcdba9e2 100644 --- a/Docs/adv_ptv.md +++ b/Docs/adv_ptv.md @@ -4,8 +4,8 @@ CARLA has developed a co-simulation feature with PTV-Vissim. This allows to dist * [__Requisites__](#requisites) * [__Run a co-simulation__](#run-the-co-simulation) - * [Create a new network](#create-a-new-network) - + * [Create a new network](#create-a-new-network) + --- ## Requisites diff --git a/Docs/adv_recorder.md b/Docs/adv_recorder.md index 235229cce..79d2c5c63 100644 --- a/Docs/adv_recorder.md +++ b/Docs/adv_recorder.md @@ -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 diff --git a/Docs/adv_rendering_options.md b/Docs/adv_rendering_options.md index 08f853208..9dd27fa0c 100644 --- a/Docs/adv_rendering_options.md +++ b/Docs/adv_rendering_options.md @@ -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 +
-

- Deprecated: emulate the virtual display -

+ + Show deprecated tutorial on how to emulate the virtual display + !!! Warning This tutorial is deprecated. To run headless CARLA, please [__run CARLA in a Docker__](build_docker.md). diff --git a/Docs/adv_rss.md b/Docs/adv_rss.md index 7ea7a0b25..12df5f156 100644 --- a/Docs/adv_rss.md +++ b/Docs/adv_rss.md @@ -1,14 +1,14 @@ # RSS -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. +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) -* [__Current state__](#current-state) - * [RssSensor](#rsssensor) - * [RssRestrictor](#rssrestrictor) +* [__Overview__](#overview) +* [__Compilation__](#compilation) + * [Dependencies](#dependencies) + * [Build](#build) +* [__Current state__](#current-state) + * [RssSensor](#rsssensor) + * [RssRestrictor](#rssrestrictor) !!! Important This feature is a work in progress. Right now, it is only available for the Linux build. @@ -16,29 +16,29 @@ CARLA integrates the [C++ Library for Responsibility Sensitive Safety](https://g --- ## Overview -The RSS library implements a mathematical model for safety assurance. It receives sensor information, and provides restrictions to the controllers of a vehicle. To sum up, the RSS module uses the sensor data to define __situations__. A situation describes the state of the ego vehicle with an element of the environment. For each situation, safety checks are made, and a proper response is calculated. The overall response is the result of all of the combined. For specific information on the library, read the [documentation](https://intel.github.io/ad-rss-lib/), especially the [Background section](https://intel.github.io/ad-rss-lib/ad_rss/Overview/). +The RSS library implements a mathematical model for safety assurance. It receives sensor information, and provides restrictions to the controllers of a vehicle. To sum up, the RSS module uses the sensor data to define __situations__. A situation describes the state of the ego vehicle with an element of the environment. For each situation, safety checks are made, and a proper response is calculated. The overall response is the result of all of the combined. For specific information on the library, read the [documentation](https://intel.github.io/ad-rss-lib/), especially the [Background section](https://intel.github.io/ad-rss-lib/ad_rss/Overview/). -This is implemented in CARLA using two elements. +This is implemented in CARLA using two elements. -* __RssSensor__ is in charge of the situation analysis, and response generation using the *ad-rss-lib*. -* __RssRestrictor__ applies the response by restricting the commands of the vehicle. +* __RssSensor__ is in charge of the situation analysis, and response generation using the *ad-rss-lib*. +* __RssRestrictor__ applies the response by restricting the commands of the vehicle. -The following image sketches the integration of __RSS__ into the CARLA architecture. +The following image sketches the integration of __RSS__ into the CARLA architecture. ![Interate RSS into CARLA](img/rss_carla_integration_architecture.png) -__1. The server.__ -     __-__ Sends a camera image to the client. (Only if the client needs visualization). -     __-__ Provides the RssSensor with world data. -     __-__ Sends a physics model of the vehicle to the RssRestrictor. (Only if the default values are overwritten). -__2. The client.__ -     __-__ Provides the *RssSensor* with some [parameters](https://intel.github.io/ad-rss-lib/ad_rss/Appendix-ParameterDiscussion/) to be considered. -     __-__ Sends to the *RssResrictor* an initial [carla.VehicleControl](python_api.md#carla.VehicleControl). -__3. The RssSensor.__ -     __-__ Uses the *ad-rss-lib* to extract situations, do safety checks, and generate a response. -     __-__ Sends the *RssRestrictor* a response containing the proper response and aceleration restrictions to be applied. -__4. The RssRestrictor__ -     __-__ If the client asks for it, applies the response to the [carla.VehicleControl](python_api.md#carla.VehicleControl), and returns the resulting one. +__1. The server.__ +     __-__ Sends a camera image to the client. (Only if the client needs visualization). +     __-__ Provides the RssSensor with world data. +     __-__ Sends a physics model of the vehicle to the RssRestrictor. (Only if the default values are overwritten). +__2. The client.__ +     __-__ Provides the *RssSensor* with some [parameters](https://intel.github.io/ad-rss-lib/ad_rss/Appendix-ParameterDiscussion/) to be considered. +     __-__ Sends to the *RssResrictor* an initial [carla.VehicleControl](python_api.md#carla.VehicleControl). +__3. The RssSensor.__ +     __-__ Uses the *ad-rss-lib* to extract situations, do safety checks, and generate a response. +     __-__ Sends the *RssRestrictor* a response containing the proper response and aceleration restrictions to be applied. +__4. The RssRestrictor__ +     __-__ If the client asks for it, applies the response to the [carla.VehicleControl](python_api.md#carla.VehicleControl), and returns the resulting one. [![RSS sensor in CARLA](img/rss_carla_integration.png)](https://www.youtube.com/watch?v=UxKPXPT2T8Q)
Visualization of the RssSensor results.
@@ -46,20 +46,20 @@ __4. The RssRestrictor__ --- ## Compilation -The RSS integration has to be built aside from the rest of CARLA. The __ad-rss-lib__ comes with an LGPL-2.1 open-source license that creates conflict. It has to be linked statically into *libCarla*. +The RSS integration has to be built aside from the rest of CARLA. The __ad-rss-lib__ comes with an LGPL-2.1 open-source license that creates conflict. It has to be linked statically into *libCarla*. -As a reminder, the feature is only available for the Linux build so far. +As a reminder, the feature is only available for the Linux build so far. ### Dependencies There are additional prerequisites required for building RSS and its dependencies. Take a look at the [official documentation](https://intel.github.io/ad-rss-lib/BUILDING)) to know more about this. -Dependencies provided by Ubunutu (>= 16.04). +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. +The dependencies are built using [colcon](https://colcon.readthedocs.io/en/released/user/installation.html), so it has to be installed. ```sh pip3 install --user -U colcon-common-extensions ``` @@ -67,27 +67,26 @@ 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 Once this is done, the full set of dependencies and RSS components can be built. -* Compile LibCarla to work with RSS. +* Compile LibCarla to work with RSS. ```sh make LibCarla.client.rss ``` -* Compile the PythonAPI to include the RSS feature. +* Compile the PythonAPI to include the RSS feature. ```sh make PythonAPI.rss ``` -* As an alternative, a package can be built directly. +* As an alternative, a package can be built directly. ```sh make package.rss ``` @@ -103,7 +102,7 @@ So far, the server provides the sensor with ground truth data of the surrounding ### RssRestrictor -When the client calls for it, the [__carla.RssRestrictor__](python_api.md#carla.RssRestrictor) will modify the vehicle controller to best reach the desired accelerations or decelerations by a given response. +When the client calls for it, the [__carla.RssRestrictor__](python_api.md#carla.RssRestrictor) will modify the vehicle controller to best reach the desired accelerations or decelerations by a given response. Due to the stucture of [carla.VehicleControl](python_api.md#carla.VehicleControl) objects, the restrictions applied have certain limitations. These controllers include `throttle`, `brake` and `streering` values. However, due to car physics and the simple control options these might not be met. The restriction intervenes in lateral direction simply by counter steering towards the parallel lane direction. The brake will be activated if deceleration requested by RSS. This depends on vehicle mass and brake torques provided by the [carla.Vehicle](python_api.md#carla.Vehicle). @@ -112,9 +111,9 @@ Due to the stucture of [carla.VehicleControl](python_api.md#carla.VehicleControl --- -That sets the basics regarding the RSS sensor in CARLA. Find out more about the specific attributes and parameters in the [sensor reference](ref_sensors.md#rss-sensor). +That sets the basics regarding the RSS sensor in CARLA. Find out more about the specific attributes and parameters in the [sensor reference](ref_sensors.md#rss-sensor). -Open CARLA and mess around for a while. If there are any doubts, feel free to post these in the forum. +Open CARLA and mess around for a while. If there are any doubts, feel free to post these in the forum.

diff --git a/Docs/adv_sumo.md b/Docs/adv_sumo.md index 9f7485cf6..25a466c69 100644 --- a/Docs/adv_sumo.md +++ b/Docs/adv_sumo.md @@ -3,12 +3,12 @@ CARLA has developed a co-simulation feature with SUMO. This allows to distribute the tasks at will, and exploit the capabilities of each simulation in favour of the user. -* [__Requisites__](#requisites) -* [__Run a custom co-simulation__](#run-a-custom-co-simulation) - * [Create CARLA vtypes](#create-carla-vtypes) - * [Create the SUMO net](#create-the-sumo-net) - * [Run the synchronization](#run-the-synchronization) -* [__Spawn NPCs controlled by SUMO__](#spawn-npcs-controlled-by-sumo) +* [__Requisites__](#requisites) +* [__Run a custom co-simulation__](#run-a-custom-co-simulation) + * [Create CARLA vtypes](#create-carla-vtypes) + * [Create the SUMO net](#create-the-sumo-net) + * [Run the synchronization](#run-the-synchronization) +* [__Spawn NPCs controlled by SUMO__](#spawn-npcs-controlled-by-sumo) --- ## Requisites @@ -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 --tls-manager carla --sumo-gui +python3 run_synchronization.py --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 ``` --- diff --git a/Docs/adv_synchrony_timestep.md b/Docs/adv_synchrony_timestep.md index b9df6b0f0..4401471cc 100644 --- a/Docs/adv_synchrony_timestep.md +++ b/Docs/adv_synchrony_timestep.md @@ -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.__
@@ -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. diff --git a/Docs/build_docker.md b/Docs/build_docker.md index 66d114ed0..90552d2cb 100644 --- a/Docs/build_docker.md +++ b/Docs/build_docker.md @@ -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: diff --git a/Docs/build_faq.md b/Docs/build_faq.md index 160cf4991..ada389097 100644 --- a/Docs/build_faq.md +++ b/Docs/build_faq.md @@ -104,6 +104,63 @@ make PythonAPI.docs

+ +
+
+ Cannot run example scripts or "RuntimeError: rpc::rpc_error during call in function version" +
+ +![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 `/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. + +
+ + --- ## 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. diff --git a/Docs/build_linux.md b/Docs/build_linux.md index 7d3bd62a1..79377a4c9 100644 --- a/Docs/build_linux.md +++ b/Docs/build_linux.md @@ -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. - -
-

- -CARLA forum -

-
+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 Show command lines to build on Linux ```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 +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" ``` + --- @@ -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 CARLA repository

-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 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. +* __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. @@ -298,21 +340,25 @@ Now CARLA is ready to go. Here is a brief summary of the most useful `make` comm - +
make rebuildmake clean and make launch both in one command.make clean and make launch both in one command.
--- -
-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.
-

- -Go to __First steps__ -

Update CARLA

+ +

+ +First steps +

+
diff --git a/Docs/build_update.md b/Docs/build_update.md index 019b604b7..01b367ae7 100644 --- a/Docs/build_update.md +++ b/Docs/build_update.md @@ -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. diff --git a/Docs/build_windows.md b/Docs/build_windows.md index cae564269..587507c69 100644 --- a/Docs/build_windows.md +++ b/Docs/build_windows.md @@ -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. - -
-

- -CARLA forum -

-
+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
Show command lines to build on Windows +
+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. !!! 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 # 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 ```
@@ -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,27 +141,42 @@ __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. +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. - Alternatively `make LibCarla` will prepare the CARLA library to be imported anywhere. + 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. +``` +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__. + 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__. Now CARLA is ready to go. Here is a brief summary of the most useful `make` commands available. @@ -167,8 +186,7 @@ Now CARLA is ready to go. Here is a brief summary of the most useful `make` comm Description - -make help +make help Prints all available commands. @@ -189,25 +207,28 @@ Now CARLA is ready to go. Here is a brief summary of the most useful `make` comm make rebuild -make clean and make launch both in one command. +make clean and make launch both in one command. --- -
-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.
-

- -Go to __First steps__ -

Update CARLA

+ +

+ +First steps +

+
- diff --git a/Docs/cont_code_of_conduct.md b/Docs/cont_code_of_conduct.md index 30b759490..ca505f82f 100644 --- a/Docs/cont_code_of_conduct.md +++ b/Docs/cont_code_of_conduct.md @@ -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 diff --git a/Docs/cont_coding_standard.md b/Docs/cont_coding_standard.md index 1c49adaed..5c6e04d1f 100644 --- a/Docs/cont_coding_standard.md +++ b/Docs/cont_coding_standard.md @@ -1,5 +1,9 @@ # Coding standard +* [__General__](#general) +* [__Python__](#python) +* [__C++__](#c++) + --- ## General diff --git a/Docs/cont_contribution_guidelines.md b/Docs/cont_contribution_guidelines.md index 71c80bd01..b130ff6c2 100644 --- a/Docs/cont_contribution_guidelines.md +++ b/Docs/cont_contribution_guidelines.md @@ -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 ) 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 ). -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 ). +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) 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) 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 - +* [ ] 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 / +``` + +__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. \ No newline at end of file diff --git a/Docs/cont_doc_standard.md b/Docs/cont_doc_standard.md index 84a580678..71d4a5357 100644 --- a/Docs/cont_doc_standard.md +++ b/Docs/cont_doc_standard.md @@ -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 `
` to make inline jumps rather than leaving two spaces at the end of a line. - * Use `

Title

` at the beggining of a new page in order to make a Title or - `Heading` 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 `
` to make inline jumps rather than leaving two spaces at the end of a line. +* Use `

Title

` at the beggining of a new page in order to make a Title or `Heading` 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]. diff --git a/Docs/core_actors.md b/Docs/core_actors.md index fa20569f0..39102d1b6 100644 --- a/Docs/core_actors.md +++ b/Docs/core_actors.md @@ -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. diff --git a/Docs/core_concepts.md b/Docs/core_concepts.md index f6c6a4891..22e0c99e1 100644 --- a/Docs/core_concepts.md +++ b/Docs/core_concepts.md @@ -5,10 +5,10 @@ This page introduces the main features and modules in CARLA. Detailed explanatio In order to learn about the different classes and methods in the API, take a look at the [Python API reference](python_api.md). Besides, the [Code recipes](ref_code_recipes.md) reference contains some common code chunks, specially useful during these first steps. * [__First steps__](#first-steps) - * [1st- World and client](#1st-world-and-client) - * [2nd- Actors and blueprints](#2nd-actors-and-blueprints) - * [3rd- Maps and navigation](#3rd-maps-and-navigation) - * [4th- Sensors and data](#4th-sensors-and-data) + * [1st- World and client](#1st-world-and-client) + * [2nd- Actors and blueprints](#2nd-actors-and-blueprints) + * [3rd- Maps and navigation](#3rd-maps-and-navigation) + * [4th- Sensors and data](#4th-sensors-and-data) * [__Advanced steps__](#advanced-steps) !!! Important diff --git a/Docs/core_map.md b/Docs/core_map.md index 6b8ad65b0..d3621067c 100644 --- a/Docs/core_map.md +++ b/Docs/core_map.md @@ -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. @@ -125,7 +130,9 @@ while True: ### Generating a map navigation -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 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() diff --git a/Docs/download.md b/Docs/download.md index b410c9065..e6f33e586 100644 --- a/Docs/download.md +++ b/Docs/download.md @@ -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) diff --git a/Docs/img/faq_rpc_error.jpg b/Docs/img/faq_rpc_error.jpg new file mode 100644 index 000000000..55233715e Binary files /dev/null and b/Docs/img/faq_rpc_error.jpg differ diff --git a/Docs/img/ref_sensors_semantic.jpg b/Docs/img/ref_sensors_semantic.jpg index 79d05730e..281de6e8d 100644 Binary files a/Docs/img/ref_sensors_semantic.jpg and b/Docs/img/ref_sensors_semantic.jpg differ diff --git a/Docs/img/tuto_suspension_blueprints.jpg b/Docs/img/tuto_suspension_blueprints.jpg new file mode 100644 index 000000000..d59978d5f Binary files /dev/null and b/Docs/img/tuto_suspension_blueprints.jpg differ diff --git a/Docs/img/tuto_suspension_blueprints.png b/Docs/img/tuto_suspension_blueprints.png new file mode 100644 index 000000000..f6cb6bc33 Binary files /dev/null and b/Docs/img/tuto_suspension_blueprints.png differ diff --git a/Docs/img/tuto_suspension_parameterization.jpg b/Docs/img/tuto_suspension_parameterization.jpg new file mode 100644 index 000000000..a3da00d3c Binary files /dev/null and b/Docs/img/tuto_suspension_parameterization.jpg differ diff --git a/Docs/index.md b/Docs/index.md index 7cb5ee601..5afd923f0 100644 --- a/Docs/index.md +++ b/Docs/index.md @@ -143,10 +143,12 @@ CARLA forum — 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.

diff --git a/Docs/plugins_carlaviz.md b/Docs/plugins_carlaviz.md index 6f7772c38..4c2479f68 100644 --- a/Docs/plugins_carlaviz.md +++ b/Docs/plugins_carlaviz.md @@ -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 diff --git a/Docs/python_api.md b/Docs/python_api.md index 6ea8a7afd..9269d6438 100644 --- a/Docs/python_api.md +++ b/Docs/python_api.md @@ -14,36 +14,51 @@ Returns whether this object was destroyed using this actor handle. - **parent** (_[carla.Actor](#carla.Actor)_) Actors may be attached to a parent actor that they will follow around. This is said actor. - **semantic_tags** (_list(int)_) -A list of semantic tags provided by the blueprint listing components for this actor. E.g. a traffic light could be tagged with "pole" and "traffic light". These tags are used by the semantic segmentation sensor. Find more about this and other sensors [here](ref_sensors.md#semantic-segmentation-camera). +A list of semantic tags provided by the blueprint listing components for this actor. E.g. a traffic light could be tagged with `Pole` and `TrafficLight`. These tags are used by the semantic segmentation sensor. Find more about this and other sensors [here](ref_sensors.md#semantic-segmentation-camera). - **type_id** (_str_) -The identifier of the blueprint this actor was based on, e.g. "vehicle.ford.mustang". +The identifier of the blueprint this actor was based on, e.g. `vehicle.ford.mustang`.

Methods

+- **add_angular_impulse**(**self**, **angular_impulse**) +Applies an angular impulse at the center of mass of the actor. This method should be used for instantaneous torques, usually applied once. Use __add_torque()__ to apply rotation forces over a period of time. + - **Parameters:** + - `angular_impulse` (_[carla.Vector3D](#carla.Vector3D) – degrees*s_) – Angular impulse vector in global coordinates. +- **add_force**(**self**, **force**) +Applies a force at the center of mass of the actor. This method should be used for forces that are applied over a certain period of time. Use __add_impulse()__ to apply an impulse that only lasts an instant. + - **Parameters:** + - `force` (_[carla.Vector3D](#carla.Vector3D) – N_) – Force vector in global coordinates. - **add_impulse**(**self**, **impulse**) -Adds an impulse to the actor. The parameter `impulse` determines magnitude and global axis where it is applied. +Applies an impulse at the center of mass of the actor. This method should be used for instantaneous forces, usually applied once. Use __add_force()__ to apply forces over a period of time. - **Parameters:** - - `impulse` (_[carla.Vector3D](#carla.Vector3D)_) -- **add_angular_impulse**(**self**, **impulse**) -Adds an angular impulse to the actor. The parameter `impulse` determines magnitude and global axis where it is applied. + - `impulse` (_[carla.Vector3D](#carla.Vector3D) – N*s_) – Impulse vector in global coordinates. +- **add_torque**(**self**, **torque**) +Applies a torque at the center of mass of the actor. This method should be used for torques that are applied over a certain period of time. Use __add_angular_impulse()__ to apply a torque that only lasts an instant. - **Parameters:** - - `impulse` (_[carla.Vector3D](#carla.Vector3D)_) + - `torque` (_[carla.Vector3D](#carla.Vector3D) – degrees_) – Torque vector in global coordinates. - **destroy**(**self**) Tells the simulator to destroy this actor and returns True if it was successful. It has no effect if it was already destroyed. - **Return:** _bool_ - **Warning:** _This method blocks the script until the destruction is completed by the simulator. _ +- **disable_constant_velocity**(**self**) +Disables any constant velocity previously set for a [carla.Vehicle](#carla.Vehicle) actor. +- **enable_constant_velocity**(**self**, **velocity**) +Sets a vehicle's velocity vector to a constant value over time. The resulting velocity will be approximately the `velocity` being set, as with __set_target_velocity()__. + - **Parameters:** + - `velocity` (_[carla.Vector3D](#carla.Vector3D) – m/s_) – Velocity vector in local space. + - **Warning:** _Enabling a constant velocity for a vehicle managed by the [Traffic Manager](https://[carla.readthedocs.io](#carla.readthedocs.io)/en/latest/adv_traffic_manager/) may cause conflicts. This method overrides any changes in velocity by the TM. +_
Getters
- **get_acceleration**(**self**) Returns the actor's 3D acceleration vector the client recieved during last tick. The method does not call the simulator. - - **Return:** _[carla.Vector3D](#carla.Vector3D)_ + - **Return:** _[carla.Vector3D](#carla.Vector3D) – m/s2_ - **get_angular_velocity**(**self**) Returns the actor's angular velocity vector the client recieved during last tick. The method does not call the simulator. - - **Return:** _[carla.Vector3D](#carla.Vector3D)_ - - **Setter:** _[carla.Actor.set_angular_velocity](#carla.Actor.set_angular_velocity)_ + - **Return:** _[carla.Vector3D](#carla.Vector3D) – rad/s_ - **get_location**(**self**) Returns the actor's location the client recieved during last tick. The method does not call the simulator. - - **Return:** _[carla.Location](#carla.Location)_ + - **Return:** _[carla.Location](#carla.Location) – meters_ - **Setter:** _[carla.Actor.set_location](#carla.Actor.set_location)_ - **get_transform**(**self**) Returns the actor's transform (location and rotation) the client recieved during last tick. The method does not call the simulator. @@ -51,22 +66,22 @@ Returns the actor's transform (location and rotation) the client recieved during - **Setter:** _[carla.Actor.set_transform](#carla.Actor.set_transform)_ - **get_velocity**(**self**) Returns the actor's velocity vector the client recieved during last tick. The method does not call the simulator. - - **Return:** _[carla.Vector3D](#carla.Vector3D)_ - - **Setter:** _[carla.Actor.set_velocity](#carla.Actor.set_velocity)_ + - **Return:** _[carla.Vector3D](#carla.Vector3D) – m/s_ - **get_world**(**self**) Returns the world this actor belongs to. - **Return:** _[carla.World](#carla.World)_
Setters
-
- **set_angular_velocity**(**self**, **angular_velocity**) -Changes the actor's angular velocity vector. +
- **set_target_angular_velocity**(**self**, **angular_velocity**) +Sets the actor's angular velocity vector. The modification will be effective two frames after the setting. Also, this is applied before the physics step so the resulting angular velocity will be affected by external forces at this frame such as friction. - **Parameters:** - `angular_velocity` (_[carla.Vector3D](#carla.Vector3D)_) - - **Getter:** _[carla.Actor.get_angular_velocity](#carla.Actor.get_angular_velocity)_ + - **Note:** _The update will not be effective until two frames after it is set. +_ - **set_location**(**self**, **location**) Teleports the actor to a given location. - **Parameters:** - - `location` (_[carla.Location](#carla.Location)_) + - `location` (_[carla.Location](#carla.Location) – meters_) - **Getter:** _[carla.Actor.get_location](#carla.Actor.get_location)_ - **set_simulate_physics**(**self**, **enabled**=True) Enables or disables the simulation of physics on this actor. @@ -77,11 +92,12 @@ Teleports the actor to a given transform (location and rotation). - **Parameters:** - `transform` (_[carla.Transform](#carla.Transform)_) - **Getter:** _[carla.Actor.get_transform](#carla.Actor.get_transform)_ -- **set_velocity**(**self**, **velocity**) -Sets the actor's velocity vector. +- **set_target_velocity**(**self**, **velocity**) +Sets the actor's velocity vector. The modification will be effective two frames after the setting. Also, this is applied before the physics step so the resulting velocity will be affected by external forces at this frame such as friction. - **Parameters:** - `velocity` (_[carla.Vector3D](#carla.Vector3D)_) - - **Getter:** _[carla.Actor.get_velocity](#carla.Actor.get_velocity)_ + - **Note:** _The update will not be effective until two frames after it is set. +_
Dunder methods
- **\__str__**(**self**) @@ -235,16 +251,16 @@ An identifier for the snapshot itself.
Getters
- **get_acceleration**(**self**) Returns the acceleration vector registered for an actor in that tick. - - **Return:** _[carla.Vector3D](#carla.Vector3D)_ + - **Return:** _[carla.Vector3D](#carla.Vector3D) – m/s2_ - **get_angular_velocity**(**self**) Returns the angular velocity vector registered for an actor in that tick. - - **Return:** _[carla.Vector3D](#carla.Vector3D)_ + - **Return:** _[carla.Vector3D](#carla.Vector3D) – rad/s_ - **get_transform**(**self**) Returns the actor's transform (location and rotation) for an actor in that tick. - **Return:** _[carla.Transform](#carla.Transform)_ - **get_velocity**(**self**) Returns the velocity vector registered for an actor in that tick. - - **Return:** _[carla.Vector3D](#carla.Vector3D)_ + - **Return:** _[carla.Vector3D](#carla.Vector3D) – m/s_ --- @@ -292,24 +308,26 @@ Parses the identifiers for every blueprint to string. --- ## carla.BoundingBox -Helper class defining a box location and its dimensions that will later be used by [carla.DebugHelper](#carla.DebugHelper) or a [carla.Client](#carla.Client) to draw shapes and detect collisions. Bounding boxes normally act for object colliders. Check out this [recipe](ref_code_recipes.md#debug-bounding-box-recipe) where the user takes a snapshot of the world and then proceeds to draw bounding boxes for traffic lights. +Bounding boxes contain the geometry of an actor or an element in the scene. They can be used by [carla.DebugHelper](#carla.DebugHelper) or a [carla.Client](#carla.Client) to draw their shapes for debugging. Check out this [recipe](ref_code_recipes.md#debug-bounding-box-recipe) where the user takes a snapshot of the world and then proceeds to draw bounding boxes for traffic lights.

Instance Variables

-- **extent** (_[carla.Vector3D](#carla.Vector3D)_) +- **extent** (_[carla.Vector3D](#carla.Vector3D) – meters_) Vector from the center of the box to one vertex. The value in each axis equals half the size of the box for that axis. `extent.x * 2` would return the size of the box in the X-axis. -- **location** (_[carla.Location](#carla.Location)_) -The center of the bounding box relative to its parent actor. +- **location** (_[carla.Location](#carla.Location) – meters_) +The center of the bounding box. +- **rotation** (_[carla.Rotation](#carla.Rotation)_) +The orientation of the bounding box.

Methods

- **\__init__**(**self**, **location**, **extent**) - **Parameters:** - - `location` (_[carla.Location](#carla.Location)_) – Point to center the box. - - `extent` (_[carla.Vector3D](#carla.Vector3D)_) – Vector containing half the size of the box for every axis. + - `location` (_[carla.Location](#carla.Location)_) – Center of the box, relative to its parent. + - `extent` (_[carla.Vector3D](#carla.Vector3D) – meters_) – Vector containing half the size of the box for every axis. - **contains**(**self**, **world_point**, **transform**) Returns **True** if a point passed in world space is inside this bounding box. - **Parameters:** - - `world_point` (_[carla.Location](#carla.Location)_) – The point in world space to be checked. + - `world_point` (_[carla.Location](#carla.Location) – meters_) – The point in world space to be checked. - `transform` (_[carla.Transform](#carla.Transform)_) – Contains location and rotation needed to convert this object's local space to world space. - **Return:** _bool_ @@ -336,6 +354,36 @@ Parses the location and extent of the bounding box to string. --- +## carla.CityObjectLabel +Enum declaration that contains the different tags available to filter the bounding boxes returned by [carla.World.get_level_bbs](#carla.World.get_level_bbs)(). These values correspond to the [semantic tag](../../ref_sensors/#semantic-segmentation-camera) that the elements in the scene have. + +

Instance Variables

+- **None** +- **Buildings** +- **Fences** +- **Other** +- **Pedestrians** +- **Poles** +- **RoadLines** +- **Roads** +- **Sidewalks** +- **TrafficSigns** +- **Vegetation** +- **Vehicles** +- **Walls** +- **Sky** +- **Ground** +- **Bridge** +- **RailTrack** +- **GuardRail** +- **TrafficLight** +- **Static** +- **Dynamic** +- **Water** +- **Terrain** + +--- + ## carla.Client The Client connects CARLA to the server which runs the simulation. Both server and client contain a CARLA library (libcarla) with some differences that allow communication between them. Many clients can be created and each of these will connect to the RPC server inside the simulation to send commands. The simulation runs server-side. Once the connection is established, the client will only receive data retrieved from the simulation. Walkers are the exception. The client is in charge of managing pedestrians so, if you are running a simulation with multiple clients, some issues may arise. For example, if you spawn walkers through different clients, collisions may happen, as each client is only aware of the ones it is in charge of. @@ -349,13 +397,13 @@ Client constructor. - `port` (_int_) – TCP port where the CARLA Simulator instance is running. Default are 2000 and the subsequent 2001. - `worker_threads` (_int_) – Number of working threads used for background updates. If 0, use all available concurrency. - **apply_batch**(**self**, **commands**) -Executes a list of commands on a single simulation step and retrieves no information. If you need information about the response of each command, use the **apply_batch_sync()** function right below this one. [Here](https://github.com/carla-simulator/carla/blob/10c5f6a482a21abfd00220c68c7f12b4110b7f63/PythonAPI/examples/spawn_npc.py#L126) is an example on how to delete the actors that appear in [carla.ActorList](#carla.ActorList) all at once. +Executes a list of commands on a single simulation step and retrieves no information. If you need information about the response of each command, use the __apply_batch_sync()__ method. [Here](https://github.com/carla-simulator/carla/blob/10c5f6a482a21abfd00220c68c7f12b4110b7f63/PythonAPI/examples/spawn_npc.py#L126) is an example on how to delete the actors that appear in [carla.ActorList](#carla.ActorList) all at once. - **Parameters:** - `commands` (_list_) – A list of commands to execute in batch. Each command is different and has its own parameters. They appear listed at the bottom of this page. - **apply_batch_sync**(**self**, **commands**, **due_tick_cue**=False) Executes a list of commands on a single simulation step, blocks until the commands are linked, and returns a list of command.Response that can be used to determine whether a single command succeeded or not. [Here](https://github.com/carla-simulator/carla/blob/10c5f6a482a21abfd00220c68c7f12b4110b7f63/PythonAPI/examples/spawn_npc.py#L112-L116) is an example of it being used to spawn actors. - **Parameters:** - - `commands` (_list_) – A list of commands to execute in batch. The commands available are listed right above, in the function **apply_batch()**. + - `commands` (_list_) – A list of commands to execute in batch. The commands available are listed right above, in the method **apply_batch()**. - `due_tick_cue` (_bool_) – A boolean parameter to specify whether or not to perform a [carla.World.tick](#carla.World.tick) after applying the batch in _synchronous mode_. It is __False__ by default. - **Return:** _list(command.Response)_ - **generate_opendrive_world**(**self**, **opendrive**, **parameters**=(2.0, 50.0, 1.0, 0.6, true, true)) @@ -374,15 +422,19 @@ Reload the current world, note that a new world is created with default settings Load a new world with default settings using `map_name` map. All actors present in the current world will be destroyed, __but__ traffic manager instances will stay alive. - **Parameters:** - `name` (_str_) – Name of the file containing the information of the simulation. - - `start` (_float_) – Time in seconds where to start playing the simulation. Negative is read as beginning from the end, being -10 just 10 seconds before the recording finished. - - `duration` (_float_) – Time in seconds that will be reenacted using the information `name` file. If the end is reached, the simulation will continue. + - `start` (_float – seconds_) – Time where to start playing the simulation. Negative is read as beginning from the end, being -10 just 10 seconds before the recording finished. + - `duration` (_float – seconds_) – Time that will be reenacted using the information `name` file. If the end is reached, the simulation will continue. - `follow_id` (_int_) – ID of the actor to follow. If this is 0 then camera is disabled. +- **stop_replayer**(**self**, **keep_actors**) +Stop current replayer. + - **Parameters:** + - `keep_actors` (_bool_) – True if you want autoremove all actors from the replayer, or False to keep them. - **show_recorder_actors_blocked**(**self**, **filename**, **min_time**, **min_distance**) The terminal will show the information registered for actors considered blocked. An actor is considered blocked when it does not move a minimum distance in a period of time, being these `min_distance` and `min_time`. - **Parameters:** - `filename` (_str_) – Name of the recorded file to load. - - `min_time` (_float_) – Minimum time in seconds the actor has to move a minimum distance before being considered blocked. Default is 60 seconds. - - `min_distance` (_float_) – Minimum distance in centimeters the actor has to move to not be considered blocked. Default is 100 centimeters. + - `min_time` (_float – seconds_) – Minimum time the actor has to move a minimum distance before being considered blocked. Default is 60 seconds. + - `min_distance` (_float – centimeters_) – Minimum distance the actor has to move to not be considered blocked. Default is 100 centimeters. - **Return:** _string_ - **show_recorder_collisions**(**self**, **filename**, **category1**, **category2**) The terminal will show the collisions registered by the recorder. These can be filtered by specifying the type of actor involved. The categories will be specified in `category1` and `category2` as follows: @@ -444,9 +496,9 @@ When used, the time speed of the reenacted simulation is modified at will. It ca - **Parameters:** - `time_factor` (_float_) – 1.0 means normal time speed. Greater than 1.0 means fast motion (2.0 would be double speed) and lesser means slow motion (0.5 would be half speed). - **set_timeout**(**self**, **seconds**) -Sets in seconds the maxixum time a network call is allowed before blocking it and raising a timeout exceeded error. +Sets the maxixum time a network call is allowed before blocking it and raising a timeout exceeded error. - **Parameters:** - - `seconds` (_float_) – New timeout value in seconds. Default is 5 seconds. + - `seconds` (_float – seconds_) – New timeout value. Default is 5 seconds. --- @@ -458,7 +510,7 @@ Sets in seconds the maxixum time a network call is allowed before blocking it an The actor the sensor is attached to, the one that measured the collision. - **other_actor** (_[carla.Actor](#carla.Actor)_) The second actor involved in the collision. -- **normal_impulse** (_[carla.Vector3D](#carla.Vector3D)_) +- **normal_impulse** (_[carla.Vector3D](#carla.Vector3D) – N*s_) Normal impulse resulting of the collision. --- @@ -497,13 +549,13 @@ Class that defines conversion patterns that can be applied to a [carla.Image](#c

Instance Variables

- **CityScapesPalette** -Converts the image to a segmentated map using tags provided by the blueprint library. Used by sensor.camera.semantic_segmentation. +Converts the image to a segmentated map using tags provided by the blueprint library. Used by the [semantic segmentation camera](ref_sensors.md#semantic-segmentation-camera). - **Depth** -Converts the image to a linear depth map. Used by sensor.camera.depth. +Converts the image to a linear depth map. Used by the [depth camera](ref_sensors.md#depth-camera). - **LogarithmicDepth** Converts the image to a depth map using a logarithmic scale, leading to better precision for small distances at the expense of losing it when further away. - **Raw** -No changes applied to the image. +No changes applied to the image. Used by the [RGB camera](ref_sensors.md#rgb-camera). --- @@ -531,8 +583,8 @@ Polarity of the event. __True__ for positive and __False__ for negative. Class that defines a stream of events in [[carla.DVSEvent](#carla.DVSEvent)](#[carla.DVSEvent](#carla.DVSEvent)). Such stream is an array of arbitrary size depending on the number of events. This class also stores the field of view, the height and width of the image and the timestamp from convenience. Learn more about them [here](ref_sensors.md).

Instance Variables

-- **fov** (_float_) -Horizontal field of view of the image in degrees. +- **fov** (_float – degrees_) +Horizontal field of view of the image. - **height** (_int_) Image height in pixels. - **width** (_int_) @@ -566,46 +618,46 @@ Returns an array with the polarity of all the events in the stream. Helper class part of [carla.World](#carla.World) that defines methods for creating debug shapes. By default, shapes last one second. They can be permanent, but take into account the resources needed to do so. Check out this [recipe](ref_code_recipes.md#debug-bounding-box-recipe) where the user takes a snapshot of the world and then proceeds to draw bounding boxes for traffic lights.

Methods

-- **draw_arrow**(**self**, **begin**, **end**, **thickness**=0.1f, **arrow_size**=0.1f, **color**=(255,0,0), **life_time**=-1.0f) +- **draw_arrow**(**self**, **begin**, **end**, **thickness**=0.1, **arrow_size**=0.1, **color**=(255,0,0), **life_time**=-1.0) Draws an arrow from `begin` to `end` pointing in that direction. - **Parameters:** - - `begin` (_[carla.Location](#carla.Location)_) – Point in the coordinate system where the arrow starts. - - `end` (_[carla.Location](#carla.Location)_) – Point in the coordinate system where the arrow ends and points towards to. - - `thickness` (_float_) – Density of the line. - - `arrow_size` (_float_) – Size of the tip of the arrow. + - `begin` (_[carla.Location](#carla.Location) – meters_) – Point in the coordinate system where the arrow starts. + - `end` (_[carla.Location](#carla.Location) – meters_) – Point in the coordinate system where the arrow ends and points towards to. + - `thickness` (_float – meters_) – Density of the line. + - `arrow_size` (_float – meters_) – Size of the tip of the arrow. - `color` (_[carla.Color](#carla.Color)_) – RGB code to color the object. Red by default. - - `life_time` (_float_) – Lifespan in seconds for the shape. By default it only lasts one frame. Set this to 0 for permanent shapes. -- **draw_box**(**self**, **box**, **rotation**, **thickness**=0.1f, **color**=(255,0,0), **life_time**=-1.0f) + - `life_time` (_float – seconds_) – Shape's lifespan. By default it only lasts one frame. Set this to 0 for permanent shapes. +- **draw_box**(**self**, **box**, **rotation**, **thickness**=0.1, **color**=(255,0,0), **life_time**=-1.0) Draws a box, ussually to act for object colliders. - **Parameters:** - `box` (_[carla.BoundingBox](#carla.BoundingBox)_) – Object containing a location and the length of a box for every axis. - - `rotation` (_[carla.Rotation](#carla.Rotation)_) – Orientation of the box according to Unreal Engine's axis system. - - `thickness` (_float_) – Density of the lines that define the box. + - `rotation` (_[carla.Rotation](#carla.Rotation) – degrees (pitch,yaw,roll)_) – Orientation of the box according to Unreal Engine's axis system. + - `thickness` (_float – meters_) – Density of the lines that define the box. - `color` (_[carla.Color](#carla.Color)_) – RGB code to color the object. Red by default. - - `life_time` (_float_) – Lifespan in seconds for the shape. By default it only lasts one frame. Set this to 0 for permanent shapes. -- **draw_line**(**self**, **begin**, **end**, **thickness**=0.1f, **color**=(255,0,0), **life_time**=-1.0f) + - `life_time` (_float – seconds_) – Shape's lifespan. By default it only lasts one frame. Set this to 0 for permanent shapes. +- **draw_line**(**self**, **begin**, **end**, **thickness**=0.1, **color**=(255,0,0), **life_time**=-1.0) Draws a line in between `begin` and `end`. - **Parameters:** - - `begin` (_[carla.Location](#carla.Location)_) – Point in the coordinate system where the line starts. - - `end` (_[carla.Location](#carla.Location)_) – Spot in the coordinate system where the line ends. - - `thickness` (_float_) – Density of the line. + - `begin` (_[carla.Location](#carla.Location) – meters_) – Point in the coordinate system where the line starts. + - `end` (_[carla.Location](#carla.Location) – meters_) – Spot in the coordinate system where the line ends. + - `thickness` (_float – meters_) – Density of the line. - `color` (_[carla.Color](#carla.Color)_) – RGB code to color the object. Red by default. - - `life_time` (_float_) – Lifespan in seconds for the shape. By default it only lasts one frame. Set this to 0 for permanent shapes. -- **draw_point**(**self**, **location**, **size**=0.1f, **color**=(255,0,0), **life_time**=-1.0f) + - `life_time` (_float – seconds_) – Shape's lifespan. By default it only lasts one frame. Set this to 0 for permanent shapes. +- **draw_point**(**self**, **location**, **size**=0.1, **color**=(255,0,0), **life_time**=-1.0) Draws a point `location`. - **Parameters:** - - `location` (_[carla.Location](#carla.Location)_) – Spot in the coordinate system to center the object. - - `size` (_float_) – Density of the point. + - `location` (_[carla.Location](#carla.Location) – meters_) – Spot in the coordinate system to center the object. + - `size` (_float – meters_) – Density of the point. - `color` (_[carla.Color](#carla.Color)_) – RGB code to color the object. Red by default. - - `life_time` (_float_) – Lifespan in seconds for the shape. By default it only lasts one frame. Set this to 0 for permanent shapes. -- **draw_string**(**self**, **location**, **text**, **draw_shadow**=False, **color**=(255,0,0), **life_time**=-1.0f) + - `life_time` (_float – seconds_) – Shape's lifespan. By default it only lasts one frame. Set this to 0 for permanent shapes. +- **draw_string**(**self**, **location**, **text**, **draw_shadow**=False, **color**=(255,0,0), **life_time**=-1.0) Draws a string in a given location of the simulation which can only be seen server-side. - **Parameters:** - - `location` (_[carla.Location](#carla.Location)_) – Spot in the simulation where the text will be centered. + - `location` (_[carla.Location](#carla.Location) – meters_) – Spot in the simulation where the text will be centered. - `text` (_str_) – Text intended to be shown in the world. - `draw_shadow` (_bool_) – Casts a shadow for the string that could help in visualization. It is disabled by default. - `color` (_[carla.Color](#carla.Color)_) – RGB code to color the string. Red by default. - - `life_time` (_float_) + - `life_time` (_float – seconds_) – Shape's lifespan. By default it only lasts one frame. Set this to 0 for permanent shapes. --- @@ -638,19 +690,19 @@ Quotient between current RPM and MaxRPM where the autonomous gear box should shi Class that contains geographical coordinates simulated data. The [carla.Map](#carla.Map) can convert simulation locations by using the tag in the OpenDRIVE file.

Instance Variables

-- **latitude** (_float_) +- **latitude** (_float – degrees_) North/South value of a point on the map. -- **longitude** (_float_) +- **longitude** (_float – degrees_) West/East value of a point on the map. -- **altitude** (_float_) +- **altitude** (_float – meters_) Height regarding ground level.

Methods

- **\__init__**(**self**, **latitude**=0.0, **longitude**=0.0, **altitude**=0.0) - **Parameters:** - - `latitude` (_float_) - - `longitude` (_float_) - - `altitude` (_float_) + - `latitude` (_float – degrees_) + - `longitude` (_float – degrees_) + - `altitude` (_float – meters_)
Dunder methods
- **\__eq__**(**self**, **other**=[carla.GeoLocation](#carla.GeoLocation)) @@ -663,11 +715,11 @@ Height regarding ground level.
Inherited from _[carla.SensorData](#carla.SensorData)_

Class that defines the Gnss data registered by a sensor.other.gnss. It essentially reports its position with the position of the sensor and an OpenDRIVE geo-reference.

Instance Variables

-- **altitude** (_float_) +- **altitude** (_float – meters_) Height regarding ground level. -- **latitude** (_float_) +- **latitude** (_float – degrees_) North/South value of a point on the map. -- **longitude** (_float_) +- **longitude** (_float – degrees_) West/East value of a point on the map.

Methods

@@ -681,12 +733,12 @@ West/East value of a point on the map.
Inherited from _[carla.SensorData](#carla.SensorData)_

Class that defines the data registered by a sensor.other.imu, regarding the sensor's transformation according to the current [carla.World](#carla.World). It essentially acts as accelerometer, gyroscope and compass.

Instance Variables

-- **accelerometer** (_[carla.Vector3D](#carla.Vector3D)_) -Linear acceleration in m/s^2. -- **compass** (_float_) -Orientation with regard to the North ((0.0, -1.0, 0.0) in Unreal Engine) in radians. -- **gyroscope** (_[carla.Vector3D](#carla.Vector3D)_) -Angular velocity in rad/sec. +- **accelerometer** (_[carla.Vector3D](#carla.Vector3D) – m/s2_) +Linear acceleration. +- **compass** (_float – radians_) +Orientation with regard to the North ([0.0, -1.0, 0.0] in Unreal Engine). +- **gyroscope** (_[carla.Vector3D](#carla.Vector3D) – rad/s_) +Angular velocity.

Methods

@@ -699,8 +751,8 @@ Angular velocity in rad/sec.
Inherited from _[carla.SensorData](#carla.SensorData)_

Class that defines an image of 32-bit BGRA colors that will be used as initial data retrieved by camera sensors. There are different camera sensors (currently three, RGB, depth and semantic segmentation) and each of these makes different use for the images. Learn more about them [here](ref_sensors.md).

Instance Variables

-- **fov** (_float_) -Horizontal field of view of the image in degrees. +- **fov** (_float – degrees_) +Horizontal field of view of the image. - **height** (_int_) Image height in pixels. - **width** (_int_) @@ -755,11 +807,11 @@ Landmarks will be accessed by [carla.Waypoint](#carla.Waypoint) objects trying t - **road_id** (_int_) The OpenDRIVE ID of the road where this landmark is defined. Due to OpenDRIVE road definitions, this road may be different from the road the landmark is currently affecting. It is mostly the case in junctions where the road diverges in different routes. Example: a traffic light is defined in one of the divergent roads in a junction, but it affects all the possible routes. -- **distance** (_float_) +- **distance** (_float – meters_) Distance between the landmark and the waypoint creating the object (querying `get_landmarks` or `get_landmarks_of_type`). -- **s** (_float_) +- **s** (_float – meters_) Distance where the landmark is positioned along the geometry of the road `road_id`. -- **t** (_float_) +- **t** (_float – meters_) Lateral distance where the landmark is positioned from the edge of the road `road_id`. - **id** (_str_) Unique ID of the landmark in the OpenDRIVE file. @@ -767,9 +819,9 @@ Unique ID of the landmark in the OpenDRIVE file. Name of the landmark in the in the OpenDRIVE file. - **is_dynamic** (_bool_) Indicates if the landmark has state changes over time such as traffic lights. -- **orientation** (_[carla.LandmarkOrientation](#carla.LandmarkOrientation)_) +- **orientation** (_[carla.LandmarkOrientation](#carla.LandmarkOrientation) – degrees_) Indicates which lanes the landmark is facing towards to. -- **z_offset** (_float_) +- **z_offset** (_float – meters_) Height where the landmark is placed. - **country** (_str_) Country code where the landmark is defined (default to OpenDRIVE is Germany 2017). @@ -781,18 +833,18 @@ Subtype identificator of the landmark according to the country code. Value printed in the signal (e.g. speed limit, maximum weight, etc). - **unit** (_str_) Units of measurement for the attribute `value`. -- **height** (_float_) +- **height** (_float – meters_) Total height of the signal. -- **width** (_float_) +- **width** (_float – meters_) Total width of the signal. - **text** (_str_) Additional text in the signal. -- **h_offset** (_float_) +- **h_offset** (_float – meters_) Orientation offset of the signal relative to the the definition of `road_id` at `s` in OpenDRIVE. -- **pitch** (_float_) -Pitch rotation of the signal. +- **pitch** (_float – meters_) +Pitch rotation of the signal (Y-axis in [UE coordinates system](https://[carla.readthedocs.io](#carla.readthedocs.io)/en/latest/python_api/#carlarotation)). - **roll** (_float_) -Roll rotation of the signal. +Roll rotation of the signal (X-axis in [UE coordinates system](https://[carla.readthedocs.io](#carla.readthedocs.io)/en/latest/python_api/#carlarotation)). - **waypoint** (_[carla.Waypoint](#carla.Waypoint)_) A waypoint placed in the lane of the one that made the query and at the `s` of the landmark. It is the first waypoint for which the landmark will be effective. - **transform** (_[carla.Transform](#carla.Transform)_) @@ -1011,10 +1063,10 @@ Every type except for NONE. Data contained inside a [carla.LidarMeasurement](#carla.LidarMeasurement). Each of these represents one of the points in the cloud with its location and its asociated intensity.

Instance Variables

-- **point** (_[carla.Location](#carla.Location)_) +- **point** (_[carla.Location](#carla.Location) – meters_) Point in xyz coordinates. - **intensity** (_float_) -Computed intensity for this point. +Computed intensity for this point as a scalar value between [0.0 , 1.0].

Methods

@@ -1029,8 +1081,8 @@ Computed intensity for this point.

Instance Variables

- **channels** (_int_) Number of lasers shot. -- **horizontal_angle** (_float_) -Horizontal angle the LIDAR is rotated at the time of the measurement (in radians). +- **horizontal_angle** (_float – radians_) +Horizontal angle the LIDAR is rotated at the time of the measurement. - **raw_data** (_bytes_) Received list of 4D points. Each point consists of [x,y,z] coordiantes plus the intensity computed for that point. @@ -1064,11 +1116,11 @@ Lights are automatically turned on when the simulator enters night mode (sun alt Color of the light. - **id** (_int_) Identifier of the light. -- **intensity** (_float_) -Intensity of the light in lumens. +- **intensity** (_float – lumens_) +Intensity of the light. - **is_on** (_bool_) Switch of the light. It is __True__ when the light is on. When the night mode starts, this is set to __True__. -- **location** (_[carla.Location](#carla.Location)_) +- **location** (_[carla.Location](#carla.Location) – meters_) Position of the light. - **light_group** (_[carla.LightGroup](#carla.LightGroup)_) Group the light belongs to. @@ -1089,7 +1141,7 @@ Changes the color of the light to `color`. - **set_intensity**(**self**, **intensity**) Changes the intensity of the light to `intensity`. - **Parameters:** - - `intensity` (_float_) + - `intensity` (_float – lumens_) - **set_light_group**(**self**, **light_group**) Changes the light to the group `light_group`. - **Parameters:** @@ -1152,7 +1204,7 @@ Returns a list with the colors of every element in `lights`. Returns a list with the intensity of every element in `lights`. - **Parameters:** - `lights` (_list([carla.Light](#carla.Light))_) – List of lights to be queried. - - **Return:** _list(float)_ + - **Return:** _list(float) – lumens_ - **Setter:** _[carla.LightManager.set_intensity](#carla.LightManager.set_intensity)_ - **get_light_group**(**self**, **lights**) Returns a list with the group of every element in `lights`. @@ -1198,13 +1250,13 @@ Changes the color of each element in `lights` to the corresponding in `colors`. Changes the intensity of every element in `lights` to `intensity`. - **Parameters:** - `lights` (_list([carla.Light](#carla.Light))_) – List of lights to be changed. - - `intensity` (_float_) – Intensity to be applied. + - `intensity` (_float – lumens_) – Intensity to be applied. - **Getter:** _[carla.LightManager.get_intensity](#carla.LightManager.get_intensity)_ - **set_intensities**(**self**, **lights**, **intensities**) Changes the intensity of each element in `lights` to the corresponding in `intensities`. - **Parameters:** - `lights` (_list([carla.Light](#carla.Light))_) – List of lights to be changed. - - `intensities` (_list(float)_) – List of intensities to be applied. + - `intensities` (_list(float) – lumens_) – List of intensities to be applied. - **set_light_group**(**self**, **lights**, **light_group**) Changes the group of every element in `lights` to `light_group`. - **Parameters:** @@ -1234,8 +1286,8 @@ Changes the state of the attributes of each element in `lights` to the correspon This class represents all the light variables except the identifier and the location, which are should to be static. Using this class allows to manage all the parametrization of the light in one call.

Instance Variables

-- **intensity** (_float_) -Intensity of a light in lumens. +- **intensity** (_float – lumens_) +Intensity of a light. - **color** (_[carla.Color](#carla.Color)_) Color of a light. - **group** (_[carla.LightGroup](#carla.LightGroup)_) @@ -1246,7 +1298,7 @@ Switch of a light. It is __True__ when the light is on.

Methods

- **\__init__**(**self**, **intensity**=0.0, **color**=[carla.Color](#carla.Color)(), **group**=[carla.LightGroup.None](#carla.LightGroup.None), **active**=False) - **Parameters:** - - `intensity` (_float_) – Intensity of the light in lumens. Default is `0.0`. + - `intensity` (_float – lumens_) – Intensity of the light. Default is `0.0`. - `color` (_[carla.Color](#carla.Color)_) – Color of the light. Default is black. - `group` (_[carla.LightGroup](#carla.LightGroup)_) – Group the light belongs to. Default is the generic group `None`. - `active` (_bool_) – Swith of the light. Default is `False`, light is off. @@ -1257,12 +1309,12 @@ Switch of a light. It is __True__ when the light is on.
Inherited from _[carla.Vector3D](#carla.Vector3D)_

Represents a spot in the world.

Instance Variables

-- **x** (_float_) -Distance in meters from origin to spot on X axis. -- **y** (_float_) -Distance in meters from origin to spot on Y axis. -- **z** (_float_) -Distance in meters from origin to spot on Z axis. +- **x** (_float – meters_) +Distance from origin to spot on X axis. +- **y** (_float – meters_) +Distance from origin to spot on Y axis. +- **z** (_float – meters_) +Distance from origin to spot on Z axis.

Methods

- **\__init__**(**self**, **x**=0.0, **y**=0.0, **z**=0.0) @@ -1271,10 +1323,10 @@ Distance in meters from origin to spot on Z axis. - `y` (_float_) - `z` (_float_) - **distance**(**self**, **location**) -Returns Euclidean distance in meters from this location to another one. +Returns Euclidean distance from this location to another one. - **Parameters:** - `location` (_[carla.Location](#carla.Location)_) – The other point to compute the distance with. - - **Return:** _float_ + - **Return:** _float – meters_
Dunder methods
- **\__eq__**(**self**, **other**=[carla.Location](#carla.Location)) @@ -1306,7 +1358,7 @@ Constructor for this class. Though a map is automatically generated when initial - **generate_waypoints**(**self**, **distance**) Returns a list of waypoints with a certain distance between them for every lane and centered inside of it. Waypoints are not listed in any particular order. Remember that waypoints closer than 2cm within the same road, section and lane will have the same identificator. - **Parameters:** - - `distance` (_float_) – Approximate distance between waypoints. + - `distance` (_float – meters_) – Approximate distance between waypoints. - **Return:** _list([carla.Waypoint](#carla.Waypoint))_ - **save_to_disk**(**self**, **path**) Saves the .xodr OpenDRIVE file of the current map to disk. @@ -1350,7 +1402,7 @@ Returns a list of tuples describing a minimal graph of the topology of the OpenD Returns a waypoint that can be located in an exact location or translated to the center of the nearest lane. Said lane type can be defined using flags such as `LaneType.Driving & LaneType.Shoulder`. The method will return None if the waypoint is not found, which may happen only when trying to retrieve a waypoint for an exact location. That eases checking if a point is inside a certain road, as otherwise, it will return the corresponding waypoint. - **Parameters:** - - `location` (_[carla.Location](#carla.Location)_) – Location used as reference for the [carla.Waypoint](#carla.Waypoint). + - `location` (_[carla.Location](#carla.Location) – meters_) – Location used as reference for the [carla.Waypoint](#carla.Waypoint). - `project_to_road` (_bool_) – If **True**, the waypoint will be at the center of the closest lane. This is the default setting. If **False**, the waypoint will be exactly in `location`. None means said location does not belong to a road. - `lane_type` (_[carla.LaneType](#carla.LaneType)_) – Limits the search for nearest lane to one or various lane types that can be flagged. - **Return:** _[carla.Waypoint](#carla.Waypoint)_ @@ -1359,7 +1411,7 @@ Returns a waypoint if all the parameters passed are correct. Otherwise, returns - **Parameters:** - `road_id` (_int_) – ID of the road to get the waypoint. - `lane_id` (_int_) – ID of the lane to get the waypoint. - - `s` (_float_) – Specify the length from the road start. + - `s` (_float – meters_) – Specify the length from the road start. - **Return:** _[carla.Waypoint](#carla.Waypoint)_
Dunder methods
@@ -1375,7 +1427,7 @@ Returns a waypoint if all the parameters passed are correct. Otherwise, returns The actor the sensor is attached to. - **other_actor** (_[carla.Actor](#carla.Actor)_) The actor or object considered to be an obstacle. -- **distance** (_float_) +- **distance** (_float – meters_) Distance between `actor` and `other`.

Methods

@@ -1425,13 +1477,13 @@ Helper class that contains the parameterization that will be used by [carla.Osm2

Instance Variables

- **use_offsets** (_bool_) Enables the use of offset for the conversion. The offset will move the origin position of the map. Default value is __False__. -- **offset_x** (_float_) +- **offset_x** (_float – meters_) Offset in the X axis. Default value is __0.0__. -- **offset_y** (_float_) +- **offset_y** (_float – meters_) Offset in the Y axis. Default value is __0.0__. -- **default_lane_width** (_float_) +- **default_lane_width** (_float – meters_) Width of the lanes described in the resulting XODR map. Default value is __4.0__. -- **elevation_layer_height** (_float_) +- **elevation_layer_height** (_float – meters_) Defines the height separating two different [OpenStreetMap layers](https://wiki.openstreetmap.org/wiki/Key:layer). Default value is __0.0__. --- @@ -1440,14 +1492,14 @@ Defines the height separating two different [OpenStreetMap layers](https://wiki. Data contained inside a [carla.RadarMeasurement](#carla.RadarMeasurement). Each of these represents one of the points in the cloud that a sensor.other.radar registers and contains the distance, angle and velocity in relation to the radar.

Instance Variables

-- **altitude** (_float_) -Altitude angle of the detection in radians. -- **azimuth** (_float_) -Azimuth angle of the detection in radians. -- **depth** (_float_) -Distance in meters from the sensor to the detection position. -- **velocity** (_float_) -The velocity of the detected object towards the sensor in m/s. +- **altitude** (_float – radians_) +Altitude angle of the detection. +- **azimuth** (_float – radians_) +Azimuth angle of the detection. +- **depth** (_float – meters_) +Distance from the sensor to the detection position. +- **velocity** (_float – m/s_) +The velocity of the detected object towards the sensor.

Methods

@@ -1479,39 +1531,39 @@ Retrieves the number of entries generated, same as **\__st --- ## carla.Rotation -Class that represents a 3D rotation and therefore, an orientation in space. - -![UE4_Rotation](https://d26ilriwvtzlb.cloudfront.net/8/83/BRMC_9.jpg) _Unreal Engine's standard (from [UE4 docs](https://wiki.unrealengine.com/Blueprint_Rotating_Movement_Component))_. +Class that represents a 3D rotation and therefore, an orientation in space. CARLA uses the Unreal Engine coordinates system. This is a Z-up left-handed system.
+
The constructor method follows a specific order of declaration: `(pitch, yaw, roll)`, which corresponds to `(Y-rotation,Z-rotation,X-rotation)`.

![UE4_Rotation](https://d26ilriwvtzlb.cloudfront.net/8/83/BRMC_9.jpg) *Unreal Engine's coordinates system*.

Instance Variables

-- **pitch** (_float_) -Degrees around the Y-axis. -- **yaw** (_float_) -Degrees around the Z-axis. -- **roll** (_float_) -Degrees around the X-axis. +- **pitch** (_float – degrees_) +Y-axis rotation angle. +- **yaw** (_float – degrees_) +Z-axis rotation angle. +- **roll** (_float – degrees_) +X-axis rotation angle.

Methods

- **\__init__**(**self**, **pitch**=0.0, **yaw**=0.0, **roll**=0.0) - **Parameters:** - - `pitch` (_float_) – Y rotation in degrees. - - `yaw` (_float_) – Z rotation in degrees. - - `roll` (_float_) – X rotation in degrees. + - `pitch` (_float – degrees_) – Y-axis rotation angle. + - `yaw` (_float – degrees_) – Z-axis rotation angle. + - `roll` (_float – degrees_) – X-axis rotation angle. + - **Warning:** _The declaration order is different in CARLA (pitch,yaw,roll), and in the Unreal Engine Editor (roll,pitch,yaw). When working in a build from source, don't mix up the axes' rotations._
Getters
- **get_forward_vector**(**self**) -Computes the vector pointing forward according to the orientation of each axis. +Computes the vector pointing forward according to the rotation of the object. - **Return:** _[carla.Vector3D](#carla.Vector3D)_ - **get_right_vector**(**self**) -Computes the vector pointing to the right according to the orientation of each axis. +Computes the vector pointing to the right according to the rotation of the object. - **Return:** _[carla.Vector3D](#carla.Vector3D)_ - **get_up_vector**(**self**) -Computes the vector pointing upwards according to the orientation of each axis. +Computes the vector pointing upwards according to the rotation of the object. - **Return:** _[carla.Vector3D](#carla.Vector3D)_
Dunder methods
- **\__eq__**(**self**, **other**=[carla.Rotation](#carla.Rotation)) -Returns __True__ if both rotations represent the same orientation of each axis. +Returns __True__ if both rotations represent the same orientation for every axis. - **Return:** _bool_ - **\__ne__**(**self**, **other**=[carla.Rotation](#carla.Rotation)) Returns __True__ if both rotations represent the same orientation for every axis. @@ -1719,14 +1771,14 @@ Sets the log level. Data contained inside a [carla.SemanticLidarMeasurement](#carla.SemanticLidarMeasurement). Each of these represents one of the points in the cloud with its location, the cosine of the incident angle, index of the object hit, and its semantic tag.

Instance Variables

-- **point** (_[carla.Location](#carla.Location)_) +- **point** (_[carla.Location](#carla.Location) – meters_) [x,y,z] coordinates of the point. - **cos_inc_angle** (_float_) Cosine of the incident angle between the ray, and the normal of the hit object. - **object_idx** (_uint_) -Carla index of the hit actor. +ID of the actor hit by the ray. - **object_tag** (_uint_) -Semantic tag of the hit component. +[Semantic tag](https://[carla.readthedocs.io](#carla.readthedocs.io)/en/latest/ref_sensors/#semantic-segmentation-camera) of the component hit by the ray.

Methods

@@ -1741,8 +1793,8 @@ Semantic tag of the hit component.

Instance Variables

- **channels** (_int_) Number of lasers shot. -- **horizontal_angle** (_float_) -Horizontal angle the LIDAR is rotated at the time of the measurement (in radians). +- **horizontal_angle** (_float – radians_) +Horizontal angle the LIDAR is rotated at the time of the measurement. - **raw_data** (_bytes_) Received list of raw detection points. Each point consists of [x,y,z] coordinates plus the cosine of the incident angle, the index of the hit actor, and its semantic tag. @@ -1770,20 +1822,20 @@ Retrieves the number of points sorted by channel that are generated by this meas ## carla.Sensor
Inherited from _[carla.Actor](#carla.Actor)_

Sensors compound a specific family of actors quite diverse and unique. They are normally spawned as attachment/sons of a vehicle (take a look at [carla.World](#carla.World) to learn about actor spawning). Sensors are thoroughly designed to retrieve different types of data that they are listening to. The data they receive is shaped as different subclasses inherited from [carla.SensorData](#carla.SensorData) (depending on the sensor). - Most sensors can be divided in two groups: those receiving data on every tick (cameras, point clouds and some specific sensors) and those who only receive under certain circumstances (trigger detectors). CARLA provides a specific set of sensors and their blueprint can be found in [carla.BlueprintLibrary](#carla.BlueprintLibrary). All the information on their preferences and settlement can be found [here](ref_sensors.md), but the list of those available in CARLA so far goes as follow. - Receive data on every tick. - - [Depth camera](ref_sensors.md#depth-camera). - - [Gnss sensor](ref_sensors.md#gnss-sensor). - - [IMU sensor](ref_sensors.md#imu-sensor). - - [Lidar raycast](ref_sensors.md#lidar-raycast-sensor). - - [SemanticLidar raycast](ref_sensors.md#semanticlidar-raycast-sensor). - - [Radar](ref_sensors.md#radar-sensor). - - [RGB camera](ref_sensors.md#rgb-camera). - - [RSS sensor](ref_sensors.md#rss-sensor). - - [Semantic Segmentation camera](ref_sensors.md#semantic-segmentation-camera). - Only receive data when triggered. - - [Collision detector](ref_sensors.md#collision-detector). - - [Lane invasion detector](ref_sensors.md#lane-invasion-detector). + Most sensors can be divided in two groups: those receiving data on every tick (cameras, point clouds and some specific sensors) and those who only receive under certain circumstances (trigger detectors). CARLA provides a specific set of sensors and their blueprint can be found in [carla.BlueprintLibrary](#carla.BlueprintLibrary). All the information on their preferences and settlement can be found [here](ref_sensors.md), but the list of those available in CARLA so far goes as follow. +
Receive data on every tick. + - [Depth camera](ref_sensors.md#depth-camera). + - [Gnss sensor](ref_sensors.md#gnss-sensor). + - [IMU sensor](ref_sensors.md#imu-sensor). + - [Lidar raycast](ref_sensors.md#lidar-raycast-sensor). + - [SemanticLidar raycast](ref_sensors.md#semanticlidar-raycast-sensor). + - [Radar](ref_sensors.md#radar-sensor). + - [RGB camera](ref_sensors.md#rgb-camera). + - [RSS sensor](ref_sensors.md#rss-sensor). + - [Semantic Segmentation camera](ref_sensors.md#semantic-segmentation-camera). +
Only receive data when triggered. + - [Collision detector](ref_sensors.md#collision-detector). + - [Lane invasion detector](ref_sensors.md#lane-invasion-detector). - [Obstacle detector](ref_sensors.md#obstacle-detector).

Instance Variables

@@ -1804,22 +1856,22 @@ Commands the sensor to stop listening for data. --- ## carla.SensorData -Base class for all the objects containing data generated by a [carla.Sensor](#carla.Sensor). This objects should be the argument of the function said sensor is listening to, in order to work with them. Each of these sensors needs for a specific type of sensor data. Hereunder is a list of the sensors and their corresponding data. - - Cameras (RGB, depth and semantic segmentation): [carla.Image](#carla.Image). - - Collision detector: [carla.CollisionEvent](#carla.CollisionEvent). - - GNSS sensor: [carla.GnssMeasurement](#carla.GnssMeasurement). - - IMU sensor: [carla.IMUMeasurement](#carla.IMUMeasurement). - - Lane invasion detector: [carla.LaneInvasionEvent](#carla.LaneInvasionEvent). - - LIDAR sensor: [carla.LidarMeasurement](#carla.LidarMeasurement). - - Obstacle detector: [carla.ObstacleDetectionEvent](#carla.ObstacleDetectionEvent). - - Radar sensor: [carla.RadarMeasurement](#carla.RadarMeasurement). - - RSS sensor: [carla.RssResponse](#carla.RssResponse). +Base class for all the objects containing data generated by a [carla.Sensor](#carla.Sensor). This objects should be the argument of the function said sensor is listening to, in order to work with them. Each of these sensors needs for a specific type of sensor data. Hereunder is a list of the sensors and their corresponding data.
+ - Cameras (RGB, depth and semantic segmentation): [carla.Image](#carla.Image).
+ - Collision detector: [carla.CollisionEvent](#carla.CollisionEvent).
+ - GNSS sensor: [carla.GnssMeasurement](#carla.GnssMeasurement).
+ - IMU sensor: [carla.IMUMeasurement](#carla.IMUMeasurement).
+ - Lane invasion detector: [carla.LaneInvasionEvent](#carla.LaneInvasionEvent).
+ - LIDAR sensor: [carla.LidarMeasurement](#carla.LidarMeasurement).
+ - Obstacle detector: [carla.ObstacleDetectionEvent](#carla.ObstacleDetectionEvent).
+ - Radar sensor: [carla.RadarMeasurement](#carla.RadarMeasurement).
+ - RSS sensor: [carla.RssResponse](#carla.RssResponse).
- Semantic LIDAR sensor: [carla.SemanticLidarMeasurement](#carla.SemanticLidarMeasurement).

Instance Variables

- **frame** (_int_) Frame count when the data was generated. -- **timestamp** (_float_) +- **timestamp** (_float – seconds_) Simulation-time when the data was generated. - **transform** (_[carla.Transform](#carla.Transform)_) Sensor's transform when the data was generated. @@ -1832,20 +1884,20 @@ Class that contains time information for simulated data. This information is aut

Instance Variables

- **frame** (_int_) The number of frames elapsed since the simulator was launched. -- **elapsed_seconds** (_float_) +- **elapsed_seconds** (_float – seconds_) Simulated seconds elapsed since the beginning of the current episode. -- **delta_seconds** (_float_) +- **delta_seconds** (_float – seconds_) Simulated seconds elapsed since the previous frame. -- **platform_timestamp** (_float_) +- **platform_timestamp** (_float – seconds_) Time register of the frame at which this measurement was taken given by the OS in seconds.

Methods

- **\__init__**(**self**, **frame**, **elapsed_seconds**, **delta_seconds**, **platform_timestamp**) - **Parameters:** - `frame` (_int_) - - `elapsed_seconds` (_float_) - - `delta_seconds` (_float_) - - `platform_timestamp` (_float_) + - `elapsed_seconds` (_float – seconds_) + - `delta_seconds` (_float – seconds_) + - `platform_timestamp` (_float – seconds_)
Dunder methods
- **\__eq__**(**self**, **other**=[carla.Timestamp](#carla.Timestamp)) @@ -1873,17 +1925,17 @@ The client returns True if a traffic light is frozen according to last ti - **Return:** _bool_ - **reset_group**(**self**) Resets the state of the traffic lights of the group to the initial state at the start of the simulation. - - **Note:** _This function calls the simulator. + - **Note:** _This method calls the simulator. _
Getters
- **get_elapsed_time**(**self**) The client returns the time in seconds since current light state started according to last tick. The method does not call the simulator. - - **Return:** _float_ + - **Return:** _float – seconds_ - **get_group_traffic_lights**(**self**) Returns all traffic lights in the group this one belongs to. - **Return:** _list([carla.TrafficLight](#carla.TrafficLight))_ - - **Note:** _This function calls the simulator. + - **Note:** _This method calls the simulator. _ - **get_pole_index**(**self**) Returns the index of the pole that identifies it as part of the traffic light group of a junction. @@ -1893,16 +1945,16 @@ The client returns the state of the traffic light according to last tick. The me - **Return:** _[carla.TrafficLightState](#carla.TrafficLightState)_ - **Setter:** _[carla.TrafficLight.set_state](#carla.TrafficLight.set_state)_ - **get_green_time**(**self**) -The client returns the seconds set for the traffic light to be green according to last tick. The method does not call the simulator. - - **Return:** _float_ +The client returns the time set for the traffic light to be green, according to last tick. The method does not call the simulator. + - **Return:** _float – seconds_ - **Setter:** _[carla.TrafficLight.set_green_time](#carla.TrafficLight.set_green_time)_ - **get_red_time**(**self**) -The client returns the seconds set for the traffic light to be red according to last tick. The method does not call the simulator. - - **Return:** _float_ +The client returns the time set for the traffic light to be red, according to last tick. The method does not call the simulator. + - **Return:** _float – seconds_ - **Setter:** _[carla.TrafficLight.set_red_time](#carla.TrafficLight.set_red_time)_ - **get_yellow_time**(**self**) -The client returns the the seconds set for the traffic light to be yellow according to last tick. The method does not call the simulator. - - **Return:** _float_ +The client returns the time set for the traffic light to be yellow, according to last tick. The method does not call the simulator. + - **Return:** _float – seconds_ - **Setter:** _[carla.TrafficLight.set_yellow_time](#carla.TrafficLight.set_yellow_time)_
Setters
@@ -1913,17 +1965,17 @@ Sets a given state to a traffic light actor. - **Getter:** _[carla.TrafficLight.get_state](#carla.TrafficLight.get_state)_ - **set_green_time**(**self**, **green_time**) - **Parameters:** - - `green_time` (_float_) – Sets a given time (in seconds) for the green light to be active. + - `green_time` (_float – seconds_) – Sets a given time for the green light to be active. - **Getter:** _[carla.TrafficLight.get_green_time](#carla.TrafficLight.get_green_time)_ - **set_red_time**(**self**, **red_time**) -Sets a given time (in seconds) for the red state to be active. +Sets a given time for the red state to be active. - **Parameters:** - - `red_time` (_float_) + - `red_time` (_float – seconds_) - **Getter:** _[carla.TrafficLight.get_red_time](#carla.TrafficLight.get_red_time)_ - **set_yellow_time**(**self**, **yellow_time**) -Sets a given time (in seconds) for the yellow light to be active. +Sets a given time for the yellow light to be active. - **Parameters:** - - `yellow_time` (_float_) + - `yellow_time` (_float – seconds_) - **Getter:** _[carla.TrafficLight.get_yellow_time](#carla.TrafficLight.get_yellow_time)_
Dunder methods
@@ -1963,7 +2015,7 @@ Tunes on/off collisions between a vehicle and another specific actor. In order t Sets the minimum distance in meters that a vehicle has to keep with the others. The distance is in meters and will affect the minimum moving distance. It is computed from front to back of the vehicle objects. - **Parameters:** - `actor` (_[carla.Actor](#carla.Actor)_) – Vehicle whose minimum distance is being changed. - - `distance` (_float_) – Meters between both vehicles. + - `distance` (_float – meters_) – Meters between both vehicles. - **force_lane_change**(**self**, **actor**, **direction**) Forces a vehicle to change either to the lane on its left or right, if existing, as indicated in `direction`. This method applies the lane change no matter what, disregarding possible collisions. - **Parameters:** @@ -1972,7 +2024,7 @@ Forces a vehicle to change either to the lane on its left or right, if existing, - **global_distance_to_leading_vehicle**(**self**, **distance**) Sets the minimum distance in meters that vehicles have to keep with the rest. The distance is in meters and will affect the minimum moving distance. It is computed from center to center of the vehicle objects. - **Parameters:** - - `distance` (_float_) – Meters between vehicles. + - `distance` (_float – meters_) – Meters between vehicles. - **global_percentage_speed_difference**(**self**, **percentage**) Sets the difference the vehicle's intended speed and its current speed limit. Speed limits can be exceeded by setting the `perc` to a negative value. Default is 30. Exceeding a speed limit can be done using negative percentages. @@ -2015,7 +2067,11 @@ Enables or disables the hybrid physics mode. In this mode, vehicle's farther tha - **set_hybrid_mode_radius**(**self**, **r**=70.0) With hybrid physics on, changes the radius of the area of influence where physics are enabled. - **Parameters:** - - `r` (_float_) – New radius where physics are enabled. + - `r` (_float – meters_) – New radius where physics are enabled. +- **set_osm_mode**(**self**, **mode_switch**=True) +Enables or disables the OSM mode. This mode allows the user to run TM in a map created with the [OSM feature](tuto_G_openstreetmap.md). These maps allow having dead-end streets. Normally, if vehicles cannot find the next waypoint, TM crashes. If OSM mode is enabled, it will show a warning, and destroy vehicles when necessary. + - **Parameters:** + - `mode_switch` (_bool_) – If __True__, the OSM mode is enabled. --- @@ -2034,14 +2090,14 @@ Class that defines a transformation, a combination of location and rotation, wit

Instance Variables

- **location** (_[carla.Location](#carla.Location)_) Describes a point in the coordinate system. -- **rotation** (_[carla.Rotation](#carla.Rotation)_) +- **rotation** (_[carla.Rotation](#carla.Rotation) – degrees (pitch, yaw, roll)_) Describes a rotation for an object according to Unreal Engine's axis system.

Methods

- **\__init__**(**self**, **location**, **rotation**) - **Parameters:** - `location` (_[carla.Location](#carla.Location)_) - - `rotation` (_[carla.Rotation](#carla.Rotation)_) + - `rotation` (_[carla.Rotation](#carla.Rotation) – degrees (pitch, yaw, roll)_) - **transform**(**self**, **in_point**) Translates a 3D point from local to global coordinates using the current transformation as frame of reference. - **Parameters:** @@ -2049,13 +2105,13 @@ Translates a 3D point from local to global coordinates using the current transfo
Getters
- **get_forward_vector**(**self**) -Computes a forward vector using its rotation. +Computes a forward vector using the rotation of the object. - **Return:** _[carla.Vector3D](#carla.Vector3D)_ - **get_right_vector**(**self**) -Computes a right vector using its rotation. +Computes a right vector using the rotatio of the object. - **Return:** _[carla.Vector3D](#carla.Vector3D)_ - **get_up_vector**(**self**) -Computes an up vector using its rotation. +Computes an up vector using the rotation of the object. - **Return:** _[carla.Vector3D](#carla.Vector3D)_ - **get_matrix**(**self**) Computes the 4-matrix representation of the transformation. @@ -2149,7 +2205,7 @@ Returns the axis values for the vector parsed as string.

Instance Variables

- **bounding_box** (_[carla.BoundingBox](#carla.BoundingBox)_) -The vehicle's collider volume. +Bounding box containing the geometry of the vehicle. Its location and rotation are relative to the vehicle it is attached to.

Methods

- **apply_control**(**self**, **control**) @@ -2175,10 +2231,10 @@ Returns a flag representing the vehicle light state, this represents which light - **get_physics_control**(**self**) The simulator returns the last physics control applied to this vehicle. - **Return:** _[carla.VehiclePhysicsControl](#carla.VehiclePhysicsControl)_ - - **Warning:** _This function does call the simulator to retrieve the value._ + - **Warning:** _This method does call the simulator to retrieve the value._ - **get_speed_limit**(**self**) The client returns the speed limit affecting this vehicle according to last tick (it does not call the simulator). The speed limit is updated when passing by a speed limit signal, so a vehicle might have none right after spawning. - - **Return:** _float_ + - **Return:** _float – m/s_ - **get_traffic_light**(**self**) Retrieves the traffic light actor affecting this vehicle (if any) according to last tick. The method does not call the simulator. - **Return:** _[carla.TrafficLight](#carla.TrafficLight)_ @@ -2225,9 +2281,9 @@ States which gear is the vehicle running on.

Methods

- **\__init__**(**self**, **throttle**=0.0, **steer**=0.0, **brake**=0.0, **hand_brake**=False, **reverse**=False, **manual_gear_shift**=False, **gear**=0) - **Parameters:** - - `throttle` (_float_) - - `steer` (_float_) - - `brake` (_float_) + - `throttle` (_float_) – Scalar value between [0.0,1.0]. + - `steer` (_float_) – Scalar value between [0.0,1.0]. + - `brake` (_float_) – Scalar value between [0.0,1.0]. - `hand_brake` (_bool_) - `reverse` (_bool_) - `manual_gear_shift` (_bool_) @@ -2272,7 +2328,7 @@ Summarizes the parameters that will be used to simulate a [carla.Vehicle](#carla Curve that indicates the torque measured in Nm for a specific RPM of the vehicle's engine. - **max_rpm** (_float_) The maximum RPM of the vehicle's engine. -- **moi** (_float_) +- **moi** (_float – kg*m2_) The moment of inertia of the vehicle's engine. - **damping_rate_full_throttle** (_float_) Damping ratio when the throttle is maximum. @@ -2282,20 +2338,20 @@ Damping ratio when the throttle is zero with clutch engaged. Damping ratio when the throttle is zero with clutch disengaged. - **use_gear_autobox** (_bool_) If True, the vehicle will have an automatic transmission. -- **gear_switch_time** (_float_) +- **gear_switch_time** (_float – seconds_) Switching time between gears. -- **clutch_strength** (_float_) -The clutch strength of the vehicle in Kgm^2/s. +- **clutch_strength** (_float – kg*m2/s_) +Clutch strength of the vehicle. - **final_ratio** (_float_) -The fixed ratio from transmission to wheels. +Fixed ratio from transmission to wheels. - **forward_gears** (_list([carla.GearPhysicsControl](#carla.GearPhysicsControl))_) List of objects defining the vehicle's gears. -- **mass** (_float_) -The mass of the vehicle in Kg. +- **mass** (_float – kilograms_) +Mass of the vehicle. - **drag_coefficient** (_float_) Drag coefficient of the vehicle's chassis. -- **center_of_mass** (_[carla.Vector3D](#carla.Vector3D)_) -The center of mass of the vehicle. +- **center_of_mass** (_[carla.Vector3D](#carla.Vector3D) – meters_) +Center of mass of the vehicle. - **steering_curve** (_list([carla.Vector2D](#carla.Vector2D))_) Curve that indicates the maximum steering for a specific forward speed. - **wheels** (_list([carla.WheelPhysicsControl](#carla.WheelPhysicsControl))_) @@ -2307,13 +2363,13 @@ VehiclePhysicsControl constructor. - **Parameters:** - `torque_curve` (_list([carla.Vector2D](#carla.Vector2D))_) - `max_rpm` (_float_) - - `moi` (_float_) + - `moi` (_float – kg*m2_) - `damping_rate_full_throttle` (_float_) - `damping_rate_zero_throttle_clutch_engaged` (_float_) - `damping_rate_zero_throttle_clutch_disengaged` (_float_) - `use_gear_autobox` (_bool_) - - `gear_switch_time` (_float_) - - `clutch_strength` (_float_) + - `gear_switch_time` (_float – seconds_) + - `clutch_strength` (_float – kg*m2/s_) - `final_ratio` (_float_) - `forward_gears` (_list([carla.GearPhysicsControl](#carla.GearPhysicsControl))_) - `drag_coefficient` (_float_) @@ -2333,7 +2389,7 @@ VehiclePhysicsControl constructor.

Instance Variables

- **bounding_box** (_[carla.BoundingBox](#carla.BoundingBox)_) -The walker's collider defined by a bounding box. +Bounding box containing the geometry of the walker. Its location and rotation are relative to the walker it is attached to.

Methods

- **apply_control**(**self**, **control**) @@ -2362,7 +2418,7 @@ The client returns the control applied to this walker during last tick. The meth - **go_to_location**(**self**, **destination**) Sets the destination that the pedestrian will reach. - **Parameters:** - - `destination` (_[carla.Location](#carla.Location)_) + - `destination` (_[carla.Location](#carla.Location) – meters_) - **start**(**self**) Enables AI control for its parent walker. - **stop**(**self**) @@ -2372,7 +2428,7 @@ Disables AI control for its parent walker.
- **set_max_speed**(**self**, **speed**=1.4) Sets a speed for the walker in meters per second. - **Parameters:** - - `speed` (_float_) – speed in m/s. An easy walking speed is set by default. + - `speed` (_float – m/s_) – An easy walking speed is set by default.
Dunder methods
- **\__str__**(**self**) @@ -2388,7 +2444,7 @@ List of tuples where the first value is the bone's name and the second value sto

Methods

- **\__init__**(**self**, **list(name,transform)**) -Intializes an object containing moves to be applied on tick. These are listed with the name of the bone and the transform that will be applied to it. +Initializes an object containing moves to be applied on tick. These are listed with the name of the bone and the transform that will be applied to it. - **Parameters:** - `list(name,transform)` (_tuple_) @@ -2405,7 +2461,7 @@ This class defines specific directions that can be commanded to a [carla.Walker]

Instance Variables

- **direction** (_[carla.Vector3D](#carla.Vector3D)_) Vector using global coordinates that will correspond to the direction of the walker. -- **speed** (_float_) +- **speed** (_float – m/s_) A scalar value to control the walker's speed. - **jump** (_bool_) If True, the walker will perform a jump. @@ -2414,7 +2470,7 @@ If True, the walker will perform a jump. - **\__init__**(**self**, **direction**=[1.0, 0.0, 0.0], **speed**=0.0, **jump**=False) - **Parameters:** - `direction` (_[carla.Vector3D](#carla.Vector3D)_) - - `speed` (_float_) + - `speed` (_float – m/s_) - `jump` (_bool_)
Dunder methods
@@ -2427,7 +2483,7 @@ Compares every variable with `other` and returns True if any of these dif --- ## carla.Waypoint -Waypoints in CARLA are described as 3D directed points. They store a certain [carla.Transform](#carla.Transform) which locates the waypoint in a road and orientates it according to the lane. They also store the road information belonging to said point regarding its lane and lane markings. All of this information is retrieved as provided by the OpenDRIVE file. +Waypoints in CARLA are described as 3D directed points. They have a [carla.Transform](#carla.Transform) which locates the waypoint in a road and orientates it according to the lane. They also store the road information belonging to said point regarding its lane and lane markings.

All the information regarding waypoints and the [waypoint API](../../core_map/#navigation-in-carla) is retrieved as provided by the OpenDRIVE file. Once the client asks for the map object to the server, no longer communication will be needed.

Instance Variables

- **id** (_int_) @@ -2460,39 +2516,39 @@ The left lane marking information based on the direction of the Waypoint. Returns a list of waypoints at a certain approximate `distance` from the current one. It takes into account the road and its possible deviations without performing any lane change and returns one waypoint per option. The list may be empty if the lane is not connected to any other at the specified distance. - **Parameters:** - - `distance` (_float_) – The approximate distance where to get the next waypoints. + - `distance` (_float – meters_) – The approximate distance where to get the next waypoints. - **Return:** _list([carla.Waypoint](#carla.Waypoint))_ - **next_until_lane_end**(**self**, **distance**) Returns a list of waypoints from this to the end of the lane separated by a certain `distance`. - **Parameters:** - - `distance` (_float_) – The approximate distance between waypoints. + - `distance` (_float – meters_) – The approximate distance between waypoints. - **Return:** _list([carla.Waypoint](#carla.Waypoint))_ - **previous**(**self**, **distance**) This method does not return the waypoint previously visited by an actor, but a list of waypoints at an approximate `distance` but in the opposite direction of the lane. Similarly to **next()**, it takes into account the road and its possible deviations without performing any lane change and returns one waypoint per option. The list may be empty if the lane is not connected to any other at the specified distance. - **Parameters:** - - `distance` (_float_) – The approximate distance where to get the previous waypoints. + - `distance` (_float – meters_) – The approximate distance where to get the previous waypoints. - **Return:** _list([carla.Waypoint](#carla.Waypoint))_ - **previous_until_lane_start**(**self**, **distance**) Returns a list of waypoints from this to the start of the lane separated by a certain `distance`. - **Parameters:** - - `distance` (_float_) – The approximate distance between waypoints. + - `distance` (_float – meters_) – The approximate distance between waypoints. - **Return:** _list([carla.Waypoint](#carla.Waypoint))_
Getters
- **get_junction**(**self**) -If the waypoint belongs to a junction this function returns the asociated junction object. Otherwise returns null. +If the waypoint belongs to a junction this method returns the asociated junction object. Otherwise returns null. - **Return:** _[carla.Junction](#carla.Junction)_ - **get_landmarks**(**self**, **distance**, **stop_at_junction**=False) Returns a list of landmarks in the road from the current waypoint until the specified distance. - **Parameters:** - - `distance` (_float_) – The maximum distance to search for landmarks from the current waypoint. + - `distance` (_float – meters_) – The maximum distance to search for landmarks from the current waypoint. - `stop_at_junction` (_bool_) – Enables or disables the landmark search through junctions. - **Return:** _list([carla.Landmark](#carla.Landmark))_ - **get_landmarks_of_type**(**self**, **distance**, **type**, **stop_at_junction**=False) Returns a list of landmarks in the road of a specified type from the current waypoint until the specified distance. - **Parameters:** - - `distance` (_float_) – The maximum distance to search for landmarks from the current waypoint. + - `distance` (_float – meters_) – The maximum distance to search for landmarks from the current waypoint. - `type` (_str_) – The type of landmarks to search. - `stop_at_junction` (_bool_) – Enables or disables the landmark search through junctions. - **Return:** _list([carla.Landmark](#carla.Landmark))_ @@ -2523,14 +2579,14 @@ Rain intensity values range from 0 to 100, being 0 none at all and 100 a heavy r Determines the creation of puddles. Values range from 0 to 100, being 0 none at all and 100 a road completely capped with water. Puddles are created with static noise, meaning that they will always appear at the same locations. - **wind_intensity** (_float_) Controls the strenght of the wind with values from 0, no wind at all, to 100, a strong wind. The wind does affect rain direction and leaves from trees, so this value is restricted to avoid animation issues. -- **sun_azimuth_angle** (_float_) -The azimuth angle of the sun in degrees. Values range from 0 to 360. Zero is an origin point in a sphere determined by Unreal Engine. -- **sun_altitude_angle** (_float_) -Altitude angle of the sun in degrees. Values range from -90 to 90 corresponding to midnight and midday each. +- **sun_azimuth_angle** (_float – degrees_) +The azimuth angle of the sun. Values range from 0 to 360. Zero is an origin point in a sphere determined by Unreal Engine. +- **sun_altitude_angle** (_float – degrees_) +Altitude angle of the sun. Values range from -90 to 90 corresponding to midnight and midday each. - **fog_density** (_float_) Fog concentration or thickness. It only affects the RGB camera sensor. Values range from 0 to 100. -- **fog_distance** (_float_) -Fog start distance (in meters). Values range from 0 to infinite. +- **fog_distance** (_float – meters_) +Fog start distance. Values range from 0 to infinite. - **wetness** (_float_) Wetness intensity. It only affects the RGB camera sensor. Values range from 0 to 100. - **fog_falloff** (_float_) @@ -2544,10 +2600,10 @@ Method to initialize an object defining weather conditions. This class has some - `precipitation` (_float_) – 0 is no rain at all, 100 a heavy rain. - `precipitation_deposits` (_float_) – 0 means no puddles on the road, 100 means roads completely capped by rain. - `wind_intensity` (_float_) – 0 is calm, 100 a strong wind. - - `sun_azimuth_angle` (_float_) – 0 is an arbitrary North, 180 its corresponding South. - - `sun_altitude_angle` (_float_) – 90 is midday, -90 is midnight. + - `sun_azimuth_angle` (_float – degrees_) – 0 is an arbitrary North, 180 its corresponding South. + - `sun_altitude_angle` (_float – degrees_) – 90 is midday, -90 is midnight. - `fog_density` (_float_) – Concentration or thickness of the fog, from 0 to 100. - - `fog_distance` (_float_) – Distance where the fog starts in meters. + - `fog_distance` (_float – meters_) – Distance where the fog starts in meters. - `wetness` (_float_) – Humidity percentages of the road, from 0 to 100. - `fog_falloff` (_float_) – Density (specific mass) of the fog, from 0 to infinity. - **Note:** _ClearNoon, CloudyNoon, WetNoon, WetCloudyNoon, SoftRainNoon, MidRainyNoon, HardRainNoon, ClearSunset, CloudySunset, WetSunset, WetCloudySunset, SoftRainSunset, MidRainSunset, HardRainSunset. @@ -2572,14 +2628,14 @@ Class that defines specific physical parameters for wheel objects that will be p A scalar value that indicates the friction of the wheel. - **damping_rate** (_float_) Damping rate of the wheel. -- **max_steer_angle** (_float_) -Maximum angle in degrees that the wheel can steer. -- **radius** (_float_) -Radius of the wheel in centimeters. -- **max_brake_torque** (_float_) -Maximum brake torque in Nm. -- **max_handbrake_torque** (_float_) -Maximum handbrake torque in Nm. +- **max_steer_angle** (_float – degrees_) +Maximum angle that the wheel can steer. +- **radius** (_float – centimeters_) +Radius of the wheel. +- **max_brake_torque** (_float – N*m_) +Maximum brake torque. +- **max_handbrake_torque** (_float – N*m_) +Maximum handbrake torque. - **position** (_[carla.Vector3D](#carla.Vector3D)_) World position of the wheel. This is a read-only parameter. @@ -2588,11 +2644,11 @@ World position of the wheel. This is a read-only parameter. - **Parameters:** - `tire_friction` (_float_) - `damping_rate` (_float_) - - `max_steer_angle` (_float_) - - `radius` (_float_) - - `max_brake_torque` (_float_) - - `max_handbrake_torque` (_float_) - - `position` (_[carla.Vector3D](#carla.Vector3D)_) + - `max_steer_angle` (_float – degrees_) + - `radius` (_float – centimerers_) + - `max_brake_torque` (_float – N*m_) + - `max_handbrake_torque` (_float – N*m_) + - `position` (_[carla.Vector3D](#carla.Vector3D) – meters_)
Dunder methods
- **\__eq__**(**self**, **other**=[carla.WheelPhysicsControl](#carla.WheelPhysicsControl)) @@ -2628,12 +2684,12 @@ Stops the callback for `callback_id` started with **on_tic - **tick**(**self**, **seconds**=10.0) This method only has effect on synchronous mode, when both client and server move together. The client tells the server when to step to the next frame and returns the id of the newly started frame. - **Parameters:** - - `seconds` (_float_) – Maximum time in seconds the server should wait for a tick. It is set to 10.0 by default. + - `seconds` (_float – seconds_) – Maximum time the server should wait for a tick. It is set to 10.0 by default. - **Return:** _int_ - **wait_for_tick**(**self**, **seconds**=10.0) The client tells the server to pause the simulation until a **World.tick()** is received. - **Parameters:** - - `seconds` (_float_) – Maximum time in seconds the server should wait for a tick. It is set to 10.0 by default. + - `seconds` (_float – seconds_) – Maximum time the server should wait for a tick. It is set to 10.0 by default. - **Return:** _[carla.WorldSnapshot](#carla.WorldSnapshot)_ - **spawn_actor**(**self**, **blueprint**, **transform**, **attach_to**=None, **attachment**=Rigid) The method will create, return and spawn an actor into the world. The actor will need an available blueprint to be created and a transform (location and rotation). It can also be attached to a parent with a certain attachment type. @@ -2655,6 +2711,8 @@ Same as **spawn_actor()** but returns None o Freezes or unfreezes all traffic lights in the scene. Frozen traffic lights can be modified by the user but the time will not update them until unfrozen. - **Parameters:** - `frozen` (_bool_) +- **reset_all_traffic_lights**(**self**) +Resets the cycle of all traffic lights in the map to the initial state.
Getters
- **get_actor**(**self**, **actor_id**) @@ -2673,12 +2731,19 @@ Returns a list of actor blueprints available to ease the spawn of these into the - **get_vehicles_light_states**(**self**) Returns a dict where the keys are [carla.Actor](#carla.Actor) IDs and the values are [carla.VehicleLightState](#carla.VehicleLightState) of that vehicle. - **Return:** _dict_ +- **get_level_bbs**(**self**, **actor_type**=None) +Returns an array of bounding boxes with location and rotation in world space. The method returns all the bounding boxes in the level by default, but the query can be filtered by semantic tags with the argument `actor_type`. + - **Parameters:** + - `actor_type` (_[carla.CityObjectLabel](#carla.CityObjectLabel)_) – Semantic tag of the elements contained in the bounding boxes that are returned. + - **Return:** _array([carla.BoundingBox](#carla.BoundingBox))_ - **get_lightmanager**(**self**) Returns an instance of [carla.LightManager](#carla.LightManager) that can be used to handle the lights in the scene. - **Return:** _[carla.LightManager](#carla.LightManager)_ - **get_map**(**self**) -Returns the object containing the navigation map used to describe this world. +Asks the server for the XODR containing the map file, and returns this parsed as a [carla.Map](#carla.Map). - **Return:** _[carla.Map](#carla.Map)_ + - **Warning:** _This method does call the simulation. It is expensive, and should only be called once. +_ - **get_traffic_light**(**self**, **landmark**) Provided a landmark, returns the traffic light object it describes. - **Parameters:** @@ -2737,7 +2802,7 @@ Creates an object containing desired settings that could later be applied throug - **Parameters:** - `synchronous_mode` (_bool_) – Set this to true to enable client-server synchrony. - `no_rendering_mode` (_bool_) – Set this to true to completely disable rendering in the simulation. - - `fixed_delta_seconds` (_float_) – Set this time in seconds to get a fixed time-step in between frames. 0.0 means variable time-step and it is the default mode. + - `fixed_delta_seconds` (_float – seconds_) – Set a fixed time-step in between frames. 0.0 means variable time-step and it is the default mode.
Dunder methods
- **\__eq__**(**self**, **other**=[carla.WorldSettings](#carla.WorldSettings)) @@ -2760,7 +2825,7 @@ This snapshot comprises all the information for every actor on scene at a certai A value unique for every snapshot to differenciate them. - **frame** (_int_) Simulation frame in which the snapshot was taken. -- **timestamp** (_[carla.Timestamp](#carla.Timestamp)_) +- **timestamp** (_[carla.Timestamp](#carla.Timestamp) – seconds_) Precise moment in time when snapshot was taken. This class works in seconds as given by the operative system.

Methods

@@ -2791,58 +2856,109 @@ Returns True if both **timestamp** are diffe --- ## command.ApplyAngularImpulse -Command adaptation of **add_angular_impulse()** in [carla.Actor](#carla.Actor). Adds angular impulse to an actor. +Command adaptation of __add_angular_impulse()__ in [carla.Actor](#carla.Actor). Applies an angular impulse to an actor.

Instance Variables

- **actor_id** (_int_) Actor affected by the command. -- **impulse** (_[carla.Vector3D](#carla.Vector3D)_) -Angular impulse applied to the actor. Determines magnitude and global axis where it is applied. +- **impulse** (_[carla.Vector3D](#carla.Vector3D) – degrees*s_) +Angular impulse applied to the actor.

Methods

- **\__init__**(**self**, **actor**, **impulse**) - **Parameters:** - `actor` (_[carla.Actor](#carla.Actor) or int_) – Actor or its ID to whom the command will be applied to. - - `impulse` (_[carla.Vector3D](#carla.Vector3D)_) + - `impulse` (_[carla.Vector3D](#carla.Vector3D) – degrees*s_) --- -## command.ApplyAngularVelocity -Command adaptation of **set_angular_velocity()** in [carla.Actor](#carla.Actor). Sets an actor's angular velocity. +## command.ApplyForce +Command adaptation of __add_force()__ in [carla.Actor](#carla.Actor). Applies a force to an actor.

Instance Variables

-- **actor_id** (_int_) +- **actor_id** (_int_) Actor affected by the command. -- **angular_velocity** (_[carla.Vector3D](#carla.Vector3D)_) -The 3D angular velocity that will be applied to the actor. +- **force** (_[carla.Vector3D](#carla.Vector3D) – N_) +Force applied to the actor over time.

Methods

-- **\__init__**(**self**, **actor**, **angular_velocity**) +- **\__init__**(**self**, **actor**, **force**) - **Parameters:** - `actor` (_[carla.Actor](#carla.Actor) or int_) – Actor or its ID to whom the command will be applied to. - - `angular_velocity` (_[carla.Vector3D](#carla.Vector3D)_) + - `force` (_[carla.Vector3D](#carla.Vector3D) – N_) --- ## command.ApplyImpulse -Command adaptation of **add_impulse()** in [carla.Actor](#carla.Actor). Adds impulse to an actor. +Command adaptation of __add_impulse()__ in [carla.Actor](#carla.Actor). Applies an impulse to an actor.

Instance Variables

- **actor_id** (_int_) Actor affected by the command. -- **impulse** (_[carla.Vector3D](#carla.Vector3D)_) +- **impulse** (_[carla.Vector3D](#carla.Vector3D) – N*s_) Impulse applied to the actor.

Methods

- **\__init__**(**self**, **actor**, **impulse**) - **Parameters:** - `actor` (_[carla.Actor](#carla.Actor) or int_) – Actor or its ID to whom the command will be applied to. - - `impulse` (_[carla.Vector3D](#carla.Vector3D)_) + - `impulse` (_[carla.Vector3D](#carla.Vector3D) – N*s_) + +--- + +## command.ApplyTargetAngularVelocity +Command adaptation of __set_target_angular_velocity()__ in [carla.Actor](#carla.Actor). Sets the actor's angular velocity vector. + +

Instance Variables

+- **actor_id** (_int_) +Actor affected by the command. +- **angular_velocity** (_[carla.Vector3D](#carla.Vector3D) – deg/s_) +The 3D angular velocity that will be applied to the actor. + +

Methods

+- **\__init__**(**self**, **actor**, **angular_velocity**) + - **Parameters:** + - `actor` (_[carla.Actor](#carla.Actor) or int_) – Actor or its ID to whom the command will be applied to. + - `angular_velocity` (_[carla.Vector3D](#carla.Vector3D) – deg/s_) – Angular velocity vector applied to the actor. + +--- + +## command.ApplyTargetVelocity +Command adaptation of __set_target_velocity()__ in [carla.Actor](#carla.Actor). + +

Instance Variables

+- **actor_id** (_int_) +Actor affected by the command. +- **velocity** (_[carla.Vector3D](#carla.Vector3D) – m/s_) +The 3D velocity applied to the actor. + +

Methods

+- **\__init__**(**self**, **actor**, **velocity**) + - **Parameters:** + - `actor` (_[carla.Actor](#carla.Actor) or int_) – Actor or its ID to whom the command will be applied to. + - `velocity` (_[carla.Vector3D](#carla.Vector3D) – m/s_) – Velocity vector applied to the actor. + +--- + +## command.ApplyTorque +Command adaptation of __add_torque()__ in [carla.Actor](#carla.Actor). Applies a torque to an actor. + +

Instance Variables

+- **actor_id** (_int_) +Actor affected by the command. +- **torque** (_[carla.Vector3D](#carla.Vector3D) – degrees_) +Torque applied to the actor over time. + +

Methods

+- **\__init__**(**self**, **actor**, **torque**) + - **Parameters:** + - `actor` (_[carla.Actor](#carla.Actor) or int_) – Actor or its ID to whom the command will be applied to. + - `torque` (_[carla.Vector3D](#carla.Vector3D) – degrees_) --- ## command.ApplyTransform -Command adaptation of **set_transform()** in [carla.Actor](#carla.Actor). Sets a new transform to an actor. +Command adaptation of __set_transform()__ in [carla.Actor](#carla.Actor). Sets a new transform to an actor.

Instance Variables

- **actor_id** (_int_) @@ -2859,7 +2975,7 @@ Transformation to be applied. --- ## command.ApplyVehicleControl -Command adaptation of **apply_control()** in [carla.Vehicle](#carla.Vehicle). Applies a certain control to a vehicle. +Command adaptation of __apply_control()__ in [carla.Vehicle](#carla.Vehicle). Applies a certain control to a vehicle.

Instance Variables

- **actor_id** (_int_) @@ -2875,25 +2991,8 @@ Vehicle control to be applied. --- -## command.ApplyVelocity -Command adaptation of **set_velocity()** in [carla.Actor](#carla.Actor). Sets an actor's velocity. - -

Instance Variables

-- **actor_id** (_int_) -Actor affected by the command. -- **velocity** (_[carla.Vector3D](#carla.Vector3D)_) -The 3D velocity applied to the actor. - -

Methods

-- **\__init__**(**self**, **actor**, **velocity**) - - **Parameters:** - - `actor` (_[carla.Actor](#carla.Actor) or int_) – Actor or its ID to whom the command will be applied to. - - `velocity` (_[carla.Vector3D](#carla.Vector3D)_) - ---- - ## command.ApplyWalkerControl -Command adaptation of **apply_control()** in [carla.Walker](#carla.Walker). Applies a control to a walker. +Command adaptation of __apply_control()__ in [carla.Walker](#carla.Walker). Applies a control to a walker.

Instance Variables

- **actor_id** (_int_) @@ -2917,7 +3016,7 @@ Apply a state to the walker actor. Specially useful to initialize an actor them Walker actor affected by the command. - **transform** (_[carla.Transform](#carla.Transform)_) Transform to be applied. -- **speed** (_float_) +- **speed** (_float – m/s_) Speed to be applied.

Methods

@@ -2925,12 +3024,12 @@ Speed to be applied. - **Parameters:** - `actor` (_[carla.Actor](#carla.Actor) or int_) – Actor or its ID to whom the command will be applied to. - `transform` (_[carla.Transform](#carla.Transform)_) - - `speed` (_float_) + - `speed` (_float – m/s_) --- ## command.DestroyActor -Command adaptation of **destroy()** in [carla.Actor](#carla.Actor) that tells the simulator to destroy this actor. It has no effect if the actor was already destroyed. When executed with **apply_batch_sync()** in [carla.Client](#carla.Client) there will be a command.Response that will return a boolean stating whether the actor was successfully destroyed. +Command adaptation of __destroy()__ in [carla.Actor](#carla.Actor) that tells the simulator to destroy this actor. It has no effect if the actor was already destroyed. When executed with __apply_batch_sync()__ in [carla.Client](#carla.Client) there will be a command.Response that will return a boolean stating whether the actor was successfully destroyed.

Instance Variables

- **actor_id** (_int_) @@ -2944,7 +3043,7 @@ Actor affected by the command. --- ## command.Response -States the result of executing a command as either the ID of the actor to whom the command was applied to (when succeeded) or an error string (when failed). actor ID, depending on whether or not the command succeeded. The method **apply_batch_sync()** in [carla.Client](#carla.Client) returns a list of these to summarize the execution of a batch. +States the result of executing a command as either the ID of the actor to whom the command was applied to (when succeeded) or an error string (when failed). actor ID, depending on whether or not the command succeeded. The method __apply_batch_sync()__ in [carla.Client](#carla.Client) returns a list of these to summarize the execution of a batch.

Instance Variables

- **actor_id** (_int_) @@ -2960,7 +3059,7 @@ Returns True if the command execution fails, and False if it was s --- ## command.SetAutopilot -Command adaptation of **set_autopilot()** in [carla.Vehicle](#carla.Vehicle). Turns on/off the vehicle's autopilot mode. +Command adaptation of __set_autopilot()__ in [carla.Vehicle](#carla.Vehicle). Turns on/off the vehicle's autopilot mode.

Instance Variables

- **actor_id** (_int_) @@ -2980,7 +3079,7 @@ Port of the Traffic Manager where the vehicle is to be registered or unlisted. --- ## command.SetSimulatePhysics -Command adaptation of **set_simulate_physics()** in [carla.Actor](#carla.Actor). Determines whether an actor will be affected by physics or not. +Command adaptation of __set_simulate_physics()__ in [carla.Actor](#carla.Actor). Determines whether an actor will be affected by physics or not.

Instance Variables

- **actor_id** (_int_) @@ -2997,7 +3096,7 @@ If physics should be activated or not. --- ## command.SetVehicleLightState -Command adaptation of **set_light_state()** in [carla.Vehicle](#carla.Vehicle). Sets the light state of a vehicle. +Command adaptation of __set_light_state()__ in [carla.Vehicle](#carla.Vehicle). Sets the light state of a vehicle.

Instance Variables

- **actor_id** (_int_) @@ -3014,7 +3113,7 @@ Defines the light state of a vehicle. --- ## command.SpawnActor -Command adaptation of **spawn_actor()** in [carla.World](#carla.World). Spawns an actor into the world based on the blueprint provided and the transform. If a parent is provided, the actor is attached to it. +Command adaptation of __spawn_actor()__ in [carla.World](#carla.World). Spawns an actor into the world based on the blueprint provided and the transform. If a parent is provided, the actor is attached to it.

Instance Variables

- **transform** (_[carla.Transform](#carla.Transform)_) diff --git a/Docs/ref_code_recipes.md b/Docs/ref_code_recipes.md index b38392438..03959b4ed 100644 --- a/Docs/ref_code_recipes.md +++ b/Docs/ref_code_recipes.md @@ -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:
``` --- -## 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 diff --git a/Docs/ref_recorder_binary_file_format.md b/Docs/ref_recorder_binary_file_format.md index 6c3cf20a0..d1345999b 100644 --- a/Docs/ref_recorder_binary_file_format.md +++ b/Docs/ref_recorder_binary_file_format.md @@ -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 diff --git a/Docs/ref_sensors.md b/Docs/ref_sensors.md index 883a0f968..6e874d346 100644 --- a/Docs/ref_sensors.md +++ b/Docs/ref_sensors.md @@ -1,18 +1,18 @@ # Sensors reference -* [__Collision detector__](#collision-detector) -* [__Depth camera__](#depth-camera) -* [__GNSS sensor__](#gnss-sensor) -* [__IMU sensor__](#imu-sensor) -* [__Lane invasion detector__](#lane-invasion-detector) -* [__LIDAR sensor__](#lidar-sensor) +* [__Collision detector__](#collision-detector) +* [__Depth camera__](#depth-camera) +* [__GNSS sensor__](#gnss-sensor) +* [__IMU sensor__](#imu-sensor) +* [__Lane invasion detector__](#lane-invasion-detector) +* [__LIDAR sensor__](#lidar-sensor) * [__Obstacle detector__](#obstacle-detector) -* [__Radar sensor__](#radar-sensor) -* [__RGB camera__](#rgb-camera) -* [__RSS sensor__](#rss-sensor) -* [__Semantic LIDAR sensor__](#semantic-lidar-sensor) -* [__Semantic segmentation camera__](#semantic-segmentation-camera) -* [__DVS camera__](#dvs-camera) +* [__Radar sensor__](#radar-sensor) +* [__RGB camera__](#rgb-camera) +* [__RSS sensor__](#rss-sensor) +* [__Semantic LIDAR sensor__](#semantic-lidar-sensor) +* [__Semantic segmentation camera__](#semantic-segmentation-camera) +* [__DVS camera__](#dvs-camera) --- ## Collision detector @@ -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.
__1.__ Set the sensor's frequency `sensors_bp['lidar'][0].set_attribute('rotation_frequency','10')`.
__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.
__1.__ Set the sensor's frequency `sensors_bp['lidar'][0].set_attribute('rotation_frequency','10')`.
__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 fstop float -8.0 +1.4 Opening of the camera lens. Aperture is 1/fstop with typical lens going down to f/1.2 (larger opening). Larger numbers will reduce the Depth of Field effect. image_size_x @@ -858,7 +864,7 @@ A value of 1.5 means that we want the sensor to capture data each second and a h iso float -200.0 +100.0 The camera sensor sensitivity. gamma @@ -959,22 +965,22 @@ Since these effects are provided by UE, please make sure to check their document exposure_mode str -manual +histogram Can be manual or histogram. More in UE4 docs. exposure_compensation float --2.2 +Linux: -1.5
Windows: 0.0 Logarithmic adjustment for the exposure. 0: no adjustment, -1:2x darker, -2:4 darker, 1:2x brighter, 2:4x brighter. exposure_min_bright float -0.1 +7.0 In exposure_mode: "histogram". Minimum brightness for auto exposure. The lowest the eye can adapt within. Must be greater than 0 and less than or equal to exposure_max_bright. exposure_max_bright float -2.0 +9.0 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`. exposure_speed_up @@ -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.
__1.__ Set the sensor's frequency `sensors_bp['lidar'][0].set_attribute('rotation_frequency','10')`.
-__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: @@ -1444,59 +1458,123 @@ The following tags are currently available: + - + + - + + - + + - + + - + + - + + - - + + + - + + - - + + + - + + - - + + + - + + - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Value Tag Converted colorDescription
0 Unlabeled( 0, 0, 0)(0, 0, 0)Elements that have not been categorized are considered Unlabeled. This category is meant to be empty or at least contain elements with no collisions.
1 Building( 70, 70, 70)(70, 70, 70)Buildings like houses, skyscrapers,... and the elements attached to them.
E.g. air conditioners, scaffolding, awning or ladders and much more.
2 Fence(190, 153, 153)(100, 40, 40)Barriers, railing, or other upright structures. Basically wood or wire assemblies that enclose an area of ground.
3 Other(250, 170, 160)(55, 90, 80) Everything that does not belong to any other category.
4 Pedestrian(220, 20, 60)(220, 20, 60)Humans that walk or ride/drive any kind of vehicle or mobility system.
E.g. bicycles or scooters, skateboards, horses, roller-blades, wheel-chairs, etc.
5 Pole(153, 153, 153)(153, 153, 153)Small mainly vertically oriented pole. If the pole has a horizontal part (often for traffic light poles) this is also considered pole.
E.g. sign pole, traffic light poles.
6 Road line(157, 234, 50)RoadLine(157, 234, 50)The markings on the road.
7 Road(128, 64, 128)(128, 64, 128)Part of ground on which cars usually drive.
E.g. lanes in any directions, and streets.
8 Sidewalk(244, 35, 232)SideWalk(244, 35, 232)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.
9 Vegetation(107, 142, 35)(107, 142, 35) Trees, hedges, all kinds of vertical vegetation. Ground-level vegetation is considered Terrain.
10 Car( 0, 0, 142)Vehicles(0, 0, 142)Cars, vans, trucks, motorcycles, bikes, buses, trains.
11 Wall(102, 102, 156)(102, 102, 156)Individual standing walls. Not part of a building.
12 Traffic sign(220, 220, 0)TrafficSign(220, 220, 0)Signs installed by the state/city authority, usually for traffic regulation. This category does not include the poles where signs are attached to.
E.g. traffic- signs, parking signs, direction signs...
13 Sky(70, 130, 180)Open sky. Includes clouds and the sun.
14 Ground(81, 0, 81)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.
15 Bridge(150, 100, 100)Only the structure of the bridge. Fences, people, vehicles, an other elements on top of it are labeled separately.
16 RailTrack(230, 150, 140)All kind of rail tracks that are non-drivable by cars.
E.g. subway and train rail tracks.
17 GuardRail(180, 165, 180)All types of guard rails/crash barriers.
18 TrafficLight(250, 170, 30)Traffic light boxes without their poles.
19 Static(110, 190, 160)Elements in the scene and props that are immovable.
E.g. fire hydrants, fixed benches, fountains, bus stops, etc.
20 Dynamic(170, 120, 50)Elements whose position is susceptible to change over time.
E.g. Movable trash bins, buggies, bags, wheelchairs, animals, etc.
21 Water(45, 60, 150)Horizontal water surfaces.
E.g. Lakes, sea, rivers.
22 Terrain(145, 170, 100)Grass, ground-level vegetation, soil or sand. These areas are not meant to be driven on. This label includes a possibly delimiting curb.

@@ -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 diff --git a/Docs/ros_installation.md b/Docs/ros_installation.md index d52e43a3a..d53abfb70 100644 --- a/Docs/ros_installation.md +++ b/Docs/ros_installation.md @@ -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__](#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 + ROS is still [experimental](http://wiki.ros.org/noetic/Installation) for Windows, so the ROS bridge has only been tested for Linux systems. + --- ## 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. +Make sure that both requirements work properly before continuing with the installation. -!!! Important - Make sure that both CARLA and ROS 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- -``` - -### 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 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 .egg file (included). Use the one supported by the Python version installed. -
+

Note: .egg files may be either in `/PythonAPI/` or `/PythonAPI/dist/` depending on the CARLA installation. ```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")' ``` diff --git a/Docs/start_introduction.md b/Docs/start_introduction.md index bf8d17719..753b021d4 100644 --- a/Docs/start_introduction.md +++ b/Docs/start_introduction.md @@ -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) diff --git a/Docs/start_quickstart.md b/Docs/start_quickstart.md index f5ed5985c..1b6408b47 100644 --- a/Docs/start_quickstart.md +++ b/Docs/start_quickstart.md @@ -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 @@ ```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 ``` @@ -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

@@ -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 ``` --- diff --git a/Docs/tuto_A_add_map.md b/Docs/tuto_A_add_map.md index 387fac0f7..e9a54d0b3 100644 --- a/Docs/tuto_A_add_map.md +++ b/Docs/tuto_A_add_map.md @@ -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 ` is not provided, the Docker will make a package of CARLA. diff --git a/Docs/tuto_A_add_props.md b/Docs/tuto_A_add_props.md index a7716dceb..c3af52f42 100644 --- a/Docs/tuto_A_add_props.md +++ b/Docs/tuto_A_add_props.md @@ -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. diff --git a/Docs/tuto_A_add_vehicle.md b/Docs/tuto_A_add_vehicle.md index d8bad3506..8c0d09e39 100644 --- a/Docs/tuto_A_add_vehicle.md +++ b/Docs/tuto_A_add_vehicle.md @@ -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 # The name used in step 10.2 +python3 manual_control.py --filter # The name used in step 10.2 ``` --- diff --git a/Docs/tuto_A_create_standalone.md b/Docs/tuto_A_create_standalone.md index c60de808d..d4b8aca82 100644 --- a/Docs/tuto_A_create_standalone.md +++ b/Docs/tuto_A_create_standalone.md @@ -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 diff --git a/Docs/tuto_A_vehicle_modelling.md b/Docs/tuto_A_vehicle_modelling.md index 6ba949ce8..06d536dca 100644 --- a/Docs/tuto_A_vehicle_modelling.md +++ b/Docs/tuto_A_vehicle_modelling.md @@ -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 diff --git a/Docs/tuto_D_create_sensor.md b/Docs/tuto_D_create_sensor.md index e28c395f6..de49031d8 100644 --- a/Docs/tuto_D_create_sensor.md +++ b/Docs/tuto_D_create_sensor.md @@ -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 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 diff --git a/Docs/tuto_D_customize_vehicle_suspension.md b/Docs/tuto_D_customize_vehicle_suspension.md new file mode 100644 index 000000000..deec87efc --- /dev/null +++ b/Docs/tuto_D_customize_vehicle_suspension.md @@ -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/`. They are named such as: `BP__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) +

In this example, the blueprint of the front left wheel of the Audi A2 is named as BP_AudiA2_FLW.
+ +`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) +
The Suspension panel inside a wheel blueprint.
+ +!!! 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. + +
+ + + + + + + + + +
Stiff suspensionCoupeUrbanVanOff-roadTruckSoft suspension
+
+ +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. + + + + + + + + + + +
ParameterizationVehicles
+Suspension Force Offset0.0
+Suspension Max Raise7.5
+Suspension Max Drop7.5
+Suspension Natural Frequency9.5
+Suspension Damping Ratio1.0
+Sweep TypeSimpleAndComplex
+
+vehicle.audi.tt
+vehicle.lincoln.mkz2017
+vehicle.mercedes-benz.coupe
+vehicle.seat.leon
+vehicle.tesla.model3
+
+
+ +### Off-road + +Vehicles with a soft suspension. + + + + + + + + + + +
ParameterizationVehicles
+Suspension Force Offset0.0
+Suspension Max Raise15.0
+Suspension Max Drop15.0
+Suspension Natural Frequency7.0
+Suspension Damping Ratio0.5
+Sweep TypeSimpleAndComplex
+
+vehicle.audi.etron
+vehicle.jeep.wrangler_rubicon
+vehicle.nissan.patrol
+vehicle.tesla.cybertruck
+
+
+ + +### Truck + +Vehicles with the softest suspension. + + + + + + + + + + +
ParameterizationVehicles
+Suspension Force Offset0.0
+Suspension Max Raise17.0
+Suspension Max Drop17.0
+Suspension Natural Frequency6.0
+Suspension Damping Ratio0.4
+Sweep TypeSimpleAndComplex
+
+vehicle.carlamotors.carlacola
+
+
+ + +### Urban + +Vehicles with a soft suspension. + + + + + + + + + + +
ParameterizationVehicles
+Suspension Force Offset0.0
+Suspension Max Raise8.0
+Suspension Max Drop8.0
+Suspension Natural Frequency9.0
+Suspension Damping Ratio0.8
+Sweep TypeSimpleAndComplex
+
+vehicle.audi.a2
+vehicle.bmw.grandtourer
+vehicle.chevrolet.impala
+vehicle.citroen.c3
+vehicle.dodge_charger.police
+vehicle.mini.cooperst
+vehicle.mustang.mustang
+vehicle.nissan.micra
+vehicle.toyota.prius
+
+
+ +### Van + +Vehicles with a middle-ground suspension. + + + + + + + + + + +
ParameterizationVehicles
+Suspension Force Offset0.0
+Suspension Max Raise9.0
+Suspension Max Drop9.0
+Suspension Natural Frequency8.0
+Suspension Damping Ratio0.8
+Sweep TypeSimpleAndComplex
+
+vehicle.volkswagen.t2
+
+
+ + +--- + +Use the forum to post any doubts, issues or suggestions regarding this topic. + + + +Here are some advised readings after this one. + + diff --git a/Docs/tuto_D_generate_pedestrian_navigation.md b/Docs/tuto_D_generate_pedestrian_navigation.md index 3b3b45919..603f5edca 100644 --- a/Docs/tuto_D_generate_pedestrian_navigation.md +++ b/Docs/tuto_D_generate_pedestrian_navigation.md @@ -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...). | + + + + + + + + + + + + + + + + + + + + + + + + + + + +
TypeStart withDescription
GroundRoad_SidewalkPedestrians can walk over these meshes freely (sidewalks...).
GrassRoad_CrosswalkPedestrians can walk over these meshes but as a second option if no ground is found.
RoadRoad_GrassPedestrians won't be allowed to walk on it unless we specify some percentage of pedestrians that will be allowed.
CrosswalkRoad_Road, Road_Curb, Road_Gutter, Road_MarkingPedestrians can cross the roads only through these meshes.
BlockAny other namePedestrians will avoid these meshes always (are obstacles like traffic lights, trees, houses...).

diff --git a/Docs/tuto_G_control_walker_skeletons.md b/Docs/tuto_G_control_walker_skeletons.md index 39bc39a2d..afa17bcc0 100644 --- a/Docs/tuto_G_control_walker_skeletons.md +++ b/Docs/tuto_G_control_walker_skeletons.md @@ -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**.
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 diff --git a/Docs/tuto_G_openstreetmap.md b/Docs/tuto_G_openstreetmap.md index ebfd49471..eb6a4d9a9 100644 --- a/Docs/tuto_G_openstreetmap.md +++ b/Docs/tuto_G_openstreetmap.md @@ -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)
Outcome of the CARLA map generation using OpenStreetMap.
+!!! 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. diff --git a/Docs/tuto_G_retrieve_data.md b/Docs/tuto_G_retrieve_data.md index 95581fbef..be168678b 100644 --- a/Docs/tuto_G_retrieve_data.md +++ b/Docs/tuto_G_retrieve_data.md @@ -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 ```
@@ -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 ```
Optional arguments in spawn_npc.py @@ -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 ```
@@ -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 diff --git a/Jenkinsfile b/Jenkinsfile index 0c4c788b8..17f3036ab 100644 --- a/Jenkinsfile +++ b/Jenkinsfile @@ -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 diff --git a/LibCarla/cmake/client/CMakeLists.txt b/LibCarla/cmake/client/CMakeLists.txt index c0b9de355..ee7fabf2c 100644 --- a/LibCarla/cmake/client/CMakeLists.txt +++ b/LibCarla/cmake/client/CMakeLists.txt @@ -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) diff --git a/LibCarla/cmake/test/CMakeLists.txt b/LibCarla/cmake/test/CMakeLists.txt index d2ac1ddf1..432f509e7 100644 --- a/LibCarla/cmake/test/CMakeLists.txt +++ b/LibCarla/cmake/test/CMakeLists.txt @@ -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") diff --git a/LibCarla/source/carla/ThreadPool.h b/LibCarla/source/carla/ThreadPool.h index c9cc38567..b807d4e24 100644 --- a/LibCarla/source/carla/ThreadPool.h +++ b/LibCarla/source/carla/ThreadPool.h @@ -12,6 +12,7 @@ #include "carla/Time.h" #include +#include #include #include @@ -40,7 +41,7 @@ namespace carla { std::future Post(FunctorT &&functor) { auto task = std::packaged_task(std::forward(functor)); auto future = task.get_future(); - _io_context.post(carla::MoveHandler(task)); + boost::asio::post(_io_context, carla::MoveHandler(task)); return future; } diff --git a/LibCarla/source/carla/client/Actor.cpp b/LibCarla/source/carla/client/Actor.cpp index aee967280..476d51890 100644 --- a/LibCarla/source/carla/client/Actor.cpp +++ b/LibCarla/source/carla/client/Actor.cpp @@ -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); } diff --git a/LibCarla/source/carla/client/Actor.h b/LibCarla/source/carla/client/Actor.h index 03f66b71d..3710765bb 100644 --- a/LibCarla/source/carla/client/Actor.h +++ b/LibCarla/source/carla/client/Actor.h @@ -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); diff --git a/LibCarla/source/carla/client/LaneInvasionSensor.cpp b/LibCarla/source/carla/client/LaneInvasionSensor.cpp index ffff730b2..30c48f8b6 100644 --- a/LibCarla/source/carla/client/LaneInvasionSensor.cpp +++ b/LibCarla/source/carla/client/LaneInvasionSensor.cpp @@ -151,8 +151,7 @@ namespace client { } auto episode = GetEpisode().Lock(); - SharedPtr map = episode->GetCurrentMap(); - + auto cb = std::make_shared( *vehicle, episode->GetCurrentMap(), diff --git a/LibCarla/source/carla/client/ServerSideSensor.cpp b/LibCarla/source/carla/client/ServerSideSensor.cpp index 102407379..52ede6457 100644 --- a/LibCarla/source/carla/client/ServerSideSensor.cpp +++ b/LibCarla/source/carla/client/ServerSideSensor.cpp @@ -11,8 +11,6 @@ #include -#include - namespace carla { namespace client { diff --git a/LibCarla/source/carla/client/World.cpp b/LibCarla/source/carla/client/World.cpp index ae56742e5..bb11f89d2 100644 --- a/LibCarla/source/carla/client/World.cpp +++ b/LibCarla/source/carla/client/World.cpp @@ -150,6 +150,10 @@ namespace client { return nullptr; } + void World::ResetAllTrafficLights() { + _episode.Lock()->ResetAllTrafficLights(); + } + SharedPtr World::GetLightManager() const { return _episode.Lock()->GetLightManager(); } @@ -158,5 +162,9 @@ namespace client { _episode.Lock()->FreezeAllTrafficLights(frozen); } + std::vector World::GetLevelBBs(uint8_t queried_tag) const { + return _episode.Lock()->GetLevelBBs(queried_tag); + } + } // namespace client } // namespace carla diff --git a/LibCarla/source/carla/client/World.h b/LibCarla/source/carla/client/World.h index 2df6af200..981598b37 100644 --- a/LibCarla/source/carla/client/World.h +++ b/LibCarla/source/carla/client/World.h @@ -138,6 +138,8 @@ namespace client { SharedPtr GetTrafficLight(const Landmark& landmark) const; + void ResetAllTrafficLights(); + SharedPtr 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 GetLevelBBs(uint8_t queried_tag) const; + private: detail::EpisodeProxy _episode; diff --git a/LibCarla/source/carla/client/detail/Client.cpp b/LibCarla/source/carla/client/detail/Client.cpp index 46de297f4..77add06c6 100644 --- a/LibCarla/source/carla/client/detail/Client.cpp +++ b/LibCarla/source/carla/client/detail/Client.cpp @@ -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("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 Client::GetLevelBBs(uint8_t queried_tag) const { + using return_t = std::vector; + return _pimpl->CallAndWait("get_all_level_BBs", queried_tag); + } + } // namespace detail } // namespace client } // namespace carla diff --git a/LibCarla/source/carla/client/detail/Client.h b/LibCarla/source/carla/client/detail/Client.h index 4a31b4e1a..eb4f840ec 100644 --- a/LibCarla/source/carla/client/detail/Client.h +++ b/LibCarla/source/carla/client/detail/Client.h @@ -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& lights, bool discard_client = false) const; + /// Returns all the BBs of all the elements of the level + std::vector GetLevelBBs(uint8_t queried_tag) const; + private: class Pimpl; diff --git a/LibCarla/source/carla/client/detail/Simulator.h b/LibCarla/source/carla/client/detail/Simulator.h index 9a7d8731b..0ceacf50c 100644 --- a/LibCarla/source/carla/client/detail/Simulator.h +++ b/LibCarla/source/carla/client/detail/Simulator.h @@ -226,6 +226,11 @@ namespace detail { return _client.GetVehicleLightState(vehicle.GetId()); } + /// Returns all the BBs of all the elements of the level + std::vector 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 GetGroupTrafficLights(TrafficLight &trafficLight) { return _client.GetGroupTrafficLights(trafficLight.GetId()); } diff --git a/LibCarla/source/carla/geom/BoundingBox.h b/LibCarla/source/carla/geom/BoundingBox.h index 726b90b56..8790d78dc 100644 --- a/LibCarla/source/carla/geom/BoundingBox.h +++ b/LibCarla/source/carla/geom/BoundingBox.h @@ -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 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 diff --git a/LibCarla/source/carla/geom/Mesh.h b/LibCarla/source/carla/geom/Mesh.h index be8375818..307a7e1df 100644 --- a/LibCarla/source/carla/geom/Mesh.h +++ b/LibCarla/source/carla/geom/Mesh.h @@ -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; diff --git a/LibCarla/source/carla/geom/Rotation.h b/LibCarla/source/carla/geom/Rotation.h index 6afe21b08..3096dc2de 100644 --- a/LibCarla/source/carla/geom/Rotation.h +++ b/LibCarla/source/carla/geom/Rotation.h @@ -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. diff --git a/LibCarla/source/carla/image/CityScapesPalette.h b/LibCarla/source/carla/image/CityScapesPalette.h index 28f393514..2be428e31 100644 --- a/LibCarla/source/carla/image/CityScapesPalette.h +++ b/LibCarla/source/carla/image/CityScapesPalette.h @@ -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 }; diff --git a/LibCarla/source/carla/rpc/Command.h b/LibCarla/source/carla/rpc/Command.h index c4191e777..b029b4d2e 100644 --- a/LibCarla/source/carla/rpc/Command.h +++ b/LibCarla/source/carla/rpc/Command.h @@ -102,9 +102,9 @@ namespace rpc { MSGPACK_DEFINE_ARRAY(actor, transform, speed); }; - struct ApplyVelocity : CommandBase { - ApplyVelocity() = default; - ApplyVelocity(ActorId id, const geom::Vector3D &value) + struct ApplyTargetVelocity : CommandBase { + 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() = default; - ApplyAngularVelocity(ActorId id, const geom::Vector3D &value) + struct ApplyTargetAngularVelocity : CommandBase { + 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() = 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() = default; ApplyAngularImpulse(ActorId id, const geom::Vector3D &value) @@ -142,6 +152,16 @@ namespace rpc { MSGPACK_DEFINE_ARRAY(actor, impulse); }; + struct ApplyTorque : CommandBase { + 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() = 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>; diff --git a/LibCarla/source/carla/rpc/ObjectLabel.h b/LibCarla/source/carla/rpc/ObjectLabel.h new file mode 100644 index 000000000..5b7b5d30d --- /dev/null +++ b/LibCarla/source/carla/rpc/ObjectLabel.h @@ -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 . + +#pragma once + +#include "carla/MsgPack.h" + +#include + +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); diff --git a/LibCarla/source/carla/rpc/Server.h b/LibCarla/source/carla/rpc/Server.h index baa50bab9..6b51e7c7c 100644 --- a/LibCarla/source/carla/rpc/Server.h +++ b/LibCarla/source/carla/rpc/Server.h @@ -12,6 +12,7 @@ #include "carla/rpc/Response.h" #include +#include #include @@ -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(); } }; diff --git a/LibCarla/source/carla/rss/RssCheck.cpp b/LibCarla/source/carla/rss/RssCheck.cpp index 15dfe3b35..713cf9a62 100644 --- a/LibCarla/source/carla/rss/RssCheck.cpp +++ b/LibCarla/source/carla/rss/RssCheck.cpp @@ -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 ×tamp, _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 ×tamp, } 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 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 diff --git a/LibCarla/source/carla/rss/RssCheck.h b/LibCarla/source/carla/rss/RssCheck.h index 3a7b13e58..b24ae3c70 100644 --- a/LibCarla/source/carla/rss/RssCheck.h +++ b/LibCarla/source/carla/rss/RssCheck.h @@ -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; diff --git a/LibCarla/source/carla/rss/RssSensor.cpp b/LibCarla/source/carla/rss/RssSensor.cpp index 81b2e27e1..c70181616 100644 --- a/LibCarla/source/carla/rss/RssSensor.cpp +++ b/LibCarla/source/carla/rss/RssSensor.cpp @@ -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)) { diff --git a/LibCarla/source/carla/rss/RssSensor.h b/LibCarla/source/carla/rss/RssSensor.h index 37bb7ffcc..89833a9fd 100644 --- a/LibCarla/source/carla/rss/RssSensor.h +++ b/LibCarla/source/carla/rss/RssSensor.h @@ -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; diff --git a/LibCarla/source/carla/streaming/detail/tcp/Client.cpp b/LibCarla/source/carla/streaming/detail/tcp/Client.cpp index da6fd0ab3..71789a08c 100644 --- a/LibCarla/source/carla/streaming/detail/tcp/Client.cpp +++ b/LibCarla/source/carla/streaming/detail/tcp/Client.cpp @@ -15,6 +15,8 @@ #include #include #include +#include +#include #include @@ -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)); }); } diff --git a/LibCarla/source/carla/streaming/detail/tcp/Server.cpp b/LibCarla/source/carla/streaming/detail/tcp/Server.cpp index e788b40cc..3ee00575f 100644 --- a/LibCarla/source/carla/streaming/detail/tcp/Server.cpp +++ b/LibCarla/source/carla/streaming/detail/tcp/Server.cpp @@ -6,6 +6,8 @@ #include "carla/streaming/detail/tcp/Server.h" +#include + #include "carla/Logging.h" #include @@ -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); }); } diff --git a/LibCarla/source/carla/streaming/detail/tcp/Server.h b/LibCarla/source/carla/streaming/detail/tcp/Server.h index c38cfa63c..72cf8fa26 100644 --- a/LibCarla/source/carla/streaming/detail/tcp/Server.h +++ b/LibCarla/source/carla/streaming/detail/tcp/Server.h @@ -12,6 +12,7 @@ #include #include +#include #include @@ -45,7 +46,7 @@ namespace tcp { /// is closed. template 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), diff --git a/LibCarla/source/carla/streaming/detail/tcp/ServerSession.cpp b/LibCarla/source/carla/streaming/detail/tcp/ServerSession.cpp index 8556fdec3..15f570de6 100644 --- a/LibCarla/source/carla/streaming/detail/tcp/ServerSession.cpp +++ b/LibCarla/source/carla/streaming/detail/tcp/ServerSession.cpp @@ -11,6 +11,8 @@ #include #include +#include +#include #include @@ -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); }); diff --git a/LibCarla/source/carla/streaming/low_level/Client.h b/LibCarla/source/carla/streaming/low_level/Client.h index 7db9a4180..aacc4ceba 100644 --- a/LibCarla/source/carla/streaming/low_level/Client.h +++ b/LibCarla/source/carla/streaming/low_level/Client.h @@ -46,12 +46,14 @@ namespace low_level { } } + /// @warning cannot subscribe twice to the same stream (even if it's a + /// MultiStream). template 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> _clients; }; diff --git a/LibCarla/source/carla/trafficmanager/ALSM.cpp b/LibCarla/source/carla/trafficmanager/ALSM.cpp index af4021e81..db3f61dba 100644 --- a/LibCarla/source/carla/trafficmanager/ALSM.cpp +++ b/LibCarla/source/carla/trafficmanager/ALSM.cpp @@ -18,6 +18,7 @@ ALSM::ALSM( AtomicActorSet ®istered_vehicles, BufferMap &buffer_map, TrackTraffic &track_traffic, + std::vector& marked_for_removal, const Parameters ¶meters, 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& 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); diff --git a/LibCarla/source/carla/trafficmanager/ALSM.h b/LibCarla/source/carla/trafficmanager/ALSM.h index 146831e34..83b4f388b 100644 --- a/LibCarla/source/carla/trafficmanager/ALSM.h +++ b/LibCarla/source/carla/trafficmanager/ALSM.h @@ -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& marked_for_removal; const Parameters ¶meters; 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& 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; // 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 ®istered_vehicles, BufferMap &buffer_map, TrackTraffic &track_traffic, + std::vector& marked_for_removal, const Parameters ¶meters, 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(); }; diff --git a/LibCarla/source/carla/trafficmanager/AtomicMap.h b/LibCarla/source/carla/trafficmanager/AtomicMap.h index e2c5a9f08..04d7a9222 100644 --- a/LibCarla/source/carla/trafficmanager/AtomicMap.h +++ b/LibCarla/source/carla/trafficmanager/AtomicMap.h @@ -27,7 +27,12 @@ namespace traffic_manager { void AddEntry(const std::pair &entry) { std::lock_guard 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 { diff --git a/LibCarla/source/carla/trafficmanager/CollisionStage.cpp b/LibCarla/source/carla/trafficmanager/CollisionStage.cpp index 37cdc2b69..2151158e8 100644 --- a/LibCarla/source/carla/trafficmanager/CollisionStage.cpp +++ b/LibCarla/source/carla/trafficmanager/CollisionStage.cpp @@ -22,14 +22,16 @@ CollisionStage::CollisionStage( const TrackTraffic &track_traffic, const Parameters ¶meters, 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 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::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 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(); diff --git a/LibCarla/source/carla/trafficmanager/CollisionStage.h b/LibCarla/source/carla/trafficmanager/CollisionStage.h index f3c9b31d8..511803259 100644 --- a/LibCarla/source/carla/trafficmanager/CollisionStage.h +++ b/LibCarla/source/carla/trafficmanager/CollisionStage.h @@ -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 NegotiateCollision(const ActorId reference_vehicle_id, @@ -93,7 +93,8 @@ public: const TrackTraffic &track_traffic, const Parameters ¶meters, CollisionFrame &output_array, - cc::DebugHelper& debug_helper); + cc::DebugHelper& debug_helper, + RandomGeneratorMap &random_devices); void Update (const unsigned long index) override; diff --git a/LibCarla/source/carla/trafficmanager/Constants.h b/LibCarla/source/carla/trafficmanager/Constants.h index 4e6fca74a..d53cdfc08 100644 --- a/LibCarla/source/carla/trafficmanager/Constants.h +++ b/LibCarla/source/carla/trafficmanager/Constants.h @@ -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::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 diff --git a/LibCarla/source/carla/trafficmanager/DataStructures.h b/LibCarla/source/carla/trafficmanager/DataStructures.h index 9e11d6635..5f604ff42 100644 --- a/LibCarla/source/carla/trafficmanager/DataStructures.h +++ b/LibCarla/source/carla/trafficmanager/DataStructures.h @@ -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; diff --git a/LibCarla/source/carla/trafficmanager/LocalizationStage.cpp b/LibCarla/source/carla/trafficmanager/LocalizationStage.cpp index ac01d6702..fa1c5ea0b 100644 --- a/LibCarla/source/carla/trafficmanager/LocalizationStage.cpp +++ b/LibCarla/source/carla/trafficmanager/LocalizationStage.cpp @@ -17,16 +17,20 @@ LocalizationStage::LocalizationStage( TrackTraffic &track_traffic, const LocalMapPtr &local_map, Parameters ¶meters, + std::vector& 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 next_waypoints = waypoint_buffer.back()->GetNextWaypoint(); + SimpleWaypointPtr furthest_waypoint = waypoint_buffer.back(); + std::vector 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(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(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); diff --git a/LibCarla/source/carla/trafficmanager/LocalizationStage.h b/LibCarla/source/carla/trafficmanager/LocalizationStage.h index e3ada46ea..042f7218e 100644 --- a/LibCarla/source/carla/trafficmanager/LocalizationStage.h +++ b/LibCarla/source/carla/trafficmanager/LocalizationStage.h @@ -34,13 +34,15 @@ private: TrackTraffic &track_traffic; const LocalMapPtr &local_map; Parameters ¶meters; + // Array of vehicles marked by stages for removal. + std::vector& marked_for_removal; LocalizationFrame &output_array; cc::DebugHelper &debug_helper; LaneChangeLocationMap last_lane_change_location; ActorIdSet vehicles_at_junction; using SimpleWaypointPair = std::pair; std::unordered_map 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 ¶meters, + std::vector& marked_for_removal, LocalizationFrame &output_array, - cc::DebugHelper &debug_helper); + cc::DebugHelper &debug_helper, + RandomGeneratorMap &random_devices); void Update(const unsigned long index) override; diff --git a/LibCarla/source/carla/trafficmanager/LocalizationUtils.cpp b/LibCarla/source/carla/trafficmanager/LocalizationUtils.cpp index cba56552a..8ced5c7c6 100644 --- a/LibCarla/source/carla/trafficmanager/LocalizationUtils.cpp +++ b/LibCarla/source/carla/trafficmanager/LocalizationUtils.cpp @@ -5,16 +5,19 @@ // For a copy, see . #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::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::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; } diff --git a/LibCarla/source/carla/trafficmanager/MotionPlanStage.cpp b/LibCarla/source/carla/trafficmanager/MotionPlanStage.cpp index bcb99d433..cda69919f 100644 --- a/LibCarla/source/carla/trafficmanager/MotionPlanStage.cpp +++ b/LibCarla/source/carla/trafficmanager/MotionPlanStage.cpp @@ -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 &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 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. diff --git a/LibCarla/source/carla/trafficmanager/MotionPlanStage.h b/LibCarla/source/carla/trafficmanager/MotionPlanStage.h index ace2de47e..9d6bb8fa1 100644 --- a/LibCarla/source/carla/trafficmanager/MotionPlanStage.h +++ b/LibCarla/source/carla/trafficmanager/MotionPlanStage.h @@ -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 pid_state_map; // Structure to keep track of duration between teleportation // in hybrid physics mode. - std::unordered_map teleportation_instance; + std::unordered_map teleportation_instance; ControlFrame &output_array; + cc::Timestamp current_timestamp; std::pair 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); diff --git a/LibCarla/source/carla/trafficmanager/PIDController.h b/LibCarla/source/carla/trafficmanager/PIDController.h index 20079dea7..1217cbfaf 100644 --- a/LibCarla/source/carla/trafficmanager/PIDController.h +++ b/LibCarla/source/carla/trafficmanager/PIDController.h @@ -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, diff --git a/LibCarla/source/carla/trafficmanager/Parameters.cpp b/LibCarla/source/carla/trafficmanager/Parameters.cpp index 397a22983..801ca6d91 100644 --- a/LibCarla/source/carla/trafficmanager/Parameters.cpp +++ b/LibCarla/source/carla/trafficmanager/Parameters.cpp @@ -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 diff --git a/LibCarla/source/carla/trafficmanager/Parameters.h b/LibCarla/source/carla/trafficmanager/Parameters.h index 7843bcba4..d017b2030 100644 --- a/LibCarla/source/carla/trafficmanager/Parameters.h +++ b/LibCarla/source/carla/trafficmanager/Parameters.h @@ -64,6 +64,8 @@ private: std::atomic hybrid_physics_mode{false}; /// Hybrid physics radius. std::atomic hybrid_physics_radius {70.0}; + /// Parameter specifying Open Street Map mode. + std::atomic 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 synchronous_time_out; }; diff --git a/LibCarla/source/carla/trafficmanager/RandomGenerator.h b/LibCarla/source/carla/trafficmanager/RandomGenerator.h index a01d93891..c3b23e3fb 100644 --- a/LibCarla/source/carla/trafficmanager/RandomGenerator.h +++ b/LibCarla/source/carla/trafficmanager/RandomGenerator.h @@ -1,20 +1,24 @@ + #pragma once #include +#include + +#include "carla/rpc/ActorId.h" namespace carla { namespace traffic_manager { -template::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 dist; + std::uniform_real_distribution dist; }; +using RandomGeneratorMap = std::unordered_map; + } // namespace traffic_manager } // namespace carla diff --git a/LibCarla/source/carla/trafficmanager/TrafficLightStage.cpp b/LibCarla/source/carla/trafficmanager/TrafficLightStage.cpp index d778f9a03..3d23fe5bd 100644 --- a/LibCarla/source/carla/trafficmanager/TrafficLightStage.cpp +++ b/LibCarla/source/carla/trafficmanager/TrafficLightStage.cpp @@ -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 ¶meters, - 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 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 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 ¤t_ticket = vehicle_last_ticket.at(ego_actor_id); - const chr::duration 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; } diff --git a/LibCarla/source/carla/trafficmanager/TrafficLightStage.h b/LibCarla/source/carla/trafficmanager/TrafficLightStage.h index 6f74a9e80..f3c19311d 100644 --- a/LibCarla/source/carla/trafficmanager/TrafficLightStage.h +++ b/LibCarla/source/carla/trafficmanager/TrafficLightStage.h @@ -18,24 +18,28 @@ private: const SimulationState &simulation_state; const BufferMap &buffer_map; const Parameters ¶meters; + const cc::World &world; /// Map containing the time ticket issued for vehicles. - std::unordered_map vehicle_last_ticket; + std::unordered_map vehicle_last_ticket; /// Map containing the previous time ticket issued for junctions. - std::unordered_map junction_last_ticket; + std::unordered_map junction_last_ticket; /// Map containing the previous junction visited by a vehicle. std::unordered_map 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 &vehicle_id_list, const SimulationState &Simulation_state, const BufferMap &buffer_map, const Parameters ¶meters, - TLFrame &output_array); + const cc::World &world, + TLFrame &output_array, + RandomGeneratorMap &random_devices); void Update(const unsigned long index) override; diff --git a/LibCarla/source/carla/trafficmanager/TrafficManager.h b/LibCarla/source/carla/trafficmanager/TrafficManager.h index 74c91a848..601f4883e 100644 --- a/LibCarla/source/carla/trafficmanager/TrafficManager.h +++ b/LibCarla/source/carla/trafficmanager/TrafficManager.h @@ -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 lock(_mutex); auto it = _tm_map.find(port); if (it != _tm_map.end()) { - _mutex.unlock(); return it->second; } return nullptr; diff --git a/LibCarla/source/carla/trafficmanager/TrafficManagerBase.h b/LibCarla/source/carla/trafficmanager/TrafficManagerBase.h index 587b226bb..cfabfb275 100644 --- a/LibCarla/source/carla/trafficmanager/TrafficManagerBase.h +++ b/LibCarla/source/carla/trafficmanager/TrafficManagerBase.h @@ -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: }; diff --git a/LibCarla/source/carla/trafficmanager/TrafficManagerClient.h b/LibCarla/source/carla/trafficmanager/TrafficManagerClient.h index bc161584b..0c38a323b 100644 --- a/LibCarla/source/carla/trafficmanager/TrafficManagerClient.h +++ b/LibCarla/source/carla/trafficmanager/TrafficManagerClient.h @@ -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. diff --git a/LibCarla/source/carla/trafficmanager/TrafficManagerLocal.cpp b/LibCarla/source/carla/trafficmanager/TrafficManagerLocal.cpp index 58bbd3374..d7bb1401e 100644 --- a/LibCarla/source/carla/trafficmanager/TrafficManagerLocal.cpp +++ b/LibCarla/source/carla/trafficmanager/TrafficManagerLocal.cpp @@ -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(this))) { @@ -123,7 +131,7 @@ void TrafficManagerLocal::Run() { // Wait for external trigger to initiate cycle in synchronous mode. if (synchronous_mode) { std::unique_lock 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 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(time_to_wait)); + chr::duration time_to_wait = chr::duration(HYBRID_MODE_DT) - elapsed_time; + if (time_to_wait > chr::duration(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 &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 &actor_list) { std::vector 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 list_of_all_groups; - TLGroup tl_to_freeze; std::vector 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(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 TrafficManagerLocal::GetRegisteredVehiclesIDs() { return registered_vehicles.GetIDList(); } +void TrafficManagerLocal::SetRandomDeviceSeed(const uint64_t _seed) { + seed = _seed; + ResetAllTrafficLights(); +} + } // namespace traffic_manager } // namespace carla diff --git a/LibCarla/source/carla/trafficmanager/TrafficManagerLocal.h b/LibCarla/source/carla/trafficmanager/TrafficManagerLocal.h index 9f376b81a..65324e0f8 100644 --- a/LibCarla/source/carla/trafficmanager/TrafficManagerLocal.h +++ b/LibCarla/source/carla/trafficmanager/TrafficManagerLocal.h @@ -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 worker_thread; + /// Structure holding random devices per vehicle. + RandomGeneratorMap random_devices; + /// Randomization seed. + uint64_t seed {static_cast(time(NULL))}; + std::vector 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 &actor_list); /// This method unregisters a vehicle from traffic manager. - void UnregisterVehicles(const std::vector &actor_list); + void UnregisterVehicles(const std::vector &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 diff --git a/LibCarla/source/carla/trafficmanager/TrafficManagerRemote.cpp b/LibCarla/source/carla/trafficmanager/TrafficManagerRemote.cpp index ac3fad8a1..168a554d7 100644 --- a/LibCarla/source/carla/trafficmanager/TrafficManagerRemote.cpp +++ b/LibCarla/source/carla/trafficmanager/TrafficManagerRemote.cpp @@ -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 diff --git a/LibCarla/source/carla/trafficmanager/TrafficManagerRemote.h b/LibCarla/source/carla/trafficmanager/TrafficManagerRemote.h index ac3023b91..790218b4b 100644 --- a/LibCarla/source/carla/trafficmanager/TrafficManagerRemote.h +++ b/LibCarla/source/carla/trafficmanager/TrafficManagerRemote.h @@ -102,6 +102,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); + /// Method to provide synchronous tick bool SynchronousTick(); @@ -114,6 +117,9 @@ public: /// Method to check server is alive or not. void HealthCheckRemoteTM(); + /// Method to set randomization seed. + void SetRandomDeviceSeed(const uint64_t seed); + private: /// Remote client using the IP and port information it connects to diff --git a/LibCarla/source/carla/trafficmanager/TrafficManagerServer.h b/LibCarla/source/carla/trafficmanager/TrafficManagerServer.h index 5f7ed1a00..67f113b81 100644 --- a/LibCarla/source/carla/trafficmanager/TrafficManagerServer.h +++ b/LibCarla/source/carla/trafficmanager/TrafficManagerServer.h @@ -163,6 +163,11 @@ public: tm->SetHybridPhysicsRadius(radius); }); + /// Method to set hybrid physics radius. + server->bind("set_osm_mode", [=](const bool mode_switch) { + tm->SetHybridPhysicsRadius(mode_switch); + }); + /// Method to set synchronous mode. server->bind("set_synchronous_mode", [=](const bool mode) { tm->SetSynchronousMode(mode); @@ -173,6 +178,11 @@ public: tm->SetSynchronousModeTimeOutInMiliSecond(time); }); + /// Method to set randomization seed. + server->bind("set_random_device_seed", [=](const uint64_t seed) { + tm->SetRandomDeviceSeed(seed); + }); + /// Method to provide synchronous tick. server->bind("synchronous_tick", [=]() -> bool { return tm->SynchronousTick(); diff --git a/LibCarla/source/test/server/test_benchmark_streaming.cpp b/LibCarla/source/test/server/test_benchmark_streaming.cpp index 1ca293767..f1f55087d 100644 --- a/LibCarla/source/test/server/test_benchmark_streaming.cpp +++ b/LibCarla/source/test/server/test_benchmark_streaming.cpp @@ -9,6 +9,8 @@ #include #include +#include + #include using namespace carla::streaming; @@ -38,7 +40,7 @@ public: _client.Subscribe(stream.token(), [this](carla::Buffer DEBUG_ONLY(msg)) { DEBUG_ASSERT_EQ(msg.size(), _message.size()); DEBUG_ASSERT(msg == _message); - _client_callback.post([this]() { + boost::asio::post(_client_callback, [this]() { CARLA_PROFILE_FPS(client, listen_callback); ++_number_of_messages_received; }); diff --git a/PythonAPI/carla/agents/navigation/behavior_agent.py b/PythonAPI/carla/agents/navigation/behavior_agent.py index 8a5b19490..0a26b4e19 100644 --- a/PythonAPI/carla/agents/navigation/behavior_agent.py +++ b/PythonAPI/carla/agents/navigation/behavior_agent.py @@ -118,7 +118,7 @@ class BehaviorAgent(Agent): route_trace = self._trace_route(self.start_waypoint, self.end_waypoint) - self._local_planner.set_global_plan(route_trace) + self._local_planner.set_global_plan(route_trace, clean) def reroute(self, spawn_points): """ diff --git a/PythonAPI/carla/agents/navigation/local_planner.py b/PythonAPI/carla/agents/navigation/local_planner.py index a02a2040c..101d382b6 100644 --- a/PythonAPI/carla/agents/navigation/local_planner.py +++ b/PythonAPI/carla/agents/navigation/local_planner.py @@ -191,10 +191,29 @@ class LocalPlanner(object): self._waypoints_queue.append((next_waypoint, road_option)) def set_global_plan(self, current_plan): + """ + Resets the waypoint queue and buffer to match the new plan. Also + sets the global_plan flag to avoid creating more waypoints + + :param current_plan: list of (carla.Waypoint, RoadOption) + :return: + """ + + # Reset the queue self._waypoints_queue.clear() for elem in current_plan: self._waypoints_queue.append(elem) self._target_road_option = RoadOption.LANEFOLLOW + + # and the buffer + self._waypoint_buffer.clear() + for _ in range(self._buffer_size): + if self._waypoints_queue: + self._waypoint_buffer.append( + self._waypoints_queue.popleft()) + else: + break + self._global_plan = True def run_step(self, debug=False): @@ -203,7 +222,7 @@ class LocalPlanner(object): follow the waypoints trajectory. :param debug: boolean flag to activate waypoints debugging - :return: + :return: control to be applied """ # not enough waypoints in the horizon? => add more! @@ -222,7 +241,7 @@ class LocalPlanner(object): # Buffering the waypoints if not self._waypoint_buffer: - for i in range(self._buffer_size): + for _ in range(self._buffer_size): if self._waypoints_queue: self._waypoint_buffer.append( self._waypoints_queue.popleft()) @@ -253,6 +272,11 @@ class LocalPlanner(object): return control def done(self): + """ + Returns whether or not the planner has finished + + :return: boolean + """ return len(self._waypoints_queue) == 0 and len(self._waypoint_buffer) == 0 def _retrieve_options(list_waypoints, current_waypoint): diff --git a/PythonAPI/carla/agents/navigation/local_planner_behavior.py b/PythonAPI/carla/agents/navigation/local_planner_behavior.py index 85944825e..86a6d6b78 100644 --- a/PythonAPI/carla/agents/navigation/local_planner_behavior.py +++ b/PythonAPI/carla/agents/navigation/local_planner_behavior.py @@ -135,7 +135,7 @@ class LocalPlanner(object): self._target_speed = speed - def set_global_plan(self, current_plan): + def set_global_plan(self, current_plan, clean=False): """ Sets new global plan. @@ -143,6 +143,16 @@ class LocalPlanner(object): """ for elem in current_plan: self.waypoints_queue.append(elem) + + if clean: + self._waypoint_buffer.clear() + for _ in range(self._buffer_size): + if self.waypoints_queue: + self._waypoint_buffer.append( + self.waypoints_queue.popleft()) + else: + break + self._global_plan = True def get_incoming_waypoint_and_direction(self, steps=3): diff --git a/PythonAPI/carla/source/libcarla/Actor.cpp b/PythonAPI/carla/source/libcarla/Actor.cpp index 8cbfe61d0..efe97a0ab 100644 --- a/PythonAPI/carla/source/libcarla/Actor.cpp +++ b/PythonAPI/carla/source/libcarla/Actor.cpp @@ -37,6 +37,16 @@ static auto GetSemanticTags(const carla::client::Actor &self) { return boost::python::list(iter); } +static void AddActorImpulse(carla::client::Actor &self, + const carla::geom::Vector3D &impulse) { + self.AddImpulse(impulse); +} + +static void AddActorForce(carla::client::Actor &self, + const carla::geom::Vector3D &force) { + self.AddForce(force); +} + static auto GetGroupTrafficLights(carla::client::TrafficLight &self) { namespace py = boost::python; auto values = self.GetGroupTrafficLights(); @@ -85,10 +95,14 @@ void export_actor() { .def("get_acceleration", &cc::Actor::GetAcceleration) .def("set_location", &cc::Actor::SetLocation, (arg("location"))) .def("set_transform", &cc::Actor::SetTransform, (arg("transform"))) - .def("set_velocity", &cc::Actor::SetVelocity, (arg("vector"))) - .def("set_angular_velocity", &cc::Actor::SetAngularVelocity, (arg("vector"))) - .def("add_impulse", &cc::Actor::AddImpulse, (arg("vector"))) - .def("add_angular_impulse", &cc::Actor::AddAngularImpulse, (arg("vector"))) + .def("set_target_velocity", &cc::Actor::SetTargetVelocity, (arg("velocity"))) + .def("set_target_angular_velocity", &cc::Actor::SetTargetAngularVelocity, (arg("angular_velocity"))) + .def("enable_constant_velocity", &cc::Actor::EnableConstantVelocity, (arg("velocity"))) + .def("disable_constant_velocity", &cc::Actor::DisableConstantVelocity) + .def("add_impulse", &AddActorImpulse, (arg("impulse"))) + .def("add_force", &AddActorForce, (arg("force"))) + .def("add_angular_impulse", &cc::Actor::AddAngularImpulse, (arg("angular_impulse"))) + .def("add_torque", &cc::Actor::AddTorque, (arg("torque"))) .def("set_simulate_physics", &cc::Actor::SetSimulatePhysics, (arg("enabled") = true)) .def("destroy", CALL_WITHOUT_GIL(cc::Actor, Destroy)) .def(self_ns::str(self_ns::self)) diff --git a/PythonAPI/carla/source/libcarla/AdRss.cpp b/PythonAPI/carla/source/libcarla/AdRss.cpp index e095063e2..d18ff1b53 100644 --- a/PythonAPI/carla/source/libcarla/AdRss.cpp +++ b/PythonAPI/carla/source/libcarla/AdRss.cpp @@ -200,6 +200,7 @@ void export_ad_rss() { .def("reset_routing_targets", &cc::RssSensor::ResetRoutingTargets) .def("drop_route", &cc::RssSensor::DropRoute) .def("set_log_level", &cc::RssSensor::SetLogLevel, (arg("log_level"))) + .def("set_map_log_level", &cc::RssSensor::SetMapLogLevel, (arg("map_log_level"))) .def(self_ns::str(self_ns::self)); class_>("RssRestrictor", diff --git a/PythonAPI/carla/source/libcarla/Commands.cpp b/PythonAPI/carla/source/libcarla/Commands.cpp index d9662ade9..2edd79387 100644 --- a/PythonAPI/carla/source/libcarla/Commands.cpp +++ b/PythonAPI/carla/source/libcarla/Commands.cpp @@ -123,18 +123,18 @@ void export_commands() { .def_readwrite("speed", &cr::Command::ApplyWalkerState::speed) ; - class_("ApplyVelocity") + class_("ApplyTargetVelocity") .def("__init__", &command_impl::CustomInit, (arg("actor"), arg("velocity"))) .def(init((arg("actor_id"), arg("velocity")))) - .def_readwrite("actor_id", &cr::Command::ApplyVelocity::actor) - .def_readwrite("velocity", &cr::Command::ApplyVelocity::velocity) + .def_readwrite("actor_id", &cr::Command::ApplyTargetVelocity::actor) + .def_readwrite("velocity", &cr::Command::ApplyTargetVelocity::velocity) ; - class_("ApplyAngularVelocity") + class_("ApplyTargetAngularVelocity") .def("__init__", &command_impl::CustomInit, (arg("actor"), arg("angular_velocity"))) .def(init((arg("actor_id"), arg("angular_velocity")))) - .def_readwrite("actor_id", &cr::Command::ApplyAngularVelocity::actor) - .def_readwrite("angular_velocity", &cr::Command::ApplyAngularVelocity::angular_velocity) + .def_readwrite("actor_id", &cr::Command::ApplyTargetAngularVelocity::actor) + .def_readwrite("angular_velocity", &cr::Command::ApplyTargetAngularVelocity::angular_velocity) ; class_("ApplyImpulse") @@ -144,6 +144,13 @@ void export_commands() { .def_readwrite("impulse", &cr::Command::ApplyImpulse::impulse) ; + class_("ApplyForce") + .def("__init__", &command_impl::CustomInit, (arg("actor"), arg("force"))) + .def(init((arg("actor_id"), arg("force")))) + .def_readwrite("actor_id", &cr::Command::ApplyForce::actor) + .def_readwrite("force", &cr::Command::ApplyForce::force) + ; + class_("ApplyAngularImpulse") .def("__init__", &command_impl::CustomInit, (arg("actor"), arg("impulse"))) .def(init((arg("actor_id"), arg("impulse")))) @@ -151,6 +158,13 @@ void export_commands() { .def_readwrite("impulse", &cr::Command::ApplyAngularImpulse::impulse) ; + class_("ApplyTorque") + .def("__init__", &command_impl::CustomInit, (arg("actor"), arg("torque"))) + .def(init((arg("actor_id"), arg("torque")))) + .def_readwrite("actor_id", &cr::Command::ApplyTorque::actor) + .def_readwrite("torque", &cr::Command::ApplyTorque::torque) + ; + class_("SetSimulatePhysics") .def("__init__", &command_impl::CustomInit, (arg("actor"), arg("enabled"))) .def(init((arg("actor_id"), arg("enabled")))) @@ -179,10 +193,12 @@ void export_commands() { implicitly_convertible(); implicitly_convertible(); implicitly_convertible(); - implicitly_convertible(); - implicitly_convertible(); + implicitly_convertible(); + implicitly_convertible(); implicitly_convertible(); + implicitly_convertible(); implicitly_convertible(); + implicitly_convertible(); implicitly_convertible(); implicitly_convertible(); implicitly_convertible(); diff --git a/PythonAPI/carla/source/libcarla/Geom.cpp b/PythonAPI/carla/source/libcarla/Geom.cpp index 333d98ed3..05044d85f 100644 --- a/PythonAPI/carla/source/libcarla/Geom.cpp +++ b/PythonAPI/carla/source/libcarla/Geom.cpp @@ -65,6 +65,7 @@ namespace geom { std::ostream &operator<<(std::ostream &out, const BoundingBox &box) { out << "BoundingBox(" << box.location << ", "; WriteVector3D(out, "Extent", box.extent); + out << ", " << box.rotation; out << ')'; return out; } @@ -205,9 +206,10 @@ void export_geom() { class_("BoundingBox") .def(init( - (arg("location")=cg::Location(), arg("extent")=cg::Vector3D()))) + (arg("location")=cg::Location(), arg("extent")=cg::Vector3D(), arg("rotation")=cg::Rotation()))) .def_readwrite("location", &cg::BoundingBox::location) .def_readwrite("extent", &cg::BoundingBox::extent) + .def_readwrite("rotation", &cg::BoundingBox::rotation) .def("contains", &cg::BoundingBox::Contains, arg("point"), arg("bbox_transform")) .def("get_local_vertices", CALL_RETURNING_LIST(cg::BoundingBox, GetLocalVertices)) .def("get_world_vertices", CALL_RETURNING_LIST_1(cg::BoundingBox, GetWorldVertices, const cg::Transform&), arg("bbox_transform")) diff --git a/PythonAPI/carla/source/libcarla/TrafficManager.cpp b/PythonAPI/carla/source/libcarla/TrafficManager.cpp index 586211d94..204c9842f 100644 --- a/PythonAPI/carla/source/libcarla/TrafficManager.cpp +++ b/PythonAPI/carla/source/libcarla/TrafficManager.cpp @@ -13,25 +13,28 @@ #include "carla/trafficmanager/TrafficManager.h" void export_trafficmanager() { - namespace cc = carla::client; - using namespace boost::python; + namespace cc = carla::client; + namespace ctm = carla::traffic_manager; + using namespace boost::python; - class_("TrafficManager", no_init) - .def("get_port", &carla::traffic_manager::TrafficManager::Port) - .def("vehicle_percentage_speed_difference", &carla::traffic_manager::TrafficManager::SetPercentageSpeedDifference) - .def("global_percentage_speed_difference", &carla::traffic_manager::TrafficManager::SetGlobalPercentageSpeedDifference) - .def("collision_detection", &carla::traffic_manager::TrafficManager::SetCollisionDetection) - .def("force_lane_change", &carla::traffic_manager::TrafficManager::SetForceLaneChange) - .def("auto_lane_change", &carla::traffic_manager::TrafficManager::SetAutoLaneChange) - .def("distance_to_leading_vehicle", &carla::traffic_manager::TrafficManager::SetDistanceToLeadingVehicle) - .def("reset_traffic_lights", &carla::traffic_manager::TrafficManager::ResetAllTrafficLights) - .def("ignore_walkers_percentage", &carla::traffic_manager::TrafficManager::SetPercentageIgnoreWalkers) - .def("ignore_vehicles_percentage", &carla::traffic_manager::TrafficManager::SetPercentageIgnoreVehicles) - .def("ignore_lights_percentage", &carla::traffic_manager::TrafficManager::SetPercentageRunningLight) - .def("ignore_signs_percentage", &carla::traffic_manager::TrafficManager::SetPercentageRunningSign) - .def("set_global_distance_to_leading_vehicle", &carla::traffic_manager::TrafficManager::SetGlobalDistanceToLeadingVehicle) - .def("set_percentage_keep_right_rule", &carla::traffic_manager::TrafficManager::SetKeepRightPercentage) - .def("set_synchronous_mode", &carla::traffic_manager::TrafficManager::SetSynchronousMode) - .def("set_hybrid_physics_mode", &carla::traffic_manager::TrafficManager::SetHybridPhysicsMode) - .def("set_hybrid_physics_radius", &carla::traffic_manager::TrafficManager::SetHybridPhysicsRadius); + class_("TrafficManager", no_init) + .def("get_port", &ctm::TrafficManager::Port) + .def("vehicle_percentage_speed_difference", &ctm::TrafficManager::SetPercentageSpeedDifference) + .def("global_percentage_speed_difference", &ctm::TrafficManager::SetGlobalPercentageSpeedDifference) + .def("collision_detection", &ctm::TrafficManager::SetCollisionDetection) + .def("force_lane_change", &ctm::TrafficManager::SetForceLaneChange) + .def("auto_lane_change", &ctm::TrafficManager::SetAutoLaneChange) + .def("distance_to_leading_vehicle", &ctm::TrafficManager::SetDistanceToLeadingVehicle) + .def("reset_traffic_lights", &ctm::TrafficManager::ResetAllTrafficLights) + .def("ignore_walkers_percentage", &ctm::TrafficManager::SetPercentageIgnoreWalkers) + .def("ignore_vehicles_percentage", &ctm::TrafficManager::SetPercentageIgnoreVehicles) + .def("ignore_lights_percentage", &ctm::TrafficManager::SetPercentageRunningLight) + .def("ignore_signs_percentage", &ctm::TrafficManager::SetPercentageRunningSign) + .def("set_global_distance_to_leading_vehicle", &ctm::TrafficManager::SetGlobalDistanceToLeadingVehicle) + .def("set_percentage_keep_right_rule", &ctm::TrafficManager::SetKeepRightPercentage) + .def("set_synchronous_mode", &ctm::TrafficManager::SetSynchronousMode) + .def("set_hybrid_physics_mode", &ctm::TrafficManager::SetHybridPhysicsMode) + .def("set_hybrid_physics_radius", &ctm::TrafficManager::SetHybridPhysicsRadius) + .def("set_random_device_seed", &ctm::TrafficManager::SetRandomDeviceSeed) + .def("set_osm_mode", &carla::traffic_manager::TrafficManager::SetOSMMode); } diff --git a/PythonAPI/carla/source/libcarla/World.cpp b/PythonAPI/carla/source/libcarla/World.cpp index c5edf6d1b..d5ca4df28 100644 --- a/PythonAPI/carla/source/libcarla/World.cpp +++ b/PythonAPI/carla/source/libcarla/World.cpp @@ -8,6 +8,7 @@ #include #include #include +#include #include @@ -70,6 +71,15 @@ static auto GetVehiclesLightStates(carla::client::World &self) { return dict; } +static auto GetLevelBBs(const carla::client::World &self, uint8_t queried_tag) { + carla::PythonUtil::ReleaseGIL unlock; + boost::python::list result; + for (const auto &bb : self.GetLevelBBs(queried_tag)) { + result.append(bb); + } + return result; +} + void export_world() { using namespace boost::python; namespace cc = carla::client; @@ -126,6 +136,32 @@ void export_world() { .value("SpringArm", cr::AttachmentType::SpringArm) ; + enum_("CityObjectLabel") + .value("Any", cr::CityObjectLabel::None) + .value("Buildings", cr::CityObjectLabel::Buildings) + .value("Fences", cr::CityObjectLabel::Fences) + .value("Other", cr::CityObjectLabel::Other) + .value("Pedestrians", cr::CityObjectLabel::Pedestrians) + .value("Poles", cr::CityObjectLabel::Poles) + .value("RoadLines", cr::CityObjectLabel::RoadLines) + .value("Roads", cr::CityObjectLabel::Roads) + .value("Sidewalks", cr::CityObjectLabel::Sidewalks) + .value("TrafficSigns", cr::CityObjectLabel::TrafficSigns) + .value("Vegetation", cr::CityObjectLabel::Vegetation) + .value("Vehicles", cr::CityObjectLabel::Vehicles) + .value("Walls", cr::CityObjectLabel::Walls) + .value("Sky", cr::CityObjectLabel::Sky) + .value("Ground", cr::CityObjectLabel::Ground) + .value("Bridge", cr::CityObjectLabel::Bridge) + .value("RailTrack", cr::CityObjectLabel::RailTrack) + .value("GuardRail", cr::CityObjectLabel::GuardRail) + .value("TrafficLight", cr::CityObjectLabel::TrafficLight) + .value("Static", cr::CityObjectLabel::Static) + .value("Dynamic", cr::CityObjectLabel::Dynamic) + .value("Water", cr::CityObjectLabel::Water) + .value("Terrain", cr::CityObjectLabel::Terrain) + ; + #define SPAWN_ACTOR_WITHOUT_GIL(fn) +[]( \ cc::World &self, \ const cc::ActorBlueprint &blueprint, \ @@ -166,8 +202,10 @@ void export_world() { .def("set_pedestrians_cross_factor", CALL_WITHOUT_GIL_1(cc::World, SetPedestriansCrossFactor, float), (arg("percentage"))) .def("get_traffic_sign", CONST_CALL_WITHOUT_GIL_1(cc::World, GetTrafficSign, cc::Landmark), arg("landmark")) .def("get_traffic_light", CONST_CALL_WITHOUT_GIL_1(cc::World, GetTrafficLight, cc::Landmark), arg("landmark")) + .def("reset_all_traffic_lights", &cc::World::ResetAllTrafficLights) .def("get_lightmanager", CONST_CALL_WITHOUT_GIL(cc::World, GetLightManager)) .def("freeze_all_traffic_lights", &cc::World::FreezeAllTrafficLights, (arg("frozen"))) + .def("get_level_bbs", &GetLevelBBs, (arg("actor_type")=cr::CityObjectLabel::None)) .def(self_ns::str(self_ns::self)) ; diff --git a/PythonAPI/docs/actor.yml b/PythonAPI/docs/actor.yml index 93f873733..361b84ed6 100644 --- a/PythonAPI/docs/actor.yml +++ b/PythonAPI/docs/actor.yml @@ -27,27 +27,53 @@ - var_name: semantic_tags type: list(int) doc: > - A list of semantic tags provided by the blueprint listing components for this actor. E.g. a traffic light could be tagged with "pole" and "traffic light". These tags are used by the semantic segmentation sensor. Find more about this and other sensors [here](ref_sensors.md#semantic-segmentation-camera). + A list of semantic tags provided by the blueprint listing components for this actor. E.g. a traffic light could be tagged with `Pole` and `TrafficLight`. These tags are used by the semantic segmentation sensor. Find more about this and other sensors [here](ref_sensors.md#semantic-segmentation-camera). - var_name: type_id type: str doc: > - The identifier of the blueprint this actor was based on, e.g. "vehicle.ford.mustang". + The identifier of the blueprint this actor was based on, e.g. `vehicle.ford.mustang`. # - METHODS ---------------------------- methods: + - def_name: add_angular_impulse + params: + - param_name: angular_impulse + type: carla.Vector3D + param_units: degrees*s + doc: > + Angular impulse vector in global coordinates. + doc: > + Applies an angular impulse at the center of mass of the actor. This method should be used for instantaneous torques, usually applied once. Use __add_torque()__ to apply rotation forces over a period of time. + # -------------------------------------- + - def_name: add_force + params: + - param_name: force + type: carla.Vector3D + param_units: N + doc: > + Force vector in global coordinates. + doc: > + Applies a force at the center of mass of the actor. This method should be used for forces that are applied over a certain period of time. Use __add_impulse()__ to apply an impulse that only lasts an instant. + # -------------------------------------- - def_name: add_impulse params: - param_name: impulse type: carla.Vector3D + param_units: N*s + doc: > + Impulse vector in global coordinates. doc: > - Adds an impulse to the actor. The parameter `impulse` determines magnitude and global axis where it is applied. + Applies an impulse at the center of mass of the actor. This method should be used for instantaneous forces, usually applied once. Use __add_force()__ to apply forces over a period of time. # -------------------------------------- - - def_name: add_angular_impulse + - def_name: add_torque params: - - param_name: impulse + - param_name: torque type: carla.Vector3D + param_units: degrees + doc: > + Torque vector in global coordinates. doc: > - Adds an angular impulse to the actor. The parameter `impulse` determines magnitude and global axis where it is applied. + Applies a torque at the center of mass of the actor. This method should be used for torques that are applied over a certain period of time. Use __add_angular_impulse()__ to apply a torque that only lasts an instant. # -------------------------------------- - def_name: destroy return: bool @@ -56,18 +82,39 @@ warning: > This method blocks the script until the destruction is completed by the simulator. # -------------------------------------- + - def_name: disable_constant_velocity + doc: > + Disables any constant velocity previously set for a carla.Vehicle actor. + # -------------------------------------- + - def_name: enable_constant_velocity + params: + - param_name: velocity + type: carla.Vector3D + doc: > + Velocity vector in local space. + param_units: m/s + doc: > + Sets a vehicle's velocity vector to a constant value over time. The resulting velocity will be approximately the `velocity` being set, as with __set_target_velocity()__. + Note: > + Only carla.Vehicle actors can use this method. + warning: > + Enabling a constant velocity for a vehicle managed by the [Traffic Manager](https://carla.readthedocs.io/en/latest/adv_traffic_manager/) may cause conflicts. This method overrides any changes in velocity by the TM. + # -------------------------------------- - def_name: get_acceleration return: carla.Vector3D + return_units: m/s2 doc: > Returns the actor's 3D acceleration vector the client recieved during last tick. The method does not call the simulator. # -------------------------------------- - def_name: get_angular_velocity return: carla.Vector3D + return_units: rad/s doc: > Returns the actor's angular velocity vector the client recieved during last tick. The method does not call the simulator. # -------------------------------------- - def_name: get_location return: carla.Location + return_units: meters doc: > Returns the actor's location the client recieved during last tick. The method does not call the simulator. # -------------------------------------- @@ -78,6 +125,7 @@ # -------------------------------------- - def_name: get_velocity return: carla.Vector3D + return_units: m/s doc: > Returns the actor's velocity vector the client recieved during last tick. The method does not call the simulator. # -------------------------------------- @@ -86,17 +134,20 @@ doc: > Returns the world this actor belongs to. # -------------------------------------- - - def_name: set_angular_velocity + - def_name: set_target_angular_velocity params: - param_name: angular_velocity type: carla.Vector3D doc: > - Changes the actor's angular velocity vector. + Sets the actor's angular velocity vector. The modification will be effective two frames after the setting. Also, this is applied before the physics step so the resulting angular velocity will be affected by external forces at this frame such as friction. + note: > + The update will not be effective until two frames after it is set. # -------------------------------------- - def_name: set_location params: - param_name: location type: carla.Location + param_units: meters doc: > Teleports the actor to a given location. # -------------------------------------- @@ -115,12 +166,14 @@ doc: > Teleports the actor to a given transform (location and rotation). # -------------------------------------- - - def_name: set_velocity + - def_name: set_target_velocity params: - param_name: velocity type: carla.Vector3D doc: > - Sets the actor's velocity vector. + Sets the actor's velocity vector. The modification will be effective two frames after the setting. Also, this is applied before the physics step so the resulting velocity will be affected by external forces at this frame such as friction. + note: > + The update will not be effective until two frames after it is set. # -------------------------------------- - def_name: __str__ # -------------------------------------- @@ -167,7 +220,7 @@ - var_name: bounding_box type: carla.BoundingBox doc: > - The vehicle's collider volume. + Bounding box containing the geometry of the vehicle. Its location and rotation are relative to the vehicle it is attached to. # - METHODS ---------------------------- methods: - def_name: apply_control @@ -198,16 +251,17 @@ return: carla.VehicleLightState doc: > Returns a flag representing the vehicle light state, - this represents which lights are active or not + this represents which lights are active or not. # -------------------------------------- - def_name: get_physics_control return: carla.VehiclePhysicsControl doc: > The simulator returns the last physics control applied to this vehicle. - warning: This function does call the simulator to retrieve the value. + warning: This method does call the simulator to retrieve the value. # -------------------------------------- - def_name: get_speed_limit return: float + return_units: m/s doc: > The client returns the speed limit affecting this vehicle according to last tick (it does not call the simulator). The speed limit is updated when passing by a speed limit signal, so a vehicle might have none right after spawning. # -------------------------------------- @@ -255,7 +309,7 @@ - var_name: bounding_box type: carla.BoundingBox doc: > - The walker's collider defined by a bounding box. + Bounding box containing the geometry of the walker. Its location and rotation are relative to the walker it is attached to. # - METHODS ---------------------------- methods: - def_name: apply_control @@ -291,6 +345,7 @@ params: - param_name: destination type: carla.Location + param_units: meters doc: > Sets the destination that the pedestrian will reach. # -------------------------------------- @@ -307,8 +362,9 @@ - param_name: speed type: float default: 1.4 + param_units: m/s doc: > - speed in m/s. An easy walking speed is set by default. + An easy walking speed is set by default. doc: > Sets a speed for the walker in meters per second. # -------------------------------------- @@ -369,6 +425,7 @@ # -------------------------------------- - def_name: get_elapsed_time return: float + return_units: seconds doc: > The client returns the time in seconds since current light state started according to last tick. The method does not call the simulator. # -------------------------------------- @@ -377,13 +434,13 @@ doc: > Returns all traffic lights in the group this one belongs to. note: > - This function calls the simulator. + This method calls the simulator. # -------------------------------------- - def_name: reset_group doc: > Resets the state of the traffic lights of the group to the initial state at the start of the simulation. note: > - This function calls the simulator. + This method calls the simulator. # -------------------------------------- - def_name: get_pole_index return: int @@ -397,18 +454,21 @@ # -------------------------------------- - def_name: get_green_time return: float + return_units: seconds doc: > - The client returns the seconds set for the traffic light to be green according to last tick. The method does not call the simulator. + The client returns the time set for the traffic light to be green, according to last tick. The method does not call the simulator. # -------------------------------------- - def_name: get_red_time return: float + return_units: seconds doc: > - The client returns the seconds set for the traffic light to be red according to last tick. The method does not call the simulator. + The client returns the time set for the traffic light to be red, according to last tick. The method does not call the simulator. # -------------------------------------- - def_name: get_yellow_time return: float + return_units: seconds doc: > - The client returns the the seconds set for the traffic light to be yellow according to last tick. The method does not call the simulator. + The client returns the time set for the traffic light to be yellow, according to last tick. The method does not call the simulator. # -------------------------------------- - def_name: set_state params: @@ -421,22 +481,25 @@ params: - param_name: green_time type: float + param_units: seconds doc: > - Sets a given time (in seconds) for the green light to be active. + Sets a given time for the green light to be active. # -------------------------------------- - def_name: set_red_time params: - param_name: red_time type: float + param_units: seconds doc: > - Sets a given time (in seconds) for the red state to be active. + Sets a given time for the red state to be active. # -------------------------------------- - def_name: set_yellow_time params: - param_name: yellow_time type: float + param_units: seconds doc: > - Sets a given time (in seconds) for the yellow light to be active. + Sets a given time for the yellow light to be active. # -------------------------------------- - def_name: __str__ # -------------------------------------- diff --git a/PythonAPI/docs/client.yml b/PythonAPI/docs/client.yml index be27b385a..4b9c12861 100644 --- a/PythonAPI/docs/client.yml +++ b/PythonAPI/docs/client.yml @@ -42,7 +42,7 @@ doc: > A list of commands to execute in batch. Each command is different and has its own parameters. They appear listed at the bottom of this page. doc: > - Executes a list of commands on a single simulation step and retrieves no information. If you need information about the response of each command, use the **apply_batch_sync()** function right below this one. + Executes a list of commands on a single simulation step and retrieves no information. If you need information about the response of each command, use the __apply_batch_sync()__ method. [Here](https://github.com/carla-simulator/carla/blob/10c5f6a482a21abfd00220c68c7f12b4110b7f63/PythonAPI/examples/spawn_npc.py#L126) is an example on how to delete the actors that appear in carla.ActorList all at once. # -------------------------------------- - def_name: apply_batch_sync @@ -50,7 +50,7 @@ - param_name: commands type: list doc: > - A list of commands to execute in batch. The commands available are listed right above, in the function **apply_batch()**. + A list of commands to execute in batch. The commands available are listed right above, in the method **apply_batch()**. - param_name: due_tick_cue type: bool default: false @@ -102,12 +102,14 @@ Name of the file containing the information of the simulation. - param_name: start type: float + param_units: seconds doc: > - Time in seconds where to start playing the simulation. Negative is read as beginning from the end, being -10 just 10 seconds before the recording finished. + Time where to start playing the simulation. Negative is read as beginning from the end, being -10 just 10 seconds before the recording finished. - param_name: duration type: float + param_units: seconds doc: > - Time in seconds that will be reenacted using the information `name` file. If the end is reached, the simulation will continue. + Time that will be reenacted using the information `name` file. If the end is reached, the simulation will continue. - param_name: follow_id type: int doc: > @@ -133,12 +135,14 @@ Name of the recorded file to load - param_name: min_time type: float + param_units: seconds doc: > - Minimum time in seconds the actor has to move a minimum distance before being considered blocked. Default is 60 seconds. + Minimum time the actor has to move a minimum distance before being considered blocked. Default is 60 seconds. - param_name: min_distance type: float + param_units: centimeters doc: > - Minimum distance in centimeters the actor has to move to not be considered blocked. Default is 100 centimeters. + Minimum distance the actor has to move to not be considered blocked. Default is 100 centimeters. return: string doc: > The terminal will show the information registered for actors considered blocked. An actor is considered blocked when it does not move a minimum distance in a period of time, being these `min_distance` and `min_time`. @@ -259,10 +263,11 @@ params: - param_name: seconds type: float + param_units: seconds doc: > - New timeout value in seconds. Default is 5 seconds. + New timeout value. Default is 5 seconds. doc: > - Sets in seconds the maxixum time a network call is allowed before blocking it and raising a timeout exceeded error. + Sets the maxixum time a network call is allowed before blocking it and raising a timeout exceeded error. # -------------------------------------- - class_name: TrafficManager @@ -313,6 +318,7 @@ Vehicle whose minimum distance is being changed. - param_name: distance type: float + param_units: meters doc: > Meters between both vehicles. doc: > @@ -335,6 +341,7 @@ params: - param_name: distance type: float + param_units: meters doc: > Meters between vehicles. doc: > @@ -430,11 +437,22 @@ - param_name: r type: float default: 70.0 + param_units: meters doc: > New radius where physics are enabled. doc: > With hybrid physics on, changes the radius of the area of influence where physics are enabled. # -------------------------------------- + - def_name: set_osm_mode + params: + - param_name: mode_switch + type: bool + default: true + doc: > + If __True__, the OSM mode is enabled. + doc: > + Enables or disables the OSM mode. This mode allows the user to run TM in a map created with the [OSM feature](tuto_G_openstreetmap.md). These maps allow having dead-end streets. Normally, if vehicles cannot find the next waypoint, TM crashes. If OSM mode is enabled, it will show a warning, and destroy vehicles when necessary. + # -------------------------------------- - class_name: OpendriveGenerationParameters # - DESCRIPTION ------------------------ @@ -444,18 +462,22 @@ instance_variables: - var_name: vertex_distance type: float + param_units: meters doc: > Distance between vertices of the mesh generated. __Default is `2.0`__. - var_name: max_road_length type: float + param_units: meters doc: > Max road length for a single mesh portion. The mesh of the map is divided into portions, in order to avoid propagating issues. __Default is `50.0`__. - var_name: wall_height type: float + param_units: meters doc: > Height of walls created on the boundaries of the road. These prevent vehicles from falling off the road. __Default is `1.0`__. - var_name: additional_width type: float + param_units: meters doc: > Additional with applied junction lanes. Complex situations tend to occur at junctions, and a little increase can prevent vehicles from falling off the road. __Default is `0.6`__. - var_name: smooth_junctions diff --git a/PythonAPI/docs/commands.yml b/PythonAPI/docs/commands.yml index 78a606f66..f9edf58fe 100644 --- a/PythonAPI/docs/commands.yml +++ b/PythonAPI/docs/commands.yml @@ -6,7 +6,7 @@ # - DESCRIPTION ------------------------ doc: > States the result of executing a command as either the ID of the actor to whom the command was applied to (when succeeded) or an error string (when failed). - actor ID, depending on whether or not the command succeeded. The method **apply_batch_sync()** in carla.Client returns a list of these to summarize the execution of a batch. + actor ID, depending on whether or not the command succeeded. The method __apply_batch_sync()__ in carla.Client returns a list of these to summarize the execution of a batch. # - PROPERTIES ------------------------- instance_variables: - var_name: actor_id @@ -29,7 +29,7 @@ - class_name: SpawnActor # - DESCRIPTION ------------------------ doc: > - Command adaptation of **spawn_actor()** in carla.World. Spawns an actor into the world based on the blueprint provided and the transform. If a parent is provided, the actor is attached to it. + Command adaptation of __spawn_actor()__ in carla.World. Spawns an actor into the world based on the blueprint provided and the transform. If a parent is provided, the actor is attached to it. # - PROPERTIES ------------------------- instance_variables: - var_name: transform @@ -73,7 +73,7 @@ - class_name: DestroyActor # - DESCRIPTION ------------------------ doc: > - Command adaptation of **destroy()** in carla.Actor that tells the simulator to destroy this actor. It has no effect if the actor was already destroyed. When executed with **apply_batch_sync()** in carla.Client there will be a command.Response that will return a boolean stating whether the actor was successfully destroyed. + Command adaptation of __destroy()__ in carla.Actor that tells the simulator to destroy this actor. It has no effect if the actor was already destroyed. When executed with __apply_batch_sync()__ in carla.Client there will be a command.Response that will return a boolean stating whether the actor was successfully destroyed. # - PROPERTIES ------------------------- instance_variables: - var_name: actor_id @@ -93,7 +93,7 @@ - class_name: ApplyVehicleControl # - DESCRIPTION ------------------------ doc: > - Command adaptation of **apply_control()** in carla.Vehicle. Applies a certain control to a vehicle. + Command adaptation of __apply_control()__ in carla.Vehicle. Applies a certain control to a vehicle. # - PROPERTIES ------------------------- instance_variables: - var_name: actor_id @@ -115,11 +115,11 @@ - param_name: control type: carla.VehicleControl # -------------------------------------- - + - class_name: ApplyWalkerControl # - DESCRIPTION ------------------------ doc: > - Command adaptation of **apply_control()** in carla.Walker. Applies a control to a walker. + Command adaptation of __apply_control()__ in carla.Walker. Applies a control to a walker. # - PROPERTIES ------------------------- instance_variables: - var_name: actor_id @@ -145,7 +145,7 @@ - class_name: ApplyTransform # - DESCRIPTION ------------------------ doc: > - Command adaptation of **set_transform()** in carla.Actor. Sets a new transform to an actor. + Command adaptation of __set_transform()__ in carla.Actor. Sets a new transform to an actor. # - PROPERTIES ------------------------- instance_variables: - var_name: actor_id @@ -184,6 +184,7 @@ Transform to be applied. - var_name: speed type: float + var_units: m/s doc: > Speed to be applied. # - METHODS ---------------------------- @@ -198,12 +199,13 @@ type: carla.Transform - param_name: speed type: float + param_units: m/s # -------------------------------------- - - class_name: ApplyVelocity + - class_name: ApplyTargetVelocity # - DESCRIPTION ------------------------ doc: > - Command adaptation of **set_velocity()** in carla.Actor. Sets an actor's velocity. + Command adaptation of __set_target_velocity()__ in carla.Actor. # - PROPERTIES ------------------------- instance_variables: - var_name: actor_id @@ -212,6 +214,7 @@ Actor affected by the command. - var_name: velocity type: carla.Vector3D + var_units: m/s doc: > The 3D velocity applied to the actor. # - METHODS ---------------------------- @@ -224,12 +227,15 @@ Actor or its ID to whom the command will be applied to. - param_name: velocity type: carla.Vector3D + param_units: m/s + doc: > + Velocity vector applied to the actor. # -------------------------------------- - - class_name: ApplyAngularVelocity + - class_name: ApplyTargetAngularVelocity # - DESCRIPTION ------------------------ doc: > - Command adaptation of **set_angular_velocity()** in carla.Actor. Sets an actor's angular velocity. + Command adaptation of __set_target_angular_velocity()__ in carla.Actor. Sets the actor's angular velocity vector. # - PROPERTIES ------------------------- instance_variables: - var_name: actor_id @@ -238,6 +244,7 @@ Actor affected by the command. - var_name: angular_velocity type: carla.Vector3D + var_units: deg/s doc: > The 3D angular velocity that will be applied to the actor. # - METHODS ---------------------------- @@ -250,12 +257,15 @@ Actor or its ID to whom the command will be applied to. - param_name: angular_velocity type: carla.Vector3D + param_units: deg/s + doc: > + Angular velocity vector applied to the actor. # -------------------------------------- - class_name: ApplyImpulse # - DESCRIPTION ------------------------ doc: > - Command adaptation of **add_impulse()** in carla.Actor. Adds impulse to an actor. + Command adaptation of __add_impulse()__ in carla.Actor. Applies an impulse to an actor. # - PROPERTIES ------------------------- instance_variables: - var_name: actor_id @@ -264,6 +274,7 @@ Actor affected by the command. - var_name: impulse type: carla.Vector3D + var_units: N*s doc: > Impulse applied to the actor. # - METHODS ---------------------------- @@ -276,22 +287,52 @@ Actor or its ID to whom the command will be applied to. - param_name: impulse type: carla.Vector3D + param_units: N*s # -------------------------------------- - - class_name: ApplyAngularImpulse + - class_name: ApplyForce # - DESCRIPTION ------------------------ doc: > - Command adaptation of **add_angular_impulse()** in carla.Actor. Adds angular impulse to an actor. + Command adaptation of __add_force()__ in carla.Actor. Applies a force to an actor. # - PROPERTIES ------------------------- instance_variables: - var_name: actor_id type: int doc: > Actor affected by the command. - - var_name: impulse + - var_name: force type: carla.Vector3D doc: > - Angular impulse applied to the actor. Determines magnitude and global axis where it is applied. + Force applied to the actor over time. + var_units: N + # - METHODS ---------------------------- + methods: + - def_name: __init__ + params: + - param_name: actor + type: carla.Actor or int + doc: > + Actor or its ID to whom the command will be applied to. + - param_name: force + type: carla.Vector3D + param_units: N + # -------------------------------------- + + - class_name: ApplyAngularImpulse + # - DESCRIPTION ------------------------ + doc: > + Command adaptation of __add_angular_impulse()__ in carla.Actor. Applies an angular impulse to an actor. + # - PROPERTIES ------------------------- + instance_variables: + - var_name: actor_id + type: int + doc: > + Actor affected by the command. + - var_name: impulse + type: carla.Vector3D + var_units: degrees*s + doc: > + Angular impulse applied to the actor. # - METHODS ---------------------------- methods: - def_name: __init__ @@ -302,12 +343,41 @@ Actor or its ID to whom the command will be applied to. - param_name: impulse type: carla.Vector3D + param_units: degrees*s + # -------------------------------------- + + - class_name: ApplyTorque + # - DESCRIPTION ------------------------ + doc: > + Command adaptation of __add_torque()__ in carla.Actor. Applies a torque to an actor. + # - PROPERTIES ------------------------- + instance_variables: + - var_name: actor_id + type: int + doc: > + Actor affected by the command. + - var_name: torque + type: carla.Vector3D + doc: > + Torque applied to the actor over time. + var_units: degrees + # - METHODS ---------------------------- + methods: + - def_name: __init__ + params: + - param_name: actor + type: carla.Actor or int + doc: > + Actor or its ID to whom the command will be applied to. + - param_name: torque + type: carla.Vector3D + param_units: degrees # -------------------------------------- - class_name: SetSimulatePhysics # - DESCRIPTION ------------------------ doc: > - Command adaptation of **set_simulate_physics()** in carla.Actor. Determines whether an actor will be affected by physics or not. + Command adaptation of __set_simulate_physics()__ in carla.Actor. Determines whether an actor will be affected by physics or not. # - PROPERTIES ------------------------- instance_variables: - var_name: actor_id @@ -333,7 +403,7 @@ - class_name: SetAutopilot # - DESCRIPTION ------------------------ doc: > - Command adaptation of **set_autopilot()** in carla.Vehicle. Turns on/off the vehicle's autopilot mode. + Command adaptation of __set_autopilot()__ in carla.Vehicle. Turns on/off the vehicle's autopilot mode. # - PROPERTIES ------------------------- instance_variables: - var_name: actor_id @@ -368,7 +438,7 @@ - class_name: SetVehicleLightState # - DESCRIPTION ------------------------ doc: > - Command adaptation of **set_light_state()** in carla.Vehicle. Sets the light state of a vehicle. + Command adaptation of __set_light_state()__ in carla.Vehicle. Sets the light state of a vehicle. # - PROPERTIES ------------------------- instance_variables: - var_name: actor_id diff --git a/PythonAPI/docs/control.yml b/PythonAPI/docs/control.yml index 4385d213a..5b289b21a 100644 --- a/PythonAPI/docs/control.yml +++ b/PythonAPI/docs/control.yml @@ -51,12 +51,15 @@ - param_name: throttle type: float default: 0.0 + doc: Scalar value between [0.0,1.0] - param_name: steer type: float default: 0.0 + doc: Scalar value between [0.0,1.0] - param_name: brake type: float default: 0.0 + doc: Scalar value between [0.0,1.0] - param_name: hand_brake type: bool default: False @@ -98,6 +101,7 @@ # -------------------------------------- - var_name: speed type: float + var_units: m/s doc: > A scalar value to control the walker's speed. # -------------------------------------- @@ -115,6 +119,7 @@ type: carla.Vector3D - param_name: speed default: 0.0 + param_units: m/s type: float - param_name: jump default: False @@ -154,7 +159,7 @@ - param_name: 'list(name,transform)' type: tuple doc: > - Intializes an object containing moves to be applied on tick. These are listed with the name of the bone and the transform that will be applied to it. + Initializes an object containing moves to be applied on tick. These are listed with the name of the bone and the transform that will be applied to it. # -------------------------------------- - def_name: __str__ # -------------------------------------- @@ -224,6 +229,7 @@ # -------------------------------------- - var_name: moi type: float + var_units: kg*m2 doc: > The moment of inertia of the vehicle's engine. # -------------------------------------- @@ -249,18 +255,20 @@ # -------------------------------------- - var_name: gear_switch_time type: float + var_units: seconds doc: > Switching time between gears. # -------------------------------------- - var_name: clutch_strength type: float + var_units: kg*m2/s doc: > - The clutch strength of the vehicle in Kgm^2/s. + Clutch strength of the vehicle. # -------------------------------------- - var_name: final_ratio type: float doc: > - The fixed ratio from transmission to wheels. + Fixed ratio from transmission to wheels. # -------------------------------------- - var_name: forward_gears type: list(carla.GearPhysicsControl) @@ -269,8 +277,9 @@ # -------------------------------------- - var_name: mass type: float + var_units: kilograms doc: > - The mass of the vehicle in Kg. + Mass of the vehicle. # -------------------------------------- - var_name: drag_coefficient type: float @@ -279,8 +288,9 @@ # -------------------------------------- - var_name: center_of_mass type: carla.Vector3D + var_units: meters doc: > - The center of mass of the vehicle. + Center of mass of the vehicle. # -------------------------------------- - var_name: steering_curve type: list(carla.Vector2D) @@ -305,6 +315,7 @@ - param_name: moi default: 1.0 type: float + param_units: kg*m2 - param_name: damping_rate_full_throttle default: 0.15 type: float @@ -320,9 +331,11 @@ - param_name: gear_switch_time default: 0.5 type: float + param_units: seconds - param_name: clutch_strength default: 10.0 type: float + param_units: kg*m2/s - param_name: final_ratio default: 4.0 type: float @@ -331,6 +344,7 @@ type: list(carla.GearPhysicsControl) - param_name: mass default: 1000.0 + param_units: kilograms - param_name: drag_coefficient default: 0.3 type: float @@ -376,23 +390,27 @@ # -------------------------------------- - var_name: max_steer_angle type: float + var_units: degrees doc: > - Maximum angle in degrees that the wheel can steer. + Maximum angle that the wheel can steer. # -------------------------------------- - var_name: radius type: float + var_units: centimeters doc: > - Radius of the wheel in centimeters. + Radius of the wheel. # -------------------------------------- - var_name: max_brake_torque type: float + var_units: N*m doc: > - Maximum brake torque in Nm. + Maximum brake torque. # -------------------------------------- - var_name: max_handbrake_torque type: float + var_units: N*m doc: > - Maximum handbrake torque in Nm. + Maximum handbrake torque. # -------------------------------------- - var_name: position type: carla.Vector3D @@ -411,18 +429,23 @@ - param_name: max_steer_angle default: 70.0 type: float + param_units: degrees - param_name: radius default: 30.0 type: float + param_units: centimerers - param_name: max_brake_torque default: 1500.0 type: float + param_units: N*m - param_name: max_handbrake_torque default: 3000.0 type: float + param_units: N*m - param_name: position default: (0.0,0.0,0.0) type: carla.Vector3D + param_units: meters # -------------------------------------- - def_name: __eq__ params: diff --git a/PythonAPI/docs/doc_gen.py b/PythonAPI/docs/doc_gen.py index b0cd9de01..d8247a422 100755 --- a/PythonAPI/docs/doc_gen.py +++ b/PythonAPI/docs/doc_gen.py @@ -129,6 +129,9 @@ def brackets(buf): def parentheses(buf): return join(['(', buf, ')']) +def small_html(buf): + return join([''+buf+'']) + def small(buf): return join(['', buf, '']) @@ -328,11 +331,14 @@ def add_doc_method_param(md, param): param_name = param['param_name'] param_type = '' param_doc = '' + param_units = '' if valid_dic_val(param, 'type'): param_type = create_hyperlinks(param['type']) if valid_dic_val(param, 'doc'): param_doc = create_hyperlinks(md.prettify_doc(param['doc'])) - param_type = '' if not param_type else parentheses(italic(param_type)) + if valid_dic_val(param, 'param_units'): + param_units = small_html(' – '+param['param_units']) + param_type = '' if not param_type else parentheses(italic(param_type+param_units)) md.list_push(code(param_name)) if param_type: md.text(' ' + param_type) @@ -372,7 +378,10 @@ def add_doc_method(md, method, class_key): # Return doc if valid_dic_val(method, 'return'): md.list_push(bold('Return:') + ' ') - md.textn(italic(create_hyperlinks(method['return']))) + return_units = '' + if valid_dic_val(method, 'return_units'): + return_units = small_html(' – '+method['return_units']) + md.textn(italic(create_hyperlinks(method['return'])+return_units)) md.list_pop() # Note doc @@ -423,7 +432,10 @@ def add_doc_getter_setter(md, method,class_key,is_getter,other_list): # Return doc if valid_dic_val(method, 'return'): md.list_push(bold('Return:') + ' ') - md.textn(italic(create_hyperlinks(method['return']))) + return_units = '' + if valid_dic_val(method, 'return_units'): + return_units = small_html(' – '+method['return_units']) + md.textn(italic(create_hyperlinks(method['return'])+return_units)) md.list_pop() # If setter/getter @@ -493,11 +505,13 @@ def add_doc_inst_var(md, inst_var, class_key): var_name = inst_var['var_name'] var_key = join([class_key, var_name], '.') var_type = '' + var_units = '' # Instance variable type if valid_dic_val(inst_var, 'type'): - var_type = ' ' + parentheses(italic(create_hyperlinks(inst_var['type']))) - + if valid_dic_val(inst_var, 'var_units'): + var_units = small_html(' – '+inst_var['var_units']) + var_type = ' ' + parentheses(italic(create_hyperlinks(inst_var['type']+var_units))) md.list_pushn( html_key(var_key) + bold(color(COLOR_INSTANCE_VAR, var_name)) + diff --git a/PythonAPI/docs/geom.yml b/PythonAPI/docs/geom.yml index 1321fcc5a..29e92d9a9 100644 --- a/PythonAPI/docs/geom.yml +++ b/PythonAPI/docs/geom.yml @@ -151,16 +151,19 @@ instance_variables: - var_name: x type: float + var_units: meters doc: > - Distance in meters from origin to spot on X axis. + Distance from origin to spot on X axis. - var_name: 'y' type: float + var_units: meters doc: > - Distance in meters from origin to spot on Y axis. + Distance from origin to spot on Y axis. - var_name: z type: float + var_units: meters doc: > - Distance in meters from origin to spot on Z axis. + Distance from origin to spot on Z axis. # - METHODS ---------------------------- methods: - def_name: __init__ @@ -182,8 +185,9 @@ doc: > The other point to compute the distance with. return: float + return_units: meters doc: > - Returns Euclidean distance in meters from this location to another one. + Returns Euclidean distance from this location to another one. # -------------------------------------- - def_name: __eq__ return: bool @@ -210,25 +214,28 @@ - class_name: Rotation # - DESCRIPTION ------------------------ doc: > - Class that represents a 3D rotation and therefore, an orientation in space. - - - ![UE4_Rotation](https://d26ilriwvtzlb.cloudfront.net/8/83/BRMC_9.jpg) - _Unreal Engine's standard (from [UE4 docs](https://wiki.unrealengine.com/Blueprint_Rotating_Movement_Component))_ + Class that represents a 3D rotation and therefore, an orientation in space. CARLA uses the Unreal Engine coordinates system. This is a Z-up left-handed system.
+ +
The constructor method follows a specific order of declaration: `(pitch, yaw, roll)`, which corresponds to `(Y-rotation,Z-rotation,X-rotation)`.
+
![UE4_Rotation](https://d26ilriwvtzlb.cloudfront.net/8/83/BRMC_9.jpg) + *Unreal Engine's coordinates system* # - PROPERTIES ------------------------- instance_variables: - var_name: pitch type: float + var_units: degrees doc: > - Degrees around the Y-axis. + Y-axis rotation angle. - var_name: yaw type: float + var_units: degrees doc: > - Degrees around the Z-axis. + Z-axis rotation angle. - var_name: roll type: float + var_units: degrees doc: > - Degrees around the X-axis. + X-axis rotation angle. # - METHODS ---------------------------- methods: - def_name: __init__ @@ -236,36 +243,40 @@ - param_name: pitch type: float default: 0.0 + param_units: degrees doc: > - Y rotation in degrees. + Y-axis rotation angle. - param_name: yaw type: float default: 0.0 + param_units: degrees doc: > - Z rotation in degrees. + Z-axis rotation angle. - param_name: roll type: float default: 0.0 + param_units: degrees doc: > - X rotation in degrees. + X-axis rotation angle. + warning: The declaration order is different in CARLA (pitch,yaw,roll), and in the Unreal Engine Editor (roll,pitch,yaw). When working in a build from source, don't mix up the axes' rotations. # -------------------------------------- - def_name: get_forward_vector params: return: carla.Vector3D doc: > - Computes the vector pointing forward according to the orientation of each axis. + Computes the vector pointing forward according to the rotation of the object. # -------------------------------------- - def_name: get_right_vector params: return: carla.Vector3D doc: > - Computes the vector pointing to the right according to the orientation of each axis. + Computes the vector pointing to the right according to the rotation of the object. # -------------------------------------- - def_name: get_up_vector params: return: carla.Vector3D doc: > - Computes the vector pointing upwards according to the orientation of each axis. + Computes the vector pointing upwards according to the rotation of the object. # -------------------------------------- - def_name: __eq__ return: bool @@ -273,7 +284,7 @@ - param_name: other type: carla.Rotation doc: > - Returns __True__ if both rotations represent the same orientation of each axis. + Returns __True__ if both rotations represent the same orientation for every axis. # -------------------------------------- - def_name: __ne__ params: @@ -300,6 +311,7 @@ Describes a point in the coordinate system. - var_name: rotation type: carla.Rotation + var_units: degrees (pitch, yaw, roll) doc: > Describes a rotation for an object according to Unreal Engine's axis system. # - METHODS ---------------------------- @@ -310,6 +322,7 @@ type: carla.Location - param_name: rotation type: carla.Rotation + param_units: degrees (pitch, yaw, roll) # -------------------------------------- - def_name: transform params: @@ -323,17 +336,17 @@ - def_name: get_forward_vector return: carla.Vector3D doc: > - Computes a forward vector using its rotation. + Computes a forward vector using the rotation of the object. # -------------------------------------- - def_name: get_right_vector return: carla.Vector3D doc: > - Computes a right vector using its rotation. + Computes a right vector using the rotatio of the object. # -------------------------------------- - def_name: get_up_vector return: carla.Vector3D doc: > - Computes an up vector using its rotation. + Computes an up vector using the rotation of the object. # -------------------------------------- - def_name: get_matrix return: list(list(float)) @@ -370,29 +383,37 @@ - class_name: BoundingBox # - DESCRIPTION ------------------------ doc: > - Helper class defining a box location and its dimensions that will later be used by carla.DebugHelper or a carla.Client to draw shapes and detect collisions. Bounding boxes normally act for object colliders. Check out this [recipe](ref_code_recipes.md#debug-bounding-box-recipe) where the user takes a snapshot of the world and then proceeds to draw bounding boxes for traffic lights. + Bounding boxes contain the geometry of an actor or an element in the scene. They can be used by carla.DebugHelper or a carla.Client to draw their shapes for debugging. Check out this [recipe](ref_code_recipes.md#debug-bounding-box-recipe) where the user takes a snapshot of the world and then proceeds to draw bounding boxes for traffic lights. # - PROPERTIES ------------------------- instance_variables: - var_name: extent type: carla.Vector3D + var_units: meters doc: > Vector from the center of the box to one vertex. The value in each axis equals half the size of the box for that axis. `extent.x * 2` would return the size of the box in the X-axis. - var_name: location type: carla.Location + var_units: meters doc: > - The center of the bounding box relative to its parent actor. + The center of the bounding box. + - var_name: rotation + type: carla.Rotation + doc: > + The orientation of the bounding box. # - METHODS ---------------------------- methods: - def_name: __init__ params: - param_name: location type: carla.Location + var_units: meters doc: > - Point to center the box. + Center of the box, relative to its parent. - param_name: extent type: carla.Vector3D + param_units: meters doc: > Vector containing half the size of the box for every axis. # -------------------------------------- @@ -401,6 +422,7 @@ params: - param_name: world_point type: carla.Location + param_units: meters doc: > The point in world space to be checked. - param_name: transform @@ -455,14 +477,17 @@ instance_variables: - var_name: latitude type: float + var_units: degrees doc: > North/South value of a point on the map. - var_name: longitude type: float + var_units: degrees doc: > West/East value of a point on the map. - var_name: altitude type: float + var_units: meters doc: > Height regarding ground level. # - METHODS ---------------------------- @@ -472,12 +497,15 @@ - param_name: latitude type: float default: 0.0 + param_units: degrees - param_name: longitude type: float default: 0.0 + param_units: degrees - param_name: altitude type: float default: 0.0 + param_units: meters # -------------------------------------- - def_name: __eq__ params: diff --git a/PythonAPI/docs/light_manager.yml b/PythonAPI/docs/light_manager.yml index e3267b3a0..3455644a8 100644 --- a/PythonAPI/docs/light_manager.yml +++ b/PythonAPI/docs/light_manager.yml @@ -28,8 +28,9 @@ instance_variables: - var_name: intensity type: float + var_units: lumens doc: > - Intensity of a light in lumens. + Intensity of a light. # -------------------------------------- - var_name: color type: carla.Color @@ -52,8 +53,9 @@ - param_name: intensity type: float default: 0.0 + param_units: lumens doc: > - Intensity of the light in lumens. Default is `0.0`. + Intensity of the light. Default is `0.0`. # -------------------------------------- - param_name: color type: carla.Color @@ -94,8 +96,9 @@ # -------------------------------------- - var_name: intensity type: float + var_units: lumens doc: > - Intensity of the light in lumens. + Intensity of the light. # -------------------------------------- - var_name: is_on type: bool @@ -104,6 +107,7 @@ # -------------------------------------- - var_name: location type: carla.Location + var_units: meters doc: > Position of the light. # -------------------------------------- @@ -139,6 +143,7 @@ params: - param_name: intensity type: float + param_units: lumens # -------------------------------------- - def_name: set_light_group doc: > @@ -222,6 +227,7 @@ doc: List of lights to be queried. return: list(float) + return_units: lumens # -------------------------------------- - def_name: get_light_group doc: > @@ -312,6 +318,7 @@ List of lights to be changed. - param_name: intensity type: float + param_units: lumens doc: Intensity to be applied. # -------------------------------------- @@ -325,6 +332,7 @@ List of lights to be changed. - param_name: intensities type: list(float) + param_units: lumens doc: List of intensities to be applied. # -------------------------------------- diff --git a/PythonAPI/docs/map.yml b/PythonAPI/docs/map.yml index 88cbaad0a..77bede69e 100644 --- a/PythonAPI/docs/map.yml +++ b/PythonAPI/docs/map.yml @@ -156,6 +156,7 @@ params: - param_name: distance type: float + param_units: meters doc: > Approximate distance between waypoints. return: list(carla.Waypoint) @@ -235,6 +236,7 @@ params: - param_name: location type: carla.Location + param_units: meters doc: > Location used as reference for the carla.Waypoint. - param_name: project_to_road @@ -263,6 +265,7 @@ ID of the lane to get the waypoint. - param_name: s type: float + param_units: meters doc: > Specify the length from the road start. return: carla.Waypoint @@ -297,7 +300,9 @@ - class_name: Waypoint # - DESCRIPTION ------------------------ doc: > - Waypoints in CARLA are described as 3D directed points. They store a certain carla.Transform which locates the waypoint in a road and orientates it according to the lane. They also store the road information belonging to said point regarding its lane and lane markings. All of this information is retrieved as provided by the OpenDRIVE file. + Waypoints in CARLA are described as 3D directed points. They have a carla.Transform which locates the waypoint in a road and orientates it according to the lane. They also store the road information belonging to said point regarding its lane and lane markings. +

+ All the information regarding waypoints and the [waypoint API](../../core_map/#navigation-in-carla) is retrieved as provided by the OpenDRIVE file. Once the client asks for the map object to the server, no longer communication will be needed. # - PROPERTIES ------------------------- instance_variables: - var_name: id @@ -322,6 +327,7 @@ OpenDRIVE lane's id, this value can be positive or negative which represents the direction of the current lane with respect to the road. For more information refer to OpenDRIVE [documentation](http://www.opendrive.org/docs/OpenDRIVEFormatSpecRev1.4H.pdf#page=20) - var_name: s type: float + param_units: meters doc: > OpenDRIVE s value of the current position. - var_name: is_junction @@ -330,6 +336,7 @@ True if the current Waypoint is on a junction as defined by OpenDRIVE. - var_name: lane_width type: float + param_units: meters doc: > Horizontal size of the road at current s. - var_name: lane_change @@ -354,6 +361,7 @@ params: - param_name: distance type: float + param_units: meters doc: > The approximate distance where to get the next waypoints. return: list(carla.Waypoint) @@ -366,8 +374,9 @@ params: - param_name: distance type: float + param_units: meters doc: > - The approximate distance between waypoints + The approximate distance between waypoints. return: list(carla.Waypoint) doc: > Returns a list of waypoints from this to the end of the lane separated by a certain `distance`. @@ -376,6 +385,7 @@ params: - param_name: distance type: float + param_units: meters doc: > The approximate distance where to get the previous waypoints. return: list(carla.Waypoint) @@ -388,8 +398,9 @@ params: - param_name: distance type: float + param_units: meters doc: > - The approximate distance between waypoints + The approximate distance between waypoints. return: list(carla.Waypoint) doc: > Returns a list of waypoints from this to the start of the lane separated by a certain `distance`. @@ -397,12 +408,13 @@ - def_name: get_junction return: carla.Junction doc: > - If the waypoint belongs to a junction this function returns the asociated junction object. Otherwise returns null. + If the waypoint belongs to a junction this method returns the asociated junction object. Otherwise returns null. # -------------------------------------- - def_name: get_landmarks params: - param_name: distance type: float + param_units: meters doc: > The maximum distance to search for landmarks from the current waypoint. - param_name: stop_at_junction @@ -417,6 +429,7 @@ - def_name: get_landmarks_of_type params: - param_name: distance + param_units: meters type: float doc: > The maximum distance to search for landmarks from the current waypoint. @@ -623,14 +636,17 @@ Example: a traffic light is defined in one of the divergent roads in a junction, but it affects all the possible routes - var_name: distance type: float + var_units: meters doc: > Distance between the landmark and the waypoint creating the object (querying `get_landmarks` or `get_landmarks_of_type`). - var_name: s type: float + var_units: meters doc: > Distance where the landmark is positioned along the geometry of the road `road_id`. - var_name: t type: float + var_units: meters doc: > Lateral distance where the landmark is positioned from the edge of the road `road_id`. - var_name: id @@ -647,10 +663,12 @@ Indicates if the landmark has state changes over time such as traffic lights. - var_name: orientation type: carla.LandmarkOrientation + var_units: degrees doc: > Indicates which lanes the landmark is facing towards to. - var_name: z_offset type: float + var_units: meters doc: > Height where the landmark is placed. - var_name: country @@ -675,10 +693,12 @@ Units of measurement for the attribute `value`. - var_name: height type: float + var_units: meters doc: > Total height of the signal. - var_name: width type: float + var_units: meters doc: > Total width of the signal. - var_name: text @@ -687,16 +707,18 @@ Additional text in the signal. - var_name: h_offset type: float + var_units: meters doc: > Orientation offset of the signal relative to the the definition of `road_id` at `s` in OpenDRIVE. - var_name: pitch type: float + var_units: meters doc: > - Pitch rotation of the signal. + Pitch rotation of the signal (Y-axis in [UE coordinates system](https://carla.readthedocs.io/en/latest/python_api/#carlarotation)). - var_name: roll type: float doc: > - Roll rotation of the signal. + Roll rotation of the signal (X-axis in [UE coordinates system](https://carla.readthedocs.io/en/latest/python_api/#carlarotation)). - var_name: waypoint type: carla.Waypoint doc: > diff --git a/PythonAPI/docs/osm2odr.yml b/PythonAPI/docs/osm2odr.yml index 365992e6b..598db3d33 100644 --- a/PythonAPI/docs/osm2odr.yml +++ b/PythonAPI/docs/osm2odr.yml @@ -40,17 +40,21 @@ Enables the use of offset for the conversion. The offset will move the origin position of the map. Default value is __False__. - var_name: offset_x type: float + var_units: meters doc: > Offset in the X axis. Default value is __0.0__. - var_name: offset_y type: float + var_units: meters doc: > Offset in the Y axis. Default value is __0.0__. - var_name: default_lane_width type: float + var_units: meters doc: > Width of the lanes described in the resulting XODR map. Default value is __4.0__. - var_name: elevation_layer_height type: float + var_units: meters doc: > Defines the height separating two different [OpenStreetMap layers](https://wiki.openstreetmap.org/wiki/Key:layer). Default value is __0.0__. diff --git a/PythonAPI/docs/sensor.yml b/PythonAPI/docs/sensor.yml index 466685b31..69aba6bc0 100644 --- a/PythonAPI/docs/sensor.yml +++ b/PythonAPI/docs/sensor.yml @@ -8,21 +8,21 @@ doc: > Sensors compound a specific family of actors quite diverse and unique. They are normally spawned as attachment/sons of a vehicle (take a look at carla.World to learn about actor spawning). Sensors are thoroughly designed to retrieve different types of data that they are listening to. The data they receive is shaped as different subclasses inherited from carla.SensorData (depending on the sensor). - Most sensors can be divided in two groups: those receiving data on every tick (cameras, point clouds and some specific sensors) and those who only receive under certain circumstances (trigger detectors). CARLA provides a specific set of sensors and their blueprint can be found in carla.BlueprintLibrary. All the information on their preferences and settlement can be found [here](ref_sensors.md), but the list of those available in CARLA so far goes as follow. - Receive data on every tick. - - [Depth camera](ref_sensors.md#depth-camera). - - [Gnss sensor](ref_sensors.md#gnss-sensor). - - [IMU sensor](ref_sensors.md#imu-sensor). - - [Lidar raycast](ref_sensors.md#lidar-raycast-sensor). - - [SemanticLidar raycast](ref_sensors.md#semanticlidar-raycast-sensor). - - [Radar](ref_sensors.md#radar-sensor). - - [RGB camera](ref_sensors.md#rgb-camera). - - [RSS sensor](ref_sensors.md#rss-sensor). - - [Semantic Segmentation camera](ref_sensors.md#semantic-segmentation-camera). - Only receive data when triggered. - - [Collision detector](ref_sensors.md#collision-detector). - - [Lane invasion detector](ref_sensors.md#lane-invasion-detector). - - [Obstacle detector](ref_sensors.md#obstacle-detector). + Most sensors can be divided in two groups: those receiving data on every tick (cameras, point clouds and some specific sensors) and those who only receive under certain circumstances (trigger detectors). CARLA provides a specific set of sensors and their blueprint can be found in carla.BlueprintLibrary. All the information on their preferences and settlement can be found [here](ref_sensors.md), but the list of those available in CARLA so far goes as follow. +
Receive data on every tick. + - [Depth camera](ref_sensors.md#depth-camera). + - [Gnss sensor](ref_sensors.md#gnss-sensor). + - [IMU sensor](ref_sensors.md#imu-sensor). + - [Lidar raycast](ref_sensors.md#lidar-raycast-sensor). + - [SemanticLidar raycast](ref_sensors.md#semanticlidar-raycast-sensor). + - [Radar](ref_sensors.md#radar-sensor). + - [RGB camera](ref_sensors.md#rgb-camera). + - [RSS sensor](ref_sensors.md#rss-sensor). + - [Semantic Segmentation camera](ref_sensors.md#semantic-segmentation-camera). +
Only receive data when triggered. + - [Collision detector](ref_sensors.md#collision-detector). + - [Lane invasion detector](ref_sensors.md#lane-invasion-detector). + - [Obstacle detector](ref_sensors.md#obstacle-detector). # - PROPERTIES ------------------------- instance_variables: diff --git a/PythonAPI/docs/sensor_data.yml b/PythonAPI/docs/sensor_data.yml index 890326abe..4b0422507 100644 --- a/PythonAPI/docs/sensor_data.yml +++ b/PythonAPI/docs/sensor_data.yml @@ -5,16 +5,16 @@ - class_name: SensorData # - DESCRIPTION ------------------------ doc: > - Base class for all the objects containing data generated by a carla.Sensor. This objects should be the argument of the function said sensor is listening to, in order to work with them. Each of these sensors needs for a specific type of sensor data. Hereunder is a list of the sensors and their corresponding data. - - Cameras (RGB, depth and semantic segmentation): carla.Image. - - Collision detector: carla.CollisionEvent. - - GNSS sensor: carla.GnssMeasurement. - - IMU sensor: carla.IMUMeasurement. - - Lane invasion detector: carla.LaneInvasionEvent. - - LIDAR sensor: carla.LidarMeasurement. - - Obstacle detector: carla.ObstacleDetectionEvent. - - Radar sensor: carla.RadarMeasurement. - - RSS sensor: carla.RssResponse. + Base class for all the objects containing data generated by a carla.Sensor. This objects should be the argument of the function said sensor is listening to, in order to work with them. Each of these sensors needs for a specific type of sensor data. Hereunder is a list of the sensors and their corresponding data.
+ - Cameras (RGB, depth and semantic segmentation): carla.Image.
+ - Collision detector: carla.CollisionEvent.
+ - GNSS sensor: carla.GnssMeasurement.
+ - IMU sensor: carla.IMUMeasurement.
+ - Lane invasion detector: carla.LaneInvasionEvent.
+ - LIDAR sensor: carla.LidarMeasurement.
+ - Obstacle detector: carla.ObstacleDetectionEvent.
+ - Radar sensor: carla.RadarMeasurement.
+ - RSS sensor: carla.RssResponse.
- Semantic LIDAR sensor: carla.SemanticLidarMeasurement. # - PROPERTIES ------------------------- instance_variables: @@ -24,6 +24,7 @@ Frame count when the data was generated. - var_name: timestamp type: float + var_units: seconds doc: > Simulation-time when the data was generated. - var_name: transform @@ -40,16 +41,47 @@ instance_variables: - var_name: CityScapesPalette doc: > - Converts the image to a segmentated map using tags provided by the blueprint library. Used by sensor.camera.semantic_segmentation. + Converts the image to a segmentated map using tags provided by the blueprint library. Used by the [semantic segmentation camera](ref_sensors.md#semantic-segmentation-camera). - var_name: Depth doc: > - Converts the image to a linear depth map. Used by sensor.camera.depth. + Converts the image to a linear depth map. Used by the [depth camera](ref_sensors.md#depth-camera). - var_name: LogarithmicDepth doc: > Converts the image to a depth map using a logarithmic scale, leading to better precision for small distances at the expense of losing it when further away. - var_name: Raw doc: > - No changes applied to the image. + No changes applied to the image. Used by the [RGB camera](ref_sensors.md#rgb-camera). + + - class_name: CityObjectLabel + # - DESCRIPTION ------------------------ + doc: > + Enum declaration that contains the different tags available to filter the bounding boxes returned by carla.World.get_level_bbs(). These values correspond to the [semantic tag](../../ref_sensors/#semantic-segmentation-camera) that the elements in the scene have. + + # - PROPERTIES ------------------------- + instance_variables: + - var_name: None + - var_name: Buildings + - var_name: Fences + - var_name: Other + - var_name: Pedestrians + - var_name: Poles + - var_name: RoadLines + - var_name: Roads + - var_name: Sidewalks + - var_name: TrafficSigns + - var_name: Vegetation + - var_name: Vehicles + - var_name: Walls + - var_name: Sky + - var_name: Ground + - var_name: Bridge + - var_name: RailTrack + - var_name: GuardRail + - var_name: TrafficLight + - var_name: Static + - var_name: Dynamic + - var_name: Water + - var_name: Terrain - class_name: Image parent: carla.SensorData @@ -60,8 +92,9 @@ instance_variables: - var_name: fov type: float + var_units: degrees doc: > - Horizontal field of view of the image in degrees. + Horizontal field of view of the image. - var_name: height type: int doc: > @@ -127,8 +160,9 @@ Number of lasers shot. - var_name: horizontal_angle type: float + var_units: radians doc: > - Horizontal angle the LIDAR is rotated at the time of the measurement (in radians). + Horizontal angle the LIDAR is rotated at the time of the measurement. - var_name: raw_data type: bytes doc: > @@ -176,13 +210,14 @@ instance_variables: - var_name: point type: carla.Location + var_units: meters doc: > Point in xyz coordinates. # -------------------------------------- - var_name: intensity type: float doc: > - Computed intensity for this point. + Computed intensity for this point as a scalar value between [0.0 , 1.0]. # - METHODS ---------------------------- methods: - def_name: __str__ @@ -201,8 +236,9 @@ Number of lasers shot. - var_name: horizontal_angle type: float + var_units: radians doc: > - Horizontal angle the LIDAR is rotated at the time of the measurement (in radians). + Horizontal angle the LIDAR is rotated at the time of the measurement. - var_name: raw_data type: bytes doc: > @@ -250,6 +286,7 @@ instance_variables: - var_name: point type: carla.Location + var_units: meters doc: > [x,y,z] coordinates of the point. # -------------------------------------- @@ -261,12 +298,12 @@ - var_name: object_idx type: uint doc: > - Carla index of the hit actor. + ID of the actor hit by the ray. # -------------------------------------- - var_name: object_tag type: uint doc: > - Semantic tag of the hit component. + [Semantic tag](https://carla.readthedocs.io/en/latest/ref_sensors/#semantic-segmentation-camera) of the component hit by the ray. # - METHODS ---------------------------- methods: - def_name: __str__ @@ -289,6 +326,7 @@ The second actor involved in the collision. - var_name: normal_impulse type: carla.Vector3D + var_units: N*s doc: > Normal impulse resulting of the collision. @@ -309,6 +347,7 @@ The actor or object considered to be an obstacle. - var_name: distance type: float + var_units: meters doc: > Distance between `actor` and `other`. # - METHODS ---------------------------- @@ -345,14 +384,17 @@ instance_variables: - var_name: altitude type: float + var_units: meters doc: > Height regarding ground level. - var_name: latitude type: float + var_units: degrees doc: > North/South value of a point on the map. - var_name: longitude type: float + var_units: degrees doc: > West/East value of a point on the map. # - METHODS ---------------------------- @@ -369,16 +411,19 @@ instance_variables: - var_name: accelerometer type: carla.Vector3D + var_units: m/s2 doc: > - Linear acceleration in m/s^2. + Linear acceleration. - var_name: compass type: float + var_units: radians doc: > - Orientation with regard to the North ((0.0, -1.0, 0.0) in Unreal Engine) in radians. + Orientation with regard to the North ([0.0, -1.0, 0.0] in Unreal Engine). - var_name: gyroscope type: carla.Vector3D + var_units: rad/s doc: > - Angular velocity in rad/sec. + Angular velocity. # - METHODS ---------------------------- methods: - def_name: __str__ @@ -428,23 +473,27 @@ instance_variables: - var_name: altitude type: float + var_units: radians doc: > - Altitude angle of the detection in radians. + Altitude angle of the detection. # -------------------------------------- - var_name: azimuth type: float + var_units: radians doc: > - Azimuth angle of the detection in radians. + Azimuth angle of the detection. # -------------------------------------- - var_name: depth type: float + var_units: meters doc: > - Distance in meters from the sensor to the detection position. + Distance from the sensor to the detection position. # -------------------------------------- - var_name: velocity type: float + var_units: m/s doc: > - The velocity of the detected object towards the sensor in m/s. + The velocity of the detected object towards the sensor. # - METHODS ---------------------------- methods: - def_name: __str__ @@ -688,8 +737,9 @@ instance_variables: - var_name: fov type: float + var_units: degrees doc: > - Horizontal field of view of the image in degrees. + Horizontal field of view of the image. # -------------------------------------- - var_name: height type: int diff --git a/PythonAPI/docs/snapshot.yml b/PythonAPI/docs/snapshot.yml index e94c5b563..04c310e30 100644 --- a/PythonAPI/docs/snapshot.yml +++ b/PythonAPI/docs/snapshot.yml @@ -19,6 +19,7 @@ Simulation frame in which the snapshot was taken. - var_name: timestamp type: carla.Timestamp + var_units: seconds doc: > Precise moment in time when snapshot was taken. This class works in seconds as given by the operative system. # - METHODS ---------------------------- @@ -79,11 +80,13 @@ methods: - def_name: get_acceleration return: carla.Vector3D + return_units: m/s2 doc: > Returns the acceleration vector registered for an actor in that tick. # -------------------------------------- - def_name: get_angular_velocity return: carla.Vector3D + return_units: rad/s doc: > Returns the angular velocity vector registered for an actor in that tick. # -------------------------------------- @@ -94,6 +97,7 @@ # -------------------------------------- - def_name: get_velocity return: carla.Vector3D + return_units: m/s doc: > Returns the velocity vector registered for an actor in that tick. # -------------------------------------- diff --git a/PythonAPI/docs/weather.yml b/PythonAPI/docs/weather.yml index 9794239bf..52e22e372 100644 --- a/PythonAPI/docs/weather.yml +++ b/PythonAPI/docs/weather.yml @@ -32,13 +32,15 @@ # -------------------------------------- - var_name: sun_azimuth_angle type: float + var_units: degrees doc: > - The azimuth angle of the sun in degrees. Values range from 0 to 360. Zero is an origin point in a sphere determined by Unreal Engine. + The azimuth angle of the sun. Values range from 0 to 360. Zero is an origin point in a sphere determined by Unreal Engine. # -------------------------------------- - var_name: sun_altitude_angle type: float + var_units: degrees doc: > - Altitude angle of the sun in degrees. Values range from -90 to 90 corresponding to midnight and midday each. + Altitude angle of the sun. Values range from -90 to 90 corresponding to midnight and midday each. # -------------------------------------- - var_name: fog_density type: float @@ -47,8 +49,9 @@ # -------------------------------------- - var_name: fog_distance type: float + var_units: meters doc: > - Fog start distance (in meters). Values range from 0 to infinite. + Fog start distance. Values range from 0 to infinite. # -------------------------------------- - var_name: wetness type: float @@ -87,11 +90,13 @@ - param_name: sun_azimuth_angle type: float default: 0.0 + param_units: degrees doc: > 0 is an arbitrary North, 180 its corresponding South. - param_name: sun_altitude_angle type: float default: 0.0 + param_units: degrees doc: > 90 is midday, -90 is midnight. - param_name: fog_density @@ -102,6 +107,7 @@ - param_name: fog_distance type: float default: 0.0 + param_units: meters doc: > Distance where the fog starts in meters. - param_name: wetness diff --git a/PythonAPI/docs/world.yml b/PythonAPI/docs/world.yml index 18c51d1e6..3edcc54e7 100644 --- a/PythonAPI/docs/world.yml +++ b/PythonAPI/docs/world.yml @@ -15,14 +15,17 @@ The number of frames elapsed since the simulator was launched. - var_name: elapsed_seconds type: float + var_units: seconds doc: > Simulated seconds elapsed since the beginning of the current episode. - var_name: delta_seconds type: float + var_units: seconds doc: > Simulated seconds elapsed since the previous frame. - var_name: platform_timestamp type: float + var_units: seconds doc: > Time register of the frame at which this measurement was taken given by the OS in seconds. # - METHODS ---------------------------- @@ -33,20 +36,25 @@ type: int - param_name: elapsed_seconds type: float + param_units: seconds - param_name: delta_seconds type: float + param_units: seconds - param_name: platform_timestamp type: float + param_units: seconds # -------------------------------------- - def_name: __eq__ params: - param_name: other type: carla.Timestamp + param_units: seconds # -------------------------------------- - def_name: __ne__ params: - param_name: other type: carla.Timestamp + param_units: seconds # -------------------------------------- - def_name: __str__ # -------------------------------------- @@ -131,8 +139,9 @@ - param_name: fixed_delta_seconds type: float default: 0.0 + param_units: seconds doc: > - Set this time in seconds to get a fixed time-step in between frames. 0.0 means variable time-step and it is the default mode. + Set a fixed time-step in between frames. 0.0 means variable time-step and it is the default mode. doc: > Creates an object containing desired settings that could later be applied through carla.World and its method **apply_settings()**. # -------------------------------------- @@ -226,8 +235,9 @@ - param_name: seconds type: float default: 10.0 + param_units: seconds doc: > - Maximum time in seconds the server should wait for a tick. It is set to 10.0 by default. + Maximum time the server should wait for a tick. It is set to 10.0 by default. doc: > This method only has effect on synchronous mode, when both client and server move together. The client tells the server when to step to the next frame and returns the id of the newly started frame. # -------------------------------------- @@ -237,8 +247,9 @@ - param_name: seconds type: float default: 10.0 + param_units: seconds doc: > - Maximum time in seconds the server should wait for a tick. It is set to 10.0 by default. + Maximum time the server should wait for a tick. It is set to 10.0 by default. doc: > The client tells the server to pause the simulation until a **World.tick()** is received. # -------------------------------------- @@ -319,6 +330,17 @@ doc: > Returns a dict where the keys are carla.Actor IDs and the values are carla.VehicleLightState of that vehicle. # -------------------------------------- + - def_name: get_level_bbs + params: + - param_name: actor_type + type: carla.CityObjectLabel + default: None + doc: > + Semantic tag of the elements contained in the bounding boxes that are returned. + return: array(carla.BoundingBox) + doc: > + Returns an array of bounding boxes with location and rotation in world space. The method returns all the bounding boxes in the level by default, but the query can be filtered by semantic tags with the argument `actor_type`. + # -------------------------------------- - def_name: get_lightmanager return: carla.LightManager doc: > @@ -331,10 +353,16 @@ doc: > Freezes or unfreezes all traffic lights in the scene. Frozen traffic lights can be modified by the user but the time will not update them until unfrozen. # -------------------------------------- + - def_name: reset_all_traffic_lights + doc: > + Resets the cycle of all traffic lights in the map to the initial state. + # -------------------------------------- - def_name: get_map return: carla.Map doc: > - Returns the object containing the navigation map used to describe this world. + Asks the server for the XODR containing the map file, and returns this parsed as a carla.Map. + warning: > + This method does call the simulation. It is expensive, and should only be called once. # -------------------------------------- - def_name: get_traffic_light return: carla.TrafficLight @@ -407,20 +435,24 @@ params: - param_name: begin type: carla.Location + param_units: meters doc: > Point in the coordinate system where the arrow starts. - param_name: end type: carla.Location + param_units: meters doc: > Point in the coordinate system where the arrow ends and points towards to. - param_name: thickness type: float - default: 0.1f + default: 0.1 + param_units: meters doc: > Density of the line. - param_name: arrow_size type: float - default: 0.1f + default: 0.1 + param_units: meters doc: > Size of the tip of the arrow. - param_name: color @@ -430,9 +462,10 @@ RGB code to color the object. Red by default. - param_name: life_time type: float - default: -1.0f + default: -1.0 + param_units: seconds doc: > - Lifespan in seconds for the shape. By default it only lasts one frame. Set this to 0 for permanent shapes. + Shape's lifespan. By default it only lasts one frame. Set this to 0 for permanent shapes. doc: > Draws an arrow from `begin` to `end` pointing in that direction. @@ -445,11 +478,13 @@ Object containing a location and the length of a box for every axis. - param_name: rotation type: carla.Rotation + param_units: degrees (pitch,yaw,roll) doc: > Orientation of the box according to Unreal Engine's axis system. - param_name: thickness type: float - default: 0.1f + default: 0.1 + param_units: meters doc: > Density of the lines that define the box. - param_name: color @@ -459,9 +494,10 @@ RGB code to color the object. Red by default. - param_name: life_time type: float - default: -1.0f + default: -1.0 + param_units: seconds doc: > - Lifespan in seconds for the shape. By default it only lasts one frame. Set this to 0 for permanent shapes. + Shape's lifespan. By default it only lasts one frame. Set this to 0 for permanent shapes. doc: > Draws a box, ussually to act for object colliders. @@ -470,15 +506,18 @@ params: - param_name: begin type: carla.Location + param_units: meters doc: > Point in the coordinate system where the line starts. - param_name: end type: carla.Location + param_units: meters doc: > Spot in the coordinate system where the line ends. - param_name: thickness type: float - default: 0.1f + default: 0.1 + param_units: meters doc: > Density of the line. - param_name: color @@ -488,9 +527,10 @@ RGB code to color the object. Red by default. - param_name: life_time type: float - default: -1.0f + default: -1.0 + param_units: seconds doc: > - Lifespan in seconds for the shape. By default it only lasts one frame. Set this to 0 for permanent shapes. + Shape's lifespan. By default it only lasts one frame. Set this to 0 for permanent shapes. doc: > Draws a line in between `begin` and `end`. # -------------------------------------- @@ -498,11 +538,13 @@ params: - param_name: location type: carla.Location + param_units: meters doc: > Spot in the coordinate system to center the object. - param_name: size type: float - default: 0.1f + default: 0.1 + param_units: meters doc: > Density of the point. - param_name: color @@ -512,9 +554,10 @@ RGB code to color the object. Red by default. - param_name: life_time type: float - default: -1.0f + default: -1.0 + param_units: seconds doc: > - Lifespan in seconds for the shape. By default it only lasts one frame. Set this to 0 for permanent shapes. + Shape's lifespan. By default it only lasts one frame. Set this to 0 for permanent shapes. doc: > Draws a point `location`. # -------------------------------------- @@ -522,6 +565,7 @@ params: - param_name: location type: carla.Location + param_units: meters doc: > Spot in the simulation where the text will be centered. - param_name: text @@ -540,7 +584,10 @@ RGB code to color the string. Red by default. - param_name: life_time type: float - default: -1.0f + default: -1.0 + param_units: seconds + doc: > + Shape's lifespan. By default it only lasts one frame. Set this to 0 for permanent shapes. doc: > Draws a string in a given location of the simulation which can only be seen server-side. # -------------------------------------- diff --git a/PythonAPI/examples/manual_control.py b/PythonAPI/examples/manual_control.py index a379eb4f4..5d6e56036 100755 --- a/PythonAPI/examples/manual_control.py +++ b/PythonAPI/examples/manual_control.py @@ -22,6 +22,7 @@ Use ARROWS or WASD keys for control. P : toggle autopilot M : toggle manual transmission ,/. : gear up/down + CTRL + W : toggle constant velocity mode at 60 km/h L : toggle next light type SHIFT + L : toggle high beam @@ -181,6 +182,7 @@ class World(object): self.world.on_tick(hud.on_world_tick) self.recording_enabled = False self.recording_start = 0 + self.constant_velocity_enabled = False def restart(self): self.player_max_speed = 1.589 @@ -261,16 +263,18 @@ class World(object): def destroy(self): if self.radar_sensor is not None: self.toggle_radar() - actors = [ + sensors = [ self.camera_manager.sensor, self.collision_sensor.sensor, self.lane_invasion_sensor.sensor, self.gnss_sensor.sensor, - self.imu_sensor.sensor, - self.player] - for actor in actors: - if actor is not None: - actor.destroy() + self.imu_sensor.sensor] + for sensor in sensors: + if sensor is not None: + sensor.stop() + sensor.destroy() + if self.player is not None: + self.player.destroy() # ============================================================================== @@ -328,6 +332,15 @@ class KeyboardControl(object): world.camera_manager.next_sensor() elif event.key == K_n: world.camera_manager.next_sensor() + elif event.key == K_w and (pygame.key.get_mods() & KMOD_CTRL): + if world.constant_velocity_enabled: + world.player.disable_constant_velocity() + world.constant_velocity_enabled = False + world.hud.notification("Disabled Constant Velocity Mode") + else: + world.player.enable_constant_velocity(carla.Vector3D(17, 0, 0)) + world.constant_velocity_enabled = True + world.hud.notification("Enabled Constant Velocity Mode at 60 km/h") elif event.key > K_0 and event.key <= K_9: world.camera_manager.set_sensor(event.key - 1 - K_0) elif event.key == K_r and not (pygame.key.get_mods() & KMOD_CTRL): diff --git a/PythonAPI/examples/manual_control_steeringwheel.py b/PythonAPI/examples/manual_control_steeringwheel.py index 7c98d3bb2..cdd551db0 100755 --- a/PythonAPI/examples/manual_control_steeringwheel.py +++ b/PythonAPI/examples/manual_control_steeringwheel.py @@ -187,16 +187,17 @@ class World(object): self.hud.render(display) def destroy(self): - actors = [ + sensors = [ self.camera_manager.sensor, self.collision_sensor.sensor, self.lane_invasion_sensor.sensor, - self.gnss_sensor.sensor, - self.player] - for actor in actors: - if actor is not None: - actor.destroy() - + self.gnss_sensor.sensor] + for sensor in sensors: + if sensor is not None: + sensor.stop() + sensor.destroy() + if self.player is not None: + self.player.destroy() # ============================================================================== # -- DualControl ----------------------------------------------------------- diff --git a/PythonAPI/examples/opend3d.py b/PythonAPI/examples/open3d_lidar.py similarity index 95% rename from PythonAPI/examples/opend3d.py rename to PythonAPI/examples/open3d_lidar.py index 2c191e6c2..f3fbe4418 100644 --- a/PythonAPI/examples/opend3d.py +++ b/PythonAPI/examples/open3d_lidar.py @@ -33,21 +33,28 @@ VIRIDIS = np.array(cm.get_cmap('plasma').colors) VID_RANGE = np.linspace(0.0, 1.0, VIRIDIS.shape[0]) LABEL_COLORS = np.array([ (255, 255, 255), # None - (70, 70, 70), # Buildings - (190, 153, 153), # Fences - (250, 170, 160), # Other - (220, 20, 60), # Pedestrians - (153, 153, 153), # Poles + (70, 70, 70), # Building + (100, 40, 40), # Fences + (55, 90, 80), # Other + (220, 20, 60), # Pedestrian + (153, 153, 153), # Pole (157, 234, 50), # RoadLines - (128, 64, 128), # Roads - (244, 35, 232), # Sidewalks + (128, 64, 128), # Road + (244, 35, 232), # Sidewalk (107, 142, 35), # Vegetation - (0, 0, 142), # Car - (102, 102, 156), # Walls + (0, 0, 142), # Vehicle + (102, 102, 156), # Wall (220, 220, 0), # TrafficSign (70, 130, 180), # Sky (81, 0, 81), # Ground - (150, 100, 100) # Bridge + (150, 100, 100), # Bridge + (230, 150, 140), # RailTrack + (180, 165, 180), # GuardRail + (250, 170, 30), # TrafficLight + (110, 190, 160), # Static + (170, 120, 50), # Dynamic + (45, 60, 150), # Water + (145, 170, 100), # Terrain ]) / 255.0 # normalize each channel [0-1] since is what Open3D uses diff --git a/PythonAPI/examples/rss/manual_control_rss.py b/PythonAPI/examples/rss/manual_control_rss.py index 74008b6e3..a5ad1147c 100755 --- a/PythonAPI/examples/rss/manual_control_rss.py +++ b/PythonAPI/examples/rss/manual_control_rss.py @@ -102,7 +102,6 @@ try: from pygame.locals import K_q from pygame.locals import K_r from pygame.locals import K_s - from pygame.locals import K_t from pygame.locals import K_w from pygame.locals import K_l from pygame.locals import K_i @@ -420,12 +419,6 @@ class VehicleControl(object): elif event.key == K_g: if self._world and self._world.rss_sensor: self._world.rss_sensor.drop_route() - elif event.key == K_t: - if self._world and self._world.rss_sensor: - if self._world.rss_sensor.assertive_parameters: - self._world.rss_sensor.set_default_parameters() - else: - self._world.rss_sensor.set_assertive_parameters() if isinstance(self._control, carla.VehicleControl): if event.key == K_q: self._control.gear = 1 if self._control.reverse else -1 diff --git a/PythonAPI/examples/rss/rss_sensor.py b/PythonAPI/examples/rss/rss_sensor.py index 187795f3a..de8897785 100644 --- a/PythonAPI/examples/rss/rss_sensor.py +++ b/PythonAPI/examples/rss/rss_sensor.py @@ -298,29 +298,6 @@ class RssSensor(object): def toggle_debug_visualization_mode(self): self.debug_visualizer.toggleMode() - @staticmethod - def get_assertive_parameters(): - ego_dynamics = rss.RssDynamics() - ego_dynamics.alphaLon.accelMax = 4.1 - ego_dynamics.alphaLon.brakeMax = -8.03 - ego_dynamics.alphaLon.brakeMin = -4.64 - ego_dynamics.alphaLon.brakeMinCorrect = -1.76 - ego_dynamics.alphaLat.accelMax = 0.43 - ego_dynamics.alphaLat.brakeMin = -0.96 - ego_dynamics.lateralFluctuationMargin = 0.07 - ego_dynamics.responseTime = 0.25 # paper: 0.53 - ego_dynamics.maxSpeedOnAcceleration = 100 - ego_dynamics.unstructuredSettings.pedestrianTurningRadius = 2.0 - ego_dynamics.unstructuredSettings.driveAwayMaxAngle = 2.4 - ego_dynamics.unstructuredSettings.vehicleYawRateChange = 0.3 - ego_dynamics.unstructuredSettings.vehicleMinRadius = 3.5 - ego_dynamics.unstructuredSettings.vehicleTrajectoryCalculationStep = 0.2 - return ego_dynamics - - def set_assertive_parameters(self): - print("Use 'assertive' RSS Parameters") - self.current_vehicle_parameters = self.get_assertive_parameters() - @staticmethod def get_default_parameters(): ego_dynamics = rss.RssDynamics() @@ -331,13 +308,18 @@ class RssSensor(object): ego_dynamics.alphaLat.accelMax = 0.2 ego_dynamics.alphaLat.brakeMin = -0.8 ego_dynamics.lateralFluctuationMargin = 0.1 - ego_dynamics.responseTime = 1.0 + ego_dynamics.responseTime = 0.5 ego_dynamics.maxSpeedOnAcceleration = 100 ego_dynamics.unstructuredSettings.pedestrianTurningRadius = 2.0 ego_dynamics.unstructuredSettings.driveAwayMaxAngle = 2.4 ego_dynamics.unstructuredSettings.vehicleYawRateChange = 0.3 ego_dynamics.unstructuredSettings.vehicleMinRadius = 3.5 ego_dynamics.unstructuredSettings.vehicleTrajectoryCalculationStep = 0.2 + ego_dynamics.unstructuredSettings.vehicleFrontIntermediateRatioSteps = 4 + ego_dynamics.unstructuredSettings.vehicleBackIntermediateRatioSteps = 0 + ego_dynamics.unstructuredSettings.vehicleContinueForwardIntermediateAccelerationSteps = 0 + ego_dynamics.unstructuredSettings.vehicleBrakeIntermediateAccelerationSteps = 0 + ego_dynamics.unstructuredSettings.vehicleResponseTimeIntermediateAccelerationSteps = 4 return ego_dynamics def set_default_parameters(self): @@ -358,9 +340,17 @@ class RssSensor(object): pedestrian_dynamics.maxSpeedOnAcceleration = 10 pedestrian_dynamics.unstructuredSettings.pedestrianTurningRadius = 2.0 pedestrian_dynamics.unstructuredSettings.driveAwayMaxAngle = 2.4 + + #not used: pedestrian_dynamics.unstructuredSettings.vehicleYawRateChange = 0.3 pedestrian_dynamics.unstructuredSettings.vehicleMinRadius = 3.5 pedestrian_dynamics.unstructuredSettings.vehicleTrajectoryCalculationStep = 0.2 + pedestrian_dynamics.unstructuredSettings.vehicleTrajectoryCalculationStep = 0.2 + pedestrian_dynamics.unstructuredSettings.vehicleFrontIntermediateRatioSteps = 4 + pedestrian_dynamics.unstructuredSettings.vehicleBackIntermediateRatioSteps = 0 + pedestrian_dynamics.unstructuredSettings.vehicleContinueForwardIntermediateAccelerationSteps = 0 + pedestrian_dynamics.unstructuredSettings.vehicleBrakeIntermediateAccelerationSteps = 0 + pedestrian_dynamics.unstructuredSettings.vehicleResponseTimeIntermediateAccelerationSteps = 4 return pedestrian_dynamics def get_steering_ranges(self): diff --git a/PythonAPI/examples/show_recorder_file_info.py b/PythonAPI/examples/show_recorder_file_info.py index f9f5f45aa..1dde92ada 100755 --- a/PythonAPI/examples/show_recorder_file_info.py +++ b/PythonAPI/examples/show_recorder_file_info.py @@ -47,14 +47,24 @@ def main(): '-a', '--show_all', action='store_true', help='show detailed info about all frames content') + argparser.add_argument( + '-s', '--save_to_file', + metavar='S', + help='save result to file (specify name and extension)') + args = argparser.parse_args() try: client = carla.Client(args.host, args.port) client.set_timeout(60.0) + if args.save_to_file: + doc = open(args.save_to_file, "w+") + doc.write(client.show_recorder_file_info(args.recorder_filename, args.show_all)) + doc.close() + else: + print(client.show_recorder_file_info(args.recorder_filename, args.show_all)) - print(client.show_recorder_file_info(args.recorder_filename, args.show_all)) finally: pass diff --git a/PythonAPI/examples/spawn_npc.py b/PythonAPI/examples/spawn_npc.py index e3e9d0e89..970e4fda4 100755 --- a/PythonAPI/examples/spawn_npc.py +++ b/PythonAPI/examples/spawn_npc.py @@ -27,8 +27,7 @@ from carla import VehicleLightState as vls import argparse import logging -import random - +from numpy import random def main(): argparser = argparse.ArgumentParser( @@ -84,6 +83,11 @@ def main(): '--hybrid', action='store_true', help='Enanble') + argparser.add_argument( + '-s', '--seed', + metavar='S', + type=int, + help='Random device seed') argparser.add_argument( '--car-lights-on', action='store_true', @@ -99,14 +103,18 @@ def main(): client = carla.Client(args.host, args.port) client.set_timeout(10.0) synchronous_master = False + random.seed(args.seed if args.seed is not None else int(time.time())) try: world = client.get_world() traffic_manager = client.get_trafficmanager(args.tm_port) - traffic_manager.set_global_distance_to_leading_vehicle(2.0) + traffic_manager.set_global_distance_to_leading_vehicle(1.0) if args.hybrid: traffic_manager.set_hybrid_physics_mode(True) + if args.seed is not None: + traffic_manager.set_random_device_seed(args.seed) + if args.sync: settings = world.get_settings() @@ -129,6 +137,8 @@ def main(): blueprints = [x for x in blueprints if not x.id.endswith('cybertruck')] blueprints = [x for x in blueprints if not x.id.endswith('t2')] + blueprints = sorted(blueprints, key=lambda bp: bp.id) + spawn_points = world.get_map().get_spawn_points() number_of_spawn_points = len(spawn_points) diff --git a/PythonAPI/examples/vehicle_physics.py b/PythonAPI/examples/vehicle_physics.py new file mode 100644 index 000000000..af1b23bf6 --- /dev/null +++ b/PythonAPI/examples/vehicle_physics.py @@ -0,0 +1,144 @@ +#!/usr/bin/env python + +# 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 . + +""" +Vehicle physics example for CARLA +Small example that shows the effect of different impulse and force aplication +methods to a vehicle. +""" + +import glob +import os +import sys +import argparse + +try: + sys.path.append(glob.glob('../carla/dist/carla-*%d.%d-%s.egg' % ( + sys.version_info.major, + sys.version_info.minor, + 'win-amd64' if os.name == 'nt' else 'linux-x86_64'))[0]) +except IndexError: + pass + +import carla + + +def print_step_info(world, vehicle): + snapshot = world.get_snapshot() + print("%d %06.03f %+8.03f %+8.03f %+8.03f %+8.03f %+8.03f %+8.03f %+8.03f %+8.03f %+8.03f" % + (snapshot.frame, snapshot.timestamp.elapsed_seconds, \ + vehicle.get_acceleration().x, vehicle.get_acceleration().y, vehicle.get_acceleration().z, \ + vehicle.get_velocity().x, vehicle.get_velocity().y, vehicle.get_velocity().z, \ + vehicle.get_location().x, vehicle.get_location().y, vehicle.get_location().z)) + + +def wait(world, frames=100): + for i in range(0, frames): + world.tick() + + +def main(arg): + """Main function of the script""" + client = carla.Client(arg.host, arg.port) + client.set_timeout(2.0) + world = client.get_world() + + try: + # Setting the world and the spawn properties + original_settings = world.get_settings() + settings = world.get_settings() + + delta = 0.1 + settings.fixed_delta_seconds = delta + settings.synchronous_mode = True + world.apply_settings(settings) + + blueprint_library = world.get_blueprint_library() + vehicle_bp = blueprint_library.filter(arg.filter)[0] + + vehicle_transform = world.get_map().get_spawn_points()[0] + vehicle_transform.location.z += 3 + vehicle = world.spawn_actor(vehicle_bp, vehicle_transform) + + physics_vehicle = vehicle.get_physics_control() + car_mass = physics_vehicle.mass + + spectator_transform = carla.Transform(vehicle_transform.location, vehicle_transform.rotation) + spectator_transform.location += vehicle_transform.get_forward_vector() * 20 + spectator_transform.rotation.yaw += 180 + spectator = world.get_spectator() + spectator.set_transform(spectator_transform) + + + # We let the vehicle stabilize and save the transform to reset it after each test. + wait(world) + vehicle.set_target_velocity(carla.Vector3D(0, 0, 0)) + vehicle_transform = vehicle.get_transform() + wait(world) + + + # Impulse/Force at the center of mass of the object + impulse = 10 * car_mass + + print("# Adding an Impulse of %f N s" % impulse) + vehicle.add_impulse(carla.Vector3D(0, 0, impulse)) + + wait(world) + vehicle.set_transform(vehicle_transform) + vehicle.set_target_velocity(carla.Vector3D(0, 0, 0)) + wait(world) + + print("# Adding a Force of %f N" % (impulse / delta)) + # The add_force method should not be use for instantaneous forces like this one, + # it is more useful for constant or variable forces acting in a finite amount of time. + # In this script it is done with the proper scaling to show the equivalence + # between the add_impulse and add_force methods. + # As in this case the force is going to be applied during the whole step dt=delta + # a force more or less equivalent is impulse / delta. + vehicle.add_force(carla.Vector3D(0, 0, impulse / delta)) + + wait(world) + vehicle.set_transform(vehicle_transform) + vehicle.set_target_velocity(carla.Vector3D(0, 0, 0)) + wait(world) + + wait(world, 500) + + + finally: + world.apply_settings(original_settings) + + vehicle.destroy() + + +if __name__ == "__main__": + + argparser = argparse.ArgumentParser( + description=__doc__) + argparser.add_argument( + '--host', + metavar='H', + default='localhost', + help='IP of the host CARLA Simulator (default: localhost)') + argparser.add_argument( + '-p', '--port', + metavar='P', + default=2000, + type=int, + help='TCP port of CARLA Simulator (default: 2000)') + argparser.add_argument( + '--filter', + metavar='PATTERN', + default='model3', + help='actor filter (default: "vehicle.*")') + args = argparser.parse_args() + + try: + main(args) + except KeyboardInterrupt: + print(' - Exited by user.') diff --git a/README.md b/README.md index 62feb1cda..18447726e 100644 --- a/README.md +++ b/README.md @@ -21,7 +21,6 @@ If you want to benchmark your model in the same conditions as in our CoRL’17 paper, check out [Benchmarking](https://github.com/carla-simulator/driving-benchmarks). -* [**Give feedback for CARLA 0.9.10 pre-release**](https://github.com/carla-simulator/carla/blob/master/Docs/download.md#pre-release-0910) * [**Get CARLA overnight build**](http://carla-releases.s3.amazonaws.com/Linux/Dev/CARLA_Latest.tar.gz) ## CARLA Ecosystem diff --git a/Unreal/CarlaUE4/Config/DefaultEngine.ini b/Unreal/CarlaUE4/Config/DefaultEngine.ini index ffa00cc80..f6064a6f3 100644 --- a/Unreal/CarlaUE4/Config/DefaultEngine.ini +++ b/Unreal/CarlaUE4/Config/DefaultEngine.ini @@ -33,6 +33,7 @@ r.DistanceFieldBuild.EightBit=False r.DistanceFieldBuild.Compress=False r.DistanceFields.AtlasSizeXY=1024 r.DistanceFields.AtlasSizeZ=2048 +r.DefaultFeature.AutoExposure.ExtendDefaultLuminanceRange=True [/Script/AIModule.AISense_Sight] bAutoRegisterAllPawnsAsSources=False diff --git a/Unreal/CarlaUE4/Config/DefaultScalability.ini b/Unreal/CarlaUE4/Config/DefaultScalability.ini new file mode 100644 index 000000000..933e476cb --- /dev/null +++ b/Unreal/CarlaUE4/Config/DefaultScalability.ini @@ -0,0 +1,14 @@ +# More info: +# https://docs.unrealengine.com/en-US/Engine/Performance/Scalability/ScalabilityReference/index.html + +[PostProcessQuality@0] +r.EyeAdaptationQuality=2 + +[PostProcessQuality@1] +r.EyeAdaptationQuality=2 + +[PostProcessQuality@2] +r.EyeAdaptationQuality=2 + +[PostProcessQuality@3] +r.EyeAdaptationQuality=2 diff --git a/Unreal/CarlaUE4/Plugins/Carla/Source/Carla/Actor/ActorBlueprintFunctionLibrary.cpp b/Unreal/CarlaUE4/Plugins/Carla/Source/Carla/Actor/ActorBlueprintFunctionLibrary.cpp index 776bf7ffd..629e4591b 100644 --- a/Unreal/CarlaUE4/Plugins/Carla/Source/Carla/Actor/ActorBlueprintFunctionLibrary.cpp +++ b/Unreal/CarlaUE4/Plugins/Carla/Source/Carla/Actor/ActorBlueprintFunctionLibrary.cpp @@ -428,7 +428,7 @@ void UActorBlueprintFunctionLibrary::MakeCameraDefinition( FActorVariation ExposureMode; ExposureMode.Id = TEXT("exposure_mode"); ExposureMode.Type = EActorAttributeType::String; - ExposureMode.RecommendedValues = { TEXT("manual"), TEXT("histogram") }; + ExposureMode.RecommendedValues = { TEXT("histogram"), TEXT("manual") }; ExposureMode.bRestrictToRecommended = true; // Logarithmic adjustment for the exposure. Only used if a tonemapper is @@ -441,7 +441,7 @@ void UActorBlueprintFunctionLibrary::MakeCameraDefinition( FActorVariation ExposureCompensation; ExposureCompensation.Id = TEXT("exposure_compensation"); ExposureCompensation.Type = EActorAttributeType::Float; - ExposureCompensation.RecommendedValues = { TEXT("-2.2") }; + ExposureCompensation.RecommendedValues = { TEXT("0.0") }; ExposureCompensation.bRestrictToRecommended = false; // - Manual ------------------------------------------------ @@ -460,7 +460,7 @@ void UActorBlueprintFunctionLibrary::MakeCameraDefinition( FActorVariation ISO; // S ISO.Id = TEXT("iso"); ISO.Type = EActorAttributeType::Float; - ISO.RecommendedValues = { TEXT("200.0") }; + ISO.RecommendedValues = { TEXT("100.0") }; ISO.bRestrictToRecommended = false; // Defines the size of the opening for the camera lens. @@ -468,7 +468,7 @@ void UActorBlueprintFunctionLibrary::MakeCameraDefinition( FActorVariation Aperture; // N Aperture.Id = TEXT("fstop"); Aperture.Type = EActorAttributeType::Float; - Aperture.RecommendedValues = { TEXT("8.0") }; + Aperture.RecommendedValues = { TEXT("1.4") }; Aperture.bRestrictToRecommended = false; // - Histogram --------------------------------------------- @@ -478,7 +478,7 @@ void UActorBlueprintFunctionLibrary::MakeCameraDefinition( FActorVariation ExposureMinBright; ExposureMinBright.Id = TEXT("exposure_min_bright"); ExposureMinBright.Type = EActorAttributeType::Float; - ExposureMinBright.RecommendedValues = { TEXT("0.1") }; + ExposureMinBright.RecommendedValues = { TEXT("7.0") }; ExposureMinBright.bRestrictToRecommended = false; // The maximum brightness for auto exposure that limits the upper @@ -486,7 +486,7 @@ void UActorBlueprintFunctionLibrary::MakeCameraDefinition( FActorVariation ExposureMaxBright; ExposureMaxBright.Id = TEXT("exposure_max_bright"); ExposureMaxBright.Type = EActorAttributeType::Float; - ExposureMaxBright.RecommendedValues = { TEXT("2.0") }; + ExposureMaxBright.RecommendedValues = { TEXT("9.0") }; ExposureMaxBright.bRestrictToRecommended = false; // The speed at which the adaptation occurs from a dark environment @@ -1389,8 +1389,8 @@ void UActorBlueprintFunctionLibrary::SetCamera( RetrieveActorAttributeToFloat("lens_flare_intensity", Description.Variations, 0.1f)); Camera->SetBloomIntensity( RetrieveActorAttributeToFloat("bloom_intensity", Description.Variations, 0.675f)); - // Exposure - if (RetrieveActorAttributeToString("exposure_mode", Description.Variations, "manual") == "histogram") + // Exposure, histogram mode by default + if (RetrieveActorAttributeToString("exposure_mode", Description.Variations, "histogram") == "histogram") { Camera->SetExposureMethod(EAutoExposureMethod::AEM_Histogram); } @@ -1399,18 +1399,18 @@ void UActorBlueprintFunctionLibrary::SetCamera( Camera->SetExposureMethod(EAutoExposureMethod::AEM_Manual); } Camera->SetExposureCompensation( - RetrieveActorAttributeToFloat("exposure_compensation", Description.Variations, -2.2f)); + RetrieveActorAttributeToFloat("exposure_compensation", Description.Variations, 0.0f)); Camera->SetShutterSpeed( RetrieveActorAttributeToFloat("shutter_speed", Description.Variations, 200.0f)); Camera->SetISO( - RetrieveActorAttributeToFloat("iso", Description.Variations, 200.0f)); + RetrieveActorAttributeToFloat("iso", Description.Variations, 100.0f)); Camera->SetAperture( - RetrieveActorAttributeToFloat("fstop", Description.Variations, 8.0f)); + RetrieveActorAttributeToFloat("fstop", Description.Variations, 1.4f)); Camera->SetExposureMinBrightness( - RetrieveActorAttributeToFloat("exposure_min_bright", Description.Variations, 0.1f)); + RetrieveActorAttributeToFloat("exposure_min_bright", Description.Variations, 7.0f)); Camera->SetExposureMaxBrightness( - RetrieveActorAttributeToFloat("exposure_max_bright", Description.Variations, 2.0f)); + RetrieveActorAttributeToFloat("exposure_max_bright", Description.Variations, 9.0f)); Camera->SetExposureSpeedUp( RetrieveActorAttributeToFloat("exposure_speed_up", Description.Variations, 3.0f)); Camera->SetExposureSpeedDown( diff --git a/Unreal/CarlaUE4/Plugins/Carla/Source/Carla/Actor/ActorInfo.h b/Unreal/CarlaUE4/Plugins/Carla/Source/Carla/Actor/ActorInfo.h index 9f407ea59..8b0e9aac7 100644 --- a/Unreal/CarlaUE4/Plugins/Carla/Source/Carla/Actor/ActorInfo.h +++ b/Unreal/CarlaUE4/Plugins/Carla/Source/Carla/Actor/ActorInfo.h @@ -11,8 +11,11 @@ #include #include +#include #include +namespace crp = carla::rpc; + /// A view over an actor and its properties. struct FActorInfo { @@ -20,11 +23,11 @@ public: FActorDescription Description; - TSet SemanticTags; + TSet SemanticTags; FBoundingBox BoundingBox; - carla::rpc::Actor SerializedData; + crp::Actor SerializedData; /// @todo To be used solely by the FWorldObserver. mutable FVector Velocity = {0.0f, 0.0f, 0.0f}; diff --git a/Unreal/CarlaUE4/Plugins/Carla/Source/Carla/Actor/ActorRegistry.cpp b/Unreal/CarlaUE4/Plugins/Carla/Source/Carla/Actor/ActorRegistry.cpp index a62a64806..953ef3447 100644 --- a/Unreal/CarlaUE4/Plugins/Carla/Source/Carla/Actor/ActorRegistry.cpp +++ b/Unreal/CarlaUE4/Plugins/Carla/Source/Carla/Actor/ActorRegistry.cpp @@ -13,6 +13,8 @@ #include "Carla/Traffic/TrafficLightBase.h" #include "Carla/Util/BoundingBoxCalculator.h" +namespace crp = carla::rpc; + static FActorView::ActorType FActorRegistry_GetActorType(const FActorView &View) { if (!View.IsValid()) @@ -41,11 +43,11 @@ static FActorView::ActorType FActorRegistry_GetActorType(const FActorView &View) } } -static FString GetRelevantTagAsString(const TSet &SemanticTags) +static FString GetRelevantTagAsString(const TSet &SemanticTags) { for (auto &&Tag : SemanticTags) { - if ((Tag != ECityObjectLabel::None) && (Tag != ECityObjectLabel::Other)) + if ((Tag != crp::CityObjectLabel::None) && (Tag != crp::CityObjectLabel::Other)) { auto Str = ATagger::GetTagAsString(Tag).ToLower(); return (Str.EndsWith(TEXT("s")) ? Str.LeftChop(1) : Str); diff --git a/Unreal/CarlaUE4/Plugins/Carla/Source/Carla/Actor/StaticMeshFactory.cpp b/Unreal/CarlaUE4/Plugins/Carla/Source/Carla/Actor/StaticMeshFactory.cpp new file mode 100644 index 000000000..89decab33 --- /dev/null +++ b/Unreal/CarlaUE4/Plugins/Carla/Source/Carla/Actor/StaticMeshFactory.cpp @@ -0,0 +1,64 @@ +// 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 . + +#include "StaticMeshFactory.h" +#include "Carla/Actor/ActorBlueprintFunctionLibrary.h" +#include "Engine/StaticMeshActor.h" +#include "Carla/Game/CarlaEpisode.h" + +TArray AStaticMeshFactory::GetDefinitions() +{ + using ABFL = UActorBlueprintFunctionLibrary; + auto StaticMeshDefinition = ABFL::MakeGenericDefinition( + TEXT("static"), + TEXT("prop"), + TEXT("mesh")); + StaticMeshDefinition.Class = AStaticMeshActor::StaticClass(); + return { StaticMeshDefinition }; +} + +FActorSpawnResult AStaticMeshFactory::SpawnActor( + const FTransform &SpawnAtTransform, + const FActorDescription &ActorDescription) +{ + using ABFL = UActorBlueprintFunctionLibrary; + auto *World = GetWorld(); + if (World == nullptr) + { + UE_LOG(LogCarla, Error, TEXT + ("AStaticMeshFactory: cannot spawn mesh into an empty world.")); + return {}; + } + + FActorSpawnParameters SpawnParameters; + SpawnParameters.SpawnCollisionHandlingOverride = + ESpawnActorCollisionHandlingMethod::AlwaysSpawn; + auto *StaticMeshActor = World->SpawnActor( + ActorDescription.Class, SpawnAtTransform, SpawnParameters); + + auto *StaticMeshComponent = Cast( + StaticMeshActor->GetRootComponent()); + if (StaticMeshComponent) + { + if (ActorDescription.Variations.Contains("mesh_path") && + ActorDescription.Variations.Contains("mass")) + { + FString MeshPath = ABFL::ActorAttributeToString( + ActorDescription.Variations["mesh_path"], ""); + UObject* MeshObject = StaticLoadObject(UStaticMesh::StaticClass(), + nullptr, + *(MeshPath)); + UStaticMesh *Mesh = Cast(MeshObject); + StaticMeshComponent->SetMobility(EComponentMobility::Movable); + StaticMeshComponent->SetStaticMesh(Mesh); + StaticMeshComponent->SetSimulatePhysics(true); + StaticMeshComponent->SetCollisionProfileName("PhysicsActor"); + StaticMeshComponent->SetMassOverrideInKg("", + ABFL::ActorAttributeToFloat(ActorDescription.Variations["mass"], 1.0f)); + } + } + return FActorSpawnResult(StaticMeshActor); +} diff --git a/Unreal/CarlaUE4/Plugins/Carla/Source/Carla/Actor/StaticMeshFactory.h b/Unreal/CarlaUE4/Plugins/Carla/Source/Carla/Actor/StaticMeshFactory.h new file mode 100644 index 000000000..3d65fdf49 --- /dev/null +++ b/Unreal/CarlaUE4/Plugins/Carla/Source/Carla/Actor/StaticMeshFactory.h @@ -0,0 +1,27 @@ +// 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 . + +#pragma once + +#include "Carla/Actor/ActorSpawnResult.h" +#include "Carla/Actor/CarlaActorFactory.h" + +#include "StaticMeshFactory.generated.h" + +/// Factory in charge of spawning static meshes. This factory is able to spawn +/// any mesh in content. +UCLASS() +class CARLA_API AStaticMeshFactory : public ACarlaActorFactory +{ + GENERATED_BODY() + + /// Retrieve the definitions of the static mesh actor + TArray GetDefinitions() final; + + FActorSpawnResult SpawnActor( + const FTransform &SpawnAtTransform, + const FActorDescription &ActorDescription) final; +}; diff --git a/Unreal/CarlaUE4/Plugins/Carla/Source/Carla/CityMapGenerator.cpp b/Unreal/CarlaUE4/Plugins/Carla/Source/Carla/CityMapGenerator.cpp index d4cb13f85..1e92bcfc2 100644 --- a/Unreal/CarlaUE4/Plugins/Carla/Source/Carla/CityMapGenerator.cpp +++ b/Unreal/CarlaUE4/Plugins/Carla/Source/Carla/CityMapGenerator.cpp @@ -22,6 +22,8 @@ #include #endif // CARLA_ROAD_GENERATOR_EXTRA_LOG +namespace crp = carla::rpc; + // ============================================================================= // -- Private types ------------------------------------------------------------ // ============================================================================= @@ -248,7 +250,7 @@ static bool LineTrace( if (Success) { for (FHitResult &Item : OutHits) { - if (ATagger::MatchComponent(*Item.Component, ECityObjectLabel::Roads)) { + if (ATagger::MatchComponent(*Item.Component, crp::CityObjectLabel::Roads)) { HitResult = Item; return true; } diff --git a/Unreal/CarlaUE4/Plugins/Carla/Source/Carla/Game/CarlaEngine.cpp b/Unreal/CarlaUE4/Plugins/Carla/Source/Carla/Game/CarlaEngine.cpp index c7c2ac374..3774c5e65 100644 --- a/Unreal/CarlaUE4/Plugins/Carla/Source/Carla/Game/CarlaEngine.cpp +++ b/Unreal/CarlaUE4/Plugins/Carla/Source/Carla/Game/CarlaEngine.cpp @@ -10,6 +10,7 @@ #include "Carla/Game/CarlaEpisode.h" #include "Carla/Game/CarlaStaticDelegates.h" #include "Carla/Lights/CarlaLightSubsystem.h" +#include "Carla/Recorder/CarlaRecorder.h" #include "Carla/Settings/CarlaSettings.h" #include "Carla/Settings/EpisodeSettings.h" @@ -82,6 +83,15 @@ void FCarlaEngine::NotifyBeginEpisode(UCarlaEpisode &Episode) { Episode.EpisodeSettings.FixedDeltaSeconds = FCarlaEngine_GetFixedDeltaSeconds(); CurrentEpisode = &Episode; + + // make connection between Episode and Recorder + if (Recorder) + { + Recorder->SetEpisode(&Episode); + Episode.SetRecorder(Recorder); + Recorder->GetReplayer()->CheckPlayAfterMapLoaded(); + } + Server.NotifyBeginEpisode(Episode); } diff --git a/Unreal/CarlaUE4/Plugins/Carla/Source/Carla/Game/CarlaEngine.h b/Unreal/CarlaUE4/Plugins/Carla/Source/Carla/Game/CarlaEngine.h index 986d82bca..5625fd1f5 100644 --- a/Unreal/CarlaUE4/Plugins/Carla/Source/Carla/Game/CarlaEngine.h +++ b/Unreal/CarlaUE4/Plugins/Carla/Source/Carla/Game/CarlaEngine.h @@ -6,6 +6,7 @@ #pragma once +#include "Carla/Recorder/CarlaRecorder.h" #include "Carla/Sensor/WorldObserver.h" #include "Carla/Server/CarlaServer.h" #include "Carla/Util/NonCopyable.h" @@ -37,6 +38,11 @@ public: return CurrentEpisode; } + void SetRecorder(ACarlaRecorder *InRecorder) + { + Recorder = InRecorder; + } + private: void OnPreTick(UWorld *World, ELevelTick TickType, float DeltaSeconds); @@ -59,6 +65,8 @@ private: UCarlaEpisode *CurrentEpisode = nullptr; + ACarlaRecorder *Recorder = nullptr; + FDelegateHandle OnPreTickHandle; FDelegateHandle OnPostTickHandle; diff --git a/Unreal/CarlaUE4/Plugins/Carla/Source/Carla/Game/CarlaEpisode.cpp b/Unreal/CarlaUE4/Plugins/Carla/Source/Carla/Game/CarlaEpisode.cpp index 2a7f81da1..e9518b8eb 100644 --- a/Unreal/CarlaUE4/Plugins/Carla/Source/Carla/Game/CarlaEpisode.cpp +++ b/Unreal/CarlaUE4/Plugins/Carla/Source/Carla/Game/CarlaEpisode.cpp @@ -299,6 +299,18 @@ void UCarlaEpisode::InitializeAtBeginPlay() ActorDispatcher->RegisterActor(*Actor, Description); } + // get the definition id for static.prop.mesh + auto Definitions = GetActorDefinitions(); + uint32 StaticMeshUId = 0; + for (auto& Definition : Definitions) + { + if (Definition.Id == "static.prop.mesh") + { + StaticMeshUId = Definition.UId; + break; + } + } + for (TActorIterator It(World); It; ++It) { auto Actor = *It; @@ -308,8 +320,15 @@ void UCarlaEpisode::InitializeAtBeginPlay() if (MeshComponent->Mobility == EComponentMobility::Movable) { FActorDescription Description; - Description.Id = TEXT("static.prop"); + Description.Id = TEXT("static.prop.mesh"); + Description.UId = StaticMeshUId; Description.Class = Actor->GetClass(); + Description.Variations.Add("mesh_path", + FActorAttribute{"mesh_path", EActorAttributeType::String, + MeshComponent->GetStaticMesh()->GetPathName()}); + Description.Variations.Add("mass", + FActorAttribute{"mass", EActorAttributeType::Float, + FString::SanitizeFloat(MeshComponent->GetMass())}); ActorDispatcher->RegisterActor(*Actor, Description); } } diff --git a/Unreal/CarlaUE4/Plugins/Carla/Source/Carla/Game/CarlaGameInstance.cpp b/Unreal/CarlaUE4/Plugins/Carla/Source/Carla/Game/CarlaGameInstance.cpp index 0c03ada25..80a1bb45f 100644 --- a/Unreal/CarlaUE4/Plugins/Carla/Source/Carla/Game/CarlaGameInstance.cpp +++ b/Unreal/CarlaUE4/Plugins/Carla/Source/Carla/Game/CarlaGameInstance.cpp @@ -11,6 +11,9 @@ UCarlaGameInstance::UCarlaGameInstance() { CarlaSettings = CreateDefaultSubobject(TEXT("CarlaSettings")); + Recorder = CreateDefaultSubobject(TEXT("Recorder")); + CarlaEngine.SetRecorder(Recorder); + check(CarlaSettings != nullptr); CarlaSettings->LoadSettings(); CarlaSettings->LogSettings(); diff --git a/Unreal/CarlaUE4/Plugins/Carla/Source/Carla/Game/CarlaGameInstance.h b/Unreal/CarlaUE4/Plugins/Carla/Source/Carla/Game/CarlaGameInstance.h index c8331b393..8fc2ed05e 100644 --- a/Unreal/CarlaUE4/Plugins/Carla/Source/Carla/Game/CarlaGameInstance.h +++ b/Unreal/CarlaUE4/Plugins/Carla/Source/Carla/Game/CarlaGameInstance.h @@ -9,8 +9,13 @@ #include "Engine/GameInstance.h" #include "Carla/Game/CarlaEngine.h" +#include "Carla/Recorder/CarlaRecorder.h" #include "Carla/Server/CarlaServer.h" +#include +#include +#include + #include "CarlaGameInstance.generated.h" class UCarlaSettings; @@ -74,12 +79,14 @@ public: } void SetOpendriveGenerationParameters( - const carla::rpc::OpendriveGenerationParameters & Parameters) { + const carla::rpc::OpendriveGenerationParameters & Parameters) + { GenerationParameters = Parameters; } const carla::rpc::OpendriveGenerationParameters& - GetOpendriveGenerationParameters() const { + GetOpendriveGenerationParameters() const + { return GenerationParameters; } @@ -90,6 +97,9 @@ private: FCarlaEngine CarlaEngine; + UPROPERTY() + ACarlaRecorder *Recorder = nullptr; + carla::rpc::OpendriveGenerationParameters GenerationParameters; }; diff --git a/Unreal/CarlaUE4/Plugins/Carla/Source/Carla/Game/CarlaGameModeBase.cpp b/Unreal/CarlaUE4/Plugins/Carla/Source/Carla/Game/CarlaGameModeBase.cpp index 9c615b3d6..fba24c8ba 100644 --- a/Unreal/CarlaUE4/Plugins/Carla/Source/Carla/Game/CarlaGameModeBase.cpp +++ b/Unreal/CarlaUE4/Plugins/Carla/Source/Carla/Game/CarlaGameModeBase.cpp @@ -42,57 +42,6 @@ ACarlaGameModeBase::ACarlaGameModeBase(const FObjectInitializer& ObjectInitializ CarlaSettingsDelegate = CreateDefaultSubobject(TEXT("CarlaSettingsDelegate")); } -void ACarlaGameModeBase::AddSceneCaptureSensor(ASceneCaptureSensor* SceneCaptureSensor) -{ - uint32 ImageWidth = SceneCaptureSensor->ImageWidth; - uint32 ImageHeight = SceneCaptureSensor->ImageHeight; - - if(AtlasTextureWidth < ImageWidth) - { - IsAtlasTextureValid = false; - AtlasTextureWidth = ImageWidth; - } - - if(AtlasTextureHeight < (CurrentAtlasTextureHeight + ImageHeight) ) - { - IsAtlasTextureValid = false; - AtlasTextureHeight = CurrentAtlasTextureHeight + ImageHeight; - } - - SceneCaptureSensor->PositionInAtlas = FIntVector(0, CurrentAtlasTextureHeight, 0); - CurrentAtlasTextureHeight += ImageHeight; - - SceneCaptureSensors.Add(SceneCaptureSensor); - - UE_LOG(LogCarla, Warning, TEXT("ACarlaGameModeBase::AddSceneCaptureSensor %d %dx%d"), SceneCaptureSensors.Num(), AtlasTextureWidth, AtlasTextureHeight); -} - -void ACarlaGameModeBase::RemoveSceneCaptureSensor(ASceneCaptureSensor* SceneCaptureSensor) -{ - FlushRenderingCommands(); - - // Remove camera - SceneCaptureSensors.Remove(SceneCaptureSensor); - - // Recalculate PositionInAtlas for each camera - AtlasTextureWidth = 0u; - CurrentAtlasTextureHeight = 0u; - for(ASceneCaptureSensor* Camera : SceneCaptureSensors) - { - Camera->PositionInAtlas = FIntVector(0, CurrentAtlasTextureHeight, 0); - CurrentAtlasTextureHeight += Camera->ImageHeight; - - if(AtlasTextureWidth < Camera->ImageWidth) - { - AtlasTextureWidth = Camera->ImageWidth; - } - - } - AtlasTextureHeight = CurrentAtlasTextureHeight; - - IsAtlasTextureValid = false; -} - void ACarlaGameModeBase::InitGame( const FString &MapName, const FString &Options, @@ -204,9 +153,6 @@ void ACarlaGameModeBase::BeginPlay() { Recorder->GetReplayer()->CheckPlayAfterMapLoaded(); } - - CaptureAtlasDelegate = FCoreDelegates::OnEndFrame.AddUObject(this, &ACarlaGameModeBase::CaptureAtlas); - } void ACarlaGameModeBase::Tick(float DeltaSeconds) @@ -218,8 +164,6 @@ void ACarlaGameModeBase::Tick(float DeltaSeconds) { Recorder->Tick(DeltaSeconds); } - - SendAtlas(); } void ACarlaGameModeBase::EndPlay(const EEndPlayReason::Type EndPlayReason) @@ -233,8 +177,6 @@ void ACarlaGameModeBase::EndPlay(const EEndPlayReason::Type EndPlayReason) { CarlaSettingsDelegate->Reset(); } - - FCoreDelegates::OnEndFrame.Remove(CaptureAtlasDelegate); } void ACarlaGameModeBase::SpawnActorFactories() @@ -390,89 +332,16 @@ void ACarlaGameModeBase::DebugShowSignals(bool enable) } -void ACarlaGameModeBase::CreateAtlasTextures() +TArray ACarlaGameModeBase::GetAllBBsOfLevel(uint8 TagQueried) { - if(AtlasTextureWidth > 0 && AtlasTextureHeight > 0) - { - FRHIResourceCreateInfo CreateInfo; - CamerasAtlasTexture = RHICreateTexture2D(AtlasTextureWidth, AtlasTextureHeight, PF_B8G8R8A8, 1, 1, TexCreate_CPUReadback, CreateInfo); + UWorld* World = GetWorld(); - AtlasImage.Init(FColor(), AtlasTextureWidth * AtlasTextureHeight); + // Get all actors of the level + TArray FoundActors; + UGameplayStatics::GetAllActorsOfClass(World, AActor::StaticClass(), FoundActors); - IsAtlasTextureValid = true; - } + TArray BoundingBoxes; + BoundingBoxes = UBoundingBoxCalculator::GetBoundingBoxOfActors(FoundActors, TagQueried); + + return BoundingBoxes; } - -void ACarlaGameModeBase::CaptureAtlas() -{ - - ACarlaGameModeBase* This = this; - - if(!SceneCaptureSensors.Num()) return; - - // Be sure that the atlas texture is ready - if(!IsAtlasTextureValid) - { - CreateAtlasTextures(); - return; - } - - // Enqueue the commands to copy the captures to the atlas - for(ASceneCaptureSensor* Sensor : SceneCaptureSensors) - { - Sensor->CopyTextureToAtlas(); - } - - // Download Atlas texture - ENQUEUE_RENDER_COMMAND(ACarlaGameModeBase_CaptureAtlas) - ( - [This](FRHICommandListImmediate& RHICmdList) mutable - { - FTexture2DRHIRef AtlasTexture = This->CamerasAtlasTexture; - - if (!AtlasTexture) - { - UE_LOG(LogCarla, Error, TEXT("ACarlaGameModeBase::CaptureAtlas: Missing atlas texture")); - return; - } - - FIntRect Rect = FIntRect(0, 0, This->AtlasTextureWidth, This->AtlasTextureHeight); - -#if !UE_BUILD_SHIPPING - if(This->ReadSurfaceMode == 2) Rect = FIntRect(0, 0, This->SurfaceW, This->SurfaceH); -#endif - -#if !UE_BUILD_SHIPPING - if (This->ReadSurfaceMode == 0) return; -#endif - - SCOPE_CYCLE_COUNTER(STAT_CarlaSensorReadRT); - RHICmdList.ReadSurfaceData( - AtlasTexture, - Rect, - This->AtlasImage, - FReadSurfaceDataFlags(RCM_UNorm, CubeFace_MAX)); - - } - ); - - -} - -void ACarlaGameModeBase::SendAtlas() -{ - -#if !UE_BUILD_SHIPPING - if(!AtlasCopyToCamera) - { - return; - } -#endif - - for(int32 Index = 0; Index < SceneCaptureSensors.Num(); Index++) - { - ASceneCaptureSensor* Sensor = SceneCaptureSensors[Index]; - Sensor->SendPixels(AtlasImage, AtlasTextureWidth); - } - -} \ No newline at end of file diff --git a/Unreal/CarlaUE4/Plugins/Carla/Source/Carla/Game/CarlaGameModeBase.h b/Unreal/CarlaUE4/Plugins/Carla/Source/Carla/Game/CarlaGameModeBase.h index d87aa1dbe..e000cee70 100644 --- a/Unreal/CarlaUE4/Plugins/Carla/Source/Carla/Game/CarlaGameModeBase.h +++ b/Unreal/CarlaUE4/Plugins/Carla/Source/Carla/Game/CarlaGameModeBase.h @@ -52,74 +52,8 @@ public: UFUNCTION(BlueprintCallable, Category = "CARLA Game Mode") ATrafficLightManager* GetTrafficLightManager(); - void AddSceneCaptureSensor(ASceneCaptureSensor* SceneCaptureSensor); - - void RemoveSceneCaptureSensor(ASceneCaptureSensor* SceneCaptureSensor); - - bool IsCameraAtlasTextureValid() const - { - return IsAtlasTextureValid; - } - - FTexture2DRHIRef GetCurrentCamerasAtlasTexture() const{ - return CamerasAtlasTexture; - } - - uint32 GetAtlasTextureWidth() const { - return AtlasTextureWidth; - } - - uint32 GetAtlasTextureHeight() const { - return AtlasTextureHeight; - } - - UFUNCTION(Exec) - void SwitchReadSurfaceMode(uint32 Mode) { -#if !UE_BUILD_SHIPPING - ReadSurfaceMode = Mode; -#endif - } - - UFUNCTION(Exec) - void SetAtlasSurface(uint32 W, uint32 H) { -#if !UE_BUILD_SHIPPING - SurfaceW = W; - SurfaceH = H; -#endif - } - - UFUNCTION(Exec) - void EnableCameraCopyToAtlas(bool Enable) { -#if !UE_BUILD_SHIPPING - CameraCopyToAtlasEnable = Enable; -#endif - } - - UFUNCTION(Exec) - void EnableAtlasCopyToCamera(bool Enable) { -#if !UE_BUILD_SHIPPING - AtlasCopyToCamera = Enable; -#endif - } - - UFUNCTION(Exec) - void EnableCameraStream(bool Enable) { -#if !UE_BUILD_SHIPPING - CameraStreamEnable = Enable; -#endif - } - -#if !UE_BUILD_SHIPPING - - bool IsCameraCopyToAtlasEnabled() const { - return CameraCopyToAtlasEnable; - } - - bool IsCameraStreamEnabled() const { - return CameraStreamEnable; - } - -#endif + UFUNCTION(Category = "Carla Game Mode", BlueprintCallable, CallInEditor, Exec) + TArray GetAllBBsOfLevel(uint8 TagQueried = 0); protected: @@ -139,12 +73,6 @@ private: void ParseOpenDrive(const FString &MapName); - void CreateAtlasTextures(); - - void CaptureAtlas(); - - void SendAtlas(); - UPROPERTY() UCarlaGameInstance *GameInstance = nullptr; @@ -158,7 +86,7 @@ private: UCarlaEpisode *Episode = nullptr; UPROPERTY() - ACarlaRecorder *Recorder = nullptr; + ACarlaRecorder *Recorder = nullptr; /// The class of Weather to spawn. UPROPERTY(Category = "CARLA Game Mode", EditAnywhere) @@ -177,23 +105,4 @@ private: boost::optional Map; - FDelegateHandle CaptureAtlasDelegate; - - TArray SceneCaptureSensors; - FTexture2DRHIRef CamerasAtlasTexture; - TArray AtlasImage; - uint32 AtlasTextureWidth = 0u; - uint32 AtlasTextureHeight = 0u; - uint32 CurrentAtlasTextureHeight = 0u; - bool IsAtlasTextureValid = false; - -#if !UE_BUILD_SHIPPING - uint32 ReadSurfaceMode = 1; - uint32 SurfaceW = 0; - uint32 SurfaceH = 0; - bool CameraCopyToAtlasEnable = true; - bool AtlasCopyToCamera = true; - bool CameraStreamEnable = true; -#endif - }; diff --git a/Unreal/CarlaUE4/Plugins/Carla/Source/Carla/Game/Tagger.cpp b/Unreal/CarlaUE4/Plugins/Carla/Source/Carla/Game/Tagger.cpp index 89b8b4a49..e214af2e4 100644 --- a/Unreal/CarlaUE4/Plugins/Carla/Source/Carla/Game/Tagger.cpp +++ b/Unreal/CarlaUE4/Plugins/Carla/Source/Carla/Game/Tagger.cpp @@ -14,39 +14,48 @@ #include "EngineUtils.h" #include "PhysicsEngine/PhysicsAsset.h" +namespace crp = carla::rpc; + template static auto CastEnum(T label) { return static_cast::type>(label); } -ECityObjectLabel ATagger::GetLabelByFolderName(const FString &String) { - if (String == "Buildings") return ECityObjectLabel::Buildings; - else if (String == "Fences") return ECityObjectLabel::Fences; - else if (String == "Pedestrians") return ECityObjectLabel::Pedestrians; - else if (String == "Pole") return ECityObjectLabel::Poles; - else if (String == "Props") return ECityObjectLabel::Other; - else if (String == "Road") return ECityObjectLabel::Roads; - else if (String == "RoadLines") return ECityObjectLabel::RoadLines; - else if (String == "SideWalk") return ECityObjectLabel::Sidewalks; - else if (String == "TrafficSigns") return ECityObjectLabel::TrafficSigns; - else if (String == "Vegetation") return ECityObjectLabel::Vegetation; - else if (String == "Vehicles") return ECityObjectLabel::Vehicles; - else if (String == "Walls") return ECityObjectLabel::Walls; - else if (String == "Sky") return ECityObjectLabel::Sky; - else if (String == "Ground") return ECityObjectLabel::Ground; - else if (String == "Bridge") return ECityObjectLabel::Bridge; - else return ECityObjectLabel::None; +crp::CityObjectLabel ATagger::GetLabelByFolderName(const FString &String) { + if (String == "Building") return crp::CityObjectLabel::Buildings; + else if (String == "Fence") return crp::CityObjectLabel::Fences; + else if (String == "Pedestrian") return crp::CityObjectLabel::Pedestrians; + else if (String == "Pole") return crp::CityObjectLabel::Poles; + else if (String == "Other") return crp::CityObjectLabel::Other; + else if (String == "Road") return crp::CityObjectLabel::Roads; + else if (String == "RoadLine") return crp::CityObjectLabel::RoadLines; + else if (String == "SideWalk") return crp::CityObjectLabel::Sidewalks; + else if (String == "TrafficSign") return crp::CityObjectLabel::TrafficSigns; + else if (String == "Vegetation") return crp::CityObjectLabel::Vegetation; + else if (String == "Vehicles") return crp::CityObjectLabel::Vehicles; + else if (String == "Wall") return crp::CityObjectLabel::Walls; + else if (String == "Sky") return crp::CityObjectLabel::Sky; + else if (String == "Ground") return crp::CityObjectLabel::Ground; + else if (String == "Bridge") return crp::CityObjectLabel::Bridge; + else if (String == "RailTrack") return crp::CityObjectLabel::RailTrack; + else if (String == "GuardRail") return crp::CityObjectLabel::GuardRail; + else if (String == "TrafficLight") return crp::CityObjectLabel::TrafficLight; + else if (String == "Static") return crp::CityObjectLabel::Static; + else if (String == "Dynamic") return crp::CityObjectLabel::Dynamic; + else if (String == "Water") return crp::CityObjectLabel::Water; + else if (String == "Terrain") return crp::CityObjectLabel::Terrain; + else return crp::CityObjectLabel::None; } void ATagger::SetStencilValue( UPrimitiveComponent &Component, - const ECityObjectLabel &Label, + const crp::CityObjectLabel &Label, const bool bSetRenderCustomDepth) { Component.SetCustomDepthStencilValue(CastEnum(Label)); Component.SetRenderCustomDepth( bSetRenderCustomDepth && - (Label != ECityObjectLabel::None)); + (Label != crp::CityObjectLabel::None)); } // ============================================================================= @@ -91,24 +100,24 @@ void ATagger::TagActorsInLevel(UWorld &World, bool bTagForSemanticSegmentation) } } -void ATagger::GetTagsOfTaggedActor(const AActor &Actor, TSet &Tags) +void ATagger::GetTagsOfTaggedActor(const AActor &Actor, TSet &Tags) { TArray Components; Actor.GetComponents(Components); for (auto *Component : Components) { if (Component != nullptr) { const auto Tag = GetTagOfTaggedComponent(*Component); - if (Tag != ECityObjectLabel::None) { + if (Tag != crp::CityObjectLabel::None) { Tags.Add(Tag); } } } } -FString ATagger::GetTagAsString(const ECityObjectLabel Label) +FString ATagger::GetTagAsString(const crp::CityObjectLabel Label) { switch (Label) { -#define CARLA_GET_LABEL_STR(lbl) case ECityObjectLabel:: lbl : return TEXT(#lbl); +#define CARLA_GET_LABEL_STR(lbl) case crp::CityObjectLabel:: lbl : return TEXT(#lbl); default: CARLA_GET_LABEL_STR(None) CARLA_GET_LABEL_STR(Buildings) @@ -126,6 +135,13 @@ FString ATagger::GetTagAsString(const ECityObjectLabel Label) CARLA_GET_LABEL_STR(Sky) CARLA_GET_LABEL_STR(Ground) CARLA_GET_LABEL_STR(Bridge) + CARLA_GET_LABEL_STR(RailTrack) + CARLA_GET_LABEL_STR(GuardRail) + CARLA_GET_LABEL_STR(TrafficLight) + CARLA_GET_LABEL_STR(Static) + CARLA_GET_LABEL_STR(Dynamic) + CARLA_GET_LABEL_STR(Water) + CARLA_GET_LABEL_STR(Terrain) #undef CARLA_GET_LABEL_STR } } diff --git a/Unreal/CarlaUE4/Plugins/Carla/Source/Carla/Game/Tagger.h b/Unreal/CarlaUE4/Plugins/Carla/Source/Carla/Game/Tagger.h index a15e188ac..5c8e578c5 100644 --- a/Unreal/CarlaUE4/Plugins/Carla/Source/Carla/Game/Tagger.h +++ b/Unreal/CarlaUE4/Plugins/Carla/Source/Carla/Game/Tagger.h @@ -8,27 +8,14 @@ #include "GameFramework/Actor.h" #include "Components/PrimitiveComponent.h" + +#include +#include +#include + #include "Tagger.generated.h" -enum class ECityObjectLabel : uint8 -{ - 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, -}; +namespace crp = carla::rpc; /// Sets actors' custom depth stencil value for semantic segmentation according /// to their meshes. @@ -60,40 +47,40 @@ public: static void TagActorsInLevel(UWorld &World, bool bTagForSemanticSegmentation); /// Retrieve the tag of an already tagged component. - static ECityObjectLabel GetTagOfTaggedComponent(const UPrimitiveComponent &Component) + static crp::CityObjectLabel GetTagOfTaggedComponent(const UPrimitiveComponent &Component) { - return static_cast(Component.CustomDepthStencilValue); + return static_cast(Component.CustomDepthStencilValue); } - /// Retrieve the tags of an already tagged actor. ECityObjectLabel::None is + /// Retrieve the tags of an already tagged actor. CityObjectLabel::None is /// not added to the array. - static void GetTagsOfTaggedActor(const AActor &Actor, TSet &Tags); + static void GetTagsOfTaggedActor(const AActor &Actor, TSet &Tags); /// Return true if @a Component has been tagged with the given @a Tag. - static bool MatchComponent(const UPrimitiveComponent &Component, ECityObjectLabel Tag) + static bool MatchComponent(const UPrimitiveComponent &Component, crp::CityObjectLabel Tag) { return (Tag == GetTagOfTaggedComponent(Component)); } - /// Retrieve the tags of an already tagged actor. ECityObjectLabel::None is + /// Retrieve the tags of an already tagged actor. CityObjectLabel::None is /// not added to the array. - static FString GetTagAsString(ECityObjectLabel Tag); + static FString GetTagAsString(crp::CityObjectLabel Tag); /// Method that computes the label corresponding to a folder path - static ECityObjectLabel GetLabelByFolderName(const FString &String); + static crp::CityObjectLabel GetLabelByFolderName(const FString &String); /// Method that computes the label corresponding to an specific object /// using the folder path in which it is stored template - static ECityObjectLabel GetLabelByPath(const T *Object) { + static crp::CityObjectLabel GetLabelByPath(const T *Object) { const FString Path = Object->GetPathName(); TArray StringArray; Path.ParseIntoArray(StringArray, TEXT("/"), false); - return (StringArray.Num() > 4 ? GetLabelByFolderName(StringArray[4]) : ECityObjectLabel::None); + return (StringArray.Num() > 4 ? GetLabelByFolderName(StringArray[4]) : crp::CityObjectLabel::None); } static void SetStencilValue(UPrimitiveComponent &Component, - const ECityObjectLabel &Label, const bool bSetRenderCustomDepth); + const crp::CityObjectLabel &Label, const bool bSetRenderCustomDepth); ATagger(); diff --git a/Unreal/CarlaUE4/Plugins/Carla/Source/Carla/MapGen/ProceduralBuilding.cpp b/Unreal/CarlaUE4/Plugins/Carla/Source/Carla/MapGen/ProceduralBuilding.cpp new file mode 100644 index 000000000..ce5ca0c26 --- /dev/null +++ b/Unreal/CarlaUE4/Plugins/Carla/Source/Carla/MapGen/ProceduralBuilding.cpp @@ -0,0 +1,599 @@ +// Copyright (c) 2017 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 . + + +#include "ProceduralBuilding.h" + + +// Sets default values +AProceduralBuilding::AProceduralBuilding() +{ + // Set this actor to call Tick() every frame. You can turn this off to improve performance if you don't need it. + PrimaryActorTick.bCanEverTick = true; + + SideVisibility.Init(true, 4); + CornerVisibility.Init(true, 4); + UseWallMesh.Init(false, 4); + + UStaticMeshComponent* StaticMeshComponent = CreateDefaultSubobject(TEXT("RootComponent")); + RootComponent = StaticMeshComponent; +} + +UHierarchicalInstancedStaticMeshComponent* AProceduralBuilding::GetHISMComp( + const UStaticMesh* SM) +{ + + FString SMName = SM->GetName(); + + UHierarchicalInstancedStaticMeshComponent** HISMCompPtr = HISMComps.Find(SMName); + + if(HISMCompPtr) return *HISMCompPtr; + + UHierarchicalInstancedStaticMeshComponent* HISMComp = *HISMCompPtr; + + // If it doesn't exist, create the component + HISMComp = NewObject(this, + FName(*FString::Printf(TEXT("HISMComp_%d"), HISMComps.Num()))); + HISMComp->SetupAttachment(RootComponent); + HISMComp->RegisterComponent(); + + // Set the mesh that will be used + HISMComp->SetStaticMesh(const_cast(SM)); + + // Add to the map + HISMComps.Emplace(SMName, HISMComp); + + return HISMComp; +} + +void AProceduralBuilding::ConvertOldBP_ToNativeCodeObject(AActor* BP_Building) +{ + AProceduralBuilding* ProceduralBuilding = nullptr; + + // Look for all the HISMComps + TArray OtherHISMComps; + BP_Building->GetComponents(OtherHISMComps); + + for(UHierarchicalInstancedStaticMeshComponent* OtherHISMComp : OtherHISMComps) + { + const UStaticMesh* SM = OtherHISMComp->GetStaticMesh(); + + // Create a new HISMComp and set the SM + UHierarchicalInstancedStaticMeshComponent* NewHISMComp = GetHISMComp(SM); + + // Create the instances + const TArray& PerInstanceSMData = OtherHISMComp->PerInstanceSMData; + + for(const FInstancedStaticMeshInstanceData& InstSMIData : PerInstanceSMData) + { + FTransform Transform = FTransform(InstSMIData.Transform); + + NewHISMComp->AddInstance(Transform); + } + } + + // TODO: Look for all ChildActors -> Add new Child + TArray OtherChildComps; + BP_Building->GetComponents(OtherChildComps); + + for(const UChildActorComponent* OtherChildActor : OtherChildComps) + { + // Create a new ChildActorComponent + UChildActorComponent* ChildActorComp = NewObject(this, + FName(*FString::Printf(TEXT("ChildActorComp_%d"), ChildActorComps.Num() ))); + ChildActorComp->SetupAttachment(RootComponent); + + // Set the class that it will use + ChildActorComp->SetChildActorClass(OtherChildActor->GetChildActorClass()); + ChildActorComp->SetRelativeTransform(OtherChildActor->GetRelativeTransform()); + + // Spawns the actor referenced by UChildActorComponent + ChildActorComp->RegisterComponent(); + + AActor* NewChildActor = ChildActorComp->GetChildActor(); + +#if WITH_EDITOR + // Add the child actor to a subfolder of the actor's name + NewChildActor->SetFolderPath(FName( *FString::Printf(TEXT("/Buildings/%s"), *GetName()))); + #endif + + // Look for all the SMComps + TArray NewSMComps; + NewChildActor->GetComponents(NewSMComps); + + // Make it invisible on the child actor to avoid duplication with the HISMComp + UStaticMeshComponent* PivotSMComp = NewSMComps[0]; + PivotSMComp->SetVisibility(false, false); + + ChildActorComps.Emplace(ChildActorComp); + + } +} + +void AProceduralBuilding::SetBaseParameters( + const TSet& InDoorsIndexPosition, + const TArray& InUseWallMesh, + int InNumFloors, + int InLengthX, + int InLengthY, + bool InCorners, + bool InUseFullBlocks) +{ + DoorsIndexPosition = InDoorsIndexPosition; + UseWallMesh = InUseWallMesh; + NumFloors = InNumFloors; + LengthX = InLengthX; + LengthY = InLengthY; + Corners = InCorners; + UseFullBlocks = InUseFullBlocks; +} + +void AProceduralBuilding::SetVisibilityParameters( + const TArray& InSideVisibility, + const TArray& InCornerVisibility, + bool InRoofVisibility) +{ + SideVisibility = InSideVisibility; + CornerVisibility = InCornerVisibility; + RoofVisibility = InRoofVisibility; +} + +void AProceduralBuilding::SetBaseMeshes( + const TArray& InBaseMeshes, + const TArray>& InBaseBPs, + const TArray& InCornerBaseMeshes, + const TArray>& InCornerBaseBPs, + const TArray& InDoorMeshes, + const TArray>& InDoorBPs) +{ + BaseMeshes = InBaseMeshes; + BaseBPs = InBaseBPs; + CornerBaseMeshes = InCornerBaseMeshes; + CornerBaseBPs = InCornerBaseBPs; + DoorMeshes = InDoorMeshes; + DoorBPs = InDoorBPs; +} + +void AProceduralBuilding::SetBodyMeshes( + const TArray& InBodyMeshes, + const TArray>& InBodyBPs, + const TArray& InCornerBodyMeshes, + const TArray>& InCornerBodyBPs, + const TArray& InWallMeshes, + const TArray>& InWallBPs) +{ + BodyMeshes = InBodyMeshes; + BodyBPs = InBodyBPs; + CornerBodyMeshes = InCornerBodyMeshes; + CornerBodyBPs = InCornerBodyBPs; + WallMeshes = InWallMeshes; + WallBPs = InWallBPs; +} + +void AProceduralBuilding::SetTopMeshes( + const TArray& InTopMeshes, + const TArray>& InTopBPs, + const TArray& InCornerTopMeshes, + const TArray>& InCornerTopBPs, + const TArray& InRoofMeshes, + const TArray>& InRoofBPs) +{ + TopMeshes = InTopMeshes; + TopBPs = InTopBPs; + CornerTopMeshes = InCornerTopMeshes; + CornerTopBPs = InCornerTopBPs; + RoofMeshes = InRoofMeshes; + RoofBPs = InRoofBPs; +} + +void AProceduralBuilding::CreateBuilding() +{ + Init(); + + // Base Floor + CreateFloor( + { &BaseMeshes, &BaseBPs, &CornerBaseMeshes, &CornerBaseBPs, &DoorMeshes, &DoorBPs }, + true, + false); + + // Body floors + const FloorMeshCollection BodyMeshCollection = + { &BodyMeshes, &BodyBPs, &CornerBodyMeshes, &CornerBodyBPs, &WallMeshes, &WallBPs }; + for(int i = 0; i < NumFloors; i++) + { + CreateFloor(BodyMeshCollection, false, true); + } + + // Top floor + CreateFloor( + { &TopMeshes, &TopBPs, &CornerTopMeshes, &CornerTopBPs }, + false, + false); + + // Roof + CreateRoof(); + +} + +void AProceduralBuilding::Reset() +{ + CurrentTransform = FTransform::Identity; + + // Discard previous calculation + SidesLength.Reset(); + + const TSet Comps = GetComponents(); + + // Remove all the instances of each HISMComp + for(auto& It : HISMComps) + { + const FString& MeshName = It.Key; + UHierarchicalInstancedStaticMeshComponent* HISMComp = It.Value; + + HISMComp->ClearInstances(); + } + // Empties out the map but preserves all allocations and capacities + HISMComps.Reset(); + + // Remove all child actors + for(UChildActorComponent* ChildActorComp : ChildActorComps) + { + if(ChildActorComp) + { + ChildActorComp->DestroyComponent(); + } + } + ChildActorComps.Reset(); + +} + +void AProceduralBuilding::Init() +{ + Reset(); + + CalculateSidesLength(); +} + +void AProceduralBuilding::CreateFloor( + const FloorMeshCollection& MeshCollection, + bool IncludeDoors, + bool IncludeWalls) +{ + float MaxZ = 0.0f; + + // Stores the total length covered. This is needed to place the doors. + int SideLengthAcumulator = 0; + + for(int i = 0; i < SidesLength.Num(); i++) + { + TSet AuxiliarPositions; + int SideLength = SidesLength[i]; + bool MainVisibility = true; + bool CornerVisbility = true; + + if (IncludeDoors) + { + AuxiliarPositions = CalculateDoorsIndexInSide(SideLengthAcumulator, SideLength); + } + if(IncludeWalls && UseWallMesh[i]) + { + AuxiliarPositions = GenerateWallsIndexPositions(SideLength); + } + + CalculateSideVisibilities(i, MainVisibility, CornerVisbility); + + // Update Max Z + float SideMaxZ = CreateSide(MeshCollection, AuxiliarPositions, SideLength, MainVisibility, CornerVisbility); + MaxZ = (MaxZ < SideMaxZ) ? SideMaxZ : MaxZ; + + // Update the acumulator to calculate doors index in next sides + SideLengthAcumulator += SideLength; + + // Update transform rotation for the next side + if(!UseFullBlocks) + { + const FQuat RotationToAdd = FRotator(0.0f, 90.0f, 0.0f).Quaternion(); + CurrentTransform.ConcatenateRotation(RotationToAdd); + } + } + + // Update transform for the next floor + FVector NewLocation = CurrentTransform.GetTranslation() + FVector(0.0f, 0.0f, MaxZ); + CurrentTransform.SetTranslation(NewLocation); + +} + +void AProceduralBuilding::CreateRoof() +{ + UStaticMesh* SelectedMesh = nullptr; + TSubclassOf SelectedBP = nullptr; + FBox SelectedMeshBounds; + + bool AreRoofMeshesAvailable = (RoofMeshes.Num() > 0) || (RoofBPs.Num() > 0); + + // Hack for top meshes. Perhaps the top part has a little part of the roof + FVector BoxSize = LastSelectedMeshBounds.GetSize(); + BoxSize = FVector(0.0f, -BoxSize.Y, 0.0f); + + CurrentTransform.SetTranslation(CurrentTransform.GetTranslation() + BoxSize); + + if(AreRoofMeshesAvailable) + { + + for(int i = 0; i < LengthY; i++) + { + FVector PivotLocation = CurrentTransform.GetTranslation(); + for(int j = 0; j < LengthX; j++) + { + // Choose a roof mesh + ChooseGeometryToSpawn(RoofMeshes, RoofBPs, &SelectedMesh, &SelectedBP); + + AddChunck(SelectedMesh, SelectedBP, RoofVisibility, SelectedMeshBounds); + + } + // Move the Transform location to the beginning of the next row + CurrentTransform.SetTranslation(PivotLocation); + UpdateTransformPositionToNextSide(SelectedMeshBounds); + } + } + + +} + +float AProceduralBuilding::CreateSide( + const FloorMeshCollection& MeshCollection, + const TSet& AuxiliarPositions, + int SideLength, + bool MainVisibility, + bool CornerVisbility) +{ + const TArray* MainMeshes = MeshCollection.MainMeshes; + const TArray>* MainBPs = MeshCollection.MainBPs; + const TArray* CornerMeshes = MeshCollection.CornerMeshes; + const TArray>* CornerBPs = MeshCollection.CornerBPs; + const TArray* AuxiliarMeshes = MeshCollection.AuxiliarMeshes; + const TArray>* AuxiliarBPs = MeshCollection.AuxiliarBPs; + + /** + * Main part + */ + + UStaticMesh* SelectedMesh = nullptr; + TSubclassOf SelectedBP = nullptr; + FBox SelectedMeshBounds; + float MaxZ = 0.0f; + + // Check to know if there are meshes for the main part available + bool AreMainMeshesAvailable = (MainMeshes && (MainMeshes->Num() > 0)) || (MainBPs && (MainBPs->Num() > 0)); + bool AreAuxMeshesAvailable = (MainMeshes && (MainMeshes->Num() > 0)) || (MainBPs && (MainBPs->Num() > 0)); + + for(int i = 0; (i < SideLength) && AreMainMeshesAvailable; i++) + { + const int* AuxiliarPosition = AuxiliarPositions.Find(i); + if(AreAuxMeshesAvailable && AuxiliarPosition) + { + // Choose an auxiliar mesh + ChooseGeometryToSpawn(*AuxiliarMeshes, *AuxiliarBPs, &SelectedMesh, &SelectedBP); + } + else + { + // Choose a main mesh + ChooseGeometryToSpawn(*MainMeshes, *MainBPs, &SelectedMesh, &SelectedBP); + } + + float ChunkZ = AddChunck(SelectedMesh, SelectedBP, MainVisibility, SelectedMeshBounds); + MaxZ = (MaxZ < ChunkZ) ? ChunkZ : MaxZ; + } + + /** + * Corner part + */ + bool AreCornerMeshesAvailable = (CornerMeshes && (CornerMeshes->Num() > 0)) || (CornerBPs && (CornerBPs->Num() > 0)); + if(Corners && AreCornerMeshesAvailable) + { + // Choose a corner mesh + ChooseGeometryToSpawn(*CornerMeshes, *CornerBPs, &SelectedMesh, &SelectedBP); + float ChunkZ = AddChunck(SelectedMesh, SelectedBP, CornerVisbility, SelectedMeshBounds); + MaxZ = (MaxZ < ChunkZ) ? ChunkZ : MaxZ; + + // Move the Transform location to the next side of the building + // because corners can be in two sides + UpdateTransformPositionToNextSide(SelectedMeshBounds); + } + + LastSelectedMeshBounds = SelectedMeshBounds; + + return MaxZ; +} + +void AProceduralBuilding::CalculateSidesLength() +{ + // Discard previous calculation + SidesLength.Reset(); + + if(UseFullBlocks) + { + // The full block configuration covers all the sides of the floor with one mesh + SidesLength.Emplace(1); + } + else + { + SidesLength.Emplace(LengthX); + SidesLength.Emplace(LengthY); + SidesLength.Emplace(LengthX); + SidesLength.Emplace(LengthY); + } + +} + +TSet AProceduralBuilding::CalculateDoorsIndexInSide(int StartIndex, int Length) +{ + TSet Result; + int MaxIndex = StartIndex + Length; + + for(int i : DoorsIndexPosition) + { + if( StartIndex <= i && i < MaxIndex ) + { + int RelativePostion = i - StartIndex; + Result.Emplace(RelativePostion); + } + } + return Result; +} + +TSet AProceduralBuilding::GenerateWallsIndexPositions(int Length) +{ + TSet Result; + for(int i = 0; i < Length; i++) + { + Result.Emplace(i); + } + return Result; +} + +void AProceduralBuilding::CalculateSideVisibilities(int SideIndex, bool& MainVisibility, bool& CornerVisbility) +{ + MainVisibility = UseFullBlocks || SideVisibility[SideIndex]; + CornerVisbility = UseFullBlocks || CornerVisibility[SideIndex]; +} + +void AProceduralBuilding::ChooseGeometryToSpawn( + const TArray& InMeshes, + const TArray>& InBPs, + UStaticMesh** OutMesh = nullptr, + TSubclassOf* OutBP = nullptr) +{ + int NumMeshes = InMeshes.Num(); + int NumBPs = InBPs.Num(); + int Range = NumMeshes + NumBPs; + + int Choosen = FMath::RandRange(0, Range - 1); + + if(Choosen < NumMeshes) + { + *OutMesh = InMeshes[Choosen]; + } + if(NumMeshes <= Choosen && Choosen < NumBPs) + { + *OutBP = InBPs[Choosen - NumMeshes]; + } +} + +float AProceduralBuilding::AddChunck( + const UStaticMesh* SelectedMesh, + const TSubclassOf SelectedBP, + bool Visible, + FBox& OutSelectedMeshBounds) +{ + float Result = 0.0f; + + // Static Mesh + if(SelectedMesh) + { + if(Visible) + { + AddMeshToBuilding(SelectedMesh); + } + FVector MeshBound = GetMeshSize(SelectedMesh); + Result = MeshBound.Z; + + UpdateTransformPositionToNextChunk(MeshBound); + OutSelectedMeshBounds = SelectedMesh->GetBoundingBox(); + } + // BP + else if(SelectedBP) + { + // Create a new ChildActorComponent + UChildActorComponent* ChildActorComp = NewObject(this, + FName(*FString::Printf(TEXT("ChildActorComp_%d"), ChildActorComps.Num() ))); + ChildActorComp->SetupAttachment(RootComponent); + + // Set the class that it will use + ChildActorComp->SetChildActorClass(SelectedBP); + ChildActorComp->SetRelativeTransform(CurrentTransform); + + // Spawns the actor referenced by UChildActorComponent + ChildActorComp->RegisterComponent(); + + AActor* ChildActor = ChildActorComp->GetChildActor(); + +#if WITH_EDITOR + // Add the child actor to a subfolder of the actor's name + ChildActor->SetFolderPath(FName( *FString::Printf(TEXT("/Buildings/%s"), *GetName()))); + #endif + + // Look for all the SMComps + TArray SMComps; + UStaticMeshComponent* PivotSMComp = nullptr; + + ChildActor->GetComponents(SMComps); + + // The first mesh on the BP is the pivot to continue creating the floor + PivotSMComp = SMComps[0]; + const UStaticMesh* SM = PivotSMComp->GetStaticMesh(); + + if(Visible) + { + ChildActorComps.Emplace(ChildActorComp); + AddMeshToBuilding(SM); + } + else + { + ChildActorComp->DestroyComponent(); + } + + FVector MeshBound = GetMeshSize(SM); + Result = MeshBound.Z; + + UpdateTransformPositionToNextChunk(MeshBound); + + // Make it invisible on the child actor to avoid duplication with the HISMComp + PivotSMComp->SetVisibility(false, false); + OutSelectedMeshBounds = SM->GetBoundingBox(); + + } + + return Result; +} + +void AProceduralBuilding::AddMeshToBuilding(const UStaticMesh* SM) +{ + + UHierarchicalInstancedStaticMeshComponent* HISMComp = GetHISMComp(SM); + HISMComp->AddInstance(CurrentTransform); +} + +FVector AProceduralBuilding::GetMeshSize(const UStaticMesh* SM) +{ + FBox Box = SM->GetBoundingBox(); + return Box.GetSize(); +} + +void AProceduralBuilding::UpdateTransformPositionToNextChunk(const FVector& Box) +{ + // Update Current Transform to the right side of the added chunk + // Nothing to change if the chunk is the size of a floor + if(!UseFullBlocks) + { + FQuat Rotation = CurrentTransform.GetRotation(); + FVector ForwardVector = -Rotation.GetForwardVector(); + + FVector NewLocation = CurrentTransform.GetTranslation() + ForwardVector * Box.X; + CurrentTransform.SetTranslation(NewLocation); + } +} + +void AProceduralBuilding::UpdateTransformPositionToNextSide(const FBox& Box) +{ + // Update Current Transform to the right side of the added chunk + // Nothing to change if the chunk is the size of a floor + if(!UseFullBlocks) + { + FQuat Rotation = CurrentTransform.GetRotation(); + FVector RightVector = -Rotation.GetRightVector(); + FVector Size = Box.GetSize(); + + FVector NewLocation = CurrentTransform.GetTranslation() + RightVector * Size.Y; + CurrentTransform.SetTranslation(NewLocation); + } +} diff --git a/Unreal/CarlaUE4/Plugins/Carla/Source/Carla/MapGen/ProceduralBuilding.h b/Unreal/CarlaUE4/Plugins/Carla/Source/Carla/MapGen/ProceduralBuilding.h new file mode 100644 index 000000000..279c9850f --- /dev/null +++ b/Unreal/CarlaUE4/Plugins/Carla/Source/Carla/MapGen/ProceduralBuilding.h @@ -0,0 +1,301 @@ +// Copyright (c) 2017 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 . + +#pragma once + +#include "CoreMinimal.h" +#include "GameFramework/Actor.h" + +#include "Components/HierarchicalInstancedStaticMeshComponent.h" + +#include "ProceduralBuilding.generated.h" + + +// TODO: support n-sides building + +struct FloorMeshCollection +{ + TArray* MainMeshes = nullptr; + TArray>* MainBPs = nullptr; + TArray* CornerMeshes = nullptr; + TArray>* CornerBPs = nullptr; + TArray* AuxiliarMeshes = nullptr; + TArray>* AuxiliarBPs = nullptr; +}; + +UCLASS() +class CARLA_API AProceduralBuilding : public AActor +{ + GENERATED_BODY() + +public: + + // Sets default values for this actor's properties + AProceduralBuilding(); + + // Looks for the HISMComp on the HISMComps Map that uses the SelectedMesh and returns it. + // If doesn't exist its created + UFUNCTION(BlueprintCallable, Category="Procedural Building") + UHierarchicalInstancedStaticMeshComponent* GetHISMComp(const UStaticMesh* SM); + + UFUNCTION(BlueprintCallable, CallInEditor, Category="Procedural Building") + void ConvertOldBP_ToNativeCodeObject(AActor* BP_Building); + + UFUNCTION(BlueprintCallable, Category="Procedural Building|Conversion") + void SetBaseParameters( + const TSet& InDoorsIndexPosition, + const TArray& InUseWallMesh, + int InNumFloors, + int InLengthX, + int InLengthY, + bool InCorners, + bool InUseFullBlocks); + + UFUNCTION(BlueprintCallable, Category="Procedural Building|Conversion") + void SetVisibilityParameters( + const TArray& InSideVisibility, + const TArray& InCornerVisibility, + bool InRoofVisibility); + + UFUNCTION(BlueprintCallable, Category="Procedural Building|Conversion") + void SetBaseMeshes( + const TArray& InBaseMeshes, + const TArray>& InBaseBPs, + const TArray& InCornerBaseMeshes, + const TArray>& InCornerBaseBPs, + const TArray& InDoorMeshes, + const TArray>& InDoorBPs); + + UFUNCTION(BlueprintCallable, Category="Procedural Building|Conversion") + void SetBodyMeshes( + const TArray& InBodyMeshes, + const TArray>& InBodyBPs, + const TArray& InCornerBodyMeshes, + const TArray>& InCornerBodyBPs, + const TArray& InWallMeshes, + const TArray>& InWallBPs); + + UFUNCTION(BlueprintCallable, Category="Procedural Building|Conversion") + void SetTopMeshes( + const TArray& InTopMeshes, + const TArray>& InTopBPs, + const TArray& InCornerTopMeshes, + const TArray>& InCornerTopBPs, + const TArray& InRoofMeshes, + const TArray>& InRoofBPs); + +protected: + + UFUNCTION(BlueprintCallable, CallInEditor, Category="Procedural Building") + void CreateBuilding(); + + UFUNCTION(BlueprintCallable, CallInEditor, Category="Procedural Building") + void Reset(); + + // TODO: AdvancedDisplay + // Map containing the pair with the name of the mesh and the component that uses it + UPROPERTY(BlueprintReadOnly, VisibleAnywhere, Category="Procedural Building|Debug") + TMap HISMComps; + + // Contains all the ChildActorComps spawned for this Actor + UPROPERTY(BlueprintReadOnly, VisibleAnywhere, Category="Procedural Building|Debug") + TArray ChildActorComps; + + /** + * Base Parameters + */ + + // Set to contain the index of the doors that need to be placed on the base floor + UPROPERTY(BlueprintReadWrite, EditAnywhere, Category="Procedural Building|Base Parameters", meta=(ToolTip="Index to indicate where the door is placed")) + TSet DoorsIndexPosition; + + // Indicates if the wall has to be filled with the wall-mesh or the body-mesh + UPROPERTY(BlueprintReadWrite, EditAnywhere, Category="Procedural Building|Base Parameters", meta=(ToolTip="True to use wall-mesh instead of body-mesh")) + TArray UseWallMesh; + + // Number of floors for the building, base and roof not included + UPROPERTY(BlueprintReadWrite, EditAnywhere, Category="Procedural Building|Base Parameters", meta=(ClampMin="0", UIMin="0", ToolTip="Number of floors for the building, base and roof not included")) + int NumFloors = 0; + + // Number of elements in X Axis + UPROPERTY(BlueprintReadWrite, EditAnywhere, Category="Procedural Building|Base Parameters") + int LengthX = 0; + + // Number of elements in Y Axis + UPROPERTY(BlueprintReadWrite, EditAnywhere, Category="Procedural Building|Base Parameters") + int LengthY = 0; + + // Enables the corners of the building + UPROPERTY(BlueprintReadWrite, EditAnywhere, Category="Procedural Building|Base Parameters") + bool Corners = false; + + // Indicates if the meshes that are used on this buildings fill the whole floor + UPROPERTY(BlueprintReadWrite, EditAnywhere, Category="Procedural Building|Base Parameters") + bool UseFullBlocks = false; + + /** + * Base Parameters | Visibility + */ + + // True to render the side of the building. Each index represents the side + UPROPERTY(BlueprintReadWrite, EditAnywhere, Category="Procedural Building|Base Parameters|Visibility") + TArray SideVisibility; + + // True to render the corner of the building. Each index represents the corner + UPROPERTY(BlueprintReadWrite, EditAnywhere, Category="Procedural Building|Base Parameters|Visibility") + TArray CornerVisibility; + + // True to render the roof + UPROPERTY(BlueprintReadWrite, EditAnywhere, Category="Procedural Building|Base Parameters|Visibility") + bool RoofVisibility = true; + + + /** + * Meshes + */ + + /** + * Meshes | Base + */ + + // Pool of meshes to be randomly selected for the base floor + UPROPERTY(BlueprintReadWrite, EditAnywhere, Category="Procedural Building|Meshes|Base") + TArray BaseMeshes; + + // Pool of BPs to be randomly selected for the base floor + UPROPERTY(BlueprintReadWrite, EditAnywhere, Category="Procedural Building|Meshes|Base") + TArray> BaseBPs; + + // Pool of meshes to be randomly selected for doors + UPROPERTY(BlueprintReadWrite, EditAnywhere, Category="Procedural Building|Meshes|Base") + TArray DoorMeshes; + + // Pool of BPs to be randomly selected for doors + UPROPERTY(BlueprintReadWrite, EditAnywhere, Category="Procedural Building|Meshes|Base") + TArray> DoorBPs; + + // Pool of meshes to be randomly selected for the corners of the base floor + UPROPERTY(BlueprintReadWrite, EditAnywhere, Category="Procedural Building|Meshes|Base") + TArray CornerBaseMeshes; + + // Pool of BPs to be randomly selected for the corners of the base floor + UPROPERTY(BlueprintReadWrite, EditAnywhere, Category="Procedural Building|Meshes|Base") + TArray> CornerBaseBPs; + + /** + * Meshes | Body + */ + + // Pool of meshes to be randomly selected for the body + UPROPERTY(BlueprintReadWrite, EditAnywhere, Category="Procedural Building|Meshes|Body") + TArray BodyMeshes; + + // Pool of BPs to be randomly selected for the body + UPROPERTY(BlueprintReadWrite, EditAnywhere, Category="Procedural Building|Meshes|Body") + TArray> BodyBPs; + + // Pool of meshes to be randomly selected for the walls of the body + UPROPERTY(BlueprintReadWrite, EditAnywhere, Category="Procedural Building|Meshes|Body") + TArray WallMeshes; + + // Pool of BPs to be randomly selected for the body walls of the body + UPROPERTY(BlueprintReadWrite, EditAnywhere, Category="Procedural Building|Meshes|Body") + TArray> WallBPs; + + // Pool of meshes to be randomly selected for the corners of the body floor + UPROPERTY(BlueprintReadWrite, EditAnywhere, Category="Procedural Building|Meshes|Body") + TArray CornerBodyMeshes; + + // Pool of BPs to be randomly selected for the corners of the body floor + UPROPERTY(BlueprintReadWrite, EditAnywhere, Category="Procedural Building|Meshes|Body") + TArray> CornerBodyBPs; + + /** + * Meshes | Top + */ + + // Pool of meshes to be randomly selected for the top + UPROPERTY(BlueprintReadWrite, EditAnywhere, Category="Procedural Building|Meshes|Top") + TArray TopMeshes; + + // Pool of BPs to be randomly selected for the top + UPROPERTY(BlueprintReadWrite, EditAnywhere, Category="Procedural Building|Meshes|Top") + TArray> TopBPs; + + // Pool of meshes to be randomly selected for the corners of the top + UPROPERTY(BlueprintReadWrite, EditAnywhere, Category="Procedural Building|Meshes|Top") + TArray CornerTopMeshes; + + // Pool of BPs to be randomly selected for the corners of the top + UPROPERTY(BlueprintReadWrite, EditAnywhere, Category="Procedural Building|Meshes|Top") + TArray> CornerTopBPs; + + // Pool of meshes to be randomly selected for the roof + UPROPERTY(BlueprintReadWrite, EditAnywhere, Category="Procedural Building|Meshes|Top") + TArray RoofMeshes; + + // Pool of BPs to be randomly selected for the roof + UPROPERTY(BlueprintReadWrite, EditAnywhere, Category="Procedural Building|Meshes|Top") + TArray> RoofBPs; + +private: + + void Init(); + + void CreateFloor(const FloorMeshCollection& MeshCollection, bool IncludeDoors, bool IncludeWalls); + + void CreateRoof(); + + // Creates the side of a floor of the building and returns the maximun height of the side + float CreateSide( + const FloorMeshCollection& MeshCollection, + const TSet& AuxiliarPositions, + int SideLength, + bool MainVisibility, + bool CornerVisbility); + + void CalculateSidesLength(); + + // Calculates the doors of DoorsIndexPosition inside the range between [StartIndex, StartIndex + Length) + // The set returns the position (index) of the doors relative to the side, ie: [0, Length) + TSet CalculateDoorsIndexInSide(int StartIndex, int Length); + + // + TSet GenerateWallsIndexPositions(int Length); + + // Check if the main and corner part of the side is visible + void CalculateSideVisibilities(int SideIndex, bool& MainVisibility, bool& CornerVisbility); + + // Choose randomly between the Mesh and BP containers, only one option will be returned. + void ChooseGeometryToSpawn( + const TArray& InMeshes, + const TArray>& InMainBPs, + UStaticMesh** OutMesh, + TSubclassOf* OutBP); + + // Add one part on the side + float AddChunck( + const UStaticMesh* SelectedMesh, + const TSubclassOf SelectedBP, + bool Visible, + FBox& OutSelectedMeshBounds); + + // Add the Static Mesh on the transform location with the transform orientation + void AddMeshToBuilding(const UStaticMesh* SM); + + // Calculate the Bounds for the Static Mesh + FVector GetMeshSize(const UStaticMesh* SM); + + void UpdateTransformPositionToNextChunk(const FVector& Box); + + void UpdateTransformPositionToNextSide(const FBox& Box); + + // The lengths of each side of the building. The length of the array is the number of sides + // Helper to iterate throught all the sides of the building + TArray SidesLength; + + // Transform used to spawn the meshes of the building. It is updated (moved) with each new mesh + FTransform CurrentTransform = FTransform::Identity; + + FBox LastSelectedMeshBounds; + +}; diff --git a/Unreal/CarlaUE4/Plugins/Carla/Source/Carla/OpenDrive/OpenDriveGenerator.cpp b/Unreal/CarlaUE4/Plugins/Carla/Source/Carla/OpenDrive/OpenDriveGenerator.cpp index 9c376c145..ddcebe60d 100644 --- a/Unreal/CarlaUE4/Plugins/Carla/Source/Carla/OpenDrive/OpenDriveGenerator.cpp +++ b/Unreal/CarlaUE4/Plugins/Carla/Source/Carla/OpenDrive/OpenDriveGenerator.cpp @@ -18,6 +18,13 @@ #include "Engine/Classes/Interfaces/Interface_CollisionDataProvider.h" #include "PhysicsEngine/BodySetupEnums.h" +AProceduralMeshActor::AProceduralMeshActor() +{ + PrimaryActorTick.bCanEverTick = false; + MeshComponent = CreateDefaultSubobject(TEXT("RootComponent")); + RootComponent = MeshComponent; +} + AOpenDriveGenerator::AOpenDriveGenerator(const FObjectInitializer &ObjectInitializer) : Super(ObjectInitializer) { @@ -77,11 +84,8 @@ void AOpenDriveGenerator::GenerateRoadMesh() { continue; } - AActor *TempActor = GetWorld()->SpawnActor(); - UProceduralMeshComponent *TempPMC = NewObject(TempActor); - TempPMC->RegisterComponent(); - TempPMC->AttachToComponent( - TempActor->GetRootComponent(), FAttachmentTransformRules::KeepRelativeTransform); + AProceduralMeshActor* TempActor = GetWorld()->SpawnActor(); + UProceduralMeshComponent *TempPMC = TempActor->MeshComponent; TempPMC->bUseAsyncCooking = true; TempPMC->bUseComplexAsSimpleCollision = true; TempPMC->SetCollisionEnabled(ECollisionEnabled::QueryAndPhysics); diff --git a/Unreal/CarlaUE4/Plugins/Carla/Source/Carla/OpenDrive/OpenDriveGenerator.h b/Unreal/CarlaUE4/Plugins/Carla/Source/Carla/OpenDrive/OpenDriveGenerator.h index 3d10c1f0e..6654e5935 100644 --- a/Unreal/CarlaUE4/Plugins/Carla/Source/Carla/OpenDrive/OpenDriveGenerator.h +++ b/Unreal/CarlaUE4/Plugins/Carla/Source/Carla/OpenDrive/OpenDriveGenerator.h @@ -18,6 +18,17 @@ #include "OpenDriveGenerator.generated.h" +UCLASS() +class CARLA_API AProceduralMeshActor : public AActor +{ + GENERATED_BODY() +public: + AProceduralMeshActor(); + + UPROPERTY(Category = "Procedural Mesh Actor", VisibleDefaultsOnly, BlueprintReadOnly, meta = (AllowPrivateAccess = "true")) + UProceduralMeshComponent* MeshComponent; +}; + UCLASS() class CARLA_API AOpenDriveGenerator : public AActor { diff --git a/Unreal/CarlaUE4/Plugins/Carla/Source/Carla/Recorder/CarlaReplayer.cpp b/Unreal/CarlaUE4/Plugins/Carla/Source/Carla/Recorder/CarlaReplayer.cpp index 6333aae50..145e92068 100644 --- a/Unreal/CarlaUE4/Plugins/Carla/Source/Carla/Recorder/CarlaReplayer.cpp +++ b/Unreal/CarlaUE4/Plugins/Carla/Source/Carla/Recorder/CarlaReplayer.cpp @@ -178,6 +178,7 @@ std::string CarlaReplayer::ReplayFile(std::string Filename, double TimeStart, do // if we don't need to load a new map, then start if (!Autoplay.Enabled) { + Helper.RemoveStaticProps(); // process all events until the time ProcessToTime(TimeStart, true); // mark as enabled @@ -237,6 +238,8 @@ void CarlaReplayer::CheckPlayAfterMapLoaded(void) // apply time factor TimeFactor = Autoplay.TimeFactor; + Helper.RemoveStaticProps(); + // process all events until the time ProcessToTime(TimeStart, true); diff --git a/Unreal/CarlaUE4/Plugins/Carla/Source/Carla/Recorder/CarlaReplayerHelper.cpp b/Unreal/CarlaUE4/Plugins/Carla/Source/Carla/Recorder/CarlaReplayerHelper.cpp index c98852dc5..01090ba5e 100644 --- a/Unreal/CarlaUE4/Plugins/Carla/Source/Carla/Recorder/CarlaReplayerHelper.cpp +++ b/Unreal/CarlaUE4/Plugins/Carla/Source/Carla/Recorder/CarlaReplayerHelper.cpp @@ -54,6 +54,10 @@ std::pairCarlaReplayerHelper::TryToCreateReplayerActor( if (desc->Id == ActorDesc.Id) { // we don't need to create, actor of same type already exist + // relocate + FRotator Rot = FRotator::MakeFromEuler(Rotation); + FTransform Trans2(Rot, Location, FVector(1, 1, 1)); + view.GetActor()->SetActorTransform(Trans2, false, nullptr, ETeleportType::TeleportPhysics); return std::pair(2, view); } } @@ -463,3 +467,20 @@ void CarlaReplayerHelper::SetWalkerSpeed(uint32_t ActorId, float Speed) } } } + +void CarlaReplayerHelper::RemoveStaticProps() +{ + check(Episode != nullptr); + auto World = Episode->GetWorld(); + for (TActorIterator It(World); It; ++It) + { + auto Actor = *It; + check(Actor != nullptr); + auto MeshComponent = Actor->GetStaticMeshComponent(); + check(MeshComponent != nullptr); + if (MeshComponent->Mobility == EComponentMobility::Movable) + { + Actor->Destroy(); + } + } +} diff --git a/Unreal/CarlaUE4/Plugins/Carla/Source/Carla/Recorder/CarlaReplayerHelper.h b/Unreal/CarlaUE4/Plugins/Carla/Source/Carla/Recorder/CarlaReplayerHelper.h index 6ea341ea0..23e004908 100644 --- a/Unreal/CarlaUE4/Plugins/Carla/Source/Carla/Recorder/CarlaReplayerHelper.h +++ b/Unreal/CarlaUE4/Plugins/Carla/Source/Carla/Recorder/CarlaReplayerHelper.h @@ -65,6 +65,8 @@ public: // set the animation speed for walkers void SetWalkerSpeed(uint32_t ActorId, float Speed); + void RemoveStaticProps(); + private: UCarlaEpisode *Episode {nullptr}; diff --git a/Unreal/CarlaUE4/Plugins/Carla/Source/Carla/Sensor/DepthCamera.cpp b/Unreal/CarlaUE4/Plugins/Carla/Source/Carla/Sensor/DepthCamera.cpp index c60abf991..e86663db3 100644 --- a/Unreal/CarlaUE4/Plugins/Carla/Source/Carla/Sensor/DepthCamera.cpp +++ b/Unreal/CarlaUE4/Plugins/Carla/Source/Carla/Sensor/DepthCamera.cpp @@ -26,16 +26,9 @@ ADepthCamera::ADepthCamera(const FObjectInitializer &ObjectInitializer) TEXT("Material'/Carla/PostProcessingMaterials/DepthEffectMaterial.DepthEffectMaterial'") #endif ); - - Offset = carla::sensor::SensorRegistry::get::type::header_offset; } -void ADepthCamera::SendPixels(const TArray& AtlasImage, uint32 AtlasTextureWidth) +void ADepthCamera::SendPixels() { -#if !UE_BUILD_SHIPPING - ACarlaGameModeBase* GameMode = Cast(GetWorld()->GetAuthGameMode()); - if(!GameMode->IsCameraStreamEnabled()) return; -#endif - - SendPixelsInStream(*this, AtlasImage, AtlasTextureWidth); + FPixelReader::SendPixelsInRenderThread(*this); } diff --git a/Unreal/CarlaUE4/Plugins/Carla/Source/Carla/Sensor/DepthCamera.h b/Unreal/CarlaUE4/Plugins/Carla/Source/Carla/Sensor/DepthCamera.h index f4bda659d..60c450fc2 100644 --- a/Unreal/CarlaUE4/Plugins/Carla/Source/Carla/Sensor/DepthCamera.h +++ b/Unreal/CarlaUE4/Plugins/Carla/Source/Carla/Sensor/DepthCamera.h @@ -26,5 +26,5 @@ public: protected: - void SendPixels(const TArray& AtlasImage, uint32 AtlasTextureWidth) override; + void SendPixels() override; }; diff --git a/Unreal/CarlaUE4/Plugins/Carla/Source/Carla/Sensor/PixelReader.cpp b/Unreal/CarlaUE4/Plugins/Carla/Source/Carla/Sensor/PixelReader.cpp index 18ecb5792..41f687a4b 100644 --- a/Unreal/CarlaUE4/Plugins/Carla/Source/Carla/Sensor/PixelReader.cpp +++ b/Unreal/CarlaUE4/Plugins/Carla/Source/Carla/Sensor/PixelReader.cpp @@ -45,6 +45,10 @@ struct LockTexture #if CARLA_WITH_VULKAN_SUPPORT == 1 +// Temporal; this avoid allocating the array each time and also avoids checking +// for a bigger texture, ReadSurfaceData will allocate the space needed. +TArray gPixels; + static void WritePixelsToBuffer_Vulkan( const UTextureRenderTarget2D &RenderTarget, carla::Buffer &Buffer, @@ -57,20 +61,19 @@ static void WritePixelsToBuffer_Vulkan( FTexture2DRHIRef Texture = RenderResource->GetRenderTargetTexture(); if (!Texture) { - UE_LOG(LogCarla, Error, TEXT("FPixelReader: UTextureRenderTarget2D missing render target texture")); return; } FIntPoint Rect = RenderResource->GetSizeXY(); + // NS: Extra copy here, don't know how to avoid it. - TArray Pixels; InRHICmdList.ReadSurfaceData( Texture, FIntRect(0, 0, Rect.X, Rect.Y), - Pixels, + gPixels, FReadSurfaceDataFlags(RCM_UNorm, CubeFace_MAX)); - Buffer.copy_from(Offset, Pixels); + Buffer.copy_from(Offset, gPixels); } #endif // CARLA_WITH_VULKAN_SUPPORT @@ -151,7 +154,12 @@ void FPixelReader::WritePixelsToBuffer( } #endif // CARLA_WITH_VULKAN_SUPPORT - FRHITexture2D *Texture = RenderTarget.GetRenderTargetResource()->GetRenderTargetTexture(); + FTextureRenderTargetResource* RenderTargetResource = RenderTarget.GetRenderTargetResource(); + if(!RenderTargetResource) + { + return; + } + FRHITexture2D *Texture = RenderTargetResource->GetRenderTargetTexture(); checkf(Texture != nullptr, TEXT("FPixelReader: UTextureRenderTarget2D missing render target texture")); const uint32 BytesPerPixel = 4u; // PF_R8G8B8A8 @@ -182,57 +190,9 @@ void FPixelReader::WritePixelsToBuffer( { check(ExpectedStride == SrcStride); const uint8 *Source = Lock.Source; - Buffer.copy_from(Offset, Source, ExpectedStride * Height); + if(Source) + { + Buffer.copy_from(Offset, Source, ExpectedStride * Height); + } } } - -void FPixelReader::WritePixelsToArray( - UTextureRenderTarget2D &RenderTarget, - TArray& Pixels, - FRHICommandListImmediate& RHICmdList) -{ - - // check(IsInRenderingThread()); - - const FTextureRenderTarget2DResource* RenderResource = - static_cast(RenderTarget.Resource); - FTexture2DRHIRef Texture = RenderResource->GetRenderTargetTexture(); - if (!Texture /* || !Texture->GetTexture2D() */) - { - UE_LOG(LogCarla, Error, TEXT("FPixelReader: UTextureRenderTarget2D missing render target texture")); - return; - } - - FIntPoint Rect = RenderResource->GetSizeXY(); - - - { - SCOPE_CYCLE_COUNTER(STAT_CarlaSensorReadRT); - - RHICmdList.ReadSurfaceData( - Texture, - FIntRect(0, 0, Rect.X, Rect.Y), - Pixels, - FReadSurfaceDataFlags(RCM_UNorm, CubeFace_MAX)); - - /* - void* ColorDataBuffer = nullptr; - - int32 Width = 0, Height = 0; - RHICmdList.MapStagingSurface(Texture, ColorDataBuffer, Width, Height); - - FColor* ColorBuffer = (FColor*)ColorDataBuffer; - FColor* Dest = &Pixels[0]; - - for (int32 Row = 0; Row < Height; ++Row) - { - FMemory::Memcpy(Dest, ColorBuffer, sizeof(FColor)*Width); - ColorBuffer += Width; - Dest += Width; - } - - RHICmdList.UnmapStagingSurface(Texture); - */ - } - -} \ No newline at end of file diff --git a/Unreal/CarlaUE4/Plugins/Carla/Source/Carla/Sensor/PixelReader.h b/Unreal/CarlaUE4/Plugins/Carla/Source/Carla/Sensor/PixelReader.h index e640caff4..05a933a4c 100644 --- a/Unreal/CarlaUE4/Plugins/Carla/Source/Carla/Sensor/PixelReader.h +++ b/Unreal/CarlaUE4/Plugins/Carla/Source/Carla/Sensor/PixelReader.h @@ -64,11 +64,6 @@ public: template static void SendPixelsInRenderThread(TSensor &Sensor); - static void WritePixelsToArray( - UTextureRenderTarget2D &RenderTarget, - TArray& Pixels, - FRHICommandListImmediate &InRHICmdList); - private: /// Copy the pixels in @a RenderTarget into @a Buffer. @@ -91,6 +86,11 @@ void FPixelReader::SendPixelsInRenderThread(TSensor &Sensor) { check(Sensor.CaptureRenderTarget != nullptr); + if (!Sensor.HasActorBegunPlay() || Sensor.IsPendingKill()) + { + return; + } + // Enqueue a command in the render-thread that will write the image buffer to // the data stream. The stream is created in the capture thus executed in the // game-thread. @@ -108,6 +108,7 @@ void FPixelReader::SendPixelsInRenderThread(TSensor &Sensor) carla::sensor::SensorRegistry::get::type::header_offset, InRHICmdList); + if(Buffer.data()) { SCOPE_CYCLE_COUNTER(STAT_CarlaSensorStreamSend); Stream.Send(Sensor, std::move(Buffer)); diff --git a/Unreal/CarlaUE4/Plugins/Carla/Source/Carla/Sensor/RayCastSemanticLidar.cpp b/Unreal/CarlaUE4/Plugins/Carla/Source/Carla/Sensor/RayCastSemanticLidar.cpp index 052dea24c..92b6a5332 100644 --- a/Unreal/CarlaUE4/Plugins/Carla/Source/Carla/Sensor/RayCastSemanticLidar.cpp +++ b/Unreal/CarlaUE4/Plugins/Carla/Source/Carla/Sensor/RayCastSemanticLidar.cpp @@ -19,6 +19,8 @@ #include "Runtime/Engine/Classes/Kismet/KismetMathLibrary.h" #include "Runtime/Core/Public/Async/ParallelFor.h" +namespace crp = carla::rpc; + FActorDefinition ARayCastSemanticLidar::GetSensorDefinition() { return UActorBlueprintFunctionLibrary::MakeLidarDefinition(TEXT("ray_cast_semantic")); @@ -160,7 +162,7 @@ void ARayCastSemanticLidar::ComputeRawDetection(const FHitResult& HitInfo, const AActor* actor = HitInfo.Actor.Get(); Detection.object_idx = 0; - Detection.object_tag = static_cast(ECityObjectLabel::None); + Detection.object_tag = static_cast(crp::CityObjectLabel::None); if (actor != nullptr) { FActorView view = Registry.Find(actor); diff --git a/Unreal/CarlaUE4/Plugins/Carla/Source/Carla/Sensor/SceneCaptureCamera.cpp b/Unreal/CarlaUE4/Plugins/Carla/Source/Carla/Sensor/SceneCaptureCamera.cpp index c86d22714..dc29b9bd3 100644 --- a/Unreal/CarlaUE4/Plugins/Carla/Source/Carla/Sensor/SceneCaptureCamera.cpp +++ b/Unreal/CarlaUE4/Plugins/Carla/Source/Carla/Sensor/SceneCaptureCamera.cpp @@ -20,16 +20,9 @@ ASceneCaptureCamera::ASceneCaptureCamera(const FObjectInitializer &ObjectInitial { AddPostProcessingMaterial( TEXT("Material'/Carla/PostProcessingMaterials/PhysicLensDistortion.PhysicLensDistortion'")); - - Offset = carla::sensor::SensorRegistry::get::type::header_offset; } -void ASceneCaptureCamera::SendPixels(const TArray& AtlasImage, uint32 AtlasTextureWidth) +void ASceneCaptureCamera::SendPixels() { -#if !UE_BUILD_SHIPPING - ACarlaGameModeBase* GameMode = Cast(GetWorld()->GetAuthGameMode()); - if(!GameMode->IsCameraStreamEnabled()) return; -#endif - - SendPixelsInStream(*this, AtlasImage, AtlasTextureWidth); + FPixelReader::SendPixelsInRenderThread(*this); } diff --git a/Unreal/CarlaUE4/Plugins/Carla/Source/Carla/Sensor/SceneCaptureCamera.h b/Unreal/CarlaUE4/Plugins/Carla/Source/Carla/Sensor/SceneCaptureCamera.h index bdd2fdf2b..ee5d8a719 100644 --- a/Unreal/CarlaUE4/Plugins/Carla/Source/Carla/Sensor/SceneCaptureCamera.h +++ b/Unreal/CarlaUE4/Plugins/Carla/Source/Carla/Sensor/SceneCaptureCamera.h @@ -26,6 +26,6 @@ public: protected: - void SendPixels(const TArray& AtlasImage, uint32 AtlasTextureWidth) override; + void SendPixels() override; }; diff --git a/Unreal/CarlaUE4/Plugins/Carla/Source/Carla/Sensor/SceneCaptureSensor.cpp b/Unreal/CarlaUE4/Plugins/Carla/Source/Carla/Sensor/SceneCaptureSensor.cpp index 908425cf4..9b1df2c61 100644 --- a/Unreal/CarlaUE4/Plugins/Carla/Source/Carla/Sensor/SceneCaptureSensor.cpp +++ b/Unreal/CarlaUE4/Plugins/Carla/Source/Carla/Sensor/SceneCaptureSensor.cpp @@ -110,7 +110,13 @@ EAutoExposureMethod ASceneCaptureSensor::GetExposureMethod() const void ASceneCaptureSensor::SetExposureCompensation(float Compensation) { check(CaptureComponent2D != nullptr); +#if PLATFORM_LINUX + // Looks like Windows and Linux have different outputs with the + // same exposure compensation, this fixes it. + CaptureComponent2D->PostProcessSettings.AutoExposureBias = Compensation - 1.5f; +#else CaptureComponent2D->PostProcessSettings.AutoExposureBias = Compensation; +#endif } float ASceneCaptureSensor::GetExposureCompensation() const @@ -484,9 +490,7 @@ void ASceneCaptureSensor::BeginPlay() Super::BeginPlay(); - ACarlaGameModeBase* GameMode = Cast(GetWorld()->GetAuthGameMode()); - GameMode->AddSceneCaptureSensor(this); - + SendPixelsDelegate = FCoreDelegates::OnEndFrameRT.AddUObject(this, &ASceneCaptureSensor::SendPixels); } void ASceneCaptureSensor::Tick(float DeltaTime) @@ -507,88 +511,7 @@ void ASceneCaptureSensor::EndPlay(const EEndPlayReason::Type EndPlayReason) Super::EndPlay(EndPlayReason); SCENE_CAPTURE_COUNTER = 0u; - ACarlaGameModeBase* GameMode = Cast(GetWorld()->GetAuthGameMode()); - GameMode->RemoveSceneCaptureSensor(this); -} - -void ASceneCaptureSensor::CopyTextureToAtlas() -{ - - check(CaptureRenderTarget != nullptr); - - ASceneCaptureSensor* This = this; - - ACarlaGameModeBase* GameMode = Cast(GetWorld()->GetAuthGameMode()); - if(!GameMode->IsCameraAtlasTextureValid()) return; - -#if !UE_BUILD_SHIPPING - if(!GameMode->IsCameraCopyToAtlasEnabled()) return; -#endif - - ENQUEUE_RENDER_COMMAND(ASceneCaptureSensor_CopyTextureToAtlas) - ( - [This, GameMode](FRHICommandListImmediate& RHICmdList) mutable - { - FTexture2DRHIRef AtlasTexture = GameMode->GetCurrentCamerasAtlasTexture(); - - if (AtlasTexture.IsValid() && This && This->HasActorBegunPlay() && !This->IsPendingKill()) - { - SCOPE_CYCLE_COUNTER(STAT_CarlaSensorCopyText); - - const FTextureRenderTarget2DResource* RenderResource = - static_cast(This->CaptureRenderTarget->Resource); - FTexture2DRHIRef Texture = RenderResource->GetRenderTargetTexture(); - if (!Texture) - { - UE_LOG(LogCarla, Error, TEXT("ASceneCaptureSensor::Capture: UTextureRenderTarget2D missing render target texture")); - return; - } - - // Prepare copy information - FRHICopyTextureInfo CopyInfo; - CopyInfo.Size = FIntVector(This->ImageWidth, This->ImageHeight, 0); // Size of the camera - CopyInfo.DestPosition = This->PositionInAtlas; // Where to copy the texture - - RHICmdList.CopyTexture(Texture, AtlasTexture, CopyInfo); - } - } - ); -} - -bool ASceneCaptureSensor::CopyTextureFromAtlas( - carla::Buffer &Buffer, - const TArray& AtlasImage, - uint32 AtlasTextureWidth) -{ - - Buffer.reset(Offset + ImageWidth * ImageHeight * sizeof(FColor)); - - // Check that the atlas alreay contains our texture - // and our image has been initialized - uint32 ExpectedSize = (uint32)(PositionInAtlas.Y * AtlasTextureWidth + ImageWidth * ImageHeight); - uint32 TotalSize = (uint32)AtlasImage.Num(); - if(AtlasImage.GetData() && TotalSize < ExpectedSize) - { - return false; - } - - SCOPE_CYCLE_COUNTER(STAT_CarlaSensorBufferCopy); - - const FColor* SourceFColor = AtlasImage.GetData() + PositionInAtlas.Y * AtlasTextureWidth; - const uint8* Source = (uint8*)SourceFColor; - uint32 Dest = Offset; - - const uint32 DstStride = ImageWidth * sizeof(FColor); - const uint32 SrcStride = AtlasTextureWidth * sizeof(FColor); - - for(uint32 i = 0; i < ImageHeight; i++) - { - Buffer.copy_from(Dest, Source, DstStride); - Source += SrcStride; - Dest += DstStride; - } - - return true; + FCoreDelegates::OnEndFrameRT.Remove(SendPixelsDelegate); } // ============================================================================= @@ -603,13 +526,17 @@ namespace SceneCaptureSensor_local_ns { // Exposure PostProcessSettings.bOverride_AutoExposureMethod = true; - PostProcessSettings.AutoExposureMethod = EAutoExposureMethod::AEM_Manual; + PostProcessSettings.AutoExposureMethod = EAutoExposureMethod::AEM_Histogram; PostProcessSettings.bOverride_AutoExposureBias = true; PostProcessSettings.bOverride_AutoExposureMinBrightness = true; PostProcessSettings.bOverride_AutoExposureMaxBrightness = true; PostProcessSettings.bOverride_AutoExposureSpeedUp = true; PostProcessSettings.bOverride_AutoExposureSpeedDown = true; PostProcessSettings.bOverride_AutoExposureCalibrationConstant = true; + PostProcessSettings.bOverride_HistogramLogMin = true; + PostProcessSettings.HistogramLogMin = 1.0f; + PostProcessSettings.bOverride_HistogramLogMax = true; + PostProcessSettings.HistogramLogMax = 12.0f; // Camera PostProcessSettings.bOverride_CameraShutterSpeed = true; @@ -636,6 +563,12 @@ namespace SceneCaptureSensor_local_ns { // Color Grading PostProcessSettings.bOverride_WhiteTemp = true; PostProcessSettings.bOverride_WhiteTint = true; + PostProcessSettings.bOverride_ColorContrast = true; +#if PLATFORM_LINUX + // Looks like Windows and Linux have different outputs with the + // same exposure compensation, this fixes it. + PostProcessSettings.ColorContrast = FVector4(1.2f, 1.2f, 1.2f, 1.0f); +#endif // Chromatic Aberration PostProcessSettings.bOverride_SceneFringeIntensity = true; diff --git a/Unreal/CarlaUE4/Plugins/Carla/Source/Carla/Sensor/SceneCaptureSensor.h b/Unreal/CarlaUE4/Plugins/Carla/Source/Carla/Sensor/SceneCaptureSensor.h index 6294320b0..b712b2e24 100644 --- a/Unreal/CarlaUE4/Plugins/Carla/Source/Carla/Sensor/SceneCaptureSensor.h +++ b/Unreal/CarlaUE4/Plugins/Carla/Source/Carla/Sensor/SceneCaptureSensor.h @@ -270,26 +270,6 @@ public: FPixelReader::SavePixelsToDisk(*CaptureRenderTarget, FilePath); } - void CopyTextureToAtlas(); - - bool CopyTextureFromAtlas(carla::Buffer &Buffer, const TArray& AtlasImage, uint32 AtlasTextureWidth); - - virtual void SendPixels(const TArray& /* AtlasImage */, uint32 /* AtlasTextureWidth */) {} - - template - void SendPixelsInStream(TSensor &Sensor, const TArray& AtlasImage, uint32 AtlasTextureWidth) - { - auto Stream = GetDataStream(Sensor); - carla::Buffer Buffer = Stream.PopBufferFromPool(); - - CopyTextureFromAtlas(Buffer, AtlasImage, AtlasTextureWidth); - - { - SCOPE_CYCLE_COUNTER(STAT_CarlaSensorStreamSend); - Stream.Send(Sensor, std::move(Buffer)); - } - } - protected: virtual void BeginPlay() override; @@ -300,6 +280,10 @@ protected: virtual void SetUpSceneCaptureComponent(USceneCaptureComponent2D &SceneCapture) {} + virtual void SendPixels() {} + + FDelegateHandle SendPixelsDelegate; + /// Render target necessary for scene capture. UPROPERTY(EditAnywhere) UTextureRenderTarget2D *CaptureRenderTarget = nullptr; @@ -308,8 +292,6 @@ protected: UPROPERTY(EditAnywhere) USceneCaptureComponent2D *CaptureComponent2D = nullptr; - FIntVector PositionInAtlas; - UPROPERTY(EditAnywhere) float TargetGamma = 2.2f; @@ -321,8 +303,6 @@ protected: UPROPERTY(EditAnywhere) uint32 ImageHeight = 600u; - uint32 Offset = 0u; - /// Whether to render the post-processing effects present in the scene. UPROPERTY(EditAnywhere) bool bEnablePostProcessingEffects = true; diff --git a/Unreal/CarlaUE4/Plugins/Carla/Source/Carla/Sensor/SemanticSegmentationCamera.cpp b/Unreal/CarlaUE4/Plugins/Carla/Source/Carla/Sensor/SemanticSegmentationCamera.cpp index df085db7b..d9fb5594e 100644 --- a/Unreal/CarlaUE4/Plugins/Carla/Source/Carla/Sensor/SemanticSegmentationCamera.cpp +++ b/Unreal/CarlaUE4/Plugins/Carla/Source/Carla/Sensor/SemanticSegmentationCamera.cpp @@ -22,16 +22,9 @@ ASemanticSegmentationCamera::ASemanticSegmentationCamera( TEXT("Material'/Carla/PostProcessingMaterials/PhysicLensDistortion.PhysicLensDistortion'")); AddPostProcessingMaterial( TEXT("Material'/Carla/PostProcessingMaterials/GTMaterial.GTMaterial'")); - - Offset = carla::sensor::SensorRegistry::get::type::header_offset; } -void ASemanticSegmentationCamera::SendPixels(const TArray& AtlasImage, uint32 AtlasTextureWidth) +void ASemanticSegmentationCamera::SendPixels() { -#if !UE_BUILD_SHIPPING - ACarlaGameModeBase* GameMode = Cast(GetWorld()->GetAuthGameMode()); - if(!GameMode->IsCameraStreamEnabled()) return; -#endif - - SendPixelsInStream(*this, AtlasImage, AtlasTextureWidth); + FPixelReader::SendPixelsInRenderThread(*this); } diff --git a/Unreal/CarlaUE4/Plugins/Carla/Source/Carla/Sensor/SemanticSegmentationCamera.h b/Unreal/CarlaUE4/Plugins/Carla/Source/Carla/Sensor/SemanticSegmentationCamera.h index d622b05fa..dd5310385 100644 --- a/Unreal/CarlaUE4/Plugins/Carla/Source/Carla/Sensor/SemanticSegmentationCamera.h +++ b/Unreal/CarlaUE4/Plugins/Carla/Source/Carla/Sensor/SemanticSegmentationCamera.h @@ -26,5 +26,5 @@ public: protected: - void SendPixels(const TArray& AtlasImage, uint32 AtlasTextureWidth) override; + void SendPixels() override; }; diff --git a/Unreal/CarlaUE4/Plugins/Carla/Source/Carla/Server/CarlaServer.cpp b/Unreal/CarlaUE4/Plugins/Carla/Source/Carla/Server/CarlaServer.cpp index 2e92a0f7c..bc1384bff 100644 --- a/Unreal/CarlaUE4/Plugins/Carla/Source/Carla/Server/CarlaServer.cpp +++ b/Unreal/CarlaUE4/Plugins/Carla/Source/Carla/Server/CarlaServer.cpp @@ -275,7 +275,6 @@ void FCarlaServer::FPimpl::BindActions() return Result; }; - BIND_SYNC(get_episode_settings) << [this]() -> R { REQUIRE_CARLA_EPISODE(); @@ -307,6 +306,19 @@ void FCarlaServer::FPimpl::BindActions() return Episode->SerializeActor(ActorView); }; + BIND_SYNC(get_all_level_BBs) << [this](uint8 QueriedTag) -> R> + { + REQUIRE_CARLA_EPISODE(); + TArray Result; + ACarlaGameModeBase* GameMode = UCarlaStatics::GetGameMode(Episode->GetWorld()); + if (!GameMode) + { + RESPOND_ERROR("unable to find CARLA game mode"); + } + Result = GameMode->GetAllBBsOfLevel(QueriedTag); + return MakeVectorFromTArray(Result); + }; + // ~~ Weather ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ BIND_SYNC(get_weather_parameters) << [this]() -> R @@ -500,7 +512,52 @@ void FCarlaServer::FPimpl::BindActions() return R::Success(); }; - BIND_SYNC(set_actor_velocity) << [this]( + + BIND_SYNC(set_actor_target_velocity) << [this]( + cr::ActorId ActorId, + cr::Vector3D vector) -> R + { + REQUIRE_CARLA_EPISODE(); + auto ActorView = Episode->FindActor(ActorId); + if (!ActorView.IsValid()) + { + RESPOND_ERROR("unable to set actor target velocity: actor not found"); + } + auto RootComponent = Cast(ActorView.GetActor()->GetRootComponent()); + if (RootComponent == nullptr) + { + RESPOND_ERROR("unable to set actor target velocity: not supported by actor"); + } + RootComponent->SetPhysicsLinearVelocity( + vector.ToCentimeters().ToFVector(), + false, + "None"); + return R::Success(); + }; + + BIND_SYNC(set_actor_target_angular_velocity) << [this]( + cr::ActorId ActorId, + cr::Vector3D vector) -> R + { + REQUIRE_CARLA_EPISODE(); + auto ActorView = Episode->FindActor(ActorId); + if (!ActorView.IsValid()) + { + RESPOND_ERROR("unable to set actor target angular velocity: actor not found"); + } + auto RootComponent = Cast(ActorView.GetActor()->GetRootComponent()); + if (RootComponent == nullptr) + { + RESPOND_ERROR("unable to set actor target angular velocity: not supported by actor"); + } + RootComponent->SetPhysicsAngularVelocityInDegrees( + vector.ToFVector(), + false, + "None"); + return R::Success(); + }; + + BIND_SYNC(enable_actor_constant_velocity) << [this]( cr::ActorId ActorId, cr::Vector3D vector) -> R { @@ -510,37 +567,34 @@ void FCarlaServer::FPimpl::BindActions() { RESPOND_ERROR("unable to set actor velocity: actor not found"); } - auto RootComponent = Cast(ActorView.GetActor()->GetRootComponent()); - if (RootComponent == nullptr) + auto CarlaVehicle = Cast(ActorView.GetActor()); + if (CarlaVehicle == nullptr) { RESPOND_ERROR("unable to set actor velocity: not supported by actor"); } - RootComponent->SetPhysicsLinearVelocity( - vector.ToCentimeters().ToFVector(), - false, - "None"); + + CarlaVehicle->ActivateVelocityControl(vector.ToCentimeters().ToFVector()); + return R::Success(); }; - BIND_SYNC(set_actor_angular_velocity) << [this]( - cr::ActorId ActorId, - cr::Vector3D vector) -> R + BIND_SYNC(disable_actor_constant_velocity) << [this]( + cr::ActorId ActorId) -> R { REQUIRE_CARLA_EPISODE(); auto ActorView = Episode->FindActor(ActorId); if (!ActorView.IsValid()) { - RESPOND_ERROR("unable to set actor angular velocity: actor not found"); + RESPOND_ERROR("unable to set actor velocity: actor not found"); } - auto RootComponent = Cast(ActorView.GetActor()->GetRootComponent()); - if (RootComponent == nullptr) + auto CarlaVehicle = Cast(ActorView.GetActor()); + if (CarlaVehicle == nullptr) { - RESPOND_ERROR("unable to set actor angular velocity: not supported by actor"); + RESPOND_ERROR("unable to set actor velocity: not supported by actor"); } - RootComponent->SetPhysicsAngularVelocityInDegrees( - vector.ToFVector(), - false, - "None"); + + CarlaVehicle->DeactivateVelocityControl(); + return R::Success(); }; @@ -566,6 +620,80 @@ void FCarlaServer::FPimpl::BindActions() return R::Success(); }; + BIND_SYNC(add_actor_impulse_at_location) << [this]( + cr::ActorId ActorId, + cr::Vector3D impulse, + cr::Vector3D location) -> R + { + REQUIRE_CARLA_EPISODE(); + auto ActorView = Episode->FindActor(ActorId); + if (!ActorView.IsValid()) + { + RESPOND_ERROR("unable to add actor impulse: actor not found"); + } + auto RootComponent = Cast(ActorView.GetActor()->GetRootComponent()); + if (RootComponent == nullptr) + { + RESPOND_ERROR("unable to add actor impulse: not supported by actor"); + } + + UE_LOG(LogCarla, Warning, TEXT("AddImpulseAtLocation: Experimental feature, use carefully.")); + + RootComponent->AddImpulseAtLocation( + impulse.ToCentimeters().ToFVector(), + location.ToCentimeters().ToFVector(), + "None"); + return R::Success(); + }; + + BIND_SYNC(add_actor_force) << [this]( + cr::ActorId ActorId, + cr::Vector3D vector) -> R + { + REQUIRE_CARLA_EPISODE(); + auto ActorView = Episode->FindActor(ActorId); + if (!ActorView.IsValid()) + { + RESPOND_ERROR("unable to add actor impulse: actor not found"); + } + auto RootComponent = Cast(ActorView.GetActor()->GetRootComponent()); + if (RootComponent == nullptr) + { + RESPOND_ERROR("unable to add actor impulse: not supported by actor"); + } + RootComponent->AddForce( + vector.ToCentimeters().ToFVector(), + "None", + false); + return R::Success(); + }; + + BIND_SYNC(add_actor_force_at_location) << [this]( + cr::ActorId ActorId, + cr::Vector3D force, + cr::Vector3D location) -> R + { + REQUIRE_CARLA_EPISODE(); + auto ActorView = Episode->FindActor(ActorId); + if (!ActorView.IsValid()) + { + RESPOND_ERROR("unable to add actor impulse: actor not found"); + } + auto RootComponent = Cast(ActorView.GetActor()->GetRootComponent()); + if (RootComponent == nullptr) + { + RESPOND_ERROR("unable to add actor impulse: not supported by actor"); + } + + UE_LOG(LogCarla, Warning, TEXT("AddImpulseAtLocation: Experimental feature, use carefully.")); + + RootComponent->AddForceAtLocation( + force.ToCentimeters().ToFVector(), + location.ToCentimeters().ToFVector(), + "None"); + return R::Success(); + }; + BIND_SYNC(add_actor_angular_impulse) << [this]( cr::ActorId ActorId, cr::Vector3D vector) -> R @@ -588,6 +716,28 @@ void FCarlaServer::FPimpl::BindActions() return R::Success(); }; + BIND_SYNC(add_actor_torque) << [this]( + cr::ActorId ActorId, + cr::Vector3D vector) -> R + { + REQUIRE_CARLA_EPISODE(); + auto ActorView = Episode->FindActor(ActorId); + if (!ActorView.IsValid()) + { + RESPOND_ERROR("unable to add actor torque: actor not found"); + } + auto RootComponent = Cast(ActorView.GetActor()->GetRootComponent()); + if (RootComponent == nullptr) + { + RESPOND_ERROR("unable to add actor torque: not supported by actor"); + } + RootComponent->AddTorqueInDegrees( + vector.ToFVector(), + "None", + false); + return R::Success(); + }; + BIND_SYNC(get_physics_control) << [this]( cr::ActorId ActorId) -> R { @@ -893,6 +1043,16 @@ void FCarlaServer::FPimpl::BindActions() return R::Success(); }; + BIND_SYNC(reset_all_traffic_lights) << [this]() -> R + { + REQUIRE_CARLA_EPISODE(); + for (TActorIterator It(Episode->GetWorld()); It; ++It) + { + It->ResetGroup(); + } + return R::Success(); + }; + BIND_SYNC(freeze_all_traffic_lights) << [this] (bool frozen) -> R { @@ -1090,10 +1250,12 @@ void FCarlaServer::FPimpl::BindActions() [=](auto, const C::ApplyVehicleControl &c) { MAKE_RESULT(apply_control_to_vehicle(c.actor, c.control)); }, [=](auto, const C::ApplyWalkerControl &c) { MAKE_RESULT(apply_control_to_walker(c.actor, c.control)); }, [=](auto, const C::ApplyTransform &c) { MAKE_RESULT(set_actor_transform(c.actor, c.transform)); }, - [=](auto, const C::ApplyVelocity &c) { MAKE_RESULT(set_actor_velocity(c.actor, c.velocity)); }, - [=](auto, const C::ApplyAngularVelocity &c) { MAKE_RESULT(set_actor_angular_velocity(c.actor, c.angular_velocity)); }, + [=](auto, const C::ApplyTargetVelocity &c) { MAKE_RESULT(set_actor_target_velocity(c.actor, c.velocity)); }, + [=](auto, const C::ApplyTargetAngularVelocity &c) { MAKE_RESULT(set_actor_target_angular_velocity(c.actor, c.angular_velocity)); }, [=](auto, const C::ApplyImpulse &c) { MAKE_RESULT(add_actor_impulse(c.actor, c.impulse)); }, + [=](auto, const C::ApplyForce &c) { MAKE_RESULT(add_actor_force(c.actor, c.force)); }, [=](auto, const C::ApplyAngularImpulse &c) { MAKE_RESULT(add_actor_angular_impulse(c.actor, c.impulse)); }, + [=](auto, const C::ApplyTorque &c) { MAKE_RESULT(add_actor_torque(c.actor, c.torque)); }, [=](auto, const C::SetSimulatePhysics &c) { MAKE_RESULT(set_actor_simulate_physics(c.actor, c.enabled)); }, // TODO: SetAutopilot should be removed. This is the old way to control the vehicles [=](auto, const C::SetAutopilot &c) { MAKE_RESULT(set_actor_autopilot(c.actor, c.enabled)); }, diff --git a/Unreal/CarlaUE4/Plugins/Carla/Source/Carla/Traffic/TrafficLightManager.cpp b/Unreal/CarlaUE4/Plugins/Carla/Source/Carla/Traffic/TrafficLightManager.cpp index 07a4bc383..e5222d6c3 100644 --- a/Unreal/CarlaUE4/Plugins/Carla/Source/Carla/Traffic/TrafficLightManager.cpp +++ b/Unreal/CarlaUE4/Plugins/Carla/Source/Carla/Traffic/TrafficLightManager.cpp @@ -33,7 +33,7 @@ ATrafficLightManager::ATrafficLightManager() } // Default traffic signs models static ConstructorHelpers::FClassFinder StopFinder( - TEXT( "/Game/Carla/Static/TrafficSigns/BP_Stop" ) ); + TEXT( "/Game/Carla/Static/TrafficSign/BP_Stop" ) ); if (StopFinder.Succeeded()) { TSubclassOf StopSignModel = StopFinder.Class; @@ -41,7 +41,7 @@ ATrafficLightManager::ATrafficLightManager() SignComponentModels.Add(carla::road::SignalType::StopSign().c_str(), UStopSignComponent::StaticClass()); } static ConstructorHelpers::FClassFinder YieldFinder( - TEXT( "/Game/Carla/Static/TrafficSigns/BP_Yield" ) ); + TEXT( "/Game/Carla/Static/TrafficSign/BP_Yield" ) ); if (YieldFinder.Succeeded()) { TSubclassOf YieldSignModel = YieldFinder.Class; diff --git a/Unreal/CarlaUE4/Plugins/Carla/Source/Carla/Traffic/TrafficLightState.h b/Unreal/CarlaUE4/Plugins/Carla/Source/Carla/Traffic/TrafficLightState.h index daba3d2e7..cc5b26fd7 100644 --- a/Unreal/CarlaUE4/Plugins/Carla/Source/Carla/Traffic/TrafficLightState.h +++ b/Unreal/CarlaUE4/Plugins/Carla/Source/Carla/Traffic/TrafficLightState.h @@ -6,11 +6,17 @@ #pragma once +#include +#include +#include + #include "TrafficLightState.generated.h" + UENUM(BlueprintType) enum class ETrafficLightState : uint8 { Red UMETA(DisplayName = "Red"), Yellow UMETA(DisplayName = "Yellow"), - Green UMETA(DisplayName = "Green") + Green UMETA(DisplayName = "Green"), + Off UMETA(DisplayName = "Off") }; diff --git a/Unreal/CarlaUE4/Plugins/Carla/Source/Carla/Util/BoundingBox.h b/Unreal/CarlaUE4/Plugins/Carla/Source/Carla/Util/BoundingBox.h index 60eb2221b..5fa687071 100644 --- a/Unreal/CarlaUE4/Plugins/Carla/Source/Carla/Util/BoundingBox.h +++ b/Unreal/CarlaUE4/Plugins/Carla/Source/Carla/Util/BoundingBox.h @@ -20,4 +20,8 @@ struct CARLA_API FBoundingBox /// Radii extent of the bounding box. UPROPERTY(EditAnywhere, BlueprintReadWrite) FVector Extent = {0.0f, 0.0f, 0.0f}; + + /// Rotation of the bounding box. + UPROPERTY(EditAnywhere, BlueprintReadWrite) + FRotator Rotation = {0.0f, 0.0f, 0.0f}; }; diff --git a/Unreal/CarlaUE4/Plugins/Carla/Source/Carla/Util/BoundingBoxCalculator.cpp b/Unreal/CarlaUE4/Plugins/Carla/Source/Carla/Util/BoundingBoxCalculator.cpp index d0a296fba..ab90777a6 100644 --- a/Unreal/CarlaUE4/Plugins/Carla/Source/Carla/Util/BoundingBoxCalculator.cpp +++ b/Unreal/CarlaUE4/Plugins/Carla/Source/Carla/Util/BoundingBoxCalculator.cpp @@ -13,7 +13,63 @@ #include "Components/CapsuleComponent.h" #include "GameFramework/Character.h" -FBoundingBox UBoundingBoxCalculator::GetActorBoundingBox(const AActor *Actor) +#include "Rendering/SkeletalMeshRenderData.h" + + +namespace crp = carla::rpc; + +static FBoundingBox ApplyTransformToBB( + const FBoundingBox& InBoundingBox, + const FTransform& Transform) +{ + const FRotator Rotation = Transform.GetRotation().Rotator(); + const FVector Translation = Transform.GetLocation(); + const FVector Scale = Transform.GetScale3D(); + + FBoundingBox BoundingBox = InBoundingBox; + BoundingBox.Origin *= Scale; + BoundingBox.Origin = Rotation.RotateVector(BoundingBox.Origin) + Translation; + BoundingBox.Extent *= Scale; + BoundingBox.Rotation = Rotation; + + return BoundingBox; +} + +static FBoundingBox CombineBBs(const TArray& BBsToCombine) +{ + FVector MaxVertex(TNumericLimits::Lowest()); + FVector MinVertex(TNumericLimits::Max()); + + for(const FBoundingBox& BB : BBsToCombine) { + FVector MaxVertexOfBB = BB.Origin + BB.Extent; + FVector MinVertexOfBB = BB.Origin - BB.Extent; + + MaxVertex.X = (MaxVertexOfBB.X > MaxVertex.X) ? MaxVertexOfBB.X : MaxVertex.X; + MaxVertex.Y = (MaxVertexOfBB.Y > MaxVertex.Y) ? MaxVertexOfBB.Y : MaxVertex.Y; + MaxVertex.Z = (MaxVertexOfBB.Z > MaxVertex.Z) ? MaxVertexOfBB.Z : MaxVertex.Z; + MinVertex.X = (MinVertexOfBB.X < MinVertex.X) ? MinVertexOfBB.X : MinVertex.X; + MinVertex.Y = (MinVertexOfBB.Y < MinVertex.Y) ? MinVertexOfBB.Y : MinVertex.Y; + MinVertex.Z = (MinVertexOfBB.Z < MinVertex.Z) ? MinVertexOfBB.Z : MinVertex.Z; + } + + // Calculate box extent + FVector Extent ( + (MaxVertex.X - MinVertex.X) * 0.5f, + (MaxVertex.Y - MinVertex.Y) * 0.5f, + (MaxVertex.Z - MinVertex.Z) * 0.5f + ); + + // Calculate middle point + FVector Origin ( + (MinVertex.X + Extent.X), + (MinVertex.Y + Extent.Y), + (MinVertex.Z + Extent.Z) + ); + + return {Origin, Extent}; +} + +FBoundingBox UBoundingBoxCalculator::GetActorBoundingBox(const AActor *Actor, uint8 InTagQueried) { if (Actor != nullptr) { @@ -57,6 +113,371 @@ FBoundingBox UBoundingBoxCalculator::GetActorBoundingBox(const AActor *Actor) return {}; } } + + } return {}; } + +FBoundingBox UBoundingBoxCalculator::GetVehicleBoundingBox( + const ACarlaWheeledVehicle* Vehicle, + uint8 InTagQueried) +{ + check(Vehicle); + + crp::CityObjectLabel TagQueried = (crp::CityObjectLabel)InTagQueried; + bool FilterByTagEnabled = (TagQueried != crp::CityObjectLabel::None); + + UActorComponent *ActorComp = Vehicle->GetComponentByClass(USkeletalMeshComponent::StaticClass()); + USkeletalMeshComponent* Comp = Cast(ActorComp); + + // Filter by tag + crp::CityObjectLabel Tag = ATagger::GetTagOfTaggedComponent(*Comp); + if(FilterByTagEnabled && Tag != TagQueried) return {}; + + USkeletalMesh* SkeletalMesh = Comp->SkeletalMesh; + FBoundingBox BoundingBox = GetSkeletalMeshBoundingBox(SkeletalMesh); + if(BoundingBox.Extent.IsZero()) + { + UE_LOG(LogCarla, Error, TEXT("%s has no SKM assigned"), *Vehicle->GetName()); + return {}; + } + + // Component-to-world transform for this component + const FTransform& CompToWorldTransform = Comp->GetComponentTransform(); + BoundingBox = ApplyTransformToBB(BoundingBox, CompToWorldTransform); + + return BoundingBox; +} + +FBoundingBox UBoundingBoxCalculator::GetCharacterBoundingBox( + const ACharacter* Character, + uint8 InTagQueried) +{ + check(Character); + + crp::CityObjectLabel TagQueried = (crp::CityObjectLabel)InTagQueried; + bool FilterByTag = TagQueried == crp::CityObjectLabel::None || + TagQueried == crp::CityObjectLabel::Pedestrians; + + UCapsuleComponent* Capsule = Character->GetCapsuleComponent(); + + + if (Capsule && FilterByTag) + { + const float Radius = Capsule->GetScaledCapsuleRadius(); + const float HalfHeight = Capsule->GetScaledCapsuleHalfHeight(); + FBoundingBox BoundingBox; + // Characters have the pivot point centered. + BoundingBox.Origin = {0.0f, 0.0f, 0.0f}; + BoundingBox.Extent = {Radius, Radius, HalfHeight}; + // Component-to-world transform for this component + const FTransform& CompToWorldTransform = Capsule->GetComponentTransform(); + BoundingBox = ApplyTransformToBB(BoundingBox, CompToWorldTransform); + + return BoundingBox; + } + + return {}; +} + +void UBoundingBoxCalculator::GetTrafficLightBoundingBox( + const ATrafficLightBase* TrafficLight, + TArray& OutBB, + uint8 InTagQueried) +{ + check(TrafficLight); + + TArray BBsOfTL; + TArray StaticMeshComps; + TrafficLight->GetComponents(StaticMeshComps); + GetBBsOfStaticMeshComponents(StaticMeshComps, BBsOfTL, InTagQueried); + + // This kind of a magic number relying that the lights of a TL are not bigger than 100. + // and we are gonna compare against a squared distance + const float DistanceThreshold = 100.0f * 100.0f; + + // The BBs of the TL are calculated per light, so we need to merge the full-box + TSet IndicesDiscarded; + for(int i = 0; i < BBsOfTL.Num(); i++) + { + // Check if the index was used to merge a previous BB + if(IndicesDiscarded.Contains(i)) continue; + + TArray BBsToCombine; + FBoundingBox& BB1 = BBsOfTL[i]; + + for(int j = i + 1; j < BBsOfTL.Num(); j++) + { + // Check if the index was used to merge a previous BB + if(IndicesDiscarded.Contains(j)) continue; + + FBoundingBox& BB2 = BBsOfTL[j]; + + float Distance = FVector::DistSquared(BB1.Origin, BB2.Origin); + + // If the lights are close enough, we merge it + if(Distance <= DistanceThreshold) + { + BBsToCombine.Emplace(BB2); + IndicesDiscarded.Emplace(j); + } + } + if(BBsToCombine.Num() > 0) + { + BBsToCombine.Emplace(BB1); + IndicesDiscarded.Emplace(i); + FBoundingBox MergedBB = CombineBBs(BBsToCombine); + MergedBB.Rotation = BB1.Rotation; + OutBB.Add(MergedBB); + } + } + + // Add the BB of the meshes that didn't need to combine (ie: poles) + for(int i = 0; i < BBsOfTL.Num(); i++) + { + // Check if the index was used to merge a previous BB + if(IndicesDiscarded.Contains(i)) continue; + FBoundingBox& BB = BBsOfTL[i]; + OutBB.Add(BB); + } + +} + + +// TODO: update to calculate current animation pose +FBoundingBox UBoundingBoxCalculator::GetSkeletalMeshBoundingBox(const USkeletalMesh* SkeletalMesh) +{ + if(!SkeletalMesh) + { + UE_LOG(LogCarla, Error, TEXT("GetSkeletalMeshBoundingBox no SkeletalMesh")); + return {}; + } + + // Get Vertex postion information from LOD 0 of the Skeletal Mesh + FSkeletalMeshRenderData* SkeletalMeshRenderData = SkeletalMesh->GetResourceForRendering(); + FSkeletalMeshLODRenderData& LODRenderData = SkeletalMeshRenderData->LODRenderData[0]; + FStaticMeshVertexBuffers& StaticMeshVertexBuffers = LODRenderData.StaticVertexBuffers; + FPositionVertexBuffer& FPositionVertexBuffer = StaticMeshVertexBuffers.PositionVertexBuffer; + uint32 NumVertices = FPositionVertexBuffer.GetNumVertices(); + + // Look for Skeletal Mesh bounds (vertex perfect) + FVector MaxVertex(TNumericLimits::Lowest()); + FVector MinVertex(TNumericLimits::Max()); + for(uint32 i = 0; i < NumVertices; i++) + { + FVector& Pos = FPositionVertexBuffer.VertexPosition(i); + MaxVertex.X = (Pos.X > MaxVertex.X) ? Pos.X : MaxVertex.X; + MaxVertex.Y = (Pos.Y > MaxVertex.Y) ? Pos.Y : MaxVertex.Y; + MaxVertex.Z = (Pos.Z > MaxVertex.Z) ? Pos.Z : MaxVertex.Z; + MinVertex.X = (Pos.X < MinVertex.X) ? Pos.X : MinVertex.X; + MinVertex.Y = (Pos.Y < MinVertex.Y) ? Pos.Y : MinVertex.Y; + MinVertex.Z = (Pos.Z < MinVertex.Z) ? Pos.Z : MinVertex.Z; + } + + // Calculate box extent + FVector Extent ( + (MaxVertex.X - MinVertex.X) * 0.5f, + (MaxVertex.Y - MinVertex.Y) * 0.5f, + (MaxVertex.Z - MinVertex.Z) * 0.5f + ); + + // Calculate middle point + FVector Origin ( + (MinVertex.X + Extent.X), + (MinVertex.Y + Extent.Y), + (MinVertex.Z + Extent.Z) + ); + + return {Origin, Extent}; +} + +FBoundingBox UBoundingBoxCalculator::GetStaticMeshBoundingBox(const UStaticMesh* StaticMesh) +{ + if(!StaticMesh) + { + UE_LOG(LogCarla, Error, TEXT("GetStaticMeshBoundingBox no StaticMesh")); + return {}; + } + + FBox Box = StaticMesh->GetBoundingBox(); + return {Box.GetCenter(), Box.GetExtent()}; + +} + +void UBoundingBoxCalculator::GetISMBoundingBox( + UInstancedStaticMeshComponent* ISMComp, + TArray& OutBoundingBox) +{ + if(!ISMComp) + { + UE_LOG(LogCarla, Error, TEXT("GetISMBoundingBox no ISMComp")); + return; + } + + const UStaticMesh *Mesh = ISMComp->GetStaticMesh(); + const FBoundingBox SMBoundingBox = GetStaticMeshBoundingBox(Mesh); + + if(SMBoundingBox.Extent.IsZero()) + { + UE_LOG(LogCarla, Error, TEXT("%s has no SM assigned to the ISM"), *ISMComp->GetOwner()->GetName()); + return; + } + + const TArray& PerInstanceSMData = ISMComp->PerInstanceSMData; + + const FTransform ParentTransform = ISMComp->GetComponentTransform(); + + for(auto& InstSMIData : PerInstanceSMData) + { + const FTransform Transform = FTransform(InstSMIData.Transform) * ParentTransform; + FBoundingBox BoundingBox = ApplyTransformToBB(SMBoundingBox, Transform); + + OutBoundingBox.Add(BoundingBox); + } + +} + +void UBoundingBoxCalculator::GetBBsOfStaticMeshComponents( + const TArray& StaticMeshComps, + TArray& OutBB, + uint8 InTagQueried) +{ + crp::CityObjectLabel TagQueried = (crp::CityObjectLabel)InTagQueried; + bool FilterByTagEnabled = (TagQueried != crp::CityObjectLabel::None); + + for(UStaticMeshComponent* Comp : StaticMeshComps) + { + + // Avoid duplication with SMComp and not visible meshes + if(!Comp->IsVisible() || Cast(Comp)) continue; + + // Filter by tag + crp::CityObjectLabel Tag = ATagger::GetTagOfTaggedComponent(*Comp); + if(FilterByTagEnabled && Tag != TagQueried) continue; + + UStaticMesh* StaticMesh = Comp->GetStaticMesh(); + FBoundingBox BoundingBox = GetStaticMeshBoundingBox(StaticMesh); + + if(BoundingBox.Extent.IsZero()) + { + UE_LOG(LogCarla, Error, TEXT("%s has no SM assigned"), *Comp->GetOwner()->GetName()); + } + else + { + // Component-to-world transform for this component + const FTransform& CompToWorldTransform = Comp->GetComponentTransform(); + BoundingBox = ApplyTransformToBB(BoundingBox, CompToWorldTransform); + OutBB.Add(BoundingBox); + } + } +} + +void UBoundingBoxCalculator::GetBBsOfSkeletalMeshComponents( + const TArray& SkeletalMeshComps, + TArray& OutBB, + uint8 InTagQueried) +{ + crp::CityObjectLabel TagQueried = (crp::CityObjectLabel)InTagQueried; + bool FilterByTagEnabled = (TagQueried != crp::CityObjectLabel::None); + + for(USkeletalMeshComponent* Comp : SkeletalMeshComps) + { + // Filter by tag + crp::CityObjectLabel Tag = ATagger::GetTagOfTaggedComponent(*Comp); + + if(!Comp->IsVisible() || (FilterByTagEnabled && Tag != TagQueried)) continue; + + USkeletalMesh* SkeletalMesh = Comp->SkeletalMesh; + FBoundingBox BoundingBox = GetSkeletalMeshBoundingBox(SkeletalMesh); + if(BoundingBox.Extent.IsZero()) + { + UE_LOG(LogCarla, Error, TEXT("%s has no SKM assigned"), *Comp->GetOwner()->GetName()); + } + else + { + // Component-to-world transform for this component + const FTransform& CompToWorldTransform = Comp->GetComponentTransform(); + BoundingBox = ApplyTransformToBB(BoundingBox, CompToWorldTransform); + OutBB.Add(BoundingBox); + } + } +} + +TArray UBoundingBoxCalculator::GetBoundingBoxOfActors( + const TArray& Actors, + uint8 InTagQueried) +{ + TArray Result; + crp::CityObjectLabel TagQueried = (crp::CityObjectLabel)InTagQueried; + bool FilterByTagEnabled = (TagQueried != crp::CityObjectLabel::None); + + for(AActor* Actor : Actors) + { + FString ClassName = Actor->GetClass()->GetName(); + + // Avoid the BP_Procedural_Building to avoid duplication with their child actors + // When improved the BP_Procedural_Building this maybe should be removed + // Note: We don't use casting here because the base class is a BP and is easier to do it this way, + // than getting the UClass of the BP to cast the actor. + if( ClassName.Contains("Procedural_Bulding") ) continue; + + // The vehicle's BP has a low-polystatic mesh for collisions, we should avoid it + ACarlaWheeledVehicle* Vehicle = Cast(Actor); + if (Vehicle) + { + FBoundingBox BoundingBox = GetVehicleBoundingBox(Vehicle, InTagQueried); + if(!BoundingBox.Extent.IsZero()) + { + Result.Add(BoundingBox); + } + continue; + } + + + // Pedestrians, we just use the capsule component at the moment. + ACharacter* Character = Cast(Actor); + if (Character) + { + FBoundingBox BoundingBox = GetCharacterBoundingBox(Character, InTagQueried); + if(!BoundingBox.Extent.IsZero()) + { + Result.Add(BoundingBox); + } + continue; + } + + // TrafficLight, we need to join all the BB of the lights in one + ATrafficLightBase* TrafficLight = Cast(Actor); + if(TrafficLight) + { + GetTrafficLightBoundingBox(TrafficLight, Result, InTagQueried); + continue; + } + + // Calculate FBoundingBox of ISM + TArray ISMComps; + Actor->GetComponents(ISMComps); + for(UInstancedStaticMeshComponent* Comp: ISMComps) + { + // Filter by tag + crp::CityObjectLabel Tag = ATagger::GetTagOfTaggedComponent(*Comp); + if(FilterByTagEnabled && Tag != TagQueried) continue; + + GetISMBoundingBox(Comp, Result); + } + + // Calculate FBoundingBox of SM + TArray StaticMeshComps; + Actor->GetComponents(StaticMeshComps); + GetBBsOfStaticMeshComponents(StaticMeshComps, Result, InTagQueried); + + // Calculate FBoundingBox of SK_M + TArray SkeletalMeshComps; + Actor->GetComponents(SkeletalMeshComps); + GetBBsOfSkeletalMeshComponents(SkeletalMeshComps, Result, InTagQueried); + + } + + return Result; +} diff --git a/Unreal/CarlaUE4/Plugins/Carla/Source/Carla/Util/BoundingBoxCalculator.h b/Unreal/CarlaUE4/Plugins/Carla/Source/Carla/Util/BoundingBoxCalculator.h index c1546bd09..ed641bc69 100644 --- a/Unreal/CarlaUE4/Plugins/Carla/Source/Carla/Util/BoundingBoxCalculator.h +++ b/Unreal/CarlaUE4/Plugins/Carla/Source/Carla/Util/BoundingBoxCalculator.h @@ -28,5 +28,52 @@ public: /// /// @warning Traffic signs return its trigger box instead. UFUNCTION(Category = "Carla Actor", BlueprintCallable) - static FBoundingBox GetActorBoundingBox(const AActor *Actor); + static FBoundingBox GetActorBoundingBox( + const AActor *Actor, + uint8 InTagQueried = 0); + + UFUNCTION(Category = "Carla Actor", BlueprintCallable) + static FBoundingBox GetVehicleBoundingBox( + const ACarlaWheeledVehicle* Vehicle, + uint8 InTagQueried = 0); + + UFUNCTION(Category = "Carla Actor", BlueprintCallable) + static FBoundingBox GetCharacterBoundingBox( + const ACharacter* Character, + uint8 InTagQueried = 0); + + UFUNCTION(Category = "Carla Actor", BlueprintCallable) + static void GetTrafficLightBoundingBox( + const ATrafficLightBase* TrafficLight, + TArray& OutBB, + uint8 InTagQueried = 0); + + UFUNCTION(Category = "Carla Util", BlueprintCallable) + static FBoundingBox GetSkeletalMeshBoundingBox(const USkeletalMesh* SkeletalMesh); + + UFUNCTION(Category = "Carla Util", BlueprintCallable) + static FBoundingBox GetStaticMeshBoundingBox(const UStaticMesh* StaticMesh); + + UFUNCTION(Category = "Carla Util", BlueprintCallable) + static void GetISMBoundingBox( + UInstancedStaticMeshComponent* HISMComp, + TArray& OutBoundingBox); + + UFUNCTION(Category = "Carla Util", BlueprintCallable) + static void GetBBsOfStaticMeshComponents( + const TArray& StaticMeshComps, + TArray& OutBB, + uint8 InTagQueried = 0); + + UFUNCTION(Category = "Carla Util", BlueprintCallable) + static void GetBBsOfSkeletalMeshComponents( + const TArray& SkeletalMeshComps, + TArray& OutBB, + uint8 InTagQueried = 0); + + UFUNCTION(Category = "Carla Util", BlueprintCallable) + static TArray GetBoundingBoxOfActors( + const TArray& Actors, + uint8 InTagQueried = 0); + }; diff --git a/Unreal/CarlaUE4/Plugins/Carla/Source/Carla/Util/DebugShapeDrawer.cpp b/Unreal/CarlaUE4/Plugins/Carla/Source/Carla/Util/DebugShapeDrawer.cpp index d648dfd21..d2cd7e801 100644 --- a/Unreal/CarlaUE4/Plugins/Carla/Source/Carla/Util/DebugShapeDrawer.cpp +++ b/Unreal/CarlaUE4/Plugins/Carla/Source/Carla/Util/DebugShapeDrawer.cpp @@ -182,7 +182,16 @@ private: uint8 DepthPriority = SDPG_World; - static constexpr double BrightMultiplier = 10000.0; + // Debug lines are way more dark in the package, that's why this + // multiplier is needed. +#if UE_BUILD_SHIPPING + static constexpr double BrightMultiplier = 1000.0; +#else + // @TODO: Use UKismetSystemLibrary::IsStandalone to support colors + // in Editor's standalone mode. + static constexpr double BrightMultiplier = 1.0; +#endif + }; void FDebugShapeDrawer::Draw(const carla::rpc::DebugShape &Shape) diff --git a/Unreal/CarlaUE4/Plugins/Carla/Source/Carla/Vehicle/CarlaWheeledVehicle.cpp b/Unreal/CarlaUE4/Plugins/Carla/Source/Carla/Vehicle/CarlaWheeledVehicle.cpp index 5c8a1ea9b..63adb9e1c 100644 --- a/Unreal/CarlaUE4/Plugins/Carla/Source/Carla/Vehicle/CarlaWheeledVehicle.cpp +++ b/Unreal/CarlaUE4/Plugins/Carla/Source/Carla/Vehicle/CarlaWheeledVehicle.cpp @@ -16,6 +16,8 @@ #include "TireConfig.h" #include "VehicleWheel.h" +#include "Rendering/SkeletalMeshRenderData.h" + // ============================================================================= // -- Constructor and destructor ----------------------------------------------- // ============================================================================= @@ -28,6 +30,9 @@ ACarlaWheeledVehicle::ACarlaWheeledVehicle(const FObjectInitializer& ObjectIniti VehicleBounds->SetHiddenInGame(true); VehicleBounds->SetCollisionProfileName(UCollisionProfile::NoCollision_ProfileName); + VelocityControl = CreateDefaultSubobject(TEXT("VelocityControl")); + VelocityControl->Deactivate(); + GetVehicleMovementComponent()->bReverseAsBrake = false; } @@ -81,6 +86,55 @@ void ACarlaWheeledVehicle::BeginPlay() Vehicle4W->WheelSetups = NewWheelSetups; } +void ACarlaWheeledVehicle::AdjustVehicleBounds() +{ + USkeletalMeshComponent *SkMeshComp = GetMesh(); + USkeletalMesh* SkeletalMesh = SkMeshComp->SkeletalMesh; + if(!SkeletalMesh) + { + UE_LOG(LogCarla, Error, TEXT("AdjustVehicleBounds no SkeletalMesh")); + return; + } + + // Get Vertex postion information from LOD 0 of the Skeletal Mesh + FPositionVertexBuffer& FPositionVertexBuffer = SkeletalMesh->GetResourceForRendering()->LODRenderData[0].StaticVertexBuffers.PositionVertexBuffer; + uint32 NumVertices = FPositionVertexBuffer.GetNumVertices(); + + // Look for Skeletal Mesh bounds (vertex perfect) + FVector MaxVertex(TNumericLimits::Min()); + FVector MinVertex(TNumericLimits::Max()); + for(uint32 i = 0; i < NumVertices; i++) + { + FVector& Pos = FPositionVertexBuffer.VertexPosition(i); + MaxVertex.X = (Pos.X > MaxVertex.X) ? Pos.X : MaxVertex.X; + MaxVertex.Y = (Pos.Y > MaxVertex.Y) ? Pos.Y : MaxVertex.Y; + MaxVertex.Z = (Pos.Z > MaxVertex.Z) ? Pos.Z : MaxVertex.Z; + MinVertex.X = (Pos.X < MinVertex.X) ? Pos.X : MinVertex.X; + MinVertex.Y = (Pos.Y < MinVertex.Y) ? Pos.Y : MinVertex.Y; + MinVertex.Z = (Pos.Z < MinVertex.Z) ? Pos.Z : MinVertex.Z; + } + + // Calculate box extent + FVector Extent ( + (MaxVertex.X - MinVertex.X) * 0.5f, + (MaxVertex.Y - MinVertex.Y) * 0.5f, + (MaxVertex.Z - MinVertex.Z) * 0.5f + ); + + // Calculate middle point + FVector Origin ( + (MinVertex.X + Extent.X), + (MinVertex.Y + Extent.Y), + (MinVertex.Z + Extent.Z) + ); + + // Prepare Box Collisions + FTransform Transform; + Transform.SetTranslation(Origin); + VehicleBounds->SetRelativeTransform(Transform); + VehicleBounds->SetBoxExtent(Extent); +} + // ============================================================================= // -- Get functions ------------------------------------------------------------ // ============================================================================= @@ -381,6 +435,16 @@ void ACarlaWheeledVehicle::ApplyVehiclePhysicsControl(const FVehiclePhysicsContr } } +void ACarlaWheeledVehicle::ActivateVelocityControl(const FVector &Velocity) +{ + VelocityControl->Activate(Velocity); +} + +void ACarlaWheeledVehicle::DeactivateVelocityControl() +{ + VelocityControl->Deactivate(); +} + void ACarlaWheeledVehicle::SetVehicleLightState(const FVehicleLightState &LightState) { InputControl.LightState = LightState; diff --git a/Unreal/CarlaUE4/Plugins/Carla/Source/Carla/Vehicle/CarlaWheeledVehicle.h b/Unreal/CarlaUE4/Plugins/Carla/Source/Carla/Vehicle/CarlaWheeledVehicle.h index 385999a39..890bb82fa 100644 --- a/Unreal/CarlaUE4/Plugins/Carla/Source/Carla/Vehicle/CarlaWheeledVehicle.h +++ b/Unreal/CarlaUE4/Plugins/Carla/Source/Carla/Vehicle/CarlaWheeledVehicle.h @@ -13,6 +13,7 @@ #include "Vehicle/VehicleLightState.h" #include "Vehicle/VehicleInputPriority.h" #include "Vehicle/VehiclePhysicsControl.h" +#include "VehicleVelocityControl.h" #include "WheeledVehicleMovementComponent4W.h" #include "CoreMinimal.h" @@ -136,6 +137,12 @@ public: } } + UFUNCTION(Category = "CARLA Wheeled Vehicle", BlueprintCallable) + void ActivateVelocityControl(const FVector &Velocity); + + UFUNCTION(Category = "CARLA Wheeled Vehicle", BlueprintCallable) + void DeactivateVelocityControl(); + /// @todo This function should be private to AWheeledVehicleAIController. void FlushVehicleControl(); @@ -196,6 +203,9 @@ protected: UFUNCTION(BlueprintImplementableEvent) void RefreshLightState(const FVehicleLightState &VehicleLightState); + UFUNCTION(BlueprintCallable, CallInEditor) + void AdjustVehicleBounds(); + private: /// Current state of the vehicle controller (for debugging purposes). @@ -205,6 +215,9 @@ private: UPROPERTY(Category = "CARLA Wheeled Vehicle", EditAnywhere) UBoxComponent *VehicleBounds; + UPROPERTY(Category = "CARLA Wheeled Vehicle", EditAnywhere) + UVehicleVelocityControl* VelocityControl; + struct { EVehicleInputPriority Priority = EVehicleInputPriority::INVALID; diff --git a/Unreal/CarlaUE4/Plugins/Carla/Source/Carla/Vehicle/VehicleVelocityControl.cpp b/Unreal/CarlaUE4/Plugins/Carla/Source/Carla/Vehicle/VehicleVelocityControl.cpp new file mode 100644 index 000000000..160c37eeb --- /dev/null +++ b/Unreal/CarlaUE4/Plugins/Carla/Source/Carla/Vehicle/VehicleVelocityControl.cpp @@ -0,0 +1,55 @@ +// 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 . + +#include "Kismet/KismetMathLibrary.h" + +#include "VehicleVelocityControl.h" + + +UVehicleVelocityControl::UVehicleVelocityControl() +{ + PrimaryComponentTick.bCanEverTick = true; +} + +void UVehicleVelocityControl::BeginPlay() +{ + Super::BeginPlay(); + + SetComponentTickEnabled(false); + SetTickGroup(ETickingGroup::TG_PrePhysics); + + OwnerVehicle = GetOwner(); + PrimitiveComponent = Cast(OwnerVehicle->GetRootComponent()); +} + +void UVehicleVelocityControl::Activate(bool bReset) +{ + Super::Activate(bReset); + + TargetVelocity = FVector(); + SetComponentTickEnabled(true); +} + +void UVehicleVelocityControl::Activate(FVector Velocity, bool bReset) +{ + Super::Activate(bReset); + + TargetVelocity = Velocity; + SetComponentTickEnabled(true); +} + +void UVehicleVelocityControl::Deactivate() +{ + SetComponentTickEnabled(false); + Super::Deactivate(); +} + +void UVehicleVelocityControl::TickComponent(float DeltaTime, enum ELevelTick TickType, FActorComponentTickFunction *ThisTickFunction) +{ + FTransform Transf = OwnerVehicle->GetActorTransform(); + const FVector LocVel = Transf.TransformVector(TargetVelocity); + PrimitiveComponent->SetPhysicsLinearVelocity(LocVel, false, "None"); +} diff --git a/Unreal/CarlaUE4/Plugins/Carla/Source/Carla/Vehicle/VehicleVelocityControl.h b/Unreal/CarlaUE4/Plugins/Carla/Source/Carla/Vehicle/VehicleVelocityControl.h new file mode 100644 index 000000000..9727f148e --- /dev/null +++ b/Unreal/CarlaUE4/Plugins/Carla/Source/Carla/Vehicle/VehicleVelocityControl.h @@ -0,0 +1,56 @@ +// 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 . + +#pragma once + +#include "Components/ActorComponent.h" +#include "Components/PrimitiveComponent.h" +#include "CoreMinimal.h" + +#include "VehicleVelocityControl.generated.h" + +/// Component that controls that the velocity of an actor is constant. +UCLASS(Blueprintable, BlueprintType, ClassGroup=(Custom), meta=(BlueprintSpawnableComponent)) +class CARLA_API UVehicleVelocityControl : public UActorComponent +{ + GENERATED_BODY() + + // =========================================================================== + /// @name Constructor and destructor + // =========================================================================== + /// @{ +public: + UVehicleVelocityControl(); + + /// @} + // =========================================================================== + /// @name Get functions + // =========================================================================== + /// @{ +public: + + void BeginPlay() override; + + virtual void TickComponent(float DeltaTime, enum ELevelTick TickType, FActorComponentTickFunction *ThisTickFunction) override; + + // Activate the component setting the target velocity + virtual void Activate(bool bReset=false) override; + + // Activate the component setting the target velocity + virtual void Activate(FVector Velocity, bool bReset=false); + + // Deactivate the component + virtual void Deactivate() override; + +private: + /// + UPROPERTY(Category = "Vehicle Velocity Control", VisibleAnywhere) + FVector TargetVelocity; + + UPrimitiveComponent* PrimitiveComponent; + AActor* OwnerVehicle; + +}; diff --git a/Unreal/CarlaUE4/Source/CarlaUE4/CarlaMapGenerator.cpp b/Unreal/CarlaUE4/Source/CarlaUE4/CarlaMapGenerator.cpp deleted file mode 100644 index a322704ee..000000000 --- a/Unreal/CarlaUE4/Source/CarlaUE4/CarlaMapGenerator.cpp +++ /dev/null @@ -1,79 +0,0 @@ -// Copyright (c) 2017 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 . - -#include "CarlaUE4.h" -#include "CarlaMapGenerator.h" - -ACarlaMapGenerator::ACarlaMapGenerator(const FObjectInitializer& ObjectInitializer) - : Super(ObjectInitializer) -{ -#define SET_STATIC_MESH(Tag, Folder, FileName) \ - { \ - static const ConstructorHelpers::FObjectFinder MeshObj( \ - TEXT("StaticMesh'" Folder "/" FileName "." FileName "'")); \ - SetStaticMesh(ECityMapMeshTag:: Tag, MeshObj.Object); \ - } - -#define PREFIX_FOLDER "/Game/Carla/Static/" - - SET_STATIC_MESH(RoadTwoLanes_LaneLeft, PREFIX_FOLDER "Road", "St_Road_TileRoad_RoadL"); - SET_STATIC_MESH(RoadTwoLanes_LaneRight, PREFIX_FOLDER "Road", "St_Road_TileRoad_RoadR"); - SET_STATIC_MESH(RoadTwoLanes_SidewalkLeft, PREFIX_FOLDER "SideWalk", "St_Road_TileRoad_SidewalkL"); - SET_STATIC_MESH(RoadTwoLanes_SidewalkRight, PREFIX_FOLDER "SideWalk", "St_Road_TileRoad_SidewalkR"); - SET_STATIC_MESH(RoadTwoLanes_LaneMarkingSolid, PREFIX_FOLDER "RoadLines", "St_Road_TileRoad_LaneMarkingSolid"); - SET_STATIC_MESH(RoadTwoLanes_LaneMarkingBroken, PREFIX_FOLDER "RoadLines", "St_Road_TileRoad_LaneMarkingBroken"); - - SET_STATIC_MESH(Road90DegTurn_Lane0, PREFIX_FOLDER "Road", "St_Road_Curve_Road0"); - SET_STATIC_MESH(Road90DegTurn_Lane1, PREFIX_FOLDER "Road", "St_Road_Curve_Road1"); - SET_STATIC_MESH(Road90DegTurn_Lane2, PREFIX_FOLDER "Road", "St_Road_Curve_Road2"); - SET_STATIC_MESH(Road90DegTurn_Lane3, PREFIX_FOLDER "Road", "St_Road_Curve_Road3"); - SET_STATIC_MESH(Road90DegTurn_Lane4, PREFIX_FOLDER "Road", "St_Road_Curve_Road4"); - SET_STATIC_MESH(Road90DegTurn_Lane5, PREFIX_FOLDER "Road", "St_Road_Curve_Road5"); - SET_STATIC_MESH(Road90DegTurn_Lane6, PREFIX_FOLDER "Road", "St_Road_Curve_Road6"); - SET_STATIC_MESH(Road90DegTurn_Lane7, PREFIX_FOLDER "Road", "St_Road_Curve_Road7"); - SET_STATIC_MESH(Road90DegTurn_Lane8, PREFIX_FOLDER "Road", "St_Road_Curve_Road8"); - SET_STATIC_MESH(Road90DegTurn_Lane9, PREFIX_FOLDER "Road", "St_Road_Curve_Road9"); - SET_STATIC_MESH(Road90DegTurn_Sidewalk0, PREFIX_FOLDER "SideWalk", "St_Road_Curve_Sidewalk1"); - SET_STATIC_MESH(Road90DegTurn_Sidewalk1, PREFIX_FOLDER "SideWalk", "St_Road_Curve_Sidewalk2"); - SET_STATIC_MESH(Road90DegTurn_Sidewalk2, PREFIX_FOLDER "SideWalk", "St_Road_Curve_Sidewalk3"); - SET_STATIC_MESH(Road90DegTurn_Sidewalk3, PREFIX_FOLDER "SideWalk", "St_Road_Curve_Sidewalk4"); - SET_STATIC_MESH(Road90DegTurn_LaneMarking, PREFIX_FOLDER "RoadLines", "St_Road_Curve_LaneMarking"); - - SET_STATIC_MESH(RoadTIntersection_Lane0, PREFIX_FOLDER "Road", "St_Road_TCross_Road0"); - SET_STATIC_MESH(RoadTIntersection_Lane1, PREFIX_FOLDER "Road", "St_Road_TCross_Road1"); - SET_STATIC_MESH(RoadTIntersection_Lane2, PREFIX_FOLDER "Road", "St_Road_TCross_Road2"); - SET_STATIC_MESH(RoadTIntersection_Lane3, PREFIX_FOLDER "Road", "St_Road_TCross_Road3"); - SET_STATIC_MESH(RoadTIntersection_Lane4, PREFIX_FOLDER "Road", "St_Road_TCross_Road4"); - SET_STATIC_MESH(RoadTIntersection_Lane5, PREFIX_FOLDER "Road", "St_Road_TCross_Road5"); - SET_STATIC_MESH(RoadTIntersection_Lane6, PREFIX_FOLDER "Road", "St_Road_TCross_Road6"); - SET_STATIC_MESH(RoadTIntersection_Lane7, PREFIX_FOLDER "Road", "St_Road_TCross_Road7"); - SET_STATIC_MESH(RoadTIntersection_Lane8, PREFIX_FOLDER "Road", "St_Road_TCross_Road8"); - SET_STATIC_MESH(RoadTIntersection_Lane9, PREFIX_FOLDER "Road", "St_Road_TCross_Road9"); - SET_STATIC_MESH(RoadTIntersection_Sidewalk0, PREFIX_FOLDER "SideWalk", "St_Road_TCross_Sidewalk1"); - SET_STATIC_MESH(RoadTIntersection_Sidewalk1, PREFIX_FOLDER "SideWalk", "St_Road_TCross_Sidewalk2"); - SET_STATIC_MESH(RoadTIntersection_Sidewalk2, PREFIX_FOLDER "SideWalk", "St_Road_TCross_Sidewalk3"); - SET_STATIC_MESH(RoadTIntersection_Sidewalk3, PREFIX_FOLDER "SideWalk", "St_Road_TCross_Sidewalk4"); - SET_STATIC_MESH(RoadTIntersection_LaneMarking, PREFIX_FOLDER "RoadLines", "St_Road_TCross_LaneMarking"); - - SET_STATIC_MESH(RoadXIntersection_Lane0, PREFIX_FOLDER "Road", "St_Road_XCross_Road0"); - SET_STATIC_MESH(RoadXIntersection_Lane1, PREFIX_FOLDER "Road", "St_Road_XCross_Road1"); - SET_STATIC_MESH(RoadXIntersection_Lane2, PREFIX_FOLDER "Road", "St_Road_XCross_Road2"); - SET_STATIC_MESH(RoadXIntersection_Lane3, PREFIX_FOLDER "Road", "St_Road_XCross_Road3"); - SET_STATIC_MESH(RoadXIntersection_Lane4, PREFIX_FOLDER "Road", "St_Road_XCross_Road4"); - SET_STATIC_MESH(RoadXIntersection_Lane5, PREFIX_FOLDER "Road", "St_Road_XCross_Road5"); - SET_STATIC_MESH(RoadXIntersection_Lane6, PREFIX_FOLDER "Road", "St_Road_XCross_Road6"); - SET_STATIC_MESH(RoadXIntersection_Lane7, PREFIX_FOLDER "Road", "St_Road_XCross_Road7"); - SET_STATIC_MESH(RoadXIntersection_Lane8, PREFIX_FOLDER "Road", "St_Road_XCross_Road8"); - SET_STATIC_MESH(RoadXIntersection_Lane9, PREFIX_FOLDER "Road", "St_Road_XCross_Road9"); - SET_STATIC_MESH(RoadXIntersection_Sidewalk0, PREFIX_FOLDER "SideWalk", "St_Road_XCross_Sidewalk1"); - SET_STATIC_MESH(RoadXIntersection_Sidewalk1, PREFIX_FOLDER "SideWalk", "St_Road_XCross_Sidewalk2"); - SET_STATIC_MESH(RoadXIntersection_Sidewalk2, PREFIX_FOLDER "SideWalk", "St_Road_XCross_Sidewalk3"); - SET_STATIC_MESH(RoadXIntersection_Sidewalk3, PREFIX_FOLDER "SideWalk", "St_Road_XCross_Sidewalk4"); - SET_STATIC_MESH(RoadXIntersection_LaneMarking, PREFIX_FOLDER "RoadLines", "St_Road_XCross_LaneMarking"); - -#undef PREFIX_FOLDER -#undef SET_STATIC_MESH -} diff --git a/Unreal/CarlaUE4/Source/CarlaUE4/CarlaMapGenerator.h b/Unreal/CarlaUE4/Source/CarlaUE4/CarlaMapGenerator.h deleted file mode 100644 index b3608a546..000000000 --- a/Unreal/CarlaUE4/Source/CarlaUE4/CarlaMapGenerator.h +++ /dev/null @@ -1,21 +0,0 @@ -// Copyright (c) 2017 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 . - -#pragma once - -#include "CityMapGenerator.h" -#include "CarlaMapGenerator.generated.h" - -/// Generates the city map using CARLA assets. -UCLASS() -class CARLAUE4_API ACarlaMapGenerator : public ACityMapGenerator -{ - GENERATED_BODY() - -public: - - ACarlaMapGenerator(const FObjectInitializer& ObjectInitializer); -}; diff --git a/Util/BuildTools/Ad-rss.sh b/Util/BuildTools/Ad-rss.sh index 15e06576d..2be72ae0d 100755 --- a/Util/BuildTools/Ad-rss.sh +++ b/Util/BuildTools/Ad-rss.sh @@ -31,7 +31,7 @@ else git clone --depth=1 -b v1.7.0 https://github.com/gabime/spdlog.git git clone --depth=1 -b 4.9.3 https://github.com/OSGeo/PROJ.git git clone --depth=1 -b v2.1.0 https://github.com/carla-simulator/map.git - git clone --depth=1 -b v4.0.1 https://github.com/intel/ad-rss-lib.git + git clone --depth=1 -b v4.1.0 https://github.com/intel/ad-rss-lib.git popd cat >"${CARLA_BUILD_FOLDER}/${ADRSS_BASENAME}/colcon.meta" </dev/null # -- Run smoke tests ----------------------------------------------------------- # ============================================================================== -if ${SMOKE_TESTS_2} || ${SMOKE_TESTS_3} ; then +if ${SMOKE_TESTS} ; then pushd "${CARLA_PYTHONAPI_ROOT_FOLDER}/util" >/dev/null log "Checking connection with the simulator." - ./test_connection.py -p 3654 --timeout=60.0 + /usr/bin/env python${PY_VERSION} test_connection.py -p 3654 --timeout=60.0 popd >/dev/null fi @@ -231,23 +209,11 @@ else EXTRA_ARGS= fi -if ${SMOKE_TESTS_2} ; then - - log "Running smoke tests for Python 2." - - /usr/bin/env python2 -m nose2 ${EXTRA_ARGS} - - if ${XML_OUTPUT} ; then - mv test-results.xml ${CARLA_TEST_RESULTS_FOLDER}/smoke-tests-2.xml - fi - -fi - -if ${SMOKE_TESTS_3} ; then +if ${SMOKE_TESTS} ; then log "Running smoke tests for Python 3." - /usr/bin/env python${PY3_VERSION} -m nose2 ${EXTRA_ARGS} + /usr/bin/env python${PY_VERSION} -m nose2 ${EXTRA_ARGS} if ${XML_OUTPUT} ; then mv test-results.xml ${CARLA_TEST_RESULTS_FOLDER}/smoke-tests-3.xml diff --git a/Util/BuildTools/Linux.mk b/Util/BuildTools/Linux.mk index 4a4ede69d..dedf211e9 100644 --- a/Util/BuildTools/Linux.mk +++ b/Util/BuildTools/Linux.mk @@ -58,20 +58,20 @@ check.LibCarla.release: LibCarla.release @${CARLA_BUILD_TOOLS_FOLDER}/Check.sh --libcarla-release $(ARGS) check.PythonAPI: PythonAPI - @${CARLA_BUILD_TOOLS_FOLDER}/Check.sh --python-api-2 --python-api-3 $(ARGS) + @${CARLA_BUILD_TOOLS_FOLDER}/Check.sh --python-api $(ARGS) check.PythonAPI.2: PythonAPI.2 - @${CARLA_BUILD_TOOLS_FOLDER}/Check.sh --python-api-2 $(ARGS) + @${CARLA_BUILD_TOOLS_FOLDER}/Check.sh --python-api --python-version=2 $(ARGS) check.PythonAPI.3: PythonAPI.3 - @${CARLA_BUILD_TOOLS_FOLDER}/Check.sh --python-api-3 $(ARGS) + @${CARLA_BUILD_TOOLS_FOLDER}/Check.sh --python-api --python-version=3 $(ARGS) benchmark: LibCarla.release @${CARLA_BUILD_TOOLS_FOLDER}/Check.sh --benchmark $(ARGS) @cat profiler.csv smoke_tests: - @${CARLA_BUILD_TOOLS_FOLDER}/Check.sh --smoke-2 --smoke-3 $(ARGS) + @${CARLA_BUILD_TOOLS_FOLDER}/Check.sh --smoke $(ARGS) examples: @for D in ${CARLA_EXAMPLES_FOLDER}/*; do [ -d "$${D}" ] && make -C $${D} build; done @@ -84,28 +84,28 @@ CarlaUE4Editor: LibCarla.server.release .PHONY: PythonAPI PythonAPI: LibCarla.client.release osm2odr - @${CARLA_BUILD_TOOLS_FOLDER}/BuildPythonAPI.sh --py2 --py3 $(ARGS) + @${CARLA_BUILD_TOOLS_FOLDER}/BuildPythonAPI.sh $(ARGS) PythonAPI.2: LibCarla.client.release osm2odr - @${CARLA_BUILD_TOOLS_FOLDER}/BuildPythonAPI.sh --py2 + @${CARLA_BUILD_TOOLS_FOLDER}/BuildPythonAPI.sh --python-version=2 PythonAPI.3: LibCarla.client.release osm2odr - @${CARLA_BUILD_TOOLS_FOLDER}/BuildPythonAPI.sh --py3 $(ARGS) + @${CARLA_BUILD_TOOLS_FOLDER}/BuildPythonAPI.sh --python-version=3 PythonAPI.rebuild: LibCarla.client.release osm2odr @${CARLA_BUILD_TOOLS_FOLDER}/BuildPythonAPI.sh --rebuild $(ARGS) PythonAPI.rss: LibCarla.client.rss.release osm2odr - @${CARLA_BUILD_TOOLS_FOLDER}/BuildPythonAPI.sh --py2 --py3 --rss $(ARGS) + @${CARLA_BUILD_TOOLS_FOLDER}/BuildPythonAPI.sh --rss $(ARGS) PythonAPI.rss.2: LibCarla.client.rss.release osm2odr - @${CARLA_BUILD_TOOLS_FOLDER}/BuildPythonAPI.sh --py2 --rss + @${CARLA_BUILD_TOOLS_FOLDER}/BuildPythonAPI.sh --python-version=2 --rss PythonAPI.rss.3: LibCarla.client.rss.release osm2odr - @${CARLA_BUILD_TOOLS_FOLDER}/BuildPythonAPI.sh --py3 --rss $(ARGS) + @${CARLA_BUILD_TOOLS_FOLDER}/BuildPythonAPI.sh --python-version=3 --rss PythonAPI.rss.rebuild: LibCarla.client.rss.release osm2odr - @${CARLA_BUILD_TOOLS_FOLDER}/BuildPythonAPI.sh --rebuild --rss + @${CARLA_BUILD_TOOLS_FOLDER}/BuildPythonAPI.sh --rebuild --rss $(ARGS) PythonAPI.docs: @python PythonAPI/docs/doc_gen.py diff --git a/Util/BuildTools/Package.sh b/Util/BuildTools/Package.sh index 9efb09a3b..a16ecd822 100755 --- a/Util/BuildTools/Package.sh +++ b/Util/BuildTools/Package.sh @@ -16,7 +16,7 @@ DO_CLEAN_INTERMEDIATE=false PROPS_MAP_NAME=PropsMap PACKAGE_CONFIG=Shipping -OPTS=`getopt -o h --long help,config:,no-zip,clean-intermediate,packages:,python3-version: -n 'parse-options' -- "$@"` +OPTS=`getopt -o h --long help,config:,no-zip,clean-intermediate,packages:,python-version: -n 'parse-options' -- "$@"` if [ $? != 0 ] ; then echo "$USAGE_STRING" ; exit 2 ; fi diff --git a/Util/BuildTools/Setup.sh b/Util/BuildTools/Setup.sh index a96e74b26..bc7e082a8 100755 --- a/Util/BuildTools/Setup.sh +++ b/Util/BuildTools/Setup.sh @@ -6,20 +6,20 @@ DOC_STRING="Download and install the required libraries for carla." -USAGE_STRING="Usage: $0 [--python3-version=VERSION]" +USAGE_STRING="Usage: $0 [--python-version=VERSION]" -OPTS=`getopt -o h --long help,rebuild,py2,py3,clean,rss,python3-version:,packages:,clean-intermediate,all,xml -n 'parse-options' -- "$@"` +OPTS=`getopt -o h --long help,rebuild,clean,rss,python-version:,packages:,clean-intermediate,all,xml -n 'parse-options' -- "$@"` if [ $? != 0 ] ; then echo "$USAGE_STRING" ; exit 2 ; fi eval set -- "$OPTS" -PY3_VERSION=3 +PY_VERSION=3 while [[ $# -gt 0 ]]; do case "$1" in - --python3-version ) - PY3_VERSION="$2"; + --python-version ) + PY_VERSION="$2"; shift 2 ;; -h | --help ) echo "$DOC_STRING" @@ -106,10 +106,19 @@ BOOST_BASENAME="boost-${BOOST_VERSION}-${CXX_TAG}" BOOST_INCLUDE=${PWD}/${BOOST_BASENAME}-install/include BOOST_LIBPATH=${PWD}/${BOOST_BASENAME}-install/lib -if [[ -d "${BOOST_BASENAME}-install" ]] ; then - log "${BOOST_BASENAME} already installed." -else +SHOULD_BUILD_BOOST=true +PYTHON_VERSION=$(/usr/bin/env python${PY_VERSION} -V) +LIB_NAME=${PYTHON_VERSION:7:3} +LIB_NAME=${LIB_NAME//.} +if [[ -d "${BOOST_BASENAME}-install" ]] ; then + if [ -f "${BOOST_BASENAME}-install/lib/libboost_python${LIB_NAME}.a" ] ; then + SHOULD_BUILD_BOOST=false + log "${BOOST_BASENAME} already installed." + fi +fi + +if { ${SHOULD_BUILD_BOOST} ; } ; then rm -Rf ${BOOST_BASENAME}-source BOOST_PACKAGE_BASENAME=boost_${BOOST_VERSION//./_} @@ -122,7 +131,7 @@ else wget "https://carla-releases.s3.eu-west-3.amazonaws.com/Backup/${BOOST_PACKAGE_BASENAME}.tar.gz" || true fi - log "Extracting boost for Python 2." + log "Extracting boost for Python ${PY_VERSION}." tar -xzf ${BOOST_PACKAGE_BASENAME}.tar.gz mkdir -p ${BOOST_BASENAME}-install/include mv ${BOOST_PACKAGE_BASENAME} ${BOOST_BASENAME}-source @@ -136,53 +145,19 @@ else BOOST_TOOLSET="clang-8.0" BOOST_CFLAGS="-fPIC -std=c++14 -DBOOST_ERROR_CODE_HEADER_ONLY" - py2="/usr/bin/env python2" - py2_root=`${py2} -c "import sys; print(sys.prefix)"` - pyv=`$py2 -c "import sys;x='{v[0]}.{v[1]}'.format(v=list(sys.version_info[:2]));sys.stdout.write(x)";` - ./bootstrap.sh \ - --with-toolset=clang \ - --prefix=../boost-install \ - --with-libraries=python,filesystem,system,program_options \ - --with-python=${py2} --with-python-root=${py2_root} - - if ${TRAVIS} ; then - echo "using python : ${pyv} : ${py2_root}/bin/python2 ;" > ${HOME}/user-config.jam - else - echo "using python : ${pyv} : ${py2_root}/bin/python2 ;" > project-config.jam - fi - - ./b2 toolset="${BOOST_TOOLSET}" cxxflags="${BOOST_CFLAGS}" --prefix="../${BOOST_BASENAME}-install" -j ${CARLA_BUILD_CONCURRENCY} stage release - ./b2 toolset="${BOOST_TOOLSET}" cxxflags="${BOOST_CFLAGS}" --prefix="../${BOOST_BASENAME}-install" -j ${CARLA_BUILD_CONCURRENCY} install - ./b2 toolset="${BOOST_TOOLSET}" cxxflags="${BOOST_CFLAGS}" --prefix="../${BOOST_BASENAME}-install" -j ${CARLA_BUILD_CONCURRENCY} --clean-all - - # Get rid of python2 build artifacts completely & do a clean build for python3 - popd >/dev/null - rm -Rf ${BOOST_BASENAME}-source - - log "Extracting boost for Python 3." - tar -xzf ${BOOST_PACKAGE_BASENAME}.tar.gz - mkdir -p ${BOOST_BASENAME}-install/include - mv ${BOOST_PACKAGE_BASENAME} ${BOOST_BASENAME}-source - # Boost patch for exception handling - cp "${CARLA_BUILD_FOLDER}/../Util/BoostFiles/rational.hpp" "${BOOST_BASENAME}-source/boost/rational.hpp" - cp "${CARLA_BUILD_FOLDER}/../Util/BoostFiles/read.hpp" "${BOOST_BASENAME}-source/boost/geometry/io/wkt/read.hpp" - # --- - - pushd ${BOOST_BASENAME}-source >/dev/null - - py3="/usr/bin/env python${PY3_VERSION}" + py3="/usr/bin/env python${PY_VERSION}" py3_root=`${py3} -c "import sys; print(sys.prefix)"` pyv=`$py3 -c "import sys;x='{v[0]}.{v[1]}'.format(v=list(sys.version_info[:2]));sys.stdout.write(x)";` ./bootstrap.sh \ --with-toolset=clang \ --prefix=../boost-install \ - --with-libraries=python \ + --with-libraries=python,filesystem,system,program_options \ --with-python=${py3} --with-python-root=${py3_root} if ${TRAVIS} ; then - echo "using python : ${pyv} : ${py3_root}/bin/python${PY3_VERSION} ;" > ${HOME}/user-config.jam + echo "using python : ${pyv} : ${py3_root}/bin/python${PY_VERSION} ;" > ${HOME}/user-config.jam else - echo "using python : ${pyv} : ${py3_root}/bin/python${PY3_VERSION} ;" > project-config.jam + echo "using python : ${pyv} : ${py3_root}/bin/python${PY_VERSION} ;" > project-config.jam fi ./b2 toolset="${BOOST_TOOLSET}" cxxflags="${BOOST_CFLAGS}" --prefix="../${BOOST_BASENAME}-install" -j ${CARLA_BUILD_CONCURRENCY} stage release @@ -198,6 +173,12 @@ else cp "${CARLA_BUILD_FOLDER}/../Util/BoostFiles/read.hpp" "${BOOST_BASENAME}-install/include/boost/geometry/io/wkt/read.hpp" # --- + # Install boost dependencies + mkdir -p "${LIBCARLA_INSTALL_CLIENT_FOLDER}/include/system" + mkdir -p "${LIBCARLA_INSTALL_CLIENT_FOLDER}/lib" + cp -rf ${BOOST_BASENAME}-install/include/* ${LIBCARLA_INSTALL_CLIENT_FOLDER}/include/system + cp -rf ${BOOST_BASENAME}-install/lib/* ${LIBCARLA_INSTALL_CLIENT_FOLDER}/lib + fi unset BOOST_BASENAME @@ -399,6 +380,40 @@ fi unset RECAST_BASENAME +# ============================================================================== +# -- Get and compile libpng 1.6.37 ------------------------------ +# ============================================================================== + +LIBPNG_VERSION=1.6.37 +LIBPNG_REPO=https://sourceforge.net/projects/libpng/files/libpng16/${LIBPNG_VERSION}/libpng-${LIBPNG_VERSION}.tar.xz +LIBPNG_BASENAME=libpng-${LIBPNG_VERSION} +LIBPNG_INSTALL=${LIBPNG_BASENAME}-install + +LIBPNG_INCLUDE=${PWD}/${LIBPNG_BASENAME}-install/include/ +LIBPNG_LIBPATH=${PWD}/${LIBPNG_BASENAME}-install/lib + +if [[ -d ${LIBPNG_INSTALL} ]] ; then + log "Libpng already installed." +else + log "Retrieving libpng." + wget ${LIBPNG_REPO} + + log "Extracting libpng." + tar -xf libpng-${LIBPNG_VERSION}.tar.xz + mv ${LIBPNG_BASENAME} ${LIBPNG_BASENAME}-source + + pushd ${LIBPNG_BASENAME}-source >/dev/null + + ./configure --prefix=${CARLA_BUILD_FOLDER}/${LIBPNG_INSTALL} + make install + + popd >/dev/null + + rm -Rf libpng-${LIBPNG_VERSION}.tar.xz + rm -Rf ${LIBPNG_BASENAME}-source +fi + + # ============================================================================== # -- Generate Version.h -------------------------------------------------------- # ============================================================================== @@ -495,6 +510,8 @@ elseif (CMAKE_BUILD_TYPE STREQUAL "Client") set(BOOST_LIB_PATH "${BOOST_LIBPATH}") set(RECAST_INCLUDE_PATH "${RECAST_INCLUDE}") set(RECAST_LIB_PATH "${RECAST_LIBPATH}") + set(LIBPNG_INCLUDE_PATH "${LIBPNG_INCLUDE}") + set(LIBPNG_LIB_PATH "${LIBPNG_LIBPATH}") endif () EOL diff --git a/Util/ContentVersions.txt b/Util/ContentVersions.txt index 511a3a5f2..a3d4c873c 100644 --- a/Util/ContentVersions.txt +++ b/Util/ContentVersions.txt @@ -32,4 +32,4 @@ 0.9.7: 20191221_c88604b 0.9.8: 20200306_06b6cb1 0.9.9: 20200422_ea5179a -0.9.10: 20200731_3e91044 +0.9.10: 20200925_88f9ceb diff --git a/Util/Docker/Prerequisites.Dockerfile b/Util/Docker/Prerequisites.Dockerfile index 7d193163e..b6db6c976 100644 --- a/Util/Docker/Prerequisites.Dockerfile +++ b/Util/Docker/Prerequisites.Dockerfile @@ -34,10 +34,9 @@ RUN apt-get update ; \ libtool \ rsync \ libxml2-dev \ - aria2 && \ - pip2 install setuptools && \ - pip3 install setuptools && \ - pip2 install distro && \ + aria2 \ + libxerces-c-dev && \ + pip3 install -Iv setuptools==47.3.1 && \ pip3 install distro && \ update-alternatives --install /usr/bin/clang++ clang++ /usr/lib/llvm-8/bin/clang++ 180 && \ update-alternatives --install /usr/bin/clang clang /usr/lib/llvm-8/bin/clang 180 diff --git a/mkdocs.yml b/mkdocs.yml index a86c2c397..ea5f1ca68 100644 --- a/mkdocs.yml +++ b/mkdocs.yml @@ -62,6 +62,7 @@ nav: - Tutorials (developers): - 'Contribute with assets': 'tuto_D_contribute_assets.md' - 'Create a sensor': 'tuto_D_create_sensor.md' + - 'Customize vehicle suspension': 'tuto_D_customize_vehicle_suspension.md' - 'Generate detailed colliders': 'tuto_D_generate_colliders.md' - 'Make a release': 'tuto_D_make_release.md' - 'Generate pedestrian navigation': 'tuto_D_generate_pedestrian_navigation.md'