diff --git a/Core/Inc/Communications/Packets/DataPackets.hpp b/Core/Inc/Communications/Packets/DataPackets.hpp new file mode 100644 index 00000000..42adabf5 --- /dev/null +++ b/Core/Inc/Communications/Packets/DataPackets.hpp @@ -0,0 +1,39 @@ +#include "ST-LIB.hpp" + +//Data packets for LCU +class DataPacket{ + +enum class general_state{ + DEFINING, +CONNECTING, +OPERATIONAL, +FAULT +}; +enum class slave_state{ + DEFINING, +CONNECTING, +OPERATIONAL, +FAULT +}; + + private: + constexpr static size_t size =2; + uint32_t id{0}; + public: + std::array packets; + StackPacket* levitation_control_data; + StackPacket* lcu_data; + + + DataPacket(uint16_t &idpacket315,general_state &general_state,slave_state &slave_state,float32 &lcu_coil_temp_1,float32 &lcu_coil_temp_2,float32 &lcu_coil_temp_3,float32 &lcu_coil_temp_4,float32 &lcu_coil_temp_5,float32 &lcu_coil_temp_6,float32 &lcu_coil_temp_7,float32 &lcu_coil_temp_8,float32 &lcu_coil_temp_9,float32 &lcu_coil_temp_10,float32 &lcu_driver_temp_1,float32 &lcu_driver_temp_2,float32 &lcu_driver_temp_3,float32 &lcu_driver_temp_4,float32 &lcu_driver_temp_5,float32 &lcu_driver_temp_6,float32 &lcu_driver_temp_7,float32 &lcu_driver_temp_8,float32 &lcu_driver_temp_9,float32 &lcu_driver_temp_10,float32 &lcu_coil_current_1,float32 &lcu_coil_current_2,float32 &lcu_coil_current_3,float32 &lcu_coil_current_4,float32 &lcu_coil_current_5,float32 &lcu_coil_current_6,float32 &lcu_coil_current_7,float32 &lcu_coil_current_8,float32 &lcu_coil_current_9,float32 &lcu_coil_current_10,float32 &lcu_vbat_1,float32 &lcu_vbat_2,float32 &lcu_vbat_3,float32 &lcu_vbat_4,float32 &lcu_vbat_5,float32 &lcu_vbat_6,float32 &lcu_vbat_7,float32 &lcu_vbat_8,float32 &lcu_vbat_9,float32 &lcu_vbat_10,float32 &lcu_airgap_1,float32 &lcu_airgap_2,float32 &lcu_airgap_3,float32 &lcu_airgap_4,float32 &lcu_airgap_5,float32 &lcu_airgap_6,float32 &lcu_airgap_7,float32 &lcu_airgap_8,uint16_t &idpacket316,uint32_t ¤t_control_frequency,uint32_t &levitation_control_frequency,float32 &lcu_coil_current_ref_1,float32 &lcu_coil_current_ref_2,float32 &lcu_coil_current_ref_3,float32 &lcu_coil_current_ref_4,float32 &lcu_coil_current_ref_5,float32 &lcu_coil_current_ref_6,float32 &lcu_coil_current_ref_7,float32 &lcu_coil_current_ref_8,float32 &lcu_coil_current_ref_9,float32 &lcu_coil_current_ref_10,float32 &pos_y,float32 &pos_y_d,float32 &pos_y_i,float32 &pos_z,float32 &pos_z_d,float32 &pos_z_i,float32 &pos_rot_x,float32 &pos_rot_x_d,float32 &pos_rot_x_i,float32 &pos_rot_y,float32 &pos_rot_y_d,float32 &pos_rot_y_i,float32 &pos_rot_z,float32 &pos_rot_z_d,float32 &pos_rot_z_i) +{ + + levitation_control_data = new StackPacket(idpacket316,current_control_frequency,levitation_control_frequency,lcu_coil_current_ref_1,lcu_coil_current_ref_2,lcu_coil_current_ref_3,lcu_coil_current_ref_4,lcu_coil_current_ref_5,lcu_coil_current_ref_6,lcu_coil_current_ref_7,lcu_coil_current_ref_8,lcu_coil_current_ref_9,lcu_coil_current_ref_10,pos_y,pos_y_d,pos_y_i,pos_z,pos_z_d,pos_z_i,pos_rot_x,pos_rot_x_d,pos_rot_x_i,pos_rot_y,pos_rot_y_d,pos_rot_y_i,pos_rot_z,pos_rot_z_d,pos_rot_z_i); + packets[id] = levitation_control_data; + id++; + lcu_data = new StackPacket(idpacket315,general_state,slave_state,lcu_coil_temp_1,lcu_coil_temp_2,lcu_coil_temp_3,lcu_coil_temp_4,lcu_coil_temp_5,lcu_coil_temp_6,lcu_coil_temp_7,lcu_coil_temp_8,lcu_coil_temp_9,lcu_coil_temp_10,lcu_driver_temp_1,lcu_driver_temp_2,lcu_driver_temp_3,lcu_driver_temp_4,lcu_driver_temp_5,lcu_driver_temp_6,lcu_driver_temp_7,lcu_driver_temp_8,lcu_driver_temp_9,lcu_driver_temp_10,lcu_coil_current_1,lcu_coil_current_2,lcu_coil_current_3,lcu_coil_current_4,lcu_coil_current_5,lcu_coil_current_6,lcu_coil_current_7,lcu_coil_current_8,lcu_coil_current_9,lcu_coil_current_10,lcu_vbat_1,lcu_vbat_2,lcu_vbat_3,lcu_vbat_4,lcu_vbat_5,lcu_vbat_6,lcu_vbat_7,lcu_vbat_8,lcu_vbat_9,lcu_vbat_10,lcu_airgap_1,lcu_airgap_2,lcu_airgap_3,lcu_airgap_4,lcu_airgap_5,lcu_airgap_6,lcu_airgap_7,lcu_airgap_8); + packets[id] = lcu_data; + id++; + +} +}; \ No newline at end of file diff --git a/Core/Inc/Communications/Packets/Packet_generation/DataTemplate.hpp b/Core/Inc/Communications/Packets/Packet_generation/DataTemplate.hpp new file mode 100644 index 00000000..2118a206 --- /dev/null +++ b/Core/Inc/Communications/Packets/Packet_generation/DataTemplate.hpp @@ -0,0 +1,21 @@ +#include "ST-LIB.hpp" + +//Data packets for %board% +class DataPacket{ + +%enums% + + private: + constexpr static size_t size =%size%; + uint32_t id{0}; + public: + std::array packets; +%packetnames% + + DataPacket(%data%) +{ + +%packets% + +} +}; \ No newline at end of file diff --git a/Core/Inc/Communications/Packets/Packet_generation/Generator.py b/Core/Inc/Communications/Packets/Packet_generation/Generator.py new file mode 100644 index 00000000..487174ac --- /dev/null +++ b/Core/Inc/Communications/Packets/Packet_generation/Generator.py @@ -0,0 +1,114 @@ +import json +import Packet_descriptions as Pd +import os + +packet_name= " StackPacket* %name%;\n" +packet_struct = " %name% = new StackPacket(%packet_data%);\n packets[id] = %name%;\n id++;" + +def Generate_PacketDescription(): + with open("Core/Inc/Communications/Packets/Packet_generation/JSON_ADE/boards.json") as f: + boards = json.load(f) + + for board in boards["boards"]: + with open("Core/Inc/Communications/Packets/Packet_generation/JSON_ADE/" + (boards["boards"][board])) as f: + b = json.load(f) + board_instance = Pd.BoardDescription(board, b) + globals()[board] = board_instance + + +def GenerateDataEnum(board:Pd.BoardDescription): + Enums = set() + for packet in board.packets: + if packet != "orders": + for packet_instance in board.packets[packet]: + for measurement in packet_instance.measurements: + if hasattr(measurement, "enum"): + Enums.add(measurement.enum) + Enums = list(Enums) + enums_data = "\n".join(Enums) + return enums_data + +def GenerateData(board:Pd.BoardDescription): + Data =set() + for packet in board.packets: + if packet != "orders": + for packet_instance in board.packets[packet]: + data = "" + i=0 + data += "uint16_t &idpacket" + str(packet_instance.id) + "," + for variable in packet_instance.variables: + data += (str(packet_instance.measurements[i].type)+" &"+ str(variable) +",") + i += 1 + Data.add(data) + Data = list(Data) + if Data and Data[-1].endswith(","): + Data[-1] = Data[-1][:-1] + total_data ="".join(Data) + return total_data + +def GenerateDataNames(board:Pd.BoardDescription,packet_name:str): + Names =[] + for packet in board.packets: + if packet != "orders": + for packet_instance in board.packets[packet]: + data = "" + data += packet_name.replace("%name%",packet_instance.name) + Names.append(data) + names_data = "".join(Names) + return names_data + + +def GenerateDataPackets(board:Pd.BoardDescription,packet_struct:str): + Packets =[] + for packet in board.packets: + if packet != "orders": + for packet_instance in board.packets[packet]: + data = "" + data +="idpacket"+str(packet_instance.id)+"," + + for variable in packet_instance.variables: + data += (str(variable) +",") + if data.endswith(","): + data = data[:-1] + aux = packet_struct + aux = aux.replace("%name%",packet_instance.name) + Packets.append(aux.replace("%packet_data%", data)) + + packets_data = "\n".join(Packets) + return packets_data + +def Generate_DataPackets_hpp(board_input:str): + board_instance = globals()[board_input] + + if board_instance.data_size == 0: + if os.path.exists("Core/Inc/Communications/Packets/DataPackets.hpp"): + os.remove("Core/Inc/Communications/Packets/DataPackets.hpp") + return + + with open("Core/Inc/Communications/Packets/Packet_generation/DataTemplate.hpp","r") as Input: + data= Input.read() + + data = data.replace("%board%", board_instance.name) + data = data.replace("%enums%", GenerateDataEnum(board_instance)) + data = data.replace("%packetnames%", GenerateDataNames(board_instance,packet_name)) + data = data.replace("%size%", str(board_instance.data_size)) + data = data.replace("%data%", GenerateData(board_instance)) + data = data.replace("%packets%", GenerateDataPackets(board_instance,packet_struct)) + + with open("Core/Inc/Communications/Packets/DataPackets.hpp","w") as Output: + Output.write(data) + +Generate_PacketDescription() +board = input("Enter board name: ") +while board not in ["VCU","OBCCU","LCU"]: + print("Board not found, only VCU, OBCCU and LCU are available") + board = input("Enter board name: ") +Generate_DataPackets_hpp(board) + + + + + + + + \ No newline at end of file diff --git a/Core/Inc/Communications/Packets/Packet_generation/JSON_ADE b/Core/Inc/Communications/Packets/Packet_generation/JSON_ADE new file mode 160000 index 00000000..5857e0f8 --- /dev/null +++ b/Core/Inc/Communications/Packets/Packet_generation/JSON_ADE @@ -0,0 +1 @@ +Subproject commit 5857e0f8d85aa9b5953e3b84d7cc39b1c9a96858 diff --git a/Core/Inc/Communications/Packets/Packet_generation/Packet_descriptions.py b/Core/Inc/Communications/Packets/Packet_generation/Packet_descriptions.py new file mode 100644 index 00000000..59cae178 --- /dev/null +++ b/Core/Inc/Communications/Packets/Packet_generation/Packet_descriptions.py @@ -0,0 +1,92 @@ +import re +import json +enum_template = "enum class %name%{ \n %values% \n};" + +class BoardDescription: + def __init__(self,name:str,board:dict): + self.name = name + self.id = board["board_id"] + self.ip = board["board_ip"] + self.data_size =0 + self.order_size =0 + i = 0 + self.packets = {} + for packets in board["packets"]: + packets_name = re.split(r'_|\.', packets)[0] + self.packets[packets_name] = [] + measurement = self._MeasurementFileSearch(packets,board["measurements"]) + with open("Core/Inc/Communications/Packets/Packet_generation/JSON_ADE/boards/" + name+"/" + board["packets"][i]) as f: + p= json.load(f) + with open("Core/Inc/Communications/Packets/Packet_generation/JSON_ADE/boards/" + name + "/" + measurement) as f: + m = json.load(f) + i += 1 + for packet in p["packets"]: + self.packets[packets_name].append(PacketDescription(packet,m)) + if packets_name != "orders": + self.data_size += 1 + else: + self.order_size += 1 + @staticmethod + def _MeasurementFileSearch(packet:str,measurements:dict): + packet_name = packet.split('_')[0] + for measurement in measurements: + measurement_name = measurement.split('_')[0] + if packet_name[0] == measurement_name[0]: + return measurement + else: + return measurements[0] +class PacketDescription: + def __init__(self, packet:dict,measurements:dict): + self.id =packet["id"] + self.name = (packet["name"].replace(" ", "_")) + self.type = packet["type"] + self.variables = [] + self.measurements = [] + i=0 + for variable in packet["variables"]: + self.variables.append(variable["name"]) + self.measurements.append(MeasurmentsDescription(measurements,variable["name"])) + + +class MeasurmentsDescription: + def __init__(self,measurements:dict, variable:str): + self.id = variable + measurement = self._MeasurementSearch(measurements,variable) + if measurement is None: + raise Exception("Measurement not found") + else: + self.name = measurement["name"] + self.type = self._unsigned_int_correction(measurement["type"]) + if self.type == "enum": + self.enum = self._create_enum(measurement) + self.type = measurement["id"] + + @staticmethod + def _MeasurementSearch(measurements:dict, variable:str): + for measurment in measurements["measurements"]: + if measurment["id"] == variable: + return measurment + return None + + @staticmethod + def _create_enum(measurement: dict): + if "enumValues" not in measurement: + raise ValueError("Measurement does not contain 'enumValues'") + + enum = enum_template.replace("%name%", measurement["id"]) + values = "" + for value in measurement["enumValues"]: + values += value + ",\n" + if values.endswith(",\n"): + values = values[:-2] + values += "\n" + enum = enum.replace("%values%", values.strip()) + return enum + + @staticmethod + def _unsigned_int_correction(type:str): + aux_type = type[:4] + if aux_type == "uint": + type += "_t" + return type + \ No newline at end of file