Skip to content

Commit ab73631

Browse files
committed
pybricks.common.IMU: implement up()
1 parent 3520d94 commit ab73631

File tree

1 file changed

+50
-0
lines changed

1 file changed

+50
-0
lines changed

pybricks/common/pb_type_imu.c

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111

1212
#include <pybricks/common.h>
1313
#include <pybricks/geometry.h>
14+
#include <pybricks/parameters.h>
1415

1516
#include <pybricks/util_pb/pb_imu.h>
1617
#include <pybricks/util_pb/pb_error.h>
@@ -76,6 +77,54 @@ STATIC void common_IMU_rotate_3d_axis(common_IMU_obj_t *self, float *values) {
7677
values[2] = self->hub_x[2] * v[0] + self->hub_y[2] * v[1] + self->hub_z[2] * v[2];
7778
}
7879

80+
// pybricks._common.IMU.up
81+
STATIC mp_obj_t common_IMU_up(mp_obj_t self_in) {
82+
common_IMU_obj_t *self = MP_OBJ_TO_PTR(self_in);
83+
84+
// Up is which side of a unit box intersects the +Z vector first.
85+
// So read +Z vector of the inertial frame, in the body frame.
86+
// For now, this is the gravity vector. In the future, we can make this
87+
// slightly more accurate by using the full IMU orientation.
88+
float_t values[3];
89+
pb_imu_accel_read(self->imu_dev, values);
90+
91+
// Find index and sign of maximum component
92+
float_t abs_max = 0;
93+
uint8_t axis = 0;
94+
bool positive = false;
95+
for (uint8_t i = 0; i < 3; i++) {
96+
if (values[i] > abs_max) {
97+
abs_max = values[i];
98+
positive = true;
99+
axis = i;
100+
} else if (-values[i] > abs_max) {
101+
abs_max = -values[i];
102+
positive = false;
103+
axis = i;
104+
}
105+
}
106+
107+
// The maximum component dicates which side of a unix box gets intersected
108+
// first. So, simply look at axis and sign to give the side.
109+
if (axis == 0 && positive) {
110+
return MP_OBJ_FROM_PTR(&pb_Side_FRONT_obj);
111+
}
112+
if (axis == 0 && !positive) {
113+
return MP_OBJ_FROM_PTR(&pb_Side_BACK_obj);
114+
}
115+
if (axis == 1 && positive) {
116+
return MP_OBJ_FROM_PTR(&pb_Side_LEFT_obj);
117+
}
118+
if (axis == 1 && !positive) {
119+
return MP_OBJ_FROM_PTR(&pb_Side_RIGHT_obj);
120+
}
121+
if (axis == 2 && positive) {
122+
return MP_OBJ_FROM_PTR(&pb_Side_TOP_obj);
123+
} else {
124+
return MP_OBJ_FROM_PTR(&pb_Side_BOTTOM_obj);
125+
}
126+
}
127+
MP_DEFINE_CONST_FUN_OBJ_1(common_IMU_up_obj, common_IMU_up);
79128

80129
// pybricks._common.IMU.acceleration
81130
STATIC mp_obj_t common_IMU_acceleration(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) {
@@ -107,6 +156,7 @@ STATIC MP_DEFINE_CONST_FUN_OBJ_KW(common_IMU_angular_velocity_obj, 1, common_IMU
107156

108157
// dir(pybricks.common.IMU)
109158
STATIC const mp_rom_map_elem_t common_IMU_locals_dict_table[] = {
159+
{ MP_ROM_QSTR(MP_QSTR_up), MP_ROM_PTR(&common_IMU_up_obj) },
110160
{ MP_ROM_QSTR(MP_QSTR_acceleration), MP_ROM_PTR(&common_IMU_acceleration_obj) },
111161
{ MP_ROM_QSTR(MP_QSTR_angular_velocity), MP_ROM_PTR(&common_IMU_angular_velocity_obj)},
112162
};

0 commit comments

Comments
 (0)