Update client to new sensor interface

This commit is contained in:
nsubiron 2018-02-24 19:13:12 +01:00
parent 33c6d06ed0
commit 2da42dae40
9 changed files with 220 additions and 305 deletions

View File

@ -138,7 +138,7 @@ class CoRL2017(Benchmark):
# This single RGB camera is used on every experiment
camera = Camera('CameraRGB')
camera.set(CameraFOV=100)
camera.set(FOV=100)
camera.set_image_size(800, 600)

View File

@ -11,7 +11,6 @@ import struct
from contextlib import contextmanager
from . import sensor
from . import settings
from . import tcp
from . import util
@ -20,6 +19,11 @@ try:
except ImportError:
raise RuntimeError('cannot import "carla_server_pb2.py", run the protobuf compiler to generate this file')
try:
import numpy
except ImportError:
raise RuntimeError('cannot import numpy, make sure numpy package is installed.')
VehicleControl = carla_protocol.Control
@ -40,7 +44,7 @@ class CarlaClient(object):
self._control_client = tcp.TCPClient(host, world_port + 2, timeout)
self._current_settings = None
self._is_episode_requested = False
self._sensor_names = []
self._sensors = {}
def connect(self, connection_attempts=10):
"""
@ -69,7 +73,6 @@ class CarlaClient(object):
self._current_settings = carla_settings
return self._request_new_episode(carla_settings)
def start_episode(self, player_start_index):
"""
Start the new episode at the player start given by the
@ -120,8 +123,7 @@ class CarlaClient(object):
pb_message = carla_protocol.Measurements()
pb_message.ParseFromString(data)
# Read sensor data.
raw_sensor_data = self._stream_client.read()
return pb_message, self._parse_raw_sensor_data(raw_sensor_data)
return pb_message, dict(x for x in self._read_sensor_data())
def send_control(self, *args, **kwargs):
"""
@ -159,40 +161,66 @@ class CarlaClient(object):
raise RuntimeError('failed to read data from server')
pb_message = carla_protocol.SceneDescription()
pb_message.ParseFromString(data)
self._sensor_names = settings.get_sensor_names(carla_settings)
self._sensors = dict((sensor.id, sensor) \
for sensor in _make_sensor_parsers(pb_message.sensors))
self._is_episode_requested = True
return pb_message
def _parse_raw_sensor_data(self, raw_data):
"""Return a dict of {'sensor_name': sensor_data, ...}."""
return dict((name, data) for name, data in zip(
self._sensor_names,
self._iterate_sensor_data(raw_data)))
def _read_sensor_data(self):
while True:
data = self._stream_client.read()
if not data:
raise StopIteration
yield self._parse_sensor_data(data)
@staticmethod
def _iterate_sensor_data(raw_data):
image_types = ['None', 'SceneFinal', 'Depth', 'SemanticSegmentation', 'Lidar']
gettype = lambda id: image_types[id] if len(image_types) > id else 'Unknown'
getint = lambda index: struct.unpack('<L', raw_data[index*4:index*4+4])[0]
getfloat = lambda index: struct.unpack('<f', raw_data[index*4:index*4+4])[0]
getdouble = lambda index: struct.unpack('<d', raw_data[index*4:index*4+8])[0]
total_size = len(raw_data) / 4
index = 0
while index < total_size:
sensor_type = gettype(getint(index + 2))
if sensor_type == 'Lidar':
horizontal_angle = getdouble(index)
channels_count = getint(index + 3)
lm = sensor.LidarMeasurement(
horizontal_angle, channels_count,
sensor_type, raw_data[index*4:])
index += lm.size_in_bytes
yield lm
else:
width = getint(index)
height = getint(index + 1)
fov = getfloat(index + 3)
begin = index + 4
end = begin + width * height
index = end
yield sensor.Image(width, height, sensor_type, fov, raw_data[begin*4:end*4])
def _parse_sensor_data(self, data):
sensor_id = struct.unpack('<L', data[0:4])[0]
parser = self._sensors[sensor_id]
return parser.name, parser.parse_raw_data(data[4:])
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]
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:])
def parse_lidar(data):
horizontal_angle = getfloat(data, 0)
channels_count = getint(data, 1)
points_count_by_channel = numpy.frombuffer(
data[8:8+channels_count*4],
dtype=numpy.dtype('uint32'))
points = numpy.frombuffer(
data[8+channels_count*4:],
dtype=numpy.dtype('f4'))
points = numpy.reshape(points, (int(points.shape[0]/3), 3))
return sensor.LidarMeasurement(
horizontal_angle,
channels_count,
points_count_by_channel,
sensor.PointCloud(points))
class SensorDefinition(object):
def __init__(self, s):
self.id = s.id
self.name = s.name
self.type = s.type
self.parse_raw_data = lambda x: x
for s in sensors:
sensor_def = SensorDefinition(s)
if sensor_def.type == carla_protocol.Sensor.UNKNOWN:
pass
elif sensor_def.type == carla_protocol.Sensor.LIDAR_RAY_TRACE:
sensor_def.parse_raw_data = parse_lidar
else:
sensor_def.parse_raw_data = parse_image
yield sensor_def

View File

@ -13,8 +13,7 @@ import os
try:
import numpy
except ImportError:
raise RuntimeError(
'cannot import numpy, make sure numpy package is installed.')
raise RuntimeError('cannot import numpy, make sure numpy package is installed.')
from collections import namedtuple
from .transform import Transform, Translation, Rotation, Scale
@ -42,12 +41,51 @@ class Sensor(object):
Base class for sensor descriptions. Used to add sensors to CarlaSettings.
"""
def __init__(self, name, sensor_type):
self.SensorName = name
self.SensorType = sensor_type
self.PositionX = 140
self.PositionY = 0
self.PositionZ = 140
self.RotationPitch = 0
self.RotationRoll = 0
self.RotationYaw = 0
def set(self, **kwargs):
for key, value in kwargs.items():
if not hasattr(self, key):
raise ValueError('CarlaSettings.Camera: no key named %r' % key)
raise ValueError('sensor.Sensor: no key named %r' % key)
setattr(self, key, value)
def set_position(self, x, y, z):
self.PositionX = x
self.PositionY = y
self.PositionZ = z
def set_rotation(self, pitch, yaw, roll):
self.RotationPitch = pitch
self.RotationYaw = yaw
self.RotationRoll = roll
def get_transform(self):
'''
Returns the camera to [whatever the camera is attached to]
transformation.
'''
return Transform(
Translation(self.PositionX, self.PositionY, self.PositionZ),
Rotation(self.RotationPitch, self.RotationYaw, self.RotationRoll))
def get_unreal_transform(self):
'''
Returns the camera to [whatever the camera is attached to]
transformation with the Unreal necessary corrections applied.
@todo Do we need to expose this?
'''
to_unreal_transform = Transform(Rotation(roll=-90, yaw=90), Scale(x=-1))
return self.get_transform() * to_unreal_transform
class Camera(Sensor):
"""
@ -56,17 +94,11 @@ class Camera(Sensor):
"""
def __init__(self, name, **kwargs):
self.CameraName = name
super(Camera, self).__init__(name, sensor_type="CAMERA")
self.PostProcessing = 'SceneFinal'
self.ImageSizeX = 800
self.ImageSizeY = 600
self.CameraFOV = 90
self.CameraPositionX = 140
self.CameraPositionY = 0
self.CameraPositionZ = 140
self.CameraRotationPitch = 0
self.CameraRotationRoll = 0
self.CameraRotationYaw = 0
self.FOV = 90
self.set(**kwargs)
def set_image_size(self, pixels_x, pixels_y):
@ -74,51 +106,6 @@ class Camera(Sensor):
self.ImageSizeX = pixels_x
self.ImageSizeY = pixels_y
def set_position(self, x, y, z):
'''Sets a position to the camera in cm'''
self.CameraPositionX = x
self.CameraPositionY = y
self.CameraPositionZ = z
def set_rotation(self, pitch, yaw, roll):
'''Sets a rotation to the camera'''
self.CameraRotationPitch = pitch
self.CameraRotationYaw = yaw
self.CameraRotationRoll = roll
def get_transform(self):
'''
Returns the camera to [whatever the camera is
attached to] transformation.
'''
return Transform(
Translation(
self.CameraPositionX,
self.CameraPositionY,
self.CameraPositionZ
),
Rotation(
self.CameraRotationPitch,
self.CameraRotationYaw,
self.CameraRotationRoll
)
)
def get_unreal_transform(self):
'''
Returns the camera to [whatever the camera is
attached to] transformation with the Unreal
necessary corrections applied.
'''
# Do the custom transformations.
to_unreal_transform = Transform(
Rotation(roll=-90, yaw=90),
Scale(x=-1)
)
# Apply and return it.
return self.get_transform() * to_unreal_transform
class Lidar(Sensor):
"""
@ -127,43 +114,16 @@ class Lidar(Sensor):
"""
def __init__(self, name, **kwargs):
self.LidarName = name
# Number of lasers
super(Lidar, self).__init__(name, sensor_type="LIDAR_RAY_TRACE")
self.Channels = 32
# Measure distance
self.Range = 5000
# Points generated by all lasers per second
self.PointsPerSecond = 100000
# Lidar rotation frequency
self.RotationFrequency = 10
# Upper laser angle, counts from horizontal,
# positive values means above horizontal line
self.UpperFovLimit = 10
# Lower laser angle, counts from horizontal,
# negative values means under horizontal line
self.LowerFovLimit = -30
# wether to show debug points of laser hits in simulator
self.ShowDebugPoints = False
# Position relative to the player.
self.LidarPositionX = 0
self.LidarPositionY = 0
self.LidarPositionZ = 250
# Rotation relative to the player.
self.LidarRotationPitch = 0
self.LidarRotationRoll = 0
self.LidarRotationYaw = 0
self.set(**kwargs)
def set_position(self, x, y, z):
self.LidarPositionX = x
self.LidarPositionY = y
self.LidarPositionZ = z
def set_rotation(self, pitch, roll, yaw):
self.LidarRotationPitch = pitch
self.LidarRotationRoll = roll
self.LidarRotationYaw = yaw
# ==============================================================================
# -- SensorData ----------------------------------------------------------
@ -339,57 +299,24 @@ class PointCloud(SensorData):
class LidarMeasurement(SensorData):
"""Data generated by a Lidar."""
def __init__(self, horizontal_angle, channels_count, lidar_type, raw_data):
def __init__(self, horizontal_angle, channels, points_count_by_channel, point_cloud):
assert numpy.sum(points_count_by_channel) == len(point_cloud.array)
self.horizontal_angle = horizontal_angle
self.channels_count = channels_count
self.type = lidar_type
self._converted_data = None
points_count_by_channel_size = channels_count * 4
points_count_by_channel_bytes = raw_data[4*4:4*4 + points_count_by_channel_size]
self.points_count_by_channel = numpy.frombuffer(points_count_by_channel_bytes, dtype=numpy.dtype('uint32'))
self.points_size = int(numpy.sum(self.points_count_by_channel) * 3 * 8) # three floats X, Y, Z
begin = 4*4 + points_count_by_channel_size # 4*4 is horizontal_angle, type, channels_count
end = begin + self.points_size
self.points_data = raw_data[begin:end]
self._data_size = 4*4 + points_count_by_channel_size + self.points_size
@property
def size_in_bytes(self):
return self._data_size
self.channels_count = channels
self.points_count_by_channel = points_count_by_channel
self.point_cloud = point_cloud
@property
def data(self):
"""The numpy array holding the point-cloud.
3D points format for n elements:
[ [X0,Y0,Z0],
...,
[Xn,Yn,Zn] ]
"""
Lazy initialization for data property, stores converted data in its
default format.
"""
if self._converted_data is None:
points_in_one_channel = self.points_count_by_channel[0]
points = numpy.frombuffer(self.points_data[:self.points_size], dtype='float')
points = numpy.reshape(points, (self.channels_count, points_in_one_channel, 3))
self._converted_data = {
'horizontal_angle' : self.horizontal_angle,
'channels_count' : self.channels_count,
'points_count_by_channel' : self.points_count_by_channel,
'points' : points
}
return self._converted_data
return self.point_cloud.array
def save_to_disk(self, filename):
"""Save lidar measurements to disk"""
folder = os.path.dirname(filename)
if not os.path.isdir(folder):
os.makedirs(folder)
with open(filename, 'wt') as f:
f.write(json.dumps({
'horizontal_angle' : self.horizontal_angle,
'channels_count' : self.channels_count,
'points_count_by_channel' : self.points_count_by_channel.tolist(),
'points' : self.data['points'].tolist()
}))
"""Save point-cloud to disk as PLY format."""
self.point_cloud.save_to_disk(filename)

View File

@ -45,8 +45,7 @@ class CarlaSettings(object):
self.SeedPedestrians = None
self.randomize_weather()
self.set(**kwargs)
self._cameras = []
self._lidars = []
self._sensors = []
def set(self, **kwargs):
for key, value in kwargs.items():
@ -68,12 +67,9 @@ class CarlaSettings(object):
def add_sensor(self, sensor):
"""Add a sensor to the player vehicle (see sensor.py)."""
if isinstance(sensor, carla_sensor.Camera):
self._cameras.append(sensor)
elif isinstance(sensor, carla_sensor.Lidar):
self._lidars.append(sensor)
else:
if not isinstance(sensor, carla_sensor.Sensor):
raise ValueError('Sensor not supported')
self._sensors.append(sensor)
def __str__(self):
"""Converts this object to an INI formatted string."""
@ -81,7 +77,10 @@ class CarlaSettings(object):
ini.optionxform = str
S_SERVER = 'CARLA/Server'
S_LEVEL = 'CARLA/LevelSettings'
S_CAPTURE = 'CARLA/SceneCapture'
S_SENSOR = 'CARLA/Sensor'
def get_attribs(obj):
return [a for a in dir(obj) if not a.startswith('_') and not callable(getattr(obj, a))]
def add_section(section, obj, keys):
for key in keys:
@ -100,38 +99,12 @@ class CarlaSettings(object):
'SeedVehicles',
'SeedPedestrians'])
ini.add_section(S_CAPTURE)
ini.set(S_CAPTURE, 'Cameras', ','.join(c.CameraName for c in self._cameras))
ini.set(S_CAPTURE, 'Lidars', ','.join(l.LidarName for l in self._lidars))
ini.add_section(S_SENSOR)
ini.set(S_SENSOR, 'Sensors', ','.join(s.SensorName for s in self._sensors))
for camera in self._cameras:
add_section(S_CAPTURE + '/' + camera.CameraName, camera, [
'PostProcessing',
'ImageSizeX',
'ImageSizeY',
'CameraFOV',
'CameraPositionX',
'CameraPositionY',
'CameraPositionZ',
'CameraRotationPitch',
'CameraRotationRoll',
'CameraRotationYaw'])
for lidar in self._lidars:
add_section(S_CAPTURE + '/' + lidar.LidarName, lidar, [
'Channels',
'Range',
'PointsPerSecond',
'RotationFrequency',
'UpperFovLimit',
'LowerFovLimit',
'ShowDebugPoints',
'LidarPositionX',
'LidarPositionY',
'LidarPositionZ',
'LidarRotationPitch',
'LidarRotationRoll',
'LidarRotationYaw'])
for sensor_def in self._sensors:
section = S_SENSOR + '/' + sensor_def.SensorName
add_section(section, sensor_def, get_attribs(sensor_def))
if sys.version_info >= (3, 0):
text = io.StringIO()
@ -140,29 +113,3 @@ class CarlaSettings(object):
ini.write(text)
return text.getvalue().replace(' = ', '=')
def get_sensor_names(settings):
"""
Return a list with the names of the sensors defined in the settings object.
The settings object can be a CarlaSettings or an INI formatted string.
"""
if isinstance(settings, CarlaSettings):
# pylint: disable=protected-access
return [camera.CameraName for camera in settings._cameras] + \
[lidar.LidarName for lidar in settings._lidars]
ini = ConfigParser()
if sys.version_info >= (3, 2):
ini.read_string(settings)
elif sys.version_info >= (3, 0):
ini.readfp(io.StringIO(settings)) # pylint: disable=deprecated-method
else:
ini.readfp(io.BytesIO(settings)) # pylint: disable=deprecated-method
section_name = 'CARLA/SceneCapture'
option_name = 'Cameras'
if ini.has_section(section_name) and ini.has_option(section_name, option_name):
cameras = ini.get(section_name, option_name)
return cameras.split(',')
return []

View File

@ -22,7 +22,7 @@ from carla.tcp import TCPConnectionError
from carla.util import print_over_same_line
def run_carla_client(host, port, autopilot_on, save_images_to_disk, image_filename_format, lidar_filename_format, settings_filepath):
def run_carla_client(args):
# Here we will run 3 episodes with 300 frames each.
number_of_episodes = 3
frames_per_episode = 300
@ -32,13 +32,13 @@ def run_carla_client(host, port, autopilot_on, save_images_to_disk, image_filena
# context manager, it creates a CARLA client object and starts the
# connection. It will throw an exception if something goes wrong. The
# context manager makes sure the connection is always cleaned up on exit.
with make_carla_client(host, port) as client:
with make_carla_client(args.host, args.port) as client:
print('CarlaClient connected')
for episode in range(0, number_of_episodes):
# Start a new episode.
if settings_filepath is None:
if args.settings_filepath is None:
# Create a CarlaSettings object. This object is a wrapper around
# the CarlaSettings.ini file. Here we set the configuration we
@ -70,23 +70,23 @@ def run_carla_client(host, port, autopilot_on, save_images_to_disk, image_filena
camera1.set_position(30, 0, 130)
settings.add_sensor(camera1)
lidar0 = Lidar('Lidar32')
lidar0.set_position(0, 0, 250)
lidar0.set_rotation(0, 0, 0)
lidar0.set(
Channels = 32,
Range = 5000,
PointsPerSecond = 100000,
RotationFrequency = 10,
UpperFovLimit = 10,
LowerFovLimit = -30,
ShowDebugPoints = False)
settings.add_sensor(lidar0)
if args.lidar:
lidar = Lidar('Lidar32')
lidar.set_position(0, 0, 250)
lidar.set_rotation(0, 0, 0)
lidar.set(
Channels=32,
Range=5000,
PointsPerSecond=100000,
RotationFrequency=10,
UpperFovLimit=10,
LowerFovLimit=-30)
settings.add_sensor(lidar)
else:
# Alternatively, we can load these settings from a file.
with open(settings_filepath, 'r') as fp:
with open(args.settings_filepath, 'r') as fp:
settings = fp.read()
# Now we load these settings into the server. The server replies
@ -115,12 +115,13 @@ def run_carla_client(host, port, autopilot_on, save_images_to_disk, image_filena
print_measurements(measurements)
# Save the images to disk if requested.
if save_images_to_disk:
if args.save_images_to_disk:
for name, measurement in sensor_data.items():
if isinstance(measurement, LidarMeasurement):
measurement.save_to_disk(lidar_filename_format.format(episode, name, frame))
filename = args.lidar_filename_format
else:
measurement.save_to_disk(image_filename_format.format(episode, name, frame))
filename = args.image_filename_format
measurement.save_to_disk(filename.format(episode, name, frame))
# We can access the encoded data of a given image as numpy
# array using its "data" property. For instance, to get the
@ -134,7 +135,7 @@ def run_carla_client(host, port, autopilot_on, save_images_to_disk, image_filena
# If we are in synchronous mode the server will pause the
# simulation until we send this control.
if not autopilot_on:
if not args.autopilot:
client.send_control(
steer=random.uniform(-1.0, 1.0),
@ -199,13 +200,19 @@ def main():
'-a', '--autopilot',
action='store_true',
help='enable autopilot')
argparser.add_argument(
'-l', '--lidar',
action='store_true',
help='enable Lidar')
argparser.add_argument(
'-i', '--images-to-disk',
action='store_true',
help='save images to disk')
dest='save_images_to_disk',
help='save images (and Lidar data if active) to disk')
argparser.add_argument(
'-c', '--carla-settings',
metavar='PATH',
dest='settings_filepath',
default=None,
help='Path to a "CarlaSettings.ini" file')
@ -216,17 +223,13 @@ def main():
logging.info('listening to server %s:%s', args.host, args.port)
args.image_filename_format = '_out/episode_{:0>4d}/{:s}/{:0>6d}.png'
args.lidar_filename_format = '_out/episode_{:0>4d}/{:s}/{:0>6d}.ply'
while True:
try:
run_carla_client(
host=args.host,
port=args.port,
autopilot_on=args.autopilot,
save_images_to_disk=args.images_to_disk,
image_filename_format='_out/episode_{:0>4d}/{:s}/{:0>6d}.png',
lidar_filename_format='_out/episode_{:0>4d}/{:s}/{:0>6d}.json',
settings_filepath=args.carla_settings)
run_carla_client(args)
print('Done.')
return

View File

@ -68,7 +68,7 @@ MINI_WINDOW_WIDTH = 320
MINI_WINDOW_HEIGHT = 180
def make_carla_settings():
def make_carla_settings(enable_lidar):
"""Make a CarlaSettings object with the settings we need."""
settings = CarlaSettings()
settings.set(
@ -93,19 +93,18 @@ def make_carla_settings():
camera2.set_position(200, 0, 140)
camera2.set_rotation(0.0, 0.0, 0.0)
settings.add_sensor(camera2)
lidar0 = sensor.Lidar('Lidar32')
lidar0.set_position(0, 0, 250)
lidar0.set_rotation(0, 0, 0)
lidar0.set(
Channels = 32,
Range = 5000,
PointsPerSecond = 100000,
RotationFrequency = 10,
UpperFovLimit = 10,
LowerFovLimit = -30,
ShowDebugPoints = False)
settings.add_sensor(lidar0)
if enable_lidar:
lidar = sensor.Lidar('Lidar32')
lidar.set_position(0, 0, 250)
lidar.set_rotation(0, 0, 0)
lidar.set(
Channels=32,
Range=5000,
PointsPerSecond=100000,
RotationFrequency=10,
UpperFovLimit=10,
LowerFovLimit=-30)
settings.add_sensor(lidar)
return settings
@ -130,13 +129,14 @@ class Timer(object):
class CarlaGame(object):
def __init__(self, carla_client, city_name=None):
def __init__(self, carla_client, enable_lidar=False, city_name=None):
self.client = carla_client
self._timer = None
self._display = None
self._main_image = None
self._mini_view_image1 = None
self._mini_view_image2 = None
self._enable_lidar = enable_lidar
self._lidar_measurement = None
self._map_view = None
self._is_on_reverse = False
@ -175,7 +175,7 @@ class CarlaGame(object):
self._on_new_episode()
def _on_new_episode(self):
scene = self.client.load_settings(make_carla_settings())
scene = self.client.load_settings(make_carla_settings(self._enable_lidar))
number_of_player_starts = len(scene.player_start_spots)
player_start = np.random.randint(number_of_player_starts)
print('Starting new episode...')
@ -191,7 +191,8 @@ class CarlaGame(object):
self._main_image = sensor_data['CameraRGB']
self._mini_view_image1 = sensor_data['CameraDepth']
self._mini_view_image2 = sensor_data['CameraSemSeg']
self._lidar_measurement = sensor_data['Lidar32']
if self._enable_lidar:
self._lidar_measurement = sensor_data['Lidar32']
# Print measurements every second.
if self._timer.elapsed_seconds_since_lap() > 1.0:
@ -222,9 +223,9 @@ class CarlaGame(object):
# Set the player position
if self._city_name is not None:
self._position = self._map.convert_to_pixel([
measurements.player_measurements.transform.location.x,
measurements.player_measurements.transform.location.y,
measurements.player_measurements.transform.location.z])
measurements.player_measurements.transform.location.x,
measurements.player_measurements.transform.location.y,
measurements.player_measurements.transform.location.z])
self._agent_positions = measurements.non_player_agents
if control is None:
@ -261,7 +262,8 @@ class CarlaGame(object):
map_position,
lane_orientation):
message = 'Step {step} ({fps:.1f} FPS): '
message += 'Map Position ({map_x:.1f},{map_y:.1f}) Lane Orientation ({ori_x:.1f},{ori_y:.1f}) '
message += 'Map Position ({map_x:.1f},{map_y:.1f}) '
message += 'Lane Orientation ({ori_x:.1f},{ori_y:.1f}) '
message += '{speed:.2f} km/h, '
message += '{other_lane:.0f}% other lane, {offroad:.0f}% off-road'
message = message.format(
@ -311,8 +313,7 @@ class CarlaGame(object):
surface, (2 * gap_x + MINI_WINDOW_WIDTH, mini_image_y))
if self._lidar_measurement is not None:
lidar_data = np.array(self._lidar_measurement.data['points'][:, :, :2])
lidar_data = np.array(self._lidar_measurement.data[:, :2])
lidar_data /= 50.0
lidar_data += 100.0
lidar_data = np.fabs(lidar_data)
@ -322,22 +323,22 @@ class CarlaGame(object):
lidar_img_size = (200, 200, 3)
lidar_img = np.zeros(lidar_img_size)
lidar_img[tuple(lidar_data.T)] = (255, 255, 255)
surface = pygame.surfarray.make_surface(
lidar_img
)
surface = pygame.surfarray.make_surface(lidar_img)
self._display.blit(surface, (10, 10))
if self._map_view is not None:
array = self._map_view
array = array[:, :, :3]
new_window_width =(float(WINDOW_HEIGHT)/float(self._map_shape[0]))*float(self._map_shape[1])
new_window_width = \
(float(WINDOW_HEIGHT) / float(self._map_shape[0])) * \
float(self._map_shape[1])
surface = pygame.surfarray.make_surface(array.swapaxes(0, 1))
w_pos = int(self._position[0]*(float(WINDOW_HEIGHT)/float(self._map_shape[0])))
h_pos = int(self._position[1] *(new_window_width/float(self._map_shape[1])))
pygame.draw.circle(surface, [255, 0, 0, 255], (w_pos,h_pos), 6, 0)
pygame.draw.circle(surface, [255, 0, 0, 255], (w_pos, h_pos), 6, 0)
for agent in self._agent_positions:
if agent.HasField('vehicle'):
agent_position = self._map.convert_to_pixel([
@ -348,7 +349,7 @@ class CarlaGame(object):
w_pos = int(agent_position[0]*(float(WINDOW_HEIGHT)/float(self._map_shape[0])))
h_pos = int(agent_position[1] *(new_window_width/float(self._map_shape[1])))
pygame.draw.circle(surface, [255, 0, 255, 255], (w_pos ,h_pos), 4, 0)
pygame.draw.circle(surface, [255, 0, 255, 255], (w_pos, h_pos), 4, 0)
self._display.blit(surface, (WINDOW_WIDTH, 0))
@ -374,11 +375,16 @@ def main():
default=2000,
type=int,
help='TCP port to listen to (default: 2000)')
argparser.add_argument(
'-l', '--lidar',
action='store_true',
help='enable Lidar')
argparser.add_argument(
'-m', '--map-name',
metavar='M',
default=None,
help='plot the map of the current city (needs to match active map in server, options: Town01 or Town02)')
help='plot the map of the current city (needs to match active map in '
'server, options: Town01 or Town02)')
args = argparser.parse_args()
log_level = logging.DEBUG if args.debug else logging.INFO
@ -392,7 +398,7 @@ def main():
try:
with make_carla_client(args.host, args.port) as client:
game = CarlaGame(client, args.map_name)
game = CarlaGame(client, args.lidar, args.map_name)
game.execute()
break

View File

@ -51,17 +51,13 @@ def run_carla_client(host, port, far):
WeatherId=random.choice([1, 3, 7, 8, 14]))
settings.randomize_seeds()
camera1 = Camera(
'CameraDepth', PostProcessing='Depth', CameraFOV=fov
)
camera1 = Camera('CameraDepth', PostProcessing='Depth', FOV=fov)
camera1.set_image_size(*image_size)
camera1.set_position(*camera_local_pos)
camera1.set_rotation(*camera_local_rotation)
settings.add_sensor(camera1)
camera2 = Camera(
'CameraRGB', PostProcessing='SceneFinal', CameraFOV=fov
)
camera2 = Camera('CameraRGB', PostProcessing='SceneFinal', FOV=fov)
camera2.set_image_size(*image_size)
camera2.set_position(*camera_local_pos)
camera2.set_rotation(*camera_local_rotation)

View File

@ -13,6 +13,7 @@ import carla
from carla.client import CarlaClient
from carla.sensor import Camera, Image
from carla.sensor import Lidar, LidarMeasurement
from carla.settings import CarlaSettings
from carla.util import make_connection
@ -45,8 +46,8 @@ class _BasicTestBase(unit_tests.CarlaServerTest):
number_of_agents = len(measurements.non_player_agents)
logging.debug('received data of %d agents', number_of_agents)
logging.debug('received %d images', len(images))
if len(images) != len(carla_settings._cameras):
raise RuntimeError('received %d images, expected %d' % (len(images), len(carla_settings._cameras)))
if len(sensor_data) != len(carla_settings._sensors):
raise RuntimeError('received %d, expected %d' % (len(sensor_data), len(carla_settings._sensors)))
logging.debug('sending control...')
control = measurements.player_measurements.autopilot_control
if not use_autopilot_control:
@ -80,7 +81,7 @@ class TwoCameras(_BasicTestBase):
settings = CarlaSettings()
settings.add_sensor(Camera('DefaultCamera'))
camera2 = Camera('Camera2')
camera2.set(PostProcessing='Depth', CameraFOV=120)
camera2.set(PostProcessing='Depth', FOV=120)
camera2.set_image_size(1924, 1028)
settings.add_sensor(camera2)
self.run_carla_client(settings, 3, 100)
@ -110,3 +111,10 @@ class LongEpisode(_BasicTestBase):
settings = CarlaSettings()
settings.add_sensor(Camera('DefaultCamera'))
self.run_carla_client(settings, 1, 2000, use_autopilot_control=True)
class LidarTest(_BasicTestBase):
def run(self):
settings = CarlaSettings()
settings.add_sensor(Lidar('DefaultLidar'))
self.run_carla_client(settings, 3, 100)

View File

@ -17,7 +17,7 @@ void UCameraDescription::Load(const FIniFile &Config, const FString &Section)
PostProcessEffect = PostProcessEffect::FromString(PostProcessing);
Config.GetInt(*Section, TEXT("ImageSizeX"), ImageSizeX);
Config.GetInt(*Section, TEXT("ImageSizeY"), ImageSizeY);
Config.GetFloat(*Section, TEXT("CameraFOV"), FOVAngle);
Config.GetFloat(*Section, TEXT("FOV"), FOVAngle);
}
void UCameraDescription::Validate()