Merge branch 'dev'

This commit is contained in:
bernatx 2021-11-15 17:15:05 +01:00
commit a1b37f7f1c
152 changed files with 7480 additions and 1916 deletions

View File

@ -1,3 +1,35 @@
## CARLA 0.9.13
* Added new **instance aware semantic segmentation** sensor `sensor.camera.instance_segmentation`
* Added new API classes: `MaterialParameter`, `TextureColor` and `TextureFloatColor` to encode texture data and field (normal map, diffuse, etc)
* Added new API functions: `apply_color_texture_to_object`, `apply_float_color_texture_to_object` and `apply_textures_to_object` to paint objects in **runtime**
* Added the option for users to set a **route** using RoadOption elements to a vehicle controlled by the Traffic Manager.
* **Cache** now has an extra folder with current version of CARLA (so different cache per version)
* Added **set_percentage_random_left_lanechange** and **set_percentage_random_right_lanechange**.
* Improved handling of **collisions** in Traffic Manager when driving at **very high speeds**.
* Added physical simulation to **vehicle doors**, capable of opening and closing
* Added **open/close doors** feature for vehicles.
* Added API functions to **3D vectors**: `squared_length`, `length`, `make_unit_vector`, `dot`, `dot_2d`, `distance`, `distance_2d`, `distance_squared`, `distance_squared_2d`, `get_vector_angle`
* Added API functions to **2D vectors**: `squared_length`, `length`, `make_unit_vector`
* Added a **seed** for better reproducibility of pedestrians
- New API function `set_pedestrians_seed`
- New parameter **--seedw** in generate_traffic.py script
* Added missing dependency `libomp5` to **Release.Dockerfile**
* Added API functions to interact with **pedestrian bones**:
- `get_bones / set_bones`: to get/set the bones of a pedestrian
- `blend_pose`: to blend a custom pose with current animation
- `show_pose / hide_pose`: to show or hide the custom pose
- `get_pose_from_animation`: to set the custom pose with the animation current frame
* Added a new script in **PythonAPI/examples/draw_skeleton.py** to draw the bones of a pedestrian from client side
* Improved **collision** detection of the Python agents
* Added the new **VehicleLightStage** to the Traffic Manager to dynamically update the vehicle lights.
* Added two new examples to **PythonAPI/util**: Conversion of OpenStreetMaps to OpenDRIVE maps `osm_to_xodr.py` and Extraction of map spawn points `extract_spawn_points.py`
* Fixed the **import of props** without any map
* Fixed **global route planner** crash when being used at maps without lane markings
* Fixed bug causing the server to **sigsegv** when a vehicle collides an environment object in recording mode.
* Fixed **RSSSensor**: made client side calculations threaded
* Fixed **keep_right_rule** parameter.
## CARLA 0.9.12
* Changed the resolution of the cached map in Traffic Manager from 0.1 to 5 meters

View File

@ -207,6 +207,65 @@ CARLA supports physics and collision determinism under specific circumstances:
- __The world must be reloaded for each new repetition:__ Reload the world each time you want to reproduce a simulation.
- __Commands should be batched instead of issued one at a time:__ Although rare, in a busy simulation or overloaded server, single issued commands can become lost. If commands are batched in a [`apply_batch_sync`](python_api.md/#carla.Client.apply_batch_sync) command, the command is guaranteed to be executed or return a failure response.
Here is an example of the steps mentioned above:
```py
client = carla.Client(HOST, PORT) # connect to the server
client.set_timeout(10.0)
world = client.get_world()
# Load the desired map
client.load_world("Town10HD_Opt")
# Set synchronous mode settings
new_settings = world.get_settings()
new_settings.synchronous_mode = True
new_settings.fixed_delta_seconds = 0.05
world.apply_settings(new_settings)
client.reload_world(False) # reload map keeping the world settings
# Set up the traffic manager
traffic_manager = client.get_trafficmanager(TM_PORT)
traffic_manager.set_synchronous_mode(True)
traffic_manager.set_random_device_seed(SEED) # define TM seed for determinism
# Spawn your vehicles, pedestrians, etc.
# Simulation loop
while True:
# Your code
world.tick()
```
And a particular example for the playback feature:
```py
client = carla.Client(HOST, PORT) # connect to the server
client.set_timeout(10.0)
world = client.get_world()
# Load the desired map
client.load_world("Town10HD_Opt")
# Set synchronous mode settings
new_settings = world.get_settings()
new_settings.synchronous_mode = True
new_settings.fixed_delta_seconds = 0.05
world.apply_settings(new_settings)
client.reload_world(False) # reload map keeping the world settings
client.replay_file(FILE_TO_PLAY, 0, 0, 0, False)
world.tick() # a tick is necessary for the server to process the replay_file command
# Simulation loop
while True:
# Your code
world.tick()
```
Running these steps will ensure the same outcome for every simulation run.
---

View File

@ -76,6 +76,11 @@ The TM generates viable commands for all vehicles in the [vehicle registry](#veh
>Vehicle movement is computed based on the defined path. A [PID controller](#pid-controller) determines how to reach the target waypoints. This is then translated into a CARLA command for application in the next step.
>__2.5 - [Vehicle Lights Stage](#stage-5-vehicle-lights-stage).__
> The vehicle lights switch on/off dynamically based on environmental factors (e.g. sunlight and the presence of fog or rain) and vehicle behavior (e.g. turning on direction indicators if the vehicle will turn left/right at the next junction, or turn on the stop lights if braking).
__3. Apply the commands in the simulation.__
Commands generated in the previous step are collected into the [command array](#command-array) and sent to the CARLA server in a batch to be applied in the same frame.
@ -119,7 +124,7 @@ __Related .cpp files:__ `SimulationState.cpp`, `SimulationState.h`.
### Control loop
The control loop manages the calculations of the next command for all autopilot vehicles so they are performed synchronously. The control loop consists of four different [stages](#stages-of-the-control-loop); localization, collision, traffic light, and motion planner.
The control loop manages the calculations of the next command for all autopilot vehicles so they are performed synchronously. The control loop consists of five different [stages](#stages-of-the-control-loop); localization, collision, traffic light, motion planner and vehicle lights.
The control loop:
@ -128,7 +133,7 @@ The control loop:
- Divides calculations into a series of [stages](#stages-of-the-control-loop).
- Creates synchronization barriers between stages to guarantee consistency. Calculations for all vehicles are finished before any of them move to the next stage, ensuring all vehicles are updated in the same frame.
- Coordinates the transition between [stages](#stages-of-the-control-loop) so all calculations are done in sync.
- Sends the [command array](#command-array) to the server when the last stage ([Motion Planner Stage](#stage-4-motion-planner-stage)) finishes so there are no frame delays between the command calculations and the command application.
- Sends the [command array](#command-array) to the server when the last stages ([Motion Planner Stage](#stage-4-motion-planner-stage) and [Vehicle Lights Stage](#stage-5-vehicle-lights-stage)) finishes so there are no frame delays between the command calculations and the command application.
__Related .cpp files:__ `TrafficManagerLocal.cpp`.
@ -228,6 +233,25 @@ The Motion Planner Stage:
__Related .cpp files:__ `MotionPlannerStage.cpp`.
##### Stage 5- Vehicle Lights Stage
The Vehicle Lights Stage activates the lights based on the condition of the vehicle and the surrounding environment.
The Vehicle Lights Stage:
- Retrieves the planned waypoints for the vehicle, information about vehicle lights (eg. light state and the planned command to be applied) and the weather conditions.
- Determines the new state of the vehicle lights:
- Turns on the blinkers if the vehicle is planning to turn left/right at the next junction.
- Turns on the stop lights if the applied command is asking the vehicle to brake.
- Turns on the low beams and the position lights from sunset to dawn, or under heavy rain.
- Turns on the fog lights under heavy fog conditions.
- Update the vehicle lights state if it has changed.
__Related .cpp files:__ `VehicleLightStage.cpp`.
---
## Using the Traffic Manager
@ -315,6 +339,20 @@ for v in my_vehicles:
tm.auto_lane_change(v,False)
```
#### Delegating the Traffic Manager to automatically update vehicle lights
By default, vehicle lights (brake, turn indicators, etc...) of the vehicles managed by the TM are never updated. It is possible to delegate the TM to update the vehicle lights of a given vehicle actor:
```python
tm = client.get_trafficmanager(port)
for actor in my_vehicles:
tm.update_vehicle_lights(actor, True)
```
Vehicle lights management has to be specified on a per-vehicle basis, and there could be at any given time both vehicles with and without the automatic light management.
### Stopping a Traffic Manager
The TM is not an actor that needs to be destroyed; it will stop when the client that created it stops. This is automatically managed by the API, the user does not have to do anything. However, when shutting down a TM, the user must destroy the vehicles controlled by it, otherwise they will remain immobile on the map. The script `generate_traffic.py` does this automatically:

File diff suppressed because it is too large Load Diff

View File

@ -2,7 +2,7 @@
### Latest Release
- [CARLA 0.9.12](https://github.com/carla-simulator/carla/releases/tag/0.9.12/) - [Documentation](https://carla.readthedocs.io/en/0.9.12/)
- [CARLA 0.9.13](https://github.com/carla-simulator/carla/releases/tag/0.9.13/) - [Documentation](https://carla.readthedocs.io/en/0.9.13/)
### Nightly build
@ -17,6 +17,7 @@
> Here are the previous versions of CARLA with links to the specific documentation for each version:
- [CARLA 0.9.12](https://github.com/carla-simulator/carla/releases/tag/0.9.12/) - [Documentation](https://carla.readthedocs.io/en/0.9.12/)
- [CARLA 0.9.11](https://github.com/carla-simulator/carla/releases/tag/0.9.11/) - [Documentation](https://carla.readthedocs.io/en/0.9.11/)
- [CARLA 0.9.10](https://github.com/carla-simulator/carla/releases/tag/0.9.10/) - [Documentation](https://carla.readthedocs.io/en/0.9.10/)
- [CARLA 0.9.9](https://github.com/carla-simulator/carla/releases/tag/0.9.9/) - [Documentation](https://carla.readthedocs.io/en/0.9.9/)

View File

@ -100,7 +100,7 @@ CARLA forum</a>
[__Control walker skeletons__](tuto_G_control_walker_skeletons.md) — Animate walkers using skeletons.
[__Generate maps with OpenStreetMap__](tuto_G_openstreetmap.md) — Use OpenStreetMap to generate maps for use in simulations.
[__Retrieve simulation data__](tuto_G_retrieve_data.md) — A step by step guide to properly gather data using the recorder.
[__CarSim Integration (Beta)__](tuto_G_carsim_integration.md) — Tutorial on how to run a simulation using the CarSim vehicle dynamics engine.
[__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
[__Build Unreal Engine and CARLA in Docker__](build_docker_unreal.md) — Build Unreal Engine and CARLA in Docker

File diff suppressed because it is too large Load Diff

View File

@ -1,12 +1,9 @@
# CarSim Integration (Beta)
# CarSim Integration
CARLA's integration with CarSim allows vehicle controls in CARLA to be forwarded to CarSim. CarSim will do all required physics calculations of the vehicle and return the new state to CARLA.
This page shows you how to generate a `.sim` file, explains how vehicle dimensions relate between CARLA and CarSim and how to run a simulation on CARLA using the CarSim integration.
!!! Warning
This feature is in beta release. This means that development of the feature is ongoing and some aspects of the feature may not work as expected. If you come across any problems feel free to open an issue on [GitHub](https://github.com/carla-simulator/carla).
* [__Before you begin__](#before-you-begin)
* [__Set up CarSim__](#set-up-carsim)
* [__Generate the .sim file__](#generate-the-sim-file)

4
Jenkinsfile vendored
View File

@ -178,13 +178,13 @@ pipeline
}
stage('ubuntu Doxygen')
{
when { anyOf { branch "master"; buildingTag() } }
when { anyOf { branch "master"; branch "dev"; buildingTag() } }
steps
{
sh 'rm -rf ~/carla-simulator.github.io/Doxygen'
sh '''
cd ~/carla-simulator.github.io
git remote set-url origin git@github.com:carla-simulator/carla-simulator.github.io.git
git remote set-url origin git@docs:carla-simulator/carla-simulator.github.io.git
git fetch
git checkout -B master origin/master
'''

View File

@ -5,6 +5,7 @@
// For a copy, see <https://opensource.org/licenses/MIT>.
#include "FileTransfer.h"
#include "carla/Version.h"
namespace carla {
namespace client {
@ -33,11 +34,21 @@ namespace client {
bool FileTransfer::FileExists(std::string file) {
// Check if the file exists or not
struct stat buffer;
return (stat((_filesBaseFolder + file).c_str(), &buffer) == 0);
std::string fullpath = _filesBaseFolder;
fullpath += "/";
fullpath += ::carla::version();
fullpath += "/";
fullpath += file;
return (stat(fullpath.c_str(), &buffer) == 0);
}
bool FileTransfer::WriteFile(std::string path, std::vector<uint8_t> content) {
std::string writePath = _filesBaseFolder + path;
std::string writePath = _filesBaseFolder;
writePath += "/";
writePath += ::carla::version();
writePath += "/";
writePath += path;
// Validate and create the file path
carla::FileSystem::ValidateFilePath(writePath);
@ -56,8 +67,13 @@ namespace client {
}
std::vector<uint8_t> FileTransfer::ReadFile(std::string path) {
std::string fullpath = _filesBaseFolder;
fullpath += "/";
fullpath += ::carla::version();
fullpath += "/";
fullpath += path;
// Read the binary file from the base folder
std::ifstream file(_filesBaseFolder + path, std::ios::binary);
std::ifstream file(fullpath, std::ios::binary);
std::vector<uint8_t> content(std::istreambuf_iterator<char>(file), {});
return content;
}

View File

@ -59,6 +59,14 @@ namespace client {
GetEpisode().Lock()->ApplyPhysicsControlToVehicle(*this, physics_control);
}
void Vehicle::OpenDoor(const VehicleDoor door_idx) {
GetEpisode().Lock()->OpenVehicleDoor(*this, rpc::VehicleDoor(door_idx));
}
void Vehicle::CloseDoor(const VehicleDoor door_idx) {
GetEpisode().Lock()->CloseVehicleDoor(*this, rpc::VehicleDoor(door_idx));
}
void Vehicle::SetLightState(const LightState &light_state) {
GetEpisode().Lock()->SetLightStateToVehicle(*this, rpc::VehicleLightState(light_state));
}

View File

@ -8,8 +8,9 @@
#include "carla/client/Actor.h"
#include "carla/rpc/TrafficLightState.h"
#include "carla/rpc/VehicleLightState.h"
#include "carla/rpc/VehicleControl.h"
#include "carla/rpc/VehicleDoor.h"
#include "carla/rpc/VehicleLightState.h"
#include "carla/rpc/VehiclePhysicsControl.h"
#include "carla/rpc/VehicleWheels.h"
#include "carla/trafficmanager/TrafficManager.h"
@ -33,6 +34,7 @@ namespace client {
using PhysicsControl = rpc::VehiclePhysicsControl;
using LightState = rpc::VehicleLightState::LightState;
using TM = traffic_manager::TrafficManager;
using VehicleDoor = rpc::VehicleDoor;
using WheelLocation = carla::rpc::VehicleWheelLocation;
@ -50,6 +52,12 @@ namespace client {
/// Apply physics control to this vehicle.
void ApplyPhysicsControl(const PhysicsControl &physics_control);
/// Open a door in this vehicle
void OpenDoor(const VehicleDoor door_idx);
/// Close a door in this vehicle
void CloseDoor(const VehicleDoor door_idx);
/// Sets a @a LightState to this vehicle.
void SetLightState(const LightState &light_state);

View File

@ -18,12 +18,25 @@ namespace client {
}
}
void Walker::ApplyControl(const BoneControl &bone_control) {
GetEpisode().Lock()->ApplyBoneControlToWalker(*this, bone_control);
}
Walker::Control Walker::GetWalkerControl() const {
return GetEpisode().Lock()->GetActorSnapshot(*this).state.walker_control;
}
Walker::BoneControlOut Walker::GetBonesTransform() {
return GetEpisode().Lock()->GetBonesTransform(*this);
}
void Walker::SetBonesTransform(const Walker::BoneControlIn &bones) {
return GetEpisode().Lock()->SetBonesTransform(*this, bones);
}
void Walker::BlendPose(float blend) {
return GetEpisode().Lock()->BlendPose(*this, blend);
}
void Walker::GetPoseFromAnimation() {
return GetEpisode().Lock()->GetPoseFromAnimation(*this);
}
} // namespace client
} // namespace carla

View File

@ -8,7 +8,8 @@
#include "carla/client/Actor.h"
#include "carla/rpc/WalkerControl.h"
#include "carla/rpc/WalkerBoneControl.h"
#include "carla/rpc/WalkerBoneControlIn.h"
#include "carla/rpc/WalkerBoneControlOut.h"
namespace carla {
namespace client {
@ -17,21 +18,27 @@ namespace client {
public:
using Control = rpc::WalkerControl;
using BoneControl = rpc::WalkerBoneControl;
using BoneControlIn = rpc::WalkerBoneControlIn;
using BoneControlOut = rpc::WalkerBoneControlOut;
explicit Walker(ActorInitializer init) : Actor(std::move(init)) {}
/// Apply @a control to this Walker.
void ApplyControl(const Control &control);
void ApplyControl(const BoneControl &bone_control);
/// Return the control last applied to this Walker.
///
/// @note This function does not call the simulator, it returns the Control
/// received in the last tick.
Control GetWalkerControl() const;
BoneControlOut GetBonesTransform();
void SetBonesTransform(const BoneControlIn &bones);
void BlendPose(float blend);
void ShowPose() { BlendPose(1.0f); };
void HidePose() { BlendPose(0.0f); };
void GetPoseFromAnimation();
private:
Control _control;

View File

@ -160,6 +160,10 @@ namespace client {
_episode.Lock()->SetPedestriansCrossFactor(percentage);
}
void World::SetPedestriansSeed(unsigned int seed) {
_episode.Lock()->SetPedestriansSeed(seed);
}
SharedPtr<Actor> World::GetTrafficSign(const Landmark& landmark) const {
SharedPtr<ActorList> actors = GetActors();
SharedPtr<TrafficSign> result;
@ -291,5 +295,93 @@ namespace client {
return Result;
}
void World::ApplyColorTextureToObject(
const std::string &object_name,
const rpc::MaterialParameter& parameter,
const rpc::TextureColor& Texture) {
_episode.Lock()->ApplyColorTextureToObjects({object_name}, parameter, Texture);
}
void World::ApplyColorTextureToObjects(
const std::vector<std::string> &objects_name,
const rpc::MaterialParameter& parameter,
const rpc::TextureColor& Texture) {
_episode.Lock()->ApplyColorTextureToObjects(objects_name, parameter, Texture);
}
void World::ApplyFloatColorTextureToObject(
const std::string &object_name,
const rpc::MaterialParameter& parameter,
const rpc::TextureFloatColor& Texture) {
_episode.Lock()->ApplyColorTextureToObjects({object_name}, parameter, Texture);
}
void World::ApplyFloatColorTextureToObjects(
const std::vector<std::string> &objects_name,
const rpc::MaterialParameter& parameter,
const rpc::TextureFloatColor& Texture) {
_episode.Lock()->ApplyColorTextureToObjects(objects_name, parameter, Texture);
}
std::vector<std::string> World::GetNamesOfAllObjects() const {
return _episode.Lock()->GetNamesOfAllObjects();
}
void World::ApplyTexturesToObject(
const std::string &object_name,
const rpc::TextureColor& diffuse_texture,
const rpc::TextureFloatColor& emissive_texture,
const rpc::TextureFloatColor& normal_texture,
const rpc::TextureFloatColor& ao_roughness_metallic_emissive_texture)
{
if (diffuse_texture.GetWidth() && diffuse_texture.GetHeight()) {
ApplyColorTextureToObject(
object_name, rpc::MaterialParameter::Tex_Diffuse, diffuse_texture);
}
if (normal_texture.GetWidth() && normal_texture.GetHeight()) {
ApplyFloatColorTextureToObject(
object_name, rpc::MaterialParameter::Tex_Normal, normal_texture);
}
if (ao_roughness_metallic_emissive_texture.GetWidth() &&
ao_roughness_metallic_emissive_texture.GetHeight()) {
ApplyFloatColorTextureToObject(
object_name,
rpc::MaterialParameter::Tex_Ao_Roughness_Metallic_Emissive,
ao_roughness_metallic_emissive_texture);
}
if (emissive_texture.GetWidth() && emissive_texture.GetHeight()) {
ApplyFloatColorTextureToObject(
object_name, rpc::MaterialParameter::Tex_Emissive, emissive_texture);
}
}
void World::ApplyTexturesToObjects(
const std::vector<std::string> &objects_names,
const rpc::TextureColor& diffuse_texture,
const rpc::TextureFloatColor& emissive_texture,
const rpc::TextureFloatColor& normal_texture,
const rpc::TextureFloatColor& ao_roughness_metallic_emissive_texture)
{
if (diffuse_texture.GetWidth() && diffuse_texture.GetHeight()) {
ApplyColorTextureToObjects(
objects_names, rpc::MaterialParameter::Tex_Diffuse, diffuse_texture);
}
if (normal_texture.GetWidth() && normal_texture.GetHeight()) {
ApplyFloatColorTextureToObjects(
objects_names, rpc::MaterialParameter::Tex_Normal, normal_texture);
}
if (ao_roughness_metallic_emissive_texture.GetWidth() &&
ao_roughness_metallic_emissive_texture.GetHeight()) {
ApplyFloatColorTextureToObjects(
objects_names,
rpc::MaterialParameter::Tex_Ao_Roughness_Metallic_Emissive,
ao_roughness_metallic_emissive_texture);
}
if (emissive_texture.GetWidth() && emissive_texture.GetHeight()) {
ApplyFloatColorTextureToObjects(
objects_names, rpc::MaterialParameter::Tex_Emissive, emissive_texture);
}
}
} // namespace client
} // namespace carla

View File

@ -26,6 +26,8 @@
#include "carla/rpc/VehiclePhysicsControl.h"
#include "carla/rpc/WeatherParameters.h"
#include "carla/rpc/VehicleLightStateList.h"
#include "carla/rpc/Texture.h"
#include "carla/rpc/MaterialParameter.h"
#include <boost/optional.hpp>
@ -143,6 +145,9 @@ namespace client {
/// percentage of 1.0f means all pedestrians can cross roads if needed
void SetPedestriansCrossFactor(float percentage);
/// set the seed to use with random numbers in the pedestrians module
void SetPedestriansSeed(unsigned int seed);
SharedPtr<Actor> GetTrafficSign(const Landmark& landmark) const;
SharedPtr<Actor> GetTrafficLight(const Landmark& landmark) const;
@ -187,6 +192,44 @@ namespace client {
std::vector<SharedPtr<Actor>> GetTrafficLightsInJunction(
const road::JuncId junc_id) const;
// std::vector<std::string> GetObjectNameList();
void ApplyColorTextureToObject(
const std::string &actor_name,
const rpc::MaterialParameter& parameter,
const rpc::TextureColor& Texture);
void ApplyColorTextureToObjects(
const std::vector<std::string> &objects_names,
const rpc::MaterialParameter& parameter,
const rpc::TextureColor& Texture);
void ApplyFloatColorTextureToObject(
const std::string &actor_name,
const rpc::MaterialParameter& parameter,
const rpc::TextureFloatColor& Texture);
void ApplyFloatColorTextureToObjects(
const std::vector<std::string> &objects_names,
const rpc::MaterialParameter& parameter,
const rpc::TextureFloatColor& Texture);
void ApplyTexturesToObject(
const std::string &actor_name,
const rpc::TextureColor& diffuse_texture,
const rpc::TextureFloatColor& emissive_texture,
const rpc::TextureFloatColor& normal_texture,
const rpc::TextureFloatColor& ao_roughness_metallic_emissive_texture);
void ApplyTexturesToObjects(
const std::vector<std::string> &objects_names,
const rpc::TextureColor& diffuse_texture,
const rpc::TextureFloatColor& emissive_texture,
const rpc::TextureFloatColor& normal_texture,
const rpc::TextureFloatColor& ao_roughness_metallic_emissive_texture);
std::vector<std::string> GetNamesOfAllObjects() const;
private:
detail::EpisodeProxy _episode;

View File

@ -11,13 +11,14 @@
#include "carla/client/FileTransfer.h"
#include "carla/client/TimeoutException.h"
#include "carla/rpc/ActorDescription.h"
#include "carla/rpc/BoneTransformData.h"
#include "carla/rpc/BoneTransformDataIn.h"
#include "carla/rpc/Client.h"
#include "carla/rpc/DebugShape.h"
#include "carla/rpc/Response.h"
#include "carla/rpc/VehicleControl.h"
#include "carla/rpc/VehicleLightState.h"
#include "carla/rpc/WalkerBoneControl.h"
#include "carla/rpc/WalkerBoneControlIn.h"
#include "carla/rpc/WalkerBoneControlOut.h"
#include "carla/rpc/WalkerControl.h"
#include "carla/streaming/Client.h"
@ -161,6 +162,24 @@ namespace detail {
_pimpl->CallAndWait<void>("copy_opendrive_to_file", std::move(opendrive), params);
}
void Client::ApplyColorTextureToObjects(
const std::vector<std::string> &objects_name,
const rpc::MaterialParameter& parameter,
const rpc::TextureColor& Texture) {
_pimpl->CallAndWait<void>("apply_color_texture_to_objects", objects_name, parameter, Texture);
}
void Client::ApplyColorTextureToObjects(
const std::vector<std::string> &objects_name,
const rpc::MaterialParameter& parameter,
const rpc::TextureFloatColor& Texture) {
_pimpl->CallAndWait<void>("apply_float_color_texture_to_objects", objects_name, parameter, Texture);
}
std::vector<std::string> Client::GetNamesOfAllObjects() const {
return _pimpl->CallAndWait<std::vector<std::string>>("get_names_of_all_objects");
}
rpc::EpisodeInfo Client::GetEpisodeInfo() {
return _pimpl->CallAndWait<rpc::EpisodeInfo>("get_episode_info");
}
@ -274,6 +293,18 @@ namespace detail {
return _pimpl->AsyncCall("set_vehicle_light_state", vehicle, light_state);
}
void Client::OpenVehicleDoor(
rpc::ActorId vehicle,
const rpc::VehicleDoor door_idx) {
return _pimpl->AsyncCall("open_vehicle_door", vehicle, door_idx);
}
void Client::CloseVehicleDoor(
rpc::ActorId vehicle,
const rpc::VehicleDoor door_idx) {
return _pimpl->AsyncCall("close_vehicle_door", vehicle, door_idx);
}
void Client::SetWheelSteerDirection(
rpc::ActorId vehicle,
rpc::VehicleWheelLocation vehicle_wheel,
@ -423,8 +454,21 @@ namespace detail {
_pimpl->AsyncCall("apply_control_to_walker", walker, control);
}
void Client::ApplyBoneControlToWalker(rpc::ActorId walker, const rpc::WalkerBoneControl &control) {
_pimpl->AsyncCall("apply_bone_control_to_walker", walker, control);
rpc::WalkerBoneControlOut Client::GetBonesTransform(rpc::ActorId walker) {
auto res = _pimpl->CallAndWait<rpc::WalkerBoneControlOut>("get_bones_transform", walker);
return res;
}
void Client::SetBonesTransform(rpc::ActorId walker, const rpc::WalkerBoneControlIn &bones) {
_pimpl->AsyncCall("set_bones_transform", walker, bones);
}
void Client::BlendPose(rpc::ActorId walker, float blend) {
_pimpl->AsyncCall("blend_pose", walker, blend);
}
void Client::GetPoseFromAnimation(rpc::ActorId walker) {
_pimpl->AsyncCall("get_pose_from_animation", walker);
}
void Client::SetTrafficLightState(

View File

@ -16,20 +16,23 @@
#include "carla/rpc/AttachmentType.h"
#include "carla/rpc/Command.h"
#include "carla/rpc/CommandResponse.h"
#include "carla/rpc/EnvironmentObject.h"
#include "carla/rpc/EpisodeInfo.h"
#include "carla/rpc/EpisodeSettings.h"
#include "carla/rpc/LabelledPoint.h"
#include "carla/rpc/LightState.h"
#include "carla/rpc/MapInfo.h"
#include "carla/rpc/MapLayer.h"
#include "carla/rpc/EnvironmentObject.h"
#include "carla/rpc/TrafficLightState.h"
#include "carla/rpc/VehiclePhysicsControl.h"
#include "carla/rpc/VehicleLightState.h"
#include "carla/rpc/WeatherParameters.h"
#include "carla/rpc/OpendriveGenerationParameters.h"
#include "carla/rpc/TrafficLightState.h"
#include "carla/rpc/VehicleDoor.h"
#include "carla/rpc/VehicleLightStateList.h"
#include "carla/rpc/VehicleLightState.h"
#include "carla/rpc/VehiclePhysicsControl.h"
#include "carla/rpc/VehicleWheels.h"
#include "carla/rpc/WeatherParameters.h"
#include "carla/rpc/Texture.h"
#include "carla/rpc/MaterialParameter.h"
#include <functional>
#include <memory>
@ -44,7 +47,8 @@ namespace rpc {
class DebugShape;
class VehicleControl;
class WalkerControl;
class WalkerBoneControl;
class WalkerBoneControlIn;
class WalkerBoneControlOut;
}
namespace sensor {
class SensorData;
@ -101,6 +105,18 @@ namespace detail {
void CopyOpenDriveToServer(
std::string opendrive, const rpc::OpendriveGenerationParameters & params);
void ApplyColorTextureToObjects(
const std::vector<std::string> &objects_name,
const rpc::MaterialParameter& parameter,
const rpc::TextureColor& Texture);
void ApplyColorTextureToObjects(
const std::vector<std::string> &objects_name,
const rpc::MaterialParameter& parameter,
const rpc::TextureFloatColor& Texture);
std::vector<std::string> GetNamesOfAllObjects() const;
rpc::EpisodeInfo GetEpisodeInfo();
rpc::MapInfo GetMapInfo();
@ -145,6 +161,14 @@ namespace detail {
rpc::ActorId vehicle,
const rpc::VehicleLightState &light_state);
void OpenVehicleDoor(
rpc::ActorId vehicle,
const rpc::VehicleDoor door_idx);
void CloseVehicleDoor(
rpc::ActorId vehicle,
const rpc::VehicleDoor door_idx);
rpc::Actor SpawnActor(
const rpc::ActorDescription &description,
const geom::Transform &transform);
@ -258,9 +282,19 @@ namespace detail {
rpc::ActorId walker,
const rpc::WalkerControl &control);
void ApplyBoneControlToWalker(
rpc::WalkerBoneControlOut GetBonesTransform(
rpc::ActorId walker);
void SetBonesTransform(
rpc::ActorId walker,
const rpc::WalkerBoneControl &control);
const rpc::WalkerBoneControlIn &bones);
void BlendPose(
rpc::ActorId walker,
float blend);
void GetPoseFromAnimation(
rpc::ActorId walker);
void SetTrafficLightState(
rpc::ActorId traffic_light,

View File

@ -101,6 +101,12 @@ namespace detail {
nav->SetPedestriansCrossFactor(percentage);
}
void SetPedestriansSeed(unsigned int seed) {
auto nav = _navigation.load();
DEBUG_ASSERT(nav != nullptr);
nav->SetPedestriansSeed(seed);
}
void AddPendingException(std::string e) {
_pending_exceptions = true;
_pending_exceptions_msg = e;

View File

@ -308,6 +308,13 @@ namespace detail {
navigation->SetPedestriansCrossFactor(percentage);
}
void Simulator::SetPedestriansSeed(unsigned int seed) {
DEBUG_ASSERT(_episode != nullptr);
auto navigation = _episode->CreateNavigationIfMissing();
DEBUG_ASSERT(navigation != nullptr);
navigation->SetPedestriansSeed(seed);
}
// ===========================================================================
// -- General operations with actors -----------------------------------------
// ===========================================================================
@ -380,6 +387,28 @@ namespace detail {
_client.FreezeAllTrafficLights(frozen);
}
// =========================================================================
/// -- Texture updating operations
// =========================================================================
void Simulator::ApplyColorTextureToObjects(
const std::vector<std::string> &objects_name,
const rpc::MaterialParameter& parameter,
const rpc::TextureColor& Texture) {
_client.ApplyColorTextureToObjects(objects_name, parameter, Texture);
}
void Simulator::ApplyColorTextureToObjects(
const std::vector<std::string> &objects_name,
const rpc::MaterialParameter& parameter,
const rpc::TextureFloatColor& Texture) {
_client.ApplyColorTextureToObjects(objects_name, parameter, Texture);
}
std::vector<std::string> Simulator::GetNamesOfAllObjects() const {
return _client.GetNamesOfAllObjects();
}
} // namespace detail
} // namespace client
} // namespace carla

View File

@ -25,6 +25,8 @@
#include "carla/rpc/VehicleLightStateList.h"
#include "carla/rpc/LabelledPoint.h"
#include "carla/rpc/VehicleWheels.h"
#include "carla/rpc/Texture.h"
#include "carla/rpc/MaterialParameter.h"
#include <boost/optional.hpp>
@ -294,6 +296,8 @@ namespace detail {
void SetPedestriansCrossFactor(float percentage);
void SetPedestriansSeed(unsigned int seed);
/// @}
// =========================================================================
/// @name General operations with actors
@ -457,8 +461,20 @@ namespace detail {
_client.ApplyControlToWalker(walker.GetId(), control);
}
void ApplyBoneControlToWalker(Walker &walker, const rpc::WalkerBoneControl &control) {
_client.ApplyBoneControlToWalker(walker.GetId(), control);
rpc::WalkerBoneControlOut GetBonesTransform(Walker &walker) {
return _client.GetBonesTransform(walker.GetId());
}
void SetBonesTransform(Walker &walker, const rpc::WalkerBoneControlIn &bones) {
return _client.SetBonesTransform(walker.GetId(), bones);
}
void BlendPose(Walker &walker, float blend) {
return _client.BlendPose(walker.GetId(), blend);
}
void GetPoseFromAnimation(Walker &walker) {
return _client.GetPoseFromAnimation(walker.GetId());
}
void ApplyPhysicsControlToVehicle(Vehicle &vehicle, const rpc::VehiclePhysicsControl &physicsControl) {
@ -469,6 +485,14 @@ namespace detail {
_client.SetLightStateToVehicle(vehicle.GetId(), light_state);
}
void OpenVehicleDoor(Vehicle &vehicle, const rpc::VehicleDoor door_idx) {
_client.OpenVehicleDoor(vehicle.GetId(), door_idx);
}
void CloseVehicleDoor(Vehicle &vehicle, const rpc::VehicleDoor door_idx) {
_client.CloseVehicleDoor(vehicle.GetId(), door_idx);
}
void SetWheelSteerDirection(Vehicle &vehicle, rpc::VehicleWheelLocation wheel_location, float angle_in_deg) {
_client.SetWheelSteerDirection(vehicle.GetId(), wheel_location, angle_in_deg);
}
@ -655,6 +679,24 @@ namespace detail {
void FreezeAllTrafficLights(bool frozen);
/// @}
// =========================================================================
/// @name Texture updating operations
// =========================================================================
/// @{
void ApplyColorTextureToObjects(
const std::vector<std::string> &objects_name,
const rpc::MaterialParameter& parameter,
const rpc::TextureColor& Texture);
void ApplyColorTextureToObjects(
const std::vector<std::string> &objects_name,
const rpc::MaterialParameter& parameter,
const rpc::TextureFloatColor& Texture);
std::vector<std::string> GetNamesOfAllObjects() const;
/// @}
private:

View File

@ -85,6 +85,10 @@ namespace detail {
_nav.SetPedestriansCrossFactor(percentage);
}
void SetPedestriansSeed(unsigned int seed) {
_nav.SetSeed(seed);
}
private:
Client &_client;

View File

@ -55,6 +55,10 @@ namespace geom {
return a * a;
}
static auto Cross(const Vector3D &a, const Vector3D &b) {
return Vector3D(a.y * b.z - a.z * b.y, a.z * b.x - a.x * b.z, a.x * b.y - a.y * b.x);
}
static auto Dot(const Vector3D &a, const Vector3D &b) {
return a.x * b.x + a.y * b.y + a.z * b.z;
}

View File

@ -67,6 +67,11 @@ namespace nav {
dtFreeNavMesh(_nav_mesh);
}
// set the seed to use with random numbers
void Navigation::SetSeed(unsigned int seed) {
srand(seed);
}
// load navigation data
bool Navigation::Load(const std::string &filename) {
std::ifstream f;

View File

@ -71,6 +71,8 @@ namespace nav {
bool GetAgentRoute(ActorId id, carla::geom::Location from, carla::geom::Location to,
std::vector<carla::geom::Location> &path, std::vector<unsigned char> &area);
/// set the seed to use with random numbers
void SetSeed(unsigned int seed);
/// create the crowd object
void CreateCrowd(void);
/// create a new walker

View File

@ -14,7 +14,7 @@
namespace carla {
namespace rpc {
using BoneTransformData = std::pair<std::string, geom::Transform>;
using BoneTransformDataIn = std::pair<std::string, geom::Transform>;
} // namespace rpc
} // namespace carla

View File

@ -0,0 +1,43 @@
// Copyright (c) 2019 Computer Vision Center (CVC) at the Universitat Autonoma
// de Barcelona (UAB).
//
// This work is licensed under the terms of the MIT license.
// For a copy, see <https://opensource.org/licenses/MIT>.
#pragma once
#include "carla/rpc/Transform.h"
#include <string>
#include <utility>
namespace carla {
namespace rpc {
// using BoneTransformDataOut = std::pair<std::string, geom::Transform>;
class BoneTransformDataOut
{
public:
std::string bone_name;
Transform world;
Transform component;
Transform relative;
bool operator!=(const BoneTransformDataOut &rhs) const {
return
bone_name != rhs.bone_name ||
world != rhs.world ||
component != rhs.component ||
relative != rhs.relative;
}
bool operator==(const BoneTransformDataOut &rhs) const {
return !(*this != rhs);
}
MSGPACK_DEFINE_ARRAY(bone_name, world, component, relative);
};
} // namespace rpc
} // namespace carla

View File

@ -0,0 +1,72 @@
// Copyright (c) 2021 Computer Vision Center (CVC) at the Universitat Autonoma
// de Barcelona (UAB).
//
// This work is licensed under the terms of the MIT license.
// For a copy, see <https://opensource.org/licenses/MIT>.
#pragma once
#include "carla/MsgPack.h"
#include <cstdint>
#ifdef LIBCARLA_INCLUDED_FROM_UE4
# include "Math/Color.h"
#endif // LIBCARLA_INCLUDED_FROM_UE4
namespace carla {
namespace rpc {
#pragma pack(push, 1)
struct FloatColor {
public:
float r = 0.f;
float g = 0.f;
float b = 0.f;
float a = 1.f;
FloatColor() = default;
FloatColor(const FloatColor &) = default;
FloatColor(float r, float g, float b, float a = 1.f)
: r(r), g(g), b(b), a(a) {}
FloatColor &operator=(const FloatColor &) = default;
bool operator==(const FloatColor &rhs) const {
return (r == rhs.r) && (g == rhs.g) && (b == rhs.b) && (a == rhs.a);
}
bool operator!=(const FloatColor &rhs) const {
return !(*this == rhs);
}
#ifdef LIBCARLA_INCLUDED_FROM_UE4
FloatColor(const FColor &color)
: FloatColor(color.R / 255.f, color.G / 255.f, color.B / 255.f, color.A / 255.f) {}
FloatColor(const FLinearColor &color)
: FloatColor(color.R, color.G, color.B, color.A) {}
FColor ToFColor() const {
return FColor{
static_cast<uint8>(r * 255),
static_cast<uint8>(g * 255),
static_cast<uint8>(b * 255),
static_cast<uint8>(a * 255)};
}
operator FLinearColor() const {
return FLinearColor{ r, g, b, a };
}
#endif // LIBCARLA_INCLUDED_FROM_UE4
MSGPACK_DEFINE_ARRAY(r, g, b, a);
};
#pragma pack(pop)
} // namespace rpc
} // namespace carla

View File

@ -0,0 +1,25 @@
// Copyright (c) 2021 Computer Vision Center (CVC) at the Universitat Autonoma
// de Barcelona (UAB).
//
// This work is licensed under the terms of the MIT license.
// For a copy, see <https://opensource.org/licenses/MIT>.
#include "MaterialParameter.h"
namespace carla {
namespace rpc {
std::string MaterialParameterToString(MaterialParameter material_parameter)
{
switch(material_parameter)
{
case MaterialParameter::Tex_Normal: return "Normal";
case MaterialParameter::Tex_Ao_Roughness_Metallic_Emissive: return "AO / Roughness / Metallic / Emissive";
case MaterialParameter::Tex_Diffuse: return "Diffuse";
case MaterialParameter::Tex_Emissive: return "Emissive";
default: return "Invalid";
}
}
}
}

View File

@ -0,0 +1,29 @@
// Copyright (c) 2021 Computer Vision Center (CVC) at the Universitat Autonoma
// de Barcelona (UAB).
//
// This work is licensed under the terms of the MIT license.
// For a copy, see <https://opensource.org/licenses/MIT>.
#pragma once
#include "carla/MsgPack.h"
#include <cstdint>
namespace carla {
namespace rpc {
enum class MaterialParameter
{
Tex_Normal,
Tex_Ao_Roughness_Metallic_Emissive,
Tex_Diffuse,
Tex_Emissive
};
std::string MaterialParameterToString(MaterialParameter material_parameter);
} // namespace rpc
} // namespace carla
MSGPACK_ADD_ENUM(carla::rpc::MaterialParameter);

View File

@ -0,0 +1,70 @@
// Copyright (c) 2021 Computer Vision Center (CVC) at the Universitat Autonoma
// de Barcelona (UAB).
//
// This work is licensed under the terms of the MIT license.
// For a copy, see <https://opensource.org/licenses/MIT>.
#pragma once
#include "carla/MsgPack.h"
#include "carla/rpc/FloatColor.h"
#include "carla/sensor/data/Color.h"
#include <vector>
namespace carla {
namespace rpc {
template<typename T>
class Texture {
public:
Texture() = default;
Texture(uint32_t width, uint32_t height)
: _width(width), _height(height) {
_texture_data.resize(_width*_height);
}
uint32_t GetWidth() const {
return _width;
}
uint32_t GetHeight() const {
return _height;
}
void SetDimensions(uint32_t width, uint32_t height) {
_width = width;
_height = height;
_texture_data.resize(_width*_height);
}
T& At (uint32_t x, uint32_t y) {
return _texture_data[y*_width + x];
}
const T& At (uint32_t x, uint32_t y) const {
return _texture_data[y*_width + x];
}
const T* GetDataPtr() const {
return _texture_data.data();
}
private:
uint32_t _width = 0;
uint32_t _height = 0;
std::vector<T> _texture_data;
public:
MSGPACK_DEFINE_ARRAY(_width, _height, _texture_data);
};
using TextureColor = Texture<sensor::data::Color>;
using TextureFloatColor = Texture<FloatColor>;
}
}

View File

@ -0,0 +1,29 @@
// Copyright (c) 2021 Computer Vision Center (CVC) at the Universitat Autonoma
// de Barcelona (UAB).
//
// This work is licensed under the terms of the MIT license.
// For a copy, see <https://opensource.org/licenses/MIT>.
#pragma once
#include "carla/MsgPack.h"
#include <cstdint>
namespace carla {
namespace rpc {
enum class VehicleDoor : uint8_t {
FL = 0,
FR = 1,
RL = 2,
RR = 3,
Hood = 4,
Trunk = 5,
All = 6
};
} // namespace rpc
} // namespace carla
MSGPACK_ADD_ENUM(carla::rpc::VehicleDoor);

View File

@ -7,12 +7,12 @@
#pragma once
#include "carla/MsgPack.h"
#include "carla/rpc/BoneTransformData.h"
#include "carla/rpc/BoneTransformDataIn.h"
#include "carla/rpc/String.h"
#include "carla/rpc/Transform.h"
#ifdef LIBCARLA_INCLUDED_FROM_UE4
# include "Carla/Walker/WalkerBoneControl.h"
# include "Carla/Walker/WalkerBoneControlIn.h"
#endif // LIBCARLA_INCLUDED_FROM_UE4
#include <vector>
@ -20,19 +20,19 @@
namespace carla {
namespace rpc {
class WalkerBoneControl {
class WalkerBoneControlIn {
public:
WalkerBoneControl() = default;
WalkerBoneControlIn() = default;
explicit WalkerBoneControl(
std::vector<rpc::BoneTransformData> bone_transforms)
explicit WalkerBoneControlIn(
std::vector<rpc::BoneTransformDataIn> bone_transforms)
: bone_transforms(bone_transforms) {}
#ifdef LIBCARLA_INCLUDED_FROM_UE4
operator FWalkerBoneControl() const {
FWalkerBoneControl Control;
operator FWalkerBoneControlIn() const {
FWalkerBoneControlIn Control;
for (auto &bone_transform : bone_transforms) {
Control.BoneTransforms.Add(ToFString(bone_transform.first), bone_transform.second);
}
@ -41,7 +41,7 @@ namespace rpc {
#endif // LIBCARLA_INCLUDED_FROM_UE4
std::vector<rpc::BoneTransformData> bone_transforms;
std::vector<rpc::BoneTransformDataIn> bone_transforms;
MSGPACK_DEFINE_ARRAY(bone_transforms);
};

View File

@ -0,0 +1,38 @@
// Copyright (c) 2019 Computer Vision Center (CVC) at the Universitat Autonoma
// de Barcelona (UAB).
//
// This work is licensed under the terms of the MIT license.
// For a copy, see <https://opensource.org/licenses/MIT>.
#pragma once
#include "carla/MsgPack.h"
#include "carla/rpc/BoneTransformDataOut.h"
#include "carla/rpc/String.h"
#include "carla/rpc/Transform.h"
#ifdef LIBCARLA_INCLUDED_FROM_UE4
# include "Carla/Walker/WalkerBoneControlOut.h"
#endif // LIBCARLA_INCLUDED_FROM_UE4
#include <vector>
namespace carla {
namespace rpc {
class WalkerBoneControlOut {
public:
WalkerBoneControlOut() = default;
explicit WalkerBoneControlOut(
std::vector<rpc::BoneTransformDataOut> bone_transforms)
: bone_transforms(bone_transforms) {}
std::vector<rpc::BoneTransformDataOut> bone_transforms;
MSGPACK_DEFINE_ARRAY(bone_transforms);
};
} // namespace rpc
} // namespace carla

View File

@ -144,6 +144,11 @@ public:
/// @brief destructor
~RssCheck();
/// @brief get the logger of this
std::shared_ptr<spdlog::logger> GetLogger() {
return _logger;
}
/// @brief main function to trigger the RSS check at a certain point in time
///
/// This function has to be called cyclic with increasing timestamps to ensure

View File

@ -22,11 +22,19 @@ RssRestrictor::RssRestrictor() {
if (!_logger) {
_logger = spdlog::create<spdlog::sinks::stdout_color_sink_st>(logger_name);
}
//_logger->set_level(spdlog::level::debug);
SetLogLevel(spdlog::level::warn);
}
RssRestrictor::~RssRestrictor() = default;
void RssRestrictor::SetLogLevel(const uint8_t log_level) {
if (log_level < spdlog::level::n_levels) {
const auto log_level_value = static_cast<spdlog::level::level_enum>(log_level);
_logger->set_level(log_level_value);
}
}
carla::rpc::VehicleControl RssRestrictor::RestrictVehicleControl(
const carla::rpc::VehicleControl &vehicle_control, const ::ad::rss::state::ProperResponse &proper_response,
const carla::rss::EgoDynamicsOnRoute &ego_dynamics_on_route,

View File

@ -50,6 +50,8 @@ public:
const carla::rss::EgoDynamicsOnRoute &ego_dynamics_on_route,
const carla::rpc::VehiclePhysicsControl &vehicle_physics);
void SetLogLevel(const uint8_t log_level);
private:
/// @brief the logger instance
std::shared_ptr<spdlog::logger> _logger;

View File

@ -22,12 +22,15 @@
namespace carla {
namespace client {
std::atomic_uint RssSensor::_global_map_initialization_counter_{0u};
RssSensor::RssSensor(ActorInitializer init) : Sensor(std::move(init)), _on_tick_register_id(0u), _drop_route(false) {}
RssSensor::~RssSensor() {
// ensure there is no processing anymore when deleting rss_check object
const std::lock_guard<std::mutex> lock(_processing_lock);
_rss_check.reset();
// ensure there is no processing anymore
if (IsListening()) {
Stop();
}
}
void RssSensor::RegisterActorConstellationCallback(ActorConstellationCallbackFunctionType callback) {
@ -68,12 +71,16 @@ void RssSensor::Listen(CallbackFunctionType callback) {
DEBUG_ASSERT(map != nullptr);
std::string const open_drive_content = map->GetOpenDrive();
_rss_check = nullptr;
::ad::map::access::cleanup();
auto mapInitializationResult = ::ad::map::access::initFromOpenDriveContent(
open_drive_content, 0.2, ::ad::map::intersection::IntersectionType::TrafficLight,
::ad::map::landmark::TrafficLightType::LEFT_STRAIGHT_RED_YELLOW_GREEN);
::ad::map::access::initFromOpenDriveContent(open_drive_content, 0.2,
::ad::map::intersection::IntersectionType::TrafficLight,
::ad::map::landmark::TrafficLightType::LEFT_STRAIGHT_RED_YELLOW_GREEN);
if (!mapInitializationResult) {
log_error(GetDisplayId(), ": Initialization of map failed");
return;
}
_global_map_initialization_counter_++;
if (_rss_actor_constellation_callback == nullptr) {
_rss_check = std::make_shared<::carla::rss::RssCheck>(max_steering_angle);
@ -84,15 +91,13 @@ void RssSensor::Listen(CallbackFunctionType callback) {
auto self = boost::static_pointer_cast<RssSensor>(shared_from_this());
_last_processed_frame=0u;
log_debug(GetDisplayId(), ": subscribing to tick event");
_on_tick_register_id = GetEpisode().Lock()->RegisterOnTickEvent(
[ cb = std::move(callback), weak_self = WeakPtr<RssSensor>(self) ](const auto &snapshot) {
auto self = weak_self.lock();
if (self != nullptr) {
auto data = self->TickRssSensor(snapshot.GetTimestamp());
if (data != nullptr) {
cb(std::move(data));
}
self->TickRssSensor(snapshot.GetTimestamp(), cb);
}
});
}
@ -106,6 +111,25 @@ void RssSensor::Stop() {
log_debug(GetDisplayId(), ": unsubscribing from tick event");
GetEpisode().Lock()->RemoveOnTickEvent(_on_tick_register_id);
_on_tick_register_id = 0u;
if ( bool(_rss_check) ) {
_rss_check->GetLogger()->info("RssSensor stopping");
}
// don't remove the braces since they protect the lock_guard
{
// ensure there is no processing anymore when deleting rss_check object
const std::lock_guard<std::mutex> lock(_processing_lock);
if ( bool(_rss_check) ) {
_rss_check->GetLogger()->info("RssSensor delete checker");
}
_rss_check.reset();
auto const map_initialization_counter_value = _global_map_initialization_counter_--;
if (map_initialization_counter_value == 0u) {
// last one stop listening is cleaning up the map
::ad::map::access::cleanup();
}
}
}
void RssSensor::SetLogLevel(const uint8_t &log_level) {
@ -269,59 +293,84 @@ void RssSensor::DropRoute() {
_drop_route = true;
}
SharedPtr<sensor::SensorData> RssSensor::TickRssSensor(const Timestamp &timestamp) {
void RssSensor::TickRssSensor(const client::Timestamp &timestamp, CallbackFunctionType callback) {
if (_processing_lock.try_lock()) {
if (!bool(_rss_check)){
_processing_lock.unlock();
return;
}
if ((timestamp.frame < _last_processed_frame) && ((_last_processed_frame - timestamp.frame) < 0xffffffffu)) {
_processing_lock.unlock();
_rss_check->GetLogger()->warn("RssSensor[{}] outdated tick dropped, LastProcessed={}", timestamp.frame, _last_processed_frame);
return;
}
_last_processed_frame = timestamp.frame;
SharedPtr<carla::client::ActorList> actors = GetWorld().GetActors();
auto const settings = GetWorld().GetSettings();
if ( settings.synchronous_mode ) {
_rss_check->GetLogger()->trace("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);
_tick_future = std::async(&RssSensor::TickRssSensorThreadLocked, this, timestamp, actors, callback);
}
} else {
if (bool(_rss_check)){
_rss_check->GetLogger()->debug("RssSensor[{}] tick dropped", timestamp.frame);
}
}
}
void RssSensor::TickRssSensorThreadLocked(const client::Timestamp &timestamp,
SharedPtr<carla::client::ActorList> actors, CallbackFunctionType callback) {
try {
bool result = false;
double const time_since_epoch_check_start_ms =
std::chrono::duration<double, std::milli>(std::chrono::system_clock::now().time_since_epoch()).count();
if (_drop_route) {
_drop_route = false;
_rss_check->DropRoute();
}
// check all object<->ego pairs with RSS and calculate proper response
::ad::rss::state::ProperResponse response;
::ad::rss::state::RssStateSnapshot rss_state_snapshot;
::ad::rss::situation::SituationSnapshot situation_snapshot;
::ad::rss::world::WorldModel world_model;
carla::rss::EgoDynamicsOnRoute ego_dynamics_on_route;
if (_processing_lock.try_lock()) {
spdlog::debug("RssSensor tick: T={}", timestamp.frame);
auto const result = _rss_check->CheckObjects(timestamp, actors, GetParent(), response, rss_state_snapshot,
situation_snapshot, world_model, ego_dynamics_on_route);
if ((timestamp.frame < _last_processed_frame) && ((_last_processed_frame - timestamp.frame) < 0xffffffffu))
{
_processing_lock.unlock();
spdlog::warn("RssSensor tick dropped: T={}", timestamp.frame);
return nullptr;
}
_last_processed_frame = timestamp.frame;
carla::client::World world = GetWorld();
SharedPtr<carla::client::ActorList> actors = world.GetActors();
if (_drop_route) {
_drop_route = false;
_rss_check->DropRoute();
}
// check all object<->ego pairs with RSS and calculate proper response
result = _rss_check->CheckObjects(timestamp, actors, GetParent(), response, rss_state_snapshot,
situation_snapshot, world_model, ego_dynamics_on_route);
_processing_lock.unlock();
spdlog::debug(
"RssSensor response: T={} S:{}->E:{} DeltaT:{}", timestamp.frame,
ego_dynamics_on_route.time_since_epoch_check_start_ms, ego_dynamics_on_route.time_since_epoch_check_end_ms,
ego_dynamics_on_route.time_since_epoch_check_end_ms - ego_dynamics_on_route.time_since_epoch_check_start_ms);
return MakeShared<sensor::data::RssResponse>(timestamp.frame, timestamp.elapsed_seconds, GetTransform(), result,
response, rss_state_snapshot, situation_snapshot, world_model,
ego_dynamics_on_route);
} else {
spdlog::debug("RssSensor tick dropped: T={}", timestamp.frame);
return nullptr;
double const time_since_epoch_check_end_ms =
std::chrono::duration<double, std::milli>(std::chrono::system_clock::now().time_since_epoch()).count();
auto const delta_time_ms = time_since_epoch_check_end_ms - time_since_epoch_check_start_ms;
_rss_check->GetLogger()->debug("RssSensor[{}] response: S:{}->E:{} DeltaT:{}", timestamp.frame,
time_since_epoch_check_start_ms, time_since_epoch_check_end_ms,
delta_time_ms);
_rss_check_timings.push_back(delta_time_ms);
while (_rss_check_timings.size() > 10u) {
_rss_check_timings.pop_front();
}
double agv_time=0.;
for (auto run_time: _rss_check_timings) {
agv_time += run_time;
}
agv_time /= _rss_check_timings.size();
_rss_check->GetLogger()->info("RssSensor[{}] runtime {} avg {}", timestamp.frame, delta_time_ms, agv_time);
_processing_lock.unlock();
callback(MakeShared<sensor::data::RssResponse>(timestamp.frame, timestamp.elapsed_seconds, GetTransform(), result,
response, rss_state_snapshot, situation_snapshot, world_model,
ego_dynamics_on_route));
} catch (const std::exception &e) {
/// @todo do we need to unsubscribe the sensor here?
std::cout << e.what() << std::endl;
_rss_check->GetLogger()->error("RssSensor[{}] tick exception", timestamp.frame);
_processing_lock.unlock();
spdlog::error("RssSensor tick exception");
return nullptr;
} catch (...) {
_rss_check->GetLogger()->error("RssSensor[{}] tick exception", timestamp.frame);
_processing_lock.unlock();
spdlog::error("RssSensor tick exception");
return nullptr;
}
}

View File

@ -5,6 +5,9 @@
#pragma once
#include <atomic>
#include <future>
#include <list>
#include <memory>
#include <mutex>
#include <vector>
@ -66,6 +69,7 @@ public:
void Listen(CallbackFunctionType callback) override;
/// Stop listening for new measurements.
/// Be aware: GIL has to be unlocked to be able to wait for callbacks not active.
void Stop() override;
/// Return whether this Sensor instance is currently listening to the
@ -123,7 +127,12 @@ public:
private:
/// the acutal sensor tick callback function
SharedPtr<sensor::SensorData> TickRssSensor(const Timestamp &timestamp);
void TickRssSensor(const client::Timestamp &timestamp, CallbackFunctionType callback);
void TickRssSensorThreadLocked(const client::Timestamp &timestamp, SharedPtr<carla::client::ActorList> actors,
CallbackFunctionType callback);
//// the object actually performing the RSS processing
std::shared_ptr<::carla::rss::RssCheck> _rss_check;
/// the id got when registering for the on tick event
std::size_t _on_tick_register_id;
@ -131,8 +140,11 @@ private:
/// the mutex to protect the actual RSS processing and in case it takes too long to process ever frame
std::mutex _processing_lock;
//// the object actually performing the RSS processing
std::shared_ptr<::carla::rss::RssCheck> _rss_check;
/// the future for the async ticking thread
std::future<void> _tick_future;
/// some debug timings
std::list<double> _rss_check_timings;
//// the rss actor constellation callback function
ActorConstellationCallbackFunctionType _rss_actor_constellation_callback;
@ -142,6 +154,8 @@ private:
/// last processed frame
std::size_t _last_processed_frame;
static std::atomic_uint _global_map_initialization_counter_;
};
} // namespace client

View File

@ -41,6 +41,7 @@ class ARayCastSemanticLidar;
class ARayCastLidar;
class ASceneCaptureCamera;
class ASemanticSegmentationCamera;
class AInstanceSegmentationCamera;
class ARssSensor;
class FWorldObserver;
@ -69,6 +70,7 @@ namespace sensor {
std::pair<ARssSensor *, s11n::NoopSerializer>,
std::pair<ASceneCaptureCamera *, s11n::ImageSerializer>,
std::pair<ASemanticSegmentationCamera *, s11n::ImageSerializer>,
std::pair<AInstanceSegmentationCamera *, s11n::ImageSerializer>,
std::pair<FWorldObserver *, s11n::EpisodeStateSerializer>
>;
@ -94,6 +96,7 @@ namespace sensor {
#include "Carla/Sensor/RssSensor.h"
#include "Carla/Sensor/SceneCaptureCamera.h"
#include "Carla/Sensor/SemanticSegmentationCamera.h"
#include "Carla/Sensor/InstanceSegmentationCamera.h"
#include "Carla/Sensor/WorldObserver.h"
#endif // LIBCARLA_SENSOR_REGISTRY_WITH_SENSOR_INCLUDES

View File

@ -7,6 +7,7 @@
#pragma once
#include "carla/rpc/Color.h"
#include "carla/rpc/FloatColor.h"
#include <cstdint>
@ -36,11 +37,15 @@ namespace data {
operator rpc::Color() const {
return {r, g, b};
}
operator rpc::FloatColor() const {
return {r/255.f, g/255.f, b/255.f, a/255.f};
}
uint8_t b = 0u;
uint8_t g = 0u;
uint8_t r = 0u;
uint8_t a = 0u;
MSGPACK_DEFINE_ARRAY(r, g, b, a);
};
#pragma pack(pop)

View File

@ -127,7 +127,7 @@ namespace tcp {
ReadData();
} else {
// Else try again.
log_info("streaming client: failed to send stream id:", ec.message());
log_debug("streaming client: failed to send stream id:", ec.message());
Connect();
}
}));
@ -186,7 +186,7 @@ namespace tcp {
ReadData();
} else {
// As usual, if anything fails start over from the very top.
log_info("streaming client: failed to read data:", ec.message());
log_debug("streaming client: failed to read data:", ec.message());
Connect();
}
};
@ -207,7 +207,7 @@ namespace tcp {
message->buffer(),
boost::asio::bind_executor(_strand, handle_read_data));
} else if (!_done) {
log_info("streaming client: failed to read header:", ec.message());
log_debug("streaming client: failed to read header:", ec.message());
DEBUG_ONLY(log_debug("size = ", message->size()));
DEBUG_ONLY(log_debug("bytes = ", bytes));
Connect();

View File

@ -27,6 +27,7 @@ ALSM::ALSM(
CollisionStage &collision_stage,
TrafficLightStage &traffic_light_stage,
MotionPlanStage &motion_plan_stage,
VehicleLightStage &vehicle_light_stage,
RandomGeneratorMap &random_devices)
: registered_vehicles(registered_vehicles),
buffer_map(buffer_map),
@ -40,6 +41,7 @@ ALSM::ALSM(
collision_stage(collision_stage),
traffic_light_stage(traffic_light_stage),
motion_plan_stage(motion_plan_stage),
vehicle_light_stage(vehicle_light_stage),
random_devices(random_devices) {}
void ALSM::Update() {
@ -378,6 +380,7 @@ void ALSM::RemoveActor(const ActorId actor_id, const bool registered_actor) {
collision_stage.RemoveActor(actor_id);
traffic_light_stage.RemoveActor(actor_id);
motion_plan_stage.RemoveActor(actor_id);
vehicle_light_stage.RemoveActor(actor_id);
}
else {
unregistered_actors.erase(actor_id);

View File

@ -18,6 +18,7 @@
#include "carla/trafficmanager/RandomGenerator.h"
#include "carla/trafficmanager/SimulationState.h"
#include "carla/trafficmanager/TrafficLightStage.h"
#include "carla/trafficmanager/VehicleLightStage.h"
namespace carla {
namespace traffic_manager {
@ -59,6 +60,7 @@ private:
CollisionStage &collision_stage;
TrafficLightStage &traffic_light_stage;
MotionPlanStage &motion_plan_stage;
VehicleLightStage &vehicle_light_stage;
// Time elapsed since last vehicle destruction due to being idle for too long.
double elapsed_last_actor_destruction {0.0};
cc::Timestamp current_timestamp;
@ -102,6 +104,7 @@ public:
CollisionStage &collision_stage,
TrafficLightStage &traffic_light_stage,
MotionPlanStage &motion_plan_stage,
VehicleLightStage &vehicle_light_stage,
RandomGeneratorMap &random_devices);
void Update();

View File

@ -35,6 +35,7 @@ namespace traffic_manager {
this->geodesic_grid_id = simple_waypoint->GetGeodesicGridId();
this->is_junction = simple_waypoint->CheckJunction();
this->road_option = static_cast<uint8_t>(simple_waypoint->GetRoadOption());
}
void CachedSimpleWaypoint::Write(std::ofstream &out_file) {
@ -70,6 +71,9 @@ namespace traffic_manager {
// is_junction
WriteValue<bool>(out_file, this->is_junction);
// road_option
WriteValue<uint8_t>(out_file, this->road_option);
}
void CachedSimpleWaypoint::Read(std::ifstream &in_file) {
@ -109,6 +113,9 @@ namespace traffic_manager {
// is_junction
ReadValue<bool>(in_file, this->is_junction);
// road_option
ReadValue<uint8_t>(in_file, this->road_option);
}
void CachedSimpleWaypoint::Read(const std::vector<uint8_t>& content, unsigned long& start) {
@ -147,6 +154,9 @@ namespace traffic_manager {
// is_junction
ReadValue<bool>(content, start, this->is_junction);
// road_option
ReadValue<uint8_t>(content, start, this->road_option);
}
} // namespace traffic_manager

View File

@ -28,6 +28,7 @@ namespace traffic_manager {
uint64_t next_right_waypoint = 0;
int32_t geodesic_grid_id;
bool is_junction;
uint8_t road_option;
CachedSimpleWaypoint() = default;
CachedSimpleWaypoint(const SimpleWaypointPtr& simple_waypoint);

View File

@ -45,13 +45,18 @@ void CollisionStage::Update(const unsigned long index) {
ActorIdSet overlapping_actors = track_traffic.GetOverlappingVehicles(ego_actor_id);
std::vector<ActorId> collision_candidate_ids;
// Run through vehicles with overlapping paths and filter them;
float value = SQUARE(COLLISION_RADIUS_RATE * velocity + COLLISION_RADIUS_MIN) + parameters.GetDistanceToLeadingVehicle(ego_actor_id);
float collision_radius_square = value;
if (velocity < 1.0f) {
collision_radius_square = SQUARE(COLLISION_RADIUS_STOP) + parameters.GetDistanceToLeadingVehicle(ego_actor_id);
const float distance_to_leading = parameters.GetDistanceToLeadingVehicle(ego_actor_id);
float collision_radius_square = SQUARE(COLLISION_RADIUS_RATE * velocity + COLLISION_RADIUS_MIN);
if (velocity < 2.0f) {
const float length = simulation_state.GetDimensions(ego_actor_id).x;
const float collision_radius_stop = COLLISION_RADIUS_STOP + length;
collision_radius_square = SQUARE(collision_radius_stop);
}
if (distance_to_leading > collision_radius_square) {
collision_radius_square = SQUARE(distance_to_leading);
}
for (ActorId overlapping_actor_id : overlapping_actors) {
// If actor is within maximum collision avoidance and vertical overlap range.
const cg::Location &overlapping_actor_location = simulation_state.GetLocation(overlapping_actor_id);
@ -116,8 +121,9 @@ float CollisionStage::GetBoundingBoxExtention(const ActorId actor_id) {
const float velocity = cg::Math::Dot(simulation_state.GetVelocity(actor_id), simulation_state.GetHeading(actor_id));
float bbox_extension;
// Using a linear function to calculate boundary length.
bbox_extension = BOUNDARY_EXTENSION_RATE * velocity + BOUNDARY_EXTENSION_MINIMUM;
// Using a function to calculate boundary length.
float velocity_extension = VEL_EXT_FACTOR * velocity;
bbox_extension = BOUNDARY_EXTENSION_MINIMUM + velocity_extension * velocity_extension;
// If a valid collision lock present, change boundary length to maintain lock.
if (collision_locks.find(actor_id) != collision_locks.end()) {
const CollisionLock &lock = collision_locks.at(actor_id);

View File

@ -38,20 +38,21 @@ static const float PHYSICS_RADIUS = 50.0f;
} // namespace HybridMode
namespace SpeedThreshold {
static const float HIGHWAY_SPEED = 50.0f / 3.6f;
static const float HIGHWAY_SPEED = 60.0f / 3.6f;
static const float AFTER_JUNCTION_MIN_SPEED = 5.0f / 3.6f;
static const float INITIAL_PERCENTAGE_SPEED_DIFFERENCE = 30.0f;
static const float INITIAL_PERCENTAGE_SPEED_DIFFERENCE = 0.0f;
} // namespace SpeedThreshold
namespace PathBufferUpdate {
static const float MAX_START_DISTANCE = 20.0f;
static const float MINIMUM_HORIZON_LENGTH = 20.0f;
static const float HORIZON_RATE = 1.45f;
static const float MINIMUM_HORIZON_LENGTH = 15.0f;
static const float HORIZON_RATE = 2.0f;
static const float HIGH_SPEED_HORIZON_RATE = 4.0f;
} // namespace PathBufferUpdate
namespace WaypointSelection {
static const float TARGET_WAYPOINT_TIME_HORIZON = 0.5f;
static const float TARGET_WAYPOINT_HORIZON_LENGTH = 1.0f;
static const float TARGET_WAYPOINT_TIME_HORIZON = 0.3f;
static const float MIN_TARGET_WAYPOINT_DISTANCE = 3.0f;
static const float JUNCTION_LOOK_AHEAD = 5.0f;
static const float SAFE_DISTANCE_AFTER_JUNCTION = 4.0f;
static const float MIN_JUNCTION_LENGTH = 8.0f;
@ -59,27 +60,33 @@ static const float MIN_SAFE_INTERVAL_LENGTH = 0.5f * SAFE_DISTANCE_AFTER_JUNCTIO
} // namespace WaypointSelection
namespace LaneChange {
static const float MINIMUM_LANE_CHANGE_DISTANCE = 15.0f;
static const float MINIMUM_LANE_CHANGE_DISTANCE = 20.0f;
static const float MAXIMUM_LANE_OBSTACLE_DISTANCE = 50.0f;
static const float MAXIMUM_LANE_OBSTACLE_CURVATURE = 0.6f;
static const float INTER_LANE_CHANGE_DISTANCE = 10.0f;
static const float MIN_WPT_DISTANCE = 5.0f;
static const float MAX_WPT_DISTANCE = 20.0f;
static const float MIN_LANE_CHANGE_SPEED = 5.0f;
static const float FIFTYPERC = 50.0f;
} // namespace LaneChange
namespace Collision {
static const float BOUNDARY_EXTENSION_MINIMUM = 2.5f;
static const float BOUNDARY_EXTENSION_RATE = 1.35f;
static const float BOUNDARY_EXTENSION_RATE = 4.35f;
static const float COS_10_DEGREES = 0.9848f;
static const float OVERLAP_THRESHOLD = 0.1f;
static const float LOCKING_DISTANCE_PADDING = 4.0f;
static const float COLLISION_RADIUS_STOP = 8.0f;
static const float COLLISION_RADIUS_MIN = 20.0f;
static const float COLLISION_RADIUS_RATE = 0.65f;
static const float COLLISION_RADIUS_RATE = 2.65f;
static const float MAX_LOCKING_EXTENSION = 10.0f;
static const float WALKER_TIME_EXTENSION = 1.5f;
static const float SQUARE_ROOT_OF_TWO = 1.414f;
static const float VERTICAL_OVERLAP_THRESHOLD = 4.0f;
static const float EPSILON = 2.0f * std::numeric_limits<float>::epsilon();
static const float MIN_REFERENCE_DISTANCE = 1.0f;
static const float MIN_REFERENCE_DISTANCE = 0.5f;
static const float MIN_VELOCITY_COLL_RADIUS = 2.0f;
static const float VEL_EXT_FACTOR = 0.36f;
} // namespace Collision
namespace FrameMemory {
@ -94,9 +101,10 @@ static const float MAX_GEODESIC_GRID_LENGTH = 20.0f;
static const float MAP_RESOLUTION = 5.0f;
static const float INV_MAP_RESOLUTION = 1.0f / MAP_RESOLUTION;
static const double MAX_WPT_DISTANCE = MAP_RESOLUTION/2.0 + SQUARE(MAP_RESOLUTION);
static const float MAX_WPT_RADIANS = 0.1745f; // 10º
static const float MAX_WPT_RADIANS = 0.087f; // 5º
static float const DELTA = 25.0f;
static float const Z_DELTA = 500.0f;
static float const STRAIGHT_DEG = 19.0f;
} // namespace Map
namespace TrafficLight {
@ -105,11 +113,9 @@ static const double DOUBLE_NO_SIGNAL_PASSTHROUGH_INTERVAL = 5.0;
} // namespace TrafficLight
namespace MotionPlan {
static const float RELATIVE_APPROACH_SPEED = 10.0f / 3.6f;
static const float RELATIVE_APPROACH_SPEED = 12.0f / 3.6f;
static const float MIN_FOLLOW_LEAD_DISTANCE = 2.0f;
static const float MAX_FOLLOW_LEAD_DISTANCE = 5.0f;
static const float FOLLOW_DISTANCE_RATE = 0.1f;
static const float CRITICAL_BRAKING_MARGIN = 0.25f;
static const float CRITICAL_BRAKING_MARGIN = 0.2f;
static const float EPSILON_RELATIVE_SPEED = 0.001f;
static const float MAX_JUNCTION_BLOCK_DISTANCE = 1.0f * WaypointSelection::SAFE_DISTANCE_AFTER_JUNCTION;
static const float TWO_KM = 2000.0f;
@ -123,19 +129,31 @@ static const float YIELD_TARGET_VELOCITY = 15.0f / 3.6f;
static const float FRICTION = 0.6f;
static const float GRAVITY = 9.81f;
static const float PI = 3.1415927f;
static const float PERC_MAX_SLOWDOWN = 0.08f;
static const float FOLLOW_LEAD_FACTOR = 2.0f;
} // namespace MotionPlan
namespace VehicleLight {
static const float SUN_ALTITUDE_DEGREES_BEFORE_DAWN = 15.0f;
static const float SUN_ALTITUDE_DEGREES_AFTER_SUNSET = 165.0f;
static const float SUN_ALTITUDE_DEGREES_JUST_AFTER_DAWN = 35.0f;
static const float SUN_ALTITUDE_DEGREES_JUST_BEFORE_SUNSET = 145.0f;
static const float HEAVY_PRECIPITATION_THRESHOLD = 80.0f;
static const float FOG_DENSITY_THRESHOLD = 20.0f;
static const float MAX_DISTANCE_LIGHT_CHECK = 225.0f;
} // namespace VehicleLight
namespace PID {
static const float MAX_THROTTLE = 0.85f;
static const float MAX_BRAKE = 1.0f;
static const float MAX_BRAKE = 0.7f;
static const float MAX_STEERING = 0.8f;
static const float MAX_STEERING_DIFF = 0.15f;
static const float DT = 0.05f;
static const float INV_DT = 1.0f / DT;
static const std::vector<float> LONGITUDIAL_PARAM = {12.0f, 0.05f, 0.02f};
static const std::vector<float> LONGITUDIAL_HIGHWAY_PARAM = {20.0f, 0.05f, 0.01f};
static const std::vector<float> LATERAL_PARAM = {5.0f, 0.02f, 0.8f};
static const std::vector<float> LATERAL_HIGHWAY_PARAM = {3.0f, 0.02f, 0.4f};
static const std::vector<float> LATERAL_PARAM = {4.0f, 0.02f, 0.08f};
static const std::vector<float> LATERAL_HIGHWAY_PARAM = {2.0f, 0.02f, 0.04f};
} // namespace PID
namespace TrackTraffic {

View File

@ -128,6 +128,9 @@ namespace traffic_manager {
WaypointPtr waypoint_ptr = _world_map->GetWaypointXODR(cached_wp.road_id, cached_wp.lane_id, cached_wp.s);
SimpleWaypointPtr wp = std::make_shared<SimpleWaypoint>(waypoint_ptr);
wp->SetGeodesicGridId(cached_wp.geodesic_grid_id);
wp->SetIsJunction(cached_wp.is_junction);
wp->SetRoadOption(static_cast<RoadOption>(cached_wp.road_option));
dense_topology.push_back(wp);
}
@ -227,8 +230,7 @@ namespace traffic_manager {
}
// 3. Processing waypoints.
auto distance_squared =
[](cg::Location l1, cg::Location l2) {
auto distance_squared = [](cg::Location l1, cg::Location l2) {
return cg::Math::DistanceSquared(l1, l2);
};
auto square = [](float input) {return std::pow(input, 2);};
@ -259,7 +261,7 @@ namespace traffic_manager {
// Adding more waypoints if the angle is too tight or if they are too distant.
for (std::size_t i = 0; i < segment_waypoints.size() - 1; ++i) {
double distance = std::abs(segment_waypoints.at(i)->GetWaypoint()->GetDistance() - segment_waypoints.at(i+1)->GetWaypoint()->GetDistance());
double angle = wpt_angle(segment_waypoints.at(i)->GetTransform().rotation.GetForwardVector(), segment_waypoints.at(i+1)->GetTransform().rotation.GetForwardVector());
double angle = wpt_angle(segment_waypoints.at(i)->GetTransform().GetForwardVector(), segment_waypoints.at(i+1)->GetTransform().GetForwardVector());
int16_t angle_splits = static_cast<int16_t>(angle/MAX_WPT_RADIANS);
int16_t distance_splits = static_cast<int16_t>((distance*distance)/MAX_WPT_DISTANCE);
auto max_splits = max(angle_splits, distance_splits);
@ -282,17 +284,19 @@ namespace traffic_manager {
// Placing intra-segment connections.
cg::Location grid_edge_location = segment_waypoints.front()->GetLocation();
for (std::size_t i = 0; i < segment_waypoints.size() - 1; ++i) {
SimpleWaypointPtr current_waypoint = segment_waypoints.at(i);
SimpleWaypointPtr next_waypoint = segment_waypoints.at(i+1);
// Assigning grid id.
if (distance_squared(grid_edge_location, segment_waypoints.at(i)->GetLocation()) >
if (distance_squared(grid_edge_location, current_waypoint->GetLocation()) >
square(MAX_GEODESIC_GRID_LENGTH)) {
++geodesic_grid_id_counter;
grid_edge_location = segment_waypoints.at(i)->GetLocation();
grid_edge_location = current_waypoint->GetLocation();
}
segment_waypoints.at(i)->SetGeodesicGridId(geodesic_grid_id_counter);
current_waypoint->SetGeodesicGridId(geodesic_grid_id_counter);
current_waypoint->SetNextWaypoint({next_waypoint});
next_waypoint->SetPreviousWaypoint({current_waypoint});
segment_waypoints.at(i)->SetNextWaypoint({segment_waypoints.at(i + 1)});
segment_waypoints.at(i + 1)->SetPreviousWaypoint({segment_waypoints.at(i)});
}
segment_waypoints.back()->SetGeodesicGridId(geodesic_grid_id_counter);
@ -326,14 +330,14 @@ namespace traffic_manager {
}
// Linking lane change connections.
for (auto &simple_waypoint:dense_topology) {
if (!simple_waypoint->CheckJunction()) {
FindAndLinkLaneChange(simple_waypoint);
for (auto &swp : dense_topology) {
if (!swp->CheckJunction()) {
FindAndLinkLaneChange(swp);
}
}
// Linking any unconnected segments.
for (auto &swp: dense_topology) {
for (auto &swp : dense_topology) {
if (swp->GetNextWaypoint().empty()) {
auto neighbour = swp->GetRightWaypoint();
if (!neighbour) {
@ -348,6 +352,9 @@ namespace traffic_manager {
}
}
}
// Specifying a RoadOption for each SimpleWaypoint
SetUpRoadOption();
}
void InMemoryMap::SetUpSpatialTree() {
@ -360,6 +367,95 @@ namespace traffic_manager {
}
}
void InMemoryMap::SetUpRoadOption() {
for (auto &swp : dense_topology) {
std::vector<SimpleWaypointPtr> next_waypoints = swp->GetNextWaypoint();
std::size_t next_swp_size = next_waypoints.size();
if (next_swp_size == 0) {
// No next waypoint means that this is an end of the road.
swp->SetRoadOption(RoadOption::RoadEnd);
}
else if (next_swp_size > 1 || (!swp->CheckJunction() && next_waypoints.front()->CheckJunction())) {
// To check if we are in an actual junction, and not on an highway, we try to see
// if there's a landmark nearby of type Traffic Light, Stop Sign or Yield Sign.
bool found_landmark= false;
if (next_swp_size <= 1) {
auto all_landmarks = swp->GetWaypoint()->GetAllLandmarksInDistance(15.0);
if (all_landmarks.empty()) {
// Landmark hasn't been found, this isn't a junction.
swp->SetRoadOption(RoadOption::LaneFollow);
} else {
for (auto &landmark : all_landmarks) {
auto landmark_type = landmark->GetType();
if (landmark_type == "1000001" || landmark_type == "206" || landmark_type == "205") {
// We found a landmark.
found_landmark= true;
break;
}
}
if (!found_landmark) {
swp->SetRoadOption(RoadOption::LaneFollow);
}
}
}
// If we did find a landmark, or we are in the other case, find all waypoints
// in the junction and assign the correct RoadOption.
if (found_landmark || next_swp_size > 1) {
swp->SetRoadOption(RoadOption::LaneFollow);
for (auto &next_swp : next_waypoints) {
std::vector<SimpleWaypointPtr> traversed_waypoints;
SimpleWaypointPtr junction_end_waypoint;
if (next_swp_size > 1) {
junction_end_waypoint = next_swp;
} else {
junction_end_waypoint = next_waypoints.front();
}
while (junction_end_waypoint->CheckJunction()){
traversed_waypoints.push_back(junction_end_waypoint);
std::vector<SimpleWaypointPtr> temp = junction_end_waypoint->GetNextWaypoint();
if (temp.empty()) {
break;
}
junction_end_waypoint = temp.front();
}
// Calculate the angle between the first and the last point of the junction.
int16_t current_angle = static_cast<int16_t>(traversed_waypoints.front()->GetTransform().rotation.yaw);
int16_t junction_end_angle = static_cast<int16_t>(traversed_waypoints.back()->GetTransform().rotation.yaw);
int16_t diff_angle = (junction_end_angle - current_angle) % 360;
bool straight = (diff_angle < STRAIGHT_DEG && diff_angle > -STRAIGHT_DEG) ||
(diff_angle > 360-STRAIGHT_DEG && diff_angle <= 360) ||
(diff_angle < -360+STRAIGHT_DEG && diff_angle >= -360);
bool right = (diff_angle >= STRAIGHT_DEG && diff_angle <= 180) ||
(diff_angle <= -180 && diff_angle >= -360+STRAIGHT_DEG);
auto assign_option = [](RoadOption ro, std::vector<SimpleWaypointPtr> traversed_waypoints) {
for (auto &twp : traversed_waypoints) {
twp->SetRoadOption(ro);
}
};
// Assign RoadOption according to the angle.
if (straight) assign_option(RoadOption::Straight, traversed_waypoints);
else if (right) assign_option(RoadOption::Right, traversed_waypoints);
else assign_option(RoadOption::Left, traversed_waypoints);
}
}
}
else if (next_swp_size == 1 && swp->GetRoadOption() == RoadOption::Void) {
swp->SetRoadOption(RoadOption::LaneFollow);
}
}
}
SimpleWaypointPtr InMemoryMap::GetWaypoint(const cg::Location loc) const {
Point3D query_point(loc.x, loc.y, loc.z);

View File

@ -75,8 +75,7 @@ namespace bgi = boost::geometry::index;
//bool Load(const std::string& filename);
bool Load(const std::vector<uint8_t>& content);
/// This method constructs the local map with a resolution of
/// sampling_resolution.
/// This method constructs the local map with a resolution of sampling_resolution.
void SetUp();
/// This method returns the closest waypoint to a given location on the map.
@ -85,8 +84,7 @@ namespace bgi = boost::geometry::index;
/// This method returns n waypoints in an delta area with a certain distance from the ego vehicle.
NodeList GetWaypointsInDelta(const cg::Location loc, const uint16_t n_points, const float random_sample) const;
/// This method returns the full list of discrete samples of the map in the
/// local cache.
/// This method returns the full list of discrete samples of the map in the local cache.
NodeList GetDenseTopology() const;
std::string GetMapName();
@ -98,6 +96,7 @@ namespace bgi = boost::geometry::index;
void SetUpDenseTopology();
void SetUpSpatialTree();
void SetUpRoadOption();
/// This method is used to find and place lane change links.
void FindAndLinkLaneChange(SimpleWaypointPtr reference_waypoint);

View File

@ -9,6 +9,9 @@ namespace traffic_manager {
using namespace constants::PathBufferUpdate;
using namespace constants::LaneChange;
using namespace constants::WaypointSelection;
using namespace constants::SpeedThreshold;
using namespace constants::Collision;
using namespace constants::MotionPlan;
LocalizationStage::LocalizationStage(
const std::vector<ActorId> &vehicle_id_list,
@ -28,7 +31,7 @@ LocalizationStage::LocalizationStage(
parameters(parameters),
marked_for_removal(marked_for_removal),
output_array(output_array),
random_devices(random_devices) {}
random_devices(random_devices){}
void LocalizationStage::Update(const unsigned long index) {
@ -39,7 +42,10 @@ void LocalizationStage::Update(const unsigned long index) {
const float vehicle_speed = vehicle_velocity_vector.Length();
// Speed dependent waypoint horizon length.
float horizon_length = vehicle_speed * HORIZON_RATE + MINIMUM_HORIZON_LENGTH;
float horizon_length = std::max(vehicle_speed * HORIZON_RATE, MINIMUM_HORIZON_LENGTH);
if (vehicle_speed > HIGHWAY_SPEED) {
horizon_length = std::max(vehicle_speed * HIGH_SPEED_HORIZON_RATE, MINIMUM_HORIZON_LENGTH);
}
const float horizon_square = SQUARE(horizon_length);
if (buffer_map.find(actor_id) == buffer_map.end()) {
@ -89,10 +95,11 @@ void LocalizationStage::Update(const unsigned long index) {
}
}
// Purge waypoints too far from the front of the buffer.
// Purge waypoints too far from the front of the buffer, but not if it has reached a junction.
while (!is_at_junction_entrance
&& !waypoint_buffer.empty()
&& waypoint_buffer.back()->DistanceSquared(waypoint_buffer.front()) > horizon_square) {
&& waypoint_buffer.back()->DistanceSquared(waypoint_buffer.front()) > horizon_square + horizon_square
&& !waypoint_buffer.back()->CheckJunction()) {
PopWaypoint(actor_id, track_traffic, waypoint_buffer, false);
}
}
@ -108,21 +115,38 @@ void LocalizationStage::Update(const unsigned long index) {
bool force_lane_change = lane_change_info.change_lane;
bool lane_change_direction = lane_change_info.direction;
if (!force_lane_change) {
float perc_keep_right = parameters.GetKeepRightPercentage(actor_id);
if (perc_keep_right >= 0.0f && perc_keep_right >= random_devices.at(actor_id).next()) {
// Apply parameters for keep right rule and random lane changes.
if (!force_lane_change && vehicle_speed > MIN_LANE_CHANGE_SPEED){
const float perc_keep_right = parameters.GetKeepRightPercentage(actor_id);
const float perc_random_leftlanechange = parameters.GetRandomLeftLaneChangePercentage(actor_id);
const float perc_random_rightlanechange = parameters.GetRandomRightLaneChangePercentage(actor_id);
const bool is_keep_right = perc_keep_right > random_devices.at(actor_id).next();
const bool is_random_left_change = perc_random_leftlanechange >= random_devices.at(actor_id).next();
const bool is_random_right_change = perc_random_rightlanechange >= random_devices.at(actor_id).next();
// Determine which of the parameters we should apply.
if (is_keep_right || is_random_right_change) {
force_lane_change = true;
lane_change_direction = true;
}
if (is_random_left_change) {
if (!force_lane_change) {
force_lane_change = true;
lane_change_direction = false;
} else {
// Both a left and right lane changes are forced. Choose between one of them.
lane_change_direction = FIFTYPERC > random_devices.at(actor_id).next();
}
}
}
const SimpleWaypointPtr front_waypoint = waypoint_buffer.front();
const float lane_change_distance = SQUARE(std::max(10.0f * vehicle_speed, INTER_LANE_CHANGE_DISTANCE));
bool recently_not_executed_lane_change = last_lane_change_location.find(actor_id) == last_lane_change_location.end();
bool recently_not_executed_lane_change = last_lane_change_swpt.find(actor_id) == last_lane_change_swpt.end();
bool done_with_previous_lane_change = true;
if (!recently_not_executed_lane_change) {
float distance_frm_previous = cg::Math::DistanceSquared(last_lane_change_location.at(actor_id), vehicle_location);
float distance_frm_previous = cg::Math::DistanceSquared(last_lane_change_swpt.at(actor_id)->GetLocation(), vehicle_location);
done_with_previous_lane_change = distance_frm_previous > lane_change_distance;
}
bool auto_or_force_lane_change = parameters.GetAutoLaneChange(actor_id) || force_lane_change;
@ -136,10 +160,10 @@ void LocalizationStage::Update(const unsigned long index) {
force_lane_change, lane_change_direction);
if (change_over_point != nullptr) {
if (last_lane_change_location.find(actor_id) != last_lane_change_location.end()) {
last_lane_change_location.at(actor_id) = vehicle_location;
if (last_lane_change_swpt.find(actor_id) != last_lane_change_swpt.end()) {
last_lane_change_swpt.at(actor_id) = change_over_point;
} else {
last_lane_change_location.insert({actor_id, vehicle_location});
last_lane_change_swpt.insert({actor_id, change_over_point});
}
auto number_of_pops = waypoint_buffer.size();
for (uint64_t j = 0u; j < number_of_pops; ++j) {
@ -149,27 +173,40 @@ void LocalizationStage::Update(const unsigned long index) {
}
}
// Populating the buffer.
while (waypoint_buffer.back()->DistanceSquared(waypoint_buffer.front()) <= horizon_square) {
Path imported_path = parameters.GetCustomPath(actor_id);
Route imported_actions = parameters.GetImportedRoute(actor_id);
// We are effectively importing a path.
if (!imported_path.empty()) {
ImportPath(imported_path, waypoint_buffer, actor_id, horizon_square);
} else if (!imported_actions.empty()) {
ImportRoute(imported_actions, waypoint_buffer, actor_id, horizon_square);
SimpleWaypointPtr furthest_waypoint = waypoint_buffer.back();
std::vector<SimpleWaypointPtr> next_waypoints = furthest_waypoint->GetNextWaypoint();
uint64_t selection_index = 0u;
// Pseudo-randomized path selection if found more than one choice.
if (next_waypoints.size() > 1) {
double r_sample = random_devices.at(actor_id).next();
selection_index = static_cast<uint64_t>(r_sample*next_waypoints.size()*0.01);
} else if (next_waypoints.size() == 0) {
if (!parameters.GetOSMMode()) {
std::cout << "This map has dead-end roads, please change the set_open_street_map parameter to true" << std::endl;
}
marked_for_removal.push_back(actor_id);
break;
}
SimpleWaypointPtr next_wp_selection = next_waypoints.at(selection_index);
PushWaypoint(actor_id, track_traffic, waypoint_buffer, next_wp_selection);
}
// Populating the buffer through randomly chosen waypoints.
else {
while (waypoint_buffer.back()->DistanceSquared(waypoint_buffer.front()) <= horizon_square) {
SimpleWaypointPtr furthest_waypoint = waypoint_buffer.back();
std::vector<SimpleWaypointPtr> next_waypoints = furthest_waypoint->GetNextWaypoint();
uint64_t selection_index = 0u;
// Pseudo-randomized path selection if found more than one choice.
if (next_waypoints.size() > 1) {
double r_sample = random_devices.at(actor_id).next();
selection_index = static_cast<uint64_t>(r_sample*next_waypoints.size()*0.01);
} else if (next_waypoints.size() == 0) {
if (!parameters.GetOSMMode()) {
std::cout << "This map has dead-end roads, please change the set_open_street_map parameter to true" << std::endl;
}
marked_for_removal.push_back(actor_id);
break;
}
SimpleWaypointPtr next_wp_selection = next_waypoints.at(selection_index);
PushWaypoint(actor_id, track_traffic, waypoint_buffer, next_wp_selection);
}
}
ExtendAndFindSafeSpace(actor_id, is_at_junction_entrance, waypoint_buffer);
// Editing output array
@ -278,12 +315,12 @@ void LocalizationStage::ExtendAndFindSafeSpace(const ActorId actor_id,
}
void LocalizationStage::RemoveActor(ActorId actor_id) {
last_lane_change_location.erase(actor_id);
last_lane_change_swpt.erase(actor_id);
vehicles_at_junction.erase(actor_id);
}
void LocalizationStage::Reset() {
last_lane_change_location.clear();
last_lane_change_swpt.clear();
vehicles_at_junction.clear();
}
@ -396,11 +433,11 @@ SimpleWaypointPtr LocalizationStage::AssignLaneChange(const ActorId actor_id,
}
if (change_over_point != nullptr) {
const float change_over_distance = cg::Math::Clamp(1.5f * vehicle_speed, 3.0f, 20.0f);
const auto starting_point = change_over_point;
const float change_over_distance = cg::Math::Clamp(1.5f * vehicle_speed, MIN_WPT_DISTANCE, MAX_WPT_DISTANCE);
const SimpleWaypointPtr starting_point = change_over_point;
while (change_over_point->DistanceSquared(starting_point) < SQUARE(change_over_distance) &&
!change_over_point->CheckJunction()) {
change_over_point = change_over_point->GetNextWaypoint()[0];
change_over_point = change_over_point->GetNextWaypoint().front();
}
}
}
@ -408,5 +445,215 @@ SimpleWaypointPtr LocalizationStage::AssignLaneChange(const ActorId actor_id,
return change_over_point;
}
void LocalizationStage::ImportPath(Path &imported_path, Buffer &waypoint_buffer, const ActorId actor_id, const float horizon_square) {
// Remove the waypoints already added to the path, except for the first.
if (parameters.GetUploadPath(actor_id)) {
auto number_of_pops = waypoint_buffer.size();
for (uint64_t j = 0u; j < number_of_pops - 1; ++j) {
PopWaypoint(actor_id, track_traffic, waypoint_buffer, false);
}
// We have successfully imported the path. Remove it from the list of paths to be imported.
parameters.RemoveUploadPath(actor_id, false);
}
// Get the latest imported waypoint. and find its closest waypoint in TM's InMemoryMap.
cg::Location latest_imported = imported_path.front();
SimpleWaypointPtr imported = local_map->GetWaypoint(latest_imported);
// We need to generate a path compatible with TM's waypoints.
while (!imported_path.empty() && waypoint_buffer.back()->DistanceSquared(waypoint_buffer.front()) <= horizon_square) {
// Get the latest point we added to the list. If starting, this will be the one referred to the vehicle's location.
SimpleWaypointPtr latest_waypoint = waypoint_buffer.back();
// Try to link the latest_waypoint to the imported waypoint.
std::vector<SimpleWaypointPtr> next_waypoints = latest_waypoint->GetNextWaypoint();
uint64_t selection_index = 0u;
// Choose correct path.
if (next_waypoints.size() > 1) {
const float imported_road_id = imported->GetWaypoint()->GetRoadId();
float min_distance = std::numeric_limits<float>::infinity();
for (uint64_t k = 0u; k < next_waypoints.size(); ++k) {
SimpleWaypointPtr junction_end_point = next_waypoints.at(k);
while (!junction_end_point->CheckJunction()) {
junction_end_point = junction_end_point->GetNextWaypoint().front();
}
while (junction_end_point->CheckJunction()) {
junction_end_point = junction_end_point->GetNextWaypoint().front();
}
while (next_waypoints.at(k)->DistanceSquared(junction_end_point) < 50.0f) {
junction_end_point = junction_end_point->GetNextWaypoint().front();
}
float jep_road_id = junction_end_point->GetWaypoint()->GetRoadId();
if (jep_road_id == imported_road_id) {
selection_index = k;
break;
}
float distance = junction_end_point->DistanceSquared(imported);
if (distance < min_distance) {
min_distance = distance;
selection_index = k;
}
}
} else if (next_waypoints.size() == 0) {
if (!parameters.GetOSMMode()) {
std::cout << "This map has dead-end roads, please change the set_open_street_map parameter to true" << std::endl;
}
marked_for_removal.push_back(actor_id);
break;
}
SimpleWaypointPtr next_wp_selection = next_waypoints.at(selection_index);
PushWaypoint(actor_id, track_traffic, waypoint_buffer, next_wp_selection);
// Remove the imported waypoint from the path if it's close to the last one.
if (next_wp_selection->DistanceSquared(imported) < 30.0f) {
imported_path.erase(imported_path.begin());
PushWaypoint(actor_id, track_traffic, waypoint_buffer, imported);
latest_imported = imported_path.front();
imported = local_map->GetWaypoint(latest_imported);
}
}
if (imported_path.empty()) {
// Once we are done, check if we can clear the structure.
parameters.RemoveUploadPath(actor_id, true);
} else {
// Otherwise, update the structure with the waypoints that we still need to import.
parameters.UpdateUploadPath(actor_id, imported_path);
}
}
void LocalizationStage::ImportRoute(Route &imported_actions, Buffer &waypoint_buffer, const ActorId actor_id, const float horizon_square) {
if (parameters.GetUploadRoute(actor_id)) {
auto number_of_pops = waypoint_buffer.size();
for (uint64_t j = 0u; j < number_of_pops - 1; ++j) {
PopWaypoint(actor_id, track_traffic, waypoint_buffer, false);
}
// We have successfully imported the route. Remove it from the list of routes to be imported.
parameters.RemoveImportedRoute(actor_id, false);
}
RoadOption next_road_option = static_cast<RoadOption>(imported_actions.front());
while (!imported_actions.empty() && waypoint_buffer.back()->DistanceSquared(waypoint_buffer.front()) <= horizon_square) {
// Get the latest point we added to the list. If starting, this will be the one referred to the vehicle's location.
SimpleWaypointPtr latest_waypoint = waypoint_buffer.back();
RoadOption latest_road_option = latest_waypoint->GetRoadOption();
// Try to link the latest_waypoint to the correct next RouteOption.
std::vector<SimpleWaypointPtr> next_waypoints = latest_waypoint->GetNextWaypoint();
uint16_t selection_index = 0u;
if (next_waypoints.size() > 1) {
for (uint16_t i=0; i<next_waypoints.size(); ++i) {
if (next_waypoints.at(i)->GetRoadOption() == next_road_option) {
selection_index = i;
break;
} else {
if (i == next_waypoints.size() - 1) {
std::cout << "We couldn't find the RoadOption you were looking for. This route might diverge from the one expected." << std::endl;
}
}
}
} else if (next_waypoints.size() == 0) {
if (!parameters.GetOSMMode()) {
std::cout << "This map has dead-end roads, please change the set_open_street_map parameter to true" << std::endl;
}
marked_for_removal.push_back(actor_id);
break;
}
SimpleWaypointPtr next_wp_selection = next_waypoints.at(selection_index);
PushWaypoint(actor_id, track_traffic, waypoint_buffer, next_wp_selection);
// If we are switching to a new RoadOption, it means the current one is already fully imported.
if (latest_road_option != next_wp_selection->GetRoadOption() && next_road_option == next_wp_selection->GetRoadOption()) {
imported_actions.erase(imported_actions.begin());
next_road_option = static_cast<RoadOption>(imported_actions.front());
}
}
if (imported_actions.empty()) {
// Once we are done, check if we can clear the structure.
parameters.RemoveImportedRoute(actor_id, true);
} else {
// Otherwise, update the structure with the waypoints that we still need to import.
parameters.UpdateImportedRoute(actor_id, imported_actions);
}
}
Action LocalizationStage::ComputeNextAction(const ActorId& actor_id) {
auto waypoint_buffer = buffer_map.at(actor_id);
auto next_action = std::make_pair(RoadOption::LaneFollow, waypoint_buffer.back()->GetWaypoint());
bool is_lane_change = false;
if (last_lane_change_swpt.find(actor_id) != last_lane_change_swpt.end()) {
// A lane change is happening.
is_lane_change = true;
const cg::Vector3D heading_vector = simulation_state.GetHeading(actor_id);
const cg::Vector3D relative_vector = simulation_state.GetLocation(actor_id) - last_lane_change_swpt.at(actor_id)->GetLocation();
bool left_heading = (heading_vector.x * relative_vector.y - heading_vector.y * relative_vector.x) > 0.0f;
if (left_heading) next_action = std::make_pair(RoadOption::ChangeLaneLeft, last_lane_change_swpt.at(actor_id)->GetWaypoint());
else next_action = std::make_pair(RoadOption::ChangeLaneRight, last_lane_change_swpt.at(actor_id)->GetWaypoint());
}
for (auto &swpt : waypoint_buffer) {
RoadOption road_opt = swpt->GetRoadOption();
if (road_opt != RoadOption::LaneFollow) {
if (!is_lane_change) {
// No lane change in sight, we can assume this will be the next action.
return std::make_pair(road_opt, swpt->GetWaypoint());
} else {
// A lane change will happen as well as another action, we need to figure out which one will happen first.
cg::Location lane_change = last_lane_change_swpt.at(actor_id)->GetLocation();
cg::Location actual_location = simulation_state.GetLocation(actor_id);
auto distance_lane_change = cg::Math::DistanceSquared(actual_location, lane_change);
auto distance_other_action = cg::Math::DistanceSquared(actual_location, swpt->GetLocation());
if (distance_lane_change < distance_other_action) return next_action;
else return std::make_pair(road_opt, swpt->GetWaypoint());
}
}
}
return next_action;
}
ActionBuffer LocalizationStage::ComputeActionBuffer(const ActorId& actor_id) {
auto waypoint_buffer = buffer_map.at(actor_id);
ActionBuffer action_buffer;
Action lane_change;
bool is_lane_change = false;
SimpleWaypointPtr buffer_front = waypoint_buffer.front();
RoadOption last_road_opt = buffer_front->GetRoadOption();
action_buffer.push_back(std::make_pair(last_road_opt, buffer_front->GetWaypoint()));
if (last_lane_change_swpt.find(actor_id) != last_lane_change_swpt.end()) {
// A lane change is happening.
is_lane_change = true;
const cg::Vector3D heading_vector = simulation_state.GetHeading(actor_id);
const cg::Vector3D relative_vector = simulation_state.GetLocation(actor_id) - last_lane_change_swpt.at(actor_id)->GetLocation();
bool left_heading = (heading_vector.x * relative_vector.y - heading_vector.y * relative_vector.x) > 0.0f;
if (left_heading) lane_change = std::make_pair(RoadOption::ChangeLaneLeft, last_lane_change_swpt.at(actor_id)->GetWaypoint());
else lane_change = std::make_pair(RoadOption::ChangeLaneRight, last_lane_change_swpt.at(actor_id)->GetWaypoint());
}
for (auto &wpt : waypoint_buffer) {
RoadOption current_road_opt = wpt->GetRoadOption();
if (current_road_opt != last_road_opt) {
action_buffer.push_back(std::make_pair(current_road_opt, wpt->GetWaypoint()));
last_road_opt = current_road_opt;
}
}
if (is_lane_change) {
// Insert the lane change action in the appropriate part of the action buffer.
auto distance_lane_change = cg::Math::DistanceSquared(waypoint_buffer.front()->GetLocation(), lane_change.second->GetTransform().location);
for (uint16_t i = 0; i < action_buffer.size(); ++i) {
auto distance_action = cg::Math::DistanceSquared(waypoint_buffer.front()->GetLocation(), waypoint_buffer.at(i)->GetLocation());
// If the waypoint related to the next action is further away from the one of the lane change, insert lane change action here.
// If we reached the end of the buffer, place the action at the end.
if (i == action_buffer.size()-1) {
action_buffer.push_back(lane_change);
break;
} else if (distance_action > distance_lane_change) {
action_buffer.insert(action_buffer.begin()+i, lane_change);
break;
}
}
}
return action_buffer;
}
} // namespace traffic_manager
} // namespace carla

View File

@ -18,7 +18,12 @@ namespace traffic_manager {
namespace cc = carla::client;
using LocalMapPtr = std::shared_ptr<InMemoryMap>;
using LaneChangeLocationMap = std::unordered_map<ActorId, cg::Location>;
using LaneChangeSWptMap = std::unordered_map<ActorId, SimpleWaypointPtr>;
using WaypointPtr = carla::SharedPtr<cc::Waypoint>;
using Action = std::pair<RoadOption, WaypointPtr>;
using ActionBuffer = std::vector<Action>;
using Path = std::vector<cg::Location>;
using Route = std::vector<uint8_t>;
/// This class has functionality to maintain a horizon of waypoints ahead
/// of the vehicle for it to follow.
@ -35,7 +40,7 @@ private:
// Array of vehicles marked by stages for removal.
std::vector<ActorId>& marked_for_removal;
LocalizationFrame &output_array;
LaneChangeLocationMap last_lane_change_location;
LaneChangeSWptMap last_lane_change_swpt;
ActorIdSet vehicles_at_junction;
using SimpleWaypointPair = std::pair<SimpleWaypointPtr, SimpleWaypointPtr>;
std::unordered_map<ActorId, SimpleWaypointPair> vehicles_at_junction_entrance;
@ -46,12 +51,20 @@ private:
const float vehicle_speed,
bool force, bool direction);
void DrawBuffer(Buffer &buffer);
void ExtendAndFindSafeSpace(const ActorId actor_id,
const bool is_at_junction_entrance,
Buffer &waypoint_buffer);
void ImportPath(Path &imported_path,
Buffer &waypoint_buffer,
const ActorId actor_id,
const float horizon_square);
void ImportRoute(Route &imported_actions,
Buffer &waypoint_buffer,
const ActorId actor_id,
const float horizon_square);
public:
LocalizationStage(const std::vector<ActorId> &vehicle_id_list,
BufferMap &buffer_map,
@ -68,6 +81,11 @@ public:
void RemoveActor(const ActorId actor_id) override;
void Reset() override;
Action ComputeNextAction(const ActorId &actor_id);
ActionBuffer ComputeActionBuffer(const ActorId& actor_id);
};
} // namespace traffic_manager

View File

@ -61,7 +61,7 @@ TargetWPInfo GetTargetWaypoint(const Buffer &waypoint_buffer, const float &targe
SimpleWaypointPtr target_waypoint = waypoint_buffer.front();
const SimpleWaypointPtr &buffer_front = waypoint_buffer.front();
uint64_t startPosn = static_cast<uint64_t>(std::fabs(target_point_distance * INV_MAP_RESOLUTION));
uint64_t index = 0;
uint64_t index = startPosn;
/// Condition to determine forward or backward scanning of waypoint buffer.
if (startPosn < waypoint_buffer.size()) {

View File

@ -157,7 +157,7 @@ void MotionPlanStage::Update(const unsigned long index) {
ActuationSignal actuation_signal{0.0f, 0.0f, 0.0f};
const float target_point_distance = std::max(vehicle_speed * TARGET_WAYPOINT_TIME_HORIZON,
TARGET_WAYPOINT_HORIZON_LENGTH);
MIN_TARGET_WAYPOINT_DISTANCE);
const SimpleWaypointPtr &target_waypoint = GetTargetWaypoint(waypoint_buffer, target_point_distance).first;
const cg::Location target_location = target_waypoint->GetLocation();
float dot_product = DeviationDotProduct(vehicle_location, vehicle_heading, target_location);
@ -307,6 +307,7 @@ std::pair<bool, float> MotionPlanStage::CollisionHandling(const CollisionHazardD
const float max_target_velocity) {
bool collision_emergency_stop = false;
float dynamic_target_velocity = max_target_velocity;
const float vehicle_speed = vehicle_velocity.Length();
if (collision_hazard.hazard && !tl_hazard) {
const ActorId other_actor_id = collision_hazard.hazard_actor_id;
@ -321,11 +322,11 @@ std::pair<bool, float> MotionPlanStage::CollisionHandling(const CollisionHazardD
if (vehicle_relative_speed > EPSILON_RELATIVE_SPEED) {
// If other vehicle is approaching lead vehicle and lead vehicle is further
// than follow_lead_distance 0 kmph -> 5m, 100 kmph -> 10m.
float follow_lead_distance = std::min(vehicle_relative_speed * FOLLOW_DISTANCE_RATE + MIN_FOLLOW_LEAD_DISTANCE, MAX_FOLLOW_LEAD_DISTANCE);
if (available_distance_margin > follow_lead_distance && other_velocity.Length() < 1.0f) {
float follow_lead_distance = FOLLOW_LEAD_FACTOR * vehicle_speed + MIN_FOLLOW_LEAD_DISTANCE;
if (available_distance_margin > follow_lead_distance) {
// Then reduce the gap between the vehicles till FOLLOW_LEAD_DISTANCE
// by maintaining a relative speed of RELATIVE_APPROACH_SPEED
dynamic_target_velocity = other_speed_along_heading + RELATIVE_APPROACH_SPEED;
// by maintaining a relative speed of other_speed_along_heading
dynamic_target_velocity = other_speed_along_heading;
}
// If vehicle is approaching a lead vehicle and the lead vehicle is further
// than CRITICAL_BRAKING_MARGIN but closer than FOLLOW_LEAD_DISTANCE.
@ -342,6 +343,11 @@ std::pair<bool, float> MotionPlanStage::CollisionHandling(const CollisionHazardD
}
}
float max_gradual_velocity = PERC_MAX_SLOWDOWN * vehicle_speed;
if (dynamic_target_velocity < vehicle_speed - max_gradual_velocity) {
// Don't slow more than PERC_MAX_SLOWDOWN per frame.
dynamic_target_velocity = vehicle_speed - max_gradual_velocity;
}
dynamic_target_velocity = std::min(max_target_velocity, dynamic_target_velocity);
return {collision_emergency_stop, dynamic_target_velocity};

View File

@ -90,6 +90,25 @@ void Parameters::SetKeepRightPercentage(const ActorPtr &actor, const float perce
perc_keep_right.AddEntry(entry);
}
void Parameters::SetRandomLeftLaneChangePercentage(const ActorPtr &actor, const float percentage) {
const auto entry = std::make_pair(actor->GetId(), percentage);
perc_random_left.AddEntry(entry);
}
void Parameters::SetRandomRightLaneChangePercentage(const ActorPtr &actor, const float percentage) {
const auto entry = std::make_pair(actor->GetId(), percentage);
perc_random_right.AddEntry(entry);
}
void Parameters::SetUpdateVehicleLights(const ActorPtr &actor, const bool do_update) {
const auto entry = std::make_pair(actor->GetId(), do_update);
auto_update_vehicle_lights.AddEntry(entry);
}
void Parameters::SetAutoLaneChange(const ActorPtr &actor, const bool enable) {
const auto entry = std::make_pair(actor->GetId(), enable);
@ -153,6 +172,48 @@ void Parameters::SetOSMMode(const bool mode_switch) {
osm_mode.store(mode_switch);
}
void Parameters::SetCustomPath(const ActorPtr &actor, const Path path, const bool empty_buffer) {
const auto entry = std::make_pair(actor->GetId(), path);
custom_path.AddEntry(entry);
const auto entry2 = std::make_pair(actor->GetId(), empty_buffer);
upload_path.AddEntry(entry2);
}
void Parameters::RemoveUploadPath(const ActorId &actor_id, const bool remove_path) {
if (!remove_path) {
upload_path.RemoveEntry(actor_id);
} else {
custom_path.RemoveEntry(actor_id);
}
}
void Parameters::UpdateUploadPath(const ActorId &actor_id, const Path path) {
custom_path.RemoveEntry(actor_id);
const auto entry = std::make_pair(actor_id, path);
custom_path.AddEntry(entry);
}
void Parameters::SetImportedRoute(const ActorPtr &actor, const Route route, const bool empty_buffer) {
const auto entry = std::make_pair(actor->GetId(), route);
custom_route.AddEntry(entry);
const auto entry2 = std::make_pair(actor->GetId(), empty_buffer);
upload_route.AddEntry(entry2);
}
void Parameters::RemoveImportedRoute(const ActorId &actor_id, const bool remove_path) {
if (!remove_path) {
upload_route.RemoveEntry(actor_id);
} else {
custom_route.RemoveEntry(actor_id);
}
}
void Parameters::UpdateImportedRoute(const ActorId &actor_id, const Route route) {
custom_route.RemoveEntry(actor_id);
const auto entry = std::make_pair(actor_id, route);
custom_route.AddEntry(entry);
}
//////////////////////////////////// GETTERS //////////////////////////////////
float Parameters::GetHybridPhysicsRadius() const {
@ -212,7 +273,27 @@ float Parameters::GetKeepRightPercentage(const ActorId &actor_id) {
percentage = perc_keep_right.GetValue(actor_id);
}
perc_keep_right.RemoveEntry(actor_id);
return percentage;
}
float Parameters::GetRandomLeftLaneChangePercentage(const ActorId &actor_id) {
float percentage = -1.0f;
if (perc_random_left.Contains(actor_id)) {
percentage = perc_random_left.GetValue(actor_id);
}
return percentage;
}
float Parameters::GetRandomRightLaneChangePercentage(const ActorId &actor_id) {
float percentage = -1.0f;
if (perc_random_right.Contains(actor_id)) {
percentage = perc_random_right.GetValue(actor_id);
}
return percentage;
}
@ -273,6 +354,16 @@ float Parameters::GetPercentageIgnoreWalkers(const ActorId &actor_id) const {
return percentage;
}
bool Parameters::GetUpdateVehicleLights(const ActorId &actor_id) const {
bool do_update = false;
if (auto_update_vehicle_lights.Contains(actor_id)) {
do_update = auto_update_vehicle_lights.GetValue(actor_id);
}
return do_update;
}
float Parameters::GetPercentageIgnoreVehicles(const ActorId &actor_id) const {
float percentage = 0.0f;
@ -310,5 +401,51 @@ bool Parameters::GetOSMMode() const {
return osm_mode.load();
}
bool Parameters::GetUploadPath(const ActorId &actor_id) const {
bool custom_path_bool = false;
if (upload_path.Contains(actor_id)) {
custom_path_bool = upload_path.GetValue(actor_id);
}
return custom_path_bool;
}
Path Parameters::GetCustomPath(const ActorId &actor_id) const {
Path custom_path_import;
if (custom_path.Contains(actor_id)) {
custom_path_import = custom_path.GetValue(actor_id);
}
return custom_path_import;
}
bool Parameters::GetUploadRoute(const ActorId &actor_id) const {
bool custom_route_bool = false;
if (upload_route.Contains(actor_id)) {
custom_route_bool = upload_route.GetValue(actor_id);
}
return custom_route_bool;
}
Route Parameters::GetImportedRoute(const ActorId &actor_id) const {
Route custom_route_import;
if (custom_route.Contains(actor_id)) {
custom_route_import = custom_route.GetValue(actor_id);
}
return custom_route_import;
}
} // namespace traffic_manager
} // namespace carla

View File

@ -9,6 +9,7 @@
#include <atomic>
#include <chrono>
#include <random>
#include <unordered_map>
#include "carla/client/Actor.h"
#include "carla/client/Vehicle.h"
@ -25,6 +26,8 @@ namespace cc = carla::client;
namespace cg = carla::geom;
using ActorPtr = carla::SharedPtr<cc::Actor>;
using ActorId = carla::ActorId;
using Path = std::vector<cg::Location>;
using Route = std::vector<uint8_t>;
struct ChangeLaneInfo {
bool change_lane = false;
@ -56,6 +59,12 @@ private:
AtomicMap<ActorId, float> perc_ignore_vehicles;
/// Map containing % of keep right rule.
AtomicMap<ActorId, float> perc_keep_right;
/// Map containing % of random left lane change.
AtomicMap<ActorId, float> perc_random_left;
/// Map containing % of random right lane change.
AtomicMap<ActorId, float> perc_random_right;
/// Map containing the automatic vehicle lights update flag
AtomicMap<ActorId, bool> auto_update_vehicle_lights;
/// Synchronous mode switch.
std::atomic<bool> synchronous_mode{false};
/// Distance margin
@ -76,6 +85,14 @@ private:
std::atomic<float> hybrid_physics_radius {70.0};
/// Parameter specifying Open Street Map mode.
std::atomic<bool> osm_mode {true};
/// Parameter specifying if importing a custom path.
AtomicMap<ActorId, bool> upload_path;
/// Structure to hold all custom paths.
AtomicMap<ActorId, Path> custom_path;
/// Parameter specifying if importing a custom route.
AtomicMap<ActorId, bool> upload_route;
/// Structure to hold all custom routes.
AtomicMap<ActorId, Route> custom_route;
public:
Parameters();
@ -120,9 +137,18 @@ public:
/// Method to set % to ignore any vehicle.
void SetPercentageIgnoreWalkers(const ActorPtr &actor, const float perc);
/// Method to set probabilistic preference to keep on the right lane.
/// Method to set % to keep on the right lane.
void SetKeepRightPercentage(const ActorPtr &actor, const float percentage);
/// Method to set % to randomly do a left lane change.
void SetRandomLeftLaneChangePercentage(const ActorPtr &actor, const float percentage);
/// Method to set % to randomly do a right lane change.
void SetRandomRightLaneChangePercentage(const ActorPtr &actor, const float percentage);
/// Method to set the automatic vehicle light state update flag.
void SetUpdateVehicleLights(const ActorPtr &actor, const bool do_update);
/// Method to set the distance to leading vehicle for all registered vehicles.
void SetGlobalDistanceToLeadingVehicle(const float dist);
@ -150,6 +176,24 @@ public:
/// Method to set limits for boundaries when respawning vehicles.
void SetMaxBoundaries(const float lower, const float upper);
/// Method to set our own imported path.
void SetCustomPath(const ActorPtr &actor, const Path path, const bool empty_buffer);
/// Method to remove a list of points.
void RemoveUploadPath(const ActorId &actor_id, const bool remove_path);
/// Method to update an already set list of points.
void UpdateUploadPath(const ActorId &actor_id, const Path path);
/// Method to set our own imported route.
void SetImportedRoute(const ActorPtr &actor, const Route route, const bool empty_buffer);
/// Method to remove a route.
void RemoveImportedRoute(const ActorId &actor_id, const bool remove_path);
/// Method to update an already set route.
void UpdateImportedRoute(const ActorId &actor_id, const Route route);
///////////////////////////////// GETTERS /////////////////////////////////////
/// Method to retrieve hybrid physics radius.
@ -167,6 +211,12 @@ public:
/// Method to query percentage probability of keep right rule for a vehicle.
float GetKeepRightPercentage(const ActorId &actor_id);
/// Method to query percentage probability of a random right lane change for a vehicle.
float GetRandomLeftLaneChangePercentage(const ActorId &actor_id);
/// Method to query percentage probability of a random left lane change for a vehicle.
float GetRandomRightLaneChangePercentage(const ActorId &actor_id);
/// Method to query auto lane change rule for a vehicle.
bool GetAutoLaneChange(const ActorId &actor_id) const;
@ -185,6 +235,9 @@ public:
/// Method to get % to ignore any walker.
float GetPercentageIgnoreWalkers(const ActorId &actor_id) const;
/// Method to get if the vehicle lights should be updates automatically
bool GetUpdateVehicleLights(const ActorId &actor_id) const;
/// Method to get synchronous mode.
bool GetSynchronousMode() const;
@ -206,6 +259,18 @@ public:
/// Method to get Open Street Map mode.
bool GetOSMMode() const;
/// Method to get if we are uploading a path.
bool GetUploadPath(const ActorId &actor_id) const;
/// Method to get a custom path.
Path GetCustomPath(const ActorId &actor_id) const;
/// Method to get if we are uploading a route.
bool GetUploadRoute(const ActorId &actor_id) const;
/// Method to get a custom route.
Route GetImportedRoute(const ActorId &actor_id) const;
/// Synchronous mode time out variable.
std::chrono::duration<double, std::milli> synchronous_time_out;
};

View File

@ -134,5 +134,13 @@ namespace traffic_manager {
return waypoint->GetTransform();
}
void SimpleWaypoint::SetRoadOption(RoadOption _road_option) {
road_option = _road_option;
}
RoadOption SimpleWaypoint::GetRoadOption() {
return road_option;
}
} // namespace traffic_manager
} // namespace carla

View File

@ -22,6 +22,16 @@ namespace traffic_manager {
namespace cg = carla::geom;
using WaypointPtr = carla::SharedPtr<cc::Waypoint>;
using GeoGridId = carla::road::JuncId;
enum class RoadOption : uint8_t {
Void = 0,
Left = 1,
Right = 2,
Straight = 3,
LaneFollow = 4,
ChangeLaneLeft = 5,
ChangeLaneRight = 6,
RoadEnd = 7
};
/// This is a simple wrapper class on Carla's waypoint object.
/// The class is used to represent discrete samples of the world map.
@ -41,6 +51,8 @@ namespace traffic_manager {
SimpleWaypointPtr next_left_waypoint;
/// Pointer to right lane change waypoint.
SimpleWaypointPtr next_right_waypoint;
/// RoadOption for the actual waypoint.
RoadOption road_option = RoadOption::Void;
/// Integer placing the waypoint into a geodesic grid.
GeoGridId geodesic_grid_id = 0;
// Boolean to hold if the waypoint belongs to a junction
@ -118,6 +130,10 @@ namespace traffic_manager {
/// Return transform object for the current waypoint.
cg::Transform GetTransform() const;
// Accessor methods for road option.
void SetRoadOption(RoadOption _road_option);
RoadOption GetRoadOption();
};
} // namespace traffic_manager

View File

@ -56,9 +56,8 @@ void TrackTraffic::UpdateGridPosition(const ActorId actor_id, const Buffer &buff
// Step through buffer and update grid list for actor and actor list for grids.
std::unordered_set<GeoGridId> current_grids;
uint64_t buffer_size = buffer.size();
uint64_t step_size = static_cast<uint64_t>(static_cast<float>(buffer_size) * INV_BUFFER_STEP_THROUGH);
for (uint64_t i = 0u; i <= BUFFER_STEP_THROUGH; ++i) {
auto waypoint = buffer.at(std::min(i * step_size, buffer_size - 1u));
for (uint64_t i = 0u; i <= buffer_size - 1u; ++i) {
auto waypoint = buffer.at(i);
GeoGridId ggid = waypoint->GetGeodesicGridId();
current_grids.insert(ggid);
// Add grid entry if not present.

View File

@ -69,8 +69,7 @@ bool TrafficLightStage::HandleNonSignalisedJunction(const ActorId ego_actor_id,
bool traffic_light_hazard = false;
if (vehicle_last_junction.find(ego_actor_id) == vehicle_last_junction.end()) {
// Initializing new map entry for the actor with
// an arbitrary and different junction id.
// Initializing new map entry for the actor with an arbitrary and different junction id.
vehicle_last_junction.insert({ego_actor_id, junction_id + 1});
}
@ -92,8 +91,7 @@ bool TrafficLightStage::HandleNonSignalisedJunction(const ActorId ego_actor_id,
}
// If new ticket is needed for the vehicle, then query the junction
// ticket map
// and update the map value to the new ticket value.
// ticket map and update the map value to the new ticket value.
if (need_to_issue_new_ticket) {
if (junction_last_ticket.find(junction_id) != junction_last_ticket.end()) {

View File

@ -65,6 +65,54 @@ public:
}
}
/// Method to set our own imported path.
void SetCustomPath(const ActorPtr &actor, const Path path, const bool empty_buffer) {
TrafficManagerBase* tm_ptr = GetTM(_port);
if (tm_ptr != nullptr) {
tm_ptr->SetCustomPath(actor, path, empty_buffer);
}
}
/// Method to remove a path.
void RemoveUploadPath(const ActorId &actor_id, const bool remove_path) {
TrafficManagerBase* tm_ptr = GetTM(_port);
if (tm_ptr != nullptr) {
tm_ptr->RemoveUploadPath(actor_id, remove_path);
}
}
/// Method to update an already set path.
void UpdateUploadPath(const ActorId &actor_id, const Path path) {
TrafficManagerBase* tm_ptr = GetTM(_port);
if (tm_ptr != nullptr) {
tm_ptr->UpdateUploadPath(actor_id, path);
}
}
/// Method to set our own imported route.
void SetImportedRoute(const ActorPtr &actor, const Route route, const bool empty_buffer) {
TrafficManagerBase* tm_ptr = GetTM(_port);
if (tm_ptr != nullptr) {
tm_ptr->SetImportedRoute(actor, route, empty_buffer);
}
}
/// Method to remove a route.
void RemoveImportedRoute(const ActorId &actor_id, const bool remove_path) {
TrafficManagerBase* tm_ptr = GetTM(_port);
if (tm_ptr != nullptr) {
tm_ptr->RemoveImportedRoute(actor_id, remove_path);
}
}
/// Method to update an already set route.
void UpdateImportedRoute(const ActorId &actor_id, const Route route) {
TrafficManagerBase* tm_ptr = GetTM(_port);
if (tm_ptr != nullptr) {
tm_ptr->UpdateImportedRoute(actor_id, route);
}
}
/// Method to set if we are automatically respawning vehicles.
void SetRespawnDormantVehicles(const bool mode_switch) {
TrafficManagerBase* tm_ptr = GetTM(_port);
@ -138,6 +186,14 @@ public:
}
}
/// Set the automatic management of the vehicle lights
void SetUpdateVehicleLights(const ActorPtr &actor, const bool do_update){
TrafficManagerBase* tm_ptr = GetTM(_port);
if(tm_ptr != nullptr){
tm_ptr->SetUpdateVehicleLights(actor, do_update);
}
}
/// Method to set collision detection rules between vehicles.
void SetCollisionDetection(const ActorPtr &reference_actor, const ActorPtr &other_actor, const bool detect_collision) {
TrafficManagerBase* tm_ptr = GetTM(_port);
@ -237,7 +293,7 @@ public:
}
}
/// Method to set probabilistic preference to keep on the right lane.
/// Method to set % to keep on the right lane.
void SetKeepRightPercentage(const ActorPtr &actor, const float percentage) {
TrafficManagerBase* tm_ptr = GetTM(_port);
if(tm_ptr != nullptr){
@ -245,6 +301,22 @@ public:
}
}
/// Method to set % to randomly do a left lane change.
void SetRandomLeftLaneChangePercentage(const ActorPtr &actor, const float percentage) {
TrafficManagerBase* tm_ptr = GetTM(_port);
if(tm_ptr != nullptr){
tm_ptr->SetRandomLeftLaneChangePercentage(actor, percentage);
}
}
/// Method to set % to randomly do a right lane change.
void SetRandomRightLaneChangePercentage(const ActorPtr &actor, const float percentage) {
TrafficManagerBase* tm_ptr = GetTM(_port);
if(tm_ptr != nullptr){
tm_ptr->SetRandomRightLaneChangePercentage(actor, percentage);
}
}
/// Method to set randomization seed.
void SetRandomDeviceSeed(const uint64_t seed) {
TrafficManagerBase* tm_ptr = GetTM(_port);
@ -255,6 +327,28 @@ public:
void ShutDown();
/// Method to get the next action.
Action GetNextAction(const ActorId &actor_id) {
Action next_action;
TrafficManagerBase* tm_ptr = GetTM(_port);
if (tm_ptr != nullptr) {
next_action = tm_ptr->GetNextAction(actor_id);
return next_action;
}
return next_action;
}
/// Method to get the action buffer.
ActionBuffer GetActionBuffer(const ActorId &actor_id) {
ActionBuffer action_buffer;
TrafficManagerBase* tm_ptr = GetTM(_port);
if (tm_ptr != nullptr) {
action_buffer = tm_ptr->GetActionBuffer(actor_id);
return action_buffer;
}
return action_buffer;
}
private:
void CreateTrafficManagerServer(

View File

@ -8,11 +8,18 @@
#include <memory>
#include "carla/client/Actor.h"
#include "carla/trafficmanager/SimpleWaypoint.h"
namespace carla {
namespace traffic_manager {
using ActorPtr = carla::SharedPtr<carla::client::Actor>;
using Path = std::vector<cg::Location>;
using Route = std::vector<uint8_t>;
using WaypointPtr = carla::SharedPtr<carla::client::Waypoint>;
using Action = std::pair<RoadOption, WaypointPtr>;
using ActionBuffer = std::vector<Action>;
/// The function of this class is to integrate all the various stages of
/// the traffic manager appropriately using messengers.
@ -51,6 +58,9 @@ public:
/// If less than 0, it's a % increase.
virtual void SetGlobalPercentageSpeedDifference(float const percentage) = 0;
/// Method to set the automatic management of the vehicle lights
virtual void SetUpdateVehicleLights(const ActorPtr &actor, const bool do_update) = 0;
/// Method to set collision detection rules between vehicles.
virtual void SetCollisionDetection(const ActorPtr &reference_actor, const ActorPtr &other_actor, const bool detect_collision) = 0;
@ -92,9 +102,15 @@ public:
/// Method to set Global Distance to Leading Vehicle.
virtual void SetGlobalDistanceToLeadingVehicle(const float dist) = 0;
/// Method to set probabilistic preference to keep on the right lane.
/// Method to set % to keep on the right lane.
virtual void SetKeepRightPercentage(const ActorPtr &actor,const float percentage) = 0;
/// Method to set % to randomly do a left lane change.
virtual void SetRandomLeftLaneChangePercentage(const ActorPtr &actor, const float percentage) = 0;
/// Method to set % to randomly do a right lane change.
virtual void SetRandomRightLaneChangePercentage(const ActorPtr &actor, const float percentage) = 0;
/// Method to set hybrid physics mode.
virtual void SetHybridPhysicsMode(const bool mode_switch) = 0;
@ -107,6 +123,24 @@ public:
/// Method to set Open Street Map mode.
virtual void SetOSMMode(const bool mode_switch) = 0;
/// Method to set our own imported path.
virtual void SetCustomPath(const ActorPtr &actor, const Path path, const bool empty_buffer) = 0;
/// Method to remove a path.
virtual void RemoveUploadPath(const ActorId &actor_id, const bool remove_path) = 0;
/// Method to update an already set path.
virtual void UpdateUploadPath(const ActorId &actor_id, const Path path) = 0;
/// Method to set our own imported route.
virtual void SetImportedRoute(const ActorPtr &actor, const Route route, const bool empty_buffer) = 0;
/// Method to remove a route.
virtual void RemoveImportedRoute(const ActorId &actor_id, const bool remove_path) = 0;
/// Method to update an already set route.
virtual void UpdateImportedRoute(const ActorId &actor_id, const Route route) = 0;
/// Method to set automatic respawn of dormant vehicles.
virtual void SetRespawnDormantVehicles(const bool mode_switch) = 0;
@ -116,6 +150,12 @@ public:
/// Method to set limits for boundaries when respawning vehicles.
virtual void SetMaxBoundaries(const float lower, const float upper) = 0;
/// Method to get the vehicle's next action.
virtual Action GetNextAction(const ActorId &actor_id) = 0;
/// Method to get the vehicle's action buffer.
virtual ActionBuffer GetActionBuffer(const ActorId &actor_id) = 0;
virtual void ShutDown() = 0;
protected:

View File

@ -88,6 +88,12 @@ public:
_client->call("set_global_percentage_speed_difference", percentage);
}
/// Method to set the automatic management of the vehicle lights
void SetUpdateVehicleLights(const carla::rpc::Actor &_actor, const bool do_update) {
DEBUG_ASSERT(_client != nullptr);
_client->call("update_vehicle_lights", std::move(_actor), do_update);
}
/// Method to set collision detection rules between vehicles.
void SetCollisionDetection(const carla::rpc::Actor &reference_actor, const carla::rpc::Actor &other_actor, const bool detect_collision) {
DEBUG_ASSERT(_client != nullptr);
@ -169,10 +175,22 @@ public:
_client->call("set_global_distance_to_leading_vehicle",distance);
}
/// Method to set probabilistic preference to keep on the right lane.
/// Method to set % to keep on the right lane.
void SetKeepRightPercentage(const carla::rpc::Actor &actor, const float percentage) {
DEBUG_ASSERT(_client != nullptr);
_client->call("set_percentage_keep_right_rule", actor, percentage);
_client->call("keep_right_rule_percentage", actor, percentage);
}
/// Method to set % to randomly do a left lane change.
void SetRandomLeftLaneChangePercentage(const carla::rpc::Actor &actor, const float percentage) {
DEBUG_ASSERT(_client != nullptr);
_client->call("random_left_lanechange_percentage", actor, percentage);
}
/// Method to set % to randomly do a right lane change.
void SetRandomRightLaneChangePercentage(const carla::rpc::Actor &actor, const float percentage) {
DEBUG_ASSERT(_client != nullptr);
_client->call("random_right_lanechange_percentage", actor, percentage);
}
/// Method to set hybrid physics mode.
@ -199,6 +217,42 @@ public:
_client->call("set_osm_mode", mode_switch);
}
/// Method to set our own imported path.
void SetCustomPath(const carla::rpc::Actor &actor, const Path path, const bool empty_buffer) {
DEBUG_ASSERT(_client != nullptr);
_client->call("set_path", actor, path, empty_buffer);
}
/// Method to remove a list of points.
void RemoveUploadPath(const ActorId &actor_id, const bool remove_path) {
DEBUG_ASSERT(_client != nullptr);
_client->call("remove_custom_path", actor_id, remove_path);
}
/// Method to update an already set list of points.
void UpdateUploadPath(const ActorId &actor_id, const Path path) {
DEBUG_ASSERT(_client != nullptr);
_client->call("update_custom_path", actor_id, path);
}
/// Method to set our own imported route.
void SetImportedRoute(const carla::rpc::Actor &actor, const Route route, const bool empty_buffer) {
DEBUG_ASSERT(_client != nullptr);
_client->call("set_imported_route", actor, route, empty_buffer);
}
/// Method to remove a route.
void RemoveImportedRoute(const ActorId &actor_id, const bool remove_path) {
DEBUG_ASSERT(_client != nullptr);
_client->call("remove_imported_route", actor_id, remove_path);
}
/// Method to update an already set list of points.
void UpdateImportedRoute(const ActorId &actor_id, const Route route) {
DEBUG_ASSERT(_client != nullptr);
_client->call("update_imported_route", actor_id, route);
}
/// Method to set automatic respawn of dormant vehicles.
void SetRespawnDormantVehicles(const bool mode_switch) {
DEBUG_ASSERT(_client != nullptr);
@ -217,6 +271,20 @@ public:
_client->call("set_max_boundaries", lower, upper);
}
/// Method to get the vehicle's next action.
Action GetNextAction(const ActorId &actor_id) {
DEBUG_ASSERT(_client != nullptr);
_client->call("get_next_action", actor_id);
return Action();
}
/// Method to get the vehicle's action buffer.
ActionBuffer GetActionBuffer(const ActorId &actor_id) {
DEBUG_ASSERT(_client != nullptr);
_client->call("get_all_actions", actor_id);
return ActionBuffer();
}
void ShutDown() {
DEBUG_ASSERT(_client != nullptr);
_client->call("shut_down");

View File

@ -77,6 +77,12 @@ TrafficManagerLocal::TrafficManagerLocal(
random_devices,
local_map)),
vehicle_light_stage(VehicleLightStage(vehicle_id_list,
buffer_map,
parameters,
world,
control_frame)),
alsm(ALSM(registered_vehicles,
buffer_map,
track_traffic,
@ -89,6 +95,7 @@ TrafficManagerLocal::TrafficManagerLocal(
collision_stage,
traffic_light_stage,
motion_plan_stage,
vehicle_light_stage,
random_devices)),
server(TrafficManagerServer(RPCportTM, static_cast<carla::traffic_manager::TrafficManagerBase *>(this))) {
@ -210,10 +217,14 @@ void TrafficManagerLocal::Run() {
tl_frame.clear();
tl_frame.resize(number_of_vehicles);
control_frame.clear();
// Reserve two frames for each vehicle: one for the ApplyVehicleControl command,
// and one for the optional SetVehicleLightState command
control_frame.reserve(2 * number_of_vehicles);
// Resize to accomodate at least all ApplyVehicleControl commands,
// that will be inserted by the motion_plan_stage stage.
control_frame.resize(number_of_vehicles);
// Run core operation stages.
for (unsigned long index = 0u; index < vehicle_id_list.size(); ++index) {
localization_stage.Update(index);
}
@ -221,9 +232,11 @@ void TrafficManagerLocal::Run() {
collision_stage.Update(index);
}
collision_stage.ClearCycleCache();
vehicle_light_stage.UpdateWorldInfo();
for (unsigned long index = 0u; index < vehicle_id_list.size(); ++index) {
traffic_light_stage.Update(index);
motion_plan_stage.Update(index);
vehicle_light_stage.Update(index);
}
registration_lock.unlock();
@ -337,6 +350,11 @@ void TrafficManagerLocal::SetGlobalPercentageSpeedDifference(const float percent
parameters.SetGlobalPercentageSpeedDifference(percentage);
}
/// Method to set the automatic management of the vehicle lights
void TrafficManagerLocal::SetUpdateVehicleLights(const ActorPtr &actor, const bool do_update) {
parameters.SetUpdateVehicleLights(actor, do_update);
}
void TrafficManagerLocal::SetCollisionDetection(const ActorPtr &reference_actor, const ActorPtr &other_actor, const bool detect_collision) {
parameters.SetCollisionDetection(reference_actor, other_actor, detect_collision);
}
@ -377,6 +395,14 @@ void TrafficManagerLocal::SetKeepRightPercentage(const ActorPtr &actor, const fl
parameters.SetKeepRightPercentage(actor, percentage);
}
void TrafficManagerLocal::SetRandomLeftLaneChangePercentage(const ActorPtr &actor, const float percentage) {
parameters.SetRandomLeftLaneChangePercentage(actor, percentage);
}
void TrafficManagerLocal::SetRandomRightLaneChangePercentage(const ActorPtr &actor, const float percentage) {
parameters.SetRandomRightLaneChangePercentage(actor, percentage);
}
void TrafficManagerLocal::SetHybridPhysicsMode(const bool mode_switch) {
parameters.SetHybridPhysicsMode(mode_switch);
}
@ -389,6 +415,30 @@ void TrafficManagerLocal::SetOSMMode(const bool mode_switch) {
parameters.SetOSMMode(mode_switch);
}
void TrafficManagerLocal::SetCustomPath(const ActorPtr &actor, const Path path, const bool empty_buffer) {
parameters.SetCustomPath(actor, path, empty_buffer);
}
void TrafficManagerLocal::RemoveUploadPath(const ActorId &actor_id, const bool remove_path) {
parameters.RemoveUploadPath(actor_id, remove_path);
}
void TrafficManagerLocal::UpdateUploadPath(const ActorId &actor_id, const Path path) {
parameters.UpdateUploadPath(actor_id, path);
}
void TrafficManagerLocal::SetImportedRoute(const ActorPtr &actor, const Route route, const bool empty_buffer) {
parameters.SetImportedRoute(actor, route, empty_buffer);
}
void TrafficManagerLocal::RemoveImportedRoute(const ActorId &actor_id, const bool remove_path) {
parameters.RemoveImportedRoute(actor_id, remove_path);
}
void TrafficManagerLocal::UpdateImportedRoute(const ActorId &actor_id, const Route route) {
parameters.UpdateImportedRoute(actor_id, route);
}
void TrafficManagerLocal::SetRespawnDormantVehicles(const bool mode_switch) {
parameters.SetRespawnDormantVehicles(mode_switch);
}
@ -401,6 +451,14 @@ void TrafficManagerLocal::SetMaxBoundaries(const float lower, const float upper)
parameters.SetMaxBoundaries(lower, upper);
}
Action TrafficManagerLocal::GetNextAction(const ActorId &actor_id) {
return localization_stage.ComputeNextAction(actor_id);
}
ActionBuffer TrafficManagerLocal::GetActionBuffer(const ActorId &actor_id) {
return localization_stage.ComputeActionBuffer(actor_id);
}
bool TrafficManagerLocal::CheckAllFrozen(TLGroup tl_to_freeze) {
for (auto &elem : tl_to_freeze) {
if (!elem->IsFrozen() || elem->GetState() != TLS::Red) {

View File

@ -55,9 +55,9 @@ private:
std::vector<float> longitudinal_highway_PID_parameters;
std::vector<float> lateral_PID_parameters;
std::vector<float> lateral_highway_PID_parameters;
/// Carla's client connection object.
/// CARLA client connection object.
carla::client::detail::EpisodeProxy episode_proxy;
/// Carla client and object.
/// CARLA client and object.
cc::World world;
/// Set of all actors registered with traffic manager.
AtomicActorSet registered_vehicles;
@ -93,6 +93,7 @@ private:
CollisionStage collision_stage;
TrafficLightStage traffic_light_stage;
MotionPlanStage motion_plan_stage;
VehicleLightStage vehicle_light_stage;
ALSM alsm;
/// Traffic manager server instance.
TrafficManagerServer server;
@ -165,6 +166,9 @@ public:
/// If less than 0, it's a % increase.
void SetGlobalPercentageSpeedDifference(float const percentage);
/// Method to set the automatic management of the vehicle lights
void SetUpdateVehicleLights(const ActorPtr &actor, const bool do_update);
/// Method to set collision detection rules between vehicles.
void SetCollisionDetection(const ActorPtr &reference_actor, const ActorPtr &other_actor, const bool detect_collision);
@ -210,9 +214,15 @@ public:
/// the Global leading vehicle.
void SetGlobalDistanceToLeadingVehicle(const float distance);
/// Method to set probabilistic preference to keep on the right lane.
/// Method to set % to keep on the right lane.
void SetKeepRightPercentage(const ActorPtr &actor, const float percentage);
/// Method to set % to randomly do a left lane change.
void SetRandomLeftLaneChangePercentage(const ActorPtr &actor, const float percentage);
/// Method to set % to randomly do a right lane change.
void SetRandomRightLaneChangePercentage(const ActorPtr &actor, const float percentage);
/// Method to set hybrid physics mode.
void SetHybridPhysicsMode(const bool mode_switch);
@ -225,15 +235,39 @@ public:
/// Method to set Open Street Map mode.
void SetOSMMode(const bool mode_switch);
/// Method to set our own imported path.
void SetCustomPath(const ActorPtr &actor, const Path path, const bool empty_buffer);
/// Method to remove a list of points.
void RemoveUploadPath(const ActorId &actor_id, const bool remove_path);
/// Method to update an already set list of points.
void UpdateUploadPath(const ActorId &actor_id, const Path path);
/// Method to set our own imported route.
void SetImportedRoute(const ActorPtr &actor, const Route route, const bool empty_buffer);
/// Method to remove a route.
void RemoveImportedRoute(const ActorId &actor_id, const bool remove_path);
/// Method to update an already set route.
void UpdateImportedRoute(const ActorId &actor_id, const Route route);
/// Method to set automatic respawn of dormant vehicles.
void SetRespawnDormantVehicles(const bool mode_switch);
// Method to set boundaries to respawn of dormant vehicles.
/// Method to set boundaries to respawn of dormant vehicles.
void SetBoundariesRespawnDormantVehicles(const float lower_bound, const float upper_bound);
// Method to set limits for boundaries when respawning dormant vehicles.
/// Method to set limits for boundaries when respawning dormant vehicles.
void SetMaxBoundaries(const float lower, const float upper);
/// Method to get the vehicle's next action.
Action GetNextAction(const ActorId &actor_id);
/// Method to get the vehicle's action buffer.
ActionBuffer GetActionBuffer(const ActorId &actor_id);
void ShutDown() {};
};

View File

@ -115,6 +115,12 @@ void TrafficManagerRemote::SetGlobalPercentageSpeedDifference(const float percen
client.SetGlobalPercentageSpeedDifference(percentage);
}
void TrafficManagerRemote::SetUpdateVehicleLights(const ActorPtr &_actor, const bool do_update) {
carla::rpc::Actor actor(_actor->Serialize());
client.SetUpdateVehicleLights(actor, do_update);
}
void TrafficManagerRemote::SetCollisionDetection(const ActorPtr &_reference_actor, const ActorPtr &_other_actor, const bool detect_collision) {
carla::rpc::Actor reference_actor(_reference_actor->Serialize());
carla::rpc::Actor other_actor(_other_actor->Serialize());
@ -175,6 +181,18 @@ void TrafficManagerRemote::SetKeepRightPercentage(const ActorPtr &_actor, const
client.SetKeepRightPercentage(actor, percentage);
}
void TrafficManagerRemote::SetRandomLeftLaneChangePercentage(const ActorPtr &_actor, const float percentage) {
carla::rpc::Actor actor(_actor->Serialize());
client.SetRandomLeftLaneChangePercentage(actor, percentage);
}
void TrafficManagerRemote::SetRandomRightLaneChangePercentage(const ActorPtr &_actor, const float percentage) {
carla::rpc::Actor actor(_actor->Serialize());
client.SetRandomRightLaneChangePercentage(actor, percentage);
}
void TrafficManagerRemote::SetHybridPhysicsMode(const bool mode_switch) {
client.SetHybridPhysicsMode(mode_switch);
}
@ -187,6 +205,34 @@ void TrafficManagerRemote::SetOSMMode(const bool mode_switch) {
client.SetOSMMode(mode_switch);
}
void TrafficManagerRemote::SetCustomPath(const ActorPtr &_actor, const Path path, const bool empty_buffer) {
carla::rpc::Actor actor(_actor->Serialize());
client.SetCustomPath(actor, path, empty_buffer);
}
void TrafficManagerRemote::RemoveUploadPath(const ActorId &actor_id, const bool remove_path) {
client.RemoveUploadPath(actor_id, remove_path);
}
void TrafficManagerRemote::UpdateUploadPath(const ActorId &actor_id, const Path path) {
client.UpdateUploadPath(actor_id, path);
}
void TrafficManagerRemote::SetImportedRoute(const ActorPtr &_actor, const Route route, const bool empty_buffer) {
carla::rpc::Actor actor(_actor->Serialize());
client.SetImportedRoute(actor, route, empty_buffer);
}
void TrafficManagerRemote::RemoveImportedRoute(const ActorId &actor_id, const bool remove_path) {
client.RemoveImportedRoute(actor_id, remove_path);
}
void TrafficManagerRemote::UpdateImportedRoute(const ActorId &actor_id, const Route route) {
client.UpdateImportedRoute(actor_id, route);
}
void TrafficManagerRemote::SetRespawnDormantVehicles(const bool mode_switch) {
client.SetRespawnDormantVehicles(mode_switch);
}
@ -211,6 +257,14 @@ void TrafficManagerRemote::SetSynchronousModeTimeOutInMiliSecond(double time) {
client.SetSynchronousModeTimeOutInMiliSecond(time);
}
Action TrafficManagerRemote::GetNextAction(const ActorId &actor_id) {
return client.GetNextAction(actor_id);
}
ActionBuffer TrafficManagerRemote::GetActionBuffer(const ActorId &actor_id) {
return client.GetActionBuffer(actor_id);
}
bool TrafficManagerRemote::SynchronousTick() {
return false;
}

View File

@ -19,6 +19,9 @@ namespace carla {
namespace traffic_manager {
using ActorPtr = carla::SharedPtr<carla::client::Actor>;
using Path = std::vector<cg::Location>;
using Route = std::vector<uint8_t>;
/// The function of this class is to integrate all the various stages of
/// the traffic manager appropriately using messengers.
@ -58,6 +61,9 @@ public:
/// If less than 0, it's a % increase.
void SetGlobalPercentageSpeedDifference(float const percentage);
/// Method to set the automatic management of the vehicle lights
void SetUpdateVehicleLights(const ActorPtr &actor, const bool do_update);
/// Method to set collision detection rules between vehicles.
void SetCollisionDetection(const ActorPtr &reference_actor, const ActorPtr &other_actor, const bool detect_collision);
@ -93,9 +99,15 @@ public:
/// Method to set Tick timeout for synchronous execution.
void SetSynchronousModeTimeOutInMiliSecond(double time);
/// Method to set probabilistic preference to keep on the right lane.
/// Method to set % to keep on the right lane.
void SetKeepRightPercentage(const ActorPtr &actor, const float percentage);
/// Method to set % to randomly do a left lane change.
void SetRandomLeftLaneChangePercentage(const ActorPtr &actor, const float percentage);
/// Method to set % to randomly do a right lane change.
void SetRandomRightLaneChangePercentage(const ActorPtr &actor, const float percentage);
/// Method to set hybrid physics mode.
void SetHybridPhysicsMode(const bool mode_switch);
@ -105,6 +117,24 @@ public:
/// Method to set Open Street Map mode.
void SetOSMMode(const bool mode_switch);
/// Method to set our own imported path.
void SetCustomPath(const ActorPtr &actor, const Path path, const bool empty_buffer);
/// Method to remove a path.
void RemoveUploadPath(const ActorId &actor_id, const bool remove_path);
/// Method to update an already set path.
void UpdateUploadPath(const ActorId &actor_id, const Path path);
/// Method to set our own imported route.
void SetImportedRoute(const ActorPtr &actor, const Route route, const bool empty_buffer);
/// Method to remove a route.
void RemoveImportedRoute(const ActorId &actor_id, const bool remove_path);
/// Method to update an already set route.
void UpdateImportedRoute(const ActorId &actor_id, const Route route);
/// Method to set automatic respawn of dormant vehicles.
void SetRespawnDormantVehicles(const bool mode_switch);
@ -116,6 +146,12 @@ public:
virtual void ShutDown();
/// Method to get the vehicle's next action.
Action GetNextAction(const ActorId &actor_id);
/// Method to get the vehicle's action buffer.
ActionBuffer GetActionBuffer(const ActorId &actor_id);
/// Method to provide synchronous tick
bool SynchronousTick();

View File

@ -19,6 +19,8 @@ namespace carla {
namespace traffic_manager {
using ActorPtr = carla::SharedPtr<carla::client::Actor>;
using Path = std::vector<cg::Location>;
using Route = std::vector<uint8_t>;
using namespace constants::Networking;
@ -92,6 +94,11 @@ public:
tm->SetPercentageSpeedDifference(carla::client::detail::ActorVariant(actor).Get(tm->GetEpisodeProxy()), percentage);
});
/// Method to set the automatic management of the vehicle lights
server->bind("update_vehicle_lights", [=](carla::rpc::Actor actor, const bool do_update) {
tm->SetUpdateVehicleLights(carla::client::detail::ActorVariant(actor).Get(tm->GetEpisodeProxy()), do_update);
});
/// Method to set a global % decrease in velocity with respect to the speed limit.
/// If less than 0, it's a % increase.
server->bind("set_global_percentage_speed_difference", [=](const float percentage) {
@ -138,21 +145,31 @@ public:
tm->SetPercentageRunningSign(carla::client::detail::ActorVariant(actor).Get(tm->GetEpisodeProxy()), percentage);
});
/// Method to specify the % chance of ignoring collisions with any walker.
/// Method to specify the % chance of ignoring collisions with any walker.
server->bind("set_percentage_ignore_walkers", [=](carla::rpc::Actor actor, const float percentage) {
tm->SetPercentageIgnoreWalkers(carla::client::detail::ActorVariant(actor).Get(tm->GetEpisodeProxy()), percentage);
});
/// Method to specify the % chance of ignoring collisions with any vehicle.
/// Method to specify the % chance of ignoring collisions with any vehicle.
server->bind("set_percentage_ignore_vehicles", [=](carla::rpc::Actor actor, const float percentage) {
tm->SetPercentageIgnoreVehicles(carla::client::detail::ActorVariant(actor).Get(tm->GetEpisodeProxy()), percentage);
});
/// Method to specify the % chance of ignoring collisions with any vehicle.
/// Method to set % to keep on the right lane.
server->bind("set_percentage_keep_right_rule", [=](carla::rpc::Actor actor, const float percentage) {
tm->SetKeepRightPercentage(carla::client::detail::ActorVariant(actor).Get(tm->GetEpisodeProxy()), percentage);
});
/// Method to set % to randomly do a left lane change.
server->bind("set_percentage_random_left_lanechange", [=](carla::rpc::Actor actor, const float percentage) {
tm->SetRandomLeftLaneChangePercentage(carla::client::detail::ActorVariant(actor).Get(tm->GetEpisodeProxy()), percentage);
});
/// Method to set % to randomly do a right lane change.
server->bind("set_percentage_random_right_lanechange", [=](carla::rpc::Actor actor, const float percentage) {
tm->SetRandomRightLaneChangePercentage(carla::client::detail::ActorVariant(actor).Get(tm->GetEpisodeProxy()), percentage);
});
/// Method to set hybrid physics mode.
server->bind("set_hybrid_physics_mode", [=](const bool mode_switch) {
tm->SetHybridPhysicsMode(mode_switch);
@ -165,7 +182,37 @@ public:
/// Method to set hybrid physics radius.
server->bind("set_osm_mode", [=](const bool mode_switch) {
tm->SetHybridPhysicsRadius(mode_switch);
tm->SetOSMMode(mode_switch);
});
/// Method to set our own imported path.
server->bind("set_path", [=](carla::rpc::Actor actor, const Path path, const bool empty_buffer) {
tm->SetCustomPath(carla::client::detail::ActorVariant(actor).Get(tm->GetEpisodeProxy()), path, empty_buffer);
});
/// Method to remove a list of points.
server->bind("remove_custom_path", [=](const ActorId actor_id, const bool remove_path) {
tm->RemoveUploadPath(actor_id, remove_path);
});
/// Method to update an already set list of points.
server->bind("update_custom_path", [=](const ActorId actor_id, const Path path) {
tm->UpdateUploadPath(actor_id, path);
});
/// Method to set our own imported route.
server->bind("set_imported_route", [=](carla::rpc::Actor actor, const Route route, const bool empty_buffer) {
tm->SetImportedRoute(carla::client::detail::ActorVariant(actor).Get(tm->GetEpisodeProxy()), route, empty_buffer);
});
/// Method to remove a route.
server->bind("remove_imported_route", [=](const ActorId actor_id, const bool remove_path) {
tm->RemoveImportedRoute(actor_id, remove_path);
});
/// Method to update an already set list of points.
server->bind("update_imported_route", [=](const ActorId actor_id, const Route route) {
tm->UpdateImportedRoute(actor_id, route);
});
/// Method to set respawn dormant vehicles mode.
@ -178,6 +225,16 @@ public:
tm->SetBoundariesRespawnDormantVehicles(lower_bound, upper_bound);
});
/// Method to get the vehicle's next action.
server->bind("get_next_action", [=](const ActorId actor_id) {
tm->GetNextAction(actor_id);
});
/// Method to get the vehicle's action buffer.
server->bind("get_all_actions", [=](const ActorId actor_id) {
tm->GetActionBuffer(actor_id);
});
server->bind("shut_down", [=]() {
tm->Release();
});

View File

@ -0,0 +1,156 @@
#include "carla/trafficmanager/Constants.h"
#include "carla/trafficmanager/LocalizationUtils.h"
#include "carla/trafficmanager/VehicleLightStage.h"
namespace carla {
namespace traffic_manager {
using namespace constants::VehicleLight;
VehicleLightStage::VehicleLightStage(
const std::vector<ActorId> &vehicle_id_list,
const BufferMap &buffer_map,
const Parameters &parameters,
const cc::World &world,
ControlFrame& control_frame)
: vehicle_id_list(vehicle_id_list),
buffer_map(buffer_map),
parameters(parameters),
world(world),
control_frame(control_frame) {}
void VehicleLightStage::UpdateWorldInfo() {
// Get the global weather and all the vehicle light states at once
all_light_states = world.GetVehiclesLightStates();
weather = world.GetWeather();
}
void VehicleLightStage::Update(const unsigned long index) {
ActorId actor_id = vehicle_id_list.at(index);
if (!parameters.GetUpdateVehicleLights(actor_id))
return; // this vehicle is not set to have automatic lights update
rpc::VehicleLightState::flag_type light_states = uint32_t(-1);
bool brake_lights = false;
bool left_turn_indicator = false;
bool right_turn_indicator = false;
bool position = false;
bool low_beam = false;
bool high_beam = false;
bool fog_lights = false;
// search the current light state of the vehicle
for (auto&& vls : all_light_states) {
if (vls.first == actor_id) {
light_states = vls.second;
break;
}
}
// Determine if the vehicle is truning left or right by checking the close waypoints
const Buffer& waypoint_buffer = buffer_map.at(actor_id);
cg::Location front_location = waypoint_buffer.front()->GetLocation();
for (const SimpleWaypointPtr& waypoint : waypoint_buffer) {
if (waypoint->CheckJunction()) {
RoadOption target_ro = waypoint->GetRoadOption();
if (target_ro == RoadOption::Left) left_turn_indicator = true;
else if (target_ro == RoadOption::Right) right_turn_indicator = true;
break;
}
if (cg::Math::DistanceSquared(front_location, waypoint->GetLocation()) > MAX_DISTANCE_LIGHT_CHECK) {
break;
}
}
// Determine brake light state
for (size_t cc = 0; cc < control_frame.size(); cc++) {
if (control_frame[cc].command.type() == typeid(carla::rpc::Command::ApplyVehicleControl)) {
carla::rpc::Command::ApplyVehicleControl& ctrl = boost::get<carla::rpc::Command::ApplyVehicleControl>(control_frame[cc].command);
if (ctrl.actor == actor_id) {
brake_lights = (ctrl.control.brake > 0.5); // hard braking, avoid blinking for throttle control
break;
}
}
}
// Determine position, fog and beams
// Turn on beams & positions from sunset to dawn
if (weather.sun_altitude_angle < SUN_ALTITUDE_DEGREES_BEFORE_DAWN ||
weather.sun_altitude_angle >SUN_ALTITUDE_DEGREES_AFTER_SUNSET)
{
position = true;
low_beam = true;
}
else if (weather.sun_altitude_angle < SUN_ALTITUDE_DEGREES_JUST_AFTER_DAWN ||
weather.sun_altitude_angle > SUN_ALTITUDE_DEGREES_JUST_BEFORE_SUNSET)
{
position = true;
}
// Turn on lights under heavy rain
if (weather.precipitation > HEAVY_PRECIPITATION_THRESHOLD) {
position = true;
low_beam = true;
}
// Turn on fog lights
if (weather.fog_density > FOG_DENSITY_THRESHOLD) {
position = true;
low_beam = true;
fog_lights = true;
}
// Determine the new vehicle light state
rpc::VehicleLightState::flag_type new_light_states = light_states;
if (brake_lights)
new_light_states |= rpc::VehicleLightState::flag_type(rpc::VehicleLightState::LightState::Brake);
else
new_light_states &= ~rpc::VehicleLightState::flag_type(rpc::VehicleLightState::LightState::Brake);
if (left_turn_indicator)
new_light_states |= rpc::VehicleLightState::flag_type(rpc::VehicleLightState::LightState::LeftBlinker);
else
new_light_states &= ~rpc::VehicleLightState::flag_type(rpc::VehicleLightState::LightState::LeftBlinker);
if (right_turn_indicator)
new_light_states |= rpc::VehicleLightState::flag_type(rpc::VehicleLightState::LightState::RightBlinker);
else
new_light_states &= ~rpc::VehicleLightState::flag_type(rpc::VehicleLightState::LightState::RightBlinker);
if (position)
new_light_states |= rpc::VehicleLightState::flag_type(rpc::VehicleLightState::LightState::Position);
else
new_light_states &= ~rpc::VehicleLightState::flag_type(rpc::VehicleLightState::LightState::Position);
if (low_beam)
new_light_states |= rpc::VehicleLightState::flag_type(rpc::VehicleLightState::LightState::LowBeam);
else
new_light_states &= ~rpc::VehicleLightState::flag_type(rpc::VehicleLightState::LightState::LowBeam);
if (high_beam)
new_light_states |= rpc::VehicleLightState::flag_type(rpc::VehicleLightState::LightState::HighBeam);
else
new_light_states &= ~rpc::VehicleLightState::flag_type(rpc::VehicleLightState::LightState::HighBeam);
if (fog_lights)
new_light_states |= rpc::VehicleLightState::flag_type(rpc::VehicleLightState::LightState::Fog);
else
new_light_states &= ~rpc::VehicleLightState::flag_type(rpc::VehicleLightState::LightState::Fog);
// Update the vehicle light state if it has changed
if (new_light_states != light_states)
control_frame.push_back(carla::rpc::Command::SetVehicleLightState(actor_id, new_light_states));
}
void VehicleLightStage::RemoveActor(const ActorId) {
}
void VehicleLightStage::Reset() {
}
} // namespace traffic_manager
} // namespace carla

View File

@ -0,0 +1,44 @@
#pragma once
#include "carla/trafficmanager/DataStructures.h"
#include "carla/trafficmanager/Parameters.h"
#include "carla/trafficmanager/RandomGenerator.h"
#include "carla/trafficmanager/SimulationState.h"
#include "carla/trafficmanager/Stage.h"
namespace carla {
namespace traffic_manager {
/// This class has functionality for turning on/off the vehicle lights
/// according to the current vehicle state and its surrounding environment.
class VehicleLightStage: Stage {
private:
const std::vector<ActorId> &vehicle_id_list;
const BufferMap &buffer_map;
const Parameters &parameters;
const cc::World &world;
ControlFrame& control_frame;
/// All vehicle light states
rpc::VehicleLightStateList all_light_states;
/// Current weather parameters
rpc::WeatherParameters weather;
public:
VehicleLightStage(const std::vector<ActorId> &vehicle_id_list,
const BufferMap &buffer_map,
const Parameters &parameters,
const cc::World &world,
ControlFrame& control_frame);
void UpdateWorldInfo();
void Update(const unsigned long index) override;
void RemoveActor(const ActorId actor_id) override;
void Reset() override;
};
} // namespace traffic_manager
} // namespace carla

View File

@ -11,10 +11,11 @@ It can also make use of the global route planner to follow a specifed route
import carla
from enum import Enum
from shapely.geometry import Polygon
from agents.navigation.local_planner import LocalPlanner
from agents.navigation.global_route_planner import GlobalRoutePlanner
from agents.tools.misc import get_speed, is_within_distance, get_trafficlight_trigger_location
from agents.tools.misc import get_speed, is_within_distance, get_trafficlight_trigger_location, compute_distance
class BasicAgent(object):
@ -166,7 +167,7 @@ class BasicAgent(object):
# Check for possible vehicle obstacles
max_vehicle_distance = self._base_vehicle_threshold + vehicle_speed
affected_by_vehicle, _ = self._vehicle_obstacle_detected(vehicle_list, max_vehicle_distance)
affected_by_vehicle, _, _ = self._vehicle_obstacle_detected(vehicle_list, max_vehicle_distance)
if affected_by_vehicle:
hazard_detected = True
@ -248,7 +249,7 @@ class BasicAgent(object):
return (False, None)
def _vehicle_obstacle_detected(self, vehicle_list=None, max_distance=None):
def _vehicle_obstacle_detected(self, vehicle_list=None, max_distance=None, up_angle_th=90, low_angle_th=0, lane_offset=0):
"""
Method to check if there is a vehicle in front of the agent blocking its path.
@ -258,7 +259,7 @@ class BasicAgent(object):
If None, the base threshold value is used
"""
if self._ignore_vehicles:
return (False, None)
return (False, None, -1)
if not vehicle_list:
vehicle_list = self._world.get_actors().filter("*vehicle*")
@ -269,6 +270,10 @@ class BasicAgent(object):
ego_transform = self._vehicle.get_transform()
ego_wpt = self._map.get_waypoint(self._vehicle.get_location())
# Get the right offset
if ego_wpt.lane_id < 0 and lane_offset != 0:
lane_offset *= -1
# Get the transform of the front of the ego
ego_forward_vector = ego_transform.get_forward_vector()
ego_extent = self._vehicle.bounding_box.extent.x
@ -280,22 +285,71 @@ class BasicAgent(object):
for target_vehicle in vehicle_list:
target_transform = target_vehicle.get_transform()
target_wpt = self._map.get_waypoint(target_transform.location)
if target_wpt.road_id != ego_wpt.road_id or target_wpt.lane_id != ego_wpt.lane_id:
next_wpt = self._local_planner.get_incoming_waypoint_and_direction(steps=3)[0]
if not next_wpt:
continue
if target_wpt.road_id != next_wpt.road_id or target_wpt.lane_id != next_wpt.lane_id:
continue
target_wpt = self._map.get_waypoint(target_transform.location, lane_type=carla.LaneType.Any)
target_forward_vector = target_transform.get_forward_vector()
target_extent = target_vehicle.bounding_box.extent.x
target_rear_transform = target_transform
target_rear_transform.location -= carla.Location(
x=target_extent * target_forward_vector.x,
y=target_extent * target_forward_vector.y,
)
# Simplified version for outside junctions
if not ego_wpt.is_junction or not target_wpt.is_junction:
if is_within_distance(target_rear_transform, ego_front_transform, max_distance, [0, 90]):
return (True, target_vehicle)
return (False, None)
if target_wpt.road_id != ego_wpt.road_id or target_wpt.lane_id != ego_wpt.lane_id + lane_offset:
next_wpt = self._local_planner.get_incoming_waypoint_and_direction(steps=3)[0]
if not next_wpt:
continue
if target_wpt.road_id != next_wpt.road_id or target_wpt.lane_id != next_wpt.lane_id + lane_offset:
continue
target_forward_vector = target_transform.get_forward_vector()
target_extent = target_vehicle.bounding_box.extent.x
target_rear_transform = target_transform
target_rear_transform.location -= carla.Location(
x=target_extent * target_forward_vector.x,
y=target_extent * target_forward_vector.y,
)
if is_within_distance(target_rear_transform, ego_front_transform, max_distance, [low_angle_th, up_angle_th]):
return (True, target_vehicle, compute_distance(target_transform.location, ego_transform.location))
# Waypoints aren't reliable, check the proximity of the vehicle to the route
else:
route_bb = []
ego_location = ego_transform.location
extent_y = self._vehicle.bounding_box.extent.y
r_vec = ego_transform.get_right_vector()
p1 = ego_location + carla.Location(extent_y * r_vec.x, extent_y * r_vec.y)
p2 = ego_location + carla.Location(-extent_y * r_vec.x, -extent_y * r_vec.y)
route_bb.append([p1.x, p1.y, p1.z])
route_bb.append([p2.x, p2.y, p2.z])
for wp, _ in self._local_planner.get_plan():
if ego_location.distance(wp.transform.location) > max_distance:
break
r_vec = wp.transform.get_right_vector()
p1 = wp.transform.location + carla.Location(extent_y * r_vec.x, extent_y * r_vec.y)
p2 = wp.transform.location + carla.Location(-extent_y * r_vec.x, -extent_y * r_vec.y)
route_bb.append([p1.x, p1.y, p1.z])
route_bb.append([p2.x, p2.y, p2.z])
if len(route_bb) < 3:
# 2 points don't create a polygon, nothing to check
return (False, None, -1)
ego_polygon = Polygon(route_bb)
# Compare the two polygons
for target_vehicle in vehicle_list:
target_extent = target_vehicle.bounding_box.extent.x
if target_vehicle.id == self._vehicle.id:
continue
if ego_location.distance(target_vehicle.get_location()) > max_distance:
continue
target_bb = target_vehicle.bounding_box
target_vertices = target_bb.get_world_vertices(target_vehicle.get_transform())
target_list = [[v.x, v.y, v.z] for v in target_vertices]
target_polygon = Polygon(target_list)
if ego_polygon.intersects(target_polygon):
return (True, target_vehicle, compute_distance(target_vehicle.get_location(), ego_location))
return (False, None, -1)
return (False, None, -1)

View File

@ -81,62 +81,6 @@ class BehaviorAgent(BasicAgent):
if self._incoming_direction is None:
self._incoming_direction = RoadOption.LANEFOLLOW
def _vehicle_obstacle_detected(self, vehicle_list, proximity_th, up_angle_th, low_angle_th=0, lane_offset=0):
"""
Check if a given vehicle is an obstacle in our way. To this end we take
into account the road and lane the target vehicle is on and run a
geometry test to check if the target vehicle is under a certain distance
in front of our ego vehicle. We also check the next waypoint, just to be
sure there's not a sudden road id change.
WARNING: This method is an approximation that could fail for very large
vehicles, which center is actually on a different lane but their
extension falls within the ego vehicle lane. Also, make sure to remove
the ego vehicle from the list. Lane offset is set to +1 for right lanes
and -1 for left lanes, but this has to be inverted if lane values are
negative.
:param vehicle_list: list of potential obstacle to check
:param proximity_th: threshold for the agent to be alerted of
a possible collision
:param up_angle_th: upper threshold for angle
:param low_angle_th: lower threshold for angle
:param lane_offset: for right and left lane changes
:return: a tuple given by (bool_flag, vehicle, distance), where:
- bool_flag is True if there is a vehicle ahead blocking us
and False otherwise
- vehicle is the blocker object itself
- distance is the meters separating the two vehicles
"""
ego_transform = self._vehicle.get_transform()
ego_location = ego_transform.location
ego_wpt = self._map.get_waypoint(ego_location)
# Get the right offset
if ego_wpt.lane_id < 0 and lane_offset != 0:
lane_offset *= -1
for target_vehicle in vehicle_list:
target_transform = target_vehicle.get_transform()
target_location = target_transform.location
# If the object is not in our next or current lane it's not an obstacle
target_wpt = self._map.get_waypoint(target_location)
if target_wpt.road_id != ego_wpt.road_id or \
target_wpt.lane_id != ego_wpt.lane_id + lane_offset:
next_wpt = self._local_planner.get_incoming_waypoint_and_direction(steps=5)[0]
if target_wpt.road_id != next_wpt.road_id or \
target_wpt.lane_id != next_wpt.lane_id + lane_offset:
continue
if is_within_distance(target_transform, ego_transform,
proximity_th, [low_angle_th, up_angle_th]):
return (True, target_vehicle, compute_distance(target_location, ego_location))
return (False, None, -1)
def traffic_light_manager(self):
"""
This method is in charge of behaviors for red lights.

View File

@ -227,7 +227,7 @@ class GlobalRoutePlanner(object):
if not segment['entry'].is_junction:
next_waypoint, next_road_option, next_segment = None, None, None
if waypoint.right_lane_marking.lane_change & carla.LaneChange.Right and not right_found:
if waypoint.right_lane_marking and waypoint.right_lane_marking.lane_change & carla.LaneChange.Right and not right_found:
next_waypoint = waypoint.get_right_lane()
if next_waypoint is not None \
and next_waypoint.lane_type == carla.LaneType.Driving \
@ -240,7 +240,7 @@ class GlobalRoutePlanner(object):
exit_waypoint=next_waypoint, intersection=False, exit_vector=None,
path=[], length=0, type=next_road_option, change_waypoint=next_waypoint)
right_found = True
if waypoint.left_lane_marking.lane_change & carla.LaneChange.Left and not left_found:
if waypoint.left_lane_marking and waypoint.left_lane_marking.lane_change & carla.LaneChange.Left and not left_found:
next_waypoint = waypoint.get_left_lane()
if next_waypoint is not None \
and next_waypoint.lane_type == carla.LaneType.Driving \

View File

@ -181,12 +181,12 @@ class LocalPlanner(object):
def set_global_plan(self, current_plan, stop_waypoint_creation=True, clean_queue=True):
"""
Adds a new plan to the local planner. A plan must be a list of [carla.Waypoint, RoadOption] pairs
If 'clean_queue`, erases the previous plan, and if not, it is added to the old one
The 'stop_waypoint_creation' flag avoids creating more random waypoints
The 'clean_queue` parameter erases the previous plan if True, otherwise, it adds it to the old one
The 'stop_waypoint_creation' flag stops the automatic creation of random waypoints
:param current_plan: list of (carla.Waypoint, RoadOption)
:param stop_waypoint_creation: bool
:param ceal_queue: bool
:param clean_queue: bool
:return:
"""
if clean_queue:
@ -275,6 +275,10 @@ class LocalPlanner(object):
except IndexError as i:
return None, RoadOption.VOID
def get_plan(self):
"""Returns the current plan of the local planner"""
return self._waypoints_queue
def done(self):
"""
Returns whether or not the planner has finished

View File

@ -2,3 +2,4 @@ networkx
numpy; python_version < '3.0'
numpy==1.18.4; python_version >= '3.0'
distro
Shapely==1.6.4.post2

View File

@ -162,7 +162,7 @@ with open("README.md") as f:
setup(
name='carla',
version='0.9.12',
version='0.9.13',
package_dir={'': 'source'},
packages=['carla'],
ext_modules=get_libcarla_extensions(),

View File

@ -154,11 +154,21 @@ void export_actor() {
.value("Back_Wheel", cr::VehicleWheelLocation::Back_Wheel)
;
enum_<cr::VehicleDoor>("VehicleDoor")
.value("FL", cr::VehicleDoor::FL)
.value("FR", cr::VehicleDoor::FR)
.value("RL", cr::VehicleDoor::RL)
.value("RR", cr::VehicleDoor::RR)
.value("All", cr::VehicleDoor::All)
;
class_<cc::Vehicle, bases<cc::Actor>, boost::noncopyable, boost::shared_ptr<cc::Vehicle>>("Vehicle",
no_init)
.def("apply_control", &cc::Vehicle::ApplyControl, (arg("control")))
.def("get_control", &cc::Vehicle::GetControl)
.def("set_light_state", &cc::Vehicle::SetLightState, (arg("light_state")))
.def("open_door", &cc::Vehicle::OpenDoor, (arg("door_idx")))
.def("close_door", &cc::Vehicle::CloseDoor, (arg("door_idx")))
.def("set_wheel_steer_direction", &cc::Vehicle::SetWheelSteerDirection, (arg("wheel_location")), (arg("angle_in_deg")))
.def("get_wheel_steer_angle", &cc::Vehicle::GetWheelSteerAngle, (arg("wheel_location")))
.def("get_light_state", CONST_CALL_WITHOUT_GIL(cc::Vehicle, GetLightState))
@ -178,8 +188,13 @@ void export_actor() {
class_<cc::Walker, bases<cc::Actor>, boost::noncopyable, boost::shared_ptr<cc::Walker>>("Walker", no_init)
.def("apply_control", &ApplyControl<cr::WalkerControl>, (arg("control")))
.def("apply_control", &ApplyControl<cr::WalkerBoneControl>, (arg("control")))
.def("get_control", &cc::Walker::GetWalkerControl)
.def("get_bones", &cc::Walker::GetBonesTransform)
.def("set_bones", &cc::Walker::SetBonesTransform, (arg("bones")))
.def("blend_pose", &cc::Walker::BlendPose, (arg("blend")))
.def("show_pose", &cc::Walker::ShowPose)
.def("hide_pose", &cc::Walker::HidePose)
.def("get_pose_from_animation", &cc::Walker::GetPoseFromAnimation)
.def(self_ns::str(self_ns::self))
;

View File

@ -93,6 +93,12 @@ static void RegisterActorConstellationCallback(carla::client::RssSensor &self, b
self.RegisterActorConstellationCallback(callback_function);
}
static void Stop(carla::client::RssSensor &self) {
// ensure the RssSensor is stopped with GIL released to sync on processing lock
carla::PythonUtil::ReleaseGIL unlock;
self.Stop();
}
void export_ad() {
using namespace boost::python;
@ -186,6 +192,7 @@ void export_ad_rss() {
.add_property("pedestrian_dynamics", &GetPedestrianDynamics, &cc::RssSensor::SetPedestrianDynamics)
.add_property("road_boundaries_mode", &GetRoadBoundariesMode, &cc::RssSensor::SetRoadBoundariesMode)
.add_property("routing_targets", &GetRoutingTargets)
.def("stop", &Stop)
.def("register_actor_constellation_callback", &RegisterActorConstellationCallback, (arg("callback")))
.def("append_routing_target", &cc::RssSensor::AppendRoutingTarget, (arg("routing_target")))
.def("reset_routing_targets", &cc::RssSensor::ResetRoutingTargets)
@ -199,5 +206,6 @@ void export_ad_rss() {
.def(init<>())
.def("restrict_vehicle_control", &carla::rss::RssRestrictor::RestrictVehicleControl,
(arg("vehicle_control"), arg("proper_response"), arg("ego_dynamics_on_route"), arg("vehicle_physics")))
.def("set_log_level", &carla::rss::RssRestrictor::SetLogLevel, (arg("log_level")))
.def(self_ns::str(self_ns::self));
}

View File

@ -103,6 +103,17 @@ void export_blueprint() {
.def(self_ns::str(self_ns::self))
;
class_<crpc::FloatColor>("FloatColor")
.def(init<float, float, float, float>(
(arg("r")=0, arg("g")=0.f, arg("b")=0.f, arg("a")=1.0f)))
.def_readwrite("r", &crpc::FloatColor::r)
.def_readwrite("g", &crpc::FloatColor::g)
.def_readwrite("b", &crpc::FloatColor::b)
.def_readwrite("a", &crpc::FloatColor::a)
.def("__eq__", &crpc::FloatColor::operator==)
.def("__ne__", &crpc::FloatColor::operator!=)
;
class_<csd::OpticalFlowPixel>("OpticalFlowPixel")
.def(init<float, float>(
(arg("x")=0, arg("y")=0)))

View File

@ -9,7 +9,8 @@
#include <carla/rpc/VehiclePhysicsControl.h>
#include <carla/rpc/WheelPhysicsControl.h>
#include <carla/rpc/WalkerControl.h>
#include <carla/rpc/WalkerBoneControl.h>
#include <carla/rpc/WalkerBoneControlIn.h>
#include <carla/rpc/WalkerBoneControlOut.h>
#include <ostream>
@ -38,8 +39,8 @@ namespace rpc {
return out;
}
std::ostream &operator<<(std::ostream &out, const WalkerBoneControl &control) {
out << "WalkerBoneControl(bone_transforms(";
std::ostream &operator<<(std::ostream &out, const WalkerBoneControlIn &control) {
out << "WalkerBoneControlIn(bone_transforms(";
for (auto bone_transform : control.bone_transforms) {
out << "(name=" << bone_transform.first
<< ", transform=" << bone_transform.second << ')';
@ -48,6 +49,21 @@ namespace rpc {
return out;
}
std::ostream &operator<<(std::ostream &out, const BoneTransformDataOut &data) {
out << "BoneTransformDataOut(name=" << data.bone_name << ", world=" << data.world << ", component=" << data.component << ", relative=" << data.relative << ')';
return out;
}
std::ostream &operator<<(std::ostream &out, const WalkerBoneControlOut &control) {
out << "WalkerBoneControlOut(bone_transforms(";
for (auto bone_transform : control.bone_transforms) {
out << "(name=" << bone_transform.bone_name
<< ", world=" << bone_transform.world << ", component=" << bone_transform.component << ", relative=" << bone_transform.relative << ')';
}
out << "))";
return out;
}
std::ostream &operator<<(std::ostream &out, const GearPhysicsControl &control) {
out << "GearPhysicsControl(ratio=" << std::to_string(control.ratio)
<< ", down_ratio=" << std::to_string(control.down_ratio)
@ -111,16 +127,16 @@ static auto GetVectorOfVector2DFromList(const boost::python::list &list) {
}
static auto GetVectorOfBoneTransformFromList(const boost::python::list &list) {
std::vector<carla::rpc::BoneTransformData> v;
std::vector<carla::rpc::BoneTransformDataIn> v;
auto length = boost::python::len(list);
v.reserve(static_cast<size_t>(length));
for (auto i = 0u; i < length; ++i) {
boost::python::extract<carla::rpc::BoneTransformData> ext(list[i]);
boost::python::extract<carla::rpc::BoneTransformDataIn> ext(list[i]);
if (ext.check()) {
v.push_back(ext);
} else {
v.push_back(carla::rpc::BoneTransformData{
v.push_back(carla::rpc::BoneTransformDataIn{
boost::python::extract<std::string>(list[i][0u]),
boost::python::extract<carla::geom::Transform>(list[i][1u])});
}
@ -227,18 +243,26 @@ boost::python::object VehiclePhysicsControl_init(boost::python::tuple args, boos
return res;
}
static auto GetBonesTransform(const carla::rpc::WalkerBoneControl &self) {
const std::vector<carla::rpc::BoneTransformData> &bone_transform_data = self.bone_transforms;
static auto GetBonesTransform(const carla::rpc::WalkerBoneControlIn &self) {
const std::vector<carla::rpc::BoneTransformDataIn> &bone_transform_data = self.bone_transforms;
boost::python::object get_iter =
boost::python::iterator<const std::vector<carla::rpc::BoneTransformData>>();
boost::python::iterator<const std::vector<carla::rpc::BoneTransformDataIn>>();
boost::python::object iter = get_iter(bone_transform_data);
return boost::python::list(iter);
}
static void SetBonesTransform(carla::rpc::WalkerBoneControl &self, const boost::python::list &list) {
static void SetBonesTransform(carla::rpc::WalkerBoneControlIn &self, const boost::python::list &list) {
self.bone_transforms = GetVectorOfBoneTransformFromList(list);
}
static auto GetBonesTransformOut(const carla::rpc::WalkerBoneControlOut &self) {
const std::vector<carla::rpc::BoneTransformDataOut> &bone_transform_data = self.bone_transforms;
boost::python::object get_iter =
boost::python::iterator<const std::vector<carla::rpc::BoneTransformDataOut>>();
boost::python::object iter = get_iter(bone_transform_data);
return boost::python::list(iter);
}
boost::python::object WalkerBoneControl_init(boost::python::tuple args, boost::python::dict kwargs) {
// Args names
const uint32_t NUM_ARGUMENTS = 1;
@ -304,13 +328,51 @@ void export_control() {
.def(self_ns::str(self_ns::self))
;
class_<cr::WalkerBoneControl>("WalkerBoneControl")
class_<cr::BoneTransformDataIn>("bone_transform")
.def(init<>())
.def_readwrite("name", &std::pair<std::string, cg::Transform>::first)
.def_readwrite("transform", &std::pair<std::string, cg::Transform>::second)
.def(self_ns::str(self_ns::self))
;
class_<std::vector<cr::BoneTransformDataIn>>("vector_of_bones")
.def(init<>())
.def(boost::python::vector_indexing_suite<std::vector<cr::BoneTransformDataIn>>())
.def(self_ns::str(self_ns::self))
;
class_<cr::BoneTransformDataOut>("bone_transform_out")
.def(init<>())
.def_readwrite("name", &cr::BoneTransformDataOut::bone_name)
.def_readwrite("world", &cr::BoneTransformDataOut::world)
.def_readwrite("component", &cr::BoneTransformDataOut::component)
.def_readwrite("relative", &cr::BoneTransformDataOut::relative)
.def(self_ns::str(self_ns::self))
.def("__eq__", &cr::BoneTransformDataOut::operator==)
.def("__ne__", &cr::BoneTransformDataOut::operator!=)
;
class_<std::vector<cr::BoneTransformDataOut>>("vector_of_bones_out")
.def(init<>())
.def(boost::python::vector_indexing_suite<std::vector<cr::BoneTransformDataOut>>())
.def(self_ns::str(self_ns::self))
;
class_<cr::WalkerBoneControlIn>("WalkerBoneControlIn")
.def("__init__", raw_function(WalkerBoneControl_init))
.def(init<>())
.add_property("bone_transforms", &GetBonesTransform, &SetBonesTransform)
.def(self_ns::str(self_ns::self))
;
class_<cr::WalkerBoneControlOut>("WalkerBoneControlOut")
.def("__init__", raw_function(WalkerBoneControl_init))
.def(init<>())
// .add_property("bone_transforms", &GetBonesTransformOut, &SetBonesTransformOut)
.add_property("bone_transforms", &GetBonesTransformOut)
.def(self_ns::str(self_ns::self))
;
class_<std::vector<cr::GearPhysicsControl>>("vector_of_gears")
.def(boost::python::vector_indexing_suite<std::vector<cr::GearPhysicsControl>>())
.def(self_ns::str(self_ns::self))

View File

@ -103,6 +103,38 @@ static auto GetInverseTransformMatrix(const carla::geom::Transform &self) {
return BuildMatrix(self.GetInverseMatrix());
}
static auto Cross(const carla::geom::Vector3D &self, const carla::geom::Vector3D &other) {
return carla::geom::Math::Cross(self, other);
}
static auto Dot(const carla::geom::Vector3D &self, const carla::geom::Vector3D &other) {
return carla::geom::Math::Dot(self, other);
}
static auto Distance(const carla::geom::Vector3D &self, const carla::geom::Vector3D &other) {
return carla::geom::Math::Distance(self, other);
}
static auto DistanceSquared(const carla::geom::Vector3D &self, const carla::geom::Vector3D &other) {
return carla::geom::Math::DistanceSquared(self, other);
}
static auto Dot2D(const carla::geom::Vector3D &self, const carla::geom::Vector3D &other) {
return carla::geom::Math::Dot2D(self, other);
}
static auto Distance2D(const carla::geom::Vector3D &self, const carla::geom::Vector3D &other) {
return carla::geom::Math::Distance2D(self, other);
}
static auto DistanceSquared2D(const carla::geom::Vector3D &self, const carla::geom::Vector3D &other) {
return carla::geom::Math::DistanceSquared2D(self, other);
}
static auto GetVectorAngle(const carla::geom::Vector3D &self, const carla::geom::Vector3D &other) {
return carla::geom::Math::GetVectorAngle(self, other);
}
void export_geom() {
using namespace boost::python;
namespace cg = carla::geom;
@ -115,6 +147,9 @@ void export_geom() {
.def(init<float, float>((arg("x")=0.0f, arg("y")=0.0f)))
.def_readwrite("x", &cg::Vector2D::x)
.def_readwrite("y", &cg::Vector2D::y)
.def("squared_length", &cg::Vector2D::SquaredLength)
.def("length", &cg::Vector2D::Length)
.def("make_unit_vector", &cg::Vector2D::MakeUnitVector)
.def("__eq__", &cg::Vector2D::operator==)
.def("__ne__", &cg::Vector2D::operator!=)
.def(self += self)
@ -139,6 +174,17 @@ void export_geom() {
.def_readwrite("x", &cg::Vector3D::x)
.def_readwrite("y", &cg::Vector3D::y)
.def_readwrite("z", &cg::Vector3D::z)
.def("length", &cg::Vector3D::Length)
.def("squared_length", &cg::Vector3D::SquaredLength)
.def("make_unit_vector", &cg::Vector3D::MakeUnitVector)
.def("cross", &Cross, (arg("vector")))
.def("dot", &Dot, (arg("vector")))
.def("dot_2d", &Dot2D, (arg("vector")))
.def("distance", &Distance, (arg("vector")))
.def("distance_2d", &Distance2D, (arg("vector")))
.def("distance_squared", &DistanceSquared, (arg("vector")))
.def("distance_squared_2d", &DistanceSquared2D, (arg("vector")))
.def("get_vector_angle", &GetVectorAngle, (arg("vector")))
.def("__eq__", &cg::Vector3D::operator==)
.def("__ne__", &cg::Vector3D::operator!=)
.def("__abs__", &cg::Vector3D::Abs)

View File

@ -365,7 +365,7 @@ void export_sensor_data() {
namespace css = carla::sensor::s11n;
// Fake image returned from optical flow to color conversion
// fakes the regular image object
// fakes the regular image object. Only used for visual purposes
class_<FakeImage>("FakeImage", no_init)
.def(vector_indexing_suite<std::vector<uint8_t>>())
.add_property("width", &FakeImage::Width)

View File

@ -6,11 +6,78 @@
#include <chrono>
#include <memory>
#include <stdio.h>
#include "carla/PythonUtil.h"
#include "boost/python/suite/indexing/vector_indexing_suite.hpp"
#include "carla/trafficmanager/TrafficManager.h"
#include "carla/trafficmanager/SimpleWaypoint.h"
using ActorPtr = carla::SharedPtr<carla::client::Actor>;
using ActorId = carla::ActorId;
const char* RoadOptionToString(carla::client::RoadOption value) {
switch (value)
{
case carla::client::RoadOption::Void: return "Void";
case carla::client::RoadOption::Left: return "Left";
case carla::client::RoadOption::Right: return "Right";
case carla::client::RoadOption::Straight: return "Straight";
case carla::client::RoadOption::LaneFollow: return "LaneFollow";
case carla::client::RoadOption::ChangeLaneLeft: return "ChangeLaneLeft";
case carla::client::RoadOption::ChangeLaneRight: return "ChangeLaneRight";
case carla::client::RoadOption::RoadEnd: return "RoadEnd";
default: return "[Unknown RoadOption]";
}
}
std::vector<uint8_t> RoadOptionToUint(boost::python::list input) {
std::vector<uint8_t> route;
for (int i = 0; i < len(input); ++i) {
uint8_t val;
char* str = boost::python::extract<char*>(input[i]);
if (strcmp(str,"Void") == 0) val = 0u;
else if (strcmp(str,"Left") == 0) val = 1u;
else if (strcmp(str,"Right") == 0) val = 2u;
else if (strcmp(str,"Straight") == 0) val = 3u;
else if (strcmp(str,"LaneFollow") == 0) val = 4u;
else if (strcmp(str,"ChangeLaneLeft") == 0) val = 5u;
else if (strcmp(str,"ChangeLaneRight") == 0) val = 6u;
else if (strcmp(str,"RoadEnd") == 0) val = 7u;
else val = 10u;
route.push_back(val);
}
return route;
}
void InterSetCustomPath(carla::traffic_manager::TrafficManager& self, const ActorPtr &actor, boost::python::list input, bool empty_buffer) {
self.SetCustomPath(actor, PythonLitstToVector<carla::geom::Location>(input), empty_buffer);
}
void InterSetImportedRoute(carla::traffic_manager::TrafficManager& self, const ActorPtr &actor, boost::python::list input, bool empty_buffer) {
self.SetImportedRoute(actor, RoadOptionToUint(input), empty_buffer);
}
boost::python::list InterGetNextAction(carla::traffic_manager::TrafficManager& self, const ActorPtr &actor_ptr) {
boost::python::list l;
auto next_action = self.GetNextAction(actor_ptr->GetId());
l.append(RoadOptionToString(next_action.first));
l.append(next_action.second);
return l;
}
boost::python::list InterGetActionBuffer(carla::traffic_manager::TrafficManager& self, const ActorPtr &actor_ptr) {
boost::python::list l;
auto action_buffer = self.GetActionBuffer(actor_ptr->GetId());
for (auto &next_action : action_buffer) {
boost::python::list temp;
temp.append(RoadOptionToString(next_action.first));
temp.append(next_action.second);
l.append(temp);
}
return l;
}
void export_trafficmanager() {
namespace cc = carla::client;
@ -21,6 +88,7 @@ void export_trafficmanager() {
.def("get_port", &ctm::TrafficManager::Port)
.def("vehicle_percentage_speed_difference", &ctm::TrafficManager::SetPercentageSpeedDifference)
.def("global_percentage_speed_difference", &ctm::TrafficManager::SetGlobalPercentageSpeedDifference)
.def("update_vehicle_lights", &ctm::TrafficManager::SetUpdateVehicleLights)
.def("collision_detection", &ctm::TrafficManager::SetCollisionDetection)
.def("force_lane_change", &ctm::TrafficManager::SetForceLaneChange)
.def("auto_lane_change", &ctm::TrafficManager::SetAutoLaneChange)
@ -30,13 +98,19 @@ void export_trafficmanager() {
.def("ignore_lights_percentage", &ctm::TrafficManager::SetPercentageRunningLight)
.def("ignore_signs_percentage", &ctm::TrafficManager::SetPercentageRunningSign)
.def("set_global_distance_to_leading_vehicle", &ctm::TrafficManager::SetGlobalDistanceToLeadingVehicle)
.def("set_percentage_keep_right_rule", &ctm::TrafficManager::SetKeepRightPercentage)
.def("keep_right_rule_percentage", &ctm::TrafficManager::SetKeepRightPercentage)
.def("random_left_lanechange_percentage", &ctm::TrafficManager::SetRandomLeftLaneChangePercentage)
.def("random_right_lanechange_percentage", &ctm::TrafficManager::SetRandomRightLaneChangePercentage)
.def("set_synchronous_mode", &ctm::TrafficManager::SetSynchronousMode)
.def("set_hybrid_physics_mode", &ctm::TrafficManager::SetHybridPhysicsMode)
.def("set_hybrid_physics_radius", &ctm::TrafficManager::SetHybridPhysicsRadius)
.def("set_random_device_seed", &ctm::TrafficManager::SetRandomDeviceSeed)
.def("set_osm_mode", &carla::traffic_manager::TrafficManager::SetOSMMode)
.def("set_path", &InterSetCustomPath, (arg("empty_buffer") = true))
.def("set_route", &InterSetImportedRoute, (arg("empty_buffer") = true))
.def("set_respawn_dormant_vehicles", &carla::traffic_manager::TrafficManager::SetRespawnDormantVehicles)
.def("set_boundaries_respawn_dormant_vehicles", &carla::traffic_manager::TrafficManager::SetBoundariesRespawnDormantVehicles)
.def("get_next_action", &InterGetNextAction)
.def("get_all_actions", &InterGetActionBuffer)
.def("shut_down", &ctm::TrafficManager::ShutDown);
}

View File

@ -125,6 +125,7 @@ void export_world() {
namespace cc = carla::client;
namespace cg = carla::geom;
namespace cr = carla::rpc;
namespace csd = carla::sensor::data;
class_<cc::Timestamp>("Timestamp")
.def(init<size_t, double, double, double>(
@ -245,6 +246,39 @@ void export_world() {
.value("All", cr::MapLayer::All)
;
enum_<cr::MaterialParameter>("MaterialParameter")
.value("Normal", cr::MaterialParameter::Tex_Normal)
.value("AO_Roughness_Metallic_Emissive", cr::MaterialParameter::Tex_Ao_Roughness_Metallic_Emissive)
.value("Diffuse", cr::MaterialParameter::Tex_Diffuse)
.value("Emissive", cr::MaterialParameter::Tex_Emissive)
;
class_<cr::TextureColor>("TextureColor")
.def(init<uint32_t, uint32_t>())
.add_property("width", &cr::TextureColor::GetWidth)
.add_property("height", &cr::TextureColor::GetHeight)
.def("set_dimensions", &cr::TextureColor::SetDimensions)
.def("get", +[](const cr::TextureColor &self, int x, int y) -> csd::Color{
return self.At(static_cast<uint32_t>(x), static_cast<uint32_t>(y));
})
.def("set", +[](cr::TextureColor &self, int x, int y, csd::Color& value) {
self.At(static_cast<uint32_t>(x), static_cast<uint32_t>(y)) = value;
})
;
class_<cr::TextureFloatColor>("TextureFloatColor")
.def(init<uint32_t, uint32_t>())
.add_property("width", &cr::TextureFloatColor::GetWidth)
.add_property("height", &cr::TextureFloatColor::GetHeight)
.def("set_dimensions", &cr::TextureFloatColor::SetDimensions)
.def("get", +[](const cr::TextureFloatColor &self, int x, int y) -> cr::FloatColor{
return self.At(static_cast<uint32_t>(x), static_cast<uint32_t>(y));
})
.def("set", +[](cr::TextureFloatColor &self, int x, int y, cr::FloatColor& value) {
self.At(static_cast<uint32_t>(x), static_cast<uint32_t>(y)) = value;
})
;
#define SPAWN_ACTOR_WITHOUT_GIL(fn) +[]( \
cc::World &self, \
const cc::ActorBlueprint &blueprint, \
@ -285,6 +319,7 @@ void export_world() {
.def("remove_on_tick", &cc::World::RemoveOnTick, (arg("callback_id")))
.def("tick", &Tick, (arg("seconds")=0.0))
.def("set_pedestrians_cross_factor", CALL_WITHOUT_GIL_1(cc::World, SetPedestriansCrossFactor, float), (arg("percentage")))
.def("set_pedestrians_seed", CALL_WITHOUT_GIL_1(cc::World, SetPedestriansSeed, unsigned int), (arg("seed")))
.def("get_traffic_sign", CONST_CALL_WITHOUT_GIL_1(cc::World, GetTrafficSign, cc::Landmark), arg("landmark"))
.def("get_traffic_light", CONST_CALL_WITHOUT_GIL_1(cc::World, GetTrafficLight, cc::Landmark), arg("landmark"))
.def("get_traffic_light_from_opendrive_id", CONST_CALL_WITHOUT_GIL_1(cc::World, GetTrafficLightFromOpenDRIVE, const carla::road::SignId&), arg("traffic_light_id"))
@ -299,6 +334,19 @@ void export_world() {
.def("cast_ray", CALL_RETURNING_LIST_2(cc::World, CastRay, cg::Location, cg::Location), (arg("initial_location"), arg("final_location")))
.def("project_point", CALL_RETURNING_OPTIONAL_3(cc::World, ProjectPoint, cg::Location, cg::Vector3D, float), (arg("location"), arg("direction"), arg("search_distance")=10000.f))
.def("ground_projection", CALL_RETURNING_OPTIONAL_2(cc::World, GroundProjection, cg::Location, float), (arg("location"), arg("search_distance")=10000.f))
.def("get_names_of_all_objects", CALL_RETURNING_LIST(cc::World, GetNamesOfAllObjects))
.def("apply_color_texture_to_object", &cc::World::ApplyColorTextureToObject, (arg("object_name"), arg("material_parameter"), arg("texture")))
.def("apply_float_color_texture_to_object", &cc::World::ApplyFloatColorTextureToObject, (arg("object_name"), arg("material_parameter"), arg("texture")))
.def("apply_textures_to_object", &cc::World::ApplyTexturesToObject, (arg("object_name"), arg("diffuse_texture"), arg("emissive_texture"), arg("normal_texture"), arg("ao_roughness_metallic_emissive_texture")))
.def("apply_color_texture_to_objects", +[](cc::World &self, boost::python::list &list, const cr::MaterialParameter& parameter, const cr::TextureColor& Texture) {
self.ApplyColorTextureToObjects(PythonLitstToVector<std::string>(list), parameter, Texture);
}, (arg("objects_name_list"), arg("material_parameter"), arg("texture")))
.def("apply_float_color_texture_to_objects", +[](cc::World &self, boost::python::list &list, const cr::MaterialParameter& parameter, const cr::TextureFloatColor& Texture) {
self.ApplyFloatColorTextureToObjects(PythonLitstToVector<std::string>(list), parameter, Texture);
}, (arg("objects_name_list"), arg("material_parameter"), arg("texture")))
.def("apply_textures_to_objects", +[](cc::World &self, boost::python::list &list, const cr::TextureColor& diffuse_texture, const cr::TextureFloatColor& emissive_texture, const cr::TextureFloatColor& normal_texture, const cr::TextureFloatColor& ao_roughness_metallic_emissive_texture) {
self.ApplyTexturesToObjects(PythonLitstToVector<std::string>(list), diffuse_texture, emissive_texture, normal_texture, ao_roughness_metallic_emissive_texture);
}, (arg("objects_name_list"), arg("diffuse_texture"), arg("emissive_texture"), arg("normal_texture"), arg("ao_roughness_metallic_emissive_texture")))
.def(self_ns::str(self_ns::self))
;

View File

@ -180,6 +180,12 @@ namespace std {
return PrintList(out, vector_of_stuff);
}
template <typename T, typename H>
std::ostream &operator<<(std::ostream &out, const std::pair<T,H> &data) {
out << "(" << data.first << "," << data.second << ")";
return out;
}
} // namespace std
static carla::time_duration TimeDurationFromSeconds(double seconds) {

View File

@ -141,6 +141,28 @@
doc: >
Enables or disables the telemetry on this vehicle. This shows information about the vehicles current state and forces applied to it in the spectator window. Only information for one vehicle can be shown so if you enable a second one, the previous will be automatically disabled.
# --------------------------------------
- def_name: open_door
params:
- param_name: door_idx
type: carla.VehicleDoor
doc: >
door index
doc: >
Open the door door_idx if the vehicle has it. Use carla.VehicleDoor.All to open all available doors.
note: >
Only carla.Vehicle actors can use this method.
# --------------------------------------
- def_name: close_door
params:
- param_name: door_idx
type: carla.VehicleDoor
doc: >
door index
doc: >
Close the door door_idx if the vehicle has it. Use carla.VehicleDoor.All to close all available doors.
note: >
Only carla.Vehicle actors can use this method.
# --------------------------------------
- def_name: get_acceleration
return: carla.Vector3D
return_units: m/s<sup>2</sup>
@ -402,18 +424,53 @@
doc: >
On the next tick, the control will move the walker in a certain direction with a certain speed. Jumps can be commanded too.
# --------------------------------------
- def_name: apply_control
params:
- param_name: control
type: carla.WalkerBoneControl
doc: >
On the next tick, the control defines a list of bone transformations that will be applied to the walker's skeleton.
# --------------------------------------
- def_name: get_control
return: carla.WalkerControl
doc: >
The client returns the control applied to this walker during last tick. The method does not call the simulator.
# --------------------------------------
- def_name: get_bones
return: carla.WalkerBoneControlOut
doc: >
Return the structure with all the bone transformations from the actor. For each bone, we get the name and its transform in three different spaces:
- name: bone name
- world: transform in world coordinates
- component: transform based on the pivot of the actor
- relative: transform based on the bone parent
# --------------------------------------
- def_name: set_bones
params:
- param_name: bones
type: carla.WalkerBoneControlIn
param_units: list of pairs (bone_name, transform) for the bones that we want to set
doc: >
Set the bones of the actor. For each bone we want to set we use a relative transform. Only the bones in this list will be set. For each bone you need to setup this info:
- name: bone name
- relative: transform based on the bone parent
# --------------------------------------
- def_name: blend_pose
params:
- param_name: blend_value
type: float
param_units: value from 0 to 1 with the blend percentage
doc: >
Set the blending value of the custom pose with the animation. The values can be:
- 0: will show only the animation
- 1: will show only the custom pose (set by the user with set_bones())
- any other: will interpolate all the bone positions between animation and the custom pose
# --------------------------------------
- def_name: show_pose
doc: >
Show the custom pose and hide the animation (same as calling blend_pose(1))
# --------------------------------------
- def_name: hide_pose
doc: >
Hide the custom pose and show the animation (same as calling blend_pose(0))
# --------------------------------------
- def_name: get_pose_from_animation
doc: >
Make a copy of the current animation frame as the custom pose. Initially the custom pose is the neutral pedestrian pose.
# --------------------------------------
- def_name: __str__
# --------------------------------------
@ -631,4 +688,26 @@
doc: >
Back wheel of a 2 wheeled vehicle.
# --------------------------------------
- class_name: VehicleDoor
doc: >
Possible index representing the possible doors that can be open.
Notice that not all possible doors are able to open in some vehicles.
# - PROPERTIES -------------------------
instance_variables:
- var_name: FL
doc: >
Front left door.
- var_name: FR
doc: >
Front right door.
- var_name: RL
doc: >
Back left door.
- var_name: RR
doc: >
Back right door.
- var_name: All
doc: >
Represents all doors.
# --------------------------------------
...

View File

@ -68,6 +68,58 @@
# --------------------------------------
- def_name: __str__
# --------------------------------------
- class_name: FloatColor
# - DESCRIPTION ------------------------
doc: >
Class that defines a float RGBA color.
# - PROPERTIES -------------------------
instance_variables:
- var_name: r
type: float
doc: >
Red color.
- var_name: g
type: float
doc: >
Green color.
- var_name: b
type: float
doc: >
Blue color.
- var_name: a
type: float
doc: >
Alpha channel.
# - METHODS ----------------------------
methods:
- def_name: __init__
params:
- param_name: r
type: float
default: 0
- param_name: g
type: float
default: 0
- param_name: b
type: float
default: 0
- param_name: a
type: float
default: 1.0
doc: >
Initializes a color, black by default.
# --------------------------------------
- def_name: __eq__
params:
- param_name: other
type: carla.FloatColor
# --------------------------------------
- def_name: __ne__
params:
- param_name: other
type: carla.FloatColor
# --------------------------------------
- class_name: OpticalFlowPixel
# - DESCRIPTION ------------------------

View File

@ -164,7 +164,7 @@ def generate_pb_docs():
md.list_push(code(attr.id))
md.text(' ' + parentheses(italic(str(attr.type))))
if attr.is_modifiable:
md.text(sub(italic(' Modifiable')))
md.text(' ' + sub(italic('- Modifiable')))
md.list_popn()
md.list_pop()
md.list_pop()

View File

@ -42,7 +42,7 @@
doc: >
A list of commands to execute in batch. Each command is different and has its own parameters. They appear listed at the bottom of this page.
doc: >
Executes a list of commands on a single simulation step and retrieves no information. If you need information about the response of each command, use the __<font color="#7fb800">apply_batch_sync()</font>__ method.
Executes a list of commands on a single simulation step and retrieves no information. If you need information about the response of each command, use the __<font color="#7fb800">apply_batch_sync()</font>__ method.
[Here](https://github.com/carla-simulator/carla/blob/master/PythonAPI/examples/generate_traffic.py) is an example on how to delete the actors that appear in carla.ActorList all at once.
# --------------------------------------
- def_name: apply_batch_sync
@ -438,7 +438,7 @@
doc: >
Between 0 and 100. Amount of times stop signs will be ignored.
doc: >
During the traffic light stage, which runs every frame, this method sets the percent chance that stop signs will be ignored for a vehicle.
During the traffic light stage, which runs every frame, this method sets the percent chance that stop signs will be ignored for a vehicle.
# --------------------------------------
- def_name: ignore_vehicles_percentage
params:
@ -481,6 +481,21 @@
Default is 30. Exceeding a speed limit can be done using negative percentages.
# --------------------------------------
- def_name: update_vehicle_lights
params:
- param_name: actor
type: carla.Actor
doc: >
Vehicle whose lights status is being changed.
- param_name: do_update
type: bool
doc: >
If __True__ the traffic manager will manage the vehicle lights for the specified vehicle.
doc: >
Sets if the Traffic Manager is responsible of updating the vehicle lights, or not.
Default is __False__. The traffic manager will not change the vehicle light status of a vehicle, unless its auto_update_status is st to __True__.
# --------------------------------------
- def_name: get_port
params:
return: uint16
@ -524,11 +539,11 @@
type: bool
default: true
doc: >
If __True__, the OSM mode is enabled.
If __True__, the OSM mode is enabled.
doc: >
Enables or disables the OSM mode. This mode allows the user to run TM in a map created with the [OSM feature](tuto_G_openstreetmap.md). These maps allow having dead-end streets. Normally, if vehicles cannot find the next waypoint, TM crashes. If OSM mode is enabled, it will show a warning, and destroy vehicles when necessary.
Enables or disables the OSM mode. This mode allows the user to run TM in a map created with the [OSM feature](tuto_G_openstreetmap.md). These maps allow having dead-end streets. Normally, if vehicles cannot find the next waypoint, TM crashes. If OSM mode is enabled, it will show a warning, and destroy vehicles when necessary.
# --------------------------------------
- def_name: set_percentage_keep_right_rule
- def_name: keep_right_rule_percentage
params:
- param_name: actor
type: carla.Actor
@ -546,7 +561,7 @@
- param_name: value
type: int
doc: >
Seed value for the random number generation of the Traffic Manager.
Seed value for the random number generation of the Traffic Manager.
doc: >
Sets a specific random seed for the Traffic Manager, thereby setting it to be deterministic.
# --------------------------------------
@ -556,11 +571,11 @@
type: bool
default: true
doc: >
If __True__, the TM synchronous mode is enabled.
If __True__, the TM synchronous mode is enabled.
doc: >
Sets the Traffic Manager to [synchronous mode](adv_traffic_manager.md#synchronous-mode). In a [multiclient situation](adv_traffic_manager.md#multiclient), only the TM-Server can tick. Similarly, in a [multiTM situation](adv_traffic_manager.md#multitm), only one TM-Server must tick. Use this method in the client that does the world tick, and right after setting the world to synchronous mode, to set which TM will be the master while in sync.
Sets the Traffic Manager to [synchronous mode](adv_traffic_manager.md#synchronous-mode). In a [multiclient situation](adv_traffic_manager.md#multiclient), only the TM-Server can tick. Similarly, in a [multiTM situation](adv_traffic_manager.md#multitm), only one TM-Server must tick. Use this method in the client that does the world tick, and right after setting the world to synchronous mode, to set which TM will be the master while in sync.
warning: >
If the server is set to synchronous mode, the TM <b>must</b> be set to synchronous mode too in the same client that does the tick.
If the server is set to synchronous mode, the TM <b>must</b> be set to synchronous mode too in the same client that does the tick.
# --------------------------------------
- def_name: set_respawn_dormant_vehicles
params:

View File

@ -88,7 +88,7 @@
- class_name: WalkerControl
doc: >
This class defines specific directions that can be commanded to a carla.Walker to control it via script. The walker's animations will blend automatically with the parameters defined in this class when applied, though specific skeleton moves can be obtained through class.WalkerBoneControl.
This class defines specific directions that can be commanded to a carla.Walker to control it via script.
AI control can be settled for walkers, but the control used to do so is carla.WalkerAIController.
@ -142,7 +142,26 @@
- def_name: __str__
# --------------------------------------
- class_name: WalkerBoneControl
- class_name: WalkerBoneControlOut
# - DESCRIPTION ------------------------
doc: >
This class is used to return all bone positions of a pedestrian. For each bone we get its _name_ and its transform in three different spaces (world, actor and relative).
# - PROPERTIES -------------------------
instance_variables:
- var_name: bone_transforms
type: list([name,world, actor, relative])
doc: >
List of one entry per bone with this information:
- name: bone name
- world: transform in world coordinates
- component: transform based on the pivot of the actor
- relative: transform based on the bone parent
# - METHODS ----------------------------
methods:
- def_name: __str__
# --------------------------------------
- class_name: WalkerBoneControlIn
# - DESCRIPTION ------------------------
doc: >
This class grants bone specific manipulation for walker. The skeletons of walkers have been unified for clarity and the transform applied to each bone are always relative to its parent. Take a look [here](tuto_G_control_walker_skeletons.md) to learn more on how to create a walker and define its movement.
@ -151,7 +170,9 @@
- var_name: bone_transforms
type: list([name,transform])
doc: >
List of tuples where the first value is the bone's name and the second value stores the transformation (changes in location and rotation) that will be applied to it.
List with the data for each bone we want to set:
- name: bone name
- relative: transform based on the bone parent
# - METHODS ----------------------------
methods:
- def_name: __init__

View File

@ -265,6 +265,7 @@ def append_code_snipets(md):
snipets_path = os.path.join(current_folder, '../../Docs/python_api_snipets.md')
snipets = open(snipets_path, 'r')
md.text(snipets.read())
snipets.close()
os.remove(snipets_path)
@ -393,13 +394,13 @@ def add_doc_method_param(md, param):
if valid_dic_val(param, 'doc'):
param_doc = create_hyperlinks(md.prettify_doc(param['doc']))
if valid_dic_val(param, 'param_units'):
param_units = small_html(' '+param['param_units'])
param_units = small_html(' - '+param['param_units'])
param_type = '' if not param_type else parentheses(italic(param_type+param_units))
md.list_push(code(param_name))
if param_type:
md.text(' ' + param_type)
if param_doc:
md.textn(' ' + param_doc)
md.textn(' - ' + param_doc)
else:
md.new_line()
md.list_pop()
@ -436,7 +437,7 @@ def add_doc_method(md, method, class_key):
md.list_push(bold('Return:') + ' ')
return_units = ''
if valid_dic_val(method, 'return_units'):
return_units = small_html(' '+method['return_units'])
return_units = small_html(' - '+method['return_units'])
md.textn(italic(create_hyperlinks(method['return'])+return_units))
md.list_pop()
@ -490,7 +491,7 @@ def add_doc_getter_setter(md, method, class_key, is_getter, other_list):
md.list_push(bold('Return:') + ' ')
return_units = ''
if valid_dic_val(method, 'return_units'):
return_units = small_html(' '+method['return_units'])
return_units = small_html(' - '+method['return_units'])
md.textn(italic(create_hyperlinks(method['return'])+return_units))
md.list_pop()
@ -566,7 +567,7 @@ def add_doc_inst_var(md, inst_var, class_key):
# Instance variable type
if valid_dic_val(inst_var, 'type'):
if valid_dic_val(inst_var, 'var_units'):
var_units = small_html(' '+inst_var['var_units'])
var_units = small_html(' - '+inst_var['var_units'])
var_type = ' ' + parentheses(italic(create_hyperlinks(inst_var['type']+var_units)))
md.list_pushn(
html_key(var_key) +

View File

@ -26,6 +26,24 @@
type: float
default: 0.0
# --------------------------------------
- def_name: length
return: float
params:
doc: >
Computes the length of the vector.
# --------------------------------------
- def_name: squared_length
return: float
params:
doc: >
Computes the squared length of the vector.
# --------------------------------------
- def_name: make_unit_vector
return: carla.Vector3D
params:
doc: >
Returns a vector with the same direction and unitary length.
# --------------------------------------
- def_name: __add__
params:
- param_name: other
@ -100,6 +118,80 @@
type: float
default: 0.0
# --------------------------------------
- def_name: length
return: float
params:
doc: >
Computes the length of the vector.
# --------------------------------------
- def_name: squared_length
return: float
params:
doc: >
Computes the squared length of the vector.
# --------------------------------------
- def_name: make_unit_vector
return: carla.Vector3D
params:
doc: >
Returns a vector with the same direction and unitary length.
# --------------------------------------
- def_name: cross
return: carla.Vector3D
params:
- param_name: vector
type: carla.Vector3D
doc: >
Computes the cross product between two vectors.
# --------------------------------------
- def_name: dot
return: float
params:
- param_name: vector
type: carla.Vector3D
doc: >
Computes the dot product between two vectors.
# --------------------------------------
- def_name: distance
return: float
params:
- param_name: vector
type: carla.Vector3D
doc: >
Computes the distance between two vectors.
# --------------------------------------
- def_name: distance_squared
return: float
params:
- param_name: vector
type: carla.Vector3D
doc: >
Computes the squared distance between two vectors.
# --------------------------------------
- def_name: dot_2d
return: float
params:
- param_name: vector
type: carla.Vector3D
doc: >
Computes the 2-dimensional dot product between two vectors.
# --------------------------------------
- def_name: distance_2d
return: float
params:
- param_name: vector
type: carla.Vector3D
doc: >
Computes the 2-dimensional distance between two vectors.
# --------------------------------------
- def_name: distance_squared_2d
return: float
params:
- param_name: vector
type: carla.Vector3D
doc: >
Computes the 2-dimensional squared distance between two vectors.
# --------------------------------------
- def_name: __add__
params:
- param_name: other
@ -226,7 +318,7 @@
# - 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*
@ -269,7 +361,7 @@
param_units: degrees
doc: >
X-axis rotation angle.
warning: The declaration order is different in CARLA <code>(pitch,yaw,roll)</code>, and in the Unreal Engine Editor <code>(roll,pitch,yaw)</code>. When working in a build from source, don't mix up the axes' rotations.
warning: The declaration order is different in CARLA <code>(pitch,yaw,roll)</code>, and in the Unreal Engine Editor <code>(roll,pitch,yaw)</code>. When working in a build from source, don't mix up the axes' rotations.
# --------------------------------------
- def_name: get_forward_vector
params:
@ -421,7 +513,7 @@
type: carla.Location
var_units: meters
doc: >
Center of the box, relative to its parent.
Center of the box, relative to its parent.
- param_name: extent
type: carla.Vector3D
param_units: meters

View File

@ -153,6 +153,14 @@
carla.VehicleControl
doc: >
Applies the safety restrictions given by a carla.RssSensor to a carla.VehicleControl.
- def_name: set_log_level
params:
- param_name: log_level
type: carla.RssLogLevel
doc: >
New log level.
doc: >
Sets the log level.
# --------------------------------------
- class_name: RssRoadBoundariesMode

View File

@ -288,6 +288,132 @@
All layers selected
# --------------------------------------
- class_name: MaterialParameter
# - DESCRIPTION ------------------------
doc: >
Class that represents material parameters. Not all objects in the scene contain all parameters.
# - PROPERTIES -------------------------
instance_variables:
- var_name: Normal
doc: >
The Normal map of the object. Present in all objects.
- var_name: Diffuse
doc: >
The Diffuse texture of the object. Present in all objects.
- var_name: AO_Roughness_Metallic_Emissive
doc: >
A texture where each color channel represent a property of the material (R: Ambien oclusion, G: Roughness, B: Metallic, A: Emissive/Height map in some objects)
- var_name: Emissive
doc: >
Emissive texture. Present in a few objects.
# --------------------------------------
- class_name: TextureColor
# - DESCRIPTION ------------------------
doc: >
Class representing a texture object to be uploaded to the server. Pixel format is RGBA, uint8 per channel.
# - PROPERTIES -------------------------
instance_variables:
- var_name: width
type: int
doc: >
X-coordinate size of the texture.
- var_name: height
type: int
doc: >
Y-coordinate size of the texture.
# - METHODS ----------------------------
methods:
- def_name: __init__
params:
- param_name: width
type: int
- param_name: height
type: int
doc: >
Initializes a the texture with a (`width`, `height`) size.
- def_name: set_dimensions
params:
- param_name: width
type: int
- param_name: height
type: int
doc: >
Resizes the texture to te specified dimensions.
- def_name: get
return: carla.Color
params:
- param_name: x
type: int
- param_name: y
type: int
doc: >
Get the (x,y) pixel data.
- def_name: set
params:
- param_name: x
type: int
- param_name: y
type: int
- param_name: value
type: carla.Color
doc: >
Sets the (x,y) pixel data with `value`.
# --------------------------------------
- class_name: TextureFloatColor
# - DESCRIPTION ------------------------
doc: >
Class representing a texture object to be uploaded to the server. Pixel format is RGBA, float per channel.
# - PROPERTIES -------------------------
instance_variables:
- var_name: width
type: int
doc: >
X-coordinate size of the texture.
- var_name: height
type: int
doc: >
Y-coordinate size of the texture.
# - METHODS ----------------------------
methods:
- def_name: __init__
params:
- param_name: width
type: int
- param_name: height
type: int
doc: >
Initializes a the texture with a (`width`, `height`) size.
- def_name: set_dimensions
params:
- param_name: width
type: int
- param_name: height
type: int
doc: >
Resizes the texture to te specified dimensions.
- def_name: get
return: carla.FloatColor
params:
- param_name: x
type: int
- param_name: y
type: int
doc: >
Get the (x,y) pixel data.
- def_name: set
params:
- param_name: x
type: int
- param_name: y
type: int
- param_name: value
type: carla.FloatColor
doc: >
Sets the (x,y) pixel data with `value`.
# --------------------------------------
- class_name: World
# - DESCRIPTION ------------------------
doc: >
@ -660,6 +786,95 @@
note: >
Should be set before pedestrians are spawned.
# --------------------------------------
- def_name: set_pedestrians_seed
params:
- param_name: seed
type: int
doc: >
Sets the seed to use for any random number generated in relation to pedestrians.
note: >
Should be set before pedestrians are spawned.
If you want to repeat the same exact bodies (blueprint) for each pedestrian, then use the same seed in the Python code (where the blueprint is choosen randomly) and here, otherwise the pedestrians will repeat the same paths but the bodies will be different.
# --------------------------------------
- def_name: apply_color_texture_to_object
params:
- param_name: object_name
type: str
- param_name: material_parameter
type: carla.MaterialParameter
- param_name: texture
type: TextureColor
doc: >
Applies a `texture` object in the field corresponfing to `material_parameter` (normal, diffuse, etc) to the object in the scene corresponding to `object_name`.
# --------------------------------------
- def_name: apply_float_color_texture_to_object
params:
- param_name: object_name
type: str
- param_name: material_parameter
type: carla.MaterialParameter
- param_name: texture
type: TextureFloatColor
doc: >
Applies a `texture` object in the field corresponfing to `material_parameter` (normal, diffuse, etc) to the object in the scene corresponding to `object_name`.
# --------------------------------------
- def_name: apply_textures_to_object
params:
- param_name: object_name
type: str
- param_name: diffuse_texture
type: TextureColor
- param_name: emissive_texture
type: TextureFloatColor
- param_name: normal_texture
type: TextureFloatColor
- param_name: ao_roughness_metallic_emissive_texture
type: TextureFloatColor
doc: >
Applies all texture fields in carla.MaterialParameter to the object `object_name`. Empty textures here will not be applied.
# --------------------------------------
- def_name: apply_color_texture_to_objects
params:
- param_name: objects_name_list
type: list(str)
- param_name: material_parameter
type: carla.MaterialParameter
- param_name: texture
type: TextureColor
doc: >
Applies a `texture` object in the field corresponfing to `material_parameter` (normal, diffuse, etc) to the object in the scene corresponding to all objects in `objects_name_list`.
# --------------------------------------
- def_name: apply_float_color_texture_to_objects
params:
- param_name: objects_name_list
type: list(str)
- param_name: material_parameter
type: carla.MaterialParameter
- param_name: texture
type: TextureFloatColor
doc: >
Applies a `texture` object in the field corresponfing to `material_parameter` (normal, diffuse, etc) to the object in the scene corresponding to all objects in `objects_name_list`.
# --------------------------------------
- def_name: apply_textures_to_objects
params:
- param_name: objects_name_list
type: list(str)
- param_name: diffuse_texture
type: TextureColor
- param_name: emissive_texture
type: TextureFloatColor
- param_name: normal_texture
type: TextureFloatColor
- param_name: ao_roughness_metallic_emissive_texture
type: TextureFloatColor
doc: >
Applies all texture fields in carla.MaterialParameter to all objects in `objects_name_list`. Empty textures here will not be applied.
# --------------------------------------
- def_name: get_names_of_all_objects
return: list(str)
doc: >
Returns a list of the names of all objects in the scene that can be painted with the apply texture functions.
# --------------------------------------
- def_name: __str__
return:
string

View File

@ -0,0 +1,430 @@
#!/usr/bin/env python
# Copyright (c) 2021 Computer Vision Center (CVC) at the Universitat Autonoma de
# Barcelona (UAB).
#
# This work is licensed under the terms of the MIT license.
# For a copy, see <https://opensource.org/licenses/MIT>.
import glob
import os
import sys
import math
import argparse
import copy
import time
from multiprocessing import Pool
from PIL import Image
try:
sys.path.append(glob.glob('../carla/dist/carla-*%d.%d-%s.egg' % (
sys.version_info.major,
sys.version_info.minor,
'win-amd64' if os.name == 'nt' else 'linux-x86_64'))[0])
except IndexError:
pass
import carla
import random
try:
import pygame
except ImportError:
raise RuntimeError('cannot import pygame, make sure pygame package is installed')
try:
import numpy as np
except ImportError:
raise RuntimeError('cannot import numpy, make sure numpy package is installed')
try:
import queue
except ImportError:
import Queue as queue
class CarlaSyncMode(object):
"""
Context manager to synchronize output from different sensors. Synchronous
mode is enabled as long as we are inside this context
with CarlaSyncMode(world, sensors) as sync_mode:
while True:
data = sync_mode.tick(timeout=1.0)
"""
def __init__(self, world, *sensors, **kwargs):
self.world = world
self.sensors = sensors
self.frame = None
self.delta_seconds = 1.0 / kwargs.get('fps', 20)
self._queues = []
self._settings = None
def __enter__(self):
self._settings = self.world.get_settings()
self.frame = self.world.apply_settings(carla.WorldSettings(
no_rendering_mode=False,
synchronous_mode=True,
fixed_delta_seconds=self.delta_seconds))
def make_queue(register_event):
q = queue.Queue()
register_event(q.put)
self._queues.append(q)
make_queue(self.world.on_tick)
for sensor in self.sensors:
make_queue(sensor.listen)
return self
def tick(self, timeout):
self.frame = self.world.tick()
data = [self._retrieve_data(q, timeout) for q in self._queues]
assert all(x.frame == self.frame for x in data)
return data
def __exit__(self, *args, **kwargs):
self.world.apply_settings(self._settings)
def _retrieve_data(self, sensor_queue, timeout):
while True:
data = sensor_queue.get(timeout=timeout)
if data.frame == self.frame:
return data
# ---------------
def build_projection_matrix(w, h, fov):
focal = w / (2.0 * np.tan(fov * np.pi / 360.0))
K = np.identity(3)
K[0, 0] = K[1, 1] = focal
K[0, 2] = w / 2.0
K[1, 2] = h / 2.0
return K
def get_image_as_array(image):
array = np.frombuffer(image.raw_data, dtype=np.dtype("uint8"))
array = np.reshape(array, (image.height, image.width, 4))
array = array[:, :, :3]
array = array[:, :, ::-1]
# make the array writeable doing a deep copy
array2 = copy.deepcopy(array)
return array2
def draw_image(surface, array, blend=False):
image_surface = pygame.surfarray.make_surface(array.swapaxes(0, 1))
if blend:
image_surface.set_alpha(100)
surface.blit(image_surface, (0, 0))
def get_font():
fonts = [x for x in pygame.font.get_fonts()]
default_font = 'ubuntumono'
font = default_font if default_font in fonts else fonts[0]
font = pygame.font.match_font(font)
return pygame.font.Font(font, 14)
def get_screen_points(camera, K, image_w, image_h, points3d):
# get 4x4 matrix to transform points from world to camera coordinates
world_2_camera = np.array(camera.get_transform().get_inverse_matrix())
# build the points array in numpy format as (x, y, z, 1) to be operable with a 4x4 matrix
points_temp = []
for p in points3d:
points_temp += [p.x, p.y, p.z, 1]
points = np.array(points_temp).reshape(-1, 4).T
# convert world points to camera space
points_camera = np.dot(world_2_camera, points)
# New we must change from UE4's coordinate system to an "standard"
# (x, y ,z) -> (y, -z, x)
# and we remove the fourth component also
points = np.array([
points_camera[1],
points_camera[2] * -1,
points_camera[0]])
# Finally we can use our K matrix to do the actual 3D -> 2D.
points_2d = np.dot(K, points)
# normalize the values and transpose
points_2d = np.array([
points_2d[0, :] / points_2d[2, :],
points_2d[1, :] / points_2d[2, :],
points_2d[2, :]]).T
return points_2d
def draw_points_on_buffer(buffer, image_w, image_h, points_2d, color, size=4):
half = int(size / 2)
# draw each point
for p in points_2d:
x = int(p[0])
y = int(p[1])
for j in range(y - half, y + half):
if (j >=0 and j <image_h):
for i in range(x - half, x + half):
if (i >=0 and i <image_w):
buffer[j][i][0] = color[0]
buffer[j][i][1] = color[1]
buffer[j][i][2] = color[2]
def draw_line_on_buffer(buffer, image_w, image_h, points_2d, color, size=4):
x0 = int(points_2d[0][0])
y0 = int(points_2d[0][1])
x1 = int(points_2d[1][0])
y1 = int(points_2d[1][1])
dx = abs(x1 - x0)
if x0 < x1:
sx = 1
else:
sx = -1
dy = -abs(y1 - y0)
if y0 < y1:
sy = 1
else:
sy = -1
err = dx + dy
while True:
draw_points_on_buffer(buffer, image_w, image_h, ((x0,y0),), color, size)
if (x0 == x1 and y0 == y1):
break
e2 = 2 * err
if (e2 >= dy):
err += dy
x0 += sx
if (e2 <= dx):
err += dx
y0 += sy
def draw_skeleton(buffer, image_w, image_h, boneIndex, points2d, color, size=4):
try:
# draw_line_on_buffer(buffer, image_w, image_h, (points2d[boneIndex["crl_root"]], points2d[boneIndex["crl_hips__C"]]), color, size)
draw_line_on_buffer(buffer, image_w, image_h, (points2d[boneIndex["crl_hips__C"]], points2d[boneIndex["crl_spine__C"]]), color, size)
draw_line_on_buffer(buffer, image_w, image_h, (points2d[boneIndex["crl_hips__C"]], points2d[boneIndex["crl_thigh__R"]]), color, size)
draw_line_on_buffer(buffer, image_w, image_h, (points2d[boneIndex["crl_hips__C"]], points2d[boneIndex["crl_thigh__L"]]), color, size)
draw_line_on_buffer(buffer, image_w, image_h, (points2d[boneIndex["crl_spine__C"]], points2d[boneIndex["crl_spine01__C"]]), color, size)
draw_line_on_buffer(buffer, image_w, image_h, (points2d[boneIndex["crl_spine01__C"]], points2d[boneIndex["crl_shoulder__L"]]), color, size)
draw_line_on_buffer(buffer, image_w, image_h, (points2d[boneIndex["crl_spine01__C"]], points2d[boneIndex["crl_neck__C"]]), color, size)
draw_line_on_buffer(buffer, image_w, image_h, (points2d[boneIndex["crl_spine01__C"]], points2d[boneIndex["crl_shoulder__R"]]), color, size)
draw_line_on_buffer(buffer, image_w, image_h, (points2d[boneIndex["crl_shoulder__L"]], points2d[boneIndex["crl_arm__L"]]), color, size)
draw_line_on_buffer(buffer, image_w, image_h, (points2d[boneIndex["crl_arm__L"]], points2d[boneIndex["crl_foreArm__L"]]), color, size)
draw_line_on_buffer(buffer, image_w, image_h, (points2d[boneIndex["crl_foreArm__L"]], points2d[boneIndex["crl_hand__L"]]), color, size)
draw_line_on_buffer(buffer, image_w, image_h, (points2d[boneIndex["crl_hand__L"]], points2d[boneIndex["crl_handThumb__L"]]), color, size)
draw_line_on_buffer(buffer, image_w, image_h, (points2d[boneIndex["crl_hand__L"]], points2d[boneIndex["crl_handIndex__L"]]), color, size)
draw_line_on_buffer(buffer, image_w, image_h, (points2d[boneIndex["crl_hand__L"]], points2d[boneIndex["crl_handMiddle__L"]]), color, size)
draw_line_on_buffer(buffer, image_w, image_h, (points2d[boneIndex["crl_hand__L"]], points2d[boneIndex["crl_handRing__L"]]), color, size)
draw_line_on_buffer(buffer, image_w, image_h, (points2d[boneIndex["crl_hand__L"]], points2d[boneIndex["crl_handPinky__L"]]), color, size)
draw_line_on_buffer(buffer, image_w, image_h, (points2d[boneIndex["crl_handThumb__L"]], points2d[boneIndex["crl_handThumb01__L"]]), color, size)
draw_line_on_buffer(buffer, image_w, image_h, (points2d[boneIndex["crl_handThumb01__L"]], points2d[boneIndex["crl_handThumb02__L"]]), color, size)
draw_line_on_buffer(buffer, image_w, image_h, (points2d[boneIndex["crl_handThumb02__L"]], points2d[boneIndex["crl_handThumbEnd__L"]]), color, size)
draw_line_on_buffer(buffer, image_w, image_h, (points2d[boneIndex["crl_handIndex__L"]], points2d[boneIndex["crl_handIndex01__L"]]), color, size)
draw_line_on_buffer(buffer, image_w, image_h, (points2d[boneIndex["crl_handIndex01__L"]], points2d[boneIndex["crl_handIndex02__L"]]), color, size)
draw_line_on_buffer(buffer, image_w, image_h, (points2d[boneIndex["crl_handIndex02__L"]], points2d[boneIndex["crl_handIndexEnd__L"]]), color, size)
draw_line_on_buffer(buffer, image_w, image_h, (points2d[boneIndex["crl_handMiddle__L"]], points2d[boneIndex["crl_handMiddle01__L"]]), color, size)
draw_line_on_buffer(buffer, image_w, image_h, (points2d[boneIndex["crl_handMiddle01__L"]], points2d[boneIndex["crl_handMiddle02__L"]]), color, size)
draw_line_on_buffer(buffer, image_w, image_h, (points2d[boneIndex["crl_handMiddle02__L"]], points2d[boneIndex["crl_handMiddleEnd__L"]]), color, size)
draw_line_on_buffer(buffer, image_w, image_h, (points2d[boneIndex["crl_handRing__L"]], points2d[boneIndex["crl_handRing01__L"]]), color, size)
draw_line_on_buffer(buffer, image_w, image_h, (points2d[boneIndex["crl_handRing01__L"]], points2d[boneIndex["crl_handRing02__L"]]), color, size)
draw_line_on_buffer(buffer, image_w, image_h, (points2d[boneIndex["crl_handRing02__L"]], points2d[boneIndex["crl_handRingEnd__L"]]), color, size)
draw_line_on_buffer(buffer, image_w, image_h, (points2d[boneIndex["crl_handPinky__L"]], points2d[boneIndex["crl_handPinky01__L"]]), color, size)
draw_line_on_buffer(buffer, image_w, image_h, (points2d[boneIndex["crl_handPinky01__L"]], points2d[boneIndex["crl_handPinky02__L"]]), color, size)
draw_line_on_buffer(buffer, image_w, image_h, (points2d[boneIndex["crl_handPinky02__L"]], points2d[boneIndex["crl_handPinkyEnd__L"]]), color, size)
draw_line_on_buffer(buffer, image_w, image_h, (points2d[boneIndex["crl_neck__C"]], points2d[boneIndex["crl_Head__C"]]), color, size)
draw_line_on_buffer(buffer, image_w, image_h, (points2d[boneIndex["crl_Head__C"]], points2d[boneIndex["crl_eye__L"]]), color, size)
draw_line_on_buffer(buffer, image_w, image_h, (points2d[boneIndex["crl_Head__C"]], points2d[boneIndex["crl_eye__R"]]), color, size)
draw_line_on_buffer(buffer, image_w, image_h, (points2d[boneIndex["crl_shoulder__R"]], points2d[boneIndex["crl_arm__R"]]), color, size)
draw_line_on_buffer(buffer, image_w, image_h, (points2d[boneIndex["crl_arm__R"]], points2d[boneIndex["crl_foreArm__R"]]), color, size)
draw_line_on_buffer(buffer, image_w, image_h, (points2d[boneIndex["crl_foreArm__R"]], points2d[boneIndex["crl_hand__R"]]), color, size)
draw_line_on_buffer(buffer, image_w, image_h, (points2d[boneIndex["crl_hand__R"]], points2d[boneIndex["crl_handThumb__R"]]), color, size)
draw_line_on_buffer(buffer, image_w, image_h, (points2d[boneIndex["crl_hand__R"]], points2d[boneIndex["crl_handIndex__R"]]), color, size)
draw_line_on_buffer(buffer, image_w, image_h, (points2d[boneIndex["crl_hand__R"]], points2d[boneIndex["crl_handMiddle__R"]]), color, size)
draw_line_on_buffer(buffer, image_w, image_h, (points2d[boneIndex["crl_hand__R"]], points2d[boneIndex["crl_handRing__R"]]), color, size)
draw_line_on_buffer(buffer, image_w, image_h, (points2d[boneIndex["crl_hand__R"]], points2d[boneIndex["crl_handPinky__R"]]), color, size)
draw_line_on_buffer(buffer, image_w, image_h, (points2d[boneIndex["crl_handThumb__R"]], points2d[boneIndex["crl_handThumb01__R"]]), color, size)
draw_line_on_buffer(buffer, image_w, image_h, (points2d[boneIndex["crl_handThumb01__R"]], points2d[boneIndex["crl_handThumb02__R"]]), color, size)
draw_line_on_buffer(buffer, image_w, image_h, (points2d[boneIndex["crl_handThumb02__R"]], points2d[boneIndex["crl_handThumbEnd__R"]]), color, size)
draw_line_on_buffer(buffer, image_w, image_h, (points2d[boneIndex["crl_handIndex__R"]], points2d[boneIndex["crl_handIndex01__R"]]), color, size)
draw_line_on_buffer(buffer, image_w, image_h, (points2d[boneIndex["crl_handIndex01__R"]], points2d[boneIndex["crl_handIndex02__R"]]), color, size)
draw_line_on_buffer(buffer, image_w, image_h, (points2d[boneIndex["crl_handIndex02__R"]], points2d[boneIndex["crl_handIndexEnd__R"]]), color, size)
draw_line_on_buffer(buffer, image_w, image_h, (points2d[boneIndex["crl_handMiddle__R"]], points2d[boneIndex["crl_handMiddle01__R"]]), color, size)
draw_line_on_buffer(buffer, image_w, image_h, (points2d[boneIndex["crl_handMiddle01__R"]], points2d[boneIndex["crl_handMiddle02__R"]]), color, size)
draw_line_on_buffer(buffer, image_w, image_h, (points2d[boneIndex["crl_handMiddle02__R"]], points2d[boneIndex["crl_handMiddleEnd__R"]]), color, size)
draw_line_on_buffer(buffer, image_w, image_h, (points2d[boneIndex["crl_handRing__R"]], points2d[boneIndex["crl_handRing01__R"]]), color, size)
draw_line_on_buffer(buffer, image_w, image_h, (points2d[boneIndex["crl_handRing01__R"]], points2d[boneIndex["crl_handRing02__R"]]), color, size)
draw_line_on_buffer(buffer, image_w, image_h, (points2d[boneIndex["crl_handRing02__R"]], points2d[boneIndex["crl_handRingEnd__R"]]), color, size)
draw_line_on_buffer(buffer, image_w, image_h, (points2d[boneIndex["crl_handPinky__R"]], points2d[boneIndex["crl_handPinky01__R"]]), color, size)
draw_line_on_buffer(buffer, image_w, image_h, (points2d[boneIndex["crl_handPinky01__R"]], points2d[boneIndex["crl_handPinky02__R"]]), color, size)
draw_line_on_buffer(buffer, image_w, image_h, (points2d[boneIndex["crl_handPinky02__R"]], points2d[boneIndex["crl_handPinkyEnd__R"]]), color, size)
draw_line_on_buffer(buffer, image_w, image_h, (points2d[boneIndex["crl_thigh__R"]], points2d[boneIndex["crl_leg__R"]]), color, size)
draw_line_on_buffer(buffer, image_w, image_h, (points2d[boneIndex["crl_leg__R"]], points2d[boneIndex["crl_foot__R"]]), color, size)
draw_line_on_buffer(buffer, image_w, image_h, (points2d[boneIndex["crl_foot__R"]], points2d[boneIndex["crl_toe__R"]]), color, size)
draw_line_on_buffer(buffer, image_w, image_h, (points2d[boneIndex["crl_toe__R"]], points2d[boneIndex["crl_toeEnd__R"]]), color, size)
draw_line_on_buffer(buffer, image_w, image_h, (points2d[boneIndex["crl_thigh__L"]], points2d[boneIndex["crl_leg__L"]]), color, size)
draw_line_on_buffer(buffer, image_w, image_h, (points2d[boneIndex["crl_leg__L"]], points2d[boneIndex["crl_foot__L"]]), color, size)
draw_line_on_buffer(buffer, image_w, image_h, (points2d[boneIndex["crl_foot__L"]], points2d[boneIndex["crl_toe__L"]]), color, size)
draw_line_on_buffer(buffer, image_w, image_h, (points2d[boneIndex["crl_toe__L"]], points2d[boneIndex["crl_toeEnd__L"]]), color, size)
except:
pass
def should_quit():
for event in pygame.event.get():
if event.type == pygame.QUIT:
return True
elif event.type == pygame.KEYUP:
if event.key == pygame.K_ESCAPE:
return True
return False
def write_image(frame, id, buffer):
# Save the image using Pillow module.
img = Image.fromarray(buffer)
img.save('_out/%s_%06d.png' % (id, frame))
def main():
argparser = argparse.ArgumentParser(
description='CARLA Manual Control Client')
argparser.add_argument(
'--fov',
default=60,
type=int,
help='FOV for camera')
argparser.add_argument(
'--res',
metavar='WIDTHxHEIGHT',
# default='1920x1080',
default='800x600',
help='window resolution (default: 800x600)')
args = argparser.parse_args()
args.width, args.height = [int(x) for x in args.res.split('x')]
actor_list = []
pygame.init()
display = pygame.display.set_mode(
(args.width, args.height),
pygame.HWSURFACE | pygame.DOUBLEBUF)
font = get_font()
clock = pygame.time.Clock()
client = carla.Client('localhost', 2000)
client.set_timeout(5.0)
world = client.get_world()
# spawn a camera
camera_bp = world.get_blueprint_library().find('sensor.camera.rgb')
camera_bp.set_attribute("image_size_x", str(args.width))
camera_bp.set_attribute("image_size_y", str(args.height))
camera_bp.set_attribute("fov", str(args.fov))
camera = world.spawn_actor(camera_bp, carla.Transform())
# spawn a pedestrian
world.set_pedestrians_seed(1235)
ped_bp = random.choice(world.get_blueprint_library().filter("walker.pedestrian.*"))
trans = carla.Transform()
trans.location = world.get_random_location_from_navigation()
ped = world.spawn_actor(ped_bp, trans)
walker_controller_bp = world.get_blueprint_library().find('controller.ai.walker')
controller = world.spawn_actor(walker_controller_bp, carla.Transform(), ped)
controller.start()
controller.go_to_location(world.get_random_location_from_navigation())
controller.set_max_speed(1.7)
# keep tracking of actors to remove
actor_list.append(camera)
actor_list.append(ped)
actor_list.append(controller)
# get some attributes from the camera
image_w = camera_bp.get_attribute("image_size_x").as_int()
image_h = camera_bp.get_attribute("image_size_y").as_int()
fov = camera_bp.get_attribute("fov").as_float()
try:
pool = Pool(processes=5)
# Create a synchronous mode context.
with CarlaSyncMode(world, camera, fps=30) as sync_mode:
# set the projection matrix
K = build_projection_matrix(image_w, image_h, fov)
blending = 0
turning = 0
while True:
if should_quit():
return
clock.tick()
# make some transition from custom pose to animation
ped.blend_pose(math.sin(blending))
# move the pedestrian
blending += 0.015
turning += 0.009
# move camera around
trans = ped.get_transform()
x = math.cos(turning) * -3
y = math.sin(turning) * 3
trans.location.x += x
trans.location.y += y
trans.location.z = 2
trans.rotation.pitch = -16
trans.rotation.roll = 0
trans.rotation.yaw = -360 * (turning/(math.pi*2))
camera.set_transform(trans)
# Advance the simulation and wait for the data.
snapshot, image_rgb = sync_mode.tick(timeout=5.0)
# Draw the display.
buffer = get_image_as_array(image_rgb)
# get the pedestrian bones
bones = ped.get_bones()
# prepare the bones (get name and world position)
boneIndex = {}
points = []
for i, bone in enumerate(bones.bone_transforms):
boneIndex[bone.name] = i
points.append(bone.world.location)
# project the 3d points to 2d screen
points2d = get_screen_points(camera, K, image_w, image_h, points)
# draw the skeleton lines
draw_skeleton(buffer, image_w, image_h, boneIndex, points2d, (0, 255, 0), 2)
# draw the bone points
draw_points_on_buffer(buffer, image_w, image_h, points2d[1:], (255, 0, 0), 4)
draw_image(display, buffer)
# pool.apply_async(write_image, (snapshot.frame, "ped", buffer))
# display.blit(font.render('%d bones' % len(points), True, (255, 255, 255)), (8, 10))
pygame.display.flip()
finally:
# time.sleep(5)
print('destroying actors.')
for actor in actor_list:
actor.destroy()
pygame.quit()
pool.close()
print('done.')
if __name__ == '__main__':
try:
main()
except KeyboardInterrupt:
print('\nCancelled by user. Bye!')

View File

@ -122,11 +122,17 @@ def main():
metavar='S',
type=int,
help='Set random device seed and deterministic mode for Traffic Manager')
argparser.add_argument(
'--seedw',
metavar='S',
default=0,
type=int,
help='Set the seed for pedestrians module')
argparser.add_argument(
'--car-lights-on',
action='store_true',
default=False,
help='Enable car lights')
help='Enable automatic car light management')
argparser.add_argument(
'--hero',
action='store_true',
@ -214,7 +220,6 @@ def main():
# @todo cannot import these directly.
SpawnActor = carla.command.SpawnActor
SetAutopilot = carla.command.SetAutopilot
SetVehicleLightState = carla.command.SetVehicleLightState
FutureActor = carla.command.FutureActor
# --------------
@ -238,15 +243,9 @@ def main():
else:
blueprint.set_attribute('role_name', 'autopilot')
# prepare the light state of the cars to spawn
light_state = vls.NONE
if args.car_lights_on:
light_state = vls.Position | vls.LowBeam | vls.LowBeam
# spawn the cars and set their autopilot and light state all together
batch.append(SpawnActor(blueprint, transform)
.then(SetAutopilot(FutureActor, True, traffic_manager.get_port()))
.then(SetVehicleLightState(FutureActor, light_state)))
.then(SetAutopilot(FutureActor, True, traffic_manager.get_port())))
for response in client.apply_batch_sync(batch, synchronous_master):
if response.error:
@ -254,12 +253,21 @@ def main():
else:
vehicles_list.append(response.actor_id)
# Set automatic vehicle lights update if specified
if args.car_lights_on:
all_vehicle_actors = world.get_actors(vehicles_list)
for actor in all_vehicle_actors:
traffic_manager.update_vehicle_lights(actor, True)
# -------------
# Spawn Walkers
# -------------
# some settings
percentagePedestriansRunning = 0.0 # how many pedestrians will run
percentagePedestriansCrossing = 0.0 # how many pedestrians will walk through the road
if args.seedw:
world.set_pedestrians_seed(args.seedw)
random.seed(args.seedw)
# 1. take all the random locations to spawn
spawn_points = []
for i in range(args.number_of_walkers):

View File

@ -75,6 +75,8 @@ def tutorial(args):
lidar = None
try:
if not os.path.isdir('_out'):
os.mkdir('_out')
# Search the desired blueprints
vehicle_bp = bp_lib.filter("vehicle.lincoln.mkz_2017")[0]
camera_bp = bp_lib.filter("sensor.camera.rgb")[0]

View File

@ -36,11 +36,13 @@ Use ARROWS or WASD keys for control.
C : change weather (Shift+C reverse)
Backspace : change vehicle
O : open/close all doors of vehicle
T : toggle vehicle's telemetry
V : Select next map layer (Shift+V reverse)
B : Load current selected map layer (Shift+B to unload)
R : toggle recording images to disk
T : toggle vehicle's telemetry
CTRL + R : toggle recording of simulation (replacing any previous)
CTRL + P : start replaying last recorded simulation
@ -120,6 +122,7 @@ try:
from pygame.locals import K_l
from pygame.locals import K_m
from pygame.locals import K_n
from pygame.locals import K_o
from pygame.locals import K_p
from pygame.locals import K_q
from pygame.locals import K_r
@ -217,6 +220,7 @@ class World(object):
self.recording_start = 0
self.constant_velocity_enabled = False
self.show_vehicle_telemetry = False
self.doors_are_open = False
self.current_map_layer = 0
self.map_layer_names = [
carla.MapLayer.NONE,
@ -262,6 +266,7 @@ class World(object):
spawn_point.rotation.pitch = 0.0
self.destroy()
self.player = self.world.try_spawn_actor(blueprint, spawn_point)
self.show_vehicle_telemetry = False
self.modify_vehicle_physics(self.player)
while self.player is None:
if not self.map.get_spawn_points():
@ -271,6 +276,7 @@ class World(object):
spawn_points = self.map.get_spawn_points()
spawn_point = random.choice(spawn_points) if spawn_points else carla.Transform()
self.player = self.world.try_spawn_actor(blueprint, spawn_point)
self.show_vehicle_telemetry = False
self.modify_vehicle_physics(self.player)
# Set up the sensors.
self.collision_sensor = CollisionSensor(self.player, self.hud)
@ -427,6 +433,18 @@ class KeyboardControl(object):
world.player.enable_constant_velocity(carla.Vector3D(17, 0, 0))
world.constant_velocity_enabled = True
world.hud.notification("Enabled Constant Velocity Mode at 60 km/h")
elif event.key == K_o:
try:
if world.doors_are_open:
world.hud.notification("Closing Doors")
world.doors_are_open = False
world.player.close_door(carla.VehicleDoor.All)
else:
world.hud.notification("Opening doors")
world.doors_are_open = True
world.player.open_door(carla.VehicleDoor.All)
except Exception:
pass
elif event.key == K_t:
if world.show_vehicle_telemetry:
world.player.show_debug_telemetry(False)
@ -1040,8 +1058,9 @@ class CameraManager(object):
['sensor.camera.depth', cc.Depth, 'Camera Depth (Gray Scale)', {}],
['sensor.camera.depth', cc.LogarithmicDepth, 'Camera Depth (Logarithmic Gray Scale)', {}],
['sensor.camera.semantic_segmentation', cc.Raw, 'Camera Semantic Segmentation (Raw)', {}],
['sensor.camera.semantic_segmentation', cc.CityScapesPalette,
'Camera Semantic Segmentation (CityScapes Palette)', {}],
['sensor.camera.semantic_segmentation', cc.CityScapesPalette, 'Camera Semantic Segmentation (CityScapes Palette)', {}],
['sensor.camera.instance_segmentation', cc.CityScapesPalette, 'Camera Instance Segmentation (CityScapes Palette)', {}],
['sensor.camera.instance_segmentation', cc.Raw, 'Camera Instance Segmentation (Raw)', {}],
['sensor.lidar.ray_cast', None, 'Lidar (Ray-Cast)', {'range': '50'}],
['sensor.camera.dvs', cc.Raw, 'Dynamic Vision Sensor', {}],
['sensor.camera.rgb', cc.Raw, 'Camera RGB Distorted',

View File

@ -426,7 +426,7 @@ class HUD(object):
'Client: % 16.0f FPS' % clock.get_fps(),
'',
'Vehicle: % 20s' % get_actor_display_name(world.player, truncate=20),
'Map: % 20s' % world.world.map_name,
'Map: % 20s' % world.world.get_map().name.split('/')[-1],
'Simulation time: % 12s' % datetime.timedelta(seconds=int(self.simulation_time)),
'',
'Speed: % 15.0f km/h' % (3.6 * math.sqrt(v.x**2 + v.y**2 + v.z**2)),

View File

@ -28,6 +28,10 @@ Use ARROWS or WASD keys for control.
R : toggle recording images to disk
F2 : toggle RSS visualization mode
F3 : increase log level
F4 : decrease log level
F5 : increase map log level
F6 : decrease map log level
B : toggle RSS Road Boundaries Mode
G : RSS check drop current route
T : toggle RSS
@ -87,6 +91,10 @@ try:
from pygame.locals import K_ESCAPE
from pygame.locals import K_F1
from pygame.locals import K_F2
from pygame.locals import K_F3
from pygame.locals import K_F4
from pygame.locals import K_F5
from pygame.locals import K_F6
from pygame.locals import K_LEFT
from pygame.locals import K_RIGHT
from pygame.locals import K_SLASH
@ -408,6 +416,20 @@ class VehicleControl(object):
elif event.key == K_F2:
if self._world and self._world.rss_sensor:
self._world.rss_sensor.toggle_debug_visualization_mode()
elif event.key == K_F3:
if self._world and self._world.rss_sensor:
self._world.rss_sensor.decrease_log_level()
self._restrictor.set_log_level(self._world.rss_sensor.log_level)
elif event.key == K_F4:
if self._world and self._world.rss_sensor:
self._world.rss_sensor.increase_log_level()
self._restrictor.set_log_level(self._world.rss_sensor.log_level)
elif event.key == K_F5:
if self._world and self._world.rss_sensor:
self._world.rss_sensor.decrease_map_log_level()
elif event.key == K_F6:
if self._world and self._world.rss_sensor:
self._world.rss_sensor.increase_map_log_level()
elif event.key == K_b:
if self._world and self._world.rss_sensor:
if self._world.rss_sensor.sensor.road_boundaries_mode == carla.RssRoadBoundariesMode.Off:

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