Skip to content

Commit 1597274

Browse files
committed
pls work encoder
1 parent 9c206d3 commit 1597274

1 file changed

Lines changed: 24 additions & 40 deletions

File tree

pybricks/experimental/pb_module_experimental.c

Lines changed: 24 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -13,60 +13,45 @@
1313
#include <pbio/tacho.h>
1414
#include <pbio/drivebase.h>
1515

16-
#if defined(__ARM_ARCH_7M__) || defined(__ARM_ARCH_7EM__)
17-
#define IS_CORTEX_M 1
18-
#define ACCEL_RAM __attribute__((section(".data"), noinline))
19-
#else
20-
#define IS_CORTEX_M 0
21-
#define ACCEL_RAM
22-
#endif
23-
24-
// Manually defining internal structures to bypass "Unknown Type" errors.
25-
// This matches the memory layout used in Spike and EV3 firmware.
26-
typedef struct _pb_type_Motor_obj_t {
27-
mp_obj_base_t base;
28-
pbio_tacho_t *tacho;
29-
} pb_type_Motor_obj_t;
30-
31-
typedef struct _pb_type_DriveBase_obj_t {
32-
mp_obj_base_t base;
33-
pbio_drivebase_t *db;
34-
} pb_type_DriveBase_obj_t;
16+
// These headers contain the "Getters" we need
17+
#include "pybricks/pupdevices.h"
18+
#include "pybricks/robotics.h"
3519

3620
// -----------------------------------------------------------------------------
37-
// Core Math Engine (MiniMax Polynomial Sine)
21+
// Core Math Engine
3822
// -----------------------------------------------------------------------------
39-
ACCEL_RAM static float fast_sin_internal(float theta) {
40-
float x = theta * 0.159154943f; // INV_TWO_PI
41-
x = theta - (float)((int)(x + (x > 0 ? 0.5f : -0.5f))) * 6.2831853f; // TWO_PI
42-
if (x > 1.5707963f) x = 3.1415926f - x; // HALF_PI, PI
23+
static float fast_sin_internal(float theta) {
24+
float x = theta * 0.159154943f;
25+
x = theta - (float)((int)(x + (x > 0 ? 0.5f : -0.5f))) * 6.2831853f;
26+
if (x > 1.5707963f) x = 3.1415926f - x;
4327
else if (x < -1.5707963f) x = -3.1415926f - x;
4428
float x2 = x * x;
4529
return x * (0.99999906f + x2 * (-0.16665554f + x2 * (0.00831190f + x2 * -0.00018488f)));
4630
}
4731

4832
// -----------------------------------------------------------------------------
49-
// High-Speed Direct-Tacho Odometry
33+
// High-Speed API-Based Odometry
5034
// -----------------------------------------------------------------------------
5135
static mp_obj_t experimental_odometry_benchmark(size_t n_args, const mp_obj_t *args) {
5236
int num_iters = mp_obj_get_int(args[0]);
5337
float wheel_circ = mp_obj_get_float(args[1]);
5438

55-
// Cast raw Python objects to our manual C-struct definitions
56-
pb_type_Motor_obj_t *right_motor = (pb_type_Motor_obj_t *)MP_OBJ_TO_PTR(args[2]);
57-
pb_type_Motor_obj_t *left_motor = (pb_type_Motor_obj_t *)MP_OBJ_TO_PTR(args[3]);
58-
pb_type_DriveBase_obj_t *db_obj = (pb_type_DriveBase_obj_t *)MP_OBJ_TO_PTR(args[4]);
39+
// Use the OFFICIAL Pybricks getters to retrieve the C-pointers.
40+
// This is the "Nuclear" fix: it works regardless of struct padding.
41+
pbio_tacho_t *right_tacho = pb_type_Motor_get_tacho(args[2]);
42+
pbio_tacho_t *left_tacho = pb_type_Motor_get_tacho(args[3]);
43+
pbio_drivebase_t *db = pb_type_drivebase_get_drivebase(args[4]);
5944

6045
float deg_to_mm = wheel_circ / 360.0f;
6146
float robot_x = 0.0f, robot_y = 0.0f;
6247

6348
pbio_angle_t ang_l, ang_r;
6449
int32_t h_mdeg;
6550

66-
// Initial state
67-
pbio_tacho_get_angle(left_motor->tacho, &ang_l);
68-
pbio_tacho_get_angle(right_motor->tacho, &ang_r);
69-
pbio_drivebase_get_state_user(db_obj->db, NULL, NULL, &h_mdeg, NULL);
51+
// Capture initial state
52+
pbio_tacho_get_angle(left_tacho, &ang_l);
53+
pbio_tacho_get_angle(right_tacho, &ang_r);
54+
pbio_drivebase_get_state_user(db, NULL, NULL, &h_mdeg, NULL);
7055

7156
float last_l_mm = ((float)ang_l.rotations * 360.0f + (float)ang_l.millidegrees / 1000.0f) * deg_to_mm;
7257
float last_r_mm = ((float)ang_r.rotations * 360.0f + (float)ang_r.millidegrees / 1000.0f) * deg_to_mm;
@@ -76,10 +61,9 @@ static mp_obj_t experimental_odometry_benchmark(size_t n_args, const mp_obj_t *a
7661
uint32_t start_time = mp_hal_ticks_ms();
7762

7863
for (int i = 0; i < num_iters; i++) {
79-
// Direct Hardware Access
80-
pbio_tacho_get_angle(left_motor->tacho, &ang_l);
81-
pbio_tacho_get_angle(right_motor->tacho, &ang_r);
82-
pbio_drivebase_get_state_user(db_obj->db, NULL, NULL, &h_mdeg, NULL);
64+
pbio_tacho_get_angle(left_tacho, &ang_l);
65+
pbio_tacho_get_angle(right_tacho, &ang_r);
66+
pbio_drivebase_get_state_user(db, NULL, NULL, &h_mdeg, NULL);
8367

8468
float cur_l_mm = ((float)ang_l.rotations * 360.0f + (float)ang_l.millidegrees / 1000.0f) * deg_to_mm;
8569
float cur_r_mm = ((float)ang_r.rotations * 360.0f + (float)ang_r.millidegrees / 1000.0f) * deg_to_mm;
@@ -91,14 +75,14 @@ static mp_obj_t experimental_odometry_benchmark(size_t n_args, const mp_obj_t *a
9175

9276
if (fabsf(linear_delta) > 0.0001f) {
9377
float avg_h_rad = (last_heading + (heading_delta / 2.0f)) * 0.01745329f;
94-
robot_x += linear_delta * fast_sin_internal(avg_h_rad + 1.5707963f); // cos
95-
robot_y += linear_delta * fast_sin_internal(avg_h_rad); // sin
78+
robot_x += linear_delta * fast_sin_internal(avg_h_rad + 1.5707963f);
79+
robot_y += linear_delta * fast_sin_internal(avg_h_rad);
9680
}
9781

9882
last_lin = cur_lin;
9983
last_heading = cur_heading;
10084

101-
// Yield to hub system every 2000 loops
85+
// Yield for stability
10286
if ((i % 2000) == 0) {
10387
mp_handle_pending(true);
10488
mp_hal_delay_ms(1);

0 commit comments

Comments
 (0)