humoto
preview_horizon.h
Go to the documentation of this file.
1 /**
2  @file
3  @author Alexander Sherikov
4  @author Don Joven Agravante
5  @author Jan Michalczyk
6  @copyright 2014-2017 INRIA, 2014-2015 CNRS. Licensed under the Apache
7  License, Version 2.0. (see @ref LICENSE or http://www.apache.org/licenses/LICENSE-2.0)
8  @brief
9 */
10 
11 #pragma once
12 
13 
14 namespace humoto
15 {
16  namespace wpg04
17  {
18  /**
19  * @brief A class representing a "state" of the walk
20  */
22  {
23  public:
24  etools::Vector2 cvel_ref_;
25  double theta_;
26 
28  etools::Vector2 R_cvel_ref_;
29  double step_height_;
30 
33 
34 
35 
36  public:
37  /**
38  * @brief Default constructor
39  */
41  {
42  theta_ = 0.0;
43  step_height_ = 0.0;
44 
45  etools::unsetMatrix(cvel_ref_);
46  etools::unsetMatrix(rotation_);
47  etools::unsetMatrix(R_cvel_ref_);
48 
49  etools::unsetMatrix(fd_bounds_);
50  etools::unsetMatrix(cop_bounds_);
51  }
52 
53 
54  /**
55  * @brief Copy stance info
56  *
57  * @param[in] stance
58  *
59  * @return this
60  */
62  {
63  humoto::walking::Stance::operator=(stance);
64  return (*this);
65  }
66 
67 
68  /**
69  * @brief Log
70  *
71  * @param[in,out] logger logger
72  * @param[in] parent parent
73  * @param[in] name name
74  */
76  const LogEntryName &parent = LogEntryName(),
77  const std::string &name = "walk_state") const
78  {
79  LogEntryName subname = parent;
80  subname.add(name);
81 
82  logger.log(LogEntryName(subname).add("theta") , theta_ );
83  logger.log(LogEntryName(subname).add("step_height"), step_height_);
84 
85  logger.log(LogEntryName(subname).add("cvel_ref") , cvel_ref_);
86  logger.log(LogEntryName(subname).add("rotation") , rotation_);
87  logger.log(LogEntryName(subname).add("R_cvel_ref"), R_cvel_ref_);
88  logger.log(LogEntryName(subname).add("fd_bounds") , fd_bounds_);
89  logger.log(LogEntryName(subname).add("cop_bounds"), cop_bounds_);
90 
91  humoto::walking::Stance::log(logger, subname, "stance");
92  }
93  };
94 
95 
96 
97  /**
98  * @brief A helper class defining one interval of a preview horizon
99  */
101  {
102  public:
103  std::size_t state_index_; /// in TDS points to the next SS
104  etools::Vector2 cvel_ref_;
105  double com_height_;
106  double omega_;
107  double T_;
108  std::size_t T_ms_;
109 
110 
111  public:
112  /**
113  * @brief Log
114  *
115  * @param[in,out] logger logger
116  * @param[in] parent parent
117  * @param[in] name name
118  */
120  const LogEntryName &parent = LogEntryName(),
121  const std::string &name = "preview_interval") const
122  {
123  LogEntryName subname = parent;
124  subname.add(name);
125 
126  logger.log(LogEntryName(subname).add("state_index") , state_index_);
127  logger.log(LogEntryName(subname).add("omega") , omega_ );
128  logger.log(LogEntryName(subname).add("T") , T_ );
129  logger.log(LogEntryName(subname).add("cvel_ref") , cvel_ref_ );
130  }
131  };
132 
133 
134 
135  /**
136  * @brief Preview horizon of an MPC [form_preview_horizon.m]
137  */
139  {
140  public:
141  std::vector<std::size_t> variable_steps_indices_;
142 
143  std::vector<PreviewHorizonInterval> intervals_;
144  std::vector<WalkState> walk_states_;
145 
146 
147  public:
148  bool form(const MPCParameters &mpc_params,
149  const Model &model,
151  const WalkParameters &walk_parameters);
152 
153  std::size_t getNumberOfVariableSteps() const;
154 
155  void log(humoto::Logger &, const LogEntryName &, const std::string &) const;
156 
157 
158  /**
159  * @brief Get CoP bounds
160  *
161  * @param[in] interval_index
162  *
163  * @return 2d matrix [lb, ub]
164  */
165  etools::Matrix2 getCoPBounds(const std::size_t interval_index) const
166  {
167  std::size_t state_index = intervals_[interval_index].state_index_;
168  return (walk_states_[state_index].cop_bounds_);
169  }
170 
171 
172  /**
173  * @brief Get bounds on foot position
174  *
175  * @param[in] var_support_index index of a variable step in the preview horizon
176  *
177  * @return 2d matrix [lb, ub]
178  */
179  etools::Matrix2 getFootPositionBounds(const std::size_t var_support_index) const
180  {
181  std::size_t interval_index = variable_steps_indices_[var_support_index];
182  std::size_t state_index = intervals_[interval_index].state_index_;
183  return (walk_states_[state_index].fd_bounds_);
184  }
185 
186 
187  /**
188  * @brief Get orientation of the support corresponding to the given interval
189  *
190  * @param[in] interval_index
191  *
192  * @return 2d rotation matrix
193  */
194  etools::Matrix2 getRotationMatrix(const std::size_t interval_index) const
195  {
196  std::size_t state_index = intervals_[interval_index].state_index_;
197  return (walk_states_[state_index].rotation_);
198  }
199 
200 
201  /**
202  * @brief Get walk state corresponding to the given interval
203  *
204  * @param[in] interval_index
205  *
206  * @return walk state
207  */
208  const WalkState & getWalkState(const std::size_t interval_index) const
209  {
210  std::size_t state_index = intervals_[interval_index].state_index_;
211  return (walk_states_[state_index]);
212  }
213 
214 
215  private:
216  void getConstraints(humoto::wpg04::WalkState &state,
217  const Model &model);
218 
219 
220  void previewStates( const Model &model,
222  const WalkParameters &walk_parameters,
223  const std::size_t preview_duration);
224  };
225 
226 
227 
228  /**
229  * @brief Preview a sequence of walk states with velocities, rotations etc.
230  *
231  * @param[in] model
232  * @param[in] stance_fsm
233  * @param[in] walk_parameters
234  * @param[in] preview_duration
235  */
238  const WalkParameters &walk_parameters,
239  const std::size_t preview_duration)
240  {
241  std::vector<humoto::walking::Stance> stances;
242 
243  stances = stance_fsm.previewStances(preview_duration);
244 
247  double ds_theta = (lss_theta + rss_theta) / 2.;
248 
249  walk_states_.resize(stances.size());
250  for(std::size_t i = 0; i < stances.size(); ++i)
251  {
252  WalkState state;
253  state = stances.at(i);
254 
255  switch(state.type_)
256  {
258  state.theta_ = lss_theta;
259  state.cvel_ref_ = walk_parameters.com_velocity_;
260  break;
261 
263  state.theta_ = rss_theta;
264  state.cvel_ref_ = walk_parameters.com_velocity_;
265  break;
266 
268  state.theta_ = ds_theta;
270  {
271  state.cvel_ref_ = walk_parameters.first_stance_com_velocity_;
272  }
274  {
275  state.cvel_ref_ = walk_parameters.last_stance_com_velocity_;
276  }
277  else
278  {
279  HUMOTO_THROW_MSG("Unsupported stance subtype.");
280  }
281  break;
282 
284  state.cvel_ref_ = walk_parameters.com_velocity_;
285  state.theta_ = ds_theta;
286  if((stances.at(i + 1).type_ == humoto::walking::StanceType::RSS) &&
288  {
289  rss_theta = lss_theta + walk_parameters.theta_increment_;
290  state.theta_ = rss_theta;
291  }
292  if((stances.at(i + 1).type_ == humoto::walking::StanceType::LSS) &&
294  {
295  lss_theta = rss_theta + walk_parameters.theta_increment_;
296  state.theta_ = lss_theta;
297  }
298  if((stances.at(i + 1).type_ == humoto::walking::StanceType::DS) &&
300  {
301  state.cvel_ref_ = walk_parameters.last_stance_com_velocity_;
302  state.theta_ = rss_theta;
303  ds_theta = rss_theta;
304  }
305  if((stances.at(i + 1).type_ == humoto::walking::StanceType::DS) &&
307  {
308  state.cvel_ref_ = walk_parameters.last_stance_com_velocity_;
309  state.theta_ = lss_theta;
310  ds_theta = lss_theta;
311  }
312  break;
313 
314  default :
315  HUMOTO_THROW_MSG("Unsupported stance type.");
316  break;
317  }
318  state.rotation_ = Eigen::Rotation2Dd(state.theta_);
319  state.R_cvel_ref_.noalias() = state.rotation_ * state.cvel_ref_;
320  state.step_height_ = 0.;
321 
323  {
324  getConstraints(state, model);
325  }
326  walk_states_[i] = state;
327  }
328  }
329 
330 
331 
332  /**
333  * @brief Returns number of variable steps in the preview.
334  *
335  * @return number of variable steps in the preview
336  */
338  {
339  return (variable_steps_indices_.size());
340  }
341 
342 
343 
344  /**
345  * @brief Form the preview horizon object
346  *
347  * @param[in] mpc_params
348  * @param[in] model
349  * @param[in] stance_fsm
350  * @param[in] walk_parameters
351  *
352  * @return
353  */
354  bool PreviewHorizon::form(const MPCParameters &mpc_params,
355  const Model &model,
357  const WalkParameters &walk_parameters)
358  {
359  bool preview_horizon_formed = true;
360 
361  // Length of the preview horizon (N)
362  std::size_t preview_horizon_length_ = mpc_params.preview_horizon_length_;
363  std::size_t sampling_time_ms_ = mpc_params.sampling_time_ms_;
364  std::size_t walk_index = 0;
365  std::size_t num_intervals_left = 0;
366 
367  //is_new_sample_ = stance_fsm.is_new_sample_;
368  previewStates(model, stance_fsm, walk_parameters, preview_horizon_length_*sampling_time_ms_);
369 
370  if(walk_states_.empty())
371  {
372  preview_horizon_formed = false;
373  return (preview_horizon_formed);
374  }
375 
376  variable_steps_indices_.clear();
377 
378  std::vector<std::size_t> support_indices;
379 
380  intervals_.resize(preview_horizon_length_);
381 
382  std::size_t interval_index = 0;
383  while(interval_index < preview_horizon_length_)
384  {
385  WalkState state = walk_states_.at(walk_index);
386 
387  PreviewHorizonInterval interval;
388  interval.cvel_ref_ = state.R_cvel_ref_;
389  interval.com_height_ = model.getCoMHeight();
390  interval.omega_ = model.getOmega(interval.com_height_);
391 
392  support_indices.push_back(interval_index);
393 
394  if (walk_index == 0)
395  {
396  // current sampling interval (the 1st in the preview window)
398  {
399  interval.T_ms_ = state.duration_ms_;
400  interval.T_ = convertMillisecondToSecond(interval.T_ms_);
401 
402  ++walk_index;
403  state = walk_states_.at(walk_index);
404  num_intervals_left = floor(state.duration_ms_ / mpc_params.sampling_time_ms_);
405  }
406  else
407  {
408  interval.T_ms_ = state.duration_ms_ % mpc_params.sampling_time_ms_;
409  interval.T_ = convertMillisecondToSecond(interval.T_ms_);
410  num_intervals_left = floor(state.duration_ms_ / mpc_params.sampling_time_ms_);
411 
412  if ((state.duration_ms_ % mpc_params.sampling_time_ms_) == 0)
413  {
414  interval.T_ms_ = mpc_params.sampling_time_ms_;
415  interval.T_ = convertMillisecondToSecond(interval.T_ms_);
416 
417  --num_intervals_left;
418  }
419  }
420 
421  interval.state_index_ = walk_index;
422  intervals_[interval_index] = interval;
423  ++interval_index;
424  }
425  else
426  {
427  HUMOTO_ASSERT(humoto::walking::StanceType::TDS == state.type_, "Unexpected state type!");
428 
429  // new variable footstep
430  variable_steps_indices_.push_back(interval_index);
431 
432  // transitional DS
433  interval.T_ms_ = mpc_params.tds_sampling_time_ms_;
434  interval.T_ = convertMillisecondToSecond(interval.T_ms_);
435 
436  // next SS
437  ++walk_index;
438  state = walk_states_.at(walk_index);
439 
440  interval.state_index_ = walk_index;
441  intervals_[interval_index] = interval;
442  ++interval_index;
443 
444  num_intervals_left = floor(state.duration_ms_ / mpc_params.sampling_time_ms_);
445  }
446 
447  interval.T_ms_ = mpc_params.sampling_time_ms_;
448  interval.T_ = convertMillisecondToSecond(interval.T_ms_);
449 
450  // fill the other intervals
451  std::size_t max_index = std::min(preview_horizon_length_, interval_index + num_intervals_left);
452  for(std::size_t i = interval_index; i < max_index; ++i)
453  {
454  intervals_[i] = interval;
455  }
456 
457  interval_index += num_intervals_left;
458  ++walk_index;
459  }
460 
461  return (preview_horizon_formed);
462  }
463 
464 
465  /**
466  * @brief Get constraints for each state
467  *
468  * @param[in,out] state
469  * @param[in] model
470  */
472  const Model &model)
473  {
475  {
476  state.fd_bounds_.setZero();
477  }
478  else
479  {
480  switch(state.type_)
481  {
483  switch(state.previous_nontds_stance_type_)
484  {
487  break;
490  break;
491  default:
492  HUMOTO_THROW_MSG("unexpected support type");
493  break;
494  }
495  break;
496 
498  switch(state.previous_nontds_stance_type_)
499  {
502  break;
505  break;
506  default:
507  HUMOTO_THROW_MSG("unexpected support type");
508  break;
509  }
510  break;
511 
513  switch(state.previous_nontds_stance_type_)
514  {
517  break;
520  break;
521  default:
522  HUMOTO_THROW_MSG("unexpected support type");
523  break;
524  }
525  break;
526 
527  default:
528  HUMOTO_THROW_MSG("unexpected support type");
529  break;
530  }
531  }
532 
534  {
535  state.cop_bounds_ = model.getADSCoPBounds();
536  }
537  else
538  {
539  state.cop_bounds_ = model.getSSCoPBounds();
540  }
541  }
542 
543 
544  /**
545  * @brief Log
546  *
547  * @param[in,out] logger logger
548  * @param[in] parent parent
549  * @param[in] name name
550  */
552  const LogEntryName &parent = LogEntryName(),
553  const std::string &name = "preview_horizon") const
554  {
555  LogEntryName subname = parent;
556  LogEntryName subname_loop;
557  subname.add(name);
558 
559 
560  // variable_steps_indices
561  logger.log(LogEntryName(subname).add("variable_steps_indices"), variable_steps_indices_);
562 
563 
564  // intervals
565  subname_loop = subname;
566  subname_loop.add("interval");
567  for (std::size_t i = 0; i < intervals_.size(); ++i)
568  {
569  intervals_[i].log(logger, LogEntryName(subname_loop).add(i), "");
570  }
571 
572 
573  // states
574  subname_loop = subname;
575  subname_loop.add("state");
576  for (std::size_t i = 0; i < walk_states_.size(); ++i)
577  {
578  walk_states_[i].log(logger, LogEntryName(subname_loop).add(i), "");
579  }
580  }
581  } // end namespace wpg04
582 }// end namespace humoto
humoto::rigidbody::RigidBodyState getFootState(const humoto::LeftOrRight::Type left_or_right) const
Returns current foot state.
Definition: model.h:119
void log(humoto::Logger &logger, const LogEntryName &parent=LogEntryName(), const std::string &name="preview_interval") const
Log.
etools::Matrix2 getFootPositionBounds(const std::size_t var_support_index) const
Get bounds on foot position.
void previewStates(const Model &model, const humoto::walking::StanceFiniteStateMachine &stance_fsm, const WalkParameters &walk_parameters, const std::size_t preview_duration)
Preview a sequence of walk states with velocities, rotations etc.
std::size_t preview_horizon_length_
Length of the preview horizon (N)
Definition: common.h:144
etools::Vector2 com_velocity_
Definition: common.h:41
#define HUMOTO_LOCAL
Definition: export_import.h:26
Preview horizon of an MPC [form_preview_horizon.m].
WalkState & operator=(const humoto::walking::Stance &stance)
Copy stance info.
#define HUMOTO_GLOBAL_LOGGER_IF_DEFINED
Definition: logger.h:997
#define HUMOTO_ASSERT(condition, message)
void log(humoto::Logger &logger, const LogEntryName &parent=LogEntryName(), const std::string &name="walk_state") const
Log.
Parameters of an MPC problem. [set_parameters_mpc.m].
Definition: common.h:80
double HUMOTO_LOCAL convertMillisecondToSecond(const std::size_t milliseconds)
Converts milliseconds to seconds.
Definition: time.h:22
etools::Matrix2 getCoPBounds(const std::size_t interval_index) const
Get CoP bounds.
#define HUMOTO_THROW_MSG(s)
HUMOTO_THROW_MSG throws an error message concatenated with the name of the function (if supported)...
etools::Vector2 last_stance_com_velocity_
Definition: common.h:43
Represents log entry name.
Definition: logger.h:169
static double getOmega(const double com_height)
[initialize_model.m]
Definition: model.h:25
etools::Vector2 first_stance_com_velocity_
Definition: common.h:42
etools::Vector2 cvel_ref_
in TDS points to the next SS
etools::Matrix2 cop_bounds_
std::size_t getNumberOfVariableSteps() const
Returns number of variable steps in the preview.
Class containing options of the walking pattern generator.
Definition: common.h:24
etools::Vector2 R_cvel_ref_
void unsetMatrix(Eigen::DenseBase< t_Derived > &matrix)
Unset matrix (initialize to NaN)
Definition: eigentools.h:178
A helper class defining one interval of a preview horizon.
WalkState()
Default constructor.
Threaded logger: any data sent to this logger is wrapped in a message and pushed to a queue...
Definition: logger.h:555
bool form(const MPCParameters &mpc_params, const Model &model, const humoto::walking::StanceFiniteStateMachine &stance_fsm, const WalkParameters &walk_parameters)
Form the preview horizon object.
etools::Matrix2 getADSCoPBounds() const
Return bounds on position of the CoP in ADS / SS.
std::vector< PreviewHorizonInterval > intervals_
void getConstraints(humoto::wpg04::WalkState &state, const Model &model)
Get constraints for each state.
void log(humoto::Logger &logger, const LogEntryName &parent=LogEntryName(), const std::string &name="stance") const
Log.
double getCoMHeight() const
Get CoM height.
Definition: model.h:142
std::vector< Stance > previewStances(const std::size_t preview_duration_ms) const
Preview sequence of Stances of the FSM.
etools::Matrix2 rotation_
const WalkState & getWalkState(const std::size_t interval_index) const
Get walk state corresponding to the given interval.
The root namespace of HuMoTo.
Definition: config.h:12
etools::Vector2 cvel_ref_
void log(humoto::Logger &, const LogEntryName &, const std::string &) const
Log.
etools::Matrix2 getRotationMatrix(const std::size_t interval_index) const
Get orientation of the support corresponding to the given interval.
A class representing a "state" of the walk.
etools::Matrix2 getSSCoPBounds() const
Return bounds on position of the CoP in ADS / SS.
etools::Matrix2 fd_bounds_
etools::Matrix2 getFootBounds(const humoto::LeftOrRight::Type left_or_right, const FootBoundsType::Type bounds_type) const
Get bounds on position of a foot.
std::vector< WalkState > walk_states_
Finite state machine for walking. [initialize_contact_walk_fsm.m].
LogEntryName & add(const char *name)
extends entry name with a subname
Definition: logger.h:232
std::size_t sampling_time_ms_
Sampling time in milliseconds (T_ms)
Definition: common.h:147
std::size_t tds_sampling_time_ms_
Sampling time of a transitional double support in milliseconds (Ttds_ms)
Definition: common.h:154
std::vector< std::size_t > variable_steps_indices_
EIGENTOOLS_CONSTANT_SIZE_MATRIX Matrix2
Definition: eigentools.h:76