Further examining a circular trajectory
parent
5f9053ae39
commit
699ba32c9e
|
|
@ -20,33 +20,49 @@
|
||||||
|
|
||||||
namespace gtsam {
|
namespace gtsam {
|
||||||
|
|
||||||
/// Simple class with constant twist 3D trajectory
|
/**
|
||||||
|
* Simple class with constant twist 3D trajectory.
|
||||||
|
* It is also assumed that gravity is magically counteracted and has no effect
|
||||||
|
* on trajectory. Hence, a simulated IMU yields the actual body angular
|
||||||
|
* velocity, and negative G acceleration plus the acceleration created by the
|
||||||
|
* rotating body frame.
|
||||||
|
*/
|
||||||
class Scenario {
|
class Scenario {
|
||||||
public:
|
public:
|
||||||
/// Construct scenario with constant twist [w,v]
|
/// Construct scenario with constant twist [w,v]
|
||||||
Scenario(const Vector3& w, const Vector3& v, double imuSampleTime = 1e-2)
|
Scenario(const Vector3& w, const Vector3& v,
|
||||||
|
double imuSampleTime = 1.0 / 100.0)
|
||||||
: twist_((Vector6() << w, v).finished()), imuSampleTime_(imuSampleTime) {}
|
: twist_((Vector6() << w, v).finished()), imuSampleTime_(imuSampleTime) {}
|
||||||
|
|
||||||
|
const double& imuSampleTime() const { return imuSampleTime_; }
|
||||||
|
|
||||||
// NOTE(frank): hardcoded for now with Z up (gravity points in negative Z)
|
// NOTE(frank): hardcoded for now with Z up (gravity points in negative Z)
|
||||||
// also, uses g=10 for easy debugging
|
// also, uses g=10 for easy debugging
|
||||||
Vector3 gravity() const { return Vector3(0, 0, -10.0); }
|
Vector3 gravity() const { return Vector3(0, 0, -10.0); }
|
||||||
|
|
||||||
Vector3 groundTruthGyroInBody() const { return twist_.head<3>(); }
|
Vector3 angularVelocityInBody() const { return twist_.head<3>(); }
|
||||||
Vector3 groundTruthVelocityInBody() const { return twist_.tail<3>(); }
|
Vector3 linearVelocityInBody() const { return twist_.tail<3>(); }
|
||||||
|
|
||||||
// All constant twist scenarios have zero acceleration
|
/// Rotation of body in nav frame at time t
|
||||||
Vector3 groundTruthAccInBody() const { return Vector3::Zero(); }
|
Rot3 rotAtTime(double t) const {
|
||||||
|
return Rot3::Expmap(angularVelocityInBody() * t);
|
||||||
const double& imuSampleTime() const { return imuSampleTime_; }
|
}
|
||||||
|
|
||||||
/// Pose of body in nav frame at time t
|
/// Pose of body in nav frame at time t
|
||||||
Pose3 poseAtTime(double t) { return Pose3::Expmap(twist_ * t); }
|
Pose3 poseAtTime(double t) const { return Pose3::Expmap(twist_ * t); }
|
||||||
|
|
||||||
/// Velocity in nav frame at time t
|
/// Velocity in nav frame at time t
|
||||||
Vector3 velocityAtTime(double t) {
|
Vector3 velocityAtTime(double t) {
|
||||||
const Pose3 pose = poseAtTime(t);
|
const Rot3 nRb = rotAtTime(t);
|
||||||
const Rot3& nRb = pose.rotation();
|
return nRb * linearVelocityInBody();
|
||||||
return nRb * groundTruthVelocityInBody();
|
}
|
||||||
|
|
||||||
|
// acceleration in nav frame
|
||||||
|
Vector3 accelerationAtTime(double t) const {
|
||||||
|
const Rot3 nRb = rotAtTime(t);
|
||||||
|
const Vector3 centripetalAcceleration =
|
||||||
|
angularVelocityInBody().cross(linearVelocityInBody());
|
||||||
|
return nRb * centripetalAcceleration - gravity();
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
|
||||||
|
|
@ -18,6 +18,8 @@
|
||||||
#include <gtsam/navigation/ImuFactor.h>
|
#include <gtsam/navigation/ImuFactor.h>
|
||||||
#include <gtsam/navigation/Scenario.h>
|
#include <gtsam/navigation/Scenario.h>
|
||||||
|
|
||||||
|
#include <iostream>
|
||||||
|
|
||||||
namespace gtsam {
|
namespace gtsam {
|
||||||
|
|
||||||
double accNoiseVar = 0.01;
|
double accNoiseVar = 0.01;
|
||||||
|
|
@ -42,11 +44,17 @@ class ScenarioRunner {
|
||||||
zeroBias, kMeasuredAccCovariance, kMeasuredOmegaCovariance,
|
zeroBias, kMeasuredAccCovariance, kMeasuredOmegaCovariance,
|
||||||
kIntegrationErrorCovariance, use2ndOrderCoriolis);
|
kIntegrationErrorCovariance, use2ndOrderCoriolis);
|
||||||
|
|
||||||
const Vector3 measuredAcc = scenario_.groundTruthAccInBody();
|
const Vector3 measuredOmega = scenario_.angularVelocityInBody();
|
||||||
const Vector3 measuredOmega = scenario_.groundTruthGyroInBody();
|
const double deltaT = scenario_.imuSampleTime();
|
||||||
double deltaT = scenario_.imuSampleTime();
|
const size_t nrSteps = T / deltaT;
|
||||||
for (double t = 0; t <= T; t += deltaT) {
|
double t = 0;
|
||||||
|
for (size_t k = 0; k < nrSteps; k++, t += deltaT) {
|
||||||
|
std::cout << t << ", " << deltaT << ": ";
|
||||||
|
const Vector3 measuredAcc = scenario_.accelerationAtTime(t);
|
||||||
result.integrateMeasurement(measuredAcc, measuredOmega, deltaT);
|
result.integrateMeasurement(measuredAcc, measuredOmega, deltaT);
|
||||||
|
// std::cout << result.deltaRij() << std::endl;
|
||||||
|
std::cout << " a:" << measuredAcc.transpose();
|
||||||
|
std::cout << " P:" << result.deltaVij().transpose() << std::endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
|
|
@ -87,13 +95,13 @@ using namespace gtsam;
|
||||||
|
|
||||||
static const double degree = M_PI / 180.0;
|
static const double degree = M_PI / 180.0;
|
||||||
|
|
||||||
/* ************************************************************************* */
|
/* ************************************************************************* *
|
||||||
TEST(ScenarioRunner, Forward) {
|
TEST(ScenarioRunner, Forward) {
|
||||||
const double v = 2; // m/s
|
const double v = 2; // m/s
|
||||||
Scenario forward(Vector3::Zero(), Vector3(v, 0, 0));
|
Scenario forward(Vector3::Zero(), Vector3(v, 0, 0));
|
||||||
|
|
||||||
ScenarioRunner runner(forward);
|
ScenarioRunner runner(forward);
|
||||||
const double T = 10; // seconds
|
const double T = 1; // seconds
|
||||||
ImuFactor::PreintegratedMeasurements integrated = runner.integrate(T);
|
ImuFactor::PreintegratedMeasurements integrated = runner.integrate(T);
|
||||||
EXPECT(assert_equal(forward.poseAtTime(T), runner.mean(integrated), 1e-9));
|
EXPECT(assert_equal(forward.poseAtTime(T), runner.mean(integrated), 1e-9));
|
||||||
}
|
}
|
||||||
|
|
@ -102,7 +110,7 @@ TEST(ScenarioRunner, Forward) {
|
||||||
TEST(ScenarioRunner, Circle) {
|
TEST(ScenarioRunner, Circle) {
|
||||||
// Forward velocity 2m/s, angular velocity 6 degree/sec
|
// Forward velocity 2m/s, angular velocity 6 degree/sec
|
||||||
const double v = 2, omega = 6 * degree;
|
const double v = 2, omega = 6 * degree;
|
||||||
Scenario circle(Vector3(0, 0, omega), Vector3(v, 0, 0));
|
Scenario circle(Vector3(0, 0, omega), Vector3(v, 0, 0), 0.1);
|
||||||
|
|
||||||
ScenarioRunner runner(circle);
|
ScenarioRunner runner(circle);
|
||||||
const double T = 15; // seconds
|
const double T = 15; // seconds
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue