Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017 #ifndef CARTOGRAPHER_MAPPING_INTERNAL_3D_IMU_INTEGRATION_H_
00018 #define CARTOGRAPHER_MAPPING_INTERNAL_3D_IMU_INTEGRATION_H_
00019
00020 #include <algorithm>
00021 #include <deque>
00022
00023 #include "Eigen/Core"
00024 #include "Eigen/Geometry"
00025 #include "cartographer/common/time.h"
00026 #include "cartographer/sensor/imu_data.h"
00027 #include "cartographer/transform/transform.h"
00028 #include "glog/logging.h"
00029
00030 namespace cartographer {
00031 namespace mapping {
00032
00033 template <typename T>
00034 struct IntegrateImuResult {
00035 Eigen::Matrix<T, 3, 1> delta_velocity;
00036 Eigen::Quaternion<T> delta_rotation;
00037 };
00038
00039 template <typename T, typename RangeType, typename IteratorType>
00040 IntegrateImuResult<T> IntegrateImu(
00041 const RangeType& imu_data,
00042 const Eigen::Transform<T, 3, Eigen::Affine>&
00043 linear_acceleration_calibration,
00044 const Eigen::Transform<T, 3, Eigen::Affine>& angular_velocity_calibration,
00045 const common::Time start_time, const common::Time end_time,
00046 IteratorType* const it) {
00047 CHECK_LE(start_time, end_time);
00048 CHECK(*it != imu_data.end());
00049 CHECK_LE((*it)->time, start_time);
00050 if (std::next(*it) != imu_data.end()) {
00051 CHECK_GT(std::next(*it)->time, start_time);
00052 }
00053
00054 common::Time current_time = start_time;
00055
00056 IntegrateImuResult<T> result = {Eigen::Matrix<T, 3, 1>::Zero(),
00057 Eigen::Quaterniond::Identity().cast<T>()};
00058 while (current_time < end_time) {
00059 common::Time next_imu_data = common::Time::max();
00060 if (std::next(*it) != imu_data.end()) {
00061 next_imu_data = std::next(*it)->time;
00062 }
00063 common::Time next_time = std::min(next_imu_data, end_time);
00064 const T delta_t(common::ToSeconds(next_time - current_time));
00065
00066 const Eigen::Matrix<T, 3, 1> delta_angle =
00067 (angular_velocity_calibration *
00068 (*it)->angular_velocity.template cast<T>()) *
00069 delta_t;
00070 result.delta_rotation *=
00071 transform::AngleAxisVectorToRotationQuaternion(delta_angle);
00072 result.delta_velocity += result.delta_rotation *
00073 ((linear_acceleration_calibration *
00074 (*it)->linear_acceleration.template cast<T>()) *
00075 delta_t);
00076 current_time = next_time;
00077 if (current_time == next_imu_data) {
00078 ++(*it);
00079 }
00080 }
00081 return result;
00082 }
00083
00084
00085 template <typename RangeType, typename IteratorType>
00086 IntegrateImuResult<double> IntegrateImu(const RangeType& imu_data,
00087 const common::Time start_time,
00088 const common::Time end_time,
00089 IteratorType* const it) {
00090 return IntegrateImu<double, RangeType, IteratorType>(
00091 imu_data, Eigen::Affine3d::Identity(), Eigen::Affine3d::Identity(),
00092 start_time, end_time, it);
00093 }
00094
00095 }
00096 }
00097
00098 #endif // CARTOGRAPHER_MAPPING_INTERNAL_3D_IMU_INTEGRATION_H_