-
Notifications
You must be signed in to change notification settings - Fork 26
Hardware Status comments #66
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -45,7 +45,7 @@ string hardware_id # unique per‐instance, e.g. "left_wheel/driver" | |
|
|
||
| # ——— Health & Error —————————————————————————————————————————————— | ||
| uint8 health_status # see HealthStatus enum | ||
| uint8 error_domain # see ErrorDomain enum | ||
| uint8[] error_domain # Array of device errors, because hardware can throw more than one, see ErrorDomain enum | ||
|
|
||
| # ——— Operational State ——————————————————————————————————————————— | ||
| uint8 operational_mode # see ModeStatus enum | ||
|
|
@@ -74,47 +74,75 @@ uint8 HEALTH_UNKNOWN=0 | |
| uint8 HEALTH_OK =1 | ||
| uint8 HEALTH_DEGRADED=2 | ||
| uint8 HEALTH_WARNING =3 | ||
| # Hardware stops publishing state when it returns ERROR/FATAL, how are these set/updated? | ||
| uint8 HEALTH_ERROR =4 | ||
| uint8 HEALTH_FATAL =5 | ||
|
|
||
| # Error category | ||
| uint8 ERROR_NONE =0 | ||
| uint8 ERROR_UNKNOWN =1 | ||
| uint8 ERROR_HW =2 | ||
| uint8 ERROR_FW =3 | ||
| uint8 ERROR_COMM =4 | ||
| uint8 ERROR_POWER =5 | ||
| uint8 ERROR_HW # generic hardware fault/error | ||
| uint8 ERROR_SW # generic software fault/error | ||
| uint8 ERROR_OVER_TRAVEL # Hardware stopped motion because position is over limits | ||
|
|
||
| # Hardware/Software status | ||
| uint8 EMERGENCY_STOP_HW # state of the emergency stop hardware (i.e. e-stop button state) | ||
| uint8 EMERGENCY_STOP_SW # state of the emergency stop software system (over travel, pinch point) | ||
| uint8 PROTECTIVE_STOP_HW # state of the protective stop hardware (i.e. safety field state) | ||
| uint8 PROTECTIVE_STOP_SW # state of the software protective stop | ||
| # Some protective stop errors need to be acknowledged before the hardware can reactivate | ||
| # see https://docs.universal-robots.com/Universal_Robots_ROS2_Documentation/doc/ur_robot_driver/ur_robot_driver/doc/dashboard_client.html#unlock-protective-stop-std-srvs-trigger | ||
| uint8 SAFETY_STOP | ||
| # Some hardware requires calibration on startup (for example a linear rail or quadruped) | ||
| unit8 CALIBRATION_REQUIRED | ||
|
|
||
|
|
||
| # Mode of operation | ||
| uint8 MODE_UNKNOWN =0 | ||
| uint8 MODE_MANUAL =1 | ||
| uint8 MODE_AUTONOMOUS =2 | ||
| uint8 MODE_SAFE =3 | ||
| uint8 MODE_AUTO =2 # automatic mode when the driver is remote controlling the hardware | ||
| uint8 MODE_SAFE =3 # what is the expected use case for this mode? | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. the idea was that when a safety sensor is touched on the robot, and it has to halt operation, this is what would be reported, in hindsight could've been named better |
||
| uint8 MODE_MAINTENANCE=4 | ||
| uint8 MODE_JOG_MANUAL | ||
| uint8 MODE_ADMITTANCE | ||
| uint8 MODE_MONITORED_STOP | ||
| uint8 MODE_HOLD_TO_RUN | ||
| unit8 MODE_CARTESIAN_TWIST | ||
| unit8 MODE_CARTESIAN_POSE | ||
| uint8 MODE_TRAJECTORY_FORWARDING | ||
| uint8 MODE_TRAJECTORY_STREAMING | ||
|
|
||
| # Power states | ||
| uint8 POWER_UNKNOWN =0 | ||
| uint8 POWER_OFF =1 | ||
| uint8 POWER_STANDBY =2 | ||
| uint8 POWER_ON =3 | ||
| uint8 POWER_SLEEP =4 | ||
| uint8 POWER_ERROR =5 | ||
| # Battery power states see [BatteryState.msg](https://docs.ros2.org/foxy/api/sensor_msgs/msg/BatteryState.html) | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. opinion on directly having that message here? goes back to the discussion in the meet, should we directly plop in messages from elsewhere or create our version of them. just a thought |
||
| uint8 POWER_LEVEL_LOW | ||
| uint8 POWER_LEVEL_CRITICAL | ||
| uint8 POWER_CHARGING | ||
| uint8 POWER_CHARGING_ERROR | ||
|
|
||
| # Connectivity | ||
| uint8 CONNECT_UNKNOWN =0 | ||
| uint8 CONNECT_UP =1 | ||
| uint8 CONNECT_DOWN =2 | ||
| uint8 CONNECT_FAILURE =3 | ||
| uint8 CONNECTION_SLOW # to tell the controlling system it is struggling to communicate at rate | ||
| ``` | ||
|
|
||
| #### 3.2. A Note on a Future Addition | ||
|
|
||
| A potential limitation of the single-value enums above is that a component can only report one state per category at a time. Consider the `error_domain`: what happens if a hardware fault (`ERROR_HW`) immediately causes a communication failure (`ERROR_COMM`)? With the current design, the hardware driver must choose to (or is limited to) report only one. | ||
| That or return an array of errors and let mission control sort out the correct action to recover. | ||
|
|
||
| A potential solution for this in a future iteration would be to define some enums as **bitfields**. This would involve assigning values as powers of 2, allowing multiple states to be combined using a bitwise `OR` operation. | ||
|
|
||
| For example, the `ErrorDomain` enum could be redefined as a bitmask: | ||
| ``` | ||
| # Example ErrorDomain as a bitfield | ||
| # Example ErrorDomain as a bitfield (why only an 8 bit number?) | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. no other reason than that everything else was also uint8, maybe here specifically we could go higher? |
||
| uint8 ERROR_NONE = 0 # 0b00000000 | ||
| uint8 ERROR_HW = 1 # 0b00000001 | ||
| uint8 ERROR_FW = 2 # 0b00000010 | ||
|
|
@@ -158,3 +186,52 @@ KeyValue[] entries # diagnostic_msgs/KeyValue[] | |
| 5. And the main questions that I have, Is this whole approach overly complicated, let's avoid that pitfall. | ||
|
|
||
| Looking forward to hearing what everyone thinks! | ||
|
|
||
| ## Hardware Status Interface | ||
| What does configuring the Hardware Status (per hardware because a mobile_base is likely different than the arm mounted on top of it) look like? | ||
| Should we have blocks of state (i.e. standardized messages) that can be added together if the hardware offers X, Y and Z features? | ||
| (For example my robot arm has a `safety interface` for e-stop/p-stop and a `hardware_status` interface to report power, operating mode and ...) | ||
| What does it look like at the interface level? Is there a separate read (and maybe write) method for status reporting and reconfiguration? | ||
| For example standard safety status (E-stop, P-stop), operating mode, [battery state](https://docs.ros2.org/foxy/api/sensor_msgs/msg/BatteryState.html). | ||
|
|
||
| JointState has been the standard ROS2 control works with. What about GPIO, SafetyStatus, BatteryState, .... these are interfaces that hardware frequently provides. | ||
| What if ros2_control made a set of messages to standardize it's interfaces for each subcategory? | ||
| [SensorMsgs](https://docs.ros2.org/foxy/api/sensor_msgs/index-msg.html) is a start of what we need. | ||
| For example the UR controller exposes lots of interfaces via [GPIO](https://github.com/UniversalRobots/Universal_Robots_ROS2_Description/blob/85d2ad8d1526ee6c0f21dca94e1e697c83706b71/urdf/ur.ros2_control.xacro#L294-L311) but not in a standardized way so if someone wanted to control it and then switch robots their codebase would likely need to change to handle auxiliary control and monitoring. | ||
|
|
||
| Some errors or states will be set as the hardware stops functioning. | ||
| Should the status broadcaster hold and continue to publish last known state? | ||
| Should the status broadcaster offer statistics on hardware DEACTIVATE/ERROR and ACTIVATIONS? | ||
| Lots of industrial applications would like to know how many e-stops, number of controller errors/faults, ____ per shift, week or some period of time | ||
| Could this open the option for custom or standard controllers to monitor and keep the system healthy? i.e. automatic arm fault reset controller, | ||
|
|
||
| Links of hardware interfaces and their attempt to convey hardware status and support other control modes | ||
|
|
||
| ### UR | ||
| [hardware_interface](https://github.com/UniversalRobots/Universal_Robots_ROS2_Driver/blob/868f240bc8578ebfa1d19b94f8a6a1ad62fa0bd1/ur_robot_driver/src/hardware_interface.cpp#L266-L270) | ||
| [SafetyMode.msg](https://github.com/UniversalRobots/Universal_Robots_ROS2_Driver/blob/main/ur_dashboard_msgs/msg/SafetyMode.msg) | ||
| [RobotMode.msg](https://github.com/UniversalRobots/Universal_Robots_ROS2_Driver/blob/main/ur_dashboard_msgs/msg/RobotMode.msg) | ||
| [control.xacro](https://github.com/UniversalRobots/Universal_Robots_ROS2_Description/blob/85d2ad8d1526ee6c0f21dca94e1e697c83706b71/urdf/ur.ros2_control.xacro#L294-L311) | ||
|
|
||
| ### Kuka | ||
| [hardware_interface](https://github.com/lbr-stack/lbr_fri_ros2_stack/blob/f2784b86e5975eddc9b5eab901baaca329306653/lbr_ros2_control/include/lbr_ros2_control/system_interface_type_values.hpp#L8-L27) | ||
|
|
||
| ### Kinova | ||
| [fault_reset controller](https://github.com/Kinovarobotics/ros2_kortex/blob/main/kortex_description/arms/gen3/7dof/config/ros2_controllers.yaml#L17-L18) to report and reset faults. | ||
| [twist_controller](https://github.com/Kinovarobotics/ros2_kortex/blob/309f9c9d4a277970e542e5ac1fe260ced0630f65/kortex_description/arms/gen3/7dof/config/ros2_controllers.yaml#L11-L12) | ||
|
|
||
| ### Dynamixel | ||
| [hardware_interface](https://github.com/ROBOTIS-GIT/dynamixel_hardware_interface/blob/02841dd2ae422676e5dc0fea37057bdec3be8cc1/include/dynamixel_hardware_interface/dynamixel_hardware_interface.hpp#L53-L91) | ||
|
|
||
| ### Robotiq | ||
| [hardware_interface](https://github.com/PickNikRobotics/ros2_robotiq_gripper/blob/12e623212e6891a5fcc9af94d67b07e640916394/robotiq_driver/include/robotiq_driver/driver.hpp#L41-L66) | ||
| [acrivation_controller](https://github.com/PickNikRobotics/ros2_robotiq_gripper/blob/main/robotiq_controllers/src/robotiq_activation_controller.cpp) | ||
|
|
||
| ### Ethercat | ||
| [hardware_interface](https://github.com/ICube-Robotics/ethercat_driver_ros2/blob/52be2c2ed163bab25d46c402ddb4e7216c0a0ec3/ethercat_generic_plugins/ethercat_generic_cia402_drive/include/ethercat_generic_plugins/cia402_common_defs.hpp#L31-L56) | ||
|
|
||
| ### ROS2 canopen driver | ||
| https://github.com/ros-industrial/ros2_canopen/tree/master | ||
|
|
||
| ### Picknik Twist & Fault controllers | ||
| https://github.com/PickNikRobotics/picknik_controllers | ||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@MarqRazz I'm still getting together my ideas in a different one. How about something like this?
saikishor@db470af
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I really like the idea of using
diagnostic_msgs/KeyValuebut unless there are some standardizedkeysthen we won't have an agnostic framework like we do with JointState. We also have the issue that everyone would be required to convert thevaluefrom string to ___ type.GPIO in ros2_control is also not standardized and completely free form other than the value is always a double (see my comments on UR's setup). Users are allowed to name the state and command interfaces anything they want which means any code downstream is specific to the hardware_interface they implemented it against and would require changes if they switched or wanted to support multiple robot brands (even though both brands offer digital IO through their hardware_interface). Now I don't think we can come up with some format that can meet all use cases for every user but do believe we could add some base standards here that could make users code more modular and hardware agnostic.