34 std::make_unique<ImuSignalLowPassFilter>(graphConfigPtr->imuLowPassFilterCutoffFreqHz_, 1.0 / graphConfigPtr->imuRate_);
40Eigen::Matrix<double, 6, 1>
ImuBuffer::addToImuBuffer(
double ts,
const Eigen::Vector3d& linearAcc,
const Eigen::Vector3d& angularVel) {
43 throw std::runtime_error(
"GMsfImuBuffer: imuBufferLength has to be set by the user.");
47 Eigen::Matrix<double, 6, 1> filteredImuMeas;
53 filteredImuMeas << linearAcc, angularVel;
76 std::ostringstream errorStream;
77 errorStream <<
YELLOW_START <<
"GMsf-ImuBuffer" <<
COLOR_END <<
" IMU Buffer has grown too large. It contains "
79 throw std::runtime_error(errorStream.str());
83 return filteredImuMeas;
96 std::ostringstream errorStream;
97 errorStream <<
YELLOW_START <<
"GMsf-ImuBuffer" <<
RED_START <<
" IMU Measurement at time " << std::fixed << ts
98 <<
" not found in buffer.";
101 returnedImuMeasurement = imuItr->second;
110 imuMap[previousItr->first] = previousItr->second;
111 imuMap[endItr->first] = endItr->second;
117 throw std::runtime_error(
118 "ImuBufferLength is not large enough for "
119 "initialization. Must be at least 1 second.");
127 Eigen::Vector3d initAccMean(0.0, 0.0, 0.0), initGyrMean(0.0, 0.0, 0.0);
129 initAccMean += itr.second.acceleration;
130 initGyrMean += itr.second.angularVelocity;
135 gravityMagnitude = initAccMean.norm();
136 Eigen::Vector3d gUnitVecInWorld = Eigen::Vector3d(0.0, 0.0, 1.0);
140 initAccMean.normalize();
141 initAttitude = gtsam::Rot3(Eigen::Quaterniond().setFromTwoVectors(initAccMean, gUnitVecInWorld));
145 gyrBias = initGyrMean;
148 std::cout <<
YELLOW_START <<
"GMsf-ImuBuffer" <<
COLOR_END <<
" Gravity Magnitude: " << gravityMagnitude << std::endl;
149 std::cout <<
YELLOW_START <<
"GMsf-ImuBuffer" <<
COLOR_END <<
" Mean IMU Acceleration Vector(x,y,z): " << initAccMean.transpose()
150 <<
" - Gravity Unit Vector(x,y,z): " << gUnitVecInWorld.transpose() << std::endl;
151 std::cout <<
YELLOW_START <<
"GMsf-ImuBuffer" <<
GREEN_START <<
" RPY (deg): " << initAttitude.rpy().transpose() * (180.0 / M_PI)
153 std::cout <<
YELLOW_START <<
"GMsf-ImuBuffer" <<
COLOR_END <<
" Gyro bias(x,y,z): " << initGyrMean.transpose() << std::endl;
159 TimeToImuMap::iterator& endIterator) {
161 if (tsStart >= tsEnd) {
162 std::cerr <<
YELLOW_START <<
"GMsf-ImuBuffer" <<
RED_START <<
" IMU Lookup Timestamps are not correct ts_start(" << std::fixed
163 << tsStart <<
") >= ts_end(" << tsEnd <<
")\n";
176 <<
" Lookup requires first message of IMU buffer, cannot "
179 << std::fixed << tsStart <<
"/" << tsEnd <<
", Buffer Start/End: " <<
timeToImuBuffer_.begin()->first <<
"/"
187 <<
" IMU Lookup start time ahead latest IMU message in the "
189 << tsStart <<
", latest IMU: " <<
timeToImuBuffer_.rbegin()->first << std::endl;
195 std::cerr <<
YELLOW_START <<
"GMsf-ImuBuffer" <<
RED_START <<
" Lookup is past IMU buffer, with lookup Start/End: " << std::fixed
196 << tsStart <<
"/" << tsEnd <<
" and latest IMU: " <<
timeToImuBuffer_.rbegin()->first << std::endl;
201 if (startIterator == endIterator) {
203 <<
" Not Enough IMU values between timestamps , with Start/End: " << std::fixed << tsStart <<
"/" << tsEnd
204 <<
", with diff: " << tsEnd - tsStart << std::endl;
213 const double maxSearchDeviation,
const double tK) {
224 const auto lowerIterator = std::prev(closestIterator);
225 if (tK - lowerIterator->first < closestIterator->first - tK) {
226 closestIterator = lowerIterator;
229 returnedImuTimestamp = closestIterator->first;
230 returnedImuMeasurement = closestIterator->second;
231 const double timeDeviation = returnedImuTimestamp - tK;
234 std::cout <<
YELLOW_START <<
"GMsf-ImuBuffer" <<
COLOR_END <<
" Searched time step: " << std::setprecision(14) << tK << std::endl;
235 std::cout <<
YELLOW_START <<
"GMsf-ImuBuffer" <<
COLOR_END <<
" Found time step: " << std::setprecision(14) << returnedImuTimestamp
237 std::cout <<
YELLOW_START <<
"GMsf-ImuBuffer" <<
COLOR_END <<
" Time Deviation (t_graph-t_request): " << 1000 * timeDeviation <<
" ms"
240 <<
", hence absolut delay of measurement is " << 1000 * (
tLatestInBuffer_ - tK) <<
"ms." << std::endl;
244 if (std::abs(timeDeviation) > maxSearchDeviation) {
252 const gtsam::imuBias::ConstantBias& imuBias,
253 const Eigen::Vector3d& W_gravityVector) {
255 TimeToImuMap::iterator startIterator, nextToStartIterator, endIterator;
258 throw std::runtime_error(
"Could not get IMU iterators in interval");
260 nextToStartIterator = startIterator;
261 ++nextToStartIterator;
264 gtsam::NavState propagatedState = stateStart;
267 Eigen::Vector3d i_measAcceleration, i_measAngularVelocity;
268 for (; startIterator != endIterator; ++startIterator, ++nextToStartIterator) {
270 i_measAcceleration = imuBias.correctAccelerometer(nextToStartIterator->second.acceleration);
271 i_measAngularVelocity = imuBias.correctGyroscope(nextToStartIterator->second.angularVelocity);
274 double dt = nextToStartIterator->first - startIterator->first;
277 Eigen::Vector3d i_gravityVector = propagatedState.R().transpose() * W_gravityVector;
279 propagatedState.update(i_gravityVector + i_measAcceleration, i_measAngularVelocity, dt);
281 return propagatedState;
ImuBuffer(const std::shared_ptr< GraphConfig > graphConfigPtr)
bool useImuSignalLowPassFilter_
bool getClosestImuMeasurement(double &returnedImuTimestamp, ImuMeasurement &returnedImuMeasurement, const double maxSearchDeviation, const double tK)
TimeToImuMap timeToImuBuffer_
double getLatestTimestampInBuffer()
gtsam::NavState integrateNavStateFromTimestamp(const double &tsStart, const double &tsEnd, const gtsam::NavState &stateStart, const gtsam::imuBias::ConstantBias &imuBias, const Eigen::Vector3d &W_gravityVector)
std::unique_ptr< ImuSignalLowPassFilter > imuSignalLowPassFilterPtr_
Eigen::Matrix< double, 6, 1 > addToImuBuffer(double ts, const Eigen::Vector3d &linearAcc, const Eigen::Vector3d &angularVel)
void getLastTwoMeasurements(TimeToImuMap &imuMap)
std::mutex writeInBufferMutex_
bool getImuMeasurementAtTime(holistic_fusion::ImuMeasurement &returnedImuMeasurement, const double ts)
bool estimateAttitudeFromImu(gtsam::Rot3 &initAttitude, double &gravityMagnitude, Eigen::Vector3d &gyrBias)
Determine initial IMU pose w.r.t to gravity vector pointing up.
bool getIMUBufferIteratorsInInterval(const double tsStart, const double tsEnd, TimeToImuMap::iterator &startIterator, TimeToImuMap::iterator &endIterator)
double imuPoseInitWaitSecs_
std::map< double, holistic_fusion::ImuMeasurement, std::less< double >, Eigen::aligned_allocator< std::pair< const double, holistic_fusion::ImuMeasurement > > > TimeToImuMap
Eigen::Vector3d acceleration
Eigen::Vector3d angularVelocity