Compare commits

...

56 Commits

Author SHA1 Message Date
Blyron 1e313b1cb5
Merge 79555a7c5d into 95728ec9a0 2024-10-18 16:32:03 +02:00
Blyron 95728ec9a0 Return sm names 2024-10-18 13:34:54 +02:00
Joel Moriana 359f723d20 fixes to ros2 native demo 2024-10-10 12:31:09 +02:00
Pablo Villanueva-Domingo 2b249b501c
Fix DVS sensor bug in manual control due to np.bool deprecation in newer numpy version (#8256)
* Update numpy version compatible for Python 3.8-3.11

* Update comments for generations of vehicles and pedestrians

* Update generation comments in all scripts which include the filter

* Update filter and printed message in vehicle_physics.py

* Add vertical offset to avoid collision when spawning

* Fix DVS sensor bug in manual control due to np.bool deprecation
2024-10-08 16:54:33 +02:00
Marcel Pi 65ef483f03 Fix package crash on Windows platforms. 2024-10-07 13:37:09 +02:00
PabloVD 2c7fcd5491 Add vertical offset to avoid collision when spawning 2024-10-03 11:44:21 +02:00
PabloVD 7f51f21ee5 Update filter and printed message in vehicle_physics.py 2024-10-03 11:44:21 +02:00
PabloVD 6ee7cf5bd1 Update generation comments in all scripts which include the filter 2024-10-03 11:44:21 +02:00
Marcel Pi 76dfbb1244 Remove SF_VULKAN_SM6 in Windows. 2024-10-01 18:23:37 +02:00
PabloVD d8045c98ff Update comments for generations of vehicles and pedestrians 2024-10-01 16:27:46 +02:00
PabloVD 13d3a3a341 Update numpy version compatible for Python 3.8-3.11 2024-10-01 16:27:46 +02:00
Blyron 31ab42c46e Write/Read doubles when writing/reading fvector 2024-10-01 12:02:42 +02:00
MarcelPiNacy-CVC fb62780b58
Improve package folder layout. (#8229)
* Improve package naming and build directory structure.

* Fix recastbuilder path.

* Remove co-simulation copy command + minor cleanup.
2024-09-30 19:08:27 +02:00
Blyron e5f7e79d09 Revert open type 2024-09-30 17:10:52 +02:00
Blyron b4b064beb3 Fix crash when spawn car while recording 2024-09-30 17:10:52 +02:00
MarcelPiNacy-CVC b8b1d3495f Fix Unreal CMake typo. Add missing dependency. 2024-09-27 12:05:54 +02:00
Blyron ad2a73f122 Remove not supported files 2024-09-27 11:44:39 +02:00
MarcelPiNacy-CVC 078029189b
Marcel/package development fix (#8189)
* Add workaround for a development package crash.

* Add Definitions.def file generation. Fix incorrect RecastBuilderPath. Enable option checking in CarlaTools.Build.cs.
2024-09-27 11:08:19 +02:00
MarcelPiNacy-CVC 6ee86983a4
Make toolchain paths absolute. (#8200) 2024-09-26 15:00:41 +02:00
MarcelPiNacy-CVC 4bbcfd2370
Add missing package target dependency. (#8193) 2024-09-25 16:58:09 +02:00
MarcelPiNacy-CVC ac66b3637e
Sync compiler with scikit-build-core. (#8190) 2024-09-25 14:44:32 +02:00
Blyron 880391b9a2
Update pull_request_template.md (#8186) 2024-09-25 09:45:23 +02:00
MattRoweEAIF 2de16a2144
added ue5 logo (#8181) 2024-09-23 13:59:05 +02:00
MarcelPiNacy-CVC 8f2fc098b4
Disable std::format unless ENABLE_STD_FORMAT is defined. (#8178) 2024-09-20 14:52:08 +02:00
MarcelPiNacy-CVC 1417cc6617
Sync ROS2 build type. (#8177) 2024-09-20 12:27:15 +02:00
MarcelPiNacy-CVC df514f94b3
Check for missing <format> header. (#8176) 2024-09-20 12:07:51 +02:00
MarcelPiNacy-CVC f8d95c2e8f
Add missing format include. (#8174) 2024-09-20 09:45:42 +02:00
MarcelPiNacy-CVC d26a3ede74
Fix incorrectly set ROS2 dependency tag. (#8172) 2024-09-19 21:15:52 +02:00
MarcelPiNacy-CVC 0bbd239b1a
CMake refactor (#8168)
* Add option VERBOSE_CONFIGURE + several other minor tweaks.

* Minor refactor and expose version option variables for ROS2 build.

* Remove unneeded option BUILD_PYTHON_API_WHEEL_PACKAGE.

* Make cmake_minimum_required uniform + fix potential linker error.

* Revert ROS2 configure.
2024-09-19 17:35:18 +02:00
MarcelPiNacy-CVC 4c1196db44
Fix linker error. (#8169) 2024-09-19 16:44:16 +02:00
MarcelPiNacy-CVC b143ef1a31
Remove unused code and change error handling in marcel/get-name. (#8166)
* Minor cleanup: Remove unused code and change error handling.

* Remove unlikely attribute.
2024-09-19 11:26:44 +02:00
MarcelPiNacy-CVC 73a716e24d
Add get_actor_name & get_actor_class_name. (#8165)
* Add initial GetUnrealName & GetUnrealClassName code.

* Remove snapshot-based code.

* Code cleanup.
2024-09-19 11:07:46 +02:00
MarcelPiNacy-CVC 001604da6b
Fix some Unreal and PythonAPI build errors. (#8162) 2024-09-19 10:12:27 +02:00
MarcelPiNacy-CVC 930fd57fbb
Remove Mobile shaders from package. (#8157) 2024-09-18 14:50:57 +02:00
MarcelPiNacy-CVC 8482279a33
Fix package dependency issues (carla-unreal-editor & RecastBuilder). (#8156) 2024-09-18 14:49:14 +02:00
MarcelPiNacy-CVC 10012e1939
Fix printer error in recorder. (#8155) 2024-09-18 11:18:53 +02:00
MarcelPiNacy-CVC e326742a67
Update VehiclePhysicsControl fields for UE5-Chaos (#8141)
* Add VehiclePhysicsControl progress...

* Update parameter names.

* Minor fixes.

* Update python initializer.

* More VehiclePhysicsControl changes.

* Fix minor UE errors.

* Update Vehicle and WheelPhysicsControl.

* Various fixes.

* Add missing linebreak.

* Fix indentation.

* Make FVehiclePhysicsControl UPROPERTYs uniform.

* Fix indentation again...

* Fix indentation, yet again...
2024-09-17 17:55:19 +02:00
joel-mb 0db777202c
Changed default vehicle generation to all (#8149) 2024-09-17 16:37:23 +02:00
MarcelPiNacy-CVC 7b491bc104
Fix Streetmap error (+ update gitignore) (#8145) 2024-09-16 17:13:36 +02:00
MarcelPiNacy-CVC 72974894e2
Add temporary recastbuilder package hack. (#8146) 2024-09-16 17:13:15 +02:00
MarcelPiNacy-CVC c6d9e65be7
Re-enable recast builder. (#8142) 2024-09-16 10:22:51 +02:00
Marcel Pi c00d44d2dc Multiple minor fixes related to build and docs. 2024-09-12 16:58:37 +02:00
meltycriss abdff1716f Add flag checker 2024-09-12 13:18:01 +02:00
meltycriss 2816f2752b Fix compilation error in win11 2024-09-12 13:18:01 +02:00
Blyron 9ffe13a9b4
Adding sensor lightning values and adding render variables to fix vsm issues (#8129) 2024-09-12 10:43:26 +02:00
MarcelPiNacy-CVC 239b73e849
Add temporary workaround for the memory blowup issue (#8098)
* Add temporary workaround for the memory blowup issue during save_to_disk.

* Add more fixes on the server side. Update gitignore to remove the _out folder in PythonAPI/examples.

* Enable clangd support. (#8104)

* Enable clangd support.

* Disable CMAKE_EXPORT_COMPILE_COMMANDS by default.

* Revert unwanted target rename.

* Solves the crash on server side

We still have an unhandled exception on client side, but it doesn't affect nominal behaviour.

* Revert "Merge branch 'marcel/leak-workaround' of https://github.com/carla-simulator/carla into marcel/leak-workaround"

This reverts commit 89c211e780, reversing
changes made to 908c203fca.

* Reapply "Merge branch 'marcel/leak-workaround' of https://github.com/carla-simulator/carla into marcel/leak-workaround"

This reverts commit fc2402efdb.

* Fixed crash on client side

Now it's both client and server crashes fixed. By removing posts but keeping async read/write, we make sure saving to disk is sequential but there's no error if it gets interrupted.

* Cleanup of Changes -- Preparation for PR

---------

Co-authored-by: Jorge Virgos <jorgevirgos.dev@gmail.com>
2024-09-06 13:56:50 +02:00
MarcelPiNacy-CVC 592eb46f43
Propagate CMake generator to scikit-build-core. (#8110) 2024-09-04 16:59:01 +02:00
MarcelPiNacy-CVC 908c203fca
Enable clangd support. (#8104)
* Enable clangd support.

* Disable CMAKE_EXPORT_COMPILE_COMMANDS by default.

* Revert unwanted target rename.
2024-09-03 13:19:20 +02:00
MattRoweEAIF aa9d95eb21
Update Ubuntu version README.md (#8045) 2024-08-09 12:07:39 +02:00
Aaron Samaniego 79555a7c5d Fix loop being in commandlet, loop on tiles should be out of them 2024-02-26 10:20:04 +01:00
JoseMartinez 286e7afd15 Adding WidgetEditorUtility uasset for running commandlet script. 2024-02-19 18:52:05 +01:00
JoseMartinez 5011f248da Commandlet iterates over all tiles of the map. 2024-02-19 18:47:27 +01:00
JoseMartinez 2566839481 Fix an issue getting the Worlf on the commandlet. 2024-02-19 16:43:38 +01:00
JoseMartinez dd5bffe8d7 Fixing commandlet argument values. 2024-02-19 16:34:48 +01:00
JoseMartinez b3fc04064d Updating commandlet file for world partition. 2024-02-19 15:45:12 +01:00
Aaron Samaniego fa7c187fb0 Add initial code for commandlet 2024-02-19 09:35:28 +01:00
159 changed files with 3364 additions and 82692 deletions

2
.clangd.in Normal file
View File

@ -0,0 +1,2 @@
CompileFlags:
CompilationDatabase: "@CMAKE_CURRENT_BINARY_DIR@"

View File

@ -2,10 +2,12 @@
Thanks for sending a pull request! Please make sure you click the link above to Thanks for sending a pull request! Please make sure you click the link above to
view the contribution guidelines, then fill out the blanks below. view the contribution guidelines, then fill out the blanks below.
Please, make sure if your contribution is for UE4 version of CARLA you merge against ue4-dev branch.
if it is for UE5 version of CARLA you merge agaisnt ue5-dev branch
Checklist: Checklist:
- [ ] Your branch is up-to-date with the `dev` branch and tested with latest changes - [ ] Your branch is up-to-date with the `ue4-dev/ue5-dev` branch and tested with latest changes
- [ ] Extended the README / documentation, if necessary - [ ] Extended the README / documentation, if necessary
- [ ] Code compiles correctly - [ ] Code compiles correctly
- [ ] All tests passing with `make check` (only Linux) - [ ] All tests passing with `make check` (only Linux)

3
.gitignore vendored
View File

@ -4,10 +4,13 @@
__pycache__/ __pycache__/
Build/ Build/
Install/
Doxygen/ Doxygen/
Dist/ Dist/
out/ out/
CMakeSettings.json CMakeSettings.json
.clangd
Help.md Help.md

View File

@ -33,18 +33,36 @@ if (WIN32)
endif () endif ()
endif () endif ()
if (CMAKE_TOOLCHAIN_FILE)
cmake_path (
ABSOLUTE_PATH
CMAKE_TOOLCHAIN_FILE
BASE_DIRECTORY
${CARLA_WORKSPACE_PATH}
NORMALIZE
OUTPUT_VARIABLE
TOOLCHAIN_FILE
)
set (CMAKE_TOOLCHAIN_FILE ${TOOLCHAIN_FILE})
endif ()
# ================================ # ================================
# Common Definitions # Common Definitions
# ================================ # ================================
if (WIN32) if (WIN32)
add_compile_definitions (_CRT_SECURE_NO_WARNINGS) add_compile_definitions (_CRT_SECURE_NO_WARNINGS)
check_cxx_compiler_flag (/utf-8 HAS_MSVC_UTF8)
if (HAS_MSVC_UTF8)
# @TODO This causes warnings with MASM. A better approach should be looked into.
add_compile_options (/utf-8)
endif ()
endif () endif ()
set (CARLA_COMMON_DEFINITIONS) set (CARLA_COMMON_DEFINITIONS)
foreach (FORMAT ${LIBCARLA_IMAGE_SUPPORTED_FORMATS}) foreach (FORMAT ${LIBCARLA_IMAGE_SUPPORTED_FORMATS})
carla_message ("Enabling CARLA image support for \"${FORMAT}\".") carla_message_verbose ("Enabling CARLA image support for \"${FORMAT}\".")
string (TOUPPER "${FORMAT}" FORMAT_UPPERCASE) string (TOUPPER "${FORMAT}" FORMAT_UPPERCASE)
list (APPEND CARLA_COMMON_DEFINITIONS LIBCARLA_IMAGE_SUPPORT_${FORMAT_UPPERCASE}=1) list (APPEND CARLA_COMMON_DEFINITIONS LIBCARLA_IMAGE_SUPPORT_${FORMAT_UPPERCASE}=1)
endforeach () endforeach ()
@ -56,6 +74,19 @@ if (WIN32)
list (APPEND CARLA_COMMON_DEFINITIONS _USE_MATH_DEFINES) list (APPEND CARLA_COMMON_DEFINITIONS _USE_MATH_DEFINES)
endif () endif ()
if (WIN32)
set (EXE_EXT .exe)
set (UE_SYSTEM_NAME Win64)
elseif (LINUX)
set (EXE_EXT)
set (UE_SYSTEM_NAME Linux)
elseif (APPLE)
set (EXE_EXT)
set (UE_SYSTEM_NAME Mac)
else ()
carla_error ("Unknown target system.")
endif ()
# ================================ # ================================
# Exception Definitions # Exception Definitions
# ================================ # ================================

View File

@ -12,29 +12,37 @@ include (FetchContent)
set (CARLA_DEPENDENCIES_PENDING) set (CARLA_DEPENDENCIES_PENDING)
macro (carla_git_dependency_add NAME TAG ARCHIVE_URL GIT_URL)
carla_message ("Cloning ${NAME}...")
FetchContent_Declare (
${NAME}
GIT_REPOSITORY ${GIT_URL}
GIT_TAG ${TAG}
GIT_SUBMODULES_RECURSE ON
GIT_SHALLOW ON
GIT_PROGRESS ON
OVERRIDE_FIND_PACKAGE
${ARGN}
)
list (APPEND CARLA_DEPENDENCIES_PENDING ${NAME})
endmacro ()
macro (carla_download_dependency_add NAME TAG ARCHIVE_URL GIT_URL)
carla_message ("Downloading ${NAME}...")
FetchContent_Declare (
${NAME}
URL ${ARCHIVE_URL}
OVERRIDE_FIND_PACKAGE
${ARGN}
)
list (APPEND CARLA_DEPENDENCIES_PENDING ${NAME})
endmacro ()
macro (carla_dependency_add NAME TAG ARCHIVE_URL GIT_URL) macro (carla_dependency_add NAME TAG ARCHIVE_URL GIT_URL)
if (PREFER_CLONE) if (PREFER_CLONE)
carla_message ("Cloning ${NAME}...") carla_git_dependency_add (${NAME} ${TAG} ${ARCHIVE_URL} ${GIT_URL} ${ARGN})
FetchContent_Declare (
${NAME}
GIT_REPOSITORY ${GIT_URL}
GIT_TAG ${TAG}
GIT_SUBMODULES_RECURSE ON
GIT_SHALLOW ON
GIT_PROGRESS ON
OVERRIDE_FIND_PACKAGE
${ARGN}
)
list (APPEND CARLA_DEPENDENCIES_PENDING ${NAME})
else () else ()
carla_message ("Downloading ${NAME}...") carla_download_dependency_add (${NAME} ${TAG} ${ARCHIVE_URL} ${GIT_URL} ${ARGN})
FetchContent_Declare (
${NAME}
URL ${ARCHIVE_URL}
OVERRIDE_FIND_PACKAGE
${ARGN}
)
list (APPEND CARLA_DEPENDENCIES_PENDING ${NAME})
endif () endif ()
endmacro () endmacro ()
@ -86,8 +94,9 @@ target_link_libraries (
libsqlite3 libsqlite3
) )
# ==== ZLIB ====
# ==== ZLIB ====
carla_dependency_option (ZLIB_BUILD_EXAMPLES OFF) carla_dependency_option (ZLIB_BUILD_EXAMPLES OFF)
carla_dependency_add ( carla_dependency_add (
zlib zlib
@ -109,8 +118,9 @@ endif ()
carla_dependency_option (ZLIB_INCLUDE_DIRS ${zlib_SOURCE_DIR} ${zlib_BINARY_DIR}) carla_dependency_option (ZLIB_INCLUDE_DIRS ${zlib_SOURCE_DIR} ${zlib_BINARY_DIR})
carla_dependency_option (ZLIB_LIBRARIES ${ZLIB_LIBRARY}) carla_dependency_option (ZLIB_LIBRARIES ${ZLIB_LIBRARY})
# ==== LIBPNG ====
# ==== LIBPNG ====
carla_dependency_option (PNG_SHARED OFF) carla_dependency_option (PNG_SHARED OFF)
carla_dependency_option (PNG_STATIC ON) carla_dependency_option (PNG_STATIC ON)
if (APPLE) if (APPLE)
@ -135,11 +145,6 @@ include_directories (
# ==== BOOST ==== # ==== BOOST ====
carla_dependency_option (BOOST_ENABLE_PYTHON ${BUILD_PYTHON_API})
carla_dependency_option (BOOST_ENABLE_MPI OFF)
carla_dependency_option (BOOST_LOCALE_WITH_ICU OFF)
carla_dependency_option (BOOST_LOCALE_WITH_ICONV OFF)
set ( set (
BOOST_INCLUDED_PROJECTS BOOST_INCLUDED_PROJECTS
asio asio
@ -147,11 +152,22 @@ set (
python python
date_time date_time
geometry geometry
gil
container container
variant2 variant2
gil
)
set (
BOOST_EXCLUDED_PROJECTS
# filesystem # <- Boost.GIL links with Boost.filesystem, so we can't remove the dependency yet.
) )
carla_dependency_option (BOOST_INCLUDE_LIBRARIES "${BOOST_INCLUDED_PROJECTS}") carla_dependency_option (BOOST_INCLUDE_LIBRARIES "${BOOST_INCLUDED_PROJECTS}")
carla_dependency_option (BOOST_EXCLUDE_LIBRARIES "${BOOST_EXCLUDED_PROJECTS}")
carla_dependency_option (BOOST_ENABLE_PYTHON ${BUILD_PYTHON_API})
carla_dependency_option (BOOST_ENABLE_MPI OFF)
carla_dependency_option (BOOST_LOCALE_WITH_ICU OFF)
carla_dependency_option (BOOST_LOCALE_WITH_ICONV OFF)
carla_dependency_option (BOOST_GIL_BUILD_EXAMPLES OFF)
carla_dependency_option (BOOST_GIL_BUILD_HEADER_TESTS OFF)
carla_dependency_add( carla_dependency_add(
boost boost
${CARLA_BOOST_TAG} ${CARLA_BOOST_TAG}
@ -159,8 +175,9 @@ carla_dependency_add(
https://github.com/boostorg/boost.git https://github.com/boostorg/boost.git
) )
# ==== EIGEN ====
# ==== EIGEN ====
carla_dependency_option (EIGEN_BUILD_PKGCONFIG OFF) carla_dependency_option (EIGEN_BUILD_PKGCONFIG OFF)
carla_dependency_option (BUILD_TESTING OFF) carla_dependency_option (BUILD_TESTING OFF)
carla_dependency_option (EIGEN_BUILD_DOC OFF) carla_dependency_option (EIGEN_BUILD_DOC OFF)
@ -171,8 +188,9 @@ carla_dependency_add (
https://gitlab.com/libeigen/eigen.git https://gitlab.com/libeigen/eigen.git
) )
# ==== RPCLIB ====
# ==== RPCLIB ====
carla_dependency_add ( carla_dependency_add (
rpclib rpclib
${CARLA_RPCLIB_TAG} ${CARLA_RPCLIB_TAG}
@ -180,9 +198,10 @@ carla_dependency_add (
https://github.com/carla-simulator/rpclib.git https://github.com/carla-simulator/rpclib.git
) )
# ==== RECAST ====
carla_dependency_option (RECASTNAVIGATION_BUILDER OFF)
# ==== RECAST ====
carla_dependency_option (RECASTNAVIGATION_BUILDER ON)
carla_dependency_add ( carla_dependency_add (
recastnavigation recastnavigation
${CARLA_RECAST_TAG} ${CARLA_RECAST_TAG}
@ -190,9 +209,10 @@ carla_dependency_add (
https://github.com/carla-simulator/recastnavigation.git https://github.com/carla-simulator/recastnavigation.git
) )
# ==== PROJ ====
if (ENABLE_OSM2ODR) if (ENABLE_OSM2ODR)
# ==== PROJ ====
carla_dependency_option (BUILD_TESTING OFF) carla_dependency_option (BUILD_TESTING OFF)
carla_dependency_option (ENABLE_TIFF OFF) carla_dependency_option (ENABLE_TIFF OFF)
carla_dependency_option (ENABLE_CURL OFF) carla_dependency_option (ENABLE_CURL OFF)
@ -204,9 +224,10 @@ if (ENABLE_OSM2ODR)
) )
endif () endif ()
# ==== XERCESC ====
if (ENABLE_OSM2ODR) if (ENABLE_OSM2ODR)
# ==== XERCESC ====
carla_dependency_add ( carla_dependency_add (
xercesc xercesc
${CARLA_XERCESC_TAG} ${CARLA_XERCESC_TAG}
@ -215,20 +236,18 @@ if (ENABLE_OSM2ODR)
) )
endif () endif ()
# ==== LUNASVG ====
if (BUILD_OSM_WORLD_RENDERER) if (BUILD_OSM_WORLD_RENDERER)
# ==== LUNASVG ====
carla_dependency_add ( carla_dependency_add (
lunasvg lunasvg
${CARLA_LUNASVG_TAG} ${CARLA_LUNASVG_TAG}
https://github.com/sammycage/lunasvg/archive/refs/tags/${CARLA_LUNASVG_TAG}.zip https://github.com/sammycage/lunasvg/archive/refs/tags/${CARLA_LUNASVG_TAG}.zip
https://github.com/sammycage/lunasvg.git https://github.com/sammycage/lunasvg.git
) )
endif ()
# ==== LIBOSMSCOUT ==== # ==== LIBOSMSCOUT ====
if (BUILD_OSM_WORLD_RENDERER)
carla_dependency_add ( carla_dependency_add (
libosmscout libosmscout
${CARLA_LIBOSMSCOUT_TAG} ${CARLA_LIBOSMSCOUT_TAG}
@ -237,9 +256,10 @@ if (BUILD_OSM_WORLD_RENDERER)
) )
endif () endif ()
# ==== STREETMAP ====
if (BUILD_CARLA_UNREAL) if (BUILD_CARLA_UNREAL)
# ==== STREETMAP ====
carla_dependency_add ( carla_dependency_add (
StreetMap StreetMap
${CARLA_STREETMAP_TAG} ${CARLA_STREETMAP_TAG}

View File

@ -104,12 +104,6 @@ carla_option (
OFF OFF
) )
carla_option (
BUILD_PYTHON_API_WHEEL_PACKAGE
"Whether to build the CARLA python API wheel package."
ON
)
carla_option ( carla_option (
ENABLE_PEP517 ENABLE_PEP517
"Whether to use PEP 517." "Whether to use PEP 517."
@ -146,6 +140,12 @@ carla_string_option (
/usr/bin/gcc-12 /usr/bin/gcc-12
) )
carla_option (
VERBOSE_CONFIGURE
"Whether to emit extra messages during CMake configure."
OFF
)
# ================================ # ================================
@ -198,18 +198,14 @@ carla_string_option (
"${CARLA_UNREAL_RHI_DEFAULT}" "${CARLA_UNREAL_RHI_DEFAULT}"
) )
if (${BUILD_CARLA_UNREAL}) if (BUILD_CARLA_UNREAL)
if (${CARLA_HAS_UNREAL_ENGINE_PATH}) if (NOT ${CARLA_HAS_UNREAL_ENGINE_PATH})
carla_message ( carla_error (
"Carla UE project successfully added to build. (UE path: ${CARLA_UNREAL_ENGINE_PATH})" "Could not add UE project to build since the carla_option CARLA_UNREAL_ENGINE_PATH "
) "is not set to a valid path (\"${CARLA_UNREAL_ENGINE_PATH}\")."
else () "Please set it to point to the root path of your CARLA Unreal Engine installation."
carla_error ( )
"Could not add UE project to build since the carla_option CARLA_UNREAL_ENGINE_PATH " endif ()
"is not set to a valid path (\"${CARLA_UNREAL_ENGINE_PATH}\")."
"Please set it to point to the root path of your CARLA Unreal Engine installation."
)
endif ()
endif () endif ()
carla_string_option ( carla_string_option (
@ -380,7 +376,6 @@ carla_string_option (
${CARLA_LIBOSMSCOUT_VERSION} ${CARLA_LIBOSMSCOUT_VERSION}
) )
# ==== STREETMAP ==== # ==== STREETMAP ====
carla_string_option ( carla_string_option (
@ -394,3 +389,45 @@ carla_string_option (
"Target StreetMap git tag." "Target StreetMap git tag."
${CARLA_STREETMAP_VERSION} ${CARLA_STREETMAP_VERSION}
) )
# ==== FASTDDS ====
carla_string_option (
CARLA_FASTDDS_VERSION
"Target Fast-DDS version."
2.11.2
)
carla_string_option (
CARLA_FASTDDS_TAG
"Target Fast-DDS git tag."
${CARLA_FASTDDS_VERSION}
)
# ==== FASTCDR ====
carla_string_option (
CARLA_FASTCDR_VERSION
"Target Fast-CDR version."
1.1.x
)
carla_string_option (
CARLA_FASTCDR_TAG
"Target Fast-CDR git tag."
${CARLA_FASTCDR_VERSION}
)
# ==== FOONATHAN MEMORY VENDOR ====
carla_string_option (
CARLA_FOONATHAN_MEMORY_VENDOR_VERSION
"Target foonathan_memory_vendor version."
master
)
carla_string_option (
CARLA_FOONATHAN_MEMORY_VENDOR_TAG
"Target foonathan_memory_vendor git tag."
${CARLA_FOONATHAN_MEMORY_VENDOR_VERSION}
)

View File

@ -1,20 +1,15 @@
# Similar to configure_file, but also expands variables
# that are set at generate time, like generator expressions.
function (carla_two_step_configure_file DESTINATION SOURCE)
carla_message ("Configuring file ${DESTINATION}")
# Configure-time step; evaluate variables:
configure_file (${SOURCE} ${DESTINATION} @ONLY)
# Generate-time step; evaluate generator expressions:
file (GENERATE OUTPUT ${DESTINATION} INPUT ${DESTINATION})
endfunction ()
# message wrapper for normal messages. # message wrapper for normal messages.
function (carla_message) function (carla_message)
message (STATUS "CARLA: " ${ARGN}) message (STATUS "CARLA: " ${ARGN})
endfunction () endfunction ()
# message wrapper for normal messages.
function (carla_message_verbose)
if (VERBOSE_CONFIGURE)
message (STATUS "CARLA: " ${ARGN})
endif ()
endfunction ()
# message() wrapper for warnings. # message() wrapper for warnings.
@ -39,7 +34,7 @@ endfunction ()
macro (carla_option NAME DESCRIPTION VALUE) macro (carla_option NAME DESCRIPTION VALUE)
option (${NAME} ${DESCRIPTION} ${VALUE}) option (${NAME} ${DESCRIPTION} ${VALUE})
carla_message ("(option) ${NAME} : ${VALUE}") carla_message_verbose ("(option) ${NAME} : ${${NAME}}")
get_property (DOCS GLOBAL PROPERTY CARLA_OPTION_DOCS) get_property (DOCS GLOBAL PROPERTY CARLA_OPTION_DOCS)
string ( string (
APPEND APPEND
@ -55,7 +50,7 @@ endmacro ()
macro (carla_string_option NAME DESCRIPTION VALUE) macro (carla_string_option NAME DESCRIPTION VALUE)
set (${NAME} "${VALUE}") set (${NAME} "${VALUE}")
carla_message ("(option) ${NAME} : \"${VALUE}\"") carla_message_verbose ("(option) ${NAME} : \"${${NAME}}\"")
get_property (DOCS GLOBAL PROPERTY CARLA_OPTION_DOCS) get_property (DOCS GLOBAL PROPERTY CARLA_OPTION_DOCS)
string ( string (
APPEND APPEND
@ -69,6 +64,18 @@ endmacro ()
# Similar to configure_file, but also expands variables
# that are set at generate time, like generator expressions.
function (carla_two_step_configure_file DESTINATION SOURCE)
carla_message_verbose ("Configuring file ${DESTINATION}")
# Configure-time step; evaluate variables:
configure_file (${SOURCE} ${DESTINATION} @ONLY)
# Generate-time step; evaluate generator expressions:
file (GENERATE OUTPUT ${DESTINATION} INPUT ${DESTINATION})
endfunction ()
# If, for some reason, CARLA is configured with CMake<3.5, this is necessary: # If, for some reason, CARLA is configured with CMake<3.5, this is necessary:
if (${CMAKE_VERSION} VERSION_LESS 3.5) if (${CMAKE_VERSION} VERSION_LESS 3.5)
include (CMakeParseArguments) include (CMakeParseArguments)
@ -139,6 +146,34 @@ endfunction ()
if (VERBOSE_CONFIGURE)
macro (carla_print_cmake_variable NAME)
carla_message ("${NAME}: \'${${NAME}}\'")
endmacro ()
carla_print_cmake_variable (CMAKE_C_COMPILER)
carla_print_cmake_variable (CMAKE_CXX_COMPILER)
carla_print_cmake_variable (CMAKE_ASM_COMPILER)
carla_print_cmake_variable (CMAKE_AR)
carla_print_cmake_variable (CMAKE_C_COMPILER_AR)
carla_print_cmake_variable (CMAKE_CXX_COMPILER_AR)
carla_print_cmake_variable (CMAKE_OBJCOPY)
carla_print_cmake_variable (CMAKE_ADDR2LINE)
carla_print_cmake_variable (CMAKE_C_COMPILER_RANLIB)
carla_print_cmake_variable (CMAKE_CXX_COMPILER_RANLIB)
carla_print_cmake_variable (CMAKE_LINKER)
carla_print_cmake_variable (CMAKE_NM)
carla_print_cmake_variable (CMAKE_OBJDUMP)
carla_print_cmake_variable (CMAKE_RANLIB)
carla_print_cmake_variable (CMAKE_READELF)
carla_print_cmake_variable (CMAKE_STRIP)
carla_print_cmake_variable (COVERAGE_COMMAND)
carla_print_cmake_variable (CMAKE_CXX_STANDARD_LIBRARIES)
carla_print_cmake_variable (CMAKE_CXX_STANDARD_INCLUDE_DIRECTORIES)
endif ()
carla_add_target_docs ( carla_add_target_docs (
NAME clean NAME clean
TYPE Builtin TYPE Builtin

View File

@ -8,9 +8,14 @@
]] ]]
set (
CARLA_CMAKE_MINIMUM_REQUIRED_VERSION
3.27.2
)
cmake_minimum_required ( cmake_minimum_required (
VERSION VERSION
3.27.2 ${CARLA_CMAKE_MINIMUM_REQUIRED_VERSION}
) )
cmake_policy (SET CMP0097 NEW) cmake_policy (SET CMP0097 NEW)
@ -18,6 +23,7 @@ cmake_policy (SET CMP0091 NEW)
cmake_policy (SET CMP0074 NEW) cmake_policy (SET CMP0074 NEW)
cmake_policy (SET CMP0077 NEW) cmake_policy (SET CMP0077 NEW)
cmake_policy (SET CMP0117 NEW) cmake_policy (SET CMP0117 NEW)
if (${CMAKE_MINOR_VERSION} GREATER_EQUAL 24) if (${CMAKE_MINOR_VERSION} GREATER_EQUAL 24)
cmake_policy (SET CMP0135 NEW) cmake_policy (SET CMP0135 NEW)
endif () endif ()
@ -38,7 +44,7 @@ project (
LANGUAGES LANGUAGES
C C
CXX CXX
ASM # This is required by some dependencies, such as LibPNG. ASM
DESCRIPTION DESCRIPTION
"Open-source simulator for autonomous driving research." "Open-source simulator for autonomous driving research."
HOMEPAGE_URL HOMEPAGE_URL
@ -50,9 +56,14 @@ set (
${CMAKE_CURRENT_SOURCE_DIR} ${CMAKE_CURRENT_SOURCE_DIR}
) )
set (
CARLA_BUILD_PATH
${CMAKE_BINARY_DIR}
)
set ( set (
CARLA_PACKAGE_PATH CARLA_PACKAGE_PATH
${CMAKE_BINARY_DIR}/Package ${CARLA_BUILD_PATH}/Package
) )
set ( set (
@ -121,3 +132,10 @@ file (
${CMAKE_CURRENT_BINARY_DIR}/Help.md ${CMAKE_CURRENT_BINARY_DIR}/Help.md
${CARLA_CMAKE_HELP_MESSAGE} ${CARLA_CMAKE_HELP_MESSAGE}
) )
if (CMAKE_EXPORT_COMPILE_COMMANDS)
configure_file (
${CARLA_WORKSPACE_PATH}/.clangd.in
${CARLA_WORKSPACE_PATH}/.clangd
)
endif ()

View File

@ -1,5 +1,11 @@
{ {
"version": 8, "version": 4,
"cmakeMinimumRequired":
{
"major": 3,
"minor": 27,
"patch": 2
},
"configurePresets": "configurePresets":
[ [
{ {
@ -14,7 +20,7 @@
"inherits": "Common", "inherits": "Common",
"cacheVariables": "cacheVariables":
{ {
"CMAKE_TOOLCHAIN_FILE": "CMake/LinuxToolchain.cmake" "CMAKE_TOOLCHAIN_FILE": "${sourceDir}/CMake/LinuxToolchain.cmake"
}, },
"hidden": true "hidden": true
}, },

Binary file not shown.

Before

Width:  |  Height:  |  Size: 57 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 143 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 409 KiB

View File

@ -1,49 +0,0 @@
PARSFILE
#FullDataName Vehicle: Sprung Mass`Lincoln 2020`CARLA
#VehCode Rigid sprung mass
#RingCtrl0 0
#CheckBox2 0
X_LENGTH 2860
Y_LENGTH 1500
iaxle 2
iside 1
LX_AXLE 2860
LX_CG_SU 1471
M_SU 2404
IXX_SU 536.6
IYY_SU 1536.7
IZZ_SU 1536.7
IXZ_SU 0
*RX 0.472
*RY 0.800
*RZ 0.800
Y_CG_SU 0
H_CG_SU 359
IXY_SU 0
IYZ_SU 0
Z_LENGTH 1300
Y_LENGTH 1800
*HWC_LF 359
*HWC_RF 359
*HWC_LR 359
*HWC_RR 359
H_WC 359
iside 2
H_WC 359
iaxle 1
iside 1
H_WC 359
iside 2
H_WC 359
iaxle 2
iside 1
LOG_ENTRY Used Dataset: Vehicle: Sprung Mass; { CARLA } Lincoln 2020
#Library : Vehicle: Sprung Mass
#DataSet : Lincoln 2020
#Category: CARLA
#FileID : SprMass_d80b7dcb-e4b1-4456-9d41-6fc41b8cd79a
#Product : CarSim 2020.0
#VehCode Rigid sprung mass
END

View File

@ -1,7 +0,0 @@
venv
# Vissim files
*.results
*.inp0
*.layx
*.err

View File

@ -1,43 +0,0 @@
{
"100": [
"vehicle.audi.a2",
"vehicle.audi.tt",
"vehicle.bmw.grandtourer",
"vehicle.citroen.c3",
"vehicle.jeep.wrangler_rubicon",
"vehicle.lincoln.mkz_2017",
"vehicle.mercedes.coupe",
"vehicle.mini.cooper_s",
"vehicle.ford.mustang",
"vehicle.nissan.micra",
"vehicle.nissan.patrol",
"vehicle.seat.leon",
"vehicle.volkswagen.t2",
"vehicle.toyota.prius",
"vehicle.tesla.model3",
"vehicle.audi.etron"
],
"200": [
"vehicle.carlamotors.carlacola"
],
"300": [],
"400": [],
"510": [],
"520": [],
"610": [
"vehicle.yamaha.yzf",
"vehicle.harley-davidson.low_rider",
"vehicle.kawasaki.ninja",
"vehicle.gazelle.omafiets",
"vehicle.diamondback.century",
"vehicle.bh.crossbike"
],
"620": [
"vehicle.yamaha.yzf",
"vehicle.harley-davidson.low_rider",
"vehicle.kawasaki.ninja",
"vehicle.gazelle.omafiets",
"vehicle.diamondback.century",
"vehicle.bh.crossbike"
]
}

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -1,234 +0,0 @@
#!/usr/bin/env python
# Copyright (c) 2020 Computer Vision Center (CVC) at the Universitat Autonoma de
# Barcelona (UAB).
#
# This work is licensed under the terms of the MIT license.
# For a copy, see <https://opensource.org/licenses/MIT>.
"""
Script to co-simulate CARLA and PTV-Vissim.
"""
# ==================================================================================================
# -- imports ---------------------------------------------------------------------------------------
# ==================================================================================================
import argparse
import json
import logging
import time
# ==================================================================================================
# -- find carla module -----------------------------------------------------------------------------
# ==================================================================================================
import glob
import os
import sys
try:
sys.path.append(
glob.glob('../../PythonAPI/carla/dist/carla-*%d.%d-%s.egg' %
(sys.version_info.major, sys.version_info.minor,
'win-amd64' if os.name == 'nt' else 'linux-x86_64'))[0])
except IndexError:
pass
# ==================================================================================================
# -- vissim integration imports --------------------------------------------------------------------
# ==================================================================================================
from vissim_integration.bridge_helper import BridgeHelper
from vissim_integration.carla_simulation import CarlaSimulation
from vissim_integration.vissim_simulation import PTVVissimSimulation
from vissim_integration.constants import INVALID_ACTOR_ID
# ==================================================================================================
# -- synchronization_loop --------------------------------------------------------------------------
# ==================================================================================================
class SimulationSynchronization(object):
"""
SimulationSynchronization class is responsible for the synchronization of ptv-vissim and carla
simulations.
"""
def __init__(self, vissim_simulation, carla_simulation, args):
self.args = args
self.vissim = vissim_simulation
self.carla = carla_simulation
# Mapped actor ids.
self.vissim2carla_ids = {} # Contains only actors controlled by vissim.
self.carla2vissim_ids = {} # Contains only actors controlled by carla.
BridgeHelper.blueprint_library = self.carla.world.get_blueprint_library()
dir_path = os.path.dirname(os.path.realpath(__file__))
with open(os.path.join(dir_path, 'data', 'vtypes.json')) as f:
BridgeHelper.vtypes = json.load(f)
# Configuring carla simulation in sync mode.
settings = self.carla.world.get_settings()
settings.synchronous_mode = True
settings.fixed_delta_seconds = args.step_length
self.carla.world.apply_settings(settings)
def tick(self):
"""
Tick to simulation synchronization
"""
# -------------------
# vissim-->carla sync
# -------------------
self.vissim.tick()
# Spawning vissim controlled vehicles in carla.
vissim_spawned_actors = self.vissim.spawned_vehicles - set(self.carla2vissim_ids.values())
for vissim_actor_id in vissim_spawned_actors:
vissim_actor = self.vissim.get_actor(vissim_actor_id)
carla_blueprint = BridgeHelper.get_carla_blueprint(vissim_actor)
if carla_blueprint is not None:
carla_transform = BridgeHelper.get_carla_transform(vissim_actor.get_transform())
carla_actor_id = self.carla.spawn_actor(carla_blueprint, carla_transform)
if carla_actor_id != INVALID_ACTOR_ID:
self.vissim2carla_ids[vissim_actor_id] = carla_actor_id
# Destroying vissim controlled vehicles in carla.
for vissim_actor_id in self.vissim.destroyed_vehicles:
if vissim_actor_id in self.vissim2carla_ids:
self.vissim.destroy_actor(self.vissim2carla_ids.pop(vissim_actor_id))
# Updating vissim controlled vehicles in carla.
for vissim_actor_id in self.vissim2carla_ids:
carla_actor_id = self.vissim2carla_ids[vissim_actor_id]
vissim_actor = self.vissim.get_actor(vissim_actor_id)
carla_actor = self.carla.get_actor(carla_actor_id)
carla_transform = BridgeHelper.get_carla_transform(vissim_actor.get_transform(),
carla_actor.bounding_box.extent)
carla_velocity = BridgeHelper.get_carla_velocity(vissim_actor.get_velocity())
self.carla.synchronize_vehicle(carla_actor_id, carla_transform, carla_velocity)
# -------------------
# carla-->vissim sync
# -------------------
self.carla.tick()
# Spawning carla controlled vehicles in vissim. This also takes into account carla vehicles
# that could not be spawned in vissim in previous time steps.
carla_spawned_actors = self.carla.spawned_actors - set(self.vissim2carla_ids.values())
carla_spawned_actors.update(
[c_id for c_id, v_id in self.carla2vissim_ids.items() if v_id == INVALID_ACTOR_ID])
for carla_actor_id in carla_spawned_actors:
carla_actor = self.carla.get_actor(carla_actor_id)
vissim_transform = BridgeHelper.get_vissim_transform(carla_actor.get_transform())
vissim_actor_id = self.vissim.spawn_actor(vissim_transform)
# Add the vissim_actor_id even if it was not possible to spawn it (INVALID_ACTOR_ID) to
# try to spawn it again in next time steps.
self.carla2vissim_ids[carla_actor_id] = vissim_actor_id
# Destroying carla controlled vehicles in vissim.
for carla_actor_id in self.carla.destroyed_actors:
if carla_actor_id in self.carla2vissim_ids:
self.vissim.destroy_actor(self.carla2vissim_ids.pop(carla_actor_id))
# Updating carla controlled vehicles in vissim.
for carla_actor_id in self.carla2vissim_ids:
vissim_actor_id = self.carla2vissim_ids[carla_actor_id]
if vissim_actor_id != INVALID_ACTOR_ID:
carla_actor = self.carla.get_actor(carla_actor_id)
vissim_transform = BridgeHelper.get_vissim_transform(
carla_actor.get_transform(), carla_actor.bounding_box.extent)
vissim_velocity = BridgeHelper.get_vissim_velocity(carla_actor.get_velocity())
self.vissim.synchronize_vehicle(vissim_actor_id, vissim_transform, vissim_velocity)
def close(self):
"""
Cleans synchronization.
"""
# Configuring carla simulation in async mode.
settings = self.carla.world.get_settings()
settings.synchronous_mode = False
settings.fixed_delta_seconds = None
self.carla.world.apply_settings(settings)
# Destroying synchronized actors.
for carla_actor_id in self.vissim2carla_ids.values():
self.carla.destroy_actor(carla_actor_id)
# Closing PTV-Vissim connection.
self.vissim.close()
def synchronization_loop(args):
"""
Entry point for vissim-carla co-simulation.
"""
carla_simulation = CarlaSimulation(args)
vissim_simulation = PTVVissimSimulation(args)
try:
synchronization = SimulationSynchronization(vissim_simulation, carla_simulation, args)
while True:
start = time.time()
synchronization.tick()
end = time.time()
elapsed = end - start
if elapsed < args.step_length:
time.sleep(args.step_length - elapsed)
except KeyboardInterrupt:
logging.info('Cancelled by user.')
finally:
logging.info('Cleaning synchronization')
synchronization.close()
# ==================================================================================================
# -- main ------------------------------------------------------------------------------------------
# ==================================================================================================
if __name__ == '__main__':
argparser = argparse.ArgumentParser(description=__doc__)
argparser.add_argument('vissim_network', type=str, help='vissim network file')
argparser.add_argument('--carla-host',
metavar='H',
default='127.0.0.1',
help='IP of the carla host server (default: 127.0.0.1)')
argparser.add_argument('--carla-port',
metavar='P',
default=2000,
type=int,
help='TCP port to listen to (default: 2000)')
argparser.add_argument('--vissim-version',
default=2020,
type=int,
help='ptv-vissim version (default: 2020)')
argparser.add_argument('--step-length',
default=0.05,
type=float,
help='set fixed delta seconds (default: 0.05s)')
argparser.add_argument('--simulator-vehicles',
default=1,
type=int,
help='number of simulator vehicles to be passed to vissim (default: 1)')
argparser.add_argument('--debug', action='store_true', help='enable debug messages')
arguments = argparser.parse_args()
if arguments.debug:
logging.basicConfig(format='%(levelname)s: %(message)s', level=logging.DEBUG)
else:
logging.basicConfig(format='%(levelname)s: %(message)s', level=logging.INFO)
synchronization_loop(arguments)

View File

@ -1,151 +0,0 @@
#!/usr/bin/env python
# Copyright (c) 2020 Computer Vision Center (CVC) at the Universitat Autonoma de
# Barcelona (UAB).
#
# This work is licensed under the terms of the MIT license.
# For a copy, see <https://opensource.org/licenses/MIT>.
""" This module provides a helper for the co-simulation between vissim and carla. """
# ==================================================================================================
# -- imports ---------------------------------------------------------------------------------------
# ==================================================================================================
import logging
import math
import random
import carla # pylint: disable=import-error
# ==================================================================================================
# -- Bridge helper (VISSIM <=> CARLA) --------------------------------------------------------------
# ==================================================================================================
class BridgeHelper(object):
"""
BridgeHelper provides methos to ease the co-simulation between vissim and carla.
"""
blueprint_library = []
vtypes = {}
@staticmethod
def get_carla_transform(in_vissim_transform, extent=None):
"""
Returns carla transform based on vissim transform.
"""
in_location = in_vissim_transform.location
in_rotation = in_vissim_transform.rotation
# From front-center-bumper to center (vissim reference system).
if extent is not None:
out_location = (in_location.x - math.cos(math.radians(in_rotation.yaw)) * extent.x,
in_location.y - math.sin(math.radians(in_rotation.yaw)) * extent.x,
in_location.z - math.sin(math.radians(in_rotation.pitch)) * extent.x)
else:
out_location = (in_location.x, in_location.y, in_location.z)
out_rotation = (in_rotation.pitch, in_rotation.yaw, in_rotation.roll)
# Transform to carla reference system (left-handed system).
out_transform = carla.Transform(
carla.Location(out_location[0], -out_location[1], out_location[2]),
carla.Rotation(out_rotation[0], -out_rotation[1], out_rotation[2]))
return out_transform
@staticmethod
def get_vissim_transform(in_carla_transform, extent=None):
"""
Returns vissim transform based on carla transform.
"""
in_location = in_carla_transform.location
in_rotation = in_carla_transform.rotation
# From center to front-center-bumper (carla reference system).
if extent is not None:
yaw = -1 * in_rotation.yaw
pitch = in_rotation.pitch
out_location = (in_location.x + math.cos(math.radians(yaw)) * extent.x,
in_location.y - math.sin(math.radians(yaw)) * extent.x,
in_location.z - math.sin(math.radians(pitch)) * extent.x)
else:
out_location = (in_location.x, in_location.y, in_location.z)
out_rotation = (in_rotation.pitch, in_rotation.yaw, in_rotation.roll)
# Transform to vissim reference system (right-handed system).
out_transform = carla.Transform(
carla.Location(out_location[0], -out_location[1], out_location[2]),
carla.Rotation(out_rotation[0], -out_rotation[1], out_rotation[2]))
return out_transform
@staticmethod
def _flip_y(in_vector):
"""
Flips y coordinate of the given vector.
"""
return carla.Vector3D(in_vector.x, -in_vector.y, in_vector.z)
@staticmethod
def get_carla_velocity(in_vissim_velocity):
"""
Returns carla velocity based on vissim velocity.
"""
return BridgeHelper._flip_y(in_vissim_velocity)
@staticmethod
def get_vissim_velocity(in_carla_velocity):
"""
Returns vissim velocity based on carla velocity.
"""
return BridgeHelper._flip_y(in_carla_velocity)
@staticmethod
def _get_recommended_carla_blueprint(vissim_actor):
"""
Returns an appropriate blueprint based on the given vissim actor.
"""
blueprint = BridgeHelper.blueprint_library.filter('vehicle.seat.leon')[0]
color = random.choice(blueprint.get_attribute('color').recommended_values)
blueprint.set_attribute('color', color)
return blueprint
@staticmethod
def get_carla_blueprint(vissim_actor):
"""
Returns an appropriate blueprint based on the received vissim actor.
"""
type_id = str(vissim_actor.type)
if type_id in BridgeHelper.vtypes:
candidates = BridgeHelper.vtypes[type_id]
if candidates:
blueprint_id = random.choice(candidates)
else:
logging.error(
'vissim type %s not supported. No vehicle will be spawned in carla', type_id)
return None
blueprint = BridgeHelper.blueprint_library.filter(blueprint_id)
if not blueprint:
logging.error(
'carla blueprint %s unknown. No vehicle will be spawned', blueprint_id)
return None
blueprint = blueprint[0]
if blueprint.has_attribute('color'):
color = random.choice(blueprint.get_attribute('color').recommended_values)
blueprint.set_attribute('color', color)
if blueprint.has_attribute('driver_id'):
driver_id = random.choice(blueprint.get_attribute('driver_id').recommended_values)
blueprint.set_attribute('driver_id', driver_id)
blueprint.set_attribute('role_name', 'vissim_driver')
return blueprint
else:
logging.error(
'vissim type %s unknown. No vehicle will be spawned in carla', type_id)
return None

View File

@ -1,114 +0,0 @@
#!/usr/bin/env python
# Copyright (c) 2020 Computer Vision Center (CVC) at the Universitat Autonoma de
# Barcelona (UAB).
#
# This work is licensed under the terms of the MIT license.
# For a copy, see <https://opensource.org/licenses/MIT>.
""" This module is responsible for the management of the carla simulation. """
# ==================================================================================================
# -- imports ---------------------------------------------------------------------------------------
# ==================================================================================================
import logging
import carla # pylint: disable=import-error
from .constants import INVALID_ACTOR_ID, CARLA_SPAWN_OFFSET_Z
# ==================================================================================================
# -- carla simulation ------------------------------------------------------------------------------
# ==================================================================================================
class CarlaSimulation(object):
"""
CarlaSimulation is responsible for the management of the carla simulation.
"""
def __init__(self, args):
self.args = args
host = args.carla_host
port = args.carla_port
self.client = carla.Client(host, port)
self.client.set_timeout(2.0)
self.world = self.client.get_world()
self.blueprint_library = self.world.get_blueprint_library()
# The following sets contain updated information for the current frame.
self._active_actors = set()
self.spawned_actors = set()
self.destroyed_actors = set()
def get_actor(self, actor_id):
"""
Accessor for carla actor.
"""
return self.world.get_actor(actor_id)
def spawn_actor(self, blueprint, transform):
"""
Spawns a new actor.
:param blueprint: blueprint of the actor to be spawned.
:param transform: transform where the actor will be spawned.
:return: actor id if the actor is successfully spawned. Otherwise, INVALID_ACTOR_ID.
"""
transform = carla.Transform(transform.location + carla.Location(0, 0, CARLA_SPAWN_OFFSET_Z),
transform.rotation)
batch = [
carla.command.SpawnActor(blueprint, transform).then(
carla.command.SetSimulatePhysics(carla.command.FutureActor, False))
]
response = self.client.apply_batch_sync(batch, False)[0]
if response.error:
logging.error('Spawn carla actor failed. %s', response.error)
return INVALID_ACTOR_ID
return response.actor_id
def destroy_actor(self, actor_id):
"""
Destroys the given actor.
"""
actor = self.world.get_actor(actor_id)
if actor is not None:
return actor.destroy()
return False
def synchronize_vehicle(self, vehicle_id, transform, velocity, lights=None):
"""
Updates vehicle state.
:param vehicle_id: id of the actor to be updated.
:param transform: new vehicle transform (i.e., position and rotation).
:param lights: new vehicle light state.
:return: True if successfully updated. Otherwise, False.
"""
vehicle = self.world.get_actor(vehicle_id)
if vehicle is None:
return False
vehicle.set_transform(transform)
if velocity is not None:
vehicle.set_target_velocity(velocity)
if lights is not None:
vehicle.set_light_state(carla.VehicleLightState(lights))
return True
def tick(self):
"""
Tick to carla simulation.
"""
self.world.tick()
# Update data structures for the current frame.
current_actors = set(
[vehicle.id for vehicle in self.world.get_actors().filter('vehicle.*')])
self.spawned_actors = current_actors.difference(self._active_actors)
self.destroyed_actors = self._active_actors.difference(current_actors)
self._active_actors = current_actors

View File

@ -1,33 +0,0 @@
#!/usr/bin/env python
# Copyright (c) 2020 Computer Vision Center (CVC) at the Universitat Autonoma de
# Barcelona (UAB).
#
# This work is licensed under the terms of the MIT license.
# For a copy, see <https://opensource.org/licenses/MIT>.
""" This module defines constants used for the vissim-carla co-simulation. """
# ==================================================================================================
# -- constants -------------------------------------------------------------------------------------
# ==================================================================================================
INVALID_ACTOR_ID = -1
CARLA_SPAWN_OFFSET_Z = 25.0 # meters
# Maximum distance of a Vissim veh/ped from a simulator veh/ped to be seen by the simulator (<=0
# means unlimited radius).
VISSIM_VISIBILITY_RADIUS = 0.0
# Maximum number of simulator vehicles/pedestrians/detectors (to be passed to Vissim).
VISSIM_MAX_SIMULATOR_VEH = 5000
VISSIM_MAX_SIMULATOR_PED = 5000
VISSIM_MAX_SIMULATOR_DET = 500
# Maximum number of vissim vehicles/pedestrians/signal groups (to be passed to the simulator).
VISSIM_MAX_VISSIM_VEH = 5000
VISSIM_MAX_VISSIM_PED = 5000
VISSIM_MAX_VISSIM_SIGGRP = 5000
# VISSIM Vehicle data constants.
NAME_MAX_LENGTH = 100
MAX_UDA = 16

View File

@ -1,284 +0,0 @@
#!/usr/bin/env python
# Copyright (c) 2020 Computer Vision Center (CVC) at the Universitat Autonoma de
# Barcelona (UAB).
#
# This work is licensed under the terms of the MIT license.
# For a copy, see <https://opensource.org/licenses/MIT>.
""" This module is responsible for the management of the ptv-vissim simulation. """
# ==================================================================================================
# -- imports ---------------------------------------------------------------------------------------
# ==================================================================================================
import enum
import logging
import math
import os
import carla # pylint: disable=import-error
from ctypes import *
from . import constants
# ==================================================================================================
# -- vissim definitions ----------------------------------------------------------------------------
# ==================================================================================================
class Simulator_Veh_Data(Structure):
"""
Structure to hold the data sent to vissim about the status of the simulator vehicles (i.e.,
carla vehicles).
"""
_fields_ = [
('Position_X', c_double), # front center of the vehicle in m
('Position_Y', c_double), # front center of the vehicle in m
('Position_Z', c_double), # front center of the vehicle in m
('Orient_Heading', c_double), # in radians, eastbound = zero, northbound = +Pi/2 */
('Orient_Pitch', c_double), # in radians, uphill = positive
('Speed', c_double), # in m/s
('ControlledByVissim', c_bool), # affects next time step
('RoutingDecisionNo', c_long), # used once if ControlledByVissim changed from false to true
('RouteNo', c_long) # used once if ControlledByVissim changed from false to true
]
class VISSIM_Veh_Data(Structure):
"""
Structure to hold the data received from vissim about the status of the traffic vehicles (i.e.,
vissim vehicles).
"""
_fields_ = [
('VehicleID', c_long),
('VehicleType', c_long), # vehicle type number from Vissim
('ModelFileName', c_char * constants.NAME_MAX_LENGTH), # .v3d
('color', c_long), # RGB
('Position_X', c_double), # front center of the vehicle in m
('Position_Y', c_double), # front center of the vehicle in m
('Position_Z', c_double), # front center of the vehicle in m
('Orient_Heading', c_double), # in radians, eastbound = zero, northbound = +Pi/2 */
('Orient_Pitch', c_double), # in radians, uphill = positive
('Speed', c_double), # in m/s
('LeadingVehicleID', c_long), # relevant vehicle in front
('TrailingVehicleID', c_long), # next vehicle back on the same lane
('LinkID', c_long), # Vissim link attribute “Number”
('LinkName', c_char * constants.NAME_MAX_LENGTH), # empty if “Name” not set in Vissim
('LinkCoordinate', c_double), # in m
('LaneIndex', c_int), # 0 = rightmost
('TurningIndicator', c_int), # 1 = left, 0 = none, -1 = right
('PreviousIndex', c_long), # for interpolation: index in the array in the previous Vissim time step, < 0 = new in the visibility area
('NumUDAs', c_long), # the number of UDA values in the following array
('UDA', c_double * constants.MAX_UDA) # the first MAX_UDA user-defined numeric vehicle attributes
]
class VissimLightState(enum.Enum):
"""
VissimLightState contains the different vissim indicator states.
"""
LEFT = 1
NONE = 0
RIGHT = -1
class VissimVehicle(object):
"""
VissimVehicle holds the data relative to traffic vehicles in vissim.
"""
def __init__(self,
vehicle_id,
type_id,
model_filename,
color,
location,
rotation,
velocity,
lights_state=VissimLightState.NONE):
# Static parameters.
self.id = vehicle_id
self.type = type_id
self.model_filename = model_filename
self.color = color
# Dynamic attributes.
loc = carla.Location(location[0], location[1], location[2])
rot = carla.Rotation(math.degrees(rotation[0]), math.degrees(rotation[1]),
math.degrees(rotation[2]))
self._transform = carla.Transform(loc, rot)
self._velocity = carla.Vector3D(
velocity * math.cos(math.radians(rot.yaw)) * math.cos(math.radians(rot.pitch)),
velocity * math.sin(math.radians(rot.yaw)) * math.cos(math.radians(rot.pitch)),
velocity * math.sin(math.radians(rot.pitch)))
self._lights_state = lights_state
def get_velocity(self):
"""
Returns the vehicle's velocity.
"""
return self._velocity
def get_transform(self):
"""
Returns carla transform.
"""
return self._transform
# ==================================================================================================
# -- vissim simulation -----------------------------------------------------------------------------
# ==================================================================================================
class PTVVissimSimulation(object):
"""
PTVVissimSimulation is responsible for the management of the vissim simulation.
"""
def __init__(self, args):
# Maximum number of simulator vehicles to be tracked by the driving simulator interface.
self._max_simulator_vehicles = args.simulator_vehicles
# Loading driving simulator proxy library.
logging.info('Loading DrivingSimulatorProxy library...')
self.ds_proxy = cdll.LoadLibrary('DrivingSimulatorProxy.dll')
# Connection to vissim simulator.
logging.info('Establishing a connection with a GUI version of PTV-Vissim')
result = self.ds_proxy.VISSIM_Connect(args.vissim_version,
os.path.abspath(args.vissim_network),
int(1. / args.step_length),
c_double(constants.VISSIM_VISIBILITY_RADIUS),
c_ushort(constants.VISSIM_MAX_SIMULATOR_VEH),
c_ushort(constants.VISSIM_MAX_SIMULATOR_PED),
c_ushort(constants.VISSIM_MAX_SIMULATOR_DET),
c_ushort(constants.VISSIM_MAX_VISSIM_VEH),
c_ushort(constants.VISSIM_MAX_VISSIM_PED),
c_ushort(constants.VISSIM_MAX_VISSIM_SIGGRP))
if not result:
raise RuntimeError('There was an error when establishing a connection with PTV-Vissim')
# Structures to keep track of the simulation state at each time step.
self._vissim_vehicles = {} # vissim_actor_id: VissimVehicle (only vissim traffic)
self._simulator_vehicles = {} # vissim_actor_id: Simulator_Veh_Data
self.spawned_vehicles = set()
self.destroyed_vehicles = set()
def _get_next_actor_id(self):
"""
Returns an available actor id. Otherwise, returns INVALID_ACTOR_ID.
"""
all_ids = set(range(1, self._max_simulator_vehicles + 1))
used_ids = set(self._simulator_vehicles.keys())
available_ids = all_ids - used_ids
if len(available_ids):
return available_ids.pop()
else:
return constants.INVALID_ACTOR_ID
def get_actor(self, actor_id):
"""
Accessor for vissim actor.
"""
return self._vissim_vehicles[actor_id]
def spawn_actor(self, transform):
"""
Spawns a new actor.
Warning: When the maximum number of simulator vehicles being tracked at the same time is
reached, no new vehicles are spawned.
"""
# Checks number of simulator vehicles currently being tracked.
if (len(self._simulator_vehicles) < self._max_simulator_vehicles):
actor_id = self._get_next_actor_id()
self._simulator_vehicles[actor_id] = Simulator_Veh_Data(
transform.location.x, transform.location.y, transform.location.z,
math.radians(transform.rotation.yaw), math.radians(transform.rotation.pitch), 0.0,
False, 0, 0)
return actor_id
else:
logging.warning(
'Maximum number of simulator vehicles reached. No vehicle will be spawned.')
return constants.INVALID_ACTOR_ID
def destroy_actor(self, actor_id):
"""
Destroys the given actor.
:param actor_id: id of the vehicle to be destroyed.
:return: True if successfully destroyed. Otherwise, False.
"""
if actor_id in self._simulator_vehicles:
del self._simulator_vehicles[actor_id]
return True
return False
def synchronize_vehicle(self, vehicle_id, transform, velocity):
"""
Updates vehicle state.
:param int vehicle_id: id of the vehicle to be updated.
:param carla.Transform transform: new vehicle transform (i.e., position and rotation).
:param carla.Vector3D velocity: new vehicle velocity.
:return: True if successfully updated. Otherwise, False.
"""
self._simulator_vehicles[vehicle_id] = Simulator_Veh_Data(
transform.location.x, transform.location.y, transform.location.z,
math.radians(transform.rotation.yaw), math.radians(transform.rotation.pitch),
math.sqrt(velocity.x**2 + velocity.y**2 + velocity.z**2), False, 0, 0)
return True
def _get_simulator_veh_data(self):
"""
Returns list of Simulator_Veh_Data structures ready to be sent to the driving simulator
interface.
"""
data = []
for i in range(1, self._max_simulator_vehicles + 1):
if i in self._simulator_vehicles:
data.append(self._simulator_vehicles[i])
else:
# Invalid Simulator_Veh_Data to set the position of simulator vehicles in vissim
# that are not yet in carla.
data.append(
Simulator_Veh_Data(float('inf'), float('inf'), float('inf'), 0.0, 0.0, 0.0,
False, 0, 0))
return data
def tick(self):
"""
Tick to vissim simulation.
"""
# Updating simulator vehicles data.
arr = (Simulator_Veh_Data * self._max_simulator_vehicles)(*self._get_simulator_veh_data())
self.ds_proxy.VISSIM_SetDriverVehicles(self._max_simulator_vehicles, byref(arr))
# Retrieving vissim traffic data.
num_vehicles = c_int(0)
traffic_data = POINTER(VISSIM_Veh_Data)()
self.ds_proxy.VISSIM_GetTrafficVehicles(byref(num_vehicles), byref(traffic_data))
vehicles = {}
for i in range(num_vehicles.value):
vehicle_data = traffic_data[i]
vehicles[vehicle_data.VehicleID] = VissimVehicle(
vehicle_data.VehicleID, vehicle_data.VehicleType, vehicle_data.ModelFileName,
vehicle_data.color,
[vehicle_data.Position_X, vehicle_data.Position_Y, vehicle_data.Position_Z],
[vehicle_data.Orient_Pitch, vehicle_data.Orient_Heading, 0.0], vehicle_data.Speed,
vehicle_data.TurningIndicator)
# Update data structures for the current time step.
active_vehicles = set(self._vissim_vehicles.keys())
current_vehicles = set(vehicles.keys())
self.spawned_vehicles = current_vehicles.difference(active_vehicles)
self.destroyed_vehicles = active_vehicles.difference(current_vehicles)
self._vissim_vehicles = vehicles
def close(self):
self.ds_proxy.VISSIM_Disconnect()

View File

@ -1 +0,0 @@
venv

View File

@ -1,94 +0,0 @@
{
"DEFAULT_2_WHEELED_VEHICLE": {
"vClass": "motorcycle"
},
"DEFAULT_WHEELED_VEHICLE": {
"vClass": "passenger"
},
"carla_blueprints": {
"vehicle.audi.a2": {
"vClass": "passenger"
},
"vehicle.audi.tt": {
"vClass": "passenger"
},
"vehicle.bmw.grandtourer": {
"vClass": "passenger"
},
"vehicle.chevrolet.impala": {
"vClass": "passenger"
},
"vehicle.citroen.c3": {
"vClass": "passenger"
},
"vehicle.jeep.wrangler_rubicon": {
"vClass": "passenger"
},
"vehicle.lincoln.mkz_2017": {
"vClass": "passenger"
},
"vehicle.mercedes.coupe": {
"vClass": "passenger"
},
"vehicle.mini.cooper_s": {
"vClass": "passenger"
},
"vehicle.ford.mustang": {
"vClass": "passenger"
},
"vehicle.nissan.micra": {
"vClass": "passenger"
},
"vehicle.nissan.patrol": {
"vClass": "passenger"
},
"vehicle.seat.leon": {
"vClass": "passenger"
},
"vehicle.volkswagen.t2": {
"vClass": "passenger",
"guiShape": "passenger/van"
},
"vehicle.dodge.charger_police": {
"vClass": "authority",
"guiShape": "police"
},
"vehicle.micro.microlino": {
"vClass": "evehicle"
},
"vehicle.toyota.prius": {
"vClass": "evehicle"
},
"vehicle.tesla.cybertruck": {
"vClass": "evehicle"
},
"vehicle.tesla.model3": {
"vClass": "evehicle"
},
"vehicle.audi.etron": {
"vClass": "evehicle"
},
"vehicle.carlamotors.carlacola": {
"vClass": "truck",
"guiShape": "truck"
},
"vehicle.yamaha.yzf": {
"vClass": "motorcycle"
},
"vehicle.harley-davidson.low_rider": {
"vClass": "motorcycle"
},
"vehicle.kawasaki.ninja": {
"vClass": "motorcycle"
},
"vehicle.gazelle.omafiets": {
"vClass": "bicycle"
},
"vehicle.diamondback.century": {
"vClass": "bicycle"
},
"vehicle.bh.crossbike": {
"vClass": "bicycle"
}
}
}

View File

@ -1,13 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<configuration xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="http://sumo.dlr.de/xsd/sumoConfiguration.xsd">
<input>
<net-file value="net/Town01.net.xml"/>
<route-files value="carlavtypes.rou.xml,rou/Town01.rou.xml"/>
</input>
<gui_only>
<gui-settings-file value="viewsettings.xml"/>
</gui_only>
</configuration>

View File

@ -1,13 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<configuration xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="http://sumo.dlr.de/xsd/sumoConfiguration.xsd">
<input>
<net-file value="net/Town04.net.xml"/>
<route-files value="carlavtypes.rou.xml,rou/Town04.rou.xml"/>
</input>
<gui_only>
<gui-settings-file value="viewsettings.xml"/>
</gui_only>
</configuration>

View File

@ -1,13 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<configuration xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="http://sumo.dlr.de/xsd/sumoConfiguration.xsd">
<input>
<net-file value="net/Town05.net.xml"/>
<route-files value="carlavtypes.rou.xml,rou/Town05.rou.xml"/>
</input>
<gui_only>
<gui-settings-file value="viewsettings.xml"/>
</gui_only>
</configuration>

View File

@ -1,31 +0,0 @@
<?xml version='1.0' encoding='UTF-8'?>
<!--generated on 2020-03-04 18:25:00 by create_sumo_vtypes.py-->
<routes>
<vType id="vehicle.audi.a2" length="3.7186214923858643" width="1.7924479246139526" height="1.5354934930801392" vClass="passenger"/>
<vType id="vehicle.audi.tt" length="4.147226333618164" width="2.0032031536102295" height="1.382421851158142" vClass="passenger"/>
<vType id="vehicle.carlamotors.carlacola" length="5.1992292404174805" width="2.6150190830230713" height="2.4768505096435547" vClass="truck" guiShape="truck"/>
<vType id="vehicle.dodge.charger_police" length="5.010976314544678" width="2.054335832595825" height="1.5807031393051147" vClass="authority" guiShape="police"/>
<vType id="vehicle.jeep.wrangler_rubicon" length="3.8681068420410156" width="1.906570553779602" height="1.8799999952316284" vClass="passenger"/>
<vType id="vehicle.chevrolet.impala" length="5.369193077087402" width="2.052736520767212" height="1.4150995016098022" vClass="passenger"/>
<vType id="vehicle.mini.cooper_s" length="3.8021926879882812" width="1.9740344285964966" height="1.4750006198883057" vClass="passenger"/>
<vType id="vehicle.micro.microlino" length="2.2024967670440674" width="1.4853248596191406" height="1.3464953899383545" vClass="evehicle"/>
<vType id="vehicle.audi.etron" length="4.892005443572998" width="2.08632230758667" height="1.6511509418487549" vClass="evehicle"/>
<vType id="vehicle.mercedes.coupe" length="5.043785095214844" width="2.1629974842071533" height="1.640134572982788" vClass="passenger"/>
<vType id="vehicle.bmw.grandtourer" length="4.639087677001953" width="2.259321928024292" height="1.6781779527664185" vClass="passenger"/>
<vType id="vehicle.toyota.prius" length="4.538333415985107" width="2.0011305809020996" height="1.5373616218566895" vClass="evehicle"/>
<vType id="vehicle.citroen.c3" length="3.9753477573394775" width="1.862074851989746" height="1.6257729530334473" vClass="passenger"/>
<vType id="vehicle.ford.mustang" length="4.904701232910156" width="2.0606582164764404" height="1.478397011756897" vClass="passenger"/>
<vType id="vehicle.tesla.model3" length="4.808821678161621" width="2.1695058345794678" height="1.5231821537017822" vClass="evehicle"/>
<vType id="vehicle.diamondback.century" length="1.6562436819076538" width="0.42141881585121155" height="1.49351167678833" vClass="bicycle"/>
<vType id="vehicle.gazelle.omafiets" length="1.843441367149353" width="0.4674844741821289" height="1.590073823928833" vClass="bicycle"/>
<vType id="vehicle.harley-davidson.low_rider" length="2.350175619125366" width="0.7662330269813538" height="1.4637391567230225" vClass="motorcycle"/>
<vType id="vehicle.bh.crossbike" length="1.5093227624893188" width="0.8659406304359436" height="1.5306309461593628" vClass="bicycle"/>
<vType id="vehicle.tesla.cybertruck" length="6.364232063293457" width="2.3934903144836426" height="2.1439828872680664" vClass="evehicle"/>
<vType id="vehicle.volkswagen.t2" length="4.473711013793945" width="1.8112499713897705" height="2.0543651580810547" vClass="passenger" guiShape="passenger/van"/>
<vType id="vehicle.kawasaki.ninja" length="2.043684244155884" width="0.7969123125076294" height="1.374603033065796" vClass="motorcycle"/>
<vType id="vehicle.lincoln.mkz_2017" length="4.904701232910156" width="2.0606582164764404" height="1.478397011756897" vClass="passenger"/>
<vType id="vehicle.seat.leon" length="4.207873821258545" width="1.8198652267456055" height="1.4694602489471436" vClass="passenger"/>
<vType id="vehicle.yamaha.yzf" length="2.1907684803009033" width="0.7662330269813538" height="1.6345058679580688" vClass="motorcycle"/>
<vType id="vehicle.nissan.patrol" length="4.519999980926514" width="1.9199999570846558" height="1.8871309757232666" vClass="passenger"/>
<vType id="vehicle.nissan.micra" length="3.6688475608825684" width="1.8561522960662842" height="1.5232137441635132" vClass="passenger"/>
</routes>

View File

@ -1,812 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<net version="1.6" junctionCornerDetail="5" rectangularLaneCut="true" limitTurnSpeed="5.50" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="http://sumo.dlr.de/xsd/net_file.xsd">
<location netOffset="0.06,328.61" convBoundary="0.00,0.00,394.44,328.66" origBoundary="-0.06,-328.61,394.38,0.05" projParameter="!"/>
<type id="bidirectional" priority="1" speed="1.39" disallow="pedestrian tram rail_urban rail rail_electric rail_fast ship" width="3.65"/>
<type id="biking" priority="-1" speed="5.56" allow="bicycle" width="1.50"/>
<type id="border" priority="0" speed="1.39" disallow="all" discard="1" width="0.10"/>
<type id="driving" priority="1" speed="13.89" disallow="pedestrian tram rail_urban rail rail_electric rail_fast ship" width="3.65"/>
<type id="entry" priority="1" speed="22.22" disallow="pedestrian tram rail_urban rail rail_electric rail_fast ship" width="3.65"/>
<type id="exit" priority="1" speed="22.22" disallow="pedestrian tram rail_urban rail rail_electric rail_fast ship" width="3.65"/>
<type id="median" priority="0" speed="1.39" disallow="all" discard="1" width="0.10"/>
<type id="mwyEntry" priority="1" speed="22.22" allow="private emergency authority army vip passenger hov taxi bus coach delivery truck trailer motorcycle evehicle custom1 custom2" width="3.65"/>
<type id="mwyExit" priority="1" speed="22.22" allow="private emergency authority army vip passenger hov taxi bus coach delivery truck trailer motorcycle evehicle custom1 custom2" width="3.65"/>
<type id="none" priority="0" speed="1.39" disallow="all" discard="1" width="1.00"/>
<type id="offRamp" priority="1" speed="22.22" allow="private emergency authority army vip passenger hov taxi bus coach delivery truck trailer motorcycle evehicle custom1 custom2" width="3.65"/>
<type id="onRamp" priority="1" speed="22.22" allow="private emergency authority army vip passenger hov taxi bus coach delivery truck trailer motorcycle evehicle custom1 custom2" width="3.65"/>
<type id="parking" priority="1" speed="1.39" disallow="pedestrian tram rail_urban rail rail_electric rail_fast ship" width="2.50"/>
<type id="rail" priority="3" speed="33.33" allow="rail_urban rail rail_electric rail_fast" width="3.65"/>
<type id="restricted" priority="0" speed="13.89" disallow="all" width="3.65"/>
<type id="roadWorks" priority="0" speed="1.39" allow="authority" width="3.65"/>
<type id="shoulder" priority="0" speed="1.39" disallow="all" discard="1" width="1.00"/>
<type id="sidewalk" priority="-2" speed="2.78" allow="pedestrian" width="2.50"/>
<type id="special1" priority="1" speed="22.22" allow="custom1" discard="1" width="3.65"/>
<type id="special2" priority="1" speed="22.22" allow="custom2" discard="1" width="3.65"/>
<type id="special3" priority="1" speed="22.22" allow="custom1 custom2" discard="1" width="3.65"/>
<type id="stop" priority="1" speed="13.89" disallow="pedestrian tram rail_urban rail rail_electric rail_fast ship" width="3.65"/>
<type id="tram" priority="2" speed="13.89" allow="tram" width="3.65"/>
<edge id=":111_0" function="internal">
<lane id=":111_0_0" index="0" disallow="pedestrian tram rail_urban rail rail_electric rail_fast ship" speed="8.22" length="14.76" width="4.00" shape="334.93,282.20 334.35,278.23 332.62,275.40 329.73,273.71 325.69,273.14"/>
</edge>
<edge id=":111_1" function="internal">
<lane id=":111_1_0" index="0" disallow="pedestrian tram rail_urban rail rail_electric rail_fast ship" speed="13.89" length="22.62" width="4.00" shape="334.93,282.20 334.92,259.58"/>
</edge>
<edge id=":111_2" function="internal">
<lane id=":111_2_0" index="0" disallow="pedestrian tram rail_urban rail rail_electric rail_fast ship" speed="13.89" length="22.62" width="4.00" shape="338.92,259.58 338.93,282.19"/>
</edge>
<edge id=":111_3" function="internal">
<lane id=":111_3_0" index="0" disallow="pedestrian tram rail_urban rail rail_electric rail_fast ship" speed="9.81" length="8.31" width="4.00" shape="338.92,259.58 338.09,265.51 336.92,267.51"/>
</edge>
<edge id=":111_6" function="internal">
<lane id=":111_6_0" index="0" disallow="pedestrian tram rail_urban rail rail_electric rail_fast ship" speed="9.81" length="13.30" width="4.00" shape="336.92,267.51 335.61,269.75 331.48,272.29 325.69,273.14"/>
</edge>
<edge id=":111_4" function="internal">
<lane id=":111_4_0" index="0" disallow="pedestrian tram rail_urban rail rail_electric rail_fast ship" speed="8.32" length="15.16" width="4.00" shape="325.69,269.14 329.73,268.54 332.61,266.75 334.34,263.76 334.92,259.58"/>
</edge>
<edge id=":111_5" function="internal">
<lane id=":111_5_0" index="0" disallow="pedestrian tram rail_urban rail rail_electric rail_fast ship" speed="9.73" length="21.20" width="4.00" shape="325.69,269.14 331.48,269.96 335.62,272.40 338.10,276.48 338.93,282.19"/>
</edge>
<edge id=":128_0" function="internal">
<lane id=":128_0_0" index="0" disallow="pedestrian tram rail_urban rail rail_electric rail_fast ship" speed="13.89" length="22.00" width="4.00" shape="88.46,142.28 88.46,120.28"/>
</edge>
<edge id=":128_1" function="internal">
<lane id=":128_1_0" index="0" disallow="pedestrian tram rail_urban rail rail_electric rail_fast ship" speed="9.65" length="7.94" width="4.00" shape="88.46,142.28 89.27,136.68 90.46,134.73"/>
</edge>
<edge id=":128_6" function="internal">
<lane id=":128_6_0" index="0" disallow="pedestrian tram rail_urban rail rail_electric rail_fast ship" speed="9.65" length="12.89" width="4.00" shape="90.46,134.73 91.72,132.67 95.79,130.27 101.48,129.47"/>
</edge>
<edge id=":128_2" function="internal">
<lane id=":128_2_0" index="0" disallow="pedestrian tram rail_urban rail rail_electric rail_fast ship" speed="8.12" length="14.39" width="4.00" shape="101.49,133.47 97.54,134.02 94.72,135.67 93.02,138.43 92.46,142.29"/>
</edge>
<edge id=":128_3" function="internal">
<lane id=":128_3_0" index="0" disallow="pedestrian tram rail_urban rail rail_electric rail_fast ship" speed="9.71" length="21.13" width="4.00" shape="101.49,133.47 95.79,132.65 91.72,130.17 89.27,126.05 88.46,120.28"/>
</edge>
<edge id=":128_4" function="internal">
<lane id=":128_4_0" index="0" disallow="pedestrian tram rail_urban rail rail_electric rail_fast ship" speed="8.20" length="14.68" width="4.00" shape="92.46,120.28 93.03,124.30 94.72,127.17 97.54,128.90 101.48,129.47"/>
</edge>
<edge id=":128_5" function="internal">
<lane id=":128_5_0" index="0" disallow="pedestrian tram rail_urban rail rail_electric rail_fast ship" speed="13.89" length="22.00" width="4.00" shape="92.46,120.28 92.46,142.29"/>
</edge>
<edge id=":139_0" function="internal">
<lane id=":139_0_0" index="0" disallow="pedestrian tram rail_urban rail rail_electric rail_fast ship" speed="8.18" length="14.62" width="4.00" shape="334.89,208.03 334.31,204.12 332.59,201.33 329.72,199.65 325.70,199.09"/>
</edge>
<edge id=":139_1" function="internal">
<lane id=":139_1_0" index="0" disallow="pedestrian tram rail_urban rail rail_electric rail_fast ship" speed="13.89" length="23.09" width="4.00" shape="334.89,208.03 334.87,184.94"/>
</edge>
<edge id=":139_2" function="internal">
<lane id=":139_2_0" index="0" disallow="pedestrian tram rail_urban rail rail_electric rail_fast ship" speed="13.89" length="23.09" width="4.00" shape="338.87,184.94 338.89,208.03"/>
</edge>
<edge id=":139_3" function="internal">
<lane id=":139_3_0" index="0" disallow="pedestrian tram rail_urban rail rail_electric rail_fast ship" speed="9.91" length="8.65" width="4.00" shape="338.87,184.94 338.05,191.13 336.88,193.24"/>
</edge>
<edge id=":139_6" function="internal">
<lane id=":139_6_0" index="0" disallow="pedestrian tram rail_urban rail rail_electric rail_fast ship" speed="9.91" length="13.39" width="4.00" shape="336.88,193.24 335.58,195.55 331.46,198.21 325.70,199.09"/>
</edge>
<edge id=":139_4" function="internal">
<lane id=":139_4_0" index="0" disallow="pedestrian tram rail_urban rail rail_electric rail_fast ship" speed="8.43" length="15.59" width="4.00" shape="325.69,195.09 329.71,194.46 332.58,192.56 334.30,189.38 334.87,184.94"/>
</edge>
<edge id=":139_5" function="internal">
<lane id=":139_5_0" index="0" disallow="pedestrian tram rail_urban rail rail_electric rail_fast ship" speed="9.70" length="21.07" width="4.00" shape="325.69,195.09 331.46,195.90 335.59,198.33 338.06,202.37 338.89,208.03"/>
</edge>
<edge id=":156_0" function="internal">
<lane id=":156_0_0" index="0" disallow="pedestrian tram rail_urban rail rail_electric rail_fast ship" speed="13.89" length="22.00" width="4.00" shape="88.45,208.77 88.45,186.77"/>
</edge>
<edge id=":156_1" function="internal">
<lane id=":156_1_0" index="0" disallow="pedestrian tram rail_urban rail rail_electric rail_fast ship" speed="9.78" length="8.37" width="4.00" shape="88.45,208.77 89.26,202.84 90.45,200.78"/>
</edge>
<edge id=":156_6" function="internal">
<lane id=":156_6_0" index="0" disallow="pedestrian tram rail_urban rail rail_electric rail_fast ship" speed="9.78" length="13.09" width="4.00" shape="90.45,200.78 91.71,198.59 95.78,196.05 101.48,195.20"/>
</edge>
<edge id=":156_2" function="internal">
<lane id=":156_2_0" index="0" disallow="pedestrian tram rail_urban rail rail_electric rail_fast ship" speed="8.28" length="15.01" width="4.00" shape="101.48,199.20 97.53,199.80 94.71,201.59 93.01,204.59 92.45,208.77"/>
</edge>
<edge id=":156_3" function="internal">
<lane id=":156_3_0" index="0" disallow="pedestrian tram rail_urban rail rail_electric rail_fast ship" speed="9.58" length="20.53" width="4.00" shape="101.48,199.20 95.78,198.42 91.71,196.09 89.27,192.21 88.45,186.77"/>
</edge>
<edge id=":156_4" function="internal">
<lane id=":156_4_0" index="0" disallow="pedestrian tram rail_urban rail rail_electric rail_fast ship" speed="8.04" length="14.07" width="4.00" shape="92.45,186.77 93.02,190.46 94.71,193.09 97.53,194.67 101.48,195.20"/>
</edge>
<edge id=":156_5" function="internal">
<lane id=":156_5_0" index="0" disallow="pedestrian tram rail_urban rail rail_electric rail_fast ship" speed="13.89" length="22.00" width="4.00" shape="92.45,186.77 92.45,208.77"/>
</edge>
<edge id=":167_0" function="internal">
<lane id=":167_0_0" index="0" disallow="pedestrian tram rail_urban rail rail_electric rail_fast ship" speed="8.23" length="14.78" width="4.00" shape="154.08,282.42 153.51,278.35 151.82,275.44 149.00,273.70 145.05,273.12"/>
</edge>
<edge id=":167_1" function="internal">
<lane id=":167_1_0" index="0" disallow="pedestrian tram rail_urban rail rail_electric rail_fast ship" speed="9.75" length="21.33" width="4.00" shape="154.08,282.42 154.90,276.60 157.36,272.44 161.47,269.95 167.23,269.12"/>
</edge>
<edge id=":167_2" function="internal">
<lane id=":167_2_0" index="0" disallow="pedestrian tram rail_urban rail rail_electric rail_fast ship" speed="8.24" length="14.87" width="4.00" shape="167.23,273.12 163.23,273.70 160.37,275.44 158.65,278.35 158.08,282.41"/>
</edge>
<edge id=":167_3" function="internal">
<lane id=":167_3_0" index="0" disallow="pedestrian tram rail_urban rail rail_electric rail_fast ship" speed="13.89" length="22.18" width="4.00" shape="167.23,273.12 145.05,273.12"/>
</edge>
<edge id=":167_4" function="internal">
<lane id=":167_4_0" index="0" disallow="pedestrian tram rail_urban rail rail_electric rail_fast ship" speed="13.89" length="22.18" width="4.00" shape="145.05,269.12 167.23,269.12"/>
</edge>
<edge id=":167_5" function="internal">
<lane id=":167_5_0" index="0" disallow="pedestrian tram rail_urban rail rail_electric rail_fast ship" speed="9.74" length="8.00" width="4.00" shape="145.05,269.12 150.75,269.95 152.66,271.12"/>
</edge>
<edge id=":167_6" function="internal">
<lane id=":167_6_0" index="0" disallow="pedestrian tram rail_urban rail rail_electric rail_fast ship" speed="9.74" length="13.23" width="4.00" shape="152.66,271.12 154.82,272.44 157.26,276.59 158.08,282.41"/>
</edge>
<edge id=":184_0" function="internal">
<lane id=":184_0_0" index="0" disallow="pedestrian tram rail_urban rail rail_electric rail_fast ship" speed="13.89" length="22.00" width="4.00" shape="88.44,282.46 88.44,260.46"/>
</edge>
<edge id=":184_1" function="internal">
<lane id=":184_1_0" index="0" disallow="pedestrian tram rail_urban rail rail_electric rail_fast ship" speed="9.74" length="8.25" width="4.00" shape="88.44,282.46 89.25,276.62 90.44,274.59"/>
</edge>
<edge id=":184_6" function="internal">
<lane id=":184_6_0" index="0" disallow="pedestrian tram rail_urban rail rail_electric rail_fast ship" speed="9.74" length="13.01" width="4.00" shape="90.44,274.59 91.69,272.45 95.76,269.94 101.45,269.11"/>
</edge>
<edge id=":184_2" function="internal">
<lane id=":184_2_0" index="0" disallow="pedestrian tram rail_urban rail rail_electric rail_fast ship" speed="8.23" length="14.80" width="4.00" shape="101.45,273.11 97.51,273.69 94.69,275.45 93.00,278.37 92.44,282.46"/>
</edge>
<edge id=":184_3" function="internal">
<lane id=":184_3_0" index="0" disallow="pedestrian tram rail_urban rail rail_electric rail_fast ship" speed="9.62" length="20.70" width="4.00" shape="101.45,273.11 95.76,272.32 91.69,269.95 89.25,265.99 88.44,260.46"/>
</edge>
<edge id=":184_4" function="internal">
<lane id=":184_4_0" index="0" disallow="pedestrian tram rail_urban rail rail_electric rail_fast ship" speed="8.08" length="14.25" width="4.00" shape="92.44,260.46 93.00,264.24 94.69,266.95 97.51,268.57 101.45,269.11"/>
</edge>
<edge id=":184_5" function="internal">
<lane id=":184_5_0" index="0" disallow="pedestrian tram rail_urban rail rail_electric rail_fast ship" speed="13.89" length="22.00" width="4.00" shape="92.44,260.46 92.44,282.46"/>
</edge>
<edge id=":195_0" function="internal">
<lane id=":195_0_0" index="0" disallow="pedestrian tram rail_urban rail rail_electric rail_fast ship" speed="8.21" length="14.74" width="4.00" shape="88.48,11.31 87.92,7.25 86.23,4.35 83.41,2.61 79.47,2.03"/>
</edge>
<edge id=":195_1" function="internal">
<lane id=":195_1_0" index="0" disallow="pedestrian tram rail_urban rail rail_electric rail_fast ship" speed="9.76" length="21.35" width="4.00" shape="88.48,11.31 89.30,5.50 91.78,1.35 95.90,-1.15 101.68,-1.98"/>
</edge>
<edge id=":195_2" function="internal">
<lane id=":195_2_0" index="0" disallow="pedestrian tram rail_urban rail rail_electric rail_fast ship" speed="8.26" length="14.91" width="4.00" shape="101.68,2.02 97.65,2.60 94.78,4.35 93.05,7.25 92.48,11.31"/>
</edge>
<edge id=":195_3" function="internal">
<lane id=":195_3_0" index="0" disallow="pedestrian tram rail_urban rail rail_electric rail_fast ship" speed="13.89" length="22.21" width="4.00" shape="101.68,2.02 79.47,2.03"/>
</edge>
<edge id=":195_4" function="internal">
<lane id=":195_4_0" index="0" disallow="pedestrian tram rail_urban rail rail_electric rail_fast ship" speed="13.89" length="22.21" width="4.00" shape="79.47,-1.97 101.68,-1.98"/>
</edge>
<edge id=":195_5" function="internal">
<lane id=":195_5_0" index="0" disallow="pedestrian tram rail_urban rail rail_electric rail_fast ship" speed="9.72" length="7.99" width="4.00" shape="79.47,-1.97 85.16,-1.14 87.07,0.03"/>
</edge>
<edge id=":195_6" function="internal">
<lane id=":195_6_0" index="0" disallow="pedestrian tram rail_urban rail rail_electric rail_fast ship" speed="9.72" length="13.21" width="4.00" shape="87.07,0.03 89.23,1.35 91.67,5.50 92.48,11.31"/>
</edge>
<edge id=":26_0" function="internal">
<lane id=":26_0_0" index="0" disallow="pedestrian tram rail_urban rail rail_electric rail_fast ship" speed="13.89" length="23.13" width="4.00" shape="168.14,330.65 145.02,330.66"/>
</edge>
<edge id=":26_1" function="internal">
<lane id=":26_1_0" index="0" disallow="pedestrian tram rail_urban rail rail_electric rail_fast ship" speed="9.81" length="8.69" width="4.00" shape="168.14,330.65 162.02,329.86 159.81,328.65"/>
</edge>
<edge id=":26_6" function="internal">
<lane id=":26_6_0" index="0" disallow="pedestrian tram rail_urban rail rail_electric rail_fast ship" speed="9.81" length="12.90" width="4.00" shape="159.81,328.65 157.64,327.47 155.01,323.48 154.13,317.90"/>
</edge>
<edge id=":26_2" function="internal">
<lane id=":26_2_0" index="0" disallow="pedestrian tram rail_urban rail rail_electric rail_fast ship" speed="8.32" length="15.15" width="4.00" shape="158.13,317.90 158.76,321.73 160.64,324.46 163.76,326.11 168.14,326.65"/>
</edge>
<edge id=":26_3" function="internal">
<lane id=":26_3_0" index="0" disallow="pedestrian tram rail_urban rail rail_electric rail_fast ship" speed="9.65" length="20.87" width="4.00" shape="158.13,317.90 157.31,323.48 154.86,327.47 150.76,329.86 145.02,330.66"/>
</edge>
<edge id=":26_4" function="internal">
<lane id=":26_4_0" index="0" disallow="pedestrian tram rail_urban rail rail_electric rail_fast ship" speed="8.12" length="14.41" width="4.00" shape="145.02,326.66 149.01,326.11 151.85,324.47 153.56,321.73 154.13,317.90"/>
</edge>
<edge id=":26_5" function="internal">
<lane id=":26_5_0" index="0" disallow="pedestrian tram rail_urban rail rail_electric rail_fast ship" speed="13.89" length="23.13" width="4.00" shape="145.02,326.66 168.14,326.65"/>
</edge>
<edge id=":43_0" function="internal">
<lane id=":43_0_0" index="0" disallow="pedestrian tram rail_urban rail rail_electric rail_fast ship" speed="13.89" length="22.60" width="4.00" shape="348.29,330.61 325.69,330.62"/>
</edge>
<edge id=":43_1" function="internal">
<lane id=":43_1_0" index="0" disallow="pedestrian tram rail_urban rail rail_electric rail_fast ship" speed="9.70" length="8.29" width="4.00" shape="348.29,330.61 342.46,329.81 340.37,328.61"/>
</edge>
<edge id=":43_6" function="internal">
<lane id=":43_6_0" index="0" disallow="pedestrian tram rail_urban rail rail_electric rail_fast ship" speed="9.70" length="12.78" width="4.00" shape="340.37,328.61 338.29,327.41 335.79,323.42 334.95,317.82"/>
</edge>
<edge id=":43_2" function="internal">
<lane id=":43_2_0" index="0" disallow="pedestrian tram rail_urban rail rail_electric rail_fast ship" speed="8.18" length="14.62" width="4.00" shape="338.95,317.81 339.54,321.66 341.29,324.41 344.21,326.06 348.29,326.61"/>
</edge>
<edge id=":43_3" function="internal">
<lane id=":43_3_0" index="0" disallow="pedestrian tram rail_urban rail rail_electric rail_fast ship" speed="9.69" length="21.02" width="4.00" shape="338.95,317.81 338.13,323.42 335.64,327.42 331.49,329.82 325.69,330.62"/>
</edge>
<edge id=":43_4" function="internal">
<lane id=":43_4_0" index="0" disallow="pedestrian tram rail_urban rail rail_electric rail_fast ship" speed="8.17" length="14.57" width="4.00" shape="325.69,326.62 329.74,326.07 332.64,324.42 334.38,321.67 334.95,317.82"/>
</edge>
<edge id=":43_5" function="internal">
<lane id=":43_5_0" index="0" disallow="pedestrian tram rail_urban rail rail_electric rail_fast ship" speed="13.89" length="22.60" width="4.00" shape="325.69,326.62 348.29,326.61"/>
</edge>
<edge id=":60_0" function="internal">
<lane id=":60_0_0" index="0" disallow="pedestrian tram rail_urban rail rail_electric rail_fast ship" speed="8.19" length="14.63" width="4.00" shape="334.77,11.16 334.20,7.15 332.52,4.29 329.71,2.57 325.78,2.00"/>
</edge>
<edge id=":60_1" function="internal">
<lane id=":60_1_0" index="0" disallow="pedestrian tram rail_urban rail rail_electric rail_fast ship" speed="9.70" length="21.12" width="4.00" shape="334.77,11.16 335.58,5.40 338.02,1.29 342.09,-1.18 347.79,-2.00"/>
</edge>
<edge id=":60_2" function="internal">
<lane id=":60_2_0" index="0" disallow="pedestrian tram rail_urban rail rail_electric rail_fast ship" speed="8.19" length="14.66" width="4.00" shape="347.79,2.00 343.84,2.57 341.02,4.29 339.33,7.15 338.77,11.16"/>
</edge>
<edge id=":60_3" function="internal">
<lane id=":60_3_0" index="0" disallow="pedestrian tram rail_urban rail rail_electric rail_fast ship" speed="13.89" length="22.01" width="4.00" shape="347.79,2.00 325.78,2.00"/>
</edge>
<edge id=":60_4" function="internal">
<lane id=":60_4_0" index="0" disallow="pedestrian tram rail_urban rail rail_electric rail_fast ship" speed="13.89" length="22.01" width="4.00" shape="325.78,-2.00 347.79,-2.00"/>
</edge>
<edge id=":60_5" function="internal">
<lane id=":60_5_0" index="0" disallow="pedestrian tram rail_urban rail rail_electric rail_fast ship" speed="9.70" length="8.00" width="4.00" shape="325.78,-2.00 331.46,-1.18 333.40,0.00"/>
</edge>
<edge id=":60_6" function="internal">
<lane id=":60_6_0" index="0" disallow="pedestrian tram rail_urban rail rail_electric rail_fast ship" speed="9.70" length="13.07" width="4.00" shape="333.40,0.00 335.52,1.29 337.95,5.40 338.77,11.16"/>
</edge>
<edge id=":7.14_0" function="internal">
<lane id=":7.14_0_0" index="0" allow="pedestrian" speed="2.78" length="6.22" width="4.00" shape="387.17,7.11 386.03,6.37 385.10,6.16 384.07,6.22 382.64,6.30"/>
<lane id=":7.14_0_1" index="1" disallow="all" speed="1.39" length="6.22" width="0.30" shape="388.50,5.43 387.02,4.43 385.82,4.08 384.49,4.08 382.64,4.15"/>
<lane id=":7.14_0_2" index="2" disallow="pedestrian tram rail_urban rail rail_electric rail_fast ship" speed="10.40" length="6.22" width="4.00" shape="389.84,3.74 388.01,2.50 386.54,2.01 384.92,1.95 382.64,2.00"/>
</edge>
<edge id=":7.14_3" function="internal">
<lane id=":7.14_3_0" index="0" allow="pedestrian" speed="2.78" length="11.83" width="4.00" shape="382.64,-6.30 386.57,-6.30 389.34,-6.02 391.84,-4.98 395.00,-2.75"/>
<lane id=":7.14_3_1" index="1" disallow="all" speed="1.39" length="11.83" width="0.30" shape="382.64,-4.15 386.14,-4.17 388.61,-3.94 390.85,-3.04 393.67,-1.07"/>
<lane id=":7.14_3_2" index="2" disallow="pedestrian tram rail_urban rail rail_electric rail_fast ship" speed="12.06" length="11.83" width="4.00" shape="382.64,-2.00 385.72,-2.03 387.89,-1.86 389.86,-1.11 392.33,0.61"/>
</edge>
<edge id=":77_0" function="internal">
<lane id=":77_0_0" index="0" disallow="pedestrian tram rail_urban rail rail_electric rail_fast ship" speed="13.89" length="23.32" width="4.00" shape="102.75,330.66 79.44,330.65"/>
</edge>
<edge id=":77_1" function="internal">
<lane id=":77_1_0" index="0" disallow="pedestrian tram rail_urban rail rail_electric rail_fast ship" speed="9.86" length="8.88" width="4.00" shape="102.75,330.66 96.49,329.86 94.22,328.66"/>
</edge>
<edge id=":77_6" function="internal">
<lane id=":77_6_0" index="0" disallow="pedestrian tram rail_urban rail rail_electric rail_fast ship" speed="9.86" length="12.94" width="4.00" shape="94.22,328.66 92.01,327.48 89.33,323.50 88.43,317.94"/>
</edge>
<edge id=":77_2" function="internal">
<lane id=":77_2_0" index="0" disallow="pedestrian tram rail_urban rail rail_electric rail_fast ship" speed="8.37" length="15.37" width="4.00" shape="92.43,317.94 93.08,321.76 95.01,324.48 98.24,326.11 102.75,326.66"/>
</edge>
<edge id=":77_3" function="internal">
<lane id=":77_3_0" index="0" disallow="pedestrian tram rail_urban rail rail_electric rail_fast ship" speed="9.62" length="20.73" width="4.00" shape="92.43,317.94 91.62,323.51 89.18,327.48 85.12,329.86 79.44,330.65"/>
</edge>
<edge id=":77_4" function="internal">
<lane id=":77_4_0" index="0" disallow="pedestrian tram rail_urban rail rail_electric rail_fast ship" speed="8.09" length="14.28" width="4.00" shape="79.44,326.65 83.37,326.11 86.18,324.48 87.87,321.75 88.43,317.94"/>
</edge>
<edge id=":77_5" function="internal">
<lane id=":77_5_0" index="0" disallow="pedestrian tram rail_urban rail rail_electric rail_fast ship" speed="13.89" length="23.32" width="4.00" shape="79.44,326.65 102.75,326.66"/>
</edge>
<edge id=":8.14_0" function="internal">
<lane id=":8.14_0_0" index="0" allow="pedestrian" speed="2.78" length="5.39" width="4.00" shape="388.11,11.57 387.57,7.48"/>
<lane id=":8.14_0_1" index="1" disallow="all" speed="1.39" length="5.39" width="0.30" shape="390.26,11.57 390.35,9.94 390.44,8.77 390.23,7.70 389.43,6.38"/>
<lane id=":8.14_0_2" index="2" disallow="pedestrian tram rail_urban rail rail_electric rail_fast ship" speed="9.96" length="5.39" width="4.00" shape="392.41,11.57 392.51,9.60 392.58,8.18 392.29,6.89 391.30,5.28"/>
</edge>
<edge id=":8.14_3" function="internal">
<lane id=":8.14_3_0" index="0" allow="pedestrian" speed="2.78" length="9.81" width="4.00" shape="398.46,1.08 399.96,3.92 400.60,6.05 400.74,8.32 400.71,11.57"/>
<lane id=":8.14_3_1" index="1" disallow="all" speed="1.39" length="9.81" width="0.30" shape="396.61,2.17 397.94,4.71 398.50,6.62 398.60,8.66 398.56,11.57"/>
<lane id=":8.14_3_2" index="2" disallow="pedestrian tram rail_urban rail rail_electric rail_fast ship" speed="13.51" length="9.81" width="4.00" shape="394.75,3.26 395.92,5.50 396.39,7.20 396.45,9.00 396.41,11.57"/>
</edge>
<edge id=":94_0" function="internal">
<lane id=":94_0_0" index="0" disallow="pedestrian tram rail_urban rail rail_electric rail_fast ship" speed="8.28" length="15.02" width="4.00" shape="334.85,142.96 334.28,138.80 332.57,135.83 329.72,134.04 325.73,133.45"/>
</edge>
<edge id=":94_1" function="internal">
<lane id=":94_1_0" index="0" disallow="pedestrian tram rail_urban rail rail_electric rail_fast ship" speed="13.89" length="23.50" width="4.00" shape="334.85,142.96 334.83,119.45"/>
</edge>
<edge id=":94_2" function="internal">
<lane id=":94_2_0" index="0" disallow="pedestrian tram rail_urban rail rail_electric rail_fast ship" speed="13.89" length="23.50" width="4.00" shape="338.83,119.45 338.85,142.96"/>
</edge>
<edge id=":94_3" function="internal">
<lane id=":94_3_0" index="0" disallow="pedestrian tram rail_urban rail rail_electric rail_fast ship" speed="9.87" length="8.59" width="4.00" shape="338.83,119.45 338.02,125.58 336.84,127.68"/>
</edge>
<edge id=":94_6" function="internal">
<lane id=":94_6_0" index="0" disallow="pedestrian tram rail_urban rail rail_electric rail_fast ship" speed="9.87" length="13.28" width="4.00" shape="336.84,127.68 335.56,129.95 331.47,132.58 325.73,133.45"/>
</edge>
<edge id=":94_4" function="internal">
<lane id=":94_4_0" index="0" disallow="pedestrian tram rail_urban rail rail_electric rail_fast ship" speed="8.38" length="15.41" width="4.00" shape="325.73,129.45 329.71,128.83 332.56,126.95 334.27,123.83 334.83,119.45"/>
</edge>
<edge id=":94_5" function="internal">
<lane id=":94_5_0" index="0" disallow="pedestrian tram rail_urban rail rail_electric rail_fast ship" speed="9.78" length="21.47" width="4.00" shape="325.73,129.45 331.47,130.29 335.56,132.83 338.02,137.05 338.85,142.96"/>
</edge>
<edge id="-1.0.00" from="43" to="26" priority="1" type="sidewalk|shoulder|driving" shape="325.69,328.62 324.71,328.62 323.74,328.62 322.77,328.62 321.79,328.62 320.82,328.62 319.85,328.62 318.87,328.62 317.90,328.63 316.92,328.63 315.95,328.63 314.98,328.63 314.00,328.63 313.03,328.63 312.06,328.63 311.08,328.63 310.11,328.63 309.14,328.63 308.16,328.63 307.19,328.63 306.21,328.63 305.24,328.63 304.27,328.63 303.29,328.63 302.32,328.63 301.35,328.63 300.37,328.63 299.40,328.64 298.43,328.64 297.45,328.64 296.48,328.64 295.50,328.64 294.53,328.64 293.56,328.64 292.58,328.64 291.61,328.64 290.64,328.64 290.42,328.64 289.43,328.64 288.43,328.64 287.44,328.64 286.44,328.64 285.45,328.64 284.45,328.64 283.45,328.64 282.46,328.64 281.46,328.64 280.47,328.64 279.47,328.64 278.48,328.64 277.48,328.64 276.49,328.64 275.49,328.64 274.49,328.64 273.50,328.64 272.50,328.64 271.51,328.64 270.51,328.64 269.52,328.64 268.52,328.64 267.52,328.64 266.53,328.64 265.53,328.64 264.54,328.64 263.54,328.64 262.55,328.64 261.55,328.64 260.55,328.64 259.56,328.64 258.56,328.64 257.57,328.64 256.57,328.64 255.58,328.64 254.58,328.64 253.59,328.64 252.59,328.64 251.59,328.64 250.60,328.64 249.60,328.64 248.61,328.64 247.61,328.64 246.62,328.64 245.62,328.64 244.62,328.64 243.63,328.64 242.63,328.65 241.64,328.65 240.64,328.65 239.65,328.65 238.65,328.65 237.66,328.65 236.66,328.65 235.66,328.65 234.67,328.65 233.67,328.65 232.68,328.65 231.68,328.65 230.69,328.65 229.69,328.65 228.69,328.65 227.70,328.65 226.70,328.65 225.71,328.65 224.71,328.65 223.72,328.65 222.72,328.65 221.73,328.65 220.73,328.65 219.73,328.65 218.74,328.65 217.74,328.65 216.75,328.65 215.75,328.65 214.76,328.65 213.76,328.65 212.76,328.65 211.77,328.65 210.77,328.65 209.78,328.65 208.78,328.65 207.79,328.65 206.79,328.65 205.80,328.65 204.80,328.65 203.80,328.65 202.81,328.65 201.81,328.65 200.82,328.65 199.82,328.65 198.83,328.65 197.83,328.65 196.83,328.65 195.85,328.65 194.86,328.65 193.87,328.65 192.88,328.65 191.89,328.65 190.90,328.65 189.91,328.65 188.92,328.65 187.93,328.65 186.94,328.65 185.95,328.65 184.96,328.65 183.97,328.65 182.98,328.65 181.99,328.65 181.00,328.65 180.02,328.65 179.03,328.65 178.04,328.65 177.05,328.65 176.06,328.65 175.07,328.65 174.08,328.65 173.09,328.65 172.10,328.65 171.11,328.65 170.12,328.65 169.13,328.65 168.14,328.65">
<lane id="-1.0.00_0" index="0" allow="pedestrian" speed="2.78" length="157.55" width="4.00" shape="325.69,334.92 324.72,334.92 323.74,334.92 322.77,334.92 321.80,334.92 320.82,334.92 319.85,334.92 318.88,334.92 317.90,334.93 316.93,334.93 315.95,334.93 314.98,334.93 314.01,334.93 313.03,334.93 312.06,334.93 311.09,334.93 310.11,334.93 309.14,334.93 308.17,334.93 307.19,334.93 306.22,334.93 305.24,334.93 304.27,334.93 303.30,334.93 302.32,334.93 301.35,334.93 300.38,334.93 299.40,334.94 298.43,334.94 297.45,334.94 296.48,334.94 295.51,334.94 294.53,334.94 293.56,334.94 292.59,334.94 291.61,334.94 290.64,334.94 290.42,334.94 289.43,334.94 288.43,334.94 287.44,334.94 286.44,334.94 285.45,334.94 284.45,334.94 283.46,334.94 282.46,334.94 281.46,334.94 280.47,334.94 279.47,334.94 278.48,334.94 277.48,334.94 276.49,334.94 275.49,334.94 274.49,334.94 273.50,334.94 272.50,334.94 271.51,334.94 270.51,334.94 269.52,334.94 268.52,334.94 267.53,334.94 266.53,334.94 265.53,334.94 264.54,334.94 263.54,334.94 262.55,334.94 261.55,334.94 260.56,334.94 259.56,334.94 258.56,334.94 257.57,334.94 256.57,334.94 255.58,334.94 254.58,334.94 253.59,334.94 252.59,334.94 251.60,334.94 250.60,334.94 249.60,334.94 248.61,334.94 247.61,334.94 246.62,334.94 245.62,334.94 244.63,334.94 243.63,334.94 242.63,334.95 241.64,334.95 240.64,334.95 239.65,334.95 238.65,334.95 237.66,334.95 236.66,334.95 235.67,334.95 234.67,334.95 233.67,334.95 232.68,334.95 231.68,334.95 230.69,334.95 229.69,334.95 228.70,334.95 227.70,334.95 226.70,334.95 225.71,334.95 224.71,334.95 223.72,334.95 222.72,334.95 221.73,334.95 220.73,334.95 219.73,334.95 218.74,334.95 217.74,334.95 216.75,334.95 215.75,334.95 214.76,334.95 213.76,334.95 212.77,334.95 211.77,334.95 210.77,334.95 209.78,334.95 208.78,334.95 207.79,334.95 206.79,334.95 205.80,334.95 204.80,334.95 203.80,334.95 202.81,334.95 201.81,334.95 200.82,334.95 199.82,334.95 198.83,334.95 197.83,334.95 196.84,334.95 195.85,334.95 194.86,334.95 193.87,334.95 192.88,334.95 191.89,334.95 190.90,334.95 189.91,334.95 188.92,334.95 187.93,334.95 186.94,334.95 185.95,334.95 184.96,334.95 183.97,334.95 182.98,334.95 182.00,334.95 181.01,334.95 180.02,334.95 179.03,334.95 178.04,334.95 177.05,334.95 176.06,334.95 175.07,334.95 174.08,334.95 173.09,334.95 172.10,334.95 171.11,334.95 170.12,334.95 169.13,334.95 168.14,334.95" type="sidewalk"/>
<lane id="-1.0.00_1" index="1" disallow="all" speed="1.39" length="157.55" width="0.30" shape="325.69,332.77 324.72,332.77 323.74,332.77 322.77,332.77 321.80,332.77 320.82,332.77 319.85,332.77 318.87,332.77 317.90,332.78 316.93,332.78 315.95,332.78 314.98,332.78 314.01,332.78 313.03,332.78 312.06,332.78 311.08,332.78 310.11,332.78 309.14,332.78 308.16,332.78 307.19,332.78 306.22,332.78 305.24,332.78 304.27,332.78 303.30,332.78 302.32,332.78 301.35,332.78 300.37,332.78 299.40,332.79 298.43,332.79 297.45,332.79 296.48,332.79 295.51,332.79 294.53,332.79 293.56,332.79 292.59,332.79 291.61,332.79 290.64,332.79 290.42,332.79 289.43,332.79 288.43,332.79 287.44,332.79 286.44,332.79 285.45,332.79 284.45,332.79 283.45,332.79 282.46,332.79 281.46,332.79 280.47,332.79 279.47,332.79 278.48,332.79 277.48,332.79 276.49,332.79 275.49,332.79 274.49,332.79 273.50,332.79 272.50,332.79 271.51,332.79 270.51,332.79 269.52,332.79 268.52,332.79 267.52,332.79 266.53,332.79 265.53,332.79 264.54,332.79 263.54,332.79 262.55,332.79 261.55,332.79 260.56,332.79 259.56,332.79 258.56,332.79 257.57,332.79 256.57,332.79 255.58,332.79 254.58,332.79 253.59,332.79 252.59,332.79 251.59,332.79 250.60,332.79 249.60,332.79 248.61,332.79 247.61,332.79 246.62,332.79 245.62,332.79 244.63,332.79 243.63,332.79 242.63,332.80 241.64,332.80 240.64,332.80 239.65,332.80 238.65,332.80 237.66,332.80 236.66,332.80 235.66,332.80 234.67,332.80 233.67,332.80 232.68,332.80 231.68,332.80 230.69,332.80 229.69,332.80 228.70,332.80 227.70,332.80 226.70,332.80 225.71,332.80 224.71,332.80 223.72,332.80 222.72,332.80 221.73,332.80 220.73,332.80 219.73,332.80 218.74,332.80 217.74,332.80 216.75,332.80 215.75,332.80 214.76,332.80 213.76,332.80 212.77,332.80 211.77,332.80 210.77,332.80 209.78,332.80 208.78,332.80 207.79,332.80 206.79,332.80 205.80,332.80 204.80,332.80 203.80,332.80 202.81,332.80 201.81,332.80 200.82,332.80 199.82,332.80 198.83,332.80 197.83,332.80 196.84,332.80 195.85,332.80 194.86,332.80 193.87,332.80 192.88,332.80 191.89,332.80 190.90,332.80 189.91,332.80 188.92,332.80 187.93,332.80 186.94,332.80 185.95,332.80 184.96,332.80 183.97,332.80 182.98,332.80 181.99,332.80 181.01,332.80 180.02,332.80 179.03,332.80 178.04,332.80 177.05,332.80 176.06,332.80 175.07,332.80 174.08,332.80 173.09,332.80 172.10,332.80 171.11,332.80 170.12,332.80 169.13,332.80 168.14,332.80" type="shoulder"/>
<lane id="-1.0.00_2" index="2" disallow="pedestrian tram rail_urban rail rail_electric rail_fast ship" speed="13.89" length="157.55" width="4.00" shape="325.69,330.62 324.71,330.62 323.74,330.62 322.77,330.62 321.79,330.62 320.82,330.62 319.85,330.62 318.87,330.62 317.90,330.63 316.93,330.63 315.95,330.63 314.98,330.63 314.00,330.63 313.03,330.63 312.06,330.63 311.08,330.63 310.11,330.63 309.14,330.63 308.16,330.63 307.19,330.63 306.22,330.63 305.24,330.63 304.27,330.63 303.29,330.63 302.32,330.63 301.35,330.63 300.37,330.63 299.40,330.64 298.43,330.64 297.45,330.64 296.48,330.64 295.51,330.64 294.53,330.64 293.56,330.64 292.58,330.64 291.61,330.64 290.64,330.64 290.42,330.64 289.43,330.64 288.43,330.64 287.44,330.64 286.44,330.64 285.45,330.64 284.45,330.64 283.45,330.64 282.46,330.64 281.46,330.64 280.47,330.64 279.47,330.64 278.48,330.64 277.48,330.64 276.49,330.64 275.49,330.64 274.49,330.64 273.50,330.64 272.50,330.64 271.51,330.64 270.51,330.64 269.52,330.64 268.52,330.64 267.52,330.64 266.53,330.64 265.53,330.64 264.54,330.64 263.54,330.64 262.55,330.64 261.55,330.64 260.56,330.64 259.56,330.64 258.56,330.64 257.57,330.64 256.57,330.64 255.58,330.64 254.58,330.64 253.59,330.64 252.59,330.64 251.59,330.64 250.60,330.64 249.60,330.64 248.61,330.64 247.61,330.64 246.62,330.64 245.62,330.64 244.63,330.64 243.63,330.64 242.63,330.65 241.64,330.65 240.64,330.65 239.65,330.65 238.65,330.65 237.66,330.65 236.66,330.65 235.66,330.65 234.67,330.65 233.67,330.65 232.68,330.65 231.68,330.65 230.69,330.65 229.69,330.65 228.70,330.65 227.70,330.65 226.70,330.65 225.71,330.65 224.71,330.65 223.72,330.65 222.72,330.65 221.73,330.65 220.73,330.65 219.73,330.65 218.74,330.65 217.74,330.65 216.75,330.65 215.75,330.65 214.76,330.65 213.76,330.65 212.77,330.65 211.77,330.65 210.77,330.65 209.78,330.65 208.78,330.65 207.79,330.65 206.79,330.65 205.80,330.65 204.80,330.65 203.80,330.65 202.81,330.65 201.81,330.65 200.82,330.65 199.82,330.65 198.83,330.65 197.83,330.65 196.84,330.65 195.85,330.65 194.86,330.65 193.87,330.65 192.88,330.65 191.89,330.65 190.90,330.65 189.91,330.65 188.92,330.65 187.93,330.65 186.94,330.65 185.95,330.65 184.96,330.65 183.97,330.65 182.98,330.65 181.99,330.65 181.01,330.65 180.02,330.65 179.03,330.65 178.04,330.65 177.05,330.65 176.06,330.65 175.07,330.65 174.08,330.65 173.09,330.65 172.10,330.65 171.11,330.65 170.12,330.65 169.13,330.65 168.14,330.65" type="driving"/>
</edge>
<edge id="-10.0.00" from="167" to="111" priority="1" type="sidewalk|shoulder|driving" shape="167.23,271.12 325.69,271.14">
<lane id="-10.0.00_0" index="0" allow="pedestrian" speed="2.78" length="158.45" width="4.00" shape="167.23,264.82 325.69,264.84" type="sidewalk"/>
<lane id="-10.0.00_1" index="1" disallow="all" speed="1.39" length="158.45" width="0.30" shape="167.23,266.97 325.69,266.99" type="shoulder"/>
<lane id="-10.0.00_2" index="2" disallow="pedestrian tram rail_urban rail rail_electric rail_fast ship" speed="13.89" length="158.45" width="4.00" shape="167.23,269.12 325.69,269.14" type="driving"/>
</edge>
<edge id="-12.0.00" from="128" to="94" priority="1" type="sidewalk|shoulder|driving" shape="101.48,131.47 325.73,131.45">
<lane id="-12.0.00_0" index="0" allow="pedestrian" speed="2.78" length="224.24" width="4.00" shape="101.48,125.17 325.73,125.15" type="sidewalk"/>
<lane id="-12.0.00_1" index="1" disallow="all" speed="1.39" length="224.24" width="0.30" shape="101.48,127.32 325.73,127.30" type="shoulder"/>
<lane id="-12.0.00_2" index="2" disallow="pedestrian tram rail_urban rail rail_electric rail_fast ship" speed="13.89" length="224.24" width="4.00" shape="101.48,129.47 325.73,129.45" type="driving"/>
</edge>
<edge id="-14.0.00" from="8.14" to="7.14" priority="1" type="sidewalk|shoulder|driving" shape="394.41,10.07 394.41,9.49 394.41,8.90 394.35,7.90 394.18,6.92 393.89,5.96 393.49,5.05 392.98,4.19 392.38,3.39 391.68,2.67 391.53,2.53 390.75,1.91 389.91,1.37 389.02,0.91 388.09,0.54 387.13,0.27 386.14,0.09 385.15,0.01 384.81,0.00 384.14,0.00">
<lane id="-14.0.00_0" index="0" allow="pedestrian" speed="2.78" length="1.83" width="4.00" shape="387.57,7.48 387.20,7.10 387.56,7.42 387.17,7.11" type="sidewalk"/>
<lane id="-14.0.00_1" index="1" disallow="all" speed="1.39" length="1.83" width="0.30" shape="389.43,6.38 389.22,6.09 388.73,5.59 388.91,5.75 388.50,5.43" type="shoulder"/>
<lane id="-14.0.00_2" index="2" disallow="pedestrian tram rail_urban rail rail_electric rail_fast ship" speed="13.89" length="1.83" width="4.00" shape="391.30,5.28 390.85,4.69 390.26,4.08 389.84,3.74" type="driving"/>
</edge>
<edge id="-16.0.00" from="43" to="111" priority="1" type="sidewalk|shoulder|driving" shape="336.95,317.82 336.93,282.19">
<lane id="-16.0.00_0" index="0" allow="pedestrian" speed="2.78" length="35.62" width="4.00" shape="330.65,317.82 330.63,282.20" type="sidewalk"/>
<lane id="-16.0.00_1" index="1" disallow="all" speed="1.39" length="35.62" width="0.30" shape="332.80,317.82 332.78,282.20" type="shoulder"/>
<lane id="-16.0.00_2" index="2" disallow="pedestrian tram rail_urban rail rail_electric rail_fast ship" speed="13.89" length="35.62" width="4.00" shape="334.95,317.82 334.93,282.20" type="driving"/>
</edge>
<edge id="-17.0.00" from="111" to="139" priority="1" type="sidewalk|shoulder|driving" shape="336.92,259.58 336.89,208.03">
<lane id="-17.0.00_0" index="0" allow="pedestrian" speed="2.78" length="51.55" width="4.00" shape="330.62,259.58 330.59,208.04" type="sidewalk"/>
<lane id="-17.0.00_1" index="1" disallow="all" speed="1.39" length="51.55" width="0.30" shape="332.77,259.58 332.74,208.04" type="shoulder"/>
<lane id="-17.0.00_2" index="2" disallow="pedestrian tram rail_urban rail rail_electric rail_fast ship" speed="13.89" length="51.55" width="4.00" shape="334.92,259.58 334.89,208.03" type="driving"/>
</edge>
<edge id="-18.0.00" from="139" to="94" priority="1" type="sidewalk|shoulder|driving" shape="336.87,184.94 336.85,142.96">
<lane id="-18.0.00_0" index="0" allow="pedestrian" speed="2.78" length="41.99" width="4.00" shape="330.57,184.95 330.55,142.96" type="sidewalk"/>
<lane id="-18.0.00_1" index="1" disallow="all" speed="1.39" length="41.99" width="0.30" shape="332.72,184.95 332.70,142.96" type="shoulder"/>
<lane id="-18.0.00_2" index="2" disallow="pedestrian tram rail_urban rail rail_electric rail_fast ship" speed="13.89" length="41.99" width="4.00" shape="334.87,184.94 334.85,142.96" type="driving"/>
</edge>
<edge id="-19.0.00" from="94" to="60" priority="1" type="sidewalk|shoulder|driving" shape="336.83,119.45 336.77,11.16">
<lane id="-19.0.00_0" index="0" allow="pedestrian" speed="2.78" length="108.29" width="4.00" shape="330.53,119.46 330.47,11.16" type="sidewalk"/>
<lane id="-19.0.00_1" index="1" disallow="all" speed="1.39" length="108.29" width="0.30" shape="332.68,119.46 332.62,11.16" type="shoulder"/>
<lane id="-19.0.00_2" index="2" disallow="pedestrian tram rail_urban rail rail_electric rail_fast ship" speed="13.89" length="108.29" width="4.00" shape="334.83,119.45 334.77,11.16" type="driving"/>
</edge>
<edge id="-2.0.00" from="26" to="77" priority="1" type="sidewalk|shoulder|driving" shape="145.02,328.66 144.02,328.66 143.03,328.66 142.03,328.66 141.04,328.66 140.04,328.66 139.05,328.66 138.05,328.66 137.06,328.66 136.07,328.66 135.07,328.66 134.08,328.66 133.08,328.66 132.09,328.66 131.09,328.66 130.10,328.66 129.10,328.66 128.11,328.66 127.12,328.66 126.12,328.66 125.13,328.66 124.13,328.66 123.14,328.66 122.14,328.66 121.15,328.66 120.15,328.66 119.16,328.66 118.17,328.66 117.17,328.66 116.18,328.66 115.18,328.66 114.19,328.66 113.19,328.66 112.20,328.66 111.20,328.66 110.21,328.66 109.21,328.66 108.22,328.66 107.23,328.66 106.23,328.66 105.24,328.66 104.24,328.66 103.25,328.66 103.03,328.66 102.75,328.66">
<lane id="-2.0.00_0" index="0" allow="pedestrian" speed="2.78" length="42.26" width="4.00" shape="145.02,334.96 144.02,334.96 143.03,334.96 142.03,334.96 141.04,334.96 140.04,334.96 139.05,334.96 138.06,334.96 137.06,334.96 136.07,334.96 135.07,334.96 134.08,334.96 133.08,334.96 132.09,334.96 131.09,334.96 130.10,334.96 129.10,334.96 128.11,334.96 127.12,334.96 126.12,334.96 125.13,334.96 124.13,334.96 123.14,334.96 122.14,334.96 121.15,334.96 120.15,334.96 119.16,334.96 118.17,334.96 117.17,334.96 116.18,334.96 115.18,334.96 114.19,334.96 113.19,334.96 112.20,334.96 111.20,334.96 110.21,334.96 109.22,334.96 108.22,334.96 107.23,334.96 106.23,334.96 105.24,334.96 104.24,334.96 103.25,334.96 103.03,334.96 102.75,334.96" type="sidewalk"/>
<lane id="-2.0.00_1" index="1" disallow="all" speed="1.39" length="42.26" width="0.30" shape="145.02,332.81 144.02,332.81 143.03,332.81 142.03,332.81 141.04,332.81 140.04,332.81 139.05,332.81 138.05,332.81 137.06,332.81 136.07,332.81 135.07,332.81 134.08,332.81 133.08,332.81 132.09,332.81 131.09,332.81 130.10,332.81 129.10,332.81 128.11,332.81 127.12,332.81 126.12,332.81 125.13,332.81 124.13,332.81 123.14,332.81 122.14,332.81 121.15,332.81 120.15,332.81 119.16,332.81 118.17,332.81 117.17,332.81 116.18,332.81 115.18,332.81 114.19,332.81 113.19,332.81 112.20,332.81 111.20,332.81 110.21,332.81 109.22,332.81 108.22,332.81 107.23,332.81 106.23,332.81 105.24,332.81 104.24,332.81 103.25,332.81 103.03,332.81 102.75,332.81" type="shoulder"/>
<lane id="-2.0.00_2" index="2" disallow="pedestrian tram rail_urban rail rail_electric rail_fast ship" speed="13.89" length="42.26" width="4.00" shape="145.02,330.66 144.02,330.66 143.03,330.66 142.03,330.66 141.04,330.66 140.04,330.66 139.05,330.66 138.05,330.66 137.06,330.66 136.07,330.66 135.07,330.66 134.08,330.66 133.08,330.66 132.09,330.66 131.09,330.66 130.10,330.66 129.10,330.66 128.11,330.66 127.12,330.66 126.12,330.66 125.13,330.66 124.13,330.66 123.14,330.66 122.14,330.66 121.15,330.66 120.15,330.66 119.16,330.66 118.17,330.66 117.17,330.66 116.18,330.66 115.18,330.66 114.19,330.66 113.19,330.66 112.20,330.66 111.20,330.66 110.21,330.66 109.22,330.66 108.22,330.66 107.23,330.66 106.23,330.66 105.24,330.66 104.24,330.66 103.25,330.66 103.03,330.66 102.75,330.66" type="driving"/>
</edge>
<edge id="-21.0.00" from="77" to="184" priority="1" type="sidewalk|shoulder|driving" shape="90.43,317.94 90.44,282.46">
<lane id="-21.0.00_0" index="0" allow="pedestrian" speed="2.78" length="35.49" width="4.00" shape="84.13,317.94 84.14,282.46" type="sidewalk"/>
<lane id="-21.0.00_1" index="1" disallow="all" speed="1.39" length="35.49" width="0.30" shape="86.28,317.94 86.29,282.46" type="shoulder"/>
<lane id="-21.0.00_2" index="2" disallow="pedestrian tram rail_urban rail rail_electric rail_fast ship" speed="13.89" length="35.49" width="4.00" shape="88.43,317.94 88.44,282.46" type="driving"/>
</edge>
<edge id="-22.0.00" from="184" to="156" priority="1" type="sidewalk|shoulder|driving" shape="90.44,260.46 90.45,208.77">
<lane id="-22.0.00_0" index="0" allow="pedestrian" speed="2.78" length="51.68" width="4.00" shape="84.14,260.46 84.15,208.77" type="sidewalk"/>
<lane id="-22.0.00_1" index="1" disallow="all" speed="1.39" length="51.68" width="0.30" shape="86.29,260.46 86.30,208.77" type="shoulder"/>
<lane id="-22.0.00_2" index="2" disallow="pedestrian tram rail_urban rail rail_electric rail_fast ship" speed="13.89" length="51.68" width="4.00" shape="88.44,260.46 88.45,208.77" type="driving"/>
</edge>
<edge id="-23.0.00" from="156" to="128" priority="1" type="sidewalk|shoulder|driving" shape="90.45,186.77 90.46,142.28">
<lane id="-23.0.00_0" index="0" allow="pedestrian" speed="2.78" length="44.49" width="4.00" shape="84.15,186.77 84.16,142.28" type="sidewalk"/>
<lane id="-23.0.00_1" index="1" disallow="all" speed="1.39" length="44.49" width="0.30" shape="86.30,186.77 86.31,142.28" type="shoulder"/>
<lane id="-23.0.00_2" index="2" disallow="pedestrian tram rail_urban rail rail_electric rail_fast ship" speed="13.89" length="44.49" width="4.00" shape="88.45,186.77 88.46,142.28" type="driving"/>
</edge>
<edge id="-24.0.00" from="128" to="195" priority="1" type="sidewalk|shoulder|driving" shape="90.46,120.28 90.48,11.31">
<lane id="-24.0.00_0" index="0" allow="pedestrian" speed="2.78" length="108.98" width="4.00" shape="84.16,120.28 84.18,11.31" type="sidewalk"/>
<lane id="-24.0.00_1" index="1" disallow="all" speed="1.39" length="108.98" width="0.30" shape="86.31,120.28 86.33,11.31" type="shoulder"/>
<lane id="-24.0.00_2" index="2" disallow="pedestrian tram rail_urban rail rail_electric rail_fast ship" speed="13.89" length="108.98" width="4.00" shape="88.46,120.28 88.48,11.31" type="driving"/>
</edge>
<edge id="-25.0.00" from="26" to="167" priority="1" type="sidewalk|shoulder|driving" shape="156.13,317.90 156.08,282.41">
<lane id="-25.0.00_0" index="0" allow="pedestrian" speed="2.78" length="35.49" width="4.00" shape="149.83,317.91 149.78,282.42" type="sidewalk"/>
<lane id="-25.0.00_1" index="1" disallow="all" speed="1.39" length="35.49" width="0.30" shape="151.98,317.91 151.93,282.42" type="shoulder"/>
<lane id="-25.0.00_2" index="2" disallow="pedestrian tram rail_urban rail rail_electric rail_fast ship" speed="13.89" length="35.49" width="4.00" shape="154.13,317.90 154.08,282.42" type="driving"/>
</edge>
<edge id="-3.0.00" from="77" to="195" priority="1" type="sidewalk|shoulder|driving" shape="79.44,328.65 11.09,328.63 10.19,328.63 9.21,328.63 8.21,328.57 7.22,328.41 6.26,328.15 5.33,327.79 4.43,327.34 3.59,326.80 2.81,326.18 2.13,325.51 1.51,324.73 0.99,323.88 0.57,322.97 0.27,322.01 0.09,321.03 0.03,320.03 0.03,319.34 0.03,318.65 0.03,317.65 0.03,316.66 0.03,315.66 0.03,314.67 0.03,313.67 0.03,312.68 0.03,311.68 0.03,310.69 0.03,309.69 0.03,308.69 0.03,307.70 0.03,306.70 0.02,305.71 0.02,304.71 0.02,303.72 0.02,302.72 0.02,301.73 0.02,300.73 0.02,299.73 0.02,298.74 0.02,297.74 0.02,296.75 0.02,295.75 0.02,294.76 0.02,293.76 0.02,292.77 0.02,291.77 0.02,290.77 0.02,289.78 0.02,288.78 0.02,287.79 0.02,286.79 0.02,285.80 0.02,284.80 0.02,283.81 0.02,282.81 0.02,281.81 0.02,280.82 0.01,279.82 0.01,278.83 0.01,277.83 0.01,276.84 0.01,275.84 0.01,274.85 0.01,273.85 0.01,272.85 0.01,271.86 0.01,270.86 0.01,269.87 0.01,268.87 0.01,267.88 0.01,266.88 0.01,265.89 0.01,264.89 0.01,263.89 0.01,262.90 0.01,261.90 0.01,260.91 0.01,259.91 0.01,258.92 0.01,257.92 0.01,256.93 0.01,255.93 0.01,254.93 0.00,253.94 0.00,252.94 0.00,251.95 0.00,250.95 0.00,249.96 0.00,248.96 0.00,247.97 0.00,246.97 0.00,245.97 0.00,244.98 0.00,243.98 0.00,242.99 0.00,241.99 0.00,241.00 0.00,240.54 0.00,239.55 0.00,238.56 0.00,237.57 0.00,236.58 0.00,235.58 0.00,234.59 0.00,233.60 0.00,232.61 0.00,231.62 0.01,230.63 0.01,229.63 0.01,228.64 0.01,227.65 0.01,226.66 0.01,225.67 0.01,224.68 0.01,223.68 0.01,222.69 0.01,221.70 0.01,220.71 0.01,219.72 0.01,218.73 0.01,217.73 0.01,216.74 0.01,215.75 0.01,214.76 0.01,213.77 0.01,212.78 0.02,211.78 0.02,210.79 0.02,209.80 0.02,208.81 0.02,207.82 0.02,206.83 0.02,205.83 0.02,204.84 0.02,203.85 0.02,202.86 0.02,201.87 0.02,200.88 0.02,199.88 0.02,198.89 0.02,197.90 0.02,196.91 0.02,195.92 0.02,194.93 0.02,193.93 0.02,192.94 0.03,191.95 0.03,190.96 0.03,189.97 0.03,188.98 0.03,187.98 0.03,186.99 0.03,186.00 0.03,185.01 0.03,184.02 0.03,183.03 0.03,182.03 0.03,181.04 0.03,180.05 0.03,179.06 0.03,178.07 0.03,177.08 0.03,176.08 0.03,175.09 0.03,174.10 0.04,173.11 0.04,172.12 0.04,171.13 0.04,170.13 0.04,169.14 0.04,168.15 0.04,167.16 0.04,166.17 0.04,165.18 0.04,164.18 0.04,163.19 0.04,162.20 0.04,161.21 0.04,160.22 0.04,159.22 0.04,158.23 0.04,157.24 0.04,156.25 0.04,155.25 0.05,154.26 0.05,153.27 0.05,152.28 0.05,151.28 0.05,150.29 0.05,149.30 0.05,148.31 0.05,147.31 0.05,146.32 0.05,145.33 0.05,144.34 0.05,143.34 0.05,142.35 0.05,141.36 0.05,140.37 0.05,139.37 0.05,138.38 0.05,137.39 0.05,136.40 0.05,135.40 0.06,134.41 0.06,133.42 0.06,132.43 0.06,131.43 0.06,130.44 0.06,129.45 0.06,128.46 0.06,127.46 0.06,126.47 0.06,125.48 0.06,124.49 0.06,123.49 0.06,122.50 0.06,121.51 0.06,120.52 0.06,119.52 0.06,118.53 0.06,117.54 0.06,116.55 0.07,115.55 0.07,114.56 0.07,113.57 0.07,112.58 0.07,111.58 0.07,110.59 0.07,109.60 0.07,108.61 0.07,107.61 0.07,106.62 0.07,105.63 0.07,104.64 0.07,103.64 0.07,102.65 0.07,101.66 0.07,100.67 0.07,99.67 0.07,98.68 0.07,97.69 0.08,96.70 0.08,95.70 0.08,94.71 0.08,93.72 0.08,92.73 0.08,91.73 0.08,90.74 0.08,89.75 0.08,88.76 0.08,87.76 0.08,87.44 0.08,86.44 0.08,85.45 0.08,84.46 0.08,83.47 0.08,82.47 0.08,81.48 0.08,80.49 0.08,79.50 0.08,78.50 0.08,77.51 0.08,76.52 0.08,75.53 0.08,74.53 0.08,73.54 0.08,72.55 0.08,71.56 0.08,70.56 0.08,69.57 0.08,68.58 0.08,67.59 0.08,66.59 0.08,65.60 0.08,64.61 0.08,63.62 0.08,62.62 0.08,61.63 0.08,60.64 0.08,59.65 0.08,58.65 0.08,57.66 0.08,56.67 0.08,55.67 0.08,54.68 0.08,53.69 0.08,52.70 0.08,51.70 0.08,50.71 0.07,49.72 0.07,48.73 0.07,47.73 0.07,46.74 0.07,45.75 0.07,44.76 0.07,43.76 0.07,42.77 0.07,41.78 0.07,40.79 0.07,39.79 0.07,38.80 0.07,37.81 0.07,36.82 0.07,35.82 0.07,34.83 0.07,33.84 0.07,32.85 0.07,31.85 0.07,30.86 0.07,29.87 0.07,28.88 0.07,27.88 0.07,26.89 0.07,25.90 0.07,24.91 0.07,23.91 0.07,22.92 0.07,21.93 0.07,20.94 0.07,19.94 0.07,18.95 0.07,17.96 0.07,16.97 0.07,15.97 0.07,14.98 0.07,13.99 0.07,13.00 0.07,12.00 0.07,11.01 0.07,10.60 0.11,9.67 0.23,8.68 0.44,7.70 0.73,6.74 1.10,5.82 1.55,4.92 2.08,4.07 2.68,3.27 3.15,2.74 3.88,2.06 4.69,1.47 5.56,0.98 6.48,0.58 7.44,0.30 8.42,0.13 9.42,0.07 10.07,0.07 79.47,0.03">
<lane id="-3.0.00_0" index="0" allow="pedestrian" speed="2.78" length="492.34" width="4.00" shape="79.43,334.95 11.09,334.93 10.19,334.93 9.02,334.93 7.52,334.84 5.89,334.58 4.31,334.15 2.77,333.56 1.31,332.82 -0.08,331.94 -1.38,330.90 -2.57,329.72 -3.66,328.34 -4.59,326.84 -5.32,325.23 -5.85,323.54 -6.17,321.80 -6.27,320.26 -6.27,319.34 -6.27,318.65 -6.27,317.66 -6.27,316.66 -6.27,315.67 -6.27,314.67 -6.27,313.67 -6.27,312.68 -6.27,311.68 -6.27,310.69 -6.27,309.69 -6.27,308.70 -6.27,307.70 -6.27,306.71 -6.28,305.71 -6.28,304.71 -6.28,303.72 -6.28,302.72 -6.28,301.73 -6.28,300.73 -6.28,299.74 -6.28,298.74 -6.28,297.75 -6.28,296.75 -6.28,295.75 -6.28,294.76 -6.28,293.76 -6.28,292.77 -6.28,291.77 -6.28,290.78 -6.28,289.78 -6.28,288.79 -6.28,287.79 -6.28,286.79 -6.28,285.80 -6.28,284.80 -6.28,283.81 -6.28,282.81 -6.28,281.82 -6.28,280.82 -6.29,279.83 -6.29,278.83 -6.29,277.83 -6.29,276.84 -6.29,275.84 -6.29,274.85 -6.29,273.85 -6.29,272.86 -6.29,271.86 -6.29,270.87 -6.29,269.87 -6.29,268.87 -6.29,267.88 -6.29,266.88 -6.29,265.89 -6.29,264.89 -6.29,263.90 -6.29,262.90 -6.29,261.91 -6.29,260.91 -6.29,259.91 -6.29,258.92 -6.29,257.92 -6.29,256.93 -6.29,255.93 -6.29,254.94 -6.30,253.94 -6.30,252.95 -6.30,251.95 -6.30,250.95 -6.30,249.96 -6.30,248.96 -6.30,247.97 -6.30,246.97 -6.30,245.98 -6.30,244.98 -6.30,243.99 -6.30,242.99 -6.30,241.99 -6.30,241.00 -6.30,240.54 -6.30,239.55 -6.30,238.56 -6.30,237.56 -6.30,236.57 -6.30,235.58 -6.30,234.59 -6.30,233.60 -6.30,232.61 -6.30,231.61 -6.29,230.62 -6.29,229.63 -6.29,228.64 -6.29,227.65 -6.29,226.66 -6.29,225.66 -6.29,224.67 -6.29,223.68 -6.29,222.69 -6.29,221.70 -6.29,220.71 -6.29,219.71 -6.29,218.72 -6.29,217.73 -6.29,216.74 -6.29,215.75 -6.29,214.76 -6.29,213.76 -6.29,212.77 -6.28,211.78 -6.28,210.79 -6.28,209.80 -6.28,208.81 -6.28,207.81 -6.28,206.82 -6.28,205.83 -6.28,204.84 -6.28,203.85 -6.28,202.86 -6.28,201.86 -6.28,200.87 -6.28,199.88 -6.28,198.89 -6.28,197.90 -6.28,196.91 -6.28,195.91 -6.28,194.92 -6.28,193.93 -6.28,192.94 -6.27,191.95 -6.27,190.96 -6.27,189.96 -6.27,188.97 -6.27,187.98 -6.27,186.99 -6.27,186.00 -6.27,185.01 -6.27,184.01 -6.27,183.02 -6.27,182.03 -6.27,181.04 -6.27,180.05 -6.27,179.06 -6.27,178.06 -6.27,177.07 -6.27,176.08 -6.27,175.09 -6.27,174.10 -6.26,173.11 -6.26,172.12 -6.26,171.12 -6.26,170.13 -6.26,169.14 -6.26,168.15 -6.26,167.16 -6.26,166.17 -6.26,165.17 -6.26,164.18 -6.26,163.19 -6.26,162.20 -6.26,161.20 -6.26,160.21 -6.26,159.22 -6.26,158.23 -6.26,157.23 -6.26,156.24 -6.26,155.25 -6.25,154.26 -6.25,153.26 -6.25,152.27 -6.25,151.28 -6.25,150.29 -6.25,149.29 -6.25,148.30 -6.25,147.31 -6.25,146.32 -6.25,145.32 -6.25,144.33 -6.25,143.34 -6.25,142.35 -6.25,141.35 -6.25,140.36 -6.25,139.37 -6.25,138.38 -6.25,137.38 -6.25,136.39 -6.25,135.40 -6.24,134.41 -6.24,133.41 -6.24,132.42 -6.24,131.43 -6.24,130.44 -6.24,129.44 -6.24,128.45 -6.24,127.46 -6.24,126.47 -6.24,125.47 -6.24,124.48 -6.24,123.49 -6.24,122.50 -6.24,121.50 -6.24,120.51 -6.24,119.52 -6.24,118.53 -6.24,117.53 -6.24,116.54 -6.23,115.55 -6.23,114.56 -6.23,113.56 -6.23,112.57 -6.23,111.58 -6.23,110.59 -6.23,109.59 -6.23,108.60 -6.23,107.61 -6.23,106.62 -6.23,105.62 -6.23,104.63 -6.23,103.64 -6.23,102.65 -6.23,101.65 -6.23,100.66 -6.23,99.67 -6.23,98.68 -6.23,97.68 -6.22,96.69 -6.22,95.70 -6.22,94.71 -6.22,93.71 -6.22,92.72 -6.22,91.73 -6.22,90.74 -6.22,89.74 -6.22,88.75 -6.22,87.76 -6.22,87.44 -6.22,86.45 -6.22,85.45 -6.22,84.46 -6.22,83.47 -6.22,82.47 -6.22,81.48 -6.22,80.49 -6.22,79.50 -6.22,78.50 -6.22,77.51 -6.22,76.52 -6.22,75.53 -6.22,74.53 -6.22,73.54 -6.22,72.55 -6.22,71.56 -6.22,70.56 -6.22,69.57 -6.22,68.58 -6.22,67.59 -6.22,66.59 -6.22,65.60 -6.22,64.61 -6.22,63.62 -6.22,62.62 -6.22,61.63 -6.22,60.64 -6.22,59.65 -6.22,58.65 -6.22,57.66 -6.22,56.67 -6.22,55.68 -6.22,54.68 -6.22,53.69 -6.22,52.70 -6.22,51.71 -6.22,50.71 -6.23,49.72 -6.23,48.73 -6.23,47.74 -6.23,46.74 -6.23,45.75 -6.23,44.76 -6.23,43.77 -6.23,42.77 -6.23,41.78 -6.23,40.79 -6.23,39.79 -6.23,38.80 -6.23,37.81 -6.23,36.82 -6.23,35.82 -6.23,34.83 -6.23,33.84 -6.23,32.85 -6.23,31.85 -6.23,30.86 -6.23,29.87 -6.23,28.88 -6.23,27.88 -6.23,26.89 -6.23,25.90 -6.23,24.91 -6.23,23.91 -6.23,22.92 -6.23,21.93 -6.23,20.94 -6.23,19.94 -6.23,18.95 -6.23,17.96 -6.23,16.97 -6.23,15.97 -6.23,14.98 -6.23,13.99 -6.23,13.00 -6.23,12.00 -6.23,11.01 -6.23,10.43 -6.17,9.15 -5.98,7.63 -5.66,6.12 -5.21,4.65 -4.64,3.22 -3.94,1.84 -3.13,0.53 -2.24,-0.67 -1.32,-1.70 -0.13,-2.81 1.26,-3.83 2.76,-4.68 4.34,-5.35 6.00,-5.84 7.69,-6.14 9.20,-6.23 10.07,-6.23 79.47,-6.27" type="sidewalk"/>
<lane id="-3.0.00_1" index="1" disallow="all" speed="1.39" length="492.34" width="0.30" shape="79.44,332.80 11.09,332.78 10.19,332.78 9.08,332.78 7.75,332.70 6.35,332.47 4.97,332.10 3.65,331.59 2.37,330.95 1.18,330.18 0.05,329.29 -0.96,328.29 -1.90,327.11 -2.68,325.83 -3.31,324.45 -3.76,323.02 -4.03,321.54 -4.12,320.18 -4.12,319.34 -4.12,318.65 -4.12,317.66 -4.12,316.66 -4.12,315.66 -4.12,314.67 -4.12,313.67 -4.12,312.68 -4.12,311.68 -4.12,310.69 -4.12,309.69 -4.12,308.70 -4.12,307.70 -4.12,306.70 -4.13,305.71 -4.13,304.71 -4.13,303.72 -4.13,302.72 -4.13,301.73 -4.13,300.73 -4.13,299.74 -4.13,298.74 -4.13,297.74 -4.13,296.75 -4.13,295.75 -4.13,294.76 -4.13,293.76 -4.13,292.77 -4.13,291.77 -4.13,290.78 -4.13,289.78 -4.13,288.78 -4.13,287.79 -4.13,286.79 -4.13,285.80 -4.13,284.80 -4.13,283.81 -4.13,282.81 -4.13,281.82 -4.13,280.82 -4.14,279.83 -4.14,278.83 -4.14,277.83 -4.14,276.84 -4.14,275.84 -4.14,274.85 -4.14,273.85 -4.14,272.86 -4.14,271.86 -4.14,270.87 -4.14,269.87 -4.14,268.87 -4.14,267.88 -4.14,266.88 -4.14,265.89 -4.14,264.89 -4.14,263.90 -4.14,262.90 -4.14,261.91 -4.14,260.91 -4.14,259.91 -4.14,258.92 -4.14,257.92 -4.14,256.93 -4.14,255.93 -4.14,254.94 -4.15,253.94 -4.15,252.95 -4.15,251.95 -4.15,250.95 -4.15,249.96 -4.15,248.96 -4.15,247.97 -4.15,246.97 -4.15,245.98 -4.15,244.98 -4.15,243.99 -4.15,242.99 -4.15,241.99 -4.15,241.00 -4.15,240.54 -4.15,239.55 -4.15,238.56 -4.15,237.57 -4.15,236.57 -4.15,235.58 -4.15,234.59 -4.15,233.60 -4.15,232.61 -4.15,231.62 -4.14,230.62 -4.14,229.63 -4.14,228.64 -4.14,227.65 -4.14,226.66 -4.14,225.67 -4.14,224.67 -4.14,223.68 -4.14,222.69 -4.14,221.70 -4.14,220.71 -4.14,219.72 -4.14,218.72 -4.14,217.73 -4.14,216.74 -4.14,215.75 -4.14,214.76 -4.14,213.77 -4.14,212.77 -4.13,211.78 -4.13,210.79 -4.13,209.80 -4.13,208.81 -4.13,207.82 -4.13,206.82 -4.13,205.83 -4.13,204.84 -4.13,203.85 -4.13,202.86 -4.13,201.87 -4.13,200.87 -4.13,199.88 -4.13,198.89 -4.13,197.90 -4.13,196.91 -4.13,195.92 -4.13,194.92 -4.13,193.93 -4.13,192.94 -4.12,191.95 -4.12,190.96 -4.12,189.97 -4.12,188.97 -4.12,187.98 -4.12,186.99 -4.12,186.00 -4.12,185.01 -4.12,184.02 -4.12,183.02 -4.12,182.03 -4.12,181.04 -4.12,180.05 -4.12,179.06 -4.12,178.07 -4.12,177.07 -4.12,176.08 -4.12,175.09 -4.12,174.10 -4.11,173.11 -4.11,172.12 -4.11,171.12 -4.11,170.13 -4.11,169.14 -4.11,168.15 -4.11,167.16 -4.11,166.17 -4.11,165.17 -4.11,164.18 -4.11,163.19 -4.11,162.20 -4.11,161.21 -4.11,160.21 -4.11,159.22 -4.11,158.23 -4.11,157.24 -4.11,156.24 -4.11,155.25 -4.10,154.26 -4.10,153.27 -4.10,152.27 -4.10,151.28 -4.10,150.29 -4.10,149.30 -4.10,148.30 -4.10,147.31 -4.10,146.32 -4.10,145.33 -4.10,144.33 -4.10,143.34 -4.10,142.35 -4.10,141.36 -4.10,140.36 -4.10,139.37 -4.10,138.38 -4.10,137.39 -4.10,136.39 -4.10,135.40 -4.09,134.41 -4.09,133.42 -4.09,132.42 -4.09,131.43 -4.09,130.44 -4.09,129.45 -4.09,128.45 -4.09,127.46 -4.09,126.47 -4.09,125.48 -4.09,124.48 -4.09,123.49 -4.09,122.50 -4.09,121.51 -4.09,120.51 -4.09,119.52 -4.09,118.53 -4.09,117.54 -4.09,116.54 -4.08,115.55 -4.08,114.56 -4.08,113.57 -4.08,112.57 -4.08,111.58 -4.08,110.59 -4.08,109.60 -4.08,108.60 -4.08,107.61 -4.08,106.62 -4.08,105.63 -4.08,104.63 -4.08,103.64 -4.08,102.65 -4.08,101.66 -4.08,100.66 -4.08,99.67 -4.08,98.68 -4.08,97.69 -4.07,96.69 -4.07,95.70 -4.07,94.71 -4.07,93.72 -4.07,92.72 -4.07,91.73 -4.07,90.74 -4.07,89.75 -4.07,88.75 -4.07,87.76 -4.07,87.44 -4.07,86.44 -4.07,85.45 -4.07,84.46 -4.07,83.47 -4.07,82.47 -4.07,81.48 -4.07,80.49 -4.07,79.50 -4.07,78.50 -4.07,77.51 -4.07,76.52 -4.07,75.53 -4.07,74.53 -4.07,73.54 -4.07,72.55 -4.07,71.56 -4.07,70.56 -4.07,69.57 -4.07,68.58 -4.07,67.59 -4.07,66.59 -4.07,65.60 -4.07,64.61 -4.07,63.62 -4.07,62.62 -4.07,61.63 -4.07,60.64 -4.07,59.65 -4.07,58.65 -4.07,57.66 -4.07,56.67 -4.07,55.68 -4.07,54.68 -4.07,53.69 -4.07,52.70 -4.07,51.71 -4.07,50.71 -4.08,49.72 -4.08,48.73 -4.08,47.74 -4.08,46.74 -4.08,45.75 -4.08,44.76 -4.08,43.76 -4.08,42.77 -4.08,41.78 -4.08,40.79 -4.08,39.79 -4.08,38.80 -4.08,37.81 -4.08,36.82 -4.08,35.82 -4.08,34.83 -4.08,33.84 -4.08,32.85 -4.08,31.85 -4.08,30.86 -4.08,29.87 -4.08,28.88 -4.08,27.88 -4.08,26.89 -4.08,25.90 -4.08,24.91 -4.08,23.91 -4.08,22.92 -4.08,21.93 -4.08,20.94 -4.08,19.94 -4.08,18.95 -4.08,17.96 -4.08,16.97 -4.08,15.97 -4.08,14.98 -4.08,13.99 -4.08,13.00 -4.08,12.00 -4.08,11.01 -4.08,10.49 -4.03,9.32 -3.86,7.99 -3.58,6.66 -3.18,5.36 -2.68,4.10 -2.06,2.89 -1.35,1.74 -0.56,0.68 0.21,-0.19 1.24,-1.14 2.43,-2.02 3.71,-2.75 5.07,-3.33 6.49,-3.75 7.94,-4.00 9.27,-4.08 10.07,-4.08 79.47,-4.12" type="shoulder"/>
<lane id="-3.0.00_2" index="2" disallow="pedestrian tram rail_urban rail rail_electric rail_fast ship" speed="13.89" length="492.34" width="4.00" shape="79.44,330.65 11.09,330.63 10.19,330.63 9.15,330.63 7.99,330.56 6.80,330.37 5.64,330.05 4.52,329.62 3.44,329.08 2.43,328.43 1.48,327.68 0.64,326.85 -0.13,325.88 -0.78,324.82 -1.30,323.68 -1.67,322.50 -1.90,321.27 -1.97,320.11 -1.97,319.34 -1.97,318.65 -1.97,317.66 -1.97,316.66 -1.97,315.66 -1.97,314.67 -1.97,313.67 -1.97,312.68 -1.97,311.68 -1.97,310.69 -1.97,309.69 -1.97,308.70 -1.97,307.70 -1.97,306.70 -1.98,305.71 -1.98,304.71 -1.98,303.72 -1.98,302.72 -1.98,301.73 -1.98,300.73 -1.98,299.74 -1.98,298.74 -1.98,297.74 -1.98,296.75 -1.98,295.75 -1.98,294.76 -1.98,293.76 -1.98,292.77 -1.98,291.77 -1.98,290.78 -1.98,289.78 -1.98,288.78 -1.98,287.79 -1.98,286.79 -1.98,285.80 -1.98,284.80 -1.98,283.81 -1.98,282.81 -1.98,281.82 -1.98,280.82 -1.99,279.82 -1.99,278.83 -1.99,277.83 -1.99,276.84 -1.99,275.84 -1.99,274.85 -1.99,273.85 -1.99,272.86 -1.99,271.86 -1.99,270.86 -1.99,269.87 -1.99,268.87 -1.99,267.88 -1.99,266.88 -1.99,265.89 -1.99,264.89 -1.99,263.90 -1.99,262.90 -1.99,261.90 -1.99,260.91 -1.99,259.91 -1.99,258.92 -1.99,257.92 -1.99,256.93 -1.99,255.93 -1.99,254.94 -2.00,253.94 -2.00,252.94 -2.00,251.95 -2.00,250.95 -2.00,249.96 -2.00,248.96 -2.00,247.97 -2.00,246.97 -2.00,245.98 -2.00,244.98 -2.00,243.98 -2.00,242.99 -2.00,241.99 -2.00,241.00 -2.00,240.54 -2.00,239.55 -2.00,238.56 -2.00,237.57 -2.00,236.58 -2.00,235.58 -2.00,234.59 -2.00,233.60 -2.00,232.61 -2.00,231.62 -1.99,230.63 -1.99,229.63 -1.99,228.64 -1.99,227.65 -1.99,226.66 -1.99,225.67 -1.99,224.68 -1.99,223.68 -1.99,222.69 -1.99,221.70 -1.99,220.71 -1.99,219.72 -1.99,218.73 -1.99,217.73 -1.99,216.74 -1.99,215.75 -1.99,214.76 -1.99,213.77 -1.99,212.78 -1.98,211.78 -1.98,210.79 -1.98,209.80 -1.98,208.81 -1.98,207.82 -1.98,206.83 -1.98,205.83 -1.98,204.84 -1.98,203.85 -1.98,202.86 -1.98,201.87 -1.98,200.88 -1.98,199.88 -1.98,198.89 -1.98,197.90 -1.98,196.91 -1.98,195.92 -1.98,194.93 -1.98,193.93 -1.98,192.94 -1.97,191.95 -1.97,190.96 -1.97,189.97 -1.97,188.98 -1.97,187.98 -1.97,186.99 -1.97,186.00 -1.97,185.01 -1.97,184.02 -1.97,183.03 -1.97,182.03 -1.97,181.04 -1.97,180.05 -1.97,179.06 -1.97,178.07 -1.97,177.08 -1.97,176.08 -1.97,175.09 -1.97,174.10 -1.96,173.11 -1.96,172.12 -1.96,171.13 -1.96,170.13 -1.96,169.14 -1.96,168.15 -1.96,167.16 -1.96,166.17 -1.96,165.18 -1.96,164.18 -1.96,163.19 -1.96,162.20 -1.96,161.21 -1.96,160.21 -1.96,159.22 -1.96,158.23 -1.96,157.24 -1.96,156.24 -1.96,155.25 -1.95,154.26 -1.95,153.27 -1.95,152.27 -1.95,151.28 -1.95,150.29 -1.95,149.30 -1.95,148.30 -1.95,147.31 -1.95,146.32 -1.95,145.33 -1.95,144.33 -1.95,143.34 -1.95,142.35 -1.95,141.36 -1.95,140.36 -1.95,139.37 -1.95,138.38 -1.95,137.39 -1.95,136.39 -1.95,135.40 -1.94,134.41 -1.94,133.42 -1.94,132.42 -1.94,131.43 -1.94,130.44 -1.94,129.45 -1.94,128.45 -1.94,127.46 -1.94,126.47 -1.94,125.48 -1.94,124.48 -1.94,123.49 -1.94,122.50 -1.94,121.51 -1.94,120.51 -1.94,119.52 -1.94,118.53 -1.94,117.54 -1.94,116.54 -1.93,115.55 -1.93,114.56 -1.93,113.57 -1.93,112.57 -1.93,111.58 -1.93,110.59 -1.93,109.60 -1.93,108.60 -1.93,107.61 -1.93,106.62 -1.93,105.63 -1.93,104.63 -1.93,103.64 -1.93,102.65 -1.93,101.66 -1.93,100.66 -1.93,99.67 -1.93,98.68 -1.93,97.69 -1.92,96.69 -1.92,95.70 -1.92,94.71 -1.92,93.72 -1.92,92.72 -1.92,91.73 -1.92,90.74 -1.92,89.75 -1.92,88.75 -1.92,87.76 -1.92,87.44 -1.92,86.44 -1.92,85.45 -1.92,84.46 -1.92,83.47 -1.92,82.47 -1.92,81.48 -1.92,80.49 -1.92,79.50 -1.92,78.50 -1.92,77.51 -1.92,76.52 -1.92,75.53 -1.92,74.53 -1.92,73.54 -1.92,72.55 -1.92,71.56 -1.92,70.56 -1.92,69.57 -1.92,68.58 -1.92,67.59 -1.92,66.59 -1.92,65.60 -1.92,64.61 -1.92,63.62 -1.92,62.62 -1.92,61.63 -1.92,60.64 -1.92,59.65 -1.92,58.65 -1.92,57.66 -1.92,56.67 -1.92,55.68 -1.92,54.68 -1.92,53.69 -1.92,52.70 -1.92,51.71 -1.92,50.71 -1.93,49.72 -1.93,48.73 -1.93,47.73 -1.93,46.74 -1.93,45.75 -1.93,44.76 -1.93,43.76 -1.93,42.77 -1.93,41.78 -1.93,40.79 -1.93,39.79 -1.93,38.80 -1.93,37.81 -1.93,36.82 -1.93,35.82 -1.93,34.83 -1.93,33.84 -1.93,32.85 -1.93,31.85 -1.93,30.86 -1.93,29.87 -1.93,28.88 -1.93,27.88 -1.93,26.89 -1.93,25.90 -1.93,24.91 -1.93,23.91 -1.93,22.92 -1.93,21.93 -1.93,20.94 -1.93,19.94 -1.93,18.95 -1.93,17.96 -1.93,16.97 -1.93,15.97 -1.93,14.98 -1.93,13.99 -1.93,13.00 -1.93,12.00 -1.93,11.01 -1.93,10.55 -1.89,9.50 -1.74,8.35 -1.50,7.20 -1.16,6.08 -0.72,4.99 -0.19,3.94 0.43,2.95 1.12,2.02 1.73,1.33 2.61,0.52 3.60,-0.21 4.67,-0.82 5.80,-1.30 6.98,-1.65 8.19,-1.86 9.35,-1.93 10.07,-1.93 79.47,-1.97" type="driving"/>
</edge>
<edge id="-4.0.00" from="156" to="139" priority="1" type="sidewalk|shoulder|driving" shape="101.48,197.20 325.70,197.09">
<lane id="-4.0.00_0" index="0" allow="pedestrian" speed="2.78" length="224.22" width="4.00" shape="101.48,190.90 325.69,190.79" type="sidewalk"/>
<lane id="-4.0.00_1" index="1" disallow="all" speed="1.39" length="224.22" width="0.30" shape="101.48,193.05 325.69,192.94" type="shoulder"/>
<lane id="-4.0.00_2" index="2" disallow="pedestrian tram rail_urban rail rail_electric rail_fast ship" speed="13.89" length="224.22" width="4.00" shape="101.48,195.20 325.69,195.09" type="driving"/>
</edge>
<edge id="-6.0.00" from="195" to="60" priority="1" type="sidewalk|shoulder|driving" shape="101.68,0.02 102.51,0.02 103.33,0.02 103.55,0.02 104.54,0.02 105.54,0.02 106.53,0.02 107.53,0.02 108.52,0.02 109.51,0.02 110.51,0.02 111.50,0.02 112.50,0.02 113.49,0.02 114.49,0.02 115.48,0.02 116.48,0.02 117.47,0.02 118.46,0.02 119.46,0.02 120.45,0.02 121.45,0.02 122.44,0.02 123.44,0.02 124.43,0.02 125.43,0.02 126.42,0.02 127.42,0.02 128.41,0.02 129.40,0.02 130.40,0.02 131.39,0.02 132.39,0.02 133.38,0.02 134.38,0.02 135.37,0.02 136.37,0.02 137.36,0.02 138.35,0.02 139.35,0.02 140.34,0.02 141.34,0.02 142.33,0.02 143.33,0.02 144.32,0.02 145.32,0.02 146.31,0.02 147.31,0.02 148.30,0.02 149.29,0.02 150.29,0.01 151.28,0.01 152.28,0.01 153.27,0.01 154.27,0.01 155.26,0.01 156.26,0.01 157.25,0.01 158.24,0.01 159.24,0.01 160.23,0.01 161.23,0.01 162.22,0.01 163.22,0.01 164.21,0.01 165.21,0.01 166.20,0.01 167.19,0.01 168.19,0.01 169.18,0.01 170.18,0.01 171.17,0.01 172.17,0.01 173.16,0.01 174.16,0.01 175.15,0.01 176.15,0.01 177.14,0.01 178.13,0.01 179.13,0.01 180.12,0.01 181.12,0.01 182.11,0.01 183.11,0.01 184.10,0.01 185.10,0.01 186.09,0.01 187.08,0.01 188.08,0.01 189.07,0.01 190.07,0.01 191.06,0.01 192.06,0.01 193.05,0.01 194.05,0.01 195.04,0.01 196.04,0.01 197.03,0.01 198.03,0.01 199.02,0.01 200.02,0.01 201.01,0.01 202.01,0.01 203.00,0.01 204.00,0.01 204.99,0.01 205.99,0.01 206.98,0.01 207.98,0.01 208.97,0.01 209.97,0.01 210.96,0.01 211.96,0.01 212.96,0.01 213.95,0.01 214.95,0.01 215.94,0.01 216.94,0.01 217.93,0.01 218.93,0.01 219.92,0.01 220.92,0.01 221.91,0.01 222.91,0.01 223.90,0.01 224.90,0.01 225.90,0.01 226.89,0.01 227.89,0.01 228.88,0.01 229.88,0.01 230.87,0.01 231.87,0.01 232.86,0.01 233.86,0.01 234.85,0.01 235.85,0.01 236.84,0.01 237.84,0.01 238.83,0.01 239.83,0.01 240.83,0.01 241.82,0.01 242.82,0.01 243.81,0.00 244.81,0.00 245.80,0.00 246.80,0.00 247.79,0.00 248.79,0.00 249.78,0.00 250.78,0.00 251.77,0.00 252.77,0.00 253.77,0.00 254.76,0.00 255.76,0.00 256.75,0.00 257.75,0.00 258.74,0.00 259.74,0.00 260.73,0.00 261.73,0.00 262.72,0.00 263.72,0.00 264.71,0.00 265.71,0.00 266.70,0.00 267.70,0.00 268.70,0.00 269.69,0.00 270.69,0.00 271.68,0.00 272.68,0.00 273.67,0.00 274.67,0.00 275.66,0.00 276.66,0.00 277.65,0.00 278.65,0.00 279.64,0.00 280.64,0.00 281.64,0.00 282.63,0.00 283.63,0.00 284.62,0.00 285.62,0.00 286.61,0.00 287.61,0.00 288.60,0.00 289.60,0.00 290.59,0.00 291.62,0.00 292.60,0.00 293.57,0.00 294.55,0.00 295.53,0.00 296.50,0.00 297.48,0.00 298.45,0.00 299.43,0.00 300.41,0.00 301.38,0.00 302.36,0.00 303.33,0.00 304.31,0.00 305.29,0.00 306.26,0.00 307.24,0.00 308.22,0.00 309.19,0.00 310.17,0.00 311.14,0.00 312.12,0.00 313.10,0.00 314.07,0.00 315.05,0.00 316.02,0.00 317.00,0.00 317.98,0.00 318.95,0.00 319.93,0.00 320.90,0.00 321.88,0.00 322.86,0.00 323.83,0.00 324.81,0.00 325.78,0.00">
<lane id="-6.0.00_0" index="0" allow="pedestrian" speed="2.78" length="224.11" width="4.00" shape="101.68,-6.28 102.50,-6.28 103.33,-6.28 103.55,-6.28 104.54,-6.28 105.54,-6.28 106.53,-6.28 107.52,-6.28 108.52,-6.28 109.51,-6.28 110.51,-6.28 111.50,-6.28 112.50,-6.28 113.49,-6.28 114.49,-6.28 115.48,-6.28 116.47,-6.28 117.47,-6.28 118.46,-6.28 119.46,-6.28 120.45,-6.28 121.45,-6.28 122.44,-6.28 123.44,-6.28 124.43,-6.28 125.43,-6.28 126.42,-6.28 127.41,-6.28 128.41,-6.28 129.40,-6.28 130.40,-6.28 131.39,-6.28 132.39,-6.28 133.38,-6.28 134.38,-6.28 135.37,-6.28 136.36,-6.28 137.36,-6.28 138.35,-6.28 139.35,-6.28 140.34,-6.28 141.34,-6.28 142.33,-6.28 143.33,-6.28 144.32,-6.28 145.32,-6.28 146.31,-6.28 147.30,-6.28 148.30,-6.28 149.29,-6.28 150.29,-6.29 151.28,-6.29 152.28,-6.29 153.27,-6.29 154.27,-6.29 155.26,-6.29 156.25,-6.29 157.25,-6.29 158.24,-6.29 159.24,-6.29 160.23,-6.29 161.23,-6.29 162.22,-6.29 163.22,-6.29 164.21,-6.29 165.21,-6.29 166.20,-6.29 167.19,-6.29 168.19,-6.29 169.18,-6.29 170.18,-6.29 171.17,-6.29 172.17,-6.29 173.16,-6.29 174.16,-6.29 175.15,-6.29 176.14,-6.29 177.14,-6.29 178.13,-6.29 179.13,-6.29 180.12,-6.29 181.12,-6.29 182.11,-6.29 183.11,-6.29 184.10,-6.29 185.10,-6.29 186.09,-6.29 187.08,-6.29 188.08,-6.29 189.07,-6.29 190.07,-6.29 191.06,-6.29 192.06,-6.29 193.05,-6.29 194.05,-6.29 195.04,-6.29 196.03,-6.29 197.03,-6.29 198.02,-6.29 199.02,-6.29 200.02,-6.29 201.01,-6.29 202.01,-6.29 203.00,-6.29 204.00,-6.29 204.99,-6.29 205.99,-6.29 206.98,-6.29 207.98,-6.29 208.97,-6.29 209.97,-6.29 210.96,-6.29 211.96,-6.29 212.95,-6.29 213.95,-6.29 214.95,-6.29 215.94,-6.29 216.94,-6.29 217.93,-6.29 218.93,-6.29 219.92,-6.29 220.92,-6.29 221.91,-6.29 222.91,-6.29 223.90,-6.29 224.90,-6.29 225.89,-6.29 226.89,-6.29 227.89,-6.29 228.88,-6.29 229.88,-6.29 230.87,-6.29 231.87,-6.29 232.86,-6.29 233.86,-6.29 234.85,-6.29 235.85,-6.29 236.84,-6.29 237.84,-6.29 238.83,-6.29 239.83,-6.29 240.82,-6.29 241.82,-6.29 242.82,-6.29 243.81,-6.30 244.81,-6.30 245.80,-6.30 246.80,-6.30 247.79,-6.30 248.79,-6.30 249.78,-6.30 250.78,-6.30 251.77,-6.30 252.77,-6.30 253.76,-6.30 254.76,-6.30 255.76,-6.30 256.75,-6.30 257.75,-6.30 258.74,-6.30 259.74,-6.30 260.73,-6.30 261.73,-6.30 262.72,-6.30 263.72,-6.30 264.71,-6.30 265.71,-6.30 266.70,-6.30 267.70,-6.30 268.69,-6.30 269.69,-6.30 270.69,-6.30 271.68,-6.30 272.68,-6.30 273.67,-6.30 274.67,-6.30 275.66,-6.30 276.66,-6.30 277.65,-6.30 278.65,-6.30 279.64,-6.30 280.64,-6.30 281.63,-6.30 282.63,-6.30 283.63,-6.30 284.62,-6.30 285.62,-6.30 286.61,-6.30 287.61,-6.30 288.60,-6.30 289.60,-6.30 290.59,-6.30 291.62,-6.30 292.60,-6.30 293.57,-6.30 294.55,-6.30 295.53,-6.30 296.50,-6.30 297.48,-6.30 298.45,-6.30 299.43,-6.30 300.41,-6.30 301.38,-6.30 302.36,-6.30 303.33,-6.30 304.31,-6.30 305.29,-6.30 306.26,-6.30 307.24,-6.30 308.22,-6.30 309.19,-6.30 310.17,-6.30 311.14,-6.30 312.12,-6.30 313.10,-6.30 314.07,-6.30 315.05,-6.30 316.02,-6.30 317.00,-6.30 317.98,-6.30 318.95,-6.30 319.93,-6.30 320.90,-6.30 321.88,-6.30 322.86,-6.30 323.83,-6.30 324.81,-6.30 325.78,-6.30" type="sidewalk"/>
<lane id="-6.0.00_1" index="1" disallow="all" speed="1.39" length="224.11" width="0.30" shape="101.68,-4.13 102.50,-4.13 103.33,-4.13 103.55,-4.13 104.54,-4.13 105.54,-4.13 106.53,-4.13 107.52,-4.13 108.52,-4.13 109.51,-4.13 110.51,-4.13 111.50,-4.13 112.50,-4.13 113.49,-4.13 114.49,-4.13 115.48,-4.13 116.48,-4.13 117.47,-4.13 118.46,-4.13 119.46,-4.13 120.45,-4.13 121.45,-4.13 122.44,-4.13 123.44,-4.13 124.43,-4.13 125.43,-4.13 126.42,-4.13 127.41,-4.13 128.41,-4.13 129.40,-4.13 130.40,-4.13 131.39,-4.13 132.39,-4.13 133.38,-4.13 134.38,-4.13 135.37,-4.13 136.37,-4.13 137.36,-4.13 138.35,-4.13 139.35,-4.13 140.34,-4.13 141.34,-4.13 142.33,-4.13 143.33,-4.13 144.32,-4.13 145.32,-4.13 146.31,-4.13 147.30,-4.13 148.30,-4.13 149.29,-4.13 150.29,-4.14 151.28,-4.14 152.28,-4.14 153.27,-4.14 154.27,-4.14 155.26,-4.14 156.26,-4.14 157.25,-4.14 158.24,-4.14 159.24,-4.14 160.23,-4.14 161.23,-4.14 162.22,-4.14 163.22,-4.14 164.21,-4.14 165.21,-4.14 166.20,-4.14 167.19,-4.14 168.19,-4.14 169.18,-4.14 170.18,-4.14 171.17,-4.14 172.17,-4.14 173.16,-4.14 174.16,-4.14 175.15,-4.14 176.15,-4.14 177.14,-4.14 178.13,-4.14 179.13,-4.14 180.12,-4.14 181.12,-4.14 182.11,-4.14 183.11,-4.14 184.10,-4.14 185.10,-4.14 186.09,-4.14 187.08,-4.14 188.08,-4.14 189.07,-4.14 190.07,-4.14 191.06,-4.14 192.06,-4.14 193.05,-4.14 194.05,-4.14 195.04,-4.14 196.03,-4.14 197.03,-4.14 198.02,-4.14 199.02,-4.14 200.02,-4.14 201.01,-4.14 202.01,-4.14 203.00,-4.14 204.00,-4.14 204.99,-4.14 205.99,-4.14 206.98,-4.14 207.98,-4.14 208.97,-4.14 209.97,-4.14 210.96,-4.14 211.96,-4.14 212.96,-4.14 213.95,-4.14 214.95,-4.14 215.94,-4.14 216.94,-4.14 217.93,-4.14 218.93,-4.14 219.92,-4.14 220.92,-4.14 221.91,-4.14 222.91,-4.14 223.90,-4.14 224.90,-4.14 225.89,-4.14 226.89,-4.14 227.89,-4.14 228.88,-4.14 229.88,-4.14 230.87,-4.14 231.87,-4.14 232.86,-4.14 233.86,-4.14 234.85,-4.14 235.85,-4.14 236.84,-4.14 237.84,-4.14 238.83,-4.14 239.83,-4.14 240.83,-4.14 241.82,-4.14 242.82,-4.14 243.81,-4.15 244.81,-4.15 245.80,-4.15 246.80,-4.15 247.79,-4.15 248.79,-4.15 249.78,-4.15 250.78,-4.15 251.77,-4.15 252.77,-4.15 253.76,-4.15 254.76,-4.15 255.76,-4.15 256.75,-4.15 257.75,-4.15 258.74,-4.15 259.74,-4.15 260.73,-4.15 261.73,-4.15 262.72,-4.15 263.72,-4.15 264.71,-4.15 265.71,-4.15 266.70,-4.15 267.70,-4.15 268.69,-4.15 269.69,-4.15 270.69,-4.15 271.68,-4.15 272.68,-4.15 273.67,-4.15 274.67,-4.15 275.66,-4.15 276.66,-4.15 277.65,-4.15 278.65,-4.15 279.64,-4.15 280.64,-4.15 281.63,-4.15 282.63,-4.15 283.63,-4.15 284.62,-4.15 285.62,-4.15 286.61,-4.15 287.61,-4.15 288.60,-4.15 289.60,-4.15 290.59,-4.15 291.62,-4.15 292.60,-4.15 293.57,-4.15 294.55,-4.15 295.53,-4.15 296.50,-4.15 297.48,-4.15 298.45,-4.15 299.43,-4.15 300.41,-4.15 301.38,-4.15 302.36,-4.15 303.33,-4.15 304.31,-4.15 305.29,-4.15 306.26,-4.15 307.24,-4.15 308.22,-4.15 309.19,-4.15 310.17,-4.15 311.14,-4.15 312.12,-4.15 313.10,-4.15 314.07,-4.15 315.05,-4.15 316.02,-4.15 317.00,-4.15 317.98,-4.15 318.95,-4.15 319.93,-4.15 320.90,-4.15 321.88,-4.15 322.86,-4.15 323.83,-4.15 324.81,-4.15 325.78,-4.15" type="shoulder"/>
<lane id="-6.0.00_2" index="2" disallow="pedestrian tram rail_urban rail rail_electric rail_fast ship" speed="13.89" length="224.11" width="4.00" shape="101.68,-1.98 102.50,-1.98 103.33,-1.98 103.55,-1.98 104.54,-1.98 105.54,-1.98 106.53,-1.98 107.52,-1.98 108.52,-1.98 109.51,-1.98 110.51,-1.98 111.50,-1.98 112.50,-1.98 113.49,-1.98 114.49,-1.98 115.48,-1.98 116.48,-1.98 117.47,-1.98 118.46,-1.98 119.46,-1.98 120.45,-1.98 121.45,-1.98 122.44,-1.98 123.44,-1.98 124.43,-1.98 125.43,-1.98 126.42,-1.98 127.41,-1.98 128.41,-1.98 129.40,-1.98 130.40,-1.98 131.39,-1.98 132.39,-1.98 133.38,-1.98 134.38,-1.98 135.37,-1.98 136.37,-1.98 137.36,-1.98 138.35,-1.98 139.35,-1.98 140.34,-1.98 141.34,-1.98 142.33,-1.98 143.33,-1.98 144.32,-1.98 145.32,-1.98 146.31,-1.98 147.30,-1.98 148.30,-1.98 149.29,-1.98 150.29,-1.99 151.28,-1.99 152.28,-1.99 153.27,-1.99 154.27,-1.99 155.26,-1.99 156.26,-1.99 157.25,-1.99 158.24,-1.99 159.24,-1.99 160.23,-1.99 161.23,-1.99 162.22,-1.99 163.22,-1.99 164.21,-1.99 165.21,-1.99 166.20,-1.99 167.19,-1.99 168.19,-1.99 169.18,-1.99 170.18,-1.99 171.17,-1.99 172.17,-1.99 173.16,-1.99 174.16,-1.99 175.15,-1.99 176.15,-1.99 177.14,-1.99 178.13,-1.99 179.13,-1.99 180.12,-1.99 181.12,-1.99 182.11,-1.99 183.11,-1.99 184.10,-1.99 185.10,-1.99 186.09,-1.99 187.08,-1.99 188.08,-1.99 189.07,-1.99 190.07,-1.99 191.06,-1.99 192.06,-1.99 193.05,-1.99 194.05,-1.99 195.04,-1.99 196.04,-1.99 197.03,-1.99 198.03,-1.99 199.02,-1.99 200.02,-1.99 201.01,-1.99 202.01,-1.99 203.00,-1.99 204.00,-1.99 204.99,-1.99 205.99,-1.99 206.98,-1.99 207.98,-1.99 208.97,-1.99 209.97,-1.99 210.96,-1.99 211.96,-1.99 212.96,-1.99 213.95,-1.99 214.95,-1.99 215.94,-1.99 216.94,-1.99 217.93,-1.99 218.93,-1.99 219.92,-1.99 220.92,-1.99 221.91,-1.99 222.91,-1.99 223.90,-1.99 224.90,-1.99 225.89,-1.99 226.89,-1.99 227.89,-1.99 228.88,-1.99 229.88,-1.99 230.87,-1.99 231.87,-1.99 232.86,-1.99 233.86,-1.99 234.85,-1.99 235.85,-1.99 236.84,-1.99 237.84,-1.99 238.83,-1.99 239.83,-1.99 240.83,-1.99 241.82,-1.99 242.82,-1.99 243.81,-2.00 244.81,-2.00 245.80,-2.00 246.80,-2.00 247.79,-2.00 248.79,-2.00 249.78,-2.00 250.78,-2.00 251.77,-2.00 252.77,-2.00 253.76,-2.00 254.76,-2.00 255.76,-2.00 256.75,-2.00 257.75,-2.00 258.74,-2.00 259.74,-2.00 260.73,-2.00 261.73,-2.00 262.72,-2.00 263.72,-2.00 264.71,-2.00 265.71,-2.00 266.70,-2.00 267.70,-2.00 268.70,-2.00 269.69,-2.00 270.69,-2.00 271.68,-2.00 272.68,-2.00 273.67,-2.00 274.67,-2.00 275.66,-2.00 276.66,-2.00 277.65,-2.00 278.65,-2.00 279.64,-2.00 280.64,-2.00 281.63,-2.00 282.63,-2.00 283.63,-2.00 284.62,-2.00 285.62,-2.00 286.61,-2.00 287.61,-2.00 288.60,-2.00 289.60,-2.00 290.59,-2.00 291.62,-2.00 292.60,-2.00 293.57,-2.00 294.55,-2.00 295.53,-2.00 296.50,-2.00 297.48,-2.00 298.45,-2.00 299.43,-2.00 300.41,-2.00 301.38,-2.00 302.36,-2.00 303.33,-2.00 304.31,-2.00 305.29,-2.00 306.26,-2.00 307.24,-2.00 308.22,-2.00 309.19,-2.00 310.17,-2.00 311.14,-2.00 312.12,-2.00 313.10,-2.00 314.07,-2.00 315.05,-2.00 316.02,-2.00 317.00,-2.00 317.98,-2.00 318.95,-2.00 319.93,-2.00 320.90,-2.00 321.88,-2.00 322.86,-2.00 323.83,-2.00 324.81,-2.00 325.78,-2.00" type="driving"/>
</edge>
<edge id="-7.0.00" from="60" to="7.14" priority="1" type="sidewalk|shoulder|driving" shape="347.79,0.00 384.14,0.00">
<lane id="-7.0.00_0" index="0" allow="pedestrian" speed="2.78" length="34.85" width="4.00" shape="347.79,-6.30 382.64,-6.30" type="sidewalk"/>
<lane id="-7.0.00_1" index="1" disallow="all" speed="1.39" length="34.85" width="0.30" shape="347.79,-4.15 382.64,-4.15" type="shoulder"/>
<lane id="-7.0.00_2" index="2" disallow="pedestrian tram rail_urban rail rail_electric rail_fast ship" speed="13.89" length="34.85" width="4.00" shape="347.79,-2.00 382.64,-2.00" type="driving"/>
</edge>
<edge id="-8.0.00" from="8.14" to="43" priority="1" type="sidewalk|shoulder|driving" shape="394.41,10.07 394.41,11.06 394.41,12.05 394.41,13.04 394.41,14.03 394.41,15.02 394.41,16.01 394.41,17.00 394.41,17.99 394.41,18.98 394.41,19.97 394.41,20.96 394.41,21.95 394.40,22.94 394.40,23.93 394.40,24.92 394.40,25.91 394.40,26.90 394.40,27.89 394.40,28.88 394.40,29.87 394.40,30.86 394.40,31.85 394.40,32.84 394.40,33.83 394.40,34.82 394.40,35.81 394.40,36.80 394.40,37.79 394.40,38.78 394.40,39.77 394.40,40.76 394.40,41.75 394.40,42.74 394.40,43.73 394.40,44.72 394.40,45.71 394.40,46.70 394.40,47.69 394.39,48.68 394.39,49.67 394.39,50.66 394.39,51.65 394.39,52.64 394.39,53.63 394.39,54.62 394.39,55.61 394.39,56.60 394.39,57.59 394.39,58.58 394.39,59.57 394.39,60.56 394.39,61.55 394.39,62.54 394.39,63.53 394.39,64.52 394.39,65.51 394.39,66.50 394.39,67.49 394.39,68.48 394.39,69.47 394.39,70.46 394.39,71.45 394.39,72.44 394.39,73.43 394.38,74.42 394.38,75.41 394.38,76.40 394.38,77.39 394.38,78.38 394.38,79.37 394.38,80.36 394.38,81.35 394.38,82.34 394.38,83.33 394.38,84.32 394.38,85.31 394.38,86.30 394.38,87.29 394.38,88.36 394.38,89.35 394.38,90.34 394.38,91.33 394.38,92.32 394.38,93.30 394.38,94.29 394.38,95.28 394.38,96.27 394.38,97.26 394.38,98.25 394.38,99.23 394.38,100.22 394.38,101.21 394.38,102.20 394.38,103.19 394.38,104.18 394.38,105.17 394.38,106.15 394.38,107.14 394.38,108.13 394.38,109.12 394.38,110.11 394.37,111.10 394.37,112.08 394.37,113.07 394.37,114.06 394.37,115.05 394.37,116.04 394.37,117.03 394.37,118.01 394.37,119.00 394.37,119.99 394.37,120.98 394.37,121.97 394.37,122.96 394.37,123.94 394.37,124.93 394.37,125.92 394.37,126.91 394.37,127.90 394.37,128.89 394.37,129.87 394.37,130.86 394.37,131.85 394.37,132.84 394.37,133.83 394.37,134.82 394.37,135.80 394.37,136.79 394.37,137.78 394.37,138.77 394.37,139.76 394.37,140.75 394.37,141.73 394.37,142.72 394.37,143.71 394.37,144.70 394.37,145.69 394.37,146.68 394.37,147.67 394.37,148.65 394.37,149.64 394.37,150.63 394.37,151.62 394.37,152.61 394.37,153.60 394.37,154.58 394.37,155.57 394.37,156.56 394.37,157.55 394.36,158.54 394.36,159.53 394.36,160.51 394.36,161.50 394.36,162.49 394.36,163.48 394.36,164.47 394.36,165.46 394.36,166.46 394.36,167.46 394.36,168.46 394.36,169.45 394.36,170.45 394.36,171.45 394.36,172.45 394.36,173.44 394.36,174.44 394.36,175.44 394.36,176.43 394.36,177.43 394.36,178.43 394.36,179.43 394.36,180.42 394.36,181.42 394.36,182.42 394.36,183.41 394.36,184.41 394.36,185.41 394.36,186.41 394.36,187.40 394.36,188.40 394.36,189.40 394.36,190.39 394.36,191.39 394.36,192.39 394.36,193.39 394.36,194.38 394.36,195.38 394.36,196.38 394.36,197.38 394.36,198.37 394.36,199.37 394.36,200.37 394.36,201.36 394.36,202.36 394.36,203.36 394.36,204.36 394.35,205.35 394.35,206.35 394.35,207.35 394.35,208.34 394.35,209.34 394.35,210.34 394.35,211.34 394.35,212.33 394.35,213.33 394.35,214.33 394.35,215.32 394.35,216.32 394.35,217.32 394.35,218.32 394.35,219.31 394.35,220.31 394.35,221.31 394.35,222.31 394.35,223.30 394.35,224.30 394.35,225.30 394.35,226.29 394.35,227.29 394.35,228.29 394.35,229.29 394.35,230.28 394.35,231.28 394.35,232.28 394.35,233.27 394.35,234.27 394.35,235.27 394.35,236.27 394.35,237.26 394.35,238.26 394.35,239.26 394.35,240.26 394.35,241.25 394.35,241.96 394.35,242.96 394.35,243.95 394.35,244.95 394.35,245.95 394.35,246.94 394.35,247.94 394.36,248.94 394.36,249.94 394.36,250.93 394.36,251.93 394.36,252.93 394.36,253.93 394.36,254.92 394.36,255.92 394.37,256.92 394.37,257.92 394.37,258.91 394.37,259.91 394.37,260.91 394.37,261.91 394.37,262.90 394.37,263.90 394.38,264.90 394.38,265.90 394.38,266.89 394.38,267.89 394.38,268.89 394.38,269.89 394.38,270.88 394.38,271.88 394.38,272.88 394.39,273.88 394.39,274.87 394.39,275.87 394.39,276.87 394.39,277.87 394.39,278.86 394.39,279.86 394.39,280.86 394.40,281.86 394.40,282.85 394.40,283.85 394.40,284.85 394.40,285.84 394.40,286.84 394.40,287.84 394.40,288.84 394.41,289.83 394.41,290.83 394.41,291.83 394.41,292.83 394.41,293.82 394.41,294.82 394.41,295.82 394.41,296.82 394.41,297.81 394.42,298.81 394.42,299.81 394.42,300.81 394.42,301.80 394.42,302.80 394.42,303.80 394.42,304.80 394.42,305.79 394.43,306.79 394.43,307.79 394.43,308.79 394.43,309.78 394.43,310.78 394.43,311.78 394.43,312.78 394.43,313.77 394.44,314.77 394.44,315.77 394.44,316.77 394.44,317.76 394.44,318.76 394.44,319.64 394.39,320.61 394.23,321.60 393.96,322.56 393.59,323.49 393.12,324.37 392.55,325.19 391.90,325.95 391.21,326.59 390.41,327.18 389.54,327.68 388.62,328.07 387.66,328.36 386.68,328.53 385.68,328.59 385.17,328.59 384.65,328.59 348.29,328.61">
<lane id="-8.0.00_0" index="0" allow="pedestrian" speed="2.78" length="365.89" width="4.00" shape="400.71,11.57 400.71,12.05 400.71,13.04 400.71,14.03 400.71,15.02 400.71,16.01 400.71,17.00 400.71,17.99 400.71,18.98 400.71,19.97 400.71,20.96 400.71,21.95 400.70,22.94 400.70,23.93 400.70,24.92 400.70,25.91 400.70,26.90 400.70,27.89 400.70,28.88 400.70,29.87 400.70,30.86 400.70,31.85 400.70,32.84 400.70,33.83 400.70,34.82 400.70,35.81 400.70,36.80 400.70,37.79 400.70,38.78 400.70,39.77 400.70,40.76 400.70,41.75 400.70,42.74 400.70,43.73 400.70,44.72 400.70,45.71 400.70,46.70 400.70,47.69 400.69,48.68 400.69,49.67 400.69,50.66 400.69,51.65 400.69,52.64 400.69,53.63 400.69,54.62 400.69,55.61 400.69,56.60 400.69,57.59 400.69,58.58 400.69,59.57 400.69,60.56 400.69,61.55 400.69,62.54 400.69,63.53 400.69,64.52 400.69,65.51 400.69,66.50 400.69,67.49 400.69,68.48 400.69,69.47 400.69,70.46 400.69,71.45 400.69,72.44 400.69,73.43 400.68,74.42 400.68,75.41 400.68,76.40 400.68,77.39 400.68,78.38 400.68,79.37 400.68,80.36 400.68,81.35 400.68,82.34 400.68,83.33 400.68,84.32 400.68,85.31 400.68,86.30 400.68,87.29 400.68,88.36 400.68,89.35 400.68,90.34 400.68,91.33 400.68,92.32 400.68,93.31 400.68,94.29 400.68,95.28 400.68,96.27 400.68,97.26 400.68,98.25 400.68,99.24 400.68,100.22 400.68,101.21 400.68,102.20 400.68,103.19 400.68,104.18 400.68,105.17 400.68,106.15 400.68,107.14 400.68,108.13 400.68,109.12 400.68,110.11 400.67,111.10 400.67,112.09 400.67,113.07 400.67,114.06 400.67,115.05 400.67,116.04 400.67,117.03 400.67,118.02 400.67,119.00 400.67,119.99 400.67,120.98 400.67,121.97 400.67,122.96 400.67,123.95 400.67,124.93 400.67,125.92 400.67,126.91 400.67,127.90 400.67,128.89 400.67,129.88 400.67,130.86 400.67,131.85 400.67,132.84 400.67,133.83 400.67,134.82 400.67,135.81 400.67,136.79 400.67,137.78 400.67,138.77 400.67,139.76 400.67,140.75 400.67,141.74 400.67,142.72 400.67,143.71 400.67,144.70 400.67,145.69 400.67,146.68 400.67,147.67 400.67,148.65 400.67,149.64 400.67,150.63 400.67,151.62 400.67,152.61 400.67,153.60 400.67,154.59 400.67,155.57 400.67,156.56 400.67,157.55 400.66,158.54 400.66,159.53 400.66,160.52 400.66,161.50 400.66,162.49 400.66,163.48 400.66,164.47 400.66,165.47 400.66,166.46 400.66,167.46 400.66,168.46 400.66,169.45 400.66,170.45 400.66,171.45 400.66,172.45 400.66,173.44 400.66,174.44 400.66,175.44 400.66,176.44 400.66,177.43 400.66,178.43 400.66,179.43 400.66,180.42 400.66,181.42 400.66,182.42 400.66,183.42 400.66,184.41 400.66,185.41 400.66,186.41 400.66,187.40 400.66,188.40 400.66,189.40 400.66,190.40 400.66,191.39 400.66,192.39 400.66,193.39 400.66,194.38 400.66,195.38 400.66,196.38 400.66,197.38 400.66,198.37 400.66,199.37 400.66,200.37 400.66,201.37 400.66,202.36 400.66,203.36 400.66,204.36 400.65,205.35 400.65,206.35 400.65,207.35 400.65,208.35 400.65,209.34 400.65,210.34 400.65,211.34 400.65,212.33 400.65,213.33 400.65,214.33 400.65,215.33 400.65,216.32 400.65,217.32 400.65,218.32 400.65,219.32 400.65,220.31 400.65,221.31 400.65,222.31 400.65,223.30 400.65,224.30 400.65,225.30 400.65,226.30 400.65,227.29 400.65,228.29 400.65,229.29 400.65,230.28 400.65,231.28 400.65,232.28 400.65,233.28 400.65,234.27 400.65,235.27 400.65,236.27 400.65,237.26 400.65,238.26 400.65,239.26 400.65,240.26 400.65,241.25 400.65,241.95 400.65,242.95 400.65,243.95 400.65,244.94 400.65,245.94 400.65,246.94 400.65,247.93 400.66,248.93 400.66,249.93 400.66,250.93 400.66,251.92 400.66,252.92 400.66,253.92 400.66,254.92 400.66,255.91 400.67,256.91 400.67,257.91 400.67,258.91 400.67,259.90 400.67,260.90 400.67,261.90 400.67,262.90 400.67,263.89 400.68,264.89 400.68,265.89 400.68,266.89 400.68,267.88 400.68,268.88 400.68,269.88 400.68,270.88 400.68,271.87 400.68,272.87 400.69,273.87 400.69,274.87 400.69,275.86 400.69,276.86 400.69,277.86 400.69,278.86 400.69,279.85 400.69,280.85 400.70,281.85 400.70,282.84 400.70,283.84 400.70,284.84 400.70,285.84 400.70,286.83 400.70,287.83 400.70,288.83 400.71,289.83 400.71,290.82 400.71,291.82 400.71,292.82 400.71,293.82 400.71,294.81 400.71,295.81 400.71,296.81 400.71,297.81 400.72,298.80 400.72,299.80 400.72,300.80 400.72,301.80 400.72,302.79 400.72,303.79 400.72,304.79 400.72,305.79 400.73,306.78 400.73,307.78 400.73,308.78 400.73,309.78 400.73,310.77 400.73,311.77 400.73,312.77 400.73,313.77 400.74,314.76 400.74,315.76 400.74,316.76 400.74,317.75 400.74,318.75 400.74,319.81 400.66,321.28 400.39,322.95 399.94,324.58 399.31,326.16 398.51,327.65 397.55,329.05 396.44,330.33 395.24,331.44 393.86,332.46 392.36,333.32 390.77,334.01 389.11,334.50 387.41,334.80 385.93,334.88 385.17,334.89 384.65,334.89 348.29,334.91" type="sidewalk"/>
<lane id="-8.0.00_1" index="1" disallow="all" speed="1.39" length="365.89" width="0.30" shape="398.56,11.57 398.56,12.05 398.56,13.04 398.56,14.03 398.56,15.02 398.56,16.01 398.56,17.00 398.56,17.99 398.56,18.98 398.56,19.97 398.56,20.96 398.56,21.95 398.55,22.94 398.55,23.93 398.55,24.92 398.55,25.91 398.55,26.90 398.55,27.89 398.55,28.88 398.55,29.87 398.55,30.86 398.55,31.85 398.55,32.84 398.55,33.83 398.55,34.82 398.55,35.81 398.55,36.80 398.55,37.79 398.55,38.78 398.55,39.77 398.55,40.76 398.55,41.75 398.55,42.74 398.55,43.73 398.55,44.72 398.55,45.71 398.55,46.70 398.55,47.69 398.54,48.68 398.54,49.67 398.54,50.66 398.54,51.65 398.54,52.64 398.54,53.63 398.54,54.62 398.54,55.61 398.54,56.60 398.54,57.59 398.54,58.58 398.54,59.57 398.54,60.56 398.54,61.55 398.54,62.54 398.54,63.53 398.54,64.52 398.54,65.51 398.54,66.50 398.54,67.49 398.54,68.48 398.54,69.47 398.54,70.46 398.54,71.45 398.54,72.44 398.54,73.43 398.53,74.42 398.53,75.41 398.53,76.40 398.53,77.39 398.53,78.38 398.53,79.37 398.53,80.36 398.53,81.35 398.53,82.34 398.53,83.33 398.53,84.32 398.53,85.31 398.53,86.30 398.53,87.29 398.53,88.36 398.53,89.35 398.53,90.34 398.53,91.33 398.53,92.32 398.53,93.31 398.53,94.29 398.53,95.28 398.53,96.27 398.53,97.26 398.53,98.25 398.53,99.24 398.53,100.22 398.53,101.21 398.53,102.20 398.53,103.19 398.53,104.18 398.53,105.17 398.53,106.15 398.53,107.14 398.53,108.13 398.53,109.12 398.53,110.11 398.52,111.10 398.52,112.08 398.52,113.07 398.52,114.06 398.52,115.05 398.52,116.04 398.52,117.03 398.52,118.01 398.52,119.00 398.52,119.99 398.52,120.98 398.52,121.97 398.52,122.96 398.52,123.95 398.52,124.93 398.52,125.92 398.52,126.91 398.52,127.90 398.52,128.89 398.52,129.88 398.52,130.86 398.52,131.85 398.52,132.84 398.52,133.83 398.52,134.82 398.52,135.81 398.52,136.79 398.52,137.78 398.52,138.77 398.52,139.76 398.52,140.75 398.52,141.74 398.52,142.72 398.52,143.71 398.52,144.70 398.52,145.69 398.52,146.68 398.52,147.67 398.52,148.65 398.52,149.64 398.52,150.63 398.52,151.62 398.52,152.61 398.52,153.60 398.52,154.58 398.52,155.57 398.52,156.56 398.52,157.55 398.51,158.54 398.51,159.53 398.51,160.51 398.51,161.50 398.51,162.49 398.51,163.48 398.51,164.47 398.51,165.47 398.51,166.46 398.51,167.46 398.51,168.46 398.51,169.45 398.51,170.45 398.51,171.45 398.51,172.45 398.51,173.44 398.51,174.44 398.51,175.44 398.51,176.43 398.51,177.43 398.51,178.43 398.51,179.43 398.51,180.42 398.51,181.42 398.51,182.42 398.51,183.42 398.51,184.41 398.51,185.41 398.51,186.41 398.51,187.40 398.51,188.40 398.51,189.40 398.51,190.40 398.51,191.39 398.51,192.39 398.51,193.39 398.51,194.38 398.51,195.38 398.51,196.38 398.51,197.38 398.51,198.37 398.51,199.37 398.51,200.37 398.51,201.36 398.51,202.36 398.51,203.36 398.51,204.36 398.50,205.35 398.50,206.35 398.50,207.35 398.50,208.35 398.50,209.34 398.50,210.34 398.50,211.34 398.50,212.33 398.50,213.33 398.50,214.33 398.50,215.33 398.50,216.32 398.50,217.32 398.50,218.32 398.50,219.31 398.50,220.31 398.50,221.31 398.50,222.31 398.50,223.30 398.50,224.30 398.50,225.30 398.50,226.30 398.50,227.29 398.50,228.29 398.50,229.29 398.50,230.28 398.50,231.28 398.50,232.28 398.50,233.28 398.50,234.27 398.50,235.27 398.50,236.27 398.50,237.26 398.50,238.26 398.50,239.26 398.50,240.26 398.50,241.25 398.50,241.95 398.50,242.95 398.50,243.95 398.50,244.95 398.50,245.94 398.50,246.94 398.50,247.94 398.51,248.93 398.51,249.93 398.51,250.93 398.51,251.93 398.51,252.92 398.51,253.92 398.51,254.92 398.51,255.92 398.52,256.91 398.52,257.91 398.52,258.91 398.52,259.91 398.52,260.90 398.52,261.90 398.52,262.90 398.52,263.90 398.53,264.89 398.53,265.89 398.53,266.89 398.53,267.89 398.53,268.88 398.53,269.88 398.53,270.88 398.53,271.88 398.53,272.87 398.54,273.87 398.54,274.87 398.54,275.87 398.54,276.86 398.54,277.86 398.54,278.86 398.54,279.86 398.54,280.85 398.55,281.85 398.55,282.85 398.55,283.84 398.55,284.84 398.55,285.84 398.55,286.84 398.55,287.83 398.55,288.83 398.56,289.83 398.56,290.83 398.56,291.82 398.56,292.82 398.56,293.82 398.56,294.82 398.56,295.81 398.56,296.81 398.56,297.81 398.57,298.81 398.57,299.80 398.57,300.80 398.57,301.80 398.57,302.80 398.57,303.79 398.57,304.79 398.57,305.79 398.58,306.79 398.58,307.78 398.58,308.78 398.58,309.78 398.58,310.78 398.58,311.77 398.58,312.77 398.58,313.77 398.59,314.77 398.59,315.76 398.59,316.76 398.59,317.76 398.59,318.76 398.59,319.75 398.52,321.05 398.29,322.49 397.90,323.89 397.36,325.25 396.67,326.53 395.84,327.73 394.89,328.83 393.87,329.79 392.68,330.66 391.40,331.40 390.04,331.98 388.62,332.40 387.16,332.66 385.84,332.74 385.17,332.74 384.65,332.74 348.29,332.76" type="shoulder"/>
<lane id="-8.0.00_2" index="2" disallow="pedestrian tram rail_urban rail rail_electric rail_fast ship" speed="13.89" length="365.89" width="4.00" shape="396.41,11.57 396.41,12.05 396.41,13.04 396.41,14.03 396.41,15.02 396.41,16.01 396.41,17.00 396.41,17.99 396.41,18.98 396.41,19.97 396.41,20.96 396.41,21.95 396.40,22.94 396.40,23.93 396.40,24.92 396.40,25.91 396.40,26.90 396.40,27.89 396.40,28.88 396.40,29.87 396.40,30.86 396.40,31.85 396.40,32.84 396.40,33.83 396.40,34.82 396.40,35.81 396.40,36.80 396.40,37.79 396.40,38.78 396.40,39.77 396.40,40.76 396.40,41.75 396.40,42.74 396.40,43.73 396.40,44.72 396.40,45.71 396.40,46.70 396.40,47.69 396.39,48.68 396.39,49.67 396.39,50.66 396.39,51.65 396.39,52.64 396.39,53.63 396.39,54.62 396.39,55.61 396.39,56.60 396.39,57.59 396.39,58.58 396.39,59.57 396.39,60.56 396.39,61.55 396.39,62.54 396.39,63.53 396.39,64.52 396.39,65.51 396.39,66.50 396.39,67.49 396.39,68.48 396.39,69.47 396.39,70.46 396.39,71.45 396.39,72.44 396.39,73.43 396.38,74.42 396.38,75.41 396.38,76.40 396.38,77.39 396.38,78.38 396.38,79.37 396.38,80.36 396.38,81.35 396.38,82.34 396.38,83.33 396.38,84.32 396.38,85.31 396.38,86.30 396.38,87.29 396.38,88.36 396.38,89.35 396.38,90.34 396.38,91.33 396.38,92.32 396.38,93.31 396.38,94.29 396.38,95.28 396.38,96.27 396.38,97.26 396.38,98.25 396.38,99.24 396.38,100.22 396.38,101.21 396.38,102.20 396.38,103.19 396.38,104.18 396.38,105.17 396.38,106.15 396.38,107.14 396.38,108.13 396.38,109.12 396.38,110.11 396.37,111.10 396.37,112.08 396.37,113.07 396.37,114.06 396.37,115.05 396.37,116.04 396.37,117.03 396.37,118.01 396.37,119.00 396.37,119.99 396.37,120.98 396.37,121.97 396.37,122.96 396.37,123.94 396.37,124.93 396.37,125.92 396.37,126.91 396.37,127.90 396.37,128.89 396.37,129.87 396.37,130.86 396.37,131.85 396.37,132.84 396.37,133.83 396.37,134.82 396.37,135.81 396.37,136.79 396.37,137.78 396.37,138.77 396.37,139.76 396.37,140.75 396.37,141.74 396.37,142.72 396.37,143.71 396.37,144.70 396.37,145.69 396.37,146.68 396.37,147.67 396.37,148.65 396.37,149.64 396.37,150.63 396.37,151.62 396.37,152.61 396.37,153.60 396.37,154.58 396.37,155.57 396.37,156.56 396.37,157.55 396.36,158.54 396.36,159.53 396.36,160.51 396.36,161.50 396.36,162.49 396.36,163.48 396.36,164.47 396.36,165.47 396.36,166.46 396.36,167.46 396.36,168.46 396.36,169.45 396.36,170.45 396.36,171.45 396.36,172.45 396.36,173.44 396.36,174.44 396.36,175.44 396.36,176.43 396.36,177.43 396.36,178.43 396.36,179.43 396.36,180.42 396.36,181.42 396.36,182.42 396.36,183.41 396.36,184.41 396.36,185.41 396.36,186.41 396.36,187.40 396.36,188.40 396.36,189.40 396.36,190.40 396.36,191.39 396.36,192.39 396.36,193.39 396.36,194.38 396.36,195.38 396.36,196.38 396.36,197.38 396.36,198.37 396.36,199.37 396.36,200.37 396.36,201.36 396.36,202.36 396.36,203.36 396.36,204.36 396.35,205.35 396.35,206.35 396.35,207.35 396.35,208.34 396.35,209.34 396.35,210.34 396.35,211.34 396.35,212.33 396.35,213.33 396.35,214.33 396.35,215.33 396.35,216.32 396.35,217.32 396.35,218.32 396.35,219.31 396.35,220.31 396.35,221.31 396.35,222.31 396.35,223.30 396.35,224.30 396.35,225.30 396.35,226.29 396.35,227.29 396.35,228.29 396.35,229.29 396.35,230.28 396.35,231.28 396.35,232.28 396.35,233.28 396.35,234.27 396.35,235.27 396.35,236.27 396.35,237.26 396.35,238.26 396.35,239.26 396.35,240.26 396.35,241.25 396.35,241.96 396.35,242.95 396.35,243.95 396.35,244.95 396.35,245.95 396.35,246.94 396.35,247.94 396.36,248.94 396.36,249.93 396.36,250.93 396.36,251.93 396.36,252.93 396.36,253.92 396.36,254.92 396.36,255.92 396.37,256.92 396.37,257.91 396.37,258.91 396.37,259.91 396.37,260.91 396.37,261.90 396.37,262.90 396.37,263.90 396.38,264.90 396.38,265.89 396.38,266.89 396.38,267.89 396.38,268.89 396.38,269.88 396.38,270.88 396.38,271.88 396.38,272.88 396.39,273.87 396.39,274.87 396.39,275.87 396.39,276.87 396.39,277.86 396.39,278.86 396.39,279.86 396.39,280.86 396.40,281.85 396.40,282.85 396.40,283.85 396.40,284.84 396.40,285.84 396.40,286.84 396.40,287.84 396.40,288.83 396.41,289.83 396.41,290.83 396.41,291.83 396.41,292.82 396.41,293.82 396.41,294.82 396.41,295.82 396.41,296.81 396.41,297.81 396.42,298.81 396.42,299.81 396.42,300.80 396.42,301.80 396.42,302.80 396.42,303.80 396.42,304.79 396.42,305.79 396.43,306.79 396.43,307.79 396.43,308.78 396.43,309.78 396.43,310.78 396.43,311.78 396.43,312.77 396.43,313.77 396.44,314.77 396.44,315.77 396.44,316.76 396.44,317.76 396.44,318.76 396.44,319.70 396.38,320.82 396.19,322.03 395.86,323.20 395.40,324.34 394.83,325.41 394.14,326.42 393.34,327.34 392.49,328.13 391.50,328.86 390.44,329.47 389.30,329.96 388.12,330.31 386.91,330.52 385.76,330.59 385.17,330.59 384.65,330.59 348.29,330.61" type="driving"/>
</edge>
<edge id="-9.0.00" from="184" to="167" priority="1" type="sidewalk|shoulder|driving" shape="101.45,271.11 145.05,271.12">
<lane id="-9.0.00_0" index="0" allow="pedestrian" speed="2.78" length="43.60" width="4.00" shape="101.45,264.81 145.05,264.82" type="sidewalk"/>
<lane id="-9.0.00_1" index="1" disallow="all" speed="1.39" length="43.60" width="0.30" shape="101.45,266.96 145.05,266.97" type="shoulder"/>
<lane id="-9.0.00_2" index="2" disallow="pedestrian tram rail_urban rail rail_electric rail_fast ship" speed="13.89" length="43.60" width="4.00" shape="101.45,269.11 145.05,269.12" type="driving"/>
</edge>
<edge id="0.0.00" from="43" to="8.14" priority="1" type="sidewalk|shoulder|driving" shape="348.29,328.61 384.65,328.59 385.17,328.59 385.68,328.59 386.68,328.53 387.66,328.36 388.62,328.07 389.54,327.68 390.41,327.18 391.21,326.59 391.90,325.95 392.55,325.19 393.12,324.37 393.59,323.49 393.96,322.56 394.23,321.60 394.39,320.61 394.44,319.64 394.44,318.76 394.44,317.76 394.44,316.77 394.44,315.77 394.44,314.77 394.43,313.77 394.43,312.78 394.43,311.78 394.43,310.78 394.43,309.78 394.43,308.79 394.43,307.79 394.43,306.79 394.42,305.79 394.42,304.80 394.42,303.80 394.42,302.80 394.42,301.80 394.42,300.81 394.42,299.81 394.42,298.81 394.41,297.81 394.41,296.82 394.41,295.82 394.41,294.82 394.41,293.82 394.41,292.83 394.41,291.83 394.41,290.83 394.41,289.83 394.40,288.84 394.40,287.84 394.40,286.84 394.40,285.84 394.40,284.85 394.40,283.85 394.40,282.85 394.40,281.86 394.39,280.86 394.39,279.86 394.39,278.86 394.39,277.87 394.39,276.87 394.39,275.87 394.39,274.87 394.39,273.88 394.38,272.88 394.38,271.88 394.38,270.88 394.38,269.89 394.38,268.89 394.38,267.89 394.38,266.89 394.38,265.90 394.38,264.90 394.37,263.90 394.37,262.90 394.37,261.91 394.37,260.91 394.37,259.91 394.37,258.91 394.37,257.92 394.37,256.92 394.36,255.92 394.36,254.92 394.36,253.93 394.36,252.93 394.36,251.93 394.36,250.93 394.36,249.94 394.36,248.94 394.35,247.94 394.35,246.94 394.35,245.95 394.35,244.95 394.35,243.95 394.35,242.96 394.35,241.96 394.35,241.25 394.35,240.26 394.35,239.26 394.35,238.26 394.35,237.26 394.35,236.27 394.35,235.27 394.35,234.27 394.35,233.27 394.35,232.28 394.35,231.28 394.35,230.28 394.35,229.29 394.35,228.29 394.35,227.29 394.35,226.29 394.35,225.30 394.35,224.30 394.35,223.30 394.35,222.31 394.35,221.31 394.35,220.31 394.35,219.31 394.35,218.32 394.35,217.32 394.35,216.32 394.35,215.32 394.35,214.33 394.35,213.33 394.35,212.33 394.35,211.34 394.35,210.34 394.35,209.34 394.35,208.34 394.35,207.35 394.35,206.35 394.35,205.35 394.36,204.36 394.36,203.36 394.36,202.36 394.36,201.36 394.36,200.37 394.36,199.37 394.36,198.37 394.36,197.38 394.36,196.38 394.36,195.38 394.36,194.38 394.36,193.39 394.36,192.39 394.36,191.39 394.36,190.39 394.36,189.40 394.36,188.40 394.36,187.40 394.36,186.41 394.36,185.41 394.36,184.41 394.36,183.41 394.36,182.42 394.36,181.42 394.36,180.42 394.36,179.43 394.36,178.43 394.36,177.43 394.36,176.43 394.36,175.44 394.36,174.44 394.36,173.44 394.36,172.45 394.36,171.45 394.36,170.45 394.36,169.45 394.36,168.46 394.36,167.46 394.36,166.46 394.36,165.46 394.36,164.47 394.36,163.48 394.36,162.49 394.36,161.50 394.36,160.51 394.36,159.53 394.36,158.54 394.37,157.55 394.37,156.56 394.37,155.57 394.37,154.58 394.37,153.60 394.37,152.61 394.37,151.62 394.37,150.63 394.37,149.64 394.37,148.65 394.37,147.67 394.37,146.68 394.37,145.69 394.37,144.70 394.37,143.71 394.37,142.72 394.37,141.73 394.37,140.75 394.37,139.76 394.37,138.77 394.37,137.78 394.37,136.79 394.37,135.80 394.37,134.82 394.37,133.83 394.37,132.84 394.37,131.85 394.37,130.86 394.37,129.87 394.37,128.89 394.37,127.90 394.37,126.91 394.37,125.92 394.37,124.93 394.37,123.94 394.37,122.96 394.37,121.97 394.37,120.98 394.37,119.99 394.37,119.00 394.37,118.01 394.37,117.03 394.37,116.04 394.37,115.05 394.37,114.06 394.37,113.07 394.37,112.08 394.37,111.10 394.38,110.11 394.38,109.12 394.38,108.13 394.38,107.14 394.38,106.15 394.38,105.17 394.38,104.18 394.38,103.19 394.38,102.20 394.38,101.21 394.38,100.22 394.38,99.23 394.38,98.25 394.38,97.26 394.38,96.27 394.38,95.28 394.38,94.29 394.38,93.30 394.38,92.32 394.38,91.33 394.38,90.34 394.38,89.35 394.38,88.36 394.38,87.29 394.38,86.30 394.38,85.31 394.38,84.32 394.38,83.33 394.38,82.34 394.38,81.35 394.38,80.36 394.38,79.37 394.38,78.38 394.38,77.39 394.38,76.40 394.38,75.41 394.38,74.42 394.39,73.43 394.39,72.44 394.39,71.45 394.39,70.46 394.39,69.47 394.39,68.48 394.39,67.49 394.39,66.50 394.39,65.51 394.39,64.52 394.39,63.53 394.39,62.54 394.39,61.55 394.39,60.56 394.39,59.57 394.39,58.58 394.39,57.59 394.39,56.60 394.39,55.61 394.39,54.62 394.39,53.63 394.39,52.64 394.39,51.65 394.39,50.66 394.39,49.67 394.39,48.68 394.40,47.69 394.40,46.70 394.40,45.71 394.40,44.72 394.40,43.73 394.40,42.74 394.40,41.75 394.40,40.76 394.40,39.77 394.40,38.78 394.40,37.79 394.40,36.80 394.40,35.81 394.40,34.82 394.40,33.83 394.40,32.84 394.40,31.85 394.40,30.86 394.40,29.87 394.40,28.88 394.40,27.89 394.40,26.90 394.40,25.91 394.40,24.92 394.40,23.93 394.40,22.94 394.41,21.95 394.41,20.96 394.41,19.97 394.41,18.98 394.41,17.99 394.41,17.00 394.41,16.01 394.41,15.02 394.41,14.03 394.41,13.04 394.41,12.05 394.41,11.06 394.41,10.07">
<lane id="0.0.00_0" index="0" allow="pedestrian" speed="2.78" length="352.84" width="4.00" shape="348.29,322.31 384.65,322.29 385.16,322.29 385.44,322.29 385.95,322.26 386.21,322.22 386.47,322.14 386.72,322.03 386.96,321.90 387.18,321.73 387.36,321.57 387.56,321.34 387.73,321.09 387.87,320.82 387.99,320.54 388.07,320.24 388.12,319.94 388.14,319.47 388.14,318.77 388.14,317.77 388.14,316.77 388.14,315.78 388.14,314.78 388.13,313.78 388.13,312.78 388.13,311.79 388.13,310.79 388.13,309.79 388.13,308.79 388.13,307.80 388.13,306.80 388.12,305.80 388.12,304.80 388.12,303.81 388.12,302.81 388.12,301.81 388.12,300.81 388.12,299.82 388.12,298.82 388.11,297.82 388.11,296.82 388.11,295.83 388.11,294.83 388.11,293.83 388.11,292.83 388.11,291.84 388.11,290.84 388.11,289.84 388.10,288.84 388.10,287.85 388.10,286.85 388.10,285.85 388.10,284.85 388.10,283.86 388.10,282.86 388.10,281.86 388.09,280.87 388.09,279.87 388.09,278.87 388.09,277.87 388.09,276.88 388.09,275.88 388.09,274.88 388.09,273.88 388.08,272.89 388.08,271.89 388.08,270.89 388.08,269.89 388.08,268.90 388.08,267.90 388.08,266.90 388.08,265.90 388.08,264.91 388.07,263.91 388.07,262.91 388.07,261.91 388.07,260.92 388.07,259.92 388.07,258.92 388.07,257.92 388.07,256.93 388.06,255.93 388.06,254.93 388.06,253.93 388.06,252.94 388.06,251.94 388.06,250.94 388.06,249.94 388.06,248.95 388.05,247.95 388.05,246.95 388.05,245.96 388.05,244.96 388.05,243.96 388.05,242.96 388.05,241.96 388.05,241.25 388.05,240.25 388.05,239.26 388.05,238.26 388.05,237.26 388.05,236.26 388.05,235.27 388.05,234.27 388.05,233.27 388.05,232.28 388.05,231.28 388.05,230.28 388.05,229.28 388.05,228.29 388.05,227.29 388.05,226.29 388.05,225.30 388.05,224.30 388.05,223.30 388.05,222.30 388.05,221.31 388.05,220.31 388.05,219.31 388.05,218.32 388.05,217.32 388.05,216.32 388.05,215.32 388.05,214.33 388.05,213.33 388.05,212.33 388.05,211.33 388.05,210.34 388.05,209.34 388.05,208.34 388.05,207.35 388.05,206.35 388.05,205.35 388.06,204.35 388.06,203.36 388.06,202.36 388.06,201.36 388.06,200.37 388.06,199.37 388.06,198.37 388.06,197.37 388.06,196.38 388.06,195.38 388.06,194.38 388.06,193.39 388.06,192.39 388.06,191.39 388.06,190.39 388.06,189.40 388.06,188.40 388.06,187.40 388.06,186.40 388.06,185.41 388.06,184.41 388.06,183.41 388.06,182.42 388.06,181.42 388.06,180.42 388.06,179.42 388.06,178.43 388.06,177.43 388.06,176.43 388.06,175.44 388.06,174.44 388.06,173.44 388.06,172.44 388.06,171.45 388.06,170.45 388.06,169.45 388.06,168.45 388.06,167.46 388.06,166.46 388.06,165.46 388.06,164.47 388.06,163.48 388.06,162.49 388.06,161.50 388.06,160.51 388.06,159.52 388.06,158.54 388.07,157.55 388.07,156.56 388.07,155.57 388.07,154.58 388.07,153.59 388.07,152.61 388.07,151.62 388.07,150.63 388.07,149.64 388.07,148.65 388.07,147.66 388.07,146.68 388.07,145.69 388.07,144.70 388.07,143.71 388.07,142.72 388.07,141.73 388.07,140.75 388.07,139.76 388.07,138.77 388.07,137.78 388.07,136.79 388.07,135.80 388.07,134.81 388.07,133.83 388.07,132.84 388.07,131.85 388.07,130.86 388.07,129.87 388.07,128.88 388.07,127.90 388.07,126.91 388.07,125.92 388.07,124.93 388.07,123.94 388.07,122.95 388.07,121.97 388.07,120.98 388.07,119.99 388.07,119.00 388.07,118.01 388.07,117.02 388.07,116.04 388.07,115.05 388.07,114.06 388.07,113.07 388.07,112.08 388.07,111.09 388.08,110.11 388.08,109.12 388.08,108.13 388.08,107.14 388.08,106.15 388.08,105.16 388.08,104.18 388.08,103.19 388.08,102.20 388.08,101.21 388.08,100.22 388.08,99.23 388.08,98.25 388.08,97.26 388.08,96.27 388.08,95.28 388.08,94.29 388.08,93.30 388.08,92.31 388.08,91.33 388.08,90.34 388.08,89.35 388.08,88.36 388.08,87.28 388.08,86.29 388.08,85.30 388.08,84.31 388.08,83.32 388.08,82.33 388.08,81.34 388.08,80.35 388.08,79.36 388.08,78.37 388.08,77.38 388.08,76.39 388.08,75.40 388.08,74.41 388.09,73.42 388.09,72.43 388.09,71.44 388.09,70.45 388.09,69.46 388.09,68.47 388.09,67.48 388.09,66.49 388.09,65.50 388.09,64.51 388.09,63.52 388.09,62.53 388.09,61.54 388.09,60.55 388.09,59.56 388.09,58.57 388.09,57.58 388.09,56.59 388.09,55.60 388.09,54.62 388.09,53.63 388.09,52.64 388.09,51.65 388.09,50.66 388.09,49.67 388.09,48.68 388.10,47.69 388.10,46.70 388.10,45.71 388.10,44.72 388.10,43.73 388.10,42.74 388.10,41.75 388.10,40.76 388.10,39.77 388.10,38.78 388.10,37.79 388.10,36.80 388.10,35.81 388.10,34.82 388.10,33.83 388.10,32.84 388.10,31.85 388.10,30.86 388.10,29.87 388.10,28.88 388.10,27.89 388.10,26.90 388.10,25.91 388.10,24.92 388.10,23.93 388.10,22.94 388.11,21.95 388.11,20.96 388.11,19.97 388.11,18.98 388.11,17.99 388.11,17.00 388.11,16.01 388.11,15.02 388.11,14.03 388.11,13.04 388.11,12.05 388.11,11.57" type="sidewalk"/>
<lane id="0.0.00_1" index="1" disallow="all" speed="1.39" length="352.84" width="0.30" shape="348.29,324.46 384.65,324.44 385.16,324.44 385.52,324.44 386.20,324.40 386.71,324.31 387.21,324.16 387.68,323.96 388.13,323.70 388.56,323.39 388.91,323.06 389.26,322.65 389.57,322.21 389.82,321.73 390.03,321.23 390.17,320.71 390.26,320.17 390.29,319.53 390.29,318.77 390.29,317.77 390.29,316.77 390.29,315.77 390.29,314.78 390.28,313.78 390.28,312.78 390.28,311.78 390.28,310.79 390.28,309.79 390.28,308.79 390.28,307.79 390.28,306.80 390.27,305.80 390.27,304.80 390.27,303.80 390.27,302.81 390.27,301.81 390.27,300.81 390.27,299.81 390.27,298.82 390.26,297.82 390.26,296.82 390.26,295.82 390.26,294.83 390.26,293.83 390.26,292.83 390.26,291.83 390.26,290.84 390.26,289.84 390.25,288.84 390.25,287.84 390.25,286.85 390.25,285.85 390.25,284.85 390.25,283.85 390.25,282.86 390.25,281.86 390.24,280.86 390.24,279.87 390.24,278.87 390.24,277.87 390.24,276.87 390.24,275.88 390.24,274.88 390.24,273.88 390.23,272.88 390.23,271.89 390.23,270.89 390.23,269.89 390.23,268.89 390.23,267.90 390.23,266.90 390.23,265.90 390.23,264.90 390.22,263.91 390.22,262.91 390.22,261.91 390.22,260.91 390.22,259.92 390.22,258.92 390.22,257.92 390.22,256.92 390.21,255.93 390.21,254.93 390.21,253.93 390.21,252.93 390.21,251.94 390.21,250.94 390.21,249.94 390.21,248.94 390.20,247.95 390.20,246.95 390.20,245.95 390.20,244.96 390.20,243.96 390.20,242.96 390.20,241.96 390.20,241.25 390.20,240.25 390.20,239.26 390.20,238.26 390.20,237.26 390.20,236.27 390.20,235.27 390.20,234.27 390.20,233.27 390.20,232.28 390.20,231.28 390.20,230.28 390.20,229.28 390.20,228.29 390.20,227.29 390.20,226.29 390.20,225.30 390.20,224.30 390.20,223.30 390.20,222.30 390.20,221.31 390.20,220.31 390.20,219.31 390.20,218.32 390.20,217.32 390.20,216.32 390.20,215.32 390.20,214.33 390.20,213.33 390.20,212.33 390.20,211.34 390.20,210.34 390.20,209.34 390.20,208.34 390.20,207.35 390.20,206.35 390.20,205.35 390.21,204.35 390.21,203.36 390.21,202.36 390.21,201.36 390.21,200.37 390.21,199.37 390.21,198.37 390.21,197.37 390.21,196.38 390.21,195.38 390.21,194.38 390.21,193.39 390.21,192.39 390.21,191.39 390.21,190.39 390.21,189.40 390.21,188.40 390.21,187.40 390.21,186.41 390.21,185.41 390.21,184.41 390.21,183.41 390.21,182.42 390.21,181.42 390.21,180.42 390.21,179.42 390.21,178.43 390.21,177.43 390.21,176.43 390.21,175.44 390.21,174.44 390.21,173.44 390.21,172.44 390.21,171.45 390.21,170.45 390.21,169.45 390.21,168.46 390.21,167.46 390.21,166.46 390.21,165.46 390.21,164.47 390.21,163.48 390.21,162.49 390.21,161.50 390.21,160.51 390.21,159.52 390.21,158.54 390.22,157.55 390.22,156.56 390.22,155.57 390.22,154.58 390.22,153.59 390.22,152.61 390.22,151.62 390.22,150.63 390.22,149.64 390.22,148.65 390.22,147.66 390.22,146.68 390.22,145.69 390.22,144.70 390.22,143.71 390.22,142.72 390.22,141.73 390.22,140.75 390.22,139.76 390.22,138.77 390.22,137.78 390.22,136.79 390.22,135.80 390.22,134.82 390.22,133.83 390.22,132.84 390.22,131.85 390.22,130.86 390.22,129.87 390.22,128.89 390.22,127.90 390.22,126.91 390.22,125.92 390.22,124.93 390.22,123.94 390.22,122.95 390.22,121.97 390.22,120.98 390.22,119.99 390.22,119.00 390.22,118.01 390.22,117.02 390.22,116.04 390.22,115.05 390.22,114.06 390.22,113.07 390.22,112.08 390.22,111.09 390.23,110.11 390.23,109.12 390.23,108.13 390.23,107.14 390.23,106.15 390.23,105.16 390.23,104.18 390.23,103.19 390.23,102.20 390.23,101.21 390.23,100.22 390.23,99.23 390.23,98.25 390.23,97.26 390.23,96.27 390.23,95.28 390.23,94.29 390.23,93.30 390.23,92.32 390.23,91.33 390.23,90.34 390.23,89.35 390.23,88.36 390.23,87.28 390.23,86.29 390.23,85.30 390.23,84.31 390.23,83.32 390.23,82.33 390.23,81.34 390.23,80.35 390.23,79.36 390.23,78.37 390.23,77.38 390.23,76.39 390.23,75.40 390.23,74.41 390.24,73.42 390.24,72.43 390.24,71.44 390.24,70.45 390.24,69.46 390.24,68.48 390.24,67.49 390.24,66.50 390.24,65.51 390.24,64.52 390.24,63.53 390.24,62.54 390.24,61.55 390.24,60.56 390.24,59.57 390.24,58.58 390.24,57.59 390.24,56.60 390.24,55.61 390.24,54.62 390.24,53.63 390.24,52.64 390.24,51.65 390.24,50.66 390.24,49.67 390.24,48.68 390.25,47.69 390.25,46.70 390.25,45.71 390.25,44.72 390.25,43.73 390.25,42.74 390.25,41.75 390.25,40.76 390.25,39.77 390.25,38.78 390.25,37.79 390.25,36.80 390.25,35.81 390.25,34.82 390.25,33.83 390.25,32.84 390.25,31.85 390.25,30.86 390.25,29.87 390.25,28.88 390.25,27.89 390.25,26.90 390.25,25.91 390.25,24.92 390.25,23.93 390.25,22.94 390.26,21.95 390.26,20.96 390.26,19.97 390.26,18.98 390.26,17.99 390.26,17.00 390.26,16.01 390.26,15.02 390.26,14.03 390.26,13.04 390.26,12.05 390.26,11.57" type="shoulder"/>
<lane id="0.0.00_2" index="2" disallow="pedestrian tram rail_urban rail rail_electric rail_fast ship" speed="13.89" length="352.84" width="4.00" shape="348.29,326.61 384.65,326.59 385.17,326.59 385.61,326.59 386.45,326.54 387.20,326.41 387.94,326.19 388.65,325.89 389.31,325.50 389.93,325.05 390.46,324.56 390.97,323.97 391.41,323.33 391.77,322.64 392.06,321.92 392.27,321.17 392.40,320.40 392.44,319.59 392.44,318.76 392.44,317.76 392.44,316.77 392.44,315.77 392.44,314.77 392.43,313.78 392.43,312.78 392.43,311.78 392.43,310.78 392.43,309.79 392.43,308.79 392.43,307.79 392.43,306.79 392.42,305.80 392.42,304.80 392.42,303.80 392.42,302.80 392.42,301.81 392.42,300.81 392.42,299.81 392.42,298.81 392.41,297.82 392.41,296.82 392.41,295.82 392.41,294.82 392.41,293.83 392.41,292.83 392.41,291.83 392.41,290.83 392.41,289.84 392.40,288.84 392.40,287.84 392.40,286.84 392.40,285.85 392.40,284.85 392.40,283.85 392.40,282.85 392.40,281.86 392.39,280.86 392.39,279.86 392.39,278.87 392.39,277.87 392.39,276.87 392.39,275.87 392.39,274.88 392.39,273.88 392.38,272.88 392.38,271.88 392.38,270.89 392.38,269.89 392.38,268.89 392.38,267.89 392.38,266.90 392.38,265.90 392.38,264.90 392.37,263.90 392.37,262.91 392.37,261.91 392.37,260.91 392.37,259.91 392.37,258.92 392.37,257.92 392.37,256.92 392.36,255.92 392.36,254.93 392.36,253.93 392.36,252.93 392.36,251.93 392.36,250.94 392.36,249.94 392.36,248.94 392.35,247.94 392.35,246.95 392.35,245.95 392.35,244.95 392.35,243.96 392.35,242.96 392.35,241.96 392.35,241.25 392.35,240.25 392.35,239.26 392.35,238.26 392.35,237.26 392.35,236.27 392.35,235.27 392.35,234.27 392.35,233.27 392.35,232.28 392.35,231.28 392.35,230.28 392.35,229.29 392.35,228.29 392.35,227.29 392.35,226.29 392.35,225.30 392.35,224.30 392.35,223.30 392.35,222.30 392.35,221.31 392.35,220.31 392.35,219.31 392.35,218.32 392.35,217.32 392.35,216.32 392.35,215.32 392.35,214.33 392.35,213.33 392.35,212.33 392.35,211.34 392.35,210.34 392.35,209.34 392.35,208.34 392.35,207.35 392.35,206.35 392.35,205.35 392.36,204.36 392.36,203.36 392.36,202.36 392.36,201.36 392.36,200.37 392.36,199.37 392.36,198.37 392.36,197.37 392.36,196.38 392.36,195.38 392.36,194.38 392.36,193.39 392.36,192.39 392.36,191.39 392.36,190.39 392.36,189.40 392.36,188.40 392.36,187.40 392.36,186.41 392.36,185.41 392.36,184.41 392.36,183.41 392.36,182.42 392.36,181.42 392.36,180.42 392.36,179.43 392.36,178.43 392.36,177.43 392.36,176.43 392.36,175.44 392.36,174.44 392.36,173.44 392.36,172.44 392.36,171.45 392.36,170.45 392.36,169.45 392.36,168.46 392.36,167.46 392.36,166.46 392.36,165.46 392.36,164.47 392.36,163.48 392.36,162.49 392.36,161.50 392.36,160.51 392.36,159.53 392.36,158.54 392.37,157.55 392.37,156.56 392.37,155.57 392.37,154.58 392.37,153.59 392.37,152.61 392.37,151.62 392.37,150.63 392.37,149.64 392.37,148.65 392.37,147.66 392.37,146.68 392.37,145.69 392.37,144.70 392.37,143.71 392.37,142.72 392.37,141.73 392.37,140.75 392.37,139.76 392.37,138.77 392.37,137.78 392.37,136.79 392.37,135.80 392.37,134.82 392.37,133.83 392.37,132.84 392.37,131.85 392.37,130.86 392.37,129.87 392.37,128.89 392.37,127.90 392.37,126.91 392.37,125.92 392.37,124.93 392.37,123.94 392.37,122.96 392.37,121.97 392.37,120.98 392.37,119.99 392.37,119.00 392.37,118.01 392.37,117.03 392.37,116.04 392.37,115.05 392.37,114.06 392.37,113.07 392.37,112.08 392.37,111.09 392.38,110.11 392.38,109.12 392.38,108.13 392.38,107.14 392.38,106.15 392.38,105.16 392.38,104.18 392.38,103.19 392.38,102.20 392.38,101.21 392.38,100.22 392.38,99.23 392.38,98.25 392.38,97.26 392.38,96.27 392.38,95.28 392.38,94.29 392.38,93.30 392.38,92.32 392.38,91.33 392.38,90.34 392.38,89.35 392.38,88.36 392.38,87.28 392.38,86.29 392.38,85.30 392.38,84.31 392.38,83.33 392.38,82.34 392.38,81.35 392.38,80.36 392.38,79.37 392.38,78.38 392.38,77.39 392.38,76.40 392.38,75.41 392.38,74.42 392.39,73.43 392.39,72.44 392.39,71.45 392.39,70.46 392.39,69.47 392.39,68.48 392.39,67.49 392.39,66.50 392.39,65.51 392.39,64.52 392.39,63.53 392.39,62.54 392.39,61.55 392.39,60.56 392.39,59.57 392.39,58.58 392.39,57.59 392.39,56.60 392.39,55.61 392.39,54.62 392.39,53.63 392.39,52.64 392.39,51.65 392.39,50.66 392.39,49.67 392.39,48.68 392.40,47.69 392.40,46.70 392.40,45.71 392.40,44.72 392.40,43.73 392.40,42.74 392.40,41.75 392.40,40.76 392.40,39.77 392.40,38.78 392.40,37.79 392.40,36.80 392.40,35.81 392.40,34.82 392.40,33.83 392.40,32.84 392.40,31.85 392.40,30.86 392.40,29.87 392.40,28.88 392.40,27.89 392.40,26.90 392.40,25.91 392.40,24.92 392.40,23.93 392.40,22.94 392.41,21.95 392.41,20.96 392.41,19.97 392.41,18.98 392.41,17.99 392.41,17.00 392.41,16.01 392.41,15.02 392.41,14.03 392.41,13.04 392.41,12.05 392.41,11.57" type="driving"/>
</edge>
<edge id="1.0.00" from="26" to="43" priority="1" type="sidewalk|shoulder|driving" shape="168.14,328.65 169.13,328.65 170.12,328.65 171.11,328.65 172.10,328.65 173.09,328.65 174.08,328.65 175.07,328.65 176.06,328.65 177.05,328.65 178.04,328.65 179.03,328.65 180.02,328.65 181.00,328.65 181.99,328.65 182.98,328.65 183.97,328.65 184.96,328.65 185.95,328.65 186.94,328.65 187.93,328.65 188.92,328.65 189.91,328.65 190.90,328.65 191.89,328.65 192.88,328.65 193.87,328.65 194.86,328.65 195.85,328.65 196.83,328.65 197.83,328.65 198.83,328.65 199.82,328.65 200.82,328.65 201.81,328.65 202.81,328.65 203.80,328.65 204.80,328.65 205.80,328.65 206.79,328.65 207.79,328.65 208.78,328.65 209.78,328.65 210.77,328.65 211.77,328.65 212.76,328.65 213.76,328.65 214.76,328.65 215.75,328.65 216.75,328.65 217.74,328.65 218.74,328.65 219.73,328.65 220.73,328.65 221.73,328.65 222.72,328.65 223.72,328.65 224.71,328.65 225.71,328.65 226.70,328.65 227.70,328.65 228.69,328.65 229.69,328.65 230.69,328.65 231.68,328.65 232.68,328.65 233.67,328.65 234.67,328.65 235.66,328.65 236.66,328.65 237.66,328.65 238.65,328.65 239.65,328.65 240.64,328.65 241.64,328.65 242.63,328.65 243.63,328.64 244.62,328.64 245.62,328.64 246.62,328.64 247.61,328.64 248.61,328.64 249.60,328.64 250.60,328.64 251.59,328.64 252.59,328.64 253.59,328.64 254.58,328.64 255.58,328.64 256.57,328.64 257.57,328.64 258.56,328.64 259.56,328.64 260.55,328.64 261.55,328.64 262.55,328.64 263.54,328.64 264.54,328.64 265.53,328.64 266.53,328.64 267.52,328.64 268.52,328.64 269.52,328.64 270.51,328.64 271.51,328.64 272.50,328.64 273.50,328.64 274.49,328.64 275.49,328.64 276.49,328.64 277.48,328.64 278.48,328.64 279.47,328.64 280.47,328.64 281.46,328.64 282.46,328.64 283.45,328.64 284.45,328.64 285.45,328.64 286.44,328.64 287.44,328.64 288.43,328.64 289.43,328.64 290.42,328.64 290.64,328.64 291.61,328.64 292.58,328.64 293.56,328.64 294.53,328.64 295.50,328.64 296.48,328.64 297.45,328.64 298.43,328.64 299.40,328.64 300.37,328.63 301.35,328.63 302.32,328.63 303.29,328.63 304.27,328.63 305.24,328.63 306.21,328.63 307.19,328.63 308.16,328.63 309.14,328.63 310.11,328.63 311.08,328.63 312.06,328.63 313.03,328.63 314.00,328.63 314.98,328.63 315.95,328.63 316.92,328.63 317.90,328.63 318.87,328.62 319.85,328.62 320.82,328.62 321.79,328.62 322.77,328.62 323.74,328.62 324.71,328.62 325.69,328.62">
<lane id="1.0.00_0" index="0" allow="pedestrian" speed="2.78" length="157.54" width="4.00" shape="168.14,322.35 169.13,322.35 170.12,322.35 171.11,322.35 172.10,322.35 173.09,322.35 174.08,322.35 175.07,322.35 176.06,322.35 177.05,322.35 178.04,322.35 179.03,322.35 180.01,322.35 181.00,322.35 181.99,322.35 182.98,322.35 183.97,322.35 184.96,322.35 185.95,322.35 186.94,322.35 187.93,322.35 188.92,322.35 189.91,322.35 190.90,322.35 191.89,322.35 192.88,322.35 193.87,322.35 194.86,322.35 195.84,322.35 196.83,322.35 197.83,322.35 198.83,322.35 199.82,322.35 200.82,322.35 201.81,322.35 202.81,322.35 203.80,322.35 204.80,322.35 205.79,322.35 206.79,322.35 207.79,322.35 208.78,322.35 209.78,322.35 210.77,322.35 211.77,322.35 212.76,322.35 213.76,322.35 214.76,322.35 215.75,322.35 216.75,322.35 217.74,322.35 218.74,322.35 219.73,322.35 220.73,322.35 221.72,322.35 222.72,322.35 223.72,322.35 224.71,322.35 225.71,322.35 226.70,322.35 227.70,322.35 228.69,322.35 229.69,322.35 230.69,322.35 231.68,322.35 232.68,322.35 233.67,322.35 234.67,322.35 235.66,322.35 236.66,322.35 237.65,322.35 238.65,322.35 239.65,322.35 240.64,322.35 241.64,322.35 242.63,322.35 243.63,322.34 244.62,322.34 245.62,322.34 246.62,322.34 247.61,322.34 248.61,322.34 249.60,322.34 250.60,322.34 251.59,322.34 252.59,322.34 253.58,322.34 254.58,322.34 255.58,322.34 256.57,322.34 257.57,322.34 258.56,322.34 259.56,322.34 260.55,322.34 261.55,322.34 262.55,322.34 263.54,322.34 264.54,322.34 265.53,322.34 266.53,322.34 267.52,322.34 268.52,322.34 269.51,322.34 270.51,322.34 271.51,322.34 272.50,322.34 273.50,322.34 274.49,322.34 275.49,322.34 276.48,322.34 277.48,322.34 278.48,322.34 279.47,322.34 280.47,322.34 281.46,322.34 282.46,322.34 283.45,322.34 284.45,322.34 285.44,322.34 286.44,322.34 287.44,322.34 288.43,322.34 289.43,322.34 290.42,322.34 290.63,322.34 291.61,322.34 292.58,322.34 293.55,322.34 294.53,322.34 295.50,322.34 296.47,322.34 297.45,322.34 298.42,322.34 299.40,322.34 300.37,322.33 301.34,322.33 302.32,322.33 303.29,322.33 304.26,322.33 305.24,322.33 306.21,322.33 307.18,322.33 308.16,322.33 309.13,322.33 310.11,322.33 311.08,322.33 312.05,322.33 313.03,322.33 314.00,322.33 314.97,322.33 315.95,322.33 316.92,322.33 317.89,322.33 318.87,322.32 319.84,322.32 320.82,322.32 321.79,322.32 322.76,322.32 323.74,322.32 324.71,322.32 325.68,322.32" type="sidewalk"/>
<lane id="1.0.00_1" index="1" disallow="all" speed="1.39" length="157.54" width="0.30" shape="168.14,324.50 169.13,324.50 170.12,324.50 171.11,324.50 172.10,324.50 173.09,324.50 174.08,324.50 175.07,324.50 176.06,324.50 177.05,324.50 178.04,324.50 179.03,324.50 180.02,324.50 181.00,324.50 181.99,324.50 182.98,324.50 183.97,324.50 184.96,324.50 185.95,324.50 186.94,324.50 187.93,324.50 188.92,324.50 189.91,324.50 190.90,324.50 191.89,324.50 192.88,324.50 193.87,324.50 194.86,324.50 195.85,324.50 196.83,324.50 197.83,324.50 198.83,324.50 199.82,324.50 200.82,324.50 201.81,324.50 202.81,324.50 203.80,324.50 204.80,324.50 205.80,324.50 206.79,324.50 207.79,324.50 208.78,324.50 209.78,324.50 210.77,324.50 211.77,324.50 212.76,324.50 213.76,324.50 214.76,324.50 215.75,324.50 216.75,324.50 217.74,324.50 218.74,324.50 219.73,324.50 220.73,324.50 221.73,324.50 222.72,324.50 223.72,324.50 224.71,324.50 225.71,324.50 226.70,324.50 227.70,324.50 228.69,324.50 229.69,324.50 230.69,324.50 231.68,324.50 232.68,324.50 233.67,324.50 234.67,324.50 235.66,324.50 236.66,324.50 237.66,324.50 238.65,324.50 239.65,324.50 240.64,324.50 241.64,324.50 242.63,324.50 243.63,324.49 244.62,324.49 245.62,324.49 246.62,324.49 247.61,324.49 248.61,324.49 249.60,324.49 250.60,324.49 251.59,324.49 252.59,324.49 253.59,324.49 254.58,324.49 255.58,324.49 256.57,324.49 257.57,324.49 258.56,324.49 259.56,324.49 260.55,324.49 261.55,324.49 262.55,324.49 263.54,324.49 264.54,324.49 265.53,324.49 266.53,324.49 267.52,324.49 268.52,324.49 269.52,324.49 270.51,324.49 271.51,324.49 272.50,324.49 273.50,324.49 274.49,324.49 275.49,324.49 276.48,324.49 277.48,324.49 278.48,324.49 279.47,324.49 280.47,324.49 281.46,324.49 282.46,324.49 283.45,324.49 284.45,324.49 285.45,324.49 286.44,324.49 287.44,324.49 288.43,324.49 289.43,324.49 290.42,324.49 290.63,324.49 291.61,324.49 292.58,324.49 293.55,324.49 294.53,324.49 295.50,324.49 296.48,324.49 297.45,324.49 298.42,324.49 299.40,324.49 300.37,324.48 301.34,324.48 302.32,324.48 303.29,324.48 304.26,324.48 305.24,324.48 306.21,324.48 307.19,324.48 308.16,324.48 309.13,324.48 310.11,324.48 311.08,324.48 312.05,324.48 313.03,324.48 314.00,324.48 314.98,324.48 315.95,324.48 316.92,324.48 317.90,324.48 318.87,324.47 319.84,324.47 320.82,324.47 321.79,324.47 322.76,324.47 323.74,324.47 324.71,324.47 325.69,324.47" type="shoulder"/>
<lane id="1.0.00_2" index="2" disallow="pedestrian tram rail_urban rail rail_electric rail_fast ship" speed="13.89" length="157.54" width="4.00" shape="168.14,326.65 169.13,326.65 170.12,326.65 171.11,326.65 172.10,326.65 173.09,326.65 174.08,326.65 175.07,326.65 176.06,326.65 177.05,326.65 178.04,326.65 179.03,326.65 180.02,326.65 181.00,326.65 181.99,326.65 182.98,326.65 183.97,326.65 184.96,326.65 185.95,326.65 186.94,326.65 187.93,326.65 188.92,326.65 189.91,326.65 190.90,326.65 191.89,326.65 192.88,326.65 193.87,326.65 194.86,326.65 195.85,326.65 196.83,326.65 197.83,326.65 198.83,326.65 199.82,326.65 200.82,326.65 201.81,326.65 202.81,326.65 203.80,326.65 204.80,326.65 205.80,326.65 206.79,326.65 207.79,326.65 208.78,326.65 209.78,326.65 210.77,326.65 211.77,326.65 212.76,326.65 213.76,326.65 214.76,326.65 215.75,326.65 216.75,326.65 217.74,326.65 218.74,326.65 219.73,326.65 220.73,326.65 221.73,326.65 222.72,326.65 223.72,326.65 224.71,326.65 225.71,326.65 226.70,326.65 227.70,326.65 228.69,326.65 229.69,326.65 230.69,326.65 231.68,326.65 232.68,326.65 233.67,326.65 234.67,326.65 235.66,326.65 236.66,326.65 237.66,326.65 238.65,326.65 239.65,326.65 240.64,326.65 241.64,326.65 242.63,326.65 243.63,326.64 244.62,326.64 245.62,326.64 246.62,326.64 247.61,326.64 248.61,326.64 249.60,326.64 250.60,326.64 251.59,326.64 252.59,326.64 253.59,326.64 254.58,326.64 255.58,326.64 256.57,326.64 257.57,326.64 258.56,326.64 259.56,326.64 260.55,326.64 261.55,326.64 262.55,326.64 263.54,326.64 264.54,326.64 265.53,326.64 266.53,326.64 267.52,326.64 268.52,326.64 269.52,326.64 270.51,326.64 271.51,326.64 272.50,326.64 273.50,326.64 274.49,326.64 275.49,326.64 276.48,326.64 277.48,326.64 278.48,326.64 279.47,326.64 280.47,326.64 281.46,326.64 282.46,326.64 283.45,326.64 284.45,326.64 285.45,326.64 286.44,326.64 287.44,326.64 288.43,326.64 289.43,326.64 290.42,326.64 290.64,326.64 291.61,326.64 292.58,326.64 293.56,326.64 294.53,326.64 295.50,326.64 296.48,326.64 297.45,326.64 298.42,326.64 299.40,326.64 300.37,326.63 301.35,326.63 302.32,326.63 303.29,326.63 304.27,326.63 305.24,326.63 306.21,326.63 307.19,326.63 308.16,326.63 309.13,326.63 310.11,326.63 311.08,326.63 312.06,326.63 313.03,326.63 314.00,326.63 314.98,326.63 315.95,326.63 316.92,326.63 317.90,326.63 318.87,326.62 319.84,326.62 320.82,326.62 321.79,326.62 322.77,326.62 323.74,326.62 324.71,326.62 325.69,326.62" type="driving"/>
</edge>
<edge id="10.0.00" from="111" to="167" priority="1" type="sidewalk|shoulder|driving" shape="325.69,271.14 167.23,271.12">
<lane id="10.0.00_0" index="0" allow="pedestrian" speed="2.78" length="158.45" width="4.00" shape="325.69,277.44 167.23,277.42" type="sidewalk"/>
<lane id="10.0.00_1" index="1" disallow="all" speed="1.39" length="158.45" width="0.30" shape="325.69,275.29 167.23,275.27" type="shoulder"/>
<lane id="10.0.00_2" index="2" disallow="pedestrian tram rail_urban rail rail_electric rail_fast ship" speed="13.89" length="158.45" width="4.00" shape="325.69,273.14 167.23,273.12" type="driving"/>
</edge>
<edge id="12.0.00" from="94" to="128" priority="1" type="sidewalk|shoulder|driving" shape="325.73,131.45 101.48,131.47">
<lane id="12.0.00_0" index="0" allow="pedestrian" speed="2.78" length="224.24" width="4.00" shape="325.73,137.75 101.49,137.77" type="sidewalk"/>
<lane id="12.0.00_1" index="1" disallow="all" speed="1.39" length="224.24" width="0.30" shape="325.73,135.60 101.49,135.62" type="shoulder"/>
<lane id="12.0.00_2" index="2" disallow="pedestrian tram rail_urban rail rail_electric rail_fast ship" speed="13.89" length="224.24" width="4.00" shape="325.73,133.45 101.49,133.47" type="driving"/>
</edge>
<edge id="14.0.00" from="7.14" to="8.14" priority="1" type="sidewalk|shoulder|driving" shape="384.14,0.00 384.81,0.00 385.15,0.01 386.14,0.09 387.13,0.27 388.09,0.54 389.02,0.91 389.91,1.37 390.75,1.91 391.53,2.53 391.68,2.67 392.38,3.39 392.98,4.19 393.49,5.05 393.89,5.96 394.18,6.92 394.35,7.90 394.41,8.90 394.41,9.49 394.41,10.07">
<lane id="14.0.00_0" index="0" allow="pedestrian" speed="2.78" length="4.40" width="4.00" shape="395.00,-2.75 395.50,-2.36 396.17,-1.76 397.17,-0.71 398.22,0.68 398.46,1.08" type="sidewalk"/>
<lane id="14.0.00_1" index="1" disallow="all" speed="1.39" length="4.40" width="0.30" shape="393.67,-1.07 394.14,-0.69 394.64,-0.24 395.53,0.69 396.43,1.87 396.61,2.17" type="shoulder"/>
<lane id="14.0.00_2" index="2" disallow="pedestrian tram rail_urban rail rail_electric rail_fast ship" speed="13.89" length="4.40" width="4.00" shape="392.33,0.61 392.79,0.98 393.11,1.27 393.90,2.09 394.64,3.07 394.75,3.26" type="driving"/>
</edge>
<edge id="16.0.00" from="111" to="43" priority="1" type="sidewalk|shoulder|driving" shape="336.93,282.19 336.95,317.82">
<lane id="16.0.00_0" index="0" allow="pedestrian" speed="2.78" length="35.62" width="4.00" shape="343.23,282.19 343.25,317.81" type="sidewalk"/>
<lane id="16.0.00_1" index="1" disallow="all" speed="1.39" length="35.62" width="0.30" shape="341.08,282.19 341.10,317.81" type="shoulder"/>
<lane id="16.0.00_2" index="2" disallow="pedestrian tram rail_urban rail rail_electric rail_fast ship" speed="13.89" length="35.62" width="4.00" shape="338.93,282.19 338.95,317.81" type="driving"/>
</edge>
<edge id="17.0.00" from="139" to="111" priority="1" type="sidewalk|shoulder|driving" shape="336.89,208.03 336.92,259.58">
<lane id="17.0.00_0" index="0" allow="pedestrian" speed="2.78" length="51.55" width="4.00" shape="343.19,208.03 343.22,259.57" type="sidewalk"/>
<lane id="17.0.00_1" index="1" disallow="all" speed="1.39" length="51.55" width="0.30" shape="341.04,208.03 341.07,259.58" type="shoulder"/>
<lane id="17.0.00_2" index="2" disallow="pedestrian tram rail_urban rail rail_electric rail_fast ship" speed="13.89" length="51.55" width="4.00" shape="338.89,208.03 338.92,259.58" type="driving"/>
</edge>
<edge id="18.0.00" from="94" to="139" priority="1" type="sidewalk|shoulder|driving" shape="336.85,142.96 336.87,184.94">
<lane id="18.0.00_0" index="0" allow="pedestrian" speed="2.78" length="41.99" width="4.00" shape="343.15,142.95 343.17,184.94" type="sidewalk"/>
<lane id="18.0.00_1" index="1" disallow="all" speed="1.39" length="41.99" width="0.30" shape="341.00,142.96 341.02,184.94" type="shoulder"/>
<lane id="18.0.00_2" index="2" disallow="pedestrian tram rail_urban rail rail_electric rail_fast ship" speed="13.89" length="41.99" width="4.00" shape="338.85,142.96 338.87,184.94" type="driving"/>
</edge>
<edge id="19.0.00" from="60" to="94" priority="1" type="sidewalk|shoulder|driving" shape="336.77,11.16 336.83,119.45">
<lane id="19.0.00_0" index="0" allow="pedestrian" speed="2.78" length="108.29" width="4.00" shape="343.07,11.15 343.13,119.45" type="sidewalk"/>
<lane id="19.0.00_1" index="1" disallow="all" speed="1.39" length="108.29" width="0.30" shape="340.92,11.16 340.98,119.45" type="shoulder"/>
<lane id="19.0.00_2" index="2" disallow="pedestrian tram rail_urban rail rail_electric rail_fast ship" speed="13.89" length="108.29" width="4.00" shape="338.77,11.16 338.83,119.45" type="driving"/>
</edge>
<edge id="2.0.00" from="77" to="26" priority="1" type="sidewalk|shoulder|driving" shape="102.75,328.66 103.03,328.66 103.25,328.66 104.24,328.66 105.24,328.66 106.23,328.66 107.23,328.66 108.22,328.66 109.21,328.66 110.21,328.66 111.20,328.66 112.20,328.66 113.19,328.66 114.19,328.66 115.18,328.66 116.18,328.66 117.17,328.66 118.17,328.66 119.16,328.66 120.15,328.66 121.15,328.66 122.14,328.66 123.14,328.66 124.13,328.66 125.13,328.66 126.12,328.66 127.12,328.66 128.11,328.66 129.10,328.66 130.10,328.66 131.09,328.66 132.09,328.66 133.08,328.66 134.08,328.66 135.07,328.66 136.07,328.66 137.06,328.66 138.05,328.66 139.05,328.66 140.04,328.66 141.04,328.66 142.03,328.66 143.03,328.66 144.02,328.66 145.02,328.66">
<lane id="2.0.00_0" index="0" allow="pedestrian" speed="2.78" length="42.26" width="4.00" shape="102.76,322.36 103.03,322.36 103.25,322.36 104.24,322.36 105.24,322.36 106.23,322.36 107.23,322.36 108.22,322.36 109.21,322.36 110.21,322.36 111.20,322.36 112.20,322.36 113.19,322.36 114.19,322.36 115.18,322.36 116.18,322.36 117.17,322.36 118.16,322.36 119.16,322.36 120.15,322.36 121.15,322.36 122.14,322.36 123.14,322.36 124.13,322.36 125.13,322.36 126.12,322.36 127.11,322.36 128.11,322.36 129.10,322.36 130.10,322.36 131.09,322.36 132.09,322.36 133.08,322.36 134.08,322.36 135.07,322.36 136.06,322.36 137.06,322.36 138.05,322.36 139.05,322.36 140.04,322.36 141.04,322.36 142.03,322.36 143.03,322.36 144.02,322.36 145.02,322.36" type="sidewalk"/>
<lane id="2.0.00_1" index="1" disallow="all" speed="1.39" length="42.26" width="0.30" shape="102.76,324.51 103.03,324.51 103.25,324.51 104.24,324.51 105.24,324.51 106.23,324.51 107.23,324.51 108.22,324.51 109.21,324.51 110.21,324.51 111.20,324.51 112.20,324.51 113.19,324.51 114.19,324.51 115.18,324.51 116.18,324.51 117.17,324.51 118.16,324.51 119.16,324.51 120.15,324.51 121.15,324.51 122.14,324.51 123.14,324.51 124.13,324.51 125.13,324.51 126.12,324.51 127.11,324.51 128.11,324.51 129.10,324.51 130.10,324.51 131.09,324.51 132.09,324.51 133.08,324.51 134.08,324.51 135.07,324.51 136.07,324.51 137.06,324.51 138.05,324.51 139.05,324.51 140.04,324.51 141.04,324.51 142.03,324.51 143.03,324.51 144.02,324.51 145.02,324.51" type="shoulder"/>
<lane id="2.0.00_2" index="2" disallow="pedestrian tram rail_urban rail rail_electric rail_fast ship" speed="13.89" length="42.26" width="4.00" shape="102.75,326.66 103.03,326.66 103.25,326.66 104.24,326.66 105.24,326.66 106.23,326.66 107.23,326.66 108.22,326.66 109.21,326.66 110.21,326.66 111.20,326.66 112.20,326.66 113.19,326.66 114.19,326.66 115.18,326.66 116.18,326.66 117.17,326.66 118.16,326.66 119.16,326.66 120.15,326.66 121.15,326.66 122.14,326.66 123.14,326.66 124.13,326.66 125.13,326.66 126.12,326.66 127.12,326.66 128.11,326.66 129.10,326.66 130.10,326.66 131.09,326.66 132.09,326.66 133.08,326.66 134.08,326.66 135.07,326.66 136.07,326.66 137.06,326.66 138.05,326.66 139.05,326.66 140.04,326.66 141.04,326.66 142.03,326.66 143.03,326.66 144.02,326.66 145.02,326.66" type="driving"/>
</edge>
<edge id="21.0.00" from="184" to="77" priority="1" type="sidewalk|shoulder|driving" shape="90.44,282.46 90.43,317.94">
<lane id="21.0.00_0" index="0" allow="pedestrian" speed="2.78" length="35.49" width="4.00" shape="96.74,282.46 96.73,317.94" type="sidewalk"/>
<lane id="21.0.00_1" index="1" disallow="all" speed="1.39" length="35.49" width="0.30" shape="94.59,282.46 94.58,317.94" type="shoulder"/>
<lane id="21.0.00_2" index="2" disallow="pedestrian tram rail_urban rail rail_electric rail_fast ship" speed="13.89" length="35.49" width="4.00" shape="92.44,282.46 92.43,317.94" type="driving"/>
</edge>
<edge id="22.0.00" from="156" to="184" priority="1" type="sidewalk|shoulder|driving" shape="90.45,208.77 90.44,260.46">
<lane id="22.0.00_0" index="0" allow="pedestrian" speed="2.78" length="51.68" width="4.00" shape="96.75,208.78 96.74,260.46" type="sidewalk"/>
<lane id="22.0.00_1" index="1" disallow="all" speed="1.39" length="51.68" width="0.30" shape="94.60,208.78 94.59,260.46" type="shoulder"/>
<lane id="22.0.00_2" index="2" disallow="pedestrian tram rail_urban rail rail_electric rail_fast ship" speed="13.89" length="51.68" width="4.00" shape="92.45,208.77 92.44,260.46" type="driving"/>
</edge>
<edge id="23.0.00" from="128" to="156" priority="1" type="sidewalk|shoulder|driving" shape="90.46,142.28 90.45,186.77">
<lane id="23.0.00_0" index="0" allow="pedestrian" speed="2.78" length="44.49" width="4.00" shape="96.76,142.29 96.75,186.78" type="sidewalk"/>
<lane id="23.0.00_1" index="1" disallow="all" speed="1.39" length="44.49" width="0.30" shape="94.61,142.29 94.60,186.78" type="shoulder"/>
<lane id="23.0.00_2" index="2" disallow="pedestrian tram rail_urban rail rail_electric rail_fast ship" speed="13.89" length="44.49" width="4.00" shape="92.46,142.29 92.45,186.77" type="driving"/>
</edge>
<edge id="24.0.00" from="195" to="128" priority="1" type="sidewalk|shoulder|driving" shape="90.48,11.31 90.46,120.28">
<lane id="24.0.00_0" index="0" allow="pedestrian" speed="2.78" length="108.98" width="4.00" shape="96.78,11.31 96.76,120.29" type="sidewalk"/>
<lane id="24.0.00_1" index="1" disallow="all" speed="1.39" length="108.98" width="0.30" shape="94.63,11.31 94.61,120.29" type="shoulder"/>
<lane id="24.0.00_2" index="2" disallow="pedestrian tram rail_urban rail rail_electric rail_fast ship" speed="13.89" length="108.98" width="4.00" shape="92.48,11.31 92.46,120.28" type="driving"/>
</edge>
<edge id="25.0.00" from="167" to="26" priority="1" type="sidewalk|shoulder|driving" shape="156.08,282.41 156.13,317.90">
<lane id="25.0.00_0" index="0" allow="pedestrian" speed="2.78" length="35.49" width="4.00" shape="162.38,282.41 162.43,317.89" type="sidewalk"/>
<lane id="25.0.00_1" index="1" disallow="all" speed="1.39" length="35.49" width="0.30" shape="160.23,282.41 160.28,317.90" type="shoulder"/>
<lane id="25.0.00_2" index="2" disallow="pedestrian tram rail_urban rail rail_electric rail_fast ship" speed="13.89" length="35.49" width="4.00" shape="158.08,282.41 158.13,317.90" type="driving"/>
</edge>
<edge id="4.0.00" from="139" to="156" priority="1" type="sidewalk|shoulder|driving" shape="325.70,197.09 101.48,197.20">
<lane id="4.0.00_0" index="0" allow="pedestrian" speed="2.78" length="224.22" width="4.00" shape="325.70,203.39 101.48,203.50" type="sidewalk"/>
<lane id="4.0.00_1" index="1" disallow="all" speed="1.39" length="224.22" width="0.30" shape="325.70,201.24 101.48,201.35" type="shoulder"/>
<lane id="4.0.00_2" index="2" disallow="pedestrian tram rail_urban rail rail_electric rail_fast ship" speed="13.89" length="224.22" width="4.00" shape="325.70,199.09 101.48,199.20" type="driving"/>
</edge>
<edge id="5.0.00" from="195" to="77" priority="1" type="sidewalk|shoulder|driving" shape="79.47,0.03 10.07,0.07 9.42,0.07 8.42,0.13 7.44,0.30 6.48,0.58 5.56,0.98 4.69,1.47 3.88,2.06 3.15,2.74 2.68,3.27 2.08,4.07 1.55,4.92 1.10,5.82 0.73,6.74 0.44,7.70 0.23,8.68 0.11,9.67 0.07,10.60 0.07,11.01 0.07,12.00 0.07,13.00 0.07,13.99 0.07,14.98 0.07,15.97 0.07,16.97 0.07,17.96 0.07,18.95 0.07,19.94 0.07,20.94 0.07,21.93 0.07,22.92 0.07,23.91 0.07,24.91 0.07,25.90 0.07,26.89 0.07,27.88 0.07,28.88 0.07,29.87 0.07,30.86 0.07,31.85 0.07,32.85 0.07,33.84 0.07,34.83 0.07,35.82 0.07,36.82 0.07,37.81 0.07,38.80 0.07,39.79 0.07,40.79 0.07,41.78 0.07,42.77 0.07,43.76 0.07,44.76 0.07,45.75 0.07,46.74 0.07,47.73 0.07,48.73 0.07,49.72 0.08,50.71 0.08,51.70 0.08,52.70 0.08,53.69 0.08,54.68 0.08,55.67 0.08,56.67 0.08,57.66 0.08,58.65 0.08,59.65 0.08,60.64 0.08,61.63 0.08,62.62 0.08,63.62 0.08,64.61 0.08,65.60 0.08,66.59 0.08,67.59 0.08,68.58 0.08,69.57 0.08,70.56 0.08,71.56 0.08,72.55 0.08,73.54 0.08,74.53 0.08,75.53 0.08,76.52 0.08,77.51 0.08,78.50 0.08,79.50 0.08,80.49 0.08,81.48 0.08,82.47 0.08,83.47 0.08,84.46 0.08,85.45 0.08,86.44 0.08,87.44 0.08,87.76 0.08,88.76 0.08,89.75 0.08,90.74 0.08,91.73 0.08,92.73 0.08,93.72 0.08,94.71 0.08,95.70 0.08,96.70 0.07,97.69 0.07,98.68 0.07,99.67 0.07,100.67 0.07,101.66 0.07,102.65 0.07,103.64 0.07,104.64 0.07,105.63 0.07,106.62 0.07,107.61 0.07,108.61 0.07,109.60 0.07,110.59 0.07,111.58 0.07,112.58 0.07,113.57 0.07,114.56 0.07,115.55 0.06,116.55 0.06,117.54 0.06,118.53 0.06,119.52 0.06,120.52 0.06,121.51 0.06,122.50 0.06,123.49 0.06,124.49 0.06,125.48 0.06,126.47 0.06,127.46 0.06,128.46 0.06,129.45 0.06,130.44 0.06,131.43 0.06,132.43 0.06,133.42 0.06,134.41 0.05,135.40 0.05,136.40 0.05,137.39 0.05,138.38 0.05,139.37 0.05,140.37 0.05,141.36 0.05,142.35 0.05,143.34 0.05,144.34 0.05,145.33 0.05,146.32 0.05,147.31 0.05,148.31 0.05,149.30 0.05,150.29 0.05,151.28 0.05,152.28 0.05,153.27 0.05,154.26 0.04,155.25 0.04,156.25 0.04,157.24 0.04,158.23 0.04,159.22 0.04,160.22 0.04,161.21 0.04,162.20 0.04,163.19 0.04,164.18 0.04,165.18 0.04,166.17 0.04,167.16 0.04,168.15 0.04,169.14 0.04,170.13 0.04,171.13 0.04,172.12 0.04,173.11 0.03,174.10 0.03,175.09 0.03,176.08 0.03,177.08 0.03,178.07 0.03,179.06 0.03,180.05 0.03,181.04 0.03,182.03 0.03,183.03 0.03,184.02 0.03,185.01 0.03,186.00 0.03,186.99 0.03,187.98 0.03,188.98 0.03,189.97 0.03,190.96 0.03,191.95 0.02,192.94 0.02,193.93 0.02,194.93 0.02,195.92 0.02,196.91 0.02,197.90 0.02,198.89 0.02,199.88 0.02,200.88 0.02,201.87 0.02,202.86 0.02,203.85 0.02,204.84 0.02,205.83 0.02,206.83 0.02,207.82 0.02,208.81 0.02,209.80 0.02,210.79 0.02,211.78 0.01,212.78 0.01,213.77 0.01,214.76 0.01,215.75 0.01,216.74 0.01,217.73 0.01,218.73 0.01,219.72 0.01,220.71 0.01,221.70 0.01,222.69 0.01,223.68 0.01,224.68 0.01,225.67 0.01,226.66 0.01,227.65 0.01,228.64 0.01,229.63 0.01,230.63 0.00,231.62 0.00,232.61 0.00,233.60 0.00,234.59 0.00,235.58 0.00,236.58 0.00,237.57 0.00,238.56 0.00,239.55 0.00,240.54 0.00,241.00 0.00,241.99 0.00,242.99 0.00,243.98 0.00,244.98 0.00,245.97 0.00,246.97 0.00,247.97 0.00,248.96 0.00,249.96 0.00,250.95 0.00,251.95 0.00,252.94 0.00,253.94 0.01,254.93 0.01,255.93 0.01,256.93 0.01,257.92 0.01,258.92 0.01,259.91 0.01,260.91 0.01,261.90 0.01,262.90 0.01,263.89 0.01,264.89 0.01,265.89 0.01,266.88 0.01,267.88 0.01,268.87 0.01,269.87 0.01,270.86 0.01,271.86 0.01,272.85 0.01,273.85 0.01,274.85 0.01,275.84 0.01,276.84 0.01,277.83 0.01,278.83 0.01,279.82 0.02,280.82 0.02,281.81 0.02,282.81 0.02,283.81 0.02,284.80 0.02,285.80 0.02,286.79 0.02,287.79 0.02,288.78 0.02,289.78 0.02,290.77 0.02,291.77 0.02,292.77 0.02,293.76 0.02,294.76 0.02,295.75 0.02,296.75 0.02,297.74 0.02,298.74 0.02,299.73 0.02,300.73 0.02,301.73 0.02,302.72 0.02,303.72 0.02,304.71 0.02,305.71 0.03,306.70 0.03,307.70 0.03,308.69 0.03,309.69 0.03,310.69 0.03,311.68 0.03,312.68 0.03,313.67 0.03,314.67 0.03,315.66 0.03,316.66 0.03,317.65 0.03,318.65 0.03,319.34 0.03,320.03 0.09,321.03 0.27,322.01 0.57,322.97 0.99,323.88 1.51,324.73 2.13,325.51 2.81,326.18 3.59,326.80 4.43,327.34 5.33,327.79 6.26,328.15 7.22,328.41 8.21,328.57 9.21,328.63 10.19,328.63 11.09,328.63 79.44,328.65">
<lane id="5.0.00_0" index="0" allow="pedestrian" speed="2.78" length="466.26" width="4.00" shape="79.48,6.33 10.07,6.37 9.64,6.37 9.15,6.40 8.88,6.44 8.61,6.52 8.36,6.63 8.12,6.77 7.90,6.93 7.62,7.18 7.59,7.21 7.29,7.62 7.05,8.01 6.84,8.42 6.67,8.84 6.54,9.28 6.44,9.72 6.39,10.19 6.37,10.78 6.37,11.01 6.37,12.00 6.37,12.99 6.37,13.99 6.37,14.98 6.37,15.97 6.37,16.96 6.37,17.96 6.37,18.95 6.37,19.94 6.37,20.93 6.37,21.93 6.37,22.92 6.37,23.91 6.37,24.90 6.37,25.90 6.37,26.89 6.37,27.88 6.37,28.88 6.37,29.87 6.37,30.86 6.37,31.85 6.37,32.85 6.37,33.84 6.37,34.83 6.37,35.82 6.37,36.82 6.37,37.81 6.37,38.80 6.37,39.79 6.37,40.79 6.37,41.78 6.37,42.77 6.37,43.76 6.37,44.76 6.37,45.75 6.37,46.74 6.37,47.73 6.37,48.73 6.37,49.72 6.38,50.71 6.38,51.70 6.38,52.70 6.38,53.69 6.38,54.68 6.38,55.67 6.38,56.67 6.38,57.66 6.38,58.65 6.38,59.64 6.38,60.64 6.38,61.63 6.38,62.62 6.38,63.61 6.38,64.61 6.38,65.60 6.38,66.59 6.38,67.58 6.38,68.58 6.38,69.57 6.38,70.56 6.38,71.56 6.38,72.55 6.38,73.54 6.38,74.53 6.38,75.53 6.38,76.52 6.38,77.51 6.38,78.50 6.38,79.50 6.38,80.49 6.38,81.48 6.38,82.47 6.38,83.47 6.38,84.46 6.38,85.45 6.38,86.44 6.38,87.44 6.38,87.77 6.38,88.76 6.38,89.75 6.38,90.74 6.38,91.74 6.38,92.73 6.38,93.72 6.38,94.71 6.38,95.71 6.38,96.70 6.37,97.69 6.37,98.68 6.37,99.68 6.37,100.67 6.37,101.66 6.37,102.65 6.37,103.65 6.37,104.64 6.37,105.63 6.37,106.62 6.37,107.62 6.37,108.61 6.37,109.60 6.37,110.59 6.37,111.59 6.37,112.58 6.37,113.57 6.37,114.56 6.37,115.56 6.36,116.55 6.36,117.54 6.36,118.53 6.36,119.53 6.36,120.52 6.36,121.51 6.36,122.50 6.36,123.50 6.36,124.49 6.36,125.48 6.36,126.47 6.36,127.47 6.36,128.46 6.36,129.45 6.36,130.44 6.36,131.44 6.36,132.43 6.36,133.42 6.36,134.41 6.35,135.41 6.35,136.40 6.35,137.39 6.35,138.38 6.35,139.38 6.35,140.37 6.35,141.36 6.35,142.35 6.35,143.35 6.35,144.34 6.35,145.33 6.35,146.32 6.35,147.32 6.35,148.31 6.35,149.30 6.35,150.29 6.35,151.29 6.35,152.28 6.35,153.27 6.35,154.26 6.34,155.26 6.34,156.25 6.34,157.24 6.34,158.23 6.34,159.23 6.34,160.22 6.34,161.21 6.34,162.20 6.34,163.20 6.34,164.19 6.34,165.18 6.34,166.17 6.34,167.16 6.34,168.15 6.34,169.15 6.34,170.14 6.34,171.13 6.34,172.12 6.34,173.11 6.33,174.10 6.33,175.10 6.33,176.09 6.33,177.08 6.33,178.07 6.33,179.06 6.33,180.05 6.33,181.05 6.33,182.04 6.33,183.03 6.33,184.02 6.33,185.01 6.33,186.00 6.33,187.00 6.33,187.99 6.33,188.98 6.33,189.97 6.33,190.96 6.33,191.95 6.32,192.95 6.32,193.94 6.32,194.93 6.32,195.92 6.32,196.91 6.32,197.90 6.32,198.90 6.32,199.89 6.32,200.88 6.32,201.87 6.32,202.86 6.32,203.85 6.32,204.85 6.32,205.84 6.32,206.83 6.32,207.82 6.32,208.81 6.32,209.80 6.32,210.80 6.32,211.79 6.31,212.78 6.31,213.77 6.31,214.76 6.31,215.75 6.31,216.75 6.31,217.74 6.31,218.73 6.31,219.72 6.31,220.71 6.31,221.70 6.31,222.70 6.31,223.69 6.31,224.68 6.31,225.67 6.31,226.66 6.31,227.65 6.31,228.65 6.31,229.64 6.31,230.63 6.30,231.62 6.30,232.61 6.30,233.60 6.30,234.60 6.30,235.59 6.30,236.58 6.30,237.57 6.30,238.56 6.30,239.55 6.30,240.55 6.30,241.00 6.30,241.99 6.30,242.99 6.30,243.98 6.30,244.98 6.30,245.97 6.30,246.97 6.30,247.96 6.30,248.96 6.30,249.95 6.30,250.95 6.30,251.95 6.30,252.94 6.30,253.94 6.31,254.93 6.31,255.93 6.31,256.92 6.31,257.92 6.31,258.91 6.31,259.91 6.31,260.91 6.31,261.90 6.31,262.90 6.31,263.89 6.31,264.89 6.31,265.88 6.31,266.88 6.31,267.87 6.31,268.87 6.31,269.87 6.31,270.86 6.31,271.86 6.31,272.85 6.31,273.85 6.31,274.84 6.31,275.84 6.31,276.83 6.31,277.83 6.31,278.83 6.31,279.82 6.32,280.82 6.32,281.81 6.32,282.81 6.32,283.80 6.32,284.80 6.32,285.79 6.32,286.79 6.32,287.79 6.32,288.78 6.32,289.78 6.32,290.77 6.32,291.77 6.32,292.76 6.32,293.76 6.32,294.75 6.32,295.75 6.32,296.75 6.32,297.74 6.32,298.74 6.32,299.73 6.32,300.73 6.32,301.72 6.32,302.72 6.32,303.71 6.32,304.71 6.32,305.71 6.33,306.70 6.33,307.70 6.33,308.69 6.33,309.69 6.33,310.68 6.33,311.68 6.33,312.67 6.33,313.67 6.33,314.67 6.33,315.66 6.33,316.66 6.33,317.65 6.33,318.65 6.33,319.34 6.33,319.80 6.36,320.26 6.40,320.49 6.47,320.71 6.56,320.91 6.68,321.11 6.83,321.30 7.00,321.46 7.26,321.67 7.56,321.86 7.88,322.02 8.21,322.15 8.55,322.24 8.91,322.30 9.40,322.33 10.19,322.33 11.09,322.33 79.44,322.35" type="sidewalk"/>
<lane id="5.0.00_1" index="1" disallow="all" speed="1.39" length="466.26" width="0.30" shape="79.48,4.18 10.07,4.22 9.57,4.22 8.90,4.26 8.39,4.35 7.88,4.50 7.40,4.70 6.95,4.96 6.53,5.27 6.09,5.67 5.92,5.87 5.51,6.41 5.17,6.96 4.88,7.53 4.64,8.12 4.46,8.74 4.32,9.37 4.24,10.01 4.22,10.72 4.22,11.01 4.22,12.00 4.22,12.99 4.22,13.99 4.22,14.98 4.22,15.97 4.22,16.96 4.22,17.96 4.22,18.95 4.22,19.94 4.22,20.93 4.22,21.93 4.22,22.92 4.22,23.91 4.22,24.91 4.22,25.90 4.22,26.89 4.22,27.88 4.22,28.88 4.22,29.87 4.22,30.86 4.22,31.85 4.22,32.85 4.22,33.84 4.22,34.83 4.22,35.82 4.22,36.82 4.22,37.81 4.22,38.80 4.22,39.79 4.22,40.79 4.22,41.78 4.22,42.77 4.22,43.76 4.22,44.76 4.22,45.75 4.22,46.74 4.22,47.73 4.22,48.73 4.22,49.72 4.23,50.71 4.23,51.70 4.23,52.70 4.23,53.69 4.23,54.68 4.23,55.67 4.23,56.67 4.23,57.66 4.23,58.65 4.23,59.64 4.23,60.64 4.23,61.63 4.23,62.62 4.23,63.61 4.23,64.61 4.23,65.60 4.23,66.59 4.23,67.59 4.23,68.58 4.23,69.57 4.23,70.56 4.23,71.56 4.23,72.55 4.23,73.54 4.23,74.53 4.23,75.53 4.23,76.52 4.23,77.51 4.23,78.50 4.23,79.50 4.23,80.49 4.23,81.48 4.23,82.47 4.23,83.47 4.23,84.46 4.23,85.45 4.23,86.44 4.23,87.44 4.23,87.77 4.23,88.76 4.23,89.75 4.23,90.74 4.23,91.74 4.23,92.73 4.23,93.72 4.23,94.71 4.23,95.71 4.23,96.70 4.22,97.69 4.22,98.68 4.22,99.68 4.22,100.67 4.22,101.66 4.22,102.65 4.22,103.65 4.22,104.64 4.22,105.63 4.22,106.62 4.22,107.62 4.22,108.61 4.22,109.60 4.22,110.59 4.22,111.59 4.22,112.58 4.22,113.57 4.22,114.56 4.22,115.56 4.21,116.55 4.21,117.54 4.21,118.53 4.21,119.53 4.21,120.52 4.21,121.51 4.21,122.50 4.21,123.50 4.21,124.49 4.21,125.48 4.21,126.47 4.21,127.47 4.21,128.46 4.21,129.45 4.21,130.44 4.21,131.43 4.21,132.43 4.21,133.42 4.21,134.41 4.20,135.40 4.20,136.40 4.20,137.39 4.20,138.38 4.20,139.37 4.20,140.37 4.20,141.36 4.20,142.35 4.20,143.34 4.20,144.34 4.20,145.33 4.20,146.32 4.20,147.31 4.20,148.31 4.20,149.30 4.20,150.29 4.20,151.28 4.20,152.28 4.20,153.27 4.20,154.26 4.19,155.25 4.19,156.25 4.19,157.24 4.19,158.23 4.19,159.22 4.19,160.22 4.19,161.21 4.19,162.20 4.19,163.19 4.19,164.19 4.19,165.18 4.19,166.17 4.19,167.16 4.19,168.15 4.19,169.15 4.19,170.14 4.19,171.13 4.19,172.12 4.19,173.11 4.18,174.10 4.18,175.10 4.18,176.09 4.18,177.08 4.18,178.07 4.18,179.06 4.18,180.05 4.18,181.05 4.18,182.04 4.18,183.03 4.18,184.02 4.18,185.01 4.18,186.00 4.18,187.00 4.18,187.99 4.18,188.98 4.18,189.97 4.18,190.96 4.18,191.95 4.17,192.95 4.17,193.94 4.17,194.93 4.17,195.92 4.17,196.91 4.17,197.90 4.17,198.90 4.17,199.89 4.17,200.88 4.17,201.87 4.17,202.86 4.17,203.85 4.17,204.85 4.17,205.84 4.17,206.83 4.17,207.82 4.17,208.81 4.17,209.80 4.17,210.80 4.17,211.79 4.16,212.78 4.16,213.77 4.16,214.76 4.16,215.75 4.16,216.75 4.16,217.74 4.16,218.73 4.16,219.72 4.16,220.71 4.16,221.70 4.16,222.70 4.16,223.69 4.16,224.68 4.16,225.67 4.16,226.66 4.16,227.65 4.16,228.65 4.16,229.64 4.16,230.63 4.15,231.62 4.15,232.61 4.15,233.60 4.15,234.60 4.15,235.59 4.15,236.58 4.15,237.57 4.15,238.56 4.15,239.55 4.15,240.54 4.15,241.00 4.15,241.99 4.15,242.99 4.15,243.98 4.15,244.98 4.15,245.97 4.15,246.97 4.15,247.96 4.15,248.96 4.15,249.96 4.15,250.95 4.15,251.95 4.15,252.94 4.15,253.94 4.16,254.93 4.16,255.93 4.16,256.92 4.16,257.92 4.16,258.92 4.16,259.91 4.16,260.91 4.16,261.90 4.16,262.90 4.16,263.89 4.16,264.89 4.16,265.88 4.16,266.88 4.16,267.88 4.16,268.87 4.16,269.87 4.16,270.86 4.16,271.86 4.16,272.85 4.16,273.85 4.16,274.84 4.16,275.84 4.16,276.84 4.16,277.83 4.16,278.83 4.16,279.82 4.17,280.82 4.17,281.81 4.17,282.81 4.17,283.80 4.17,284.80 4.17,285.80 4.17,286.79 4.17,287.79 4.17,288.78 4.17,289.78 4.17,290.77 4.17,291.77 4.17,292.76 4.17,293.76 4.17,294.76 4.17,295.75 4.17,296.75 4.17,297.74 4.17,298.74 4.17,299.73 4.17,300.73 4.17,301.72 4.17,302.72 4.17,303.72 4.17,304.71 4.17,305.71 4.18,306.70 4.18,307.70 4.18,308.69 4.18,309.69 4.18,310.68 4.18,311.68 4.18,312.68 4.18,313.67 4.18,314.67 4.18,315.66 4.18,316.66 4.18,317.65 4.18,318.65 4.18,319.34 4.18,319.88 4.22,320.52 4.31,321.01 4.46,321.48 4.66,321.93 4.92,322.35 5.23,322.74 5.57,323.07 6.01,323.42 6.49,323.73 7.01,323.99 7.54,324.20 8.10,324.35 8.67,324.44 9.33,324.48 10.19,324.48 11.09,324.48 79.44,324.50" type="shoulder"/>
<lane id="5.0.00_2" index="2" disallow="pedestrian tram rail_urban rail rail_electric rail_fast ship" speed="13.89" length="466.26" width="4.00" shape="79.47,2.03 10.07,2.07 9.49,2.07 8.65,2.12 7.89,2.25 7.16,2.47 6.45,2.77 5.78,3.15 5.16,3.61 4.57,4.15 4.24,4.52 3.73,5.20 3.30,5.90 2.93,6.64 2.62,7.41 2.38,8.20 2.20,9.01 2.10,9.84 2.07,10.66 2.07,11.01 2.07,12.00 2.07,12.99 2.07,13.99 2.07,14.98 2.07,15.97 2.07,16.97 2.07,17.96 2.07,18.95 2.07,19.94 2.07,20.94 2.07,21.93 2.07,22.92 2.07,23.91 2.07,24.91 2.07,25.90 2.07,26.89 2.07,27.88 2.07,28.88 2.07,29.87 2.07,30.86 2.07,31.85 2.07,32.85 2.07,33.84 2.07,34.83 2.07,35.82 2.07,36.82 2.07,37.81 2.07,38.80 2.07,39.79 2.07,40.79 2.07,41.78 2.07,42.77 2.07,43.76 2.07,44.76 2.07,45.75 2.07,46.74 2.07,47.73 2.07,48.73 2.07,49.72 2.08,50.71 2.08,51.70 2.08,52.70 2.08,53.69 2.08,54.68 2.08,55.67 2.08,56.67 2.08,57.66 2.08,58.65 2.08,59.64 2.08,60.64 2.08,61.63 2.08,62.62 2.08,63.62 2.08,64.61 2.08,65.60 2.08,66.59 2.08,67.59 2.08,68.58 2.08,69.57 2.08,70.56 2.08,71.56 2.08,72.55 2.08,73.54 2.08,74.53 2.08,75.53 2.08,76.52 2.08,77.51 2.08,78.50 2.08,79.50 2.08,80.49 2.08,81.48 2.08,82.47 2.08,83.47 2.08,84.46 2.08,85.45 2.08,86.44 2.08,87.44 2.08,87.76 2.08,88.76 2.08,89.75 2.08,90.74 2.08,91.73 2.08,92.73 2.08,93.72 2.08,94.71 2.08,95.70 2.08,96.70 2.07,97.69 2.07,98.68 2.07,99.67 2.07,100.67 2.07,101.66 2.07,102.65 2.07,103.64 2.07,104.64 2.07,105.63 2.07,106.62 2.07,107.61 2.07,108.61 2.07,109.60 2.07,110.59 2.07,111.58 2.07,112.58 2.07,113.57 2.07,114.56 2.07,115.55 2.06,116.55 2.06,117.54 2.06,118.53 2.06,119.52 2.06,120.52 2.06,121.51 2.06,122.50 2.06,123.49 2.06,124.49 2.06,125.48 2.06,126.47 2.06,127.46 2.06,128.46 2.06,129.45 2.06,130.44 2.06,131.43 2.06,132.43 2.06,133.42 2.06,134.41 2.05,135.40 2.05,136.40 2.05,137.39 2.05,138.38 2.05,139.37 2.05,140.37 2.05,141.36 2.05,142.35 2.05,143.34 2.05,144.34 2.05,145.33 2.05,146.32 2.05,147.31 2.05,148.31 2.05,149.30 2.05,150.29 2.05,151.28 2.05,152.28 2.05,153.27 2.05,154.26 2.04,155.25 2.04,156.25 2.04,157.24 2.04,158.23 2.04,159.22 2.04,160.22 2.04,161.21 2.04,162.20 2.04,163.19 2.04,164.19 2.04,165.18 2.04,166.17 2.04,167.16 2.04,168.15 2.04,169.14 2.04,170.14 2.04,171.13 2.04,172.12 2.04,173.11 2.03,174.10 2.03,175.09 2.03,176.09 2.03,177.08 2.03,178.07 2.03,179.06 2.03,180.05 2.03,181.04 2.03,182.04 2.03,183.03 2.03,184.02 2.03,185.01 2.03,186.00 2.03,186.99 2.03,187.99 2.03,188.98 2.03,189.97 2.03,190.96 2.03,191.95 2.02,192.94 2.02,193.94 2.02,194.93 2.02,195.92 2.02,196.91 2.02,197.90 2.02,198.89 2.02,199.89 2.02,200.88 2.02,201.87 2.02,202.86 2.02,203.85 2.02,204.84 2.02,205.84 2.02,206.83 2.02,207.82 2.02,208.81 2.02,209.80 2.02,210.79 2.02,211.79 2.01,212.78 2.01,213.77 2.01,214.76 2.01,215.75 2.01,216.74 2.01,217.74 2.01,218.73 2.01,219.72 2.01,220.71 2.01,221.70 2.01,222.69 2.01,223.69 2.01,224.68 2.01,225.67 2.01,226.66 2.01,227.65 2.01,228.64 2.01,229.64 2.01,230.63 2.00,231.62 2.00,232.61 2.00,233.60 2.00,234.59 2.00,235.59 2.00,236.58 2.00,237.57 2.00,238.56 2.00,239.55 2.00,240.54 2.00,241.00 2.00,241.99 2.00,242.99 2.00,243.98 2.00,244.98 2.00,245.97 2.00,246.97 2.00,247.96 2.00,248.96 2.00,249.96 2.00,250.95 2.00,251.95 2.00,252.94 2.00,253.94 2.01,254.93 2.01,255.93 2.01,256.92 2.01,257.92 2.01,258.92 2.01,259.91 2.01,260.91 2.01,261.90 2.01,262.90 2.01,263.89 2.01,264.89 2.01,265.88 2.01,266.88 2.01,267.88 2.01,268.87 2.01,269.87 2.01,270.86 2.01,271.86 2.01,272.85 2.01,273.85 2.01,274.84 2.01,275.84 2.01,276.84 2.01,277.83 2.01,278.83 2.01,279.82 2.02,280.82 2.02,281.81 2.02,282.81 2.02,283.80 2.02,284.80 2.02,285.80 2.02,286.79 2.02,287.79 2.02,288.78 2.02,289.78 2.02,290.77 2.02,291.77 2.02,292.76 2.02,293.76 2.02,294.76 2.02,295.75 2.02,296.75 2.02,297.74 2.02,298.74 2.02,299.73 2.02,300.73 2.02,301.72 2.02,302.72 2.02,303.72 2.02,304.71 2.02,305.71 2.03,306.70 2.03,307.70 2.03,308.69 2.03,309.69 2.03,310.68 2.03,311.68 2.03,312.68 2.03,313.67 2.03,314.67 2.03,315.66 2.03,316.66 2.03,317.65 2.03,318.65 2.03,319.34 2.03,319.96 2.08,320.79 2.22,321.53 2.45,322.25 2.76,322.94 3.15,323.58 3.62,324.17 4.14,324.68 4.76,325.17 5.43,325.60 6.14,325.96 6.88,326.24 7.65,326.45 8.43,326.58 9.27,326.63 10.19,326.63 11.09,326.63 79.44,326.65" type="driving"/>
</edge>
<edge id="6.0.00" from="60" to="195" priority="1" type="sidewalk|shoulder|driving" shape="325.78,0.00 324.81,0.00 323.83,0.00 322.86,0.00 321.88,0.00 320.90,0.00 319.93,0.00 318.95,0.00 317.98,0.00 317.00,0.00 316.02,0.00 315.05,0.00 314.07,0.00 313.10,0.00 312.12,0.00 311.14,0.00 310.17,0.00 309.19,0.00 308.22,0.00 307.24,0.00 306.26,0.00 305.29,0.00 304.31,0.00 303.33,0.00 302.36,0.00 301.38,0.00 300.41,0.00 299.43,0.00 298.45,0.00 297.48,0.00 296.50,0.00 295.53,0.00 294.55,0.00 293.57,0.00 292.60,0.00 291.62,0.00 290.59,0.00 289.60,0.00 288.60,0.00 287.61,0.00 286.61,0.00 285.62,0.00 284.62,0.00 283.63,0.00 282.63,0.00 281.64,0.00 280.64,0.00 279.64,0.00 278.65,0.00 277.65,0.00 276.66,0.00 275.66,0.00 274.67,0.00 273.67,0.00 272.68,0.00 271.68,0.00 270.69,0.00 269.69,0.00 268.70,0.00 267.70,0.00 266.70,0.00 265.71,0.00 264.71,0.00 263.72,0.00 262.72,0.00 261.73,0.00 260.73,0.00 259.74,0.00 258.74,0.00 257.75,0.00 256.75,0.00 255.76,0.00 254.76,0.00 253.77,0.00 252.77,0.00 251.77,0.00 250.78,0.00 249.78,0.00 248.79,0.00 247.79,0.00 246.80,0.00 245.80,0.00 244.81,0.00 243.81,0.00 242.82,0.01 241.82,0.01 240.83,0.01 239.83,0.01 238.83,0.01 237.84,0.01 236.84,0.01 235.85,0.01 234.85,0.01 233.86,0.01 232.86,0.01 231.87,0.01 230.87,0.01 229.88,0.01 228.88,0.01 227.89,0.01 226.89,0.01 225.90,0.01 224.90,0.01 223.90,0.01 222.91,0.01 221.91,0.01 220.92,0.01 219.92,0.01 218.93,0.01 217.93,0.01 216.94,0.01 215.94,0.01 214.95,0.01 213.95,0.01 212.96,0.01 211.96,0.01 210.96,0.01 209.97,0.01 208.97,0.01 207.98,0.01 206.98,0.01 205.99,0.01 204.99,0.01 204.00,0.01 203.00,0.01 202.01,0.01 201.01,0.01 200.02,0.01 199.02,0.01 198.03,0.01 197.03,0.01 196.04,0.01 195.04,0.01 194.05,0.01 193.05,0.01 192.06,0.01 191.06,0.01 190.07,0.01 189.07,0.01 188.08,0.01 187.08,0.01 186.09,0.01 185.10,0.01 184.10,0.01 183.11,0.01 182.11,0.01 181.12,0.01 180.12,0.01 179.13,0.01 178.13,0.01 177.14,0.01 176.15,0.01 175.15,0.01 174.16,0.01 173.16,0.01 172.17,0.01 171.17,0.01 170.18,0.01 169.18,0.01 168.19,0.01 167.19,0.01 166.20,0.01 165.21,0.01 164.21,0.01 163.22,0.01 162.22,0.01 161.23,0.01 160.23,0.01 159.24,0.01 158.24,0.01 157.25,0.01 156.26,0.01 155.26,0.01 154.27,0.01 153.27,0.01 152.28,0.01 151.28,0.01 150.29,0.01 149.29,0.02 148.30,0.02 147.31,0.02 146.31,0.02 145.32,0.02 144.32,0.02 143.33,0.02 142.33,0.02 141.34,0.02 140.34,0.02 139.35,0.02 138.35,0.02 137.36,0.02 136.37,0.02 135.37,0.02 134.38,0.02 133.38,0.02 132.39,0.02 131.39,0.02 130.40,0.02 129.40,0.02 128.41,0.02 127.42,0.02 126.42,0.02 125.43,0.02 124.43,0.02 123.44,0.02 122.44,0.02 121.45,0.02 120.45,0.02 119.46,0.02 118.46,0.02 117.47,0.02 116.48,0.02 115.48,0.02 114.49,0.02 113.49,0.02 112.50,0.02 111.50,0.02 110.51,0.02 109.51,0.02 108.52,0.02 107.53,0.02 106.53,0.02 105.54,0.02 104.54,0.02 103.55,0.02 103.33,0.02 102.51,0.02 101.68,0.02">
<lane id="6.0.00_0" index="0" allow="pedestrian" speed="2.78" length="224.10" width="4.00" shape="325.78,6.30 324.81,6.30 323.83,6.30 322.86,6.30 321.88,6.30 320.90,6.30 319.93,6.30 318.95,6.30 317.98,6.30 317.00,6.30 316.02,6.30 315.05,6.30 314.07,6.30 313.10,6.30 312.12,6.30 311.14,6.30 310.17,6.30 309.19,6.30 308.22,6.30 307.24,6.30 306.26,6.30 305.29,6.30 304.31,6.30 303.33,6.30 302.36,6.30 301.38,6.30 300.41,6.30 299.43,6.30 298.45,6.30 297.48,6.30 296.50,6.30 295.53,6.30 294.55,6.30 293.57,6.30 292.60,6.30 291.62,6.30 290.59,6.30 289.60,6.30 288.60,6.30 287.61,6.30 286.61,6.30 285.62,6.30 284.62,6.30 283.63,6.30 282.63,6.30 281.64,6.30 280.64,6.30 279.64,6.30 278.65,6.30 277.65,6.30 276.66,6.30 275.66,6.30 274.67,6.30 273.67,6.30 272.68,6.30 271.68,6.30 270.69,6.30 269.69,6.30 268.70,6.30 267.70,6.30 266.71,6.30 265.71,6.30 264.71,6.30 263.72,6.30 262.72,6.30 261.73,6.30 260.73,6.30 259.74,6.30 258.74,6.30 257.75,6.30 256.75,6.30 255.76,6.30 254.76,6.30 253.77,6.30 252.77,6.30 251.78,6.30 250.78,6.30 249.78,6.30 248.79,6.30 247.79,6.30 246.80,6.30 245.80,6.30 244.81,6.30 243.81,6.30 242.82,6.31 241.82,6.31 240.83,6.31 239.83,6.31 238.84,6.31 237.84,6.31 236.84,6.31 235.85,6.31 234.85,6.31 233.86,6.31 232.86,6.31 231.87,6.31 230.87,6.31 229.88,6.31 228.88,6.31 227.89,6.31 226.89,6.31 225.90,6.31 224.90,6.31 223.91,6.31 222.91,6.31 221.91,6.31 220.92,6.31 219.92,6.31 218.93,6.31 217.93,6.31 216.94,6.31 215.94,6.31 214.95,6.31 213.95,6.31 212.96,6.31 211.96,6.31 210.97,6.31 209.97,6.31 208.97,6.31 207.98,6.31 206.98,6.31 205.99,6.31 204.99,6.31 204.00,6.31 203.00,6.31 202.01,6.31 201.01,6.31 200.02,6.31 199.02,6.31 198.03,6.31 197.03,6.31 196.04,6.31 195.04,6.31 194.05,6.31 193.05,6.31 192.06,6.31 191.06,6.31 190.07,6.31 189.07,6.31 188.08,6.31 187.09,6.31 186.09,6.31 185.10,6.31 184.10,6.31 183.11,6.31 182.11,6.31 181.12,6.31 180.12,6.31 179.13,6.31 178.14,6.31 177.14,6.31 176.15,6.31 175.15,6.31 174.16,6.31 173.16,6.31 172.17,6.31 171.17,6.31 170.18,6.31 169.18,6.31 168.19,6.31 167.20,6.31 166.20,6.31 165.21,6.31 164.21,6.31 163.22,6.31 162.22,6.31 161.23,6.31 160.23,6.31 159.24,6.31 158.25,6.31 157.25,6.31 156.26,6.31 155.26,6.31 154.27,6.31 153.27,6.31 152.28,6.31 151.28,6.31 150.29,6.31 149.29,6.32 148.30,6.32 147.31,6.32 146.31,6.32 145.32,6.32 144.32,6.32 143.33,6.32 142.33,6.32 141.34,6.32 140.34,6.32 139.35,6.32 138.36,6.32 137.36,6.32 136.37,6.32 135.37,6.32 134.38,6.32 133.38,6.32 132.39,6.32 131.39,6.32 130.40,6.32 129.40,6.32 128.41,6.32 127.42,6.32 126.42,6.32 125.43,6.32 124.43,6.32 123.44,6.32 122.44,6.32 121.45,6.32 120.45,6.32 119.46,6.32 118.47,6.32 117.47,6.32 116.48,6.32 115.48,6.32 114.49,6.32 113.49,6.32 112.50,6.32 111.50,6.32 110.51,6.32 109.51,6.32 108.52,6.32 107.53,6.32 106.53,6.32 105.54,6.32 104.54,6.32 103.55,6.32 103.34,6.32 102.51,6.32 101.68,6.32" type="sidewalk"/>
<lane id="6.0.00_1" index="1" disallow="all" speed="1.39" length="224.10" width="0.30" shape="325.78,4.15 324.81,4.15 323.83,4.15 322.86,4.15 321.88,4.15 320.90,4.15 319.93,4.15 318.95,4.15 317.98,4.15 317.00,4.15 316.02,4.15 315.05,4.15 314.07,4.15 313.10,4.15 312.12,4.15 311.14,4.15 310.17,4.15 309.19,4.15 308.22,4.15 307.24,4.15 306.26,4.15 305.29,4.15 304.31,4.15 303.33,4.15 302.36,4.15 301.38,4.15 300.41,4.15 299.43,4.15 298.45,4.15 297.48,4.15 296.50,4.15 295.53,4.15 294.55,4.15 293.57,4.15 292.60,4.15 291.62,4.15 290.59,4.15 289.60,4.15 288.60,4.15 287.61,4.15 286.61,4.15 285.62,4.15 284.62,4.15 283.63,4.15 282.63,4.15 281.64,4.15 280.64,4.15 279.64,4.15 278.65,4.15 277.65,4.15 276.66,4.15 275.66,4.15 274.67,4.15 273.67,4.15 272.68,4.15 271.68,4.15 270.69,4.15 269.69,4.15 268.70,4.15 267.70,4.15 266.71,4.15 265.71,4.15 264.71,4.15 263.72,4.15 262.72,4.15 261.73,4.15 260.73,4.15 259.74,4.15 258.74,4.15 257.75,4.15 256.75,4.15 255.76,4.15 254.76,4.15 253.77,4.15 252.77,4.15 251.77,4.15 250.78,4.15 249.78,4.15 248.79,4.15 247.79,4.15 246.80,4.15 245.80,4.15 244.81,4.15 243.81,4.15 242.82,4.16 241.82,4.16 240.83,4.16 239.83,4.16 238.84,4.16 237.84,4.16 236.84,4.16 235.85,4.16 234.85,4.16 233.86,4.16 232.86,4.16 231.87,4.16 230.87,4.16 229.88,4.16 228.88,4.16 227.89,4.16 226.89,4.16 225.90,4.16 224.90,4.16 223.90,4.16 222.91,4.16 221.91,4.16 220.92,4.16 219.92,4.16 218.93,4.16 217.93,4.16 216.94,4.16 215.94,4.16 214.95,4.16 213.95,4.16 212.96,4.16 211.96,4.16 210.97,4.16 209.97,4.16 208.97,4.16 207.98,4.16 206.98,4.16 205.99,4.16 204.99,4.16 204.00,4.16 203.00,4.16 202.01,4.16 201.01,4.16 200.02,4.16 199.02,4.16 198.03,4.16 197.03,4.16 196.04,4.16 195.04,4.16 194.05,4.16 193.05,4.16 192.06,4.16 191.06,4.16 190.07,4.16 189.07,4.16 188.08,4.16 187.09,4.16 186.09,4.16 185.10,4.16 184.10,4.16 183.11,4.16 182.11,4.16 181.12,4.16 180.12,4.16 179.13,4.16 178.13,4.16 177.14,4.16 176.15,4.16 175.15,4.16 174.16,4.16 173.16,4.16 172.17,4.16 171.17,4.16 170.18,4.16 169.18,4.16 168.19,4.16 167.20,4.16 166.20,4.16 165.21,4.16 164.21,4.16 163.22,4.16 162.22,4.16 161.23,4.16 160.23,4.16 159.24,4.16 158.24,4.16 157.25,4.16 156.26,4.16 155.26,4.16 154.27,4.16 153.27,4.16 152.28,4.16 151.28,4.16 150.29,4.16 149.29,4.17 148.30,4.17 147.31,4.17 146.31,4.17 145.32,4.17 144.32,4.17 143.33,4.17 142.33,4.17 141.34,4.17 140.34,4.17 139.35,4.17 138.35,4.17 137.36,4.17 136.37,4.17 135.37,4.17 134.38,4.17 133.38,4.17 132.39,4.17 131.39,4.17 130.40,4.17 129.40,4.17 128.41,4.17 127.42,4.17 126.42,4.17 125.43,4.17 124.43,4.17 123.44,4.17 122.44,4.17 121.45,4.17 120.45,4.17 119.46,4.17 118.47,4.17 117.47,4.17 116.48,4.17 115.48,4.17 114.49,4.17 113.49,4.17 112.50,4.17 111.50,4.17 110.51,4.17 109.51,4.17 108.52,4.17 107.53,4.17 106.53,4.17 105.54,4.17 104.54,4.17 103.55,4.17 103.33,4.17 102.51,4.17 101.68,4.17" type="shoulder"/>
<lane id="6.0.00_2" index="2" disallow="pedestrian tram rail_urban rail rail_electric rail_fast ship" speed="13.89" length="224.10" width="4.00" shape="325.78,2.00 324.81,2.00 323.83,2.00 322.86,2.00 321.88,2.00 320.90,2.00 319.93,2.00 318.95,2.00 317.98,2.00 317.00,2.00 316.02,2.00 315.05,2.00 314.07,2.00 313.10,2.00 312.12,2.00 311.14,2.00 310.17,2.00 309.19,2.00 308.22,2.00 307.24,2.00 306.26,2.00 305.29,2.00 304.31,2.00 303.33,2.00 302.36,2.00 301.38,2.00 300.41,2.00 299.43,2.00 298.45,2.00 297.48,2.00 296.50,2.00 295.53,2.00 294.55,2.00 293.57,2.00 292.60,2.00 291.62,2.00 290.59,2.00 289.60,2.00 288.60,2.00 287.61,2.00 286.61,2.00 285.62,2.00 284.62,2.00 283.63,2.00 282.63,2.00 281.64,2.00 280.64,2.00 279.64,2.00 278.65,2.00 277.65,2.00 276.66,2.00 275.66,2.00 274.67,2.00 273.67,2.00 272.68,2.00 271.68,2.00 270.69,2.00 269.69,2.00 268.70,2.00 267.70,2.00 266.70,2.00 265.71,2.00 264.71,2.00 263.72,2.00 262.72,2.00 261.73,2.00 260.73,2.00 259.74,2.00 258.74,2.00 257.75,2.00 256.75,2.00 255.76,2.00 254.76,2.00 253.77,2.00 252.77,2.00 251.77,2.00 250.78,2.00 249.78,2.00 248.79,2.00 247.79,2.00 246.80,2.00 245.80,2.00 244.81,2.00 243.81,2.00 242.82,2.01 241.82,2.01 240.83,2.01 239.83,2.01 238.84,2.01 237.84,2.01 236.84,2.01 235.85,2.01 234.85,2.01 233.86,2.01 232.86,2.01 231.87,2.01 230.87,2.01 229.88,2.01 228.88,2.01 227.89,2.01 226.89,2.01 225.90,2.01 224.90,2.01 223.90,2.01 222.91,2.01 221.91,2.01 220.92,2.01 219.92,2.01 218.93,2.01 217.93,2.01 216.94,2.01 215.94,2.01 214.95,2.01 213.95,2.01 212.96,2.01 211.96,2.01 210.97,2.01 209.97,2.01 208.97,2.01 207.98,2.01 206.98,2.01 205.99,2.01 204.99,2.01 204.00,2.01 203.00,2.01 202.01,2.01 201.01,2.01 200.02,2.01 199.02,2.01 198.03,2.01 197.03,2.01 196.04,2.01 195.04,2.01 194.05,2.01 193.05,2.01 192.06,2.01 191.06,2.01 190.07,2.01 189.07,2.01 188.08,2.01 187.09,2.01 186.09,2.01 185.10,2.01 184.10,2.01 183.11,2.01 182.11,2.01 181.12,2.01 180.12,2.01 179.13,2.01 178.13,2.01 177.14,2.01 176.15,2.01 175.15,2.01 174.16,2.01 173.16,2.01 172.17,2.01 171.17,2.01 170.18,2.01 169.18,2.01 168.19,2.01 167.20,2.01 166.20,2.01 165.21,2.01 164.21,2.01 163.22,2.01 162.22,2.01 161.23,2.01 160.23,2.01 159.24,2.01 158.24,2.01 157.25,2.01 156.26,2.01 155.26,2.01 154.27,2.01 153.27,2.01 152.28,2.01 151.28,2.01 150.29,2.01 149.29,2.02 148.30,2.02 147.31,2.02 146.31,2.02 145.32,2.02 144.32,2.02 143.33,2.02 142.33,2.02 141.34,2.02 140.34,2.02 139.35,2.02 138.35,2.02 137.36,2.02 136.37,2.02 135.37,2.02 134.38,2.02 133.38,2.02 132.39,2.02 131.39,2.02 130.40,2.02 129.40,2.02 128.41,2.02 127.42,2.02 126.42,2.02 125.43,2.02 124.43,2.02 123.44,2.02 122.44,2.02 121.45,2.02 120.45,2.02 119.46,2.02 118.46,2.02 117.47,2.02 116.48,2.02 115.48,2.02 114.49,2.02 113.49,2.02 112.50,2.02 111.50,2.02 110.51,2.02 109.51,2.02 108.52,2.02 107.53,2.02 106.53,2.02 105.54,2.02 104.54,2.02 103.55,2.02 103.33,2.02 102.51,2.02 101.68,2.02" type="driving"/>
</edge>
<edge id="7.0.00" from="7.14" to="60" priority="1" type="sidewalk|shoulder|driving" shape="384.14,0.00 347.79,0.00">
<lane id="7.0.00_0" index="0" allow="pedestrian" speed="2.78" length="34.85" width="4.00" shape="382.64,6.30 347.79,6.30" type="sidewalk"/>
<lane id="7.0.00_1" index="1" disallow="all" speed="1.39" length="34.85" width="0.30" shape="382.64,4.15 347.79,4.15" type="shoulder"/>
<lane id="7.0.00_2" index="2" disallow="pedestrian tram rail_urban rail rail_electric rail_fast ship" speed="13.89" length="34.85" width="4.00" shape="382.64,2.00 347.79,2.00" type="driving"/>
</edge>
<edge id="9.0.00" from="167" to="184" priority="1" type="sidewalk|shoulder|driving" shape="145.05,271.12 101.45,271.11">
<lane id="9.0.00_0" index="0" allow="pedestrian" speed="2.78" length="43.60" width="4.00" shape="145.05,277.42 101.45,277.41" type="sidewalk"/>
<lane id="9.0.00_1" index="1" disallow="all" speed="1.39" length="43.60" width="0.30" shape="145.05,275.27 101.45,275.26" type="shoulder"/>
<lane id="9.0.00_2" index="2" disallow="pedestrian tram rail_urban rail rail_electric rail_fast ship" speed="13.89" length="43.60" width="4.00" shape="145.05,273.12 101.45,273.11" type="driving"/>
</edge>
<junction id="111" type="priority" x="331.31" y="270.89" incLanes="-16.0.00_0 -16.0.00_1 -16.0.00_2 17.0.00_0 17.0.00_1 17.0.00_2 -10.0.00_0 -10.0.00_1 -10.0.00_2" intLanes=":111_0_0 :111_1_0 :111_2_0 :111_6_0 :111_4_0 :111_5_0" shape="328.63,282.20 345.23,282.19 345.22,259.57 328.62,259.58 328.29,261.39 327.89,262.02 327.32,262.48 326.58,262.75 325.69,262.84 325.69,279.44 327.32,279.75 327.89,280.13 328.30,280.67 328.55,281.36">
<request index="0" response="000000" foes="001000" cont="0"/>
<request index="1" response="000000" foes="111000" cont="0"/>
<request index="2" response="000000" foes="100000" cont="0"/>
<request index="3" response="000011" foes="100011" cont="1"/>
<request index="4" response="000010" foes="000010" cont="0"/>
<request index="5" response="001110" foes="001110" cont="0"/>
</junction>
<junction id="128" type="priority" x="95.97" y="131.28" incLanes="-23.0.00_0 -23.0.00_1 -23.0.00_2 12.0.00_0 12.0.00_1 12.0.00_2 24.0.00_0 24.0.00_1 24.0.00_2" intLanes=":128_0_0 :128_6_0 :128_2_0 :128_3_0 :128_4_0 :128_5_0" shape="82.16,142.28 98.76,142.29 99.06,140.89 99.44,140.40 99.97,140.05 100.65,139.84 101.49,139.77 101.48,123.17 99.97,122.85 99.44,122.45 99.06,121.89 98.84,121.17 98.76,120.29 82.16,120.28">
<request index="0" response="000000" foes="001000" cont="0"/>
<request index="1" response="110000" foes="111000" cont="1"/>
<request index="2" response="100000" foes="100000" cont="0"/>
<request index="3" response="100011" foes="100011" cont="0"/>
<request index="4" response="000000" foes="000010" cont="0"/>
<request index="5" response="000000" foes="001110" cont="0"/>
</junction>
<junction id="139" type="priority" x="331.29" y="196.49" incLanes="-17.0.00_0 -17.0.00_1 -17.0.00_2 18.0.00_0 18.0.00_1 18.0.00_2 -4.0.00_0 -4.0.00_1 -4.0.00_2" intLanes=":139_0_0 :139_1_0 :139_2_0 :139_6_0 :139_4_0 :139_5_0" shape="328.59,208.04 345.19,208.03 345.17,184.94 328.57,184.95 328.25,187.08 327.85,187.83 327.29,188.37 326.57,188.69 325.69,188.79 325.70,205.39 327.30,205.69 327.86,206.06 328.27,206.57 328.51,207.23">
<request index="0" response="000000" foes="001000" cont="0"/>
<request index="1" response="000000" foes="111000" cont="0"/>
<request index="2" response="000000" foes="100000" cont="0"/>
<request index="3" response="000011" foes="100011" cont="1"/>
<request index="4" response="000010" foes="000010" cont="0"/>
<request index="5" response="001110" foes="001110" cont="0"/>
</junction>
<junction id="156" type="priority" x="95.96" y="197.77" incLanes="-22.0.00_0 -22.0.00_1 -22.0.00_2 4.0.00_0 4.0.00_1 4.0.00_2 23.0.00_0 23.0.00_1 23.0.00_2" intLanes=":156_0_0 :156_6_0 :156_2_0 :156_3_0 :156_4_0 :156_5_0" shape="82.15,208.77 98.75,208.78 99.05,206.95 99.43,206.32 99.96,205.86 100.65,205.59 101.48,205.50 101.48,188.90 99.96,188.66 99.43,188.37 99.05,187.95 98.83,187.42 98.75,186.78 82.15,186.77">
<request index="0" response="000000" foes="001000" cont="0"/>
<request index="1" response="110000" foes="111000" cont="1"/>
<request index="2" response="100000" foes="100000" cont="0"/>
<request index="3" response="100011" foes="100011" cont="0"/>
<request index="4" response="000000" foes="000010" cont="0"/>
<request index="5" response="000000" foes="001110" cont="0"/>
</junction>
<junction id="167" type="priority" x="156.14" y="276.76" incLanes="-25.0.00_0 -25.0.00_1 -25.0.00_2 10.0.00_0 10.0.00_1 10.0.00_2 -9.0.00_0 -9.0.00_1 -9.0.00_2" intLanes=":167_0_0 :167_1_0 :167_2_0 :167_3_0 :167_4_0 :167_6_0" shape="147.78,282.42 164.38,282.40 164.70,280.75 165.09,280.17 165.65,279.75 166.36,279.50 167.23,279.42 167.23,262.82 145.05,262.82 145.05,279.42 146.57,279.75 147.10,280.17 147.48,280.75 147.71,281.50">
<request index="0" response="001000" foes="001000" cont="0"/>
<request index="1" response="111000" foes="111000" cont="0"/>
<request index="2" response="000000" foes="100000" cont="0"/>
<request index="3" response="000000" foes="100011" cont="0"/>
<request index="4" response="000000" foes="000010" cont="0"/>
<request index="5" response="001100" foes="001110" cont="1"/>
</junction>
<junction id="184" type="priority" x="95.94" y="271.46" incLanes="-21.0.00_0 -21.0.00_1 -21.0.00_2 9.0.00_0 9.0.00_1 9.0.00_2 22.0.00_0 22.0.00_1 22.0.00_2" intLanes=":184_0_0 :184_6_0 :184_2_0 :184_3_0 :184_4_0 :184_5_0" shape="82.14,282.46 98.74,282.46 99.04,280.77 99.42,280.17 99.94,279.75 100.62,279.50 101.45,279.41 101.45,262.81 99.95,262.55 99.42,262.22 99.04,261.77 98.82,261.18 98.74,260.46 82.14,260.46">
<request index="0" response="000000" foes="001000" cont="0"/>
<request index="1" response="110000" foes="111000" cont="1"/>
<request index="2" response="100000" foes="100000" cont="0"/>
<request index="3" response="100011" foes="100011" cont="0"/>
<request index="4" response="000000" foes="000010" cont="0"/>
<request index="5" response="000000" foes="001110" cont="0"/>
</junction>
<junction id="195" type="priority" x="90.58" y="5.66" incLanes="-24.0.00_0 -24.0.00_1 -24.0.00_2 6.0.00_0 6.0.00_1 6.0.00_2 -3.0.00_0 -3.0.00_1 -3.0.00_2" intLanes=":195_0_0 :195_1_0 :195_2_0 :195_3_0 :195_4_0 :195_6_0" shape="82.18,11.31 98.78,11.31 99.10,9.65 99.50,9.07 100.07,8.65 100.80,8.40 101.68,8.32 101.67,-8.28 79.47,-8.27 79.48,8.33 80.98,8.66 81.50,9.08 81.88,9.65 82.10,10.40">
<request index="0" response="001000" foes="001000" cont="0"/>
<request index="1" response="111000" foes="111000" cont="0"/>
<request index="2" response="000000" foes="100000" cont="0"/>
<request index="3" response="000000" foes="100011" cont="0"/>
<request index="4" response="000000" foes="000010" cont="0"/>
<request index="5" response="001100" foes="001110" cont="1"/>
</junction>
<junction id="26" type="priority" x="156.58" y="323.28" incLanes="-1.0.00_0 -1.0.00_1 -1.0.00_2 25.0.00_0 25.0.00_1 25.0.00_2 2.0.00_0 2.0.00_1 2.0.00_2" intLanes=":26_0_0 :26_6_0 :26_2_0 :26_3_0 :26_4_0 :26_5_0" shape="168.14,336.95 168.14,320.35 166.08,320.08 165.36,319.74 164.84,319.26 164.53,318.64 164.43,317.89 147.83,317.91 147.52,319.27 147.13,319.74 146.58,320.08 145.87,320.29 145.01,320.36 145.02,336.96">
<request index="0" response="000000" foes="001000" cont="0"/>
<request index="1" response="110000" foes="111000" cont="1"/>
<request index="2" response="100000" foes="100000" cont="0"/>
<request index="3" response="100011" foes="100011" cont="0"/>
<request index="4" response="000000" foes="000010" cont="0"/>
<request index="5" response="000000" foes="001110" cont="0"/>
</junction>
<junction id="43" type="priority" x="336.99" y="323.22" incLanes="-8.0.00_0 -8.0.00_1 -8.0.00_2 16.0.00_0 16.0.00_1 16.0.00_2 1.0.00_0 1.0.00_1 1.0.00_2" intLanes=":43_0_0 :43_6_0 :43_2_0 :43_3_0 :43_4_0 :43_5_0" shape="348.29,336.91 348.29,320.31 346.60,320.03 346.01,319.69 345.59,319.20 345.34,318.57 345.25,317.81 328.65,317.82 328.32,319.21 327.91,319.70 327.33,320.04 326.59,320.25 325.68,320.32 325.69,336.92">
<request index="0" response="000000" foes="001000" cont="0"/>
<request index="1" response="110000" foes="111000" cont="1"/>
<request index="2" response="100000" foes="100000" cont="0"/>
<request index="3" response="100011" foes="100011" cont="0"/>
<request index="4" response="000000" foes="000010" cont="0"/>
<request index="5" response="000000" foes="001110" cont="0"/>
</junction>
<junction id="60" type="priority" x="336.79" y="5.58" incLanes="-19.0.00_0 -19.0.00_1 -19.0.00_2 7.0.00_0 7.0.00_1 7.0.00_2 -6.0.00_0 -6.0.00_1 -6.0.00_2" intLanes=":60_0_0 :60_1_0 :60_2_0 :60_3_0 :60_4_0 :60_6_0" shape="328.47,11.16 345.07,11.15 345.37,9.57 345.75,9.01 346.28,8.62 346.96,8.38 347.79,8.30 347.79,-8.30 325.78,-8.30 325.78,8.30 327.27,8.62 327.80,9.02 328.17,9.57 328.39,10.29">
<request index="0" response="001000" foes="001000" cont="0"/>
<request index="1" response="111000" foes="111000" cont="0"/>
<request index="2" response="000000" foes="100000" cont="0"/>
<request index="3" response="000000" foes="100011" cont="0"/>
<request index="4" response="000000" foes="000010" cont="0"/>
<request index="5" response="001100" foes="001110" cont="1"/>
</junction>
<junction id="7.14" type="priority" x="384.14" y="0.00" incLanes="-14.0.00_0 -14.0.00_1 -14.0.00_2 -7.0.00_0 -7.0.00_1 -7.0.00_2" intLanes=":7.14_0_0 :7.14_0_1 :7.14_0_2 :7.14_3_0 :7.14_3_1 :7.14_3_2" shape="387.15,7.13 389.81,-7.59 387.21,-8.21 386.28,-8.32 385.33,-8.34 384.18,-8.32 382.64,-8.30 382.64,8.30">
<request index="0" response="000000" foes="000000" cont="0"/>
<request index="1" response="000000" foes="000000" cont="0"/>
<request index="2" response="000000" foes="000000" cont="0"/>
<request index="3" response="000000" foes="000000" cont="0"/>
<request index="4" response="000000" foes="000000" cont="0"/>
<request index="5" response="000000" foes="000000" cont="0"/>
</junction>
<junction id="77" type="priority" x="91.10" y="323.30" incLanes="-2.0.00_0 -2.0.00_1 -2.0.00_2 21.0.00_0 21.0.00_1 21.0.00_2 5.0.00_0 5.0.00_1 5.0.00_2" intLanes=":77_0_0 :77_6_0 :77_2_0 :77_3_0 :77_4_0 :77_5_0" shape="102.75,336.96 102.76,320.36 100.52,320.09 99.74,319.76 99.18,319.29 98.84,318.68 98.73,317.94 82.13,317.94 81.83,319.16 81.46,319.59 80.93,319.89 80.26,320.07 79.44,320.13 79.43,336.95">
<request index="0" response="000000" foes="001000" cont="0"/>
<request index="1" response="110000" foes="111000" cont="1"/>
<request index="2" response="100000" foes="100000" cont="0"/>
<request index="3" response="100011" foes="100011" cont="0"/>
<request index="4" response="000000" foes="000010" cont="0"/>
<request index="5" response="000000" foes="001110" cont="0"/>
</junction>
<junction id="8.14" type="priority" x="394.41" y="10.07" incLanes="0.0.00_0 0.0.00_1 0.0.00_2 14.0.00_0 14.0.00_1 14.0.00_2" intLanes=":8.14_0_0 :8.14_0_1 :8.14_0_2 :8.14_3_0 :8.14_3_1 :8.14_3_2" shape="386.11,11.57 402.71,11.57 402.73,9.03 402.72,7.10 402.57,5.52 402.17,4.00 401.41,2.28 400.19,0.07 387.54,8.70 386.74,8.99 386.47,9.39 386.27,9.95 386.15,10.67">
<request index="0" response="000000" foes="000000" cont="0"/>
<request index="1" response="000000" foes="000000" cont="0"/>
<request index="2" response="000000" foes="000000" cont="0"/>
<request index="3" response="000000" foes="000000" cont="0"/>
<request index="4" response="000000" foes="000000" cont="0"/>
<request index="5" response="000000" foes="000000" cont="0"/>
</junction>
<junction id="94" type="priority" x="331.29" y="131.21" incLanes="-18.0.00_0 -18.0.00_1 -18.0.00_2 19.0.00_0 19.0.00_1 19.0.00_2 -12.0.00_0 -12.0.00_1 -12.0.00_2" intLanes=":94_0_0 :94_1_0 :94_2_0 :94_6_0 :94_4_0 :94_5_0" shape="328.55,142.96 345.15,142.95 345.13,119.45 328.53,119.46 328.22,121.51 327.83,122.23 327.29,122.74 326.59,123.05 325.73,123.15 325.73,139.75 327.29,140.11 327.84,140.55 328.23,141.18 328.47,141.98">
<request index="0" response="000000" foes="001000" cont="0"/>
<request index="1" response="000000" foes="111000" cont="0"/>
<request index="2" response="000000" foes="100000" cont="0"/>
<request index="3" response="000011" foes="100011" cont="1"/>
<request index="4" response="000010" foes="000010" cont="0"/>
<request index="5" response="001110" foes="001110" cont="0"/>
</junction>
<junction id=":111_6_0" type="internal" x="336.92" y="267.51" incLanes=":111_3_0 -16.0.00_2" intLanes=":111_0_0 :111_1_0 :111_5_0"/>
<junction id=":128_6_0" type="internal" x="90.46" y="134.73" incLanes=":128_1_0 24.0.00_2" intLanes=":128_3_0 :128_4_0 :128_5_0"/>
<junction id=":139_6_0" type="internal" x="336.88" y="193.24" incLanes=":139_3_0 -17.0.00_2" intLanes=":139_0_0 :139_1_0 :139_5_0"/>
<junction id=":156_6_0" type="internal" x="90.45" y="200.78" incLanes=":156_1_0 23.0.00_2" intLanes=":156_3_0 :156_4_0 :156_5_0"/>
<junction id=":167_6_0" type="internal" x="152.66" y="271.12" incLanes=":167_5_0 10.0.00_2" intLanes=":167_1_0 :167_2_0 :167_3_0"/>
<junction id=":184_6_0" type="internal" x="90.44" y="274.59" incLanes=":184_1_0 22.0.00_2" intLanes=":184_3_0 :184_4_0 :184_5_0"/>
<junction id=":195_6_0" type="internal" x="87.07" y="0.03" incLanes=":195_5_0 6.0.00_2" intLanes=":195_1_0 :195_2_0 :195_3_0"/>
<junction id=":26_6_0" type="internal" x="159.81" y="328.65" incLanes=":26_1_0 2.0.00_2" intLanes=":26_3_0 :26_4_0 :26_5_0"/>
<junction id=":43_6_0" type="internal" x="340.37" y="328.61" incLanes=":43_1_0 1.0.00_2" intLanes=":43_3_0 :43_4_0 :43_5_0"/>
<junction id=":60_6_0" type="internal" x="333.40" y="0.00" incLanes=":60_5_0 7.0.00_2" intLanes=":60_1_0 :60_2_0 :60_3_0"/>
<junction id=":77_6_0" type="internal" x="94.22" y="328.66" incLanes=":77_1_0 5.0.00_2" intLanes=":77_3_0 :77_4_0 :77_5_0"/>
<junction id=":94_6_0" type="internal" x="336.84" y="127.68" incLanes=":94_3_0 -18.0.00_2" intLanes=":94_0_0 :94_1_0 :94_5_0"/>
<connection from="-1.0.00" to="-2.0.00" fromLane="2" toLane="2" via=":26_0_0" dir="s" state="M"/>
<connection from="-1.0.00" to="-25.0.00" fromLane="2" toLane="2" via=":26_1_0" dir="l" state="m"/>
<connection from="-10.0.00" to="-17.0.00" fromLane="2" toLane="2" via=":111_4_0" dir="r" state="m"/>
<connection from="-10.0.00" to="16.0.00" fromLane="2" toLane="2" via=":111_5_0" dir="l" state="m"/>
<connection from="-12.0.00" to="-19.0.00" fromLane="2" toLane="2" via=":94_4_0" dir="r" state="m"/>
<connection from="-12.0.00" to="18.0.00" fromLane="2" toLane="2" via=":94_5_0" dir="l" state="m"/>
<connection from="-14.0.00" to="7.0.00" fromLane="0" toLane="0" via=":7.14_0_0" dir="s" state="M"/>
<connection from="-14.0.00" to="7.0.00" fromLane="1" toLane="1" via=":7.14_0_1" dir="s" state="M"/>
<connection from="-14.0.00" to="7.0.00" fromLane="2" toLane="2" via=":7.14_0_2" dir="s" state="M"/>
<connection from="-16.0.00" to="10.0.00" fromLane="2" toLane="2" via=":111_0_0" dir="r" state="M"/>
<connection from="-16.0.00" to="-17.0.00" fromLane="2" toLane="2" via=":111_1_0" dir="s" state="M"/>
<connection from="-17.0.00" to="4.0.00" fromLane="2" toLane="2" via=":139_0_0" dir="r" state="M"/>
<connection from="-17.0.00" to="-18.0.00" fromLane="2" toLane="2" via=":139_1_0" dir="s" state="M"/>
<connection from="-18.0.00" to="12.0.00" fromLane="2" toLane="2" via=":94_0_0" dir="r" state="M"/>
<connection from="-18.0.00" to="-19.0.00" fromLane="2" toLane="2" via=":94_1_0" dir="s" state="M"/>
<connection from="-19.0.00" to="6.0.00" fromLane="2" toLane="2" via=":60_0_0" dir="r" state="m"/>
<connection from="-19.0.00" to="-7.0.00" fromLane="2" toLane="2" via=":60_1_0" dir="l" state="m"/>
<connection from="-2.0.00" to="-3.0.00" fromLane="2" toLane="2" via=":77_0_0" dir="s" state="M"/>
<connection from="-2.0.00" to="-21.0.00" fromLane="2" toLane="2" via=":77_1_0" dir="l" state="m"/>
<connection from="-21.0.00" to="-22.0.00" fromLane="2" toLane="2" via=":184_0_0" dir="s" state="M"/>
<connection from="-21.0.00" to="-9.0.00" fromLane="2" toLane="2" via=":184_1_0" dir="l" state="m"/>
<connection from="-22.0.00" to="-23.0.00" fromLane="2" toLane="2" via=":156_0_0" dir="s" state="M"/>
<connection from="-22.0.00" to="-4.0.00" fromLane="2" toLane="2" via=":156_1_0" dir="l" state="m"/>
<connection from="-23.0.00" to="-24.0.00" fromLane="2" toLane="2" via=":128_0_0" dir="s" state="M"/>
<connection from="-23.0.00" to="-12.0.00" fromLane="2" toLane="2" via=":128_1_0" dir="l" state="m"/>
<connection from="-24.0.00" to="5.0.00" fromLane="2" toLane="2" via=":195_0_0" dir="r" state="m"/>
<connection from="-24.0.00" to="-6.0.00" fromLane="2" toLane="2" via=":195_1_0" dir="l" state="m"/>
<connection from="-25.0.00" to="9.0.00" fromLane="2" toLane="2" via=":167_0_0" dir="r" state="m"/>
<connection from="-25.0.00" to="-10.0.00" fromLane="2" toLane="2" via=":167_1_0" dir="l" state="m"/>
<connection from="-3.0.00" to="-6.0.00" fromLane="2" toLane="2" via=":195_4_0" dir="s" state="M"/>
<connection from="-3.0.00" to="24.0.00" fromLane="2" toLane="2" via=":195_5_0" dir="l" state="m"/>
<connection from="-4.0.00" to="-18.0.00" fromLane="2" toLane="2" via=":139_4_0" dir="r" state="m"/>
<connection from="-4.0.00" to="17.0.00" fromLane="2" toLane="2" via=":139_5_0" dir="l" state="m"/>
<connection from="-6.0.00" to="-7.0.00" fromLane="2" toLane="2" via=":60_4_0" dir="s" state="M"/>
<connection from="-6.0.00" to="19.0.00" fromLane="2" toLane="2" via=":60_5_0" dir="l" state="m"/>
<connection from="-7.0.00" to="14.0.00" fromLane="0" toLane="0" via=":7.14_3_0" dir="s" state="M"/>
<connection from="-7.0.00" to="14.0.00" fromLane="1" toLane="1" via=":7.14_3_1" dir="s" state="M"/>
<connection from="-7.0.00" to="14.0.00" fromLane="2" toLane="2" via=":7.14_3_2" dir="s" state="M"/>
<connection from="-8.0.00" to="-1.0.00" fromLane="2" toLane="2" via=":43_0_0" dir="s" state="M"/>
<connection from="-8.0.00" to="-16.0.00" fromLane="2" toLane="2" via=":43_1_0" dir="l" state="m"/>
<connection from="-9.0.00" to="-10.0.00" fromLane="2" toLane="2" via=":167_4_0" dir="s" state="M"/>
<connection from="-9.0.00" to="25.0.00" fromLane="2" toLane="2" via=":167_5_0" dir="l" state="m"/>
<connection from="0.0.00" to="-14.0.00" fromLane="0" toLane="0" via=":8.14_0_0" dir="s" state="M"/>
<connection from="0.0.00" to="-14.0.00" fromLane="1" toLane="1" via=":8.14_0_1" dir="s" state="M"/>
<connection from="0.0.00" to="-14.0.00" fromLane="2" toLane="2" via=":8.14_0_2" dir="s" state="M"/>
<connection from="1.0.00" to="-16.0.00" fromLane="2" toLane="2" via=":43_4_0" dir="r" state="M"/>
<connection from="1.0.00" to="0.0.00" fromLane="2" toLane="2" via=":43_5_0" dir="s" state="M"/>
<connection from="10.0.00" to="25.0.00" fromLane="2" toLane="2" via=":167_2_0" dir="r" state="M"/>
<connection from="10.0.00" to="9.0.00" fromLane="2" toLane="2" via=":167_3_0" dir="s" state="M"/>
<connection from="12.0.00" to="23.0.00" fromLane="2" toLane="2" via=":128_2_0" dir="r" state="m"/>
<connection from="12.0.00" to="-24.0.00" fromLane="2" toLane="2" via=":128_3_0" dir="l" state="m"/>
<connection from="14.0.00" to="-8.0.00" fromLane="0" toLane="0" via=":8.14_3_0" dir="s" state="M"/>
<connection from="14.0.00" to="-8.0.00" fromLane="1" toLane="1" via=":8.14_3_1" dir="s" state="M"/>
<connection from="14.0.00" to="-8.0.00" fromLane="2" toLane="2" via=":8.14_3_2" dir="s" state="M"/>
<connection from="16.0.00" to="0.0.00" fromLane="2" toLane="2" via=":43_2_0" dir="r" state="m"/>
<connection from="16.0.00" to="-1.0.00" fromLane="2" toLane="2" via=":43_3_0" dir="l" state="m"/>
<connection from="17.0.00" to="16.0.00" fromLane="2" toLane="2" via=":111_2_0" dir="s" state="M"/>
<connection from="17.0.00" to="10.0.00" fromLane="2" toLane="2" via=":111_3_0" dir="l" state="m"/>
<connection from="18.0.00" to="17.0.00" fromLane="2" toLane="2" via=":139_2_0" dir="s" state="M"/>
<connection from="18.0.00" to="4.0.00" fromLane="2" toLane="2" via=":139_3_0" dir="l" state="m"/>
<connection from="19.0.00" to="18.0.00" fromLane="2" toLane="2" via=":94_2_0" dir="s" state="M"/>
<connection from="19.0.00" to="12.0.00" fromLane="2" toLane="2" via=":94_3_0" dir="l" state="m"/>
<connection from="2.0.00" to="-25.0.00" fromLane="2" toLane="2" via=":26_4_0" dir="r" state="M"/>
<connection from="2.0.00" to="1.0.00" fromLane="2" toLane="2" via=":26_5_0" dir="s" state="M"/>
<connection from="21.0.00" to="2.0.00" fromLane="2" toLane="2" via=":77_2_0" dir="r" state="m"/>
<connection from="21.0.00" to="-3.0.00" fromLane="2" toLane="2" via=":77_3_0" dir="l" state="m"/>
<connection from="22.0.00" to="-9.0.00" fromLane="2" toLane="2" via=":184_4_0" dir="r" state="M"/>
<connection from="22.0.00" to="21.0.00" fromLane="2" toLane="2" via=":184_5_0" dir="s" state="M"/>
<connection from="23.0.00" to="-4.0.00" fromLane="2" toLane="2" via=":156_4_0" dir="r" state="M"/>
<connection from="23.0.00" to="22.0.00" fromLane="2" toLane="2" via=":156_5_0" dir="s" state="M"/>
<connection from="24.0.00" to="-12.0.00" fromLane="2" toLane="2" via=":128_4_0" dir="r" state="M"/>
<connection from="24.0.00" to="23.0.00" fromLane="2" toLane="2" via=":128_5_0" dir="s" state="M"/>
<connection from="25.0.00" to="1.0.00" fromLane="2" toLane="2" via=":26_2_0" dir="r" state="m"/>
<connection from="25.0.00" to="-2.0.00" fromLane="2" toLane="2" via=":26_3_0" dir="l" state="m"/>
<connection from="4.0.00" to="22.0.00" fromLane="2" toLane="2" via=":156_2_0" dir="r" state="m"/>
<connection from="4.0.00" to="-23.0.00" fromLane="2" toLane="2" via=":156_3_0" dir="l" state="m"/>
<connection from="5.0.00" to="-21.0.00" fromLane="2" toLane="2" via=":77_4_0" dir="r" state="M"/>
<connection from="5.0.00" to="2.0.00" fromLane="2" toLane="2" via=":77_5_0" dir="s" state="M"/>
<connection from="6.0.00" to="24.0.00" fromLane="2" toLane="2" via=":195_2_0" dir="r" state="M"/>
<connection from="6.0.00" to="5.0.00" fromLane="2" toLane="2" via=":195_3_0" dir="s" state="M"/>
<connection from="7.0.00" to="19.0.00" fromLane="2" toLane="2" via=":60_2_0" dir="r" state="M"/>
<connection from="7.0.00" to="6.0.00" fromLane="2" toLane="2" via=":60_3_0" dir="s" state="M"/>
<connection from="9.0.00" to="21.0.00" fromLane="2" toLane="2" via=":184_2_0" dir="r" state="m"/>
<connection from="9.0.00" to="-22.0.00" fromLane="2" toLane="2" via=":184_3_0" dir="l" state="m"/>
<connection from=":111_0" to="10.0.00" fromLane="0" toLane="2" dir="r" state="M"/>
<connection from=":111_1" to="-17.0.00" fromLane="0" toLane="2" dir="s" state="M"/>
<connection from=":111_2" to="16.0.00" fromLane="0" toLane="2" dir="s" state="M"/>
<connection from=":111_3" to="10.0.00" fromLane="0" toLane="2" via=":111_6_0" dir="l" state="m"/>
<connection from=":111_6" to="10.0.00" fromLane="0" toLane="2" dir="l" state="M"/>
<connection from=":111_4" to="-17.0.00" fromLane="0" toLane="2" dir="r" state="M"/>
<connection from=":111_5" to="16.0.00" fromLane="0" toLane="2" dir="l" state="M"/>
<connection from=":128_0" to="-24.0.00" fromLane="0" toLane="2" dir="s" state="M"/>
<connection from=":128_1" to="-12.0.00" fromLane="0" toLane="2" via=":128_6_0" dir="l" state="m"/>
<connection from=":128_6" to="-12.0.00" fromLane="0" toLane="2" dir="l" state="M"/>
<connection from=":128_2" to="23.0.00" fromLane="0" toLane="2" dir="r" state="M"/>
<connection from=":128_3" to="-24.0.00" fromLane="0" toLane="2" dir="l" state="M"/>
<connection from=":128_4" to="-12.0.00" fromLane="0" toLane="2" dir="r" state="M"/>
<connection from=":128_5" to="23.0.00" fromLane="0" toLane="2" dir="s" state="M"/>
<connection from=":139_0" to="4.0.00" fromLane="0" toLane="2" dir="r" state="M"/>
<connection from=":139_1" to="-18.0.00" fromLane="0" toLane="2" dir="s" state="M"/>
<connection from=":139_2" to="17.0.00" fromLane="0" toLane="2" dir="s" state="M"/>
<connection from=":139_3" to="4.0.00" fromLane="0" toLane="2" via=":139_6_0" dir="l" state="m"/>
<connection from=":139_6" to="4.0.00" fromLane="0" toLane="2" dir="l" state="M"/>
<connection from=":139_4" to="-18.0.00" fromLane="0" toLane="2" dir="r" state="M"/>
<connection from=":139_5" to="17.0.00" fromLane="0" toLane="2" dir="l" state="M"/>
<connection from=":156_0" to="-23.0.00" fromLane="0" toLane="2" dir="s" state="M"/>
<connection from=":156_1" to="-4.0.00" fromLane="0" toLane="2" via=":156_6_0" dir="l" state="m"/>
<connection from=":156_6" to="-4.0.00" fromLane="0" toLane="2" dir="l" state="M"/>
<connection from=":156_2" to="22.0.00" fromLane="0" toLane="2" dir="r" state="M"/>
<connection from=":156_3" to="-23.0.00" fromLane="0" toLane="2" dir="l" state="M"/>
<connection from=":156_4" to="-4.0.00" fromLane="0" toLane="2" dir="r" state="M"/>
<connection from=":156_5" to="22.0.00" fromLane="0" toLane="2" dir="s" state="M"/>
<connection from=":167_0" to="9.0.00" fromLane="0" toLane="2" dir="r" state="M"/>
<connection from=":167_1" to="-10.0.00" fromLane="0" toLane="2" dir="l" state="M"/>
<connection from=":167_2" to="25.0.00" fromLane="0" toLane="2" dir="r" state="M"/>
<connection from=":167_3" to="9.0.00" fromLane="0" toLane="2" dir="s" state="M"/>
<connection from=":167_4" to="-10.0.00" fromLane="0" toLane="2" dir="s" state="M"/>
<connection from=":167_5" to="25.0.00" fromLane="0" toLane="2" via=":167_6_0" dir="l" state="m"/>
<connection from=":167_6" to="25.0.00" fromLane="0" toLane="2" dir="l" state="M"/>
<connection from=":184_0" to="-22.0.00" fromLane="0" toLane="2" dir="s" state="M"/>
<connection from=":184_1" to="-9.0.00" fromLane="0" toLane="2" via=":184_6_0" dir="l" state="m"/>
<connection from=":184_6" to="-9.0.00" fromLane="0" toLane="2" dir="l" state="M"/>
<connection from=":184_2" to="21.0.00" fromLane="0" toLane="2" dir="r" state="M"/>
<connection from=":184_3" to="-22.0.00" fromLane="0" toLane="2" dir="l" state="M"/>
<connection from=":184_4" to="-9.0.00" fromLane="0" toLane="2" dir="r" state="M"/>
<connection from=":184_5" to="21.0.00" fromLane="0" toLane="2" dir="s" state="M"/>
<connection from=":195_0" to="5.0.00" fromLane="0" toLane="2" dir="r" state="M"/>
<connection from=":195_1" to="-6.0.00" fromLane="0" toLane="2" dir="l" state="M"/>
<connection from=":195_2" to="24.0.00" fromLane="0" toLane="2" dir="r" state="M"/>
<connection from=":195_3" to="5.0.00" fromLane="0" toLane="2" dir="s" state="M"/>
<connection from=":195_4" to="-6.0.00" fromLane="0" toLane="2" dir="s" state="M"/>
<connection from=":195_5" to="24.0.00" fromLane="0" toLane="2" via=":195_6_0" dir="l" state="m"/>
<connection from=":195_6" to="24.0.00" fromLane="0" toLane="2" dir="l" state="M"/>
<connection from=":26_0" to="-2.0.00" fromLane="0" toLane="2" dir="s" state="M"/>
<connection from=":26_1" to="-25.0.00" fromLane="0" toLane="2" via=":26_6_0" dir="l" state="m"/>
<connection from=":26_6" to="-25.0.00" fromLane="0" toLane="2" dir="l" state="M"/>
<connection from=":26_2" to="1.0.00" fromLane="0" toLane="2" dir="r" state="M"/>
<connection from=":26_3" to="-2.0.00" fromLane="0" toLane="2" dir="l" state="M"/>
<connection from=":26_4" to="-25.0.00" fromLane="0" toLane="2" dir="r" state="M"/>
<connection from=":26_5" to="1.0.00" fromLane="0" toLane="2" dir="s" state="M"/>
<connection from=":43_0" to="-1.0.00" fromLane="0" toLane="2" dir="s" state="M"/>
<connection from=":43_1" to="-16.0.00" fromLane="0" toLane="2" via=":43_6_0" dir="l" state="m"/>
<connection from=":43_6" to="-16.0.00" fromLane="0" toLane="2" dir="l" state="M"/>
<connection from=":43_2" to="0.0.00" fromLane="0" toLane="2" dir="r" state="M"/>
<connection from=":43_3" to="-1.0.00" fromLane="0" toLane="2" dir="l" state="M"/>
<connection from=":43_4" to="-16.0.00" fromLane="0" toLane="2" dir="r" state="M"/>
<connection from=":43_5" to="0.0.00" fromLane="0" toLane="2" dir="s" state="M"/>
<connection from=":60_0" to="6.0.00" fromLane="0" toLane="2" dir="r" state="M"/>
<connection from=":60_1" to="-7.0.00" fromLane="0" toLane="2" dir="l" state="M"/>
<connection from=":60_2" to="19.0.00" fromLane="0" toLane="2" dir="r" state="M"/>
<connection from=":60_3" to="6.0.00" fromLane="0" toLane="2" dir="s" state="M"/>
<connection from=":60_4" to="-7.0.00" fromLane="0" toLane="2" dir="s" state="M"/>
<connection from=":60_5" to="19.0.00" fromLane="0" toLane="2" via=":60_6_0" dir="l" state="m"/>
<connection from=":60_6" to="19.0.00" fromLane="0" toLane="2" dir="l" state="M"/>
<connection from=":7.14_0" to="7.0.00" fromLane="0" toLane="0" dir="s" state="M"/>
<connection from=":7.14_0" to="7.0.00" fromLane="1" toLane="1" dir="s" state="M"/>
<connection from=":7.14_0" to="7.0.00" fromLane="2" toLane="2" dir="s" state="M"/>
<connection from=":7.14_3" to="14.0.00" fromLane="0" toLane="0" dir="s" state="M"/>
<connection from=":7.14_3" to="14.0.00" fromLane="1" toLane="1" dir="s" state="M"/>
<connection from=":7.14_3" to="14.0.00" fromLane="2" toLane="2" dir="s" state="M"/>
<connection from=":77_0" to="-3.0.00" fromLane="0" toLane="2" dir="s" state="M"/>
<connection from=":77_1" to="-21.0.00" fromLane="0" toLane="2" via=":77_6_0" dir="l" state="m"/>
<connection from=":77_6" to="-21.0.00" fromLane="0" toLane="2" dir="l" state="M"/>
<connection from=":77_2" to="2.0.00" fromLane="0" toLane="2" dir="r" state="M"/>
<connection from=":77_3" to="-3.0.00" fromLane="0" toLane="2" dir="l" state="M"/>
<connection from=":77_4" to="-21.0.00" fromLane="0" toLane="2" dir="r" state="M"/>
<connection from=":77_5" to="2.0.00" fromLane="0" toLane="2" dir="s" state="M"/>
<connection from=":8.14_0" to="-14.0.00" fromLane="0" toLane="0" dir="s" state="M"/>
<connection from=":8.14_0" to="-14.0.00" fromLane="1" toLane="1" dir="s" state="M"/>
<connection from=":8.14_0" to="-14.0.00" fromLane="2" toLane="2" dir="s" state="M"/>
<connection from=":8.14_3" to="-8.0.00" fromLane="0" toLane="0" dir="s" state="M"/>
<connection from=":8.14_3" to="-8.0.00" fromLane="1" toLane="1" dir="s" state="M"/>
<connection from=":8.14_3" to="-8.0.00" fromLane="2" toLane="2" dir="s" state="M"/>
<connection from=":94_0" to="12.0.00" fromLane="0" toLane="2" dir="r" state="M"/>
<connection from=":94_1" to="-19.0.00" fromLane="0" toLane="2" dir="s" state="M"/>
<connection from=":94_2" to="18.0.00" fromLane="0" toLane="2" dir="s" state="M"/>
<connection from=":94_3" to="12.0.00" fromLane="0" toLane="2" via=":94_6_0" dir="l" state="m"/>
<connection from=":94_6" to="12.0.00" fromLane="0" toLane="2" dir="l" state="M"/>
<connection from=":94_4" to="-19.0.00" fromLane="0" toLane="2" dir="r" state="M"/>
<connection from=":94_5" to="18.0.00" fromLane="0" toLane="2" dir="l" state="M"/>
</net>

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -1,303 +0,0 @@
<?xml version='1.0' encoding='UTF-8'?>
<routes xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="http://sumo.dlr.de/xsd/routes_file.xsd">
<vehicle id="0" type="vehicle.diamondback.century" depart="0.00">
<route edges="-16.0.00 -17.0.00 4.0.00 22.0.00"/>
</vehicle>
<vehicle id="1" type="vehicle.yamaha.yzf" depart="1.00">
<route edges="-4.0.00 17.0.00 10.0.00 25.0.00 1.0.00 -16.0.00 -17.0.00 4.0.00"/>
</vehicle>
<vehicle id="2" type="vehicle.bh.crossbike" depart="2.00">
<route edges="-24.0.00 -6.0.00 19.0.00 18.0.00 17.0.00 16.0.00 0.0.00 -14.0.00 7.0.00 6.0.00"/>
</vehicle>
<vehicle id="3" type="vehicle.ford.mustang" depart="3.00">
<route edges="-8.0.00 -1.0.00 -2.0.00 -21.0.00 -22.0.00 -23.0.00 -12.0.00 18.0.00"/>
</vehicle>
<vehicle id="4" type="vehicle.harley-davidson.low_rider" depart="4.00">
<route edges="22.0.00 21.0.00 2.0.00 1.0.00 0.0.00"/>
</vehicle>
<vehicle id="5" type="vehicle.mini.cooper_s" depart="5.00">
<route edges="22.0.00 -9.0.00"/>
</vehicle>
<vehicle id="6" type="vehicle.jeep.wrangler_rubicon" depart="6.00">
<route edges="-25.0.00 -10.0.00 -17.0.00 -18.0.00 -19.0.00 -7.0.00 14.0.00 -8.0.00"/>
</vehicle>
<vehicle id="7" type="vehicle.audi.tt" depart="7.00">
<route edges="-18.0.00 12.0.00 23.0.00 22.0.00 21.0.00 -3.0.00"/>
</vehicle>
<vehicle id="8" type="vehicle.toyota.prius" depart="8.00">
<route edges="-14.0.00 7.0.00 19.0.00 18.0.00 17.0.00 16.0.00 0.0.00"/>
</vehicle>
<vehicle id="9" type="vehicle.citroen.c3" depart="9.00">
<route edges="-3.0.00 -6.0.00 19.0.00 12.0.00 -24.0.00"/>
</vehicle>
<vehicle id="10" type="vehicle.harley-davidson.low_rider" depart="10.00">
<route edges="-24.0.00 -6.0.00 19.0.00 12.0.00 23.0.00"/>
</vehicle>
<vehicle id="11" type="vehicle.micro.microlino" depart="11.00">
<route edges="18.0.00 4.0.00 -23.0.00 -24.0.00"/>
</vehicle>
<vehicle id="12" type="vehicle.micro.microlino" depart="12.00">
<route edges="-16.0.00 -17.0.00 -18.0.00 -19.0.00 -7.0.00 14.0.00 -8.0.00"/>
</vehicle>
<vehicle id="13" type="vehicle.seat.leon" depart="13.00">
<route edges="-21.0.00 -9.0.00 -10.0.00 16.0.00 -1.0.00"/>
</vehicle>
<vehicle id="14" type="vehicle.bmw.grandtourer" depart="14.00">
<route edges="17.0.00 16.0.00 -1.0.00 -2.0.00 -21.0.00"/>
</vehicle>
<vehicle id="15" type="vehicle.bmw.grandtourer" depart="15.00">
<route edges="7.0.00 6.0.00 24.0.00 23.0.00"/>
</vehicle>
<vehicle id="16" type="vehicle.bmw.grandtourer" depart="16.00">
<route edges="23.0.00 22.0.00 -9.0.00 -10.0.00 16.0.00"/>
</vehicle>
<vehicle id="17" type="vehicle.toyota.prius" depart="17.00">
<route edges="4.0.00 22.0.00 -9.0.00 -10.0.00 16.0.00"/>
</vehicle>
<vehicle id="18" type="vehicle.dodge.charger_police" depart="18.00">
<route edges="21.0.00 -3.0.00 -6.0.00"/>
</vehicle>
<vehicle id="19" type="vehicle.mercedes.coupe" depart="19.00">
<route edges="-22.0.00 -4.0.00 17.0.00 16.0.00 -1.0.00 -2.0.00"/>
</vehicle>
<vehicle id="20" type="vehicle.micro.microlino" depart="20.00">
<route edges="-1.0.00"/>
</vehicle>
<vehicle id="21" type="vehicle.bmw.grandtourer" depart="21.00">
<route edges="-17.0.00 -18.0.00 -19.0.00 -7.0.00"/>
</vehicle>
<vehicle id="22" type="vehicle.dodge.charger_police" depart="22.00">
<route edges="-25.0.00 9.0.00"/>
</vehicle>
<vehicle id="23" type="vehicle.diamondback.century" depart="23.00">
<route edges="12.0.00 23.0.00 22.0.00 21.0.00 2.0.00 1.0.00 -16.0.00"/>
</vehicle>
<vehicle id="24" type="vehicle.kawasaki.ninja" depart="24.00">
<route edges="22.0.00 21.0.00 2.0.00 -25.0.00 9.0.00 -22.0.00 -23.0.00 -24.0.00"/>
</vehicle>
<vehicle id="25" type="vehicle.tesla.cybertruck" depart="25.00">
<route edges="-8.0.00 -16.0.00 -17.0.00 -18.0.00 -19.0.00 6.0.00"/>
</vehicle>
<vehicle id="26" type="vehicle.ford.mustang" depart="26.00">
<route edges="-4.0.00 17.0.00 16.0.00 -1.0.00"/>
</vehicle>
<vehicle id="27" type="vehicle.seat.leon" depart="27.00">
<route edges="25.0.00 -2.0.00 -21.0.00 -22.0.00 -23.0.00 -12.0.00 18.0.00"/>
</vehicle>
<vehicle id="28" type="vehicle.jeep.wrangler_rubicon" depart="28.00">
<route edges="9.0.00 -22.0.00"/>
</vehicle>
<vehicle id="29" type="vehicle.kawasaki.ninja" depart="29.00">
<route edges="-2.0.00 -21.0.00 -9.0.00 25.0.00 1.0.00"/>
</vehicle>
<vehicle id="30" type="vehicle.ford.mustang" depart="30.00">
<route edges="-4.0.00 17.0.00 16.0.00 -1.0.00 -2.0.00 -21.0.00"/>
</vehicle>
<vehicle id="31" type="vehicle.citroen.c3" depart="31.00">
<route edges="17.0.00 16.0.00 0.0.00 -14.0.00 7.0.00 6.0.00 24.0.00 23.0.00"/>
</vehicle>
<vehicle id="32" type="vehicle.citroen.c3" depart="32.00">
<route edges="-3.0.00 -6.0.00 19.0.00"/>
</vehicle>
<vehicle id="33" type="vehicle.diamondback.century" depart="33.00">
<route edges="-4.0.00 17.0.00 16.0.00 0.0.00"/>
</vehicle>
<vehicle id="34" type="vehicle.dodge.charger_police" depart="34.00">
<route edges="14.0.00 -8.0.00 -16.0.00 10.0.00 25.0.00 1.0.00 0.0.00 -14.0.00 7.0.00"/>
</vehicle>
<vehicle id="35" type="vehicle.carlamotors.carlacola" depart="35.00">
<route edges="6.0.00 24.0.00 23.0.00 22.0.00 21.0.00 2.0.00"/>
</vehicle>
<vehicle id="36" type="vehicle.audi.tt" depart="36.00">
<route edges="-19.0.00 -7.0.00 14.0.00 -8.0.00"/>
</vehicle>
<vehicle id="37" type="vehicle.nissan.patrol" depart="37.00">
<route edges="-19.0.00 6.0.00 5.0.00"/>
</vehicle>
<vehicle id="38" type="vehicle.diamondback.century" depart="38.00">
<route edges="22.0.00 -9.0.00 -10.0.00 16.0.00 -1.0.00"/>
</vehicle>
<vehicle id="39" type="vehicle.tesla.cybertruck" depart="39.00">
<route edges="-21.0.00 -9.0.00 -10.0.00 16.0.00 -1.0.00"/>
</vehicle>
<vehicle id="40" type="vehicle.mercedes.coupe" depart="40.00">
<route edges="17.0.00 10.0.00 25.0.00 1.0.00"/>
</vehicle>
<vehicle id="41" type="vehicle.audi.tt" depart="41.00">
<route edges="-3.0.00 24.0.00 -12.0.00 -19.0.00 6.0.00"/>
</vehicle>
<vehicle id="42" type="vehicle.dodge.charger_police" depart="42.00">
<route edges="-8.0.00 -16.0.00 10.0.00 25.0.00 1.0.00"/>
</vehicle>
<vehicle id="43" type="vehicle.micro.microlino" depart="43.00">
<route edges="9.0.00 -22.0.00 -23.0.00"/>
</vehicle>
<vehicle id="44" type="vehicle.seat.leon" depart="44.00">
<route edges="-25.0.00 -10.0.00 -17.0.00 -18.0.00 -19.0.00 -7.0.00"/>
</vehicle>
<vehicle id="45" type="vehicle.mini.cooper_s" depart="45.00">
<route edges="-12.0.00 18.0.00 4.0.00 22.0.00 21.0.00"/>
</vehicle>
<vehicle id="46" type="vehicle.mini.cooper_s" depart="46.00">
<route edges="2.0.00 -25.0.00 9.0.00 21.0.00"/>
</vehicle>
<vehicle id="47" type="vehicle.chevrolet.impala" depart="47.00">
<route edges="-24.0.00 5.0.00 2.0.00 -25.0.00 -10.0.00"/>
</vehicle>
<vehicle id="48" type="vehicle.carlamotors.carlacola" depart="48.00">
<route edges="14.0.00 -8.0.00 -16.0.00 -17.0.00 4.0.00 22.0.00"/>
</vehicle>
<vehicle id="49" type="vehicle.citroen.c3" depart="49.00">
<route edges="-10.0.00 -17.0.00 -18.0.00 -19.0.00 6.0.00 5.0.00"/>
</vehicle>
<vehicle id="50" type="vehicle.ford.mustang" depart="50.00">
<route edges="18.0.00 4.0.00 22.0.00 -9.0.00"/>
</vehicle>
<vehicle id="51" type="vehicle.dodge.charger_police" depart="51.00">
<route edges="25.0.00 1.0.00 -16.0.00 -17.0.00 -18.0.00 -19.0.00 -7.0.00 14.0.00 -8.0.00"/>
</vehicle>
<vehicle id="52" type="vehicle.bmw.grandtourer" depart="52.00">
<route edges="21.0.00 2.0.00 1.0.00 0.0.00"/>
</vehicle>
<vehicle id="53" type="vehicle.audi.etron" depart="53.00">
<route edges="-16.0.00 -17.0.00 -18.0.00 -19.0.00 6.0.00"/>
</vehicle>
<vehicle id="54" type="vehicle.chevrolet.impala" depart="54.00">
<route edges="24.0.00 23.0.00 22.0.00 -9.0.00 -10.0.00"/>
</vehicle>
<vehicle id="55" type="vehicle.volkswagen.t2" depart="55.00">
<route edges="-12.0.00 18.0.00 17.0.00 16.0.00 -1.0.00"/>
</vehicle>
<vehicle id="56" type="vehicle.micro.microlino" depart="56.00">
<route edges="14.0.00 -8.0.00 -1.0.00 -25.0.00 -10.0.00"/>
</vehicle>
<vehicle id="57" type="vehicle.ford.mustang" depart="57.00">
<route edges="-22.0.00 -23.0.00 -24.0.00 5.0.00 2.0.00"/>
</vehicle>
<vehicle id="58" type="vehicle.tesla.cybertruck" depart="58.00">
<route edges="19.0.00 18.0.00 4.0.00 22.0.00"/>
</vehicle>
<vehicle id="59" type="vehicle.mini.cooper_s" depart="59.00">
<route edges="6.0.00 24.0.00 -12.0.00 18.0.00"/>
</vehicle>
<vehicle id="60" type="vehicle.ford.mustang" depart="60.00">
<route edges="-1.0.00 -25.0.00 -10.0.00 -17.0.00 -18.0.00 -19.0.00 -7.0.00"/>
</vehicle>
<vehicle id="61" type="vehicle.gazelle.omafiets" depart="61.00">
<route edges="4.0.00 -23.0.00 -24.0.00 -6.0.00 -7.0.00 14.0.00"/>
</vehicle>
<vehicle id="62" type="vehicle.audi.a2" depart="62.00">
<route edges="-2.0.00 -21.0.00 -22.0.00 -4.0.00 -18.0.00 12.0.00"/>
</vehicle>
<vehicle id="63" type="vehicle.nissan.micra" depart="63.00">
<route edges="-14.0.00 7.0.00 6.0.00 5.0.00"/>
</vehicle>
<vehicle id="64" type="vehicle.nissan.micra" depart="64.00">
<route edges="-25.0.00 -10.0.00 16.0.00"/>
</vehicle>
<vehicle id="65" type="vehicle.toyota.prius" depart="65.00">
<route edges="-21.0.00 -22.0.00 -4.0.00 -18.0.00 12.0.00"/>
</vehicle>
<vehicle id="66" type="vehicle.chevrolet.impala" depart="66.00">
<route edges="10.0.00 25.0.00 1.0.00 -16.0.00 -17.0.00 -18.0.00 -19.0.00 -7.0.00"/>
</vehicle>
<vehicle id="67" type="vehicle.audi.a2" depart="67.00">
<route edges="22.0.00 -9.0.00 -10.0.00 -17.0.00 -18.0.00 -19.0.00 -7.0.00 14.0.00"/>
</vehicle>
<vehicle id="68" type="vehicle.mini.cooper_s" depart="68.00">
<route edges="-23.0.00 -12.0.00 18.0.00 17.0.00 16.0.00 -1.0.00"/>
</vehicle>
<vehicle id="69" type="vehicle.mini.cooper_s" depart="69.00">
<route edges="24.0.00 23.0.00 22.0.00 21.0.00 2.0.00 1.0.00 0.0.00 -14.0.00 7.0.00 19.0.00"/>
</vehicle>
<vehicle id="70" type="vehicle.dodge.charger_police" depart="70.00">
<route edges="14.0.00 -8.0.00 -1.0.00 -2.0.00 -21.0.00 -22.0.00 -23.0.00 -24.0.00 -6.0.00"/>
</vehicle>
<vehicle id="71" type="vehicle.bmw.grandtourer" depart="71.00">
<route edges="7.0.00 19.0.00 18.0.00 4.0.00 -23.0.00"/>
</vehicle>
<vehicle id="72" type="vehicle.volkswagen.t2" depart="72.00">
<route edges="6.0.00 24.0.00 23.0.00 22.0.00 21.0.00 2.0.00 1.0.00 0.0.00 -14.0.00"/>
</vehicle>
<vehicle id="73" type="vehicle.tesla.model3" depart="73.00">
<route edges="-14.0.00 7.0.00 6.0.00 24.0.00 -12.0.00 -19.0.00 -7.0.00"/>
</vehicle>
<vehicle id="74" type="vehicle.mercedes.coupe" depart="74.00">
<route edges="-22.0.00 -4.0.00 -18.0.00 -19.0.00"/>
</vehicle>
<vehicle id="75" type="vehicle.jeep.wrangler_rubicon" depart="75.00">
<route edges="-25.0.00 -10.0.00 -17.0.00 -18.0.00 -19.0.00 -7.0.00"/>
</vehicle>
<vehicle id="76" type="vehicle.kawasaki.ninja" depart="76.00">
<route edges="6.0.00 24.0.00 23.0.00 22.0.00 -9.0.00"/>
</vehicle>
<vehicle id="77" type="vehicle.diamondback.century" depart="77.00">
<route edges="-4.0.00 -18.0.00 -19.0.00 6.0.00 24.0.00"/>
</vehicle>
<vehicle id="78" type="vehicle.mercedes.coupe" depart="78.00">
<route edges="9.0.00 -22.0.00 -4.0.00 -18.0.00 -19.0.00 6.0.00"/>
</vehicle>
<vehicle id="79" type="vehicle.mercedes.coupe" depart="79.00">
<route edges="-24.0.00 -6.0.00 -7.0.00"/>
</vehicle>
<vehicle id="80" type="vehicle.citroen.c3" depart="80.00">
<route edges="-14.0.00 7.0.00 19.0.00 18.0.00 17.0.00 16.0.00"/>
</vehicle>
<vehicle id="81" type="vehicle.seat.leon" depart="81.00">
<route edges="-8.0.00 -16.0.00 -17.0.00 -18.0.00 -19.0.00"/>
</vehicle>
<vehicle id="82" type="vehicle.audi.a2" depart="82.00">
<route edges="2.0.00 1.0.00 -16.0.00 -17.0.00 -18.0.00 -19.0.00 -7.0.00"/>
</vehicle>
<vehicle id="83" type="vehicle.audi.tt" depart="83.00">
<route edges="-19.0.00 6.0.00"/>
</vehicle>
<vehicle id="84" type="vehicle.lincoln.mkz_2017" depart="84.00">
<route edges="-6.0.00 19.0.00 18.0.00 4.0.00 -23.0.00"/>
</vehicle>
<vehicle id="85" type="vehicle.mini.cooper_s" depart="85.00">
<route edges="-19.0.00 6.0.00 24.0.00 23.0.00 22.0.00 21.0.00 2.0.00 1.0.00"/>
</vehicle>
<vehicle id="86" type="vehicle.tesla.model3" depart="86.00">
<route edges="-4.0.00 17.0.00 16.0.00"/>
</vehicle>
<vehicle id="87" type="vehicle.micro.microlino" depart="87.00">
<route edges="-10.0.00 -17.0.00 4.0.00 22.0.00 -9.0.00 25.0.00"/>
</vehicle>
<vehicle id="88" type="vehicle.diamondback.century" depart="88.00">
<route edges="-7.0.00 14.0.00 -8.0.00 -16.0.00 10.0.00 25.0.00 1.0.00"/>
</vehicle>
<vehicle id="89" type="vehicle.mercedes.coupe" depart="89.00">
<route edges="-1.0.00 -25.0.00 -10.0.00 16.0.00 0.0.00 -14.0.00"/>
</vehicle>
<vehicle id="90" type="vehicle.volkswagen.t2" depart="90.00">
<route edges="-12.0.00 -19.0.00"/>
</vehicle>
<vehicle id="91" type="vehicle.mini.cooper_s" depart="91.00">
<route edges="-24.0.00 5.0.00 2.0.00 -25.0.00"/>
</vehicle>
<vehicle id="92" type="vehicle.gazelle.omafiets" depart="92.00">
<route edges="4.0.00 22.0.00 21.0.00"/>
</vehicle>
<vehicle id="93" type="vehicle.nissan.micra" depart="93.00">
<route edges="4.0.00 22.0.00 21.0.00 2.0.00 1.0.00 0.0.00 -14.0.00"/>
</vehicle>
<vehicle id="94" type="vehicle.chevrolet.impala" depart="94.00">
<route edges="-19.0.00 6.0.00 24.0.00 23.0.00"/>
</vehicle>
<vehicle id="95" type="vehicle.diamondback.century" depart="95.00">
<route edges="-10.0.00 -17.0.00 -18.0.00 12.0.00 -24.0.00 -6.0.00"/>
</vehicle>
<vehicle id="96" type="vehicle.bh.crossbike" depart="96.00">
<route edges="-17.0.00 -18.0.00 -19.0.00"/>
</vehicle>
<vehicle id="97" type="vehicle.toyota.prius" depart="97.00">
<route edges="-14.0.00 7.0.00 19.0.00 18.0.00 17.0.00 10.0.00 25.0.00"/>
</vehicle>
<vehicle id="98" type="vehicle.nissan.micra" depart="98.00">
<route edges="9.0.00 -22.0.00 -4.0.00 -18.0.00 -19.0.00 6.0.00"/>
</vehicle>
<vehicle id="99" type="vehicle.kawasaki.ninja" depart="99.00">
<route edges="-9.0.00 -10.0.00 -17.0.00 -18.0.00"/>
</vehicle>
</routes>

View File

@ -1,603 +0,0 @@
<?xml version='1.0' encoding='UTF-8'?>
<routes xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="http://sumo.dlr.de/xsd/routes_file.xsd">
<vehicle id="0" type="vehicle.chevrolet.impala" depart="0.00">
<route edges="-46.0.00 -47.0.00 34.0.00 -39.0.00 33.0.00 47.0.00 44.0.00 39.0.00 38.0.00 37.0.00 36.0.00 35.0.00 42.0.00 -23.0.00"/>
</vehicle>
<vehicle id="1" type="vehicle.micro.microlino" depart="1.00">
<route edges="34.0.00 -39.0.00 33.0.00 47.0.00 44.0.00 39.0.00 31.0.00 -47.0.00 -48.0.00 -7.0.00 -8.0.00 52.0.00 27.0.00 26.0.00"/>
</vehicle>
<vehicle id="2" type="vehicle.tesla.model3" depart="2.00">
<route edges="45.0.00 40.0.00 39.0.00 31.0.00 -47.0.00 -48.0.00 -7.0.00 -8.0.00 -9.0.00 -10.0.00 -11.0.00 3.0.00 2.0.00"/>
</vehicle>
<vehicle id="3" type="vehicle.mini.cooper_s" depart="3.00">
<route edges="38.0.00 37.0.00 36.0.00 35.0.00 42.0.00 49.0.00 48.0.00 47.0.00 46.0.00"/>
</vehicle>
<vehicle id="4" type="vehicle.citroen.c3" depart="4.00">
<route edges="-52.0.00 -9.0.00 17.0.00"/>
</vehicle>
<vehicle id="5" type="vehicle.ford.mustang" depart="5.00">
<route edges="18.0.00 -10.0.00 -11.0.00 -12.0.00 -13.0.00 -14.0.00 -36.0.00 -37.0.00 -38.0.00 -39.0.00 33.0.00 47.0.00 44.0.00 39.0.00 38.0.00 37.0.00 36.0.00 35.0.00 42.0.00 49.0.00"/>
</vehicle>
<vehicle id="6" type="vehicle.ford.mustang" depart="6.00">
<route edges="-5.0.00 -37.0.00 -38.0.00 -39.0.00 33.0.00 47.0.00 44.0.00 39.0.00 31.0.00 -47.0.00 -48.0.00 -7.0.00 -8.0.00 52.0.00 27.0.00 -30.0.00"/>
</vehicle>
<vehicle id="7" type="vehicle.lincoln.mkz_2017" depart="7.00">
<route edges="30.0.00 29.0.00 28.0.00 -19.0.00 -5.0.00 -37.0.00 -38.0.00 -39.0.00 33.0.00 47.0.00 44.0.00 39.0.00 38.0.00 37.0.00 36.0.00 35.0.00 42.0.00 -23.0.00"/>
</vehicle>
<vehicle id="8" type="vehicle.jeep.wrangler_rubicon" depart="8.00">
<route edges="52.0.00 27.0.00 26.0.00 -2.0.00 -3.0.00 -4.0.00 -5.0.00 -37.0.00 -38.0.00 -39.0.00 33.0.00 47.0.00 44.0.00 39.0.00 31.0.00 -47.0.00"/>
</vehicle>
<vehicle id="9" type="vehicle.volkswagen.t2" depart="9.00">
<route edges="2.0.00 -26.0.00 29.0.00 10.0.00"/>
</vehicle>
<vehicle id="10" type="vehicle.carlamotors.carlacola" depart="10.00">
<route edges="-36.0.00 5.0.00 19.0.00 18.0.00 9.0.00 52.0.00"/>
</vehicle>
<vehicle id="11" type="vehicle.toyota.prius" depart="11.00">
<route edges="17.0.00 27.0.00 26.0.00 25.0.00 -14.0.00"/>
</vehicle>
<vehicle id="12" type="vehicle.nissan.micra" depart="12.00">
<route edges="-49.0.00 -50.0.00 -43.0.00 14.0.00 13.0.00 21.0.00 2.0.00"/>
</vehicle>
<vehicle id="13" type="vehicle.nissan.micra" depart="13.00">
<route edges="-16.0.00 27.0.00 -30.0.00 0.0.00"/>
</vehicle>
<vehicle id="14" type="vehicle.harley-davidson.low_rider" depart="14.00">
<route edges="-49.0.00 -50.0.00 -15.0.00 -16.0.00"/>
</vehicle>
<vehicle id="15" type="vehicle.diamondback.century" depart="15.00">
<route edges="30.0.00 26.0.00 -2.0.00 -3.0.00 -4.0.00 19.0.00"/>
</vehicle>
<vehicle id="16" type="vehicle.jeep.wrangler_rubicon" depart="16.00">
<route edges="-50.0.00 -43.0.00 14.0.00"/>
</vehicle>
<vehicle id="17" type="vehicle.lincoln.mkz_2017" depart="17.00">
<route edges="-23.0.00 40.0.00 39.0.00 31.0.00 -47.0.00 -48.0.00 -7.0.00 -8.0.00 -9.0.00 -10.0.00 -11.0.00 -12.0.00 -13.0.00"/>
</vehicle>
<vehicle id="18" type="vehicle.jeep.wrangler_rubicon" depart="18.00">
<route edges="13.0.00 12.0.00"/>
</vehicle>
<vehicle id="19" type="vehicle.yamaha.yzf" depart="19.00">
<route edges="18.0.00 -10.0.00 -11.0.00 -12.0.00 -13.0.00 -14.0.00 -36.0.00 -37.0.00 -38.0.00 -39.0.00 -40.0.00 -41.0.00 -22.0.00"/>
</vehicle>
<vehicle id="20" type="vehicle.mini.cooper_s" depart="20.00">
<route edges="42.0.00 49.0.00 48.0.00 47.0.00 44.0.00 39.0.00 31.0.00 -47.0.00 -48.0.00 -7.0.00 -8.0.00 52.0.00 -17.0.00 9.0.00 8.0.00 7.0.00"/>
</vehicle>
<vehicle id="21" type="vehicle.nissan.patrol" depart="21.00">
<route edges="48.0.00 47.0.00 44.0.00 39.0.00 38.0.00 37.0.00 36.0.00 35.0.00 42.0.00"/>
</vehicle>
<vehicle id="22" type="vehicle.bmw.grandtourer" depart="22.00">
<route edges="18.0.00 -10.0.00 -29.0.00 26.0.00 -2.0.00"/>
</vehicle>
<vehicle id="23" type="vehicle.mini.cooper_s" depart="23.00">
<route edges="-17.0.00 -10.0.00 -29.0.00 26.0.00"/>
</vehicle>
<vehicle id="24" type="vehicle.diamondback.century" depart="24.00">
<route edges="-10.0.00 28.0.00 18.0.00 9.0.00 8.0.00"/>
</vehicle>
<vehicle id="25" type="vehicle.tesla.model3" depart="25.00">
<route edges="29.0.00 10.0.00 17.0.00 16.0.00 -51.0.00 -8.0.00"/>
</vehicle>
<vehicle id="26" type="vehicle.dodge.charger_police" depart="26.00">
<route edges="39.0.00 31.0.00 -47.0.00 -48.0.00 -7.0.00 -8.0.00 52.0.00 27.0.00 29.0.00 10.0.00"/>
</vehicle>
<vehicle id="27" type="vehicle.chevrolet.impala" depart="27.00">
<route edges="47.0.00"/>
</vehicle>
<vehicle id="28" type="vehicle.toyota.prius" depart="28.00">
<route edges="47.0.00 44.0.00 39.0.00 31.0.00 -47.0.00 -48.0.00 -7.0.00 -8.0.00 52.0.00 27.0.00 29.0.00 10.0.00"/>
</vehicle>
<vehicle id="29" type="vehicle.micro.microlino" depart="29.00">
<route edges="28.0.00 -19.0.00 4.0.00 -12.0.00 -13.0.00 -14.0.00 -36.0.00"/>
</vehicle>
<vehicle id="30" type="vehicle.tesla.cybertruck" depart="30.00">
<route edges="34.0.00 -39.0.00 33.0.00 47.0.00 44.0.00 39.0.00 31.0.00 -47.0.00 -48.0.00 -7.0.00 -8.0.00 -9.0.00 -10.0.00"/>
</vehicle>
<vehicle id="31" type="vehicle.tesla.cybertruck" depart="31.00">
<route edges="37.0.00 36.0.00 35.0.00 42.0.00 49.0.00 48.0.00 47.0.00 44.0.00 39.0.00 31.0.00 -47.0.00 -48.0.00"/>
</vehicle>
<vehicle id="32" type="vehicle.lincoln.mkz_2017" depart="32.00">
<route edges="39.0.00 31.0.00 -47.0.00 -48.0.00 -7.0.00 51.0.00"/>
</vehicle>
<vehicle id="33" type="vehicle.citroen.c3" depart="33.00">
<route edges="-16.0.00 -17.0.00 -18.0.00 -19.0.00 -5.0.00 -37.0.00 -38.0.00 -39.0.00 33.0.00 47.0.00 46.0.00 45.0.00 40.0.00"/>
</vehicle>
<vehicle id="34" type="vehicle.diamondback.century" depart="34.00">
<route edges="-28.0.00 -11.0.00 -4.0.00 -20.0.00 13.0.00"/>
</vehicle>
<vehicle id="35" type="vehicle.gazelle.omafiets" depart="35.00">
<route edges="-10.0.00 -11.0.00 -4.0.00 -5.0.00"/>
</vehicle>
<vehicle id="36" type="vehicle.jeep.wrangler_rubicon" depart="36.00">
<route edges="39.0.00 31.0.00 -47.0.00 34.0.00 -39.0.00 33.0.00"/>
</vehicle>
<vehicle id="37" type="vehicle.audi.etron" depart="37.00">
<route edges="-43.0.00 14.0.00 -25.0.00"/>
</vehicle>
<vehicle id="38" type="vehicle.yamaha.yzf" depart="38.00">
<route edges="49.0.00 48.0.00 47.0.00 44.0.00 39.0.00 31.0.00 -47.0.00 -48.0.00 -7.0.00 -8.0.00 -9.0.00 -18.0.00 -28.0.00"/>
</vehicle>
<vehicle id="39" type="vehicle.gazelle.omafiets" depart="39.00">
<route edges="38.0.00 37.0.00 36.0.00 35.0.00 42.0.00 49.0.00 48.0.00 47.0.00 44.0.00 39.0.00 31.0.00 -47.0.00 -48.0.00 -7.0.00 -8.0.00 -9.0.00"/>
</vehicle>
<vehicle id="40" type="vehicle.citroen.c3" depart="40.00">
<route edges="13.0.00 12.0.00 -4.0.00 -5.0.00 -37.0.00"/>
</vehicle>
<vehicle id="41" type="vehicle.bh.crossbike" depart="41.00">
<route edges="-39.0.00 33.0.00 47.0.00 44.0.00 39.0.00 31.0.00 -47.0.00 -48.0.00 -7.0.00 -8.0.00 -9.0.00 17.0.00"/>
</vehicle>
<vehicle id="42" type="vehicle.bh.crossbike" depart="42.00">
<route edges="-39.0.00 33.0.00 47.0.00 44.0.00 39.0.00 31.0.00 -47.0.00 -48.0.00 -7.0.00 -8.0.00 -9.0.00 -18.0.00 -19.0.00 -5.0.00 -37.0.00 -38.0.00"/>
</vehicle>
<vehicle id="43" type="vehicle.lincoln.mkz_2017" depart="43.00">
<route edges="-18.0.00 -19.0.00 -5.0.00 -37.0.00 -38.0.00 -39.0.00 33.0.00 47.0.00 44.0.00 39.0.00 31.0.00 -47.0.00 -48.0.00 -7.0.00"/>
</vehicle>
<vehicle id="44" type="vehicle.mercedes.coupe" depart="44.00">
<route edges="0.0.00 15.0.00 -43.0.00 -36.0.00 -37.0.00 -38.0.00 -39.0.00 33.0.00 47.0.00 46.0.00 45.0.00 40.0.00"/>
</vehicle>
<vehicle id="45" type="vehicle.volkswagen.t2" depart="45.00">
<route edges="7.0.00 -49.0.00 -50.0.00"/>
</vehicle>
<vehicle id="46" type="vehicle.bh.crossbike" depart="46.00">
<route edges="-22.0.00 37.0.00 36.0.00 35.0.00 42.0.00 -23.0.00 -41.0.00"/>
</vehicle>
<vehicle id="47" type="vehicle.mercedes.coupe" depart="47.00">
<route edges="26.0.00 -2.0.00 -3.0.00 11.0.00 10.0.00 9.0.00 52.0.00"/>
</vehicle>
<vehicle id="48" type="vehicle.citroen.c3" depart="48.00">
<route edges="46.0.00 45.0.00 40.0.00 39.0.00 31.0.00 -47.0.00 34.0.00 -39.0.00 33.0.00 47.0.00"/>
</vehicle>
<vehicle id="49" type="vehicle.lincoln.mkz_2017" depart="49.00">
<route edges="-11.0.00 -12.0.00 -13.0.00"/>
</vehicle>
<vehicle id="50" type="vehicle.gazelle.omafiets" depart="50.00">
<route edges="4.0.00 3.0.00 2.0.00 -26.0.00 -27.0.00 -52.0.00 -9.0.00"/>
</vehicle>
<vehicle id="51" type="vehicle.ford.mustang" depart="51.00">
<route edges="-19.0.00 -5.0.00 -37.0.00"/>
</vehicle>
<vehicle id="52" type="vehicle.tesla.cybertruck" depart="52.00">
<route edges="-20.0.00 -25.0.00 -26.0.00 -30.0.00 -1.0.00"/>
</vehicle>
<vehicle id="53" type="vehicle.harley-davidson.low_rider" depart="53.00">
<route edges="34.0.00 -39.0.00 33.0.00 47.0.00 44.0.00 39.0.00 31.0.00 -47.0.00 -48.0.00 -7.0.00 -8.0.00 52.0.00 27.0.00 26.0.00"/>
</vehicle>
<vehicle id="54" type="vehicle.kawasaki.ninja" depart="54.00">
<route edges="-25.0.00 -2.0.00 -3.0.00 -4.0.00 19.0.00 -28.0.00"/>
</vehicle>
<vehicle id="55" type="vehicle.tesla.cybertruck" depart="55.00">
<route edges="-10.0.00 -29.0.00 26.0.00 -2.0.00"/>
</vehicle>
<vehicle id="56" type="vehicle.mercedes.coupe" depart="56.00">
<route edges="36.0.00 35.0.00 42.0.00 49.0.00 48.0.00 47.0.00 44.0.00 39.0.00 31.0.00 -47.0.00 -48.0.00 -7.0.00 51.0.00"/>
</vehicle>
<vehicle id="57" type="vehicle.micro.microlino" depart="57.00">
<route edges="27.0.00 26.0.00 -2.0.00 -3.0.00 -12.0.00 -13.0.00"/>
</vehicle>
<vehicle id="58" type="vehicle.tesla.cybertruck" depart="58.00">
<route edges="-8.0.00"/>
</vehicle>
<vehicle id="59" type="vehicle.bmw.grandtourer" depart="59.00">
<route edges="-15.0.00 -0.0.00 -1.0.00 -2.0.00 -3.0.00 -4.0.00 -5.0.00 -37.0.00 -38.0.00 -39.0.00 33.0.00"/>
</vehicle>
<vehicle id="60" type="vehicle.lincoln.mkz_2017" depart="60.00">
<route edges="-36.0.00 -37.0.00 -38.0.00 -39.0.00 33.0.00 47.0.00 44.0.00 39.0.00 31.0.00 -47.0.00 -48.0.00"/>
</vehicle>
<vehicle id="61" type="vehicle.kawasaki.ninja" depart="61.00">
<route edges="-12.0.00 -13.0.00 -14.0.00 -36.0.00 -37.0.00 -38.0.00 -39.0.00 33.0.00 47.0.00 44.0.00 39.0.00 31.0.00 -47.0.00 -48.0.00"/>
</vehicle>
<vehicle id="62" type="vehicle.toyota.prius" depart="62.00">
<route edges="-30.0.00 0.0.00 -51.0.00 7.0.00 -49.0.00"/>
</vehicle>
<vehicle id="63" type="vehicle.citroen.c3" depart="63.00">
<route edges="-50.0.00 -15.0.00 -0.0.00 -1.0.00 -2.0.00 -3.0.00 -4.0.00 -5.0.00"/>
</vehicle>
<vehicle id="64" type="vehicle.citroen.c3" depart="64.00">
<route edges="1.0.00 30.0.00 29.0.00 28.0.00 -19.0.00 -5.0.00 -37.0.00 -38.0.00 -39.0.00 33.0.00 47.0.00 46.0.00"/>
</vehicle>
<vehicle id="65" type="vehicle.kawasaki.ninja" depart="65.00">
<route edges="11.0.00 -29.0.00 26.0.00 1.0.00"/>
</vehicle>
<vehicle id="66" type="vehicle.mercedes.coupe" depart="66.00">
<route edges="-20.0.00 13.0.00 12.0.00 3.0.00"/>
</vehicle>
<vehicle id="67" type="vehicle.chevrolet.impala" depart="67.00">
<route edges="-29.0.00 -27.0.00 -17.0.00 9.0.00 52.0.00"/>
</vehicle>
<vehicle id="68" type="vehicle.diamondback.century" depart="68.00">
<route edges="35.0.00 42.0.00 49.0.00 48.0.00 47.0.00 44.0.00"/>
</vehicle>
<vehicle id="69" type="vehicle.audi.tt" depart="69.00">
<route edges="14.0.00 13.0.00 12.0.00 -4.0.00 -5.0.00 -37.0.00 -38.0.00 -39.0.00 33.0.00 47.0.00 44.0.00 39.0.00 31.0.00 -47.0.00 -48.0.00 -7.0.00"/>
</vehicle>
<vehicle id="70" type="vehicle.audi.a2" depart="70.00">
<route edges="38.0.00 37.0.00 36.0.00 35.0.00 42.0.00 49.0.00 48.0.00 47.0.00 44.0.00 39.0.00 31.0.00 -47.0.00 34.0.00"/>
</vehicle>
<vehicle id="71" type="vehicle.jeep.wrangler_rubicon" depart="71.00">
<route edges="37.0.00 36.0.00 35.0.00 42.0.00 49.0.00 48.0.00 47.0.00 44.0.00 39.0.00 31.0.00 -47.0.00 -48.0.00 -7.0.00 -8.0.00 -9.0.00 -10.0.00 28.0.00 18.0.00"/>
</vehicle>
<vehicle id="72" type="vehicle.mercedes.coupe" depart="72.00">
<route edges="-7.0.00 -8.0.00 -9.0.00 17.0.00 -52.0.00"/>
</vehicle>
<vehicle id="73" type="vehicle.mercedes.coupe" depart="73.00">
<route edges="-47.0.00 -48.0.00 -7.0.00 -8.0.00 -9.0.00 -10.0.00 -11.0.00 -12.0.00 -13.0.00 -14.0.00"/>
</vehicle>
<vehicle id="74" type="vehicle.chevrolet.impala" depart="74.00">
<route edges="-3.0.00 -4.0.00 -5.0.00 -37.0.00 -38.0.00 -39.0.00 33.0.00 47.0.00 46.0.00"/>
</vehicle>
<vehicle id="75" type="vehicle.diamondback.century" depart="75.00">
<route edges="-11.0.00 3.0.00 2.0.00 1.0.00 0.0.00 15.0.00 -43.0.00 14.0.00"/>
</vehicle>
<vehicle id="76" type="vehicle.carlamotors.carlacola" depart="76.00">
<route edges="19.0.00 18.0.00 9.0.00 8.0.00 7.0.00"/>
</vehicle>
<vehicle id="77" type="vehicle.citroen.c3" depart="77.00">
<route edges="48.0.00 47.0.00 44.0.00 39.0.00 31.0.00 -47.0.00 34.0.00 -39.0.00 -40.0.00 -41.0.00"/>
</vehicle>
<vehicle id="78" type="vehicle.mini.cooper_s" depart="78.00">
<route edges="-36.0.00 5.0.00"/>
</vehicle>
<vehicle id="79" type="vehicle.ford.mustang" depart="79.00">
<route edges="-15.0.00 -16.0.00 -17.0.00 9.0.00"/>
</vehicle>
<vehicle id="80" type="vehicle.carlamotors.carlacola" depart="80.00">
<route edges="37.0.00 36.0.00 35.0.00 42.0.00 49.0.00 48.0.00 47.0.00 44.0.00 39.0.00 31.0.00 -47.0.00 -48.0.00 -7.0.00 51.0.00 -0.0.00 30.0.00"/>
</vehicle>
<vehicle id="81" type="vehicle.audi.etron" depart="81.00">
<route edges="34.0.00 -39.0.00 33.0.00 47.0.00 44.0.00 39.0.00 31.0.00 -47.0.00 -48.0.00 -7.0.00 -8.0.00 -9.0.00 -18.0.00 -19.0.00"/>
</vehicle>
<vehicle id="82" type="vehicle.toyota.prius" depart="82.00">
<route edges="14.0.00 13.0.00 21.0.00 2.0.00 1.0.00 0.0.00 -51.0.00 -8.0.00"/>
</vehicle>
<vehicle id="83" type="vehicle.volkswagen.t2" depart="83.00">
<route edges="-18.0.00 -28.0.00 -29.0.00 -30.0.00 0.0.00 -16.0.00"/>
</vehicle>
<vehicle id="84" type="vehicle.nissan.micra" depart="84.00">
<route edges="-38.0.00 -39.0.00 33.0.00 47.0.00 44.0.00 39.0.00 31.0.00 -47.0.00 -48.0.00 -7.0.00 -8.0.00 -9.0.00 17.0.00"/>
</vehicle>
<vehicle id="85" type="vehicle.gazelle.omafiets" depart="85.00">
<route edges="-18.0.00 -28.0.00 10.0.00"/>
</vehicle>
<vehicle id="86" type="vehicle.diamondback.century" depart="86.00">
<route edges="-16.0.00 -17.0.00 -10.0.00 -29.0.00 -27.0.00"/>
</vehicle>
<vehicle id="87" type="vehicle.jeep.wrangler_rubicon" depart="87.00">
<route edges="36.0.00 35.0.00 42.0.00 49.0.00 48.0.00 47.0.00 44.0.00 39.0.00 31.0.00 -47.0.00 -48.0.00 -7.0.00 -8.0.00 52.0.00 27.0.00 26.0.00 25.0.00"/>
</vehicle>
<vehicle id="88" type="vehicle.chevrolet.impala" depart="88.00">
<route edges="-49.0.00 -50.0.00 -15.0.00 -0.0.00 30.0.00 29.0.00"/>
</vehicle>
<vehicle id="89" type="vehicle.chevrolet.impala" depart="89.00">
<route edges="-38.0.00 -39.0.00 33.0.00 47.0.00 44.0.00 39.0.00 31.0.00 -47.0.00 -48.0.00"/>
</vehicle>
<vehicle id="90" type="vehicle.yamaha.yzf" depart="90.00">
<route edges="39.0.00 31.0.00 -47.0.00 -48.0.00 -7.0.00 -8.0.00 -9.0.00 -10.0.00 -11.0.00 -4.0.00 19.0.00"/>
</vehicle>
<vehicle id="91" type="vehicle.mercedes.coupe" depart="91.00">
<route edges="51.0.00 -16.0.00 27.0.00"/>
</vehicle>
<vehicle id="92" type="vehicle.kawasaki.ninja" depart="92.00">
<route edges="-41.0.00 -46.0.00 -47.0.00 -48.0.00 -7.0.00 -8.0.00 52.0.00 27.0.00 26.0.00 -2.0.00 -3.0.00"/>
</vehicle>
<vehicle id="93" type="vehicle.diamondback.century" depart="93.00">
<route edges="-52.0.00 -9.0.00 -18.0.00 -28.0.00 10.0.00"/>
</vehicle>
<vehicle id="94" type="vehicle.bh.crossbike" depart="94.00">
<route edges="-5.0.00 -37.0.00 -38.0.00 -39.0.00 33.0.00 47.0.00 44.0.00 39.0.00 31.0.00 -47.0.00 -48.0.00 -7.0.00 -8.0.00 -9.0.00 17.0.00"/>
</vehicle>
<vehicle id="95" type="vehicle.yamaha.yzf" depart="95.00">
<route edges="-47.0.00 -48.0.00 -7.0.00 -8.0.00 -9.0.00 -18.0.00 -19.0.00 -5.0.00"/>
</vehicle>
<vehicle id="96" type="vehicle.mercedes.coupe" depart="96.00">
<route edges="3.0.00 2.0.00 -26.0.00 -27.0.00 16.0.00 -0.0.00"/>
</vehicle>
<vehicle id="97" type="vehicle.nissan.micra" depart="97.00">
<route edges="-29.0.00"/>
</vehicle>
<vehicle id="98" type="vehicle.yamaha.yzf" depart="98.00">
<route edges="-4.0.00 -20.0.00"/>
</vehicle>
<vehicle id="99" type="vehicle.audi.etron" depart="99.00">
<route edges="-41.0.00 -46.0.00 -47.0.00 -48.0.00 -7.0.00 -8.0.00 52.0.00 27.0.00 26.0.00 -2.0.00"/>
</vehicle>
<vehicle id="100" type="vehicle.bmw.grandtourer" depart="100.00">
<route edges="-28.0.00 -11.0.00 -12.0.00 -13.0.00"/>
</vehicle>
<vehicle id="101" type="vehicle.audi.a2" depart="101.00">
<route edges="-29.0.00 -27.0.00 -17.0.00 -10.0.00"/>
</vehicle>
<vehicle id="102" type="vehicle.harley-davidson.low_rider" depart="102.00">
<route edges="39.0.00 31.0.00 -47.0.00 34.0.00 -39.0.00 33.0.00 47.0.00 46.0.00 45.0.00"/>
</vehicle>
<vehicle id="103" type="vehicle.dodge.charger_police" depart="103.00">
<route edges="-19.0.00 4.0.00 -12.0.00 -13.0.00"/>
</vehicle>
<vehicle id="104" type="vehicle.tesla.model3" depart="104.00">
<route edges="34.0.00 -39.0.00 33.0.00 47.0.00 44.0.00 39.0.00 31.0.00 -47.0.00"/>
</vehicle>
<vehicle id="105" type="vehicle.ford.mustang" depart="105.00">
<route edges="8.0.00 51.0.00 -0.0.00 30.0.00 29.0.00 -11.0.00"/>
</vehicle>
<vehicle id="106" type="vehicle.mercedes.coupe" depart="106.00">
<route edges="-36.0.00 -37.0.00 -38.0.00 -39.0.00 33.0.00 47.0.00 44.0.00 39.0.00 38.0.00 37.0.00 36.0.00 35.0.00"/>
</vehicle>
<vehicle id="107" type="vehicle.tesla.cybertruck" depart="107.00">
<route edges="-28.0.00 10.0.00 17.0.00 27.0.00 29.0.00"/>
</vehicle>
<vehicle id="108" type="vehicle.audi.a2" depart="108.00">
<route edges="-23.0.00 40.0.00 39.0.00 31.0.00 -47.0.00 34.0.00 -39.0.00 33.0.00 47.0.00 44.0.00"/>
</vehicle>
<vehicle id="109" type="vehicle.ford.mustang" depart="109.00">
<route edges="5.0.00 19.0.00 -28.0.00 -29.0.00 -30.0.00 0.0.00 -51.0.00"/>
</vehicle>
<vehicle id="110" type="vehicle.tesla.cybertruck" depart="110.00">
<route edges="4.0.00 11.0.00 10.0.00 17.0.00 16.0.00"/>
</vehicle>
<vehicle id="111" type="vehicle.tesla.model3" depart="111.00">
<route edges="26.0.00 1.0.00 0.0.00"/>
</vehicle>
<vehicle id="112" type="vehicle.diamondback.century" depart="112.00">
<route edges="33.0.00 47.0.00 44.0.00 39.0.00 31.0.00 -47.0.00 34.0.00 -39.0.00 -40.0.00 -41.0.00 -22.0.00"/>
</vehicle>
<vehicle id="113" type="vehicle.dodge.charger_police" depart="113.00">
<route edges="47.0.00 44.0.00 39.0.00 31.0.00 -47.0.00 -48.0.00 -7.0.00 -8.0.00 52.0.00 27.0.00 26.0.00 25.0.00 13.0.00"/>
</vehicle>
<vehicle id="114" type="vehicle.gazelle.omafiets" depart="114.00">
<route edges="-29.0.00 -30.0.00 0.0.00 15.0.00 -43.0.00"/>
</vehicle>
<vehicle id="115" type="vehicle.ford.mustang" depart="115.00">
<route edges="-2.0.00 -3.0.00 11.0.00 -29.0.00 -30.0.00 -1.0.00"/>
</vehicle>
<vehicle id="116" type="vehicle.bh.crossbike" depart="116.00">
<route edges="28.0.00 18.0.00 9.0.00 8.0.00 7.0.00 -49.0.00 -50.0.00"/>
</vehicle>
<vehicle id="117" type="vehicle.toyota.prius" depart="117.00">
<route edges="-52.0.00 -9.0.00 -18.0.00 -19.0.00 -5.0.00 -37.0.00 -38.0.00 -39.0.00 33.0.00 47.0.00 46.0.00 45.0.00"/>
</vehicle>
<vehicle id="118" type="vehicle.bh.crossbike" depart="118.00">
<route edges="3.0.00 2.0.00 -26.0.00 -30.0.00"/>
</vehicle>
<vehicle id="119" type="vehicle.seat.leon" depart="119.00">
<route edges="7.0.00 -49.0.00 -50.0.00 -43.0.00 -36.0.00 -37.0.00 -38.0.00 -39.0.00 33.0.00 47.0.00 44.0.00 39.0.00 38.0.00 37.0.00"/>
</vehicle>
<vehicle id="120" type="vehicle.kawasaki.ninja" depart="120.00">
<route edges="-47.0.00 34.0.00 -39.0.00 -40.0.00 -41.0.00 -46.0.00"/>
</vehicle>
<vehicle id="121" type="vehicle.mercedes.coupe" depart="121.00">
<route edges="-11.0.00 -12.0.00 -13.0.00 -14.0.00 -36.0.00 -37.0.00 -38.0.00 -39.0.00 33.0.00 47.0.00 44.0.00 39.0.00 38.0.00 37.0.00 36.0.00 35.0.00"/>
</vehicle>
<vehicle id="122" type="vehicle.tesla.model3" depart="122.00">
<route edges="-3.0.00 -4.0.00 -5.0.00 -37.0.00 -38.0.00 -39.0.00 33.0.00 47.0.00"/>
</vehicle>
<vehicle id="123" type="vehicle.ford.mustang" depart="123.00">
<route edges="5.0.00 19.0.00 18.0.00 17.0.00 -52.0.00 -9.0.00"/>
</vehicle>
<vehicle id="124" type="vehicle.bh.crossbike" depart="124.00">
<route edges="5.0.00 19.0.00 18.0.00 17.0.00 -52.0.00 -9.0.00"/>
</vehicle>
<vehicle id="125" type="vehicle.seat.leon" depart="125.00">
<route edges="-14.0.00 -36.0.00 5.0.00 19.0.00 18.0.00 17.0.00 -52.0.00"/>
</vehicle>
<vehicle id="126" type="vehicle.nissan.patrol" depart="126.00">
<route edges="37.0.00 36.0.00 35.0.00 42.0.00 49.0.00 48.0.00 47.0.00 44.0.00 39.0.00 31.0.00 -47.0.00 34.0.00 -39.0.00 -40.0.00"/>
</vehicle>
<vehicle id="127" type="vehicle.bh.crossbike" depart="127.00">
<route edges="-25.0.00 -2.0.00 -3.0.00"/>
</vehicle>
<vehicle id="128" type="vehicle.dodge.charger_police" depart="128.00">
<route edges="27.0.00 26.0.00 -2.0.00 -3.0.00 -4.0.00 -5.0.00 -37.0.00 -38.0.00 -39.0.00 33.0.00 47.0.00 44.0.00 39.0.00 38.0.00 37.0.00 36.0.00 35.0.00"/>
</vehicle>
<vehicle id="129" type="vehicle.yamaha.yzf" depart="129.00">
<route edges="9.0.00 52.0.00 27.0.00 29.0.00"/>
</vehicle>
<vehicle id="130" type="vehicle.nissan.patrol" depart="130.00">
<route edges="-12.0.00 -13.0.00 -14.0.00 -36.0.00 -37.0.00 -38.0.00 -39.0.00 33.0.00 47.0.00 44.0.00 39.0.00 38.0.00 37.0.00 36.0.00 35.0.00 42.0.00"/>
</vehicle>
<vehicle id="131" type="vehicle.mini.cooper_s" depart="131.00">
<route edges="-26.0.00 -30.0.00 0.0.00 -51.0.00"/>
</vehicle>
<vehicle id="132" type="vehicle.diamondback.century" depart="132.00">
<route edges="4.0.00 -12.0.00 -13.0.00 -14.0.00 -36.0.00 5.0.00"/>
</vehicle>
<vehicle id="133" type="vehicle.mercedes.coupe" depart="133.00">
<route edges="-9.0.00 17.0.00 16.0.00"/>
</vehicle>
<vehicle id="134" type="vehicle.diamondback.century" depart="134.00">
<route edges="46.0.00 45.0.00 40.0.00 39.0.00 31.0.00 -47.0.00 -48.0.00 -7.0.00 -8.0.00 52.0.00 -17.0.00 9.0.00 8.0.00"/>
</vehicle>
<vehicle id="135" type="vehicle.kawasaki.ninja" depart="135.00">
<route edges="10.0.00 -18.0.00 -19.0.00 -5.0.00 -37.0.00 -38.0.00 -39.0.00 33.0.00 47.0.00 44.0.00 39.0.00 38.0.00"/>
</vehicle>
<vehicle id="136" type="vehicle.citroen.c3" depart="136.00">
<route edges="15.0.00 -43.0.00 14.0.00 13.0.00"/>
</vehicle>
<vehicle id="137" type="vehicle.mini.cooper_s" depart="137.00">
<route edges="-14.0.00 -36.0.00 -37.0.00 -38.0.00 -39.0.00 33.0.00"/>
</vehicle>
<vehicle id="138" type="vehicle.carlamotors.carlacola" depart="138.00">
<route edges="27.0.00 29.0.00 28.0.00 -19.0.00 4.0.00"/>
</vehicle>
<vehicle id="139" type="vehicle.chevrolet.impala" depart="139.00">
<route edges="-41.0.00 -46.0.00 -47.0.00 -48.0.00 -7.0.00 -8.0.00 -9.0.00 -18.0.00 -28.0.00"/>
</vehicle>
<vehicle id="140" type="vehicle.citroen.c3" depart="140.00">
<route edges="14.0.00 24.0.00 4.0.00 -12.0.00 -13.0.00"/>
</vehicle>
<vehicle id="141" type="vehicle.bmw.grandtourer" depart="141.00">
<route edges="-19.0.00 4.0.00 11.0.00 10.0.00 17.0.00 16.0.00 -0.0.00"/>
</vehicle>
<vehicle id="142" type="vehicle.dodge.charger_police" depart="142.00">
<route edges="25.0.00 13.0.00 21.0.00 2.0.00 1.0.00 0.0.00 15.0.00 -43.0.00"/>
</vehicle>
<vehicle id="143" type="vehicle.nissan.patrol" depart="143.00">
<route edges="-8.0.00 -9.0.00 -18.0.00 -19.0.00 -5.0.00 -37.0.00 -38.0.00 -39.0.00 33.0.00 47.0.00 44.0.00 39.0.00 38.0.00 37.0.00"/>
</vehicle>
<vehicle id="144" type="vehicle.audi.a2" depart="144.00">
<route edges="-29.0.00 26.0.00 -2.0.00 -3.0.00 -4.0.00 -20.0.00"/>
</vehicle>
<vehicle id="145" type="vehicle.audi.tt" depart="145.00">
<route edges="0.0.00 15.0.00 -43.0.00 -36.0.00 -37.0.00 -38.0.00 -39.0.00 33.0.00 47.0.00 44.0.00 39.0.00 31.0.00"/>
</vehicle>
<vehicle id="146" type="vehicle.lincoln.mkz_2017" depart="146.00">
<route edges="51.0.00 -16.0.00 -17.0.00 -10.0.00"/>
</vehicle>
<vehicle id="147" type="vehicle.bmw.grandtourer" depart="147.00">
<route edges="24.0.00 19.0.00 18.0.00"/>
</vehicle>
<vehicle id="148" type="vehicle.audi.a2" depart="148.00">
<route edges="-1.0.00 -26.0.00 -27.0.00 -52.0.00 8.0.00 7.0.00 -49.0.00 -50.0.00"/>
</vehicle>
<vehicle id="149" type="vehicle.nissan.micra" depart="149.00">
<route edges="46.0.00 45.0.00 40.0.00 39.0.00 31.0.00 -47.0.00 -48.0.00 -7.0.00 -8.0.00 52.0.00 16.0.00 -51.0.00"/>
</vehicle>
<vehicle id="150" type="vehicle.citroen.c3" depart="150.00">
<route edges="-10.0.00 -11.0.00 -12.0.00 -13.0.00 -14.0.00 -36.0.00 -37.0.00 -38.0.00 -39.0.00 33.0.00 47.0.00 44.0.00 39.0.00 38.0.00 37.0.00 36.0.00 35.0.00 42.0.00 -23.0.00"/>
</vehicle>
<vehicle id="151" type="vehicle.lincoln.mkz_2017" depart="151.00">
<route edges="-37.0.00 -38.0.00 -39.0.00 33.0.00 47.0.00 44.0.00 39.0.00 31.0.00 -47.0.00 -48.0.00 -49.0.00 -50.0.00 -43.0.00"/>
</vehicle>
<vehicle id="152" type="vehicle.bh.crossbike" depart="152.00">
<route edges="31.0.00 -47.0.00 -48.0.00 -7.0.00 -8.0.00 -9.0.00 -18.0.00 -19.0.00 -5.0.00 -37.0.00"/>
</vehicle>
<vehicle id="153" type="vehicle.volkswagen.t2" depart="153.00">
<route edges="-5.0.00 -37.0.00 -38.0.00 -39.0.00 33.0.00 47.0.00 44.0.00 39.0.00 31.0.00 -47.0.00 -48.0.00 -49.0.00"/>
</vehicle>
<vehicle id="154" type="vehicle.harley-davidson.low_rider" depart="154.00">
<route edges="-7.0.00 -8.0.00 52.0.00 27.0.00 26.0.00 -2.0.00"/>
</vehicle>
<vehicle id="155" type="vehicle.harley-davidson.low_rider" depart="155.00">
<route edges="-18.0.00 -19.0.00 4.0.00 -12.0.00 -13.0.00"/>
</vehicle>
<vehicle id="156" type="vehicle.micro.microlino" depart="156.00">
<route edges="34.0.00 -39.0.00 33.0.00 47.0.00 44.0.00 39.0.00 31.0.00 -47.0.00"/>
</vehicle>
<vehicle id="157" type="vehicle.audi.tt" depart="157.00">
<route edges="-0.0.00 30.0.00 -27.0.00 -17.0.00"/>
</vehicle>
<vehicle id="158" type="vehicle.bmw.grandtourer" depart="158.00">
<route edges="19.0.00 -28.0.00 -11.0.00 -12.0.00 -13.0.00 -14.0.00 -36.0.00 -37.0.00 -38.0.00 -39.0.00 33.0.00"/>
</vehicle>
<vehicle id="159" type="vehicle.seat.leon" depart="159.00">
<route edges="2.0.00 1.0.00 0.0.00"/>
</vehicle>
<vehicle id="160" type="vehicle.lincoln.mkz_2017" depart="160.00">
<route edges="-40.0.00 -41.0.00 -46.0.00 -47.0.00 -48.0.00 -7.0.00 -8.0.00 -9.0.00 -10.0.00 -11.0.00"/>
</vehicle>
<vehicle id="161" type="vehicle.citroen.c3" depart="161.00">
<route edges="-0.0.00 30.0.00 29.0.00 10.0.00 -18.0.00"/>
</vehicle>
<vehicle id="162" type="vehicle.citroen.c3" depart="162.00">
<route edges="-40.0.00 -41.0.00 -22.0.00 37.0.00"/>
</vehicle>
<vehicle id="163" type="vehicle.mini.cooper_s" depart="163.00">
<route edges="12.0.00 -4.0.00 -5.0.00 -37.0.00 -38.0.00 -39.0.00 -40.0.00 -41.0.00"/>
</vehicle>
<vehicle id="164" type="vehicle.volkswagen.t2" depart="164.00">
<route edges="45.0.00 40.0.00 39.0.00 31.0.00 -47.0.00 34.0.00 -39.0.00 -40.0.00 -41.0.00 -46.0.00"/>
</vehicle>
<vehicle id="165" type="vehicle.jeep.wrangler_rubicon" depart="165.00">
<route edges="31.0.00 -47.0.00 -48.0.00 -7.0.00 -8.0.00 -9.0.00 -18.0.00 -19.0.00 -5.0.00"/>
</vehicle>
<vehicle id="166" type="vehicle.citroen.c3" depart="166.00">
<route edges="3.0.00 2.0.00 25.0.00 -14.0.00 -36.0.00 -37.0.00 -38.0.00 -39.0.00 -40.0.00 -41.0.00"/>
</vehicle>
<vehicle id="167" type="vehicle.nissan.micra" depart="167.00">
<route edges="35.0.00 42.0.00 49.0.00 48.0.00 47.0.00 44.0.00 39.0.00 31.0.00 -47.0.00 -48.0.00 -7.0.00 -8.0.00 -9.0.00 -10.0.00 -11.0.00 -12.0.00 -13.0.00 -14.0.00"/>
</vehicle>
<vehicle id="168" type="vehicle.mercedes.coupe" depart="168.00">
<route edges="-18.0.00 -28.0.00 -29.0.00 -27.0.00 16.0.00"/>
</vehicle>
<vehicle id="169" type="vehicle.tesla.cybertruck" depart="169.00">
<route edges="16.0.00 -0.0.00 30.0.00 29.0.00 10.0.00 -18.0.00"/>
</vehicle>
<vehicle id="170" type="vehicle.audi.tt" depart="170.00">
<route edges="-4.0.00 19.0.00 -28.0.00 -29.0.00 -27.0.00 -17.0.00"/>
</vehicle>
<vehicle id="171" type="vehicle.audi.tt" depart="171.00">
<route edges="48.0.00 47.0.00 44.0.00 39.0.00 31.0.00 -47.0.00 -48.0.00 -7.0.00 51.0.00 -16.0.00"/>
</vehicle>
<vehicle id="172" type="vehicle.chevrolet.impala" depart="172.00">
<route edges="48.0.00 47.0.00 44.0.00 39.0.00 31.0.00 -47.0.00 -48.0.00 -7.0.00 -8.0.00 -9.0.00 17.0.00 -52.0.00"/>
</vehicle>
<vehicle id="173" type="vehicle.chevrolet.impala" depart="173.00">
<route edges="16.0.00 -0.0.00 -1.0.00 -2.0.00"/>
</vehicle>
<vehicle id="174" type="vehicle.nissan.micra" depart="174.00">
<route edges="-41.0.00 -46.0.00 -47.0.00 -48.0.00 -7.0.00 -8.0.00 52.0.00 27.0.00 26.0.00 25.0.00 13.0.00 12.0.00"/>
</vehicle>
<vehicle id="175" type="vehicle.audi.tt" depart="175.00">
<route edges="-30.0.00 -1.0.00 -26.0.00 29.0.00 10.0.00"/>
</vehicle>
<vehicle id="176" type="vehicle.ford.mustang" depart="176.00">
<route edges="33.0.00 47.0.00 44.0.00 39.0.00 31.0.00 -47.0.00 -48.0.00 -7.0.00"/>
</vehicle>
<vehicle id="177" type="vehicle.chevrolet.impala" depart="177.00">
<route edges="-16.0.00 -52.0.00 8.0.00"/>
</vehicle>
<vehicle id="178" type="vehicle.mercedes.coupe" depart="178.00">
<route edges="-2.0.00 -3.0.00 -4.0.00 -20.0.00"/>
</vehicle>
<vehicle id="179" type="vehicle.tesla.model3" depart="179.00">
<route edges="33.0.00 47.0.00 44.0.00 39.0.00 31.0.00 -47.0.00 -48.0.00 -7.0.00 -8.0.00 -9.0.00 -10.0.00 -29.0.00"/>
</vehicle>
<vehicle id="180" type="vehicle.ford.mustang" depart="180.00">
<route edges="-25.0.00 1.0.00 30.0.00"/>
</vehicle>
<vehicle id="181" type="vehicle.citroen.c3" depart="181.00">
<route edges="-36.0.00 5.0.00 19.0.00 -28.0.00 -29.0.00 -30.0.00"/>
</vehicle>
<vehicle id="182" type="vehicle.dodge.charger_police" depart="182.00">
<route edges="-52.0.00 -9.0.00 -18.0.00 -19.0.00 -20.0.00"/>
</vehicle>
<vehicle id="183" type="vehicle.harley-davidson.low_rider" depart="183.00">
<route edges="-23.0.00 -41.0.00 -46.0.00"/>
</vehicle>
<vehicle id="184" type="vehicle.harley-davidson.low_rider" depart="184.00">
<route edges="36.0.00 35.0.00 42.0.00 49.0.00 48.0.00 47.0.00 44.0.00 39.0.00 31.0.00 -47.0.00 -48.0.00 -7.0.00 -8.0.00 52.0.00 -17.0.00"/>
</vehicle>
<vehicle id="185" type="vehicle.harley-davidson.low_rider" depart="185.00">
<route edges="5.0.00 19.0.00 18.0.00 9.0.00 8.0.00 7.0.00 -49.0.00 -50.0.00 -15.0.00"/>
</vehicle>
<vehicle id="186" type="vehicle.chevrolet.impala" depart="186.00">
<route edges="-8.0.00 -9.0.00 -10.0.00 -11.0.00 -12.0.00 -13.0.00 -14.0.00"/>
</vehicle>
<vehicle id="187" type="vehicle.jeep.wrangler_rubicon" depart="187.00">
<route edges="-9.0.00 -10.0.00 28.0.00 18.0.00"/>
</vehicle>
<vehicle id="188" type="vehicle.audi.etron" depart="188.00">
<route edges="36.0.00 35.0.00 42.0.00 49.0.00 48.0.00 47.0.00 44.0.00 39.0.00 31.0.00 -47.0.00 -48.0.00 -7.0.00 -8.0.00 -9.0.00 -10.0.00 -11.0.00 3.0.00 2.0.00"/>
</vehicle>
<vehicle id="189" type="vehicle.toyota.prius" depart="189.00">
<route edges="-0.0.00 30.0.00 29.0.00 10.0.00 9.0.00"/>
</vehicle>
<vehicle id="190" type="vehicle.chevrolet.impala" depart="190.00">
<route edges="29.0.00 28.0.00 -19.0.00 -5.0.00 -37.0.00 -38.0.00 -39.0.00 33.0.00 47.0.00 46.0.00 45.0.00 40.0.00"/>
</vehicle>
<vehicle id="191" type="vehicle.lincoln.mkz_2017" depart="191.00">
<route edges="17.0.00 27.0.00 26.0.00 -2.0.00 -3.0.00 -4.0.00 -20.0.00"/>
</vehicle>
<vehicle id="192" type="vehicle.harley-davidson.low_rider" depart="192.00">
<route edges="-1.0.00 -2.0.00 -3.0.00 -4.0.00 -5.0.00 -37.0.00 -38.0.00 -39.0.00 33.0.00 47.0.00 46.0.00 45.0.00 40.0.00"/>
</vehicle>
<vehicle id="193" type="vehicle.audi.etron" depart="193.00">
<route edges="26.0.00 1.0.00 0.0.00 -16.0.00"/>
</vehicle>
<vehicle id="194" type="vehicle.jeep.wrangler_rubicon" depart="194.00">
<route edges="3.0.00 2.0.00 25.0.00 -14.0.00 -36.0.00 -37.0.00 -38.0.00 -39.0.00 33.0.00 47.0.00 44.0.00 39.0.00 38.0.00 37.0.00 36.0.00 35.0.00"/>
</vehicle>
<vehicle id="195" type="vehicle.micro.microlino" depart="195.00">
<route edges="-50.0.00 -43.0.00 14.0.00 24.0.00"/>
</vehicle>
<vehicle id="196" type="vehicle.mercedes.coupe" depart="196.00">
<route edges="52.0.00 27.0.00 26.0.00 -2.0.00 -3.0.00 -4.0.00 -5.0.00 -37.0.00 -38.0.00 -39.0.00 33.0.00 47.0.00 44.0.00 39.0.00 38.0.00 37.0.00"/>
</vehicle>
<vehicle id="197" type="vehicle.dodge.charger_police" depart="197.00">
<route edges="-28.0.00 -11.0.00 3.0.00"/>
</vehicle>
<vehicle id="198" type="vehicle.gazelle.omafiets" depart="198.00">
<route edges="-27.0.00 -17.0.00 -10.0.00 -11.0.00 -12.0.00 -13.0.00 -25.0.00"/>
</vehicle>
<vehicle id="199" type="vehicle.chevrolet.impala" depart="199.00">
<route edges="18.0.00 17.0.00 16.0.00"/>
</vehicle>
</routes>

View File

@ -1,603 +0,0 @@
<?xml version='1.0' encoding='UTF-8'?>
<routes xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="http://sumo.dlr.de/xsd/routes_file.xsd">
<vehicle id="0" type="vehicle.bh.crossbike" depart="0.00">
<route edges="43.0.00 23.0.00 -52.0.00 49.0.00 7.0.00 6.0.00"/>
</vehicle>
<vehicle id="1" type="vehicle.micro.microlino" depart="1.00">
<route edges="33.0.00 -39.0.00 25.0.00 -6.0.00"/>
</vehicle>
<vehicle id="2" type="vehicle.carlamotors.carlacola" depart="2.00">
<route edges="-8.0.00 -45.0.00 -46.0.00 6.0.00 15.0.00 13.0.00 35.0.00 -27.0.00 20.0.00"/>
</vehicle>
<vehicle id="3" type="vehicle.diamondback.century" depart="3.00">
<route edges="2.0.00 -50.0.00 -23.0.00 -24.0.00 11.0.00 10.0.00 9.0.00"/>
</vehicle>
<vehicle id="4" type="vehicle.gazelle.omafiets" depart="4.00">
<route edges="-14.0.00 33.0.00 -48.0.00"/>
</vehicle>
<vehicle id="5" type="vehicle.seat.leon" depart="5.00">
<route edges="-8.0.00 44.0.00 2.0.00 -50.0.00 -23.0.00"/>
</vehicle>
<vehicle id="6" type="vehicle.harley-davidson.low_rider" depart="6.00">
<route edges="40.0.00 -1.0.00 -2.0.00 43.0.00 -24.0.00 11.0.00"/>
</vehicle>
<vehicle id="7" type="vehicle.tesla.cybertruck" depart="7.00">
<route edges="-39.0.00 -0.0.00 -18.0.00 -41.0.00"/>
</vehicle>
<vehicle id="8" type="vehicle.volkswagen.t2" depart="8.00">
<route edges="46.0.00 -4.0.00 -8.0.00"/>
</vehicle>
<vehicle id="9" type="vehicle.bh.crossbike" depart="9.00">
<route edges="3.0.00 2.0.00 1.0.00 -18.0.00 -41.0.00"/>
</vehicle>
<vehicle id="10" type="vehicle.lincoln.mkz_2017" depart="10.00">
<route edges="-48.0.00 -20.0.00 -28.0.00 -29.0.00 -0.0.00 -1.0.00 49.0.00 7.0.00"/>
</vehicle>
<vehicle id="11" type="vehicle.chevrolet.impala" depart="11.00">
<route edges="31.0.00 28.0.00 27.0.00 37.0.00"/>
</vehicle>
<vehicle id="12" type="vehicle.dodge.charger_police" depart="12.00">
<route edges="-39.0.00 -26.0.00 -21.0.00 40.0.00"/>
</vehicle>
<vehicle id="13" type="vehicle.toyota.prius" depart="13.00">
<route edges="20.0.00 48.0.00 -39.0.00 -0.0.00 -1.0.00 49.0.00 4.0.00"/>
</vehicle>
<vehicle id="14" type="vehicle.gazelle.omafiets" depart="14.00">
<route edges="-45.0.00 -46.0.00 6.0.00"/>
</vehicle>
<vehicle id="15" type="vehicle.gazelle.omafiets" depart="15.00">
<route edges="10.0.00 9.0.00 8.0.00 7.0.00 46.0.00"/>
</vehicle>
<vehicle id="16" type="vehicle.toyota.prius" depart="16.00">
<route edges="-26.0.00 -21.0.00 40.0.00 -1.0.00 49.0.00 4.0.00"/>
</vehicle>
<vehicle id="17" type="vehicle.micro.microlino" depart="17.00">
<route edges="-51.0.00 -52.0.00"/>
</vehicle>
<vehicle id="18" type="vehicle.mini.cooper_s" depart="18.00">
<route edges="-52.0.00 49.0.00 7.0.00 6.0.00 15.0.00 13.0.00 35.0.00 -27.0.00 20.0.00"/>
</vehicle>
<vehicle id="19" type="vehicle.bmw.grandtourer" depart="19.00">
<route edges="37.0.00 -13.0.00 -14.0.00 -6.0.00 -7.0.00 -8.0.00 -9.0.00 -10.0.00 -11.0.00"/>
</vehicle>
<vehicle id="20" type="vehicle.mini.cooper_s" depart="20.00">
<route edges="44.0.00 2.0.00"/>
</vehicle>
<vehicle id="21" type="vehicle.tesla.model3" depart="21.00">
<route edges="-23.0.00 -43.0.00 -44.0.00 -45.0.00 -46.0.00"/>
</vehicle>
<vehicle id="22" type="vehicle.seat.leon" depart="22.00">
<route edges="-38.0.00 -13.0.00 -14.0.00"/>
</vehicle>
<vehicle id="23" type="vehicle.volkswagen.t2" depart="23.00">
<route edges="40.0.00 0.0.00 25.0.00 15.0.00 13.0.00"/>
</vehicle>
<vehicle id="24" type="vehicle.lincoln.mkz_2017" depart="24.00">
<route edges="11.0.00 10.0.00"/>
</vehicle>
<vehicle id="25" type="vehicle.citroen.c3" depart="25.00">
<route edges="-3.0.00 -11.0.00 24.0.00 23.0.00 22.0.00 21.0.00 28.0.00"/>
</vehicle>
<vehicle id="26" type="vehicle.mini.cooper_s" depart="26.00">
<route edges="-48.0.00 19.0.00 13.0.00"/>
</vehicle>
<vehicle id="27" type="vehicle.jeep.wrangler_rubicon" depart="27.00">
<route edges="-0.0.00"/>
</vehicle>
<vehicle id="28" type="vehicle.citroen.c3" depart="28.00">
<route edges="-27.0.00 -28.0.00 -30.0.00 -32.0.00 -16.0.00"/>
</vehicle>
<vehicle id="29" type="vehicle.tesla.cybertruck" depart="29.00">
<route edges="-29.0.00 -0.0.00 -18.0.00 -22.0.00"/>
</vehicle>
<vehicle id="30" type="vehicle.carlamotors.carlacola" depart="30.00">
<route edges="0.0.00 25.0.00 -6.0.00 -7.0.00 4.0.00"/>
</vehicle>
<vehicle id="31" type="vehicle.mercedes.coupe" depart="31.00">
<route edges="37.0.00 -13.0.00 -14.0.00 33.0.00 -39.0.00 25.0.00 15.0.00"/>
</vehicle>
<vehicle id="32" type="vehicle.seat.leon" depart="32.00">
<route edges="15.0.00 -19.0.00 48.0.00 -32.0.00 -6.0.00 -7.0.00 -8.0.00 44.0.00 2.0.00"/>
</vehicle>
<vehicle id="33" type="vehicle.lincoln.mkz_2017" depart="33.00">
<route edges="37.0.00 -13.0.00 -14.0.00 -16.0.00 -0.0.00 -1.0.00"/>
</vehicle>
<vehicle id="34" type="vehicle.tesla.cybertruck" depart="34.00">
<route edges="37.0.00 -13.0.00 -14.0.00 -16.0.00 -0.0.00 17.0.00"/>
</vehicle>
<vehicle id="35" type="vehicle.nissan.micra" depart="35.00">
<route edges="-36.0.00 -27.0.00 -28.0.00 -29.0.00 39.0.00 31.0.00 28.0.00 27.0.00 37.0.00"/>
</vehicle>
<vehicle id="36" type="vehicle.carlamotors.carlacola" depart="36.00">
<route edges="39.0.00 -32.0.00 -6.0.00 -7.0.00 -8.0.00"/>
</vehicle>
<vehicle id="37" type="vehicle.nissan.micra" depart="37.00">
<route edges="-36.0.00 -27.0.00 -28.0.00 -29.0.00 -0.0.00 -1.0.00 -2.0.00 -3.0.00 10.0.00"/>
</vehicle>
<vehicle id="38" type="vehicle.tesla.cybertruck" depart="38.00">
<route edges="44.0.00 2.0.00 49.0.00 -8.0.00"/>
</vehicle>
<vehicle id="39" type="vehicle.dodge.charger_police" depart="39.00">
<route edges="-44.0.00 8.0.00 7.0.00 6.0.00 15.0.00 13.0.00 35.0.00 -27.0.00 20.0.00"/>
</vehicle>
<vehicle id="40" type="vehicle.nissan.micra" depart="40.00">
<route edges="-16.0.00 39.0.00 -32.0.00"/>
</vehicle>
<vehicle id="41" type="vehicle.bmw.grandtourer" depart="41.00">
<route edges="44.0.00"/>
</vehicle>
<vehicle id="42" type="vehicle.audi.etron" depart="42.00">
<route edges="-18.0.00 21.0.00 -29.0.00 39.0.00"/>
</vehicle>
<vehicle id="43" type="vehicle.jeep.wrangler_rubicon" depart="43.00">
<route edges="33.0.00 -39.0.00 -26.0.00 -30.0.00"/>
</vehicle>
<vehicle id="44" type="vehicle.mini.cooper_s" depart="44.00">
<route edges="2.0.00 1.0.00 0.0.00 39.0.00"/>
</vehicle>
<vehicle id="45" type="vehicle.audi.a2" depart="45.00">
<route edges="20.0.00 48.0.00 31.0.00 -21.0.00 -41.0.00"/>
</vehicle>
<vehicle id="46" type="vehicle.mini.cooper_s" depart="46.00">
<route edges="-14.0.00 -16.0.00 -26.0.00 -21.0.00 -22.0.00"/>
</vehicle>
<vehicle id="47" type="vehicle.nissan.patrol" depart="47.00">
<route edges="-26.0.00 -21.0.00 40.0.00 17.0.00 -7.0.00 -8.0.00"/>
</vehicle>
<vehicle id="48" type="vehicle.mercedes.coupe" depart="48.00">
<route edges="-41.0.00 -51.0.00 22.0.00 21.0.00 28.0.00 27.0.00 37.0.00"/>
</vehicle>
<vehicle id="49" type="vehicle.bh.crossbike" depart="49.00">
<route edges="-2.0.00 -44.0.00 8.0.00 7.0.00 6.0.00 15.0.00 -19.0.00 48.0.00"/>
</vehicle>
<vehicle id="50" type="vehicle.audi.a2" depart="50.00">
<route edges="-19.0.00 48.0.00 -32.0.00 -6.0.00 -7.0.00 -8.0.00 -9.0.00 -10.0.00"/>
</vehicle>
<vehicle id="51" type="vehicle.dodge.charger_police" depart="51.00">
<route edges="37.0.00 -13.0.00 -14.0.00 -6.0.00 -7.0.00 -8.0.00 44.0.00"/>
</vehicle>
<vehicle id="52" type="vehicle.nissan.patrol" depart="52.00">
<route edges="13.0.00 35.0.00 -27.0.00 -28.0.00 -29.0.00 -0.0.00 -1.0.00 -2.0.00 43.0.00"/>
</vehicle>
<vehicle id="53" type="vehicle.nissan.micra" depart="53.00">
<route edges="-39.0.00 25.0.00 -6.0.00"/>
</vehicle>
<vehicle id="54" type="vehicle.audi.etron" depart="54.00">
<route edges="-14.0.00 33.0.00 -48.0.00 -20.0.00 -28.0.00"/>
</vehicle>
<vehicle id="55" type="vehicle.nissan.patrol" depart="55.00">
<route edges="7.0.00 -47.0.00 -1.0.00 -2.0.00 -3.0.00 10.0.00 9.0.00"/>
</vehicle>
<vehicle id="56" type="vehicle.volkswagen.t2" depart="56.00">
<route edges="19.0.00 13.0.00 35.0.00 -27.0.00 -28.0.00 -29.0.00 39.0.00 31.0.00 28.0.00 27.0.00"/>
</vehicle>
<vehicle id="57" type="vehicle.toyota.prius" depart="57.00">
<route edges="42.0.00 -51.0.00 -52.0.00 -2.0.00 -3.0.00 10.0.00"/>
</vehicle>
<vehicle id="58" type="vehicle.bh.crossbike" depart="58.00">
<route edges="2.0.00 1.0.00 0.0.00 -26.0.00 28.0.00"/>
</vehicle>
<vehicle id="59" type="vehicle.diamondback.century" depart="59.00">
<route edges="-2.0.00 -44.0.00 8.0.00 4.0.00"/>
</vehicle>
<vehicle id="60" type="vehicle.ford.mustang" depart="60.00">
<route edges="46.0.00 -4.0.00 -5.0.00 1.0.00 0.0.00 39.0.00 -48.0.00 19.0.00"/>
</vehicle>
<vehicle id="61" type="vehicle.seat.leon" depart="61.00">
<route edges="-52.0.00 49.0.00 7.0.00 -47.0.00 -1.0.00"/>
</vehicle>
<vehicle id="62" type="vehicle.chevrolet.impala" depart="62.00">
<route edges="-7.0.00 -5.0.00 1.0.00 0.0.00 -26.0.00 28.0.00 27.0.00 -38.0.00"/>
</vehicle>
<vehicle id="63" type="vehicle.seat.leon" depart="63.00">
<route edges="-2.0.00 43.0.00 23.0.00 22.0.00 21.0.00 28.0.00"/>
</vehicle>
<vehicle id="64" type="vehicle.audi.tt" depart="64.00">
<route edges="-36.0.00 -27.0.00 -28.0.00 -21.0.00 -22.0.00 -23.0.00 42.0.00"/>
</vehicle>
<vehicle id="65" type="vehicle.nissan.patrol" depart="65.00">
<route edges="-41.0.00 -42.0.00 -43.0.00 -3.0.00"/>
</vehicle>
<vehicle id="66" type="vehicle.nissan.patrol" depart="66.00">
<route edges="-4.0.00 -5.0.00 1.0.00 0.0.00 -26.0.00 28.0.00 27.0.00 37.0.00"/>
</vehicle>
<vehicle id="67" type="vehicle.tesla.cybertruck" depart="67.00">
<route edges="28.0.00 27.0.00 -38.0.00 -13.0.00 -14.0.00 -16.0.00 -0.0.00 -1.0.00 -2.0.00 43.0.00 42.0.00"/>
</vehicle>
<vehicle id="68" type="vehicle.audi.a2" depart="68.00">
<route edges="51.0.00 -42.0.00 23.0.00 -52.0.00"/>
</vehicle>
<vehicle id="69" type="vehicle.yamaha.yzf" depart="69.00">
<route edges="-45.0.00 -46.0.00 6.0.00 15.0.00 13.0.00 35.0.00"/>
</vehicle>
<vehicle id="70" type="vehicle.gazelle.omafiets" depart="70.00">
<route edges="-20.0.00 -28.0.00 -29.0.00 39.0.00 31.0.00 28.0.00"/>
</vehicle>
<vehicle id="71" type="vehicle.citroen.c3" depart="71.00">
<route edges="35.0.00 -27.0.00 -28.0.00 -29.0.00 -0.0.00 -1.0.00 -2.0.00 43.0.00"/>
</vehicle>
<vehicle id="72" type="vehicle.nissan.micra" depart="72.00">
<route edges="-42.0.00 -43.0.00 -3.0.00 -11.0.00 24.0.00"/>
</vehicle>
<vehicle id="73" type="vehicle.nissan.micra" depart="73.00">
<route edges="23.0.00 22.0.00 21.0.00 28.0.00 27.0.00 -38.0.00"/>
</vehicle>
<vehicle id="74" type="vehicle.bmw.grandtourer" depart="74.00">
<route edges="-48.0.00 -20.0.00 -28.0.00 -30.0.00"/>
</vehicle>
<vehicle id="75" type="vehicle.toyota.prius" depart="75.00">
<route edges="-13.0.00 -14.0.00 33.0.00 -39.0.00 25.0.00"/>
</vehicle>
<vehicle id="76" type="vehicle.jeep.wrangler_rubicon" depart="76.00">
<route edges="15.0.00 -19.0.00 48.0.00 31.0.00 -21.0.00 -41.0.00 -51.0.00"/>
</vehicle>
<vehicle id="77" type="vehicle.volkswagen.t2" depart="77.00">
<route edges="-43.0.00 2.0.00 -50.0.00 -23.0.00 42.0.00"/>
</vehicle>
<vehicle id="78" type="vehicle.kawasaki.ninja" depart="78.00">
<route edges="-9.0.00 -10.0.00 3.0.00 43.0.00 -24.0.00 11.0.00 10.0.00"/>
</vehicle>
<vehicle id="79" type="vehicle.mini.cooper_s" depart="79.00">
<route edges="27.0.00 -38.0.00 -13.0.00 -14.0.00 -6.0.00 -7.0.00 4.0.00"/>
</vehicle>
<vehicle id="80" type="vehicle.nissan.micra" depart="80.00">
<route edges="49.0.00 7.0.00 46.0.00"/>
</vehicle>
<vehicle id="81" type="vehicle.nissan.micra" depart="81.00">
<route edges="21.0.00 -29.0.00 -0.0.00 17.0.00 46.0.00 45.0.00"/>
</vehicle>
<vehicle id="82" type="vehicle.bmw.grandtourer" depart="82.00">
<route edges="-20.0.00 -28.0.00 -29.0.00 39.0.00 31.0.00"/>
</vehicle>
<vehicle id="83" type="vehicle.mini.cooper_s" depart="83.00">
<route edges="-3.0.00 -11.0.00 24.0.00 23.0.00 22.0.00"/>
</vehicle>
<vehicle id="84" type="vehicle.tesla.model3" depart="84.00">
<route edges="13.0.00 35.0.00 -27.0.00 -28.0.00 -21.0.00 -22.0.00 -23.0.00 42.0.00"/>
</vehicle>
<vehicle id="85" type="vehicle.tesla.model3" depart="85.00">
<route edges="-22.0.00 -52.0.00 49.0.00"/>
</vehicle>
<vehicle id="86" type="vehicle.audi.tt" depart="86.00">
<route edges="40.0.00 -1.0.00 49.0.00 7.0.00 -47.0.00"/>
</vehicle>
<vehicle id="87" type="vehicle.nissan.micra" depart="87.00">
<route edges="-45.0.00 -4.0.00 -8.0.00 -9.0.00"/>
</vehicle>
<vehicle id="88" type="vehicle.audi.a2" depart="88.00">
<route edges="51.0.00 -42.0.00 -43.0.00 2.0.00 1.0.00"/>
</vehicle>
<vehicle id="89" type="vehicle.volkswagen.t2" depart="89.00">
<route edges="-42.0.00 -43.0.00 2.0.00 1.0.00 0.0.00 25.0.00 15.0.00 13.0.00"/>
</vehicle>
<vehicle id="90" type="vehicle.yamaha.yzf" depart="90.00">
<route edges="0.0.00 25.0.00 -6.0.00 -7.0.00 4.0.00"/>
</vehicle>
<vehicle id="91" type="vehicle.kawasaki.ninja" depart="91.00">
<route edges="48.0.00 -39.0.00 -0.0.00 -1.0.00 -2.0.00 43.0.00 -24.0.00 11.0.00 3.0.00"/>
</vehicle>
<vehicle id="92" type="vehicle.mercedes.coupe" depart="92.00">
<route edges="-16.0.00 -26.0.00 -21.0.00 -41.0.00 -42.0.00"/>
</vehicle>
<vehicle id="93" type="vehicle.ford.mustang" depart="93.00">
<route edges="-38.0.00 -13.0.00 -14.0.00 33.0.00 -39.0.00 25.0.00 15.0.00 13.0.00"/>
</vehicle>
<vehicle id="94" type="vehicle.audi.a2" depart="94.00">
<route edges="-10.0.00"/>
</vehicle>
<vehicle id="95" type="vehicle.chevrolet.impala" depart="95.00">
<route edges="-11.0.00 24.0.00 23.0.00 22.0.00 21.0.00 28.0.00 27.0.00 -38.0.00 -13.0.00 -14.0.00"/>
</vehicle>
<vehicle id="96" type="vehicle.mini.cooper_s" depart="96.00">
<route edges="40.0.00 0.0.00 -26.0.00 28.0.00 27.0.00 37.0.00"/>
</vehicle>
<vehicle id="97" type="vehicle.audi.tt" depart="97.00">
<route edges="-22.0.00 -52.0.00 49.0.00 4.0.00"/>
</vehicle>
<vehicle id="98" type="vehicle.audi.etron" depart="98.00">
<route edges="-47.0.00 0.0.00 25.0.00 15.0.00 13.0.00"/>
</vehicle>
<vehicle id="99" type="vehicle.audi.tt" depart="99.00">
<route edges="0.0.00 -26.0.00 -21.0.00 -41.0.00 -42.0.00 23.0.00"/>
</vehicle>
<vehicle id="100" type="vehicle.micro.microlino" depart="100.00">
<route edges="1.0.00 0.0.00 25.0.00 15.0.00"/>
</vehicle>
<vehicle id="101" type="vehicle.kawasaki.ninja" depart="101.00">
<route edges="-14.0.00 -16.0.00 -0.0.00 -1.0.00 -2.0.00 -3.0.00"/>
</vehicle>
<vehicle id="102" type="vehicle.yamaha.yzf" depart="102.00">
<route edges="-24.0.00 11.0.00 10.0.00 9.0.00 8.0.00 7.0.00 6.0.00"/>
</vehicle>
<vehicle id="103" type="vehicle.lincoln.mkz_2017" depart="103.00">
<route edges="10.0.00 9.0.00 8.0.00 7.0.00 6.0.00 15.0.00"/>
</vehicle>
<vehicle id="104" type="vehicle.audi.tt" depart="104.00">
<route edges="9.0.00 44.0.00 2.0.00 1.0.00 0.0.00 -26.0.00 28.0.00 27.0.00 37.0.00"/>
</vehicle>
<vehicle id="105" type="vehicle.carlamotors.carlacola" depart="105.00">
<route edges="-24.0.00 11.0.00 3.0.00 2.0.00 1.0.00 0.0.00 39.0.00 31.0.00"/>
</vehicle>
<vehicle id="106" type="vehicle.bh.crossbike" depart="106.00">
<route edges="-30.0.00 -39.0.00 -0.0.00 17.0.00"/>
</vehicle>
<vehicle id="107" type="vehicle.jeep.wrangler_rubicon" depart="107.00">
<route edges="-47.0.00 -1.0.00 49.0.00 -8.0.00"/>
</vehicle>
<vehicle id="108" type="vehicle.audi.a2" depart="108.00">
<route edges="-23.0.00 42.0.00 41.0.00 40.0.00 -1.0.00"/>
</vehicle>
<vehicle id="109" type="vehicle.volkswagen.t2" depart="109.00">
<route edges="-22.0.00 -52.0.00 1.0.00 0.0.00 -26.0.00"/>
</vehicle>
<vehicle id="110" type="vehicle.nissan.patrol" depart="110.00">
<route edges="19.0.00 13.0.00 35.0.00 -27.0.00 -28.0.00 -29.0.00 -0.0.00 -1.0.00 -2.0.00 43.0.00"/>
</vehicle>
<vehicle id="111" type="vehicle.harley-davidson.low_rider" depart="111.00">
<route edges="-50.0.00 -23.0.00 -24.0.00 11.0.00 3.0.00"/>
</vehicle>
<vehicle id="112" type="vehicle.ford.mustang" depart="112.00">
<route edges="-4.0.00 7.0.00 6.0.00 -16.0.00 -0.0.00"/>
</vehicle>
<vehicle id="113" type="vehicle.gazelle.omafiets" depart="113.00">
<route edges="-13.0.00 -14.0.00 -6.0.00 -7.0.00 -8.0.00 -9.0.00 -10.0.00 3.0.00"/>
</vehicle>
<vehicle id="114" type="vehicle.ford.mustang" depart="114.00">
<route edges="-39.0.00 -0.0.00 -1.0.00 -2.0.00 -44.0.00 8.0.00"/>
</vehicle>
<vehicle id="115" type="vehicle.jeep.wrangler_rubicon" depart="115.00">
<route edges="-8.0.00 -45.0.00 -46.0.00 6.0.00"/>
</vehicle>
<vehicle id="116" type="vehicle.tesla.cybertruck" depart="116.00">
<route edges="43.0.00 -24.0.00 11.0.00 10.0.00 9.0.00 -45.0.00"/>
</vehicle>
<vehicle id="117" type="vehicle.lincoln.mkz_2017" depart="117.00">
<route edges="-4.0.00 7.0.00 6.0.00 15.0.00 13.0.00 35.0.00"/>
</vehicle>
<vehicle id="118" type="vehicle.tesla.model3" depart="118.00">
<route edges="-11.0.00 24.0.00 -43.0.00 2.0.00 -50.0.00 -23.0.00"/>
</vehicle>
<vehicle id="119" type="vehicle.audi.etron" depart="119.00">
<route edges="-48.0.00 -20.0.00 -28.0.00 -29.0.00 -0.0.00 -1.0.00 49.0.00 4.0.00"/>
</vehicle>
<vehicle id="120" type="vehicle.nissan.patrol" depart="120.00">
<route edges="48.0.00 -32.0.00 -6.0.00 46.0.00 45.0.00"/>
</vehicle>
<vehicle id="121" type="vehicle.nissan.patrol" depart="121.00">
<route edges="19.0.00 13.0.00 35.0.00 -27.0.00 -28.0.00 -29.0.00 -0.0.00 -1.0.00 -2.0.00"/>
</vehicle>
<vehicle id="122" type="vehicle.citroen.c3" depart="122.00">
<route edges="-4.0.00 7.0.00 6.0.00 15.0.00 -19.0.00 48.0.00"/>
</vehicle>
<vehicle id="123" type="vehicle.toyota.prius" depart="123.00">
<route edges="27.0.00 -38.0.00 -13.0.00 -14.0.00 -16.0.00 39.0.00 -32.0.00"/>
</vehicle>
<vehicle id="124" type="vehicle.kawasaki.ninja" depart="124.00">
<route edges="-18.0.00 -41.0.00 -51.0.00 22.0.00 40.0.00"/>
</vehicle>
<vehicle id="125" type="vehicle.micro.microlino" depart="125.00">
<route edges="-51.0.00 -23.0.00 42.0.00"/>
</vehicle>
<vehicle id="126" type="vehicle.ford.mustang" depart="126.00">
<route edges="37.0.00 -13.0.00 -14.0.00 -16.0.00 -26.0.00 -30.0.00"/>
</vehicle>
<vehicle id="127" type="vehicle.micro.microlino" depart="127.00">
<route edges="25.0.00 33.0.00 -39.0.00 -26.0.00"/>
</vehicle>
<vehicle id="128" type="vehicle.audi.a2" depart="128.00">
<route edges="24.0.00 -43.0.00 2.0.00 1.0.00 0.0.00 39.0.00 -32.0.00"/>
</vehicle>
<vehicle id="129" type="vehicle.seat.leon" depart="129.00">
<route edges="-19.0.00 48.0.00 -39.0.00 -0.0.00 -1.0.00 49.0.00 4.0.00"/>
</vehicle>
<vehicle id="130" type="vehicle.micro.microlino" depart="130.00">
<route edges="41.0.00 -22.0.00 -23.0.00 -43.0.00 2.0.00"/>
</vehicle>
<vehicle id="131" type="vehicle.micro.microlino" depart="131.00">
<route edges="28.0.00 27.0.00 -38.0.00 -13.0.00 -14.0.00 33.0.00 31.0.00"/>
</vehicle>
<vehicle id="132" type="vehicle.jeep.wrangler_rubicon" depart="132.00">
<route edges="-8.0.00 -45.0.00 -46.0.00 6.0.00 -16.0.00 -0.0.00"/>
</vehicle>
<vehicle id="133" type="vehicle.ford.mustang" depart="133.00">
<route edges="-26.0.00 -21.0.00 40.0.00 17.0.00"/>
</vehicle>
<vehicle id="134" type="vehicle.dodge.charger_police" depart="134.00">
<route edges="46.0.00 -4.0.00 -8.0.00 -45.0.00 -46.0.00"/>
</vehicle>
<vehicle id="135" type="vehicle.audi.etron" depart="135.00">
<route edges="-48.0.00 -20.0.00 -28.0.00 -29.0.00 -0.0.00 -1.0.00 -2.0.00 -3.0.00 -11.0.00 24.0.00"/>
</vehicle>
<vehicle id="136" type="vehicle.tesla.model3" depart="136.00">
<route edges="-7.0.00 -5.0.00 -50.0.00 51.0.00 -42.0.00"/>
</vehicle>
<vehicle id="137" type="vehicle.volkswagen.t2" depart="137.00">
<route edges="-38.0.00 -13.0.00 -14.0.00 33.0.00 -39.0.00 25.0.00 15.0.00 13.0.00 35.0.00"/>
</vehicle>
<vehicle id="138" type="vehicle.toyota.prius" depart="138.00">
<route edges="-11.0.00 24.0.00 23.0.00 51.0.00 -42.0.00 -24.0.00 11.0.00"/>
</vehicle>
<vehicle id="139" type="vehicle.nissan.patrol" depart="139.00">
<route edges="-2.0.00 43.0.00 42.0.00 41.0.00 -22.0.00"/>
</vehicle>
<vehicle id="140" type="vehicle.volkswagen.t2" depart="140.00">
<route edges="-19.0.00 48.0.00 -39.0.00 -0.0.00 -1.0.00 -2.0.00 -3.0.00"/>
</vehicle>
<vehicle id="141" type="vehicle.tesla.model3" depart="141.00">
<route edges="-38.0.00 -13.0.00 -14.0.00 -6.0.00 -7.0.00 -5.0.00 -50.0.00"/>
</vehicle>
<vehicle id="142" type="vehicle.audi.etron" depart="142.00">
<route edges="25.0.00 15.0.00 13.0.00 35.0.00 -27.0.00 20.0.00"/>
</vehicle>
<vehicle id="143" type="vehicle.harley-davidson.low_rider" depart="143.00">
<route edges="25.0.00 -6.0.00 -7.0.00 -8.0.00 -9.0.00 -10.0.00 -11.0.00"/>
</vehicle>
<vehicle id="144" type="vehicle.tesla.cybertruck" depart="144.00">
<route edges="13.0.00 35.0.00 -27.0.00 -28.0.00 -21.0.00 -22.0.00 -23.0.00 -24.0.00"/>
</vehicle>
<vehicle id="145" type="vehicle.audi.etron" depart="145.00">
<route edges="22.0.00 21.0.00"/>
</vehicle>
<vehicle id="146" type="vehicle.bmw.grandtourer" depart="146.00">
<route edges="37.0.00 -13.0.00 -14.0.00 -6.0.00"/>
</vehicle>
<vehicle id="147" type="vehicle.seat.leon" depart="147.00">
<route edges="-50.0.00 22.0.00 40.0.00 17.0.00 6.0.00 33.0.00"/>
</vehicle>
<vehicle id="148" type="vehicle.citroen.c3" depart="148.00">
<route edges="-32.0.00 -16.0.00 -26.0.00 28.0.00 27.0.00"/>
</vehicle>
<vehicle id="149" type="vehicle.carlamotors.carlacola" depart="149.00">
<route edges="-11.0.00 24.0.00 -43.0.00 2.0.00 1.0.00 0.0.00 25.0.00 15.0.00 13.0.00 35.0.00 -27.0.00 20.0.00"/>
</vehicle>
<vehicle id="150" type="vehicle.dodge.charger_police" depart="150.00">
<route edges="-39.0.00 -0.0.00 -1.0.00 -2.0.00 43.0.00 42.0.00"/>
</vehicle>
<vehicle id="151" type="vehicle.tesla.model3" depart="151.00">
<route edges="27.0.00 -38.0.00 -13.0.00 -14.0.00 -6.0.00 -7.0.00 -8.0.00 -45.0.00"/>
</vehicle>
<vehicle id="152" type="vehicle.chevrolet.impala" depart="152.00">
<route edges="31.0.00 -29.0.00 -0.0.00 -1.0.00 -2.0.00 -44.0.00"/>
</vehicle>
<vehicle id="153" type="vehicle.mercedes.coupe" depart="153.00">
<route edges="-20.0.00 -28.0.00 -29.0.00 -0.0.00 -1.0.00 -2.0.00 -44.0.00"/>
</vehicle>
<vehicle id="154" type="vehicle.ford.mustang" depart="154.00">
<route edges="7.0.00 -47.0.00 0.0.00 25.0.00 -6.0.00"/>
</vehicle>
<vehicle id="155" type="vehicle.gazelle.omafiets" depart="155.00">
<route edges="44.0.00 2.0.00 49.0.00"/>
</vehicle>
<vehicle id="156" type="vehicle.dodge.charger_police" depart="156.00">
<route edges="33.0.00 -39.0.00 -0.0.00 17.0.00 -7.0.00 -5.0.00"/>
</vehicle>
<vehicle id="157" type="vehicle.seat.leon" depart="157.00">
<route edges="-18.0.00 21.0.00 -29.0.00 39.0.00 31.0.00"/>
</vehicle>
<vehicle id="158" type="vehicle.bh.crossbike" depart="158.00">
<route edges="-14.0.00 -6.0.00 46.0.00"/>
</vehicle>
<vehicle id="159" type="vehicle.carlamotors.carlacola" depart="159.00">
<route edges="35.0.00 -27.0.00 20.0.00 48.0.00"/>
</vehicle>
<vehicle id="160" type="vehicle.gazelle.omafiets" depart="160.00">
<route edges="6.0.00 33.0.00 -48.0.00 19.0.00"/>
</vehicle>
<vehicle id="161" type="vehicle.yamaha.yzf" depart="161.00">
<route edges="23.0.00 -52.0.00 -2.0.00 -44.0.00 8.0.00 -5.0.00"/>
</vehicle>
<vehicle id="162" type="vehicle.tesla.cybertruck" depart="162.00">
<route edges="17.0.00 -7.0.00"/>
</vehicle>
<vehicle id="163" type="vehicle.seat.leon" depart="163.00">
<route edges="-24.0.00 11.0.00 10.0.00"/>
</vehicle>
<vehicle id="164" type="vehicle.ford.mustang" depart="164.00">
<route edges="24.0.00 23.0.00 -52.0.00"/>
</vehicle>
<vehicle id="165" type="vehicle.audi.etron" depart="165.00">
<route edges="-8.0.00 44.0.00 2.0.00 1.0.00 17.0.00"/>
</vehicle>
<vehicle id="166" type="vehicle.bh.crossbike" depart="166.00">
<route edges="24.0.00 23.0.00 22.0.00 21.0.00 28.0.00 27.0.00 -38.0.00 -13.0.00"/>
</vehicle>
<vehicle id="167" type="vehicle.lincoln.mkz_2017" depart="167.00">
<route edges="37.0.00 -13.0.00 -14.0.00 -6.0.00 -7.0.00 -5.0.00 -50.0.00 -23.0.00"/>
</vehicle>
<vehicle id="168" type="vehicle.yamaha.yzf" depart="168.00">
<route edges="-26.0.00 -21.0.00 40.0.00 -1.0.00 -2.0.00"/>
</vehicle>
<vehicle id="169" type="vehicle.citroen.c3" depart="169.00">
<route edges="-7.0.00 -8.0.00"/>
</vehicle>
<vehicle id="170" type="vehicle.mercedes.coupe" depart="170.00">
<route edges="25.0.00 -6.0.00 -7.0.00 -8.0.00"/>
</vehicle>
<vehicle id="171" type="vehicle.mini.cooper_s" depart="171.00">
<route edges="9.0.00 44.0.00 43.0.00 42.0.00 -51.0.00"/>
</vehicle>
<vehicle id="172" type="vehicle.seat.leon" depart="172.00">
<route edges="-30.0.00 -39.0.00 25.0.00 33.0.00"/>
</vehicle>
<vehicle id="173" type="vehicle.nissan.micra" depart="173.00">
<route edges="-50.0.00 22.0.00 21.0.00 28.0.00 27.0.00 37.0.00"/>
</vehicle>
<vehicle id="174" type="vehicle.citroen.c3" depart="174.00">
<route edges="-3.0.00 10.0.00 9.0.00 8.0.00 -5.0.00 -2.0.00"/>
</vehicle>
<vehicle id="175" type="vehicle.volkswagen.t2" depart="175.00">
<route edges="33.0.00 31.0.00"/>
</vehicle>
<vehicle id="176" type="vehicle.dodge.charger_police" depart="176.00">
<route edges="-19.0.00 48.0.00 31.0.00 -21.0.00 -22.0.00 51.0.00 41.0.00"/>
</vehicle>
<vehicle id="177" type="vehicle.ford.mustang" depart="177.00">
<route edges="-0.0.00 17.0.00 6.0.00 -16.0.00 -26.0.00"/>
</vehicle>
<vehicle id="178" type="vehicle.citroen.c3" depart="178.00">
<route edges="45.0.00 8.0.00 7.0.00 6.0.00 15.0.00 -19.0.00 48.0.00"/>
</vehicle>
<vehicle id="179" type="vehicle.kawasaki.ninja" depart="179.00">
<route edges="6.0.00 15.0.00 -19.0.00 48.0.00"/>
</vehicle>
<vehicle id="180" type="vehicle.ford.mustang" depart="180.00">
<route edges="-9.0.00 -10.0.00 3.0.00 2.0.00 49.0.00 7.0.00 6.0.00 -16.0.00 -0.0.00"/>
</vehicle>
<vehicle id="181" type="vehicle.seat.leon" depart="181.00">
<route edges="-20.0.00 -28.0.00 -29.0.00 -0.0.00 17.0.00 46.0.00 45.0.00"/>
</vehicle>
<vehicle id="182" type="vehicle.audi.etron" depart="182.00">
<route edges="-22.0.00 51.0.00 41.0.00 21.0.00 28.0.00 27.0.00 -38.0.00 -13.0.00"/>
</vehicle>
<vehicle id="183" type="vehicle.toyota.prius" depart="183.00">
<route edges="2.0.00 1.0.00 0.0.00 -26.0.00 28.0.00 27.0.00 -38.0.00 -13.0.00"/>
</vehicle>
<vehicle id="184" type="vehicle.ford.mustang" depart="184.00">
<route edges="-16.0.00 -0.0.00 -1.0.00 -2.0.00 -3.0.00 10.0.00"/>
</vehicle>
<vehicle id="185" type="vehicle.lincoln.mkz_2017" depart="185.00">
<route edges="41.0.00 40.0.00 17.0.00 6.0.00"/>
</vehicle>
<vehicle id="186" type="vehicle.diamondback.century" depart="186.00">
<route edges="-4.0.00 -5.0.00 1.0.00 -18.0.00 -22.0.00"/>
</vehicle>
<vehicle id="187" type="vehicle.jeep.wrangler_rubicon" depart="187.00">
<route edges="46.0.00 45.0.00 44.0.00 43.0.00 -24.0.00 11.0.00"/>
</vehicle>
<vehicle id="188" type="vehicle.audi.tt" depart="188.00">
<route edges="42.0.00 -51.0.00 -52.0.00 -2.0.00"/>
</vehicle>
<vehicle id="189" type="vehicle.gazelle.omafiets" depart="189.00">
<route edges="25.0.00 -6.0.00 -7.0.00 4.0.00 -46.0.00 6.0.00 -16.0.00"/>
</vehicle>
<vehicle id="190" type="vehicle.diamondback.century" depart="190.00">
<route edges="3.0.00 2.0.00 1.0.00"/>
</vehicle>
<vehicle id="191" type="vehicle.mini.cooper_s" depart="191.00">
<route edges="-6.0.00 -47.0.00 -18.0.00 21.0.00 -29.0.00"/>
</vehicle>
<vehicle id="192" type="vehicle.yamaha.yzf" depart="192.00">
<route edges="-10.0.00 3.0.00 2.0.00 -50.0.00"/>
</vehicle>
<vehicle id="193" type="vehicle.dodge.charger_police" depart="193.00">
<route edges="19.0.00 13.0.00 35.0.00 -27.0.00 -28.0.00 -21.0.00 40.0.00"/>
</vehicle>
<vehicle id="194" type="vehicle.audi.tt" depart="194.00">
<route edges="-43.0.00 2.0.00 1.0.00 0.0.00 -26.0.00 28.0.00 27.0.00"/>
</vehicle>
<vehicle id="195" type="vehicle.mercedes.coupe" depart="195.00">
<route edges="-30.0.00 -39.0.00 -0.0.00 -1.0.00 -2.0.00 -3.0.00 10.0.00"/>
</vehicle>
<vehicle id="196" type="vehicle.nissan.micra" depart="196.00">
<route edges="51.0.00 41.0.00 21.0.00 -30.0.00 -48.0.00"/>
</vehicle>
<vehicle id="197" type="vehicle.toyota.prius" depart="197.00">
<route edges="-23.0.00 -43.0.00 -44.0.00"/>
</vehicle>
<vehicle id="198" type="vehicle.micro.microlino" depart="198.00">
<route edges="51.0.00 -42.0.00 -24.0.00 11.0.00 10.0.00 9.0.00"/>
</vehicle>
<vehicle id="199" type="vehicle.bmw.grandtourer" depart="199.00">
<route edges="-39.0.00 -0.0.00 -1.0.00 -2.0.00 -3.0.00 -11.0.00 24.0.00"/>
</vehicle>
</routes>

View File

@ -1,774 +0,0 @@
<viewsettings>
<scheme name="custom_1">
<opengl dither="0" fps="0" drawBoundaries="0" forceDrawPositionSelection="0" forceDrawRectangleSelection="0"/>
<background backgroundColor="white" showGrid="0" gridXSize="100.00" gridYSize="100.00"/>
<edges laneEdgeMode="0" scaleMode="0" laneShowBorders="1" showBikeMarkings="1" showLinkDecals="1" showLinkRules="1" showRails="1" hideConnectors="0" widthExaggeration="1.00" minSize="0.00" showDirection="0" showSublanes="1" spreadSuperposed="0" edgeParam="EDGE_KEY" laneParam="LANE_KEY" vehicleParam="PARAM_NUMERICAL" vehicleTextParam="PARAM_TEXT" edgeData="speed"
edgeName_show="0" edgeName_size="60.00" edgeName_color="orange" edgeName_bgColor="128,0,0,0" edgeName_constantSize="1"
internalEdgeName_show="0" internalEdgeName_size="45.00" internalEdgeName_color="128,64,0" internalEdgeName_bgColor="128,0,0,0" internalEdgeName_constantSize="1"
cwaEdgeName_show="0" cwaEdgeName_size="60.00" cwaEdgeName_color="magenta" cwaEdgeName_bgColor="128,0,0,0" cwaEdgeName_constantSize="1"
streetName_show="0" streetName_size="60.00" streetName_color="yellow" streetName_bgColor="128,0,0,0" streetName_constantSize="1"
edgeValue_show="0" edgeValue_size="100.00" edgeValue_color="cyan" edgeValue_bgColor="128,0,0,0" edgeValue_constantSize="1">
<colorScheme name="uniform">
<entry color="black" name="road"/>
<entry color="grey" name="sidewalk"/>
<entry color="192,66,44" name="bike lane"/>
<entry color="0,0,0,0" name="green verge"/>
<entry color="150,200,200" name="waterway"/>
<entry color="black" name="railway"/>
<entry color="92,92,92" name="no passenger"/>
<entry color="red" name="closed"/>
<entry color="green" name="connector"/>
<entry color="orange" name="forbidden"/>
</colorScheme>
<colorScheme name="by selection">
<entry color="grey" name="unselected"/>
<entry color="0,80,180" name="selected"/>
</colorScheme>
<colorScheme name="by permission code" interpolated="1">
<entry color="240,240,240" threshold="0.00" name="nobody"/>
<entry color="grey" threshold="32.00" name="pedestrian"/>
<entry color="10,10,10" threshold="64.00" name="passenger"/>
<entry color="166,147,26" threshold="256.00" name="taxi"/>
<entry color="40,100,40" threshold="512.00" name="bus"/>
<entry color="80,80,80" threshold="2080.00" name="pedestrian_delivery"/>
<entry color="192,66,44" threshold="65536.00" name="bicycle"/>
<entry color="150,200,200" threshold="8388608.00" name="waterway"/>
<entry color="255,206,0" threshold="50495455.00" name="motorway"/>
<entry color="black" threshold="50593759.00" name="disallow_pedestrian"/>
<entry color="black" threshold="50593791.00" name="normal_road"/>
<entry color="green" threshold="67108863.00" name="all"/>
</colorScheme>
<colorScheme name="by allowed speed (lanewise)" interpolated="1">
<entry color="red" threshold="0.00"/>
<entry color="yellow" threshold="8.33"/>
<entry color="green" threshold="15.28"/>
<entry color="cyan" threshold="22.22"/>
<entry color="blue" threshold="33.33"/>
<entry color="magenta" threshold="41.67"/>
</colorScheme>
<colorScheme name="by current occupancy (lanewise, brutto)" interpolated="1">
<entry color="235,235,235" threshold="0.00"/>
<entry color="green" threshold="0.25"/>
<entry color="yellow" threshold="0.50"/>
<entry color="orange" threshold="0.75"/>
<entry color="red" threshold="1.00"/>
</colorScheme>
<colorScheme name="by current occupancy (lanewise, netto)" interpolated="1">
<entry color="235,235,235" threshold="0.00"/>
<entry color="green" threshold="0.25"/>
<entry color="yellow" threshold="0.50"/>
<entry color="orange" threshold="0.75"/>
<entry color="red" threshold="1.00"/>
</colorScheme>
<colorScheme name="by first vehicle waiting time (lanewise)" interpolated="1">
<entry color="235,235,235" threshold="0.00"/>
<entry color="cyan" threshold="30.00"/>
<entry color="green" threshold="100.00"/>
<entry color="yellow" threshold="200.00"/>
<entry color="red" threshold="300.00"/>
</colorScheme>
<colorScheme name="by lane number (streetwise)" interpolated="1">
<entry color="red" threshold="0.00"/>
<entry color="blue" threshold="5.00"/>
</colorScheme>
<colorScheme name="by CO2 emissions" interpolated="1">
<entry color="green" threshold="0.00"/>
<entry color="red" threshold="0.27"/>
</colorScheme>
<colorScheme name="by CO emissions" interpolated="1">
<entry color="green" threshold="0.00"/>
<entry color="red" threshold="0.00"/>
</colorScheme>
<colorScheme name="by PMx emissions" interpolated="1">
<entry color="green" threshold="0.00"/>
<entry color="red" threshold="0.00"/>
</colorScheme>
<colorScheme name="by NOx emissions" interpolated="1">
<entry color="green" threshold="0.00"/>
<entry color="red" threshold="0.00"/>
</colorScheme>
<colorScheme name="by HC emissions" interpolated="1">
<entry color="green" threshold="0.00"/>
<entry color="red" threshold="0.00"/>
</colorScheme>
<colorScheme name="by fuel consumption" interpolated="1">
<entry color="green" threshold="0.00"/>
<entry color="red" threshold="0.07"/>
</colorScheme>
<colorScheme name="by noise emissions (Harmonoise)" interpolated="1">
<entry color="green" threshold="0.00"/>
<entry color="red" threshold="100.00"/>
</colorScheme>
<colorScheme name="by global travel time" interpolated="1">
<entry color="green" threshold="0.00"/>
<entry color="red" threshold="100.00"/>
</colorScheme>
<colorScheme name="by global speed percentage" interpolated="1">
<entry color="red" threshold="0.00"/>
<entry color="yellow" threshold="50.00"/>
<entry color="green" threshold="100.00"/>
</colorScheme>
<colorScheme name="by given length/geometrical length" interpolated="1">
<entry color="black" threshold="0.00"/>
<entry color="red" threshold="0.25"/>
<entry color="yellow" threshold="0.50"/>
<entry color="179,179,179" threshold="1.00"/>
<entry color="green" threshold="2.00"/>
<entry color="blue" threshold="4.00"/>
</colorScheme>
<colorScheme name="by angle">
<entry color="yellow"/>
</colorScheme>
<colorScheme name="by loaded weight" interpolated="1">
<entry color="green" threshold="0.00"/>
<entry color="red" threshold="100.00"/>
</colorScheme>
<colorScheme name="by priority" interpolated="1">
<entry color="red" threshold="-20.00"/>
<entry color="yellow" threshold="0.00"/>
<entry color="green" threshold="20.00"/>
</colorScheme>
<colorScheme name="by height at start" interpolated="1">
<entry color="blue" threshold="-10.00"/>
<entry color="grey" threshold="0.00"/>
<entry color="red" threshold="10.00"/>
<entry color="yellow" threshold="50.00"/>
<entry color="green" threshold="100.00"/>
<entry color="magenta" threshold="200.00"/>
</colorScheme>
<colorScheme name="by height at geometry-segment start" interpolated="1">
<entry color="blue" threshold="-10.00"/>
<entry color="grey" threshold="0.00"/>
<entry color="red" threshold="10.00"/>
<entry color="yellow" threshold="50.00"/>
<entry color="green" threshold="100.00"/>
<entry color="magenta" threshold="200.00"/>
</colorScheme>
<colorScheme name="by inclination" interpolated="1">
<entry color="blue" threshold="-0.30"/>
<entry color="green" threshold="-0.10"/>
<entry color="grey" threshold="0.00"/>
<entry color="yellow" threshold="0.10"/>
<entry color="red" threshold="0.30"/>
</colorScheme>
<colorScheme name="by geometry-segment inclination" interpolated="1">
<entry color="blue" threshold="-0.30"/>
<entry color="green" threshold="-0.10"/>
<entry color="grey" threshold="0.00"/>
<entry color="yellow" threshold="0.10"/>
<entry color="red" threshold="0.30"/>
</colorScheme>
<colorScheme name="by average speed" interpolated="1">
<entry color="red" threshold="0.00"/>
<entry color="yellow" threshold="8.33"/>
<entry color="green" threshold="15.28"/>
<entry color="cyan" threshold="22.22"/>
<entry color="blue" threshold="33.33"/>
<entry color="magenta" threshold="41.67"/>
</colorScheme>
<colorScheme name="by average relative speed " interpolated="1">
<entry color="red" threshold="0.00"/>
<entry color="yellow" threshold="0.25"/>
<entry color="green" threshold="0.50"/>
<entry color="cyan" threshold="0.75"/>
<entry color="blue" threshold="1.00"/>
<entry color="magenta" threshold="1.25"/>
</colorScheme>
<colorScheme name="by routing device assumed speed " interpolated="1">
<entry color="red" threshold="0.00"/>
<entry color="yellow" threshold="8.33"/>
<entry color="green" threshold="15.28"/>
<entry color="cyan" threshold="22.22"/>
<entry color="blue" threshold="33.33"/>
<entry color="magenta" threshold="41.67"/>
</colorScheme>
<colorScheme name="by electricity consumption" interpolated="1">
<entry color="green" threshold="0.00"/>
<entry color="red" threshold="0.03"/>
</colorScheme>
<colorScheme name="by insertion-backlog (streetwise)" interpolated="1">
<entry color="204,204,204" threshold="0.00"/>
<entry color="green" threshold="1.00"/>
<entry color="yellow" threshold="10.00"/>
<entry color="red" threshold="100.00"/>
</colorScheme>
<colorScheme name="by TAZ (streetwise)">
<entry color="204,204,204" name="no TAZ"/>
</colorScheme>
<colorScheme name="by param (numerical, streetwise)" interpolated="1">
<entry color="204,204,204" threshold="0.00"/>
</colorScheme>
<colorScheme name="by param (numerical, lanewise)" interpolated="1">
<entry color="204,204,204" threshold="0.00"/>
</colorScheme>
<colorScheme name="by edgeData (numerical, streetwise)" interpolated="1">
<entry color="204,204,204" threshold="0.00"/>
</colorScheme>
<colorScheme name="by distance (kilometrage)" interpolated="1">
<entry color="blue" threshold="-10000.00"/>
<entry color="204,204,255" threshold="-1.00"/>
<entry color="204,204,204" threshold="0.00"/>
<entry color="255,204,204" threshold="1.00"/>
<entry color="red" threshold="10000.00"/>
</colorScheme>
<colorScheme name="by abs distance (kilometrage)" interpolated="1">
<entry color="204,204,204" threshold="0.00"/>
<entry color="red" threshold="1.00"/>
</colorScheme>
<colorScheme name="by reachability (traveltime)" interpolated="1">
<entry color="204,204,204" threshold="0.00"/>
<entry color="red" threshold="1.00"/>
</colorScheme>
<colorScheme name="by thread index" interpolated="1">
<entry color="204,204,204" threshold="0.00"/>
<entry color="red" threshold="1.00"/>
</colorScheme>
<scalingScheme name="default">
<entry color="1.00" name="uniform"/>
</scalingScheme>
<scalingScheme name="by selection">
<entry color="0.50" name="unselected"/>
<entry color="5.00" name="selected"/>
</scalingScheme>
<scalingScheme name="by allowed speed (lanewise)" interpolated="1">
<entry color="0.00" threshold="0.00"/>
<entry color="10.00" threshold="41.67"/>
</scalingScheme>
<scalingScheme name="by current occupancy (lanewise, brutto)" interpolated="1">
<entry color="0.00" threshold="0.00"/>
<entry color="10.00" threshold="0.95"/>
</scalingScheme>
<scalingScheme name="by current occupancy (lanewise, netto)" interpolated="1">
<entry color="0.00" threshold="0.00"/>
<entry color="10.00" threshold="0.95"/>
</scalingScheme>
<scalingScheme name="by first vehicle waiting time (lanewise)" interpolated="1">
<entry color="0.00" threshold="0.00"/>
<entry color="10.00" threshold="300.00"/>
</scalingScheme>
<scalingScheme name="by lane number (streetwise)" interpolated="1">
<entry color="1.00" threshold="0.00"/>
<entry color="10.00" threshold="5.00"/>
</scalingScheme>
<scalingScheme name="by CO2 emissions" interpolated="1">
<entry color="0.00" threshold="0.00"/>
<entry color="10.00" threshold="0.27"/>
</scalingScheme>
<scalingScheme name="by CO emissions" interpolated="1">
<entry color="0.00" threshold="0.00"/>
<entry color="10.00" threshold="0.00"/>
</scalingScheme>
<scalingScheme name="by PMx emissions" interpolated="1">
<entry color="0.00" threshold="0.00"/>
<entry color="10.00" threshold="0.00"/>
</scalingScheme>
<scalingScheme name="by NOx emissions" interpolated="1">
<entry color="0.00" threshold="0.00"/>
<entry color="10.00" threshold="0.00"/>
</scalingScheme>
<scalingScheme name="by HC emissions" interpolated="1">
<entry color="0.00" threshold="0.00"/>
<entry color="10.00" threshold="0.00"/>
</scalingScheme>
<scalingScheme name="by fuel consumption" interpolated="1">
<entry color="0.00" threshold="0.00"/>
<entry color="10.00" threshold="0.07"/>
</scalingScheme>
<scalingScheme name="by noise emissions (Harmonoise)" interpolated="1">
<entry color="0.00" threshold="0.00"/>
<entry color="10.00" threshold="100.00"/>
</scalingScheme>
<scalingScheme name="by global travel time" interpolated="1">
<entry color="0.00" threshold="0.00"/>
<entry color="10.00" threshold="100.00"/>
</scalingScheme>
<scalingScheme name="by global speed percentage" interpolated="1">
<entry color="0.00" threshold="0.00"/>
<entry color="10.00" threshold="100.00"/>
</scalingScheme>
<scalingScheme name="by given length/geometrical length" interpolated="1">
<entry color="0.00" threshold="0.00"/>
<entry color="10.00" threshold="10.00"/>
</scalingScheme>
<scalingScheme name="by loaded weight" interpolated="1">
<entry color="-1000.00" threshold="-1000.00"/>
<entry color="0.00" threshold="0.00"/>
<entry color="1000.00" threshold="1000.00"/>
</scalingScheme>
<scalingScheme name="by priority" interpolated="1">
<entry color="0.50" threshold="-20.00"/>
<entry color="1.00" threshold="0.00"/>
<entry color="5.00" threshold="20.00"/>
</scalingScheme>
<scalingScheme name="by average speed" interpolated="1">
<entry color="0.00" threshold="0.00"/>
<entry color="10.00" threshold="41.67"/>
</scalingScheme>
<scalingScheme name="by average relative speed" interpolated="1">
<entry color="0.00" threshold="0.00"/>
<entry color="0.50" threshold="0.50"/>
<entry color="2.00" threshold="1.00"/>
<entry color="10.00" threshold="2.00"/>
</scalingScheme>
<scalingScheme name="by electricity consumption" interpolated="1">
<entry color="0.00" threshold="0.00"/>
<entry color="10.00" threshold="0.03"/>
</scalingScheme>
<scalingScheme name="by insertion-backlog (streetwise)" interpolated="1">
<entry color="0.00" threshold="0.00"/>
<entry color="1.00" threshold="1.00"/>
<entry color="10.00" threshold="10.00"/>
<entry color="50.00" threshold="100.00"/>
</scalingScheme>
<colorScheme name="uniform">
<entry color="0,0,0,0"/>
</colorScheme>
<colorScheme name="by selection">
<entry color="grey" name="unselected"/>
<entry color="0,80,180" name="selected"/>
</colorScheme>
<colorScheme name="by purpose (streetwise)">
<entry color="0,0,0,0" name="normal"/>
<entry color="128,0,128" name="connector"/>
<entry color="blue" name="internal"/>
</colorScheme>
<colorScheme name="by allowed speed (streetwise)" interpolated="1">
<entry color="red" threshold="0.00"/>
<entry color="yellow" threshold="8.33"/>
<entry color="green" threshold="15.28"/>
<entry color="cyan" threshold="22.22"/>
<entry color="blue" threshold="33.33"/>
<entry color="magenta" threshold="41.67"/>
</colorScheme>
<colorScheme name="by current occupancy (streetwise, brutto)" interpolated="1">
<entry color="blue" threshold="0.00"/>
<entry color="red" threshold="0.95"/>
</colorScheme>
<colorScheme name="by current speed (streetwise)" interpolated="1">
<entry color="red" threshold="0.00"/>
<entry color="yellow" threshold="8.33"/>
<entry color="green" threshold="15.28"/>
<entry color="cyan" threshold="22.22"/>
<entry color="blue" threshold="33.33"/>
<entry color="magenta" threshold="41.67"/>
</colorScheme>
<colorScheme name="by current flow (streetwise)" interpolated="1">
<entry color="blue" threshold="0.00"/>
<entry color="red" threshold="5000.00"/>
</colorScheme>
<colorScheme name="by relative speed (streetwise)" interpolated="1">
<entry color="red" threshold="0.00"/>
<entry color="yellow" threshold="0.25"/>
<entry color="green" threshold="0.50"/>
<entry color="cyan" threshold="0.75"/>
<entry color="blue" threshold="1.00"/>
<entry color="magenta" threshold="1.25"/>
</colorScheme>
<colorScheme name="by routing device assumed speed" interpolated="1">
<entry color="red" threshold="0.00"/>
<entry color="yellow" threshold="8.33"/>
<entry color="green" threshold="15.28"/>
<entry color="cyan" threshold="22.22"/>
<entry color="blue" threshold="33.33"/>
<entry color="magenta" threshold="41.67"/>
</colorScheme>
<colorScheme name="by angle">
<entry color="yellow"/>
</colorScheme>
<colorScheme name="by segments (alternating)">
<entry color="blue" name="odd"/>
<entry color="red" name="even"/>
</colorScheme>
<colorScheme name="by jammed state (segmentwise)">
<entry color="green" name="free"/>
<entry color="red" name="jammed"/>
</colorScheme>
<colorScheme name="by current occupancy (segmentwise, brutto)" interpolated="1">
<entry color="blue" threshold="0.00"/>
<entry color="red" threshold="0.95"/>
</colorScheme>
<colorScheme name="by current speed (segmentwise)" interpolated="1">
<entry color="red" threshold="0.00"/>
<entry color="yellow" threshold="8.33"/>
<entry color="green" threshold="15.28"/>
<entry color="cyan" threshold="22.22"/>
<entry color="blue" threshold="33.33"/>
<entry color="magenta" threshold="41.67"/>
</colorScheme>
<colorScheme name="by current flow (segmentwise)" interpolated="1">
<entry color="blue" threshold="0.00"/>
<entry color="red" threshold="5000.00"/>
</colorScheme>
<colorScheme name="by relative speed (segmentwise)" interpolated="1">
<entry color="red" threshold="0.00"/>
<entry color="yellow" threshold="0.25"/>
<entry color="green" threshold="0.50"/>
<entry color="cyan" threshold="0.75"/>
<entry color="blue" threshold="1.00"/>
<entry color="magenta" threshold="1.25"/>
</colorScheme>
<colorScheme name="by insertion-backlog (streetwise)" interpolated="1">
<entry color="grey" threshold="0.00"/>
<entry color="green" threshold="1.00"/>
<entry color="yellow" threshold="10.00"/>
<entry color="red" threshold="100.00"/>
</colorScheme>
<colorScheme name="by TAZ (streetwise)">
<entry color="204,204,204" name="no TAZ"/>
</colorScheme>
<scalingScheme name="uniform">
<entry color="1.00"/>
</scalingScheme>
<scalingScheme name="by selection">
<entry color="0.50" name="unselected"/>
<entry color="5.00" name="selected"/>
</scalingScheme>
<scalingScheme name="by allowed speed (streetwise)" interpolated="1">
<entry color="0.00" threshold="0.00"/>
<entry color="10.00" threshold="41.67"/>
</scalingScheme>
<scalingScheme name="by current occupancy (streetwise, brutto)" interpolated="1">
<entry color="0.00" threshold="0.00"/>
<entry color="10.00" threshold="0.95"/>
</scalingScheme>
<scalingScheme name="by current speed (streetwise)" interpolated="1">
<entry color="0.00" threshold="0.00"/>
<entry color="10.00" threshold="41.67"/>
</scalingScheme>
<scalingScheme name="by current flow (streetwise)" interpolated="1">
<entry color="0.00" threshold="0.00"/>
<entry color="20.00" threshold="5000.00"/>
</scalingScheme>
<scalingScheme name="by relative speed (streetwise)" interpolated="1">
<entry color="0.00" threshold="0.00"/>
<entry color="20.00" threshold="1.00"/>
</scalingScheme>
<scalingScheme name="by insertion-backlog (streetwise)" interpolated="1">
<entry color="0.00" threshold="0.00"/>
<entry color="1.00" threshold="1.00"/>
<entry color="10.00" threshold="10.00"/>
<entry color="50.00" threshold="100.00"/>
</scalingScheme>
</edges>
<vehicles vehicleMode="0" vehicleQuality="3" vehicle_minSize="1.00" vehicle_exaggeration="1.00" vehicle_constantSize="0" vehicle_constantSizeSelected="0" showBlinker="1" drawMinGap="0" drawBrakeGap="0" showBTRange="0" showRouteIndex="0"
vehicleName_show="0" vehicleName_size="60.00" vehicleName_color="204,153,0" vehicleName_bgColor="128,0,0,0" vehicleName_constantSize="1"
vehicleValue_show="0" vehicleValue_size="80.00" vehicleValue_color="cyan" vehicleValue_bgColor="128,0,0,0" vehicleValue_constantSize="1"
vehicleText_show="0" vehicleText_size="80.00" vehicleText_color="red" vehicleText_bgColor="128,0,0,0" vehicleText_constantSize="1">
<colorScheme name="given vehicle/type/route color">
<entry color="yellow"/>
</colorScheme>
<colorScheme name="uniform">
<entry color="yellow"/>
</colorScheme>
<colorScheme name="given/assigned vehicle color">
<entry color="yellow"/>
</colorScheme>
<colorScheme name="given/assigned type color">
<entry color="yellow"/>
</colorScheme>
<colorScheme name="given/assigned route color">
<entry color="yellow"/>
</colorScheme>
<colorScheme name="depart position as HSV">
<entry color="yellow"/>
</colorScheme>
<colorScheme name="arrival position as HSV">
<entry color="yellow"/>
</colorScheme>
<colorScheme name="direction/distance as HSV">
<entry color="yellow"/>
</colorScheme>
<colorScheme name="by speed" interpolated="1">
<entry color="red" threshold="0.00"/>
<entry color="yellow" threshold="8.33"/>
<entry color="green" threshold="15.28"/>
<entry color="cyan" threshold="22.22"/>
<entry color="blue" threshold="33.33"/>
<entry color="magenta" threshold="41.67"/>
</colorScheme>
<colorScheme name="by action step">
<entry color="grey" name="no action"/>
<entry color="green" name="action in next step"/>
<entry color="80,160,80" name="had action step"/>
</colorScheme>
<colorScheme name="by waiting time" interpolated="1">
<entry color="blue" threshold="0.00"/>
<entry color="cyan" threshold="30.00"/>
<entry color="green" threshold="100.00"/>
<entry color="yellow" threshold="200.00"/>
<entry color="red" threshold="300.00"/>
</colorScheme>
<colorScheme name="by accumulated waiting time" interpolated="1">
<entry color="blue" threshold="0.00"/>
<entry color="cyan" threshold="25.00"/>
<entry color="green" threshold="50.00"/>
<entry color="yellow" threshold="75.00"/>
<entry color="red" threshold="100.00"/>
</colorScheme>
<colorScheme name="by time since lane change" interpolated="1">
<entry color="189,189,179" threshold="-180.00"/>
<entry color="yellow" threshold="-20.00"/>
<entry color="red" threshold="-0.00"/>
<entry color="179,179,179" threshold="0.00" name="0"/>
<entry color="blue" threshold="0.00"/>
<entry color="cyan" threshold="20.00"/>
<entry color="179,189,189" threshold="180.00"/>
</colorScheme>
<colorScheme name="by max speed" interpolated="1">
<entry color="red" threshold="0.00"/>
<entry color="yellow" threshold="8.33"/>
<entry color="green" threshold="15.28"/>
<entry color="cyan" threshold="22.22"/>
<entry color="blue" threshold="33.33"/>
<entry color="magenta" threshold="41.67"/>
</colorScheme>
<colorScheme name="by CO2 emissions" interpolated="1">
<entry color="green" threshold="0.00"/>
<entry color="red" threshold="5.00"/>
</colorScheme>
<colorScheme name="by CO emissions" interpolated="1">
<entry color="green" threshold="0.00"/>
<entry color="red" threshold="0.05"/>
</colorScheme>
<colorScheme name="by PMx emissions" interpolated="1">
<entry color="green" threshold="0.00"/>
<entry color="red" threshold="0.01"/>
</colorScheme>
<colorScheme name="by NOx emissions" interpolated="1">
<entry color="green" threshold="0.00"/>
<entry color="red" threshold="0.12"/>
</colorScheme>
<colorScheme name="by HC emissions" interpolated="1">
<entry color="green" threshold="0.00"/>
<entry color="red" threshold="0.02"/>
</colorScheme>
<colorScheme name="by fuel consumption" interpolated="1">
<entry color="green" threshold="0.00"/>
<entry color="red" threshold="0.01"/>
</colorScheme>
<colorScheme name="by noise emissions (Harmonoise)" interpolated="1">
<entry color="green" threshold="0.00"/>
<entry color="red" threshold="100.00"/>
</colorScheme>
<colorScheme name="by reroute number" interpolated="1">
<entry color="red" threshold="0.00"/>
<entry color="yellow" threshold="1.00"/>
<entry color="white" threshold="10.00"/>
</colorScheme>
<colorScheme name="by selection">
<entry color="179,179,179" name="unselected"/>
<entry color="0,102,204" name="selected"/>
</colorScheme>
<colorScheme name="by offset from best lane" interpolated="1">
<entry color="magenta" threshold="-100.00" name="opposite lane"/>
<entry color="red" threshold="-3.00" name="-3"/>
<entry color="yellow" threshold="-1.00" name="-1"/>
<entry color="179,179,179" threshold="0.00" name="0"/>
<entry color="cyan" threshold="1.00" name="1"/>
<entry color="blue" threshold="3.00" name="3"/>
</colorScheme>
<colorScheme name="by acceleration" interpolated="1">
<entry color="64,0,0" threshold="-9.00"/>
<entry color="red" threshold="-4.50"/>
<entry color="yellow" threshold="-0.10"/>
<entry color="179,179,179" threshold="0.00" name="0"/>
<entry color="cyan" threshold="0.10"/>
<entry color="blue" threshold="2.60"/>
<entry color="magenta" threshold="5.20"/>
</colorScheme>
<colorScheme name="by time gap on lane" interpolated="1">
<entry color="179,179,179" threshold="-1.00"/>
<entry color="yellow" threshold="0.00" name="0"/>
<entry color="cyan" threshold="1.00"/>
<entry color="blue" threshold="2.00"/>
</colorScheme>
<colorScheme name="by depart delay" interpolated="1">
<entry color="blue" threshold="0.00"/>
<entry color="cyan" threshold="30.00"/>
<entry color="green" threshold="100.00"/>
<entry color="yellow" threshold="200.00"/>
<entry color="red" threshold="300.00"/>
</colorScheme>
<colorScheme name="by electricity consumption" interpolated="1">
<entry color="green" threshold="0.00"/>
<entry color="red" threshold="5.00"/>
</colorScheme>
<colorScheme name="by time loss" interpolated="1">
<entry color="blue" threshold="0.00"/>
<entry color="cyan" threshold="10.00"/>
<entry color="green" threshold="60.00"/>
<entry color="yellow" threshold="180.00"/>
<entry color="red" threshold="900.00"/>
</colorScheme>
<colorScheme name="by lateral speed" interpolated="1">
<entry color="red" threshold="-3.00" name="-1.5"/>
<entry color="yellow" threshold="-1.00" name="-0.5"/>
<entry color="179,179,179" threshold="0.00" name="0"/>
<entry color="cyan" threshold="1.00" name="0.5"/>
<entry color="blue" threshold="3.00" name="1.5"/>
</colorScheme>
<colorScheme name="random">
<entry color="yellow"/>
</colorScheme>
<colorScheme name="by param (numerical)" interpolated="1">
<entry color="204,204,204" threshold="0.00"/>
</colorScheme>
</vehicles>
<persons personMode="0" personQuality="3" person_minSize="1.00" person_exaggeration="1.00" person_constantSize="0" person_constantSizeSelected="0"
personName_show="0" personName_size="60.00" personName_color="0,153,204" personName_bgColor="128,0,0,0" personName_constantSize="1"
personValue_show="0" personValue_size="80.00" personValue_color="cyan" personValue_bgColor="128,0,0,0" personValue_constantSize="1">
<colorScheme name="given person/type color">
<entry color="blue"/>
</colorScheme>
<colorScheme name="uniform">
<entry color="blue"/>
</colorScheme>
<colorScheme name="given/assigned person color">
<entry color="blue"/>
</colorScheme>
<colorScheme name="given/assigned type color">
<entry color="blue"/>
</colorScheme>
<colorScheme name="by speed" interpolated="1">
<entry color="red" threshold="0.00"/>
<entry color="yellow" threshold="0.69"/>
<entry color="green" threshold="1.39"/>
<entry color="blue" threshold="2.78"/>
</colorScheme>
<colorScheme name="by mode">
<entry color="grey" name="waiting for insertion"/>
<entry color="red" name="stopped"/>
<entry color="green" name="walking"/>
<entry color="blue" name="riding"/>
<entry color="cyan" name="accessing trainStop"/>
<entry color="yellow" name="waiting for ride"/>
</colorScheme>
<colorScheme name="by waiting time" interpolated="1">
<entry color="blue" threshold="0.00"/>
<entry color="cyan" threshold="30.00"/>
<entry color="green" threshold="100.00"/>
<entry color="yellow" threshold="200.00"/>
<entry color="red" threshold="300.00"/>
</colorScheme>
<colorScheme name="by selection">
<entry color="179,179,179" name="unselected"/>
<entry color="0,102,204" name="selected"/>
</colorScheme>
<colorScheme name="by angle">
<entry color="yellow"/>
</colorScheme>
<colorScheme name="random">
<entry color="yellow"/>
</colorScheme>
</persons>
<containers containerMode="0" containerQuality="0" container_minSize="1.00" container_exaggeration="1.00" container_constantSize="0" container_constantSizeSelected="0"
containerName_show="0" containerName_size="60.00" containerName_color="0,153,204" containerName_bgColor="128,0,0,0" containerName_constantSize="1">
<colorScheme name="given container/type color">
<entry color="yellow"/>
</colorScheme>
<colorScheme name="uniform">
<entry color="yellow"/>
</colorScheme>
<colorScheme name="given/assigned container color">
<entry color="yellow"/>
</colorScheme>
<colorScheme name="given/assigned type color">
<entry color="yellow"/>
</colorScheme>
<colorScheme name="by speed" interpolated="1">
<entry color="red" threshold="0.00"/>
<entry color="yellow" threshold="0.69"/>
<entry color="green" threshold="1.39"/>
<entry color="blue" threshold="2.78"/>
</colorScheme>
<colorScheme name="by mode">
<entry color="grey" name="waiting for insertion"/>
<entry color="red" name="stopped"/>
<entry color="green" name="tranship"/>
<entry color="blue" name="transport"/>
<entry color="cyan" name="accessing trainStop"/>
<entry color="yellow" name="waiting for transport"/>
</colorScheme>
<colorScheme name="by waiting time" interpolated="1">
<entry color="blue" threshold="0.00"/>
<entry color="cyan" threshold="30.00"/>
<entry color="green" threshold="100.00"/>
<entry color="yellow" threshold="200.00"/>
<entry color="red" threshold="300.00"/>
</colorScheme>
<colorScheme name="by selection">
<entry color="179,179,179" name="unselected"/>
<entry color="0,102,204" name="selected"/>
</colorScheme>
<colorScheme name="by angle">
<entry color="yellow"/>
</colorScheme>
</containers>
<junctions junctionMode="0"
drawLinkTLIndex_show="0" drawLinkTLIndex_size="50.00" drawLinkTLIndex_color="128,128,255" drawLinkTLIndex_bgColor="128,0,0,0" drawLinkTLIndex_constantSize="1"
drawLinkJunctionIndex_show="0" drawLinkJunctionIndex_size="50.00" drawLinkJunctionIndex_color="128,128,255" drawLinkJunctionIndex_bgColor="128,0,0,0" drawLinkJunctionIndex_constantSize="1"
junctionName_show="0" junctionName_size="60.00" junctionName_color="0,255,128" junctionName_bgColor="128,0,0,0" junctionName_constantSize="1"
internalJunctionName_show="0" internalJunctionName_size="50.00" internalJunctionName_color="0,204,128" internalJunctionName_bgColor="128,0,0,0" internalJunctionName_constantSize="1"
tlsPhaseIndex_show="0" tlsPhaseIndex_size="150.00" tlsPhaseIndex_color="yellow" tlsPhaseIndex_bgColor="128,0,0,0" tlsPhaseIndex_constantSize="1"
showLane2Lane="0" drawShape="1" drawCrossingsAndWalkingareas="1" junction_minSize="1.00" junction_exaggeration="1.00" junction_constantSize="0" junction_constantSizeSelected="0">
<colorScheme name="uniform">
<entry color="black"/>
<entry color="150,200,200" name="waterway"/>
<entry color="0,0,0,0" name="railway"/>
</colorScheme>
<colorScheme name="by selection">
<entry color="grey" name="unselected"/>
<entry color="0,80,180" name="selected"/>
</colorScheme>
<colorScheme name="by type">
<entry color="green" name="traffic_light"/>
<entry color="0,128,0" name="traffic_light_unregulated"/>
<entry color="yellow" name="priority"/>
<entry color="red" name="priority_stop"/>
<entry color="blue" name="right_before_left"/>
<entry color="cyan" name="allway_stop"/>
<entry color="grey" name="district"/>
<entry color="magenta" name="unregulated"/>
<entry color="black" name="dead_end"/>
<entry color="orange" name="rail_signal"/>
<entry color="172,108,44" name="zipper"/>
<entry color="192,255,192" name="traffic_light_right_on_red"/>
<entry color="128,0,128" name="rail_crossing"/>
</colorScheme>
<colorScheme name="by height" interpolated="1">
<entry color="blue" threshold="-10.00"/>
<entry color="grey" threshold="0.00"/>
<entry color="red" threshold="10.00"/>
<entry color="yellow" threshold="50.00"/>
<entry color="green" threshold="100.00"/>
<entry color="magenta" threshold="200.00"/>
</colorScheme>
</junctions>
<additionals addMode="0" add_minSize="1.00" add_exaggeration="1.00" add_constantSize="0" add_constantSizeSelected="0" addName_show="0" addName_size="60.00" addName_color="255,0,128" addName_bgColor="128,0,0,0" addName_constantSize="1" addFullName_show="0" addFullName_size="60.00" addFullName_color="255,0,128" addFullName_bgColor="128,0,0,0" addFullName_constantSize="1"/>
<pois poi_minSize="0.00" poi_exaggeration="1.00" poi_constantSize="0" poi_constantSizeSelected="0" poiName_show="0" poiName_size="50.00" poiName_color="255,0,128" poiName_bgColor="128,0,0,0" poiName_constantSize="1" poiType_show="0" poiType_size="60.00" poiType_color="255,0,128" poiType_bgColor="128,0,0,0" poiType_constantSize="1">
<colorScheme name="given POI color">
<entry color="red"/>
</colorScheme>
<colorScheme name="by selection">
<entry color="179,179,179" name="unselected"/>
<entry color="0,102,204" name="selected"/>
</colorScheme>
<colorScheme name="uniform">
<entry color="red"/>
</colorScheme>
</pois>
<polys poly_minSize="0.00" poly_exaggeration="1.00" poly_constantSize="0" poly_constantSizeSelected="0" polyName_show="0" polyName_size="50.00" polyName_color="255,0,128" polyName_bgColor="128,0,0,0" polyName_constantSize="1" polyType_show="0" polyType_size="60.00" polyType_color="255,0,128" polyType_bgColor="128,0,0,0" polyType_constantSize="1">
<colorScheme name="given polygon color">
<entry color="orange"/>
</colorScheme>
<colorScheme name="by selection">
<entry color="179,179,179" name="unselected"/>
<entry color="0,102,204" name="selected"/>
</colorScheme>
<colorScheme name="uniform">
<entry color="orange"/>
</colorScheme>
</polys>
<legend showSizeLegend="1" showColorLegend="0"/>
</scheme>
</viewsettings>

View File

@ -1 +0,0 @@
lxml==4.6.2

View File

@ -1,319 +0,0 @@
#!/usr/bin/env python
# Copyright (c) 2020 Computer Vision Center (CVC) at the Universitat Autonoma de
# Barcelona (UAB).
#
# This work is licensed under the terms of the MIT license.
# For a copy, see <https://opensource.org/licenses/MIT>.
"""
Script to integrate CARLA and SUMO simulations
"""
# ==================================================================================================
# -- imports ---------------------------------------------------------------------------------------
# ==================================================================================================
import argparse
import logging
import time
# ==================================================================================================
# -- find carla module -----------------------------------------------------------------------------
# ==================================================================================================
import glob
import os
import sys
try:
sys.path.append(
glob.glob('../../PythonAPI/carla/dist/carla-*%d.%d-%s.egg' %
(sys.version_info.major, sys.version_info.minor,
'win-amd64' if os.name == 'nt' else 'linux-x86_64'))[0])
except IndexError:
pass
# ==================================================================================================
# -- find traci module -----------------------------------------------------------------------------
# ==================================================================================================
if 'SUMO_HOME' in os.environ:
sys.path.append(os.path.join(os.environ['SUMO_HOME'], 'tools'))
else:
sys.exit("please declare environment variable 'SUMO_HOME'")
# ==================================================================================================
# -- sumo integration imports ----------------------------------------------------------------------
# ==================================================================================================
from sumo_integration.bridge_helper import BridgeHelper # pylint: disable=wrong-import-position
from sumo_integration.carla_simulation import CarlaSimulation # pylint: disable=wrong-import-position
from sumo_integration.constants import INVALID_ACTOR_ID # pylint: disable=wrong-import-position
from sumo_integration.sumo_simulation import SumoSimulation # pylint: disable=wrong-import-position
# ==================================================================================================
# -- synchronization_loop --------------------------------------------------------------------------
# ==================================================================================================
class SimulationSynchronization(object):
"""
SimulationSynchronization class is responsible for the synchronization of sumo and carla
simulations.
"""
def __init__(self,
sumo_simulation,
carla_simulation,
tls_manager='none',
sync_vehicle_color=False,
sync_vehicle_lights=False):
self.sumo = sumo_simulation
self.carla = carla_simulation
self.tls_manager = tls_manager
self.sync_vehicle_color = sync_vehicle_color
self.sync_vehicle_lights = sync_vehicle_lights
if tls_manager == 'carla':
self.sumo.switch_off_traffic_lights()
elif tls_manager == 'sumo':
self.carla.switch_off_traffic_lights()
# Mapped actor ids.
self.sumo2carla_ids = {} # Contains only actors controlled by sumo.
self.carla2sumo_ids = {} # Contains only actors controlled by carla.
BridgeHelper.blueprint_library = self.carla.world.get_blueprint_library()
BridgeHelper.offset = self.sumo.get_net_offset()
# Configuring carla simulation in sync mode.
settings = self.carla.world.get_settings()
settings.synchronous_mode = True
settings.fixed_delta_seconds = self.carla.step_length
self.carla.world.apply_settings(settings)
traffic_manager = self.carla.client.get_trafficmanager()
traffic_manager.set_synchronous_mode(True)
def tick(self):
"""
Tick to simulation synchronization
"""
# -----------------
# sumo-->carla sync
# -----------------
self.sumo.tick()
# Spawning new sumo actors in carla (i.e, not controlled by carla).
sumo_spawned_actors = self.sumo.spawned_actors - set(self.carla2sumo_ids.values())
for sumo_actor_id in sumo_spawned_actors:
self.sumo.subscribe(sumo_actor_id)
sumo_actor = self.sumo.get_actor(sumo_actor_id)
carla_blueprint = BridgeHelper.get_carla_blueprint(sumo_actor, self.sync_vehicle_color)
if carla_blueprint is not None:
carla_transform = BridgeHelper.get_carla_transform(sumo_actor.transform,
sumo_actor.extent)
carla_actor_id = self.carla.spawn_actor(carla_blueprint, carla_transform)
if carla_actor_id != INVALID_ACTOR_ID:
self.sumo2carla_ids[sumo_actor_id] = carla_actor_id
else:
self.sumo.unsubscribe(sumo_actor_id)
# Destroying sumo arrived actors in carla.
for sumo_actor_id in self.sumo.destroyed_actors:
if sumo_actor_id in self.sumo2carla_ids:
self.carla.destroy_actor(self.sumo2carla_ids.pop(sumo_actor_id))
# Updating sumo actors in carla.
for sumo_actor_id in self.sumo2carla_ids:
carla_actor_id = self.sumo2carla_ids[sumo_actor_id]
sumo_actor = self.sumo.get_actor(sumo_actor_id)
carla_actor = self.carla.get_actor(carla_actor_id)
carla_transform = BridgeHelper.get_carla_transform(sumo_actor.transform,
sumo_actor.extent)
if self.sync_vehicle_lights:
carla_lights = BridgeHelper.get_carla_lights_state(carla_actor.get_light_state(),
sumo_actor.signals)
else:
carla_lights = None
self.carla.synchronize_vehicle(carla_actor_id, carla_transform, carla_lights)
# Updates traffic lights in carla based on sumo information.
if self.tls_manager == 'sumo':
common_landmarks = self.sumo.traffic_light_ids & self.carla.traffic_light_ids
for landmark_id in common_landmarks:
sumo_tl_state = self.sumo.get_traffic_light_state(landmark_id)
carla_tl_state = BridgeHelper.get_carla_traffic_light_state(sumo_tl_state)
self.carla.synchronize_traffic_light(landmark_id, carla_tl_state)
# -----------------
# carla-->sumo sync
# -----------------
self.carla.tick()
# Spawning new carla actors (not controlled by sumo)
carla_spawned_actors = self.carla.spawned_actors - set(self.sumo2carla_ids.values())
for carla_actor_id in carla_spawned_actors:
carla_actor = self.carla.get_actor(carla_actor_id)
type_id = BridgeHelper.get_sumo_vtype(carla_actor)
color = carla_actor.attributes.get('color', None) if self.sync_vehicle_color else None
if type_id is not None:
sumo_actor_id = self.sumo.spawn_actor(type_id, color)
if sumo_actor_id != INVALID_ACTOR_ID:
self.carla2sumo_ids[carla_actor_id] = sumo_actor_id
self.sumo.subscribe(sumo_actor_id)
# Destroying required carla actors in sumo.
for carla_actor_id in self.carla.destroyed_actors:
if carla_actor_id in self.carla2sumo_ids:
self.sumo.destroy_actor(self.carla2sumo_ids.pop(carla_actor_id))
# Updating carla actors in sumo.
for carla_actor_id in self.carla2sumo_ids:
sumo_actor_id = self.carla2sumo_ids[carla_actor_id]
carla_actor = self.carla.get_actor(carla_actor_id)
sumo_actor = self.sumo.get_actor(sumo_actor_id)
sumo_transform = BridgeHelper.get_sumo_transform(carla_actor.get_transform(),
carla_actor.bounding_box.extent)
if self.sync_vehicle_lights:
carla_lights = self.carla.get_actor_light_state(carla_actor_id)
if carla_lights is not None:
sumo_lights = BridgeHelper.get_sumo_lights_state(sumo_actor.signals,
carla_lights)
else:
sumo_lights = None
else:
sumo_lights = None
self.sumo.synchronize_vehicle(sumo_actor_id, sumo_transform, sumo_lights)
# Updates traffic lights in sumo based on carla information.
if self.tls_manager == 'carla':
common_landmarks = self.sumo.traffic_light_ids & self.carla.traffic_light_ids
for landmark_id in common_landmarks:
carla_tl_state = self.carla.get_traffic_light_state(landmark_id)
sumo_tl_state = BridgeHelper.get_sumo_traffic_light_state(carla_tl_state)
# Updates all the sumo links related to this landmark.
self.sumo.synchronize_traffic_light(landmark_id, sumo_tl_state)
def close(self):
"""
Cleans synchronization.
"""
# Configuring carla simulation in async mode.
settings = self.carla.world.get_settings()
settings.synchronous_mode = False
settings.fixed_delta_seconds = None
self.carla.world.apply_settings(settings)
# Destroying synchronized actors.
for carla_actor_id in self.sumo2carla_ids.values():
self.carla.destroy_actor(carla_actor_id)
for sumo_actor_id in self.carla2sumo_ids.values():
self.sumo.destroy_actor(sumo_actor_id)
# Closing sumo and carla client.
self.carla.close()
self.sumo.close()
def synchronization_loop(args):
"""
Entry point for sumo-carla co-simulation.
"""
sumo_simulation = SumoSimulation(args.sumo_cfg_file, args.step_length, args.sumo_host,
args.sumo_port, args.sumo_gui, args.client_order)
carla_simulation = CarlaSimulation(args.carla_host, args.carla_port, args.step_length)
synchronization = SimulationSynchronization(sumo_simulation, carla_simulation, args.tls_manager,
args.sync_vehicle_color, args.sync_vehicle_lights)
try:
while True:
start = time.time()
synchronization.tick()
end = time.time()
elapsed = end - start
if elapsed < args.step_length:
time.sleep(args.step_length - elapsed)
except KeyboardInterrupt:
logging.info('Cancelled by user.')
finally:
logging.info('Cleaning synchronization')
synchronization.close()
if __name__ == '__main__':
argparser = argparse.ArgumentParser(description=__doc__)
argparser.add_argument('sumo_cfg_file', type=str, help='sumo configuration file')
argparser.add_argument('--carla-host',
metavar='H',
default='127.0.0.1',
help='IP of the carla host server (default: 127.0.0.1)')
argparser.add_argument('--carla-port',
metavar='P',
default=2000,
type=int,
help='TCP port to listen to (default: 2000)')
argparser.add_argument('--sumo-host',
metavar='H',
default=None,
help='IP of the sumo host server (default: 127.0.0.1)')
argparser.add_argument('--sumo-port',
metavar='P',
default=None,
type=int,
help='TCP port to listen to (default: 8813)')
argparser.add_argument('--sumo-gui', action='store_true', help='run the gui version of sumo')
argparser.add_argument('--step-length',
default=0.05,
type=float,
help='set fixed delta seconds (default: 0.05s)')
argparser.add_argument('--client-order',
metavar='TRACI_CLIENT_ORDER',
default=1,
type=int,
help='client order number for the co-simulation TraCI connection (default: 1)')
argparser.add_argument('--sync-vehicle-lights',
action='store_true',
help='synchronize vehicle lights state (default: False)')
argparser.add_argument('--sync-vehicle-color',
action='store_true',
help='synchronize vehicle color (default: False)')
argparser.add_argument('--sync-vehicle-all',
action='store_true',
help='synchronize all vehicle properties (default: False)')
argparser.add_argument('--tls-manager',
type=str,
choices=['none', 'sumo', 'carla'],
help="select traffic light manager (default: none)",
default='none')
argparser.add_argument('--debug', action='store_true', help='enable debug messages')
arguments = argparser.parse_args()
if arguments.sync_vehicle_all is True:
arguments.sync_vehicle_lights = True
arguments.sync_vehicle_color = True
if arguments.debug:
logging.basicConfig(format='%(levelname)s: %(message)s', level=logging.DEBUG)
else:
logging.basicConfig(format='%(levelname)s: %(message)s', level=logging.INFO)
synchronization_loop(arguments)

View File

@ -1,300 +0,0 @@
#!/usr/bin/env python
# Copyright (c) 2020 Computer Vision Center (CVC) at the Universitat Autonoma de
# Barcelona (UAB).
#
# This work is licensed under the terms of the MIT license.
# For a copy, see <https://opensource.org/licenses/MIT>.
"""Spawn Sumo NPCs vehicles into the simulation"""
# ==================================================================================================
# -- imports ---------------------------------------------------------------------------------------
# ==================================================================================================
import argparse
import json
import logging
import random
import re
import shutil
import tempfile
import time
import lxml.etree as ET # pylint: disable=wrong-import-position
# ==================================================================================================
# -- find carla module -----------------------------------------------------------------------------
# ==================================================================================================
import glob
import os
import sys
try:
sys.path.append(
glob.glob('../../PythonAPI/carla/dist/carla-*%d.%d-%s.egg' %
(sys.version_info.major, sys.version_info.minor,
'win-amd64' if os.name == 'nt' else 'linux-x86_64'))[0])
except IndexError:
pass
# ==================================================================================================
# -- find traci module -----------------------------------------------------------------------------
# ==================================================================================================
if 'SUMO_HOME' in os.environ:
sys.path.append(os.path.join(os.environ['SUMO_HOME'], 'tools'))
else:
sys.exit("please declare environment variable 'SUMO_HOME'")
# ==================================================================================================
# -- imports ---------------------------------------------------------------------------------------
# ==================================================================================================
import sumolib # pylint: disable=wrong-import-position
import traci # pylint: disable=wrong-import-position
from sumo_integration.carla_simulation import CarlaSimulation # pylint: disable=wrong-import-position
from sumo_integration.sumo_simulation import SumoSimulation # pylint: disable=wrong-import-position
from run_synchronization import SimulationSynchronization # pylint: disable=wrong-import-position
from util.netconvert_carla import netconvert_carla
# ==================================================================================================
# -- main ------------------------------------------------------------------------------------------
# ==================================================================================================
def write_sumocfg_xml(cfg_file, net_file, vtypes_file, viewsettings_file, additional_traci_clients=0):
"""
Writes sumo configuration xml file.
"""
root = ET.Element('configuration')
input_tag = ET.SubElement(root, 'input')
ET.SubElement(input_tag, 'net-file', {'value': net_file})
ET.SubElement(input_tag, 'route-files', {'value': vtypes_file})
gui_tag = ET.SubElement(root, 'gui_only')
ET.SubElement(gui_tag, 'gui-settings-file', {'value': viewsettings_file})
ET.SubElement(root, 'num-clients', {'value': str(additional_traci_clients+1)})
tree = ET.ElementTree(root)
tree.write(cfg_file, pretty_print=True, encoding='UTF-8', xml_declaration=True)
def main(args):
# Temporal folder to save intermediate files.
tmpdir = tempfile.mkdtemp()
# ----------------
# carla simulation
# ----------------
carla_simulation = CarlaSimulation(args.host, args.port, args.step_length)
world = carla_simulation.client.get_world()
current_map = world.get_map()
xodr_file = os.path.join(tmpdir, current_map.name + '.xodr')
current_map.save_to_disk(xodr_file)
# ---------------
# sumo simulation
# ---------------
net_file = os.path.join(tmpdir, current_map.name + '.net.xml')
netconvert_carla(xodr_file, net_file, guess_tls=True)
basedir = os.path.dirname(os.path.realpath(__file__))
cfg_file = os.path.join(tmpdir, current_map.name + '.sumocfg')
vtypes_file = os.path.join(basedir, 'examples', 'carlavtypes.rou.xml')
viewsettings_file = os.path.join(basedir, 'examples', 'viewsettings.xml')
write_sumocfg_xml(cfg_file, net_file, vtypes_file, viewsettings_file, args.additional_traci_clients)
sumo_net = sumolib.net.readNet(net_file)
sumo_simulation = SumoSimulation(cfg_file,
args.step_length,
host=args.sumo_host,
port=args.sumo_port,
sumo_gui=args.sumo_gui,
client_order=args.client_order)
# ---------------
# synchronization
# ---------------
synchronization = SimulationSynchronization(sumo_simulation, carla_simulation, args.tls_manager,
args.sync_vehicle_color, args.sync_vehicle_lights)
try:
# ----------
# Blueprints
# ----------
with open('data/vtypes.json') as f:
vtypes = json.load(f)['carla_blueprints']
blueprints = vtypes.keys()
filterv = re.compile(args.filterv)
blueprints = list(filter(filterv.search, blueprints))
if args.safe:
blueprints = [
x for x in blueprints if vtypes[x]['vClass'] not in ('motorcycle', 'bicycle')
]
blueprints = [x for x in blueprints if not x.endswith('microlino')]
blueprints = [x for x in blueprints if not x.endswith('carlacola')]
blueprints = [x for x in blueprints if not x.endswith('cybertruck')]
blueprints = [x for x in blueprints if not x.endswith('t2')]
blueprints = [x for x in blueprints if not x.endswith('sprinter')]
blueprints = [x for x in blueprints if not x.endswith('firetruck')]
blueprints = [x for x in blueprints if not x.endswith('ambulance')]
if not blueprints:
raise RuntimeError('No blueprints available due to user restrictions.')
if args.number_of_walkers > 0:
logging.warning('Pedestrians are not supported yet. No walkers will be spawned.')
# --------------
# Spawn vehicles
# --------------
# Spawns sumo NPC vehicles.
sumo_edges = sumo_net.getEdges()
for i in range(args.number_of_vehicles):
type_id = random.choice(blueprints)
vclass = vtypes[type_id]['vClass']
allowed_edges = [e for e in sumo_edges if e.allows(vclass)]
if allowed_edges:
edge = random.choice(allowed_edges)
traci.route.add('route_{}'.format(i), [edge.getID()])
traci.vehicle.add('sumo_{}'.format(i), 'route_{}'.format(i), typeID=type_id)
else:
logging.error(
'Could not found a route for %s. No vehicle will be spawned in sumo',
type_id)
while True:
start = time.time()
synchronization.tick()
# Updates vehicle routes
for vehicle_id in traci.vehicle.getIDList():
route = traci.vehicle.getRoute(vehicle_id)
index = traci.vehicle.getRouteIndex(vehicle_id)
vclass = traci.vehicle.getVehicleClass(vehicle_id)
if index == (len(route) - 1):
current_edge = sumo_net.getEdge(route[index])
available_edges = list(current_edge.getAllowedOutgoing(vclass).keys())
if available_edges:
next_edge = random.choice(available_edges)
new_route = [current_edge.getID(), next_edge.getID()]
traci.vehicle.setRoute(vehicle_id, new_route)
end = time.time()
elapsed = end - start
if elapsed < args.step_length:
time.sleep(args.step_length - elapsed)
except KeyboardInterrupt:
logging.info('Cancelled by user.')
finally:
synchronization.close()
if os.path.exists(tmpdir):
shutil.rmtree(tmpdir)
if __name__ == '__main__':
argparser = argparse.ArgumentParser(description=__doc__)
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('--sumo-host',
default=None,
help='IP of the sumo host server (default: None)')
argparser.add_argument('--sumo-port',
default=None,
type=int,
help='TCP port to listen to (default: None)')
argparser.add_argument('-n',
'--number-of-vehicles',
metavar='N',
default=10,
type=int,
help='number of vehicles (default: 10)')
argparser.add_argument('-w',
'--number-of-walkers',
metavar='W',
default=0,
type=int,
help='number of walkers (default: 0)')
argparser.add_argument('--safe',
action='store_true',
help='avoid spawning vehicles prone to accidents')
argparser.add_argument('--filterv',
metavar='PATTERN',
default='vehicle.*',
help='vehicles filter (default: "vehicle.*")')
argparser.add_argument('--filterw',
metavar='PATTERN',
default='walker.pedestrian.*',
help='pedestrians filter (default: "walker.pedestrian.*")')
argparser.add_argument('--sumo-gui', action='store_true', help='run the gui version of sumo')
argparser.add_argument('--step-length',
default=0.05,
type=float,
help='set fixed delta seconds (default: 0.05s)')
argparser.add_argument('--additional-traci-clients',
metavar='TRACI_CLIENTS',
default=0,
type=int,
help='number of additional TraCI clients to wait for (default: 0)')
argparser.add_argument('--client-order',
metavar='TRACI_CLIENT_ORDER',
default=1,
type=int,
help='client order number for the co-simulation TraCI connection (default: 1)')
argparser.add_argument('--sync-vehicle-lights',
action='store_true',
help='synchronize vehicle lights state (default: False)')
argparser.add_argument('--sync-vehicle-color',
action='store_true',
help='synchronize vehicle color (default: False)')
argparser.add_argument('--sync-vehicle-all',
action='store_true',
help='synchronize all vehicle properties (default: False)')
argparser.add_argument('--tls-manager',
type=str,
choices=['none', 'sumo', 'carla'],
help="select traffic light manager (default: none)",
default='none')
argparser.add_argument('--debug', action='store_true', help='enable debug messages')
args = argparser.parse_args()
if args.sync_vehicle_all is True:
args.sync_vehicle_lights = True
args.sync_vehicle_color = True
if args.debug:
logging.basicConfig(format='%(levelname)s: %(message)s', level=logging.DEBUG)
else:
logging.basicConfig(format='%(levelname)s: %(message)s', level=logging.INFO)
main(args)

View File

@ -1,369 +0,0 @@
#!/usr/bin/env python
# Copyright (c) 2020 Computer Vision Center (CVC) at the Universitat Autonoma de
# Barcelona (UAB).
#
# This work is licensed under the terms of the MIT license.
# For a copy, see <https://opensource.org/licenses/MIT>.
""" This module provides a helper for the co-simulation between sumo and carla ."""
# ==================================================================================================
# -- imports ---------------------------------------------------------------------------------------
# ==================================================================================================
import json
import logging
import math
import os
import random
import carla # pylint: disable=import-error
import traci # pylint: disable=import-error
from .sumo_simulation import SumoSignalState, SumoVehSignal
# ==================================================================================================
# -- Bridge helper (SUMO <=> CARLA) ----------------------------------------------------------------
# ==================================================================================================
class BridgeHelper(object):
"""
BridgeHelper provides methos to ease the co-simulation between sumo and carla.
"""
blueprint_library = []
offset = (0, 0)
_vtypes_path = os.path.join(os.path.dirname(os.path.realpath(__file__)), "..", "data",
"vtypes.json")
with open(_vtypes_path) as f:
_VTYPES = json.load(f)['carla_blueprints']
@staticmethod
def get_carla_transform(in_sumo_transform, extent):
"""
Returns carla transform based on sumo transform.
"""
offset = BridgeHelper.offset
in_location = in_sumo_transform.location
in_rotation = in_sumo_transform.rotation
# From front-center-bumper to center (sumo reference system).
# (http://sumo.sourceforge.net/userdoc/Purgatory/Vehicle_Values.html#angle)
yaw = -1 * in_rotation.yaw + 90
pitch = in_rotation.pitch
out_location = (in_location.x - math.cos(math.radians(yaw)) * extent.x,
in_location.y - math.sin(math.radians(yaw)) * extent.x,
in_location.z - math.sin(math.radians(pitch)) * extent.x)
out_rotation = (in_rotation.pitch, in_rotation.yaw, in_rotation.roll)
# Applying offset sumo-carla net.
out_location = (out_location[0] - offset[0], out_location[1] - offset[1], out_location[2])
# Transform to carla reference system (left-handed system).
out_transform = carla.Transform(
carla.Location(out_location[0], -out_location[1], out_location[2]),
carla.Rotation(out_rotation[0], out_rotation[1] - 90, out_rotation[2]))
return out_transform
@staticmethod
def get_sumo_transform(in_carla_transform, extent):
"""
Returns sumo transform based on carla transform.
"""
offset = BridgeHelper.offset
in_location = in_carla_transform.location
in_rotation = in_carla_transform.rotation
# From center to front-center-bumper (carla reference system).
yaw = -1 * in_rotation.yaw
pitch = in_rotation.pitch
out_location = (in_location.x + math.cos(math.radians(yaw)) * extent.x,
in_location.y - math.sin(math.radians(yaw)) * extent.x,
in_location.z - math.sin(math.radians(pitch)) * extent.x)
out_rotation = (in_rotation.pitch, in_rotation.yaw, in_rotation.roll)
# Applying offset carla-sumo net
out_location = (out_location[0] + offset[0], out_location[1] - offset[1], out_location[2])
# Transform to sumo reference system.
out_transform = carla.Transform(
carla.Location(out_location[0], -out_location[1], out_location[2]),
carla.Rotation(out_rotation[0], out_rotation[1] + 90, out_rotation[2]))
return out_transform
@staticmethod
def _get_recommended_carla_blueprint(sumo_actor):
"""
Returns an appropriate blueprint based on the given sumo actor.
"""
vclass = sumo_actor.vclass.value
blueprints = []
for blueprint in BridgeHelper.blueprint_library:
if blueprint.id in BridgeHelper._VTYPES and \
BridgeHelper._VTYPES[blueprint.id]['vClass'] == vclass:
blueprints.append(blueprint)
if not blueprints:
return None
return random.choice(blueprints)
@staticmethod
def get_carla_blueprint(sumo_actor, sync_color=False):
"""
Returns an appropriate blueprint based on the received sumo actor.
"""
blueprint_library = BridgeHelper.blueprint_library
type_id = sumo_actor.type_id
if type_id in [bp.id for bp in blueprint_library]:
blueprint = blueprint_library.filter(type_id)[0]
logging.debug('[BridgeHelper] sumo vtype %s found in carla blueprints', type_id)
else:
blueprint = BridgeHelper._get_recommended_carla_blueprint(sumo_actor)
if blueprint is not None:
logging.warning(
'sumo vtype %s not found in carla. The following blueprint will be used: %s',
type_id, blueprint.id)
else:
logging.error('sumo vtype %s not supported. No vehicle will be spawned in carla',
type_id)
return None
if blueprint.has_attribute('color'):
if sync_color:
color = "{},{},{}".format(sumo_actor.color[0], sumo_actor.color[1],
sumo_actor.color[2])
else:
color = random.choice(blueprint.get_attribute('color').recommended_values)
blueprint.set_attribute('color', color)
if blueprint.has_attribute('driver_id'):
driver_id = random.choice(blueprint.get_attribute('driver_id').recommended_values)
blueprint.set_attribute('driver_id', driver_id)
blueprint.set_attribute('role_name', 'sumo_driver')
logging.debug(
'''[BridgeHelper] sumo vtype %s will be spawned in carla with the following attributes:
\tblueprint: %s
\tcolor: %s''', type_id, blueprint.id,
sumo_actor.color if blueprint.has_attribute('color') else (-1, -1, -1))
return blueprint
@staticmethod
def _create_sumo_vtype(carla_actor):
"""
Creates an appropriate vtype based on the given carla_actor.
"""
type_id = carla_actor.type_id
attrs = carla_actor.attributes
extent = carla_actor.bounding_box.extent
if int(attrs['number_of_wheels']) == 2:
traci.vehicletype.copy('DEFAULT_BIKETYPE', type_id)
else:
traci.vehicletype.copy('DEFAULT_VEHTYPE', type_id)
if type_id in BridgeHelper._VTYPES:
if 'vClass' in BridgeHelper._VTYPES[type_id]:
_class = BridgeHelper._VTYPES[type_id]['vClass']
traci.vehicletype.setVehicleClass(type_id, _class)
if 'guiShape' in BridgeHelper._VTYPES[type_id]:
shape = BridgeHelper._VTYPES[type_id]['guiShape']
traci.vehicletype.setShapeClass(type_id, shape)
if 'color' in attrs:
color = attrs['color'].split(',')
traci.vehicletype.setColor(type_id, color)
traci.vehicletype.setLength(type_id, 2.0 * extent.x)
traci.vehicletype.setWidth(type_id, 2.0 * extent.y)
traci.vehicletype.setHeight(type_id, 2.0 * extent.z)
logging.debug(
'''[BridgeHelper] blueprint %s not found in sumo vtypes
\tdefault vtype: %s
\tvtype: %s
\tclass: %s
\tshape: %s
\tcolor: %s
\tlenght: %s
\twidth: %s
\theight: %s''', type_id,
'DEFAULT_BIKETYPE' if int(attrs['number_of_wheels']) == 2 else 'DEFAULT_VEHTYPE',
type_id, traci.vehicletype.getVehicleClass(type_id),
traci.vehicletype.getShapeClass(type_id), traci.vehicletype.getColor(type_id),
traci.vehicletype.getLength(type_id), traci.vehicletype.getWidth(type_id),
traci.vehicletype.getHeight(type_id))
return type_id
@staticmethod
def get_sumo_vtype(carla_actor):
"""
Returns an appropriate vtype based on the type id and attributes.
"""
type_id = carla_actor.type_id
if not type_id.startswith('vehicle'):
logging.error(
'[BridgeHelper] Blueprint %s not supported. No vehicle will be spawned in sumo',
type_id)
return None
if type_id in traci.vehicletype.getIDList():
logging.debug('[BridgeHelper] blueprint %s found in sumo vtypes', type_id)
return type_id
return BridgeHelper._create_sumo_vtype(carla_actor)
@staticmethod
def get_carla_lights_state(current_carla_lights, sumo_lights):
"""
Returns carla vehicle light state based on sumo signals.
"""
current_lights = current_carla_lights
# Blinker right / emergency.
if (any([
bool(sumo_lights & SumoVehSignal.BLINKER_RIGHT),
bool(sumo_lights & SumoVehSignal.BLINKER_EMERGENCY)
]) != bool(current_lights & carla.VehicleLightState.RightBlinker)):
current_lights ^= carla.VehicleLightState.RightBlinker
# Blinker left / emergency.
if (any([
bool(sumo_lights & SumoVehSignal.BLINKER_LEFT),
bool(sumo_lights & SumoVehSignal.BLINKER_EMERGENCY)
]) != bool(current_lights & carla.VehicleLightState.LeftBlinker)):
current_lights ^= carla.VehicleLightState.LeftBlinker
# Break.
if (bool(sumo_lights & SumoVehSignal.BRAKELIGHT) !=
bool(current_lights & carla.VehicleLightState.Brake)):
current_lights ^= carla.VehicleLightState.Brake
# Front (low beam).
if (bool(sumo_lights & SumoVehSignal.FRONTLIGHT) !=
bool(current_lights & carla.VehicleLightState.LowBeam)):
current_lights ^= carla.VehicleLightState.LowBeam
# Fog.
if (bool(sumo_lights & SumoVehSignal.FOGLIGHT) !=
bool(current_lights & carla.VehicleLightState.Fog)):
current_lights ^= carla.VehicleLightState.Fog
# High beam.
if (bool(sumo_lights & SumoVehSignal.HIGHBEAM) !=
bool(current_lights & carla.VehicleLightState.HighBeam)):
current_lights ^= carla.VehicleLightState.HighBeam
# Backdrive (reverse).
if (bool(sumo_lights & SumoVehSignal.BACKDRIVE) !=
bool(current_lights & carla.VehicleLightState.Reverse)):
current_lights ^= carla.VehicleLightState.Reverse
# Door open left/right.
if (any([
bool(sumo_lights & SumoVehSignal.DOOR_OPEN_LEFT),
bool(sumo_lights & SumoVehSignal.DOOR_OPEN_RIGHT)
]) != bool(current_lights & carla.VehicleLightState.Position)):
current_lights ^= carla.VehicleLightState.Position
return current_lights
@staticmethod
def get_sumo_lights_state(current_sumo_lights, carla_lights):
"""
Returns sumo signals based on carla vehicle light state.
"""
current_lights = current_sumo_lights
# Blinker right.
if (bool(carla_lights & carla.VehicleLightState.RightBlinker) !=
bool(current_lights & SumoVehSignal.BLINKER_RIGHT)):
current_lights ^= SumoVehSignal.BLINKER_RIGHT
# Blinker left.
if (bool(carla_lights & carla.VehicleLightState.LeftBlinker) !=
bool(current_lights & SumoVehSignal.BLINKER_LEFT)):
current_lights ^= SumoVehSignal.BLINKER_LEFT
# Emergency.
if (all([
bool(carla_lights & carla.VehicleLightState.RightBlinker),
bool(carla_lights & carla.VehicleLightState.LeftBlinker)
]) != (current_lights & SumoVehSignal.BLINKER_EMERGENCY)):
current_lights ^= SumoVehSignal.BLINKER_EMERGENCY
# Break.
if (bool(carla_lights & carla.VehicleLightState.Brake) !=
bool(current_lights & SumoVehSignal.BRAKELIGHT)):
current_lights ^= SumoVehSignal.BRAKELIGHT
# Front (low beam)
if (bool(carla_lights & carla.VehicleLightState.LowBeam) !=
bool(current_lights & SumoVehSignal.FRONTLIGHT)):
current_lights ^= SumoVehSignal.FRONTLIGHT
# Fog light.
if (bool(carla_lights & carla.VehicleLightState.Fog) !=
bool(current_lights & SumoVehSignal.FOGLIGHT)):
current_lights ^= SumoVehSignal.FOGLIGHT
# High beam ligth.
if (bool(carla_lights & carla.VehicleLightState.HighBeam) !=
bool(current_lights & SumoVehSignal.HIGHBEAM)):
current_lights ^= SumoVehSignal.HIGHBEAM
# Backdrive (reverse)
if (bool(carla_lights & carla.VehicleLightState.Reverse) !=
bool(current_lights & SumoVehSignal.BACKDRIVE)):
current_lights ^= SumoVehSignal.BACKDRIVE
return current_lights
@staticmethod
def get_carla_traffic_light_state(sumo_tl_state):
"""
Returns carla traffic light state based on sumo traffic light state.
"""
if sumo_tl_state == SumoSignalState.RED or sumo_tl_state == SumoSignalState.RED_YELLOW:
return carla.TrafficLightState.Red
elif sumo_tl_state == SumoSignalState.YELLOW:
return carla.TrafficLightState.Yellow
elif sumo_tl_state == SumoSignalState.GREEN or \
sumo_tl_state == SumoSignalState.GREEN_WITHOUT_PRIORITY:
return carla.TrafficLightState.Green
elif sumo_tl_state == SumoSignalState.OFF:
return carla.TrafficLightState.Off
else: # SumoSignalState.GREEN_RIGHT_TURN and SumoSignalState.OFF_BLINKING
return carla.TrafficLightState.Unknown
@staticmethod
def get_sumo_traffic_light_state(carla_tl_state):
"""
Returns sumo traffic light state based on carla traffic light state.
"""
if carla_tl_state == carla.TrafficLightState.Red:
return SumoSignalState.RED
elif carla_tl_state == carla.TrafficLightState.Yellow:
return SumoSignalState.YELLOW
elif carla_tl_state == carla.TrafficLightState.Green:
return SumoSignalState.GREEN
else: # carla.TrafficLightState.Off and carla.TrafficLightState.Unknown
return SumoSignalState.OFF

View File

@ -1,184 +0,0 @@
#!/usr/bin/env python
# Copyright (c) 2020 Computer Vision Center (CVC) at the Universitat Autonoma de
# Barcelona (UAB).
#
# This work is licensed under the terms of the MIT license.
# For a copy, see <https://opensource.org/licenses/MIT>.
""" This module is responsible for the management of the carla simulation. """
# ==================================================================================================
# -- imports ---------------------------------------------------------------------------------------
# ==================================================================================================
import logging
import carla # pylint: disable=import-error
from .constants import INVALID_ACTOR_ID, SPAWN_OFFSET_Z
# ==================================================================================================
# -- carla simulation ------------------------------------------------------------------------------
# ==================================================================================================
class CarlaSimulation(object):
"""
CarlaSimulation is responsible for the management of the carla simulation.
"""
def __init__(self, host, port, step_length):
self.client = carla.Client(host, port)
self.client.set_timeout(2.0)
self.world = self.client.get_world()
self.blueprint_library = self.world.get_blueprint_library()
self.step_length = step_length
# The following sets contain updated information for the current frame.
self._active_actors = set()
self.spawned_actors = set()
self.destroyed_actors = set()
# Set traffic lights.
self._tls = {} # {landmark_id: traffic_ligth_actor}
tmp_map = self.world.get_map()
for landmark in tmp_map.get_all_landmarks_of_type('1000001'):
if landmark.id != '':
traffic_ligth = self.world.get_traffic_light(landmark)
if traffic_ligth is not None:
self._tls[landmark.id] = traffic_ligth
else:
logging.warning('Landmark %s is not linked to any traffic light', landmark.id)
def get_actor(self, actor_id):
"""
Accessor for carla actor.
"""
return self.world.get_actor(actor_id)
# This is a workaround to fix synchronization issues when other carla clients remove an actor in
# carla without waiting for tick (e.g., running sumo co-simulation and manual control at the
# same time)
def get_actor_light_state(self, actor_id):
"""
Accessor for carla actor light state.
If the actor is not alive, returns None.
"""
try:
actor = self.get_actor(actor_id)
return actor.get_light_state()
except RuntimeError:
return None
@property
def traffic_light_ids(self):
return set(self._tls.keys())
def get_traffic_light_state(self, landmark_id):
"""
Accessor for traffic light state.
If the traffic ligth does not exist, returns None.
"""
if landmark_id not in self._tls:
return None
return self._tls[landmark_id].state
def switch_off_traffic_lights(self):
"""
Switch off all traffic lights.
"""
for actor in self.world.get_actors():
if actor.type_id == 'traffic.traffic_light':
actor.freeze(True)
# We set the traffic light to 'green' because 'off' state sets the traffic light to
# 'red'.
actor.set_state(carla.TrafficLightState.Green)
def spawn_actor(self, blueprint, transform):
"""
Spawns a new actor.
:param blueprint: blueprint of the actor to be spawned.
:param transform: transform where the actor will be spawned.
:return: actor id if the actor is successfully spawned. Otherwise, INVALID_ACTOR_ID.
"""
transform = carla.Transform(transform.location + carla.Location(0, 0, SPAWN_OFFSET_Z),
transform.rotation)
batch = [
carla.command.SpawnActor(blueprint, transform).then(
carla.command.SetSimulatePhysics(carla.command.FutureActor, False))
]
response = self.client.apply_batch_sync(batch, False)[0]
if response.error:
logging.error('Spawn carla actor failed. %s', response.error)
return INVALID_ACTOR_ID
return response.actor_id
def destroy_actor(self, actor_id):
"""
Destroys the given actor.
"""
actor = self.world.get_actor(actor_id)
if actor is not None:
return actor.destroy()
return False
def synchronize_vehicle(self, vehicle_id, transform, lights=None):
"""
Updates vehicle state.
:param vehicle_id: id of the actor to be updated.
:param transform: new vehicle transform (i.e., position and rotation).
:param lights: new vehicle light state.
:return: True if successfully updated. Otherwise, False.
"""
vehicle = self.world.get_actor(vehicle_id)
if vehicle is None:
return False
vehicle.set_transform(transform)
if lights is not None:
vehicle.set_light_state(carla.VehicleLightState(lights))
return True
def synchronize_traffic_light(self, landmark_id, state):
"""
Updates traffic light state.
:param landmark_id: id of the landmark to be updated.
:param state: new traffic light state.
:return: True if successfully updated. Otherwise, False.
"""
if not landmark_id in self._tls:
logging.warning('Landmark %s not found in carla', landmark_id)
return False
traffic_light = self._tls[landmark_id]
traffic_light.set_state(state)
return True
def tick(self):
"""
Tick to carla simulation.
"""
self.world.tick()
# Update data structures for the current frame.
current_actors = set(
[vehicle.id for vehicle in self.world.get_actors().filter('vehicle.*')])
self.spawned_actors = current_actors.difference(self._active_actors)
self.destroyed_actors = self._active_actors.difference(current_actors)
self._active_actors = current_actors
def close(self):
"""
Closes carla client.
"""
for actor in self.world.get_actors():
if actor.type_id == 'traffic.traffic_light':
actor.freeze(False)

View File

@ -1,15 +0,0 @@
#!/usr/bin/env python
# Copyright (c) 2020 Computer Vision Center (CVC) at the Universitat Autonoma de
# Barcelona (UAB).
#
# This work is licensed under the terms of the MIT license.
# For a copy, see <https://opensource.org/licenses/MIT>.
""" This module defines constants used for the sumo-carla co-simulation. """
# ==================================================================================================
# -- constants -------------------------------------------------------------------------------------
# ==================================================================================================
INVALID_ACTOR_ID = -1
SPAWN_OFFSET_Z = 25.0 # meters

View File

@ -1,517 +0,0 @@
#!/usr/bin/env python
# Copyright (c) 2020 Computer Vision Center (CVC) at the Universitat Autonoma de
# Barcelona (UAB).
#
# This work is licensed under the terms of the MIT license.
# For a copy, see <https://opensource.org/licenses/MIT>.
""" This module is responsible for the management of the sumo simulation. """
# ==================================================================================================
# -- imports ---------------------------------------------------------------------------------------
# ==================================================================================================
import collections
import enum
import logging
import os
import carla # pylint: disable=import-error
import sumolib # pylint: disable=import-error
import traci # pylint: disable=import-error
from .constants import INVALID_ACTOR_ID
import lxml.etree as ET # pylint: disable=import-error
# ==================================================================================================
# -- sumo definitions ------------------------------------------------------------------------------
# ==================================================================================================
# https://sumo.dlr.de/docs/Simulation/Traffic_Lights.html#signal_state_definitions
class SumoSignalState(object):
"""
SumoSignalState contains the different traffic light states.
"""
RED = 'r'
YELLOW = 'y'
GREEN = 'G'
GREEN_WITHOUT_PRIORITY = 'g'
GREEN_RIGHT_TURN = 's'
RED_YELLOW = 'u'
OFF_BLINKING = 'o'
OFF = 'O'
# https://sumo.dlr.de/docs/TraCI/Vehicle_Signalling.html
class SumoVehSignal(object):
"""
SumoVehSignal contains the different sumo vehicle signals.
"""
BLINKER_RIGHT = 1 << 0
BLINKER_LEFT = 1 << 1
BLINKER_EMERGENCY = 1 << 2
BRAKELIGHT = 1 << 3
FRONTLIGHT = 1 << 4
FOGLIGHT = 1 << 5
HIGHBEAM = 1 << 6
BACKDRIVE = 1 << 7
WIPER = 1 << 8
DOOR_OPEN_LEFT = 1 << 9
DOOR_OPEN_RIGHT = 1 << 10
EMERGENCY_BLUE = 1 << 11
EMERGENCY_RED = 1 << 12
EMERGENCY_YELLOW = 1 << 13
# https://sumo.dlr.de/docs/Definition_of_Vehicles,_Vehicle_Types,_and_Routes.html#abstract_vehicle_class
class SumoActorClass(enum.Enum):
"""
SumoActorClass enumerates the different sumo actor classes.
"""
IGNORING = "ignoring"
PRIVATE = "private"
EMERGENCY = "emergency"
AUTHORITY = "authority"
ARMY = "army"
VIP = "vip"
PEDESTRIAN = "pedestrian"
PASSENGER = "passenger"
HOV = "hov"
TAXI = "taxi"
BUS = "bus"
COACH = "coach"
DELIVERY = "delivery"
TRUCK = "truck"
TRAILER = "trailer"
MOTORCYCLE = "motorcycle"
MOPED = "moped"
BICYCLE = "bicycle"
EVEHICLE = "evehicle"
TRAM = "tram"
RAIL_URBAN = "rail_urban"
RAIL = "rail"
RAIL_ELECTRIC = "rail_electric"
RAIL_FAST = "rail_fast"
SHIP = "ship"
CUSTOM1 = "custom1"
CUSTOM2 = "custom2"
SumoActor = collections.namedtuple('SumoActor', 'type_id vclass transform signals extent color')
# ==================================================================================================
# -- sumo traffic lights ---------------------------------------------------------------------------
# ==================================================================================================
class SumoTLLogic(object):
"""
SumoTLLogic holds the data relative to a traffic light in sumo.
"""
def __init__(self, tlid, states, parameters):
self.tlid = tlid
self.states = states
self._landmark2link = {}
self._link2landmark = {}
for link_index, landmark_id in parameters.items():
# Link index information is added in the parameter as 'linkSignalID:x'
link_index = int(link_index.split(':')[1])
if landmark_id not in self._landmark2link:
self._landmark2link[landmark_id] = []
self._landmark2link[landmark_id].append((tlid, link_index))
self._link2landmark[(tlid, link_index)] = landmark_id
def get_number_signals(self):
"""
Returns number of internal signals of the traffic light.
"""
if len(self.states) > 0:
return len(self.states[0])
return 0
def get_all_signals(self):
"""
Returns all the signals of the traffic light.
:returns list: [(tlid, link_index), (tlid, link_index), ...]
"""
return [(self.tlid, i) for i in range(self.get_number_signals())]
def get_all_landmarks(self):
"""
Returns all the landmarks associated with this traffic light.
"""
return self._landmark2link.keys()
def get_associated_signals(self, landmark_id):
"""
Returns all the signals associated with the given landmark.
:returns list: [(tlid, link_index), (tlid, link_index), ...]
"""
return self._landmark2link.get(landmark_id, [])
class SumoTLManager(object):
"""
SumoTLManager is responsible for the management of the sumo traffic lights (i.e., keeps control
of the current program, phase, ...)
"""
def __init__(self):
self._tls = {} # {tlid: {program_id: SumoTLLogic}
self._current_program = {} # {tlid: program_id}
self._current_phase = {} # {tlid: index_phase}
for tlid in traci.trafficlight.getIDList():
self.subscribe(tlid)
self._tls[tlid] = {}
for tllogic in traci.trafficlight.getAllProgramLogics(tlid):
states = [phase.state for phase in tllogic.getPhases()]
parameters = tllogic.getParameters()
tl = SumoTLLogic(tlid, states, parameters)
self._tls[tlid][tllogic.programID] = tl
# Get current status of the traffic lights.
self._current_program[tlid] = traci.trafficlight.getProgram(tlid)
self._current_phase[tlid] = traci.trafficlight.getPhase(tlid)
self._off = False
@staticmethod
def subscribe(tlid):
"""
Subscribe the given traffic ligth to the following variables:
* Current program.
* Current phase.
"""
traci.trafficlight.subscribe(tlid, [
traci.constants.TL_CURRENT_PROGRAM,
traci.constants.TL_CURRENT_PHASE,
])
@staticmethod
def unsubscribe(tlid):
"""
Unsubscribe the given traffic ligth from receiving updated information each step.
"""
traci.trafficlight.unsubscribe(tlid)
def get_all_signals(self):
"""
Returns all the traffic light signals.
"""
signals = set()
for tlid, program_id in self._current_program.items():
signals.update(self._tls[tlid][program_id].get_all_signals())
return signals
def get_all_landmarks(self):
"""
Returns all the landmarks associated with a traffic light in the simulation.
"""
landmarks = set()
for tlid, program_id in self._current_program.items():
landmarks.update(self._tls[tlid][program_id].get_all_landmarks())
return landmarks
def get_all_associated_signals(self, landmark_id):
"""
Returns all the signals associated with the given landmark.
:returns list: [(tlid, link_index), (tlid, link_index), ...]
"""
signals = set()
for tlid, program_id in self._current_program.items():
signals.update(self._tls[tlid][program_id].get_associated_signals(landmark_id))
return signals
def get_state(self, landmark_id):
"""
Returns the traffic light state of the signals associated with the given landmark.
"""
states = set()
for tlid, link_index in self.get_all_associated_signals(landmark_id):
current_program = self._current_program[tlid]
current_phase = self._current_phase[tlid]
tl = self._tls[tlid][current_program]
states.update(tl.states[current_phase][link_index])
if len(states) == 1:
return states.pop()
elif len(states) > 1:
logging.warning('Landmark %s is associated with signals with different states',
landmark_id)
return SumoSignalState.RED
else:
return None
def set_state(self, landmark_id, state):
"""
Updates the state of all the signals associated with the given landmark.
"""
for tlid, link_index in self.get_all_associated_signals(landmark_id):
traci.trafficlight.setLinkState(tlid, link_index, state)
return True
def switch_off(self):
"""
Switch off all traffic lights.
"""
for tlid, link_index in self.get_all_signals():
traci.trafficlight.setLinkState(tlid, link_index, SumoSignalState.OFF)
self._off = True
def tick(self):
"""
Tick to traffic light manager
"""
if self._off is False:
for tl_id in traci.trafficlight.getIDList():
results = traci.trafficlight.getSubscriptionResults(tl_id)
current_program = results[traci.constants.TL_CURRENT_PROGRAM]
current_phase = results[traci.constants.TL_CURRENT_PHASE]
if current_program != 'online':
self._current_program[tl_id] = current_program
self._current_phase[tl_id] = current_phase
# ==================================================================================================
# -- sumo simulation -------------------------------------------------------------------------------
# ==================================================================================================
def _get_sumo_net(cfg_file):
"""
Returns sumo net.
This method reads the sumo configuration file and retrieve the sumo net filename to create the
net.
"""
cfg_file = os.path.join(os.getcwd(), cfg_file)
tree = ET.parse(cfg_file)
tag = tree.find('//net-file')
if tag is None:
return None
net_file = os.path.join(os.path.dirname(cfg_file), tag.get('value'))
logging.debug('Reading net file: %s', net_file)
sumo_net = traci.sumolib.net.readNet(net_file)
return sumo_net
class SumoSimulation(object):
"""
SumoSimulation is responsible for the management of the sumo simulation.
"""
def __init__(self, cfg_file, step_length, host=None, port=None, sumo_gui=False, client_order=1):
if sumo_gui is True:
sumo_binary = sumolib.checkBinary('sumo-gui')
else:
sumo_binary = sumolib.checkBinary('sumo')
if host is None or port is None:
logging.info('Starting new sumo server...')
if sumo_gui is True:
logging.info('Remember to press the play button to start the simulation')
traci.start([sumo_binary,
'--configuration-file', cfg_file,
'--step-length', str(step_length),
'--lateral-resolution', '0.25',
'--collision.check-junctions'
])
else:
logging.info('Connection to sumo server. Host: %s Port: %s', host, port)
traci.init(host=host, port=port)
traci.setOrder(client_order)
# Retrieving net from configuration file.
self.net = _get_sumo_net(cfg_file)
# To keep track of the vehicle classes for which a route has been generated in sumo.
self._routes = set()
# Variable to asign an id to new added actors.
self._sequential_id = 0
# Structures to keep track of the spawned and destroyed vehicles at each time step.
self.spawned_actors = set()
self.destroyed_actors = set()
# Traffic light manager.
self.traffic_light_manager = SumoTLManager()
@property
def traffic_light_ids(self):
return self.traffic_light_manager.get_all_landmarks()
@staticmethod
def subscribe(actor_id):
"""
Subscribe the given actor to the following variables:
* Type.
* Vehicle class.
* Color.
* Length, Width, Height.
* Position3D (i.e., x, y, z).
* Angle, Slope.
* Speed.
* Lateral speed.
* Signals.
"""
traci.vehicle.subscribe(actor_id, [
traci.constants.VAR_TYPE, traci.constants.VAR_VEHICLECLASS, traci.constants.VAR_COLOR,
traci.constants.VAR_LENGTH, traci.constants.VAR_WIDTH, traci.constants.VAR_HEIGHT,
traci.constants.VAR_POSITION3D, traci.constants.VAR_ANGLE, traci.constants.VAR_SLOPE,
traci.constants.VAR_SPEED, traci.constants.VAR_SPEED_LAT, traci.constants.VAR_SIGNALS
])
@staticmethod
def unsubscribe(actor_id):
"""
Unsubscribe the given actor from receiving updated information each step.
"""
traci.vehicle.unsubscribe(actor_id)
def get_net_offset(self):
"""
Accessor for sumo net offset.
"""
if self.net is None:
return (0, 0)
return self.net.getLocationOffset()
@staticmethod
def get_actor(actor_id):
"""
Accessor for sumo actor.
"""
results = traci.vehicle.getSubscriptionResults(actor_id)
type_id = results[traci.constants.VAR_TYPE]
vclass = SumoActorClass(results[traci.constants.VAR_VEHICLECLASS])
color = results[traci.constants.VAR_COLOR]
length = results[traci.constants.VAR_LENGTH]
width = results[traci.constants.VAR_WIDTH]
height = results[traci.constants.VAR_HEIGHT]
location = list(results[traci.constants.VAR_POSITION3D])
rotation = [results[traci.constants.VAR_SLOPE], results[traci.constants.VAR_ANGLE], 0.0]
transform = carla.Transform(carla.Location(location[0], location[1], location[2]),
carla.Rotation(rotation[0], rotation[1], rotation[2]))
signals = results[traci.constants.VAR_SIGNALS]
extent = carla.Vector3D(length / 2.0, width / 2.0, height / 2.0)
return SumoActor(type_id, vclass, transform, signals, extent, color)
def spawn_actor(self, type_id, color=None):
"""
Spawns a new actor.
:param type_id: vtype to be spawned.
:param color: color attribute for this specific actor.
:return: actor id if the actor is successfully spawned. Otherwise, INVALID_ACTOR_ID.
"""
actor_id = 'carla' + str(self._sequential_id)
try:
vclass = traci.vehicletype.getVehicleClass(type_id)
if vclass not in self._routes:
logging.debug('Creating route for %s vehicle class', vclass)
allowed_edges = [e for e in self.net.getEdges() if e.allows(vclass)]
if allowed_edges:
traci.route.add("carla_route_{}".format(vclass), [allowed_edges[0].getID()])
self._routes.add(vclass)
else:
logging.error(
'Could not found a route for %s. No vehicle will be spawned in sumo',
type_id)
return INVALID_ACTOR_ID
traci.vehicle.add(actor_id, 'carla_route_{}'.format(vclass), typeID=type_id)
except traci.exceptions.TraCIException as error:
logging.error('Spawn sumo actor failed: %s', error)
return INVALID_ACTOR_ID
if color is not None:
color = color.split(',')
traci.vehicle.setColor(actor_id, color)
self._sequential_id += 1
return actor_id
@staticmethod
def destroy_actor(actor_id):
"""
Destroys the given actor.
"""
traci.vehicle.remove(actor_id)
def get_traffic_light_state(self, landmark_id):
"""
Accessor for traffic light state.
If the traffic ligth does not exist, returns None.
"""
return self.traffic_light_manager.get_state(landmark_id)
def switch_off_traffic_lights(self):
"""
Switch off all traffic lights.
"""
self.traffic_light_manager.switch_off()
def synchronize_vehicle(self, vehicle_id, transform, signals=None):
"""
Updates vehicle state.
:param vehicle_id: id of the actor to be updated.
:param transform: new vehicle transform (i.e., position and rotation).
:param signals: new vehicle signals.
:return: True if successfully updated. Otherwise, False.
"""
loc_x, loc_y = transform.location.x, transform.location.y
yaw = transform.rotation.yaw
traci.vehicle.moveToXY(vehicle_id, "", 0, loc_x, loc_y, angle=yaw, keepRoute=2)
if signals is not None:
traci.vehicle.setSignals(vehicle_id, signals)
return True
def synchronize_traffic_light(self, landmark_id, state):
"""
Updates traffic light state.
:param tl_id: id of the traffic light to be updated (logic id, link index).
:param state: new traffic light state.
:return: True if successfully updated. Otherwise, False.
"""
self.traffic_light_manager.set_state(landmark_id, state)
def tick(self):
"""
Tick to sumo simulation.
"""
traci.simulationStep()
self.traffic_light_manager.tick()
# Update data structures for the current frame.
self.spawned_actors = set(traci.simulation.getDepartedIDList())
self.destroyed_actors = set(traci.simulation.getArrivedIDList())
@staticmethod
def close():
"""
Closes traci client.
"""
traci.close()

View File

@ -1,174 +0,0 @@
#!/usr/bin/env python
# Copyright (c) 2020 Computer Vision Center (CVC) at the Universitat Autonoma de
# Barcelona (UAB).
#
# This work is licensed under the terms of the MIT license.
# For a copy, see <https://opensource.org/licenses/MIT>.
"""
Script to create sumo vtypes based on carla blueprints.
"""
# ==================================================================================================
# -- imports ---------------------------------------------------------------------------------------
# ==================================================================================================
import argparse
import glob
import datetime
import json
import logging
import os
import sys
import lxml.etree as ET # pylint: disable=import-error
# ==================================================================================================
# -- find carla module -----------------------------------------------------------------------------
# ==================================================================================================
try:
sys.path.append(
glob.glob('../../../PythonAPI/carla/dist/carla-*%d.%d-%s.egg' %
(sys.version_info.major, sys.version_info.minor,
'win-amd64' if os.name == 'nt' else 'linux-x86_64'))[0])
except IndexError:
pass
import carla # pylint: disable=import-error, wrong-import-position
# ==================================================================================================
# -- load specs definition -------------------------------------------------------------------------
# ==================================================================================================
with open('../data/vtypes.json') as f:
SPECS = json.load(f)
DEFAULT_2_WHEELED_VEHICLE = SPECS['DEFAULT_2_WHEELED_VEHICLE']
DEFAULT_WHEELED_VEHICLE = SPECS['DEFAULT_WHEELED_VEHICLE']
CARLA_BLUEPRINTS_SPECS = SPECS['carla_blueprints']
# ==================================================================================================
# -- main ------------------------------------------------------------------------------------------
# ==================================================================================================
def write_vtype_xml(filename, vtypes):
"""
Write route xml file.
"""
root = ET.Element('routes')
root.addprevious(
ET.Comment('generated on {date:%Y-%m-%d %H:%M:%S} by {script:}'.format(
date=datetime.datetime.now(), script=os.path.basename(__file__))))
for vtype in vtypes:
ET.SubElement(root, 'vType', vtype)
tree = ET.ElementTree(root)
tree.write(filename, pretty_print=True, encoding='UTF-8', xml_declaration=True)
def generate_vtype(vehicle):
"""Generates sumo vtype specification for a given carla vehicle.
:param vehicle: carla actor (carla.Actor)
:return: sumo vtype specifications
"""
type_id = vehicle.type_id
if type_id not in CARLA_BLUEPRINTS_SPECS:
number_of_wheels = int(vehicle.attributes['number_of_wheels'])
if number_of_wheels == 2:
logging.warning(
'''type id %s not mapped to any sumo vtype.
\tUsing default specification for two-wheeled vehicles: %s''', type_id,
DEFAULT_2_WHEELED_VEHICLE)
user_specs = DEFAULT_2_WHEELED_VEHICLE
else:
logging.warning(
'''type id %s not mapped to any sumo vtype.
\tUsing default specification for wheeled vehicles: %s''', type_id,
DEFAULT_WHEELED_VEHICLE)
user_specs = DEFAULT_WHEELED_VEHICLE
else:
logging.info('type id %s mapped to the following specifications: %s', type_id,
CARLA_BLUEPRINTS_SPECS[type_id])
user_specs = CARLA_BLUEPRINTS_SPECS[type_id]
specs = {
'id': vehicle.type_id,
'length': str(2.0 * vehicle.bounding_box.extent.x),
'width': str(2.0 * vehicle.bounding_box.extent.y),
'height': str(2.0 * vehicle.bounding_box.extent.z)
}
specs.update(user_specs)
return specs
def main(args):
"""
Main method.
"""
client = carla.Client(args.carla_host, args.carla_port)
client.set_timeout(2.0)
try:
world = client.get_world()
vehicle_blueprints = world.get_blueprint_library().filter('vehicle.*')
transform = world.get_map().get_spawn_points()[0]
vtypes = []
for blueprint in vehicle_blueprints:
logging.info('processing vtype for %s', blueprint.id)
vehicle = world.spawn_actor(blueprint, transform)
vtype = generate_vtype(vehicle)
if vtype:
vtypes.append(vtype)
else:
logging.error(
'type id %s could no be mapped to any vtype', vehicle.type_id)
vehicle.destroy()
write_vtype_xml(args.output_file, vtypes)
finally:
logging.info('done')
if __name__ == '__main__':
# Define arguments that will be received and parsed.
argparser = argparse.ArgumentParser(description=__doc__)
argparser.add_argument('--carla-host',
metavar='H',
default='127.0.0.1',
help='IP of the host server (default: 127.0.0.1)')
argparser.add_argument('--carla-port',
metavar='P',
default=2000,
type=int,
help='TCP port to listen to (default: 2000)')
argparser.add_argument(
'--output-file',
'-o',
metavar='FILE',
default='carlavtypes.rou.xml',
type=str,
help='the generated vtypes will be written to FILE (default: carlavtypes.rou.xml)')
argparser.add_argument('--verbose', '-v', action='store_true', help='increase output verbosity')
arguments = argparser.parse_args()
if arguments.verbose:
logging.basicConfig(format='%(levelname)s: %(message)s', level=logging.INFO)
else:
logging.basicConfig(format='%(levelname)s: %(message)s', level=logging.WARNING)
main(arguments)

View File

@ -1,31 +0,0 @@
<types xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="http://sumo.dlr.de/xsd/types_file.xsd">
<type id="driving" priority="1" speed="13.89" width="3.65" disallow="pedestrian rail rail_urban rail_electric rail_fast tram ship"/>
<type id="stop" priority="1" speed="13.89" width="3.65" disallow="pedestrian rail rail_urban rail_electric rail_fast tram ship"/>
<type id="restricted" priority="0" speed="13.89" width="3.65" disallow="all"/>
<type id="parking" priority="1" speed="1.39" width="2.50" disallow="pedestrian rail rail_urban rail_electric rail_fast tram ship"/>
<type id="entry" priority="1" speed="22.22" width="3.65" disallow="pedestrian rail rail_urban rail_electric rail_fast tram ship"/>
<type id="exit" priority="1" speed="22.22" width="3.65" disallow="pedestrian rail rail_urban rail_electric rail_fast tram ship"/>
<type id="offRamp" priority="1" speed="22.22" width="3.65" disallow="pedestrian bicycle moped rail rail_urban rail_electric rail_fast tram ship"/>
<type id="onRamp" priority="1" speed="22.22" width="3.65" disallow="pedestrian bicycle moped rail rail_urban rail_electric rail_fast tram ship"/>
<type id="roadWorks" priority="0" speed="1.39" width="3.65" allow="authority"/>
<type id="tram" priority="2" speed="13.89" width="3.65" allow="tram"/>
<type id="rail" priority="3" speed="33.33" width="3.65" allow="rail rail_urban rail_electric rail_fast"/>
<type id="biking" priority="-1" speed="5.56" width="1.50" allow="bicycle"/>
<type id="sidewalk" priority="-2" speed="2.78" width="2.50" allow="pedestrian"/>
<!-- discarded -->
<type id="none" priority="0" speed="1.39" width="1.0" disallow="all" discard="true"/>
<type id="shoulder" priority="0" speed="1.39" width="1.0" disallow="all" discard="true"/>
<type id="border" priority="0" speed="1.39" width="0.1" disallow="all" discard="true"/>
<type id="median" priority="0" speed="1.39" width="0.1" disallow="all" discard="true"/>
<type id="special1" priority="1" speed="22.22" width="3.65" allow="custom1" discard="true"/>
<type id="special2" priority="1" speed="22.22" width="3.65" allow="custom2" discard="true"/>
<type id="special3" priority="1" speed="22.22" width="3.65" allow="custom1 custom2" discard="true"/>
<!-- deprecated -->
<type id="mwyEntry" priority="1" speed="22.22" width="3.65" disallow="pedestrian bicycle moped rail rail_urban rail_electric rail_fast tram ship"/>
<type id="mwyExit" priority="1" speed="22.22" width="3.65" disallow="pedestrian bicycle moped rail rail_urban rail_electric rail_fast tram ship"/>
<!-- not fully implemented -->
<type id="bidirectional" priority="1" speed="1.39" width="3.65" disallow="pedestrian rail rail_urban rail_electric rail_fast tram ship"/>
</types>

View File

@ -1,541 +0,0 @@
#!/usr/bin/env python
# Copyright (c) 2020 Computer Vision Center (CVC) at the Universitat Autonoma de
# Barcelona (UAB).
#
# This work is licensed under the terms of the MIT license.
# For a copy, see <https://opensource.org/licenses/MIT>.
"""
Script to generate sumo nets based on opendrive files. Internally, it uses netconvert to generate
the net and inserts, manually, the traffic light landmarks retrieved from the opendrive.
"""
# ==================================================================================================
# -- imports ---------------------------------------------------------------------------------------
# ==================================================================================================
import argparse
import bisect
import collections
import logging
import shutil
import subprocess
import tempfile
import lxml.etree as ET # pylint: disable=import-error
# ==================================================================================================
# -- find carla module -----------------------------------------------------------------------------
# ==================================================================================================
import glob
import os
import sys
try:
sys.path.append(
glob.glob('../../../PythonAPI/carla/dist/carla-*%d.%d-%s.egg' %
(sys.version_info.major, sys.version_info.minor,
'win-amd64' if os.name == 'nt' else 'linux-x86_64'))[0])
except IndexError:
pass
# ==================================================================================================
# -- find sumo modules -----------------------------------------------------------------------------
# ==================================================================================================
if 'SUMO_HOME' in os.environ:
sys.path.append(os.path.join(os.environ['SUMO_HOME'], 'tools'))
else:
sys.exit("please declare environment variable 'SUMO_HOME'")
# ==================================================================================================
# -- imports ---------------------------------------------------------------------------------------
# ==================================================================================================
import carla
import sumolib
# ==================================================================================================
# -- topology --------------------------------------------------------------------------------------
# ==================================================================================================
class SumoTopology(object):
"""
This object holds the topology of a sumo net. Internally, the information is structured as
follows:
- topology: {
(road_id, lane_id): [(successor_road_id, succesor_lane_id), ...], ...}
- paths: {
(road_id, lane_id): [
((in_road_id, in_lane_id), (out_road_id, out_lane_id)), ...
], ...}
- odr2sumo_ids: {
(odr_road_id, odr_lane_id): [(sumo_edge_id, sumo_lane_id), ...], ...}
"""
def __init__(self, topology, paths, odr2sumo_ids):
# Contains only standard roads.
self._topology = topology
# Contaions only roads that belong to a junction.
self._paths = paths
# Mapped ids between sumo and opendrive.
self._odr2sumo_ids = odr2sumo_ids
# http://sumo.sourceforge.net/userdoc/Networks/Import/OpenDRIVE.html#dealing_with_lane_sections
def get_sumo_id(self, odr_road_id, odr_lane_id, s=0):
"""
Returns the pair (sumo_edge_id, sumo_lane index) corresponding to the provided odr pair. The
argument 's' allows selecting the better sumo edge when it has been split into different
edges due to different odr lane sections.
"""
if (odr_road_id, odr_lane_id) not in self._odr2sumo_ids:
return None
sumo_ids = list(self._odr2sumo_ids[(odr_road_id, odr_lane_id)])
if (len(sumo_ids)) == 1:
return sumo_ids[0]
# The edge is split into different lane sections. We return the nearest edge based on the
# s coordinate of the provided landmark.
else:
# Ensures that all the related sumo edges belongs to the same opendrive road but to
# different lane sections.
assert set([edge.split('.', 1)[0] for edge, lane_index in sumo_ids]) == 1
s_coords = [float(edge.split('.', 1)[1]) for edge, lane_index in sumo_ids]
s_coords, sumo_ids = zip(*sorted(zip(s_coords, sumo_ids)))
index = bisect.bisect_left(s_coords, s, lo=1) - 1
return sumo_ids[index]
def is_junction(self, odr_road_id, odr_lane_id):
"""
Checks whether the provided pair (odr_road_id, odr_lane_id) belongs to a junction.
"""
return (odr_road_id, odr_lane_id) in self._paths
def get_successors(self, sumo_edge_id, sumo_lane_index):
"""
Returns the successors (standard roads) of the provided pair (sumo_edge_id, sumo_lane_index)
"""
if self.is_junction(sumo_edge_id, sumo_lane_index):
return []
return list(self._topology.get((sumo_edge_id, sumo_lane_index), set()))
def get_incoming(self, odr_road_id, odr_lane_id):
"""
If the pair (odr_road_id, odr_lane_id) belongs to a junction, returns the incoming edges of
the path. Otherwise, return and empty list.
"""
if not self.is_junction(odr_road_id, odr_lane_id):
return []
result = set([(connection[0][0], connection[0][1])
for connection in self._paths[(odr_road_id, odr_lane_id)]])
return list(result)
def get_outgoing(self, odr_road_id, odr_lane_id):
"""
If the pair (odr_road_id, odr_lane_id) belongs to a junction, returns the outgoing edges of
the path. Otherwise, return and empty list.
"""
if not self.is_junction(odr_road_id, odr_lane_id):
return []
result = set([(connection[1][0], connection[1][1])
for connection in self._paths[(odr_road_id, odr_lane_id)]])
return list(result)
def get_path_connectivity(self, odr_road_id, odr_lane_id):
"""
Returns incoming and outgoing roads of the pair (odr_road_id, odr_lane_id). If the provided
pair not belongs to a junction, returns an empty list.
"""
return list(self._paths.get((odr_road_id, odr_lane_id), set()))
def build_topology(sumo_net):
"""
Builds sumo topology.
"""
# --------------------------
# OpenDrive->Sumo mapped ids
# --------------------------
# Only takes into account standard roads.
#
# odr2sumo_ids = {(odr_road_id, odr_lane_id) : [(sumo_edge_id, sumo_lane_index), ...], ...}
odr2sumo_ids = {}
for edge in sumo_net.getEdges():
for lane in edge.getLanes():
if lane.getParam('origId') is None:
raise RuntimeError(
'Sumo lane {} does not have "origId" parameter. Make sure that the --output.original-names parameter is active when running netconvert.'
.format(lane.getID()))
if len(lane.getParam('origId').split()) > 1:
logging.warning('[Building topology] Sumo net contains joined opendrive roads.')
for odr_id in lane.getParam('origId').split():
odr_road_id, odr_lane_id = odr_id.split('_')
if (odr_road_id, int(odr_lane_id)) not in odr2sumo_ids:
odr2sumo_ids[(odr_road_id, int(odr_lane_id))] = set()
odr2sumo_ids[(odr_road_id, int(odr_lane_id))].add((edge.getID(), lane.getIndex()))
# -----------
# Connections
# -----------
#
# topology -- {(sumo_road_id, sumo_lane_index): [(sumo_road_id, sumo_lane_index), ...], ...}
# paths -- {(odr_road_id, odr_lane_id): [
# ((sumo_edge_id, sumo_lane_index), (sumo_edge_id, sumo_lane_index))
# ]}
topology = {}
paths = {}
for from_edge in sumo_net.getEdges():
for to_edge in sumo_net.getEdges():
connections = from_edge.getConnections(to_edge)
for connection in connections:
from_ = connection.getFromLane()
to_ = connection.getToLane()
from_edge_id, from_lane_index = from_.getEdge().getID(), from_.getIndex()
to_edge_id, to_lane_index = to_.getEdge().getID(), to_.getIndex()
if (from_edge_id, from_lane_index) not in topology:
topology[(from_edge_id, from_lane_index)] = set()
topology[(from_edge_id, from_lane_index)].add((to_edge_id, to_lane_index))
# Checking if the connection is an opendrive path.
conn_odr_ids = connection.getParam('origId')
if conn_odr_ids is not None:
if len(conn_odr_ids.split()) > 1:
logging.warning(
'[Building topology] Sumo net contains joined opendrive paths.')
for odr_id in conn_odr_ids.split():
odr_road_id, odr_lane_id = odr_id.split('_')
if (odr_road_id, int(odr_lane_id)) not in paths:
paths[(odr_road_id, int(odr_lane_id))] = set()
paths[(odr_road_id, int(odr_lane_id))].add(
((from_edge_id, from_lane_index), (to_edge_id, to_lane_index)))
return SumoTopology(topology, paths, odr2sumo_ids)
# ==================================================================================================
# -- sumo definitions ------------------------------------------------------------------------------
# ==================================================================================================
class SumoTrafficLight(object):
"""
SumoTrafficLight holds all the necessary data to define a traffic light in sumo:
* connections (tlid, from_road, to_road, from_lane, to_lane, link_index).
* phases (duration, state, min_dur, max_dur, nex, name).
* parameters.
"""
DEFAULT_DURATION_GREEN_PHASE = 42
DEFAULT_DURATION_YELLOW_PHASE = 3
DEFAULT_DURATION_RED_PHASE = 3
Phase = collections.namedtuple('Phase', 'duration state min_dur max_dur next name')
Connection = collections.namedtuple('Connection',
'tlid from_road to_road from_lane to_lane link_index')
def __init__(self, tlid, program_id='0', offset=0, tltype='static'):
self.id = tlid
self.program_id = program_id
self.offset = offset
self.type = tltype
self.phases = []
self.parameters = set()
self.connections = set()
@staticmethod
def generate_tl_id(from_edge, to_edge):
"""
Generates sumo traffic light id based on the junction connectivity.
"""
return '{}:{}'.format(from_edge, to_edge)
@staticmethod
def generate_default_program(tl):
"""
Generates a default program for the given sumo traffic light
"""
incoming_roads = [connection.from_road for connection in tl.connections]
for road in set(incoming_roads):
phase_green = ['r'] * len(tl.connections)
phase_yellow = ['r'] * len(tl.connections)
phase_red = ['r'] * len(tl.connections)
for connection in tl.connections:
if connection.from_road == road:
phase_green[connection.link_index] = 'g'
phase_yellow[connection.link_index] = 'y'
tl.add_phase(SumoTrafficLight.DEFAULT_DURATION_GREEN_PHASE, ''.join(phase_green))
tl.add_phase(SumoTrafficLight.DEFAULT_DURATION_YELLOW_PHASE, ''.join(phase_yellow))
tl.add_phase(SumoTrafficLight.DEFAULT_DURATION_RED_PHASE, ''.join(phase_red))
def add_phase(self, duration, state, min_dur=-1, max_dur=-1, next_phase=None, name=''):
"""
Adds a new phase.
"""
self.phases.append(
SumoTrafficLight.Phase(duration, state, min_dur, max_dur, next_phase, name))
def add_parameter(self, key, value):
"""
Adds a new parameter.
"""
self.parameters.add((key, value))
def add_connection(self, connection):
"""
Adds a new connection.
"""
self.connections.add(connection)
def add_landmark(self,
landmark_id,
tlid,
from_road,
to_road,
from_lane,
to_lane,
link_index=-1):
"""
Adds a new landmark.
Returns True if the landmark is successfully included. Otherwise, returns False.
"""
if link_index == -1:
link_index = len(self.connections)
def is_same_connection(c1, c2):
return c1.from_road == c2.from_road and c1.to_road == c2.to_road and \
c1.from_lane == c2.from_lane and c1.to_lane == c2.to_lane
connection = SumoTrafficLight.Connection(tlid, from_road, to_road, from_lane, to_lane,
link_index)
if any([is_same_connection(connection, c) for c in self.connections]):
logging.warning(
'Different landmarks controlling the same connection. Only one will be included.')
return False
self.add_connection(connection)
self.add_parameter(link_index, landmark_id)
return True
def to_xml(self):
info = {
'id': self.id,
'type': self.type,
'programID': self.program_id,
'offset': str(self.offset)
}
xml_tag = ET.Element('tlLogic', info)
for phase in self.phases:
ET.SubElement(xml_tag, 'phase', {'state': phase.state, 'duration': str(phase.duration)})
for parameter in sorted(self.parameters, key=lambda x: x[0]):
ET.SubElement(xml_tag, 'param', {
'key': 'linkSignalID:' + str(parameter[0]),
'value': str(parameter[1])
})
return xml_tag
# ==================================================================================================
# -- main ------------------------------------------------------------------------------------------
# ==================================================================================================
def _netconvert_carla_impl(xodr_file, output, tmpdir, guess_tls=False):
"""
Implements netconvert carla.
"""
# ----------
# netconvert
# ----------
basename = os.path.splitext(os.path.basename(xodr_file))[0]
tmp_sumo_net = os.path.join(tmpdir, basename + '.net.xml')
try:
basedir = os.path.dirname(os.path.realpath(__file__))
result = subprocess.call(['netconvert',
'--opendrive', xodr_file,
'--output-file', tmp_sumo_net,
'--geometry.min-radius.fix',
'--geometry.remove',
'--opendrive.curve-resolution', '1',
'--opendrive.import-all-lanes',
'--type-files', os.path.join(basedir, 'data/opendrive_netconvert.typ.xml'),
# Necessary to link odr and sumo ids.
'--output.original-names',
# Discard loading traffic lights as them will be inserted manually afterwards.
'--tls.discard-loaded', 'true',
])
except subprocess.CalledProcessError:
raise RuntimeError('There was an error when executing netconvert.')
else:
if result != 0:
raise RuntimeError('There was an error when executing netconvert.')
# --------
# Sumo net
# --------
sumo_net = sumolib.net.readNet(tmp_sumo_net)
sumo_topology = build_topology(sumo_net)
# ---------
# Carla map
# ---------
with open(xodr_file, 'r') as f:
carla_map = carla.Map('netconvert', str(f.read()))
# ---------
# Landmarks
# ---------
tls = {} # {tlsid: SumoTrafficLight}
landmarks = carla_map.get_all_landmarks_of_type('1000001')
for landmark in landmarks:
if landmark.name == '':
# This is a workaround to avoid adding traffic lights without controllers.
logging.warning('Landmark %s has not a valid name.', landmark.name)
continue
road_id = str(landmark.road_id)
for from_lane, to_lane in landmark.get_lane_validities():
for lane_id in range(from_lane, to_lane + 1):
if lane_id == 0:
continue
wp = carla_map.get_waypoint_xodr(landmark.road_id, lane_id, landmark.s)
if wp is None:
logging.warning(
'Could not find waypoint for landmark {} (road_id: {}, lane_id: {}, s:{}'.
format(landmark.id, landmark.road_id, lane_id, landmark.s))
continue
# When the landmark belongs to a junction, we place te traffic light at the
# entrance of the junction.
if wp.is_junction and sumo_topology.is_junction(road_id, lane_id):
tlid = str(wp.get_junction().id)
if tlid not in tls:
tls[tlid] = SumoTrafficLight(tlid)
tl = tls[tlid]
if guess_tls:
for from_edge, from_lane in sumo_topology.get_incoming(road_id, lane_id):
successors = sumo_topology.get_successors(from_edge, from_lane)
for to_edge, to_lane in successors:
tl.add_landmark(landmark.id, tl.id, from_edge, to_edge, from_lane,
to_lane)
else:
connections = sumo_topology.get_path_connectivity(road_id, lane_id)
for from_, to_ in connections:
from_edge, from_lane = from_
to_edge, to_lane = to_
tl.add_landmark(landmark.id, tl.id, from_edge, to_edge, from_lane,
to_lane)
# When the landmarks does not belong to a junction (i.e., belongs to a std road),
# we place the traffic light between that std road and its successor.
elif not wp.is_junction and not sumo_topology.is_junction(road_id, lane_id):
from_edge, from_lane = sumo_topology.get_sumo_id(road_id, lane_id, landmark.s)
for to_edge, to_lane in sumo_topology.get_successors(from_edge, from_lane):
tlid = SumoTrafficLight.generate_tl_id(from_edge, to_edge)
if tlid not in tls:
tls[tlid] = SumoTrafficLight(tlid)
tl = tls[tlid]
tl.add_landmark(landmark.id, tl.id, from_edge, to_edge, from_lane, to_lane)
else:
logging.warning('Landmark %s could not be added.', landmark.id)
# ---------------
# Modify sumo net
# ---------------
parser = ET.XMLParser(remove_blank_text=True)
tree = ET.parse(tmp_sumo_net, parser)
root = tree.getroot()
for tl in tls.values():
SumoTrafficLight.generate_default_program(tl)
edges_tags = tree.xpath('//edge')
if not edges_tags:
raise RuntimeError('No edges found in sumo net.')
root.insert(root.index(edges_tags[-1]) + 1, tl.to_xml())
for connection in tl.connections:
tags = tree.xpath(
'//connection[@from="{}" and @to="{}" and @fromLane="{}" and @toLane="{}"]'.format(
connection.from_road, connection.to_road, connection.from_lane,
connection.to_lane))
if tags:
if len(tags) > 1:
logging.warning(
'Found repeated connections from={} to={} fromLane={} toLane={}.'.format(
connection.from_road, connection.to_road, connection.from_lane,
connection.to_lane))
tags[0].set('tl', str(connection.tlid))
tags[0].set('linkIndex', str(connection.link_index))
else:
logging.warning('Not found connection from={} to={} fromLane={} toLane={}.'.format(
connection.from_road, connection.to_road, connection.from_lane,
connection.to_lane))
tree.write(output, pretty_print=True, encoding='UTF-8', xml_declaration=True)
def netconvert_carla(xodr_file, output, guess_tls=False):
"""
Generates sumo net.
:param xodr_file: opendrive file (*.xodr)
:param output: output file (*.net.xml)
:param guess_tls: guess traffic lights at intersections.
:returns: path to the generated sumo net.
"""
try:
tmpdir = tempfile.mkdtemp()
_netconvert_carla_impl(xodr_file, output, tmpdir, guess_tls)
finally:
if os.path.exists(tmpdir):
shutil.rmtree(tmpdir)
if __name__ == '__main__':
argparser = argparse.ArgumentParser(description=__doc__)
argparser.add_argument('xodr_file', help='opendrive file (*.xodr')
argparser.add_argument('--output',
'-o',
default='net.net.xml',
type=str,
help='output file (default: net.net.xml)')
argparser.add_argument('--guess-tls',
action='store_true',
help='guess traffic lights at intersections (default: False)')
args = argparser.parse_args()
netconvert_carla(args.xodr_file, args.output, args.guess_tls)

View File

@ -1,89 +0,0 @@
#!/usr/bin/env python
# Copyright (c) 2020 Computer Vision Center (CVC) at the Universitat Autonoma de
# Barcelona (UAB).
#
# This work is licensed under the terms of the MIT license.
# For a copy, see <https://opensource.org/licenses/MIT>.
"""
Script to modify automatically vtypes to carla type ids in sumo route files.
"""
# ==================================================================================================
# -- imports ---------------------------------------------------------------------------------------
# ==================================================================================================
import argparse
import fnmatch
import json
import logging
import random
import lxml.etree as ET # pylint: disable=import-error
# ==================================================================================================
# -- load vtypes -----------------------------------------------------------------------------------
# ==================================================================================================
with open('../data/vtypes.json') as f:
VTYPES = json.load(f)['carla_blueprints'].keys()
# ==================================================================================================
# -- main ------------------------------------------------------------------------------------------
# ==================================================================================================
def main(route_files, vtypes, _random=False):
"""
Main method to automatically modify vtypes to carla type ids in sumo route files.
"""
for filename in route_files:
tree = ET.parse(filename)
root = tree.getroot()
if not _random:
index = 0
counter = 0
for vtype in root.iter('vehicle'):
if _random:
new_type = random.choice(vtypes)
else:
new_type = vtypes[index]
index = (index + 1) if index < (len(vtypes) - 1) else 0
vtype.set('type', new_type)
counter += 1
tree = ET.ElementTree(root)
tree.write(filename, pretty_print=True, encoding='UTF-8', xml_declaration=True)
logging.info('modified %d vtype(s) in %s', counter, filename)
if __name__ == '__main__':
# Define arguments that will be received and parsed.
argparser = argparse.ArgumentParser(description=__doc__)
argparser.add_argument('--route-files',
'-r',
metavar='FILES',
nargs='+',
default=[],
help='sumo route files')
argparser.add_argument('--random',
action='store_true',
help='apply vtypes randomly or sequentially')
argparser.add_argument('--filterv',
metavar='PATTERN',
default='vehicle.*',
help='vehicles filter (default: "vehicle.*")')
argparser.add_argument('--verbose', '-v', action='store_true', help='increase output verbosity')
args = argparser.parse_args()
if args.verbose:
logging.basicConfig(format='%(levelname)s: %(message)s', level=logging.INFO)
else:
logging.basicConfig(format='%(levelname)s: %(message)s', level=logging.WARNING)
filtered_vtypes = [vtype for vtype in VTYPES if fnmatch.fnmatch(vtype, args.filterv)]
main(args.route_files, filtered_vtypes, args.random)

Binary file not shown.

After

Width:  |  Height:  |  Size: 34 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 33 KiB

View File

@ -1,6 +1,8 @@
# CARLA Documentation # CARLA Unreal Engine 5 Documentation
Welcome to the CARLA documentation. Welcome to the CARLA Unreal Engine 5 documentation.
This documentation refers to the Unreal Engine 5 version of CARLA, which differs significantly in functionality and features from the Unreal Engine 4 version of CARLA. If you are using the Unreal Engine 4 version of CARLA please refer to the [documentation for that version](https://carla.readthedocs.org)
This home page contains an index with a brief description of the different sections in the documentation. Feel free to read in whatever order preferred. In any case, here are a few suggestions for newcomers. This home page contains an index with a brief description of the different sections in the documentation. Feel free to read in whatever order preferred. In any case, here are a few suggestions for newcomers.

View File

@ -1,11 +1,14 @@
set ( project (
LIBCARLA_SOURCE_PATH libcarla
${CARLA_WORKSPACE_PATH}/LibCarla/source LANGUAGES
CXX
VERSION
${CARLA_VERSION}
) )
set ( set (
LIBCARLA_THIRD_PARTY_SOURCE_PATH LIBCARLA_SOURCE_PATH
${LIBCARLA_SOURCE_PATH}/third-party ${CARLA_WORKSPACE_PATH}/LibCarla/source
) )
carla_two_step_configure_file ( carla_two_step_configure_file (
@ -15,14 +18,6 @@ carla_two_step_configure_file (
if (BUILD_CARLA_SERVER) if (BUILD_CARLA_SERVER)
project (
carla-server
LANGUAGES
CXX
VERSION
${CARLA_VERSION}
)
file ( file (
GLOB GLOB
LIBCARLA_SERVER_SOURCES LIBCARLA_SERVER_SOURCES
@ -59,9 +54,9 @@ if (BUILD_CARLA_SERVER)
file ( file (
GLOB GLOB
LIBCARLA_SERVER_SOURCES_THIRD_PARTY LIBCARLA_SERVER_SOURCES_THIRD_PARTY
${LIBCARLA_THIRD_PARTY_SOURCE_PATH}/odrSpiral/*.cpp ${LIBCARLA_SOURCE_PATH}/third-party/odrSpiral/*.cpp
${LIBCARLA_THIRD_PARTY_SOURCE_PATH}/moodycamel/*.cpp ${LIBCARLA_SOURCE_PATH}/third-party/moodycamel/*.cpp
${LIBCARLA_THIRD_PARTY_SOURCE_PATH}/pugixml/*.cpp ${LIBCARLA_SOURCE_PATH}/third-party/pugixml/*.cpp
) )
file ( file (
@ -107,9 +102,9 @@ if (BUILD_CARLA_SERVER)
file ( file (
GLOB GLOB
LIBCARLA_SERVER_HEADERS_THIRD_PARTY LIBCARLA_SERVER_HEADERS_THIRD_PARTY
${LIBCARLA_THIRD_PARTY_SOURCE_PATH}/odrSpiral/*.h ${LIBCARLA_SOURCE_PATH}/third-party/odrSpiral/*.h
${LIBCARLA_THIRD_PARTY_SOURCE_PATH}/moodycamel/*.h ${LIBCARLA_SOURCE_PATH}/third-party/moodycamel/*.h
${LIBCARLA_THIRD_PARTY_SOURCE_PATH}/pugixml/*.hpp ${LIBCARLA_SOURCE_PATH}/third-party/pugixml/*.hpp
) )
carla_add_library ( carla_add_library (
@ -159,14 +154,6 @@ endif ()
if (BUILD_CARLA_CLIENT) if (BUILD_CARLA_CLIENT)
project (
carla-client
LANGUAGES
CXX
VERSION
${CARLA_VERSION}
)
file ( file (
GLOB GLOB
LIBCARLA_CLIENT_HEADERS LIBCARLA_CLIENT_HEADERS
@ -214,10 +201,10 @@ if (BUILD_CARLA_CLIENT)
file ( file (
GLOB GLOB
LIBCARLA_CLIENT_HEADERS_THIRD_PARTY LIBCARLA_CLIENT_HEADERS_THIRD_PARTY
${LIBCARLA_THIRD_PARTY_SOURCE_PATH}/odrSpiral/*.h ${LIBCARLA_SOURCE_PATH}/third-party/odrSpiral/*.h
${LIBCARLA_THIRD_PARTY_SOURCE_PATH}/moodycamel/*.h ${LIBCARLA_SOURCE_PATH}/third-party/moodycamel/*.h
${LIBCARLA_THIRD_PARTY_SOURCE_PATH}/pugixml/*.hpp ${LIBCARLA_SOURCE_PATH}/third-party/pugixml/*.hpp
${LIBCARLA_THIRD_PARTY_SOURCE_PATH}/pugixml/*.h ${LIBCARLA_SOURCE_PATH}/third-party/pugixml/*.h
) )
file ( file (
@ -265,8 +252,8 @@ if (BUILD_CARLA_CLIENT)
file ( file (
GLOB GLOB
LIBCARLA_CLIENT_SOURCES_THIRD_PARTY LIBCARLA_CLIENT_SOURCES_THIRD_PARTY
${LIBCARLA_THIRD_PARTY_SOURCE_PATH}/odrSpiral/*.cpp ${LIBCARLA_SOURCE_PATH}/third-party/odrSpiral/*.cpp
${LIBCARLA_THIRD_PARTY_SOURCE_PATH}/pugixml/*.cpp ${LIBCARLA_SOURCE_PATH}/third-party/pugixml/*.cpp
) )
carla_add_library ( carla_add_library (

View File

@ -32,6 +32,16 @@ namespace client {
return GetEpisode().Lock()->GetActorAcceleration(*this); return GetEpisode().Lock()->GetActorAcceleration(*this);
} }
std::string Actor::GetActorName() const
{
return GetEpisode().Lock()->GetActorName(*this);
}
std::string Actor::GetActorClassName() const
{
return GetEpisode().Lock()->GetActorClassName(*this);
}
void Actor::SetLocation(const geom::Location &location) { void Actor::SetLocation(const geom::Location &location) {
GetEpisode().Lock()->SetActorLocation(*this, location); GetEpisode().Lock()->SetActorLocation(*this, location);
} }

View File

@ -60,6 +60,18 @@ namespace client {
/// acceleration calculated after the actor's velocity. /// acceleration calculated after the actor's velocity.
geom::Vector3D GetAcceleration() const; geom::Vector3D GetAcceleration() const;
/// Return the name of the underlying Unreal actor.
///
/// @note This function does not call the simulator, it returns the
/// acceleration calculated after the actor's velocity.
std::string GetActorName() const;
/// Return the name of the underlying actor's Unreal class.
///
/// @note This function does not call the simulator, it returns the
/// acceleration calculated after the actor's velocity.
std::string GetActorClassName() const;
/// Teleport the actor to @a location. /// Teleport the actor to @a location.
void SetLocation(const geom::Location &location); void SetLocation(const geom::Location &location);

View File

@ -710,6 +710,16 @@ namespace detail {
return _pimpl->CallAndWait<return_t>("cast_ray", start_location, end_location); return _pimpl->CallAndWait<return_t>("cast_ray", start_location, end_location);
} }
std::string Client::GetActorName(rpc::ActorId actor) const
{
return _pimpl->CallAndWait<std::string>("get_actor_name", actor);
}
std::string Client::GetActorClassName(rpc::ActorId actor) const
{
return _pimpl->CallAndWait<std::string>("get_actor_class_name", actor);
}
} // namespace detail } // namespace detail
} // namespace client } // namespace client
} // namespace carla } // namespace carla

View File

@ -439,6 +439,10 @@ namespace detail {
std::vector<rpc::LabelledPoint> CastRay( std::vector<rpc::LabelledPoint> CastRay(
geom::Location start_location, geom::Location end_location) const; geom::Location start_location, geom::Location end_location) const;
std::string GetActorName(rpc::ActorId actor) const;
std::string GetActorClassName(rpc::ActorId actor) const;
private: private:
class Pimpl; class Pimpl;

View File

@ -438,6 +438,16 @@ namespace detail {
return GetActorSnapshot(actor).acceleration; return GetActorSnapshot(actor).acceleration;
} }
std::string GetActorName(const Actor& actor) const
{
return _client.GetActorName(actor.GetId());
}
std::string GetActorClassName(const Actor& actor) const
{
return _client.GetActorClassName(actor.GetId());
}
void SetActorLocation(Actor &actor, const geom::Location &location) { void SetActorLocation(Actor &actor, const geom::Location &location) {
_client.SetActorLocation(actor.GetId(), location); _client.SetActorLocation(actor.GetId(), location);
} }

View File

@ -11,7 +11,7 @@
namespace carla { namespace carla {
namespace geom { namespace geom {
class Location; struct Location;
class GeoLocation { class GeoLocation {
public: public:

View File

@ -19,8 +19,7 @@
namespace carla { namespace carla {
namespace geom { namespace geom {
class Location : public Vector3D { struct Location : Vector3D {
public:
// ========================================================================= // =========================================================================
// -- Constructors --------------------------------------------------------- // -- Constructors ---------------------------------------------------------

View File

@ -14,8 +14,9 @@
namespace carla { namespace carla {
namespace geom { namespace geom {
class Vector2D { struct Vector2D {
public:
static constexpr auto Dim = 2;
// ========================================================================= // =========================================================================
// -- Public data members -------------------------------------------------- // -- Public data members --------------------------------------------------

View File

@ -14,8 +14,9 @@
namespace carla { namespace carla {
namespace geom { namespace geom {
class Vector3D { struct Vector3D {
public:
static constexpr auto Dim = 3;
// ========================================================================= // =========================================================================
// -- Public data members -------------------------------------------------- // -- Public data members --------------------------------------------------

View File

@ -11,7 +11,7 @@
#include <vector> #include <vector>
namespace carla { namespace carla {
namespace geom { class Location; } namespace geom { struct Location; }
namespace road { namespace road {
class Map; class Map;

View File

@ -22,7 +22,7 @@ class AActor;
namespace carla { namespace carla {
namespace geom { namespace geom {
class GeoLocation; class GeoLocation;
class Vector3D; struct Vector3D;
} }
namespace sensor { namespace sensor {
namespace data { namespace data {

View File

@ -16,313 +16,230 @@
#include <vector> #include <vector>
namespace carla { namespace carla {
namespace rpc { namespace rpc {
class VehiclePhysicsControl { struct VehiclePhysicsControl
public: {
// Engine Setup:
std::vector<geom::Vector2D> torque_curve = {
geom::Vector2D(0.0f, 500.0f),
geom::Vector2D(5000.0f, 500.0f)
};
VehiclePhysicsControl() = default; float max_torque = 300.0f;
float max_rpm = 5000.0f;
float idle_rpm = 1.0f;
float brake_effect = 1.0f;
float rev_up_moi = 1.0f;
float rev_down_rate = 600.0f;
VehiclePhysicsControl( // ToDo: Convert to an enum, see EVehicleDifferential.
const std::vector<carla::geom::Vector2D> &in_torque_curve, uint8_t differential_type = 0;
float in_max_torque, float front_rear_split = 0.5f;
float in_max_rpm,
float in_moi,
float in_rev_down_rate,
uint8_t in_differential_type, bool use_automatic_gears = true;
float in_front_rear_split, float gear_change_time = 0.5f;
float final_ratio = 4.0f;
std::vector<float> forward_gear_ratios = { 2.85, 2.02, 1.35, 1.0, 2.85, 2.02, 1.35, 1.0 };
std::vector<float> reverse_gear_ratios = { 2.86, 2.86 };
float change_up_rpm = 4500.0f;
float change_down_rpm = 2000.0f;
float transmission_efficiency = 0.9f;
bool in_use_gear_autobox, float mass = 1000.0f;
float in_gear_switch_time, float drag_coefficient = 0.3f;
float in_final_ratio, geom::Location center_of_mass = geom::Location(0, 0, 0);
std::vector<float> &in_forward_gears, float chassis_width = 180.f;
std::vector<float> &in_reverse_gears, float chassis_height = 140.f;
float in_change_up_rpm, float downforce_coefficient = 0.3f;
float in_change_down_rpm, float drag_area = 0.0f;
float in_transmission_efficiency, geom::Vector3D inertia_tensor_scale = geom::Vector3D(1, 1, 1);
float sleep_threshold = 10.0f;
float sleep_slope_limit = 0.866f;
float in_mass, std::vector<geom::Vector2D> steering_curve = {
float in_drag_coefficient, geom::Vector2D(0.0f, 1.0f),
geom::Location in_center_of_mass, geom::Vector2D(10.0f, 0.5f)
const std::vector<carla::geom::Vector2D> &in_steering_curve, };
std::vector<WheelPhysicsControl> &in_wheels, std::vector<WheelPhysicsControl> wheels;
bool in_use_sweep_wheel_collision)
: torque_curve(in_torque_curve),
max_torque(in_max_torque),
max_rpm(in_max_rpm),
moi(in_moi),
rev_down_rate(in_rev_down_rate),
differential_type(in_differential_type),
front_rear_split(in_front_rear_split),
use_gear_autobox(in_use_gear_autobox),
gear_switch_time(in_gear_switch_time),
final_ratio(in_final_ratio),
forward_gears(in_forward_gears),
reverse_gears(in_reverse_gears),
change_up_rpm(in_change_up_rpm),
change_down_rpm(in_change_down_rpm),
transmission_efficiency(in_transmission_efficiency),
mass(in_mass),
drag_coefficient(in_drag_coefficient),
center_of_mass(in_center_of_mass),
steering_curve(in_steering_curve),
wheels(in_wheels),
use_sweep_wheel_collision(in_use_sweep_wheel_collision) {}
const std::vector<float> &GetForwardGears() const { bool use_sweep_wheel_collision = false;
return forward_gears;
}
void SetForwardGears(std::vector<float> &in_forward_gears) { inline bool operator==(const VehiclePhysicsControl& rhs) const {
forward_gears = in_forward_gears; const bool cmp[] = {
} torque_curve == rhs.torque_curve,
max_torque == rhs.max_torque,
max_rpm == rhs.max_rpm,
idle_rpm == rhs.idle_rpm,
brake_effect == rhs.brake_effect,
rev_up_moi == rhs.rev_up_moi,
rev_down_rate == rhs.rev_down_rate,
differential_type == rhs.differential_type,
front_rear_split == rhs.front_rear_split,
use_automatic_gears == rhs.use_automatic_gears,
gear_change_time == rhs.gear_change_time,
final_ratio == rhs.final_ratio,
forward_gear_ratios == rhs.forward_gear_ratios,
reverse_gear_ratios == rhs.reverse_gear_ratios,
change_up_rpm == rhs.change_up_rpm,
change_down_rpm == rhs.change_down_rpm,
transmission_efficiency == rhs.transmission_efficiency,
mass == rhs.mass,
drag_coefficient == rhs.drag_coefficient,
center_of_mass == rhs.center_of_mass,
chassis_width == rhs.chassis_width,
chassis_height == rhs.chassis_height,
downforce_coefficient == rhs.downforce_coefficient,
drag_area == rhs.drag_area,
inertia_tensor_scale == rhs.inertia_tensor_scale,
sleep_threshold == rhs.sleep_threshold,
sleep_slope_limit == rhs.sleep_slope_limit,
steering_curve == rhs.steering_curve,
wheels == rhs.wheels,
use_sweep_wheel_collision == rhs.use_sweep_wheel_collision,
};
const std::vector<float> &GetReverseGears() const { return std::all_of(
return reverse_gears; std::begin(cmp),
} std::end(cmp),
std::identity());
}
void SetReverseGears(std::vector<float> &in_reverse_gears) { inline bool operator!=(const VehiclePhysicsControl& rhs) const {
reverse_gears = in_reverse_gears; return !(*this == rhs);
} }
const std::vector<WheelPhysicsControl> &GetWheels() const {
return wheels;
}
void SetWheels(std::vector<WheelPhysicsControl> &in_wheels) {
wheels = in_wheels;
}
const std::vector<geom::Vector2D> &GetTorqueCurve() const {
return torque_curve;
}
void SetTorqueCurve(std::vector<geom::Vector2D> &in_torque_curve) {
torque_curve = in_torque_curve;
}
const std::vector<geom::Vector2D> &GetSteeringCurve() const {
return steering_curve;
}
void SetSteeringCurve(std::vector<geom::Vector2D> &in_steering_curve) {
steering_curve = in_steering_curve;
}
void SetUseSweepWheelCollision(bool in_sweep) {
use_sweep_wheel_collision = in_sweep;
}
bool GetUseSweepWheelCollision() {
return use_sweep_wheel_collision;
}
std::vector<geom::Vector2D> torque_curve = {geom::Vector2D(0.0f, 500.0f), geom::Vector2D(5000.0f, 500.0f)};
float max_torque = 300.0f;
float max_rpm = 5000.0f;
float moi = 1.0f;
float rev_down_rate = 600.0f;
// ToDo: Convert to an enum, see EVehicleDifferential.
uint8_t differential_type = 0;
float front_rear_split = 0.5f;
bool use_gear_autobox = true;
float gear_switch_time = 0.5f;
float final_ratio = 4.0f;
std::vector<float> forward_gears = {2.85, 2.02, 1.35, 1.0, 2.85, 2.02, 1.35, 1.0};
std::vector<float> reverse_gears = {2.86, 2.86};
float change_up_rpm = 4500.0f;
float change_down_rpm = 2000.0f;
float transmission_efficiency = 0.9f;
float mass = 1000.0f;
float drag_coefficient = 0.3f;
geom::Location center_of_mass;
std::vector<geom::Vector2D> steering_curve = {geom::Vector2D(0.0f, 1.0f), geom::Vector2D(10.0f, 0.5f)};
std::vector<WheelPhysicsControl> wheels;
bool use_sweep_wheel_collision = false;
bool operator!=(const VehiclePhysicsControl &rhs) const {
return
max_torque != rhs.max_torque ||
max_rpm != rhs.max_rpm ||
moi != rhs.moi ||
rev_down_rate != rhs.rev_down_rate ||
differential_type != rhs.differential_type ||
front_rear_split != rhs.front_rear_split ||
use_gear_autobox != rhs.use_gear_autobox ||
gear_switch_time != rhs.gear_switch_time ||
final_ratio != rhs.final_ratio ||
forward_gears != rhs.forward_gears ||
reverse_gears != rhs.reverse_gears ||
change_up_rpm != rhs.change_up_rpm ||
change_down_rpm != rhs.change_down_rpm ||
transmission_efficiency != rhs.transmission_efficiency ||
mass != rhs.mass ||
drag_coefficient != rhs.drag_coefficient ||
steering_curve != rhs.steering_curve ||
center_of_mass != rhs.center_of_mass ||
wheels != rhs.wheels ||
use_sweep_wheel_collision != rhs.use_sweep_wheel_collision;
}
bool operator==(const VehiclePhysicsControl &rhs) const {
return !(*this != rhs);
}
#ifdef LIBCARLA_INCLUDED_FROM_UE4 #ifdef LIBCARLA_INCLUDED_FROM_UE4
VehiclePhysicsControl(const FVehiclePhysicsControl &Control) { static VehiclePhysicsControl FromFVehiclePhysicsControl(
// Engine Setup const FVehiclePhysicsControl& Control) {
torque_curve = std::vector<carla::geom::Vector2D>(); VehiclePhysicsControl Out = { };
TArray<FRichCurveKey> TorqueCurveKeys = Control.TorqueCurve.GetCopyOfKeys(); Out.torque_curve.reserve(Control.TorqueCurve.GetNumKeys());
for (int32 KeyIdx = 0; KeyIdx < TorqueCurveKeys.Num(); KeyIdx++) { for (auto& Key : Control.TorqueCurve.GetConstRefOfKeys())
geom::Vector2D point(TorqueCurveKeys[KeyIdx].Time, TorqueCurveKeys[KeyIdx].Value); Out.torque_curve.push_back(geom::Vector2D(Key.Time, Key.Value));
torque_curve.push_back(point); Out.max_torque = Control.MaxTorque;
} Out.max_rpm = Control.MaxRPM;
max_torque = Control.MaxTorque; Out.idle_rpm = Control.IdleRPM;
max_rpm = Control.MaxRPM; Out.brake_effect = Control.BrakeEffect;
moi = Control.MOI; Out.rev_up_moi = Control.RevUpMOI;
rev_down_rate = Control.RevDownRate; Out.rev_down_rate = Control.RevDownRate;
Out.differential_type = Control.DifferentialType;
// Differential Setup Out.front_rear_split = Control.FrontRearSplit;
differential_type = Control.DifferentialType; Out.use_automatic_gears = Control.bUseAutomaticGears;
front_rear_split = Control.FrontRearSplit; Out.gear_change_time = Control.GearChangeTime;
Out.final_ratio = Control.FinalRatio;
// Transmission Setup Out.forward_gear_ratios.resize(Control.ForwardGearRatios.Num());
use_gear_autobox = Control.bUseGearAutoBox; for (size_t i = 0; i != Out.forward_gear_ratios.size(); ++i)
gear_switch_time = Control.GearSwitchTime; Out.forward_gear_ratios[i] = Control.ForwardGearRatios[i];
final_ratio = Control.FinalRatio; Out.reverse_gear_ratios.resize(Control.ReverseGearRatios.Num());
change_up_rpm = Control.ChangeUpRPM; for (size_t i = 0; i != Out.reverse_gear_ratios.size(); ++i)
change_down_rpm = Control.ChangeDownRPM; Out.reverse_gear_ratios[i] = Control.ReverseGearRatios[i];
transmission_efficiency = Control.TransmissionEfficiency; Out.change_up_rpm = Control.ChangeUpRPM;
forward_gears = std::vector<float>(); Out.change_down_rpm = Control.ChangeDownRPM;
forward_gears.reserve(Control.ForwardGears.Num()); Out.transmission_efficiency = Control.TransmissionEfficiency;
for (const auto &Gear : Control.ForwardGears) { Out.mass = Control.Mass;
forward_gears.push_back(Gear); Out.drag_coefficient = Control.DragCoefficient;
} Out.center_of_mass = Control.CenterOfMass;
reverse_gears = std::vector<float>(); Out.chassis_width = Control.ChassisWidth;
reverse_gears.reserve(Control.ReverseGears.Num()); Out.chassis_height = Control.ChassisHeight;
for (const auto &Gear : Control.ReverseGears) { Out.downforce_coefficient = Control.DownforceCoefficient;
reverse_gears.push_back(Gear); Out.drag_area = Control.DragArea;
Out.inertia_tensor_scale = geom::Vector3D(
Control.InertiaTensorScale.X,
Control.InertiaTensorScale.Y,
Control.InertiaTensorScale.Z);
Out.sleep_threshold = Control.SleepThreshold;
Out.sleep_slope_limit = Control.SleepSlopeLimit;
Out.steering_curve.reserve(Control.SteeringCurve.GetNumKeys());
for (auto& Key : Control.SteeringCurve.GetConstRefOfKeys())
Out.steering_curve.push_back(geom::Vector2D(Key.Time, Key.Value));
Out.wheels.resize(Control.Wheels.Num());
for (size_t i = 0; i != Out.wheels.size(); ++i)
Out.wheels[i] = WheelPhysicsControl::FromFWheelPhysicsControl(Control.Wheels[i]);
Out.use_sweep_wheel_collision = Control.UseSweepWheelCollision;
return Out;
} }
// Vehicle Setup operator FVehiclePhysicsControl() const {
mass = Control.Mass; FVehiclePhysicsControl Control = { };
drag_coefficient = Control.DragCoefficient; for (auto [x, y] : torque_curve)
Control.TorqueCurve.AddKey(x, y);
steering_curve = std::vector<carla::geom::Vector2D>(); Control.MaxTorque = max_torque;
TArray<FRichCurveKey> SteeringCurveKeys = Control.SteeringCurve.GetCopyOfKeys(); Control.MaxRPM = max_rpm;
for (int32 KeyIdx = 0; KeyIdx < SteeringCurveKeys.Num(); KeyIdx++) { Control.IdleRPM = idle_rpm;
geom::Vector2D point(SteeringCurveKeys[KeyIdx].Time, SteeringCurveKeys[KeyIdx].Value); Control.BrakeEffect = brake_effect;
steering_curve.push_back(point); Control.RevUpMOI = rev_up_moi;
Control.RevDownRate = rev_down_rate;
Control.DifferentialType = differential_type;
Control.FrontRearSplit = front_rear_split;
Control.bUseAutomaticGears = use_automatic_gears;
Control.GearChangeTime = gear_change_time;
Control.FinalRatio = final_ratio;
Control.ForwardGearRatios.SetNum(forward_gear_ratios.size());
for (size_t i = 0; i != Control.ForwardGearRatios.Num(); ++i)
Control.ForwardGearRatios[i] = forward_gear_ratios[i];
Control.ReverseGearRatios.SetNum(reverse_gear_ratios.size());
for (size_t i = 0; i != Control.ReverseGearRatios.Num(); ++i)
Control.ReverseGearRatios[i] = reverse_gear_ratios[i];
Control.ChangeUpRPM = change_up_rpm;
Control.ChangeDownRPM = change_down_rpm;
Control.TransmissionEfficiency = transmission_efficiency;
Control.Mass = mass;
Control.DragCoefficient = drag_coefficient;
Control.CenterOfMass = center_of_mass;
Control.ChassisWidth = chassis_width;
Control.ChassisHeight = chassis_height;
Control.DownforceCoefficient = downforce_coefficient;
Control.DragArea = drag_area;
Control.InertiaTensorScale = FVector(
inertia_tensor_scale.x,
inertia_tensor_scale.y,
inertia_tensor_scale.z);
Control.SleepThreshold = sleep_threshold;
Control.SleepSlopeLimit = sleep_slope_limit;
for (auto [x, y] : steering_curve)
Control.SteeringCurve.AddKey(x, y);
Control.Wheels.SetNum(wheels.size());
for (size_t i = 0; i != Control.Wheels.Num(); ++i)
Control.Wheels[i] = wheels[i];
Control.UseSweepWheelCollision = use_sweep_wheel_collision;
return Control;
} }
center_of_mass = Control.CenterOfMass;
// Wheels Setup
wheels = std::vector<WheelPhysicsControl>();
for (const auto &Wheel : Control.Wheels) {
wheels.push_back(WheelPhysicsControl(Wheel));
}
use_sweep_wheel_collision = Control.UseSweepWheelCollision;
}
operator FVehiclePhysicsControl() const {
FVehiclePhysicsControl Control;
// Engine Setup
FRichCurve TorqueCurve;
for (const auto &point : torque_curve) {
TorqueCurve.AddKey(point.x, point.y);
}
Control.TorqueCurve = TorqueCurve;
Control.MaxTorque = max_torque;
Control.MaxRPM = max_rpm;
Control.MOI = moi;
Control.RevDownRate = rev_down_rate;
// Differential Setup
Control.DifferentialType = differential_type;
Control.FrontRearSplit = front_rear_split;
// Transmission Setup
Control.bUseGearAutoBox = use_gear_autobox;
Control.GearSwitchTime = gear_switch_time;
Control.FinalRatio = final_ratio;
Control.ChangeUpRPM = change_up_rpm;
Control.ChangeDownRPM = change_down_rpm;
Control.TransmissionEfficiency = transmission_efficiency;
TArray<float> ForwardGears;
ForwardGears.Reserve(forward_gears.size());
for (const auto &gear : forward_gears) {
ForwardGears.Add(gear);
}
Control.ForwardGears = ForwardGears;
TArray<float> ReverseGears;
ReverseGears.Reserve(reverse_gears.size());
for (const auto &gear : reverse_gears) {
ReverseGears.Add(gear);
}
Control.ReverseGears = ReverseGears;
// Vehicle Setup
Control.Mass = mass;
Control.DragCoefficient = drag_coefficient;
// Transmission Setup
FRichCurve SteeringCurve;
for (const auto &point : steering_curve) {
SteeringCurve.AddKey(point.x, point.y);
}
Control.SteeringCurve = SteeringCurve;
Control.CenterOfMass = center_of_mass;
// Wheels Setup
TArray<FWheelPhysicsControl> Wheels;
for (const auto &wheel : wheels) {
Wheels.Add(FWheelPhysicsControl(wheel));
}
Control.Wheels = Wheels;
Control.UseSweepWheelCollision = use_sweep_wheel_collision;
return Control;
}
#endif #endif
MSGPACK_DEFINE_ARRAY(torque_curve, MSGPACK_DEFINE_ARRAY(
torque_curve,
max_torque, max_torque,
max_rpm, max_rpm,
moi, idle_rpm,
brake_effect,
rev_up_moi,
rev_down_rate, rev_down_rate,
differential_type, differential_type,
front_rear_split, front_rear_split,
use_gear_autobox, use_automatic_gears,
gear_switch_time, gear_change_time,
final_ratio, final_ratio,
forward_gears, forward_gear_ratios,
reverse_gears, reverse_gear_ratios,
change_up_rpm, change_up_rpm,
change_down_rpm, change_down_rpm,
transmission_efficiency, transmission_efficiency,
mass, mass,
drag_coefficient, drag_coefficient,
center_of_mass, center_of_mass,
chassis_width,
chassis_height,
downforce_coefficient,
drag_area,
inertia_tensor_scale,
sleep_threshold,
sleep_slope_limit,
steering_curve, steering_curve,
wheels, wheels,
use_sweep_wheel_collision); use_sweep_wheel_collision
}; );
};
} // namespace rpc } // namespace rpc
} // namespace carla } // namespace carla

View File

@ -6,101 +6,255 @@
#pragma once #pragma once
#include "carla/geom/Vector2D.h"
#include "carla/geom/Vector3D.h" #include "carla/geom/Vector3D.h"
#include "carla/geom/Location.h"
#include "carla/MsgPack.h" #include "carla/MsgPack.h"
namespace carla { namespace carla {
namespace rpc { namespace rpc {
class WheelPhysicsControl { struct WheelPhysicsControl {
public:
WheelPhysicsControl() = default; uint8_t axle_type = 0; // @TODO INTRODUCE ENUM
geom::Vector3D offset = geom::Vector3D(0, 0, 0);
float wheel_radius = 30.0f;
float wheel_width = 30.0f;
float wheel_mass = 30.0f;
float cornering_stiffness = 1000.0f;
float friction_force_multiplier = 3.0f;
float side_slip_modifier = 1.0f;
float slip_threshold = 20.0f;
float skid_threshold = 20.0f;
float max_steer_angle = 70.0f;
bool affected_by_steering = true;
bool affected_by_brake = true;
bool affected_by_handbrake = true;
bool affected_by_engine = true;
bool abs_enabled = false;
bool traction_control_enabled = false;
float max_wheelspin_rotation = 30;
uint8_t external_torque_combine_method = 0; // @TODO INTRODUCE ENUM
std::vector<geom::Vector2D> lateral_slip_graph = {};
geom::Vector3D suspension_axis = geom::Vector3D(0, 0, -1);
geom::Vector3D suspension_force_offset = geom::Vector3D(0, 0, 0);
float suspension_max_raise = 10.0f;
float suspension_max_drop = 10.0f;
float suspension_damping_ratio = 0.5f;
float wheel_load_ratio = 0.5f;
float spring_rate = 250.0f;
float spring_preload = 50.0f;
int suspension_smoothing = 0;
float rollbar_scaling = 0.15f;
uint8_t sweep_shape = 0; // @TODO INTRODUCE ENUM
uint8_t sweep_type = 0; // @TODO INTRODUCE ENUM
float max_brake_torque = 1500.0f;
float max_hand_brake_torque = 3000.0f;
int32_t wheel_index = -1;
geom::Location location = geom::Location(0, 0, 0);
geom::Location old_location = geom::Location(0, 0, 0);
geom::Location velocity = geom::Location(0, 0, 0);
WheelPhysicsControl( inline bool operator==(const WheelPhysicsControl& rhs) const {
float in_tire_friction, const bool cmp[] =
float in_max_steer_angle, {
float in_radius, axle_type == rhs.axle_type,
float in_cornering_stiffness, offset == rhs.offset,
bool in_abs, wheel_radius == rhs.wheel_radius,
bool in_traction_control, wheel_width == rhs.wheel_width,
float in_max_brake_torque, wheel_mass == rhs.wheel_mass,
float in_max_handbrake_torque, cornering_stiffness == rhs.cornering_stiffness,
geom::Vector3D in_position) friction_force_multiplier == rhs.friction_force_multiplier,
: tire_friction(in_tire_friction), side_slip_modifier == rhs.side_slip_modifier,
max_steer_angle(in_max_steer_angle), slip_threshold == rhs.slip_threshold,
radius(in_radius), skid_threshold == rhs.skid_threshold,
cornering_stiffness(in_cornering_stiffness), max_steer_angle == rhs.max_steer_angle,
abs(in_abs), affected_by_steering == rhs.affected_by_steering,
traction_control(in_traction_control), affected_by_brake == rhs.affected_by_brake,
max_brake_torque(in_max_brake_torque), affected_by_handbrake == rhs.affected_by_handbrake,
max_handbrake_torque(in_max_handbrake_torque), affected_by_engine == rhs.affected_by_engine,
position(in_position) {} abs_enabled == rhs.abs_enabled,
traction_control_enabled == rhs.traction_control_enabled,
max_wheelspin_rotation == rhs.max_wheelspin_rotation,
external_torque_combine_method == rhs.external_torque_combine_method,
lateral_slip_graph == rhs.lateral_slip_graph,
suspension_axis == rhs.suspension_axis,
suspension_force_offset == rhs.suspension_force_offset,
suspension_max_raise == rhs.suspension_max_raise,
suspension_max_drop == rhs.suspension_max_drop,
suspension_damping_ratio == rhs.suspension_damping_ratio,
wheel_load_ratio == rhs.wheel_load_ratio,
spring_rate == rhs.spring_rate,
spring_preload == rhs.spring_preload,
suspension_smoothing == rhs.suspension_smoothing,
rollbar_scaling == rhs.rollbar_scaling,
sweep_shape == rhs.sweep_shape,
sweep_type == rhs.sweep_type,
max_brake_torque == rhs.max_brake_torque,
max_hand_brake_torque == rhs.max_hand_brake_torque,
wheel_index == rhs.wheel_index,
location == rhs.location,
old_location == rhs.old_location,
velocity == rhs.velocity
};
return std::all_of(std::begin(cmp), std::end(cmp), std::identity());
}
float tire_friction = 3.0f; inline bool operator!=(const WheelPhysicsControl& rhs) const {
float max_steer_angle = 70.0f; return !(*this == rhs);
float radius = 30.0f; }
float cornering_stiffness = 1000.0f;
bool abs = false;
bool traction_control = false;
float max_brake_torque = 1500.0f;
float max_handbrake_torque = 3000.0f;
geom::Vector3D position = {0.0f, 0.0f, 0.0f};
bool operator!=(const WheelPhysicsControl &rhs) const {
return
tire_friction != rhs.tire_friction ||
max_steer_angle != rhs.max_steer_angle ||
radius != rhs.radius ||
cornering_stiffness != rhs.cornering_stiffness ||
abs != rhs.abs ||
traction_control != rhs.traction_control ||
max_brake_torque != rhs.max_brake_torque ||
max_handbrake_torque != rhs.max_handbrake_torque ||
position != rhs.position;
}
bool operator==(const WheelPhysicsControl &rhs) const {
return !(*this != rhs);
}
#ifdef LIBCARLA_INCLUDED_FROM_UE4 #ifdef LIBCARLA_INCLUDED_FROM_UE4
WheelPhysicsControl(const FWheelPhysicsControl &Wheel) static WheelPhysicsControl FromFWheelPhysicsControl(
: tire_friction(Wheel.FrictionForceMultiplier), const FWheelPhysicsControl& Wheel)
max_steer_angle(Wheel.MaxSteerAngle), {
radius(Wheel.Radius), WheelPhysicsControl Out = { };
cornering_stiffness(Wheel.CorneringStiffness), Out.axle_type = (uint8_t)Wheel.AxleType;
abs(Wheel.bABSEnabled), Out.offset = geom::Vector3D(
traction_control(Wheel.bTractionControlEnabled), Wheel.Offset.X,
max_brake_torque(Wheel.MaxBrakeTorque), Wheel.Offset.Y,
max_handbrake_torque(Wheel.MaxHandBrakeTorque), Wheel.Offset.Z);
position(Wheel.Position.X, Wheel.Position.Y, Wheel.Position.Z) {} Out.wheel_radius = Wheel.WheelRadius;
Out.wheel_width = Wheel.WheelWidth;
Out.wheel_mass = Wheel.WheelMass;
Out.cornering_stiffness = Wheel.CorneringStiffness;
Out.friction_force_multiplier = Wheel.FrictionForceMultiplier;
Out.side_slip_modifier = Wheel.SideSlipModifier;
Out.slip_threshold = Wheel.SlipThreshold;
Out.skid_threshold = Wheel.SkidThreshold;
Out.max_steer_angle = Wheel.MaxSteerAngle;
Out.affected_by_steering = Wheel.bAffectedBySteering;
Out.affected_by_brake = Wheel.bAffectedByBrake;
Out.affected_by_handbrake = Wheel.bAffectedByHandbrake;
Out.affected_by_engine = Wheel.bAffectedByEngine;
Out.abs_enabled = Wheel.bABSEnabled;
Out.traction_control_enabled = Wheel.bTractionControlEnabled;
Out.max_wheelspin_rotation = Wheel.MaxWheelspinRotation;
Out.external_torque_combine_method = (uint8_t)Wheel.ExternalTorqueCombineMethod;
Out.lateral_slip_graph.reserve(Wheel.LateralSlipGraph.GetNumKeys());
for (auto& e : Wheel.LateralSlipGraph.GetConstRefOfKeys())
Out.lateral_slip_graph.push_back({ e.Time, e.Value });
Out.suspension_axis = geom::Vector3D(
Wheel.SuspensionAxis.X,
Wheel.SuspensionAxis.Y,
Wheel.SuspensionAxis.Z);
Out.suspension_force_offset = geom::Vector3D(
Wheel.SuspensionForceOffset.X,
Wheel.SuspensionForceOffset.Y,
Wheel.SuspensionForceOffset.Z);
Out.suspension_max_raise = Wheel.SuspensionMaxRaise;
Out.suspension_max_drop = Wheel.SuspensionMaxDrop;
Out.suspension_damping_ratio = Wheel.SuspensionDampingRatio;
Out.wheel_load_ratio = Wheel.WheelLoadRatio;
Out.spring_rate = Wheel.SpringRate;
Out.spring_preload = Wheel.SpringPreload;
Out.suspension_smoothing = Wheel.SuspensionSmoothing;
Out.rollbar_scaling = Wheel.RollbarScaling;
Out.sweep_shape = (uint8_t)Wheel.SweepShape;
Out.sweep_type = (uint8_t)Wheel.SweepType;
Out.max_brake_torque = Wheel.MaxBrakeTorque;
Out.max_hand_brake_torque = Wheel.MaxHandBrakeTorque;
Out.wheel_index = Wheel.WheelIndex;
Out.location = Wheel.Location;
Out.old_location = Wheel.OldLocation;
Out.velocity = Wheel.Velocity;
return Out;
}
operator FWheelPhysicsControl() const { operator FWheelPhysicsControl() const {
FWheelPhysicsControl Wheel; FWheelPhysicsControl Wheel;
Wheel.FrictionForceMultiplier = tire_friction; Wheel.AxleType = (EAxleType)axle_type;
Wheel.MaxSteerAngle = max_steer_angle; Wheel.Offset = FVector(offset.x, offset.y, offset.z);
Wheel.Radius = radius; Wheel.WheelRadius = wheel_radius;
Wheel.CorneringStiffness = cornering_stiffness; Wheel.WheelWidth = wheel_width;
Wheel.bABSEnabled = abs; Wheel.WheelMass = wheel_mass;
Wheel.bTractionControlEnabled = traction_control; Wheel.CorneringStiffness = cornering_stiffness;
Wheel.MaxBrakeTorque = max_brake_torque; Wheel.FrictionForceMultiplier = friction_force_multiplier;
Wheel.MaxHandBrakeTorque = max_handbrake_torque; Wheel.SideSlipModifier = side_slip_modifier;
Wheel.Position = {position.x, position.y, position.z}; Wheel.SlipThreshold = slip_threshold;
return Wheel; Wheel.SkidThreshold = skid_threshold;
} Wheel.MaxSteerAngle = max_steer_angle;
Wheel.bAffectedBySteering = affected_by_steering;
Wheel.bAffectedByBrake = affected_by_brake;
Wheel.bAffectedByHandbrake = affected_by_handbrake;
Wheel.bAffectedByEngine = affected_by_engine;
Wheel.bABSEnabled = abs_enabled;
Wheel.bTractionControlEnabled = traction_control_enabled;
Wheel.MaxWheelspinRotation = max_wheelspin_rotation;
Wheel.ExternalTorqueCombineMethod = (ETorqueCombineMethod)external_torque_combine_method;
for (auto [x, y] : lateral_slip_graph)
Wheel.LateralSlipGraph.AddKey(x, y);
Wheel.SuspensionAxis = FVector(
suspension_axis.x,
suspension_axis.y,
suspension_axis.z);
Wheel.SuspensionForceOffset = FVector(
suspension_force_offset.x,
suspension_force_offset.y,
suspension_force_offset.z);
Wheel.SuspensionMaxRaise = suspension_max_raise;
Wheel.SuspensionMaxDrop = suspension_max_drop;
Wheel.SuspensionDampingRatio = suspension_damping_ratio;
Wheel.WheelLoadRatio = wheel_load_ratio;
Wheel.SpringRate = spring_rate;
Wheel.SpringPreload = spring_preload;
Wheel.SuspensionSmoothing = suspension_smoothing;
Wheel.RollbarScaling = rollbar_scaling;
Wheel.SweepShape = (ESweepShape)sweep_shape;
Wheel.SweepType = (ESweepType)sweep_type;
Wheel.MaxBrakeTorque = max_brake_torque;
Wheel.MaxHandBrakeTorque = max_hand_brake_torque;
Wheel.WheelIndex = wheel_index;
Wheel.Location = location;
Wheel.OldLocation = old_location;
Wheel.Velocity = velocity;
return Wheel;
}
#endif #endif
MSGPACK_DEFINE_ARRAY(tire_friction, MSGPACK_DEFINE_ARRAY(
max_steer_angle, axle_type,
radius, offset,
wheel_radius,
wheel_width,
wheel_mass,
cornering_stiffness, cornering_stiffness,
abs, friction_force_multiplier,
traction_control, side_slip_modifier,
slip_threshold,
skid_threshold,
max_steer_angle,
affected_by_steering,
affected_by_brake,
affected_by_handbrake,
affected_by_engine,
abs_enabled,
traction_control_enabled,
max_wheelspin_rotation,
external_torque_combine_method,
lateral_slip_graph,
suspension_axis,
suspension_force_offset,
suspension_max_raise,
suspension_max_drop,
suspension_damping_ratio,
wheel_load_ratio,
spring_rate,
spring_preload,
suspension_smoothing,
rollbar_scaling,
sweep_shape,
sweep_type,
max_brake_torque, max_brake_torque,
max_handbrake_torque, max_hand_brake_torque,
position) wheel_index,
}; location,
old_location,
velocity)
};
} }
} }

View File

@ -134,7 +134,6 @@ namespace detail {
geom::Vector3D angular_velocity; geom::Vector3D angular_velocity;
geom::Vector3D acceleration; geom::Vector3D acceleration;
union TypeDependentState { union TypeDependentState {
detail::TrafficLightData traffic_light_data; detail::TrafficLightData traffic_light_data;
detail::TrafficSignData traffic_sign_data; detail::TrafficSignData traffic_sign_data;

View File

@ -15,7 +15,6 @@
#include <boost/asio/connect.hpp> #include <boost/asio/connect.hpp>
#include <boost/asio/read.hpp> #include <boost/asio/read.hpp>
#include <boost/asio/write.hpp> #include <boost/asio/write.hpp>
#include <boost/asio/post.hpp>
#include <boost/asio/bind_executor.hpp> #include <boost/asio/bind_executor.hpp>
#include <exception> #include <exception>
@ -86,7 +85,6 @@ namespace tcp {
void Client::Connect() { void Client::Connect() {
auto self = shared_from_this(); auto self = shared_from_this();
boost::asio::post(_strand, [this, self]() {
if (_done) { if (_done) {
return; return;
} }
@ -139,18 +137,15 @@ namespace tcp {
log_debug("streaming client: connecting to", ep); log_debug("streaming client: connecting to", ep);
_socket.async_connect(ep, boost::asio::bind_executor(_strand, handle_connect)); _socket.async_connect(ep, boost::asio::bind_executor(_strand, handle_connect));
});
} }
void Client::Stop() { void Client::Stop() {
_connection_timer.cancel(); _connection_timer.cancel();
auto self = shared_from_this(); auto self = shared_from_this();
boost::asio::post(_strand, [this, self]() {
_done = true; _done = true;
if (_socket.is_open()) { if (_socket.is_open()) {
_socket.close(); _socket.close();
} }
});
} }
void Client::Reconnect() { void Client::Reconnect() {
@ -165,7 +160,6 @@ namespace tcp {
void Client::ReadData() { void Client::ReadData() {
auto self = shared_from_this(); auto self = shared_from_this();
boost::asio::post(_strand, [this, self]() {
if (_done) { if (_done) {
return; return;
} }
@ -182,7 +176,7 @@ namespace tcp {
// Move the buffer to the callback function and start reading the next // Move the buffer to the callback function and start reading the next
// piece of data. // piece of data.
// log_debug("streaming client: success reading data, calling the callback"); // log_debug("streaming client: success reading data, calling the callback");
boost::asio::post(_strand, [self, message]() { self->_callback(message->pop()); }); _callback(message->pop());
ReadData(); ReadData();
} else { } else {
// As usual, if anything fails start over from the very top. // As usual, if anything fails start over from the very top.
@ -219,7 +213,6 @@ namespace tcp {
_socket, _socket,
message->size_as_buffer(), message->size_as_buffer(),
boost::asio::bind_executor(_strand, handle_read_header)); boost::asio::bind_executor(_strand, handle_read_header));
});
} }
} // namespace tcp } // namespace tcp

View File

@ -79,43 +79,39 @@ namespace tcp {
DEBUG_ASSERT(message != nullptr); DEBUG_ASSERT(message != nullptr);
DEBUG_ASSERT(!message->empty()); DEBUG_ASSERT(!message->empty());
auto self = shared_from_this(); auto self = shared_from_this();
boost::asio::post(_strand, [=]() { if (!_socket.is_open()) {
if (!_socket.is_open()) { return;
}
if (_is_writing) {
if (_server.IsSynchronousMode()) {
// wait until previous message has been sent
while (_is_writing) {
std::this_thread::yield();
}
} else {
// ignore this message
log_debug("session", _session_id, ": connection too slow: message discarded");
return; return;
} }
if (_is_writing) { }
if (_server.IsSynchronousMode()) { _is_writing = true;
// wait until previous message has been sent
while (_is_writing) { auto handle_sent = [this, self, message](const boost::system::error_code &ec, size_t DEBUG_ONLY(bytes)) {
std::this_thread::yield(); _is_writing = false;
} if (ec) {
} else { log_info("session", _session_id, ": error sending data :", ec.message());
// ignore this message CloseNow(ec);
log_debug("session", _session_id, ": connection too slow: message discarded"); } else {
return; DEBUG_ONLY(log_debug("session", _session_id, ": successfully sent", bytes, "bytes"));
} DEBUG_ASSERT_EQ(bytes, sizeof(message_size_type) + message->size());
} }
_is_writing = true; };
auto handle_sent = [this, self, message](const boost::system::error_code &ec, size_t DEBUG_ONLY(bytes)) { log_debug("session", _session_id, ": sending message of", message->size(), "bytes");
_is_writing = false;
if (ec) {
log_info("session", _session_id, ": error sending data :", ec.message());
CloseNow(ec);
} else {
DEBUG_ONLY(log_debug("session", _session_id, ": successfully sent", bytes, "bytes"));
DEBUG_ASSERT_EQ(bytes, sizeof(message_size_type) + message->size());
}
};
log_debug("session", _session_id, ": sending message of", message->size(), "bytes"); _deadline.expires_from_now(_timeout);
boost::asio::async_write(_socket, message->GetBufferSequence(),
_deadline.expires_from_now(_timeout); boost::asio::bind_executor(_strand, handle_sent));
boost::asio::async_write(
_socket,
message->GetBufferSequence(),
handle_sent);
});
} }
void ServerSession::Close() { void ServerSession::Close() {

View File

@ -23,19 +23,75 @@ set (
RecastNavigation::DetourCrowd RecastNavigation::DetourCrowd
) )
get_target_property (Boost_asio_TARGET_NAME Boost::asio ALIASED_TARGET) get_target_property (
get_target_property (Boost_python_TARGET_NAME Boost::python${Python3_VERSION_MAJOR}${Python3_VERSION_MINOR} ALIASED_TARGET) Boost_asio_TARGET_NAME
get_target_property (Boost_geometry_TARGET_NAME Boost::geometry ALIASED_TARGET) Boost::asio
get_target_property (Boost_gil_TARGET_NAME Boost::gil ALIASED_TARGET) ALIASED_TARGET
get_target_property (RecastNavigation_Recast_TARGET_NAME RecastNavigation::Recast ALIASED_TARGET) )
get_target_property (RecastNavigation_Detour_TARGET_NAME RecastNavigation::Detour ALIASED_TARGET)
get_target_property (RecastNavigation_DetourCrowd_TARGET_NAME RecastNavigation::DetourCrowd ALIASED_TARGET) get_target_property (
Boost_python_TARGET_NAME
Boost::python${Python3_VERSION_MAJOR}${Python3_VERSION_MINOR}
ALIASED_TARGET
)
get_target_property (
Boost_geometry_TARGET_NAME
Boost::geometry
ALIASED_TARGET
)
get_target_property (
Boost_gil_TARGET_NAME
Boost::gil
ALIASED_TARGET
)
get_target_property (
RecastNavigation_Recast_TARGET_NAME
RecastNavigation::Recast
ALIASED_TARGET
)
get_target_property (
RecastNavigation_Detour_TARGET_NAME
RecastNavigation::Detour
ALIASED_TARGET
)
get_target_property (
RecastNavigation_DetourCrowd_TARGET_NAME
RecastNavigation::DetourCrowd
ALIASED_TARGET
)
set ( set (
CARLA_PYTHON_API_CARLA_PATH CARLA_PYTHON_API_CARLA_PATH
${CMAKE_CURRENT_SOURCE_DIR}/carla ${CMAKE_CURRENT_SOURCE_DIR}/carla
) )
set (
CARLA_PYTHON_API_CMAKE_ARGS
"\t'-G${CMAKE_GENERATOR}'"
)
set (
CARLA_PYTHON_API_CMAKE_ARGS
"${CARLA_PYTHON_API_CMAKE_ARGS},\n\t'-DCMAKE_C_COMPILER=${CMAKE_C_COMPILER}'"
)
set (
CARLA_PYTHON_API_CMAKE_ARGS
"${CARLA_PYTHON_API_CMAKE_ARGS},\n\t'-DCMAKE_CXX_COMPILER=${CMAKE_CXX_COMPILER}'"
)
if (CMAKE_TOOLCHAIN_FILE)
set (
CARLA_PYTHON_API_CMAKE_ARGS
"${CARLA_PYTHON_API_CMAKE_ARGS},\n\t\'--toolchain=${CMAKE_TOOLCHAIN_FILE}\'"
)
endif ()
carla_two_step_configure_file ( carla_two_step_configure_file (
${CARLA_PYTHON_API_CARLA_PATH}/pyproject.toml ${CARLA_PYTHON_API_CARLA_PATH}/pyproject.toml
${CARLA_PYTHON_API_CARLA_PATH}/pyproject.toml.in ${CARLA_PYTHON_API_CARLA_PATH}/pyproject.toml.in

View File

@ -1,6 +1,6 @@
cmake_minimum_required ( cmake_minimum_required (
VERSION VERSION
@CMAKE_MAJOR_VERSION@.@CMAKE_MINOR_VERSION@.@CMAKE_PATCH_VERSION@ @CARLA_CMAKE_MINIMUM_REQUIRED_VERSION@
) )
project ( project (
@ -47,7 +47,7 @@ set (
${CMAKE_CURRENT_SOURCE_DIR} ${CMAKE_CURRENT_SOURCE_DIR}
) )
carla_message ( carla_message_verbose (
"Selected Python executable: ${Python3_EXECUTABLE} (Interpreter ID: ${Python3_INTERPRETER_ID})" "Selected Python executable: ${Python3_EXECUTABLE} (Interpreter ID: ${Python3_INTERPRETER_ID})"
) )

View File

@ -466,40 +466,80 @@ namespace rpc {
} }
inline std::ostream &operator<<(std::ostream &out, const WheelPhysicsControl &control) { inline std::ostream &operator<<(std::ostream &out, const WheelPhysicsControl &control) {
out << "WheelPhysicsControl(tire_friction=" << std::to_string(control.tire_friction) out << "WheelPhysicsControl(axle_type=" << std::to_string(control.axle_type)
<< ", max_steer_angle=" << std::to_string(control.max_steer_angle) << ", offset" << control.offset
<< ", radius=" << std::to_string(control.radius) << ", wheel_radius=" << std::to_string(control.wheel_radius)
<< ", cornering_stiffness=" << std::to_string(control.cornering_stiffness) << ", wheel_width=" << std::to_string(control.wheel_width)
<< ", abs=" << std::to_string(control.abs) << ", wheel_mass=" << std::to_string(control.wheel_mass)
<< ", traction_control=" << std::to_string(control.traction_control) << ", cornering_stiffness=" << std::to_string(control.cornering_stiffness)
<< ", max_brake_torque=" << std::to_string(control.max_brake_torque) << ", friction_force_multiplier=" << std::to_string(control.friction_force_multiplier)
<< ", max_handbrake_torque=" << std::to_string(control.max_handbrake_torque) << ", side_slip_modifier=" << std::to_string(control.side_slip_modifier)
<< ", position=" << control.position << ')'; << ", slip_threshold=" << std::to_string(control.slip_threshold)
<< ", skid_threshold=" << std::to_string(control.skid_threshold)
<< ", max_steer_angle=" << std::to_string(control.max_steer_angle)
<< ", affected_by_steering=" << std::to_string(control.affected_by_steering)
<< ", affected_by_brake=" << std::to_string(control.affected_by_brake)
<< ", affected_by_handbrake=" << std::to_string(control.affected_by_handbrake)
<< ", affected_by_engine=" << std::to_string(control.affected_by_engine)
<< ", abs_enabled=" << std::to_string(control.abs_enabled)
<< ", traction_control_enabled=" << std::to_string(control.traction_control_enabled)
<< ", max_wheelspin_rotation=" << std::to_string(control.max_wheelspin_rotation)
<< ", external_torque_combine_method=" << std::to_string(control.external_torque_combine_method)
<< ", lateral_slip_graph=" << control.lateral_slip_graph
<< ", suspension_axis=" << control.suspension_axis
<< ", suspension_force_offset=" << control.suspension_force_offset
<< ", suspension_max_raise=" << std::to_string(control.suspension_max_raise)
<< ", suspension_max_drop=" << std::to_string(control.suspension_max_drop)
<< ", suspension_damping_ratio=" << std::to_string(control.suspension_damping_ratio)
<< ", wheel_load_ratio=" << std::to_string(control.wheel_load_ratio)
<< ", spring_rate=" << std::to_string(control.spring_rate)
<< ", spring_preload=" << std::to_string(control.spring_preload)
<< ", suspension_smoothing=" << std::to_string(control.suspension_smoothing)
<< ", rollbar_scaling=" << std::to_string(control.rollbar_scaling)
<< ", sweep_shape=" << std::to_string(control.sweep_shape)
<< ", sweep_type=" << std::to_string(control.sweep_type)
<< ", max_brake_torque=" << std::to_string(control.max_brake_torque)
<< ", max_hand_brake_torque=" << std::to_string(control.max_hand_brake_torque)
<< ", wheel_index=" << std::to_string(control.wheel_index)
<< ", location=" << control.location
<< ", old_location=" << control.old_location
<< ", velocity=" << control.velocity
<< ')';
return out; return out;
} }
inline std::ostream &operator<<(std::ostream &out, const VehiclePhysicsControl &control) { inline std::ostream &operator<<(std::ostream &out, const VehiclePhysicsControl &control) {
out << "VehiclePhysicsControl(torque_curve=" << control.torque_curve out << "VehiclePhysicsControl(torque_curve=" << control.torque_curve
<< ", max_torque=" << std::to_string(control.max_torque) << ", max_torque=" << control.max_torque
<< ", max_rpm=" << std::to_string(control.max_rpm) << ", max_rpm=" << control.max_rpm
<< ", moi=" << std::to_string(control.moi) << ", idle_rpm=" << control.idle_rpm
<< ", rev_down_rate=" << std::to_string(control.rev_down_rate) << ", brake_effect=" << control.brake_effect
<< ", differential_type=" << std::to_string(control.differential_type) << ", rev_up_moi=" << control.rev_up_moi
<< ", front_rear_split=" << std::to_string(control.front_rear_split) << ", rev_down_rate=" << control.rev_down_rate
<< ", use_gear_autobox=" << boolalpha(control.use_gear_autobox) << ", differential_type=" << control.differential_type
<< ", gear_switch_time=" << std::to_string(control.gear_switch_time) << ", front_rear_split=" << control.front_rear_split
<< ", final_ratio=" << std::to_string(control.final_ratio) << ", use_automatic_gears=" << control.use_automatic_gears
<< ", forward_gears=" << control.forward_gears << ", gear_change_time=" << control.gear_change_time
<< ", reverse_gears=" << control.reverse_gears << ", final_ratio=" << control.final_ratio
<< ", change_up_rpm=" << std::to_string(control.change_up_rpm) << ", forward_gear_ratios=" << control.forward_gear_ratios
<< ", change_down_rpm=" << std::to_string(control.change_down_rpm) << ", reverse_gear_ratios=" << control.reverse_gear_ratios
<< ", transmission_efficiency=" << std::to_string(control.transmission_efficiency) << ", change_up_rpm=" << control.change_up_rpm
<< ", mass=" << std::to_string(control.mass) << ", change_down_rpm=" << control.change_down_rpm
<< ", drag_coefficient=" << std::to_string(control.drag_coefficient) << ", transmission_efficiency=" << control.transmission_efficiency
<< ", center_of_mass=" << control.center_of_mass << ", mass=" << control.mass
<< ", steering_curve=" << control.steering_curve << ", drag_coefficient=" << control.drag_coefficient
<< ", wheels=" << control.wheels << ", center_of_mass=" << control.center_of_mass
<< ", use_sweep_wheel_collision=" << control.use_sweep_wheel_collision << ')'; << ", chassis_width=" << control.chassis_width
<< ", chassis_height=" << control.chassis_height
<< ", downforce_coefficient=" << control.downforce_coefficient
<< ", drag_area=" << control.drag_area
<< ", inertia_tensor_scale=" << control.inertia_tensor_scale
<< ", sleep_threshold=" << control.sleep_threshold
<< ", sleep_slope_limit=" << control.sleep_slope_limit
<< ", steering_curve=" << control.steering_curve
<< ", wheels=" << control.wheels
<< ", use_sweep_wheel_collision=" << control.use_sweep_wheel_collision
<< ")";
return out; return out;
} }
@ -556,4 +596,4 @@ inline auto MakeCallback(boost::python::object callback) {
PyErr_Print(); PyErr_Print();
} }
}; };
} }

View File

@ -7,8 +7,10 @@ wheel.packages = ['carla']
cmake.version = '>=@CMAKE_MAJOR_VERSION@.@CMAKE_MINOR_VERSION@' cmake.version = '>=@CMAKE_MAJOR_VERSION@.@CMAKE_MINOR_VERSION@'
cmake.build-type = '@CMAKE_BUILD_TYPE@' cmake.build-type = '@CMAKE_BUILD_TYPE@'
cmake.args = [ cmake.args = [
'-DCMAKE_TOOLCHAIN_FILE=@CMAKE_TOOLCHAIN_FILE@' @CARLA_PYTHON_API_CMAKE_ARGS@
] ]
ninja.version=">=1.10"
ninja.make-fallback=true
[project] [project]
name = 'carla' name = 'carla'

View File

@ -111,6 +111,8 @@ void export_actor() {
.def("get_velocity", &cc::Actor::GetVelocity) .def("get_velocity", &cc::Actor::GetVelocity)
.def("get_angular_velocity", &cc::Actor::GetAngularVelocity) .def("get_angular_velocity", &cc::Actor::GetAngularVelocity)
.def("get_acceleration", &cc::Actor::GetAcceleration) .def("get_acceleration", &cc::Actor::GetAcceleration)
.def("get_actor_name", &cc::Actor::GetActorName)
.def("get_actor_class_name", &cc::Actor::GetActorClassName)
.def("set_location", &cc::Actor::SetLocation, (arg("location"))) .def("set_location", &cc::Actor::SetLocation, (arg("location")))
.def("set_transform", &cc::Actor::SetTransform, (arg("transform"))) .def("set_transform", &cc::Actor::SetTransform, (arg("transform")))
.def("set_target_velocity", &cc::Actor::SetTargetVelocity, (arg("velocity"))) .def("set_target_velocity", &cc::Actor::SetTargetVelocity, (arg("velocity")))

View File

@ -46,7 +46,7 @@ static auto GetVectorOfBoneTransformFromList(const boost::python::list &list) {
} }
static auto GetWheels(const carla::rpc::VehiclePhysicsControl &self) { static auto GetWheels(const carla::rpc::VehiclePhysicsControl &self) {
const auto &wheels = self.GetWheels(); auto &wheels = self.wheels;
boost::python::object get_iter = boost::python::iterator<std::vector<carla::rpc::WheelPhysicsControl>>(); boost::python::object get_iter = boost::python::iterator<std::vector<carla::rpc::WheelPhysicsControl>>();
boost::python::object iter = get_iter(wheels); boost::python::object iter = get_iter(wheels);
return boost::python::list(iter); return boost::python::list(iter);
@ -61,40 +61,40 @@ static void SetWheels(carla::rpc::VehiclePhysicsControl &self, const boost::pyth
self.wheels = wheels; self.wheels = wheels;
} }
static auto GetForwardGears(const carla::rpc::VehiclePhysicsControl &self) { static auto GetForwardGearRatios(const carla::rpc::VehiclePhysicsControl &self) {
const auto &gears = self.GetForwardGears(); auto &gears = self.forward_gear_ratios;
boost::python::object get_iter = boost::python::iterator<std::vector<float>>(); boost::python::object get_iter = boost::python::iterator<std::vector<float>>();
boost::python::object iter = get_iter(gears); boost::python::object iter = get_iter(gears);
return boost::python::list(iter); return boost::python::list(iter);
} }
static void SetForwardGears(carla::rpc::VehiclePhysicsControl &self, const boost::python::list &list) { static void SetForwardGearRatios(carla::rpc::VehiclePhysicsControl &self, const boost::python::list &list) {
std::vector<float> gears; std::vector<float> gears;
auto length = boost::python::len(list); auto length = boost::python::len(list);
for (auto i = 0u; i < length; ++i) { for (auto i = 0u; i < length; ++i) {
gears.push_back(boost::python::extract<float &>(list[i])); gears.push_back(boost::python::extract<float &>(list[i]));
} }
self.SetForwardGears(gears); self.forward_gear_ratios = gears;
} }
static auto GetReverseGears(const carla::rpc::VehiclePhysicsControl &self) { static auto GetReverseGearRatios(const carla::rpc::VehiclePhysicsControl &self) {
const auto &gears = self.GetReverseGears(); auto &gears = self.reverse_gear_ratios;
boost::python::object get_iter = boost::python::iterator<std::vector<float>>(); boost::python::object get_iter = boost::python::iterator<std::vector<float>>();
boost::python::object iter = get_iter(gears); boost::python::object iter = get_iter(gears);
return boost::python::list(iter); return boost::python::list(iter);
} }
static void SetReverseGears(carla::rpc::VehiclePhysicsControl &self, const boost::python::list &list) { static void SetReverseGearRatios(carla::rpc::VehiclePhysicsControl &self, const boost::python::list &list) {
std::vector<float> gears; std::vector<float> gears;
auto length = boost::python::len(list); auto length = boost::python::len(list);
for (auto i = 0u; i < length; ++i) { for (auto i = 0u; i < length; ++i) {
gears.push_back(boost::python::extract<float &>(list[i])); gears.push_back(boost::python::extract<float &>(list[i]));
} }
self.SetReverseGears(gears); self.reverse_gear_ratios = gears;
} }
static auto GetTorqueCurve(const carla::rpc::VehiclePhysicsControl &self) { static auto GetTorqueCurve(const carla::rpc::VehiclePhysicsControl &self) {
const std::vector<carla::geom::Vector2D> &torque_curve = self.GetTorqueCurve(); auto &torque_curve = self.torque_curve;
boost::python::object get_iter = boost::python::iterator<const std::vector<carla::geom::Vector2D>>(); boost::python::object get_iter = boost::python::iterator<const std::vector<carla::geom::Vector2D>>();
boost::python::object iter = get_iter(torque_curve); boost::python::object iter = get_iter(torque_curve);
return boost::python::list(iter); return boost::python::list(iter);
@ -105,7 +105,7 @@ static void SetTorqueCurve(carla::rpc::VehiclePhysicsControl &self, const boost:
} }
static auto GetSteeringCurve(const carla::rpc::VehiclePhysicsControl &self) { static auto GetSteeringCurve(const carla::rpc::VehiclePhysicsControl &self) {
const std::vector<carla::geom::Vector2D> &steering_curve = self.GetSteeringCurve(); auto &steering_curve = self.steering_curve;
boost::python::object get_iter = boost::python::iterator<const std::vector<carla::geom::Vector2D>>(); boost::python::object get_iter = boost::python::iterator<const std::vector<carla::geom::Vector2D>>();
boost::python::object iter = get_iter(steering_curve); boost::python::object iter = get_iter(steering_curve);
return boost::python::list(iter); return boost::python::list(iter);
@ -117,34 +117,102 @@ static void SetSteeringCurve(carla::rpc::VehiclePhysicsControl &self, const boos
boost::python::object VehiclePhysicsControl_init(boost::python::tuple args, boost::python::dict kwargs) { boost::python::object VehiclePhysicsControl_init(boost::python::tuple args, boost::python::dict kwargs) {
// Args names // Args names
const uint32_t NUM_ARGUMENTS = 21; const char* const args_names[] = {
const char *args_names[NUM_ARGUMENTS] = {
"torque_curve", "torque_curve",
"max_torque", "max_torque",
"max_rpm", "max_rpm",
"moi", "idle_rpm",
"brake_effect",
"rev_up_moi",
"rev_down_rate", "rev_down_rate",
"differential_type", "differential_type",
"front_rear_split", "front_rear_split",
"use_automatic_gears",
"use_gear_autobox", "gear_change_time",
"gear_switch_time",
"final_ratio", "final_ratio",
"forward_gears", "forward_gear_ratios",
"reverse_gears", "reverse_gear_ratios",
"change_up_rpm", "change_up_rpm",
"change_down_rpm", "change_down_rpm",
"transmission_efficiency", "transmission_efficiency",
"mass", "mass",
"drag_coefficient", "drag_coefficient",
"center_of_mass", "center_of_mass",
"chassis_width",
"chassis_height",
"downforce_coefficient",
"drag_area",
"inertia_tensor_scale",
"sleep_threshold",
"sleep_slope_limit",
"steering_curve", "steering_curve",
"wheels", "wheels",
"use_sweep_wheel_collision", "use_sweep_wheel_collision"
}; };
const auto NUM_ARGUMENTS = sizeof(args_names) / sizeof(const char*);
boost::python::object self = args[0];
args = boost::python::tuple(args.slice(1, boost::python::_));
auto res = self.attr("__init__")();
if (len(args) > 0) {
for (unsigned int i = 0; i < len(args); ++i) {
self.attr(args_names[i]) = args[i];
}
}
for (unsigned int i = 0; i < NUM_ARGUMENTS; ++i) {
if (kwargs.contains(args_names[i])) {
self.attr(args_names[i]) = kwargs[args_names[i]];
}
}
return res;
}
boost::python::object WheelPhysicsControl_init(boost::python::tuple args, boost::python::dict kwargs) {
// Args names
const char* const args_names[] = {
"axle_type",
"offset",
"wheel_radius",
"wheel_width",
"wheel_mass",
"cornering_stiffness",
"friction_force_multiplier",
"side_slip_modifier",
"slip_threshold",
"skid_threshold",
"max_steer_angle",
"affected_by_steering",
"affected_by_brake",
"affected_by_handbrake",
"affected_by_engine",
"abs_enabled",
"traction_control_enabled",
"max_wheelspin_rotation",
"external_torque_combine_method",
"lateral_slip_graph",
"suspension_axis",
"suspension_force_offset",
"suspension_max_raise",
"suspension_max_drop",
"suspension_damping_ratio",
"wheel_load_ratio",
"spring_rate",
"spring_preload",
"suspension_smoothing",
"rollbar_scaling",
"sweep_shape",
"sweep_type",
"max_brake_torque",
"max_hand_brake_torque",
"wheel_index",
"location",
"old_location",
"velocity",
};
const auto NUM_ARGUMENTS = sizeof(args_names) / sizeof(const char*);
boost::python::object self = args[0]; boost::python::object self = args[0];
args = boost::python::tuple(args.slice(1, boost::python::_)); args = boost::python::tuple(args.slice(1, boost::python::_));
@ -336,26 +404,48 @@ void export_control() {
.def(self_ns::str(self_ns::self)) .def(self_ns::str(self_ns::self))
; ;
class_<cr::WheelPhysicsControl>("WheelPhysicsControl")
.def(init<float, float, float, float, bool, bool, float, float, cg::Vector3D>( class_<cr::WheelPhysicsControl>("WheelPhysicsControl", no_init)
(arg("tire_friction")=3.0f, .def("__init__", raw_function(WheelPhysicsControl_init))
arg("max_steer_angle")=70.0f, .def(init<>())
arg("radius")=30.0f, .def_readwrite("axle_type", &cr::WheelPhysicsControl::axle_type)
arg("cornering_stiffness")=1000.0f, .def_readwrite("offset", &cr::WheelPhysicsControl::offset)
arg("abs")=false, .def_readwrite("wheel_radius", &cr::WheelPhysicsControl::wheel_radius)
arg("traction_control")=false, .def_readwrite("wheel_width", &cr::WheelPhysicsControl::wheel_width)
arg("max_brake_torque")=1500.0f, .def_readwrite("wheel_mass", &cr::WheelPhysicsControl::wheel_mass)
arg("max_handbrake_torque")=3000.0f,
arg("position")=cg::Vector3D{0.0f, 0.0f, 0.0f})))
.def_readwrite("tire_friction", &cr::WheelPhysicsControl::tire_friction)
.def_readwrite("max_steer_angle", &cr::WheelPhysicsControl::max_steer_angle)
.def_readwrite("radius", &cr::WheelPhysicsControl::radius)
.def_readwrite("cornering_stiffness", &cr::WheelPhysicsControl::cornering_stiffness) .def_readwrite("cornering_stiffness", &cr::WheelPhysicsControl::cornering_stiffness)
.def_readwrite("abs", &cr::WheelPhysicsControl::abs) .def_readwrite("friction_force_multiplier", &cr::WheelPhysicsControl::friction_force_multiplier)
.def_readwrite("traction_control", &cr::WheelPhysicsControl::traction_control) .def_readwrite("side_slip_modifier", &cr::WheelPhysicsControl::side_slip_modifier)
.def_readwrite("slip_threshold", &cr::WheelPhysicsControl::slip_threshold)
.def_readwrite("skid_threshold", &cr::WheelPhysicsControl::skid_threshold)
.def_readwrite("max_steer_angle", &cr::WheelPhysicsControl::max_steer_angle)
.def_readwrite("affected_by_steering", &cr::WheelPhysicsControl::affected_by_steering)
.def_readwrite("affected_by_brake", &cr::WheelPhysicsControl::affected_by_brake)
.def_readwrite("affected_by_handbrake", &cr::WheelPhysicsControl::affected_by_handbrake)
.def_readwrite("affected_by_engine", &cr::WheelPhysicsControl::affected_by_engine)
.def_readwrite("abs_enabled", &cr::WheelPhysicsControl::abs_enabled)
.def_readwrite("traction_control_enabled", &cr::WheelPhysicsControl::traction_control_enabled)
.def_readwrite("max_wheelspin_rotation", &cr::WheelPhysicsControl::max_wheelspin_rotation)
.def_readwrite("external_torque_combine_method", &cr::WheelPhysicsControl::external_torque_combine_method)
.def_readwrite("lateral_slip_graph", &cr::WheelPhysicsControl::lateral_slip_graph)
.def_readwrite("suspension_axis", &cr::WheelPhysicsControl::suspension_axis)
.def_readwrite("suspension_force_offset", &cr::WheelPhysicsControl::suspension_force_offset)
.def_readwrite("suspension_max_raise", &cr::WheelPhysicsControl::suspension_max_raise)
.def_readwrite("suspension_max_drop", &cr::WheelPhysicsControl::suspension_max_drop)
.def_readwrite("suspension_damping_ratio", &cr::WheelPhysicsControl::suspension_damping_ratio)
.def_readwrite("wheel_load_ratio", &cr::WheelPhysicsControl::wheel_load_ratio)
.def_readwrite("spring_rate", &cr::WheelPhysicsControl::spring_rate)
.def_readwrite("spring_preload", &cr::WheelPhysicsControl::spring_preload)
.def_readwrite("suspension_smoothing", &cr::WheelPhysicsControl::suspension_smoothing)
.def_readwrite("rollbar_scaling", &cr::WheelPhysicsControl::rollbar_scaling)
.def_readwrite("sweep_shape", &cr::WheelPhysicsControl::sweep_shape)
.def_readwrite("sweep_type", &cr::WheelPhysicsControl::sweep_type)
.def_readwrite("max_brake_torque", &cr::WheelPhysicsControl::max_brake_torque) .def_readwrite("max_brake_torque", &cr::WheelPhysicsControl::max_brake_torque)
.def_readwrite("max_handbrake_torque", &cr::WheelPhysicsControl::max_handbrake_torque) .def_readwrite("max_hand_brake_torque", &cr::WheelPhysicsControl::max_hand_brake_torque)
.def_readwrite("position", &cr::WheelPhysicsControl::position) .def_readwrite("wheel_index", &cr::WheelPhysicsControl::wheel_index)
.def_readwrite("location", &cr::WheelPhysicsControl::location)
.def_readwrite("old_location", &cr::WheelPhysicsControl::old_location)
.def_readwrite("velocity", &cr::WheelPhysicsControl::velocity)
.def("__eq__", &cr::WheelPhysicsControl::operator==) .def("__eq__", &cr::WheelPhysicsControl::operator==)
.def("__ne__", &cr::WheelPhysicsControl::operator!=) .def("__ne__", &cr::WheelPhysicsControl::operator!=)
.def(self_ns::str(self_ns::self)) .def(self_ns::str(self_ns::self))
@ -365,26 +455,35 @@ void export_control() {
.def("__init__", raw_function(VehiclePhysicsControl_init)) .def("__init__", raw_function(VehiclePhysicsControl_init))
.def(init<>()) .def(init<>())
.add_property("torque_curve", &GetTorqueCurve, &SetTorqueCurve) .add_property("torque_curve", &GetTorqueCurve, &SetTorqueCurve)
.def_readwrite("max_torque", &cr::VehiclePhysicsControl::max_torque) .add_property("max_torque", &cr::VehiclePhysicsControl::max_torque)
.def_readwrite("max_rpm", &cr::VehiclePhysicsControl::max_rpm) .add_property("max_rpm", &cr::VehiclePhysicsControl::max_rpm)
.def_readwrite("moi", &cr::VehiclePhysicsControl::moi) .add_property("idle_rpm", &cr::VehiclePhysicsControl::idle_rpm)
.def_readwrite("rev_down_rate", &cr::VehiclePhysicsControl::rev_down_rate) .add_property("brake_effect", &cr::VehiclePhysicsControl::brake_effect)
.def_readwrite("differential_type", &cr::VehiclePhysicsControl::differential_type) .add_property("rev_up_moi", &cr::VehiclePhysicsControl::rev_up_moi)
.def_readwrite("front_rear_split", &cr::VehiclePhysicsControl::front_rear_split) .add_property("rev_down_rate", &cr::VehiclePhysicsControl::rev_down_rate)
.def_readwrite("use_gear_autobox", &cr::VehiclePhysicsControl::use_gear_autobox) .add_property("differential_type", &cr::VehiclePhysicsControl::differential_type)
.def_readwrite("gear_switch_time", &cr::VehiclePhysicsControl::gear_switch_time) .add_property("front_rear_split", &cr::VehiclePhysicsControl::front_rear_split)
.def_readwrite("final_ratio", &cr::VehiclePhysicsControl::final_ratio) .add_property("use_automatic_gears", &cr::VehiclePhysicsControl::use_automatic_gears)
.add_property("forward_gears", &GetForwardGears, &SetForwardGears) .add_property("gear_change_time", &cr::VehiclePhysicsControl::gear_change_time)
.add_property("reverse_gears", &GetReverseGears, &SetReverseGears) .add_property("final_ratio", &cr::VehiclePhysicsControl::final_ratio)
.def_readwrite("change_up_rpm", &cr::VehiclePhysicsControl::change_up_rpm) .add_property("forward_gear_ratios", &GetForwardGearRatios, &SetForwardGearRatios)
.def_readwrite("change_down_rpm", &cr::VehiclePhysicsControl::change_down_rpm) .add_property("reverse_gear_ratios", &GetReverseGearRatios, &SetReverseGearRatios)
.def_readwrite("transmission_efficiency", &cr::VehiclePhysicsControl::mass) .add_property("change_up_rpm", &cr::VehiclePhysicsControl::change_up_rpm)
.def_readwrite("mass", &cr::VehiclePhysicsControl::mass) .add_property("change_down_rpm", &cr::VehiclePhysicsControl::change_down_rpm)
.def_readwrite("drag_coefficient", &cr::VehiclePhysicsControl::drag_coefficient) .add_property("transmission_efficiency", &cr::VehiclePhysicsControl::transmission_efficiency)
.def_readwrite("center_of_mass", &cr::VehiclePhysicsControl::center_of_mass) .add_property("mass", &cr::VehiclePhysicsControl::mass)
.add_property("drag_coefficient", &cr::VehiclePhysicsControl::drag_coefficient)
.add_property("center_of_mass", &cr::VehiclePhysicsControl::center_of_mass)
.add_property("chassis_width", &cr::VehiclePhysicsControl::chassis_width)
.add_property("chassis_height", &cr::VehiclePhysicsControl::chassis_height)
.add_property("downforce_coefficient", &cr::VehiclePhysicsControl::downforce_coefficient)
.add_property("drag_area", &cr::VehiclePhysicsControl::drag_area)
.add_property("inertia_tensor_scale", &cr::VehiclePhysicsControl::inertia_tensor_scale)
.add_property("sleep_threshold", &cr::VehiclePhysicsControl::sleep_threshold)
.add_property("sleep_slope_limit", &cr::VehiclePhysicsControl::sleep_slope_limit)
.add_property("steering_curve", &GetSteeringCurve, &SetSteeringCurve) .add_property("steering_curve", &GetSteeringCurve, &SetSteeringCurve)
.add_property("wheels", &GetWheels, &SetWheels) .add_property("wheels", &GetWheels, &SetWheels)
.def_readwrite("use_sweep_wheel_collision", &cr::VehiclePhysicsControl::use_sweep_wheel_collision) .add_property("use_sweep_wheel_collision", &cr::VehiclePhysicsControl::use_sweep_wheel_collision)
.def("__eq__", &cr::VehiclePhysicsControl::operator==) .def("__eq__", &cr::VehiclePhysicsControl::operator==)
.def("__ne__", &cr::VehiclePhysicsControl::operator!=) .def("__ne__", &cr::VehiclePhysicsControl::operator!=)
.def(self_ns::str(self_ns::self)) .def(self_ns::str(self_ns::self))

View File

@ -1,2 +1 @@
carla.so _out/
carla.pyd

View File

@ -839,8 +839,8 @@ def main():
argparser.add_argument( argparser.add_argument(
'--generation', '--generation',
metavar='G', metavar='G',
default='2', default='All',
help='restrict to certain actor generation (values: "1","2","All" - default: "2")') help='restrict to certain actor generation (values: "2","3","All" - default: "All")')
argparser.add_argument( argparser.add_argument(
'-l', '--loop', '-l', '--loop',
action='store_true', action='store_true',

View File

@ -327,6 +327,7 @@ def main():
ped_bp = random.choice(world.get_blueprint_library().filter("walker.pedestrian.*")) ped_bp = random.choice(world.get_blueprint_library().filter("walker.pedestrian.*"))
trans = carla.Transform() trans = carla.Transform()
trans.location = world.get_random_location_from_navigation() trans.location = world.get_random_location_from_navigation()
trans.location.z += 1 # Apply an offset in vertical axis to avoid collision spawning
ped = world.spawn_actor(ped_bp, trans) ped = world.spawn_actor(ped_bp, trans)
walker_controller_bp = world.get_blueprint_library().find('controller.ai.walker') walker_controller_bp = world.get_blueprint_library().find('controller.ai.walker')
controller = world.spawn_actor(walker_controller_bp, carla.Transform(), ped) controller = world.spawn_actor(walker_controller_bp, carla.Transform(), ped)

View File

@ -1,153 +0,0 @@
#!/usr/bin/env python
# Copyright (c) 2019 Computer Vision Center (CVC) at the Universitat Autonoma de
# Barcelona (UAB).
#
# This work is licensed under the terms of the MIT license.
# For a copy, see <https://opensource.org/licenses/MIT>.
"""
CARLA Dynamic Weather:
Connect to a CARLA Simulator instance and control the weather. Change Sun
position smoothly with time and generate storms occasionally.
"""
import glob
import os
import sys
try:
sys.path.append(glob.glob('../carla/dist/carla-*%d.%d-%s.egg' % (
sys.version_info.major,
sys.version_info.minor,
'win-amd64' if os.name == 'nt' else 'linux-x86_64'))[0])
except IndexError:
pass
import carla
import argparse
import math
def clamp(value, minimum=0.0, maximum=100.0):
return max(minimum, min(value, maximum))
class Sun(object):
def __init__(self, azimuth, altitude):
self.azimuth = azimuth
self.altitude = altitude
self._t = 0.0
def tick(self, delta_seconds):
self._t += 0.008 * delta_seconds
self._t %= 2.0 * math.pi
self.azimuth += 0.25 * delta_seconds
self.azimuth %= 360.0
self.altitude = (70 * math.sin(self._t)) - 20
def __str__(self):
return 'Sun(alt: %.2f, azm: %.2f)' % (self.altitude, self.azimuth)
class Storm(object):
def __init__(self, precipitation):
self._t = precipitation if precipitation > 0.0 else -50.0
self._increasing = True
self.clouds = 0.0
self.rain = 0.0
self.wetness = 0.0
self.puddles = 0.0
self.wind = 0.0
self.fog = 0.0
def tick(self, delta_seconds):
delta = (1.3 if self._increasing else -1.3) * delta_seconds
self._t = clamp(delta + self._t, -250.0, 100.0)
self.clouds = clamp(self._t + 40.0, 0.0, 90.0)
self.rain = clamp(self._t, 0.0, 80.0)
delay = -10.0 if self._increasing else 90.0
self.puddles = clamp(self._t + delay, 0.0, 85.0)
self.wetness = clamp(self._t * 5, 0.0, 100.0)
self.wind = 5.0 if self.clouds <= 20 else 90 if self.clouds >= 70 else 40
self.fog = clamp(self._t - 10, 0.0, 30.0)
if self._t == -250.0:
self._increasing = True
if self._t == 100.0:
self._increasing = False
def __str__(self):
return 'Storm(clouds=%d%%, rain=%d%%, wind=%d%%)' % (self.clouds, self.rain, self.wind)
class Weather(object):
def __init__(self, weather):
self.weather = weather
self._sun = Sun(weather.sun_azimuth_angle, weather.sun_altitude_angle)
self._storm = Storm(weather.precipitation)
def tick(self, delta_seconds):
self._sun.tick(delta_seconds)
self._storm.tick(delta_seconds)
self.weather.cloudiness = self._storm.clouds
self.weather.precipitation = self._storm.rain
self.weather.precipitation_deposits = self._storm.puddles
self.weather.wind_intensity = self._storm.wind
self.weather.fog_density = self._storm.fog
self.weather.wetness = self._storm.wetness
self.weather.sun_azimuth_angle = self._sun.azimuth
self.weather.sun_altitude_angle = self._sun.altitude
def __str__(self):
return '%s %s' % (self._sun, self._storm)
def main():
argparser = argparse.ArgumentParser(
description=__doc__)
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(
'-s', '--speed',
metavar='FACTOR',
default=1.0,
type=float,
help='rate at which the weather changes (default: 1.0)')
args = argparser.parse_args()
speed_factor = args.speed
update_freq = 0.1 / speed_factor
client = carla.Client(args.host, args.port)
client.set_timeout(2.0)
world = client.get_world()
weather = Weather(world.get_weather())
elapsed_time = 0.0
while True:
timestamp = world.wait_for_tick(seconds=30.0).timestamp
elapsed_time += timestamp.delta_seconds
if elapsed_time > update_freq:
weather.tick(speed_factor * elapsed_time)
world.set_weather(weather.weather)
sys.stdout.write('\r' + str(weather) + 12 * ' ')
sys.stdout.flush()
elapsed_time = 0.0
if __name__ == '__main__':
main()

View File

@ -92,7 +92,7 @@ def main():
'--generationv', '--generationv',
metavar='G', metavar='G',
default='All', default='All',
help='restrict to certain vehicle generation (values: "1","2","All" - default: "All")') help='restrict to certain vehicle generation (values: "2","3","All" - default: "All")')
argparser.add_argument( argparser.add_argument(
'--filterw', '--filterw',
metavar='PATTERN', metavar='PATTERN',
@ -101,8 +101,8 @@ def main():
argparser.add_argument( argparser.add_argument(
'--generationw', '--generationw',
metavar='G', metavar='G',
default='2', default='All',
help='restrict to certain pedestrian generation (values: "1","2","All" - default: "2")') help='restrict to certain pedestrian generation (values: "2","3","All" - default: "All")')
argparser.add_argument( argparser.add_argument(
'--tm-port', '--tm-port',
metavar='P', metavar='P',

View File

@ -1194,7 +1194,7 @@ class CameraManager(object):
# Example of converting the raw_data from a carla.DVSEventArray # Example of converting the raw_data from a carla.DVSEventArray
# sensor into a NumPy array and using it as an image # sensor into a NumPy array and using it as an image
dvs_events = np.frombuffer(image.raw_data, dtype=np.dtype([ dvs_events = np.frombuffer(image.raw_data, dtype=np.dtype([
('x', np.uint16), ('y', np.uint16), ('t', np.int64), ('pol', np.bool)])) ('x', np.uint16), ('y', np.uint16), ('t', np.int64), ('pol', np.bool_)]))
dvs_img = np.zeros((image.height, image.width, 3), dtype=np.uint8) dvs_img = np.zeros((image.height, image.width, 3), dtype=np.uint8)
# Blue is positive, red is negative # Blue is positive, red is negative
dvs_img[dvs_events[:]['y'], dvs_events[:]['x'], dvs_events[:]['pol'] * 2] = 255 dvs_img[dvs_events[:]['y'], dvs_events[:]['x'], dvs_events[:]['pol'] * 2] = 255
@ -1329,8 +1329,8 @@ def main():
argparser.add_argument( argparser.add_argument(
'--generation', '--generation',
metavar='G', metavar='G',
default='4', default='All',
help='restrict to certain actor generation (values: "1","2","3","4","All" - default: "4")') help='restrict to certain actor generation (values: "2","3","All" - default: "All")')
argparser.add_argument( argparser.add_argument(
'--rolename', '--rolename',
metavar='NAME', metavar='NAME',

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -1,865 +0,0 @@
#!/usr/bin/env python
# Copyright (c) 2019 Intel Labs
#
# This work is licensed under the terms of the MIT license.
# For a copy, see <https://opensource.org/licenses/MIT>.
# Allows controlling a vehicle with a keyboard. For a simpler and more
# documented example, please take a look at tutorial.py.
"""
Welcome to CARLA manual control with steering wheel Logitech G29.
To drive start by preshing the brake pedal.
Change your wheel_config.ini according to your steering wheel.
To find out the values of your steering wheel use jstest-gtk in Ubuntu.
"""
from __future__ import print_function
# ==============================================================================
# -- find carla module ---------------------------------------------------------
# ==============================================================================
import glob
import os
import sys
try:
sys.path.append(glob.glob('../carla/dist/carla-*%d.%d-%s.egg' % (
sys.version_info.major,
sys.version_info.minor,
'win-amd64' if os.name == 'nt' else 'linux-x86_64'))[0])
except IndexError:
pass
# ==============================================================================
# -- imports -------------------------------------------------------------------
# ==============================================================================
import carla
from carla import ColorConverter as cc
import argparse
import collections
import datetime
import logging
import math
import random
import re
import weakref
if sys.version_info >= (3, 0):
from configparser import ConfigParser
else:
from ConfigParser import RawConfigParser as ConfigParser
try:
import pygame
from pygame.locals import KMOD_CTRL
from pygame.locals import KMOD_SHIFT
from pygame.locals import K_0
from pygame.locals import K_9
from pygame.locals import K_BACKQUOTE
from pygame.locals import K_BACKSPACE
from pygame.locals import K_COMMA
from pygame.locals import K_DOWN
from pygame.locals import K_ESCAPE
from pygame.locals import K_F1
from pygame.locals import K_LEFT
from pygame.locals import K_PERIOD
from pygame.locals import K_RIGHT
from pygame.locals import K_SLASH
from pygame.locals import K_SPACE
from pygame.locals import K_TAB
from pygame.locals import K_UP
from pygame.locals import K_a
from pygame.locals import K_c
from pygame.locals import K_d
from pygame.locals import K_h
from pygame.locals import K_m
from pygame.locals import K_p
from pygame.locals import K_q
from pygame.locals import K_r
from pygame.locals import K_s
from pygame.locals import K_w
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')
# ==============================================================================
# -- Global functions ----------------------------------------------------------
# ==============================================================================
def find_weather_presets():
rgx = re.compile('.+?(?:(?<=[a-z])(?=[A-Z])|(?<=[A-Z])(?=[A-Z][a-z])|$)')
name = lambda x: ' '.join(m.group(0) for m in rgx.finditer(x))
presets = [x for x in dir(carla.WeatherParameters) if re.match('[A-Z].+', x)]
return [(getattr(carla.WeatherParameters, x), name(x)) for x in presets]
def get_actor_display_name(actor, truncate=250):
name = ' '.join(actor.type_id.replace('_', '.').title().split('.')[1:])
return (name[:truncate - 1] + u'\u2026') if len(name) > truncate else name
# ==============================================================================
# -- World ---------------------------------------------------------------------
# ==============================================================================
class World(object):
def __init__(self, carla_world, hud, actor_filter):
self.world = carla_world
self.hud = hud
self.player = None
self.collision_sensor = None
self.lane_invasion_sensor = None
self.gnss_sensor = None
self.camera_manager = None
self._weather_presets = find_weather_presets()
self._weather_index = 0
self._actor_filter = actor_filter
self.restart()
self.world.on_tick(hud.on_world_tick)
def restart(self):
# Keep same camera config if the camera manager exists.
cam_index = self.camera_manager.index if self.camera_manager is not None else 0
cam_pos_index = self.camera_manager.transform_index if self.camera_manager is not None else 0
# Get a random blueprint.
blueprint = random.choice(self.world.get_blueprint_library().filter(self._actor_filter))
blueprint.set_attribute('role_name', 'hero')
if blueprint.has_attribute('color'):
color = random.choice(blueprint.get_attribute('color').recommended_values)
blueprint.set_attribute('color', color)
# Spawn the player.
if self.player is not None:
spawn_point = self.player.get_transform()
spawn_point.location.z += 2.0
spawn_point.rotation.roll = 0.0
spawn_point.rotation.pitch = 0.0
self.destroy()
self.player = self.world.try_spawn_actor(blueprint, spawn_point)
while self.player is None:
spawn_points = self.world.get_map().get_spawn_points()
spawn_point = random.choice(spawn_points) if spawn_points else carla.Transform()
self.player = self.world.try_spawn_actor(blueprint, spawn_point)
# Set up the sensors.
self.collision_sensor = CollisionSensor(self.player, self.hud)
self.lane_invasion_sensor = LaneInvasionSensor(self.player, self.hud)
self.gnss_sensor = GnssSensor(self.player)
self.camera_manager = CameraManager(self.player, self.hud)
self.camera_manager.transform_index = cam_pos_index
self.camera_manager.set_sensor(cam_index, notify=False)
actor_type = get_actor_display_name(self.player)
self.hud.notification(actor_type)
def next_weather(self, reverse=False):
self._weather_index += -1 if reverse else 1
self._weather_index %= len(self._weather_presets)
preset = self._weather_presets[self._weather_index]
self.hud.notification('Weather: %s' % preset[1])
self.player.get_world().set_weather(preset[0])
def tick(self, clock):
self.hud.tick(self, clock)
def render(self, display):
self.camera_manager.render(display)
self.hud.render(display)
def destroy(self):
sensors = [
self.camera_manager.sensor,
self.collision_sensor.sensor,
self.lane_invasion_sensor.sensor,
self.gnss_sensor.sensor]
for sensor in sensors:
if sensor is not None:
sensor.stop()
sensor.destroy()
if self.player is not None:
self.player.destroy()
# ==============================================================================
# -- DualControl -----------------------------------------------------------
# ==============================================================================
class DualControl(object):
def __init__(self, world, start_in_autopilot):
self._autopilot_enabled = start_in_autopilot
if isinstance(world.player, carla.Vehicle):
self._control = carla.VehicleControl()
world.player.set_autopilot(self._autopilot_enabled)
elif isinstance(world.player, carla.Walker):
self._control = carla.WalkerControl()
self._autopilot_enabled = False
self._rotation = world.player.get_transform().rotation
else:
raise NotImplementedError("Actor type not supported")
self._steer_cache = 0.0
world.hud.notification("Press 'H' or '?' for help.", seconds=4.0)
# initialize steering wheel
pygame.joystick.init()
joystick_count = pygame.joystick.get_count()
if joystick_count > 1:
raise ValueError("Please Connect Just One Joystick")
self._joystick = pygame.joystick.Joystick(0)
self._joystick.init()
self._parser = ConfigParser()
self._parser.read('wheel_config.ini')
self._steer_idx = int(
self._parser.get('G29 Racing Wheel', 'steering_wheel'))
self._throttle_idx = int(
self._parser.get('G29 Racing Wheel', 'throttle'))
self._brake_idx = int(self._parser.get('G29 Racing Wheel', 'brake'))
self._reverse_idx = int(self._parser.get('G29 Racing Wheel', 'reverse'))
self._handbrake_idx = int(
self._parser.get('G29 Racing Wheel', 'handbrake'))
def parse_events(self, world, clock):
for event in pygame.event.get():
if event.type == pygame.QUIT:
return True
elif event.type == pygame.JOYBUTTONDOWN:
if event.button == 0:
world.restart()
elif event.button == 1:
world.hud.toggle_info()
elif event.button == 2:
world.camera_manager.toggle_camera()
elif event.button == 3:
world.next_weather()
elif event.button == self._reverse_idx:
self._control.gear = 1 if self._control.reverse else -1
elif event.button == 23:
world.camera_manager.next_sensor()
elif event.type == pygame.KEYUP:
if self._is_quit_shortcut(event.key):
return True
elif event.key == K_BACKSPACE:
world.restart()
elif event.key == K_F1:
world.hud.toggle_info()
elif event.key == K_h or (event.key == K_SLASH and pygame.key.get_mods() & KMOD_SHIFT):
world.hud.help.toggle()
elif event.key == K_TAB:
world.camera_manager.toggle_camera()
elif event.key == K_c and pygame.key.get_mods() & KMOD_SHIFT:
world.next_weather(reverse=True)
elif event.key == K_c:
world.next_weather()
elif event.key == K_BACKQUOTE:
world.camera_manager.next_sensor()
elif event.key > K_0 and event.key <= K_9:
world.camera_manager.set_sensor(event.key - 1 - K_0)
elif event.key == K_r:
world.camera_manager.toggle_recording()
if isinstance(self._control, carla.VehicleControl):
if event.key == K_q:
self._control.gear = 1 if self._control.reverse else -1
elif event.key == K_m:
self._control.manual_gear_shift = not self._control.manual_gear_shift
self._control.gear = world.player.get_control().gear
world.hud.notification('%s Transmission' %
('Manual' if self._control.manual_gear_shift else 'Automatic'))
elif self._control.manual_gear_shift and event.key == K_COMMA:
self._control.gear = max(-1, self._control.gear - 1)
elif self._control.manual_gear_shift and event.key == K_PERIOD:
self._control.gear = self._control.gear + 1
elif event.key == K_p:
self._autopilot_enabled = not self._autopilot_enabled
world.player.set_autopilot(self._autopilot_enabled)
world.hud.notification('Autopilot %s' % ('On' if self._autopilot_enabled else 'Off'))
if not self._autopilot_enabled:
if isinstance(self._control, carla.VehicleControl):
self._parse_vehicle_keys(pygame.key.get_pressed(), clock.get_time())
self._parse_vehicle_wheel()
self._control.reverse = self._control.gear < 0
elif isinstance(self._control, carla.WalkerControl):
self._parse_walker_keys(pygame.key.get_pressed(), clock.get_time())
world.player.apply_control(self._control)
def _parse_vehicle_keys(self, keys, milliseconds):
self._control.throttle = 1.0 if keys[K_UP] or keys[K_w] else 0.0
steer_increment = 5e-4 * milliseconds
if keys[K_LEFT] or keys[K_a]:
self._steer_cache -= steer_increment
elif keys[K_RIGHT] or keys[K_d]:
self._steer_cache += steer_increment
else:
self._steer_cache = 0.0
self._steer_cache = min(0.7, max(-0.7, self._steer_cache))
self._control.steer = round(self._steer_cache, 1)
self._control.brake = 1.0 if keys[K_DOWN] or keys[K_s] else 0.0
self._control.hand_brake = keys[K_SPACE]
def _parse_vehicle_wheel(self):
numAxes = self._joystick.get_numaxes()
jsInputs = [float(self._joystick.get_axis(i)) for i in range(numAxes)]
# print (jsInputs)
jsButtons = [float(self._joystick.get_button(i)) for i in
range(self._joystick.get_numbuttons())]
# Custom function to map range of inputs [1, -1] to outputs [0, 1] i.e 1 from inputs means nothing is pressed
# For the steering, it seems fine as it is
K1 = 1.0 # 0.55
steerCmd = K1 * math.tan(1.1 * jsInputs[self._steer_idx])
K2 = 1.6 # 1.6
throttleCmd = K2 + (2.05 * math.log10(
-0.7 * jsInputs[self._throttle_idx] + 1.4) - 1.2) / 0.92
if throttleCmd <= 0:
throttleCmd = 0
elif throttleCmd > 1:
throttleCmd = 1
brakeCmd = 1.6 + (2.05 * math.log10(
-0.7 * jsInputs[self._brake_idx] + 1.4) - 1.2) / 0.92
if brakeCmd <= 0:
brakeCmd = 0
elif brakeCmd > 1:
brakeCmd = 1
self._control.steer = steerCmd
self._control.brake = brakeCmd
self._control.throttle = throttleCmd
#toggle = jsButtons[self._reverse_idx]
self._control.hand_brake = bool(jsButtons[self._handbrake_idx])
def _parse_walker_keys(self, keys, milliseconds):
self._control.speed = 0.0
if keys[K_DOWN] or keys[K_s]:
self._control.speed = 0.0
if keys[K_LEFT] or keys[K_a]:
self._control.speed = .01
self._rotation.yaw -= 0.08 * milliseconds
if keys[K_RIGHT] or keys[K_d]:
self._control.speed = .01
self._rotation.yaw += 0.08 * milliseconds
if keys[K_UP] or keys[K_w]:
self._control.speed = 5.556 if pygame.key.get_mods() & KMOD_SHIFT else 2.778
self._control.jump = keys[K_SPACE]
self._rotation.yaw = round(self._rotation.yaw, 1)
self._control.direction = self._rotation.get_forward_vector()
@staticmethod
def _is_quit_shortcut(key):
return (key == K_ESCAPE) or (key == K_q and pygame.key.get_mods() & KMOD_CTRL)
# ==============================================================================
# -- HUD -----------------------------------------------------------------------
# ==============================================================================
class HUD(object):
def __init__(self, width, height):
self.dim = (width, height)
font = pygame.font.Font(pygame.font.get_default_font(), 20)
font_name = 'courier' if os.name == 'nt' else 'mono'
fonts = [x for x in pygame.font.get_fonts() if font_name in x]
default_font = 'ubuntumono'
mono = default_font if default_font in fonts else fonts[0]
mono = pygame.font.match_font(mono)
self._font_mono = pygame.font.Font(mono, 12 if os.name == 'nt' else 14)
self._notifications = FadingText(font, (width, 40), (0, height - 40))
self.help = HelpText(pygame.font.Font(mono, 24), width, height)
self.server_fps = 0
self.frame = 0
self.simulation_time = 0
self._show_info = True
self._info_text = []
self._server_clock = pygame.time.Clock()
def on_world_tick(self, timestamp):
self._server_clock.tick()
self.server_fps = self._server_clock.get_fps()
self.frame = timestamp.frame
self.simulation_time = timestamp.elapsed_seconds
def tick(self, world, clock):
self._notifications.tick(world, clock)
if not self._show_info:
return
t = world.player.get_transform()
v = world.player.get_velocity()
c = world.player.get_control()
heading = 'N' if abs(t.rotation.yaw) < 89.5 else ''
heading += 'S' if abs(t.rotation.yaw) > 90.5 else ''
heading += 'E' if 179.5 > t.rotation.yaw > 0.5 else ''
heading += 'W' if -0.5 > t.rotation.yaw > -179.5 else ''
colhist = world.collision_sensor.get_collision_history()
collision = [colhist[x + self.frame - 200] for x in range(0, 200)]
max_col = max(1.0, max(collision))
collision = [x / max_col for x in collision]
vehicles = world.world.get_actors().filter('vehicle.*')
self._info_text = [
'Server: % 16.0f FPS' % self.server_fps,
'Client: % 16.0f FPS' % clock.get_fps(),
'',
'Vehicle: % 20s' % get_actor_display_name(world.player, truncate=20),
'Map: % 20s' % world.world.get_map().name.split('/')[-1],
'Simulation time: % 12s' % datetime.timedelta(seconds=int(self.simulation_time)),
'',
'Speed: % 15.0f km/h' % (3.6 * math.sqrt(v.x**2 + v.y**2 + v.z**2)),
u'Heading:% 16.0f\N{DEGREE SIGN} % 2s' % (t.rotation.yaw, heading),
'Location:% 20s' % ('(% 5.1f, % 5.1f)' % (t.location.x, t.location.y)),
'GNSS:% 24s' % ('(% 2.6f, % 3.6f)' % (world.gnss_sensor.lat, world.gnss_sensor.lon)),
'Height: % 18.0f m' % t.location.z,
'']
if isinstance(c, carla.VehicleControl):
self._info_text += [
('Throttle:', c.throttle, 0.0, 1.0),
('Steer:', c.steer, -1.0, 1.0),
('Brake:', c.brake, 0.0, 1.0),
('Reverse:', c.reverse),
('Hand brake:', c.hand_brake),
('Manual:', c.manual_gear_shift),
'Gear: %s' % {-1: 'R', 0: 'N'}.get(c.gear, c.gear)]
elif isinstance(c, carla.WalkerControl):
self._info_text += [
('Speed:', c.speed, 0.0, 5.556),
('Jump:', c.jump)]
self._info_text += [
'',
'Collision:',
collision,
'',
'Number of vehicles: % 8d' % len(vehicles)]
if len(vehicles) > 1:
self._info_text += ['Nearby vehicles:']
distance = lambda l: math.sqrt((l.x - t.location.x)**2 + (l.y - t.location.y)**2 + (l.z - t.location.z)**2)
vehicles = [(distance(x.get_location()), x) for x in vehicles if x.id != world.player.id]
for d, vehicle in sorted(vehicles):
if d > 200.0:
break
vehicle_type = get_actor_display_name(vehicle, truncate=22)
self._info_text.append('% 4dm %s' % (d, vehicle_type))
def toggle_info(self):
self._show_info = not self._show_info
def notification(self, text, seconds=2.0):
self._notifications.set_text(text, seconds=seconds)
def error(self, text):
self._notifications.set_text('Error: %s' % text, (255, 0, 0))
def render(self, display):
if self._show_info:
info_surface = pygame.Surface((220, self.dim[1]))
info_surface.set_alpha(100)
display.blit(info_surface, (0, 0))
v_offset = 4
bar_h_offset = 100
bar_width = 106
for item in self._info_text:
if v_offset + 18 > self.dim[1]:
break
if isinstance(item, list):
if len(item) > 1:
points = [(x + 8, v_offset + 8 + (1.0 - y) * 30) for x, y in enumerate(item)]
pygame.draw.lines(display, (255, 136, 0), False, points, 2)
item = None
v_offset += 18
elif isinstance(item, tuple):
if isinstance(item[1], bool):
rect = pygame.Rect((bar_h_offset, v_offset + 8), (6, 6))
pygame.draw.rect(display, (255, 255, 255), rect, 0 if item[1] else 1)
else:
rect_border = pygame.Rect((bar_h_offset, v_offset + 8), (bar_width, 6))
pygame.draw.rect(display, (255, 255, 255), rect_border, 1)
f = (item[1] - item[2]) / (item[3] - item[2])
if item[2] < 0.0:
rect = pygame.Rect((bar_h_offset + f * (bar_width - 6), v_offset + 8), (6, 6))
else:
rect = pygame.Rect((bar_h_offset, v_offset + 8), (f * bar_width, 6))
pygame.draw.rect(display, (255, 255, 255), rect)
item = item[0]
if item: # At this point has to be a str.
surface = self._font_mono.render(item, True, (255, 255, 255))
display.blit(surface, (8, v_offset))
v_offset += 18
self._notifications.render(display)
self.help.render(display)
# ==============================================================================
# -- FadingText ----------------------------------------------------------------
# ==============================================================================
class FadingText(object):
def __init__(self, font, dim, pos):
self.font = font
self.dim = dim
self.pos = pos
self.seconds_left = 0
self.surface = pygame.Surface(self.dim)
def set_text(self, text, color=(255, 255, 255), seconds=2.0):
text_texture = self.font.render(text, True, color)
self.surface = pygame.Surface(self.dim)
self.seconds_left = seconds
self.surface.fill((0, 0, 0, 0))
self.surface.blit(text_texture, (10, 11))
def tick(self, _, clock):
delta_seconds = 1e-3 * clock.get_time()
self.seconds_left = max(0.0, self.seconds_left - delta_seconds)
self.surface.set_alpha(500.0 * self.seconds_left)
def render(self, display):
display.blit(self.surface, self.pos)
# ==============================================================================
# -- HelpText ------------------------------------------------------------------
# ==============================================================================
class HelpText(object):
def __init__(self, font, width, height):
lines = __doc__.split('\n')
self.font = font
self.dim = (680, len(lines) * 22 + 12)
self.pos = (0.5 * width - 0.5 * self.dim[0], 0.5 * height - 0.5 * self.dim[1])
self.seconds_left = 0
self.surface = pygame.Surface(self.dim)
self.surface.fill((0, 0, 0, 0))
for n, line in enumerate(lines):
text_texture = self.font.render(line, True, (255, 255, 255))
self.surface.blit(text_texture, (22, n * 22))
self._render = False
self.surface.set_alpha(220)
def toggle(self):
self._render = not self._render
def render(self, display):
if self._render:
display.blit(self.surface, self.pos)
# ==============================================================================
# -- CollisionSensor -----------------------------------------------------------
# ==============================================================================
class CollisionSensor(object):
def __init__(self, parent_actor, hud):
self.sensor = None
self.history = []
self._parent = parent_actor
self.hud = hud
world = self._parent.get_world()
bp = world.get_blueprint_library().find('sensor.other.collision')
self.sensor = world.spawn_actor(bp, carla.Transform(), attach_to=self._parent)
# We need to pass the lambda a weak reference to self to avoid circular
# reference.
weak_self = weakref.ref(self)
self.sensor.listen(lambda event: CollisionSensor._on_collision(weak_self, event))
def get_collision_history(self):
history = collections.defaultdict(int)
for frame, intensity in self.history:
history[frame] += intensity
return history
@staticmethod
def _on_collision(weak_self, event):
self = weak_self()
if not self:
return
actor_type = get_actor_display_name(event.other_actor)
self.hud.notification('Collision with %r' % actor_type)
impulse = event.normal_impulse
intensity = math.sqrt(impulse.x**2 + impulse.y**2 + impulse.z**2)
self.history.append((event.frame, intensity))
if len(self.history) > 4000:
self.history.pop(0)
# ==============================================================================
# -- LaneInvasionSensor --------------------------------------------------------
# ==============================================================================
class LaneInvasionSensor(object):
def __init__(self, parent_actor, hud):
self.sensor = None
self._parent = parent_actor
self.hud = hud
world = self._parent.get_world()
bp = world.get_blueprint_library().find('sensor.other.lane_invasion')
self.sensor = world.spawn_actor(bp, carla.Transform(), attach_to=self._parent)
# We need to pass the lambda a weak reference to self to avoid circular
# reference.
weak_self = weakref.ref(self)
self.sensor.listen(lambda event: LaneInvasionSensor._on_invasion(weak_self, event))
@staticmethod
def _on_invasion(weak_self, event):
self = weak_self()
if not self:
return
lane_types = set(x.type for x in event.crossed_lane_markings)
text = ['%r' % str(x).split()[-1] for x in lane_types]
self.hud.notification('Crossed line %s' % ' and '.join(text))
# ==============================================================================
# -- GnssSensor --------------------------------------------------------
# ==============================================================================
class GnssSensor(object):
def __init__(self, parent_actor):
self.sensor = None
self._parent = parent_actor
self.lat = 0.0
self.lon = 0.0
world = self._parent.get_world()
bp = world.get_blueprint_library().find('sensor.other.gnss')
self.sensor = world.spawn_actor(bp, carla.Transform(carla.Location(x=1.0, z=2.8)), attach_to=self._parent)
# We need to pass the lambda a weak reference to self to avoid circular
# reference.
weak_self = weakref.ref(self)
self.sensor.listen(lambda event: GnssSensor._on_gnss_event(weak_self, event))
@staticmethod
def _on_gnss_event(weak_self, event):
self = weak_self()
if not self:
return
self.lat = event.latitude
self.lon = event.longitude
# ==============================================================================
# -- CameraManager -------------------------------------------------------------
# ==============================================================================
class CameraManager(object):
def __init__(self, parent_actor, hud):
self.sensor = None
self.surface = None
self._parent = parent_actor
self.hud = hud
self.recording = False
self._camera_transforms = [
carla.Transform(carla.Location(x=-5.5, z=2.8), carla.Rotation(pitch=-15)),
carla.Transform(carla.Location(x=1.6, z=1.7))]
self.transform_index = 1
self.sensors = [
['sensor.camera.rgb', cc.Raw, 'Camera RGB'],
['sensor.camera.depth', cc.Raw, 'Camera Depth (Raw)'],
['sensor.camera.depth', cc.Depth, 'Camera Depth (Gray Scale)'],
['sensor.camera.depth', cc.LogarithmicDepth, 'Camera Depth (Logarithmic Gray Scale)'],
['sensor.camera.semantic_segmentation', cc.Raw, 'Camera Semantic Segmentation (Raw)'],
['sensor.camera.semantic_segmentation', cc.CityScapesPalette,
'Camera Semantic Segmentation (CityScapes Palette)'],
['sensor.lidar.ray_cast', None, 'Lidar (Ray-Cast)']]
world = self._parent.get_world()
bp_library = world.get_blueprint_library()
for item in self.sensors:
bp = bp_library.find(item[0])
if item[0].startswith('sensor.camera'):
bp.set_attribute('image_size_x', str(hud.dim[0]))
bp.set_attribute('image_size_y', str(hud.dim[1]))
elif item[0].startswith('sensor.lidar'):
bp.set_attribute('range', '50')
item.append(bp)
self.index = None
def toggle_camera(self):
self.transform_index = (self.transform_index + 1) % len(self._camera_transforms)
self.sensor.set_transform(self._camera_transforms[self.transform_index])
def set_sensor(self, index, notify=True):
index = index % len(self.sensors)
needs_respawn = True if self.index is None \
else self.sensors[index][0] != self.sensors[self.index][0]
if needs_respawn:
if self.sensor is not None:
self.sensor.destroy()
self.surface = None
self.sensor = self._parent.get_world().spawn_actor(
self.sensors[index][-1],
self._camera_transforms[self.transform_index],
attach_to=self._parent)
# We need to pass the lambda a weak reference to self to avoid
# circular reference.
weak_self = weakref.ref(self)
self.sensor.listen(lambda image: CameraManager._parse_image(weak_self, image))
if notify:
self.hud.notification(self.sensors[index][2])
self.index = index
def next_sensor(self):
self.set_sensor(self.index + 1)
def toggle_recording(self):
self.recording = not self.recording
self.hud.notification('Recording %s' % ('On' if self.recording else 'Off'))
def render(self, display):
if self.surface is not None:
display.blit(self.surface, (0, 0))
@staticmethod
def _parse_image(weak_self, image):
self = weak_self()
if not self:
return
if self.sensors[self.index][0].startswith('sensor.lidar'):
points = np.frombuffer(image.raw_data, dtype=np.dtype('f4'))
points = np.reshape(points, (int(points.shape[0] / 4), 4))
lidar_data = np.array(points[:, :2])
lidar_data *= min(self.hud.dim) / 100.0
lidar_data += (0.5 * self.hud.dim[0], 0.5 * self.hud.dim[1])
lidar_data = np.fabs(lidar_data) # pylint: disable=E1111
lidar_data = lidar_data.astype(np.int32)
lidar_data = np.reshape(lidar_data, (-1, 2))
lidar_img_size = (self.hud.dim[0], self.hud.dim[1], 3)
lidar_img = np.zeros(lidar_img_size)
lidar_img[tuple(lidar_data.T)] = (255, 255, 255)
self.surface = pygame.surfarray.make_surface(lidar_img)
else:
image.convert(self.sensors[self.index][1])
array = np.frombuffer(image.raw_data, dtype=np.dtype("uint8"))
array = np.reshape(array, (image.height, image.width, 4))
array = array[:, :, :3]
array = array[:, :, ::-1]
self.surface = pygame.surfarray.make_surface(array.swapaxes(0, 1))
if self.recording:
image.save_to_disk('_out/%08d' % image.frame)
# ==============================================================================
# -- game_loop() ---------------------------------------------------------------
# ==============================================================================
def game_loop(args):
pygame.init()
pygame.font.init()
world = None
try:
client = carla.Client(args.host, args.port)
client.set_timeout(2.0)
display = pygame.display.set_mode(
(args.width, args.height),
pygame.HWSURFACE | pygame.DOUBLEBUF)
hud = HUD(args.width, args.height)
world = World(client.get_world(), hud, args.filter)
controller = DualControl(world, args.autopilot)
clock = pygame.time.Clock()
while True:
clock.tick_busy_loop(60)
if controller.parse_events(world, clock):
return
world.tick(clock)
world.render(display)
pygame.display.flip()
finally:
if world is not None:
world.destroy()
pygame.quit()
# ==============================================================================
# -- main() --------------------------------------------------------------------
# ==============================================================================
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='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(
'--res',
metavar='WIDTHxHEIGHT',
default='1280x720',
help='window resolution (default: 1280x720)')
argparser.add_argument(
'--filter',
metavar='PATTERN',
default='vehicle.*',
help='actor filter (default: "vehicle.*")')
args = argparser.parse_args()
args.width, args.height = [int(x) for x in args.res.split('x')]
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__)
try:
game_loop(args)
except KeyboardInterrupt:
print('\nCancelled by user. Bye!')
if __name__ == '__main__':
main()

File diff suppressed because it is too large Load Diff

View File

@ -1,6 +1,6 @@
future future
numpy; python_version < '3.0' numpy; python_version < '3.0'
numpy==1.18.4; python_version >= '3.0' numpy==1.24; python_version >= '3.0'
pygame pygame
matplotlib matplotlib
open3d open3d

View File

@ -82,6 +82,9 @@ def main(args):
settings.fixed_delta_seconds = 0.05 settings.fixed_delta_seconds = 0.05
world.apply_settings(settings) world.apply_settings(settings)
traffic_manager = client.get_trafficmanager()
traffic_manager.set_synchronous_mode(True)
with open(args.file) as f: with open(args.file) as f:
config = json.load(f) config = json.load(f)

View File

@ -1,5 +1,5 @@
{ {
"type": "vehicle.lincoln.mkz_2020", "type": "vehicle.lincoln.mkz",
"id": "hero", "id": "hero",
"sensors": [ "sensors": [
{ {
@ -20,7 +20,7 @@
"range": 85, "range": 85,
"channels": 64, "channels": 64,
"points_per_second": 600000, "points_per_second": 600000,
"rotation_frequency": 10, "rotation_frequency": 20,
"upper_fov": 10, "upper_fov": 10,
"lower_fov": -30, "lower_fov": -30,
"atmosphere_attenuation_rate": 0.004, "atmosphere_attenuation_rate": 0.004,

View File

@ -1,921 +0,0 @@
#!/usr/bin/env python
# Copyright (c) 2024 Computer Vision Center (CVC) at the Universitat Autonoma de
# Barcelona (UAB).
# Copyright (c) 2019-2020 Intel Corporation
#
# This work is licensed under the terms of the MIT license.
# For a copy, see <https://opensource.org/licenses/MIT>.
# Allows controlling a vehicle with a keyboard. For a simpler and more
# documented example, please take a look at tutorial.py.
"""
Welcome to CARLA manual control.
Use ARROWS or WASD keys for control.
W : throttle
S : brake
AD : steer
Q : toggle reverse
Space : hand-brake
P : toggle autopilot
TAB : change view
Backspace : change vehicle
R : toggle recording images to disk
F2 : toggle RSS visualization mode
F3 : increase log level
F4 : decrease log level
F5 : increase map log level
F6 : decrease map log level
B : toggle RSS Road Boundaries Mode
G : RSS check drop current route
T : toggle RSS
N : pause simulation
F1 : toggle HUD
H/? : toggle help
ESC : quit
"""
from __future__ import print_function
# ==============================================================================
# -- find carla module ---------------------------------------------------------
# ==============================================================================
import glob
import os
import sys
import signal
try:
sys.path.append(glob.glob(os.path.dirname(os.path.dirname(os.path.dirname(os.path.abspath(__file__)))) + '/carla/dist/carla-*%d.%d-%s.egg' % (
sys.version_info.major,
sys.version_info.minor,
'win-amd64' if os.name == 'nt' else 'linux-x86_64'))[0])
except IndexError:
pass
# ==============================================================================
# -- imports -------------------------------------------------------------------
# ==============================================================================
import carla
from carla import ColorConverter as cc
import argparse
import logging
import math
import random
import weakref
from rss_sensor import RssSensor # pylint: disable=relative-import
from rss_visualization import RssUnstructuredSceneVisualizer, RssBoundingBoxVisualizer, RssStateVisualizer # pylint: disable=relative-import
try:
import pygame
from pygame.locals import KMOD_CTRL
from pygame.locals import KMOD_SHIFT
from pygame.locals import K_BACKSPACE
from pygame.locals import K_TAB
from pygame.locals import K_DOWN
from pygame.locals import K_ESCAPE
from pygame.locals import K_F1
from pygame.locals import K_F2
from pygame.locals import K_F3
from pygame.locals import K_F4
from pygame.locals import K_F5
from pygame.locals import K_F6
from pygame.locals import K_LEFT
from pygame.locals import K_RIGHT
from pygame.locals import K_SLASH
from pygame.locals import K_SPACE
from pygame.locals import K_UP
from pygame.locals import K_a
from pygame.locals import K_b
from pygame.locals import K_d
from pygame.locals import K_g
from pygame.locals import K_h
from pygame.locals import K_n
from pygame.locals import K_p
from pygame.locals import K_q
from pygame.locals import K_r
from pygame.locals import K_s
from pygame.locals import K_w
from pygame.locals import K_l
from pygame.locals import K_i
from pygame.locals import K_z
from pygame.locals import K_x
from pygame.locals import MOUSEBUTTONDOWN
from pygame.locals import MOUSEBUTTONUP
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')
# ==============================================================================
# -- World ---------------------------------------------------------------------
# ==============================================================================
class World(object):
def __init__(self, carla_world, args):
self.world = carla_world
self.sync = args.sync
self.actor_role_name = args.rolename
self.dim = (args.width, args.height)
try:
self.map = self.world.get_map()
except RuntimeError as error:
print('RuntimeError: {}'.format(error))
print(' The server could not send the OpenDRIVE (.xodr) file:')
print(' Make sure it exists, has the same name of your town, and is correct.')
sys.exit(1)
self.external_actor = args.externalActor
self.hud = HUD(args.width, args.height, carla_world)
self.recording_frame_num = 0
self.recording = False
self.recording_dir_num = 0
self.player = None
self.actors = []
self.rss_sensor = None
self.rss_unstructured_scene_visualizer = None
self.rss_bounding_box_visualizer = None
self._actor_filter = args.filter
if not self._actor_filter.startswith("vehicle."):
print('Error: RSS only supports vehicles as ego.')
sys.exit(1)
self.restart()
self.world_tick_id = self.world.on_tick(self.hud.on_world_tick)
def toggle_pause(self):
settings = self.world.get_settings()
self.pause_simulation(not settings.synchronous_mode)
def pause_simulation(self, pause):
settings = self.world.get_settings()
if pause and not settings.synchronous_mode:
settings.synchronous_mode = True
settings.fixed_delta_seconds = 0.05
self.world.apply_settings(settings)
elif not pause and settings.synchronous_mode:
settings.synchronous_mode = False
settings.fixed_delta_seconds = None
self.world.apply_settings(settings)
def restart(self):
if self.external_actor:
# Check whether there is already an actor with defined role name
for actor in self.world.get_actors():
if actor.attributes.get('role_name') == self.actor_role_name:
self.player = actor
break
else:
# Get a random blueprint.
blueprint = random.choice(self.world.get_blueprint_library().filter(self._actor_filter))
blueprint.set_attribute('role_name', self.actor_role_name)
if blueprint.has_attribute('color'):
color = random.choice(blueprint.get_attribute('color').recommended_values)
blueprint.set_attribute('color', color)
if blueprint.has_attribute('driver_id'):
driver_id = random.choice(blueprint.get_attribute('driver_id').recommended_values)
blueprint.set_attribute('driver_id', driver_id)
if blueprint.has_attribute('is_invincible'):
blueprint.set_attribute('is_invincible', 'true')
# Spawn the player.
if self.player is not None:
spawn_point = self.player.get_transform()
spawn_point.location.z += 2.0
spawn_point.rotation.roll = 0.0
spawn_point.rotation.pitch = 0.0
self.destroy()
self.player = self.world.try_spawn_actor(blueprint, spawn_point)
while self.player is None:
if not self.map.get_spawn_points():
print('There are no spawn points available in your map/town.')
print('Please add some Vehicle Spawn Point to your UE4 scene.')
sys.exit(1)
spawn_points = self.map.get_spawn_points()
spawn_point = random.choice(spawn_points) if spawn_points else carla.Transform()
self.player = self.world.try_spawn_actor(blueprint, spawn_point)
if self.external_actor:
ego_sensors = []
for actor in self.world.get_actors():
if actor.parent == self.player:
ego_sensors.append(actor)
for ego_sensor in ego_sensors:
if ego_sensor is not None:
ego_sensor.destroy()
# Set up the sensors.
self.camera = Camera(self.player, self.dim)
self.rss_unstructured_scene_visualizer = RssUnstructuredSceneVisualizer(self.player, self.world, self.dim)
self.rss_bounding_box_visualizer = RssBoundingBoxVisualizer(self.dim, self.world, self.camera.sensor)
self.rss_sensor = RssSensor(self.player, self.world,
self.rss_unstructured_scene_visualizer, self.rss_bounding_box_visualizer, self.hud.rss_state_visualizer)
if self.sync:
self.world.tick()
else:
self.world.wait_for_tick()
def tick(self, clock):
self.hud.tick(self.player, clock)
def toggle_recording(self):
if not self.recording:
dir_name = "_out%04d" % self.recording_dir_num
while os.path.exists(dir_name):
self.recording_dir_num += 1
dir_name = "_out%04d" % self.recording_dir_num
self.recording_frame_num = 0
os.mkdir(dir_name)
else:
self.hud.notification('Recording finished (folder: _out%04d)' % self.recording_dir_num)
self.recording = not self.recording
def render(self, display):
self.camera.render(display)
self.rss_bounding_box_visualizer.render(display, self.camera.current_frame)
self.rss_unstructured_scene_visualizer.render(display)
self.hud.render(display)
if self.recording:
pygame.image.save(display, "_out%04d/%08d.bmp" % (self.recording_dir_num, self.recording_frame_num))
self.recording_frame_num += 1
def destroy(self):
# stop from ticking
if self.world_tick_id:
self.world.remove_on_tick(self.world_tick_id)
if self.camera:
self.camera.destroy()
if self.rss_sensor:
self.rss_sensor.destroy()
if self.rss_unstructured_scene_visualizer:
self.rss_unstructured_scene_visualizer.destroy()
if self.player:
self.player.destroy()
# ==============================================================================
# -- Camera --------------------------------------------------------------------
# ==============================================================================
class Camera(object):
def __init__(self, parent_actor, display_dimensions):
self.surface = None
self._parent = parent_actor
self.current_frame = None
bp_library = self._parent.get_world().get_blueprint_library()
bp = bp_library.find('sensor.camera.rgb')
bp.set_attribute('image_size_x', str(display_dimensions[0]))
bp.set_attribute('image_size_y', str(display_dimensions[1]))
self.sensor = self._parent.get_world().spawn_actor(bp, carla.Transform(carla.Location(
x=-5.5, z=2.5), carla.Rotation(pitch=8.0)), attach_to=self._parent, attachment_type=carla.AttachmentType.SpringArmGhost)
# We need to pass the lambda a weak reference to self to avoid
# circular reference.
weak_self = weakref.ref(self)
self.sensor.listen(lambda image: Camera._parse_image(weak_self, image))
def destroy(self):
self.sensor.stop()
self.sensor.destroy()
self.sensor = None
def render(self, display):
if self.surface is not None:
display.blit(self.surface, (0, 0))
@staticmethod
def _parse_image(weak_self, image):
self = weak_self()
if not self:
return
self.current_frame = image.frame
image.convert(cc.Raw)
array = np.frombuffer(image.raw_data, dtype=np.dtype("uint8"))
array = np.reshape(array, (image.height, image.width, 4))
array = array[:, :, :3]
array = array[:, :, ::-1]
self.surface = pygame.surfarray.make_surface(array.swapaxes(0, 1))
# ==============================================================================
# -- VehicleControl -----------------------------------------------------------
# ==============================================================================
class VehicleControl(object):
MOUSE_STEERING_RANGE = 200
signal_received = False
"""Class that handles keyboard input."""
def __init__(self, world, start_in_autopilot):
self._autopilot_enabled = start_in_autopilot
self._world = world
self._control = carla.VehicleControl()
self._lights = carla.VehicleLightState.NONE
world.player.set_autopilot(self._autopilot_enabled)
self._restrictor = carla.RssRestrictor()
self._vehicle_physics = world.player.get_physics_control()
world.player.set_light_state(self._lights)
self._steer_cache = 0.0
self._mouse_steering_center = None
self._surface = pygame.Surface((self.MOUSE_STEERING_RANGE * 2, self.MOUSE_STEERING_RANGE * 2))
self._surface.set_colorkey(pygame.Color('black'))
self._surface.set_alpha(60)
line_width = 2
pygame.draw.polygon(self._surface,
(0, 0, 255),
[
(0, 0),
(0, self.MOUSE_STEERING_RANGE * 2 - line_width),
(self.MOUSE_STEERING_RANGE * 2 - line_width,
self.MOUSE_STEERING_RANGE * 2 - line_width),
(self.MOUSE_STEERING_RANGE * 2 - line_width, 0),
(0, 0)
], line_width)
pygame.draw.polygon(self._surface,
(0, 0, 255),
[
(0, self.MOUSE_STEERING_RANGE),
(self.MOUSE_STEERING_RANGE * 2, self.MOUSE_STEERING_RANGE)
], line_width)
pygame.draw.polygon(self._surface,
(0, 0, 255),
[
(self.MOUSE_STEERING_RANGE, 0),
(self.MOUSE_STEERING_RANGE, self.MOUSE_STEERING_RANGE * 2)
], line_width)
world.hud.notification("Press 'H' or '?' for help.", seconds=4.0)
def render(self, display):
if self._mouse_steering_center:
display.blit(
self._surface, (self._mouse_steering_center[0] - self.MOUSE_STEERING_RANGE, self._mouse_steering_center[1] - self.MOUSE_STEERING_RANGE))
@staticmethod
def signal_handler(signum, _):
print('\nReceived signal {}. Trigger stopping...'.format(signum))
VehicleControl.signal_received = True
def parse_events(self, world, clock, sync_mode):
if VehicleControl.signal_received:
print('\nAccepted signal. Stopping loop...')
return True
if isinstance(self._control, carla.VehicleControl):
current_lights = self._lights
for event in pygame.event.get():
if event.type == pygame.QUIT:
return True
elif event.type == pygame.KEYUP:
if self._is_quit_shortcut(event.key):
return True
elif event.key == K_BACKSPACE:
if self._autopilot_enabled:
world.player.set_autopilot(False)
world.restart()
world.player.set_autopilot(True)
else:
world.restart()
elif event.key == K_F1:
world.hud.toggle_info()
elif event.key == K_h or (event.key == K_SLASH and pygame.key.get_mods() & KMOD_SHIFT):
world.hud.help.toggle()
elif event.key == K_TAB:
world.rss_unstructured_scene_visualizer.toggle_camera()
elif event.key == K_n:
world.toggle_pause()
elif event.key == K_r:
world.toggle_recording()
elif event.key == K_F2:
if self._world and self._world.rss_sensor:
self._world.rss_sensor.toggle_debug_visualization_mode()
elif event.key == K_F3:
if self._world and self._world.rss_sensor:
self._world.rss_sensor.decrease_log_level()
self._restrictor.set_log_level(self._world.rss_sensor.log_level)
elif event.key == K_F4:
if self._world and self._world.rss_sensor:
self._world.rss_sensor.increase_log_level()
self._restrictor.set_log_level(self._world.rss_sensor.log_level)
elif event.key == K_F5:
if self._world and self._world.rss_sensor:
self._world.rss_sensor.decrease_map_log_level()
elif event.key == K_F6:
if self._world and self._world.rss_sensor:
self._world.rss_sensor.increase_map_log_level()
elif event.key == K_b:
if self._world and self._world.rss_sensor:
if self._world.rss_sensor.sensor.road_boundaries_mode == carla.RssRoadBoundariesMode.Off:
self._world.rss_sensor.sensor.road_boundaries_mode = carla.RssRoadBoundariesMode.On
print("carla.RssRoadBoundariesMode.On")
else:
self._world.rss_sensor.sensor.road_boundaries_mode = carla.RssRoadBoundariesMode.Off
print("carla.RssRoadBoundariesMode.Off")
elif event.key == K_g:
if self._world and self._world.rss_sensor:
self._world.rss_sensor.drop_route()
if isinstance(self._control, carla.VehicleControl):
if event.key == K_q:
self._control.gear = 1 if self._control.reverse else -1
elif event.key == K_p and not pygame.key.get_mods() & KMOD_CTRL:
self._autopilot_enabled = not self._autopilot_enabled
world.player.set_autopilot(self._autopilot_enabled)
world.hud.notification(
'Autopilot %s' % ('On' if self._autopilot_enabled else 'Off'))
elif event.key == K_l and pygame.key.get_mods() & KMOD_CTRL:
current_lights ^= carla.VehicleLightState.Special1
elif event.key == K_l and pygame.key.get_mods() & KMOD_SHIFT:
current_lights ^= carla.VehicleLightState.HighBeam
elif event.key == K_l:
# Use 'L' key to switch between lights:
# closed -> position -> low beam -> fog
if not self._lights & carla.VehicleLightState.Position:
world.hud.notification("Position lights")
current_lights |= carla.VehicleLightState.Position
else:
world.hud.notification("Low beam lights")
current_lights |= carla.VehicleLightState.LowBeam
if self._lights & carla.VehicleLightState.LowBeam:
world.hud.notification("Fog lights")
current_lights |= carla.VehicleLightState.Fog
if self._lights & carla.VehicleLightState.Fog:
world.hud.notification("Lights off")
current_lights ^= carla.VehicleLightState.Position
current_lights ^= carla.VehicleLightState.LowBeam
current_lights ^= carla.VehicleLightState.Fog
elif event.key == K_i:
current_lights ^= carla.VehicleLightState.Interior
elif event.key == K_z:
current_lights ^= carla.VehicleLightState.LeftBlinker
elif event.key == K_x:
current_lights ^= carla.VehicleLightState.RightBlinker
elif event.type == MOUSEBUTTONDOWN:
# store current mouse position for mouse-steering
if event.button == 1:
self._mouse_steering_center = event.pos
elif event.type == MOUSEBUTTONUP:
if event.button == 1:
self._mouse_steering_center = None
if not self._autopilot_enabled:
prev_steer_cache = self._steer_cache
self._parse_vehicle_keys(pygame.key.get_pressed(), clock.get_time())
if pygame.mouse.get_pressed()[0]:
self._parse_mouse(pygame.mouse.get_pos())
self._control.reverse = self._control.gear < 0
vehicle_control = self._control
world.hud.original_vehicle_control = vehicle_control
world.hud.restricted_vehicle_control = vehicle_control
# limit speed to 30kmh
v = self._world.player.get_velocity()
if (3.6 * math.sqrt(v.x**2 + v.y**2 + v.z**2)) > 30.0:
self._control.throttle = 0
# if self._world.rss_sensor and self._world.rss_sensor.ego_dynamics_on_route and not self._world.rss_sensor.ego_dynamics_on_route.ego_center_within_route:
# print ("Not on route!" + str(self._world.rss_sensor.ego_dynamics_on_route))
if self._restrictor:
rss_proper_response = self._world.rss_sensor.proper_response if self._world.rss_sensor and self._world.rss_sensor.response_valid else None
if rss_proper_response:
if not (pygame.key.get_mods() & KMOD_CTRL):
vehicle_control = self._restrictor.restrict_vehicle_control(
vehicle_control, rss_proper_response, self._world.rss_sensor.ego_dynamics_on_route, self._vehicle_physics)
world.hud.restricted_vehicle_control = vehicle_control
world.hud.allowed_steering_ranges = self._world.rss_sensor.get_steering_ranges()
if world.hud.original_vehicle_control.steer != world.hud.restricted_vehicle_control.steer:
self._steer_cache = prev_steer_cache
# Set automatic control-related vehicle lights
if vehicle_control.brake:
current_lights |= carla.VehicleLightState.Brake
else: # Remove the Brake flag
current_lights &= carla.VehicleLightState.All ^ carla.VehicleLightState.Brake
if vehicle_control.reverse:
current_lights |= carla.VehicleLightState.Reverse
else: # Remove the Reverse flag
current_lights &= carla.VehicleLightState.All ^ carla.VehicleLightState.Reverse
if current_lights != self._lights: # Change the light state only if necessary
self._lights = current_lights
world.player.set_light_state(carla.VehicleLightState(self._lights))
world.player.apply_control(vehicle_control)
def _parse_vehicle_keys(self, keys, milliseconds):
if keys[K_UP] or keys[K_w]:
self._control.throttle = min(self._control.throttle + 0.2, 1)
else:
self._control.throttle = max(self._control.throttle - 0.2, 0)
if keys[K_DOWN] or keys[K_s]:
self._control.brake = min(self._control.brake + 0.2, 1)
else:
self._control.brake = max(self._control.brake - 0.2, 0)
steer_increment = 5e-4 * milliseconds
if keys[K_LEFT] or keys[K_a]:
if self._steer_cache > 0:
self._steer_cache = 0
else:
self._steer_cache -= steer_increment
elif keys[K_RIGHT] or keys[K_d]:
if self._steer_cache < 0:
self._steer_cache = 0
else:
self._steer_cache += steer_increment
elif self._steer_cache > 0:
self._steer_cache = max(self._steer_cache - steer_increment, 0.0)
elif self._steer_cache < 0:
self._steer_cache = min(self._steer_cache + steer_increment, 0.0)
else:
self._steer_cache = 0
self._steer_cache = min(1.0, max(-1.0, self._steer_cache))
self._control.steer = round(self._steer_cache, 1)
self._control.hand_brake = keys[K_SPACE]
def _parse_mouse(self, pos):
if not self._mouse_steering_center:
return
lateral = float(pos[0] - self._mouse_steering_center[0])
longitudinal = float(pos[1] - self._mouse_steering_center[1])
max_val = self.MOUSE_STEERING_RANGE
lateral = -max_val if lateral < -max_val else max_val if lateral > max_val else lateral
longitudinal = -max_val if longitudinal < -max_val else max_val if longitudinal > max_val else longitudinal
self._control.steer = lateral / max_val
if longitudinal < 0.0:
self._control.throttle = -longitudinal / max_val
self._control.brake = 0.0
elif longitudinal > 0.0:
self._control.throttle = 0.0
self._control.brake = longitudinal / max_val
@staticmethod
def _is_quit_shortcut(key):
return (key == K_ESCAPE) or (key == K_q and pygame.key.get_mods() & KMOD_CTRL)
# ==============================================================================
# -- HUD -----------------------------------------------------------------------
# ==============================================================================
class HUD(object):
def __init__(self, width, height, world):
self.dim = (width, height)
self._world = world
self.map_name = world.get_map().name
font = pygame.font.Font(pygame.font.get_default_font(), 20)
font_name = 'courier' if os.name == 'nt' else 'mono'
fonts = [x for x in pygame.font.get_fonts() if font_name in x]
default_font = 'ubuntumono'
mono = default_font if default_font in fonts else fonts[0]
mono = pygame.font.match_font(mono)
self._font_mono = pygame.font.Font(mono, 12 if os.name == 'nt' else 14)
self._notifications = FadingText(font, (width, 40), (0, height - 40))
self.help = HelpText(pygame.font.Font(mono, 16), width, height)
self.server_fps = 0
self.frame = 0
self.simulation_time = 0
self.original_vehicle_control = None
self.restricted_vehicle_control = None
self.allowed_steering_ranges = []
self._show_info = True
self._info_text = []
self._server_clock = pygame.time.Clock()
self.rss_state_visualizer = RssStateVisualizer(self.dim, self._font_mono, self._world)
def on_world_tick(self, timestamp):
self._server_clock.tick()
self.server_fps = self._server_clock.get_fps()
self.frame = timestamp.frame
self.simulation_time = timestamp.elapsed_seconds
def tick(self, player, clock):
self._notifications.tick(clock)
if not self._show_info:
return
t = player.get_transform()
v = player.get_velocity()
c = player.get_control()
self._info_text = [
'Server: % 16.0f FPS' % self.server_fps,
'Client: % 16.0f FPS' % clock.get_fps(),
'Map: % 20s' % self.map_name,
'',
'Speed: % 15.0f km/h' % (3.6 * math.sqrt(v.x**2 + v.y**2 + v.z**2)),
'Location:% 20s' % ('(% 5.1f, % 5.1f)' % (t.location.x, t.location.y)),
'Heading: % 20.2f' % math.radians(t.rotation.yaw),
'']
if self.original_vehicle_control:
orig_control = self.original_vehicle_control
restricted_control = self.restricted_vehicle_control
allowed_steering_ranges = self.allowed_steering_ranges
self._info_text += [
('Throttle:', orig_control.throttle, 0.0, 1.0, restricted_control.throttle),
('Steer:', orig_control.steer, -1.0, 1.0, restricted_control.steer, allowed_steering_ranges),
('Brake:', orig_control.brake, 0.0, 1.0, restricted_control.brake)]
self._info_text += [
('Reverse:', c.reverse),
'']
def toggle_info(self):
self._show_info = not self._show_info
def notification(self, text, seconds=2.0):
self._notifications.set_text(text, seconds=seconds)
def error(self, text):
self._notifications.set_text('Error: %s' % text, (255, 0, 0))
def render(self, display):
if self._show_info:
info_surface = pygame.Surface((220, self.dim[1]))
info_surface.set_alpha(100)
display.blit(info_surface, (0, 0))
v_offset = 4
bar_h_offset = 100
bar_width = 106
for item in self._info_text:
text_color = (255, 255, 255)
if v_offset + 18 > self.dim[1]:
break
if isinstance(item, list):
if len(item) > 1:
points = [(x + 8, v_offset + 8 + (1.0 - y) * 30) for x, y in enumerate(item)]
pygame.draw.lines(display, (255, 136, 0), False, points, 2)
item = None
v_offset += 18
elif isinstance(item, tuple):
if isinstance(item[1], bool):
rect = pygame.Rect((bar_h_offset, v_offset + 2), (10, 10))
pygame.draw.rect(display, (255, 255, 255), rect, 0 if item[1] else 1)
else:
# draw allowed steering ranges
if len(item) == 6 and item[2] < 0.0:
for steering_range in item[5]:
starting_value = min(steering_range[0], steering_range[1])
length = (max(steering_range[0], steering_range[1]) -
min(steering_range[0], steering_range[1])) / 2
rect = pygame.Rect(
(bar_h_offset + (starting_value + 1) * (bar_width / 2), v_offset + 2), (length * bar_width, 14))
pygame.draw.rect(display, (0, 255, 0), rect)
# draw border
rect_border = pygame.Rect((bar_h_offset, v_offset + 2), (bar_width, 14))
pygame.draw.rect(display, (255, 255, 255), rect_border, 1)
# draw value / restricted value
input_value_rect_fill = 0
if len(item) >= 5:
if item[1] != item[4]:
input_value_rect_fill = 1
f = (item[4] - item[2]) / (item[3] - item[2])
if item[2] < 0.0:
rect = pygame.Rect(
(bar_h_offset + 1 + f * (bar_width - 6), v_offset + 3), (12, 12))
else:
rect = pygame.Rect((bar_h_offset + 1, v_offset + 3), (f * bar_width, 12))
pygame.draw.rect(display, (255, 0, 0), rect)
f = (item[1] - item[2]) / (item[3] - item[2])
rect = None
if item[2] < 0.0:
rect = pygame.Rect((bar_h_offset + 2 + f * (bar_width - 14), v_offset + 4), (10, 10))
else:
if item[1] != 0:
rect = pygame.Rect((bar_h_offset + 2, v_offset + 4), (f * (bar_width - 4), 10))
if rect:
pygame.draw.rect(display, (255, 255, 255), rect, input_value_rect_fill)
item = item[0]
if item: # At this point has to be a str.
surface = self._font_mono.render(item, True, text_color)
display.blit(surface, (8, v_offset))
v_offset += 18
self.rss_state_visualizer.render(display, v_offset)
self._notifications.render(display)
self.help.render(display)
# ==============================================================================
# -- FadingText ----------------------------------------------------------------
# ==============================================================================
class FadingText(object):
def __init__(self, font, dim, pos):
self.font = font
self.dim = dim
self.pos = pos
self.seconds_left = 0
self.surface = pygame.Surface(self.dim)
def set_text(self, text, color=(255, 255, 255), seconds=2.0):
text_texture = self.font.render(text, True, color)
self.surface = pygame.Surface(self.dim)
self.seconds_left = seconds
self.surface.fill((0, 0, 0, 0))
self.surface.blit(text_texture, (10, 11))
def tick(self, clock):
delta_seconds = 1e-3 * clock.get_time()
self.seconds_left = max(0.0, self.seconds_left - delta_seconds)
self.surface.set_alpha(500.0 * self.seconds_left)
def render(self, display):
display.blit(self.surface, self.pos)
# ==============================================================================
# -- HelpText ------------------------------------------------------------------
# ==============================================================================
class HelpText(object):
"""Helper class to handle text output using pygame"""
def __init__(self, font, width, height):
lines = __doc__.split('\n')
self.font = font
self.line_space = 18
self.dim = (780, len(lines) * self.line_space + 12)
self.pos = (0.5 * width - 0.5 * self.dim[0], 0.5 * height - 0.5 * self.dim[1])
self.seconds_left = 0
self.surface = pygame.Surface(self.dim)
self.surface.fill((0, 0, 0, 0))
for n, line in enumerate(lines):
text_texture = self.font.render(line, True, (255, 255, 255))
self.surface.blit(text_texture, (22, n * self.line_space))
self._render = False
self.surface.set_alpha(220)
def toggle(self):
self._render = not self._render
def render(self, display):
if self._render:
display.blit(self.surface, self.pos)
# ==============================================================================
# -- game_loop() ---------------------------------------------------------------
# ==============================================================================
def game_loop(args):
pygame.init()
pygame.font.init()
world = None
try:
client = carla.Client(args.host, args.port)
client.set_timeout(2.0)
display = pygame.display.set_mode(
(args.width, args.height),
pygame.HWSURFACE | pygame.DOUBLEBUF)
sim_world = client.get_world()
original_settings = sim_world.get_settings()
settings = sim_world.get_settings()
if args.sync != settings.synchronous_mode:
args.sync = True
settings.synchronous_mode = True
settings.fixed_delta_seconds = 0.05
sim_world.apply_settings(settings)
traffic_manager = client.get_trafficmanager()
traffic_manager.set_synchronous_mode(True)
world = World(sim_world, args)
controller = VehicleControl(world, args.autopilot)
clock = pygame.time.Clock()
while True:
if args.sync:
sim_world.tick()
clock.tick_busy_loop(60)
if controller.parse_events(world, clock, args.sync):
return
world.tick(clock)
world.render(display)
controller.render(display)
pygame.display.flip()
finally:
if world is not None:
print('Destroying the world...')
world.destroy()
print('Destroyed!')
pygame.quit()
# ==============================================================================
# -- main() --------------------------------------------------------------------
# ==============================================================================
def main():
argparser = argparse.ArgumentParser(
description='CARLA Manual Control Client RSS')
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(
'--res',
metavar='WIDTHxHEIGHT',
default='1280x720',
help='window resolution (default: 1280x720)')
argparser.add_argument(
'--filter',
metavar='PATTERN',
default='vehicle.*',
help='actor filter (default: "vehicle.*")')
argparser.add_argument(
'--rolename',
metavar='NAME',
default='hero',
help='actor role name (default: "hero")')
argparser.add_argument(
'--externalActor',
action='store_true',
help='attaches to externally created actor by role name')
argparser.add_argument(
'--sync',
action='store_true',
help='Activate synchronous mode execution')
args = argparser.parse_args()
args.width, args.height = [int(x) for x in args.res.split('x')]
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__)
signal.signal(signal.SIGINT, VehicleControl.signal_handler)
try:
game_loop(args)
except KeyboardInterrupt:
print('\nCancelled by user. Bye!')
if __name__ == '__main__':
main()

View File

@ -1,457 +0,0 @@
#!/usr/bin/env python
#
# Copyright (c) 2020 Intel Corporation
#
import glob
import os
import sys
try:
sys.path.append(glob.glob(os.path.dirname(os.path.dirname(os.path.dirname(os.path.abspath(__file__)))) + '/carla/dist/carla-*%d.%d-%s.egg' % (
sys.version_info.major,
sys.version_info.minor,
'win-amd64' if os.name == 'nt' else 'linux-x86_64'))[0])
except IndexError:
pass
import inspect
import carla
from carla import ad
import math
from rss_visualization import RssDebugVisualizer # pylint: disable=relative-import
# ==============================================================================
# -- RssSensor -----------------------------------------------------------------
# ==============================================================================
class RssStateInfo(object):
def __init__(self, rss_state, ego_dynamics_on_route, world_model):
self.rss_state = rss_state
self.distance = -1
self.is_dangerous = ad.rss.state.isDangerous(rss_state)
if rss_state.situationType == ad.rss.situation.SituationType.Unstructured:
self.actor_calculation_mode = ad.rss.map.RssMode.Unstructured
else:
self.actor_calculation_mode = ad.rss.map.RssMode.Structured
# calculate distance to other vehicle
object_state = None
for scene in world_model.scenes:
if scene.object.objectId == rss_state.objectId:
object_state = scene.object.state
break
if object_state:
self.distance = math.sqrt((float(ego_dynamics_on_route.ego_center.x) - float(object_state.centerPoint.x))**2 +
(float(ego_dynamics_on_route.ego_center.y) - float(object_state.centerPoint.y))**2)
self.longitudinal_margin = float(rss_state.longitudinalState.rssStateInformation.currentDistance - rss_state.longitudinalState.rssStateInformation.safeDistance)
self.margin = max(0, self.longitudinal_margin)
self.lateral_margin = None
if rss_state.lateralStateLeft.rssStateInformation.evaluator != "None":
self.lateral_margin = rss_state.lateralStateLeft.rssStateInformation.currentDistance - rss_state.lateralStateLeft.rssStateInformation.safeDistance
if rss_state.lateralStateRight.rssStateInformation.evaluator != "None":
lateral_margin_right = rss_state.lateralStateRight.rssStateInformation.currentDistance - rss_state.lateralStateRight.rssStateInformation.safeDistance
if self.lateral_margin==None or self.lateral_margin > lateral_margin_right:
self.lateral_margin=lateral_margin_right
if self.lateral_margin!=None and self.lateral_margin>0:
self.margin += self.lateral_margin
def get_actor(self, world):
if self.rss_state.objectId == 18446744073709551614:
return None # "Border Left"
elif self.rss_state.objectId == 18446744073709551615:
return None # "Border Right"
else:
return world.get_actor(self.rss_state.objectId)
def __str__(self):
return "RssStateInfo: object=" + str(self.rss_state.objectId) + " dangerous=" + str(self.is_dangerous)
class RssSensor(object):
def __init__(self, parent_actor, world, unstructured_scene_visualizer, bounding_box_visualizer, state_visualizer, routing_targets=None):
self.sensor = None
self.unstructured_scene_visualizer = unstructured_scene_visualizer
self.bounding_box_visualizer = bounding_box_visualizer
self._parent = parent_actor
self.timestamp = None
self.response_valid = False
self.proper_response = None
self.rss_state_snapshot = None
self.situation_snapshot = None
self.world_model = None
self.individual_rss_states = []
self._allowed_heading_ranges = []
self.ego_dynamics_on_route = None
self.current_vehicle_parameters = self.get_default_parameters()
self.route = None
self.debug_visualizer = RssDebugVisualizer(parent_actor, world)
self.state_visualizer = state_visualizer
self.change_to_unstructured_position_map = dict()
# get max steering angle
physics_control = parent_actor.get_physics_control()
self._max_steer_angle = 0.0
for wheel in physics_control.wheels:
if wheel.max_steer_angle > self._max_steer_angle:
self._max_steer_angle = wheel.max_steer_angle
self._max_steer_angle = math.radians(self._max_steer_angle)
world = self._parent.get_world()
bp = world.get_blueprint_library().find('sensor.other.rss')
self.sensor = world.spawn_actor(bp, carla.Transform(carla.Location(x=0.0, z=0.0)), attach_to=self._parent)
# We need to pass the lambda a weak reference to self to avoid circular
# reference.
def check_rss_class(clazz):
return inspect.isclass(clazz) and "RssSensor" in clazz.__name__
if not inspect.getmembers(carla, check_rss_class):
raise RuntimeError('CARLA PythonAPI not compiled in RSS variant, please "make PythonAPI.rss"')
self.log_level = carla.RssLogLevel.warn
self.map_log_level = carla.RssLogLevel.warn
self.set_default_parameters()
self.sensor.register_actor_constellation_callback(self._on_actor_constellation_request)
self.sensor.listen(self._on_rss_response)
self.sensor.set_log_level(self.log_level)
self.sensor.set_map_log_level(self.map_log_level)
# only relevant if actor constellation callback is not registered
# self.sensor.ego_vehicle_dynamics = self.current_vehicle_parameters
self.sensor.road_boundaries_mode = carla.RssRoadBoundariesMode.Off
self.sensor.reset_routing_targets()
if routing_targets:
for target in routing_targets:
self.sensor.append_routing_target(target)
def _on_actor_constellation_request(self, actor_constellation_data):
# print("_on_actor_constellation_request: ", str(actor_constellation_data))
actor_constellation_result = carla.RssActorConstellationResult()
actor_constellation_result.rss_calculation_mode = ad.rss.map.RssMode.NotRelevant
actor_constellation_result.restrict_speed_limit_mode = ad.rss.map.RssSceneCreation.RestrictSpeedLimitMode.IncreasedSpeedLimit10
actor_constellation_result.ego_vehicle_dynamics = self.current_vehicle_parameters
actor_constellation_result.actor_object_type = ad.rss.world.ObjectType.Invalid
actor_constellation_result.actor_dynamics = self.current_vehicle_parameters
actor_id = -1
# actor_type_id = "none"
if actor_constellation_data.other_actor != None:
actor_id = actor_constellation_data.other_actor.id
# actor_type_id = actor_constellation_data.other_actor.type_id
ego_on_the_sidewalk = False
ego_on_routeable_road = False
for occupied_region in actor_constellation_data.ego_match_object.mapMatchedBoundingBox.laneOccupiedRegions:
lane = ad.map.lane.getLane(occupied_region.laneId)
if lane.type == ad.map.lane.LaneType.PEDESTRIAN:
# if not ego_on_the_sidewalk:
# print ( "ego-{} on lane of lane type {} => sidewalk".format(actor_id, lane.type))
ego_on_the_sidewalk = True
elif ad.map.lane.isRouteable(lane):
# if not ego_on_routeable_road:
# print ( "ego-{} on lane of lane type {} => road".format(actor_id, lane.type))
ego_on_routeable_road = True
if 'walker.pedestrian' in actor_constellation_data.other_actor.type_id:
# determine if the pedestrian is walking on the sidewalk or on the road
pedestrian_on_the_road = False
pedestrian_on_the_sidewalk = False
for occupied_region in actor_constellation_data.other_match_object.mapMatchedBoundingBox.laneOccupiedRegions:
lane = ad.map.lane.getLane(occupied_region.laneId)
if lane.type == ad.map.lane.LaneType.PEDESTRIAN:
# if not pedestrian_on_the_sidewalk:
# print ( "pedestrian-{} on lane of lane type {} => sidewalk".format(actor_id, lane.type))
pedestrian_on_the_sidewalk = True
else:
# if not pedestrian_on_the_road:
# print ( "pedestrian-{} on lane of lane type {} => road".format(actor_id, lane.type))
pedestrian_on_the_road = True
if ego_on_routeable_road and not ego_on_the_sidewalk and not pedestrian_on_the_road and pedestrian_on_the_sidewalk:
# pedestrian is not on the road, but on the sidewalk: then common sense is that vehicle has priority
# This analysis can and should be done more detailed, but this is a basic starting point for the decision
# In addition, the road network has to be correct to work best
# (currently there are no sidewalks in intersection areas)
# print ( "pedestrian-{} Off".format(actor_id))
actor_constellation_result.rss_calculation_mode = ad.rss.map.RssMode.NotRelevant
else:
# print ( "pedestrian-{} Unstructured".format(actor_id))
actor_constellation_result.rss_calculation_mode = ad.rss.map.RssMode.Unstructured
actor_constellation_result.actor_object_type = ad.rss.world.ObjectType.Pedestrian
actor_constellation_result.actor_dynamics = self.get_pedestrian_parameters()
elif 'vehicle' in actor_constellation_data.other_actor.type_id:
actor_constellation_result.actor_object_type = ad.rss.world.ObjectType.OtherVehicle
# set the response time of others vehicles to 2 seconds; the rest stays the same
actor_constellation_result.actor_dynamics.responseTime = 2.0
# per default, if ego is not on the road -> unstructured
if ego_on_routeable_road:
actor_constellation_result.rss_calculation_mode = ad.rss.map.RssMode.Structured
else:
# print("vehicle-{} unstructured: reason other ego not on routeable road".format(actor_id))
actor_constellation_result.rss_calculation_mode = ad.rss.map.RssMode.Unstructured
# special handling for vehicles standing still
actor_vel = actor_constellation_data.other_actor.get_velocity()
actor_speed = math.sqrt(actor_vel.x**2 + actor_vel.y**2 + actor_vel.z**2)
if actor_speed < 0.01:
# reduce response time
actor_constellation_result.actor_dynamics.responseTime = 1.0
# still in structured?
if actor_constellation_result.rss_calculation_mode == ad.rss.map.RssMode.Structured:
actor_distance = math.sqrt(float(actor_constellation_data.ego_match_object.enuPosition.centerPoint.x -
actor_constellation_data.other_match_object.enuPosition.centerPoint.x)**2 +
float(actor_constellation_data.ego_match_object.enuPosition.centerPoint.y -
actor_constellation_data.other_match_object.enuPosition.centerPoint.y)**2)
# print("vehicle-{} unstructured check: other distance {}".format(actor_id, actor_distance))
if actor_constellation_data.ego_dynamics_on_route.ego_speed < 0.01:
# both vehicles stand still, so we have to analyze in detail if we possibly want to use
# unstructured mode to cope with blockades on the road...
if actor_distance < 10:
# the other has to be near enough to trigger a switch to unstructured
other_outside_routeable_road = False
for occupied_region in actor_constellation_data.other_match_object.mapMatchedBoundingBox.laneOccupiedRegions:
lane = ad.map.lane.getLane(occupied_region.laneId)
if not ad.map.lane.isRouteable(lane):
other_outside_routeable_road = True
if other_outside_routeable_road:
# if the other is somewhat outside the standard routeable road (e.g. parked at the side, ...)
# we immediately decide for unstructured
# print("vehicle-{} unstructured: reason other outside routeable
# road".format(actor_id))
actor_constellation_result.rss_calculation_mode = ad.rss.map.RssMode.Unstructured
else:
# otherwise we have to look in the orientation delta in addition to get some basic idea of the
# constellation (we don't want to go into unstructured if we both waiting
# behind a red light...)
heading_delta = abs(float(actor_constellation_data.ego_match_object.enuPosition.heading -
actor_constellation_data.other_match_object.enuPosition.heading))
if heading_delta > 0.2: # around 11 degree
# print("vehicle-{} unstructured: reason heading delta
# {}".format(actor_id, heading_delta))
actor_constellation_result.rss_calculation_mode = ad.rss.map.RssMode.Unstructured
self.change_to_unstructured_position_map[
actor_id] = actor_constellation_data.other_match_object.enuPosition
else:
# ego moves
if actor_distance < 10:
# if the ego moves, the other actor doesn't move an the mode was
# previously set to unstructured, keep it
try:
if self.change_to_unstructured_position_map[actor_id] == actor_constellation_data.other_match_object.enuPosition:
heading_delta = abs(float(actor_constellation_data.ego_match_object.enuPosition.heading -
actor_constellation_data.other_match_object.enuPosition.heading))
if heading_delta > 0.2:
actor_constellation_result.rss_calculation_mode = ad.rss.map.RssMode.Unstructured
else:
del self.change_to_unstructured_position_map[actor_id]
except (AttributeError, KeyError):
pass
else:
if actor_id in self.change_to_unstructured_position_map:
del self.change_to_unstructured_position_map[actor_id]
# still in structured?
if actor_constellation_result.rss_calculation_mode == ad.rss.map.RssMode.Structured:
# in structured case we have to cope with not yet implemented lateral intersection checks in core RSS implementation
# if the other is standing still, we don't assume that he will accelerate
# otherwise if standing at the intersection the acceleration within reaction time
# will allow to enter the intersection which current RSS implementation will immediately consider
# as dangerous
# print("_on_actor_constellation_result({}) setting accelMax to
# zero".format(actor_constellation_data.other_actor.id))
actor_constellation_result.actor_dynamics.alphaLon.accelMax = 0.
actor_constellation_result.actor_dynamics.alphaLat.accelMax = 0.
else:
# store route for debug drawings
self.route = actor_constellation_data.ego_route
# since the ego vehicle is controlled manually, it is easy possible that the ego vehicle
# accelerates far more in lateral direction than the ego_dynamics indicate
# in an automated vehicle this would be considered by the low-level controller when the RSS restriction
# is taken into account properly
# but the simple RSS restrictor within CARLA is not able to do so...
# So we should at least tell RSS about the fact that we acceleration more than this
# to be able to react on this
abs_avg_route_accel_lat = abs(float(actor_constellation_data.ego_dynamics_on_route.avg_route_accel_lat))
if abs_avg_route_accel_lat > actor_constellation_result.ego_vehicle_dynamics.alphaLat.accelMax:
# print("!! Route lateral dynamics exceed expectations: route:{} expected:{} !!".format(abs_avg_route_accel_lat,
# actor_constellation_result.ego_vehicle_dynamics.alphaLat.accelMax))
actor_constellation_result.ego_vehicle_dynamics.alphaLat.accelMax = min(20., abs_avg_route_accel_lat)
# print("_on_actor_constellation_result({}-{}): ".format(actor_id,
# actor_type_id), str(actor_constellation_result))
return actor_constellation_result
def destroy(self):
if self.sensor:
print("Stopping RSS sensor")
self.sensor.stop()
print("Deleting Scene Visualizer")
self.unstructured_scene_visualizer = None
print("Destroying RSS sensor")
self.sensor.destroy()
print("Destroyed RSS sensor")
def toggle_debug_visualization_mode(self):
self.debug_visualizer.toggleMode()
def increase_log_level(self):
print("inccrease {}".format(self.log_level))
if self.log_level < carla.RssLogLevel.off:
self.log_level = self.log_level+1
self.sensor.set_log_level(self.log_level)
def decrease_log_level(self):
print("decrease {}".format(self.log_level))
if self.log_level > carla.RssLogLevel.trace:
self.log_level = self.log_level-1
self.sensor.set_log_level(self.log_level)
def increase_map_log_level(self):
if self.map_log_level < carla.RssLogLevel.off:
self.map_log_level = self.map_log_level+1
self.sensor.set_map_log_level(self.map_log_level)
def decrease_map_log_level(self):
if self.map_log_level > carla.RssLogLevel.trace:
self.map_log_level = self.map_log_level-1
self.sensor.set_map_log_level(self.map_log_level)
def drop_route(self):
self.sensor.drop_route()
@staticmethod
def get_default_parameters():
ego_dynamics = ad.rss.world.RssDynamics()
ego_dynamics.alphaLon.accelMax = 5
ego_dynamics.alphaLon.brakeMax = -8
ego_dynamics.alphaLon.brakeMin = -4
ego_dynamics.alphaLon.brakeMinCorrect = -3
ego_dynamics.alphaLat.accelMax = 0.2
ego_dynamics.alphaLat.brakeMin = -0.8
ego_dynamics.lateralFluctuationMargin = 0.1
ego_dynamics.responseTime = 0.5
ego_dynamics.maxSpeedOnAcceleration = 100
ego_dynamics.unstructuredSettings.pedestrianTurningRadius = 2.0
ego_dynamics.unstructuredSettings.driveAwayMaxAngle = 2.4
ego_dynamics.unstructuredSettings.vehicleYawRateChange = 1.3
ego_dynamics.unstructuredSettings.vehicleMinRadius = 3.5
ego_dynamics.unstructuredSettings.vehicleTrajectoryCalculationStep = 0.2
ego_dynamics.unstructuredSettings.vehicleFrontIntermediateYawRateChangeRatioSteps = 4
ego_dynamics.unstructuredSettings.vehicleBackIntermediateYawRateChangeRatioSteps = 0
ego_dynamics.unstructuredSettings.vehicleContinueForwardIntermediateAccelerationSteps = 3
ego_dynamics.unstructuredSettings.vehicleBrakeIntermediateAccelerationSteps = 3
ego_dynamics.unstructuredSettings.pedestrianTurningRadius = 2.0
ego_dynamics.unstructuredSettings.pedestrianContinueForwardIntermediateHeadingChangeRatioSteps = 3
ego_dynamics.unstructuredSettings.pedestrianContinueForwardIntermediateAccelerationSteps = 0
ego_dynamics.unstructuredSettings.pedestrianBrakeIntermediateAccelerationSteps = 3
ego_dynamics.unstructuredSettings.pedestrianFrontIntermediateHeadingChangeRatioSteps = 4
ego_dynamics.unstructuredSettings.pedestrianBackIntermediateHeadingChangeRatioSteps = 0
return ego_dynamics
def set_default_parameters(self):
print("Use 'default' RSS Parameters")
self.current_vehicle_parameters = self.get_default_parameters()
@staticmethod
def get_pedestrian_parameters():
pedestrian_dynamics = ad.rss.world.RssDynamics()
pedestrian_dynamics.alphaLon.accelMax = 2.0
pedestrian_dynamics.alphaLon.brakeMax = -2.0
pedestrian_dynamics.alphaLon.brakeMin = -2.0
pedestrian_dynamics.alphaLon.brakeMinCorrect = -2.0
pedestrian_dynamics.alphaLat.accelMax = 0.001
pedestrian_dynamics.alphaLat.brakeMin = -0.001
pedestrian_dynamics.lateralFluctuationMargin = 0.1
pedestrian_dynamics.responseTime = 0.8
pedestrian_dynamics.maxSpeedOnAcceleration = 10
pedestrian_dynamics.unstructuredSettings.pedestrianTurningRadius = 2.0
pedestrian_dynamics.unstructuredSettings.driveAwayMaxAngle = 2.4
pedestrian_dynamics.unstructuredSettings.pedestrianContinueForwardIntermediateHeadingChangeRatioSteps = 3
pedestrian_dynamics.unstructuredSettings.pedestrianContinueForwardIntermediateAccelerationSteps = 0
pedestrian_dynamics.unstructuredSettings.pedestrianBrakeIntermediateAccelerationSteps = 3
pedestrian_dynamics.unstructuredSettings.pedestrianFrontIntermediateHeadingChangeRatioSteps = 4
pedestrian_dynamics.unstructuredSettings.pedestrianBackIntermediateHeadingChangeRatioSteps = 0
#not used:
pedestrian_dynamics.unstructuredSettings.vehicleYawRateChange = 1.3
pedestrian_dynamics.unstructuredSettings.vehicleMinRadius = 3.5
pedestrian_dynamics.unstructuredSettings.vehicleTrajectoryCalculationStep = 0.2
pedestrian_dynamics.unstructuredSettings.vehicleFrontIntermediateYawRateChangeRatioSteps = 4
pedestrian_dynamics.unstructuredSettings.vehicleBackIntermediateYawRateChangeRatioSteps = 0
pedestrian_dynamics.unstructuredSettings.vehicleContinueForwardIntermediateAccelerationSteps = 3
pedestrian_dynamics.unstructuredSettings.vehicleBrakeIntermediateAccelerationSteps = 3
return pedestrian_dynamics
def get_steering_ranges(self):
ranges = []
for heading_range in self._allowed_heading_ranges:
ranges.append(
(
(float(self.ego_dynamics_on_route.ego_heading) - float(heading_range.begin)) / self._max_steer_angle,
(float(self.ego_dynamics_on_route.ego_heading) - float(heading_range.end)) / self._max_steer_angle)
)
return ranges
def _on_rss_response(self, response):
if not self or not response:
return
delta_time = 0.1
if self.timestamp:
delta_time = response.timestamp - self.timestamp
if delta_time > -0.05:
self.timestamp = response.timestamp
self.response_valid = response.response_valid
self.proper_response = response.proper_response
self.ego_dynamics_on_route = response.ego_dynamics_on_route
self.rss_state_snapshot = response.rss_state_snapshot
self.situation_snapshot = response.situation_snapshot
self.world_model = response.world_model
# calculate the allowed heading ranges:
if response.proper_response.headingRanges:
heading = float(response.ego_dynamics_on_route.ego_heading)
heading_ranges = response.proper_response.headingRanges
steering_range = ad.rss.state.HeadingRange()
steering_range.begin = - self._max_steer_angle + heading
steering_range.end = self._max_steer_angle + heading
ad.rss.unstructured.getHeadingOverlap(steering_range, heading_ranges)
self._allowed_heading_ranges = heading_ranges
else:
self._allowed_heading_ranges = []
if self.unstructured_scene_visualizer:
self.unstructured_scene_visualizer.tick(response.frame, response, self._allowed_heading_ranges)
new_states = []
for rss_state in response.rss_state_snapshot.individualResponses:
new_states.append(RssStateInfo(rss_state, response.ego_dynamics_on_route, response.world_model))
if len(new_states) > 0:
new_states.sort(key=lambda rss_states: rss_states.distance)
self.individual_rss_states = new_states
if self.bounding_box_visualizer:
self.bounding_box_visualizer.tick(response.frame, self.individual_rss_states)
if self.state_visualizer:
self.state_visualizer.tick(self.individual_rss_states)
self.debug_visualizer.tick(self.route, not response.proper_response.isSafe,
self.individual_rss_states, self.ego_dynamics_on_route)
else:
print("ignore outdated response {}".format(delta_time))

View File

@ -1,738 +0,0 @@
#!/usr/bin/env python
#
# Copyright (c) 2020 Intel Corporation
#
import glob
import os
import sys
try:
sys.path.append(glob.glob(os.path.dirname(os.path.dirname(os.path.dirname(os.path.abspath(__file__)))) + '/carla/dist/carla-*%d.%d-%s.egg' % (
sys.version_info.major,
sys.version_info.minor,
'win-amd64' if os.name == 'nt' else 'linux-x86_64'))[0])
except IndexError:
pass
from enum import Enum
import math
import numpy as np
import pygame
import weakref
import carla
from carla import ad
class RssStateVisualizer(object):
def __init__(self, display_dimensions, font, world):
self._surface = None
self._display_dimensions = display_dimensions
self._font = font
self._world = world
def tick(self, individual_rss_states):
state_surface = pygame.Surface((220, self._display_dimensions[1]))
state_surface.set_colorkey(pygame.Color('black'))
v_offset = 0
if individual_rss_states:
surface = self._font.render('RSS States:', True, (255, 255, 255))
state_surface.blit(surface, (8, v_offset))
v_offset += 26
for state in individual_rss_states:
object_name = "Obj"
if state.rss_state.objectId == 18446744073709551614:
object_name = "Border Left"
elif state.rss_state.objectId == 18446744073709551615:
object_name = "Border Right"
else:
other_actor = state.get_actor(self._world)
if other_actor:
li = list(other_actor.type_id.split("."))
if li:
li.pop(0)
li = [element.capitalize() for element in li]
object_name = " ".join(li).strip()[:15]
mode = "?"
if state.actor_calculation_mode == ad.rss.map.RssMode.Structured:
mode = "S"
elif state.actor_calculation_mode == ad.rss.map.RssMode.Unstructured:
mode = "U"
elif state.actor_calculation_mode == ad.rss.map.RssMode.NotRelevant:
mode = "-"
item = '%4s % 2dm %8s' % (mode, state.distance, object_name)
surface = self._font.render(item, True, (255, 255, 255))
state_surface.blit(surface, (5, v_offset))
color = (128, 128, 128)
if state.actor_calculation_mode != ad.rss.map.RssMode.NotRelevant:
if state.is_dangerous:
color = (255, 0, 0)
else:
color = (0, 255, 0)
pygame.draw.circle(state_surface, color, (12, v_offset + 7), 5)
xpos = 184
if state.actor_calculation_mode == ad.rss.map.RssMode.Structured:
if not state.rss_state.longitudinalState.isSafe and ((state.rss_state.longitudinalState.rssStateInformation.evaluator == "LongitudinalDistanceSameDirectionOtherInFront") or (state.rss_state.longitudinalState.rssStateInformation.evaluator == "LongitudinalDistanceSameDirectionEgoFront")):
pygame.draw.polygon(
state_surface, (
255, 255, 255), ((xpos + 1, v_offset + 1 + 4), (xpos + 6, v_offset + 1 + 0), (xpos + 11, v_offset + 1 + 4),
(xpos + 7, v_offset + 1 + 4), (xpos + 7, v_offset + 1 + 12), (xpos + 5, v_offset + 1 + 12), (xpos + 5, v_offset + 1 + 4)))
xpos += 14
if not state.rss_state.longitudinalState.isSafe and ((state.rss_state.longitudinalState.rssStateInformation.evaluator == "LongitudinalDistanceOppositeDirectionEgoCorrectLane") or (state.rss_state.longitudinalState.rssStateInformation.evaluator == "LongitudinalDistanceOppositeDirection")):
pygame.draw.polygon(
state_surface, (
255, 255, 255), ((xpos + 2, v_offset + 1 + 8), (xpos + 6, v_offset + 1 + 12), (xpos + 10, v_offset + 1 + 8),
(xpos + 7, v_offset + 1 + 8), (xpos + 7, v_offset + 1 + 0), (xpos + 5, v_offset + 1 + 0), (xpos + 5, v_offset + 1 + 8)))
xpos += 14
if not state.rss_state.lateralStateRight.isSafe and not (state.rss_state.lateralStateRight.rssStateInformation.evaluator == "None"):
pygame.draw.polygon(
state_surface, (
255, 255, 255), ((xpos + 0, v_offset + 1 + 4), (xpos + 8, v_offset + 1 + 4), (xpos + 8, v_offset + 1 + 1),
(xpos + 12, v_offset + 1 + 6), (xpos + 8, v_offset + 1 + 10), (xpos + 8, v_offset + 1 + 8), (xpos + 0, v_offset + 1 + 8)))
xpos += 14
if not state.rss_state.lateralStateLeft.isSafe and not (state.rss_state.lateralStateLeft.rssStateInformation.evaluator == "None"):
pygame.draw.polygon(
state_surface, (
255, 255, 255), ((xpos + 0, v_offset + 1 + 6), (xpos + 4, v_offset + 1 + 1), (xpos + 4, v_offset + 1 + 4),
(xpos + 12, v_offset + 1 + 4), (xpos + 12, v_offset + 1 + 8), (xpos + 4, v_offset + 1 + 8), (xpos + 4, v_offset + 1 + 10)))
xpos += 14
elif state.actor_calculation_mode == ad.rss.map.RssMode.Unstructured:
text = ""
if state.rss_state.unstructuredSceneState.response == ad.rss.state.UnstructuredSceneResponse.DriveAway:
text = " D"
elif state.rss_state.unstructuredSceneState.response == ad.rss.state.UnstructuredSceneResponse.ContinueForward:
text = " C"
elif state.rss_state.unstructuredSceneState.response == ad.rss.state.UnstructuredSceneResponse.Brake:
text = " B"
surface = self._font.render(text, True, (255, 255, 255))
state_surface.blit(surface, (xpos, v_offset))
v_offset += 14
self._surface = state_surface
def render(self, display, v_offset):
if self._surface:
display.blit(self._surface, (0, v_offset))
def get_matrix(transform):
"""
Creates matrix from carla transform.
"""
rotation = transform.rotation
location = transform.location
c_y = np.cos(np.radians(rotation.yaw))
s_y = np.sin(np.radians(rotation.yaw))
c_r = np.cos(np.radians(rotation.roll))
s_r = np.sin(np.radians(rotation.roll))
c_p = np.cos(np.radians(rotation.pitch))
s_p = np.sin(np.radians(rotation.pitch))
matrix = np.matrix(np.identity(4))
matrix[0, 3] = location.x
matrix[1, 3] = location.y
matrix[2, 3] = location.z
matrix[0, 0] = c_p * c_y
matrix[0, 1] = c_y * s_p * s_r - s_y * c_r
matrix[0, 2] = -c_y * s_p * c_r - s_y * s_r
matrix[1, 0] = s_y * c_p
matrix[1, 1] = s_y * s_p * s_r + c_y * c_r
matrix[1, 2] = -s_y * s_p * c_r + c_y * s_r
matrix[2, 0] = s_p
matrix[2, 1] = -c_p * s_r
matrix[2, 2] = c_p * c_r
return matrix
# ==============================================================================
# -- RssUnstructuredSceneVisualizer ------------------------------------------------
# ==============================================================================
class RssUnstructuredSceneVisualizerMode(Enum):
disabled = 1
window = 2
fullscreen = 3
class RssUnstructuredSceneVisualizer(object):
def __init__(self, parent_actor, world, display_dimensions):
self._last_rendered_frame = -1
self._surface = None
self._current_rss_surface = None
self.current_camera_surface = (0, None)
self._world = world
self._parent_actor = parent_actor
self._display_dimensions = display_dimensions
self._camera = None
self._mode = RssUnstructuredSceneVisualizerMode.disabled
self.restart(RssUnstructuredSceneVisualizerMode.window)
def destroy(self):
if self._camera:
self._camera.stop()
self._camera.destroy()
self._camera = None
def restart(self, mode):
# setup up top down camera
self.destroy()
self._mode = mode
spawn_sensor = False
if mode == RssUnstructuredSceneVisualizerMode.window:
self._dim = (self._display_dimensions[0] / 3, self._display_dimensions[1] / 2)
spawn_sensor = True
elif mode == RssUnstructuredSceneVisualizerMode.fullscreen:
self._dim = (self._display_dimensions[0], self._display_dimensions[1])
spawn_sensor = True
else:
self._surface = None
if spawn_sensor:
self._calibration = np.identity(3)
self._calibration[0, 2] = self._dim[0] / 2.0
self._calibration[1, 2] = self._dim[1] / 2.0
self._calibration[0, 0] = self._calibration[1, 1] = self._dim[0] / \
(2.0 * np.tan(90.0 * np.pi / 360.0)) # fov default: 90.0
bp_library = self._world.get_blueprint_library()
bp = bp_library.find('sensor.camera.rgb')
bp.set_attribute('image_size_x', str(self._dim[0]))
bp.set_attribute('image_size_y', str(self._dim[1]))
self._camera = self._world.spawn_actor(
bp,
carla.Transform(carla.Location(x=7.5, z=10), carla.Rotation(pitch=-90)),
attach_to=self._parent_actor)
# We need to pass the lambda a weak reference to self to avoid
# circular reference.
weak_self = weakref.ref(self)
self._camera.listen(lambda image: self._parse_image(weak_self, image))
def update_surface(self, cam_frame, rss_frame):
if self._mode == RssUnstructuredSceneVisualizerMode.disabled:
return
render = False
if cam_frame and self._current_rss_surface and self._current_rss_surface[0] == cam_frame:
render = True
if rss_frame and self.current_camera_surface and self.current_camera_surface[0] == rss_frame:
render = True
if render:
surface = self.current_camera_surface[1]
surface.blit(self._current_rss_surface[1], (0, 0))
rect = pygame.Rect((0, 0), (2, surface.get_height()))
pygame.draw.rect(surface, (0, 0, 0), rect, 0)
rect = pygame.Rect((0, 0), (surface.get_width(), 2))
pygame.draw.rect(surface, (0, 0, 0), rect, 0)
rect = pygame.Rect((0, surface.get_height() - 2), (surface.get_width(), surface.get_height()))
pygame.draw.rect(surface, (0, 0, 0), rect, 0)
rect = pygame.Rect((surface.get_width() - 2, 0), (surface.get_width(), surface.get_width()))
pygame.draw.rect(surface, (0, 0, 0), rect, 0)
self._surface = surface
def toggle_camera(self):
print("Toggle RssUnstructuredSceneVisualizer")
if self._mode == RssUnstructuredSceneVisualizerMode.window:
self.restart(RssUnstructuredSceneVisualizerMode.fullscreen)
elif self._mode == RssUnstructuredSceneVisualizerMode.fullscreen:
self.restart(RssUnstructuredSceneVisualizerMode.disabled)
elif self._mode == RssUnstructuredSceneVisualizerMode.disabled:
self.restart(RssUnstructuredSceneVisualizerMode.window)
@staticmethod
def _parse_image(weak_self, image):
self = weak_self()
if not self:
return
image.convert(carla.ColorConverter.Raw)
array = np.frombuffer(image.raw_data, dtype=np.dtype("uint8"))
array = np.reshape(array, (image.height, image.width, 4))
array = array[:, :, :3]
array = array[:, :, ::-1]
surface = pygame.surfarray.make_surface(array.swapaxes(0, 1))
self.current_camera_surface = (image.frame, surface)
self.update_surface(image.frame, None)
@staticmethod
def rotate_around_point(xy, radians, origin):
"""Rotate a point around a given point.
"""
x, y = xy
offset_x, offset_y = origin
adjusted_x = (x - offset_x)
adjusted_y = (y - offset_y)
cos_rad = math.cos(radians)
sin_rad = math.sin(radians)
qx = offset_x + cos_rad * adjusted_x - sin_rad * adjusted_y
qy = offset_y + sin_rad * adjusted_x + cos_rad * adjusted_y
return qx, qy
def tick(self, frame, rss_response, allowed_heading_ranges):
if not self._camera:
return
surface = pygame.Surface(self._dim)
surface.set_colorkey(pygame.Color('black'))
surface.set_alpha(180)
try:
lines = RssUnstructuredSceneVisualizer.get_trajectory_sets(
rss_response.rss_state_snapshot, self._camera.get_transform(), self._calibration)
polygons = []
for heading_range in allowed_heading_ranges:
polygons.append((RssUnstructuredSceneVisualizer.transform_points(
RssUnstructuredSceneVisualizer._get_points_from_pairs(
RssUnstructuredSceneVisualizer.draw_heading_range(
heading_range, rss_response.ego_dynamics_on_route)),
self._camera.get_transform(), self._calibration), (0, 0, 255)))
RssUnstructuredSceneVisualizer.draw_lines(surface, lines)
RssUnstructuredSceneVisualizer.draw_polygons(surface, polygons)
except RuntimeError as e:
print("ERROR {}".format(e))
self._current_rss_surface = (frame, surface)
self.update_surface(None, frame)
def render(self, display):
if self._surface:
display.blit(self._surface, (display.get_width() - self._dim[0], 0))
@staticmethod
def draw_heading_range(heading_range, ego_dynamics_on_route):
line = [(float(ego_dynamics_on_route.ego_center.x), float(ego_dynamics_on_route.ego_center.y))]
length = 3.0
current_angle = float(heading_range.begin)
max_angle = float(heading_range.end)
if heading_range.end < heading_range.begin:
max_angle += 2.0 * np.pi
while current_angle < max_angle:
line.append((float(ego_dynamics_on_route.ego_center.x) + length * np.cos(current_angle),
float(ego_dynamics_on_route.ego_center.y) + length * np.sin(current_angle)))
current_angle += 0.2
if current_angle != max_angle:
line.append((float(ego_dynamics_on_route.ego_center.x) + length * np.cos(max_angle),
float(ego_dynamics_on_route.ego_center.y) + length * np.sin(max_angle)))
line.append((float(ego_dynamics_on_route.ego_center.x), float(ego_dynamics_on_route.ego_center.y)))
return line
@staticmethod
def get_trajectory_sets(rss_state_snapshot, camera_transform, calibration):
"""
Creates 3D bounding boxes based on carla vehicle list and camera.
"""
trajectory_sets = []
# ego
trajectory_sets.append((RssUnstructuredSceneVisualizer.transform_points(RssUnstructuredSceneVisualizer._get_trajectory_set_points(
rss_state_snapshot.unstructuredSceneEgoInformation.brakeTrajectorySet), camera_transform, calibration), (255, 0, 0)))
trajectory_sets.append((RssUnstructuredSceneVisualizer.transform_points(RssUnstructuredSceneVisualizer._get_trajectory_set_points(
rss_state_snapshot.unstructuredSceneEgoInformation.continueForwardTrajectorySet), camera_transform, calibration), (0, 255, 0)))
# others
for state in rss_state_snapshot.individualResponses:
if state.unstructuredSceneState.rssStateInformation.brakeTrajectorySet:
trajectory_sets.append((RssUnstructuredSceneVisualizer.transform_points(RssUnstructuredSceneVisualizer._get_trajectory_set_points(
state.unstructuredSceneState.rssStateInformation.brakeTrajectorySet), camera_transform, calibration), (255, 0, 0)))
if state.unstructuredSceneState.rssStateInformation.continueForwardTrajectorySet:
trajectory_sets.append((RssUnstructuredSceneVisualizer.transform_points(RssUnstructuredSceneVisualizer._get_trajectory_set_points(
state.unstructuredSceneState.rssStateInformation.continueForwardTrajectorySet), camera_transform, calibration), (0, 255, 0)))
return trajectory_sets
@staticmethod
def draw_lines(surface, lines):
"""
Draws lines on pygame display.
"""
for line, color in lines:
if len(line) > 1:
pygame.draw.lines(surface, color, True, line, 2)
@staticmethod
def draw_polygons(surface, polygons):
"""
Draws polygons on pygame display.
"""
for polygon, color in polygons:
if len(polygon) > 1:
pygame.draw.polygon(surface, color, polygon)
@staticmethod
def transform_points(world_cords, camera_transform, calibration):
"""
Returns trajectory set projected to camera view
"""
world_cords = np.transpose(world_cords)
cords_x_y_z = RssUnstructuredSceneVisualizer._world_to_sensor(world_cords, camera_transform)[:3, :]
cords_y_minus_z_x = np.concatenate([cords_x_y_z[1, :], -cords_x_y_z[2, :], cords_x_y_z[0, :]])
ts = np.transpose(np.dot(calibration, cords_y_minus_z_x))
camera_ts = np.concatenate([ts[:, 0] / ts[:, 2], ts[:, 1] / ts[:, 2], ts[:, 2]], axis=1)
line_to_draw = []
for point in camera_ts:
line_to_draw.append((int(point[0, 0]), int(point[0, 1])))
return line_to_draw
@staticmethod
def _get_trajectory_set_points(trajectory_set):
"""
"""
cords = np.zeros((len(trajectory_set), 4))
i = 0
for pt in trajectory_set:
cords[i, :] = np.array([pt.x, -pt.y, 0, 1])
i += 1
return cords
@staticmethod
def _get_points_from_pairs(trajectory_set):
"""
"""
cords = np.zeros((len(trajectory_set), 4))
i = 0
for pt in trajectory_set:
cords[i, :] = np.array([pt[0], -pt[1], 0, 1])
i += 1
return cords
@staticmethod
def _world_to_sensor(cords, camera_transform):
"""
Transforms world coordinates to sensor.
"""
sensor_world_matrix = get_matrix(camera_transform)
world_sensor_matrix = np.linalg.inv(sensor_world_matrix)
sensor_cords = np.dot(world_sensor_matrix, cords)
return sensor_cords
# ==============================================================================
# -- RssBoundingBoxVisualizer ------------------------------------------------------
# ==============================================================================
class RssBoundingBoxVisualizer(object):
def __init__(self, display_dimensions, world, camera):
self._last_camera_frame = 0
self._surface_for_frame = []
self._world = world
self._dim = display_dimensions
self._calibration = np.identity(3)
self._calibration[0, 2] = self._dim[0] / 2.0
self._calibration[1, 2] = self._dim[1] / 2.0
self._calibration[0, 0] = self._calibration[1, 1] = self._dim[0] / \
(2.0 * np.tan(90.0 * np.pi / 360.0)) # fov default: 90.0
self._camera = camera
def tick(self, frame, individual_rss_states):
if len(self._surface_for_frame) > 0:
try:
while self._surface_for_frame[0][0] < self._last_camera_frame:
self._surface_for_frame.pop(0)
except IndexError:
return
# only render on new frame
if len(self._surface_for_frame) > 0:
if self._surface_for_frame[0][0] == frame:
return
surface = pygame.Surface(self._dim)
surface.set_colorkey(pygame.Color('black'))
surface.set_alpha(80)
try:
bounding_boxes = RssBoundingBoxVisualizer.get_bounding_boxes(
individual_rss_states, self._camera.get_transform(), self._calibration, self._world)
RssBoundingBoxVisualizer.draw_bounding_boxes(surface, bounding_boxes)
self._surface_for_frame.append((frame, surface, len(bounding_boxes)))
except RuntimeError:
pass
def render(self, display, current_camera_frame):
rendered = False
boxes_to_render = 0
for frame, surface, box_count in self._surface_for_frame:
if frame == current_camera_frame:
display.blit(surface, (0, 0))
boxes_to_render = box_count
rendered = True
break
if not rendered and boxes_to_render > 0:
print("Warning: {} bounding boxes were not drawn.".format(boxes_to_render))
self._last_camera_frame = current_camera_frame
@staticmethod
def get_bounding_boxes(individual_rss_states, camera_transform, calibration, world):
"""
Creates 3D bounding boxes based on carla vehicle list and camera.
"""
bounding_boxes = []
for state in individual_rss_states:
if state.actor_calculation_mode != ad.rss.map.RssMode.NotRelevant and state.is_dangerous:
other_actor = state.get_actor(world)
if other_actor:
bounding_boxes.append(RssBoundingBoxVisualizer.get_bounding_box(
other_actor, camera_transform, calibration))
# filter objects behind camera
bounding_boxes = [bb for bb in bounding_boxes if all(bb[:, 2] > 0)]
return bounding_boxes
@staticmethod
def draw_bounding_boxes(surface, bounding_boxes, color=pygame.Color('red')):
"""
Draws bounding boxes on pygame display.
"""
for bbox in bounding_boxes:
points = [(int(bbox[i, 0]), int(bbox[i, 1])) for i in range(8)]
# draw lines
# base
polygon = [points[0], points[1], points[2], points[3]]
pygame.draw.polygon(surface, color, polygon)
# top
polygon = [points[4], points[5], points[6], points[7]]
pygame.draw.polygon(surface, color, polygon)
# base-top
polygon = [points[0], points[1], points[5], points[4]]
pygame.draw.polygon(surface, color, polygon)
polygon = [points[1], points[2], points[6], points[5]]
pygame.draw.polygon(surface, color, polygon)
polygon = [points[2], points[6], points[7], points[3]]
pygame.draw.polygon(surface, color, polygon)
polygon = [points[0], points[4], points[7], points[3]]
pygame.draw.polygon(surface, color, polygon)
@staticmethod
def get_bounding_box(vehicle, camera_transform, calibration):
"""
Returns 3D bounding box for a vehicle based on camera view.
"""
bb_cords = RssBoundingBoxVisualizer._create_bb_points(vehicle)
cords_x_y_z = RssBoundingBoxVisualizer._vehicle_to_sensor(bb_cords, vehicle, camera_transform)[:3, :]
cords_y_minus_z_x = np.concatenate([cords_x_y_z[1, :], -cords_x_y_z[2, :], cords_x_y_z[0, :]])
bbox = np.transpose(np.dot(calibration, cords_y_minus_z_x))
camera_bbox = np.concatenate([bbox[:, 0] / bbox[:, 2], bbox[:, 1] / bbox[:, 2], bbox[:, 2]], axis=1)
return camera_bbox
@staticmethod
def _create_bb_points(vehicle):
"""
Returns 3D bounding box for a vehicle.
"""
cords = np.zeros((8, 4))
extent = vehicle.bounding_box.extent
cords[0, :] = np.array([extent.x, extent.y, -extent.z, 1])
cords[1, :] = np.array([-extent.x, extent.y, -extent.z, 1])
cords[2, :] = np.array([-extent.x, -extent.y, -extent.z, 1])
cords[3, :] = np.array([extent.x, -extent.y, -extent.z, 1])
cords[4, :] = np.array([extent.x, extent.y, extent.z, 1])
cords[5, :] = np.array([-extent.x, extent.y, extent.z, 1])
cords[6, :] = np.array([-extent.x, -extent.y, extent.z, 1])
cords[7, :] = np.array([extent.x, -extent.y, extent.z, 1])
return cords
@staticmethod
def _vehicle_to_sensor(cords, vehicle, camera_transform):
"""
Transforms coordinates of a vehicle bounding box to sensor.
"""
world_cord = RssBoundingBoxVisualizer._vehicle_to_world(cords, vehicle)
sensor_cord = RssBoundingBoxVisualizer._world_to_sensor(world_cord, camera_transform)
return sensor_cord
@staticmethod
def _vehicle_to_world(cords, vehicle):
"""
Transforms coordinates of a vehicle bounding box to world.
"""
bb_transform = carla.Transform(vehicle.bounding_box.location)
bb_vehicle_matrix = get_matrix(bb_transform)
vehicle_world_matrix = get_matrix(vehicle.get_transform())
bb_world_matrix = np.dot(vehicle_world_matrix, bb_vehicle_matrix)
world_cords = np.dot(bb_world_matrix, np.transpose(cords))
return world_cords
@staticmethod
def _world_to_sensor(cords, camera_transform):
"""
Transforms world coordinates to sensor.
"""
sensor_world_matrix = get_matrix(camera_transform)
world_sensor_matrix = np.linalg.inv(sensor_world_matrix)
sensor_cords = np.dot(world_sensor_matrix, cords)
return sensor_cords
# ==============================================================================
# -- RssDebugVisualizer ------------------------------------------------------------
# ==============================================================================
class RssDebugVisualizationMode(Enum):
Off = 1
RouteOnly = 2
VehicleStateOnly = 3
VehicleStateAndRoute = 4
All = 5
class RssDebugVisualizer(object):
def __init__(self, player, world):
self._world = world
self._player = player
self._visualization_mode = RssDebugVisualizationMode.Off
def toggleMode(self):
if self._visualization_mode == RssDebugVisualizationMode.All:
self._visualization_mode = RssDebugVisualizationMode.Off
elif self._visualization_mode == RssDebugVisualizationMode.Off:
self._visualization_mode = RssDebugVisualizationMode.RouteOnly
elif self._visualization_mode == RssDebugVisualizationMode.RouteOnly:
self._visualization_mode = RssDebugVisualizationMode.VehicleStateOnly
elif self._visualization_mode == RssDebugVisualizationMode.VehicleStateOnly:
self._visualization_mode = RssDebugVisualizationMode.VehicleStateAndRoute
elif self._visualization_mode == RssDebugVisualizationMode.VehicleStateAndRoute:
self._visualization_mode = RssDebugVisualizationMode.All
print("New Debug Visualizer Mode {}".format(self._visualization_mode))
def tick(self, route, dangerous, individual_rss_states, ego_dynamics_on_route):
if self._visualization_mode == RssDebugVisualizationMode.RouteOnly or \
self._visualization_mode == RssDebugVisualizationMode.VehicleStateAndRoute or \
self._visualization_mode == RssDebugVisualizationMode.All:
self.visualize_route(dangerous, route)
if self._visualization_mode == RssDebugVisualizationMode.VehicleStateOnly or \
self._visualization_mode == RssDebugVisualizationMode.VehicleStateAndRoute or \
self._visualization_mode == RssDebugVisualizationMode.All:
self.visualize_rss_results(individual_rss_states)
if self._visualization_mode == RssDebugVisualizationMode.All:
self.visualize_ego_dynamics(ego_dynamics_on_route)
def visualize_route(self, dangerous, route):
if not route:
return
right_lane_edges = dict()
left_lane_edges = dict()
for road_segment in route.roadSegments:
right_most_lane = road_segment.drivableLaneSegments[0]
if right_most_lane.laneInterval.laneId not in right_lane_edges:
edge = ad.map.route.getRightProjectedENUEdge(right_most_lane.laneInterval)
right_lane_edges[right_most_lane.laneInterval.laneId] = edge
intersection_lane = ad.map.intersection.Intersection.isLanePartOfAnIntersection(right_most_lane.laneInterval.laneId)
color = carla.Color(r=(128 if dangerous else 255))
if intersection_lane:
color.b = 128 if dangerous else 255
color = carla.Color(r=255, g=0, b=255)
self.visualize_enu_edge(edge, color, self._player.get_location().z)
left_most_lane = road_segment.drivableLaneSegments[-1]
if left_most_lane.laneInterval.laneId not in left_lane_edges:
edge = ad.map.route.getLeftProjectedENUEdge(left_most_lane.laneInterval)
left_lane_edges[left_most_lane.laneInterval.laneId] = edge
intersection_lane = ad.map.intersection.Intersection.isLanePartOfAnIntersection(left_most_lane.laneInterval.laneId)
color = carla.Color(g=(128 if dangerous else 255))
if intersection_lane:
color.b = 128 if dangerous else 255
self.visualize_enu_edge(edge, color, self._player.get_location().z)
def visualize_enu_edge(self, edge, color, z_offset):
for point in edge:
carla_point = carla.Location(x=float(point.x), y=-1. * float(point.y), z=float(point.z) + z_offset)
self._world.debug.draw_point(carla_point, 0.1, color, 0.1, False)
def visualize_rss_results(self, state_snapshot):
for state in state_snapshot:
other_actor = state.get_actor(self._world)
if not other_actor:
# print("Actor not found. Skip visualizing state {}".format(state))
continue
ego_point = self._player.get_location()
ego_point.z += 0.05
yaw = self._player.get_transform().rotation.yaw
cosine = math.cos(math.radians(yaw))
sine = math.sin(math.radians(yaw))
line_offset = carla.Location(-sine * 0.1, cosine * 0.1, 0.0)
point = other_actor.get_location()
point.z += 0.05
indicator_color = carla.Color(0, 255, 0)
dangerous = ad.rss.state.isDangerous(state.rss_state)
if dangerous:
indicator_color = carla.Color(255, 0, 0)
elif state.rss_state.situationType == ad.rss.situation.SituationType.NotRelevant:
indicator_color = carla.Color(150, 150, 150)
if self._visualization_mode == RssDebugVisualizationMode.All:
# the connection lines are only visualized if All is requested
lon_color = indicator_color
lat_l_color = indicator_color
lat_r_color = indicator_color
if not state.rss_state.longitudinalState.isSafe:
lon_color.r = 255
lon_color.g = 0 if dangerous else 255
if not state.rss_state.lateralStateLeft.isSafe:
lat_l_color.r = 255
lat_l_color.g = 0 if dangerous else 255
if not state.rss_state.lateralStateRight.isSafe:
lat_r_color.r = 255
lat_r_color.g = 0 if dangerous else 255
self._world.debug.draw_line(ego_point, point, 0.1, lon_color, 0.02, False)
self._world.debug.draw_line(ego_point - line_offset, point -
line_offset, 0.1, lat_l_color, 0.02, False)
self._world.debug.draw_line(ego_point + line_offset, point +
line_offset, 0.1, lat_r_color, 0.02, False)
point.z += 3.
self._world.debug.draw_point(point, 0.2, indicator_color, 0.02, False)
def visualize_ego_dynamics(self, ego_dynamics_on_route):
color = carla.Color(0, 0, 255)
sin_heading = math.sin(float(ego_dynamics_on_route.route_heading))
cos_heading = math.cos(float(ego_dynamics_on_route.route_heading))
heading_location_start = self._player.get_location()
heading_location_start.x -= cos_heading * 10.
heading_location_start.y += sin_heading * 10.
heading_location_start.z += 0.5
heading_location_end = self._player.get_location()
heading_location_end.x += cos_heading * 10.
heading_location_end.y -= sin_heading * 10.
heading_location_end.z += 0.5
self._world.debug.draw_arrow(heading_location_start, heading_location_end, 0.1, 0.1, color, 0.02, False)
sin_center = math.sin(float(ego_dynamics_on_route.route_heading) + math.pi / 2.)
cos_center = math.cos(float(ego_dynamics_on_route.route_heading) + math.pi / 2.)
center_location_start = self._player.get_location()
center_location_start.x -= cos_center * 2.
center_location_start.y += sin_center * 2.
center_location_start.z += 0.5
center_location_end = self._player.get_location()
center_location_end.x += cos_center * 2.
center_location_end.y -= sin_center * 2.
center_location_end.z += 0.5
self._world.debug.draw_line(center_location_start, center_location_end, 0.1, color, 0.02, False)

View File

@ -1,187 +0,0 @@
<?xml version="1.0"?>
<OpenSCENARIO>
<FileHeader revMajor="1" revMinor="0" date="2019-06-25T00:00:00" description="CARLA:FollowLeadingVehicle" author=""/>
<ParameterDeclarations>
<ParameterDeclaration name="$leadingSpeed" parameterType="double" value="2.0"/>
</ParameterDeclarations>
<CatalogLocations>
</CatalogLocations>
<RoadNetwork>
<LogicFile filepath="Town01"/>
<SceneGraphFile filepath=""/>
</RoadNetwork>
<Entities>
<ScenarioObject name="hero">
<Vehicle name="vehicle.lincoln.mkz_2017" vehicleCategory="car">
<ParameterDeclarations/>
<Performance maxSpeed="69.444" maxAcceleration="10.0" maxDeceleration="10.0"/>
<BoundingBox>
<Center x="1.5" y="0.0" z="0.9"/>
<Dimensions width="2.1" length="4.5" height="1.8"/>
</BoundingBox>
<Axles>
<FrontAxle maxSteering="0.5" wheelDiameter="0.6" trackWidth="1.8" positionX="3.1" positionZ="0.3"/>
<RearAxle maxSteering="0.0" wheelDiameter="0.6" trackWidth="1.8" positionX="0.0" positionZ="0.3"/>
</Axles>
<Properties>
<Property name="type" value="ego_vehicle"/>
<Property name="color" value="0,0,255"/>
</Properties>
</Vehicle>
</ScenarioObject>
<ScenarioObject name="blockingVehicle">
<Vehicle name="vehicle.lincoln.mkz_2017" vehicleCategory="car">
<ParameterDeclarations/>
<Performance maxSpeed="69.444" maxAcceleration="10.0" maxDeceleration="10.0"/>
<BoundingBox>
<Center x="1.5" y="0.0" z="0.9"/>
<Dimensions width="2.1" length="4.5" height="1.8"/>
</BoundingBox>
<Axles>
<FrontAxle maxSteering="0.5" wheelDiameter="0.6" trackWidth="1.8" positionX="3.1" positionZ="0.3"/>
<RearAxle maxSteering="0.0" wheelDiameter="0.6" trackWidth="1.8" positionX="0.0" positionZ="0.3"/>
</Axles>
<Properties>
<Property name="type" value="simulation"/>
<Property name="color" value="255,0,0"/>
</Properties>
</Vehicle>
</ScenarioObject>
</Entities>
<Storyboard>
<Init>
<Actions>
<GlobalAction>
<EnvironmentAction>
<Environment name="Environment1">
<TimeOfDay animation="false" dateTime="2019-06-25T12:00:00"/>
<Weather cloudState="free">
<Sun intensity="1.0" azimuth="0.0" elevation="1.31"/>
<Fog visualRange="100000.0"/>
<Precipitation precipitationType="dry" intensity="0.0"/>
</Weather>
<RoadCondition frictionScaleFactor="1.0"/>
</Environment>
</EnvironmentAction>
</GlobalAction>
<Private entityRef="hero">
<PrivateAction>
<TeleportAction>
<Position>
<WorldPosition x="150" y="133" z="0" h="0"/>
</Position>
</TeleportAction>
</PrivateAction>
<PrivateAction>
<ControllerAction>
<AssignControllerAction>
<Controller name="EgoVehicleAgent">
<Properties>
<Property name="module" value="external_control" />
</Properties>
</Controller>
</AssignControllerAction>
<OverrideControllerValueAction>
<Throttle value="0" active="false" />
<Brake value="0" active="false" />
<Clutch value="0" active="false" />
<ParkingBrake value="0" active="false" />
<SteeringWheel value="0" active="false" />
<Gear number="0" active="false" />
</OverrideControllerValueAction>
</ControllerAction>
</PrivateAction>
</Private>
<Private entityRef="blockingVehicle">
<PrivateAction>
<TeleportAction>
<Position>
<WorldPosition x="165" y="133" z="0" h="2.8"/>
</Position>
</TeleportAction>
</PrivateAction>
</Private>
</Actions>
</Init>
<Story name="MyStory">
<Act name="Behavior">
<ManeuverGroup maximumExecutionCount="1" name="ManeuverSequence">
<Actors selectTriggeringEntities="false">
<EntityRef entityRef="hero"/>
</Actors>
<Maneuver name="EmptyManeuver">
<Event name="EmptyEvent" priority="overwrite">
<!-- never triggered -->
<Action name="EmptyAcion">
</Action>
<StartTrigger>
</StartTrigger>
</Event>
</Maneuver>
</ManeuverGroup>
<StartTrigger>
<ConditionGroup>
<Condition name="StartTime" delay="0" conditionEdge="rising">
<ByValueCondition>
<SimulationTimeCondition value="0" rule="equalTo"/>
</ByValueCondition>
</Condition>
</ConditionGroup>
</StartTrigger>
<StopTrigger>
<ConditionGroup>
<Condition name="EndCondition" delay="0" conditionEdge="rising">
<ByEntityCondition>
<TriggeringEntities triggeringEntitiesRule="any">
<EntityRef entityRef="hero"/>
</TriggeringEntities>
<EntityCondition>
<TraveledDistanceCondition value="100.0"/>
</EntityCondition>
</ByEntityCondition>
</Condition>
</ConditionGroup>
</StopTrigger>
</Act>
</Story>
<StopTrigger>
<ConditionGroup>
<Condition name="criteria_RunningStopTest" delay="0" conditionEdge="rising">
<ByValueCondition>
<ParameterCondition parameterRef="" value="" rule="lessThan"/>
</ByValueCondition>
</Condition>
<Condition name="criteria_RunningRedLightTest" delay="0" conditionEdge="rising">
<ByValueCondition>
<ParameterCondition parameterRef="" value="" rule="lessThan"/>
</ByValueCondition>
</Condition>
<Condition name="criteria_WrongLaneTest" delay="0" conditionEdge="rising">
<ByValueCondition>
<ParameterCondition parameterRef="" value="" rule="lessThan"/>
</ByValueCondition>
</Condition>
<Condition name="criteria_OnSidewalkTest" delay="0" conditionEdge="rising">
<ByValueCondition>
<ParameterCondition parameterRef="" value="" rule="lessThan"/>
</ByValueCondition>
</Condition>
<Condition name="criteria_KeepLaneTest" delay="0" conditionEdge="rising">
<ByValueCondition>
<ParameterCondition parameterRef="" value="" rule="lessThan"/>
</ByValueCondition>
</Condition>
<Condition name="criteria_CollisionTest" delay="0" conditionEdge="rising">
<ByValueCondition>
<ParameterCondition parameterRef="" value="" rule="lessThan"/>
</ByValueCondition>
</Condition>
<Condition name="criteria_DrivenDistanceTest" delay="0" conditionEdge="rising">
<ByValueCondition>
<ParameterCondition parameterRef="distance_success" value="100" rule="lessThan"/>
</ByValueCondition>
</Condition>
</ConditionGroup>
</StopTrigger>
</Storyboard>
</OpenSCENARIO>

View File

@ -1,223 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<OpenSCENARIO>
<FileHeader revMajor="1" revMinor="0" date="2020-03-20T00:00:00" description="CARLA:AgentExample" author="" />
<ParameterDeclarations/>
<CatalogLocations/>
<RoadNetwork>
<LogicFile filepath="Town01" />
<SceneGraphFile filepath="" />
</RoadNetwork>
<Entities>
<ScenarioObject name="hero">
<Vehicle name="vehicle.lincoln.mkz_2017" vehicleCategory="car">
<ParameterDeclarations/>
<Performance maxSpeed="69.444" maxAcceleration="200" maxDeceleration="10.0"/>
<BoundingBox>
<Center x="1.5" y="0.0" z="0.9" />
<Dimensions width="2.1" length="4.5" height="1.8"/>
</BoundingBox>
<Axles>
<FrontAxle maxSteering="0.5" wheelDiameter="0.6" trackWidth="1.8" positionX="3.1" positionZ="0.3" />
<RearAxle maxSteering="0.0" wheelDiameter="0.6" trackWidth="1.8" positionX="0.0" positionZ="0.3" />
</Axles>
<Properties>
<Property name="type" value="ego_vehicle" />
<Property name="color" value="0,0,255" />
</Properties>
</Vehicle>
</ScenarioObject>
<ScenarioObject name="pedestrian1">
<Pedestrian mass="100" model="walker.pedestrian.0001" name="Pedestrian1" pedestrianCategory="pedestrian">
<ParameterDeclarations/>
<BoundingBox>
<Center x="0.5" y="0.5" z="0.9"/>
<Dimensions width="1.0" length="1.0" height="1.8"/>
</BoundingBox>
<Properties>
<Property name="type" value="simulation"/>
</Properties>
</Pedestrian>
</ScenarioObject>
</Entities>
<Storyboard>
<Init>
<Actions>
<GlobalAction>
<EnvironmentAction>
<Environment name="Environment1">
<TimeOfDay animation="false" dateTime="2020-03-20T12:00:00"/>
<Weather cloudState="free">
<Sun intensity="0.85" azimuth="0" elevation="1.31" />
<Fog visualRange="100000.0" />
<Precipitation precipitationType="dry" intensity="0.0" />
</Weather>
<RoadCondition frictionScaleFactor="1.0" />
</Environment>
</EnvironmentAction>
</GlobalAction>
<Private entityRef="hero">
<PrivateAction>
<TeleportAction>
<Position>
<WorldPosition x="338.9" y="319.5" z="1" h="4.71" />
</Position>
</TeleportAction>
</PrivateAction>
<PrivateAction>
<ControllerAction>
<AssignControllerAction>
<Controller name="EgoVehicleAgent">
<Properties>
<Property name="module" value="external_control"/>
</Properties>
</Controller>
</AssignControllerAction>
<OverrideControllerValueAction>
<Throttle value="0" active="false" />
<Brake value="0" active="false" />
<Clutch value="0" active="false" />
<ParkingBrake value="0" active="false" />
<SteeringWheel value="0" active="false" />
<Gear number="0" active="false" />
</OverrideControllerValueAction>
</ControllerAction>
</PrivateAction>
<PrivateAction>
<LongitudinalAction>
<SpeedAction>
<SpeedActionDynamics dynamicsShape="step" value="20" dynamicsDimension="distance"/>
<SpeedActionTarget>
<AbsoluteTargetSpeed value="10" />
</SpeedActionTarget>
</SpeedAction>
</LongitudinalAction>
</PrivateAction>
</Private>
<Private entityRef="pedestrian1">
<PrivateAction>
<TeleportAction>
<Position>
<WorldPosition x="339.5" y="300" z="1" h="4.71" />
</Position>
</TeleportAction>
</PrivateAction>
</Private>
</Actions>
</Init>
<Story name="MyStory">
<Act name="Behavior">
<ManeuverGroup name="Pedestrian1ManeuverSequence" maximumExecutionCount="1">
<Actors selectTriggeringEntities="false">
<EntityRef entityRef="pedestrian1" />
</Actors>
<Maneuver name="Pedestrian1RouteManeuver">
<!--
1. walk 20m when the ego-vehicle starts moving
1. pause for some seconds
3. walk another 20m
-->
<Event name="Pedestrian1WalksEvent" priority="overwrite">
<Action name="Pedestrian1Walks">
<PrivateAction>
<LongitudinalAction>
<SpeedAction>
<SpeedActionDynamics dynamicsShape="step" value="20" dynamicsDimension="distance"/>
<SpeedActionTarget>
<AbsoluteTargetSpeed value="2" />
</SpeedActionTarget>
</SpeedAction>
</LongitudinalAction>
</PrivateAction>
</Action>
<StartTrigger>
<ConditionGroup>
<Condition name="Pedestrian1WalksCondition" delay="0" conditionEdge="rising">
<ByEntityCondition>
<TriggeringEntities triggeringEntitiesRule="any">
<EntityRef entityRef="hero" />
</TriggeringEntities>
<EntityCondition>
<TraveledDistanceCondition value="1.0" />
</EntityCondition>
</ByEntityCondition>
</Condition>
</ConditionGroup>
</StartTrigger>
</Event>
<Event name="Pedestrian1WaitsEvent" priority="overwrite">
<Action name="Pedestrian1Waits">
<PrivateAction>
<LongitudinalAction>
<SpeedAction>
<SpeedActionDynamics dynamicsShape="step" value="10" dynamicsDimension="time"/>
<SpeedActionTarget>
<AbsoluteTargetSpeed value="0.0"/>
</SpeedActionTarget>
</SpeedAction>
</LongitudinalAction>
</PrivateAction>
</Action>
<StartTrigger>
<ConditionGroup>
<Condition name="AfterPedestrian1Walks" delay="0" conditionEdge="rising">
<ByValueCondition>
<StoryboardElementStateCondition storyboardElementType="action" storyboardElementRef="Pedestrian1Walks" state="endTransition"/>
</ByValueCondition>
</Condition>
</ConditionGroup>
</StartTrigger>
</Event>
<Event name="Pedestrian1ContinuesWalkingEvent" priority="overwrite">
<!-- contine walking 20m -->
<Action name="Pedestrian1ContinuesWalking">
<PrivateAction>
<LongitudinalAction>
<SpeedAction>
<SpeedActionDynamics dynamicsShape="step" value="20" dynamicsDimension="distance"/>
<SpeedActionTarget>
<AbsoluteTargetSpeed value="2" />
</SpeedActionTarget>
</SpeedAction>
</LongitudinalAction>
</PrivateAction>
</Action>
<StartTrigger>
<ConditionGroup>
<Condition name="AfterPedestrian1Waits" delay="0" conditionEdge="rising">
<ByValueCondition>
<StoryboardElementStateCondition storyboardElementType="action" storyboardElementRef="Pedestrian1Waits" state="endTransition"/>
</ByValueCondition>
</Condition>
</ConditionGroup>
</StartTrigger>
</Event>
</Maneuver>
</ManeuverGroup>
<StartTrigger>
<ConditionGroup>
<Condition name="StartTime" delay="0" conditionEdge="rising">
<ByValueCondition>
<SimulationTimeCondition value="0" rule="equalTo" />
</ByValueCondition>
</Condition>
</ConditionGroup>
</StartTrigger>
<StopTrigger>
<ConditionGroup>
<Condition name="EndCondition" delay="0" conditionEdge="rising">
<ByEntityCondition>
<TriggeringEntities triggeringEntitiesRule="any">
<EntityRef entityRef="hero" />
</TriggeringEntities>
<EntityCondition>
<TraveledDistanceCondition value="40.0" />
</EntityCondition>
</ByEntityCondition>
</Condition>
</ConditionGroup>
</StopTrigger>
</Act>
</Story>
<StopTrigger/>
</Storyboard>
</OpenSCENARIO>

View File

@ -1,78 +0,0 @@
#!/usr/bin/env python
# Copyright (c) 2024 Computer Vision Center (CVC) at the Universitat Autonoma de
# Barcelona (UAB).
#
# This work is licensed under the terms of the MIT license.
# For a copy, see <https://opensource.org/licenses/MIT>.
import glob
import os
import sys
try:
sys.path.append(glob.glob('../carla/dist/carla-*%d.%d-%s.egg' % (
sys.version_info.major,
sys.version_info.minor,
'win-amd64' if os.name == 'nt' else 'linux-x86_64'))[0])
except IndexError:
pass
import carla
import argparse
def main():
argparser = argparse.ArgumentParser(
description=__doc__)
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(
'-f', '--recorder_filename',
metavar='F',
default="test1.rec",
help='recorder filename (test1.rec)')
argparser.add_argument(
'-t', '--time',
metavar='T',
default="30",
type=float,
help='minimum time to consider it is blocked')
argparser.add_argument(
'-d', '--distance',
metavar='D',
default="100",
type=float,
help='minimum distance to consider it is not moving (in cm)')
args = argparser.parse_args()
try:
client = carla.Client(args.host, args.port)
client.set_timeout(60.0)
print(client.show_recorder_actors_blocked(args.recorder_filename, args.time, args.distance))
finally:
pass
if __name__ == '__main__':
try:
main()
except KeyboardInterrupt:
pass
finally:
print('\ndone.')

View File

@ -1,128 +0,0 @@
#!/usr/bin/env python
# Copyright (c) 2024 Computer Vision Center (CVC) at the Universitat Autonoma de
# Barcelona (UAB).
#
# This work is licensed under the terms of the MIT license.
# For a copy, see <https://opensource.org/licenses/MIT>.
import glob
import os
import sys
try:
sys.path.append(glob.glob('../carla/dist/carla-*%d.%d-%s.egg' % (
sys.version_info.major,
sys.version_info.minor,
'win-amd64' if os.name == 'nt' else 'linux-x86_64'))[0])
except IndexError:
pass
import carla
import random
import time
def main():
actor_list = []
# In this tutorial script, we are going to add a vehicle to the simulation
# and let it drive in autopilot. We will also create a camera attached to
# that vehicle, and save all the images generated by the camera to disk.
try:
# First of all, we need to create the client that will send the requests
# to the simulator. Here we'll assume the simulator is accepting
# requests in the localhost at port 2000.
client = carla.Client('localhost', 2000)
client.set_timeout(2.0)
# Once we have a client we can retrieve the world that is currently
# running.
world = client.get_world()
# The world contains the list blueprints that we can use for adding new
# actors into the simulation.
blueprint_library = world.get_blueprint_library()
# Now let's filter all the blueprints of type 'vehicle' and choose one
# at random.
bp = random.choice(blueprint_library.filter('vehicle'))
# A blueprint contains the list of attributes that define a vehicle's
# instance, we can read them and modify some of them. For instance,
# let's randomize its color.
if bp.has_attribute('color'):
color = random.choice(bp.get_attribute('color').recommended_values)
bp.set_attribute('color', color)
# Now we need to give an initial transform to the vehicle. We choose a
# random transform from the list of recommended spawn points of the map.
transform = random.choice(world.get_map().get_spawn_points())
# So let's tell the world to spawn the vehicle.
vehicle = world.spawn_actor(bp, transform)
# It is important to note that the actors we create won't be destroyed
# unless we call their "destroy" function. If we fail to call "destroy"
# they will stay in the simulation even after we quit the Python script.
# For that reason, we are storing all the actors we create so we can
# destroy them afterwards.
actor_list.append(vehicle)
print('created %s' % vehicle.type_id)
# Let's put the vehicle to drive around.
vehicle.set_autopilot(True)
# Let's add now a "depth" camera attached to the vehicle. Note that the
# transform we give here is now relative to the vehicle.
camera_bp = blueprint_library.find('sensor.camera.depth')
camera_transform = carla.Transform(carla.Location(x=1.5, z=2.4))
camera = world.spawn_actor(camera_bp, camera_transform, attach_to=vehicle)
actor_list.append(camera)
print('created %s' % camera.type_id)
# Now we register the function that will be called each time the sensor
# receives an image. In this example we are saving the image to disk
# converting the pixels to gray-scale.
cc = carla.ColorConverter.LogarithmicDepth
camera.listen(lambda image: image.save_to_disk('_out/%06d.png' % image.frame, cc))
# Oh wait, I don't like the location we gave to the vehicle, I'm going
# to move it a bit forward.
location = vehicle.get_location()
location.x += 40
vehicle.set_location(location)
print('moved vehicle to %s' % location)
# But the city now is probably quite empty, let's add a few more
# vehicles.
transform.location += carla.Location(x=40, y=-3.2)
transform.rotation.yaw = -180.0
for _ in range(0, 10):
transform.location.x += 8.0
bp = random.choice(blueprint_library.filter('vehicle'))
# This time we are using try_spawn_actor. If the spot is already
# occupied by another object, the function will return None.
npc = world.try_spawn_actor(bp, transform)
if npc is not None:
actor_list.append(npc)
npc.set_autopilot(True)
print('created %s' % npc.type_id)
time.sleep(5)
finally:
print('destroying actors')
camera.destroy()
client.apply_batch([carla.command.DestroyActor(x) for x in actor_list])
print('done.')
if __name__ == '__main__':
main()

View File

@ -1,127 +0,0 @@
#!/usr/bin/env python
# Copyright (c) 2024 Computer Vision Center (CVC) at the Universitat Autonoma de
# Barcelona (UAB).
#
# This work is licensed under the terms of the MIT license.
# For a copy, see <https://opensource.org/licenses/MIT>.
import glob
import os
import sys
try:
sys.path.append(glob.glob('../carla/dist/carla-*%d.%d-%s.egg' % (
sys.version_info.major,
sys.version_info.minor,
'win-amd64' if os.name == 'nt' else 'linux-x86_64'))[0])
except IndexError:
pass
import carla
import random
import time
def main():
actor_list = []
# In this tutorial script, we are going to add a vehicle to the simulation
# and let it drive in autopilot. We will also create a camera attached to
# that vehicle, and save all the images generated by the camera to disk.
# Additionally, we will save all of the gbuffer textures for each frame.
try:
# First of all, we need to create the client that will send the requests
# to the simulator. Here we'll assume the simulator is accepting
# requests in the localhost at port 2000.
client = carla.Client('127.0.0.1', 2000)
client.set_timeout(2.0)
# Once we have a client we can retrieve the world that is currently
# running.
world = client.get_world()
# The world contains the list blueprints that we can use for adding new
# actors into the simulation.
blueprint_library = world.get_blueprint_library()
# Now let's filter all the blueprints of type 'vehicle' and choose one
# at random.
bp = random.choice(blueprint_library.filter('vehicle'))
# A blueprint contains the list of attributes that define a vehicle's
# instance, we can read them and modify some of them. For instance,
# let's randomize its color.
if bp.has_attribute('color'):
color = random.choice(bp.get_attribute('color').recommended_values)
bp.set_attribute('color', color)
# Now we need to give an initial transform to the vehicle. We choose a
# random transform from the list of recommended spawn points of the map.
transform = world.get_map().get_spawn_points()[0]
# So let's tell the world to spawn the vehicle.
vehicle = world.spawn_actor(bp, transform)
# It is important to note that the actors we create won't be destroyed
# unless we call their "destroy" function. If we fail to call "destroy"
# they will stay in the simulation even after we quit the Python script.
# For that reason, we are storing all the actors we create so we can
# destroy them afterwards.
actor_list.append(vehicle)
print('created %s' % vehicle.type_id)
# Let's put the vehicle to drive around.
vehicle.set_autopilot(True)
# Let's add now a "rgb" camera attached to the vehicle. Note that the
# transform we give here is now relative to the vehicle.
camera_bp = blueprint_library.find('sensor.camera.rgb')
camera_bp.set_attribute('image_size_x', '1920')
camera_bp.set_attribute('image_size_y', '1080')
camera_transform = carla.Transform(carla.Location(x=1.5, z=2.4))
camera = world.spawn_actor(camera_bp, camera_transform, attach_to=vehicle)
actor_list.append(camera)
print('created %s' % camera.type_id)
# Register a callback for whenever a new frame is available. This step is
# currently required to correctly receive the gbuffer textures, as it is
# used to determine whether the sensor is active.
camera.listen(lambda image: image.save_to_disk('_out/FinalColor-%06d.png' % image.frame))
# Here we will register the callbacks for each gbuffer texture.
# The function "listen_to_gbuffer" behaves like the regular listen function,
# but you must first pass it the ID of the desired gbuffer texture.
camera.listen_to_gbuffer(carla.GBufferTextureID.SceneColor, lambda image: image.save_to_disk('_out/GBuffer-SceneColor-%06d.png' % image.frame))
camera.listen_to_gbuffer(carla.GBufferTextureID.SceneDepth, lambda image: image.save_to_disk('_out/GBuffer-SceneDepth-%06d.png' % image.frame))
camera.listen_to_gbuffer(carla.GBufferTextureID.SceneStencil, lambda image: image.save_to_disk('_out/GBuffer-SceneStencil-%06d.png' % image.frame))
camera.listen_to_gbuffer(carla.GBufferTextureID.GBufferA, lambda image: image.save_to_disk('_out/GBuffer-A-%06d.png' % image.frame))
camera.listen_to_gbuffer(carla.GBufferTextureID.GBufferB, lambda image: image.save_to_disk('_out/GBuffer-B-%06d.png' % image.frame))
camera.listen_to_gbuffer(carla.GBufferTextureID.GBufferC, lambda image: image.save_to_disk('_out/GBuffer-C-%06d.png' % image.frame))
camera.listen_to_gbuffer(carla.GBufferTextureID.GBufferD, lambda image: image.save_to_disk('_out/GBuffer-D-%06d.png' % image.frame))
# Note that some gbuffer textures may not be available for a particular scene.
# For example, the textures E and F are likely unavailable in this example,
# which will result in them being sent as black images.
camera.listen_to_gbuffer(carla.GBufferTextureID.GBufferE, lambda image: image.save_to_disk('_out/GBuffer-E-%06d.png' % image.frame))
camera.listen_to_gbuffer(carla.GBufferTextureID.GBufferF, lambda image: image.save_to_disk('_out/GBuffer-F-%06d.png' % image.frame))
camera.listen_to_gbuffer(carla.GBufferTextureID.Velocity, lambda image: image.save_to_disk('_out/GBuffer-Velocity-%06d.png' % image.frame))
camera.listen_to_gbuffer(carla.GBufferTextureID.SSAO, lambda image: image.save_to_disk('_out/GBuffer-SSAO-%06d.png' % image.frame))
camera.listen_to_gbuffer(carla.GBufferTextureID.CustomDepth, lambda image: image.save_to_disk('_out/GBuffer-CustomDepth-%06d.png' % image.frame))
camera.listen_to_gbuffer(carla.GBufferTextureID.CustomStencil, lambda image: image.save_to_disk('_out/GBuffer-CustomStencil-%06d.png' % image.frame))
time.sleep(10)
finally:
print('destroying actors')
camera.destroy()
client.apply_batch([carla.command.DestroyActor(x) for x in actor_list])
print('done.')
if __name__ == '__main__':
main()

View File

@ -85,7 +85,7 @@ def main(arg):
# Impulse/Force at the center of mass of the object # Impulse/Force at the center of mass of the object
impulse = 10 * car_mass impulse = 10 * car_mass
print("# Adding an Impulse of %f N s" % impulse) print("# Adding an Impulse of {:.1f} N s".format(impulse))
vehicle.add_impulse(carla.Vector3D(0, 0, impulse)) vehicle.add_impulse(carla.Vector3D(0, 0, impulse))
wait(world) wait(world)
@ -93,7 +93,7 @@ def main(arg):
vehicle.set_target_velocity(carla.Vector3D(0, 0, 0)) vehicle.set_target_velocity(carla.Vector3D(0, 0, 0))
wait(world) wait(world)
print("# Adding a Force of %f N" % (impulse / delta)) print("# Adding a Force of {:.1f} N".format(impulse / delta))
# The add_force method should not be use for instantaneous forces like this one, # The add_force method should not be use for instantaneous forces like this one,
# it is more useful for constant or variable forces acting in a finite amount of time. # it is more useful for constant or variable forces acting in a finite amount of time.
# In this script it is done with the proper scaling to show the equivalence # In this script it is done with the proper scaling to show the equivalence
@ -107,8 +107,6 @@ def main(arg):
vehicle.set_target_velocity(carla.Vector3D(0, 0, 0)) vehicle.set_target_velocity(carla.Vector3D(0, 0, 0))
wait(world) wait(world)
wait(world, 500)
finally: finally:
world.apply_settings(original_settings) world.apply_settings(original_settings)
@ -134,7 +132,7 @@ if __name__ == "__main__":
argparser.add_argument( argparser.add_argument(
'--filter', '--filter',
metavar='PATTERN', metavar='PATTERN',
default='model3', default='vehicle.*',
help='actor filter (default: "vehicle.*")') help='actor filter (default: "vehicle.*")')
args = argparser.parse_args() args = argparser.parse_args()

View File

@ -1,518 +0,0 @@
#!/usr/bin/env python
# Copyright (c) 2020 Computer Vision Center (CVC) at the Universitat Autonoma de
# Barcelona (UAB).
#
# This work is licensed under the terms of the MIT license.
# For a copy, see <https://opensource.org/licenses/MIT>.
"""
Test collisions example for CARLA
This script runs several scenarios involving collisions and check if they
are deterministic for different simulation parameters.
"""
import glob
import os
import sys
import argparse
import time
import filecmp
import shutil
import numpy as np
try:
sys.path.append(glob.glob('../carla/dist/carla-*%d.%d-%s.egg' % (
sys.version_info.major,
sys.version_info.minor,
'win-amd64' if os.name == 'nt' else 'linux-x86_64'))[0])
except IndexError:
pass
import carla
class Scenario():
def __init__(self, client, world, save_snapshots_mode=False):
self.world = world
self.client = client
self.actor_list = []
self.init_timestamp = []
self.active = False
self.prefix = ""
self.save_snapshots_mode = save_snapshots_mode
self.snapshots = []
def init_scene(self, prefix, settings = None, spectator_tr = None):
self.prefix = prefix
self.actor_list = []
self.active = True
self.snapshots = []
self.reload_world(settings, spectator_tr)
# Init timestamp
world_snapshot = self.world.get_snapshot()
self.init_timestamp = {'frame0' : world_snapshot.frame, 'time0' : world_snapshot.timestamp.elapsed_seconds}
def add_actor(self, actor, actor_name="Actor"):
actor_idx = len(self.actor_list)
name = str(actor_idx) + "_" + actor_name
self.actor_list.append((name, actor))
if self.save_snapshots_mode:
self.snapshots.append(np.empty((0,11), float))
def wait(self, frames=100):
for _i in range(0, frames):
self.world.tick()
def clear_scene(self):
for actor in self.actor_list:
actor[1].destroy()
self.active = False
def reload_world(self, settings = None, spectator_tr = None):
self.client.reload_world()
if settings is not None:
self.world.apply_settings(settings)
if spectator_tr is not None:
self.reset_spectator(spectator_tr)
def reset_spectator(self, spectator_tr):
spectator = self.world.get_spectator()
spectator.set_transform(spectator_tr)
def save_snapshot(self, actor):
snapshot = self.world.get_snapshot()
actor_snapshot = np.array([
float(snapshot.frame - self.init_timestamp['frame0']), \
snapshot.timestamp.elapsed_seconds - self.init_timestamp['time0'], \
actor.get_location().x, actor.get_location().y, actor.get_location().z, \
actor.get_velocity().x, actor.get_velocity().y, actor.get_velocity().z, \
actor.get_angular_velocity().x, actor.get_angular_velocity().y, actor.get_angular_velocity().z])
return actor_snapshot
def save_snapshots(self):
if not self.save_snapshots_mode:
return
for i in range (0, len(self.actor_list)):
self.snapshots[i] = np.vstack((self.snapshots[i], self.save_snapshot(self.actor_list[i][1])))
def save_snapshots_to_disk(self):
if not self.save_snapshots_mode:
return
for i, actor in enumerate(self.actor_list):
np.savetxt(self.get_filename(actor[0]), self.snapshots[i])
def get_filename_with_prefix(self, prefix, actor_id=None, frame=None):
add_id = "" if actor_id is None else "_" + actor_id
add_frame = "" if frame is None else ("_%04d") % frame
return prefix + add_id + add_frame + ".out"
def get_filename(self, actor_id=None, frame=None):
return self.get_filename_with_prefix(self.prefix, actor_id, frame)
def run_simulation(self, prefix, run_settings, spectator_tr, tics = 200):
original_settings = self.world.get_settings()
self.init_scene(prefix, run_settings, spectator_tr)
t_start = time.perf_counter()
for _i in range(0, tics):
self.world.tick()
self.save_snapshots()
t_end = time.perf_counter()
self.world.apply_settings(original_settings)
self.save_snapshots_to_disk()
self.clear_scene()
return t_end - t_start
class TwoSpawnedCars(Scenario):
def init_scene(self, prefix, settings = None, spectator_tr = None):
super().init_scene(prefix, settings, spectator_tr)
blueprint_library = self.world.get_blueprint_library()
vehicle00_tr = carla.Transform(carla.Location(100, -257, 0.02), carla.Rotation(yaw=181.5))
vehicle00 = self.world.spawn_actor(blueprint_library.filter("tt")[0], vehicle00_tr)
vehicle01_tr = carla.Transform(carla.Location(110, -253, 0.04), carla.Rotation(yaw=181.5))
vehicle01 = self.world.spawn_actor(blueprint_library.filter("lincoln")[0], vehicle01_tr)
self.wait(1)
vehicle00.set_target_velocity(carla.Vector3D(-25, 0, 0))
vehicle01.set_target_velocity(carla.Vector3D(-25, 0, 0))
self.add_actor(vehicle00, "Car")
self.add_actor(vehicle01, "Car")
self.wait(1)
class TwoCarsSlowSpeedCollision(Scenario):
def init_scene(self, prefix, settings = None, spectator_tr = None):
super().init_scene(prefix, settings, spectator_tr)
blueprint_library = self.world.get_blueprint_library()
vehicle00_tr = carla.Transform(carla.Location(100, -256, 0.015), carla.Rotation(yaw=178))
vehicle00 = self.world.spawn_actor(blueprint_library.filter("tt")[0], vehicle00_tr)
vehicle01_tr = carla.Transform(carla.Location(40, -255, 0.04), carla.Rotation(yaw=0))
vehicle01 = self.world.spawn_actor(blueprint_library.filter("lincoln")[0], vehicle01_tr)
self.wait(1)
vehicle00.set_target_velocity(carla.Vector3D(-12, 0, 0))
vehicle01.set_target_velocity(carla.Vector3D(+12, 0, 0))
self.add_actor(vehicle00, "Car")
self.add_actor(vehicle01, "Car")
self.wait(1)
class TwoCarsHighSpeedCollision(Scenario):
def init_scene(self, prefix, settings = None, spectator_tr = None):
super().init_scene(prefix, settings, spectator_tr)
blueprint_library = self.world.get_blueprint_library()
vehicle00_tr = carla.Transform(carla.Location(140, -256, 0.015), carla.Rotation(yaw=180))
vehicle00 = self.world.spawn_actor(blueprint_library.filter("tt")[0], vehicle00_tr)
vehicle01_tr = carla.Transform(carla.Location(40, -255, 0.04), carla.Rotation(yaw=0))
vehicle01 = self.world.spawn_actor(blueprint_library.filter("lincoln")[0], vehicle01_tr)
self.wait(1)
vehicle00.set_target_velocity( carla.Vector3D(-50, 0, 0))
vehicle01.set_target_velocity(carla.Vector3D(+50, 0, 0))
self.add_actor(vehicle00, "Car")
self.add_actor(vehicle01, "Car")
self.wait(1)
class ThreeCarsSlowSpeedCollision(Scenario):
def init_scene(self, prefix, settings = None, spectator_tr = None):
super().init_scene(prefix, settings, spectator_tr)
blueprint_library = self.world.get_blueprint_library()
vehicle00_tr = carla.Transform(carla.Location(110, -255, 0.05), carla.Rotation(yaw=180))
vehicle00 = self.world.spawn_actor(blueprint_library.filter("prius")[0], vehicle00_tr)
vehicle01_tr = carla.Transform(carla.Location(53, -257, 0.00), carla.Rotation(yaw=0))
vehicle01 = self.world.spawn_actor(blueprint_library.filter("a2")[0], vehicle01_tr)
vehicle02_tr = carla.Transform(carla.Location(85, -230, 0.04), carla.Rotation(yaw=-90))
vehicle02 = self.world.spawn_actor(blueprint_library.filter("lincoln")[0], vehicle02_tr)
self.wait(1)
vehicle00.set_target_velocity(carla.Vector3D(-15, 0, 0))
vehicle01.set_target_velocity(carla.Vector3D(+15, 0, 0))
vehicle02.set_target_velocity(carla.Vector3D(0, -15, 0))
self.add_actor(vehicle00, "Car")
self.add_actor(vehicle01, "Car")
self.add_actor(vehicle02, "Car")
self.wait(1)
class ThreeCarsHighSpeedCollision(Scenario):
def init_scene(self, prefix, settings = None, spectator_tr = None):
super().init_scene(prefix, settings, spectator_tr)
blueprint_library = self.world.get_blueprint_library()
vehicle00_tr = carla.Transform(carla.Location(110, -255, 0.05), carla.Rotation(yaw=180))
vehicle00 = self.world.spawn_actor(blueprint_library.filter("prius")[0], vehicle00_tr)
vehicle01_tr = carla.Transform(carla.Location(53, -257, 0.00), carla.Rotation(yaw=0))
vehicle01 = self.world.spawn_actor(blueprint_library.filter("a2")[0], vehicle01_tr)
vehicle02_tr = carla.Transform(carla.Location(85, -230, 0.04), carla.Rotation(yaw=-90))
vehicle02 = self.world.spawn_actor(blueprint_library.filter("lincoln")[0], vehicle02_tr)
self.wait(1)
vehicle00.set_target_velocity(carla.Vector3D(-30, 0, 0))
vehicle01.set_target_velocity(carla.Vector3D(+30, 0, 0))
vehicle02.set_target_velocity(carla.Vector3D(0, -30, 0))
self.add_actor(vehicle00, "Car")
self.add_actor(vehicle01, "Car")
self.add_actor(vehicle02, "Car")
self.wait(1)
class CarBikeCollision(Scenario):
def init_scene(self, prefix, settings = None, spectator_tr = None):
super().init_scene(prefix, settings, spectator_tr)
blueprint_library = self.world.get_blueprint_library()
car_tr = carla.Transform(carla.Location(50, -255, 0.04), carla.Rotation(yaw=0))
car = self.world.spawn_actor(blueprint_library.filter("*lincoln*")[0], car_tr)
bike_tr = carla.Transform(carla.Location(85, -245, 0.04), carla.Rotation(yaw=-90))
bike = self.world.spawn_actor(blueprint_library.filter("*gazelle*")[0], bike_tr)
self.wait(1)
car.set_target_velocity(carla.Vector3D(+30, 0, 0))
bike.set_target_velocity(carla.Vector3D(0, -12, 0))
self.add_actor(car, "Car")
self.add_actor(bike, "Bike")
self.wait(1)
class CarWalkerCollision(Scenario):
def init_scene(self, prefix, settings = None, spectator_tr = None):
super().init_scene(prefix, settings, spectator_tr)
blueprint_library = self.world.get_blueprint_library()
car_tr = carla.Transform(carla.Location(50, -255, 0.04), carla.Rotation(yaw=0))
car = self.world.spawn_actor(blueprint_library.filter("*lincoln*")[0], car_tr)
walker_tr = carla.Transform(carla.Location(85, -255, 1.00), carla.Rotation(yaw=-90))
walker_bp = blueprint_library.filter("walker.pedestrian.0007")[0]
if walker_bp.has_attribute('is_invincible'):
walker_bp.set_attribute('is_invincible', 'false')
walker = self.world.spawn_actor(walker_bp, walker_tr)
self.wait(1)
car.set_target_velocity(carla.Vector3D(+20, 0, 0))
walker.set_simulate_physics(True)
self.add_actor(car, "Car")
self.add_actor(walker, "Walker")
self.wait(1)
class CollisionScenarioTester():
def __init__(self, scene, output_path):
self.scene = scene
self.world = self.scene.world
self.client = self.scene.client
self.scenario_name = self.scene.__class__.__name__
self.output_path = output_path
def compare_files(self, file_i, file_j):
check_ij = filecmp.cmp(file_i, file_j)
if check_ij:
return True
data_i = np.loadtxt(file_i)
data_j = np.loadtxt(file_j)
max_error = np.amax(np.abs(data_i-data_j))
return max_error < 0.01
def check_simulations(self, rep_prefixes, gen_prefix):
repetitions = len(rep_prefixes)
mat_check = np.zeros((repetitions, repetitions), int)
for i in range(0, repetitions):
mat_check[i][i] = 1
for j in range(0, i):
sim_check = True
for actor in self.scene.actor_list:
actor_id = actor[0]
file_i = self.scene.get_filename_with_prefix(rep_prefixes[i], actor_id)
file_j = self.scene.get_filename_with_prefix(rep_prefixes[j], actor_id)
check_ij = self.compare_files(file_i, file_j)
sim_check = sim_check and check_ij
mat_check[i][j] = int(sim_check)
mat_check[j][i] = int(sim_check)
determinism = np.sum(mat_check,axis=1)
#max_rep_equal = np.amax(determinism)
max_rep_equal_idx = np.argmax(determinism)
min_rep_equal_idx = np.argmin(determinism)
determinism_set = list(set(determinism))
determinism_set.sort(reverse=True)
#print(determinism)
#print(np.argmax(determinism))
#print(np.argmin(determinism))
self.save_simulations(rep_prefixes, gen_prefix, max_rep_equal_idx, min_rep_equal_idx)
return determinism_set
def save_simulations(self, rep_prefixes, prefix, max_idx, min_idx):
for actor in self.scene.actor_list:
actor_id = actor[0]
reference_id = "reference_" + actor_id
file_repetition = self.scene.get_filename_with_prefix(rep_prefixes[max_idx], actor_id)
file_reference = self.scene.get_filename_with_prefix(prefix, reference_id)
shutil.copyfile(file_repetition, file_reference)
if min_idx != max_idx:
for actor in self.scene.actor_list:
actor_id = actor[0]
failed_id = "failed_" + actor_id
file_repetition = self.scene.get_filename_with_prefix(rep_prefixes[min_idx], actor_id)
file_failed = self.scene.get_filename_with_prefix(prefix, failed_id)
shutil.copyfile(file_repetition, file_failed)
for r_prefix in rep_prefixes:
for actor in self.scene.actor_list:
actor_id = actor[0]
file_repetition = self.scene.get_filename_with_prefix(r_prefix, actor_id)
os.remove(file_repetition)
def test_scenario(self, fps=20, fps_phys=100, repetitions = 1, sim_tics = 100):
output_str = "Testing Determinism in %s for %3d render FPS and %3d physics FPS -> " % (self.scenario_name, fps, fps_phys)
# Creating run features: prefix, settings and spectator options
prefix = self.output_path + self.scenario_name + "_" + str(fps) + "_" + str(fps_phys)
config_settings = self.world.get_settings()
config_settings.synchronous_mode = True
config_settings.fixed_delta_seconds = 1.0/fps
config_settings.substepping = True
config_settings.max_substep_delta_time = 1.0/fps_phys
config_settings.max_substeps = 16
spectator_tr = carla.Transform(carla.Location(120, -256, 10), carla.Rotation(yaw=180))
t_comp = 0
sim_prefixes = []
for i in range(0, repetitions):
prefix_rep = prefix + "_rep" + str(i)
t_comp += self.scene.run_simulation(prefix_rep, config_settings, spectator_tr, tics=sim_tics)
sim_prefixes.append(prefix_rep)
determ_repet = self.check_simulations(sim_prefixes, prefix)
output_str += "Deterministic Repetitions: %r / %2d" % (determ_repet, repetitions)
output_str += " -> Comp. Time per frame: %.0f" % (t_comp/repetitions*sim_tics)
if determ_repet[0] != repetitions:
print("Error!!! Scenario %s is not deterministic: %d / %d" % (self.scenario_name, determ_repet[0], repetitions))
return output_str
def main(arg):
"""Main function of the script"""
client = carla.Client(arg.host, arg.port)
client.set_timeout(30.0)
world = client.get_world()
pre_settings = world.get_settings()
world = client.load_world("Town03")
spectator_transform = carla.Transform(carla.Location(120, -256, 5), carla.Rotation(yaw=180))
spectator_transform.location.z += 5
spectator = world.get_spectator()
spectator.set_transform(spectator_transform)
try:
# Setting output temporal folder
output_path = os.path.dirname(os.path.realpath(__file__))
output_path = os.path.join(output_path, "_collisions") + os.path.sep
if not os.path.exists(output_path):
os.mkdir(output_path)
test_list = [
CollisionScenarioTester(TwoSpawnedCars(client, world, True), output_path),
CollisionScenarioTester(TwoCarsSlowSpeedCollision(client, world, True), output_path),
CollisionScenarioTester(TwoCarsHighSpeedCollision(client, world, True), output_path),
CollisionScenarioTester(CarBikeCollision(client, world, True), output_path),
CollisionScenarioTester(CarWalkerCollision(client, world, True), output_path),
CollisionScenarioTester(ThreeCarsSlowSpeedCollision(client, world, True), output_path),
CollisionScenarioTester(ThreeCarsHighSpeedCollision(client, world, True), output_path),
]
repetitions = 10
for item in test_list:
print("--------------------------------------------------------------")
#item.test_scenario(20, 20, repetitions)
#item.test_scenario(20, 40, repetitions)
#item.test_scenario(20, 60, repetitions)
#item.test_scenario(20, 80, repetitions)
out = item.test_scenario(20, 100, repetitions)
print(out)
print("--------------------------------------------------------------")
# Remove all the output files
#shutil.rmtree(path)
finally:
world.apply_settings(pre_settings)
if __name__ == "__main__":
argparser = argparse.ArgumentParser(
description=__doc__)
argparser.add_argument(
'--host',
metavar='H',
default='localhost',
help='IP of the host CARLA Simulator (default: localhost)')
argparser.add_argument(
'-p', '--port',
metavar='P',
default=2000,
type=int,
help='TCP port of CARLA Simulator (default: 2000)')
argparser.add_argument(
'--filter',
metavar='PATTERN',
default='model3',
help='actor filter (default: "vehicle.*")')
# argparser.add_argument(
# '-fps', '--fps',
# metavar='FPS',
# default=20,
# type=int,
# help='Frames per simulatation second (default: 20)')
# argparser.add_argument(
# '-phys_fps', '--phys_fps',
# metavar='PHYSFPS',
# default=100,
# type=int,
# help='Target physical frames per simulatation second, it will \
# divide the dt in substeps if required to get more precision. (default: 100)')
args = argparser.parse_args()
try:
main(args)
except KeyboardInterrupt:
print(' - Exited by user.')

View File

@ -1,370 +0,0 @@
#!/usr/bin/env python
# Copyright (c) 2020 Computer Vision Center (CVC) at the Universitat Autonoma de
# Barcelona (UAB).
#
# This work is licensed under the terms of the MIT license.
# For a copy, see <https://opensource.org/licenses/MIT>.
"""
Lidar/BB check for CARLA
This script obtains the LiDAR's point cloud corresponding to all the vehicles
of the scene and make sure that they are inside the bounding box of the
corresponding actor.
This is done in a predefined route in Town03 with a high speed and several agressive
turns.
In a nutshell, the script have a queue that is filled in each frame with a lidar point
cloud and an structure for storing the Bounding Boxes. This last one is emulated as a
sensor filling the queue in the on_tick callback of the carla.world. In this way, we make
sure that we are correctly syncronizing the lidar point cloud and BB/actor transformations.
Then, we select the points corresponding to each actor (car) in the scene and check they
are inside the bounding boxes of that actor, all in each vehicle frame of reference.
Important Data structure description:
+ Lidar data structure: four element tuple with:
- [0] Frame
- [1] Sensor name: 'semlidar'
- [2] Point cloud in the form of a numpy dictionary with all semantic lidar information
- [3] Global transformation of the sensor
+ Bounding box data structure: four element tuple with:
- [0] Frame
- [1] Sensor name: 'bb'
- [2] List of actor information: each a tuple with:
- [0] Actor id
- [1] Actor type (blueprint's name)
- [0] Actor's global transformation
- [0] Actor's bounding box
+ ActorTrace class: Takes the Lidar data structure and one actor information and
check if all the data points related with this actor are inside its BB.
This is done in the local coordinate frame of the actor and should be done like:
trace = ActorTrace(actor_info, lidar_data)
trace.process()
trace.check_lidar_data()
"""
import glob
import os
import sys
import numpy as np
from queue import Queue
from queue import Empty
try:
sys.path.append(glob.glob('../carla/dist/carla-*%d.%d-%s.egg' % (
sys.version_info.major,
sys.version_info.minor,
'win-amd64' if os.name == 'nt' else 'linux-x86_64'))[0])
except IndexError:
pass
import carla
class ActorTrace(object):
"""Class that store and process information about an actor at certain moment."""
def __init__(self, actor, lidar):
self.set_lidar(lidar)
self.set_actor(actor)
self._lidar_pc_local = np.array([])
self._bb_vertices = np.array([])
self._bb_minlimits = [0, 0, 0]
self._bb_maxlimits = [0, 0, 0]
def set_lidar(self, lidar):
self._frame = lidar[0]
self._lidar_data = lidar[2]
self._lidar_transf = lidar[3]
def set_actor(self, actor):
self._actor_id = actor[0]
self._actor_type = actor[1]
self._actor_transf = actor[2]
self._actor_bb = actor[3]
def process(self):
# Filter lidar points that correspond to my actor id
data_actor = self._lidar_data[self._lidar_data['ObjIdx'] == self._actor_id]
# Take the xyz point cloud data and transform it to actor's frame
points = np.array([data_actor['x'], data_actor['y'], data_actor['z']]).T
points = np.append(points, np.ones((points.shape[0], 1)), axis=1)
points = np.dot(self._lidar_transf.get_matrix(), points.T).T # sensor -> world
points = np.dot(self._actor_transf.get_inverse_matrix(), points.T).T # world -> actor
points = points[:, :-1]
# Saving the points in 'local' coordinates
self._lidar_pc_local = points
# We compute the limits in the local frame of reference using the
# vertices of the bounding box
vertices = self._actor_bb.get_local_vertices()
ver_py = []
for v in vertices:
ver_py.append([v.x, v.y, v.z])
ver_np = np.array(ver_py)
self._bb_vertices = ver_np
self._bb_minlimits = ver_np.min(axis=0) - 0.001
self._bb_maxlimits = ver_np.max(axis=0) + 0.001
def print(self, print_if_empty = False):
if self._lidar_pc_local.shape[0] > 0 or print_if_empty:
np.savetxt("veh_data_%d_%s_%d.out" % (self._frame, self._actor_type, self._actor_id), self._lidar_pc_local)
np.savetxt("bb_data_%d_%s_%d.out" % (self._frame, self._actor_type, self._actor_id), self._bb_vertices)
def lidar_is_outside_bb(self, check_axis = [True, True, True]):
lidar_pc = self._lidar_pc_local
if check_axis[0]:
xmin = self._bb_minlimits[0]
xmax = self._bb_maxlimits[0]
out = np.any((lidar_pc[:,0] > xmax) | (lidar_pc[:,0] < xmin))
if out:
print("Problem with x axis")
return True
if check_axis[1]:
ymin = self._bb_minlimits[1]
ymax = self._bb_maxlimits[1]
out = np.any((lidar_pc[:, 1] > ymax) | (lidar_pc[:, 1] < ymin))
if out:
print("Problem with y axis")
return True
if check_axis[2]:
zmin = self._bb_minlimits[2]
zmax = self._bb_maxlimits[2]
out = np.any((lidar_pc[:, 2] > zmax) | (lidar_pc[:, 2] < zmin))
if out:
print("Problem with z axis")
return True
return False
def check_lidar_data(self):
if self.lidar_is_outside_bb():
print("Error!!! Points of lidar point cloud are outside its BB for car %d: %s " % (self._actor_id, self._actor_type))
self.print()
return False
else:
return True
def wait(world, frames=100, queue = None, slist = None):
for i in range(0, frames):
world.tick()
if queue != None and slist != None:
try:
for _i in range (0, len(slist)):
s_frame = queue.get(True, 1.0)
except Empty:
print(" Some of the sensor information is missed")
# Sensor callback.
# This is where you receive the sensor data and
# process it as you liked and the important part is that,
# at the end, it should include an element into the sensor queue.
def lidar_callback(sensor_data, sensor_queue, sensor_name):
sensor_pc_local = np.frombuffer(sensor_data.raw_data, dtype=np.dtype([
('x', np.float32), ('y', np.float32), ('z', np.float32),
('CosAngle', np.float32), ('ObjIdx', np.uint32), ('ObjTag', np.uint32)]))
sensor_transf = sensor_data.transform
sensor_queue.put((sensor_data.frame, sensor_name, sensor_pc_local, sensor_transf))
def bb_callback(snapshot, world, sensor_queue, sensor_name):
data_array = []
vehicles = world.get_actors().filter('vehicle.*')
for actor in vehicles:
data_array.append((actor.id, actor.type_id, actor.get_transform(), actor.bounding_box))
sensor_queue.put((snapshot.frame, sensor_name, data_array))
def move_spectator(world, actor):
actor_tr = actor.get_transform()
spectator_transform = carla.Transform(actor_tr.location, actor_tr.rotation)
spectator_transform.location -= actor_tr.get_forward_vector() * 5
spectator_transform.location -= actor_tr.get_up_vector() * 3
spectator = world.get_spectator()
spectator.set_transform(spectator_transform)
def world_callback(snapshot, world, sensor_queue, sensor_name, actor):
move_spectator(world, actor)
bb_callback(snapshot, world, sensor_queue, sensor_name)
def process_sensors(w_frame, sensor_queue, sensor_number):
if sensor_number != 2:
print("Error!!! Sensor number should be two")
sl_data = None
bb_data = None
try:
for i in range (0, sensor_number):
s_frame = sensor_queue.get(True, 1.0)
while s_frame[0] != w_frame:
print("Warning! Missmatch for sensor %s in the frame timestamp (w: %d, s: %d)" % (s_frame[1], w_frame, s_frame[0]))
print("This could be due to accumulated data for previous steps")
s_frame = sensor_queue.get(True, 1.0)
if s_frame[1] == "semlidar":
sl_data = s_frame
elif s_frame[1] == "bb":
bb_data = s_frame
#print(" Frame: %d Sensor: %s Len: %d " % (s_frame[0], s_frame[1], len(s_frame[2])))
except Empty:
print("Error!!! The needeinformation is not here!!!")
return
if sl_data == None or bb_data == None:
print("Error!!! Missmatch for sensor %s in the frame timestamp (w: %d, s: %d)" % (s_frame[1], w_frame, s_frame[0]))
for actor_data in bb_data[2]:
trace_vehicle = ActorTrace(actor_data, sl_data)
trace_vehicle.process()
trace_vehicle.check_lidar_data()
class SpawnCar(object):
def __init__(self, location, rotation, filter="vehicle.*", autopilot = False, velocity = None):
self._filter = filter
self._transform = carla.Transform(location, rotation)
self._autopilot = autopilot
self._velocity = velocity
self._actor = None
self._world = None
def spawn(self, world):
self._world = world
actor_BP = world.get_blueprint_library().filter(self._filter)[0]
self._actor = world.spawn_actor(actor_BP, self._transform)
self._actor.set_autopilot(True)
return self._actor
def destroy(self):
if self._actor != None:
self._actor.destroy()
CarPropList = [
SpawnCar(carla.Location(x=83, y= -40, z=5), carla.Rotation(yaw=-90), filter= "mkz_2017", autopilot=True),
SpawnCar(carla.Location(x=83, y= -30, z=3), carla.Rotation(yaw=-90), filter= "ambulance", autopilot=True),
SpawnCar(carla.Location(x=83, y= -20, z=3), carla.Rotation(yaw=-90), filter= "etron", autopilot=True),
SpawnCar(carla.Location(x=120, y= -3.5, z=2), carla.Rotation(yaw=+180), filter= "microlino", autopilot=True),
SpawnCar(carla.Location(x=100, y= -3.5, z=2), carla.Rotation(yaw=+180), filter= "coupe_2020", autopilot=True),
SpawnCar(carla.Location(x=140, y= -3.5, z=2), carla.Rotation(yaw=+180), filter= "model3", autopilot=True),
SpawnCar(carla.Location(x=160, y= -3.5, z=2), carla.Rotation(yaw=+180), filter= "impala", autopilot=False),
SpawnCar(carla.Location(x=180, y= -3.5, z=2), carla.Rotation(yaw=+180), filter= "a2", autopilot=True),
SpawnCar(carla.Location(x=60, y= +6, z=2), carla.Rotation(yaw=+00), filter= "sprinter", autopilot=True),
SpawnCar(carla.Location(x=80, y= +6, z=2), carla.Rotation(yaw=+00), filter= "t2", autopilot=True),
SpawnCar(carla.Location(x=100, y= +6, z=2), carla.Rotation(yaw=+00), filter= "mustang", autopilot=True),
SpawnCar(carla.Location(x=120, y= +6, z=2), carla.Rotation(yaw=+00), filter= "patrol_2021", autopilot=True),
SpawnCar(carla.Location(x=140, y= +6, z=2), carla.Rotation(yaw=+00), filter= "impala", autopilot=True),
SpawnCar(carla.Location(x=160, y= +6, z=2), carla.Rotation(yaw=+00), filter= "prius", autopilot=True),
SpawnCar(carla.Location(x=234, y= +20,z=2), carla.Rotation(yaw=+90), filter= "charger_police_2020", autopilot=True),
SpawnCar(carla.Location(x=234, y= +40,z=2), carla.Rotation(yaw=+90), filter= "microlino", autopilot=True),
SpawnCar(carla.Location(x=234, y= +80,z=2), carla.Rotation(yaw=+90), filter= "tt", autopilot=True),
SpawnCar(carla.Location(x=243, y= -40,z=2), carla.Rotation(yaw=-90), filter= "etron", autopilot=True),
SpawnCar(carla.Location(x=243, y= -20,z=2), carla.Rotation(yaw=-90), filter= "mkz_2017", autopilot=True),
SpawnCar(carla.Location(x=243, y= +00,z=2), carla.Rotation(yaw=-90), filter= "mustang", autopilot=True),
SpawnCar(carla.Location(x=243, y= +20,z=2), carla.Rotation(yaw=-90), filter= "cooper_s_2021", autopilot=True),
SpawnCar(carla.Location(x=243, y= +40,z=2), carla.Rotation(yaw=-90), filter= "charger_2020", autopilot=True),
SpawnCar(carla.Location(x=243, y= +60,z=2), carla.Rotation(yaw=-90), filter= "mkz_2020", autopilot=True),
SpawnCar(carla.Location(x=243, y= +80,z=2), carla.Rotation(yaw=-90), filter= "tt", autopilot=True),
SpawnCar(carla.Location(x=243, y=+100,z=2), carla.Rotation(yaw=-90), filter= "a2", autopilot=True),
SpawnCar(carla.Location(x=243, y=+120,z=2), carla.Rotation(yaw=-90), filter= "wrangler_rubicon", autopilot=True),
SpawnCar(carla.Location(x=243, y=+140,z=2), carla.Rotation(yaw=-90), filter= "c3", autopilot=True)
]
def spawn_prop_vehicles(world):
for car in CarPropList:
car.spawn(world)
def destroy_prop_vehicles():
for car in CarPropList:
car.destroy()
def main():
# We start creating the client
client = carla.Client('localhost', 2000)
client.set_timeout(2.0)
world = client.get_world()
try:
# We need to save the settings to be able to recover them at the end
# of the script to leave the server in the same state that we found it.
original_settings = world.get_settings()
settings = world.get_settings()
# We set CARLA syncronous mode
settings.fixed_delta_seconds = 0.05
settings.synchronous_mode = True
world.apply_settings(settings)
traffic_manager = client.get_trafficmanager(8000)
traffic_manager.set_synchronous_mode(True)
# We create the sensor queue in which we keep track of the information
# already received. This structure is thread safe and can be
# accessed by all the sensors callback concurrently without problem.
sensor_queue = Queue()
# Spawning ego vehicle
actor_BP = world.get_blueprint_library().filter("vehicle.lincoln.mkz_2017")[0]
car_tr = carla.Transform(carla.Location(x=239, y=125, z=0.9), carla.Rotation(yaw=-88.5))
actor = world.spawn_actor(actor_BP, car_tr)
world.tick()
move_spectator(world, actor)
spawn_prop_vehicles(world)
wait(world, 10)
# We create all the sensors and keep them in a list for convenience.
sensor_list = []
lidar_bp = world.get_blueprint_library().find('sensor.lidar.ray_cast_semantic')
lidar_bp.set_attribute('channels', '64')
lidar_bp.set_attribute('points_per_second', '500000')
lidar_bp.set_attribute('range', '300')
lidar_bp.set_attribute('upper_fov', '10.0')
lidar_bp.set_attribute('lower_fov', '-90.0')
lidar_tr = carla.Transform(carla.Location(z=3), carla.Rotation(yaw=0))
lidar = world.spawn_actor(lidar_bp, lidar_tr, attach_to=actor)
lidar.listen(lambda data: lidar_callback(data, sensor_queue, "semlidar"))
world.on_tick(lambda snapshot: world_callback(snapshot, world, sensor_queue, "bb", actor))
sensor_list.append(lidar)
sensor_list.append(actor) # actor acts as a 'sensor' to simplify bb-lidar data comparison
# Set autopilot for main vehicle
actor.enable_constant_velocity(carla.Vector3D(20, 0, 0))
for _i in range(0, 100):
# Tick the server
world.tick()
w_frame = world.get_snapshot().frame
process_sensors(w_frame, sensor_queue, len(sensor_list))
actor.disable_constant_velocity()
finally:
world.apply_settings(original_settings)
# Destroy all the actors
destroy_prop_vehicles()
for sensor in sensor_list:
sensor.destroy()
if __name__ == "__main__":
try:
main()
except KeyboardInterrupt:
print(' - Exited by user.')

Some files were not shown because too many files have changed in this diff Show More