A sparse MPC solver for walking motion generation.
WMG_private.cpp
Go to the documentation of this file.
1 
6 #include <cmath> // sqrt
7 
8 #include "WMG.h"
9 #include "footstep.h"
10 
11 
12 
23 int WMG::getNextSS(const int start_ind, const fs_type type)
24 {
25  int index = start_ind + 1;
26  for (; index < (int) FS.size(); index++)
27  {
28  if (FS[index].type != FS_TYPE_DS)
29  {
30  if (type == FS_TYPE_AUTO)
31  {
32  break;
33  }
34  else
35  {
36  if (FS[index].type == type)
37  {
38  break;
39  }
40  }
41  }
42  }
43  return (index);
44 }
45 
46 
47 
58 int WMG::getPrevSS(const int start_ind, const fs_type type)
59 {
60  int index = start_ind - 1;
61  for (; index >= 0; index--)
62  {
63  if (FS[index].type != FS_TYPE_DS)
64  {
65  if (type == FS_TYPE_AUTO)
66  {
67  break;
68  }
69  else
70  {
71  if (FS[index].type == type)
72  {
73  break;
74  }
75  }
76  }
77  }
78  return (index);
79 }
80 
81 
82 
91  const int support_number,
92  double *left_foot_pos,
93  double *right_foot_pos)
94 {
95  int left_ind, right_ind;
96 
97  left_ind = getNextSS (support_number);
98  if (FS[left_ind].type == FS_TYPE_SS_L)
99  {
100  right_ind = getPrevSS (support_number);
101  }
102  else
103  {
104  right_ind = left_ind;
105  left_ind = getPrevSS (support_number);
106  }
107 
108  Matrix4d::Map(left_foot_pos) = FS[left_ind].posture->matrix();
109  Matrix4d::Map(right_foot_pos) = FS[right_ind].posture->matrix();
110 }
111 
112 
113 
123  const int support_number,
124  const double theta,
125  double *left_foot_pos,
126  double *right_foot_pos)
127 {
128  double *swing_foot_pos, *ref_foot_pos;
129  int next_swing_ind, prev_swing_ind;
130  footstep& current_step = FS[support_number];
131 
132 
133  if (current_step.type == FS_TYPE_SS_L)
134  {
135  ref_foot_pos = left_foot_pos;
136  swing_foot_pos = right_foot_pos;
137 
138  prev_swing_ind = getPrevSS (support_number, FS_TYPE_SS_R);
139  next_swing_ind = getNextSS (support_number, FS_TYPE_SS_R);
140  }
141  else
142  {
143  ref_foot_pos = right_foot_pos;
144  swing_foot_pos = left_foot_pos;
145 
146  prev_swing_ind = getPrevSS (support_number, FS_TYPE_SS_L);
147  next_swing_ind = getNextSS (support_number, FS_TYPE_SS_L);
148  }
149 
150  Matrix4d::Map(ref_foot_pos) = current_step.posture->matrix();
151 
152 
153  double dx = FS[next_swing_ind].x() - FS[prev_swing_ind].x();
154  double dy = FS[next_swing_ind].y() - FS[prev_swing_ind].y();
155  double l = sqrt(dx*dx + dy*dy);
156 
157 
158  double x[3] = {0.0, l/2, l};
159  double b_coef = - (x[2]*x[2] /*- x[0]*x[0]*/)/(x[2] /*- x[0]*/);
160  double a = step_height / (x[1]*x[1] /*- x[0]*x[0]*/ + b_coef*(x[1] /*- x[0]*/));
161  double b = a * b_coef;
162  //double c = - a*x[0]*x[0] - b*x[0];
163 
164 
165  double dl = /*(1-theta)*x[0] +*/ theta * l;
166 
167  Matrix4d::Map(swing_foot_pos) = (
168  (*FS[prev_swing_ind].posture)
169  * Translation<double, 3>(theta * dx, theta * dy, a*dl*dl + b*dl)
170  * AngleAxisd(FS[next_swing_ind].angle - FS[prev_swing_ind].angle, Vector3d::UnitZ())
171  ).matrix();
172 }
173 
174 
175 
185  const int support_number,
186  const double theta,
187  double *left_foot_pos,
188  double *right_foot_pos)
189 {
190  double *swing_foot_pos, *ref_foot_pos;
191  int next_swing_ind, prev_swing_ind;
192  int inclination_sign = 0;
193  footstep& current_step = FS[support_number];
194 
195 
196  if (current_step.type == FS_TYPE_SS_L)
197  {
198  inclination_sign = -1;
199 
200  ref_foot_pos = left_foot_pos;
201  swing_foot_pos = right_foot_pos;
202 
203  prev_swing_ind = getPrevSS (support_number, FS_TYPE_SS_R);
204  next_swing_ind = getNextSS (support_number, FS_TYPE_SS_R);
205  }
206  else
207  {
208  inclination_sign = 1;
209 
210  ref_foot_pos = right_foot_pos;
211  swing_foot_pos = left_foot_pos;
212 
213  prev_swing_ind = getPrevSS (support_number, FS_TYPE_SS_L);
214  next_swing_ind = getNextSS (support_number, FS_TYPE_SS_L);
215  }
216 
217  Matrix4d::Map(ref_foot_pos) = current_step.posture->matrix();
218 
219 
220 
221  Vector4d weighted_binomial_coef;
222  // first number is the weight
223  weighted_binomial_coef(0) = 1 * (1-theta)*(1-theta)*(1-theta);
224  weighted_binomial_coef(1) = bezier_weight_1 * 3*(1-theta)*(1-theta)*theta;
225  weighted_binomial_coef(2) = bezier_weight_2 * 3*(1-theta)*theta*theta;
226  weighted_binomial_coef(3) = 1 * theta*theta*theta;
227 
228 
229  Matrix<double, 3, 4> control_points;
230  control_points.col(0) = FS[prev_swing_ind].posture->translation();
231  control_points.col(3) = FS[next_swing_ind].posture->translation();
232 
233  // In order to reach step_height on z axis in the middle of trajectory,
234  // z coordinates for these two points are derived as follows:
235  //
236  // S = sum of weighted binomial coefficients
237  // 0.5^3 * w0*z0 + 3*0.5^3 * w1*z1 + 3*0.5^3 * w2*z2 + 0.5^3 * w3*z3 = step_height * S
238  // =0 =0
239  // 3*0.5^3 * (w1*z1 + w2*z2) = step_height * S
240  //
241  // lets take z1=z2=z, then:
242  //
243  // z = step_height * S / (3*0.5^3 * (w1+w2))
244 
245  // control points in a frame fixed in the reference points of the steps
246  control_points.col(1).x() = 0.0;
247  control_points.col(1).y() = inclination_sign * bezier_inclination_1;
248  control_points.col(1).z() = step_height*weighted_binomial_coef.sum()
249  / (3*0.5*0.5*0.5 * (bezier_weight_1 + bezier_weight_2));
250  control_points.col(2).x() = 0.0;
251  control_points.col(2).y() = inclination_sign * bezier_inclination_2;
252  control_points.col(2).z() = control_points.col(1).z();
253 
254  // control points in the world frame
255  control_points.col(1) = (*FS[prev_swing_ind].posture) * control_points.col(1);
256  control_points.col(2) = (*FS[next_swing_ind].posture) * control_points.col(2);
257 
258 
259 
260  Transform<double, 3> swing_posture =
261  Translation<double,3>(
262  control_points * weighted_binomial_coef / weighted_binomial_coef.sum())
263  *
264  Quaterniond (AngleAxisd (FS[prev_swing_ind].angle,Vector3d::UnitZ())).slerp (
265  theta,
266  Quaterniond (AngleAxisd (FS[next_swing_ind].angle,Vector3d::UnitZ())));
267 
268  Matrix4d::Map(swing_foot_pos) = swing_posture.matrix();
269 }
double step_height
The maximum height, that can be reached by a swing foot.
Definition: WMG.h:437
int getPrevSS(const int, const fs_type type=FS_TYPE_AUTO)
Returns index of the previous SS.
Definition: WMG_private.cpp:58
void getDSFeetPositions(const int, double *, double *)
Determine position and orientation of feet in DS.
Definition: WMG_private.cpp:90
double bezier_weight_2
Definition: WMG.h:471
fs_type type
type of the step.
Definition: footstep.h:64
void getSSFeetPositions(const int, const double, double *, double *)
Determine position and orientation of feet (parabolic trajectory)
double bezier_inclination_2
Definition: WMG.h:473
Transform< double, 3 > * posture
Definition: footstep.h:70
void getSSFeetPositionsBezier(const int, const double, double *, double *)
Determine position and orientation of feet (using cubic Bezier curves)
Defines a footstep.
Definition: footstep.h:29
Definition: WMG.h:47
int getNextSS(const int, const fs_type type=FS_TYPE_AUTO)
Returns index of the next SS.
Definition: WMG_private.cpp:23
double bezier_weight_1
Definition: WMG.h:470
std::vector< footstep > FS
A vector of footsteps.
Definition: WMG.h:420
double bezier_inclination_1
Definition: WMG.h:472
fs_type
Definition: WMG.h:42