-
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
deactivate hardware from read/write return value #884
Conversation
@VX792 could you please give this a review from the KUKA use-case perspective? |
I think something like this would be useful for the (unofficial) KUKA RoX driver too. We're also using a blocking read for our system component, and the problem was that whenever the component got deactivated when a read or write call returned with This is a bit different from your original issue, since the equivalent of your interpreter code is running constantly on the robot. At the worst case, commands coming through the ros2 driver are ignored, but the internal service is still active. Still, the above problem was solved in a really hacky way, and if a simple hw lifecycle change allows us to receive the latest state values from the robot without sending out any commands then I'm all for it! |
d6e6526
to
b7fa535
Compare
112fd58
to
e4b03a4
Compare
Codecov Report
Additional details and impacted files@@ Coverage Diff @@
## master #884 +/- ##
==========================================
- Coverage 34.61% 32.46% -2.16%
==========================================
Files 52 94 +42
Lines 2981 10033 +7052
Branches 1855 6755 +4900
==========================================
+ Hits 1032 3257 +2225
- Misses 310 782 +472
- Partials 1639 5994 +4355
Flags with carried forward coverage won't be shown. Click here to find out more.
|
I've revisited this also with a discussion I had with @destogl last week. I think this is in a state, where I'd like to discuss some things here. I've re-structured the PR such that the individual commits explain the points I'd like to discuss best.
The main discussion points I see are the following:
|
This pull request is in conflict. Could you fix it @fmauch? |
Yes, I see here multiple PR that can be added after each other. Just for simpler traceability and review. You can have a big PR implementing everything, but we merge it once featured by one. NOTE: The points 1 and 2 can be done independently.
yes. As described above.
Yes, if (command) interfaces don't have flag "available when inactive" set then they should be only available when hardware is in active state.
There might be a bug. The controller should be deactivated. I know I was implementing this, but maybe missed something...
I would go with the 4 PR as proposed above. You can create a big one first will full functionality and then slice it into smaller chunks for faster review and merging. So we are also sure that everything is well tested. |
Before we consider this PR can we please include some documentation of the state transitions the Here is a proposal I am working on for Faults and Hardware Status that I would appreciate any input you might have because it very much fits into this use case. |
This is the first step to deactivate a hw component when writing to that component stops working (e.g. because of some interpreter program stopped running). The idea is that a hw component can go back to "configured", where the communication is working, but commanding the robot is not possible.
I've finally finished this (rather small) PR from my point of view. This now
I didn't change any documentation so far and I didn't add tests inside the |
Inside the tests there exist special values to simulate an error in the hardware. These magic numbers were used and defined at different places. This creates one common place to define those. This should make maintenance more stable and the tests easier to understand for new developers.
Basically, the hardware tells the resource_manager to deactivate the port, so the imperative is probably the better wording.
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.
There are a few details we need to review and fix.
The major thing is the placement of the header file with error codes. Besides that, I propose to add a few comments to increase the readability of the test.
hardware_interface/include/hardware_interface/types/test_hardware_interface_constants.hpp
Outdated
Show resolved
Hide resolved
using lifecycle_msgs::msg::State; | ||
rclcpp_lifecycle::State state( | ||
State::PRIMARY_STATE_INACTIVE, lifecycle_state_names::INACTIVE); | ||
set_component_state(component.get_name(), state); |
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 would call directly deactivate_hardware
from line 319 to avoid unnecessary iterations, searches and so on.
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.
Since at this point we don't really have the Hardware datatype we cannot call this directly. Getting this would be duplication of code from lines 1138-1191 which is the main part of ResourceManager::set_component_state
. I don't quite understand your suggestion here @destogl , I'm afraid.
using lifecycle_msgs::msg::State; | ||
rclcpp_lifecycle::State state( | ||
State::PRIMARY_STATE_INACTIVE, lifecycle_state_names::INACTIVE); | ||
set_component_state(component.get_name(), state); |
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.
check comment below
hardware_interface/include/hardware_interface/types/test_hardware_interface_constants.hpp
Outdated
Show resolved
Hide resolved
ping @fmauch |
Sorry for not being responsive ATM. I am currently on vacation struggling to find the time to do OSS development. Will do this until Tuesday! |
as suggested by @destogl Co-authored-by: Dr. Denis <[email protected]>
As introduced in moving constants definition file
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.
@fmauch thanks for the following up. The last part I have updated directly.
@Mergifyio backport humble |
✅ Backports have been created
|
) * Deactivate hardware from read/write return value * Added tests to DEACTIVATE return value * Use constants for defining of special test-values for different HW behaviors --------- Co-authored-by: Dr. Denis <[email protected]> (cherry picked from commit bd6911d) # Conflicts: # controller_manager/test/test_controller_manager_hardware_error_handling.cpp # hardware_interface/src/resource_manager.cpp # hardware_interface/test/test_components/test_actuator.cpp # hardware_interface/test/test_components/test_system.cpp # hardware_interface/test/test_resource_manager.cpp
Hi @fmauch, I am trying this new feature, and I was expecting my controller to not publish ros_topics after I desactivate a component using a controller. But data are still being read from my sensors and being publish. Is this the expected behavior? If yes, then I misunderstood the point of the PR. Thank you in advance. PS: I am not sure if I should post this here or write a new issue.. |
…value (ros-controls#884)" This reverts commit bd6911d.
…value (ros-controls#884)" This reverts commit bd6911d.
…ls#922) * Update list of reviewers (ros-controls#884) (cherry picked from commit 0a96cbb513282880d2d64adfb8c3c8c0ffc84b5b) # Conflicts: # .github/reviewer-lottery.yml * Update reviewer-lottery.yml --------- Co-authored-by: Christoph Fröhlich <[email protected]>
This PR aims at adding the possibility to trigger transitions between
active
andinactive
for writing interfaces only. I discussed this with @destogl and this is my first implementation that should help further explain my intention.The basic idea is that many hardware controllers require some form of activation or interpreter code running on the hardware controller in order to control the hardware. However, streaming data from the robot does not necessarily require such interpreter script to be running. For example, in the UR driver we read data from the robot as soon as a connection to the robot is established. We can read joint data, wrench sensor information and IO status. However, when the interpreter code is not running on the robot, we cannot control the robot. I think there are many hardware components that allow reading some sort of information when the hardware is not completely running (and be it only the fact that the hardware itself is not in a
running
state).To mitigate this, we have a small helper node that we call "controller stopper" that reads status information from the robot, whether the interpreter code is running and takes down controllers accordingly. It basically listens to a boolean topic and stops all controllers instead of a set of preconfigured controllers when receiving a
false
message. On atrue
message it restarts the previously stopped controllers. This has the following benefits:Obviously, this is a rather simple method to achieve that goal which has the culprit that nothing stops users from starting controllers manually while robot control is not active...
(The above paragraph is copied from my corresponding post in ROS1
ros_control
regarding the controller_stopper).We think that it would be beneficial to handle that using lifecycle transitions inside the hardware interface than this method. Currently, we can set the hardware back to the
inactive
state as a whole, also deactivating all reading interfaces. With this PR I added a third return type to theread
andwrite
functions that triggers deactivating all writing interfaces while leaving the reading interfaces untouched. Controllers currently are not aware of this switch and stay active, but that would probably be a followup task (though this would need to be synchronized when / if ever this gets merged.)I tested this together with a modified
ur_robot_driver
which can be found here.I am aware that this PR is not yet in a fine state, hence the draft status. But I wanted to raise the discussion, anyway. Do you consider this an edge case for UR not relevant for other hardware components? Does this make sense from a logical point of view? Would there be any conceptual comments?