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
9#include "comm/utils.hpp"
10#include "debugUtils.hpp"
11#include "enum_utils.hpp"
12#include "model/systemData.hpp"
13
18inline std::array<Code, 7> fifoCodes = {{{0, C1_ID},
22 {4, AS_CU_ID},
23 {5, RES_STATE},
24 {6, RES_READY}}};
25
30inline std::array<Code, 1> fifoExtendedCodes = {{
31 {7, STEERING_ID},
32}};
33
40private:
41 // Static FlexCAN_T4 object for CAN2 interface with RX and TX buffer sizes specified
42 inline static FlexCAN_T4<CAN2, RX_SIZE_256, TX_SIZE_16> can2;
43
44public:
45 // Pointer to SystemData instance for storing system-related data
46 inline static SystemData *_systemData = nullptr;
47
53 explicit Communicator(SystemData *systemdata);
54
58 void init();
59
63 static void parse_message(const CAN_message_t &msg);
64
72 template <std::size_t N>
73 static int send_message(unsigned len, const std::array<uint8_t, N> &buffer, unsigned id);
74
78 static void pc_callback(const uint8_t *buf);
79
83 static void c1_callback(const uint8_t *buf);
84
88 static void res_state_callback(const uint8_t *buf);
89
93 static void res_ready_callback();
94
98 static void bamocar_callback(const uint8_t *buf);
99
103 static void steering_callback();
104
108 static int publish_state(int state_id);
109
113 static int publish_mission(int mission_id);
114
118 static int publish_debug_log(SystemData system_data, uint8_t sate, uint8_t state_checkup);
119
123 static int publish_left_wheel_rpm(double value);
124};
125
127
129 // Library initialization
130 can2.begin();
131 can2.setBaudRate(500000);
132
133 // Enable FIFO
134 can2.enableFIFO();
135 can2.enableFIFOInterrupt();
136
137 // Set filters
138 can2.setFIFOFilter(REJECT_ALL);
139 for (auto &fifoCode : fifoCodes) can2.setFIFOFilter(fifoCode.key, fifoCode.code, STD);
140
141 // Set filters for extended
142 for (auto &fifoExtendedCode : fifoExtendedCodes)
143 can2.setFIFOFilter(fifoExtendedCode.key, fifoExtendedCode.code, EXT);
144
145 // Set callback
146 can2.onReceive(FIFO, parse_message);
147
148 DEBUG_PRINT("CAN2 started");
149 can2.mailboxStatus(); // Prints CAN mailbox info
150}
151
152inline void Communicator::c1_callback(const uint8_t *buf) {
153 if (buf[0] == HYDRAULIC_LINE) {
154 _systemData->sensors_._hydraulic_line_pressure = (buf[2] << 8) | buf[1];
155 } else if (buf[0] == RIGHT_WHEEL_CODE) {
156 double right_wheel_rpm = (buf[4] << 24) | (buf[3] << 16) | (buf[2] << 8) | buf[1];
157 right_wheel_rpm *= WHEEL_PRECISION; // convert back adding decimal part
158 _systemData->sensors_._right_wheel_rpm = right_wheel_rpm;
159 } else if (buf[0] == LEFT_WHEEL_CODE) {
160 double left_wheel_rpm = (buf[4] << 24) | (buf[3] << 16) | (buf[2] << 8) | buf[1];
161 left_wheel_rpm *= WHEEL_PRECISION; // convert back adding decimal part
162 _systemData->sensors_._left_wheel_rpm = left_wheel_rpm;
163 }
164}
165
166inline void Communicator::res_state_callback(const uint8_t *buf) {
167 bool emg_stop1 = buf[0] & 0x01;
168 bool emg_stop2 = buf[3] >> 7 & 0x01;
169 bool go_switch = (buf[0] >> 1) & 0x01;
170 bool go_button = (buf[0] >> 2) & 0x01;
171
172 // DEBUG_PRINT("Received message from RES");
173
174 if (go_button || go_switch)
176 else if (!emg_stop1 && !emg_stop2) {
177 DEBUG_PRINT("RES Emergency Signal");
179 }
180
182 bool signal_loss = (buf[7] >> 6) & 0x01;
183 if (!signal_loss) {
185 .reset(); // making ure we dont receive only ignal lo for the defined time interval
186 // DEBUG_PRINT("SIGNAL OKAY");
187 } else {
188 // Too many will violate the disconnection time limit
189 // DEBUG_PRINT("SIGNAL LOSS");
190 }
191}
192
194 // If res sends boot message, activate it
195 DEBUG_PRINT("Received RES Ready");
196 unsigned id = RES_ACTIVATE;
197 std::array<uint8_t, 2> msg = {0x01, NODE_ID}; // 0x00 in byte 2 for all nodes
198
199 send_message(2, msg, id);
200}
201
202inline void Communicator::bamocar_callback(const uint8_t *buf) {
204
205 if (buf[0] == BTB_READY) {
206 if (buf[1] == false) {
207 DEBUG_PRINT("BTB not ready");
210 }
211 } else if (buf[0] == VDC_BUS) {
212 unsigned dc_voltage = (buf[2] << 8) | buf[1];
214
215 if (dc_voltage < DC_THRESHOLD) {
218 DEBUG_PRINT("DC Voltage Drop under defined value for more than 150ms");
219
221 }
222 } else {
226 }
227 }
228 }
229}
230
231inline void Communicator::pc_callback(const uint8_t *buf) {
232 DEBUG_PRINT("PC callback");
233 if (buf[0] == PC_ALIVE) {
235 // DEBUG_PRINT("Received AS CU Alive");
236 } else if (buf[0] == MISSION_FINISHED) {
238 } else if (buf[0] == AS_CU_EMERGENCY_SIGNAL) {
241 }
242}
243
247
248inline void Communicator::parse_message(const CAN_message_t &msg) {
249 switch (msg.id) {
250 case AS_CU_ID:
251 pc_callback(msg.buf);
252 case RES_STATE:
254 break;
255 case RES_READY:
257 break;
258 case C1_ID:
259 c1_callback(msg.buf); // rwheel, lwheel and hydraulic line
260 break;
261 case BAMO_RESPONSE_ID:
263 break;
264 case STEERING_ID:
266 break;
267 default:
268 break;
269 }
270}
271
272inline int Communicator::publish_state(const int state_id) {
273 const std::array<uint8_t, 2> msg = {STATE_MSG, static_cast<uint8_t>(state_id)};
275 return 0;
276}
277
278inline int Communicator::publish_mission(int mission_id) {
279 const std::array<uint8_t, 2> msg = {MISSION_MSG, static_cast<uint8_t>(mission_id)};
280
282 return 0;
283}
284
286 uint8_t state_checkup) {
287 // 8 bytes for the CAN message
288 uint32_t hydraulic_pressure = system_data.sensors_._hydraulic_line_pressure; // 32-bit value
289 // TBD, consider extracting to a function in utils.hpp
290 uint8_t emergency_signal_bit = system_data.failure_detection_.emergency_signal_;
291 uint8_t pneumatic_line_pressure_bit = system_data.digital_data_.pneumatic_line_pressure_;
292 uint8_t engage_ebs_check_bit = system_data.r2d_logics_.engageEbsTimestamp.checkWithoutReset();
293 uint8_t release_ebs_check_bit = system_data.r2d_logics_.releaseEbsTimestamp.checkWithoutReset();
294 uint8_t steer_dead_bit = system_data.failure_detection_.steer_dead_;
295 uint8_t pc_dead_bit = system_data.failure_detection_.pc_dead_;
296 uint8_t inversor_dead_bit = system_data.failure_detection_.inversor_dead_;
297 uint8_t res_dead_bit = system_data.failure_detection_.res_dead_;
298 uint8_t asms_on_bit = system_data.digital_data_.asms_on_;
299 uint8_t ts_on_bit = system_data.failure_detection_.ts_on_;
300 uint8_t sdc_state_open_bit = system_data.digital_data_.sdc_open_;
301 uint8_t mission = to_underlying(system_data.mission_);
302 const std::array<uint8_t, 8> msg = {
304 (hydraulic_pressure >> 24) & 0xFF,
305 (hydraulic_pressure >> 16) & 0xFF,
306 (hydraulic_pressure >> 8) & 0xFF,
307 hydraulic_pressure & 0xFF,
308 (emergency_signal_bit & 0x01) << 7 | (pneumatic_line_pressure_bit & 0x01) << 6 |
309 (engage_ebs_check_bit & 0x01) << 5 | (release_ebs_check_bit & 0x01) << 4 |
310 (steer_dead_bit & 0x01) << 3 | (pc_dead_bit & 0x01) << 2 |
311 (inversor_dead_bit & 0x01) << 1 | (res_dead_bit & 0x01),
312 (asms_on_bit & 0x01) << 7 | (ts_on_bit & 0x01) << 6 | (sdc_state_open_bit & 0x01) << 5 |
313 (state_checkup & 0x0F),
314 (mission & 0x0F) | ((state & 0x0F) << 4)};
315
317
318 uint32_t dc_voltage = system_data.failure_detection_.dc_voltage_;
319 uint8_t pneumatic_line_pressure_bit_1 = system_data.digital_data_.pneumatic_line_pressure_1_;
320 uint8_t pneumatic_line_pressure_bit_2 = system_data.digital_data_.pneumatic_line_pressure_2_;
321
322 const std::array<uint8_t, 7> msg2 = {DBG_LOG_MSG_2,
323 (dc_voltage >> 24) & 0xFF,
324 (dc_voltage >> 16) & 0xFF,
325 (dc_voltage >> 8) & 0xFF,
326 dc_voltage & 0xFF,
327 pneumatic_line_pressure_bit_1 & 0x01,
328 pneumatic_line_pressure_bit_2 & 0x01};
330 return 0;
331}
332
333inline int Communicator::publish_left_wheel_rpm(double value) {
334 std::array<uint8_t, 5> msg;
336
338 return 0;
339}
340
341template <std::size_t N>
342inline int Communicator::send_message(const unsigned len, const std::array<uint8_t, N> &buffer,
343 const unsigned id) {
344 CAN_message_t can_message;
345 can_message.id = id;
346 can_message.len = len;
347 for (unsigned i = 0; i < len; i++) {
348 can_message.buf[i] = buffer[i];
349 }
350 can2.write(can_message);
351
352 return 0;
353}
#define C1_ID
Definition main.cpp:30
#define MASTER_ID
Definition can.h:10
#define DC_THRESHOLD
Definition can.cpp:74
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.
void init()
Initializes the CAN bus.
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 int send_message(unsigned len, const std::array< uint8_t, N > &buffer, unsigned id)
Sends a message to the CAN bus.
static void c1_callback(const uint8_t *buf)
Callback for data from C1 Teensy.
static void pc_callback(const uint8_t *buf)
Callback for message from AS CU.
static void bamocar_callback(const uint8_t *buf)
Callback from inversor, for alive signal and data.
static int publish_debug_log(SystemData system_data, uint8_t sate, uint8_t state_checkup)
Publish AS Mission to CAN.
static SystemData * _systemData
static void res_ready_callback()
Callback for RES activation.
static int publish_left_wheel_rpm(double value)
Publish rl wheel rpm to CAN.
static int publish_state(int state_id)
Publish AS State to CAN.
void reset()
Resets the timer to the current time.
Definition metro.h:124
bool checkWithoutReset() const
Checks if the interval has passed without resetting the timer.
Definition metro.h:115
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, 7 > fifoCodes
Array of standard CAN message codes to be used for FIFO filtering Each Code struct contains a key and...
constexpr auto RIGHT_WHEEL_CODE
constexpr auto AS_CU_EMERGENCY_SIGNAL
constexpr auto RES_ACTIVATE
constexpr auto STEERING_ID
constexpr auto RES_READY
constexpr auto RES_STATE
constexpr auto MISSION_FINISHED
constexpr auto AS_CU_ID
constexpr auto MISSION_MSG
constexpr auto NODE_ID
constexpr auto HYDRAULIC_LINE
constexpr auto LEFT_WHEEL_CODE
constexpr auto STATE_MSG
constexpr auto VDC_BUS
constexpr auto BTB_READY
constexpr auto DBG_LOG_MSG_2
constexpr auto PC_ALIVE
constexpr auto DBG_LOG_MSG
constexpr auto WHEEL_PRECISION
#define DEBUG_PRINT(str)
#define DEBUG_PRINT_VAR(var)
constexpr auto to_underlying(Enum e) noexcept
Definition enum_utils.hpp:4
#define BAMO_RESPONSE_ID
Definition logging.h:22
SystemData system_data
Definition main.cpp:10
CAN_message_t msg2
Definition message.cpp:6
bool pneumatic_line_pressure_1_
bool pneumatic_line_pressure_
bool pneumatic_line_pressure_2_
bool process_go_signal()
Processes the go signal.
Metro releaseEbsTimestamp
int _hydraulic_line_pressure
Definition sensors.hpp:9
double _right_wheel_rpm
Definition sensors.hpp:7
double _left_wheel_rpm
Definition sensors.hpp:8
The whole model of the system: holds all the data necessary.
Mission mission_
DigitalData digital_data_
R2DLogics r2d_logics_
FailureDetection failure_detection_
bool mission_finished_
Sensors sensors_
CAN_message_t msg
void create_left_wheel_msg(std::array< uint8_t, 5 > &msg, double value)
Function to create left wheel msg.
Definition utils.hpp:9