Moved to header
parent
f6731fe559
commit
419de466c0
|
|
@ -17,12 +17,70 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <gtsam/nonlinear/NonlinearFactor.h>
|
#include <gtsam/nonlinear/NonlinearFactor.h>
|
||||||
|
#include <gtsam/geometry/Rot2.h>
|
||||||
#include <gtsam/geometry/Rot3.h>
|
#include <gtsam/geometry/Rot3.h>
|
||||||
#include <gtsam/base/LieVector.h>
|
#include <gtsam/base/LieVector.h>
|
||||||
#include <gtsam/base/LieScalar.h>
|
#include <gtsam/base/LieScalar.h>
|
||||||
|
|
||||||
namespace gtsam {
|
namespace gtsam {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Factor to estimate rotation given magnetometer reading
|
||||||
|
* This version uses model measured bM = scale * bRn * direction + bias
|
||||||
|
* and assumes scale, direction, and the bias are given
|
||||||
|
*/
|
||||||
|
class MagFactor: public NoiseModelFactor1<Rot2> {
|
||||||
|
|
||||||
|
const Vector3 measured_; /** The measured magnetometer values */
|
||||||
|
const double scale_;
|
||||||
|
const Sphere2 direction_;
|
||||||
|
const Vector3 bias_;
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
/** Constructor */
|
||||||
|
MagFactor(Key key, const Vector3& measured, const LieScalar& scale,
|
||||||
|
const Sphere2& direction, const LieVector& bias,
|
||||||
|
const SharedNoiseModel& model) :
|
||||||
|
NoiseModelFactor1<Rot2>(model, key), //
|
||||||
|
measured_(measured), scale_(scale), direction_(direction), bias_(bias) {
|
||||||
|
}
|
||||||
|
|
||||||
|
/// @return a deep copy of this factor
|
||||||
|
virtual NonlinearFactor::shared_ptr clone() const {
|
||||||
|
return boost::static_pointer_cast<NonlinearFactor>(
|
||||||
|
NonlinearFactor::shared_ptr(new MagFactor(*this)));
|
||||||
|
}
|
||||||
|
|
||||||
|
static Sphere2 unrotate(const Rot2& R, const Sphere2& p,
|
||||||
|
boost::optional<Matrix&> HR = boost::none) {
|
||||||
|
Sphere2 q = Rot3::yaw(R.theta()) * p;
|
||||||
|
if (HR) {
|
||||||
|
HR->resize(2, 1);
|
||||||
|
Point3 Q = q.unitVector();
|
||||||
|
Matrix B = q.basis().transpose();
|
||||||
|
(*HR) = Q.x() * B.col(1) - Q.y() * B.col(0);
|
||||||
|
}
|
||||||
|
return q;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief vector of errors
|
||||||
|
*/
|
||||||
|
Vector evaluateError(const Rot2& nRb,
|
||||||
|
boost::optional<Matrix&> H = boost::none) const {
|
||||||
|
// measured bM = nRbÕ * nM + b, where b is unknown bias
|
||||||
|
Sphere2 rotated = unrotate(nRb, direction_, H);
|
||||||
|
Vector3 hx = scale_ * rotated.unitVector() + bias_;
|
||||||
|
if (H) {
|
||||||
|
Matrix U;
|
||||||
|
rotated.unitVector(U);
|
||||||
|
*H = scale_ * U * (*H);
|
||||||
|
}
|
||||||
|
return hx - measured_;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Factor to estimate rotation given magnetometer reading
|
* Factor to estimate rotation given magnetometer reading
|
||||||
* This version uses model measured bM = scale * bRn * direction + bias
|
* This version uses model measured bM = scale * bRn * direction + bias
|
||||||
|
|
|
||||||
|
|
@ -17,7 +17,6 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <gtsam/navigation/MagFactor.h>
|
#include <gtsam/navigation/MagFactor.h>
|
||||||
#include <gtsam/geometry/Rot2.h>
|
|
||||||
#include <gtsam/base/Testable.h>
|
#include <gtsam/base/Testable.h>
|
||||||
#include <gtsam/base/numericalDerivative.h>
|
#include <gtsam/base/numericalDerivative.h>
|
||||||
|
|
||||||
|
|
@ -29,64 +28,6 @@ using namespace std;
|
||||||
using namespace gtsam;
|
using namespace gtsam;
|
||||||
using namespace GeographicLib;
|
using namespace GeographicLib;
|
||||||
|
|
||||||
/**
|
|
||||||
* Factor to estimate rotation given magnetometer reading
|
|
||||||
* This version uses model measured bM = scale * bRn * direction + bias
|
|
||||||
* and assumes scale, direction, and the bias are given
|
|
||||||
*/
|
|
||||||
class MagFactor: public NoiseModelFactor1<Rot2> {
|
|
||||||
|
|
||||||
const Vector3 measured_; /** The measured magnetometer values */
|
|
||||||
const double scale_;
|
|
||||||
const Sphere2 direction_;
|
|
||||||
const Vector3 bias_;
|
|
||||||
|
|
||||||
public:
|
|
||||||
|
|
||||||
/** Constructor */
|
|
||||||
MagFactor(Key key, const Vector3& measured, const LieScalar& scale,
|
|
||||||
const Sphere2& direction, const LieVector& bias,
|
|
||||||
const SharedNoiseModel& model) :
|
|
||||||
NoiseModelFactor1<Rot2>(model, key), //
|
|
||||||
measured_(measured), scale_(scale), direction_(direction), bias_(bias) {
|
|
||||||
}
|
|
||||||
|
|
||||||
/// @return a deep copy of this factor
|
|
||||||
virtual NonlinearFactor::shared_ptr clone() const {
|
|
||||||
return boost::static_pointer_cast<NonlinearFactor>(
|
|
||||||
NonlinearFactor::shared_ptr(new MagFactor(*this)));
|
|
||||||
}
|
|
||||||
|
|
||||||
static Sphere2 unrotate(const Rot2& R, const Sphere2& p,
|
|
||||||
boost::optional<Matrix&> HR = boost::none) {
|
|
||||||
Sphere2 q = Rot3::yaw(R.theta()) * p;
|
|
||||||
if (HR) {
|
|
||||||
HR->resize(2, 1);
|
|
||||||
Point3 Q = q.unitVector();
|
|
||||||
Matrix B = q.basis().transpose();
|
|
||||||
(*HR) = Q.x() * B.col(1) - Q.y() * B.col(0);
|
|
||||||
}
|
|
||||||
return q;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief vector of errors
|
|
||||||
*/
|
|
||||||
Vector evaluateError(const Rot2& nRb,
|
|
||||||
boost::optional<Matrix&> H = boost::none) const {
|
|
||||||
// measured bM = nRbÕ * nM + b, where b is unknown bias
|
|
||||||
Sphere2 rotated = unrotate(nRb, direction_, H);
|
|
||||||
Vector3 hx = scale_ * rotated.unitVector() + bias_;
|
|
||||||
if (H) // I think H2 is 2*2, but we need 3*2
|
|
||||||
{
|
|
||||||
Matrix U;
|
|
||||||
rotated.unitVector(U);
|
|
||||||
*H = scale_ * U * (*H);
|
|
||||||
}
|
|
||||||
return hx - measured_;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
// *************************************************************************
|
// *************************************************************************
|
||||||
// Convert from Mag to ENU
|
// Convert from Mag to ENU
|
||||||
// ENU Origin is where the plane was in hold next to runway
|
// ENU Origin is where the plane was in hold next to runway
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue