@@ -84,6 +84,7 @@ class ImuIntegrator
8484public:
8585 void addSample (const ImuMsg& imu);
8686 void trimSamples (TimeFloatT trim_ts);
87+ void setAutoTrimWindow (TimeFloatT window_s = 0 .f);
8788 bool recalibrate (TimeFloatT dt, bool force = false );
8889
8990 Vec3 estimateGravity (
@@ -121,6 +122,7 @@ class ImuIntegrator
121122 std::atomic<bool > use_orientation;
122123
123124 const double calib_time;
125+ double trim_window{600.0 };
124126};
125127
126128
@@ -156,10 +158,13 @@ void ImuIntegrator<F>::addSample(const ImuMsg& imu)
156158 stamp,
157159 q);
158160
159- // 10 min max, orientation is likely still valid but at this point we probably have worse problems
160- util::tsq::trimToStamp (
161- this ->orient_buffer ,
162- (util::tsq::newestStamp (this ->orient_buffer ) - 600 .));
161+ if (this ->trim_window > 0 )
162+ {
163+ util::tsq::trimToStamp (
164+ this ->orient_buffer ,
165+ (util::tsq::newestStamp (this ->orient_buffer ) -
166+ this ->trim_window ));
167+ }
163168 }
164169
165170 {
@@ -179,10 +184,12 @@ void ImuIntegrator<F>::addSample(const ImuMsg& imu)
179184 this ->recalibrateRange (0 , this ->raw_buffer .size ());
180185 }
181186
182- // 5 min max, integration is definitely deviated after this for most imus
183- util::tsq::trimToStamp (
184- this ->raw_buffer ,
185- (util::tsq::newestStamp (this ->raw_buffer ) - 300 .));
187+ if (this ->trim_window > 0 )
188+ {
189+ util::tsq::trimToStamp (
190+ this ->raw_buffer ,
191+ (util::tsq::newestStamp (this ->raw_buffer ) - this ->trim_window ));
192+ }
186193 }
187194}
188195
@@ -195,6 +202,14 @@ void ImuIntegrator<F>::trimSamples(TimeFloatT trim_ts)
195202 util::tsq::trimToStamp (this ->raw_buffer , trim_ts);
196203}
197204
205+ template <typename F>
206+ void ImuIntegrator<F>::setAutoTrimWindow(TimeFloatT window_s)
207+ {
208+ std::unique_lock imu_lock{this ->mtx };
209+
210+ this ->trim_window = window_s;
211+ }
212+
198213template <typename F>
199214bool ImuIntegrator<F>::recalibrate(TimeFloatT dt, bool force)
200215{
@@ -265,6 +280,8 @@ typename ImuIntegrator<F>::Quat ImuIntegrator<F>::getDelta(
265280 TimeFloatT start,
266281 TimeFloatT end) const
267282{
283+ using namespace util ::geom::cvt::ops;
284+
268285 Quat q = Quat::Identity ();
269286 std::unique_lock imu_lock{this ->mtx };
270287
@@ -282,72 +299,89 @@ typename ImuIntegrator<F>::Quat ImuIntegrator<F>::getDelta(
282299 newest--;
283300 }
284301
285- if (newest != oldest)
302+ if (newest < oldest)
286303 {
287304 const auto & a = this ->orient_buffer [oldest];
288305 const auto & b = this ->orient_buffer [oldest - 1 ];
289306 const auto & c = this ->orient_buffer [newest + 1 ];
290307 const auto & d = this ->orient_buffer [newest];
291308
292- Quat prev = a.second .slerp (
309+ const Quat prev = a.second .slerp (
293310 (start - a.first ) / (b.first - a.first ),
294311 b.second );
295- Quat curr =
312+ const Quat curr =
296313 c.second .slerp ((end - c.first ) / (d.first - c.first ), d.second );
297314
298315 q = prev.inverse () * curr;
299316 }
300317 }
301318 else
302319 {
303- assert (!" IMU angular velocity integration is not implemented!" );
304- #if 0 // TODO
305- const size_t
306- init_idx = util::tsq::binarySearchIdx(this->imu_buffer, start),
307- end_idx = util::tsq::binarySearchIdx(this->imu_buffer, end);
308-
309- // Relative IMU integration of gyro and accelerometer
310- double curr_imu_stamp = 0.;
311- double prev_imu_stamp = 0.;
312- double dt;
313-
314- for(size_t i = init_idx; i >= end_idx; i--)
320+ size_t oldest = util::tsq::binarySearchIdx (this ->raw_buffer , start);
321+ size_t newest = util::tsq::binarySearchIdx (this ->raw_buffer , end);
322+
323+ if (oldest == this ->raw_buffer .size () && oldest > 0 )
324+ {
325+ oldest--;
326+ }
327+ if (newest > 0 )
315328 {
316- const auto& imu_sample = this->raw_buffer[i];
329+ newest--;
330+ }
317331
318- if(prev_imu_stamp == 0.)
332+ if (newest < oldest)
333+ {
334+ const auto & a = this ->raw_buffer [oldest];
335+ const auto & b = this ->raw_buffer [oldest - 1 ];
336+ const auto & c = this ->raw_buffer [newest + 1 ];
337+ const auto & d = this ->raw_buffer [newest];
338+
339+ const Vec3 head =
340+ a.second .ang_vel + (b.second .ang_vel - a.second .ang_vel ) *
341+ (start - a.first ) / (b.first - a.first );
342+ const Vec3 tail =
343+ c.second .ang_vel + (d.second .ang_vel - c.second .ang_vel ) *
344+ (end - c.first ) / (d.first - c.first );
345+
346+ for (size_t i = oldest; i > newest; i--)
319347 {
320- prev_imu_stamp = imu_sample.first;
321- continue;
348+ const Vec3 *from, *to;
349+ double from_t , to_t ;
350+ if (i == oldest)
351+ {
352+ from = &head;
353+ from_t = start;
354+ }
355+ else
356+ {
357+ from = &(this ->raw_buffer [i].second .ang_vel );
358+ from_t = this ->raw_buffer [i].first ;
359+ }
360+
361+ if (i - 1 == newest)
362+ {
363+ to = &tail;
364+ to_t = end;
365+ }
366+ else
367+ {
368+ to = &(this ->raw_buffer [i - 1 ].second .ang_vel );
369+ to_t = this ->raw_buffer [i - 1 ].first ;
370+ }
371+
372+ const Vec3 avg_w = (*from + *to) * 0 .5f ;
373+ const FloatT dt = static_cast <FloatT>(to_t - from_t );
374+ const Vec3 theta = avg_w * dt;
375+ const FloatT angle = theta.norm ();
376+
377+ if (angle > 1e-8 )
378+ {
379+ const Vec3 axis = theta / angle;
380+ q = (q * Quat{Eigen::AngleAxis<FloatT>(angle, axis)})
381+ .normalized ();
382+ }
322383 }
323-
324- // Calculate difference in imu measurement times IN SECONDS
325- curr_imu_stamp = imu_sample.first;
326- dt = curr_imu_stamp - prev_imu_stamp;
327- prev_imu_stamp = curr_imu_stamp;
328-
329- // Relative gyro propagation quaternion dynamics
330- Quatd qq = q;
331- q.w() -= 0.5 * dt *
332- (qq.x() * imu_sample.second.ang_vel.x()
333- + qq.y() * imu_sample.second.ang_vel.y()
334- + qq.z() * imu_sample.second.ang_vel.z() );
335- q.x() += 0.5 * dt *
336- (qq.w() * imu_sample.second.ang_vel.x()
337- - qq.z() * imu_sample.second.ang_vel.y()
338- + qq.y() * imu_sample.second.ang_vel.z() );
339- q.y() += 0.5 * dt *
340- (qq.z() * imu_sample.second.ang_vel.x()
341- + qq.w() * imu_sample.second.ang_vel.y()
342- - qq.x() * imu_sample.second.ang_vel.z() );
343- q.z() += 0.5 * dt *
344- (qq.x() * imu_sample.second.ang_vel.y()
345- - qq.y() * imu_sample.second.ang_vel.x()
346- + qq.w() * imu_sample.second.ang_vel.z() );
347384 }
348-
349- q.normalize();
350- #endif
351385 }
352386
353387 return q;
0 commit comments