Raycasting (#3483)

* Added raycasting and point projection capabilities to python api.

* Added documentation of new functions.

* Fixed missing .f on floats

Co-authored-by: doterop <daniel.oterop@gmail.com>
This commit is contained in:
Axel1092 2020-10-26 11:13:35 +01:00 committed by GitHub
parent 52d706014b
commit 003e74fc91
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
18 changed files with 568 additions and 244 deletions

1
.gitignore vendored
View File

@ -6,6 +6,7 @@ TrafficManager/build
Util/Build
Install
Plugins
!Unreal/CarlaUE4/Plugins
/ExportedMaps
/Import/*

View File

@ -801,6 +801,17 @@ Returns a list of pairs of waypoints. Every tuple on the list contains first an
---
## carla.LabelledPoint<a name="carla.LabelledPoint"></a>
Class that represent a position in space with a semantic label.
<h3>Instance Variables</h3>
- <a name="carla.LabelledPoint.location"></a>**<font color="#f8805a">location</font>**
Position in 3D space.
- <a name="carla.LabelledPoint.label"></a>**<font color="#f8805a">label</font>**
Semantic tag of the point.
---
## carla.Landmark<a name="carla.Landmark"></a>
Class that defines any type of traffic landmark or sign affecting a road. These class mediates between the [OpenDRIVE 1.4 standard](http://www.opendrive.org/docs/OpenDRIVEFormatSpecRev1.4H.pdf) definition of the landmarks and their representation in the simulation. This class retrieves all the information defining a landmark in OpenDRIVE and facilitates information about which lanes does it affect and when.
Landmarks will be accessed by [carla.Waypoint](#carla.Waypoint) objects trying to retrieve the regulation of their lane. Therefore some attributes depend on the waypoint that is consulting the landmark and so, creating the object.
@ -2702,15 +2713,34 @@ This method applies settings contained in an object to the simulation running an
- **Return:** _int_
- **Warning:** <font color="#ED2F2F">_If synchronous mode is enabled, and there is a Traffic Manager running, this must be set to sync mode too. Read [this](adv_traffic_manager.md#synchronous-mode) to learn how to do it.
_</font>
- <a name="carla.World.cast_ray"></a>**<font color="#7fb800">cast_ray</font>**(<font color="#00a6ed">**self**</font>, <font color="#00a6ed">**initial_location**</font>, <font color="#00a6ed">**final_location**</font>)
Casts a ray from the specified initial_location to final_location. The function then detects all geometries intersecting the ray and returns a list of [carla.LabelledPoint](#carla.LabelledPoint) in order.
- **Parameters:**
- `initial_location` (_[carla.Location](#carla.Location)_) The initial position of the ray.
- `final_location` (_[carla.Location](#carla.Location)_) The final position of the ray.
- **Return:** _list([carla.LabelledPoint](#carla.LabelledPoint))_
- <a name="carla.World.freeze_all_traffic_lights"></a>**<font color="#7fb800">freeze_all_traffic_lights</font>**(<font color="#00a6ed">**self**</font>, <font color="#00a6ed">**frozen**</font>)
Freezes or unfreezes all traffic lights in the scene. Frozen traffic lights can be modified by the user but the time will not update them until unfrozen.
- **Parameters:**
- `frozen` (_bool_)
- <a name="carla.World.ground_projection"></a>**<font color="#7fb800">ground_projection</font>**(<font color="#00a6ed">**self**</font>, <font color="#00a6ed">**location**</font>, <font color="#00a6ed">**search_distance**</font>)
Projects the specified point downwards in the scene. The functions casts a ray from location in the direction (0,0,-1) (downwards) and returns a [carla.Labelled](#carla.Labelled) object with the first geometry this ray intersects (usually the ground). If no geometry is found in the search_distance range the function returns `None`.
- **Parameters:**
- `location` (_[carla.Location](#carla.Location)_) The point to be projected.
- `search_distance` (_float_) The maximum distance to perform the projection.
- **Return:** _[carla.LabelledPoint](#carla.LabelledPoint)_
- <a name="carla.World.on_tick"></a>**<font color="#7fb800">on_tick</font>**(<font color="#00a6ed">**self**</font>, <font color="#00a6ed">**callback**</font>)
This method is used in [__asynchronous__ mode](https://[carla.readthedocs.io](#carla.readthedocs.io)/en/latest/adv_synchrony_timestep/). It starts callbacks from the client for the function defined as `callback`, and returns the ID of the callback. The function will be called everytime the server ticks. It requires a [carla.WorldSnapshot](#carla.WorldSnapshot) as argument, which can be retrieved from __<font color="#7fb800">wait_for_tick()</font>__. Use __<font color="#7fb800">remove_on_tick()</font>__ to stop the callbacks.
- **Parameters:**
- `callback` (_[carla.WorldSnapshot](#carla.WorldSnapshot)_) Function with a snapshot as compulsory parameter that will be called when the client receives a tick.
- **Return:** _int_
- <a name="carla.World.project_point"></a>**<font color="#7fb800">project_point</font>**(<font color="#00a6ed">**self**</font>, <font color="#00a6ed">**location**</font>, <font color="#00a6ed">**direction**</font>, <font color="#00a6ed">**search_distance**</font>)
Projects the specified point to the desired direction in the scene. The functions casts a ray from location in a direction and returns a [carla.Labelled](#carla.Labelled) object with the first geometry this ray intersects. If no geometry is found in the search_distance range the function returns `None`.
- **Parameters:**
- `location` (_[carla.Location](#carla.Location)_) The point to be projected.
- `direction` (_[carla.Vector3D](#carla.Vector3D)_) The direction of projection.
- `search_distance` (_float_) The maximum distance to perform the projection.
- **Return:** _[carla.LabelledPoint](#carla.LabelledPoint)_
- <a name="carla.World.remove_on_tick"></a>**<font color="#7fb800">remove_on_tick</font>**(<font color="#00a6ed">**self**</font>, <font color="#00a6ed">**callback_id**</font>)
Stops the callback for `callback_id` started with __<font color="#7fb800">on_tick()</font>__.
- **Parameters:**
@ -3196,89 +3226,6 @@ document.getElementById("snipets-container").innerHTML = null;
}
</script>
<div id ="carla.Map.get_waypoint-snipet" style="display: none;">
<p class="SnipetFont">
Snipet for carla.Map.get_waypoint
</p>
<div id="carla.Map.get_waypoint-code" class="SnipetContent">
```py
# This recipe shows the current traffic rules affecting the vehicle.
# Shows the current lane type and if a lane change can be done in the actual lane or the surrounding ones.
# ...
waypoint = world.get_map().get_waypoint(vehicle.get_location(),project_to_road=True, lane_type=(carla.LaneType.Driving | carla.LaneType.Shoulder | carla.LaneType.Sidewalk))
print("Current lane type: " + str(waypoint.lane_type))
# Check current lane change allowed
print("Current Lane change: " + str(waypoint.lane_change))
# Left and Right lane markings
print("L lane marking type: " + str(waypoint.left_lane_marking.type))
print("L lane marking change: " + str(waypoint.left_lane_marking.lane_change))
print("R lane marking type: " + str(waypoint.right_lane_marking.type))
print("R lane marking change: " + str(waypoint.right_lane_marking.lane_change))
# ...
```
<button id="button1" class="CopyScript" onclick="CopyToClipboard('carla.Map.get_waypoint-code')">Copy snipet</button>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<button id="button1" class="CloseSnipet" onclick="CloseSnipet()">Close snipet</button><br><br>
<img src="/img/snipets_images/carla.Map.get_waypoint.jpg">
</div>
<div id ="carla.Sensor.listen-snipet" style="display: none;">
<p class="SnipetFont">
Snipet for carla.Sensor.listen
</p>
<div id="carla.Sensor.listen-code" class="SnipetContent">
```py
# This recipe applies a color conversion to the image taken by a camera sensor,
# so it is converted to a semantic segmentation image.
# ...
camera_bp = world.get_blueprint_library().filter('sensor.camera.semantic_segmentation')
# ...
cc = carla.ColorConverter.CityScapesPalette
camera.listen(lambda image: image.save_to_disk('output/%06d.png' % image.frame, cc))
# ...
```
<button id="button1" class="CopyScript" onclick="CopyToClipboard('carla.Sensor.listen-code')">Copy snipet</button>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<button id="button1" class="CloseSnipet" onclick="CloseSnipet()">Close snipet</button><br><br>
</div>
<div id ="carla.World.spawn_actor-snipet" style="display: none;">
<p class="SnipetFont">
Snipet for carla.World.spawn_actor
</p>
<div id="carla.World.spawn_actor-code" class="SnipetContent">
```py
# This recipe attaches different camera / sensors to a vehicle with different attachments.
# ...
camera = world.spawn_actor(rgb_camera_bp, transform, attach_to=vehicle, attachment_type=Attachment.Rigid)
# Default attachment: Attachment.Rigid
gnss_sensor = world.spawn_actor(sensor_gnss_bp, transform, attach_to=vehicle)
collision_sensor = world.spawn_actor(sensor_collision_bp, transform, attach_to=vehicle)
lane_invasion_sensor = world.spawn_actor(sensor_lane_invasion_bp, transform, attach_to=vehicle)
# ...
```
<button id="button1" class="CopyScript" onclick="CopyToClipboard('carla.World.spawn_actor-code')">Copy snipet</button>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<button id="button1" class="CloseSnipet" onclick="CloseSnipet()">Close snipet</button><br><br>
</div>
<div id ="carla.ActorBlueprint.set_attribute-snipet" style="display: none;">
<p class="SnipetFont">
Snipet for carla.ActorBlueprint.set_attribute
@ -3313,160 +3260,6 @@ camera_bp.set_attribute('image_size_y', 600)
</div>
<div id ="carla.World.get_spectator-snipet" style="display: none;">
<p class="SnipetFont">
Snipet for carla.World.get_spectator
</p>
<div id="carla.World.get_spectator-code" class="SnipetContent">
```py
# This recipe spawns an actor and the spectator camera at the actor's location.
# ...
world = client.get_world()
spectator = world.get_spectator()
vehicle_bp = random.choice(world.get_blueprint_library().filter('vehicle.bmw.*'))
transform = random.choice(world.get_map().get_spawn_points())
vehicle = world.try_spawn_actor(vehicle_bp, transform)
# Wait for world to get the vehicle actor
world.tick()
world_snapshot = world.wait_for_tick()
actor_snapshot = world_snapshot.find(vehicle.id)
# Set spectator at given transform (vehicle transform)
spectator.set_transform(actor_snapshot.get_transform())
# ...
```
<button id="button1" class="CopyScript" onclick="CopyToClipboard('carla.World.get_spectator-code')">Copy snipet</button>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<button id="button1" class="CloseSnipet" onclick="CloseSnipet()">Close snipet</button><br><br>
</div>
<div id ="carla.DebugHelper.draw_line-snipet" style="display: none;">
<p class="SnipetFont">
Snipet for carla.DebugHelper.draw_line
</p>
<div id="carla.DebugHelper.draw_line-code" class="SnipetContent">
```py
# This recipe is a modification of lane_explorer.py example.
# It draws the path of an actor through the world, printing information at each waypoint.
# ...
current_w = map.get_waypoint(vehicle.get_location())
while True:
next_w = map.get_waypoint(vehicle.get_location(), lane_type=carla.LaneType.Driving | carla.LaneType.Shoulder | carla.LaneType.Sidewalk )
# Check if the vehicle is moving
if next_w.id != current_w.id:
vector = vehicle.get_velocity()
# Check if the vehicle is on a sidewalk
if current_w.lane_type == carla.LaneType.Sidewalk:
draw_waypoint_union(debug, current_w, next_w, cyan if current_w.is_junction else red, 60)
else:
draw_waypoint_union(debug, current_w, next_w, cyan if current_w.is_junction else green, 60)
debug.draw_string(current_w.transform.location, str('%15.0f km/h' % (3.6 * math.sqrt(vector.x**2 + vector.y**2 + vector.z**2))), False, orange, 60)
draw_transform(debug, current_w.transform, white, 60)
# Update the current waypoint and sleep for some time
current_w = next_w
time.sleep(args.tick_time)
# ...
```
<button id="button1" class="CopyScript" onclick="CopyToClipboard('carla.DebugHelper.draw_line-code')">Copy snipet</button>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<button id="button1" class="CloseSnipet" onclick="CloseSnipet()">Close snipet</button><br><br>
<img src="/img/snipets_images/carla.DebugHelper.draw_line.jpg">
</div>
<div id ="carla.DebugHelper.draw_box-snipet" style="display: none;">
<p class="SnipetFont">
Snipet for carla.DebugHelper.draw_box
</p>
<div id="carla.DebugHelper.draw_box-code" class="SnipetContent">
```py
# This recipe shows how to draw traffic light actor bounding boxes from a world snapshot.
# ....
debug = world.debug
world_snapshot = world.get_snapshot()
for actor_snapshot in world_snapshot:
actual_actor = world.get_actor(actor_snapshot.id)
if actual_actor.type_id == 'traffic.traffic_light':
debug.draw_box(carla.BoundingBox(actor_snapshot.get_transform().location,carla.Vector3D(0.5,0.5,2)),actor_snapshot.get_transform().rotation, 0.05, carla.Color(255,0,0,0),0)
# ...
```
<button id="button1" class="CopyScript" onclick="CopyToClipboard('carla.DebugHelper.draw_box-code')">Copy snipet</button>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<button id="button1" class="CloseSnipet" onclick="CloseSnipet()">Close snipet</button><br><br>
<img src="/img/snipets_images/carla.DebugHelper.draw_box.jpg">
</div>
<div id ="carla.TrafficLight.set_state-snipet" style="display: none;">
<p class="SnipetFont">
Snipet for carla.TrafficLight.set_state
</p>
<div id="carla.TrafficLight.set_state-code" class="SnipetContent">
```py
# This recipe changes from red to green the traffic light that affects the vehicle.
# This is done by detecting if the vehicle actor is at a traffic light.
# ...
world = client.get_world()
spectator = world.get_spectator()
vehicle_bp = random.choice(world.get_blueprint_library().filter('vehicle.bmw.*'))
transform = random.choice(world.get_map().get_spawn_points())
vehicle = world.try_spawn_actor(vehicle_bp, transform)
# Wait for world to get the vehicle actor
world.tick()
world_snapshot = world.wait_for_tick()
actor_snapshot = world_snapshot.find(vehicle.id)
# Set spectator at given transform (vehicle transform)
spectator.set_transform(actor_snapshot.get_transform())
# ...# ...
if vehicle_actor.is_at_traffic_light():
traffic_light = vehicle_actor.get_traffic_light()
if traffic_light.get_state() == carla.TrafficLightState.Red:
# world.hud.notification("Traffic light changed! Good to go!")
traffic_light.set_state(carla.TrafficLightState.Green)
# ...
```
<button id="button1" class="CopyScript" onclick="CopyToClipboard('carla.TrafficLight.set_state-code')">Copy snipet</button>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<button id="button1" class="CloseSnipet" onclick="CloseSnipet()">Close snipet</button><br><br>
<img src="/img/snipets_images/carla.TrafficLight.set_state.gif">
</div>
<div id ="carla.Client.apply_batch_sync-snipet" style="display: none;">
<p class="SnipetFont">
Snipet for carla.Client.apply_batch_sync
@ -3564,6 +3357,158 @@ client.apply_batch([carla.command.DestroyActor(x) for x in all_id])
</div>
<div id ="carla.Map.get_waypoint-snipet" style="display: none;">
<p class="SnipetFont">
Snipet for carla.Map.get_waypoint
</p>
<div id="carla.Map.get_waypoint-code" class="SnipetContent">
```py
# This recipe shows the current traffic rules affecting the vehicle.
# Shows the current lane type and if a lane change can be done in the actual lane or the surrounding ones.
# ...
waypoint = world.get_map().get_waypoint(vehicle.get_location(),project_to_road=True, lane_type=(carla.LaneType.Driving | carla.LaneType.Shoulder | carla.LaneType.Sidewalk))
print("Current lane type: " + str(waypoint.lane_type))
# Check current lane change allowed
print("Current Lane change: " + str(waypoint.lane_change))
# Left and Right lane markings
print("L lane marking type: " + str(waypoint.left_lane_marking.type))
print("L lane marking change: " + str(waypoint.left_lane_marking.lane_change))
print("R lane marking type: " + str(waypoint.right_lane_marking.type))
print("R lane marking change: " + str(waypoint.right_lane_marking.lane_change))
# ...
```
<button id="button1" class="CopyScript" onclick="CopyToClipboard('carla.Map.get_waypoint-code')">Copy snipet</button>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<button id="button1" class="CloseSnipet" onclick="CloseSnipet()">Close snipet</button><br><br>
<img src="/img/snipets_images/carla.Map.get_waypoint.jpg">
</div>
<div id ="carla.DebugHelper.draw_line-snipet" style="display: none;">
<p class="SnipetFont">
Snipet for carla.DebugHelper.draw_line
</p>
<div id="carla.DebugHelper.draw_line-code" class="SnipetContent">
```py
# This recipe is a modification of lane_explorer.py example.
# It draws the path of an actor through the world, printing information at each waypoint.
# ...
current_w = map.get_waypoint(vehicle.get_location())
while True:
next_w = map.get_waypoint(vehicle.get_location(), lane_type=carla.LaneType.Driving | carla.LaneType.Shoulder | carla.LaneType.Sidewalk )
# Check if the vehicle is moving
if next_w.id != current_w.id:
vector = vehicle.get_velocity()
# Check if the vehicle is on a sidewalk
if current_w.lane_type == carla.LaneType.Sidewalk:
draw_waypoint_union(debug, current_w, next_w, cyan if current_w.is_junction else red, 60)
else:
draw_waypoint_union(debug, current_w, next_w, cyan if current_w.is_junction else green, 60)
debug.draw_string(current_w.transform.location, str('%15.0f km/h' % (3.6 * math.sqrt(vector.x**2 + vector.y**2 + vector.z**2))), False, orange, 60)
draw_transform(debug, current_w.transform, white, 60)
# Update the current waypoint and sleep for some time
current_w = next_w
time.sleep(args.tick_time)
# ...
```
<button id="button1" class="CopyScript" onclick="CopyToClipboard('carla.DebugHelper.draw_line-code')">Copy snipet</button>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<button id="button1" class="CloseSnipet" onclick="CloseSnipet()">Close snipet</button><br><br>
<img src="/img/snipets_images/carla.DebugHelper.draw_line.jpg">
</div>
<div id ="carla.TrafficLight.set_state-snipet" style="display: none;">
<p class="SnipetFont">
Snipet for carla.TrafficLight.set_state
</p>
<div id="carla.TrafficLight.set_state-code" class="SnipetContent">
```py
# This recipe changes from red to green the traffic light that affects the vehicle.
# This is done by detecting if the vehicle actor is at a traffic light.
# ...
world = client.get_world()
spectator = world.get_spectator()
vehicle_bp = random.choice(world.get_blueprint_library().filter('vehicle.bmw.*'))
transform = random.choice(world.get_map().get_spawn_points())
vehicle = world.try_spawn_actor(vehicle_bp, transform)
# Wait for world to get the vehicle actor
world.tick()
world_snapshot = world.wait_for_tick()
actor_snapshot = world_snapshot.find(vehicle.id)
# Set spectator at given transform (vehicle transform)
spectator.set_transform(actor_snapshot.get_transform())
# ...# ...
if vehicle_actor.is_at_traffic_light():
traffic_light = vehicle_actor.get_traffic_light()
if traffic_light.get_state() == carla.TrafficLightState.Red:
# world.hud.notification("Traffic light changed! Good to go!")
traffic_light.set_state(carla.TrafficLightState.Green)
# ...
```
<button id="button1" class="CopyScript" onclick="CopyToClipboard('carla.TrafficLight.set_state-code')">Copy snipet</button>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<button id="button1" class="CloseSnipet" onclick="CloseSnipet()">Close snipet</button><br><br>
<img src="/img/snipets_images/carla.TrafficLight.set_state.gif">
</div>
<div id ="carla.DebugHelper.draw_box-snipet" style="display: none;">
<p class="SnipetFont">
Snipet for carla.DebugHelper.draw_box
</p>
<div id="carla.DebugHelper.draw_box-code" class="SnipetContent">
```py
# This recipe shows how to draw traffic light actor bounding boxes from a world snapshot.
# ....
debug = world.debug
world_snapshot = world.get_snapshot()
for actor_snapshot in world_snapshot:
actual_actor = world.get_actor(actor_snapshot.id)
if actual_actor.type_id == 'traffic.traffic_light':
debug.draw_box(carla.BoundingBox(actor_snapshot.get_transform().location,carla.Vector3D(0.5,0.5,2)),actor_snapshot.get_transform().rotation, 0.05, carla.Color(255,0,0,0),0)
# ...
```
<button id="button1" class="CopyScript" onclick="CopyToClipboard('carla.DebugHelper.draw_box-code')">Copy snipet</button>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<button id="button1" class="CloseSnipet" onclick="CloseSnipet()">Close snipet</button><br><br>
<img src="/img/snipets_images/carla.DebugHelper.draw_box.jpg">
</div>
<div id ="carla.Client.__init__-snipet" style="display: none;">
<p class="SnipetFont">
Snipet for carla.Client.__init__
@ -3609,6 +3554,91 @@ Snipet for carla.Client.__init__
</div>
<div id ="carla.Sensor.listen-snipet" style="display: none;">
<p class="SnipetFont">
Snipet for carla.Sensor.listen
</p>
<div id="carla.Sensor.listen-code" class="SnipetContent">
```py
# This recipe applies a color conversion to the image taken by a camera sensor,
# so it is converted to a semantic segmentation image.
# ...
camera_bp = world.get_blueprint_library().filter('sensor.camera.semantic_segmentation')
# ...
cc = carla.ColorConverter.CityScapesPalette
camera.listen(lambda image: image.save_to_disk('output/%06d.png' % image.frame, cc))
# ...
```
<button id="button1" class="CopyScript" onclick="CopyToClipboard('carla.Sensor.listen-code')">Copy snipet</button>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<button id="button1" class="CloseSnipet" onclick="CloseSnipet()">Close snipet</button><br><br>
</div>
<div id ="carla.World.spawn_actor-snipet" style="display: none;">
<p class="SnipetFont">
Snipet for carla.World.spawn_actor
</p>
<div id="carla.World.spawn_actor-code" class="SnipetContent">
```py
# This recipe attaches different camera / sensors to a vehicle with different attachments.
# ...
camera = world.spawn_actor(rgb_camera_bp, transform, attach_to=vehicle, attachment_type=Attachment.Rigid)
# Default attachment: Attachment.Rigid
gnss_sensor = world.spawn_actor(sensor_gnss_bp, transform, attach_to=vehicle)
collision_sensor = world.spawn_actor(sensor_collision_bp, transform, attach_to=vehicle)
lane_invasion_sensor = world.spawn_actor(sensor_lane_invasion_bp, transform, attach_to=vehicle)
# ...
```
<button id="button1" class="CopyScript" onclick="CopyToClipboard('carla.World.spawn_actor-code')">Copy snipet</button>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<button id="button1" class="CloseSnipet" onclick="CloseSnipet()">Close snipet</button><br><br>
</div>
<div id ="carla.World.get_spectator-snipet" style="display: none;">
<p class="SnipetFont">
Snipet for carla.World.get_spectator
</p>
<div id="carla.World.get_spectator-code" class="SnipetContent">
```py
# This recipe spawns an actor and the spectator camera at the actor's location.
# ...
world = client.get_world()
spectator = world.get_spectator()
vehicle_bp = random.choice(world.get_blueprint_library().filter('vehicle.bmw.*'))
transform = random.choice(world.get_map().get_spawn_points())
vehicle = world.try_spawn_actor(vehicle_bp, transform)
# Wait for world to get the vehicle actor
world.tick()
world_snapshot = world.wait_for_tick()
actor_snapshot = world_snapshot.find(vehicle.id)
# Set spectator at given transform (vehicle transform)
spectator.set_transform(actor_snapshot.get_transform())
# ...
```
<button id="button1" class="CopyScript" onclick="CopyToClipboard('carla.World.get_spectator-code')">Copy snipet</button>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<button id="button1" class="CloseSnipet" onclick="CloseSnipet()">Close snipet</button><br><br>
</div>
</div>

View File

@ -176,5 +176,25 @@ namespace client {
_episode.Lock()->EnableEnvironmentObjects(env_objects_ids, enable);
}
boost::optional<rpc::LabelledPoint> World::ProjectPoint(
geom::Location location, geom::Vector3D direction, float search_distance) const {
auto result = _episode.Lock()->ProjectPoint(location, direction, search_distance);
if (result.first) {
return result.second;
}
return {};
}
boost::optional<rpc::LabelledPoint> World::GroundProjection(
geom::Location location, float search_distance) const {
const geom::Vector3D DownVector(0,0,-1);
return ProjectPoint(location, DownVector, search_distance);
}
std::vector<rpc::LabelledPoint> World::CastRay(
geom::Location start_location, geom::Location end_location) const {
return _episode.Lock()->CastRay(start_location, end_location);
}
} // namespace client
} // namespace carla

View File

@ -19,6 +19,7 @@
#include "carla/rpc/AttachmentType.h"
#include "carla/rpc/EpisodeSettings.h"
#include "carla/rpc/EnvironmentObject.h"
#include "carla/rpc/LabelledPoint.h"
#include "carla/rpc/VehiclePhysicsControl.h"
#include "carla/rpc/WeatherParameters.h"
#include "carla/rpc/VehicleLightStateList.h"
@ -162,6 +163,15 @@ namespace client {
std::vector<uint64_t> env_objects_ids,
bool enable) const;
boost::optional<rpc::LabelledPoint> ProjectPoint(
geom::Location location, geom::Vector3D direction, float search_distance = 10000.f) const;
boost::optional<rpc::LabelledPoint> GroundProjection(
geom::Location location, float search_distance = 10000.0) const;
std::vector<rpc::LabelledPoint> CastRay(
geom::Location start_location, geom::Location end_location) const;
private:
detail::EpisodeProxy _episode;

View File

@ -461,6 +461,18 @@ namespace detail {
_pimpl->AsyncCall("enable_environment_objects", std::move(env_objects_ids), enable);
}
std::pair<bool,rpc::LabelledPoint> Client::ProjectPoint(
geom::Location location, geom::Vector3D direction, float search_distance) const {
using return_t = std::pair<bool,rpc::LabelledPoint>;
return _pimpl->CallAndWait<return_t>("project_point", location, direction, search_distance);
}
std::vector<rpc::LabelledPoint> Client::CastRay(
geom::Location start_location, geom::Location end_location) const {
using return_t = std::vector<rpc::LabelledPoint>;
return _pimpl->CallAndWait<return_t>("cast_ray", start_location, end_location);
}
} // namespace detail
} // namespace client
} // namespace carla

View File

@ -10,6 +10,7 @@
#include "carla/NonCopyable.h"
#include "carla/Time.h"
#include "carla/geom/Transform.h"
#include "carla/geom/Location.h"
#include "carla/rpc/Actor.h"
#include "carla/rpc/ActorDefinition.h"
#include "carla/rpc/AttachmentType.h"
@ -17,6 +18,7 @@
#include "carla/rpc/CommandResponse.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/EnvironmentObject.h"
@ -297,6 +299,12 @@ namespace detail {
std::vector<uint64_t> env_objects_ids,
bool enable) const;
std::pair<bool,rpc::LabelledPoint> ProjectPoint(
geom::Location location, geom::Vector3D direction, float search_distance) const;
std::vector<rpc::LabelledPoint> CastRay(
geom::Location start_location, geom::Location end_location) const;
private:
class Pimpl;

View File

@ -23,6 +23,7 @@
#include "carla/profiler/LifetimeProfiled.h"
#include "carla/rpc/TrafficLightState.h"
#include "carla/rpc/VehicleLightStateList.h"
#include "carla/rpc/LabelledPoint.h"
#include <boost/optional.hpp>
@ -241,6 +242,16 @@ namespace detail {
_client.EnableEnvironmentObjects(env_objects_ids, enable);
}
std::pair<bool,rpc::LabelledPoint> ProjectPoint(
geom::Location location, geom::Vector3D direction, float search_distance) const {
return _client.ProjectPoint(location, direction, search_distance);
}
std::vector<rpc::LabelledPoint> CastRay(
geom::Location start_location, geom::Location end_location) const {
return _client.CastRay(start_location, end_location);
}
/// @}
// =========================================================================
/// @name AI

View File

@ -0,0 +1,32 @@
// Copyright (c) 2020 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/Location.h"
#include "carla/rpc/ObjectLabel.h"
namespace carla {
namespace rpc {
struct LabelledPoint {
LabelledPoint () {}
LabelledPoint (Location location, CityObjectLabel label)
: _location(location), _label(label)
{}
Location _location;
CityObjectLabel _label;
MSGPACK_DEFINE_ARRAY(_location, _label);
};
}
}

View File

@ -23,10 +23,10 @@ namespace rpc {
RoadLines = 6u,
Roads = 7u,
Sidewalks = 8u,
TrafficSigns = 12u,
Vegetation = 9u,
Vehicles = 10u,
Walls = 11u,
TrafficSigns = 12u,
Sky = 13u,
Ground = 14u,
Bridge = 15u,

View File

@ -201,6 +201,11 @@ void export_world() {
.value("Terrain", cr::CityObjectLabel::Terrain)
;
class_<cr::LabelledPoint>("LabelledPoint", no_init)
.def_readonly("location", &cr::LabelledPoint::_location)
.def_readonly("label", &cr::LabelledPoint::_label)
;
#define SPAWN_ACTOR_WITHOUT_GIL(fn) +[]( \
cc::World &self, \
const cc::ActorBlueprint &blueprint, \
@ -247,6 +252,9 @@ void export_world() {
.def("get_level_bbs", &GetLevelBBs, (arg("actor_type")=cr::CityObjectLabel::None))
.def("get_environment_objects", &GetEnvironmentObjects)
.def("enable_environment_objects", &EnableEnvironmentObjects, (arg("env_objects_ids"), arg("enable")))
.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(self_ns::str(self_ns::self))
;

View File

@ -111,6 +111,16 @@ static boost::python::object OptionalToPythonObject(OptionalT &optional) {
return OptionalToPythonObject(optional); \
}
#define CALL_RETURNING_OPTIONAL_2(cls, fn, T1_, T2_) +[](const cls &self, T1_ t1, T2_ t2) { \
auto optional = self.fn(std::forward<T1_>(t1), std::forward<T2_>(t2)); \
return OptionalToPythonObject(optional); \
}
#define CALL_RETURNING_OPTIONAL_3(cls, fn, T1_, T2_, T3_) +[](const cls &self, T1_ t1, T2_ t2, T3_ t3) { \
auto optional = self.fn(std::forward<T1_>(t1), std::forward<T2_>(t2), std::forward<T3_>(t3)); \
return OptionalToPythonObject(optional); \
}
#define CALL_RETURNING_OPTIONAL_WITHOUT_GIL(cls, fn) +[](const cls &self) { \
carla::PythonUtil::ReleaseGIL unlock; \
auto optional = self.fn(); \

View File

@ -186,6 +186,20 @@
An attachment that expands or retracts the position of the actor, depending on its parent. This attachment is only recommended to record videos from the simulation where a smooth movement is needed. SpringArms are an Unreal Engine component so [check the UE docs](https://docs.unrealengine.com/en-US/Gameplay/HowTo/UsingCameras/SpringArmComponents/index.html) to learn more about them. <br><b style="color:red;">Warning:</b> The <b>SpringArm</b> attachment presents weird behaviors when an actor is spawned with a relative translation in the Z-axis (e.g. <code>child_location = Location(0,0,2)</code>).
# --------------------------------------
- class_name: LabelledPoint
# - DESCRIPTION ------------------------
doc: >
Class that represent a position in space with a semantic label.
# - PROPERTIES -------------------------
instance_variables:
- var_name: location
doc: >
Position in 3D space.
- var_name: label
doc: >
Semantic tag of the point.
# --------------------------------------
- class_name: World
# - DESCRIPTION ------------------------
doc: >
@ -421,13 +435,59 @@
New conditions to be applied.
doc: >
Changes the weather parameteres ruling the simulation to another ones defined in an object.
# --------------------------------------
# --------------------------------------
- def_name: cast_ray
return: list(carla.LabelledPoint)
params:
- param_name: initial_location
type: carla.Location
doc: >
The initial position of the ray.
- param_name: final_location
type: carla.Location
doc: >
The final position of the ray.
doc: >
Casts a ray from the specified initial_location to final_location. The function then detects all geometries intersecting the ray and returns a list of carla.LabelledPoint in order.
# --------------------------------------
- def_name: project_point
return: carla.LabelledPoint
params:
- param_name: location
type: carla.Location
doc: >
The point to be projected.
- param_name: direction
type: carla.Vector3D
doc: >
The direction of projection.
- param_name: search_distance
type: float
doc: >
The maximum distance to perform the projection
doc: >
Projects the specified point to the desired direction in the scene. The functions casts a ray from location in a direction and returns a carla.Labelled object with the first geometry this ray intersects. If no geometry is found in the search_distance range the function returns `None`.
# --------------------------------------
- def_name: ground_projection
return: carla.LabelledPoint
params:
- param_name: location
type: carla.Location
doc: >
The point to be projected.
- param_name: search_distance
type: float
doc: >
The maximum distance to perform the projection
doc: >
Projects the specified point downwards in the scene. The functions casts a ray from location in the direction (0,0,-1) (downwards) and returns a carla.Labelled object with the first geometry this ray intersects (usually the ground). If no geometry is found in the search_distance range the function returns `None`.
# --------------------------------------
- def_name: __str__
return:
string
doc: >
The content of the world is parsed and printed as a brief report of its current state.
# --------------------------------------
# --------------------------------------
- class_name: DebugHelper
# - DESCRIPTION ------------------------

View File

@ -97,13 +97,15 @@ InitialAverageFrameRate=0.016667
PhysXTreeRebuildRate=10
DefaultBroadphaseSettings=(bUseMBPOnClient=False,bUseMBPOnServer=False,MBPBounds=(Min=(X=0.000000,Y=0.000000,Z=0.000000),Max=(X=0.000000,Y=0.000000,Z=0.000000),IsValid=0),MBPNumSubdivs=2)
[/Script/WindowsTargetPlatform.WindowsTargetSettings]
DefaultGraphicsRHI=DefaultGraphicsRHI_DX12
[/Script/Engine.CollisionProfile]
+Profiles=(Name="CustomSensorCollision",CollisionEnabled=QueryOnly,bCanModify=True,ObjectTypeName="SensorObject",CustomResponses=((Channel="WorldStatic",Response=ECR_Ignore),(Channel="WorldDynamic",Response=ECR_Ignore),(Channel="Pawn",Response=ECR_Ignore),(Channel="Visibility",Response=ECR_Ignore),(Channel="Camera",Response=ECR_Ignore),(Channel="PhysicsBody",Response=ECR_Ignore),(Channel="Vehicle",Response=ECR_Ignore),(Channel="Destructible",Response=ECR_Ignore),(Channel="SensorObject"),(Channel="SensorTrace")),HelpMessage="Used for custom collision meshes for objects that has very complex meshes but we want them to appear in raycast based sensors")
+DefaultChannelResponses=(Channel=ECC_GameTraceChannel1,DefaultResponse=ECR_Ignore,bTraceType=False,bStaticObject=False,Name="SensorObject")
+DefaultChannelResponses=(Channel=ECC_GameTraceChannel2,DefaultResponse=ECR_Ignore,bTraceType=True,bStaticObject=False,Name="SensorTrace")
+DefaultChannelResponses=(Channel=ECC_GameTraceChannel3,DefaultResponse=ECR_Overlap,bTraceType=True,bStaticObject=False,Name="OverlapChannel")
+EditProfiles=(Name="BlockAll",CustomResponses=((Channel="SensorObject"),(Channel="SensorTrace")))
+EditProfiles=(Name="OverlapAll",CustomResponses=((Channel="SensorObject",Response=ECR_Overlap),(Channel="SensorTrace",Response=ECR_Overlap)))
[/Script/WindowsTargetPlatform.WindowsTargetSettings]
DefaultGraphicsRHI=DefaultGraphicsRHI_DX12

View File

@ -10,9 +10,11 @@
#include "Carla/OpenDrive/OpenDrive.h"
#include "Carla/Util/DebugShapeDrawer.h"
#include "Carla/Util/NavigationMesh.h"
#include "Carla/Util/RayTracer.h"
#include "Carla/Vehicle/CarlaWheeledVehicle.h"
#include "Carla/Walker/WalkerController.h"
#include "GameFramework/CharacterMovementComponent.h"
#include "Carla/Game/Tagger.h"
#include <compiler/disable-ue4-macros.h>
#include <carla/Functional.h>
@ -25,6 +27,7 @@
#include <carla/rpc/DebugShape.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/EnvironmentObject.h>
@ -46,6 +49,7 @@
#include <vector>
#include <map>
#include <tuple>
template <typename T>
using R = carla::rpc::Response<T>;
@ -1410,6 +1414,28 @@ void FCarlaServer::FPimpl::BindActions()
};
// ~~ Ray Casting ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
BIND_SYNC(project_point) << [this]
(cr::Location Location, cr::Vector3D Direction, float SearchDistance)
-> R<std::pair<bool,cr::LabelledPoint>>
{
REQUIRE_CARLA_EPISODE();
auto *World = Episode->GetWorld();
constexpr float meter_to_centimeter = 100.0f;
return URayTracer::ProjectPoint(Location, Direction.ToFVector(),
meter_to_centimeter * SearchDistance, World);
};
BIND_SYNC(cast_ray) << [this]
(cr::Location StartLocation, cr::Location EndLocation)
-> R<std::vector<cr::LabelledPoint>>
{
REQUIRE_CARLA_EPISODE();
auto *World = Episode->GetWorld();
return URayTracer::CastRay(StartLocation, EndLocation, World);
};
}
// =============================================================================

View File

@ -1,4 +1,4 @@
// Copyright (c) 2017 Computer Vision Center (CVC) at the Universitat Autonoma
// Copyright (c) 2020 Computer Vision Center (CVC) at the Universitat Autonoma
// de Barcelona (UAB).
//
// This work is licensed under the terms of the MIT license.

View File

@ -1,4 +1,4 @@
// Copyright (c) 2017 Computer Vision Center (CVC) at the Universitat Autonoma
// Copyright (c) 2020 Computer Vision Center (CVC) at the Universitat Autonoma
// de Barcelona (UAB).
//
// This work is licensed under the terms of the MIT license.

View File

@ -0,0 +1,58 @@
// Copyright (c) 2020 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 "Carla.h"
#include "Carla/Util/RayTracer.h"
#include "Carla/Game/CarlaStatics.h"
namespace crp = carla::rpc;
std::vector<crp::LabelledPoint> URayTracer::CastRay(
FVector StartLocation, FVector EndLocation, UWorld * World)
{
TArray<FHitResult> OutHits;
World->LineTraceMultiByChannel(
OutHits,
StartLocation,
EndLocation,
ECC_GameTraceChannel3, // overlap channel
FCollisionQueryParams(),
FCollisionResponseParams()
);
std::vector<crp::LabelledPoint> result;
for (auto& Hit : OutHits)
{
UPrimitiveComponent* Component = Hit.GetComponent();
crp::CityObjectLabel ComponentTag =
ATagger::GetTagOfTaggedComponent(*Component);
result.emplace_back(crp::LabelledPoint(Hit.Location, ComponentTag));
}
return result;
}
std::pair<bool, crp::LabelledPoint> URayTracer::ProjectPoint(
FVector StartLocation, FVector Direction, float MaxDistance, UWorld * World)
{
FHitResult Hit;
bool bDidHit = World->LineTraceSingleByChannel(
Hit,
StartLocation,
StartLocation + Direction.GetSafeNormal() * MaxDistance,
ECC_GameTraceChannel2, // camera
FCollisionQueryParams(),
FCollisionResponseParams()
);
if (bDidHit)
{
UPrimitiveComponent* Component = Hit.GetComponent();
crp::CityObjectLabel ComponentTag =
ATagger::GetTagOfTaggedComponent(*Component);
return std::make_pair(bDidHit, crp::LabelledPoint(Hit.Location, ComponentTag));
}
return std::make_pair(bDidHit, crp::LabelledPoint(FVector(0.0f,0.0f,0.0f), crp::CityObjectLabel::None));
}

View File

@ -0,0 +1,36 @@
// Copyright (c) 2020 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 "Kismet/BlueprintFunctionLibrary.h"
#include <compiler/disable-ue4-macros.h>
#include "carla/rpc/ObjectLabel.h"
#include "carla/rpc/LabelledPoint.h"
#include <compiler/enable-ue4-macros.h>
#include <vector>
#include <utility>
#include "RayTracer.generated.h"
class AActor;
UCLASS()
class CARLA_API URayTracer : public UBlueprintFunctionLibrary
{
GENERATED_BODY()
public:
static std::vector<carla::rpc::LabelledPoint> CastRay(
FVector StartLocation, FVector EndLocation, UWorld * World);
static std::pair<bool, carla::rpc::LabelledPoint> ProjectPoint(
FVector StartLocation, FVector Direction, float MaxDistance, UWorld * World);
};