Merge branch 'dev'
This commit is contained in:
commit
a1b37f7f1c
32
CHANGELOG.md
32
CHANGELOG.md
|
@ -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
|
||||
|
|
|
@ -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.
|
||||
|
||||
---
|
||||
|
||||
|
|
|
@ -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:
|
||||
|
|
1121
Docs/bp_library.md
1121
Docs/bp_library.md
File diff suppressed because it is too large
Load Diff
|
@ -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/)
|
||||
|
|
|
@ -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
|
||||
|
|
1655
Docs/python_api.md
1655
Docs/python_api.md
File diff suppressed because it is too large
Load Diff
|
@ -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)
|
||||
|
|
|
@ -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
|
||||
'''
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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));
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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(
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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:
|
||||
|
||||
|
|
|
@ -85,6 +85,10 @@ namespace detail {
|
|||
_nav.SetPedestriansCrossFactor(percentage);
|
||||
}
|
||||
|
||||
void SetPedestriansSeed(unsigned int seed) {
|
||||
_nav.SetSeed(seed);
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
Client &_client;
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
|
@ -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";
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
|
@ -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);
|
|
@ -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>;
|
||||
|
||||
}
|
||||
}
|
|
@ -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);
|
|
@ -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);
|
||||
};
|
|
@ -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
|
|
@ -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
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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 ×tamp) {
|
||||
void RssSensor::TickRssSensor(const client::Timestamp ×tamp, 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 ×tamp,
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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 ×tamp);
|
||||
void TickRssSensor(const client::Timestamp ×tamp, CallbackFunctionType callback);
|
||||
void TickRssSensorThreadLocked(const client::Timestamp ×tamp, 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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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)
|
||||
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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()) {
|
||||
|
|
|
@ -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};
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
};
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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()) {
|
||||
|
||||
|
|
|
@ -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(
|
||||
|
|
|
@ -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:
|
||||
|
|
|
@ -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");
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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() {};
|
||||
};
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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();
|
||||
|
||||
|
|
|
@ -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();
|
||||
});
|
||||
|
|
|
@ -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 ¶meters,
|
||||
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
|
|
@ -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 ¶meters;
|
||||
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 ¶meters,
|
||||
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
|
|
@ -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)
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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 \
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -2,3 +2,4 @@ networkx
|
|||
numpy; python_version < '3.0'
|
||||
numpy==1.18.4; python_version >= '3.0'
|
||||
distro
|
||||
Shapely==1.6.4.post2
|
||||
|
|
|
@ -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(),
|
||||
|
|
|
@ -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))
|
||||
;
|
||||
|
||||
|
|
|
@ -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));
|
||||
}
|
||||
|
|
|
@ -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)))
|
||||
|
|
|
@ -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))
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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))
|
||||
;
|
||||
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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.
|
||||
# --------------------------------------
|
||||
...
|
||||
|
|
|
@ -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 ------------------------
|
||||
|
|
|
@ -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()
|
||||
|
|
|
@ -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:
|
||||
|
|
|
@ -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__
|
||||
|
|
|
@ -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) +
|
||||
|
|
|
@ -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>
|
||||
*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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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!')
|
|
@ -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):
|
||||
|
|
|
@ -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]
|
||||
|
|
|
@ -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',
|
||||
|
|
|
@ -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)),
|
||||
|
|
|
@ -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
Loading…
Reference in New Issue