1use serde::{Deserialize, Serialize};
2
3use crate::config::{AllocationStrategy, LIMB_COUNT};
4
5pub const LIMB_NAMES: [&str; LIMB_COUNT] = ["front_left", "front_right", "rear_left", "rear_right"];
6
7#[derive(Debug, Clone, Serialize, Deserialize)]
8pub struct SystemState {
9 pub time_s: f64,
10 pub ep_j: f64,
11 pub temperature_k: f64,
12 pub y_m: f64,
13 pub v_mps: f64,
14 pub local_buffers_j: [f64; LIMB_COUNT],
15}
16
17impl SystemState {
18 pub fn new(ep_j: f64, temperature_k: f64, y_m: f64, v_mps: f64, local_buffer_j: f64) -> Self {
19 Self {
20 time_s: 0.0,
21 ep_j,
22 temperature_k,
23 y_m,
24 v_mps,
25 local_buffers_j: [local_buffer_j; LIMB_COUNT],
26 }
27 }
28}
29
30#[derive(Debug, Clone, Serialize, Deserialize)]
31pub struct ControlInput {
32 pub command_fraction: f64,
33 pub disturbance_n: f64,
34 pub active_segment: String,
35 pub allocation_strategy: AllocationStrategy,
36}
37
38#[derive(Debug, Clone, Serialize, Deserialize)]
39pub struct LimbFlow {
40 pub limb: String,
41 pub requested_power_w: f64,
42 pub transfer_power_w: f64,
43 pub delivered_power_w: f64,
44 pub buffer_energy_before_j: f64,
45 pub buffer_energy_after_j: f64,
46 pub saturation: bool,
47}
48
49#[derive(Debug, Clone, Serialize, Deserialize)]
50pub struct StepDiagnostics {
51 pub command_fraction: f64,
52 pub disturbance_n: f64,
53 pub active_segment: String,
54 pub allocation_strategy: AllocationStrategy,
55 pub requested_actuator_power_w: f64,
56 pub delivered_actuator_power_w: f64,
57 pub central_transfer_power_w: f64,
58 pub commanded_recharge_power_w: f64,
59 pub parasitic_loss_w: f64,
60 pub heat_generation_w: f64,
61 pub heat_rejection_w: f64,
62 pub gain: f64,
63 pub damping: f64,
64 pub stiffness: f64,
65 pub mechanical_force_n: f64,
66 pub acceleration_mps2: f64,
67 pub delivered_ratio: f64,
68 pub energy_factor: f64,
69 pub thermal_factor: f64,
70 pub saturation_fraction: f64,
71 pub ep_dot_j_per_s: f64,
72 pub temperature_dot_k_per_s: f64,
73 pub mechanical_power_w: f64,
74 pub raw_next_ep_j: f64,
75 pub raw_next_temperature_k: f64,
76 pub raw_next_y_m: f64,
77 pub raw_next_v_mps: f64,
78 pub ep_clamped: bool,
79 pub temperature_clamped: bool,
80 pub y_clamped: bool,
81 pub v_clamped: bool,
82 pub limb_flows: [LimbFlow; LIMB_COUNT],
83}
84
85impl StepDiagnostics {
86 pub fn zero() -> Self {
87 Self {
88 command_fraction: 0.0,
89 disturbance_n: 0.0,
90 active_segment: "initial".to_string(),
91 allocation_strategy: AllocationStrategy::Equal,
92 requested_actuator_power_w: 0.0,
93 delivered_actuator_power_w: 0.0,
94 central_transfer_power_w: 0.0,
95 commanded_recharge_power_w: 0.0,
96 parasitic_loss_w: 0.0,
97 heat_generation_w: 0.0,
98 heat_rejection_w: 0.0,
99 gain: 0.0,
100 damping: 0.0,
101 stiffness: 0.0,
102 mechanical_force_n: 0.0,
103 acceleration_mps2: 0.0,
104 delivered_ratio: 1.0,
105 energy_factor: 1.0,
106 thermal_factor: 1.0,
107 saturation_fraction: 0.0,
108 ep_dot_j_per_s: 0.0,
109 temperature_dot_k_per_s: 0.0,
110 mechanical_power_w: 0.0,
111 raw_next_ep_j: 0.0,
112 raw_next_temperature_k: 0.0,
113 raw_next_y_m: 0.0,
114 raw_next_v_mps: 0.0,
115 ep_clamped: false,
116 temperature_clamped: false,
117 y_clamped: false,
118 v_clamped: false,
119 limb_flows: std::array::from_fn(|index| LimbFlow {
120 limb: LIMB_NAMES[index].to_string(),
121 requested_power_w: 0.0,
122 transfer_power_w: 0.0,
123 delivered_power_w: 0.0,
124 buffer_energy_before_j: 0.0,
125 buffer_energy_after_j: 0.0,
126 saturation: false,
127 }),
128 }
129 }
130}
131
132#[derive(Debug, Clone, Serialize, Deserialize)]
133pub struct TimeSeriesRecord {
134 pub time_s: f64,
135 pub ep_j: f64,
136 pub ep_gj: f64,
137 pub temperature_k: f64,
138 pub temperature_c: f64,
139 pub y_m: f64,
140 pub v_mps: f64,
141 pub command_fraction: f64,
142 pub active_segment: String,
143 pub requested_actuator_power_w: f64,
144 pub delivered_actuator_power_w: f64,
145 pub central_transfer_power_w: f64,
146 pub commanded_recharge_power_w: f64,
147 pub parasitic_loss_w: f64,
148 pub heat_generation_w: f64,
149 pub heat_rejection_w: f64,
150 pub gain: f64,
151 pub damping: f64,
152 pub stiffness: f64,
153 pub mechanical_force_n: f64,
154 pub acceleration_mps2: f64,
155 pub delivered_ratio: f64,
156 pub saturation_fraction: f64,
157 pub ep_dot_j_per_s: f64,
158 pub temperature_dot_k_per_s: f64,
159 pub mechanical_power_w: f64,
160 pub authority_utilization: f64,
161 pub reduced_response_target_y_m: f64,
162 pub reduced_response_target_rate_mps: f64,
163 pub reduced_response_error_m: f64,
164 pub reduced_response_error_rate_mps: f64,
165 pub lyapunov_v: f64,
166 pub lyapunov_dv_dt: f64,
167 pub raw_next_ep_j: f64,
168 pub raw_next_temperature_k: f64,
169 pub raw_next_y_m: f64,
170 pub raw_next_v_mps: f64,
171 pub ep_clamped: bool,
172 pub temperature_clamped: bool,
173 pub y_clamped: bool,
174 pub ydot_clamped: bool,
175 pub near_admissible_boundary: bool,
176 pub outside_admissible_region: bool,
177 pub admissible_margin_fraction: f64,
178}
179
180#[derive(Debug, Clone, Serialize, Deserialize)]
181pub struct LimbBufferRecord {
182 pub time_s: f64,
183 pub limb: String,
184 pub buffer_energy_j: f64,
185 pub buffer_energy_mj: f64,
186 pub requested_power_w: f64,
187 pub transfer_power_w: f64,
188 pub delivered_power_w: f64,
189 pub saturation: bool,
190}
191
192#[derive(Debug, Clone, Serialize, Deserialize)]
193pub struct EventRecord {
194 pub time_s: f64,
195 pub event_type: String,
196 pub severity: String,
197 pub message: String,
198 pub value: f64,
199 pub threshold: f64,
200}
201
202#[derive(Debug, Clone, Serialize, Deserialize)]
203pub struct DerivedMetricRecord {
204 pub metric: String,
205 pub value: f64,
206 pub unit: String,
207}
208
209#[derive(Debug, Clone, Default)]
210pub struct EventLatch {
211 pub low_energy: bool,
212 pub high_temperature: bool,
213 pub local_buffer_low: bool,
214 pub saturated: bool,
215 pub admissible_outside: bool,
216 pub admissible_margin: bool,
217}