From cb208cb150f690f3c512040696d2538ee6538504 Mon Sep 17 00:00:00 2001 From: MattRoweEAIF Date: Fri, 8 Sep 2023 13:15:09 +0200 Subject: [PATCH 01/29] synkrotron docs --- Docs/ecosys_synkrotron.md | 13 +++++++++++++ Docs/img/synkrotron.jpg | Bin 0 -> 31475 bytes mkdocs.yml | 1 + 3 files changed, 14 insertions(+) create mode 100644 Docs/ecosys_synkrotron.md create mode 100644 Docs/img/synkrotron.jpg diff --git a/Docs/ecosys_synkrotron.md b/Docs/ecosys_synkrotron.md new file mode 100644 index 000000000..9a5ae507d --- /dev/null +++ b/Docs/ecosys_synkrotron.md @@ -0,0 +1,13 @@ +# Synkrotron simulation solutions + +“synkrotron_logo” + +Synkrotron provides advanced solutions for autonomous driving simulation, built on top of CARLA's existing toolset to streamline scenario authoring, simulation data pipelining, sensor modelling and cloud based compute scaling tools for streamlining the AD research and development process. + +## [__OASIS simulation platform__](https://www.synkrotron.ai/sim.html) + +The OASIS simulation platform provides a set of tools to augment CARLA's functionality with a graphical scenario authoring tool, a built in scenario library, a scenario description language, a REST API for integration with DevOps and CI/CD piptines along with cloud computing tools for scaling AD simulation with massive concurrency. + +## [__OASIS data platform__](https://www.synkrotron.ai/data.html) + +The OASIS data platform provides a data management system for managing the high volume of data required throughout the autonomous driving R&D pipeline. The OASIS data management solution helps managing data pipelines to streamline the transferral of data through data acquisition, storage, filtering, annotation, scene extraction and finally into algorithm training, testing and deployment. OASIS provides a user friendly management interface to control all aspects of the data pipeline. \ No newline at end of file diff --git a/Docs/img/synkrotron.jpg b/Docs/img/synkrotron.jpg new file mode 100644 index 0000000000000000000000000000000000000000..e854362a52ec2c45ffa02f32a73c9c80aaa7557f GIT binary patch literal 31475 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

vcf0-{`nSE-fT`LKwgc)dD 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%0A#=}>;ko{|6?`8sU6q~FJwj**84`C~x^P>n`1 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 literal 0 HcmV?d00001 diff --git a/mkdocs.yml b/mkdocs.yml index 15dc563b2..b84d7e916 100644 --- a/mkdocs.yml +++ b/mkdocs.yml @@ -47,6 +47,7 @@ nav: - 'ROS': https://carla.readthedocs.io/projects/ros-bridge/en/latest/ - 'Scenic': 'tuto_G_scenic.md' - 'SUMO': 'adv_sumo.md' + - 'SYNKROTRON': 'ecosys_synkrotron.md' - Contributing: - 'Guidelines': 'cont_contribution_guidelines.md' From 53a7a15fa068f5a59f07bea97e9e29989c4cfe1a Mon Sep 17 00:00:00 2001 From: MattRoweEAIF Date: Fri, 8 Sep 2023 13:22:35 +0200 Subject: [PATCH 02/29] fixed imagge path --- Docs/ecosys_synkrotron.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Docs/ecosys_synkrotron.md b/Docs/ecosys_synkrotron.md index 9a5ae507d..5b289e847 100644 --- a/Docs/ecosys_synkrotron.md +++ b/Docs/ecosys_synkrotron.md @@ -1,6 +1,6 @@ # Synkrotron simulation solutions -“synkrotron_logo” +“synkrotron_logo” Synkrotron provides advanced solutions for autonomous driving simulation, built on top of CARLA's existing toolset to streamline scenario authoring, simulation data pipelining, sensor modelling and cloud based compute scaling tools for streamlining the AD research and development process. From 1510f7522ded2f85e07cfc753cd3dedc417de4a1 Mon Sep 17 00:00:00 2001 From: MattRoweEAIF Date: Tue, 26 Sep 2023 15:57:00 +0200 Subject: [PATCH 03/29] added details from james --- Docs/ecosys_synkrotron.md | 43 +++++++++++++++++++++++++++++++++----- Docs/img/oasis_logo.png | Bin 0 -> 67648 bytes 2 files changed, 38 insertions(+), 5 deletions(-) create mode 100644 Docs/img/oasis_logo.png diff --git a/Docs/ecosys_synkrotron.md b/Docs/ecosys_synkrotron.md index 5b289e847..81584c78d 100644 --- a/Docs/ecosys_synkrotron.md +++ b/Docs/ecosys_synkrotron.md @@ -1,13 +1,46 @@ -# Synkrotron simulation solutions - “synkrotron_logo” -Synkrotron provides advanced solutions for autonomous driving simulation, built on top of CARLA's existing toolset to streamline scenario authoring, simulation data pipelining, sensor modelling and cloud based compute scaling tools for streamlining the AD research and development process. +# Synkrotron simulation solutions + +Synkrotron provides advanced solutions for autonomous driving simulation built on top of CARLA. Its product suite Oasis supports ​a broad range of applications including scenario generation, sensor modelling, ​traffic simulation and data management. Based on a flexible architecture Oasis ​can be deployed on the cloud at scale, or in a developer's local environment for prototyping. + +--- + +# __OASIS platform__ + +“synkrotron_logo” ## [__OASIS simulation platform__](https://www.synkrotron.ai/sim.html) -The OASIS simulation platform provides a set of tools to augment CARLA's functionality with a graphical scenario authoring tool, a built in scenario library, a scenario description language, a REST API for integration with DevOps and CI/CD piptines along with cloud computing tools for scaling AD simulation with massive concurrency. +Oasis Sim is a full-fledged scalable simulation platform with CARLA at its core. It supports the complete life-cycle of AD simulation: scenario import & editing with a graphical user interface, sensor configuration, distributed task management as well as diagnosis through rich simulation data and logs. Both cloud and local deployment are available through containerized ​packaging. Comprehensive APIs are exposed for integration with DevOps too. You can [request a trial](https://synkrotron.ai/contact.html) from Synkrotron. ## [__OASIS data platform__](https://www.synkrotron.ai/data.html) -The OASIS data platform provides a data management system for managing the high volume of data required throughout the autonomous driving R&D pipeline. The OASIS data management solution helps managing data pipelines to streamline the transferral of data through data acquisition, storage, filtering, annotation, scene extraction and finally into algorithm training, testing and deployment. OASIS provides a user friendly management interface to control all aspects of the data pipeline. \ No newline at end of file +Oasis Data is a platform for managing the high volume of data flowing through the autonomous driving R&D pipeline. Data-driven development of AD systems are made possible with Oasis Data via the following functionalities,: + +* data acquisition and anonymization +* multi-stage filtering based on structured (CAN bus signals, active-safety triggering, etc.) and unstructured (sensor readings) +* information mapping and environment reconstruction with lidar and/or vision-only strategy +* auto-labeling of data with pre-trained perception models +* scenario tagging and reconstruction with OpenX format output + +The processed data from the platform supports downstream applications such as scenario re-simulation with Oasis Sim, retraining of perception models with new labeled data and operational fleet management. + +## __Synkrotron Tools and Services__ + +In addition to the complete solutions introduced above, Synkrotron also offers the following developer tools and services to facilitate AD simulation development. + +| Product/service | Description | +| -----------| ------ | +| __Sensor model__: fish-eye camera | Fisheye camera with configurable distortion parameters | +| __Sensor model__: LIDAR | Advanced lidar model with configurable shutter mode and material reflections | +| __SOTIF__ scenario generation tool | Given the ODD description from user, identify important scenario elements and generate critical scenarios to help uncover unknown unsafe domains of the autonomous driving systems, achieved by using an ontology-based method combined with iterative optimizations against evaluations in Carla | +| __Map creation__ | Given lidar scan data (can also provide road-test data collection equipments & service), create HD maps for the user and output OpenDrive files which can be loaded in Carla for PnC tests or logsim | +| __Sensor model__: physics models for camera | Supports CMOS simulations and outputs 12bit raw sensor data, for customers who develop ISP algorithms or who has ECUs that need raw data from camera instead of RGBs | +| __Static scene creation__ | Combined HD mapping, 3D asset development and procedural modeling to create 3D static scenes/digital twins for users | +| __Dynamic scenario reconstruction__ | On top of static scenes, also detect and track various traffic participants from user's road-test data; the recovered trajectories/behaviors are turned into OpenScenario 1.0 files and can be re-simulated in CARLA | + + + + + diff --git a/Docs/img/oasis_logo.png b/Docs/img/oasis_logo.png new file mode 100644 index 0000000000000000000000000000000000000000..3108bc78ef80ac2ebcb71fb5484c51d5dca9a824 GIT binary patch literal 67648 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 uWAVs1{%=2-VZ8Yte{8!6$A9H7ECuiTrNzi+&h�|Bf6s)+y7n5Bnc@>gNjp literal 0 HcmV?d00001 From 14ebea66861acf90c1db202d6463be113afe5a49 Mon Sep 17 00:00:00 2001 From: MattRoweEAIF Date: Fri, 10 Nov 2023 21:12:54 +0100 Subject: [PATCH 04/29] added simready instructions --- Docs/ecosys_simready.md | 64 +++++++++++++++++++++++++++++++++++++++++ mkdocs.yml | 1 + 2 files changed, 65 insertions(+) create mode 100644 Docs/ecosys_simready.md diff --git a/Docs/ecosys_simready.md b/Docs/ecosys_simready.md new file mode 100644 index 000000000..996cd2df0 --- /dev/null +++ b/Docs/ecosys_simready.md @@ -0,0 +1,64 @@ +# SimReady content with NVIDIA Omnivers + +NVIDIA's [__SimReady__](#simready-content-from-nvidias-omniverse) specification supports the preparation of 3D content that is purpose-built for simulation to help streamline content creation pipelines for simulating 3D virtual environments for machine learning purposes in robotics and autonomous driving. Through the Omniverse Unreal Engine plugin now integrated into CARLA users can import, in just a few clicks, SimReady content such as vehicles already configured with working lights, doors and wheels and props ready for use instantaneously to decorate CARLA maps. CARLA's Omniverse integration boasts to significantly accelerate your environment building pipeline and opens the door to a whole world of applications in the [__Omniverse ecosystem__](https://www.nvidia.com/en-us/omniverse/ecosystem/). + +The Omniverse Unreal Engine Connector is currently only available in Windows. + +Follow these stesps to start using Omniverse and using SimReady content in CARLA: + +Before anything else, you should first [install NVIDIA Omniverse](https://docs.omniverse.nvidia.com/install-guide/latest/index.html) + +### 1. Installing the Unreal Engine Omniverse Connector + +1. Launch the NVIDIA Omniverse Launcher. +2. Navigate to the Exchange tab. +3. Locate the Epic Games Unreal Engine 4.26 Omniverse Connector. +4. Ensure the Install version is Release 105.1.578 +5. Click *Install*. +6. Omniverse will not find Unreal Engine, click OK. +7. It will prompt you to find your Unreal Engine installation, Select this path: {UE4_ROOT}\Engine\Plugins\Marketplace\NVIDIA +8. Press *Install*. + +### 2. Set Up Local Omniverse Server + +1. Launch the NVIDIA Omniverse Launcher. +2. Navigate to the Nucleus tab. +3. Click on create Local Server. +4. Add administrator details (any). +5. Select on the folder icon next to Local Nucleus Service, this should open your localhost server navigator. + +### 3. Connecting to CARLA Simulator + +1. Launch CARLA using `make launch` from the command line ine the CARLA root folder. +2. If an existing server is active, and you want to restart the setup, click on Clean Local Assets. (Optional) +3. Select the Omniverse icon and click on *Add Server*. +4. Name the server and click *Add to Content Browser*. +5. A login form should launch in your browser, click *Create Account*. +6. Add administrator details(any). +7. Omniverse folders should have appeared in your Content/Omniverse folder within the Engine. +8. Go to your local host browser Navigator +9. Click on *Connect to a Server*. +10. Authenticate using the server name you set for the CARLA server. +11. Use administrator details you set for the CARLA server. +12. The server folders should now show up in your browser navigator. + +### 4. Importing the SimReady Car Asset + +1. Navigate to the Projects folder within the browser navigator. +2. Right click, and select Upload Folder. +3. Select your SimReady folders. +4. Upload the files. + +### 5. Using the Omniverse Connector to Load the Vehicle to CARLA + +1. Open the CARLA project in Unreal Engine. +2. Navigate to CarlaTools Content\USDImporter. +3. Right click on *UW_USDVehicleImporterEditorWidget*. +4. Select *Run Editor Utility Widget*. +5. Find the Vehicle within your Omniverse browser navigator +6. Copy the path (should look something like: omniverse://localhost/Projects/SimReadyUSD.../vehicle.usd) +7. Paste it inside the Omiverse URL tab within the Widget. +8. Select Import Asset. +9. You should see the vehicle show up in the engine, within Content/OmniverseImports. +10. Open another map scene since it opened a new scene with the imported data, a *Save Content* prompt should appear. Uncheck the *Untitled* scene, and click on *Save selected* to save new content. +11. The vehicle is now usable within CARLA. diff --git a/mkdocs.yml b/mkdocs.yml index b84d7e916..40a876c9e 100644 --- a/mkdocs.yml +++ b/mkdocs.yml @@ -41,6 +41,7 @@ nav: - 'CarSIM': 'tuto_G_carsim_integration.md' - 'Chrono': 'tuto_G_chrono.md' - 'MathWorks': 'large_map_roadrunner.md' + - 'NVIDIA SimReady': 'ecosys_simready.md' - 'OpenDRIVE': 'adv_opendrive.md' - 'PTV Vissim': 'adv_ptv.md' - 'RSS': 'adv_rss.md' From 2e5039636ac75d2314739484a7d21ac8b9386ddc Mon Sep 17 00:00:00 2001 From: bernatx Date: Thu, 15 Jun 2023 10:15:02 +0200 Subject: [PATCH 05/29] adding graph to document --- Docs/adv_multigpu.md | 57 ++++++++++++++++------------------ Docs/img/multigpu-example.png | Bin 0 -> 25382 bytes 2 files changed, 27 insertions(+), 30 deletions(-) create mode 100644 Docs/img/multigpu-example.png diff --git a/Docs/adv_multigpu.md b/Docs/adv_multigpu.md index 8b3873cda..52b312ee9 100644 --- a/Docs/adv_multigpu.md +++ b/Docs/adv_multigpu.md @@ -1,52 +1,49 @@ # Carla Multi-GPU feature -Multi-GPU in carla means that the user can start several servers (called secondary servers) that will do render work for the main server (called primary server) for different sensors. +Multi-GPU in carla means that the user can start several servers (called secondary servers) that will do render work for the main server (called primary server) using a dedicated GPU from the system. The primary server will distribute the sensors, that are created by the user, to the different secondary servers available. + +![Multi-GPU example with 2 secondary servers](img/multigpu-example.png) + +We need to start the primary server (usually with a flag to avoid using any GPU). This server will process all physics and synchronize the scene data to the others secondary servers. Then we can start any secondary server as we want (usually one per dedicated GPU in the system), using the parameters we will describe further. After this, the client can connect (always to the primary server) and proceed as usual. +All the system is transparent to the user, who don't need to know from which server comes the sensor data, he just receives the data directly from a secondary server. ## Primary server -The steps are: first, start the primary server without any render capability. The parameters we can use are: +The steps are, first, start the primary server without any render capability. +The parameters we can use are: +* `-nullrhi`: disables any render capabilities (GPU free) +* `-carla-primary-port`: TCP port used to listen for secondary servers (default 2002) -* `-nullrhi` -* `-carla-primary-port` +For example -Run the following from the command line: +**./CarlaUE4.sh --nullrhi** -```sh -./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 -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 port flag: - -```sh -./CarlaUE4.sh -nullrhi -carla-primary-port=3002 -``` +**./CarlaUE4.sh --nullrhi -carla-primary-port=3002** ## Secondary servers -We may then start as many servers as we need, but the ideal is to have as many secondary servers as the number of GPUs installed in the computer. Through parameters we need to specify the GPU we want the server use and also the host/port where the primary server is listening, with the flags: +Then we need to start as many servers as we want, but the ideal is to have as many secondary servers as GPU. Through parameters we need to specify the GPU we want the server use and also the host/port where the primary server is listenning, with the flags: + * `-carla-rpc-port`: TCP port to accept client connections (for secondary servers it is not needed, but the port needs to be free) + * `-carla-primary-host`: IP of the primary server to connect + * `-carla-primary-port`: TCP port of the primary server to connect + * `-ini:[/Script/Engine.RendererSettings]:r.GraphicsAdapter`: tells which GPU device to use for this secondary server - * `-carla-rpc-port` - * `-carla-primary-host` - * `-carla-primary-port` - * `-ini:[/Script/Engine.RendererSettings]:r.GraphicsAdapter` +For example, if the primary server is executing in the same computer than the secondary servers and with the default port, we can use this: -For example, if the primary server is executing in the same computer than the secondary servers and with the default port, we can use this command: - -```sh -./CarlaUE4.sh -carla-rpc-port=3000 -carla-primary-host=127.0.0.1 -ini:[/Script/Engine.RendererSettings]:r.GraphicsAdapter=0 -``` +**./CarlaUE4.sh -carla-rpc-port=3000 -carla-primary-host=127.0.0.1 -ini:[/Script/Engine.RendererSettings]:r.GraphicsAdapter=0** Here, the secondary server will use port 3000 as the RPC server to avoid conflicts with other ports (but it will never be used), and will connect to the primary server located at IP 127.0.0.1 (localhost) in the default port (2002), and also this server will use the GPU device 0. -If we want to start another secondary server using another GPU, we could use the following command: +If we want to start another secondary server in the same machine using another GPU, we could use this command: -```sh -./CarlaUE4.sh -carla-rpc-port=4000 -carla-primary-host=127.0.0.1 -carla-primary-port=2002 -ini:[/Script/Engine.RendererSettings]:r.GraphicsAdapter=1 -``` +**./CarlaUE4.sh -carla-rpc-port=4000 -carla-primary-host=127.0.0.1 -carla-primary-port=2002 -ini:[/Script/Engine.RendererSettings]:r.GraphicsAdapter=1** -This secondary server will use port 4000 as the RPC server to avoid conflicts with other ports and will connect to the primary server located at IP 127.0.0.1 in port 2002, and also this server will use the GPU device 1. +This secondary server will use port 4000 as the RPC server to avoid conflicts with other ports and will connect to the primary server located at IP 127.0.0.1 in the port 2002, and also this server will use the GPU device 1. -## Pipeline +## Synchronous mode + +After the first secondary server connects to the primary server, the system is setup to synchronous mode automatically, with the default values of 1/20 delta seconds. -After the first secondary server connects to the primary server, it will set up the synchronous mode automatically, with the default values of 1/20 delta seconds. diff --git a/Docs/img/multigpu-example.png b/Docs/img/multigpu-example.png new file mode 100644 index 0000000000000000000000000000000000000000..a0763daad1ed4b867bfce2a9a596ca195bb9a93e GIT binary patch literal 25382 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 PNLx0UZM?VM;ne>C)CAIu literal 0 HcmV?d00001 From 603633c08fe17696290d28f469551e079052c595 Mon Sep 17 00:00:00 2001 From: MattRoweEAIF <125647690+MattRoweEAIF@users.noreply.github.com> Date: Tue, 14 Nov 2023 13:02:28 +0100 Subject: [PATCH 06/29] Tidy up of SimReady docs after release (#6910) * added simready instructions * tidied up SimReady instructions * typos --- Docs/ecosys_simready.md | 86 +++++++++++++++++++++-------------------- 1 file changed, 44 insertions(+), 42 deletions(-) diff --git a/Docs/ecosys_simready.md b/Docs/ecosys_simready.md index 996cd2df0..da15569bc 100644 --- a/Docs/ecosys_simready.md +++ b/Docs/ecosys_simready.md @@ -1,64 +1,66 @@ -# SimReady content with NVIDIA Omnivers +# SimReady content with NVIDIA Omniverse -NVIDIA's [__SimReady__](#simready-content-from-nvidias-omniverse) specification supports the preparation of 3D content that is purpose-built for simulation to help streamline content creation pipelines for simulating 3D virtual environments for machine learning purposes in robotics and autonomous driving. Through the Omniverse Unreal Engine plugin now integrated into CARLA users can import, in just a few clicks, SimReady content such as vehicles already configured with working lights, doors and wheels and props ready for use instantaneously to decorate CARLA maps. CARLA's Omniverse integration boasts to significantly accelerate your environment building pipeline and opens the door to a whole world of applications in the [__Omniverse ecosystem__](https://www.nvidia.com/en-us/omniverse/ecosystem/). +NVIDIA's [__SimReady__](https://developer.nvidia.com/omniverse/simready-assets) specification supports the preparation of __3D content that is purpose-built for simulation__ to help streamline content creation pipelines for simulating 3D virtual environments for machine learning purposes in robotics and autonomous driving. Through the Omniverse Unreal Engine plugin now integrated into CARLA users can import, in just a few clicks, SimReady content such as vehicles already configured with working lights, doors and wheels and props ready for use instantaneously to decorate CARLA maps. CARLA's Omniverse integration boasts to significantly accelerate your environment building pipeline and opens the door to a whole world of applications in the [__Omniverse ecosystem__](https://www.nvidia.com/en-us/omniverse/ecosystem/). -The Omniverse Unreal Engine Connector is currently only available in Windows. +!!! note + The Omniverse Unreal Engine Connector is currently only available in Windows. -Follow these stesps to start using Omniverse and using SimReady content in CARLA: +Follow these steps to start using Omniverse and using SimReady content in CARLA: Before anything else, you should first [install NVIDIA Omniverse](https://docs.omniverse.nvidia.com/install-guide/latest/index.html) ### 1. Installing the Unreal Engine Omniverse Connector -1. Launch the NVIDIA Omniverse Launcher. -2. Navigate to the Exchange tab. -3. Locate the Epic Games Unreal Engine 4.26 Omniverse Connector. -4. Ensure the Install version is Release 105.1.578 -5. Click *Install*. -6. Omniverse will not find Unreal Engine, click OK. -7. It will prompt you to find your Unreal Engine installation, Select this path: {UE4_ROOT}\Engine\Plugins\Marketplace\NVIDIA +1. Launch the NVIDIA Omniverse Launcher +2. Navigate to the **Exchange** tab +3. Locate the __Epic Games Unreal Engine 4.26 Omniverse Connector__ +4. Ensure the install version is **Release 105.1.578** +5. Click *Install* +6. Omniverse will not be able to find Unreal Engine, click **OK**. +7. It will prompt you to find your Unreal Engine installation, select this path: {UE4_ROOT}\Engine\Plugins\Marketplace\NVIDIA 8. Press *Install*. ### 2. Set Up Local Omniverse Server -1. Launch the NVIDIA Omniverse Launcher. -2. Navigate to the Nucleus tab. -3. Click on create Local Server. -4. Add administrator details (any). -5. Select on the folder icon next to Local Nucleus Service, this should open your localhost server navigator. +1. Open NVIDIA Omniverse with the launcher +2. Navigate to the *Nucleus* tab +3. Click on *Create Local Server* +4. Create administrator details +5. Select the folder icon next to *Local Nucleus Service*, this should open your localhost server in your web browser ### 3. Connecting to CARLA Simulator -1. Launch CARLA using `make launch` from the command line ine the CARLA root folder. -2. If an existing server is active, and you want to restart the setup, click on Clean Local Assets. (Optional) -3. Select the Omniverse icon and click on *Add Server*. -4. Name the server and click *Add to Content Browser*. -5. A login form should launch in your browser, click *Create Account*. -6. Add administrator details(any). -7. Omniverse folders should have appeared in your Content/Omniverse folder within the Engine. -8. Go to your local host browser Navigator -9. Click on *Connect to a Server*. -10. Authenticate using the server name you set for the CARLA server. -11. Use administrator details you set for the CARLA server. -12. The server folders should now show up in your browser navigator. +1. Launch CARLA using `make launch` from the command line the CARLA root folder +2. If an existing server is active and you want to restart the setup, click on *Clean Local Assets* (optional) +3. Select the *Omniverse* icon and click on *Add Server* +4. Name the server and click *Add to Content Browser* +5. A login form should launch in your browser, click *Create Account* +6. Create administrator details +7. Omniverse folders should now be visible in your Content/Omniverse folder in the Unreal Engine content browser +8. Go to your web browser again +9. Click on *Connect to a Server* +10. Authenticate using the server name you set for the CARLA server +11. Use the administrator details that you set for the CARLA server +12. The server folders should now show up in your browser -### 4. Importing the SimReady Car Asset +### 4. Importing a SimReady asset -1. Navigate to the Projects folder within the browser navigator. -2. Right click, and select Upload Folder. -3. Select your SimReady folders. -4. Upload the files. +1. Navigate to the Projects folder within the browser navigator +2. Right click, and select *Upload Folder* +3. Select your SimReady folders +4. Upload the files ### 5. Using the Omniverse Connector to Load the Vehicle to CARLA -1. Open the CARLA project in Unreal Engine. -2. Navigate to CarlaTools Content\USDImporter. -3. Right click on *UW_USDVehicleImporterEditorWidget*. -4. Select *Run Editor Utility Widget*. +1. Open the CARLA project in Unreal Engine +2. Navigate to `CarlaTools/Content/USDImporter` +3. Right click on *UW_USDVehicleImporterEditorWidget* +4. Select *Run Editor Utility Widget* 5. Find the Vehicle within your Omniverse browser navigator 6. Copy the path (should look something like: omniverse://localhost/Projects/SimReadyUSD.../vehicle.usd) -7. Paste it inside the Omiverse URL tab within the Widget. -8. Select Import Asset. -9. You should see the vehicle show up in the engine, within Content/OmniverseImports. -10. Open another map scene since it opened a new scene with the imported data, a *Save Content* prompt should appear. Uncheck the *Untitled* scene, and click on *Save selected* to save new content. -11. The vehicle is now usable within CARLA. +7. Paste it inside the Omiverse URL tab within the Widget +8. Select *Import Asset* +9. You should see the vehicle show up in the engine within the folder that you specified in the *Import destination* field +10. Open another map scene (it may have opened a new scene with the imported data) a *Save Content* prompt should appear. Uncheck the *Untitled* scene, and click on *Save selected* to save new content +11. The vehicle is now usable within CARLA and will be available through the Python API + From 0ac122b69921c3d1454e0f2eb7ad0c83a5283f44 Mon Sep 17 00:00:00 2001 From: Fabian Oboril Date: Tue, 14 Nov 2023 11:22:08 +0100 Subject: [PATCH 07/29] Enable RSS build with CARLA 0.9.15 --- LibCarla/cmake/client/CMakeLists.txt | 8 ++++++++ Util/BuildTools/Ad-rss.sh | 23 +++++++++++------------ Util/BuildTools/BuildLibCarla.sh | 2 +- 3 files changed, 20 insertions(+), 13 deletions(-) diff --git a/LibCarla/cmake/client/CMakeLists.txt b/LibCarla/cmake/client/CMakeLists.txt index b4ecce487..6c085f6b3 100644 --- a/LibCarla/cmake/client/CMakeLists.txt +++ b/LibCarla/cmake/client/CMakeLists.txt @@ -21,6 +21,14 @@ if (BUILD_RSS_VARIANT) install(FILES ${spdlog_file} DESTINATION lib) list(APPEND ADRSS_LIBS ${spdlog_file}) + set(proj_include_dir ${ADRSS_INSTALL_DIR}/../../proj-install/include) + set(proj_lib ${ADRSS_INSTALL_DIR}/../../proj-install/lib/libproj.a) + install(DIRECTORY ${proj_include_dir} DESTINATION include/system) + list(APPEND ADRSS_INCLUDE_DIRS ${proj_include_dir}) + install(FILES ${proj_lib} DESTINATION lib) + list(APPEND ADRSS_LIBS ${proj_lib}) + + foreach(ad_lib ad_physics ad_rss ad_map_access ad_map_opendrive_reader ad_rss_map_integration) set(${ad_lib}_file ${ADRSS_INSTALL_DIR}/${ad_lib}/lib/lib${ad_lib}.a) install(FILES ${${ad_lib}_file} DESTINATION lib) diff --git a/Util/BuildTools/Ad-rss.sh b/Util/BuildTools/Ad-rss.sh index 9c6bfecd1..d05f69a49 100755 --- a/Util/BuildTools/Ad-rss.sh +++ b/Util/BuildTools/Ad-rss.sh @@ -29,7 +29,7 @@ IFS="," read -r -a PY_VERSION_LIST <<< "${PY_VERSION_LIST}" # -- Get ad-rss ------------------------------------------- # ============================================================================== -ADRSS_VERSION=4.4.3 +ADRSS_VERSION=4.5.3 ADRSS_BASENAME=ad-rss-${ADRSS_VERSION} ADRSS_COLCON_WORKSPACE="${CARLA_BUILD_FOLDER}/${ADRSS_BASENAME}" ADRSS_SRC_DIR="${ADRSS_COLCON_WORKSPACE}/src" @@ -40,10 +40,12 @@ if [[ ! -d "${ADRSS_SRC_DIR}" ]]; then mkdir -p "${ADRSS_SRC_DIR}" + # clone ad-rss with all submodules, but remove proj, as CARLA already uses it pushd "${ADRSS_SRC_DIR}" >/dev/null - git clone --depth=1 -b v1.7.0 https://github.com/gabime/spdlog.git - git clone --depth=1 -b v2.4.5_hotfix https://github.com/carla-simulator/map.git - git clone --depth=1 -b v${ADRSS_VERSION} https://github.com/intel/ad-rss-lib.git + git clone -b v${ADRSS_VERSION} https://github.com/intel/ad-rss-lib.git && cd ad-rss-lib && git submodule update --init --recursive && rm -rf dependencies/map/dependencies/PROJ4 && cd .. + + # ADRSS_VERSION is designed for older boost, update datatype from boost::array to std::array + grep -rl "boost::array" | xargs sed -i 's/boost::array/std::array/g' popd cat >"${ADRSS_COLCON_WORKSPACE}/colcon.meta" </dev/null - if [ "${CMAKE_PREFIX_PATH}" == "" ]; then - CMAKE_PREFIX_PATH="${CARLA_BUILD_FOLDER}/boost-1.72.0-c$CARLA_LLVM_VERSION_MAJOR-install;${CARLA_BUILD_FOLDER}/proj-install" - else - CMAKE_PREFIX_PATH="${CMAKE_PREFIX_PATH};${CARLA_BUILD_FOLDER}/boost-1.72.0-c$CARLA_LLVM_VERSION_MAJOR-install;${CARLA_BUILD_FOLDER}/proj-install" - fi + CMAKE_PREFIX_PATH="${CMAKE_PREFIX_PATH};${CARLA_BUILD_FOLDER}/boost-1.80.0-c$CARLA_LLVM_VERSION_MAJOR-install;${CARLA_BUILD_FOLDER}/proj-install" # get the python version of the binding to be built - PYTHON_VERSION=$(/usr/bin/env python${PY_VERSION} -V 2>&1) - PYTHON_BINDING_VERSIONS=${PYTHON_VERSION:7:3} + PYTHON_VERSION=3 + PYTHON_BINDING_VERSIONS=${PYTHON_VERSION:8} echo "PYTHON_BINDING_VERSIONS=${PYTHON_BINDING_VERSIONS}" # enforce sequential executor to reduce the required memory for compilation diff --git a/Util/BuildTools/BuildLibCarla.sh b/Util/BuildTools/BuildLibCarla.sh index 783ed594e..891d35853 100755 --- a/Util/BuildTools/BuildLibCarla.sh +++ b/Util/BuildTools/BuildLibCarla.sh @@ -146,7 +146,7 @@ function build_libcarla { M_TOOLCHAIN=${LIBSTDCPP_TOOLCHAIN_FILE} M_BUILD_FOLDER=${LIBCARLA_BUILD_CLIENT_FOLDER}.rss.$(echo "$2" | tr '[:upper:]' '[:lower:]') M_INSTALL_FOLDER=${LIBCARLA_INSTALL_CLIENT_FOLDER} - CMAKE_EXTRA_OPTIONS="${CMAKE_EXTRA_OPTIONS:+${CMAKE_EXTRA_OPTIONS} }-DBUILD_RSS_VARIANT=ON -DADRSS_INSTALL_DIR=${CARLA_BUILD_FOLDER}/ad-rss-4.4.3/install" + CMAKE_EXTRA_OPTIONS="${CMAKE_EXTRA_OPTIONS:+${CMAKE_EXTRA_OPTIONS} }-DBUILD_RSS_VARIANT=ON -DADRSS_INSTALL_DIR=${CARLA_BUILD_FOLDER}/ad-rss-4.5.3/install" else fatal_error "Invalid build configuration \"$1\"" fi From 834679d254cd7cb9f8b3fed020ab1030a27e6959 Mon Sep 17 00:00:00 2001 From: Tay Yim Date: Fri, 17 Nov 2023 02:58:40 -0600 Subject: [PATCH 08/29] Fix typo in map_town13.md (#6920) * Update map_town13.md Typo: This should be Town 12 --- Docs/map_town13.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Docs/map_town13.md b/Docs/map_town13.md index 7a86e3e3c..9ea5ff694 100644 --- a/Docs/map_town13.md +++ b/Docs/map_town13.md @@ -5,7 +5,7 @@ Town 13 is a Large Map with dimensions of 10x10 km2. It is divided into 36 tiles, most with dimensions of 2x2 km2 (some edge tiles are smaller). There are numerous contrasting regions to the city including urban, residential and rural areas, along with a large highway system surrounding the city with a ringroad. The architectural styles reflect those of many medium to large cities across North America. !!! note - Town 13 has been designed as an adjunct to Town 13, such that they can serve as a __train-test pair__. The towns share many common features, but also many differences in the styles of buildings, road textures, pavement textures and also vegetation. Using one of the pair to produce training data and then using the other for testing is ideal for exposing overfitting issues that might be arising while developing an AD stack. + Town 13 has been designed as an adjunct to Town 12, such that they can serve as a __train-test pair__. The towns share many common features, but also many differences in the styles of buildings, road textures, pavement textures and also vegetation. Using one of the pair to produce training data and then using the other for testing is ideal for exposing overfitting issues that might be arising while developing an AD stack. ## Navigator From c461f901cf5e76357b7ef1da0da0c20b5fb584d9 Mon Sep 17 00:00:00 2001 From: javiergrCS <139075626+javiergrCS@users.noreply.github.com> Date: Thu, 23 Nov 2023 09:36:43 +0100 Subject: [PATCH 09/29] Javiergr cs/recorder doors (#6922) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Fix a typo in setting the max brake From self._max_steer to self._max_brake * Fix example commands in Multi-GPU docs Only one dash before `-nullrhi` argument * Correct incoherent structuring of tutorial for adding sensor to CARLA. * Add contribution to CHANGELOG.md * Add notes into breakout boxes in sensor create tutorial. * Update build_linux.md Change pseudopath to linux format * Update build_linux.md The same change 1 line above * Fixing Recast pulling by branch instead of hash id * Added functionality to the recorder to add door state info * Final update * Correction CarlaRecorder.h * Include correction CarlaRecorderQuery.cpp * Last correction * Changelog update * Last corrections --------- Co-authored-by: kykim0 Co-authored-by: bernatx Co-authored-by: Paul Erik Frivold Co-authored-by: Balázs Kis Co-authored-by: matejm42 <116560704+matejm42@users.noreply.github.com> Co-authored-by: Blyron <53337103+Blyron@users.noreply.github.com> --- CHANGELOG.md | 4 + .../Source/Carla/Recorder/CarlaRecorder.cpp | 19 +++++ .../Source/Carla/Recorder/CarlaRecorder.h | 8 ++ .../Recorder/CarlaRecorderDoorVehicle.cpp | 75 +++++++++++++++++++ .../Carla/Recorder/CarlaRecorderDoorVehicle.h | 45 +++++++++++ .../Carla/Recorder/CarlaRecorderQuery.cpp | 45 +++++++++++ .../Carla/Recorder/CarlaRecorderQuery.h | 2 + .../Source/Carla/Recorder/CarlaReplayer.cpp | 27 +++++++ .../Source/Carla/Recorder/CarlaReplayer.h | 2 + .../Carla/Recorder/CarlaReplayerHelper.cpp | 18 +++++ .../Carla/Recorder/CarlaReplayerHelper.h | 4 + .../Carla/Settings/CarlaSettingsDelegate.cpp | 2 +- .../Carla/Vehicle/CarlaWheeledVehicle.cpp | 12 +++ .../Carla/Vehicle/CarlaWheeledVehicle.h | 3 + 14 files changed, 265 insertions(+), 1 deletion(-) create mode 100644 Unreal/CarlaUE4/Plugins/Carla/Source/Carla/Recorder/CarlaRecorderDoorVehicle.cpp create mode 100644 Unreal/CarlaUE4/Plugins/Carla/Source/Carla/Recorder/CarlaRecorderDoorVehicle.h diff --git a/CHANGELOG.md b/CHANGELOG.md index 8e25a3c61..56073502d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,7 @@ +## Latest + + * Added vehicle doors to the recorder + ## CARLA 0.9.15 * Added Digital Twins feature version 0.1. Now you can create your own map based on OpenStreetMaps diff --git a/Unreal/CarlaUE4/Plugins/Carla/Source/Carla/Recorder/CarlaRecorder.cpp b/Unreal/CarlaUE4/Plugins/Carla/Source/Carla/Recorder/CarlaRecorder.cpp index 50cadabd8..596e8473f 100644 --- a/Unreal/CarlaUE4/Plugins/Carla/Source/Carla/Recorder/CarlaRecorder.cpp +++ b/Unreal/CarlaUE4/Plugins/Carla/Source/Carla/Recorder/CarlaRecorder.cpp @@ -304,6 +304,15 @@ void ACarlaRecorder::AddVehicleLight(FCarlaActor *CarlaActor) AddLightVehicle(LightVehicle); } +void ACarlaRecorder::AddVehicleDoor(const ACarlaWheeledVehicle &Vehicle, const EVehicleDoor SDoors, bool bIsOpen) +{ + CarlaRecorderDoorVehicle DoorVehicle; + DoorVehicle.DatabaseId = Episode->GetActorRegistry().FindCarlaActor(&Vehicle)->GetActorId(); + DoorVehicle.Doors = static_cast(SDoors); + DoorVehicle.bIsOpen = bIsOpen; + AddDoorVehicle(DoorVehicle); +} + void ACarlaRecorder::AddActorKinematics(FCarlaActor *CarlaActor) { check(CarlaActor != nullptr); @@ -478,6 +487,7 @@ void ACarlaRecorder::Clear(void) PhysicsControls.Clear(); TrafficLightTimes.Clear(); WalkersBones.Clear(); + DoorVehicles.Clear(); Wheels.Clear(); Bikers.Clear(); } @@ -496,6 +506,7 @@ void ACarlaRecorder::Write(double DeltaSeconds) EventsDel.Write(File); EventsParent.Write(File); Collisions.Write(File); + DoorVehicles.Write(File); // positions and states Positions.Write(File); @@ -652,6 +663,14 @@ void ACarlaRecorder::AddLightVehicle(const CarlaRecorderLightVehicle &LightVehic } } +void ACarlaRecorder::AddDoorVehicle(const CarlaRecorderDoorVehicle &DoorVehicle) +{ + if (Enabled) + { + DoorVehicles.Add(DoorVehicle); + } +} + void ACarlaRecorder::AddEventLightSceneChanged(const UCarlaLight* Light) { if (Enabled) diff --git a/Unreal/CarlaUE4/Plugins/Carla/Source/Carla/Recorder/CarlaRecorder.h b/Unreal/CarlaUE4/Plugins/Carla/Source/Carla/Recorder/CarlaRecorder.h index f6662d254..12f527728 100644 --- a/Unreal/CarlaUE4/Plugins/Carla/Source/Carla/Recorder/CarlaRecorder.h +++ b/Unreal/CarlaUE4/Plugins/Carla/Source/Carla/Recorder/CarlaRecorder.h @@ -33,7 +33,9 @@ #include "CarlaRecorderState.h" #include "CarlaRecorderVisualTime.h" #include "CarlaRecorderWalkerBones.h" +#include "CarlaRecorderDoorVehicle.h" #include "CarlaReplayer.h" +#include "Carla/Vehicle/CarlaWheeledVehicle.h" #include "CarlaRecorder.generated.h" @@ -67,6 +69,7 @@ enum class CarlaRecorderPacketId : uint8_t FrameCounter, WalkerBones, VisualTime, + VehicleDoor, AnimVehicleWheels, AnimBiker }; @@ -137,6 +140,10 @@ public: void AddActorBones(FCarlaActor *CarlaActor); + void AddVehicleDoor(const ACarlaWheeledVehicle& Vehicle, const EVehicleDoor SDoors, bool bIsOpen); + + void AddDoorVehicle(const CarlaRecorderDoorVehicle &DoorVehicle); + // set episode void SetEpisode(UCarlaEpisode *ThisEpisode) { @@ -208,6 +215,7 @@ private: CarlaRecorderTrafficLightTimes TrafficLightTimes; CarlaRecorderWalkersBones WalkersBones; CarlaRecorderVisualTime VisualTime; + CarlaRecorderDoorVehicles DoorVehicles; // replayer CarlaReplayer Replayer; diff --git a/Unreal/CarlaUE4/Plugins/Carla/Source/Carla/Recorder/CarlaRecorderDoorVehicle.cpp b/Unreal/CarlaUE4/Plugins/Carla/Source/Carla/Recorder/CarlaRecorderDoorVehicle.cpp new file mode 100644 index 000000000..ab6da8860 --- /dev/null +++ b/Unreal/CarlaUE4/Plugins/Carla/Source/Carla/Recorder/CarlaRecorderDoorVehicle.cpp @@ -0,0 +1,75 @@ +// Copyright (c) 2023 Computer Vision Center (CVC) at the Universitat Autonoma +// de Barcelona (UAB). +// +// This work is licensed under the terms of the MIT license. +// For a copy, see . + +#include "CarlaRecorderDoorVehicle.h" +#include "CarlaRecorder.h" +#include "CarlaRecorderHelpers.h" + + +void CarlaRecorderDoorVehicle::Write(std::ostream &OutFile) +{ + // database id + WriteValue(OutFile, this->DatabaseId); + WriteValue(OutFile, this->Doors); + WriteValue(OutFile, this->bIsOpen); +} +void CarlaRecorderDoorVehicle::Read(std::istream &InFile) +{ + // database id + ReadValue(InFile, this->DatabaseId); + ReadValue(InFile, this->Doors); + ReadValue(InFile, this->bIsOpen); +} + +// --------------------------------------------- + +void CarlaRecorderDoorVehicles::Clear(void) +{ + Vehicles.clear(); +} + +void CarlaRecorderDoorVehicles::Add(const CarlaRecorderDoorVehicle &Vehicle) +{ + Vehicles.push_back(Vehicle); +} + +void CarlaRecorderDoorVehicles::Write(std::ostream &OutFile) +{ + // write the packet id + WriteValue(OutFile, static_cast(CarlaRecorderPacketId::VehicleDoor)); + + // write a dummy packet size + uint32_t Total = 2 + Vehicles.size() * sizeof(CarlaRecorderDoorVehicle); + WriteValue(OutFile, Total); + + // write total records + Total = Vehicles.size(); + WriteValue(OutFile, Total); + + for (auto& Vehicle : Vehicles) + { + Vehicle.Write(OutFile); + } +} + +void CarlaRecorderDoorVehicles::Read(std::istream &InFile) +{ + uint16_t Total; + CarlaRecorderDoorVehicle DoorVehicle; + + // read Total walkers + ReadValue(InFile, Total); + for (uint16_t i = 0; i < Total; ++i) + { + DoorVehicle.Read(InFile); + Add(DoorVehicle); + } +} + +const std::vector& CarlaRecorderDoorVehicles::GetDoorVehicles() +{ + return Vehicles; +} diff --git a/Unreal/CarlaUE4/Plugins/Carla/Source/Carla/Recorder/CarlaRecorderDoorVehicle.h b/Unreal/CarlaUE4/Plugins/Carla/Source/Carla/Recorder/CarlaRecorderDoorVehicle.h new file mode 100644 index 000000000..0ba395f47 --- /dev/null +++ b/Unreal/CarlaUE4/Plugins/Carla/Source/Carla/Recorder/CarlaRecorderDoorVehicle.h @@ -0,0 +1,45 @@ +// Copyright (c) 2023 Computer Vision Center (CVC) at the Universitat Autonoma +// de Barcelona (UAB). +// +// This work is licensed under the terms of the MIT license. +// For a copy, see . + +#pragma once + +#include +#include +#include + +#pragma pack(push, 1) +struct CarlaRecorderDoorVehicle +{ + // Use same type as carla::vehicle::CarlaWheeledVehicle::EVehicleDoor + using VehicleDoorType = uint8_t; + + uint32_t DatabaseId; + VehicleDoorType Doors; + bool bIsOpen; + + void Read(std::istream &InFile); + + void Write(std::ostream &OutFile); +}; +#pragma pack(pop) + +struct CarlaRecorderDoorVehicles +{ +public: + + void Add(const CarlaRecorderDoorVehicle &InObj); + + void Clear(void); + + void Write(std::ostream &OutFile); + + void Read(std::istream &InFile); + + const std::vector& GetDoorVehicles(); + +private: + std::vector Vehicles; +}; diff --git a/Unreal/CarlaUE4/Plugins/Carla/Source/Carla/Recorder/CarlaRecorderQuery.cpp b/Unreal/CarlaUE4/Plugins/Carla/Source/Carla/Recorder/CarlaRecorderQuery.cpp index 47cda18c5..75f2202c8 100644 --- a/Unreal/CarlaUE4/Plugins/Carla/Source/Carla/Recorder/CarlaRecorderQuery.cpp +++ b/Unreal/CarlaUE4/Plugins/Carla/Source/Carla/Recorder/CarlaRecorderQuery.cpp @@ -19,6 +19,8 @@ #include #include +#include + inline bool CarlaRecorderQuery::ReadHeader(void) { if (File.eof()) @@ -271,6 +273,49 @@ std::string CarlaRecorderQuery::QueryInfo(std::string Filename, bool bShowAll) SkipPacket(); break; + // vehicle door animations + case static_cast(CarlaRecorderPacketId::VehicleDoor): + if (bShowAll) + { + ReadValue(File, Total); + if (Total > 0 && !bFramePrinted) + { + PrintFrame(Info); + bFramePrinted = true; + } + Info << " Vehicle door animations: " << Total << std::endl; + for (i = 0; i < Total; ++i) + { + DoorVehicle.Read(File); + + CarlaRecorderDoorVehicle::VehicleDoorType doorVehicle; + doorVehicle = DoorVehicle.Doors; + EVehicleDoor eDoorVehicle = static_cast(doorVehicle); + std::string opened_doors_list; + + Info << " Id: " << DoorVehicle.DatabaseId << std::endl; + Info << " Doors opened: "; + if (eDoorVehicle == EVehicleDoor::FL) + Info << " Front Left " << std::endl; + if (eDoorVehicle == EVehicleDoor::FR) + Info << " Front Right " << std::endl; + if (eDoorVehicle == EVehicleDoor::RL) + Info << " Rear Left " << std::endl; + if (eDoorVehicle == EVehicleDoor::RR) + Info << " Rear Right " << std::endl; + if (eDoorVehicle == EVehicleDoor::Hood) + Info << " Hood " << std::endl; + if (eDoorVehicle == EVehicleDoor::Trunk) + Info << " Trunk " << std::endl; + if (eDoorVehicle == EVehicleDoor::All) + Info << " All " << std::endl; + } + } + else + SkipPacket(); + break; + + // vehicle light animations case static_cast(CarlaRecorderPacketId::VehicleLight): if (bShowAll) diff --git a/Unreal/CarlaUE4/Plugins/Carla/Source/Carla/Recorder/CarlaRecorderQuery.h b/Unreal/CarlaUE4/Plugins/Carla/Source/Carla/Recorder/CarlaRecorderQuery.h index 070fb117c..f3e4c53cb 100644 --- a/Unreal/CarlaUE4/Plugins/Carla/Source/Carla/Recorder/CarlaRecorderQuery.h +++ b/Unreal/CarlaUE4/Plugins/Carla/Source/Carla/Recorder/CarlaRecorderQuery.h @@ -26,6 +26,7 @@ #include "CarlaRecorderPosition.h" #include "CarlaRecorderState.h" #include "CarlaRecorderWalkerBones.h" +#include "CarlaRecorderDoorVehicle.h" class CarlaRecorderQuery { @@ -69,6 +70,7 @@ private: CarlaRecorderPhysicsControl PhysicsControl; CarlaRecorderTrafficLightTime TrafficLightTime; CarlaRecorderWalkerBones WalkerBones; + CarlaRecorderDoorVehicle DoorVehicle; // read next header packet bool ReadHeader(void); diff --git a/Unreal/CarlaUE4/Plugins/Carla/Source/Carla/Recorder/CarlaReplayer.cpp b/Unreal/CarlaUE4/Plugins/Carla/Source/Carla/Recorder/CarlaReplayer.cpp index 918d3aa51..64e208b55 100644 --- a/Unreal/CarlaUE4/Plugins/Carla/Source/Carla/Recorder/CarlaReplayer.cpp +++ b/Unreal/CarlaUE4/Plugins/Carla/Source/Carla/Recorder/CarlaReplayer.cpp @@ -378,6 +378,14 @@ void CarlaReplayer::ProcessToTime(double Time, bool IsFirstTime) SkipPacket(); break; + // vehicle door animation + case static_cast(CarlaRecorderPacketId::VehicleDoor): + if (bFrameFound) + ProcessDoorVehicle(); + else + SkipPacket(); + break; + // scene lights animation case static_cast(CarlaRecorderPacketId::SceneLight): if (bFrameFound) @@ -649,6 +657,25 @@ void CarlaReplayer::ProcessLightVehicle(void) } } +void CarlaReplayer::ProcessDoorVehicle(void) +{ + uint16_t Total; + CarlaRecorderDoorVehicle DoorVehicle; + + // read Total walkers + ReadValue(File, Total); + for (uint16_t i = 0; i < Total; ++i) + { + DoorVehicle.Read(File); + DoorVehicle.DatabaseId = MappedId[DoorVehicle.DatabaseId]; + // check if ignore this actor + if (!(IgnoreHero && IsHeroMap[DoorVehicle.DatabaseId])) + { + Helper.ProcessReplayerDoorVehicle(DoorVehicle); + } + } +} + void CarlaReplayer::ProcessLightScene(void) { uint16_t Total; diff --git a/Unreal/CarlaUE4/Plugins/Carla/Source/Carla/Recorder/CarlaReplayer.h b/Unreal/CarlaUE4/Plugins/Carla/Source/Carla/Recorder/CarlaReplayer.h index f1e73f05e..3e2f2408b 100644 --- a/Unreal/CarlaUE4/Plugins/Carla/Source/Carla/Recorder/CarlaReplayer.h +++ b/Unreal/CarlaUE4/Plugins/Carla/Source/Carla/Recorder/CarlaReplayer.h @@ -158,6 +158,8 @@ private: void ProcessLightVehicle(void); void ProcessLightScene(void); + void ProcessDoorVehicle(void); + void ProcessWalkerBones(void); // positions diff --git a/Unreal/CarlaUE4/Plugins/Carla/Source/Carla/Recorder/CarlaReplayerHelper.cpp b/Unreal/CarlaUE4/Plugins/Carla/Source/Carla/Recorder/CarlaReplayerHelper.cpp index 3ca4c4b4f..9bfa120f6 100644 --- a/Unreal/CarlaUE4/Plugins/Carla/Source/Carla/Recorder/CarlaReplayerHelper.cpp +++ b/Unreal/CarlaUE4/Plugins/Carla/Source/Carla/Recorder/CarlaReplayerHelper.cpp @@ -416,6 +416,24 @@ void CarlaReplayerHelper::ProcessReplayerAnimVehicle(CarlaRecorderAnimVehicle Ve } } +// set the openings and closings of vehicle doors +void CarlaReplayerHelper::ProcessReplayerDoorVehicle(CarlaRecorderDoorVehicle DoorVehicle) +{ + check(Episode != nullptr); + FCarlaActor * CarlaActor = Episode->FindCarlaActor(DoorVehicle.DatabaseId); + if (CarlaActor) + { + ACarlaWheeledVehicle * Vehicle = Cast(CarlaActor->GetActor()); + if (Vehicle) { + if(DoorVehicle.bIsOpen){ + Vehicle->OpenDoor(static_cast(DoorVehicle.Doors)); + }else{ + Vehicle->CloseDoor(static_cast(DoorVehicle.Doors)); + } + } + } +} + // set the lights for vehicles void CarlaReplayerHelper::ProcessReplayerLightVehicle(CarlaRecorderLightVehicle LightVehicle) { diff --git a/Unreal/CarlaUE4/Plugins/Carla/Source/Carla/Recorder/CarlaReplayerHelper.h b/Unreal/CarlaUE4/Plugins/Carla/Source/Carla/Recorder/CarlaReplayerHelper.h index f6751117d..d4379dddd 100644 --- a/Unreal/CarlaUE4/Plugins/Carla/Source/Carla/Recorder/CarlaReplayerHelper.h +++ b/Unreal/CarlaUE4/Plugins/Carla/Source/Carla/Recorder/CarlaReplayerHelper.h @@ -15,6 +15,7 @@ #include "CarlaRecorderAnimVehicleWheels.h" #include "CarlaRecorderLightVehicle.h" #include "CarlaRecorderLightScene.h" +#include "CarlaRecorderDoorVehicle.h" #include "CarlaRecorderWalkerBones.h" #include @@ -65,6 +66,9 @@ public: // set the animation for walkers void ProcessReplayerAnimWalker(CarlaRecorderAnimWalker Walker); + // set the openings and closing of vehicle doors + void ProcessReplayerDoorVehicle(CarlaRecorderDoorVehicle DoorVehicle); + // set the animation for bikers void ProcessReplayerAnimBiker(CarlaRecorderAnimBiker Biker); diff --git a/Unreal/CarlaUE4/Plugins/Carla/Source/Carla/Settings/CarlaSettingsDelegate.cpp b/Unreal/CarlaUE4/Plugins/Carla/Source/Carla/Settings/CarlaSettingsDelegate.cpp index 33f018ae2..673ef6ebe 100644 --- a/Unreal/CarlaUE4/Plugins/Carla/Source/Carla/Settings/CarlaSettingsDelegate.cpp +++ b/Unreal/CarlaUE4/Plugins/Carla/Source/Carla/Settings/CarlaSettingsDelegate.cpp @@ -4,7 +4,7 @@ #include "Carla/Game/CarlaGameInstance.h" #include "Carla/Settings/CarlaSettings.h" -#include "Carla/Game/CarlaGameInstance.h" + #include "Async.h" #include "Components/StaticMeshComponent.h" #include "Engine/DirectionalLight.h" diff --git a/Unreal/CarlaUE4/Plugins/Carla/Source/Carla/Vehicle/CarlaWheeledVehicle.cpp b/Unreal/CarlaUE4/Plugins/Carla/Source/Carla/Vehicle/CarlaWheeledVehicle.cpp index 1580e7180..8ba705acd 100644 --- a/Unreal/CarlaUE4/Plugins/Carla/Source/Carla/Vehicle/CarlaWheeledVehicle.cpp +++ b/Unreal/CarlaUE4/Plugins/Carla/Source/Carla/Vehicle/CarlaWheeledVehicle.cpp @@ -1019,6 +1019,8 @@ void ACarlaWheeledVehicle::OpenDoorPhys(const EVehicleDoor DoorIdx) { (*CollisionDisable)->InitComponentConstraint(); } + + RecordDoorChange(DoorIdx, true); } void ACarlaWheeledVehicle::CloseDoorPhys(const EVehicleDoor DoorIdx) @@ -1032,6 +1034,16 @@ void ACarlaWheeledVehicle::CloseDoorPhys(const EVehicleDoor DoorIdx) DoorComponent->SetWorldTransform(DoorInitialTransform); DoorComponent->AttachToComponent( GetMesh(), FAttachmentTransformRules(EAttachmentRule::KeepWorld, true)); + RecordDoorChange(DoorIdx, false); +} + +void ACarlaWheeledVehicle::RecordDoorChange(const EVehicleDoor DoorIdx, bool bIsOpen) +{ + auto * Recorder = UCarlaStatics::GetRecorder(GetWorld()); + if (Recorder && Recorder->IsEnabled()) + { + Recorder->AddVehicleDoor(*this, DoorIdx, bIsOpen); + } } void ACarlaWheeledVehicle::ApplyRolloverBehavior() diff --git a/Unreal/CarlaUE4/Plugins/Carla/Source/Carla/Vehicle/CarlaWheeledVehicle.h b/Unreal/CarlaUE4/Plugins/Carla/Source/Carla/Vehicle/CarlaWheeledVehicle.h index 704d4c72f..0f5b4fea8 100644 --- a/Unreal/CarlaUE4/Plugins/Carla/Source/Carla/Vehicle/CarlaWheeledVehicle.h +++ b/Unreal/CarlaUE4/Plugins/Carla/Source/Carla/Vehicle/CarlaWheeledVehicle.h @@ -406,6 +406,9 @@ public: UFUNCTION(Category = "CARLA Wheeled Vehicle", BlueprintCallable) void CloseDoorPhys(const EVehicleDoor DoorIdx); + UFUNCTION(Category = "CARLA Wheeled Vehicle", BlueprintCallable) + void RecordDoorChange(const EVehicleDoor DoorIdx, const bool bIsOpen); + virtual FVector GetVelocity() const override; //-----CARSIM-------------------------------- From b745d6eeffe8386514f253492cae33ac65f69c17 Mon Sep 17 00:00:00 2001 From: MattRoweEAIF Date: Thu, 16 Nov 2023 14:47:08 +0100 Subject: [PATCH 10/29] removed build status --- README.md | 32 +++++--------------------------- 1 file changed, 5 insertions(+), 27 deletions(-) diff --git a/README.md b/README.md index 98086e0c0..2afb6a9fa 100644 --- a/README.md +++ b/README.md @@ -1,7 +1,6 @@ CARLA Simulator =============== -[![Build Status](https://travis-ci.org/carla-simulator/carla.svg?branch=master)](https://travis-ci.org/carla-simulator/carla) [![Documentation](https://readthedocs.org/projects/carla/badge/?version=latest)](http://carla.readthedocs.io) [![carla.org](Docs/img/btn/web.png)](http://carla.org) @@ -33,8 +32,8 @@ Windows: * Intel i7 gen 9th - 11th / Intel i9 gen 9th - 11th / AMD ryzen 7 / AMD ryzen 9 * +16 GB RAM memory -* NVIDIA RTX 2070 / NVIDIA RTX 2080 / NVIDIA RTX 3070, NVIDIA RTX 3080 -* Ubuntu 18.04 +* NVIDIA RTX 2070 / NVIDIA RTX 2080 / NVIDIA RTX 3070, NVIDIA RTX 3080 / NVIDIA RTX 4090 +* Ubuntu 20.04 ## CARLA Ecosystem Repositories associated to the CARLA simulation platform: @@ -46,8 +45,10 @@ Repositories associated to 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 * [**Map Editor**](https://github.com/carla-simulator/carla-map-editor): Standalone GUI application to enhance RoadRunner maps with traffic lights and traffic signs information + **Like what you see? Star us on GitHub to support the project!** Paper @@ -76,7 +77,7 @@ Building CARLA Use `git clone` or download the project from this page. Note that the master branch contains the most recent release of CARLA with the latest fixes and features. -Then follow the instruction at [How to build on Linux][buildlinuxlink] or [How to build on Windows][buildwindowslink]. +Then follow the instructions at [How to build on Linux][buildlinuxlink] or [How to build on Windows][buildwindowslink]. The Linux build needs for an UE patch to solve some visualization issues regarding Vulkan. Those already working with a Linux build should install the patch and make the UE build again using the following commands. ```sh # Download and install the UE patch @@ -106,29 +107,6 @@ F.A.Q. If you run into problems, check our [FAQ](https://carla.readthedocs.io/en/latest/build_faq/). -CARLA Talks ------- -The team creates some additional content for users, besides the docs. This is a great way to cover different subjects such as detailed explanations for a specific module, latest improvements in a feature, future work and much more. - -__CARLA Talks 2020 (May):__ - -* __General__ - * Art improvements: environment and rendering — [video](https://youtu.be/ZZaHevsz8W8) | [slides](https://drive.google.com/file/d/1l9Ztaq0Q8fNN5YPU4-5vL13eZUwsQl5P/view?usp=sharing) - * Core implementations: synchrony, snapshots and landmarks — [video](https://youtu.be/nyyTLmphqY4) | [slides](https://drive.google.com/file/d/1yaOwf1419qWZqE1gTSrrknsWOhawEWh_/view?usp=sharing) - * Data ingestion — [video](https://youtu.be/mHiUUZ4xC9o) | [slides](https://drive.google.com/file/d/10uNBAMreKajYimIhwCqSYXjhfVs2bX31/view?usp=sharing) - * Pedestrians and their implementation — [video](https://youtu.be/Uoz2ihDwaWA) | [slides](https://drive.google.com/file/d/1Tsosin7BLP1k558shtbzUdo2ZXVKy5CB/view?usp=sharing) - * Sensors in CARLA — [video](https://youtu.be/T8qCSet8WK0) | [slides](https://drive.google.com/file/d/1UO8ZAIOp-1xaBzcFMfn_IoipycVkUo4q/view?usp=sharing) -* __Modules__ - * Improvements in the Traffic Manager — [video](https://youtu.be/n9cufaJ17eA) | [slides](https://drive.google.com/file/d/1R9uNZ6pYHSZoEBxs2vYK7swiriKbbuxo/view?usp=sharing) - * Integration of autoware and ROS — [video](https://youtu.be/ChIgcC2scwU) | [slides](https://drive.google.com/file/d/1uO6nBaFirrllb08OeqGAMVLApQ6EbgAt/view?usp=sharing) - * Introducing ScenarioRunner — [video](https://youtu.be/dcnnNJowqzM) | [slides](https://drive.google.com/file/d/1zgoH_kLOfIw117FJGm2IVZZAIRw9U2Q0/view?usp=sharing) - * OpenSCENARIO support — [slides](https://drive.google.com/file/d/1g6ATxZRTWEdstiZwfBN1_T_x_WwZs0zE/view?usp=sharing) -* __Features__ - * Co-Simulations with SUMO and PTV-Vissim — [video](https://youtu.be/PuFSbj1PU94) | [slides](https://drive.google.com/file/d/10DgMNUBqKqWBrdiwBiAIT4DdR9ObCquI/view?usp=sharing) - * Integration of RSS-lib — [slides](https://drive.google.com/file/d/1whREmrCv67fOMipgCk6kkiW4VPODig0A/view?usp=sharing) - * The External Sensor Interface (ESI) — [video](https://youtu.be/5hXHPV9FIeY) | [slides](https://drive.google.com/file/d/1VWFaEoS12siW6NtQDUkm44BVO7tveRbJ/view?usp=sharing) - * The OpenDRIVE Standalone Mode — [video](https://youtu.be/U25GhofVV1Q) | [slides](https://drive.google.com/file/d/1D5VsgfX7dmgPWn7UtDDid3-OdS1HI4pY/view?usp=sharing) - Licenses ------- From f40ab6590492bc8132d4d7617733312a377be066 Mon Sep 17 00:00:00 2001 From: MattRoweEAIF Date: Tue, 21 Nov 2023 14:20:25 +0100 Subject: [PATCH 11/29] removed outdated patch instructions --- README.md | 32 +++++++++++++++++++++++++------- 1 file changed, 25 insertions(+), 7 deletions(-) diff --git a/README.md b/README.md index 2afb6a9fa..5eb2986f0 100644 --- a/README.md +++ b/README.md @@ -75,15 +75,33 @@ Felipe Codevilla, Antonio Lopez, Vladlen Koltun; PMLR 78:1-16 Building CARLA -------------- -Use `git clone` or download the project from this page. Note that the master branch contains the most recent release of CARLA with the latest fixes and features. +Clone the repository locally from GitHub: + +```sh +git clone https://github.com/carla-simulator/carla.git . +``` + +Also, clone the [CARLA fork of the Unreal Engine](https://github.com/CarlaUnreal/UnrealEngine) into an appropriate location: + +```sh +git clone --depth 1 -b carla https://github.com/CarlaUnreal/UnrealEngine.git . +``` + +Install the prerequisites (these are for Ubuntu 20.04): + +```sh +sudo apt-add-repository "deb http://apt.llvm.org/focal/ llvm-toolchain-focal main" +sudo apt-get update +sudo apt-get install build-essential clang-10 lld-10 g++-7 cmake ninja-build libvulkan1 python python-dev python3-dev python3-pip libpng-dev libtiff5-dev libjpeg-dev tzdata sed curl unzip autoconf libtool rsync libxml2-dev git +sudo update-alternatives --install /usr/bin/clang++ clang++ /usr/lib/llvm-10/bin/clang++ 180 && +sudo update-alternatives --install /usr/bin/clang clang /usr/lib/llvm-10/bin/clang 180 +``` + +For other versions please consult [the build instructions for Linux][buildlinuxlink] or [for Windows][buildwindowslink]: + +Build Unreal Engine first, inside the directory where you cloned UE: -Then follow the instructions at [How to build on Linux][buildlinuxlink] or [How to build on Windows][buildwindowslink]. -The Linux build needs for an UE patch to solve some visualization issues regarding Vulkan. Those already working with a Linux build should install the patch and make the UE build again using the following commands. ```sh -# Download and install the UE patch -cd ~/UnrealEngine_4.24 -wget https://carla-releases.s3.eu-west-3.amazonaws.com/Linux/UE_Patch/430667-13636743-patch.txt ~/430667-13636743-patch.txt -patch --strip=4 < ~/430667-13636743-patch.txt # Build UE ./Setup.sh && ./GenerateProjectFiles.sh && make ``` From e74523e5e80ec74c2151df989a3366e1f46a6f1d Mon Sep 17 00:00:00 2001 From: MattRoweEAIF Date: Tue, 21 Nov 2023 15:50:24 +0100 Subject: [PATCH 12/29] changed video thumbnail --- Docs/img/0_9_15_thumbnail.webp | Bin 0 -> 35910 bytes README.md | 30 +++++------------------------- 2 files changed, 5 insertions(+), 25 deletions(-) create mode 100644 Docs/img/0_9_15_thumbnail.webp diff --git a/Docs/img/0_9_15_thumbnail.webp b/Docs/img/0_9_15_thumbnail.webp new file mode 100644 index 0000000000000000000000000000000000000000..41c25d1c68f97fb4ac3c72b273c2a44735ced174 GIT binary patch literal 35910 zcmV(vKCsO0|}zS7M7m-er+c2%TDO>^%dmy)-Ak)A(S zKG(psrdxmSo_`|!!1TTHzvw^X_{Zn#`ghZwpMUB9Rpf8xU&DXt z|1azj_~-Kv^Z(fY!h48F=cK=(`#bD$?vLaDXFaSxL;l~Zf8crv|7q(-gmoBM}mdrN4AFaYy^aO})#QC|RyHfBl%io7TT=J{D{z0P|g|8PJ9&HsBZ$c+LU zt3=fszx8x3%V2XI4Mw4N_X}v}!uI6eqMzE%rJA)buKb#f9y91)*h@e(Oz$^D1IshM z$Mqv%I}5e0R0TYQa};ZJuK5Vi;Fx1zt!;!kClVWK;#G2-263t&ZD^Vm^a0B;|=ILurW`c zS}dUr-8F`&ixTLgX-||y(Z1d0iz`=n?$P>{S$Ek?+>E;sAjk1OyliVtyH8+88_*92 zXPs>U%Wga)Ngs%=0k-JHD z*B>{l_gRZ1n8no}F<#0#8!~@%7N&Y?b_<`J28z~(hnqw5pIS$x=SSjh?VU2r){6Ak zZvtM1!M3|aL4y}HslfiRaCDL$8m}$-ipG;d+9c9%0Yt_U1MpKxeb6ak74O9`)@LKQQh!!Z1E-r;Jc_fPnl9L)O%j0z4zrCyuqy1ho z2eo{fDBlR}5C6qd=!b3YETVofl%KzDae3m|=VdT{yW_o%Yv!_?7Bt;hHBU!>|Dpdto8xAmn@D^z!r#}m4mSWvS`h2% zSe9u7S*C_4UN>*Cj_~*%=|6pPRDQ1hUl(S+99-JGY&hD<4}~>|5z%-4*VUMkX#WI%5UV8l;mkiMPuqADR9YAo z;(-M+IZKfEju#*+1Tfy<$bDF0|C9vhgdgx>@Ew6SKX>76KgX^S;T6o=43?4JvxSuJ zQjkXz5T#8io@ zh2cOLIi?eck%jr_b3R^~q?yp#==pCtYV`<#RNbS~-}DjCaVJ{Bmh&0Y zj@X_pPeWFyi<)7$)ivrs910-C#W80@;!zam(9=a2e=|-6?q}sPU{1?UM(`I;0q|RJ zB!cW<2J(fG)owDgoss=WP2ixrAwH^KG^Z%)8o9Vrfyx33#hTz4EQm(-TY{Vn}qX|N9d0xbahpCvSv$C;xcnKL8yiSHqkXqCYf#=|aizr=z8 znHhs0L%$#r7A}Gb%k5Xz#}RMccbTPdRpJ!}?-2N^rG3UKm;Ykn}OO_o~$MNnx*65R&9&L?}LQgLV(3 z-pT%Bqc=Vo>afSg(>pNDU?2+S#&O~7yGuOSrr8VXuU*V_+=0XE{$HzeT9D5eU zMiHbfL2ouV0CSZPB3W+5+tnPs!I$4_nE7juAfAVMB<6h>s$n@r~v#KJck!vh7H!0 zD=L^zWgie8NSpxGxd}g1=p3`_e2ubja2V@tY1yIzm7&CG|Y8sqcdu}A) zG*#C~I`t0K@@|q~t$^>5Sxd_!bR$f?`WOoF$%+aN$>stY0uZJTpu7#S4g|>tuG=EB z(V*u8i`&5;E0IU1V7vtK!y=x}1D$z#mS)_v1o;ndPdUdCJ`Enek#D1ZQ=)4%o`DuQ zIzUP$j4Z~g`AZJnbX6~7U%Td7-Dt>BmS;w|W0n`SZ~GdBjz_O;!zllfJn#}6o#@9s zGiW65Tugtk@U3npf0|>RxLzU~f|VC_E8@C|^^`w}dfZC7GqwzrEk0L{JtRawUt}iT zeEDjP{nqj3ppQA?K!;+TFo$l)JIIcd5aD2Qo@sm#^rAJW*Wp*wvc6QP+NJCq(LX$I zjI^Lp|Gv$+&Q}+OfD>+)7_+@_biOO_6&j@WgJW^^HBHHUD81?~g8(I4JyWDKT5cr4 z&AY$Te5dLsRvZBNkY)_EAJz8ZDh`_~p2KAcGz9+OR^VeY>QMi1`xi$x>vGJ3ueHyH z*bh3TaZ6>#5~^M%>12ypmBeW9E=T7h8!X4NJjXMf)5XEC$$dYwzPU({^^$CsLJ&ThaU?2xvfh?}T*fBmA@4p7S?dCkuq<)s`hYX64C^_99|RpTjBvP!S&__^zKhBv0J=z^XGj zQp16X2OJx$4e&*MIChCP1p)zk8jUYfG9=-B?PD2UVLzyAY9ufft`kOO}*3a{yvS;Zv%43 zx?&Pe27ZosuRVgGmTmXD5Z6`&aM9M|^D1}}yY}!kxNs^YS)b*-z6y$$|9c68z{Pur z-&sX3Ilqm~UEi$MH3bCvrDd}d0b5ut&Oaei%6e-r8~J*yI5$@l zP}C_U4+yhsjRTSt^dJ!xBb2d2oIj8!uh<_aR|sk1h#HopoK7CCc3XPs**|MEigNZH zktpzG_32lGRNFA$ni*5y&Xqs^h5L-MqlY9*MLR0PHdyhP z^Em$UV`pAfAh)PG%)B3iFG-!3rIIB^q;GD`2Jc>6Na|y75lHj;G|xm0&ef6wB($@J zs@YG!eTNde?ncN-gO}G(pAS#GB{-y%-8}*?VNkGcuyx*9fi)EK{mb;f#AJ`KShod> zlIZ>XiYhqAd;au%i0hCKy${zt=2Aln=l5NAIFc-9^uk6Mww-=W0S! zWMXpS>&`K-YH#slmHk$cH*;#0tKk3UdR8CXaEsU)YDVGT##zFY-;-J@>%mjTi5teU z6Y(tAptzu%;R%S^i9x2nxVBS7U*PFpnJ2sD zUKKTwd+>f>j7Xl2QU7IAp^c~(8|7AsnH%@UN|#aT z8YjPQvBGDr>ua1n-aYesg)Y#*6ETVYqjWL&ft_ve+uVqwuiW?u>XnS{!WYHAw|Tgc z-CXnZj?RLRktG?oo7F1%ZI5Y@i=JAyBJ9br)Ir%V3Sd&rivX=k+)`2(F z_+ma>!rgkiwH`9x^wJINn^FFpe*P~WfZaPy7x-rX{fMz75?CC^*l(DQK~u06ffs%& z_~1o~nBEw!8lAVjr|8=Ik{<3Gu}whW2>r=(bz*+!q{)DSukQEcsDPtmE0@+QM6BK1 z}J)Z|(4&WSOM}IkU#`0W`D4;J52g%)j z9rl}d*NU;pbQKmWr2N@yGIzo%No*G(1@Bx232^bkdeqZKgM4gGJZ zgPvS2=#boV+3WrY&mgjQjy69G>p%T?7aVR*tZlzt*e9sE?BOqi4tiahAj>PlJ*Ex5 zpNkR;tqY|-fn!+j)wSc22Bzi}N3Jue#N4RE`@cA7(1GyClVA+{O!sVG;yUk)rXEeegfC{d-|0F)H|Tp!a#!tmyYz9&RtaKgM^@ zzwN|>{n+lQKmYXH7uZs&`A4kOr5SJ|G=3PkwG+9BcLNbFElpaz#Ix_XCG?@wBrs5CgL2&M+=iSbDyyt>NS50B#Gz~~>EmU+QhMh<|?D?!|L?JKSULNJzXsw1f5fA6NU>F-fXHT;l4K@cL#k zyZ`x);;efk#^L2Z+r+8ibb-7tzv0HIJ;OM8CwOIX_A-0LrpGIvzh}_m3oZB~*Z!A$ znL0{>`V&d8bXLRv=aogEjs~sSl`09xu61DEys06h(IxqWFQ3l%J*4>S(zKB;<_3WR zsIMvhUX6y1e}T1K-07nsDal%PHQ*6WCQ+Uk$6##H!nbboZbK+W-fC{_Zi?&5R@{zr zHy>~A%EW|8UaZarlFEHtE>HiVxlXTf`deXd!uT=8Tt=6@Ha=Z2@{on+Fs=)KPqy)^w|$PnLCQ?SN@Zk@v-E9FlMMD||ur`8=B0lTA+`U@v9 zH-LdO?^v-WNw4Z*wSn}A`ch-Aa&gB<|U9Ajg zE&0qvcoX}0VC5;fzrW0xa`67Z*yVS%u#2Y|Jre!&ZPv?4d|!#jeQVNH#77=~b2w!2 zW;>D8+_$BLWZM`|6iY9a@%$-*mjm^g=}n?tTWm zH@WrcHY)K3hZU{Aq=i~-a%ZQjPN(_$*!fZqLuY@BE|NZ3O|4o;U zt9-zEg`LaLHD8O5WpBy2N99^BVUjpm*?2p%CB5!TZdJMJ-6dCqKFiy<{Zpn>f6~t8 ztFc@BO+&t8ZCWI|*CEGDqfMiM(Vwn;1ESVXO4Ww zg{?#W2Oqlb4>0d*Rd8Rsbs@FiWjBuTW08{|-no~a$Mkd!U)5L5a6x;@Q#o+u0Lxm~ z&!(=Qg0Mn&UZE~#dcKzwNJOc7r|7m+@~~Oc;(p1t(D)MRd(WaSFmle%GLv0Yf#5L{ z_z5ADlT@x7tU*$ULuAsL&RSF;Xak?xqUzQmQ?v}=y8QO_1`(`0z@KGrQl<|ijrL9M zgy;GWVcN=7#Rdo>G>KT)7Z&FV1TuZ~n~<~JM?6210=|L9p3!=Y=+nSuo|)D6dZBVZ z`VE^8<~sn1A0j6gUn}&6+P|rx`h0PHw;!`b<9ci4(Q%N{+2&n+?$bOJ)*E$A0Si_C z%I93AEd9h4(;_q<<>ChcDK`(|I=X_If5-i+r>am~i28Gl9_&7d857l!Y?272RJr|; zc4%J719GSRZ|B-E;e|Q%#}D564rTuX!rIB4O|mNabt;X<%-ntNfGzLCA2YS1L;K|N z2-;%#rf_yvp5IwpJGPnfyD##w+BS%K#h|{!OO?}865h^$!$C2R$A8`nF^9qzf%C0d z`Vs1b0vCrH-!f%A{w(0p54&Za?^q4r|Kk<<8mpx(`?ki?iQ>-*s})slQ;16+WXLrk zyWiv0MOXj$*z53;H^$LP@KojeyY^s0--Ne$COv8~>_JY9DXlhc<>rU2jUxcZ`DSIf ziMr&5@rlMjtKxr{t&oj8it5gLBgpF9S5uL%OEM~~mt-ZLNtXh~rz!2CV8Ji`L_AS= zgHSfAV}|zVufmxr;yHPaFf)={`ybBQh0!U4o&FzJhBOBA<4UvH+>7eQ7^?ptfnTIZ z6;odY-;oVJ{j*4I$d{SIV@*E(fqv9S707==K1i@PdJUYADfiIw!7IM#Z?#xKH3 zBSFR2ws9ElBup$3;K*Tpxqn2|ExLlsXYQ#2;!$ja@Moglp;{sz>3j%u!8KdZ62nEN zPV^S1lVY^YE!VwFdUM!d8AEl|dxKB@rY?%-|MMS|?H{|$RnwHj`Z+t5n5a@H= zkac0~`ZgvB`%n(d>3;^O_?-k~Cs*`P zi6Ltr!9l8;O%mPM;`!^_Lh6DW0skS!1%jz)Wo>d*-LBK?>W*kFCy&f6wIMe=*)P|jkcFq0IoqboC?j$F zH?sx*r^R{5J{?{a=YJ zI4TLXz({OAhYkx)52uVfe*0O@Wy>P-n9e3CP<{Wmbr}7TDBX>*6+jTf4w8MOZP4c< z{8lyWBtu%hT0@eq>;d3aPRvgCC$~+3G0vfQLdp3d81#8Q+;^Hq<;h3 z0CX&Lk%#Na5XXdFIqNCroQA}su@mT&Md?+{ItS_;^H5HLOCLcp7X&;+jnv1v#;~KE zbFoh(nRmM=EQLdW6U1ksS3oE6NI!=KjlYDiY?Z(O{4Drkmtmr}L;qNMmk4Hlnbh=^2&!$}b6 z8s|uYCkIiL5|{ip4e|zkaG;bBiuOPtFi1vfb6}x5m?+x7Q$i*R05QG3lk$O&Tq}zq1mzyeEcW6Zq|Ir9n>rUGDu9e+z5y*7 z0e>rm+!(uGu=xe&RjY=XSodsb?i7A2^sBL6>9W& zNIgN|McEDcyp@!~9G?Cl!?y!2qzmR0Db79%$oW(s)S2#Uxr`A4qrdzb=De*SkP#0X zwrGTEAdfMY00003ehvCIW6xEB=Wfjrz>35_VOSzoUQ@3-G_pgz)z4HK2V! z5USX0Lukdd!9q8tuZ1FR_X+06ZwE+`qVi zr|q=x4N{?wtuwfne&=P~HABEku}={1zMl0-*Tk=pj$TpB|8a?NM;yLLWE* za#B4=I17)3?>#fX2E8Jv%e8c)T27jXhZCvHgov@QcCXoi+lu4VAxBEHa#1uE@iI6y78T)*a9v~?T&q>LI-ul4~R1 ze~Nc1d<2n#KEdHs!2>}$p5oiXl(E&gyYzKk*X!;)ZxUw=by{Y{fx5<(r`Q@pK&r)4 zPv%@w^4Aj&1xSVYM_sAe%@t7M3OAAD+!_J|OnU*;@@D}QgbphVMq(2Lt-md$kQF<& zy#R7*VQUA`4rE&90cU{Y>t8%EF@lVhVm4GI_93{JTQ-V{bdr7?4#E2N2*4~qQT?oV z)^_L7L|VyxK2E~p>zgMyasf7NcVDFf;a4jCJFzPh-^Rx9P_zV0QN)=|1L^J>bw@va27VwY+ zh_Uo*wtTbsol9X^1!r-G{&MLoa)x+*eyL>};${`( zItV6VB42@bBa%!wteLF}!Ah8EGmmn(|o23&8ZS(PxU;2?m~x(<5?O7 zsV5)-SF+!Dl?-cDyGEgx{5$a=C3(ld01h{BSzQaoY?28wX6oO1q*UKN+|C>XsX`+@ z13)I+qjnxH>~xg_-b@336#Uvm2;&3ef@|j0HnO~_K z;`CZebof4Yw~Fw+q#a$lIGJ_7g&c%a;)M+oP0H-&xRF|a^^RpZaqU}pONvAc;2Z$+r^!ZCmX{g` z?wu_rT15N&lr~p)_zE?Eu0+fyo-8oERTlRoWlga*ah}U@Z{HMoiDV{b+|rOXAOF?V zl^^<%wos9cEWHa)zA%n8AlM_p+|@|PO0Sl=Gf>U-ZgFIRQ}X^nllaAF}vt#z%U9^?Y|&4_f^=H zQ6o$3aN=sl#%oI3KB=gJvJgNd5>a_nK#Mqs67^EI)bj;P1=7q>uHj=sq@LqsAok)c z3#-Y;^YOPSas;fOs$@b>bj-pt6jNIVLZSL6&>et5gbxdTl{nEIT3K=>uf4|q#Wj`t9)Hb$D`23RNA&JpkuBhs3O zK$te+|JPox=_m%|a;P?qe<6a{wSnb-dSoXXS~(DEGzyNvFieUX3;XPts}o=QSB)wV z&Fr=IP*;IS z1tkEdI5sq_Nf3@q>8k*aF&yolTB7HcaYz5_LP;n7t>E48pB&}Fd}xE561fwK2ZsZx zB_AeYa})6G^Jt(MBX%esqSIujU%Ud`h#oP%l|DXl2AnL-orzMA44LRaFMhyR+J5Ea zP3*6^?QOscRwgMA*i~XSy9QGLBxgg;8fJ@SY<-bBmww}3A5}g8R_NS{#rQ=L8dG;L zx0DRi+I6Pi`FIVNqV!2@9t6p)pT0vB@bh zIMPz~jai9-P9*Ji&`N9HTaUm+BIa)S_lzaA!;$Cd{f{Iki^3wReJI!&hI%45oLQRF z*x=P>vhCn1#)J&YL~F(I|e3+CZ5sAWX$T!q?&zM zQZWhwe$_EVTL2MTiTDV$BVYh>ttXjZ00SDwi(mRz9MyQR2yIAfoksU%WYuydNY@LE zQUQPm$9VQ|bPT$yn`;J~%HHP4IU($ax)w@gT}Ca=V}*$p7^%y1ESm<2pwlNVneTiyCgVvR<+$W_IT=4=| z_7{ywVtG&mgacRdh6O;w8=5R-^Q5LLQ17Pg%!sA%x3|?CN8dp1@)IhBeVHVCpbHQI z*dT~AQ58+iwEIf&fNEQ~<&ktn_}t0mZ?`W#h>rKZY#~%Voaqc`mx?jf+W%|~C?%?= zZ#X(t?KEO&XvM*%njh83c|@L&5lLj;9U#85Udxd!SBVz1WYXb~CXmjRYCSy!cEzKCAv8UhQZ zl#gg_nwyu#M05;p2(@b4Dxuffv&gCQj+>u|Y^!0+kMrGq^Mg(@)w>aHAb~3s9n2Aq z31~V?G9f6s&y|{kH7to$WT4T%Np_}PnYql+Q$p`BiHEzE(lAW~2Iy1a>7{Hem*kdF zXowN?Osj%3f+Eb==R0kn*E!EJ_Z3YwxJO#Xv$co#WznmjYuI)95&rCUbxQ1RSJA}O zq8_Sk#XNE2om!?3XX}UskC14&<=uG&=OpK|5Z;R~M#%NEy*7s^THJ42at_%vm<=sr z+sl->&XI{ULY%o}q|@Ap$9}#-o2VjHucS zOPotqtQ`{vcC4afg8QQT*gsaY^W~p?bN%&oaOLT`$X3c9dP5s?s}>-|`e%jXWHVpm zbn5>+Q;I@@J>&?aMc}gDHZPGr9RbyY+2pt3>l^G!MOrqFXF!8B?Vom%_xciQHMeIz zO%8baWQav9d1ct9n5AMV6pC4xw#h&A3m#SnifC5fbZWPFFE#4q=J1QX6L5f^X&NmsIfkrIPTra|L;5lwU5+wy zou|fPOy7RY#CQ<9TeHBDg3qb7QB0H9Si&7N3jpB?d5lmA#j1)fni65@BJgjmp}wGu z0y7hml5t6EXdWPNuOcWCs~05w@J(XTfS)iYg~YWuVYmG-9BkQ#%cYPGY3znE##rpVy$PWksDU0+~tav<&;m*j)5e(5%g9lgKOGN@wr-SKuXdJIHkGTRP|SuN~S8G z_IcqiKOm$Z(YUE(<(r&j%l`IRf$w5vR;_Zn6M+jYUJ;b$AVRvgjK?81ujLBm3E(fz ze7@9i`tg=*2j2YlAYVvUqyZh0!({809kIgU>$)mQiCnqxy@=-dz#xL+@SwNCP(R14 z2Sc>#a_^&SVtHCuh~Lp5CRGfjUO zpn*bj?-HBXQ(%72PX4vjZv!pcmffA{ z6*N%VnP|e?3>srhJvg4V?q$f@-b8E+yVVr_ZKv6Ligb2(3h}cm=s1HA&HSK1K{W{rAD*z+x(+S_VP2#ymF#h0 ztP-CEf_Nx{kV?*9tV>WUTCsX1aXQLp+TK zdWE0o(MA`ILDGmTujm<7b5u;l>6E%<@bzR-88DEhrgvR0;8L@3=DTLs({%c-fPa$! zkxv))oCtL=q3VxRK&sg7SbNZiLHEviawXD0DmZSra|O`|7%Y|-UG+hv;5O=3_4VV2 zc?bI0R)PG%`~s$G0}mh~%&JCtY2G9w3eqh=9d;jF2_NTg+u%F&Rfa6{$}VIuhZ<*i zvD)%a*knWXMK1_bntQAI{b{;90Gv_2@9g$DECR#5i-~ZDm4KYZvPPCAB9YEu~JxG|{XN{sQH)xy#>iEo&a3Q(D`>$$cYYn+gXU0Skly!au z=8F)gDjki8m$NL(=U|i@5ifx&Kng7fWTb@b3OtuDS=t^KXU~DBcLh=&gLhx}&zGu* zMO>mlqHgZDH!Rd@8h_lJ8)Uz~!;9H(loh8ld-RG?=(J9lP7A`K8g#%mT0>xm3+&i`!wc9G{(rZ0isieZw6 zEO$3Ap@Od}6C>}TU{XQI_!s$CU;m*1jpkkeqcD?I`TNEb{u6`Dd^bZBZL_s^k(E7? z{((N{Rxgp6tTxgt@q%youcGOI#sG79bkT}lYB{g%va~D|nHq5PR)Ap|1>;*EN#)2* zoFy$GCLg)E&W-{tgqL>x?_S6Wd$i+en-oGM3=%?M`_)$)^^)tN?Lw zoOwtK!^DQH2%DTqira{+Z--*VaNt+A9@16riE&6levwv-Sd41gc^kY6&?4E^o# zO8H>d|I7LxgL+0_uX=Sr`GRLIaEh48)g?mlr+wH*o7y)%EDr}f%vH7$ zWfZWXKy?>L0uz8(&R?PLX=-AzT)`(_bKz|?E3@lusv6uP-G28nLDKSivj>X7g@SR= z8v>dZvfu6pNcMFnJIVI4^xzoqQ(OpZCGFmqf|I&ibuoA?rHZWhbDUKbtfe}hj&^)R z(1vQ3J{ODuTXDSqH}RBGrQ7m-&cL|{sbI67+R|1B1%q-gGIDsx+asppQSrLnHCR-x zmVK#Y8ss%UwR>AxOLQSt|2%;TTEBtolh^uk9?zI|y7!Qv=8^TtH{i&K4-)lY!m*P2xHAVjQ)_z#yD zpplbBu7A>ZbR;JMuWau9kD46h$Jg}>MAiYjPPsIH5w#4UK<(Qpm_u@An8^mygSg8i z3AGypzpceMP%wRiy)jmTo+3|5QN(3=xcSm0c`MLS$jscTw~rLOY)bJA(rUNk%7BGY zJrZRi&`y*k6B`Z*UU}yBB)_(pVpR`D#51GCID;v(KpihVgIm}+NEhwlLiR{7vuNA4 zuL;%Rv2}rNKI)W6YbN2yd7ckgPq%|nHInD4j{GR@x?3Wb=Q=t6AV_J~iILmXNNy)O z5s3ggE5z_LF2X53JYbm8Zv(@+wqh0uXocP!=2R4Q zfd^=2|KW1dEsL+PDo&S#0Qhhsvkg|DCC})~&3g8S)*HS!lFbj-R+G5_+ic}`ME>1i z&h~jxP!I)}Z)zOaY2gGfK$Lrl2fHUuy*G(IQIhr1Hhr1>KewShZiJYHLHUMt*P9unH|ux$u(g;N!d@Xmq|jv>zbxI5Y73~}OBQ*F3+UWJ+af!KK⪙>ik9i}@ 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 Date: Tue, 21 Nov 2023 16:10:24 +0100 Subject: [PATCH 13/29] removed benchmark link --- README.md | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/README.md b/README.md index 05c815526..fc2d41e42 100644 --- a/README.md +++ b/README.md @@ -16,10 +16,6 @@ environmental conditions. [![CARLA Video](Docs/img/0_9_15_thumbnail.webp)](https://www.youtube.com/watch?v=q4V9GYjA1pE ) -If you want to benchmark your model in the same conditions as in our CoRL’17 -paper, check out -[Benchmarking](https://github.com/carla-simulator/driving-benchmarks). - Linux: * [**Get CARLA overnight build**](http://carla-releases.s3.amazonaws.com/Linux/Dev/CARLA_Latest.tar.gz) * [**Get AdditionalMaps overnight build**](http://carla-releases.s3.amazonaws.com/Linux/Dev/AdditionalMaps_Latest.tar.gz) @@ -36,7 +32,7 @@ Windows: * Ubuntu 20.04 ## CARLA Ecosystem -Repositories associated to the CARLA simulation platform: +Repositories associated with the CARLA simulation platform: * [**CARLA Autonomous Driving leaderboard**](https://leaderboard.carla.org/): Automatic platform to validate Autonomous Driving stacks * [**Scenario_Runner**](https://github.com/carla-simulator/scenario_runner): Engine to execute traffic scenarios in CARLA 0.9.X @@ -87,7 +83,7 @@ Also, clone the [CARLA fork of the Unreal Engine](https://github.com/CarlaUnreal git clone --depth 1 -b carla https://github.com/CarlaUnreal/UnrealEngine.git . ``` -Once you have cloned the repositories, follow the instructions for [building in Linux][buildlinuxlink] or [building in Windows][buildwindowslink]: +Once you have cloned the repositories, follow the instructions for [building in Linux][buildlinuxlink] or [building in Windows][buildwindowslink]. [buildlinuxlink]: https://carla.readthedocs.io/en/latest/build_linux/ [buildwindowslink]: https://carla.readthedocs.io/en/latest/build_windows/ From 458f6dde146280d40d62aef43b2dcf99ee51530e Mon Sep 17 00:00:00 2001 From: MattRoweEAIF Date: Tue, 21 Nov 2023 16:38:08 +0100 Subject: [PATCH 14/29] added docs key links --- README.md | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/README.md b/README.md index fc2d41e42..56bfdee11 100644 --- a/README.md +++ b/README.md @@ -31,6 +31,17 @@ Windows: * NVIDIA RTX 3070 / NVIDIA RTX 3080 / NVIDIA RTX 4090 * Ubuntu 20.04 +## Documentation + +The CARLA documentation is hosted on [ReadTheDocs](https://carla.readthedocs.io/en/latest/). Please see the following key links: + +- [Building on Linux](https://carla.readthedocs.io/en/latest/build_linux/) +- [Building on Windows](https://carla.readthedocs.io/en/latest/build_windows/) +- [First steps](https://carla.readthedocs.io/en/latest/tuto_first_steps/) +- [CARLA asset catalogue](https://carla.readthedocs.io/en/latest/catalogue/) +- [Python API reference](https://carla.readthedocs.io/en/latest/python_api/) +- [Blueprint library](https://carla.readthedocs.io/en/latest/bp_library/) + ## CARLA Ecosystem Repositories associated with the CARLA simulation platform: From f64c09e2f68b295eebec3a66a5df364192bdfa92 Mon Sep 17 00:00:00 2001 From: MattRoweEAIF Date: Tue, 21 Nov 2023 16:42:19 +0100 Subject: [PATCH 15/29] small fixes --- README.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 56bfdee11..eaad3df72 100644 --- a/README.md +++ b/README.md @@ -16,6 +16,8 @@ environmental conditions. [![CARLA Video](Docs/img/0_9_15_thumbnail.webp)](https://www.youtube.com/watch?v=q4V9GYjA1pE ) +### Download CARLA + Linux: * [**Get CARLA overnight build**](http://carla-releases.s3.amazonaws.com/Linux/Dev/CARLA_Latest.tar.gz) * [**Get AdditionalMaps overnight build**](http://carla-releases.s3.amazonaws.com/Linux/Dev/AdditionalMaps_Latest.tar.gz) @@ -33,7 +35,7 @@ Windows: ## Documentation -The CARLA documentation is hosted on [ReadTheDocs](https://carla.readthedocs.io/en/latest/). Please see the following key links: +The [CARLA documentation](https://carla.readthedocs.io/en/latest/) is hosted on ReadTheDocs. Please see the following key links: - [Building on Linux](https://carla.readthedocs.io/en/latest/build_linux/) - [Building on Windows](https://carla.readthedocs.io/en/latest/build_windows/) From 800b394d2ade9f76c191832484470ed26571e8be Mon Sep 17 00:00:00 2001 From: Bernd Gassmann Date: Thu, 16 Nov 2023 16:03:58 +0100 Subject: [PATCH 16/29] Fix build of RSS version with python 3.10 and Ubuntu 22.04 --- LibCarla/cmake/client/CMakeLists.txt | 4 ++++ PythonAPI/carla/setup.py | 3 ++- Util/BuildTools/Ad-rss.sh | 34 ++++++++++++++++++---------- Util/BuildTools/BuildLibCarla.sh | 2 +- 4 files changed, 29 insertions(+), 14 deletions(-) diff --git a/LibCarla/cmake/client/CMakeLists.txt b/LibCarla/cmake/client/CMakeLists.txt index 6c085f6b3..2aaaebfd0 100644 --- a/LibCarla/cmake/client/CMakeLists.txt +++ b/LibCarla/cmake/client/CMakeLists.txt @@ -28,6 +28,10 @@ if (BUILD_RSS_VARIANT) install(FILES ${proj_lib} DESTINATION lib) list(APPEND ADRSS_LIBS ${proj_lib}) + # as long as the libosm2dr uses the same odrSprial interface it is enough to copy the built static library + set(odr_lib ${ADRSS_INSTALL_DIR}/../src/ad-rss-lib/dependencies/map/dependencies/odrSpiral/lib/libodrSpiral.a) + install(FILES ${odr_lib} DESTINATION lib) + list(APPEND ADRSS_LIBS ${odr_lib}) foreach(ad_lib ad_physics ad_rss ad_map_access ad_map_opendrive_reader ad_rss_map_integration) set(${ad_lib}_file ${ADRSS_INSTALL_DIR}/${ad_lib}/lib/lib${ad_lib}.a) diff --git a/PythonAPI/carla/setup.py b/PythonAPI/carla/setup.py index 1f10d0d66..067e140a9 100755 --- a/PythonAPI/carla/setup.py +++ b/PythonAPI/carla/setup.py @@ -55,7 +55,7 @@ def get_libcarla_extensions(): os.path.join(pwd, 'dependencies/lib/libxerces-c.a')] extra_link_args += ['-lz'] extra_compile_args = [ - '-isystem', 'dependencies/include/system', '-fPIC', '-std=c++14', + '-isystem', os.path.join(pwd, 'dependencies/include/system'), '-fPIC', '-std=c++14', '-Werror', '-Wall', '-Wextra', '-Wpedantic', '-Wno-self-assign-overloaded', '-Wdeprecated', '-Wno-shadow', '-Wuninitialized', '-Wunreachable-code', '-Wpessimizing-move', '-Wold-style-cast', '-Wnull-dereference', @@ -77,6 +77,7 @@ def get_libcarla_extensions(): extra_link_args += [os.path.join(pwd, 'dependencies/lib/libad_physics.a')] extra_link_args += [os.path.join(pwd, 'dependencies/lib/libad_map_opendrive_reader.a')] extra_link_args += [os.path.join(pwd, 'dependencies/lib/libboost_program_options.a')] + extra_link_args += [os.path.join(pwd, 'dependencies/lib/libodrSpiral.a')] extra_link_args += [os.path.join(pwd, 'dependencies/lib/libspdlog.a')] extra_link_args += ['-lrt'] extra_link_args += ['-ltbb'] diff --git a/Util/BuildTools/Ad-rss.sh b/Util/BuildTools/Ad-rss.sh index d05f69a49..3f7c71695 100755 --- a/Util/BuildTools/Ad-rss.sh +++ b/Util/BuildTools/Ad-rss.sh @@ -29,7 +29,7 @@ IFS="," read -r -a PY_VERSION_LIST <<< "${PY_VERSION_LIST}" # -- Get ad-rss ------------------------------------------- # ============================================================================== -ADRSS_VERSION=4.5.3 +ADRSS_VERSION=4.4.4 ADRSS_BASENAME=ad-rss-${ADRSS_VERSION} ADRSS_COLCON_WORKSPACE="${CARLA_BUILD_FOLDER}/${ADRSS_BASENAME}" ADRSS_SRC_DIR="${ADRSS_COLCON_WORKSPACE}/src" @@ -46,6 +46,7 @@ if [[ ! -d "${ADRSS_SRC_DIR}" ]]; then # ADRSS_VERSION is designed for older boost, update datatype from boost::array to std::array grep -rl "boost::array" | xargs sed -i 's/boost::array/std::array/g' + grep -rl "find_package(Boost" | xargs sed -i 's/find_package(Boost/find_package(Boost 1.80/g' popd cat >"${ADRSS_COLCON_WORKSPACE}/colcon.meta" </dev/null - CMAKE_PREFIX_PATH="${CMAKE_PREFIX_PATH};${CARLA_BUILD_FOLDER}/boost-1.80.0-c$CARLA_LLVM_VERSION_MAJOR-install;${CARLA_BUILD_FOLDER}/proj-install" + if [[ "${CMAKE_PREFIX_PATH}" == "" ]]; then + CMAKE_PREFIX_PATH="${CARLA_BUILD_FOLDER}/boost-1.80.0-$CXX_TAG-install;${CARLA_BUILD_FOLDER}/proj-install" + else + CMAKE_PREFIX_PATH="${CARLA_BUILD_FOLDER}/boost-1.80.0-$CXX_TAG-install;${CARLA_BUILD_FOLDER}/proj-install;${CMAKE_PREFIX_PATH}" + fi - # get the python version of the binding to be built - PYTHON_VERSION=3 - PYTHON_BINDING_VERSIONS=${PYTHON_VERSION:8} + # get the python version of the binding to be built, need to query the binary, + # because might be just provided a '3' as PY_VERSION and then the symbolic linked python3 is called + PYTHON_VERSION=$(/usr/bin/env python${PY_VERSION} -V 2>&1) + PYTHON_BINDING_VERSIONS=${PYTHON_VERSION:7} + PYTHON_BINDING_VERSIONS=${PYTHON_BINDING_VERSIONS%.*} echo "PYTHON_BINDING_VERSIONS=${PYTHON_BINDING_VERSIONS}" # enforce sequential executor to reduce the required memory for compilation diff --git a/Util/BuildTools/BuildLibCarla.sh b/Util/BuildTools/BuildLibCarla.sh index 891d35853..c9e2f13a0 100755 --- a/Util/BuildTools/BuildLibCarla.sh +++ b/Util/BuildTools/BuildLibCarla.sh @@ -146,7 +146,7 @@ function build_libcarla { M_TOOLCHAIN=${LIBSTDCPP_TOOLCHAIN_FILE} M_BUILD_FOLDER=${LIBCARLA_BUILD_CLIENT_FOLDER}.rss.$(echo "$2" | tr '[:upper:]' '[:lower:]') M_INSTALL_FOLDER=${LIBCARLA_INSTALL_CLIENT_FOLDER} - CMAKE_EXTRA_OPTIONS="${CMAKE_EXTRA_OPTIONS:+${CMAKE_EXTRA_OPTIONS} }-DBUILD_RSS_VARIANT=ON -DADRSS_INSTALL_DIR=${CARLA_BUILD_FOLDER}/ad-rss-4.5.3/install" + CMAKE_EXTRA_OPTIONS="${CMAKE_EXTRA_OPTIONS:+${CMAKE_EXTRA_OPTIONS} }-DBUILD_RSS_VARIANT=ON -DADRSS_INSTALL_DIR=${CARLA_BUILD_FOLDER}/ad-rss-4.4.4/install" else fatal_error "Invalid build configuration \"$1\"" fi From 7003a7cfbf3045b305a163f7e9a877a0850b7a5a Mon Sep 17 00:00:00 2001 From: Bernd Gassmann Date: Mon, 20 Nov 2023 14:50:00 +0100 Subject: [PATCH 17/29] Fix RSS python code and adapt on updated synchronous mode handling --- LibCarla/source/carla/rss/RssSensor.cpp | 6 ++-- PythonAPI/examples/rss/manual_control_rss.py | 35 ++++++++++++++++---- PythonAPI/examples/rss/rss_sensor.py | 3 ++ 3 files changed, 34 insertions(+), 10 deletions(-) diff --git a/LibCarla/source/carla/rss/RssSensor.cpp b/LibCarla/source/carla/rss/RssSensor.cpp index 29fb6e164..ae19c145e 100644 --- a/LibCarla/source/carla/rss/RssSensor.cpp +++ b/LibCarla/source/carla/rss/RssSensor.cpp @@ -309,17 +309,17 @@ void RssSensor::TickRssSensor(const client::Timestamp ×tamp, CallbackFuncti auto const settings = GetWorld().GetSettings(); if ( settings.synchronous_mode ) { - _rss_check->GetLogger()->trace("RssSensor[{}] sync-tick", timestamp.frame); + _rss_check->GetLogger()->info("RssSensor[{}] sync-tick", timestamp.frame); TickRssSensorThreadLocked(timestamp, actors, callback); } else { // store the future to prevent the destructor of the future from blocked waiting - _rss_check->GetLogger()->trace("RssSensor[{}] async-tick", timestamp.frame); + _rss_check->GetLogger()->info("RssSensor[{}] async-tick", timestamp.frame); _tick_future = std::async(&RssSensor::TickRssSensorThreadLocked, this, timestamp, actors, callback); } } else { if (bool(_rss_check)){ - _rss_check->GetLogger()->debug("RssSensor[{}] tick dropped", timestamp.frame); + _rss_check->GetLogger()->info("RssSensor[{}] tick dropped", timestamp.frame); } } } diff --git a/PythonAPI/examples/rss/manual_control_rss.py b/PythonAPI/examples/rss/manual_control_rss.py index a845e6457..ff0b7e1c5 100755 --- a/PythonAPI/examples/rss/manual_control_rss.py +++ b/PythonAPI/examples/rss/manual_control_rss.py @@ -135,6 +135,7 @@ class World(object): def __init__(self, carla_world, args): self.world = carla_world + self.sync = args.sync self.actor_role_name = args.rolename self.dim = (args.width, args.height) try: @@ -161,10 +162,7 @@ class World(object): sys.exit(1) self.restart() - self.world_tick_id = self.world.on_tick(self.on_world_tick) - - def on_world_tick(self, world_snapshot): - self.hud.on_world_tick(world_snapshot) + self.world_tick_id = self.world.on_tick(self.hud.on_world_tick) def toggle_pause(self): settings = self.world.get_settings() @@ -235,6 +233,11 @@ class World(object): self.rss_sensor = RssSensor(self.player, self.world, self.rss_unstructured_scene_visualizer, self.rss_bounding_box_visualizer, self.hud.rss_state_visualizer) + if self.sync: + self.world.tick() + else: + self.world.wait_for_tick() + def tick(self, clock): self.hud.tick(self.player, clock) @@ -384,7 +387,7 @@ class VehicleControl(object): print('\nReceived signal {}. Trigger stopping...'.format(signum)) VehicleControl.signal_received = True - def parse_events(self, world, clock): + def parse_events(self, world, clock, sync_mode): if VehicleControl.signal_received: print('\nAccepted signal. Stopping loop...') return True @@ -806,13 +809,27 @@ def game_loop(args): (args.width, args.height), pygame.HWSURFACE | pygame.DOUBLEBUF) - world = World(client.get_world(), args) + sim_world = client.get_world() + original_settings = sim_world.get_settings() + settings = sim_world.get_settings() + if args.sync != settings.synchronous_mode: + args.sync = True + settings.synchronous_mode = True + settings.fixed_delta_seconds = 0.05 + sim_world.apply_settings(settings) + + traffic_manager = client.get_trafficmanager() + traffic_manager.set_synchronous_mode(True) + + world = World(sim_world, args) controller = VehicleControl(world, args.autopilot) clock = pygame.time.Clock() while True: + if args.sync: + sim_world.tick() clock.tick_busy_loop(60) - if controller.parse_events(world, clock): + if controller.parse_events(world, clock, args.sync): return world.tick(clock) world.render(display) @@ -875,6 +892,10 @@ def main(): '--externalActor', action='store_true', help='attaches to externally created actor by role name') + argparser.add_argument( + '--sync', + action='store_true', + help='Activate synchronous mode execution') args = argparser.parse_args() args.width, args.height = [int(x) for x in args.res.split('x')] diff --git a/PythonAPI/examples/rss/rss_sensor.py b/PythonAPI/examples/rss/rss_sensor.py index 68f1938dd..022660718 100644 --- a/PythonAPI/examples/rss/rss_sensor.py +++ b/PythonAPI/examples/rss/rss_sensor.py @@ -334,6 +334,9 @@ class RssSensor(object): self.map_log_level = self.map_log_level-1 self.sensor.set_map_log_level(self.map_log_level) + def drop_route(self): + self.sensor.drop_route() + @staticmethod def get_default_parameters(): ego_dynamics = ad.rss.world.RssDynamics() From 6489eafa4cf9bf8183c09c184869d4fe196de662 Mon Sep 17 00:00:00 2001 From: Bernd Gassmann Date: Tue, 21 Nov 2023 08:45:49 +0100 Subject: [PATCH 18/29] Fix typo in comment --- LibCarla/cmake/client/CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/LibCarla/cmake/client/CMakeLists.txt b/LibCarla/cmake/client/CMakeLists.txt index 2aaaebfd0..20438ad3e 100644 --- a/LibCarla/cmake/client/CMakeLists.txt +++ b/LibCarla/cmake/client/CMakeLists.txt @@ -28,7 +28,7 @@ if (BUILD_RSS_VARIANT) install(FILES ${proj_lib} DESTINATION lib) list(APPEND ADRSS_LIBS ${proj_lib}) - # as long as the libosm2dr uses the same odrSprial interface it is enough to copy the built static library + # as long as the libosm2odr uses the same odrSprial interface it is enough to copy the built static library set(odr_lib ${ADRSS_INSTALL_DIR}/../src/ad-rss-lib/dependencies/map/dependencies/odrSpiral/lib/libodrSpiral.a) install(FILES ${odr_lib} DESTINATION lib) list(APPEND ADRSS_LIBS ${odr_lib}) From dd64af486a820b1d79eef6adc11e6a303c95fa77 Mon Sep 17 00:00:00 2001 From: MattRoweEAIF <125647690+MattRoweEAIF@users.noreply.github.com> Date: Fri, 24 Nov 2023 08:35:01 +0100 Subject: [PATCH 19/29] embedded OASIS demo video (#6944) Co-authored-by: Blyron <53337103+Blyron@users.noreply.github.com> --- Docs/ecosys_synkrotron.md | 26 ++++++++++++++++++-------- 1 file changed, 18 insertions(+), 8 deletions(-) diff --git a/Docs/ecosys_synkrotron.md b/Docs/ecosys_synkrotron.md index 81584c78d..703dc99a0 100644 --- a/Docs/ecosys_synkrotron.md +++ b/Docs/ecosys_synkrotron.md @@ -2,25 +2,36 @@ # Synkrotron simulation solutions -Synkrotron provides advanced solutions for autonomous driving simulation built on top of CARLA. Its product suite Oasis supports ​a broad range of applications including scenario generation, sensor modelling, ​traffic simulation and data management. Based on a flexible architecture Oasis ​can be deployed on the cloud at scale, or in a developer's local environment for prototyping. +Synkrotron provides advanced solutions for autonomous driving simulation built on top of CARLA. Synkrotron's product suite OASIS supports ​a broad range of applications including scenario generation, sensor modelling, ​traffic simulation and data management. Based on a flexible architecture OASIS ​can be deployed on the cloud at scale, or in a developer's local environment for prototyping. --- -# __OASIS platform__ - “synkrotron_logo” +

+ +
+ ## [__OASIS simulation platform__](https://www.synkrotron.ai/sim.html) -Oasis Sim is a full-fledged scalable simulation platform with CARLA at its core. It supports the complete life-cycle of AD simulation: scenario import & editing with a graphical user interface, sensor configuration, distributed task management as well as diagnosis through rich simulation data and logs. Both cloud and local deployment are available through containerized ​packaging. Comprehensive APIs are exposed for integration with DevOps too. You can [request a trial](https://synkrotron.ai/contact.html) from Synkrotron. +OASIS Sim is a fully-fledged, scalable simulation platform with CARLA at its core. It supports the complete life-cycle of AD simulation: + +- scenario import & editing with a graphical user interface +- sensor configuration +- distributed task management +- diagnosis through rich simulation data and logs + +Both cloud and local deployment are available through containerized ​packaging. Comprehensive APIs are exposed for integration with DevOps too. You can [request a trial](https://synkrotron.ai/contact.html) from Synkrotron. ## [__OASIS data platform__](https://www.synkrotron.ai/data.html) -Oasis Data is a platform for managing the high volume of data flowing through the autonomous driving R&D pipeline. Data-driven development of AD systems are made possible with Oasis Data via the following functionalities,: +OASIS Data is a platform for managing the high volume of data flowing through the autonomous driving R&D pipeline. Data-driven development of AD systems are made possible with OASIS Data via the following functionalities: * data acquisition and anonymization -* multi-stage filtering based on structured (CAN bus signals, active-safety triggering, etc.) and unstructured (sensor readings) -* information mapping and environment reconstruction with lidar and/or vision-only strategy +* multi-stage filtering based on structured data (CAN bus signals, active-safety triggering, etc.) and unstructured data (sensor readings) +* information mapping and environment reconstruction with LIDAR and/or vision-only strategy * auto-labeling of data with pre-trained perception models * scenario tagging and reconstruction with OpenX format output @@ -43,4 +54,3 @@ In addition to the complete solutions introduced above, Synkrotron also offers t - From 9490ec085dd048a6a7407fa0ec9a693f24983a87 Mon Sep 17 00:00:00 2001 From: berndgassmann Date: Mon, 27 Nov 2023 16:18:46 +0100 Subject: [PATCH 20/29] Prevent from segfault on missing SignalReference when loading OpenDrive (#6934) * Prevent from segfault on missing SignalReference when loading OpenDrive Prevent from segfault on failing SignalReference identification when loading OpenDrive files Since boost is compiled without exceptions in CARLA there is no meaningful error handling for boost optional via exceptions. Therefore, a validity check has to be introduced to react on potential issues. * Update changelog --------- Co-authored-by: Blyron <53337103+Blyron@users.noreply.github.com> --- CHANGELOG.md | 4 ++-- .../Source/Carla/Traffic/YieldSignComponent.cpp | 12 ++++++++---- 2 files changed, 10 insertions(+), 6 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 56073502d..a361dd37a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,5 @@ -## Latest - +## Latest Changes + * Prevent from segfault on failing SignalReference identification when loading OpenDrive files * Added vehicle doors to the recorder ## CARLA 0.9.15 diff --git a/Unreal/CarlaUE4/Plugins/Carla/Source/Carla/Traffic/YieldSignComponent.cpp b/Unreal/CarlaUE4/Plugins/Carla/Source/Carla/Traffic/YieldSignComponent.cpp index 9fc0e3dcf..8e660919a 100644 --- a/Unreal/CarlaUE4/Plugins/Carla/Source/Carla/Traffic/YieldSignComponent.cpp +++ b/Unreal/CarlaUE4/Plugins/Carla/Source/Carla/Traffic/YieldSignComponent.cpp @@ -36,11 +36,15 @@ void UYieldSignComponent::InitializeSign(const carla::road::Map &Map) if(lane == 0) continue; - auto signal_waypoint = Map.GetWaypoint( - RoadId, lane, SignalReference->GetS()).get(); - - if(Map.GetLane(signal_waypoint).GetType() != cr::Lane::LaneType::Driving) + auto signal_waypoint_optional = Map.GetWaypoint(RoadId, lane, SignalReference->GetS()); + if (!signal_waypoint_optional) { + carla::log_warning("YieldSignComponent::InitializeSignsignal() waypoint seems to be invalid, ignoring. RoadId:", RoadId, " LaneId:", lane, " s:", SignalReference->GetS()); + continue; + } + auto signal_waypoint = signal_waypoint_optional.value(); + if(Map.GetLane(signal_waypoint).GetType() != cr::Lane::LaneType::Driving) { continue; + } auto box_waypoint = signal_waypoint; // Prevent adding the bounding box inside the intersection From 48fa35f1da452f09ac9d74fbe268356521fbaf0f Mon Sep 17 00:00:00 2001 From: MattRoweEAIF Date: Tue, 28 Nov 2023 10:48:09 +0100 Subject: [PATCH 21/29] english demo video update --- Docs/ecosys_synkrotron.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Docs/ecosys_synkrotron.md b/Docs/ecosys_synkrotron.md index 703dc99a0..a147cab54 100644 --- a/Docs/ecosys_synkrotron.md +++ b/Docs/ecosys_synkrotron.md @@ -9,7 +9,7 @@ Synkrotron provides advanced solutions for autonomous driving simulation built “synkrotron_logo”
- +

From 7e69258e2dd202a0af2cfb8b17ca9b77615d29f4 Mon Sep 17 00:00:00 2001 From: Blyron <53337103+Blyron@users.noreply.github.com> Date: Wed, 13 Dec 2023 08:00:20 +0100 Subject: [PATCH 22/29] Aaron/updateurls (#6994) * Set commit for download libsomscout * Update urls to new storage * Merge dev into current branch --- Docs/build_update.md | 76 ++++++++++----------- Docs/download.md | 8 +-- Docs/tuto_content_authoring_vehicles.md | 88 ++++++++++++------------- Docs/tutorials.md | 50 +++++++------- README.md | 12 ++-- Update.bat | 2 +- Update.sh | 2 +- Util/BuildTools/Setup.bat | 2 +- Util/BuildTools/Setup.sh | 4 +- Util/ContentVersions.txt | 2 +- Util/CreateDebian.sh | 4 +- Util/InstallersWin/install_boost.bat | 2 +- Util/InstallersWin/install_libpng.bat | 2 +- Util/InstallersWin/install_xercesc.bat | 6 +- Util/InstallersWin/install_zlib.bat | 2 +- 15 files changed, 131 insertions(+), 131 deletions(-) diff --git a/Docs/build_update.md b/Docs/build_update.md index eb5432934..f3f7eff8f 100644 --- a/Docs/build_update.md +++ b/Docs/build_update.md @@ -1,13 +1,13 @@ # Update CARLA -* [__Update commands summary__](#update-commands-summary) -* [__Get the lastest binary release__](#get-latest-binary-release) -* [__Update Linux and Windows build__](#update-linux-and-windows-build) - * [Clean the build](#clean-the-build) - * [Pull from origin](#pull-from-origin) - * [Download the assets](#download-the-assets) - * [Launch the server](#launch-the-server) -* [__Get development assets__](#get-development-assets) +* [__Update commands summary__](#update-commands-summary) +* [__Get the lastest binary release__](#get-latest-binary-release) +* [__Update Linux and Windows build__](#update-linux-and-windows-build) + * [Clean the build](#clean-the-build) + * [Pull from origin](#pull-from-origin) + * [Download the assets](#download-the-assets) + * [Launch the server](#launch-the-server) +* [__Get development assets__](#get-development-assets) To post unexpected issues, doubts or suggestions, feel free to login in the CARLA forum. @@ -25,30 +25,30 @@ CARLA forum
Show command lines to update CARLA ```sh -# Update a CARLA packaged release. -# 1. Delete the current one. -# 2. Follow the Quick start installation to get the one desired. +# Update a CARLA packaged release. +# 1. Delete the current one. +# 2. Follow the Quick start installation to get the one desired. -# Update Linux build. +# Update Linux build. git checkout master make clean git pull origin master ./Update.sh -# Update Windows build. +# Update Windows build. git checkout master make clean git pull origin master # Erase the content in `Unreal\CarlaUE4\Content\Carla`. # Go to `\Util\ContentVersions.txt`. # Download the latest content. -# Extract the new content in `Unreal\CarlaUE4\Content\Carla`. +# Extract the new content in `Unreal\CarlaUE4\Content\Carla`. -# Get development assets. -# Delete the `/Carla` folder containing previous assets. +# Get development assets. +# Delete the `/Carla` folder containing previous assets. # Go to the main carla folder. git clone https://bitbucket.org/carla-simulator/carla-content Unreal/CarlaUE4/Content/Carla @@ -56,11 +56,11 @@ git clone https://bitbucket.org/carla-simulator/carla-content Unreal/CarlaUE4/Co --- -## Get latest binary release +## Get latest binary release -Binary releases are prepackaged and thus, tied to a specific version of CARLA. To get the latest, erase the previous and follow the [quick start installation](start_quickstart.md) to get the one desired. +Binary releases are prepackaged and thus, tied to a specific version of CARLA. To get the latest, erase the previous and follow the [quick start installation](start_quickstart.md) to get the one desired. -Releases are listed in __Development__ in the CARLA repository. There is also a highly experimental __Nightly build__ containing the current state of CARLA up to date. +Releases are listed in __Development__ in the CARLA repository. There is also a highly experimental __Nightly build__ containing the current state of CARLA up to date.

@@ -69,22 +69,22 @@ Releases are listed in __Development__ in the CARLA repository. There is also a

- + Get the linux nightly build

- + Get the linux nightly build additional maps

- + Get the windows nightly build

- + Get the windows nightly build additional maps

@@ -93,22 +93,22 @@ Releases are listed in __Development__ in the CARLA repository. There is also a --- ## Update Linux and Windows build -Make sure to be in the local `master` branch before the update. Then, merge or rebase the changes to other branches and solve possible conflicts. +Make sure to be in the local `master` branch before the update. Then, merge or rebase the changes to other branches and solve possible conflicts. -```sh +```sh git checkout master ``` ### Clean the build Go to the main CARLA folder and delete binaries and temporals generated by the previous build. -```sh +```sh make clean ``` ### Pull from origin -Get the current version from `master` in the CARLA repository. +Get the current version from `master` in the CARLA repository. ```sh git pull origin master ``` @@ -120,19 +120,19 @@ __Linux.__ ./Update.sh ``` -__Windows.__ +__Windows.__ -__1.__ Erase the previous content in `Unreal\CarlaUE4\Content\Carla`. -__2.__ Go to `\Util\ContentVersions.txt`. -__3.__ Download the content for `latest`. -__4.__ Extract the new content in `Unreal\CarlaUE4\Content\Carla`. +__1.__ Erase the previous content in `Unreal\CarlaUE4\Content\Carla`. +__2.__ Go to `\Util\ContentVersions.txt`. +__3.__ Download the content for `latest`. +__4.__ Extract the new content in `Unreal\CarlaUE4\Content\Carla`. !!! Note - In order to work with that the CARLA team is devleoping, go to __get development assets__ below. + In order to work with that the CARLA team is devleoping, go to __get development assets__ below. ### Launch the server -Run the server in spectator view to make sure that everything worked properly. +Run the server in spectator view to make sure that everything worked properly. ```sh make launch @@ -141,18 +141,18 @@ make launch --- ## Get development assets -The CARLA team works with assets still in development. These models and maps have a [public git repository][contentrepolink] where the CARLA team regularly pushes latest updates. Assets are still unfinished, using them is only recommended for developers. +The CARLA team works with assets still in development. These models and maps have a [public git repository][contentrepolink] where the CARLA team regularly pushes latest updates. Assets are still unfinished, using them is only recommended for developers. -In order to handle this repository it is advisted to install [git-lfs][gitlfslink]. The repository is modified regularly, and git-lfs works faster with large binary files. +In order to handle this repository it is advisted to install [git-lfs][gitlfslink]. The repository is modified regularly, and git-lfs works faster with large binary files. -To clone the repository, __go to the main CARLA directory__ and run the following command. +To clone the repository, __go to the main CARLA directory__ and run the following command. ```sh git clone https://bitbucket.org/carla-simulator/carla-content Unreal/CarlaUE4/Content/Carla ``` !!! Warning - Delete the `/Carla` folder containing the assets before cloning the repository. Otherwise, an error will show. + Delete the `/Carla` folder containing the assets before cloning the repository. Otherwise, an error will show. [contentrepolink]: https://bitbucket.org/carla-simulator/carla-content [gitlfslink]: https://github.com/git-lfs/git-lfs/wiki/Installation diff --git a/Docs/download.md b/Docs/download.md index 28583453b..e90c845c8 100644 --- a/Docs/download.md +++ b/Docs/download.md @@ -10,10 +10,10 @@ > branch. It contains the very latest fixes and features that will be part of the > next release, but also some experimental changes. Use at your own risk! -- [CARLA Nightly Build (Linux)](https://carla-releases.s3.eu-west-3.amazonaws.com/Linux/Dev/CARLA_Latest.tar.gz) -- [AdditionalMaps Nightly Build (Linux)](https://carla-releases.s3.eu-west-3.amazonaws.com/Linux/Dev/AdditionalMaps_Latest.tar.gz) -- [CARLA Nightly Build (Windows)](https://carla-releases.s3.eu-west-3.amazonaws.com/Windows/Dev/CARLA_Latest.zip) -- [AdditionalMaps Nightly Build (Windows)](https://carla-releases.s3.eu-west-3.amazonaws.com/Windows/Dev/AdditionalMaps_Latest.zip) +- [CARLA Nightly Build (Linux)](https://carla-releases.s3.us-east-005.backblazeb2.com/Linux/Dev/CARLA_Latest.tar.gz) +- [AdditionalMaps Nightly Build (Linux)](https://carla-releases.s3.us-east-005.backblazeb2.com/Linux/Dev/AdditionalMaps_Latest.tar.gz) +- [CARLA Nightly Build (Windows)](https://carla-releases.s3.us-east-005.backblazeb2.com/Windows/Dev/CARLA_Latest.zip) +- [AdditionalMaps Nightly Build (Windows)](https://carla-releases.s3.us-east-005.backblazeb2.com/Windows/Dev/AdditionalMaps_Latest.zip) ### Versions 0.9.x diff --git a/Docs/tuto_content_authoring_vehicles.md b/Docs/tuto_content_authoring_vehicles.md index abd54abc9..764a6179c 100644 --- a/Docs/tuto_content_authoring_vehicles.md +++ b/Docs/tuto_content_authoring_vehicles.md @@ -1,36 +1,36 @@ # Content authoring - vehicles -CARLA provides a comprehensive set of vehicles out of the box in the blueprint library. CARLA allows the user to expand upon this with custom vehicles for maximum extensibility. +CARLA provides a comprehensive set of vehicles out of the box in the blueprint library. CARLA allows the user to expand upon this with custom vehicles for maximum extensibility. 3D modelling of detailed vehicles is highly complex and requires a significant degree of skill. We therefore refer the reader to alternative sources of documentation on 3D modelling, since this is beyond the scope of this guide. There are, however, numerous sources of vehicle models in both free and proprietary online repositories. Hence the user has many options to turn to for creating custom vehicles for use in CARLA. The key factors in preparing a custom vehicle for CARLA lie in rigging the vehicle armature and then importing into the Unreal Engine. After rigging and importing, blueprints need to be set for the car and the wheels. Then apply materials and add the glass parts of the vehicle. We will cover these steps in the following guide. -* __[Modeling](#modeling)__ - * [Naming conventions](#naming-conventions) -* __[Rigging](#rigging-the-vehicle-using-an-armature)__ - * [Import](#import) +* __[Modeling](#modeling)__ + * [Naming conventions](#naming-conventions) +* __[Rigging](#rigging-the-vehicle-using-an-armature)__ + * [Import](#import) * [Armature](#add-an-armature) * [Parenting](#parenting) - * [Assignment](#assigning-car-parts-to-bones) + * [Assignment](#assigning-car-parts-to-bones) * [Blender add-on](#blender-ue4-vehicle-rigging-add-on) - * [Export](#export) -* __[Import into Unreal Engine](#importing-into-unreal-engine)__ - * [Physics asset](#setting-the-physics-asset) + * [Export](#export) +* __[Import into Unreal Engine](#importing-into-unreal-engine)__ + * [Physics asset](#setting-the-physics-asset) * [Animation](#creating-the-animation) * [Blueprint](#creating-the-blueprint) -* __[Materials](#materials)__ +* __[Materials](#materials)__ * [Applying materials](#applying-a-material-to-your-vehicle) * [Color](#color) * [Clear coat](#clear-coat) * [Orange peel](#orange-peel) * [Flakes](#flakes) * [Dust](#dust) -* __[Glass](#glass)__ +* __[Glass](#glass)__ * [Glass meshes](#glass-meshes) * [Glass material](#glass-material) * [Single layer glass](#single-layer-glass) -* __[Wheels](#wheels)__ +* __[Wheels](#wheels)__ * [Wheel blueprint](#wheel-blueprint) * [Collision mesh](#collision-mesh) * [Tire configuration](#tire-configuration) @@ -41,7 +41,7 @@ The key factors in preparing a custom vehicle for CARLA lie in rigging the vehic ## Modeling -Vehicles should have between 50,000 and 100,000 faces. We recommend triangulating the model prior to export as best practice. CARLA vehicles are modeled using the size and scale of actual cars as reference. Please ensure you pay careful attention to the units of your 3D application. Some work in centimeters while others work in meters. +Vehicles should have between 50,000 and 100,000 faces. We recommend triangulating the model prior to export as best practice. CARLA vehicles are modeled using the size and scale of actual cars as reference. Please ensure you pay careful attention to the units of your 3D application. Some work in centimeters while others work in meters. ### Naming conventions @@ -53,7 +53,7 @@ For ease and consistency we recommend that you divide the vehicle into the follo - __Lights__: Headlights, indicator lights, etc. - __LightGlass_Ext__: A layer of glass that allows visibility from the outside to the inside of the light. - __LightGlass_Int__: A layer of glass that allows visibility from the inside to the outside of the light. -- __LicensePlate__: A rectangular plane of 29x12 cm. You can use the CARLA provided `.fbx` for best results, download it [here](https://carla-assets.s3.eu-west-3.amazonaws.com/fbx/LicensePlate.rar). The texture will be assigned automatically in Unreal Engine. +- __LicensePlate__: A rectangular plane of 29x12 cm. You can use the CARLA provided `.fbx` for best results, download it [here](https://carla-assets.s3.us-east-005.backblazeb2.com/fbx/LicensePlate.rar). The texture will be assigned automatically in Unreal Engine. - __Interior__: Any other details that don't fit in the above sections can go into _Interior_. Materials should be named using the format `M_CarPart_CarName`, e.g, `M_Bodywork_Mustang`. @@ -62,11 +62,11 @@ Textures should be named using the format `T_CarPart_CarName`, e.g, `T_Bodywork_ ## Rigging the vehicle using an armature -To look realistic within the simulation, the car needs to have rotating and wheels, the front pair of which can turn with steering inputs. Therefore to prepare a vehicle for CARLA, an armature needs to be rigged to the car to identify the wheels and allow their movement. +To look realistic within the simulation, the car needs to have rotating and wheels, the front pair of which can turn with steering inputs. Therefore to prepare a vehicle for CARLA, an armature needs to be rigged to the car to identify the wheels and allow their movement. -### Import +### Import -Import or model the vehicle model mesh in your 3D modelling application. In this guide we will use Blender 3D. Ensure that the wheels are separable from the main body. Each wheel must be accessible as a distinct object. +Import or model the vehicle model mesh in your 3D modelling application. In this guide we will use Blender 3D. Ensure that the wheels are separable from the main body. Each wheel must be accessible as a distinct object. ![model_in_blender](img/tuto_content_authoring_vehicles/import_model_blender.png) @@ -74,23 +74,23 @@ It is important to ensure that the vehicle faces in the positive X direction, so ### Add an armature -Now add an armature to the center of the vehicle, ensure the object is properly centered, the root of the armature bone should be set at the origin. Switch to edit mode and rotate the armature 90 around the x axis. +Now add an armature to the center of the vehicle, ensure the object is properly centered, the root of the armature bone should be set at the origin. Switch to edit mode and rotate the armature 90 around the x axis. ![armature_init](img/tuto_content_authoring_vehicles/vehicle_base_bone.png) -Now select the armature and add 4 more bones. Each of these bones needs to be located such that the root of the bone coincides with the centre of the each wheel. This can be achieved by locating the 3D cursor at the center of each wheel in edit mode. Select one of the wheels in object mode, select a vertex, press A to select all vertices then `Shift+S` and select `Cursor to selected`. This will locate the cursor in the center of the wheel. Then, in object mode, select the armature, switch to edit mode, select a bone and choose `Selection to cursor`. Your bone will now coincide with the wheel. Rotate each bone such that it lines up with the base of the armature. +Now select the armature and add 4 more bones. Each of these bones needs to be located such that the root of the bone coincides with the centre of the each wheel. This can be achieved by locating the 3D cursor at the center of each wheel in edit mode. Select one of the wheels in object mode, select a vertex, press A to select all vertices then `Shift+S` and select `Cursor to selected`. This will locate the cursor in the center of the wheel. Then, in object mode, select the armature, switch to edit mode, select a bone and choose `Selection to cursor`. Your bone will now coincide with the wheel. Rotate each bone such that it lines up with the base of the armature. -For each wheel, it is recommended to name the bone according to the wheel it needs to be coupled to, this will help in identification later when you need to assign vertex groups to each bone. +For each wheel, it is recommended to name the bone according to the wheel it needs to be coupled to, this will help in identification later when you need to assign vertex groups to each bone. ![armature_full](img/tuto_content_authoring_vehicles/all_vehicle_bones.png) -### Parenting +### Parenting -Now select all the parts of the body and all 4 wheels using shift or control in the project outliner, then control select the armature you have created (this order is important, it won't work if you select these in reverse order). Press `Ctrl+p` and select `With empty groups` to bind the mesh to the armature. +Now select all the parts of the body and all 4 wheels using shift or control in the project outliner, then control select the armature you have created (this order is important, it won't work if you select these in reverse order). Press `Ctrl+p` and select `With empty groups` to bind the mesh to the armature. ![bind_armature](img/tuto_content_authoring_vehicles/bind_armature.gif) -Now you have parented the mesh to the armature, you now need to assign each wheel to its respective bone. Select a wheel either in the outliner or the editor. Switch to edit mode, and select all the vertices of the wheel (shortcut - `a`). +Now you have parented the mesh to the armature, you now need to assign each wheel to its respective bone. Select a wheel either in the outliner or the editor. Switch to edit mode, and select all the vertices of the wheel (shortcut - `a`). ### Assigning car parts to bones @@ -108,9 +108,9 @@ There is a very useful add on for blender for rigging a vehicle for import into ### Export -Now we will export our rigged model into FBX format for import into Unreal Engine. Select `Export > FBX (.fbx)` from the File menu. In the `Object Types` section of the `Include` panel, shift select the `Armature` and `Mesh` options. +Now we will export our rigged model into FBX format for import into Unreal Engine. Select `Export > FBX (.fbx)` from the File menu. In the `Object Types` section of the `Include` panel, shift select the `Armature` and `Mesh` options. -In the `Transform` panel. Change `Forward` to `X Forward` and change `Up` to `Z Up`. This is important to ensure the vehicle is oriented correctly in the Unreal Engine. +In the `Transform` panel. Change `Forward` to `X Forward` and change `Up` to `Z Up`. This is important to ensure the vehicle is oriented correctly in the Unreal Engine. In the `Armature` section uncheck `Add Leaf Bones` and uncheck `Bake Animation`. @@ -118,7 +118,7 @@ In the `Armature` section uncheck `Add Leaf Bones` and uncheck `Bake Animation`. ## Importing into unreal engine -Launch the Unreal Editor with the `make launch` command from the CARLA root directory (the one where you have built CARLA from source). Open a content browser, set up an appropriate directory and right click and select `Import to ....`. Choose the FBX file that you previously exported from Blender (or another 3D modelling application). Import with default settings. +Launch the Unreal Editor with the `make launch` command from the CARLA root directory (the one where you have built CARLA from source). Open a content browser, set up an appropriate directory and right click and select `Import to ....`. Choose the FBX file that you previously exported from Blender (or another 3D modelling application). Import with default settings. ### Setting the physics asset @@ -130,7 +130,7 @@ First, select the main body, in the `Details` menu on the right, change the `Lin ![physics_details](img/tuto_content_authoring_vehicles/physics_details.png) -Now select all the wheels (in the `Skeleton Tree` section on the left). +Now select all the wheels (in the `Skeleton Tree` section on the left). ![regenerate_wheels](img/tuto_content_authoring_vehicles/wheels_asset.png) @@ -170,7 +170,7 @@ Select the `Vehicles` node and expand the `Vehicles` item in the `Default value` ![vehicle_factory](img/tuto_content_authoring_vehicles/vehicle_factory_page.png) -Press the plus icon to add your new vehicle. Scroll down to the last entry and expand it, it should be empty. Name the make and model of your vehicle and under the class section find your blueprint class that you created in the previous section. Leave the number of wheels as 4 and put the generation as 2. Compile and save. Do a global save for safety and you are now..ready to run your vehicle in a simulation. +Press the plus icon to add your new vehicle. Scroll down to the last entry and expand it, it should be empty. Name the make and model of your vehicle and under the class section find your blueprint class that you created in the previous section. Leave the number of wheels as 4 and put the generation as 2. Compile and save. Do a global save for safety and you are now..ready to run your vehicle in a simulation. Press play in the unreal toolbar to run the simulation. Once it is running, open a terminal and run the `manual_control.py` script with the filter option to specify your new vehicle model: @@ -185,13 +185,13 @@ As it is, the vehicle currently has no textures or colors applied. The next step Once you have your vehicle imported as a basic asset with the mesh and blueprints laid out, you now want to add materials to your vehicle to facilitate photorealistic rendering in the Unreal Engine, for maximum fidelity in your machine learning training data. -The Unreal Editor boasts a comprehensive materials workflow that facilitates the creation of highly realistic materials. This does, however, add a significant degree of complexity to the process. For this reason, CARLA is provided with a large library of material prototypes for you to use without having to start from scratch. +The Unreal Editor boasts a comprehensive materials workflow that facilitates the creation of highly realistic materials. This does, however, add a significant degree of complexity to the process. For this reason, CARLA is provided with a large library of material prototypes for you to use without having to start from scratch. ### Applying a material to your vehicle CARLA provides a prototype material for replicating the glossy finish of vehicles that can mimic numerous different types of vehicle paint jobs and features. Open Unreal editor and in the content browser, locate the material in `Content > Carla > Static > GenericMaterials > 00_MastersOpt`. The basic material is called `M_CarPaint_Master`. Right click on this material and choose `Create Material Instance` from the context material. Name it and move it into the folder where your new vehicle content is stored. -In the Unreal Editor, move the spectator to a point near the floor and drag the skeletal mesh of the vehicle from the content browser into the scene, the body of your vehicle will now appear there. +In the Unreal Editor, move the spectator to a point near the floor and drag the skeletal mesh of the vehicle from the content browser into the scene, the body of your vehicle will now appear there. ![add_model](img/tuto_content_authoring_vehicles/add_model.gif) @@ -207,7 +207,7 @@ The color settings govern the overall color of the car. The base color is simply ![change_base_color](img/tuto_content_authoring_vehicles/change_base_color.gif) -#### __Clear coat__ +#### __Clear coat__ The clear coat settings govern the appearance of the finish and how it reacts to light. The roughness uses a texture to apply imperfections to the vehicle surface, scattering light more with higher values to create a matte look. Subtle adjustments and low values are recommended for a realistic look. Generally, car paint jobs are smooth and reflective, however, this effect might be used more generously to model specialist matte finishes of custom paint jobs. @@ -215,7 +215,7 @@ The clear coat settings govern the appearance of the finish and how it reacts to An important parameter to govern the "shininess" or "glossiness" of your car is the `Clear Coat Intensity`. High values close to 1 will make the coat shiny and glossy. -#### __Orange peel__ +#### __Orange peel__ Finishes on real cars (particularly on mass produced cars for the general market) tend to have imperfections that appear as slight ripples in the paint. The orange peel effect mimics this and makes cars look more realistic. @@ -223,13 +223,13 @@ Finishes on real cars (particularly on mass produced cars for the general market #### __Flakes__ -Some cars have paint jobs that include flakes of other material, such as metals or ceramics, to give the car a `metallic` or `pearlescant` appearance, adding extra glints and reflections that react in an attractive way to light. The flakes parameters allows CARLA to mimic this. To mimic metallic finishes, it would be +Some cars have paint jobs that include flakes of other material, such as metals or ceramics, to give the car a `metallic` or `pearlescant` appearance, adding extra glints and reflections that react in an attractive way to light. The flakes parameters allows CARLA to mimic this. To mimic metallic finishes, it would be ![flakes](img/tuto_content_authoring_vehicles/flakes.gif) #### __Dust__ -Cars often accumulate grease and dust on the body that adds additional texture to the paint, affecting the way it reflects the light. The dust parameters allow you to add patches of disruption to the coat to mimic foreign materials sticking to the paint. +Cars often accumulate grease and dust on the body that adds additional texture to the paint, affecting the way it reflects the light. The dust parameters allow you to add patches of disruption to the coat to mimic foreign materials sticking to the paint. ![dust](img/tuto_content_authoring_vehicles/change_dust.gif) @@ -245,15 +245,15 @@ Here we see the glass parts attached to the main bodywork (not the doors or othe ![main_glass](img/tuto_content_authoring_vehicles/glass.png) -If we separate the constituent mesh parts, we can see that the glass profile is separated into 4 different layers. +If we separate the constituent mesh parts, we can see that the glass profile is separated into 4 different layers. ![main_glass_expanded](img/tuto_content_authoring_vehicles/glass_expanded.png) -The 4 layers are separated into 2 groups, the exterior layers, with normals facing out of the vehicle and the interior layers, with mesh normals facing into the vehicle interior. The following diagram demonstrates +The 4 layers are separated into 2 groups, the exterior layers, with normals facing out of the vehicle and the interior layers, with mesh normals facing into the vehicle interior. The following diagram demonstrates ![glass_layers](img/tuto_content_authoring_vehicles/glass_layers.png) -Once you have created your mesh layers, import them in the content browser into the Unreal Editor in the folder where you have stored your vehicle. +Once you have created your mesh layers, import them in the content browser into the Unreal Editor in the folder where you have stored your vehicle. Shift select the 4 glass layers and drag them into the map so you can see them. @@ -288,7 +288,7 @@ For the wheels of CARLA vehicles, we need to set up a blueprint class for each w ### Wheel blueprint -Inside the folder where you have your new vehicle, right click and choose to create a new blueprint class. Search for +Inside the folder where you have your new vehicle, right click and choose to create a new blueprint class. Search for ![wheel_blueprint](img/tuto_content_authoring_vehicles/wheel_blueprint.png) @@ -298,12 +298,12 @@ Double click on the blueprint to adjust it: ### Collision mesh -Firstly, the default cylinder used for the collision mesh has a high polygon count, so we should replace this with a low polygon version. In the content browser locate the `CollisionWheel` mesh inside `Content > Carla > Blueprints > Vehicles`. Drag it onto the +Firstly, the default cylinder used for the collision mesh has a high polygon count, so we should replace this with a low polygon version. In the content browser locate the `CollisionWheel` mesh inside `Content > Carla > Blueprints > Vehicles`. Drag it onto the `Collision Mesh` slot in the details panel of the blueprint. This will improve performance without any noticeable deficit to physics simulation. ### Tire configuration -Next, we set the tire configuration. Inside `Content > Carla > Blueprints > Vehicles` locate the `CommonTireConfig` configuration and drag it onto the `Tire Config` section of the blueprint. If you double click on the Tire Config in the blueprint, you can adjust the Friction Scale, you can modify the behavior of the vehicle's road handling. By default it is set at 3.5, a value suitable for most vehicle use cases. However, if you wish to model for example a racing vehicle with slick tires, this would be the appropriate parameter to adjust. +Next, we set the tire configuration. Inside `Content > Carla > Blueprints > Vehicles` locate the `CommonTireConfig` configuration and drag it onto the `Tire Config` section of the blueprint. If you double click on the Tire Config in the blueprint, you can adjust the Friction Scale, you can modify the behavior of the vehicle's road handling. By default it is set at 3.5, a value suitable for most vehicle use cases. However, if you wish to model for example a racing vehicle with slick tires, this would be the appropriate parameter to adjust. ### Wheel dimensions @@ -316,24 +316,24 @@ Now plug these numbers into the `Wheel` section of the blueprint.Take care to re ![bp_wheel_dimensions](img/tuto_content_authoring_vehicles/bp_wheel_dimensions.png) -`Affected by handbrake` should be checked for both rear wheels. +`Affected by handbrake` should be checked for both rear wheels. `Steer angle` should be set to the maximum intended steer angle for both front wheels and set to zero for both rear wheels. ### __Suspension characteristics__ -The default values here provide a reasonable starting point. View [__this guide__](tuto_D_customize_vehicle_suspension.md) to set suspension characteristics appropriate to your vehicle type. +The default values here provide a reasonable starting point. View [__this guide__](tuto_D_customize_vehicle_suspension.md) to set suspension characteristics appropriate to your vehicle type. ## Lights -The last element to complete a realistic vehicle for CARLA is the lights, headlights, brake lights, blinkers etc. In your 3D modelling application, you should model some shapes that resemble the lights of the vehicle you are replicating. This would be flat discs or flat cuboid structures for most headlights. Some vehicles may also have strips of LEDs. +The last element to complete a realistic vehicle for CARLA is the lights, headlights, brake lights, blinkers etc. In your 3D modelling application, you should model some shapes that resemble the lights of the vehicle you are replicating. This would be flat discs or flat cuboid structures for most headlights. Some vehicles may also have strips of LEDs. ![lights_blender](img/tuto_content_authoring_vehicles/lights_blender.png) ### UV map -The different types of lights (headlights, blinkers, brake lights, etc.) are distinguished using a texture. You need to create a UV map in your 3D modelling application and position the lights to match up with the relevant region of the texture. +The different types of lights (headlights, blinkers, brake lights, etc.) are distinguished using a texture. You need to create a UV map in your 3D modelling application and position the lights to match up with the relevant region of the texture. ![lights_uv](img/tuto_content_authoring_vehicles/lights_uv_map.png) diff --git a/Docs/tutorials.md b/Docs/tutorials.md index c09204d82..602c99eaf 100644 --- a/Docs/tutorials.md +++ b/Docs/tutorials.md @@ -1,45 +1,45 @@ # Tutorials -Here you will find the multitude of tutorials available to help you understand how to use CARLA's many features. +Here you will find the multitude of tutorials available to help you understand how to use CARLA's many features. ## General ### CARLA features -[__Retrieve simulation data__](tuto_G_retrieve_data.md) — A step by step guide to properly gather data using the recorder. -[__Traffic manager__](tuto_G_traffic_manager.md) — How to use traffic manager to guide traffic around your town. -[__Texture streaming__](tuto_G_texture_streaming.md) — Modify textures of map objects in real time to add variation. -[__Instance segmentation camera__](tuto_G_instance_segmentation_sensor.md) — Use an instance segmentation camera to distinguish objects of the same class. -[__Bounding boxes__](tuto_G_bounding_boxes.md) — Project bounding boxes from CARLA objects into the camera. -[__Pedestrian bones__](tuto_G_pedestrian_bones.md) — Project pedestrian skeleton into camera plane. -[__Control walker skeletons__](tuto_G_control_walker_skeletons.md) — Animate walkers using skeletons. +[__Retrieve simulation data__](tuto_G_retrieve_data.md) — A step by step guide to properly gather data using the recorder. +[__Traffic manager__](tuto_G_traffic_manager.md) — How to use traffic manager to guide traffic around your town. +[__Texture streaming__](tuto_G_texture_streaming.md) — Modify textures of map objects in real time to add variation. +[__Instance segmentation camera__](tuto_G_instance_segmentation_sensor.md) — Use an instance segmentation camera to distinguish objects of the same class. +[__Bounding boxes__](tuto_G_bounding_boxes.md) — Project bounding boxes from CARLA objects into the camera. +[__Pedestrian bones__](tuto_G_pedestrian_bones.md) — Project pedestrian skeleton into camera plane. +[__Control walker skeletons__](tuto_G_control_walker_skeletons.md) — Animate walkers using skeletons. ### Building and integration -[__Build Unreal Engine and CARLA in Docker__](build_docker_unreal.md) — Build Unreal Engine and CARLA in Docker. -[__CarSim Integration__](tuto_G_carsim_integration.md) — Tutorial on how to run a simulation using the CarSim vehicle dynamics engine. -[__RLlib Integration__](tuto_G_rllib_integration.md) — Find out how to run your own experiment using the RLlib library. -[__Chrono Integration__](tuto_G_chrono.md) — Use the Chrono integration to simulation physics. -[__PyGame control__](tuto_G_pygame.md) — Use PyGame to display the output of camera sensors. +[__Build Unreal Engine and CARLA in Docker__](build_docker_unreal.md) — Build Unreal Engine and CARLA in Docker. +[__CarSim Integration__](tuto_G_carsim_integration.md) — Tutorial on how to run a simulation using the CarSim vehicle dynamics engine. +[__RLlib Integration__](tuto_G_rllib_integration.md) — Find out how to run your own experiment using the RLlib library. +[__Chrono Integration__](tuto_G_chrono.md) — Use the Chrono integration to simulation physics. +[__PyGame control__](tuto_G_pygame.md) — Use PyGame to display the output of camera sensors. ## Assets and maps -[__Generate maps with OpenStreetMap__](tuto_G_openstreetmap.md) — Use OpenStreetMap to generate maps for use in simulations. -[__Add a new vehicle__](tuto_A_add_vehicle.md) — Prepare a vehicle to be used in CARLA. -[__Add new props__](tuto_A_add_props.md) — Import additional props into CARLA. -[__Create standalone packages__](tuto_A_create_standalone.md) — Generate and handle standalone packages for assets. -[__Material customization__](tuto_A_material_customization.md) — Edit vehicle and building materials. +[__Generate maps with OpenStreetMap__](tuto_G_openstreetmap.md) — Use OpenStreetMap to generate maps for use in simulations. +[__Add a new vehicle__](tuto_A_add_vehicle.md) — Prepare a vehicle to be used in CARLA. +[__Add new props__](tuto_A_add_props.md) — Import additional props into CARLA. +[__Create standalone packages__](tuto_A_create_standalone.md) — Generate and handle standalone packages for assets. +[__Material customization__](tuto_A_material_customization.md) — Edit vehicle and building materials. ## Developers -[__How to upgrade content__](tuto_D_contribute_assets.md) — Add new content to CARLA. -[__Create a sensor__](tuto_D_create_sensor.md) — Develop a new sensor to be used in CARLA. -[__Create semantic tags__](tuto_D_create_semantic_tags.md) — Define customized tags for semantic segmentation. -[__Customize vehicle suspension__](tuto_D_customize_vehicle_suspension.md) — Modify the suspension system of a vehicle. -[__Generate detailed colliders__](tuto_D_generate_colliders.md) — Create detailed colliders for vehicles. +[__How to upgrade content__](tuto_D_contribute_assets.md) — Add new content to CARLA. +[__Create a sensor__](tuto_D_create_sensor.md) — Develop a new sensor to be used in CARLA. +[__Create semantic tags__](tuto_D_create_semantic_tags.md) — Define customized tags for semantic segmentation. +[__Customize vehicle suspension__](tuto_D_customize_vehicle_suspension.md) — Modify the suspension system of a vehicle. +[__Generate detailed colliders__](tuto_D_generate_colliders.md) — Create detailed colliders for vehicles. [__Make a release__](tuto_D_make_release.md) — How to make a release of CARLA ## Video tutorials -[__Fundamentals__](https://www.youtube.com/watch?v=pONr1R1dy88) — Learn the fundamental concepts of CARLA and start your first script. [__CODE__](https://carla-releases.s3.eu-west-3.amazonaws.com/Docs/Fundamentals.ipynb) -[__An in depth look at CARLA's sensors__](https://www.youtube.com/watch?v=om8klsBj4rc) — An in depth look at CARLA's sensors and how to use them. [__CODE__](https://carla-releases.s3.eu-west-3.amazonaws.com/Docs/Sensors_code.zip) +[__Fundamentals__](https://www.youtube.com/watch?v=pONr1R1dy88) — Learn the fundamental concepts of CARLA and start your first script. [__CODE__](https://carla-releases.s3.us-east-005.backblazeb2.com/Docs/Fundamentals.ipynb) +[__An in depth look at CARLA's sensors__](https://www.youtube.com/watch?v=om8klsBj4rc) — An in depth look at CARLA's sensors and how to use them. [__CODE__](https://carla-releases.s3.us-east-005.backblazeb2.com/Docs/Sensors_code.zip) diff --git a/README.md b/README.md index eaad3df72..0ab8fc1a1 100644 --- a/README.md +++ b/README.md @@ -19,17 +19,17 @@ environmental conditions. ### Download CARLA Linux: -* [**Get CARLA overnight build**](http://carla-releases.s3.amazonaws.com/Linux/Dev/CARLA_Latest.tar.gz) -* [**Get AdditionalMaps overnight build**](http://carla-releases.s3.amazonaws.com/Linux/Dev/AdditionalMaps_Latest.tar.gz) +* [**Get CARLA overnight build**](https://carla-releases.s3.us-east-005.backblazeb2.com/Linux/Dev/CARLA_Latest.tar.gz) +* [**Get AdditionalMaps overnight build**](https://carla-releases.s3.us-east-005.backblazeb2.com/Linux/Dev/AdditionalMaps_Latest.tar.gz) Windows: -* [**Get CARLA overnight build**](http://carla-releases.s3.amazonaws.com/Windows/Dev/CARLA_Latest.zip) -* [**Get AdditionalMaps overnight build**](http://carla-releases.s3.amazonaws.com/Windows/Dev/AdditionalMaps_Latest.zip) +* [**Get CARLA overnight build**](https://carla-releases.s3.us-east-005.backblazeb2.com/Windows/Dev/CARLA_Latest.zip) +* [**Get AdditionalMaps overnight build**](https://carla-releases.s3.us-east-005.backblazeb2.com/Windows/Dev/AdditionalMaps_Latest.zip) ### Recommended system * Intel i7 gen 9th - 11th / Intel i9 gen 9th - 11th / AMD ryzen 7 / AMD ryzen 9 -* +32 GB RAM memory +* +32 GB RAM memory * NVIDIA RTX 3070 / NVIDIA RTX 3080 / NVIDIA RTX 4090 * Ubuntu 20.04 @@ -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 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 diff --git a/Update.bat b/Update.bat index 36e8f15a8..30a6ccb52 100644 --- a/Update.bat +++ b/Update.bat @@ -19,7 +19,7 @@ for /F "delims=" %%a in (%CONTENT_VERSIONS%) do ( set "lastLine=%%a" ) set CONTENT_ID=%lastLine:~-16,16% -set CONTENT_LINK=http://carla-assets.s3.amazonaws.com/%CONTENT_ID%.tar.gz +set CONTENT_LINK=http://carla-assets.s3.us-east-005.backblazeb2.com/%CONTENT_ID%.tar.gz if "%CONTENT_ID:~0,2%"=="20" ( set CONTENT_FILE=%CONTENT_FOLDER%/%CONTENT_ID%.tar.gz set CONTENT_FILE_TAR=%CONTENT_FOLDER%/%CONTENT_ID%.tar diff --git a/Update.sh b/Update.sh index 72ed63907..58d8a1999 100755 --- a/Update.sh +++ b/Update.sh @@ -47,7 +47,7 @@ pushd "$SCRIPT_DIR" >/dev/null CONTENT_FOLDER="${SCRIPT_DIR}/Unreal/CarlaUE4/Content/Carla" CONTENT_ID=$(tac $SCRIPT_DIR/Util/ContentVersions.txt | egrep -m 1 . | rev | cut -d' ' -f1 | rev) -CONTENT_LINK=http://carla-assets.s3.amazonaws.com/${CONTENT_ID}.tar.gz +CONTENT_LINK=http://carla-assets.s3.us-east-005.backblazeb2.com/${CONTENT_ID}.tar.gz VERSION_FILE="${CONTENT_FOLDER}/.version" diff --git a/Util/BuildTools/Setup.bat b/Util/BuildTools/Setup.bat index 46eac87e5..344f2bb08 100644 --- a/Util/BuildTools/Setup.bat +++ b/Util/BuildTools/Setup.bat @@ -367,7 +367,7 @@ FOR /F "usebackq tokens=1,2" %%i in ("%VERSION_FILE%") do ( set ASSETS_VERSION=%%i set HASH=%%j ) -set URL=http://carla-assets.s3.amazonaws.com/%HASH%.tar.gz +set URL=http://carla-assets.s3.us-east-005.backblazeb2.com/%HASH%.tar.gz rem ============================================================================ rem -- Generate CMake ---------------------------------------------------------- diff --git a/Util/BuildTools/Setup.sh b/Util/BuildTools/Setup.sh index 9aa65533b..5277db2ac 100755 --- a/Util/BuildTools/Setup.sh +++ b/Util/BuildTools/Setup.sh @@ -95,7 +95,7 @@ for PY_VERSION in ${PY_VERSION_LIST[@]} ; do # try to use the backup boost we have in Jenkins if [[ ! -f "${BOOST_PACKAGE_BASENAME}.tar.gz" ]] ; then log "Using boost backup" - wget "https://carla-releases.s3.eu-west-3.amazonaws.com/Backup/${BOOST_PACKAGE_BASENAME}.tar.gz" || true + wget "https://carla-releases.s3.us-east-005.backblazeb2.com/Backup/${BOOST_PACKAGE_BASENAME}.tar.gz" || true fi log "Extracting boost for Python ${PY_VERSION}." @@ -392,7 +392,7 @@ else # try to use the backup boost we have in Jenkins if [[ ! -f "${XERCESC_BASENAME}.tar.gz" ]] ; then log "Using xerces backup" - wget "https://carla-releases.s3.eu-west-3.amazonaws.com/Backup/${XERCESC_BASENAME}.tar.gz" || true + wget "https://carla-releases.s3.us-east-005.backblazeb2.com/Backup/${XERCESC_BASENAME}.tar.gz" || true fi log "Extracting xerces-c." diff --git a/Util/ContentVersions.txt b/Util/ContentVersions.txt index f664bd4a2..9489f8087 100644 --- a/Util/ContentVersions.txt +++ b/Util/ContentVersions.txt @@ -25,7 +25,7 @@ # # You can download it directly from # -# http://carla-assets.s3.amazonaws.com/PUT_FILE_ID_HERE.tar.gz +# http://carla-assets.s3.us-east-005.backblazeb2.com/PUT_FILE_ID_HERE.tar.gz 0.9.5: 20190404_c7b464a 0.9.6: 20190710_0097e66 diff --git a/Util/CreateDebian.sh b/Util/CreateDebian.sh index 04664aeb1..3dcc7d941 100755 --- a/Util/CreateDebian.sh +++ b/Util/CreateDebian.sh @@ -28,8 +28,8 @@ fi CARLA_VERSION=$1 CARLA_DIR=carla-simulator-${CARLA_VERSION} -CARLA_RELEASE_URL=https://carla-releases.s3.eu-west-3.amazonaws.com/Linux/CARLA_${CARLA_VERSION}.tar.gz -ADDITIONAL_MAPS_URL=https://carla-releases.s3.eu-west-3.amazonaws.com/Linux/AdditionalMaps_${CARLA_VERSION}.tar.gz +CARLA_RELEASE_URL=https://carla-releases.s3.us-east-005.backblazeb2.com/Linux/CARLA_${CARLA_VERSION}.tar.gz +ADDITIONAL_MAPS_URL=https://carla-releases.s3.us-east-005.backblazeb2.com/Linux/AdditionalMaps_${CARLA_VERSION}.tar.gz # Adding maintainer name. DEBFULLNAME=Carla\ Simulator\ Team diff --git a/Util/InstallersWin/install_boost.bat b/Util/InstallersWin/install_boost.bat index bcefaa72d..441ece291 100644 --- a/Util/InstallersWin/install_boost.bat +++ b/Util/InstallersWin/install_boost.bat @@ -91,7 +91,7 @@ if not exist "%BOOST_SRC_DIR%" ( ) if not exist "%BOOST_TEMP_FILE_DIR%" ( echo %FILE_N% Using Boost backup - powershell -Command "(New-Object System.Net.WebClient).DownloadFile('https://carla-releases.s3.eu-west-3.amazonaws.com/Backup/%BOOST_TEMP_FILE%', '%BOOST_TEMP_FILE_DIR%')" + powershell -Command "(New-Object System.Net.WebClient).DownloadFile('https://carla-releases.s3.us-east-005.backblazeb2.com/Backup/%BOOST_TEMP_FILE%', '%BOOST_TEMP_FILE_DIR%')" ) if %errorlevel% neq 0 goto error_download echo %FILE_N% Extracting boost from "%BOOST_TEMP_FILE%", this can take a while... diff --git a/Util/InstallersWin/install_libpng.bat b/Util/InstallersWin/install_libpng.bat index 383def190..fa26dc0df 100644 --- a/Util/InstallersWin/install_libpng.bat +++ b/Util/InstallersWin/install_libpng.bat @@ -81,7 +81,7 @@ if not exist "%LIBPNG_SRC_DIR%" ( ) if not exist "%LIBPNG_TEMP_FILE_DIR%" ( echo %FILE_N% Using %LIBPNG_BASENAME% from backup. - powershell -Command "(New-Object System.Net.WebClient).DownloadFile('https://carla-releases.s3.eu-west-3.amazonaws.com/Backup/libpng-%LIBPNG_VERSION%-src.zip', '%LIBPNG_TEMP_FILE_DIR%')" + powershell -Command "(New-Object System.Net.WebClient).DownloadFile('https://carla-releases.s3.us-east-005.backblazeb2.com/Backup/libpng-%LIBPNG_VERSION%-src.zip', '%LIBPNG_TEMP_FILE_DIR%')" ) if %errorlevel% neq 0 goto error_download rem Extract the downloaded library diff --git a/Util/InstallersWin/install_xercesc.bat b/Util/InstallersWin/install_xercesc.bat index cf7be255b..a99bf1b47 100644 --- a/Util/InstallersWin/install_xercesc.bat +++ b/Util/InstallersWin/install_xercesc.bat @@ -58,7 +58,7 @@ rem ../xerces-c-x.x.x-src.zip set XERCESC_TEMP_FILE_DIR=%BUILD_DIR%%XERCESC_TEMP_FILE% set XERCESC_REPO=https://archive.apache.org/dist/xerces/c/3/sources/xerces-c-%XERCESC_VERSION%.zip -set XERCESC_BACKUP_REPO=https://carla-releases.s3.eu-west-3.amazonaws.com/Backup/xerces-c-%XERCESC_VERSION%.zip +set XERCESC_BACKUP_REPO=https://carla-releases.s3.us-east-005.backblazeb2.com/Backup/xerces-c-%XERCESC_VERSION%.zip rem ../xerces-c-x.x.x-source/ set XERCESC_SRC_DIR=%BUILD_DIR%%XERCESC_BASENAME%-%XERCESC_VERSION%-source\ @@ -93,7 +93,7 @@ if not exist "%XERCESC_SRC_DIR%" ( del "%XERCESC_TEMP_FILE_DIR%" echo %FILE_N% Removing dir "%BUILD_DIR%manifest" rmdir /s/q "%BUILD_DIR%manifest" - + echo %FILE_N% Renaming dir %XERCESC_TEMP_FOLDER_DIR% to %XERCESC_BASENAME%-%XERCESC_VERSION%-source rename "%XERCESC_TEMP_FOLDER_DIR%" "%XERCESC_BASENAME%-%XERCESC_VERSION%-source" ) else ( @@ -133,7 +133,7 @@ cmake .. -G %GENERATOR% %PLATFORM%^ "%BUILD_DIR%%XERCESC_BASENAME%-%XERCESC_VERSION%-source" if %errorlevel% neq 0 goto error_cmake -cmake --build . --config Release --target install +cmake --build . --config Release --target install goto success diff --git a/Util/InstallersWin/install_zlib.bat b/Util/InstallersWin/install_zlib.bat index f418293d3..e6bdf2db6 100644 --- a/Util/InstallersWin/install_zlib.bat +++ b/Util/InstallersWin/install_zlib.bat @@ -55,7 +55,7 @@ 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_BACKUP_REPO=https://carla-releases.s3.eu-west-3.amazonaws.com/Backup/zlib%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\ From 43a1436c659c5a26bdd9e86d865fb2805ab9f6a1 Mon Sep 17 00:00:00 2001 From: xiaofei <13319202082@163.com> Date: Wed, 13 Dec 2023 10:08:50 +0800 Subject: [PATCH 23/29] Fix GenerateLaneMarksForCenterLine problem --- LibCarla/source/carla/road/MeshFactory.cpp | 37 +++++++++++++++++++--- 1 file changed, 33 insertions(+), 4 deletions(-) diff --git a/LibCarla/source/carla/road/MeshFactory.cpp b/LibCarla/source/carla/road/MeshFactory.cpp index 43eef0617..83cb3f513 100644 --- a/LibCarla/source/carla/road/MeshFactory.cpp +++ b/LibCarla/source/carla/road/MeshFactory.cpp @@ -930,8 +930,23 @@ std::map>> MeshFactory: std::pair edges = lane.GetCornerPositions(s_current, road_param.extra_lane_width); - geom::Vector3D director = edges.second - edges.first; - director /= director.Length(); + geom::Vector3D director; + if (lane.GetWidth(s_current) != 0) { + director = edges.second - edges.first; + director /= director.Length(); + } else { + const std::map & lanes = lane_section.GetLanes(); + for (const auto& lane_pair : lanes) { + if (lane_pair.second.GetWidth(s_current) != 0) { + std::pair another_edge = + lane_pair.second.GetCornerPositions(s_current, road_param.extra_lane_width); + director = another_edge.second - another_edge.first; + director /= director.Length(); + break; + } + } + } + geom::Vector3D endmarking = edges.first + director * lane_mark_info.width; out_mesh.AddVertex(edges.first); @@ -944,8 +959,22 @@ std::map>> MeshFactory: edges = lane.GetCornerPositions(s_current, road_param.extra_lane_width); - director = edges.second - edges.first; - director /= director.Length(); + if (lane.GetWidth(s_current) != 0) { + director = edges.second - edges.first; + director /= director.Length(); + } else { + const std::map & lanes = lane_section.GetLanes(); + for (const auto& lane_pair : lanes) { + if (lane_pair.second.GetWidth(s_current) != 0) { + std::pair another_edge = + lane_pair.second.GetCornerPositions(s_current, road_param.extra_lane_width); + director = another_edge.second - another_edge.first; + director /= director.Length(); + break; + } + } + } + endmarking = edges.first + director * lane_mark_info.width; out_mesh.AddVertex(edges.first); From 60af9139232505cad4cc55fe7b9401c852855e6f Mon Sep 17 00:00:00 2001 From: MattRoweEAIF <125647690+MattRoweEAIF@users.noreply.github.com> Date: Wed, 13 Dec 2023 13:50:28 +0100 Subject: [PATCH 24/29] corrected tutorials page (#7000) --- Docs/tutorials.md | 50 +++++++++++++++++++++++------------------------ 1 file changed, 25 insertions(+), 25 deletions(-) diff --git a/Docs/tutorials.md b/Docs/tutorials.md index 602c99eaf..77c227acb 100644 --- a/Docs/tutorials.md +++ b/Docs/tutorials.md @@ -6,40 +6,40 @@ Here you will find the multitude of tutorials available to help you understand h ### CARLA features -[__Retrieve simulation data__](tuto_G_retrieve_data.md) — A step by step guide to properly gather data using the recorder. -[__Traffic manager__](tuto_G_traffic_manager.md) — How to use traffic manager to guide traffic around your town. -[__Texture streaming__](tuto_G_texture_streaming.md) — Modify textures of map objects in real time to add variation. -[__Instance segmentation camera__](tuto_G_instance_segmentation_sensor.md) — Use an instance segmentation camera to distinguish objects of the same class. -[__Bounding boxes__](tuto_G_bounding_boxes.md) — Project bounding boxes from CARLA objects into the camera. -[__Pedestrian bones__](tuto_G_pedestrian_bones.md) — Project pedestrian skeleton into camera plane. -[__Control walker skeletons__](tuto_G_control_walker_skeletons.md) — Animate walkers using skeletons. +* [__Retrieve simulation data__](tuto_G_retrieve_data.md) — A step by step guide to properly gather data using the recorder. +* [__Traffic manager__](tuto_G_traffic_manager.md) — How to use traffic manager to guide traffic around your town. +* [__Texture streaming__](tuto_G_texture_streaming.md) — Modify textures of map objects in real time to add variation. +* [__Instance segmentation camera__](tuto_G_instance_segmentation_sensor.md) — Use an instance segmentation camera to distinguish objects of the same class. +* [__Bounding boxes__](tuto_G_bounding_boxes.md) — Project bounding boxes from CARLA objects into the camera. +* [__Pedestrian bones__](tuto_G_pedestrian_bones.md) — Project pedestrian skeleton into camera plane. +* [__Control walker skeletons__](tuto_G_control_walker_skeletons.md) — Animate walkers using skeletons. ### Building and integration -[__Build Unreal Engine and CARLA in Docker__](build_docker_unreal.md) — Build Unreal Engine and CARLA in Docker. -[__CarSim Integration__](tuto_G_carsim_integration.md) — Tutorial on how to run a simulation using the CarSim vehicle dynamics engine. -[__RLlib Integration__](tuto_G_rllib_integration.md) — Find out how to run your own experiment using the RLlib library. -[__Chrono Integration__](tuto_G_chrono.md) — Use the Chrono integration to simulation physics. -[__PyGame control__](tuto_G_pygame.md) — Use PyGame to display the output of camera sensors. +* [__Build Unreal Engine and CARLA in Docker__](build_docker_unreal.md) — Build Unreal Engine and CARLA in Docker. +* [__CarSim Integration__](tuto_G_carsim_integration.md) — Tutorial on how to run a simulation using the CarSim vehicle dynamics engine. +* [__RLlib Integration__](tuto_G_rllib_integration.md) — Find out how to run your own experiment using the RLlib library. +* [__Chrono Integration__](tuto_G_chrono.md) — Use the Chrono integration to simulation physics. +* [__PyGame control__](tuto_G_pygame.md) — Use PyGame to display the output of camera sensors. ## Assets and maps -[__Generate maps with OpenStreetMap__](tuto_G_openstreetmap.md) — Use OpenStreetMap to generate maps for use in simulations. -[__Add a new vehicle__](tuto_A_add_vehicle.md) — Prepare a vehicle to be used in CARLA. -[__Add new props__](tuto_A_add_props.md) — Import additional props into CARLA. -[__Create standalone packages__](tuto_A_create_standalone.md) — Generate and handle standalone packages for assets. -[__Material customization__](tuto_A_material_customization.md) — Edit vehicle and building materials. +* [__Generate maps with OpenStreetMap__](tuto_G_openstreetmap.md) — Use OpenStreetMap to generate maps for use in simulations. +* [__Add a new vehicle__](tuto_A_add_vehicle.md) — Prepare a vehicle to be used in CARLA. +* [__Add new props__](tuto_A_add_props.md) — Import additional props into CARLA. +* [__Create standalone packages__](tuto_A_create_standalone.md) — Generate and handle standalone packages for assets. +* [__Material customization__](tuto_A_material_customization.md) — Edit vehicle and building materials. ## Developers -[__How to upgrade content__](tuto_D_contribute_assets.md) — Add new content to CARLA. -[__Create a sensor__](tuto_D_create_sensor.md) — Develop a new sensor to be used in CARLA. -[__Create semantic tags__](tuto_D_create_semantic_tags.md) — Define customized tags for semantic segmentation. -[__Customize vehicle suspension__](tuto_D_customize_vehicle_suspension.md) — Modify the suspension system of a vehicle. -[__Generate detailed colliders__](tuto_D_generate_colliders.md) — Create detailed colliders for vehicles. -[__Make a release__](tuto_D_make_release.md) — How to make a release of CARLA +* [__How to upgrade content__](tuto_D_contribute_assets.md) — Add new content to CARLA. +* [__Create a sensor__](tuto_D_create_sensor.md) — Develop a new sensor to be used in CARLA. +* [__Create semantic tags__](tuto_D_create_semantic_tags.md) — Define customized tags for semantic segmentation. +* [__Customize vehicle suspension__](tuto_D_customize_vehicle_suspension.md) — Modify the suspension system of a vehicle. +* [__Generate detailed colliders__](tuto_D_generate_colliders.md) — Create detailed colliders for vehicles. +* [__Make a release__](tuto_D_make_release.md) — How to make a release of CARLA ## Video tutorials -[__Fundamentals__](https://www.youtube.com/watch?v=pONr1R1dy88) — Learn the fundamental concepts of CARLA and start your first script. [__CODE__](https://carla-releases.s3.us-east-005.backblazeb2.com/Docs/Fundamentals.ipynb) -[__An in depth look at CARLA's sensors__](https://www.youtube.com/watch?v=om8klsBj4rc) — An in depth look at CARLA's sensors and how to use them. [__CODE__](https://carla-releases.s3.us-east-005.backblazeb2.com/Docs/Sensors_code.zip) +* [__Fundamentals__](https://www.youtube.com/watch?v=pONr1R1dy88) — Learn the fundamental concepts of CARLA and start your first script. [__CODE__](https://carla-releases.s3.us-east-005.backblazeb2.com/Docs/Fundamentals.ipynb) +* [__An in depth look at CARLA's sensors__](https://www.youtube.com/watch?v=om8klsBj4rc) — An in depth look at CARLA's sensors and how to use them. [__CODE__](https://carla-releases.s3.us-east-005.backblazeb2.com/Docs/Sensors_code.zip) From 86fcfe5e807b22c174ed38e8002da89248095c8d Mon Sep 17 00:00:00 2001 From: synkrotron Date: Mon, 18 Dec 2023 17:02:33 +0800 Subject: [PATCH 25/29] Fix problems of lanemarking generation and tree generation (#7006) Co-authored-by: xiaofei <13319202082@163.com> --- LibCarla/source/carla/road/Map.cpp | 1 + LibCarla/source/carla/road/MeshFactory.cpp | 113 +++++++++------------ LibCarla/source/carla/road/MeshFactory.h | 9 ++ 3 files changed, 56 insertions(+), 67 deletions(-) diff --git a/LibCarla/source/carla/road/Map.cpp b/LibCarla/source/carla/road/Map.cpp index e746ad893..70bedbeee 100644 --- a/LibCarla/source/carla/road/Map.cpp +++ b/LibCarla/source/carla/road/Map.cpp @@ -1232,6 +1232,7 @@ namespace road { while(s_current < s_end){ if(lane->GetWidth(s_current) != 0.0f){ const auto edges = lane->GetCornerPositions(s_current, 0); + if (edges.first == edges.second) continue; geom::Vector3D director = edges.second - edges.first; geom::Vector3D treeposition = edges.first - director.MakeUnitVector() * distancefromdrivinglineborder; geom::Transform lanetransform = lane->ComputeTransform(s_current); diff --git a/LibCarla/source/carla/road/MeshFactory.cpp b/LibCarla/source/carla/road/MeshFactory.cpp index 83cb3f513..8d7019ebb 100644 --- a/LibCarla/source/carla/road/MeshFactory.cpp +++ b/LibCarla/source/carla/road/MeshFactory.cpp @@ -761,14 +761,11 @@ std::map>> MeshFactory: case carla::road::element::LaneMarking::Type::Solid: { size_t currentIndex = out_mesh.GetVertices().size() + 1; - std::pair edges = lane.GetCornerPositions(s_current, 0); - - geom::Vector3D director = edges.second - edges.first; - director /= director.Length(); - geom::Vector3D endmarking = edges.first + director * lane_mark_info.width; + std::pair edges = + ComputeEdgesForLanemark(lane_section, lane, s_current, lane_mark_info.width); out_mesh.AddVertex(edges.first); - out_mesh.AddVertex(endmarking); + out_mesh.AddVertex(edges.second); out_mesh.AddIndex(currentIndex); out_mesh.AddIndex(currentIndex + 1); @@ -784,30 +781,23 @@ std::map>> MeshFactory: case carla::road::element::LaneMarking::Type::Broken: { size_t currentIndex = out_mesh.GetVertices().size() + 1; - std::pair edges = - lane.GetCornerPositions(s_current, road_param.extra_lane_width); - - geom::Vector3D director = edges.second - edges.first; - director /= director.Length(); - geom::Vector3D endmarking = edges.first + director * lane_mark_info.width; + std::pair edges = + ComputeEdgesForLanemark(lane_section, lane, s_current, lane_mark_info.width); out_mesh.AddVertex(edges.first); - out_mesh.AddVertex(endmarking); + out_mesh.AddVertex(edges.second); s_current += road_param.resolution * 3; if (s_current > s_end) { s_current = s_end; } - edges = lane.GetCornerPositions(s_current, road_param.extra_lane_width); - director = edges.second - edges.first; - director /= director.Length(); - endmarking = edges.first + director * lane_mark_info.width; + edges = ComputeEdgesForLanemark(lane_section, lane, s_current, lane_mark_info.width); out_mesh.AddVertex(edges.first); - out_mesh.AddVertex(endmarking); - + out_mesh.AddVertex(edges.second); + out_mesh.AddIndex(currentIndex); out_mesh.AddIndex(currentIndex + 1); out_mesh.AddIndex(currentIndex + 2); @@ -864,13 +854,12 @@ std::map>> MeshFactory: const carla::road::element::RoadInfoMarkRecord* road_info_mark = lane.GetInfo(s_current); if (road_info_mark != nullptr) { carla::road::element::LaneMarking lane_mark_info(*road_info_mark); - std::pair edges = lane.GetCornerPositions(s_end, 0); - geom::Vector3D director = edges.second - edges.first; - director /= director.Length(); - geom::Vector3D endmarking = edges.first + director * lane_mark_info.width; + + std::pair edges = + ComputeEdgesForLanemark(lane_section, lane, s_end, lane_mark_info.width); out_mesh.AddVertex(edges.first); - out_mesh.AddVertex(endmarking); + out_mesh.AddVertex(edges.second); } inout.push_back(std::make_unique(out_mesh)); } @@ -927,58 +916,21 @@ std::map>> MeshFactory: case carla::road::element::LaneMarking::Type::Broken: { size_t currentIndex = out_mesh.GetVertices().size() + 1; - std::pair edges = - lane.GetCornerPositions(s_current, road_param.extra_lane_width); - - geom::Vector3D director; - if (lane.GetWidth(s_current) != 0) { - director = edges.second - edges.first; - director /= director.Length(); - } else { - const std::map & lanes = lane_section.GetLanes(); - for (const auto& lane_pair : lanes) { - if (lane_pair.second.GetWidth(s_current) != 0) { - std::pair another_edge = - lane_pair.second.GetCornerPositions(s_current, road_param.extra_lane_width); - director = another_edge.second - another_edge.first; - director /= director.Length(); - break; - } - } - } - - geom::Vector3D endmarking = edges.first + director * lane_mark_info.width; - + std::pair edges = + ComputeEdgesForLanemark(lane_section, lane, s_current, lane_mark_info.width); + out_mesh.AddVertex(edges.first); - out_mesh.AddVertex(endmarking); + out_mesh.AddVertex(edges.second); s_current += road_param.resolution * 3; if (s_current > s_end) { s_current = s_end; } - edges = lane.GetCornerPositions(s_current, road_param.extra_lane_width); - - if (lane.GetWidth(s_current) != 0) { - director = edges.second - edges.first; - director /= director.Length(); - } else { - const std::map & lanes = lane_section.GetLanes(); - for (const auto& lane_pair : lanes) { - if (lane_pair.second.GetWidth(s_current) != 0) { - std::pair another_edge = - lane_pair.second.GetCornerPositions(s_current, road_param.extra_lane_width); - director = another_edge.second - another_edge.first; - director /= director.Length(); - break; - } - } - } - - endmarking = edges.first + director * lane_mark_info.width; + edges = ComputeEdgesForLanemark(lane_section, lane, s_current, lane_mark_info.width); out_mesh.AddVertex(edges.first); - out_mesh.AddVertex(endmarking); + out_mesh.AddVertex(edges.second); out_mesh.AddIndex(currentIndex); out_mesh.AddIndex(currentIndex + 1); @@ -1179,6 +1131,33 @@ std::map>> MeshFactory: return std::make_unique(out_mesh); } + std::pair MeshFactory::ComputeEdgesForLanemark( + const road::LaneSection& lane_section, + const road::Lane& lane, + const double s_current, + const double lanemark_width) const { + std::pair edges = + lane.GetCornerPositions(s_current, road_param.extra_lane_width); + + geom::Vector3D director; + if (edges.first != edges.second) { + director = edges.second - edges.first; + director /= director.Length(); + } else { + const std::map & lanes = lane_section.GetLanes(); + for (const auto& lane_pair : lanes) { + std::pair another_edge = + lane_pair.second.GetCornerPositions(s_current, road_param.extra_lane_width); + if (another_edge.first != another_edge.second) { + director = another_edge.second - another_edge.first; + director /= director.Length(); + break; + } + } + } + geom::Vector3D endmarking = edges.first + director * lanemark_width; + return std::make_pair(edges.first, endmarking); + } } // namespace geom } // namespace carla diff --git a/LibCarla/source/carla/road/MeshFactory.h b/LibCarla/source/carla/road/MeshFactory.h index 0334d01d4..42bc60ea1 100644 --- a/LibCarla/source/carla/road/MeshFactory.h +++ b/LibCarla/source/carla/road/MeshFactory.h @@ -148,6 +148,15 @@ namespace geom { RoadParameters road_param; + private: + + // Calculate the points on both sides of the lane mark for the specified s_current + std::pair ComputeEdgesForLanemark( + const road::LaneSection& lane_section, + const road::Lane& lane, + const double s_current, + const double lanemark_width) const; + }; } // namespace geom From 1c9d8663b4a8cede6b7e60c590880e6d72d9547e Mon Sep 17 00:00:00 2001 From: MattRoweEAIF <125647690+MattRoweEAIF@users.noreply.github.com> Date: Wed, 20 Dec 2023 16:47:18 +0100 Subject: [PATCH 26/29] specified CMake version 3.15 for windows build (#7019) --- Docs/build_windows.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Docs/build_windows.md b/Docs/build_windows.md index 627e1982c..06aeef776 100644 --- a/Docs/build_windows.md +++ b/Docs/build_windows.md @@ -40,7 +40,7 @@ In this section you will find details of system requirements, minor and major so #### Minor installations -* [__CMake__](https://cmake.org/download/) generates standard build files from simple configuration files. +* [__CMake__](https://cmake.org/download/) generates standard build files from simple configuration files. __We recommend you use version 3.15+__. * [__Git__](https://git-scm.com/downloads) is a version control system to manage CARLA repositories. * [__Make__](http://gnuwin32.sourceforge.net/packages/make.htm) generates the executables. It is necessary to use __Make version 3.81__, otherwise the build may fail. If you have multiple versions of Make installed, check that you are using version 3.81 in your PATH when building CARLA. You can check your default version of Make by running `make --version`. * [__7Zip__](https://www.7-zip.org/) is a file compression software. This is required for automatic decompression of asset files and prevents errors during build time due to large files being extracted incorrectly or partially. From b87fad064bbc7ca559f427a47d028f5678427e75 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=8E=8B=E6=B5=B7=E4=B8=9C?= Date: Thu, 4 Jan 2024 17:34:52 +0800 Subject: [PATCH 27/29] Fix some spelling errors in the document (#7043) * Remove excess parentheses from RSS document * Fix some spelling errors in the document --- Docs/adv_rss.md | 2 +- Docs/tuto_A_material_customization.md | 8 ++++---- Docs/tuto_D_generate_colliders.md | 2 +- Docs/tuto_G_retrieve_data.md | 2 +- Docs/tuto_G_texture_streaming.md | 2 +- Docs/tuto_content_authoring_maps.md | 2 +- 6 files changed, 9 insertions(+), 9 deletions(-) diff --git a/Docs/adv_rss.md b/Docs/adv_rss.md index 6ec09807c..e357822d4 100644 --- a/Docs/adv_rss.md +++ b/Docs/adv_rss.md @@ -59,7 +59,7 @@ As a reminder, the feature is only available for the Linux build so far. ### Dependencies -There are additional prerequisites required for building RSS and its dependencies. Take a look at the [official documentation](https://intel.github.io/ad-rss-lib/BUILDING)) to know more about this. +There are additional prerequisites required for building RSS and its dependencies. Take a look at the [official documentation](https://intel.github.io/ad-rss-lib/BUILDING) to know more about this. Dependencies provided by Ubunutu (>= 16.04). ```sh diff --git a/Docs/tuto_A_material_customization.md b/Docs/tuto_A_material_customization.md index fc360a6e2..5fa0e8bee 100644 --- a/Docs/tuto_A_material_customization.md +++ b/Docs/tuto_A_material_customization.md @@ -23,9 +23,9 @@ In CARLA, there is a set of master materials that are used as templates for the * __M_CarInterior_Master__ — Material applied to the inside of the car. * __M_CarLightsGlass_Master__ — Material applied to the glass covering car lights. * __M_CarWindows_Master__ — Material applied to the windows. -* __M_CarLicensePlate_Master__ — Material applied to the license plate. -* __M_CarVehicleLights_Master__ — Material applied to the car lights as an emissive texure. -* __M_CarVehicleLigthsSirens_Master__ — Material applied to the sirens, if applicable. +* __M_LicensePlate_Master__ — Material applied to the license plate. +* __M_VehicleLights_Master__ — Material applied to the car lights as an emissive texure. +* __M_VehicleLights_Sirens_Master__ — Material applied to the sirens, if applicable. --- ## Customize car materials @@ -142,7 +142,7 @@ Similarly to car materials, a building material can be greatly changed if desire * `Color` — Tint to be applied based on the white area on the __Diffuse__ `Alpha` texture. * `Emissive Texture` — Enable the usage of an __Emissive__ texture. * `EmissiveColor` — Tint to be applied based on the white area on the __ORME__ `Emissive mask` texture. - * `Emissive atenuance` — Factor that divides the intensity stated in __BP_Lights__ to obtain proper emissive values. + * `Emissive attenuance` — Factor that divides the intensity stated in __BP_Lights__ to obtain proper emissive values. * `RoughnessCorrection` — Changes the intensity of the roughness map. * `MetallicCorrection` — Changes the intensity of the metallic map. * `NormalFlatness` — Changes the intensity of the normal map. diff --git a/Docs/tuto_D_generate_colliders.md b/Docs/tuto_D_generate_colliders.md index b4b0bf864..b23178b4b 100644 --- a/Docs/tuto_D_generate_colliders.md +++ b/Docs/tuto_D_generate_colliders.md @@ -67,7 +67,7 @@ __4.3__ Press `Compile` in the toolbar above and save the changes. ## Physics colliders !!! Important - This tutorial is based on a [contribution](https://bitbucket.org/yankagan/carla-content/wiki/Home) made by __[yankagan](https://github.com/yankagan)__! The contributor also wants to aknowledge __Francisco E__ for the tutorial on [how to import custom collisions in UE](https://www.youtube.com/watch?v=SEH4f0HrCDM). + This tutorial is based on a [contribution](https://bitbucket.org/yankagan/carla-content/wiki/Home) made by __[yankagan](https://github.com/yankagan)__! The contributor also wants to acknowledge __Francisco E__ for the tutorial on [how to import custom collisions in UE](https://www.youtube.com/watch?v=SEH4f0HrCDM). [This video](https://www.youtube.com/watch?v=CXK2M2cNQ4Y) shows the results achieved after following this tutorial. diff --git a/Docs/tuto_G_retrieve_data.md b/Docs/tuto_G_retrieve_data.md index 4a3c3427e..34591f7f2 100644 --- a/Docs/tuto_G_retrieve_data.md +++ b/Docs/tuto_G_retrieve_data.md @@ -568,7 +568,7 @@ The script places the sensor on the hood of the car, and rotated a bit upwards. The callback is a bit more complex this time, showing more of its capabilities. It will draw the points captured by the radar on the fly. The points will be colored depending on their velocity regarding the ego vehicle. * __Blue__ for points approaching the vehicle. -* __Read__ for points moving away from it. +* __Red__ for points moving away from it. * __White__ for points static regarding the ego vehicle. ```py diff --git a/Docs/tuto_G_texture_streaming.md b/Docs/tuto_G_texture_streaming.md index cbcf794f4..a16435f8f 100644 --- a/Docs/tuto_G_texture_streaming.md +++ b/Docs/tuto_G_texture_streaming.md @@ -8,7 +8,7 @@ Firstly, we need to load the Unreal Editor and load a CARLA map, follow the inst ![select_building](../img/tuto_G_texture_streaming/building_selected.png) -We have selected __BP_Apartment04_v5_Opt__ for texture manipulation, the name can be seen in the World Outliner panel. __Make sure to hover over the name in the World Outliner and use the name defined in the tooltip__. The the internal name may differ from the title displayed in the list. In this case, the internal name is actually __BP_Apartment04_v5_Opt_2__. +We have selected __BP_Apartment04_v05_Opt__ for texture manipulation, the name can be seen in the World Outliner panel. __Make sure to hover over the name in the World Outliner and use the name defined in the tooltip__. The the internal name may differ from the title displayed in the list. In this case, the internal name is actually __BP_Apartment04_v05_Opt_2__. ![tooltip](../img/tuto_G_texture_streaming/tooltip.png) diff --git a/Docs/tuto_content_authoring_maps.md b/Docs/tuto_content_authoring_maps.md index c9619b894..e3dcdd0ee 100644 --- a/Docs/tuto_content_authoring_maps.md +++ b/Docs/tuto_content_authoring_maps.md @@ -403,7 +403,7 @@ Navigate to the vegetation folder in the CARLA content library: `Carla > Static A useful tool for trees and vegetation is the [__Unreal Engine foliage tool__](https://docs.unrealengine.com/4.27/en-US/BuildingWorlds/Foliage/). Activate the tool by selecting the `mode` from the mode dropdown in the toolbar. -![foliage_tool](img/tuto_content_authoring_maps/select_foliage_tool.png) +![foliage_tool](img/tuto_content_authoring_maps/select_foliage_tool.gif) Drag your desired foliage item into the box labeled `+ Drop Foliage Here`. Set an appropriate density in the density field, then paint into the map with your foliage item. From c8acb3942336f769120e01f99ad4acd5cf56493f Mon Sep 17 00:00:00 2001 From: MattRoweEAIF Date: Tue, 16 Jan 2024 10:31:51 +0100 Subject: [PATCH 28/29] replaced final aws links --- Docs/tuto_A_add_vehicle.md | 6 +++--- Docs/tuto_G_carsim_integration.md | 2 +- Docs/tuto_G_pedestrian_bones.md | 2 +- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/Docs/tuto_A_add_vehicle.md b/Docs/tuto_A_add_vehicle.md index 635290f37..db008911e 100644 --- a/Docs/tuto_A_add_vehicle.md +++ b/Docs/tuto_A_add_vehicle.md @@ -13,7 +13,7 @@ This tutorial details how to add a new vehicle to CARLA. There are two sections, --- ## Add a 4 wheeled vehicle -Vehicles added to CARLA need to use a __common base skeleton__ which is found [__here__](https://carla-assets.s3.eu-west-3.amazonaws.com/fbx/VehicleSkeleton.rar). This link will download a folder called `VehicleSkeleton.rar` which contains the base skeleton in two different `.fbx` formats, one in ASCII and the other in binary. The format you use will depend on your 3D modeling software requirements. +Vehicles added to CARLA need to use a __common base skeleton__ which is found [__here__](https://carla-assets.s3.us-east-005.backblazeb2.com/fbx/VehicleSkeleton.rar). This link will download a folder called `VehicleSkeleton.rar` which contains the base skeleton in two different `.fbx` formats, one in ASCII and the other in binary. The format you use will depend on your 3D modeling software requirements. __The positions of the skeleton bones can be changed but any other manipulation such as rotation, addition of new bones, or changing the current hierarchy will lead to errors. __ @@ -52,7 +52,7 @@ We recommend that you divide the vehicle into the following materials: - __Lights__: Headlights, indicator lights, etc. - __LightGlass_Ext__: A layer of glass that allows visibility from the outside to the inside of the light. - __LightGlass_Int__: A layer of glass that allows visibility from the inside to the outside of the light. -- __LicensePlate__: A rectangular plane of 29x12 cm. You can use the CARLA provided `.fbx` for best results, download it [here](https://carla-assets.s3.eu-west-3.amazonaws.com/fbx/LicensePlate.rar). The texture will be assigned automatically in Unreal Engine. +- __LicensePlate__: A rectangular plane of 29x12 cm. You can use the CARLA provided `.fbx` for best results, download it [here](https://carla-assets.s3.us-east-005.backblazeb2.com/fbx/LicensePlate.rar). The texture will be assigned automatically in Unreal Engine. - __Interior__: Any other details that don't fit in the above sections can go into _Interior_. Materials should be named using the format `M_CarPart_CarName`, e.g., `M_Bodywork_Mustang`. @@ -278,7 +278,7 @@ All other parameters such as engine, transmission, steering curve, are the same --- ## Add a 2 wheeled vehicle -Adding 2 wheeled vehicles is similar to adding a 4 wheeled one but due to the complexity of the animation you'll need to set up aditional bones to guide the driver's animation. [Here](https://carla-assets.s3.eu-west-3.amazonaws.com/fbx/BikeSkeleton.rar) is the link to the reference skeleton for 2 wheeled vehicles. +Adding 2 wheeled vehicles is similar to adding a 4 wheeled one but due to the complexity of the animation you'll need to set up aditional bones to guide the driver's animation. [Here](https://carla-assets.s3.us-east-005.backblazeb2.com/fbx/BikeSkeleton.rar) is the link to the reference skeleton for 2 wheeled vehicles. As with the 4 wheeled vehicles, orient the model towards positive "x" and every bone axis towards positive x and with the z axis facing upwards. diff --git a/Docs/tuto_G_carsim_integration.md b/Docs/tuto_G_carsim_integration.md index c828fc6f6..b973590bf 100644 --- a/Docs/tuto_G_carsim_integration.md +++ b/Docs/tuto_G_carsim_integration.md @@ -25,7 +25,7 @@ This page shows you how to generate a `.sim` file, explains how vehicle dimensio __For Ubuntu__: 1. Download the plugin [here](https://www.carsim.com/users/unreal_plugin/unreal_plugin_2020_0.php). - 2. Replace the file `CarSim.Build.cs` with the file found [here](https://carla-releases.s3.eu-west-3.amazonaws.com/Backup/CarSim.Build.cs) in order to use the correct solver for Ubuntu. + 2. Replace the file `CarSim.Build.cs` with the file found [here](https://carla-assets.s3.us-east-005.backblazeb2.com/Backup/CarSim.Build.cs) in order to use the correct solver for Ubuntu. 3. This step can be skipped if you are using the packaged version of CARLA. The packaged version has already been compiled using this flag but if you are building CARLA from source then you will need to compile the server with the `--carsim` flag. diff --git a/Docs/tuto_G_pedestrian_bones.md b/Docs/tuto_G_pedestrian_bones.md index bbd459a67..48358c2b2 100644 --- a/Docs/tuto_G_pedestrian_bones.md +++ b/Docs/tuto_G_pedestrian_bones.md @@ -147,7 +147,7 @@ def build_projection_matrix(w, h, fov): ## Build the skeleton -Now we can put the moving parts together. First, gather the bone coordinates from the simulation using `pedestrian.get_bones()` and then put together the skeleton and project it onto the 2D imaging plane of the camera sensor. The bones are joined into the complete skeleton using the pairs defined in __skeleton.txt__ that can be downloaded [__here__](https://carla-assets.s3.eu-west-3.amazonaws.com/fbx/skeleton.txt). +Now we can put the moving parts together. First, gather the bone coordinates from the simulation using `pedestrian.get_bones()` and then put together the skeleton and project it onto the 2D imaging plane of the camera sensor. The bones are joined into the complete skeleton using the pairs defined in __skeleton.txt__ that can be downloaded [__here__](https://carla-assets.s3.us-east-005.backblazeb2.com/fbx/skeleton.txt). We need a function to iterate through the bone pairs defined in __skeleton.txt__ and join the bone coordinates into lines that can be overlayed onto a camera sensor image. From 5ae0e4ee089617fb64501604afdedcf7f912e720 Mon Sep 17 00:00:00 2001 From: xavisolesoft Date: Wed, 17 Jan 2024 08:30:59 +0100 Subject: [PATCH 29/29] Doc: Add Ubuntu 22.04 build steps --- Docs/build_linux.md | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/Docs/build_linux.md b/Docs/build_linux.md index 611f0cd2d..704aa8447 100644 --- a/Docs/build_linux.md +++ b/Docs/build_linux.md @@ -48,6 +48,16 @@ wget -O - https://apt.llvm.org/llvm-snapshot.gpg.key|sudo apt-key add To avoid compatibility issues between Unreal Engine and the CARLA dependencies, use the same compiler version and C++ runtime library to compile everything. The CARLA team uses clang-8 (or clang-10 in Ubuntu 20.04) and LLVM's libc++. Change the default clang version to compile Unreal Engine and the CARLA dependencies. +__Ubuntu 22.04__. +```sh +sudo apt-add-repository "deb http://archive.ubuntu.com/ubuntu focal main universe" +sudo apt-get update +sudo apt-get install build-essential clang-10 lld-10 g++-7 cmake ninja-build libvulkan1 python python3 python3-dev python3-pip libpng-dev libtiff5-dev libjpeg-dev tzdata sed curl unzip autoconf libtool rsync libxml2-dev git git-lfs +sudo update-alternatives --install /usr/bin/clang++ clang++ /usr/lib/llvm-10/bin/clang++ 180 && +sudo update-alternatives --install /usr/bin/clang clang /usr/lib/llvm-10/bin/clang 180 && +sudo update-alternatives --install /usr/bin/g++ g++ /usr/bin/g++-7 180 +``` + __Ubuntu 20.04__. ```sh sudo apt-add-repository "deb http://apt.llvm.org/focal/ llvm-toolchain-focal main"