full nonholon example
parent
3a72df2deb
commit
1e42af6548
|
@ -16,51 +16,80 @@
|
||||||
* @brief unit tests for testFactorJacobians and testExpressionJacobians
|
* @brief unit tests for testFactorJacobians and testExpressionJacobians
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#include <gtsam/geometry/Pose3.h>
|
||||||
#include <gtsam/nonlinear/expressions.h>
|
#include <gtsam/nonlinear/expressions.h>
|
||||||
#include <gtsam/geometry/Point3.h>
|
|
||||||
#include <gtsam/nonlinear/expressionTesting.h>
|
#include <gtsam/nonlinear/expressionTesting.h>
|
||||||
|
#include <gtsam/slam/expressions.h>
|
||||||
|
|
||||||
#include <CppUnitLite/TestHarness.h>
|
#include <CppUnitLite/TestHarness.h>
|
||||||
|
|
||||||
using namespace gtsam;
|
using namespace gtsam;
|
||||||
|
|
||||||
/* ************************************************************************* */
|
/* ************************************************************************* */
|
||||||
class ScaleAndCompare {
|
Vector3 bodyVelocity(const Pose3& w_t_b,
|
||||||
public:
|
const Vector3& vec_w,
|
||||||
ScaleAndCompare() = default;
|
OptionalJacobian<3, 6> Hpose = boost::none,
|
||||||
explicit ScaleAndCompare(const Vector3& other) : other_(other) {}
|
OptionalJacobian<3, 3> Hvel = boost::none) {
|
||||||
Vector3 operator()(const Vector3& v,
|
Matrix36 Hrot__pose;
|
||||||
const double& s,
|
Rot3 w_R_b = w_t_b.rotation(Hrot__pose);
|
||||||
OptionalJacobian<3, 3> Dv,
|
Matrix33 Hvel__rot;
|
||||||
OptionalJacobian<3, 1> Ds) const {
|
Vector3 vec_b = w_R_b.unrotate(vec_w, Hvel__rot, Hvel);
|
||||||
const Vector3 e = v - other_ * s;
|
if (Hpose) {
|
||||||
if(Dv) {
|
*Hpose = Hvel__rot * Hrot__pose;
|
||||||
*Dv = I_3x3;
|
}
|
||||||
|
return vec_b;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Functor used to create an expression for the measured wheel speed scaled
|
||||||
|
// by the scale factor.
|
||||||
|
class ScaledVelocityFunctor {
|
||||||
|
public:
|
||||||
|
explicit ScaledVelocityFunctor(double measured_wheel_speed)
|
||||||
|
: measured_velocity_(measured_wheel_speed, 0, 0) {}
|
||||||
|
|
||||||
|
// Computes the scaled measured velocity vector from the measured wheel speed
|
||||||
|
// and velocity scale factor. Also computes the corresponding jacobian
|
||||||
|
// (w.r.t. the velocity scale).
|
||||||
|
Vector3 operator()(double vscale,
|
||||||
|
OptionalJacobian<3, 1> H = boost::none) const {
|
||||||
|
// The velocity scale factor value we are optimizing for is centered around
|
||||||
|
// 0, so we need to add 1 to it before scaling the velocity.
|
||||||
|
const Vector3 scaled_velocity = (vscale + 1.0) * measured_velocity_;
|
||||||
|
if (H) {
|
||||||
|
*H = measured_velocity_;
|
||||||
}
|
}
|
||||||
if(Ds) {
|
return scaled_velocity;
|
||||||
*Ds = -other_;
|
|
||||||
}
|
|
||||||
return e;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
Vector3 other_ = Z_3x1;
|
Vector3 measured_velocity_;
|
||||||
};
|
};
|
||||||
|
|
||||||
/* ************************************************************************* */
|
/* ************************************************************************* */
|
||||||
// Constant
|
TEST(ExpressionTesting, Issue16) {
|
||||||
TEST(ExpressionTesting, ScaleAndCompare) {
|
|
||||||
const double tol = 1e-4;
|
const double tol = 1e-4;
|
||||||
const double numerical_step = 1e-3;
|
const double numerical_step = 1e-3;
|
||||||
|
|
||||||
const Vector3 other(1, 0, 0);
|
// Note: name of keys matters: if we use 'p' instead of 'x' then this no
|
||||||
Values values;
|
// longer repros the problem from issue 16. This is because the order of
|
||||||
values.insert<Vector3>(Symbol('v', 0), Vector3(1.1, 0, 0));
|
// evaluation in linearizeNumerically depends on the key values. To repro
|
||||||
values.insert<double>(Symbol('s', 0), 1.1);
|
// we want to first evaluate the jacobian for the scale, then velocity,
|
||||||
|
// then pose.
|
||||||
|
const auto pose_key = Symbol('x', 1);
|
||||||
|
const auto vel_key = Symbol('v', 1);
|
||||||
|
const auto scale_key = Symbol('s', 1);
|
||||||
|
|
||||||
const auto err_expr = Expression<Vector3>(ScaleAndCompare{other},
|
Values values;
|
||||||
Vector3_(Symbol('v', 0)),
|
values.insert<Pose3>(pose_key, Pose3());
|
||||||
Double_(Symbol('s', 0)));
|
values.insert<Vector3>(vel_key, Vector3(1, 0, 0));
|
||||||
|
values.insert<double>(scale_key, 0);
|
||||||
|
|
||||||
|
const Vector3_ body_vel(&bodyVelocity,
|
||||||
|
Pose3_(pose_key),
|
||||||
|
Vector3_(vel_key));
|
||||||
|
const Vector3_ scaled_measured_vel(ScaledVelocityFunctor(1),
|
||||||
|
Double_(scale_key));
|
||||||
|
const auto err_expr = body_vel - scaled_measured_vel;
|
||||||
|
|
||||||
const auto err = err_expr.value(values);
|
const auto err = err_expr.value(values);
|
||||||
EXPECT_LONGS_EQUAL(3, err.size());
|
EXPECT_LONGS_EQUAL(3, err.size());
|
||||||
|
|
Loading…
Reference in New Issue