ADCS.flight_software.single_core.ttc_single_core module

class ADCS.flight_software.single_core.ttc_single_core.TTC_Single_Core(base_rate_hz, tasks, memory, debug=False)[source]

Bases: object

Single-core time-triggered cooperative scheduler with WCET-based accounting.

This class models a deterministic, non-preemptive, fixed-priority scheduler intended to represent a spacecraft flight computer executing a static set of periodic tasks on a single CPU core.

The scheduler operates on a fixed base frame of duration:

\[\Delta t = \frac{1}{f_{\text{base}}}\]

where \(f_{\text{base}}\) is the base scheduler frequency.

At the start of each frame:

  • The available CPU budget is reset to \(\Delta t\)

  • Tasks are evaluated in ascending priority order (lower numerical value means higher priority)

  • A task may execute at most once per release

  • If a task executes, it consumes exactly its WCET from the frame budget

The scheduler enforces the per-frame constraint:

\[\sum_{i \in \text{executed in frame}} C_i \le \Delta t\]

This model is especially suitable for:

  • Offline schedulability analysis

  • Deterministic unit testing

  • Worst-case execution modeling

  • TTC (Time-Triggered Cooperative) flight software architectures

Tasks are instances of Task and communicate via a shared memory dictionary.

Parameters:
  • base_rate_hz (float)

  • tasks (List[Task])

  • memory (dict)

  • debug (bool)

base_utilization_wcet()[source]

Compute total system utilization using WCET-based analysis.

Utilization is defined as the sum of each enabled task’s WCET divided by its period:

\[U = \sum_{i} \frac{C_i}{T_i}\]

where:

  • \(C_i\) is the WCET of task i

  • \(T_i\) is the period of task i

This metric provides a necessary but not sufficient condition for schedulability in TTC systems.

Returns:

Total WCET-based utilization.

Return type:

float

frame_budget_feasible_wcet()[source]

Perform a conservative per-frame feasibility check.

This method assumes all enabled tasks are released simultaneously and checks whether their combined WCET fits within a single base frame:

\[\sum_i C_i \le \Delta t\]

While pessimistic, this condition is useful as a fast sanity check during system design.

Returns:

True if the sum of WCETs fits within one base frame.

Return type:

bool

gantt_ascii(t0, t1, width=80)[source]

Generate an ASCII Gantt-style timeline of task execution.

Each line in the output corresponds to one base frame and shows how the frame’s CPU budget was consumed by tasks, in execution order. Tasks are represented by the first letter of their name.

The horizontal axis is normalized to the base frame duration \(\Delta t\).

Parameters:
  • t0 (float) – Start of the logical time window to display, in seconds.

  • t1 (float) – End of the logical time window to display, in seconds.

  • width (int) – Number of characters used to represent one base frame.

Returns:

Multi-line ASCII Gantt diagram.

Return type:

str

hyperperiod_s(max_den=10000)[source]

Compute the approximate hyperperiod of all enabled tasks.

The hyperperiod is the least common multiple (LCM) of all task periods. For real-valued periods, a rational approximation is used:

\[H = \operatorname{lcm}(T_1, T_2, \dots, T_n)\]

This value represents the time after which the task release pattern repeats exactly.

Parameters:

max_den (int) – Maximum denominator used when approximating periods as rational numbers.

Returns:

Hyperperiod in seconds.

Return type:

float

report()[source]

Generate a human-readable schedulability and execution report.

The report summarizes:

  • Base frame parameters

  • WCET-based utilization

  • Approximate hyperperiod

  • Mean and minimum slack

  • Per-task execution and miss statistics

This method relies on trace data generated by simulate().

Returns:

Multi-line formatted report string.

Return type:

str

reset_trace()[source]

Clear all recorded instrumentation data.

This method removes:

  • All per-frame FrameEvent records

  • All stored per-frame slack measurements

It does not reset task state, logical time, or scheduler configuration. This is typically called prior to a new simulation run.

Returns:

None

Return type:

None

simulate(duration_s, reset_trace=True)[source]

Simulate scheduler execution for a given logical duration.

The scheduler is stepped repeatedly until the specified duration is reached or exceeded. Instrumentation data is collected for analysis.

The number of frames executed is:

\[N = \left\lceil \frac{\text{duration}_s}{\Delta t} \right\rceil\]
Parameters:
  • duration_s (float) – Logical simulation duration in seconds.

  • reset_trace (bool) – If True, clears previously recorded trace data before simulation.

Returns:

None

Return type:

None

slack_stats()[source]

Compute slack statistics over all recorded base frames.

Slack is defined as the unused CPU budget at the end of a base frame:

\[S_k = \Delta t - \sum_{i \in \text{executed in frame } k} C_i\]

This method reports aggregate statistics over all simulated frames.

Returns:

Dictionary containing mean and minimum slack values in seconds.

Return type:

dict[str, float]

stats()[source]

Compute per-task execution statistics from the recorded trace.

Statistics are derived from all recorded FrameEvent entries and include both successful executions and missed executions due to insufficient CPU budget.

For each task, the following metrics are computed:

Key

Description

attempts

Number of frames in which the task was released

runs

Number of frames in which the task executed

misses

Number of released frames where it did not run

run_rate

Fraction of attempts that resulted in execution

Returns:

Dictionary keyed by task name containing execution statistics.

Return type:

dict[str, dict[str, float]]

step()[source]

Advance the scheduler by exactly one base frame.

This method performs one deterministic scheduling cycle:

  1. Reset CPU budget to the base frame duration

  2. Iterate through enabled tasks in priority order

  3. Check task release conditions

  4. Execute tasks while sufficient CPU budget remains

  5. Record WCET-based execution events

  6. Advance logical time by one base frame

If a task is released but insufficient CPU budget remains, the task is skipped for this frame without consuming its release. This behavior mirrors common TTC implementations.

Logical time is advanced as:

\[t_{\text{fsw}} \leftarrow t_{\text{fsw}} + \Delta t\]
Returns:

None

Return type:

None

timeline_dot(t0, t1)[source]

Generate a Graphviz DOT representation of the execution timeline.

Each base frame is represented as a node containing:

  • Frame start time

  • Executed tasks and their WCETs

  • Remaining slack for the frame

Frames are connected sequentially to form a left-to-right timeline. The resulting DOT source can be rendered using Graphviz tools.

Parameters:
  • t0 (float) – Start of the logical time window to include, in seconds.

  • t1 (float) – End of the logical time window to include, in seconds.

Returns:

Graphviz DOT source encoding the execution timeline.

Return type:

str

t_fsw

Logical flight software time [s]