Merge pull request #499 from Eskilade/add_Rot3_RzRyRx_jacobian
Added Jacobians for Rot3::RzRyRx and related named constructorsrelease/4.3a0
						commit
						64a6e90b90
					
				| 
						 | 
					@ -154,12 +154,23 @@ namespace gtsam {
 | 
				
			||||||
    static Rot3 Rz(double t);
 | 
					    static Rot3 Rz(double t);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /// Rotations around Z, Y, then X axes as in http://en.wikipedia.org/wiki/Rotation_matrix, counterclockwise when looking from unchanging axis.
 | 
					    /// Rotations around Z, Y, then X axes as in http://en.wikipedia.org/wiki/Rotation_matrix, counterclockwise when looking from unchanging axis.
 | 
				
			||||||
    static Rot3 RzRyRx(double x, double y, double z);
 | 
					    static Rot3 RzRyRx(double x, double y, double z,
 | 
				
			||||||
 | 
					                       OptionalJacobian<3, 1> Hx = boost::none,
 | 
				
			||||||
 | 
					                       OptionalJacobian<3, 1> Hy = boost::none,
 | 
				
			||||||
 | 
					                       OptionalJacobian<3, 1> Hz = boost::none);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /// Rotations around Z, Y, then X axes as in http://en.wikipedia.org/wiki/Rotation_matrix, counterclockwise when looking from unchanging axis.
 | 
					    /// Rotations around Z, Y, then X axes as in http://en.wikipedia.org/wiki/Rotation_matrix, counterclockwise when looking from unchanging axis.
 | 
				
			||||||
    inline static Rot3 RzRyRx(const Vector& xyz) {
 | 
					    inline static Rot3 RzRyRx(const Vector& xyz,
 | 
				
			||||||
 | 
					                              OptionalJacobian<3, 3> H = boost::none) {
 | 
				
			||||||
      assert(xyz.size() == 3);
 | 
					      assert(xyz.size() == 3);
 | 
				
			||||||
      return RzRyRx(xyz(0), xyz(1), xyz(2));
 | 
					      Rot3 out;
 | 
				
			||||||
 | 
					      if (H) {
 | 
				
			||||||
 | 
					        Vector3 Hx, Hy, Hz;
 | 
				
			||||||
 | 
					        out = RzRyRx(xyz(0), xyz(1), xyz(2), Hx, Hy, Hz);
 | 
				
			||||||
 | 
					        (*H) << Hx, Hy, Hz;
 | 
				
			||||||
 | 
					      } else
 | 
				
			||||||
 | 
					        out = RzRyRx(xyz(0), xyz(1), xyz(2));
 | 
				
			||||||
 | 
					      return out;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /// Positive yaw is to right (as in aircraft heading). See ypr
 | 
					    /// Positive yaw is to right (as in aircraft heading). See ypr
 | 
				
			||||||
| 
						 | 
					@ -185,7 +196,12 @@ namespace gtsam {
 | 
				
			||||||
     * Positive pitch is down (decreasing aircraft altitude).
 | 
					     * Positive pitch is down (decreasing aircraft altitude).
 | 
				
			||||||
     * Positive roll is to right (decreasing yaw in aircraft).
 | 
					     * Positive roll is to right (decreasing yaw in aircraft).
 | 
				
			||||||
     */
 | 
					     */
 | 
				
			||||||
    static Rot3 Ypr(double y, double p, double r) { return RzRyRx(r,p,y);}
 | 
					    static Rot3 Ypr(double y, double p, double r,
 | 
				
			||||||
 | 
					                    OptionalJacobian<3, 1> Hy = boost::none,
 | 
				
			||||||
 | 
					                    OptionalJacobian<3, 1> Hp = boost::none,
 | 
				
			||||||
 | 
					                    OptionalJacobian<3, 1> Hr = boost::none) {
 | 
				
			||||||
 | 
					      return RzRyRx(r, p, y, Hr, Hp, Hy);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /** Create from Quaternion coefficients */
 | 
					    /** Create from Quaternion coefficients */
 | 
				
			||||||
    static Rot3 Quaternion(double w, double x, double y, double z) {
 | 
					    static Rot3 Quaternion(double w, double x, double y, double z) {
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -82,7 +82,8 @@ Rot3 Rot3::Rz(double t) {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* ************************************************************************* */
 | 
					/* ************************************************************************* */
 | 
				
			||||||
// Considerably faster than composing matrices above !
 | 
					// Considerably faster than composing matrices above !
 | 
				
			||||||
Rot3 Rot3::RzRyRx(double x, double y, double z) {
 | 
					Rot3 Rot3::RzRyRx(double x, double y, double z, OptionalJacobian<3, 1> Hx,
 | 
				
			||||||
 | 
					                  OptionalJacobian<3, 1> Hy, OptionalJacobian<3, 1> Hz) {
 | 
				
			||||||
  double cx=cos(x),sx=sin(x);
 | 
					  double cx=cos(x),sx=sin(x);
 | 
				
			||||||
  double cy=cos(y),sy=sin(y);
 | 
					  double cy=cos(y),sy=sin(y);
 | 
				
			||||||
  double cz=cos(z),sz=sin(z);
 | 
					  double cz=cos(z),sz=sin(z);
 | 
				
			||||||
| 
						 | 
					@ -97,6 +98,9 @@ Rot3 Rot3::RzRyRx(double x, double y, double z) {
 | 
				
			||||||
  double s_c = sx * cz;
 | 
					  double s_c = sx * cz;
 | 
				
			||||||
  double c_c = cx * cz;
 | 
					  double c_c = cx * cz;
 | 
				
			||||||
  double ssc = ss_ * cz, csc = cs_ * cz, sss = ss_ * sz, css = cs_ * sz;
 | 
					  double ssc = ss_ * cz, csc = cs_ * cz, sss = ss_ * sz, css = cs_ * sz;
 | 
				
			||||||
 | 
					  if (Hx) (*Hx) << 1, 0, 0;
 | 
				
			||||||
 | 
					  if (Hy) (*Hy) << 0, cx, -sx;
 | 
				
			||||||
 | 
					  if (Hz) (*Hz) << -sy, sc_, cc_;
 | 
				
			||||||
  return Rot3(
 | 
					  return Rot3(
 | 
				
			||||||
      _cc,- c_s + ssc,  s_s + csc,
 | 
					      _cc,- c_s + ssc,  s_s + csc,
 | 
				
			||||||
      _cs,  c_c + sss, -s_c + css,
 | 
					      _cs,  c_c + sss, -s_c + css,
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -67,7 +67,20 @@ namespace gtsam {
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  /* ************************************************************************* */
 | 
					  /* ************************************************************************* */
 | 
				
			||||||
  Rot3 Rot3::RzRyRx(double x, double y, double z) { return Rot3(
 | 
					  Rot3 Rot3::RzRyRx(double x, double y, double z, OptionalJacobian<3, 1> Hx,
 | 
				
			||||||
 | 
					                    OptionalJacobian<3, 1> Hy, OptionalJacobian<3, 1> Hz) {
 | 
				
			||||||
 | 
					    if (Hx) (*Hx) << 1, 0, 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if (Hy or Hz) {
 | 
				
			||||||
 | 
					      const auto cx = cos(x), sx = sin(x);
 | 
				
			||||||
 | 
					      if (Hy) (*Hy) << 0, cx, -sx;
 | 
				
			||||||
 | 
					      if (Hz) {
 | 
				
			||||||
 | 
					        const auto cy = cos(y), sy = sin(y);
 | 
				
			||||||
 | 
					        (*Hz) << -sy, sx * cy, cx * cy;
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    return Rot3(
 | 
				
			||||||
        gtsam::Quaternion(Eigen::AngleAxisd(z, Eigen::Vector3d::UnitZ())) *
 | 
					        gtsam::Quaternion(Eigen::AngleAxisd(z, Eigen::Vector3d::UnitZ())) *
 | 
				
			||||||
        gtsam::Quaternion(Eigen::AngleAxisd(y, Eigen::Vector3d::UnitY())) *
 | 
					        gtsam::Quaternion(Eigen::AngleAxisd(y, Eigen::Vector3d::UnitY())) *
 | 
				
			||||||
        gtsam::Quaternion(Eigen::AngleAxisd(x, Eigen::Vector3d::UnitX())));
 | 
					        gtsam::Quaternion(Eigen::AngleAxisd(x, Eigen::Vector3d::UnitX())));
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -743,6 +743,57 @@ TEST(Rot3, axisAngle) {
 | 
				
			||||||
  CHECK_AXIS_ANGLE(_axis, theta165, Rot3::AxisAngle(axis, theta195))
 | 
					  CHECK_AXIS_ANGLE(_axis, theta165, Rot3::AxisAngle(axis, theta195))
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* ************************************************************************* */
 | 
				
			||||||
 | 
					Rot3 RzRyRx_proxy(double const& a, double const& b, double const& c) {
 | 
				
			||||||
 | 
					  return Rot3::RzRyRx(a, b, c);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					TEST(Rot3, RzRyRx_scalars_derivative) {
 | 
				
			||||||
 | 
					  const auto x = 0.1, y = 0.4, z = 0.2;
 | 
				
			||||||
 | 
					  const auto num_x = numericalDerivative31(RzRyRx_proxy, x, y, z);
 | 
				
			||||||
 | 
					  const auto num_y = numericalDerivative32(RzRyRx_proxy, x, y, z);
 | 
				
			||||||
 | 
					  const auto num_z = numericalDerivative33(RzRyRx_proxy, x, y, z);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  Vector3 act_x, act_y, act_z;
 | 
				
			||||||
 | 
					  Rot3::RzRyRx(x, y, z, act_x, act_y, act_z);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  CHECK(assert_equal(num_x, act_x));
 | 
				
			||||||
 | 
					  CHECK(assert_equal(num_y, act_y));
 | 
				
			||||||
 | 
					  CHECK(assert_equal(num_z, act_z));
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* ************************************************************************* */
 | 
				
			||||||
 | 
					Rot3 RzRyRx_proxy(Vector3 const& xyz) { return Rot3::RzRyRx(xyz); }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					TEST(Rot3, RzRyRx_vector_derivative) {
 | 
				
			||||||
 | 
					  const auto xyz = Vector3{-0.3, 0.1, 0.7};
 | 
				
			||||||
 | 
					  const auto num = numericalDerivative11(RzRyRx_proxy, xyz);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  Matrix3 act;
 | 
				
			||||||
 | 
					  Rot3::RzRyRx(xyz, act);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  CHECK(assert_equal(num, act));
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* ************************************************************************* */
 | 
				
			||||||
 | 
					Rot3 Ypr_proxy(double const& y, double const& p, double const& r) {
 | 
				
			||||||
 | 
					  return Rot3::Ypr(y, p, r);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					TEST(Rot3, Ypr_derivative) {
 | 
				
			||||||
 | 
					  const auto y = 0.7, p = -0.3, r = 0.1;
 | 
				
			||||||
 | 
					  const auto num_y = numericalDerivative31(Ypr_proxy, y, p, r);
 | 
				
			||||||
 | 
					  const auto num_p = numericalDerivative32(Ypr_proxy, y, p, r);
 | 
				
			||||||
 | 
					  const auto num_r = numericalDerivative33(Ypr_proxy, y, p, r);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  Vector3 act_y, act_p, act_r;
 | 
				
			||||||
 | 
					  Rot3::Ypr(y, p, r, act_y, act_p, act_r);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  CHECK(assert_equal(num_y, act_y));
 | 
				
			||||||
 | 
					  CHECK(assert_equal(num_p, act_p));
 | 
				
			||||||
 | 
					  CHECK(assert_equal(num_r, act_r));
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* ************************************************************************* */
 | 
					/* ************************************************************************* */
 | 
				
			||||||
int main() {
 | 
					int main() {
 | 
				
			||||||
  TestResult tr;
 | 
					  TestResult tr;
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
		Reference in New Issue