merged with carla master after 0.7.0
This commit is contained in:
commit
56c65871e5
|
@ -18,9 +18,9 @@ Util/Build
|
||||||
*.workspace
|
*.workspace
|
||||||
*CodeCompletionFolders.txt
|
*CodeCompletionFolders.txt
|
||||||
*CodeLitePreProcessor.txt
|
*CodeLitePreProcessor.txt
|
||||||
*_pb2.py
|
|
||||||
.codelite
|
.codelite
|
||||||
.tags*
|
.tags*
|
||||||
.vs
|
.vs
|
||||||
__pycache__
|
__pycache__
|
||||||
|
_images
|
||||||
core
|
core
|
||||||
|
|
|
@ -42,7 +42,8 @@
|
||||||
"settings":
|
"settings":
|
||||||
{
|
{
|
||||||
"tab_size": 2,
|
"tab_size": 2,
|
||||||
"translate_tabs_to_spaces": true
|
"translate_tabs_to_spaces": true,
|
||||||
|
"trim_trailing_white_space_on_save": true
|
||||||
},
|
},
|
||||||
"build_systems":
|
"build_systems":
|
||||||
[
|
[
|
||||||
|
|
19
CHANGELOG.md
19
CHANGELOG.md
|
@ -1,8 +1,25 @@
|
||||||
|
## CARLA 0.7.0
|
||||||
|
|
||||||
|
* New Python client API
|
||||||
|
- Cleaner and more robust
|
||||||
|
- Compatible with Python 2 and 3
|
||||||
|
- Improved exception handling
|
||||||
|
- Improved examples
|
||||||
|
- Included methods for parsing the images
|
||||||
|
- Better documentation
|
||||||
|
- Protocol: renamed "ai_control" to "autopilot_control"
|
||||||
|
- Merged testing client
|
||||||
|
- Added the maps for both cities, the client can now access the car position within the lane.
|
||||||
|
* Make CARLA start without client by default
|
||||||
|
* Added wind effect to some trees and plants
|
||||||
|
* Improvements to the existing weather presets
|
||||||
|
* Build script: skip content download if up-to-date
|
||||||
|
|
||||||
## CARLA 0.6.0
|
## CARLA 0.6.0
|
||||||
|
|
||||||
* Included Unreal project and reorganised folders
|
* Included Unreal project and reorganised folders
|
||||||
* Enabled semantic segmentation by default
|
* Enabled semantic segmentation by default
|
||||||
* Added Felipe's Pyhton client
|
* Added Felipe's Python client
|
||||||
* New build system (Linux only)
|
* New build system (Linux only)
|
||||||
* Few fixes to city assets
|
* Few fixes to city assets
|
||||||
|
|
||||||
|
|
|
@ -8,16 +8,11 @@ started (every time the level is loaded).
|
||||||
Settings are loaded following the next hierarchy, with values later in the
|
Settings are loaded following the next hierarchy, with values later in the
|
||||||
hierarchy overriding earlier values.
|
hierarchy overriding earlier values.
|
||||||
|
|
||||||
1. `{ProjectFolder}/Config/CarlaSettings.ini`
|
1. `{CarlaFolder}/Unreal/CarlaUE4/Config/CarlaSettings.ini`.
|
||||||
2. File provided by command-line argument `-carla-settings=<path-to-ini-file>`
|
2. File provided by command-line argument `-carla-settings="Path/To/CarlaSettings.ini"`.
|
||||||
3. Other command-line arguments as `-world-port`, or `-carla-no-networking`
|
3. Other command-line arguments as `-carla-server` or `-world-port`.
|
||||||
4. Settings file sent by the client on every new episode.
|
4. Settings file sent by the client on every new episode.
|
||||||
|
|
||||||
Take a look at the [CARLA Settings example][settingslink].
|
Take a look at the [CARLA Settings example][settingslink].
|
||||||
|
|
||||||
[settingslink]: https://github.com/carla-simulator/carla/blob/master/Docs/Example.CarlaSettings.ini
|
[settingslink]: https://github.com/carla-simulator/carla/blob/master/Docs/Example.CarlaSettings.ini
|
||||||
|
|
||||||
!!! tip
|
|
||||||
If you are in editor, you most probably want to disable networking.
|
|
||||||
Otherwise the game will hang until a client connects. Set
|
|
||||||
`UseNetworking=false` in "./Unreal/CarlaUE4/Config/CarlaSettings.ini".
|
|
||||||
|
|
|
@ -0,0 +1,35 @@
|
||||||
|
CARLA F.A.Q.
|
||||||
|
============
|
||||||
|
|
||||||
|
#### What is the expected disk space needed for building CARLA?
|
||||||
|
|
||||||
|
Building CARLA from source requires about 15GB of disk space, not counting
|
||||||
|
Unreal Engine installation.
|
||||||
|
|
||||||
|
However, you will also need to build and install Unreal Engine, which on Linux
|
||||||
|
requires much more disk space as it keeps all the intermediate files,
|
||||||
|
[see this thread](https://answers.unrealengine.com/questions/430541/linux-engine-size.html).
|
||||||
|
|
||||||
|
#### Is it possible to dump images from the CARLA server view?
|
||||||
|
|
||||||
|
Yes, this is an Unreal Engine feature. You can dump the images of the server
|
||||||
|
camera by running CARLA with
|
||||||
|
|
||||||
|
$ ./CarlaUE4.sh -benchmark -fps=30 -dumpmovie
|
||||||
|
|
||||||
|
Images are saved to "CarlaUE4/Saved/Screenshots/LinuxNoEditor".
|
||||||
|
|
||||||
|
#### I downloaded CARLA source from GitHub, where is the "CarlaUE4.sh" script?
|
||||||
|
|
||||||
|
There is no "CarlaUE4.sh" script in the source version of CARLA, you need to
|
||||||
|
follow the instructions in the [documentation](http://carla.readthedocs.io) on
|
||||||
|
building CARLA from source.
|
||||||
|
|
||||||
|
Once you open the project in the Unreal Editor, you can hit Play to test CARLA.
|
||||||
|
|
||||||
|
#### How can I create a binary version of CARLA?
|
||||||
|
|
||||||
|
To compile a binary (packaged) version of CARLA, open the CarlaUE4 project with
|
||||||
|
Unreal Editor, go to the menu “File -> Package Project”, and select your
|
||||||
|
platform. This takes a while, but in the end it should generate a packaged
|
||||||
|
version of CARLA to execute without Unreal Editor.
|
|
@ -6,7 +6,7 @@ How to build CARLA on Linux
|
||||||
|
|
||||||
Install the build tools and dependencies
|
Install the build tools and dependencies
|
||||||
|
|
||||||
$ sudo apt-get install build-essential clang-3.9 git cmake ninja-build python3-pip python3-requests python-dev tzdata curl wget unzip autoconf libtool
|
$ sudo apt-get install build-essential clang-3.9 git cmake ninja-build python3-pip python3-requests python-dev tzdata sed curl wget unzip autoconf libtool
|
||||||
$ sudo pip3 install protobuf
|
$ sudo pip3 install protobuf
|
||||||
|
|
||||||
To avoid compatibility issues between Unreal Engine and the CARLA dependencies,
|
To avoid compatibility issues between Unreal Engine and the CARLA dependencies,
|
||||||
|
@ -74,6 +74,15 @@ use the Makefile generated in the Unreal project folder
|
||||||
$ cd Unreal/CarlaUE4
|
$ cd Unreal/CarlaUE4
|
||||||
$ make CarlaUE4Editor
|
$ make CarlaUE4Editor
|
||||||
|
|
||||||
|
Updating CARLA
|
||||||
|
--------------
|
||||||
|
|
||||||
|
Every new release of CARLA we release a new package with the latest changes in
|
||||||
|
the CARLA assets. To download the latest version, run the "Update" script
|
||||||
|
|
||||||
|
$ git pull
|
||||||
|
$ ./Update.sh
|
||||||
|
|
||||||
Launching the editor
|
Launching the editor
|
||||||
--------------------
|
--------------------
|
||||||
|
|
||||||
|
|
|
@ -7,79 +7,88 @@ CARLA Simulator
|
||||||
Welcome to CARLA simulator.
|
Welcome to CARLA simulator.
|
||||||
|
|
||||||
This file contains the instructions to run the CARLA simulator binaries on
|
This file contains the instructions to run the CARLA simulator binaries on
|
||||||
Linux. [Get the latest release here.][releaselink]
|
Linux.
|
||||||
|
|
||||||
|
[Get the latest release here.][releaselink]
|
||||||
|
|
||||||
For building CARLA from source, please check out the
|
For building CARLA from source, please check out the
|
||||||
[CARLA Documentation][docslink].
|
[CARLA Documentation][docslink].
|
||||||
|
|
||||||
|
CARLA can be run directly by running the "CarlaUE4.sh" script provided in the
|
||||||
|
release package.
|
||||||
|
|
||||||
|
There are currently two scenarios available, the desired scenario can be chosen
|
||||||
|
from the command-line
|
||||||
|
|
||||||
|
$ ./CarlaUE4.sh /Game/Maps/Town01
|
||||||
|
|
||||||
|
or
|
||||||
|
|
||||||
|
$ ./CarlaUE4.sh /Game/Maps/Town02
|
||||||
|
|
||||||
|
To run CARLA as server, see ["Running the server"](#running-the-server) below.
|
||||||
|
|
||||||
[releaselink]: https://github.com/carla-simulator/carla/releases/latest
|
[releaselink]: https://github.com/carla-simulator/carla/releases/latest
|
||||||
[docslink]: http://carla.readthedocs.io
|
[docslink]: http://carla.readthedocs.io
|
||||||
|
|
||||||
Running the Python client
|
Running the Python client
|
||||||
-------------------------
|
-------------------------
|
||||||
|
|
||||||
Requires Python 3 with some extra modules installed
|
The "carla" Python module provides a basic API for communicating with the CARLA
|
||||||
|
server. In the "PythonClient" folder we provide a couple of examples on how to
|
||||||
|
use this API. We recommend Python 3, but they are also compatible with Python 2.
|
||||||
|
|
||||||
|
The basic functionality requires only the protobuf module to be installed
|
||||||
|
|
||||||
$ sudo apt-get install python3 python3-pip
|
$ sudo apt-get install python3 python3-pip
|
||||||
$ sudo pip3 install protobuf numpy Pillow
|
$ sudo pip3 install protobuf
|
||||||
|
|
||||||
A sample Python script is provided at `PythonClient/client_example.py`. The
|
However, other operations as handling images require some extra modules, and the
|
||||||
script is well commented explaining how to use the client API.
|
"manual_control.py" example requires pygame
|
||||||
|
|
||||||
The script can be run and provides basic functionality for controlling the
|
$ sudo pip3 install numpy Pillow pygame
|
||||||
vehicle and saving images to disk. Run the help command to see options available
|
|
||||||
|
|
||||||
$ ./carla_example.py --help
|
The script "PythonClient/client_example.py" provides basic functionality for
|
||||||
|
controlling the vehicle and saving images to disk. Run the help command to see
|
||||||
|
options available
|
||||||
|
|
||||||
A second Python script is provided at `PythonClient/carla_manual_control.py`.
|
$ ./client_example.py --help
|
||||||
The script is pygame dependent and serves as an interactive example where the
|
|
||||||
user controls the car with a keyboard.
|
|
||||||
|
|
||||||
$ sudo apt-get install python3-tk
|
The script "PythonClient/manual_control.py" launches a PyGame window with
|
||||||
$ sudo pip3 install pygame matplolib
|
several views and allows to control the vehicle using the WASD keys.
|
||||||
|
|
||||||
Run the help command to see options available
|
$ ./manual_control.py --help
|
||||||
|
|
||||||
$ ./carla_manual_control.py --help
|
|
||||||
|
|
||||||
Running the server
|
Running the server
|
||||||
------------------
|
------------------
|
||||||
|
|
||||||
!!! note
|
The server can be started by running the "CarlaUE4.sh" script with some extra
|
||||||
By default the game starts in networking mode. It will hang until a client
|
arguments. When run in server mode (controlled by the CARLA client), it is
|
||||||
is connected. See below how to run it without client.
|
highly recommended to run it at fixed time-step
|
||||||
|
|
||||||
The server can be started by running the `CarlaUE4.sh` script. When run in
|
$ ./CarlaUE4.sh /Game/Maps/Town01 -carla-server -benchmark -fps=15
|
||||||
networking mode (controlled by the CARLA client), it is highly recommended to
|
|
||||||
run it at fixed time-step
|
|
||||||
|
|
||||||
$ ./CarlaUE4.sh /Game/Maps/Town01 -benchmark -fps=15
|
|
||||||
|
|
||||||
The arguments `-benchmark -fps=15` make the engine run at a fixed time-step of
|
The arguments `-benchmark -fps=15` make the engine run at a fixed time-step of
|
||||||
1/15 seconds. In this mode, game-time decouples from real-time and the
|
1/15 seconds. In this mode, game-time decouples from real-time and the
|
||||||
simulation runs as fast as possible.
|
simulation runs as fast as possible.
|
||||||
|
|
||||||
To run the game on the second city, just change the command to select the
|
To run the game on the second town, just change the command to select the
|
||||||
"Town02"
|
"Town02" map
|
||||||
|
|
||||||
$ ./CarlaUE4.sh /Game/Maps/Town02 -benchmark -fps=15
|
$ ./CarlaUE4.sh /Game/Maps/Town02 -carla-server -benchmark -fps=15
|
||||||
|
|
||||||
To run the game windowed at a given resolution
|
When run as server, it is sometimes useful to run the game in a smaller window,
|
||||||
|
this can be chosen with
|
||||||
|
|
||||||
$ ./CarlaUE4.sh /Game/Maps/Town01 -benchmark -fps=15 -windowed -ResX=800 -ResY=600
|
$ ./CarlaUE4.sh /Game/Maps/Town01 -carla-server -benchmark -fps=15 -windowed -ResX=800 -ResY=600
|
||||||
|
|
||||||
The game can also be run without a client, this way you can drive around the
|
#### CARLA specific command-line options
|
||||||
city just using the keyboard (in this mode is not recommended to use fixed
|
|
||||||
frame-rate to get a more realistic feeling)
|
|
||||||
|
|
||||||
$ ./CarlaUE4.sh /Game/Maps/Town02 -carla-no-networking
|
* `-carla-server` Launches CARLA as server, the execution hangs until a client connects.
|
||||||
|
* `-carla-settings="Path/To/CarlaSettings.ini"` Load settings from the given INI file. See Example.CarlaSettings.ini.
|
||||||
#### CARLA command-line options
|
* `-carla-world-port=N` Listen for client connections at port N, agent ports are set to N+1 and N+2 respectively. Activates server.
|
||||||
|
|
||||||
* `-carla-settings=<ini-file-path>` Load settings from the given INI file. See Example.CarlaSettings.ini.
|
|
||||||
* `-carla-world-port=<port-number>` Listen for client connections at <port-number>, agent ports are set to <port-number>+1 and <port-number>+2 respectively. Activates networking.
|
|
||||||
* `-carla-no-networking` Disable networking. Overrides other settings.
|
|
||||||
* `-carla-no-hud` Do not display the HUD by default.
|
* `-carla-no-hud` Do not display the HUD by default.
|
||||||
|
* `-carla-no-networking` Disable networking. Overrides `-carla-server` if present.
|
||||||
|
|
||||||
#### Running CARLA off-screen
|
#### Running CARLA off-screen
|
||||||
|
|
||||||
|
@ -134,9 +143,9 @@ started (every time the level is loaded).
|
||||||
Settings are loaded following the next hierarchy, with values later in the
|
Settings are loaded following the next hierarchy, with values later in the
|
||||||
hierarchy overriding earlier values.
|
hierarchy overriding earlier values.
|
||||||
|
|
||||||
1. `{ProjectFolder}/Config/CarlaSettings.ini`
|
1. `{ProjectFolder}/Config/CarlaSettings.ini`.
|
||||||
2. File provided by command-line argument `-carla-settings=<path-to-ini-file>`
|
2. File provided by command-line argument `-carla-settings="Path/To/CarlaSettings.ini"`.
|
||||||
3. Other command-line arguments as `-world-port`, or `-carla-no-networking`
|
3. Other command-line arguments as `-carla-server` or `-world-port`.
|
||||||
4. Settings file sent by the client on every new episode.
|
4. Settings file sent by the client on every new episode.
|
||||||
|
|
||||||
Take a look at the Example.CarlaSettings.ini file for further details.
|
Take a look at the Example.CarlaSettings.ini file for further details.
|
||||||
|
|
Binary file not shown.
After Width: | Height: | Size: 424 KiB |
|
@ -7,6 +7,8 @@ CARLA Documentation
|
||||||
* [CARLA settings](carla_settings.md)
|
* [CARLA settings](carla_settings.md)
|
||||||
* [Measurements](measurements.md)
|
* [Measurements](measurements.md)
|
||||||
* [Cameras and sensors](cameras_and_sensors.md)
|
* [Cameras and sensors](cameras_and_sensors.md)
|
||||||
|
|
||||||
|
* [F.A.Q.](faq.md)
|
||||||
* [Troubleshooting](troubleshooting.md)
|
* [Troubleshooting](troubleshooting.md)
|
||||||
|
|
||||||
#### Building from source
|
#### Building from source
|
||||||
|
@ -17,5 +19,6 @@ CARLA Documentation
|
||||||
|
|
||||||
#### Development
|
#### Development
|
||||||
|
|
||||||
|
* [Map customization](map_customization.md)
|
||||||
* [How to add assets](how_to_add_assets.md)
|
* [How to add assets](how_to_add_assets.md)
|
||||||
* [CarlaServer documentation](carla_server.md)
|
* [CarlaServer documentation](carla_server.md)
|
||||||
|
|
|
@ -0,0 +1,93 @@
|
||||||
|
# Map customization
|
||||||
|
|
||||||
|
This are the specific blueprint assets created to help building the environment.
|
||||||
|
|
||||||
|
## MultipleFloorBuilding:
|
||||||
|
|
||||||
|
The purpose of this blueprint is to make repeating and varying tall buildings a bit easier. Provided a Base, a MiddleFloor and a roof; this blueprint repeats the middle floor to the desired number of stores and tops it whith the last floor given some conditions:
|
||||||
|
- All model pivots should be in the bottom center of the Specific mesh.
|
||||||
|
- Al models must start and end exactly where the repetition happen.
|
||||||
|
|
||||||
|
This blueprint is controlled by this 6 specific Parameters:
|
||||||
|
|
||||||
|
- GroundFloor: The mesh to be placed in the base of the building.
|
||||||
|
- Floor: The mesh to be repeated along the building.
|
||||||
|
- Roof: Final mesh to top the building.
|
||||||
|
- FloorNumber: Number of stores of the building.
|
||||||
|
- FloorHeightOffset: Adjust The placement of every floor verticaly.
|
||||||
|
- RoofOffset: Adjust the placement of the roof verticaly.
|
||||||
|
|
||||||
|
All of This parameters can be modified once this blueprint is placed in the world.
|
||||||
|
|
||||||
|
## SplinemeshRepeater:
|
||||||
|
|
||||||
|
!!! Bug
|
||||||
|
See [#35 SplineMeshRepeater loses its collider mesh](https://github.com/carla-simulator/carla/issues/35)
|
||||||
|
|
||||||
|
### Standard use:
|
||||||
|
|
||||||
|
SplineMeshRepeater "Content/Blueprints/SplineMeshRepeater" is a tool included in the Carla Project to help building urban environments; It repeats and aligns a specific choosen mesh along a [Spline](https://docs.unrealengine.com/latest/INT/Engine/BlueprintSplines/Reference/SplineEditorTool/index.html) (Unreal Component). Its principal function is to build Tipicaly tiled and repetitive structures as Walls, Roads, Bridges, Fences... Once the actor is placed into the world the spline can be modified so the object gets the desired form. Each Point Defining the spline Generates a new tile so that as more points the Spline has, the more defined it will be, but also heavyer on the world. This actor is defined by the following parameters:
|
||||||
|
|
||||||
|
|
||||||
|
- StaticMesh: The mesh to be repeated along the spline.
|
||||||
|
- ForWardAxis: Changes the mesh axis to be alingned with the spline.
|
||||||
|
- Material: Overrides the mesh' default material.
|
||||||
|
- Colission Enabled: Chooses the tipe of colission to use.
|
||||||
|
- Gap distance: Places a Gap between each repeated mesh, for repetitive non continuous walls: bush chains, bollards...
|
||||||
|
|
||||||
|
|
||||||
|
(Last three variables are specific for some particular assets to be defined in the next point) A requisite to create assets compatibles with this componenis is that all the meshes have their pivot placed wherever the repetition starts in the lower point possible with the rest of the mesh pointing positive (Preferably by the X axis)
|
||||||
|
|
||||||
|
|
||||||
|
### Specific Walls (Dynamic material)
|
||||||
|
|
||||||
|
In the project folder "Content/Static/Walls" are included some specific assets to be used with this SplineMeshRepeater with a series of special caracteristics. The uv space of this meshes and their materials are the same for all of them, making them excangeable. each material is composed of three different surfaces the last three parameters slightly modify the color of this surfaces:
|
||||||
|
|
||||||
|
- MainMaterialColor: Change the main material of the Wall
|
||||||
|
- DetailsColor: Change the color of the details (if any)
|
||||||
|
- TopWallColor: Cambia el color de la cubierta del muro (if any)
|
||||||
|
|
||||||
|
To add elements that profit from this functions exist in the (Carpeta) folder the GardenWallMask File that defines the uv space to place the materials: (Blue space: MainMaterial; green space: Details; red space TopWall).
|
||||||
|
|
||||||
|
Between the material masters is WallMaster which is going to be the master of the materials using this function. An instance of this material will be created and the correspondent textures will be added. This material includes the following parameters to be modified by the material to use:
|
||||||
|
|
||||||
|
- Normal Flattener: Slightly modifies the normal map values to exagerate it or flatten it.
|
||||||
|
- RoughnessCorrection: Para corregir El valor de rugosidad dado por la textura.
|
||||||
|
|
||||||
|
The rest of the parameters are the mask the textures and the color corrections that won't be modified in this instance but in the blueprint that will be launched into the world.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
## Weather
|
||||||
|
This is the actor in charge of modifying all the lighting, environmental actors an anything that affects the impression of the climate. It runs automaticaly with the game when is not specified otherwise In the Config.Ini but has Its own actor to launch in editor mode to configure the climatic conditions. To fuly work It will need One of each of the folowing actors: SkySphere, Skylight, Postprocess Volume (Boundless) And Light Source to exist in the world.
|
||||||
|
|
||||||
|
- SunPolarAngle: polar angle of the sun, determines time of the day
|
||||||
|
- SunAzimuthAngle: adds to the location of the sun in the current level
|
||||||
|
- SunBrightness: Brightness of the rendering of the sun in the skybox
|
||||||
|
- SunDirectionalLightIntensity: Intensity of the sunlight
|
||||||
|
- SunDirectionalLightColor: Color of the sunlight
|
||||||
|
- SunIndirectLightIntensity: intensity of the bounces of the main light
|
||||||
|
- CloudOpacity: visivility of the cloud rendering on the skybox
|
||||||
|
- HorizontFalloff: determines the height of the gradient between the zenith and horizon color
|
||||||
|
- ZenithColor: Defines the color of the zenith.
|
||||||
|
- HorizonColor: Defines the color of the horizon.
|
||||||
|
- CloudColor: Defines the color of the Clouds, if any.
|
||||||
|
- OverallSkyColor: multiplies every colored element in the sky by a single color.
|
||||||
|
- SkyLightIntensity: Intensity of the light bounced from the sky.
|
||||||
|
- SkyLightColor: Color of the light bounced from the sky.
|
||||||
|
- Precipitation: Defines if any precipitation is active.
|
||||||
|
- PrecipitationType: the type of precipitation to active.
|
||||||
|
- PrecipitationAmount: the quantity of the chosen precipitation.
|
||||||
|
- PrecipitationAccumulation: the acumulation of the chosen precipitation.
|
||||||
|
- bWind: defines if there is any wind.
|
||||||
|
- WindIntensity: defines the wind intensity.
|
||||||
|
- WindAngle: defines the wind direction.
|
||||||
|
- bOverrideCameraPostProcessParameters: Defines if the default camera postprocess is overwritten.
|
||||||
|
- CameraPostProcessParameters.AutoExposureMethod: Defines the method of autoexposure.
|
||||||
|
- CameraPostProcessParameters.AutoExposureMinBrightness: defines the minimum brightness the autoexposure will count as right in the final image.
|
||||||
|
- CameraPostProcessParameters.AutoExposureMaxBrightness: defines the maximum brightness the autoexposure will count as right in the final image.
|
||||||
|
- CameraPostProcessParameters.AutoExposureBias: Darkens or brightens the final image towards a defined bias.
|
||||||
|
|
||||||
|
|
||||||
|
You can have as many different configurations saved in the proyect as you want and choose the configuration to aply while on the build, through the [settings file](carla_settings.md); or in the editor while building the level or testing.
|
|
@ -33,7 +33,7 @@ collision_pedestrians | float | Collision intensity with pedestrians.
|
||||||
collision_other | float | General collision intensity (everything else but pedestrians and vehicles).
|
collision_other | float | General collision intensity (everything else but pedestrians and vehicles).
|
||||||
intersection_otherlane | float | Percentage of the car invading other lanes.
|
intersection_otherlane | float | Percentage of the car invading other lanes.
|
||||||
intersection_offroad | float | Percentage of the car off-road.
|
intersection_offroad | float | Percentage of the car off-road.
|
||||||
ai_control | Control | Vehicle's AI control that would apply this frame.
|
autopilot_control | Control | Vehicle's autopilot control that would apply this frame.
|
||||||
|
|
||||||
###### Transform
|
###### Transform
|
||||||
|
|
||||||
|
@ -67,10 +67,10 @@ rectangle) against the map image of the city. These images are generated in the
|
||||||
editor and serialized for runtime use. You can find them too in the release
|
editor and serialized for runtime use. You can find them too in the release
|
||||||
package under the folder "RoadMaps".
|
package under the folder "RoadMaps".
|
||||||
|
|
||||||
###### AI control
|
###### Autopilot control
|
||||||
|
|
||||||
The `ai_control` measurement contains the control values that the in-game AI
|
The `autopilot_control` measurement contains the control values that the in-game
|
||||||
would apply if it were controlling the vehicle.
|
autopilot system would apply as if it were controlling the vehicle.
|
||||||
|
|
||||||
This is the same structure used to send the vehicle control to the server.
|
This is the same structure used to send the vehicle control to the server.
|
||||||
|
|
||||||
|
@ -82,6 +82,16 @@ brake | float | Brake input between [ 0.0, 1.0]
|
||||||
hand_brake | bool | Whether the hand-brake is engaged
|
hand_brake | bool | Whether the hand-brake is engaged
|
||||||
reverse | bool | Whether the vehicle is in reverse gear
|
reverse | bool | Whether the vehicle is in reverse gear
|
||||||
|
|
||||||
|
To activate the autopilot from the client, send this `autopilot_control` back
|
||||||
|
to the server. Note that you can modify it before sending it back.
|
||||||
|
|
||||||
|
```py
|
||||||
|
measurements, sensor_data = carla_client.read_data()
|
||||||
|
control = measurements.player_measurements.autopilot_control
|
||||||
|
# modify here control if wanted.
|
||||||
|
carla_client.send_control(control)
|
||||||
|
```
|
||||||
|
|
||||||
(*) The actual steering angle depends on the vehicle used. The default Mustang
|
(*) The actual steering angle depends on the vehicle used. The default Mustang
|
||||||
has a maximum steering angle of 70 degrees (this can be checked in the vehicle's
|
has a maximum steering angle of 70 degrees (this can be checked in the vehicle's
|
||||||
front wheel blueprint).
|
front wheel blueprint).
|
||||||
|
@ -102,10 +112,22 @@ If enabled, the server attaches a list of agents to the measurements package
|
||||||
every frame. Each of these agents has an unique id that identifies it, and
|
every frame. Each of these agents has an unique id that identifies it, and
|
||||||
belongs to one of the following classes
|
belongs to one of the following classes
|
||||||
|
|
||||||
* **Vehicle** Contains its transform, bounding-box, and forward speed.
|
* **Vehicle** Contains its transform, box-extent, and forward speed.
|
||||||
* **Pedestrian** Contains its transform, bounding-box, and forward speed. (*)
|
* **Pedestrian** Contains its transform, box-extent, and forward speed. (*)
|
||||||
* **Traffic light** Contains its transform and state (green, yellow, red).
|
* **Traffic light** Contains its transform and state (green, yellow, red).
|
||||||
* **Speed-limit sign** Contains its transform and speed-limit.
|
* **Speed-limit sign** Contains its transform and speed-limit.
|
||||||
|
|
||||||
(*) At this point every pedestrian is assumed to have the same bounding-box
|
(*) At this point every pedestrian is assumed to have the same bounding-box
|
||||||
size.
|
size.
|
||||||
|
|
||||||
|
###### Transform and bounding box
|
||||||
|
|
||||||
|
The transform defines the location and orientation of the agent. The bounding
|
||||||
|
box is assumed to be centered at the agent's location. The box extent gives the
|
||||||
|
radii dimensions of the bounding box of the agent.
|
||||||
|
|
||||||
|
![Vehicle Bounding Box](img/vehicle_bounding_box.png)
|
||||||
|
|
||||||
|
!!! important
|
||||||
|
As seen in the picture, the Z coordinate of the box is not fitted to
|
||||||
|
vehicle's height.
|
||||||
|
|
|
@ -0,0 +1,10 @@
|
||||||
|
CARLA Simulator
|
||||||
|
===============
|
||||||
|
|
||||||
|
Thanks for downloading CARLA!
|
||||||
|
|
||||||
|
Execute "CarlaUE4.sh" to launch CARLA.
|
||||||
|
|
||||||
|
For more details and running options please refer to our online documentation
|
||||||
|
|
||||||
|
http://carla.readthedocs.io
|
|
@ -3,12 +3,26 @@ Troubleshooting
|
||||||
|
|
||||||
#### Editor hangs after hitting Play
|
#### Editor hangs after hitting Play
|
||||||
|
|
||||||
By default, when CARLA is started it waits for a client to be connected and
|
This is most probably happening because CARLA is started in server mode. Check
|
||||||
control the vehicle. This is the intended behavior. This can be changed in
|
in your CarlaSettings.ini file ("./Unreal/CarlaUE4/Config/CarlaSettings.ini")
|
||||||
"./Unreal/CarlaUE4/Config/CarlaSettings.ini" changing `UseNetworking=false`.
|
and set
|
||||||
|
|
||||||
|
```ini
|
||||||
|
[CARLA/Server]
|
||||||
|
UseNetworking=false
|
||||||
|
```
|
||||||
|
|
||||||
#### Very low FPS in editor when not in focus
|
#### Very low FPS in editor when not in focus
|
||||||
|
|
||||||
UE4 Editor goes to a low performance mode when out of focus. It can be disabled
|
UE4 Editor goes to a low performance mode when out of focus. It can be disabled
|
||||||
in the editor preferences. Go to "Edit->Editor Preferences->Performance" and
|
in the editor preferences. Go to "Edit->Editor Preferences->Performance" and
|
||||||
disable the "Use Less CPU When in Background" option.
|
disable the "Use Less CPU When in Background" option.
|
||||||
|
|
||||||
|
#### Fatal error: file '/usr/include/linux/version.h' has been modified since the precompiled header
|
||||||
|
|
||||||
|
This happens from time to time due to Linux updates. It is possible to force a
|
||||||
|
rebuild of all the project files with
|
||||||
|
|
||||||
|
$ cd Unreal/CarlaUE4/
|
||||||
|
$ make CarlaUE4Editor ARGS=-clean
|
||||||
|
$ make CarlaUE4Editor
|
||||||
|
|
2
Makefile
2
Makefile
|
@ -1,5 +1,5 @@
|
||||||
INSTALL_FOLDER=$(CURDIR)/Unreal/CarlaUE4/Plugins/Carla/CarlaServer
|
INSTALL_FOLDER=$(CURDIR)/Unreal/CarlaUE4/Plugins/Carla/CarlaServer
|
||||||
PYTHON_CLIENT_FOLDER=$(CURDIR)/Util/TestingClient/test
|
PYTHON_CLIENT_FOLDER=$(CURDIR)/PythonClient/test
|
||||||
BASE_BUILD_FOLDER=$(CURDIR)/Util/Build/carlaserver-build
|
BASE_BUILD_FOLDER=$(CURDIR)/Util/Build/carlaserver-build
|
||||||
MY_CMAKE_FOLDER=$(CURDIR)/Util/cmake
|
MY_CMAKE_FOLDER=$(CURDIR)/Util/cmake
|
||||||
MY_CMAKE_FLAGS=-B"$(BUILD_FOLDER)" -DCMAKE_INSTALL_PREFIX="$(INSTALL_FOLDER)"
|
MY_CMAKE_FLAGS=-B"$(BUILD_FOLDER)" -DCMAKE_INSTALL_PREFIX="$(INSTALL_FOLDER)"
|
||||||
|
|
|
@ -1,3 +0,0 @@
|
||||||
from .carla import CARLA
|
|
||||||
from .protoc import SceneDescription,EpisodeStart,EpisodeReady,Control,Measurements,RequestNewEpisode
|
|
||||||
|
|
|
@ -1,323 +0,0 @@
|
||||||
#!/usr/bin/env python3
|
|
||||||
|
|
||||||
# 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>.
|
|
||||||
|
|
||||||
from __future__ import print_function
|
|
||||||
|
|
||||||
from .datastream import DataStream
|
|
||||||
import socket
|
|
||||||
import time
|
|
||||||
import os, signal
|
|
||||||
import sys
|
|
||||||
import logging
|
|
||||||
import struct
|
|
||||||
|
|
||||||
import re
|
|
||||||
from .protoc import *
|
|
||||||
|
|
||||||
from . import socket_util
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
def get_image_resolution(data):
|
|
||||||
return int(re.search('[\n\r].*ImageSizeX\s*=([^\n\r]*)', data).group(1)),int(re.search('[\n\r].*ImageSizeY\s*=([^\n\r]*)', data).group(1))
|
|
||||||
|
|
||||||
|
|
||||||
class CARLA(object):
|
|
||||||
|
|
||||||
"""
|
|
||||||
Normal instanciation of the class, creating also the thread class responsible for receiving data
|
|
||||||
"""
|
|
||||||
def __init__(self,host,port):
|
|
||||||
self._host = host
|
|
||||||
self._port = port
|
|
||||||
logging.debug('selected host %s' % host)
|
|
||||||
logging.debug('selected port %s' % port)
|
|
||||||
|
|
||||||
|
|
||||||
self._port_control = self._port +2
|
|
||||||
self._port_stream = self._port +1
|
|
||||||
|
|
||||||
# Default start. Keep it as class param for eventual restart
|
|
||||||
self._image_x =0
|
|
||||||
self._image_y = 0
|
|
||||||
|
|
||||||
|
|
||||||
self._socket_world = socket_util.pers_connect(self._host ,self._port)
|
|
||||||
print ('Successfully Connected to Carla Server')
|
|
||||||
logging.debug("Connected to Unreal Server World Socket")
|
|
||||||
self._socket_stream = 0
|
|
||||||
self._socket_control = 0
|
|
||||||
self._latest_start = 0
|
|
||||||
self._agent_is_running = False
|
|
||||||
|
|
||||||
self._episode_requested = False
|
|
||||||
|
|
||||||
self._data_stream = None
|
|
||||||
logging.debug("Started Unreal Client")
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
"""
|
|
||||||
Starting the Player Agent. The image stream port
|
|
||||||
and the control port
|
|
||||||
|
|
||||||
Args:
|
|
||||||
None
|
|
||||||
Returns:
|
|
||||||
None
|
|
||||||
|
|
||||||
"""
|
|
||||||
|
|
||||||
|
|
||||||
def startAgent(self):
|
|
||||||
|
|
||||||
self._data_stream = DataStream(self._image_x,self._image_y)
|
|
||||||
|
|
||||||
logging.debug("Going to Connect Stream and start thread")
|
|
||||||
# Perform persistent connections, try up to 10 times
|
|
||||||
try:
|
|
||||||
self._socket_stream = socket_util.pers_connect(self._host ,self._port_stream)
|
|
||||||
except Exception:
|
|
||||||
logging.exception("Attempts to connect Stream all failed, restart...")
|
|
||||||
self.restart()
|
|
||||||
|
|
||||||
self._data_stream.start(self._socket_stream)
|
|
||||||
logging.debug("Streaming Thread Started")
|
|
||||||
|
|
||||||
try:
|
|
||||||
self._socket_control = socket_util.pers_connect(self._host ,self._port_control)
|
|
||||||
except Exception:
|
|
||||||
logging.exception("Attempts to connect Agent all failed, restart ...")
|
|
||||||
self.restart()
|
|
||||||
|
|
||||||
logging.debug("Control Socket Connected")
|
|
||||||
self._agent_is_running = True
|
|
||||||
|
|
||||||
def stopAgent(self):
|
|
||||||
|
|
||||||
|
|
||||||
logging.debug("Going to Stop thread and Disconect Stream")
|
|
||||||
self._data_stream.stop()
|
|
||||||
|
|
||||||
logging.debug("Streaming Thread Stoped")
|
|
||||||
|
|
||||||
socket_util.disconnect(self._socket_control)
|
|
||||||
logging.debug("Control Socket DisConnected")
|
|
||||||
self._agent_is_running = False
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
# This function requests a new episode and send the string containing this episode configuration file
|
|
||||||
|
|
||||||
|
|
||||||
def receiveSceneConfiguration(self):
|
|
||||||
|
|
||||||
try:
|
|
||||||
logging.debug("Reading for the scene configuration")
|
|
||||||
data = socket_util.get_message(self._socket_world)
|
|
||||||
|
|
||||||
scene = SceneDescription()
|
|
||||||
scene.ParseFromString(data)
|
|
||||||
logging.debug("Received Scene Configuration")
|
|
||||||
|
|
||||||
|
|
||||||
return scene.player_start_spots
|
|
||||||
|
|
||||||
|
|
||||||
except Exception as e:
|
|
||||||
logging.exception("Server not responing when receiving configuration")
|
|
||||||
return self.restart()
|
|
||||||
|
|
||||||
|
|
||||||
def requestNewEpisode(self,ini_path=None):
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
if ini_path == None:
|
|
||||||
ini_file = self._config_path
|
|
||||||
else:
|
|
||||||
ini_file = ini_path
|
|
||||||
self._config_path = ini_path # We just save the last config file in case the client dies
|
|
||||||
|
|
||||||
requestEpisode = RequestNewEpisode()
|
|
||||||
with open (ini_file, "r") as myfile:
|
|
||||||
data=myfile.read()
|
|
||||||
try:
|
|
||||||
self._image_x,self._image_y = get_image_resolution(data)
|
|
||||||
except Exception as e:
|
|
||||||
logging.exception("No image resolution found on config file")
|
|
||||||
|
|
||||||
|
|
||||||
logging.debug("Resolution %d , %d",self._image_x,self._image_y)
|
|
||||||
|
|
||||||
logging.debug("Set the Init File")
|
|
||||||
logging.debug("sent %s" % (data))
|
|
||||||
requestEpisode.ini_file = data.encode('utf-8')
|
|
||||||
try:
|
|
||||||
socket_util.send_message(self._socket_world,requestEpisode)
|
|
||||||
except Exception as e:
|
|
||||||
logging.exception("Server not responding when requesting new episode")
|
|
||||||
self.restart()
|
|
||||||
else:
|
|
||||||
logging.debug("Successfully sent the new episode Request")
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
if self._agent_is_running:
|
|
||||||
self.stopAgent()
|
|
||||||
self._episode_requested = True
|
|
||||||
|
|
||||||
return self.receiveSceneConfiguration()
|
|
||||||
|
|
||||||
def loadConfigurationFile(self,ini_path):
|
|
||||||
|
|
||||||
return self.requestNewEpisode(ini_path)
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
def newEpisode(self,start_index):
|
|
||||||
|
|
||||||
# Save the latest new episode positon, just in case of crashes
|
|
||||||
self._latest_start = start_index
|
|
||||||
|
|
||||||
if not self._episode_requested:
|
|
||||||
positions = self.requestNewEpisode(self._config_path)
|
|
||||||
|
|
||||||
scene_init = EpisodeStart()
|
|
||||||
scene_init.player_start_spot_index = start_index
|
|
||||||
try:
|
|
||||||
socket_util.send_message(self._socket_world,scene_init)
|
|
||||||
except Exception:
|
|
||||||
logging.exception("Server not responding when trying to send episode start confirmation")
|
|
||||||
self.restart()
|
|
||||||
else:
|
|
||||||
logging.debug("Successfully sent the new episode Message")
|
|
||||||
|
|
||||||
episode_ready = EpisodeReady()
|
|
||||||
episode_ready.ready = False
|
|
||||||
|
|
||||||
try:
|
|
||||||
|
|
||||||
data = socket_util.get_message(self._socket_world)
|
|
||||||
logging.debug("Got the episode ready message")
|
|
||||||
episode_ready.ParseFromString(data)
|
|
||||||
except Exception:
|
|
||||||
logging.exception("Server not responding when trying to receive episode reading")
|
|
||||||
self.restart()
|
|
||||||
else:
|
|
||||||
logging.debug("Episode is Ready")
|
|
||||||
|
|
||||||
self.startAgent()
|
|
||||||
self._episode_requested = False
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
""" Measurements
|
|
||||||
returns
|
|
||||||
@game time
|
|
||||||
@wall time
|
|
||||||
@player measurements
|
|
||||||
@non_player_agents : vector with all agents present on the game
|
|
||||||
@image_data
|
|
||||||
|
|
||||||
"""
|
|
||||||
|
|
||||||
|
|
||||||
def getMeasurements(self):
|
|
||||||
|
|
||||||
while True:
|
|
||||||
try:
|
|
||||||
meas_dict = self._data_stream.get_the_latest_data()
|
|
||||||
|
|
||||||
|
|
||||||
logging.debug("Got A new Measurement")
|
|
||||||
return meas_dict
|
|
||||||
except AttributeError:
|
|
||||||
logging.exception("Unitialized DataStream. Tip: Connect and start an episode before requesting measurements")
|
|
||||||
return None
|
|
||||||
except Exception:
|
|
||||||
logging.exception("Got an empty Measurement")
|
|
||||||
self.restart()
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
""" Command contains:
|
|
||||||
Steering: -1 to 1
|
|
||||||
Acc : -1 to 1
|
|
||||||
"""
|
|
||||||
|
|
||||||
def sendCommand(self,control):
|
|
||||||
|
|
||||||
logging.debug("Send Control Comand : throttle -> %f , steer %f, brake %f, hand_brake %d, gear %d" % (control.throttle,control.steer,control.brake,control.hand_brake,control.reverse))
|
|
||||||
try:
|
|
||||||
socket_util.send_message(self._socket_control,control)
|
|
||||||
except Exception:
|
|
||||||
|
|
||||||
logging.exception("Problems on sending the commands... restarting")
|
|
||||||
self.restart() # the mensage is not resend because it likely lost its relevance.
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
def restart(self):
|
|
||||||
logging.debug("Trying to close clients")
|
|
||||||
self.closeConections()
|
|
||||||
connected = False
|
|
||||||
if self._data_stream != None:
|
|
||||||
self._data_stream._running = False
|
|
||||||
self._agent_is_running = False
|
|
||||||
while not connected:
|
|
||||||
try:
|
|
||||||
logging.debug("Trying to connect to the world thread")
|
|
||||||
self._socket_world = socket_util.connect(self._host ,self._port)
|
|
||||||
connected = True
|
|
||||||
except Exception:
|
|
||||||
logging.exception("Couldn't connected ... retry in 10 seconds...")
|
|
||||||
time.sleep(10)
|
|
||||||
|
|
||||||
self._data_stream = DataStream(self._image_x,self._image_y)
|
|
||||||
|
|
||||||
|
|
||||||
positions = self.requestNewEpisode()
|
|
||||||
self.newEpisode(self._latest_start)
|
|
||||||
logging.debug("restarted the world connection")
|
|
||||||
return positions
|
|
||||||
|
|
||||||
def stop(self):
|
|
||||||
self.closeConections()
|
|
||||||
connected = False
|
|
||||||
|
|
||||||
self._data_stream._running = False
|
|
||||||
self._data_stream = DataStream(self._image_x,self._image_y)
|
|
||||||
|
|
||||||
def closeConections(self):
|
|
||||||
|
|
||||||
try:
|
|
||||||
self._socket_world.shutdown(socket.SHUT_RDWR)
|
|
||||||
self._socket_world.close()
|
|
||||||
|
|
||||||
logging.debug("Close world")
|
|
||||||
except Exception as ex:
|
|
||||||
logging.exception("Exception on closing Connections")
|
|
||||||
|
|
||||||
try:
|
|
||||||
self._socket_stream.shutdown(socket.SHUT_RDWR)
|
|
||||||
self._socket_stream.close()
|
|
||||||
logging.debug("Close Stream")
|
|
||||||
except Exception as ex:
|
|
||||||
logging.exception("Exception on closing Connections")
|
|
||||||
|
|
||||||
try:
|
|
||||||
self._socket_control.shutdown(socket.SHUT_RDWR)
|
|
||||||
self._socket_control.close()
|
|
||||||
logging.debug("Close Control")
|
|
||||||
except Exception as ex:
|
|
||||||
logging.exception("Exception on closing Connections")
|
|
|
@ -0,0 +1,836 @@
|
||||||
|
# Generated by the protocol buffer compiler. DO NOT EDIT!
|
||||||
|
# source: carla_server.proto
|
||||||
|
|
||||||
|
import sys
|
||||||
|
_b=sys.version_info[0]<3 and (lambda x:x) or (lambda x:x.encode('latin1'))
|
||||||
|
from google.protobuf import descriptor as _descriptor
|
||||||
|
from google.protobuf import message as _message
|
||||||
|
from google.protobuf import reflection as _reflection
|
||||||
|
from google.protobuf import symbol_database as _symbol_database
|
||||||
|
from google.protobuf import descriptor_pb2
|
||||||
|
# @@protoc_insertion_point(imports)
|
||||||
|
|
||||||
|
_sym_db = _symbol_database.Default()
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
DESCRIPTOR = _descriptor.FileDescriptor(
|
||||||
|
name='carla_server.proto',
|
||||||
|
package='carla_server',
|
||||||
|
syntax='proto3',
|
||||||
|
serialized_pb=_b('\n\x12\x63\x61rla_server.proto\x12\x0c\x63\x61rla_server\"+\n\x08Vector3D\x12\t\n\x01x\x18\x01 \x01(\x02\x12\t\n\x01y\x18\x02 \x01(\x02\x12\t\n\x01z\x18\x03 \x01(\x02\"b\n\tTransform\x12(\n\x08location\x18\x01 \x01(\x0b\x32\x16.carla_server.Vector3D\x12+\n\x0borientation\x18\x02 \x01(\x0b\x32\x16.carla_server.Vector3D\"x\n\x07Vehicle\x12*\n\ttransform\x18\x01 \x01(\x0b\x32\x17.carla_server.Transform\x12*\n\nbox_extent\x18\x02 \x01(\x0b\x32\x16.carla_server.Vector3D\x12\x15\n\rforward_speed\x18\x03 \x01(\x02\"{\n\nPedestrian\x12*\n\ttransform\x18\x01 \x01(\x0b\x32\x17.carla_server.Transform\x12*\n\nbox_extent\x18\x02 \x01(\x0b\x32\x16.carla_server.Vector3D\x12\x15\n\rforward_speed\x18\x03 \x01(\x02\"\x94\x01\n\x0cTrafficLight\x12*\n\ttransform\x18\x01 \x01(\x0b\x32\x17.carla_server.Transform\x12/\n\x05state\x18\x02 \x01(\x0e\x32 .carla_server.TrafficLight.State\"\'\n\x05State\x12\t\n\x05GREEN\x10\x00\x12\n\n\x06YELLOW\x10\x01\x12\x07\n\x03RED\x10\x02\"Q\n\x0eSpeedLimitSign\x12*\n\ttransform\x18\x01 \x01(\x0b\x32\x17.carla_server.Transform\x12\x13\n\x0bspeed_limit\x18\x02 \x01(\x02\"\xe5\x01\n\x05\x41gent\x12\n\n\x02id\x18\x01 \x01(\x07\x12(\n\x07vehicle\x18\x02 \x01(\x0b\x32\x15.carla_server.VehicleH\x00\x12.\n\npedestrian\x18\x03 \x01(\x0b\x32\x18.carla_server.PedestrianH\x00\x12\x33\n\rtraffic_light\x18\x04 \x01(\x0b\x32\x1a.carla_server.TrafficLightH\x00\x12\x38\n\x10speed_limit_sign\x18\x05 \x01(\x0b\x32\x1c.carla_server.SpeedLimitSignH\x00\x42\x07\n\x05\x61gent\"%\n\x11RequestNewEpisode\x12\x10\n\x08ini_file\x18\x01 \x01(\t\"G\n\x10SceneDescription\x12\x33\n\x12player_start_spots\x18\x01 \x03(\x0b\x32\x17.carla_server.Transform\"/\n\x0c\x45pisodeStart\x12\x1f\n\x17player_start_spot_index\x18\x01 \x01(\r\"\x1d\n\x0c\x45pisodeReady\x12\r\n\x05ready\x18\x01 \x01(\x08\"^\n\x07\x43ontrol\x12\r\n\x05steer\x18\x01 \x01(\x02\x12\x10\n\x08throttle\x18\x02 \x01(\x02\x12\r\n\x05\x62rake\x18\x03 \x01(\x02\x12\x12\n\nhand_brake\x18\x04 \x01(\x08\x12\x0f\n\x07reverse\x18\x05 \x01(\x08\"\x8a\x04\n\x0cMeasurements\x12\x1a\n\x12platform_timestamp\x18\x01 \x01(\r\x12\x16\n\x0egame_timestamp\x18\x02 \x01(\r\x12J\n\x13player_measurements\x18\x03 \x01(\x0b\x32-.carla_server.Measurements.PlayerMeasurements\x12.\n\x11non_player_agents\x18\x04 \x03(\x0b\x32\x13.carla_server.Agent\x1a\xc9\x02\n\x12PlayerMeasurements\x12*\n\ttransform\x18\x01 \x01(\x0b\x32\x17.carla_server.Transform\x12,\n\x0c\x61\x63\x63\x65leration\x18\x03 \x01(\x0b\x32\x16.carla_server.Vector3D\x12\x15\n\rforward_speed\x18\x04 \x01(\x02\x12\x1a\n\x12\x63ollision_vehicles\x18\x05 \x01(\x02\x12\x1d\n\x15\x63ollision_pedestrians\x18\x06 \x01(\x02\x12\x17\n\x0f\x63ollision_other\x18\x07 \x01(\x02\x12\x1e\n\x16intersection_otherlane\x18\x08 \x01(\x02\x12\x1c\n\x14intersection_offroad\x18\t \x01(\x02\x12\x30\n\x11\x61utopilot_control\x18\n \x01(\x0b\x32\x15.carla_server.ControlB\x03\xf8\x01\x01\x62\x06proto3')
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
_TRAFFICLIGHT_STATE = _descriptor.EnumDescriptor(
|
||||||
|
name='State',
|
||||||
|
full_name='carla_server.TrafficLight.State',
|
||||||
|
filename=None,
|
||||||
|
file=DESCRIPTOR,
|
||||||
|
values=[
|
||||||
|
_descriptor.EnumValueDescriptor(
|
||||||
|
name='GREEN', index=0, number=0,
|
||||||
|
options=None,
|
||||||
|
type=None),
|
||||||
|
_descriptor.EnumValueDescriptor(
|
||||||
|
name='YELLOW', index=1, number=1,
|
||||||
|
options=None,
|
||||||
|
type=None),
|
||||||
|
_descriptor.EnumValueDescriptor(
|
||||||
|
name='RED', index=2, number=2,
|
||||||
|
options=None,
|
||||||
|
type=None),
|
||||||
|
],
|
||||||
|
containing_type=None,
|
||||||
|
options=None,
|
||||||
|
serialized_start=538,
|
||||||
|
serialized_end=577,
|
||||||
|
)
|
||||||
|
_sym_db.RegisterEnumDescriptor(_TRAFFICLIGHT_STATE)
|
||||||
|
|
||||||
|
|
||||||
|
_VECTOR3D = _descriptor.Descriptor(
|
||||||
|
name='Vector3D',
|
||||||
|
full_name='carla_server.Vector3D',
|
||||||
|
filename=None,
|
||||||
|
file=DESCRIPTOR,
|
||||||
|
containing_type=None,
|
||||||
|
fields=[
|
||||||
|
_descriptor.FieldDescriptor(
|
||||||
|
name='x', full_name='carla_server.Vector3D.x', index=0,
|
||||||
|
number=1, type=2, cpp_type=6, label=1,
|
||||||
|
has_default_value=False, default_value=float(0),
|
||||||
|
message_type=None, enum_type=None, containing_type=None,
|
||||||
|
is_extension=False, extension_scope=None,
|
||||||
|
options=None),
|
||||||
|
_descriptor.FieldDescriptor(
|
||||||
|
name='y', full_name='carla_server.Vector3D.y', index=1,
|
||||||
|
number=2, type=2, cpp_type=6, label=1,
|
||||||
|
has_default_value=False, default_value=float(0),
|
||||||
|
message_type=None, enum_type=None, containing_type=None,
|
||||||
|
is_extension=False, extension_scope=None,
|
||||||
|
options=None),
|
||||||
|
_descriptor.FieldDescriptor(
|
||||||
|
name='z', full_name='carla_server.Vector3D.z', index=2,
|
||||||
|
number=3, type=2, cpp_type=6, label=1,
|
||||||
|
has_default_value=False, default_value=float(0),
|
||||||
|
message_type=None, enum_type=None, containing_type=None,
|
||||||
|
is_extension=False, extension_scope=None,
|
||||||
|
options=None),
|
||||||
|
],
|
||||||
|
extensions=[
|
||||||
|
],
|
||||||
|
nested_types=[],
|
||||||
|
enum_types=[
|
||||||
|
],
|
||||||
|
options=None,
|
||||||
|
is_extendable=False,
|
||||||
|
syntax='proto3',
|
||||||
|
extension_ranges=[],
|
||||||
|
oneofs=[
|
||||||
|
],
|
||||||
|
serialized_start=36,
|
||||||
|
serialized_end=79,
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
_TRANSFORM = _descriptor.Descriptor(
|
||||||
|
name='Transform',
|
||||||
|
full_name='carla_server.Transform',
|
||||||
|
filename=None,
|
||||||
|
file=DESCRIPTOR,
|
||||||
|
containing_type=None,
|
||||||
|
fields=[
|
||||||
|
_descriptor.FieldDescriptor(
|
||||||
|
name='location', full_name='carla_server.Transform.location', index=0,
|
||||||
|
number=1, type=11, cpp_type=10, label=1,
|
||||||
|
has_default_value=False, default_value=None,
|
||||||
|
message_type=None, enum_type=None, containing_type=None,
|
||||||
|
is_extension=False, extension_scope=None,
|
||||||
|
options=None),
|
||||||
|
_descriptor.FieldDescriptor(
|
||||||
|
name='orientation', full_name='carla_server.Transform.orientation', index=1,
|
||||||
|
number=2, type=11, cpp_type=10, label=1,
|
||||||
|
has_default_value=False, default_value=None,
|
||||||
|
message_type=None, enum_type=None, containing_type=None,
|
||||||
|
is_extension=False, extension_scope=None,
|
||||||
|
options=None),
|
||||||
|
],
|
||||||
|
extensions=[
|
||||||
|
],
|
||||||
|
nested_types=[],
|
||||||
|
enum_types=[
|
||||||
|
],
|
||||||
|
options=None,
|
||||||
|
is_extendable=False,
|
||||||
|
syntax='proto3',
|
||||||
|
extension_ranges=[],
|
||||||
|
oneofs=[
|
||||||
|
],
|
||||||
|
serialized_start=81,
|
||||||
|
serialized_end=179,
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
_VEHICLE = _descriptor.Descriptor(
|
||||||
|
name='Vehicle',
|
||||||
|
full_name='carla_server.Vehicle',
|
||||||
|
filename=None,
|
||||||
|
file=DESCRIPTOR,
|
||||||
|
containing_type=None,
|
||||||
|
fields=[
|
||||||
|
_descriptor.FieldDescriptor(
|
||||||
|
name='transform', full_name='carla_server.Vehicle.transform', index=0,
|
||||||
|
number=1, type=11, cpp_type=10, label=1,
|
||||||
|
has_default_value=False, default_value=None,
|
||||||
|
message_type=None, enum_type=None, containing_type=None,
|
||||||
|
is_extension=False, extension_scope=None,
|
||||||
|
options=None),
|
||||||
|
_descriptor.FieldDescriptor(
|
||||||
|
name='box_extent', full_name='carla_server.Vehicle.box_extent', index=1,
|
||||||
|
number=2, type=11, cpp_type=10, label=1,
|
||||||
|
has_default_value=False, default_value=None,
|
||||||
|
message_type=None, enum_type=None, containing_type=None,
|
||||||
|
is_extension=False, extension_scope=None,
|
||||||
|
options=None),
|
||||||
|
_descriptor.FieldDescriptor(
|
||||||
|
name='forward_speed', full_name='carla_server.Vehicle.forward_speed', index=2,
|
||||||
|
number=3, type=2, cpp_type=6, label=1,
|
||||||
|
has_default_value=False, default_value=float(0),
|
||||||
|
message_type=None, enum_type=None, containing_type=None,
|
||||||
|
is_extension=False, extension_scope=None,
|
||||||
|
options=None),
|
||||||
|
],
|
||||||
|
extensions=[
|
||||||
|
],
|
||||||
|
nested_types=[],
|
||||||
|
enum_types=[
|
||||||
|
],
|
||||||
|
options=None,
|
||||||
|
is_extendable=False,
|
||||||
|
syntax='proto3',
|
||||||
|
extension_ranges=[],
|
||||||
|
oneofs=[
|
||||||
|
],
|
||||||
|
serialized_start=181,
|
||||||
|
serialized_end=301,
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
_PEDESTRIAN = _descriptor.Descriptor(
|
||||||
|
name='Pedestrian',
|
||||||
|
full_name='carla_server.Pedestrian',
|
||||||
|
filename=None,
|
||||||
|
file=DESCRIPTOR,
|
||||||
|
containing_type=None,
|
||||||
|
fields=[
|
||||||
|
_descriptor.FieldDescriptor(
|
||||||
|
name='transform', full_name='carla_server.Pedestrian.transform', index=0,
|
||||||
|
number=1, type=11, cpp_type=10, label=1,
|
||||||
|
has_default_value=False, default_value=None,
|
||||||
|
message_type=None, enum_type=None, containing_type=None,
|
||||||
|
is_extension=False, extension_scope=None,
|
||||||
|
options=None),
|
||||||
|
_descriptor.FieldDescriptor(
|
||||||
|
name='box_extent', full_name='carla_server.Pedestrian.box_extent', index=1,
|
||||||
|
number=2, type=11, cpp_type=10, label=1,
|
||||||
|
has_default_value=False, default_value=None,
|
||||||
|
message_type=None, enum_type=None, containing_type=None,
|
||||||
|
is_extension=False, extension_scope=None,
|
||||||
|
options=None),
|
||||||
|
_descriptor.FieldDescriptor(
|
||||||
|
name='forward_speed', full_name='carla_server.Pedestrian.forward_speed', index=2,
|
||||||
|
number=3, type=2, cpp_type=6, label=1,
|
||||||
|
has_default_value=False, default_value=float(0),
|
||||||
|
message_type=None, enum_type=None, containing_type=None,
|
||||||
|
is_extension=False, extension_scope=None,
|
||||||
|
options=None),
|
||||||
|
],
|
||||||
|
extensions=[
|
||||||
|
],
|
||||||
|
nested_types=[],
|
||||||
|
enum_types=[
|
||||||
|
],
|
||||||
|
options=None,
|
||||||
|
is_extendable=False,
|
||||||
|
syntax='proto3',
|
||||||
|
extension_ranges=[],
|
||||||
|
oneofs=[
|
||||||
|
],
|
||||||
|
serialized_start=303,
|
||||||
|
serialized_end=426,
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
_TRAFFICLIGHT = _descriptor.Descriptor(
|
||||||
|
name='TrafficLight',
|
||||||
|
full_name='carla_server.TrafficLight',
|
||||||
|
filename=None,
|
||||||
|
file=DESCRIPTOR,
|
||||||
|
containing_type=None,
|
||||||
|
fields=[
|
||||||
|
_descriptor.FieldDescriptor(
|
||||||
|
name='transform', full_name='carla_server.TrafficLight.transform', index=0,
|
||||||
|
number=1, type=11, cpp_type=10, label=1,
|
||||||
|
has_default_value=False, default_value=None,
|
||||||
|
message_type=None, enum_type=None, containing_type=None,
|
||||||
|
is_extension=False, extension_scope=None,
|
||||||
|
options=None),
|
||||||
|
_descriptor.FieldDescriptor(
|
||||||
|
name='state', full_name='carla_server.TrafficLight.state', index=1,
|
||||||
|
number=2, type=14, cpp_type=8, label=1,
|
||||||
|
has_default_value=False, default_value=0,
|
||||||
|
message_type=None, enum_type=None, containing_type=None,
|
||||||
|
is_extension=False, extension_scope=None,
|
||||||
|
options=None),
|
||||||
|
],
|
||||||
|
extensions=[
|
||||||
|
],
|
||||||
|
nested_types=[],
|
||||||
|
enum_types=[
|
||||||
|
_TRAFFICLIGHT_STATE,
|
||||||
|
],
|
||||||
|
options=None,
|
||||||
|
is_extendable=False,
|
||||||
|
syntax='proto3',
|
||||||
|
extension_ranges=[],
|
||||||
|
oneofs=[
|
||||||
|
],
|
||||||
|
serialized_start=429,
|
||||||
|
serialized_end=577,
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
_SPEEDLIMITSIGN = _descriptor.Descriptor(
|
||||||
|
name='SpeedLimitSign',
|
||||||
|
full_name='carla_server.SpeedLimitSign',
|
||||||
|
filename=None,
|
||||||
|
file=DESCRIPTOR,
|
||||||
|
containing_type=None,
|
||||||
|
fields=[
|
||||||
|
_descriptor.FieldDescriptor(
|
||||||
|
name='transform', full_name='carla_server.SpeedLimitSign.transform', index=0,
|
||||||
|
number=1, type=11, cpp_type=10, label=1,
|
||||||
|
has_default_value=False, default_value=None,
|
||||||
|
message_type=None, enum_type=None, containing_type=None,
|
||||||
|
is_extension=False, extension_scope=None,
|
||||||
|
options=None),
|
||||||
|
_descriptor.FieldDescriptor(
|
||||||
|
name='speed_limit', full_name='carla_server.SpeedLimitSign.speed_limit', index=1,
|
||||||
|
number=2, type=2, cpp_type=6, label=1,
|
||||||
|
has_default_value=False, default_value=float(0),
|
||||||
|
message_type=None, enum_type=None, containing_type=None,
|
||||||
|
is_extension=False, extension_scope=None,
|
||||||
|
options=None),
|
||||||
|
],
|
||||||
|
extensions=[
|
||||||
|
],
|
||||||
|
nested_types=[],
|
||||||
|
enum_types=[
|
||||||
|
],
|
||||||
|
options=None,
|
||||||
|
is_extendable=False,
|
||||||
|
syntax='proto3',
|
||||||
|
extension_ranges=[],
|
||||||
|
oneofs=[
|
||||||
|
],
|
||||||
|
serialized_start=579,
|
||||||
|
serialized_end=660,
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
_AGENT = _descriptor.Descriptor(
|
||||||
|
name='Agent',
|
||||||
|
full_name='carla_server.Agent',
|
||||||
|
filename=None,
|
||||||
|
file=DESCRIPTOR,
|
||||||
|
containing_type=None,
|
||||||
|
fields=[
|
||||||
|
_descriptor.FieldDescriptor(
|
||||||
|
name='id', full_name='carla_server.Agent.id', index=0,
|
||||||
|
number=1, type=7, cpp_type=3, label=1,
|
||||||
|
has_default_value=False, default_value=0,
|
||||||
|
message_type=None, enum_type=None, containing_type=None,
|
||||||
|
is_extension=False, extension_scope=None,
|
||||||
|
options=None),
|
||||||
|
_descriptor.FieldDescriptor(
|
||||||
|
name='vehicle', full_name='carla_server.Agent.vehicle', index=1,
|
||||||
|
number=2, type=11, cpp_type=10, label=1,
|
||||||
|
has_default_value=False, default_value=None,
|
||||||
|
message_type=None, enum_type=None, containing_type=None,
|
||||||
|
is_extension=False, extension_scope=None,
|
||||||
|
options=None),
|
||||||
|
_descriptor.FieldDescriptor(
|
||||||
|
name='pedestrian', full_name='carla_server.Agent.pedestrian', index=2,
|
||||||
|
number=3, type=11, cpp_type=10, label=1,
|
||||||
|
has_default_value=False, default_value=None,
|
||||||
|
message_type=None, enum_type=None, containing_type=None,
|
||||||
|
is_extension=False, extension_scope=None,
|
||||||
|
options=None),
|
||||||
|
_descriptor.FieldDescriptor(
|
||||||
|
name='traffic_light', full_name='carla_server.Agent.traffic_light', index=3,
|
||||||
|
number=4, type=11, cpp_type=10, label=1,
|
||||||
|
has_default_value=False, default_value=None,
|
||||||
|
message_type=None, enum_type=None, containing_type=None,
|
||||||
|
is_extension=False, extension_scope=None,
|
||||||
|
options=None),
|
||||||
|
_descriptor.FieldDescriptor(
|
||||||
|
name='speed_limit_sign', full_name='carla_server.Agent.speed_limit_sign', index=4,
|
||||||
|
number=5, type=11, cpp_type=10, label=1,
|
||||||
|
has_default_value=False, default_value=None,
|
||||||
|
message_type=None, enum_type=None, containing_type=None,
|
||||||
|
is_extension=False, extension_scope=None,
|
||||||
|
options=None),
|
||||||
|
],
|
||||||
|
extensions=[
|
||||||
|
],
|
||||||
|
nested_types=[],
|
||||||
|
enum_types=[
|
||||||
|
],
|
||||||
|
options=None,
|
||||||
|
is_extendable=False,
|
||||||
|
syntax='proto3',
|
||||||
|
extension_ranges=[],
|
||||||
|
oneofs=[
|
||||||
|
_descriptor.OneofDescriptor(
|
||||||
|
name='agent', full_name='carla_server.Agent.agent',
|
||||||
|
index=0, containing_type=None, fields=[]),
|
||||||
|
],
|
||||||
|
serialized_start=663,
|
||||||
|
serialized_end=892,
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
_REQUESTNEWEPISODE = _descriptor.Descriptor(
|
||||||
|
name='RequestNewEpisode',
|
||||||
|
full_name='carla_server.RequestNewEpisode',
|
||||||
|
filename=None,
|
||||||
|
file=DESCRIPTOR,
|
||||||
|
containing_type=None,
|
||||||
|
fields=[
|
||||||
|
_descriptor.FieldDescriptor(
|
||||||
|
name='ini_file', full_name='carla_server.RequestNewEpisode.ini_file', index=0,
|
||||||
|
number=1, type=9, cpp_type=9, label=1,
|
||||||
|
has_default_value=False, default_value=_b("").decode('utf-8'),
|
||||||
|
message_type=None, enum_type=None, containing_type=None,
|
||||||
|
is_extension=False, extension_scope=None,
|
||||||
|
options=None),
|
||||||
|
],
|
||||||
|
extensions=[
|
||||||
|
],
|
||||||
|
nested_types=[],
|
||||||
|
enum_types=[
|
||||||
|
],
|
||||||
|
options=None,
|
||||||
|
is_extendable=False,
|
||||||
|
syntax='proto3',
|
||||||
|
extension_ranges=[],
|
||||||
|
oneofs=[
|
||||||
|
],
|
||||||
|
serialized_start=894,
|
||||||
|
serialized_end=931,
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
_SCENEDESCRIPTION = _descriptor.Descriptor(
|
||||||
|
name='SceneDescription',
|
||||||
|
full_name='carla_server.SceneDescription',
|
||||||
|
filename=None,
|
||||||
|
file=DESCRIPTOR,
|
||||||
|
containing_type=None,
|
||||||
|
fields=[
|
||||||
|
_descriptor.FieldDescriptor(
|
||||||
|
name='player_start_spots', full_name='carla_server.SceneDescription.player_start_spots', index=0,
|
||||||
|
number=1, type=11, cpp_type=10, label=3,
|
||||||
|
has_default_value=False, default_value=[],
|
||||||
|
message_type=None, enum_type=None, containing_type=None,
|
||||||
|
is_extension=False, extension_scope=None,
|
||||||
|
options=None),
|
||||||
|
],
|
||||||
|
extensions=[
|
||||||
|
],
|
||||||
|
nested_types=[],
|
||||||
|
enum_types=[
|
||||||
|
],
|
||||||
|
options=None,
|
||||||
|
is_extendable=False,
|
||||||
|
syntax='proto3',
|
||||||
|
extension_ranges=[],
|
||||||
|
oneofs=[
|
||||||
|
],
|
||||||
|
serialized_start=933,
|
||||||
|
serialized_end=1004,
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
_EPISODESTART = _descriptor.Descriptor(
|
||||||
|
name='EpisodeStart',
|
||||||
|
full_name='carla_server.EpisodeStart',
|
||||||
|
filename=None,
|
||||||
|
file=DESCRIPTOR,
|
||||||
|
containing_type=None,
|
||||||
|
fields=[
|
||||||
|
_descriptor.FieldDescriptor(
|
||||||
|
name='player_start_spot_index', full_name='carla_server.EpisodeStart.player_start_spot_index', index=0,
|
||||||
|
number=1, type=13, cpp_type=3, label=1,
|
||||||
|
has_default_value=False, default_value=0,
|
||||||
|
message_type=None, enum_type=None, containing_type=None,
|
||||||
|
is_extension=False, extension_scope=None,
|
||||||
|
options=None),
|
||||||
|
],
|
||||||
|
extensions=[
|
||||||
|
],
|
||||||
|
nested_types=[],
|
||||||
|
enum_types=[
|
||||||
|
],
|
||||||
|
options=None,
|
||||||
|
is_extendable=False,
|
||||||
|
syntax='proto3',
|
||||||
|
extension_ranges=[],
|
||||||
|
oneofs=[
|
||||||
|
],
|
||||||
|
serialized_start=1006,
|
||||||
|
serialized_end=1053,
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
_EPISODEREADY = _descriptor.Descriptor(
|
||||||
|
name='EpisodeReady',
|
||||||
|
full_name='carla_server.EpisodeReady',
|
||||||
|
filename=None,
|
||||||
|
file=DESCRIPTOR,
|
||||||
|
containing_type=None,
|
||||||
|
fields=[
|
||||||
|
_descriptor.FieldDescriptor(
|
||||||
|
name='ready', full_name='carla_server.EpisodeReady.ready', index=0,
|
||||||
|
number=1, type=8, cpp_type=7, label=1,
|
||||||
|
has_default_value=False, default_value=False,
|
||||||
|
message_type=None, enum_type=None, containing_type=None,
|
||||||
|
is_extension=False, extension_scope=None,
|
||||||
|
options=None),
|
||||||
|
],
|
||||||
|
extensions=[
|
||||||
|
],
|
||||||
|
nested_types=[],
|
||||||
|
enum_types=[
|
||||||
|
],
|
||||||
|
options=None,
|
||||||
|
is_extendable=False,
|
||||||
|
syntax='proto3',
|
||||||
|
extension_ranges=[],
|
||||||
|
oneofs=[
|
||||||
|
],
|
||||||
|
serialized_start=1055,
|
||||||
|
serialized_end=1084,
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
_CONTROL = _descriptor.Descriptor(
|
||||||
|
name='Control',
|
||||||
|
full_name='carla_server.Control',
|
||||||
|
filename=None,
|
||||||
|
file=DESCRIPTOR,
|
||||||
|
containing_type=None,
|
||||||
|
fields=[
|
||||||
|
_descriptor.FieldDescriptor(
|
||||||
|
name='steer', full_name='carla_server.Control.steer', index=0,
|
||||||
|
number=1, type=2, cpp_type=6, label=1,
|
||||||
|
has_default_value=False, default_value=float(0),
|
||||||
|
message_type=None, enum_type=None, containing_type=None,
|
||||||
|
is_extension=False, extension_scope=None,
|
||||||
|
options=None),
|
||||||
|
_descriptor.FieldDescriptor(
|
||||||
|
name='throttle', full_name='carla_server.Control.throttle', index=1,
|
||||||
|
number=2, type=2, cpp_type=6, label=1,
|
||||||
|
has_default_value=False, default_value=float(0),
|
||||||
|
message_type=None, enum_type=None, containing_type=None,
|
||||||
|
is_extension=False, extension_scope=None,
|
||||||
|
options=None),
|
||||||
|
_descriptor.FieldDescriptor(
|
||||||
|
name='brake', full_name='carla_server.Control.brake', index=2,
|
||||||
|
number=3, type=2, cpp_type=6, label=1,
|
||||||
|
has_default_value=False, default_value=float(0),
|
||||||
|
message_type=None, enum_type=None, containing_type=None,
|
||||||
|
is_extension=False, extension_scope=None,
|
||||||
|
options=None),
|
||||||
|
_descriptor.FieldDescriptor(
|
||||||
|
name='hand_brake', full_name='carla_server.Control.hand_brake', index=3,
|
||||||
|
number=4, type=8, cpp_type=7, label=1,
|
||||||
|
has_default_value=False, default_value=False,
|
||||||
|
message_type=None, enum_type=None, containing_type=None,
|
||||||
|
is_extension=False, extension_scope=None,
|
||||||
|
options=None),
|
||||||
|
_descriptor.FieldDescriptor(
|
||||||
|
name='reverse', full_name='carla_server.Control.reverse', index=4,
|
||||||
|
number=5, type=8, cpp_type=7, label=1,
|
||||||
|
has_default_value=False, default_value=False,
|
||||||
|
message_type=None, enum_type=None, containing_type=None,
|
||||||
|
is_extension=False, extension_scope=None,
|
||||||
|
options=None),
|
||||||
|
],
|
||||||
|
extensions=[
|
||||||
|
],
|
||||||
|
nested_types=[],
|
||||||
|
enum_types=[
|
||||||
|
],
|
||||||
|
options=None,
|
||||||
|
is_extendable=False,
|
||||||
|
syntax='proto3',
|
||||||
|
extension_ranges=[],
|
||||||
|
oneofs=[
|
||||||
|
],
|
||||||
|
serialized_start=1086,
|
||||||
|
serialized_end=1180,
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
_MEASUREMENTS_PLAYERMEASUREMENTS = _descriptor.Descriptor(
|
||||||
|
name='PlayerMeasurements',
|
||||||
|
full_name='carla_server.Measurements.PlayerMeasurements',
|
||||||
|
filename=None,
|
||||||
|
file=DESCRIPTOR,
|
||||||
|
containing_type=None,
|
||||||
|
fields=[
|
||||||
|
_descriptor.FieldDescriptor(
|
||||||
|
name='transform', full_name='carla_server.Measurements.PlayerMeasurements.transform', index=0,
|
||||||
|
number=1, type=11, cpp_type=10, label=1,
|
||||||
|
has_default_value=False, default_value=None,
|
||||||
|
message_type=None, enum_type=None, containing_type=None,
|
||||||
|
is_extension=False, extension_scope=None,
|
||||||
|
options=None),
|
||||||
|
_descriptor.FieldDescriptor(
|
||||||
|
name='acceleration', full_name='carla_server.Measurements.PlayerMeasurements.acceleration', index=1,
|
||||||
|
number=3, type=11, cpp_type=10, label=1,
|
||||||
|
has_default_value=False, default_value=None,
|
||||||
|
message_type=None, enum_type=None, containing_type=None,
|
||||||
|
is_extension=False, extension_scope=None,
|
||||||
|
options=None),
|
||||||
|
_descriptor.FieldDescriptor(
|
||||||
|
name='forward_speed', full_name='carla_server.Measurements.PlayerMeasurements.forward_speed', index=2,
|
||||||
|
number=4, type=2, cpp_type=6, label=1,
|
||||||
|
has_default_value=False, default_value=float(0),
|
||||||
|
message_type=None, enum_type=None, containing_type=None,
|
||||||
|
is_extension=False, extension_scope=None,
|
||||||
|
options=None),
|
||||||
|
_descriptor.FieldDescriptor(
|
||||||
|
name='collision_vehicles', full_name='carla_server.Measurements.PlayerMeasurements.collision_vehicles', index=3,
|
||||||
|
number=5, type=2, cpp_type=6, label=1,
|
||||||
|
has_default_value=False, default_value=float(0),
|
||||||
|
message_type=None, enum_type=None, containing_type=None,
|
||||||
|
is_extension=False, extension_scope=None,
|
||||||
|
options=None),
|
||||||
|
_descriptor.FieldDescriptor(
|
||||||
|
name='collision_pedestrians', full_name='carla_server.Measurements.PlayerMeasurements.collision_pedestrians', index=4,
|
||||||
|
number=6, type=2, cpp_type=6, label=1,
|
||||||
|
has_default_value=False, default_value=float(0),
|
||||||
|
message_type=None, enum_type=None, containing_type=None,
|
||||||
|
is_extension=False, extension_scope=None,
|
||||||
|
options=None),
|
||||||
|
_descriptor.FieldDescriptor(
|
||||||
|
name='collision_other', full_name='carla_server.Measurements.PlayerMeasurements.collision_other', index=5,
|
||||||
|
number=7, type=2, cpp_type=6, label=1,
|
||||||
|
has_default_value=False, default_value=float(0),
|
||||||
|
message_type=None, enum_type=None, containing_type=None,
|
||||||
|
is_extension=False, extension_scope=None,
|
||||||
|
options=None),
|
||||||
|
_descriptor.FieldDescriptor(
|
||||||
|
name='intersection_otherlane', full_name='carla_server.Measurements.PlayerMeasurements.intersection_otherlane', index=6,
|
||||||
|
number=8, type=2, cpp_type=6, label=1,
|
||||||
|
has_default_value=False, default_value=float(0),
|
||||||
|
message_type=None, enum_type=None, containing_type=None,
|
||||||
|
is_extension=False, extension_scope=None,
|
||||||
|
options=None),
|
||||||
|
_descriptor.FieldDescriptor(
|
||||||
|
name='intersection_offroad', full_name='carla_server.Measurements.PlayerMeasurements.intersection_offroad', index=7,
|
||||||
|
number=9, type=2, cpp_type=6, label=1,
|
||||||
|
has_default_value=False, default_value=float(0),
|
||||||
|
message_type=None, enum_type=None, containing_type=None,
|
||||||
|
is_extension=False, extension_scope=None,
|
||||||
|
options=None),
|
||||||
|
_descriptor.FieldDescriptor(
|
||||||
|
name='autopilot_control', full_name='carla_server.Measurements.PlayerMeasurements.autopilot_control', index=8,
|
||||||
|
number=10, type=11, cpp_type=10, label=1,
|
||||||
|
has_default_value=False, default_value=None,
|
||||||
|
message_type=None, enum_type=None, containing_type=None,
|
||||||
|
is_extension=False, extension_scope=None,
|
||||||
|
options=None),
|
||||||
|
],
|
||||||
|
extensions=[
|
||||||
|
],
|
||||||
|
nested_types=[],
|
||||||
|
enum_types=[
|
||||||
|
],
|
||||||
|
options=None,
|
||||||
|
is_extendable=False,
|
||||||
|
syntax='proto3',
|
||||||
|
extension_ranges=[],
|
||||||
|
oneofs=[
|
||||||
|
],
|
||||||
|
serialized_start=1376,
|
||||||
|
serialized_end=1705,
|
||||||
|
)
|
||||||
|
|
||||||
|
_MEASUREMENTS = _descriptor.Descriptor(
|
||||||
|
name='Measurements',
|
||||||
|
full_name='carla_server.Measurements',
|
||||||
|
filename=None,
|
||||||
|
file=DESCRIPTOR,
|
||||||
|
containing_type=None,
|
||||||
|
fields=[
|
||||||
|
_descriptor.FieldDescriptor(
|
||||||
|
name='platform_timestamp', full_name='carla_server.Measurements.platform_timestamp', index=0,
|
||||||
|
number=1, type=13, cpp_type=3, label=1,
|
||||||
|
has_default_value=False, default_value=0,
|
||||||
|
message_type=None, enum_type=None, containing_type=None,
|
||||||
|
is_extension=False, extension_scope=None,
|
||||||
|
options=None),
|
||||||
|
_descriptor.FieldDescriptor(
|
||||||
|
name='game_timestamp', full_name='carla_server.Measurements.game_timestamp', index=1,
|
||||||
|
number=2, type=13, cpp_type=3, label=1,
|
||||||
|
has_default_value=False, default_value=0,
|
||||||
|
message_type=None, enum_type=None, containing_type=None,
|
||||||
|
is_extension=False, extension_scope=None,
|
||||||
|
options=None),
|
||||||
|
_descriptor.FieldDescriptor(
|
||||||
|
name='player_measurements', full_name='carla_server.Measurements.player_measurements', index=2,
|
||||||
|
number=3, type=11, cpp_type=10, label=1,
|
||||||
|
has_default_value=False, default_value=None,
|
||||||
|
message_type=None, enum_type=None, containing_type=None,
|
||||||
|
is_extension=False, extension_scope=None,
|
||||||
|
options=None),
|
||||||
|
_descriptor.FieldDescriptor(
|
||||||
|
name='non_player_agents', full_name='carla_server.Measurements.non_player_agents', index=3,
|
||||||
|
number=4, type=11, cpp_type=10, label=3,
|
||||||
|
has_default_value=False, default_value=[],
|
||||||
|
message_type=None, enum_type=None, containing_type=None,
|
||||||
|
is_extension=False, extension_scope=None,
|
||||||
|
options=None),
|
||||||
|
],
|
||||||
|
extensions=[
|
||||||
|
],
|
||||||
|
nested_types=[_MEASUREMENTS_PLAYERMEASUREMENTS, ],
|
||||||
|
enum_types=[
|
||||||
|
],
|
||||||
|
options=None,
|
||||||
|
is_extendable=False,
|
||||||
|
syntax='proto3',
|
||||||
|
extension_ranges=[],
|
||||||
|
oneofs=[
|
||||||
|
],
|
||||||
|
serialized_start=1183,
|
||||||
|
serialized_end=1705,
|
||||||
|
)
|
||||||
|
|
||||||
|
_TRANSFORM.fields_by_name['location'].message_type = _VECTOR3D
|
||||||
|
_TRANSFORM.fields_by_name['orientation'].message_type = _VECTOR3D
|
||||||
|
_VEHICLE.fields_by_name['transform'].message_type = _TRANSFORM
|
||||||
|
_VEHICLE.fields_by_name['box_extent'].message_type = _VECTOR3D
|
||||||
|
_PEDESTRIAN.fields_by_name['transform'].message_type = _TRANSFORM
|
||||||
|
_PEDESTRIAN.fields_by_name['box_extent'].message_type = _VECTOR3D
|
||||||
|
_TRAFFICLIGHT.fields_by_name['transform'].message_type = _TRANSFORM
|
||||||
|
_TRAFFICLIGHT.fields_by_name['state'].enum_type = _TRAFFICLIGHT_STATE
|
||||||
|
_TRAFFICLIGHT_STATE.containing_type = _TRAFFICLIGHT
|
||||||
|
_SPEEDLIMITSIGN.fields_by_name['transform'].message_type = _TRANSFORM
|
||||||
|
_AGENT.fields_by_name['vehicle'].message_type = _VEHICLE
|
||||||
|
_AGENT.fields_by_name['pedestrian'].message_type = _PEDESTRIAN
|
||||||
|
_AGENT.fields_by_name['traffic_light'].message_type = _TRAFFICLIGHT
|
||||||
|
_AGENT.fields_by_name['speed_limit_sign'].message_type = _SPEEDLIMITSIGN
|
||||||
|
_AGENT.oneofs_by_name['agent'].fields.append(
|
||||||
|
_AGENT.fields_by_name['vehicle'])
|
||||||
|
_AGENT.fields_by_name['vehicle'].containing_oneof = _AGENT.oneofs_by_name['agent']
|
||||||
|
_AGENT.oneofs_by_name['agent'].fields.append(
|
||||||
|
_AGENT.fields_by_name['pedestrian'])
|
||||||
|
_AGENT.fields_by_name['pedestrian'].containing_oneof = _AGENT.oneofs_by_name['agent']
|
||||||
|
_AGENT.oneofs_by_name['agent'].fields.append(
|
||||||
|
_AGENT.fields_by_name['traffic_light'])
|
||||||
|
_AGENT.fields_by_name['traffic_light'].containing_oneof = _AGENT.oneofs_by_name['agent']
|
||||||
|
_AGENT.oneofs_by_name['agent'].fields.append(
|
||||||
|
_AGENT.fields_by_name['speed_limit_sign'])
|
||||||
|
_AGENT.fields_by_name['speed_limit_sign'].containing_oneof = _AGENT.oneofs_by_name['agent']
|
||||||
|
_SCENEDESCRIPTION.fields_by_name['player_start_spots'].message_type = _TRANSFORM
|
||||||
|
_MEASUREMENTS_PLAYERMEASUREMENTS.fields_by_name['transform'].message_type = _TRANSFORM
|
||||||
|
_MEASUREMENTS_PLAYERMEASUREMENTS.fields_by_name['acceleration'].message_type = _VECTOR3D
|
||||||
|
_MEASUREMENTS_PLAYERMEASUREMENTS.fields_by_name['autopilot_control'].message_type = _CONTROL
|
||||||
|
_MEASUREMENTS_PLAYERMEASUREMENTS.containing_type = _MEASUREMENTS
|
||||||
|
_MEASUREMENTS.fields_by_name['player_measurements'].message_type = _MEASUREMENTS_PLAYERMEASUREMENTS
|
||||||
|
_MEASUREMENTS.fields_by_name['non_player_agents'].message_type = _AGENT
|
||||||
|
DESCRIPTOR.message_types_by_name['Vector3D'] = _VECTOR3D
|
||||||
|
DESCRIPTOR.message_types_by_name['Transform'] = _TRANSFORM
|
||||||
|
DESCRIPTOR.message_types_by_name['Vehicle'] = _VEHICLE
|
||||||
|
DESCRIPTOR.message_types_by_name['Pedestrian'] = _PEDESTRIAN
|
||||||
|
DESCRIPTOR.message_types_by_name['TrafficLight'] = _TRAFFICLIGHT
|
||||||
|
DESCRIPTOR.message_types_by_name['SpeedLimitSign'] = _SPEEDLIMITSIGN
|
||||||
|
DESCRIPTOR.message_types_by_name['Agent'] = _AGENT
|
||||||
|
DESCRIPTOR.message_types_by_name['RequestNewEpisode'] = _REQUESTNEWEPISODE
|
||||||
|
DESCRIPTOR.message_types_by_name['SceneDescription'] = _SCENEDESCRIPTION
|
||||||
|
DESCRIPTOR.message_types_by_name['EpisodeStart'] = _EPISODESTART
|
||||||
|
DESCRIPTOR.message_types_by_name['EpisodeReady'] = _EPISODEREADY
|
||||||
|
DESCRIPTOR.message_types_by_name['Control'] = _CONTROL
|
||||||
|
DESCRIPTOR.message_types_by_name['Measurements'] = _MEASUREMENTS
|
||||||
|
_sym_db.RegisterFileDescriptor(DESCRIPTOR)
|
||||||
|
|
||||||
|
Vector3D = _reflection.GeneratedProtocolMessageType('Vector3D', (_message.Message,), dict(
|
||||||
|
DESCRIPTOR = _VECTOR3D,
|
||||||
|
__module__ = 'carla_server_pb2'
|
||||||
|
# @@protoc_insertion_point(class_scope:carla_server.Vector3D)
|
||||||
|
))
|
||||||
|
_sym_db.RegisterMessage(Vector3D)
|
||||||
|
|
||||||
|
Transform = _reflection.GeneratedProtocolMessageType('Transform', (_message.Message,), dict(
|
||||||
|
DESCRIPTOR = _TRANSFORM,
|
||||||
|
__module__ = 'carla_server_pb2'
|
||||||
|
# @@protoc_insertion_point(class_scope:carla_server.Transform)
|
||||||
|
))
|
||||||
|
_sym_db.RegisterMessage(Transform)
|
||||||
|
|
||||||
|
Vehicle = _reflection.GeneratedProtocolMessageType('Vehicle', (_message.Message,), dict(
|
||||||
|
DESCRIPTOR = _VEHICLE,
|
||||||
|
__module__ = 'carla_server_pb2'
|
||||||
|
# @@protoc_insertion_point(class_scope:carla_server.Vehicle)
|
||||||
|
))
|
||||||
|
_sym_db.RegisterMessage(Vehicle)
|
||||||
|
|
||||||
|
Pedestrian = _reflection.GeneratedProtocolMessageType('Pedestrian', (_message.Message,), dict(
|
||||||
|
DESCRIPTOR = _PEDESTRIAN,
|
||||||
|
__module__ = 'carla_server_pb2'
|
||||||
|
# @@protoc_insertion_point(class_scope:carla_server.Pedestrian)
|
||||||
|
))
|
||||||
|
_sym_db.RegisterMessage(Pedestrian)
|
||||||
|
|
||||||
|
TrafficLight = _reflection.GeneratedProtocolMessageType('TrafficLight', (_message.Message,), dict(
|
||||||
|
DESCRIPTOR = _TRAFFICLIGHT,
|
||||||
|
__module__ = 'carla_server_pb2'
|
||||||
|
# @@protoc_insertion_point(class_scope:carla_server.TrafficLight)
|
||||||
|
))
|
||||||
|
_sym_db.RegisterMessage(TrafficLight)
|
||||||
|
|
||||||
|
SpeedLimitSign = _reflection.GeneratedProtocolMessageType('SpeedLimitSign', (_message.Message,), dict(
|
||||||
|
DESCRIPTOR = _SPEEDLIMITSIGN,
|
||||||
|
__module__ = 'carla_server_pb2'
|
||||||
|
# @@protoc_insertion_point(class_scope:carla_server.SpeedLimitSign)
|
||||||
|
))
|
||||||
|
_sym_db.RegisterMessage(SpeedLimitSign)
|
||||||
|
|
||||||
|
Agent = _reflection.GeneratedProtocolMessageType('Agent', (_message.Message,), dict(
|
||||||
|
DESCRIPTOR = _AGENT,
|
||||||
|
__module__ = 'carla_server_pb2'
|
||||||
|
# @@protoc_insertion_point(class_scope:carla_server.Agent)
|
||||||
|
))
|
||||||
|
_sym_db.RegisterMessage(Agent)
|
||||||
|
|
||||||
|
RequestNewEpisode = _reflection.GeneratedProtocolMessageType('RequestNewEpisode', (_message.Message,), dict(
|
||||||
|
DESCRIPTOR = _REQUESTNEWEPISODE,
|
||||||
|
__module__ = 'carla_server_pb2'
|
||||||
|
# @@protoc_insertion_point(class_scope:carla_server.RequestNewEpisode)
|
||||||
|
))
|
||||||
|
_sym_db.RegisterMessage(RequestNewEpisode)
|
||||||
|
|
||||||
|
SceneDescription = _reflection.GeneratedProtocolMessageType('SceneDescription', (_message.Message,), dict(
|
||||||
|
DESCRIPTOR = _SCENEDESCRIPTION,
|
||||||
|
__module__ = 'carla_server_pb2'
|
||||||
|
# @@protoc_insertion_point(class_scope:carla_server.SceneDescription)
|
||||||
|
))
|
||||||
|
_sym_db.RegisterMessage(SceneDescription)
|
||||||
|
|
||||||
|
EpisodeStart = _reflection.GeneratedProtocolMessageType('EpisodeStart', (_message.Message,), dict(
|
||||||
|
DESCRIPTOR = _EPISODESTART,
|
||||||
|
__module__ = 'carla_server_pb2'
|
||||||
|
# @@protoc_insertion_point(class_scope:carla_server.EpisodeStart)
|
||||||
|
))
|
||||||
|
_sym_db.RegisterMessage(EpisodeStart)
|
||||||
|
|
||||||
|
EpisodeReady = _reflection.GeneratedProtocolMessageType('EpisodeReady', (_message.Message,), dict(
|
||||||
|
DESCRIPTOR = _EPISODEREADY,
|
||||||
|
__module__ = 'carla_server_pb2'
|
||||||
|
# @@protoc_insertion_point(class_scope:carla_server.EpisodeReady)
|
||||||
|
))
|
||||||
|
_sym_db.RegisterMessage(EpisodeReady)
|
||||||
|
|
||||||
|
Control = _reflection.GeneratedProtocolMessageType('Control', (_message.Message,), dict(
|
||||||
|
DESCRIPTOR = _CONTROL,
|
||||||
|
__module__ = 'carla_server_pb2'
|
||||||
|
# @@protoc_insertion_point(class_scope:carla_server.Control)
|
||||||
|
))
|
||||||
|
_sym_db.RegisterMessage(Control)
|
||||||
|
|
||||||
|
Measurements = _reflection.GeneratedProtocolMessageType('Measurements', (_message.Message,), dict(
|
||||||
|
|
||||||
|
PlayerMeasurements = _reflection.GeneratedProtocolMessageType('PlayerMeasurements', (_message.Message,), dict(
|
||||||
|
DESCRIPTOR = _MEASUREMENTS_PLAYERMEASUREMENTS,
|
||||||
|
__module__ = 'carla_server_pb2'
|
||||||
|
# @@protoc_insertion_point(class_scope:carla_server.Measurements.PlayerMeasurements)
|
||||||
|
))
|
||||||
|
,
|
||||||
|
DESCRIPTOR = _MEASUREMENTS,
|
||||||
|
__module__ = 'carla_server_pb2'
|
||||||
|
# @@protoc_insertion_point(class_scope:carla_server.Measurements)
|
||||||
|
))
|
||||||
|
_sym_db.RegisterMessage(Measurements)
|
||||||
|
_sym_db.RegisterMessage(Measurements.PlayerMeasurements)
|
||||||
|
|
||||||
|
|
||||||
|
DESCRIPTOR.has_options = True
|
||||||
|
DESCRIPTOR._options = _descriptor._ParseOptions(descriptor_pb2.FileOptions(), _b('\370\001\001'))
|
||||||
|
# @@protoc_insertion_point(module_scope)
|
|
@ -0,0 +1,202 @@
|
||||||
|
# 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>.
|
||||||
|
|
||||||
|
"""CARLA Client."""
|
||||||
|
|
||||||
|
import struct
|
||||||
|
|
||||||
|
from contextlib import contextmanager
|
||||||
|
|
||||||
|
from . import sensor
|
||||||
|
from . import settings
|
||||||
|
from . import tcp
|
||||||
|
from . import util
|
||||||
|
|
||||||
|
try:
|
||||||
|
from . import carla_server_pb2 as carla_protocol
|
||||||
|
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):
|
||||||
|
"""Context manager for creating and connecting a CarlaClient."""
|
||||||
|
with util.make_connection(CarlaClient, host, world_port, timeout) as client:
|
||||||
|
yield client
|
||||||
|
|
||||||
|
|
||||||
|
class CarlaClient(object):
|
||||||
|
"""The CARLA client. Manages communications with the CARLA server."""
|
||||||
|
|
||||||
|
def __init__(self, host, world_port, timeout=15):
|
||||||
|
self._world_client = tcp.TCPClient(host, world_port, timeout)
|
||||||
|
self._stream_client = tcp.TCPClient(host, world_port + 1, timeout)
|
||||||
|
self._control_client = tcp.TCPClient(host, world_port + 2, timeout)
|
||||||
|
self._current_settings = None
|
||||||
|
self._is_episode_requested = False
|
||||||
|
self._sensor_names = []
|
||||||
|
|
||||||
|
def connect(self, connection_attempts=10):
|
||||||
|
"""
|
||||||
|
Try to establish a connection to a CARLA server at the given host:port.
|
||||||
|
"""
|
||||||
|
self._world_client.connect(connection_attempts)
|
||||||
|
|
||||||
|
def disconnect(self):
|
||||||
|
"""Disconnect from server."""
|
||||||
|
self._control_client.disconnect()
|
||||||
|
self._stream_client.disconnect()
|
||||||
|
self._world_client.disconnect()
|
||||||
|
|
||||||
|
def connected(self):
|
||||||
|
"""Return whether there is an active connection."""
|
||||||
|
return self._world_client.connected()
|
||||||
|
|
||||||
|
def load_settings(self, carla_settings):
|
||||||
|
"""
|
||||||
|
Load new settings and request a new episode based on these settings.
|
||||||
|
carla_settings object must be convertible to a str holding the contents
|
||||||
|
of a CarlaSettings.ini file.
|
||||||
|
|
||||||
|
Return a protobuf object holding the scene description.
|
||||||
|
"""
|
||||||
|
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
|
||||||
|
player_start_index. The list of player starts is retrieved by
|
||||||
|
"load_settings".
|
||||||
|
|
||||||
|
The new episode is started based on the last settings loaded by
|
||||||
|
"load_settings".
|
||||||
|
|
||||||
|
This function waits until the server answers with an EpisodeReady.
|
||||||
|
"""
|
||||||
|
if self._current_settings is None:
|
||||||
|
raise RuntimeError('no settings loaded, cannot start episode')
|
||||||
|
|
||||||
|
# if no new settings are loaded, request new episode with previous
|
||||||
|
if not self._is_episode_requested:
|
||||||
|
self._request_new_episode(self._current_settings)
|
||||||
|
|
||||||
|
try:
|
||||||
|
pb_message = carla_protocol.EpisodeStart()
|
||||||
|
pb_message.player_start_spot_index = player_start_index
|
||||||
|
self._world_client.write(pb_message.SerializeToString())
|
||||||
|
# Wait for EpisodeReady.
|
||||||
|
data = self._world_client.read()
|
||||||
|
if not data:
|
||||||
|
raise RuntimeError('failed to read data from server')
|
||||||
|
pb_message = carla_protocol.EpisodeReady()
|
||||||
|
pb_message.ParseFromString(data)
|
||||||
|
if not pb_message.ready:
|
||||||
|
raise RuntimeError('cannot start episode: server failed to start episode')
|
||||||
|
# We can start the agent clients now.
|
||||||
|
self._stream_client.connect()
|
||||||
|
self._control_client.connect()
|
||||||
|
# Set again the status for no episode requested
|
||||||
|
finally:
|
||||||
|
self._is_episode_requested = False
|
||||||
|
|
||||||
|
def read_data(self):
|
||||||
|
"""
|
||||||
|
Read the data sent from the server this frame. The episode must be
|
||||||
|
started. Return a pair containing the protobuf object containing the
|
||||||
|
measurements followed by the raw data of the sensors.
|
||||||
|
"""
|
||||||
|
# Read measurements.
|
||||||
|
data = self._stream_client.read()
|
||||||
|
if not data:
|
||||||
|
raise RuntimeError('failed to read data from server')
|
||||||
|
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)
|
||||||
|
|
||||||
|
def send_control(self, *args, **kwargs):
|
||||||
|
"""
|
||||||
|
Send the VehicleControl to be applied this frame.
|
||||||
|
|
||||||
|
If synchronous mode was requested, the server will pause the simulation
|
||||||
|
until this message is received.
|
||||||
|
"""
|
||||||
|
if isinstance(args[0] if args else None, carla_protocol.Control):
|
||||||
|
pb_message = args[0]
|
||||||
|
else:
|
||||||
|
pb_message = carla_protocol.Control()
|
||||||
|
pb_message.steer = kwargs.get('steer', 0.0)
|
||||||
|
pb_message.throttle = kwargs.get('throttle', 0.0)
|
||||||
|
pb_message.brake = kwargs.get('brake', 0.0)
|
||||||
|
pb_message.hand_brake = kwargs.get('hand_brake', False)
|
||||||
|
pb_message.reverse = kwargs.get('reverse', False)
|
||||||
|
self._control_client.write(pb_message.SerializeToString())
|
||||||
|
|
||||||
|
def _request_new_episode(self, carla_settings):
|
||||||
|
"""
|
||||||
|
Internal function to request a new episode. Prepare the client for a new
|
||||||
|
episode by disconnecting agent clients.
|
||||||
|
"""
|
||||||
|
# Disconnect agent clients.
|
||||||
|
self._stream_client.disconnect()
|
||||||
|
self._control_client.disconnect()
|
||||||
|
# Send new episode request.
|
||||||
|
pb_message = carla_protocol.RequestNewEpisode()
|
||||||
|
pb_message.ini_file = str(carla_settings)
|
||||||
|
self._world_client.write(pb_message.SerializeToString())
|
||||||
|
# Read scene description.
|
||||||
|
data = self._world_client.read()
|
||||||
|
if not data:
|
||||||
|
raise RuntimeError('failed to read data from server')
|
||||||
|
pb_message = carla_protocol.SceneDescription()
|
||||||
|
pb_message.ParseFromString(data)
|
||||||
|
if len(pb_message.player_start_spots) < 1:
|
||||||
|
raise RuntimeError("received 0 player start spots")
|
||||||
|
self._sensor_names = settings._get_sensor_names(carla_settings)
|
||||||
|
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)))
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def _iterate_sensor_data(raw_data):
|
||||||
|
# At this point the only sensors available are images, the raw_data
|
||||||
|
# consists of images only.
|
||||||
|
image_types = ['None', 'SceneFinal', 'Depth', 'SemanticSegmentation', 'Lidar']
|
||||||
|
gettype = lambda id: image_types[id] if len(image_types) > id else 'Unknown'
|
||||||
|
getval = lambda index: struct.unpack('<L', raw_data[index*4:index*4+4])[0]
|
||||||
|
getfloatval = 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(getval(index + 2))
|
||||||
|
if sensor_type == 'Lidar':
|
||||||
|
|
||||||
|
horizontal_angle = getfloatval(index)
|
||||||
|
channels_count = getval(index + 3)
|
||||||
|
lm = sensor.LidarMeasurement(
|
||||||
|
horizontal_angle, channels_count,
|
||||||
|
sensor_type, raw_data[index*4:])
|
||||||
|
index += lm.size_in_bytes
|
||||||
|
yield lm
|
||||||
|
|
||||||
|
else:
|
||||||
|
width = getval(index)
|
||||||
|
height = getval(index + 1)
|
||||||
|
begin = index + 3
|
||||||
|
end = begin + width * height
|
||||||
|
index = end
|
||||||
|
yield sensor.Image(width, height, sensor_type, raw_data[begin*4:end*4])
|
|
@ -0,0 +1,103 @@
|
||||||
|
# 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')
|
||||||
|
|
||||||
|
|
||||||
|
from . import sensor
|
||||||
|
|
||||||
|
|
||||||
|
def to_bgra_array(image):
|
||||||
|
"""Convert a CARLA raw image to a BGRA numpy array."""
|
||||||
|
if not isinstance(image, sensor.Image):
|
||||||
|
raise ValueError("Argument must be a carla.sensor.Image")
|
||||||
|
array = numpy.frombuffer(image.raw_data, dtype=numpy.dtype("uint8"))
|
||||||
|
array = numpy.reshape(array, (image.height, image.width, 4))
|
||||||
|
return array
|
||||||
|
|
||||||
|
|
||||||
|
def to_rgb_array(image):
|
||||||
|
"""Convert a CARLA raw image to a RGB numpy array."""
|
||||||
|
array = to_bgra_array(image)
|
||||||
|
# Convert BGRA to RGB.
|
||||||
|
array = array[:, :, :3]
|
||||||
|
array = array[:, :, ::-1]
|
||||||
|
return array
|
||||||
|
|
||||||
|
|
||||||
|
def labels_to_array(image):
|
||||||
|
"""
|
||||||
|
Convert an image containing CARLA semantic segmentation labels to a 2D array
|
||||||
|
containing the label of each pixel.
|
||||||
|
"""
|
||||||
|
return to_bgra_array(image)[:, :, 2]
|
||||||
|
|
||||||
|
|
||||||
|
def labels_to_cityscapes_palette(image):
|
||||||
|
"""
|
||||||
|
Convert 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 = labels_to_array(image)
|
||||||
|
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_array(image):
|
||||||
|
"""
|
||||||
|
Convert an image containing CARLA encoded depth-map to a 2D array containing
|
||||||
|
the depth value of each pixel normalized between [0.0, 1.0].
|
||||||
|
"""
|
||||||
|
array = to_bgra_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)
|
||||||
|
return grayscale
|
||||||
|
|
||||||
|
|
||||||
|
def depth_to_logarithmic_grayscale(image):
|
||||||
|
"""
|
||||||
|
Convert an image containing CARLA encoded depth-map to a logarithmic
|
||||||
|
grayscale image array.
|
||||||
|
"""
|
||||||
|
grayscale = depth_to_array(image)
|
||||||
|
# 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)
|
Binary file not shown.
After Width: | Height: | Size: 534 KiB |
|
@ -0,0 +1,49 @@
|
||||||
|
0.0,0.0,-3811.000000
|
||||||
|
0.000000,0.000000,0.0
|
||||||
|
1.000000,1.000000,1.000000
|
||||||
|
-1643.022,-1643.022,0.000
|
||||||
|
49, 41
|
||||||
|
0,0 0,40 40
|
||||||
|
0,40 0,0 40
|
||||||
|
48,40 41,40 7
|
||||||
|
41,40 48,40 7
|
||||||
|
48,0 48,40 40
|
||||||
|
48,40 48,0 40
|
||||||
|
0,0 11,0 11
|
||||||
|
11,0 0,0 11
|
||||||
|
41,0 48,0 7
|
||||||
|
48,0 41,0 7
|
||||||
|
41,40 11,40 30
|
||||||
|
11,40 41,40 30
|
||||||
|
41,0 41,7 7
|
||||||
|
41,7 41,0 7
|
||||||
|
11,40 0,40 11
|
||||||
|
0,40 11,40 11
|
||||||
|
11,0 19,0 8
|
||||||
|
19,0 11,0 8
|
||||||
|
11,40 11,24 16
|
||||||
|
11,24 11,40 16
|
||||||
|
41,24 41,40 16
|
||||||
|
41,40 41,24 16
|
||||||
|
11,24 11,16 8
|
||||||
|
11,16 11,24 8
|
||||||
|
41,24 11,24 30
|
||||||
|
11,24 41,24 30
|
||||||
|
41,16 41,24 8
|
||||||
|
41,24 41,16 8
|
||||||
|
11,16 11,7 9
|
||||||
|
11,7 11,16 9
|
||||||
|
41,16 11,16 30
|
||||||
|
11,16 41,16 30
|
||||||
|
41,7 41,16 9
|
||||||
|
41,16 41,7 9
|
||||||
|
11,7 11,0 7
|
||||||
|
11,0 11,7 7
|
||||||
|
41,7 19,7 22
|
||||||
|
19,7 41,7 22
|
||||||
|
19,0 41,0 22
|
||||||
|
41,0 19,0 22
|
||||||
|
19,7 11,7 8
|
||||||
|
11,7 19,7 8
|
||||||
|
19,0 19,7 7
|
||||||
|
19,7 19,0 7
|
Binary file not shown.
After Width: | Height: | Size: 33 KiB |
Binary file not shown.
After Width: | Height: | Size: 175 KiB |
|
@ -0,0 +1,37 @@
|
||||||
|
544.000000,-10748.000000,-22.000000
|
||||||
|
0.000000,0.000000,0.000000
|
||||||
|
1.000000,1.000000,1.000000
|
||||||
|
-1643.022,-1643.022,0.000
|
||||||
|
25, 25
|
||||||
|
0,10 0,24 14
|
||||||
|
0,24 0,10 14
|
||||||
|
24,24 6,24 18
|
||||||
|
6,24 24,24 18
|
||||||
|
24,0 24,10 10
|
||||||
|
24,10 24,0 10
|
||||||
|
0,0 24,0 24
|
||||||
|
24,0 0,0 24
|
||||||
|
0,10 0,0 10
|
||||||
|
0,0 0,10 10
|
||||||
|
24,10 24,16 6
|
||||||
|
24,16 24,10 6
|
||||||
|
0,10 6,10 6
|
||||||
|
6,10 0,10 6
|
||||||
|
6,24 0,24 6
|
||||||
|
0,24 6,24 6
|
||||||
|
6,10 17,10 11
|
||||||
|
17,10 6,10 11
|
||||||
|
6,24 6,16 8
|
||||||
|
6,16 6,24 8
|
||||||
|
24,16 24,24 8
|
||||||
|
24,24 24,16 8
|
||||||
|
6,16 6,10 6
|
||||||
|
6,10 6,16 6
|
||||||
|
24,16 17,16 7
|
||||||
|
17,16 24,16 7
|
||||||
|
17,16 6,16 11
|
||||||
|
6,16 17,16 11
|
||||||
|
17,10 24,10 7
|
||||||
|
24,10 17,10 7
|
||||||
|
17,16 17,10 6
|
||||||
|
17,10 17,16 6
|
Binary file not shown.
After Width: | Height: | Size: 400 KiB |
Binary file not shown.
After Width: | Height: | Size: 15 KiB |
|
@ -0,0 +1,146 @@
|
||||||
|
# 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>.
|
||||||
|
|
||||||
|
"""Class used for operating the city map."""
|
||||||
|
|
||||||
|
import math
|
||||||
|
import os
|
||||||
|
|
||||||
|
try:
|
||||||
|
import numpy as np
|
||||||
|
except ImportError:
|
||||||
|
raise RuntimeError('cannot import numpy, make sure numpy package is installed')
|
||||||
|
|
||||||
|
try:
|
||||||
|
from PIL import Image
|
||||||
|
except ImportError:
|
||||||
|
raise RuntimeError('cannot import PIL, make sure pillow package is installed')
|
||||||
|
|
||||||
|
|
||||||
|
def string_to_node(string):
|
||||||
|
vec = string.split(',')
|
||||||
|
return (int(vec[0]), int(vec[1]))
|
||||||
|
|
||||||
|
|
||||||
|
def string_to_floats(string):
|
||||||
|
vec = string.split(',')
|
||||||
|
return (float(vec[0]), float(vec[1]), float(vec[2]))
|
||||||
|
|
||||||
|
|
||||||
|
class CarlaMap(object):
|
||||||
|
def __init__(self, city):
|
||||||
|
dir_path = os.path.dirname(__file__)
|
||||||
|
city_file = os.path.join(dir_path, city + '.txt')
|
||||||
|
|
||||||
|
city_map_file = os.path.join(dir_path, city + '.png')
|
||||||
|
city_map_file_lanes = os.path.join(dir_path, city + 'Lanes.png')
|
||||||
|
|
||||||
|
with open(city_file, 'r') as file:
|
||||||
|
|
||||||
|
linewordloffset = file.readline()
|
||||||
|
# The offset of the world from the zero coordinates ( The
|
||||||
|
# coordinate we consider zero)
|
||||||
|
self.worldoffset = string_to_floats(linewordloffset)
|
||||||
|
|
||||||
|
lineworldangles = file.readline()
|
||||||
|
self.angles = string_to_floats(lineworldangles)
|
||||||
|
|
||||||
|
self.worldrotation = np.array([
|
||||||
|
[math.cos(math.radians(self.angles[2])), -math.sin(math.radians(self.angles[2])), 0.0],
|
||||||
|
[math.sin(math.radians(self.angles[2])), math.cos(math.radians(self.angles[2])), 0.0],
|
||||||
|
[0.0, 0.0, 1.0]])
|
||||||
|
|
||||||
|
# Ignore for now, these are offsets for map coordinates and scale
|
||||||
|
# (not used).
|
||||||
|
_ = file.readline()
|
||||||
|
linemapoffset = file.readline()
|
||||||
|
|
||||||
|
# The offset of the map zero coordinate.
|
||||||
|
self.mapoffset = string_to_floats(linemapoffset)
|
||||||
|
|
||||||
|
# the graph resolution.
|
||||||
|
linegraphres = file.readline()
|
||||||
|
self.resolution = string_to_node(linegraphres)
|
||||||
|
|
||||||
|
# The number of game units per pixel.
|
||||||
|
self.pixel_density = 16.43
|
||||||
|
# Load the lanes image
|
||||||
|
self.map_image_lanes = Image.open(city_map_file_lanes)
|
||||||
|
self.map_image_lanes.load()
|
||||||
|
self.map_image_lanes = np.asarray(self.map_image_lanes, dtype="int32")
|
||||||
|
# Load the image
|
||||||
|
self.map_image = Image.open(city_map_file)
|
||||||
|
self.map_image.load()
|
||||||
|
self.map_image = np.asarray(self.map_image, dtype="int32")
|
||||||
|
|
||||||
|
|
||||||
|
def get_map(self, height=None):
|
||||||
|
if height is not None:
|
||||||
|
img = Image.fromarray(self.map_image.astype(np.uint8))
|
||||||
|
|
||||||
|
aspect_ratio = height/float(self.map_image.shape[0])
|
||||||
|
|
||||||
|
img = img.resize((int(aspect_ratio*self.map_image.shape[1]),height), Image.ANTIALIAS)
|
||||||
|
img.load()
|
||||||
|
return np.asarray(img, dtype="int32")
|
||||||
|
return np.fliplr(self.map_image)
|
||||||
|
|
||||||
|
def get_map_lanes(self, height=None):
|
||||||
|
if size is not None:
|
||||||
|
img = Image.fromarray(self.map_image_lanes.astype(np.uint8))
|
||||||
|
img = img.resize((size[1], size[0]), Image.ANTIALIAS)
|
||||||
|
img.load()
|
||||||
|
return np.fliplr(np.asarray(img, dtype="int32"))
|
||||||
|
return np.fliplr(self.map_image_lanes)
|
||||||
|
|
||||||
|
def get_position_on_map(self, world):
|
||||||
|
"""Get the position on the map for a certain world position."""
|
||||||
|
relative_location = []
|
||||||
|
pixel = []
|
||||||
|
|
||||||
|
rotation = np.array([world[0], world[1], world[2]])
|
||||||
|
rotation = rotation.dot(self.worldrotation)
|
||||||
|
|
||||||
|
relative_location.append(rotation[0] + self.worldoffset[0] - self.mapoffset[0])
|
||||||
|
relative_location.append(rotation[1] + self.worldoffset[1] - self.mapoffset[1])
|
||||||
|
relative_location.append(rotation[2] + self.worldoffset[2] - self.mapoffset[2])
|
||||||
|
|
||||||
|
pixel.append(math.floor(relative_location[0] / float(self.pixel_density)))
|
||||||
|
pixel.append(math.floor(relative_location[1] / float(self.pixel_density)))
|
||||||
|
|
||||||
|
return pixel
|
||||||
|
|
||||||
|
def get_position_on_world(self, pixel):
|
||||||
|
"""Get world position of a certain map position."""
|
||||||
|
relative_location = []
|
||||||
|
world_vertex = []
|
||||||
|
relative_location.append(pixel[0] * self.pixel_density)
|
||||||
|
relative_location.append(pixel[1] * self.pixel_density)
|
||||||
|
|
||||||
|
world_vertex.append(relative_location[0] + self.mapoffset[0] - self.worldoffset[0])
|
||||||
|
world_vertex.append(relative_location[1] + self.mapoffset[1] - self.worldoffset[1])
|
||||||
|
world_vertex.append(22) # Z does not matter for now.
|
||||||
|
|
||||||
|
return world_vertex
|
||||||
|
|
||||||
|
def get_lane_orientation(self, world):
|
||||||
|
"""Get the lane orientation of a certain world position."""
|
||||||
|
relative_location = []
|
||||||
|
pixel = []
|
||||||
|
rotation = np.array([world[0], world[1], world[2]])
|
||||||
|
rotation = rotation.dot(self.worldrotation)
|
||||||
|
|
||||||
|
relative_location.append(rotation[0] + self.worldoffset[0] - self.mapoffset[0])
|
||||||
|
relative_location.append(rotation[1] + self.worldoffset[1] - self.mapoffset[1])
|
||||||
|
relative_location.append(rotation[2] + self.worldoffset[2] - self.mapoffset[2])
|
||||||
|
|
||||||
|
pixel.append(math.floor(relative_location[0] / float(self.pixel_density)))
|
||||||
|
pixel.append(math.floor(relative_location[1] / float(self.pixel_density)))
|
||||||
|
|
||||||
|
ori = self.map_image_lanes[int(pixel[1]), int(pixel[0]), 2]
|
||||||
|
ori = ((float(ori) / 255.0)) * 2 * math.pi
|
||||||
|
|
||||||
|
return (-math.cos(ori), -math.sin(ori))
|
|
@ -1,2 +0,0 @@
|
||||||
from .carla_server_pb2 import SceneDescription,EpisodeStart,EpisodeReady,Control,Measurements,RequestNewEpisode
|
|
||||||
|
|
|
@ -0,0 +1,231 @@
|
||||||
|
# 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>.
|
||||||
|
|
||||||
|
"""CARLA sensors."""
|
||||||
|
|
||||||
|
|
||||||
|
import os
|
||||||
|
import numpy as np
|
||||||
|
|
||||||
|
|
||||||
|
# ==============================================================================
|
||||||
|
# -- Sensor --------------------------------------------------------------------
|
||||||
|
# ==============================================================================
|
||||||
|
|
||||||
|
|
||||||
|
class Sensor(object):
|
||||||
|
"""
|
||||||
|
Base class for sensor descriptions. Used to add sensors to CarlaSettings.
|
||||||
|
"""
|
||||||
|
|
||||||
|
def set(self, **kwargs):
|
||||||
|
for key, value in kwargs.items():
|
||||||
|
if not hasattr(self, key):
|
||||||
|
raise ValueError('CarlaSettings.Camera: no key named %r' % key)
|
||||||
|
setattr(self, key, value)
|
||||||
|
|
||||||
|
|
||||||
|
class Camera(Sensor):
|
||||||
|
"""
|
||||||
|
Camera description. This class can be added to a CarlaSettings object to add
|
||||||
|
a camera to the player vehicle.
|
||||||
|
"""
|
||||||
|
|
||||||
|
def __init__(self, name, **kwargs):
|
||||||
|
self.CameraName = name
|
||||||
|
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.set(**kwargs)
|
||||||
|
|
||||||
|
def set_image_size(self, pixels_x, pixels_y):
|
||||||
|
self.ImageSizeX = pixels_x
|
||||||
|
self.ImageSizeY = pixels_y
|
||||||
|
|
||||||
|
def set_position(self, x, y, z):
|
||||||
|
self.CameraPositionX = x
|
||||||
|
self.CameraPositionY = y
|
||||||
|
self.CameraPositionZ = z
|
||||||
|
|
||||||
|
def set_rotation(self, pitch, roll, yaw):
|
||||||
|
self.CameraRotationPitch = pitch
|
||||||
|
self.CameraRotationRoll = roll
|
||||||
|
self.CameraRotationYaw = yaw
|
||||||
|
|
||||||
|
|
||||||
|
class Lidar(Sensor):
|
||||||
|
"""
|
||||||
|
Lidar description. This class can be added to a CarlaSettings object to add
|
||||||
|
a Lidar to the player vehicle.
|
||||||
|
"""
|
||||||
|
|
||||||
|
def __init__(self, name, **kwargs):
|
||||||
|
self.LidarName = name
|
||||||
|
# Number of lasers
|
||||||
|
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 ----------------------------------------------------------------
|
||||||
|
# ==============================================================================
|
||||||
|
|
||||||
|
|
||||||
|
class SensorData(object):
|
||||||
|
"""Base class for sensor data returned from the server."""
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
class Image(SensorData):
|
||||||
|
"""Data generated by a Camera."""
|
||||||
|
|
||||||
|
def __init__(self, width, height, image_type, raw_data):
|
||||||
|
assert len(raw_data) == 4 * width * height
|
||||||
|
self.width = width
|
||||||
|
self.height = height
|
||||||
|
self.type = image_type
|
||||||
|
self.raw_data = raw_data
|
||||||
|
self._converted_data = None
|
||||||
|
|
||||||
|
@property
|
||||||
|
def data(self):
|
||||||
|
"""
|
||||||
|
Lazy initialization for data property, stores converted data in its
|
||||||
|
default format.
|
||||||
|
"""
|
||||||
|
if self._converted_data is None:
|
||||||
|
from . import image_converter
|
||||||
|
|
||||||
|
if self.type == 'Depth':
|
||||||
|
self._converted_data = image_converter.depth_to_array(self)
|
||||||
|
elif self.type == 'SemanticSegmentation':
|
||||||
|
self._converted_data = image_converter.labels_to_array(self)
|
||||||
|
else:
|
||||||
|
self._converted_data = image_converter.to_rgb_array(self)
|
||||||
|
return self._converted_data
|
||||||
|
|
||||||
|
def save_to_disk(self, filename):
|
||||||
|
"""Save this image to disk (requires PIL installed)."""
|
||||||
|
try:
|
||||||
|
from PIL import Image as PImage
|
||||||
|
except ImportError:
|
||||||
|
raise RuntimeError('cannot import PIL, make sure pillow package is installed')
|
||||||
|
|
||||||
|
image = PImage.frombytes(
|
||||||
|
mode='RGBA',
|
||||||
|
size=(self.width, self.height),
|
||||||
|
data=self.raw_data,
|
||||||
|
decoder_name='raw')
|
||||||
|
b, g, r, a = image.split()
|
||||||
|
image = PImage.merge("RGB", (r, g, b))
|
||||||
|
|
||||||
|
folder = os.path.dirname(filename)
|
||||||
|
if not os.path.isdir(folder):
|
||||||
|
os.makedirs(folder)
|
||||||
|
image.save(filename)
|
||||||
|
|
||||||
|
|
||||||
|
class LidarMeasurement(SensorData):
|
||||||
|
"""Data generated by a Lidar."""
|
||||||
|
|
||||||
|
def __init__(self, horizontal_angle, channels_count, lidar_type, raw_data):
|
||||||
|
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 = np.frombuffer(points_count_by_channel_bytes, dtype=np.dtype('uint32'))
|
||||||
|
|
||||||
|
self.points_size = int(np.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
|
||||||
|
|
||||||
|
@property
|
||||||
|
def data(self):
|
||||||
|
"""
|
||||||
|
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 = np.frombuffer(self.points_data[:self.points_size], dtype='float')
|
||||||
|
points = np.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
|
||||||
|
|
||||||
|
def save_to_disk(self, filename):
|
||||||
|
"""Save lidar measurements to disk"""
|
||||||
|
|
||||||
|
pass
|
||||||
|
|
||||||
|
# image = PImage.frombytes(
|
||||||
|
# mode='RGBA',
|
||||||
|
# size=(self.width, self.height),
|
||||||
|
# data=self.raw_data,
|
||||||
|
# decoder_name='raw')
|
||||||
|
# b, g, r, a = image.split()
|
||||||
|
# image = PImage.merge("RGB", (r, g, b))
|
||||||
|
#
|
||||||
|
# folder = os.path.dirname(filename)
|
||||||
|
# if not os.path.isdir(folder):
|
||||||
|
# os.makedirs(folder)
|
||||||
|
# image.save(filename)
|
|
@ -6,53 +6,32 @@
|
||||||
|
|
||||||
"""CARLA Settings"""
|
"""CARLA Settings"""
|
||||||
|
|
||||||
import configparser
|
|
||||||
import io
|
import io
|
||||||
import random
|
import random
|
||||||
|
import sys
|
||||||
|
|
||||||
|
|
||||||
|
if sys.version_info >= (3, 0):
|
||||||
|
|
||||||
|
from configparser import ConfigParser
|
||||||
|
|
||||||
|
else:
|
||||||
|
|
||||||
|
from ConfigParser import RawConfigParser as ConfigParser
|
||||||
|
|
||||||
|
|
||||||
|
from . import sensor as carla_sensor
|
||||||
|
|
||||||
|
|
||||||
MAX_NUMBER_OF_WEATHER_IDS = 14
|
MAX_NUMBER_OF_WEATHER_IDS = 14
|
||||||
|
|
||||||
|
|
||||||
class Camera(object):
|
|
||||||
"""Camera description. To be added to CarlaSettings."""
|
|
||||||
def __init__(self, name, **kwargs):
|
|
||||||
self.CameraName = name
|
|
||||||
self.PostProcessing = 'SceneFinal'
|
|
||||||
self.ImageSizeX = 800
|
|
||||||
self.ImageSizeY = 600
|
|
||||||
self.CameraFOV = 90
|
|
||||||
self.CameraPositionX = 15
|
|
||||||
self.CameraPositionY = 0
|
|
||||||
self.CameraPositionZ = 123
|
|
||||||
self.CameraRotationPitch = 8
|
|
||||||
self.CameraRotationRoll = 0
|
|
||||||
self.CameraRotationYaw = 0
|
|
||||||
self.set(**kwargs)
|
|
||||||
|
|
||||||
def set(self, **kwargs):
|
|
||||||
for key, value in kwargs.items():
|
|
||||||
if not hasattr(self, key):
|
|
||||||
raise ValueError('CarlaSettings.Camera: no key named %r' % key)
|
|
||||||
setattr(self, key, value)
|
|
||||||
|
|
||||||
def set_image_size(self, pixels_x, pixels_y):
|
|
||||||
self.ImageSizeX = pixels_x
|
|
||||||
self.ImageSizeY = pixels_y
|
|
||||||
|
|
||||||
def set_position(self, x, y, z):
|
|
||||||
self.CameraPositionX = x
|
|
||||||
self.CameraPositionY = y
|
|
||||||
self.CameraPositionZ = z
|
|
||||||
|
|
||||||
def set_rotation(self, pitch, roll, yaw):
|
|
||||||
self.CameraRotationPitch = pitch
|
|
||||||
self.CameraRotationRoll = roll
|
|
||||||
self.CameraRotationYaw = yaw
|
|
||||||
|
|
||||||
|
|
||||||
class CarlaSettings(object):
|
class CarlaSettings(object):
|
||||||
"""CARLA settings object. Convertible to str as CarlaSettings.ini."""
|
"""
|
||||||
|
The CarlaSettings object controls the settings of an episode. The __str__
|
||||||
|
method retrieves an str with a CarlaSettings.ini file contents.
|
||||||
|
"""
|
||||||
|
|
||||||
def __init__(self, **kwargs):
|
def __init__(self, **kwargs):
|
||||||
# [CARLA/Server]
|
# [CARLA/Server]
|
||||||
self.SynchronousMode = True
|
self.SynchronousMode = True
|
||||||
|
@ -67,6 +46,7 @@ class CarlaSettings(object):
|
||||||
self.randomize_weather()
|
self.randomize_weather()
|
||||||
self.set(**kwargs)
|
self.set(**kwargs)
|
||||||
self._cameras = []
|
self._cameras = []
|
||||||
|
self._lidars = []
|
||||||
|
|
||||||
def set(self, **kwargs):
|
def set(self, **kwargs):
|
||||||
for key, value in kwargs.items():
|
for key, value in kwargs.items():
|
||||||
|
@ -74,25 +54,30 @@ class CarlaSettings(object):
|
||||||
raise ValueError('CarlaSettings: no key named %r' % key)
|
raise ValueError('CarlaSettings: no key named %r' % key)
|
||||||
setattr(self, key, value)
|
setattr(self, key, value)
|
||||||
|
|
||||||
def get_number_of_agents(self):
|
|
||||||
if not self.SendNonPlayerAgentsInfo:
|
|
||||||
return 0
|
|
||||||
return self.NumberOfVehicles + self.NumberOfPedestrians
|
|
||||||
|
|
||||||
def randomize_seeds(self):
|
def randomize_seeds(self):
|
||||||
|
"""
|
||||||
|
Randomize the seeds of the new episode's pseudo-random number
|
||||||
|
generators.
|
||||||
|
"""
|
||||||
self.SeedVehicles = random.getrandbits(16)
|
self.SeedVehicles = random.getrandbits(16)
|
||||||
self.SeedPedestrians = random.getrandbits(16)
|
self.SeedPedestrians = random.getrandbits(16)
|
||||||
|
|
||||||
def randomize_weather(self):
|
def randomize_weather(self):
|
||||||
|
"""Randomized the WeatherId."""
|
||||||
self.WeatherId = random.randint(0, MAX_NUMBER_OF_WEATHER_IDS)
|
self.WeatherId = random.randint(0, MAX_NUMBER_OF_WEATHER_IDS)
|
||||||
|
|
||||||
def add_camera(self, camera):
|
def add_sensor(self, sensor):
|
||||||
if not isinstance(camera, Camera):
|
"""Add a sensor to the player vehicle (see sensor.py)."""
|
||||||
raise ValueError('Can only add instances of carla_settings.Camera')
|
if isinstance(sensor, carla_sensor.Camera):
|
||||||
self._cameras.append(camera)
|
self._cameras.append(sensor)
|
||||||
|
elif isinstance(sensor, carla_sensor.Lidar):
|
||||||
|
self._lidars.append(sensor)
|
||||||
|
else:
|
||||||
|
raise ValueError('Sensor not supported')
|
||||||
|
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
ini = configparser.ConfigParser()
|
"""Converts this object to an INI formatted string."""
|
||||||
|
ini = ConfigParser()
|
||||||
ini.optionxform=str
|
ini.optionxform=str
|
||||||
S_SERVER = 'CARLA/Server'
|
S_SERVER = 'CARLA/Server'
|
||||||
S_LEVEL = 'CARLA/LevelSettings'
|
S_LEVEL = 'CARLA/LevelSettings'
|
||||||
|
@ -117,6 +102,7 @@ class CarlaSettings(object):
|
||||||
|
|
||||||
ini.add_section(S_CAPTURE)
|
ini.add_section(S_CAPTURE)
|
||||||
ini.set(S_CAPTURE, 'Cameras', ','.join(c.CameraName for c in self._cameras))
|
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))
|
||||||
|
|
||||||
for camera in self._cameras:
|
for camera in self._cameras:
|
||||||
add_section(S_CAPTURE + '/' + camera.CameraName, camera, [
|
add_section(S_CAPTURE + '/' + camera.CameraName, camera, [
|
||||||
|
@ -131,6 +117,49 @@ class CarlaSettings(object):
|
||||||
'CameraRotationRoll',
|
'CameraRotationRoll',
|
||||||
'CameraRotationYaw'])
|
'CameraRotationYaw'])
|
||||||
|
|
||||||
text = io.StringIO()
|
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'])
|
||||||
|
|
||||||
|
if sys.version_info >= (3, 0):
|
||||||
|
text = io.StringIO()
|
||||||
|
else:
|
||||||
|
text = io.BytesIO()
|
||||||
|
|
||||||
ini.write(text)
|
ini.write(text)
|
||||||
return text.getvalue().replace(' = ', '=')
|
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):
|
||||||
|
return [camera.CameraName for camera in settings._cameras] + \
|
||||||
|
[lidar.LidarName for lidar in settings._lidars]
|
||||||
|
ini = ConfigParser()
|
||||||
|
if sys.version_info >= (3, 0):
|
||||||
|
ini.readfp(io.StringIO(settings))
|
||||||
|
else:
|
||||||
|
ini.readfp(io.BytesIO(settings))
|
||||||
|
|
||||||
|
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 []
|
|
@ -1,114 +0,0 @@
|
||||||
#!/usr/bin/env python3
|
|
||||||
|
|
||||||
# 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>.
|
|
||||||
|
|
||||||
import binascii
|
|
||||||
import socket
|
|
||||||
import struct
|
|
||||||
import logging
|
|
||||||
import time
|
|
||||||
import select
|
|
||||||
|
|
||||||
def int2bytes(i):
|
|
||||||
hex_string = '%x' % i
|
|
||||||
n = len(hex_string)
|
|
||||||
return binascii.unhexlify(hex_string.zfill(n + (n & 1)))
|
|
||||||
|
|
||||||
def bytes2int(str):
|
|
||||||
return int(str.encode('hex'), 16)
|
|
||||||
|
|
||||||
|
|
||||||
def connect(host,port):
|
|
||||||
|
|
||||||
try:
|
|
||||||
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
|
|
||||||
sock.settimeout(100)
|
|
||||||
except socket.error:
|
|
||||||
logginge.exception("Error Creating Socket World")
|
|
||||||
|
|
||||||
sock.connect((host,port))
|
|
||||||
logging.debug("connected to %s port %d" %(host,port))
|
|
||||||
|
|
||||||
return sock
|
|
||||||
|
|
||||||
def pers_connect(host,port):
|
|
||||||
for attempt in range(10):
|
|
||||||
try:
|
|
||||||
sock = connect(host,port)
|
|
||||||
return sock
|
|
||||||
except Exception as e:
|
|
||||||
logging.exception("Failure on connection")
|
|
||||||
time.sleep(1)
|
|
||||||
continue
|
|
||||||
else:
|
|
||||||
break
|
|
||||||
raise socket.error
|
|
||||||
|
|
||||||
|
|
||||||
def disconnect(sock):
|
|
||||||
|
|
||||||
sock.shutdown(socket.SHUT_RDWR)
|
|
||||||
sock.close()
|
|
||||||
|
|
||||||
|
|
||||||
def send_message(sock, message):
|
|
||||||
""" Send a serialized message (protobuf Message interface)
|
|
||||||
to a socket, prepended by its length packed in 4
|
|
||||||
bytes (big endian).
|
|
||||||
"""
|
|
||||||
|
|
||||||
s = message.SerializeToString()
|
|
||||||
packed_len =struct.pack('<L', len(s)) #int2bytes(len(s))
|
|
||||||
logging.debug( "SOCKET Send: %d bytes" % int(len(s)))
|
|
||||||
|
|
||||||
sock.sendall(packed_len + s)
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
def get_message(sock):
|
|
||||||
""" Read a message from a socket.
|
|
||||||
"""
|
|
||||||
|
|
||||||
|
|
||||||
len_buf = socket_read_n(sock, 4)
|
|
||||||
|
|
||||||
msg_len = struct.unpack('<L', len_buf)[0]
|
|
||||||
logging.debug( "SOCKET RECEIVED: %d bytes" % msg_len)
|
|
||||||
|
|
||||||
msg_buf = socket_read_n(sock, msg_len)
|
|
||||||
|
|
||||||
return msg_buf
|
|
||||||
|
|
||||||
|
|
||||||
def socket_read_n(sock,n):
|
|
||||||
""" Read exactly n bytes from the socket.
|
|
||||||
Raise RuntimeError if the connection closed before
|
|
||||||
n bytes were read.
|
|
||||||
"""
|
|
||||||
|
|
||||||
buf = b''
|
|
||||||
while n > 0:
|
|
||||||
|
|
||||||
sock.setblocking(0)
|
|
||||||
ready = select.select([sock], [], [], 3)
|
|
||||||
if ready[0]:
|
|
||||||
try:
|
|
||||||
data = sock.recv(n)
|
|
||||||
if data == b'':
|
|
||||||
raise RuntimeError('unexpected connection close')
|
|
||||||
buf += data
|
|
||||||
n -= len(data)
|
|
||||||
except socket.error:
|
|
||||||
raise socket.error
|
|
||||||
|
|
||||||
sock.setblocking(1)
|
|
||||||
|
|
||||||
|
|
||||||
return buf
|
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,98 @@
|
||||||
|
# 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>.
|
||||||
|
|
||||||
|
"""Basic TCP client."""
|
||||||
|
|
||||||
|
import logging
|
||||||
|
import socket
|
||||||
|
import struct
|
||||||
|
import time
|
||||||
|
|
||||||
|
class TCPConnectionError(Exception):
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
class TCPClient(object):
|
||||||
|
"""
|
||||||
|
Basic networking client for TCP connections. Errors occurred during
|
||||||
|
networking operations are raised as TCPConnectionError.
|
||||||
|
|
||||||
|
Received messages are expected to be prepended by a int32 defining the
|
||||||
|
message size. Messages are sent following this convention.
|
||||||
|
"""
|
||||||
|
|
||||||
|
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, connection_attempts=10):
|
||||||
|
"""Try to establish a connection to the given host:port."""
|
||||||
|
connection_attempts = max(1, connection_attempts)
|
||||||
|
error = None
|
||||||
|
for attempt in range(1, connection_attempts + 1):
|
||||||
|
try:
|
||||||
|
self._socket = socket.create_connection(address=(self._host, self._port), timeout=self._timeout)
|
||||||
|
self._socket.settimeout(self._timeout)
|
||||||
|
logging.debug(self._logprefix + 'connected')
|
||||||
|
return
|
||||||
|
except Exception as exception:
|
||||||
|
error = exception
|
||||||
|
logging.debug(self._logprefix + 'connection attempt %d: %s', attempt, error)
|
||||||
|
time.sleep(1)
|
||||||
|
continue
|
||||||
|
self._reraise_exception_as_tcp_error('failed to connect', error)
|
||||||
|
|
||||||
|
def disconnect(self):
|
||||||
|
"""Disconnect any active connection."""
|
||||||
|
if self._socket is not None:
|
||||||
|
logging.debug(self._logprefix + 'disconnecting')
|
||||||
|
self._socket.close()
|
||||||
|
self._socket = None
|
||||||
|
|
||||||
|
def connected(self):
|
||||||
|
"""Return whether there is an active connection."""
|
||||||
|
return self._socket is not None
|
||||||
|
|
||||||
|
def write(self, message):
|
||||||
|
"""Send message to the server."""
|
||||||
|
if self._socket is None:
|
||||||
|
raise TCPConnectionError(self._logprefix + 'not connected')
|
||||||
|
header = struct.pack('<L', len(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):
|
||||||
|
"""Read a message from the server."""
|
||||||
|
header = self._read_n(4)
|
||||||
|
if not header:
|
||||||
|
raise TCPConnectionError(self._logprefix + 'connection closed')
|
||||||
|
length = struct.unpack('<L', header)[0]
|
||||||
|
data = self._read_n(length)
|
||||||
|
return data
|
||||||
|
|
||||||
|
def _read_n(self, length):
|
||||||
|
"""Read n bytes from the socket."""
|
||||||
|
if self._socket is None:
|
||||||
|
raise TCPConnectionError(self._logprefix + 'not connected')
|
||||||
|
buf = bytes()
|
||||||
|
while length > 0:
|
||||||
|
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 TCPConnectionError(self._logprefix + 'connection closed')
|
||||||
|
buf += data
|
||||||
|
length -= len(data)
|
||||||
|
return buf
|
||||||
|
|
||||||
|
def _reraise_exception_as_tcp_error(self, message, exception):
|
||||||
|
raise TCPConnectionError('%s%s: %s' % (self._logprefix, message, exception))
|
|
@ -5,17 +5,14 @@
|
||||||
# For a copy, see <https://opensource.org/licenses/MIT>.
|
# For a copy, see <https://opensource.org/licenses/MIT>.
|
||||||
|
|
||||||
import datetime
|
import datetime
|
||||||
|
import sys
|
||||||
|
|
||||||
from contextlib import contextmanager
|
from contextlib import contextmanager
|
||||||
|
|
||||||
|
|
||||||
def to_hex_str(header):
|
|
||||||
return ':'.join('{:02x}'.format(ord(c)) for c in header)
|
|
||||||
|
|
||||||
|
|
||||||
@contextmanager
|
@contextmanager
|
||||||
def make_connection(client_type, *args, **kwargs):
|
def make_connection(client_type, *args, **kwargs):
|
||||||
"""Context manager to create and connect a networking object."""
|
"""Context manager to create and connect a networking client object."""
|
||||||
client = None
|
client = None
|
||||||
try:
|
try:
|
||||||
client = client_type(*args, **kwargs)
|
client = client_type(*args, **kwargs)
|
||||||
|
@ -36,3 +33,29 @@ class StopWatch(object):
|
||||||
|
|
||||||
def milliseconds(self):
|
def milliseconds(self):
|
||||||
return 1000.0 * (self.end - self.start).total_seconds()
|
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
|
|
@ -1,241 +0,0 @@
|
||||||
#!/usr/bin/env python3
|
|
||||||
|
|
||||||
# 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>.
|
|
||||||
|
|
||||||
"""Basic CARLA client example."""
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
from __future__ import print_function
|
|
||||||
# General Imports
|
|
||||||
import numpy as np
|
|
||||||
from PIL import Image
|
|
||||||
import random
|
|
||||||
import time
|
|
||||||
import sys
|
|
||||||
import argparse
|
|
||||||
import logging
|
|
||||||
import os
|
|
||||||
|
|
||||||
# Carla imports, Everything can be imported directly from "carla" package
|
|
||||||
|
|
||||||
from carla import CARLA
|
|
||||||
from carla import Control
|
|
||||||
from carla import Measurements
|
|
||||||
|
|
||||||
# Constant that set how offten the episodes are reseted
|
|
||||||
|
|
||||||
RESET_FREQUENCY = 100
|
|
||||||
|
|
||||||
"""
|
|
||||||
Print function, prints all the measurements saving
|
|
||||||
the images into a folder. WARNING just prints the first BGRA image
|
|
||||||
Args:
|
|
||||||
param1: The measurements dictionary to be printed
|
|
||||||
param2: The iterations
|
|
||||||
|
|
||||||
Returns:
|
|
||||||
None
|
|
||||||
Raises:
|
|
||||||
None
|
|
||||||
"""
|
|
||||||
|
|
||||||
def print_pack(measurements,i,write_images):
|
|
||||||
|
|
||||||
if write_images:
|
|
||||||
image_result = Image.fromarray( measurements['BGRA'][0])
|
|
||||||
|
|
||||||
b, g, r,a = image_result.split()
|
|
||||||
image_result = Image.merge("RGBA", (r, g, b,a))
|
|
||||||
|
|
||||||
if not os.path.exists('images'):
|
|
||||||
os.mkdir('images')
|
|
||||||
image_result.save('images/image' + str(i) + '.png')
|
|
||||||
|
|
||||||
|
|
||||||
print ('Pack ',i)
|
|
||||||
print (' Wall Time: ',measurements['WallTime'])
|
|
||||||
print (' Game Time: ',measurements['GameTime'])
|
|
||||||
print (' Player Measurements ')
|
|
||||||
|
|
||||||
print (' Position: (%f,%f,%f)' % (measurements['PlayerMeasurements'].\
|
|
||||||
transform.location.x,measurements['PlayerMeasurements'].transform.location.y,\
|
|
||||||
measurements['PlayerMeasurements'].transform.location.z ))
|
|
||||||
print (' Orientation: (%f,%f,%f)' % (measurements['PlayerMeasurements'].\
|
|
||||||
transform.orientation.x,measurements['PlayerMeasurements'].transform.orientation.y,\
|
|
||||||
measurements['PlayerMeasurements'].transform.orientation.z ))
|
|
||||||
|
|
||||||
print (' Acceleration: (%f,%f,%f)' % (measurements['PlayerMeasurements'].\
|
|
||||||
acceleration.x,measurements['PlayerMeasurements'].acceleration.y,measurements['PlayerMeasurements'].acceleration.z ))
|
|
||||||
print (' Speed: ',measurements['PlayerMeasurements'].forward_speed)
|
|
||||||
print (' Collision Vehicles (Acum. Impact): ',measurements['PlayerMeasurements'].collision_vehicles)
|
|
||||||
print (' Collision Pedestrians (Acum. Impact): ',measurements['PlayerMeasurements'].collision_pedestrians)
|
|
||||||
print (' Collision Other (Acum. Impact): ',measurements['PlayerMeasurements'].collision_other)
|
|
||||||
print (' Intersection Opposite Lane (% Volume): ',measurements['PlayerMeasurements'].intersection_otherlane)
|
|
||||||
print (' Intersection Opposite Sidewalk (% Volume): ',measurements['PlayerMeasurements'].intersection_offroad)
|
|
||||||
|
|
||||||
|
|
||||||
print (' ',len(measurements['Agents']),' Agents (Positions not printed)')
|
|
||||||
print (' ',end='')
|
|
||||||
for agent in measurements['Agents']:
|
|
||||||
|
|
||||||
if agent.HasField('vehicle'):
|
|
||||||
print ('Car',end='')
|
|
||||||
|
|
||||||
elif agent.HasField('pedestrian'):
|
|
||||||
print ('Pedestrian',end='')
|
|
||||||
|
|
||||||
elif agent.HasField('traffic_light'):
|
|
||||||
print ('Traffic Light',end='')
|
|
||||||
|
|
||||||
|
|
||||||
elif agent.HasField('speed_limit_sign'):
|
|
||||||
print ('Speed Limit Sign',end='')
|
|
||||||
print(',',end='')
|
|
||||||
print('')
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
def use_example(ini_file,port = 2000, host ='127.0.0.1',print_measurements =False,images_to_disk=False):
|
|
||||||
|
|
||||||
# We assume the CARLA server is already waiting for a client to connect at
|
|
||||||
# host:port. To create a connection we can use the CARLA
|
|
||||||
# constructor, it creates a CARLA client object and starts the
|
|
||||||
# connection. It will throw an exception if something goes wrong.
|
|
||||||
|
|
||||||
carla =CARLA(host,port)
|
|
||||||
|
|
||||||
""" As a first step, Carla must have a configuration file loaded. This will load a map in the server
|
|
||||||
with the properties specified by the ini file. It returns all the posible starting positions on the map
|
|
||||||
in a vector.
|
|
||||||
"""
|
|
||||||
positions = carla.loadConfigurationFile(ini_file)
|
|
||||||
|
|
||||||
"""
|
|
||||||
Ask Server for a new episode starting on position of index zero in the positions vector
|
|
||||||
"""
|
|
||||||
carla.newEpisode(0)
|
|
||||||
|
|
||||||
capture = time.time()
|
|
||||||
# General iteratior
|
|
||||||
i = 1
|
|
||||||
# Iterator that will go over the positions on the map after each episode
|
|
||||||
iterator_start_positions = 1
|
|
||||||
|
|
||||||
while True:
|
|
||||||
try:
|
|
||||||
"""
|
|
||||||
User get the measurements dictionary from the server.
|
|
||||||
Measurements contains:
|
|
||||||
* WallTime: Current time on Wall from server machine.
|
|
||||||
* GameTime: Current time on Game. Restarts at every episode
|
|
||||||
* PlayerMeasurements : All information and events that happens to player
|
|
||||||
* Agents : All non-player agents present on the map information such as cars positions, traffic light states
|
|
||||||
* BRGA : BGRA optical images
|
|
||||||
* Depth : Depth Images
|
|
||||||
* Labels : Images containing the semantic segmentation. NOTE: the semantic segmentation must be
|
|
||||||
previously activated on the server. See documentation for that.
|
|
||||||
|
|
||||||
"""
|
|
||||||
|
|
||||||
|
|
||||||
measurements = carla.getMeasurements()
|
|
||||||
|
|
||||||
# Print all the measurements... Will write images to disk
|
|
||||||
if print_measurements:
|
|
||||||
print_pack(measurements,i,images_to_disk)
|
|
||||||
|
|
||||||
"""
|
|
||||||
Sends a control command to the server
|
|
||||||
This control structue contains the following fields:
|
|
||||||
* throttle : goes from 0 to -1
|
|
||||||
* steer : goes from -1 to 1
|
|
||||||
* brake : goes from 0 to 1
|
|
||||||
* hand_brake : Activate or desactivate the Hand Brake.
|
|
||||||
* reverse: Activate or desactive the reverse gear.
|
|
||||||
|
|
||||||
"""
|
|
||||||
|
|
||||||
control = Control()
|
|
||||||
control.throttle = 0.9
|
|
||||||
control.steer = (random.random() * 2) - 1
|
|
||||||
|
|
||||||
carla.sendCommand(control)
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
i+=1
|
|
||||||
|
|
||||||
|
|
||||||
if i % RESET_FREQUENCY ==0:
|
|
||||||
|
|
||||||
print ('Fps for this episode : ',(1.0/((time.time() -capture)/100.0)))
|
|
||||||
|
|
||||||
|
|
||||||
"""
|
|
||||||
Starts another new episode, the episode will have the same configuration as the previous
|
|
||||||
one. In order to change configuration, the loadConfigurationFile could be called at any
|
|
||||||
time.
|
|
||||||
"""
|
|
||||||
if iterator_start_positions < len(positions):
|
|
||||||
carla.newEpisode(iterator_start_positions)
|
|
||||||
iterator_start_positions+=1
|
|
||||||
else :
|
|
||||||
carla.newEpisode(0)
|
|
||||||
iterator_start_positions = 1
|
|
||||||
|
|
||||||
print("Now Starting on Position: ",iterator_start_positions-1)
|
|
||||||
capture = time.time()
|
|
||||||
|
|
||||||
|
|
||||||
except Exception as e:
|
|
||||||
|
|
||||||
logging.exception('Exception raised to the top')
|
|
||||||
time.sleep(1)
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
if __name__ == "__main__" :
|
|
||||||
parser = argparse.ArgumentParser(description='Run the carla client example that connects to a server')
|
|
||||||
parser.add_argument('host', metavar='HOST', type=str, help='host to connect to')
|
|
||||||
parser.add_argument('port', metavar='PORT', type=int, help='port to connect to')
|
|
||||||
|
|
||||||
parser.add_argument("-c", "--config", help="the path for the server ini file that the client sends",type=str,default="CarlaSettings.ini")
|
|
||||||
|
|
||||||
|
|
||||||
parser.add_argument("-l", "--log", help="activate the log file",action="store_true")
|
|
||||||
parser.add_argument("-lv", "--log_verbose", help="activate log and put the log file to screen",action="store_true")
|
|
||||||
|
|
||||||
parser.add_argument("-pm", "--print", help=" prints the game measurements",action="store_true")
|
|
||||||
parser.add_argument(
|
|
||||||
'-i', '--images-to-disk',
|
|
||||||
action='store_true',
|
|
||||||
help='save images to disk')
|
|
||||||
|
|
||||||
|
|
||||||
args = parser.parse_args()
|
|
||||||
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
|
|
||||||
|
|
||||||
|
|
||||||
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)
|
|
||||||
else:
|
|
||||||
sys.tracebacklimit=0 # Avoid huge exception messages out of debug mode
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
use_example(args.config,port=args.port, host=args.host,print_measurements=args.print,images_to_disk= args.images_to_disk)
|
|
|
@ -0,0 +1,231 @@
|
||||||
|
#!/usr/bin/env python3
|
||||||
|
|
||||||
|
# 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>.
|
||||||
|
|
||||||
|
"""Basic CARLA client example."""
|
||||||
|
|
||||||
|
from __future__ import print_function
|
||||||
|
|
||||||
|
import argparse
|
||||||
|
import logging
|
||||||
|
import random
|
||||||
|
import sys
|
||||||
|
import time
|
||||||
|
|
||||||
|
from carla.client import make_carla_client
|
||||||
|
from carla.sensor import Camera
|
||||||
|
from carla.settings import CarlaSettings
|
||||||
|
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, settings_filepath):
|
||||||
|
# Here we will run 3 episodes with 300 frames each.
|
||||||
|
number_of_episodes = 3
|
||||||
|
frames_per_episode = 300
|
||||||
|
|
||||||
|
# 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(host, port) as client:
|
||||||
|
print('CarlaClient connected')
|
||||||
|
|
||||||
|
for episode in range(0, number_of_episodes):
|
||||||
|
# Start a new episode.
|
||||||
|
|
||||||
|
if settings_filepath is None:
|
||||||
|
|
||||||
|
# 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([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.
|
||||||
|
|
||||||
|
# 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_sensor(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_sensor(camera1)
|
||||||
|
|
||||||
|
else:
|
||||||
|
|
||||||
|
# Alternatively, we can load these settings from a file.
|
||||||
|
with open(settings_filepath, 'r') as fp:
|
||||||
|
settings = fp.read()
|
||||||
|
|
||||||
|
# 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 at random.
|
||||||
|
number_of_player_starts = len(scene.player_start_spots)
|
||||||
|
player_start = random.randint(0, max(0, number_of_player_starts - 1))
|
||||||
|
|
||||||
|
# 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)
|
||||||
|
|
||||||
|
# Save the images to disk if requested.
|
||||||
|
if save_images_to_disk:
|
||||||
|
for name, image in sensor_data.items():
|
||||||
|
image.save_to_disk(image_filename_format.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
|
||||||
|
# depth value (normalized) at pixel X, Y
|
||||||
|
#
|
||||||
|
# depth_array = sensor_data['CameraDepth'].data
|
||||||
|
# value_at_pixel = depth_array[Y, X]
|
||||||
|
#
|
||||||
|
|
||||||
|
# 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 autopilot_on:
|
||||||
|
|
||||||
|
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
|
||||||
|
control.steer += random.uniform(-0.1, 0.1)
|
||||||
|
client.send_control(control)
|
||||||
|
|
||||||
|
|
||||||
|
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:.2f} 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 / 100, # cm -> m
|
||||||
|
pos_y=player_measurements.transform.location.y / 100,
|
||||||
|
speed=player_measurements.forward_speed,
|
||||||
|
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(
|
||||||
|
'-i', '--images-to-disk',
|
||||||
|
action='store_true',
|
||||||
|
help='save images to disk')
|
||||||
|
argparser.add_argument(
|
||||||
|
'-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='%(levelname)s: %(message)s', level=log_level)
|
||||||
|
|
||||||
|
logging.info('listening to server %s:%s', args.host, args.port)
|
||||||
|
|
||||||
|
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='_images/episode_{:0>3d}/{:s}/image_{:0>5d}.png',
|
||||||
|
settings_filepath=args.carla_settings)
|
||||||
|
|
||||||
|
print('Done.')
|
||||||
|
return
|
||||||
|
|
||||||
|
except TCPConnectionError as error:
|
||||||
|
logging.error(error)
|
||||||
|
time.sleep(1)
|
||||||
|
except Exception as exception:
|
||||||
|
logging.exception(exception)
|
||||||
|
sys.exit(1)
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == '__main__':
|
||||||
|
|
||||||
|
try:
|
||||||
|
main()
|
||||||
|
except KeyboardInterrupt:
|
||||||
|
print('\nCancelled by user. Bye!')
|
|
@ -0,0 +1,398 @@
|
||||||
|
#!/usr/bin/env python3
|
||||||
|
|
||||||
|
# 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>.
|
||||||
|
|
||||||
|
# Keyboard controlling for carla. Please refer to client_example for a simpler
|
||||||
|
# and more documented example.
|
||||||
|
|
||||||
|
"""
|
||||||
|
Welcome to CARLA manual control.
|
||||||
|
|
||||||
|
Use ARROWS or WASD keys for control.
|
||||||
|
|
||||||
|
W : throttle
|
||||||
|
S : brake
|
||||||
|
AD : steer
|
||||||
|
Q : toggle reverse
|
||||||
|
Space : hand-brake
|
||||||
|
|
||||||
|
R : restart level
|
||||||
|
|
||||||
|
STARTING in a moment...
|
||||||
|
"""
|
||||||
|
|
||||||
|
from __future__ import print_function
|
||||||
|
|
||||||
|
import argparse
|
||||||
|
import logging
|
||||||
|
import random
|
||||||
|
import sys
|
||||||
|
import time
|
||||||
|
|
||||||
|
try:
|
||||||
|
import pygame
|
||||||
|
from pygame.locals import *
|
||||||
|
except ImportError:
|
||||||
|
raise RuntimeError('cannot import pygame, make sure pygame package is installed')
|
||||||
|
|
||||||
|
try:
|
||||||
|
import numpy as np
|
||||||
|
except ImportError:
|
||||||
|
raise RuntimeError('cannot import numpy, make sure numpy package is installed')
|
||||||
|
|
||||||
|
from carla import image_converter
|
||||||
|
from carla import sensor
|
||||||
|
from carla.client import make_carla_client, VehicleControl
|
||||||
|
from carla.planner.map import CarlaMap
|
||||||
|
from carla.settings import CarlaSettings
|
||||||
|
from carla.tcp import TCPConnectionError
|
||||||
|
from carla.util import print_over_same_line
|
||||||
|
|
||||||
|
|
||||||
|
WINDOW_WIDTH = 800
|
||||||
|
WINDOW_HEIGHT = 600
|
||||||
|
MINI_WINDOW_WIDTH = 320
|
||||||
|
MINI_WINDOW_HEIGHT = 180
|
||||||
|
|
||||||
|
|
||||||
|
def make_carla_settings():
|
||||||
|
"""Make a CarlaSettings object with the settings we need."""
|
||||||
|
settings = CarlaSettings()
|
||||||
|
settings.set(
|
||||||
|
SynchronousMode=False,
|
||||||
|
SendNonPlayerAgentsInfo=True,
|
||||||
|
NumberOfVehicles=15,
|
||||||
|
NumberOfPedestrians=30,
|
||||||
|
WeatherId=random.choice([1, 3, 7, 8, 14]))
|
||||||
|
settings.randomize_seeds()
|
||||||
|
camera0 = sensor.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_sensor(camera0)
|
||||||
|
camera1 = sensor.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_sensor(camera1)
|
||||||
|
camera2 = sensor.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_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)
|
||||||
|
|
||||||
|
return settings
|
||||||
|
|
||||||
|
|
||||||
|
class Timer(object):
|
||||||
|
def __init__(self):
|
||||||
|
self.step = 0
|
||||||
|
self._lap_step = 0
|
||||||
|
self._lap_time = time.time()
|
||||||
|
|
||||||
|
def tick(self):
|
||||||
|
self.step += 1
|
||||||
|
|
||||||
|
def lap(self):
|
||||||
|
self._lap_step = self.step
|
||||||
|
self._lap_time = time.time()
|
||||||
|
|
||||||
|
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, 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._map_view = None
|
||||||
|
self._is_on_reverse = False
|
||||||
|
self._city_name = city_name
|
||||||
|
self._map = CarlaMap(city_name) if city_name is not None else None
|
||||||
|
self._map_shape = self._map.map_image.shape if city_name is not None else None
|
||||||
|
self._map_view = self._map.get_map(WINDOW_HEIGHT) if city_name is not None else None
|
||||||
|
|
||||||
|
def execute(self):
|
||||||
|
"""Launch the PyGame."""
|
||||||
|
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):
|
||||||
|
if self._city_name is not None:
|
||||||
|
self._display = pygame.display.set_mode(
|
||||||
|
(WINDOW_WIDTH + int((WINDOW_HEIGHT/float(self._map.map_image.shape[0]))*self._map.map_image.shape[1]), WINDOW_HEIGHT),
|
||||||
|
pygame.HWSURFACE | pygame.DOUBLEBUF)
|
||||||
|
else:
|
||||||
|
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):
|
||||||
|
scene = self.client.load_settings(make_carla_settings())
|
||||||
|
number_of_player_starts = len(scene.player_start_spots)
|
||||||
|
player_start = np.random.randint(number_of_player_starts)
|
||||||
|
print('Starting new episode...')
|
||||||
|
self.client.start_episode(player_start)
|
||||||
|
self._timer = Timer()
|
||||||
|
self._is_on_reverse = False
|
||||||
|
|
||||||
|
def _on_loop(self):
|
||||||
|
self._timer.tick()
|
||||||
|
|
||||||
|
measurements, sensor_data = self.client.read_data()
|
||||||
|
|
||||||
|
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']
|
||||||
|
|
||||||
|
# Print measurements every second.
|
||||||
|
if self._timer.elapsed_seconds_since_lap() > 1.0:
|
||||||
|
if self._city_name is not None:
|
||||||
|
# Function to get car position on map.
|
||||||
|
map_position = self._map.get_position_on_map([
|
||||||
|
measurements.player_measurements.transform.location.x,
|
||||||
|
measurements.player_measurements.transform.location.y,
|
||||||
|
measurements.player_measurements.transform.location.z])
|
||||||
|
# Function to get orientation of the road car is in.
|
||||||
|
lane_orientation = self._map.get_lane_orientation([
|
||||||
|
measurements.player_measurements.transform.location.x,
|
||||||
|
measurements.player_measurements.transform.location.y,
|
||||||
|
measurements.player_measurements.transform.location.z])
|
||||||
|
|
||||||
|
self._print_player_measurements_map(
|
||||||
|
measurements.player_measurements,
|
||||||
|
map_position,
|
||||||
|
lane_orientation)
|
||||||
|
else:
|
||||||
|
self._print_player_measurements(measurements.player_measurements)
|
||||||
|
|
||||||
|
# Plot position on the map as well.
|
||||||
|
|
||||||
|
self._timer.lap()
|
||||||
|
|
||||||
|
control = self._get_keyboard_control(pygame.key.get_pressed())
|
||||||
|
# Set the player position
|
||||||
|
if self._city_name is not None:
|
||||||
|
self._position = self._map.get_position_on_map([
|
||||||
|
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:
|
||||||
|
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
|
||||||
|
if keys[K_RIGHT] or keys[K_d]:
|
||||||
|
control.steer = 1.0
|
||||||
|
if keys[K_UP] or keys[K_w]:
|
||||||
|
control.throttle = 1.0
|
||||||
|
if keys[K_DOWN] or keys[K_s]:
|
||||||
|
control.brake = 1.0
|
||||||
|
if keys[K_SPACE]:
|
||||||
|
control.hand_brake = True
|
||||||
|
if keys[K_q]:
|
||||||
|
self._is_on_reverse = not self._is_on_reverse
|
||||||
|
control.reverse = self._is_on_reverse
|
||||||
|
return control
|
||||||
|
|
||||||
|
def _print_player_measurements_map(
|
||||||
|
self,
|
||||||
|
player_measurements,
|
||||||
|
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 += '{speed:.2f} km/h, '
|
||||||
|
message += '{other_lane:.0f}% other lane, {offroad:.0f}% off-road'
|
||||||
|
message = message.format(
|
||||||
|
map_x=map_position[0],
|
||||||
|
map_y=map_position[1],
|
||||||
|
ori_x=lane_orientation[0],
|
||||||
|
ori_y=lane_orientation[1],
|
||||||
|
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)
|
||||||
|
|
||||||
|
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)
|
||||||
|
|
||||||
|
def _on_render(self):
|
||||||
|
gap_x = (WINDOW_WIDTH - 2 * MINI_WINDOW_WIDTH) / 3
|
||||||
|
mini_image_y = WINDOW_HEIGHT - MINI_WINDOW_HEIGHT - gap_x
|
||||||
|
|
||||||
|
if self._main_image is not None:
|
||||||
|
array = image_converter.to_rgb_array(self._main_image)
|
||||||
|
surface = pygame.surfarray.make_surface(array.swapaxes(0, 1))
|
||||||
|
self._display.blit(surface, (0, 0))
|
||||||
|
|
||||||
|
if self._mini_view_image1 is not None:
|
||||||
|
array = image_converter.depth_to_logarithmic_grayscale(self._mini_view_image1)
|
||||||
|
surface = pygame.surfarray.make_surface(array.swapaxes(0, 1))
|
||||||
|
self._display.blit(surface, (gap_x, mini_image_y))
|
||||||
|
|
||||||
|
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.swapaxes(0, 1))
|
||||||
|
|
||||||
|
self._display.blit(
|
||||||
|
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 /= 50.0
|
||||||
|
lidar_data += 100.0
|
||||||
|
lidar_data = np.fabs(lidar_data)
|
||||||
|
lidar_data = lidar_data.astype(np.int32)
|
||||||
|
lidar_data = np.reshape(lidar_data, (-1, 2))
|
||||||
|
#draw lidar
|
||||||
|
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
|
||||||
|
)
|
||||||
|
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])
|
||||||
|
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)
|
||||||
|
for agent in self._agent_positions:
|
||||||
|
if agent.HasField('vehicle'):
|
||||||
|
agent_position = self._map.get_position_on_map([
|
||||||
|
agent.vehicle.transform.location.x,
|
||||||
|
agent.vehicle.transform.location.y,
|
||||||
|
agent.vehicle.transform.location.z])
|
||||||
|
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)
|
||||||
|
|
||||||
|
self._display.blit(surface, (WINDOW_WIDTH, 0))
|
||||||
|
|
||||||
|
pygame.display.flip()
|
||||||
|
|
||||||
|
|
||||||
|
def main():
|
||||||
|
argparser = argparse.ArgumentParser(
|
||||||
|
description='CARLA Manual Control Client')
|
||||||
|
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(
|
||||||
|
'-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)')
|
||||||
|
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)
|
||||||
|
|
||||||
|
print(__doc__)
|
||||||
|
|
||||||
|
while True:
|
||||||
|
try:
|
||||||
|
|
||||||
|
with make_carla_client(args.host, args.port) as client:
|
||||||
|
game = CarlaGame(client, args.map_name)
|
||||||
|
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__':
|
||||||
|
|
||||||
|
try:
|
||||||
|
main()
|
||||||
|
except KeyboardInterrupt:
|
||||||
|
print('\nCancelled by user. Bye!')
|
|
@ -15,8 +15,9 @@ import threading
|
||||||
import time
|
import time
|
||||||
|
|
||||||
|
|
||||||
from .client import CarlaClient
|
from carla.client import CarlaClient
|
||||||
from .settings import CarlaSettings, Camera
|
from carla.sensor import Camera, Image
|
||||||
|
from carla.settings import CarlaSettings
|
||||||
|
|
||||||
|
|
||||||
class _Control(object):
|
class _Control(object):
|
||||||
|
@ -55,7 +56,7 @@ def get_default_carla_settings(args):
|
||||||
NumberOfVehicles=20,
|
NumberOfVehicles=20,
|
||||||
NumberOfPedestrians=40,
|
NumberOfPedestrians=40,
|
||||||
WeatherId=1)
|
WeatherId=1)
|
||||||
settings.add_camera(Camera('Camera1'))
|
settings.add_sensor(Camera('Camera1'))
|
||||||
return str(settings)
|
return str(settings)
|
||||||
|
|
||||||
|
|
||||||
|
@ -88,7 +89,6 @@ class CarlaClientConsole(cmd.Cmd):
|
||||||
self.done = False
|
self.done = False
|
||||||
self.thread.start()
|
self.thread.start()
|
||||||
|
|
||||||
|
|
||||||
def cleanup(self):
|
def cleanup(self):
|
||||||
self.do_disconnect()
|
self.do_disconnect()
|
||||||
self.done = True
|
self.done = True
|
||||||
|
@ -129,7 +129,7 @@ class CarlaClientConsole(cmd.Cmd):
|
||||||
self.control = _Control()
|
self.control = _Control()
|
||||||
if not self.client.connected():
|
if not self.client.connected():
|
||||||
self.client.connect()
|
self.client.connect()
|
||||||
self.client.request_new_episode(self.settings)
|
self.client.load_settings(self.settings)
|
||||||
self.client.start_episode(0)
|
self.client.start_episode(0)
|
||||||
logging.info('new episode started')
|
logging.info('new episode started')
|
||||||
except Exception as exception:
|
except Exception as exception:
|
||||||
|
@ -165,11 +165,12 @@ class CarlaClientConsole(cmd.Cmd):
|
||||||
filename = '_images/console/camera_{:0>3d}/image_{:0>8d}.png'
|
filename = '_images/console/camera_{:0>3d}/image_{:0>8d}.png'
|
||||||
while not self.done:
|
while not self.done:
|
||||||
try:
|
try:
|
||||||
measurements, images = self.client.read_measurements()
|
measurements, sensor_data = self.client.read_data()
|
||||||
if self.print_measurements:
|
if self.print_measurements:
|
||||||
print(measurements)
|
print(measurements)
|
||||||
|
|
||||||
if self.args.images_to_disk:
|
if self.args.images_to_disk:
|
||||||
|
images = [x for x in sensor_data.values() if isinstance(x, Image)]
|
||||||
for n, image in enumerate(images):
|
for n, image in enumerate(images):
|
||||||
path = filename.format(n, measurements.game_timestamp)
|
path = filename.format(n, measurements.game_timestamp)
|
||||||
image.save_to_disk(path)
|
image.save_to_disk(path)
|
|
@ -20,11 +20,13 @@ sys.path.append(os.path.join(os.path.dirname(__file__), '..'))
|
||||||
import carla
|
import carla
|
||||||
|
|
||||||
from carla.client import CarlaClient
|
from carla.client import CarlaClient
|
||||||
from carla.console import CarlaClientConsole
|
from carla.sensor import Camera, Image
|
||||||
from carla.settings import CarlaSettings, Camera
|
from carla.settings import CarlaSettings
|
||||||
from carla.tcp import TCPClient
|
from carla.tcp import TCPClient
|
||||||
from carla.util import make_connection
|
from carla.util import make_connection
|
||||||
|
|
||||||
|
import console
|
||||||
|
|
||||||
|
|
||||||
def run_carla_client(args):
|
def run_carla_client(args):
|
||||||
with make_connection(CarlaClient, args.host, args.port, timeout=15) as client:
|
with make_connection(CarlaClient, args.host, args.port, timeout=15) as client:
|
||||||
|
@ -39,12 +41,12 @@ def run_carla_client(args):
|
||||||
settings.randomize_seeds()
|
settings.randomize_seeds()
|
||||||
camera = Camera('DefaultCamera')
|
camera = Camera('DefaultCamera')
|
||||||
camera.set_image_size(300, 200) # Do not change this, hard-coded in test.
|
camera.set_image_size(300, 200) # Do not change this, hard-coded in test.
|
||||||
settings.add_camera(camera)
|
settings.add_sensor(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')
|
||||||
|
|
||||||
scene = client.request_new_episode(settings)
|
scene = client.load_settings(settings)
|
||||||
|
|
||||||
number_of_player_starts = len(scene.player_start_spots)
|
number_of_player_starts = len(scene.player_start_spots)
|
||||||
player_start = random.randint(0, max(0, number_of_player_starts - 1))
|
player_start = random.randint(0, max(0, number_of_player_starts - 1))
|
||||||
|
@ -56,12 +58,13 @@ def run_carla_client(args):
|
||||||
|
|
||||||
client.start_episode(player_start)
|
client.start_episode(player_start)
|
||||||
|
|
||||||
use_ai_control = (random.random() < 0.5)
|
use_autopilot_control = (random.random() < 0.5)
|
||||||
reverse = (random.random() < 0.2)
|
reverse = (random.random() < 0.2)
|
||||||
|
|
||||||
for frame 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, sensor_data = client.read_data()
|
||||||
|
images = [x for x in sensor_data.values() if isinstance(x, Image)]
|
||||||
|
|
||||||
logging.debug('received data of %d agents', len(measurements.non_player_agents))
|
logging.debug('received data of %d agents', len(measurements.non_player_agents))
|
||||||
assert len(images) == 1
|
assert len(images) == 1
|
||||||
|
@ -71,8 +74,8 @@ def run_carla_client(args):
|
||||||
images[0].save_to_disk(filename.format(episode, frame))
|
images[0].save_to_disk(filename.format(episode, frame))
|
||||||
|
|
||||||
logging.debug('sending control...')
|
logging.debug('sending control...')
|
||||||
control = measurements.player_measurements.ai_control
|
control = measurements.player_measurements.autopilot_control
|
||||||
if not use_ai_control:
|
if not use_autopilot_control:
|
||||||
control.steer = random.uniform(-1.0, 1.0)
|
control.steer = random.uniform(-1.0, 1.0)
|
||||||
control.throttle = 0.3
|
control.throttle = 0.3
|
||||||
control.hand_brake = False
|
control.hand_brake = False
|
||||||
|
@ -140,7 +143,7 @@ def main():
|
||||||
logging.info('listening to server %s:%s', args.host, args.port)
|
logging.info('listening to server %s:%s', args.host, args.port)
|
||||||
|
|
||||||
if args.console:
|
if args.console:
|
||||||
cmd = CarlaClientConsole(args)
|
cmd = console.CarlaClientConsole(args)
|
||||||
try:
|
try:
|
||||||
cmd.cmdloop()
|
cmd.cmdloop()
|
||||||
finally:
|
finally:
|
|
@ -23,6 +23,7 @@ sys.path.append(os.path.join(os.path.dirname(__file__), '.'))
|
||||||
|
|
||||||
import carla
|
import carla
|
||||||
|
|
||||||
|
from carla.tcp import TCPConnectionError
|
||||||
from carla.util import StopWatch
|
from carla.util import StopWatch
|
||||||
|
|
||||||
from unit_tests import CarlaServerTest
|
from unit_tests import CarlaServerTest
|
||||||
|
@ -99,14 +100,20 @@ def run_test(test, args):
|
||||||
logging.error('exception instantiating %r: %s', test.name, exception)
|
logging.error('exception instantiating %r: %s', test.name, exception)
|
||||||
return False
|
return False
|
||||||
log_test(RUN, test.name)
|
log_test(RUN, test.name)
|
||||||
try:
|
while True:
|
||||||
timer = StopWatch()
|
try:
|
||||||
result = test.run()
|
timer = StopWatch()
|
||||||
timer.stop()
|
result = test.run()
|
||||||
except Exception as exception:
|
timer.stop()
|
||||||
timer.stop()
|
break
|
||||||
logging.error('exception: %s', exception)
|
except TCPConnectionError as error:
|
||||||
result = False
|
logging.error(error)
|
||||||
|
time.sleep(1)
|
||||||
|
except Exception as exception:
|
||||||
|
timer.stop()
|
||||||
|
logging.exception('exception: %s', exception)
|
||||||
|
result = False
|
||||||
|
break
|
||||||
log_test(OK if result else FAILED, '%s (%d ms)', test.name, timer.milliseconds())
|
log_test(OK if result else FAILED, '%s (%d ms)', test.name, timer.milliseconds())
|
||||||
return result
|
return result
|
||||||
|
|
||||||
|
@ -118,9 +125,6 @@ def do_the_tests(args):
|
||||||
failed = []
|
failed = []
|
||||||
log_test(SEP0, 'Running %d tests.', len(tests))
|
log_test(SEP0, 'Running %d tests.', len(tests))
|
||||||
for test in tests:
|
for test in tests:
|
||||||
if succeeded or failed:
|
|
||||||
logging.info('waiting for the server to be ready again')
|
|
||||||
time.sleep(7)
|
|
||||||
if run_test(test, args):
|
if run_test(test, args):
|
||||||
succeeded.append(test)
|
succeeded.append(test)
|
||||||
else:
|
else:
|
|
@ -4,20 +4,21 @@
|
||||||
# This work is licensed under the terms of the MIT license.
|
# This work is licensed under the terms of the MIT license.
|
||||||
# For a copy, see <https://opensource.org/licenses/MIT>.
|
# For a copy, see <https://opensource.org/licenses/MIT>.
|
||||||
|
|
||||||
import unit_tests
|
|
||||||
|
|
||||||
import logging
|
import logging
|
||||||
import random
|
import random
|
||||||
|
|
||||||
|
import unit_tests
|
||||||
|
|
||||||
import carla
|
import carla
|
||||||
|
|
||||||
from carla.client import CarlaClient
|
from carla.client import CarlaClient
|
||||||
from carla.settings import CarlaSettings, Camera
|
from carla.sensor import Camera, Image
|
||||||
|
from carla.settings import CarlaSettings
|
||||||
from carla.util import make_connection
|
from carla.util import make_connection
|
||||||
|
|
||||||
|
|
||||||
class _BasicTestBase(unit_tests.CarlaServerTest):
|
class _BasicTestBase(unit_tests.CarlaServerTest):
|
||||||
def run_carla_client(self, carla_settings, number_of_episodes, number_of_frames, use_ai_control=None):
|
def run_carla_client(self, carla_settings, number_of_episodes, number_of_frames, use_autopilot_control=None):
|
||||||
with make_connection(CarlaClient, self.args.host, self.args.port, timeout=15) as client:
|
with make_connection(CarlaClient, self.args.host, self.args.port, timeout=15) as client:
|
||||||
logging.info('CarlaClient connected, running %d episodes', number_of_episodes)
|
logging.info('CarlaClient connected, running %d episodes', number_of_episodes)
|
||||||
for _ in range(0, number_of_episodes):
|
for _ in range(0, number_of_episodes):
|
||||||
|
@ -25,7 +26,7 @@ class _BasicTestBase(unit_tests.CarlaServerTest):
|
||||||
carla_settings.randomize_weather()
|
carla_settings.randomize_weather()
|
||||||
logging.debug('sending CarlaSettings:\n%s', carla_settings)
|
logging.debug('sending CarlaSettings:\n%s', carla_settings)
|
||||||
logging.info('new episode requested')
|
logging.info('new episode requested')
|
||||||
scene = client.request_new_episode(carla_settings)
|
scene = client.load_settings(carla_settings)
|
||||||
number_of_player_starts = len(scene.player_start_spots)
|
number_of_player_starts = len(scene.player_start_spots)
|
||||||
player_start = random.randint(0, max(0, number_of_player_starts - 1))
|
player_start = random.randint(0, max(0, number_of_player_starts - 1))
|
||||||
logging.info(
|
logging.info(
|
||||||
|
@ -34,20 +35,21 @@ class _BasicTestBase(unit_tests.CarlaServerTest):
|
||||||
number_of_player_starts,
|
number_of_player_starts,
|
||||||
number_of_frames)
|
number_of_frames)
|
||||||
client.start_episode(player_start)
|
client.start_episode(player_start)
|
||||||
if use_ai_control is None:
|
if use_autopilot_control is None:
|
||||||
use_ai_control = (random.random() < 0.5)
|
use_autopilot_control = (random.random() < 0.5)
|
||||||
reverse = (random.random() < 0.2)
|
reverse = (random.random() < 0.2)
|
||||||
for _ in range(0, number_of_frames):
|
for _ in range(0, number_of_frames):
|
||||||
logging.debug('reading measurements...')
|
logging.debug('reading measurements...')
|
||||||
measurements, images = client.read_measurements()
|
measurements, sensor_data = client.read_data()
|
||||||
|
images = [x for x in sensor_data.values() if isinstance(x, Image)]
|
||||||
number_of_agents = len(measurements.non_player_agents)
|
number_of_agents = len(measurements.non_player_agents)
|
||||||
logging.debug('received data of %d agents', number_of_agents)
|
logging.debug('received data of %d agents', number_of_agents)
|
||||||
logging.debug('received %d images', len(images))
|
logging.debug('received %d images', len(images))
|
||||||
if len(images) != len(carla_settings._cameras):
|
if len(images) != len(carla_settings._cameras):
|
||||||
raise RuntimeError('received %d images, expected %d' % (len(images), len(carla_settings._cameras)))
|
raise RuntimeError('received %d images, expected %d' % (len(images), len(carla_settings._cameras)))
|
||||||
logging.debug('sending control...')
|
logging.debug('sending control...')
|
||||||
control = measurements.player_measurements.ai_control
|
control = measurements.player_measurements.autopilot_control
|
||||||
if not use_ai_control:
|
if not use_autopilot_control:
|
||||||
control.steer = random.uniform(-1.0, 1.0)
|
control.steer = random.uniform(-1.0, 1.0)
|
||||||
control.throttle = 0.3
|
control.throttle = 0.3
|
||||||
control.hand_brake = False
|
control.hand_brake = False
|
||||||
|
@ -63,7 +65,7 @@ class _BasicTestBase(unit_tests.CarlaServerTest):
|
||||||
class UseCase(_BasicTestBase):
|
class UseCase(_BasicTestBase):
|
||||||
def run(self):
|
def run(self):
|
||||||
settings = CarlaSettings()
|
settings = CarlaSettings()
|
||||||
settings.add_camera(Camera('DefaultCamera'))
|
settings.add_sensor(Camera('DefaultCamera'))
|
||||||
self.run_carla_client(settings, 5, 200)
|
self.run_carla_client(settings, 5, 200)
|
||||||
|
|
||||||
|
|
||||||
|
@ -76,18 +78,18 @@ class NoCamera(_BasicTestBase):
|
||||||
class TwoCameras(_BasicTestBase):
|
class TwoCameras(_BasicTestBase):
|
||||||
def run(self):
|
def run(self):
|
||||||
settings = CarlaSettings()
|
settings = CarlaSettings()
|
||||||
settings.add_camera(Camera('DefaultCamera'))
|
settings.add_sensor(Camera('DefaultCamera'))
|
||||||
camera2 = Camera('Camera2')
|
camera2 = Camera('Camera2')
|
||||||
camera2.set(PostProcessing='Depth', CameraFOV=120)
|
camera2.set(PostProcessing='Depth', CameraFOV=120)
|
||||||
camera2.set_image_size(1924, 1028)
|
camera2.set_image_size(1924, 1028)
|
||||||
settings.add_camera(camera2)
|
settings.add_sensor(camera2)
|
||||||
self.run_carla_client(settings, 3, 100)
|
self.run_carla_client(settings, 3, 100)
|
||||||
|
|
||||||
|
|
||||||
class SynchronousMode(_BasicTestBase):
|
class SynchronousMode(_BasicTestBase):
|
||||||
def run(self):
|
def run(self):
|
||||||
settings = CarlaSettings(SynchronousMode=True)
|
settings = CarlaSettings(SynchronousMode=True)
|
||||||
settings.add_camera(Camera('DefaultCamera'))
|
settings.add_sensor(Camera('DefaultCamera'))
|
||||||
self.run_carla_client(settings, 3, 200)
|
self.run_carla_client(settings, 3, 200)
|
||||||
|
|
||||||
|
|
||||||
|
@ -99,12 +101,12 @@ class GetAgentsInfo(_BasicTestBase):
|
||||||
SendNonPlayerAgentsInfo=True,
|
SendNonPlayerAgentsInfo=True,
|
||||||
NumberOfVehicles=60,
|
NumberOfVehicles=60,
|
||||||
NumberOfPedestrians=90)
|
NumberOfPedestrians=90)
|
||||||
settings.add_camera(Camera('DefaultCamera'))
|
settings.add_sensor(Camera('DefaultCamera'))
|
||||||
self.run_carla_client(settings, 3, 100)
|
self.run_carla_client(settings, 3, 100)
|
||||||
|
|
||||||
|
|
||||||
class LongEpisode(_BasicTestBase):
|
class LongEpisode(_BasicTestBase):
|
||||||
def run(self):
|
def run(self):
|
||||||
settings = CarlaSettings()
|
settings = CarlaSettings()
|
||||||
settings.add_camera(Camera('DefaultCamera'))
|
settings.add_sensor(Camera('DefaultCamera'))
|
||||||
self.run_carla_client(settings, 1, 2000, use_ai_control=True)
|
self.run_carla_client(settings, 1, 2000, use_autopilot_control=True)
|
19
README.md
19
README.md
|
@ -16,6 +16,25 @@ environmental conditions.
|
||||||
For instructions on how to use and compile CARLA, check out
|
For instructions on how to use and compile CARLA, check out
|
||||||
[CARLA Documentation](http://carla.readthedocs.io).
|
[CARLA Documentation](http://carla.readthedocs.io).
|
||||||
|
|
||||||
|
News
|
||||||
|
----
|
||||||
|
|
||||||
|
- 28.11.2017 CARLA 0.7.0 released: [change log](https://github.com/carla-simulator/carla/blob/master/CHANGELOG.md#carla-070), [release](https://github.com/carla-simulator/carla/releases/tag/0.7.0).
|
||||||
|
- 15.11.2017 CARLA 0.6.0 released: [change log](https://github.com/carla-simulator/carla/blob/master/CHANGELOG.md#carla-060), [release](https://github.com/carla-simulator/carla/releases/tag/0.6.0).
|
||||||
|
|
||||||
|
Roadmap
|
||||||
|
-------
|
||||||
|
|
||||||
|
We are continuously working on improving CARLA, and we appreciate contributions
|
||||||
|
from the community. Our most immediate goals are:
|
||||||
|
|
||||||
|
- Releasing the methods evaluated in the CARLA paper
|
||||||
|
- Adding a LiDAR sensor
|
||||||
|
- Allowing for flexible and user-friendly import and editing of maps
|
||||||
|
- Allowing the users to control non-player characters (and therefore set up user-specified scenarios)
|
||||||
|
|
||||||
|
We will post a detailed roadmap and contribution guidelines soon - stay tuned!
|
||||||
|
|
||||||
Paper
|
Paper
|
||||||
-----
|
-----
|
||||||
|
|
||||||
|
|
29
Setup.sh
29
Setup.sh
|
@ -22,32 +22,12 @@ command -v clang++-3.9 >/dev/null 2>&1 || {
|
||||||
exit 1;
|
exit 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
# Update content.
|
||||||
|
./Update.sh
|
||||||
|
|
||||||
mkdir -p Util/Build
|
mkdir -p Util/Build
|
||||||
pushd Util/Build >/dev/null
|
pushd Util/Build >/dev/null
|
||||||
|
|
||||||
# ==============================================================================
|
|
||||||
# -- Download the content ------------------------------------------------------
|
|
||||||
# ==============================================================================
|
|
||||||
|
|
||||||
CONTENT_FOLDER=$SCRIPT_DIR/Unreal/CarlaUE4/Content
|
|
||||||
|
|
||||||
CONTENT_GDRIVE_ID=$(tac $SCRIPT_DIR/Util/ContentVersions.txt | egrep -m 1 . | rev | cut -d' ' -f1 | rev)
|
|
||||||
|
|
||||||
if [[ ! -d "$CONTENT_FOLDER/.git" ]]; then
|
|
||||||
if [[ -d "$CONTENT_FOLDER" ]]; then
|
|
||||||
echo "Backing up existing Content..."
|
|
||||||
mv -v "$CONTENT_FOLDER" "${CONTENT_FOLDER}_$(date +%Y%m%d%H%M%S)"
|
|
||||||
fi
|
|
||||||
mkdir -p $CONTENT_FOLDER
|
|
||||||
mkdir -p Content
|
|
||||||
../download_from_gdrive.py $CONTENT_GDRIVE_ID Content.tar.gz
|
|
||||||
tar -xvzf Content.tar.gz -C Content
|
|
||||||
rm Content.tar.gz
|
|
||||||
mv Content/* $CONTENT_FOLDER
|
|
||||||
else
|
|
||||||
echo "Using git version of 'Content', skipping download..."
|
|
||||||
fi
|
|
||||||
|
|
||||||
# ==============================================================================
|
# ==============================================================================
|
||||||
# -- Get and compile libc++ ----------------------------------------------------
|
# -- Get and compile libc++ ----------------------------------------------------
|
||||||
# ==============================================================================
|
# ==============================================================================
|
||||||
|
@ -175,7 +155,8 @@ popd >/dev/null
|
||||||
CARLA_SETTINGS_FILE="./Unreal/CarlaUE4/Config/CarlaSettings.ini"
|
CARLA_SETTINGS_FILE="./Unreal/CarlaUE4/Config/CarlaSettings.ini"
|
||||||
|
|
||||||
if [[ ! -f $CARLA_SETTINGS_FILE ]]; then
|
if [[ ! -f $CARLA_SETTINGS_FILE ]]; then
|
||||||
cp -v ./Docs/Example.CarlaSettings.ini $CARLA_SETTINGS_FILE
|
echo "Copying CarlaSettings.ini..."
|
||||||
|
sed -e 's/UseNetworking=true/UseNetworking=false/' ./Docs/Example.CarlaSettings.ini > $CARLA_SETTINGS_FILE
|
||||||
fi
|
fi
|
||||||
|
|
||||||
./Util/Protoc.sh
|
./Util/Protoc.sh
|
||||||
|
|
|
@ -18,7 +18,7 @@ PrecipitationType=Rain
|
||||||
PrecipitationAmount=0
|
PrecipitationAmount=0
|
||||||
PrecipitationAccumulation=0
|
PrecipitationAccumulation=0
|
||||||
bWind=False
|
bWind=False
|
||||||
WindIntensity=20
|
WindIntensity=40
|
||||||
WindAngle=0
|
WindAngle=0
|
||||||
bOverrideCameraPostProcessParameters=True
|
bOverrideCameraPostProcessParameters=True
|
||||||
CameraPostProcessParameters.AutoExposureMethod=Histogram
|
CameraPostProcessParameters.AutoExposureMethod=Histogram
|
||||||
|
@ -46,7 +46,7 @@ PrecipitationType=Rain
|
||||||
PrecipitationAmount=0
|
PrecipitationAmount=0
|
||||||
PrecipitationAccumulation=0
|
PrecipitationAccumulation=0
|
||||||
bWind=False
|
bWind=False
|
||||||
WindIntensity=20
|
WindIntensity=40
|
||||||
WindAngle=0
|
WindAngle=0
|
||||||
bOverrideCameraPostProcessParameters=True
|
bOverrideCameraPostProcessParameters=True
|
||||||
CameraPostProcessParameters.AutoExposureMethod=Histogram
|
CameraPostProcessParameters.AutoExposureMethod=Histogram
|
||||||
|
|
|
@ -158,7 +158,7 @@ PrecipitationType=Rain
|
||||||
PrecipitationAmount=40
|
PrecipitationAmount=40
|
||||||
PrecipitationAccumulation=50
|
PrecipitationAccumulation=50
|
||||||
bWind=False
|
bWind=False
|
||||||
WindIntensity=20
|
WindIntensity=40
|
||||||
WindAngle=0
|
WindAngle=0
|
||||||
bOverrideCameraPostProcessParameters=True
|
bOverrideCameraPostProcessParameters=True
|
||||||
CameraPostProcessParameters.AutoExposureMethod=Histogram
|
CameraPostProcessParameters.AutoExposureMethod=Histogram
|
||||||
|
@ -186,7 +186,7 @@ PrecipitationType=Rain
|
||||||
PrecipitationAmount=80
|
PrecipitationAmount=80
|
||||||
PrecipitationAccumulation=87.248
|
PrecipitationAccumulation=87.248
|
||||||
bWind=False
|
bWind=False
|
||||||
WindIntensity=20
|
WindIntensity=40
|
||||||
WindAngle=0
|
WindAngle=0
|
||||||
bOverrideCameraPostProcessParameters=True
|
bOverrideCameraPostProcessParameters=True
|
||||||
CameraPostProcessParameters.AutoExposureMethod=Histogram
|
CameraPostProcessParameters.AutoExposureMethod=Histogram
|
||||||
|
@ -333,19 +333,19 @@ CameraPostProcessParameters.AutoExposureBias=-3.5
|
||||||
|
|
||||||
[MidRainSunset]
|
[MidRainSunset]
|
||||||
SunPolarAngle=86
|
SunPolarAngle=86
|
||||||
SunAzimuthAngle=0.0
|
SunAzimuthAngle=0
|
||||||
SunBrightness=13.761
|
SunBrightness=12.381
|
||||||
SunDirectionalLightIntensity=12.587
|
SunDirectionalLightIntensity=5.714
|
||||||
SunDirectionalLightColor=(R=0.810000,G=0.347162,B=0.083003,A=1.000000)
|
SunDirectionalLightColor=(R=0.810000,G=0.347162,B=0.083003,A=1.000000)
|
||||||
SunIndirectLightIntensity=6
|
SunIndirectLightIntensity=6
|
||||||
CloudOpacity=44.037
|
CloudOpacity=17.143
|
||||||
HorizontFalloff=1.835
|
HorizontFalloff=1.835
|
||||||
ZenithColor=(R=0.360000,G=0.000000,B=0.025421,A=1.000000)
|
ZenithColor=(R=0.317708,G=0.208096,B=0.260868,A=1.000000)
|
||||||
HorizonColor=(R=1.000000,G=0.590000,B=0.000000,A=1.000000)
|
HorizonColor=(R=1.000000,G=0.590000,B=0.000000,A=1.000000)
|
||||||
CloudColor=(R=0.555000,G=0.290880,B=0.066600,A=1.000000)
|
CloudColor=(R=0.555000,G=0.290880,B=0.066600,A=1.000000)
|
||||||
OverallSkyColor=(R=1.000000,G=1.000000,B=1.000000,A=1.000000)
|
OverallSkyColor=(R=1.000000,G=1.000000,B=1.000000,A=1.000000)
|
||||||
SkyLightIntensity=7.339
|
SkyLightIntensity=6.667
|
||||||
SkyLightColor=(R=0.086250,G=0.159340,B=0.750000,A=0.000000)
|
SkyLightColor=(R=0.214844,G=0.273773,B=0.750000,A=0.000000)
|
||||||
bPrecipitation=True
|
bPrecipitation=True
|
||||||
PrecipitationType=Rain
|
PrecipitationType=Rain
|
||||||
PrecipitationAmount=37.156
|
PrecipitationAmount=37.156
|
||||||
|
@ -361,19 +361,19 @@ CameraPostProcessParameters.AutoExposureBias=-3.5
|
||||||
|
|
||||||
[HardRainSunset]
|
[HardRainSunset]
|
||||||
SunPolarAngle=86
|
SunPolarAngle=86
|
||||||
SunAzimuthAngle=0.0
|
SunAzimuthAngle=0
|
||||||
SunBrightness=13.761
|
SunBrightness=0.952
|
||||||
SunDirectionalLightIntensity=12.587
|
SunDirectionalLightIntensity=3.063
|
||||||
SunDirectionalLightColor=(R=0.810000,G=0.347162,B=0.083003,A=1.000000)
|
SunDirectionalLightColor=(R=0.810000,G=0.347162,B=0.083003,A=1.000000)
|
||||||
SunIndirectLightIntensity=6
|
SunIndirectLightIntensity=6
|
||||||
CloudOpacity=44.037
|
CloudOpacity=17.37
|
||||||
HorizontFalloff=1.835
|
HorizontFalloff=1.835
|
||||||
ZenithColor=(R=0.360000,G=0.000000,B=0.025421,A=1.000000)
|
ZenithColor=(R=0.307292,G=0.161669,B=0.123237,A=1.000000)
|
||||||
HorizonColor=(R=1.000000,G=0.590000,B=0.000000,A=1.000000)
|
HorizonColor=(R=0.453125,G=0.297809,B=0.228923,A=1.000000)
|
||||||
CloudColor=(R=0.555000,G=0.290880,B=0.066600,A=1.000000)
|
CloudColor=(R=0.416667,G=0.288257,B=0.189558,A=1.000000)
|
||||||
OverallSkyColor=(R=1.000000,G=1.000000,B=1.000000,A=1.000000)
|
OverallSkyColor=(R=1.000000,G=0.736403,B=0.487039,A=1.000000)
|
||||||
SkyLightIntensity=7.339
|
SkyLightIntensity=5.81
|
||||||
SkyLightColor=(R=0.086250,G=0.159340,B=0.750000,A=0.000000)
|
SkyLightColor=(R=0.500000,G=0.383356,B=0.250000,A=0.000000)
|
||||||
bPrecipitation=True
|
bPrecipitation=True
|
||||||
PrecipitationType=Rain
|
PrecipitationType=Rain
|
||||||
PrecipitationAmount=84.862
|
PrecipitationAmount=84.862
|
||||||
|
|
|
@ -3,7 +3,7 @@ ProjectID=675BF8694238308FA9368292CC440350
|
||||||
ProjectName=CARLA UE4
|
ProjectName=CARLA UE4
|
||||||
CompanyName=CVC
|
CompanyName=CVC
|
||||||
CopyrightNotice="Copyright (c) 2017 Computer Vision Center (CVC) at the Universitat Autonomade 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>."
|
CopyrightNotice="Copyright (c) 2017 Computer Vision Center (CVC) at the Universitat Autonomade 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>."
|
||||||
ProjectVersion=0.6.0
|
ProjectVersion=0.7.0
|
||||||
|
|
||||||
[/Script/UnrealEd.ProjectPackagingSettings]
|
[/Script/UnrealEd.ProjectPackagingSettings]
|
||||||
BuildConfiguration=PPBC_Development
|
BuildConfiguration=PPBC_Development
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
{
|
{
|
||||||
"FileVersion": 3,
|
"FileVersion": 3,
|
||||||
"Version": 1,
|
"Version": 1,
|
||||||
"VersionName": "0.6.0",
|
"VersionName": "0.7.0",
|
||||||
"FriendlyName": "CARLA",
|
"FriendlyName": "CARLA",
|
||||||
"Description": "",
|
"Description": "",
|
||||||
"Category": "Science",
|
"Category": "Science",
|
||||||
|
|
|
@ -195,6 +195,9 @@ void UCarlaSettings::LoadSettings()
|
||||||
}
|
}
|
||||||
// Override settings from command-line.
|
// Override settings from command-line.
|
||||||
{
|
{
|
||||||
|
if (FParse::Param(FCommandLine::Get(), TEXT("carla-server"))) {
|
||||||
|
bUseNetworking = true;
|
||||||
|
}
|
||||||
uint32 Value;
|
uint32 Value;
|
||||||
if (FParse::Value(FCommandLine::Get(), TEXT("-world-port="), Value) ||
|
if (FParse::Value(FCommandLine::Get(), TEXT("-world-port="), Value) ||
|
||||||
FParse::Value(FCommandLine::Get(), TEXT("-carla-world-port="), Value)) {
|
FParse::Value(FCommandLine::Get(), TEXT("-carla-world-port="), Value)) {
|
||||||
|
|
|
@ -73,7 +73,7 @@ public:
|
||||||
|
|
||||||
/** If active, wait for the client to connect and control the pawn. */
|
/** If active, wait for the client to connect and control the pawn. */
|
||||||
UPROPERTY(Category = "CARLA Server", VisibleAnywhere)
|
UPROPERTY(Category = "CARLA Server", VisibleAnywhere)
|
||||||
bool bUseNetworking = true;
|
bool bUseNetworking = false;
|
||||||
|
|
||||||
/** World port to listen for client connections. */
|
/** World port to listen for client connections. */
|
||||||
UPROPERTY(Category = "CARLA Server", VisibleAnywhere, meta = (EditCondition = bUseNetworking))
|
UPROPERTY(Category = "CARLA Server", VisibleAnywhere, meta = (EditCondition = bUseNetworking))
|
||||||
|
|
|
@ -0,0 +1,45 @@
|
||||||
|
#! /bin/bash
|
||||||
|
|
||||||
|
################################################################################
|
||||||
|
# Updates CARLA contents.
|
||||||
|
################################################################################
|
||||||
|
|
||||||
|
set -e
|
||||||
|
|
||||||
|
SCRIPT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
|
||||||
|
pushd "$SCRIPT_DIR" >/dev/null
|
||||||
|
|
||||||
|
CONTENT_FOLDER=$SCRIPT_DIR/Unreal/CarlaUE4/Content
|
||||||
|
|
||||||
|
CONTENT_GDRIVE_ID=$(tac $SCRIPT_DIR/Util/ContentVersions.txt | egrep -m 1 . | rev | cut -d' ' -f1 | rev)
|
||||||
|
|
||||||
|
VERSION_FILE=${CONTENT_FOLDER}/.version
|
||||||
|
|
||||||
|
function download_content {
|
||||||
|
if [[ -d "$CONTENT_FOLDER" ]]; then
|
||||||
|
echo "Backing up existing Content..."
|
||||||
|
mv -v "$CONTENT_FOLDER" "${CONTENT_FOLDER}_$(date +%Y%m%d%H%M%S)"
|
||||||
|
fi
|
||||||
|
mkdir -p $CONTENT_FOLDER
|
||||||
|
mkdir -p Content
|
||||||
|
./Util/download_from_gdrive.py $CONTENT_GDRIVE_ID Content.tar.gz
|
||||||
|
tar -xvzf Content.tar.gz -C Content
|
||||||
|
rm Content.tar.gz
|
||||||
|
mv Content/* $CONTENT_FOLDER
|
||||||
|
echo "$CONTENT_GDRIVE_ID" > "$VERSION_FILE"
|
||||||
|
echo "Content updated successfully."
|
||||||
|
}
|
||||||
|
|
||||||
|
if [[ -d "$CONTENT_FOLDER/.git" ]]; then
|
||||||
|
echo "Using git version of 'Content', skipping update."
|
||||||
|
elif [[ -f "$CONTENT_FOLDER/.version" ]]; then
|
||||||
|
if [ "$CONTENT_GDRIVE_ID" == `cat $VERSION_FILE` ]; then
|
||||||
|
echo "Content is up-to-date."
|
||||||
|
else
|
||||||
|
download_content
|
||||||
|
fi
|
||||||
|
else
|
||||||
|
download_content
|
||||||
|
fi
|
||||||
|
|
||||||
|
popd >/dev/null
|
|
@ -126,7 +126,7 @@ namespace server {
|
||||||
player->set_collision_other(values.player_measurements.collision_other);
|
player->set_collision_other(values.player_measurements.collision_other);
|
||||||
player->set_intersection_otherlane(values.player_measurements.intersection_otherlane);
|
player->set_intersection_otherlane(values.player_measurements.intersection_otherlane);
|
||||||
player->set_intersection_offroad(values.player_measurements.intersection_offroad);
|
player->set_intersection_offroad(values.player_measurements.intersection_offroad);
|
||||||
Set(player->mutable_ai_control(), values.player_measurements.ai_control);
|
Set(player->mutable_autopilot_control(), values.player_measurements.ai_control);
|
||||||
// Non-player agents.
|
// Non-player agents.
|
||||||
message->clear_non_player_agents(); // we need to clear as we cache the message.
|
message->clear_non_player_agents(); // we need to clear as we cache the message.
|
||||||
for (auto &agent : agents(values)) {
|
for (auto &agent : agents(values)) {
|
||||||
|
|
|
@ -66,7 +66,7 @@ namespace server {
|
||||||
auto begin = buffer;
|
auto begin = buffer;
|
||||||
for (const auto &lidar_measurement : lidar_measurements) {
|
for (const auto &lidar_measurement : lidar_measurements) {
|
||||||
begin += WriteDoubleToBuffer(begin, lidar_measurement.horizontal_angle);
|
begin += WriteDoubleToBuffer(begin, lidar_measurement.horizontal_angle);
|
||||||
begin += WriteIntToBuffer(begin, 10); // type of lidar message
|
begin += WriteIntToBuffer(begin, 4); // type of lidar message
|
||||||
begin += WriteIntToBuffer(begin, lidar_measurement.channels_count);
|
begin += WriteIntToBuffer(begin, lidar_measurement.channels_count);
|
||||||
begin += WriteLidarMeasurementToBuffer(begin, lidar_measurement);
|
begin += WriteLidarMeasurementToBuffer(begin, lidar_measurement);
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,3 +6,4 @@
|
||||||
|
|
||||||
0.5.4: 0B2HFV-VuKn3PYUFFanlmZ2VMTW8
|
0.5.4: 0B2HFV-VuKn3PYUFFanlmZ2VMTW8
|
||||||
0.6.0: 1Gw8sw01hDEV4FtpHEZZwvS-6XN0jmaLT
|
0.6.0: 1Gw8sw01hDEV4FtpHEZZwvS-6XN0jmaLT
|
||||||
|
0.7.0: 11PKC_lG7L80L1ZxiMlzV17utU45UcRnT
|
||||||
|
|
|
@ -1,3 +1,3 @@
|
||||||
./bin
|
bin
|
||||||
./images
|
images
|
||||||
./converted_images
|
converted_images
|
||||||
|
|
|
@ -111,7 +111,7 @@ message Measurements {
|
||||||
float intersection_otherlane = 8;
|
float intersection_otherlane = 8;
|
||||||
float intersection_offroad = 9;
|
float intersection_offroad = 9;
|
||||||
|
|
||||||
Control ai_control = 10;
|
Control autopilot_control = 10;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32 platform_timestamp = 1;
|
uint32 platform_timestamp = 1;
|
||||||
|
|
|
@ -2,16 +2,14 @@
|
||||||
|
|
||||||
set PROTOBUF_SRC_DIR=Proto
|
set PROTOBUF_SRC_DIR=Proto
|
||||||
set PROTOBUF_CPP_OUT_DIR=CarlaServer/source/carla/server
|
set PROTOBUF_CPP_OUT_DIR=CarlaServer/source/carla/server
|
||||||
set PROTOBUF_PY_OUT_DIR0=../PythonClient/carla/protoc
|
set PROTOBUF_PY_OUT_DIR=../PythonClient/carla
|
||||||
set PROTOBUF_PY_OUT_DIR1=TestingClient/carla
|
|
||||||
set PROTO_BASENAME=carla_server
|
set PROTO_BASENAME=carla_server
|
||||||
|
|
||||||
if "%1" == "--clean" (
|
if "%1" == "--clean" (
|
||||||
rem Delete existing ones.
|
rem Delete existing ones.
|
||||||
rm -f %PROTOBUF_CPP_OUT_DIR%/carla_server.pb.h
|
rm -f %PROTOBUF_CPP_OUT_DIR%/carla_server.pb.h
|
||||||
rm -f %PROTOBUF_CPP_OUT_DIR%/carla_server.pb.cc
|
rm -f %PROTOBUF_CPP_OUT_DIR%/carla_server.pb.cc
|
||||||
rm -f %PROTOBUF_PY_OUT_DIR0%/carla_server_pb2.py
|
rm -f %PROTOBUF_PY_OUT_DIR%/carla_server_pb2.py
|
||||||
rm -f %PROTOBUF_PY_OUT_DIR1%/carla_server_pb2.py
|
|
||||||
goto end
|
goto end
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -24,8 +22,7 @@ if exist %PROTOC% (
|
||||||
%PROTOC% ^
|
%PROTOC% ^
|
||||||
-I=%PROTOBUF_SRC_DIR% ^
|
-I=%PROTOBUF_SRC_DIR% ^
|
||||||
--cpp_out=%PROTOBUF_CPP_OUT_DIR% ^
|
--cpp_out=%PROTOBUF_CPP_OUT_DIR% ^
|
||||||
--python_out=%PROTOBUF_PY_OUT_DIR0% ^
|
--python_out=%PROTOBUF_PY_OUT_DIR% ^
|
||||||
--python_out=%PROTOBUF_PY_OUT_DIR1% ^
|
|
||||||
%PROTOBUF_SRC_DIR%/%PROTO_BASENAME%.proto
|
%PROTOBUF_SRC_DIR%/%PROTO_BASENAME%.proto
|
||||||
|
|
||||||
echo done.
|
echo done.
|
||||||
|
|
|
@ -7,15 +7,13 @@ pushd "$SCRIPT_DIR" >/dev/null
|
||||||
|
|
||||||
PROTOBUF_SRC_DIR=Proto
|
PROTOBUF_SRC_DIR=Proto
|
||||||
PROTOBUF_CPP_OUT_DIR=CarlaServer/source/carla/server
|
PROTOBUF_CPP_OUT_DIR=CarlaServer/source/carla/server
|
||||||
PROTOBUF_PY_OUT_DIR0=../PythonClient/carla/protoc
|
PROTOBUF_PY_OUT_DIR=../PythonClient/carla
|
||||||
PROTOBUF_PY_OUT_DIR1=TestingClient/carla
|
|
||||||
PROTO_BASENAME=carla_server
|
PROTO_BASENAME=carla_server
|
||||||
|
|
||||||
if [ "$1" == "--clean" ]; then
|
if [ "$1" == "--clean" ]; then
|
||||||
# Delete existing ones.
|
# Delete existing ones.
|
||||||
rm -f ${PROTOBUF_CPP_OUT_DIR}/*.pb.h ${PROTOBUF_CPP_OUT_DIR}/*.pb.cc
|
rm -f ${PROTOBUF_CPP_OUT_DIR}/*.pb.h ${PROTOBUF_CPP_OUT_DIR}/*.pb.cc
|
||||||
rm -f ${PROTOBUF_PY_OUT_DIR0}/*_pb2.py
|
rm -f ${PROTOBUF_PY_OUT_DIR}/*_pb2.py
|
||||||
rm -f ${PROTOBUF_PY_OUT_DIR1}/*_pb2.py
|
|
||||||
exit 0
|
exit 0
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
@ -33,8 +31,7 @@ echo "Compiling ${PROTO_BASENAME}.proto..."
|
||||||
${PROTOC} \
|
${PROTOC} \
|
||||||
-I=${PROTOBUF_SRC_DIR} \
|
-I=${PROTOBUF_SRC_DIR} \
|
||||||
--cpp_out=${PROTOBUF_CPP_OUT_DIR} \
|
--cpp_out=${PROTOBUF_CPP_OUT_DIR} \
|
||||||
--python_out=${PROTOBUF_PY_OUT_DIR0} \
|
--python_out=${PROTOBUF_PY_OUT_DIR} \
|
||||||
--python_out=${PROTOBUF_PY_OUT_DIR1} \
|
|
||||||
${PROTOBUF_SRC_DIR}/${PROTO_BASENAME}.proto
|
${PROTOBUF_SRC_DIR}/${PROTO_BASENAME}.proto
|
||||||
|
|
||||||
popd >/dev/null
|
popd >/dev/null
|
||||||
|
|
|
@ -1,12 +0,0 @@
|
||||||
CARLA Client for Testing
|
|
||||||
========================
|
|
||||||
|
|
||||||
Requires Python 3 and the protobuf module installed, saving images to disk
|
|
||||||
requires the PIL module too.
|
|
||||||
|
|
||||||
$ sudo apt-get install python3 python3-pip
|
|
||||||
$ sudo pip3 install protobuf
|
|
||||||
|
|
||||||
A sample Python script explaining how to use the client API is provided
|
|
||||||
|
|
||||||
$ ./client_example.py --help
|
|
|
@ -1,161 +0,0 @@
|
||||||
# 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>.
|
|
||||||
|
|
||||||
"""CARLA Client."""
|
|
||||||
|
|
||||||
import os
|
|
||||||
import struct
|
|
||||||
|
|
||||||
from contextlib import contextmanager
|
|
||||||
|
|
||||||
from . import tcp
|
|
||||||
from . import util
|
|
||||||
|
|
||||||
try:
|
|
||||||
from . import carla_server_pb2 as carla_protocol
|
|
||||||
except ImportError:
|
|
||||||
raise RuntimeError('cannot import "carla_server_pb2.py", run the protobuf compiler to generate this file')
|
|
||||||
|
|
||||||
|
|
||||||
@contextmanager
|
|
||||||
def make_carla_client(host, world_port, timeout=15):
|
|
||||||
with util.make_connection(CarlaClient, host, world_port, timeout) as client:
|
|
||||||
yield client
|
|
||||||
|
|
||||||
|
|
||||||
class CarlaClient(object):
|
|
||||||
def __init__(self, host, world_port, timeout=15):
|
|
||||||
self._world_client = tcp.TCPClient(host, world_port, timeout)
|
|
||||||
self._stream_client = tcp.TCPClient(host, world_port + 1, timeout)
|
|
||||||
self._control_client = tcp.TCPClient(host, world_port + 2, timeout)
|
|
||||||
|
|
||||||
def connect(self):
|
|
||||||
self._world_client.connect()
|
|
||||||
|
|
||||||
def disconnect(self):
|
|
||||||
self._control_client.disconnect()
|
|
||||||
self._stream_client.disconnect()
|
|
||||||
self._world_client.disconnect()
|
|
||||||
|
|
||||||
def connected(self):
|
|
||||||
return self._world_client.connected()
|
|
||||||
|
|
||||||
def request_new_episode(self, carla_settings):
|
|
||||||
"""Request a new episode. carla_settings object must be convertible to
|
|
||||||
a str holding a CarlaSettings.ini.
|
|
||||||
|
|
||||||
Returns a protobuf object holding the scene description.
|
|
||||||
"""
|
|
||||||
# Disconnect agent clients.
|
|
||||||
self._stream_client.disconnect()
|
|
||||||
self._control_client.disconnect()
|
|
||||||
# Send new episode request.
|
|
||||||
pb_message = carla_protocol.RequestNewEpisode()
|
|
||||||
pb_message.ini_file = str(carla_settings)
|
|
||||||
self._world_client.write(pb_message.SerializeToString())
|
|
||||||
# Read scene description.
|
|
||||||
data = self._world_client.read()
|
|
||||||
if not data:
|
|
||||||
raise RuntimeError('failed to read data from server')
|
|
||||||
pb_message = carla_protocol.SceneDescription()
|
|
||||||
pb_message.ParseFromString(data)
|
|
||||||
if len(pb_message.player_start_spots) < 1:
|
|
||||||
raise RuntimeError("received 0 player start spots")
|
|
||||||
return pb_message
|
|
||||||
|
|
||||||
def start_episode(self, player_start_index):
|
|
||||||
"""Start the new episode at the player start given by the
|
|
||||||
player_start_index. The list of player starts is retrieved by
|
|
||||||
request_new_episode().
|
|
||||||
|
|
||||||
This function waits until the server answers with an EpisodeReady.
|
|
||||||
"""
|
|
||||||
pb_message = carla_protocol.EpisodeStart()
|
|
||||||
pb_message.player_start_spot_index = player_start_index
|
|
||||||
self._world_client.write(pb_message.SerializeToString())
|
|
||||||
# Wait for EpisodeReady.
|
|
||||||
data = self._world_client.read()
|
|
||||||
if not data:
|
|
||||||
raise RuntimeError('failed to read data from server')
|
|
||||||
pb_message = carla_protocol.EpisodeReady()
|
|
||||||
pb_message.ParseFromString(data)
|
|
||||||
if not pb_message.ready:
|
|
||||||
raise RuntimeError('cannot start episode: server failed to start episode')
|
|
||||||
# We can start the agent clients now.
|
|
||||||
self._stream_client.connect()
|
|
||||||
self._control_client.connect()
|
|
||||||
|
|
||||||
def read_measurements(self):
|
|
||||||
"""Read measuremnts of current frame. The episode must be started.
|
|
||||||
Return the protobuf object with the measurements followed by the raw
|
|
||||||
data with the images.
|
|
||||||
"""
|
|
||||||
# Read measurements.
|
|
||||||
data = self._stream_client.read()
|
|
||||||
if not data:
|
|
||||||
raise RuntimeError('failed to read data from server')
|
|
||||||
pb_message = carla_protocol.Measurements()
|
|
||||||
pb_message.ParseFromString(data)
|
|
||||||
# Read images.
|
|
||||||
images_raw_data = self._stream_client.read()
|
|
||||||
return pb_message, CarlaImage.parse_raw_data(images_raw_data)
|
|
||||||
|
|
||||||
def send_control(self, *args, **kwargs):
|
|
||||||
"""Send vehicle control for the current frame."""
|
|
||||||
if isinstance(args[0] if args else None, carla_protocol.Control):
|
|
||||||
pb_message = args[0]
|
|
||||||
else:
|
|
||||||
pb_message = carla_protocol.Control()
|
|
||||||
pb_message.steer = kwargs.get('steer', 0.0)
|
|
||||||
pb_message.throttle = kwargs.get('throttle', 0.0)
|
|
||||||
pb_message.brake = kwargs.get('brake', 0.0)
|
|
||||||
pb_message.hand_brake = kwargs.get('hand_brake', False)
|
|
||||||
pb_message.reverse = kwargs.get('reverse', False)
|
|
||||||
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):
|
|
||||||
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)
|
|
||||||
image.save(filename)
|
|
|
@ -1,62 +0,0 @@
|
||||||
# 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>.
|
|
||||||
|
|
||||||
"""Basic TCP client."""
|
|
||||||
|
|
||||||
import logging
|
|
||||||
import socket
|
|
||||||
import struct
|
|
||||||
|
|
||||||
|
|
||||||
class TCPClient(object):
|
|
||||||
def __init__(self, host, port, timeout):
|
|
||||||
self._host = host
|
|
||||||
self._port = port
|
|
||||||
self._timeout = timeout
|
|
||||||
self._socket = None
|
|
||||||
|
|
||||||
def connect(self):
|
|
||||||
self._socket = socket.create_connection(address=(self._host, self._port), timeout=self._timeout)
|
|
||||||
self._socket.settimeout(self._timeout)
|
|
||||||
self._log('connected')
|
|
||||||
|
|
||||||
def disconnect(self):
|
|
||||||
if self._socket is not None:
|
|
||||||
self._log('disconnecting...')
|
|
||||||
self._socket.close()
|
|
||||||
self._socket = None
|
|
||||||
|
|
||||||
def connected(self):
|
|
||||||
return self._socket is not None
|
|
||||||
|
|
||||||
def write(self, message):
|
|
||||||
if self._socket is None:
|
|
||||||
raise RuntimeError('%s:%s not connected' % (self._host, self._port))
|
|
||||||
header = struct.pack('<L', len(message))
|
|
||||||
self._socket.sendall(header + message)
|
|
||||||
|
|
||||||
def read(self):
|
|
||||||
header = self._read_n(4)
|
|
||||||
if not header:
|
|
||||||
raise RuntimeError('%s:%s connection closed' % (self._host, self._port))
|
|
||||||
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))
|
|
||||||
buf = bytes()
|
|
||||||
while length > 0:
|
|
||||||
data = self._socket.recv(length)
|
|
||||||
if not data:
|
|
||||||
raise RuntimeError('%s:%s connection closed' % (self._host, self._port))
|
|
||||||
buf += data
|
|
||||||
length -= len(data)
|
|
||||||
return buf
|
|
||||||
|
|
||||||
def _log(self, message, *args):
|
|
||||||
logging.debug('tcpclient %s:%d - ' + message, self._host, self._port, *args)
|
|
|
@ -1,215 +0,0 @@
|
||||||
#!/usr/bin/env python3
|
|
||||||
|
|
||||||
# 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>.
|
|
||||||
|
|
||||||
"""Basic CARLA client example."""
|
|
||||||
|
|
||||||
|
|
||||||
import argparse
|
|
||||||
import logging
|
|
||||||
import random
|
|
||||||
import shutil
|
|
||||||
import sys
|
|
||||||
import time
|
|
||||||
|
|
||||||
|
|
||||||
from carla.client import make_carla_client
|
|
||||||
from carla.console import CarlaClientConsole
|
|
||||||
from carla.settings import CarlaSettings, Camera
|
|
||||||
|
|
||||||
|
|
||||||
def run_carla_client(host, port, autopilot_on, save_images_to_disk, image_filename_format):
|
|
||||||
# Here we will run 3 episodes with 300 frames each.
|
|
||||||
number_of_episodes = 3
|
|
||||||
frames_per_episode = 300
|
|
||||||
|
|
||||||
# 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(host, port) as client:
|
|
||||||
print('CarlaClient connected')
|
|
||||||
|
|
||||||
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()
|
|
||||||
|
|
||||||
# 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)
|
|
||||||
|
|
||||||
# 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.
|
|
||||||
scene = client.request_new_episode(settings)
|
|
||||||
|
|
||||||
# Choose one player start at random.
|
|
||||||
number_of_player_starts = len(scene.player_start_spots)
|
|
||||||
player_start = random.randint(0, max(0, number_of_player_starts - 1))
|
|
||||||
|
|
||||||
# Notify the server that we want to start the episode at
|
|
||||||
# `player_start`. This function blocks until the server is ready to
|
|
||||||
# start the episode.
|
|
||||||
client.start_episode(player_start)
|
|
||||||
|
|
||||||
# Iterate every frame in the episode.
|
|
||||||
for frame in range(0, frames_per_episode):
|
|
||||||
|
|
||||||
# Read the measurements and images produced by the server this
|
|
||||||
# frame.
|
|
||||||
measurements, images = client.read_measurements()
|
|
||||||
|
|
||||||
# Print some of the measurements we received.
|
|
||||||
print_player_measurements(measurements.player_measurements)
|
|
||||||
|
|
||||||
# Save the images to disk if requested.
|
|
||||||
if save_images_to_disk:
|
|
||||||
for n, image in enumerate(images):
|
|
||||||
image.save_to_disk(image_filename_format.format(episode, n, frame))
|
|
||||||
|
|
||||||
# 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 autopilot_on:
|
|
||||||
|
|
||||||
client.send_control(
|
|
||||||
steer=random.uniform(-1.0, 1.0),
|
|
||||||
throttle=0.3,
|
|
||||||
brake=False,
|
|
||||||
hand_brake=False,
|
|
||||||
reverse=False)
|
|
||||||
|
|
||||||
else:
|
|
||||||
|
|
||||||
# Together with the measurements, the server has sent the
|
|
||||||
# control that the in-game AI would do this frame. We can
|
|
||||||
# enable autopilot by sending back this control to the
|
|
||||||
# server. Here we will also add some noise to the steer.
|
|
||||||
|
|
||||||
control = measurements.player_measurements.ai_control
|
|
||||||
control.steer += random.uniform(-0.1, 0.1)
|
|
||||||
client.send_control(control)
|
|
||||||
|
|
||||||
print('Done.')
|
|
||||||
return True
|
|
||||||
|
|
||||||
|
|
||||||
def print_player_measurements(player_measurements):
|
|
||||||
message = 'Vehicle at ({pos_x:.1f}, {pos_y:.1f}, {pos_z:.1f}) '
|
|
||||||
message += '{speed:.2f} km/h, '
|
|
||||||
message += '{other_lane:.0f}% other lane, {offroad:.0f}% off-road'
|
|
||||||
message = message.format(
|
|
||||||
pos_x=player_measurements.transform.location.x / 100, # cm -> m
|
|
||||||
pos_y=player_measurements.transform.location.y / 100,
|
|
||||||
pos_z=player_measurements.transform.location.z / 100,
|
|
||||||
speed=player_measurements.forward_speed,
|
|
||||||
other_lane=100 * player_measurements.intersection_otherlane,
|
|
||||||
offroad=100 * player_measurements.intersection_offroad)
|
|
||||||
empty_space = shutil.get_terminal_size((80, 20)).columns - len(message)
|
|
||||||
sys.stdout.write('\r' + message + empty_space * ' ')
|
|
||||||
sys.stdout.flush()
|
|
||||||
|
|
||||||
|
|
||||||
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='127.0.0.1',
|
|
||||||
help='IP of the host server (default: 127.0.0.1)')
|
|
||||||
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(
|
|
||||||
'-i', '--images-to-disk',
|
|
||||||
action='store_true',
|
|
||||||
help='save images to disk')
|
|
||||||
argparser.add_argument(
|
|
||||||
'-c', '--console',
|
|
||||||
action='store_true',
|
|
||||||
help='start the client console')
|
|
||||||
|
|
||||||
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.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
|
|
||||||
|
|
||||||
while True:
|
|
||||||
try:
|
|
||||||
|
|
||||||
end = run_carla_client(
|
|
||||||
host=args.host,
|
|
||||||
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')
|
|
||||||
|
|
||||||
if end:
|
|
||||||
return
|
|
||||||
|
|
||||||
except Exception as exception:
|
|
||||||
logging.error('exception: %s', exception)
|
|
||||||
time.sleep(1)
|
|
||||||
|
|
||||||
|
|
||||||
if __name__ == '__main__':
|
|
||||||
|
|
||||||
try:
|
|
||||||
main()
|
|
||||||
except KeyboardInterrupt:
|
|
||||||
print('\nCancelled by user. Bye!')
|
|
|
@ -9,12 +9,14 @@ pages:
|
||||||
- 'CARLA Settings': 'carla_settings.md'
|
- 'CARLA Settings': 'carla_settings.md'
|
||||||
- 'Measurements': 'measurements.md'
|
- 'Measurements': 'measurements.md'
|
||||||
- 'Cameras and sensors': 'cameras_and_sensors.md'
|
- 'Cameras and sensors': 'cameras_and_sensors.md'
|
||||||
|
- 'F.A.Q.': 'faq.md'
|
||||||
- 'Troubleshooting': 'troubleshooting.md'
|
- 'Troubleshooting': 'troubleshooting.md'
|
||||||
- Building from source:
|
- Building from source:
|
||||||
- 'How to build on Linux': 'how_to_build_on_linux.md'
|
- 'How to build on Linux': 'how_to_build_on_linux.md'
|
||||||
- 'How to build on Windows': 'how_to_build_on_windows.md'
|
- 'How to build on Windows': 'how_to_build_on_windows.md'
|
||||||
- 'How to add Automotive Materials': 'how_to_add_automotive_materials.md'
|
- 'How to add Automotive Materials': 'how_to_add_automotive_materials.md'
|
||||||
- Development:
|
- Development:
|
||||||
|
- 'Map customization': 'map_customization.md'
|
||||||
- 'How to add assets': 'how_to_add_assets.md'
|
- 'How to add assets': 'how_to_add_assets.md'
|
||||||
- 'CarlaServer documentation': 'carla_server.md'
|
- 'CarlaServer documentation': 'carla_server.md'
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue