#32 Clean up carla_manual_control, make API more robust, add image converter

This commit is contained in:
nsubiron 2017-11-18 17:51:05 +01:00
parent 1b9029b056
commit 0f28adb9f9
12 changed files with 407 additions and 352 deletions

1
.gitignore vendored
View File

@ -23,4 +23,5 @@ Util/Build
.tags*
.vs
__pycache__
_images
core

View File

@ -1,3 +0,0 @@
from .carla import CARLA
from .protoc import SceneDescription,EpisodeStart,EpisodeReady,Control,Measurements,RequestNewEpisode

View File

@ -20,6 +20,9 @@ except ImportError:
raise RuntimeError('cannot import "carla_server_pb2.py", run the protobuf compiler to generate this file')
VehicleControl = carla_protocol.Control
@contextmanager
def make_carla_client(host, world_port, timeout=15):
with util.make_connection(CarlaClient, host, world_port, timeout) as client:
@ -101,7 +104,7 @@ class CarlaClient(object):
pb_message.ParseFromString(data)
# Read images.
images_raw_data = self._stream_client.read()
return pb_message, CarlaImage.parse_raw_data(images_raw_data)
return pb_message, CarlaImage._parse_raw_data(images_raw_data)
def send_control(self, *args, **kwargs):
"""Send vehicle control for the current frame."""
@ -119,7 +122,7 @@ class CarlaClient(object):
class CarlaImage(object):
@staticmethod
def parse_raw_data(raw_data):
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
@ -142,6 +145,7 @@ class CarlaImage(object):
self.raw = raw_data
def save_to_disk(self, filename):
"""Save this image to disk (requires PIL installed)."""
try:
from PIL import Image
except ImportError:

View File

@ -0,0 +1,86 @@
# Copyright (c) 2017 Computer Vision Center (CVC) at the Universitat Autonoma de
# Barcelona (UAB), and the INTEL Visual Computing Lab.
#
# This work is licensed under the terms of the MIT license.
# For a copy, see <https://opensource.org/licenses/MIT>.
"""
Handy conversions for CARLA images.
The functions here are provided for real-time display, if you want to save the
converted images, save the images from Python without conversion and convert
them afterwards with the C++ implementation at "Util/ImageConverter" as it
provides considerably better performance.
"""
try:
import numpy
except ImportError:
raise RuntimeError('cannot import numpy, make sure numpy package is installed')
def to_numpy_array(image):
"""Convert a CARLA raw image to a BGRA numpy array."""
array = numpy.frombuffer(image.raw, dtype=numpy.dtype("uint8"))
array = numpy.reshape(array, (image.height, image.width, 4))
array = numpy.transpose(array, (1, 0, 2))
return array
def to_rgb_array(image):
"""Convert a CARLA raw image to a RGB numpy array."""
array = to_numpy_array(image)
# Convert BGRA to RGB.
array = array[:, :, :3]
array = array[:, :, ::-1]
return array
def labels_to_cityscapes_palette(image):
"""
Converts an image containing CARLA semantic segmentation labels to
Cityscapes palette.
"""
classes = {
0: [0, 0, 0], # None
1: [70, 70, 70], # Buildings
2: [190, 153, 153], # Fences
3: [72, 0, 90], # Other
4: [220, 20, 60], # Pedestrians
5: [153, 153, 153], # Poles
6: [157, 234, 50], # RoadLines
7: [128, 64, 128], # Roads
8: [244, 35, 232], # Sidewalks
9: [107, 142, 35], # Vegetation
10: [0, 0, 255], # Vehicles
11: [102, 102, 156], # Walls
12: [220, 220, 0] # TrafficSigns
}
array = to_numpy_array(image)
array = array[:, :, 2]
result = numpy.zeros((array.shape[0], array.shape[1], 3))
for (key, value) in classes.items():
result[numpy.where(array == key)] = value
return result
def depth_to_grayscale(image):
"""
Converts an image containing CARLA encoded depth-map to logarithmic
grayscale.
"""
array = to_numpy_array(image)
array = array.astype(numpy.float32)
# Apply (R + G * 256 + B * 256 * 256) / (256 * 256 * 256 - 1).
grayscale = numpy.dot(array[:, :,:3], [256.0 * 256.0, 256.0, 1.0])
grayscale /= (256.0 * 256.0 * 256.0 - 1.0)
# Convert to logarithmic depth.
logdepth = numpy.ones(grayscale.shape) + (numpy.log(grayscale) / 5.70378)
logdepth = numpy.clip(logdepth, 0.0, 1.0)
logdepth *= 255.0
# Expand to three colors.
return numpy.repeat(logdepth[:, :, numpy.newaxis], 3, axis=2)

View File

@ -6,9 +6,17 @@
"""CARLA Settings"""
import configparser
import io
import random
import sys
try:
from configparser import ConfigParser
except ImportError:
from ConfigParser import RawConfigParser as ConfigParser
MAX_NUMBER_OF_WEATHER_IDS = 14
@ -22,10 +30,10 @@ class Camera(object):
self.ImageSizeX = 800
self.ImageSizeY = 600
self.CameraFOV = 90
self.CameraPositionX = 15
self.CameraPositionX = 140
self.CameraPositionY = 0
self.CameraPositionZ = 123
self.CameraRotationPitch = 8
self.CameraPositionZ = 140
self.CameraRotationPitch = 0
self.CameraRotationRoll = 0
self.CameraRotationYaw = 0
self.set(**kwargs)
@ -92,7 +100,7 @@ class CarlaSettings(object):
self._cameras.append(camera)
def __str__(self):
ini = configparser.ConfigParser()
ini = ConfigParser()
ini.optionxform=str
S_SERVER = 'CARLA/Server'
S_LEVEL = 'CARLA/LevelSettings'
@ -131,6 +139,9 @@ class CarlaSettings(object):
'CameraRotationRoll',
'CameraRotationYaw'])
text = io.StringIO()
if sys.version_info >= (3, 0):
text = io.StringIO()
else:
text = io.BytesIO()
ini.write(text)
return text.getvalue().replace(' = ', '=')

View File

@ -11,21 +11,29 @@ import socket
import struct
class TCPConnectionError(Exception):
pass
class TCPClient(object):
def __init__(self, host, port, timeout):
self._host = host
self._port = port
self._timeout = timeout
self._socket = None
self._logprefix = '(%s:%s) ' % (self._host, self._port)
def connect(self):
self._socket = socket.create_connection(address=(self._host, self._port), timeout=self._timeout)
self._socket.settimeout(self._timeout)
self._log('connected')
try:
self._socket = socket.create_connection(address=(self._host, self._port), timeout=self._timeout)
self._socket.settimeout(self._timeout)
logging.debug(self._logprefix + 'connected')
except Exception as exception:
self._reraise_exception_as_tcp_error('failed to connect', exception)
def disconnect(self):
if self._socket is not None:
self._log('disconnecting...')
logging.debug(self._logprefix + 'disconnecting')
self._socket.close()
self._socket = None
@ -34,29 +42,35 @@ class TCPClient(object):
def write(self, message):
if self._socket is None:
raise RuntimeError('%s:%s not connected' % (self._host, self._port))
raise TCPConnectionError(self._logprefix + 'not connected')
header = struct.pack('<L', len(message))
self._socket.sendall(header + message)
try:
self._socket.sendall(header + message)
except Exception as exception:
self._reraise_exception_as_tcp_error('failed to write data', exception)
def read(self):
header = self._read_n(4)
if not header:
raise RuntimeError('%s:%s connection closed' % (self._host, self._port))
raise TCPConnectionError(self._logprefix + 'connection closed')
length = struct.unpack('<L', header)[0]
data = self._read_n(length)
return data
def _read_n(self, length):
if self._socket is None:
raise RuntimeError('%s:%s not connected' % (self._host, self._port))
raise TCPConnectionError(self._logprefix + 'not connected')
buf = bytes()
while length > 0:
data = self._socket.recv(length)
try:
data = self._socket.recv(length)
except Exception as exception:
self._reraise_exception_as_tcp_error('failed to read data', exception)
if not data:
raise RuntimeError('%s:%s connection closed' % (self._host, self._port))
raise TCPConnectionError(self._logprefix + 'connection closed')
buf += data
length -= len(data)
return buf
def _log(self, message, *args):
logging.debug('tcpclient %s:%d - ' + message, self._host, self._port, *args)
def _reraise_exception_as_tcp_error(self, message, exception):
raise TCPConnectionError('%s%s: %s' % (self._logprefix, message, exception))

View File

@ -5,14 +5,11 @@
# For a copy, see <https://opensource.org/licenses/MIT>.
import datetime
import sys
from contextlib import contextmanager
def to_hex_str(header):
return ':'.join('{:02x}'.format(ord(c)) for c in header)
@contextmanager
def make_connection(client_type, *args, **kwargs):
"""Context manager to create and connect a networking object."""
@ -36,3 +33,29 @@ class StopWatch(object):
def milliseconds(self):
return 1000.0 * (self.end - self.start).total_seconds()
def to_hex_str(header):
return ':'.join('{:02x}'.format(ord(c)) for c in header)
if sys.version_info >= (3, 3):
import shutil
def print_over_same_line(text):
terminal_width = shutil.get_terminal_size((80, 20)).columns
empty_space = max(0, terminal_width - len(text))
sys.stdout.write('\r' + text + empty_space * ' ')
sys.stdout.flush()
else:
# Workaround for older Python versions.
def print_over_same_line(text):
line_length = max(print_over_same_line._last_line_length, len(text))
empty_space = max(0, line_length - len(text))
sys.stdout.write('\r' + text + empty_space * ' ')
sys.stdout.flush()
print_over_same_line._last_line_length = line_length
print_over_same_line._last_line_length = 0

View File

@ -6,8 +6,8 @@
# This work is licensed under the terms of the MIT license.
# For a copy, see <https://opensource.org/licenses/MIT>.
# Keyboard controlling for carla. Please refer to carla_use_example for a
# simpler and more documented example.
# Keyboard controlling for carla. Please refer to client_example for a simpler
# and more documented example.
"""
Welcome to CARLA manual control.
@ -29,324 +29,237 @@ from __future__ import print_function
import argparse
import logging
import random
import sys
import time
import numpy as np
import matplotlib.pyplot as plt
import pygame
from pygame.locals import *
from carla.client import CarlaClient
try:
import pygame
from pygame.locals import *
except ImportError:
raise RuntimeError('cannot import pygame, make sure pygame package is installed')
try:
from carla.carla_server_pb2 import Control
import numpy as np
except ImportError:
raise RuntimeError('cannot import "carla_server_pb2.py", run the protobuf compiler to generate this file')
raise RuntimeError('cannot import numpy, make sure numpy package is installed')
from carla import image_converter
from carla.client import make_carla_client, VehicleControl
from carla.settings import CarlaSettings, Camera
from carla.tcp import TCPConnectionError
from carla.util import print_over_same_line
def join_classes(labels_image):
classes_join = {
0: [0, 0, 0], # None
1: [70, 70, 70], # Buildings
2: [190, 153, 153], # Fences
3: [72, 0, 90], # Other
4: [220, 20, 60], # Pedestrians
5: [153, 153, 153], # Poles
6: [157, 234, 50], # RoadLines
7: [128, 64, 128], # Roads
8: [244, 35, 232], # Sidewalks
9: [107, 142, 35], # Vegetation
10: [0, 0, 255], # Vehicles
11: [102, 102, 156], # Walls
12: [220, 220, 0] # TrafficSigns
}
compressed_labels_image = np.zeros((labels_image.shape[0], labels_image.shape[1], 3))
for (key, value) in classes_join.items():
compressed_labels_image[np.where(labels_image == key)] = value
return compressed_labels_image
WINDOW_WIDTH = 800
WINDOW_HEIGHT = 600
MINI_WINDOW_WIDTH = 320
MINI_WINDOW_HEIGHT = 180
def grayscale_colormap(img, colormap):
"""Make colormaps from grayscale."""
cmap = plt.get_cmap(colormap)
rgba_img = cmap(img)
rgb_img = np.delete(rgba_img, 3, 2)
return rgb_img
def make_carla_settings():
settings = CarlaSettings()
settings.set(
SynchronousMode=False,
NumberOfVehicles=15,
NumberOfPedestrians=30,
WeatherId=random.choice([1, 3, 7, 8, 14]))
settings.randomize_seeds()
camera0 = Camera('CameraRGB')
camera0.set_image_size(WINDOW_WIDTH, WINDOW_HEIGHT)
camera0.set_position(200, 0, 140)
camera0.set_rotation(0.0, 0.0, 0.0)
settings.add_camera(camera0)
camera1 = Camera('CameraDepth', PostProcessing='Depth')
camera1.set_image_size(MINI_WINDOW_WIDTH, MINI_WINDOW_HEIGHT)
camera1.set_position(200, 0, 140)
camera1.set_rotation(0.0, 0.0, 0.0)
settings.add_camera(camera1)
camera2 = Camera('CameraSemSeg', PostProcessing='SemanticSegmentation')
camera2.set_image_size(MINI_WINDOW_WIDTH, MINI_WINDOW_HEIGHT)
camera2.set_position(200, 0, 140)
camera2.set_rotation(0.0, 0.0, 0.0)
settings.add_camera(camera2)
return settings
def convert_depth(depth):
"""Convert depth to human readable format."""
depth = depth.astype(np.float32)
gray_depth = ((depth[:, :, 0] + # Red
depth[:, :, 1] * 256.0 + # Green
depth[:, :, 2] * 256.0 * 256.0)) # Blue
gray_depth /= (256.0 * 256.0 * 256.0 - 1)
color_depth = grayscale_colormap(gray_depth, 'jet') * 255
return color_depth
def get_image_array(image):
new_image = np.frombuffer(image.raw, dtype=np.dtype("uint8"))
return [np.reshape(new_image, (image.height, image.width, 4))]
if sys.version_info >= (3, 3):
import shutil
def get_terminal_width():
return shutil.get_terminal_size((80, 20)).columns
else:
def get_terminal_width():
return 120
class App(object):
def __init__(
self,
port=2000,
host='127.0.0.1',
config='./CarlaSettings.ini',
resolution=(800, 600),
verbose=True):
self._running = True
self._display_surf = None
self.port = port
self.host = host
with open(config, 'r') as fp:
self.config = fp.read()
self.verbose = verbose
self.resolution = resolution
self.size = self.weight, self.height = resolution
self.reverse_gear = False
def on_init(self):
pygame.init()
print(__doc__)
time.sleep(3)
self._display_surf = pygame.display.set_mode(
self.size, pygame.HWSURFACE | pygame.DOUBLEBUF)
logging.debug('Started the PyGame Library')
self._running = True
class Timer(object):
def __init__(self):
self.step = 0
self.prev_step = 0
self.prev_time = time.time()
self._lap_step = 0
self._lap_time = time.time()
self.carla = CarlaClient(self.host, self.port)
while True:
try:
self.carla.connect()
break
except Exception as e:
logging.error("Cannot connect: %s", e)
time.sleep(1)
scene = self.carla.request_new_episode(self.config)
self.num_pos = len(scene.player_start_spots)
player_start = np.random.randint(self.num_pos)
print("Starting episode...")
self.carla.start_episode(player_start)
self.prev_restart_time = time.time()
def on_event(self, event):
if event.type == pygame.QUIT:
self._running = False
def on_loop(self):
def tick(self):
self.step += 1
keys = pygame.key.get_pressed()
restart = False
control = Control()
def lap(self):
self._lap_step = self.step
self._lap_time = time.time()
pressed_keys = []
def ticks_per_second(self):
return float(self.step - self._lap_step) / self.elapsed_seconds_since_lap()
def elapsed_seconds_since_lap(self):
return time.time() - self._lap_time
class CarlaGame(object):
def __init__(self, carla_client):
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._is_on_reverse = False
def execute(self):
pygame.init()
self._initialize_game()
try:
while True:
for event in pygame.event.get():
if event.type == pygame.QUIT:
return
self._on_loop()
self._on_render()
finally:
pygame.quit()
def _initialize_game(self):
self._display = pygame.display.set_mode(
(WINDOW_WIDTH, WINDOW_HEIGHT),
pygame.HWSURFACE | pygame.DOUBLEBUF)
logging.debug('pygame started')
self._on_new_episode()
def _on_new_episode(self):
print('Requesting new episode...')
scene = self.client.request_new_episode(make_carla_settings())
number_of_player_starts = len(scene.player_start_spots)
player_start = np.random.randint(number_of_player_starts)
self.client.start_episode(player_start)
self._timer = Timer()
def _on_loop(self):
self._timer.tick()
measurements, images = self.client.read_measurements()
self._main_image = images[0]
self._mini_view_image1 = images[1]
self._mini_view_image2 = images[2]
# Print measurements every second.
if self._timer.elapsed_seconds_since_lap() > 1.0:
self._print_player_measurements(measurements.player_measurements)
self._timer.lap()
control = self._get_keyboard_control(pygame.key.get_pressed())
if control is None:
self._on_new_episode()
else:
self.client.send_control(control)
def _get_keyboard_control(self, keys):
"""
Return a VehicleControl message based on the pressed keys. Return None
if a new episode was requested.
"""
if keys[K_r]:
return None
control = VehicleControl()
if keys[K_LEFT] or keys[K_a]:
control.steer = -1.0
pressed_keys.append('left')
if keys[K_RIGHT] or keys[K_d]:
control.steer = 1.0
pressed_keys.append('right')
if keys[K_UP] or keys[K_w]:
control.throttle = 1.0
pressed_keys.append('reverse' if self.reverse_gear else 'forward')
if keys[K_DOWN] or keys[K_s]:
control.brake = 1.0
pressed_keys.append('brake')
if keys[K_SPACE]:
control.hand_brake = True
pressed_keys.append('hand-brake')
if keys[K_q]:
self.reverse_gear = not self.reverse_gear
pressed_keys.append('toggle reverse')
if keys[K_r]:
pressed_keys.append('reset')
if time.time() - self.prev_restart_time > 2.:
self.prev_restart_time = time.time()
restart = True
self._is_on_reverse = not self._is_on_reverse
control.reverse = self._is_on_reverse
return control
if time.time() - self.prev_restart_time < 2.:
control.throttle = 0.0
control.steer = 0.0
def _print_player_measurements(self, player_measurements):
message = 'Step {step} ({fps:.1f} FPS): '
message += '{speed:.2f} km/h, '
message += '{other_lane:.0f}% other lane, {offroad:.0f}% off-road'
message = message.format(
step=self._timer.step,
fps=self._timer.ticks_per_second(),
speed=player_measurements.forward_speed,
other_lane=100 * player_measurements.intersection_otherlane,
offroad=100 * player_measurements.intersection_offroad)
print_over_same_line(message)
control.reverse = self.reverse_gear
def _on_render(self):
gap_x = (WINDOW_WIDTH - 2 * MINI_WINDOW_WIDTH) / 3
mini_image_y = WINDOW_HEIGHT - MINI_WINDOW_HEIGHT - gap_x
measurements, images = self.carla.read_measurements()
if self._main_image is not None:
array = image_converter.to_rgb_array(self._main_image)
surface = pygame.surfarray.make_surface(array)
self._display.blit(surface, (0, 0))
self.carla.send_control(control)
if self._mini_view_image1 is not None:
array = image_converter.depth_to_grayscale(self._mini_view_image1)
surface = pygame.surfarray.make_surface(array)
self._display.blit(surface, (gap_x, mini_image_y))
pack = measurements.player_measurements
self.img_vec = get_image_array(images[0])
self.depth_vec = get_image_array(images[1])
self.labels_vec = get_image_array(images[2])
if time.time() - self.prev_time > 1.:
message = 'Step {step} ({fps:.1f} FPS): '
message += '{speed:.2f} km/h, '
message += '{other_lane:.0f}% other lane, {offroad:.0f}% off-road'
message += ': pressed [%s]' % ', '.join(pressed_keys)
message = message.format(
step=self.step,
fps=float(self.step - self.prev_step) / (time.time() - self.prev_time),
speed=pack.forward_speed,
other_lane=100 * pack.intersection_otherlane,
offroad=100 * pack.intersection_offroad)
empty_space = max(0, get_terminal_width() - len(message))
sys.stdout.write('\r' + message + empty_space * ' ')
sys.stdout.flush()
self.prev_step = self.step
self.prev_time = time.time()
if restart:
print('\n *** RESTART *** \n')
player_pos = np.random.randint(self.num_pos)
print(' Player pos %d \n' % (player_pos))
self.carla.newEpisode(player_pos)
def on_render(self):
"""
The render method plots the First RGB, the First Depth and First
Semantic Segmentation Camera.
"""
auxImgResolution = (320, 180)
auxImgYPos = self.height - auxImgResolution[1] - 25
nImages = 2
f = ((self.weight - nImages * auxImgResolution[0]) / (nImages + 1) + auxImgResolution[0])
x_pos = (self.weight - nImages * auxImgResolution[0]) / (nImages + 1)
if self.img_vec:
self.img_vec[0] = self.img_vec[0][:, :, :3]
self.img_vec[0] = self.img_vec[0][:, :, ::-1]
surface = pygame.surfarray.make_surface(
np.transpose(self.img_vec[0], (1, 0, 2)))
self._display_surf.blit(surface, (0, 0))
if self.depth_vec:
self.depth_vec[0] = self.depth_vec[0][:, :, :3]
self.depth_vec[0] = self.depth_vec[0][:, :, ::-1]
self.depth_vec[0] = convert_depth(self.depth_vec[0])
surface = pygame.surfarray.make_surface(
np.transpose(self.depth_vec[0], (1, 0, 2)))
# Resize image
auxImgXPos = (self.weight / 4) - (auxImgResolution[0] / 2)
surface = pygame.transform.scale(surface, auxImgResolution)
self._display_surf.blit(surface, (x_pos, auxImgYPos))
x_pos += f
if self.labels_vec:
self.labels_vec[0] = join_classes(self.labels_vec[0][:, :, 2])
surface = pygame.surfarray.make_surface(
np.transpose(self.labels_vec[0], (1, 0, 2)))
# Resize image
auxImgXPos = ((self.weight / 4) * 3) - (auxImgResolution[0] / 2)
surface = pygame.transform.scale(surface, auxImgResolution)
self._display_surf.blit(surface, (x_pos, auxImgYPos))
x_pos += f
if self._mini_view_image2 is not None:
array = image_converter.labels_to_cityscapes_palette(self._mini_view_image2)
surface = pygame.surfarray.make_surface(array)
self._display.blit(surface, (2 * gap_x + MINI_WINDOW_WIDTH, mini_image_y))
pygame.display.flip()
def on_cleanup(self):
self.carla.disconnect()
pygame.quit()
def on_execute(self):
if self.on_init() == False:
self._running = False
while(self._running):
try:
for event in pygame.event.get():
self.on_event(event)
self.on_loop()
self.on_render()
except Exception as e:
logging.exception(e)
self._running = False
break
self.on_cleanup()
def main():
parser = argparse.ArgumentParser(
description='Run the carla client manual that connects to CARLA server')
parser.add_argument(
'host',
metavar='HOST',
type=str,
help='host to connect to')
parser.add_argument(
'port',
metavar='PORT',
argparser = argparse.ArgumentParser(description=__doc__)
argparser.add_argument(
'-v', '--verbose',
action='store_true',
dest='debug',
help='print debug information')
argparser.add_argument(
'--host',
metavar='H',
default='localhost',
help='IP of the host server (default: localhost)')
argparser.add_argument(
'-p', '--port',
metavar='P',
default=2000,
type=int,
help='port to connect to')
help='TCP port to listen to (default: 2000)')
args = argparser.parse_args()
parser.add_argument(
"-c",
"--config",
help="the path for the server .ini config file that the client sends",
type=str,
default="./CarlaSettings.ini")
log_level = logging.DEBUG if args.debug else logging.INFO
logging.basicConfig(format='%(levelname)s: %(message)s', level=log_level)
parser.add_argument(
"-l",
"--log",
help="activate the log file",
action="store_true")
parser.add_argument(
"-lv",
"--log_verbose",
help="put the log file to screen",
action="store_true")
args = parser.parse_args()
logging.info('listening to server %s:%s', args.host, args.port)
if args.log or args.log_verbose:
LOG_FILENAME = 'log_manual_control.log'
logging.basicConfig(filename=LOG_FILENAME, level=logging.DEBUG)
if args.log_verbose: # set of functions to put the logging to screen
print(__doc__)
root = logging.getLogger()
root.setLevel(logging.DEBUG)
ch = logging.StreamHandler(sys.stdout)
ch.setLevel(logging.DEBUG)
formatter = logging.Formatter(
'%(asctime)s - %(name)s - %(levelname)s - %(message)s')
ch.setFormatter(formatter)
root.addHandler(ch)
while True:
try:
theApp = App(port=args.port, host=args.host, config=args.config)
theApp.on_execute()
with make_carla_client(args.host, args.port) as client:
game = CarlaGame(client)
game.execute()
break
except TCPConnectionError as error:
logging.error(error)
time.sleep(1)
except Exception as exception:
logging.exception(exception)
sys.exit(1)
if __name__ == '__main__':

View File

@ -8,6 +8,7 @@
"""Basic CARLA client example."""
from __future__ import print_function
import argparse
import logging
@ -18,11 +19,11 @@ import time
from carla.client import make_carla_client
from carla.console import CarlaClientConsole
from carla.settings import CarlaSettings, Camera
from carla.tcp import TCPConnectionError
def run_carla_client(host, port, autopilot_on, save_images_to_disk, image_filename_format):
def run_carla_client(host, port, autopilot_on, save_images_to_disk, image_filename_format, settings):
# Here we will run 3 episodes with 300 frames each.
number_of_episodes = 3
frames_per_episode = 300
@ -38,40 +39,42 @@ def run_carla_client(host, port, autopilot_on, save_images_to_disk, image_filena
for episode in range(0, number_of_episodes):
# Start a new episode.
# Create a CarlaSettings object. This object is a handy wrapper
# around the CarlaSettings.ini file. Here we set the configuration
# we want for the new episode.
settings = CarlaSettings()
settings.set(
SynchronousMode=True,
NumberOfVehicles=30,
NumberOfPedestrians=50,
WeatherId=random.choice([1, 3, 7, 8, 14]))
settings.randomize_seeds()
if settings is None:
# Create a CarlaSettings object. This object is a handy wrapper
# around the CarlaSettings.ini file. Here we set the
# configuration we want for the new episode.
settings = CarlaSettings()
settings.set(
SynchronousMode=True,
NumberOfVehicles=20,
NumberOfPedestrians=40,
WeatherId=random.choice([1, 3, 7, 8, 14]))
settings.randomize_seeds()
# Now we want to add a couple of cameras to the player vehicle. We
# will collect the images produced by these cameras every frame.
# Now we want to add a couple of cameras to the player vehicle.
# We will collect the images produced by these cameras every
# frame.
# The default camera captures RGB images of the scene.
camera0 = Camera('CameraRGB')
# Set image resolution in pixels.
camera0.set_image_size(800, 600)
# Set its position relative to the car in centimeters.
camera0.set_position(30, 0, 130)
settings.add_camera(camera0)
# The default camera captures RGB images of the scene.
camera0 = Camera('CameraRGB')
# Set image resolution in pixels.
camera0.set_image_size(800, 600)
# Set its position relative to the car in centimeters.
camera0.set_position(30, 0, 130)
settings.add_camera(camera0)
# Let's add another camera producing ground-truth depth.
camera1 = Camera('CameraDepth', PostProcessing='Depth')
camera1.set_image_size(800, 600)
camera1.set_position(30, 0, 130)
settings.add_camera(camera1)
# Let's add another camera producing ground-truth depth.
camera1 = Camera('CameraDepth', PostProcessing='Depth')
camera1.set_image_size(800, 600)
camera1.set_position(30, 0, 130)
settings.add_camera(camera1)
print('Requesting new episode...')
# Now we request a new episode with these settings. The server
# replies with a scene description containing the available start
# spots for the player. Here instead of a CarlaSettings object we
# could also provide a CarlaSettings.ini file as string.
# can also provide a CarlaSettings.ini file as string.
scene = client.request_new_episode(settings)
# Choose one player start at random.
@ -152,8 +155,8 @@ def main():
argparser.add_argument(
'--host',
metavar='H',
default='127.0.0.1',
help='IP of the host server (default: 127.0.0.1)')
default='localhost',
help='IP of the host server (default: localhost)')
argparser.add_argument(
'-p', '--port',
metavar='P',
@ -169,25 +172,24 @@ def main():
action='store_true',
help='save images to disk')
argparser.add_argument(
'-c', '--console',
action='store_true',
help='start the client console')
'-c', '--carla-settings',
metavar='PATH',
default=None,
help='Path to a "CarlaSettings.ini" file')
args = argparser.parse_args()
log_level = logging.DEBUG if args.debug else logging.INFO
logging.basicConfig(format='carla_client: %(levelname)s: %(message)s', level=log_level)
logging.basicConfig(format='%(levelname)s: %(message)s', level=log_level)
logging.info('listening to server %s:%s', args.host, args.port)
if args.console:
args.synchronous = True
cmd = CarlaClientConsole(args)
try:
cmd.cmdloop()
finally:
cmd.cleanup()
return
if args.carla_settings is not None:
logging.info('reading CarlaSettings from %r', args.carla_settings)
with open(args.carla_settings, 'r') as fp:
settings = fp.read()
else:
settings = None
while True:
try:
@ -197,14 +199,18 @@ def main():
port=args.port,
autopilot_on=args.autopilot,
save_images_to_disk=args.images_to_disk,
image_filename_format='_images/episode_{:0>3d}/camera_{:0>3d}/image_{:0>5d}.png')
image_filename_format='_images/episode_{:0>3d}/camera_{:0>3d}/image_{:0>5d}.png',
settings=settings)
if end:
return
except Exception as exception:
logging.error('exception: %s', exception)
except TCPConnectionError as error:
logging.error(error)
time.sleep(1)
except Exception as exception:
logging.exception(exception)
sys.exit(1)
if __name__ == '__main__':

View File

View File

@ -15,8 +15,8 @@ import threading
import time
from .client import CarlaClient
from .settings import CarlaSettings, Camera
from carla.client import CarlaClient
from carla.settings import CarlaSettings, Camera
class _Control(object):
@ -88,7 +88,6 @@ class CarlaClientConsole(cmd.Cmd):
self.done = False
self.thread.start()
def cleanup(self):
self.do_disconnect()
self.done = True

View File

@ -20,11 +20,12 @@ sys.path.append(os.path.join(os.path.dirname(__file__), '..'))
import carla
from carla.client import CarlaClient
from carla.console import CarlaClientConsole
from carla.settings import CarlaSettings, Camera
from carla.tcp import TCPClient
from carla.util import make_connection
import console
def run_carla_client(args):
with make_connection(CarlaClient, args.host, args.port, timeout=15) as client:
@ -140,7 +141,7 @@ def main():
logging.info('listening to server %s:%s', args.host, args.port)
if args.console:
cmd = CarlaClientConsole(args)
cmd = console.CarlaClientConsole(args)
try:
cmd.cmdloop()
finally: