Compare commits
9 Commits
b013f1756d
...
9a59963cad
Author | SHA1 | Date |
---|---|---|
Daraan | 9a59963cad | |
MattRoweEAIF | 715c217ad0 | |
MattRoweEAIF | f91eab2f34 | |
MattRoweEAIF | 6df1c1ed79 | |
setnr | 1c559660e0 | |
MattRoweEAIF | 0ce3559162 | |
Blyron | d6f23ed84e | |
Blyron | 21f3e404bb | |
Blyron | 43441c7beb |
|
@ -2,13 +2,15 @@
|
|||
|
||||
Thanks for sending a pull request! Please make sure you click the link above to
|
||||
view the contribution guidelines, then fill out the blanks below.
|
||||
Please, make sure if your contribution is for UE4 version of CARLA you merge against ue4-dev branch.
|
||||
if it is for UE5 version of CARLA you merge agaisnt ue5-dev branch
|
||||
|
||||
Checklist:
|
||||
|
||||
- [ ] Your branch is up-to-date with the `dev` branch and tested with latest changes
|
||||
- [ ] Your branch is up-to-date with the `ue4-dev/ue5-dev` branch and tested with latest changes
|
||||
- [ ] Extended the README / documentation, if necessary
|
||||
- [ ] Code compiles correctly
|
||||
- [ ] All tests passing with `make check` (only Linux)
|
||||
- [ ] All tests passing with `make check` (only Linux and ue4-dev)
|
||||
- [ ] If relevant, update CHANGELOG.md with your changes
|
||||
|
||||
-->
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
## Latest Changes
|
||||
* Fixed a bug that caused navigation information not to be loaded when switching maps
|
||||
* Prevent from segfault on failing SignalReference identification when loading OpenDrive files
|
||||
* Added vehicle doors to the recorder
|
||||
* Added functions to get actor' components transform
|
||||
|
@ -18,6 +19,8 @@
|
|||
* PythonAPI `Sensor.is_listening` was defined twice (property and method), cleaned and clarified it as a method.
|
||||
* Added V2X sensors for cooperative awareness message and custom user-defined messages to support vehicle-to-vehicle communication
|
||||
* Added named tuples for BasicAgent.py's detection result to allow for type-hints and better semantics.
|
||||
* Added type-hint support for the PythonAPI
|
||||
* Added type-hints to GlobalRoutePlanner and use carla.Vector3D code instead of pre 0.9.13 numpy code.
|
||||
|
||||
|
||||
## CARLA 0.9.15
|
||||
|
|
|
@ -0,0 +1,141 @@
|
|||
# C++ client example
|
||||
|
||||
To build the C++ client example you will need `make` installed. Before building a C++ client, you will need to build CARLA, follow the relevant [build instructions](build_carla.md) for your platform.
|
||||
|
||||
Navigate to the `Examples/CppClient` folder in the CARLA repository and open a terminal. You will find a Makefile in this directory. To build and run it in Linux execute `make run` at the command prompt. In Windows, create a file named `CMakeLists.txt` in the same directory and add the contents in [this file](cpp_client_cmake_windows.md), then run `cmake`.
|
||||
|
||||
This C++ example will connect to the server, spawn a vehicle and apply a command to the vehicle before destroying it and terminating.
|
||||
|
||||
### Include the relevant header files
|
||||
|
||||
For this example, we will be using several different CARLA classes, so we need to include the relevant header files from the CARLA library and include any standard libraries we will use:
|
||||
|
||||
```cpp
|
||||
#include <iostream>
|
||||
#include <random>
|
||||
#include <sstream>
|
||||
#include <stdexcept>
|
||||
#include <string>
|
||||
#include <thread>
|
||||
#include <tuple>
|
||||
|
||||
#include <carla/client/ActorBlueprint.h>
|
||||
#include <carla/client/BlueprintLibrary.h>
|
||||
#include <carla/client/Client.h>
|
||||
#include <carla/client/Map.h>
|
||||
#include <carla/client/Sensor.h>
|
||||
#include <carla/client/TimeoutException.h>
|
||||
#include <carla/client/World.h>
|
||||
#include <carla/geom/Transform.h>
|
||||
#include <carla/image/ImageIO.h>
|
||||
#include <carla/image/ImageView.h>
|
||||
#include <carla/sensor/data/Image.h>
|
||||
|
||||
```
|
||||
|
||||
### Connecting the C++ client to the server
|
||||
|
||||
Include `carla/client/Client.h` and then connect the client:
|
||||
|
||||
```cpp
|
||||
...
|
||||
#include <carla/client/Client.h>
|
||||
...
|
||||
int main(int argc, const char *argv[]) {
|
||||
|
||||
std::string host;
|
||||
uint16_t port;
|
||||
std::tie(host, port) = ParseArguments(argc, argv);
|
||||
...
|
||||
// Connect the client to the server
|
||||
auto client = cc::Client(host, port);
|
||||
client.SetTimeout(40s);
|
||||
```
|
||||
|
||||
### Load a map
|
||||
|
||||
Now let's load a randomly chosen map:
|
||||
|
||||
```cpp
|
||||
// Initialize random number generator
|
||||
std::mt19937_64 rng((std::random_device())());
|
||||
...
|
||||
auto town_name = RandomChoice(client.GetAvailableMaps(), rng);
|
||||
std::cout << "Loading world: " << town_name << std::endl;
|
||||
auto world = client.LoadWorld(town_name);
|
||||
```
|
||||
|
||||
### Spawn a randomly chosen vehicle
|
||||
|
||||
Next we will fetch the blueprint library, filter for vehicles and choose a random vehicle blueprint:
|
||||
|
||||
```cpp
|
||||
auto blueprint_library = world.GetBlueprintLibrary();
|
||||
auto vehicles = blueprint_library->Filter("vehicle");
|
||||
auto blueprint = RandomChoice(*vehicles, rng);
|
||||
```
|
||||
|
||||
Now we need to find a location to spawn the vehicle from a spawn point in the map. We will get a pointer reference to the map object and then choose a random spawn point (ensure you have initialized the random number generator):
|
||||
|
||||
```cpp
|
||||
auto map = world.GetMap();
|
||||
auto transform = RandomChoice(map->GetRecommendedSpawnPoints(), rng);
|
||||
```
|
||||
|
||||
Now we have the blueprint and spawn location, we can now spawn the vehicle using the `world.SpawnActor(...)` method:
|
||||
|
||||
```cpp
|
||||
auto actor = world.SpawnActor(blueprint, transform);
|
||||
std::cout << "Spawned " << actor->GetDisplayId() << '\n';
|
||||
// Retrieve a pointer to the vehicle object
|
||||
auto vehicle = boost::static_pointer_cast<cc::Vehicle>(actor);
|
||||
```
|
||||
|
||||
### Apply a control
|
||||
|
||||
Let's now apply some control to the vehicle to move it using the `ApplyControl(...)` method:
|
||||
|
||||
```cpp
|
||||
cc::Vehicle::Control control;
|
||||
control.throttle = 1.0f;
|
||||
vehicle->ApplyControl(control);
|
||||
```
|
||||
|
||||
Now we will relocate the spectator so that we can see our newly spawned vehicle in the map:
|
||||
|
||||
```cpp
|
||||
auto spectator = world.GetSpectator();
|
||||
// Adjust the transform to look
|
||||
transform.location += 32.0f * transform.GetForwardVector();
|
||||
transform.location.z += 2.0f;
|
||||
transform.rotation.yaw += 180.0f;
|
||||
transform.rotation.pitch = -15.0f;
|
||||
// Now set the spectator transform
|
||||
spectator->SetTransform(transform);
|
||||
```
|
||||
|
||||
We'll also sleep the process for 10 seconds to observe the simulation shortly, before the client closes:
|
||||
|
||||
|
||||
```cpp
|
||||
std::this_thread::sleep_for(10s);
|
||||
|
||||
```
|
||||
|
||||
If you wish to keep the client open while other commands are executed, create a game loop. Now you have loaded a map and spawned a vehicle. To further explore the C++ API [build the Doxygen documentation](ref_cpp.md#c-documentation) and open it in a browser.
|
||||
|
||||
To build the C++ client in another location outside of the CARLA repository, edit the first 5 lines of the Makefile to reference the correct locations for the `/build` directory and the CARLA build location:
|
||||
|
||||
```make
|
||||
CARLADIR=$(CURDIR)/../..
|
||||
BUILDDIR=$(CURDIR)/build
|
||||
BINDIR=$(CURDIR)/bin
|
||||
INSTALLDIR=$(CURDIR)/libcarla-install
|
||||
TOOLCHAIN=$(CURDIR)/ToolChain.cmake
|
||||
```
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
|
@ -15,6 +15,8 @@
|
|||
|
||||
The __Digital Twin Tool__ enables procedural generation of unique 3D environments based on road networks derived from the [OpenStreetMap](https://www.openstreetmap.org) (OSM) service. Through the Digital Twin Tool interface in CARLA's Unreal Engine editor a user can select a region of map from OSM and download the road network as the basis for a new CARLA map. The tool then fills the spaces between the roads with procedurally generated 3D buildings that adjust to the layout of the road, creating a realistic 3D road environment with high variability.
|
||||
|
||||
<iframe width="100%" height="400px" src="https://www.youtube.com/embed/gTutXdS2UkQ?si=hssM3YRCAjSIzdXM" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen></iframe>
|
||||
|
||||
## Building the OSM renderer
|
||||
|
||||
If you are using Linux, you have the option of using the OSM renderer in the CARLA interface to navigate a large OSM map region that you have downloaded. You first need to build the OSM renderer before proceeding to build CARLA. Run `make osmrenderer` inside the CARLA root directory. You may need to upgrade your version of CMake to v3.2 or above in order for this to work. This will create two folders in your build directory called `libosmcout-source` and `libosmcout-build`. Before proceeding to build CARLA, you need to then edit the `Build.sh` file in the directory `$CARLA_ROOT/Build/libosmcout-source/maps` like so, to ensure the executable is found:
|
||||
|
@ -103,4 +105,3 @@ The generation step will take around 10 minutes for a 2x2 km<sup>2</sup> region,
|
|||
## Save the map
|
||||
|
||||
If you are satisfied with the generated map then you can press *Save Map* button to save the map. __This step will take a significant amount of time__, it may take over an hour and could take several. You should prepare to leave your computer running for several hours while this step is completed. Once this step is completed, the map will be available through the Unreal Engine editor or through the CARLA API, the same as any other map.
|
||||
|
||||
|
|
|
@ -129,7 +129,7 @@ pip3 install --user -Iv setuptools==47.3.1 &&
|
|||
pip install --user distro &&
|
||||
pip3 install --user distro &&
|
||||
pip install --user wheel &&
|
||||
pip3 install --user wheel auditwheel
|
||||
pip3 install --user wheel auditwheel==4.0.0
|
||||
```
|
||||
|
||||
---
|
||||
|
|
|
@ -88,4 +88,8 @@ If you want to install the Python API corresponding to the package you have buil
|
|||
|
||||
```sh
|
||||
pip3 install PythonAPI/carla/dist/carla-*.whl
|
||||
```
|
||||
```
|
||||
|
||||
## Additional build targets
|
||||
|
||||
The procedure outlined above will download all necessary components to build CARLA, you may not want to
|
|
@ -1,7 +1,7 @@
|
|||
!!! warning
|
||||
This is a work in progress!! This version of CARLA is not considered a stable release. Over the following months many significant changes may be made to this branch which could break any modifications you make. We advise you to treat this branch as experimental.
|
||||
|
||||
# Building CARLA in Windowswith Unreal Engine 5.3
|
||||
# Building CARLA in Windows with Unreal Engine 5.3
|
||||
|
||||
## Set up the environment
|
||||
|
||||
|
|
|
@ -0,0 +1,68 @@
|
|||
```make
|
||||
cmake_minimum_required(VERSION 3.5.1)
|
||||
project(example)
|
||||
|
||||
link_directories(
|
||||
${RPCLIB_LIB_PATH})
|
||||
|
||||
file(GLOB example_sources "*.cpp" "*.h")
|
||||
|
||||
file(GLOB example_client_sources "")
|
||||
|
||||
set(carla_config client)
|
||||
list(APPEND build_targets example_${carla_config}_debug)
|
||||
|
||||
# Create targets for debug and release in the same build type.
|
||||
foreach(target ${build_targets})
|
||||
|
||||
add_executable(${target} ${example_sources})
|
||||
|
||||
target_compile_definitions(${target} PUBLIC
|
||||
-DLIBCARLA_ENABLE_PROFILER)
|
||||
|
||||
target_include_directories(${target} SYSTEM PRIVATE
|
||||
"../../LibCarla/source"
|
||||
"../../Build/boost-1.80.0-install/include"
|
||||
"../../Build/rpclib-install/include/"
|
||||
"../../Build/recast-22dfcb-install/include/"
|
||||
"../../Build/zlib-install/include/"
|
||||
"../../Build/libpng-1.2.37-install/include/"
|
||||
"../../LibCarla/source/third-party/")
|
||||
|
||||
target_link_directories(${target} SYSTEM PRIVATE
|
||||
"../../Build/boost-1.80.0-install/lib"
|
||||
"../../Build/rpclib-install/lib/"
|
||||
"../../Build/recast-22dfcb-install/lib/"
|
||||
"../../Build/zlib-install/lib/"
|
||||
"../../Build/libcarla-visualstudio/LibCarla/cmake/client/Release/"
|
||||
"../../Build/libpng-1.2.37-install/lib/")
|
||||
|
||||
target_include_directories(${target} PRIVATE
|
||||
"${libcarla_source_path}/test")
|
||||
|
||||
if (WIN32)
|
||||
target_link_libraries(${target} "rpc.lib")
|
||||
target_link_libraries(${target} "carla_client.lib")
|
||||
target_link_libraries(${target} "DebugUtils.lib")
|
||||
target_link_libraries(${target} "Detour.lib")
|
||||
target_link_libraries(${target} "DetourCrowd.lib")
|
||||
target_link_libraries(${target} "DetourTileCache.lib")
|
||||
target_link_libraries(${target} "Recast.lib")
|
||||
target_link_libraries(${target} "Shlwapi.lib")
|
||||
else()
|
||||
target_link_libraries(${target} "-lrpc")
|
||||
endif()
|
||||
|
||||
install(TARGETS ${target} DESTINATION test OPTIONAL)
|
||||
endforeach(target)
|
||||
|
||||
if (LIBCARLA_BUILD_DEBUG)
|
||||
# Specific options for debug.
|
||||
set_target_properties(example_${carla_config}_debug PROPERTIES COMPILE_FLAGS "${CMAKE_CXX_FLAGS_DEBUG}")
|
||||
target_link_libraries(example_${carla_config}_debug "carla_${carla_config}${carla_target_postfix}_debug")
|
||||
target_compile_definitions(example_${carla_config}_debug PUBLIC -DBOOST_ASIO_ENABLE_BUFFER_DEBUGGING)
|
||||
if (CMAKE_BUILD_TYPE STREQUAL "Client")
|
||||
target_link_libraries(example_${carla_config}_debug "${BOOST_LIB_PATH}/libboost_filesystem.a")
|
||||
endif()
|
||||
endif()
|
||||
```
|
Binary file not shown.
After Width: | Height: | Size: 38 KiB |
|
@ -1998,8 +1998,7 @@ Iterate over the [carla.RadarDetection](#carla.RadarDetection) retrieved as data
|
|||
---
|
||||
|
||||
## carla.Rotation<a name="carla.Rotation"></a>
|
||||
Class that represents a 3D rotation and therefore, an orientation in space. CARLA uses the Unreal Engine coordinates system. This is a Z-up left-handed system. <br>
|
||||
<br>The constructor method follows a specific order of declaration: `(pitch, yaw, roll)`, which corresponds to `(Y-rotation,Z-rotation,X-rotation)`. <br> <br>![UE4_Rotation](https://d26ilriwvtzlb.cloudfront.net/8/83/BRMC_9.jpg) *Unreal Engine's coordinates system*.
|
||||
Class that represents a 3D rotation and therefore, an orientation in space. CARLA uses the Unreal Engine coordinates system. This is a Z-up left-handed system. <br> <br> The constructor method follows a specific order of declaration: `(pitch, yaw, roll)`, which corresponds to `(Y-rotation,Z-rotation,X-rotation)`. <br> <img src="https://github.com/carla-simulator/carla/blob/ue4-dev/Docs/img/unreal_lhcs.png?raw=true" width="100%"> *Unreal Engine's left handed coordinate system with rotations*.
|
||||
|
||||
### Instance Variables
|
||||
- <a name="carla.Rotation.pitch"></a>**<font color="#f8805a">pitch</font>** (_float<small> - degrees</small>_)
|
||||
|
|
|
@ -1,4 +1,15 @@
|
|||
# C++ Reference
|
||||
|
||||
## C++ client
|
||||
|
||||
The C++ client can be built with `make` on Linux and `cmake` in Windows. An C++ client example is provided in the repository in `CARLA_ROOT/Examples/CppClient/main.cpp`. This example shows how to connect the C++ client to the CARLA server and use the API for some simple tasks.
|
||||
|
||||
To build the example C++ client, open a terminal in the `CARLA_ROOT/Examples/CppClient` directory in the repository. Run `make` in this folder and then execute `./bin/cpp_client` to run the example. The example will choose a random map from those available then load it. It will then spawn a vehicle and apply a control to the vehicle.
|
||||
|
||||
Please see the [C++ client example](adv_cpp_client.md) for more details on this example script.
|
||||
|
||||
## C++ documentation
|
||||
|
||||
We use Doxygen to generate the documentation of our C++ code:
|
||||
|
||||
[Libcarla/Source](http://carla.org/Doxygen/html/dir_b9166249188ce33115fd7d5eed1849f2.html)<br>
|
||||
|
|
|
@ -186,10 +186,11 @@ Provides measures that accelerometer, gyroscope and compass would retrieve for t
|
|||
| `timestamp` | double | Simulation time of the measurement in seconds since the beginning of the episode. |
|
||||
| `transform` | [carla.Transform](<../python_api#carlatransform>) | Location and rotation in world coordinates of the sensor at the time of the measurement. |
|
||||
| `accelerometer` | [carla.Vector3D](<../python_api#carlavector3d>) | Measures linear acceleration in `m/s^2`. |
|
||||
| `gyroscope` | [carla.Vector3D](<../python_api#carlavector3d>) | Measures angular velocity in `rad/sec`. |
|
||||
| `compass` | float | Orientation in radians. North is `(0.0, -1.0, 0.0)` in UE. |
|
||||
|
||||
| `gyroscope` | [carla.Vector3D](<../python_api#carlavector3d>) | Measures angular velocity in `rad/s`. |
|
||||
| `compass` | float | Orientation in radians. North is 0 radians. |
|
||||
|
||||
!!! note
|
||||
For the compass, North is 0 radians. East is *pi*/2 radians, South is *pi* radians, West is 3*pi*/2 radians. North is in the direction of decreasing Y in CARLA's global coordinate system. East is in the direction of increasing X. The compass value converted to degrees is equal to 90 - yaw.
|
||||
|
||||
---
|
||||
## Lane invasion detector
|
||||
|
@ -735,7 +736,7 @@ The following tags are currently available (Note, tags changed from version 0.9.
|
|||
| `14` | Car | `(0, 0, 142)` | Cars, vans |
|
||||
| `15` | Truck | `(0, 0, 70)` | Trucks |
|
||||
| `16` | Bus | `(0, 60, 100)` | Busses |
|
||||
| `17` | Train | `(0, 60, 100)` | Trains |
|
||||
| `17` | Train | `(0, 80, 100)` | Trains |
|
||||
| `18` | Motorcycle | `(0, 0, 230)` | Motorcycle, Motorbike |
|
||||
| `19` | Bicycle | `(119, 11, 32)` | Bicylces |
|
||||
| `20` | Static | `(110, 190, 160)` | Elements in the scene and props that are immovable. <br> E.g. fire hydrants, fixed benches, fountains, bus stops, etc. |
|
||||
|
@ -939,21 +940,19 @@ While the visibility is simulated within CARLA, the scenario can be configured b
|
|||
* __Output:__ [carla.CAMData](python_api.md#carla.CAMData), triggered according to the ETSI CAM standard, unless configured otherwise
|
||||
|
||||
Triggering conditions according to ETSI standard:
|
||||
- Heading angle change > $4$°
|
||||
- Position difference > $4$ m
|
||||
- Speed change > $5$ m/s
|
||||
- Heading angle change > 4°
|
||||
- Position difference > 4 m
|
||||
- Speed change > 5 m/s
|
||||
- Time elapsed > CAM Generation time (configurable)
|
||||
- Low Frequency Container Time Elapsed $> 500$ ms
|
||||
- Low Frequency Container Time Elapsed > 500 ms
|
||||
|
||||
For the CAM V2X sensor, additional blueprint attributes apply:
|
||||
|
||||
| Blueprint attribute | Type | Default | Description |
|
||||
|-------------------------|--------|-------------------------|------------------------------------|
|
||||
| <td colspan=4> Message generation |
|
||||
| gen\_cam\_min | float | $0.1$ | Minimum elapsed time between two successive CAMs in seconds (s) |
|
||||
| gen\_cam\_max | float | $1.0$ | Maximum elapsed time between two successive CAMs in seconds (s) |
|
||||
| gen\_cam\_min | float | 0.1 | Minimum elapsed time between two successive CAMs in seconds (s) |
|
||||
| gen\_cam\_max | float | 1.0 | Maximum elapsed time between two successive CAMs in seconds (s) |
|
||||
| fixed\_rate | bool | false [true] | Generate a CAM in every CARLA tick (only for debug purposes, will result in slowdown) |
|
||||
| <td colspan=4> Data generation |
|
||||
| `noise_vel_stddev_x` | float | 0\.0 | Standard deviation parameter in the noise model for velocity (X axis). |
|
||||
| `noise_accel_stddev_x` | float | 0\.0 | Standard deviation parameter in the noise model for acceleration (X axis). |
|
||||
| `noise_accel_stddev_y` | float | 0\.0 | Standard deviation parameter in the noise model for acceleration (Y axis). |
|
||||
|
@ -992,17 +991,16 @@ Example:
|
|||
|
||||
| Blueprint attribute | Type | Default | Description |
|
||||
|-------------------------|--------|-------------------------|------------------------------------|
|
||||
| transmit\_power | float | $21.5$ | Sender transmission power in dBm |
|
||||
| receiver\_sensitivity | float | $-99$ | Receiver sensitivity in dBm |
|
||||
| frequency\_ghz | float | $5.9$ | Transmission frequency in GHz. 5.9 GHz is standard for several physical channels. |
|
||||
| noise\_seed | int | $0$ | Random parameter for initialization of noise |
|
||||
| filter\_distance | float | $500$ | Maximum transmission distance in meter, path loss calculations above are skipped for simulation speed |
|
||||
| <td colspan=4> __Path loss model parameters__ |
|
||||
| combined\_antenna\_gain | float | $10.0$ | Combined gain of sender and receiver antennas in dBi, parameter for radiation efficiency and directivity |
|
||||
| d\_ref | float | $ 1.0 $ | reference distance for Log-distance path loss model in meter |
|
||||
| transmit\_power | float | 21.5 | Sender transmission power in dBm |
|
||||
| receiver\_sensitivity | float | -99 | Receiver sensitivity in dBm |
|
||||
| frequency\_ghz | float | 5.9 | Transmission frequency in GHz. 5.9 GHz is standard for several physical channels. |
|
||||
| noise\_seed | int | 0 | Random parameter for initialization of noise |
|
||||
| filter\_distance | float | 500 | Maximum transmission distance in meter, path loss calculations above are skipped for simulation speed |
|
||||
| __Path loss model parameters__ | | | |
|
||||
| combined\_antenna\_gain | float | 10.0 | Combined gain of sender and receiver antennas in dBi, parameter for radiation efficiency and directivity |
|
||||
| d\_ref | float | 1.0 | reference distance for Log-distance path loss model in meter |
|
||||
| path\_loss\_exponent | float | 2.7 | Loss parameter for non-line of sight due to building obstruction |
|
||||
| scenario | string | urban | Options: [urban, rural, highway], defines the fading noise parameters |
|
||||
| path\_loss\_model | string | geometric | general path loss model to be used. Options: [geometric, winner] |
|
||||
| use\_etsi\_fading | bool | true | Use the fading params as mentioned in the ETSI publication (true), or use the custom fading standard deviation |
|
||||
| custom\_fading\_stddev | float | 0.0 | Custom value for fading standard deviation, only used if `use_etsi_fading` is set to `false` |
|
||||
|
||||
|
|
|
@ -125,14 +125,14 @@ pipeline
|
|||
}
|
||||
stage('Checkout Doxygen repo')
|
||||
{
|
||||
when { anyOf { branch "master"; branch "dev"; buildingTag() } }
|
||||
when { anyOf { branch "master"; branch "ue4-dev"; buildingTag() } }
|
||||
steps
|
||||
{
|
||||
|
||||
dir('doc_repo')
|
||||
{
|
||||
checkout scmGit(
|
||||
branches: [[name: '*/dev']],
|
||||
branches: [[name: '*/ue4-dev']],
|
||||
extensions: [
|
||||
cleanBeforeCheckout(),
|
||||
checkoutOption(120),
|
||||
|
@ -236,7 +236,7 @@ pipeline
|
|||
{
|
||||
stage('ubuntu Doxygen generation')
|
||||
{
|
||||
when { anyOf { branch "master"; branch "dev"; buildingTag() } }
|
||||
when { anyOf { branch "master"; branch "ue4-dev"; buildingTag() } }
|
||||
steps
|
||||
{
|
||||
sh 'make docs'
|
||||
|
@ -279,9 +279,9 @@ pipeline
|
|||
|
||||
}
|
||||
|
||||
stage('ubuntu deploy dev')
|
||||
stage('ubuntu deploy ue4-dev')
|
||||
{
|
||||
when { branch "dev"; }
|
||||
when { branch "ue4-dev"; }
|
||||
steps
|
||||
{
|
||||
sh 'git checkout .'
|
||||
|
@ -305,7 +305,7 @@ pipeline
|
|||
{
|
||||
stage('ubuntu Doxygen upload')
|
||||
{
|
||||
when { anyOf { branch "master"; branch "dev"; buildingTag() } }
|
||||
when { anyOf { branch "master"; branch "ue4-dev"; buildingTag() } }
|
||||
steps
|
||||
{
|
||||
dir('doc_repo')
|
||||
|
@ -316,7 +316,7 @@ pipeline
|
|||
tar -xvzf carla_doc.tar.gz
|
||||
git add Doxygen
|
||||
git commit -m "Updated c++ docs" || true
|
||||
git push --set-upstream origin dev
|
||||
git push --set-upstream origin ue4-dev
|
||||
'''
|
||||
}
|
||||
}
|
||||
|
@ -444,7 +444,7 @@ pipeline
|
|||
|
||||
stage('windows deploy')
|
||||
{
|
||||
when { anyOf { branch "master"; branch "dev"; buildingTag() } }
|
||||
when { anyOf { branch "master"; branch "ue4-dev"; buildingTag() } }
|
||||
steps {
|
||||
bat """
|
||||
call C:\\Users\\jenkins\\setEnv64.bat
|
||||
|
|
|
@ -88,6 +88,12 @@ namespace detail {
|
|||
const auto id = GetCurrentEpisode().GetId();
|
||||
_client.LoadEpisode(std::move(map_name), reset_settings, map_layers);
|
||||
|
||||
// delete the pointer to _episode so that the Navigation information
|
||||
// will be loaded for the correct map
|
||||
assert(_episode.use_count() == 1);
|
||||
_episode.reset();
|
||||
GetReadyCurrentEpisode();
|
||||
|
||||
// We are waiting 50ms for the server to reload the episode.
|
||||
// If in this time we have not detected a change of episode, we try again
|
||||
// 'number_of_attempts' times.
|
||||
|
|
|
@ -15,7 +15,6 @@
|
|||
#include <boost/asio/connect.hpp>
|
||||
#include <boost/asio/read.hpp>
|
||||
#include <boost/asio/write.hpp>
|
||||
#include <boost/asio/post.hpp>
|
||||
#include <boost/asio/bind_executor.hpp>
|
||||
|
||||
#include <exception>
|
||||
|
@ -86,7 +85,6 @@ namespace tcp {
|
|||
|
||||
void Client::Connect() {
|
||||
auto self = shared_from_this();
|
||||
boost::asio::post(_strand, [this, self]() {
|
||||
if (_done) {
|
||||
return;
|
||||
}
|
||||
|
@ -139,18 +137,15 @@ namespace tcp {
|
|||
|
||||
log_debug("streaming client: connecting to", ep);
|
||||
_socket.async_connect(ep, boost::asio::bind_executor(_strand, handle_connect));
|
||||
});
|
||||
}
|
||||
|
||||
void Client::Stop() {
|
||||
_connection_timer.cancel();
|
||||
auto self = shared_from_this();
|
||||
boost::asio::post(_strand, [this, self]() {
|
||||
_done = true;
|
||||
if (_socket.is_open()) {
|
||||
_socket.close();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
void Client::Reconnect() {
|
||||
|
@ -165,7 +160,6 @@ namespace tcp {
|
|||
|
||||
void Client::ReadData() {
|
||||
auto self = shared_from_this();
|
||||
boost::asio::post(_strand, [this, self]() {
|
||||
if (_done) {
|
||||
return;
|
||||
}
|
||||
|
@ -182,7 +176,7 @@ namespace tcp {
|
|||
// Move the buffer to the callback function and start reading the next
|
||||
// piece of data.
|
||||
// log_debug("streaming client: success reading data, calling the callback");
|
||||
boost::asio::post(_strand, [self, message]() { self->_callback(message->pop()); });
|
||||
self->_callback(message->pop());
|
||||
ReadData();
|
||||
} else {
|
||||
// As usual, if anything fails start over from the very top.
|
||||
|
@ -219,7 +213,6 @@ namespace tcp {
|
|||
_socket,
|
||||
message->size_as_buffer(),
|
||||
boost::asio::bind_executor(_strand, handle_read_header));
|
||||
});
|
||||
}
|
||||
|
||||
} // namespace tcp
|
||||
|
|
|
@ -79,7 +79,6 @@ namespace tcp {
|
|||
DEBUG_ASSERT(message != nullptr);
|
||||
DEBUG_ASSERT(!message->empty());
|
||||
auto self = shared_from_this();
|
||||
boost::asio::post(_strand, [=]() {
|
||||
if (!_socket.is_open()) {
|
||||
return;
|
||||
}
|
||||
|
@ -111,11 +110,8 @@ namespace tcp {
|
|||
log_debug("session", _session_id, ": sending message of", message->size(), "bytes");
|
||||
|
||||
_deadline.expires_from_now(_timeout);
|
||||
boost::asio::async_write(
|
||||
_socket,
|
||||
message->GetBufferSequence(),
|
||||
handle_sent);
|
||||
});
|
||||
boost::asio::async_write(_socket, message->GetBufferSequence(),
|
||||
boost::asio::bind_executor(_strand, handle_sent));
|
||||
}
|
||||
|
||||
void ServerSession::Close() {
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
"""
|
||||
This module implements an agent that roams around a track following random
|
||||
waypoints and avoiding other vehicles. The agent also responds to traffic lights.
|
||||
It can also make use of the global route planner to follow a specifed route
|
||||
It can also make use of the global route planner to follow a specified route
|
||||
"""
|
||||
|
||||
import carla
|
||||
|
@ -15,13 +15,12 @@ from shapely.geometry import Polygon
|
|||
from agents.navigation.local_planner import LocalPlanner, RoadOption
|
||||
from agents.navigation.global_route_planner import GlobalRoutePlanner
|
||||
from agents.tools.misc import (get_speed, is_within_distance,
|
||||
get_trafficlight_trigger_location,
|
||||
compute_distance)
|
||||
get_trafficlight_trigger_location)
|
||||
|
||||
from agents.tools.hints import ObstacleDetectionResult, TrafficLightDetectionResult
|
||||
|
||||
|
||||
class BasicAgent(object):
|
||||
class BasicAgent:
|
||||
"""
|
||||
BasicAgent implements an agent that navigates the scene.
|
||||
This agent respects traffic lights and other vehicles, but ignores stop signs.
|
||||
|
@ -31,7 +30,7 @@ class BasicAgent(object):
|
|||
|
||||
def __init__(self, vehicle, target_speed=20, opt_dict={}, map_inst=None, grp_inst=None):
|
||||
"""
|
||||
Initialization the agent paramters, the local and the global planner.
|
||||
Initialization the agent parameters, the local and the global planner.
|
||||
|
||||
:param vehicle: actor to apply to agent logic onto
|
||||
:param target_speed: speed (in Km/h) at which the vehicle will move
|
||||
|
@ -102,7 +101,7 @@ class BasicAgent(object):
|
|||
|
||||
# Get the static elements of the scene
|
||||
self._lights_list = self._world.get_actors().filter("*traffic_light*")
|
||||
self._lights_map = {} # Dictionary mapping a traffic light to a wp corrspoing to its trigger volume location
|
||||
self._lights_map = {} # Dictionary mapping a traffic light to a wp corresponding to its trigger volume location
|
||||
|
||||
def add_emergency_stop(self, control):
|
||||
"""
|
||||
|
@ -139,14 +138,14 @@ class BasicAgent(object):
|
|||
def get_global_planner(self):
|
||||
"""Get method for protected member local planner"""
|
||||
return self._global_planner
|
||||
|
||||
|
||||
def set_destination(self, end_location, start_location=None, clean_queue=True):
|
||||
# type: (carla.Location, carla.Location | None, bool) -> None
|
||||
"""
|
||||
This method creates a list of waypoints between a starting and ending location,
|
||||
based on the route returned by the global router, and adds it to the local planner.
|
||||
If no starting location is passed and `clean_queue` is True, the vehicle local planner's
|
||||
target location is chosen, which corresponds (by default), to a location about 5 meters
|
||||
If no starting location is passed and `clean_queue` is True, the vehicle local planner's
|
||||
target location is chosen, which corresponds (by default), to a location about 5 meters
|
||||
in front of the vehicle.
|
||||
If `clean_queue` is False the newly planned route will be appended to the current route.
|
||||
|
||||
|
@ -157,19 +156,19 @@ class BasicAgent(object):
|
|||
if not start_location:
|
||||
if clean_queue and self._local_planner.target_waypoint:
|
||||
# Plan from the waypoint in front of the vehicle onwards
|
||||
start_location = self._local_planner.target_waypoint.transform.location
|
||||
start_location = self._local_planner.target_waypoint.transform.location
|
||||
elif not clean_queue and self._local_planner._waypoints_queue:
|
||||
# Append to the current plan
|
||||
start_location = self._local_planner._waypoints_queue[-1][0].transform.location
|
||||
else:
|
||||
# no target_waypoint or _waypoints_queue empty, use vehicle location
|
||||
start_location = self._vehicle.get_location()
|
||||
start_location = self._vehicle.get_location()
|
||||
start_waypoint = self._map.get_waypoint(start_location)
|
||||
end_waypoint = self._map.get_waypoint(end_location)
|
||||
|
||||
|
||||
route_trace = self.trace_route(start_waypoint, end_waypoint)
|
||||
self._local_planner.set_global_plan(route_trace, clean_queue=clean_queue)
|
||||
|
||||
|
||||
def set_global_plan(self, plan, stop_waypoint_creation=True, clean_queue=True):
|
||||
"""
|
||||
Adds a specific plan to the agent.
|
||||
|
@ -325,7 +324,7 @@ class BasicAgent(object):
|
|||
"""
|
||||
Method to check if there is a vehicle in front of the agent blocking its path.
|
||||
|
||||
:param vehicle_list (list of carla.Vehicle): list contatining vehicle objects.
|
||||
:param vehicle_list (list of carla.Vehicle): list containing vehicle objects.
|
||||
If None, all vehicle in the scene are used
|
||||
:param max_distance: max freespace to check for obstacles.
|
||||
If None, the base threshold value is used
|
||||
|
@ -354,7 +353,7 @@ class BasicAgent(object):
|
|||
return None
|
||||
|
||||
return Polygon(route_bb)
|
||||
|
||||
|
||||
if self._ignore_vehicles:
|
||||
return ObstacleDetectionResult(False, None, -1)
|
||||
|
||||
|
@ -404,7 +403,7 @@ class BasicAgent(object):
|
|||
target_polygon = Polygon(target_list)
|
||||
|
||||
if route_polygon.intersects(target_polygon):
|
||||
return ObstacleDetectionResult(True, target_vehicle, compute_distance(target_vehicle.get_location(), ego_location))
|
||||
return ObstacleDetectionResult(True, target_vehicle, target_vehicle.get_location().distance(ego_location))
|
||||
|
||||
# Simplified approach, using only the plan waypoints (similar to TM)
|
||||
else:
|
||||
|
@ -425,13 +424,15 @@ class BasicAgent(object):
|
|||
)
|
||||
|
||||
if is_within_distance(target_rear_transform, ego_front_transform, max_distance, [low_angle_th, up_angle_th]):
|
||||
return ObstacleDetectionResult(True, target_vehicle, compute_distance(target_transform.location, ego_transform.location))
|
||||
return ObstacleDetectionResult(True, target_vehicle, target_transform.location.distance(ego_transform.location))
|
||||
|
||||
return ObstacleDetectionResult(False, None, -1)
|
||||
|
||||
def _generate_lane_change_path(self, waypoint, direction='left', distance_same_lane=10,
|
||||
@staticmethod
|
||||
def _generate_lane_change_path(waypoint, direction='left', distance_same_lane=10,
|
||||
distance_other_lane=25, lane_change_distance=25,
|
||||
check=True, lane_changes=1, step_distance=2):
|
||||
# type: (carla.Waypoint, str, float, float, float, bool, int, float) -> list[tuple[carla.Waypoint, RoadOption]]
|
||||
"""
|
||||
This methods generates a path that results in a lane change.
|
||||
Use the different distances to fine-tune the maneuver.
|
||||
|
|
|
@ -8,14 +8,13 @@
|
|||
waypoints and avoiding other vehicles. The agent also responds to traffic lights,
|
||||
traffic signs, and has different possible configurations. """
|
||||
|
||||
import random
|
||||
import numpy as np
|
||||
import carla
|
||||
from agents.navigation.basic_agent import BasicAgent
|
||||
from agents.navigation.local_planner import RoadOption
|
||||
from agents.navigation.behavior_types import Cautious, Aggressive, Normal
|
||||
|
||||
from agents.tools.misc import get_speed, positive, is_within_distance, compute_distance
|
||||
from agents.tools.misc import get_speed, positive
|
||||
|
||||
class BehaviorAgent(BasicAgent):
|
||||
"""
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
""" This module contains the different parameters sets for each behavior. """
|
||||
|
||||
|
||||
class Cautious(object):
|
||||
class Cautious:
|
||||
"""Class for Cautious agent."""
|
||||
max_speed = 40
|
||||
speed_lim_dist = 6
|
||||
|
@ -15,7 +15,7 @@ class Cautious(object):
|
|||
tailgate_counter = 0
|
||||
|
||||
|
||||
class Normal(object):
|
||||
class Normal:
|
||||
"""Class for Normal agent."""
|
||||
max_speed = 50
|
||||
speed_lim_dist = 3
|
||||
|
@ -26,7 +26,7 @@ class Normal(object):
|
|||
tailgate_counter = 0
|
||||
|
||||
|
||||
class Aggressive(object):
|
||||
class Aggressive:
|
||||
"""Class for Aggressive agent."""
|
||||
max_speed = 70
|
||||
speed_lim_dist = 1
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
"""
|
||||
This module implements an agent that roams around a track following random
|
||||
waypoints and avoiding other vehicles. The agent also responds to traffic lights.
|
||||
It can also make use of the global route planner to follow a specifed route
|
||||
It can also make use of the global route planner to follow a specified route
|
||||
"""
|
||||
|
||||
import carla
|
||||
|
|
|
@ -12,7 +12,7 @@ import carla
|
|||
from agents.tools.misc import get_speed
|
||||
|
||||
|
||||
class VehiclePIDController():
|
||||
class VehiclePIDController:
|
||||
"""
|
||||
VehiclePIDController is the combination of two PID controllers
|
||||
(lateral and longitudinal) to perform the
|
||||
|
@ -105,7 +105,7 @@ class VehiclePIDController():
|
|||
self._lat_controller.set_offset(offset)
|
||||
|
||||
|
||||
class PIDLongitudinalController():
|
||||
class PIDLongitudinalController:
|
||||
"""
|
||||
PIDLongitudinalController implements longitudinal control using a PID.
|
||||
"""
|
||||
|
@ -171,7 +171,7 @@ class PIDLongitudinalController():
|
|||
self._dt = dt
|
||||
|
||||
|
||||
class PIDLateralController():
|
||||
class PIDLateralController:
|
||||
"""
|
||||
PIDLateralController implements lateral control using a PID.
|
||||
"""
|
||||
|
@ -199,7 +199,7 @@ class PIDLateralController():
|
|||
def run_step(self, waypoint):
|
||||
"""
|
||||
Execute one step of lateral control to steer
|
||||
the vehicle towards a certain waypoin.
|
||||
the vehicle towards a certain waypoint.
|
||||
|
||||
:param waypoint: target waypoint
|
||||
:return: steering control in the range [-1, 1] where:
|
||||
|
|
|
@ -14,20 +14,55 @@ import networkx as nx
|
|||
|
||||
import carla
|
||||
from agents.navigation.local_planner import RoadOption
|
||||
from agents.tools.misc import vector
|
||||
|
||||
class GlobalRoutePlanner(object):
|
||||
# Python 2 compatibility
|
||||
TYPE_CHECKING = False
|
||||
if TYPE_CHECKING:
|
||||
import sys
|
||||
if sys.version_info >= (3, 11):
|
||||
from typing import TypedDict, NotRequired
|
||||
elif sys.version_info >= (3, 8):
|
||||
from typing import TypedDict
|
||||
from typing_extensions import NotRequired
|
||||
else:
|
||||
from typing_extensions import TypedDict, NotRequired
|
||||
|
||||
TopologyDict = TypedDict('TopologyDict',
|
||||
{
|
||||
'entry': carla.Waypoint,
|
||||
'exit': carla.Waypoint,
|
||||
'entryxyz': tuple[float, float, float],
|
||||
'exitxyz': tuple[float, float, float],
|
||||
'path': list[carla.Waypoint]
|
||||
})
|
||||
|
||||
EdgeDict = TypedDict('EdgeDict',
|
||||
{
|
||||
'length': int,
|
||||
'path': list[carla.Waypoint],
|
||||
'entry_waypoint': carla.Waypoint,
|
||||
'exit_waypoint': carla.Waypoint,
|
||||
'entry_vector': np.ndarray,
|
||||
'exit_vector': np.ndarray,
|
||||
'net_vector': list[float],
|
||||
'intersection': bool,
|
||||
'type': RoadOption,
|
||||
'change_waypoint': NotRequired[carla.Waypoint]
|
||||
})
|
||||
|
||||
class GlobalRoutePlanner:
|
||||
"""
|
||||
This class provides a very high level route plan.
|
||||
"""
|
||||
|
||||
def __init__(self, wmap, sampling_resolution):
|
||||
# type: (carla.Map, float) -> None
|
||||
self._sampling_resolution = sampling_resolution
|
||||
self._wmap = wmap
|
||||
self._topology = None
|
||||
self._graph = None
|
||||
self._id_map = None
|
||||
self._road_id_to_edge = None
|
||||
self._topology = [] # type: list[TopologyDict]
|
||||
self._graph = None # type: nx.DiGraph # type: ignore[assignment]
|
||||
self._id_map = None # type: dict[tuple[float, float, float], int] # type: ignore[assignment]
|
||||
self._road_id_to_edge = None # type: dict[int, dict[int, dict[int, tuple[int, int]]]] # type: ignore[assignment]
|
||||
|
||||
self._intersection_end_node = -1
|
||||
self._previous_decision = RoadOption.VOID
|
||||
|
@ -39,28 +74,29 @@ class GlobalRoutePlanner(object):
|
|||
self._lane_change_link()
|
||||
|
||||
def trace_route(self, origin, destination):
|
||||
# type: (carla.Location, carla.Location) -> list[tuple[carla.Waypoint, RoadOption]]
|
||||
"""
|
||||
This method returns list of (carla.Waypoint, RoadOption)
|
||||
from origin to destination
|
||||
"""
|
||||
route_trace = []
|
||||
route_trace = [] # type: list[tuple[carla.Waypoint, RoadOption]]
|
||||
route = self._path_search(origin, destination)
|
||||
current_waypoint = self._wmap.get_waypoint(origin)
|
||||
destination_waypoint = self._wmap.get_waypoint(destination)
|
||||
|
||||
for i in range(len(route) - 1):
|
||||
road_option = self._turn_decision(i, route)
|
||||
edge = self._graph.edges[route[i], route[i+1]]
|
||||
path = []
|
||||
edge = self._graph.edges[route[i], route[i + 1]] # type: EdgeDict
|
||||
path = [] # type: list[carla.Waypoint]
|
||||
|
||||
if edge['type'] != RoadOption.LANEFOLLOW and edge['type'] != RoadOption.VOID:
|
||||
route_trace.append((current_waypoint, road_option))
|
||||
exit_wp = edge['exit_waypoint']
|
||||
n1, n2 = self._road_id_to_edge[exit_wp.road_id][exit_wp.section_id][exit_wp.lane_id]
|
||||
next_edge = self._graph.edges[n1, n2]
|
||||
next_edge = self._graph.edges[n1, n2] # type: EdgeDict
|
||||
if next_edge['path']:
|
||||
closest_index = self._find_closest_in_list(current_waypoint, next_edge['path'])
|
||||
closest_index = min(len(next_edge['path'])-1, closest_index+5)
|
||||
closest_index = min(len(next_edge['path']) - 1, closest_index + 5)
|
||||
current_waypoint = next_edge['path'][closest_index]
|
||||
else:
|
||||
current_waypoint = next_edge['exit_waypoint']
|
||||
|
@ -72,9 +108,11 @@ class GlobalRoutePlanner(object):
|
|||
for waypoint in path[closest_index:]:
|
||||
current_waypoint = waypoint
|
||||
route_trace.append((current_waypoint, road_option))
|
||||
if len(route)-i <= 2 and waypoint.transform.location.distance(destination) < 2*self._sampling_resolution:
|
||||
if len(route) - i <= 2 and waypoint.transform.location.distance(
|
||||
destination) < 2 * self._sampling_resolution:
|
||||
break
|
||||
elif len(route)-i <= 2 and current_waypoint.road_id == destination_waypoint.road_id and current_waypoint.section_id == destination_waypoint.section_id and current_waypoint.lane_id == destination_waypoint.lane_id:
|
||||
elif len(
|
||||
route) - i <= 2 and current_waypoint.road_id == destination_waypoint.road_id and current_waypoint.section_id == destination_waypoint.section_id and current_waypoint.lane_id == destination_waypoint.lane_id:
|
||||
destination_index = self._find_closest_in_list(destination_waypoint, path)
|
||||
if closest_index > destination_index:
|
||||
break
|
||||
|
@ -101,7 +139,7 @@ class GlobalRoutePlanner(object):
|
|||
# Rounding off to avoid floating point imprecision
|
||||
x1, y1, z1, x2, y2, z2 = np.round([l1.x, l1.y, l1.z, l2.x, l2.y, l2.z], 0)
|
||||
wp1.transform.location, wp2.transform.location = l1, l2
|
||||
seg_dict = dict()
|
||||
seg_dict = dict() # type: TopologyDict # type: ignore[assignment]
|
||||
seg_dict['entry'], seg_dict['exit'] = wp1, wp2
|
||||
seg_dict['entryxyz'], seg_dict['exitxyz'] = (x1, y1, z1), (x2, y2, z2)
|
||||
seg_dict['path'] = []
|
||||
|
@ -163,6 +201,7 @@ class GlobalRoutePlanner(object):
|
|||
|
||||
entry_carla_vector = entry_wp.transform.rotation.get_forward_vector()
|
||||
exit_carla_vector = exit_wp.transform.rotation.get_forward_vector()
|
||||
net_carla_vector = (exit_wp.transform.location - entry_wp.transform.location).make_unit_vector()
|
||||
|
||||
# Adding edge with attributes
|
||||
self._graph.add_edge(
|
||||
|
@ -173,7 +212,7 @@ class GlobalRoutePlanner(object):
|
|||
[entry_carla_vector.x, entry_carla_vector.y, entry_carla_vector.z]),
|
||||
exit_vector=np.array(
|
||||
[exit_carla_vector.x, exit_carla_vector.y, exit_carla_vector.z]),
|
||||
net_vector=vector(entry_wp.transform.location, exit_wp.transform.location),
|
||||
net_vector=[net_carla_vector.x, net_carla_vector.y, net_carla_vector.z],
|
||||
intersection=intersection, type=RoadOption.LANEFOLLOW)
|
||||
|
||||
def _find_loose_ends(self):
|
||||
|
@ -198,10 +237,10 @@ class GlobalRoutePlanner(object):
|
|||
if section_id not in self._road_id_to_edge[road_id]:
|
||||
self._road_id_to_edge[road_id][section_id] = dict()
|
||||
n1 = self._id_map[exit_xyz]
|
||||
n2 = -1*count_loose_ends
|
||||
n2 = -1 * count_loose_ends
|
||||
self._road_id_to_edge[road_id][section_id][lane_id] = (n1, n2)
|
||||
next_wp = end_wp.next(hop_resolution)
|
||||
path = []
|
||||
path = [] # type: list[carla.Waypoint]
|
||||
while next_wp is not None and next_wp \
|
||||
and next_wp[0].road_id == road_id \
|
||||
and next_wp[0].section_id == section_id \
|
||||
|
@ -263,12 +302,13 @@ class GlobalRoutePlanner(object):
|
|||
break
|
||||
|
||||
def _localize(self, location):
|
||||
# type: (carla.Location) -> None | tuple[int, int]
|
||||
"""
|
||||
This function finds the road segment that a given location
|
||||
is part of, returning the edge it belongs to
|
||||
"""
|
||||
waypoint = self._wmap.get_waypoint(location)
|
||||
edge = None
|
||||
edge = None # type: None | tuple[int, int]
|
||||
try:
|
||||
edge = self._road_id_to_edge[waypoint.road_id][waypoint.section_id][waypoint.lane_id]
|
||||
except KeyError:
|
||||
|
@ -282,9 +322,10 @@ class GlobalRoutePlanner(object):
|
|||
"""
|
||||
l1 = np.array(self._graph.nodes[n1]['vertex'])
|
||||
l2 = np.array(self._graph.nodes[n2]['vertex'])
|
||||
return np.linalg.norm(l1-l2)
|
||||
return np.linalg.norm(l1 - l2)
|
||||
|
||||
def _path_search(self, origin, destination):
|
||||
# type: (carla.Location, carla.Location) -> list[int]
|
||||
"""
|
||||
This function finds the shortest path connecting origin and destination
|
||||
using A* search with distance heuristic.
|
||||
|
@ -302,6 +343,7 @@ class GlobalRoutePlanner(object):
|
|||
return route
|
||||
|
||||
def _successive_last_intersection_edge(self, index, route):
|
||||
# type: (int, list[int]) -> tuple[int | None, EdgeDict | None]
|
||||
"""
|
||||
This method returns the last successive intersection edge
|
||||
from a starting index on the route.
|
||||
|
@ -309,10 +351,10 @@ class GlobalRoutePlanner(object):
|
|||
proper turn decisions.
|
||||
"""
|
||||
|
||||
last_intersection_edge = None
|
||||
last_intersection_edge = None # type: EdgeDict | None
|
||||
last_node = None
|
||||
for node1, node2 in [(route[i], route[i+1]) for i in range(index, len(route)-1)]:
|
||||
candidate_edge = self._graph.edges[node1, node2]
|
||||
for node1, node2 in [(route[i], route[i + 1]) for i in range(index, len(route) - 1)]:
|
||||
candidate_edge = self._graph.edges[node1, node2] # type: EdgeDict
|
||||
if node1 == route[index]:
|
||||
last_intersection_edge = candidate_edge
|
||||
if candidate_edge['type'] == RoadOption.LANEFOLLOW and candidate_edge['intersection']:
|
||||
|
@ -324,16 +366,17 @@ class GlobalRoutePlanner(object):
|
|||
return last_node, last_intersection_edge
|
||||
|
||||
def _turn_decision(self, index, route, threshold=math.radians(35)):
|
||||
# type: (int, list[int], float) -> RoadOption
|
||||
"""
|
||||
This method returns the turn decision (RoadOption) for pair of edges
|
||||
around current index of route list
|
||||
"""
|
||||
|
||||
decision = None
|
||||
previous_node = route[index-1]
|
||||
previous_node = route[index - 1]
|
||||
current_node = route[index]
|
||||
next_node = route[index+1]
|
||||
next_edge = self._graph.edges[current_node, next_node]
|
||||
next_node = route[index + 1]
|
||||
next_edge = self._graph.edges[current_node, next_node] # type: EdgeDict
|
||||
if index > 0:
|
||||
if self._previous_decision != RoadOption.VOID \
|
||||
and self._intersection_end_node > 0 \
|
||||
|
@ -343,7 +386,7 @@ class GlobalRoutePlanner(object):
|
|||
decision = self._previous_decision
|
||||
else:
|
||||
self._intersection_end_node = -1
|
||||
current_edge = self._graph.edges[previous_node, current_node]
|
||||
current_edge = self._graph.edges[previous_node, current_node] # type: EdgeDict
|
||||
calculate_turn = current_edge['type'] == RoadOption.LANEFOLLOW and not current_edge[
|
||||
'intersection'] and next_edge['type'] == RoadOption.LANEFOLLOW and next_edge['intersection']
|
||||
if calculate_turn:
|
||||
|
@ -358,12 +401,12 @@ class GlobalRoutePlanner(object):
|
|||
for neighbor in self._graph.successors(current_node):
|
||||
select_edge = self._graph.edges[current_node, neighbor]
|
||||
if select_edge['type'] == RoadOption.LANEFOLLOW:
|
||||
if neighbor != route[index+1]:
|
||||
if neighbor != route[index + 1]:
|
||||
sv = select_edge['net_vector']
|
||||
cross_list.append(np.cross(cv, sv)[2])
|
||||
next_cross = np.cross(cv, nv)[2]
|
||||
deviation = math.acos(np.clip(
|
||||
np.dot(cv, nv)/(np.linalg.norm(cv)*np.linalg.norm(nv)), -1.0, 1.0))
|
||||
np.dot(cv, nv) / (np.linalg.norm(cv) * np.linalg.norm(nv)), -1.0, 1.0))
|
||||
if not cross_list:
|
||||
cross_list.append(0)
|
||||
if deviation < threshold:
|
||||
|
|
|
@ -28,7 +28,7 @@ class RoadOption(IntEnum):
|
|||
CHANGELANERIGHT = 6
|
||||
|
||||
|
||||
class LocalPlanner(object):
|
||||
class LocalPlanner:
|
||||
"""
|
||||
LocalPlanner implements the basic behavior of following a
|
||||
trajectory of waypoints that is generated on-the-fly.
|
||||
|
@ -151,7 +151,7 @@ class LocalPlanner(object):
|
|||
|
||||
def follow_speed_limits(self, value=True):
|
||||
"""
|
||||
Activates a flag that makes the max speed dynamically vary according to the spped limits
|
||||
Activates a flag that makes the max speed dynamically vary according to the speed limits
|
||||
|
||||
:param value: bool
|
||||
:return:
|
||||
|
@ -287,7 +287,7 @@ class LocalPlanner(object):
|
|||
try:
|
||||
wpt, direction = self._waypoints_queue[-1]
|
||||
return wpt, direction
|
||||
except IndexError as i:
|
||||
except IndexError:
|
||||
return None, RoadOption.VOID
|
||||
|
||||
def get_plan(self):
|
||||
|
@ -316,7 +316,7 @@ def _retrieve_options(list_waypoints, current_waypoint):
|
|||
options = []
|
||||
for next_waypoint in list_waypoints:
|
||||
# this is needed because something we are linking to
|
||||
# the beggining of an intersection, therefore the
|
||||
# the beginning of an intersection, therefore the
|
||||
# variation in angle is small
|
||||
next_next_waypoint = next_waypoint.next(3.0)[0]
|
||||
link = _compute_connection(current_waypoint, next_next_waypoint)
|
||||
|
|
|
@ -18,7 +18,7 @@ else:
|
|||
class ObstacleDetectionResult(NamedTuple):
|
||||
obstacle_was_found : bool
|
||||
obstacle : Union[Actor, None]
|
||||
distance : float
|
||||
distance : float
|
||||
# distance : Union[float, Literal[-1]] # Python 3.8+ only
|
||||
|
||||
class TrafficLightDetectionResult(NamedTuple):
|
||||
|
@ -30,5 +30,5 @@ else:
|
|||
ObstacleDetectionResult = NamedTuple('ObstacleDetectionResult', [('obstacle_was_found', bool), ('obstacle', Union[Actor, None]), ('distance', Union[float, Literal[-1]])])
|
||||
else:
|
||||
ObstacleDetectionResult = NamedTuple('ObstacleDetectionResult', [('obstacle_was_found', bool), ('obstacle', Union[Actor, None]), ('distance', float)])
|
||||
|
||||
|
||||
TrafficLightDetectionResult = NamedTuple('TrafficLightDetectionResult', [('traffic_light_was_found', bool), ('traffic_light', Union[TrafficLight, None])])
|
||||
|
|
|
@ -12,6 +12,8 @@ import math
|
|||
import numpy as np
|
||||
import carla
|
||||
|
||||
_EPS = np.finfo(float).eps
|
||||
|
||||
def draw_waypoints(world, waypoints, z=0.5):
|
||||
"""
|
||||
Draw a list of waypoints at a certain height given in z.
|
||||
|
@ -140,12 +142,15 @@ def vector(location_1, location_2):
|
|||
Returns the unit vector from location_1 to location_2
|
||||
|
||||
:param location_1, location_2: carla.Location objects
|
||||
|
||||
.. note::
|
||||
Alternatively you can use:
|
||||
`(location_2 - location_1).make_unit_vector()`
|
||||
"""
|
||||
x = location_2.x - location_1.x
|
||||
y = location_2.y - location_1.y
|
||||
z = location_2.z - location_1.z
|
||||
norm = np.linalg.norm([x, y, z]) + np.finfo(float).eps
|
||||
|
||||
norm = np.linalg.norm([x, y, z]) + _EPS
|
||||
return [x / norm, y / norm, z / norm]
|
||||
|
||||
|
||||
|
@ -154,11 +159,14 @@ def compute_distance(location_1, location_2):
|
|||
Euclidean distance between 3D points
|
||||
|
||||
:param location_1, location_2: 3D points
|
||||
|
||||
.. deprecated:: 0.9.13
|
||||
Use `location_1.distance(location_2)` instead
|
||||
"""
|
||||
x = location_2.x - location_1.x
|
||||
y = location_2.y - location_1.y
|
||||
z = location_2.z - location_1.z
|
||||
norm = np.linalg.norm([x, y, z]) + np.finfo(float).eps
|
||||
norm = np.linalg.norm([x, y, z]) + _EPS
|
||||
return norm
|
||||
|
||||
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -237,6 +237,10 @@ void export_geom() {
|
|||
self.TransformPoint(location);
|
||||
return location;
|
||||
}, arg("in_point"))
|
||||
.def("inverse_transform", +[](const cg::Transform &self, cg::Vector3D &location) {
|
||||
self.InverseTransformPoint(location);
|
||||
return location;
|
||||
}, arg("in_point"))
|
||||
.def("transform_vector", +[](const cg::Transform &self, cg::Vector3D &vector) {
|
||||
self.TransformVector(vector);
|
||||
return vector;
|
||||
|
|
|
@ -325,11 +325,13 @@
|
|||
- class_name: Rotation
|
||||
# - DESCRIPTION ------------------------
|
||||
doc: >
|
||||
Class that represents a 3D rotation and therefore, an orientation in space. CARLA uses the Unreal Engine coordinates system. This is a Z-up left-handed system. <br>
|
||||
|
||||
<br>The constructor method follows a specific order of declaration: `(pitch, yaw, roll)`, which corresponds to `(Y-rotation,Z-rotation,X-rotation)`. <br>
|
||||
<br>![UE4_Rotation](https://d26ilriwvtzlb.cloudfront.net/8/83/BRMC_9.jpg)
|
||||
*Unreal Engine's coordinates system*
|
||||
Class that represents a 3D rotation and therefore, an orientation in space. CARLA uses the Unreal Engine coordinates system. This is a Z-up left-handed system.
|
||||
<br>
|
||||
<br>
|
||||
The constructor method follows a specific order of declaration: `(pitch, yaw, roll)`, which corresponds to `(Y-rotation,Z-rotation,X-rotation)`.
|
||||
<br>
|
||||
<img src="https://github.com/carla-simulator/carla/blob/ue4-dev/Docs/img/unreal_lhcs.png?raw=true" width="100%">
|
||||
*Unreal Engine's left handed coordinate system with rotations*
|
||||
# - PROPERTIES -------------------------
|
||||
instance_variables:
|
||||
- var_name: pitch
|
||||
|
|
|
@ -279,8 +279,11 @@ def main():
|
|||
for spawn_point in spawn_points:
|
||||
walker_bp = random.choice(blueprintsWalkers)
|
||||
# set as not invincible
|
||||
probability = random.randint(0,100 + 1);
|
||||
if walker_bp.has_attribute('is_invincible'):
|
||||
walker_bp.set_attribute('is_invincible', 'false')
|
||||
if walker_bp.has_attribute('can_use_wheelchair') and probability < 11:
|
||||
walker_bp.set_attribute('use_wheelchair', 'true')
|
||||
# set the max speed
|
||||
if walker_bp.has_attribute('speed'):
|
||||
if (random.random() > percentagePedestriansRunning):
|
||||
|
|
|
@ -22,12 +22,12 @@ environmental conditions.
|
|||
### Download CARLA
|
||||
|
||||
Linux:
|
||||
* [**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)
|
||||
* [**Get CARLA overnight build**](https://tiny.carla.org/carla-latest-linux)
|
||||
* [**Get AdditionalMaps overnight build**](https://tiny.carla.org/additional-maps-latest-linux)
|
||||
|
||||
Windows:
|
||||
* [**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)
|
||||
* [**Get CARLA overnight build**](https://tiny.carla.org/carla-latest-windows)
|
||||
* [**Get AdditionalMaps overnight build**](https://tiny.carla.org/additional-maps-latest-windows)
|
||||
|
||||
>[!WARNING]
|
||||
>The CARLA package downloads are now provided using the BackBlaze CDN. The Amazon Web Service download links have been discontinued. Please ensure you update any relevant information in repositories using the CARLA simulator package versions.
|
||||
|
|
|
@ -1595,7 +1595,7 @@ void UActorBlueprintFunctionLibrary::MakePedestrianDefinition(
|
|||
|
||||
|
||||
Definition.Attributes.Emplace(FActorAttribute{
|
||||
TEXT("can_use_wheel_chair"),
|
||||
TEXT("can_use_wheelchair"),
|
||||
EActorAttributeType::Bool,
|
||||
Parameters.bCanUseWheelChair ? TEXT("true") : TEXT("false") });
|
||||
|
||||
|
@ -1626,7 +1626,7 @@ void UActorBlueprintFunctionLibrary::MakePedestrianDefinition(
|
|||
WheelChairVariation.Type = EActorAttributeType::Bool;
|
||||
if(bCanUseWheelChair)
|
||||
{
|
||||
WheelChairVariation.RecommendedValues = { TEXT("true"), TEXT("false") };
|
||||
WheelChairVariation.RecommendedValues = { TEXT("false"), TEXT("true") };
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
|
@ -5,3 +5,9 @@
|
|||
// For a copy, see <https://opensource.org/licenses/MIT>.
|
||||
|
||||
#include "WalkerBase.h"
|
||||
|
||||
|
||||
AWalkerBase::AWalkerBase(const FObjectInitializer &ObjectInitializer)
|
||||
: Super(ObjectInitializer)
|
||||
{
|
||||
}
|
|
@ -16,6 +16,7 @@ class CARLA_API AWalkerBase : public ACharacter
|
|||
|
||||
GENERATED_BODY()
|
||||
|
||||
AWalkerBase(const FObjectInitializer &ObjectInitializer);
|
||||
public:
|
||||
|
||||
UPROPERTY(Category="Walker Base", BlueprintReadWrite, EditAnywhere)
|
||||
|
|
|
@ -138,7 +138,7 @@ LibCarla.client.rss.release: setup ad-rss
|
|||
plugins:
|
||||
@${CARLA_BUILD_TOOLS_FOLDER}/Plugins.sh $(ARGS)
|
||||
|
||||
setup downloadplugins:
|
||||
setup: downloadplugins
|
||||
@${CARLA_BUILD_TOOLS_FOLDER}/Setup.sh $(ARGS)
|
||||
|
||||
ad-rss:
|
||||
|
|
|
@ -86,7 +86,7 @@ if %errorlevel% neq 0 goto error_cmake
|
|||
echo %FILE_N% Building...
|
||||
cmake --build . --config Release --target install
|
||||
|
||||
if errorlevel neq 0 goto error_install
|
||||
if %errorlevel% neq 0 goto error_install
|
||||
|
||||
rem Remove the downloaded Google Test source because is no more needed
|
||||
if %DEL_SRC% == true (
|
||||
|
|
Loading…
Reference in New Issue