Tetrapod Project
gaits.cpp
Go to the documentation of this file.
3 #include <list>
4 #include<iostream>
6 {
7  Eigen::Vector3d res(offset);
8 
9  switch (leg)
10  {
12  res(1) = -res(1);
13  break;
15  res(0) = -res(0);
16  break;
18  res(0) = -res(0);
19  res(1) = -res(1);
20  default:
21  break;
22  }
23 
24  return res;
25 }
26 
28 {
29  Eigen::Vector3d offset(-0.15, 0.1, -0.25);
30 
31  double full_stance = 0.4;
32 
33  double t0;
34 
35  double radius = 0.15;
36 
37  double max_height = 0.05;
38 
39  offset = mirrorOffset(offset, leg);
40 
41  if (leg == Kinematics::frontRight || leg == Kinematics::rearLeft)
42  {
43  t = std::fmod(t + 0.5, 1);
44  }
45  if (t <= full_stance/2)
46  {
47  return offset + Eigen::Vector3d(radius, 0, 0);
48  }
49  else if (t <= 0.5)
50  {
51  t0 = full_stance/2;
52  double x = radius - (t - t0)*(2*radius/(0.5 - t0));
53 
54  return offset + Eigen::Vector3d(x, 0, 0);
55  }
56  else if (t <= 0.5 + full_stance/2)
57  {
58  return offset + Eigen::Vector3d(-radius, 0, 0);
59  }
60  else
61  {
62  t0 = 0.5 + full_stance/2;
63 
64  double x = -radius + (t - t0)*(2*radius/(0.5 - t0));
65 
66  double z = max_height*(1 - std::pow(x/radius, 2));
67 
68  return offset + Eigen::Vector3d(x, 0, z);
69  }
70 }
71 
72 double smallestPositiveRoot(Eigen::Matrix<double, Eigen::Dynamic, 1> coeffs)
73 {
74  Eigen::PolynomialSolver<double, Eigen::Dynamic> solver;
75 
76  solver.compute(coeffs);
77 
78  std::list<double> real_roots;
79 
80  solver.realRoots(real_roots);
81 
82  real_roots.sort();
83 
84  for (auto it = real_roots.begin(); it != real_roots.end(); ++it)
85  {
86  if ( *it >= 0)
87  {
88  return *it;
89  break;
90  }
91  }
92  return INFINITY;
93 }
94 
95 double polynomialSpine(double t, double t_tot, double d_tot, double a_max, double v_rob)
96 {
97  Eigen::Vector3d tr_coeffs(-d_tot - t_tot*v_rob, (2.0/3)*a_max*t_tot, (-4.0/3) + (8.0/9 - 4.0/15)*a_max);
98 
99  double t_r = smallestPositiveRoot(tr_coeffs);
100 
101  Eigen::PolynomialSolver<double, Eigen::Dynamic> solver;
102 
103  double a = -(2.0/3)*a_max/std::pow(t_r, 3);
104 
105  double b = (4.0/3)*a_max/t_r;
106 
107  double c = -v_rob;
108 
109  Eigen::Matrix<double, 5, 1> coeffs;
110 
111  coeffs << c , 0, b, 0, a;
112 
113  std::cout << "t_tot: " << t_tot << " t_r: " <<t_r << std::endl;
114  if (t <= t_r)
115  {
116  return Eigen::poly_eval(coeffs, t);
117  }
118  else if (t <= t_tot - t_r)
119  {
120  return Eigen::poly_eval(coeffs, t_r);
121  }
122  else
123  {
124  return Eigen::poly_eval(coeffs, t_tot - t);
125  }
126 }
127 
128 /*
129 bool CalculatePolynomialTrajectory(double t, double T_end, double distance, double acc_max, double vel_cmd, double &_pos, double &_vel, double &_acc, double &_jerk)
130 {
131  Eigen::Vector3d T_rise_coeffs(- distance - T_end * vel_cmd, (2.0/3) * acc_max*T_end, (-4.0/3) + (8.0/9 - 4.0/15) * acc_max);
132 
133  double T_rise = smallestPositiveRoot(T_rise_coeffs);
134 
135  Eigen::PolynomialSolver<double, Eigen::Dynamic> solver;
136 
137  double a = -(2.0/3.0) * acc_max / std::pow(T_rise, 3);
138 
139  double b = (4.0/3.0) * acc_max/T_rise;
140 
141  double c = - vel_cmd;
142 
143  ROS_INFO("a: %f, b: %f, c: %f", a, b, c);
144 
145  Eigen::Matrix<double, 6, 1> pos_coefficients;
146 
147  Eigen::Matrix<double, 5, 1> vel_coefficients;
148 
149  Eigen::Matrix<double, 4, 1> acc_coefficients;
150 
151  Eigen::Matrix<double, 3, 1> jerk_coefficients;
152 
153  pos_coefficients << 0, c, 0, b/3.0, 0, a/5.0;
154 
155  vel_coefficients << c, 0, b, 0, a;
156 
157  acc_coefficients << 0, 2*b, 0, 4*a;
158 
159  jerk_coefficients << 2*b, 0, 12*a;
160 
161  if(T_rise > T_end/2.0)
162  {
163  ROS_WARN("CalculatePolynomialTrajectory: Invalid set of input parameters");
164 
165  return false;
166  }
167  else
168  {
169  if(t <= T_rise)
170  {
171  _pos = Eigen::poly_eval(pos_coefficients, t);
172  _vel = Eigen::poly_eval(vel_coefficients, t);
173  _acc = Eigen::poly_eval(acc_coefficients, t);
174  _jerk = Eigen::poly_eval(jerk_coefficients, t);
175  }
176  else if (t <= T_end - T_rise)
177  {
178  _pos = Eigen::poly_eval(pos_coefficients, T_rise) + Eigen::poly_eval(vel_coefficients, T_rise) * (t - T_rise);
179  _vel = Eigen::poly_eval(vel_coefficients, T_rise);
180  _acc = Eigen::poly_eval(acc_coefficients, T_rise); // Should be zero
181  _jerk = Eigen::poly_eval(jerk_coefficients, T_rise);
182  }
183  else
184  {
185  _pos = Eigen::poly_eval(pos_coefficients, T_rise) + Eigen::poly_eval(vel_coefficients, T_rise) * (T_end - 2 * T_rise) + (Eigen::poly_eval(pos_coefficients, t - T_end) - Eigen::poly_eval(pos_coefficients, - T_rise));
186  _vel = Eigen::poly_eval(vel_coefficients, t - T_end);
187  _acc = Eigen::poly_eval(acc_coefficients, t - T_end);
188  _jerk = Eigen::poly_eval(jerk_coefficients, t - T_end);
189  }
190 
191  return true;
192  }
193 }
194 */
195 
196 void CalculatePolynomialTrajectory(double t, double swing_period, double rise_percentage, double distance, double vel_cmd, double &_pos, double &_vel, double &_acc, double &_jerk)
197 {
198  if(distance == 0.0)
199  {
200  // Can do something more fancy here, like moving towards the nominal position
201  _pos = 0.0;
202  _vel = 0.0;
203  _acc = 0.0;
204  _jerk = 0.0;
205  }
206  else
207  {
208  double rise_period = swing_period * rise_percentage;
209 
210  double high_period = swing_period - 2.0 * rise_period;
211 
212  double beta = 1.0/(1.0/rise_percentage - 2.0);
213 
214  double rise_distance = (- vel_cmd * rise_period + 8.0 / 7.0 * beta * distance) / (15.0 / 7.0 + beta * 16.0 / 7.0);
215 
216  double c = beta * (distance - 2.0 * rise_distance) / rise_distance;
217 
218  double a = 15.0 / 7.0 * (c - 1.0);
219 
220  double d = 1.0 - c;
221 
222  double b = - 2.0 * a;
223 
224  Eigen::Matrix<double, 6, 1> pos_coefficients;
225 
226  Eigen::Matrix<double, 5, 1> vel_coefficients;
227 
228  Eigen::Matrix<double, 4, 1> acc_coefficients;
229 
230  Eigen::Matrix<double, 3, 1> jerk_coefficients;
231 
232  pos_coefficients << d, c, 0, b/3.0, 0, a/5.0;
233 
234  vel_coefficients << c, 0, b, 0, a;
235 
236  acc_coefficients << 0, 2.0*b, 0, 4.0*a;
237 
238  jerk_coefficients << 2.0*b, 0, 12.0*a;
239 
240  if(t <= rise_period)
241  {
242  double x = t / rise_period;
243 
244 
245  _pos = rise_distance * (a / 5.0 * pow(x - 1.0, 5) + b / 3.0 * pow(x - 1.0, 3) + c * x + d);
246  /*
247  _vel = rise_distance / rise_period * (a * pow(x - 1, 4) + b * pow(x - 1, 2) + c);
248  _acc = rise_distance / pow(rise_period, 2) * (4.0 * a * pow(x - 1.0, 3) + 2.0 * b * (x - 1.0));
249  _jerk = rise_distance / pow(rise_period, 3) * (12.0 * a * pow(x - 1.0, 2) + 2.0 * b);
250  */
251 
252  //_pos = rise_distance * Eigen::poly_eval(pos_coefficients, x - 1.0);
253  _vel = rise_distance / rise_period * Eigen::poly_eval(vel_coefficients, x - 1.0);
254  _acc = rise_distance / pow(rise_period, 2) * Eigen::poly_eval(acc_coefficients, x - 1.0);
255  _jerk = rise_distance / pow(rise_period, 3) * Eigen::poly_eval(jerk_coefficients, x - 1.0);
256 
257  }
258  else if (t <= rise_period + high_period)
259  {
260  _pos = rise_distance * (a / 5.0 * pow(0.0, 5) + b / 3.0 * pow(0.0, 3) + c * 1.0 + d) + rise_distance / rise_period * Eigen::poly_eval(vel_coefficients, 0.0) * (t - rise_period);
261  _vel = rise_distance / rise_period * Eigen::poly_eval(vel_coefficients, 0.0);
262  _acc = rise_distance / pow(rise_period, 2.0) * Eigen::poly_eval(acc_coefficients, 0.0); // Should be zero
263  _jerk = rise_distance / pow(rise_period, 3.0) * Eigen::poly_eval(jerk_coefficients, 0.0);
264  }
265  else
266  {
267  double x = (t - high_period) / rise_period;
268 
269  _pos = _pos = rise_distance * (a / 5.0 * pow(x - 1.0, 5) + b / 3.0 * pow(x - 1.0, 3) + c * x + d) + rise_distance / rise_period * Eigen::poly_eval(vel_coefficients, 0.0) * high_period;
270  _vel = rise_distance / rise_period * Eigen::poly_eval(vel_coefficients, x - 1.0);
271  _acc = rise_distance / pow(rise_period, 2) * Eigen::poly_eval(acc_coefficients, x - 1.0);
272  _jerk = rise_distance / pow(rise_period, 3) * Eigen::poly_eval(jerk_coefficients, x - 1.0);
273  }
274  }
275 }
276 
277 void CalculateFourthOrderPolynomialTrajectory(double t, double swing_period, double distance, double &_pos, double &_vel, double _acc)
278 {
279  double a = 1.0;
280  double b = - 2.0;
281  double c = 1.0;
282 
283  double rise_period = swing_period / 2.0;
284 
285  double x = t/rise_period - 1.0;
286 
287  _pos = distance * (a * pow(x, 4) + b * pow(x, 2) + c);
288 
289  _vel = distance / rise_period * (4.0 * a * pow(x, 3) + 2.0 * b * x);
290 
291  _acc = distance / pow(rise_period, 2) * (12.0 * pow(x, 2) + 2 * b);
292 
293  ROS_INFO("Height - pos: %f, vel: %f, acc: %f, x: %f, dis: %f", _pos, _vel, _acc, x, distance);
294 }
LegType
Leg type enumerator.
Definition: kinematics.h:56
double polynomialSpine(double t, double t_tot, double d_tot, double a_max, double v_rob)
Definition: gaits.cpp:95
void CalculateFourthOrderPolynomialTrajectory(double t, double swing_period, double distance, double &_pos, double &_vel, double _acc)
Definition: gaits.cpp:277
Eigen::Vector3d mirrorOffset(Eigen::Vector3d offset, Kinematics::LegType leg)
Definition: gaits.cpp:5
void CalculatePolynomialTrajectory(double t, double swing_period, double rise_percentage, double distance, double vel_cmd, double &_pos, double &_vel, double &_acc, double &_jerk)
Definition: gaits.cpp:196
Eigen::Vector3d classicGait(double t, Kinematics::LegType leg)
Definition: gaits.cpp:27
double smallestPositiveRoot(Eigen::Matrix< double, Eigen::Dynamic, 1 > coeffs)
Definition: gaits.cpp:72
Eigen::Vector3d Vector3d
Definition: kinematics.h:49