From 8e2d19f3eb674d4b72d772619dd22e7476622e68 Mon Sep 17 00:00:00 2001 From: Adam Morrissett Date: Fri, 27 Oct 2023 15:35:28 -0400 Subject: [PATCH 1/8] #167 Add ScenarioRunner Docker configuration The Docker image contains all necessary dependencies and embeds any custom CARMA scenarios to run. --- scenario-runner/.dockerignore | 3 + scenario-runner/Dockerfile | 49 ++++ scenario-runner/README.md | 63 +++++ .../{ => examples}/my_scenario.xml | 0 scenario-runner/install_carma_scenario_runner | 217 ++++++++++++++++++ scenario-runner/requirements.txt | 6 - .../{ => scenarios}/my_scenario.py | 0 7 files changed, 332 insertions(+), 6 deletions(-) create mode 100644 scenario-runner/.dockerignore create mode 100644 scenario-runner/Dockerfile rename scenario-runner/{ => examples}/my_scenario.xml (100%) create mode 100755 scenario-runner/install_carma_scenario_runner delete mode 100644 scenario-runner/requirements.txt rename scenario-runner/{ => scenarios}/my_scenario.py (100%) diff --git a/scenario-runner/.dockerignore b/scenario-runner/.dockerignore new file mode 100644 index 00000000..5a01a324 --- /dev/null +++ b/scenario-runner/.dockerignore @@ -0,0 +1,3 @@ +Dockerfile +README.md +requirements.txt diff --git a/scenario-runner/Dockerfile b/scenario-runner/Dockerfile new file mode 100644 index 00000000..b19c6941 --- /dev/null +++ b/scenario-runner/Dockerfile @@ -0,0 +1,49 @@ +# Copyright 2023 Leidos +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +FROM ubuntu:18.04 + +ARG CARLA_VERSION=0.9.10 + +RUN apt update \ + && DEBIAN_FRONTEND=noninteractive apt install --no-install-recommends --yes --quiet \ + libpng16-16 \ + libtiff5 \ + libjpeg8 \ + build-essential \ + wget \ + git \ + python3.7 \ + python3.7-dev \ + python3-pip \ + libxerces-c-dev \ + && rm -rf /var/lib/apt/lists/* + +WORKDIR /tmp +COPY . . +RUN ./install_carma_scenario_runner --prefix /app $CARLA_VERSION \ + && wget -qO- "https://carla-releases.s3.eu-west-3.amazonaws.com/Linux/CARLA_$CARLA_VERSION.tar.gz" \ + | tar -xz PythonAPI/carla \ + && mv PythonAPI/carla /app \ + && rm -rf * + +# RUN + +# && rm -rf PythonAPI + +WORKDIR /app/scenario_runner + +ENV PYTHONPATH "/app/carla/agents:/app/carla:/app/carla/dist/carla-$CARLA_VERSION-py3.7-linux-x86_64.egg" + +# ENTRYPOINT ["python3", "scenario_runner.py"] diff --git a/scenario-runner/README.md b/scenario-runner/README.md index 9c5c6108..dda7e3b0 100644 --- a/scenario-runner/README.md +++ b/scenario-runner/README.md @@ -5,3 +5,66 @@ scenario configurations to facilitate integration testing. This still a work in progress, so the scenarios serve more as example references. [scenario_runner_docs_link]: https://carla-scenariorunner.readthedocs.io/en/latest/ + +## Getting started + +ScenarioRunner's code resides in the `srunner` Python package, and the +`scenario_runner.py` script is responsible for launching scenarios. If we want +to use ScenarioRunner for custom CARMA scenarios, we have to overcome two +technical hurdles: + +1. the `srunner` package is unavailable in [PyPi][pypi_link]; +2. we have to embed our scenario definitions and configurations within + `srunner`; and +3. ScenarioRunner uses on the [CARLA Python API][carla_python_api_link] + internally, which we have to install separately. + +You have three options for getting ScenarioRunner working with the custom +CARMA scenarios, each described below. + +[pypi_link]: https://pypi.org +[carla_python_api_link]: https://carla.readthedocs.io/en/latest/python_api/ + +### Manual installation + +Check out the official documentation on how to install ScenarioRunner, the +CARLA Python client library. Their instructions also show how to add custom +scenario definitions (in the `scenarios/` directory) and configurations (in the +`examples/` directory) to the installation. + +### Convenience script + +You can use the convenience script (`install_carma_scenario_runner`) provided +in this directory to download and install a specific ScenarioRunner version to +a desired location. The script will also replace the provided scenarios with +the ones specific to CARMA. + +The example below shows how you can install ScenarioRunner version 0.9.10 to +the `/opt/scenario_runner` directory: + +```shell +$ ./install_carma_scenario_runner --prefix /opt 0.9.10 +``` + +> [!IMPORTANT]\ +> This script does not install the CARLA Python client library, so you will +> still have to do that separately. It also does not modify the `PYTHONPATH` +> environment variable, so double check that Python can find the `srunner` +> package after you install it. + +### Docker (recommended) + +You can build a Docker image that packages ScenarioRunner, the CARMA scenarios, +and the CARLA Python API. The `Dockerfile` included in this directory handles +all the required installation steps. + +After building the image, you can run ScenarioRunner as shown in the below +example: + +```shell +$ docker run --rm -it usdotfhwastol/carma-scenario-runner:0.9.10 \ + --scenario FollowLeadingVehicle_1 --reloadWorld +``` + +The container automatically invokes the `scenario_runner.py` script, so you +need only to specify the desired scenario. diff --git a/scenario-runner/my_scenario.xml b/scenario-runner/examples/my_scenario.xml similarity index 100% rename from scenario-runner/my_scenario.xml rename to scenario-runner/examples/my_scenario.xml diff --git a/scenario-runner/install_carma_scenario_runner b/scenario-runner/install_carma_scenario_runner new file mode 100755 index 00000000..a60c6919 --- /dev/null +++ b/scenario-runner/install_carma_scenario_runner @@ -0,0 +1,217 @@ +#!/bin/bash + +# Copyright 2023 Leidos +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +####################################### +# Prints a string to standard error +# Globals: +# None +# Arguments: +# String to print +# Returns: +# 0 +####################################### +function err() { + echo "$*" >&2 +} + +####################################### +# Prints error and exits script if argument count is unexpected +# Globals: +# None +# Arguments: +# Actual argument count +# Expected argument count +# Error message to print before exiting (if unexpected count) +# Returns: +# 0 +####################################### +function assert_argument_count_eq() { + if [ "$1" -ne "$2" ]; then + if [ "$#" -eq 3 ]; then + echo "$3" + fi + print_usage + exit 1 + fi +} + +####################################### +# Prints the script's argument descriptions +# Globals: +# None +# Arguments: +# None +# Returns: +# 0 +####################################### +function print_help() { + command cat <<-HELP +options: + -h, --help Show usage + --prefix The path prefix for the installation. Installation + will be located at /scenario_runner + +positional arguments: + scenario_runner_version The scenario_runner version to install (should be + identical to the CARLA version being used) +HELP +} + +####################################### +# Prints the script's usage +# Globals: +# None +# Arguments: +# None +# Returns: +# 0 +####################################### +function print_usage() { + command cat <<-USAGE +usage: install_carma_scenario_runner [-h | --help] [--prefix ] + +USAGE +} + +####################################### +# Downlaods a minimized scenario_runner +# Globals: +# SCENARIO_RUNNER_HOME (read) +# SCENARIO_RUNNER_VERSION (read) +# Arguments: +# None +# Returns: +# 0 if the download succeeded +####################################### +function install_minimal_scenario_runner() { + git clone \ + -c advice.detachedHead=false \ + --depth 1 \ + --branch "${SCENARIO_RUNNER_VERSION}" \ + https://github.com/carla-simulator/scenario_runner.git \ + "${SCENARIO_RUNNER_HOME}" + + if [[ "$?" -ne 0 ]]; then + err "error: could not clone scenario_runner repository" + return "$?" + fi + + cd "${SCENARIO_RUNNER_HOME}" + + python3 -m pip install --upgrade --no-cache-dir -r requirements.txt + + rm -rf \ + CARLA_VER \ + Dockerfile \ + Docs \ + .git \ + .github \ + .gitignore \ + Jenkinsfile \ + LICENSE \ + manual_control.py \ + metrics_manager.py \ + mkdocs.yml \ + no_rendering_mode.py \ + .pylintrc \ + README.md \ + .readthedocs.yml \ + requirements.txt \ + tests + + # We will replace the provided scenarios with our own + rm -rf \ + srunner/examples \ + srunner/scenarios + + cd - > /dev/null +} + +####################################### +# Installs CARMA-specific scenario_runner scenarios from current directory +# Globals: +# SCENARIO_RUNNER_HOME (read) +# Arguments: +# None +# Returns: +# 0 +####################################### +function install_carma_scenarios() { + cp -r scenarios examples "${SCENARIO_RUNNER_HOME}/srunner" +} + +####################################### +# Main script entrypoint +# Globals: +# SCENARIO_RUNNER_HOME (write) +# SCENARIO_RUNNER_VERSION (write) +# Arguments: +# commandline arguments +# Returns: +# 0 +####################################### +function main() { + local install_prefix="" + + while :; do + case "$1" in + -h|--help) + print_usage + echo "" + print_help + exit 0 + ;; + --prefix) + shift + if [ "$#" -eq 0 ]; then + err "error: option 'prefix' requires a value" + print_usage + exit 129 + fi + install_prefix="$1" + ;; + *) + if [[ "$1" == -* ]]; then + err "unknown option '$1'" + print_usage + exit 129 + fi + break + esac + shift + done + + assert_argument_count_eq "$#" 1 "error: missing scneario_runner branch" + + mkdir -p "${install_prefix}" + + declare -rg SCENARIO_RUNNER_HOME="${install_prefix:+${install_prefix}/}scenario_runner" + declare -rg SCENARIO_RUNNER_VERSION="$1" + + python3 -m pip install --upgrade --no-cache-dir pip setuptools wheel + + if ! install_minimal_scenario_runner; then + err "error: could not install scenario_runner" + exit 1 + fi + + if ! install_carma_scenarios; then + err "error: could not install CARMA scenarios" + exit 1 + fi +} + +main "$@" diff --git a/scenario-runner/requirements.txt b/scenario-runner/requirements.txt deleted file mode 100644 index 3682601a..00000000 --- a/scenario-runner/requirements.txt +++ /dev/null @@ -1,6 +0,0 @@ -py_trees - -# Note: The `srunner` package in PyPi is outdated, and the ScenarioRunner -# documentation uses the source-installed `srunner` package in all of its -# examples. -# srunner diff --git a/scenario-runner/my_scenario.py b/scenario-runner/scenarios/my_scenario.py similarity index 100% rename from scenario-runner/my_scenario.py rename to scenario-runner/scenarios/my_scenario.py From f3ef27ef0a5f8cc3ee5e68e13f5fbd36004d6167 Mon Sep 17 00:00:00 2001 From: Adam Morrissett Date: Fri, 27 Oct 2023 15:39:55 -0400 Subject: [PATCH 2/8] #167 Clean up Dockerfile --- scenario-runner/Dockerfile | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/scenario-runner/Dockerfile b/scenario-runner/Dockerfile index b19c6941..4b2359c7 100644 --- a/scenario-runner/Dockerfile +++ b/scenario-runner/Dockerfile @@ -38,12 +38,7 @@ RUN ./install_carma_scenario_runner --prefix /app $CARLA_VERSION \ && mv PythonAPI/carla /app \ && rm -rf * -# RUN - -# && rm -rf PythonAPI - WORKDIR /app/scenario_runner - ENV PYTHONPATH "/app/carla/agents:/app/carla:/app/carla/dist/carla-$CARLA_VERSION-py3.7-linux-x86_64.egg" -# ENTRYPOINT ["python3", "scenario_runner.py"] +ENTRYPOINT ["python3", "scenario_runner.py"] From 7e3dfd643e5ba65be134a489275c37fcedbed6a5 Mon Sep 17 00:00:00 2001 From: Adam Morrissett Date: Fri, 27 Oct 2023 17:19:05 -0400 Subject: [PATCH 3/8] #167 Fix script issues The scenario_runner.py script requires that the existing files in the scenarios/ directory remain there. The installation script no longer deletes them. --- scenario-runner/install_carma_scenario_runner | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/scenario-runner/install_carma_scenario_runner b/scenario-runner/install_carma_scenario_runner index a60c6919..1e40ad62 100755 --- a/scenario-runner/install_carma_scenario_runner +++ b/scenario-runner/install_carma_scenario_runner @@ -133,9 +133,7 @@ function install_minimal_scenario_runner() { tests # We will replace the provided scenarios with our own - rm -rf \ - srunner/examples \ - srunner/scenarios + rm -rf srunner/examples cd - > /dev/null } From dfad3e7caee0b3969c78f9274560de613b1c5a9a Mon Sep 17 00:00:00 2001 From: Adam Morrissett Date: Fri, 27 Oct 2023 17:35:34 -0400 Subject: [PATCH 4/8] #167 Resolve ShellCheck linting issues --- scenario-runner/install_carma_scenario_runner | 59 +++++++++---------- 1 file changed, 29 insertions(+), 30 deletions(-) diff --git a/scenario-runner/install_carma_scenario_runner b/scenario-runner/install_carma_scenario_runner index 1e40ad62..3f183e88 100755 --- a/scenario-runner/install_carma_scenario_runner +++ b/scenario-runner/install_carma_scenario_runner @@ -97,45 +97,44 @@ USAGE # 0 if the download succeeded ####################################### function install_minimal_scenario_runner() { - git clone \ + if ! git clone \ -c advice.detachedHead=false \ --depth 1 \ --branch "${SCENARIO_RUNNER_VERSION}" \ https://github.com/carla-simulator/scenario_runner.git \ "${SCENARIO_RUNNER_HOME}" - - if [[ "$?" -ne 0 ]]; then + then err "error: could not clone scenario_runner repository" return "$?" fi - cd "${SCENARIO_RUNNER_HOME}" - - python3 -m pip install --upgrade --no-cache-dir -r requirements.txt - - rm -rf \ - CARLA_VER \ - Dockerfile \ - Docs \ - .git \ - .github \ - .gitignore \ - Jenkinsfile \ - LICENSE \ - manual_control.py \ - metrics_manager.py \ - mkdocs.yml \ - no_rendering_mode.py \ - .pylintrc \ - README.md \ - .readthedocs.yml \ - requirements.txt \ - tests - - # We will replace the provided scenarios with our own - rm -rf srunner/examples - - cd - > /dev/null + ( + cd "${SCENARIO_RUNNER_HOME}" || exit + + python3 -m pip install --upgrade --no-cache-dir -r requirements.txt + + rm -rf \ + CARLA_VER \ + Dockerfile \ + Docs \ + .git \ + .github \ + .gitignore \ + Jenkinsfile \ + LICENSE \ + manual_control.py \ + metrics_manager.py \ + mkdocs.yml \ + no_rendering_mode.py \ + .pylintrc \ + README.md \ + .readthedocs.yml \ + requirements.txt \ + tests + + # We will replace the provided scenarios with our own + rm -rf srunner/examples + ) } ####################################### From 65d4bd1eeaf6e87a1c8ba957a92e86f7d456d455 Mon Sep 17 00:00:00 2001 From: Adam Morrissett Date: Mon, 30 Oct 2023 09:15:18 -0400 Subject: [PATCH 5/8] #167 Fix typo in README --- scenario-runner/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scenario-runner/README.md b/scenario-runner/README.md index dda7e3b0..ab7f1a5a 100644 --- a/scenario-runner/README.md +++ b/scenario-runner/README.md @@ -10,7 +10,7 @@ progress, so the scenarios serve more as example references. ScenarioRunner's code resides in the `srunner` Python package, and the `scenario_runner.py` script is responsible for launching scenarios. If we want -to use ScenarioRunner for custom CARMA scenarios, we have to overcome two +to use ScenarioRunner for custom CARMA scenarios, we have to overcome three technical hurdles: 1. the `srunner` package is unavailable in [PyPi][pypi_link]; From d53219aded32fdb77978a2dbb51a493c3e148db0 Mon Sep 17 00:00:00 2001 From: Adam Morrissett Date: Tue, 31 Oct 2023 16:49:55 -0400 Subject: [PATCH 6/8] #167 Comment out cyclist It was causing CDASim to crash. It's not a big deal right now since we are not using it in the MyScenario definition. --- scenario-runner/examples/my_scenario.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scenario-runner/examples/my_scenario.xml b/scenario-runner/examples/my_scenario.xml index d4b6111f..cee95a2f 100644 --- a/scenario-runner/examples/my_scenario.xml +++ b/scenario-runner/examples/my_scenario.xml @@ -20,7 +20,7 @@ limitations under the License. - + From 647c7e75981b014d4d632d334d09fbd839892298 Mon Sep 17 00:00:00 2001 From: Adam Morrissett Date: Wed, 1 Nov 2023 10:32:15 -0400 Subject: [PATCH 7/8] #167 Reorganize Dockerfile items The Dockerfile now downloads CARLA's Python API before installing the CARMA ScenarioRunner scenarios. This allows Docker to cache the CARLA download layer, reducing build times when developers want to develop new scenarios. --- scenario-runner/Dockerfile | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/scenario-runner/Dockerfile b/scenario-runner/Dockerfile index 4b2359c7..ece4ff35 100644 --- a/scenario-runner/Dockerfile +++ b/scenario-runner/Dockerfile @@ -31,13 +31,15 @@ RUN apt update \ && rm -rf /var/lib/apt/lists/* WORKDIR /tmp -COPY . . -RUN ./install_carma_scenario_runner --prefix /app $CARLA_VERSION \ - && wget -qO- "https://carla-releases.s3.eu-west-3.amazonaws.com/Linux/CARLA_$CARLA_VERSION.tar.gz" \ +RUN wget -qO- "https://carla-releases.s3.eu-west-3.amazonaws.com/Linux/CARLA_$CARLA_VERSION.tar.gz" \ | tar -xz PythonAPI/carla \ + && mkdir -p /app \ && mv PythonAPI/carla /app \ && rm -rf * +COPY . . +RUN ./install_carma_scenario_runner --prefix /app $CARLA_VERSION + WORKDIR /app/scenario_runner ENV PYTHONPATH "/app/carla/agents:/app/carla:/app/carla/dist/carla-$CARLA_VERSION-py3.7-linux-x86_64.egg" From 5a41d1c4198a445638ef8dfc4672f19788f88bd7 Mon Sep 17 00:00:00 2001 From: Adam Morrissett Date: Wed, 1 Nov 2023 11:21:16 -0400 Subject: [PATCH 8/8] #167 Remove nonexistant file in .dockerignore --- scenario-runner/.dockerignore | 1 - 1 file changed, 1 deletion(-) diff --git a/scenario-runner/.dockerignore b/scenario-runner/.dockerignore index 5a01a324..6b7b5403 100644 --- a/scenario-runner/.dockerignore +++ b/scenario-runner/.dockerignore @@ -1,3 +1,2 @@ Dockerfile README.md -requirements.txt