1+ #include " PID.h"
2+ #include < cmath>
3+ #include < algorithm>
4+ #include < iostream>
5+
6+ PID::PID (const PIDParams ¶ms) {
7+ this ->p = params;
8+ g_u = (1 / (model.m - model.X_u_dot ));
9+ g_psi = (1 / (model.Iz - model.N_r_dot ));
10+ }
11+
12+ PIDParams PID::defaultParams () {
13+ PIDParams p;
14+ p.pk_u = 0.5 ;
15+ p.i_u = 0.2 ;
16+ p.d_u = 0.1 ;
17+ p.pk_psi = 0.5 ;
18+ p.i_psi = 0.2 ;
19+ p.d_psi = 0.1 ;
20+ p.tc_u = 2.0 ;
21+ p.tc_psi = 2 ;
22+ p.q_u = 3.0 ;
23+ p.q_psi = 3.0 ;
24+ p.p_u = 5.0 ;
25+ p.p_psi = 5.0 ;
26+ return p;
27+ }
28+
29+ double PID::normalize_angle (double angle_in){
30+ double angle_out = std::fmod (angle_in + M_PI, 2 * M_PI);
31+ if (angle_out < 0 ){
32+ angle_out += 2 *M_PI;
33+ }
34+ return angle_out - M_PI;
35+ }
36+
37+ double PID::angle_dist (double ang1, double ang2){
38+ double diff = ang1 - ang2;
39+ return normalize_angle (diff);
40+ }
41+
42+ ControllerOutput PID::update (const vanttec::ControllerState &s, const PIDSetpoint &setpoint) {
43+ double Xu = -25 ;
44+ double Xuu = 0 ;
45+ if (std::abs (s.u ) > 1.2 ) {
46+ Xu = 64.55 ;
47+ Xuu = -70.92 ;
48+ }
49+
50+ double sideslip_angle = std::asin (s.v / (0.001 + std::hypot (s.u , s.v )));
51+ sideslip_angle = 0 ;
52+
53+ double Nr = (-0.52 ) * std::hypot (s.u , s.v );
54+ double f_u = (((m - model.Y_v_dot ) * s.v * s.r + (Xuu * std::abs (s.u ) * s.u + Xu * s.u )) / (m - model.X_u_dot ));
55+ double f_psi = (((-model.X_u_dot + model.Y_v_dot ) * s.u * s.v + (model.Nrr * std::abs (s.r ) * s.r + Nr * s.r )) /
56+ (Iz - model.N_r_dot ));
57+
58+ double e_u = setpoint.u - s.u ;
59+
60+ // Second order error (yaw rate)
61+ // double e_psi = angle_dist(setpoint.psi, s.psi);
62+ // Same but including
63+ double e_psi = angle_dist (setpoint.psi + sideslip_angle, s.psi );
64+ std::cout << " SIDESLIP: " << sideslip_angle << std::endl;
65+ // TODO: PRINT THE SIDESLIP VARIABLE, DO FURTHER DEBUGGING TO KNOW WHY EVERYTHING F'S UP WHEN THE BOAT GOES FAST
66+
67+ // First order error (heading)
68+ // double e_psi = setpoint.psi - s.r;
69+
70+ double sign_u = copysign (e_u != 0 ? 1 : 0 , e_u);
71+ double sign_psi = copysign (e_psi != 0 ? 1 : 0 , e_psi);
72+
73+ double edot_u = (e_u - e_u_last) / integral_step;
74+ e_u_last = e_u;
75+ double eidot_u = sign_u * std::pow (std::abs (e_u), p.q_u / p.p_u );
76+ double eidot_psi = sign_psi * std::pow (std::abs (e_psi), p.q_psi / p.p_psi );
77+ ei_u = integral_step * (eidot_u + eidot_u_last) / 2.0 + ei_u;
78+ eidot_u_last = eidot_u;
79+ ei_psi = integral_step * (eidot_psi + eidot_psi_last) / 2.0 + ei_psi;
80+ // ei_psi = std::clamp(ei_psi, -M_PI, M_PI);
81+ eidot_psi_last = eidot_psi;
82+
83+ double edot_psi = setpoint.psi_dot - s.r ;
84+ e_psi_last_last = e_psi_last;
85+ e_psi_last = e_psi;
86+
87+ // TODO find how to initialize vars
88+ static int starting = 1 ;
89+ if (starting == 0 ){
90+ double e_u0 = e_u;
91+ double e_psi0 = e_psi;
92+ alpha_u = (std::pow (std::abs (e_u0),1 -p.q_u /p.p_u ))/(p.tc_u *(1 -p.q_u /p.p_u ));
93+ alpha_psi = (std::pow (std::abs (e_psi0),1 -p.q_psi /p.p_psi ))/(p.tc_psi *(1 -p.q_psi /p.p_psi ));
94+ alpha_u = 0.0001 ;
95+ // alpha_psi = 0.0001;
96+ alpha_psi = 0.01 ;
97+ beta_psi = 10 .;
98+ // beta_psi = 0.;
99+ ei_u = -e_u0 / alpha_u;
100+ ei_psi = -e_psi0 / alpha_psi;
101+ if (alpha_u < 0.0001 ) ei_u = 0 ;
102+ if (alpha_psi < 0.0001 ) ei_psi = 0 ;
103+ starting = 2 ;
104+ }
105+
106+ double ua_u = p.pk_u *e_u + p.i_u *ei_u + p.d_u *edot_u;
107+ double ua_psi = p.pk_psi *e_psi + p.i_psi *ei_psi + p.d_psi *edot_psi;
108+
109+ double Tx = (setpoint.dot_u + (alpha_u * eidot_u) - f_u - ua_u) / g_u;
110+
111+ // Second order control output
112+ double Tz = (setpoint.dot_r + (beta_psi * edot_psi) + (alpha_psi * eidot_psi) - f_psi - ua_psi) / g_psi;
113+
114+ // First order control output
115+ // double Tz = (setpoint.dot_r + (alpha_psi * eidot_psi) - f_psi - ua_psi) / g_psi;
116+
117+ // Clamp forces
118+ Tx = std::clamp (Tx, -60.0 , 73.0 );
119+ Tz = std::clamp (Tz, -14.0 , 14.0 );
120+
121+ if (starting == 1 ){
122+ Tx = 0 ;
123+ Tz = 0 ;
124+ Ka_u = 0 ;
125+ Ka_dot_last_u = 0 ;
126+
127+ Ka_psi = 0 ;
128+ Ka_dot_last_psi = 0 ;
129+
130+ ei_u = -e_u / alpha_u;
131+ eidot_u_last = 0 ;
132+
133+ ei_psi = -e_psi / alpha_psi;
134+ eidot_psi_last = 0 ;
135+ // edot_psi = 0;
136+
137+ starting = 0 ;
138+ }
139+
140+ double port_t = (Tx / 2.0 ) + (Tz / B);
141+ double starboard_t = (Tx / (2.0 * c)) - (Tz / (B * c));
142+
143+ port_t = std::clamp (port_t , -60.0 , 73.0 ) / 2.0 ;
144+ starboard_t = std::clamp (starboard_t , -60.0 , 73.0 ) / 2.0 ;
145+
146+ ControllerOutput out{};
147+ out.left_thruster = port_t ;
148+ out.right_thruster = starboard_t ;
149+
150+ out.Tx = Tx;
151+ out.Tz = Tz;
152+
153+ debugData.e_u = e_u;
154+ debugData.e_psi = e_psi;
155+ debugData.ei_psi = eidot_psi;
156+ debugData.Tx = Tx;
157+ debugData.Tz = Tz;
158+
159+ return out;
160+ }
0 commit comments