WIP: Implementation of components for controlling robots#101
WIP: Implementation of components for controlling robots#101destogl wants to merge 29 commits intoros-controls:masterfrom
Conversation
hardware_interface/include/hardware_interface/robot_hardware.hpp
Outdated
Show resolved
Hide resolved
| { | ||
| // Classes | ||
| template < typename T > | ||
| class ROS2ControlLoaderPluginlib |
There was a problem hiding this comment.
I'd propose to leave out the plugin loading functionality as for now until we've figured out an API for the components.
There was a problem hiding this comment.
I added loading of Hardware already in Demo repository, and we will need this very soon for Sensors and Actuators.
robot_control_components/include/robot_control_components/sensor.hpp
Outdated
Show resolved
Hide resolved
robot_control_components/include/robot_control_components/sensor.hpp
Outdated
Show resolved
Hide resolved
robot_control_components/include/robot_control_components/simple_component.hpp
Outdated
Show resolved
Hide resolved
olivier-stasse
left a comment
There was a problem hiding this comment.
Dear @destogl thanks again for this second iteration.
As a general feedback, I understand better the framework. Mimizing the dependency to the middleware is for me a great force of ros_control. Making it also in ros2_control would be super nice.
As far as I understood and IMHO the message targeted for the controllers should not be at the level of the Robot class. But their C++ mapping are definitely needed.
Thanks again !
| #include <vector> | ||
|
|
||
| #include "control_msgs/msg/dynamic_joint_state.hpp" | ||
| #include "control_msgs/msg/interface_value.hpp" |
There was a problem hiding this comment.
@destogl I am not sure that we want to put straight at this level the middleware.
In the ROS1 interface the middleware was present only for loading and unloading the controllers not at the robot level.
Right now I do not see the functionnal need to have it here.
IMHO if you want to have a robot compound through a middleware (OpenRTM, Micro-DDS) it should be implemented in another object.
There was a problem hiding this comment.
To precise: dynamic_joint_state and interface_value are a convenient way to communicate with the controllers but to be agnostic they could be map to std::map<> and std::vector<> containers in the C++ space of the robot.
There was a problem hiding this comment.
I agree to do this if there is a use case for it
| #include "control_msgs/msg/dynamic_joint_state.hpp" | ||
| #include "control_msgs/msg/interface_value.hpp" | ||
|
|
||
| #include "rclcpp/macros.hpp" |
There was a problem hiding this comment.
The convenient macros to handle the shared pointers could be exposed to avoid a dependency to rclcpp for this specific object.
| #include "control_msgs/msg/interface_value.hpp" | ||
|
|
||
| #include "rclcpp/macros.hpp" | ||
| #include "rclcpp/rclcpp.hpp" |
There was a problem hiding this comment.
Could you clarify why rclcpp is needed ?
There was a problem hiding this comment.
it will be used for logging.
| { | ||
| //TODO: Add catch | ||
| try { | ||
| ComponentInfo robot_info = parse_robot_from_urdf(urdf_string); |
There was a problem hiding this comment.
I think that this is very nice idea, but maybe not at the right place.
If you asked me few years ago I would be with you on this one, nevertheless always when I separate this I ended up with doubling code, but still using it in ROS... Is anybody using ros_control outside ROS? And what are exactly issues including ROS-main headers? I understand your reasoning and we should clarify this for sure. I am also interesting if there is really a use case where you cannot afford to load a few ROS header (some microcontrollers or something). |
Having small dependencies is always desirable for various reasons. But I guess we have to distinguish here between a strong dependency to something like a |
|
OK, I agree, should we then remove completely dependency to |
|
@Karsten1987 I added interfaces and initial implementations of sensors and actuators. For this simple data, I believe we should make data-management directly in Sensor and Actuator interfaces since it will be shared functionality by many user components. Is this a good direction? Did you have another concept in mind? |
|
I do agree that logging is important for real-time system. For this very reason, some implementation are carefully crafted to meet real-time constraints. My only point is that the object Robot should be as lean as possible, and then derived class, or class matching polymorphic use offers various design patterns. (Thanks for the link @Karsten1987) For more details you can see: |
54165d3 to
aa885a2
Compare
|
in the meeting, I understood that we should not use ROS2 logging infrastructure. So what are alternative? Do we need to implement some soft of real-time logger? |
|
@destogl For the logging infra-structure this is something which can be illustrate in the ros2_control_demos repository. PAL-robotics has a package called dynamic_introspection I believe. |
|
As described in destogl/ros2-control#1 there are some still things to clarify. The main open questions are:
And TODO:
|
|
I was thinking a bit more about the resource management and came up with the following diagram: The "Resource Manager" loads the actuators/sensors/systems from the URDF and each component registers their handles. That is, each component can (statically) allocate the data storage it needs and give access to it via the handle. The registered resources are fixed on runtime, making it hard to reload new components but I guess that's okay and usually the hardware is fixed within a setup - opposite to controllers, where we would like to dynamically load/start/stop them. |
|
@Karsten1987 thanks for sharing your idea. This sounds sensible to me this means that our "Container" would actually be I would like that we get more concrete on the point how |
|
The building is failing on |
bmagyar
left a comment
There was a problem hiding this comment.
couple of styling comments going forward
hardware_interface/include/hardware_interface/types/hardware_interface_return_values.hpp
Outdated
Show resolved
Hide resolved
hardware_interface/include/hardware_interface/types/hardware_interface_type_values.hpp
Outdated
Show resolved
Hide resolved
hardware_interface/include/hardware_interface/utils/ros2_control_utils.hpp
Outdated
Show resolved
Hide resolved
|
|
||
| namespace | ||
| { | ||
| constexpr const auto kRobotTag = "robot"; |
There was a problem hiding this comment.
Is it just me, being the hungarian who doesn't like hungarian notation? We also aren't using it anywhere else on the codebase (thank god) but only for some constants. Do we even need this? I know some people don't like shouty capital-case constants but they are not that bad nor would it be horrific to simply drop the gibberish from these variable names and go with robot_tag in this instance...
There was a problem hiding this comment.
that's the Google style guide. We've been using it in the ROS2 code base as such.
There was a problem hiding this comment.
Should I change something here?
There was a problem hiding this comment.
please just stay consistent at least. You've been using constants in three different places, all with their own style :D
@olivier-stasse It was rewritten as https://github.com/pal-robotics/pal_statistics but, it is still ROS1 only and it's useful for publishing numerical data in a RT safe way, not messages. So not useful here right now I believe. |
|
Before I do some more coding, first 1-2 questions. @Karsten1987: Can you look at the What would be the best way to manage hardware in |
hardware_interface/include/hardware_interface/component_info.hpp
Outdated
Show resolved
Hide resolved
| std::string name; | ||
| std::string type; | ||
| std::string class_type; | ||
| std::string joint; | ||
| std::vector<std::string> interface_names; | ||
| std::unordered_map<std::string, std::string> parameters; | ||
| std::vector<ComponentInfo> subcomponents; | ||
|
|
||
| std::string hardware_class_type; | ||
| std::unordered_map<std::string, std::string> hardware_parameters; |
There was a problem hiding this comment.
this should be limited to what's currently being used in this PR.
I also strongly advise against having a recursive data structure here. A component info should be a POD, with a flat structure and describing one specific component (either actuator or sensor).
There was a problem hiding this comment.
OK. I added than SystemInfo to realize structural dependencies in URDF. is this OK? I extended test URDF and tests to support hardware class types in components.
hardware_interface/include/hardware_interface/resource_manager.hpp
Outdated
Show resolved
Hide resolved
hardware_interface/include/hardware_interface/types/hardware_interface_type_values.hpp
Outdated
Show resolved
Hide resolved
hardware_interface/include/hardware_interface/utils/ros2_control_utils.hpp
Outdated
Show resolved
Hide resolved
|
|
||
| namespace | ||
| { | ||
| constexpr const auto kRobotTag = "robot"; |
There was a problem hiding this comment.
that's the Google style guide. We've been using it in the ROS2 code base as such.
…URDF. Removed recursion from ComponentInfo.
|
@Karsten1987 @bmagyar I hope I addressed all your comments. is build failing because the master is also failing? |
|
Looking at the CI output, it seems like two tests are failing: The return code for the |
I agree with the diagram and have a few questions...
I agree.
This is OK for now. I can only imagine that this registering resources at runtime would be interesting for tool changers. Nevertheless, this could be extended in the future. |
Given that As @Karsten1987 mentioned, I think focusing on the Joints and Sensor interfaces should be the only scope of the current PR. The ResourceManager and any other feature should come later. |
…om/destogl/ros2_control into hardware_control_components-design
|
Hi guys, I renamed Can somebody help me with the output of the tests? I tried using the following command: but there is no additional output. Therefore it is very hard to pin-point the error(s). |
|
@destogl From the logs of the github action run The output is: it seems to come from a problem with rclcpp_lifecycle. What I do not get it that CMakeLists.txt:112 seems to be a comment in rclcpp_lifecycle CMakeLists.txt: |
Karsten1987
left a comment
There was a problem hiding this comment.
are you planning on adding tests to the APIs introduced here? There's quite some new stuff in here which doesn't have any corresponding test.
| /** | ||
| * \brief (optional) key-value pairs for components hardware. | ||
| */ | ||
| std::unordered_map<std::string, std::string> hardware_parameters; |
There was a problem hiding this comment.
what's the difference here to parameters?
There was a problem hiding this comment.
parameters are for component and hardware_parameters are hardware-specific stuff. It could be that in some cases one have the same parameter for the component but uses different hardware/interface.
| /** | ||
| * \brief constants for types of components. | ||
| */ | ||
| constexpr const auto robotType = "robot"; |
There was a problem hiding this comment.
should this be systemType?
There was a problem hiding this comment.
Not really. Those types are for definitions for ResourceManager to get correct type from type property when initializing components.
There was a problem hiding this comment.
not sure I understand this.
| /** | ||
| * \brief list of subcomponents in the system, i.e., list of sensors and actuators. | ||
| */ | ||
| std::vector<ComponentInfo> subcomponents; |
There was a problem hiding this comment.
I still don't understand why we need this. Can a system not be treated as a single black-box component?
There was a problem hiding this comment.
According to your figure yes. You are right, this is not the best way, at least it shouldn't be placed inside SystemInfo type. Nevertheless, we need one top "container" which corresponds to the robot tag in URDF, as there could be System, Sensor and Joints defined, and they are like "subcomponents" of this robot.
The SystemInfo here represents exactly this robot level in URDF. IMHO it is better name than RobotInfo since one can define a good deal of different stuff with URDF, not only robots.
I hope you got my idea, and if you have any proposal, I would be happy to discuss it.
There was a problem hiding this comment.
fair enough. I am cross-posting here as I just went through #121 but I think we definitely need a piece of URDF here which dictates how the individual components as well as the systems are supposed to be specified.
| constexpr const auto HW_IF_POSITION = "position"; | ||
| constexpr const auto HW_IF_VELOCITY = "velocity"; | ||
| constexpr const auto HW_IF_EFFORT = "effort"; |
There was a problem hiding this comment.
why do we need these values? I thought they'd be defined as constants in the control_msgs?
There was a problem hiding this comment.
what does that mean for this PR?
|
|
||
| namespace | ||
| { | ||
| constexpr const auto kRobotTag = "robot"; |
There was a problem hiding this comment.
please just stay consistent at least. You've been using constants in three different places, all with their own style :D
| <description>The main package for `ros2_control`-concept testing. The package implements the most important classes and tests them with `demo_robot` to enable functionality and test driven development.</description> | ||
| <maintainer email="denis@stogl.de">Denis Štogl</maintainer> | ||
| <license>Apache License 2.0</license> | ||
|
|
I will add tests in the follow-up PRs starting with #121 with small example. |
|
@destogl what's the state on this PR here? |
* joint velocity controller initial class version with tests * Set velocity to zero when deactivating controller * Renaming to joint_group_velocity_controller * Default initialize logger * Improved error message log

This PR replaces #80 .
There are a few things to consider:
hardwareword in the name since the components should be completely hardware agnostic and provide the abstraction for controller and controller manager.Robot-Component insideRobotHardware. This component should take care of parsing the urdf and gluing sensors and actuators. In the final version, there should be another way around, i.e. Component has reference to the Hardware. Nevertheless, starting as proposed in this PR should reduce number of braking changes and hopefully simplify integration.