First commit of the code
This commit is contained in:
		
							
								
								
									
										118
									
								
								test/feature_initialization_test.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										118
									
								
								test/feature_initialization_test.cpp
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,118 @@
 | 
			
		||||
/*
 | 
			
		||||
 * COPYRIGHT AND PERMISSION NOTICE
 | 
			
		||||
 * Penn Software MSCKF_VIO
 | 
			
		||||
 * Copyright (C) 2017 The Trustees of the University of Pennsylvania
 | 
			
		||||
 * All rights reserved.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#include <iostream>
 | 
			
		||||
#include <vector>
 | 
			
		||||
#include <map>
 | 
			
		||||
 | 
			
		||||
#include <Eigen/Dense>
 | 
			
		||||
#include <Eigen/Geometry>
 | 
			
		||||
#include <Eigen/StdVector>
 | 
			
		||||
 | 
			
		||||
#include <gtest/gtest.h>
 | 
			
		||||
#include <random_numbers/random_numbers.h>
 | 
			
		||||
 | 
			
		||||
#include <msckf_vio/cam_state.h>
 | 
			
		||||
#include <msckf_vio/feature.hpp>
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
using namespace std;
 | 
			
		||||
using namespace Eigen;
 | 
			
		||||
using namespace msckf_vio;
 | 
			
		||||
 | 
			
		||||
TEST(FeatureInitializeTest, sphereDistribution) {
 | 
			
		||||
  // Set the real feature at the origin of the world frame.
 | 
			
		||||
  Vector3d feature(0.5, 0.0, 0.0);
 | 
			
		||||
 | 
			
		||||
  // Add 6 camera poses, all of which are able to see the
 | 
			
		||||
  // feature at the origin. For simplicity, the six camera
 | 
			
		||||
  // view are located at the six intersections between a
 | 
			
		||||
  // unit sphere and the coordinate system. And the z axes
 | 
			
		||||
  // of the camera frames are facing the origin.
 | 
			
		||||
  vector<Isometry3d> cam_poses(6);
 | 
			
		||||
  // Positive x axis.
 | 
			
		||||
  cam_poses[0].linear() << 0.0,  0.0, -1.0,
 | 
			
		||||
    1.0,  0.0,  0.0, 0.0, -1.0,  0.0;
 | 
			
		||||
  cam_poses[0].translation() << 1.0,  0.0,  0.0;
 | 
			
		||||
  // Positive y axis.
 | 
			
		||||
  cam_poses[1].linear() << -1.0,  0.0,  0.0,
 | 
			
		||||
     0.0,  0.0, -1.0, 0.0, -1.0,  0.0;
 | 
			
		||||
  cam_poses[1].translation() << 0.0,  1.0,  0.0;
 | 
			
		||||
  // Negative x axis.
 | 
			
		||||
  cam_poses[2].linear() << 0.0,  0.0,  1.0,
 | 
			
		||||
    -1.0,  0.0,  0.0, 0.0, -1.0,  0.0;
 | 
			
		||||
  cam_poses[2].translation() << -1.0,  0.0,  0.0;
 | 
			
		||||
  // Negative y axis.
 | 
			
		||||
  cam_poses[3].linear() << 1.0,  0.0,  0.0,
 | 
			
		||||
     0.0,  0.0,  1.0, 0.0, -1.0,  0.0;
 | 
			
		||||
  cam_poses[3].translation() << 0.0, -1.0,  0.0;
 | 
			
		||||
  // Positive z axis.
 | 
			
		||||
  cam_poses[4].linear() << 0.0, -1.0,  0.0,
 | 
			
		||||
    -1.0,  0.0,  0.0, 0.0, 0.0, -1.0;
 | 
			
		||||
  cam_poses[4].translation() << 0.0,  0.0,  1.0;
 | 
			
		||||
  // Negative z axis.
 | 
			
		||||
  cam_poses[5].linear() << 1.0,  0.0,  0.0,
 | 
			
		||||
     0.0,  1.0,  0.0, 0.0,  0.0,  1.0;
 | 
			
		||||
  cam_poses[5].translation() << 0.0,  0.0, -1.0;
 | 
			
		||||
 | 
			
		||||
  // Set the camera states
 | 
			
		||||
  CamStateServer cam_states;
 | 
			
		||||
  for (int i = 0; i < 6; ++i) {
 | 
			
		||||
    CAMState new_cam_state;
 | 
			
		||||
    new_cam_state.id = i;
 | 
			
		||||
    new_cam_state.time = static_cast<double>(i);
 | 
			
		||||
    new_cam_state.orientation = rotationToQuaternion(
 | 
			
		||||
        Matrix3d(cam_poses[i].linear().transpose()));
 | 
			
		||||
    new_cam_state.position = cam_poses[i].translation();
 | 
			
		||||
    cam_states[new_cam_state.id] = new_cam_state;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  // Compute measurements.
 | 
			
		||||
  random_numbers::RandomNumberGenerator noise_generator;
 | 
			
		||||
  vector<Vector2d, aligned_allocator<Vector2d> > measurements(6);
 | 
			
		||||
  for (int i = 0; i < 6; ++i) {
 | 
			
		||||
    Isometry3d cam_pose_inv = cam_poses[i].inverse();
 | 
			
		||||
    Vector3d p = cam_pose_inv.linear()*feature + cam_pose_inv.translation();
 | 
			
		||||
    double u = p(0) / p(2) + noise_generator.gaussian(0.0, 0.01);
 | 
			
		||||
    double v = p(1) / p(2) + noise_generator.gaussian(0.0, 0.01);
 | 
			
		||||
    //double u = p(0) / p(2);
 | 
			
		||||
    //double v = p(1) / p(2);
 | 
			
		||||
    measurements[i] = Vector2d(u, v);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  for (int i = 0; i < 6; ++i) {
 | 
			
		||||
    cout << "pose " << i << ":" << endl;
 | 
			
		||||
    cout << "orientation: " << endl;
 | 
			
		||||
    cout << cam_poses[i].linear() << endl;
 | 
			
		||||
    cout << "translation: "  << endl;
 | 
			
		||||
    cout << cam_poses[i].translation().transpose() << endl;
 | 
			
		||||
    cout << "measurement: " << endl;
 | 
			
		||||
    cout << measurements[i].transpose() << endl;
 | 
			
		||||
    cout << endl;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  // Initialize a feature object.
 | 
			
		||||
  Feature feature_object;
 | 
			
		||||
  for (int i = 0; i < 6; ++i)
 | 
			
		||||
    feature_object.observations[i] = measurements[i];
 | 
			
		||||
 | 
			
		||||
  // Compute the 3d position of the feature.
 | 
			
		||||
  feature_object.initializePosition(cam_states);
 | 
			
		||||
 | 
			
		||||
  // Check the difference between the computed 3d
 | 
			
		||||
  // feature position and the groud truth.
 | 
			
		||||
  cout << "ground truth position: " << feature.transpose() << endl;
 | 
			
		||||
  cout << "estimated position: " << feature_object.position.transpose() << endl;
 | 
			
		||||
  Eigen::Vector3d error = feature_object.position - feature;
 | 
			
		||||
  EXPECT_NEAR(error.norm(), 0, 0.05);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int main(int argc, char** argv) {
 | 
			
		||||
  testing::InitGoogleTest(&argc, argv);
 | 
			
		||||
  return RUN_ALL_TESTS();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										77
									
								
								test/math_utils_test.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										77
									
								
								test/math_utils_test.cpp
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,77 @@
 | 
			
		||||
/*
 | 
			
		||||
 * COPYRIGHT AND PERMISSION NOTICE
 | 
			
		||||
 * Penn Software MSCKF_VIO
 | 
			
		||||
 * Copyright (C) 2017 The Trustees of the University of Pennsylvania
 | 
			
		||||
 * All rights reserved.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#include <iostream>
 | 
			
		||||
#include <Eigen/Dense>
 | 
			
		||||
#include <gtest/gtest.h>
 | 
			
		||||
#include <msckf_vio/math_utils.hpp>
 | 
			
		||||
 | 
			
		||||
using namespace std;
 | 
			
		||||
using namespace Eigen;
 | 
			
		||||
using namespace msckf_vio;
 | 
			
		||||
 | 
			
		||||
TEST(MathUtilsTest, skewSymmetric) {
 | 
			
		||||
  Vector3d w(1.0, 2.0, 3.0);
 | 
			
		||||
  Matrix3d w_hat = skewSymmetric(w);
 | 
			
		||||
  Vector3d zero_vector = w_hat * w;
 | 
			
		||||
 | 
			
		||||
  FullPivLU<Matrix3d> lu_helper(w_hat);
 | 
			
		||||
  EXPECT_EQ(lu_helper.rank(), 2);
 | 
			
		||||
  EXPECT_DOUBLE_EQ(zero_vector.norm(), 0.0);
 | 
			
		||||
  return;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
TEST(MathUtilsTest, quaternionNormalize) {
 | 
			
		||||
  Vector4d q(1.0, 1.0, 1.0, 1.0);
 | 
			
		||||
  quaternionNormalize(q);
 | 
			
		||||
 | 
			
		||||
  EXPECT_DOUBLE_EQ(q.norm(), 1.0);
 | 
			
		||||
  return;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
TEST(MathUtilsTest, quaternionToRotation) {
 | 
			
		||||
  Vector4d q(0.0, 0.0, 0.0, 1.0);
 | 
			
		||||
  Matrix3d R = quaternionToRotation(q);
 | 
			
		||||
  Matrix3d zero_matrix = R - Matrix3d::Identity();
 | 
			
		||||
 | 
			
		||||
  FullPivLU<Matrix3d> lu_helper(zero_matrix);
 | 
			
		||||
  EXPECT_EQ(lu_helper.rank(), 0);
 | 
			
		||||
  return;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
TEST(MathUtilsTest, rotationToQuaternion) {
 | 
			
		||||
  Vector4d q1(0.0, 0.0, 0.0, 1.0);
 | 
			
		||||
  Matrix3d I = Matrix3d::Identity();
 | 
			
		||||
  Vector4d q2 = rotationToQuaternion(I);
 | 
			
		||||
  Vector4d zero_vector = q1 - q2;
 | 
			
		||||
 | 
			
		||||
  EXPECT_DOUBLE_EQ(zero_vector.norm(), 0.0);
 | 
			
		||||
  return;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
TEST(MathUtilsTest, quaternionMultiplication) {
 | 
			
		||||
  Vector4d q1(2.0, 2.0, 1.0, 1.0);
 | 
			
		||||
  Vector4d q2(1.0, 2.0, 3.0, 1.0);
 | 
			
		||||
  q1 = q1 / q1.norm();
 | 
			
		||||
  q2 = q2 / q2.norm();
 | 
			
		||||
  Vector4d q_prod = quaternionMultiplication(q1, q2);
 | 
			
		||||
 | 
			
		||||
  Matrix3d R1 = quaternionToRotation(q1);
 | 
			
		||||
  Matrix3d R2 = quaternionToRotation(q2);
 | 
			
		||||
  Matrix3d R_prod = R1 * R2;
 | 
			
		||||
  Matrix3d R_prod_cp = quaternionToRotation(q_prod);
 | 
			
		||||
 | 
			
		||||
  Matrix3d zero_matrix = R_prod - R_prod_cp;
 | 
			
		||||
 | 
			
		||||
  EXPECT_NEAR(zero_matrix.sum(), 0.0, 1e-10);
 | 
			
		||||
  return;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int main(int argc, char** argv) {
 | 
			
		||||
  testing::InitGoogleTest(&argc, argv);
 | 
			
		||||
  return RUN_ALL_TESTS();
 | 
			
		||||
}
 | 
			
		||||
		Reference in New Issue
	
	Block a user