-
Notifications
You must be signed in to change notification settings - Fork 304
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
Add class for thread management of async hw interfaces #981
Conversation
hardware_interface/include/hardware_interface/async_components.hpp
Outdated
Show resolved
Hide resolved
hardware_interface/include/hardware_interface/async_components.hpp
Outdated
Show resolved
Hide resolved
hardware_interface/include/hardware_interface/resource_manager.hpp
Outdated
Show resolved
Hide resolved
ff34923
to
1280079
Compare
Codecov Report
❗ Your organization is not using the GitHub App Integration. As a result you may experience degraded service beginning May 15th. Please install the Github App Integration for your organization. Read more. @@ Coverage Diff @@
## master #981 +/- ##
==========================================
- Coverage 34.61% 32.48% -2.14%
==========================================
Files 52 92 +40
Lines 2981 9647 +6666
Branches 1855 6484 +4629
==========================================
+ Hits 1032 3134 +2102
- Misses 310 766 +456
- Partials 1639 5747 +4108
Flags with carried forward coverage won't be shown. Click here to find out more.
|
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.
Generally fine, few small comments to make simpler interfaces and proposal for the better code-reuse in the follow-up.
std::is_same<hardware_interface::Actuator, HardwareT>::value || | ||
std::is_same<hardware_interface::System, HardwareT>::value || | ||
std::is_same<hardware_interface::Sensor, HardwareT>::value, |
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.
Does this means if someone extends a component type, they will not be able to use this async implementation?
Can we enable this to all types that have mentioned types as base class?
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.
Actually that wouldn't work since all component type classes are final. Maybe I don't understand the use case here.
hardware_interface/include/hardware_interface/async_components.hpp
Outdated
Show resolved
Hide resolved
hardware_interface/include/hardware_interface/async_components.hpp
Outdated
Show resolved
Hide resolved
hardware_interface/include/hardware_interface/async_components.hpp
Outdated
Show resolved
Hide resolved
hardware_interface/include/hardware_interface/async_components.hpp
Outdated
Show resolved
Hide resolved
explicit AsyncComponentThread( | ||
Actuator * component, unsigned int update_rate, | ||
rclcpp::node_interfaces::NodeClockInterface::SharedPtr clock_interface) | ||
: hardware_component_(component), cm_update_rate_(update_rate), clock_interface_(clock_interface) | ||
{ | ||
} | ||
|
||
explicit AsyncComponentThread( | ||
System * component, unsigned int update_rate, | ||
rclcpp::node_interfaces::NodeClockInterface::SharedPtr clock_interface) | ||
: hardware_component_(component), cm_update_rate_(update_rate), clock_interface_(clock_interface) | ||
{ | ||
} | ||
|
||
explicit AsyncComponentThread( | ||
Sensor * component, unsigned int update_rate, | ||
rclcpp::node_interfaces::NodeClockInterface::SharedPtr clock_interface) | ||
: hardware_component_(component), cm_update_rate_(update_rate), clock_interface_(clock_interface) | ||
{ | ||
} |
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.
Can we template this?
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.
the constructor sadly no, but I think I can provide a templated setup function or something similar instead
@@ -46,7 +49,9 @@ class HARDWARE_INTERFACE_PUBLIC ResourceManager | |||
{ | |||
public: | |||
/// Default constructor for the Resource Manager. | |||
ResourceManager(); | |||
ResourceManager( | |||
unsigned int update_rate = 100, |
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.
Why default value? I would avoid it
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.
Because this is the default update rate of the ControllerManager too, and this way you don't have to provide one when creating a ResourceManager object. Also, this is passed to the ResourceStorage and only used for async components. But it might be misleading for the reader of the code though.
@@ -73,10 +76,16 @@ class ResourceStorage | |||
static constexpr const char * system_interface_name = "hardware_interface::SystemInterface"; | |||
|
|||
public: | |||
ResourceStorage() | |||
// TODO(VX792): Change this when HW ifs get their own update rate, |
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.
How do you want to do this? I don't understand. Resource Storage will easier know the update rate then component. Or do you mean that for async HW has this in parameters?
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.
Yes, the async HW itself. Since when HW ifs get their own update rate, then this could be parsed from the config file directly to the HardwareInfo struct of the component.
This PR is about making the async components fit into the framework structurally. I didn't have the opportunity to test the lifecycle changes extensively. I think it should be safe enough, since the only change is that we're destroying the map elements on shutdown, plus storing the components in a separate vector so we don't have to check for is_async everytime in the control loop.
The threads are created and started at the end of the init_resource_manager class, but I'll put it into the activate function to be consistent with the async controllers' solution. Also, now the resource manager owns all async components and their thread wrapper classes