5 #include "pinocchio/multibody/model.hpp" 6 #include "pinocchio/multibody/data.hpp" 7 #include "pinocchio/algorithm/jacobian.hpp" 8 #include "pinocchio/algorithm/joint-configuration.hpp" 9 #include "pinocchio/algorithm/rnea-second-order-derivatives.hpp" 10 #include "pinocchio/algorithm/rnea-derivatives.hpp" 11 #include "pinocchio/parsers/sample-models.hpp" 15 #include <boost/test/unit_test.hpp> 16 #include <boost/utility/binary.hpp> 18 BOOST_AUTO_TEST_SUITE(BOOST_TEST_MODULE)
21 using namespace Eigen;
47 VectorXd::Zero(model.
nv), dtau2_dq, dtau2_dv,
48 dtau2_dqdv, dtau2_dadq);
59 MatrixXd drnea_dq_plus(MatrixXd::Zero(model.
nv, model.
nv));
60 MatrixXd drnea_dv_plus(MatrixXd::Zero(model.
nv, model.
nv));
61 MatrixXd drnea_da_plus(MatrixXd::Zero(model.
nv, model.
nv));
63 MatrixXd temp1(MatrixXd::Zero(model.
nv, model.
nv));
64 MatrixXd temp2(MatrixXd::Zero(model.
nv, model.
nv));
70 MatrixXd rnea_partial_dq(MatrixXd::Zero(model.
nv, model.
nv));
71 MatrixXd rnea_partial_dv(MatrixXd::Zero(model.
nv, model.
nv));
72 MatrixXd rnea_partial_da(MatrixXd::Zero(model.
nv, model.
nv));
75 VectorXd::Zero(model.
nv), rnea_partial_dq,
76 rnea_partial_dv, rnea_partial_da);
78 const double alpha = 1e-7;
80 for (
int k = 0; k < model.
nv; ++k) {
84 VectorXd::Zero(model.
nv), drnea_dq_plus,
85 drnea_dv_plus, drnea_da_plus);
86 temp1 = (drnea_dq_plus - rnea_partial_dq) / alpha;
87 for (
int ii = 0; ii < model.
nv; ii++) {
88 for (
int jj = 0; jj < model.
nv; jj++) {
89 dtau2_dq_fd(jj, ii, k) = temp1(jj, ii);
95 Map<VectorXd> mq(dtau2_dq.
data(), dtau2_dq.
size());
96 Map<VectorXd> mq_fd(dtau2_dq_fd.
data(), dtau2_dq_fd.
size());
97 BOOST_CHECK(mq.isApprox(mq_fd, sqrt(alpha)));
105 dtau2_dq, dtau2_dv, dtau2_dqdv, dtau2_dadq);
107 rnea_partial_dq.setZero();
108 rnea_partial_dv.setZero();
109 rnea_partial_da.setZero();
118 rnea_partial_dq, rnea_partial_dv, rnea_partial_da);
120 for (
int k = 0; k < model.
nv; ++k) {
124 drnea_dq_plus, drnea_dv_plus, drnea_da_plus);
125 temp1 = (drnea_dq_plus - rnea_partial_dq) / alpha;
126 temp2 = (drnea_da_plus - rnea_partial_da) / alpha;
127 temp2.triangularView<Eigen::StrictlyLower>() =
128 temp2.transpose().triangularView<Eigen::StrictlyLower>();
129 for (
int ii = 0; ii < model.
nv; ii++) {
130 for (
int jj = 0; jj < model.
nv; jj++) {
131 dtau2_dq_fd(jj, ii, k) = temp1(jj, ii);
132 dtau2_dadq_fd(jj, ii, k) = temp2(jj, ii);
137 Map<VectorXd> maq(dtau2_dadq.
data(), dtau2_dadq.
size());
138 Map<VectorXd> maq_fd(dtau2_dadq_fd.
data(), dtau2_dadq_fd.
size());
140 BOOST_CHECK(mq.isApprox(mq_fd, sqrt(alpha)));
141 BOOST_CHECK(maq.isApprox(maq_fd, sqrt(alpha)));
151 rnea_partial_dq.setZero();
152 rnea_partial_dv.setZero();
153 rnea_partial_da.setZero();
163 for (
int k = 0; k < model.
nv; ++k) {
167 drnea_dv_plus, drnea_da_plus);
168 temp1 = (drnea_dq_plus - rnea_partial_dq) / alpha;
169 temp2 = (drnea_da_plus - rnea_partial_da) / alpha;
170 temp2.triangularView<Eigen::StrictlyLower>() =
171 temp2.transpose().triangularView<Eigen::StrictlyLower>();
172 for (
int ii = 0; ii < model.
nv; ii++) {
173 for (
int jj = 0; jj < model.
nv; jj++) {
174 dtau2_dq_fd(jj, ii, k) = temp1(jj, ii);
175 dtau2_dadq_fd(jj, ii, k) = temp2(jj, ii);
182 for (
int k = 0; k < model.
nv; ++k) {
186 drnea_dv_plus, drnea_da_plus);
187 temp1 = (drnea_dv_plus - rnea_partial_dv) / alpha;
188 temp2 = (drnea_dq_plus - rnea_partial_dq) / alpha;
189 for (
int ii = 0; ii < model.
nv; ii++) {
190 for (
int jj = 0; jj < model.
nv; jj++) {
191 dtau2_dv_fd(jj, ii, k) = temp1(jj, ii);
192 dtau2_dqdv_fd(jj, ii, k) = temp2(jj, ii);
197 Map<VectorXd> mv(dtau2_dv.
data(), dtau2_dv.
size());
198 Map<VectorXd> mv_fd(dtau2_dv_fd.
data(), dtau2_dv_fd.
size());
200 Map<VectorXd> mqv(dtau2_dqdv.
data(), dtau2_dqdv.
size());
201 Map<VectorXd> mqv_fd(dtau2_dqdv_fd.
data(), dtau2_dqdv_fd.
size());
203 BOOST_CHECK(mq.isApprox(mq_fd, sqrt(alpha)));
204 BOOST_CHECK(maq.isApprox(maq_fd, sqrt(alpha)));
205 BOOST_CHECK(mv.isApprox(mv_fd, sqrt(alpha)));
206 BOOST_CHECK(mqv.isApprox(mqv_fd, sqrt(alpha)));
211 Map<VectorXd> mq2(data2.d2tau_dqdq.data(), (data2.d2tau_dqdq).
size());
212 Map<VectorXd> mv2(data2.d2tau_dvdv.data(), (data2.d2tau_dvdv).
size());
213 Map<VectorXd> mqv2(data2.d2tau_dqdv.data(), (data2.d2tau_dqdv).
size());
214 Map<VectorXd> maq2(data2.d2tau_dadq.data(), (data2.d2tau_dadq).
size());
216 BOOST_CHECK(mq.isApprox(mq2, sqrt(alpha)));
217 BOOST_CHECK(mv.isApprox(mv2, sqrt(alpha)));
218 BOOST_CHECK(mqv.isApprox(mqv2, sqrt(alpha)));
219 BOOST_CHECK(maq.isApprox(maq2, sqrt(alpha)));
222 BOOST_AUTO_TEST_SUITE_END()
void integrate(const ModelTpl< Scalar, Options, JointCollectionTpl > &model, const Eigen::MatrixBase< ConfigVectorType > &q, const Eigen::MatrixBase< TangentVectorType > &v, const Eigen::MatrixBase< ReturnType > &qout)
Integrate a configuration vector for the specified model for a tangent vector during one unit time...
ConfigVectorType lowerPositionLimit
Lower joint configuration limit.
void randomConfiguration(const ModelTpl< Scalar, Options, JointCollectionTpl > &model, const Eigen::MatrixBase< ConfigVectorIn1 > &lowerLimits, const Eigen::MatrixBase< ConfigVectorIn2 > &upperLimits, const Eigen::MatrixBase< ReturnType > &qout)
Generate a configuration vector uniformly sampled among provided limits.
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Scalar * data()
BOOST_AUTO_TEST_CASE(test_rnea_derivatives_SO)
bp::tuple computeRNEADerivatives(const Model &model, Data &data, const Eigen::VectorXd &q, const Eigen::VectorXd &v, const Eigen::VectorXd &a)
Main pinocchio namespace.
void ComputeRNEASecondOrderDerivatives(const ModelTpl< Scalar, Options, JointCollectionTpl > &model, DataTpl< Scalar, Options, JointCollectionTpl > &data, const Eigen::MatrixBase< ConfigVectorType > &q, const Eigen::MatrixBase< TangentVectorType1 > &v, const Eigen::MatrixBase< TangentVectorType2 > &a, const Tensor1 &d2tau_dqdq, const Tensor2 &d2tau_dvdv, const Tensor3 &dtau_dqdv, const Tensor4 &dtau_dadq)
Computes the Second-Order partial derivatives of the Recursive Newton Euler Algorithm w...
int nv
Dimension of the velocity vector space.
ConfigVectorType upperPositionLimit
Upper joint configuration limit.
void humanoidRandom(ModelTpl< Scalar, Options, JointCollectionTpl > &model, bool usingFF=true)
Create a humanoid kinematic tree with 6-DOF limbs and random joint placements.
Eigen::Matrix< Scalar, Eigen::Dynamic, 1 > VectorXd
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Index size() const
int nq
Dimension of the configuration vector representation.
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Tensor & setZero()