smooth_feedback
Control and estimation on Lie groups
Loading...
Searching...
No Matches
pid.hpp
1// Copyright (C) 2022 Petter Nilsson. MIT License.
2
3#pragma once
4
5#include <chrono>
6
7#include <smooth/concepts/lie_group.hpp>
8#include <smooth/spline/spline.hpp>
9
10#include "time.hpp"
11
12namespace smooth::feedback {
13
18{
20 double windup_limit = std::numeric_limits<double>::infinity();
21};
22
37template<Time T, LieGroup G>
38 requires(Dof<G> > 0)
39class PID
40{
41public:
43 using TrajectoryReturnT = std::tuple<G, Tangent<G>, Tangent<G>>;
44
53 inline PID(const PIDParams & prm = PIDParams{}) noexcept : prm_(prm) {}
55 PID(const PID &) = default;
57 PID(PID &&) = default;
59 PID & operator=(const PID &) = default;
61 PID & operator=(PID &&) = default;
63 ~PID() = default;
64
74 inline Tangent<G> operator()(const T & t, const G & x, const Tangent<G> & v)
75 {
76 const auto [g_des, v_des, a_des] = x_des_(t);
77 const Tangent<G> g_err = g_des - x;
78
79 if (t_last && t > t_last.value()) {
80 // update integral state
81 i_err_ += time_trait<T>::minus(t, t_last.value()) * g_err;
82 i_err_ = i_err_.cwiseMax(-prm_.windup_limit).cwiseMin(prm_.windup_limit);
83 }
84 t_last = t;
85
86 return a_des + kp_.cwiseProduct(g_err) + kd_.cwiseProduct(v_des - v) + ki_.cwiseProduct(i_err_);
87 }
88
92 inline void set_kp(double kp) { kp_.setConstant(kp); }
93
97 template<typename Derived>
98 inline void set_kp(const Eigen::MatrixBase<Derived> & kp)
99 {
100 kp_ = kp;
101 }
102
106 inline void set_kd(double kd) { kd_.setConstant(kd); }
107
111 template<typename Derived>
112 inline void set_kd(const Eigen::MatrixBase<Derived> & kd)
113 {
114 kd_ = kd;
115 }
116
120 inline void set_ki(double ki) { ki_.setConstant(ki); }
121
125 template<typename Derived>
126 inline void set_ki(const Eigen::MatrixBase<Derived> & ki)
127 {
128 ki_ = ki;
129 }
130
134 inline void reset_integral() { i_err_.setZero(); }
135
142 template<int K>
143 inline void set_xdes(T t0, const smooth::Spline<K, G> & c)
144 {
145 set_xdes(t0, smooth::Spline<K, G>(c));
146 }
147
151 template<int K>
152 inline void set_xdes(T t0, smooth::Spline<K, G> && c)
153 {
154 set_xdes([t0 = std::move(t0), c = std::move(c)](T t) -> TrajectoryReturnT {
155 Tangent<G> vel, acc;
156 G x = c(time_trait<T>::minus(t, t0), vel, acc);
157 return TrajectoryReturnT(std::move(x), std::move(vel), std::move(acc));
158 });
159 }
160
177 inline void set_xdes(const std::function<TrajectoryReturnT(T)> & f)
178 {
179 auto f_copy = f;
180 set_xdes(std::move(f_copy));
181 }
182
186 inline void set_xdes(std::function<TrajectoryReturnT(T)> && f) { x_des_ = std::move(f); }
187
188private:
189 PIDParams prm_;
190
191 // gains
192 Tangent<G> kd_ = Tangent<G>::Ones();
193 Tangent<G> kp_ = Tangent<G>::Ones();
194 Tangent<G> ki_ = Tangent<G>::Zero();
195
196 // integral state
197 std::optional<T> t_last;
198 Tangent<G> i_err_ = Tangent<G>::Zero();
199
200 // desired trajectory
201 std::function<TrajectoryReturnT(T)> x_des_ = [](T) -> TrajectoryReturnT {
202 return TrajectoryReturnT(Identity<G>(), Tangent<G>::Zero(), Tangent<G>::Zero());
203 };
204};
205
206} // namespace smooth::feedback
Proportional-Integral-Derivative controller for Lie groups.
Definition: pid.hpp:40
void set_kp(const Eigen::MatrixBase< Derived > &kp)
Set proportional gains.
Definition: pid.hpp:98
void set_xdes(T t0, const smooth::Spline< K, G > &c)
Set desired trajectory as a smooth::Spline.
Definition: pid.hpp:143
void set_kd(const Eigen::MatrixBase< Derived > &kd)
Set derivative gains.
Definition: pid.hpp:112
void set_xdes(std::function< TrajectoryReturnT(T)> &&f)
Set desired trajectory (rvalue version).
Definition: pid.hpp:186
void set_kd(double kd)
Set all derivative gains to kd.
Definition: pid.hpp:106
PID & operator=(const PID &)=default
Default copy assignment.
PID & operator=(PID &&)=default
Default move assignment.
std::tuple< G, Tangent< G >, Tangent< G > > TrajectoryReturnT
Desired trajectory consists of position, velocity, and acceleration.
Definition: pid.hpp:43
void reset_integral()
Reset integral state to zero.
Definition: pid.hpp:134
void set_ki(double ki)
Set all integral gains to ki.
Definition: pid.hpp:120
void set_xdes(const std::function< TrajectoryReturnT(T)> &f)
Set desired trajectory.
Definition: pid.hpp:177
void set_xdes(T t0, smooth::Spline< K, G > &&c)
Set desired trajectory as a smooth::Spline (rvalue version)
Definition: pid.hpp:152
PID(const PIDParams &prm=PIDParams{}) noexcept
Create a PID controller.
Definition: pid.hpp:53
PID(PID &&)=default
Default move constructor.
Tangent< G > operator()(const T &t, const G &x, const Tangent< G > &v)
Calculate control input.
Definition: pid.hpp:74
void set_ki(const Eigen::MatrixBase< Derived > &ki)
Set derivative gains.
Definition: pid.hpp:126
PID(const PID &)=default
Default copy constructor.
void set_kp(double kp)
Set all proportional gains to kp.
Definition: pid.hpp:92
~PID()=default
Default destructor.
double windup_limit
Maximal absolute value for integral states.
Definition: pid.hpp:20
Trait class to specify Time operations.
Definition: time.hpp:14