humoto
preview_horizon.h
Go to the documentation of this file.
1 /**
2  @file
3  @author Alexander Sherikov
4  @author Jan Michalczyk
5  @copyright 2014-2017 INRIA. Licensed under the Apache License, Version 2.0.
6  (see @ref LICENSE or http://www.apache.org/licenses/LICENSE-2.0)
7  @brief
8 */
9 
10 #pragma once
11 
12 
13 namespace humoto
14 {
15  namespace pepper_mpc
16  {
17  /**
18  * @brief A helper class defining one interval of a preview horizon
19  */
21  {
22  public:
23  // meter
25  // meter / second
27  // meter / second^2
29  // [lb, ub] meter
31  // meter / second
32  etools::Vector2 base_vel_ref_;
33  // meter
34  etools::Vector2 base_pos_ref_;
35 
36  double base_height_;
37  double body_height_;
38 
39  double base_mass_;
40  double body_mass_;
41 
42  std::size_t T_ms_;
43  double T_;
44 
45  double theta_;
47 
48 
49  public:
50  /**
51  * @brief Default constructor
52  */
54  {
55  base_height_ = 0.0;
56  body_height_ = 0.0;
57 
58  base_mass_ = 0.0;
59  body_mass_ = 0.0;
60 
61  T_ms_ = 0;
62  T_ = 0.0;
63  theta_ = 0.0;
64 
65  etools::unsetMatrix(cop_bounds_);
66  etools::unsetMatrix(nominal_base_velocity_bounds_);
67  etools::unsetMatrix(nominal_base_acceleration_bounds_);
68  etools::unsetMatrix(body_bounds_);
69 
70  etools::unsetMatrix(base_vel_ref_);
71  etools::unsetMatrix(base_pos_ref_);
72  etools::unsetMatrix(rotation_);
73  }
74 
75 
76  /**
77  * @brief Form the preview horizon object
78  *
79  * @param[in] mpc_params
80  * @param[in] model
81  * @param[in] motion_parameters
82  * @param[in] theta
83  *
84  * @return
85  */
86  void initialize(double & theta,
87  const MPCParameters &mpc_params,
88  const MotionParameters &motion_parameters,
89  const Model &model)
90  {
91  T_ms_ = mpc_params.sampling_time_ms_;
92  T_ = mpc_params.getSamplingTime();
93 
94  cop_bounds_ = model.robot_parameters_.getCoPBounds();
95  nominal_base_velocity_bounds_ = model.robot_parameters_.getNominalBaseVelocityBounds();
96  nominal_base_acceleration_bounds_ = model.robot_parameters_.getNominalBaseAccelerationBounds();
97  body_bounds_ = model.robot_parameters_.getBodyBounds();
98 
99  base_height_ = model.getBaseHeight();
100  body_height_ = model.getBodyHeight();
101 
102  base_mass_ = model.getBaseMass();
103  body_mass_ = model.getBodyMass();
104 
105  theta += motion_parameters.getBaseAngularVelocity()*T_;
106  theta_ = theta;
107  rotation_ = Eigen::Rotation2Dd(theta);
108 
109  base_vel_ref_ = rotation_ * motion_parameters.getBaseVelocity();
110  base_pos_ref_ = motion_parameters.getBasePosition();
111  }
112 
113 
114  /**
115  * @brief Log
116  *
117  * @param[in,out] logger logger
118  * @param[in] parent parent
119  * @param[in] name name
120  */
122  const LogEntryName &parent = LogEntryName(),
123  const std::string & name = "preview_interval") const
124  {
125  LogEntryName subname = parent; subname.add(name);
126 
127  logger.log(LogEntryName(subname).add("base_height") , base_height_ );
128  logger.log(LogEntryName(subname).add("body_height") , body_height_ );
129  logger.log(LogEntryName(subname).add("base_mass") , base_mass_ );
130  logger.log(LogEntryName(subname).add("body_mass") , body_mass_ );
131  logger.log(LogEntryName(subname).add("T") , T_ );
132  logger.log(LogEntryName(subname).add("T_ms") , T_ms_ );
133  logger.log(LogEntryName(subname).add("base_vel_ref") , base_vel_ref_);
134  logger.log(LogEntryName(subname).add("base_pos_ref") , base_pos_ref_);
135  logger.log(LogEntryName(subname).add("theta") , theta_ );
136  logger.log(LogEntryName(subname).add("rotation") , rotation_);
137  logger.log(LogEntryName(subname).add("body_bounds"), body_bounds_);
138  logger.log(LogEntryName(subname).add("cop_bounds"), cop_bounds_);
139  logger.log(LogEntryName(subname).add("nominal_base_velocity_bounds"), nominal_base_velocity_bounds_);
140  logger.log(LogEntryName(subname).add("nominal_base_acceleration_bounds"), nominal_base_acceleration_bounds_);
141  }
142  };
143 
144 
145 
146  /**
147  * @brief Preview horizon of an MPC [form_preview_horizon.m]
148  */
150  {
151  public:
152  std::vector<PreviewHorizonInterval> intervals_;
153 
154 
155  public:
156  /**
157  * @brief Form the preview horizon object
158  *
159  * @param[in] mpc_params
160  * @param[in] model
161  * @param[in] motion_parameters
162  *
163  * @return true if successful
164  */
165  bool form( const MPCParameters &mpc_params,
166  const Model &model,
167  const MotionParameters &motion_parameters)
168  {
169  bool preview_horizon_formed = false;
170 
171 
172  if ((motion_parameters.duration_ms_ == MotionParameters::UNLIMITED_DURATION)
173  ||
174  ( static_cast<std::ptrdiff_t>(mpc_params.preview_horizon_length_ * mpc_params.sampling_time_ms_)
175  <= motion_parameters.duration_ms_ ))
176  {
177  double theta = model.getBaseOrientation();
178 
179  intervals_.resize(mpc_params.preview_horizon_length_);
180 
181  for (std::size_t i = 0; i < mpc_params.preview_horizon_length_; ++i)
182  {
183  intervals_[i].initialize(theta, mpc_params, motion_parameters, model);
184  }
185 
186  preview_horizon_formed = true;
187  }
188 
189  return (preview_horizon_formed);
190  }
191 
192 
193  /**
194  * @brief Form the preview horizon object
195  *
196  * @param[in] mpc_params
197  * @param[in] model
198  * @param[in] motion_parameters_deque
199  *
200  * @return true if successful
201  */
202  bool form( const MPCParameters &mpc_params,
203  const Model &model,
204  const std::deque<MotionParameters> &motion_parameters_deque)
205  {
206  bool preview_horizon_formed = false;
207 
208 
209  double theta = model.getBaseOrientation();
210  intervals_.resize(mpc_params.preview_horizon_length_);
211 
212 
213  std::size_t i = 0;
214  std::size_t remainder_ms = 0;
215  for ( std::deque<MotionParameters>::const_iterator it = motion_parameters_deque.begin();
216  it != motion_parameters_deque.end();
217  ++it)
218  {
219  if (it->duration_ms_ == MotionParameters::UNLIMITED_DURATION)
220  {
221  for (; i < mpc_params.preview_horizon_length_; ++i)
222  {
223  intervals_[i].initialize(theta, mpc_params, *it, model);
224  }
225  preview_horizon_formed = true;
226  break;
227  }
228  else
229  {
230  std::size_t number_of_iterations = std::min(
231  static_cast<std::size_t>( (remainder_ms + it->duration_ms_) / mpc_params.sampling_time_ms_),
232  mpc_params.preview_horizon_length_ - i);
233 
234  for (std::size_t j = 0; j < number_of_iterations; ++i, ++j)
235  {
236  intervals_[i].initialize(theta, mpc_params, *it, model);
237  }
238 
239  if (i == mpc_params.preview_horizon_length_)
240  {
241  preview_horizon_formed = true;
242  break;
243  }
244  else
245  {
246  remainder_ms = static_cast<std::size_t>(
247  (remainder_ms + it->duration_ms_) % mpc_params.sampling_time_ms_);
248  }
249  }
250  }
251 
252  return (preview_horizon_formed);
253  }
254 
255 
256  /**
257  * @brief Get preview horizon length
258  *
259  * @return preview horizon length
260  */
261  std::size_t getPreviewHorizonLength() const
262  {
263  return (intervals_.size());
264  }
265 
266 
267  /**
268  * @brief Get nominal base velocity bounds for a given interval
269  *
270  * @param[in] interval_index
271  *
272  * @return 2d matrix [x_base_vel, y_base_vel]
273  */
274  etools::Matrix2 getNominalBaseVelocityBounds(const std::size_t interval_index) const
275  {
276  return (intervals_[interval_index].nominal_base_velocity_bounds_);
277  }
278 
279 
280  /**
281  * @brief Get nominal base acceleration bounds for a given interval
282  *
283  * @param[in] interval_index
284  *
285  * @return 2d matrix [x_base_acc, y_base_acc]
286  */
287  etools::Matrix2 getNominalBaseAccelerationBounds(const std::size_t interval_index) const
288  {
289  return (intervals_[interval_index].nominal_base_acceleration_bounds_);
290  }
291 
292 
293  /**
294  * @brief Get body bounds
295  *
296  * @param[in] interval_index
297  *
298  * @return 2d matrix [lb, ub]
299  */
300  etools::Matrix2 getBodyBounds(const std::size_t interval_index) const
301  {
302  return (intervals_[interval_index].body_bounds_);
303  }
304 
305 
306  /**
307  * @brief Get CoP bounds for given interval
308  *
309  * @param[in] interval_index
310  *
311  * @return 2d matrix [lb, ub]
312  */
313  etools::Matrix2 getCoPBounds(const std::size_t interval_index) const
314  {
315  return (intervals_[interval_index].cop_bounds_);
316  }
317 
318 
319  /**
320  * @brief Get base reference velocity
321  *
322  * @param[in] interval_index
323  *
324  * @return 2d vector [base_vel_ref_x, base_vel_ref_y]
325  */
326  etools::Vector2 getBaseReferenceVelocity(const std::size_t interval_index) const
327  {
328  return (intervals_[interval_index].base_vel_ref_);
329  }
330 
331 
332  /**
333  * @brief Get base reference position
334  *
335  * @param[in] interval_index
336  *
337  * @return 2d vector [base_pos_ref_x, base_pos_ref_y]
338  */
339  etools::Vector2 getBaseReferencePosition(const std::size_t interval_index) const
340  {
341  return (intervals_[interval_index].base_pos_ref_);
342  }
343 
344 
345  /**
346  * @brief Get orientation of the support corresponding to the given interval
347  *
348  * @param[in] interval_index
349  *
350  * @return 2d rotation matrix
351  */
352  etools::Matrix2 getRotationMatrix(const std::size_t interval_index) const
353  {
354  return (intervals_[interval_index].rotation_);
355  }
356 
357 
358  /**
359  * @brief Finds interval which contains the time instant with the given
360  * offset from the beginning of the preview horizon.
361  *
362  * @param[in,out] offset_ms input: offset within the preview horizon
363  * output: offset within the interval
364  *
365  * @return interval index
366  */
367  std::size_t getIntervalIndexByTimeOffset(std::size_t & offset_ms) const
368  {
369  for (std::size_t interval_index = 0; interval_index < intervals_.size(); ++interval_index)
370  {
371  std::size_t interval_duration_ms = intervals_[interval_index].T_ms_;
372 
373  if (offset_ms > interval_duration_ms)
374  {
375  offset_ms -= interval_duration_ms;
376  }
377  else
378  {
379  return (interval_index);
380  }
381  }
382 
383  HUMOTO_THROW_MSG("The requested time offset is outside of the preview horizon.");
384  }
385 
386 
387  /**
388  * @brief Finds interval which contains the time instant with the given
389  * offset from the beginning of the preview horizon.
390  *
391  * @param[in,out] offset input: offset within the preview horizon
392  * output: offset within the interval
393  *
394  * @return interval index
395  */
396  std::size_t getIntervalIndexByTimeOffset(double & offset) const
397  {
398  for (std::size_t interval_index = 0; interval_index < intervals_.size(); ++interval_index)
399  {
400  double interval_duration = intervals_[interval_index].T_;
401 
402  if (offset > interval_duration)
403  {
404  offset -= interval_duration;
405  }
406  else
407  {
408  return (interval_index);
409  }
410  }
411 
412  HUMOTO_THROW_MSG("The requested time offset is outside of the preview horizon.");
413  }
414 
415 
416  /**
417  * @brief Log
418  *
419  * @param[in,out] logger logger
420  * @param[in] parent parent
421  * @param[in] name name
422  */
424  const LogEntryName &parent = LogEntryName(),
425  const std::string & name = "preview_horizon") const
426  {
427  LogEntryName subname = parent;
428  subname.add(name).add("interval");
429 
430  // intervals
431  for (std::size_t i = 0; i < intervals_.size(); ++i)
432  {
433  intervals_[i].log(logger, LogEntryName(subname).add(i), "");
434  }
435  }
436  };
437  } // end namespace pepper_mpc
438 }// end namespace humoto
etools::Vector2 getBaseVelocity() const
Get base reference velocity.
Definition: common.h:246
std::size_t preview_horizon_length_
Length of the preview horizon (N)
Definition: common.h:313
double getBaseAngularVelocity() const
Get theta increment.
Definition: common.h:268
double getBodyHeight() const
Get body height.
Definition: model.h:300
etools::Matrix2 getBodyBounds() const
Get respective bounds.
Definition: common.h:153
#define HUMOTO_LOCAL
Definition: export_import.h:26
void log(humoto::Logger &logger, const LogEntryName &parent=LogEntryName(), const std::string &name="preview_horizon") const
Log.
void log(humoto::Logger &logger, const LogEntryName &parent=LogEntryName(), const std::string &name="preview_interval") const
Log.
std::size_t getIntervalIndexByTimeOffset(std::size_t &offset_ms) const
Finds interval which contains the time instant with the given offset from the beginning of the previe...
std::size_t getPreviewHorizonLength() const
Get preview horizon length.
#define HUMOTO_GLOBAL_LOGGER_IF_DEFINED
Definition: logger.h:997
std::size_t getIntervalIndexByTimeOffset(double &offset) const
Finds interval which contains the time instant with the given offset from the beginning of the previe...
#define HUMOTO_THROW_MSG(s)
HUMOTO_THROW_MSG throws an error message concatenated with the name of the function (if supported)...
Represents log entry name.
Definition: logger.h:169
etools::Matrix2 getNominalBaseAccelerationBounds() const
Get respective bounds.
Definition: common.h:147
double getBaseMass() const
Get base mass.
Definition: model.h:334
etools::Matrix2 getBodyBounds(const std::size_t interval_index) const
Get body bounds.
etools::Matrix2 getNominalBaseAccelerationBounds(const std::size_t interval_index) const
Get nominal base acceleration bounds for a given interval.
bool form(const MPCParameters &mpc_params, const Model &model, const std::deque< MotionParameters > &motion_parameters_deque)
Form the preview horizon object.
Parameters of the motion.
Definition: common.h:176
void unsetMatrix(Eigen::DenseBase< t_Derived > &matrix)
Unset matrix (initialize to NaN)
Definition: eigentools.h:178
etools::Matrix2 getCoPBounds() const
Get respective bounds.
Definition: common.h:135
Threaded logger: any data sent to this logger is wrapped in a message and pushed to a queue...
Definition: logger.h:555
std::size_t sampling_time_ms_
Sampling time in milliseconds (T_ms)
Definition: common.h:316
Parameters of the MPC problem.
Definition: common.h:279
double getBaseOrientation() const
Get base orientation.
Definition: model.h:345
double getBaseHeight() const
Get base height.
Definition: model.h:311
A helper class defining one interval of a preview horizon.
etools::Matrix2 getNominalBaseVelocityBounds(const std::size_t interval_index) const
Get nominal base velocity bounds for a given interval.
The root namespace of HuMoTo.
Definition: config.h:12
humoto::pepper_mpc::RobotParameters robot_parameters_
robot parameters
Definition: model.h:38
std::vector< PreviewHorizonInterval > intervals_
bool form(const MPCParameters &mpc_params, const Model &model, const MotionParameters &motion_parameters)
Form the preview horizon object.
static const std::ptrdiff_t UNLIMITED_DURATION
Definition: common.h:190
etools::Vector2 getBaseReferenceVelocity(const std::size_t interval_index) const
Get base reference velocity.
etools::Matrix2 getRotationMatrix(const std::size_t interval_index) const
Get orientation of the support corresponding to the given interval.
etools::Matrix2 getNominalBaseVelocityBounds() const
Get respective bounds.
Definition: common.h:141
Preview horizon of an MPC [form_preview_horizon.m].
LogEntryName & add(const char *name)
extends entry name with a subname
Definition: logger.h:232
etools::Vector2 getBasePosition() const
Get base reference position.
Definition: common.h:257
double getBodyMass() const
Get body mass.
Definition: model.h:323
void initialize(double &theta, const MPCParameters &mpc_params, const MotionParameters &motion_parameters, const Model &model)
Form the preview horizon object.
etools::Vector2 getBaseReferencePosition(const std::size_t interval_index) const
Get base reference position.
EIGENTOOLS_CONSTANT_SIZE_MATRIX Matrix2
Definition: eigentools.h:76
double getSamplingTime() const
Get sampling time in seconds.
Definition: common.h:360
etools::Matrix2 getCoPBounds(const std::size_t interval_index) const
Get CoP bounds for given interval.