Skip to content
Draft
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
34 changes: 31 additions & 3 deletions src/osc_simulator/simulation/engine.py
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,18 @@ def __init__(
self.completed = False


class _PendingAction:
def __init__(
self,
event_state: _EventState,
event_key: str,
action_state: _ActionExecutionState,
) -> None:
self.event_state = event_state
self.event_key = event_key
self.action_state = action_state


class SimulationEngine:
"""Execute a :class:`~osc_simulator.parser.openscenario.Scenario`."""

Expand Down Expand Up @@ -121,6 +133,7 @@ def __init__(self, scenario: Scenario, step_size: float = 0.05) -> None:
self._completed_elements: set[str] = set()
self._storyboard_lookup = self._build_storyboard_lookup()
self._condition_prev_values: dict[int, bool] = {}
self._pending_actions: list[_PendingAction] = []

# ------------------------------------------------------------------
# Public
Expand All @@ -132,6 +145,7 @@ def run(self) -> Iterator[tuple[float, Any]]:
gt = self._build_ground_truth()
yield self._time, gt
self._advance()
self._apply_pending_actions()

# Emit final frame at stop time
yield self._time, self._build_ground_truth()
Expand Down Expand Up @@ -429,9 +443,7 @@ def _evaluate_maneuver(
for action in event.actions:
action_state = _ActionExecutionState(action, list(actors))
state.action_states.append(action_state)
action_state.started = True
self._apply_action(action, actors)
action_state.completed = self._is_action_completed(action, actors)
self._pending_actions.append(_PendingAction(state, event_key, action_state))
if not state.action_states or all(a.completed for a in state.action_states):
state.completed = True
self._completed_elements.add(event_key)
Expand All @@ -441,6 +453,8 @@ def _update_event_action_completion_states(self) -> None:
if not state.started or state.completed:
continue
for action_state in state.action_states:
if not action_state.started:
continue
if action_state.completed:
continue
action_state.completed = self._is_action_completed(
Expand All @@ -449,6 +463,20 @@ def _update_event_action_completion_states(self) -> None:
if all(a.completed for a in state.action_states):
state.completed = True

def _apply_pending_actions(self) -> None:
pending_actions = self._pending_actions
self._pending_actions = []
for pending in pending_actions:
action_state = pending.action_state
action_state.started = True
self._apply_action(action_state.action, action_state.actor_names)
action_state.completed = self._is_action_completed(
action_state.action, action_state.actor_names
)
if all(a.completed for a in pending.event_state.action_states):
pending.event_state.completed = True
self._completed_elements.add(pending.event_key)

def _story_key(self, story: Story) -> str:
return f"story:{story.name}"

Expand Down
Loading