Skip to content
Snippets Groups Projects
Commit de467244 authored by Justin Carpentier's avatar Justin Carpentier Committed by GitHub
Browse files

Merge pull request #309 from jmirabel/topic/planar_integrate

Topic/planar integrate
parents 3f034aa1 80db4ded
No related branches found
No related tags found
No related merge requests found
...@@ -394,31 +394,52 @@ namespace se3 ...@@ -394,31 +394,52 @@ namespace se3
{ {
Eigen::VectorXd::ConstFixedSegmentReturnType<NQ>::Type & q = qs.segment<NQ> (idx_q ()); Eigen::VectorXd::ConstFixedSegmentReturnType<NQ>::Type & q = qs.segment<NQ> (idx_q ());
Eigen::VectorXd::ConstFixedSegmentReturnType<NV>::Type & q_dot = vs.segment<NV> (idx_v ()); Eigen::VectorXd::ConstFixedSegmentReturnType<NV>::Type & q_dot = vs.segment<NV> (idx_v ());
typedef Transformation_t::Matrix3 Matrix3; typedef Eigen::Matrix<double, 2, 2> Matrix22;
typedef Eigen::Matrix<double, 2, 1> Vector2;
double c0,s0; SINCOS (q(2), &s0, &c0); double c0,s0; SINCOS (q(2), &s0, &c0);
Matrix3 R0(Matrix3::Identity()); Matrix22 R0;
R0.topLeftCorner <2,2> () << c0, -s0, s0, c0; R0 << c0, -s0, s0, c0;
const double& t = q_dot[2];
const double theta = std::fabs(t);
ConfigVector_t res(q); ConfigVector_t res(q);
if(std::fabs(q_dot(2)) > 1e-14) if(theta > 1e-14)
{ {
ConfigVector_t tmp(ConfigVector_t::Zero()); // q_dot = [ x, y, t ]
// w = [ 0, 0, t ]
double c1,s1; SINCOS (q_dot(2), &s1, &c1); // v = [ x, y, 0 ]
const double c_coeff = (1.-c1)/q_dot(2); // Considering only the 2x2 top left corner:
tmp.head<2>() = s1/q_dot(2)*q_dot.head<2>(); // Sp = [ 0, -1; 1, 0],
tmp(0) -= c_coeff*q_dot(1); // if t > 0: S = Sp
tmp(1) += c_coeff*q_dot(0); // else : S = -Sp
// S / t = Sp / |t|
res.head<2>() += R0.topLeftCorner<2,2>()*tmp.head<2>(); // S * S = - I2
res(2) += q_dot(2); // R = I2 + ( 1 - ct) / |t| * S + ( 1 - st / t ) * S * S
// = ( 1 - ct) / |t| * S + st / t * I2
//
// Ru = exp3 (w)
// tu = R * v = (1 - ct) / |t| * S * v + st / t * v
//
// M0 * Mu = ( R0 * Ru, R0 * tu + t0 )
Eigen::VectorXd::ConstFixedSegmentReturnType<2>::Type v = vs.segment<2>(idx_v());
double ct,st; SINCOS (theta, &st, &ct);
const double inv_theta = 1/theta;
const double c_coeff = (1.-ct) * inv_theta;
const double s_coeff = st * inv_theta;
const Vector2 Sp_v (-v[1], v[0]);
if (t > 0) res.head<2>() += R0 * (s_coeff * v + c_coeff * Sp_v);
else res.head<2>() += R0 * (s_coeff * v - c_coeff * Sp_v);
res[2] += t;
return res; return res;
} }
else else
{ {
res.head<2>() += R0.topLeftCorner<2,2>()*q_dot.head<2>(); res.head<2>() += R0*q_dot.head<2>();
res[2] += t;
} }
return res; return res;
...@@ -433,6 +454,8 @@ namespace se3 ...@@ -433,6 +454,8 @@ namespace se3
else if( u == 1) return q_1; else if( u == 1) return q_1;
else else
{ {
// TODO This only works if idx_v() == 0
assert(idx_v() == 0);
TangentVector_t nu(u*difference(q0, q1)); TangentVector_t nu(u*difference(q0, q1));
return integrate(q0, nu); return integrate(q0, nu);
} }
......
...@@ -83,9 +83,10 @@ namespace se3 ...@@ -83,9 +83,10 @@ namespace se3
Scalar t = w.norm(); Scalar t = w.norm();
if (t > 1e-15) if (t > 1e-15)
{ {
Matrix3 S(alphaSkew(1./t, w)); const double inv_t = 1./t;
Matrix3 S(alphaSkew(inv_t, w));
double ct,st; SINCOS (t,&st,&ct); double ct,st; SINCOS (t,&st,&ct);
Matrix3 V((1. - ct)/t * S + (1. - st/t) * S * S); Matrix3 V((1. - ct) * inv_t * S + (1. - st * inv_t) * S * S);
Vector3 p(v + V * v); Vector3 p(v + V * v);
return SE3Tpl<_Scalar, _Options>(exp3(w), p); return SE3Tpl<_Scalar, _Options>(exp3(w), p);
} }
......
...@@ -102,6 +102,19 @@ struct TestIntegrationJoint ...@@ -102,6 +102,19 @@ struct TestIntegrationJoint
SE3 M1_exp = M0*exp6(v0); SE3 M1_exp = M0*exp6(v0);
BOOST_CHECK(M1.isApprox(M1_exp)); BOOST_CHECK(M1.isApprox(M1_exp));
qdot *= -1;
jmodel.calc(jdata,q0,qdot);
M0 = jdata.M;
v0 = jdata.v;
q1 = jmodel.integrate(q0,qdot);
jmodel.calc(jdata,q1);
M1 = jdata.M;
M1_exp = M0*exp6(v0);
BOOST_CHECK(M1.isApprox(M1_exp));
} }
}; };
...@@ -175,6 +188,8 @@ struct TestDifferentiationJoint ...@@ -175,6 +188,8 @@ struct TestDifferentiationJoint
BOOST_CHECK_MESSAGE( jmodel.integrate(q0, qdot).isApprox(q1), std::string("Error in difference for joint " + jmodel.shortname())); BOOST_CHECK_MESSAGE( jmodel.integrate(q0, qdot).isApprox(q1), std::string("Error in difference for joint " + jmodel.shortname()));
BOOST_CHECK_MESSAGE( jmodel.integrate(q1, -qdot).isApprox(q0), std::string("Error in difference for joint " + jmodel.shortname()));
} }
void operator()(JointModelBase<JointModelFreeFlyer> & jmodel) void operator()(JointModelBase<JointModelFreeFlyer> & jmodel)
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment