1010namespace rcs {
1111namespace common {
1212
13- Pin::Pin (const std::string& path, const std::string& frame_id,
14- bool urdf = false )
13+ Pin::Pin (const std::string& path, const std::string& frame_id, bool urdf,
14+ const VectorXd& nullspace_q, double nullspace_gain,
15+ bool enforce_limits)
1516 : model() {
1617 if (urdf) {
1718 pinocchio::urdf::buildModel (path, this ->model );
@@ -24,6 +25,16 @@ Pin::Pin(const std::string& path, const std::string& frame_id,
2425 throw std::runtime_error (
2526 frame_id + " frame id could not be found in the provided URDF" );
2627 }
28+
29+ this ->q_lower = this ->model .lowerPositionLimit ;
30+ this ->q_upper = this ->model .upperPositionLimit ;
31+ this ->enforce_limits = enforce_limits;
32+
33+ this ->nullspace_gain = nullspace_gain;
34+ this ->nullspace_q = VectorXd::Zero (this ->model .nq );
35+ const Eigen::Index n =
36+ std::min<Eigen::Index>(nullspace_q.size (), this ->nullspace_q .size ());
37+ this ->nullspace_q .head (n) = nullspace_q.head (n);
2738}
2839
2940std::optional<VectorXd> Pin::inverse (const Pose& pose, const VectorXd& q0,
@@ -58,8 +69,26 @@ std::optional<VectorXd> Pin::inverse(const Pose& pose, const VectorXd& q0,
5869 pinocchio::Data::Matrix6 JJt;
5970 JJt.noalias () = J * J.transpose ();
6071 JJt.diagonal ().array () += this ->damp ;
61- v.noalias () = -J.transpose () * JJt.ldlt ().solve (err);
72+
73+ if (this ->nullspace_gain > 0.0 ) {
74+ Eigen::MatrixXd Jpinv =
75+ J.transpose () *
76+ JJt.ldlt ().solve (pinocchio::Data::Matrix6::Identity ());
77+ v.noalias () = -Jpinv * err;
78+
79+ VectorXd dq_ns (model.nv );
80+ pinocchio::difference (model, q, this ->nullspace_q , dq_ns);
81+ const Eigen::MatrixXd N =
82+ Eigen::MatrixXd::Identity (model.nv , model.nv ) - Jpinv * J;
83+ v.noalias () += N * (this ->nullspace_gain * dq_ns);
84+ } else {
85+ v.noalias () = -J.transpose () * JJt.ldlt ().solve (err);
86+ }
87+
6288 q = pinocchio::integrate (model, q, v * this ->DT );
89+ if (this ->enforce_limits ) {
90+ q = q.cwiseMax (this ->q_lower ).cwiseMin (this ->q_upper );
91+ }
6392 }
6493 if (success) {
6594 return q;
0 commit comments