Skip to content
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

[CM] Fix controller missing update cycles in a real setup #1774

Merged

Conversation

saikishor
Copy link
Member

@saikishor saikishor commented Oct 2, 2024

When we introduced supporting different update rates to the controllers. I realized that inside the tests I assumed a perfect system without any jitter and it was performing well.

time += rclcpp::Duration::from_seconds(0.01);

However, this is not the case in reality. We have some influence of system jitter, and due to the jitter if the system sleeps a bit less than what it should, then it skips and waits for the next cycle, and that's the reason we have double the period in most occasions.

rclcpp::Time old_time = time;
cm_->get_clock()->sleep_until(old_time + PERIOD);
time = cm_->get_clock()->now();

This PR introduces a new approach to solving this issue and the tests have been updated to be more realistic than earlier version

Fixes: #1769
Fixes: #1574

Copy link

codecov bot commented Oct 2, 2024

Codecov Report

Attention: Patch coverage is 97.72727% with 1 line in your changes missing coverage. Please review.

Project coverage is 87.60%. Comparing base (d55def1) to head (69095e5).
Report is 12 commits behind head on master.

Files with missing lines Patch % Lines
...ontroller_manager/test/test_controller_manager.cpp 97.05% 1 Missing ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##           master    #1774      +/-   ##
==========================================
- Coverage   87.62%   87.60%   -0.03%     
==========================================
  Files         120      120              
  Lines       12217    12227      +10     
  Branches     1093     1093              
==========================================
+ Hits        10705    10711       +6     
- Misses       1123     1126       +3     
- Partials      389      390       +1     
Flag Coverage Δ
unittests 87.60% <97.72%> (-0.03%) ⬇️

Flags with carried forward coverage won't be shown. Click here to find out more.

Files with missing lines Coverage Δ
...controller_interface/controller_interface_base.hpp 92.30% <ø> (ø)
.../include/controller_manager/controller_manager.hpp 100.00% <100.00%> (ø)
controller_manager/src/controller_manager.cpp 77.98% <100.00%> (-0.19%) ⬇️
...ontroller_manager/test/test_controller_manager.cpp 96.25% <97.05%> (-0.11%) ⬇️

Copy link
Contributor

@fmauch fmauch left a comment

Choose a reason for hiding this comment

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

This does absolutely make sense and I can confirm that this solves the problem I had in #1769. With this PR I get:

image

Thanks a lot, @saikishor

Copy link
Contributor

@christophfroehlich christophfroehlich left a comment

Choose a reason for hiding this comment

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

Sounds reasonable for me

controller_manager/src/controller_manager.cpp Show resolved Hide resolved
@fmauch
Copy link
Contributor

fmauch commented Oct 2, 2024

One comment I forgot earlier: It might be good to add an API doc change to this PR:

* \param[in] period The measured time taken by the last control loop iteration

Maybe that should be changed to

* \param[in] period The measured time since this method was called last

Copy link
Contributor

@christophfroehlich christophfroehlich 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 explanation

@bijoua29
Copy link
Contributor

bijoua29 commented Oct 9, 2024

Funny. I just ran into this issue with my controller in the last day. I had a controller manager and controller running at 100 Hz. And due to some jitter in one of the first samples, it was calling my controller at 100 Hz but passing a period of 20 ms continuously. I hacked a quick workaround which fixed the issue but this approach works too. Thanks for fixing this @saikishor .

My only concern is that previously we were tracking the next update time based on an absolute time reference at the beginning. With this change, we are determining the next update time based on a moving time reference i.e. the last update time. Maybe, it doesn't matter in practical terms but I feel the previous version was "more" correct in that respect.

@saikishor
Copy link
Member Author

My only concern is that previously we were tracking the next update time based on an absolute time reference at the beginning. With this change, we are determining the next update time based on a moving time reference i.e. the last update time. Maybe, it doesn't matter in practical terms but I feel the previous version was "more" correct in that respect.

@bijoua29 Even though the previous one might feel right, in reality, due to the system jitter it only creates issues in the long run. Conceptually, the proposed method is more robust to the system jitter and functionally better

@bijoua29
Copy link
Contributor

bijoua29 commented Oct 9, 2024

My only concern is that previously we were tracking the next update time based on an absolute time reference at the beginning. With this change, we are determining the next update time based on a moving time reference i.e. the last update time. Maybe, it doesn't matter in practical terms but I feel the previous version was "more" correct in that respect.

@bijoua29 Even though the previous one might feel right, in reality, due to the system jitter it only creates issues in the long run. Conceptually, the proposed method is more robust to the system jitter and functionally better

@saikishor I think you can track both next update time to make it a fixed frrequency without jitter in addition to the last update time fix you added to account for current time jitter and setting the period correctly. It does mean you have to track two variables. But if you think this is sufficient, that is fine.

Copy link
Contributor

mergify bot commented Oct 16, 2024

This pull request is in conflict. Could you fix it @saikishor?

bijoua29 added a commit to SchillingRobotics/ros2_control_schilling that referenced this pull request Oct 17, 2024
Copy link
Contributor

mergify bot commented Oct 17, 2024

This pull request is in conflict. Could you fix it @saikishor?

@fmauch
Copy link
Contributor

fmauch commented Oct 25, 2024

We could probably also add #1574 to the linked issues of this PR.

@saikishor
Copy link
Member Author

We could probably also add #1574 to the linked issues of this PR.

Done. Thank you :)

@bmagyar bmagyar merged commit 814137d into ros-controls:master Nov 5, 2024
16 of 19 checks passed
@bmagyar bmagyar added the backport-iron This label should be used by maintaines only! Label triggers PR backport to ROS2 Iron. label Nov 5, 2024
@saikishor saikishor deleted the fix/controller_update_period branch November 5, 2024 12:41
mergify bot pushed a commit that referenced this pull request Nov 5, 2024
(cherry picked from commit 814137d)

# Conflicts:
#	controller_manager/src/controller_manager.cpp
#	controller_manager/test/test_controller_manager.cpp
christophfroehlich pushed a commit that referenced this pull request Nov 6, 2024
)

Co-authored-by: Sai Kishor Kothakota <sai.kishor@pal-robotics.com>
saikishor added a commit to pal-robotics-forks/ros2_control that referenced this pull request Nov 12, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
backport-iron This label should be used by maintaines only! Label triggers PR backport to ROS2 Iron.
Projects
None yet
5 participants