STAR
Cal STAR — firmware, DAQ server, and engine design
Loading...
Searching...
No Matches
StateMachine.hpp
Go to the documentation of this file.
1#pragma once
2
3#include <cstdint>
4#include <map>
5#include <set>
6#include <string>
7#include <vector>
8
9namespace sequencer {
10
11/**
12 * System state IDs — must match the TypeScript SystemState enum in web-gui/shared/types.ts.
13 */
38
39/**
40 * Parses state_transitions.csv and validates state transitions.
41 * Thread-safe for concurrent reads after load().
42 */
44public:
45 /**
46 * Load from a state_transitions.csv file.
47 * Tries the given path, then a set of fallback paths.
48 * @return true on success.
49 */
50 bool load(const std::string& csv_path);
51
52 /**
53 * Returns true if transitioning from→to is allowed.
54 * In debug mode, always returns true.
55 */
56 bool isAllowed(State from, State to) const;
57
58 /**
59 * Returns the list of states reachable from the given state.
60 * In debug mode, returns all known states.
61 */
62 std::vector<State> allowedFrom(State state) const;
63
64 /**
65 * Returns a bitmask where bit N is set if state N is reachable from the given state.
66 * Used for the [0x50, 0x00] Elodin VTable payload.
67 */
68 uint32_t allowedBitmask(State state) const;
69
70 /**
71 * Adopt the [[states]] entries from a config as the source of truth for state names and
72 * semantics.
73 *
74 * This is an OVERRIDE LAYER, deliberately: anything the config does not mention keeps its
75 * built-in name and behaviour. The state list was duplicated in eight places across C++, the
76 * shared TS types, the backend and six frontend label maps, several already disagreeing (the
77 * top bar rendered GSE Abort and Emergency Abort as "STATE 18"/"STATE 19"). Config becomes the
78 * one place to edit, without a partial or missing [[states]] being able to erase the machine's
79 * knowledge of its own states.
80 *
81 * `id` is a stable key, not an ordering: it is written into Elodin run history as a raw u8
82 * with no name table beside it, so an id must keep meaning the same state. Reordering,
83 * renaming, adding and removing are all fine; reusing an id for a different state is not.
84 */
85 static void loadStatesFromConfig(const std::string& config_content);
86
87 /** True if the state carries the abort semantics (config `is_abort`, else the built-in trio).
88 */
89 static bool isAbort(State s);
90
91 /** The state to boot into (config `is_boot`, else Idle). */
92 static State bootState();
93
94 /** Translate a CSV name (e.g. "Emergency Abort") to a State. */
95 static State fromName(const std::string& name);
96
97 /** Human-readable name for a State (e.g. State::FIRE → "Fire"). */
98 static std::string name(State s);
99 /** Numeric id for a state name, or 255 if unknown. Lets a service that only needs the id
100 * (e.g. the controller's PWM gate) avoid carrying its own copy of the enum. */
101 static uint8_t stateId(const std::string& name) {
102 State s = fromName(name);
103 return static_cast<uint8_t>(s);
104 }
105
106 bool isLoaded() const {
107 return loaded_;
108 }
109
110private:
111 std::map<State, std::set<State>> transitions_;
112 bool loaded_{false};
113
114 static const std::map<std::string, State>& csvStateMap();
115};
116
117} // namespace sequencer
Parses state_transitions.csv and validates state transitions.
bool load(const std::string &csv_path)
Load from a state_transitions.csv file.
std::vector< State > allowedFrom(State state) const
Returns the list of states reachable from the given state.
static uint8_t stateId(const std::string &name)
Numeric id for a state name, or 255 if unknown.
static State fromName(const std::string &name)
Translate a CSV name (e.g.
static std::string name(State s)
Human-readable name for a State (e.g.
static const std::map< std::string, State > & csvStateMap()
uint32_t allowedBitmask(State state) const
Returns a bitmask where bit N is set if state N is reachable from the given state.
bool isAllowed(State from, State to) const
Returns true if transitioning from→to is allowed.
static State bootState()
The state to boot into (config is_boot, else Idle).
static void loadStatesFromConfig(const std::string &config_content)
Adopt the [[states]] entries from a config as the source of truth for state names and semantics.
static bool isAbort(State s)
True if the state carries the abort semantics (config is_abort, else the built-in trio).
std::map< State, std::set< State > > transitions_
static ActuatorControllerState state
Definition main.cpp:57
@ IDLE
Definition gnss_frame.c:6
State
System state IDs — must match the TypeScript SystemState enum in web-gui/shared/types....