From cd629ec301dbf87a38138cad6eedfee897d4c822 Mon Sep 17 00:00:00 2001 From: Cameron Brown Date: Sun, 3 Nov 2024 12:09:32 -0500 Subject: [PATCH] electrical_protocol: Allow string and character packets to be constructed --- .../electrical_protocol/packet.py | 36 ++++++---- .../test/calculator_device.py | 47 +++++++++++-- .../test/test_simulated_basic.py | 69 +++++++++++++++++-- 3 files changed, 128 insertions(+), 24 deletions(-) diff --git a/mil_common/drivers/electrical_protocol/electrical_protocol/packet.py b/mil_common/drivers/electrical_protocol/electrical_protocol/packet.py index d69ed073b..dde372b87 100644 --- a/mil_common/drivers/electrical_protocol/electrical_protocol/packet.py +++ b/mil_common/drivers/electrical_protocol/electrical_protocol/packet.py @@ -112,17 +112,15 @@ def __init_subclass__( def __post_init__(self): for name, field_type in get_cache_hints(self.__class__).items(): - if ( - name - not in [ - "class_id", - "subclass_id", - "payload_format", - ] - and not isinstance(self.__dict__[name], field_type) - and issubclass(field_type, Enum) - ): - setattr(self, name, field_type(self.__dict__[name])) + if name not in [ + "class_id", + "subclass_id", + "payload_format", + ] and not isinstance(self.__dict__[name], field_type): + if issubclass(field_type, Enum): + setattr(self, name, field_type(self.__dict__[name])) + elif issubclass(field_type, str): + setattr(self, name, self.__dict__[name].rstrip(b"\x00").decode()) if self.payload_format and not self.payload_format.startswith( ("<", ">", "=", "!"), ): @@ -163,7 +161,21 @@ def _calculate_checksum(cls, data: bytes) -> tuple[int, int]: return sum1, sum2 def __bytes__(self): - payload = struct.pack(self.payload_format, *self.__dict__.values()) + ready_values = [] + for value in self.__dict__.values(): + if isinstance(value, Enum): + ready_values.append( + ( + value.value + if not isinstance(value.value, str) + else value.value.encode() + ), + ) + elif isinstance(value, str): + ready_values.append(value.encode()) + else: + ready_values.append(value) + payload = struct.pack(self.payload_format, *ready_values) data = struct.pack( f" None: - self.answer_topic.publish(Float32(data=packet.result)) - self.next_packet.set() + if isinstance(packet, AnswerPacket): + self.answer_one_topic.publish(Float32(data=packet.result)) + self.next_packet.set() + elif isinstance(packet, EnumPacket): + self.answer_two_topic.publish(Float32(data=packet.number.value)) if __name__ == "__main__": diff --git a/mil_common/drivers/electrical_protocol/test/test_simulated_basic.py b/mil_common/drivers/electrical_protocol/test/test_simulated_basic.py index c722cd420..0151bde82 100755 --- a/mil_common/drivers/electrical_protocol/test/test_simulated_basic.py +++ b/mil_common/drivers/electrical_protocol/test/test_simulated_basic.py @@ -4,6 +4,7 @@ import pty import unittest from dataclasses import dataclass +from enum import Enum, IntEnum import rospy import rostest @@ -12,6 +13,18 @@ from std_srvs.srv import Empty +class CalculatorMode(IntEnum): + ADD = 0 + SUB = 1 + MUL = 2 + + +class Sign(Enum): + PLUS = "+" + MINUS = "-" + MULTIPLY = "*" + + @dataclass class RequestAddPacket(Packet, class_id=0x37, subclass_id=0x00, payload_format="