Skip to content

Structure of hardware_interfaces#10

Closed
destogl wants to merge 34 commits intoros-controls:masterfrom
destogl:ros2_hardware_interface_design_proposal
Closed

Structure of hardware_interfaces#10
destogl wants to merge 34 commits intoros-controls:masterfrom
destogl:ros2_hardware_interface_design_proposal

Conversation

@destogl
Copy link
Copy Markdown
Member

@destogl destogl commented Mar 25, 2020

Next steps

Open issues / discussion points

  1. The naming convention for classes. Proposal:
    • RobotHardware
    • SensorHardware
    • ActuatorHardware
  2. How to abstract possibilities properly to read/write data for all sensors/actuators at once and for only one of them.
    Example: industrial robot expects to read/write all data at once (RobotHardware should do this); a sensor attached to it can be read separately (SensorHardware should do this).
  3. How to manage interfaces toward controllers? Do we use the same approach as in ROS1, or should this be based on flexible joint state message?
  4. Why is in ROS1 Time parameter in read/write functions?
  5. Does the controller key-approach is sensible to protect the actuator from multiple access or the controller's name is sufficient?
  6. Does RobotHardware communicate in a separate thread with a physical hardware?

@destogl destogl changed the title Start working on proposal for hardware_interfaces Structure of hardware_interfaces Mar 25, 2020
@bmagyar
Copy link
Copy Markdown
Member

bmagyar commented Mar 25, 2020

  1. Good proposals but let's keep thinking, if you were to mention a class named ActuatorHardware or SensorHardware to someone who doesn't know ros_control, would they get the gist of it after a brief intro?

  2. We could define a mechanism of sharing communications between a collection of XYHardware by creating it and registering them into it. This of course would need to be very specific. MyCompanyEthercatGripperA, MyCompanyEthercatGripperB, MyCompanyEthercatArm could be registered into MyCompanyEthercatComms. How to handle these comms is a new question.

  3. Should aim to use flexibe joint state but if that doesn't play out nicely we can define the old-fashioned C++ interfaces to interface to flexible joint state.

  4. Querying WallTime is not realtime safe. This is where you can inject time from any realtime backend framework you are using.

  5. Not decided on this yet...

  6. We should define the ros2_control framework to leave this optional for RobotHardware developers.

@mikepurvis
Copy link
Copy Markdown

Definitely excited to see the CombinedRobotHW-like functionality becoming a first-class citizen, and the separate-but-similar use cases of "one or more manipulators on a mobile base" and "one or more independent actuators/sensors comprising a robot" both receiving consideration.

My other point of interest is around sharing resources between instances, which @bmagyar alludes to above. The ideal scenario for this kind of thing is where any needed multiplexing happens at the OS layer— eg, multiple processes can open a socketcan device and it all just magically works. But this is very much not the reality for many systems, especially when you have a single connection (serial, a socket, whatever) bridging into a separate system with multiple devices where those devices are variable and you'd like to handle them with separate instances of xHardware classes.

The specific case of this that I was describing on the call last week is with systems which are accessible over register-based protocols. There are several systems like this in the industrial world (modbus, ethercat, profinet, canopen, etc) and it would be nice to be able to supply a suite of classes which permit plugging a ModbusHardware or ProfinetHardware (which would expose named registers) into a GenericRegisterActuatorHardware, where you tell it which named registers are its command and feedback, with the appropriate scaling factors.

@gavanderhoorn
Copy link
Copy Markdown

gavanderhoorn commented Apr 2, 2020

where you tell it which named registers are its command and feedback, with the appropriate scaling factors.

This strongly reminds me of how ros_canopen works.

Especially the "chain" and motor nodes (ie: canopen_chain_node). Conversion from registers to ROS and back is done (for 'simple' devices) using expressions you configure in a .yaml configuration file. See also canopen_motor_node (especially the unit conversions and Configuration section).


Edit: btw, this sounds like the typical opaque proxy vs transparent bridge design discussion.

@destogl
Copy link
Copy Markdown
Member Author

destogl commented Apr 8, 2020

Hi all,

in this second iteration I managed to solve the following points:

Nr. 2 - there is a separation between internal structures and HWInterfaces. Internal structures hold a reference to them and they are initialized on run-time.

Nr. 3 - we go then with FlexibleJointStateMessage (or how it is called in the future.

Nr. 6 - see comment to Nr. 2 - the robot developers are now free :)

Note on the implementation: we should do some "handle"-stuff to provide access between internal structures and communication, i.e. if a robot uses "batch" communication, we should take care that data come into Sensor/Actuator structures.

@destogl
Copy link
Copy Markdown
Member Author

destogl commented Apr 8, 2020

comment on Nr.1.

should we use word "Joint" instead of "Actuator".Because almost every actuator has a possibility to know (read) its own state. Only problem in semantics is when one has e.g., a drilling machine on the TCP, because it is not actually a joint.

@olivier-stasse
Copy link
Copy Markdown
Contributor

olivier-stasse commented Apr 27, 2020

Dear @destogl , the SVG diagram is very nice.
I have a couple of questions/remarks:

  1. Below the ComponentHWInteface there is an ActorHWInterface did you mean ActuatorHWInterface ?
  2. What is the difference between Component and BaseComponent ? From your comment, BaseComponent is an Abstract class and Component a template ?
  3. IMHO Actuator is preferable to Joint which has a strong meaning in mechanics. We should consider the fact than an actuator may have a micro controller, its own internal bus, and complex way of interacting with sensors.
  4. Not widely needed, but in my field I see more and more the need to have multiple core control architecture. But this make only sense if we can describe at least describe the number of CPUs. I do not think this is a main stream problem. But for complex robots (factory cells), distributed robotics for instance, providing this information for the complex control architecture proposed by @Karsten1987 this would make sense. It could derive from BaseComponent/Component and its interface from ComponentHWInterface I guess.
  5. @Karsten1987 used Hardware instead of HW in its implementation. I found it more simple and straightforward to understand, but heavier to write.
  6. It would be very important to show that one can still come with a simple implementation to avoid making people go away from ros_control.

@destogl
Copy link
Copy Markdown
Member Author

destogl commented Apr 28, 2020

Hi @olivier-stasse,

Thank you for your comments! Here the answers:

  1. Yes, I meant actuator interface.
  2. The BaseComponent is extended by Robot class to able to define its interface without separate interfaces for Sensors and Actuators. For example, KUKA robot which use "batch" communication for the whole robot and not separated channels for each actuator. -- We have to think one more time about this part, it is somehow blurry to me now....
  3. Thanks! I also prefer that (but the ros users are used to joints...)
  4. We could extend this. Can you propose an extension? What would it be? Try to start from Component.
  5. I can use Hardware thanks for info.
  6. I believe we can achieve that, especially after all experience with ROS1-control

Copy link
Copy Markdown
Contributor

@Karsten1987 Karsten1987 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for the design doc. I like the overall Motivation and the composition of an abstract robot instance with various actuators and sensors.

I got a bit lost with the three packages you want to introduce. Are these mainly interface classes or abstract base classes for predefined hardware components? It wasn't really clear to me what each user has to implement per robot. Basically, I wasn't sure what you mean with class, whether it's an interface the user has to implement or a library providing functionality.
I guess it would be great to have another SVG which depicts a smaller, less complex setup. Maybe a single off-the-shelf robot.

ros2_control_components:

  • I got a bit confused with what exactly a BaseComponent entails. Is that a common base interface which Sensor and Actuator inherit from? If so, what common functionality do you see in that BaseComponent?
  • The Robot interface makes a lot of sense from what you've described. However, I couldn't find that pattern in your SVG. In your example, I would have expected that there are two Robot implementations (i.e. Kuka and Schunk) and a third implementation which only holds two references to Kuka and Schunk. A recursive relationship so to say.

ros2_control_hardware_interface:

  • Given the comments above, can you elaborate once more what's the difference between the hardware interfaces and the component class?

### Robot Hardware

A robot is logically represented with the `RobotHardware` class.
This structure has at least one sensor and one actuator, but it generally represents any composition of `RobotHardware`, `SensorHardware`, and `ActuatorHardware` structures.
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why does it have at least one sensor and one actuator? What if I have "blind" robot structure, where I can solely control some motors without reading their states?

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Also, how are motors with encoders treated here? Do they count as one SensorHardware and one ActuatorHardware?

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is a good point. I am not sure if we can assume that any Actuator knows its state. Or do we need something like IntelligentActuator (not very good name) which is Sensor and Actutator in one structure.

@destogl
Copy link
Copy Markdown
Member Author

destogl commented May 5, 2020

I got a bit lost with the three packages you want to introduce. Are these mainly interface classes or abstract base classes for predefined hardware components? It wasn't really clear to me what each user has to implement per robot. Basically, I wasn't sure what you mean with class, whether it's an interface the user has to implement or a library providing functionality.

The white blocks would be interfaces and colored ones implementation. One could use colored one directly as they are. If your interfaces are implemented, you have to implement only the HardwareCommunicationInterface everything else would be composed of existing interfaces. I will try to elaborate this more clearly in an example.

Basicaly a user should implement only HardwareCommunicationInterface and if the type of the actuator is not provided than also that. I will draw a flow-chart with the process.

I guess it would be great to have another SVG which depicts a smaller, less complex setup. Maybe a single off-the-shelf robot.

I will do this.

I made reduced version of the chart. I hope this makes everything clearer.

* I got a bit confused with what exactly a `BaseComponent` entails. Is that a common base interface which `Sensor` and `Actuator` inherit from? If so, what common functionality do you see in that `BaseComponent`?

BaseComponent was a way to abstract the Sensor, Actuator and Robot to have the same base class. The reason behind it is that the Robot in general does not have value_identifiers but its sensors and actuators

* The `Robot` interface makes a lot of sense from what you've described. However, I couldn't find that pattern in your SVG. In your example, I would have expected that there are two `Robot` implementations (i.e. `Kuka` and `Schunk`) and a third implementation which only holds two references to `Kuka` and `Schunk`. A recursive relationship so to say.

Robot is in ros2_control_components package just under Sensor and Actuator class.
The point is that one do not have to have a Schunk or Kuka Robot implementations as long as you have your hardware interfaces done properly.

The order of inheritance is as follows:
BaseComponent --> Component --> Sensor/Actuator
BaseComponent --> Robot

So, the BaseComponent is the most abstract interface of all classes in ros2_control_components package. It enables unified interface toward ComponentHardwareInterface and the main reason for this is to support loading the HardwareInterfaces for each Sensor and Actuator in a robot separately and also as one object (i.e., RobotHardwareInterface.

Also, it helps to have clear split of Sensor/Actuator internals compared to Robot internal. Concrete: a Sensor and Actuator classes have ValueIdentifier type of variables and Robot does not have (they are hold in its sensors and actuators).

* Given the comments above, can you elaborate once more what's the difference between the hardware interfaces and the component class?

hardware_interface would be really an interface to the hardware. It implements all the hardware logic. hardware_components class provides software models of the robotic components. This models then be used flexibly, and they do not have to be changed at all. Without this abstraction I am not sure we can manage flexibility we want to have. I did this kind of work for Force-Torque sensors in ROS1. So I am able to reuse all the logic and just exchange ForceTorqueSensorHW implementation when using another hardware.

destogl and others added 9 commits May 5, 2020 18:09
Co-authored-by: Karsten Knese <Karsten1987@users.noreply.github.com>
Co-authored-by: Karsten Knese <Karsten1987@users.noreply.github.com>
Co-authored-by: Karsten Knese <Karsten1987@users.noreply.github.com>
Co-authored-by: Karsten Knese <Karsten1987@users.noreply.github.com>
Co-authored-by: Karsten Knese <Karsten1987@users.noreply.github.com>
Co-authored-by: Karsten Knese <Karsten1987@users.noreply.github.com>
Co-authored-by: Karsten Knese <Karsten1987@users.noreply.github.com>
Co-authored-by: Karsten Knese <Karsten1987@users.noreply.github.com>
@destogl
Copy link
Copy Markdown
Member Author

destogl commented May 5, 2020

Expect the simplification of the diagram I got one further idea. We could put core components, i.e. interfaces into ros2_control_core since these components will depend on each other anyway...

I marked those in violet in the simplified class diagram.

ROS2 Control - Class Diagram Proposal ros2_control_core

@bmagyar
Copy link
Copy Markdown
Member

bmagyar commented May 20, 2020

@destogl @Karsten1987 is this ready for merging? Could we get it in before the PR with code drops?

@destogl
Copy link
Copy Markdown
Member Author

destogl commented May 20, 2020

@bmagyar: I will do one more review until this friday. There are still some typos in graphics.

@destogl
Copy link
Copy Markdown
Member Author

destogl commented May 22, 2020

I updated the diagrams. The description still needs to be updated. I will do it today or latest tomorrow.

This is now ready for review.
@destogl
Copy link
Copy Markdown
Member Author

destogl commented Jun 17, 2020

This description should be reviewed and revised according to current developments in ros-controls/ros2_control#101 and the project.

@destogl destogl self-assigned this Jun 17, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

6 participants