/* ---------------------------------------------------------------------------- * GTSAM Copyright 2010, Georgia Tech Research Corporation, * Atlanta, Georgia 30332-0415 * All Rights Reserved * Authors: Frank Dellaert, et al. (see THANKS for the full author list) * See LICENSE for the license information * -------------------------------------------------------------------------- */ /** * @file Scenario.h * @brief Simple class to test navigation scenarios * @author Frank Dellaert */ #pragma once #include #include namespace gtsam { /// Simple trajectory simulator. class Scenario { public: /// virtual destructor virtual ~Scenario() {} // Quantities a Scenario needs to specify: virtual Pose3 pose(double t) const = 0; ///< pose at time t virtual Vector3 omega_b(double t) const = 0; ///< angular velocity in body frame virtual Vector3 velocity_n(double t) const = 0; ///< velocity at time t, in nav frame virtual Vector3 acceleration_n(double t) const = 0; ///< acceleration in nav frame // Derived quantities: Rot3 rotation(double t) const { return pose(t).rotation(); } NavState navState(double t) const { return NavState(pose(t), velocity_n(t)); } Vector3 velocity_b(double t) const { const Rot3 nRb = rotation(t); return nRb.transpose() * velocity_n(t); } Vector3 acceleration_b(double t) const { const Rot3 nRb = rotation(t); return nRb.transpose() * acceleration_n(t); } }; /** * Scenario with constant twist 3D trajectory. * Note that a plane flying level does not feel any acceleration: gravity is * being perfectly compensated by the lift generated by the wings, and drag is * compensated by thrust. The accelerometer will add the gravity component back * in, as modeled by the specificForce method in ScenarioRunner. */ class ConstantTwistScenario : public Scenario { public: /// Construct scenario with constant twist [w,v] ConstantTwistScenario(const Vector3& w, const Vector3& v, const Pose3& nTb0 = Pose3()) : twist_((Vector6() << w, v).finished()), a_b_(w.cross(v)), nTb0_(nTb0) {} Pose3 pose(double t) const override { return nTb0_ * Pose3::Expmap(twist_ * t); } Vector3 omega_b(double t) const override { return twist_.head<3>(); } Vector3 velocity_n(double t) const override { return rotation(t).matrix() * twist_.tail<3>(); } Vector3 acceleration_n(double t) const override { return rotation(t) * a_b_; } private: const Vector6 twist_; const Vector3 a_b_; // constant centripetal acceleration in body = w_b * v_b const Pose3 nTb0_; }; /// Accelerating from an arbitrary initial state, with optional rotation class AcceleratingScenario : public Scenario { public: /// Construct scenario with constant acceleration in navigation frame and /// optional angular velocity in body: rotating while translating... AcceleratingScenario(const Rot3& nRb, const Point3& p0, const Vector3& v0, const Vector3& a_n, const Vector3& omega_b = Vector3::Zero()) : nRb_(nRb), p0_(p0), v0_(v0), a_n_(a_n), omega_b_(omega_b) {} Pose3 pose(double t) const override { return Pose3(nRb_.expmap(omega_b_ * t), p0_ + v0_ * t + a_n_ * t * t / 2.0); } Vector3 omega_b(double t) const override { return omega_b_; } Vector3 velocity_n(double t) const override { return v0_ + a_n_ * t; } Vector3 acceleration_n(double t) const override { return a_n_; } private: const Rot3 nRb_; const Vector3 p0_, v0_, a_n_, omega_b_; }; } // namespace gtsam