Skip to content

[Pid] Save i_term instead of error integral #294

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

Merged
merged 3 commits into from
Mar 12, 2025

Conversation

christophfroehlich
Copy link
Contributor

@christophfroehlich christophfroehlich commented Mar 7, 2025

The internal state should be the i_term to avoid jumps in the output while tuning the integral gain. Reverts #33

With constant gains, this PR does not change the current behavior of output calculation. Only the field in the published message and the result of get_current_pid_errors will be changed.

I got confused of the message definition, because it has some duplicates:
ros-controls/control_msgs#173
If yes, let's fix that in a new PR.

Base automatically changed from cleanup/pid to ros2-master March 10, 2025 19:41
@christophfroehlich christophfroehlich marked this pull request as ready for review March 10, 2025 19:41
@codecov-commenter
Copy link

codecov-commenter commented Mar 10, 2025

Codecov Report

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

Project coverage is 75.62%. Comparing base (769d610) to head (4591257).

Files with missing lines Patch % Lines
src/pid_ros.cpp 66.66% 1 Missing ⚠️
Additional details and impacted files
@@             Coverage Diff              @@
##           ros2-master     #294   +/-   ##
============================================
  Coverage        75.62%   75.62%           
============================================
  Files               24       24           
  Lines             1161     1157    -4     
  Branches            87       86    -1     
============================================
- Hits               878      875    -3     
  Misses             236      236           
+ Partials            47       46    -1     
Flag Coverage Δ
unittests 75.62% <88.88%> (+<0.01%) ⬆️

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

Files with missing lines Coverage Δ
include/control_toolbox/pid.hpp 77.77% <ø> (ø)
include/control_toolbox/pid_ros.hpp 100.00% <ø> (ø)
src/pid.cpp 94.93% <100.00%> (+0.96%) ⬆️
test/pid_tests.cpp 100.00% <ø> (ø)
src/pid_ros.cpp 71.03% <66.66%> (ø)
🚀 New features to boost your workflow:
  • Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

Copy link
Member

@saikishor saikishor left a comment

Choose a reason for hiding this comment

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

In general, LGTM

I'll review antiwindup part again will approve it

Copy link

@Amronos Amronos left a comment

Choose a reason for hiding this comment

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

LGTM! The documentation though should be updated for the antiwindup parameter of the pid_controller. As the documentation currently states that i_term_ is always limited regardless of what the value of the antiwindup parameter is, which was the case before this PR.

}

// Calculate derivative contribution to command
d_term = gains.d_gain_ * d_error_;

// Compute the command
cmd_ = p_term + i_term + d_term;
// Limit i_term so that the limit is meaningful in the output
cmd_ = p_term + std::clamp(i_term_, gains.i_min_, gains.i_max_) + d_term;

Choose a reason for hiding this comment

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

Not sure why i_term is being clamped again here when it was clamped above when antiwindup is true. Shouldn't it only be clamped when antiwindup is true

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I left that to keep the current behavior, it was clamped even with antiwindup being true.
from the docstring:

antiwindup Antiwindup functionality. When set to true, limits
        the integral error to prevent windup; otherwise, constrains the
        integral contribution to the control output. i_max and
        i_min are applied in both scenarios.

this was already questioned in #276 and I didn't want to change this behavior in this PR.

Choose a reason for hiding this comment

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

Ok. I understand and it shouldn't be changed in this PR. The only minor comment I would make is if antiwindup is false, the iterm is not clamped but the use of it is clamped when calculating output. That is slightly different behavior than before where the iterm was always clamped. Practically, I don't think it makes a difference.

I definitely think the antiwindup behavior needs to be fixed and I guess it will be addressed in #276. With this PR and the earlier behavior, the antiwindup flag, in practical terms, doesn't change anything. Antiwindup is always being implemented regardless of the flag.

@@ -284,7 +284,7 @@ void PidROS::publish_pid_state(double cmd, double error, rclcpp::Duration dt)
rt_state_pub_->msg_.error = error;
rt_state_pub_->msg_.error_dot = d_error;
rt_state_pub_->msg_.p_error = p_error;
rt_state_pub_->msg_.i_error = i_error;
rt_state_pub_->msg_.i_error = i_term;

Choose a reason for hiding this comment

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

I think you said you will change the message in a different PR since this is really weighted i-error.

Copy link

@bijoua29 bijoua29 left a comment

Choose a reason for hiding this comment

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

LGTM

}

// Calculate derivative contribution to command
d_term = gains.d_gain_ * d_error_;

// Compute the command
cmd_ = p_term + i_term + d_term;
// Limit i_term so that the limit is meaningful in the output
cmd_ = p_term + std::clamp(i_term_, gains.i_min_, gains.i_max_) + d_term;

Choose a reason for hiding this comment

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

Ok. I understand and it shouldn't be changed in this PR. The only minor comment I would make is if antiwindup is false, the iterm is not clamped but the use of it is clamped when calculating output. That is slightly different behavior than before where the iterm was always clamped. Practically, I don't think it makes a difference.

I definitely think the antiwindup behavior needs to be fixed and I guess it will be addressed in #276. With this PR and the earlier behavior, the antiwindup flag, in practical terms, doesn't change anything. Antiwindup is always being implemented regardless of the flag.

Copy link
Member

@saikishor saikishor left a comment

Choose a reason for hiding this comment

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

Seems fine to me

@christophfroehlich christophfroehlich merged commit 37a12e8 into ros2-master Mar 12, 2025
10 of 11 checks passed
@christophfroehlich christophfroehlich deleted the fix/i_term branch March 12, 2025 10:51
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants