@@ -90,6 +90,7 @@ namespace simple_mpc
9090
9191 com0_ = data_handler_->getData ().com [0 ];
9292 now_ = WALKING;
93+ one_horizon_iterator_ = 0 ;
9394
9495 velocity_base_.setZero ();
9596 next_pose_.setZero ();
@@ -182,6 +183,65 @@ namespace simple_mpc
182183 }
183184 }
184185
186+ void MPC::generateOneHorizon (const std::vector<std::map<std::string, bool >> & contact_states)
187+ {
188+ one_contact_states_ = contact_states;
189+
190+ // Generate contact switch timings
191+ std::map<std::string, bool > previous_contacts;
192+ for (auto const & name : ee_names_)
193+ {
194+ previous_contacts.insert ({name, true });
195+ }
196+
197+ // Generate the model stages for one horizon
198+ for (auto const & state : one_contact_states_)
199+ {
200+ int active_contacts = 0 ;
201+ for (auto const & contact : state)
202+ {
203+ if (contact.second )
204+ active_contacts += 1 ;
205+ }
206+
207+ Eigen::VectorXd force_ref (ocp_handler_->getReferenceForce (0 , ocp_handler_->getModelHandler ().getFootName (0 )));
208+ Eigen::VectorXd force_zero (ocp_handler_->getReferenceForce (0 , ocp_handler_->getModelHandler ().getFootName (0 )));
209+ force_ref.setZero ();
210+ force_zero.setZero ();
211+ force_ref[2 ] = settings_.support_force / active_contacts;
212+
213+ std::map<std::string, pinocchio::SE3> contact_poses;
214+ std::map<std::string, Eigen::VectorXd> force_map;
215+
216+ for (auto const & name : ee_names_)
217+ {
218+ contact_poses.insert ({name, data_handler_->getFootPose (name)});
219+ if (state.at (name))
220+ force_map.insert ({name, force_ref});
221+ else
222+ force_map.insert ({name, force_zero});
223+ }
224+ std::map<std::string, bool > land_contacts;
225+ for (auto const & name : ee_names_)
226+ {
227+ if (!previous_contacts.at (name) and state.at (name))
228+ {
229+ land_contacts.insert ({name, true });
230+ }
231+ else
232+ {
233+ land_contacts.insert ({name, false });
234+ }
235+ }
236+
237+ std::shared_ptr<StageModel> sm =
238+ std::make_shared<StageModel>(ocp_handler_->createStage (state, contact_poses, force_map, land_contacts));
239+ one_horizon_.push_back (sm);
240+ one_horizon_data_.push_back (sm->createData ());
241+ previous_contacts = state;
242+ }
243+ }
244+
185245 void MPC::iterate (const ConstVectorRef & x)
186246 {
187247
@@ -215,6 +275,21 @@ namespace simple_mpc
215275
216276 void MPC::recedeWithCycle ()
217277 {
278+ if (now_ == MOTION)
279+ {
280+ ocp_handler_->getProblem ().replaceStageCircular (*one_horizon_[0 ]);
281+ solver_->cycleProblem (ocp_handler_->getProblem (), one_horizon_data_[0 ]);
282+
283+ rotate_vec_left (one_horizon_);
284+ rotate_vec_left (one_horizon_data_);
285+
286+ one_horizon_iterator_ += 1 ;
287+ if (one_horizon_iterator_ == one_horizon_.size ())
288+ {
289+ one_horizon_iterator_ = 0 ;
290+ now_ = STANDING;
291+ }
292+ }
218293 if (now_ == WALKING or ocp_handler_->getContactSupport (ocp_handler_->getSize () - 1 ) < ee_names_.size ())
219294 {
220295
0 commit comments