Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .gitmodules
Original file line number Diff line number Diff line change
Expand Up @@ -3,4 +3,4 @@
url = https://github.com/HyperloopUPV-H8/ST-LIB
[submodule "Core/Inc/Communications/JSON_ADE"]
path = Core/Inc/Code_generation/JSON_ADE
url = https://github.com/HyperloopUPV-H8/JSON_ADE
url = https://github.com/HyperloopUPV-H8/adj
2 changes: 1 addition & 1 deletion CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ include(CTest)
enable_testing()

set(EXECUTABLE ${PROJECT_NAME}.elf)
set(BOARD_NAME "TEST" CACHE STRING "Board key from Core/Inc/Code_generation/JSON_ADE/boards.json")
set(BOARD_NAME "VCU" CACHE STRING "Board key from Core/Inc/Code_generation/JSON_ADE/boards.json" FORCE)
if(BOARD_NAME STREQUAL "")
message(FATAL_ERROR "BOARD_NAME cannot be empty")
endif()
Expand Down
2 changes: 1 addition & 1 deletion Core/Inc/Code_generation/JSON_ADE
51 changes: 34 additions & 17 deletions Core/Inc/Code_generation/Packet_generation/Packet_descriptions.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,17 +6,28 @@ def __init__(self,name:str,board:dict,JSONpath:str):
self.name = name
self.id = board["board_id"]
self.ip = board["board_ip"]

# Load backend IP from general_info.json
backend_ip = "0.0.0.0"
try:
with open(JSONpath + "/general_info.json") as f:
general_info = json.load(f)
if "addresses" in general_info and "backend" in general_info["addresses"]:
backend_ip = general_info["addresses"]["backend"]
except Exception as e:
print(f"Warning: Could not load backend IP from general_info.json: {e}")

#Sockets:
try:
with open(JSONpath+"/boards/"+name+"/sockets.json") as s:
socks = json.load(s)
self.sockets=self.SocketsDescription(socks,self.ip)
self.sockets = self.SocketsDescription(socks, self.ip, backend_ip)
except Exception as e:
raise Exception(f"Error in file {JSONpath}/boards/{name}/sockets.json: {e}")
#Packets:
self.sending_packets = []
self.data_size =0
self.order_size =0
self.data_size = 0
self.order_size = 0
self.measurement_lists = []
self.packets = {}
for measurement in board["measurements"]:
Expand Down Expand Up @@ -60,11 +71,11 @@ def fix_sendind_packets(sending_packets:list):
period_type = item.get("period_type")
socket = item.get("socket")
name = item.get("name")
key = (period,period_type, socket)
key = (period, period_type, socket)
lookup.setdefault(key, []).append(name)

for (period,period_type, socket), names in lookup.items():
entry = {"period": period,"period_type":period_type, "socket": socket}
for (period, period_type, socket), names in lookup.items():
entry = {"period": period, "period_type": period_type, "socket": socket}
if len(names) == 1:
entry["name"] = names[0]
else:
Expand All @@ -76,23 +87,30 @@ def fix_sendind_packets(sending_packets:list):


class SocketsDescription:
def __init__(self,sockets:list,board_ip:str):
self.allSockets=[]
def __init__(self, sockets: list, board_ip: str, backend_ip: str):
self.allSockets = []
self.ServerSockets = []
self.Sockets = []
self.DatagramSockets = []
self.board_ip = board_ip
self.backend_ip = backend_ip
for sock in sockets:
name = sock["name"].replace(" ", "_").replace("-", "_")
sock_type = sock["type"]
self.allSockets.append({"name": name,"type":sock_type})
self.allSockets.append({"name": name, "type": sock_type})

if sock_type == "ServerSocket":
self.ServerSockets.append({"name": name,"type":sock_type,"board_ip":self.board_ip, "port": sock["port"]})
self.ServerSockets.append({"name": name, "type": sock_type, "board_ip": self.board_ip, "port": sock["port"]})
elif sock_type == "Socket":
self.Sockets.append({"name": name,"type":sock_type,"board_ip":self.board_ip, "local_port": sock["local_port"], "remote_ip": sock["remote_ip"], "remote_port": sock["remote_port"]})
remote_ip = sock["remote_ip"]
if remote_ip == "backend":
remote_ip = self.backend_ip
self.Sockets.append({"name": name, "type": sock_type, "board_ip": self.board_ip, "local_port": sock["local_port"], "remote_ip": remote_ip, "remote_port": sock["remote_port"]})
elif sock_type == "DatagramSocket":
self.DatagramSockets.append({"name": name,"type":sock_type,"board_ip":self.board_ip, "port": sock["port"],"remote_ip":sock["remote_ip"]})
remote_ip = sock["remote_ip"]
if remote_ip == "backend":
remote_ip = self.backend_ip
self.DatagramSockets.append({"name": name, "type": sock_type, "board_ip": self.board_ip, "port": sock["port"], "remote_ip": remote_ip})



Expand All @@ -110,14 +128,11 @@ def __init__(self, packet:dict,measurements:list, filename:str="Unknown"):
self.measurements.append(MeasurmentsDescription(measurements,variable, filename))

@staticmethod
def check_for_sending(packet:dict):
def check_for_sending(packet: dict):
if "period" in packet and "period_type" in packet and "socket" in packet:
name = packet["name"].replace(" ", "_").replace("-", "_")
return {"name": name,"period": packet["period"],"period_type":packet["period_type"],"socket": packet["socket"]}
return {"name": name, "period": packet["period"], "period_type": packet["period_type"], "socket": packet["socket"]}

elif "period_ms" in packet and "socket" in packet:
name = packet["name"].replace(" ", "_").replace("-", "_")
return {"name": name,"period": packet["period_ms"],"period_type":"ms","socket": packet["socket"]}
else:
return None
class MeasurmentsDescription:
Expand Down Expand Up @@ -166,4 +181,6 @@ def _unsigned_int_correction(type:str):
type += "_t"
elif type == "float32":
type = "float"
elif type == "float64":
type = "double"
return type
35 changes: 16 additions & 19 deletions Core/Inc/Code_generation/Packet_generation/Packet_generation.py
Original file line number Diff line number Diff line change
Expand Up @@ -38,17 +38,17 @@ def GenerateDataEnum(board:BoardDescription):
return Enums


def GenerateDataPackets(board:BoardDescription):
Packets =[]
def GenerateDataPackets(board: BoardDescription):
Packets = []
totaldata = []
for packet in board.packets:
for packet_instance in board.packets[packet]:
if packet_instance.type != "order":
tempdata = ""
tempdata_but_pointer = ""
for variable in packet_instance.variables:
tempdata +=(str(variable) +",")
tempdata_but_pointer +=("&"+str(variable) +",")
tempdata += (str(variable) + ",")
tempdata_but_pointer += ("&" + str(variable) + ",")
if tempdata.endswith(","):
tempdata = tempdata[:-1]
if tempdata_but_pointer.endswith(","):
Expand All @@ -61,7 +61,7 @@ def GenerateDataPackets(board:BoardDescription):
"type": measurement.type
})

aux_packet = {"name": packet_instance.name, "data":tempdata_but_pointer.replace(" ", "_").replace("-", "_") , "id": packet_instance.id, "variables": packet_variables}
aux_packet = {"name": packet_instance.name, "data": tempdata_but_pointer.replace(" ", "_").replace("-", "_"), "id": packet_instance.id, "variables": packet_variables}
Packets.append(aux_packet)
for measurement in packet_instance.measurements:
aux_data = {"type": measurement.type, "name": measurement.id.replace(" ", "_").replace("-", "_")}
Expand Down Expand Up @@ -135,8 +135,8 @@ def Generate_DataPackets_hpp(board_input:str):

#--------------OrderPackets.hpp generation---------------#

def Get_order_context(board:BoardDescription):
def GenerateOrderEnum(board:BoardDescription):
def Get_order_context(board: BoardDescription):
def GenerateOrderEnum(board: BoardDescription):
Enums = []
for packet in board.packets:
for packet_instance in board.packets[packet]:
Expand All @@ -146,18 +146,17 @@ def GenerateOrderEnum(board:BoardDescription):
Enums.append(measurement.enum)
return Enums


def GenerateOrderPackets(board:BoardDescription):
Packets =[]
def GenerateOrderPackets(board: BoardDescription):
Packets = []
totaldata = []
for packet in board.packets:
for packet_instance in board.packets[packet]:
if packet_instance.type == "order":
tempdata = ""
tempdata_but_pointer = ""
for variable in packet_instance.variables:
tempdata +=(str(variable) +",")
tempdata_but_pointer +=("&"+str(variable) +",")
tempdata += (str(variable) + ",")
tempdata_but_pointer += ("&" + str(variable) + ",")
if tempdata.endswith(","):
tempdata = tempdata[:-1]
tempdata_but_pointer = tempdata_but_pointer[:-1]
Expand All @@ -169,17 +168,16 @@ def GenerateOrderPackets(board:BoardDescription):
"type": measurement.type
})

aux_packet = {"name": packet_instance.name, "data":tempdata_but_pointer , "id": packet_instance.id, "variables": packet_variables}
aux_packet = {"name": packet_instance.name, "data": tempdata_but_pointer, "id": packet_instance.id, "variables": packet_variables}
Packets.append(aux_packet)
for measurement in packet_instance.measurements:
aux_data = {"type": measurement.type, "name": measurement.id}
aux_data = {"type": measurement.type, "name": measurement.name}
if not any(x["name"] == aux_data["name"] for x in totaldata):
totaldata.append(aux_data)

return Packets,totaldata

return Packets, totaldata

packets,data = GenerateOrderPackets(board)
packets, data = GenerateOrderPackets(board)
context = {
"board": board.name,
"enums": GenerateOrderEnum(board),
Expand All @@ -203,6 +201,5 @@ def Generate_OrderPackets_hpp(board_input:str):
template = env.get_template("OrderTemplate.hpp")
context = Get_order_context(board_instance)


with open(order_packets_path,"w") as Output:
with open(order_packets_path, "w") as Output:
Output.write(template.render(context))
95 changes: 80 additions & 15 deletions Core/Src/Examples/LinearSensorCharacterization.cpp
Original file line number Diff line number Diff line change
@@ -1,13 +1,28 @@
#ifdef EXAMPLE_LINEAR_SENSOR_CHARACTERIZATION

#include "Communications/Packets/DataPackets.hpp"
#include "Communications/Packets/OrderPackets.hpp"
#include "ST-LIB.hpp"
#include "main.h"

using namespace ST_LIB;

constexpr auto led = ST_LIB::DigitalOutputDomain::DigitalOutput(ST_LIB::PB0);
double slope{1.0};
double offset{0.0};

double value{0.0};
double sensor_value{0.0};

double real_value{0.0};

constinit float raw_value{0.0f};
constexpr auto sensor = ADCDomain::ADC(
ST_LIB::PA0,
raw_value,
ADCDomain::Resolution::BITS_16,
ADCDomain::SampleTime::CYCLES_8_5
);

#ifdef STLIB_ETH
#if defined(USE_PHY_LAN8742)
constexpr auto eth = EthernetDomain::Ethernet(
EthernetDomain::PINSET_H10,
Expand All @@ -32,26 +47,76 @@ constexpr auto eth = EthernetDomain::Ethernet(
#else
#error "No PHY selected for Ethernet pinset selection"
#endif
using ExampleEthernetBoard = ST_LIB::Board<eth, led>;
#else
using ExampleEthernetBoard = ST_LIB::Board<led>;
#endif
using ExampleEthernetBoard = ST_LIB::Board<eth, sensor>;

extern "C" void Error_Handler(void) {
ErrorHandler("HAL error handler triggered");
while (1) {
}
}

void characterize(float raw, double read) {
// Incremental OLS accumulators for y = slope * x + offset.
static uint64_t sample_count{0};
static double sum_x{0.0};
static double sum_y{0.0};
static double sum_xx{0.0};
static double sum_xy{0.0};

const double x = static_cast<double>(raw);
const double y = read;

++sample_count;
sum_x += x;
sum_y += y;
sum_xx += x * x;
sum_xy += x * y;

if (sample_count < 2) {
offset = y - (slope * x);
return;
}

const double n = static_cast<double>(sample_count);
const double denominator = (n * sum_xx) - (sum_x * sum_x);
if (denominator == 0.0) {
return;
}

slope = ((n * sum_xy) - (sum_x * sum_y)) / denominator;
offset = (sum_y - (slope * sum_x)) / n;
}

int main(void) {
Hard_fault_check();

ExampleEthernetBoard::init();
#ifdef STLIB_ETH

Scheduler::start();
// Comms
OrderPackets::characterize_init(real_value);
DataPackets::characterization_init(slope, offset);
DataPackets::Value_init(sensor_value, value);
DataPackets::start();

OrderPackets::start();

// Instances
auto& eth_instance = ExampleEthernetBoard::instance_of<eth>();
#endif
auto& led_instance = ExampleEthernetBoard::instance_of<led>();
auto& sensor_instance = ExampleEthernetBoard::instance_of<sensor>();

led_instance.turn_on();
while (1) {
#ifdef STLIB_ETH
eth_instance.update();
#endif
Scheduler::update();

sensor_instance.read();
sensor_value = static_cast<double>(raw_value);
value = slope * sensor_value + offset;

if (OrderPackets::characterize_flag) {
OrderPackets::characterize_flag = false;
characterize(raw_value, real_value);
DataPackets::packets_socket->send_packet(*DataPackets::characterization_packet);
}
}
}

#endif // EXAMPLE_LINEAR_SENSOR_CHARACTERIZATION
#endif
6 changes: 3 additions & 3 deletions Core/Src/Runes/generated_metadata.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,11 @@
extern "C" {
const char DESCRIPTION[255] __attribute__((section(".metadata_pool"))) =
"****************" // placeholder for beggining
"20260206T223828" // DateTime using ISO-8601 format
"20260218T203535" // DateTime using ISO-8601 format
" " // alignment
"dcf817b3" // STLIB commit
"019403b6" // STLIB commit
"--------" // ADJ commit
"4b3d0ec4" // Board commit
"9c87b508" // Board commit
// the '=' is used for unparsing
;
}
Loading