Pose3 interpolateRt method (#647)

* Pose3 interpolate() which correctly interpolates between poses

* Pose3 template specialization for interpolate

* added easy-to-verify test for Pose3 interpolate

* added new Pose3 interpolateRt function, updated tests

* update documentation of interpolateRt

* update docs and tests
release/4.3a0
Varun Agrawal 2020-12-31 13:21:24 -05:00 committed by GitHub
parent 2597a7cf1f
commit bac74dbde5
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 46 additions and 0 deletions

View File

@ -112,6 +112,25 @@ public:
return Pose3(R_ * T.R_, t_ + R_ * T.t_);
}
/**
* Interpolate between two poses via individual rotation and translation
* interpolation.
*
* The default "interpolate" method defined in Lie.h minimizes the geodesic
* distance on the manifold, leading to a screw motion interpolation in
* Cartesian space, which might not be what is expected.
* In contrast, this method executes a straight line interpolation for the
* translation, while still using interpolate (aka "slerp") for the rotational
* component. This might be more intuitive in many applications.
*
* @param T End point of interpolation.
* @param t A value in [0, 1].
*/
Pose3 interpolateRt(const Pose3& T, double t) const {
return Pose3(interpolate<Rot3>(R_, T.R_, t),
interpolate<Point3>(t_, T.t_, t));
}
/// @}
/// @name Lie Group
/// @{

View File

@ -1016,6 +1016,33 @@ TEST(Pose3, TransformCovariance6) {
TEST(Pose3, interpolate) {
EXPECT(assert_equal(T2, interpolate(T2,T3, 0.0)));
EXPECT(assert_equal(T3, interpolate(T2,T3, 1.0)));
// Trivial example: start at origin and move to (1, 0, 0) while rotating pi/2
// about z-axis.
Pose3 start;
Pose3 end(Rot3::Rz(M_PI_2), Point3(1, 0, 0));
// This interpolation is easy to calculate by hand.
double t = 0.5;
Pose3 expected0(Rot3::Rz(M_PI_4), Point3(0.5, 0, 0));
EXPECT(assert_equal(expected0, start.interpolateRt(end, t)));
// Example from Peter Corke
// https://robotacademy.net.au/lesson/interpolating-pose-in-3d/
t = 0.0759; // corresponds to the 10th element when calling `ctraj` in
// the video
Pose3 O;
Pose3 F(Rot3::Roll(0.6).compose(Rot3::Pitch(0.8)).compose(Rot3::Yaw(1.4)),
Point3(1, 2, 3));
// The expected answer matches the result presented in the video.
Pose3 expected1(interpolate(O.rotation(), F.rotation(), t),
interpolate(O.translation(), F.translation(), t));
EXPECT(assert_equal(expected1, O.interpolateRt(F, t)));
// Non-trivial interpolation, translation value taken from output.
Pose3 expected2(interpolate(T2.rotation(), T3.rotation(), t),
interpolate(T2.translation(), T3.translation(), t));
EXPECT(assert_equal(expected2, T2.interpolateRt(T3, t)));
}
/* ************************************************************************* */