Skip to content

Commit 8f33324

Browse files
Extend ROS2 support Step 1: V2XSensor (#9435)
- V2XSensor allows selection of virtual communication channels via sensors 'channel_id ' attribute. - V2XCustomSensor sends bytes instead of std::string to support binary data blobs - V2XCustomSensor allows multiple messages to be sent at once supporting individual larger messages - Allow V2X-sensors without an owner if these are placed within the infrastructure (V2I communication) - Removed the extra height on the PathLossModel after switching the actor to the sensor's actor instance. Therefore, the considered position is always the position of the sensor itself which can be defined when spawning/attaching - Updated V2X docu
1 parent 3b938d7 commit 8f33324

File tree

28 files changed

+838
-551
lines changed

28 files changed

+838
-551
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
* Introduced geom::AngularVelocity, geom::Velocity, geom::Acceleration, geom::Quaternion types
88
* Fixed geom::Rotation::RotateVector() rotation directions of pitch and roll
99
* Prepare server for multistream support and ROS2 client calls
10+
* Improved V2X sensor capabilities: send complex custom user-defined data, support V2I sensors not attached to a vehicle
1011

1112
## CARLA 0.9.16
1213

Docs/bp_library.md

Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -258,6 +258,63 @@ Check out the [introduction to blueprints](core_actors.md).
258258
- **<font color="#498efc">sensor.other.rss</font>**
259259
- **Attributes:**
260260
- `role_name` (_String_) <sub>_- Modifiable_</sub>
261+
- **<font color="#498efc">sensor.other.v2x</font>**
262+
- **Attributes:**
263+
- `channel_id` (_String_) <sub>_- Modifiable_</sub>
264+
- `combined_antenna_gain` (_Float_) <sub>_- Modifiable_</sub>
265+
- `custom_fading_stddev` (_Float_) <sub>_- Modifiable_</sub>
266+
- `d_ref` (_Float_) <sub>_- Modifiable_</sub>
267+
- `filter_distance` (_Float_) <sub>_- Modifiable_</sub>
268+
- `fixed_rate` (_Bool_) <sub>_- Modifiable_</sub>
269+
- `frequency_ghz` (_Float_) <sub>_- Modifiable_</sub>
270+
- `gen_cam_max` (_Float_) <sub>_- Modifiable_</sub>
271+
- `gen_cam_min` (_Float_) <sub>_- Modifiable_</sub>
272+
- `noise_accel_stddev_x` (_Float_) <sub>_- Modifiable_</sub>
273+
- `noise_accel_stddev_y` (_Float_) <sub>_- Modifiable_</sub>
274+
- `noise_accel_stddev_z` (_Float_) <sub>_- Modifiable_</sub>
275+
- `noise_alt_bias` (_Float_) <sub>_- Modifiable_</sub>
276+
- `noise_alt_stddev` (_Float_) <sub>_- Modifiable_</sub>
277+
- `noise_head_bias` (_Float_) <sub>_- Modifiable_</sub>
278+
- `noise_head_stddev` (_Float_) <sub>_- Modifiable_</sub>
279+
- `noise_lat_bias` (_Float_) <sub>_- Modifiable_</sub>
280+
- `noise_lat_stddev` (_Float_) <sub>_- Modifiable_</sub>
281+
- `noise_lon_bias` (_Float_) <sub>_- Modifiable_</sub>
282+
- `noise_lon_stddev` (_Float_) <sub>_- Modifiable_</sub>
283+
- `noise_seed` (_Int_) <sub>_- Modifiable_</sub>
284+
- `noise_vel_stddev_x` (_Float_) <sub>_- Modifiable_</sub>
285+
- `noise_yawrate_bias` (_Float_) <sub>_- Modifiable_</sub>
286+
- `noise_yawrate_stddev` (_Float_) <sub>_- Modifiable_</sub>
287+
- `path_loss_exponent` (_Float_) <sub>_- Modifiable_</sub>
288+
- `path_loss_model` (_String_) <sub>_- Modifiable_</sub>
289+
- `receiver_sensitivity` (_Float_) <sub>_- Modifiable_</sub>
290+
- `role_name` (_String_) <sub>_- Modifiable_</sub>
291+
- `ros_frame_id` (_String_) <sub>_- Modifiable_</sub>
292+
- `ros_name` (_String_) <sub>_- Modifiable_</sub>
293+
- `ros_publish_tf` (_Bool_) <sub>_- Modifiable_</sub>
294+
- `scenario` (_String_) <sub>_- Modifiable_</sub>
295+
- `sensor_tick` (_Float_) <sub>_- Modifiable_</sub>
296+
- `transmit_power` (_Float_) <sub>_- Modifiable_</sub>
297+
- `use_etsi_fading` (_Bool_) <sub>_- Modifiable_</sub>
298+
- **<font color="#498efc">sensor.other.v2x_custom</font>**
299+
- **Attributes:**
300+
- `channel_id` (_String_) <sub>_- Modifiable_</sub>
301+
- `combined_antenna_gain` (_Float_) <sub>_- Modifiable_</sub>
302+
- `custom_fading_stddev` (_Float_) <sub>_- Modifiable_</sub>
303+
- `d_ref` (_Float_) <sub>_- Modifiable_</sub>
304+
- `filter_distance` (_Float_) <sub>_- Modifiable_</sub>
305+
- `frequency_ghz` (_Float_) <sub>_- Modifiable_</sub>
306+
- `noise_seed` (_Int_) <sub>_- Modifiable_</sub>
307+
- `path_loss_exponent` (_Float_) <sub>_- Modifiable_</sub>
308+
- `path_loss_model` (_String_) <sub>_- Modifiable_</sub>
309+
- `receiver_sensitivity` (_Float_) <sub>_- Modifiable_</sub>
310+
- `role_name` (_String_) <sub>_- Modifiable_</sub>
311+
- `ros_frame_id` (_String_) <sub>_- Modifiable_</sub>
312+
- `ros_name` (_String_) <sub>_- Modifiable_</sub>
313+
- `ros_publish_tf` (_Bool_) <sub>_- Modifiable_</sub>
314+
- `scenario` (_String_) <sub>_- Modifiable_</sub>
315+
- `sensor_tick` (_Float_) <sub>_- Modifiable_</sub>
316+
- `transmit_power` (_Float_) <sub>_- Modifiable_</sub>
317+
- `use_etsi_fading` (_Bool_) <sub>_- Modifiable_</sub>
261318

262319
### static
263320
- **<font color="#498efc">static.prop.advertisement</font>**

Docs/python_api.md

Lines changed: 45 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -723,6 +723,48 @@ No changes applied to the image. Used by the [RGB camera](ref_sensors.md#rgb-cam
723723

724724
---
725725

726+
## carla.CustomV2XBytes<a name="carla.CustomV2XBytes"></a>
727+
This is the data type defining the bytes of a custom V2X message. Sent by the method `[carla.Sensor.send](#carla.Sensor.send)` and received as part of a [CustomV2XEvent](#carlacustomv2xevent).
728+
729+
### Instance Variables
730+
- <a name="carla.CustomV2XBytes.data_size"></a>**<font color="#f8805a">data_size</font>** (_int_)
731+
The actual number of bytes of the message.
732+
733+
### Methods
734+
- <a name="carla.CustomV2XBytes.get"></a>**<font color="#7fb800">get</font>**(<font color="#00a6ed">**self**</font>)
735+
Get the custom bytes. Returns a nested dictionary containing the message. It has three primary keys: - `DataSize` : int - `MaxDataSize`: int - `Bytes`: memory view containing the bytes.
736+
- **Return:** _dict_
737+
- <a name="carla.CustomV2XBytes.max_data_size"></a>**<font color="#7fb800">max_data_size</font>**(<font color="#00a6ed">**self**</font>)
738+
Get the maximum data size that a single message is able to transport.
739+
- **Return:** _int_
740+
741+
##### Getters
742+
- <a name="carla.CustomV2XBytes.get_bytes"></a>**<font color="#7fb800">get_bytes</font>**(<font color="#00a6ed">**self**</font>)
743+
Get the custom bytes.
744+
- **Return:** _bytes_
745+
- **Setter:** _[carla.CustomV2XBytes.set_bytes](#carla.CustomV2XBytes.set_bytes)_
746+
- <a name="carla.CustomV2XBytes.get_string"></a>**<font color="#7fb800">get_string</font>**(<font color="#00a6ed">**self**</font>)
747+
Get the custom bytes as string. Be aware: this is a convenience method for quick tests, no coding/decoding is performed.
748+
- **Return:** _str_
749+
- **Setter:** _[carla.CustomV2XBytes.set_string](#carla.CustomV2XBytes.set_string)_
750+
751+
##### Setters
752+
- <a name="carla.CustomV2XBytes.set_bytes"></a>**<font color="#7fb800">set_bytes</font>**(<font color="#00a6ed">**self**</font>, <font color="#00a6ed">**bytes**</font>)
753+
Set the custom bytes from a bytearray. Be aware that only up to `MaxDataSize` bytes are considered. If you have larger data, you need to split it manually.
754+
- **Parameters:**
755+
- `bytes` (_bytes_)
756+
- **Getter:** _[carla.CustomV2XBytes.get_bytes](#carla.CustomV2XBytes.get_bytes)_
757+
- <a name="carla.CustomV2XBytes.set_string"></a>**<font color="#7fb800">set_string</font>**(<font color="#00a6ed">**self**</font>, <font color="#00a6ed">**string**</font>)
758+
Set the custom bytes directly from a string. The null termination is not transmitted. Be aware that only up to `MaxDataSize` bytes are considered. If you have larger data, you need to split it manually. Be aware: this is a convenience method for quick tests, no coding/decoding is performed.
759+
- **Parameters:**
760+
- `string` (_str_)
761+
- **Getter:** _[carla.CustomV2XBytes.get_string](#carla.CustomV2XBytes.get_string)_
762+
763+
##### Dunder methods
764+
- <a name="carla.CustomV2XBytes.__str__"></a>**<font color="#7fb800">\__str__</font>**(<font color="#00a6ed">**self**</font>)
765+
766+
---
767+
726768
## carla.CustomV2XData<a name="carla.CustomV2XData"></a>
727769
<small style="display:block;margin-top:-20px;">Inherited from _[carla.SensorData](#carla.SensorData)_</small></br>
728770
This is the data type defining a custom V2X message. Received as part of a [CustomV2XEvent](#carlacustomv2xevent).
@@ -733,7 +775,7 @@ Received power.
733775

734776
### Methods
735777
- <a name="carla.CustomV2XData.get"></a>**<font color="#7fb800">get</font>**(<font color="#00a6ed">**self**</font>)
736-
Get the custom message. Returns a nested dictionary containing the message. It has two primary keys: - `Header` : dict - `Message`: str.
778+
Get the custom message. Returns a nested dictionary containing the message. It has two primary keys: - `Header` : dict - `Message`: dict.
737779
- **Return:** _dict_
738780

739781
##### Dunder methods
@@ -2493,9 +2535,9 @@ The function the sensor will be calling to every time the desired GBuffer textur
24932535
- `gbuffer_id` (_[carla.GBufferTextureID](#carla.GBufferTextureID)_) - The ID of the target Unreal Engine GBuffer texture.
24942536
- `callback` (_function_) - The called function with one argument containing the received GBuffer texture.
24952537
- <a name="carla.Sensor.send"></a>**<font color="#7fb800">send</font>**(<font color="#00a6ed">**self**</font>, <font color="#00a6ed">**message**</font>)
2496-
Instructs the sensor to send the string given by `message` to all other CustomV2XSensors on the next tick.
2538+
Instructs the sensor to send the bytes given by `message` to all other CustomV2XSensors on the next tick.
24972539
- **Parameters:**
2498-
- `message` (_string_) - The data to send. Note: maximum string length is 100 chars.
2540+
- `message` (_[carla.CustomV2XBytes](#carla.CustomV2XBytes)_) - The data to send. Note: There is a maximum data size for a single message see [carla.CustomV2XBytes](#carla.CustomV2XBytes) for more information.
24992541
- <a name="carla.Sensor.stop"></a>**<font color="#7fb800">stop</font>**(<font color="#00a6ed">**self**</font>)
25002542
Commands the sensor to stop listening for data.
25012543
- <a name="carla.Sensor.stop_gbuffer"></a>**<font color="#7fb800">stop_gbuffer</font>**(<font color="#00a6ed">**self**</font>, <font color="#00a6ed">**gbuffer_id**</font>)

Docs/ref_sensors.md

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1087,18 +1087,21 @@ The function the user has to call every time to send a message. This function ne
10871087
- **Parameters:**
10881088
- `data` (_function_) - The called function with one argument containing the sensor data.
10891089

1090-
The custom V2X message sensor works a little bit different than other sensors, because it has the *send* function in addition to the *listen* function, that needs to be called, before another sensor of this type will receive anything. The transmission of a custom message is only triggered, when *send* is called. Each message given to the *send* function is only transmitted once to all Custom V2X Message sensors currently spawned.
1090+
The custom V2X message sensor works a little bit different than other sensors, because it has the *send* function in addition to the *listen* function, that needs to be called, before another sensor of this type will receive anything. The transmission of a custom message is only triggered, when *send* is called. Each message given to the *send* function is only transmitted once to all Custom V2X Message sensors currently spawned. Independent communcation channels can be created by the sensors 'channel_id' attribute. Only sensors having the same 'channel_id' are communicating with each other. This allows to create different sender/receiver groups within the system.
10911091

10921092
Example:
10931093

10941094
bp = world.get_blueprint_library().find('sensor.other.v2x_custom')
10951095
sensor = world.spawn_actor(bp, carla.Transform(), attach_to=parent)
1096-
sensor.send("Hello CARLA")
1096+
message = carla.CustomV2XBytes()
1097+
message.set_bytes(bytearray("Hello CARLA", 'utf-8'))
1098+
sensor.send(message)
10971099

10981100
### V2X sensors blueprint attributes
10991101

11001102
| Blueprint attribute | Type | Default | Description |
11011103
|-------------------------|--------|-------------------------|------------------------------------|
1104+
| channel\_id | string | '' | Only Sender/Receiver with the same channel_id are communicating with each other |
11021105
| transmit\_power | float | 21.5 | Sender transmission power in dBm |
11031106
| receiver\_sensitivity | float | -99 | Receiver sensitivity in dBm |
11041107
| frequency\_ghz | float | 5.9 | Transmission frequency in GHz. 5.9 GHz is standard for several physical channels. |

LibCarla/source/carla/client/ServerSideSensor.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -55,14 +55,14 @@ namespace client {
5555
listening_mask.reset(0);
5656
}
5757

58-
void ServerSideSensor::Send(std::string message) {
58+
void ServerSideSensor::Send(const rpc::CustomV2XBytes &data) {
5959
log_debug("calling sensor Send() ", GetDisplayId());
6060
if (GetActorDescription().description.id != "sensor.other.v2x_custom")
6161
{
6262
log_warning("Send methods are not supported on non-V2x sensors (sensor.other.v2x_custom).");
6363
return;
6464
}
65-
GetEpisode().Lock()->Send(*this,message);
65+
GetEpisode().Lock()->Send(*this,data);
6666
}
6767

6868
void ServerSideSensor::EnableGBuffers(bool bEnabled) {

LibCarla/source/carla/client/ServerSideSensor.h

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,9 +6,11 @@
66

77
#pragma once
88

9-
#include "carla/client/Sensor.h"
109
#include <bitset>
1110

11+
#include "carla/client/Sensor.h"
12+
#include "carla/rpc/CustomV2XBytes.h"
13+
1214
namespace carla {
1315
namespace client {
1416

@@ -51,7 +53,7 @@ namespace client {
5153
}
5254

5355
/// Send data via this sensor
54-
void Send(std::string message);
56+
void Send(const rpc::CustomV2XBytes &data);
5557

5658
/// @copydoc Actor::Destroy()
5759
///

LibCarla/source/carla/client/detail/Client.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -724,8 +724,8 @@ namespace detail {
724724
return _pimpl->CallAndWait<bool>("is_actor_enabled_for_ros", actor);
725725
}
726726

727-
void Client::Send(rpc::ActorId ActorId, std::string message) {
728-
_pimpl->AsyncCall("send", ActorId, message);
727+
void Client::Send(rpc::ActorId ActorId, const rpc::CustomV2XBytes &data) {
728+
_pimpl->AsyncCall("send", ActorId, data);
729729
}
730730

731731
void Client::SetIgnoredVehicles(rpc::ActorId ActorId, const std::vector<rpc::ActorId>& vehicle_ids) {

LibCarla/source/carla/client/detail/Client.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
#include "carla/rpc/AttachmentType.h"
1717
#include "carla/rpc/Command.h"
1818
#include "carla/rpc/CommandResponse.h"
19+
#include "carla/rpc/CustomV2XBytes.h"
1920
#include "carla/rpc/EnvironmentObject.h"
2021
#include "carla/rpc/EpisodeInfo.h"
2122
#include "carla/rpc/EpisodeSettings.h"
@@ -467,7 +468,7 @@ namespace detail {
467468
rpc::ActorId ActorId,
468469
uint32_t GBufferId);
469470

470-
void Send(rpc::ActorId ActorId, std::string message);
471+
void Send(rpc::ActorId ActorId, const rpc::CustomV2XBytes &data);
471472

472473
void SetIgnoredVehicles(rpc::ActorId ActorId, const std::vector<rpc::ActorId>& vehicle_ids);
473474

LibCarla/source/carla/client/detail/Simulator.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -453,8 +453,8 @@ EpisodeProxy Simulator::GetCurrentEpisode() {
453453
_client.FreezeAllTrafficLights(frozen);
454454
}
455455

456-
void Simulator::Send(const Sensor &sensor, std::string message) {
457-
_client.Send(sensor.GetId(), message);
456+
void Simulator::Send(const Sensor &sensor, const carla::rpc::CustomV2XBytes &data) {
457+
_client.Send(sensor.GetId(), data);
458458
}
459459

460460
void Simulator::SetIgnoredVehicles(const Sensor &sensor, const std::vector<ActorId>& vehicle_ids) {

LibCarla/source/carla/client/detail/Simulator.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
#include "carla/client/detail/Episode.h"
2323
#include "carla/client/detail/EpisodeProxy.h"
2424
#include "carla/profiler/LifetimeProfiled.h"
25+
#include "carla/rpc/CustomV2XBytes.h"
2526
#include "carla/rpc/TrafficLightState.h"
2627
#include "carla/rpc/VehicleLightStateList.h"
2728
#include "carla/rpc/LabelledPoint.h"
@@ -731,7 +732,7 @@ namespace detail {
731732
Actor & sensor,
732733
uint32_t gbuffer_id);
733734

734-
void Send(const Sensor &sensor, std::string message);
735+
void Send(const Sensor &sensor, const carla::rpc::CustomV2XBytes &data);
735736

736737
void SetIgnoredVehicles(const Sensor &sensor, const std::vector<ActorId>& vehicle_ids);
737738

0 commit comments

Comments
 (0)