Skip to content

Commit 9e39566

Browse files
committed
pls work encoder
1 parent 288c8c4 commit 9e39566

1 file changed

Lines changed: 25 additions & 27 deletions

File tree

pybricks/experimental/pb_module_experimental.c

Lines changed: 25 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -31,53 +31,51 @@ ACCEL_RAM static float fast_sin_internal(float theta) {
3131
}
3232

3333
// -----------------------------------------------------------------------------
34-
// High-Speed API Odometry
34+
// High-Speed API Odometry (Pure Encoders, No Gyro)
3535
// -----------------------------------------------------------------------------
3636
static mp_obj_t experimental_odometry_benchmark(size_t n_args, const mp_obj_t *args) {
3737
int num_iters = mp_obj_get_int(args[0]);
3838
float wheel_circ = mp_obj_get_float(args[1]);
39+
float axle_track = mp_obj_get_float(args[2]); // Added so we can do wheel math
3940

40-
// THE CORRECT WAY: Receive the bound MicroPython methods (e.g. motor.angle)
41-
mp_obj_t right_angle_func = args[2];
42-
mp_obj_t left_angle_func = args[3];
43-
mp_obj_t db_heading_func = args[4];
41+
// Receive the bound MicroPython methods for the motors
42+
mp_obj_t right_angle_func = args[3];
43+
mp_obj_t left_angle_func = args[4];
4444

4545
float deg_to_mm = wheel_circ / 360.0f;
4646
float robot_x = 0.0f, robot_y = 0.0f;
47+
float current_heading_rad = 0.0f;
4748

48-
// Call the functions safely via the MicroPython VM dispatcher to get initial state
49+
// motor.angle() safely returns an integer
4950
int32_t last_r_deg = mp_obj_get_int(mp_call_function_0(right_angle_func));
5051
int32_t last_l_deg = mp_obj_get_int(mp_call_function_0(left_angle_func));
51-
int32_t last_heading_deg = mp_obj_get_int(mp_call_function_0(db_heading_func));
52-
53-
float last_r_mm = (float)last_r_deg * deg_to_mm;
54-
float last_l_mm = (float)last_l_deg * deg_to_mm;
55-
float last_lin = (last_l_mm + last_r_mm) / 2.0f;
5652

5753
uint32_t start_time = mp_hal_ticks_ms();
5854

5955
for (int i = 0; i < num_iters; i++) {
60-
// Execute the hardware read securely.
61-
// This resolves to the internal Pybricks C-function automatically.
6256
int32_t cur_r_deg = mp_obj_get_int(mp_call_function_0(right_angle_func));
6357
int32_t cur_l_deg = mp_obj_get_int(mp_call_function_0(left_angle_func));
64-
int32_t cur_heading_deg = mp_obj_get_int(mp_call_function_0(db_heading_func));
65-
66-
float cur_r_mm = (float)cur_r_deg * deg_to_mm;
67-
float cur_l_mm = (float)cur_l_deg * deg_to_mm;
68-
float cur_lin = (cur_l_mm + cur_r_mm) / 2.0f;
69-
70-
float linear_delta = cur_lin - last_lin;
71-
float heading_delta = (float)(cur_heading_deg - last_heading_deg);
7258

73-
if (fabsf(linear_delta) > 0.0001f) {
74-
float avg_h_rad = ((float)last_heading_deg + (heading_delta / 2.0f)) * 0.01745329f;
75-
robot_x += linear_delta * fast_sin_internal(avg_h_rad + 1.5707963f);
76-
robot_y += linear_delta * fast_sin_internal(avg_h_rad);
59+
// Calculate distance traveled by each wheel in this specific loop step
60+
float delta_r_mm = (float)(cur_r_deg - last_r_deg) * deg_to_mm;
61+
float delta_l_mm = (float)(cur_l_deg - last_l_deg) * deg_to_mm;
62+
63+
// Kinematics: Center distance and heading change
64+
float linear_delta = (delta_r_mm + delta_l_mm) / 2.0f;
65+
float heading_delta_rad = (delta_r_mm - delta_l_mm) / axle_track;
66+
67+
if (fabsf(linear_delta) > 0.0001f || fabsf(heading_delta_rad) > 0.0001f) {
68+
// Arc integration: use the average heading during the movement step
69+
float avg_h_rad = current_heading_rad + (heading_delta_rad / 2.0f);
70+
71+
robot_x += linear_delta * fast_sin_internal(avg_h_rad + 1.5707963f); // cos
72+
robot_y += linear_delta * fast_sin_internal(avg_h_rad); // sin
73+
74+
current_heading_rad += heading_delta_rad;
7775
}
7876

79-
last_lin = cur_lin;
80-
last_heading_deg = cur_heading_deg;
77+
last_r_deg = cur_r_deg;
78+
last_l_deg = cur_l_deg;
8179

8280
// Yield for system stability
8381
if ((i % 2000) == 0) {

0 commit comments

Comments
 (0)