Compare commits
49 Commits
2478083e46
...
1e313b1cb5
Author | SHA1 | Date |
---|---|---|
Blyron | 1e313b1cb5 | |
Blyron | 95728ec9a0 | |
Joel Moriana | 359f723d20 | |
Pablo Villanueva-Domingo | 2b249b501c | |
Marcel Pi | 65ef483f03 | |
PabloVD | 2c7fcd5491 | |
PabloVD | 7f51f21ee5 | |
PabloVD | 6ee7cf5bd1 | |
Marcel Pi | 76dfbb1244 | |
PabloVD | d8045c98ff | |
PabloVD | 13d3a3a341 | |
Blyron | 31ab42c46e | |
MarcelPiNacy-CVC | fb62780b58 | |
Blyron | e5f7e79d09 | |
Blyron | b4b064beb3 | |
MarcelPiNacy-CVC | b8b1d3495f | |
Blyron | ad2a73f122 | |
MarcelPiNacy-CVC | 078029189b | |
MarcelPiNacy-CVC | 6ee86983a4 | |
MarcelPiNacy-CVC | 4bbcfd2370 | |
MarcelPiNacy-CVC | ac66b3637e | |
Blyron | 880391b9a2 | |
MattRoweEAIF | 2de16a2144 | |
MarcelPiNacy-CVC | 8f2fc098b4 | |
MarcelPiNacy-CVC | 1417cc6617 | |
MarcelPiNacy-CVC | df514f94b3 | |
MarcelPiNacy-CVC | f8d95c2e8f | |
MarcelPiNacy-CVC | d26a3ede74 | |
MarcelPiNacy-CVC | 0bbd239b1a | |
MarcelPiNacy-CVC | 4c1196db44 | |
MarcelPiNacy-CVC | b143ef1a31 | |
MarcelPiNacy-CVC | 73a716e24d | |
MarcelPiNacy-CVC | 001604da6b | |
MarcelPiNacy-CVC | 930fd57fbb | |
MarcelPiNacy-CVC | 8482279a33 | |
MarcelPiNacy-CVC | 10012e1939 | |
MarcelPiNacy-CVC | e326742a67 | |
joel-mb | 0db777202c | |
MarcelPiNacy-CVC | 7b491bc104 | |
MarcelPiNacy-CVC | 72974894e2 | |
MarcelPiNacy-CVC | c6d9e65be7 | |
Marcel Pi | c00d44d2dc | |
meltycriss | abdff1716f | |
meltycriss | 2816f2752b | |
Blyron | 9ffe13a9b4 | |
MarcelPiNacy-CVC | 239b73e849 | |
MarcelPiNacy-CVC | 592eb46f43 | |
MarcelPiNacy-CVC | 908c203fca | |
MattRoweEAIF | aa9d95eb21 |
|
@ -0,0 +1,2 @@
|
||||||
|
CompileFlags:
|
||||||
|
CompilationDatabase: "@CMAKE_CURRENT_BINARY_DIR@"
|
|
@ -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)
|
||||||
|
|
|
@ -4,10 +4,13 @@
|
||||||
__pycache__/
|
__pycache__/
|
||||||
|
|
||||||
Build/
|
Build/
|
||||||
|
Install/
|
||||||
Doxygen/
|
Doxygen/
|
||||||
Dist/
|
Dist/
|
||||||
out/
|
out/
|
||||||
|
|
||||||
CMakeSettings.json
|
CMakeSettings.json
|
||||||
|
|
||||||
|
.clangd
|
||||||
|
|
||||||
Help.md
|
Help.md
|
||||||
|
|
|
@ -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
|
||||||
# ================================
|
# ================================
|
||||||
|
|
|
@ -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}
|
||||||
|
|
|
@ -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}
|
||||||
|
)
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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 ()
|
||||||
|
|
|
@ -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 |
|
@ -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
|
|
|
@ -1,7 +0,0 @@
|
||||||
venv
|
|
||||||
|
|
||||||
# Vissim files
|
|
||||||
*.results
|
|
||||||
*.inp0
|
|
||||||
*.layx
|
|
||||||
*.err
|
|
|
@ -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
|
@ -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)
|
|
|
@ -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
|
|
|
@ -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
|
|
|
@ -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
|
|
|
@ -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()
|
|
|
@ -1 +0,0 @@
|
||||||
venv
|
|
|
@ -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"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -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>
|
|
|
@ -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>
|
|
|
@ -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>
|
|
|
@ -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>
|
|
|
@ -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
|
@ -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>
|
|
|
@ -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>
|
|
|
@ -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>
|
|
|
@ -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>
|
|
|
@ -1 +0,0 @@
|
||||||
lxml==4.6.2
|
|
|
@ -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)
|
|
|
@ -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)
|
|
|
@ -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
|
|
|
@ -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)
|
|
|
@ -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
|
|
|
@ -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()
|
|
|
@ -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)
|
|
|
@ -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>
|
|
|
@ -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)
|
|
|
@ -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 |
|
@ -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.
|
||||||
|
|
||||||
|
|
|
@ -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 (
|
||||||
|
|
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
|
@ -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);
|
||||||
|
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
|
@ -11,7 +11,7 @@
|
||||||
namespace carla {
|
namespace carla {
|
||||||
namespace geom {
|
namespace geom {
|
||||||
|
|
||||||
class Location;
|
struct Location;
|
||||||
|
|
||||||
class GeoLocation {
|
class GeoLocation {
|
||||||
public:
|
public:
|
||||||
|
|
|
@ -19,8 +19,7 @@
|
||||||
namespace carla {
|
namespace carla {
|
||||||
namespace geom {
|
namespace geom {
|
||||||
|
|
||||||
class Location : public Vector3D {
|
struct Location : Vector3D {
|
||||||
public:
|
|
||||||
|
|
||||||
// =========================================================================
|
// =========================================================================
|
||||||
// -- Constructors ---------------------------------------------------------
|
// -- Constructors ---------------------------------------------------------
|
||||||
|
|
|
@ -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 --------------------------------------------------
|
||||||
|
|
|
@ -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 --------------------------------------------------
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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 {
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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)
|
||||||
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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() {
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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})"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
|
@ -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();
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
|
@ -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'
|
||||||
|
|
|
@ -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")))
|
||||||
|
|
|
@ -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))
|
||||||
|
|
|
@ -1,2 +1 @@
|
||||||
carla.so
|
_out/
|
||||||
carla.pyd
|
|
||||||
|
|
|
@ -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',
|
||||||
|
|
|
@ -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)
|
||||||
|
|
|
@ -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()
|
|
|
@ -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',
|
||||||
|
|
|
@ -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
|
@ -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
|
@ -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
|
||||||
|
|
|
@ -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)
|
||||||
|
|
||||||
|
|
|
@ -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,
|
||||||
|
|
|
@ -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()
|
|
|
@ -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))
|
|
|
@ -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)
|
|
|
@ -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>
|
|
|
@ -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>
|
|
|
@ -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.')
|
|
|
@ -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()
|
|
|
@ -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()
|
|
|
@ -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()
|
||||||
|
|
||||||
|
|
|
@ -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.')
|
|
|
@ -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
Loading…
Reference in New Issue