Merge remote-tracking branch 'upstream/master' into toyota-fuzzy-v2

pull/28641/head
Shane Smiskol 2 years ago
commit 34683788c8
  1. 2
      .devcontainer/Dockerfile
  2. 3
      .devcontainer/devcontainer.json
  3. 9
      .github/workflows/selfdrive_tests.yaml
  4. 1
      .pre-commit-config.yaml
  5. 4
      selfdrive/test/helpers.py
  6. 2
      selfdrive/thermald/tests/test_power_monitoring.py
  7. 62
      selfdrive/ui/translations/main_zh-CHT.ts
  8. 2
      tools/sim/bridge/common.py
  9. 156
      tools/sim/bridge/metadrive.py
  10. 4
      tools/sim/lib/simulated_car.py
  11. 6
      tools/sim/run_bridge.py
  12. 43
      tools/sim/tests/test_carla_bridge.py
  13. 15
      tools/sim/tests/test_metadrive_bridge.py
  14. 37
      tools/sim/tests/test_sim_bridge.py

@ -9,3 +9,5 @@ RUN pip install ipython jupyter jupyterlab
RUN cd $HOME && \ RUN cd $HOME && \
curl -O https://raw.githubusercontent.com/commaai/agnos-builder/master/userspace/home/.tmux.conf && \ curl -O https://raw.githubusercontent.com/commaai/agnos-builder/master/userspace/home/.tmux.conf && \
curl -O https://github.com/commaai/agnos-builder/blob/master/userspace/home/.vimrc curl -O https://github.com/commaai/agnos-builder/blob/master/userspace/home/.vimrc
ENV CARLA_HOST="host.docker.internal"

@ -18,7 +18,8 @@
"--volume=${localEnv:HOME}/.comma:/root/.comma", "--volume=${localEnv:HOME}/.comma:/root/.comma",
"--volume=/tmp/comma_download_cache:/tmp/comma_download_cache", "--volume=/tmp/comma_download_cache:/tmp/comma_download_cache",
"--volume=/tmp/devcontainer_scons_cache:/tmp/scons_cache", "--volume=/tmp/devcontainer_scons_cache:/tmp/scons_cache",
"--shm-size=1G" "--shm-size=1G",
"--add-host=host.docker.internal:host-gateway" // required to use host.docker.internal on linux
], ],
"customizations": { "customizations": {
"vscode": { "vscode": {

@ -70,7 +70,10 @@ jobs:
build: build:
strategy: strategy:
matrix: matrix:
arch: ${{ fromJson( (github.repository == 'commaai/openpilot') && '["x86_64", "aarch64"]' || '["x86_64"]' ) }} arch: ${{ fromJson(
((github.repository == 'commaai/openpilot') &&
((github.event_name != 'pull_request') ||
(github.event.pull_request.head.repo.full_name == 'commaai/openpilot'))) && '["x86_64", "aarch64"]' || '["x86_64"]' ) }}
runs-on: ${{ (matrix.arch == 'aarch64') && 'buildjet-2vcpu-ubuntu-2204-arm' || 'ubuntu-20.04' }} runs-on: ${{ (matrix.arch == 'aarch64') && 'buildjet-2vcpu-ubuntu-2204-arm' || 'ubuntu-20.04' }}
steps: steps:
- uses: actions/checkout@v3 - uses: actions/checkout@v3
@ -277,7 +280,9 @@ jobs:
process_replay: process_replay:
name: process replay name: process replay
runs-on: ${{ ((github.event.pull_request.head.repo.full_name == 'commaai/openpilot') || (github.repository == 'commaai/openpilot')) && 'buildjet-8vcpu-ubuntu-2004' || 'ubuntu-20.04' }} runs-on: ${{ ((github.repository == 'commaai/openpilot') &&
((github.event_name != 'pull_request') ||
(github.event.pull_request.head.repo.full_name == 'commaai/openpilot'))) && 'buildjet-8vcpu-ubuntu-2004' || 'ubuntu-20.04' }}
steps: steps:
- uses: actions/checkout@v3 - uses: actions/checkout@v3
with: with:

@ -10,6 +10,7 @@ repos:
- id: check-ast - id: check-ast
exclude: '^(third_party)/' exclude: '^(third_party)/'
- id: check-json - id: check-json
exclude: '.devcontainer/devcontainer.json' # this supports JSON with comments
- id: check-toml - id: check-toml
- id: check-xml - id: check-xml
- id: check-yaml - id: check-yaml

@ -69,3 +69,7 @@ def with_processes(processes, init_time=0, ignore_stopped=None):
return wrap return wrap
return wrapper return wrapper
def noop(*args, **kwargs):
pass

@ -3,6 +3,7 @@ import unittest
from unittest.mock import patch from unittest.mock import patch
from openpilot.common.params import Params from openpilot.common.params import Params
from openpilot.selfdrive.test.helpers import noop
from openpilot.selfdrive.thermald.power_monitoring import PowerMonitoring, CAR_BATTERY_CAPACITY_uWh, \ from openpilot.selfdrive.thermald.power_monitoring import PowerMonitoring, CAR_BATTERY_CAPACITY_uWh, \
CAR_CHARGING_RATE_W, VBATT_PAUSE_CHARGING, DELAY_SHUTDOWN_TIME_S CAR_CHARGING_RATE_W, VBATT_PAUSE_CHARGING, DELAY_SHUTDOWN_TIME_S
@ -25,6 +26,7 @@ def pm_patch(name, value, constant=False):
@patch("time.monotonic", new=mock_time_monotonic) @patch("time.monotonic", new=mock_time_monotonic)
@patch("openpilot.selfdrive.thermald.power_monitoring.put_nonblocking", new=noop) # TODO: Remove this once nonblocking params are safer
class TestPowerMonitoring(unittest.TestCase): class TestPowerMonitoring(unittest.TestCase):
def setUp(self): def setUp(self):
self.params = Params() self.params = Params()

@ -171,15 +171,15 @@
</message> </message>
<message> <message>
<source>Reset Calibration</source> <source>Reset Calibration</source>
<translation></translation> <translation></translation>
</message> </message>
<message> <message>
<source>RESET</source> <source>RESET</source>
<translation></translation> <translation></translation>
</message> </message>
<message> <message>
<source>Are you sure you want to reset calibration?</source> <source>Are you sure you want to reset calibration?</source>
<translation></translation> <translation></translation>
</message> </message>
<message> <message>
<source>Review Training Guide</source> <source>Review Training Guide</source>
@ -227,7 +227,7 @@
</message> </message>
<message> <message>
<source>openpilot requires the device to be mounted within 4° left or right and within 5° up or 8° down. openpilot is continuously calibrating, resetting is rarely required.</source> <source>openpilot requires the device to be mounted within 4° left or right and within 5° up or 8° down. openpilot is continuously calibrating, resetting is rarely required.</source>
<translation>openpilot 4° 5° 8° </translation> <translation>openpilot 4° 5° 8° </translation>
</message> </message>
<message> <message>
<source> Your device is pointed %1° %2 and %3° %4.</source> <source> Your device is pointed %1° %2 and %3° %4.</source>
@ -290,7 +290,7 @@
</message> </message>
<message> <message>
<source>PAST WEEK</source> <source>PAST WEEK</source>
<translation></translation> <translation></translation>
</message> </message>
<message> <message>
<source>KM</source> <source>KM</source>
@ -369,7 +369,7 @@
<name>MapWindow</name> <name>MapWindow</name>
<message> <message>
<source>Map Loading</source> <source>Map Loading</source>
<translation></translation> <translation></translation>
</message> </message>
<message> <message>
<source>Waiting for GPS</source> <source>Waiting for GPS</source>
@ -452,11 +452,11 @@
</message> </message>
<message> <message>
<source>openpilot was unable to identify your car. Your car is either unsupported or its ECUs are not recognized. Please submit a pull request to add the firmware versions to the proper vehicle. Need help? Join discord.comma.ai.</source> <source>openpilot was unable to identify your car. Your car is either unsupported or its ECUs are not recognized. Please submit a pull request to add the firmware versions to the proper vehicle. Need help? Join discord.comma.ai.</source>
<translation>openpilot (ECU) Pull Request discord.comma.ai </translation> <translation>openpilot (ECU) Pull Request discord.comma.ai </translation>
</message> </message>
<message> <message>
<source>openpilot was unable to identify your car. Check integrity of cables and ensure all connections are secure, particularly that the comma power is fully inserted in the OBD-II port of the vehicle. Need help? Join discord.comma.ai.</source> <source>openpilot was unable to identify your car. Check integrity of cables and ensure all connections are secure, particularly that the comma power is fully inserted in the OBD-II port of the vehicle. Need help? Join discord.comma.ai.</source>
<translation>openpilot comma power OBD-II discord.comma.ai </translation> <translation>openpilot comma power OBD-II discord.comma.ai </translation>
</message> </message>
<message> <message>
<source>openpilot detected a change in the device&apos;s mounting position. Ensure the device is fully seated in the mount and the mount is firmly secured to the windshield.</source> <source>openpilot detected a change in the device&apos;s mounting position. Ensure the device is fully seated in the mount and the mount is firmly secured to the windshield.</source>
@ -498,7 +498,7 @@
</message> </message>
<message> <message>
<source>Bookmark connect.comma.ai to your home screen to use it like an app</source> <source>Bookmark connect.comma.ai to your home screen to use it like an app</source>
<translation> connect.comma.ai 便 App 使</translation> <translation> connect.comma.ai 便 App 使</translation>
</message> </message>
</context> </context>
<context> <context>
@ -528,7 +528,7 @@
</message> </message>
<message> <message>
<source>Remote access</source> <source>Remote access</source>
<translation></translation> <translation></translation>
</message> </message>
<message> <message>
<source>24/7 LTE connectivity</source> <source>24/7 LTE connectivity</source>
@ -611,15 +611,15 @@
<name>Reset</name> <name>Reset</name>
<message> <message>
<source>Reset failed. Reboot to try again.</source> <source>Reset failed. Reboot to try again.</source>
<translation></translation> <translation></translation>
</message> </message>
<message> <message>
<source>Are you sure you want to reset your device?</source> <source>Are you sure you want to reset your device?</source>
<translation></translation> <translation></translation>
</message> </message>
<message> <message>
<source>System Reset</source> <source>System Reset</source>
<translation></translation> <translation></translation>
</message> </message>
<message> <message>
<source>Cancel</source> <source>Cancel</source>
@ -644,7 +644,7 @@
<message> <message>
<source>Resetting device... <source>Resetting device...
This may take up to a minute.</source> This may take up to a minute.</source>
<translation> <translation>
</translation> </translation>
</message> </message>
</context> </context>
@ -699,7 +699,7 @@ This may take up to a minute.</source>
</message> </message>
<message> <message>
<source>Connect to Wi-Fi</source> <source>Connect to Wi-Fi</source>
<translation></translation> <translation></translation>
</message> </message>
<message> <message>
<source>Back</source> <source>Back</source>
@ -719,7 +719,7 @@ This may take up to a minute.</source>
</message> </message>
<message> <message>
<source>for Custom Software</source> <source>for Custom Software</source>
<translation></translation> <translation></translation>
</message> </message>
<message> <message>
<source>Downloading...</source> <source>Downloading...</source>
@ -829,27 +829,27 @@ This may take up to a minute.</source>
</message> </message>
<message> <message>
<source>Wi-Fi</source> <source>Wi-Fi</source>
<translation type="unfinished"></translation> <translation>Wi-Fi</translation>
</message> </message>
<message> <message>
<source>ETH</source> <source>ETH</source>
<translation type="unfinished"></translation> <translation>ETH</translation>
</message> </message>
<message> <message>
<source>2G</source> <source>2G</source>
<translation type="unfinished"></translation> <translation>2G</translation>
</message> </message>
<message> <message>
<source>3G</source> <source>3G</source>
<translation type="unfinished"></translation> <translation>3G</translation>
</message> </message>
<message> <message>
<source>LTE</source> <source>LTE</source>
<translation type="unfinished"></translation> <translation>LTE</translation>
</message> </message>
<message> <message>
<source>5G</source> <source>5G</source>
<translation type="unfinished"></translation> <translation>5G</translation>
</message> </message>
</context> </context>
<context> <context>
@ -931,11 +931,11 @@ This may take up to a minute.</source>
<name>SshControl</name> <name>SshControl</name>
<message> <message>
<source>SSH Keys</source> <source>SSH Keys</source>
<translation>SSH </translation> <translation>SSH </translation>
</message> </message>
<message> <message>
<source>Warning: This grants SSH access to all public keys in your GitHub settings. Never enter a GitHub username other than your own. A comma employee will NEVER ask you to add their GitHub username.</source> <source>Warning: This grants SSH access to all public keys in your GitHub settings. Never enter a GitHub username other than your own. A comma employee will NEVER ask you to add their GitHub username.</source>
<translation> GitHub SSH GitHub comma GitHub </translation> <translation> GitHub SSH GitHub 使comma GitHub 使</translation>
</message> </message>
<message> <message>
<source>ADD</source> <source>ADD</source>
@ -943,7 +943,7 @@ This may take up to a minute.</source>
</message> </message>
<message> <message>
<source>Enter your GitHub username</source> <source>Enter your GitHub username</source>
<translation> GitHub </translation> <translation> GitHub 使</translation>
</message> </message>
<message> <message>
<source>LOADING</source> <source>LOADING</source>
@ -955,7 +955,7 @@ This may take up to a minute.</source>
</message> </message>
<message> <message>
<source>Username &apos;%1&apos; has no keys on GitHub</source> <source>Username &apos;%1&apos; has no keys on GitHub</source>
<translation>GitHub &apos;%1&apos; </translation> <translation>GitHub &apos;%1&apos; </translation>
</message> </message>
<message> <message>
<source>Request timed out</source> <source>Request timed out</source>
@ -1024,7 +1024,7 @@ This may take up to a minute.</source>
</message> </message>
<message> <message>
<source>Upload data from the driver facing camera and help improve the driver monitoring algorithm.</source> <source>Upload data from the driver facing camera and help improve the driver monitoring algorithm.</source>
<translation></translation> <translation></translation>
</message> </message>
<message> <message>
<source>Disengage on Accelerator Pedal</source> <source>Disengage on Accelerator Pedal</source>
@ -1080,7 +1080,7 @@ This may take up to a minute.</source>
</message> </message>
<message> <message>
<source>WARNING: openpilot longitudinal control is in alpha for this car and will disable Automatic Emergency Braking (AEB).</source> <source>WARNING: openpilot longitudinal control is in alpha for this car and will disable Automatic Emergency Braking (AEB).</source>
<translation> openpilot Alpha 使AEB</translation> <translation> openpilot Alpha 使AEB</translation>
</message> </message>
<message> <message>
<source>On this car, openpilot defaults to the car&apos;s built-in ACC instead of openpilot&apos;s longitudinal control. Enable this to switch to openpilot longitudinal control. Enabling Experimental mode is recommended when enabling openpilot longitudinal control alpha.</source> <source>On this car, openpilot defaults to the car&apos;s built-in ACC instead of openpilot&apos;s longitudinal control. Enable this to switch to openpilot longitudinal control. Enabling Experimental mode is recommended when enabling openpilot longitudinal control alpha.</source>
@ -1124,11 +1124,11 @@ This may take up to a minute.</source>
</message> </message>
<message> <message>
<source>When navigation has a destination, openpilot will input the map information into the model. This provides useful context for the model and allows openpilot to keep left or right appropriately at forks/exits. Lane change behavior is unchanged and still activated by the driver. This is an alpha quality feature; mistakes should be expected, particularly around exits and forks. These mistakes can include unintended laneline crossings, late exit taking, driving towards dividing barriers in the gore areas, etc.</source> <source>When navigation has a destination, openpilot will input the map information into the model. This provides useful context for the model and allows openpilot to keep left or right appropriately at forks/exits. Lane change behavior is unchanged and still activated by the driver. This is an alpha quality feature; mistakes should be expected, particularly around exits and forks. These mistakes can include unintended laneline crossings, late exit taking, driving towards dividing barriers in the gore areas, etc.</source>
<translation>openpilot 使 openpilot / Alpha </translation> <translation>openpilot 使 openpilot / Alpha </translation>
</message> </message>
<message> <message>
<source>The driving visualization will transition to the road-facing wide-angle camera at low speeds to better show some turns. The Experimental mode logo will also be shown in the top right corner. When a navigation destination is set and the driving model is using it as input, the driving path on the map will turn green.</source> <source>The driving visualization will transition to the road-facing wide-angle camera at low speeds to better show some turns. The Experimental mode logo will also be shown in the top right corner. When a navigation destination is set and the driving model is using it as input, the driving path on the map will turn green.</source>
<translation></translation> <translation></translation>
</message> </message>
</context> </context>
<context> <context>
@ -1143,7 +1143,7 @@ This may take up to a minute.</source>
</message> </message>
<message> <message>
<source>Connect to Wi-Fi</source> <source>Connect to Wi-Fi</source>
<translation></translation> <translation></translation>
</message> </message>
<message> <message>
<source>Install</source> <source>Install</source>

@ -19,7 +19,7 @@ from openpilot.tools.sim.lib.simulated_sensors import SimulatedSensors
def rk_loop(function, hz, exit_event: threading.Event): def rk_loop(function, hz, exit_event: threading.Event):
rk = Ratekeeper(hz) rk = Ratekeeper(hz, None)
while not exit_event.is_set(): while not exit_event.is_set():
function() function()
rk.keep_time() rk.keep_time()

@ -0,0 +1,156 @@
import math
import numpy as np
import time
from openpilot.tools.sim.bridge.common import World, SimulatorBridge
from openpilot.tools.sim.lib.common import vec3, SimulatorState
from openpilot.tools.sim.lib.camerad import W, H
def apply_metadrive_patches():
from metadrive.engine.core.engine_core import EngineCore
from metadrive.engine.core.image_buffer import ImageBuffer
from metadrive.obs.image_obs import ImageObservation
# By default, metadrive won't try to use cuda images unless it's used as a sensor for vehicles, so patch that in
def add_image_sensor_patched(self, name: str, cls, args):
if self.global_config["image_on_cuda"]:# and name == self.global_config["vehicle_config"]["image_source"]:
sensor = cls(*args, self, cuda=True)
else:
sensor = cls(*args, self, cuda=False)
assert isinstance(sensor, ImageBuffer), "This API is for adding image sensor"
self.sensors[name] = sensor
EngineCore.add_image_sensor = add_image_sensor_patched
# we aren't going to use the built-in observation stack, so disable it to save time
def observe_patched(self, vehicle):
return self.state
ImageObservation.observe = observe_patched
class MetaDriveWorld(World):
def __init__(self, env, ticks_per_frame: float, dual_camera = False):
super().__init__(dual_camera)
self.env = env
self.ticks_per_frame = ticks_per_frame
self.dual_camera = dual_camera
self.steer_ratio = 15
self.vc = [0.0,0.0]
self.reset_time = 0
def get_cam_as_rgb(self, cam):
cam = self.env.engine.sensors[cam]
img = cam.perceive(self.env.vehicle, clip=False)
if type(img) != np.ndarray:
img = img.get() # convert cupy array to numpy
return img
def apply_controls(self, steer_angle, throttle_out, brake_out):
steer_metadrive = steer_angle * 1 / (self.env.vehicle.MAX_STEERING * self.steer_ratio)
steer_metadrive = np.clip(steer_metadrive, -1, 1)
if (time.monotonic() - self.reset_time) > 5:
self.vc[0] = steer_metadrive
if throttle_out:
self.vc[1] = throttle_out/10
else:
self.vc[1] = -brake_out
else:
self.vc[0] = 0
self.vc[1] = 0
def read_sensors(self, state: SimulatorState):
state.velocity = vec3(x=float(self.env.vehicle.velocity[0]), y=float(self.env.vehicle.velocity[1]), z=0)
state.gps.from_xy(self.env.vehicle.position)
state.bearing = float(math.degrees(self.env.vehicle.heading_theta))
state.steering_angle = self.env.vehicle.steering * self.env.vehicle.MAX_STEERING
state.valid = True
def read_cameras(self):
if self.dual_camera:
self.wide_road_image = self.get_cam_as_rgb("rgb_wide")
self.road_image = self.get_cam_as_rgb("rgb_road")
def tick(self):
obs, _, terminated, _, info = self.env.step(self.vc)
if terminated:
self.env.reset()
self.reset_time = time.monotonic()
def close(self):
pass
class MetaDriveBridge(SimulatorBridge):
TICKS_PER_FRAME = 2
def __init__(self, args):
self.should_render = False
super(MetaDriveBridge, self).__init__(args)
def spawn_world(self):
print("----------------------------------------------------------")
print("---- Spawning Metadrive world, this might take awhile ----")
print("----------------------------------------------------------")
from metadrive.component.sensors.rgb_camera import RGBCamera
from metadrive.component.sensors.base_camera import _cuda_enable
from metadrive.envs.metadrive_env import MetaDriveEnv
from panda3d.core import Vec3
apply_metadrive_patches()
C3_POSITION = Vec3(0, 0, 1)
class RGBCameraWide(RGBCamera):
def __init__(self, *args, **kwargs):
super(RGBCameraWide, self).__init__(*args, **kwargs)
cam = self.get_cam()
cam.setPos(C3_POSITION)
lens = self.get_lens()
lens.setFov(160)
class RGBCameraRoad(RGBCamera):
def __init__(self, *args, **kwargs):
super(RGBCameraRoad, self).__init__(*args, **kwargs)
cam = self.get_cam()
cam.setPos(C3_POSITION)
lens = self.get_lens()
lens.setFov(40)
sensors = {
"rgb_road": (RGBCameraRoad, W, H, )
}
if self.dual_camera:
sensors["rgb_wide"] = (RGBCameraWide, W, H)
env = MetaDriveEnv(
dict(
use_render=self.should_render,
vehicle_config=dict(
enable_reverse=False,
image_source="rgb_road",
spawn_longitude=15
),
sensors=sensors,
image_on_cuda=_cuda_enable,
image_observation=True,
interface_panel=[],
out_of_route_done=False,
on_continuous_line_done=False,
crash_vehicle_done=False,
crash_object_done=False,
)
)
env.reset()
return MetaDriveWorld(env, self.TICKS_PER_FRAME)

@ -107,6 +107,8 @@ class SimulatedCar:
def update(self, simulator_state: SimulatorState): def update(self, simulator_state: SimulatorState):
self.send_can_messages(simulator_state) self.send_can_messages(simulator_state)
self.send_panda_state(simulator_state)
if self.idx % 50 == 0: # only send panda states at 2hz
self.send_panda_state(simulator_state)
self.idx += 1 self.idx += 1

@ -1,11 +1,13 @@
#!/usr/bin/env python #!/usr/bin/env python
import argparse import argparse
import os
from typing import Any from typing import Any
from multiprocessing import Queue from multiprocessing import Queue
from openpilot.tools.sim.bridge.common import SimulatorBridge from openpilot.tools.sim.bridge.common import SimulatorBridge
from openpilot.tools.sim.bridge.carla import CarlaBridge from openpilot.tools.sim.bridge.carla import CarlaBridge
from openpilot.tools.sim.bridge.metadrive import MetaDriveBridge
def parse_args(add_args=None): def parse_args(add_args=None):
@ -18,7 +20,7 @@ def parse_args(add_args=None):
# Carla specific # Carla specific
parser.add_argument('--town', type=str, default='Town04_Opt') parser.add_argument('--town', type=str, default='Town04_Opt')
parser.add_argument('--spawn_point', dest='num_selected_spawn_point', type=int, default=16) parser.add_argument('--spawn_point', dest='num_selected_spawn_point', type=int, default=16)
parser.add_argument('--host', dest='host', type=str, default='127.0.0.1') parser.add_argument('--host', dest='host', type=str, default=os.environ.get("CARLA_HOST", '127.0.0.1'))
parser.add_argument('--port', dest='port', type=int, default=2000) parser.add_argument('--port', dest='port', type=int, default=2000)
return parser.parse_args(add_args) return parser.parse_args(add_args)
@ -30,6 +32,8 @@ if __name__ == "__main__":
simulator_bridge: SimulatorBridge simulator_bridge: SimulatorBridge
if args.simulator == "carla": if args.simulator == "carla":
simulator_bridge = CarlaBridge(args) simulator_bridge = CarlaBridge(args)
elif args.simulator == "metadrive":
simulator_bridge = MetaDriveBridge(args)
else: else:
raise AssertionError("simulator type not supported") raise AssertionError("simulator type not supported")
p = simulator_bridge.run(q) p = simulator_bridge.run(q)

@ -0,0 +1,43 @@
#!/usr/bin/env python3
import subprocess
import time
import unittest
from openpilot.selfdrive.manager.helpers import unblock_stdout
from openpilot.tools.sim.run_bridge import parse_args
from openpilot.tools.sim.bridge.carla import CarlaBridge
from openpilot.tools.sim.tests.test_sim_bridge import SIM_DIR, TestSimBridgeBase
class TestCarlaBridge(TestSimBridgeBase):
"""
Tests need Carla simulator to run
"""
carla_process = None
def setUp(self):
super().setUp()
# We want to make sure that carla_sim docker isn't still running.
subprocess.run("docker rm -f carla_sim", shell=True, stderr=subprocess.PIPE, check=False)
self.carla_process = subprocess.Popen("./start_carla.sh", cwd=SIM_DIR)
# Too many lagging messages in bridge.py can cause a crash. This prevents it.
unblock_stdout()
# Wait 10 seconds to startup carla
time.sleep(10)
def create_bridge(self):
return CarlaBridge(parse_args([]))
def tearDown(self):
super().tearDown()
# Stop carla simulator by removing docker container
subprocess.run("docker rm -f carla_sim", shell=True, stderr=subprocess.PIPE, check=False)
if self.carla_process is not None:
self.carla_process.wait()
if __name__ == "__main__":
unittest.main()

@ -0,0 +1,15 @@
#!/usr/bin/env python3
import unittest
from openpilot.tools.sim.run_bridge import parse_args
from openpilot.tools.sim.bridge.metadrive import MetaDriveBridge
from openpilot.tools.sim.tests.test_sim_bridge import TestSimBridgeBase
class TestMetaDriveBridge(TestSimBridgeBase):
def create_bridge(self):
return MetaDriveBridge(parse_args([]))
if __name__ == "__main__":
unittest.main()

@ -1,40 +1,24 @@
#!/usr/bin/env python3 import os
import subprocess import subprocess
import time import time
import unittest import unittest
import os
from multiprocessing import Queue from multiprocessing import Queue
from cereal import messaging from cereal import messaging
from openpilot.common.basedir import BASEDIR from openpilot.common.basedir import BASEDIR
from openpilot.selfdrive.manager.helpers import unblock_stdout
from openpilot.tools.sim.run_bridge import parse_args
from openpilot.tools.sim.bridge.carla import CarlaBridge
CI = "CI" in os.environ
SIM_DIR = os.path.join(BASEDIR, "tools/sim") SIM_DIR = os.path.join(BASEDIR, "tools/sim")
class TestCarlaIntegration(unittest.TestCase): class TestSimBridgeBase(unittest.TestCase):
""" @classmethod
Tests need Carla simulator to run def setUpClass(cls):
""" if cls is TestSimBridgeBase:
processes = None raise unittest.SkipTest("Don't run this base class, run test_carla_bridge.py instead")
carla_process = None
def setUp(self): def setUp(self):
self.processes = [] self.processes = []
if not CI:
# We want to make sure that carla_sim docker isn't still running.
subprocess.run("docker rm -f carla_sim", shell=True, stderr=subprocess.PIPE, check=False)
self.carla_process = subprocess.Popen("./start_carla.sh", cwd=SIM_DIR)
# Too many lagging messages in bridge.py can cause a crash. This prevents it.
unblock_stdout()
# Wait 10 seconds to startup carla
time.sleep(10)
def test_engage(self): def test_engage(self):
# Startup manager and bridge.py. Check processes are running, then engage and verify. # Startup manager and bridge.py. Check processes are running, then engage and verify.
p_manager = subprocess.Popen("./launch_openpilot.sh", cwd=SIM_DIR) p_manager = subprocess.Popen("./launch_openpilot.sh", cwd=SIM_DIR)
@ -42,7 +26,7 @@ class TestCarlaIntegration(unittest.TestCase):
sm = messaging.SubMaster(['controlsState', 'carEvents', 'managerState']) sm = messaging.SubMaster(['controlsState', 'carEvents', 'managerState'])
q = Queue() q = Queue()
carla_bridge = CarlaBridge(parse_args([])) carla_bridge = self.create_bridge()
p_bridge = carla_bridge.run(q, retries=10) p_bridge = carla_bridge.run(q, retries=10)
self.processes.append(p_bridge) self.processes.append(p_bridge)
@ -99,11 +83,6 @@ class TestCarlaIntegration(unittest.TestCase):
else: else:
p.join(15) p.join(15)
# Stop carla simulator by removing docker container
subprocess.run("docker rm -f carla_sim", shell=True, stderr=subprocess.PIPE, check=False)
if self.carla_process is not None:
self.carla_process.wait()
if __name__ == "__main__": if __name__ == "__main__":
unittest.main() unittest.main()
Loading…
Cancel
Save