@@ -82,7 +82,7 @@ static pbio_geometry_xyz_t acceleration_calibrated; // mm/s^2, in hub frame
8282 * 1D integrated angular velocity for each body axis.
8383 *
8484 * This is based on integrating the calibrated angular velocity over time, so
85- * including its bias and adjustments to achhieve 360 degrees per rotation.
85+ * including its bias and adjustments to achieve 360 degrees per rotation.
8686 *
8787 * This is not used for 3D attitude estimation, but serves as a useful way to
8888 * estimate 1D rotations without being effected by accelerometer fusion which
@@ -180,9 +180,8 @@ const float standard_gravity = 9806.65f;
180180 */
181181static void pbio_imu_apply_pbdrv_settings (pbio_imu_persistent_settings_t * settings ) {
182182
183- // IMU config is loaded set pbio, while this first occurence of applying
184- // settings is only called by pbsys (after pbio init), so this should
185- // never happen.
183+ // First occurence of this being called is when pbsys loads or resets
184+ // the settings, so this should never happen.
186185 if (!imu_config ) {
187186 return ;
188187 }
@@ -206,6 +205,7 @@ void pbio_imu_set_default_settings(pbio_imu_persistent_settings_t *settings) {
206205 settings -> gravity_neg .x = settings -> gravity_neg .y = settings -> gravity_neg .z = - standard_gravity ;
207206 settings -> angular_velocity_bias_start .x = settings -> angular_velocity_bias_start .y = settings -> angular_velocity_bias_start .z = 0.0f ;
208207 settings -> angular_velocity_scale .x = settings -> angular_velocity_scale .y = settings -> angular_velocity_scale .z = 360.0f ;
208+ settings -> heading_correction_1d = 360.0f ;
209209 pbio_imu_apply_pbdrv_settings (settings );
210210}
211211
@@ -521,6 +521,10 @@ pbio_error_t pbio_imu_set_settings(pbio_imu_persistent_settings_t *new_settings)
521521 persistent_settings -> gravity_neg = new_settings -> gravity_neg ;
522522 }
523523
524+ if (new_settings -> flags & PBIO_IMU_SETTINGS_FLAGS_HEADING_CORRECTION_1D_SET ) {
525+ persistent_settings -> heading_correction_1d = new_settings -> heading_correction_1d ;
526+ }
527+
524528 // If any settings were changed, request saving.
525529 if (new_settings -> flags ) {
526530 persistent_settings -> flags |= new_settings -> flags ;
@@ -621,18 +625,38 @@ pbio_geometry_side_t pbio_imu_get_up_side(bool calibrated) {
621625 return pbio_geometry_side_from_vector (acceleration );
622626}
623627
624- static float heading_offset = 0 ;
628+ static float heading_offset_1d = 0 ;
629+ static float heading_offset_3d = 0 ;
625630
626631/**
627632 * Reads the estimated IMU heading in degrees, accounting for user offset and
628633 * user-specified heading correction scaling constant.
629634 *
630635 * Heading is defined as clockwise positive.
631636 *
637+ * @param [in] type The type of heading to get.
638+ *
632639 * @return Heading angle in the base frame.
633640 */
634- float pbio_imu_get_heading (void ) {
635- return heading_rotations * 360.0f + heading_projection - heading_offset ;
641+ float pbio_imu_get_heading (pbio_imu_heading_type_t type ) {
642+
643+ // 3D. Mapping into user frame is already accounted for in the projection.
644+ if (type == PBIO_IMU_HEADING_TYPE_3D ) {
645+ return heading_rotations * 360.0f + heading_projection - heading_offset_3d ;
646+ }
647+
648+ // 1D. Map the per-axis integrated rotation to the user frame, then take
649+ // the negative z component as the heading for positive-clockwise convention.
650+ pbio_geometry_xyz_t heading_mapped ;
651+ pbio_geometry_vector_map (& pbio_imu_base_orientation , & single_axis_rotation , & heading_mapped );
652+
653+ float correction = (persistent_settings && (persistent_settings -> flags & PBIO_IMU_SETTINGS_FLAGS_HEADING_CORRECTION_1D_SET )) ?
654+ // If set, adjust by the user-specified scaling constant.
655+ (360.0f / persistent_settings -> heading_correction_1d ):
656+ // No (additional) correction.
657+ 1.0f ;
658+
659+ return - heading_mapped .z * correction - heading_offset_1d ;
636660}
637661
638662/**
@@ -645,7 +669,8 @@ float pbio_imu_get_heading(void) {
645669 */
646670void pbio_imu_set_heading (float desired_heading ) {
647671 heading_rotations = 0 ;
648- heading_offset = pbio_imu_get_heading () + heading_offset - desired_heading ;
672+ heading_offset_3d = pbio_imu_get_heading (PBIO_IMU_HEADING_TYPE_3D ) + heading_offset_3d - desired_heading ;
673+ heading_offset_1d = pbio_imu_get_heading (PBIO_IMU_HEADING_TYPE_1D ) + heading_offset_1d - desired_heading ;
649674}
650675
651676/**
@@ -657,14 +682,15 @@ void pbio_imu_set_heading(float desired_heading) {
657682 *
658683 * Heading is defined as clockwise positive.
659684 *
685+ * @param [in] type Heading type to get.
660686 * @param [out] heading The heading angle in control units.
661687 * @param [out] heading_rate The heading rate in control units.
662688 * @param [in] ctl_steps_per_degree The number of control steps per heading degree.
663689 */
664- void pbio_imu_get_heading_scaled (pbio_angle_t * heading , int32_t * heading_rate , int32_t ctl_steps_per_degree ) {
690+ void pbio_imu_get_heading_scaled (pbio_imu_heading_type_t type , pbio_angle_t * heading , int32_t * heading_rate , int32_t ctl_steps_per_degree ) {
665691
666692 // Heading in degrees of the robot.
667- float heading_degrees = pbio_imu_get_heading ();
693+ float heading_degrees = pbio_imu_get_heading (type );
668694
669695 // Number of whole rotations in control units (in terms of wheels, not robot).
670696 heading -> rotations = (int32_t )(heading_degrees / (360000.0f / ctl_steps_per_degree ));
0 commit comments