19 #ifndef GRAPH_FACTORS_POINT_TO_HANDRAIL_ENDPOINT_FACTOR_H_
20 #define GRAPH_FACTORS_POINT_TO_HANDRAIL_ENDPOINT_FACTOR_H_
22 #include <gtsam/geometry/Pose3.h>
23 #include <gtsam/geometry/Point3.h>
24 #include <gtsam/nonlinear/NonlinearFactor.h>
30 typedef NoiseModelFactor1<Pose3> Base;
38 const SharedNoiseModel& model, Key pose_key)
39 : Base(model, pose_key),
45 void print(
const std::string& s =
"",
const KeyFormatter& keyFormatter = DefaultKeyFormatter)
const override {
46 std::cout << s <<
"PointToHandrailEndpointFactor, z = ";
51 Base::print(
"", keyFormatter);
54 bool equals(
const NonlinearFactor& p,
double tol = 1e-9)
const override {
55 const This* e =
dynamic_cast<const This*
>(&p);
62 Vector
evaluateError(
const Pose3& world_T_body, boost::optional<Matrix&> H = boost::none)
const override {
64 Matrix66 d_world_T_sensor_d_world_T_body;
65 Matrix36 d_world_t_point_d_world_T_sensor;
66 Matrix33 d_local_d_world_t_point;
67 const auto error =
getError(world_T_body, d_world_T_sensor_d_world_T_body, d_world_t_point_d_world_T_sensor,
68 d_local_d_world_t_point);
69 *H = d_local_d_world_t_point * d_world_t_point_d_world_T_sensor * d_world_T_sensor_d_world_T_body;
75 Vector
getError(
const Pose3& world_T_body, OptionalJacobian<6, 6> d_world_T_sensor_d_world_T_body = boost::none,
76 OptionalJacobian<3, 6> d_world_t_point_d_world_T_sensor = boost::none,
77 OptionalJacobian<3, 3> d_local_d_world_t_point = boost::none)
const {
78 const Pose3 world_T_sensor = world_T_body.transformPoseFrom(body_T_sensor_, d_world_T_sensor_d_world_T_body);
79 const Point3 world_t_point = world_T_sensor.transformFrom(sensor_t_point_, d_world_t_point_d_world_T_sensor);
80 const double distance_to_endpoint_a = (world_t_point - world_t_endpoint_a_).norm();
81 const double distance_to_endpoint_b = (world_t_point - world_t_endpoint_b_).norm();
83 const Point3& world_t_closest_endpoint =
84 distance_to_endpoint_a < distance_to_endpoint_b ? world_t_endpoint_a_ : world_t_endpoint_b_;
85 const Point3 world_F_point_t_closest_endpoint =
86 local(world_t_point, world_t_closest_endpoint, d_local_d_world_t_point);
87 return world_F_point_t_closest_endpoint;
92 static Point3
local(
const Point3& point1,
const Point3& point2,
93 OptionalJacobian<3, 3> d_local_d_point1 = boost::none) {
94 if (d_local_d_point1) {
95 *d_local_d_point1 = I_3x3;
97 return point1 - point2;
107 template <
class ARCHIVE>
108 void serialize(ARCHIVE& ar,
const unsigned int ) {
109 ar& BOOST_SERIALIZATION_BASE_OBJECT_NVP(Base);
110 ar& BOOST_SERIALIZATION_NVP(sensor_t_point_);
111 ar& BOOST_SERIALIZATION_NVP(world_t_endpoint_a_);
112 ar& BOOST_SERIALIZATION_NVP(world_t_endpoint_b_);
113 ar& BOOST_SERIALIZATION_NVP(body_T_sensor_);
116 Point3 sensor_t_point_;
117 Point3 world_t_endpoint_a_;
118 Point3 world_t_endpoint_b_;
119 Pose3 body_T_sensor_;
122 GTSAM_MAKE_ALIGNED_OPERATOR_NEW
126 #endif // GRAPH_FACTORS_POINT_TO_HANDRAIL_ENDPOINT_FACTOR_H_