Sensor Sincronization
Added script as an example to syncronize all gathering of sensor data in the client. Co-authored-by: Marc Garcia Puig <marcgpuig@gmail.com>
This commit is contained in:
parent
9430d7e6f3
commit
66a123e2e3
|
@ -0,0 +1,137 @@
|
|||
#!/usr/bin/env python
|
||||
|
||||
# Copyright (c) 2020 Computer Vision Center (CVC) at the Universitat Autonoma de
|
||||
# Barcelona (UAB).
|
||||
#
|
||||
# This work is licensed under the terms of the MIT license.
|
||||
# For a copy, see <https://opensource.org/licenses/MIT>.
|
||||
|
||||
"""
|
||||
Sensor synchronization example for CARLA
|
||||
|
||||
The communication model for the syncronous mode in CARLA sends the snapshot
|
||||
of the world and the sensors streams in parallel.
|
||||
We provide this script as an example of how to syncrononize the sensor
|
||||
data gathering in the client.
|
||||
To to this, we create a queue that is being filled by every sensor when the
|
||||
client receives its data and the main loop is blocked until all the sensors
|
||||
have received its data.
|
||||
This suppose that all the sensors gather information at every tick. It this is
|
||||
not the case, the clients needs to take in account at each frame how many
|
||||
sensors are going to tick at each frame.
|
||||
"""
|
||||
|
||||
import glob
|
||||
import os
|
||||
import sys
|
||||
from queue import Queue
|
||||
from queue import Empty
|
||||
|
||||
try:
|
||||
sys.path.append(glob.glob('../carla/dist/carla-*%d.%d-%s.egg' % (
|
||||
sys.version_info.major,
|
||||
sys.version_info.minor,
|
||||
'win-amd64' if os.name == 'nt' else 'linux-x86_64'))[0])
|
||||
except IndexError:
|
||||
pass
|
||||
|
||||
import carla
|
||||
|
||||
|
||||
# Sensor callback.
|
||||
# This is where you receive the sensor data and
|
||||
# process it as you liked and the important part is that,
|
||||
# at the end, it should include an element into the sensor queue.
|
||||
def sensor_callback(sensor_data, sensor_queue, sensor_name):
|
||||
# Do stuff with the sensor_data data like save it to disk
|
||||
# Then you just need to add to the queue
|
||||
sensor_queue.put((sensor_data.frame, sensor_name))
|
||||
|
||||
|
||||
def main():
|
||||
# We start creating the client
|
||||
client = carla.Client('localhost', 2000)
|
||||
client.set_timeout(2.0)
|
||||
world = client.get_world()
|
||||
|
||||
try:
|
||||
# We need to save the settings to be able to recover them at the end
|
||||
# of the script to leave the server in the same state that we found it.
|
||||
original_settings = world.get_settings()
|
||||
settings = world.get_settings()
|
||||
|
||||
# We set CARLA syncronous mode
|
||||
settings.fixed_delta_seconds = 0.2
|
||||
settings.synchronous_mode = True
|
||||
world.apply_settings(settings)
|
||||
|
||||
# We create the sensor queue in which we keep track of the information
|
||||
# already received. This structure is thread safe and can be
|
||||
# accessed by all the sensors callback concurrently without problem.
|
||||
sensor_queue = Queue()
|
||||
|
||||
# Bluepints for the sensors
|
||||
blueprint_library = world.get_blueprint_library()
|
||||
cam_bp = blueprint_library.find('sensor.camera.rgb')
|
||||
lidar_bp = blueprint_library.find('sensor.lidar.ray_cast')
|
||||
radar_bp = blueprint_library.find('sensor.other.radar')
|
||||
|
||||
|
||||
# We create all the sensors and keep them in a list for convenience.
|
||||
sensor_list = []
|
||||
|
||||
cam01 = world.spawn_actor(cam_bp, carla.Transform())
|
||||
cam01.listen(lambda data: sensor_callback(data, sensor_queue, "camera01"))
|
||||
sensor_list.append(cam01)
|
||||
|
||||
lidar_bp.set_attribute('points_per_second', '100000')
|
||||
lidar01 = world.spawn_actor(lidar_bp, carla.Transform())
|
||||
lidar01.listen(lambda data: sensor_callback(data, sensor_queue, "lidar01"))
|
||||
sensor_list.append(lidar01)
|
||||
|
||||
lidar_bp.set_attribute('points_per_second', '1000000')
|
||||
lidar02 = world.spawn_actor(lidar_bp, carla.Transform())
|
||||
lidar02.listen(lambda data: sensor_callback(data, sensor_queue, "lidar02"))
|
||||
sensor_list.append(lidar02)
|
||||
|
||||
radar01 = world.spawn_actor(radar_bp, carla.Transform())
|
||||
radar01.listen(lambda data: sensor_callback(data, sensor_queue, "radar01"))
|
||||
sensor_list.append(radar01)
|
||||
|
||||
radar02 = world.spawn_actor(radar_bp, carla.Transform())
|
||||
radar02.listen(lambda data: sensor_callback(data, sensor_queue, "radar02"))
|
||||
sensor_list.append(radar02)
|
||||
|
||||
# Main loop
|
||||
while True:
|
||||
# Tick the server
|
||||
world.tick()
|
||||
w_frame = world.get_snapshot().frame
|
||||
print("\nWorld's frame: %d" % w_frame)
|
||||
|
||||
# Now, we wait to the sensors data to be received.
|
||||
# As the queue is blocking, we will wait in the queue.get() methods
|
||||
# until all the information is processed and we continue with the next frame.
|
||||
# We include a timeout of 1.0 s (in the get method) and if some information is
|
||||
# not received in this time we continue.
|
||||
try:
|
||||
for i in range (0, len(sensor_list)):
|
||||
s_frame = sensor_queue.get(True, 1.0)
|
||||
print(" Frame: %d Sensor: %s" % (s_frame[0], s_frame[1]))
|
||||
|
||||
except Empty:
|
||||
print(" Some of the sensor information is missed")
|
||||
|
||||
|
||||
finally:
|
||||
world.apply_settings(original_settings)
|
||||
for sensor in sensor_list:
|
||||
sensor.destroy()
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
try:
|
||||
main()
|
||||
except KeyboardInterrupt:
|
||||
print(' - Exited by user.')
|
||||
|
Loading…
Reference in New Issue