testTransferFactor.cpp
Go to the documentation of this file.
1 /*
2  * @file testTransferFactor.cpp
3  * @brief Test TransferFactor class
4  * @author Your Name
5  * @date October 23, 2024
6  */
7 
12 
13 using namespace gtsam;
14 
15 //*************************************************************************
17 std::array<Pose3, 3> generateCameraPoses() {
18  std::array<Pose3, 3> cameraPoses;
19  const double radius = 1.0;
20  for (int i = 0; i < 3; ++i) {
21  double angle = i * 2.0 * M_PI / 3.0;
22  double c = cos(angle), s = sin(angle);
23  Rot3 aRb({-s, c, 0}, {0, 0, -1}, {-c, -s, 0});
24  cameraPoses[i] = {aRb, Point3(radius * c, radius * s, 0)};
25  }
26  return cameraPoses;
27 }
28 
29 //*************************************************************************
30 // Function to generate a TripleF from camera poses
32  const std::array<Pose3, 3>& cameraPoses) {
33  std::array<SimpleFundamentalMatrix, 3> F;
34  for (size_t i = 0; i < 3; ++i) {
35  size_t j = (i + 1) % 3;
36  const Pose3 iPj = cameraPoses[i].between(cameraPoses[j]);
38  F[i] = {E, 1000.0, 1000.0, Point2(640 / 2, 480 / 2),
39  Point2(640 / 2, 480 / 2)};
40  }
41  return {F[0], F[1], F[2]}; // Return a TripleF instance
42 }
43 
44 //*************************************************************************
45 namespace fixture {
46 // Generate cameras on a circle
47 std::array<Pose3, 3> cameraPoses = generateCameraPoses();
49 double focalLength = 1000;
50 Point2 principalPoint(640 / 2, 480 / 2);
51 const Cal3_S2 K(focalLength, focalLength, 0.0, //
53 } // namespace fixture
54 
55 //*************************************************************************
56 // Test for getMatrices
57 TEST(TransferFactor, GetMatrices) {
58  using namespace fixture;
59  TransferFactor<SimpleFundamentalMatrix> factor{{2, 0}, {1, 2}, {}};
60 
61  // Check that getMatrices is correct
62  auto [Fki, Fkj] = factor.getMatrices(triplet.Fca, triplet.Fbc);
63  EXPECT(assert_equal<Matrix3>(triplet.Fca.matrix(), Fki));
64  EXPECT(assert_equal<Matrix3>(triplet.Fbc.matrix().transpose(), Fkj));
65 }
66 
67 //*************************************************************************
68 // Test for TransferFactor
69 TEST(TransferFactor, Jacobians) {
70  using namespace fixture;
71 
72  // Now project a point into the three cameras
73  const Point3 P(0.1, 0.2, 0.3);
74 
75  std::array<Point2, 3> p;
76  for (size_t i = 0; i < 3; ++i) {
77  // Project the point into each camera
79  p[i] = camera.project(P);
80  }
81 
82  // Create a TransferFactor
83  EdgeKey key01(0, 1), key12(1, 2), key20(2, 0);
85  factor0{key01, key20, p[1], p[2], p[0]},
86  factor1{key12, key01, p[2], p[0], p[1]},
87  factor2{key20, key12, p[0], p[1], p[2]};
88 
89  // Create Values with edge keys
90  Values values;
91  values.insert(key01, triplet.Fab);
92  values.insert(key12, triplet.Fbc);
93  values.insert(key20, triplet.Fca);
94 
95  // Check error and Jacobians
96  for (auto&& f : {factor0, factor1, factor2}) {
97  Vector error = f.unwhitenedError(values);
98  EXPECT(assert_equal<Vector>(Z_2x1, error));
100  }
101 }
102 
103 //*************************************************************************
104 // Test for TransferFactor with multiple tuples
105 TEST(TransferFactor, MultipleTuples) {
106  using namespace fixture;
107 
108  // Now project multiple points into the three cameras
109  const size_t numPoints = 5; // Number of points to test
110  std::vector<Point3> points3D;
111  std::vector<std::array<Point2, 3>> projectedPoints;
112 
113  // Generate random 3D points and project them
114  for (size_t n = 0; n < numPoints; ++n) {
115  Point3 P(0.1 * n, 0.2 * n, 0.3 + 0.1 * n);
116  points3D.push_back(P);
117 
118  std::array<Point2, 3> p;
119  for (size_t i = 0; i < 3; ++i) {
120  // Project the point into each camera
122  p[i] = camera.project(P);
123  }
124  projectedPoints.push_back(p);
125  }
126 
127  // Create a vector of tuples for the TransferFactor
128  EdgeKey key01(0, 1), key12(1, 2), key20(2, 0);
129  std::vector<std::tuple<Point2, Point2, Point2>> tuples;
130 
131  for (size_t n = 0; n < numPoints; ++n) {
132  const auto& p = projectedPoints[n];
133  tuples.emplace_back(p[1], p[2], p[0]);
134  }
135 
136  // Create TransferFactors using the new constructor
137  TransferFactor<SimpleFundamentalMatrix> factor{key01, key20, tuples};
138 
139  // Create Values with edge keys
140  Values values;
141  values.insert(key01, triplet.Fab);
142  values.insert(key12, triplet.Fbc);
143  values.insert(key20, triplet.Fca);
144 
145  // Check error and Jacobians for multiple tuples
146  Vector error = factor.unwhitenedError(values);
147  // The error vector should be of size 2 * numPoints
148  EXPECT_LONGS_EQUAL(2 * numPoints, error.size());
149  // Since the points are perfectly matched, the error should be zero
150  EXPECT(assert_equal<Vector>(Vector::Zero(2 * numPoints), error, 1e-9));
151 
152  // Check the Jacobians
153  EXPECT_CORRECT_FACTOR_JACOBIANS(factor, values, 1e-5, 1e-7);
154 }
155 
156 //*************************************************************************
157 int main() {
158  TestResult tr;
159  return TestRegistry::runAllTests(tr);
160 }
161 //*************************************************************************
TestRegistry::runAllTests
static int runAllTests(TestResult &result)
Definition: TestRegistry.cpp:27
fixture::triplet
auto triplet
Definition: testTransferFactor.cpp:48
EXPECT_CORRECT_FACTOR_JACOBIANS
#define EXPECT_CORRECT_FACTOR_JACOBIANS(factor, values, numerical_derivative_step, tolerance)
Check the Jacobians produced by a factor against finite differences.
Definition: factorTesting.h:114
aRb
Rot3 aRb
Definition: testFundamentalMatrix.cpp:146
simple_graph::factor2
auto factor2
Definition: testJacobianFactor.cpp:203
s
RealScalar s
Definition: level1_cplx_impl.h:126
e
Array< double, 1, 3 > e(1./3., 0.5, 2.)
EXPECT_LONGS_EQUAL
#define EXPECT_LONGS_EQUAL(expected, actual)
Definition: Test.h:154
ceres::sin
Jet< T, N > sin(const Jet< T, N > &f)
Definition: jet.h:439
EXPECT
#define EXPECT(condition)
Definition: Test.h:150
TestHarness.h
generateCameraPoses
std::array< Pose3, 3 > generateCameraPoses()
Generate three cameras on a circle, looking in.
Definition: testTransferFactor.cpp:17
c
Scalar Scalar * c
Definition: benchVecAdd.cpp:17
fixture::K
const Cal3_S2 K(focalLength, focalLength, 0.0, principalPoint.x(), principalPoint.y())
fixture
Definition: testTransferFactor.cpp:45
generateTripleF
TripleF< SimpleFundamentalMatrix > generateTripleF(const std::array< Pose3, 3 > &cameraPoses)
Definition: testTransferFactor.cpp:31
different_sigmas::values
HybridValues values
Definition: testHybridBayesNet.cpp:245
gtsam::Vector
Eigen::VectorXd Vector
Definition: Vector.h:38
ceres::cos
Jet< T, N > cos(const Jet< T, N > &f)
Definition: jet.h:426
focalLength
double focalLength
Definition: testFundamentalMatrix.cpp:118
n
int n
Definition: BiCGSTAB_simple.cpp:1
j
std::ptrdiff_t j
Definition: tut_arithmetic_redux_minmax.cpp:2
gtsam::EssentialMatrix
Definition: EssentialMatrix.h:26
gtsam::Rot3
Rot3 is a 3D rotation represented as a rotation matrix if the preprocessor symbol GTSAM_USE_QUATERNIO...
Definition: Rot3.h:58
gtsam::Pose3
Definition: Pose3.h:37
gtsam::PinholeCamera
Definition: PinholeCamera.h:33
gtsam::Pose3::translation
const Point3 & translation(OptionalJacobian< 3, 6 > Hself={}) const
get translation
Definition: Pose3.cpp:308
factorTesting.h
Evaluate derivatives of a nonlinear factor numerically.
principalPoint
Point2 principalPoint(640/2, 480/2)
gtsam::HybridValues::insert
void insert(Key j, const Vector &value)
Definition: HybridValues.cpp:85
gtsam::Point2
Vector2 Point2
Definition: Point2.h:32
TransferFactor.h
gtsam::symbol_shorthand::F
Key F(std::uint64_t j)
Definition: inference/Symbol.h:153
gtsam::TransferFactor
Definition: TransferFactor.h:33
TestResult
Definition: TestResult.h:26
E
DiscreteKey E(5, 2)
tree::f
Point2(* f)(const Point3 &, OptionalJacobian< 2, 3 >)
Definition: testExpression.cpp:218
fixture::cameraPoses
std::array< Pose3, 3 > cameraPoses
Definition: testTransferFactor.cpp:47
gtsam::Pose3::rotation
const Rot3 & rotation(OptionalJacobian< 3, 6 > Hself={}) const
get rotation
Definition: Pose3.cpp:315
gtsam::EdgeKey
Definition: EdgeKey.h:25
gtsam::TransferFactor::getMatrices
std::pair< Matrix3, Matrix3 > getMatrices(const F &F1, const F &F2) const
Definition: TransferFactor.h:78
gtsam
traits
Definition: SFMdata.h:40
gtsam::TEST
TEST(SmartFactorBase, Pinhole)
Definition: testSmartFactorBase.cpp:38
error
static double error
Definition: testRot3.cpp:37
gtsam::Values
Definition: Values.h:65
p
float * p
Definition: Tutorial_Map_using.cpp:9
gtsam::Z_2x1
static const Eigen::MatrixBase< Vector2 >::ConstantReturnType Z_2x1
Definition: Vector.h:45
P
static double P[]
Definition: ellpe.c:68
gtsam::Cal3_S2
The most common 5DOF 3D->2D calibration.
Definition: Cal3_S2.h:34
gtsam::TripleF
Definition: FundamentalMatrix.h:199
gtsam::Point3
Vector3 Point3
Definition: Point3.h:38
main
int main()
Definition: testTransferFactor.cpp:157
SimpleCamera.h
A simple camera class with a Cal3_S2 calibration.
gtsam::Unit3
Represents a 3D point on a unit sphere.
Definition: Unit3.h:42
camera
static const CalibratedCamera camera(kDefaultPose)
M_PI
#define M_PI
Definition: mconf.h:117
i
int i
Definition: BiCGSTAB_step_by_step.cpp:9
simple_graph::factor1
auto factor1
Definition: testJacobianFactor.cpp:196
gtsam::CalibratedCamera::project
Point2 project(const Point3 &point, OptionalJacobian< 2, 6 > Dcamera={}, OptionalJacobian< 2, 3 > Dpoint={}) const
Definition: CalibratedCamera.cpp:188


gtsam
Author(s):
autogenerated on Fri Nov 1 2024 03:41:51