diff --git a/include/qrw/InvKin.hpp b/include/qrw/InvKin.hpp index f35c312bc0277afcc1d1f65165aa2729b6909a55..127b8eb9f51c425ce8ba912fd24f4e6580219971 100644 --- a/include/qrw/InvKin.hpp +++ b/include/qrw/InvKin.hpp @@ -10,6 +10,14 @@ #ifndef INVKIN_H_INCLUDED #define INVKIN_H_INCLUDED +#include <example-robot-data/path.hpp> +#include "pinocchio/algorithm/compute-all-terms.hpp" +#include "pinocchio/algorithm/frames.hpp" +#include "pinocchio/algorithm/jacobian.hpp" +#include "pinocchio/algorithm/joint-configuration.hpp" +#include "pinocchio/math/rpy.hpp" +#include "pinocchio/parsers/urdf.hpp" +#include "pinocchio/spatial/explog.hpp" #include "pinocchio/multibody/data.hpp" #include "pinocchio/multibody/model.hpp" #include "qrw/Params.hpp" @@ -85,9 +93,9 @@ class InvKin { // Matrices initialisation Matrix12 invJ; // Inverse of the feet Jacobian - Eigen::Matrix<double, 1, 30> acc; // Reshaped feet acceleration references to get command acc for actuators - Eigen::Matrix<double, 1, 30> x_err; // Reshaped feet position errors to get command position step for actuators - Eigen::Matrix<double, 1, 30> dx_r; // Reshaped feet velocity references to get command velocities for actuators + Eigen::Matrix<double, 1, 18> acc; // Reshaped feet acceleration references to get command acc for actuators + Eigen::Matrix<double, 1, 18> x_err; // Reshaped feet position errors to get command position step for actuators + Eigen::Matrix<double, 1, 18> dx_r; // Reshaped feet velocity references to get command velocities for actuators Matrix43 pfeet_err; // Feet position errors to get command position step for actuators Matrix43 vfeet_ref; // Feet velocity references to get command velocities for actuators @@ -122,8 +130,9 @@ class InvKin { Matrix43 afeet_contacts_; // Acceleration references for the feet contact task Eigen::Matrix<double, 6, 18> Jb_; // Jacobian of the base (linear/angular) - Eigen::Matrix<double, 30, 18> J_; // Task Jacobian - Eigen::Matrix<double, 18, 30> invJ_; // Inverse of Task Jacobian + Eigen::Matrix<double, 18, 18> invJ_; // Inverse of Task Jacobian + Matrix3 invJi_; // Inverse of a foot Jacobian + Matrix3 pskew_; // Skew-symetric matrix of base-foot vector Vector3 Kp_base_position; // Proportional gains for base position task Vector3 Kd_base_position; // Derivative gains for base position task diff --git a/src/InvKin.cpp b/src/InvKin.cpp index 49e7475a0d5779369b8a46de2e398c850d6596d4..e474c63b65a0ab2729ca3968bb7bb5f95bb64f56 100644 --- a/src/InvKin.cpp +++ b/src/InvKin.cpp @@ -1,20 +1,10 @@ #include "qrw/InvKin.hpp" -#include <example-robot-data/path.hpp> - -#include "pinocchio/algorithm/compute-all-terms.hpp" -#include "pinocchio/algorithm/frames.hpp" -#include "pinocchio/algorithm/jacobian.hpp" -#include "pinocchio/algorithm/joint-configuration.hpp" -#include "pinocchio/math/rpy.hpp" -#include "pinocchio/parsers/urdf.hpp" -#include "pinocchio/spatial/explog.hpp" - InvKin::InvKin() : invJ(Matrix12::Zero()), - acc(Eigen::Matrix<double, 1, 30>::Zero()), - x_err(Eigen::Matrix<double, 1, 30>::Zero()), - dx_r(Eigen::Matrix<double, 1, 30>::Zero()), + acc(Eigen::Matrix<double, 1, 18>::Zero()), + x_err(Eigen::Matrix<double, 1, 18>::Zero()), + dx_r(Eigen::Matrix<double, 1, 18>::Zero()), pfeet_err(Matrix43::Zero()), vfeet_ref(Matrix43::Zero()), afeet(Matrix43::Zero()), @@ -40,8 +30,7 @@ InvKin::InvKin() awbasis(Vector3::Zero()), afeet_contacts_(Matrix43::Zero()), Jb_(Eigen::Matrix<double, 6, 18>::Zero()), - J_(Eigen::Matrix<double, 30, 18>::Zero()), - invJ_(Eigen::Matrix<double, 18, 30>::Zero()), + invJ_(Eigen::Matrix<double, 18, 18>::Zero()), ddq_cmd_(Vector18::Zero()), dq_cmd_(Vector18::Zero()), q_cmd_(Vector19::Zero()), @@ -101,28 +90,14 @@ void InvKin::refreshAndCompute(RowVector4 const& contacts, Matrix43 const& pgoal // Compute tasks accelerations and Jacobians ///// - // Accelerations references for the base / feet position task + // Accelerations references for the feet position task for (int i = 0; i < 4; i++) { // Feet acceleration pfeet_err.row(i) = pgoals.row(i) - posf_.row(i); vfeet_ref.row(i) = vgoals.row(i); - afeet.row(i) = +params_->Kp_flyingfeet * pfeet_err.row(i) + - params_->Kd_flyingfeet * (vfeet_ref.row(i) - vf_.row(i)) + agoals.row(i); - - // std::cout << "1: " << afeet.row(i) << std::endl; + afeet.row(i) = +params_->Kp_flyingfeet * pfeet_err.row(i); + afeet.row(i) += params_->Kd_flyingfeet * (vfeet_ref.row(i) - vf_.row(i)) + agoals.row(i); afeet.row(i) -= af_.row(i) + (wf_.row(i)).cross(vf_.row(i)); - // std::cout << "2: " << afeet.row(i) << std::endl; - - // Subtract base acceleration - afeet.row(i) -= (params_->Kd_flyingfeet * (vb_ref_ - vb_) - (ab_.head(3) + wb_.cross(vb_))).transpose(); - // std::cout << "3: " << afeet.row(i) << std::endl; - /*std::cout << vb_ref_.transpose() << std::endl; - std::cout << vb_.transpose() << std::endl; - std::cout << wb_.transpose() << std::endl; - std::cout << ab_.head(3).transpose() << std::endl; - std::cout << (vb_ref_ - vb_).transpose() << std::endl; - std::cout << (wb_.cross(vb_)).transpose() << std::endl;*/ - // std::cout << "---" << std::endl; } // Jacobian for the base / feet position task @@ -132,12 +107,9 @@ void InvKin::refreshAndCompute(RowVector4 const& contacts, Matrix43 const& pgoal // Acceleration references for the base linear velocity task posb_err_ = Vector3::Zero(); // No tracking in x, y, z - abasis = Kd_base_position.cwiseProduct(vb_ref_ - vb_); + abasis = Kp_base_position.cwiseProduct(posb_err_) + Kd_base_position.cwiseProduct(vb_ref_ - vb_); abasis -= ab_.head(3) + wb_.cross(vb_); - // Jacobian for the base linear velocity task - J_.block(0, 0, 3, 18) = Jb_.block(0, 0, 3, 18); - // Acceleration references for the base orientation task rotb_err_ = -rotb_ref_ * pinocchio::log3(rotb_ref_.transpose() * rotb_); rotb_err_(2, 0) = 0.0; // No tracking in yaw @@ -145,52 +117,6 @@ void InvKin::refreshAndCompute(RowVector4 const& contacts, Matrix43 const& pgoal Kd_base_orientation.cwiseProduct(wb_ref_ - wb_); // Roll, Pitch, Yaw awbasis -= ab_.tail(3); - // Jacobian for the base orientation task - J_.block(3, 0, 3, 18) = Jb_.block(3, 0, 3, 18); - - // Acceleration references for the non-moving contact task - /*int cpt = 0; - for (int i = 0; i < 4; i++) { - if (contacts(0, i) == 1.0) { - afeet_contacts_.row(cpt) = + params_->Kp_flyingfeet * pfeet_err.row(i) - + params_->Kd_flyingfeet * (vfeet_ref.row(i) - vf_.row(i)) - + agoals.row(i); - afeet_contacts_.row(cpt) -= af_.row(i) + (wf_.row(i)).cross(vf_.row(i)); - cpt++; - } - } - for (int i = cpt; i < 4; i++) { // Set to 0s the lines that are not used - afeet_contacts_.row(i).setZero(); - }*/ - for (int i = 0; i < 4; i++) { - if (contacts(0, i) == 1.0) { - afeet_contacts_.row(i) = +params_->Kp_flyingfeet * pfeet_err.row(i) + - params_->Kd_flyingfeet * (vfeet_ref.row(i) - vf_.row(i)) + agoals.row(i); - afeet_contacts_.row(i) -= af_.row(i) + (wf_.row(i)).cross(vf_.row(i)); - } else { - afeet_contacts_.row(i).setZero(); - } - } - - // Jacobian for the non-moving contact task - for (int i = 0; i < 4; i++) { - if (contacts(0, i) == 1.0) { // Store Jacobian of feet in contact - J_.block(18 + 3 * i, 0, 3, 18) = Jf_.block(3 * i, 0, 3, 18); - } else { - J_.block(18 + 3 * i, 0, 3, 18).setZero(); - } - } - /*cpt = 0; - for (int i = 0; i < 4; i++) { - if (contacts(0, i) == 1.0) { // Store Jacobian of feet in contact - J_.block(18 + 3 * cpt, 0, 3, 18) = Jf_.block(3*i, 0, 3, 18); - cpt++; - } - } - for (int i = cpt; i < 4; i++) { // Set to 0s the lines that are not used - J_.block(18 + 3 * i, 0, 3, 18).setZero(); - }*/ - ///// // Fill acceleration reference vector ///// @@ -203,10 +129,6 @@ void InvKin::refreshAndCompute(RowVector4 const& contacts, Matrix43 const& pgoal acc.block(0, 0, 1, 3) = abasis.transpose(); // Base angular task acc.block(0, 3, 1, 3) = awbasis.transpose(); - // Non-moving contact task - for (int i = 0; i < 4; i++) { - acc.block(0, 18 + 3 * i, 1, 3) = afeet_contacts_.row(i); - } ///// // Fill velocity reference vector @@ -214,16 +136,12 @@ void InvKin::refreshAndCompute(RowVector4 const& contacts, Matrix43 const& pgoal // Feet / base tracking task for (int i = 0; i < 4; i++) { - dx_r.block(0, 6 + 3 * i, 1, 3) = vfeet_ref.row(i) - vb_ref_.transpose(); + dx_r.block(0, 6 + 3 * i, 1, 3) = vfeet_ref.row(i); } // Base linear task dx_r.block(0, 0, 1, 3) = vb_ref_.transpose(); // Base angular task dx_r.block(0, 3, 1, 3) = wb_ref_.transpose(); - // Non-moving contact task - for (int i = 0; i < 4; i++) { - dx_r.block(0, 18 + 3 * i, 1, 3) = vfeet_ref.row(i); - } ///// // Fill position reference vector @@ -231,55 +149,54 @@ void InvKin::refreshAndCompute(RowVector4 const& contacts, Matrix43 const& pgoal // Feet / base tracking task for (int i = 0; i < 4; i++) { - x_err.block(0, 6 + 3 * i, 1, 3) = pfeet_err.row(i) - posb_err_.transpose(); + x_err.block(0, 6 + 3 * i, 1, 3) = pfeet_err.row(i); } // Base linear task x_err.block(0, 0, 1, 3) = posb_err_.transpose(); // Base angular task x_err.block(0, 3, 1, 3) = rotb_err_.transpose(); - // Non-moving contact task - for (int i = 0; i < 4; i++) { - x_err.block(0, 18 + 3 * i, 1, 3) = pfeet_err.row(i); - } ///// // Apply tasks weights ///// - // Product with tasks weights for Jacobian - J_.block(6, 0, 12, 18) *= w_tasks(0, 0); - for (int i = 0; i < 6; i++) { - J_.row(i) *= w_tasks(1 + i, 0); + if (contacts.isZero()) { + w_tasks.tail(7).setZero(); + } else { + w_tasks.tail(7).setOnes(); } - J_.block(18, 0, 12, 18) *= w_tasks(7, 0); // Product with tasks weights for acc references acc.block(6, 0, 1, 12) *= w_tasks(0, 0); for (int i = 0; i < 6; i++) { acc(0, i) *= w_tasks(1 + i, 0); } - acc.tail(12) *= w_tasks(7, 0); // Product with tasks weights for vel references dx_r.block(6, 0, 1, 12) *= w_tasks(0, 0); for (int i = 0; i < 6; i++) { dx_r(0, i) *= w_tasks(1 + i, 0); } - dx_r.tail(12) *= w_tasks(7, 0); // Product with tasks weights for pos references x_err.block(6, 0, 1, 12) *= w_tasks(0, 0); for (int i = 0; i < 6; i++) { x_err(0, i) *= w_tasks(1 + i, 0); } - x_err.tail(12) *= w_tasks(7, 0); ///// // Jacobian inversion ///// - // Using damped pseudo inverse - invJ_ = pseudoInverse(J_); + invJ_.block(0, 0, 3, 3) = Jb_.block(0, 0, 3, 3).transpose(); + invJ_.block(3, 3, 3, 3) = Jb_.block(0, 0, 3, 3).transpose(); + for (int i = 0; i < 4; i++) { + invJi_ = pseudoInverse(Jf_.block(3 * i, 6 + 3 * i, 3, 3)); + invJ_.block(6 + 3 * i, 0, 3, 3) = -invJi_; + pskew_ << 0.0, -posf_(i, 2), posf_(i, 1), posf_(i, 2), 0.0, -posf_(i, 0), -posf_(i, 1), posf_(i, 0), 0.0; + invJ_.block(6 + 3 * i, 3, 3, 3) = invJi_ * pskew_; + invJ_.block(6 + 3 * i, 6 + 3 * i, 3, 3) = invJi_; + } ///// // Compute command accelerations, velocities and positions @@ -317,7 +234,7 @@ void InvKin::refreshAndCompute(RowVector4 const& contacts, Matrix43 const& pgoal } void InvKin::run(VectorN const& q, VectorN const& dq, MatrixN const& contacts, MatrixN const& pgoals, - MatrixN const& vgoals, MatrixN const& agoals, MatrixN const& x_cmd) { + MatrixN const& vgoals, MatrixN const& agoals, MatrixN const& x_cmd) { // std::cout << "run invkin q: " << q << std::endl; // Update model and data of the robot