Skip to content

Commit a683269

Browse files
authored
Feature/drivebrain can integrity (#64)
* break out latencies * mid testing * tested on the car * created a seperate task for this * pluh * define shared interfaces version * updated firmware interface * saving * passes unit tests * fix linter issues * fix shared_firmware_types * pluh
1 parent aa26441 commit a683269

17 files changed

+261
-177
lines changed

include/VCR_Constants.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -111,6 +111,8 @@ constexpr unsigned long ams_update_period_us = 5000; // 5 000 us
111111
constexpr unsigned long ams_priority = 2;
112112
constexpr unsigned long suspension_can_period_us = 4000; // 4 000 us = 250 Hz
113113
constexpr unsigned long suspension_priority = 4;
114+
constexpr unsigned long controls_can_period_us = 4000; // 4 000 us = 250 Hz
115+
constexpr unsigned long controls_priority = 8;
114116
constexpr unsigned long ethernet_update_period = 100000; // 100 000 us = 10 Hz
115117
constexpr unsigned long ethernet_send_priority = 6;
116118
constexpr unsigned long inv_send_period = 5000; // 5 000 us = 200 Hz

include/VCR_InterfaceTasks.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,11 @@ HT_TASK::TaskResponse read_ioexpander(const unsigned long& sysMicros, const HT_T
5555
*/
5656
HT_TASK::TaskResponse enqueue_suspension_CAN_data(const unsigned long& sysMicros, const HT_TASK::TaskInfo& taskInfo); // NOLINT (capitalized CAN)
5757

58+
/**
59+
* Handles sending controls info for drivebrain (latencies and stuff)
60+
*/
61+
HT_TASK::TaskResponse enqueue_controls_CAN_data(const unsigned long& sysMicro, const HT_TASK::TaskInfo& taskInfo);
62+
5863
/**
5964
* Handles sending of coolant temperature data
6065
*/

include/controls.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,9 @@ class VCRControls
4848

4949
bool drivebrain_is_in_control();
5050
bool drivebrain_timing_failure();
51+
52+
void send_controls_can_messages();
53+
5154
private:
5255
TorqueControllerSimple _mode0; // this needs to be first for tc_mux to have a valid capture
5356
LoadCellVectoringTorqueController _mode1;

lib/interfaces/include/DrivebrainInterface.h

Lines changed: 13 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -24,15 +24,22 @@ class DrivebrainInterface {
2424
const ThermistorData_s &flowmeter_data,
2525
IPAddress drivebrain_ip,
2626
uint16_t vcr_data_port, qindesign::network::EthernetUDP *udp_socket);
27-
void receive_drivebrain_speed_command(const CAN_message_t &msg, unsigned long curr_millis);
28-
void receive_drivebrain_torque_lim_command(const CAN_message_t &msg, unsigned long curr_millis);
27+
void receive_drivebrain_speed_command_telem(const CAN_message_t &msg, unsigned long curr_millis);
28+
29+
void receive_drivebrain_torque_lim_command_telem(const CAN_message_t &msg, unsigned long curr_millis);
30+
31+
void receive_drivebrain_speed_command_auxillary(const CAN_message_t &msg, unsigned long curr_millis);
32+
33+
void receive_drivebrain_torque_lim_command_auxillary(const CAN_message_t &msg, unsigned long curr_millis);
2934

3035
void handle_enqueue_suspension_CAN_data();
3136

3237
void handle_enqueue_coolant_temp_CAN_data();
3338

3439
void handle_send_ethernet_data(const hytech_msgs_VCRData_s &data);
35-
StampedDrivetrainCommand_s get_latest_data();
40+
41+
StampedDrivetrainCommand_s get_latest_telem_drivebrain_command();
42+
StampedDrivetrainCommand_s get_latest_auxillary_drivebrain_command();
3643

3744
private:
3845
struct {
@@ -49,7 +56,9 @@ class DrivebrainInterface {
4956
IPAddress _drivebrain_ip;
5057
uint16_t _vcr_data_port;
5158
qindesign::network::EthernetUDP *_udp_socket;
52-
StampedDrivetrainCommand_s _latest_drivebrain_command = {};
59+
60+
StampedDrivetrainCommand_s _latest_drivebrain_command_telem = {};
61+
StampedDrivetrainCommand_s _latest_drivebrain_command_auxillary = {};
5362
};
5463

5564
using DrivebrainInterfaceInstance = etl::singleton<DrivebrainInterface>;

lib/interfaces/include/VCRCANInterfaceImpl.h

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -66,26 +66,27 @@ using CANInterfacesInstance = etl::singleton<CANInterfaces>;
6666

6767
namespace VCRCANInterfaceImpl {
6868

69-
extern CANRXBufferType CAN1_rxBuffer;
69+
extern CANRXBufferType auxillary_can_rx_buffer;
7070
extern CANRXBufferType inverter_can_rx_buffer;
7171
extern CANRXBufferType telem_can_rx_buffer;
7272

7373
/* TX buffer for CAN1 */
74-
extern CANTXBufferType CAN1_txBuffer;
74+
extern CANTXBufferType auxillary_can_tx_buffer;
7575
/* TX buffer for CAN2 */
7676
extern CANTXBufferType inverter_can_tx_buffer;
7777
/* TX buffer for CAN3 */
7878
extern CANTXBufferType telem_can_tx_buffer;
7979

80+
extern FlexCAN_T4<CAN1, RX_SIZE_256, TX_SIZE_16> AUXILLARY_CAN;
8081
extern FlexCAN_T4<CAN3, RX_SIZE_256, TX_SIZE_16> TELEM_CAN; // gets defined in main as of right now
8182
extern FlexCAN_T4<CAN2, RX_SIZE_256, TX_SIZE_16> INVERTER_CAN; // gets defined in main as of right now
8283
//extern FlexCAN_T4<CAN1, RX_SIZE_256, TX_SIZE_16> CAN_1;
8384

8485

85-
void on_can1_receive(const CAN_message_t &msg);
86+
void on_auxillary_can_receive(const CAN_message_t &msg);
8687
void on_inverter_can_receive(const CAN_message_t &msg);
8788
void on_telem_can_receive(const CAN_message_t &msg);
88-
void vcr_CAN_recv(CANInterfaces &interfaces, const CAN_message_t &msg, unsigned long millis);
89+
void vcr_CAN_recv(CANInterfaces &interfaces, const CAN_message_t &msg, unsigned long millis, CANInterfaceType_e interface_type);
8990

9091
void send_all_CAN_msgs(CANTXBufferType &buffer, FlexCAN_T4_Base *can_interface);
9192

lib/interfaces/src/DrivebrainInterface.cpp

Lines changed: 55 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
#include "hytech_msgs.pb.h"
1111
#include <cstdint>
1212

13+
1314
DrivebrainInterface::DrivebrainInterface(const RearLoadCellData_s &rear_load_cell_data,
1415
const RearSusPotData_s &rear_suspot_data,
1516
const ThermistorData_s &coolant_temperature_data_0,
@@ -27,36 +28,78 @@ DrivebrainInterface::DrivebrainInterface(const RearLoadCellData_s &rear_load_cel
2728
_vcr_data_port(vcr_data_port),
2829
_udp_socket(udp_socket) { };
2930

30-
StampedDrivetrainCommand_s DrivebrainInterface::get_latest_data() {
31-
return _latest_drivebrain_command;
31+
StampedDrivetrainCommand_s DrivebrainInterface::get_latest_telem_drivebrain_command() {
32+
return _latest_drivebrain_command_telem;
33+
}
34+
35+
StampedDrivetrainCommand_s DrivebrainInterface::get_latest_auxillary_drivebrain_command() {
36+
return _latest_drivebrain_command_auxillary;
37+
}
38+
39+
40+
void DrivebrainInterface::receive_drivebrain_speed_command_telem(const CAN_message_t &msg,
41+
unsigned long curr_millis) {
42+
DRIVEBRAIN_SPEED_SET_INPUT_t drivebrain_msg;
43+
44+
Unpack_DRIVEBRAIN_SPEED_SET_INPUT_hytech(&drivebrain_msg, &msg.buf[0], msg.len);
45+
46+
_latest_drivebrain_command_telem.desired_speeds.recvd = true;
47+
_latest_drivebrain_command_telem.desired_speeds.last_recv_millis = curr_millis;
48+
49+
_latest_drivebrain_command_telem.desired_speeds.veh_vec_data = {
50+
static_cast<float>(drivebrain_msg.drivebrain_set_rpm_fl),
51+
static_cast<float>(drivebrain_msg.drivebrain_set_rpm_fr),
52+
static_cast<float>(drivebrain_msg.drivebrain_set_rpm_rl),
53+
static_cast<float>(drivebrain_msg.drivebrain_set_rpm_rr)};
54+
};
55+
56+
void DrivebrainInterface::receive_drivebrain_torque_lim_command_telem(const CAN_message_t &msg,
57+
unsigned long curr_millis) {
58+
DRIVEBRAIN_TORQUE_LIM_INPUT_t drivebrain_msg;
59+
60+
Unpack_DRIVEBRAIN_TORQUE_LIM_INPUT_hytech(&drivebrain_msg, &msg.buf[0], msg.len);
61+
62+
_latest_drivebrain_command_telem.torque_limits.recvd = true;
63+
_latest_drivebrain_command_telem.torque_limits.last_recv_millis = curr_millis;
64+
65+
_latest_drivebrain_command_telem.torque_limits.veh_vec_data = {
66+
static_cast<float>(
67+
HYTECH_drivebrain_torque_fl_ro_fromS(drivebrain_msg.drivebrain_torque_fl_ro)),
68+
static_cast<float>(
69+
HYTECH_drivebrain_torque_fr_ro_fromS(drivebrain_msg.drivebrain_torque_fr_ro)),
70+
static_cast<float>(
71+
HYTECH_drivebrain_torque_rl_ro_fromS(drivebrain_msg.drivebrain_torque_rl_ro)),
72+
static_cast<float>(
73+
HYTECH_drivebrain_torque_rr_ro_fromS(drivebrain_msg.drivebrain_torque_rr_ro))};
3274
}
3375

34-
void DrivebrainInterface::receive_drivebrain_speed_command(const CAN_message_t &msg,
76+
77+
void DrivebrainInterface::receive_drivebrain_speed_command_auxillary(const CAN_message_t &msg,
3578
unsigned long curr_millis) {
3679
DRIVEBRAIN_SPEED_SET_INPUT_t drivebrain_msg;
3780

3881
Unpack_DRIVEBRAIN_SPEED_SET_INPUT_hytech(&drivebrain_msg, &msg.buf[0], msg.len);
3982

40-
_latest_drivebrain_command.desired_speeds.recvd = true;
41-
_latest_drivebrain_command.desired_speeds.last_recv_millis = curr_millis;
83+
_latest_drivebrain_command_auxillary.desired_speeds.recvd = true;
84+
_latest_drivebrain_command_auxillary.desired_speeds.last_recv_millis = curr_millis;
4285

43-
_latest_drivebrain_command.desired_speeds.veh_vec_data = {
86+
_latest_drivebrain_command_auxillary.desired_speeds.veh_vec_data = {
4487
static_cast<float>(drivebrain_msg.drivebrain_set_rpm_fl),
4588
static_cast<float>(drivebrain_msg.drivebrain_set_rpm_fr),
4689
static_cast<float>(drivebrain_msg.drivebrain_set_rpm_rl),
4790
static_cast<float>(drivebrain_msg.drivebrain_set_rpm_rr)};
4891
};
4992

50-
void DrivebrainInterface::receive_drivebrain_torque_lim_command(const CAN_message_t &msg,
93+
void DrivebrainInterface::receive_drivebrain_torque_lim_command_auxillary(const CAN_message_t &msg,
5194
unsigned long curr_millis) {
5295
DRIVEBRAIN_TORQUE_LIM_INPUT_t drivebrain_msg;
5396

5497
Unpack_DRIVEBRAIN_TORQUE_LIM_INPUT_hytech(&drivebrain_msg, &msg.buf[0], msg.len);
5598

56-
_latest_drivebrain_command.torque_limits.recvd = true;
57-
_latest_drivebrain_command.torque_limits.last_recv_millis = curr_millis;
99+
_latest_drivebrain_command_auxillary.torque_limits.recvd = true;
100+
_latest_drivebrain_command_auxillary.torque_limits.last_recv_millis = curr_millis;
58101

59-
_latest_drivebrain_command.torque_limits.veh_vec_data = {
102+
_latest_drivebrain_command_auxillary.torque_limits.veh_vec_data = {
60103
static_cast<float>(
61104
HYTECH_drivebrain_torque_fl_ro_fromS(drivebrain_msg.drivebrain_torque_fl_ro)),
62105
static_cast<float>(
@@ -69,11 +112,12 @@ void DrivebrainInterface::receive_drivebrain_torque_lim_command(const CAN_messag
69112

70113
void DrivebrainInterface::handle_enqueue_suspension_CAN_data() {
71114
REAR_SUSPENSION_t rear_sus_msg;
115+
72116
rear_sus_msg.rl_load_cell = _suspension_data.rear_load_cell_data.RL_loadcell_analog;
73117
rear_sus_msg.rr_load_cell = _suspension_data.rear_load_cell_data.RR_loadcell_analog;
74118
rear_sus_msg.rl_shock_pot = _suspension_data.rear_suspot_data.RL_sus_pot_analog;
75119
rear_sus_msg.rr_shock_pot = _suspension_data.rear_suspot_data.RR_sus_pot_analog;
76-
120+
77121
CAN_util::enqueue_msg(&rear_sus_msg, &Pack_REAR_SUSPENSION_hytech,
78122
VCRCANInterfaceImpl::telem_can_tx_buffer);
79123
}

lib/interfaces/src/VCRCANInterfaceImpl.cpp

Lines changed: 16 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -6,20 +6,20 @@
66
namespace VCRCANInterfaceImpl {
77

88
// global forwards
9-
CANRXBufferType CAN1_rxBuffer; // can1 = aux can
9+
CANRXBufferType auxillary_can_rx_buffer;
1010
CANRXBufferType inverter_can_rx_buffer;
1111
CANRXBufferType telem_can_rx_buffer;
1212

13-
CANTXBufferType CAN1_txBuffer;
13+
CANTXBufferType auxillary_can_tx_buffer;
1414
CANTXBufferType inverter_can_tx_buffer;
1515
CANTXBufferType telem_can_tx_buffer;
1616

1717

1818

19-
void on_can1_receive(const CAN_message_t &msg) {
19+
void on_auxillary_can_receive(const CAN_message_t &msg) {
2020
uint8_t buf[sizeof(CAN_message_t)];
2121
memmove(buf, &msg, sizeof(msg));
22-
CAN1_rxBuffer.push_back(buf, sizeof(CAN_message_t));
22+
auxillary_can_rx_buffer.push_back(buf, sizeof(CAN_message_t));
2323
}
2424

2525
void on_inverter_can_receive(const CAN_message_t &msg) {
@@ -35,7 +35,7 @@ void on_telem_can_receive(const CAN_message_t &msg) {
3535
telem_can_rx_buffer.push_back(buf, sizeof(CAN_message_t));
3636
}
3737

38-
void vcr_CAN_recv(CANInterfaces &interfaces, const CAN_message_t &msg, unsigned long millis) {
38+
void vcr_CAN_recv(CANInterfaces &interfaces, const CAN_message_t &msg, unsigned long millis, CANInterfaceType_e interface_type) {
3939
switch (msg.id) {
4040

4141
case PEDALS_SYSTEM_DATA_CANID:
@@ -60,11 +60,20 @@ void vcr_CAN_recv(CANInterfaces &interfaces, const CAN_message_t &msg, unsigned
6060
}
6161
case DRIVEBRAIN_TORQUE_LIM_INPUT_CANID:
6262
{
63-
interfaces.db_interface.receive_drivebrain_torque_lim_command(msg, millis);
63+
if (interface_type == CANInterfaceType_e::AUX) {
64+
interfaces.db_interface.receive_drivebrain_torque_lim_command_auxillary(msg, millis);
65+
} else if (interface_type == CANInterfaceType_e::TELEM) {
66+
interfaces.db_interface.receive_drivebrain_torque_lim_command_telem(msg, millis);
67+
}
6468
break;
6569
}
6670
case DRIVEBRAIN_SPEED_SET_INPUT_CANID: {
67-
interfaces.db_interface.receive_drivebrain_speed_command(msg, millis);
71+
if (interface_type == CANInterfaceType_e::AUX) {
72+
interfaces.db_interface.receive_drivebrain_speed_command_auxillary(msg, millis);
73+
} else if (interface_type == CANInterfaceType_e::TELEM) {
74+
interfaces.db_interface.receive_drivebrain_speed_command_telem(msg, millis);
75+
}
76+
interfaces.db_interface.receive_drivebrain_speed_command_telem(msg, millis);
6877
break;
6978
}
7079

lib/systems/include/DrivetrainSystem.h

Lines changed: 1 addition & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -14,18 +14,7 @@
1414
#include <shared_types.h>
1515
#include "SystemTimeInterface.h"
1616

17-
// requirements:
18-
// - [x] must support ability to initialize the drivetrain
19-
// - [x] ability to command inverters individually and be able to return a failure status when attempting to send invalid command for a certain state
20-
// - [x] contain a state machine for managing the state of the drivetrain as a whole (aka: all inverters have the same state)
21-
// - [x] initialization states included
22-
// - [ ] different control mode states
23-
// - [x] single point of interaction / control of the drivetrain that can receive "commands"
24-
// (at least for now, need to see how this works out once we start using it)
25-
// - [x] be decoupled from the inverter class
26-
// std::function / etl::delegate registered functions for the inverter interface. mostly for ease of testing.
27-
// - [x] be able to reset drivetrain
28-
// - [ ]
17+
2918

3019
/**
3120
* When user calls evaluate_drivetrain(), this is part of the returned status to

0 commit comments

Comments
 (0)