Calico
A visual-inertial calibration library designed for rapid problem construction and debugging.
test_utils.h
1 #ifndef CALICO_TEST_UTILS_H_
2 #define CALICO_TEST_UTILS_H_
3 
4 #include "absl/container/flat_hash_map.h"
5 #include "calico/typedefs.h"
6 #include "Eigen/Dense"
7 
8 
9 namespace calico {
10 
12  public:
14  // Create position and orientation setpoints through which we will smoothly
15  // interpolate.
16  const Eigen::Quaterniond q_world_sensorrig0(
17  Eigen::AngleAxisd(M_PI, Eigen::Vector3d::UnitZ()) *
18  Eigen::AngleAxisd(M_PI, Eigen::Vector3d::UnitX()));
19  const Eigen::Vector3d t_world_sensorrig0 =
20  Eigen::Vector3d(0.0, 0.0, 1.0);
21  std::vector<double> angle_displacements =
22  {0.0, kAngleAmplitude, 0.0, -kAngleAmplitude, 0.0};
23  std::vector<double> position_displacements =
24  {0.0, kPosAmplitude, 0.0, -kPosAmplitude, 0.0};
25  // Excitation per axis.
26  std::vector<double> interpolation_times(kNumSamplesPerSegment);
27  const double dt_interpolation =
28  1.0 / static_cast<double>(kNumSamplesPerSegment);
29  const double dt_actual = dt_interpolation * kSegmentDuration;
30  for (int i = 0; i < kNumSamplesPerSegment; ++i) {
31  const double temp = dt_interpolation * i;
32  interpolation_times[i] = (std::sin(temp * M_PI - M_PI_2) + 1.0) / 2.0;
33  }
34  double current_time = 0.0;
35  for (const Eigen::Vector3d& axis : std::vector{
36  Eigen::Vector3d::UnitX(), Eigen::Vector3d::UnitY(),
37  Eigen::Vector3d::UnitZ()}) {
38  // Angular excitation.
39  for (int i = 1; i < angle_displacements.size(); ++i) {
40  const double& theta0 = angle_displacements[i - 1];
41  const double& theta1 = angle_displacements[i];
42  const double dtheta = theta1 - theta0;
43  for (const double& interp_time : interpolation_times) {
44  const double theta = dtheta * interp_time + theta0;
45  const Eigen::Quaterniond q_sensorrig0_sensorrig(
46  Eigen::AngleAxisd(theta, axis));
47  const Eigen::Quaterniond q_world_sensorrig =
48  q_world_sensorrig0 * q_sensorrig0_sensorrig;
49  trajectory_world_sensorrig_[current_time] =
50  Pose3d(q_world_sensorrig, t_world_sensorrig0);
51  current_time += dt_actual;
52  }
53  }
54  // Linear excitation.
55  for (int i = 1; i < position_displacements.size(); ++i) {
56  const double& pos0 = position_displacements[i - 1];
57  const double& pos1 = position_displacements[i];
58  const double dpos = pos1 - pos0;
59  for (const double& interp_time : interpolation_times) {
60  const double pos = dpos * interp_time + pos0;
61  trajectory_world_sensorrig_[current_time] =
62  Pose3d(q_world_sensorrig0, axis * pos + t_world_sensorrig0);
63  current_time += dt_actual;
64  }
65  }
66  }
67  for (const auto& [stamp, _] : trajectory_world_sensorrig_) {
68  trajectory_key_values_.push_back(stamp);
69  }
70  std::sort(trajectory_key_values_.begin(), trajectory_key_values_.end());
71 
72  // Construct planar points.
73  for (int i = 0; i < kNumXPoints; ++i) {
74  for (int j = 0; j < kNumYPoints; ++j) {
75  const double x = i * kDelta - kSamplePlaneWidth / 2.0;
76  const double y = j * kDelta - kSamplePlaneHeight / 2.0;;
77  t_world_points_.push_back(Eigen::Vector3d(x, y, 0.0));
78  }
79  }
80  }
81 
82  // Getter for trajectory as a timestamp-to-pose hash map.
83  const absl::flat_hash_map<double, Pose3d>& TrajectoryAsMap() const {
84  return trajectory_world_sensorrig_;
85  }
86 
87  // Convenience getter for timestamps.
88  const std::vector<double>& TrajectoryMapKeys() const {
89  return trajectory_key_values_;
90  }
91 
92  const std::vector<Eigen::Vector3d>& WorldPoints() const {
93  return t_world_points_;
94  }
95 
96  private:
97  absl::flat_hash_map<double, Pose3d> trajectory_world_sensorrig_;
98  std::vector<double> trajectory_key_values_;
99  std::vector<Eigen::Vector3d> t_world_points_;
100 
101  static constexpr double kDeg2Rad = M_PI / 180.0;
102  // Sensor rig trajectory specs.
103  static constexpr int kNumSamplesPerSegment = 10;
104  static constexpr double kPosAmplitude = 0.5;
105  static constexpr double kAngleAmplitude = 30 * kDeg2Rad;
106  static constexpr double kSegmentDuration = 0.75;
107  // Planar points specs.
108  static constexpr double kSamplePlaneWidth = 1.5;
109  static constexpr double kSamplePlaneHeight = 1.5;
110  static constexpr double kDelta = 0.3;
111  static constexpr int kNumXPoints =
112  static_cast<int>(kSamplePlaneWidth / kDelta) + 1;
113  static constexpr int kNumYPoints =
114  static_cast<int>(kSamplePlaneHeight / kDelta) + 1;
115  std::vector<Eigen::Vector3d> t_world_points;
116 };
117 } // namespace
118 
119 #endif // CALICO_TEST_UTILS_H_
Definition: test_utils.h:11
Primary calico namespace.
Definition: __init__.py:1