-
Notifications
You must be signed in to change notification settings - Fork 4
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
Steven telemetry CAN autogen #343
base: main
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,60 @@ | ||
#include <stdint.h> | ||
|
||
#include "can_board_ids.h" | ||
#include "can_codegen.h" | ||
|
||
static CanMessage s_msg = { | ||
.type = CAN_MSG_TYPE_DATA, | ||
}; | ||
static void prv_tx_can_message(CanMessageId id, uint8_t num_bytes, uint64_t data) { | ||
s_msg.id.raw = id, | ||
s_msg.dlc = num_bytes; | ||
s_msg.data = data; | ||
s_msg.extended = (s_msg.id.msg_id >= CAN_MSG_MAX_STD_IDS); | ||
can_transmit(&s_msg); | ||
} | ||
|
||
void can_tx_all() { | ||
prv_tx_can_message( | ||
SYSTEM_CAN_MESSAGE_BMS_CARRIER_BATTERY_STATUS,7, | ||
(uint64_t) g_tx_struct.battery_status_fault << 0 | | ||
(uint64_t) g_tx_struct.battery_status_fault_val << 16 | | ||
(uint64_t) g_tx_struct.battery_status_aux_batt_v << 32 | | ||
(uint64_t) g_tx_struct.battery_status_afe_status << 48); | ||
prv_tx_can_message( | ||
SYSTEM_CAN_MESSAGE_BMS_CARRIER_BATTERY_INFO,6, | ||
(uint64_t) g_tx_struct.battery_info_fan1 << 0 | | ||
(uint64_t) g_tx_struct.battery_info_fan2 << 8 | | ||
(uint64_t) g_tx_struct.battery_info_max_cell_v << 16 | | ||
(uint64_t) g_tx_struct.battery_info_min_cell_v << 32); | ||
prv_tx_can_message( | ||
SYSTEM_CAN_MESSAGE_BMS_CARRIER_BATTERY_VT,8, | ||
(uint64_t) g_tx_struct.battery_vt_voltage << 0 | | ||
(uint64_t) g_tx_struct.battery_vt_current << 16 | | ||
(uint64_t) g_tx_struct.battery_vt_temperature << 32 | | ||
(uint64_t) g_tx_struct.battery_vt_batt_perc << 48); | ||
prv_tx_can_message( | ||
SYSTEM_CAN_MESSAGE_BMS_CARRIER_BATTERY_RELAY_INFO,1, | ||
(uint64_t) g_tx_struct.battery_relay_info_state << 0); | ||
prv_tx_can_message( | ||
SYSTEM_CAN_MESSAGE_BMS_CARRIER_AFE1_STATUS,8, | ||
(uint64_t) g_tx_struct.AFE1_status_id << 0 | | ||
(uint64_t) g_tx_struct.AFE1_status_temp << 8 | | ||
(uint64_t) g_tx_struct.AFE1_status_v1 << 16 | | ||
(uint64_t) g_tx_struct.AFE1_status_v2 << 32 | | ||
(uint64_t) g_tx_struct.AFE1_status_v3 << 48); | ||
prv_tx_can_message( | ||
SYSTEM_CAN_MESSAGE_BMS_CARRIER_AFE2_STATUS,8, | ||
(uint64_t) g_tx_struct.AFE2_status_id << 0 | | ||
(uint64_t) g_tx_struct.AFE2_status_temp << 8 | | ||
(uint64_t) g_tx_struct.AFE2_status_v1 << 16 | | ||
(uint64_t) g_tx_struct.AFE2_status_v2 << 32 | | ||
(uint64_t) g_tx_struct.AFE2_status_v3 << 48); | ||
prv_tx_can_message( | ||
SYSTEM_CAN_MESSAGE_BMS_CARRIER_AFE3_STATUS,8, | ||
(uint64_t) g_tx_struct.AFE3_status_id << 0 | | ||
(uint64_t) g_tx_struct.AFE3_status_temp << 8 | | ||
(uint64_t) g_tx_struct.AFE3_status_v1 << 16 | | ||
(uint64_t) g_tx_struct.AFE3_status_v2 << 32 | | ||
(uint64_t) g_tx_struct.AFE3_status_v3 << 48); | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -60,7 +60,7 @@ def check_yaml_file(data): | |
def get_data(): | ||
boards = [] | ||
messages = [] | ||
|
||
messages_dict = {} | ||
for yaml_path in Path(__file__).parent.glob("boards/*.yaml"): | ||
# read yaml | ||
with open(yaml_path, "r") as f: | ||
|
@@ -94,8 +94,31 @@ def get_data(): | |
"receiver": message["target"], | ||
}) | ||
|
||
return {"Boards": boards, "Messages": messages} | ||
messages_dict[message["id"]] = { | ||
"id": message["id"], | ||
"critical": message["critical"], | ||
"name": message_name, | ||
"signals": signals, | ||
"sender": sender, | ||
"receiver": message["target"], | ||
} | ||
|
||
print("Boards:") | ||
for board in boards: | ||
print(f" - {board}") | ||
|
||
print("\nMessages:") | ||
for message in messages: | ||
print(f"Message Name: {message['name']}") | ||
print(f" ID: {message['id']}") | ||
print(f" Critical: {message['critical']}") | ||
print(f" Sender: {message['sender']}") | ||
print(f" Receiver: {message['receiver']}") | ||
print(" Signals:") | ||
for signal in message['signals']: | ||
print(f" - Name: {signal['name']}, Start Bit: {signal['start_bit']}, Length: {signal['length']}") | ||
|
||
return {"Boards": boards, "Messages": messages, "Messages_dict": messages_dict} | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Nice you're right this should speed things up, not a big deal for our regular autogen but definitely useful for telemetry. |
||
|
||
def main(): | ||
parser = argparse.ArgumentParser() | ||
|
@@ -119,6 +142,6 @@ def main(): | |
output = env.get_template(template).render(data=data) | ||
Path(output_dir, get_file_name(template, args.board)).write_text(output) | ||
|
||
|
||
if __name__ == "__main__": | ||
main() |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -26,5 +26,4 @@ void can_tx_all() { | |
(uint64_t) g_tx_struct.{{message.name}}_{{signal.name}} << {{signal.start_bit}}{{ " |" if not loop.last }} | ||
{%- endfor -%} | ||
); | ||
{%- endfor %} | ||
} | ||
{% } | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Why the edit in the .c file? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Think when looking into the CAN message in C side and accidently changed something. Sorry about that. |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,50 @@ | ||
{% set bitstream = data["bitstream"] -%} | ||
{% set messages_dict = data["Messages_dict"] -%} | ||
|
||
def decode_packet(messages_dict, bitstream): | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. So here does the user pass in the messages dict themselves? You're right that maybe a quick sample app/unit test would be good and answer this question implicitly. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I was also having a bit confusion in relation to this one. The jinja defines a python function that passes these two in as parameter, but currently they are located in generator.py. (data from get_data() that gets all the yaml files) I am planning on after generating the python script, I just run Define message values
If eventually this python_autogen.py file will be in libraries/codegen, I'm thinking about just doing |
||
# Clean the bitstream by removing spaces | ||
clean_bitstream = bitstream.replace(" ", "") | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. So, your function received a CAN frame right? Why are there spaces in the bitstream? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. in case something like 0000 0001 occurs, just removing the blank space in between. |
||
|
||
# Extract the source_id (first 8 bits) | ||
source_id_binary = clean_bitstream[0:8] | ||
source_id = int(source_id_binary, 2) # Assuming it's a binary string | ||
print(source_id) | ||
|
||
# Extract the msg_id (next 24 bits) | ||
msg_id_binary = clean_bitstream[8:32] | ||
msg_id = int(msg_id_binary, 2) # Assuming it's a binary string | ||
print(msg_id) | ||
|
||
# Message definition | ||
if 0 < msg_id <= 63: | ||
message = messages_dict[msg_id] | ||
else: | ||
print(f"Message ID {msg_id} not found in messages dictionary.") | ||
return | ||
|
||
parsed_signals = [] | ||
data_start_bit = 56 | ||
|
||
# Iterate through each signal in the message dictionary | ||
for signal in message['signals']: | ||
name = signal['name'] | ||
start_bit = signal['start_bit'] + data_start_bit | ||
length = signal['length'] | ||
|
||
# Extract the relevant bits for the signal | ||
signal_bits = clean_bitstream[start_bit:start_bit + length] | ||
|
||
# Convert the bits to a decimal value | ||
signal_value = int(signal_bits, 2) # Assuming it's a binary string | ||
|
||
# Store the parsed signal value | ||
parsed_signals.append({ | ||
"name": name, | ||
"value": signal_value | ||
}) | ||
|
||
return { | ||
"message ID": msg_id, | ||
"message name": message["name"], | ||
"signals": parsed_signals | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hey, saw you working on this yesterday! Gonna close this out but it looks like you're missing the 103 files, 101 and 102 are here. Let me know if you need help with anything!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think this file is autogenerated when im playing around with the generator.py to see how it generates files. If I accidentally deleted something it might unintentional.