Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fw-136-Code-generation-for-data-packets #31

Closed
wants to merge 2 commits into from
Closed
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
39 changes: 39 additions & 0 deletions Core/Inc/Communications/Packets/DataPackets.hpp
Original file line number Diff line number Diff line change
@@ -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<StackPacket*,size> 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 &current_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++;

}
};
21 changes: 21 additions & 0 deletions Core/Inc/Communications/Packets/Packet_generation/DataTemplate.hpp
Original file line number Diff line number Diff line change
@@ -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<StackPacket*,size> packets;
%packetnames%

DataPacket(%data%)
{

%packets%

}
};
114 changes: 114 additions & 0 deletions Core/Inc/Communications/Packets/Packet_generation/Generator.py
Original file line number Diff line number Diff line change
@@ -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)








1 change: 1 addition & 0 deletions Core/Inc/Communications/Packets/Packet_generation/JSON_ADE
Submodule JSON_ADE added at 5857e0
Original file line number Diff line number Diff line change
@@ -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

Loading