@@ -58,12 +58,8 @@ void pbio_imu_set_default_settings(pbio_imu_persistent_settings_t *settings) {
5858 settings -> gyro_stationary_threshold = 3.0f ;
5959 settings -> accel_stationary_threshold = 2500.0f ;
6060 settings -> heading_correction = 360.0f ;
61- settings -> gravity_x_pos = standard_gravity ;
62- settings -> gravity_x_neg = - standard_gravity ;
63- settings -> gravity_y_pos = standard_gravity ;
64- settings -> gravity_y_neg = - standard_gravity ;
65- settings -> gravity_z_pos = standard_gravity ;
66- settings -> gravity_z_neg = - standard_gravity ;
61+ settings -> gravity_pos .x = settings -> gravity_pos .y = settings -> gravity_pos .z = standard_gravity ;
62+ settings -> gravity_neg .x = settings -> gravity_neg .y = settings -> gravity_neg .z = - standard_gravity ;
6763 pbio_imu_apply_pbdrv_settings (settings );
6864}
6965
@@ -80,7 +76,8 @@ void pbio_imu_apply_loaded_settings(pbio_imu_persistent_settings_t *settings) {
8076
8177// Cached sensor values that can be read at any time without polling again.
8278static pbio_geometry_xyz_t angular_velocity ; // deg/s, in hub frame, already adjusted for bias.
83- static pbio_geometry_xyz_t acceleration ; // mm/s^2, in hub frame
79+ static pbio_geometry_xyz_t acceleration_uncalibrated ; // mm/s^2, in hub frame
80+ static pbio_geometry_xyz_t acceleration_calibrated ; // mm/s^2, in hub frame
8481static pbio_geometry_xyz_t gyro_bias ;
8582static pbio_geometry_xyz_t single_axis_rotation ; // deg, in hub frame
8683
@@ -89,7 +86,16 @@ static void pbio_imu_handle_frame_data_func(int16_t *data) {
8986 for (uint8_t i = 0 ; i < PBIO_ARRAY_SIZE (angular_velocity .values ); i ++ ) {
9087 // Update angular velocity and acceleration cache so user can read them.
9188 angular_velocity .values [i ] = data [i ] * imu_config -> gyro_scale - gyro_bias .values [i ];
92- acceleration .values [i ] = data [i + 3 ] * imu_config -> accel_scale ;
89+ acceleration_uncalibrated .values [i ] = data [i + 3 ] * imu_config -> accel_scale ;
90+
91+ // Once settings loaded, maintain calibrated cached values.
92+ if (persistent_settings ) {
93+ float acceleration_offset = (persistent_settings -> gravity_pos .values [i ] + persistent_settings -> gravity_neg .values [i ]) / 2 ;
94+ float acceleration_scale = (persistent_settings -> gravity_pos .values [i ] - persistent_settings -> gravity_neg .values [i ]) / 2 ;
95+ acceleration_calibrated .values [i ] = (acceleration_uncalibrated .values [i ] - acceleration_offset ) * standard_gravity / acceleration_scale ;
96+ } else {
97+ acceleration_calibrated .values [i ] = acceleration_uncalibrated .values [i ];
98+ }
9399
94100 // Update "heading" on all axes. This is not useful for 3D attitude
95101 // estimation, but it allows the user to get a 1D heading even with
@@ -246,21 +252,17 @@ pbio_error_t pbio_imu_set_settings(pbio_imu_persistent_settings_t *new_settings)
246252 }
247253
248254 if (new_settings -> flags & PBIO_IMU_SETTINGS_FLAGS_ACCEL_CALIBRATED ) {
249- if (pbio_imu_stationary_acceleration_out_of_range (new_settings -> gravity_x_pos , true) ||
250- pbio_imu_stationary_acceleration_out_of_range (new_settings -> gravity_x_neg , false) ||
251- pbio_imu_stationary_acceleration_out_of_range (new_settings -> gravity_y_pos , true) ||
252- pbio_imu_stationary_acceleration_out_of_range (new_settings -> gravity_y_neg , false) ||
253- pbio_imu_stationary_acceleration_out_of_range (new_settings -> gravity_z_pos , true) ||
254- pbio_imu_stationary_acceleration_out_of_range (new_settings -> gravity_z_neg , false)) {
255+ if (pbio_imu_stationary_acceleration_out_of_range (new_settings -> gravity_pos . x , true) ||
256+ pbio_imu_stationary_acceleration_out_of_range (new_settings -> gravity_neg . x , false) ||
257+ pbio_imu_stationary_acceleration_out_of_range (new_settings -> gravity_pos . y , true) ||
258+ pbio_imu_stationary_acceleration_out_of_range (new_settings -> gravity_neg . y , false) ||
259+ pbio_imu_stationary_acceleration_out_of_range (new_settings -> gravity_pos . z , true) ||
260+ pbio_imu_stationary_acceleration_out_of_range (new_settings -> gravity_neg . z , false)) {
255261 return PBIO_ERROR_INVALID_ARG ;
256262 }
257263 persistent_settings -> flags |= PBIO_IMU_SETTINGS_FLAGS_ACCEL_CALIBRATED ;
258- persistent_settings -> gravity_x_pos = new_settings -> gravity_x_pos ;
259- persistent_settings -> gravity_x_neg = new_settings -> gravity_x_neg ;
260- persistent_settings -> gravity_y_pos = new_settings -> gravity_y_pos ;
261- persistent_settings -> gravity_y_neg = new_settings -> gravity_y_neg ;
262- persistent_settings -> gravity_z_pos = new_settings -> gravity_z_pos ;
263- persistent_settings -> gravity_z_neg = new_settings -> gravity_z_neg ;
264+ persistent_settings -> gravity_pos = new_settings -> gravity_pos ;
265+ persistent_settings -> gravity_neg = new_settings -> gravity_neg ;
264266 }
265267
266268 // If any settings were changed, request saving.
@@ -275,14 +277,6 @@ pbio_error_t pbio_imu_set_settings(pbio_imu_persistent_settings_t *new_settings)
275277 return PBIO_SUCCESS ;
276278}
277279
278- /**
279- * Gets the thresholds that define when the hub is stationary.
280- *
281- * @param [out] angular_velocity Angular velocity threshold in deg/s.
282- * @param [out] acceleration Acceleration threshold in mm/s^2
283- * @param [out] heading_correction Measured degrees per full rotation of the hub.
284- */
285-
286280/**
287281 * Gets the IMU settings
288282 *
@@ -310,10 +304,13 @@ void pbio_imu_get_angular_velocity(pbio_geometry_xyz_t *values) {
310304/**
311305 * Gets the cached IMU acceleration in mm/s^2.
312306 *
307+ * @param [in] calibrated Whether to use calibrated or uncalibrated data.
308+ *
313309 * @param [out] values The acceleration vector.
314310 */
315- void pbio_imu_get_acceleration (pbio_geometry_xyz_t * values ) {
316- pbio_geometry_vector_map (& pbio_orientation_base_orientation , & acceleration , values );
311+ void pbio_imu_get_acceleration (pbio_geometry_xyz_t * values , bool calibrated ) {
312+ pbio_geometry_xyz_t * acceleration = calibrated ? & acceleration_calibrated : & acceleration_uncalibrated ;
313+ pbio_geometry_vector_map (& pbio_orientation_base_orientation , acceleration , values );
317314}
318315
319316/**
@@ -338,14 +335,17 @@ pbio_error_t pbio_imu_get_single_axis_rotation(pbio_geometry_xyz_t *axis, float
338335/**
339336 * Gets which side of a hub points upwards.
340337 *
338+ * @param [in] calibrated Whether to use calibrated or uncalibrated data.
339+ *
341340 * @return Which side is up.
342341 */
343- pbio_geometry_side_t pbio_imu_get_up_side (void ) {
342+ pbio_geometry_side_t pbio_imu_get_up_side (bool calibrated ) {
344343 // Up is which side of a unit box intersects the +Z vector first.
345344 // So read +Z vector of the inertial frame, in the body frame.
346345 // For now, this is the gravity vector. In the future, we can make this
347346 // slightly more accurate by using the full IMU orientation.
348- return pbio_geometry_side_from_vector (& acceleration );
347+ pbio_geometry_xyz_t * acceleration = calibrated ? & acceleration_calibrated : & acceleration_uncalibrated ;
348+ return pbio_geometry_side_from_vector (acceleration );
349349}
350350
351351static float heading_offset = 0 ;
0 commit comments