-
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
Controller sorting and proper execution in a chain (Fixes #853) #1063
Conversation
c3a96e4
to
f7c54fc
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 #1063 +/- ##
==========================================
- Coverage 34.61% 31.83% -2.79%
==========================================
Files 52 94 +42
Lines 2981 10475 +7494
Branches 1855 7130 +5275
==========================================
+ Hits 1032 3335 +2303
- Misses 310 801 +491
- Partials 1639 6339 +4700
Flags with carried forward coverage won't be shown. Click here to find out more.
|
f7c54fc
to
84f7b1d
Compare
5a067f7
to
bbb582e
Compare
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.
LGTM
controller_manager/include/controller_manager/controller_manager.hpp
Outdated
Show resolved
Hide resolved
controller_manager/test/test_controllers_chaining_with_controller_manager.cpp
Outdated
Show resolved
Hide resolved
controller_manager/include/controller_manager/controller_manager.hpp
Outdated
Show resolved
Hide resolved
Consider a 5 controller chain: A => B => C => D => E controller_sorting(B,C) == true This is a violation of : required of the comparison function parameter by std::sort. |
@sgmurray Thank you for pointing out. You were right. This wouldn't work with the current version. I've started working on the fix. I more or less have it. In the next few days, I will add the logic and will add a proper test case. Thank you, |
@sgmurray Now the newly added changes should already work for the use-case that you have mentioned, but also for the complex scenario such as controller branching, as in a controller that commands 2 different controller chains. Thank you again for the comment. Best Regards, |
This is a topological sorting problem. I don't think using std::sort is the right approach. The set of controllers form a directed acyclic graph. Each node represents a controller and an edge from node A to node B means that A's command is B's reference. Maybe we could create a Directed Acyclic Graph class. This class would support:
The controller manager would then call the Directed Acyclic Graph class every time it does something to change the graph or when it needs to know some property of the graph. This would allow us to pull the logic involving the graph out of the controller manager. |
I would say that this is the right approach with another caveat. A lot of controllers are using the previous value of a controller. For instance B will need the previous value of D. If you do not take into account time, this will create a cycle in the graph. The only way to break the cycle is to consider the time dependency. |
Thank you all for the insightful comments on this topic! With that in mind I have one question for everyone: Of course that is only given that we can understand & fix the issues highlighted by the tests without cheating ;) |
Hello @sgmurray and @olivier-stasse Yes, I think the Directed Acyclic Graph is a very nice idea. We can consider implementing the same in the near future. Right now, this PR achieves some level of sorting that was not existing right now with most of the cases that we face. So, do you guys agree to merge it and then work on the proper version to replace it? |
1ec41fb
to
e9780b0
Compare
"I would say that this is the right approach with another caveat. A lot of controllers are using the previous value of a controller. For instance B will need the previous value of D. If you do not take into account time, this will create a cycle in the graph. The only way to break the cycle is to consider the time dependency. " I don't think the current pull request handles this. If B uses the previous value of D, I think this current pull request could end up inserting D before B in the list. @olivier-stasse How could the controller manager determine that B is using a pervious value of D and that it is safe execute B before D? This PR checks for command interface/state interface matches to determine precedence relationships. Should we also check for command interface/reference interface matches? @saikishor I wrote up a quick test for std::sort and it failed. `int main()
}` Result. Failure. 4 occurs after 6 and 3 occurs after 5. |
As a control engineer using Matlab/Simulink, this is a typical encountered problem called "Algebraic Loops". It happens if there is no break of the connection with a time delay, e.g., the next solver loop. If we open the framework for such algebraic loops, we easily get numerical issues in solving this problem. (how are the values propagated in the loop, are there any dynamics inside etc..). I suggest merging this PR for the simple forward directed loops, and prohibit other loop configurations in the meantime. |
48ab603
to
3ef00f3
Compare
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.
Thank you!
@destogl needs more time to review 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.
Just few things to disucss.
controller_manager/include/controller_manager/controller_manager.hpp
Outdated
Show resolved
Hide resolved
controller_manager/include/controller_manager/controller_manager.hpp
Outdated
Show resolved
Hide resolved
* @note The following conditions needs to be handled while ordering the controller list | ||
* 1. The controllers that do not use any state or command interfaces are updated first | ||
* 2. The controllers that use only the state system interfaces only are updated next | ||
* 3. The controllers that use any of an another controller's reference interface are updated | ||
* before the preceding controller | ||
* 4. The controllers that use the controller's estimated interfaces are updated after the | ||
* preceding controller | ||
* 5. The controllers that only use the system's command interfaces are updated last | ||
* 6. All inactive controllers go at the end of the list |
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.
Should we go with the “new” nomenclature here?
Should we first merge “estimated” interfaces and then do rename, or do the renaming first.
* @note The following conditions needs to be handled while ordering the controller list | |
* 1. The controllers that do not use any state or command interfaces are updated first | |
* 2. The controllers that use only the state system interfaces only are updated next | |
* 3. The controllers that use any of an another controller's reference interface are updated | |
* before the preceding controller | |
* 4. The controllers that use the controller's estimated interfaces are updated after the | |
* preceding controller | |
* 5. The controllers that only use the system's command interfaces are updated last | |
* 6. All inactive controllers go at the end of the list | |
* @note The following conditions needs to be handled while ordering the controller list | |
* 1. The controllers that do not use any feedback or output interfaces are updated first | |
* 2. The controllers that use only the state system interfaces only are updated next | |
* 3. The controllers that use any of an another controller's reference interface are updated | |
* before the preceding controller | |
* 4. The controllers that use the controller's state interfaces are updated after the | |
* preceding controller | |
* 5. The controllers that only use the system's command interfaces are updated last | |
* 6. All inactive controllers go at the end of the list |
What do you mean with “system's” command interfaces? Do you mean HW command interfaces?
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.
This docs should be probably moved somewhere else.
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.
Should we go with the “new” nomenclature here?
Maybe it would be easier to have the renaming to the new nomenclature everything at once. As it is not started, it might create confusion to the community.
Should we first merge “estimated” interfaces and then do rename, or do the renaming first.
I think it is better to merge the "estimated" interfaces first and then do the renaming together (or) may be we can start a renaming branch on top of the estimated interfaces branch, that would also work right?
What do you mean with “system's” command interfaces? Do you mean HW command interfaces?
Yes, you are right. I mean HW command interfaces. I will be changing it.
This docs should be probably moved somewhere else.
Where do you think would be the right place.
Co-authored-by: Dr. Denis <denis@stoglrobotics.de>
…s#853) (ros-controls#1063) * Added test for the reordering controllers case * Perform controller sorting at the end of switch_controller * fix the list_chained_controllers_srv test case for the new controller sorting * move the logic to a separate function * Apply suggestions from code review Co-authored-by: Christoph Fröhlich <christophfroehlich@users.noreply.github.com> * remove obsolete TODO comments in the controller chaining tests * Add a test case to sort 6 controllers in chained mode * Added a method to retrieve the following controller names given a controller name * Update the controller_sorting method to support progressive chaining ability * Added test case to sort chained controllers with branching * Added a method to retrieve the preceding controller names given a controller name * Added logic to controller_sorting to support sorting branched controller chains * Added some documentation to the newly added functions * Add debug print of reordered controllers list once they are sorted * Add the condition to skip the non-configured controllers * remove logging for every command interface * Improve the complex chain test case checking * added a test case to sort independent chains * Added fixes for the independent chains sorting * better randomization in independent chains testing * Fix minor logic issues * Add 3rd chain for better complex testing * Apply suggestions from code review - Denis Co-authored-by: Dr. Denis <denis@stoglrobotics.de> * address pull request review comments --------- Co-authored-by: Christoph Fröhlich <christophfroehlich@users.noreply.github.com> Co-authored-by: Dr. Denis <denis@stoglrobotics.de> Co-authored-by: Bence Magyar <bence.magyar.robotics@gmail.com>
Hello!
This PR addresses the issue of controllers sorting in proper order(#853), in order to be able to execute them in a proper sequential order. The newly added test fails at the first instance and after doing proper controller sorting it passes.
Thank you,