Merge with dev

This commit is contained in:
JoseM98 2024-04-18 13:46:04 +02:00
commit 1ec58b4cf5
83 changed files with 1887 additions and 588 deletions

View File

@ -3,6 +3,18 @@
* Added vehicle doors to the recorder
* Adjusted vehicle BoundingBox when the vehicle opens the doors.
* Added functions to get actor' components transform
* Added posibility to Digital Twins to work with local files (osm and xodr)
* Enable proper material merging for Building in Digital Twins
* Added functions to get actor' bones transforms
* Added functions to get actor' bones and components names
* Added functions to get actor' sockets transforms
* make PythonAPI Windows: Fixed incompatibility issue with Anaconda due `py` command.
* Added function to get actor' sockets names
* Fixed bug in python agents when vehicle list was empty causing a check on all vehicles (BasicAgent.py) and detected pedestrians as vehicles if no pedestrains are present (BehaviourAgent.py)
* Extended debug drawing functions to allow drawing primitives on HUD layer
* Added possibility to change gravity variable in imui sensor for the accelerometer
* Fixed ROS2 native extension build error when ROS2 is installed in the system.
* ROS2Native: Force fast-dds dependencies download to avoid build crash when boost_asio and tinyxml2 are not installed in Linux.
## CARLA 0.9.15
@ -31,6 +43,8 @@
* Fixed bug causing the `FPixelReader::SavePixelsToDisk(PixelData, FilePath)` function to crash due to pixel array not set correctly.
* Fixed segfaults in Python API due to incorrect GIL locking under Python 3.10.
* Fixed the import script, where could use any other TilesInfo.txt if the destination folder has many
* Fixed PythonAPI not installing on Debian due to deprecated function of distro in setup.py. Less ambiguous error for other posix platforms.
## CARLA 0.9.14

View File

@ -301,7 +301,7 @@ def _get_sumo_net(cfg_file):
net_file = os.path.join(os.path.dirname(cfg_file), tag.get('value'))
logging.debug('Reading net file: %s', net_file)
sumo_net = traci.sumolib.net.readNet(net_file)
sumo_net = sumolib.net.readNet(net_file)
return sumo_net
class SumoSimulation(object):

View File

@ -8,7 +8,7 @@ CARLA has been developed to integrate with several 3rd party applications in ord
- [__Scenic__](tuto_G_scenic.md)
- [__CarSIM__](tuto_G_carsim_integration.md)
- [__Chrono__](tuto_G_chrono.md)
- [__OpenDRIVE__](adv_opendrive.md)
- [__ASAM OpenDRIVE__](adv_opendrive.md)
- [__PTV Vissim__](adv_ptv.md)
- [__RSS__](adv_rss.md)
- [__AWS and RLlib__](tuto_G_rllib_integration.md)
@ -59,9 +59,9 @@ CARLA's integration with CarSim allows vehicle controls in CARLA to be forwarded
Learn how to use CARLA alongside CarSIM [here](tuto_G_carsim_integration.md).
## OpenDRIVE
## ASAM OpenDRIVE
[__OpenDRIVE__](https://www.asam.net/standards/detail/opendrive/) is an open format specification used to describe the logic of a road network intended to standardise the discription of road networks in digital format and allow different applications to exchange data on road networks. Please refer to the full documentation [__here__](adv_opendrive.md)
[__ASAM OpenDRIVE__](https://www.asam.net/standards/detail/opendrive/) is an open format specification used to describe the logic of a road network intended to standardise the discription of road networks in digital format and allow different applications to exchange data on road networks. Please refer to the full documentation [__here__](adv_opendrive.md)
## RSS - Responsibility Sensitive Safety

View File

@ -17,7 +17,26 @@ The __Digital Twin Tool__ enables procedural generation of unique 3D environment
## Building the OSM renderer
If you are using Linux, you have the option of using the OSM renderer in the CARLA interface to navigate a large OSM map region that you have downloaded. You first need to build the OSM renderer. Run `make osmrenderer` inside the CARLA root directory. You may need to upgrade your version of CMake to v3.2 or above in order for this to work. This will create two folders in your build directory called `libosmcout-source` and `libosmcout-build`. Windows users do not have the option of using the OSM renderer and must use directly a URL.
If you are using Linux, you have the option of using the OSM renderer in the CARLA interface to navigate a large OSM map region that you have downloaded. You first need to build the OSM renderer before proceeding to build CARLA. Run `make osmrenderer` inside the CARLA root directory. You may need to upgrade your version of CMake to v3.2 or above in order for this to work. This will create two folders in your build directory called `libosmcout-source` and `libosmcout-build`. Before proceeding to build CARLA, you need to then edit the `Build.sh` file in the directory `$CARLA_ROOT/Build/libosmcout-source/maps` like so, to ensure the executable is found:
```bash
if [[ -x ../Import/src/Import ]]; then
importExe=../Import/src/Import
elif [[ -x ../debug/Import/Import ]]; then
importExe=../debug/Import/Import
elif [[ -x ../build/Import/Import ]]; then
importExe=../build/Import/Import
################### Add this line ####################
elif [ -x ../../libosmscout-build/Import/Import ]; then
importExe=../../libosmscout-build/Import/Import
#######################################################
else
echo "Cannot find Import executable!"
exit 1
fi
```
Then continue to build CARLA in the normal way. Windows users do not have the option of using the OSM renderer and must directly the URL.
## Downloading and preparing OSM map data

View File

@ -16,11 +16,11 @@ The parameters we can use are:
For example
**./CarlaUE4.sh --nullrhi**
**./CarlaUE4.sh -nullrhi**
The primary server will use by default the port 2002 to listen for secondary servers. If you need to listen on another port, then you can change it with the flag
**./CarlaUE4.sh --nullrhi -carla-primary-port=3002**
**./CarlaUE4.sh -nullrhi -carla-primary-port=3002**
## Secondary servers

View File

@ -1,6 +1,6 @@
# OpenDRIVE standalone mode
# ASAM OpenDRIVE standalone mode
This feature allows users to ingest any OpenDRIVE file as a CARLA map out-of-the-box. In order to do so, the simulator will automatically generate a road mesh for actors to navigate through.
This feature allows users to ingest any ASAM OpenDRIVE file as a CARLA map out-of-the-box. In order to do so, the simulator will automatically generate a road mesh for actors to navigate through.
* [__Overview__](#overview)
* [__Run a standalone map__](#run-a-standalone-map)
@ -26,9 +26,9 @@ Traffic lights, stops and yields will be generated on the fly. Pedestrians will
---
## Run a standalone map
Open an OpenDRIVE file is just a matter of calling [`client.generate_opendrive_world()`](python_api.md#carla.Client.generate_opendrive_world) through the API. This will generate the new map, and block the simulation until it is ready. The method needs for two parameters.
Open an ASAM OpenDRIVE file is just a matter of calling [`client.generate_opendrive_world()`](python_api.md#carla.Client.generate_opendrive_world) through the API. This will generate the new map, and block the simulation until it is ready. The method needs for two parameters.
* __`opendrive`__ is the content of the OpenDRIVE file parsed as a string.
* __`opendrive`__ is the content of the ASAM OpenDRIVE file parsed as a string.
* __`parameters`__ is a [carla.OpendriveGenerationParameters](python_api.md#carla.OpendriveGenerationParameters) containing settings for the generation of the mesh. __This argument is optional__.
* __`vertex_distance`__ *(default 2.0 meters)* — Distance between the vertices of the mesh. The bigger, the distance, the more inaccurate the mesh will be. However, if the distance is too small, the resulting mesh will be too heavy to work with.

View File

@ -76,7 +76,7 @@ CARLA forum</a>
> CARLA is a performance demanding software. At the very minimum it requires a 6GB GPU or, even better, a dedicated GPU capable of running Unreal Engine.
>
> Take a look at [Unreal Engine's recommended hardware](https://www.ue4community.wiki/recommended-hardware-x1p9qyg0).
> Take a look at [Unreal Engine's recommended hardware](https://dev.epicgames.com/documentation/en-us/unreal-engine/hardware-and-software-specifications-for-unreal-engine).
---
@ -365,7 +365,7 @@ CARLA forum</a>
>In Windows it will be the default Python version for:
> py -3 --version
> python --version
>Make sure you are running your scripts with the version of Python that corresponds to your `.egg` file.
>In Linux, you may also need to set your Python path to point to the CARLA `.egg`. To do this, run the following command:

View File

@ -37,7 +37,7 @@ __Blueprints__ are already-made actor layouts necessary to spawn an actor. Basic
### 3rd- Maps and navigation
__The map__ is the object representing the simulated world, the town mostly. There are eight maps available. All of them use OpenDRIVE 1.4 standard to describe the roads.
__The map__ is the object representing the simulated world, the town mostly. There are eight maps available. All of them use ASAM OpenDRIVE 1.4 standard to describe the roads.
__Roads, lanes and junctions__ are managed by the [Python API](python_api.md) to be accessed from the client. These are used along with the __waypoint__ class to provide vehicles with a navigation path.

View File

@ -23,6 +23,7 @@ After discussing about the world and its actors, it is time to put everything in
- [Add map package](tuto_M_add_map_package.md)
- [Add map source](tuto_M_add_map_source.md)
- [Alternative methods](tuto_M_add_map_alternative.md)
- [__Additional maps__](#additional-maps)
---
@ -257,6 +258,9 @@ Non-layered maps are shown in the table below (click the town name to see an ove
| [__Town11__](map_town11.md) | A Large Map that is undecorated. Serves as a proof of concept for the Large Maps feature. |
| [__Town12__](map_town12.md) | A Large Map with numerous different regions, including high-rise, residential and rural environments.|
!!! note
Town06 and Town07 are additional content which does not come with the standard CARLA package. Please see the [additional maps section](#additional-maps) for details on how to import these.
### Layered maps
The layout of layered maps is the same as non-layered maps but it is possible to toggle off and on the layers of the map. There is a minimum layout that cannot be toggled off and consists of roads, sidewalks, traffic lights and traffic signs. Layered maps can be identified by the suffix `_Opt`, for example, `Town01_Opt`. With these maps it is possible to [load][load_layer] and [unload][unload_layer] layers via the Python API:
@ -291,3 +295,27 @@ CARLA is designed to be extensible and highly customisable for specialist applic
* [__Add map package__](tuto_M_add_map_package.md)
* [__Add map source__](tuto_M_add_map_source.md)
* [__Alternative methods__](tuto_M_add_map_alternative.md)
## Additional maps
Each release has it's own additional package of extra assets and maps. This additional package includes the maps __Town06__ and __Town07__. These are stored separately to reduce the size of the build, so they can only be imported after the main package has been installed.
__1.__ [Download](https://github.com/carla-simulator/carla/blob/master/Docs/download.md) the appropriate package for your desired version of CARLA.
__2.__ Extract the package:
- __On Linux__:
- move the package to the _Import_ folder and run the following script to extract the contents:
```sh
cd path/to/carla/root
./ImportAssets.sh
```
- __On Windows__:
- Extract the contents directly in the root folder.
---

View File

@ -434,7 +434,13 @@ Enum declaration that contains the different tags available to filter the boundi
- <a name="carla.CityObjectLabel.Sidewalks"></a>**<font color="#f8805a">Sidewalks</font>**
- <a name="carla.CityObjectLabel.TrafficSigns"></a>**<font color="#f8805a">TrafficSigns</font>**
- <a name="carla.CityObjectLabel.Vegetation"></a>**<font color="#f8805a">Vegetation</font>**
- <a name="carla.CityObjectLabel.Vehicles"></a>**<font color="#f8805a">Vehicles</font>**
- <a name="carla.CityObjectLabel.Car"></a>**<font color="#f8805a">Car</font>**
- <a name="carla.CityObjectLabel.Bus"></a>**<font color="#f8805a">Bus</font>**
- <a name="carla.CityObjectLabel.Truck"></a>**<font color="#f8805a">Truck</font>**
- <a name="carla.CityObjectLabel.Motorcycle"></a>**<font color="#f8805a">Motorcycle</font>**
- <a name="carla.CityObjectLabel.Bicycle"></a>**<font color="#f8805a">Bicycle</font>**
- <a name="carla.CityObjectLabel.Rider"></a>**<font color="#f8805a">Rider</font>**
- <a name="carla.CityObjectLabel.Train"></a>**<font color="#f8805a">Train</font>**
- <a name="carla.CityObjectLabel.Walls"></a>**<font color="#f8805a">Walls</font>**
- <a name="carla.CityObjectLabel.Sky"></a>**<font color="#f8805a">Sky</font>**
- <a name="carla.CityObjectLabel.Ground"></a>**<font color="#f8805a">Ground</font>**
@ -475,7 +481,7 @@ Executes a list of commands on a single simulation step, blocks until the comman
- <a name="carla.Client.generate_opendrive_world"></a>**<font color="#7fb800">generate_opendrive_world</font>**(<font color="#00a6ed">**self**</font>, <font color="#00a6ed">**opendrive**</font>, <font color="#00a6ed">**parameters**=(2.0, 50.0, 1.0, 0.6, true, true)</font>, <font color="#00a6ed">**reset_settings**=True</font>)
Loads a new world with a basic 3D topology generated from the content of an OpenDRIVE file. This content is passed as a `string` parameter. It is similar to `client.load_world(map_name)` but allows for custom OpenDRIVE maps in server side. Cars can drive around the map, but there are no graphics besides the road and sidewalks.
- **Parameters:**
- `opendrive` (_str_) - Content of an OpenDRIVE file as `string`, __not the path to the `.xodr`__.
- `opendrive` (_str_) - Content of an ASAM OpenDRIVE file as `string`, __not the path to the `.xodr`__.
- `parameters` (_[carla.OpendriveGenerationParameters](#carla.OpendriveGenerationParameters)_) - Additional settings for the mesh generation. If none are provided, default values will be used.
- `reset_settings` (_bool_) - Option to reset the episode setting to default values, set to false to keep the current settings. This is useful to keep sync mode when changing map and to keep deterministic scenarios.
- <a name="carla.Client.load_world"></a>**<font color="#7fb800">load_world</font>**(<font color="#00a6ed">**self**</font>, <font color="#00a6ed">**map_name**</font>, <font color="#00a6ed">**reset_settings**=True</font>, <font color="#00a6ed">**map_layers**=[carla.MapLayer.All](#carla.MapLayer.All)</font>)
@ -484,12 +490,23 @@ Creates a new world with default settings using `map_name` map. All actors in th
- `map_name` (_str_) - Name of the map to be used in this world. Accepts both full paths and map names, e.g. '/Game/Carla/Maps/Town01' or 'Town01'. Remember that these paths are dynamic.
- `reset_settings` (_bool_) - Option to reset the episode setting to default values, set to false to keep the current settings. This is useful to keep sync mode when changing map and to keep deterministic scenarios.
- `map_layers` (_[carla.MapLayer](#carla.MapLayer)_) - Layers of the map that will be loaded. By default all layers are loaded. This parameter works like a flag mask.
- **Return:** _[carla.World](#carla.World)_
- **Warning:** <font color="#ED2F2F">_`map_layers` are only available for "Opt" maps
_</font>
- <a name="carla.Client.load_world_if_different"></a>**<font color="#7fb800">load_world_if_different</font>**(<font color="#00a6ed">**self**</font>, <font color="#00a6ed">**map_name**</font>, <font color="#00a6ed">**reset_settings**=True</font>, <font color="#00a6ed">**map_layers**=[carla.MapLayer.All](#carla.MapLayer.All)</font>)
Creates a new world with default settings using `map_name` map only if it is a different map from the currently loaded map. Otherwise this function returns `None`. All actors in the current world will be destroyed.
- **Parameters:**
- `map_name` (_str_) - Name of the map to be used in this world. Accepts both full paths and map names, e.g. '/Game/Carla/Maps/Town01' or 'Town01'. Remember that these paths are dynamic.
- `reset_settings` (_bool_) - Option to reset the episode setting to default values, set to false to keep the current settings. This is useful to keep sync mode when changing map and to keep deterministic scenarios.
- `map_layers` (_[carla.MapLayer](#carla.MapLayer)_) - Layers of the map that will be loaded. By default all layers are loaded. This parameter works like a flag mask.
- **Return:** _[carla.World](#carla.World)_
- **Warning:** <font color="#ED2F2F">_`map_layers` are only available for "Opt" maps
_</font>
- <a name="carla.Client.reload_world"></a>**<font color="#7fb800">reload_world</font>**(<font color="#00a6ed">**self**</font>, <font color="#00a6ed">**reset_settings**=True</font>)
Reload the current world, note that a new world is created with default settings using the same map. All actors present in the world will be destroyed, __but__ traffic manager instances will stay alive.
- **Parameters:**
- `reset_settings` (_bool_) - Option to reset the episode setting to default values, set to false to keep the current settings. This is useful to keep sync mode when changing map and to keep deterministic scenarios.
- **Return:** _[carla.World](#carla.World)_
- **Raises:** RuntimeError when corresponding.
- <a name="carla.Client.replay_file"></a>**<font color="#7fb800">replay_file</font>**(<font color="#00a6ed">**self**</font>, <font color="#00a6ed">**name**</font>, <font color="#00a6ed">**start**</font>, <font color="#00a6ed">**duration**</font>, <font color="#00a6ed">**follow_id**</font>, <font color="#00a6ed">**replay_sensors**</font>)
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.
@ -722,13 +739,45 @@ Draws an arrow from `begin` to `end` pointing in that direction.
- `color` (_[carla.Color](#carla.Color)_) - RGB code to color the object. Red by default.
- `life_time` (_float<small> - seconds</small>_) - Shape's lifespan. By default it only lasts one frame. Set this to <code>0</code> for permanent shapes.
- <a name="carla.DebugHelper.draw_box"></a>**<font color="#7fb800">draw_box</font>**(<font color="#00a6ed">**self**</font>, <font color="#00a6ed">**box**</font>, <font color="#00a6ed">**rotation**</font>, <font color="#00a6ed">**thickness**=0.1</font>, <font color="#00a6ed">**color**=(255,0,0)</font>, <font color="#00a6ed">**life_time**=-1.0</font>)<button class="SnipetButton" id="carla.DebugHelper.draw_box-snipet_button">snippet &rarr;</button>
Draws a box, ussually to act for object colliders.
Draws a box, usually 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)<small> - degrees (pitch,yaw,roll)</small>_) - Orientation of the box according to Unreal Engine's axis system.
- `thickness` (_float<small> - meters</small>_) - 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<small> - seconds</small>_) - Shape's lifespan. By default it only lasts one frame. Set this to <code>0</code> for permanent shapes.
- <a name="carla.DebugHelper.draw_hud_arrow"></a>**<font color="#7fb800">draw_hud_arrow</font>**(<font color="#00a6ed">**self**</font>, <font color="#00a6ed">**begin**</font>, <font color="#00a6ed">**end**</font>, <font color="#00a6ed">**thickness**=0.1</font>, <font color="#00a6ed">**arrow_size**=0.1</font>, <font color="#00a6ed">**color**=(255,0,0)</font>, <font color="#00a6ed">**life_time**=-1.0</font>)
Draws an arrow on the HUD from `begin` to `end` which can only be seen server-side.
- **Parameters:**
- `begin` (_[carla.Location](#carla.Location)<small> - meters</small>_) - Point in the coordinate system where the arrow starts.
- `end` (_[carla.Location](#carla.Location)<small> - meters</small>_) - Point in the coordinate system where the arrow ends and points towards to.
- `thickness` (_float<small> - meters</small>_) - Density of the line.
- `arrow_size` (_float<small> - meters</small>_) - Size of the tip of the arrow.
- `color` (_[carla.Color](#carla.Color)_) - RGB code to color the object. Red by default.
- `life_time` (_float<small> - seconds</small>_) - Shape's lifespan. By default it only lasts one frame. Set this to <code>0</code> for permanent shapes.
- <a name="carla.DebugHelper.draw_hud_box"></a>**<font color="#7fb800">draw_hud_box</font>**(<font color="#00a6ed">**self**</font>, <font color="#00a6ed">**box**</font>, <font color="#00a6ed">**rotation**</font>, <font color="#00a6ed">**thickness**=0.1</font>, <font color="#00a6ed">**color**=(255,0,0)</font>, <font color="#00a6ed">**life_time**=-1.0</font>)
Draws a box on the HUD, usually to act for object colliders. The box can only be seen server-side.
- **Parameters:**
- `box` (_[carla.BoundingBox](#carla.BoundingBox)_) - Object containing a location and the length of a box for every axis.
- `rotation` (_[carla.Rotation](#carla.Rotation)<small> - degrees (pitch,yaw,roll)</small>_) - Orientation of the box according to Unreal Engine's axis system.
- `thickness` (_float<small> - meters</small>_) - 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<small> - seconds</small>_) - Shape's lifespan. By default it only lasts one frame. Set this to <code>0</code> for permanent shapes.
- <a name="carla.DebugHelper.draw_hud_line"></a>**<font color="#7fb800">draw_hud_line</font>**(<font color="#00a6ed">**self**</font>, <font color="#00a6ed">**begin**</font>, <font color="#00a6ed">**end**</font>, <font color="#00a6ed">**thickness**=0.1</font>, <font color="#00a6ed">**color**=(255,0,0)</font>, <font color="#00a6ed">**life_time**=-1.0</font>)
Draws a line on the HUD in between `begin` and `end`. The line can only be seen server-side.
- **Parameters:**
- `begin` (_[carla.Location](#carla.Location)<small> - meters</small>_) - Point in the coordinate system where the line starts.
- `end` (_[carla.Location](#carla.Location)<small> - meters</small>_) - Spot in the coordinate system where the line ends.
- `thickness` (_float<small> - meters</small>_) - Density of the line.
- `color` (_[carla.Color](#carla.Color)_) - RGB code to color the object. Red by default.
- `life_time` (_float<small> - seconds</small>_) - Shape's lifespan. By default it only lasts one frame. Set this to <code>0</code> for permanent shapes.
- <a name="carla.DebugHelper.draw_hud_point"></a>**<font color="#7fb800">draw_hud_point</font>**(<font color="#00a6ed">**self**</font>, <font color="#00a6ed">**location**</font>, <font color="#00a6ed">**size**=0.1</font>, <font color="#00a6ed">**color**=(255,0,0)</font>, <font color="#00a6ed">**life_time**=-1.0</font>)
Draws a point on the HUD at `location`. The point can only be seen server-side.
- **Parameters:**
- `location` (_[carla.Location](#carla.Location)<small> - meters</small>_) - Spot in the coordinate system to center the object.
- `size` (_float<small> - meters</small>_) - Density of the point.
- `color` (_[carla.Color](#carla.Color)_) - RGB code to color the object. Red by default.
- `life_time` (_float<small> - seconds</small>_) - Shape's lifespan. By default it only lasts one frame. Set this to <code>0</code> for permanent shapes.
- <a name="carla.DebugHelper.draw_line"></a>**<font color="#7fb800">draw_line</font>**(<font color="#00a6ed">**self**</font>, <font color="#00a6ed">**begin**</font>, <font color="#00a6ed">**end**</font>, <font color="#00a6ed">**thickness**=0.1</font>, <font color="#00a6ed">**color**=(255,0,0)</font>, <font color="#00a6ed">**life_time**=-1.0</font>)
Draws a line in between `begin` and `end`.
- **Parameters:**
@ -1706,7 +1755,7 @@ Distance between `actor` and `other`.
---
## carla.OpendriveGenerationParameters<a name="carla.OpendriveGenerationParameters"></a>
This class defines the parameters used when generating a world using an OpenDRIVE file.
This class defines the parameters used when generating a world using an ASAM OpenDRIVE file.
### Instance Variables
- <a name="carla.OpendriveGenerationParameters.vertex_distance"></a>**<font color="#f8805a">vertex_distance</font>** (_float_)
@ -2202,6 +2251,12 @@ Sensors compound a specific family of actors quite diverse and unique. They are
When <b>True</b> the sensor will be waiting for data.
### Methods
- <a name="carla.Sensor.disable_for_ros"></a>**<font color="#7fb800">disable_for_ros</font>**(<font color="#00a6ed">**self**</font>)
Commands the sensor to not be processed for publishing in ROS2 if there is no any listen to it.
- <a name="carla.Sensor.enable_for_ros"></a>**<font color="#7fb800">enable_for_ros</font>**(<font color="#00a6ed">**self**</font>)
Commands the sensor to be processed to be able to publish in ROS2 without any listen to it.
- <a name="carla.Sensor.is_enabled_for_ros"></a>**<font color="#7fb800">is_enabled_for_ros</font>**(<font color="#00a6ed">**self**</font>)
Returns if the sensor is enabled or not to publish in ROS2 if there is no any listen to it.
- <a name="carla.Sensor.is_listening"></a>**<font color="#7fb800">is_listening</font>**(<font color="#00a6ed">**self**</font>)
Returns whether the sensor is in a listening state.
- <a name="carla.Sensor.is_listening_gbuffer"></a>**<font color="#7fb800">is_listening_gbuffer</font>**(<font color="#00a6ed">**self**</font>, <font color="#00a6ed">**gbuffer_id**</font>)
@ -3733,9 +3788,9 @@ When enabled, the simulation will run no rendering at all. This is mainly used t
- <a name="carla.WorldSettings.fixed_delta_seconds"></a>**<font color="#f8805a">fixed_delta_seconds</font>** (_float_)
Ensures that the time elapsed between two steps of the simulation is fixed. Set this to <b>0.0</b> to work with a variable time-step, as happens by default.
- <a name="carla.WorldSettings.substepping"></a>**<font color="#f8805a">substepping</font>** (_bool_)
Enable the physics substepping. This option allows computing some physics substeps between two render frames. If synchronous mode is set, the number of substeps and its time interval are fixed and computed are so they fulfilled the requirements of [carla.WorldSettings.max_substep](#carla.WorldSettings.max_substep) and [carla.WorldSettings.max_substep_delta_time](#carla.WorldSettings.max_substep_delta_time). These last two parameters need to be compatible with [carla.WorldSettings.fixed_delta_seconds](#carla.WorldSettings.fixed_delta_seconds). Enabled by default.
Enable the physics substepping. This option allows computing some physics substeps between two render frames. If synchronous mode is set, the number of substeps and its time interval are fixed and computed are so they fulfilled the requirements of [carla.WorldSettings.max_substeps](#carla.WorldSettings.max_substeps) and [carla.WorldSettings.max_substep_delta_time](#carla.WorldSettings.max_substep_delta_time). These last two parameters need to be compatible with [carla.WorldSettings.fixed_delta_seconds](#carla.WorldSettings.fixed_delta_seconds). Enabled by default.
- <a name="carla.WorldSettings.max_substep_delta_time"></a>**<font color="#f8805a">max_substep_delta_time</font>** (_float_)
Maximum delta time of the substeps. If the [carla.WorldSettingsmax_substep](#carla.WorldSettingsmax_substep) is high enough, the substep delta time would be always below or equal to this value. By default, the value is set to 0.01.
Maximum delta time of the substeps. If the [carla.WorldSettings.max_substeps](#carla.WorldSettings.max_substeps) is high enough, the substep delta time would be always below or equal to this value. By default, the value is set to 0.01.
- <a name="carla.WorldSettings.max_substeps"></a>**<font color="#f8805a">max_substeps</font>** (_int_)
The maximum number of physics substepping that are allowed. By default, the value is set to 10.
- <a name="carla.WorldSettings.max_culling_distance"></a>**<font color="#f8805a">max_culling_distance</font>** (_float_)
@ -4034,6 +4089,11 @@ Actor affected by the command.
---
## command.FutureActor<a name="command.FutureActor"></a>
A utility object used to reference an actor that will be created in the command in the previous step, it has no parameters or methods.
---
## command.Response<a name="command.Response"></a>
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 __<font color="#7fb800">apply_batch_sync()</font>__ in [carla.Client](#carla.Client) returns a list of these to summarize the execution of a batch.
@ -4188,33 +4248,29 @@ document.getElementById("snipets-container").innerHTML = null;
}
</script>
<div id ="carla.World.enable_environment_objects-snipet" style="display: none;">
<div id ="carla.World.unload_map_layer-snipet" style="display: none;">
<p class="SnipetFont">
Snippet for carla.World.enable_environment_objects
Snippet for carla.World.unload_map_layer
</p>
<div id="carla.World.enable_environment_objects-code" class="SnipetContent">
<div id="carla.World.unload_map_layer-code" class="SnipetContent">
```py
# This recipe turn visibility off and on for two specifc buildings on the map
# This recipe toggles off several layers in our "_Opt" maps
# Get the buildings in the world
world = client.get_world()
env_objs = world.get_environment_objects(carla.CityObjectLabel.Buildings)
# Load town one with minimum layout (roads, sidewalks, traffic lights and traffic signs)
# as well as buildings and parked vehicles
world = client.load_world('Town01_Opt', carla.MapLayer.Buildings | carla.MapLayer.ParkedVehicles)
# Access individual building IDs and save in a set
building_01 = env_objs[0]
building_02 = env_objs[1]
objects_to_toggle = {building_01.id, building_02.id}
# Toggle all buildings off
world.unload_map_layer(carla.MapLayer.Buildings)
# Toggle buildings off
world.enable_environment_objects(objects_to_toggle, False)
# Toggle buildings on
world.enable_environment_objects(objects_to_toggle, True)
# Toggle all parked vehicles off
world.unload_map_layer(carla.MapLayer.ParkedVehicles)
```
<button id="button1" class="CopyScript" onclick="CopyToClipboard('carla.World.enable_environment_objects-code')">Copy snippet</button>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<button id="button1" class="CloseSnipet" onclick="CloseSnipet()">Close snippet</button><br><br>
<button id="button1" class="CopyScript" onclick="CopyToClipboard('carla.World.unload_map_layer-code')">Copy snippet</button>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<button id="button1" class="CloseSnipet" onclick="CloseSnipet()">Close snippet</button><br><br>
</div>
@ -4257,206 +4313,37 @@ while True:
</div>
<div id ="carla.World.unload_map_layer-snipet" style="display: none;">
<div id ="carla.ActorBlueprint.set_attribute-snipet" style="display: none;">
<p class="SnipetFont">
Snippet for carla.World.unload_map_layer
Snippet for carla.ActorBlueprint.set_attribute
</p>
<div id="carla.World.unload_map_layer-code" class="SnipetContent">
```py
# This recipe toggles off several layers in our "_Opt" maps
# Load town one with minimum layout (roads, sidewalks, traffic lights and traffic signs)
# as well as buildings and parked vehicles
world = client.load_world('Town01_Opt', carla.MapLayer.Buildings | carla.MapLayer.ParkedVehicles)
# Toggle all buildings off
world.unload_map_layer(carla.MapLayer.Buildings)
# Toggle all parked vehicles off
world.unload_map_layer(carla.MapLayer.ParkedVehicles)
```
<button id="button1" class="CopyScript" onclick="CopyToClipboard('carla.World.unload_map_layer-code')">Copy snippet</button>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<button id="button1" class="CloseSnipet" onclick="CloseSnipet()">Close snippet</button><br><br>
</div>
<div id ="carla.Vehicle.set_wheel_steer_direction-snipet" style="display: none;">
<p class="SnipetFont">
Snippet for carla.Vehicle.set_wheel_steer_direction
</p>
<div id="carla.Vehicle.set_wheel_steer_direction-code" class="SnipetContent">
```py
# Sets the appearance of the vehicles front wheels to 40°. Vehicle physics will not be affected.
vehicle.set_wheel_steer_direction(carla.VehicleWheelLocation.FR_Wheel, 40.0)
vehicle.set_wheel_steer_direction(carla.VehicleWheelLocation.FL_Wheel, 40.0)
```
<button id="button1" class="CopyScript" onclick="CopyToClipboard('carla.Vehicle.set_wheel_steer_direction-code')">Copy snippet</button>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<button id="button1" class="CloseSnipet" onclick="CloseSnipet()">Close snippet</button><br><br>
</div>
<div id ="carla.Client.__init__-snipet" style="display: none;">
<p class="SnipetFont">
Snippet for carla.Client.__init__
</p>
<div id="carla.Client.__init__-code" class="SnipetContent">
<div id="carla.ActorBlueprint.set_attribute-code" class="SnipetContent">
```py
# This recipe shows in every script provided in PythonAPI/Examples
# and it is used to parse the client creation arguments when running the script.
argparser = argparse.ArgumentParser(
description=__doc__)
argparser.add_argument(
'--host',
metavar='H',
default='127.0.0.1',
help='IP of the host server (default: 127.0.0.1)')
argparser.add_argument(
'-p', '--port',
metavar='P',
default=2000,
type=int,
help='TCP port to listen to (default: 2000)')
argparser.add_argument(
'-s', '--speed',
metavar='FACTOR',
default=1.0,
type=float,
help='rate at which the weather changes (default: 1.0)')
args = argparser.parse_args()
speed_factor = args.speed
update_freq = 0.1 / speed_factor
client = carla.Client(args.host, args.port)
```
<button id="button1" class="CopyScript" onclick="CopyToClipboard('carla.Client.__init__-code')">Copy snippet</button>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<button id="button1" class="CloseSnipet" onclick="CloseSnipet()">Close snippet</button><br><br>
</div>
<div id ="carla.Map.get_waypoint-snipet" style="display: none;">
<p class="SnipetFont">
Snippet for carla.Map.get_waypoint
</p>
<div id="carla.Map.get_waypoint-code" class="SnipetContent">
```py
# This recipe shows the current traffic rules affecting the vehicle.
# Shows the current lane type and if a lane change can be done in the actual lane or the surrounding ones.
# This recipe changes attributes of different type of blueprint actors.
# ...
waypoint = world.get_map().get_waypoint(vehicle.get_location(),project_to_road=True, lane_type=(carla.LaneType.Driving | carla.LaneType.Shoulder | carla.LaneType.Sidewalk))
print("Current lane type: " + str(waypoint.lane_type))
# Check current lane change allowed
print("Current Lane change: " + str(waypoint.lane_change))
# Left and Right lane markings
print("L lane marking type: " + str(waypoint.left_lane_marking.type))
print("L lane marking change: " + str(waypoint.left_lane_marking.lane_change))
print("R lane marking type: " + str(waypoint.right_lane_marking.type))
print("R lane marking change: " + str(waypoint.right_lane_marking.lane_change))
walker_bp = world.get_blueprint_library().filter('walker.pedestrian.0002')
walker_bp.set_attribute('is_invincible', True)
# ...
# Changes attribute randomly by the recommended value
vehicle_bp = wolrd.get_blueprint_library().filter('vehicle.bmw.*')
color = random.choice(vehicle_bp.get_attribute('color').recommended_values)
vehicle_bp.set_attribute('color', color)
# ...
camera_bp = world.get_blueprint_library().filter('sensor.camera.rgb')
camera_bp.set_attribute('image_size_x', 600)
camera_bp.set_attribute('image_size_y', 600)
# ...
```
<button id="button1" class="CopyScript" onclick="CopyToClipboard('carla.Map.get_waypoint-code')">Copy snippet</button>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<button id="button1" class="CloseSnipet" onclick="CloseSnipet()">Close snippet</button><br><br>
<img src="/img/snipets_images/carla.Map.get_waypoint.jpg">
</div>
<div id ="carla.World.spawn_actor-snipet" style="display: none;">
<p class="SnipetFont">
Snippet for carla.World.spawn_actor
</p>
<div id="carla.World.spawn_actor-code" class="SnipetContent">
```py
# This recipe attaches different camera / sensors to a vehicle with different attachments.
# ...
camera = world.spawn_actor(rgb_camera_bp, transform, attach_to=vehicle, attachment_type=Attachment.Rigid)
# Default attachment: Attachment.Rigid
gnss_sensor = world.spawn_actor(sensor_gnss_bp, transform, attach_to=vehicle)
collision_sensor = world.spawn_actor(sensor_collision_bp, transform, attach_to=vehicle)
lane_invasion_sensor = world.spawn_actor(sensor_lane_invasion_bp, transform, attach_to=vehicle)
# ...
```
<button id="button1" class="CopyScript" onclick="CopyToClipboard('carla.World.spawn_actor-code')">Copy snippet</button>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<button id="button1" class="CloseSnipet" onclick="CloseSnipet()">Close snippet</button><br><br>
</div>
<div id ="carla.WalkerAIController.stop-snipet" style="display: none;">
<p class="SnipetFont">
Snippet for carla.WalkerAIController.stop
</p>
<div id="carla.WalkerAIController.stop-code" class="SnipetContent">
```py
#To destroy the pedestrians, stop them from the navigation, and then destroy the objects (actor and controller).
# stop pedestrians (list is [controller, actor, controller, actor ...])
for i in range(0, len(all_id), 2):
all_actors[i].stop()
# destroy pedestrian (actor and controller)
client.apply_batch([carla.command.DestroyActor(x) for x in all_id])
```
<button id="button1" class="CopyScript" onclick="CopyToClipboard('carla.WalkerAIController.stop-code')">Copy snippet</button>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<button id="button1" class="CloseSnipet" onclick="CloseSnipet()">Close snippet</button><br><br>
</div>
<div id ="carla.DebugHelper.draw_box-snipet" style="display: none;">
<p class="SnipetFont">
Snippet for carla.DebugHelper.draw_box
</p>
<div id="carla.DebugHelper.draw_box-code" class="SnipetContent">
```py
# This recipe shows how to draw traffic light actor bounding boxes from a world snapshot.
# ....
debug = world.debug
world_snapshot = world.get_snapshot()
for actor_snapshot in world_snapshot:
actual_actor = world.get_actor(actor_snapshot.id)
if actual_actor.type_id == 'traffic.traffic_light':
debug.draw_box(carla.BoundingBox(actor_snapshot.get_transform().location,carla.Vector3D(0.5,0.5,2)),actor_snapshot.get_transform().rotation, 0.05, carla.Color(255,0,0,0),0)
# ...
```
<button id="button1" class="CopyScript" onclick="CopyToClipboard('carla.DebugHelper.draw_box-code')">Copy snippet</button>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<button id="button1" class="CloseSnipet" onclick="CloseSnipet()">Close snippet</button><br><br>
<img src="/img/snipets_images/carla.DebugHelper.draw_box.jpg">
<button id="button1" class="CopyScript" onclick="CopyToClipboard('carla.ActorBlueprint.set_attribute-code')">Copy snippet</button>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<button id="button1" class="CloseSnipet" onclick="CloseSnipet()">Close snippet</button><br><br>
</div>
@ -4520,6 +4407,67 @@ camera.listen(lambda image: image.save_to_disk('output/%06d.png' % image.frame,
</div>
<div id ="carla.World.load_map_layer-snipet" style="display: none;">
<p class="SnipetFont">
Snippet for carla.World.load_map_layer
</p>
<div id="carla.World.load_map_layer-code" class="SnipetContent">
```py
# This recipe toggles on several layers in our "_Opt" maps
# Load town one with only minimum layout (roads, sidewalks, traffic lights and traffic signs)
world = client.load_world('Town01_Opt', carla.MapLayer.None)
# Toggle all buildings on
world.load_map_layer(carla.MapLayer.Buildings)
# Toggle all foliage on
world.load_map_layer(carla.MapLayer.Foliage)
# Toggle all parked vehicles on
world.load_map_layer(carla.MapLayer.ParkedVehicles)
```
<button id="button1" class="CopyScript" onclick="CopyToClipboard('carla.World.load_map_layer-code')">Copy snippet</button>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<button id="button1" class="CloseSnipet" onclick="CloseSnipet()">Close snippet</button><br><br>
</div>
<div id ="carla.Map.get_waypoint-snipet" style="display: none;">
<p class="SnipetFont">
Snippet for carla.Map.get_waypoint
</p>
<div id="carla.Map.get_waypoint-code" class="SnipetContent">
```py
# This recipe shows the current traffic rules affecting the vehicle.
# Shows the current lane type and if a lane change can be done in the actual lane or the surrounding ones.
# ...
waypoint = world.get_map().get_waypoint(vehicle.get_location(),project_to_road=True, lane_type=(carla.LaneType.Driving | carla.LaneType.Shoulder | carla.LaneType.Sidewalk))
print("Current lane type: " + str(waypoint.lane_type))
# Check current lane change allowed
print("Current Lane change: " + str(waypoint.lane_change))
# Left and Right lane markings
print("L lane marking type: " + str(waypoint.left_lane_marking.type))
print("L lane marking change: " + str(waypoint.left_lane_marking.lane_change))
print("R lane marking type: " + str(waypoint.right_lane_marking.type))
print("R lane marking change: " + str(waypoint.right_lane_marking.lane_change))
# ...
```
<button id="button1" class="CopyScript" onclick="CopyToClipboard('carla.Map.get_waypoint-code')">Copy snippet</button>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<button id="button1" class="CloseSnipet" onclick="CloseSnipet()">Close snippet</button><br><br>
<img src="/img/snipets_images/carla.Map.get_waypoint.jpg">
</div>
<div id ="carla.TrafficLight.set_state-snipet" style="display: none;">
<p class="SnipetFont">
Snippet for carla.TrafficLight.set_state
@ -4566,37 +4514,77 @@ if vehicle_actor.is_at_traffic_light():
</div>
<div id ="carla.ActorBlueprint.set_attribute-snipet" style="display: none;">
<div id ="carla.Vehicle.set_wheel_steer_direction-snipet" style="display: none;">
<p class="SnipetFont">
Snippet for carla.ActorBlueprint.set_attribute
Snippet for carla.Vehicle.set_wheel_steer_direction
</p>
<div id="carla.ActorBlueprint.set_attribute-code" class="SnipetContent">
<div id="carla.Vehicle.set_wheel_steer_direction-code" class="SnipetContent">
```py
# Sets the appearance of the vehicles front wheels to 40°. Vehicle physics will not be affected.
vehicle.set_wheel_steer_direction(carla.VehicleWheelLocation.FR_Wheel, 40.0)
vehicle.set_wheel_steer_direction(carla.VehicleWheelLocation.FL_Wheel, 40.0)
```
<button id="button1" class="CopyScript" onclick="CopyToClipboard('carla.Vehicle.set_wheel_steer_direction-code')">Copy snippet</button>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<button id="button1" class="CloseSnipet" onclick="CloseSnipet()">Close snippet</button><br><br>
</div>
<div id ="carla.DebugHelper.draw_box-snipet" style="display: none;">
<p class="SnipetFont">
Snippet for carla.DebugHelper.draw_box
</p>
<div id="carla.DebugHelper.draw_box-code" class="SnipetContent">
```py
# This recipe changes attributes of different type of blueprint actors.
# This recipe shows how to draw traffic light actor bounding boxes from a world snapshot.
# ...
walker_bp = world.get_blueprint_library().filter('walker.pedestrian.0002')
walker_bp.set_attribute('is_invincible', True)
# ...
# Changes attribute randomly by the recommended value
vehicle_bp = wolrd.get_blueprint_library().filter('vehicle.bmw.*')
color = random.choice(vehicle_bp.get_attribute('color').recommended_values)
vehicle_bp.set_attribute('color', color)
# ....
debug = world.debug
world_snapshot = world.get_snapshot()
for actor_snapshot in world_snapshot:
actual_actor = world.get_actor(actor_snapshot.id)
if actual_actor.type_id == 'traffic.traffic_light':
debug.draw_box(carla.BoundingBox(actor_snapshot.get_transform().location,carla.Vector3D(0.5,0.5,2)),actor_snapshot.get_transform().rotation, 0.05, carla.Color(255,0,0,0),0)
# ...
camera_bp = world.get_blueprint_library().filter('sensor.camera.rgb')
camera_bp.set_attribute('image_size_x', 600)
camera_bp.set_attribute('image_size_y', 600)
# ...
```
<button id="button1" class="CopyScript" onclick="CopyToClipboard('carla.ActorBlueprint.set_attribute-code')">Copy snippet</button>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<button id="button1" class="CloseSnipet" onclick="CloseSnipet()">Close snippet</button><br><br>
<button id="button1" class="CopyScript" onclick="CopyToClipboard('carla.DebugHelper.draw_box-code')">Copy snippet</button>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<button id="button1" class="CloseSnipet" onclick="CloseSnipet()">Close snippet</button><br><br>
<img src="/img/snipets_images/carla.DebugHelper.draw_box.jpg">
</div>
<div id ="carla.WalkerAIController.stop-snipet" style="display: none;">
<p class="SnipetFont">
Snippet for carla.WalkerAIController.stop
</p>
<div id="carla.WalkerAIController.stop-code" class="SnipetContent">
```py
#To destroy the pedestrians, stop them from the navigation, and then destroy the objects (actor and controller).
# stop pedestrians (list is [controller, actor, controller, actor ...])
for i in range(0, len(all_id), 2):
all_actors[i].stop()
# destroy pedestrian (actor and controller)
client.apply_batch([carla.command.DestroyActor(x) for x in all_id])
```
<button id="button1" class="CopyScript" onclick="CopyToClipboard('carla.WalkerAIController.stop-code')">Copy snippet</button>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<button id="button1" class="CloseSnipet" onclick="CloseSnipet()">Close snippet</button><br><br>
</div>
@ -4673,31 +4661,103 @@ for i in range(0, len(all_actors), 2):
</div>
<div id ="carla.World.load_map_layer-snipet" style="display: none;">
<div id ="carla.World.enable_environment_objects-snipet" style="display: none;">
<p class="SnipetFont">
Snippet for carla.World.load_map_layer
Snippet for carla.World.enable_environment_objects
</p>
<div id="carla.World.load_map_layer-code" class="SnipetContent">
<div id="carla.World.enable_environment_objects-code" class="SnipetContent">
```py
# This recipe toggles on several layers in our "_Opt" maps
# This recipe turn visibility off and on for two specifc buildings on the map
# Load town one with only minimum layout (roads, sidewalks, traffic lights and traffic signs)
world = client.load_world('Town01_Opt', carla.MapLayer.None)
# Get the buildings in the world
world = client.get_world()
env_objs = world.get_environment_objects(carla.CityObjectLabel.Buildings)
# Toggle all buildings on
world.load_map_layer(carla.MapLayer.Buildings)
# Access individual building IDs and save in a set
building_01 = env_objs[0]
building_02 = env_objs[1]
objects_to_toggle = {building_01.id, building_02.id}
# Toggle all foliage on
world.load_map_layer(carla.MapLayer.Foliage)
# Toggle all parked vehicles on
world.load_map_layer(carla.MapLayer.ParkedVehicles)
# Toggle buildings off
world.enable_environment_objects(objects_to_toggle, False)
# Toggle buildings on
world.enable_environment_objects(objects_to_toggle, True)
```
<button id="button1" class="CopyScript" onclick="CopyToClipboard('carla.World.load_map_layer-code')">Copy snippet</button>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<button id="button1" class="CloseSnipet" onclick="CloseSnipet()">Close snippet</button><br><br>
<button id="button1" class="CopyScript" onclick="CopyToClipboard('carla.World.enable_environment_objects-code')">Copy snippet</button>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<button id="button1" class="CloseSnipet" onclick="CloseSnipet()">Close snippet</button><br><br>
</div>
<div id ="carla.Client.__init__-snipet" style="display: none;">
<p class="SnipetFont">
Snippet for carla.Client.__init__
</p>
<div id="carla.Client.__init__-code" class="SnipetContent">
```py
# This recipe shows in every script provided in PythonAPI/Examples
# and it is used to parse the client creation arguments when running the script.
argparser = argparse.ArgumentParser(
description=__doc__)
argparser.add_argument(
'--host',
metavar='H',
default='127.0.0.1',
help='IP of the host server (default: 127.0.0.1)')
argparser.add_argument(
'-p', '--port',
metavar='P',
default=2000,
type=int,
help='TCP port to listen to (default: 2000)')
argparser.add_argument(
'-s', '--speed',
metavar='FACTOR',
default=1.0,
type=float,
help='rate at which the weather changes (default: 1.0)')
args = argparser.parse_args()
speed_factor = args.speed
update_freq = 0.1 / speed_factor
client = carla.Client(args.host, args.port)
```
<button id="button1" class="CopyScript" onclick="CopyToClipboard('carla.Client.__init__-code')">Copy snippet</button>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<button id="button1" class="CloseSnipet" onclick="CloseSnipet()">Close snippet</button><br><br>
</div>
<div id ="carla.World.spawn_actor-snipet" style="display: none;">
<p class="SnipetFont">
Snippet for carla.World.spawn_actor
</p>
<div id="carla.World.spawn_actor-code" class="SnipetContent">
```py
# This recipe attaches different camera / sensors to a vehicle with different attachments.
# ...
camera = world.spawn_actor(rgb_camera_bp, transform, attach_to=vehicle, attachment_type=Attachment.Rigid)
# Default attachment: Attachment.Rigid
gnss_sensor = world.spawn_actor(sensor_gnss_bp, transform, attach_to=vehicle)
collision_sensor = world.spawn_actor(sensor_collision_bp, transform, attach_to=vehicle)
lane_invasion_sensor = world.spawn_actor(sensor_lane_invasion_bp, transform, attach_to=vehicle)
# ...
```
<button id="button1" class="CopyScript" onclick="CopyToClipboard('carla.World.spawn_actor-code')">Copy snippet</button>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<button id="button1" class="CloseSnipet" onclick="CloseSnipet()">Close snippet</button><br><br>
</div>

View File

@ -6,7 +6,7 @@
This document refers to the latest version of CARLA. For documentation of previous versions, select the required version in the bottom right hand corner where you see this button: ![docs_version_panel](img/docs_version_panel.jpg)
CARLA is an open-source autonomous driving simulator. It was built from scratch to serve as a modular and flexible API to address a range of tasks involved in the problem of autonomous driving. One of the main goals of CARLA is to help democratize autonomous driving R&D, serving as a tool that can be easily accessed and customized by users. To do so, the simulator has to meet the requirements of different use cases within the general problem of driving (e.g. learning driving policies, training perception algorithms, etc.). CARLA is grounded on Unreal Engine to run the simulation and uses the OpenDRIVE standard (1.4 as today) to define roads and urban settings. Control over the simulation is granted through an API handled in Python and C++ that is constantly growing as the project does.
CARLA is an open-source autonomous driving simulator. It was built from scratch to serve as a modular and flexible API to address a range of tasks involved in the problem of autonomous driving. One of the main goals of CARLA is to help democratize autonomous driving R&D, serving as a tool that can be easily accessed and customized by users. To do so, the simulator has to meet the requirements of different use cases within the general problem of driving (e.g. learning driving policies, training perception algorithms, etc.). CARLA is grounded on Unreal Engine to run the simulation and uses the ASAM OpenDRIVE standard (1.4 as today) to define roads and urban settings. Control over the simulation is granted through an API handled in Python and C++ that is constantly growing as the project does.
In order to smooth the process of developing, training and validating driving systems, CARLA evolved to become an ecosystem of projects, built around the main platform by the community. In this context, it is important to understand some things about how does CARLA work, so as to fully comprehend its capabilities.

View File

@ -106,7 +106,7 @@ The package is a compressed file named __CARLA_version.number__. Download and ex
---
## Import additional assets
Each release has it's own additional package of extra assets and maps. This additional package includes the maps __Town06__, __Town07__, and __Town10__. These are stored separately to reduce the size of the build, so they can only be imported after the main package has been installed.
Each release has it's own additional package of extra assets and maps. This additional package includes the maps __Town06__ and __Town07__. These are stored separately to reduce the size of the build, so they can only be imported after the main package has been installed.
__1.__ [Download](https://github.com/carla-simulator/carla/blob/master/Docs/download.md) the appropriate package for your desired version of CARLA.

View File

@ -32,7 +32,7 @@ You will need to install RoadRunner. You can follow the [installation guide][rr_
## Build a map in RoadRunner
The specifics of how to build a map in RoadRunner go beyond the scope of this guide, however, there are video tutorials available in the [RoadRunner documentation][rr_tutorials].
The specifics of how to build a map in RoadRunner go beyond the scope of this guide, however, there is an introductory tutorial series available on the [MathWorks website][rr_intro_tutorials] and there are video tutorials for specific actions available in the [RoadRunner documentation][rr_tutorials].
__Keep in mind that a map heavy with props can slow the import process significantly.__ This is because Unreal Engine needs to convert every mesh to an Unreal asset. If you plan to import your map into a source build version of CARLA, we highly recommend that you only create the road layout in RoadRunner and leave any customization until after the map has been imported into Unreal Engine. CARLA provides several tools that you can use in the Unreal Engine editor to simplify the customization process.
@ -41,6 +41,7 @@ __Keep in mind that a map heavy with props can slow the import process significa
## Export a map in RoadRunner
[rr_tutorials]: https://www.mathworks.com/support/search.html?fq=asset_type_name:video%20category:roadrunner/index&page=1&s_tid=CRUX_topnav
[rr_intro_tutorials]: https://www.mathworks.com/solutions/automated-driving/roadrunner-tutorial.html
Below is a basic guideline to export your custom map from RoadRunner. You can find more detailed information about how to export to CARLA in [MathWorks' documentation][exportlink].

View File

@ -78,6 +78,10 @@ __6.__ A `<mapName>.bin` file will be created. This file contains the informatio
__7.__ Test the pedestrian navigation by starting a simulation and running the example script `generate_traffic.py` in `PythonAPI/examples`.
!!! note
**If you need to rebuild the pedestrian navigation** after updating the map, ensure to delete the CARLA cache. This is normally found in the home directory in Ubuntu (i.e. `cd ~`), or in the user directory in Windows (the directory assigned to the environment variable `USERPROFILE`), remove the folder named `carlaCache` and all of its contents, it is likely to be large in size.
---
If you have any questions about the process, then you can ask in the [forum](https://github.com/carla-simulator/carla/discussions).

32
Jenkinsfile vendored
View File

@ -24,6 +24,18 @@ pipeline
}
stages
{
stage('stash dependencies')
{
agent{ label 'cache' }
options{skipDefaultCheckout()}
steps
{
sh "echo ${BRANCH_NAME}"
sh "set"
sh "cp ../../Build_Linux.tar.gz ."
stash includes: 'Build_Linux.tar.gz', name: 'build_cache'
}
}
stage('prepare environment')
{
parallel
@ -36,6 +48,8 @@ pipeline
{
steps
{
unstash name: 'build_cache'
sh 'tar -xvzf Build_Linux.tar.gz'
sh 'git update-index --skip-worktree Unreal/CarlaUE4/CarlaUE4.uproject'
sh 'make setup ARGS="--python-version=3.8,2 --target-wheel-platform=manylinux_2_27_x86_64 --chrono"'
}
@ -155,7 +169,19 @@ pipeline
steps
{
sh 'make package ARGS="--python-version=3.8,2 --target-wheel-platform=manylinux_2_27_x86_64 --chrono"'
sh 'make package ARGS="--packages=AdditionalMaps,Town06_Opt,Town07_Opt,Town11,Town12,Town13,Town15 --target-archive=AdditionalMaps --clean-intermediate --python-version=3.8,2 --target-wheel-platform=manylinux_2_27_x86_64"'
sh '''
prefix="PR-"
case "$BRANCH_NAME" in
("$prefix"*)
echo "This is a pull request, skipping complete package"
;;
(*)
echo "Generating complete package"
make package ARGS="--packages=AdditionalMaps,Town06_Opt,Town07_Opt,Town11,Town12,Town13,Town15 --target-archive=AdditionalMaps --clean-intermediate --python-version=3.8,2 --target-wheel-platform=manylinux_2_27_x86_64"
tar -czf CarlaUE4_logs.tar.gz Unreal/CarlaUE4/Saved/Logs/
;;
esac
'''
sh 'make examples ARGS="localhost 3654"'
}
post
@ -163,6 +189,8 @@ pipeline
always
{
archiveArtifacts 'Dist/*.tar.gz'
archiveArtifacts artifacts:'CarlaUE4_logs.tar.gz',
allowEmptyArchive: true
stash includes: 'Dist/CARLA*.tar.gz', name: 'ubuntu_package'
stash includes: 'Examples/', name: 'ubuntu_examples'
}
@ -189,14 +217,12 @@ pipeline
sh 'DISPLAY= ./Dist/CarlaUE4.sh -nullrhi -RenderOffScreen --carla-rpc-port=3654 --carla-streaming-port=0 -nosound > CarlaUE4.log &'
sh 'make smoke_tests ARGS="--xml --python-version=3.8 --target-wheel-platform=manylinux_2_27_x86_64"'
sh 'make run-examples ARGS="localhost 3654"'
sh 'tar -czf CarlaUE4_logs.tar.gz Unreal/CarlaUE4/Saved/Logs/'
}
post
{
always
{
archiveArtifacts 'CarlaUE4.log'
archiveArtifacts 'CarlaUE4_logs.tar.gz'
junit 'Build/test-results/smoke-tests-*.xml'
}
}

View File

@ -40,6 +40,34 @@ namespace client {
return GetEpisode().Lock()->GetActorComponentRelativeTransform(*this, componentName);
}
std::vector<geom::Transform> Actor::GetBoneWorldTransforms() const {
return GetEpisode().Lock()->GetActorBoneWorldTransforms(*this);
}
std::vector<geom::Transform> Actor::GetBoneRelativeTransforms() const {
return GetEpisode().Lock()->GetActorBoneRelativeTransforms(*this);
}
std::vector<std::string> Actor::GetComponentNames() const {
return GetEpisode().Lock()->GetActorComponentNames(*this);
}
std::vector<std::string> Actor::GetBoneNames() const {
return GetEpisode().Lock()->GetActorBoneNames(*this);
}
std::vector<geom::Transform> Actor::GetSocketWorldTransforms() const {
return GetEpisode().Lock()->GetActorSocketWorldTransforms(*this);
}
std::vector<geom::Transform> Actor::GetSocketRelativeTransforms() const {
return GetEpisode().Lock()->GetActorSocketRelativeTransforms(*this);
}
std::vector<std::string> Actor::GetSocketNames() const {
return GetEpisode().Lock()->GetActorSocketNames(*this);
}
void Actor::SetLocation(const geom::Location &location) {
GetEpisode().Lock()->SetActorLocation(*this, location);
}

View File

@ -64,6 +64,20 @@ namespace client {
geom::Transform GetComponentRelativeTransform(const std::string componentName) const;
std::vector<geom::Transform> GetBoneWorldTransforms() const;
std::vector<geom::Transform> GetBoneRelativeTransforms() const;
std::vector<std::string> GetComponentNames() const;
std::vector<std::string> GetBoneNames() const;
std::vector<geom::Transform> GetSocketWorldTransforms() const;
std::vector<geom::Transform> GetSocketRelativeTransforms() const;
std::vector<std::string> GetSocketNames() const;
/// Teleport the actor to @a location.
void SetLocation(const geom::Location &location);

View File

@ -35,6 +35,16 @@ namespace client {
DrawShape(_episode, point, color, life_time, persistent_lines);
}
void DebugHelper::DrawHUDPoint(
const geom::Location &location,
float size,
sensor::data::Color color,
float life_time,
bool persistent_lines) {
Shape::HUDPoint point{location, size};
DrawShape(_episode, point, color, life_time, persistent_lines);
}
void DebugHelper::DrawLine(
const geom::Location &begin,
const geom::Location &end,
@ -46,6 +56,17 @@ namespace client {
DrawShape(_episode, line, color, life_time, persistent_lines);
}
void DebugHelper::DrawHUDLine(
const geom::Location &begin,
const geom::Location &end,
float thickness,
Color color,
float life_time,
bool persistent_lines) {
Shape::HUDLine line{begin, end, thickness};
DrawShape(_episode, line, color, life_time, persistent_lines);
}
void DebugHelper::DrawArrow(
const geom::Location &begin,
const geom::Location &end,
@ -59,6 +80,19 @@ namespace client {
DrawShape(_episode, arrow, color, life_time, persistent_lines);
}
void DebugHelper::DrawHUDArrow(
const geom::Location &begin,
const geom::Location &end,
float thickness,
float arrow_size,
sensor::data::Color color,
float life_time,
bool persistent_lines) {
Shape::HUDLine line{begin, end, thickness};
Shape::HUDArrow arrow{line, arrow_size};
DrawShape(_episode, arrow, color, life_time, persistent_lines);
}
void DebugHelper::DrawBox(
const geom::BoundingBox &box,
const geom::Rotation &rotation,
@ -70,6 +104,17 @@ namespace client {
DrawShape(_episode, the_box, color, life_time, persistent_lines);
}
void DebugHelper::DrawHUDBox(
const geom::BoundingBox &box,
const geom::Rotation &rotation,
float thickness,
sensor::data::Color color,
float life_time,
bool persistent_lines) {
Shape::HUDBox the_box{box, rotation, thickness};
DrawShape(_episode, the_box, color, life_time, persistent_lines);
}
void DebugHelper::DrawString(
const geom::Location &location,
const std::string &text,

View File

@ -30,6 +30,13 @@ namespace client {
float life_time = -1.0f,
bool persistent_lines = true);
void DrawHUDPoint(
const geom::Location &location,
float size = 0.1f,
Color color = Color{255u, 0u, 0u},
float life_time = -1.0f,
bool persistent_lines = true);
void DrawLine(
const geom::Location &begin,
const geom::Location &end,
@ -38,6 +45,14 @@ namespace client {
float life_time = -1.0f,
bool persistent_lines = true);
void DrawHUDLine(
const geom::Location &begin,
const geom::Location &end,
float thickness = 1.0f,
Color color = Color{225u, 0u, 0u},
float life_time = -1.0f,
bool presistent_lines = true);
void DrawArrow(
const geom::Location &begin,
const geom::Location &end,
@ -47,6 +62,15 @@ namespace client {
float life_time = -1.0f,
bool persistent_lines = true);
void DrawHUDArrow(
const geom::Location &begin,
const geom::Location &end,
float thickness = 0.1f,
float arrow_size = 0.1f,
Color color = Color{255u, 0u, 0u},
float life_time = -1.0f,
bool persistent_lines = true);
void DrawBox(
const geom::BoundingBox &box,
const geom::Rotation &rotation,
@ -55,6 +79,14 @@ namespace client {
float life_time = -1.0f,
bool persistent_lines = true);
void DrawHUDBox(
const geom::BoundingBox &box,
const geom::Rotation &rotation,
float thickness = 0.1f,
Color color = Color{255u, 0u, 0u},
float life_time = -1.0f,
bool persistent_lines = true);
void DrawString(
const geom::Location &location,
const std::string &text,

View File

@ -12,6 +12,7 @@
#include <iostream>
#include <string>
#include <sys/stat.h>
#include <cstdint>
namespace carla {
namespace client {

View File

@ -144,6 +144,10 @@ namespace client {
BaseJSONPath);
}
void Vehicle::RestorePhysXPhysics() {
GetEpisode().Lock()->RestorePhysXPhysics(*this);
}
rpc::VehicleFailureState Vehicle::GetFailureState() const {
return GetEpisode().Lock()->GetActorSnapshot(*this).state.vehicle_data.failure_state;
}

View File

@ -137,6 +137,8 @@ namespace client {
std::string TireJSON = "",
std::string BaseJSONPath = "");
void RestorePhysXPhysics();
/// Returns the failure state of the vehicle
rpc::VehicleFailureState GetFailureState() const;

View File

@ -91,6 +91,15 @@ namespace client {
_episode.Lock()->SetWeatherParameters(weather);
}
float World::GetIMUISensorGravity() const {
return _episode.Lock()->GetIMUISensorGravity();
}
void World::SetIMUISensorGravity(float NewIMUISensorGravity) {
_episode.Lock()->SetIMUISensorGravity(NewIMUISensorGravity);
}
WorldSnapshot World::GetSnapshot() const {
return _episode.Lock()->GetWorldSnapshot();
}
@ -119,17 +128,19 @@ namespace client {
const ActorBlueprint &blueprint,
const geom::Transform &transform,
Actor *parent_actor,
rpc::AttachmentType attachment_type) {
return _episode.Lock()->SpawnActor(blueprint, transform, parent_actor, attachment_type);
rpc::AttachmentType attachment_type,
const std::string& socket_name) {
return _episode.Lock()->SpawnActor(blueprint, transform, parent_actor, attachment_type, GarbageCollectionPolicy::Inherit, socket_name);
}
SharedPtr<Actor> World::TrySpawnActor(
const ActorBlueprint &blueprint,
const geom::Transform &transform,
Actor *parent_actor,
rpc::AttachmentType attachment_type) noexcept {
rpc::AttachmentType attachment_type,
const std::string& socket_name) noexcept {
try {
return SpawnActor(blueprint, transform, parent_actor, attachment_type);
return SpawnActor(blueprint, transform, parent_actor, attachment_type, socket_name);
} catch (const std::exception &) {
return nullptr;
}

View File

@ -29,6 +29,7 @@
#include "carla/rpc/Texture.h"
#include "carla/rpc/MaterialParameter.h"
#include <string>
#include <boost/optional.hpp>
namespace carla {
@ -93,6 +94,12 @@ namespace client {
/// Change the weather in the simulation.
void SetWeather(const rpc::WeatherParameters &weather);
/// Get Gravity value used for IMUI Sensor accelerometer calculation
float GetIMUISensorGravity() const;
/// Set Gravity value used for IMUI Sensor accelerometer calculation
void SetIMUISensorGravity(float NewIMUISensorGravity);
/// Return a snapshot of the world at this moment.
WorldSnapshot GetSnapshot() const;
@ -112,7 +119,8 @@ namespace client {
const ActorBlueprint &blueprint,
const geom::Transform &transform,
Actor *parent = nullptr,
rpc::AttachmentType attachment_type = rpc::AttachmentType::Rigid);
rpc::AttachmentType attachment_type = rpc::AttachmentType::Rigid,
const std::string& socket_name = "");
/// Same as SpawnActor but return nullptr on failure instead of throwing an
/// exception.
@ -120,7 +128,8 @@ namespace client {
const ActorBlueprint &blueprint,
const geom::Transform &transform,
Actor *parent = nullptr,
rpc::AttachmentType attachment_type = rpc::AttachmentType::Rigid) noexcept;
rpc::AttachmentType attachment_type = rpc::AttachmentType::Rigid,
const std::string& socket_name = "") noexcept;
/// Block calling thread until a world tick is received.
WorldSnapshot WaitForTick(time_duration timeout) const;

View File

@ -267,6 +267,14 @@ namespace detail {
_pimpl->AsyncCall("set_weather_parameters", weather);
}
float Client::GetIMUISensorGravity() const {
return _pimpl->CallAndWait<float>("get_imui_gravity");
}
void Client::SetIMUISensorGravity(float NewIMUISensorGravity) {
_pimpl->AsyncCall("set_imui_gravity", NewIMUISensorGravity);
}
std::vector<rpc::Actor> Client::GetActorsById(
const std::vector<ActorId> &ids) {
using return_t = std::vector<rpc::Actor>;
@ -330,7 +338,8 @@ namespace detail {
const rpc::ActorDescription &description,
const geom::Transform &transform,
rpc::ActorId parent,
rpc::AttachmentType attachment_type) {
rpc::AttachmentType attachment_type,
const std::string& socket_name) {
if (attachment_type == rpc::AttachmentType::SpringArm ||
attachment_type == rpc::AttachmentType::SpringArmGhost)
@ -348,7 +357,8 @@ namespace detail {
description,
transform,
parent,
attachment_type);
attachment_type,
socket_name);
}
bool Client::DestroyActor(rpc::ActorId actor) {
@ -416,6 +426,41 @@ namespace detail {
return _pimpl->CallAndWait<geom::Transform>("get_actor_component_relative_transform", actor, componentName);
}
std::vector<geom::Transform> Client::GetActorBoneWorldTransforms(rpc::ActorId actor) {
using return_t = std::vector<geom::Transform>;
return _pimpl->CallAndWait<return_t>("get_actor_bone_world_transforms", actor);
}
std::vector<geom::Transform> Client::GetActorBoneRelativeTransforms(rpc::ActorId actor) {
using return_t = std::vector<geom::Transform>;
return _pimpl->CallAndWait<return_t>("get_actor_bone_relative_transforms", actor);
}
std::vector<std::string> Client::GetActorComponentNames(rpc::ActorId actor) {
using return_t = std::vector<std::string>;
return _pimpl->CallAndWait<return_t>("get_actor_component_names", actor);
}
std::vector<std::string> Client::GetActorBoneNames(rpc::ActorId actor) {
using return_t = std::vector<std::string>;
return _pimpl->CallAndWait<return_t>("get_actor_bone_names", actor);
}
std::vector<geom::Transform> Client::GetActorSocketWorldTransforms(rpc::ActorId actor) {
using return_t = std::vector<geom::Transform>;
return _pimpl->CallAndWait<return_t>("get_actor_socket_world_transforms", actor);
}
std::vector<geom::Transform> Client::GetActorSocketRelativeTransforms(rpc::ActorId actor) {
using return_t = std::vector<geom::Transform>;
return _pimpl->CallAndWait<return_t>("get_actor_socket_relative_transforms", actor);
}
std::vector<std::string> Client::GetActorSocketNames(rpc::ActorId actor) {
using return_t = std::vector<std::string>;
return _pimpl->CallAndWait<return_t>("get_actor_socket_names", actor);
}
void Client::SetActorSimulatePhysics(rpc::ActorId actor, const bool enabled) {
_pimpl->CallAndWait<void>("set_actor_simulate_physics", actor, enabled);
}
@ -483,6 +528,10 @@ namespace detail {
BaseJSONPath);
}
void Client::RestorePhysXPhysics(rpc::ActorId vehicle) {
_pimpl->AsyncCall("restore_physx_physics", vehicle);
}
void Client::ApplyControlToWalker(rpc::ActorId walker, const rpc::WalkerControl &control) {
_pimpl->AsyncCall("apply_control_to_walker", walker, control);
}

View File

@ -88,7 +88,6 @@ namespace detail {
void DestroyTrafficManager(uint16_t port) const;
void SetTimeout(time_duration timeout);
time_duration GetTimeout() const;
@ -150,6 +149,10 @@ namespace detail {
void SetWeatherParameters(const rpc::WeatherParameters &weather);
float GetIMUISensorGravity() const;
void SetIMUISensorGravity( float NewIMUISensorGravity );
std::vector<rpc::Actor> GetActorsById(const std::vector<ActorId> &ids);
rpc::VehiclePhysicsControl GetVehiclePhysicsControl(rpc::ActorId vehicle) const;
@ -180,7 +183,8 @@ namespace detail {
const rpc::ActorDescription &description,
const geom::Transform &transform,
rpc::ActorId parent,
rpc::AttachmentType attachment_type);
rpc::AttachmentType attachment_type,
const std::string& socket_name = "");
bool DestroyActor(rpc::ActorId actor);
@ -241,6 +245,27 @@ namespace detail {
rpc::ActorId actor,
const std::string componentName);
std::vector<geom::Transform> GetActorBoneWorldTransforms(
rpc::ActorId actor);
std::vector<geom::Transform> GetActorBoneRelativeTransforms(
rpc::ActorId actor);
std::vector<std::string> GetActorComponentNames(
rpc::ActorId actor);
std::vector<std::string> GetActorBoneNames(
rpc::ActorId actor);
std::vector<geom::Transform> GetActorSocketWorldTransforms(
rpc::ActorId actor);
std::vector<geom::Transform> GetActorSocketRelativeTransforms(
rpc::ActorId actor);
std::vector<std::string> GetActorSocketNames(
rpc::ActorId actor);
void SetActorSimulatePhysics(
rpc::ActorId actor,
bool enabled);
@ -306,6 +331,8 @@ namespace detail {
std::string TireJSON,
std::string BaseJSONPath);
void RestorePhysXPhysics(rpc::ActorId vehicle);
void ApplyControlToWalker(
rpc::ActorId walker,
const rpc::WalkerControl &control);

View File

@ -347,14 +347,16 @@ EpisodeProxy Simulator::GetCurrentEpisode() {
const geom::Transform &transform,
Actor *parent,
rpc::AttachmentType attachment_type,
GarbageCollectionPolicy gc) {
GarbageCollectionPolicy gc,
const std::string& socket_name) {
rpc::Actor actor;
if (parent != nullptr) {
actor = _client.SpawnActorWithParent(
blueprint.MakeActorDescription(),
transform,
parent->GetId(),
attachment_type);
attachment_type,
socket_name);
} else {
actor = _client.SpawnActor(
blueprint.MakeActorDescription(),

View File

@ -259,6 +259,14 @@ namespace detail {
_client.SetWeatherParameters(weather);
}
float GetIMUISensorGravity() const {
return _client.GetIMUISensorGravity();
}
void SetIMUISensorGravity(float NewIMUISensorGravity) {
_client.SetIMUISensorGravity(NewIMUISensorGravity);
}
rpc::VehiclePhysicsControl GetVehiclePhysicsControl(const Vehicle &vehicle) const {
return _client.GetVehiclePhysicsControl(vehicle.GetId());
}
@ -357,7 +365,8 @@ namespace detail {
const geom::Transform &transform,
Actor *parent = nullptr,
rpc::AttachmentType attachment_type = rpc::AttachmentType::Rigid,
GarbageCollectionPolicy gc = GarbageCollectionPolicy::Inherit);
GarbageCollectionPolicy gc = GarbageCollectionPolicy::Inherit,
const std::string& socket_name = "");
bool DestroyActor(Actor &actor);
@ -446,6 +455,34 @@ namespace detail {
return _client.GetActorComponentRelativeTransform(actor.GetId(), componentName);
}
std::vector<geom::Transform> GetActorBoneWorldTransforms(const Actor &actor) {
return _client.GetActorBoneWorldTransforms(actor.GetId());
}
std::vector<geom::Transform> GetActorBoneRelativeTransforms(const Actor &actor) {
return _client.GetActorBoneRelativeTransforms(actor.GetId());
}
std::vector<std::string> GetActorComponentNames(const Actor &actor) {
return _client.GetActorComponentNames(actor.GetId());
}
std::vector<std::string> GetActorBoneNames(const Actor &actor) {
return _client.GetActorBoneNames(actor.GetId());
}
std::vector<geom::Transform> GetActorSocketWorldTransforms(const Actor &actor) {
return _client.GetActorSocketWorldTransforms(actor.GetId());
}
std::vector<geom::Transform> GetActorSocketRelativeTransforms(const Actor &actor) {
return _client.GetActorSocketRelativeTransforms(actor.GetId());
}
std::vector<std::string> GetActorSocketNames(const Actor &actor) {
return _client.GetActorSocketNames(actor.GetId());
}
void SetActorLocation(Actor &actor, const geom::Location &location) {
_client.SetActorLocation(actor.GetId(), location);
}
@ -580,6 +617,10 @@ namespace detail {
BaseJSONPath);
}
void RestorePhysXPhysics(Vehicle &vehicle) {
_client.RestorePhysXPhysics(vehicle.GetId());
}
/// @}
// =========================================================================
/// @name Operations with the recorder

View File

@ -1238,7 +1238,11 @@ namespace road {
geom::Transform lanetransform = lane->ComputeTransform(s_current);
geom::Transform treeTransform(treeposition, lanetransform.rotation);
const carla::road::element::RoadInfoSpeed* roadinfo = lane->GetInfo<carla::road::element::RoadInfoSpeed>(s_current);
transforms.push_back(std::make_pair(treeTransform,roadinfo->GetType()));
if(roadinfo){
transforms.push_back(std::make_pair(treeTransform, roadinfo->GetType()));
}else{
transforms.push_back(std::make_pair(treeTransform, "urban"));
}
}
s_current += distancebetweentrees;
}

View File

@ -10,6 +10,7 @@
#include "carla/MsgPackAdaptors.h"
#include "carla/geom/Transform.h"
#include "carla/rpc/ActorDescription.h"
#include "carla/rpc/AttachmentType.h"
#include "carla/rpc/ActorId.h"
#include "carla/rpc/TrafficLightState.h"
#include "carla/rpc/VehicleAckermannControl.h"
@ -18,6 +19,8 @@
#include "carla/rpc/VehicleLightState.h"
#include "carla/rpc/WalkerControl.h"
#include <string>
#ifdef _MSC_VER
#pragma warning(push)
#pragma warning(disable:4583)
@ -59,11 +62,19 @@ namespace rpc {
: description(std::move(description)),
transform(transform),
parent(parent) {}
SpawnActor(ActorDescription description, const geom::Transform &transform, ActorId parent, AttachmentType attachment_type, const std::string& bone)
: description(std::move(description)),
transform(transform),
parent(parent),
attachment_type(attachment_type),
socket_name(bone) {}
ActorDescription description;
geom::Transform transform;
boost::optional<ActorId> parent;
AttachmentType attachment_type;
std::string socket_name;
std::vector<Command> do_after;
MSGPACK_DEFINE_ARRAY(description, transform, parent, do_after);
MSGPACK_DEFINE_ARRAY(description, transform, parent, attachment_type, socket_name, do_after);
};
struct DestroyActor : CommandBase<DestroyActor> {

View File

@ -35,6 +35,12 @@ namespace rpc {
MSGPACK_DEFINE_ARRAY(location, size);
};
struct HUDPoint {
geom::Location location;
float size;
MSGPACK_DEFINE_ARRAY(location, size);
};
struct Line {
geom::Location begin;
geom::Location end;
@ -42,12 +48,25 @@ namespace rpc {
MSGPACK_DEFINE_ARRAY(begin, end, thickness);
};
struct HUDLine {
geom::Location begin;
geom::Location end;
float thickness;
MSGPACK_DEFINE_ARRAY(begin, end, thickness);
};
struct Arrow {
Line line;
float arrow_size;
MSGPACK_DEFINE_ARRAY(line, arrow_size);
};
struct HUDArrow {
HUDLine line;
float arrow_size;
MSGPACK_DEFINE_ARRAY(line, arrow_size);
};
struct Box {
geom::BoundingBox box;
geom::Rotation rotation;
@ -55,6 +74,13 @@ namespace rpc {
MSGPACK_DEFINE_ARRAY(box, rotation, thickness);
};
struct HUDBox {
geom::BoundingBox box;
geom::Rotation rotation;
float thickness;
MSGPACK_DEFINE_ARRAY(box, rotation, thickness);
};
struct String {
geom::Location location;
std::string text;
@ -62,7 +88,7 @@ namespace rpc {
MSGPACK_DEFINE_ARRAY(location, text, draw_shadow);
};
boost::variant2::variant<Point, Line, Arrow, Box, String> primitive;
boost::variant2::variant<Point, Line, Arrow, Box, String, HUDPoint, HUDLine, HUDArrow, HUDBox> primitive;
Color color = {255u, 0u, 0u};

View File

@ -349,8 +349,10 @@ class BasicAgent(object):
if self._ignore_vehicles:
return (False, None, -1)
if not vehicle_list:
if vehicle_list is None:
vehicle_list = self._world.get_actors().filter("*vehicle*")
if len(vehicle_list) == 0:
return (False, None, -1)
if not max_distance:
max_distance = self._base_vehicle_threshold

View File

@ -33,9 +33,10 @@ def get_libcarla_extensions():
if os.name == "posix":
import distro
supported_dists = ["ubuntu", "debian", "deepin"]
linux_distro = distro.linux_distribution()[0]
if linux_distro.lower() in ["ubuntu", "debian", "deepin"]:
linux_distro = distro.id().lower()
if linux_distro in supported_dists:
pwd = os.path.dirname(os.path.realpath(__file__))
pylib = "libboost_python%d%d.a" % (sys.version_info.major,
sys.version_info.minor)
@ -101,7 +102,7 @@ def get_libcarla_extensions():
# extra_link_args += ['/usr/lib/gcc/x86_64-linux-gnu/7/libstdc++.a']
extra_link_args += ['-lstdc++']
else:
raise NotImplementedError
raise NotImplementedError(linux_distro + " not in supported posix platforms: " + str(supported_dists))
elif os.name == "nt":
pwd = os.path.dirname(os.path.realpath(__file__))
pylib = 'libboost_python%d%d' % (

View File

@ -115,6 +115,13 @@ void export_actor() {
.def("get_acceleration", &cc::Actor::GetAcceleration)
.def("get_component_world_transform", &cc::Actor::GetComponentWorldTransform, (arg("component_name")))
.def("get_component_relative_transform", &cc::Actor::GetComponentRelativeTransform, (arg("component_name")))
.def("get_bone_world_transforms", CALL_RETURNING_LIST(cc::Actor,GetBoneWorldTransforms))
.def("get_bone_relative_transforms", CALL_RETURNING_LIST(cc::Actor,GetBoneRelativeTransforms))
.def("get_component_names", CALL_RETURNING_LIST(cc::Actor,GetComponentNames))
.def("get_bone_names", CALL_RETURNING_LIST(cc::Actor,GetBoneNames))
.def("get_socket_world_transforms", CALL_RETURNING_LIST(cc::Actor,GetSocketWorldTransforms))
.def("get_socket_relative_transforms", CALL_RETURNING_LIST(cc::Actor,GetSocketRelativeTransforms))
.def("get_socket_names", CALL_RETURNING_LIST(cc::Actor,GetSocketNames))
.def("set_location", &cc::Actor::SetLocation, (arg("location")))
.def("set_transform", &cc::Actor::SetTransform, (arg("transform")))
.def("set_target_velocity", &cc::Actor::SetTargetVelocity, (arg("velocity")))
@ -196,6 +203,7 @@ void export_actor() {
.def("enable_carsim", &cc::Vehicle::EnableCarSim, (arg("simfile_path") = ""))
.def("use_carsim_road", &cc::Vehicle::UseCarSimRoad, (arg("enabled")))
.def("enable_chrono_physics", &cc::Vehicle::EnableChronoPhysics, (arg("max_substeps")=30, arg("max_substep_delta_time")=0.002, arg("vehicle_json")="", arg("powetrain_json")="", arg("tire_json")="", arg("base_json_path")=""))
.def("restore_physx_physics", &cc::Vehicle::RestorePhysXPhysics)
.def("get_failure_state", &cc::Vehicle::GetFailureState)
.def(self_ns::str(self_ns::self))
;

View File

@ -82,9 +82,15 @@ void export_commands() {
"__init__",
&command_impl::CustomSpawnActorInit<cc::ActorBlueprint, cg::Transform, ActorPtr>,
(arg("blueprint"), arg("transform"), arg("parent")))
.def(
"__init__",
&command_impl::CustomSpawnActorInit<cc::ActorBlueprint, cg::Transform, ActorPtr, cr::AttachmentType, std::string>,
(arg("blueprint"), arg("transform"), arg("parent"), arg("attachment_type"), arg("socket_name")))
.def(init<cr::Command::SpawnActor>())
.def_readwrite("transform", &cr::Command::SpawnActor::transform)
.def_readwrite("parent_id", &cr::Command::SpawnActor::parent)
.def_readwrite("attachment_type", &cr::Command::SpawnActor::attachment_type)
.def_readwrite("socket_name", &cr::Command::SpawnActor::socket_name)
.def("then", &command_impl::Then, (arg("command")))
;

View File

@ -11,6 +11,8 @@
#include <carla/rpc/EnvironmentObject.h>
#include <carla/rpc/ObjectLabel.h>
#include <string>
#include <boost/python/suite/indexing/vector_indexing_suite.hpp>
namespace carla {
@ -293,15 +295,17 @@ void export_world() {
const cc::ActorBlueprint &blueprint, \
const cg::Transform &transform, \
cc::Actor *parent, \
cr::AttachmentType attachment_type) { \
cr::AttachmentType attachment_type, \
const std::string& bone) { \
carla::PythonUtil::ReleaseGIL unlock; \
return self.fn(blueprint, transform, parent, attachment_type); \
return self.fn(blueprint, transform, parent, attachment_type, bone); \
}, \
( \
arg("blueprint"), \
arg("transform"), \
arg("attach_to")=carla::SharedPtr<cc::Actor>(), \
arg("attachment_type")=cr::AttachmentType::Rigid)
arg("attachment_type")=cr::AttachmentType::Rigid, \
arg("bone")=std::string())
class_<cc::World>("World", no_init)
.add_property("id", &cc::World::GetId)
@ -317,6 +321,8 @@ void export_world() {
.def("apply_settings", &ApplySettings, (arg("settings"), arg("seconds")=0.0))
.def("get_weather", CONST_CALL_WITHOUT_GIL(cc::World, GetWeather))
.def("set_weather", &cc::World::SetWeather)
.def("get_imui_sensor_gravity", CONST_CALL_WITHOUT_GIL(cc::World, GetIMUISensorGravity))
.def("set_imui_sensor_gravity", &cc::World::SetIMUISensorGravity, (arg("NewIMUISensorGravity")) )
.def("get_snapshot", &cc::World::GetSnapshot)
.def("get_actor", CONST_CALL_WITHOUT_GIL_1(cc::World, GetActor, carla::ActorId), (arg("actor_id")))
.def("get_actors", CONST_CALL_WITHOUT_GIL(cc::World, GetActors))
@ -368,6 +374,12 @@ void export_world() {
arg("color")=cc::DebugHelper::Color(255u, 0u, 0u),
arg("life_time")=-1.0f,
arg("persistent_lines")=true))
.def("draw_hud_point", &cc::DebugHelper::DrawHUDPoint,
(arg("location"),
arg("size")=0.1f,
arg("color")=cc::DebugHelper::Color(255u, 0u, 0u),
arg("life_time")=-1.0f,
arg("persistent_lines")=true))
.def("draw_line", &cc::DebugHelper::DrawLine,
(arg("begin"),
arg("end"),
@ -375,6 +387,13 @@ void export_world() {
arg("color")=cc::DebugHelper::Color(255u, 0u, 0u),
arg("life_time")=-1.0f,
arg("persistent_lines")=true))
.def("draw_hud_line", &cc::DebugHelper::DrawHUDLine,
(arg("begin"),
arg("end"),
arg("thickness")=0.1f,
arg("color")=cc::DebugHelper::Color(255u, 0u, 0u),
arg("life_time")=-1.0f,
arg("persistent_lines")=true))
.def("draw_arrow", &cc::DebugHelper::DrawArrow,
(arg("begin"),
arg("end"),
@ -383,6 +402,14 @@ void export_world() {
arg("color")=cc::DebugHelper::Color(255u, 0u, 0u),
arg("life_time")=-1.0f,
arg("persistent_lines")=true))
.def("draw_hud_arrow", &cc::DebugHelper::DrawHUDArrow,
(arg("begin"),
arg("end"),
arg("thickness")=0.1f,
arg("arrow_size")=0.1f,
arg("color")=cc::DebugHelper::Color(255u, 0u, 0u),
arg("life_time")=-1.0f,
arg("persistent_lines")=true))
.def("draw_box", &cc::DebugHelper::DrawBox,
(arg("box"),
arg("rotation"),
@ -390,6 +417,13 @@ void export_world() {
arg("color")=cc::DebugHelper::Color(255u, 0u, 0u),
arg("life_time")=-1.0f,
arg("persistent_lines")=true))
.def("draw_hud_box", &cc::DebugHelper::DrawHUDBox,
(arg("box"),
arg("rotation"),
arg("thickness")=0.1f,
arg("color")=cc::DebugHelper::Color(255u, 0u, 0u),
arg("life_time")=-1.0f,
arg("persistent_lines")=true))
.def("draw_string", &cc::DebugHelper::DrawString,
(arg("location"),
arg("text"),
@ -398,4 +432,6 @@ void export_world() {
arg("life_time")=-1.0f,
arg("persistent_lines")=true))
;
// scope HUD = class_<cc::DebugHelper>(
}

View File

@ -65,7 +65,7 @@
- param_name: opendrive
type: str
doc: >
Content of an OpenDRIVE file as `string`, __not the path to the `.xodr`__.
Content of an ASAM OpenDRIVE file as `string`, __not the path to the `.xodr`__.
- param_name: parameters
type: carla.OpendriveGenerationParameters
default: (2.0, 50.0, 1.0, 0.6, true, true)
@ -101,6 +101,7 @@
doc: >
Layers of the map that will be loaded. By default all layers are loaded.
This parameter works like a flag mask.
return: carla.World
warning: >
`map_layers` are only available for "Opt" maps
doc: >
@ -114,12 +115,38 @@
doc: >
Option to reset the episode setting to default values, set to false to keep the current settings.
This is useful to keep sync mode when changing map and to keep deterministic scenarios.
return: carla.World
raises: RuntimeError when corresponding.
doc: >
Reload the current world, note that a new world is created with default
settings using the same map. All actors present in the world will be
destroyed, __but__ traffic manager instances will stay alive.
# --------------------------------------
- def_name: load_world_if_different
params:
- param_name: map_name
type: str
doc: >
Name of the map to be used in this world. Accepts both full paths and map names, e.g.
'/Game/Carla/Maps/Town01' or 'Town01'. Remember that these paths are dynamic.
- param_name: reset_settings
type: bool
default: true
doc: >
Option to reset the episode setting to default values, set to false to keep the current settings.
This is useful to keep sync mode when changing map and to keep deterministic scenarios.
- param_name: map_layers
type: carla.MapLayer
default: carla.MapLayer.All
doc: >
Layers of the map that will be loaded. By default all layers are loaded.
This parameter works like a flag mask.
return: carla.World
warning: >
`map_layers` are only available for "Opt" maps
doc: >
Creates a new world with default settings using `map_name` map only if it is a different map from the currently loaded map. Otherwise this function returns `None`. All actors in the current world will be destroyed.
# --------------------------------------
- def_name: replay_file
params:
- param_name: name
@ -732,7 +759,7 @@
- class_name: OpendriveGenerationParameters
# - DESCRIPTION ------------------------
doc: >
This class defines the parameters used when generating a world using an OpenDRIVE file.
This class defines the parameters used when generating a world using an ASAM OpenDRIVE file.
# - PROPERTIES -------------------------
instance_variables:
- var_name: vertex_distance

View File

@ -69,7 +69,11 @@
doc: >
Links another command to be executed right after. It allows to ease very common flows such as spawning a set of vehicles by command and then using this method to set them to autopilot automatically.
# --------------------------------------
- class_name: FutureActor
# - DESCRIPTION ------------------------
doc: >
A utility object used to reference an actor that will be created in the command in the previous step, it has no parameters or methods.
# --------------------------------------
- class_name: DestroyActor
# - DESCRIPTION ------------------------
doc: >

View File

@ -70,7 +70,13 @@
- var_name: Sidewalks
- var_name: TrafficSigns
- var_name: Vegetation
- var_name: Vehicles
- var_name: Car
- var_name: Bus
- var_name: Truck
- var_name: Motorcycle
- var_name: Bicycle
- var_name: Rider
- var_name: Train
- var_name: Walls
- var_name: Sky
- var_name: Ground

View File

@ -125,11 +125,11 @@
- var_name: substepping
type: bool
doc: >
Enable the physics substepping. This option allows computing some physics substeps between two render frames. If synchronous mode is set, the number of substeps and its time interval are fixed and computed are so they fulfilled the requirements of carla.WorldSettings.max_substep and carla.WorldSettings.max_substep_delta_time. These last two parameters need to be compatible with carla.WorldSettings.fixed_delta_seconds. Enabled by default.
Enable the physics substepping. This option allows computing some physics substeps between two render frames. If synchronous mode is set, the number of substeps and its time interval are fixed and computed are so they fulfilled the requirements of carla.WorldSettings.max_substeps and carla.WorldSettings.max_substep_delta_time. These last two parameters need to be compatible with carla.WorldSettings.fixed_delta_seconds. Enabled by default.
- var_name: max_substep_delta_time
type: float
doc: >
Maximum delta time of the substeps. If the carla.WorldSettingsmax_substep is high enough, the substep delta time would be always below or equal to this value. By default, the value is set to 0.01.
Maximum delta time of the substeps. If the carla.WorldSettings.max_substeps is high enough, the substep delta time would be always below or equal to this value. By default, the value is set to 0.01.
- var_name: max_substeps
type: int
doc: >
@ -993,7 +993,139 @@
doc: >
Shape's lifespan. By default it only lasts one frame. Set this to <code>0</code> for permanent shapes.
doc: >
Draws a box, ussually to act for object colliders.
Draws a box, usually to act for object colliders.
# --------------------------------------
- def_name: draw_hud_arrow
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.1
param_units: meters
doc: >
Density of the line.
- param_name: arrow_size
type: float
default: 0.1
param_units: meters
doc: >
Size of the tip of the arrow.
- param_name: color
type: carla.Color
default: (255,0,0)
doc: >
RGB code to color the object. Red by default.
- param_name: life_time
type: float
default: -1.0
param_units: seconds
doc: >
Shape's lifespan. By default it only lasts one frame. Set this to <code>0</code> for permanent shapes.
doc: >
Draws an arrow on the HUD from `begin` to `end` which can only be seen server-side.
# --------------------------------------
- def_name: draw_hud_box
params:
- param_name: box
type: carla.BoundingBox
doc: >
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.1
param_units: meters
doc: >
Density of the lines that define the box.
- param_name: color
type: carla.Color
default: (255,0,0)
doc: >
RGB code to color the object. Red by default.
- param_name: life_time
type: float
default: -1.0
param_units: seconds
doc: >
Shape's lifespan. By default it only lasts one frame. Set this to <code>0</code> for permanent shapes.
doc: >
Draws a box on the HUD, usually to act for object colliders. The box can only be seen server-side.
# --------------------------------------
- def_name: draw_hud_line
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.1
param_units: meters
doc: >
Density of the line.
- param_name: color
type: carla.Color
default: (255,0,0)
doc: >
RGB code to color the object. Red by default.
- param_name: life_time
type: float
default: -1.0
param_units: seconds
doc: >
Shape's lifespan. By default it only lasts one frame. Set this to <code>0</code> for permanent shapes.
doc: >
Draws a line on the HUD in between `begin` and `end`. The line can only be seen server-side.
# --------------------------------------
- def_name: draw_hud_point
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.1
param_units: meters
doc: >
Density of the point.
- param_name: color
type: carla.Color
default: (255,0,0)
doc: >
RGB code to color the object. Red by default.
- param_name: life_time
type: float
default: -1.0
param_units: seconds
doc: >
Shape's lifespan. By default it only lasts one frame. Set this to <code>0</code> for permanent shapes.
doc: >
Draws a point on the HUD at `location`. The point can only be seen server-side.
# --------------------------------------
- def_name: draw_line

View File

@ -324,6 +324,7 @@ class KeyboardControl(object):
def __init__(self, world, start_in_autopilot):
self._carsim_enabled = False
self._carsim_road = False
self._chrono_enabled = False
self._autopilot_enabled = start_in_autopilot
if isinstance(world.player, carla.Vehicle):
self._control = carla.VehicleControl()
@ -417,14 +418,24 @@ class KeyboardControl(object):
world.camera_manager.set_sensor(current_index)
elif event.key == K_k and (pygame.key.get_mods() & KMOD_CTRL):
print("k pressed")
if not self._carsim_enabled:
self._carsim_enabled = True
world.player.enable_carsim()
else:
self._carsim_enabled = False
world.player.restore_physx_physics()
elif event.key == K_o and (pygame.key.get_mods() & KMOD_CTRL):
print("o pressed")
if not self._chrono_enabled:
self._chrono_enabled = True
vehicle_json = "sedan/vehicle/Sedan_Vehicle.json"
powertrain_json = "sedan/powertrain/Sedan_SimpleMapPowertrain.json"
tire_json = "sedan/tire/Sedan_TMeasyTire.json"
base_path = "~/carla/Build/chrono-install/share/chrono/data/vehicle/"
base_path = "/home/adas/carla/Build/chrono-install/share/chrono/data/vehicle/"
world.player.enable_chrono_physics(5000, 0.002, vehicle_json, powertrain_json, tire_json, base_path)
else:
self._chrono_enabled = False
world.player.restore_physx_physics()
elif event.key == K_j and (pygame.key.get_mods() & KMOD_CTRL):
self._carsim_road = not self._carsim_road
world.player.use_carsim_road(self._carsim_road)

View File

@ -54,7 +54,7 @@ Repositories associated with the CARLA simulation platform:
* [**Conditional Imitation-Learning**](https://github.com/felipecode/coiltraine): Training and testing Conditional Imitation Learning models in CARLA
* [**AutoWare AV stack**](https://github.com/carla-simulator/carla-autoware): Bridge to connect AutoWare AV stack to CARLA
* [**Reinforcement-Learning**](https://github.com/carla-simulator/reinforcement-learning): Code for running Conditional Reinforcement Learning models in CARLA
* [**RoadRunner**](https://www.mathworks.com/products/roadrunner.html): MATLAB GUI based application to create road networks in OpenDrive format
* [**RoadRunner**](https://www.mathworks.com/products/roadrunner.html): MATLAB GUI based application to create road networks in the ASAM OpenDRIVE format
* [**Map Editor**](https://github.com/carla-simulator/carla-map-editor): Standalone GUI application to enhance RoadRunner maps with traffic lights and traffic signs information

View File

@ -1055,6 +1055,28 @@ ECarlaServerResponse FVehicleActor::EnableChronoPhysics(
return ECarlaServerResponse::Success;
}
ECarlaServerResponse FVehicleActor::RestorePhysXPhysics()
{
if (IsDormant())
{
}
else
{
auto Vehicle = Cast<ACarlaWheeledVehicle>(GetActor());
if (Vehicle == nullptr)
{
return ECarlaServerResponse::NotAVehicle;
}
UBaseCarlaMovementComponent* MovementComponent =
Vehicle->GetCarlaMovementComponent<UBaseCarlaMovementComponent>();
if(MovementComponent)
{
MovementComponent->DisableSpecialPhysics();
}
}
return ECarlaServerResponse::Success;
}
// FSensorActor functions ---------------------
// FtrafficSignActor functions ---------------------

View File

@ -343,6 +343,11 @@ public:
return ECarlaServerResponse::ActorTypeMismatch;
}
virtual ECarlaServerResponse RestorePhysXPhysics()
{
return ECarlaServerResponse::ActorTypeMismatch;
}
// Traffic light functions
virtual ECarlaServerResponse SetTrafficLightState(const ETrafficLightState&)
@ -532,6 +537,8 @@ public:
uint64_t MaxSubsteps, float MaxSubstepDeltaTime,
const FString& VehicleJSON, const FString& PowertrainJSON,
const FString& TireJSON, const FString& BaseJSONPath) final;
virtual ECarlaServerResponse RestorePhysXPhysics();
};
class FSensorActor : public FCarlaActor

View File

@ -34,6 +34,9 @@ static bool ValidateStaticMesh(UStaticMesh *Mesh)
for (int i = 0; i < Mesh->StaticMaterials.Num(); i++)
{
UMaterialInterface *Material = Mesh->GetMaterial(i);
if (!Material) {
Material = UMaterial::GetDefaultMaterial(MD_Surface);
}
const FString MaterialName = Material->GetName();
if (MaterialName.Contains(TEXT("light"), ESearchCase::IgnoreCase) ||

View File

@ -294,11 +294,12 @@ carla::rpc::Actor UCarlaEpisode::SerializeActor(AActor* Actor) const
void UCarlaEpisode::AttachActors(
AActor *Child,
AActor *Parent,
EAttachmentType InAttachmentType)
EAttachmentType InAttachmentType,
const FString& SocketName)
{
Child->AddActorWorldOffset(FVector(CurrentMapOrigin));
UActorAttacher::AttachActors(Child, Parent, InAttachmentType);
UActorAttacher::AttachActors(Child, Parent, InAttachmentType, SocketName);
if (bIsPrimaryServer)
{

View File

@ -245,7 +245,8 @@ public:
void AttachActors(
AActor *Child,
AActor *Parent,
EAttachmentType InAttachmentType = EAttachmentType::Rigid);
EAttachmentType InAttachmentType = EAttachmentType::Rigid,
const FString& SocketName = "");
/// @copydoc FActorDispatcher::DestroyActor(AActor*)
UFUNCTION(BlueprintCallable)

View File

@ -112,6 +112,10 @@ public:
TArray<FString> GetNamesOfAllActors();
// Gravitational acceleration. Default is earth one, which is approximately 9.81 m/s^2
UPROPERTY(BlueprintReadOnly, EditAnywhere, Category="Sensor Gravity")
float IMUISensorGravity = 9.81f;
protected:
void InitGame(const FString &MapName, const FString &Options, FString &ErrorMessage) override;
@ -176,6 +180,7 @@ private:
UPROPERTY()
ATrafficLightManager* TrafficLightManager = nullptr;
UPROPERTY()
ALargeMapManager* LMManager = nullptr;
FDelegateHandle OnEpisodeSettingsChangeHandle;

View File

@ -33,7 +33,6 @@ void ACarlaHUD::DrawHUD()
FVector2D Screen;
if (Player->ProjectWorldLocationToScreen(StringList[i].Location, Screen, true))
{
// draw text
DrawText(StringList[i].Str, StringList[i].Color, Screen.X, Screen.Y);
}
@ -45,6 +44,25 @@ void ACarlaHUD::DrawHUD()
else
++i;
}
while (i < LineList.Num())
{
// project position from camera
FVector2D Begin, End;
if (Player->ProjectWorldLocationToScreen(LineList[i].Begin, Begin, true) &&
Player->ProjectWorldLocationToScreen(LineList[i].End, End, true))
{
DrawLine(Begin.X, Begin.Y, End.X, End.Y, LineList[i].Color, LineList[i].Thickness);
}
// check to remove the string
if (Now >= LineList[i].TimeToDie)
{
LineList.RemoveAt(i);
}
else
++i;
}
}
void ACarlaHUD::AddHUDString(const FString Str, const FVector Location, const FColor Color, double LifeTime)
@ -53,3 +71,10 @@ void ACarlaHUD::AddHUDString(const FString Str, const FVector Location, const FC
HUDString Obj { Str, Location, Color, Now + LifeTime };
StringList.Add(std::move(Obj));
}
void ACarlaHUD::AddHUDLine(const FVector Begin, const FVector End, const float Thickness, const FColor Color, double LifeTime)
{
double Now = FPlatformTime::Seconds();
HUDLine Obj { Begin, End, Thickness, Color, Now + LifeTime };
LineList.Add(std::move(Obj));
}

View File

@ -35,6 +35,15 @@ struct HUDString
double TimeToDie;
};
struct HUDLine
{
FVector Begin;
FVector End;
float Thickness;
FColor Color;
double TimeToDie;
};
/// Class to draw on HUD
UCLASS()
class CARLA_API ACarlaHUD : public AHUD
@ -55,7 +64,9 @@ public:
void AddDebugVehicleForTelemetry(UWheeledVehicleMovementComponent* Veh) { DebugVehicle = Veh; }
void AddHUDString(const FString Str, const FVector Location, const FColor Color, double LifeTime);
void AddHUDLine(const FVector Begin, const FVector End, const float Thickness, const FColor Color, double LifeTime);
private:
TArray<HUDString> StringList;
TArray<HUDLine> LineList;
};

View File

@ -1,11 +1,12 @@
// Copyright (c) 2017 Computer Vision Center (CVC) at the Universitat Autonoma
// Copyright (c) 2024 Computer Vision Center (CVC) at the Universitat Autonoma
// de Barcelona (UAB).
//
// This work is licensed under the terms of the MIT license.
// For a copy, see <https://opensource.org/licenses/MIT>.
#include "Carla.h"
#include "Carla/Sensor/CollisionSensor.h"
#include "Carla.h"
#include "CoreMinimal.h"
#include "Carla/Actor/ActorBlueprintFunctionLibrary.h"
#include "Carla/Actor/ActorRegistry.h"
@ -13,11 +14,13 @@
#include "Carla/Game/CarlaEngine.h"
#include "Carla/Game/CarlaGameInstance.h"
#include "Carla/Game/CarlaGameModeBase.h"
#include "Carla/Vehicle/CarlaWheeledVehicle.h"
#include "Carla/Walker/WalkerBase.h"
ACollisionSensor::ACollisionSensor(const FObjectInitializer& ObjectInitializer)
: Super(ObjectInitializer)
{
PrimaryActorTick.bCanEverTick = false;
PrimaryActorTick.bCanEverTick = true;
}
FActorDefinition ACollisionSensor::GetSensorDefinition()
@ -32,27 +35,37 @@ void ACollisionSensor::SetOwner(AActor *NewOwner)
Super::SetOwner(NewOwner);
/// @todo Deregister previous owner if there was one.
if (NewOwner != nullptr)
if (IsValid(NewOwner))
{
NewOwner->OnActorHit.AddDynamic(this, &ACollisionSensor::OnCollisionEvent);
ACarlaWheeledVehicle* Vehicle = Cast<ACarlaWheeledVehicle>(NewOwner);
if(IsValid(Vehicle))
{
Vehicle->GetMesh()->OnComponentHit.AddDynamic(this, &ACollisionSensor::OnComponentCollisionEvent);
}
else
{
AWalkerBase* Walker = Cast<AWalkerBase>(NewOwner);
if(IsValid(Walker))
{
Walker->GetMesh()->OnComponentHit.AddDynamic(this, &ACollisionSensor::OnComponentCollisionEvent);
}
else
{
OnActorHit.AddDynamic(this, &ACollisionSensor::OnActorCollisionEvent);
}
}
}
else
{
UE_LOG(LogCarla, Log, TEXT("ACollisionSensor::SetOwner New owner is not valid or you are destroying collision sensor") );
}
}
void ACollisionSensor::OnCollisionEvent(
AActor *Actor,
AActor *OtherActor,
FVector NormalImpulse,
const FHitResult &Hit)
{
if (Actor == nullptr || OtherActor == nullptr)
{
return;
}
uint64_t CurrentFrame = FCarlaEngine::GetFrameCounter();
void ACollisionSensor::PrePhysTick(float DeltaSeconds) {
Super::PrePhysTick(DeltaSeconds);
// remove all items from previous frames
uint64_t CurrentFrame = FCarlaEngine::GetFrameCounter();
CollisionRegistry.erase(
std::remove_if(
CollisionRegistry.begin(),
@ -62,6 +75,29 @@ void ACollisionSensor::OnCollisionEvent(
return std::get<0>(Item) < CurrentFrame;
}),
CollisionRegistry.end());
}
void ACollisionSensor::OnCollisionEvent(
AActor *Actor,
AActor *OtherActor,
FVector NormalImpulse,
const FHitResult &Hit)
{
if (!IsValid(OtherActor))
{
UE_LOG(LogCarla, Error, TEXT("ACollisionSensor::OnActorCollisionEvent Error with collided actor; Not valid.\n Collider actor %s"),
*(Actor->GetName()) );
return;
}
if (!IsValid(Actor))
{
UE_LOG(LogCarla, Error, TEXT("ACollisionSensor::OnActorCollisionEvent Error with collider actor; Not valid.\n Collided actor %s"),
*(OtherActor->GetName()) );
return;
}
uint64_t CurrentFrame = FCarlaEngine::GetFrameCounter();
// check if this collision has been procesed already in this frame
for (auto& Collision: CollisionRegistry)
@ -74,23 +110,27 @@ void ACollisionSensor::OnCollisionEvent(
}
}
const auto &Episode = GetEpisode();
const auto& CurrentEpisode = GetEpisode();
constexpr float TO_METERS = 1e-2;
NormalImpulse *= TO_METERS;
GetDataStream(*this).SerializeAndSend(
*this,
Episode.SerializeActor(Actor),
Episode.SerializeActor(OtherActor),
carla::geom::Vector3D{NormalImpulse.X, NormalImpulse.Y, NormalImpulse.Z});
CurrentEpisode.SerializeActor(Actor),
CurrentEpisode.SerializeActor(OtherActor),
carla::geom::Vector3D(
(float)NormalImpulse.X,
(float)NormalImpulse.Y,
(float)NormalImpulse.Z));
// record the collision event
if (Episode.GetRecorder()->IsEnabled()){
Episode.GetRecorder()->AddCollision(Actor, OtherActor);
if (CurrentEpisode.GetRecorder()->IsEnabled()){
CurrentEpisode.GetRecorder()->AddCollision(Actor, OtherActor);
}
CollisionRegistry.emplace_back(CurrentFrame, Actor, OtherActor);
// ROS2
#if defined(WITH_ROS2)
#if defined(WITH_ROS2)
auto ROS2 = carla::ros2::ROS2::GetInstance();
if (ROS2->IsEnabled())
{
@ -107,5 +147,25 @@ void ACollisionSensor::OnCollisionEvent(
ROS2->ProcessDataFromCollisionSensor(0, StreamId, GetActorTransform(), OtherActor->GetUniqueID(), carla::geom::Vector3D{NormalImpulse.X, NormalImpulse.Y, NormalImpulse.Z}, this);
}
}
#endif
#endif
}
void ACollisionSensor::OnActorCollisionEvent(
AActor *Actor,
AActor *OtherActor,
FVector NormalImpulse,
const FHitResult &Hit)
{
OnCollisionEvent(Actor, OtherActor, NormalImpulse, Hit);
}
void ACollisionSensor::OnComponentCollisionEvent(
UPrimitiveComponent* HitComp,
AActor* OtherActor,
UPrimitiveComponent* OtherComp,
FVector NormalImpulse,
const FHitResult& Hit)
{
AActor* Actor = HitComp->GetOwner();
OnCollisionEvent(Actor, OtherActor, NormalImpulse, Hit);
}

View File

@ -1,4 +1,4 @@
// Copyright (c) 2017 Computer Vision Center (CVC) at the Universitat Autonoma
// Copyright (c) 2024 Computer Vision Center (CVC) at the Universitat Autonoma
// de Barcelona (UAB).
//
// This work is licensed under the terms of the MIT license.
@ -26,10 +26,9 @@ public:
ACollisionSensor(const FObjectInitializer& ObjectInitializer);
virtual void PrePhysTick(float DeltaSeconds) override;
void SetOwner(AActor *NewOwner) override;
private:
UFUNCTION()
void OnCollisionEvent(
AActor *Actor,
@ -37,6 +36,22 @@ private:
FVector NormalImpulse,
const FHitResult &Hit);
UFUNCTION(BlueprintCallable, Category="Collision")
void OnActorCollisionEvent(
AActor *Actor,
AActor *OtherActor,
FVector NormalImpulse,
const FHitResult &Hit);
UFUNCTION()
void OnComponentCollisionEvent(
UPrimitiveComponent* HitComp,
AActor* OtherActor,
UPrimitiveComponent* OtherComp,
FVector NormalImpulse,
const FHitResult& Hit);
private:
/// Registry that saves all collisions. Used to avoid sending the same collision more than once per frame,
/// as the collision sensor uses the PhysX substepping tick. Helps with sensor usage and stream overload.
std::vector<std::tuple<uint64_t, AActor*, AActor*>> CollisionRegistry;

View File

@ -104,8 +104,8 @@ carla::geom::Vector3D AInertialMeasurementUnit::ComputeAccelerometer(
{
// Used to convert from UE4's cm to meters
constexpr float TO_METERS = 1e-2;
// Earth's gravitational acceleration is approximately 9.81 m/s^2
constexpr float GRAVITY = 9.81f;
// Gravity set by gamemode
const float GRAVITY = UCarlaStatics::GetGameMode(GetWorld())->IMUISensorGravity;
// 2nd derivative of the polynomic (quadratic) interpolation
// using the point in current time and two previous steps:

View File

@ -9,6 +9,11 @@
#include "Carla/Server/CarlaServerResponse.h"
#include "Carla/Traffic/TrafficLightGroup.h"
#include "EngineUtils.h"
#include "Components/SkeletalMeshComponent.h"
#include "Components/SkinnedMeshComponent.h"
#include "Components/SceneComponent.h"
#include "Engine/SkeletalMesh.h"
#include "Engine/SkeletalMeshSocket.h"
#include "Carla/OpenDrive/OpenDrive.h"
#include "Carla/Util/DebugShapeDrawer.h"
@ -660,6 +665,31 @@ void FCarlaServer::FPimpl::BindActions()
return R<void>::Success();
};
// -- IMUI Gravity ---------------------------------------------------------
BIND_SYNC(get_imui_gravity) << [this]() -> R<float>
{
REQUIRE_CARLA_EPISODE();
ACarlaGameModeBase* GameMode = UCarlaStatics::GetGameMode(Episode->GetWorld());
if (GameMode == nullptr)
{
RESPOND_ERROR("get_imui_gravity error: unable to get carla gamemode");
}
return GameMode->IMUISensorGravity;
};
BIND_SYNC(set_imui_gravity) << [this](float newimuigravity) -> R<void>
{
REQUIRE_CARLA_EPISODE();
ACarlaGameModeBase* GameMode = UCarlaStatics::GetGameMode(Episode->GetWorld());
if (GameMode == nullptr)
{
RESPOND_ERROR("get_imui_gravity error: unable to get carla gamemode");
}
GameMode->IMUISensorGravity = newimuigravity;
return R<void>::Success();
};
// ~~ Actor operations ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
BIND_SYNC(get_actors_by_id) << [this](
@ -706,7 +736,8 @@ void FCarlaServer::FPimpl::BindActions()
cr::ActorDescription Description,
const cr::Transform &Transform,
cr::ActorId ParentId,
cr::AttachmentType InAttachmentType) -> R<cr::Actor>
cr::AttachmentType InAttachmentType,
const std::string& socket_name) -> R<cr::Actor>
{
REQUIRE_CARLA_EPISODE();
@ -760,7 +791,8 @@ void FCarlaServer::FPimpl::BindActions()
Episode->AttachActors(
CarlaActor->GetActor(),
ParentCarlaActor->GetActor(),
static_cast<EAttachmentType>(InAttachmentType));
static_cast<EAttachmentType>(InAttachmentType),
FString(socket_name.c_str()));
}
else
{
@ -1292,7 +1324,7 @@ BIND_SYNC(is_sensor_enabled_for_ros) << [this](carla::streaming::detail::stream_
TArray<UActorComponent*> Components;
CarlaActor->GetActor()->GetComponents(Components);
USceneComponent* Component;
USceneComponent* Component = nullptr;
for(auto Cmp : Components)
{
if(USceneComponent* SCMP = Cast<USceneComponent>(Cmp))
@ -1336,7 +1368,7 @@ BIND_SYNC(is_sensor_enabled_for_ros) << [this](carla::streaming::detail::stream_
TArray<UActorComponent*> Components;
CarlaActor->GetActor()->GetComponents(Components);
USceneComponent* Component;
USceneComponent* Component = nullptr;
for(auto Cmp : Components)
{
if(USceneComponent* SCMP = Cast<USceneComponent>(Cmp))
@ -1362,6 +1394,252 @@ BIND_SYNC(is_sensor_enabled_for_ros) << [this](carla::streaming::detail::stream_
}
};
BIND_SYNC(get_actor_bone_world_transforms) << [this](
cr::ActorId ActorId) -> R<std::vector<cr::Transform>>
{
REQUIRE_CARLA_EPISODE();
FCarlaActor* CarlaActor = Episode->FindCarlaActor(ActorId);
if (!CarlaActor)
{
return RespondError(
"get_actor_bone_world_transforms",
ECarlaServerResponse::ActorNotFound,
" Actor Id: " + FString::FromInt(ActorId));
}
else
{
TArray<FTransform> BoneWorldTransforms;
TArray<USkinnedMeshComponent*> SkinnedMeshComponents;
CarlaActor->GetActor()->GetComponents<USkinnedMeshComponent>(SkinnedMeshComponents);
if(!SkinnedMeshComponents[0])
{
return RespondError(
"get_actor_bone_world_transforms",
ECarlaServerResponse::ComponentNotFound,
" Component Name: SkinnedMeshComponent ");
}
else
{
for(USkinnedMeshComponent* SkinnedMeshComponent : SkinnedMeshComponents)
{
const int32 NumBones = SkinnedMeshComponent->GetNumBones();
for (int32 BoneIndex = 0; BoneIndex < NumBones; ++BoneIndex)
{
FTransform WorldTransform = SkinnedMeshComponent->GetComponentTransform();
FTransform BoneTransform = SkinnedMeshComponent->GetBoneTransform(BoneIndex, WorldTransform);
BoneWorldTransforms.Add(BoneTransform);
}
}
return MakeVectorFromTArray<cr::Transform>(BoneWorldTransforms);
}
}
};
BIND_SYNC(get_actor_bone_relative_transforms) << [this](
cr::ActorId ActorId) -> R<std::vector<cr::Transform>>
{
REQUIRE_CARLA_EPISODE();
FCarlaActor* CarlaActor = Episode->FindCarlaActor(ActorId);
if (!CarlaActor)
{
return RespondError(
"get_actor_bone_relative_transforms",
ECarlaServerResponse::ActorNotFound,
" Actor Id: " + FString::FromInt(ActorId));
}
else
{
TArray<FTransform> BoneRelativeTransforms;
TArray<USkinnedMeshComponent*> SkinnedMeshComponents;
CarlaActor->GetActor()->GetComponents<USkinnedMeshComponent>(SkinnedMeshComponents);
if(!SkinnedMeshComponents[0])
{
return RespondError(
"get_actor_bone_relative_transforms",
ECarlaServerResponse::ComponentNotFound,
" Component Name: SkinnedMeshComponent ");
}
else
{
for(USkinnedMeshComponent* SkinnedMeshComponent : SkinnedMeshComponents)
{
const int32 NumBones = SkinnedMeshComponent->GetNumBones();
for (int32 BoneIndex = 0; BoneIndex < NumBones; ++BoneIndex)
{
FTransform BoneTransform = SkinnedMeshComponent->GetBoneTransform(BoneIndex, FTransform::Identity);
BoneRelativeTransforms.Add(BoneTransform);
}
}
return MakeVectorFromTArray<cr::Transform>(BoneRelativeTransforms);
}
}
};
BIND_SYNC(get_actor_component_names) << [this](
cr::ActorId ActorId) -> R<std::vector<std::string>>
{
REQUIRE_CARLA_EPISODE();
FCarlaActor* CarlaActor = Episode->FindCarlaActor(ActorId);
if (!CarlaActor)
{
return RespondError(
"get_actor_component_names",
ECarlaServerResponse::ActorNotFound,
" Actor Id: " + FString::FromInt(ActorId));
}
else
{
TArray<UActorComponent*> Components;
CarlaActor->GetActor()->GetComponents(Components);
std::vector<std::string> ComponentNames;
for(auto Cmp : Components)
{
FString ComponentName = Cmp->GetName();
ComponentNames.push_back(TCHAR_TO_UTF8(*ComponentName));
}
return ComponentNames;
}
};
BIND_SYNC(get_actor_bone_names) << [this](
cr::ActorId ActorId) -> R<std::vector<std::string>>
{
REQUIRE_CARLA_EPISODE();
FCarlaActor* CarlaActor = Episode->FindCarlaActor(ActorId);
if (!CarlaActor)
{
return RespondError(
"get_actor_bone_names",
ECarlaServerResponse::ActorNotFound,
" Actor Id: " + FString::FromInt(ActorId));
}
else
{
USkinnedMeshComponent* SkinnedMeshComponent = CarlaActor->GetActor()->FindComponentByClass<USkinnedMeshComponent>();
if(!SkinnedMeshComponent)
{
return RespondError(
"get_actor_bone_names",
ECarlaServerResponse::ComponentNotFound,
" Component Name: SkinnedMeshComponent ");
}
else
{
TArray<FName> BoneNames;
SkinnedMeshComponent->GetBoneNames(BoneNames);
TArray<std::string> StringBoneNames;
for (const FName& Name : BoneNames)
{
FString FBoneName = Name.ToString();
std::string StringBoneName = TCHAR_TO_UTF8(*FBoneName);
StringBoneNames.Add(StringBoneName);
}
return MakeVectorFromTArray<std::string>(StringBoneNames);
}
}
};
BIND_SYNC(get_actor_socket_world_transforms) << [this](
cr::ActorId ActorId) -> R<std::vector<cr::Transform>>
{
REQUIRE_CARLA_EPISODE();
FCarlaActor* CarlaActor = Episode->FindCarlaActor(ActorId);
if (!CarlaActor)
{
return RespondError(
"get_actor_socket_world_transforms",
ECarlaServerResponse::ActorNotFound,
" Actor Id: " + FString::FromInt(ActorId));
}
else
{
TArray<FTransform> SocketWorldTransforms;
TArray<UActorComponent*> Components;
CarlaActor->GetActor()->GetComponents(Components);
for(UActorComponent* ActorComponent : Components)
{
if(USceneComponent* SceneComponent = Cast<USceneComponent>(ActorComponent))
{
const TArray<FName>& SocketNames = SceneComponent->GetAllSocketNames();
for (const FName& SocketName : SocketNames)
{
FTransform SocketTransform = SceneComponent->GetSocketTransform(SocketName);
SocketWorldTransforms.Add(SocketTransform);
}
}
}
return MakeVectorFromTArray<cr::Transform>(SocketWorldTransforms);
}
};
BIND_SYNC(get_actor_socket_relative_transforms) << [this](
cr::ActorId ActorId) -> R<std::vector<cr::Transform>>
{
REQUIRE_CARLA_EPISODE();
FCarlaActor* CarlaActor = Episode->FindCarlaActor(ActorId);
if (!CarlaActor)
{
return RespondError(
"get_actor_socket_relative_transforms",
ECarlaServerResponse::ActorNotFound,
" Actor Id: " + FString::FromInt(ActorId));
}
else
{
TArray<FTransform> SocketRelativeTransforms;
TArray<UActorComponent*> Components;
CarlaActor->GetActor()->GetComponents(Components);
for(UActorComponent* ActorComponent : Components)
{
if(USceneComponent* SceneComponent = Cast<USceneComponent>(ActorComponent))
{
const TArray<FName>& SocketNames = SceneComponent->GetAllSocketNames();
for (const FName& SocketName : SocketNames)
{
FTransform SocketTransform = SceneComponent->GetSocketTransform(SocketName, ERelativeTransformSpace::RTS_Actor);
SocketRelativeTransforms.Add(SocketTransform);
}
}
}
return MakeVectorFromTArray<cr::Transform>(SocketRelativeTransforms);
}
};
BIND_SYNC(get_actor_socket_names) << [this](
cr::ActorId ActorId) -> R<std::vector<std::string>>
{
REQUIRE_CARLA_EPISODE();
FCarlaActor* CarlaActor = Episode->FindCarlaActor(ActorId);
if (!CarlaActor)
{
return RespondError(
"get_actor_socket_names",
ECarlaServerResponse::ActorNotFound,
" Actor Id: " + FString::FromInt(ActorId));
}
else
{
TArray<FName> SocketNames;
std::vector<std::string> StringSocketNames;
TArray<UActorComponent*> Components;
CarlaActor->GetActor()->GetComponents(Components);
for(UActorComponent* ActorComponent : Components)
{
if(USceneComponent* SceneComponent = Cast<USceneComponent>(ActorComponent))
{
SocketNames = SceneComponent->GetAllSocketNames();
for (const FName& Name : SocketNames)
{
FString FSocketName = Name.ToString();
std::string StringSocketName = TCHAR_TO_UTF8(*FSocketName);
StringSocketNames.push_back(StringSocketName);
}
}
}
return StringSocketNames;
}
};
BIND_SYNC(get_physics_control) << [this](
cr::ActorId ActorId) -> R<cr::VehiclePhysicsControl>
{
@ -2041,6 +2319,30 @@ BIND_SYNC(is_sensor_enabled_for_ros) << [this](carla::streaming::detail::stream_
return R<void>::Success();
};
BIND_SYNC(restore_physx_physics) << [this](
cr::ActorId ActorId) -> R<void>
{
REQUIRE_CARLA_EPISODE();
FCarlaActor* CarlaActor = Episode->FindCarlaActor(ActorId);
if (!CarlaActor)
{
return RespondError(
"restore_physx_physics",
ECarlaServerResponse::ActorNotFound,
" Actor Id: " + FString::FromInt(ActorId));
}
ECarlaServerResponse Response =
CarlaActor->RestorePhysXPhysics();
if (Response != ECarlaServerResponse::Success)
{
return RespondError(
"restore_physx_physics",
Response,
" Actor Id: " + FString::FromInt(ActorId));
}
return R<void>::Success();
};
// ~~ Traffic lights ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
BIND_SYNC(set_traffic_light_state) << [this](
@ -2545,7 +2847,8 @@ BIND_SYNC(is_sensor_enabled_for_ros) << [this](carla::streaming::detail::stream_
c.description,
c.transform,
*c.parent,
cr::AttachmentType::Rigid) :
cr::AttachmentType::Rigid,
c.socket_name) :
spawn_actor(c.description, c.transform);
if (!result.HasError())
{

View File

@ -96,7 +96,8 @@ static void UActorAttacher_AttachActorsWithSpringArmGhost(
void UActorAttacher::AttachActors(
AActor *Child,
AActor *Parent,
const EAttachmentType AttachmentType)
const EAttachmentType AttachmentType,
const FString& SocketName)
{
check(Child != nullptr);
check(Parent != nullptr);
@ -104,7 +105,7 @@ void UActorAttacher::AttachActors(
switch (AttachmentType)
{
case EAttachmentType::Rigid:
Child->AttachToActor(Parent, FAttachmentTransformRules::KeepRelativeTransform);
Child->AttachToActor(Parent, FAttachmentTransformRules::KeepRelativeTransform, FName(*SocketName));
break;
case EAttachmentType::SpringArm:
UActorAttacher_AttachActorsWithSpringArm(Child, Parent);

View File

@ -42,5 +42,5 @@ class CARLA_API UActorAttacher : public UBlueprintFunctionLibrary
public:
UFUNCTION(BlueprintCallable, Category="CARLA|Actor Attacher")
static void AttachActors(AActor *Child, AActor *Parent, EAttachmentType AttachmentType);
static void AttachActors(AActor *Child, AActor *Parent, EAttachmentType AttachmentType, const FString& SocketName = "");
};

View File

@ -33,6 +33,17 @@ struct FShapeVisitor
World->PersistentLineBatcher->SetCollisionEnabled(ECollisionEnabled::NoCollision);
}
ACarlaHUD * GetHUD() const {
auto PlayerController = UGameplayStatics::GetPlayerController(World, 0);
if (PlayerController == nullptr)
{
UE_LOG(LogCarla, Error, TEXT("Can't find player controller!"));
return nullptr;
}
ACarlaHUD *Hud = Cast<ACarlaHUD>(PlayerController->GetHUD());
return Hud;
}
void operator()(const Shape::Point &Point) const
{
FVector Location = FVector(Point.location);
@ -49,6 +60,20 @@ struct FShapeVisitor
LifeTime);
}
void operator()(const Shape::HUDPoint &Point) const
{
auto Hud = GetHUD();
if (!Hud) return; // Don't draw if HUD is not available.
FVector Location = FVector(Point.location);
ALargeMapManager* LargeMap = UCarlaStatics::GetLargeMapManager(World);
if (LargeMap)
{
Location = LargeMap->GlobalToLocalLocation(Location);
}
Hud->AddHUDLine(Location, Location, Point.size, Color.Quantize(), LifeTime);
}
void operator()(const Shape::Line &Line) const
{
FVector Begin = FVector(Line.begin);
@ -68,6 +93,20 @@ struct FShapeVisitor
LifeTime);
}
void operator()(const Shape::HUDLine &Line) const {
auto Hud = GetHUD();
if (!Hud) return; // Don't draw if HUD is not available.
FVector Begin = FVector(Line.begin);
FVector End = FVector(Line.end);
ALargeMapManager* LargeMap = UCarlaStatics::GetLargeMapManager(World);
if (LargeMap)
{
Begin = LargeMap->GlobalToLocalLocation(Begin);
End = LargeMap->GlobalToLocalLocation(End);
}
Hud->AddHUDLine(Begin, End, Line.thickness, Color.Quantize(), LifeTime);
}
void operator()(const Shape::Arrow &Arrow) const
{
FVector Begin = FVector(Arrow.line.begin);
@ -90,40 +129,55 @@ struct FShapeVisitor
World->PersistentLineBatcher->DrawLines(TArray<FBatchedLine>({
FBatchedLine(
Begin,
End,
Color,
LifeTime,
Thickness,
DepthPriority),
Begin, End, Color, LifeTime, Thickness, DepthPriority),
FBatchedLine(
Transform.TransformPosition(FVector(ArrowTipDist, +ArrowSize, +ArrowSize)),
End,
Color,
LifeTime,
Thickness,
DepthPriority),
End, Color, LifeTime, Thickness, DepthPriority),
FBatchedLine(
Transform.TransformPosition(FVector(ArrowTipDist, +ArrowSize, -ArrowSize)),
End,
Color,
LifeTime,
Thickness,
DepthPriority),
End, Color, LifeTime, Thickness, DepthPriority),
FBatchedLine(
Transform.TransformPosition(FVector(ArrowTipDist, -ArrowSize, +ArrowSize)),
End,
Color,
LifeTime,
Thickness,
DepthPriority),
End, Color, LifeTime, Thickness, DepthPriority),
FBatchedLine(
Transform.TransformPosition(FVector(ArrowTipDist, -ArrowSize, -ArrowSize)),
End,
Color,
LifeTime,
Thickness,
DepthPriority)}));
End, Color, LifeTime, Thickness, DepthPriority)}));
}
void operator()(const Shape::HUDArrow &Arrow) const {
auto Hud = GetHUD();
if (!Hud) return; // Don't draw if HUD is not available.
FVector Begin = FVector(Arrow.line.begin);
FVector End = FVector(Arrow.line.end);
ALargeMapManager* LargeMap = UCarlaStatics::GetLargeMapManager(World);
if (LargeMap)
{
Begin = LargeMap->GlobalToLocalLocation(Begin);
End = LargeMap->GlobalToLocalLocation(End);
}
const auto Diff = End - Begin;
const FRotator LookAt = FRotationMatrix::MakeFromX(Diff).Rotator();
const FTransform Transform = {LookAt, Begin};
// Everything in centimeters
const auto Dist = Diff.Size();
const auto ArrowSize = Arrow.arrow_size;
const auto ArrowTipDist = Dist - ArrowSize;
const auto Thickness = Arrow.line.thickness;
Hud->AddHUDLine(Begin, End, Thickness, Color.Quantize(), LifeTime);
Hud->AddHUDLine(
Transform.TransformPosition(FVector(ArrowTipDist, +ArrowSize, +ArrowSize)),
End, Thickness, Color.Quantize(), LifeTime);
Hud->AddHUDLine(
Transform.TransformPosition(FVector(ArrowTipDist, +ArrowSize, -ArrowSize)),
End, Thickness, Color.Quantize(), LifeTime);
Hud->AddHUDLine(
Transform.TransformPosition(FVector(ArrowTipDist, -ArrowSize, +ArrowSize)),
End, Thickness, Color.Quantize(), LifeTime);
Hud->AddHUDLine(
Transform.TransformPosition(FVector(ArrowTipDist, -ArrowSize, -ArrowSize)),
End, Thickness, Color.Quantize(), LifeTime);
}
void operator()(const Shape::Box &Box) const
@ -146,66 +200,79 @@ struct FShapeVisitor
{
for(int32 j = 0; j < 2; ++j)
{
P.X=B[i].X;
Q.X=B[i].X;
P.Y=B[j].Y;
Q.Y=B[j].Y;
P.Z=B[0].Z;
Q.Z=B[1].Z;
P.X=B[i].X; Q.X=B[i].X; P.Y=B[j].Y;
Q.Y=B[j].Y; P.Z=B[0].Z; Q.Z=B[1].Z;
World->PersistentLineBatcher->DrawLine(
Transform.TransformPosition(P),
Transform.TransformPosition(Q),
Color,
DepthPriority,
Thickness,
LifeTime);
Transform.TransformPosition(P), Transform.TransformPosition(Q),
Color, DepthPriority, Thickness, LifeTime);
P.Y=B[i].Y;
Q.Y=B[i].Y;
P.Z=B[j].Z;
Q.Z=B[j].Z;
P.X=B[0].X;
Q.X=B[1].X;
P.Y=B[i].Y; Q.Y=B[i].Y; P.Z=B[j].Z;
Q.Z=B[j].Z; P.X=B[0].X; Q.X=B[1].X;
World->PersistentLineBatcher->DrawLine(
Transform.TransformPosition(P),
Transform.TransformPosition(Q),
Color,
DepthPriority,
Thickness,
LifeTime);
Transform.TransformPosition(P), Transform.TransformPosition(Q),
Color, DepthPriority, Thickness, LifeTime);
P.Z=B[i].Z;
Q.Z=B[i].Z;
P.X=B[j].X;
Q.X=B[j].X;
P.Y=B[0].Y;
Q.Y=B[1].Y;
P.Z=B[i].Z; Q.Z=B[i].Z; P.X=B[j].X;
Q.X=B[j].X; P.Y=B[0].Y; Q.Y=B[1].Y;
World->PersistentLineBatcher->DrawLine(
Transform.TransformPosition(P),
Transform.TransformPosition(Q),
Color,
DepthPriority,
Thickness,
LifeTime);
Transform.TransformPosition(P), Transform.TransformPosition(Q),
Color, DepthPriority, Thickness, LifeTime);
}
}
}
void operator()(const Shape::HUDBox &Box) const {
auto Hud = GetHUD();
if (!Hud) return; // Don't draw if HUD is not available.
const FVector Extent = 1e2f * FVector{Box.box.extent.x, Box.box.extent.y, Box.box.extent.z};
FTransform Transform = {FRotator(Box.rotation), Box.box.location};
const auto Thickness = Box.thickness;
ALargeMapManager* LargeMap = UCarlaStatics::GetLargeMapManager(World);
if (LargeMap)
{
Transform = LargeMap->GlobalToLocalTransform(Transform);
}
FVector B[2], P, Q;
B[0] = -Extent;
B[1] = Extent;
for(int32 i = 0; i < 2; ++i)
{
for(int32 j = 0; j < 2; ++j)
{
P.X=B[i].X; Q.X=B[i].X; P.Y=B[j].Y;
Q.Y=B[j].Y; P.Z=B[0].Z; Q.Z=B[1].Z;
Hud->AddHUDLine(
Transform.TransformPosition(P), Transform.TransformPosition(Q),
Thickness, Color.Quantize(), LifeTime);
P.Y=B[i].Y; Q.Y=B[i].Y; P.Z=B[j].Z;
Q.Z=B[j].Z; P.X=B[0].X; Q.X=B[1].X;
Hud->AddHUDLine(
Transform.TransformPosition(P), Transform.TransformPosition(Q),
Thickness, Color.Quantize(), LifeTime);
P.Z=B[i].Z; Q.Z=B[i].Z; P.X=B[j].X;
Q.X=B[j].X; P.Y=B[0].Y; Q.Y=B[1].Y;
Hud->AddHUDLine(
Transform.TransformPosition(P), Transform.TransformPosition(Q),
Thickness, Color.Quantize(), LifeTime);
}
}
}
void operator()(const Shape::String &Str) const
{
auto PlayerController = UGameplayStatics::GetPlayerController(World, 0);
if (PlayerController == nullptr)
{
UE_LOG(LogCarla, Error, TEXT("Can't find player controller!"));
return;
}
auto Hud = GetHUD();
if (!Hud) return;
FVector Location = FVector(Str.location);
ALargeMapManager* LargeMap = UCarlaStatics::GetLargeMapManager(World);
if (LargeMap)
{
Location = LargeMap->GlobalToLocalLocation(Location);
}
ACarlaHUD *Hud = Cast<ACarlaHUD>(PlayerController->GetHUD());
Hud->AddHUDString(carla::rpc::ToFString(Str.text), Location, Color.Quantize(), LifeTime);
}

View File

@ -459,7 +459,9 @@ FVehiclePhysicsControl ACarlaWheeledVehicle::GetVehiclePhysicsControl() const
{
FWheelPhysicsControl PhysicsWheel;
if (bPhysicsEnabled) {
PxVehicleWheelData PWheelData = Vehicle4W->PVehicle->mWheelsSimData.getWheelData(i);
PhysicsWheel.DampingRate = Cm2ToM2(PWheelData.mDampingRate);
PhysicsWheel.MaxSteerAngle = FMath::RadiansToDegrees(PWheelData.mMaxSteer);
PhysicsWheel.Radius = PWheelData.mRadius;
@ -467,9 +469,15 @@ FVehiclePhysicsControl ACarlaWheeledVehicle::GetVehiclePhysicsControl() const
PhysicsWheel.MaxHandBrakeTorque = Cm2ToM2(PWheelData.mMaxHandBrakeTorque);
PxVehicleTireData PTireData = Vehicle4W->PVehicle->mWheelsSimData.getTireData(i);
PhysicsWheel.LatStiffMaxLoad = PTireData.mLatStiffX;
PhysicsWheel.LatStiffValue = PTireData.mLatStiffY;
PhysicsWheel.LongStiffValue = PTireData.mLongitudinalStiffnessPerUnitGravity;
} else {
if (i < LastPhysicsControl.Wheels.Num()) {
PhysicsWheel = LastPhysicsControl.Wheels[i];
}
}
PhysicsWheel.TireFriction = Vehicle4W->Wheels[i]->TireConfig->GetFrictionScale();
PhysicsWheel.Position = Vehicle4W->Wheels[i]->Location;
@ -537,6 +545,7 @@ FVehiclePhysicsControl ACarlaWheeledVehicle::GetVehiclePhysicsControl() const
{
FWheelPhysicsControl PhysicsWheel;
if (bPhysicsEnabled) {
PxVehicleWheelData PWheelData = VehicleNW->PVehicle->mWheelsSimData.getWheelData(i);
PhysicsWheel.DampingRate = Cm2ToM2(PWheelData.mDampingRate);
PhysicsWheel.MaxSteerAngle = FMath::RadiansToDegrees(PWheelData.mMaxSteer);
@ -548,6 +557,11 @@ FVehiclePhysicsControl ACarlaWheeledVehicle::GetVehiclePhysicsControl() const
PhysicsWheel.LatStiffMaxLoad = PTireData.mLatStiffX;
PhysicsWheel.LatStiffValue = PTireData.mLatStiffY;
PhysicsWheel.LongStiffValue = PTireData.mLongitudinalStiffnessPerUnitGravity;
} else {
if (i < LastPhysicsControl.Wheels.Num()) {
PhysicsWheel = LastPhysicsControl.Wheels[i];
}
}
PhysicsWheel.TireFriction = VehicleNW->Wheels[i]->TireConfig->GetFrictionScale();
PhysicsWheel.Position = VehicleNW->Wheels[i]->Location;

View File

@ -35,6 +35,8 @@ public:
virtual float GetVehicleForwardSpeed() const;
virtual void DisableSpecialPhysics() {};
protected:
void DisableUE4VehiclePhysics();

View File

@ -103,10 +103,7 @@ void UCarSimManagerComponent::ProcessControl(FVehicleControl &Control)
#endif
}
void UCarSimManagerComponent::OnCarSimHit(AActor *Actor,
AActor *OtherActor,
FVector NormalImpulse,
const FHitResult &Hit)
void UCarSimManagerComponent::DisableCarSimPhysics()
{
#ifdef WITH_CARSIM
// finish Carsim simulation
@ -130,6 +127,19 @@ void UCarSimManagerComponent::OnCarSimHit(AActor *Actor,
#endif
}
void UCarSimManagerComponent::DisableSpecialPhysics()
{
DisableCarSimPhysics();
}
void UCarSimManagerComponent::OnCarSimHit(AActor *Actor,
AActor *OtherActor,
FVector NormalImpulse,
const FHitResult &Hit)
{
DisableCarSimPhysics();
}
void UCarSimManagerComponent::OnCarSimOverlap(UPrimitiveComponent* OverlappedComponent,
AActor* OtherActor,
@ -142,26 +152,7 @@ void UCarSimManagerComponent::OnCarSimOverlap(UPrimitiveComponent* OverlappedCom
ECollisionChannel::ECC_WorldDynamic) ==
ECollisionResponse::ECR_Block)
{
#ifdef WITH_CARSIM
// finish Carsim simulation
UDefaultMovementComponent::CreateDefaultMovementComponent(CarlaVehicle);
CarlaVehicle->GetMesh()->SetPhysicsLinearVelocity(FVector(0,0,0), false, "Vehicle_Base");
CarlaVehicle->GetVehicleMovementComponent()->SetComponentTickEnabled(true);
CarlaVehicle->GetVehicleMovementComponent()->Activate();
CarlaVehicle->GetMesh()->PhysicsTransformUpdateMode = EPhysicsTransformUpdateMode::SimulationUpatesComponentTransform;
auto * Bone = CarlaVehicle->GetMesh()->GetBodyInstance(NAME_None);
if (Bone)
{
Bone->SetInstanceSimulatePhysics(true);
}
else
{
carla::log_warning("No bone with name");
}
CarlaVehicle->GetMesh()->SetCollisionResponseToChannel(ECollisionChannel::ECC_WorldStatic, ECollisionResponse::ECR_Block);
CarlaVehicle->GetMesh()->SetCollisionProfileName("Vehicle");
CarlaVehicle->RestoreVehiclePhysicsControl();
#endif
DisableCarSimPhysics();
}
}

View File

@ -52,6 +52,10 @@ public:
float GetVehicleForwardSpeed() const override;
void DisableCarSimPhysics();
virtual void DisableSpecialPhysics() override;
private:
// On car mesh hit, only works when carsim is enabled

View File

@ -348,6 +348,11 @@ void UChronoMovementComponent::EndPlay(const EEndPlayReason::Type EndPlayReason)
}
#endif
void UChronoMovementComponent::DisableSpecialPhysics()
{
DisableChronoPhysics();
}
void UChronoMovementComponent::DisableChronoPhysics()
{
this->SetComponentTickEnabled(false);
@ -358,7 +363,6 @@ void UChronoMovementComponent::DisableChronoPhysics()
CarlaVehicle->GetMesh()->SetCollisionResponseToChannel(
ECollisionChannel::ECC_WorldStatic, ECollisionResponse::ECR_Block);
UDefaultMovementComponent::CreateDefaultMovementComponent(CarlaVehicle);
carla::log_warning("Chrono physics does not support collisions yet, reverting to default PhysX physics.");
}
void UChronoMovementComponent::OnVehicleHit(AActor *Actor,
@ -366,6 +370,7 @@ void UChronoMovementComponent::OnVehicleHit(AActor *Actor,
FVector NormalImpulse,
const FHitResult &Hit)
{
carla::log_warning("Chrono physics does not support collisions yet, reverting to default PhysX physics.");
DisableChronoPhysics();
}
@ -383,6 +388,7 @@ void UChronoMovementComponent::OnVehicleOverlap(
ECollisionChannel::ECC_WorldDynamic) ==
ECollisionResponse::ECR_Block)
{
carla::log_warning("Chrono physics does not support collisions yet, reverting to default PhysX physics.");
DisableChronoPhysics();
}
}

View File

@ -101,6 +101,8 @@ public:
virtual void EndPlay(const EEndPlayReason::Type EndPlayReason) override;
#endif
virtual void DisableSpecialPhysics() override;
private:
void DisableChronoPhysics();

View File

@ -6,7 +6,6 @@ using UnrealBuildTool;
public class CarlaTools : ModuleRules
{
bool UsingHoudini = true;
bool bUsingOmniverseConnector = false;
private bool IsWindows(ReadOnlyTargetRules Target)
{
@ -97,16 +96,6 @@ public class CarlaTools : ModuleRules
// ... add private dependencies that you statically link with here ...
}
);
if(UsingHoudini)
{
PrivateDependencyModuleNames.AddRange(
new string[]
{
"HoudiniEngine",
"HoudiniEngineEditor",
"HoudiniEngineRuntime"
});
}
if(bUsingOmniverseConnector)
{
PrivateDependencyModuleNames.AddRange(

View File

@ -5,7 +5,6 @@
// For a copy, see <https://opensource.org/licenses/MIT>.
#include "HoudiniImportNodeWrapper.h"
#include "HoudiniAsset.h"
UHoudiniImportNodeWrapper::UHoudiniImportNodeWrapper(const FObjectInitializer& ObjectInitializer)
{
@ -24,44 +23,15 @@ UHoudiniImportNodeWrapper* UHoudiniImportNodeWrapper::ImportBuildings(
int ClusterSize, int CurrentCluster,
bool bUseCOM)
{
UE_LOG(LogCarlaTools, Log, TEXT("Start building import"));
UHoudiniAsset* InHoudiniAsset = Cast<UHoudiniAsset>(InHoudiniObject);
if (!InHoudiniAsset)
{
UE_LOG(LogCarlaTools, Error, TEXT("Houdini asset not valid"));
return nullptr;
}
UHoudiniImportNodeWrapper* WrapperNode = NewObject<UHoudiniImportNodeWrapper>();
TMap<FName, FHoudiniParameterTuple> InParameters =
{ {"userMapName", FHoudiniParameterTuple(MapName)},
{"osmPath", FHoudiniParameterTuple(OSMFilePath)},
{"clusterSize", FHoudiniParameterTuple(ClusterSize)},
{"displayedCluster", FHoudiniParameterTuple(CurrentCluster)},
{"startCooking", FHoudiniParameterTuple(true)},
{"lat", FHoudiniParameterTuple(Latitude)},
{"lon", FHoudiniParameterTuple(Longitude)},
{"centOfMass", FHoudiniParameterTuple(bUseCOM)}};
WrapperNode->HDANode =
UHoudiniPublicAPIProcessHDANode::ProcessHDA(
InHoudiniAsset, InInstantiateAt, InParameters, {}, {},
InWorldContextObject, nullptr,
true, true, "", EHoudiniEngineBakeOption::ToActor,
true);
WrapperNode->HDANode->Completed.AddDynamic(WrapperNode, &UHoudiniImportNodeWrapper::HandleCompleted);
WrapperNode->HDANode->Failed.AddDynamic(WrapperNode, &UHoudiniImportNodeWrapper::HandleFailed);
UE_LOG(LogCarlaTools, Log, TEXT("HDA node created"));
return WrapperNode;
}
void UHoudiniImportNodeWrapper::Activate()
{
HDANode->Activate();
}
void UHoudiniImportNodeWrapper::HandleCompleted(
UHoudiniPublicAPIAssetWrapper* ,
bool bCookSuccess, bool bBakeSuccess)
{
UE_LOG(LogCarlaTools, Log, TEXT("Generation Finished"));
@ -73,7 +43,6 @@ void UHoudiniImportNodeWrapper::HandleCompleted(
}
void UHoudiniImportNodeWrapper::HandleFailed(
UHoudiniPublicAPIAssetWrapper* ,
bool bCookSuccess, bool bBakeSuccess)
{
UE_LOG(LogCarlaTools, Log, TEXT("Generation failed"));

View File

@ -154,6 +154,8 @@ void UOpenDriveToMap::CreateMap()
UE_LOG(LogCarlaToolsMapGenerator, Error, TEXT("Map Name Is Empty") );
return;
}
if( !Url.IsEmpty() ) {
if ( !IsValid(FileDownloader) )
{
FileDownloader = NewObject<UCustomFileDownloader>();
@ -164,6 +166,20 @@ void UOpenDriveToMap::CreateMap()
FileDownloader->DownloadDelegate.BindUObject( this, &UOpenDriveToMap::ConvertOSMInOpenDrive );
FileDownloader->StartDownload();
}
else if(LocalFilePath.EndsWith(".xodr"))
{
ImportXODR();
}
else if(LocalFilePath.EndsWith(".osm"))
{
ImportOSM();
}
else
{
UE_LOG(LogCarlaToolsMapGenerator, Error, TEXT("URL and Local FilePath are Empty. URL: %s Local FilePath: %s"), *Url, *LocalFilePath );
}
}
void UOpenDriveToMap::CreateTerrain( const int MeshGridSize, const float MeshGridSectionSize)
@ -490,7 +506,7 @@ void UOpenDriveToMap::GenerateAll(const boost::optional<carla::road::Map>& Param
{
GenerateRoadMesh(ParamCarlaMap, MinLocation, MaxLocation);
GenerateLaneMarks(ParamCarlaMap, MinLocation, MaxLocation);
//GenerateSpawnPoints(ParamCarlaMap);
GenerateSpawnPoints(ParamCarlaMap, MinLocation, MaxLocation);
CreateTerrain(12800, 256);
GenerateTreePositions(ParamCarlaMap, MinLocation, MaxLocation);
GenerationFinished(MinLocation, MaxLocation);
@ -714,11 +730,15 @@ void UOpenDriveToMap::GenerateSpawnPoints( const boost::optional<carla::road::Ma
for (const auto &Wp : Waypoints)
{
const FTransform Trans = ParamCarlaMap->ComputeTransform(Wp);
if( Trans.GetLocation().X >= MinLocation.X && Trans.GetLocation().Y >= MinLocation.Y &&
Trans.GetLocation().X <= MaxLocation.X && Trans.GetLocation().Y <= MaxLocation.Y)
{
AVehicleSpawnPoint *Spawner = UEditorLevelLibrary::GetEditorWorld()->SpawnActor<AVehicleSpawnPoint>();
Spawner->SetActorRotation(Trans.GetRotation());
Spawner->SetActorLocation(Trans.GetTranslation() + FVector(0.f, 0.f, SpawnersHeight));
ActorsToMove.Add(Spawner);
}
}
}
void UOpenDriveToMap::GenerateTreePositions( const boost::optional<carla::road::Map>& ParamCarlaMap, FVector MinLocation, FVector MaxLocation )
@ -878,6 +898,41 @@ bool UOpenDriveToMap::IsInRoad(
return false;
}
void UOpenDriveToMap::ImportXODR(){
IPlatformFile& FileManager = FPlatformFileManager::Get().GetPlatformFile();
FString MyFileDestination = FPaths::ProjectContentDir() + "CustomMaps/" + MapName + "/OpenDrive/" + MapName + ".xodr";
if(FileManager.CopyFile( *MyFileDestination, *LocalFilePath,
EPlatformFileRead::None,
EPlatformFileWrite::None))
{
UE_LOG(LogCarlaToolsMapGenerator, Verbose, TEXT("FilePaths: File Copied!"));
FilePath = MyFileDestination;
LoadMap();
}
else
{
UE_LOG(LogCarlaToolsMapGenerator, Error, TEXT("FilePaths local xodr file not copied: File not Copied!"));
}
}
void UOpenDriveToMap::ImportOSM(){
IPlatformFile& FileManager = FPlatformFileManager::Get().GetPlatformFile();
FString MyFileDestination = FPaths::ProjectContentDir() + "CustomMaps/" + MapName + "/OpenDrive/" + MapName + ".osm";
if(FileManager.CopyFile( *MyFileDestination, *LocalFilePath,
EPlatformFileRead::None,
EPlatformFileWrite::None))
{
UE_LOG(LogCarlaToolsMapGenerator, Verbose, TEXT("FilePaths: File Copied!"));
ConvertOSMInOpenDrive();
}
else
{
UE_LOG(LogCarlaToolsMapGenerator, Error, TEXT("FilePaths local osm file not copied: File not Copied!"));
}
}
void UOpenDriveToMap::MoveActorsToSubLevels(TArray<AActor*> ActorsToMove)
{
AActor* QueryActor = UGameplayStatics::GetActorOfClass(

View File

@ -8,9 +8,6 @@
#include "CoreMinimal.h"
#include "Kismet/BlueprintAsyncActionBase.h"
#include "HoudiniPublicAPIProcessHDANode.h"
#include "HoudiniImportNodeWrapper.generated.h"
// Delegate type for output pins on the node.
@ -49,17 +46,13 @@ protected:
UFUNCTION()
void HandleCompleted(
UHoudiniPublicAPIAssetWrapper* AssetWrapper,
bool bCookSuccess,
bool bBakeSuccess);
UFUNCTION()
void HandleFailed(
UHoudiniPublicAPIAssetWrapper* AssetWrapper,
bool bCookSuccess,
bool bBakeSuccess);
private:
UHoudiniPublicAPIProcessHDANode* HDANode;
};

View File

@ -91,6 +91,9 @@ public:
UPROPERTY( EditAnywhere, BlueprintReadWrite, Category="Settings" )
FString Url;
UPROPERTY( EditAnywhere, BlueprintReadWrite, Category="Settings" )
FString LocalFilePath;
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Settings")
FVector2D OriginGeoCoordinates;
@ -213,6 +216,9 @@ private:
void InitTextureData();
void ImportXODR();
void ImportOSM();
UPROPERTY()
UCustomFileDownloader* FileDownloader;
UPROPERTY()

View File

@ -129,18 +129,6 @@ if %REMOVE_INTERMEDIATE% == true (
)
)
rem Download Houdini Plugin
set HOUDINI_PLUGIN_REPO=https://github.com/sideeffects/HoudiniEngineForUnreal.git
set HOUDINI_PLUGIN_PATH=Plugins/HoudiniEngine
set HOUDINI_PLUGIN_COMMIT=55b6a16cdf274389687fce3019b33e3b6e92a914
set HOUDINI_PATCH=${CARLA_UTIL_FOLDER}/Patches/houdini_patch.txt
if not exist "%HOUDINI_PLUGIN_PATH%" (
call git clone %HOUDINI_PLUGIN_REPO% %HOUDINI_PLUGIN_PATH%
cd %HOUDINI_PLUGIN_PATH%
call git checkout %HOUDINI_PLUGIN_COMMIT%
cd ../..
)
rem Build Carla Editor
rem
@ -155,10 +143,10 @@ if exist %OMNIVERSE_PLUGIN_FOLDER% (
)
if %USE_CARSIM% == true (
py -3 %ROOT_PATH%Util/BuildTools/enable_carsim_to_uproject.py -f="%ROOT_PATH%Unreal/CarlaUE4/CarlaUE4.uproject" -e
python %ROOT_PATH%Util/BuildTools/enable_carsim_to_uproject.py -f="%ROOT_PATH%Unreal/CarlaUE4/CarlaUE4.uproject" -e
set CARSIM_STATE="CarSim ON"
) else (
py -3 %ROOT_PATH%Util/BuildTools/enable_carsim_to_uproject.py -f="%ROOT_PATH%Unreal/CarlaUE4/CarlaUE4.uproject"
python %ROOT_PATH%Util/BuildTools/enable_carsim_to_uproject.py -f="%ROOT_PATH%Unreal/CarlaUE4/CarlaUE4.uproject"
set CARSIM_STATE="CarSim OFF"
)
if %USE_CHRONO% == true (

View File

@ -19,7 +19,6 @@ USE_UNITY=true
USE_ROS2=false
EDITOR_FLAGS=""
USE_HOUDINI=false
GDB=
RHI="-vulkan"
@ -71,9 +70,6 @@ while [[ $# -gt 0 ]]; do
--no-unity )
USE_UNITY=false
shift ;;
--with-houdini )
USE_HOUDINI=true;
shift ;;
-h | --help )
echo "$DOC_STRING"
echo "$USAGE_STRING"
@ -136,22 +132,6 @@ if ${REMOVE_INTERMEDIATE} ; then
fi
# ==============================================================================
# -- Download Houdini Plugin for Unreal Engine ---------------------------------
# ==============================================================================
HOUDINI_PLUGIN_REPO=https://github.com/sideeffects/HoudiniEngineForUnreal.git
HOUDINI_PLUGIN_PATH=Plugins/HoudiniEngine
HOUDINI_PLUGIN_COMMIT=55b6a16cdf274389687fce3019b33e3b6e92a914
HOUDINI_PATCH=${CARLA_UTIL_FOLDER}/Patches/houdini_patch.txt
if [[ ! -d ${HOUDINI_PLUGIN_PATH} ]] ; then
git clone ${HOUDINI_PLUGIN_REPO} ${HOUDINI_PLUGIN_PATH}
pushd ${HOUDINI_PLUGIN_PATH} >/dev/null
git checkout ${HOUDINI_PLUGIN_COMMIT}
git apply ${HOUDINI_PATCH}
popd >/dev/null
fi
# ==============================================================================
# -- Build CarlaUE4 ------------------------------------------------------------
# ==============================================================================

View File

@ -109,7 +109,7 @@ rem Build for Python 3
rem
if %BUILD_FOR_PYTHON3%==true (
echo Building Python API for Python 3.
py -3 setup.py bdist_egg bdist_wheel
python setup.py bdist_egg bdist_wheel
if %errorlevel% neq 0 goto error_build_wheel
)

View File

@ -119,10 +119,10 @@ rem ============================================================================
if %DO_PACKAGE%==true (
if %USE_CARSIM% == true (
py -3 %ROOT_PATH%Util/BuildTools/enable_carsim_to_uproject.py -f="%ROOT_PATH%Unreal/CarlaUE4/CarlaUE4.uproject" -e
python %ROOT_PATH%Util/BuildTools/enable_carsim_to_uproject.py -f="%ROOT_PATH%Unreal/CarlaUE4/CarlaUE4.uproject" -e
echo CarSim ON > "%ROOT_PATH%Unreal/CarlaUE4/Config/CarSimConfig.ini"
) else (
py -3 %ROOT_PATH%Util/BuildTools/enable_carsim_to_uproject.py -f="%ROOT_PATH%Unreal/CarlaUE4/CarlaUE4.uproject"
python %ROOT_PATH%Util/BuildTools/enable_carsim_to_uproject.py -f="%ROOT_PATH%Unreal/CarlaUE4/CarlaUE4.uproject"
echo CarSim OFF > "%ROOT_PATH%Unreal/CarlaUE4/Config/CarSimConfig.ini"
)

View File

@ -1,3 +1,4 @@
#!/bin/bash
# ==============================================================================
# -- Parse arguments -----------------------------------------------------------
# ==============================================================================

View File

@ -320,6 +320,7 @@ IF "%USE_ROS2%"=="true" (
-DCMAKE_INSTALL_PREFIX="%FASTDDS_INSTALL_DIR%" ^
-DBUILD_SHARED_LIBS=ON ^
-DCMAKE_CXX_FLAGS_RELEASE="-D_GLIBCXX_USE_CXX11_ABI=0" ^
-DFOONATHAN_MEMORY_FORCE_VENDORED_BUILD=ON ^
..
ninja
ninja install

View File

@ -92,15 +92,30 @@ for PY_VERSION in ${PY_VERSION_LIST[@]} ; do
BOOST_PACKAGE_BASENAME=boost_${BOOST_VERSION//./_}
log "Retrieving boost."
start=$(date +%s)
wget "https://archives.boost.io/release/${BOOST_VERSION}/source/${BOOST_PACKAGE_BASENAME}.tar.gz" || true
end=$(date +%s)
echo "Elapsed Time downloading from boost webpage: $(($end-$start)) seconds"
# try to use the backup boost we have in Jenkins
if [ ! -f "${BOOST_PACKAGE_BASENAME}.tar.gz" ] || [[ $(sha256sum "${BOOST_PACKAGE_BASENAME}.tar.gz") != "${BOOST_SHA256SUM}" ]] ; then
log "Using boost backup"
start=$(date +%s)
wget "https://carla-releases.s3.us-east-005.backblazeb2.com/Backup/${BOOST_PACKAGE_BASENAME}.tar.gz" || true
end=$(date +%s)
echo "Elapsed Time downloading from boost carla backup in backblaze: $(($end-$start)) seconds"
fi
log "Extracting boost for Python ${PY_VERSION}."
start=$(date +%s)
tar -xzf ${BOOST_PACKAGE_BASENAME}.tar.gz
end=$(date +%s)
echo "Elapsed Time Extracting boost for Python: $(($end-$start)) seconds"
mkdir -p ${BOOST_BASENAME}-install/include
mv ${BOOST_PACKAGE_BASENAME} ${BOOST_BASENAME}-source
@ -166,8 +181,13 @@ else
log "Retrieving rpclib."
start_download_time=$(date +%s)
git clone -b ${RPCLIB_PATCH} https://github.com/carla-simulator/rpclib.git ${RPCLIB_BASENAME}-source
end_download_time=$(date +%s)
echo "Elapsed Time downloading rpclib: $(($end_download_time-$start_download_time)) seconds"
log "Building rpclib with libc++."
# rpclib does not use any cmake 3.9 feature.
@ -234,8 +254,13 @@ else
log "Retrieving Google Test."
start_download_time=$(date +%s)
git clone --depth=1 -b release-${GTEST_VERSION} https://github.com/google/googletest.git ${GTEST_BASENAME}-source
end_download_time=$(date +%s)
echo "Elapsed Time downloading rpclib: $(($end_download_time-$start_download_time)) seconds"
log "Building Google Test with libc++."
mkdir -p ${GTEST_BASENAME}-libcxx-build
@ -296,12 +321,15 @@ else
log "Retrieving Recast & Detour"
git clone https://github.com/carla-simulator/recastnavigation.git ${RECAST_BASENAME}-source
start=$(date +%s)
git clone --depth 1 -b carla https://github.com/carla-simulator/recastnavigation.git ${RECAST_BASENAME}-source
end=$(date +%s)
echo "Elapsed Time downloading: $(($end-$start)) seconds"
pushd ${RECAST_BASENAME}-source >/dev/null
git checkout carla
popd >/dev/null
log "Building Recast & Detour with libc++."
@ -351,10 +379,18 @@ if [[ -d ${LIBPNG_INSTALL} ]] ; then
log "Libpng already installed."
else
log "Retrieving libpng."
wget ${LIBPNG_REPO}
start=$(date +%s)
wget ${LIBPNG_REPO}
end=$(date +%s)
echo "Elapsed Time downloading libpng: $(($end-$start)) seconds"
start=$(date +%s)
log "Extracting libpng."
tar -xf libpng-${LIBPNG_VERSION}.tar.xz
end=$(date +%s)
echo "Elapsed Time Extracting libpng: $(($end-$start)) seconds"
mv ${LIBPNG_BASENAME} ${LIBPNG_BASENAME}-source
pushd ${LIBPNG_BASENAME}-source >/dev/null
@ -388,16 +424,26 @@ if [[ -d ${XERCESC_INSTALL_DIR} && -d ${XERCESC_INSTALL_SERVER_DIR} ]] ; then
log "Xerces-c already installed."
else
log "Retrieving xerces-c."
start=$(date +%s)
wget ${XERCESC_REPO}
end=$(date +%s)
echo "Elapsed Time downloading from xerces repo: $(($end-$start)) seconds"
# try to use the backup boost we have in Jenkins
if [[ ! -f "${XERCESC_BASENAME}.tar.gz" ]] ; then
log "Using xerces backup"
start=$(date +%s)
wget "https://carla-releases.s3.us-east-005.backblazeb2.com/Backup/${XERCESC_BASENAME}.tar.gz" || true
end=$(date +%s)
echo "Elapsed Time downloading from xerces backup: $(($end-$start)) seconds"
fi
log "Extracting xerces-c."
start=$(date +%s)
tar -xzf ${XERCESC_BASENAME}.tar.gz
end=$(date +%s)
echo "Elapsed Time Extracting xerces-c: $(($end-$start)) seconds"
mv ${XERCESC_BASENAME} ${XERCESC_SRC_DIR}
mkdir -p ${XERCESC_INSTALL_DIR}
mkdir -p ${XERCESC_SRC_DIR}/build
@ -461,10 +507,18 @@ if [[ -d ${EIGEN_INSTALL_DIR} ]] ; then
log "Eigen already installed."
else
log "Retrieving Eigen."
start=$(date +%s)
wget ${EIGEN_REPO}
end=$(date +%s)
echo "Elapsed Time downloading from eigen repo: $(($end-$start)) seconds"
log "Extracting Eigen."
start=$(date +%s)
tar -xzf ${EIGEN_BASENAME}.tar.gz
end=$(date +%s)
echo "Elapsed Time Extracting EIGEN: $(($end-$start)) seconds"
mv ${EIGEN_BASENAME} ${EIGEN_SRC_DIR}
mkdir -p ${EIGEN_INCLUDE}/unsupported
mv ${EIGEN_SRC_DIR}/Eigen ${EIGEN_INCLUDE}
@ -496,10 +550,19 @@ if ${USE_CHRONO} ; then
log "Eigen already installed."
else
log "Retrieving Eigen."
start=$(date +%s)
wget ${EIGEN_REPO}
end=$(date +%s)
echo "Elapsed Time: $(($end-$start)) seconds"
log "Extracting Eigen."
start=$(date +%s)
tar -xzf ${EIGEN_BASENAME}.tar.gz
end=$(date +%s)
echo "Elapsed Time Extracting for Eigen: $(($end-$start)) seconds"
mv ${EIGEN_BASENAME} ${EIGEN_SRC_DIR}
mkdir -p ${EIGEN_INCLUDE}/unsupported
mv ${EIGEN_SRC_DIR}/Eigen ${EIGEN_INCLUDE}
@ -527,7 +590,10 @@ if ${USE_CHRONO} ; then
log "chrono library already installed."
else
log "Retrieving chrono library."
start=$(date +%s)
git clone --depth 1 --branch ${CHRONO_TAG} ${CHRONO_REPO} ${CHRONO_SRC_DIR}
end=$(date +%s)
echo "Elapsed Time dowloading chrono: $(($end-$start)) seconds"
mkdir -p ${CHRONO_SRC_DIR}/build
@ -574,10 +640,19 @@ if [[ -d ${SQLITE_INSTALL_DIR} ]] ; then
log "Sqlite already installed."
else
log "Retrieving Sqlite3"
start=$(date +%s)
wget ${SQLITE_REPO}
end=$(date +%s)
echo "Elapsed Time: $(($end-$start)) seconds"
log "Extracting Sqlite3"
start=$(date +%s)
tar -xzf ${SQLITE_TAR}
end=$(date +%s)
echo "Elapsed Time Extracting for SQlite: $(($end-$start)) seconds"
mv ${SQLITE_VERSION} ${SQLITE_SOURCE_DIR}
mkdir ${SQLITE_INSTALL_DIR}
@ -621,10 +696,18 @@ if [[ -d ${PROJ_INSTALL_DIR} && -d ${PROJ_INSTALL_SERVER_DIR_FULL} ]] ; then
log "PROJ already installed."
else
log "Retrieving PROJ"
start=$(date +%s)
wget ${PROJ_REPO}
end=$(date +%s)
echo "Elapsed Time: $(($end-$start)) seconds"
log "Extracting PROJ"
start=$(date +%s)
tar -xzf ${PROJ_TAR}
end=$(date +%s)
echo "Elapsed Time Extracting for PROJ: $(($end-$start)) seconds"
mv ${PROJ_VERSION} ${PROJ_SRC_DIR}
mkdir -p ${PROJ_SRC_DIR}/build
@ -692,10 +775,18 @@ if [[ -d ${PATCHELF_INSTALL_DIR} ]] ; then
log "Patchelf already installed."
else
log "Retrieving patchelf"
start=$(date +%s)
wget ${PATCHELF_REPO}
end=$(date +%s)
echo "Elapsed Time: $(($end-$start)) seconds"
log "Extracting patchelf"
start=$(date +%s)
tar -xzf ${PATCHELF_TAR}
end=$(date +%s)
echo "Elapsed Time Extracting patchelf: $(($end-$start)) seconds"
mv patchelf-${PATCHELF_VERSION} ${PATCHELF_SOURCE_DIR}
mkdir ${PATCHELF_INSTALL_DIR}
@ -730,7 +821,12 @@ if ${USE_PYTORCH} ; then
LIBTORCH_ZIPFILE=libtorch-shared-with-deps-1.11.0+cu113.zip
LIBTORCH_REPO=https://download.pytorch.org/libtorch/cu113/libtorch-shared-with-deps-1.11.0%2Bcu113.zip
if [[ ! -d ${LIBTORCH_PATH} ]] ; then
start=$(date +%s)
wget ${LIBTORCH_REPO}
end=$(date +%s)
echo "Elapsed Time downloading LIBTORCH_REPO: $(($end-$start)) seconds"
unzip ${LIBTORCH_ZIPFILE}
fi
@ -810,7 +906,10 @@ if ${USE_ROS2} ; then
if [[ ! -d ${LIB_SOURCE} ]] ; then
mkdir -p ${LIB_SOURCE}
log "${LIB_REPO}"
start=$(date +%s)
git clone --depth 1 --branch ${LIB_BRANCH} ${LIB_REPO} ${LIB_SOURCE}
end=$(date +%s)
echo "Elapsed Time dowloading fastdds extension: $(($end-$start)) seconds"
mkdir -p ${LIB_SOURCE}/build
fi
}
@ -827,6 +926,7 @@ if ${USE_ROS2} ; then
-DCMAKE_INSTALL_PREFIX="${FASTDDS_INSTALL_DIR}" \
-DBUILD_SHARED_LIBS=ON \
-DCMAKE_CXX_FLAGS_RELEASE="-D_GLIBCXX_USE_CXX11_ABI=0" \
-DFOONATHAN_MEMORY_FORCE_VENDORED_BUILD=ON \
..
ninja
ninja install
@ -860,7 +960,8 @@ if ${USE_ROS2} ; then
-DCMAKE_INSTALL_PREFIX="${FASTDDS_INSTALL_DIR}" \
-DCMAKE_CXX_FLAGS=-latomic \
-DCMAKE_CXX_FLAGS_RELEASE="-D_GLIBCXX_USE_CXX11_ABI=0" \
\
-DTHIRDPARTY_Asio=FORCE \
-DTHIRDPARTY_TinyXML2=FORCE \
..
ninja
ninja install

View File

@ -54,7 +54,7 @@ set ZLIB_TEMP_FOLDER=%ZLIB_BASENAME%-%ZLIB_VERSION%
set ZLIB_TEMP_FILE=%ZLIB_TEMP_FOLDER%.zip
set ZLIB_TEMP_FILE_DIR=%BUILD_DIR%%ZLIB_TEMP_FILE%
set ZLIB_REPO=https://www.zlib.net/zlib%ZLIB_VERSION:.=%.zip
set ZLIB_REPO=https://github.com/madler/zlib/archive/refs/tags/v%ZLIB_VERSION%.zip
set ZLIB_BACKUP_REPO=https://carla-releases.s3.us-east-005.backblazeb2.com/Backup/zlib%ZLIB_VERSION:.=%.zip
set ZLIB_SRC_DIR=%BUILD_DIR%%ZLIB_BASENAME%-source\
set ZLIB_INSTALL_DIR=%BUILD_DIR%%ZLIB_BASENAME%-install\

View File

@ -1,15 +0,0 @@
diff --git a/Source/HoudiniEngineEditor/Private/HoudiniEngineDetails.cpp b/Source/HoudiniEngineEditor/Private/HoudiniEngineDetails.cpp
index 36c9bf5cd..d9d6dbfdb 100755
--- a/Source/HoudiniEngineEditor/Private/HoudiniEngineDetails.cpp
+++ b/Source/HoudiniEngineEditor/Private/HoudiniEngineDetails.cpp
@@ -1131,8 +1131,8 @@ FHoudiniEngineDetails::CreateAssetOptionsWidgets(
auto IsCheckedParameterChangedLambda = [MainHAC]()
{
- if (!IsValidWeakPointer(MainHAC))
- return ECheckBoxState::Unchecked;
+ if (!IsValidWeakPointer(MainHAC))
+ return ECheckBoxState::Unchecked;
return MainHAC->bCookOnParameterChange ? ECheckBoxState::Checked : ECheckBoxState::Unchecked;
};

View File

@ -42,7 +42,7 @@ nav:
- 'Chrono': 'tuto_G_chrono.md'
- 'MathWorks': 'large_map_roadrunner.md'
- 'NVIDIA SimReady': 'ecosys_simready.md'
- 'OpenDRIVE': 'adv_opendrive.md'
- 'ASAM OpenDRIVE': 'adv_opendrive.md'
- 'PTV Vissim': 'adv_ptv.md'
- 'RSS': 'adv_rss.md'
- 'ROS': https://carla.readthedocs.io/projects/ros-bridge/en/latest/