Formula Student Electronics & Software
The code for the embedded software
Loading...
Searching...
No Matches
outputCoordinator.hpp
Go to the documentation of this file.
1#pragma once
2
3#include "TeensyTimerTool.h"
5#include "debugUtils.hpp"
7#include "enum_utils.hpp"
8#include "metro.h"
10#include "timings.hpp"
11
13private:
14 Metro blink_timer_{LED_BLINK_INTERVAL};
15
16 SystemData* system_data_;
17 Communicator* communicator_;
18 DigitalSender* digital_sender_;
19
20 Metro mission_timer_;
21 Metro state_timer_;
22 Metro process_timer_{PROCESS_INTERVAL};
23 Metro slower_process_timer_{SLOWER_PROCESS_INTERVAL};
24
25 uint8_t previous_master_state_;
26 uint8_t previous_checkup_state_;
27 uint8_t previous_mission_;
28
29 unsigned long tsms_open_time_ = 0;
30 unsigned long counter = 0;
31 bool opened = false;
32 bool tsms_was_closed_ = false;
33
34public:
37 : system_data_(system_data),
38 communicator_(communicator),
39 digital_sender_(digital_sender),
40 mission_timer_(MISSION_PUBLISH_INTERVAL),
41 state_timer_(STATE_PUBLISH_INTERVAL),
42 previous_master_state_(static_cast<uint8_t>(15)),
43 previous_checkup_state_(static_cast<uint8_t>(15)),
44 previous_mission_(static_cast<uint8_t>(15)) {}
45
46 void init() {
47 mission_timer_.reset();
48 state_timer_.reset();
49 DEBUG_PRINT("Output coordinator initialized...");
50 }
51
52 void process(uint8_t current_master_state, uint8_t current_checkup_state, uint8_t ebs_state) {
53 dash_ats_update(current_master_state);
54 update_physical_outputs();
55 if (process_timer_.check()) {
56 send_soc();
57 send_asms();
58 send_mission_update();
59 send_state_update(current_master_state);
60 send_ebs_state(current_checkup_state, ebs_state);
61 }
62 if (slower_process_timer_.check()) {
63 send_data_logging_data(current_master_state, current_checkup_state);
64 }
65 }
66
68 if (blink_timer_.check()) {
69 digital_sender_->blink_led(ASSI_BLUE_PIN);
70 }
71 }
72
74 if (blink_timer_.check()) {
75 digital_sender_->blink_led(ASSI_YELLOW_PIN);
76 }
77 }
78
83 digital_sender_->turn_off_assi();
84 blink_timer_.reset();
85 digital_sender_->activate_ebs();
86 digital_sender_->open_sdc();
87 this->system_data_->hardware_data_.master_sdc_closed_ = false;
88 }
89
94 digital_sender_->turn_off_assi();
95 digital_sender_->deactivate_ebs();
96 digital_sender_->open_sdc();
97 this->system_data_->hardware_data_.master_sdc_closed_ = false;
98 DEBUG_PRINT("Entering manual state...");
99 }
100
105 digital_sender_->turn_off_assi();
106 digital_sender_->activate_ebs();
107 digital_sender_->open_sdc();
108 // this->system_data_->hardware_data_.master_sdc_closed_ = false;
109 }
110
115 digital_sender_->turn_off_assi();
116 digital_sender_->turn_on_yellow();
117 digital_sender_->activate_ebs();
118 digital_sender_->close_sdc();
119 this->system_data_->hardware_data_.master_sdc_closed_ = true;
120 }
121
126 digital_sender_->turn_off_assi();
127 blink_timer_.reset();
128 digital_sender_->deactivate_ebs();
129 digital_sender_->close_sdc();
130 this->system_data_->hardware_data_.master_sdc_closed_ = true;
131 }
132
137 digital_sender_->turn_off_assi();
138 digital_sender_->turn_on_blue();
139 digital_sender_->activate_ebs();
140 digital_sender_->open_sdc();
141 this->system_data_->hardware_data_.master_sdc_closed_ = false;
142 }
143
144 void refresh_r2d_vars() { this->system_data_->r2d_logics_.refresh_r2d_vars(); }
146 this->system_data_->failure_detection_.emergency_signal_ = false;
147 this->system_data_->failure_detection_.steer_dead_ = false;
148 this->system_data_->failure_detection_.pc_dead_ = false;
149 this->system_data_->failure_detection_.inversor_dead_ = false;
150 this->system_data_->failure_detection_.res_dead_ = false;
151 }
152
153private:
154 // Communication functions
155 void send_data_logging_data(uint8_t current_master_state, uint8_t current_checkup_state) {
156 Communicator::publish_debug_morning_log(*system_data_, current_master_state,
157 current_checkup_state);
158 }
159
160 void send_soc() { Communicator::publish_soc(system_data_->hardware_data_.soc_); }
161
162 void send_asms() { Communicator::publish_asms_on(system_data_->hardware_data_.asms_on_); }
163
164 void send_mission_update() {
165 if (mission_timer_.check()) {
167 mission_timer_.reset();
168 }
169 }
170 void send_ebs_state(uint8_t current_checkup_state, uint8_t ebs_state) {
171 static constexpr uint8_t ASB_EBS_STATE_OFF = 1;
172 static constexpr uint8_t ASB_EBS_STATE_INITIAL_CHECKUP_PASSED = 2;
173 static constexpr uint8_t ASB_EBS_STATE_ACTIVATED = 3;
174
175 static constexpr uint8_t ASB_REDUNDANCY_STATE_DEACTIVATED = 1;
176 static constexpr uint8_t ASB_REDUNDANCY_STATE_ENGAGED = 2;
177 static constexpr uint8_t ASB_REDUNDANCY_STATE_INITIAL_CHECKUP_PASSED = 3;
178 switch (ebs_state) {
179 case 0: // DISABLE_ACTUATOR_1
180 Communicator::publish_ebs_states(ASB_EBS_STATE_OFF, false);
181 Communicator::publish_ebs_states(ASB_REDUNDANCY_STATE_ENGAGED, true);
182 break;
183
184 case 1: // CHECK_ACTUATOR_2
185 Communicator::publish_ebs_states(ASB_EBS_STATE_OFF, false);
186 Communicator::publish_ebs_states(ASB_REDUNDANCY_STATE_ENGAGED, true);
187 break;
188
189 case 2: // CHANGE_ACTUATORS
190 Communicator::publish_ebs_states(ASB_EBS_STATE_ACTIVATED, false);
191 Communicator::publish_ebs_states(ASB_REDUNDANCY_STATE_DEACTIVATED, true);
192 break;
193
194 case 3: // CHECK_ACTUATOR_1
195 Communicator::publish_ebs_states(ASB_EBS_STATE_ACTIVATED, false);
196 Communicator::publish_ebs_states(ASB_REDUNDANCY_STATE_DEACTIVATED, true);
197 break;
198
199 case 4: // ENABLE_ACTUATOR_2
200 Communicator::publish_ebs_states(ASB_EBS_STATE_ACTIVATED, false);
201 Communicator::publish_ebs_states(ASB_REDUNDANCY_STATE_ENGAGED, true);
202 break;
203
204 case 5: // CHECK_BOTH_ACTUATORS
205 Communicator::publish_ebs_states(ASB_EBS_STATE_ACTIVATED, false);
206 Communicator::publish_ebs_states(ASB_REDUNDANCY_STATE_ENGAGED, true);
207 break;
208
209 case 6: // COMPLETE
210 Communicator::publish_ebs_states(ASB_EBS_STATE_INITIAL_CHECKUP_PASSED, false);
211 Communicator::publish_ebs_states(ASB_REDUNDANCY_STATE_INITIAL_CHECKUP_PASSED, true);
212 break;
213
214 default:
215 Communicator::publish_ebs_states(ASB_EBS_STATE_OFF, false);
216 Communicator::publish_ebs_states(ASB_REDUNDANCY_STATE_DEACTIVATED, true);
217 break;
218 }
219 }
220 void send_state_update(uint8_t current_master_state) {
221 if (state_timer_.check()) {
222 Communicator::publish_state(current_master_state);
223 state_timer_.reset();
224 }
225 }
226
227 void update_physical_outputs() {
228 brake_light_update();
229 // bsdp_sdc_update();
230 // digital_sender_->turn_on_blue();
231 // digital_sender_->turn_on_yellow();
232 }
233
234 void brake_light_update() {
235 int brake_val = system_data_->hardware_data_._hydraulic_line_pressure;
236 // DEBUG_PRINT("Brake pressure: " + String(brake_val));
237 // DEBUG_PRINT("Brake pressure lower threshold: " +
238 // String(BRAKE_PRESSURE_LOWER_THRESHOLD));
239 // DEBUG_PRINT("Brake pressure upper threshold: " +
240 // String(BRAKE_PRESSURE_UPPER_THRESHOLD));
241
242 if (brake_val >= BRAKE_PRESSURE_LOWER_THRESHOLD &&
243 brake_val <= BRAKE_PRESSURE_UPPER_THRESHOLD) {
244 digital_sender_->turn_on_brake_light();
245 } else {
246 digital_sender_->turn_off_brake_light();
247 }
248 }
249
250 void bsdp_sdc_update() {
251 // TODO: implement bspd logic, update led from this output in Dash
252 if (!system_data_->hardware_data_.tsms_sdc_closed_) {
253 digital_sender_->bspd_error();
254 } else {
255 digital_sender_->no_bspd_error();
256 }
257 }
258 void dash_ats_update(uint8_t current_master_state) {
259 // DEBUG_PRINT("=== ATS Update Debug ===");
260 // DEBUG_PRINT("ATS Pressed: " + String(system_data_->hardware_data_.ats_pressed_));
261 // DEBUG_PRINT("Current Master State: " + String(current_master_state) +
262 // " (AS_MANUAL=" + String(to_underlying(State::AS_MANUAL)) + ")");
263 // DEBUG_PRINT("TSMS SDC Closed: " +
264 // String(system_data_->hardware_data_.tsms_sdc_closed_)); if
265 // (system_data_->hardware_data_.tsms_sdc_closed_) {
266 // opened_again = false;
267 // }
268
269 // if (tsms_was_closed_ && !system_data_->hardware_data_.tsms_sdc_closed_) {
270 // DEBUG_PRINT(">>> TSMS opened - recording time for 100ms delay");
271 // tsms_open_time_ = millis();
272 // opened = true;
273 // }
274
275 // DEBUG_PRINT_VAR(system_data_->hardware_data_.tsms_sdc_closed_);
276 // DEBUG_PRINT_VAR(tsms_open_time_);
277 // DEBUG_PRINT_VAR(tsms_was_closed_);
278 // DEBUG_PRINT_VAR(this->counter);
279 // DEBUG_PRINT_VAR(this->opened);
280 // DEBUG_PRINT_VAR(this->system_data_->hardware_data_.master_sdc_closed_);
281 // if (tsms_open_time_ > 0) {
282 // this->counter++;
283
284 // }
285
286 if (system_data_->hardware_data_.ats_pressed_ &&
287 current_master_state == to_underlying(State::AS_MANUAL) &&
288 system_data_->hardware_data_.tsms_sdc_closed_) {
289 // DEBUG_PRINT(">>> CLOSING SDC - All conditions met");
290 digital_sender_->close_sdc();
291 // tsms_was_closed_ = system_data_->hardware_data_.tsms_sdc_closed_;
292
293 this->system_data_->hardware_data_.master_sdc_closed_ = true;
294 } else if (!system_data_->hardware_data_.tsms_sdc_closed_
295 // && tsms_open_time_ > 0 &&
296 // (millis() - tsms_open_time_) >= 100
297 )
298 {
299 // DEBUG_PRINT(">>> OPENING SDC - TSMS SDC not closed (100ms delay elapsed)");
300 digital_sender_->open_sdc();
301 this->system_data_->hardware_data_.master_sdc_closed_ = false;
302 } else {
303 // DEBUG_PRINT(">>> NO SDC ACTION - Conditions not met");
304 if (!system_data_->hardware_data_.ats_pressed_) {
305 // DEBUG_PRINT(" - ATS not pressed");
306 }
307 if (current_master_state != to_underlying(State::AS_MANUAL)) {
308 // DEBUG_PRINT(" - Not in AS_MANUAL state");
309 }
310 }
311 }
312 void send_rpm() { Communicator::publish_rpm(); }
313};
Class that contains definitions of typical messages to send via CAN It serves only as an example of t...
static int publish_mission(int mission_id)
Publish AS Mission to CAN.
static int publish_rpm()
Publish rl wheel rpm to CAN.
static int publish_debug_morning_log(const SystemData &system_data, uint8_t sate, uint8_t state_checkup)
Publish AS Mission to CAN.
static int publish_soc(uint8_t soc)
Publish SOC to CAN.
static int publish_asms_on(bool asms_on)
Publish ASMS state to CAN.
static int publish_ebs_states(uint8_t ebs_state, bool is_redundancy=false)
Publish EBS States to CAN.
static int publish_state(int state_id)
Publish AS State to CAN.
Class responsible for controlling digital outputs in the Master Teensy.
void bspd_error()
Turns on the BSPD error signal.
static void turn_off_assi()
Turns off both ASSI LEDs (yellow and blue).
void blink_led(int pin)
Blinks the LED at the given pin.
void turn_on_brake_light()
Turns on the brake light.
void no_bspd_error()
Turns off the BSPD error signal.
void turn_on_blue()
Turns on the blue ASSI LED.
void turn_off_brake_light()
Turns off the brake light.
static void activate_ebs()
Activates the solenoid EBS valves.
static void deactivate_ebs()
Deactivates the solenoid EBS valves.
static void open_sdc()
Opens the SDC in Master and SDC Logic.
static void close_sdc()
Closes the SDC in Master and SDC Logic.
void turn_on_yellow()
Turns on the yellow ASSI LED.
Our own implementation of Metro class.
Definition metro.h:13
void reset()
Resets the timer to the current time.
Definition metro.h:124
bool check()
Checks if the interval has passed and resets the timer if true.
Definition metro.h:90
OutputCoordinator(SystemData *system_data, Communicator *communicator, DigitalSender *digital_sender)
void enter_finish_state()
ASSI blue LED on, ebs valves activated, sdc open.
void enter_manual_state()
Everything off, sdc closed.
void enter_off_state()
Everything off, sdc open.
void enter_driving_state()
ASSI LEDs yellow flashing, ebs valves deactivated, sdc closed.
void enter_emergency_state()
ASSI LEDs blue flashing, sdc open and buzzer ringing.
void process(uint8_t current_master_state, uint8_t current_checkup_state, uint8_t ebs_state)
void enter_ready_state()
ASSI yellow LED on, ebs valves activated, sdc closed.
#define DEBUG_PRINT(str)
constexpr auto to_underlying(Enum e) noexcept
Definition enum_utils.hpp:4
constexpr int PROCESS_INTERVAL
constexpr int LED_BLINK_INTERVAL
constexpr int BRAKE_PRESSURE_UPPER_THRESHOLD
constexpr int BRAKE_PRESSURE_LOWER_THRESHOLD
constexpr int SLOWER_PROCESS_INTERVAL
constexpr int ASSI_BLUE_PIN
constexpr int ASSI_YELLOW_PIN
Communicator communicator
Definition main.cpp:12
SystemData system_data
Definition main.cpp:11
DigitalSender digital_sender
Definition main.cpp:14
volatile bool emergency_signal_
int _hydraulic_line_pressure
bool master_sdc_closed_
void refresh_r2d_vars()
resets timestamps for ready
The whole model of the system: holds all the data necessary.
Mission mission_
R2DLogics r2d_logics_
FailureDetection failure_detection_
HardwareData hardware_data_
@ AS_MANUAL
constexpr auto MISSION_PUBLISH_INTERVAL
Definition timings.hpp:6
constexpr auto STATE_PUBLISH_INTERVAL
Definition timings.hpp:5