Skip to content

Commit 57793e3

Browse files
committedFeb 25, 2025·
pybricks.common.IMU: Simplify tilt and up.
When writing the API docs, I realized it was not easy to explain. Instead of having two kwargs to get three options, now use a single kwarg for only two options: Either fully raw or fully fused.
1 parent 6052a43 commit 57793e3

File tree

4 files changed

+31
-18
lines changed

4 files changed

+31
-18
lines changed
 

‎CHANGELOG.md

+10-4
Original file line numberDiff line numberDiff line change
@@ -5,10 +5,13 @@
55
## [Unreleased]
66

77
### Changed
8-
- Changed order of the `DriveBase.arc` method. This method has not yet been
9-
released or documented, so this is not a breaking change ([support#1157]).
8+
- Changed order of the `DriveBase.arc` method parameters. This method has not
9+
yet been released or documented, so this is not a breaking change ([support#1157]).
1010
- Reduced voltage threshold at which the charging light goes from red to green
1111
to indicate that the battery is full from 8300 to 8190 mV ([pybricks-micropython#292]).
12+
- Simplified API for `hub.imu.up()` and `hub.imu.tilt()` to only use a single
13+
`calibrated` keyword argument instead of separate `use_gyro` options. This
14+
had not been released yet so is not a breaking change.
1215

1316
## [3.6.0b4] - 2025-02-14
1417

@@ -31,13 +34,15 @@
3134
scale and acceleration offset and scale.
3235
- Added `hub.system.reset_storage` to restore storage and settings to default
3336
state.
37+
- Replaced `update_heading_correction` with `_imu_calibrate.py` for 3D
38+
calibration ([support#1907]).
3439

3540
### Changed
3641
- Enabled UTF-8 support for `str` objects.
3742
- The method `DriveBase.angle()` now returns a float ([support#1844]). This
3843
makes it properly equivalent to `hub.imu.heading`.
3944
- Re-implemented tilt using the gyro data by default. Pure accelerometer tilt
40-
can still be obtained with `hub.imu.tilt(use_gyro=False)`.
45+
can still be obtained with `hub.imu.tilt(calibrated=False)`.
4146
- Re-implemented `hub.imu.heading()` to use optionally use the projection of 3D
4247
orientation to improve performance when the hub is lifted off the ground.
4348
The 1D-based heading remains the default for now.
@@ -67,6 +72,7 @@
6772
[support#943]: https://github.com/pybricks/support/issues/943
6873
[support#1886]: https://github.com/pybricks/support/issues/1886
6974
[support#1844]: https://github.com/pybricks/support/issues/1844
75+
[support#1907]: https://github.com/pybricks/support/issues/1907
7076
[support#1975]: https://github.com/pybricks/support/issues/1975
7177
[support#1996]: https://github.com/pybricks/support/issues/1996
7278
[support#2055]: https://github.com/pybricks/support/issues/2055
@@ -151,7 +157,7 @@
151157
- Allow gyro calibration only while all motors are coasting ([support#1840]) to
152158
prevent recalibration during very steady moves ([support#1687])
153159
- Reduced default angular velocity stationary threshold from an undocumented
154-
5 deg/s to 3 deg/s to reduce unwanted calibration while moving ([support#1105]).
160+
5 deg/s to 2 deg/s to reduce unwanted calibration while moving ([support#1105]).
155161
- If `imu.reset_heading()` is called while a drive base is actively using the
156162
gyro, an exception will be raised ([support#1818]).
157163

‎bricks/primehub/modules/_imu_calibrate.py

+2-2
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ def beep(freq):
1616

1717

1818
def wait_for_stationary(side):
19-
while not hub.imu.stationary() or hub.imu.up() != side:
19+
while not hub.imu.stationary() or hub.imu.up(calibrated=False) != side:
2020
wait(10)
2121

2222

@@ -42,7 +42,7 @@ def roll_over_axis(axis, new_side):
4242
print("Roll it towards you, without lifting the hub up!")
4343

4444
angle_start = hub.imu.rotation(axis, calibrated=False)
45-
while hub.imu.up() != new_side or not hub.imu.stationary():
45+
while hub.imu.up(calibrated=False) != new_side or not hub.imu.stationary():
4646

4747
_, _, z = hub.imu.orientation() * axis
4848
if abs(z) > 0.07:

‎lib/pbio/src/imu.c

+15-6
Original file line numberDiff line numberDiff line change
@@ -590,7 +590,8 @@ void pbio_imu_get_acceleration(pbio_geometry_xyz_t *values, bool calibrated) {
590590
}
591591

592592
/**
593-
* Gets the vector that is parallel to the acceleration measurement of the stationary case.
593+
* Gets the tilt-based vector that is parallel to the acceleration measurement
594+
* if we were stationary.
594595
*
595596
* @param [out] values The acceleration vector.
596597
*/
@@ -639,17 +640,25 @@ pbio_error_t pbio_imu_get_single_axis_rotation(pbio_geometry_xyz_t *axis, float
639640
/**
640641
* Gets which side of a hub points upwards.
641642
*
642-
* @param [in] calibrated Whether to use calibrated or uncalibrated data.
643+
* @param [in] calibrated Whether to use calibrated/fused (true) or raw data (false).
643644
*
644645
* @return Which side is up.
645646
*/
646647
pbio_geometry_side_t pbio_imu_get_up_side(bool calibrated) {
647648
// Up is which side of a unit box intersects the +Z vector first.
648649
// So read +Z vector of the inertial frame, in the body frame.
649-
// For now, this is the gravity vector. In the future, we can make this
650-
// slightly more accurate by using the full IMU orientation.
651-
pbio_geometry_xyz_t *acceleration = calibrated ? &acceleration_calibrated : &acceleration_uncalibrated;
652-
return pbio_geometry_side_from_vector(acceleration);
650+
// This is either the raw acceleration or the third row of the fused
651+
// rotation matrix.
652+
653+
pbio_geometry_xyz_t *vector = &acceleration_uncalibrated;
654+
if (calibrated) {
655+
// This is similar to pbio_imu_get_tilt_vector, but this should stay
656+
// in the hub frame rather than projected into user frame.
657+
vector->x = pbio_imu_rotation.m31;
658+
vector->y = pbio_imu_rotation.m32;
659+
vector->z = pbio_imu_rotation.m33;
660+
}
661+
return pbio_geometry_side_from_vector(vector);
653662
}
654663

655664
static float heading_offset_1d = 0;

‎pybricks/common/pb_type_imu.c

+4-6
Original file line numberDiff line numberDiff line change
@@ -60,17 +60,16 @@ static MP_DEFINE_CONST_FUN_OBJ_KW(pb_type_imu_up_obj, 1, pb_type_imu_up);
6060
static mp_obj_t pb_type_imu_tilt(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) {
6161
PB_PARSE_ARGS_METHOD(n_args, pos_args, kw_args,
6262
pb_type_imu_obj_t, self,
63-
PB_ARG_DEFAULT_TRUE(use_gyro),
6463
PB_ARG_DEFAULT_TRUE(calibrated));
6564

6665
(void)self;
6766

6867
// Read acceleration in the user frame.
6968
pbio_geometry_xyz_t accl;
70-
if (mp_obj_is_true(use_gyro_in)) {
69+
if (mp_obj_is_true(calibrated_in)) {
7170
pbio_imu_get_tilt_vector(&accl);
7271
} else {
73-
pbio_imu_get_acceleration(&accl, mp_obj_is_true(calibrated_in));
72+
pbio_imu_get_acceleration(&accl, false);
7473
}
7574

7675
mp_obj_t tilt[2];
@@ -187,10 +186,10 @@ static mp_obj_t pb_type_imu_settings(size_t n_args, const mp_obj_t *pos_args, mp
187186
pb_type_imu_obj_t, self,
188187
PB_ARG_DEFAULT_NONE(angular_velocity_threshold),
189188
PB_ARG_DEFAULT_NONE(acceleration_threshold),
189+
PB_ARG_DEFAULT_NONE(heading_correction),
190190
PB_ARG_DEFAULT_NONE(angular_velocity_bias),
191191
PB_ARG_DEFAULT_NONE(angular_velocity_scale),
192-
PB_ARG_DEFAULT_NONE(acceleration_correction),
193-
PB_ARG_DEFAULT_NONE(heading_correction));
192+
PB_ARG_DEFAULT_NONE(acceleration_correction));
194193

195194
(void)self;
196195

@@ -308,7 +307,6 @@ static mp_obj_t pb_type_imu_heading(size_t n_args, const mp_obj_t *pos_args, mp_
308307
PBIO_IMU_HEADING_TYPE_3D : PBIO_IMU_HEADING_TYPE_1D;
309308

310309
return mp_obj_new_float(pbio_imu_get_heading(type));
311-
;
312310
}
313311
static MP_DEFINE_CONST_FUN_OBJ_KW(pb_type_imu_heading_obj, 1, pb_type_imu_heading);
314312

0 commit comments

Comments
 (0)
Please sign in to comment.