Add image parser to client
This commit is contained in:
parent
1d7e5ec769
commit
25a4f0411c
|
@ -13,3 +13,4 @@ Util/Install
|
||||||
|
|
||||||
*.log
|
*.log
|
||||||
*.pid
|
*.pid
|
||||||
|
_*
|
||||||
|
|
|
@ -2,6 +2,10 @@
|
||||||
|
|
||||||
"""CARLA Client."""
|
"""CARLA Client."""
|
||||||
|
|
||||||
|
import logging
|
||||||
|
import os
|
||||||
|
import struct
|
||||||
|
|
||||||
from . import tcp
|
from . import tcp
|
||||||
|
|
||||||
from . import carla_server_pb2 as carla_protocol
|
from . import carla_server_pb2 as carla_protocol
|
||||||
|
@ -79,7 +83,7 @@ class CarlaClient(object):
|
||||||
pb_message.ParseFromString(data)
|
pb_message.ParseFromString(data)
|
||||||
# Read images.
|
# Read images.
|
||||||
images_raw_data = self._stream_client.read()
|
images_raw_data = self._stream_client.read()
|
||||||
return pb_message, images_raw_data
|
return pb_message, CarlaImage.parse_raw_data(images_raw_data)
|
||||||
|
|
||||||
def send_control(self, **kwargs):
|
def send_control(self, **kwargs):
|
||||||
"""Send vehicle control for the current frame."""
|
"""Send vehicle control for the current frame."""
|
||||||
|
@ -91,3 +95,49 @@ class CarlaClient(object):
|
||||||
pb_message.reverse = kwargs.get('reverse', False)
|
pb_message.reverse = kwargs.get('reverse', False)
|
||||||
pb_message.autopilot = kwargs.get('autopilot', False)
|
pb_message.autopilot = kwargs.get('autopilot', False)
|
||||||
self._control_client.write(pb_message.SerializeToString())
|
self._control_client.write(pb_message.SerializeToString())
|
||||||
|
|
||||||
|
|
||||||
|
class CarlaImage(object):
|
||||||
|
@staticmethod
|
||||||
|
def parse_raw_data(raw_data):
|
||||||
|
getval = lambda index: struct.unpack('<L', raw_data[index*4:index*4+4])[0]
|
||||||
|
images = []
|
||||||
|
total_size = len(raw_data) / 4
|
||||||
|
index = 0
|
||||||
|
while index < total_size:
|
||||||
|
width = getval(index)
|
||||||
|
height = getval(index + 1)
|
||||||
|
image_type = getval(index + 2)
|
||||||
|
begin = index + 3
|
||||||
|
end = begin + width * height
|
||||||
|
images.append(CarlaImage(width, height, image_type, raw_data[begin*4:end*4]))
|
||||||
|
index = end
|
||||||
|
return images
|
||||||
|
|
||||||
|
def __init__(self, width, height, image_type, raw_data):
|
||||||
|
logging.debug('parsed image %dx%d type %d (%d bytes)', width, height, image_type, len(raw_data))
|
||||||
|
assert len(raw_data) == 4 * width * height
|
||||||
|
self.width = width
|
||||||
|
self.height = height
|
||||||
|
self.image_type = image_type
|
||||||
|
self.raw = raw_data
|
||||||
|
|
||||||
|
def save_to_disk(self, filename):
|
||||||
|
try:
|
||||||
|
from PIL import Image
|
||||||
|
except ImportError:
|
||||||
|
raise RuntimeError('cannot import PIL, make sure pillow package is installed')
|
||||||
|
|
||||||
|
image = Image.frombytes(
|
||||||
|
mode='RGBA',
|
||||||
|
size=(self.width, self.height),
|
||||||
|
data=self.raw,
|
||||||
|
decoder_name='raw')
|
||||||
|
b, g, r, a = image.split()
|
||||||
|
image = Image.merge("RGB", (r, g, b))
|
||||||
|
|
||||||
|
folder = os.path.dirname(filename)
|
||||||
|
if not os.path.isdir(folder):
|
||||||
|
os.makedirs(folder)
|
||||||
|
logging.debug('saving image to %r...', filename)
|
||||||
|
image.save(filename)
|
||||||
|
|
|
@ -75,12 +75,6 @@ class CarlaSettings(object):
|
||||||
return 0
|
return 0
|
||||||
return self.NumberOfVehicles + self.NumberOfPedestrians
|
return self.NumberOfVehicles + self.NumberOfPedestrians
|
||||||
|
|
||||||
def get_images_byte_size(self):
|
|
||||||
size = 0
|
|
||||||
for camera in self._cameras:
|
|
||||||
size += 3 + int(camera.ImageSizeX) * int(camera.ImageSizeY)
|
|
||||||
return 4 * size
|
|
||||||
|
|
||||||
def randomize_seeds(self):
|
def randomize_seeds(self):
|
||||||
self.SeedVehicles = random.getrandbits(32)
|
self.SeedVehicles = random.getrandbits(32)
|
||||||
self.SeedPedestrians = random.getrandbits(32)
|
self.SeedPedestrians = random.getrandbits(32)
|
||||||
|
|
|
@ -17,15 +17,20 @@ from carla.tcp import TCPClient
|
||||||
from carla.util import make_connection
|
from carla.util import make_connection
|
||||||
|
|
||||||
|
|
||||||
def run_carla_server(host, port):
|
def run_carla_server(args):
|
||||||
with make_connection(CarlaClient, host, port, timeout=15) as client:
|
with make_connection(CarlaClient, args.host, args.port, timeout=15) as client:
|
||||||
logging.info('CarlaClient connected')
|
logging.info('CarlaClient connected')
|
||||||
|
filename = '_images/episode_{:0>3d}/image_{:0>5d}.png'
|
||||||
frames_per_episode = 300
|
frames_per_episode = 300
|
||||||
|
episode = 0
|
||||||
while True:
|
while True:
|
||||||
|
episode += 1
|
||||||
settings = CarlaSettings()
|
settings = CarlaSettings()
|
||||||
settings.set(SendNonPlayerAgentsInfo=True)
|
settings.set(SendNonPlayerAgentsInfo=True,SynchronousMode=args.synchronous)
|
||||||
settings.randomize_seeds()
|
settings.randomize_seeds()
|
||||||
settings.add_camera(Camera('DefaultCamera'))
|
camera = Camera('DefaultCamera')
|
||||||
|
camera.set_image_size(300, 200)
|
||||||
|
settings.add_camera(camera)
|
||||||
|
|
||||||
logging.debug('sending CarlaSettings:\n%s', settings)
|
logging.debug('sending CarlaSettings:\n%s', settings)
|
||||||
logging.info('new episode requested')
|
logging.info('new episode requested')
|
||||||
|
@ -45,12 +50,16 @@ def run_carla_server(host, port):
|
||||||
autopilot = (random.random() < 0.5)
|
autopilot = (random.random() < 0.5)
|
||||||
reverse = (random.random() < 0.2)
|
reverse = (random.random() < 0.2)
|
||||||
|
|
||||||
for _ in range(0, frames_per_episode):
|
for frame in range(0, frames_per_episode):
|
||||||
logging.debug('reading measurements...')
|
logging.debug('reading measurements...')
|
||||||
measurements, images = client.read_measurements()
|
measurements, images = client.read_measurements()
|
||||||
|
|
||||||
logging.debug('received data of %d agents', len(measurements.non_player_agents))
|
logging.debug('received data of %d agents', len(measurements.non_player_agents))
|
||||||
logging.debug('received %d bytes of images', len(images))
|
assert len(images) == 1
|
||||||
|
assert (images[0].width, images[0].height) == (camera.ImageSizeX, camera.ImageSizeY)
|
||||||
|
|
||||||
|
if args.images_to_disk:
|
||||||
|
images[0].save_to_disk(filename.format(episode, frame))
|
||||||
|
|
||||||
logging.debug('sending control...')
|
logging.debug('sending control...')
|
||||||
client.send_control(
|
client.send_control(
|
||||||
|
@ -83,6 +92,14 @@ def main():
|
||||||
default=2000,
|
default=2000,
|
||||||
type=int,
|
type=int,
|
||||||
help='TCP port to listen to (default: 2000)')
|
help='TCP port to listen to (default: 2000)')
|
||||||
|
argparser.add_argument(
|
||||||
|
'-s', '--synchronous',
|
||||||
|
action='store_true',
|
||||||
|
help='enable synchronous mode')
|
||||||
|
argparser.add_argument(
|
||||||
|
'-i', '--images-to-disk',
|
||||||
|
action='store_true',
|
||||||
|
help='save images to disk')
|
||||||
argparser.add_argument(
|
argparser.add_argument(
|
||||||
'--echo',
|
'--echo',
|
||||||
action='store_true',
|
action='store_true',
|
||||||
|
@ -118,11 +135,15 @@ def main():
|
||||||
|
|
||||||
else:
|
else:
|
||||||
|
|
||||||
run_carla_server(args.host, args.port)
|
run_carla_server(args)
|
||||||
|
|
||||||
except Exception as exception:
|
except AssertionError as assertion:
|
||||||
|
raise assertion
|
||||||
|
except ConnectionRefusedError as exception:
|
||||||
logging.error('exception: %s', exception)
|
logging.error('exception: %s', exception)
|
||||||
time.sleep(1)
|
time.sleep(1)
|
||||||
|
except Exception as exception:
|
||||||
|
raise exception
|
||||||
|
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
|
|
|
@ -36,11 +36,11 @@ class _BasicTestBase(test.CarlaServerTest):
|
||||||
number_of_agents = len(measurements.non_player_agents)
|
number_of_agents = len(measurements.non_player_agents)
|
||||||
expected_number_of_agents = carla_settings.get_number_of_agents()
|
expected_number_of_agents = carla_settings.get_number_of_agents()
|
||||||
logging.debug('received data of %d/%d agents', number_of_agents, expected_number_of_agents)
|
logging.debug('received data of %d/%d agents', number_of_agents, expected_number_of_agents)
|
||||||
logging.debug('received %d bytes of images', len(images))
|
logging.debug('received %d images', len(images))
|
||||||
if number_of_agents > expected_number_of_agents or number_of_agents + 10 < expected_number_of_agents:
|
if number_of_agents > expected_number_of_agents or number_of_agents + 10 < expected_number_of_agents:
|
||||||
raise RuntimeError('received data for %d agents, but %d was requested' % (number_of_agents, expected_number_of_agents))
|
raise RuntimeError('received data for %d agents, but %d was requested' % (number_of_agents, expected_number_of_agents))
|
||||||
if len(images) != carla_settings.get_images_byte_size():
|
if len(images) != len(carla_settings._cameras):
|
||||||
raise RuntimeError('received %d bytes of images, expected %d' % (len(images), carla_settings.get_images_byte_size()))
|
raise RuntimeError('received %d images, expected %d' % (len(images), len(carla_settings._cameras)))
|
||||||
logging.debug('sending control...')
|
logging.debug('sending control...')
|
||||||
client.send_control(
|
client.send_control(
|
||||||
steer=random.uniform(-1.0, 1.0),
|
steer=random.uniform(-1.0, 1.0),
|
||||||
|
|
Loading…
Reference in New Issue