67     Eigen::Matrix<Eigen::Vector3d, 4, 1> desired_f_pos;
 
   68     Eigen::Matrix<Eigen::Vector3d, 4, 1> desired_f_vel;
 
   69     Eigen::Matrix<Eigen::Vector3d, 4, 1> desired_f_acc;
 
   72     Eigen::Matrix<double, 12, 1> desired_tau;
 
   75     std_msgs::Float64MultiArray base_pose_cmd_msg;
 
   76     std_msgs::Float64MultiArray base_twist_cmd_msg;
 
   78     base_pose_cmd_msg.data.resize(6);
 
   79     base_twist_cmd_msg.data.resize(6);
 
   82     ros::Rate loop_rate(200);
 
   88         desired_base_pos << 0,
 
   91         desired_base_vel.setZero();
 
   92         desired_base_acc.setZero();
 
   93         desired_base_ori.setZero();
 
   95         desired_f_pos = this->
fPos;
 
   97         for (
int i = 0; i < 4; i++)
 
   99             desired_f_vel(i).setZero();
 
  100             desired_f_acc(i).setZero();
 
  103         auto start = std::chrono::steady_clock::now();
 
  118         auto end = std::chrono::steady_clock::now();
 
  120         std::chrono::duration<double, std::micro> diff = end - start;
 
  122         ROS_INFO_STREAM(
"HO run-time: " << diff.count() << 
" microseconds. \n");
 
  130         base_pose_cmd_msg.data[0] = desired_base_pos(0);
 
  131         base_pose_cmd_msg.data[1] = desired_base_pos(1);
 
  132         base_pose_cmd_msg.data[2] = desired_base_pos(2);
 
  133         base_pose_cmd_msg.data[3] = desired_base_ori(0);
 
  134         base_pose_cmd_msg.data[4] = desired_base_ori(1);
 
  135         base_pose_cmd_msg.data[5] = desired_base_ori(2);
 
  138         base_twist_cmd_msg.data[0] = desired_base_vel(0);
 
  139         base_twist_cmd_msg.data[1] = desired_base_vel(1);
 
  140         base_twist_cmd_msg.data[2] = desired_base_vel(2);
 
  141         base_twist_cmd_msg.data[3] = 0;
 
  142         base_twist_cmd_msg.data[4] = 0;
 
  143         base_twist_cmd_msg.data[5] = 0;
 
  161     Eigen::Matrix<Eigen::Vector3d, 4, 1> desired_f_pos;
 
  162     Eigen::Matrix<Eigen::Vector3d, 4, 1> desired_f_vel;
 
  163     Eigen::Matrix<Eigen::Vector3d, 4, 1> desired_f_acc;
 
  166     Eigen::Matrix<double, 12, 1> desired_tau;
 
  169     std_msgs::Float64MultiArray base_pose_cmd_msg;
 
  170     std_msgs::Float64MultiArray base_twist_cmd_msg;
 
  172     base_pose_cmd_msg.data.resize(6);
 
  173     base_twist_cmd_msg.data.resize(6);
 
  176     ros::Rate loop_rate(200);
 
  185         desired_base_pos << 0,
 
  188                             0.05 * std::sin(timefactor*ros::Time::now().toSec()) + 0.2; 
 
  189         desired_base_vel.setZero();
 
  190         desired_base_vel << 0,
 
  192                             timefactor * 0.05 * std::cos(timefactor*ros::Time::now().toSec());
 
  193         desired_base_acc.setZero();
 
  194         desired_base_acc << 0,
 
  196                             - timefactor * timefactor * 0.05 * std::sin(timefactor*ros::Time::now().toSec());
 
  197         desired_base_ori.setZero();
 
  199         desired_base_ori(0) = 0.3 * std::cos(timefactor*ros::Time::now().toSec());
 
  200         desired_base_ori(2) = 0.15 * std::sin(timefactor*ros::Time::now().toSec());
 
  202         desired_f_pos = this->
fPos;
 
  204         for (
int i = 0; i < 4; i++)
 
  206             desired_f_vel(i).setZero();
 
  207             desired_f_acc(i).setZero();
 
  213         auto start = std::chrono::steady_clock::now();
 
  228         auto end = std::chrono::steady_clock::now();
 
  230         std::chrono::duration<double, std::micro> diff = end - start;
 
  232         ROS_INFO_STREAM(
"HO run-time: " << diff.count() << 
" microseconds. \n");
 
  240         base_pose_cmd_msg.data[0] = desired_base_pos(0);
 
  241         base_pose_cmd_msg.data[1] = desired_base_pos(1);
 
  242         base_pose_cmd_msg.data[2] = desired_base_pos(2);
 
  243         base_pose_cmd_msg.data[3] = desired_base_ori(0);
 
  244         base_pose_cmd_msg.data[4] = desired_base_ori(1);
 
  245         base_pose_cmd_msg.data[5] = desired_base_ori(2);
 
  248         base_twist_cmd_msg.data[0] = desired_base_vel(0);
 
  249         base_twist_cmd_msg.data[1] = desired_base_vel(1);
 
  250         base_twist_cmd_msg.data[2] = desired_base_vel(2);
 
  251         base_twist_cmd_msg.data[3] = 0;
 
  252         base_twist_cmd_msg.data[4] = 0;
 
  253         base_twist_cmd_msg.data[5] = 0;
 
  267                                                                                        const Eigen::Matrix<double, 3, 1> &_desired_base_vel,
 
  268                                                                                        const Eigen::Matrix<double, 3, 1> &_desired_base_acc,
 
  269                                                                                        const Eigen::Matrix<double, 3, 1> &_desired_base_ori,
 
  270                                                                                        const Eigen::Matrix<Eigen::Vector3d, 4, 1> &_desired_f_pos,
 
  271                                                                                        const Eigen::Matrix<Eigen::Vector3d, 4, 1> &_desired_f_vel,
 
  272                                                                                        const Eigen::Matrix<Eigen::Vector3d, 4, 1> &_desired_f_acc,
 
  273                                                                                        const Eigen::Matrix<Eigen::Vector3d, 4, 1> &_f_pos,
 
  274                                                                                        const Eigen::Matrix<Eigen::Vector3d, 4, 1> &_f_vel,
 
  275                                                                                        const Eigen::Matrix<double, 18, 1> &_q,
 
  276                                                                                        const Eigen::Matrix<double, 18, 1> &_u,
 
  283     Eigen::Matrix<double, 12, 1> desired_tau;    
 
  285     Eigen::VectorXd x_opt;                       
 
  298     std::vector<Task> tasks; 
 
  302     Eigen::Matrix<double, 18, 18> M;                      
 
  303     Eigen::Matrix<double, 18, 1> 
b;                       
 
  304     Eigen::Matrix<double, 18, 1> g;                       
 
  305     Eigen::Matrix<double, Eigen::Dynamic, 18> J_c;        
 
  306     Eigen::Matrix<double, Eigen::Dynamic, 18> dot_J_c;    
 
  309     Eigen::Matrix<double, 3, 18> J_P_fb;                   
 
  310     Eigen::Matrix<double, 3, 18> J_R_fb;                   
 
  311     Eigen::Matrix<double, 3, 18> J_P_fl;                   
 
  312     Eigen::Matrix<double, 3, 18> J_P_fr;                   
 
  313     Eigen::Matrix<double, 3, 18> J_P_rl;                   
 
  314     Eigen::Matrix<double, 3, 18> J_P_rr;                   
 
  316     Eigen::Matrix<double, 3, 18> dot_J_P_fb;               
 
  317     Eigen::Matrix<double, 3, 18> dot_J_R_fb;               
 
  318     Eigen::Matrix<double, 3, 18> dot_J_P_fl;               
 
  319     Eigen::Matrix<double, 3, 18> dot_J_P_fr;               
 
  320     Eigen::Matrix<double, 3, 18> dot_J_P_rl;               
 
  321     Eigen::Matrix<double, 3, 18> dot_J_P_rr;               
 
  324     Eigen::Matrix<double, 12, 1> q_r_nom;                  
 
  330     Eigen::Matrix<double, 3, 3> rotationWToC;             
 
  331     Eigen::Matrix<double, 12, 1> tau_min;                 
 
  332     Eigen::Matrix<double, 12, 1> tau_max;                 
 
  334     std::vector<Kinematics::LegType> contact_legs; 
 
  335     std::vector<Kinematics::LegType> swing_legs;   
 
  345     Eigen::Matrix3d k_p_fb_pos = 15*Eigen::Matrix3d::Identity(); 
 
  346     Eigen::Matrix3d k_d_fb_pos = 2*Eigen::Matrix3d::Identity(); 
 
  347     Eigen::Matrix3d k_p_fb_rot = 30*Eigen::Matrix3d::Identity(); 
 
  348     Eigen::Matrix3d k_d_fb_rot = 2*Eigen::Matrix3d::Identity(); 
 
  349     Eigen::Matrix3d k_p_fl = 2*Eigen::Matrix3d::Identity();     
 
  350     Eigen::Matrix3d k_d_fl = 2*Eigen::Matrix3d::Identity();     
 
  351     Eigen::Matrix3d k_p_fr = 2*Eigen::Matrix3d::Identity();     
 
  352     Eigen::Matrix3d k_d_fr = 2*Eigen::Matrix3d::Identity();     
 
  353     Eigen::Matrix3d k_p_rl = 2*Eigen::Matrix3d::Identity();     
 
  354     Eigen::Matrix3d k_d_rl = 2*Eigen::Matrix3d::Identity();     
 
  355     Eigen::Matrix3d k_p_rr = 2*Eigen::Matrix3d::Identity();     
 
  356     Eigen::Matrix3d k_d_rr = 2*Eigen::Matrix3d::Identity();     
 
  359     Eigen::Matrix<double, 12, 12> k_p_pt = 15*Eigen::Matrix<double, 12, 12>::Identity();      
 
  360     Eigen::Matrix<double, 12, 12> k_d_pt = 4*Eigen::Matrix<double, 12, 12>::Identity();      
 
  367     for (
size_t i = 0; i < 4; i++)
 
  383     const unsigned int n_c = contact_legs.size();
 
  384     const unsigned int n_s = swing_legs.size();
 
  387     const unsigned int state_dim = 18 + 3*n_c;
 
  390     t_eom.
A_eq.resize(6, state_dim);
 
  391     t_eom.
b_eq.resize(6, 1);
 
  393     t_cmc.
A_eq.resize(3*n_c, state_dim);
 
  394     t_cmc.
b_eq.resize(3*n_c, 1);
 
  396     t_cftl.
A_ineq.resize(4*n_c + 24, state_dim);
 
  397     t_cftl.
b_ineq.resize(4*n_c + 24, 1);
 
  399     t_mt.
A_eq.resize(18, state_dim);
 
  400     t_mt.
b_eq.resize(18, 1);
 
  402     t_pt.
A_eq.resize(12, state_dim);
 
  403     t_pt.
b_eq.resize(12, 1);
 
  405     t_cfm.
A_eq.resize(3*n_c, state_dim);
 
  406     t_cfm.
b_eq.resize(3*n_c, 1);
 
  409     x_opt.resize(state_dim, 1);
 
  411     J_c.resize(3*n_c, 18);
 
  412     dot_J_c.resize(3*n_c, 18);
 
  416     kindr::EulerAnglesXyz<double> base_ori(_q.segment(3,3));
 
  418     kindr::EulerAnglesXyz<double> desired_base_ori_kindr(_desired_base_ori);
 
  420     Eigen::Vector3d orientation_error = desired_base_ori_kindr.boxMinus(base_ori);
 
  435                                                   Kinematics::BodyType::base,
 
  438                                                Kinematics::BodyType::base,
 
  441                                                   Kinematics::BodyType::foot,
 
  444                                                   Kinematics::BodyType::foot,
 
  447                                                   Kinematics::BodyType::foot,
 
  450                                                   Kinematics::BodyType::foot,
 
  454                                                           Kinematics::BodyType::base,
 
  458                                                        Kinematics::BodyType::base,
 
  462                                                           Kinematics::BodyType::foot,
 
  466                                                           Kinematics::BodyType::foot,
 
  470                                                           Kinematics::BodyType::foot,
 
  474                                                           Kinematics::BodyType::foot,
 
  510     tau_max.setConstant(40);
 
  511     tau_min.setConstant(-40);
 
  514     t_eom.
A_eq.leftCols(18) = M.topRows(6);
 
  515     t_eom.
A_eq.rightCols(3*n_c) = - J_c.transpose().topRows(6);
 
  516     t_eom.
b_eq = - (
b.topRows(6) + g.topRows(6));
 
  520     for (
size_t i = 0; i < n_c; i++)
 
  522         t_cftl.
A_ineq.block(4*i, 0, 1, state_dim).setZero();
 
  523         t_cftl.
A_ineq.block(4*i, 18 + 3*i, 1, 3) = (h.transpose() - n.transpose() * mu);
 
  525         t_cftl.
A_ineq.block(4*i + 1, 0, 1, state_dim).setZero();
 
  526         t_cftl.
A_ineq.block(4*i + 1, 18 + 3*i, 1, 3) = - (h.transpose() + n.transpose() * mu);
 
  528         t_cftl.
A_ineq.block(4*i + 2, 0, 1, state_dim).setZero();
 
  529         t_cftl.
A_ineq.block(4*i + 2, 18 + 3*i, 1, 3) = (l.transpose() - n.transpose() * mu);
 
  531         t_cftl.
A_ineq.block(4*i + 3, 0, 1, state_dim).setZero();
 
  532         t_cftl.
A_ineq.block(4*i + 3, 18 + 3*i, 1, 3) = - (l.transpose() + n.transpose() * mu);
 
  535     t_cftl.
b_ineq.topRows(4*n_c).setZero();
 
  540     t_cftl.
A_ineq.block(4*n_c, 0, 12, 18) = M.bottomRows(12);
 
  541     t_cftl.
A_ineq.block(4*n_c, 18, 12, 3*n_c) = - J_c.transpose().bottomRows(12);
 
  542     t_cftl.
b_ineq.block(4*n_c, 0, 12, 1) = tau_max - (
b.bottomRows(12) + g.bottomRows(12));
 
  548     t_cftl.
A_ineq.block(4*n_c + 12, 0, 12, 18) = - M.bottomRows(12);
 
  549     t_cftl.
A_ineq.block(4*n_c + 12, 18, 12, 3*n_c) = J_c.transpose().bottomRows(12);
 
  550     t_cftl.
b_ineq.block(4*n_c + 12, 0, 12, 1) = - tau_min + (
b.bottomRows(12) + g.bottomRows(12));
 
  553     t_cmc.
A_eq.leftCols(18) = J_c;
 
  554     t_cmc.
A_eq.rightCols(3*n_c).setZero();
 
  555     t_cmc.
b_eq = - dot_J_c * _u;
 
  562     t_mt.
A_eq.block(0, 0, 3, state_dim).leftCols(18) = J_P_fb;
 
  563     t_mt.
A_eq.block(0, 0, 3, state_dim).rightCols(3*n_c).setZero();
 
  564     t_mt.
b_eq.block(0, 0, 3, 1) = _desired_base_acc + k_p_fb_pos * (_desired_base_pos - _q.topRows(3))
 
  565                                   + k_d_fb_pos * (_desired_base_vel - _u.topRows(3)) - dot_J_P_fb * _u;
 
  569     t_mt.
A_eq.block(3, 0, 3, state_dim).leftCols(18) = J_R_fb;
 
  570     t_mt.
A_eq.block(3, 0, 3, state_dim).rightCols(3*n_c).setZero();
 
  575     t_mt.
b_eq.block(3, 0, 3, 1) = k_p_fb_rot * (orientation_error)
 
  576                                   + k_d_fb_rot * (- _u.segment(3,3)) - dot_J_R_fb * _u;
 
  581     t_mt.
A_eq.block(6, 0, 3, state_dim).leftCols(18) = J_P_fl;
 
  582     t_mt.
A_eq.block(6, 0, 3, state_dim).rightCols(3*n_c).setZero();
 
  583     t_mt.
b_eq.block(6, 0, 3, 1) = _desired_f_acc(0) + k_p_fl * (_desired_f_pos(0) - _f_pos(0))
 
  584                                   + k_d_fl * (_desired_f_vel(0) - _f_vel(0)) - dot_J_P_fl * _u;
 
  587     t_mt.
A_eq.block(9, 0, 3, state_dim).leftCols(18) = J_P_fr;
 
  588     t_mt.
A_eq.block(9, 0, 3, state_dim).rightCols(3*n_c).setZero();
 
  589     t_mt.
b_eq.block(9, 0, 3, 1) = _desired_f_acc(1) + k_p_fr * (_desired_f_pos(1) - _f_pos(1))
 
  590                                   + k_d_fr * (_desired_f_vel(1) - _f_vel(1)) - dot_J_P_fr * _u;
 
  593     t_mt.
A_eq.block(12, 0, 3, state_dim).leftCols(18) = J_P_rl;
 
  594     t_mt.
A_eq.block(12, 0, 3, state_dim).rightCols(3*n_c).setZero();
 
  595     t_mt.
b_eq.block(12, 0, 3, 1) = _desired_f_acc(2) + k_p_rl * (_desired_f_pos(2) - _f_pos(2))
 
  596                                   + k_d_rl * (_desired_f_vel(2) - _f_vel(2)) - dot_J_P_rl * _u;
 
  599     t_mt.
A_eq.block(15, 0, 3, state_dim).leftCols(18) = J_P_rr;
 
  600     t_mt.
A_eq.block(15, 0, 3, state_dim).rightCols(3*n_c).setZero();
 
  601     t_mt.
b_eq.block(15, 0, 3, 1) = _desired_f_acc(3) + k_p_rr * (_desired_f_pos(3) - _f_pos(3))
 
  602                                   + k_d_rr * (_desired_f_vel(3) - _f_vel(3)) - dot_J_P_rr * _u;
 
  605     t_pt.
A_eq.leftCols(6).setZero();
 
  606     t_pt.
A_eq.block(0, 6, 12, 12).setIdentity();
 
  607     t_pt.
A_eq.rightCols(3*n_c).setZero();
 
  608     t_pt.
b_eq = k_p_pt * (q_r_nom - _q.bottomRows(12)) + k_d_pt * (-_u.bottomRows(12));
 
  611     t_cfm.
A_eq.leftCols(18).setZero();
 
  612     t_cfm.
A_eq.rightCols(3*n_c).setIdentity();
 
  613     t_cfm.
b_eq.setZero();
 
  628     tasks.push_back(t_eom);
 
  629     tasks.push_back(t_cftl);
 
  630     tasks.push_back(t_cmc);
 
  631     tasks.push_back(t_mt);
 
  633     tasks.push_back(t_cfm);
 
  635     Eigen::Matrix<Eigen::MatrixXd, 5, 1> A_ls;
 
  636     Eigen::Matrix<Eigen::VectorXd, 5, 1> b_ls;
 
  638     A_ls(0) = t_eom.
A_eq;
 
  639     b_ls(0) = t_eom.
b_eq;
 
  640     A_ls(1) = t_cmc.
A_eq;
 
  641     b_ls(1) = t_cmc.
b_eq;
 
  646     A_ls(4) = t_cfm.
A_eq;
 
  647     b_ls(4) = t_cfm.
b_eq;
 
  663     desired_tau = M.bottomRows(12) * x_opt.topRows(18) -  J_c.transpose().bottomRows(12) * x_opt.bottomRows(3*n_c) + 
b.bottomRows(12) + g.bottomRows(12);
 
  680                                                                                                      const std::vector<Task> &_tasks,
 
  685     Eigen::VectorXd x_opt(_state_dim);           
 
  686     Eigen::MatrixXd N(_state_dim, _state_dim);   
 
  687     Eigen::VectorXd z(_state_dim);               
 
  688     Eigen::MatrixXd stacked_A_eq;                
 
  689     Eigen::MatrixXd stacked_A_ineq;              
 
  690     Eigen::VectorXd stacked_b_ineq;              
 
  694     Eigen::MatrixXd E_ineq;       
 
  695     Eigen::VectorXd f_ineq;       
 
  698     Eigen::VectorXd stacked_v;    
 
  710     for (
Task t : _tasks)
 
  719         if (
t.has_eq_constraint)
 
  722             rowsA_eq = 
t.A_eq.rows(); 
 
  725             Eigen::MatrixXd stacked_A_eq_tmp = stacked_A_eq;
 
  727             stacked_A_eq.resize(
t.A_eq.rows() + stacked_A_eq_tmp.rows(), _state_dim); 
 
  728             stacked_A_eq << 
t.A_eq,
 
  738         if (
t.has_ineq_constraint)
 
  741             rowsA_ineq = 
t.A_ineq.rows();
 
  744             Eigen::MatrixXd stacked_A_ineq_tmp = stacked_A_ineq;
 
  746             stacked_A_ineq.resize(
t.A_ineq.rows() + stacked_A_ineq_tmp.rows(), _state_dim); 
 
  747             stacked_A_ineq << 
t.A_ineq,
 
  751             Eigen::VectorXd stacked_b_ineq_tmp = stacked_b_ineq;
 
  753             stacked_b_ineq.resize(
t.b_ineq.rows() + stacked_b_ineq_tmp.rows(), 1);
 
  754             stacked_b_ineq << 
t.b_ineq,
 
  765         v.resize(rowsA_ineq, 1);
 
  766         xi.resize(colsN + rowsA_ineq, 1);
 
  769         Q.resize(colsN + rowsA_ineq, colsN + rowsA_ineq);
 
  770         c.resize(colsN + rowsA_ineq, 1);
 
  772         if (
t.has_eq_constraint)
 
  774             Q.topLeftCorner(colsN, colsN) = N.transpose() * 
t.A_eq.transpose() * 
t.A_eq * N;
 
  775             Q.topRightCorner(colsN, rowsA_ineq).setZero();
 
  776             Q.bottomLeftCorner(rowsA_ineq, colsN).setZero();
 
  777             Q.bottomRightCorner(rowsA_ineq, rowsA_ineq).setIdentity();
 
  779             c.topRows(colsN) = N.transpose() * 
t.A_eq.transpose() * (
t.A_eq * x_opt - 
t.b_eq);
 
  780             c.bottomRows(rowsA_ineq).setZero();
 
  785             Q.bottomRightCorner(rowsA_ineq, rowsA_ineq).setIdentity();
 
  791         E_ineq.resize(stacked_A_ineq.rows() + rowsA_ineq, colsN + rowsA_ineq);
 
  792         f_ineq.resize(stacked_A_ineq.rows() + rowsA_ineq, 1);
 
  796         E_ineq.topLeftCorner(stacked_A_ineq.rows(), colsN) = stacked_A_ineq * N;
 
  797         E_ineq.topRightCorner(rowsA_ineq, rowsA_ineq) = - Eigen::MatrixXd::Identity(rowsA_ineq, rowsA_ineq);
 
  799         E_ineq.bottomRightCorner(rowsA_ineq, rowsA_ineq) = - Eigen::MatrixXd::Identity(rowsA_ineq, rowsA_ineq);
 
  801         f_ineq.topRows(stacked_b_ineq.rows()) = stacked_b_ineq - stacked_A_ineq * x_opt;
 
  802         f_ineq.segment(rowsA_ineq, stacked_b_ineq.rows() - rowsA_ineq) += stacked_v; 
 
  803         f_ineq.bottomRows(rowsA_ineq).setZero();
 
  808             ROS_INFO_STREAM(
"----------------------" << 
"Task: " << count << 
"---------------------- \n" );
 
  809             ROS_INFO_STREAM(
"Q: \n" << Q << 
"\n");
 
  810             ROS_INFO_STREAM(
"eigenvalues(Q): \n" << Q.eigenvalues() << 
"\n");
 
  811             ROS_INFO_STREAM(
"c: \n" << 
c << 
"\n");
 
  812             ROS_INFO_STREAM(
"E_ineq: \n" << E_ineq << 
"\n");
 
  813             ROS_INFO_STREAM(
"f_ineq: \n" << f_ineq << 
"\n");
 
  817             ROS_INFO_STREAM(
"N: \n" << N << 
"\n");
 
  818             ROS_INFO_STREAM(
"A_eq: \n" << 
t.A_eq << 
"\n");
 
  819             ROS_INFO_STREAM(
"b_eq: \n" << 
t.b_eq << 
"\n");
 
  820             ROS_INFO_STREAM(
"stacked_A_eq: \n" << stacked_A_eq << 
"\n");
 
  821             ROS_INFO_STREAM(
"stacked_A_ineq: \n" << stacked_A_ineq << 
"\n");
 
  822             ROS_INFO_STREAM(
"stacked_b_ineq: \n" << stacked_b_ineq << 
"\n");
 
  826         if (!
SolveQP(Q, 
c, E_ineq, f_ineq, xi, _solver,_v))
 
  828             ROS_ERROR_STREAM(
"[HierarchicalOptimizationControl::HierarchicalQPOptimization] Failed to solve QP at task " << count << 
"!");
 
  834         z = xi.topRows(colsN);
 
  835         v = xi.bottomRows(rowsA_ineq);
 
  838         x_opt = x_opt + N * z;
 
  842         if (
t.has_eq_constraint)
 
  849         if (
t.has_ineq_constraint)
 
  851             Eigen::VectorXd stacked_v_tmp = stacked_v;
 
  853             stacked_v.resize(v.rows() + stacked_v_tmp.rows(), 1);
 
  861             ROS_INFO_STREAM(
"Solution at task " << count << 
" is: \n" << x_opt);
 
  869                 ROS_INFO_STREAM(
"Terminating at task " << count << 
" due to the null-space being zero. \n");
 
  881                                                                                                               const Eigen::Matrix<Eigen::Matrix<double, Eigen::Dynamic, 1>, Eigen::Dynamic, 1> &_b,
 
  884     const auto rowsA = _A.rows();
 
  885     const auto rowsb = _b.rows();
 
  890         ROS_ERROR(
"[HierarchicalOptimizationControl::HierarchicalLeastSquareOptimization] _A and _b does not contain equal amount of elements!");
 
  895     const auto state_dim = _A(0).cols();
 
  898     for (
size_t i = 0; i < rowsA; i++)
 
  900         if (_A(i).cols() != state_dim || _A(i).rows() != _b(i).rows() )
 
  902             ROS_ERROR_STREAM(
"[HierarchicalOptimizationControl::HierarchicalLeastSquareOptimization] State or equation dimensions failed at index: i = !" << i);
 
  909     Eigen::Matrix<double, Eigen::Dynamic, 1> x_opt;                 
 
  910     Eigen::Matrix<double, Eigen::Dynamic, 1> x_i;                   
 
  911     Eigen::Matrix<double, Eigen::Dynamic, Eigen::Dynamic> N;        
 
  912     Eigen::Matrix<double, Eigen::Dynamic, Eigen::Dynamic> AN;       
 
  913     Eigen::Matrix<double, Eigen::Dynamic, Eigen::Dynamic> pinvAN;   
 
  914     Eigen::MatrixXd A_stacked;                                      
 
  917     x_opt.resize(state_dim, 1);
 
  918     N.resize(state_dim, state_dim);
 
  925     for (
size_t i = 0; i < rowsA; i++)
 
  929         kindr::pseudoInverse(AN, pinvAN);
 
  932         x_i = pinvAN * (_b(i) - _A(i) * x_opt);
 
  935         x_opt = x_opt + N * x_i;
 
  938         Eigen::MatrixXd A_stacked_tmp = A_stacked;
 
  940         A_stacked.resize(A_stacked_tmp.rows() + _A(i).rows(), state_dim);
 
  941         A_stacked << A_stacked_tmp,
 
  949             ROS_INFO_STREAM(
"Solution at iteration " << i << 
" is: \n" << x_opt);
 
  959                                               const Eigen::VectorXd &_c,
 
  960                                               const Eigen::MatrixXd &_E_ineq,
 
  961                                               const Eigen::VectorXd &_f_ineq,
 
  962                                               Eigen::VectorXd &_sol,
 
  967     if (_E_ineq.rows() != _f_ineq.rows())
 
  969         ROS_INFO_STREAM(
"[HierarchicalOptimizationControl::SolveQP] Equality constraint dimensions does not match!");
 
  977     lb.resize(_f_ineq.rows(), 1);
 
  981     return this->
SolveQP(_Q, _c, _E_ineq, lb, _f_ineq, _sol, _solver, _v);
 
  986                                               const Eigen::VectorXd &_c,
 
  987                                               const Eigen::MatrixXd &_A,
 
  988                                               const Eigen::VectorXd &_lb,
 
  989                                               const Eigen::VectorXd &_ub,
 
  990                                               Eigen::VectorXd &_sol,
 
  995     drake::solvers::MathematicalProgram prog;
 
  998     drake::solvers::MathematicalProgramResult result;
 
 1001     auto x = prog.NewContinuousVariables(_Q.cols(), 
"x");
 
 1004     prog.AddQuadraticCost(_Q, _c, 
x, 
true);
 
 1011             ROS_INFO_STREAM(
"Linear ineq, A: \n" << _A << 
"\n");
 
 1012             ROS_INFO_STREAM(
"Linear ineq, lb: \n" << _lb << 
"\n");
 
 1013             ROS_INFO_STREAM(
"Linear ineq, ub: \n" << _ub << 
"\n");
 
 1016         prog.AddLinearConstraint(_A, _lb, _ub, 
x);
 
 1024             auto solver = drake::solvers::OsqpSolver();
 
 1026             auto start = std::chrono::steady_clock::now();
 
 1028             result = solver.Solve(prog);
 
 1032                 auto end = std::chrono::steady_clock::now();
 
 1034                 std::chrono::duration<double, std::micro> diff = end - start;
 
 1036                 ROS_INFO_STREAM(
"OSQP run-time: " << diff.count() << 
" microseconds. \n");
 
 1038                 auto details = result.get_solver_details<drake::solvers::OsqpSolver>();
 
 1039                 ROS_INFO_STREAM(
"Solver details: run_time: " << details.run_time << 
"\n");
 
 1046             auto solver = drake::solvers::EqualityConstrainedQPSolver();
 
 1047             result = solver.Solve(prog);
 
 1053             auto solver = drake::solvers::ClpSolver();
 
 1054             result = solver.Solve(prog);
 
 1060             auto solver = drake::solvers::ScsSolver();
 
 1061             result = solver.Solve(prog);
 
 1067             auto solver = drake::solvers::SnoptSolver();
 
 1068             result = solver.Solve(prog);
 
 1074             result = Solve(prog);
 
 1080             ROS_WARN(
"[HierarchicalOptimizationControl::SolveQP] Could not determine solver type!");
 
 1086     if (!result.is_success())
 
 1088         ROS_WARN(
"[HierarchicalOptimizationControl::SolveQP] Failed to solve QP!");
 
 1094             ROS_INFO_STREAM(
"Solver id: " << result.get_solver_id() << 
"\n");
 
 1095             ROS_INFO_STREAM(
"Solver result: " << result.get_solution_result() << 
"\n");
 
 1096             ROS_INFO_STREAM(
"Solution result: " << result.GetSolution(
x) << 
"\n");
 
 1097             ROS_INFO_STREAM(
"Solution result: " << result.GetSolution(
x) << 
"\n");
 
 1109     _sol = result.GetSolution(
x);
 
 1121                                               const Eigen::VectorXd &_c,
 
 1122                                               const Eigen::MatrixXd &_E_eq,
 
 1123                                               const Eigen::VectorXd &_f_eq,
 
 1124                                               const Eigen::MatrixXd &_E_ineq,
 
 1125                                               const Eigen::VectorXd &_f_ineq,
 
 1126                                               Eigen::VectorXd &_sol,
 
 1131     drake::solvers::MathematicalProgram prog;
 
 1134     drake::solvers::MathematicalProgramResult result;
 
 1137     auto x = prog.NewContinuousVariables(_Q.cols(), 
"x");
 
 1140     prog.AddQuadraticCost(_Q, _c, 
x, 
true);
 
 1143     if (!_E_eq.isZero())
 
 1145         prog.AddLinearEqualityConstraint(_E_eq, _f_eq, 
x);
 
 1149     if (!_E_ineq.isZero())
 
 1151         prog.AddLinearConstraint((_E_ineq * 
x).array() <= _f_ineq.array());
 
 1159             auto solver = drake::solvers::OsqpSolver();
 
 1160             result = solver.Solve(prog);
 
 1165             auto solver = drake::solvers::EqualityConstrainedQPSolver();
 
 1166             result = solver.Solve(prog);
 
 1171             auto solver = drake::solvers::ClpSolver();
 
 1172             result = solver.Solve(prog);
 
 1177             auto solver = drake::solvers::ScsSolver();
 
 1178             result = solver.Solve(prog);
 
 1183             auto solver = drake::solvers::SnoptSolver();
 
 1184             result = solver.Solve(prog);
 
 1189             result = Solve(prog);
 
 1194             ROS_WARN(
"[HierarchicalOptimizationControl::SolveQP] Could not determine solver type!");
 
 1200     if (!result.is_success())
 
 1202         ROS_WARN(
"[HierarchicalOptimizationControl::SolveQP] Failed to solve QP!");
 
 1210     _sol = result.GetSolution(
x);
 
 1223     sensor_msgs::JointState joint_state_msg;    
 
 1226     joint_state_msg.effort.resize(12);
 
 1229     joint_state_msg.effort[0] = _desired_tau(0);
 
 1230     joint_state_msg.effort[1] = _desired_tau(1);
 
 1231     joint_state_msg.effort[2] = _desired_tau(2);
 
 1234     joint_state_msg.effort[3] = _desired_tau(3);
 
 1235     joint_state_msg.effort[4] = _desired_tau(4);
 
 1236     joint_state_msg.effort[5] = _desired_tau(5);
 
 1239     joint_state_msg.effort[6] = _desired_tau(6);
 
 1240     joint_state_msg.effort[7] = _desired_tau(7);
 
 1241     joint_state_msg.effort[8] = _desired_tau(8);
 
 1244     joint_state_msg.effort[9] = _desired_tau(9);
 
 1245     joint_state_msg.effort[10] = _desired_tau(10);
 
 1246     joint_state_msg.effort[11] = _desired_tau(11);
 
 1249     joint_state_msg.header.stamp = ros::Time::now();
 
 1258     std::vector<double> data = _msg->data;
 
 1260     this->
genCoord = Eigen::Map<Eigen::MatrixXd>(data.data(), 18, 1);
 
 1266         ROS_ERROR(
"[HierarchicalOptimizationControl::OnGenCoordMsg] Could not solve forward kinematics!");
 
 1275     std::vector<double> data = _msg->data;
 
 1277     this->
genVel = Eigen::Map<Eigen::MatrixXd>(data.data(), 18, 1); 
 
 1279     for (
int i = 0; i < 4; i++)
 
 1290     if (!_msg->data.size() == 4)
 
 1292         ROS_ERROR(
"[HierarchicalOptimizationControl::OnContactStateMsg] Received contact message with wrong size!");
 
 1307     static const double timeout = 0.01;
 
 1317     static const double timeout = 0.01;
 
 1327     if (!ros::isInitialized())
 
 1334             "hierarchical_optimization_control_node",
 
 1335             ros::init_options::NoSigintHandler
 
 1339     this->
rosNode.reset(
new ros::NodeHandle(
"hierarchical_optimization_control_node"));
 
 1341     ros::SubscribeOptions gen_coord_so = 
 
 1342         ros::SubscribeOptions::create<std_msgs::Float64MultiArray>(
 
 1343             "/my_robot/gen_coord",
 
 1350     ros::SubscribeOptions gen_vel_so = 
 
 1351         ros::SubscribeOptions::create<std_msgs::Float64MultiArray>(
 
 1352             "/my_robot/gen_vel",
 
 1359     ros::SubscribeOptions contact_state_so = 
 
 1360         ros::SubscribeOptions::create<std_msgs::Int8MultiArray>(
 
 1361             "/my_robot/contact_state",
 
 1368     ros::AdvertiseOptions joint_state_ao =
 
 1369         ros::AdvertiseOptions::create<sensor_msgs::JointState>(
 
 1370             "/my_robot/joint_state_cmd",
 
 1372             ros::SubscriberStatusCallback(),
 
 1373             ros::SubscriberStatusCallback(),
 
 1378     ros::AdvertiseOptions base_pose_cmd_ao =
 
 1379         ros::AdvertiseOptions::create<std_msgs::Float64MultiArray>(
 
 1380             "/my_robot/base_pose_cmd",
 
 1382             ros::SubscriberStatusCallback(),
 
 1383             ros::SubscriberStatusCallback(),
 
 1388     ros::AdvertiseOptions base_twist_cmd_ao =
 
 1389         ros::AdvertiseOptions::create<std_msgs::Float64MultiArray>(
 
 1390             "/my_robot/base_twist_cmd",
 
 1392             ros::SubscriberStatusCallback(),
 
 1393             ros::SubscriberStatusCallback(),
 
ros::Subscriber genVelSub
ROS Generalized Coordinates Subscriber.
std::thread rosProcessQueueThread
Thread running the rosProcessQueue.
std::unique_ptr< ros::NodeHandle > rosNode
Node used for ROS transport.
std::thread rosPublishQueueThread
Thread running the rosPublishQueue.
HierarchicalOptimizationControl()
Constructor.
Eigen::Matrix< double, 18, 1 > genCoord
Generalized Coordinates.
Kinematics kinematics
Kinematics.
bool SolveQP(const Eigen::MatrixXd &_Q, const Eigen::VectorXd &_c, const Eigen::MatrixXd &_E_ineq, const Eigen::VectorXd &_f_ineq, Eigen::VectorXd &_sol, const SolverType &_solver=SolverType::UNSPECIFIED, const int &_v=0)
The SolveQP function solves a (convex) quadratic program (QP) on the form:
void PublishTorqueMsg(const Eigen::Matrix< double, 12, 1 > &_desired_tau)
The PublishTorqueMsg function publishes a desired torque message to the ROS topic set by the joint st...
int contactState[4]
Contact State.
Eigen::Matrix< double, Eigen::Dynamic, 1 > HierarchicalQPOptimization(const int &_state_dim, const std::vector< Task > &_tasks, const SolverType &_solver=SolverType::OSQP, const int &_v=0)
The HierarchicalQPOptimization function finds the optimal solution for a set of tasks in a strictly p...
ros::CallbackQueue rosProcessQueue
ROS callbackque that helps process messages.
Eigen::Matrix< double, 18, 1 > genVel
Generalized Velocities.
void ProcessQueueThread()
The ProcessQueueThread function is a ROS helper function that processes messages.
void OnGenCoordMsg(const std_msgs::Float64MultiArrayConstPtr &_msg)
The OnGenCoordMsg function handles an incoming generalized coordinates message from ROS.
Eigen::Matrix< Eigen::Vector3d, 4, 1 > fVel
Foot-point velocities.
void InitRosQueueThreads()
The InitRosQueueThreads function is called to initialize the ROS Publish and Process Queue Threads.
Eigen::Matrix< double, 12, 1 > HierarchicalOptimization(const Eigen::Matrix< double, 3, 1 > &_desired_base_pos, const Eigen::Matrix< double, 3, 1 > &_desired_base_vel, const Eigen::Matrix< double, 3, 1 > &_desired_base_acc, const Eigen::Matrix< double, 3, 1 > &_desired_base_ori, const Eigen::Matrix< Eigen::Vector3d, 4, 1 > &_desired_f_pos, const Eigen::Matrix< Eigen::Vector3d, 4, 1 > &_desired_f_vel, const Eigen::Matrix< Eigen::Vector3d, 4, 1 > &_desired_f_acc, const Eigen::Matrix< Eigen::Vector3d, 4, 1 > &_f_pos, const Eigen::Matrix< Eigen::Vector3d, 4, 1 > &_f_vel, const Eigen::Matrix< double, 18, 1 > &_q, const Eigen::Matrix< double, 18, 1 > &_u, const int &_v=0)
The HierarchicalOptimization function finds the optimal joint torques for a desired motion plan....
void OnContactStateMsg(const std_msgs::Int8MultiArrayConstPtr &_msg)
The OnContactStateMsg function handles an incoming contact state message from ROS.
Eigen::Matrix< Eigen::Vector3d, 4, 1 > fPos
Foot-point positions.
void PublishQueueThread()
The PublishQueueThread function is a ROS helper function that publish state messages.
ros::Publisher jointStatePub
ROS Joint State Publisher.
Eigen::Matrix< double, Eigen::Dynamic, 1 > HierarchicalLeastSquareOptimization(const Eigen::Matrix< Eigen::MatrixXd, Eigen::Dynamic, 1 > &_A, const Eigen::Matrix< Eigen::Matrix< double, Eigen::Dynamic, 1 >, Eigen::Dynamic, 1 > &_b, const int &_v=0)
The HierarchicalLeastSquareOptimization function finds the optimal solution for a set of linear equal...
void InitRos()
The InitRos function is called to initialize ROS.
void OnGenVelMsg(const std_msgs::Float64MultiArrayConstPtr &_msg)
The OnGenVelMsg function handles an incoming generalized velocities message from ROS.
ros::Subscriber genCoordSub
ROS Generalized Coordinates Subscriber.
ros::CallbackQueue rosPublishQueue
ROS callbackque that helps publish messages.
virtual ~HierarchicalOptimizationControl()
Destructor.
ros::Publisher basePoseCmdPub
ROS Base Position Command Publisher.
SolverType
Drake Solver type enumerator.
ros::Subscriber contactStateSub
ROS Contact State Subscriber.
ros::Publisher baseTwistCmdPub
ROS Base Position Command Publisher.
Eigen::Matrix< double, 3, 18 > GetTranslationJacobianInW(const LegType &_leg, const BodyType &_body, const Eigen::Matrix< double, 18, 1 > &_q)
The GetTranslationJacobianInW function returns the 3x18 spatial translation Jacobian mapping generali...
Eigen::Matrix< double, Eigen::Dynamic, 18 > GetContactJacobianInW(std::vector< LegType > &_legs, const Eigen::Matrix< double, 18, 1 > &_q)
The GetContactJacobianInW function returns the (3*n_c)x18 support Jacobian mapping reaction forces at...
Eigen::Matrix< double, 18, 18 > GetMassMatrix(const Eigen::Matrix< double, 18, 1 > &_q)
The GetMassMatrix function returns the mass matrix for the floating base system.
Eigen::Matrix< double, 3, 18 > GetTranslationJacobianInCDiff(const LegType &_leg, const BodyType &_body, const Eigen::Matrix< double, 18, 1 > &_q, const Eigen::Matrix< double, 18, 1 > &_u)
The GetTranslationJacobianInCDiff function returns the time derivative of the 3x18 spatial translatio...
Eigen::Matrix< double, 3, 3 > GetRotationMatrixWToC(const double &_roll, const double &_pitch, const double &_yaw)
The GetRotationMatrixWToC function returns the Euler Angles ZYX rotation matrix from World to Control...
bool SolveForwardKinematics(const GeneralizedCoordinates &_q, FootstepPositions &_f_pos)
The SolveForwardKinematics function calculates the Forward Kinematics, i.e. maps joint angles in Join...
Eigen::Matrix< double, 18, 1 > GetGravitationalTerms(const Eigen::Matrix< double, 18, 1 > &_q)
The GetGravitationalTerms function returns the gravitational terms for the floating base system.
Eigen::Matrix< double, Eigen::Dynamic, 18 > GetContactJacobianInWDiff(std::vector< LegType > &_legs, const Eigen::Matrix< double, 18, 1 > &_q, const Eigen::Matrix< double, 18, 1 > &_u)
The GetContactJacobianInWDiff function returns the time derivative of the (3*n_c)x18 support Jacobian...
Eigen::Matrix< double, 3, 18 > GetTranslationJacobianInC(const LegType &_leg, const BodyType &_body, const Eigen::Matrix< double, 18, 1 > &_q)
The GetTranslationJacobianInC function returns the 3x18 spatial translation Jacobian mapping generali...
Eigen::Matrix< double, 3, 18 > GetRotationJacobianInC(const LegType &_leg, const BodyType &_body, const Eigen::Matrix< double, 18, 1 > &_q)
The GetRotationJacobianInC function returns the 3x18 spatial rotation Jacobian mapping generalized ve...
Eigen::Matrix< double, 3, 18 > GetRotationJacobianInCDiff(const LegType &_leg, const BodyType &_body, const Eigen::Matrix< double, 18, 1 > &_q, const Eigen::Matrix< double, 18, 1 > &_u)
The GetRotationJacobianInCDiff function returns the time derivative of the 3x18 control frame Rotatio...
LegType
Leg type enumerator.
Eigen::Matrix< double, 18, 1 > GetCoriolisAndCentrifugalTerms(const Eigen::Matrix< double, 18, 1 > &_q, const Eigen::Matrix< double, 18, 1 > &_u)
The GetCoriolisAndCentrifugalTerms function returns the coriolis and centrifugal terms for the floati...
void printGeneralizedAccelerations(const Eigen::Matrix< double, 18, 1 > &_gen_accel)
The printGeneralizedAccelerations function prints a given set of generalized accelerations to ROS usi...
void printJointTorques(const Eigen::Matrix< double, 12, 1 > &_joint_trq)
The printJointTorques function prints given joint- torques to ROS using print level INFO.
void printFootstepForces(const int *_contact_state, const Eigen::VectorXd &_F_c)
The printFootstepPositions function prints a given set of footstep forces to ROS using print level IN...
double degToRad(const double &_deg)
The degToRad function converts degrees to radians.
Eigen::Matrix< typename Matrix_TypeA::Scalar, Eigen::Dynamic, Eigen::Dynamic > SVDNullSpaceProjector(const Matrix_TypeA &_A)
The SVDNullSpaceProjector function calculates the null-space projector of a given matrix....
static constexpr double INF
Define infinity.
bool has_eq_constraint
Bool indicating whether the task has a linear equality constraint.
Eigen::MatrixXd A_ineq
Linear inequality constraint matrix A.
Eigen::VectorXd b_ineq
Linear inequality constraint vector b.
Eigen::VectorXd b_eq
Linear equality constraint vector b.
bool has_ineq_constraint
Bool indicating whether the task has a linear inequality constraint.
Eigen::MatrixXd A_eq
Linear equality constraint matrix A.