From 2adcf31dcda2c643413901fc9c267c7355eb5435 Mon Sep 17 00:00:00 2001 From: Adam Shapiro Date: Wed, 5 Jun 2024 13:14:20 -0400 Subject: [PATCH 01/13] Renamed SocketType to UNIXSocketType for clarity. --- .../fusion_engine/messages/configuration.h | 29 ++++++++++--------- 1 file changed, 15 insertions(+), 14 deletions(-) diff --git a/src/point_one/fusion_engine/messages/configuration.h b/src/point_one/fusion_engine/messages/configuration.h index c25077bce..424cb70aa 100644 --- a/src/point_one/fusion_engine/messages/configuration.h +++ b/src/point_one/fusion_engine/messages/configuration.h @@ -1598,9 +1598,9 @@ enum class InterfaceConfigType : uint8_t { * Valid for: * - @ref TransportType::UNIX * - * Payload format: @ref SocketType + * Payload format: @ref UNIXSocketType */ - SOCKET_TYPE = 7, + UNIX_SOCKET_TYPE = 7, }; /** @@ -1634,8 +1634,8 @@ P1_CONSTEXPR_FUNC const char* to_string(InterfaceConfigType type) { case InterfaceConfigType::DIRECTION: return "Transport Direction"; - case InterfaceConfigType::SOCKET_TYPE: - return "Socket Type"; + case InterfaceConfigType::UNIX_SOCKET_TYPE: + return "UNIX Socket Type"; default: return "Unrecognized Configuration"; @@ -1764,7 +1764,7 @@ enum class TransportType : uint8_t { * * For a UNIX domain socket, you must specify: * - The @ref TransportDirection (client or server) - * - The @ref SocketType (streaming, datagram, or sequenced) + * - The @ref UNIXSocketType (streaming, datagram, or sequenced) * - The path to a socket file to connect to (client) or create (server) */ UNIX = 8, @@ -1866,7 +1866,7 @@ inline p1_ostream& operator<<(p1_ostream& stream, TransportDirection val) { * sockets. * @ingroup io_interfaces */ -enum class SocketType : uint8_t { +enum class UNIXSocketType : uint8_t { INVALID = 0, /** * Operate in connection-oriented streaming mode and do not preserve message @@ -1886,32 +1886,33 @@ enum class SocketType : uint8_t { }; /** - * @brief Get a human-friendly string name for the specified @ref SocketType. + * @brief Get a human-friendly string name for the specified @ref + * UNIXSocketType. * @ingroup io_interfaces * * @param val The enum to get the string name for. * * @return The corresponding string name. */ -P1_CONSTEXPR_FUNC const char* to_string(SocketType val) { +P1_CONSTEXPR_FUNC const char* to_string(UNIXSocketType val) { switch (val) { - case SocketType::INVALID: + case UNIXSocketType::INVALID: return "INVALID"; - case SocketType::STREAM: + case UNIXSocketType::STREAM: return "STREAM"; - case SocketType::DATAGRAM: + case UNIXSocketType::DATAGRAM: return "DATAGRAM"; - case SocketType::SEQPACKET: + case UNIXSocketType::SEQPACKET: return "SEQPACKET"; } return "Unrecognized"; } /** - * @brief @ref SocketType stream operator. + * @brief @ref UNIXSocketType stream operator. * @ingroup io_interfaces */ -inline p1_ostream& operator<<(p1_ostream& stream, SocketType val) { +inline p1_ostream& operator<<(p1_ostream& stream, UNIXSocketType val) { stream << to_string(val) << " (" << (int)val << ")"; return stream; } From 7831522299d2282be580a662b4f8c4d7e71074c3 Mon Sep 17 00:00:00 2001 From: Adam Shapiro Date: Wed, 5 Jun 2024 13:19:14 -0400 Subject: [PATCH 02/13] Added InterfaceConfigType::ALL_PARAMETERS option for bulk configuration. --- .../fusion_engine/messages/configuration.h | 67 +++++++++++++++++++ 1 file changed, 67 insertions(+) diff --git a/src/point_one/fusion_engine/messages/configuration.h b/src/point_one/fusion_engine/messages/configuration.h index 424cb70aa..6ca1eef34 100644 --- a/src/point_one/fusion_engine/messages/configuration.h +++ b/src/point_one/fusion_engine/messages/configuration.h @@ -1601,6 +1601,18 @@ enum class InterfaceConfigType : uint8_t { * Payload format: @ref UNIXSocketType */ UNIX_SOCKET_TYPE = 7, + + /** + * Configure all settings for the specified interface/transport type. + * + * Payload format depends on the @ref TransportType%: + * - @ref TransportType::SERIAL - @ref SerialConfig + * - @ref TransportType::TCP - @ref TCPConfig + * - @ref TransportType::UDP - @ref UDPConfig + * - @ref TransportType::WEBSOCKET - @ref WebsocketConfig + * - @ref TransportType::UNIX - @ref UNIXSocketConfig + */ + ALL_PARAMETERS = 8, }; /** @@ -1637,6 +1649,9 @@ P1_CONSTEXPR_FUNC const char* to_string(InterfaceConfigType type) { case InterfaceConfigType::UNIX_SOCKET_TYPE: return "UNIX Socket Type"; + case InterfaceConfigType::ALL_PARAMETERS: + return "All Parameters"; + default: return "Unrecognized Configuration"; } @@ -2218,6 +2233,58 @@ inline p1_ostream& operator<<(p1_ostream& stream, MessageRate val) { return stream; } +/** + * @param TCP client/server interface configuration parameters. + * @ingroup io_interfaces + */ +struct P1_ALIGNAS(4) TCPConfig { + TransportDirection direction = TransportDirection::SERVER; + uint8_t reserved[1] = {0}; + uint16_t port = 0; + char remote_address[64] = {0}; +}; + +/** + * @param UDP interface configuration parameters. + * @ingroup io_interfaces + */ +struct P1_ALIGNAS(4) UDPConfig { + uint8_t reserved[2] = {0}; + uint16_t port = 0; + char remote_address[64] = {0}; +}; + +/** + * @param WebSocket client/server interface configuration parameters. + * @ingroup io_interfaces + */ +struct P1_ALIGNAS(4) WebsocketConfig { + TransportDirection direction = TransportDirection::SERVER; + uint8_t reserved[1] = {0}; + uint16_t port = 0; + char remote_address[64] = {0}; +}; + +/** + * @param UNIX domain socket client/server interface configuration parameters. + * @ingroup io_interfaces + */ +struct P1_ALIGNAS(4) UNIXSocketConfig { + TransportDirection direction = TransportDirection::SERVER; + UNIXSocketType socket_type = UNIXSocketType::STREAM; + uint8_t reserved[2] = {0}; + char path[64] = {0}; +}; + +/** + * @param Serial port (UART) interface configuration parameters. + * @ingroup io_interfaces + */ +struct P1_ALIGNAS(4) SerialConfig { + uint32_t baud_rate = 0; + char device_path[64] = {0}; +}; + /** * @brief I/O interface parameter configuration submessage (used when sending * a @ref SetConfigMessage or @ref GetConfigMessage for @ref From e9dea0e1046f6978a8d65f5582b7db3b2da984cc Mon Sep 17 00:00:00 2001 From: Adam Shapiro Date: Tue, 25 Jun 2024 10:42:23 -0400 Subject: [PATCH 03/13] Added enabled bool to all transport config structs. --- src/point_one/fusion_engine/messages/configuration.h | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/src/point_one/fusion_engine/messages/configuration.h b/src/point_one/fusion_engine/messages/configuration.h index 6ca1eef34..1941830a9 100644 --- a/src/point_one/fusion_engine/messages/configuration.h +++ b/src/point_one/fusion_engine/messages/configuration.h @@ -2238,8 +2238,8 @@ inline p1_ostream& operator<<(p1_ostream& stream, MessageRate val) { * @ingroup io_interfaces */ struct P1_ALIGNAS(4) TCPConfig { + uint8_t enabled = 1; TransportDirection direction = TransportDirection::SERVER; - uint8_t reserved[1] = {0}; uint16_t port = 0; char remote_address[64] = {0}; }; @@ -2249,7 +2249,8 @@ struct P1_ALIGNAS(4) TCPConfig { * @ingroup io_interfaces */ struct P1_ALIGNAS(4) UDPConfig { - uint8_t reserved[2] = {0}; + uint8_t enabled = 1; + uint8_t reserved[1] = {0}; uint16_t port = 0; char remote_address[64] = {0}; }; @@ -2259,8 +2260,8 @@ struct P1_ALIGNAS(4) UDPConfig { * @ingroup io_interfaces */ struct P1_ALIGNAS(4) WebsocketConfig { + uint8_t enabled = 1; TransportDirection direction = TransportDirection::SERVER; - uint8_t reserved[1] = {0}; uint16_t port = 0; char remote_address[64] = {0}; }; @@ -2270,9 +2271,10 @@ struct P1_ALIGNAS(4) WebsocketConfig { * @ingroup io_interfaces */ struct P1_ALIGNAS(4) UNIXSocketConfig { + uint8_t enabled = 1; TransportDirection direction = TransportDirection::SERVER; UNIXSocketType socket_type = UNIXSocketType::STREAM; - uint8_t reserved[2] = {0}; + uint8_t reserved[1] = {0}; char path[64] = {0}; }; @@ -2281,6 +2283,8 @@ struct P1_ALIGNAS(4) UNIXSocketConfig { * @ingroup io_interfaces */ struct P1_ALIGNAS(4) SerialConfig { + uint8_t enabled = 1; + uint8_t reserved[3] = {0}; uint32_t baud_rate = 0; char device_path[64] = {0}; }; From b84ec979f2d817a6006071fabcad8a7231e7ede8 Mon Sep 17 00:00:00 2001 From: Adam Shapiro Date: Tue, 25 Jun 2024 10:43:50 -0400 Subject: [PATCH 04/13] Minor review cleanup. --- python/fusion_engine_client/messages/configuration.py | 2 +- src/point_one/fusion_engine/messages/configuration.h | 3 ++- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/python/fusion_engine_client/messages/configuration.py b/python/fusion_engine_client/messages/configuration.py index 99432b5cc..94541dea2 100644 --- a/python/fusion_engine_client/messages/configuration.py +++ b/python/fusion_engine_client/messages/configuration.py @@ -320,7 +320,7 @@ def GetType(cls) -> ConfigType: class InterfaceConfigClass(ConfigClass): """! - @brief Abstract base class for accessing configuration types. + @brief Abstract base class for accessing I/O interface configuration types. """ @classmethod def GetType(cls) -> ConfigType: diff --git a/src/point_one/fusion_engine/messages/configuration.h b/src/point_one/fusion_engine/messages/configuration.h index 1941830a9..401e06ccd 100644 --- a/src/point_one/fusion_engine/messages/configuration.h +++ b/src/point_one/fusion_engine/messages/configuration.h @@ -1603,7 +1603,8 @@ enum class InterfaceConfigType : uint8_t { UNIX_SOCKET_TYPE = 7, /** - * Configure all settings for the specified interface/transport type. + * Configure all settings for the specified interface/transport type in a + * single operation. * * Payload format depends on the @ref TransportType%: * - @ref TransportType::SERIAL - @ref SerialConfig From bb6ac2c84ce3c839c4d9dde534d29cbe286d56f9 Mon Sep 17 00:00:00 2001 From: Adam Shapiro Date: Tue, 25 Jun 2024 11:46:47 -0400 Subject: [PATCH 05/13] Fixed Python encoding for TransportDirection and SocketType values. --- python/fusion_engine_client/messages/configuration.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/python/fusion_engine_client/messages/configuration.py b/python/fusion_engine_client/messages/configuration.py index 94541dea2..d782732b5 100644 --- a/python/fusion_engine_client/messages/configuration.py +++ b/python/fusion_engine_client/messages/configuration.py @@ -275,7 +275,7 @@ def get_message_type_string(protocol: ProtocolType, message_id: int): def _define_enum_config_classes(enum_type, construct_type=Int8ul): class EnumVal(NamedTuple): value: enum_type = list(enum_type)[0] - construct = AutoEnum(construct_type, enum_type) + construct = Struct("value" / AutoEnum(construct_type, enum_type)) return EnumVal, construct From bbf4ab5584aba8130e105f660752bd5559754c3f Mon Sep 17 00:00:00 2001 From: Adam Shapiro Date: Tue, 25 Jun 2024 11:47:41 -0400 Subject: [PATCH 06/13] Added example sending TCP transport direction SetConfig request in Python. --- python/examples/send_command.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/python/examples/send_command.py b/python/examples/send_command.py index c97f6f26f..e31fff795 100755 --- a/python/examples/send_command.py +++ b/python/examples/send_command.py @@ -68,6 +68,8 @@ # protocol=ProtocolType.FUSION_ENGINE, # message_id=MessageType.POSE, # rate=MessageRate.ON_CHANGE) + # message = SetConfigMessage(InterfaceDirectionConfig(TransportDirection.SERVER), + # interface=InterfaceID(TransportType.TCP, 0)) # message = FaultControlMessage(payload=FaultControlMessage.EnableGNSS(False)) # Connect to the device. From 407b9a4ccbc51861bb696d6f51a2648ac6b58b4f Mon Sep 17 00:00:00 2001 From: Adam Shapiro Date: Tue, 25 Jun 2024 11:48:19 -0400 Subject: [PATCH 07/13] Allow interface config mappings for specific transport types. --- .../messages/configuration.py | 46 +++++++++++-------- 1 file changed, 27 insertions(+), 19 deletions(-) diff --git a/python/fusion_engine_client/messages/configuration.py b/python/fusion_engine_client/messages/configuration.py index d782732b5..2ef8ff3f0 100644 --- a/python/fusion_engine_client/messages/configuration.py +++ b/python/fusion_engine_client/messages/configuration.py @@ -170,6 +170,19 @@ class TransportType(IntEnum): ALL = 255 +class InterfaceID(NamedTuple): + type: TransportType = TransportType.INVALID + index: int = 0 + + +_InterfaceIDConstructRaw = Struct( + "type" / AutoEnum(Int8ul, TransportType), + "index" / Int8ul, + Padding(2) +) +_InterfaceIDConstruct = NamedTupleAdapter(InterfaceID, _InterfaceIDConstructRaw) + + class TransportDirection(IntEnum): INVALID = 0 SERVER = 1 @@ -355,7 +368,7 @@ def GetType(cls) -> ConfigType: return InnerClass return inner - def create_interface_config_class(self, config_subtype, construct_class): + def create_interface_config_class(self, config_subtype, construct_class, transport_type: TransportType = None): """! @brief Decorator for generating InterfaceConfigClass children. @@ -370,11 +383,19 @@ def GetSubtype(cls) -> InterfaceConfigType: InnerClass.__name__ = config_class.__name__ # Register the construct with the MessageType. - self.INTERFACE_CONFIG_MAP[config_subtype] = NamedTupleAdapter(InnerClass, construct_class) + self.INTERFACE_CONFIG_MAP[(transport_type, config_subtype)] = NamedTupleAdapter(InnerClass, construct_class) return InnerClass return inner + def find_interface_config_construct(self, interface: InterfaceID, config_subtype: InterfaceConfigType): + construct_obj = _conf_gen.INTERFACE_CONFIG_MAP.get((interface.type, config_subtype), None) + if construct_obj is None: + construct_obj = _conf_gen.INTERFACE_CONFIG_MAP.get((None, config_subtype), None) + if construct_obj is None: + raise KeyError(f'No interface config mapping found for {interface}, config type {config_subtype}.') + return construct_obj + class Point3F(NamedTuple): """! @brief 3D coordinate specifier, stored as 32-bit float values. @@ -992,19 +1013,6 @@ class InvalidConfig(_conf_gen.Empty): pass -class InterfaceID(NamedTuple): - type: TransportType = TransportType.INVALID - index: int = 0 - - -_InterfaceIDConstructRaw = Struct( - "type" / AutoEnum(Int8ul, TransportType), - "index" / Int8ul, - Padding(2) -) -_InterfaceIDConstruct = NamedTupleAdapter(InterfaceID, _InterfaceIDConstructRaw) - - class InterfaceConfigSubmessage(NamedTuple): interface: InterfaceID = InterfaceID() subtype: InterfaceConfigType = InterfaceConfigType.INVALID @@ -1093,7 +1101,7 @@ def pack(self, buffer: Optional[bytes] = None, offset: int = 0, return_buffer: b if submessage: data = _InterfaceConfigSubmessageConstruct.build(submessage) - construct_obj = _conf_gen.INTERFACE_CONFIG_MAP[submessage.subtype] + construct_obj = _conf_gen.find_interface_config_construct(self.interface, submessage.subtype) else: data = bytes() construct_obj = _conf_gen.CONFIG_MAP[config_type] @@ -1120,7 +1128,7 @@ def unpack(self, buffer: bytes, offset: int = 0, message_version: int = MessageP interface_header = _InterfaceConfigSubmessageConstruct.parse(header_data) subtype = interface_header.subtype self.interface = interface_header.interface - construct_obj = _conf_gen.INTERFACE_CONFIG_MAP[subtype] + construct_obj = _conf_gen.find_interface_config_construct(self.interface, subtype) else: construct_obj = _conf_gen.CONFIG_MAP[parsed.config_type] @@ -1351,7 +1359,7 @@ def pack(self, buffer: bytes = None, offset: int = 0, return_buffer: bool = True if submessage: data = _InterfaceConfigSubmessageConstruct.build(submessage) - construct_obj = _conf_gen.INTERFACE_CONFIG_MAP[submessage.subtype] + construct_obj = _conf_gen.find_interface_config_construct(self.interface, submessage.subtype) else: data = bytes() construct_obj = _conf_gen.CONFIG_MAP[config_type] @@ -1381,7 +1389,7 @@ def unpack(self, buffer: bytes, offset: int = 0, message_version: int = MessageP interface_header = _InterfaceConfigSubmessageConstruct.parse(header_data) subtype = interface_header.subtype self.interface = interface_header.interface - construct_obj = _conf_gen.INTERFACE_CONFIG_MAP[subtype] + construct_obj = _conf_gen.find_interface_config_construct(self.interface, subtype) else: self.interface = None construct_obj = _conf_gen.CONFIG_MAP[parsed.config_type] From 754ad24c596b315d63f7c93d68e2390d087f83e3 Mon Sep 17 00:00:00 2001 From: Adam Shapiro Date: Tue, 25 Jun 2024 13:34:31 -0400 Subject: [PATCH 08/13] Fixed doxygen typo. --- src/point_one/fusion_engine/messages/configuration.h | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/point_one/fusion_engine/messages/configuration.h b/src/point_one/fusion_engine/messages/configuration.h index 401e06ccd..f8e89719d 100644 --- a/src/point_one/fusion_engine/messages/configuration.h +++ b/src/point_one/fusion_engine/messages/configuration.h @@ -2235,7 +2235,7 @@ inline p1_ostream& operator<<(p1_ostream& stream, MessageRate val) { } /** - * @param TCP client/server interface configuration parameters. + * @brief TCP client/server interface configuration parameters. * @ingroup io_interfaces */ struct P1_ALIGNAS(4) TCPConfig { @@ -2246,7 +2246,7 @@ struct P1_ALIGNAS(4) TCPConfig { }; /** - * @param UDP interface configuration parameters. + * @brief UDP interface configuration parameters. * @ingroup io_interfaces */ struct P1_ALIGNAS(4) UDPConfig { @@ -2257,7 +2257,7 @@ struct P1_ALIGNAS(4) UDPConfig { }; /** - * @param WebSocket client/server interface configuration parameters. + * @brief WebSocket client/server interface configuration parameters. * @ingroup io_interfaces */ struct P1_ALIGNAS(4) WebsocketConfig { @@ -2268,7 +2268,7 @@ struct P1_ALIGNAS(4) WebsocketConfig { }; /** - * @param UNIX domain socket client/server interface configuration parameters. + * @brief UNIX domain socket client/server interface configuration parameters. * @ingroup io_interfaces */ struct P1_ALIGNAS(4) UNIXSocketConfig { @@ -2280,7 +2280,7 @@ struct P1_ALIGNAS(4) UNIXSocketConfig { }; /** - * @param Serial port (UART) interface configuration parameters. + * @brief Serial port (UART) interface configuration parameters. * @ingroup io_interfaces */ struct P1_ALIGNAS(4) SerialConfig { From 469cc580cb0c879c8f30f0c29b436a6791cd93a7 Mon Sep 17 00:00:00 2001 From: Adam Shapiro Date: Tue, 25 Jun 2024 13:34:41 -0400 Subject: [PATCH 09/13] Renamed serial device_path to path. --- src/point_one/fusion_engine/messages/configuration.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/point_one/fusion_engine/messages/configuration.h b/src/point_one/fusion_engine/messages/configuration.h index f8e89719d..87c9e6aa6 100644 --- a/src/point_one/fusion_engine/messages/configuration.h +++ b/src/point_one/fusion_engine/messages/configuration.h @@ -2287,7 +2287,7 @@ struct P1_ALIGNAS(4) SerialConfig { uint8_t enabled = 1; uint8_t reserved[3] = {0}; uint32_t baud_rate = 0; - char device_path[64] = {0}; + char path[64] = {0}; }; /** From bed95f1971f34c168518474d3b918599a9685af9 Mon Sep 17 00:00:00 2001 From: Adam Shapiro Date: Tue, 25 Jun 2024 13:34:54 -0400 Subject: [PATCH 10/13] Added InterfaceConfigType::PATH alias. --- python/fusion_engine_client/messages/configuration.py | 1 + src/point_one/fusion_engine/messages/configuration.h | 10 +++++++--- 2 files changed, 8 insertions(+), 3 deletions(-) diff --git a/python/fusion_engine_client/messages/configuration.py b/python/fusion_engine_client/messages/configuration.py index 2ef8ff3f0..d4772ddf9 100644 --- a/python/fusion_engine_client/messages/configuration.py +++ b/python/fusion_engine_client/messages/configuration.py @@ -53,6 +53,7 @@ class InterfaceConfigType(IntEnum): OUTPUT_DIAGNOSTICS_MESSAGES = 1 BAUD_RATE = 2 REMOTE_ADDRESS = 3 + PATH = 3 # Alias for REMOTE_ADDRESS PORT = 4 ENABLED = 5 DIRECTION = 6 diff --git a/src/point_one/fusion_engine/messages/configuration.h b/src/point_one/fusion_engine/messages/configuration.h index 87c9e6aa6..80abb1278 100644 --- a/src/point_one/fusion_engine/messages/configuration.h +++ b/src/point_one/fusion_engine/messages/configuration.h @@ -1545,12 +1545,14 @@ enum class InterfaceConfigType : uint8_t { BAUD_RATE = 2, /** - * Configure the network address for a client to connect to. + * Configure the network address for a client to connect to, or the path to a + * local file. * - * For UNIX domain sockets, this string represents the path to the local - * socket file. + * For UNIX domain sockets and serial ports, this string represents the path + * to the local socket or device file. * * Valid for: + * - @ref TransportType::SERIAL * - @ref TransportType::TCP * - @ref TransportType::UDP * - @ref TransportType::UNIX @@ -1558,6 +1560,8 @@ enum class InterfaceConfigType : uint8_t { * Payload format: `char[64]` containing a NULL terminated string. */ REMOTE_ADDRESS = 3, + /** Alias for `REMOTE_ADDRESS`. */ + PATH = 3, /** * Configure the network port. From 511ae8ad9c98243b21dc3164c7ec2622bd41b994 Mon Sep 17 00:00:00 2001 From: Adam Shapiro Date: Tue, 25 Jun 2024 15:16:01 -0400 Subject: [PATCH 11/13] Allow interface argumetn for GetConfigMessage, similar to SetConfigMessage. --- python/fusion_engine_client/messages/configuration.py | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/python/fusion_engine_client/messages/configuration.py b/python/fusion_engine_client/messages/configuration.py index d4772ddf9..239a72397 100644 --- a/python/fusion_engine_client/messages/configuration.py +++ b/python/fusion_engine_client/messages/configuration.py @@ -1187,7 +1187,9 @@ def __validate_interface_header(self): def __init__(self, config_type: Union[ConfigType, _ConfigClassGenerator.ConfigClass] = ConfigType.INVALID, - request_source: ConfigurationSource = ConfigurationSource.ACTIVE, interface_header: Optional[InterfaceConfigSubmessage]=None): + request_source: ConfigurationSource = ConfigurationSource.ACTIVE, + interface: Optional[InterfaceID] = None, + interface_header: Optional[InterfaceConfigSubmessage] = None): self.request_source = request_source if isinstance(config_type, ConfigType): @@ -1195,6 +1197,11 @@ def __init__(self, else: self.config_type = config_type.GetType() + if interface_header is None and interface is not None: + if issubclass(config_type, _ConfigClassGenerator.InterfaceConfigClass): + interface_header = InterfaceConfigSubmessage(interface=interface, subtype=config_type.GetSubtype()) + else: + raise ValueError('Interface configuration subtype not specified. Cannot construct header.') self.interface_header = interface_header self.__validate_interface_header() From 3067ff2b2a9903e86843548e3e37602dcfaf3ac3 Mon Sep 17 00:00:00 2001 From: Adam Shapiro Date: Tue, 25 Jun 2024 15:15:04 -0400 Subject: [PATCH 12/13] Added Python descriptions for using set/get config messages. --- python/examples/send_command.py | 4 +- .../messages/configuration.py | 64 ++++++++++++++++--- 2 files changed, 59 insertions(+), 9 deletions(-) diff --git a/python/examples/send_command.py b/python/examples/send_command.py index e31fff795..375051059 100755 --- a/python/examples/send_command.py +++ b/python/examples/send_command.py @@ -68,7 +68,9 @@ # protocol=ProtocolType.FUSION_ENGINE, # message_id=MessageType.POSE, # rate=MessageRate.ON_CHANGE) - # message = SetConfigMessage(InterfaceDirectionConfig(TransportDirection.SERVER), + # message = SetConfigMessage(InterfaceDiagnosticMessagesEnabled(True), + # interface=InterfaceID(TransportType.TCP, 0)) + # message = GetConfigMessage(InterfaceDiagnosticMessagesEnabled, # interface=InterfaceID(TransportType.TCP, 0)) # message = FaultControlMessage(payload=FaultControlMessage.EnableGNSS(False)) diff --git a/python/fusion_engine_client/messages/configuration.py b/python/fusion_engine_client/messages/configuration.py index 239a72397..ba93e1392 100644 --- a/python/fusion_engine_client/messages/configuration.py +++ b/python/fusion_engine_client/messages/configuration.py @@ -753,6 +753,35 @@ class Empty(NamedTuple): _conf_gen = _ConfigClassGenerator() +######################################################################################################################## +# Device configuration settings (lever arms, orientation, wheel speed settings, etc.). +# +# The classes below may be passed to a SetConfigMessage or returned by a ConfigResponseMessage using the `config_object` +# field. For example: +# ``` +# SetConfigMessage(GNSSLeverArmConfig(0.4, 0.0, 1.2)) +# SetConfigMessage(EnabledGNSSSystemsConfig(SatelliteType.GPS, SatelliteType.GALILEO)) +# +# GetConfigMessage(GNSSLeverArmConfig) +# config_response.config_object.x == 0.4 +# ``` +# +# Note that many of these configuration classes share common parameters, and their fields are defined by their specified +# base classes. For example, `GNSSLeverArmConfig` inherits from `Point3F` and contains `x`, `y`, and `z` fields as +# follows: +# ``` +# class Point3F(NamedTuple): +# """! +# @brief 3D coordinate specifier, stored as 32-bit float values. +# """ +# x: float = math.nan +# y: float = math.nan +# z: float = math.nan +# class GNSSLeverArmConfig(_conf_gen.Point3F): ... +# ``` +######################################################################################################################## + + @_conf_gen.create_config_class(ConfigType.DEVICE_LEVER_ARM, _conf_gen.Point3FConstruct) class DeviceLeverArmConfig(_conf_gen.Point3F): """! @@ -950,6 +979,33 @@ class HardwareTickConfig(_conf_gen.HardwareTickConfig): pass +@_conf_gen.create_config_class(ConfigType.INVALID, _conf_gen.EmptyConstruct) +class InvalidConfig(_conf_gen.Empty): + """! + @brief Placeholder for empty invalid configuration messages. + """ + pass + + +######################################################################################################################## +# Input/output interface controls. +# +# When configuring I/O interfaces, you must specify the desired interface: +# +# Examples: +# ``` +# SetConfigMessage( +# InterfaceDiagnosticMessagesEnabled(True), +# interface=InterfaceID(TransportType.TCP, 0)) +# +# GetConfigMessage( +# InterfaceDiagnosticMessagesEnabled, +# interface=InterfaceID(TransportType.TCP, 0)) +# config_response.config_object.value == True +# ``` +######################################################################################################################## + + @_conf_gen.create_interface_config_class(InterfaceConfigType.BAUD_RATE, _conf_gen.UInt32Construct) class InterfaceBaudRateConfig(_conf_gen.IntegerVal): """! @@ -1006,14 +1062,6 @@ class InterfaceDiagnosticMessagesEnabled(_conf_gen.BoolVal): pass -@_conf_gen.create_config_class(ConfigType.INVALID, _conf_gen.EmptyConstruct) -class InvalidConfig(_conf_gen.Empty): - """! - @brief Placeholder for empty invalid configuration messages. - """ - pass - - class InterfaceConfigSubmessage(NamedTuple): interface: InterfaceID = InterfaceID() subtype: InterfaceConfigType = InterfaceConfigType.INVALID From c08304b15d980894698f1ce6554b34c76ce2fdd4 Mon Sep 17 00:00:00 2001 From: Adam Shapiro Date: Tue, 25 Jun 2024 15:16:36 -0400 Subject: [PATCH 13/13] Added Python InterfaceConfigType.ALL_PARAMETERS support. --- python/examples/send_command.py | 3 + .../messages/configuration.py | 103 ++++++++++++++++++ 2 files changed, 106 insertions(+) diff --git a/python/examples/send_command.py b/python/examples/send_command.py index 375051059..ef7a57873 100755 --- a/python/examples/send_command.py +++ b/python/examples/send_command.py @@ -72,6 +72,9 @@ # interface=InterfaceID(TransportType.TCP, 0)) # message = GetConfigMessage(InterfaceDiagnosticMessagesEnabled, # interface=InterfaceID(TransportType.TCP, 0)) + # message = SetConfigMessage( + # TCPConfig(direction=TransportDirection.CLIENT, remote_address='remote-hostname', port=1234), + # interface=InterfaceID(TransportType.TCP, 1)) # message = FaultControlMessage(payload=FaultControlMessage.EnableGNSS(False)) # Connect to the device. diff --git a/python/fusion_engine_client/messages/configuration.py b/python/fusion_engine_client/messages/configuration.py index ba93e1392..4c9222504 100644 --- a/python/fusion_engine_client/messages/configuration.py +++ b/python/fusion_engine_client/messages/configuration.py @@ -58,6 +58,7 @@ class InterfaceConfigType(IntEnum): ENABLED = 5 DIRECTION = 6 SOCKET_TYPE = 7 + ALL_PARAMETERS = 8 class Direction(IntEnum): @@ -997,6 +998,9 @@ class InvalidConfig(_conf_gen.Empty): # SetConfigMessage( # InterfaceDiagnosticMessagesEnabled(True), # interface=InterfaceID(TransportType.TCP, 0)) +# SetConfigMessage( +# TCPConfig(direction=TransportDirection.CLIENT, remote_address='remote-hostname', port=1234), +# interface=InterfaceID(TransportType.TCP, 1)) # # GetConfigMessage( # InterfaceDiagnosticMessagesEnabled, @@ -1062,6 +1066,105 @@ class InterfaceDiagnosticMessagesEnabled(_conf_gen.BoolVal): pass +_TCPConfigConstruct = Struct( + "enabled" / Flag, + "direction" / AutoEnum(Int8ul, TransportDirection), + "port"/ Int16ul, + "remote_address" / PaddedString(64, 'utf8'), +) + + +@_conf_gen.create_interface_config_class(InterfaceConfigType.ALL_PARAMETERS, _TCPConfigConstruct, + transport_type=TransportType.TCP) +class TCPConfig(NamedTuple): + """! + @brief TCP client/server configuration settings. + """ + enabled: bool = True + direction: TransportDirection = TransportDirection.SERVER + port: int = 0 + remote_address: str = '' + + +_UDPConfigConstruct = Struct( + "enabled" / Flag, + Padding(1), + "port"/ Int16ul, + "remote_address" / PaddedString(64, 'utf8'), +) + + +@_conf_gen.create_interface_config_class(InterfaceConfigType.ALL_PARAMETERS, _UDPConfigConstruct, + transport_type=TransportType.UDP) +class UDPConfig(NamedTuple): + """! + @brief UDP interface configuration settings. + """ + enabled: bool = True + port: int = 0 + remote_address: str = '' + + +_WebsocketConfigConstruct = Struct( + "enabled" / Flag, + "direction" / AutoEnum(Int8ul, TransportDirection), + "port"/ Int16ul, + "remote_address" / PaddedString(64, 'utf8'), +) + + +@_conf_gen.create_interface_config_class(InterfaceConfigType.ALL_PARAMETERS, _WebsocketConfigConstruct, + transport_type=TransportType.WEBSOCKET) +class WebsocketConfig(NamedTuple): + """! + @brief WebSocket client/server configuration settings. + """ + enabled: bool = True + direction: TransportDirection = TransportDirection.SERVER + port: int = 0 + remote_address: str = '' + + +_UNIXSocketConfigConstruct = Struct( + "enabled" / Flag, + "direction" / AutoEnum(Int8ul, TransportDirection), + "socket_type" / AutoEnum(Int8ul, SocketType), + Padding(1), + "path" / PaddedString(64, 'utf8'), +) + + +@_conf_gen.create_interface_config_class(InterfaceConfigType.ALL_PARAMETERS, _UNIXSocketConfigConstruct, + transport_type=TransportType.UNIX) +class UNIXSocketConfig(NamedTuple): + """! + @brief UNIX domain socket client/server configuration settings. + """ + enabled: bool = True + direction: TransportDirection = TransportDirection.SERVER + socket_type: SocketType = SocketType.STREAM + path: str = '' + + +_SerialConfigConstruct = Struct( + "enabled" / Flag, + Padding(3), + "baud_rate" / Int32ul, + "path" / PaddedString(64, 'utf8'), +) + + +@_conf_gen.create_interface_config_class(InterfaceConfigType.ALL_PARAMETERS, _SerialConfigConstruct, + transport_type=TransportType.SERIAL) +class SerialConfig(NamedTuple): + """! + @brief Serial port (UART) configuration settings. + """ + enabled: bool = True + baud_rate: int = 0 + path: str = '' + + class InterfaceConfigSubmessage(NamedTuple): interface: InterfaceID = InterfaceID() subtype: InterfaceConfigType = InterfaceConfigType.INVALID