|
11 | 11 |
|
12 | 12 | #include <pybricks/common.h> |
13 | 13 | #include <pybricks/geometry.h> |
| 14 | +#include <pybricks/parameters.h> |
14 | 15 |
|
15 | 16 | #include <pybricks/util_pb/pb_imu.h> |
16 | 17 | #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) { |
76 | 77 | values[2] = self->hub_x[2] * v[0] + self->hub_y[2] * v[1] + self->hub_z[2] * v[2]; |
77 | 78 | } |
78 | 79 |
|
| 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); |
79 | 128 |
|
80 | 129 | // pybricks._common.IMU.acceleration |
81 | 130 | 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 |
107 | 156 |
|
108 | 157 | // dir(pybricks.common.IMU) |
109 | 158 | 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) }, |
110 | 160 | { MP_ROM_QSTR(MP_QSTR_acceleration), MP_ROM_PTR(&common_IMU_acceleration_obj) }, |
111 | 161 | { MP_ROM_QSTR(MP_QSTR_angular_velocity), MP_ROM_PTR(&common_IMU_angular_velocity_obj)}, |
112 | 162 | }; |
|
0 commit comments