Formula Student Electronics & Software
The code for the embedded software
Loading...
Searching...
No Matches
communicator.hpp
Go to the documentation of this file.
1#pragma once
2
3#include <Arduino.h>
4#include <FlexCAN_T4.h>
5
6#include <string>
7
8#include "../../CAN_IDs.h"
9#include "../utils.hpp"
10#include "comm/utils.hpp"
11#include "debugUtils.hpp"
12#include "enum_utils.hpp"
13#include "model/systemData.hpp"
14#include "utils.hpp"
15
20inline std::array<Code, 8> fifoCodes = {{{0, DASH_ID},
21 {1, BAMO_RESPONSE_ID},
22 {2, AS_CU_EMERGENCY_SIGNAL},
23 {3, MISSION_FINISHED},
24 {4, AS_CU_ID},
25 {5, RES_STATE},
26 {6, RES_READY},
27 {7, BMS_ID}}};
28
33inline std::array<Code, 1> fifoExtendedCodes = {{
34 {8, STEERING_ID},
35}};
36
43private:
44 // Static FlexCAN_T4 object for CAN2 interface with RX and TX buffer sizes specified
45 inline static FlexCAN_T4<CAN3, RX_SIZE_256, TX_SIZE_16> can3;
46
47public:
48 // Pointer to SystemData instance for storing system-related data
49 inline static SystemData *_systemData = nullptr;
50
56 explicit Communicator(SystemData *systemdata);
57
61 void init();
62
66 static void parse_message(const CAN_message_t &msg);
67
75 template <std::size_t N>
76 static int send_message(unsigned len, const std::array<uint8_t, N> &buffer, unsigned id);
77
81 static void pc_callback(const uint8_t *buf);
82
86 static void res_state_callback(const uint8_t *buf);
87
91 static void res_ready_callback();
92
96 static void bamocar_callback(const uint8_t *buf);
97
101 static void steering_callback();
102
106 static void dash_callback(const uint8_t *buf);
107
111 static void bms_callback(const uint8_t *buf);
115 static int publish_state(int state_id);
116
120 static int publish_ebs_states(uint8_t ebs_state, bool is_redundancy = false);
121
125 static int publish_mission(int mission_id);
129 static int publish_soc(uint8_t soc);
133 static int publish_asms_on(bool asms_on);
137 static int publish_debug_morning_log(const SystemData &system_data, uint8_t sate,
138 uint8_t state_checkup);
139
143 static int publish_rpm();
144};
145
147
149 can3.begin();
150 can3.setBaudRate(1'000'000);
151 can3.setRFFN(RFFN_32);
152 can3.enableFIFO();
153 can3.enableFIFOInterrupt();
154
155 can3.setFIFOFilter(REJECT_ALL);
156 for (auto &fifoCode : fifoCodes) can3.setFIFOFilter(fifoCode.key, fifoCode.code, STD);
157
158 for (auto &fifoExtendedCode : fifoExtendedCodes)
159 can3.setFIFOFilter(fifoExtendedCode.key, fifoExtendedCode.code, EXT);
160
161 can3.onReceive(FIFO, parse_message);
162
163 can3.mailboxStatus();
164}
165inline void Communicator::res_state_callback(const uint8_t *buf) {
166 bool emg_stop1 = buf[0] & 0x01;
167 bool emg_stop2 = buf[3] >> 7 & 0x01;
168 bool go_switch = (buf[0] >> 1) & 0x01;
169 bool go_button = (buf[0] >> 2) & 0x01;
170 // DEBUG_PRINT("RES GO: " + String(go_switch) + " EMG 1: " + String(emg_stop1) + " EMG 2: " +
171 // String(emg_stop2));
172
173 if (go_button || go_switch)
175 else if (!(emg_stop1 || emg_stop2)) { // If both are false
176 // DEBUG_PRINT("Received Emergency from RES");
178 }
179
181 bool signal_loss = (buf[7] >> 6) & 0x01;
182 if (!signal_loss) {
184 .reset(); // making sure we dont receive only signal loss for the defined time interval
185 // DEBUG_PRINT("SIGNAL OKAY");
186 } else {
187 // Too many will violate the disconnection time limit
188 // DEBUG_PRINT("SIGNAL LOSS");
189 }
190}
191
193 // If res sends boot message, activate it
194 std::array<uint8_t, 2> msg = {0x01, NODE_ID}; // 0x00 in byte 2 for all nodes
195
196 send_message(2, msg, RES_ACTIVATE);
197}
198
199inline void Communicator::bamocar_callback(const uint8_t *buf) {
201
202 if (buf[0] == BTB_READY) {
203 if (buf[1] == false) {
205 }
206 } else if (buf[0] == BAMOCAR_BATTERY_VOLTAGE_CODE) {
207 unsigned dc_voltage = (buf[2] << 8) | buf[1];
209
210 // Voltage hysteresis:
211 if (dc_voltage < DC_THRESHOLD) {
212 // When voltage drops/is below threshold:
213 // Reset hold timer and check if voltage has been below threshold long enough
217 }
218 } else {
219 // When voltage is above threshold:
220 // Reset drop timer and check if voltage has been above threshold long enough
224 }
225 }
226 }
227}
228
229inline void Communicator::pc_callback(const uint8_t *buf) {
230 // DEBUG_PRINT("PC alive signal received");
231 if (buf[0] == PC_ALIVE) {
233 } else if (buf[0] == MISSION_FINISHED) {
235 } else if (buf[0] == AS_CU_EMERGENCY_SIGNAL) {
236 DEBUG_PRINT("Received Emergency from AS CU");
238 }
239}
240
244
245inline void Communicator::dash_callback(const uint8_t *buf) {
246 if (buf[0] == HYDRAULIC_LINE) {
248 }
249}
253
254inline void Communicator::parse_message(const CAN_message_t &msg) {
255 switch (msg.id) {
256 case AS_CU_ID:
257 pc_callback(msg.buf);
258 case RES_STATE:
260 break;
261 case RES_READY:
263 break;
264 case BAMO_RESPONSE_ID:
266 break;
267 case STEERING_ID:
269 break;
270 case DASH_ID:
271 dash_callback(msg.buf);
272 case BMS_ID:
273 bms_callback(msg.buf);
274 break;
275 default:
276 break;
277 }
278}
279
280inline int Communicator::publish_state(const int state_id) {
281 const std::array<uint8_t, 2> msg = {STATE_MSG, static_cast<uint8_t>(state_id)};
282 send_message(2, msg, MASTER_ID);
283 return 0;
284}
285
286inline int Communicator::publish_mission(int mission_id) {
287 const std::array<uint8_t, 2> msg = {MISSION_MSG, static_cast<uint8_t>(mission_id)};
288
289 send_message(2, msg, MASTER_ID);
290 return 0;
291}
293 uint8_t state_checkup) {
294 // send_message(8, create_debug_message_1(system_data, state, state_checkup), MASTER_ID);
295 // send_message(8, create_debug_message_2(system_data), MASTER_ID);
296 send_message(8, create_signals_msg_1(system_data, state, state_checkup), DATA_LOGGER_SIGNALS_1);
297 send_message(8, create_hydraulic_presures_msg(system_data), DATA_LOGGER_SIGNALS_2);
298 return 0;
299}
300
301inline int Communicator::publish_soc(uint8_t soc) {
302 const std::array<uint8_t, 2> msg = {SOC_MSG, soc};
303 send_message(2, msg, MASTER_ID);
304 return 0;
305}
306
307inline int Communicator::publish_asms_on(bool asms_on) {
308 const std::array<uint8_t, 2> msg = {ASMS, asms_on};
309 send_message(2, msg, MASTER_ID);
310 return 0;
311}
312
314 std::array<uint8_t, 5> rl_rpm_msg = {0};
315 std::array<uint8_t, 5> rr_rpm_msg = {0};
316
317 char rr_rpm_byte[4];
318 char rl_rpm_byte[4];
321
322 rl_rpm_msg[0] = LEFT_WHEEL_CODE;
323 for (int i = 0; i < 4; i++) {
324 rl_rpm_msg[i + 1] = rl_rpm_byte[i];
325 }
326
327 rr_rpm_msg[0] = RIGHT_WHEEL_CODE;
328 for (int i = 0; i < 4; i++) {
329 rr_rpm_msg[i + 1] = rr_rpm_byte[i];
330 }
331 send_message(5, rl_rpm_msg, MASTER_ID);
332 send_message(5, rr_rpm_msg, MASTER_ID);
333
334 return 0;
335}
336
337inline int Communicator::publish_ebs_states(uint8_t ebs_state, bool is_redundancy) {
338 // EBS state is a 4-bit value, we need to send it as a byte
339 // std::array<uint8_t, 2> msg = {EBS_REDUNDANCY_MSG, ebs_state & 0x0F};
340 // send_message(2, msg, MASTER_ID);
341 // std::array<uint8_t, 2> msg = {EBS_STATE_MSG, ebs_state & 0x0F};
342 // send_message(2, msg, MASTER_ID);
343 if (is_redundancy) {
344 std::array<uint8_t, 2> msg = {EBS_REDUNDANCY_MSG, ebs_state & 0x0F};
345 send_message(2, msg, MASTER_ID);
346 }else {
347 std::array<uint8_t, 2> msg = {EBS_STATE_MSG, ebs_state & 0x0F};
348 send_message(2, msg, MASTER_ID);
349 }
350
351 return 0;
352}
353
354template <std::size_t N>
355inline int Communicator::send_message(const unsigned len, const std::array<uint8_t, N> &buffer,
356 const unsigned id) {
357 CAN_message_t can_message;
358 can_message.id = id;
359 can_message.len = len;
360 for (unsigned i = 0; i < len; i++) {
361 can_message.buf[i] = buffer[i];
362 }
363 can3.write(can_message);
364
365 return 0;
366}
Class that contains definitions of typical messages to send via CAN It serves only as an example of t...
static void steering_callback()
Callback for steering actuator information.
static int publish_mission(int mission_id)
Publish AS Mission to CAN.
static int publish_rpm()
Publish rl wheel rpm to CAN.
void init()
Initializes the CAN bus.
static int publish_debug_morning_log(const SystemData &system_data, uint8_t sate, uint8_t state_checkup)
Publish AS Mission to CAN.
Communicator(SystemData *systemdata)
Constructor for the Communicator class Initializes the Communicator with the given system data instan...
static void parse_message(const CAN_message_t &msg)
Parses the message received from the CAN bus.
static void res_state_callback(const uint8_t *buf)
Callback RES default callback.
static void dash_callback(const uint8_t *buf)
Callback for dashboard.
static void bms_callback(const uint8_t *buf)
Callback for BMS messages.
static int send_message(unsigned len, const std::array< uint8_t, N > &buffer, unsigned id)
Sends a message to the CAN bus.
static void pc_callback(const uint8_t *buf)
Callback for message from AS CU.
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 void bamocar_callback(const uint8_t *buf)
Callback from inversor, for alive signal and data.
static SystemData * _systemData
static int publish_ebs_states(uint8_t ebs_state, bool is_redundancy=false)
Publish EBS States to CAN.
static void res_ready_callback()
Callback for RES activation.
static int publish_state(int state_id)
Publish AS State to CAN.
void reset() volatile
Resets the timer to the current time.
Definition metro.h:212
bool checkWithoutReset() const volatile
Checks if the interval has passed without resetting the timer.
Definition metro.h:203
std::array< uint8_t, 8 > create_signals_msg_1(const SystemData &system_data, const uint8_t state, const uint8_t state_checkup)
Definition utils.hpp:21
std::array< uint8_t, 8 > create_hydraulic_presures_msg(const SystemData &system_data)
Definition utils.hpp:63
std::array< Code, 1 > fifoExtendedCodes
Array of extended CAN message codes to be used for FIFO filtering Contains the key and corresponding ...
std::array< Code, 8 > fifoCodes
Array of standard CAN message codes to be used for FIFO filtering Each Code struct contains a key and...
#define DEBUG_PRINT(str)
SystemData system_data
Definition main.cpp:11
volatile bool emergency_signal_
volatile unsigned dc_voltage_
volatile double radio_quality_
int hydraulic_line_front_pressure
double _right_wheel_rpm
double _left_wheel_rpm
void process_go_signal()
Processes the go signal.
The whole model of the system: holds all the data necessary.
R2DLogics r2d_logics_
FailureDetection failure_detection_
HardwareData hardware_data_
NonUnitaryFailureDetection updatable_timestamps_
bool mission_finished_
CAN_message_t msg
void rpm_2_byte(const float rr_rpm, char *rr_rpm_byte)
Definition utils.hpp:38