diff --git a/README.md b/README.md index 8501a15..b3430e5 100644 --- a/README.md +++ b/README.md @@ -1,12 +1,13 @@ # RoShip Interfaces -ROS2 interface definitions for marine robotic systems. This package provides standardized message types for hydraulic control and propulsion systems commonly found on ROVs (Remotely Operated Vehicles) and other underwater and autonomous ocean platforms. +ROS2 interface definitions for marine robotic systems. This package provides standardized message types for hydraulic control, propulsion, and I/O systems commonly found on ROVs (Remotely Operated Vehicles) and other underwater and autonomous ocean platforms. ## Overview RoShip (Robotic Ship) is a collection of standards and supporting software packages for operating robotic systems in marine environments. This interface package contains message definitions organized into domain-specific sub-packages: - **[hydraulic_interfaces](hydraulic_interfaces/README.md)** - Messages for hydraulic valve control systems +- **[io_interfaces](io_interfaces/README.md)** - Messages and services for analog outputs, digital outputs, relay control, raw sensor data, and channel triggering - **[propulsion_interfaces](propulsion_interfaces/README.md)** - Messages for thruster and propulsion systems ## Design Philosophy @@ -41,6 +42,19 @@ roship_interfaces/ │ │ └── ValvePack.msg │ ├── CMakeLists.txt │ └── package.xml +├── io_interfaces/ +│ ├── msg/ +│ │ ├── RawAnalog.msg +│ │ ├── RawAnalogArray.msg +│ │ ├── RawAnalogStamped.msg +│ │ ├── RawDigital.msg +│ │ ├── RawDigitalArray.msg +│ │ ├── RawDigitalStamped.msg +│ │ └── RawPacket.msg +│ ├── srv/ +│ │ └── ChannelTrigger.srv +│ ├── CMakeLists.txt +│ └── package.xml ├── propulsion_interfaces/ │ ├── msg/ │ │ ├── Thrust.msg diff --git a/io_interfaces/CMakeLists.txt b/io_interfaces/CMakeLists.txt new file mode 100644 index 0000000..dfee7dc --- /dev/null +++ b/io_interfaces/CMakeLists.txt @@ -0,0 +1,29 @@ +cmake_minimum_required(VERSION 3.8) + +project(io_interfaces) + +find_package(ament_cmake REQUIRED) +find_package(rosidl_default_generators REQUIRED) +find_package(std_msgs REQUIRED) + +set(MSG_FILES + "msg/RawPacket.msg" + "msg/RawAnalog.msg" + "msg/RawAnalogArray.msg" + "msg/RawAnalogStamped.msg" + "msg/RawDigital.msg" + "msg/RawDigitalArray.msg" + "msg/RawDigitalStamped.msg") + +set(SRV_FILES + "srv/ChannelTrigger.srv") + +rosidl_generate_interfaces(${PROJECT_NAME} + ${MSG_FILES} + ${SRV_FILES} + DEPENDENCIES + std_msgs) + +ament_export_dependencies(rosidl_default_runtime) + +ament_package() diff --git a/io_interfaces/README.md b/io_interfaces/README.md new file mode 100644 index 0000000..a346145 --- /dev/null +++ b/io_interfaces/README.md @@ -0,0 +1,161 @@ +# IO Interfaces + +ROS2 message definitions for raw input/output device control. This package provides standardized interfaces for analog outputs, digital outputs, relay control, and raw binary sensor data commonly used in marine robotic platforms. + +## Message Types + +### RawAnalog.msg +Core message representing a single analog output channel with proportional and scaled voltage/current control. + +``` +int32 channel_id # Analog channel identifier (may be indexed from 0, 1, or use hardware-specific IDs) + +uint8 type # Output type +uint8 TYPE_VOLTAGE=0 +uint8 TYPE_CURRENT=1 + +float32 scale # Scale factor: voltage = proportional_value * scale + # Set to 0.0 if scale is unknown +float32 proportional_value # Control value from -1.0 to 1.0 +``` + +### RawAnalogArray.msg +Array of analog channel commands with a common timestamp for devices such as DAC boards. The array may address any subset of channels — only the channels included in the message are affected. + +``` +std_msgs/Header header +RawAnalog[] analogs +``` + +**Usage:** Command one or more analog channels in a single message without needing to address the entire board. + +### RawAnalogStamped.msg +Time-stamped single analog channel command published on a per-output per-topic basis. + +``` +std_msgs/Header header +RawAnalog analog +``` + +**Usage:** Command a single analog output without constructing a full array. Useful when multiple independent nodes need to control individual channels on the same device — each node publishes to its own topic without needing awareness of the other channels. + +--- + +### RawDigital.msg +Core message representing a single digital output (DIO) or relay channel. + +``` +int32 channel_id # Digital channel identifier (may be indexed from 0, 1, or use hardware-specific IDs) + +bool state # Commanded output state + # True = HIGH / energized / closed (relay) + # False = LOW / de-energized / open (relay) +``` + +### RawDigitalArray.msg +Array of digital channel commands with a common timestamp for devices such as relay boards or DIO boards. The array may address any subset of channels — only the channels included in the message are affected. + +``` +std_msgs/Header header +RawDigital[] digitals +``` + +**Usage:** Command one or more digital channels in a single message without needing to address the entire board. + +### RawDigitalStamped.msg +Time-stamped single digital channel command published on a per-output per-topic basis. + +``` +std_msgs/Header header +RawDigital digital +``` + +**Usage:** Command a single digital output without constructing a full array. Useful when multiple independent nodes need to control individual channels on the same device — each node publishes to its own topic without needing awareness of the other channels. + +--- + +### RawPacket.msg +Raw binary data packet received directly from a sensor or device, published one topic per sensor. + +``` +std_msgs/Header header # stamp corresponds to the time the message was generated or decoded +byte[] data # Raw binary payload +``` + +**Usage:** Publish unprocessed binary data from hardware devices. Since each sensor publishes on its own dedicated topic, the source and data format are implicit from the topic name. + +--- + +## Service Types + +### ChannelTrigger.srv +Service for triggering a single channel by ID. Returns a success flag and optional message. + +``` +# Request +int32 channel_id # Channel identifier to trigger + +--- + +# Response +bool success # True if the channel was triggered successfully +string message # Human-readable result or error description +``` + +**Usage:** Send a one-shot trigger command to a specific channel. Suitable for relay pulse operations or any channel-based action that requires acknowledgement. + +--- + +## Design Philosophy + +- **Hardware Agnostic**: Normalized values and boolean states work across different device types and manufacturers +- **Flexible Indexing**: `channel_id` fields accommodate various indexing schemes (0-based, 1-based, hardware-specific) +- **Array Messages for Boards**: Array messages address any subset of channels on a multi-output device (relay board, DAC board) in a single timestamped message — only the included channels are affected +- **Stamped Messages for Individual Control**: Stamped messages allow multiple independent nodes to each control a single channel on a shared device without coordinating with other nodes +- **One Topic Per Device**: `RawPacket` is published per sensor per topic, keeping source and format implicit in the topic name rather than the message + +## Usage + +### Publishing Digital Commands + +```python +from io_interfaces.msg import RawDigitalArray, RawDigital + +# Create digital array message +msg = RawDigitalArray() +msg.header.stamp = self.get_clock().now().to_msg() +msg.header.frame_id = 'relay_panel' + +# Command two relay channels +relay1 = RawDigital() +relay1.channel_id = 1 +relay1.state = True # Energize / close + +relay2 = RawDigital() +relay2.channel_id = 2 +relay2.state = False # De-energize / open + +msg.digitals = [relay1, relay2] +publisher.publish(msg) +``` + +### Publishing Analog Commands + +```python +from io_interfaces.msg import RawAnalogStamped, RawAnalog + +msg = RawAnalogStamped() +msg.header.stamp = self.get_clock().now().to_msg() +msg.header.frame_id = 'analog_output_0' + +msg.analog.channel_id = 0 +msg.analog.type = RawAnalog.TYPE_VOLTAGE +msg.analog.scale = 10.0 # 10V full scale +msg.analog.proportional_value = 0.5 # 5V output + +publisher.publish(msg) +``` + +## Part of RoShip Interfaces + +This package is part of the [RoShip Interfaces](../README.md) collection for marine robotic systems. diff --git a/io_interfaces/msg/RawAnalog.msg b/io_interfaces/msg/RawAnalog.msg new file mode 100644 index 0000000..dcb70af --- /dev/null +++ b/io_interfaces/msg/RawAnalog.msg @@ -0,0 +1,22 @@ +# The RawAnalog message represents both a proportional and +# an absolute thrust value +# Voltage shall be computed as follows: +# float voltage = proportional_value * scale + +# ID of the analog channel. analogs may be indexed from one, zero, or randomly selected. +int32 channel_id + +uint8 type +uint8 TYPE_VOLTAGE=0 +uint8 TYPE_CURRENT=1 + +# A scale factor that, when multiplied by the proportional_value, yields +# the electic potential in volts. If this value is not known the scale shall +# be set to 0.0. This will produce a valid voltage of 0.0 if no checking is +# implemented in software but still allows to us +float32 scale + +## A value from -1.0 to 1.0 representing the proportional value of an analog value +float32 proportional_value + + diff --git a/relay_interfaces/msg/RelayStamped.msg b/io_interfaces/msg/RawAnalogArray.msg similarity index 51% rename from relay_interfaces/msg/RelayStamped.msg rename to io_interfaces/msg/RawAnalogArray.msg index 0abec5b..406f24e 100644 --- a/relay_interfaces/msg/RelayStamped.msg +++ b/io_interfaces/msg/RawAnalogArray.msg @@ -1,2 +1,3 @@ std_msgs/Header header -Relay relay + +RawAnalog[] analogs diff --git a/io_interfaces/msg/RawAnalogStamped.msg b/io_interfaces/msg/RawAnalogStamped.msg new file mode 100644 index 0000000..d750709 --- /dev/null +++ b/io_interfaces/msg/RawAnalogStamped.msg @@ -0,0 +1,3 @@ +std_msgs/Header header + +RawAnalog analog diff --git a/io_interfaces/msg/RawDigital.msg b/io_interfaces/msg/RawDigital.msg new file mode 100644 index 0000000..d6d0981 --- /dev/null +++ b/io_interfaces/msg/RawDigital.msg @@ -0,0 +1,10 @@ +# The RawDigital message represents a single digital output (DIO) or relay channel. +# The output state is expressed as a boolean on/off value. + +# ID of the digital channel. channels may be indexed from one, zero, or randomly selected. +int32 channel_id + +# The commanded state of the digital output. +# True = HIGH / energized / closed (relay) +# False = LOW / de-energized / open (relay) +bool state diff --git a/io_interfaces/msg/RawDigitalArray.msg b/io_interfaces/msg/RawDigitalArray.msg new file mode 100644 index 0000000..c5d1980 --- /dev/null +++ b/io_interfaces/msg/RawDigitalArray.msg @@ -0,0 +1,3 @@ +std_msgs/Header header + +RawDigital[] digitals diff --git a/io_interfaces/msg/RawDigitalStamped.msg b/io_interfaces/msg/RawDigitalStamped.msg new file mode 100644 index 0000000..1ae28f3 --- /dev/null +++ b/io_interfaces/msg/RawDigitalStamped.msg @@ -0,0 +1,3 @@ +std_msgs/Header header + +RawDigital digital diff --git a/io_interfaces/msg/RawPacket.msg b/io_interfaces/msg/RawPacket.msg new file mode 100644 index 0000000..07674e5 --- /dev/null +++ b/io_interfaces/msg/RawPacket.msg @@ -0,0 +1,3 @@ +std_msgs/Header header #stamp corresponds to the time the message was generated or decoded + +byte[] data diff --git a/relay_interfaces/package.xml b/io_interfaces/package.xml similarity index 82% rename from relay_interfaces/package.xml rename to io_interfaces/package.xml index 814646e..7ed4a53 100644 --- a/relay_interfaces/package.xml +++ b/io_interfaces/package.xml @@ -1,15 +1,15 @@ - relay_interfaces + io_interfaces 1.0.0 - RoShip relay interface definitions + RoShip io interface definitions Kristopher Krasnosky Apache 2.0 ament_cmake - rosidl_default_generators + rosidl_default_generators std_msgs diff --git a/io_interfaces/srv/ChannelTrigger.srv b/io_interfaces/srv/ChannelTrigger.srv new file mode 100644 index 0000000..f627cfd --- /dev/null +++ b/io_interfaces/srv/ChannelTrigger.srv @@ -0,0 +1,6 @@ +# Request +int32 channel_id +--- +# Response +bool success +string message diff --git a/propulsion_interfaces/README.md b/propulsion_interfaces/README.md index 3a92337..169d6c5 100644 --- a/propulsion_interfaces/README.md +++ b/propulsion_interfaces/README.md @@ -1,40 +1,39 @@ # Propulsion Interfaces -ROS2 message definitions for thruster and propulsion control systems. This package provides messages that support both proportional control and calibrated thrust commands for underwater and surface vehicles. +ROS2 message definitions for thruster and propulsion control systems. This package provides standardized interfaces for proportional and calibrated thrust commands for underwater and surface vehicles. ## Message Types ### Thrust.msg -Core message representing thruster command with dual representation: -- **Proportional control**: Normalized value from `-1.0` to `1.0` -- **Calibrated thrust**: Optional `scale` factor (N per unit) allows commanded thrust in Newtons -- **Uncalibrated mode**: `scale == 0.0` convention indicates uncalibrated thruster +Core message representing a single thruster command with proportional and optional calibrated thrust values. ``` -float32 scale # Thrust scale factor (N per unit proportional_value) - # Set to 0.0 if uncalibrated -float32 proportional_value # Normalized control value from -1.0 to 1.0 +int32 thruster_id # Thruster identifier (may be indexed from 0, 1, or use hardware-specific IDs) + +float32 scale # Scale factor: thrust_N = proportional_value * scale + # Set to 0.0 if uncalibrated +float32 proportional_value # Control value from -1.0 to 1.0 ``` -### ThrustStamped.msg -Time-stamped single thruster command for control loops requiring precise timing and coordination. +### ThrustArray.msg +Array of thruster commands with a common timestamp for devices such as thruster controllers. The array may address any subset of thrusters — only the thrusters included in the message are affected. ``` std_msgs/Header header -Thrust thrust +Thrust[] thrusts ``` -**Usage:** Command individual thrusters with timing information for control loops. +**Usage:** Command one or more thrusters in a single message without needing to address the entire propulsion system. Well suited for speed controllers or motor controllers with multiple outputs, where all channels are driven from a single device or control loop. -### ThrustArray.msg -Array of thruster commands with common timestamp for complete propulsion system control. Variable-length array supports any thruster configuration. +### ThrustStamped.msg +Time-stamped single thruster command published on a per-thruster per-topic basis. ``` std_msgs/Header header -Thrust[] thrusts +Thrust thrust ``` -**Usage:** Command complete thruster configuration in a single message, ensuring coordinated propulsion control. +**Usage:** Command a single thruster without constructing a full array. Useful when multiple independent nodes need to control individual thrusters — each node publishes to its own topic without needing awareness of the other thrusters. ## Design Philosophy @@ -52,6 +51,7 @@ thrust_N = proportional_value × scale When `scale == 0.0`, the system operates in proportional-only mode. ## Usage + ### Publishing Thrust Commands ```python @@ -62,14 +62,16 @@ msg = ThrustArray() msg.header.stamp = self.get_clock().now().to_msg() msg.header.frame_id = 'base_link' -# Command calibrated thrusters +# Command two calibrated thrusters thrust1 = Thrust() -thrust1.scale = 50.0 # 50 N per unit -thrust1.proportional_value = 0.8 # 40 N forward +thrust1.thruster_id = 1 +thrust1.scale = 50.0 # 50 N full scale +thrust1.proportional_value = 0.8 # 40 N forward thrust2 = Thrust() +thrust2.thruster_id = 2 thrust2.scale = 50.0 -thrust2.proportional_value = -0.6 # 30 N reverse +thrust2.proportional_value = -0.6 # 30 N reverse msg.thrusts = [thrust1, thrust2] publisher.publish(msg) @@ -77,4 +79,4 @@ publisher.publish(msg) ## Part of RoShip Interfaces -This package is part of the [RoShip Interfaces](../README.md) collection for marine robotic systems. +This package is part of the [RoShip Interfaces](../README.md) collection for marine robotic systems. \ No newline at end of file diff --git a/propulsion_interfaces/msg/Thrust.msg b/propulsion_interfaces/msg/Thrust.msg index d98594d..ebcff5f 100644 --- a/propulsion_interfaces/msg/Thrust.msg +++ b/propulsion_interfaces/msg/Thrust.msg @@ -1,16 +1,17 @@ -# The Thrust message represents both a proportional and -# an absolute thrust value +# The Thrust message represents a proportional thruster command with an optional +# absolute thrust value. # Thrust shall be computed as follows: # float thrust = proportional_value * scale +# ID of the thruster. thrusters may be indexed from one, zero, or randomly selected. +int32 thruster_id + # A scale factor that, when multiplied by the proportional_value, yields # the thrust in newtons. If this value is not known the scale shall -# be set to 0.0. This will produce a valid thrust of 0.0 if no checking is -# implemented in software but still allows to user to see if the thruster +# be set to 0.0. This will produce a valid thrust of 0.0 if no checking is +# implemented in software but still allows the user to see if the thruster # is uncalibrated by checking (scale == 0.0) float32 scale -## A value from -1.0 to 1.0 representing the proportional control thruster -float32 proportional_value - - +# A value from -1.0 to 1.0 representing the proportional thruster command +float32 proportional_value \ No newline at end of file diff --git a/relay_interfaces/CMakeLists.txt b/relay_interfaces/CMakeLists.txt deleted file mode 100644 index 8fcf510..0000000 --- a/relay_interfaces/CMakeLists.txt +++ /dev/null @@ -1,21 +0,0 @@ -cmake_minimum_required(VERSION 3.8) - -project(relay_interfaces) - -find_package(ament_cmake REQUIRED) -find_package(rosidl_default_generators REQUIRED) -find_package(std_msgs REQUIRED) - -set(MSG_FILES - "msg/Relay.msg" - "msg/RelayStamped.msg" - "msg/RelayCard.msg") - -rosidl_generate_interfaces(${PROJECT_NAME} - ${MSG_FILES} - DEPENDENCIES - std_msgs) - -ament_export_dependencies(rosidl_default_runtime) - -ament_package() diff --git a/relay_interfaces/README.md b/relay_interfaces/README.md deleted file mode 100644 index fb687e6..0000000 --- a/relay_interfaces/README.md +++ /dev/null @@ -1,93 +0,0 @@ -# Relay Interfaces - -ROS2 message definitions for relay board control systems. This package provides standardized interfaces for binary, proportional, and trip-protected relays commonly used in marine robotic platforms. - -## Message Types - -### Relay.msg - -Core message representing a single relay channel command. - -``` -uint8 node_id # Target node ID (stack position) -int32 channel # Target channel ID - -bool powered # Relay on/off (true = energize, false = de-energize) -float32 setpoint # Setpoint value for proportional relays (0.0 to 1.0) -bool trip_reset # Trip reset (true = reset trip, false = no action) -``` - -### RelayStamped.msg - -Time-stamped single relay command, suitable for control loops requiring precise timing. - -``` -std_msgs/Header header -Relay relay -``` - -**Usage:** Publish individual relay commands with timing information. - -### RelayCard.msg - -Array of relay commands with a common timestamp for synchronized multi-relay control. The variable-length array supports boards with any number of channels. - -``` -std_msgs/Header header -Relay[] relays -``` - -**Usage:** Command multiple relay channels simultaneously with a single synchronized message. - -## Design Philosophy - -- **Hardware Agnostic**: `node_id` + `channel` addressing decouples commands from physical wiring and hardware-specific indexing schemes -- **Multi-board Support**: `node_id` (stack position) allows a single topic to address multiple relay boards on a shared bus -- **Trip Protection**: `trip_reset` is a first-class field, acknowledging that marine relay systems commonly implement overcurrent/fault latching -- **Proportional Support**: `setpoint` accommodates solid-state and proportional relay types alongside standard binary relays - -## Usage - -### Publishing a Single Relay Command (Python) - -```python -from relay_interfaces.msg import RelayStamped, Relay - -msg = RelayStamped() -msg.header.stamp = self.get_clock().now().to_msg() -msg.header.frame_id = 'relay_board' - -msg.relay.node_id = 1 -msg.relay.channel = 3 -msg.relay.powered = True - -publisher.publish(msg) -``` - -### Publishing Multiple Relay Commands (Python) - -```python -from relay_interfaces.msg import RelayCard, Relay - -msg = RelayCard() -msg.header.stamp = self.get_clock().now().to_msg() -msg.header.frame_id = 'relay_board' - -r1 = Relay() -r1.node_id = 1 -r1.channel = 0 -r1.powered = True - -r2 = Relay() -r2.node_id = 1 -r2.channel = 1 -r2.powered = False -r2.trip_reset = True # Reset a latched fault on channel 1 - -msg.relays = [r1, r2] -publisher.publish(msg) -``` - -## Part of RoShip Interfaces - -This package is part of the [RoShip Interfaces](../README.md) collection for marine robotic systems. diff --git a/relay_interfaces/msg/Relay.msg b/relay_interfaces/msg/Relay.msg deleted file mode 100644 index 15584a1..0000000 --- a/relay_interfaces/msg/Relay.msg +++ /dev/null @@ -1,7 +0,0 @@ -uint8 node_id # Target node ID (stack position) -int32 channel # Target channel ID - -bool powered # Relay on/off (true = energize, false = de-energize) -float32 setpoint # Setpoint value for proportional relays (0.0 to 1.0) -bool trip_reset # Trip reset (true = reset trip, false = no action) - diff --git a/relay_interfaces/msg/RelayCard.msg b/relay_interfaces/msg/RelayCard.msg deleted file mode 100644 index f2def8e..0000000 --- a/relay_interfaces/msg/RelayCard.msg +++ /dev/null @@ -1,2 +0,0 @@ -std_msgs/Header header -Relay[] relays # Variable-length array to represent the state of any number of relays