Skip to content
Merged
55 changes: 55 additions & 0 deletions lib/interfaces/include/BrakeRotorTemp.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
#ifndef BRAKEROTORTEMP_H
#define BRAKEROTORTEMP_H

/* External libraries */
#include "FlexCAN_T4.h"
#include "etl/singleton.h"


namespace BrakeRotorTempDefaultParams {
constexpr size_t channels_within_brake_temp_sensor = 16; // TODO: check if our sensors are actually 16 channel
}

struct BrakeTempSensorData_s {
float max_temp;
float avg_temp;

std::array<float, BrakeRotorTempDefaultParams::channels_within_brake_temp_sensor> channel_data;
};

struct BrakeTempData_s {
BrakeTempSensorData_s fl_sensor;
BrakeTempSensorData_s fr_sensor;
};

/**
* Interface to receive messages from the Izze Racing IRTS-60deg-v3 sensor
*/
class BrakeRotorTemp
{
public:
// default empty constructor will init state to zeros
BrakeRotorTemp() {}

/**
* Retrieves the latest data that has been sent from the sensors
* @return the latest temp data
*/
BrakeTempData_s getBrakeRotorTempData() const;

/**
* CAN receive function to parse the new CAN msg and update internal state
* Called by VCF's recv switch
* @param msg the CAN msg to parse
*/
void receiveBrakeRotorTempData(const CAN_message_t &msg);

private:
BrakeTempData_s _temp_data;

void _updateCalculatedValues(bool FR);
};

using BrakeRotorTempInstance = etl::singleton<BrakeRotorTemp>;

#endif // BRAKEROTORTEMP_H
4 changes: 2 additions & 2 deletions lib/interfaces/include/DashboardInterface.h
Original file line number Diff line number Diff line change
Expand Up @@ -52,14 +52,14 @@ class DashboardInterface
DashInputState_s get_dashboard_outputs();

// Stores outputs
DashInputState_s DashboardInterface::get_dashboard_stored_state();
DashInputState_s get_dashboard_stored_state();

/**
* Syncs stored outputs with last read outputs.
* Used to store previous state of buttons to determine if they are clicked or not.
* In other words, to find the falling edge.
*/
void DashboardInterface::sync_dashboard_stored_state();
void sync_dashboard_stored_state();

// Receiving
void receive_ACU_OK(const CAN_message_t &can_msg);
Expand Down
7 changes: 5 additions & 2 deletions lib/interfaces/include/VCFCANInterfaceImpl.h
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
#include "DashboardInterface.h"
#include "ACUInterface.h"
#include "VCRInterface.h"
#include "BrakeRotorTemp.h"

#include "SharedFirmwareTypes.h"

Expand All @@ -27,14 +28,16 @@ using FrontAuxCAN_t = FlexCAN_T4<CAN2, RX_SIZE_256, TX_SIZE_16>;

/* Interfaces accessible to this one */
struct CANInterfaces {
explicit CANInterfaces(DashboardInterface &dash_int, ACUInterface &acu_int, VCRInterface &vcr_int)
explicit CANInterfaces(DashboardInterface &dash_int, ACUInterface &acu_int, VCRInterface &vcr_int, BrakeRotorTemp &brake_rotor_temp_int)
: dash_interface(dash_int),
acu_interface(acu_int),
vcr_interface(vcr_int) {}
vcr_interface(vcr_int),
brake_rotor_temp_interface(brake_rotor_temp_int) {}

DashboardInterface &dash_interface;
ACUInterface &acu_interface;
VCRInterface &vcr_interface;
BrakeRotorTemp &brake_rotor_temp_interface;
};
using CANInterfacesInstance = etl::singleton<CANInterfaces>;

Expand Down
7 changes: 6 additions & 1 deletion lib/interfaces/include/VCFEthernetInterface.h
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
#include "ADCInterface.h"
#include "DashboardInterface.h"
#include "PedalsSystem.h"
#include "BrakeRotorTemp.h"
#include "SteeringSystem.h"

namespace VCFEthernetInterface
Expand All @@ -18,7 +19,11 @@ namespace VCFEthernetInterface
* @return A populated instance of the outgoing protoc struct.
*/
// hytech_msgs_VCFData_s make_vcf_data_msg(VCFData_s &shared_state);
hytech_msgs_VCFData_s make_vcf_data_msg(ADCInterface &ADCInterfaceInstance, DashboardInterface &dashInstance, PedalsSystem &pedalsInstance, SteeringSystem &steeringInstance);
hytech_msgs_VCFData_s make_vcf_data_msg(ADCInterface &ADCInterfaceInstance,
DashboardInterface &dashInstance,
PedalsSystem &pedalsInstance,
SteeringSystem &steeringInstance,
BrakeRotorTemp &brakeRotorTempInstance);

/**
* Function to take a populated protoc struct from VCR and update the VCF state. This is ONLY critical
Expand Down
179 changes: 179 additions & 0 deletions lib/interfaces/src/BrakeRotorTemp.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,179 @@
#include "BrakeRotorTemp.h"

#include "hytech.h"

BrakeTempData_s BrakeRotorTemp::getBrakeRotorTempData() const {
return _temp_data;
}

void BrakeRotorTemp::receiveBrakeRotorTempData(const CAN_message_t &msg) {
switch (msg.id) {
case FL_BRAKE_ROTOR_TEMP_CH1_CH4_CANID:
{
// unpack the msg
FL_BRAKE_ROTOR_TEMP_CH1_CH4_t unpacked_msg;
Unpack_FL_BRAKE_ROTOR_TEMP_CH1_CH4_hytech(&unpacked_msg, msg.buf, msg.len); // NOLINT array decay to pointer

// copy data over to interface data
std::get<0>(_temp_data.fl_sensor.channel_data) = HYTECH_brake_temp_channel_1_ro_fromS(unpacked_msg.brake_temp_channel_1_ro);
std::get<1>(_temp_data.fl_sensor.channel_data) = HYTECH_brake_temp_channel_2_ro_fromS(unpacked_msg.brake_temp_channel_2_ro);
std::get<2>(_temp_data.fl_sensor.channel_data) = HYTECH_brake_temp_channel_3_ro_fromS(unpacked_msg.brake_temp_channel_3_ro);
std::get<3>(_temp_data.fl_sensor.channel_data) = HYTECH_brake_temp_channel_4_ro_fromS(unpacked_msg.brake_temp_channel_4_ro);

// update FL outputs
_updateCalculatedValues(false);
break;
}

case FL_BRAKE_ROTOR_TEMP_CH5_CH8_CANID:
{
// unpack the msg
FL_BRAKE_ROTOR_TEMP_CH5_CH8_t unpacked_msg;
Unpack_FL_BRAKE_ROTOR_TEMP_CH5_CH8_hytech(&unpacked_msg, msg.buf, msg.len); // NOLINT array decay to pointer

// copy data over to interface data
std::get<4>(_temp_data.fl_sensor.channel_data) = HYTECH_brake_temp_channel_5_ro_fromS(unpacked_msg.brake_temp_channel_5_ro);
std::get<5>(_temp_data.fl_sensor.channel_data) = HYTECH_brake_temp_channel_6_ro_fromS(unpacked_msg.brake_temp_channel_6_ro);
std::get<6>(_temp_data.fl_sensor.channel_data) = HYTECH_brake_temp_channel_7_ro_fromS(unpacked_msg.brake_temp_channel_7_ro);
std::get<7>(_temp_data.fl_sensor.channel_data) = HYTECH_brake_temp_channel_8_ro_fromS(unpacked_msg.brake_temp_channel_8_ro);

// update FL outputs
_updateCalculatedValues(false);
break;
}

case FL_BRAKE_ROTOR_TEMP_CH9_CH12_CANID:
{
// unpack the msg
FL_BRAKE_ROTOR_TEMP_CH9_CH12_t unpacked_msg;
Unpack_FL_BRAKE_ROTOR_TEMP_CH9_CH12_hytech(&unpacked_msg, msg.buf, msg.len); // NOLINT array decay to pointer

// copy data over to interface data
std::get<8>(_temp_data.fl_sensor.channel_data) = HYTECH_brake_temp_channel_9_ro_fromS(unpacked_msg.brake_temp_channel_9_ro);
std::get<9>(_temp_data.fl_sensor.channel_data) = HYTECH_brake_temp_channel_10_ro_fromS(unpacked_msg.brake_temp_channel_10_ro);
std::get<10>(_temp_data.fl_sensor.channel_data) = HYTECH_brake_temp_channel_11_ro_fromS(unpacked_msg.brake_temp_channel_11_ro);
std::get<11>(_temp_data.fl_sensor.channel_data) = HYTECH_brake_temp_channel_12_ro_fromS(unpacked_msg.brake_temp_channel_12_ro);

// update FL outputs
_updateCalculatedValues(false);
break;
}

case FL_BRAKE_ROTOR_TEMP_CH13_CH16_CANID:
{
// unpack the msg
FL_BRAKE_ROTOR_TEMP_CH13_CH16_t unpacked_msg;
Unpack_FL_BRAKE_ROTOR_TEMP_CH13_CH16_hytech(&unpacked_msg, msg.buf, msg.len); // NOLINT array decay to pointer

// copy data over to interface data
std::get<12>(_temp_data.fl_sensor.channel_data) = HYTECH_brake_temp_channel_13_ro_fromS(unpacked_msg.brake_temp_channel_13_ro);
std::get<13>(_temp_data.fl_sensor.channel_data) = HYTECH_brake_temp_channel_14_ro_fromS(unpacked_msg.brake_temp_channel_14_ro);
std::get<14>(_temp_data.fl_sensor.channel_data) = HYTECH_brake_temp_channel_15_ro_fromS(unpacked_msg.brake_temp_channel_15_ro);
std::get<15>(_temp_data.fl_sensor.channel_data) = HYTECH_brake_temp_channel_16_ro_fromS(unpacked_msg.brake_temp_channel_16_ro);

// update FL outputs
_updateCalculatedValues(false);
break;
}

case FR_BRAKE_ROTOR_TEMP_CH1_CH4_CANID:
{
// unpack the msg
FR_BRAKE_ROTOR_TEMP_CH1_CH4_t unpacked_msg;
Unpack_FR_BRAKE_ROTOR_TEMP_CH1_CH4_hytech(&unpacked_msg, msg.buf, msg.len); // NOLINT array decay to pointer

// copy data over to interface data
std::get<0>(_temp_data.fr_sensor.channel_data) = HYTECH_brake_temp_channel_1_ro_fromS(unpacked_msg.brake_temp_channel_1_ro);
std::get<1>(_temp_data.fr_sensor.channel_data) = HYTECH_brake_temp_channel_2_ro_fromS(unpacked_msg.brake_temp_channel_2_ro);
std::get<2>(_temp_data.fr_sensor.channel_data) = HYTECH_brake_temp_channel_3_ro_fromS(unpacked_msg.brake_temp_channel_3_ro);
std::get<3>(_temp_data.fr_sensor.channel_data) = HYTECH_brake_temp_channel_4_ro_fromS(unpacked_msg.brake_temp_channel_4_ro);

// update FR outputs
_updateCalculatedValues(true);
break;
}

case FR_BRAKE_ROTOR_TEMP_CH5_CH8_CANID:
{
// unpack the msg
FR_BRAKE_ROTOR_TEMP_CH5_CH8_t unpacked_msg;
Unpack_FR_BRAKE_ROTOR_TEMP_CH5_CH8_hytech(&unpacked_msg, msg.buf, msg.len); // NOLINT array decay to pointer

// copy data over to interface data
std::get<4>(_temp_data.fr_sensor.channel_data) = HYTECH_brake_temp_channel_5_ro_fromS(unpacked_msg.brake_temp_channel_5_ro);
std::get<5>(_temp_data.fr_sensor.channel_data) = HYTECH_brake_temp_channel_6_ro_fromS(unpacked_msg.brake_temp_channel_6_ro);
std::get<6>(_temp_data.fr_sensor.channel_data) = HYTECH_brake_temp_channel_7_ro_fromS(unpacked_msg.brake_temp_channel_7_ro);
std::get<7>(_temp_data.fr_sensor.channel_data) = HYTECH_brake_temp_channel_8_ro_fromS(unpacked_msg.brake_temp_channel_8_ro);

// update FR outputs
_updateCalculatedValues(true);
break;
}

case FR_BRAKE_ROTOR_TEMP_CH9_CH12_CANID:
{
// unpack the msg
FR_BRAKE_ROTOR_TEMP_CH9_CH12_t unpacked_msg;
Unpack_FR_BRAKE_ROTOR_TEMP_CH9_CH12_hytech(&unpacked_msg, msg.buf, msg.len); // NOLINT array decay to pointer

// copy data over to interface data
std::get<8>(_temp_data.fr_sensor.channel_data) = HYTECH_brake_temp_channel_9_ro_fromS(unpacked_msg.brake_temp_channel_9_ro);
std::get<9>(_temp_data.fr_sensor.channel_data) = HYTECH_brake_temp_channel_10_ro_fromS(unpacked_msg.brake_temp_channel_10_ro);
std::get<10>(_temp_data.fr_sensor.channel_data) = HYTECH_brake_temp_channel_11_ro_fromS(unpacked_msg.brake_temp_channel_11_ro);
std::get<11>(_temp_data.fr_sensor.channel_data) = HYTECH_brake_temp_channel_12_ro_fromS(unpacked_msg.brake_temp_channel_12_ro);

// update FR outputs
_updateCalculatedValues(true);
break;
}

case FR_BRAKE_ROTOR_TEMP_CH13_CH16_CANID:
{
// unpack the msg
FR_BRAKE_ROTOR_TEMP_CH13_CH16_t unpacked_msg;
Unpack_FR_BRAKE_ROTOR_TEMP_CH13_CH16_hytech(&unpacked_msg, msg.buf, msg.len); // NOLINT array decay to pointer

// copy data over to interface data
std::get<12>(_temp_data.fr_sensor.channel_data) = HYTECH_brake_temp_channel_13_ro_fromS(unpacked_msg.brake_temp_channel_13_ro);
std::get<13>(_temp_data.fr_sensor.channel_data) = HYTECH_brake_temp_channel_14_ro_fromS(unpacked_msg.brake_temp_channel_14_ro);
std::get<14>(_temp_data.fr_sensor.channel_data) = HYTECH_brake_temp_channel_15_ro_fromS(unpacked_msg.brake_temp_channel_15_ro);
std::get<15>(_temp_data.fr_sensor.channel_data) = HYTECH_brake_temp_channel_16_ro_fromS(unpacked_msg.brake_temp_channel_16_ro);

// update FR outputs
_updateCalculatedValues(true);
break;
}

default:
break;
}
}

/**
* Helper method to update the calculated values of max and avg temps for each sensor after new data is
* received. Will only update for the specified sensor.
* @param sensor corresponds to which sensor was updated. FL = 0, FR = 1
*/
void BrakeRotorTemp::_updateCalculatedValues(bool FR) {
if (FR) { // check if FR needs to be updated
auto begin_iterator = _temp_data.fr_sensor.channel_data.begin();
auto end_iterator = _temp_data.fr_sensor.channel_data.end();

// update maximum value
_temp_data.fr_sensor.max_temp = *std::max_element(begin_iterator, end_iterator);

// update avg value
float sum = std::accumulate(begin_iterator, end_iterator, 0.0f); // find sum
_temp_data.fr_sensor.avg_temp = sum / static_cast<float>(BrakeRotorTempDefaultParams::channels_within_brake_temp_sensor);
} else { // otherwise update FL
auto begin_iterator = _temp_data.fl_sensor.channel_data.begin();
auto end_iterator = _temp_data.fl_sensor.channel_data.end();

// update maximum value
_temp_data.fl_sensor.max_temp = *std::max_element(begin_iterator, end_iterator);

// update avg value
float sum = std::accumulate(begin_iterator, end_iterator, 0.0f); // find sum
_temp_data.fl_sensor.avg_temp = sum / static_cast<float>(BrakeRotorTempDefaultParams::channels_within_brake_temp_sensor);
}
}
14 changes: 13 additions & 1 deletion lib/interfaces/src/VCFCANInterfaceImpl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ namespace VCFCANInterfaceImpl {

void on_faux_can_recv(const CAN_message_t &msg)
{
VCFCANInterfaceInstance::instance().TELEM_CAN.write(msg); //immediately forward onto telem can to view data
// VCFCANInterfaceInstance::instance().TELEM_CAN.write(msg); //immediately forward onto telem can to view data
uint8_t buf[sizeof(CAN_message_t)];
memmove(buf, &msg, sizeof(msg)); // NOLINT (memory operations are fine)
VCFCANInterfaceInstance::instance().front_aux_can_rx_buffer.push_back(buf, sizeof(CAN_message_t));
Expand Down Expand Up @@ -61,6 +61,18 @@ namespace VCFCANInterfaceImpl {
interfaces.vcr_interface.receive_inverter_status_4(msg);
break;
}
case FL_BRAKE_ROTOR_SENSOR_TEMP_CANID:
case FL_BRAKE_ROTOR_TEMP_CH1_CH4_CANID:
case FL_BRAKE_ROTOR_TEMP_CH5_CH8_CANID:
case FL_BRAKE_ROTOR_TEMP_CH9_CH12_CANID:
case FL_BRAKE_ROTOR_TEMP_CH13_CH16_CANID:
case FR_BRAKE_ROTOR_SENSOR_TEMP_CANID:
case FR_BRAKE_ROTOR_TEMP_CH1_CH4_CANID:
case FR_BRAKE_ROTOR_TEMP_CH5_CH8_CANID:
case FR_BRAKE_ROTOR_TEMP_CH9_CH12_CANID:
case FR_BRAKE_ROTOR_TEMP_CH13_CH16_CANID:
interfaces.brake_rotor_temp_interface.receiveBrakeRotorTempData(msg);
break;
default:
break;
}
Expand Down
9 changes: 8 additions & 1 deletion lib/interfaces/src/VCFEthernetInterface.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
#include "hytech_msgs_version.h"
#include "device_fw_version.h"

hytech_msgs_VCFData_s VCFEthernetInterface::make_vcf_data_msg(ADCInterface &ADCInterfaceInstance, DashboardInterface &dashInstance, PedalsSystem &pedalsInstance, SteeringSystem &steeringInstance)
hytech_msgs_VCFData_s VCFEthernetInterface::make_vcf_data_msg(ADCInterface &ADCInterfaceInstance, DashboardInterface &dashInstance, PedalsSystem &pedalsInstance, SteeringSystem &steeringInstance, BrakeRotorTemp &brakeRotorTempInstance)
{
hytech_msgs_VCFData_s out;

Expand All @@ -18,6 +18,7 @@ hytech_msgs_VCFData_s VCFEthernetInterface::make_vcf_data_msg(ADCInterface &ADCI
out.has_vcf_ethernet_link_data = true;
out.has_vcf_shutdown_data = true;
out.has_brake_pressure_data = true;
out.has_brake_rotor_temp_data = true;

// Load cells
out.front_loadcell_data.FL_loadcell_analog = static_cast<uint32_t>(ADCInterfaceInstance.get_filtered_FL_load_cell());
Expand Down Expand Up @@ -81,6 +82,12 @@ hytech_msgs_VCFData_s VCFEthernetInterface::make_vcf_data_msg(ADCInterface &ADCI
out.brake_pressure_data.front_brake_pressure = ADCInterfaceInstance.get_brake_pressure_front().conversion;
out.brake_pressure_data.rear_brake_pressure = ADCInterfaceInstance.get_brake_pressure_rear().conversion;

// Brake rotor temps
out.brake_rotor_temp_data.fl_max_brake_rotor_temp = brakeRotorTempInstance.getBrakeRotorTempData().fl_sensor.max_temp;
out.brake_rotor_temp_data.fl_avg_brake_rotor_temp = brakeRotorTempInstance.getBrakeRotorTempData().fl_sensor.avg_temp;
out.brake_rotor_temp_data.fr_max_brake_rotor_temp = brakeRotorTempInstance.getBrakeRotorTempData().fr_sensor.max_temp;
out.brake_rotor_temp_data.fr_avg_brake_rotor_temp = brakeRotorTempInstance.getBrakeRotorTempData().fr_sensor.avg_temp;

// Shutdown Senses
out.vcf_shutdown_data.d_inertia_switch_out_read = ADCInterfaceInstance.shdn_d().conversion;
out.vcf_shutdown_data.d_inertia_switch = ADCInterfaceInstance.shdn_d().conversion > SHDN_HIGH_THRESHOLD ? true : false;
Expand Down
11 changes: 5 additions & 6 deletions platformio.ini
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,11 @@
[common]
lib_deps_shared =
nanopb/Nanopb@0.4.91
https://github.com/hytech-racing/shared_firmware_systems.git
https://github.com/hytech-racing/shared_firmware_types.git#d9818df40287f21524de7e4b8558ced2023bd705
https://github.com/hytech-racing/shared_firmware_systems.git#af96a631bd76ac4da2084c6fa4faa62ca1bac9d1
https://github.com/hytech-racing/shared_firmware_types.git#956ce41b93d93975a56d33aa3abd7efac7706533
https://github.com/hytech-racing/HT_SCHED#c13cff762c59dd82a8c273e3e98fd1a80622656d
https://github.com/hytech-racing/HT_proto/releases/download/2026-04-19T22_02_36/hytech_msgs_pb_lib.tar.gz
https://github.com/hytech-racing/HT_CAN/releases/download/251/can_lib.tar.gz

https://github.com/hytech-racing/HT_proto/releases/download/2026-05-07T16_36_28/hytech_msgs_pb_lib.tar.gz
https://github.com/hytech-racing/HT_CAN/releases/download/254/can_lib.tar.gz
etlcpp/Embedded Template Library

; Teensy41 Environment. This environment is the primary environment for uploading code to the car.
Expand Down Expand Up @@ -52,7 +51,7 @@ lib_deps =
${common.lib_deps_shared}
arkhipenko/TaskScheduler@^3.8.5
https://github.com/ssilverman/QNEthernet#v0.26.0
https://github.com/hytech-racing/shared_firmware_interfaces.git
https://github.com/hytech-racing/shared_firmware_interfaces.git#d9f195a0e5640cd99411deb97c960edb7b455659
blemasle/MCP23017@^2.0.0
https://github.com/adafruit/Adafruit_NeoPixel.git
https://github.com/KSU-MS/pio-git-hash-gen#7998b5b3f8a2464209b0e73338717998bcf511ee
Expand Down
Loading
Loading