Merge branch 'master' into some_benchmark_fixes
This commit is contained in:
commit
213707c685
|
@ -27,4 +27,5 @@ __pycache__
|
|||
_benchmarks_results
|
||||
_images*
|
||||
_out
|
||||
_site
|
||||
core
|
||||
|
|
15
.travis.yml
15
.travis.yml
|
@ -25,3 +25,18 @@ matrix:
|
|||
- cppcheck
|
||||
script:
|
||||
- cppcheck . -iBuild -i.pb.cc --error-exitcode=1 --enable=warning --quiet
|
||||
|
||||
- env: TEST="MkDocs"
|
||||
install:
|
||||
- pip install mkdocs
|
||||
script:
|
||||
- mkdocs build --verbose --clean --strict --site-dir _site
|
||||
|
||||
- env: TEST="AwesomeBot"
|
||||
install:
|
||||
- gem install awesome_bot
|
||||
script:
|
||||
- find . -name '*.md' | xargs awesome_bot --allow-dupe --allow-redirect --skip-save-results
|
||||
|
||||
notifications:
|
||||
email: false
|
||||
|
|
|
@ -18,7 +18,8 @@
|
|||
"Intermediate",
|
||||
"Saved",
|
||||
"Unreal/CarlaUE4/Content*",
|
||||
"__pycache__"
|
||||
"__pycache__",
|
||||
"_site"
|
||||
],
|
||||
"file_exclude_patterns":
|
||||
[
|
||||
|
|
|
@ -101,7 +101,7 @@ spawned. Note that the blueprint can call back C++ functions, for instance for
|
|||
getting the random engine. This way there is a back-and-forth communication
|
||||
between C++ code and blueprints.
|
||||
|
||||
[capturelink]: https://github.com/carla-simulator/carla/blob/master/Unreal/CarlaUE4/Plugins/Carla/Source/Carla/SceneCaptureToDiskCamera.h
|
||||
[capturelink]: https://github.com/carla-simulator/carla/blob/master/Unreal/CarlaUE4/Plugins/Carla/Source/Carla/Sensor/SceneCaptureToDiskCamera.h
|
||||
|
||||
#### Coding standard
|
||||
|
||||
|
|
|
@ -35,6 +35,11 @@ to a more human readable palette of colors. It can be found at
|
|||
["Util/ImageConverter"][imgconvlink]. Alternatively, they can also be converted
|
||||
using the functions at `carla.image_converter` Python module.
|
||||
|
||||
Note that all the sensor data comes with a _frame number_ stamp, this _frame
|
||||
number_ matches the one received in the measurements. This is especially useful
|
||||
for running the simulator in asynchronous mode and synchronize sensor data on
|
||||
the client side.
|
||||
|
||||
[clientexamplelink]: https://github.com/carla-simulator/carla/blob/master/PythonClient/client_example.py
|
||||
[settingslink]: https://github.com/carla-simulator/carla/blob/master/Docs/Example.CarlaSettings.ini
|
||||
[imgconvlink]: https://github.com/carla-simulator/carla/tree/master/Util/ImageConverter
|
||||
|
|
|
@ -11,13 +11,13 @@ to the client. This document describes the details of these measurements.
|
|||
Time-stamps
|
||||
-----------
|
||||
|
||||
Since CARLA can be run at fixed-frame rate, we keep track of two different
|
||||
time-stamps.
|
||||
Every frame is described by three different counters/time-stamps
|
||||
|
||||
Key | Type | Units | Description
|
||||
-------------------------- | --------- | ------------ | ------------
|
||||
frame_number | uint64 | | Frame counter (it is **not** restarted on each episode).
|
||||
platform_timestamp | uint32 | milliseconds | Time-stamp of the current frame, as given by the OS.
|
||||
game_timestamp | uint32 | milliseconds | In-game time-stamp, elapsed since the beginning of the current level.
|
||||
game_timestamp | uint32 | milliseconds | In-game time-stamp, elapsed since the beginning of the current episode.
|
||||
|
||||
In real-time mode, the elapsed time between two time steps should be similar
|
||||
both platform and game time-stamps. When run in fixed-time step, the game
|
||||
|
@ -126,18 +126,68 @@ If enabled, the server attaches a list of agents to the measurements package
|
|||
every frame. Each of these agents has an unique id that identifies it, and
|
||||
belongs to one of the following classes
|
||||
|
||||
* **Vehicle** Contains its transform, box-extent, and forward speed.
|
||||
* **Pedestrian** Contains its transform, box-extent, and forward speed. (*)
|
||||
* **Traffic light** Contains its transform and state (green, yellow, red).
|
||||
* **Speed-limit sign** Contains its transform and speed-limit.
|
||||
* Vehicle
|
||||
* Pedestrian
|
||||
* Traffic ligth
|
||||
* Speed limit sign
|
||||
|
||||
(*) At this point every pedestrian is assumed to have the same bounding-box
|
||||
size.
|
||||
Each of them can be accessed in Python by checking if the agent object has the
|
||||
field enabled
|
||||
|
||||
```python
|
||||
measurements, sensor_data = client.read_data()
|
||||
|
||||
for agent in measurements.non_player_agents:
|
||||
agent.id # unique id of the agent
|
||||
if agent.HasField('vehicle'):
|
||||
agent.vehicle.forward_speed
|
||||
agent.vehicle.transform
|
||||
agent.vehicle.bounding_box
|
||||
```
|
||||
|
||||
<h6>Vehicle</h6>
|
||||
|
||||
Key | Type | Description
|
||||
------------------------------- | --------- | ------------
|
||||
id | uint32 | Agent ID
|
||||
vehicle.forward_speed | float | Forward speed of the vehicle in m/s
|
||||
vehicle.transform | Transform | Agent-to-world transform
|
||||
vehicle.bounding_box.transform | Transform | Transform of the bounding box relative to the vehicle
|
||||
vehicle.bounding_box.extent | Vector3D | Radii dimensions of the bounding box in meters
|
||||
|
||||
<h6>Pedestrian</h6>
|
||||
|
||||
Key | Type | Description
|
||||
--------------------------------- | --------- | ------------
|
||||
id | uint32 | Agent ID
|
||||
pedestrian.forward_speed | float | Forward speed of the pedestrian in m/s
|
||||
pedestrian.transform | Transform | Agent-to-world transform
|
||||
pedestrian.bounding_box.transform | Transform | Transform of the bounding box relative to the pedestrian
|
||||
pedestrian.bounding_box.extent | Vector3D | Radii dimensions of the bounding box in meters (*)
|
||||
|
||||
<small>(*) At this point every pedestrian is assumed to have the same
|
||||
bounding-box size.</small>
|
||||
|
||||
<h6>Traffic light</h6>
|
||||
|
||||
Key | Type | Description
|
||||
---------------------------- | --------- | ------------
|
||||
id | uint32 | Agent ID
|
||||
traffic_light.transform | Transform | Agent-to-world transform
|
||||
traffic_light.state | enum | Traffic light state; `GREEN`, `YELLOW`, or `RED`
|
||||
|
||||
<h6>Speed limit sign</h6>
|
||||
|
||||
Key | Type | Description
|
||||
---------------------------- | --------- | ------------
|
||||
id | uint32 | Agent ID
|
||||
speed_limit_sign.transform | Transform | Agent-to-world transform
|
||||
speed_limit_sign.speed_limit | float | Speed limit in m/s
|
||||
|
||||
<h4>Transform and bounding box</h4>
|
||||
|
||||
The transform defines the location and orientation of the agent. The bounding
|
||||
box is centered at the agent's location. The box extent gives the radii
|
||||
dimensions of the bounding box of the agent.
|
||||
The transform defines the location and orientation of the agent. The transform
|
||||
of the bounding box is given relative to the vehicle. The box extent gives the
|
||||
radii dimensions of the bounding box of the agent.
|
||||
|
||||
![Vehicle Bounding Box](img/vehicle_bounding_box.png)
|
||||
|
|
5
Makefile
5
Makefile
|
@ -35,6 +35,11 @@ vsproject: MY_CMAKE_FLAGS+=-DCMAKE_BUILD_TYPE=Release
|
|||
vsproject: MY_CMAKE_FLAGS+=-G "Visual Studio 14 2015 Win64"
|
||||
vsproject: call_cmake
|
||||
|
||||
vsproject15: BUILD_FOLDER=$(BASE_BUILD_FOLDER)/visualstudio
|
||||
vsproject15: MY_CMAKE_FLAGS+=-DCMAKE_BUILD_TYPE=Release
|
||||
vsproject15: MY_CMAKE_FLAGS+=-G "Visual Studio 15 2017 Win64"
|
||||
vsproject15: call_cmake
|
||||
|
||||
build_linux: MY_CMAKE_FLAGS+=-G "Ninja"
|
||||
build_linux: call_cmake
|
||||
@cd $(BUILD_FOLDER) && ninja && ninja install
|
||||
|
|
|
@ -19,7 +19,7 @@ DESCRIPTOR = _descriptor.FileDescriptor(
|
|||
name='carla_server.proto',
|
||||
package='carla_server',
|
||||
syntax='proto3',
|
||||
serialized_pb=_b('\n\x12\x63\x61rla_server.proto\x12\x0c\x63\x61rla_server\"+\n\x08Vector3D\x12\t\n\x01x\x18\x01 \x01(\x02\x12\t\n\x01y\x18\x02 \x01(\x02\x12\t\n\x01z\x18\x03 \x01(\x02\"6\n\nRotation3D\x12\r\n\x05pitch\x18\x01 \x01(\x02\x12\x0b\n\x03yaw\x18\x02 \x01(\x02\x12\x0c\n\x04roll\x18\x03 \x01(\x02\"\x92\x01\n\tTransform\x12(\n\x08location\x18\x01 \x01(\x0b\x32\x16.carla_server.Vector3D\x12/\n\x0borientation\x18\x02 \x01(\x0b\x32\x16.carla_server.Vector3DB\x02\x18\x01\x12*\n\x08rotation\x18\x03 \x01(\x0b\x32\x18.carla_server.Rotation3D\"\x80\x01\n\x06Sensor\x12\n\n\x02id\x18\x01 \x01(\x07\x12\'\n\x04type\x18\x02 \x01(\x0e\x32\x19.carla_server.Sensor.Type\x12\x0c\n\x04name\x18\x03 \x01(\t\"3\n\x04Type\x12\x0b\n\x07UNKNOWN\x10\x00\x12\n\n\x06\x43\x41MERA\x10\x01\x12\x12\n\x0eLIDAR_RAY_CAST\x10\x02\"x\n\x07Vehicle\x12*\n\ttransform\x18\x01 \x01(\x0b\x32\x17.carla_server.Transform\x12*\n\nbox_extent\x18\x02 \x01(\x0b\x32\x16.carla_server.Vector3D\x12\x15\n\rforward_speed\x18\x03 \x01(\x02\"{\n\nPedestrian\x12*\n\ttransform\x18\x01 \x01(\x0b\x32\x17.carla_server.Transform\x12*\n\nbox_extent\x18\x02 \x01(\x0b\x32\x16.carla_server.Vector3D\x12\x15\n\rforward_speed\x18\x03 \x01(\x02\"\x94\x01\n\x0cTrafficLight\x12*\n\ttransform\x18\x01 \x01(\x0b\x32\x17.carla_server.Transform\x12/\n\x05state\x18\x02 \x01(\x0e\x32 .carla_server.TrafficLight.State\"\'\n\x05State\x12\t\n\x05GREEN\x10\x00\x12\n\n\x06YELLOW\x10\x01\x12\x07\n\x03RED\x10\x02\"Q\n\x0eSpeedLimitSign\x12*\n\ttransform\x18\x01 \x01(\x0b\x32\x17.carla_server.Transform\x12\x13\n\x0bspeed_limit\x18\x02 \x01(\x02\"\xe5\x01\n\x05\x41gent\x12\n\n\x02id\x18\x01 \x01(\x07\x12(\n\x07vehicle\x18\x02 \x01(\x0b\x32\x15.carla_server.VehicleH\x00\x12.\n\npedestrian\x18\x03 \x01(\x0b\x32\x18.carla_server.PedestrianH\x00\x12\x33\n\rtraffic_light\x18\x04 \x01(\x0b\x32\x1a.carla_server.TrafficLightH\x00\x12\x38\n\x10speed_limit_sign\x18\x05 \x01(\x0b\x32\x1c.carla_server.SpeedLimitSignH\x00\x42\x07\n\x05\x61gent\"%\n\x11RequestNewEpisode\x12\x10\n\x08ini_file\x18\x01 \x01(\t\"n\n\x10SceneDescription\x12\x33\n\x12player_start_spots\x18\x01 \x03(\x0b\x32\x17.carla_server.Transform\x12%\n\x07sensors\x18\x02 \x03(\x0b\x32\x14.carla_server.Sensor\"/\n\x0c\x45pisodeStart\x12\x1f\n\x17player_start_spot_index\x18\x01 \x01(\r\"\x1d\n\x0c\x45pisodeReady\x12\r\n\x05ready\x18\x01 \x01(\x08\"^\n\x07\x43ontrol\x12\r\n\x05steer\x18\x01 \x01(\x02\x12\x10\n\x08throttle\x18\x02 \x01(\x02\x12\r\n\x05\x62rake\x18\x03 \x01(\x02\x12\x12\n\nhand_brake\x18\x04 \x01(\x08\x12\x0f\n\x07reverse\x18\x05 \x01(\x08\"\xb6\x04\n\x0cMeasurements\x12\x1a\n\x12platform_timestamp\x18\x01 \x01(\r\x12\x16\n\x0egame_timestamp\x18\x02 \x01(\r\x12J\n\x13player_measurements\x18\x03 \x01(\x0b\x32-.carla_server.Measurements.PlayerMeasurements\x12.\n\x11non_player_agents\x18\x04 \x03(\x0b\x32\x13.carla_server.Agent\x1a\xf5\x02\n\x12PlayerMeasurements\x12*\n\ttransform\x18\x01 \x01(\x0b\x32\x17.carla_server.Transform\x12*\n\nbox_extent\x18\x0b \x01(\x0b\x32\x16.carla_server.Vector3D\x12,\n\x0c\x61\x63\x63\x65leration\x18\x03 \x01(\x0b\x32\x16.carla_server.Vector3D\x12\x15\n\rforward_speed\x18\x04 \x01(\x02\x12\x1a\n\x12\x63ollision_vehicles\x18\x05 \x01(\x02\x12\x1d\n\x15\x63ollision_pedestrians\x18\x06 \x01(\x02\x12\x17\n\x0f\x63ollision_other\x18\x07 \x01(\x02\x12\x1e\n\x16intersection_otherlane\x18\x08 \x01(\x02\x12\x1c\n\x14intersection_offroad\x18\t \x01(\x02\x12\x30\n\x11\x61utopilot_control\x18\n \x01(\x0b\x32\x15.carla_server.ControlB\x03\xf8\x01\x01\x62\x06proto3')
|
||||
serialized_pb=_b('\n\x12\x63\x61rla_server.proto\x12\x0c\x63\x61rla_server\"+\n\x08Vector3D\x12\t\n\x01x\x18\x01 \x01(\x02\x12\t\n\x01y\x18\x02 \x01(\x02\x12\t\n\x01z\x18\x03 \x01(\x02\"6\n\nRotation3D\x12\r\n\x05pitch\x18\x01 \x01(\x02\x12\x0b\n\x03yaw\x18\x02 \x01(\x02\x12\x0c\n\x04roll\x18\x03 \x01(\x02\"\x92\x01\n\tTransform\x12(\n\x08location\x18\x01 \x01(\x0b\x32\x16.carla_server.Vector3D\x12/\n\x0borientation\x18\x02 \x01(\x0b\x32\x16.carla_server.Vector3DB\x02\x18\x01\x12*\n\x08rotation\x18\x03 \x01(\x0b\x32\x18.carla_server.Rotation3D\"a\n\x0b\x42oundingBox\x12*\n\ttransform\x18\x01 \x01(\x0b\x32\x17.carla_server.Transform\x12&\n\x06\x65xtent\x18\x02 \x01(\x0b\x32\x16.carla_server.Vector3D\"\x80\x01\n\x06Sensor\x12\n\n\x02id\x18\x01 \x01(\x07\x12\'\n\x04type\x18\x02 \x01(\x0e\x32\x19.carla_server.Sensor.Type\x12\x0c\n\x04name\x18\x03 \x01(\t\"3\n\x04Type\x12\x0b\n\x07UNKNOWN\x10\x00\x12\n\n\x06\x43\x41MERA\x10\x01\x12\x12\n\x0eLIDAR_RAY_CAST\x10\x02\"}\n\x07Vehicle\x12*\n\ttransform\x18\x01 \x01(\x0b\x32\x17.carla_server.Transform\x12/\n\x0c\x62ounding_box\x18\x04 \x01(\x0b\x32\x19.carla_server.BoundingBox\x12\x15\n\rforward_speed\x18\x03 \x01(\x02\"\x80\x01\n\nPedestrian\x12*\n\ttransform\x18\x01 \x01(\x0b\x32\x17.carla_server.Transform\x12/\n\x0c\x62ounding_box\x18\x04 \x01(\x0b\x32\x19.carla_server.BoundingBox\x12\x15\n\rforward_speed\x18\x03 \x01(\x02\"\x94\x01\n\x0cTrafficLight\x12*\n\ttransform\x18\x01 \x01(\x0b\x32\x17.carla_server.Transform\x12/\n\x05state\x18\x02 \x01(\x0e\x32 .carla_server.TrafficLight.State\"\'\n\x05State\x12\t\n\x05GREEN\x10\x00\x12\n\n\x06YELLOW\x10\x01\x12\x07\n\x03RED\x10\x02\"Q\n\x0eSpeedLimitSign\x12*\n\ttransform\x18\x01 \x01(\x0b\x32\x17.carla_server.Transform\x12\x13\n\x0bspeed_limit\x18\x02 \x01(\x02\"\xe5\x01\n\x05\x41gent\x12\n\n\x02id\x18\x01 \x01(\x07\x12(\n\x07vehicle\x18\x02 \x01(\x0b\x32\x15.carla_server.VehicleH\x00\x12.\n\npedestrian\x18\x03 \x01(\x0b\x32\x18.carla_server.PedestrianH\x00\x12\x33\n\rtraffic_light\x18\x04 \x01(\x0b\x32\x1a.carla_server.TrafficLightH\x00\x12\x38\n\x10speed_limit_sign\x18\x05 \x01(\x0b\x32\x1c.carla_server.SpeedLimitSignH\x00\x42\x07\n\x05\x61gent\"%\n\x11RequestNewEpisode\x12\x10\n\x08ini_file\x18\x01 \x01(\t\"n\n\x10SceneDescription\x12\x33\n\x12player_start_spots\x18\x01 \x03(\x0b\x32\x17.carla_server.Transform\x12%\n\x07sensors\x18\x02 \x03(\x0b\x32\x14.carla_server.Sensor\"/\n\x0c\x45pisodeStart\x12\x1f\n\x17player_start_spot_index\x18\x01 \x01(\r\"\x1d\n\x0c\x45pisodeReady\x12\r\n\x05ready\x18\x01 \x01(\x08\"^\n\x07\x43ontrol\x12\r\n\x05steer\x18\x01 \x01(\x02\x12\x10\n\x08throttle\x18\x02 \x01(\x02\x12\r\n\x05\x62rake\x18\x03 \x01(\x02\x12\x12\n\nhand_brake\x18\x04 \x01(\x08\x12\x0f\n\x07reverse\x18\x05 \x01(\x08\"\xd1\x04\n\x0cMeasurements\x12\x14\n\x0c\x66rame_number\x18\x05 \x01(\x04\x12\x1a\n\x12platform_timestamp\x18\x01 \x01(\r\x12\x16\n\x0egame_timestamp\x18\x02 \x01(\r\x12J\n\x13player_measurements\x18\x03 \x01(\x0b\x32-.carla_server.Measurements.PlayerMeasurements\x12.\n\x11non_player_agents\x18\x04 \x03(\x0b\x32\x13.carla_server.Agent\x1a\xfa\x02\n\x12PlayerMeasurements\x12*\n\ttransform\x18\x01 \x01(\x0b\x32\x17.carla_server.Transform\x12/\n\x0c\x62ounding_box\x18\x0c \x01(\x0b\x32\x19.carla_server.BoundingBox\x12,\n\x0c\x61\x63\x63\x65leration\x18\x03 \x01(\x0b\x32\x16.carla_server.Vector3D\x12\x15\n\rforward_speed\x18\x04 \x01(\x02\x12\x1a\n\x12\x63ollision_vehicles\x18\x05 \x01(\x02\x12\x1d\n\x15\x63ollision_pedestrians\x18\x06 \x01(\x02\x12\x17\n\x0f\x63ollision_other\x18\x07 \x01(\x02\x12\x1e\n\x16intersection_otherlane\x18\x08 \x01(\x02\x12\x1c\n\x14intersection_offroad\x18\t \x01(\x02\x12\x30\n\x11\x61utopilot_control\x18\n \x01(\x0b\x32\x15.carla_server.ControlB\x03\xf8\x01\x01\x62\x06proto3')
|
||||
)
|
||||
|
||||
|
||||
|
@ -45,8 +45,8 @@ _SENSOR_TYPE = _descriptor.EnumDescriptor(
|
|||
],
|
||||
containing_type=None,
|
||||
options=None,
|
||||
serialized_start=364,
|
||||
serialized_end=415,
|
||||
serialized_start=463,
|
||||
serialized_end=514,
|
||||
)
|
||||
_sym_db.RegisterEnumDescriptor(_SENSOR_TYPE)
|
||||
|
||||
|
@ -71,8 +71,8 @@ _TRAFFICLIGHT_STATE = _descriptor.EnumDescriptor(
|
|||
],
|
||||
containing_type=None,
|
||||
options=None,
|
||||
serialized_start=774,
|
||||
serialized_end=813,
|
||||
serialized_start=884,
|
||||
serialized_end=923,
|
||||
)
|
||||
_sym_db.RegisterEnumDescriptor(_TRAFFICLIGHT_STATE)
|
||||
|
||||
|
@ -212,6 +212,44 @@ _TRANSFORM = _descriptor.Descriptor(
|
|||
)
|
||||
|
||||
|
||||
_BOUNDINGBOX = _descriptor.Descriptor(
|
||||
name='BoundingBox',
|
||||
full_name='carla_server.BoundingBox',
|
||||
filename=None,
|
||||
file=DESCRIPTOR,
|
||||
containing_type=None,
|
||||
fields=[
|
||||
_descriptor.FieldDescriptor(
|
||||
name='transform', full_name='carla_server.BoundingBox.transform', index=0,
|
||||
number=1, type=11, cpp_type=10, label=1,
|
||||
has_default_value=False, default_value=None,
|
||||
message_type=None, enum_type=None, containing_type=None,
|
||||
is_extension=False, extension_scope=None,
|
||||
options=None),
|
||||
_descriptor.FieldDescriptor(
|
||||
name='extent', full_name='carla_server.BoundingBox.extent', index=1,
|
||||
number=2, type=11, cpp_type=10, label=1,
|
||||
has_default_value=False, default_value=None,
|
||||
message_type=None, enum_type=None, containing_type=None,
|
||||
is_extension=False, extension_scope=None,
|
||||
options=None),
|
||||
],
|
||||
extensions=[
|
||||
],
|
||||
nested_types=[],
|
||||
enum_types=[
|
||||
],
|
||||
options=None,
|
||||
is_extendable=False,
|
||||
syntax='proto3',
|
||||
extension_ranges=[],
|
||||
oneofs=[
|
||||
],
|
||||
serialized_start=286,
|
||||
serialized_end=383,
|
||||
)
|
||||
|
||||
|
||||
_SENSOR = _descriptor.Descriptor(
|
||||
name='Sensor',
|
||||
full_name='carla_server.Sensor',
|
||||
|
@ -253,8 +291,8 @@ _SENSOR = _descriptor.Descriptor(
|
|||
extension_ranges=[],
|
||||
oneofs=[
|
||||
],
|
||||
serialized_start=287,
|
||||
serialized_end=415,
|
||||
serialized_start=386,
|
||||
serialized_end=514,
|
||||
)
|
||||
|
||||
|
||||
|
@ -273,8 +311,8 @@ _VEHICLE = _descriptor.Descriptor(
|
|||
is_extension=False, extension_scope=None,
|
||||
options=None),
|
||||
_descriptor.FieldDescriptor(
|
||||
name='box_extent', full_name='carla_server.Vehicle.box_extent', index=1,
|
||||
number=2, type=11, cpp_type=10, label=1,
|
||||
name='bounding_box', full_name='carla_server.Vehicle.bounding_box', index=1,
|
||||
number=4, type=11, cpp_type=10, label=1,
|
||||
has_default_value=False, default_value=None,
|
||||
message_type=None, enum_type=None, containing_type=None,
|
||||
is_extension=False, extension_scope=None,
|
||||
|
@ -298,8 +336,8 @@ _VEHICLE = _descriptor.Descriptor(
|
|||
extension_ranges=[],
|
||||
oneofs=[
|
||||
],
|
||||
serialized_start=417,
|
||||
serialized_end=537,
|
||||
serialized_start=516,
|
||||
serialized_end=641,
|
||||
)
|
||||
|
||||
|
||||
|
@ -318,8 +356,8 @@ _PEDESTRIAN = _descriptor.Descriptor(
|
|||
is_extension=False, extension_scope=None,
|
||||
options=None),
|
||||
_descriptor.FieldDescriptor(
|
||||
name='box_extent', full_name='carla_server.Pedestrian.box_extent', index=1,
|
||||
number=2, type=11, cpp_type=10, label=1,
|
||||
name='bounding_box', full_name='carla_server.Pedestrian.bounding_box', index=1,
|
||||
number=4, type=11, cpp_type=10, label=1,
|
||||
has_default_value=False, default_value=None,
|
||||
message_type=None, enum_type=None, containing_type=None,
|
||||
is_extension=False, extension_scope=None,
|
||||
|
@ -343,8 +381,8 @@ _PEDESTRIAN = _descriptor.Descriptor(
|
|||
extension_ranges=[],
|
||||
oneofs=[
|
||||
],
|
||||
serialized_start=539,
|
||||
serialized_end=662,
|
||||
serialized_start=644,
|
||||
serialized_end=772,
|
||||
)
|
||||
|
||||
|
||||
|
@ -382,8 +420,8 @@ _TRAFFICLIGHT = _descriptor.Descriptor(
|
|||
extension_ranges=[],
|
||||
oneofs=[
|
||||
],
|
||||
serialized_start=665,
|
||||
serialized_end=813,
|
||||
serialized_start=775,
|
||||
serialized_end=923,
|
||||
)
|
||||
|
||||
|
||||
|
@ -420,8 +458,8 @@ _SPEEDLIMITSIGN = _descriptor.Descriptor(
|
|||
extension_ranges=[],
|
||||
oneofs=[
|
||||
],
|
||||
serialized_start=815,
|
||||
serialized_end=896,
|
||||
serialized_start=925,
|
||||
serialized_end=1006,
|
||||
)
|
||||
|
||||
|
||||
|
@ -482,8 +520,8 @@ _AGENT = _descriptor.Descriptor(
|
|||
name='agent', full_name='carla_server.Agent.agent',
|
||||
index=0, containing_type=None, fields=[]),
|
||||
],
|
||||
serialized_start=899,
|
||||
serialized_end=1128,
|
||||
serialized_start=1009,
|
||||
serialized_end=1238,
|
||||
)
|
||||
|
||||
|
||||
|
@ -513,8 +551,8 @@ _REQUESTNEWEPISODE = _descriptor.Descriptor(
|
|||
extension_ranges=[],
|
||||
oneofs=[
|
||||
],
|
||||
serialized_start=1130,
|
||||
serialized_end=1167,
|
||||
serialized_start=1240,
|
||||
serialized_end=1277,
|
||||
)
|
||||
|
||||
|
||||
|
@ -551,8 +589,8 @@ _SCENEDESCRIPTION = _descriptor.Descriptor(
|
|||
extension_ranges=[],
|
||||
oneofs=[
|
||||
],
|
||||
serialized_start=1169,
|
||||
serialized_end=1279,
|
||||
serialized_start=1279,
|
||||
serialized_end=1389,
|
||||
)
|
||||
|
||||
|
||||
|
@ -582,8 +620,8 @@ _EPISODESTART = _descriptor.Descriptor(
|
|||
extension_ranges=[],
|
||||
oneofs=[
|
||||
],
|
||||
serialized_start=1281,
|
||||
serialized_end=1328,
|
||||
serialized_start=1391,
|
||||
serialized_end=1438,
|
||||
)
|
||||
|
||||
|
||||
|
@ -613,8 +651,8 @@ _EPISODEREADY = _descriptor.Descriptor(
|
|||
extension_ranges=[],
|
||||
oneofs=[
|
||||
],
|
||||
serialized_start=1330,
|
||||
serialized_end=1359,
|
||||
serialized_start=1440,
|
||||
serialized_end=1469,
|
||||
)
|
||||
|
||||
|
||||
|
@ -672,8 +710,8 @@ _CONTROL = _descriptor.Descriptor(
|
|||
extension_ranges=[],
|
||||
oneofs=[
|
||||
],
|
||||
serialized_start=1361,
|
||||
serialized_end=1455,
|
||||
serialized_start=1471,
|
||||
serialized_end=1565,
|
||||
)
|
||||
|
||||
|
||||
|
@ -692,8 +730,8 @@ _MEASUREMENTS_PLAYERMEASUREMENTS = _descriptor.Descriptor(
|
|||
is_extension=False, extension_scope=None,
|
||||
options=None),
|
||||
_descriptor.FieldDescriptor(
|
||||
name='box_extent', full_name='carla_server.Measurements.PlayerMeasurements.box_extent', index=1,
|
||||
number=11, type=11, cpp_type=10, label=1,
|
||||
name='bounding_box', full_name='carla_server.Measurements.PlayerMeasurements.bounding_box', index=1,
|
||||
number=12, type=11, cpp_type=10, label=1,
|
||||
has_default_value=False, default_value=None,
|
||||
message_type=None, enum_type=None, containing_type=None,
|
||||
is_extension=False, extension_scope=None,
|
||||
|
@ -766,8 +804,8 @@ _MEASUREMENTS_PLAYERMEASUREMENTS = _descriptor.Descriptor(
|
|||
extension_ranges=[],
|
||||
oneofs=[
|
||||
],
|
||||
serialized_start=1651,
|
||||
serialized_end=2024,
|
||||
serialized_start=1783,
|
||||
serialized_end=2161,
|
||||
)
|
||||
|
||||
_MEASUREMENTS = _descriptor.Descriptor(
|
||||
|
@ -778,28 +816,35 @@ _MEASUREMENTS = _descriptor.Descriptor(
|
|||
containing_type=None,
|
||||
fields=[
|
||||
_descriptor.FieldDescriptor(
|
||||
name='platform_timestamp', full_name='carla_server.Measurements.platform_timestamp', index=0,
|
||||
name='frame_number', full_name='carla_server.Measurements.frame_number', index=0,
|
||||
number=5, type=4, cpp_type=4, label=1,
|
||||
has_default_value=False, default_value=0,
|
||||
message_type=None, enum_type=None, containing_type=None,
|
||||
is_extension=False, extension_scope=None,
|
||||
options=None),
|
||||
_descriptor.FieldDescriptor(
|
||||
name='platform_timestamp', full_name='carla_server.Measurements.platform_timestamp', index=1,
|
||||
number=1, type=13, cpp_type=3, label=1,
|
||||
has_default_value=False, default_value=0,
|
||||
message_type=None, enum_type=None, containing_type=None,
|
||||
is_extension=False, extension_scope=None,
|
||||
options=None),
|
||||
_descriptor.FieldDescriptor(
|
||||
name='game_timestamp', full_name='carla_server.Measurements.game_timestamp', index=1,
|
||||
name='game_timestamp', full_name='carla_server.Measurements.game_timestamp', index=2,
|
||||
number=2, type=13, cpp_type=3, label=1,
|
||||
has_default_value=False, default_value=0,
|
||||
message_type=None, enum_type=None, containing_type=None,
|
||||
is_extension=False, extension_scope=None,
|
||||
options=None),
|
||||
_descriptor.FieldDescriptor(
|
||||
name='player_measurements', full_name='carla_server.Measurements.player_measurements', index=2,
|
||||
name='player_measurements', full_name='carla_server.Measurements.player_measurements', index=3,
|
||||
number=3, type=11, cpp_type=10, label=1,
|
||||
has_default_value=False, default_value=None,
|
||||
message_type=None, enum_type=None, containing_type=None,
|
||||
is_extension=False, extension_scope=None,
|
||||
options=None),
|
||||
_descriptor.FieldDescriptor(
|
||||
name='non_player_agents', full_name='carla_server.Measurements.non_player_agents', index=3,
|
||||
name='non_player_agents', full_name='carla_server.Measurements.non_player_agents', index=4,
|
||||
number=4, type=11, cpp_type=10, label=3,
|
||||
has_default_value=False, default_value=[],
|
||||
message_type=None, enum_type=None, containing_type=None,
|
||||
|
@ -817,19 +862,21 @@ _MEASUREMENTS = _descriptor.Descriptor(
|
|||
extension_ranges=[],
|
||||
oneofs=[
|
||||
],
|
||||
serialized_start=1458,
|
||||
serialized_end=2024,
|
||||
serialized_start=1568,
|
||||
serialized_end=2161,
|
||||
)
|
||||
|
||||
_TRANSFORM.fields_by_name['location'].message_type = _VECTOR3D
|
||||
_TRANSFORM.fields_by_name['orientation'].message_type = _VECTOR3D
|
||||
_TRANSFORM.fields_by_name['rotation'].message_type = _ROTATION3D
|
||||
_BOUNDINGBOX.fields_by_name['transform'].message_type = _TRANSFORM
|
||||
_BOUNDINGBOX.fields_by_name['extent'].message_type = _VECTOR3D
|
||||
_SENSOR.fields_by_name['type'].enum_type = _SENSOR_TYPE
|
||||
_SENSOR_TYPE.containing_type = _SENSOR
|
||||
_VEHICLE.fields_by_name['transform'].message_type = _TRANSFORM
|
||||
_VEHICLE.fields_by_name['box_extent'].message_type = _VECTOR3D
|
||||
_VEHICLE.fields_by_name['bounding_box'].message_type = _BOUNDINGBOX
|
||||
_PEDESTRIAN.fields_by_name['transform'].message_type = _TRANSFORM
|
||||
_PEDESTRIAN.fields_by_name['box_extent'].message_type = _VECTOR3D
|
||||
_PEDESTRIAN.fields_by_name['bounding_box'].message_type = _BOUNDINGBOX
|
||||
_TRAFFICLIGHT.fields_by_name['transform'].message_type = _TRANSFORM
|
||||
_TRAFFICLIGHT.fields_by_name['state'].enum_type = _TRAFFICLIGHT_STATE
|
||||
_TRAFFICLIGHT_STATE.containing_type = _TRAFFICLIGHT
|
||||
|
@ -853,7 +900,7 @@ _AGENT.fields_by_name['speed_limit_sign'].containing_oneof = _AGENT.oneofs_by_na
|
|||
_SCENEDESCRIPTION.fields_by_name['player_start_spots'].message_type = _TRANSFORM
|
||||
_SCENEDESCRIPTION.fields_by_name['sensors'].message_type = _SENSOR
|
||||
_MEASUREMENTS_PLAYERMEASUREMENTS.fields_by_name['transform'].message_type = _TRANSFORM
|
||||
_MEASUREMENTS_PLAYERMEASUREMENTS.fields_by_name['box_extent'].message_type = _VECTOR3D
|
||||
_MEASUREMENTS_PLAYERMEASUREMENTS.fields_by_name['bounding_box'].message_type = _BOUNDINGBOX
|
||||
_MEASUREMENTS_PLAYERMEASUREMENTS.fields_by_name['acceleration'].message_type = _VECTOR3D
|
||||
_MEASUREMENTS_PLAYERMEASUREMENTS.fields_by_name['autopilot_control'].message_type = _CONTROL
|
||||
_MEASUREMENTS_PLAYERMEASUREMENTS.containing_type = _MEASUREMENTS
|
||||
|
@ -862,6 +909,7 @@ _MEASUREMENTS.fields_by_name['non_player_agents'].message_type = _AGENT
|
|||
DESCRIPTOR.message_types_by_name['Vector3D'] = _VECTOR3D
|
||||
DESCRIPTOR.message_types_by_name['Rotation3D'] = _ROTATION3D
|
||||
DESCRIPTOR.message_types_by_name['Transform'] = _TRANSFORM
|
||||
DESCRIPTOR.message_types_by_name['BoundingBox'] = _BOUNDINGBOX
|
||||
DESCRIPTOR.message_types_by_name['Sensor'] = _SENSOR
|
||||
DESCRIPTOR.message_types_by_name['Vehicle'] = _VEHICLE
|
||||
DESCRIPTOR.message_types_by_name['Pedestrian'] = _PEDESTRIAN
|
||||
|
@ -897,6 +945,13 @@ Transform = _reflection.GeneratedProtocolMessageType('Transform', (_message.Mess
|
|||
))
|
||||
_sym_db.RegisterMessage(Transform)
|
||||
|
||||
BoundingBox = _reflection.GeneratedProtocolMessageType('BoundingBox', (_message.Message,), dict(
|
||||
DESCRIPTOR = _BOUNDINGBOX,
|
||||
__module__ = 'carla_server_pb2'
|
||||
# @@protoc_insertion_point(class_scope:carla_server.BoundingBox)
|
||||
))
|
||||
_sym_db.RegisterMessage(BoundingBox)
|
||||
|
||||
Sensor = _reflection.GeneratedProtocolMessageType('Sensor', (_message.Message,), dict(
|
||||
DESCRIPTOR = _SENSOR,
|
||||
__module__ = 'carla_server_pb2'
|
||||
|
|
|
@ -183,31 +183,36 @@ class CarlaClient(object):
|
|||
def _make_sensor_parsers(sensors):
|
||||
image_types = ['None', 'SceneFinal', 'Depth', 'SemanticSegmentation']
|
||||
getimgtype = lambda id: image_types[id] if len(image_types) > id else 'Unknown'
|
||||
getint = lambda data, index: struct.unpack('<L', data[index*4:index*4+4])[0]
|
||||
getint32 = lambda data, index: struct.unpack('<L', data[index*4:index*4+4])[0]
|
||||
getint64 = lambda data, index: struct.unpack('<Q', data[index*4:index*4+8])[0]
|
||||
getfloat = lambda data, index: struct.unpack('<f', data[index*4:index*4+4])[0]
|
||||
|
||||
def parse_image(data):
|
||||
width = getint(data, 0)
|
||||
height = getint(data, 1)
|
||||
image_type = getimgtype(getint(data, 2))
|
||||
fov = getfloat(data, 3)
|
||||
return sensor.Image(width, height, image_type, fov, data[16:])
|
||||
frame_number = getint64(data, 0)
|
||||
width = getint32(data, 2)
|
||||
height = getint32(data, 3)
|
||||
image_type = getimgtype(getint32(data, 4))
|
||||
fov = getfloat(data, 5)
|
||||
return sensor.Image(frame_number, width, height, image_type, fov, data[24:])
|
||||
|
||||
def parse_lidar(data):
|
||||
horizontal_angle = getfloat(data, 0)
|
||||
channels = getint(data, 1)
|
||||
frame_number = getint64(data, 0)
|
||||
horizontal_angle = getfloat(data, 2)
|
||||
channels = getint32(data, 3)
|
||||
header_size = 16
|
||||
point_count_by_channel = numpy.frombuffer(
|
||||
data[8:8+channels*4],
|
||||
data[header_size:header_size+channels*4],
|
||||
dtype=numpy.dtype('uint32'))
|
||||
points = numpy.frombuffer(
|
||||
data[8+channels*4:],
|
||||
data[header_size+channels*4:],
|
||||
dtype=numpy.dtype('f4'))
|
||||
points = numpy.reshape(points, (int(points.shape[0]/3), 3))
|
||||
return sensor.LidarMeasurement(
|
||||
frame_number,
|
||||
horizontal_angle,
|
||||
channels,
|
||||
point_count_by_channel,
|
||||
sensor.PointCloud(points))
|
||||
sensor.PointCloud(frame_number, points))
|
||||
|
||||
class SensorDefinition(object):
|
||||
def __init__(self, s):
|
||||
|
|
|
@ -154,6 +154,9 @@ def depth_to_local_point_cloud(image, color=None, max_depth=0.9):
|
|||
# [[X1,Y1,Z1,R1,G1,B1],[X2,Y2,Z2,R2,G2,B2], ... [Xn,Yn,Zn,Rn,Gn,Bn]]
|
||||
if color is not None:
|
||||
# numpy.concatenate((numpy.transpose(p3d), color), axis=1)
|
||||
return sensor.PointCloud(numpy.transpose(p3d), color_array=color)
|
||||
return sensor.PointCloud(
|
||||
image.frame_number,
|
||||
numpy.transpose(p3d),
|
||||
color_array=color)
|
||||
# [[X1,Y1,Z1],[X2,Y2,Z2], ... [Xn,Yn,Zn]]
|
||||
return sensor.PointCloud(numpy.transpose(p3d))
|
||||
return sensor.PointCloud(image.frame_number, numpy.transpose(p3d))
|
||||
|
|
|
@ -134,15 +134,18 @@ class Lidar(Sensor):
|
|||
# -- SensorData ----------------------------------------------------------------
|
||||
# ==============================================================================
|
||||
|
||||
|
||||
class SensorData(object):
|
||||
"""Base class for sensor data returned from the server."""
|
||||
pass
|
||||
def __init__(self, frame_number):
|
||||
self.frame_number = frame_number
|
||||
|
||||
|
||||
class Image(SensorData):
|
||||
"""Data generated by a Camera."""
|
||||
|
||||
def __init__(self, width, height, image_type, fov, raw_data):
|
||||
def __init__(self, frame_number, width, height, image_type, fov, raw_data):
|
||||
super(Image, self).__init__(frame_number=frame_number)
|
||||
assert len(raw_data) == 4 * width * height
|
||||
self.width = width
|
||||
self.height = height
|
||||
|
@ -195,7 +198,8 @@ class Image(SensorData):
|
|||
class PointCloud(SensorData):
|
||||
"""A list of points."""
|
||||
|
||||
def __init__(self, array, color_array=None):
|
||||
def __init__(self, frame_number, array, color_array=None):
|
||||
super(PointCloud, self).__init__(frame_number=frame_number)
|
||||
self._array = array
|
||||
self._color_array = color_array
|
||||
self._has_colors = color_array is not None
|
||||
|
@ -306,7 +310,8 @@ class PointCloud(SensorData):
|
|||
class LidarMeasurement(SensorData):
|
||||
"""Data generated by a Lidar."""
|
||||
|
||||
def __init__(self, horizontal_angle, channels, point_count_by_channel, point_cloud):
|
||||
def __init__(self, frame_number, horizontal_angle, channels, point_count_by_channel, point_cloud):
|
||||
super(LidarMeasurement, self).__init__(frame_number=frame_number)
|
||||
assert numpy.sum(point_count_by_channel) == len(point_cloud.array)
|
||||
self.horizontal_angle = horizontal_angle
|
||||
self.channels = channels
|
||||
|
|
13
README.md
13
README.md
|
@ -43,8 +43,6 @@ from the community. Our most immediate goals are:
|
|||
- [ ] Allowing for flexible and user-friendly import and editing of maps
|
||||
- [ ] Allowing the users to control non-player characters (and therefore set up user-specified scenarios)
|
||||
|
||||
We will post a detailed roadmap and contribution guidelines soon - stay tuned!
|
||||
|
||||
Paper
|
||||
-----
|
||||
|
||||
|
@ -101,13 +99,4 @@ CARLA specific code is distributed under MIT License.
|
|||
|
||||
CARLA specific assets are distributed under CC-BY License.
|
||||
|
||||
Note that UE4 itself and the UE4 free automotive materials follow their own
|
||||
license terms.
|
||||
|
||||
CARLA uses free automotive materials from Epic Games. For compiling CARLA, these
|
||||
materials must be downloaded from the UE4 marketplace and manually linked in
|
||||
CARLA following the instructions provided in the documentation.
|
||||
|
||||
CARLA uses pedestrians created with Adobe Fuse, which is a free tool for that
|
||||
purpose. Currently, we cannot redistribute these pedestrians models. They can
|
||||
only be used in the provided executable.
|
||||
Note that UE4 itself follows its own license terms.
|
||||
|
|
|
@ -8,7 +8,11 @@ rem FOR %%G IN (Binaries,Intermediate,Plugins\Carla\Binaries,Plugins\Carla\Inter
|
|||
|
||||
rem echo Making CarlaServer...
|
||||
rem call "C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\vcvarsall.bat" amd64
|
||||
rem Visual Studio 2017 Enterprise:
|
||||
rem call "C:\Program Files (x86)\Microsoft Visual Studio\2017\Enterprise\VC\Auxiliary\Build\vcvarsall.bat"
|
||||
rem START /wait cmd.exe /k "cd Plugins\Carla & make clean default & pause & exit"
|
||||
|
||||
|
||||
|
||||
rem echo Launch editor...
|
||||
rem start CarlaUE4.uproject
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
[Default]
|
||||
SunPolarAngle=44.586
|
||||
SunAzimuthAngle=0
|
||||
SunAzimuthAngle=-179
|
||||
SunBrightness=50
|
||||
SunDirectionalLightIntensity=15.092
|
||||
SunDirectionalLightColor=(R=255.000000,G=239.000000,B=194.000000,A=1.000000)
|
||||
|
@ -28,7 +28,7 @@ CameraPostProcessParameters.AutoExposureBias=-3.5
|
|||
|
||||
[ClearNoon]
|
||||
SunPolarAngle=44.586
|
||||
SunAzimuthAngle=0
|
||||
SunAzimuthAngle=-179
|
||||
SunBrightness=50
|
||||
SunDirectionalLightIntensity=15.092
|
||||
SunDirectionalLightColor=(R=255.000000,G=239.000000,B=194.000000,A=1.000000)
|
||||
|
@ -56,7 +56,7 @@ CameraPostProcessParameters.AutoExposureBias=-3.5
|
|||
|
||||
[CloudyNoon]
|
||||
SunPolarAngle=44.586
|
||||
SunAzimuthAngle=0
|
||||
SunAzimuthAngle=-179
|
||||
SunBrightness=0
|
||||
SunDirectionalLightIntensity=1.835
|
||||
SunDirectionalLightColor=(R=1.000000,G=0.862295,B=0.475000,A=1.000000)
|
||||
|
@ -84,7 +84,7 @@ CameraPostProcessParameters.AutoExposureBias=-3.5
|
|||
|
||||
[WetNoon]
|
||||
SunPolarAngle=44.586
|
||||
SunAzimuthAngle=0.0
|
||||
SunAzimuthAngle=-179
|
||||
SunBrightness=3.67
|
||||
SunDirectionalLightIntensity=20.184
|
||||
SunDirectionalLightColor=(R=1.000000,G=0.862295,B=0.475000,A=1.000000)
|
||||
|
@ -112,7 +112,7 @@ CameraPostProcessParameters.AutoExposureBias=-3.5
|
|||
|
||||
[WetCloudyNoon]
|
||||
SunPolarAngle=44.586
|
||||
SunAzimuthAngle=0
|
||||
SunAzimuthAngle=-179
|
||||
SunBrightness=0
|
||||
SunDirectionalLightIntensity=1.835
|
||||
SunDirectionalLightColor=(R=1.000000,G=0.862295,B=0.475000,A=1.000000)
|
||||
|
@ -140,7 +140,7 @@ CameraPostProcessParameters.AutoExposureBias=-3.5
|
|||
|
||||
[MidRainyNoon]
|
||||
SunPolarAngle=44.586
|
||||
SunAzimuthAngle=0
|
||||
SunAzimuthAngle=-179
|
||||
SunBrightness=0
|
||||
SunDirectionalLightIntensity=1.33
|
||||
SunDirectionalLightColor=(R=255.000000,G=239.000000,B=194.000000,A=1.000000)
|
||||
|
@ -168,7 +168,7 @@ CameraPostProcessParameters.AutoExposureBias=-3.5
|
|||
|
||||
[HardRainNoon]
|
||||
SunPolarAngle=44.586
|
||||
SunAzimuthAngle=0
|
||||
SunAzimuthAngle=-179
|
||||
SunBrightness=0
|
||||
SunDirectionalLightIntensity=1.33
|
||||
SunDirectionalLightColor=(R=255.000000,G=239.000000,B=194.000000,A=1.000000)
|
||||
|
@ -196,7 +196,7 @@ CameraPostProcessParameters.AutoExposureBias=-3.5
|
|||
|
||||
[SoftRainNoon]
|
||||
SunPolarAngle=44.586
|
||||
SunAzimuthAngle=0
|
||||
SunAzimuthAngle=-179
|
||||
SunBrightness=0
|
||||
SunDirectionalLightIntensity=1.33
|
||||
SunDirectionalLightColor=(R=255.000000,G=239.000000,B=194.000000,A=1.000000)
|
||||
|
@ -224,7 +224,7 @@ CameraPostProcessParameters.AutoExposureBias=-3.5
|
|||
|
||||
[ClearSunset]
|
||||
SunPolarAngle=86
|
||||
SunAzimuthAngle=0
|
||||
SunAzimuthAngle=-179
|
||||
SunBrightness=1.835
|
||||
SunDirectionalLightIntensity=50
|
||||
SunDirectionalLightColor=(R=0.810000,G=0.347470,B=0.170100,A=1.000000)
|
||||
|
@ -252,7 +252,7 @@ CameraPostProcessParameters.AutoExposureBias=-3.5
|
|||
|
||||
[CloudySunset]
|
||||
SunPolarAngle=86
|
||||
SunAzimuthAngle=0
|
||||
SunAzimuthAngle=-179
|
||||
SunBrightness=67.89
|
||||
SunDirectionalLightIntensity=6.422
|
||||
SunDirectionalLightColor=(R=0.810000,G=0.347162,B=0.083003,A=1.000000)
|
||||
|
@ -280,7 +280,7 @@ CameraPostProcessParameters.AutoExposureBias=-3.5
|
|||
|
||||
[WetSunset]
|
||||
SunPolarAngle=86
|
||||
SunAzimuthAngle=0
|
||||
SunAzimuthAngle=-179
|
||||
SunBrightness=0
|
||||
SunDirectionalLightIntensity=25.688
|
||||
SunDirectionalLightColor=(R=0.810000,G=0.347162,B=0.083003,A=1.000000)
|
||||
|
@ -308,7 +308,7 @@ CameraPostProcessParameters.AutoExposureBias=-3.5
|
|||
|
||||
[WetCloudySunset]
|
||||
SunPolarAngle=86
|
||||
SunAzimuthAngle=0
|
||||
SunAzimuthAngle=-179
|
||||
SunBrightness=67.89
|
||||
SunDirectionalLightIntensity=25.688
|
||||
SunDirectionalLightColor=(R=0.810000,G=0.347162,B=0.083003,A=1.000000)
|
||||
|
@ -336,7 +336,7 @@ WindAngle=0
|
|||
|
||||
[MidRainSunset]
|
||||
SunPolarAngle=86
|
||||
SunAzimuthAngle=0
|
||||
SunAzimuthAngle=-179
|
||||
SunBrightness=13.761
|
||||
SunDirectionalLightIntensity=12.587
|
||||
SunDirectionalLightColor=(R=0.810000,G=0.347162,B=0.083003,A=1.000000)
|
||||
|
@ -364,7 +364,7 @@ CameraPostProcessParameters.AutoExposureBias=-3.5
|
|||
|
||||
[HardRainSunset]
|
||||
SunPolarAngle=86
|
||||
SunAzimuthAngle=0
|
||||
SunAzimuthAngle=-179
|
||||
SunBrightness=13.761
|
||||
SunDirectionalLightIntensity=12.587
|
||||
SunDirectionalLightColor=(R=0.810000,G=0.347162,B=0.083003,A=1.000000)
|
||||
|
@ -392,7 +392,7 @@ CameraPostProcessParameters.AutoExposureBias=-3.5
|
|||
|
||||
[SoftRainSunset]
|
||||
SunPolarAngle=86
|
||||
SunAzimuthAngle=0
|
||||
SunAzimuthAngle=-179
|
||||
SunBrightness=13.761
|
||||
SunDirectionalLightIntensity=12.587
|
||||
SunDirectionalLightColor=(R=0.810000,G=0.347162,B=0.083003,A=1.000000)
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
[Default]
|
||||
SunPolarAngle=44.586
|
||||
SunAzimuthAngle=0
|
||||
SunAzimuthAngle=174
|
||||
SunBrightness=50
|
||||
SunDirectionalLightIntensity=15.092
|
||||
SunDirectionalLightColor=(R=255.000000,G=239.000000,B=194.000000,A=1.000000)
|
||||
|
@ -28,7 +28,7 @@ CameraPostProcessParameters.AutoExposureBias=-3.5
|
|||
|
||||
[ClearNoon]
|
||||
SunPolarAngle=44.586
|
||||
SunAzimuthAngle=0
|
||||
SunAzimuthAngle=174
|
||||
SunBrightness=50
|
||||
SunDirectionalLightIntensity=34.286
|
||||
SunDirectionalLightColor=(R=255.000000,G=239.000000,B=194.000000,A=1.000000)
|
||||
|
@ -56,7 +56,7 @@ CameraPostProcessParameters.AutoExposureBias=-3.5
|
|||
|
||||
[CloudyNoon]
|
||||
SunPolarAngle=44.586
|
||||
SunAzimuthAngle=0.0
|
||||
SunAzimuthAngle=174
|
||||
SunBrightness=0
|
||||
SunDirectionalLightIntensity=1.835
|
||||
SunDirectionalLightColor=(R=1.000000,G=0.862295,B=0.475000,A=1.000000)
|
||||
|
@ -84,7 +84,7 @@ CameraPostProcessParameters.AutoExposureBias=-3.5
|
|||
|
||||
[WetNoon]
|
||||
SunPolarAngle=44.586
|
||||
SunAzimuthAngle=0.0
|
||||
SunAzimuthAngle=174
|
||||
SunBrightness=3.67
|
||||
SunDirectionalLightIntensity=20.184
|
||||
SunDirectionalLightColor=(R=1.000000,G=0.862295,B=0.475000,A=1.000000)
|
||||
|
@ -112,7 +112,7 @@ CameraPostProcessParameters.AutoExposureBias=-3.5
|
|||
|
||||
[WetCloudyNoon]
|
||||
SunPolarAngle=44.586
|
||||
SunAzimuthAngle=0.0
|
||||
SunAzimuthAngle=174
|
||||
SunBrightness=0
|
||||
SunDirectionalLightIntensity=1.835
|
||||
SunDirectionalLightColor=(R=1.000000,G=0.862295,B=0.475000,A=1.000000)
|
||||
|
@ -140,7 +140,7 @@ CameraPostProcessParameters.AutoExposureBias=-3.5
|
|||
|
||||
[MidRainyNoon]
|
||||
SunPolarAngle=44.586
|
||||
SunAzimuthAngle=0.0
|
||||
SunAzimuthAngle=174
|
||||
SunBrightness=0
|
||||
SunDirectionalLightIntensity=1.33
|
||||
SunDirectionalLightColor=(R=255.000000,G=239.000000,B=194.000000,A=1.000000)
|
||||
|
@ -168,7 +168,7 @@ CameraPostProcessParameters.AutoExposureBias=-3.5
|
|||
|
||||
[HardRainNoon]
|
||||
SunPolarAngle=44.586
|
||||
SunAzimuthAngle=0.0
|
||||
SunAzimuthAngle=174
|
||||
SunBrightness=0
|
||||
SunDirectionalLightIntensity=1.33
|
||||
SunDirectionalLightColor=(R=255.000000,G=239.000000,B=194.000000,A=1.000000)
|
||||
|
@ -196,7 +196,7 @@ CameraPostProcessParameters.AutoExposureBias=-3.5
|
|||
|
||||
[SoftRainNoon]
|
||||
SunPolarAngle=44.586
|
||||
SunAzimuthAngle=0
|
||||
SunAzimuthAngle=174
|
||||
SunBrightness=0
|
||||
SunDirectionalLightIntensity=1.33
|
||||
SunDirectionalLightColor=(R=255.000000,G=239.000000,B=194.000000,A=1.000000)
|
||||
|
@ -224,7 +224,7 @@ CameraPostProcessParameters.AutoExposureBias=-3.5
|
|||
|
||||
[ClearSunset]
|
||||
SunPolarAngle=86
|
||||
SunAzimuthAngle=0
|
||||
SunAzimuthAngle=174
|
||||
SunBrightness=1.835
|
||||
SunDirectionalLightIntensity=50
|
||||
SunDirectionalLightColor=(R=0.810000,G=0.347470,B=0.170100,A=1.000000)
|
||||
|
@ -252,7 +252,7 @@ CameraPostProcessParameters.AutoExposureBias=-3.5
|
|||
|
||||
[CloudySunset]
|
||||
SunPolarAngle=86
|
||||
SunAzimuthAngle=0
|
||||
SunAzimuthAngle=174
|
||||
SunBrightness=67.89
|
||||
SunDirectionalLightIntensity=6.422
|
||||
SunDirectionalLightColor=(R=0.810000,G=0.347162,B=0.083003,A=1.000000)
|
||||
|
@ -280,7 +280,7 @@ CameraPostProcessParameters.AutoExposureBias=-3.5
|
|||
|
||||
[WetSunset]
|
||||
SunPolarAngle=86
|
||||
SunAzimuthAngle=0.0
|
||||
SunAzimuthAngle=174
|
||||
SunBrightness=0
|
||||
SunDirectionalLightIntensity=25.688
|
||||
SunDirectionalLightColor=(R=0.810000,G=0.347162,B=0.083003,A=1.000000)
|
||||
|
@ -308,7 +308,7 @@ CameraPostProcessParameters.AutoExposureBias=-3.5
|
|||
|
||||
[WetCloudySunset]
|
||||
SunPolarAngle=86
|
||||
SunAzimuthAngle=0.0
|
||||
SunAzimuthAngle=174
|
||||
SunBrightness=67.89
|
||||
SunDirectionalLightIntensity=25.688
|
||||
SunDirectionalLightColor=(R=0.810000,G=0.347162,B=0.083003,A=1.000000)
|
||||
|
@ -333,7 +333,7 @@ CameraPostProcessParameters.AutoExposureBias=-3.5
|
|||
|
||||
[MidRainSunset]
|
||||
SunPolarAngle=86
|
||||
SunAzimuthAngle=0
|
||||
SunAzimuthAngle=174
|
||||
SunBrightness=12.381
|
||||
SunDirectionalLightIntensity=5.714
|
||||
SunDirectionalLightColor=(R=0.810000,G=0.347162,B=0.083003,A=1.000000)
|
||||
|
@ -361,7 +361,7 @@ CameraPostProcessParameters.AutoExposureBias=-3.5
|
|||
|
||||
[HardRainSunset]
|
||||
SunPolarAngle=86
|
||||
SunAzimuthAngle=0
|
||||
SunAzimuthAngle=174
|
||||
SunBrightness=0.952
|
||||
SunDirectionalLightIntensity=3.063
|
||||
SunDirectionalLightColor=(R=0.810000,G=0.347162,B=0.083003,A=1.000000)
|
||||
|
@ -389,7 +389,7 @@ CameraPostProcessParameters.AutoExposureBias=-3.5
|
|||
|
||||
[SoftRainSunset]
|
||||
SunPolarAngle=86
|
||||
SunAzimuthAngle=0
|
||||
SunAzimuthAngle=174
|
||||
SunBrightness=13.761
|
||||
SunDirectionalLightIntensity=12.587
|
||||
SunDirectionalLightColor=(R=0.810000,G=0.347162,B=0.083003,A=1.000000)
|
||||
|
|
|
@ -77,3 +77,5 @@ InitialAverageFrameRate=0.016667
|
|||
PhysXTreeRebuildRate=10
|
||||
|
||||
|
||||
[/Script/AIModule.CrowdManager]
|
||||
MaxAgents=1000
|
|
@ -16,7 +16,7 @@
|
|||
"Modules": [
|
||||
{
|
||||
"Name": "Carla",
|
||||
"Type": "Developer",
|
||||
"Type": "Runtime",
|
||||
"LoadingPhase": "PreDefault",
|
||||
"AdditionalDependencies": [
|
||||
"Engine"
|
||||
|
|
|
@ -8,14 +8,16 @@
|
|||
|
||||
#include "Carla.h"
|
||||
#include "AgentComponent.h"
|
||||
|
||||
#include "Engine/World.h"
|
||||
#include "Game/CarlaGameModeBase.h"
|
||||
#include "Game/DataRouter.h"
|
||||
#include "Engine/Engine.h"
|
||||
#include "Kismet/GameplayStatics.h"
|
||||
|
||||
static FDataRouter &GetDataRouter(UWorld *World)
|
||||
{
|
||||
check(World != nullptr);
|
||||
auto *GameMode = Cast<ACarlaGameModeBase>(World->GetAuthGameMode());
|
||||
ACarlaGameModeBase *GameMode = Cast<ACarlaGameModeBase>(World->GetAuthGameMode());
|
||||
check(GameMode != nullptr);
|
||||
return GameMode->GetDataRouter();
|
||||
}
|
||||
|
@ -40,7 +42,20 @@ void UAgentComponent::BeginPlay()
|
|||
|
||||
if (bRegisterAgentComponent)
|
||||
{
|
||||
GetDataRouter(GetWorld()).RegisterAgent(this);
|
||||
/**
|
||||
* This only returns true if the current game mode is not null
|
||||
* because you can only access a game mode if you are the host
|
||||
* @param oftheworld UWorld is needed to access the game mode
|
||||
* @return true if there is a game mode and it is not null
|
||||
*/
|
||||
if(UGameplayStatics::GetGameMode(GetWorld())!=nullptr)
|
||||
{
|
||||
GetDataRouter(GetWorld()).RegisterAgent(this);
|
||||
} else
|
||||
{
|
||||
UCarlaGameInstance* GameInstance = Cast<UCarlaGameInstance>(UGameplayStatics::GetGameInstance(GetWorld()));
|
||||
if(GameInstance) GameInstance->GetDataRouter().RegisterAgent(this);
|
||||
}
|
||||
bAgentComponentIsRegistered = true;
|
||||
}
|
||||
}
|
||||
|
@ -49,9 +64,19 @@ void UAgentComponent::EndPlay(const EEndPlayReason::Type EndPlayReason)
|
|||
{
|
||||
if (bAgentComponentIsRegistered)
|
||||
{
|
||||
GetDataRouter(GetWorld()).DeregisterAgent(this);
|
||||
if(UGameplayStatics::GetGameMode(GetWorld())!=nullptr)
|
||||
{
|
||||
GetDataRouter(GetWorld()).DeregisterAgent(this);
|
||||
}
|
||||
else
|
||||
{
|
||||
UCarlaGameInstance* GameInstance = Cast<UCarlaGameInstance>(UGameplayStatics::GetGameInstance(GetWorld()));
|
||||
if(GameInstance)
|
||||
GameInstance->GetDataRouter().DeregisterAgent(this);
|
||||
}
|
||||
bAgentComponentIsRegistered = false;
|
||||
}
|
||||
|
||||
Super::EndPlay(EndPlayReason);
|
||||
}
|
||||
|
||||
|
|
|
@ -9,11 +9,9 @@
|
|||
#include "Carla.h"
|
||||
#include "VehicleAgentComponent.h"
|
||||
|
||||
#include "Vehicle/CarlaWheeledVehicle.h"
|
||||
|
||||
static bool IsPlayer(const ACarlaWheeledVehicle &Vehicle)
|
||||
static bool IsPlayer(const ACarlaWheeledVehicle &InVehicle)
|
||||
{
|
||||
auto *Controller = Cast<AWheeledVehicleAIController>(Vehicle.GetController());
|
||||
auto *Controller = Cast<AWheeledVehicleAIController>(InVehicle.GetController());
|
||||
return (Controller != nullptr) && Controller->IsPossessingThePlayer();
|
||||
}
|
||||
|
||||
|
@ -22,11 +20,11 @@ UVehicleAgentComponent::UVehicleAgentComponent(const FObjectInitializer &ObjectI
|
|||
|
||||
void UVehicleAgentComponent::BeginPlay()
|
||||
{
|
||||
WheeledVehicle = Cast<ACarlaWheeledVehicle>(GetOwner());
|
||||
checkf(WheeledVehicle != nullptr, TEXT("UVehicleAgentComponent can only be attached to ACarlaWheeledVehicle"));
|
||||
Vehicle = Cast<ACarlaWheeledVehicle>(GetOwner());
|
||||
checkf(Vehicle != nullptr, TEXT("UVehicleAgentComponent can only be attached to ACarlaWheeledVehicle"));
|
||||
|
||||
// We only want to register non-player agents.
|
||||
bRegisterAgentComponent = !IsPlayer(*WheeledVehicle);
|
||||
bRegisterAgentComponent = !IsPlayer(*Vehicle);
|
||||
|
||||
Super::BeginPlay();
|
||||
}
|
||||
|
|
|
@ -8,9 +8,9 @@
|
|||
|
||||
#include "Agent/AgentComponent.h"
|
||||
|
||||
#include "VehicleAgentComponent.generated.h"
|
||||
#include "Vehicle/CarlaWheeledVehicle.h"
|
||||
|
||||
class ACarlaWheeledVehicle;
|
||||
#include "VehicleAgentComponent.generated.h"
|
||||
|
||||
UCLASS(ClassGroup=(Custom), meta=(BlueprintSpawnableComponent))
|
||||
class CARLA_API UVehicleAgentComponent : public UAgentComponent
|
||||
|
@ -21,10 +21,25 @@ public:
|
|||
|
||||
UVehicleAgentComponent(const FObjectInitializer &ObjectInitializer);
|
||||
|
||||
ACarlaWheeledVehicle &GetVehicle() const
|
||||
/// Return forward speed in cm/s.
|
||||
float GetForwardSpeed() const
|
||||
{
|
||||
check(WheeledVehicle != nullptr);
|
||||
return *WheeledVehicle;
|
||||
return Vehicle->GetVehicleForwardSpeed();
|
||||
}
|
||||
|
||||
FTransform GetTransform() const
|
||||
{
|
||||
return Vehicle->GetVehicleTransform();
|
||||
}
|
||||
|
||||
FTransform GetBoundingBoxTransform() const
|
||||
{
|
||||
return Vehicle->GetVehicleBoundingBoxTransform();
|
||||
}
|
||||
|
||||
FVector GetBoundingBoxExtent() const
|
||||
{
|
||||
return Vehicle->GetVehicleBoundingBoxExtent();
|
||||
}
|
||||
|
||||
protected:
|
||||
|
@ -38,5 +53,6 @@ protected:
|
|||
|
||||
private:
|
||||
|
||||
ACarlaWheeledVehicle *WheeledVehicle = nullptr;
|
||||
UPROPERTY()
|
||||
ACarlaWheeledVehicle *Vehicle = nullptr;
|
||||
};
|
||||
|
|
|
@ -9,17 +9,9 @@
|
|||
#include "Carla.h"
|
||||
#include "WalkerAgentComponent.h"
|
||||
|
||||
#include "GameFramework/Character.h"
|
||||
|
||||
UWalkerAgentComponent::UWalkerAgentComponent(const FObjectInitializer &ObjectInitializer)
|
||||
: Super(ObjectInitializer) {}
|
||||
|
||||
float UWalkerAgentComponent::GetForwardSpeed() const
|
||||
{
|
||||
/// @todo Is it necessary to compute this speed every tick?
|
||||
return FVector::DotProduct(Walker->GetVelocity(), Walker->GetActorRotation().Vector());
|
||||
}
|
||||
|
||||
void UWalkerAgentComponent::BeginPlay()
|
||||
{
|
||||
Walker = Cast<ACharacter>(GetOwner());
|
||||
|
|
|
@ -8,9 +8,9 @@
|
|||
|
||||
#include "Agent/AgentComponent.h"
|
||||
|
||||
#include "WalkerAgentComponent.generated.h"
|
||||
#include "GameFramework/Character.h"
|
||||
|
||||
class ACharacter;
|
||||
#include "WalkerAgentComponent.generated.h"
|
||||
|
||||
/// This component can be added to any ACharacter to be added as agent.
|
||||
/// See UAgentComponent.
|
||||
|
@ -24,7 +24,20 @@ public:
|
|||
UWalkerAgentComponent(const FObjectInitializer &ObjectInitializer);
|
||||
|
||||
/// Return forward speed in cm/s.
|
||||
float GetForwardSpeed() const;
|
||||
float GetForwardSpeed() const
|
||||
{
|
||||
return FVector::DotProduct(Walker->GetVelocity(), Walker->GetActorRotation().Vector());
|
||||
}
|
||||
|
||||
FTransform GetTransform() const
|
||||
{
|
||||
return Walker->GetActorTransform();
|
||||
}
|
||||
|
||||
FTransform GetBoundingBoxTransform() const
|
||||
{
|
||||
return FTransform();
|
||||
}
|
||||
|
||||
FVector GetBoundingBoxExtent() const
|
||||
{
|
||||
|
|
|
@ -202,7 +202,7 @@ void ACarlaGameModeBase::BeginPlay()
|
|||
void ACarlaGameModeBase::EndPlay(const EEndPlayReason::Type EndPlayReason)
|
||||
{
|
||||
Super::EndPlay(EndPlayReason);
|
||||
if (CarlaSettingsDelegate != nullptr)
|
||||
if (CarlaSettingsDelegate != nullptr && EndPlayReason!=EEndPlayReason::EndPlayInEditor)
|
||||
{
|
||||
CarlaSettingsDelegate->Reset();
|
||||
}
|
||||
|
|
|
@ -7,6 +7,8 @@
|
|||
#include "Carla.h"
|
||||
#include "CarlaPlayerState.h"
|
||||
|
||||
#include "CoreGlobals.h"
|
||||
|
||||
void ACarlaPlayerState::Reset()
|
||||
{
|
||||
Super::Reset();
|
||||
|
@ -25,6 +27,7 @@ void ACarlaPlayerState::CopyProperties(APlayerState *PlayerState)
|
|||
ACarlaPlayerState *Other = Cast<ACarlaPlayerState>(PlayerState);
|
||||
if (Other != nullptr)
|
||||
{
|
||||
FrameNumber = Other->FrameNumber;
|
||||
FramesPerSecond = Other->FramesPerSecond;
|
||||
PlatformTimeStamp = Other->PlatformTimeStamp;
|
||||
GameTimeStamp = Other->GameTimeStamp;
|
||||
|
@ -74,6 +77,7 @@ static int32 RoundToMilliseconds(float Seconds)
|
|||
|
||||
void ACarlaPlayerState::UpdateTimeStamp(float DeltaSeconds)
|
||||
{
|
||||
FrameNumber = GFrameCounter;
|
||||
FramesPerSecond = 1.0f / DeltaSeconds;
|
||||
PlatformTimeStamp = RoundToMilliseconds(FPlatformTime::Seconds());
|
||||
GameTimeStamp += RoundToMilliseconds(DeltaSeconds);
|
||||
|
|
|
@ -40,6 +40,11 @@ public:
|
|||
// ===========================================================================
|
||||
/// @{
|
||||
|
||||
uint64 GetFrameNumber() const
|
||||
{
|
||||
return FrameNumber;
|
||||
}
|
||||
|
||||
UFUNCTION(BlueprintCallable)
|
||||
float GetFramesPerSecond() const
|
||||
{
|
||||
|
@ -83,9 +88,15 @@ public:
|
|||
}
|
||||
|
||||
UFUNCTION(BlueprintCallable)
|
||||
FVector GetBoundsExtent() const
|
||||
FTransform GetBoundingBoxTransform() const
|
||||
{
|
||||
return BoundsExtent;
|
||||
return BoundingBoxTransform;
|
||||
}
|
||||
|
||||
UFUNCTION(BlueprintCallable)
|
||||
FVector GetBoundingBoxExtent() const
|
||||
{
|
||||
return BoundingBoxExtent;
|
||||
}
|
||||
|
||||
UFUNCTION(BlueprintCallable)
|
||||
|
@ -214,6 +225,9 @@ private:
|
|||
// If you add another variable here, don't forget to copy it inside
|
||||
// CopyProperties if necessary.
|
||||
|
||||
UPROPERTY(VisibleAnywhere)
|
||||
uint64 FrameNumber;
|
||||
|
||||
UPROPERTY(VisibleAnywhere)
|
||||
float FramesPerSecond;
|
||||
|
||||
|
@ -227,7 +241,10 @@ private:
|
|||
FTransform Transform;
|
||||
|
||||
UPROPERTY(VisibleAnywhere)
|
||||
FVector BoundsExtent;
|
||||
FTransform BoundingBoxTransform;
|
||||
|
||||
UPROPERTY(VisibleAnywhere)
|
||||
FVector BoundingBoxExtent;
|
||||
|
||||
UPROPERTY(VisibleAnywhere)
|
||||
float ForwardSpeed = 0.0f;
|
||||
|
|
|
@ -94,6 +94,7 @@ void ALidar::ReadPoints(const float DeltaTime)
|
|||
}
|
||||
|
||||
const float HorizontalAngle = std::fmod(CurrentHorizontalAngle + AngleDistanceOfTick, 360.0f);
|
||||
LidarMeasurement.SetFrameNumber(GFrameCounter);
|
||||
LidarMeasurement.SetHorizontalAngle(HorizontalAngle);
|
||||
}
|
||||
|
||||
|
|
|
@ -15,6 +15,7 @@
|
|||
/// The header consists of an array of uint32's in the following layout
|
||||
///
|
||||
/// {
|
||||
/// Frame number (uint64)
|
||||
/// Horizontal angle (float),
|
||||
/// Channel count,
|
||||
/// Point count of channel 0,
|
||||
|
@ -37,8 +38,8 @@ public:
|
|||
explicit FLidarMeasurement(uint32 SensorId = 0u, uint32 ChannelCount = 0u)
|
||||
: SensorId(SensorId)
|
||||
{
|
||||
Header.AddDefaulted(2u + ChannelCount);
|
||||
Header[1] = ChannelCount;
|
||||
Header.AddDefaulted(4u + ChannelCount);
|
||||
Header[3] = ChannelCount;
|
||||
}
|
||||
|
||||
FLidarMeasurement &operator=(FLidarMeasurement &&Other)
|
||||
|
@ -50,31 +51,36 @@ public:
|
|||
return *this;
|
||||
}
|
||||
|
||||
void SetFrameNumber(uint64 FrameNumber)
|
||||
{
|
||||
std::memcpy(Header.GetData(), reinterpret_cast<const void *>(&FrameNumber), 2u);
|
||||
}
|
||||
|
||||
float GetHorizontalAngle() const
|
||||
{
|
||||
return reinterpret_cast<const float &>(Header[0]);
|
||||
return reinterpret_cast<const float &>(Header[2]);
|
||||
}
|
||||
|
||||
void SetHorizontalAngle(float HorizontalAngle)
|
||||
{
|
||||
Header[0] = reinterpret_cast<const uint32 &>(HorizontalAngle);
|
||||
Header[2] = reinterpret_cast<const uint32 &>(HorizontalAngle);
|
||||
}
|
||||
|
||||
uint32 GetChannelCount() const
|
||||
{
|
||||
return Header[1];
|
||||
return Header[3];
|
||||
}
|
||||
|
||||
void Reset(uint32 TotalPointCount)
|
||||
{
|
||||
std::memset(Header.GetData() + 2u, 0, sizeof(uint32) * GetChannelCount());
|
||||
std::memset(Header.GetData() + 4u, 0, sizeof(uint32) * GetChannelCount());
|
||||
Points.Reset(3u * TotalPointCount);
|
||||
}
|
||||
|
||||
void WritePoint(uint32 Channel, const FVector &Point)
|
||||
{
|
||||
check(Header[1] > Channel);
|
||||
Header[2u + Channel] += 1u;
|
||||
check(Header[3] > Channel);
|
||||
Header[4u + Channel] += 1u;
|
||||
constexpr float TO_METERS = 1e-2f;
|
||||
Points.Emplace(TO_METERS * Point.X);
|
||||
Points.Emplace(TO_METERS * Point.Y);
|
||||
|
|
|
@ -8,41 +8,68 @@
|
|||
#include "SceneCaptureCamera.h"
|
||||
|
||||
#include "Sensor/SensorDataView.h"
|
||||
#include "Settings/CarlaSettings.h"
|
||||
|
||||
#include "Components/DrawFrustumComponent.h"
|
||||
#include "Components/SceneCaptureComponent2D.h"
|
||||
#include "Components/StaticMeshComponent.h"
|
||||
#include "ConstructorHelpers.h"
|
||||
#include "CoreGlobals.h"
|
||||
#include "Engine/CollisionProfile.h"
|
||||
#include "Engine/TextureRenderTarget2D.h"
|
||||
#include "HighResScreenshot.h"
|
||||
#include "Game/CarlaGameInstance.h"
|
||||
#include "Kismet/KismetSystemLibrary.h"
|
||||
#include "Materials/Material.h"
|
||||
#include "Paths.h"
|
||||
|
||||
#include <memory>
|
||||
|
||||
// =============================================================================
|
||||
// -- Local static variables ---------------------------------------------------
|
||||
// =============================================================================
|
||||
|
||||
static constexpr auto DEPTH_MAT_PATH =
|
||||
#if PLATFORM_LINUX
|
||||
TEXT("Material'/Carla/PostProcessingMaterials/DepthEffectMaterial_GLSL.DepthEffectMaterial_GLSL'");
|
||||
TEXT("Material'/Carla/PostProcessingMaterials/DepthEffectMaterial_GLSL.DepthEffectMaterial_GLSL'");
|
||||
#elif PLATFORM_WINDOWS
|
||||
TEXT("Material'/Carla/PostProcessingMaterials/DepthEffectMaterial.DepthEffectMaterial'");
|
||||
TEXT("Material'/Carla/PostProcessingMaterials/DepthEffectMaterial.DepthEffectMaterial'");
|
||||
#else
|
||||
# error No depth material defined for this platform
|
||||
#endif
|
||||
|
||||
static constexpr auto SEMANTIC_SEGMENTATION_MAT_PATH =
|
||||
TEXT("Material'/Carla/PostProcessingMaterials/GTMaterial.GTMaterial'");
|
||||
TEXT("Material'/Carla/PostProcessingMaterials/GTMaterial.GTMaterial'");
|
||||
|
||||
// =============================================================================
|
||||
// -- Local static methods and types -------------------------------------------
|
||||
// =============================================================================
|
||||
|
||||
struct FImageHeaderData
|
||||
{
|
||||
uint64 FrameNumber;
|
||||
uint32 Width;
|
||||
uint32 Height;
|
||||
uint32 Type;
|
||||
float FOV;
|
||||
};
|
||||
|
||||
static void RemoveShowFlags(FEngineShowFlags &ShowFlags);
|
||||
|
||||
ASceneCaptureCamera::ASceneCaptureCamera(const FObjectInitializer& ObjectInitializer) :
|
||||
Super(ObjectInitializer),
|
||||
SizeX(720u),
|
||||
SizeY(512u),
|
||||
PostProcessEffect(EPostProcessEffect::SceneFinal)
|
||||
// =============================================================================
|
||||
// -- ASceneCaptureCamera ------------------------------------------------------
|
||||
// =============================================================================
|
||||
|
||||
uint32 ASceneCaptureCamera::NumSceneCapture = 0;
|
||||
|
||||
ASceneCaptureCamera::ASceneCaptureCamera(const FObjectInitializer &ObjectInitializer)
|
||||
: Super(ObjectInitializer),
|
||||
SizeX(720u),
|
||||
SizeY(512u),
|
||||
PostProcessEffect(EPostProcessEffect::SceneFinal)
|
||||
{
|
||||
PrimaryActorTick.bCanEverTick = true;
|
||||
PrimaryActorTick.TickGroup = TG_PrePhysics;
|
||||
|
||||
MeshComp = CreateDefaultSubobject<UStaticMeshComponent>(TEXT("CamMesh0"));
|
||||
MeshComp = CreateDefaultSubobject<UStaticMeshComponent>(TEXT("CamMesh"));
|
||||
|
||||
MeshComp->SetCollisionProfileName(UCollisionProfile::NoCollision_ProfileName);
|
||||
|
||||
|
@ -51,28 +78,34 @@ ASceneCaptureCamera::ASceneCaptureCamera(const FObjectInitializer& ObjectInitial
|
|||
MeshComp->PostPhysicsComponentTick.bCanEverTick = false;
|
||||
RootComponent = MeshComp;
|
||||
|
||||
DrawFrustum = CreateDefaultSubobject<UDrawFrustumComponent>(TEXT("DrawFrust0"));
|
||||
DrawFrustum = CreateDefaultSubobject<UDrawFrustumComponent>(TEXT("DrawFrust"));
|
||||
DrawFrustum->bIsEditorOnly = true;
|
||||
DrawFrustum->SetupAttachment(MeshComp);
|
||||
|
||||
CaptureRenderTarget = CreateDefaultSubobject<UTextureRenderTarget2D>(TEXT("CaptureRenderTarget0"));
|
||||
#if WITH_EDITORONLY_DATA
|
||||
CaptureRenderTarget->CompressionNoAlpha = true;
|
||||
CaptureRenderTarget->MipGenSettings = TextureMipGenSettings::TMGS_NoMipmaps;
|
||||
#endif
|
||||
CaptureRenderTarget = CreateDefaultSubobject<UTextureRenderTarget2D>(
|
||||
FName(*FString::Printf(TEXT("CaptureRenderTarget%d"), NumSceneCapture)));
|
||||
#if WITH_EDITORONLY_DATA
|
||||
CaptureRenderTarget->CompressionNoAlpha = true;
|
||||
CaptureRenderTarget->MipGenSettings = TextureMipGenSettings::TMGS_NoMipmaps;
|
||||
CaptureRenderTarget->bUseLegacyGamma = false;
|
||||
#endif
|
||||
CaptureRenderTarget->CompressionSettings = TextureCompressionSettings::TC_Default;
|
||||
CaptureRenderTarget->SRGB=0;
|
||||
CaptureRenderTarget->SRGB = false;
|
||||
CaptureRenderTarget->bAutoGenerateMips = false;
|
||||
CaptureRenderTarget->AddressX = TextureAddress::TA_Clamp;
|
||||
CaptureRenderTarget->AddressY = TextureAddress::TA_Clamp;
|
||||
CaptureComponent2D = CreateDefaultSubobject<USceneCaptureComponent2D>(TEXT("SceneCaptureComponent2D"));
|
||||
CaptureComponent2D = CreateDefaultSubobject<USceneCaptureComponent2D>(
|
||||
TEXT("SceneCaptureComponent2D"));
|
||||
CaptureComponent2D->SetupAttachment(MeshComp);
|
||||
|
||||
// Load post-processing materials.
|
||||
static ConstructorHelpers::FObjectFinder<UMaterial> DEPTH(DEPTH_MAT_PATH);
|
||||
static ConstructorHelpers::FObjectFinder<UMaterial> DEPTH(
|
||||
DEPTH_MAT_PATH);
|
||||
PostProcessDepth = DEPTH.Object;
|
||||
static ConstructorHelpers::FObjectFinder<UMaterial> SEMANTIC_SEGMENTATION(SEMANTIC_SEGMENTATION_MAT_PATH);
|
||||
static ConstructorHelpers::FObjectFinder<UMaterial> SEMANTIC_SEGMENTATION(
|
||||
SEMANTIC_SEGMENTATION_MAT_PATH);
|
||||
PostProcessSemanticSegmentation = SEMANTIC_SEGMENTATION.Object;
|
||||
NumSceneCapture++;
|
||||
}
|
||||
|
||||
void ASceneCaptureCamera::PostActorCreated()
|
||||
|
@ -81,18 +114,23 @@ void ASceneCaptureCamera::PostActorCreated()
|
|||
|
||||
// no need load the editor mesh when there is no editor
|
||||
#if WITH_EDITOR
|
||||
if(MeshComp)
|
||||
if (MeshComp)
|
||||
{
|
||||
if (!IsRunningCommandlet())
|
||||
{
|
||||
if( !MeshComp->GetStaticMesh())
|
||||
if (!MeshComp->GetStaticMesh())
|
||||
{
|
||||
UStaticMesh* CamMesh = LoadObject<UStaticMesh>(NULL, TEXT("/Engine/EditorMeshes/MatineeCam_SM.MatineeCam_SM"), NULL, LOAD_None, NULL);
|
||||
UStaticMesh *CamMesh = LoadObject<UStaticMesh>(
|
||||
NULL,
|
||||
TEXT("/Engine/EditorMeshes/MatineeCam_SM.MatineeCam_SM"),
|
||||
NULL,
|
||||
LOAD_None,
|
||||
NULL);
|
||||
MeshComp->SetStaticMesh(CamMesh);
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif // WITH_EDITOR
|
||||
#endif // WITH_EDITOR
|
||||
|
||||
// Sync component with CameraActor frustum settings.
|
||||
UpdateDrawFrustum();
|
||||
|
@ -105,49 +143,104 @@ void ASceneCaptureCamera::BeginPlay()
|
|||
// Setup render target.
|
||||
const bool bInForceLinearGamma = bRemovePostProcessing;
|
||||
CaptureRenderTarget->InitCustomFormat(SizeX, SizeY, PF_B8G8R8A8, bInForceLinearGamma);
|
||||
|
||||
if (!IsValid(CaptureComponent2D) || CaptureComponent2D->IsPendingKill())
|
||||
{
|
||||
CaptureComponent2D = NewObject<USceneCaptureComponent2D>(this, TEXT("SceneCaptureComponent2D"));
|
||||
CaptureComponent2D->SetupAttachment(MeshComp);
|
||||
}
|
||||
CaptureComponent2D->Deactivate();
|
||||
CaptureComponent2D->TextureTarget = CaptureRenderTarget;
|
||||
|
||||
// Setup camera post-processing.
|
||||
if (PostProcessEffect != EPostProcessEffect::None) {
|
||||
CaptureComponent2D->CaptureSource = ESceneCaptureSource::SCS_FinalColorLDR; //HD is much slower!
|
||||
// Setup camera post-processing depending on the quality level:
|
||||
const UCarlaGameInstance *GameInstance = Cast<UCarlaGameInstance>(GetWorld()->GetGameInstance());
|
||||
check(GameInstance != nullptr);
|
||||
const UCarlaSettings &CarlaSettings = GameInstance->GetCarlaSettings();
|
||||
switch (PostProcessEffect)
|
||||
{
|
||||
case EPostProcessEffect::None:
|
||||
break;
|
||||
case EPostProcessEffect::SceneFinal:
|
||||
{
|
||||
// We set LDR for high quality because it will include post-fx and HDR for
|
||||
// low quality to avoid high contrast.
|
||||
switch (CarlaSettings.GetQualitySettingsLevel())
|
||||
{
|
||||
case EQualitySettingsLevel::Low:
|
||||
CaptureComponent2D->CaptureSource = ESceneCaptureSource::SCS_SceneColorHDRNoAlpha;
|
||||
break;
|
||||
default:
|
||||
// LDR is faster than HDR (smaller bitmap array).
|
||||
CaptureComponent2D->CaptureSource = ESceneCaptureSource::SCS_FinalColorLDR;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
default:
|
||||
CaptureComponent2D->CaptureSource = SCS_FinalColorLDR;
|
||||
break;
|
||||
}
|
||||
if (bRemovePostProcessing) {
|
||||
|
||||
if (bRemovePostProcessing)
|
||||
{
|
||||
RemoveShowFlags(CaptureComponent2D->ShowFlags);
|
||||
}
|
||||
if (PostProcessEffect == EPostProcessEffect::Depth) {
|
||||
|
||||
if (PostProcessEffect == EPostProcessEffect::Depth)
|
||||
{
|
||||
CaptureComponent2D->PostProcessSettings.AddBlendable(PostProcessDepth, 1.0f);
|
||||
} else if (PostProcessEffect == EPostProcessEffect::SemanticSegmentation) {
|
||||
}
|
||||
else if (PostProcessEffect == EPostProcessEffect::SemanticSegmentation)
|
||||
{
|
||||
CaptureComponent2D->PostProcessSettings.AddBlendable(PostProcessSemanticSegmentation, 1.0f);
|
||||
}
|
||||
|
||||
CaptureComponent2D->UpdateContent();
|
||||
CaptureComponent2D->Activate();
|
||||
|
||||
// Make sure that there is enough time in the render queue.
|
||||
UKismetSystemLibrary::ExecuteConsoleCommand(
|
||||
GetWorld(),
|
||||
FString("g.TimeoutForBlockOnRenderFence 300000"));
|
||||
|
||||
Super::BeginPlay();
|
||||
}
|
||||
|
||||
void ASceneCaptureCamera::EndPlay(const EEndPlayReason::Type EndPlayReason)
|
||||
{
|
||||
if (NumSceneCapture != 0)
|
||||
{
|
||||
NumSceneCapture = 0;
|
||||
}
|
||||
}
|
||||
|
||||
void ASceneCaptureCamera::Tick(const float DeltaSeconds)
|
||||
{
|
||||
Super::Tick(DeltaSeconds);
|
||||
if(IsVulkanPlatform(GMaxRHIShaderPlatform))
|
||||
|
||||
const auto FrameNumber = GFrameCounter;
|
||||
|
||||
if (IsVulkanPlatform(GMaxRHIShaderPlatform))
|
||||
{
|
||||
auto fn = [=](FRHICommandListImmediate& RHICmdList){WritePixelsNonBlocking(DeltaSeconds,RHICmdList);};
|
||||
auto fn = [=](FRHICommandListImmediate &RHICmdList) {
|
||||
WritePixelsNonBlocking(FrameNumber, RHICmdList);
|
||||
};
|
||||
ENQUEUE_UNIQUE_RENDER_COMMAND_ONEPARAMETER(
|
||||
FWritePixelsNonBlocking,
|
||||
decltype(fn),write_function_vulkan,fn,
|
||||
{
|
||||
write_function_vulkan(RHICmdList);
|
||||
});
|
||||
} else
|
||||
{
|
||||
auto fn = [=](){WritePixels(DeltaSeconds);};
|
||||
ENQUEUE_UNIQUE_RENDER_COMMAND_ONEPARAMETER(
|
||||
FWritePixels,
|
||||
decltype(fn),write_function,fn,
|
||||
FWritePixelsNonBlocking,
|
||||
decltype(fn), write_function_vulkan, fn,
|
||||
{
|
||||
write_function();
|
||||
write_function_vulkan(RHICmdList);
|
||||
});
|
||||
}
|
||||
else
|
||||
{
|
||||
auto fn = [=]() {
|
||||
WritePixels(FrameNumber);
|
||||
};
|
||||
ENQUEUE_UNIQUE_RENDER_COMMAND_ONEPARAMETER(
|
||||
FWritePixels,
|
||||
decltype(fn), write_function, fn,
|
||||
{
|
||||
write_function();
|
||||
});
|
||||
}
|
||||
}
|
||||
|
@ -168,7 +261,8 @@ void ASceneCaptureCamera::SetPostProcessEffect(EPostProcessEffect otherPostProce
|
|||
{
|
||||
PostProcessEffect = otherPostProcessEffect;
|
||||
auto &PostProcessSettings = CaptureComponent2D->PostProcessSettings;
|
||||
if (PostProcessEffect != EPostProcessEffect::SceneFinal) {
|
||||
if (PostProcessEffect != EPostProcessEffect::SceneFinal)
|
||||
{
|
||||
PostProcessSettings.bOverride_AutoExposureMethod = false;
|
||||
PostProcessSettings.bOverride_AutoExposureMinBrightness = false;
|
||||
PostProcessSettings.bOverride_AutoExposureMaxBrightness = false;
|
||||
|
@ -192,7 +286,8 @@ void ASceneCaptureCamera::Set(const UCameraDescription &CameraDescription)
|
|||
{
|
||||
Super::Set(CameraDescription);
|
||||
|
||||
if (CameraDescription.bOverrideCameraPostProcessParameters) {
|
||||
if (CameraDescription.bOverrideCameraPostProcessParameters)
|
||||
{
|
||||
auto &Override = CameraDescription.CameraPostProcessParameters;
|
||||
auto &PostProcessSettings = CaptureComponent2D->PostProcessSettings;
|
||||
PostProcessSettings.bOverride_AutoExposureMethod = true;
|
||||
|
@ -211,13 +306,15 @@ void ASceneCaptureCamera::Set(const UCameraDescription &CameraDescription)
|
|||
|
||||
bool ASceneCaptureCamera::ReadPixels(TArray<FColor> &BitMap) const
|
||||
{
|
||||
if(!CaptureRenderTarget)
|
||||
if (!CaptureRenderTarget)
|
||||
{
|
||||
UE_LOG(LogCarla, Error, TEXT("SceneCaptureCamera: Missing render target"));
|
||||
return false;
|
||||
UE_LOG(LogCarla, Error, TEXT("SceneCaptureCamera: Missing render target"));
|
||||
return false;
|
||||
}
|
||||
FTextureRenderTargetResource* RTResource = CaptureRenderTarget->GameThread_GetRenderTargetResource();
|
||||
if (RTResource == nullptr) {
|
||||
FTextureRenderTargetResource *RTResource =
|
||||
CaptureRenderTarget->GameThread_GetRenderTargetResource();
|
||||
if (RTResource == nullptr)
|
||||
{
|
||||
UE_LOG(LogCarla, Error, TEXT("SceneCaptureCamera: Missing render target"));
|
||||
return false;
|
||||
}
|
||||
|
@ -226,105 +323,116 @@ bool ASceneCaptureCamera::ReadPixels(TArray<FColor> &BitMap) const
|
|||
return RTResource->ReadPixels(BitMap, ReadPixelFlags);
|
||||
}
|
||||
|
||||
void ASceneCaptureCamera::WritePixelsNonBlocking(float DeltaTime, FRHICommandListImmediate& rhi_cmd_list) const
|
||||
{
|
||||
void ASceneCaptureCamera::WritePixelsNonBlocking(
|
||||
const uint64 FrameNumber,
|
||||
FRHICommandListImmediate &rhi_cmd_list) const
|
||||
{
|
||||
check(IsInRenderingThread());
|
||||
if(!CaptureRenderTarget)
|
||||
if (!CaptureRenderTarget)
|
||||
{
|
||||
UE_LOG(LogCarla, Error, TEXT("SceneCaptureCamera: Missing render target"));
|
||||
return ;
|
||||
UE_LOG(LogCarla, Error, TEXT("SceneCaptureCamera: Missing render target"));
|
||||
return;
|
||||
}
|
||||
FTextureRenderTarget2DResource* RenderResource = (FTextureRenderTarget2DResource*)CaptureRenderTarget->Resource;
|
||||
FTextureRenderTarget2DResource *RenderResource =
|
||||
(FTextureRenderTarget2DResource *) CaptureRenderTarget->Resource;
|
||||
FTextureRHIParamRef texture = RenderResource->GetRenderTargetTexture();
|
||||
if(!texture)
|
||||
if (!texture)
|
||||
{
|
||||
UE_LOG(LogCarla, Error, TEXT("SceneCaptureCamera: Missing render target texture"));
|
||||
return;
|
||||
}
|
||||
struct {
|
||||
uint32 Width;
|
||||
uint32 Height;
|
||||
uint32 Type;
|
||||
float FOV;
|
||||
} ImageHeader = {
|
||||
FImageHeaderData ImageHeader = {
|
||||
FrameNumber,
|
||||
SizeX,
|
||||
SizeY,
|
||||
PostProcessEffect::ToUInt(PostProcessEffect),
|
||||
CaptureComponent2D->FOVAngle
|
||||
};
|
||||
|
||||
struct FReadSurfaceContext
|
||||
{
|
||||
FRenderTarget* SrcRenderTarget;
|
||||
TArray<FColor>* OutData;
|
||||
FIntRect Rect;
|
||||
FReadSurfaceDataFlags Flags;
|
||||
};
|
||||
TArray<FColor> Pixels;
|
||||
rhi_cmd_list.ReadSurfaceData(
|
||||
texture,
|
||||
FIntRect(0, 0, RenderResource->GetSizeXY().X, RenderResource->GetSizeXY().Y),
|
||||
Pixels,
|
||||
FReadSurfaceDataFlags(RCM_UNorm, CubeFace_MAX)
|
||||
);
|
||||
texture,
|
||||
FIntRect(0, 0, RenderResource->GetSizeXY().X, RenderResource->GetSizeXY().Y),
|
||||
Pixels,
|
||||
FReadSurfaceDataFlags(RCM_UNorm, CubeFace_MAX));
|
||||
FSensorDataView DataView(
|
||||
GetId(),
|
||||
FReadOnlyBufferView{reinterpret_cast<const void *>(&ImageHeader), sizeof(ImageHeader)},
|
||||
FReadOnlyBufferView{Pixels}
|
||||
);
|
||||
WriteSensorData(DataView);
|
||||
|
||||
GetId(),
|
||||
FReadOnlyBufferView{reinterpret_cast<const void *>(&ImageHeader), sizeof(ImageHeader)},
|
||||
FReadOnlyBufferView{Pixels});
|
||||
WriteSensorData(DataView);
|
||||
}
|
||||
|
||||
void ASceneCaptureCamera::WritePixels(float DeltaTime) const
|
||||
void ASceneCaptureCamera::WritePixels(const uint64 FrameNumber) const
|
||||
{
|
||||
FRHITexture2D *texture = CaptureRenderTarget->GetRenderTargetResource()->GetRenderTargetTexture();
|
||||
if(!texture)
|
||||
if (!texture)
|
||||
{
|
||||
UE_LOG(LogCarla, Error, TEXT("SceneCaptureCamera: Missing render texture"));
|
||||
return ;
|
||||
UE_LOG(LogCarla, Error, TEXT("SceneCaptureCamera: Missing render texture"));
|
||||
return;
|
||||
}
|
||||
const uint32 num_bytes_per_pixel = 4; // PF_R8G8B8A8
|
||||
const uint32 width = texture->GetSizeX();
|
||||
uint32 height = texture->GetSizeY();
|
||||
uint32 stride;
|
||||
uint8 *src = reinterpret_cast<uint8*>(RHILockTexture2D(texture, 0, RLM_ReadOnly, stride, false));
|
||||
struct {
|
||||
uint32 Width;
|
||||
uint32 Height;
|
||||
uint32 Type;
|
||||
float FOV;
|
||||
} ImageHeader = {
|
||||
SizeX,
|
||||
SizeY,
|
||||
const uint32 height = texture->GetSizeY();
|
||||
const uint32 dest_stride = width * height * num_bytes_per_pixel;
|
||||
uint32 src_stride;
|
||||
uint8 *src = reinterpret_cast<uint8 *>(
|
||||
RHILockTexture2D(texture, 0, RLM_ReadOnly, src_stride, false));
|
||||
FImageHeaderData ImageHeader = {
|
||||
FrameNumber,
|
||||
width,
|
||||
height,
|
||||
PostProcessEffect::ToUInt(PostProcessEffect),
|
||||
CaptureComponent2D->FOVAngle
|
||||
};
|
||||
FSensorDataView DataView(
|
||||
GetId(),
|
||||
FReadOnlyBufferView{reinterpret_cast<const void *>(&ImageHeader), sizeof(ImageHeader)},
|
||||
FReadOnlyBufferView{src,stride*height}
|
||||
);
|
||||
|
||||
std::unique_ptr<uint8[]> dest = nullptr;
|
||||
// Direct 3D uses additional rows in the buffer,so we need check the result
|
||||
// stride from the lock:
|
||||
if (IsD3DPlatform(GMaxRHIShaderPlatform, false) && (dest_stride != src_stride))
|
||||
{
|
||||
const uint32 copy_row_stride = width * num_bytes_per_pixel;
|
||||
dest = std::make_unique<uint8[]>(dest_stride);
|
||||
// Copy per row
|
||||
uint8 *dest_row = dest.get();
|
||||
uint8 *src_row = src;
|
||||
for (uint32 Row = 0; Row < height; ++Row)
|
||||
{
|
||||
FMemory::Memcpy(dest_row, src_row, copy_row_stride);
|
||||
dest_row += copy_row_stride;
|
||||
src_row += src_stride;
|
||||
}
|
||||
src = dest.get();
|
||||
}
|
||||
|
||||
const FSensorDataView DataView(
|
||||
GetId(),
|
||||
FReadOnlyBufferView{reinterpret_cast<const void *>(&ImageHeader), sizeof(ImageHeader)},
|
||||
FReadOnlyBufferView{src, dest_stride});
|
||||
|
||||
WriteSensorData(DataView);
|
||||
RHIUnlockTexture2D(texture, 0, false);
|
||||
}
|
||||
|
||||
|
||||
void ASceneCaptureCamera::UpdateDrawFrustum()
|
||||
{
|
||||
if(DrawFrustum && CaptureComponent2D)
|
||||
if (DrawFrustum && CaptureComponent2D)
|
||||
{
|
||||
DrawFrustum->FrustumStartDist = GNearClippingPlane;
|
||||
|
||||
// 1000 is the default frustum distance, ideally this would be infinite but that might cause rendering issues
|
||||
DrawFrustum->FrustumEndDist = (CaptureComponent2D->MaxViewDistanceOverride > DrawFrustum->FrustumStartDist)
|
||||
// 1000 is the default frustum distance, ideally this would be infinite but
|
||||
// that might cause rendering issues.
|
||||
DrawFrustum->FrustumEndDist =
|
||||
(CaptureComponent2D->MaxViewDistanceOverride > DrawFrustum->FrustumStartDist)
|
||||
? CaptureComponent2D->MaxViewDistanceOverride : 1000.0f;
|
||||
|
||||
DrawFrustum->FrustumAngle = CaptureComponent2D->FOVAngle;
|
||||
//DrawFrustum->FrustumAspectRatio = CaptureComponent2D->AspectRatio;
|
||||
}
|
||||
}
|
||||
|
||||
// =============================================================================
|
||||
// -- Local static functions implementations -----------------------------------
|
||||
// =============================================================================
|
||||
|
||||
// Remove the show flags that might interfere with post-processing effects like
|
||||
// depth and semantic segmentation.
|
||||
static void RemoveShowFlags(FEngineShowFlags &ShowFlags)
|
||||
|
|
|
@ -37,7 +37,7 @@ protected:
|
|||
public:
|
||||
|
||||
virtual void BeginPlay() override;
|
||||
|
||||
virtual void EndPlay(const EEndPlayReason::Type EndPlayReason) override;
|
||||
virtual void Tick(float DeltaSeconds) override;
|
||||
|
||||
uint32 GetImageSizeX() const
|
||||
|
@ -69,12 +69,20 @@ public:
|
|||
|
||||
bool ReadPixels(TArray<FColor> &BitMap) const;
|
||||
|
||||
protected:
|
||||
static uint32 NumSceneCapture;
|
||||
|
||||
private:
|
||||
///Read the camera buffer and write it to the client with no lock of the resources (for Vulkan API)
|
||||
void WritePixelsNonBlocking(float DeltaTime,FRHICommandListImmediate& rhi_cmd_list) const;
|
||||
///Read the camera buffer and write it to the client with opengl or direct3d
|
||||
void WritePixels(float DeltaTime) const;
|
||||
|
||||
/// Read the camera buffer and write it to the client with no lock of the
|
||||
/// resources (for Vulkan API).
|
||||
void WritePixelsNonBlocking(
|
||||
uint64 FrameNumber,
|
||||
FRHICommandListImmediate& rhi_cmd_list) const;
|
||||
|
||||
/// Read the camera buffer and write it to the client with opengl or direct3d.
|
||||
void WritePixels(uint64 FrameNumber) const;
|
||||
|
||||
/// Used to synchronize the DrawFrustumComponent with the
|
||||
/// SceneCaptureComponent2D settings.
|
||||
void UpdateDrawFrustum();
|
||||
|
@ -97,7 +105,7 @@ private:
|
|||
UDrawFrustumComponent* DrawFrustum;
|
||||
|
||||
/** Render target necessary for scene capture */
|
||||
UPROPERTY(Transient)
|
||||
UPROPERTY()
|
||||
UTextureRenderTarget2D* CaptureRenderTarget;
|
||||
|
||||
/** Scene capture component. */
|
||||
|
|
|
@ -12,7 +12,7 @@
|
|||
|
||||
ASceneCaptureToDiskCamera::ASceneCaptureToDiskCamera(const FObjectInitializer& ObjectInitializer) :
|
||||
Super(ObjectInitializer),
|
||||
SaveToFolder(FPaths::Combine(FPaths::ProjectSavedDir(), "SceneCaptures")),
|
||||
SaveToFolder(*FPaths::Combine(FPaths::ProjectSavedDir(), TEXT("SceneCaptures"))),
|
||||
FileName("capture_%05d.png") {}
|
||||
|
||||
void ASceneCaptureToDiskCamera::BeginPlay()
|
||||
|
|
|
@ -106,11 +106,13 @@ void FCarlaEncoder::Encode(
|
|||
const ACarlaPlayerState &PlayerState,
|
||||
carla_measurements &Data)
|
||||
{
|
||||
Data.frame_number = PlayerState.GetFrameNumber();
|
||||
Data.platform_timestamp = PlayerState.GetPlatformTimeStamp();
|
||||
Data.game_timestamp = PlayerState.GetGameTimeStamp();
|
||||
auto &Player = Data.player_measurements;
|
||||
::Encode(PlayerState.GetTransform(), Player.transform);
|
||||
::Encode(PlayerState.GetBoundsExtent() * TO_METERS, Player.box_extent);
|
||||
::Encode(PlayerState.GetBoundingBoxTransform(), Player.bounding_box.transform);
|
||||
::Encode(PlayerState.GetBoundingBoxExtent() * TO_METERS, Player.bounding_box.extent);
|
||||
::Encode(PlayerState.GetAcceleration() * TO_METERS, Player.acceleration);
|
||||
Player.forward_speed = PlayerState.GetForwardSpeed() * TO_METERS;
|
||||
Player.collision_vehicles = PlayerState.GetCollisionIntensityCars() * TO_METERS;
|
||||
|
@ -204,17 +206,18 @@ void FCarlaEncoder::Visit(const UTrafficSignAgentComponent &Agent)
|
|||
|
||||
void FCarlaEncoder::Visit(const UVehicleAgentComponent &Agent)
|
||||
{
|
||||
auto &Vehicle = Agent.GetVehicle();
|
||||
::Encode(Vehicle.GetVehicleTransform(), Data.transform);
|
||||
::Encode(Agent.GetTransform(), Data.transform);
|
||||
Data.type = CARLA_SERVER_AGENT_VEHICLE;
|
||||
Data.forward_speed = Vehicle.GetVehicleForwardSpeed() * TO_METERS;
|
||||
::Encode(Vehicle.GetVehicleBoundsExtent() * TO_METERS, Data.box_extent);
|
||||
Data.forward_speed = Agent.GetForwardSpeed() * TO_METERS;
|
||||
::Encode(Agent.GetBoundingBoxTransform(), Data.bounding_box.transform);
|
||||
::Encode(Agent.GetBoundingBoxExtent() * TO_METERS, Data.bounding_box.extent);
|
||||
}
|
||||
|
||||
void FCarlaEncoder::Visit(const UWalkerAgentComponent &Agent)
|
||||
{
|
||||
::Encode(Agent.GetComponentTransform(), Data.transform);
|
||||
::Encode(Agent.GetTransform(), Data.transform);
|
||||
Data.type = CARLA_SERVER_AGENT_PEDESTRIAN;
|
||||
Data.forward_speed = Agent.GetForwardSpeed() * TO_METERS;
|
||||
::Encode(Agent.GetBoundingBoxExtent() * TO_METERS, Data.box_extent);
|
||||
::Encode(Agent.GetBoundingBoxTransform(), Data.bounding_box.transform);
|
||||
::Encode(Agent.GetBoundingBoxExtent() * TO_METERS, Data.bounding_box.extent);
|
||||
}
|
||||
|
|
|
@ -122,10 +122,7 @@ static void LoadSettingsFromConfig(
|
|||
// QualitySettings.
|
||||
FString sQualityLevel;
|
||||
ConfigFile.GetString(S_CARLA_QUALITYSETTINGS, TEXT("QualityLevel"), sQualityLevel);
|
||||
if(!Settings.SetQualitySettingsLevel(UQualitySettings::FromString(sQualityLevel)))
|
||||
{
|
||||
//error
|
||||
}
|
||||
Settings.SetQualitySettingsLevel(UQualitySettings::FromString(sQualityLevel));
|
||||
|
||||
// Sensors.
|
||||
FString Sensors;
|
||||
|
@ -176,17 +173,9 @@ FString UQualitySettings::ToString(EQualitySettingsLevel QualitySettingsLevel)
|
|||
return ptr->GetNameStringByIndex(static_cast<int32>(QualitySettingsLevel));
|
||||
}
|
||||
|
||||
bool UCarlaSettings::SetQualitySettingsLevel(EQualitySettingsLevel newQualityLevel)
|
||||
void UCarlaSettings::SetQualitySettingsLevel(EQualitySettingsLevel newQualityLevel)
|
||||
{
|
||||
if(newQualityLevel==EQualitySettingsLevel::None)
|
||||
{
|
||||
UE_LOG(LogCarla ,Warning, TEXT("Quality Settings Level not set!"));
|
||||
return false;
|
||||
}
|
||||
|
||||
QualitySettingsLevel = newQualityLevel;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void UCarlaSettings::LoadSettings()
|
||||
|
|
|
@ -5,13 +5,11 @@
|
|||
// For a copy, see <https://opensource.org/licenses/MIT>.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "Engine/StaticMesh.h"
|
||||
#include "WeatherDescription.h"
|
||||
|
||||
#include "UObject/NoExportTypes.h"
|
||||
|
||||
#include "CarlaSettings.generated.h"
|
||||
|
||||
|
||||
UENUM(BlueprintType)
|
||||
enum class EQualitySettingsLevel : uint8
|
||||
{
|
||||
|
@ -42,7 +40,7 @@ public:
|
|||
};
|
||||
|
||||
class USensorDescription;
|
||||
struct FStaticMaterial;
|
||||
|
||||
/** Global settings for CARLA.
|
||||
* Setting object used to hold both config settings and editable ones in one place
|
||||
* To ensure the settings are saved to the specified config file make sure to add
|
||||
|
@ -57,12 +55,12 @@ public:
|
|||
|
||||
/**
|
||||
* Sets the new quality settings level and make changes in the game related to it.
|
||||
* Returns the result of the operation.
|
||||
* @note This will not apply the quality settings. Use ApplyQualitySettings functions instead
|
||||
* @param newQualityLevel Store the new quality
|
||||
*/
|
||||
UFUNCTION(BlueprintCallable, Category="CARLA Settings")
|
||||
bool SetQualitySettingsLevel(EQualitySettingsLevel newQualityLevel);
|
||||
void SetQualitySettingsLevel(EQualitySettingsLevel newQualityLevel);
|
||||
|
||||
/** @return current quality settings level (could not be applied yet) */
|
||||
UFUNCTION(BlueprintCallable, Category="CARLA Settings")
|
||||
EQualitySettingsLevel GetQualitySettingsLevel() const { return QualitySettingsLevel; }
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
#include "Carla.h"
|
||||
#include "Engine/World.h"
|
||||
|
||||
#include "Game/CarlaGameModeBase.h"
|
||||
#include "Settings/CarlaSettings.h"
|
||||
#include "CarlaSettingsDelegate.h"
|
||||
|
@ -10,6 +10,7 @@
|
|||
#include "Engine/StaticMesh.h"
|
||||
#include "Engine/PostProcessVolume.h"
|
||||
#include "UObjectIterator.h"
|
||||
#include "Async.h"
|
||||
|
||||
///quality settings configuration between runs
|
||||
EQualitySettingsLevel UCarlaSettingsDelegate::AppliedLowPostResetQualitySettingsLevel = EQualitySettingsLevel::Epic;
|
||||
|
@ -21,8 +22,7 @@ UCarlaSettingsDelegate::UCarlaSettingsDelegate() :
|
|||
|
||||
void UCarlaSettingsDelegate::Reset()
|
||||
{
|
||||
LaunchEpicQualityCommands(GetLocalWorld());
|
||||
AppliedLowPostResetQualitySettingsLevel = EQualitySettingsLevel::Epic;
|
||||
AppliedLowPostResetQualitySettingsLevel = EQualitySettingsLevel::None;
|
||||
}
|
||||
|
||||
void UCarlaSettingsDelegate::RegisterSpawnHandler(UWorld *InWorld)
|
||||
|
@ -62,7 +62,8 @@ void UCarlaSettingsDelegate::ApplyQualitySettingsLevelPostRestart()
|
|||
{
|
||||
CheckCarlaSettings(nullptr);
|
||||
UWorld *InWorld = CarlaSettings->GetWorld();
|
||||
EQualitySettingsLevel QualitySettingsLevel = CarlaSettings->GetQualitySettingsLevel();
|
||||
|
||||
EQualitySettingsLevel QualitySettingsLevel = CarlaSettings->GetQualitySettingsLevel();
|
||||
if(AppliedLowPostResetQualitySettingsLevel==QualitySettingsLevel) return;
|
||||
|
||||
switch(QualitySettingsLevel)
|
||||
|
@ -181,45 +182,49 @@ void UCarlaSettingsDelegate::LaunchLowQualityCommands(UWorld * world) const
|
|||
|
||||
void UCarlaSettingsDelegate::SetAllRoads(UWorld* world, const float max_draw_distance, const TArray<FStaticMaterial> &road_pieces_materials) const
|
||||
{
|
||||
TArray<AActor*> actors;
|
||||
UGameplayStatics::GetAllActorsWithTag(world, UCarlaSettings::CARLA_ROAD_TAG,actors);
|
||||
if(!world||!IsValid(world)||world->IsPendingKill()) return;
|
||||
AsyncTask(ENamedThreads::GameThread, [=](){
|
||||
if(!world||!IsValid(world)||world->IsPendingKill()) return;
|
||||
TArray<AActor*> actors;
|
||||
UGameplayStatics::GetAllActorsWithTag(world, UCarlaSettings::CARLA_ROAD_TAG,actors);
|
||||
|
||||
for(int32 i=0; i<actors.Num(); i++)
|
||||
{
|
||||
if(!IsValid(actors[i]) || actors[i]->IsPendingKillPending()) continue;
|
||||
TArray<UActorComponent*> components = actors[i]->GetComponentsByClass(UStaticMeshComponent::StaticClass());
|
||||
for(int32 j=0; j<components.Num(); j++)
|
||||
{
|
||||
UStaticMeshComponent* staticmeshcomponent = Cast<UStaticMeshComponent>(components[j]);
|
||||
if(staticmeshcomponent)
|
||||
{
|
||||
staticmeshcomponent->bAllowCullDistanceVolume = (max_draw_distance>0);
|
||||
staticmeshcomponent->bUseAsOccluder = false;
|
||||
staticmeshcomponent->LDMaxDrawDistance = max_draw_distance;
|
||||
staticmeshcomponent->CastShadow = (max_draw_distance==0);
|
||||
if(road_pieces_materials.Num()>0)
|
||||
{
|
||||
TArray<FName> meshslotsnames = staticmeshcomponent->GetMaterialSlotNames();
|
||||
for(int32 k=0; k<meshslotsnames.Num(); k++)
|
||||
for(int32 i=0; i<actors.Num(); i++)
|
||||
{
|
||||
if(!IsValid(actors[i]) || actors[i]->IsPendingKillPending()) continue;
|
||||
TArray<UActorComponent*> components = actors[i]->GetComponentsByClass(UStaticMeshComponent::StaticClass());
|
||||
for(int32 j=0; j<components.Num(); j++)
|
||||
{
|
||||
UStaticMeshComponent* staticmeshcomponent = Cast<UStaticMeshComponent>(components[j]);
|
||||
if(staticmeshcomponent)
|
||||
{
|
||||
staticmeshcomponent->bAllowCullDistanceVolume = (max_draw_distance>0);
|
||||
staticmeshcomponent->bUseAsOccluder = false;
|
||||
staticmeshcomponent->LDMaxDrawDistance = max_draw_distance;
|
||||
staticmeshcomponent->CastShadow = (max_draw_distance==0);
|
||||
if(road_pieces_materials.Num()>0)
|
||||
{
|
||||
const FName &slotname = meshslotsnames[k];
|
||||
road_pieces_materials.ContainsByPredicate(
|
||||
[staticmeshcomponent,slotname](const FStaticMaterial& material)
|
||||
TArray<FName> meshslotsnames = staticmeshcomponent->GetMaterialSlotNames();
|
||||
for(int32 k=0; k<meshslotsnames.Num(); k++)
|
||||
{
|
||||
if(material.MaterialSlotName.IsEqual(slotname))
|
||||
const FName &slotname = meshslotsnames[k];
|
||||
road_pieces_materials.ContainsByPredicate(
|
||||
[staticmeshcomponent,slotname](const FStaticMaterial& material)
|
||||
{
|
||||
staticmeshcomponent->SetMaterial(
|
||||
staticmeshcomponent->GetMaterialIndex(slotname),
|
||||
material.MaterialInterface
|
||||
);
|
||||
return true;
|
||||
} else return false;
|
||||
});
|
||||
if(material.MaterialSlotName.IsEqual(slotname))
|
||||
{
|
||||
staticmeshcomponent->SetMaterial(
|
||||
staticmeshcomponent->GetMaterialIndex(slotname),
|
||||
material.MaterialInterface
|
||||
);
|
||||
return true;
|
||||
} else return false;
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}); //,DELAY_TIME_TO_SET_ALL_ROADS, false);
|
||||
}
|
||||
|
||||
void UCarlaSettingsDelegate::SetActorComponentsDrawDistance(AActor* actor, const float max_draw_distance) const
|
||||
|
@ -243,20 +248,24 @@ void UCarlaSettingsDelegate::SetActorComponentsDrawDistance(AActor* actor, const
|
|||
void UCarlaSettingsDelegate::SetAllActorsDrawDistance(UWorld* world, const float max_draw_distance) const
|
||||
{
|
||||
///@TODO: use semantics to grab all actors by type (vehicles,ground,people,props) and set different distances configured in the global properties
|
||||
TArray<AActor*> actors;
|
||||
#define _MAX_SCALE_SIZE 50.0f
|
||||
//set the lower quality - max draw distance
|
||||
UGameplayStatics::GetAllActorsOfClass(world, AActor::StaticClass(),actors);
|
||||
for(int32 i=0; i<actors.Num(); i++)
|
||||
{
|
||||
if(!IsValid(actors[i]) || actors[i]->IsPendingKillPending() ||
|
||||
actors[i]->ActorHasTag(UCarlaSettings::CARLA_ROAD_TAG) ||
|
||||
actors[i]->ActorHasTag(UCarlaSettings::CARLA_SKY_TAG)
|
||||
){
|
||||
continue;
|
||||
}
|
||||
SetActorComponentsDrawDistance(actors[i], max_draw_distance);
|
||||
}
|
||||
if(!world||!IsValid(world)||world->IsPendingKill()) return;
|
||||
AsyncTask(ENamedThreads::GameThread, [=](){
|
||||
if(!world||!IsValid(world)||world->IsPendingKill()) return;
|
||||
TArray<AActor*> actors;
|
||||
#define _MAX_SCALE_SIZE 50.0f
|
||||
//set the lower quality - max draw distance
|
||||
UGameplayStatics::GetAllActorsOfClass(world, AActor::StaticClass(),actors);
|
||||
for(int32 i=0; i<actors.Num(); i++)
|
||||
{
|
||||
if(!IsValid(actors[i]) || actors[i]->IsPendingKillPending() ||
|
||||
actors[i]->ActorHasTag(UCarlaSettings::CARLA_ROAD_TAG) ||
|
||||
actors[i]->ActorHasTag(UCarlaSettings::CARLA_SKY_TAG)
|
||||
){
|
||||
continue;
|
||||
}
|
||||
SetActorComponentsDrawDistance(actors[i], max_draw_distance);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
|
@ -266,12 +275,12 @@ void UCarlaSettingsDelegate::SetPostProcessEffectsEnabled(UWorld* world, const b
|
|||
UGameplayStatics::GetAllActorsOfClass(world, APostProcessVolume::StaticClass(), actors);
|
||||
for(int32 i=0; i<actors.Num(); i++)
|
||||
{
|
||||
if(!IsValid(actors[i]) || actors[i]->IsPendingKillPending()) continue;
|
||||
APostProcessVolume* postprocessvolume = Cast<APostProcessVolume>(actors[i]);
|
||||
if(postprocessvolume)
|
||||
{
|
||||
postprocessvolume->bEnabled = enabled;
|
||||
}
|
||||
if(!IsValid(actors[i]) || actors[i]->IsPendingKillPending()) continue;
|
||||
APostProcessVolume* postprocessvolume = Cast<APostProcessVolume>(actors[i]);
|
||||
if(postprocessvolume)
|
||||
{
|
||||
postprocessvolume->bEnabled = enabled;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -318,21 +327,26 @@ void UCarlaSettingsDelegate::LaunchEpicQualityCommands(UWorld* world) const
|
|||
|
||||
void UCarlaSettingsDelegate::SetAllLights(UWorld* world, const float max_distance_fade, const bool cast_shadows, const bool hide_non_directional) const
|
||||
{
|
||||
TArray<AActor*> actors;
|
||||
UGameplayStatics::GetAllActorsOfClass(world, ALight::StaticClass(), actors);
|
||||
for(int32 i=0;i<actors.Num();i++)
|
||||
{
|
||||
if(!IsValid(actors[i]) || actors[i]->IsPendingKillPending()) continue;
|
||||
//tweak directional lights
|
||||
ADirectionalLight* directionallight = Cast<ADirectionalLight>(actors[i]);
|
||||
if(directionallight)
|
||||
if(!world||!IsValid(world)||world->IsPendingKill()) return;
|
||||
AsyncTask(ENamedThreads::GameThread, [=](){
|
||||
if(!world||!IsValid(world)||world->IsPendingKill()) return;
|
||||
TArray<AActor*> actors;
|
||||
UGameplayStatics::GetAllActorsOfClass(world, ALight::StaticClass(), actors);
|
||||
for(int32 i=0;i<actors.Num();i++)
|
||||
{
|
||||
directionallight->SetCastShadows(cast_shadows);
|
||||
directionallight->SetLightFunctionFadeDistance(max_distance_fade);
|
||||
continue;
|
||||
if(!IsValid(actors[i]) || actors[i]->IsPendingKillPending()) continue;
|
||||
//tweak directional lights
|
||||
ADirectionalLight* directionallight = Cast<ADirectionalLight>(actors[i]);
|
||||
if(directionallight)
|
||||
{
|
||||
directionallight->SetCastShadows(cast_shadows);
|
||||
directionallight->SetLightFunctionFadeDistance(max_distance_fade);
|
||||
continue;
|
||||
}
|
||||
//disable any other type of light
|
||||
actors[i]->SetActorHiddenInGame(hide_non_directional);
|
||||
}
|
||||
//disable any other type of light
|
||||
actors[i]->SetActorHiddenInGame(hide_non_directional);
|
||||
}
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
|
|
|
@ -5,12 +5,10 @@
|
|||
// For a copy, see <https://opensource.org/licenses/MIT>.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "CoreMinimal.h"
|
||||
#include "Engine/World.h"
|
||||
#include "CarlaSettingsDelegate.generated.h"
|
||||
|
||||
|
||||
class UCarlaSettings;
|
||||
|
||||
/// Used to set settings for every actor that is spawned into the world.
|
||||
UCLASS(BlueprintType)
|
||||
class CARLA_API UCarlaSettingsDelegate : public UObject
|
||||
|
|
|
@ -42,8 +42,9 @@ void ACarlaVehicleController::Possess(APawn *aPawn)
|
|||
// Get custom player state.
|
||||
CarlaPlayerState = Cast<ACarlaPlayerState>(PlayerState);
|
||||
check(CarlaPlayerState != nullptr);
|
||||
// We can set bounds extent already as it's not going to change.
|
||||
CarlaPlayerState->BoundsExtent = GetPossessedVehicle()->GetVehicleBoundsExtent();
|
||||
// We can set the bounding box already as it's not going to change.
|
||||
CarlaPlayerState->BoundingBoxTransform = GetPossessedVehicle()->GetVehicleBoundingBoxTransform();
|
||||
CarlaPlayerState->BoundingBoxExtent = GetPossessedVehicle()->GetVehicleBoundingBoxExtent();
|
||||
// Set HUD input.
|
||||
CarlaHUD = Cast<ACarlaHUD>(GetHUD());
|
||||
if (CarlaHUD != nullptr) {
|
||||
|
@ -114,9 +115,11 @@ void ACarlaVehicleController::IntersectPlayerWithRoadMap()
|
|||
check(IsPossessingAVehicle());
|
||||
auto Vehicle = GetPossessedVehicle();
|
||||
constexpr float ChecksPerCentimeter = 0.1f;
|
||||
const auto *BoundingBox = Vehicle->GetVehicleBoundingBox();
|
||||
check(BoundingBox != nullptr);
|
||||
auto Result = RoadMap->Intersect(
|
||||
Vehicle->GetVehicleTransform(),
|
||||
Vehicle->GetVehicleBoundsExtent(),
|
||||
BoundingBox->GetComponentTransform(),
|
||||
Vehicle->GetVehicleBoundingBoxExtent(), // Get scaled bounding box extent.
|
||||
ChecksPerCentimeter);
|
||||
|
||||
CarlaPlayerState->OffRoadIntersectionFactor = Result.OffRoad;
|
||||
|
|
|
@ -8,7 +8,6 @@
|
|||
#include "CarlaWheeledVehicle.h"
|
||||
|
||||
#include "Agent/VehicleAgentComponent.h"
|
||||
#include "Vehicle/VehicleControl.h"
|
||||
|
||||
#include "Components/BoxComponent.h"
|
||||
#include "Engine/CollisionProfile.h"
|
||||
|
@ -37,13 +36,6 @@ ACarlaWheeledVehicle::~ACarlaWheeledVehicle() {}
|
|||
// -- Get functions ------------------------------------------------------------
|
||||
// =============================================================================
|
||||
|
||||
FTransform ACarlaWheeledVehicle::GetVehicleTransform() const
|
||||
{
|
||||
FTransform Transform = VehicleBounds->GetComponentTransform();
|
||||
Transform.SetScale3D(GetActorTransform().GetScale3D());
|
||||
return Transform;
|
||||
}
|
||||
|
||||
float ACarlaWheeledVehicle::GetVehicleForwardSpeed() const
|
||||
{
|
||||
return GetVehicleMovementComponent()->GetForwardSpeed();
|
||||
|
@ -59,7 +51,12 @@ int32 ACarlaWheeledVehicle::GetVehicleCurrentGear() const
|
|||
return GetVehicleMovementComponent()->GetCurrentGear();
|
||||
}
|
||||
|
||||
FVector ACarlaWheeledVehicle::GetVehicleBoundsExtent() const
|
||||
FTransform ACarlaWheeledVehicle::GetVehicleBoundingBoxTransform() const
|
||||
{
|
||||
return VehicleBounds->GetRelativeTransform();
|
||||
}
|
||||
|
||||
FVector ACarlaWheeledVehicle::GetVehicleBoundingBoxExtent() const
|
||||
{
|
||||
return VehicleBounds->GetScaledBoxExtent();
|
||||
}
|
||||
|
|
|
@ -9,6 +9,7 @@
|
|||
#include "WheeledVehicle.h"
|
||||
|
||||
#include "Vehicle/CarlaWheeledVehicleState.h"
|
||||
#include "Vehicle/VehicleControl.h"
|
||||
|
||||
#include "CoreMinimal.h"
|
||||
|
||||
|
@ -16,7 +17,6 @@
|
|||
|
||||
class UBoxComponent;
|
||||
class UVehicleAgentComponent;
|
||||
struct FVehicleControl;
|
||||
|
||||
/// Base class for CARLA wheeled vehicles.
|
||||
UCLASS()
|
||||
|
@ -44,7 +44,10 @@ public:
|
|||
/// Transform of the vehicle. Location is shifted so it matches center of the
|
||||
/// vehicle bounds rather than the actor's location.
|
||||
UFUNCTION(Category = "CARLA Wheeled Vehicle", BlueprintCallable)
|
||||
FTransform GetVehicleTransform() const;
|
||||
FTransform GetVehicleTransform() const
|
||||
{
|
||||
return GetActorTransform();
|
||||
}
|
||||
|
||||
/// Forward speed in cm/s. Might be negative if goes backwards.
|
||||
UFUNCTION(Category = "CARLA Wheeled Vehicle", BlueprintCallable)
|
||||
|
@ -58,9 +61,20 @@ public:
|
|||
UFUNCTION(Category = "CARLA Wheeled Vehicle", BlueprintCallable)
|
||||
int32 GetVehicleCurrentGear() const;
|
||||
|
||||
/// Extent of the vehicle's bounds.
|
||||
/// Transform of the vehicle's bounding box relative to the vehicle.
|
||||
UFUNCTION(Category = "CARLA Wheeled Vehicle", BlueprintCallable)
|
||||
FVector GetVehicleBoundsExtent() const;
|
||||
FTransform GetVehicleBoundingBoxTransform() const;
|
||||
|
||||
/// Extent of the vehicle's bounding box.
|
||||
UFUNCTION(Category = "CARLA Wheeled Vehicle", BlueprintCallable)
|
||||
FVector GetVehicleBoundingBoxExtent() const;
|
||||
|
||||
/// Get vehicle's bounding box component.
|
||||
UFUNCTION(Category = "CARLA Wheeled Vehicle", BlueprintCallable)
|
||||
UBoxComponent *GetVehicleBoundingBox() const
|
||||
{
|
||||
return VehicleBounds;
|
||||
}
|
||||
|
||||
/// Get the maximum angle at which the front wheel can steer.
|
||||
UFUNCTION(Category = "CARLA Wheeled Vehicle", BlueprintCallable)
|
||||
|
|
|
@ -11,10 +11,12 @@
|
|||
#include "Vehicle/CarlaWheeledVehicle.h"
|
||||
#include "Vehicle/WheeledVehicleAIController.h"
|
||||
|
||||
#include "Engine/PlayerStartPIE.h"
|
||||
|
||||
#include "EngineUtils.h"
|
||||
#include "GameFramework/Character.h"
|
||||
#include "GameFramework/PlayerStart.h"
|
||||
#include "TimerManager.h"
|
||||
#include "Kismet/GameplayStatics.h"
|
||||
|
||||
// =============================================================================
|
||||
// -- Static local methods -----------------------------------------------------
|
||||
|
@ -35,8 +37,7 @@ static AWheeledVehicleAIController *GetController(ACarlaWheeledVehicle *Vehicle)
|
|||
// =============================================================================
|
||||
|
||||
// Sets default values
|
||||
AVehicleSpawnerBase::AVehicleSpawnerBase(const FObjectInitializer& ObjectInitializer)
|
||||
: Super(ObjectInitializer)
|
||||
AVehicleSpawnerBase::AVehicleSpawnerBase(const FObjectInitializer& ObjectInitializer): Super(ObjectInitializer)
|
||||
{
|
||||
PrimaryActorTick.bCanEverTick = false;
|
||||
}
|
||||
|
@ -55,31 +56,71 @@ void AVehicleSpawnerBase::BeginPlay()
|
|||
SpawnPoints.Add(*It);
|
||||
}
|
||||
|
||||
UE_LOG(LogCarla, Log, TEXT("Found %d positions for spawning vehicles"), SpawnPoints.Num());
|
||||
UE_LOG(LogCarla, Log, TEXT("Found %d PlayerStart positions for spawning vehicles"), SpawnPoints.Num());
|
||||
|
||||
if (SpawnPoints.Num() < NumberOfVehicles) {
|
||||
bSpawnVehicles = false;
|
||||
UE_LOG(LogCarla, Error, TEXT("We don't have enough spawn points for vehicles!"));
|
||||
if (SpawnPoints.Num() < NumberOfVehicles && SpawnPoints.Num()>0)
|
||||
{
|
||||
UE_LOG(LogCarla, Warning, TEXT("We don't have enough spawn points (PlayerStart) for vehicles!"));
|
||||
if(SpawnPoints.Num()==0)
|
||||
{
|
||||
UE_LOG(LogCarla, Error, TEXT("At least one spawn point (PlayerStart) is needed to spawn vehicles!"));
|
||||
} else
|
||||
{
|
||||
UE_LOG(LogCarla, Log,
|
||||
TEXT("To cover the %d vehicles to spawn after beginplay, it will spawn one new vehicle each %f seconds"),
|
||||
NumberOfVehicles - SpawnPoints.Num(),
|
||||
TimeBetweenSpawnAttemptsAfterBegin
|
||||
)
|
||||
;
|
||||
}
|
||||
}
|
||||
|
||||
if (bSpawnVehicles) {
|
||||
const int32 MaximumNumberOfAttempts = 4 * NumberOfVehicles;
|
||||
if(NumberOfVehicles==0||SpawnPoints.Num()==0) bSpawnVehicles = false;
|
||||
|
||||
if (bSpawnVehicles)
|
||||
{
|
||||
GetRandomEngine()->Shuffle(SpawnPoints);
|
||||
const int32 MaximumNumberOfAttempts = SpawnPoints.Num();
|
||||
int32 NumberOfAttempts = 0;
|
||||
while ((NumberOfVehicles > Vehicles.Num()) && (NumberOfAttempts < MaximumNumberOfAttempts)) {
|
||||
// Try to spawn one vehicle.
|
||||
TryToSpawnRandomVehicle();
|
||||
|
||||
while ((NumberOfVehicles > Vehicles.Num()) && (NumberOfAttempts < MaximumNumberOfAttempts))
|
||||
{
|
||||
SpawnVehicleAtSpawnPoint(*SpawnPoints[NumberOfAttempts]);
|
||||
++NumberOfAttempts;
|
||||
}
|
||||
|
||||
if (NumberOfVehicles > Vehicles.Num()) {
|
||||
if (NumberOfAttempts > NumberOfVehicles)
|
||||
{
|
||||
UE_LOG(LogCarla, Error, TEXT("Requested %d vehicles, but we were only able to spawn %d"), NumberOfVehicles, Vehicles.Num());
|
||||
} else
|
||||
{
|
||||
if(NumberOfAttempts == NumberOfVehicles)
|
||||
{
|
||||
UE_LOG(LogCarla, Log, TEXT("Spawned all %d vehicles"), NumberOfAttempts);
|
||||
} else
|
||||
{
|
||||
UE_LOG(LogCarla, Log,
|
||||
TEXT("Starting the timer to spawn the other %d vehicles, one per %f seconds"),
|
||||
NumberOfVehicles - NumberOfAttempts,
|
||||
TimeBetweenSpawnAttemptsAfterBegin
|
||||
);
|
||||
GetWorld()->GetTimerManager().SetTimer(AttemptTimerHandle,this, &AVehicleSpawnerBase::SpawnVehicleAttempt, TimeBetweenSpawnAttemptsAfterBegin,false,-1);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void AVehicleSpawnerBase::EndPlay(const EEndPlayReason::Type EndPlayReason)
|
||||
{
|
||||
GetWorld()->GetTimerManager().ClearAllTimersForObject(this);
|
||||
}
|
||||
|
||||
void AVehicleSpawnerBase::SetNumberOfVehicles(const int32 Count)
|
||||
{
|
||||
if (Count > 0) {
|
||||
if (Count > 0)
|
||||
{
|
||||
bSpawnVehicles = true;
|
||||
NumberOfVehicles = Count;
|
||||
} else {
|
||||
|
@ -90,7 +131,8 @@ void AVehicleSpawnerBase::SetNumberOfVehicles(const int32 Count)
|
|||
void AVehicleSpawnerBase::TryToSpawnRandomVehicle()
|
||||
{
|
||||
auto SpawnPoint = GetRandomSpawnPoint();
|
||||
if (SpawnPoint != nullptr) {
|
||||
if (SpawnPoint != nullptr)
|
||||
{
|
||||
SpawnVehicleAtSpawnPoint(*SpawnPoint);
|
||||
} else {
|
||||
UE_LOG(LogCarla, Error, TEXT("Unable to find spawn point"));
|
||||
|
@ -102,11 +144,13 @@ void AVehicleSpawnerBase::SpawnVehicleAtSpawnPoint(
|
|||
{
|
||||
ACarlaWheeledVehicle *Vehicle;
|
||||
SpawnVehicle(SpawnPoint.GetActorTransform(), Vehicle);
|
||||
if ((Vehicle != nullptr) && !Vehicle->IsPendingKill()) {
|
||||
if ((Vehicle != nullptr) && !Vehicle->IsPendingKill())
|
||||
{
|
||||
Vehicle->AIControllerClass = AWheeledVehicleAIController::StaticClass();
|
||||
Vehicle->SpawnDefaultController();
|
||||
auto Controller = GetController(Vehicle);
|
||||
if (Controller != nullptr) { // Sometimes fails...
|
||||
if (Controller != nullptr)
|
||||
{ // Sometimes fails...
|
||||
Controller->GetRandomEngine()->Seed(GetRandomEngine()->GenerateSeed());
|
||||
Controller->SetRoadMap(GetRoadMap());
|
||||
Controller->SetAutopilot(true);
|
||||
|
@ -118,6 +162,38 @@ void AVehicleSpawnerBase::SpawnVehicleAtSpawnPoint(
|
|||
}
|
||||
}
|
||||
|
||||
void AVehicleSpawnerBase::SpawnVehicleAttempt()
|
||||
{
|
||||
if(Vehicles.Num()>=NumberOfVehicles)
|
||||
{
|
||||
UE_LOG(LogCarla, Log, TEXT("All vehicles spawned correctly"));
|
||||
return;
|
||||
}
|
||||
|
||||
APlayerStart* spawnpoint = GetRandomSpawnPoint();
|
||||
APawn* playerpawn = UGameplayStatics::GetPlayerPawn(GetWorld(),0);
|
||||
const float DistanceToPlayer = playerpawn&&spawnpoint? FVector::Distance(playerpawn->GetActorLocation(),spawnpoint->GetActorLocation()):0.0f;
|
||||
float NextTime = TimeBetweenSpawnAttemptsAfterBegin;
|
||||
if(DistanceToPlayer>DistanceToPlayerBetweenSpawnAttemptsAfterBegin)
|
||||
{
|
||||
SpawnVehicleAtSpawnPoint(*spawnpoint);
|
||||
} else
|
||||
{
|
||||
NextTime /= 2.0f;
|
||||
}
|
||||
|
||||
if(Vehicles.Num()<NumberOfVehicles)
|
||||
{
|
||||
auto &timemanager = GetWorld()->GetTimerManager();
|
||||
if(AttemptTimerHandle.IsValid()) timemanager.ClearTimer(AttemptTimerHandle);
|
||||
timemanager.SetTimer(AttemptTimerHandle,this, &AVehicleSpawnerBase::SpawnVehicleAttempt,NextTime,false,-1);
|
||||
} else
|
||||
{
|
||||
UE_LOG(LogCarla, Log, TEXT("Last vehicle spawned correctly"));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
APlayerStart *AVehicleSpawnerBase::GetRandomSpawnPoint()
|
||||
{
|
||||
return (SpawnPoints.Num() > 0 ? GetRandomEngine()->PickOne(SpawnPoints) : nullptr);
|
||||
|
|
|
@ -28,6 +28,9 @@ protected:
|
|||
// Called when the game starts or when spawned
|
||||
virtual void BeginPlay() override;
|
||||
|
||||
// Called when the actor is removed from the level
|
||||
virtual void EndPlay(const EEndPlayReason::Type EndPlayReason) override;
|
||||
|
||||
UFUNCTION(BlueprintImplementableEvent)
|
||||
void SpawnVehicle(const FTransform &SpawnTransform, ACarlaWheeledVehicle *&SpawnedCharacter);
|
||||
|
||||
|
@ -57,6 +60,9 @@ public:
|
|||
{
|
||||
return RoadMap;
|
||||
}
|
||||
/** Function called to spawn another vehicle when there is not enough spawn points in the beginplay */
|
||||
UFUNCTION(Category = "Vehicle Spawner", BlueprintCallable)
|
||||
void SpawnVehicleAttempt();
|
||||
|
||||
protected:
|
||||
|
||||
|
@ -65,7 +71,7 @@ protected:
|
|||
void SpawnVehicleAtSpawnPoint(const APlayerStart &SpawnPoint);
|
||||
|
||||
UPROPERTY()
|
||||
URoadMap *RoadMap;
|
||||
URoadMap *RoadMap = nullptr;
|
||||
|
||||
/** If false, no walker will be spawned. */
|
||||
UPROPERTY(Category = "Vehicle Spawner", EditAnywhere)
|
||||
|
@ -75,9 +81,22 @@ protected:
|
|||
UPROPERTY(Category = "Vehicle Spawner", EditAnywhere, meta = (EditCondition = bSpawnVehicles, ClampMin = "1"))
|
||||
int32 NumberOfVehicles = 10;
|
||||
|
||||
UPROPERTY(Category = "Vechicle Spawner", VisibleAnywhere, AdvancedDisplay)
|
||||
UPROPERTY(Category = "Vehicle Spawner", VisibleAnywhere, AdvancedDisplay)
|
||||
TArray<APlayerStart *> SpawnPoints;
|
||||
|
||||
UPROPERTY(Category = "Vehicle Spawner", BlueprintReadOnly, VisibleAnywhere, AdvancedDisplay)
|
||||
TArray<ACarlaWheeledVehicle *> Vehicles;
|
||||
|
||||
/** Time to spawn new vehicles after begin play if there was not enough spawn points at the moment */
|
||||
UPROPERTY(Category = "Vehicle Spawner", BlueprintReadWrite, EditAnywhere, meta = (ClampMin = "0.1", ClampMax = "1000.0", UIMin = "0.1", UIMax = "1000.0"))
|
||||
float TimeBetweenSpawnAttemptsAfterBegin = 3.0f;
|
||||
|
||||
/** Min Distance to the player vehicle to validate a spawn point location for the next vehicle spawn attempt */
|
||||
UPROPERTY(Category = "Vehicle Spawner", BlueprintReadWrite, EditAnywhere, meta = (ClampMin = "10", ClampMax = "10000", UIMin = "10", UIMax = "10000"))
|
||||
float DistanceToPlayerBetweenSpawnAttemptsAfterBegin = 5000;
|
||||
private:
|
||||
|
||||
/** Time handler to spawn more vehicles in the case we could not do it in the beginplay */
|
||||
FTimerHandle AttemptTimerHandle;
|
||||
|
||||
};
|
||||
|
|
|
@ -40,7 +40,7 @@ static bool IsThereAnObstacleAhead(
|
|||
const FVector &Direction)
|
||||
{
|
||||
const auto ForwardVector = Vehicle.GetVehicleOrientation();
|
||||
const auto VehicleBounds = Vehicle.GetVehicleBoundsExtent();
|
||||
const auto VehicleBounds = Vehicle.GetVehicleBoundingBoxExtent();
|
||||
|
||||
const float Distance = std::max(50.0f, Speed * Speed); // why?
|
||||
|
||||
|
@ -250,7 +250,7 @@ float AWheeledVehicleAIController::GoToNextTargetLocation(FVector &Direction)
|
|||
float AWheeledVehicleAIController::CalcStreeringValue(FVector &direction)
|
||||
{
|
||||
float steering = 0;
|
||||
FVector BoxExtent = Vehicle->GetVehicleBoundsExtent();
|
||||
FVector BoxExtent = Vehicle->GetVehicleBoundingBoxExtent();
|
||||
FVector forward = Vehicle->GetActorForwardVector();
|
||||
|
||||
FVector rightSensorPosition(BoxExtent.X / 2.0f, (BoxExtent.Y / 2.0f) + 100.0f, 0.0f);
|
||||
|
|
|
@ -10,7 +10,6 @@
|
|||
#include "Navigation/CrowdFollowingComponent.h"
|
||||
#include "Perception/AIPerceptionComponent.h"
|
||||
#include "Perception/AISenseConfig_Sight.h"
|
||||
#include "Perception/AISense_Sight.h"
|
||||
#include "WheeledVehicle.h"
|
||||
#include "WheeledVehicleMovementComponent.h"
|
||||
|
||||
|
@ -27,8 +26,8 @@ static constexpr float UPDATE_TIME_IN_SECONDS = 0.6f;
|
|||
static constexpr float PREVISION_TIME_IN_SECONDS = 5.0f;
|
||||
static constexpr float WALKER_SIGHT_RADIUS = 500.0f;
|
||||
static constexpr float WALKER_SPEED_DAMPING = 4.0f;
|
||||
static constexpr float WALKER_PERIPHERAL_VISION_ANGLE_IN_DEGREES = 155.0f;
|
||||
static constexpr float WALKER_MAX_TIME_PAUSED = 10.0f;
|
||||
static constexpr float WALKER_PERIPHERAL_VISION_ANGLE_IN_DEGREES = 130.0f;
|
||||
static constexpr float WALKER_MAX_TIME_PAUSED = 5.0f;
|
||||
static constexpr float VEHICLE_SAFETY_RADIUS = 600.0f;
|
||||
|
||||
|
||||
|
@ -176,11 +175,13 @@ void AWalkerAIController::Tick(float DeltaSeconds)
|
|||
{
|
||||
Super::Tick(DeltaSeconds);
|
||||
TimeInState+=DeltaSeconds;
|
||||
if (Status != EWalkerStatus::RunOver) {
|
||||
if (Status != EWalkerStatus::RunOver)
|
||||
{
|
||||
switch (GetMoveStatus())
|
||||
{
|
||||
default: break;
|
||||
case EPathFollowingStatus::Idle:
|
||||
case EPathFollowingStatus::Waiting:
|
||||
//case EPathFollowingStatus::Waiting: //<-- incomplete path
|
||||
LOG_AI_WALKER(Warning, "is stuck!");
|
||||
ChangeStatus(EWalkerStatus::Stuck);
|
||||
break;
|
||||
|
@ -190,7 +191,8 @@ void AWalkerAIController::Tick(float DeltaSeconds)
|
|||
TryResumeMovement();
|
||||
}
|
||||
break;
|
||||
};
|
||||
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -225,7 +227,7 @@ void AWalkerAIController::OnMoveCompleted(
|
|||
ChangeStatus(EWalkerStatus::MoveCompleted);
|
||||
}
|
||||
|
||||
void AWalkerAIController::SenseActors(const TArray<AActor *> Actors)
|
||||
void AWalkerAIController::SenseActors(TArray<AActor *> Actors)
|
||||
{
|
||||
const auto *aPawn = GetPawn();
|
||||
if ((Status == EWalkerStatus::Moving) &&
|
||||
|
|
|
@ -54,6 +54,9 @@ public:
|
|||
UFUNCTION(BlueprintCallable)
|
||||
void TrySetMovement(bool paused);
|
||||
|
||||
UFUNCTION(BlueprintCallable)
|
||||
float GetTimeInState() const { return TimeInState; }
|
||||
|
||||
private:
|
||||
void ChangeStatus(EWalkerStatus status);
|
||||
void TryResumeMovement();
|
||||
|
@ -68,6 +71,6 @@ private:
|
|||
|
||||
UPROPERTY(VisibleAnywhere)
|
||||
EWalkerStatus Status = EWalkerStatus::Unknown;
|
||||
|
||||
/** Continous time in the same EWalkerStatus */
|
||||
float TimeInState=0.0f;
|
||||
};
|
||||
|
|
|
@ -10,10 +10,10 @@
|
|||
#include "Util/RandomEngine.h"
|
||||
#include "Walker/WalkerAIController.h"
|
||||
#include "Walker/WalkerSpawnPoint.h"
|
||||
|
||||
#include "Components/BoxComponent.h"
|
||||
#include "EngineUtils.h"
|
||||
#include "GameFramework/Character.h"
|
||||
#include "Kismet/KismetSystemLibrary.h"
|
||||
|
||||
// =============================================================================
|
||||
// -- Static local methods -----------------------------------------------------
|
||||
|
@ -78,14 +78,19 @@ void AWalkerSpawnerBase::BeginPlay()
|
|||
SpawnPoints.Add(SpawnPoint);
|
||||
}
|
||||
}
|
||||
#ifdef CARLA_AI_WALKERS_EXTRA_LOG
|
||||
UE_LOG(LogCarla, Log, TEXT("Found %d positions for spawning walkers at begin play."), BeginSpawnPoints.Num());
|
||||
UE_LOG(LogCarla, Log, TEXT("Found %d positions for spawning walkers during game play."), SpawnPoints.Num());
|
||||
|
||||
#endif
|
||||
if (SpawnPoints.Num() < 2) {
|
||||
bSpawnWalkers = false;
|
||||
#ifdef CARLA_AI_WALKERS_EXTRA_LOG
|
||||
UE_LOG(LogCarla, Error, TEXT("We don't have enough spawn points for walkers!"));
|
||||
#endif
|
||||
} else if (BeginSpawnPoints.Num() < NumberOfWalkers) {
|
||||
#ifdef CARLA_AI_WALKERS_EXTRA_LOG
|
||||
UE_LOG(LogCarla, Warning, TEXT("Requested %d walkers, but we only have %d spawn points. Some will fail to spawn."), NumberOfWalkers, BeginSpawnPoints.Num());
|
||||
#endif
|
||||
}
|
||||
|
||||
GetRandomEngine()->Shuffle(BeginSpawnPoints);
|
||||
|
@ -97,7 +102,9 @@ void AWalkerSpawnerBase::BeginPlay()
|
|||
++Count;
|
||||
}
|
||||
}
|
||||
#ifdef CARLA_AI_WALKERS_EXTRA_LOG
|
||||
UE_LOG(LogCarla, Log, TEXT("Spawned %d walkers at begin play."), Count);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -110,45 +117,139 @@ void AWalkerSpawnerBase::Tick(float DeltaTime)
|
|||
TryToSpawnWalkerAt(GetRandomSpawnPoint());
|
||||
}
|
||||
|
||||
if (WalkersBlackList.Num() > 0) {
|
||||
// If still stuck in the black list, just kill it.
|
||||
const int32 Index = (++CurrentIndexToCheck % WalkersBlackList.Num());
|
||||
auto Walker = WalkersBlackList[Index];
|
||||
const auto Status = GetWalkerStatus(Walker);
|
||||
if ((Status == EWalkerStatus::MoveCompleted) ||
|
||||
(Status == EWalkerStatus::Invalid) ||
|
||||
(Status == EWalkerStatus::RunOver)) {
|
||||
WalkersBlackList.RemoveAtSwap(Index);
|
||||
if ((Walker != nullptr) && (Status != EWalkerStatus::RunOver)) {
|
||||
Walker->Destroy();
|
||||
if (WalkersBlackList.Num() > 0)
|
||||
{
|
||||
CurrentBlackWalkerIndexToCheck = ++CurrentBlackWalkerIndexToCheck % WalkersBlackList.Num();
|
||||
ACharacter* BlackListedWalker = WalkersBlackList[CurrentBlackWalkerIndexToCheck];
|
||||
AWalkerAIController* controller = BlackListedWalker!=nullptr?Cast<AWalkerAIController>(BlackListedWalker->GetController()):nullptr;
|
||||
if(BlackListedWalker != nullptr && controller!=nullptr && IsValid(BlackListedWalker))
|
||||
{
|
||||
const auto Status = GetWalkerStatus(BlackListedWalker);
|
||||
#ifdef CARLA_AI_WALKERS_EXTRA_LOG
|
||||
UE_LOG(LogCarla, Log, TEXT("Watching walker %s with state %d"), *UKismetSystemLibrary::GetDisplayName(BlackListedWalker), (int)Status);
|
||||
#endif
|
||||
switch(Status)
|
||||
{
|
||||
case EWalkerStatus::RunOver:{
|
||||
//remove from list and wait for auto-destroy
|
||||
WalkersBlackList.RemoveAtSwap(CurrentBlackWalkerIndexToCheck);
|
||||
break;
|
||||
}
|
||||
case EWalkerStatus::MoveCompleted:
|
||||
{
|
||||
BlackListedWalker->Destroy();
|
||||
break;
|
||||
}
|
||||
default: {
|
||||
switch(controller->GetMoveStatus())
|
||||
{
|
||||
case EPathFollowingStatus::Idle:
|
||||
if(!TrySetDestination(*BlackListedWalker))
|
||||
{
|
||||
if(!SetRandomWalkerDestination(BlackListedWalker))
|
||||
{
|
||||
#ifdef CARLA_AI_WALKERS_EXTRA_LOG
|
||||
UE_LOG(LogCarla,Error,TEXT("Could not set a random destination to walker %s"),*UKismetSystemLibrary::GetDisplayName(BlackListedWalker));
|
||||
#endif
|
||||
}
|
||||
}
|
||||
break;
|
||||
case EPathFollowingStatus::Waiting:
|
||||
//incomplete path
|
||||
break;
|
||||
case EPathFollowingStatus::Paused:
|
||||
//waiting for blueprint code
|
||||
break;
|
||||
case EPathFollowingStatus::Moving:
|
||||
if(BlackListedWalker->GetVelocity().Size()>1.0f)
|
||||
{
|
||||
WalkersBlackList.RemoveAtSwap(CurrentBlackWalkerIndexToCheck);
|
||||
Walkers.Add(BlackListedWalker);
|
||||
}
|
||||
break;
|
||||
default: break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
#ifdef CARLA_AI_WALKERS_EXTRA_LOG
|
||||
UE_LOG(LogCarla, Log, TEXT("New state for walker %s : %d"), *UKismetSystemLibrary::GetDisplayName(BlackListedWalker), (int)GetWalkerStatus(BlackListedWalker));
|
||||
#endif
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if (Walkers.Num() > 0) {
|
||||
if (Walkers.Num() > 0)
|
||||
{
|
||||
// Check one walker, if fails black-list it or kill it.
|
||||
const int32 Index = (++CurrentIndexToCheck % Walkers.Num());
|
||||
auto Walker = Walkers[Index];
|
||||
const auto Status = GetWalkerStatus(Walker);
|
||||
|
||||
if ((Status == EWalkerStatus::MoveCompleted) ||
|
||||
(Status == EWalkerStatus::Invalid) ||
|
||||
(Status == EWalkerStatus::RunOver)) {
|
||||
// Kill it.
|
||||
Walkers.RemoveAtSwap(Index);
|
||||
// If it was run over will self-destroy.
|
||||
if ((Walker != nullptr) && (Status != EWalkerStatus::RunOver)) {
|
||||
Walker->Destroy();
|
||||
}
|
||||
} else if (Status == EWalkerStatus::Stuck) {
|
||||
// Black-list it.
|
||||
TrySetDestination(*Walker);
|
||||
WalkersBlackList.Add(Walker);
|
||||
Walkers.RemoveAtSwap(Index);
|
||||
CurrentWalkerIndexToCheck = ++CurrentWalkerIndexToCheck % Walkers.Num();
|
||||
auto Walker = Walkers[CurrentWalkerIndexToCheck];
|
||||
if(Walker == nullptr || !IsValid(Walker))
|
||||
{
|
||||
Walkers.RemoveAtSwap(CurrentWalkerIndexToCheck);
|
||||
} else {
|
||||
const auto Status = GetWalkerStatus(Walker);
|
||||
switch (Status)
|
||||
{
|
||||
default:
|
||||
case EWalkerStatus::Paused:
|
||||
case EWalkerStatus::Unknown:
|
||||
break;
|
||||
case EWalkerStatus::RunOver: {
|
||||
Walkers.RemoveAtSwap(CurrentWalkerIndexToCheck);
|
||||
break;
|
||||
}
|
||||
case EWalkerStatus::MoveCompleted:
|
||||
Walker->Destroy();
|
||||
break;
|
||||
case EWalkerStatus::Invalid:
|
||||
case EWalkerStatus::Stuck:
|
||||
{
|
||||
SetRandomWalkerDestination(Walker);
|
||||
// Black-list it and wait for this walker to move
|
||||
WalkersBlackList.Add(Walker);
|
||||
Walkers.RemoveAtSwap(CurrentWalkerIndexToCheck);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool AWalkerSpawnerBase::SetRandomWalkerDestination(ACharacter *Walker)
|
||||
{
|
||||
const auto &DestinationPoint = GetRandomSpawnPoint();
|
||||
auto Controller = GetController(Walker);
|
||||
if(!Controller) {
|
||||
#ifdef CARLA_AI_WALKERS_EXTRA_LOG
|
||||
UE_LOG(LogCarla, Warning, TEXT("AWalkerSpawnerBase::SetRandomWalkerDestination: Walker %s has no controller"),
|
||||
*UKismetSystemLibrary::GetDisplayName(Walker)
|
||||
);
|
||||
#endif
|
||||
return false;
|
||||
}
|
||||
const EPathFollowingRequestResult::Type request_result = Controller->MoveToLocation(DestinationPoint.GetActorLocation(),-1.0f,false,true,true,true,nullptr,true);
|
||||
switch(request_result)
|
||||
{
|
||||
case EPathFollowingRequestResult::Type::Failed:
|
||||
{
|
||||
#ifdef CARLA_AI_WALKERS_EXTRA_LOG
|
||||
UE_LOG(LogCarla, Warning, TEXT("AWalkerSpawnerBase::SetRandomWalkerDestination: Bad destination point %s"),
|
||||
*UKismetSystemLibrary::GetDisplayName(&DestinationPoint)
|
||||
);
|
||||
#endif
|
||||
return false;
|
||||
}
|
||||
case EPathFollowingRequestResult::Type::AlreadyAtGoal:{
|
||||
#ifdef CARLA_AI_WALKERS_EXTRA_LOG
|
||||
UE_LOG(LogCarla, Log, TEXT("AWalkerSpawnerBase::SetRandomWalkerDestination already in destination, generating new location"));
|
||||
#endif
|
||||
return SetRandomWalkerDestination(Walker);
|
||||
}
|
||||
default: case EPathFollowingRequestResult::Type::RequestSuccessful: return true;
|
||||
}
|
||||
}
|
||||
|
||||
// =============================================================================
|
||||
// -- Other member functions ---------------------------------------------------
|
||||
// =============================================================================
|
||||
|
@ -205,7 +306,10 @@ bool AWalkerSpawnerBase::TryToSpawnWalkerAt(const AWalkerSpawnPointBase &SpawnPo
|
|||
|
||||
// Add walker and set destination.
|
||||
Walkers.Add(Walker);
|
||||
Controller->MoveToLocation(Destination);
|
||||
if (Controller->MoveToLocation(Destination,-1.0f,false,true,true,true,nullptr,true)!=EPathFollowingRequestResult::Type::RequestSuccessful)
|
||||
{
|
||||
SetRandomWalkerDestination(Walker);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -214,15 +318,22 @@ bool AWalkerSpawnerBase::TrySetDestination(ACharacter &Walker)
|
|||
// Try to retrieve controller.
|
||||
auto Controller = GetController(&Walker);
|
||||
if (Controller == nullptr) {
|
||||
UE_LOG(LogCarla, Warning, TEXT("Could not get valid controller for walker: %s"), *Walker.GetName());
|
||||
return false;
|
||||
}
|
||||
|
||||
// Try find destination.
|
||||
FVector Destination;
|
||||
if (!TryGetValidDestination(Walker.GetActorLocation(), Destination)) {
|
||||
#ifdef CARLA_AI_WALKERS_EXTRA_LOG
|
||||
UE_LOG(
|
||||
LogCarla, Warning,
|
||||
TEXT("Could not get a new destiny: %s for walker: %s"),
|
||||
*Destination.ToString(), *Walker.GetName()
|
||||
);
|
||||
#endif
|
||||
return false;
|
||||
}
|
||||
|
||||
Controller->MoveToLocation(Destination);
|
||||
return true;
|
||||
return Controller->MoveToLocation(Destination,-1.0f,false,true,true,true,nullptr,true)==EPathFollowingRequestResult::RequestSuccessful;
|
||||
}
|
||||
|
|
|
@ -45,6 +45,7 @@ public:
|
|||
|
||||
virtual void Tick(float DeltaTime) override;
|
||||
|
||||
|
||||
/// @}
|
||||
// ===========================================================================
|
||||
/// @name Blueprintable functions
|
||||
|
@ -87,6 +88,7 @@ private:
|
|||
|
||||
bool TrySetDestination(ACharacter &Walker);
|
||||
|
||||
bool SetRandomWalkerDestination(ACharacter * Walker);
|
||||
/// @}
|
||||
|
||||
private:
|
||||
|
@ -116,5 +118,7 @@ private:
|
|||
UPROPERTY(Category = "Walker Spawner", VisibleAnywhere, AdvancedDisplay)
|
||||
TArray<ACharacter *> WalkersBlackList;
|
||||
|
||||
uint32 CurrentIndexToCheck = 0u;
|
||||
uint32 CurrentWalkerIndexToCheck = 0u;
|
||||
|
||||
uint32 CurrentBlackWalkerIndexToCheck = 0u;
|
||||
};
|
||||
|
|
|
@ -43,6 +43,11 @@ extern "C" {
|
|||
struct carla_rotation3d rotation;
|
||||
};
|
||||
|
||||
struct carla_bounding_box {
|
||||
struct carla_transform transform;
|
||||
struct carla_vector3d extent;
|
||||
};
|
||||
|
||||
/* ======================================================================== */
|
||||
/* -- agents -------------------------------------------------------------- */
|
||||
/* ======================================================================== */
|
||||
|
@ -66,7 +71,7 @@ extern "C" {
|
|||
uint32_t id;
|
||||
uint32_t type;
|
||||
struct carla_transform transform;
|
||||
struct carla_vector3d box_extent;
|
||||
struct carla_bounding_box bounding_box;
|
||||
float forward_speed;
|
||||
};
|
||||
|
||||
|
@ -159,8 +164,8 @@ extern "C" {
|
|||
struct carla_player_measurements {
|
||||
/** World transform of the player. */
|
||||
struct carla_transform transform;
|
||||
/** Extent of the bounding box of the player. */
|
||||
struct carla_vector3d box_extent;
|
||||
/** Bounding box of the player. */
|
||||
struct carla_bounding_box bounding_box;
|
||||
/** Current acceleration of the player. */
|
||||
struct carla_vector3d acceleration;
|
||||
/** Forward speed in m/s. */
|
||||
|
@ -184,6 +189,8 @@ extern "C" {
|
|||
/* ======================================================================== */
|
||||
|
||||
struct carla_measurements {
|
||||
/** Frame counter. */
|
||||
uint32_t frame_number;
|
||||
/** Time-stamp of the current frame, in milliseconds as given by the OS. */
|
||||
uint32_t platform_timestamp;
|
||||
/** In-game time-stamp, milliseconds elapsed since the beginning of the current level. */
|
||||
|
|
|
@ -54,6 +54,12 @@ namespace server {
|
|||
Set(lhs->mutable_rotation(), rhs.rotation);
|
||||
}
|
||||
|
||||
static void Set(cs::BoundingBox *lhs, const carla_bounding_box &rhs) {
|
||||
DEBUG_ASSERT(lhs != nullptr);
|
||||
Set(lhs->mutable_transform(), rhs.transform);
|
||||
Set(lhs->mutable_extent(), rhs.extent);
|
||||
}
|
||||
|
||||
static void Set(cs::Sensor *lhs, const carla_sensor_definition &rhs) {
|
||||
DEBUG_ASSERT(lhs != nullptr);
|
||||
lhs->set_id(rhs.id);
|
||||
|
@ -79,14 +85,14 @@ namespace server {
|
|||
static void SetVehicle(cs::Vehicle *lhs, const carla_agent &rhs) {
|
||||
DEBUG_ASSERT(lhs != nullptr);
|
||||
Set(lhs->mutable_transform(), rhs.transform);
|
||||
Set(lhs->mutable_box_extent(), rhs.box_extent);
|
||||
Set(lhs->mutable_bounding_box(), rhs.bounding_box);
|
||||
lhs->set_forward_speed(rhs.forward_speed);
|
||||
}
|
||||
|
||||
static void SetPedestrian(cs::Pedestrian *lhs, const carla_agent &rhs) {
|
||||
DEBUG_ASSERT(lhs != nullptr);
|
||||
Set(lhs->mutable_transform(), rhs.transform);
|
||||
Set(lhs->mutable_box_extent(), rhs.box_extent);
|
||||
Set(lhs->mutable_bounding_box(), rhs.bounding_box);
|
||||
lhs->set_forward_speed(rhs.forward_speed);
|
||||
}
|
||||
|
||||
|
@ -149,13 +155,14 @@ namespace server {
|
|||
std::string CarlaEncoder::Encode(const carla_measurements &values) {
|
||||
static thread_local auto *message = _protobuf.CreateMessage<cs::Measurements>();
|
||||
DEBUG_ASSERT(message != nullptr);
|
||||
message->set_frame_number(values.frame_number);
|
||||
message->set_platform_timestamp(values.platform_timestamp);
|
||||
message->set_game_timestamp(values.game_timestamp);
|
||||
// Player measurements.
|
||||
auto *player = message->mutable_player_measurements();
|
||||
DEBUG_ASSERT(player != nullptr);
|
||||
Set(player->mutable_transform(), values.player_measurements.transform);
|
||||
Set(player->mutable_box_extent(), values.player_measurements.box_extent);
|
||||
Set(player->mutable_bounding_box(), values.player_measurements.bounding_box);
|
||||
Set(player->mutable_acceleration(), values.player_measurements.acceleration);
|
||||
player->set_forward_speed(values.player_measurements.forward_speed);
|
||||
player->set_collision_vehicles(values.player_measurements.collision_vehicles);
|
||||
|
|
|
@ -17,11 +17,12 @@ namespace test {
|
|||
std::lock_guard<std::mutex> lock(_mutex);
|
||||
|
||||
const struct {
|
||||
uint64_t FrameNumber;
|
||||
uint32_t Width;
|
||||
uint32_t Height;
|
||||
uint32_t Type;
|
||||
float FOV;
|
||||
} ImageHeader = {300u, 200u, 1u, 90.0f};
|
||||
} ImageHeader = {++_frame_number, 300u, 200u, 1u, 90.0f};
|
||||
|
||||
_data.header_size = sizeof(ImageHeader);
|
||||
auto header = std::make_unique<unsigned char[]>(_data.header_size);
|
||||
|
|
|
@ -34,6 +34,8 @@ namespace test {
|
|||
|
||||
Sensor(uint32_t id);
|
||||
|
||||
uint64_t _frame_number = 0u;
|
||||
|
||||
mutable std::mutex _mutex;
|
||||
|
||||
const std::string _name;
|
||||
|
|
|
@ -106,7 +106,7 @@ TEST(CarlaServerAPI, SimBlocking) {
|
|||
agents_data[i].id = i;
|
||||
agents_data[i].type = CARLA_SERVER_AGENT_VEHICLE;
|
||||
agents_data[i].transform = start_locations[0u];
|
||||
agents_data[i].box_extent = {100.0f, 100.0f, 100.0f};
|
||||
agents_data[i].bounding_box = {start_locations[0u], {100.0f, 100.0f, 100.0f}};
|
||||
agents_data[i].forward_speed = 50.0f;
|
||||
}
|
||||
|
||||
|
|
|
@ -10,3 +10,4 @@
|
|||
0.7.1: 1gf3YaFIjwr1EaK6qxq2V-a510Brt9Imq
|
||||
0.8.0: 1tA-WwKA0RNhBoENYunqF3-F_wg11dL86
|
||||
0.8.1: 1su5wQH7KJphAcirMA8VEDLndGigQ9tzq
|
||||
Latest: 17Fi8DYdNkBJ5AIsh_uUbUPdD-XeVlTf9
|
||||
|
|
|
@ -32,6 +32,11 @@ message Transform {
|
|||
Rotation3D rotation = 3;
|
||||
}
|
||||
|
||||
message BoundingBox {
|
||||
Transform transform = 1;
|
||||
Vector3D extent = 2;
|
||||
}
|
||||
|
||||
// =============================================================================
|
||||
// -- Sensors ------------------------------------------------------------------
|
||||
// =============================================================================
|
||||
|
@ -54,13 +59,13 @@ message Sensor {
|
|||
|
||||
message Vehicle {
|
||||
Transform transform = 1;
|
||||
Vector3D box_extent = 2;
|
||||
BoundingBox bounding_box = 4;
|
||||
float forward_speed = 3;
|
||||
}
|
||||
|
||||
message Pedestrian {
|
||||
Transform transform = 1;
|
||||
Vector3D box_extent = 2;
|
||||
BoundingBox bounding_box = 4;
|
||||
float forward_speed = 3;
|
||||
}
|
||||
|
||||
|
@ -126,7 +131,7 @@ message Measurements {
|
|||
message PlayerMeasurements {
|
||||
Transform transform = 1;
|
||||
|
||||
Vector3D box_extent = 11;
|
||||
BoundingBox bounding_box = 12;
|
||||
|
||||
Vector3D acceleration = 3;
|
||||
float forward_speed = 4;
|
||||
|
@ -141,6 +146,8 @@ message Measurements {
|
|||
Control autopilot_control = 10;
|
||||
}
|
||||
|
||||
uint64 frame_number = 5;
|
||||
|
||||
uint32 platform_timestamp = 1;
|
||||
|
||||
uint32 game_timestamp = 2;
|
||||
|
|
Loading…
Reference in New Issue