20 #pragma GCC diagnostic push 21 #pragma GCC diagnostic ignored "-Wunused-parameter" 22 #pragma GCC diagnostic ignored "-Wunused-value" 24 #pragma GCC diagnostic pop 35 template <
class SYSTEM>
39 EIGEN_MAKE_ALIGNED_OPERATOR_NEW
41 static const bool FLOATING_BASE = SYSTEM::Dynamics::FB;
43 typedef std::shared_ptr<RbdLinearizer<SYSTEM>>
Ptr;
44 typedef typename SYSTEM::SCALAR
SCALAR;
46 static const size_t STATE_DIM = SYSTEM::STATE_DIM;
47 static const size_t CONTROL_DIM = SYSTEM::CONTROL_DIM;
48 static const size_t NJOINTS = SYSTEM::Dynamics::NJOINTS;
50 static_assert(SYSTEM::STATE_DIM == 2 * (SYSTEM::Dynamics::NJOINTS + FLOATING_BASE * 6),
51 "STATE DIMENSION MISMATCH. RBD LINEARIZER ONLY WORKS FOR PURE RIGID BODY DYNAMICS.");
52 static_assert(SYSTEM::CONTROL_DIM == SYSTEM::Dynamics::NJOINTS,
53 "CONTROL DIMENSION MISMATCH. RBD LINEARIZER ONLY WORKS FOR FULL JOINT CONTROLLED SYSTEMS.");
66 : Base(RBDSystem, doubleSidedDerivative), RBDSystem_(RBDSystem)
69 if (!FLOATING_BASE && (this->getType() != ct::core::SYSTEM_TYPE::SECOND_ORDER))
72 <<
"RbdLinearizer.h: Warning, fixed base system not declared as second order system. " 73 <<
"Normally, fixed base systems are second order systems and RbdLinearizer will treat them like this. " 74 <<
"To declare system as second order, see ct::core::System" << std::endl;
78 this->dFdx_.template topLeftCorner<STATE_DIM / 2, STATE_DIM / 2>().setZero();
79 this->dFdx_.template topRightCorner<STATE_DIM / 2, STATE_DIM / 2>().setIdentity();
82 this->dFdu_.template topRows<STATE_DIM / 2>().setZero();
89 const control_vector_t& u,
90 const SCALAR t = 0.0)
override 95 return Base::getDerivativeState(x, u,
t);
99 Base::getDerivativeState(x, u,
t);
102 kindr::EulerAnglesXyz<SCALAR> eulerXyz(x.template topRows<3>());
103 kindr::RotationMatrix<SCALAR> R_WB_kindr(eulerXyz);
105 Eigen::Matrix<SCALAR, 3, 6> jacAngVel =
106 jacobianOfAngularVelocityMapping(x.template topRows<3>(), x.template segment<3>(STATE_DIM / 2))
110 this->dFdx_.template block<3, 3>(0, 0) = jacAngVel.template block<3, 3>(0, 0);
112 this->dFdx_.template block<3, 3>(3, 0) =
113 -R_WB_kindr.toImplementation() *
114 JacobianOfRotationMultiplyVector(x.template topRows<3>(),
115 R_WB_kindr.
toImplementation() * (x.template segment<3>(STATE_DIM / 2 + 3)));
120 this->dFdx_.template block<3, 3>(0, STATE_DIM / 2) = jacAngVel.template block<3, 3>(0, 3);
125 this->dFdx_.template block<3, 3>(3, STATE_DIM / 2 + 3) = R_WB_kindr.toImplementation();
132 const control_vector_t& u,
133 const SCALAR t = 0.0)
override 135 const jsim_t& M = RBDSystem_->dynamics().kinematics().robcogen().jSim().update(
136 x.template segment<NJOINTS>(FLOATING_BASE * 6));
140 const typename jsim_t::MatrixType& M_inv = llt_.solve(jsim_t::Identity());
143 typename jsim_t::MatrixType Meigen = M;
144 if (!Meigen.inverse().isApprox(M_inv))
146 Eigen::SelfAdjointEigenSolver<typename jsim_t::MatrixType> eigensolver(M);
147 std::cout <<
"The eigenvalues of M are:\n" << eigensolver.eigenvalues().transpose() << std::endl;
148 std::cout <<
"M inverse incorrect" << std::endl;
149 std::cout <<
"M.inverse: " << std::endl << Meigen.inverse() << std::endl;
150 std::cout <<
"M_inv: " << std::endl << M_inv << std::endl;
155 M_temp.computeInverse();
156 auto M_inv_robcogen = M_temp.getInverse();
157 std::cout <<
"M_inv_robcogen: " << std::endl << M_inv_robcogen << std::endl;
161 auto& S = RBDSystem_->dynamics().S();
163 this->dFdu_.template block<STATE_DIM / 2, CONTROL_DIM>(STATE_DIM / 2, 0) = M_inv * S.transpose();
174 Eigen::LLT<typename jsim_t::MatrixType>
llt_;
178 Eigen::Matrix<SCALAR, 3, 3> JacobianOfRotationMultiplyVector(
const Eigen::Matrix<SCALAR, 3, 1>& theta,
179 const Eigen::Matrix<SCALAR, 3, 1>& vector)
181 const SCALAR& theta_1 = theta(0);
182 const SCALAR& theta_2 = theta(1);
183 const SCALAR& theta_3 = theta(2);
185 const SCALAR& vector_1 = vector(0);
186 const SCALAR& vector_2 = vector(1);
187 const SCALAR& vector_3 = vector(2);
190 Eigen::Matrix<SCALAR, 3, 3> A0;
194 SCALAR t2 = cos(theta_1);
195 SCALAR t3 = sin(theta_3);
196 SCALAR t4 = cos(theta_3);
197 SCALAR t5 = sin(theta_1);
198 SCALAR t6 = sin(theta_2);
199 SCALAR t7 = cos(theta_2);
201 SCALAR t9 = t2 * t3 * t6;
202 SCALAR t10 = t8 + t9;
203 SCALAR t11 = t2 * t4;
204 SCALAR t12 = t11 - t3 * t5 * t6;
205 SCALAR t13 = t6 * vector_1;
206 SCALAR t14 = t2 * t7 * vector_3;
207 SCALAR t15 = t13 + t14 - t5 * t7 * vector_2;
208 SCALAR t16 = t2 * t3;
209 SCALAR t17 = t4 * t5 * t6;
210 SCALAR t18 = t16 + t17;
211 SCALAR t19 = t3 * t5;
212 SCALAR t20 = t19 - t2 * t4 * t6;
213 A0(0, 0) = t18 * vector_3 - t20 * vector_2;
214 A0(0, 1) = -t4 * t15;
215 A0(0, 2) = t10 * vector_3 + t12 * vector_2 - t3 * t7 * vector_1;
216 A0(1, 0) = -t10 * vector_2 + t12 * vector_3;
218 A0(1, 2) = -t18 * vector_2 - t20 * vector_3 - t4 * t7 * vector_1;
219 A0(2, 0) = -t7 * (t2 * vector_2 + t5 * vector_3);
220 A0(2, 1) = t7 * vector_1 - t2 * t6 * vector_3 + t5 * t6 * vector_2;
236 Eigen::Matrix<SCALAR, 6, 3> jacobianOfAngularVelocityMapping(
const Eigen::Matrix<SCALAR, 3, 1>& eulerAnglesXyz,
237 const Eigen::Matrix<SCALAR, 3, 1>& angularVelocity)
241 Eigen::Matrix<SCALAR, 6, 1> xAD;
242 xAD << eulerAnglesXyz, angularVelocity;
243 const SCALAR*
x = xAD.data();
245 std::array<SCALAR, 10> v;
247 Eigen::Matrix<SCALAR, 6, 3> jac;
248 SCALAR* y = jac.data();
256 y[1] = 0 - (0 - (0 - x[4] * y[9] + x[3] * y[10]) * 1 / v[0] * v[1]) * v[2];
261 y[2] = 0 - x[3] * v[1] * v[3] + x[4] * v[4] * v[5];
262 y[8] = 0 - x[4] * v[3] + x[3] * v[5];
270 y[13] = (x[4] * v[6] + x[3] * v[7]) * v[0] - (0 - (v[9] * y[9] - v[8] * y[10]) * 1 / v[0] * v[1]) * v[2];
271 y[14] = 0 - v[8] * v[4] * v[3] + v[9] * v[1] * v[5];
RbdLinearizer< SYSTEM > * clone() const override
Definition: RbdLinearizer.h:87
const state_control_matrix_t & getDerivativeControl(const state_vector_t &x, const control_vector_t &u, const SCALAR t=0.0) override
Definition: RbdLinearizer.h:131
virtual ~RbdLinearizer() override
Definition: RbdLinearizer.h:86
tpl::JSIM< rbd::DoubleTrait > JSIM
Definition: jsim.h:154
ct::core::SystemLinearizer< STATE_DIM, CONTROL_DIM, SCALAR > Base
Definition: RbdLinearizer.h:51
RbdLinearizer(std::shared_ptr< SYSTEM > RBDSystem, bool doubleSidedDerivative=false)
Definition: RbdLinearizer.h:65
RbdLinearizer(const RbdLinearizer &arg)
Definition: RbdLinearizer.h:85
clear all close all load ct GNMSLog0 mat reformat t
std::shared_ptr< SYSTEM > RBDSystem_
Definition: RbdLinearizer.h:172
Eigen::LLT< typename jsim_t::MatrixType > llt_
Definition: RbdLinearizer.h:174
Base & toImplementation()
SYSTEM::SCALAR SCALAR
Definition: RbdLinearizer.h:44
ct::core::StateControlMatrix< STATE_DIM, CONTROL_DIM, SCALAR > state_control_matrix_t
Definition: RbdLinearizer.h:62
This is a common interface class for an RBDSystem.
Definition: RBDSystem.h:15
ct::core::ControlVector< CONTROL_DIM, SCALAR > control_vector_t
Definition: RbdLinearizer.h:59
ct::core::StateVector< state_dim > x
char operator()()
Definition: RbdLinearizer.h:29
const state_matrix_t & getDerivativeState(const state_vector_t &x, const control_vector_t &u, const SCALAR t=0.0) override
Definition: RbdLinearizer.h:88
ct::core::StateVector< STATE_DIM, SCALAR > state_vector_t
Definition: RbdLinearizer.h:58
SYSTEM::Dynamics::ROBCOGEN::JSIM jsim_t
Definition: RbdLinearizer.h:170
ct::core::StateMatrix< STATE_DIM, SCALAR > state_matrix_t
Definition: RbdLinearizer.h:61
std::shared_ptr< RbdLinearizer< SYSTEM > > Ptr
Definition: RbdLinearizer.h:43
Definition: RbdLinearizer.h:36
System Linearizer dedicated to Articulated Rigid Body Model.
Definition: RbdLinearizer.h:27