Skip to content

Commit

Permalink
added in stats system and eeprom interface
Browse files Browse the repository at this point in the history
  • Loading branch information
RCMast3r committed Nov 10, 2024
1 parent 6afeb7b commit cb35439
Show file tree
Hide file tree
Showing 7 changed files with 185 additions and 1 deletion.
52 changes: 52 additions & 0 deletions lib/interfaces/include/EEPROMInterface.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
#ifndef __EEPROMINTERFACE_H__
#define __EEPROMINTERFACE_H__
#include <cstdlib>
#include <cstddef>
#include <SharedDataTypes.h>

// what this is:
// this interface will encompass any and all interfacing / writing of the eeprom on a micro platform (for now: teensy)

// first goal of this interface: be able to keep a log of our mileage with intermittent updates of the current km driven.

// we will be writing a struct to the memory that will contain the mileage data / any of the other
// data we will write and be able to read / recall from the eeprom


// this class will also manage the time in which we update the EEPROM values so that we can safely call the update function
// repeatedly without concern for the life of the underlying EEPROM.
class EEPROMInterface
{
public:
struct params
{
unsigned int write_interval_ms;
};

EEPROMInterface(params p = {120000000}) :
_params(p) {
_last_write_time_millis = 0;
_last_written_distance_m = 0;
_eeprom_written_data = {};
}

/// @brief initialize the EEPROMInterface by reading the last written data from the EEPROM.
// reads first the size of the low level data in bytes (a uint16_t) and then
// proceeds to read that amount of data.

/// @brief
/// @param reset_eeprom use this flag to write
void init(bool reset_eeprom);

void update_eeprom(const SharedCarState_s & car_state);
EEPROMInterfaceData_s get_current_data();

private:
unsigned long _last_write_time_millis;
int _last_written_distance_m;
params _params;
std::byte _data_buffer[4284]; // 4284 bytes is the size of the EEPROM on the teensy41

EEPROMInterfaceData_s _eeprom_written_data;
};
#endif // __EEPROMINTERFACE_H__
59 changes: 59 additions & 0 deletions lib/interfaces/src/EEPROMInterface.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
#include <EEPROMInterface.h>
#include <EEPROM.h>
#include <cmath>
#include <cstring>
#include <bit>

void EEPROMInterface::init(bool reset_eeprom)
{
// we know that the first 2 bytes tell us the size of the previously written data
std::byte size_data[2];

// if the reset eeprom flag is set, the eeprom previously written data will stay initialized to all zeros
// so all previous data will be lost if there was any written as the new sums will not include this previous data.
if(!reset_eeprom)
{
uint16_t written_size;

size_data[0] = static_cast<std::byte>(EEPROM.read(0));
size_data[1] = static_cast<std::byte>(EEPROM.read(1));
memcpy(&written_size, size_data, 2);

// proceed to read out all of the existing data

for(int i = 2; i < written_size; i++)
{
_data_buffer[i] = static_cast<std::byte>(EEPROM.read(i));
}

memcpy(&_eeprom_written_data, _data_buffer, written_size);
}
// go ahead and updating the written size to the current struct size as we are now finished using the data
uint16_t new_write_size = sizeof(LowLevelStatData_s);
memcpy(size_data, &new_write_size, 2);
EEPROM.write(0, static_cast<uint8_t>(size_data[0]));
EEPROM.write(1, static_cast<uint8_t>(size_data[1]));
}

void EEPROMInterface::update_eeprom(const SharedCarState_s &car_state)
{

if(car_state.systick.millis - _last_write_time_millis > _params.write_interval_ms)
{
// distanc_m current_session_distance = car_state.low_level_stats.session_distance;

// get the difference between the last written distance to the previous driven meters;

auto diff = static_cast<uint32_t>(abs(std::round(car_state.low_level_stats.session_distance)) - _last_written_distance_m);
_eeprom_written_data.current_driven_m += diff;
memcpy(_data_buffer, &_eeprom_written_data, sizeof(EEPROMInterfaceData_s));
size_t byte_size_to_write = sizeof(EEPROMInterfaceData_s);
for(size_t i = 0; i < byte_size_to_write; i++)
{
EEPROM.write(i+2, static_cast<uint8_t>(_data_buffer[i]));
}

_last_written_distance_m = car_state.low_level_stats.session_distance;
_last_write_time_millis = car_state.systick.millis;
}
}
17 changes: 17 additions & 0 deletions lib/shared_data/include/SharedDataTypes.h
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@

using speed_rpm = float;
using torque_nm = float;
using distance_m = float;

/// @brief Defines modes of torque limit to be processed in torque limit map for exact values.
enum class TorqueLimit_e
Expand Down Expand Up @@ -140,6 +141,21 @@ struct SteeringSystemData_s
SteeringSystemStatus_e status;
};

/// @brief the struct that will be serialized and written into the memory of the eeprom
struct __attribute__((packed)) EEPROMInterfaceData_s
{
uint32_t current_driven_m;
};

/// @brief low level stats. will contain things like current session
// driven meters, total faults occured during a session, etc. that will get written directly into the EEPROM
struct LowLevelStatData_s
{
// this is needed since if we change this struct we need to ensure that we read garbage data from the EEPROM on init
uint16_t low_level_data_size_in_bytes;
distance_m session_distance;
};

/// @brief car state struct that contains state of everything about the car including
// things such as steering, drivetrain, current system time, vectornav / INS data,
// etc. an instance of this struct is created in main and updated there by all of the systems
Expand All @@ -158,6 +174,7 @@ struct SharedCarState_s
DrivebrainData_s db_data;
TorqueControllerMuxStatus tc_mux_status;
bool drivebrain_timing_failure = false;
LowLevelStatData_s low_level_stats = {};
SharedCarState_s() = delete;
SharedCarState_s(const SysTick_s &_systick,
const SteeringSystemData_s &_steering_data,
Expand Down
22 changes: 22 additions & 0 deletions lib/systems/include/StatsSystem.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
#ifndef __STATSSYSTEM_H__
#define __STATSSYSTEM_H__

#include <SharedDataTypes.h>
#include <Utility.h>

class StatsSystem
{
public:
StatsSystem() {
_prev_dt_s = 0.0f;
_last_stat_update_timestamp = 0;
_current_data = {};
}
LowLevelStatData_s get_latest_vehicle_stats(const SharedCarState_s& veh_state);
private:
float _prev_dt_s;
unsigned long _last_stat_update_timestamp;
LowLevelStatData_s _current_data;

};
#endif // __STATSSYSTEM_H__
24 changes: 24 additions & 0 deletions lib/systems/src/StatsSystem.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
#include <StatsSystem.h>

LowLevelStatData_s StatsSystem::get_latest_vehicle_stats(const SharedCarState_s &veh_state)
{
if (_last_stat_update_timestamp == 0)
{
_prev_dt_s = 0.0f;
_last_stat_update_timestamp = veh_state.systick.millis;
}
else
{
_prev_dt_s = (veh_state.systick.millis - _last_stat_update_timestamp) / 1000.0f;
}

float avg_rpm = 0;
for (int i = 0; i < NUM_MOTORS; i++)
{
avg_rpm += veh_state.drivetrain_data.measuredSpeeds[i];
}

avg_rpm = avg_rpm / static_cast<float>(NUM_MOTORS);
_current_data.session_distance += _prev_dt_s * (avg_rpm * RPM_TO_METERS_PER_SECOND);
return _current_data;
}
1 change: 1 addition & 0 deletions platformio.ini
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,7 @@ monitor_speed = 115200
upload_protocol = teensy-cli
extra_scripts = pre:extra_script.py
lib_deps =
https://github.com/PaulStoffregen/EEPROM.git
${common.lib_deps_shared}
Nanopb
SPI
Expand Down
11 changes: 10 additions & 1 deletion src/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@
#include "SABInterface.h"
#include "VectornavInterface.h"
#include "LoadCellInterface.h"
#include "EEPROMInterface.h"

/* Systems */
#include "SysClock.h"
Expand All @@ -40,6 +41,7 @@
#include "TorqueControllerMux.h"
#include "TorqueControllers.h"
#include "CASESystem.h"
#include "StatsSystem.h"

// /* State machine */
#include "MCUStateMachine.h"
Expand Down Expand Up @@ -208,6 +210,8 @@ struct inverters
InvInt_t rr = InvInt_t(&CAN2_txBuffer, ID_MC4_SETPOINTS_COMMAND);
} inv;

EEPROMInterface eeprom_interface;

// /*
// SYSTEMS
// */
Expand Down Expand Up @@ -321,6 +325,8 @@ TCMuxType torque_controller_mux({static_cast<Controller *>(&tc_simple),
static_cast<Controller *>(&db_controller)},
{false, false, true, false, true});

StatsSystem stats_system;

/* Declare state machine */
MCUStateMachine<DriveSys_t> fsm(&buzzer, &drivetrain, &dashboard, &pedals_system, &torque_controller_mux, &safety_system);

Expand Down Expand Up @@ -444,6 +450,10 @@ void loop()
car_state_inst.drivebrain_timing_failure = db_controller.get_timing_failure_status();
hytech_msgs_MCUOutputData out_eth_msg = db_eth_interface.make_db_msg(car_state_inst);

car_state_inst.low_level_stats = stats_system.get_latest_vehicle_stats(car_state_inst);

eeprom_interface.update_eeprom(car_state_inst);

handle_ethernet_interface_comms(curr_tick, out_eth_msg);

tick_all_systems(curr_tick);
Expand Down Expand Up @@ -545,7 +555,6 @@ void init_all_CAN_devices()

void tick_all_interfaces(const SysTick_s &current_system_tick)
{

TriggerBits_s t = current_system_tick.triggers;
if (t.trigger10) // 10Hz
{
Expand Down

0 comments on commit cb35439

Please sign in to comment.