carla-simulator / carla

Open-source simulator for autonomous driving research.
http://carla.org
MIT License
11.11k stars 3.58k forks source link

Changing the player vehicle #764

Closed link-er closed 5 years ago

link-er commented 6 years ago

Hello!

I want to record separate distinct datasets of camera images by running autopilot and I would prefer to have distinct cars as player vehicle. I am changing the setting PlayerVehicle as it is documented to various values following https://github.com/carla-simulator/carla/issues/671 , but I always get the same default Mustang. I tried it both with Carla0.8.2 and Carla 0.8.4. I am running the prebuild version for Ubuntu with

./CarlaUE4.sh /Game/Maps/Town01 -benchmark -fps=25 -windowed -ResX=1000 -ResY=500 -carla-server

and

python client_example.py --autopilot -i

I am changing the value of PlayerVehicle inside of the script client_example.py and even (maybe it is used for the server?) in the Example.CarlaSettings.ini, but nothing affects the car

Can you suggest what is the problem?

marcgpuig commented 6 years ago

Hi @link-er. First of all, if you want to use the CarlaSettings.ini you must send it to the simulator:

./CarlaUE4.sh /Game/Maps/Town01 -benchmark -fps=25 -windowed -ResX=1000 -ResY=500 -carla-server -carla-settings="Path/To/CarlaSettings.ini"

I recommend you to keep the file in the default path so you can use -carla-settings="Example.CarlaSettings.ini"

Will be good if you share your code because if you have done it right in your python code it must work anyway.

link-er commented 5 years ago

Hi @marcgpuig. Thank you for the answer - providing the settings file when starting server did change the car finally. But I am a bit confused - I thought that settings of the client overlay settings of the server? If no, then does it mean that all the settings would be always taken from the server settings? The weather is changing when I change it in the client script though. And now, when I changed the car, in some models I can see the frontal window in the recorded data. I thought I can get read of it by moving the camera (camera.set_position(x,y,z)), but I tried to change it both in server settings and in client settings without any success. Any ideas here? 000002

marcgpuig commented 5 years ago

@link-er Settings in the Python client overlaps the setting on the CarlaSettings.ini. Maybe you are sending the settings after starting the simulation? Can I see your code? See how we've done it here: https://github.com/carla-simulator/carla/blob/09df66a08326cec590dc4fa7757a2ece372154b2/PythonClient/manual_control.py#L84-L88

link-er commented 5 years ago

@marcgpuig I am using PythonClient example code basically, with slight changes of initial positions. But I definitely first start server and then Client - so that is the reason then? I do not have any uniting code, I am just starting both scripts manually in separate terminals.

link-er commented 5 years ago

@marcgpuig I tried it with the position you set in both settings - server and client - and I still has the same image. Here is my client code

from __future__ import print_function

import argparse
import logging
import random
import time

from carla.client import make_carla_client
from carla.sensor import Camera, Lidar
from carla.settings import CarlaSettings
from carla.tcp import TCPConnectionError
from carla.util import print_over_same_line

TRAIN_POSITIONS_T1 = [  0,   1,   2,   3,   4,   5,   6,   7,   8,   9,  10,  11,  12,
        13,  14,  21,  26,  27,  28,  29,  30,  31,  32,  33,  34,  43,
        54,  65,  72,  73,  78,  79,  80,  81,  82,  83,  84,  85,  86,
        87,  88,  89,  94,  95,  96,  97,  98,  99, 100, 101, 102, 103,
       104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116,
       117, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130,
       131, 132, 133, 140, 149, 150, 151, 118]

def run_carla_client(args):
    # Here we will run train episodes with 400 frames each.
    number_of_episodes = len(TRAIN_POSITIONS_T1)
    frames_per_episode = 400

    # We assume the CARLA server is already waiting for a client to connect at
    # host:port. To create a connection we can use the `make_carla_client`
    # 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(args.host, args.port) as client:
        print('CarlaClient connected')
        driving_commands = open("driving_commands.txt", "w")
        coordinates = open("coordinates.txt", "w")
        speeds = open("speeds.txt", "w")

        for episode in range(0, number_of_episodes):
            # Start a new episode.

            # Create a CarlaSettings object. This object is a wrapper around
            # the CarlaSettings.ini file. Here we set the configuration we
            # want for the new episode.
            settings = CarlaSettings()
            settings.set(
                SynchronousMode=True,
                SendNonPlayerAgentsInfo=True,
                NumberOfVehicles=20,
                NumberOfPedestrians=40,
                WeatherId=random.choice(range(15)),
                QualityLevel=args.quality_level)
            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.

            # 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 meters.
            camera0.set_position(2.0, 0.0, 1.4)
            settings.add_sensor(camera0)

            # Now we load these settings into the server. The server replies
            # with a scene description containing the available start spots for
            # the player. Here we can provide a CarlaSettings object or a
            # CarlaSettings.ini file as string.
            scene = client.load_settings(settings)

            # Choose one player start.
            player_start = TRAIN_POSITIONS_T1[episode]

            # Notify the server that we want to start the episode at the
            # player_start index. This function blocks until the server is ready
            # to start the episode.
            print('Starting new episode...')
            client.start_episode(player_start)

            # Iterate every frame in the episode.
            for frame in range(0, frames_per_episode):

                # Read the data produced by the server this frame.
                measurements, sensor_data = client.read_data()

                # Print some of the measurements.
                print_measurements(measurements)
                coordinates.write(str(measurements.player_measurements.transform.location.x) + "\t" + str(measurements.player_measurements.transform.location.y) + "\n")
                speeds.write(str(measurements.player_measurements.forward_speed) + "\n")

                # Save the images to disk if requested.
                if args.save_images_to_disk:
                    for name, measurement in sensor_data.items():
                        filename = args.out_filename_format.format(episode, name, frame)
                        measurement.save_to_disk(filename)

                # Now we have to send the instructions to control the vehicle.
                # If we are in synchronous mode the server will pause the
                # simulation until we send this control.

                if not args.autopilot:

                    client.send_control(
                        steer=random.uniform(-1.0, 1.0),
                        throttle=0.5,
                        brake=0.0,
                        hand_brake=False,
                        reverse=False)

                else:

                    # Together with the measurements, the server has sent the
                    # control that the in-game autopilot would do this frame. We
                    # can enable autopilot by sending back this control to the
                    # server. We can modify it if wanted, here for instance we
                    # will add some noise to the steer.

                    control = measurements.player_measurements.autopilot_control
                    driving_commands.write(str(control.steer) + "\n")
                    control.steer += random.uniform(-0.1, 0.1)
                    client.send_control(control)
        driving_commands.close()
        coordinates.close()
        speeds.close()

def print_measurements(measurements):
    number_of_agents = len(measurements.non_player_agents)
    player_measurements = measurements.player_measurements
    message = 'Vehicle at ({pos_x:.1f}, {pos_y:.1f}), '
    message += '{speed:.0f} km/h, '
    message += 'Collision: {{vehicles={col_cars:.0f}, pedestrians={col_ped:.0f}, other={col_other:.0f}}}, '
    message += '{other_lane:.0f}% other lane, {offroad:.0f}% off-road, '
    message += '({agents_num:d} non-player agents in the scene)'
    message = message.format(
        pos_x=player_measurements.transform.location.x,
        pos_y=player_measurements.transform.location.y,
        speed=player_measurements.forward_speed * 3.6, # m/s -> km/h
        col_cars=player_measurements.collision_vehicles,
        col_ped=player_measurements.collision_pedestrians,
        col_other=player_measurements.collision_other,
        other_lane=100 * player_measurements.intersection_otherlane,
        offroad=100 * player_measurements.intersection_offroad,
        agents_num=number_of_agents)
    print_over_same_line(message)

def main():
    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='TCP port to listen to (default: 2000)')
    argparser.add_argument(
        '-a', '--autopilot',
        action='store_true',
        help='enable autopilot')
    argparser.add_argument(
        '-l', '--lidar',
        action='store_true',
        help='enable Lidar')
    argparser.add_argument(
        '-q', '--quality-level',
        choices=['Low', 'Epic'],
        type=lambda s: s.title(),
        default='Epic',
        help='graphics quality level, a lower level makes the simulation run considerably faster.')
    argparser.add_argument(
        '-i', '--images-to-disk',
        action='store_true',
        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')

    args = argparser.parse_args()

    log_level = logging.DEBUG if args.debug else logging.INFO
    logging.basicConfig(format='%(levelname)s: %(message)s', level=log_level)

    logging.info('listening to server %s:%s', args.host, args.port)

    args.out_filename_format = '_out/episode_{:0>4d}/{:s}/{:0>6d}'

    while True:
        try:

            run_carla_client(args)

            print('Done.')
            return

        except TCPConnectionError as error:
            logging.error(error)
            time.sleep(1)

if __name__ == '__main__':

    try:
        main()
    except KeyboardInterrupt:
        print('\nCancelled by user. Bye!')

Server settings:

; Example of settings file for CARLA.
;
; This file can be loaded with the Python client to be sent to the server. It
; defines the parameters to be used when requesting a new episode.
;
; Note that server specific variables are only loaded when launching the
; simulator. Use it with `./CarlaUE4.sh -carla-settings=Path/To/This/File`.

[CARLA/Server]
; If set to false, a mock controller will be used instead of waiting for a real
; client to connect. (Server only)
UseNetworking=false
; Ports to use for the server-client communication. This can be overridden by
; the command-line switch `-world-port=N`, write and read ports will be set to
; N+1 and N+2 respectively. (Server only)
WorldPort=2000
; Time-out in milliseconds for the networking operations. (Server only)
ServerTimeOut=10000
; In synchronous mode, CARLA waits every frame until the control from the client
; is received.
SynchronousMode=true
; Send info about every non-player agent in the scene every frame, the
; information is attached to the measurements message. This includes other
; vehicles, pedestrians and traffic signs. Disabled by default to improve
; performance.
SendNonPlayerAgentsInfo=false

[CARLA/QualitySettings]
; Quality level of the graphics, a lower level makes the simulation run
; considerably faster. Available: Low or Epic.
QualityLevel=Epic

[CARLA/LevelSettings]
; Path of the vehicle class to be used for the player. Leave empty for default.
; Paths follow the pattern "/Game/Blueprints/Vehicles/Mustang/Mustang.Mustang_C"
PlayerVehicle="/Game/Blueprints/Vehicles/ChevroletImpala/ChevroletImpala.ChevroletImpala_C"
; Number of non-player vehicles to be spawned into the level.
NumberOfVehicles=15
; Number of non-player pedestrians to be spawned into the level.
NumberOfPedestrians=30
; Index of the weather/lighting presets to use. If negative, the default presets
; of the map will be used.
WeatherId=1
; Seeds for the pseudo-random number generators.
SeedVehicles=123456789
SeedPedestrians=123456789

[CARLA/Sensor]
; Names of the sensors to be attached to the player, comma-separated, each of
; them should be defined in its own subsection.

; Uncomment next line to add a camera called MyCamera to the vehicle
; Sensors=MyCamera

; or uncomment next line to add a camera and a Lidar
; Sensors=MyCamera,MyLidar

; or uncomment next line to add a regular camera and a depth camera
; Sensors=MyCamera,MyCamera/Depth

; Now, every camera we added needs to be defined it in its own subsection.
[CARLA/Sensor/MyCamera]
; Type of the sensor. The available types are:
;   * CAMERA                        A scene capture camera.
;   * LIDAR_RAY_CAST                A Lidar implementation based on ray-casting.
SensorType=CAMERA
; Post-processing effect to be applied to this camera. Valid values:
;   * None                  No effects applied.
;   * SceneFinal            Post-processing present at scene (bloom, fog, etc).
;   * Depth                 Depth map ground-truth only.
;   * SemanticSegmentation  Semantic segmentation ground-truth only.
PostProcessing=SceneFinal
; Size of the captured image in pixels.
ImageSizeX=800
ImageSizeY=600
; Camera (horizontal) field of view in degrees.
FOV=90
; Position of the camera relative to the car in meters.
PositionX=2.0
PositionY=0
PositionZ=1.4
; Rotation of the camera relative to the car in degrees.
RotationPitch=8
RotationRoll=0
RotationYaw=0

[CARLA/Sensor/MyCamera/Depth]
; The sensor can be defined in a subsection of MyCamera so it inherits the
; values in MyCamera. This adds a camera similar to MyCamera but generating
; depth map images instead.
PostProcessing=Depth

[CARLA/Sensor/MyLidar]
SensorType=LIDAR_RAY_CAST
; Number of lasers.
Channels=32
; Measure distance in meters.
Range=50.0
; Points generated by all lasers per second.
PointsPerSecond=100000
; Lidar rotation frequency.
RotationFrequency=10
; Upper and lower laser angles, positive values means above horizontal line.
UpperFOVLimit=10
LowerFOVLimit=-30
; Position and rotation relative to the vehicle.
PositionX=0
PositionY=0
PositionZ=1.40
RotationPitch=0
RotationYaw=0
RotationRoll=0

And I start server this way: ./CarlaUE4.sh /Game/Maps/Town01 -benchmark -fps=25 -windowed -ResX=1000 -ResY=500 -carla-server -carla-settings="Example.CarlaSettings.ini" And client this way: python training_dataset_creator.py --autopilot -i

marcgpuig commented 5 years ago

@link-er Well, this is weird, your code looks good to me... Can you try something like camera0.set_position(2.0, 0.0, 100.0) to exaggerate the camera position and share your results?

link-er commented 5 years ago

@marcgpuig With the height 100 it showed completely out of scope landscape =) But it helped me to understand what is the problem - I was not restarting client script, only the server, after trying to adjust camera. Thus settings were not overridden and the image of the previous setup was displayed. Thank you for help!