From 16eee7e1549ece516c1bec10d12801acdd01b9e2 Mon Sep 17 00:00:00 2001 From: ChanceCtrl Date: Wed, 21 Feb 2024 21:39:21 +0000 Subject: [PATCH 01/17] Cleaning and abstraction Added some helper bash guys to use a virtual can for broadcast testing, as well as fitting all of the canbus stuffs into the IO handeler folder, as well as adding some stuff for serial support --- .gitignore | 1 + downv.sh | 13 +++ py_data_acq/broadcast-test.py | 42 ------- py_data_acq/can-broadcast-test.py | 57 +++++++++ .../py_data_acq/io_handler/can_handle.py | 74 ++++++++++++ .../py_data_acq/io_handler/serial_handle.py | 0 py_data_acq/runner.py | 109 +++++------------- py_data_acq/serial-broadcast-test.py | 9 ++ py_data_acq/setup.py | 10 +- upv.sh | 19 +++ 10 files changed, 210 insertions(+), 124 deletions(-) create mode 100755 downv.sh delete mode 100644 py_data_acq/broadcast-test.py create mode 100644 py_data_acq/can-broadcast-test.py create mode 100644 py_data_acq/py_data_acq/io_handler/serial_handle.py create mode 100644 py_data_acq/serial-broadcast-test.py create mode 100755 upv.sh diff --git a/.gitignore b/.gitignore index 7ea06c9..cc2f777 100644 --- a/.gitignore +++ b/.gitignore @@ -4,3 +4,4 @@ __pycache__/ result result/ .env +hytech.proto diff --git a/downv.sh b/downv.sh new file mode 100755 index 0000000..036c82f --- /dev/null +++ b/downv.sh @@ -0,0 +1,13 @@ +#!/bin/bash + +# Check if vcan0 is already down +if ! ip link show up | grep -q vcan0; then + echo "vcan0 is already down." +else + echo "Bringing down vcan0..." + + # Bring down can0 interface + sudo ip link set down vcan0 + + echo "vcan0 has been brought down." +fi diff --git a/py_data_acq/broadcast-test.py b/py_data_acq/broadcast-test.py deleted file mode 100644 index f40fb8e..0000000 --- a/py_data_acq/broadcast-test.py +++ /dev/null @@ -1,42 +0,0 @@ -#!/usr/bin/env python -import socket -import time -import can -from can.interfaces.udp_multicast import UdpMulticastBus -import cantools -from pprint import pprint -import os - -from hytech_np_proto_py import hytech_pb2 - -# Define the IP and port for the UDP socket -# bus1 = can.interface.Bus('can0', bustype='virtual') -bus1 = can.Bus(channel="can0", interface='socketcan') -def main(): - path_to_dbc = os.environ.get('DBC_PATH') - full_path = os.path.join(path_to_dbc, "hytech.dbc") - # Serialize the message to bytes - db = cantools.database.load_file(full_path) - - msg = db.get_message_by_name("MC1_TORQUE_COMMAND") - rpm = db.get_message_by_name("MC4_SETPOINTS_COMMAND") - data = msg.encode({'torque_command': 100}) - - msg = can.Message(arbitration_id=msg.frame_id, is_extended_id=False, data=data) - - rpm_set = 100 - while(1): - try: - rpm_set= rpm_set+1 - bus1.send(msg) - rpm_data = rpm.encode({'negative_torque_limit': 1, 'positive_torque_limit': 1, 'speed_setpoint_rpm': rpm_set, 'remove_error': 1, 'driver_enable': 1, 'hv_enable': 1, 'inverter_enable': 1}) - rpm_msg = can.Message(arbitration_id=rpm.frame_id, is_extended_id=False, data=rpm_data) - bus1.send(rpm_msg) - - print("Message sent on {}".format(bus1.channel_info)) - except can.CanError: - print("Message NOT sent! Please verify can0 is working first") - time.sleep(0.1) - -if __name__ == "__main__": - main() diff --git a/py_data_acq/can-broadcast-test.py b/py_data_acq/can-broadcast-test.py new file mode 100644 index 0000000..5731968 --- /dev/null +++ b/py_data_acq/can-broadcast-test.py @@ -0,0 +1,57 @@ +#!/usr/bin/env python +import time +import can +import cantools +import os + +# Define the IP and port for the UDP socket +bus1 = can.Bus(channel="vcan0", interface="socketcan") + + +def main(): + path_to_dbc = os.environ.get("DBC_PATH") + full_path = os.path.join(path_to_dbc, "hytech.dbc") + db = cantools.database.load_file(full_path) + + # Setup fake messages + msg = db.get_message_by_name("MC1_TORQUE_COMMAND") + rpm = db.get_message_by_name("MC4_SETPOINTS_COMMAND") + + # Serialize the message to bytes + data = msg.encode({"torque_command": 100}) + msg = can.Message(arbitration_id=msg.frame_id, is_extended_id=False, data=data) + + rpm_set = 100 + while 1: + try: + # Iterate example vals + rpm_set = rpm_set + 1 + + # Send the guy + bus1.send(msg) + + # Serialize the message to bytes + rpm_data = rpm.encode( + { + "negative_torque_limit": 1, + "positive_torque_limit": 1, + "speed_setpoint_rpm": rpm_set, + "remove_error": 1, + "driver_enable": 1, + "hv_enable": 1, + "inverter_enable": 1, + } + ) + rpm_msg = can.Message( + arbitration_id=rpm.frame_id, is_extended_id=False, data=rpm_data + ) + bus1.send(rpm_msg) + + print("Message sent on {}".format(bus1.channel_info)) + except can.CanError: + print("Message NOT sent! Please verify can0 is working first") + time.sleep(0.1) + + +if __name__ == "__main__": + main() diff --git a/py_data_acq/py_data_acq/io_handler/can_handle.py b/py_data_acq/py_data_acq/io_handler/can_handle.py index e69de29..4ea89a1 100644 --- a/py_data_acq/py_data_acq/io_handler/can_handle.py +++ b/py_data_acq/py_data_acq/io_handler/can_handle.py @@ -0,0 +1,74 @@ +import os +import can +import asyncio +import cantools +from can.interfaces.udp_multicast import UdpMulticastBus + +can_methods = { + "debug": [UdpMulticastBus.DEFAULT_GROUP_IPv6, "udp_multicast"], + "local_can_usb_KV": [0, "kvaser"], + "local_debug": ["vcan0", "socketcan"], +} + + +def find_can_interface(): + """Find a CAN interface by checking /sys/class/net/.""" + for interface in os.listdir("/sys/class/net/"): + if interface.startswith("can"): + return interface + return None + + +def init_can(): + can_interface = find_can_interface() + + if can_interface: + print(f"Found CAN interface: {can_interface}") + try: + # Attempt to initialize the CAN bus + bus = can.interface.Bus(channel=can_interface, bustype="socketcan") + print(f"Successfully initialized CAN bus on {can_interface}") + # Interface exists and bus is initialized, but this doesn't ensure the interface is 'up' + except can.CanError as e: + print(f"Failed to initialize CAN bus on {can_interface}: {e}") + print("defaulting to using virtual can interface vcan0") + bus = can.Bus( + interface="socketcan", channel="vcan0", receive_own_messages=True + ) + else: + print("defaulting to using virtual can interface vcan0") + bus = can.Bus(interface="socketcan", channel="vcan0", receive_own_messages=True) + + return bus + + +async def can_receiver( + can_msg_decoder: cantools.db.Database, message_classes, queue, q2 +): + # Get bus + can_bus = init_can() + + loop = asyncio.get_event_loop() + reader = can.AsyncBufferedReader() + notifier = can.Notifier(can_bus, [reader], loop=loop) + + while True: + # Wait for the next message from the buffer + msg = await reader.get_message() + try: + decoded_msg = can_msg_decoder.decode_message( + msg.arbitration_id, msg.data, decode_containers=True + ) + msg = can_msg_decoder.get_message_by_frame_id(msg.arbitration_id) + msg = pb_helpers.pack_protobuf_msg( + decoded_msg, msg.name.lower(), message_classes + ) + data = QueueData(msg.DESCRIPTOR.name, msg) + # await asyncio.sleep(1) + await queue.put(data) + await q2.put(data) + except: + pass + + # Don't forget to stop the notifier to clean up resources. + notifier.stop() diff --git a/py_data_acq/py_data_acq/io_handler/serial_handle.py b/py_data_acq/py_data_acq/io_handler/serial_handle.py new file mode 100644 index 0000000..e69de29 diff --git a/py_data_acq/runner.py b/py_data_acq/runner.py index 69539aa..8e1e51f 100644 --- a/py_data_acq/runner.py +++ b/py_data_acq/runner.py @@ -3,15 +3,13 @@ from py_data_acq.foxglove_live.foxglove_ws import HTProtobufFoxgloveServer from py_data_acq.mcap_writer.writer import HTPBMcapWriter -from py_data_acq.common.common_types import QueueData import py_data_acq.common.protobuf_helpers as pb_helpers from py_data_acq.web_server.mcap_server import MCAPServer -from hytech_np_proto_py import hytech_pb2 -import concurrent.futures +from py_data_acq.io_handler.can_handle import can_receiver, init_can + +# from py_data_acq.io_handler.serial_handle import import sys import os -import can -from can.interfaces.udp_multicast import UdpMulticastBus import cantools import logging @@ -22,116 +20,67 @@ # - protobuf binary schema file location and file name # - config to inform io handler (say for different CAN baudrates) -can_methods = { - "debug": [UdpMulticastBus.DEFAULT_GROUP_IPv6, 'udp_multicast'], - "local_can_usb_KV": [0, 'kvaser'], - "local_debug": ["vcan0", 'socketcan'] -} -def find_can_interface(): - """Find a CAN interface by checking /sys/class/net/.""" - for interface in os.listdir('/sys/class/net/'): - if interface.startswith('can'): - return interface - return None - -async def continuous_can_receiver(can_msg_decoder: cantools.db.Database, message_classes, queue, q2, can_bus): - loop = asyncio.get_event_loop() - reader = can.AsyncBufferedReader() - notifier = can.Notifier(can_bus, [reader], loop=loop) - - while True: - # Wait for the next message from the buffer - msg = await reader.get_message() - try: - - decoded_msg = can_msg_decoder.decode_message(msg.arbitration_id, msg.data, decode_containers=True) - msg = can_msg_decoder.get_message_by_frame_id(msg.arbitration_id) - msg = pb_helpers.pack_protobuf_msg(decoded_msg, msg.name.lower(), message_classes) - data = QueueData(msg.DESCRIPTOR.name, msg) - # await asyncio.sleep(1) - await queue.put(data) - await q2.put(data) - except: - pass - - # Don't forget to stop the notifier to clean up resources. - notifier.stop() - async def write_data_to_mcap(queue, mcap_writer): async with mcap_writer as mcw: while True: await mcw.write_data(queue) + async def fxglv_websocket_consume_data(queue, foxglove_server): async with foxglove_server as fz: while True: await fz.send_msgs_from_queue(queue) -async def run(logger): - - # for example, we will have CAN as our only input as of right now but we may need to add in - # a sensor that inputs over UART or ethernet - - can_interface = find_can_interface() - - if can_interface: - print(f"Found CAN interface: {can_interface}") - try: - # Attempt to initialize the CAN bus - bus = can.interface.Bus(channel=can_interface, bustype='socketcan') - print(f"Successfully initialized CAN bus on {can_interface}") - # Interface exists and bus is initialized, but this doesn't ensure the interface is 'up' - except can.CanError as e: - print(f"Failed to initialize CAN bus on {can_interface}: {e}") - else: - - print("defaulting to using virtual can interface vcan0") - bus = can.Bus(interface='socketcan', channel='vcan0', receive_own_messages=True) +async def run(logger): + # Init some bois queue = asyncio.Queue() queue2 = asyncio.Queue() path_to_bin = "" path_to_dbc = "" - + + # Get paths if len(sys.argv) > 2: path_to_bin = sys.argv[1] path_to_dbc = sys.argv[2] else: - path_to_bin = os.environ.get('BIN_PATH') - path_to_dbc = os.environ.get('DBC_PATH') - - full_path = os.path.join(path_to_bin, "hytech.bin") - full_path_to_dbc = os.path.join(path_to_dbc, "hytech.dbc") - db = cantools.db.load_file(full_path_to_dbc) + path_to_bin = os.environ.get("BIN_PATH") + path_to_dbc = os.environ.get("DBC_PATH") + # Load everything + fp_proto = os.path.join(path_to_bin, "hytech.bin") + fp_dbc = os.path.join(path_to_dbc, "hytech.dbc") + db = cantools.db.load_file(fp_dbc) + # Start foxglove websocket and send message list list_of_msg_names, msg_pb_classes = pb_helpers.get_msg_names_and_classes() - fx_s = HTProtobufFoxgloveServer("0.0.0.0", 8765, "asdf", full_path, list_of_msg_names) + fx_s = HTProtobufFoxgloveServer( + "0.0.0.0", 8765, "asdf", fp_proto, list_of_msg_names + ) + + # Set output path of mcap files, and if on nixos save to a predefined path path_to_mcap = "." - if(os.path.exists('/etc/nixos')): + if os.path.exists("/etc/nixos"): logger.info("detected running on nixos") path_to_mcap = "/home/nixos/recordings" - mcap_writer = HTPBMcapWriter(path_to_mcap, list_of_msg_names, True) mcap_server = MCAPServer(mcap_writer=mcap_writer, path=path_to_mcap) - receiver_task = asyncio.create_task(continuous_can_receiver(db, msg_pb_classes, queue, queue2, bus)) + + # Setup receiver_task to listen to CAN + receiver_task = asyncio.create_task(can_receiver(db, msg_pb_classes, queue, queue2)) + + # Setup other guys to respective asyncio tasks fx_task = asyncio.create_task(fxglv_websocket_consume_data(queue, fx_s)) mcap_task = asyncio.create_task(write_data_to_mcap(queue2, mcap_writer)) srv_task = asyncio.create_task(mcap_server.start_server()) logger.info("created tasks") - # in the mcap task I actually have to deserialize the any protobuf msg into the message ID and - # the encoded message for the message id. I will need to handle the same association of message id - # and schema in the foxglove websocket server. - + await asyncio.gather(receiver_task, fx_task, mcap_task, srv_task) - # await asyncio.gather(receiver_task, fx_task, mcap_task) - # await asyncio.gather(receiver_task, mcap_task, srv_task) - # await asyncio.gather(receiver_task) if __name__ == "__main__": logging.basicConfig() - logger = logging.getLogger('data_writer_service') + logger = logging.getLogger("data_writer_service") logger.setLevel(logging.INFO) - asyncio.run(run(logger)) \ No newline at end of file + asyncio.run(run(logger)) diff --git a/py_data_acq/serial-broadcast-test.py b/py_data_acq/serial-broadcast-test.py new file mode 100644 index 0000000..3be62ee --- /dev/null +++ b/py_data_acq/serial-broadcast-test.py @@ -0,0 +1,9 @@ +#!/usr/bin/env python + + +def main(): + print("lol not real") + + +if __name__ == "__main__": + main() diff --git a/py_data_acq/setup.py b/py_data_acq/setup.py index 0918035..e666066 100644 --- a/py_data_acq/setup.py +++ b/py_data_acq/setup.py @@ -5,5 +5,11 @@ name="py_data_acq", version="1.0", packages=find_packages(), - scripts=['runner.py', 'broadcast-test.py', 'data_acq_service.py', 'server_runner.py'] -) \ No newline at end of file + scripts=[ + "runner.py", + "can-broadcast-test.py", + "serial-broadcast-test.py", + "data_acq_service.py", + "server_runner.py", + ], +) diff --git a/upv.sh b/upv.sh new file mode 100755 index 0000000..4161992 --- /dev/null +++ b/upv.sh @@ -0,0 +1,19 @@ +#!/bin/bash + +# Check if can0 is up +if ! ip link show up | grep -q can0; then + echo "Bringing up vcan0..." + + # Load CAN related modules + sudo modprobe vcan + + # Setup the faux can + sudo ip link add dev vcan0 type vcan + + # Bring up can0 interface + sudo ip link set up vcan0 + + echo "vcan0 setup complete." +else + echo "vcan0 is already up." +fi From 01004e43292ee1897424cc269a93bc22a23f4fbc Mon Sep 17 00:00:00 2001 From: ChanceCtrl Date: Fri, 23 Feb 2024 15:15:28 +0000 Subject: [PATCH 02/17] Almost working serial reader Still currently fighting bugs, but outside of that I slightly updated the readme for the enduser and added the pyserial-asyncio package to the nix stuffs --- README.md | 11 ++++- default.nix | 1 + py_data_acq/can-broadcast-test.py | 2 +- .../py_data_acq/io_handler/can_handle.py | 13 ++--- .../py_data_acq/io_handler/serial_handle.py | 42 ++++++++++++++++ py_data_acq/runner.py | 17 +++++-- py_data_acq/serial-broadcast-test.py | 49 ++++++++++++++++++- 7 files changed, 121 insertions(+), 14 deletions(-) diff --git a/README.md b/README.md index b9cad68..5f5a451 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,11 @@ -usage: +# Base person usage: +1. Download foxglove studio at https://github.com/foxglove/studio/releases +2. Connect to the Pi's network +3. Open foxglove studio +4. Open a connection to the Pi's IP on port 8765 +5. Look at data + +# dev usage: to get into a dev environment locally (on linux): 1. install nix: @@ -117,4 +124,4 @@ flowchart TD kvaser u100 pinout: -![Alt text](image.png) \ No newline at end of file +![Alt text](image.png) diff --git a/default.nix b/default.nix index 0dd5e4d..09f159d 100644 --- a/default.nix +++ b/default.nix @@ -18,6 +18,7 @@ python311Packages.buildPythonApplication { python311Packages.websockets python311Packages.pprintpp python311Packages.can + python311Packages.pyserial-asyncio asyncudp_pkg python311Packages.lz4 python311Packages.zstandard diff --git a/py_data_acq/can-broadcast-test.py b/py_data_acq/can-broadcast-test.py index 5731968..049dcd7 100644 --- a/py_data_acq/can-broadcast-test.py +++ b/py_data_acq/can-broadcast-test.py @@ -4,7 +4,7 @@ import cantools import os -# Define the IP and port for the UDP socket +# Define the bus to yap on bus1 = can.Bus(channel="vcan0", interface="socketcan") diff --git a/py_data_acq/py_data_acq/io_handler/can_handle.py b/py_data_acq/py_data_acq/io_handler/can_handle.py index 4ea89a1..6ec3ac1 100644 --- a/py_data_acq/py_data_acq/io_handler/can_handle.py +++ b/py_data_acq/py_data_acq/io_handler/can_handle.py @@ -2,6 +2,8 @@ import can import asyncio import cantools +from ..common import protobuf_helpers +from ..common.common_types import QueueData from can.interfaces.udp_multicast import UdpMulticastBus can_methods = { @@ -26,7 +28,7 @@ def init_can(): print(f"Found CAN interface: {can_interface}") try: # Attempt to initialize the CAN bus - bus = can.interface.Bus(channel=can_interface, bustype="socketcan") + bus = can.Bus(channel=can_interface, bustype="socketcan") print(f"Successfully initialized CAN bus on {can_interface}") # Interface exists and bus is initialized, but this doesn't ensure the interface is 'up' except can.CanError as e: @@ -42,12 +44,11 @@ def init_can(): return bus -async def can_receiver( - can_msg_decoder: cantools.db.Database, message_classes, queue, q2 -): +async def can_receiver(can_msg_decoder: cantools.db.Database, message_classes, q1, q2): # Get bus can_bus = init_can() + # Set some asyncio vars loop = asyncio.get_event_loop() reader = can.AsyncBufferedReader() notifier = can.Notifier(can_bus, [reader], loop=loop) @@ -60,12 +61,12 @@ async def can_receiver( msg.arbitration_id, msg.data, decode_containers=True ) msg = can_msg_decoder.get_message_by_frame_id(msg.arbitration_id) - msg = pb_helpers.pack_protobuf_msg( + msg = protobuf_helpers.pack_protobuf_msg( decoded_msg, msg.name.lower(), message_classes ) data = QueueData(msg.DESCRIPTOR.name, msg) # await asyncio.sleep(1) - await queue.put(data) + await q1.put(data) await q2.put(data) except: pass diff --git a/py_data_acq/py_data_acq/io_handler/serial_handle.py b/py_data_acq/py_data_acq/io_handler/serial_handle.py index e69de29..5ce1325 100644 --- a/py_data_acq/py_data_acq/io_handler/serial_handle.py +++ b/py_data_acq/py_data_acq/io_handler/serial_handle.py @@ -0,0 +1,42 @@ +import serial_asyncio +import cantools +from ..common import protobuf_helpers +from ..common.common_types import QueueData + + +async def serial_reciever(can_db: cantools.db.Database, message_classes, q1, q2): + # Start asyncio on the port + reader, writer = await serial_asyncio.open_serial_connection( + url="/dev/ttyUSB0", baudrate=230400 + ) + + while True: + # Wait for the next message from the buffer, then break it into parts using the byte value for "," + nl_byte = await reader.readline() + vals = nl_byte.split(b",") + print(vals) + # This is fine + print(vals[0]) + # BUG: This crashes everything, even with the rest of this commented out... + print(vals[1]) + + try: + # Get message data for foxglove + msg = can_db.get_message_by_frame_id(int.from_bytes(vals[0])) + + # Break down message + decoded_msg = can_db.decode_message( + int.from_bytes(vals[0]), vals[1], decode_containers=True + ) + + # Package as protobuf guy + msg = protobuf_helpers.pack_protobuf_msg( + decoded_msg, msg.name.lower(), message_classes + ) + data = QueueData(msg.DESCRIPTOR.name, msg) + + # Throw data into queues and start again + await q1.put(data) + await q2.put(data) + except: + pass diff --git a/py_data_acq/runner.py b/py_data_acq/runner.py index 8e1e51f..1d7f457 100644 --- a/py_data_acq/runner.py +++ b/py_data_acq/runner.py @@ -5,7 +5,8 @@ from py_data_acq.mcap_writer.writer import HTPBMcapWriter import py_data_acq.common.protobuf_helpers as pb_helpers from py_data_acq.web_server.mcap_server import MCAPServer -from py_data_acq.io_handler.can_handle import can_receiver, init_can +from py_data_acq.io_handler.can_handle import can_receiver +from py_data_acq.io_handler.serial_handle import serial_reciever # from py_data_acq.io_handler.serial_handle import import sys @@ -35,7 +36,7 @@ async def fxglv_websocket_consume_data(queue, foxglove_server): async def run(logger): # Init some bois - queue = asyncio.Queue() + queue1 = asyncio.Queue() queue2 = asyncio.Queue() path_to_bin = "" path_to_dbc = "" @@ -68,10 +69,18 @@ async def run(logger): mcap_server = MCAPServer(mcap_writer=mcap_writer, path=path_to_mcap) # Setup receiver_task to listen to CAN - receiver_task = asyncio.create_task(can_receiver(db, msg_pb_classes, queue, queue2)) + # receiver_task = asyncio.create_task( + # can_receiver(db, msg_pb_classes, queue1, queue2) + # ) + + # BUG: This shit breaks and crashes everything, fix it + # And another for serial + receiver_task = asyncio.create_task( + serial_reciever(db, msg_pb_classes, queue1, queue2) + ) # Setup other guys to respective asyncio tasks - fx_task = asyncio.create_task(fxglv_websocket_consume_data(queue, fx_s)) + fx_task = asyncio.create_task(fxglv_websocket_consume_data(queue1, fx_s)) mcap_task = asyncio.create_task(write_data_to_mcap(queue2, mcap_writer)) srv_task = asyncio.create_task(mcap_server.start_server()) logger.info("created tasks") diff --git a/py_data_acq/serial-broadcast-test.py b/py_data_acq/serial-broadcast-test.py index 3be62ee..9d5a67c 100644 --- a/py_data_acq/serial-broadcast-test.py +++ b/py_data_acq/serial-broadcast-test.py @@ -1,8 +1,55 @@ #!/usr/bin/env python +import time +import cantools +import os +import serial, pty +# TODO: Make this real (currently does not actually send data(?)) def main(): - print("lol not real") + # Open fake serial port + snd, rev = pty.openpty() + p_name = os.ttyname(snd) + print("Opening on {}".format(p_name)) + ser = serial.Serial(p_name) + + print("Opened for on {}".format(ser)) + + # Load DBC + path_to_dbc = os.environ.get("DBC_PATH") + full_path = os.path.join(path_to_dbc, "hytech.dbc") + db = cantools.database.load_file(full_path) + + # Setup fake messages + msg = db.get_message_by_name("MC1_TORQUE_COMMAND") + rpm = db.get_message_by_name("MC4_SETPOINTS_COMMAND") + + # Serialize the message to bytes + data = msg.encode({"torque_command": 100}) + rpm_set = 100 + + while 1: + # Iterate example vals + rpm_set = rpm_set + 1 + + # Send the guy + ser.write(bytearray(msg.frame_id) + b"," + data) + + # make new message with new data + rpm_data = rpm.encode( + { + "negative_torque_limit": 1, + "positive_torque_limit": 1, + "speed_setpoint_rpm": rpm_set, + "remove_error": 1, + "driver_enable": 1, + "hv_enable": 1, + "inverter_enable": 1, + } + ) + ser.write(bytearray(rpm.frame_id) + b"," + rpm_data) + + time.sleep(0.1) if __name__ == "__main__": From ff2c8324debaa3be87017e4c4ce438279c39af76 Mon Sep 17 00:00:00 2001 From: ChanceCtrl Date: Sun, 25 Feb 2024 03:06:38 +0000 Subject: [PATCH 03/17] Actually it was working Took a depressignly long time to figure out it did in fact work... N e ways I also updated the flake to take in KSU's DBC file for testing on monday, should work on adding udev rule and this package to the ksu-nixos guy here soon --- .gitignore | 1 + dbc_proto_bin_gen.nix | 8 +-- flake.lock | 58 +++++++++---------- flake.nix | 16 ++--- py_data_acq/can-broadcast-test.py | 38 ++++++------ .../py_data_acq/io_handler/serial_handle.py | 6 +- py_data_acq/runner.py | 5 +- py_dbc_proto_gen/dbc_to_proto.py | 49 ++++++++-------- 8 files changed, 88 insertions(+), 93 deletions(-) diff --git a/.gitignore b/.gitignore index cc2f777..779b256 100644 --- a/.gitignore +++ b/.gitignore @@ -5,3 +5,4 @@ result result/ .env hytech.proto +dbc_to.proto diff --git a/dbc_proto_bin_gen.nix b/dbc_proto_bin_gen.nix index dc5bed4..264bc1d 100644 --- a/dbc_proto_bin_gen.nix +++ b/dbc_proto_bin_gen.nix @@ -1,16 +1,16 @@ -{pkgs, py_dbc_proto_gen_pkg, ht_can_pkg, protobuf}: +{pkgs, py_dbc_proto_gen_pkg, can_pkg, protobuf}: pkgs.stdenv.mkDerivation rec { name = "ht-proto-gen"; src = builtins.filterSource (path: type: false) ./.; - buildInputs = [ py_dbc_proto_gen_pkg ht_can_pkg protobuf ]; # Python as a build dependency + buildInputs = [ py_dbc_proto_gen_pkg can_pkg protobuf ]; # Python as a build dependency # Define the build phase to execute the scripts buildPhase = '' # Run the Python script - dbc_to_proto.py ${ht_can_pkg} + dbc_to_proto.py ${can_pkg} protoc --include_imports --descriptor_set_out=hytech.bin hytech.proto ''; @@ -22,4 +22,4 @@ pkgs.stdenv.mkDerivation rec { cp hytech.proto $out/proto cp hytech.bin $out/bin ''; -} \ No newline at end of file +} diff --git a/flake.lock b/flake.lock index cea78ad..c8c99d0 100644 --- a/flake.lock +++ b/flake.lock @@ -19,41 +19,41 @@ "type": "github" } }, - "foxglove-websocket": { + "can_pkg_flake": { "inputs": { "nixpkgs": "nixpkgs_2", "utils": "utils_2" }, "locked": { - "lastModified": 1703087404, - "narHash": "sha256-PJB1pXZUrt8Za4PxXyIZtRffq5FuDS4do8lQPpY4iMY=", - "owner": "RCMast3r", - "repo": "py_foxglove_webserver_nix", - "rev": "bbab26c716248fad51447b4ab8f4b84b75e3677a", + "lastModified": 1708796918, + "narHash": "sha256-cR0Rudt+T5xYWuLPRtC6p2K+c83sN6p6DNo9CecTql8=", + "owner": "KSU-MS", + "repo": "Nix_CAN", + "rev": "94499eaa5f9a447ad559c6fbbb7163ce15c3af31", "type": "github" }, "original": { - "owner": "RCMast3r", - "repo": "py_foxglove_webserver_nix", + "owner": "KSU-MS", + "repo": "Nix_CAN", "type": "github" } }, - "ht_can_pkg_flake": { + "foxglove-websocket": { "inputs": { "nixpkgs": "nixpkgs_3", "utils": "utils_3" }, "locked": { - "lastModified": 1708295505, - "narHash": "sha256-djxRSAyr+9N3AO7uP4lYg1wW/X8a85D3XADFM3Rreeo=", - "owner": "hytech-racing", - "repo": "ht_can", - "rev": "a52db761d58f1caa163c44ca197ec19777a6b2f5", + "lastModified": 1703087404, + "narHash": "sha256-PJB1pXZUrt8Za4PxXyIZtRffq5FuDS4do8lQPpY4iMY=", + "owner": "RCMast3r", + "repo": "py_foxglove_webserver_nix", + "rev": "bbab26c716248fad51447b4ab8f4b84b75e3677a", "type": "github" }, "original": { - "owner": "hytech-racing", - "repo": "ht_can", + "owner": "RCMast3r", + "repo": "py_foxglove_webserver_nix", "type": "github" } }, @@ -163,11 +163,11 @@ }, "nixpkgs_2": { "locked": { - "lastModified": 1702921762, - "narHash": "sha256-O/rP7gulApQAB47u6szEd8Pn8Biw0d84j5iuP2tcxzY=", + "lastModified": 1707650010, + "narHash": "sha256-dOhphIA4MGrH4ElNCy/OlwmN24MsnEqFjRR6+RY7jZw=", "owner": "NixOS", "repo": "nixpkgs", - "rev": "d02ffbbe834b5599fc5f134e644e49397eb07188", + "rev": "809cca784b9f72a5ad4b991e0e7bcf8890f9c3a6", "type": "github" }, "original": { @@ -179,11 +179,11 @@ }, "nixpkgs_3": { "locked": { - "lastModified": 1707650010, - "narHash": "sha256-dOhphIA4MGrH4ElNCy/OlwmN24MsnEqFjRR6+RY7jZw=", + "lastModified": 1702921762, + "narHash": "sha256-O/rP7gulApQAB47u6szEd8Pn8Biw0d84j5iuP2tcxzY=", "owner": "NixOS", "repo": "nixpkgs", - "rev": "809cca784b9f72a5ad4b991e0e7bcf8890f9c3a6", + "rev": "d02ffbbe834b5599fc5f134e644e49397eb07188", "type": "github" }, "original": { @@ -260,8 +260,8 @@ "root": { "inputs": { "asyncudp": "asyncudp", + "can_pkg_flake": "can_pkg_flake", "foxglove-websocket": "foxglove-websocket", - "ht_can_pkg_flake": "ht_can_pkg_flake", "mcap": "mcap", "mcap-protobuf": "mcap-protobuf", "nix-proto": "nix-proto", @@ -382,11 +382,11 @@ "systems": "systems_2" }, "locked": { - "lastModified": 1701680307, - "narHash": "sha256-kAuep2h5ajznlPMD9rnQyffWG8EM/C73lejGofXvdM8=", + "lastModified": 1705309234, + "narHash": "sha256-uNRRNRKmJyCRC/8y1RqBkqWBLM034y4qN7EprSdmgyA=", "owner": "numtide", "repo": "flake-utils", - "rev": "4022d587cbbfd70fe950c1e2083a02621806a725", + "rev": "1ef2e671c3b0c19053962c07dbda38332dcebf26", "type": "github" }, "original": { @@ -400,11 +400,11 @@ "systems": "systems_3" }, "locked": { - "lastModified": 1705309234, - "narHash": "sha256-uNRRNRKmJyCRC/8y1RqBkqWBLM034y4qN7EprSdmgyA=", + "lastModified": 1701680307, + "narHash": "sha256-kAuep2h5ajznlPMD9rnQyffWG8EM/C73lejGofXvdM8=", "owner": "numtide", "repo": "flake-utils", - "rev": "1ef2e671c3b0c19053962c07dbda38332dcebf26", + "rev": "4022d587cbbfd70fe950c1e2083a02621806a725", "type": "github" }, "original": { diff --git a/flake.nix b/flake.nix index 45c4d4b..57030c5 100644 --- a/flake.nix +++ b/flake.nix @@ -9,12 +9,12 @@ mcap.url = "github:RCMast3r/py_mcap_nix"; foxglove-websocket.url = "github:RCMast3r/py_foxglove_webserver_nix"; asyncudp.url = "github:RCMast3r/asyncudp_nix"; - ht_can_pkg_flake.url = "github:hytech-racing/ht_can"; - nix-proto = { url = "github:notalltim/nix-proto"; }; + can_pkg_flake.url = "github:KSU-MS/Nix_CAN"; + nix-proto.url = "github:notalltim/nix-proto"; }; outputs = { self, nixpkgs, utils, mcap-protobuf, mcap, foxglove-websocket - , asyncudp, nix-proto, ht_can_pkg_flake, ... }@inputs: + , asyncudp, nix-proto, can_pkg_flake, ... }@inputs: let makePackageSet = pkgs: { py_data_acq_pkg = pkgs.py_data_acq_pkg; @@ -48,7 +48,7 @@ py_dbc_proto_gen_overlay py_data_acq_overlay proto_gen_overlay - ht_can_pkg_flake.overlays.default + can_pkg_flake.overlays.default mcap-protobuf.overlays.default mcap.overlays.default asyncudp.overlays.default @@ -90,7 +90,7 @@ py_data_acq_pkg py_dbc_proto_gen_pkg proto_gen_pkg - ht_can_pkg + can_pkg cmake can-utils ]; @@ -100,7 +100,7 @@ in '' path=${x86_pkgs.proto_gen_pkg} bin_path=$path"/bin" - dbc_path=${x86_pkgs.ht_can_pkg} + dbc_path=${x86_pkgs.can_pkg} export BIN_PATH=$bin_path export DBC_PATH=$dbc_path @@ -115,14 +115,14 @@ # Development Tools py_dbc_proto_gen_pkg proto_gen_pkg - ht_can_pkg + can_pkg protobuf ]; shellHook = '' path=${x86_pkgs.proto_gen_pkg} bin_path=$path"/bin" - dbc_path=${x86_pkgs.ht_can_pkg} + dbc_path=${x86_pkgs.can_pkg} export BIN_PATH=$bin_path export DBC_PATH=$dbc_path ''; diff --git a/py_data_acq/can-broadcast-test.py b/py_data_acq/can-broadcast-test.py index 049dcd7..8fc87cb 100644 --- a/py_data_acq/can-broadcast-test.py +++ b/py_data_acq/can-broadcast-test.py @@ -1,25 +1,26 @@ #!/usr/bin/env python import time import can -import cantools +import math import os +from cantools import database # Define the bus to yap on bus1 = can.Bus(channel="vcan0", interface="socketcan") +def generate_sine_wave(amplitude, frequency, phase_shift, time_variable): + return amplitude * math.sin(2 * math.pi * frequency * time_variable + phase_shift) + + def main(): + # Load DBC into path_to_dbc = os.environ.get("DBC_PATH") - full_path = os.path.join(path_to_dbc, "hytech.dbc") - db = cantools.database.load_file(full_path) + full_path = os.path.join(path_to_dbc, "car.dbc") + db = database.load_file(full_path) - # Setup fake messages - msg = db.get_message_by_name("MC1_TORQUE_COMMAND") - rpm = db.get_message_by_name("MC4_SETPOINTS_COMMAND") - - # Serialize the message to bytes - data = msg.encode({"torque_command": 100}) - msg = can.Message(arbitration_id=msg.frame_id, is_extended_id=False, data=data) + # Setup fake message + rpm = db.get_message_by_name("M165_Motor_Position_Info") rpm_set = 100 while 1: @@ -27,19 +28,14 @@ def main(): # Iterate example vals rpm_set = rpm_set + 1 - # Send the guy - bus1.send(msg) - # Serialize the message to bytes + rpm_set = generate_sine_wave(3000, 1, 90, time.time()) + 3000 rpm_data = rpm.encode( { - "negative_torque_limit": 1, - "positive_torque_limit": 1, - "speed_setpoint_rpm": rpm_set, - "remove_error": 1, - "driver_enable": 1, - "hv_enable": 1, - "inverter_enable": 1, + "D4_Delta_Resolver_Filtered": int(1), + "D3_Electrical_Output_Frequency": int(1), + "D2_Motor_Speed": rpm_set, + "D1_Motor_Angle_Electrical": int(1), } ) rpm_msg = can.Message( @@ -47,7 +43,7 @@ def main(): ) bus1.send(rpm_msg) - print("Message sent on {}".format(bus1.channel_info)) + # print("Message sent on {}".format(bus1.channel_info)) except can.CanError: print("Message NOT sent! Please verify can0 is working first") time.sleep(0.1) diff --git a/py_data_acq/py_data_acq/io_handler/serial_handle.py b/py_data_acq/py_data_acq/io_handler/serial_handle.py index 5ce1325..a36414c 100644 --- a/py_data_acq/py_data_acq/io_handler/serial_handle.py +++ b/py_data_acq/py_data_acq/io_handler/serial_handle.py @@ -14,11 +14,6 @@ async def serial_reciever(can_db: cantools.db.Database, message_classes, q1, q2) # Wait for the next message from the buffer, then break it into parts using the byte value for "," nl_byte = await reader.readline() vals = nl_byte.split(b",") - print(vals) - # This is fine - print(vals[0]) - # BUG: This crashes everything, even with the rest of this commented out... - print(vals[1]) try: # Get message data for foxglove @@ -39,4 +34,5 @@ async def serial_reciever(can_db: cantools.db.Database, message_classes, q1, q2) await q1.put(data) await q2.put(data) except: + print("Fail") pass diff --git a/py_data_acq/runner.py b/py_data_acq/runner.py index 1d7f457..19516d7 100644 --- a/py_data_acq/runner.py +++ b/py_data_acq/runner.py @@ -51,7 +51,7 @@ async def run(logger): # Load everything fp_proto = os.path.join(path_to_bin, "hytech.bin") - fp_dbc = os.path.join(path_to_dbc, "hytech.dbc") + fp_dbc = os.path.join(path_to_dbc, "car.dbc") db = cantools.db.load_file(fp_dbc) # Start foxglove websocket and send message list @@ -73,8 +73,7 @@ async def run(logger): # can_receiver(db, msg_pb_classes, queue1, queue2) # ) - # BUG: This shit breaks and crashes everything, fix it - # And another for serial + # Setup receiver_task to listen to SERIAL receiver_task = asyncio.create_task( serial_reciever(db, msg_pb_classes, queue1, queue2) ) diff --git a/py_dbc_proto_gen/dbc_to_proto.py b/py_dbc_proto_gen/dbc_to_proto.py index f2284e4..b612cac 100644 --- a/py_dbc_proto_gen/dbc_to_proto.py +++ b/py_dbc_proto_gen/dbc_to_proto.py @@ -1,40 +1,36 @@ #!/usr/bin/env python import cantools -from cantools.database import * -import pkg_resources +from cantools.database import can, conversion import sys +import os -class HyTechCANmsg: - def __init__(self): - self.can_id_name = "" - self.can_id_hex = 0x0 - self.sender_name = "" - self.packing_type = "" - self.signals = [can.signal.Signal] -# def create_field_name(name: str) -> str: replaced_text = name.replace(" ", "_") replaced_text = replaced_text.replace("(", "") replaced_text = replaced_text.replace(")", "") return replaced_text + def append_proto_message_from_CAN_message(file, can_msg: can.message.Message): # if the msg has a conversion, we know that the value with be a float - file_lines = [] msgname = can_msg.name # type and then name file.write("message " + msgname.lower() + " {\n") line_index = 0 for sig in can_msg.signals: line_index += 1 - - if sig.is_float or ((sig.scale is not None) and (sig.scale != 1.0)) or ( - type(sig.conversion) - is not type(conversion.IdentityConversion(is_float=False)) - and not type( - conversion.NamedSignalConversion( - choices={}, scale=0, offset=0, is_float=False + + if ( + sig.is_float + or ((sig.scale is not None) and (sig.scale != 1.0)) + or ( + type(sig.conversion) + is not type(conversion.IdentityConversion(is_float=False)) + and not type( + conversion.NamedSignalConversion( + choices={}, scale=0, offset=0, is_float=False + ) ) ) ): @@ -45,7 +41,7 @@ def append_proto_message_from_CAN_message(file, can_msg: can.message.Message): + str(line_index) + ";" ) - elif sig.choices is not None and sig.length is not 1: + elif sig.choices is not None and sig.length != 1: line = ( " string " + create_field_name(sig.name) @@ -71,20 +67,27 @@ def append_proto_message_from_CAN_message(file, can_msg: can.message.Message): ) else: print("ERROR") + line = ( + " null " + + create_field_name(sig.name) + + " = " + + str(line_index) + + ";" + ) file.write(line + "\n") file.write("}\n\n") return file + # load dbc file from the package location -if(len (sys.argv) > 1): +if len(sys.argv) > 1: path_to_dbc = sys.argv[1] else: - path_to_dbc = os.environ.get('DBC_PATH') -full_path = os.path.join(path_to_dbc, "hytech.dbc") + path_to_dbc = os.environ.get("DBC_PATH") +full_path = os.path.join(path_to_dbc, "car.dbc") db = cantools.database.load_file(full_path) with open("hytech.proto", "w+") as proto_file: proto_file.write('syntax = "proto3";\n\n') for msg in db.messages: proto_file = append_proto_message_from_CAN_message(proto_file, msg) - From 39d1add99c5b635a82c006e640c0f7527716d055 Mon Sep 17 00:00:00 2001 From: ChanceCtrl Date: Sun, 25 Feb 2024 21:08:06 +0000 Subject: [PATCH 04/17] updated port now it looks for /dev/xboi and that gets defined by a udev rule found in the ksu-nixos repo, so baller --- py_data_acq/py_data_acq/io_handler/serial_handle.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/py_data_acq/py_data_acq/io_handler/serial_handle.py b/py_data_acq/py_data_acq/io_handler/serial_handle.py index a36414c..e0dbbfa 100644 --- a/py_data_acq/py_data_acq/io_handler/serial_handle.py +++ b/py_data_acq/py_data_acq/io_handler/serial_handle.py @@ -7,7 +7,7 @@ async def serial_reciever(can_db: cantools.db.Database, message_classes, q1, q2): # Start asyncio on the port reader, writer = await serial_asyncio.open_serial_connection( - url="/dev/ttyUSB0", baudrate=230400 + url="/dev/xboi", baudrate=230400 ) while True: From 811e33277a9bb99fe273c8b176158740c6b2a1d5 Mon Sep 17 00:00:00 2001 From: ChanceCtrl Date: Sun, 25 Feb 2024 21:52:54 +0000 Subject: [PATCH 05/17] added env var Now runner.py looks for the D_SOURCE env var to tell what data source its looking for --- py_data_acq/runner.py | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 deletions(-) diff --git a/py_data_acq/runner.py b/py_data_acq/runner.py index 19516d7..e2888be 100644 --- a/py_data_acq/runner.py +++ b/py_data_acq/runner.py @@ -68,15 +68,16 @@ async def run(logger): mcap_writer = HTPBMcapWriter(path_to_mcap, list_of_msg_names, True) mcap_server = MCAPServer(mcap_writer=mcap_writer, path=path_to_mcap) - # Setup receiver_task to listen to CAN - # receiver_task = asyncio.create_task( - # can_receiver(db, msg_pb_classes, queue1, queue2) - # ) - - # Setup receiver_task to listen to SERIAL - receiver_task = asyncio.create_task( - serial_reciever(db, msg_pb_classes, queue1, queue2) - ) + # Get data source + match os.environ.get("D_SOURCE"): + case "SERIAL": + receiver_task = asyncio.create_task( + serial_reciever(db, msg_pb_classes, queue1, queue2) + ) + case _: + receiver_task = asyncio.create_task( + can_receiver(db, msg_pb_classes, queue1, queue2) + ) # Setup other guys to respective asyncio tasks fx_task = asyncio.create_task(fxglv_websocket_consume_data(queue1, fx_s)) From 67396d21fc9dbc7b0272602ca57ece9b92c4ffa1 Mon Sep 17 00:00:00 2001 From: mathbrook Date: Mon, 8 Apr 2024 22:22:58 -0400 Subject: [PATCH 06/17] only the serial handler mods --- .../py_data_acq/io_handler/serial_handle.py | 26 ++++++++++++------- 1 file changed, 16 insertions(+), 10 deletions(-) diff --git a/py_data_acq/py_data_acq/io_handler/serial_handle.py b/py_data_acq/py_data_acq/io_handler/serial_handle.py index e0dbbfa..be88522 100644 --- a/py_data_acq/py_data_acq/io_handler/serial_handle.py +++ b/py_data_acq/py_data_acq/io_handler/serial_handle.py @@ -14,14 +14,16 @@ async def serial_reciever(can_db: cantools.db.Database, message_classes, q1, q2) # Wait for the next message from the buffer, then break it into parts using the byte value for "," nl_byte = await reader.readline() vals = nl_byte.split(b",") - + print(f"Raw Line: {nl_byte}") + print(f"Comma delimited: {vals}") + # try: + # Get message data for foxglove + frameid = int.from_bytes(vals[0],byteorder='little') try: - # Get message data for foxglove - msg = can_db.get_message_by_frame_id(int.from_bytes(vals[0])) - + msg = can_db.get_message_by_frame_id(frameid) # Break down message decoded_msg = can_db.decode_message( - int.from_bytes(vals[0]), vals[1], decode_containers=True + frameid, vals[1], decode_containers=True ) # Package as protobuf guy @@ -29,10 +31,14 @@ async def serial_reciever(can_db: cantools.db.Database, message_classes, q1, q2) decoded_msg, msg.name.lower(), message_classes ) data = QueueData(msg.DESCRIPTOR.name, msg) - - # Throw data into queues and start again + # Throw data into queues and start again await q1.put(data) await q2.put(data) - except: - print("Fail") - pass + # except: + # print("Fail") + # pass + except (KeyError,TypeError,ValueError) as e: + print(f"Error with id {frameid}, error : {e}") + continue + + From 4ad1658a9f1c21658fe1f7101ea5f1cced8062d5 Mon Sep 17 00:00:00 2001 From: mathbrook Date: Mon, 8 Apr 2024 22:27:28 -0400 Subject: [PATCH 07/17] correct baudrate --- py_data_acq/py_data_acq/io_handler/serial_handle.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/py_data_acq/py_data_acq/io_handler/serial_handle.py b/py_data_acq/py_data_acq/io_handler/serial_handle.py index be88522..a38ae4b 100644 --- a/py_data_acq/py_data_acq/io_handler/serial_handle.py +++ b/py_data_acq/py_data_acq/io_handler/serial_handle.py @@ -7,7 +7,7 @@ async def serial_reciever(can_db: cantools.db.Database, message_classes, q1, q2): # Start asyncio on the port reader, writer = await serial_asyncio.open_serial_connection( - url="/dev/xboi", baudrate=230400 + url="/dev/xboi", baudrate=115200 ) while True: From 543b939cd305be207659d2232f291e5a6c1e3df4 Mon Sep 17 00:00:00 2001 From: ChanceCtrl Date: Tue, 9 Apr 2024 00:40:32 +0000 Subject: [PATCH 08/17] try guy throwing everything into try block to prevent the serial handler from killing the server --- .../py_data_acq/io_handler/serial_handle.py | 20 +++++++------------ 1 file changed, 7 insertions(+), 13 deletions(-) diff --git a/py_data_acq/py_data_acq/io_handler/serial_handle.py b/py_data_acq/py_data_acq/io_handler/serial_handle.py index a38ae4b..bdf3c0a 100644 --- a/py_data_acq/py_data_acq/io_handler/serial_handle.py +++ b/py_data_acq/py_data_acq/io_handler/serial_handle.py @@ -11,15 +11,11 @@ async def serial_reciever(can_db: cantools.db.Database, message_classes, q1, q2) ) while True: - # Wait for the next message from the buffer, then break it into parts using the byte value for "," - nl_byte = await reader.readline() - vals = nl_byte.split(b",") - print(f"Raw Line: {nl_byte}") - print(f"Comma delimited: {vals}") - # try: - # Get message data for foxglove - frameid = int.from_bytes(vals[0],byteorder='little') try: + # Wait for the next message from the buffer, then break it into parts using the byte value for "," + nl_byte = await reader.readline() + vals = nl_byte.split(b",") + frameid = int.from_bytes(vals[0], byteorder="little") msg = can_db.get_message_by_frame_id(frameid) # Break down message decoded_msg = can_db.decode_message( @@ -31,14 +27,12 @@ async def serial_reciever(can_db: cantools.db.Database, message_classes, q1, q2) decoded_msg, msg.name.lower(), message_classes ) data = QueueData(msg.DESCRIPTOR.name, msg) - # Throw data into queues and start again + # Throw data into queues and start again await q1.put(data) await q2.put(data) # except: # print("Fail") # pass - except (KeyError,TypeError,ValueError) as e: - print(f"Error with id {frameid}, error : {e}") + except (KeyError, TypeError, ValueError) as e: + print(f"Error decoding frame, error : {e}") continue - - From cb480ab3a5c33f1ed7f3d6427008f417ae6fa899 Mon Sep 17 00:00:00 2001 From: ChanceCtrl Date: Tue, 9 Apr 2024 02:27:55 +0000 Subject: [PATCH 09/17] adding errors lol --- py_data_acq/py_data_acq/io_handler/serial_handle.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/py_data_acq/py_data_acq/io_handler/serial_handle.py b/py_data_acq/py_data_acq/io_handler/serial_handle.py index bdf3c0a..059ea03 100644 --- a/py_data_acq/py_data_acq/io_handler/serial_handle.py +++ b/py_data_acq/py_data_acq/io_handler/serial_handle.py @@ -33,6 +33,6 @@ async def serial_reciever(can_db: cantools.db.Database, message_classes, q1, q2) # except: # print("Fail") # pass - except (KeyError, TypeError, ValueError) as e: + except (KeyError, TypeError, ValueError, IndexError) as e: print(f"Error decoding frame, error : {e}") continue From 1622a8403abde90e577fe390a503ba829fbcb4e0 Mon Sep 17 00:00:00 2001 From: ChanceCtrl Date: Wed, 10 Apr 2024 00:45:14 +0000 Subject: [PATCH 10/17] update lock --- flake.lock | 36 ++++++++++++++++++------------------ 1 file changed, 18 insertions(+), 18 deletions(-) diff --git a/flake.lock b/flake.lock index c8c99d0..5e40584 100644 --- a/flake.lock +++ b/flake.lock @@ -25,11 +25,11 @@ "utils": "utils_2" }, "locked": { - "lastModified": 1708796918, - "narHash": "sha256-cR0Rudt+T5xYWuLPRtC6p2K+c83sN6p6DNo9CecTql8=", + "lastModified": 1712715991, + "narHash": "sha256-5eZWtJPBq/to3uVkmmhp6KcWcbaTMY4ihV8cFRJ7BfI=", "owner": "KSU-MS", "repo": "Nix_CAN", - "rev": "94499eaa5f9a447ad559c6fbbb7163ce15c3af31", + "rev": "f7b31f081ba3a8ddff0aa0eee0fbd207a9860a7b", "type": "github" }, "original": { @@ -44,11 +44,11 @@ "utils": "utils_3" }, "locked": { - "lastModified": 1703087404, - "narHash": "sha256-PJB1pXZUrt8Za4PxXyIZtRffq5FuDS4do8lQPpY4iMY=", + "lastModified": 1711401255, + "narHash": "sha256-V9VX0LOHqXKoBuIY6gIsiU1WDDGZTGmOQULQ0YUur8s=", "owner": "RCMast3r", "repo": "py_foxglove_webserver_nix", - "rev": "bbab26c716248fad51447b4ab8f4b84b75e3677a", + "rev": "61b43a707534b3ea41fed1ccc9369d893178a7f4", "type": "github" }, "original": { @@ -117,11 +117,11 @@ "nixpkgs": "nixpkgs_6" }, "locked": { - "lastModified": 1703652955, - "narHash": "sha256-9kCfd8qbkRwflWRuuhs8hJM/2b+ojmBTmULvCiCl0Hg=", + "lastModified": 1709706423, + "narHash": "sha256-uL/H0zh/Ckz1o5vWdd2DiKSu2QAPlYDNiOzpSymbPao=", "owner": "notalltim", "repo": "nix-proto", - "rev": "a067a064aee705e75f38163c869a6a77456278fe", + "rev": "2ccac0a3f70bb84a485db60f1a7ac7688c992d92", "type": "github" }, "original": { @@ -163,11 +163,11 @@ }, "nixpkgs_2": { "locked": { - "lastModified": 1707650010, - "narHash": "sha256-dOhphIA4MGrH4ElNCy/OlwmN24MsnEqFjRR6+RY7jZw=", + "lastModified": 1708294118, + "narHash": "sha256-evZzmLW7qoHXf76VCepvun1esZDxHfVRFUJtumD7L2M=", "owner": "NixOS", "repo": "nixpkgs", - "rev": "809cca784b9f72a5ad4b991e0e7bcf8890f9c3a6", + "rev": "e0da498ad77ac8909a980f07eff060862417ccf7", "type": "github" }, "original": { @@ -243,11 +243,11 @@ }, "nixpkgs_7": { "locked": { - "lastModified": 1702921762, - "narHash": "sha256-O/rP7gulApQAB47u6szEd8Pn8Biw0d84j5iuP2tcxzY=", + "lastModified": 1712588820, + "narHash": "sha256-y31s5idk3jMJMAVE4Ud9AdI7HT3CgTAeMTJ0StqKN7Y=", "owner": "NixOS", "repo": "nixpkgs", - "rev": "d02ffbbe834b5599fc5f134e644e49397eb07188", + "rev": "d272ca50d1f7424fbfcd1e6f1c9e01d92f6da167", "type": "github" }, "original": { @@ -454,11 +454,11 @@ "systems": "systems_6" }, "locked": { - "lastModified": 1701680307, - "narHash": "sha256-kAuep2h5ajznlPMD9rnQyffWG8EM/C73lejGofXvdM8=", + "lastModified": 1710146030, + "narHash": "sha256-SZ5L6eA7HJ/nmkzGG7/ISclqe6oZdOZTNoesiInkXPQ=", "owner": "numtide", "repo": "flake-utils", - "rev": "4022d587cbbfd70fe950c1e2083a02621806a725", + "rev": "b1d9ab70662946ef0850d488da1c9019f3a9752a", "type": "github" }, "original": { From fd7f65b49af9355a7e53cb0c21ad6367051dcdf2 Mon Sep 17 00:00:00 2001 From: ChanceCtrl Date: Wed, 10 Apr 2024 03:23:20 +0000 Subject: [PATCH 11/17] fix cantools --- flake.nix | 63 +++++++++++++++++++++++++++++++++++++------------------ 1 file changed, 43 insertions(+), 20 deletions(-) diff --git a/flake.nix b/flake.nix index 57030c5..50fb34d 100644 --- a/flake.nix +++ b/flake.nix @@ -13,8 +13,18 @@ nix-proto.url = "github:notalltim/nix-proto"; }; - outputs = { self, nixpkgs, utils, mcap-protobuf, mcap, foxglove-websocket - , asyncudp, nix-proto, can_pkg_flake, ... }@inputs: + outputs = + { self + , nixpkgs + , utils + , mcap-protobuf + , mcap + , foxglove-websocket + , asyncudp + , nix-proto + , can_pkg_flake + , ... + }@inputs: let makePackageSet = pkgs: { py_data_acq_pkg = pkgs.py_data_acq_pkg; @@ -45,6 +55,16 @@ }; }; my_overlays = [ + (self: super: { + cantools = super.cantools.overridePythonAttrs (old: rec { + version = "39.4.5"; + src = old.fetchPypi { + pname = "cantools"; + inherit version; + # hash = "sha256-JQn+rtpy/OA2deLszSKEuxyttqBzcAil50H+JDHUdCE="; + }; + }); + }) py_dbc_proto_gen_overlay py_data_acq_overlay proto_gen_overlay @@ -76,7 +96,8 @@ "aarch64-linux" = makePackageSet arm_pkgs; # Add more systems as needed }; - in { + in + { overlays.default = nixpkgs.lib.composeManyExtensions my_overlays; @@ -96,17 +117,19 @@ ]; # Setting up the environment variables you need during # development. - shellHook = let icon = "f121"; - in '' - path=${x86_pkgs.proto_gen_pkg} - bin_path=$path"/bin" - dbc_path=${x86_pkgs.can_pkg} - export BIN_PATH=$bin_path - export DBC_PATH=$dbc_path + shellHook = + let icon = "f121"; + in + '' + path=${x86_pkgs.proto_gen_pkg} + bin_path=$path"/bin" + dbc_path=${x86_pkgs.can_pkg} + export BIN_PATH=$bin_path + export DBC_PATH=$dbc_path - echo -e "PYTHONPATH=$PYTHONPATH\nBIN_PATH=$bin_path\nDBC_PATH=$dbc_path\n" > .env - export PS1="$(echo -e '\u${icon}') {\[$(tput sgr0)\]\[\033[38;5;228m\]\w\[$(tput sgr0)\]\[\033[38;5;15m\]} (${name}) \\$ \[$(tput sgr0)\]" - ''; + echo -e "PYTHONPATH=$PYTHONPATH\nBIN_PATH=$bin_path\nDBC_PATH=$dbc_path\n" > .env + export PS1="$(echo -e '\u${icon}') {\[$(tput sgr0)\]\[\033[38;5;228m\]\w\[$(tput sgr0)\]\[\033[38;5;15m\]} (${name}) \\$ \[$(tput sgr0)\]" + ''; }; devShells.x86_64-linux.ci = x86_pkgs.mkShell rec { # Update the name to something that suites your project. @@ -119,13 +142,13 @@ protobuf ]; shellHook = - '' - path=${x86_pkgs.proto_gen_pkg} - bin_path=$path"/bin" - dbc_path=${x86_pkgs.can_pkg} - export BIN_PATH=$bin_path - export DBC_PATH=$dbc_path - ''; + '' + path=${x86_pkgs.proto_gen_pkg} + bin_path=$path"/bin" + dbc_path=${x86_pkgs.can_pkg} + export BIN_PATH=$bin_path + export DBC_PATH=$dbc_path + ''; }; From d50fa750c65a4fe7fd9bc6b8ab491a525c87f774 Mon Sep 17 00:00:00 2001 From: ChanceCtrl Date: Wed, 10 Apr 2024 22:44:14 +0000 Subject: [PATCH 12/17] Revert flake lock fuc --- flake.lock | 34 +++++++++++------------ flake.nix | 63 ++++++++++++++----------------------------- py_data_acq/runner.py | 1 + 3 files changed, 38 insertions(+), 60 deletions(-) diff --git a/flake.lock b/flake.lock index 5e40584..5209dcb 100644 --- a/flake.lock +++ b/flake.lock @@ -25,8 +25,8 @@ "utils": "utils_2" }, "locked": { - "lastModified": 1712715991, - "narHash": "sha256-5eZWtJPBq/to3uVkmmhp6KcWcbaTMY4ihV8cFRJ7BfI=", + "lastModified": 1708796918, + "narHash": "sha256-cR0Rudt+T5xYWuLPRtC6p2K+c83sN6p6DNo9CecTql8=", "owner": "KSU-MS", "repo": "Nix_CAN", "rev": "f7b31f081ba3a8ddff0aa0eee0fbd207a9860a7b", @@ -44,11 +44,11 @@ "utils": "utils_3" }, "locked": { - "lastModified": 1711401255, - "narHash": "sha256-V9VX0LOHqXKoBuIY6gIsiU1WDDGZTGmOQULQ0YUur8s=", + "lastModified": 1703087404, + "narHash": "sha256-PJB1pXZUrt8Za4PxXyIZtRffq5FuDS4do8lQPpY4iMY=", "owner": "RCMast3r", "repo": "py_foxglove_webserver_nix", - "rev": "61b43a707534b3ea41fed1ccc9369d893178a7f4", + "rev": "bbab26c716248fad51447b4ab8f4b84b75e3677a", "type": "github" }, "original": { @@ -117,11 +117,11 @@ "nixpkgs": "nixpkgs_6" }, "locked": { - "lastModified": 1709706423, - "narHash": "sha256-uL/H0zh/Ckz1o5vWdd2DiKSu2QAPlYDNiOzpSymbPao=", + "lastModified": 1703652955, + "narHash": "sha256-9kCfd8qbkRwflWRuuhs8hJM/2b+ojmBTmULvCiCl0Hg=", "owner": "notalltim", "repo": "nix-proto", - "rev": "2ccac0a3f70bb84a485db60f1a7ac7688c992d92", + "rev": "a067a064aee705e75f38163c869a6a77456278fe", "type": "github" }, "original": { @@ -163,11 +163,11 @@ }, "nixpkgs_2": { "locked": { - "lastModified": 1708294118, - "narHash": "sha256-evZzmLW7qoHXf76VCepvun1esZDxHfVRFUJtumD7L2M=", + "lastModified": 1707650010, + "narHash": "sha256-dOhphIA4MGrH4ElNCy/OlwmN24MsnEqFjRR6+RY7jZw=", "owner": "NixOS", "repo": "nixpkgs", - "rev": "e0da498ad77ac8909a980f07eff060862417ccf7", + "rev": "809cca784b9f72a5ad4b991e0e7bcf8890f9c3a6", "type": "github" }, "original": { @@ -243,11 +243,11 @@ }, "nixpkgs_7": { "locked": { - "lastModified": 1712588820, - "narHash": "sha256-y31s5idk3jMJMAVE4Ud9AdI7HT3CgTAeMTJ0StqKN7Y=", + "lastModified": 1702921762, + "narHash": "sha256-O/rP7gulApQAB47u6szEd8Pn8Biw0d84j5iuP2tcxzY=", "owner": "NixOS", "repo": "nixpkgs", - "rev": "d272ca50d1f7424fbfcd1e6f1c9e01d92f6da167", + "rev": "d02ffbbe834b5599fc5f134e644e49397eb07188", "type": "github" }, "original": { @@ -454,11 +454,11 @@ "systems": "systems_6" }, "locked": { - "lastModified": 1710146030, - "narHash": "sha256-SZ5L6eA7HJ/nmkzGG7/ISclqe6oZdOZTNoesiInkXPQ=", + "lastModified": 1701680307, + "narHash": "sha256-kAuep2h5ajznlPMD9rnQyffWG8EM/C73lejGofXvdM8=", "owner": "numtide", "repo": "flake-utils", - "rev": "b1d9ab70662946ef0850d488da1c9019f3a9752a", + "rev": "4022d587cbbfd70fe950c1e2083a02621806a725", "type": "github" }, "original": { diff --git a/flake.nix b/flake.nix index 50fb34d..57030c5 100644 --- a/flake.nix +++ b/flake.nix @@ -13,18 +13,8 @@ nix-proto.url = "github:notalltim/nix-proto"; }; - outputs = - { self - , nixpkgs - , utils - , mcap-protobuf - , mcap - , foxglove-websocket - , asyncudp - , nix-proto - , can_pkg_flake - , ... - }@inputs: + outputs = { self, nixpkgs, utils, mcap-protobuf, mcap, foxglove-websocket + , asyncudp, nix-proto, can_pkg_flake, ... }@inputs: let makePackageSet = pkgs: { py_data_acq_pkg = pkgs.py_data_acq_pkg; @@ -55,16 +45,6 @@ }; }; my_overlays = [ - (self: super: { - cantools = super.cantools.overridePythonAttrs (old: rec { - version = "39.4.5"; - src = old.fetchPypi { - pname = "cantools"; - inherit version; - # hash = "sha256-JQn+rtpy/OA2deLszSKEuxyttqBzcAil50H+JDHUdCE="; - }; - }); - }) py_dbc_proto_gen_overlay py_data_acq_overlay proto_gen_overlay @@ -96,8 +76,7 @@ "aarch64-linux" = makePackageSet arm_pkgs; # Add more systems as needed }; - in - { + in { overlays.default = nixpkgs.lib.composeManyExtensions my_overlays; @@ -117,19 +96,17 @@ ]; # Setting up the environment variables you need during # development. - shellHook = - let icon = "f121"; - in - '' - path=${x86_pkgs.proto_gen_pkg} - bin_path=$path"/bin" - dbc_path=${x86_pkgs.can_pkg} - export BIN_PATH=$bin_path - export DBC_PATH=$dbc_path + shellHook = let icon = "f121"; + in '' + path=${x86_pkgs.proto_gen_pkg} + bin_path=$path"/bin" + dbc_path=${x86_pkgs.can_pkg} + export BIN_PATH=$bin_path + export DBC_PATH=$dbc_path - echo -e "PYTHONPATH=$PYTHONPATH\nBIN_PATH=$bin_path\nDBC_PATH=$dbc_path\n" > .env - export PS1="$(echo -e '\u${icon}') {\[$(tput sgr0)\]\[\033[38;5;228m\]\w\[$(tput sgr0)\]\[\033[38;5;15m\]} (${name}) \\$ \[$(tput sgr0)\]" - ''; + echo -e "PYTHONPATH=$PYTHONPATH\nBIN_PATH=$bin_path\nDBC_PATH=$dbc_path\n" > .env + export PS1="$(echo -e '\u${icon}') {\[$(tput sgr0)\]\[\033[38;5;228m\]\w\[$(tput sgr0)\]\[\033[38;5;15m\]} (${name}) \\$ \[$(tput sgr0)\]" + ''; }; devShells.x86_64-linux.ci = x86_pkgs.mkShell rec { # Update the name to something that suites your project. @@ -142,13 +119,13 @@ protobuf ]; shellHook = - '' - path=${x86_pkgs.proto_gen_pkg} - bin_path=$path"/bin" - dbc_path=${x86_pkgs.can_pkg} - export BIN_PATH=$bin_path - export DBC_PATH=$dbc_path - ''; + '' + path=${x86_pkgs.proto_gen_pkg} + bin_path=$path"/bin" + dbc_path=${x86_pkgs.can_pkg} + export BIN_PATH=$bin_path + export DBC_PATH=$dbc_path + ''; }; diff --git a/py_data_acq/runner.py b/py_data_acq/runner.py index e2888be..e7a9b7e 100644 --- a/py_data_acq/runner.py +++ b/py_data_acq/runner.py @@ -69,6 +69,7 @@ async def run(logger): mcap_server = MCAPServer(mcap_writer=mcap_writer, path=path_to_mcap) # Get data source + os.environ["D_SOURCE"] = "SERIAL" match os.environ.get("D_SOURCE"): case "SERIAL": receiver_task = asyncio.create_task( From a0ace387674e4ef1051fc1c85b9151bf9fa8ca1d Mon Sep 17 00:00:00 2001 From: ChanceCtrl Date: Wed, 10 Apr 2024 23:17:38 +0000 Subject: [PATCH 13/17] update input to expect sync byte and fixed message length --- .../py_data_acq/io_handler/serial_handle.py | 49 +++++++++++-------- 1 file changed, 29 insertions(+), 20 deletions(-) diff --git a/py_data_acq/py_data_acq/io_handler/serial_handle.py b/py_data_acq/py_data_acq/io_handler/serial_handle.py index 059ea03..af68ac4 100644 --- a/py_data_acq/py_data_acq/io_handler/serial_handle.py +++ b/py_data_acq/py_data_acq/io_handler/serial_handle.py @@ -4,6 +4,14 @@ from ..common.common_types import QueueData +def check_sync_byte(reader): + byte_guy = reader.read(1) + if byte_guy == 0xFA: + return True + else: + return False + + async def serial_reciever(can_db: cantools.db.Database, message_classes, q1, q2): # Start asyncio on the port reader, writer = await serial_asyncio.open_serial_connection( @@ -12,27 +20,28 @@ async def serial_reciever(can_db: cantools.db.Database, message_classes, q1, q2) while True: try: - # Wait for the next message from the buffer, then break it into parts using the byte value for "," - nl_byte = await reader.readline() - vals = nl_byte.split(b",") - frameid = int.from_bytes(vals[0], byteorder="little") - msg = can_db.get_message_by_frame_id(frameid) - # Break down message - decoded_msg = can_db.decode_message( - frameid, vals[1], decode_containers=True - ) + if check_sync_byte(reader): + # Wait for the next message from the buffer, then break it into parts using the byte value for "," + sync_msg = await reader.readexactly(12) + frameid = int.from_bytes(sync_msg[0:4], byteorder="little") + msg = can_db.get_message_by_frame_id(frameid) + + # Break down message + decoded_msg = can_db.decode_message( + frameid, sync_msg[4:12], decode_containers=True + ) - # Package as protobuf guy - msg = protobuf_helpers.pack_protobuf_msg( - decoded_msg, msg.name.lower(), message_classes - ) - data = QueueData(msg.DESCRIPTOR.name, msg) - # Throw data into queues and start again - await q1.put(data) - await q2.put(data) - # except: - # print("Fail") - # pass + # Package as protobuf guy + msg = protobuf_helpers.pack_protobuf_msg( + decoded_msg, msg.name.lower(), message_classes + ) + data = QueueData(msg.DESCRIPTOR.name, msg) + # Throw data into queues and start again + await q1.put(data) + await q2.put(data) + # except: + # print("Fail") + # pass except (KeyError, TypeError, ValueError, IndexError) as e: print(f"Error decoding frame, error : {e}") continue From 281fb11cb6f7f9e00f921dbc450627159a79cd11 Mon Sep 17 00:00:00 2001 From: mathbrook Date: Thu, 11 Apr 2024 00:12:01 -0400 Subject: [PATCH 14/17] joe delimiter --- .../py_data_acq/io_handler/serial_handle.py | 44 +++++++++---------- 1 file changed, 22 insertions(+), 22 deletions(-) diff --git a/py_data_acq/py_data_acq/io_handler/serial_handle.py b/py_data_acq/py_data_acq/io_handler/serial_handle.py index af68ac4..ca15e8b 100644 --- a/py_data_acq/py_data_acq/io_handler/serial_handle.py +++ b/py_data_acq/py_data_acq/io_handler/serial_handle.py @@ -4,8 +4,8 @@ from ..common.common_types import QueueData -def check_sync_byte(reader): - byte_guy = reader.read(1) +async def check_sync_byte(reader): + byte_guy = await reader.read(1) if byte_guy == 0xFA: return True else: @@ -20,28 +20,28 @@ async def serial_reciever(can_db: cantools.db.Database, message_classes, q1, q2) while True: try: - if check_sync_byte(reader): - # Wait for the next message from the buffer, then break it into parts using the byte value for "," - sync_msg = await reader.readexactly(12) - frameid = int.from_bytes(sync_msg[0:4], byteorder="little") - msg = can_db.get_message_by_frame_id(frameid) + # if check_sync_byte(reader): + # Wait for the next message from the buffer, then break it into parts using the byte value for "," + sync_msg = await reader.readuntil(b'\n\xff\n') + frameid = int.from_bytes(sync_msg[0:2], byteorder="little") + msg = can_db.get_message_by_frame_id(frameid) - # Break down message - decoded_msg = can_db.decode_message( - frameid, sync_msg[4:12], decode_containers=True - ) + # Break down message + decoded_msg = can_db.decode_message( + frameid, sync_msg[2:-3], decode_containers=True + ) - # Package as protobuf guy - msg = protobuf_helpers.pack_protobuf_msg( - decoded_msg, msg.name.lower(), message_classes - ) - data = QueueData(msg.DESCRIPTOR.name, msg) - # Throw data into queues and start again - await q1.put(data) - await q2.put(data) - # except: - # print("Fail") - # pass + # Package as protobuf guy + msg = protobuf_helpers.pack_protobuf_msg( + decoded_msg, msg.name.lower(), message_classes + ) + data = QueueData(msg.DESCRIPTOR.name, msg) + # Throw data into queues and start again + await q1.put(data) + await q2.put(data) + # except: + # print("Fail") + # pass except (KeyError, TypeError, ValueError, IndexError) as e: print(f"Error decoding frame, error : {e}") continue From 26aeab8b9ce159e445612cbcc0091cfd5353b67f Mon Sep 17 00:00:00 2001 From: ChanceCtrl Date: Thu, 11 Apr 2024 00:16:53 +0000 Subject: [PATCH 15/17] joe lock --- flake.lock | 34 +++++++++---------- .../py_data_acq/io_handler/serial_handle.py | 6 ++-- 2 files changed, 19 insertions(+), 21 deletions(-) diff --git a/flake.lock b/flake.lock index 5209dcb..5e40584 100644 --- a/flake.lock +++ b/flake.lock @@ -25,8 +25,8 @@ "utils": "utils_2" }, "locked": { - "lastModified": 1708796918, - "narHash": "sha256-cR0Rudt+T5xYWuLPRtC6p2K+c83sN6p6DNo9CecTql8=", + "lastModified": 1712715991, + "narHash": "sha256-5eZWtJPBq/to3uVkmmhp6KcWcbaTMY4ihV8cFRJ7BfI=", "owner": "KSU-MS", "repo": "Nix_CAN", "rev": "f7b31f081ba3a8ddff0aa0eee0fbd207a9860a7b", @@ -44,11 +44,11 @@ "utils": "utils_3" }, "locked": { - "lastModified": 1703087404, - "narHash": "sha256-PJB1pXZUrt8Za4PxXyIZtRffq5FuDS4do8lQPpY4iMY=", + "lastModified": 1711401255, + "narHash": "sha256-V9VX0LOHqXKoBuIY6gIsiU1WDDGZTGmOQULQ0YUur8s=", "owner": "RCMast3r", "repo": "py_foxglove_webserver_nix", - "rev": "bbab26c716248fad51447b4ab8f4b84b75e3677a", + "rev": "61b43a707534b3ea41fed1ccc9369d893178a7f4", "type": "github" }, "original": { @@ -117,11 +117,11 @@ "nixpkgs": "nixpkgs_6" }, "locked": { - "lastModified": 1703652955, - "narHash": "sha256-9kCfd8qbkRwflWRuuhs8hJM/2b+ojmBTmULvCiCl0Hg=", + "lastModified": 1709706423, + "narHash": "sha256-uL/H0zh/Ckz1o5vWdd2DiKSu2QAPlYDNiOzpSymbPao=", "owner": "notalltim", "repo": "nix-proto", - "rev": "a067a064aee705e75f38163c869a6a77456278fe", + "rev": "2ccac0a3f70bb84a485db60f1a7ac7688c992d92", "type": "github" }, "original": { @@ -163,11 +163,11 @@ }, "nixpkgs_2": { "locked": { - "lastModified": 1707650010, - "narHash": "sha256-dOhphIA4MGrH4ElNCy/OlwmN24MsnEqFjRR6+RY7jZw=", + "lastModified": 1708294118, + "narHash": "sha256-evZzmLW7qoHXf76VCepvun1esZDxHfVRFUJtumD7L2M=", "owner": "NixOS", "repo": "nixpkgs", - "rev": "809cca784b9f72a5ad4b991e0e7bcf8890f9c3a6", + "rev": "e0da498ad77ac8909a980f07eff060862417ccf7", "type": "github" }, "original": { @@ -243,11 +243,11 @@ }, "nixpkgs_7": { "locked": { - "lastModified": 1702921762, - "narHash": "sha256-O/rP7gulApQAB47u6szEd8Pn8Biw0d84j5iuP2tcxzY=", + "lastModified": 1712588820, + "narHash": "sha256-y31s5idk3jMJMAVE4Ud9AdI7HT3CgTAeMTJ0StqKN7Y=", "owner": "NixOS", "repo": "nixpkgs", - "rev": "d02ffbbe834b5599fc5f134e644e49397eb07188", + "rev": "d272ca50d1f7424fbfcd1e6f1c9e01d92f6da167", "type": "github" }, "original": { @@ -454,11 +454,11 @@ "systems": "systems_6" }, "locked": { - "lastModified": 1701680307, - "narHash": "sha256-kAuep2h5ajznlPMD9rnQyffWG8EM/C73lejGofXvdM8=", + "lastModified": 1710146030, + "narHash": "sha256-SZ5L6eA7HJ/nmkzGG7/ISclqe6oZdOZTNoesiInkXPQ=", "owner": "numtide", "repo": "flake-utils", - "rev": "4022d587cbbfd70fe950c1e2083a02621806a725", + "rev": "b1d9ab70662946ef0850d488da1c9019f3a9752a", "type": "github" }, "original": { diff --git a/py_data_acq/py_data_acq/io_handler/serial_handle.py b/py_data_acq/py_data_acq/io_handler/serial_handle.py index ca15e8b..293e76f 100644 --- a/py_data_acq/py_data_acq/io_handler/serial_handle.py +++ b/py_data_acq/py_data_acq/io_handler/serial_handle.py @@ -22,7 +22,7 @@ async def serial_reciever(can_db: cantools.db.Database, message_classes, q1, q2) try: # if check_sync_byte(reader): # Wait for the next message from the buffer, then break it into parts using the byte value for "," - sync_msg = await reader.readuntil(b'\n\xff\n') + sync_msg = await reader.readuntil(b"\n\xff\n") frameid = int.from_bytes(sync_msg[0:2], byteorder="little") msg = can_db.get_message_by_frame_id(frameid) @@ -39,9 +39,7 @@ async def serial_reciever(can_db: cantools.db.Database, message_classes, q1, q2) # Throw data into queues and start again await q1.put(data) await q2.put(data) - # except: - # print("Fail") - # pass + except (KeyError, TypeError, ValueError, IndexError) as e: print(f"Error decoding frame, error : {e}") continue From c9e78f67577036b5a3e68078c1f67285ed1f0ad4 Mon Sep 17 00:00:00 2001 From: mathbrook Date: Thu, 11 Apr 2024 02:33:49 -0400 Subject: [PATCH 16/17] modify protogen and force typecasting in protobuf helper --- .../py_data_acq/common/protobuf_helpers.py | 14 ++++++++--- .../py_data_acq/io_handler/serial_handle.py | 10 ++++---- py_dbc_proto_gen/dbc_to_proto.py | 23 +++++++++++++++---- 3 files changed, 36 insertions(+), 11 deletions(-) diff --git a/py_data_acq/py_data_acq/common/protobuf_helpers.py b/py_data_acq/py_data_acq/common/protobuf_helpers.py index 6ebf5af..d6e4f29 100644 --- a/py_data_acq/py_data_acq/common/protobuf_helpers.py +++ b/py_data_acq/py_data_acq/common/protobuf_helpers.py @@ -24,8 +24,16 @@ def pack_protobuf_msg(cantools_dict: dict, msg_name: str, message_classes): if msg_name in message_classes: pb_msg = message_classes[msg_name]() for key in cantools_dict.keys(): - if(type(cantools_dict[key]) is namedsignalvalue.NamedSignalValue): - setattr(pb_msg, key, cantools_dict[key].value) - else: + try: setattr(pb_msg, key, cantools_dict[key]) + except TypeError as e: + print(f"Caught TypeError: {e}") + expected_type = type(getattr(pb_msg, key)) + + try: + converted_value = expected_type(cantools_dict[key]) + setattr(pb_msg, key, converted_value) + print(f"Successfully set {key} to {converted_value}") + except ValueError: + print(f"Unable to convert {cantools_dict[key]} to {expected_type.__name__}") return pb_msg diff --git a/py_data_acq/py_data_acq/io_handler/serial_handle.py b/py_data_acq/py_data_acq/io_handler/serial_handle.py index 293e76f..49518a2 100644 --- a/py_data_acq/py_data_acq/io_handler/serial_handle.py +++ b/py_data_acq/py_data_acq/io_handler/serial_handle.py @@ -22,15 +22,15 @@ async def serial_reciever(can_db: cantools.db.Database, message_classes, q1, q2) try: # if check_sync_byte(reader): # Wait for the next message from the buffer, then break it into parts using the byte value for "," - sync_msg = await reader.readuntil(b"\n\xff\n") + decoded_msg = None + sync_msg = await reader.readuntil(b'\n\xff\n') frameid = int.from_bytes(sync_msg[0:2], byteorder="little") msg = can_db.get_message_by_frame_id(frameid) - + payload = sync_msg[2:-3] # Break down message decoded_msg = can_db.decode_message( - frameid, sync_msg[2:-3], decode_containers=True + frameid, payload, decode_containers=True, decode_choices=True ) - # Package as protobuf guy msg = protobuf_helpers.pack_protobuf_msg( decoded_msg, msg.name.lower(), message_classes @@ -42,4 +42,6 @@ async def serial_reciever(can_db: cantools.db.Database, message_classes, q1, q2) except (KeyError, TypeError, ValueError, IndexError) as e: print(f"Error decoding frame, error : {e}") + if decoded_msg: + print(f"error msg: {decoded_msg}") continue diff --git a/py_dbc_proto_gen/dbc_to_proto.py b/py_dbc_proto_gen/dbc_to_proto.py index b612cac..d623a86 100644 --- a/py_dbc_proto_gen/dbc_to_proto.py +++ b/py_dbc_proto_gen/dbc_to_proto.py @@ -41,7 +41,7 @@ def append_proto_message_from_CAN_message(file, can_msg: can.message.Message): + str(line_index) + ";" ) - elif sig.choices is not None and sig.length != 1: + elif sig.choices is not None: line = ( " string " + create_field_name(sig.name) @@ -57,7 +57,7 @@ def append_proto_message_from_CAN_message(file, can_msg: can.message.Message): + str(line_index) + ";" ) - elif sig.length > 1: + elif (sig.length > 1 and sig.length <=32): line = ( " int32 " + create_field_name(sig.name) @@ -65,10 +65,25 @@ def append_proto_message_from_CAN_message(file, can_msg: can.message.Message): + str(line_index) + ";" ) + elif (sig.length >= 32 and not sig.is_signed): + line = ( + " uint64 " + + create_field_name(sig.name) + + " = " + + str(line_index) + + ";" + ) + elif (sig.length >= 32 and not sig.is_signed): + line = ( + " uint64 " + + create_field_name(sig.name) + + " = " + + str(line_index) + + ";" + ) else: - print("ERROR") line = ( - " null " + " int64 " + create_field_name(sig.name) + " = " + str(line_index) From 4fd94effefcff1dbb3744bb45f4f3fa82a0c3d62 Mon Sep 17 00:00:00 2001 From: ChanceCtrl <142356358+ChanceCtrl@users.noreply.github.com> Date: Thu, 11 Apr 2024 06:51:29 +0000 Subject: [PATCH 17/17] Update serial_handle.py --- py_data_acq/py_data_acq/io_handler/serial_handle.py | 8 -------- 1 file changed, 8 deletions(-) diff --git a/py_data_acq/py_data_acq/io_handler/serial_handle.py b/py_data_acq/py_data_acq/io_handler/serial_handle.py index 49518a2..ecd7569 100644 --- a/py_data_acq/py_data_acq/io_handler/serial_handle.py +++ b/py_data_acq/py_data_acq/io_handler/serial_handle.py @@ -4,14 +4,6 @@ from ..common.common_types import QueueData -async def check_sync_byte(reader): - byte_guy = await reader.read(1) - if byte_guy == 0xFA: - return True - else: - return False - - async def serial_reciever(can_db: cantools.db.Database, message_classes, q1, q2): # Start asyncio on the port reader, writer = await serial_asyncio.open_serial_connection(