Created
June 27, 2019 14:40
-
-
Save nsubiron/b6effce218e10a855a1674fb74bc135c to your computer and use it in GitHub Desktop.
Example of context manager to ease working with CARLA Simulator in synchronous mode.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# Example of context manager to ease working with CARLA Simulator in synchronous | |
# mode. Creates an object that synchronizes the data of every sensor. | |
# ============================================================================== | |
# -- Usage example ------------------------------------------------------------- | |
# ============================================================================== | |
import carla | |
def usage_example(): | |
client = carla.Client('localhost', 2000) | |
world = client.get_world() | |
sensors = [] | |
try: | |
sensors.append(world.spawn_actor( | |
world.get_blueprint_library().find('sensor.camera.rgb'), | |
carla.Transform())) | |
sensors.append(world.spawn_actor( | |
world.get_blueprint_library().find('sensor.camera.depth'), | |
carla.Transform())) | |
sensors.append(world.spawn_actor( | |
world.get_blueprint_library().find('sensor.camera.semantic_segmentation'), | |
carla.Transform())) | |
sensors.append(world.spawn_actor( | |
world.get_blueprint_library().find('sensor.lidar.ray_cast'), | |
carla.Transform())) | |
# Create a context in which the synchronous mode is enabled. | |
with CarlaSyncMode(world, *sensors) as sync_mode: | |
while True: | |
# The returned object has a "tick" method that advances the | |
# simulation one frame and returns the data of all the sensors | |
# generated during that frame. | |
data = sync_mode.tick(timeout=1.0) | |
# The first element is a "carla.WorldSnapshot" containing the | |
# transforms, velocities, etc. of every object in the world at | |
# that precise frame. | |
snapshot = data[0] | |
# The rest of elements in the list are the different data | |
# objects generated by the sensors; images, point-cloud, etc. | |
for n, item in enumerate(data[1:]): | |
item.save_to_disk('_out/%01d_%08d' % (n, sync_mode.frame)) | |
finally: | |
for sensor in sensors: | |
sensor.destroy() | |
# ============================================================================== | |
# -- CarlaSyncMode Context Manager --------------------------------------------- | |
# ============================================================================== | |
import carla | |
try: | |
import queue | |
except ImportError: | |
import Queue as queue | |
class CarlaSyncMode(object): | |
def __init__(self, world, *sensors): | |
self.world = world | |
self.sensors = sensors | |
self.frame = None | |
self._queues = [] | |
def __enter__(self): | |
settings = self.world.get_settings() | |
settings.synchronous_mode = True | |
self._sync(self.world.apply_settings(settings)) | |
def make_queue(register_event): | |
q = queue.Queue() | |
register_event(q.put) | |
self._queues.append(q) | |
make_queue(self.world.on_tick) | |
for sensor in self.sensors: | |
make_queue(sensor.listen) | |
return self | |
def tick(self, timeout): | |
self._sync(self.world.tick()) | |
data = [self._retrieve_data(q, timeout) for q in self._queues] | |
assert all(x.frame == self.frame for x in data) | |
return data | |
def __exit__(self, type, value, traceback): | |
settings = self.world.get_settings() | |
settings.synchronous_mode = False | |
self.world.apply_settings(settings) | |
def _sync(self, frame): | |
while frame > self.world.get_snapshot().timestamp.frame: | |
pass | |
assert frame == self.world.get_snapshot().timestamp.frame | |
self.frame = frame | |
def _retrieve_data(self, queue, timeout): | |
while True: | |
data = queue.get(timeout=timeout) | |
if data.frame == self.frame: | |
return data |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment