239void voxl::FrameTransform::update(
const imu_data_t &data)
243 printf(
"[INFO] IMU body measurements are disabled, THIS WON'T WORK AS EXPECTED.\n");
254 Eigen::Vector3d accel(data.accl_ms2[0], data.accl_ms2[1], data.accl_ms2[2]);
255 accel = accel / accel.norm();
257 Eigen::Vector3d grav_versor_expected = Eigen::Vector3d::UnitZ();
259 grav_versor_expected = -grav_versor_expected;
260 auto dot_product = accel.dot(grav_versor_expected);
261 dot_product = std::max(-1.0, std::min(1.0, dot_product));
262 double angle_rad = std::acos(dot_product);
263 double angle_deg = angle_rad * 180.0 / M_PI;
264 gravity_axis = Axis::Z;
265 gravity_direction = Direction::NEGATIVE;
266 printf(
"[INFO] IMU Initialization: Gravity angle = %.2f degrees\n", angle_deg);
267 if (angle_deg > 15.0)
269 printf(
"[ERROR] IMU Initialization: Gravity angle too large, cannot initialize\n");
270 is_initialized =
false;
275 printf(
"[INFO] IMU Initialization: Gravity angle within acceptable range\n");
276 is_initialized =
true;
280 printf(
"[INFO] Frame transform initialized - Gravity axis: %d, Direction: %d\n",
281 static_cast<int>(gravity_axis),
282 static_cast<int>(gravity_direction));
284void voxl::FrameTransform::detectJerk(
const imu_data_t &data)
287 const float vel_mag_current =
vel_mag.load(std::memory_order_acquire);
295 if (current_total_samples >= expected_total_samples * 0.5f)
297 resetJerkDetection();
303 const Eigen::Vector3d acc_sample(data.accl_ms2[0], data.accl_ms2[1], data.accl_ms2[2]);
304 const Eigen::Vector3d gyro_sample(data.gyro_rad[0], data.gyro_rad[1], data.gyro_rad[2]);
307 if (current_total_samples <= expected_total_samples * 0.5f)
309 avg_acc_1t0 += acc_sample;
310 avg_gyro_1t0 += gyro_sample;
311 acc1t0_samples.push_back(acc_sample);
312 gyro1t0_samples.push_back(gyro_sample);
313 current_total_samples += 1.0f;
316 else if (current_total_samples > expected_total_samples * 0.5f && current_total_samples < expected_total_samples)
319 avg_acc_2t1 += acc_sample;
320 avg_gyro_2t1 += gyro_sample;
321 acc2t1_samples.push_back(acc_sample);
322 gyro2t1_samples.push_back(gyro_sample);
323 current_total_samples += 1.0f;
325 else if (current_total_samples >= expected_total_samples)
329 double var_acc1t0 = 0.0, var_gyro1t0 = 0.0, var_acc2t1 = 0.0, var_gyro2t1 = 0.0;
331 avg_acc_1t0 /= acc1t0_samples.size();
332 avg_gyro_1t0 /= gyro1t0_samples.size();
333 avg_acc_2t1 /= acc2t1_samples.size();
334 avg_gyro_2t1 /= gyro2t1_samples.size();
337 for (
size_t i = 0; i < acc1t0_samples.size(); ++i)
339 var_acc1t0 += (acc1t0_samples[i] - avg_acc_1t0).dot(acc1t0_samples[i] - avg_acc_1t0);
340 var_gyro1t0 += (gyro1t0_samples[i] - avg_gyro_1t0).dot(gyro1t0_samples[i] - avg_gyro_1t0);
342 var_acc1t0 = std::sqrt(var_acc1t0 / (acc1t0_samples.size() - 1));
343 var_gyro1t0 = std::sqrt(var_gyro1t0 / (gyro1t0_samples.size() - 1));
345 for (
size_t i = 0; i < acc2t1_samples.size(); ++i)
347 var_acc2t1 += (acc2t1_samples[i] - avg_acc_2t1).dot(acc2t1_samples[i] - avg_acc_2t1);
348 var_gyro2t1 += (gyro2t1_samples[i] - avg_gyro_2t1).dot(gyro2t1_samples[i] - avg_gyro_2t1);
350 var_acc2t1 = std::sqrt(var_acc2t1 / (acc2t1_samples.size() - 1));
351 var_gyro2t1 = std::sqrt(var_gyro2t1 / (gyro2t1_samples.size() - 1));
354 printf(
"Accelerometer variance: %f, %f\n", var_acc1t0, var_acc2t1);
355 printf(
"Gyroscope variance: %f, %f\n", var_gyro1t0, var_gyro2t1);
358 bool accel_jerk_detected =
false;
359 bool gyro_jerk_detected =
false;
363 case JerkOption::ACCEL_ONLY:
366 case JerkOption::GYRO_ONLY:
369 case JerkOption::ACCEL_AND_GYRO:
373 case JerkOption::NONE:
375 resetJerkDetection();
381 has_acc_jerk.store(accel_jerk_detected, std::memory_order_release);
382 has_gyro_jerk.store(gyro_jerk_detected, std::memory_order_release);
383 non_static.store(accel_jerk_detected || gyro_jerk_detected, std::memory_order_release);
384 avg_acc_1t0.setZero();
385 avg_gyro_1t0.setZero();
386 avg_acc_2t1.setZero();
387 avg_gyro_2t1.setZero();
388 current_total_samples = 0;
389 acc1t0_samples.clear();
390 gyro1t0_samples.clear();
391 acc2t1_samples.clear();
392 gyro2t1_samples.clear();
398void voxl::FrameTransform::resetJerkDetection()
402 non_static.store(
true, std::memory_order_release);
405 avg_acc_1t0.setZero();
406 avg_gyro_1t0.setZero();
407 avg_acc_2t1.setZero();
408 avg_gyro_2t1.setZero();
409 current_total_samples = 0;
410 acc1t0_samples.clear();
411 gyro1t0_samples.clear();
412 acc2t1_samples.clear();
413 gyro2t1_samples.clear();
Common definitions and utilities for the VOXL OpenVINS server.
int en_verbose
Enable verbose output.
bool occlude_stereo_right
Occlude stereo right.
int cameras_used
Number of cameras currently in use.
volatile int64_t last_cam_time
Timestamp of last camera data (nanoseconds)
float fusion_rate_dt_ms
Fusion rate in milliseconds.
volatile int64_t last_imu_timestamp_ns
Timestamp of last IMU data (nanoseconds)
int camera_pipe_channels[MAX_CAM_CNT]
Camera pipe channels array.
volatile int main_running
Main process running flag.
char folder_base[CHAR_BUF_SIZE]
Base folder for yaml configuration files.
std::atomic< uint32_t > active_callbacks
Number of callbacks inside the system.
ov_msckf::VioManagerOptions vio_manager_options
VIO manager options.
int quality_initial_to_bad_count
Consecutive samples for INITIAL→BAD transition.
int quality_low_thresh_initial
Quality low threshold for INITIAL state.
int takeoff_cam
Takeoff camera identifier.
int quality_bad_to_good_count
Consecutive samples for BAD→GOOD transition.
float fast_yaw_thresh
Fast yaw threshold.
int en_auto_reset
Enable automatic reset functionality.
float auto_fallback_timeout_s
Auto fallback timeout (seconds)
float auto_reset_max_velocity
Maximum velocity threshold for auto reset.
char imu_name[64]
IMU device name.
voxl::FrameTransform frame_transform
Global frame transform instance.
bool en_cont_yaw_checks
Enable continuous yaw checks.
bool occlude_stereo_left
Occlude stereo left.
int quality_good_to_bad_count
Consecutive samples for GOOD→BAD transition.
float auto_reset_max_v_cov_timeout_s
Timeout duration for velocity covariance reset (seconds)
double window_size_s
Window size in seconds for jerk detection.
std::mutex reset_mtx
Mutex used by reset thread.
float auto_reset_max_v_cov
Maximum velocity covariance for timeout reset.
int using_stereo
using_stereo
float ok_state_grace_timeout_s
Minimum amount of time after initialization that quality is held low (CEP)
voxl::img_ringbuf_packet * img_ringbuf
Image ring buffer for processing.
bool en_imu_body
Enable IMU body measurements.
float auto_reset_min_feature_timeout_s
Minimum feature timeout for auto reset (seconds)
float auto_fallback_min_v
Minimum velocity for auto fallback.
float takeoff_alt_threshold
Takeoff altitude threshold.
imu_model_t imu_model
Active IMU model.
int en_takeoff_cam
Enable takeoff camera functionality.
std::atomic< uint32_t > reset_num_counter
Counter which increments on resets.
float fast_yaw_timeout_s
Fast yaw timeout (seconds)
int auto_reset_min_features
Minimum number of features for auto reset.
std::unique_ptr< ov_msckf::VioManager > vio_manager
Main VIO manager instance.
std::vector< int > takeoff_cams
Vector of takeoff camera identifiers.
int quality_high_thresh
Quality high threshold for recovery.
int en_debug
Enable debug output.
std::vector< cam_info > cam_info_vec
Vector of camera configuration information.
float auto_reset_max_v_cov_instant
Maximum velocity covariance for instant reset.
int quality_low_thresh_good
Quality low threshold for GOOD state.
int quality_initial_to_good_count
Consecutive samples for INITIAL→GOOD transition.
int config_only
Configuration only mode.
std::condition_variable reset_cv
Reset conditional variable.
bool sync_config
Flag to indicate if configuration synchronization is enabled.
Global variable declarations and constants for VOXL OpenVINS server.
#define VEL_MAG_JERK_THRESHOLD
Velocity magnitude threshold for jerk detection.
std::atomic< bool > non_static
Non-static flag for jerk detection.
std::atomic< bool > is_resetting
VIO reset state flag.
std::atomic< uint8_t > vio_state
Current VIO system state.
std::atomic< bool > is_armed
System armed state.
std::atomic< float > alt_z
Altitude z.
std::atomic< bool > has_acc_jerk
Flag indicating if accelerometer jerk is detected.
std::atomic< uint32_t > vio_error_codes
VIO error codes.
std::atomic< float > vel_mag
Velocity Magnitude.
#define ACC_VAR_THRESHOLD
Accelerometer variance threshold for motion detection.
imu_model_t
Enumeration of supported IMU models.
std::atomic< bool > is_imu_connected
IMU connection state.
std::atomic< bool > reset_requested
Should reset floag.
std::atomic< bool > has_gyro_jerk
Flag indicating if gyroscope jerk is detected.
std::atomic< double > imu_rate_hz
Estimated IMU sampling rate in Hz.
std::atomic< bool > is_cam_connected
Camera connection state.
#define CHAR_BUF_SIZE
Standard character buffer size.
#define GYRO_VAR_THRESHOLD
Gyro variance threshold for motion detection.
#define MAX_CAM_CNT
Maximum number of cameras supported by VOXL2.
Structure to hold image data packet for the ring buffer.