Skip to content

Commit

Permalink
Merge branch 'CASE_testbranch'
Browse files Browse the repository at this point in the history
  • Loading branch information
Luke-kC committed May 5, 2024
2 parents ebe6c6d + a373714 commit 78067d9
Show file tree
Hide file tree
Showing 16 changed files with 511 additions and 164 deletions.
17 changes: 17 additions & 0 deletions ETHERNET.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
```mermaid
flowchart TD
ethernet[ethernet port] --> qnethernet[encoded ethernet data packets]
qnethernet --> port[protobuf union msgs port]
port --> ht_eth[HT ethernet interface]
ht_eth --> union_dec[union msgs splitter]
union_dec --> int1[interface 1 message buffer]
union_dec --> int2[interface 2 message buffer]
union_dec --> intN[interface N message buffer]
```

## explanation

### receiving
Packets stream over ethernet and hit the ethernet port itself. The ethernet library has an internal queue for the UDP packets received. We know that a specific port id (say 4521) all messages will be a protobuf union msg that can contain only one of the types of messages that we will be sending (config control, TCU status, CASE msgs, etc.) and the union decoder method in the ethernet interface itself will handle this. The ethernet shall be able to receive multiple messages in one loop (of a limited number) and in between iterations of the loop the ethernet driver will hold the un-parsed messages in it's queue.

The union message decoder will handle parsing of all of the messages in the queue and will be able to determine what message the union pb packet holds. If all messages of a specific type are needed, The message decoder will then add the decoded particular protobuf message struct to the message queue in the respective interface that way if multiple messages of the same type appear in one loop iteration they can all be processed by the underlying system / interface. If the interface just needs the latest version of a message each loop, the decoder will just update the message instance in its respective interface.
60 changes: 60 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -296,3 +296,63 @@ new MCU code:
- interface level:
- hytech_can interface
- spi interfaces: SPI adcs for load cells, steering input, glv, etc.


```mermaid
flowchart LR
subgraph user_inputs[user defined inputs]
simulink
o_params
CAN_data
other_protos
end
subgraph user_interact[user interfaces]
fxglv_live
mcap
database
param_server
end
subgraph user_code_interact[user embedded code interfaces]
MCU
end
subgraph CASE_lib_repo[CASE lib repo gen]
CASE_lib
params
outputs
end
subgraph HT_params[HT_params repo gen]
param_defaults
nanopb
end
simulink[CASE simulink model] --> CASE_lib
simulink --> params[CASE defined params.json]
simulink --> outputs[CASE_outputs.proto]
params --> param_protos[params.proto]
params --> param_defaults[config defaults header]
param_defaults --> MCU
o_params[other params.json] --> param_protos
outputs --> h_proto
param_protos --> param_server[parameter server]
h_proto --> data_acq
data_acq --> fxglv_live[live foxglove]
data_acq --> mcap[output mcap files]
CAN_data[CAN message definitions] --> can_protos[CAN messages in hytech.proto]
can_protos --> h_proto
mcap --> database[mcap metadata defined database]
CASE_lib --> MCU
CAN_data --> dbc_h[dbc to C code gen hytech.h for CAN]
param_protos --> h_proto[hytech.proto]
dbc_h --> MCU
h_proto --> nanopb[protobuf msg defs ht_eth.pb.h]
nanopb --> MCU
other_protos[other msgs.proto]
other_protos --> h_proto
```
18 changes: 18 additions & 0 deletions include/MCU_rev15_defs.h
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,24 @@
#define __MCU15_H__

#include "PedalsSystem.h"
#include "NativeEthernet.h"

namespace EthParams
{
uint8_t default_MCU_MAC_address[6] =
{0x04, 0xe9, 0xe5, 0x10, 0x1f, 0x22};

const IPAddress default_MCU_ip(192, 168, 1, 30);
const IPAddress default_TCU_ip(192, 168, 1, 69);

const uint16_t default_protobuf_send_port = 2000;
const uint16_t default_protobuf_recv_port = 2001;

const IPAddress default_netmask(255, 255, 255, 0);
const IPAddress default_gateway(192, 168, 0, 1);

const uint16_t default_buffer_size = 512;
}

// pindefs
const int ADC1_CS = 34;
Expand Down
45 changes: 45 additions & 0 deletions lib/interfaces/include/ParameterInterface.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
#ifndef PARAMETERINTERFACE
#define PARAMETERINTERFACE
#include "MCUStateMachine.h"
#include "ht_eth.pb.h"

// yes, i know this is a singleton. im prototyping rn.
// TODO review if I can just give this a pointer to an ethernet port
class ParameterInterface
{
public:
ParameterInterface(): current_car_state_(CAR_STATE::STARTUP), params_need_sending_(false), config_({}) {}

void update_car_state(const CAR_STATE& state)
{
current_car_state_ = state;
}
void update_config(const config &config)
{
if(static_cast<int>(current_car_state_) < 5 ){
config_ = config;
}

}
config get_config()
{
return config_;
}
void set_params_need_sending()
{
params_need_sending_ = true;
}
void reset_params_need_sending()
{
params_need_sending_ = false;
}
bool params_need_sending() { return params_need_sending_; }

private:
CAR_STATE current_car_state_;
bool params_need_sending_ = false;
config config_;

};

#endif
78 changes: 78 additions & 0 deletions lib/interfaces/include/ProtobufMsgInterface.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
#ifndef PROTOBUFMSGINTERFACE
#define PROTOBUFMSGINTERFACE

#include "ht_eth.pb.h"
#include "pb_encode.h"
#include "pb_decode.h"
#include "pb_common.h"
#include "ParameterInterface.h"
#include "circular_buffer.h"
#include "NativeEthernet.h"
#include "MCU_rev15_defs.h"


struct ETHInterfaces
{
ParameterInterface* param_interface;
};

using recv_function_t = void (*)(const uint8_t* buffer, size_t packet_size, ETHInterfaces& interfaces);

// this should be usable with arbitrary functions idk something
void handle_ethernet_socket_receive(EthernetUDP* socket, recv_function_t recv_function, ETHInterfaces& interfaces)
{
int packet_size = socket->parsePacket();
if(packet_size > 0)
{
// Serial.println("packet size");
// Serial.println(packet_size);
uint8_t buffer[EthParams::default_buffer_size];
size_t read_bytes = socket->read(buffer, sizeof(buffer));
socket->read(buffer, UDP_TX_PACKET_MAX_SIZE);
recv_function(buffer, read_bytes, interfaces);
}
}

template <typename pb_struct>
bool handle_ethernet_socket_send_pb(EthernetUDP* socket, const pb_struct& msg, const pb_msgdesc_t* msg_desc)
{
socket->beginPacket(EthParams::default_TCU_ip, EthParams::default_protobuf_send_port);

uint8_t buffer[EthParams::default_buffer_size];
pb_ostream_t stream = pb_ostream_from_buffer(buffer, sizeof(buffer));
if (!pb_encode(&stream, msg_desc, &msg)) {
// You can handle error more explicitly by looking at stream.errmsg
return false;
}
auto message_length = stream.bytes_written;
socket->write(buffer, message_length);
socket->endPacket();
return true;
}

//
void recv_pb_stream_union_msg(const uint8_t *buffer, size_t packet_size, ETHInterfaces& interfaces)
{
pb_istream_t stream = pb_istream_from_buffer(buffer, packet_size);
HT_ETH_Union msg = HT_ETH_Union_init_zero;
if (pb_decode(&stream, HT_ETH_Union_fields, &msg))
{
// Serial.println("decoded!");

switch (msg.which_type_union)
{
case HT_ETH_Union_config__tag:
interfaces.param_interface->update_config(msg.type_union.config_);
break;
case HT_ETH_Union_get_config__tag:
interfaces.param_interface->set_params_need_sending();
break;
default:
break;
}
}
}



#endif
52 changes: 0 additions & 52 deletions lib/library.json

This file was deleted.

43 changes: 29 additions & 14 deletions lib/systems/include/CASESystem.h
Original file line number Diff line number Diff line change
Expand Up @@ -7,14 +7,18 @@
#include "DrivetrainSystem.h"
#include "SteeringSystem.h"
#include "MCUStateMachine.h"
#include "ProtobufMsgInterface.h"

struct CASEConfiguration
{
float AbsoluteTorqueLimit;
float yaw_pid_p;
float yaw_pid_i;
float yaw_pid_d;
float tcs_pid_p;
float tcs_pid_p_lowerBound_front;
float tcs_pid_p_upperBound_front;
float tcs_pid_p_lowerBound_rear;
float tcs_pid_p_upperBound_rear;
float tcs_pid_i;
float tcs_pid_d;
bool useLaunch;
Expand Down Expand Up @@ -47,6 +51,12 @@ struct CASEConfiguration
float DriveTorquePercentFront;
float BrakeTorquePercentFront;
float MechPowerMaxkW;
float launchLeftRightMaxDiff;
float tcs_pid_lower_rpm_front;
float tcs_pid_upper_rpm_front;
float tcs_pid_lower_rpm_rear;
float tcs_pid_upper_rpm_rear;
float maxNormalLoadBrakeScalingFront;

float max_rpm;
float max_regen_torque;
Expand All @@ -68,6 +78,7 @@ class CASESystem
message_queue *can_queue,
unsigned long controller_send_period_ms,
unsigned long vehicle_math_offset_ms,
unsigned long lowest_controller_send_period_ms,
CASEConfiguration config)
{
msg_queue_ = can_queue;
Expand All @@ -76,10 +87,13 @@ class CASESystem
config_ = config;
last_controller_pt1_send_time_ = 0;
last_controller_pt2_send_time_ = 0;
last_controller_pt3_send_time_ = 0;
last_lowest_priority_controller_send_time_ = 0;

controller_send_period_ms_ = controller_send_period_ms;
last_vehm_send_time_ = 0;
vehicle_math_offset_ms_ = vehicle_math_offset_ms;
lowest_priority_controller_send_period_ms_ = lowest_controller_send_period_ms;
}

/// @brief function that evaluates the CASE (controller and state estimation) system. updates the internal pstate_ and returns controller result
Expand All @@ -105,20 +119,21 @@ class CASESystem
bool start_button_pressed,
uint8_t vn_status);

void update_pid(float yaw_p, float yaw_i, float yaw_d, float tcs_p, float tcs_i, float tcs_d, float brake_p, float brake_i, float brake_d)
{
config_.yaw_pid_p = yaw_p;
config_.yaw_pid_p = yaw_i;
config_.yaw_pid_p = yaw_d;
// void update_pid(float yaw_p, float yaw_i, float yaw_d, float tcs_p, float tcs_i, float tcs_d, float brake_p, float brake_i, float brake_d)
// {
// config_.yaw_pid_p = yaw_p;
// config_.yaw_pid_p = yaw_i;
// config_.yaw_pid_p = yaw_d;

config_.tcs_pid_p = tcs_p;
config_.tcs_pid_i = tcs_i;
config_.tcs_pid_d = tcs_d;
// config_.tcs_pid_p = tcs_p;
// config_.tcs_pid_i = tcs_i;
// config_.tcs_pid_d = tcs_d;

// config_.yaw_pid_brakes_p = brake_p;
// config_.yaw_pid_brakes_i = brake_i;
// config_.yaw_pid_brakes_d = brake_d;
// }

config_.yaw_pid_brakes_p = brake_p;
config_.yaw_pid_brakes_i = brake_i;
config_.yaw_pid_brakes_d = brake_d;
}
float calculate_torque_request(const PedalsSystemData_s &pedals_data, float max_regen_torque, float max_rpm);
/// @brief configuration function to determine what CASE is using / turn on and off different features within CASE
/// @param config the configuration struct we will be setting
Expand All @@ -143,7 +158,7 @@ class CASESystem
message_queue *msg_queue_;
HT08_CASE case_;

unsigned long vn_active_start_time_, last_eval_time_, vehicle_math_offset_ms_, last_controller_pt1_send_time_, last_controller_pt2_send_time_, last_controller_pt3_send_time_, last_vehm_send_time_, controller_send_period_ms_;
unsigned long vn_active_start_time_, last_eval_time_, vehicle_math_offset_ms_, last_controller_pt1_send_time_, last_controller_pt2_send_time_, last_controller_pt3_send_time_, last_vehm_send_time_, controller_send_period_ms_, lowest_priority_controller_send_period_ms_, last_lowest_priority_controller_send_time_;
};

#include "CASESystem.tpp"
Expand Down
Loading

0 comments on commit 78067d9

Please sign in to comment.