15 #include <boost/test/unit_test.hpp>
16 #include <boost/utility/binary.hpp>
18 BOOST_AUTO_TEST_SUITE(BOOST_TEST_MODULE)
20 using namespace Eigen;
29 VectorXd
q = VectorXd::Ones(
model.nq);
34 VectorXd
v = VectorXd::Ones(
model.nv);
35 VectorXd
tau = VectorXd::Random(
model.nv);
37 const std::string RF =
"rleg6_joint";
45 Motion::Vector6 gamma_RF;
48 gamma_RF +=
data.a[RF_id].toVector();
55 VectorXd ddq_ref =
data.ddq;
56 Force::Vector6 contact_force_ref =
data.lambda_c;
64 BOOST_CHECK(data_check.
tau.isApprox(
tau));
66 BOOST_CHECK(data_check.a[RF_id].toVector().isApprox(-gamma_RF));
69 VectorXd q_plus(
model.nq);
70 VectorXd v_eps(
model.nv);
73 VectorXd tau_plus(
tau);
74 const double eps = 1e-8;
80 for (
int k = 0; k <
model.nv; ++k)
90 Force::Vector6 contact_force_plus = data_fd.
lambda_c;
92 dddq_dtau.col(k) = (ddq_plus - ddq_ref) /
eps;
93 dlambda_dtau.col(k) = (contact_force_plus - contact_force_ref) /
eps;
99 data.M.transpose().triangularView<Eigen::Upper>() =
data.M.triangularView<Eigen::Upper>();
101 A.bottomLeftCorner(6,
model.nv) = J_RF;
102 A.topRightCorner(
model.nv, 6) = J_RF.transpose();
103 A.bottomRightCorner(6, 6).setZero();
105 MatrixXd Ainv =
A.inverse();
106 BOOST_CHECK(Ainv.topRows(
model.nv).leftCols(
model.nv).isApprox(dddq_dtau, std::sqrt(
eps)));
107 BOOST_CHECK(Ainv.bottomRows(6).leftCols(
model.nv).isApprox(-dlambda_dtau, std::sqrt(
eps)));
113 for (
int k = 0; k <
model.nv; ++k)
123 Force::Vector6 contact_force_plus = data_fd.
lambda_c;
125 dddq_dv.col(k) = (ddq_plus - ddq_ref) /
eps;
126 dlambda_dv.col(k) = (contact_force_plus - contact_force_ref) /
eps;
132 MatrixXd dddq_dv_anal = -Ainv.topRows(
model.nv).leftCols(
model.nv) * data_check.
dtau_dv;
133 MatrixXd dlambda_dv_anal = -Ainv.bottomRows(6).leftCols(
model.nv) * data_check.
dtau_dv;
135 BOOST_CHECK(dddq_dv_anal.isApprox(dddq_dv, std::sqrt(
eps)));
136 BOOST_CHECK(dlambda_dv_anal.isApprox(-dlambda_dv, std::sqrt(
eps)));
141 for (
int k = 0; k <
model.nv; ++k)
154 Force::Vector6 contact_force_plus = data_fd.
lambda_c;
156 dddq_dq.col(k) = (ddq_plus - ddq_ref) /
eps;
157 dlambda_dq.col(k) = (contact_force_plus - contact_force_ref) /
eps;
164 a_partial_da(6,
model.nv);
165 v_partial_dq.setZero();
166 a_partial_dq.setZero();
167 a_partial_dv.setZero();
168 a_partial_da.setZero();
172 model, data_kin, RF_id,
LOCAL, v_partial_dq, a_partial_dq, a_partial_dv, a_partial_da);
174 MatrixXd dddq_dq_anal = -Ainv.topRows(
model.nv).leftCols(
model.nv) * data_check.
dtau_dq;
175 dddq_dq_anal -= Ainv.topRows(
model.nv).rightCols(6) * a_partial_dq;
177 MatrixXd dlambda_dq_anal = Ainv.bottomRows(6).leftCols(
model.nv) * data_check.
dtau_dq;
178 dlambda_dq_anal += Ainv.bottomRows(6).rightCols(6) * a_partial_dq;
180 BOOST_CHECK(dddq_dq_anal.isApprox(dddq_dq, std::sqrt(
eps)));
181 BOOST_CHECK(dlambda_dq_anal.isApprox(dlambda_dq, std::sqrt(
eps)));
184 template<
typename ConfigVectorType,
typename TangentVectorType1,
typename TangentVectorType2>
188 const Eigen::MatrixBase<ConfigVectorType> & q,
189 const Eigen::MatrixBase<TangentVectorType1> &
v,
190 const Eigen::MatrixBase<TangentVectorType2> &
tau,
198 Motion::Vector6 gamma;
200 gamma =
data.a[
id].toVector();
207 VectorXd
res(VectorXd::Zero(
model.nv + 6));
221 VectorXd
q = VectorXd::Ones(
model.nq);
224 VectorXd
v = VectorXd::Random(
model.nv);
225 VectorXd
tau = VectorXd::Random(
model.nv);
227 const std::string RF =
"rleg6_joint";
234 Motion::Vector6 gamma_RF;
238 VectorXd ddq_ref = x_ref.head(
model.nv);
239 Force::Vector6 contact_force_ref = x_ref.tail(6);
247 BOOST_CHECK(data_check.
tau.isApprox(
tau));
249 BOOST_CHECK(data_check.a[RF_id].toVector().isZero());
252 VectorXd q_plus(
model.nq);
253 VectorXd v_eps(
model.nv);
256 VectorXd tau_plus(
tau);
257 VectorXd x_plus(
model.nv + 6);
258 const double eps = 1e-8;
264 for (
int k = 0; k <
model.nv; ++k)
270 Force::Vector6 contact_force_plus = x_plus.tail(6);
272 dddq_dtau.col(k) = (ddq_plus - ddq_ref) /
eps;
273 dlambda_dtau.col(k) = (contact_force_plus - contact_force_ref) /
eps;
279 data.M.transpose().triangularView<Eigen::Upper>() =
data.M.triangularView<Eigen::Upper>();
281 A.bottomLeftCorner(6,
model.nv) = J_RF;
282 A.topRightCorner(
model.nv, 6) = J_RF.transpose();
283 A.bottomRightCorner(6, 6).setZero();
285 MatrixXd Ainv =
A.inverse();
286 BOOST_CHECK(Ainv.topRows(
model.nv).leftCols(
model.nv).isApprox(dddq_dtau, std::sqrt(
eps)));
287 BOOST_CHECK(Ainv.bottomRows(6).leftCols(
model.nv).isApprox(-dlambda_dtau, std::sqrt(
eps)));
293 for (
int k = 0; k <
model.nv; ++k)
299 Force::Vector6 contact_force_plus = x_plus.tail(6);
301 dddq_dv.col(k) = (ddq_plus - ddq_ref) /
eps;
302 dlambda_dv.col(k) = (contact_force_plus - contact_force_ref) /
eps;
309 a_partial_da(6,
model.nv);
310 v_partial_dq.setZero();
311 a_partial_dq.setZero();
312 a_partial_dv.setZero();
313 a_partial_da.setZero();
317 model, data_kin, RF_id,
LOCAL, v_partial_dq, a_partial_dq, a_partial_dv, a_partial_da);
319 MatrixXd dddq_dv_anal = -Ainv.topRows(
model.nv).leftCols(
model.nv) * data_check.
dtau_dv;
320 dddq_dv_anal -= Ainv.topRows(
model.nv).rightCols(6) * a_partial_dv;
321 MatrixXd dlambda_dv_anal = -Ainv.bottomRows(6).leftCols(
model.nv) * data_check.
dtau_dv;
322 dlambda_dv_anal -= Ainv.bottomRows(6).rightCols(6) * a_partial_dv;
324 BOOST_CHECK(dddq_dv_anal.isApprox(dddq_dv, std::sqrt(
eps)));
325 BOOST_CHECK(dlambda_dv_anal.isApprox(-dlambda_dv, std::sqrt(
eps)));
330 for (
int k = 0; k <
model.nv; ++k)
338 Force::Vector6 contact_force_plus = x_plus.tail(6);
340 dddq_dq.col(k) = (ddq_plus - ddq_ref) /
eps;
341 dlambda_dq.col(k) = (contact_force_plus - contact_force_ref) /
eps;
347 v_partial_dq.setZero();
348 a_partial_dq.setZero();
349 a_partial_dv.setZero();
350 a_partial_da.setZero();
353 model, data_kin, RF_id,
LOCAL, v_partial_dq, a_partial_dq, a_partial_dv, a_partial_da);
355 MatrixXd dddq_dq_anal = -Ainv.topRows(
model.nv).leftCols(
model.nv) * data_check.
dtau_dq;
356 dddq_dq_anal -= Ainv.topRows(
model.nv).rightCols(6) * a_partial_dq;
358 BOOST_CHECK(dddq_dq_anal.isApprox(dddq_dq, std::sqrt(
eps)));
360 MatrixXd dlambda_dq_anal = Ainv.bottomRows(6).leftCols(
model.nv) * data_check.
dtau_dq;
361 dlambda_dq_anal += Ainv.bottomRows(6).rightCols(6) * a_partial_dq;
363 BOOST_CHECK(dlambda_dq_anal.isApprox(dlambda_dq, std::sqrt(
eps)));
366 BOOST_AUTO_TEST_SUITE_END()