32 R_.setZero(preview_horizon_.intervals_.size());
34 for(std::size_t i=0; i < preview_horizon_.intervals_.size(); ++i)
36 R_(i) = preview_horizon_.getRotationMatrix(i).transpose();
55 double T = preview_horizon_.intervals_[0].T_;
56 double base_height = preview_horizon_.intervals_[0].base_height_;
57 double body_height = preview_horizon_.intervals_[0].body_height_;
58 double theta = preview_horizon_.intervals_[0].theta_;
64 base_controls_.head(2),
65 body_controls_.head(2),
83 sol_structure_.reset();
89 formRotationMatrices();
94 std::vector< etools::Matrix3 > As_matrices;
95 std::vector< etools::Vector3 > Bs_matrices;
97 std::vector< etools::Matrix3 > Ad_matrices;
98 std::vector< etools::Vector3 > Bd_matrices;
100 std::vector< etools::Matrix1x3 > Djs_matrices;
101 std::vector< double > Ejs_matrices;
107 As_matrices.resize(mpc_parameters_.preview_horizon_length_);
108 Bs_matrices.resize(mpc_parameters_.preview_horizon_length_);
110 Ad_matrices.resize(mpc_parameters_.preview_horizon_length_);
111 Bd_matrices.resize(mpc_parameters_.preview_horizon_length_);
113 Djs_matrices.resize(mpc_parameters_.preview_horizon_length_);
114 Ejs_matrices.resize(mpc_parameters_.preview_horizon_length_);
116 Dps.
setZero(mpc_parameters_.preview_horizon_length_);
117 Dpd.
setZero(mpc_parameters_.preview_horizon_length_);
120 for (std::size_t i = 0; i < mpc_parameters_.preview_horizon_length_; ++i)
122 double T = preview_horizon_.intervals_[i].T_;
123 double base_height = preview_horizon_.intervals_[i].base_height_;
124 double body_height = preview_horizon_.intervals_[i].body_height_;
125 double base_mass = preview_horizon_.intervals_[i].base_mass_;
126 double body_mass = preview_horizon_.intervals_[i].body_mass_;
129 As_matrices[i] = model.
getAs3(T);
130 Bs_matrices[i] = model.
getBs3(T);
132 Ad_matrices[i] = model.
getAd3(T);
133 Bd_matrices[i] = model.
getBd3(T);
135 Djs_matrices[i] = model.
getDjs3(T);
136 Ejs_matrices[i] = model.
getEjs3(T);
138 Dps(i) = model.
getDps3(base_height, base_mass, body_mass);
139 Dpd(i) = model.
getDpd3(body_height, base_mass, body_mass);
148 condense(Uxs, Uus, As_matrices, Bs_matrices);
149 condense(Uxd, Uud, Ad_matrices, Bd_matrices);
154 condenseOutput(Ojxs, Ojus, Djs_matrices, Ejs_matrices, Uxs, Uus);
163 std::size_t number_of_state_variables = model.
Ns_ * mpc_parameters_.preview_horizon_length_;
168 number_of_state_variables/2,
169 sol_structure_.getNumberOfVariables()/2);
181 S_bmi(0,1).setZero();
182 S_bmi(1,0).setZero();
186 s_.resize(number_of_state_variables);
197 Ap_.
resize(2*mpc_parameters_.preview_horizon_length_, sol_structure_.getNumberOfVariables ());
217 sas_.noalias() = Uxs.selectRowInBlocks(2).getBlockKroneckerProduct(2) * mpc_base_state;
218 Uus.selectRowInBlocks(2).getBlockKroneckerProduct(2).
evaluate(Aas_);
230 sps_.noalias() = Uxs.selectRowInBlocks(0).getBlockKroneckerProduct(2) * mpc_base_state;
231 Uus.selectRowInBlocks(0).getBlockKroneckerProduct(2).
evaluate(Aps_);
245 R_ * ( Uxs.selectRowInBlocks(0).getBlockKroneckerProduct(2) * mpc_base_state
247 Uxd.selectRowInBlocks(0).getBlockKroneckerProduct(2) * mpc_body_state);
248 Apd_.resize(2*mpc_parameters_.preview_horizon_length_, sol_structure_.getNumberOfVariables ());
249 Apd_ << R_ * Uus.selectRowInBlocks(0).getBlockKroneckerProduct(2),
250 - (R_ * Uud.selectRowInBlocks(0).getBlockKroneckerProduct(2));
276 const std::size_t interval_index,
277 const double interval_offset)
279 double base_height = preview_horizon_.intervals_[interval_index].base_height_;
280 double body_height = preview_horizon_.intervals_[interval_index].body_height_;
283 if (0 == interval_index)
289 theta_prev = preview_horizon_.intervals_[interval_index-1].theta_;
291 double theta = theta_prev
292 + (preview_horizon_.intervals_[interval_index].theta_ - theta_prev)
293 * interval_offset / preview_horizon_.intervals_[interval_index].T_;
297 etools::Vector2 base_control;
298 etools::Vector2 body_control;
301 if (interval_index == 0)
303 preceding_cstate = model.getMPCState();
307 preceding_cstate << cstate_profile_.segment((interval_index - 1)*model.
Ns_/2, model.
Ns_/2),
308 cstate_profile_.segment(getPreviewHorizonLength()*model.
Ns_/2
309 + (interval_index - 1)*model.
Ns_/2, model.
Ns_/2);
311 base_control = base_controls_.segment(interval_index*2, 2);
312 body_control = body_controls_.segment(interval_index*2, 2);
318 preview_horizon_.intervals_[interval_index].T_,
321 base_controls_.head(2),
322 body_controls_.head(2),
327 return (model_state);
332 static const std::ptrdiff_t DEFAULT_PREVIEW_HORIZON_SHIFT = -1;
382 solution_is_parsed_ =
false;
393 solution_is_parsed_ =
false;
394 setParameters(mpc_parameters);
405 mpc_parameters_ = mpc_parameters;
419 template <
class t_MotionParameters>
421 update(
const t_MotionParameters &motion_parameters,
425 solution_is_parsed_ =
false;
427 if (preview_horizon_.
form( mpc_parameters_,
431 updateMatrices(model);
439 return (control_status);
451 const std::ptrdiff_t time_shift_ms = DEFAULT_PREVIEW_HORIZON_SHIFT)
455 if (time_shift_ms == DEFAULT_PREVIEW_HORIZON_SHIFT)
478 void shift( std::deque<MotionParameters> &motion_parameters_deque,
479 const std::ptrdiff_t time_shift_ms = DEFAULT_PREVIEW_HORIZON_SHIFT)
481 std::ptrdiff_t tmp_time_shift_ms = time_shift_ms;
482 if (time_shift_ms == DEFAULT_PREVIEW_HORIZON_SHIFT)
489 if (motion_parameters_deque.size() > 0)
498 if (motion_parameters_deque.front().duration_ms_ <= tmp_time_shift_ms)
500 tmp_time_shift_ms -= motion_parameters_deque.front().duration_ms_;
501 motion_parameters_deque.pop_front();
505 motion_parameters_deque.front().duration_ms_ -= tmp_time_shift_ms;
507 if (motion_parameters_deque.front().duration_ms_ < 0)
509 motion_parameters_deque.front().duration_ms_ = 0;
537 template <
class t_MotionParameters>
541 const std::ptrdiff_t time_shift_ms = DEFAULT_PREVIEW_HORIZON_SHIFT)
547 shift(motion_parameters, time_shift_ms);
561 cstate_profile_.noalias() = S_ * solution.
get_x() + s_;
562 cop_profile_.noalias() = Ap_ * solution.
get_x() + sp_;
563 base_jerk_profile_.noalias() = Ajs_ * solution.
get_x().segment(0, sol_structure_.getNumberOfVariables()/2)
569 solution_is_parsed_ =
true;
585 HUMOTO_ASSERT(solution_is_parsed_ ==
false,
"The solution is parsed.");
586 parseSolution(solution);
587 return(initializeNextModelState(model));
601 HUMOTO_ASSERT(solution_is_parsed_ ==
true,
"This function can be called only after the solution is parsed.");
602 return(initializeNextModelState(model));
616 solution_guess.
initialize(sol_structure_, 0.0);
633 solution_guess.
getData(guess_part) = old_solution.
getData(old_part);
645 solution_guess.
getData(guess_part) = old_solution.
getData(old_part);
660 const std::size_t time_instant_ms)
662 HUMOTO_ASSERT(solution_is_parsed_ ==
true,
"This function can be called only after the solution is parsed.");
665 std::size_t time_offset_ms = time_instant_ms;
681 const double time_instant)
683 HUMOTO_ASSERT(solution_is_parsed_ ==
true,
"This function can be called only after the solution is parsed.");
686 double time_offset = time_instant;
689 return(getModelState(model, interval_index, time_offset));
715 const std::string & name =
"mpcmg")
const 719 preview_horizon_.
log(logger, subname);
739 logger.log(
LogEntryName(subname).add(
"base_controls"), base_controls_);
740 logger.log(
LogEntryName(subname).add(
"body_controls"), body_controls_);
742 logger.log(
LogEntryName(subname).add(
"cstate_profile"), cstate_profile_);
743 logger.log(
LogEntryName(subname).add(
"jerk_profile"), base_jerk_profile_);
744 logger.log(
LogEntryName(subname).add(
"cop_profile"), cop_profile_);
std::size_t getNumberOfVariables() const
Get total number of variables in the solution vector.
static const char * BODY_JERK_VARIABLES_ID
void getNextState(humoto::pepper_mpc::ModelState &model_state, const double T, const double Ts, const etools::Vector2 &base_control, const etools::Vector2 &body_control, const double base_height, const double body_height, const double theta) const
Get next state from the current state.
std::size_t preview_horizon_length_
Length of the preview horizon (N)
etools::Matrix3 getAd3(const double T) const
Create intermediate Ad3 matrix.
static const char * BASE_VEL_VARIABLES_ID
void log(humoto::Logger &logger, const LogEntryName &parent=LogEntryName(), const std::string &name="preview_horizon") const
Log.
etools::Matrix1x3 getDps3(const double base_height, const double base_mass, const double body_mass) const
Create Dps3 matrix.
Eigen::VectorBlock< Eigen::VectorXd > getSolutionPart(const std::string &id)
Get part of the solution by its id.
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::ptrdiff_t duration_ms_
#define HUMOTO_GLOBAL_LOGGER_IF_DEFINED
#define HUMOTO_ASSERT(condition, message)
Eigen::VectorBlock< Eigen::VectorXd > getData(const Location &location)
Get data from solution vector.
double HUMOTO_LOCAL convertMillisecondToSecond(const std::size_t milliseconds)
Converts milliseconds to seconds.
Container of the solution.
Represents log entry name.
bool isNonEmpty() const
Checks if the structure is empty or not.
etools::Matrix1x3 getDpd3(const double body_height, const double base_mass, const double body_mass) const
Create Dpd3 matrix.
etools::Vector3 getBd3(const double T) const
Create intermediate Bd3 matrix.
Parameters of the motion.
double getTheta() const
Get theta angle of the current state.
Threaded logger: any data sent to this logger is wrapped in a message and pushed to a queue...
void initialize(const SolutionStructure &sol_structure)
Initialize the solution vector.
std::size_t sampling_time_ms_
Sampling time in milliseconds (T_ms)
etools::Vector6 getMPCBodyState() const
Get body state.
Parameters of the MPC problem.
Location getSolutionPartLocation(const std::string &id) const
Get location of a data in the solution vector.
etools::Vector3 getBs3(const double T) const
Create intermediate Bs3 matrix.
etools::Matrix3 getAs3(const double T) const
Create intermediate As3 matrix.
The root namespace of HuMoTo.
const Eigen::VectorXd & get_x() const
Returns solution vector.
bool form(const MPCParameters &mpc_params, const Model &model, const MotionParameters &motion_parameters)
Form the preview horizon object.
etools::Vector6 getMPCBaseState() const
Get base state.
static const std::ptrdiff_t UNLIMITED_DURATION
double getEjs3(const double T) const
Create intermediate Esc6 matrix of final model.
Preview horizon of an MPC [form_preview_horizon.m].
LogEntryName & add(const char *name)
extends entry name with a subname
Location of a data chunk (offset + length).
etools::Matrix1x3 getDjs3(const double T) const
Create intermediate Dc6 matrix of final model.
Abstract base class for Model Predictive Control problems.