Core Modules
BasePlugin
BasePlugin defines the required interface for all OpenRoadSim plugins.
Every plugin must inherit from this class and implement the following lifecycle methods: - on_init(): Called once at startup for initialization. - on_event(): Called when a subscribed event is published. - on_shutdown(): Called when the simulation ends.
Source code in core/base_plugin.py
25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 |
|
on_event(topic, data, timestamp)
Called when a relevant event is published on the EventBus.
Parameters:
Name | Type | Description | Default |
---|---|---|---|
topic
|
str
|
The topic of the event (e.g., "gps.set_location"). |
required |
data
|
dict
|
Parameters passed with the event. |
required |
timestamp
|
float
|
The simulation time when the event is triggered. |
required |
Source code in core/base_plugin.py
44 45 46 47 48 49 50 51 52 53 |
|
on_init(config)
Called once after the plugin is loaded.
Parameters:
Name | Type | Description | Default |
---|---|---|---|
config
|
dict
|
Optional configuration data (reserved for future use). |
required |
Source code in core/base_plugin.py
35 36 37 38 39 40 41 42 |
|
on_shutdown()
Called once at the end of the simulation to clean up resources.
Source code in core/base_plugin.py
55 56 57 58 59 |
|
ScenarioParser
ScenarioParser is responsible for reading YAML scenario files and converting them into a list of executable event dictionaries.
It supports: - Basic event steps with time, target, and action - Looping blocks to repeat steps with offsets - Variable injection (for future use) - Modular scenario imports
Source code in core/scenario_parser.py
28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 |
|
__init__(logger)
Initializes the parser with a logger.
Parameters:
Name | Type | Description | Default |
---|---|---|---|
logger
|
Logger
|
The logger instance used for output. |
required |
Source code in core/scenario_parser.py
40 41 42 43 44 45 46 47 48 |
|
load(path)
Loads and parses a scenario YAML file from disk.
Parameters:
Name | Type | Description | Default |
---|---|---|---|
path
|
str
|
Path to the scenario file. |
required |
Returns:
Type | Description |
---|---|
list[dict]
|
list[dict]: A sorted list of events (each with 'time', 'target', 'action', etc.) |
Source code in core/scenario_parser.py
50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 |
|
EventBus
EventBus is the central messaging system for OpenRoadSim. It handles publishing and subscribing of events between the ScenarioEngine and plugins.
Events are routed based on a topic string in the form 'target.action' (e.g., 'can.send', 'gps.update').
Source code in core/event_bus.py
27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 |
|
__init__(logger)
Initializes the EventBus.
Parameters:
Name | Type | Description | Default |
---|---|---|---|
logger
|
Logger
|
An instance of the project's logger to output debug/info messages. |
required |
Source code in core/event_bus.py
36 37 38 39 40 41 42 43 44 |
|
subscribe(topic, plugin)
Subscribes a plugin to a specific event topic.
Parameters:
Name | Type | Description | Default |
---|---|---|---|
topic
|
str
|
The event topic to listen for (e.g., "echo.say"). |
required |
plugin
|
BasePlugin
|
An instance of a plugin that implements on_event(). |
required |
Source code in core/event_bus.py
46 47 48 49 50 51 52 53 54 55 56 57 |
|
PluginManager
PluginManager is responsible for dynamically loading and managing simulation plugins.
It:
- Loads plugin metadata from each plugin's plugin.yaml
- Dynamically imports the plugin's main module (main.py
)
- Instantiates the plugin class
- Registers subscriptions with the EventBus
- Manages lifecycle hooks (init and shutdown)
Source code in core/plugin_manager.py
31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 |
|
__init__(logger, event_bus, plugin_dir='plugins')
Initializes the PluginManager.
Parameters:
Name | Type | Description | Default |
---|---|---|---|
logger
|
Logger
|
The logging utility instance. |
required |
event_bus
|
EventBus
|
The event dispatcher used to route plugin events. |
required |
plugin_dir
|
str
|
The directory path where plugins are located. |
'plugins'
|
Source code in core/plugin_manager.py
43 44 45 46 47 48 49 50 51 52 53 54 55 |
|
load_plugins()
Discovers, loads, and registers all plugins from the plugin directory.
- Validates that each plugin folder contains
plugin.yaml
andmain.py
. - Dynamically imports the plugin class defined in metadata (
entry_class
, defaults toPlugin
). - Calls each plugin's
on_init()
method. - Subscribes the plugin to topics defined in
plugin.yaml
(undersubscriptions
).
Source code in core/plugin_manager.py
57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 |
|
shutdown_plugins()
Gracefully shuts down all loaded plugins by calling their on_shutdown()
methods.
Logs any failures during shutdown.
Source code in core/plugin_manager.py
116 117 118 119 120 121 122 123 124 125 |
|
ScenarioEngine
ScenarioEngine is responsible for orchestrating the execution of simulation events according to their scheduled timestamps.
It reads a list of parsed scenario events and dispatches them via the EventBus to subscribed plugins in time-aligned order.
Source code in core/scenario_engine.py
27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 |
|
__init__(logger, event_bus)
Initializes the ScenarioEngine.
Parameters:
Name | Type | Description | Default |
---|---|---|---|
logger
|
Logger
|
Logger instance for outputting status and debug info. |
required |
event_bus
|
EventBus
|
Event bus for publishing events to plugins. |
required |
Source code in core/scenario_engine.py
36 37 38 39 40 41 42 43 44 45 46 |
|
run(events)
Executes a scenario by processing each event at its designated simulation time.
This function uses real wall-clock time to delay dispatch until the scheduled event['time']
.
Parameters:
Name | Type | Description | Default |
---|---|---|---|
events
|
list[dict]
|
List of events loaded from a scenario file. Each event must include 'time', 'target', 'action', and optional 'params'. |
required |
Source code in core/scenario_engine.py
48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 |
|
stop()
Stops the currently running scenario (typically via user interrupt).
Source code in core/scenario_engine.py
83 84 85 86 87 88 |
|
APIInterface
Singleton class providing a unified API for managing OpenRoadSim simulation lifecycle.
This class encapsulates scenario parsing, plugin management, engine execution, and result reporting. It is designed for use by both GUI and console tools.
Example usage
from core.api_interface import APIInterface api = APIInterface.get_instance(logger) api.load_scenario("scenarios/example.yaml") api.start()
Attributes:
Name | Type | Description |
---|---|---|
logger |
Logger
|
Logger used for output. |
plugin_dir |
str
|
Plugin folder path (defaults to 'plugins'). |
on_status |
callable
|
Optional callback for simulation status events. |
on_log |
callable
|
Optional callback for simulation log messages. |
Source code in core/api_interface.py
52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 |
|
get_instance(logger=None, plugin_dir='plugins')
classmethod
Retrieves the global singleton instance.
Parameters:
Name | Type | Description | Default |
---|---|---|---|
logger
|
Logger
|
Logger instance (required on first call). |
None
|
plugin_dir
|
str
|
Optional path to plugins folder. |
'plugins'
|
Returns:
Name | Type | Description |
---|---|---|
APIInterface |
Shared instance of the APIInterface. |
Source code in core/api_interface.py
75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 |
|
load_scenario(scenario_path)
Parses a YAML scenario file and prepares its events for execution.
Parameters:
Name | Type | Description | Default |
---|---|---|---|
scenario_path
|
str
|
Path to the scenario YAML file. |
required |
Returns:
Name | Type | Description |
---|---|---|
bool |
True if the scenario was successfully loaded. |
Raises:
Type | Description |
---|---|
ValueError
|
If no events are found in the scenario. |
Source code in core/api_interface.py
116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 |
|
start()
Starts the simulation in a background thread.
Loads plugins, begins execution of scenario events, and monitors progress.
Source code in core/api_interface.py
138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 |
|
stop()
Gracefully stops the currently running simulation.
Source code in core/api_interface.py
174 175 176 177 178 179 180 181 |
|