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

Rework PID class API #246

Open
wants to merge 25 commits into
base: ros2-master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 18 commits
Commits
Show all changes
25 commits
Select commit Hold shift + click to select a range
d24c7b6
Add computeCommand with double dt
christophfroehlich Dec 7, 2024
d351720
Calc dt only once
christophfroehlich Dec 7, 2024
59b65c6
Add specializations for duration types
christophfroehlich Dec 7, 2024
d883ab3
Format code
christophfroehlich Dec 7, 2024
a7773d5
Deprecate camelCase methods and add new overloads
christophfroehlich Dec 13, 2024
589a555
Merge branch 'ros2-master' into pid_double
christophfroehlich Dec 13, 2024
e18bc66
init_pid --> initialize
christophfroehlich Dec 13, 2024
0539f87
initialize
christophfroehlich Dec 13, 2024
c96b8df
Satisfy pre-commit
christophfroehlich Dec 13, 2024
8954660
Move function definitions to cpp file
christophfroehlich Dec 13, 2024
eb12319
Rename variables
christophfroehlich Dec 13, 2024
542b68a
Add tests for overloaded methods
christophfroehlich Dec 13, 2024
4c1ae85
Merge branch 'ros2-master' into pid_double
saikishor Dec 17, 2024
6cf88ab
Apply suggestions from code review
christophfroehlich Dec 17, 2024
49e192f
Make dt arguments const &
christophfroehlich Dec 17, 2024
f694d57
Rename initialize methods
christophfroehlich Dec 18, 2024
46e89a4
Disable deprecation warning of deprecated class member
christophfroehlich Dec 18, 2024
fc06593
Update comments
christophfroehlich Dec 18, 2024
44a8734
Apply suggestions from code review
christophfroehlich Dec 18, 2024
3d3bb50
Update docstring
christophfroehlich Dec 18, 2024
6d5df18
Merge branch 'ros2-master' into pid_double
christophfroehlich Jan 1, 2025
876907d
Cleanup includes
christophfroehlich Jan 1, 2025
23a86a4
Update comments and remove default constructor
christophfroehlich Jan 1, 2025
e869bd2
Merge branch 'ros2-master' into pid_double
christophfroehlich Jan 1, 2025
15e132a
Update docstring
christophfroehlich Jan 2, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
261 changes: 241 additions & 20 deletions include/control_toolbox/pid.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@
#include <stdexcept>
#include <string>

#include "rclcpp/duration.hpp"
#include "realtime_tools/realtime_buffer.hpp"

#include "control_toolbox/visibility_control.hpp"
Expand Down Expand Up @@ -88,13 +89,13 @@ namespace control_toolbox

\verbatim
control_toolbox::Pid pid;
pid.initPid(6.0, 1.0, 2.0, 0.3, -0.3);
pid.initialize(6.0, 1.0, 2.0, 0.3, -0.3);
double position_desi_ = 0.5;
...
rclcpp::Time last_time = get_clock()->now();
while (true) {
rclcpp::Time time = get_clock()->now();
double effort = pid.computeCommand(position_desi_ - currentPosition(), (time - last_time).nanoseconds());
double effort = pid.computeCommand(position_desi_ - currentPosition(), (time - last_time));
last_time = time;
}
\endverbatim
Expand Down Expand Up @@ -196,7 +197,26 @@ class CONTROL_TOOLBOX_PUBLIC Pid
*
* \note New gains are not applied if i_min_ > i_max_
*/
void initPid(double p, double i, double d, double i_max, double i_min, bool antiwindup = false);
void initialize(
double p, double i, double d, double i_max, double i_min, bool antiwindup = false);

/*!
* \brief Zeros out Pid values and initialize Pid-gains and integral term limits
* Does not initialize the node's parameter interface for PID gains
*
* \param p The proportional gain.
* \param i The integral gain.
* \param d The derivative gain.
* \param i_max The max integral windup.
* \param i_min The min integral windup.
* \param antiwindup If true, antiwindup is enabled and i_max/i_min are enforced
*
* \note New gains are not applied if i_min_ > i_max_
*/
[[deprecated("Use initialize() instead")]] void initPid(
double p, double i, double d, double i_max, double i_min, bool antiwindup = false) {
initialize(p, i, d, i_max, i_min, antiwindup);
}

/*!
* \brief Reset the state of this PID controller
Expand All @@ -211,7 +231,21 @@ class CONTROL_TOOLBOX_PUBLIC Pid
* \param i_max The max integral windup.
* \param i_min The min integral windup.
*/
void getGains(double & p, double & i, double & d, double & i_max, double & i_min);
void get_gains(double & p, double & i, double & d, double & i_max, double & i_min);

/*!
* \brief Get PID gains for the controller.
* \param p The proportional gain.
* \param i The integral gain.
* \param d The derivative gain.
* \param i_max The max integral windup.
* \param i_min The min integral windup.
*/
[[deprecated("Use get_gains() instead")]] void getGains(
double & p, double & i, double & d, double & i_max, double & i_min) {
get_gains(p, i, d, i_max, i_min);
}

/*!
* \brief Get PID gains for the controller.
* \param p The proportional gain.
Expand All @@ -221,14 +255,36 @@ class CONTROL_TOOLBOX_PUBLIC Pid
* \param i_min The min integral windup.
* \param antiwindup If true, antiwindup is enabled and i_max/i_min are enforced
*/
void getGains(
void get_gains(
double & p, double & i, double & d, double & i_max, double & i_min, bool & antiwindup);

/*!
* \brief Get PID gains for the controller.
* \param p The proportional gain.
* \param i The integral gain.
* \param d The derivative gain.
* \param i_max The max integral windup.
* \param i_min The min integral windup.
* \param antiwindup If true, antiwindup is enabled and i_max/i_min are enforced
*/
[[deprecated("Use get_gains() instead")]] void getGains(
double & p, double & i, double & d, double & i_max, double & i_min, bool & antiwindup) {
get_gains(p, i, d, i_max, i_min, antiwindup);
}

/*!
* \brief Get PID gains for the controller.
* \return gains A struct of the PID gain values
*/
Gains get_gains();

/*!
* \brief Get PID gains for the controller.
* \return gains A struct of the PID gain values
*/
Gains getGains();
[[deprecated("Use get_gains() instead")]] Gains getGains() {
return get_gains();
}

/*!
* \brief Set PID gains for the controller.
Expand All @@ -241,15 +297,53 @@ class CONTROL_TOOLBOX_PUBLIC Pid
*
* \note New gains are not applied if i_min > i_max
*/
void setGains(double p, double i, double d, double i_max, double i_min, bool antiwindup = false);
void set_gains(double p, double i, double d, double i_max, double i_min, bool antiwindup = false);

/*!
* \brief Set PID gains for the controller.
* \param p The proportional gain.
* \param i The integral gain.
* \param d The derivative gain.
* \param i_max The max integral windup.
* \param i_min The min integral windup.
* \param antiwindup If true, antiwindup is enabled and i_max/i_min are enforced
*
* \note New gains are not applied if i_min > i_max
*/
[[deprecated("Use set_gains() instead")]] void setGains(
double p, double i, double d, double i_max, double i_min, bool antiwindup = false) {
set_gains(p, i, d, i_max, i_min, antiwindup);
}

/*!
* \brief Set PID gains for the controller.
* \param gains A struct of the PID gain values
*
* \note New gains are not applied if gains.i_min_ > gains.i_max_
*/
void set_gains(const Gains & gains);

/*!
* \brief Set PID gains for the controller.
* \param gains A struct of the PID gain values
*
* \note New gains are not applied if gains.i_min_ > gains.i_max_
*/
void setGains(const Gains & gains);
[[deprecated("Use set_gains() instead")]] void setGains(const Gains & gains) {
set_gains(gains);
}

/*!
* \brief Set the PID error and compute the PID command with nonuniform time
* step size. The derivative error is computed from the change in the error
* and the timestep \c dt.
*
* \param error Error since last call (error = target - state)
* \param dt Change in time since last call in seconds
*
* \returns PID command
*/
[[nodiscard]] double compute_command(double error, const double & dt_s);

/*!
* \brief Set the PID error and compute the PID command with nonuniform time
Expand All @@ -261,7 +355,59 @@ class CONTROL_TOOLBOX_PUBLIC Pid
*
* \returns PID command
*/
[[nodiscard]] double computeCommand(double error, uint64_t dt);
[[deprecated("Use compute_command() instead")]] [[nodiscard]] double computeCommand(
double error, uint64_t dt_ns) {
return compute_command(error, static_cast<double>(dt_ns) / 1.e9);
}

/*!
* \brief Set the PID error and compute the PID command with nonuniform time
* step size. The derivative error is computed from the change in the error
* and the timestep \c dt.
*
* \param error Error since last call (error = target - state)
* \param dt Change in time since last call, measured in nanoseconds.
*
* \returns PID command
*/
[[nodiscard]] double compute_command(double error, const rcl_duration_value_t & dt_ns);

/*!
* \brief Set the PID error and compute the PID command with nonuniform time
* step size. The derivative error is computed from the change in the error
* and the timestep \c dt.
*
* \param error Error since last call (error = target - state)
* \param dt Change in time since last call
*
* \returns PID command
*/
[[nodiscard]] double compute_command(double error, const rclcpp::Duration & dt);

/*!
* \brief Set the PID error and compute the PID command with nonuniform time
* step size. The derivative error is computed from the change in the error
* and the timestep \c dt.
*
* \param error Error since last call (error = target - state)
* \param dt Change in time since last call
*
* \returns PID command
*/
[[nodiscard]] double compute_command(double error, const std::chrono::nanoseconds & dt_ns);

/*!
* \brief Set the PID error and compute the PID command with nonuniform
* time step size. This also allows the user to pass in a precomputed
* derivative error.
*
* \param error Error since last call (error = target - state)
* \param error_dot d(Error)/dt since last call
* \param dt Change in time since last call in seconds
*
* \returns PID command
*/
[[nodiscard]] double compute_command(double error, double error_dot, const double & dt_s);

/*!
* \brief Set the PID error and compute the PID command with nonuniform
Expand All @@ -274,30 +420,104 @@ class CONTROL_TOOLBOX_PUBLIC Pid
*
* \returns PID command
*/
[[nodiscard]] double computeCommand(double error, double error_dot, uint64_t dt);
[[deprecated("Use compute_command() instead")]] [[nodiscard]] double computeCommand(
double error, double error_dot, uint64_t dt_ns) {
return compute_command(error, error_dot, static_cast<double>(dt_ns) / 1.e9);
}

/*!
* \brief Set the PID error and compute the PID command with nonuniform
* time step size. This also allows the user to pass in a precomputed
* derivative error.
*
* \param error Error since last call (error = target - state)
* \param error_dot d(Error)/dt since last call
* \param dt Change in time since last call, measured in nanoseconds.
*
* \returns PID command
*/
[[nodiscard]] double compute_command(
double error, double error_dot, const rcl_duration_value_t & dt_ns);

/*!
* \brief Set the PID error and compute the PID command with nonuniform
* time step size. This also allows the user to pass in a precomputed
* derivative error.
*
* \param error Error since last call (error = target - state)
* \param error_dot d(Error)/dt since last call
* \param dt Change in time since last call
*
* \returns PID command
*/
[[nodiscard]] double compute_command(double error, double error_dot, const rclcpp::Duration & dt);

/*!
* \brief Set the PID error and compute the PID command with nonuniform
* time step size. This also allows the user to pass in a precomputed
* derivative error.
*
* \param error Error since last call (error = target - state)
* \param error_dot d(Error)/dt since last call
* \param dt Change in time since last call, measured in nanoseconds.
*
* \returns PID command
*/
[[nodiscard]] double compute_command(
double error, double error_dot, const std::chrono::nanoseconds & dt_ns);

/*!
* \brief Set current command for this PID controller
*/
void setCurrentCmd(double cmd);
void set_current_cmd(double cmd);

/*!
* \brief Set current command for this PID controller
*/
[[deprecated("Use set_current_cmd() instead")]] void setCurrentCmd(double cmd) {
set_current_cmd(cmd);
}

/*!
* \brief Return current command for this PID controller
*/
double getCurrentCmd();
double get_current_cmd();

/*!
* \brief Return current command for this PID controller
*/
[[deprecated("Use get_current_cmd() instead")]] double getCurrentCmd() {
return get_current_cmd();
}

/*!
* \brief Return derivative error
*/
double getDerivativeError();
[[deprecated("Use get_current_pid_errors() instead")]]
double getDerivativeError() {
double pe, ie, de;
get_current_pid_errors(pe, ie, de);
return de;
}

/*!
* \brief Return PID error terms for the controller.
* \param pe The proportional error.
* \param ie The integral error.
* \param de The derivative error.
*/
void get_current_pid_errors(double & pe, double & ie, double & de);

/*!
* \brief Return PID error terms for the controller.
* \param pe The proportional error.
* \param ie The integral error.
* \param de The derivative error.
*/
void getCurrentPIDErrors(double & pe, double & ie, double & de);
[[deprecated("Use get_current_pid_errors() instead")]] void getCurrentPIDErrors(
double & pe, double & ie, double & de) {
get_current_pid_errors(pe, ie, de);
}

/*!
* @brief Custom assignment operator
Expand All @@ -323,12 +543,13 @@ class CONTROL_TOOLBOX_PUBLIC Pid
// blocking the realtime update loop
realtime_tools::RealtimeBuffer<Gains> gains_buffer_;

double p_error_last_; /**< _Save position state for derivative state calculation. */
double p_error_; /**< Position error. */
double i_error_; /**< Integral of position error. */
double d_error_; /**< Derivative of position error. */
double cmd_; /**< Command to send. */
double error_dot_; /**< Derivative error */
double p_error_last_; /** Save state for derivative state calculation. */
double p_error_; /** Error. */
double i_error_; /** Integral of error. */
double d_error_; /** Derivative of error. */
double cmd_; /** Command to send. */
// TODO(christophfroehlich) remove this -> breaks ABI
[[deprecated("Use d_error_")]] double error_dot_; /** Derivative error */
};

} // namespace control_toolbox
Expand Down
Loading
Loading