24#include <gtsam/base/VectorSpace.h>
56 typename traits<Pose>::TangentVector> {
60 static_assert(std::is_same_v<typename traits<Pose>::structure_category,
62 std::is_same_v<typename traits<Pose>::structure_category,
64 "Pose type must be either a Lie group or vector space");
74 using MatrixN = Eigen::Matrix<double, dim, dim>;
75 using VectorN = Eigen::Matrix<double, dim, 1>;
76 using Matrix2N = Eigen::Matrix<double, 2 * dim, 2 * dim>;
77 using Vector2N = Eigen::Matrix<double, 2 * dim, 1>;
78 using MatrixNx2N = Eigen::Matrix<double, dim, 2 * dim>;
84 inline static const MatrixN kIdentity = MatrixN::Identity();
85 inline static const MatrixN kZero = MatrixN::Zero();
104 static void ComputeRelativePose(
const Pose& p1,
const Pose& p2,
105 const Velocity& v2, VectorN& xi,
106 MatrixN& invJr, MatrixN* dxi_dT1,
107 MatrixN* dxi_dT2, MatrixN* dvErr_dxi) {
114 if (dxi_dT1) *dxi_dT1 = invJr * dBetween_p1;
115 if (dxi_dT2) *dxi_dT2 = invJr;
120 if constexpr (std::is_same_v<typename traits<Pose>::structure_category,
122 dvErr_dxi->setZero();
125 auto ad_v2 = Pose::adjointMap(v2);
126 auto ad_xi = Pose::adjointMap(xi);
127 *dvErr_dxi = -ad_v2 / 2.0 -
128 (Pose::adjointMap(ad_xi * v2) + ad_xi * ad_v2) / 12.0;
151 const VectorN& q_psd_diag)
157 this->deltaT_ = state_kp1.
time - state_k.
time;
158 assert(this->deltaT_ > 0.0 &&
159 "Time difference between input states must be positive.");
175 const double deltaT,
const VectorN& q_psd_diag)
186 const std::string& s =
"",
188 std::cout << s <<
"WnoaMotionFactor(" << keyFormatter(this->key1()) <<
","
189 << keyFormatter(this->key2()) <<
"," << keyFormatter(this->key3())
190 <<
"," << keyFormatter(this->key4()) <<
")\n";
191 this->noiseModel_->print(
" noise model: ");
196 double tol = 1e-9)
const override {
197 const This* e =
dynamic_cast<const This*
>(&expected);
230 ComputeRelativePose(p1, p2, v2, xi, invJr, &dxi_dT1, &dxi_dT2,
233 ComputeRelativePose(p1, p2, v2, xi, invJr,
nullptr,
nullptr,
nullptr);
238 err.template head<dim>() = xi - deltaT_ * v1;
239 err.template tail<dim>() = invJr * v2 - v1;
244 Hp1->resize(2 * dim, dim);
245 Hp1->template block<dim, dim>(0, 0) = dxi_dT1;
246 Hp1->template block<dim, dim>(dim, 0) = dvErr_dxi * dxi_dT1;
250 Hv1->resize(2 * dim, dim);
251 Hv1->template block<dim, dim>(0, 0) = -deltaT_ * kIdentity;
252 Hv1->template block<dim, dim>(dim, 0) = -kIdentity;
256 Hp2->resize(2 * dim, dim);
257 Hp2->template block<dim, dim>(0, 0) = dxi_dT2;
258 Hp2->template block<dim, dim>(dim, 0) = dvErr_dxi * dxi_dT2;
262 Hv2->resize(2 * dim, dim);
263 Hv2->template block<dim, dim>(0, 0) = kZero;
264 Hv2->template block<dim, dim>(dim, 0) = invJr;
283 const VectorN& q_psd_diag) {
286 const MatrixN Q_diag = q_psd_diag.asDiagonal();
287 covariance.template topLeftCorner<dim, dim>() =
288 (1.0 / 3.0 * std::pow(timestep, 3)) * Q_diag;
289 covariance.template topRightCorner<dim, dim>() =
290 (0.5 * std::pow(timestep, 2)) * Q_diag;
291 covariance.template bottomLeftCorner<dim, dim>() =
292 (0.5 * std::pow(timestep, 2)) * Q_diag;
293 covariance.template bottomRightCorner<dim, dim>() = timestep * Q_diag;
305 const VectorN& q_psd_diag) {
307 Matrix2N inverse_covariance;
308 const MatrixN Q_inv_diag = q_psd_diag.cwiseInverse().asDiagonal();
309 const double dt2 = dt * dt, dt3 = dt2 * dt;
310 inverse_covariance.template topLeftCorner<dim, dim>() =
311 (12.0 / dt3) * Q_inv_diag;
312 inverse_covariance.template topRightCorner<dim, dim>() =
313 (-6.0 / dt2) * Q_inv_diag;
314 inverse_covariance.template bottomLeftCorner<dim, dim>() =
315 (-6.0 / dt2) * Q_inv_diag;
316 inverse_covariance.template bottomRightCorner<dim, dim>() =
317 (4.0 / dt) * Q_inv_diag;
319 return inverse_covariance;
333 double timestep,
const VectorN& q_psd_diag) {
350 F.template topLeftCorner<dim, dim>() = kIdentity;
351 F.template topRightCorner<dim, dim>() = deltaT * kIdentity;
352 F.template bottomLeftCorner<dim, dim>() = kZero;
353 F.template bottomRightCorner<dim, dim>() = kIdentity;
371 const std::pair<Pose, Velocity>& pv2,
374 const auto& p1 = pv1.first;
375 const auto& p2 = pv2.first;
376 const auto& v2 = pv2.second;
382 ComputeRelativePose(p1, p2, v2, xi, invJr, &dxi_dT1,
nullptr, &dvErr_dxi);
386 F.template topLeftCorner<dim, dim>() = dxi_dT1;
387 F.template topRightCorner<dim, dim>() = -deltaT * kIdentity;
388 F.template bottomLeftCorner<dim, dim>() = dvErr_dxi * dxi_dT1;
389 F.template bottomRightCorner<dim, dim>() = -kIdentity;
407 const std::pair<Pose, Velocity>& pv2,
410 const auto& p1 = pv1.first;
411 const auto& p2 = pv2.first;
412 const auto& v2 = pv2.second;
418 ComputeRelativePose(p1, p2, v2, xi, invJr,
nullptr, &dxi_dT2, &dvErr_dxi);
422 E.template topLeftCorner<dim, dim>() = dxi_dT2;
423 E.template topRightCorner<dim, dim>() = kZero;
424 E.template bottomLeftCorner<dim, dim>() = dvErr_dxi * dxi_dT2;
425 E.template bottomRightCorner<dim, dim>() = invJr;
433 :
public Testable<WnoaMotionFactor<Pose>> {};
Concept check for values that can be used in unit tests.
Base class and basic functions for Lie types.
3D Pose manifold SO(3) x R^3 and group SE(3)
Introduces a lightweight struct for identifying states in continuous-time estimation and interpolatio...
Non-linear factor base classes.
Global functions in a separate testing namespace.
Definition chartTesting.h:28
KeyFormatter DefaultKeyFormatter
Assign default key formatter.
Definition Key.cpp:30
Matrix * OptionalMatrixType
This typedef will be used everywhere boost::optional<Matrix&> reference was used previously.
Definition NonlinearFactor.h:57
NoiseModelFactorT< Vector, ValueTypes... > NoiseModelFactorN
Noise model factor with N value types and dynamic-sized error vector.
Definition NoiseModelFactorN.h:561
std::function< std::string(Key)> KeyFormatter
Typedef for a function to format a key, i.e. to convert it to a string.
Definition Key.h:35
std::uint64_t Key
Integer nonlinear key type.
Definition types.h:43
A manifold defines a space in which there is a notion of a linear tangent space that can be centered ...
Definition Group.h:37
tag to assert a type is a Lie group
Definition Lie.h:271
Lie Group Concept.
Definition Lie.h:377
A testable concept check that should be placed in applicable unit tests and in generic algorithms.
Definition Testable.h:59
A helper that implements the traits interface for GTSAM types.
Definition Testable.h:152
tag to assert a type is a vector space
Definition VectorSpace.h:21
KeyVector keys_
The keys involved in this factor.
Definition Factor.h:88
bool equals(const This &other, double tol=1e-9) const
check equality
Definition Factor.cpp:42
static shared_ptr Covariance(const Matrix &covariance, bool smart=true)
A Gaussian noise model created by specifying a covariance matrix.
Definition NoiseModel.cpp:116
virtual Vector evaluateError(const ValueTypes &... x, OptionalMatrixTypeT< ValueTypes >... H) const=0
Nonlinear factor base class.
Definition NonlinearFactor.h:70
WNOA (White Noise on Acceleration) motion prior factor.
Definition WnoaFactor.h:56
void print(const std::string &s="", const KeyFormatter &keyFormatter=DefaultKeyFormatter) const override
print
Definition WnoaFactor.h:185
static Matrix2N TransitionFunction(double deltaT)
Transition matrix for the WNOA prior.
Definition WnoaFactor.h:347
static Matrix2N ComputeJacobianPrev(const std::pair< Pose, Velocity > &pv1, const std::pair< Pose, Velocity > &pv2, double deltaT)
Compute interpolation Jacobian with respect to the previous (left) state.
Definition WnoaFactor.h:370
bool equals(const NonlinearFactor &expected, double tol=1e-9) const override
equals
Definition WnoaFactor.h:195
Vector evaluateError(const Pose &p1, const Velocity &v1, const Pose &p2, const Velocity &v2, OptionalMatrixType Hp1, OptionalMatrixType Hv1, OptionalMatrixType Hp2, OptionalMatrixType Hv2) const override
Evaluate the WNOA factor residual and optional Jacobians.
Definition WnoaFactor.h:220
static Matrix2N BuildInverseWnoaCovariance(double dt, const VectorN &q_psd_diag)
Build the inverse of the WNOA discretized process covariance.
Definition WnoaFactor.h:304
static Matrix2N ComputeJacobianNext(const std::pair< Pose, Velocity > &pv1, const std::pair< Pose, Velocity > &pv2, double deltaT)
Compute interpolation Jacobian with respect to the next (right) state.
Definition WnoaFactor.h:406
static Matrix2N BuildWnoaCovariance(double timestep, const VectorN &q_psd_diag)
Build the continuous-time WNOA discretized process covariance.
Definition WnoaFactor.h:282
static noiseModel::Gaussian::shared_ptr BuildWnoaNoiseModel(double timestep, const VectorN &q_psd_diag)
Convenience helper to construct a Gaussian noise model from q_psd_diag.
Definition WnoaFactor.h:332
WnoaMotionFactor(Key poseKey0, Key velKey0, Key poseKey1, Key velKey1, const double deltaT, const VectorN &q_psd_diag)
Construct a WNOA factor given explicit keys and timestep.
Definition WnoaFactor.h:174
WnoaMotionFactor(const StateData &state_k, const StateData &state_kp1, const VectorN &q_psd_diag)
Construct a WNOA motion factor from two StateData entries.
Definition WnoaFactor.h:150
Lightweight container for states used for continuous-time estimation and interpolation.
Definition WnoaStateData.h:39
double time
Timestamp (seconds) associated with this state.
Definition WnoaStateData.h:42
Key pose
Key of the pose variable.
Definition WnoaStateData.h:40
Key velocity
Key of the velocity variable.
Definition WnoaStateData.h:41