Skip to content

Commit 0993e03

Browse files
Debug Overlay & Testing (#60)
* Debug overlay skeleton * Add colour to debug overlay * Debug state event handler done * Cleanup * Implemented Debug Overlay Signed-off-by: [ 大鳄 ] Asew <[email protected]> * Added deterministic execution Signed-off-by: [ 大鳄 ] Asew <[email protected]> * Merged DebugStateEventManager into EventManager by adding a broadcast function Signed-off-by: [ 大鳄 ] Asew <[email protected]> * Removed debug print Signed-off-by: [ 大鳄 ] Asew <[email protected]> * Optimise graphics testing to use debug overlay * Refactor last test * Polished tests Signed-off-by: [ 大鳄 ] Asew <[email protected]> * Reworked tests Signed-off-by: [ 大鳄 ] Asew <[email protected]> * Polished code & tests Signed-off-by: [ 大鳄 ] Asew <[email protected]> * Polished take_screenshot Signed-off-by: [ 大鳄 ] Asew <[email protected]> * Fixes to tests Signed-off-by: [ 大鳄 ] Asew <[email protected]> * Fixed save restore test Signed-off-by: [ 大鳄 ] Asew <[email protected]> Co-authored-by: Radina Milenkova <[email protected]>
1 parent 63534d1 commit 0993e03

27 files changed

+339
-200
lines changed

data/test/done.png

1.38 KB
Loading

data/test/initialised.png

1.91 KB
Loading

data/test/labyrinth_rrt_1.png

-218 KB
Binary file not shown.

src/algorithms/configuration/configuration.py

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,8 @@ class Configuration:
5656
load_simulator: bool
5757
clear_cache: bool
5858
num_dim: int
59+
map_name: Optional[str]
60+
algorithm_name: Optional[str]
5961

6062
def __init__(self) -> None:
6163
# Simulator settings
@@ -110,6 +112,9 @@ def __init__(self) -> None:
110112
from algorithms.algorithm_manager import AlgorithmManager
111113
self.algorithms = copy.deepcopy(AlgorithmManager.builtins)
112114

115+
self.map_name = None
116+
self.algorithm_name = None
117+
113118
# Simulator
114119
self.load_simulator = False
115120

src/main.py

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,9 @@
1616

1717
from panda3d.core import load_prc_file_data
1818
from screeninfo import get_monitors
19+
import torch
20+
import numpy as np
21+
import random
1922

2023
class MainRunner:
2124
main_services: Services
@@ -176,6 +179,11 @@ def configure_common(config, args) -> bool:
176179

177180
config.algorithms = algorithms
178181

182+
if args.deterministic:
183+
random.seed(args.std_random_seed)
184+
torch.manual_seed(args.torch_random_seed)
185+
np.random.seed(args.numpy_random_seed)
186+
179187
return True
180188

181189
def configure_and_run(args):
@@ -215,10 +223,16 @@ def main() -> bool:
215223

216224
# Miscellaneous
217225
parser.add_argument("--dims", type=int, help="[generator|analyzer] number of dimensions", default=3)
226+
218227
parser.add_argument("--algorithms", help="[visualiser|analyzer] algorithms to load (either built-in algorithm name or module file path)", nargs="+")
219228
parser.add_argument("--include-builtin-algorithms", action='store_true', help="include all builtin algorithms even when a custom list is provided via '--algorithms'")
220229
parser.add_argument("--list-algorithms", action="store_true", help="[visualiser|analyzer] output list of available built-in algorithms")
221230

231+
parser.add_argument("--deterministic", action='store_true', help="use pre-defined random seeds for deterministic exeuction")
232+
parser.add_argument("--std-random-seed", type=int, default=0, help="'random' module random number generator seed")
233+
parser.add_argument("--numpy-random-seed", type=int, default=0, help="'numpy' module random number generator seed")
234+
parser.add_argument("--torch-random-seed", type=int, default=0, help="'torch' module random number generator seed")
235+
222236
parser.add_argument("-d", "--debug", choices=['NONE', 'BASIC', 'LOW', 'MEDIUM', 'HIGH'], default='LOW', help="debug level when running, default is low")
223237

224238
args = parser.parse_args()

src/simulator/controllers/map/map_controller.py

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
from simulator.controllers.map.map_picker import MapPicker
88
from simulator.controllers.map.camera_controller import CameraController
99
from simulator.services.event_manager.events.take_map_screenshot_event import TakeMapScreenshotEvent
10+
from simulator.services.event_manager.events.state_running_event import StateRunningEvent
1011

1112
import math
1213
from typing import Optional
@@ -41,13 +42,17 @@ def right_click():
4142

4243
def set_view(i):
4344
self._services.state.view_idx = i
45+
46+
def compute_trace():
47+
self._services.ev_manager.broadcast(StateRunningEvent())
48+
self._model.compute_trace()
4449

4550
self.accept('mouse1', left_click)
4651
self.accept('mouse3', right_click)
47-
self.accept("t", lambda: self._model.compute_trace())
4852
self.accept("m", lambda: self._model.toggle_convert_map())
4953
self.accept("x", lambda: self._model.toggle_pause_algorithm())
5054
self.accept("o", lambda: self._services.ev_manager.post(TakeMapScreenshotEvent()))
55+
self.accept("t", compute_trace)
5156

5257
for i in range(6):
5358
self.accept(str(i+1), partial(set_view, i))

src/simulator/models/map_model.py

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,10 +11,17 @@
1111
from simulator.services.services import Services
1212
from simulator.services.timer import Timer
1313
from structures import Point
14+
from simulator.services.event_manager.events.state_done_event import StateDoneEvent
15+
from simulator.services.event_manager.events.state_terminated_event import StateTerminatedEvent
16+
from simulator.services.event_manager.events.state_entity_update_event import StateEntityUpdateEvent
17+
from simulator.services.event_manager.events.initialise_event import InitialiseEvent
18+
from simulator.services.event_manager.events.reinit_event import ReinitEvent
19+
1420

1521
class AlgorithmTerminated(Exception):
1622
pass
1723

24+
1825
class MapModel(Model):
1926
speed: int
2027
key_frame_is_paused: bool
@@ -72,10 +79,12 @@ def reset(self) -> None:
7279
def move(self, to: Point) -> None:
7380
self.reset()
7481
self._services.algorithm.map.move_agent(to, True)
82+
self._services.ev_manager.broadcast(StateEntityUpdateEvent())
7583

7684
def move_goal(self, to: Point) -> None:
7785
self.reset()
7886
self._services.algorithm.map.move(self._services.algorithm.map.goal, to, True)
87+
self._services.ev_manager.broadcast(StateEntityUpdateEvent())
7988

8089
def stop_algorithm(self) -> None:
8190
self.key_frame_is_paused = True
@@ -119,6 +128,7 @@ def compute_trace(self) -> None:
119128
self.reset()
120129

121130
def compute_wrapper() -> None:
131+
terminated = False
122132
self.key_frame_is_paused = False
123133
if self._services.settings.simulator_key_frame_speed > 0:
124134
self._services.algorithm.instance.set_condition(self.cv)
@@ -128,10 +138,14 @@ def compute_wrapper() -> None:
128138
except AlgorithmTerminated:
129139
self._services.debug.write("Terminated algorithm", DebugLevel.BASIC)
130140
self._services.ev_manager.post(KeyFrameEvent(refresh=True))
141+
terminated = True
131142
if self._services.settings.simulator_key_frame_speed == 0:
132143
# no animation hence there hasn't been a chance to render
133144
# the last state of the algorithm.
134145
self._services.ev_manager.post(KeyFrameEvent(refresh=True))
146+
147+
self._services.ev_manager.broadcast(StateTerminatedEvent() if terminated else StateDoneEvent())
148+
135149
with self.cv:
136150
self.last_thread = None
137151
self.cv.notify()

src/simulator/services/event_manager/event_manager.py

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,17 @@ def unregister_listener(self, listener: None) -> None:
5757

5858
if listener in self.__listeners.keys():
5959
del self.__listeners[listener]
60+
61+
def broadcast(self, event: Event) -> None:
62+
"""
63+
Broadcast an event to all listeners
64+
immediately.
65+
66+
:param event: The event to post
67+
"""
68+
69+
for listener in list(self.__listeners.keys()):
70+
listener.notify(event)
6071

6172
def post(self, event: Event) -> None:
6273
"""
@@ -82,8 +93,8 @@ def tick(self) -> None:
8293
"""
8394
for tick_listener in self.__tick_listeners.keys():
8495
tick_listener.tick()
96+
8597
# send all events
8698
while len(self.__event_queue) > 0:
8799
event = self.__event_queue.pop(0)
88-
for listener in list(self.__listeners.keys()):
89-
listener.notify(event)
100+
self.broadcast(event)
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
from simulator.services.event_manager.events.event import Event
2+
3+
4+
class StateDoneEvent(Event):
5+
def __init__(self) -> None:
6+
super().__init__("SetDone event", True)
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
from simulator.services.event_manager.events.event import Event
2+
3+
4+
class StateEntityUpdateEvent(Event):
5+
def __init__(self) -> None:
6+
super().__init__("SetRunning event", True)

0 commit comments

Comments
 (0)