From 0c512998d3bb6fe2d905c74f1d23acc12ebeaa29 Mon Sep 17 00:00:00 2001 From: bongbui321 Date: Thu, 11 Jan 2024 00:51:47 -0500 Subject: [PATCH 1/5] good? --- tools/sim/tests/test_sim_bridge.py | 34 +++++++++++++++++++++++++++++- 1 file changed, 33 insertions(+), 1 deletion(-) diff --git a/tools/sim/tests/test_sim_bridge.py b/tools/sim/tests/test_sim_bridge.py index 850fd83baca73a..68a289127291d6 100644 --- a/tools/sim/tests/test_sim_bridge.py +++ b/tools/sim/tests/test_sim_bridge.py @@ -72,6 +72,39 @@ def test_engage(self): break self.assertEqual(min_counts_control_active, control_active, f"Simulator did not engage a minimal of {min_counts_control_active} steps was {control_active}") + + def test_drive_course(self): + p_manager = subprocess.Popen("./launch_openpilot.sh", cwd=SIM_DIR) + self.processes.append(p_manager) + + sm = messaging.SubMaster(['controlsState', 'onroadEvents', 'managerState']) + q = Queue() + bridge = self.create_bridge() + bridge.started = Value('b', False) + p_bridge = bridge.run(q, retries=10) + self.processes.append(p_bridge) + + max_time_per_step = 60 + + start_waiting = time.monotonic() + while not bridge.started and time.monotonic() < start_waiting + max_time_per_step: + time.sleep(0.1) + self.assertEqual(p_bridge.exitcode, None, f"Bridge process should be running, but exited with code {p_bridge.exitcode}") + + start_time = time.monotonic() + user_disengage_once = False + disengage_events = ('stockAeb', 'fcw', 'ldw') + + while time.monotonic() < start_time + max_time_per_step: + sm.update() + + onroadEventNames = [e.name for e in sm['onroadEvents']] + + if any(e in onroadEventNames for e in disengage_events): + user_disengage_once = True + break + + self.assertFalse(user_disengage_once, "Failed because user has to disengage") def tearDown(self): print("Test shutting down. CommIssues are acceptable") @@ -84,6 +117,5 @@ def tearDown(self): else: p.join(15) - if __name__ == "__main__": unittest.main() From af77df09e02ee5a4c084b58f0863d22015a6d6cc Mon Sep 17 00:00:00 2001 From: bongbui321 Date: Thu, 11 Jan 2024 01:04:13 -0500 Subject: [PATCH 2/5] setup works --- tools/sim/tests/test_sim_bridge.py | 59 ++++++++++++------------------ 1 file changed, 23 insertions(+), 36 deletions(-) diff --git a/tools/sim/tests/test_sim_bridge.py b/tools/sim/tests/test_sim_bridge.py index 68a289127291d6..a27eca8422606f 100644 --- a/tools/sim/tests/test_sim_bridge.py +++ b/tools/sim/tests/test_sim_bridge.py @@ -9,6 +9,7 @@ from openpilot.common.basedir import BASEDIR SIM_DIR = os.path.join(BASEDIR, "tools/sim") +max_time_per_step = 60 class TestSimBridgeBase(unittest.TestCase): @classmethod @@ -17,39 +18,35 @@ def setUpClass(cls): raise unittest.SkipTest("Don't run this base class, run test_metadrive_bridge.py instead") def setUp(self): - self.processes = [] + self.p_manager = subprocess.Popen("./launch_openpilot.sh", cwd=SIM_DIR) + self.sm = messaging.SubMaster(['controlsState', 'onroadEvents', 'managerState']) + self.q = Queue() + self.bridge = self.create_bridge() + self.bridge.started = Value('b', False) + self.p_bridge = self.bridge.run(self.q, retries=10) + self.processes = [self.p_manager, self.p_bridge] def test_engage(self): # Startup manager and bridge.py. Check processes are running, then engage and verify. - p_manager = subprocess.Popen("./launch_openpilot.sh", cwd=SIM_DIR) - self.processes.append(p_manager) - - sm = messaging.SubMaster(['controlsState', 'onroadEvents', 'managerState']) - q = Queue() - bridge = self.create_bridge() - bridge.started = Value('b', False) - p_bridge = bridge.run(q, retries=10) - self.processes.append(p_bridge) - - max_time_per_step = 60 + self.q.put("reset") # Wait for bridge to startup start_waiting = time.monotonic() - while not bridge.started and time.monotonic() < start_waiting + max_time_per_step: + while not self.bridge.started and time.monotonic() < start_waiting + max_time_per_step: time.sleep(0.1) - self.assertEqual(p_bridge.exitcode, None, f"Bridge process should be running, but exited with code {p_bridge.exitcode}") + self.assertEqual(self.p_bridge.exitcode, None, f"Bridge process should be running, but exited with code {self.p_bridge.exitcode}") start_time = time.monotonic() no_car_events_issues_once = False car_event_issues = [] not_running = [] while time.monotonic() < start_time + max_time_per_step: - sm.update() + self.sm.update() - not_running = [p.name for p in sm['managerState'].processes if not p.running and p.shouldBeRunning] - car_event_issues = [event.name for event in sm['onroadEvents'] if any([event.noEntry, event.softDisable, event.immediateDisable])] + not_running = [p.name for p in self.sm['managerState'].processes if not p.running and p.shouldBeRunning] + car_event_issues = [event.name for event in self.sm['onroadEvents'] if any([event.noEntry, event.softDisable, event.immediateDisable])] - if sm.all_alive() and len(car_event_issues) == 0 and len(not_running) == 0: + if self.sm.all_alive() and len(car_event_issues) == 0 and len(not_running) == 0: no_car_events_issues_once = True break @@ -61,11 +58,11 @@ def test_engage(self): control_active = 0 while time.monotonic() < start_time + max_time_per_step: - sm.update() + self.sm.update() - q.put("cruise_down") # Try engaging + self.q.put("cruise_down") # Try engaging - if sm.all_alive() and sm['controlsState'].active: + if self.sm.all_alive() and self.sm['controlsState'].active: control_active += 1 if control_active == min_counts_control_active: @@ -74,31 +71,21 @@ def test_engage(self): self.assertEqual(min_counts_control_active, control_active, f"Simulator did not engage a minimal of {min_counts_control_active} steps was {control_active}") def test_drive_course(self): - p_manager = subprocess.Popen("./launch_openpilot.sh", cwd=SIM_DIR) - self.processes.append(p_manager) - - sm = messaging.SubMaster(['controlsState', 'onroadEvents', 'managerState']) - q = Queue() - bridge = self.create_bridge() - bridge.started = Value('b', False) - p_bridge = bridge.run(q, retries=10) - self.processes.append(p_bridge) - - max_time_per_step = 60 + self.q.put("reset") start_waiting = time.monotonic() - while not bridge.started and time.monotonic() < start_waiting + max_time_per_step: + while not self.bridge.started and time.monotonic() < start_waiting + max_time_per_step: time.sleep(0.1) - self.assertEqual(p_bridge.exitcode, None, f"Bridge process should be running, but exited with code {p_bridge.exitcode}") + self.assertEqual(self.p_bridge.exitcode, None, f"Bridge process should be running, but exited with code {self.p_bridge.exitcode}") start_time = time.monotonic() user_disengage_once = False disengage_events = ('stockAeb', 'fcw', 'ldw') while time.monotonic() < start_time + max_time_per_step: - sm.update() + self.sm.update() - onroadEventNames = [e.name for e in sm['onroadEvents']] + onroadEventNames = [e.name for e in self.sm['onroadEvents']] if any(e in onroadEventNames for e in disengage_events): user_disengage_once = True From 8faf3199d5778ab9e97981963b25b780da584851 Mon Sep 17 00:00:00 2001 From: bongbui321 Date: Thu, 11 Jan 2024 02:11:31 -0500 Subject: [PATCH 3/5] add change time --- tools/sim/tests/test_metadrive_bridge.py | 5 +++-- tools/sim/tests/test_sim_bridge.py | 25 ++++++++++-------------- 2 files changed, 13 insertions(+), 17 deletions(-) diff --git a/tools/sim/tests/test_metadrive_bridge.py b/tools/sim/tests/test_metadrive_bridge.py index 2c534656bb4c24..2d738bedf4bb15 100755 --- a/tools/sim/tests/test_metadrive_bridge.py +++ b/tools/sim/tests/test_metadrive_bridge.py @@ -1,15 +1,16 @@ #!/usr/bin/env python3 import unittest +import os from openpilot.tools.sim.run_bridge import parse_args from openpilot.tools.sim.bridge.metadrive.metadrive_bridge import MetaDriveBridge from openpilot.tools.sim.tests.test_sim_bridge import TestSimBridgeBase - class TestMetaDriveBridge(TestSimBridgeBase): + drive_time = 60 def create_bridge(self): return MetaDriveBridge(parse_args([])) - if __name__ == "__main__": + TestMetaDriveBridge.drive_time = int(os.getenv("DRIVE_TIME", TestMetaDriveBridge.drive_time)) unittest.main() diff --git a/tools/sim/tests/test_sim_bridge.py b/tools/sim/tests/test_sim_bridge.py index a27eca8422606f..2edf3d7313913d 100644 --- a/tools/sim/tests/test_sim_bridge.py +++ b/tools/sim/tests/test_sim_bridge.py @@ -9,13 +9,14 @@ from openpilot.common.basedir import BASEDIR SIM_DIR = os.path.join(BASEDIR, "tools/sim") -max_time_per_step = 60 + class TestSimBridgeBase(unittest.TestCase): @classmethod def setUpClass(cls): if cls is TestSimBridgeBase: raise unittest.SkipTest("Don't run this base class, run test_metadrive_bridge.py instead") + TestSimBridgeBase.drive_time = cls.drive_time if cls.drive_time else 60 def setUp(self): self.p_manager = subprocess.Popen("./launch_openpilot.sh", cwd=SIM_DIR) @@ -26,26 +27,25 @@ def setUp(self): self.p_bridge = self.bridge.run(self.q, retries=10) self.processes = [self.p_manager, self.p_bridge] - def test_engage(self): - # Startup manager and bridge.py. Check processes are running, then engage and verify. - self.q.put("reset") - # Wait for bridge to startup + start_up_max_time = 60 start_waiting = time.monotonic() - while not self.bridge.started and time.monotonic() < start_waiting + max_time_per_step: + while not self.bridge.started and time.monotonic() < start_waiting + start_up_max_time: time.sleep(0.1) self.assertEqual(self.p_bridge.exitcode, None, f"Bridge process should be running, but exited with code {self.p_bridge.exitcode}") + def test_engage(self): + # Startup manager and bridge.py. Check processes are running, then engage and verify. + max_time_per_step = 60 + start_time = time.monotonic() no_car_events_issues_once = False car_event_issues = [] not_running = [] while time.monotonic() < start_time + max_time_per_step: self.sm.update() - not_running = [p.name for p in self.sm['managerState'].processes if not p.running and p.shouldBeRunning] car_event_issues = [event.name for event in self.sm['onroadEvents'] if any([event.noEntry, event.softDisable, event.immediateDisable])] - if self.sm.all_alive() and len(car_event_issues) == 0 and len(not_running) == 0: no_car_events_issues_once = True break @@ -73,16 +73,11 @@ def test_engage(self): def test_drive_course(self): self.q.put("reset") - start_waiting = time.monotonic() - while not self.bridge.started and time.monotonic() < start_waiting + max_time_per_step: - time.sleep(0.1) - self.assertEqual(self.p_bridge.exitcode, None, f"Bridge process should be running, but exited with code {self.p_bridge.exitcode}") - start_time = time.monotonic() user_disengage_once = False - disengage_events = ('stockAeb', 'fcw', 'ldw') - while time.monotonic() < start_time + max_time_per_step: + disengage_events = ('stockAeb', 'fcw', 'ldw') + while time.monotonic() < start_time + TestSimBridgeBase.drive_time: self.sm.update() onroadEventNames = [e.name for e in self.sm['onroadEvents']] From 1612f8a0de0779c4c1523eab33a8825e4ba61fc2 Mon Sep 17 00:00:00 2001 From: bongbui321 Date: Thu, 11 Jan 2024 02:17:00 -0500 Subject: [PATCH 4/5] drive course with customizable time --- tools/sim/tests/test_sim_bridge.py | 29 +++++++++++------------------ 1 file changed, 11 insertions(+), 18 deletions(-) diff --git a/tools/sim/tests/test_sim_bridge.py b/tools/sim/tests/test_sim_bridge.py index 2edf3d7313913d..a5abf3371c975f 100644 --- a/tools/sim/tests/test_sim_bridge.py +++ b/tools/sim/tests/test_sim_bridge.py @@ -27,21 +27,23 @@ def setUp(self): self.p_bridge = self.bridge.run(self.q, retries=10) self.processes = [self.p_manager, self.p_bridge] - # Wait for bridge to startup - start_up_max_time = 60 - start_waiting = time.monotonic() - while not self.bridge.started and time.monotonic() < start_waiting + start_up_max_time: - time.sleep(0.1) - self.assertEqual(self.p_bridge.exitcode, None, f"Bridge process should be running, but exited with code {self.p_bridge.exitcode}") def test_engage(self): # Startup manager and bridge.py. Check processes are running, then engage and verify. + + # Wait for bridge to startup max_time_per_step = 60 + start_waiting = time.monotonic() + while not self.bridge.started and time.monotonic() < start_waiting + max_time_per_step: + time.sleep(0.1) + self.assertEqual(self.p_bridge.exitcode, None, f"Bridge process should be running, but exited with code {self.p_bridge.exitcode}") + start_time = time.monotonic() no_car_events_issues_once = False car_event_issues = [] not_running = [] + while time.monotonic() < start_time + max_time_per_step: self.sm.update() not_running = [p.name for p in self.sm['managerState'].processes if not p.running and p.shouldBeRunning] @@ -49,7 +51,6 @@ def test_engage(self): if self.sm.all_alive() and len(car_event_issues) == 0 and len(not_running) == 0: no_car_events_issues_once = True break - self.assertTrue(no_car_events_issues_once, f"Failed because no messages received, or CarEvents '{car_event_issues}' or processes not running '{not_running}'") @@ -59,33 +60,25 @@ def test_engage(self): while time.monotonic() < start_time + max_time_per_step: self.sm.update() - self.q.put("cruise_down") # Try engaging - if self.sm.all_alive() and self.sm['controlsState'].active: control_active += 1 - if control_active == min_counts_control_active: break - self.assertEqual(min_counts_control_active, control_active, f"Simulator did not engage a minimal of {min_counts_control_active} steps was {control_active}") - - def test_drive_course(self): - self.q.put("reset") + # Drive course + self.q.put("reset") start_time = time.monotonic() user_disengage_once = False - disengage_events = ('stockAeb', 'fcw', 'ldw') + while time.monotonic() < start_time + TestSimBridgeBase.drive_time: self.sm.update() - onroadEventNames = [e.name for e in self.sm['onroadEvents']] - if any(e in onroadEventNames for e in disengage_events): user_disengage_once = True break - self.assertFalse(user_disengage_once, "Failed because user has to disengage") def tearDown(self): From d870225af8b6596ccd0759629515e3f902d141d9 Mon Sep 17 00:00:00 2001 From: bongbui321 Date: Thu, 11 Jan 2024 02:32:01 -0500 Subject: [PATCH 5/5] restore starter --- tools/sim/tests/test_sim_bridge.py | 42 ++++++++++++++++-------------- 1 file changed, 22 insertions(+), 20 deletions(-) diff --git a/tools/sim/tests/test_sim_bridge.py b/tools/sim/tests/test_sim_bridge.py index a5abf3371c975f..2d37fbef7cad6d 100644 --- a/tools/sim/tests/test_sim_bridge.py +++ b/tools/sim/tests/test_sim_bridge.py @@ -19,25 +19,27 @@ def setUpClass(cls): TestSimBridgeBase.drive_time = cls.drive_time if cls.drive_time else 60 def setUp(self): - self.p_manager = subprocess.Popen("./launch_openpilot.sh", cwd=SIM_DIR) - self.sm = messaging.SubMaster(['controlsState', 'onroadEvents', 'managerState']) - self.q = Queue() - self.bridge = self.create_bridge() - self.bridge.started = Value('b', False) - self.p_bridge = self.bridge.run(self.q, retries=10) - self.processes = [self.p_manager, self.p_bridge] - + self.processes = [] def test_engage(self): # Startup manager and bridge.py. Check processes are running, then engage and verify. + p_manager = subprocess.Popen("./launch_openpilot.sh", cwd=SIM_DIR) + sm = messaging.SubMaster(['controlsState', 'onroadEvents', 'managerState']) + self.processes.append(p_manager) + + q = Queue() + bridge = self.create_bridge() + bridge.started = Value('b', False) + p_bridge = bridge.run(q, retries=10) + self.processes.append(p_bridge) # Wait for bridge to startup max_time_per_step = 60 start_waiting = time.monotonic() - while not self.bridge.started and time.monotonic() < start_waiting + max_time_per_step: + while not bridge.started and time.monotonic() < start_waiting + max_time_per_step: time.sleep(0.1) - self.assertEqual(self.p_bridge.exitcode, None, f"Bridge process should be running, but exited with code {self.p_bridge.exitcode}") + self.assertEqual(p_bridge.exitcode, None, f"Bridge process should be running, but exited with code {p_bridge.exitcode}") start_time = time.monotonic() no_car_events_issues_once = False @@ -45,10 +47,10 @@ def test_engage(self): not_running = [] while time.monotonic() < start_time + max_time_per_step: - self.sm.update() - not_running = [p.name for p in self.sm['managerState'].processes if not p.running and p.shouldBeRunning] - car_event_issues = [event.name for event in self.sm['onroadEvents'] if any([event.noEntry, event.softDisable, event.immediateDisable])] - if self.sm.all_alive() and len(car_event_issues) == 0 and len(not_running) == 0: + sm.update() + not_running = [p.name for p in sm['managerState'].processes if not p.running and p.shouldBeRunning] + car_event_issues = [event.name for event in sm['onroadEvents'] if any([event.noEntry, event.softDisable, event.immediateDisable])] + if sm.all_alive() and len(car_event_issues) == 0 and len(not_running) == 0: no_car_events_issues_once = True break self.assertTrue(no_car_events_issues_once, @@ -59,23 +61,23 @@ def test_engage(self): control_active = 0 while time.monotonic() < start_time + max_time_per_step: - self.sm.update() - self.q.put("cruise_down") # Try engaging - if self.sm.all_alive() and self.sm['controlsState'].active: + sm.update() + q.put("cruise_down") # Try engaging + if sm.all_alive() and sm['controlsState'].active: control_active += 1 if control_active == min_counts_control_active: break self.assertEqual(min_counts_control_active, control_active, f"Simulator did not engage a minimal of {min_counts_control_active} steps was {control_active}") # Drive course - self.q.put("reset") + q.put("reset") start_time = time.monotonic() user_disengage_once = False disengage_events = ('stockAeb', 'fcw', 'ldw') while time.monotonic() < start_time + TestSimBridgeBase.drive_time: - self.sm.update() - onroadEventNames = [e.name for e in self.sm['onroadEvents']] + sm.update() + onroadEventNames = [e.name for e in sm['onroadEvents']] if any(e in onroadEventNames for e in disengage_events): user_disengage_once = True break