openbricks 2.6.0__tar.gz → 2.6.2__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {openbricks-2.6.0 → openbricks-2.6.2}/CHANGELOG.md +33 -0
- {openbricks-2.6.0/openbricks.egg-info → openbricks-2.6.2}/PKG-INFO +1 -1
- {openbricks-2.6.0 → openbricks-2.6.2}/native/_shared/drivebase_core.c +45 -6
- {openbricks-2.6.0 → openbricks-2.6.2}/native/_shared/drivebase_core.h +21 -2
- {openbricks-2.6.0 → openbricks-2.6.2}/native/openbricks_sim_native.c +4 -3
- {openbricks-2.6.0 → openbricks-2.6.2/openbricks.egg-info}/PKG-INFO +1 -1
- {openbricks-2.6.0 → openbricks-2.6.2}/openbricks_dev/__init__.py +1 -1
- {openbricks-2.6.0 → openbricks-2.6.2}/MANIFEST.in +0 -0
- {openbricks-2.6.0 → openbricks-2.6.2}/README.md +0 -0
- {openbricks-2.6.0 → openbricks-2.6.2}/examples/color_drive.py +0 -0
- {openbricks-2.6.0 → openbricks-2.6.2}/examples/repeat_mission.py +0 -0
- {openbricks-2.6.0 → openbricks-2.6.2}/examples/scored_mission.py +0 -0
- {openbricks-2.6.0 → openbricks-2.6.2}/examples/unified_chassis_dims.py +0 -0
- {openbricks-2.6.0 → openbricks-2.6.2}/examples/wall_avoid.py +0 -0
- {openbricks-2.6.0 → openbricks-2.6.2}/examples/wander.py +0 -0
- {openbricks-2.6.0 → openbricks-2.6.2}/examples/wander_hardware_style.py +0 -0
- {openbricks-2.6.0 → openbricks-2.6.2}/examples/wander_with_gyro.py +0 -0
- {openbricks-2.6.0 → openbricks-2.6.2}/examples/wro_elementary_walkthrough.py +0 -0
- {openbricks-2.6.0 → openbricks-2.6.2}/native/_shared/motor_process_core.c +0 -0
- {openbricks-2.6.0 → openbricks-2.6.2}/native/_shared/motor_process_core.h +0 -0
- {openbricks-2.6.0 → openbricks-2.6.2}/native/_shared/observer_core.c +0 -0
- {openbricks-2.6.0 → openbricks-2.6.2}/native/_shared/observer_core.h +0 -0
- {openbricks-2.6.0 → openbricks-2.6.2}/native/_shared/servo_core.c +0 -0
- {openbricks-2.6.0 → openbricks-2.6.2}/native/_shared/servo_core.h +0 -0
- {openbricks-2.6.0 → openbricks-2.6.2}/native/_shared/st_move_core.c +0 -0
- {openbricks-2.6.0 → openbricks-2.6.2}/native/_shared/st_move_core.h +0 -0
- {openbricks-2.6.0 → openbricks-2.6.2}/native/_shared/trajectory_core.c +0 -0
- {openbricks-2.6.0 → openbricks-2.6.2}/native/_shared/trajectory_core.h +0 -0
- {openbricks-2.6.0 → openbricks-2.6.2}/openbricks.egg-info/SOURCES.txt +0 -0
- {openbricks-2.6.0 → openbricks-2.6.2}/openbricks.egg-info/dependency_links.txt +0 -0
- {openbricks-2.6.0 → openbricks-2.6.2}/openbricks.egg-info/entry_points.txt +0 -0
- {openbricks-2.6.0 → openbricks-2.6.2}/openbricks.egg-info/requires.txt +0 -0
- {openbricks-2.6.0 → openbricks-2.6.2}/openbricks.egg-info/top_level.txt +0 -0
- {openbricks-2.6.0 → openbricks-2.6.2}/openbricks_dev/__main__.py +0 -0
- {openbricks-2.6.0 → openbricks-2.6.2}/openbricks_dev/_docs/offline-docs.zip +0 -0
- {openbricks-2.6.0 → openbricks-2.6.2}/openbricks_dev/_nus.py +0 -0
- {openbricks-2.6.0 → openbricks-2.6.2}/openbricks_dev/_ports.py +0 -0
- {openbricks-2.6.0 → openbricks-2.6.2}/openbricks_dev/_signing.py +0 -0
- {openbricks-2.6.0 → openbricks-2.6.2}/openbricks_dev/cli.py +0 -0
- {openbricks-2.6.0 → openbricks-2.6.2}/openbricks_dev/docs.py +0 -0
- {openbricks-2.6.0 → openbricks-2.6.2}/openbricks_dev/flash.py +0 -0
- {openbricks-2.6.0 → openbricks-2.6.2}/openbricks_dev/log.py +0 -0
- {openbricks-2.6.0 → openbricks-2.6.2}/openbricks_dev/mpycompile.py +0 -0
- {openbricks-2.6.0 → openbricks-2.6.2}/openbricks_dev/pasteprobe.py +0 -0
- {openbricks-2.6.0 → openbricks-2.6.2}/openbricks_dev/run.py +0 -0
- {openbricks-2.6.0 → openbricks-2.6.2}/openbricks_dev/scan.py +0 -0
- {openbricks-2.6.0 → openbricks-2.6.2}/openbricks_dev/servo_id.py +0 -0
- {openbricks-2.6.0 → openbricks-2.6.2}/openbricks_dev/stop.py +0 -0
- {openbricks-2.6.0 → openbricks-2.6.2}/openbricks_dev/upload.py +0 -0
- {openbricks-2.6.0 → openbricks-2.6.2}/openbricks_sim/__init__.py +0 -0
- {openbricks-2.6.0 → openbricks-2.6.2}/openbricks_sim/__main__.py +0 -0
- {openbricks-2.6.0 → openbricks-2.6.2}/openbricks_sim/chassis.py +0 -0
- {openbricks-2.6.0 → openbricks-2.6.2}/openbricks_sim/cli.py +0 -0
- {openbricks-2.6.0 → openbricks-2.6.2}/openbricks_sim/lego_mjcf.py +0 -0
- {openbricks-2.6.0 → openbricks-2.6.2}/openbricks_sim/randomization.py +0 -0
- {openbricks-2.6.0 → openbricks-2.6.2}/openbricks_sim/robot.py +0 -0
- {openbricks-2.6.0 → openbricks-2.6.2}/openbricks_sim/runtime.py +0 -0
- {openbricks-2.6.0 → openbricks-2.6.2}/openbricks_sim/shim.py +0 -0
- {openbricks-2.6.0 → openbricks-2.6.2}/openbricks_sim/world.py +0 -0
- {openbricks-2.6.0 → openbricks-2.6.2}/openbricks_sim/worlds/practice_line/world.xml +0 -0
- {openbricks-2.6.0 → openbricks-2.6.2}/openbricks_sim/worlds/practice_walls/README.md +0 -0
- {openbricks-2.6.0 → openbricks-2.6.2}/openbricks_sim/worlds/practice_walls/world.xml +0 -0
- {openbricks-2.6.0 → openbricks-2.6.2}/openbricks_sim/worlds/practice_zones/README.md +0 -0
- {openbricks-2.6.0 → openbricks-2.6.2}/openbricks_sim/worlds/practice_zones/world.xml +0 -0
- {openbricks-2.6.0 → openbricks-2.6.2}/openbricks_sim/worlds/wro_2026_elementary_robot_rockstars/README.md +0 -0
- {openbricks-2.6.0 → openbricks-2.6.2}/openbricks_sim/worlds/wro_2026_elementary_robot_rockstars/mat.png +0 -0
- {openbricks-2.6.0 → openbricks-2.6.2}/openbricks_sim/worlds/wro_2026_elementary_robot_rockstars/props/amplifier.ldr +0 -0
- {openbricks-2.6.0 → openbricks-2.6.2}/openbricks_sim/worlds/wro_2026_elementary_robot_rockstars/props/cable.ldr +0 -0
- {openbricks-2.6.0 → openbricks-2.6.2}/openbricks_sim/worlds/wro_2026_elementary_robot_rockstars/props/clef.ldr +0 -0
- {openbricks-2.6.0 → openbricks-2.6.2}/openbricks_sim/worlds/wro_2026_elementary_robot_rockstars/props/congas.ldr +0 -0
- {openbricks-2.6.0 → openbricks-2.6.2}/openbricks_sim/worlds/wro_2026_elementary_robot_rockstars/props/guitar.ldr +0 -0
- {openbricks-2.6.0 → openbricks-2.6.2}/openbricks_sim/worlds/wro_2026_elementary_robot_rockstars/props/keyboard.ldr +0 -0
- {openbricks-2.6.0 → openbricks-2.6.2}/openbricks_sim/worlds/wro_2026_elementary_robot_rockstars/props/microphone.ldr +0 -0
- {openbricks-2.6.0 → openbricks-2.6.2}/openbricks_sim/worlds/wro_2026_elementary_robot_rockstars/props/note_black.ldr +0 -0
- {openbricks-2.6.0 → openbricks-2.6.2}/openbricks_sim/worlds/wro_2026_elementary_robot_rockstars/props/note_blue.ldr +0 -0
- {openbricks-2.6.0 → openbricks-2.6.2}/openbricks_sim/worlds/wro_2026_elementary_robot_rockstars/props/note_green.ldr +0 -0
- {openbricks-2.6.0 → openbricks-2.6.2}/openbricks_sim/worlds/wro_2026_elementary_robot_rockstars/props/note_red.ldr +0 -0
- {openbricks-2.6.0 → openbricks-2.6.2}/openbricks_sim/worlds/wro_2026_elementary_robot_rockstars/props/note_white.ldr +0 -0
- {openbricks-2.6.0 → openbricks-2.6.2}/openbricks_sim/worlds/wro_2026_elementary_robot_rockstars/props/note_yellow.ldr +0 -0
- {openbricks-2.6.0 → openbricks-2.6.2}/openbricks_sim/worlds/wro_2026_elementary_robot_rockstars/props/speaker.ldr +0 -0
- {openbricks-2.6.0 → openbricks-2.6.2}/openbricks_sim/worlds/wro_2026_elementary_robot_rockstars/world.xml +0 -0
- {openbricks-2.6.0 → openbricks-2.6.2}/openbricks_sim/worlds/wro_2026_junior_heritage_heroes/README.md +0 -0
- {openbricks-2.6.0 → openbricks-2.6.2}/openbricks_sim/worlds/wro_2026_junior_heritage_heroes/mat.png +0 -0
- {openbricks-2.6.0 → openbricks-2.6.2}/openbricks_sim/worlds/wro_2026_junior_heritage_heroes/props/artefact.ldr +0 -0
- {openbricks-2.6.0 → openbricks-2.6.2}/openbricks_sim/worlds/wro_2026_junior_heritage_heroes/props/barrier.ldr +0 -0
- {openbricks-2.6.0 → openbricks-2.6.2}/openbricks_sim/worlds/wro_2026_junior_heritage_heroes/props/dirt.ldr +0 -0
- {openbricks-2.6.0 → openbricks-2.6.2}/openbricks_sim/worlds/wro_2026_junior_heritage_heroes/props/parrot.ldr +0 -0
- {openbricks-2.6.0 → openbricks-2.6.2}/openbricks_sim/worlds/wro_2026_junior_heritage_heroes/props/red_tower.ldr +0 -0
- {openbricks-2.6.0 → openbricks-2.6.2}/openbricks_sim/worlds/wro_2026_junior_heritage_heroes/props/visitor.ldr +0 -0
- {openbricks-2.6.0 → openbricks-2.6.2}/openbricks_sim/worlds/wro_2026_junior_heritage_heroes/props/yellow_tower.ldr +0 -0
- {openbricks-2.6.0 → openbricks-2.6.2}/openbricks_sim/worlds/wro_2026_junior_heritage_heroes/world.xml +0 -0
- {openbricks-2.6.0 → openbricks-2.6.2}/openbricks_sim/worlds/wro_2026_senior_mosaic_masters/README.md +0 -0
- {openbricks-2.6.0 → openbricks-2.6.2}/openbricks_sim/worlds/wro_2026_senior_mosaic_masters/mat.png +0 -0
- {openbricks-2.6.0 → openbricks-2.6.2}/openbricks_sim/worlds/wro_2026_senior_mosaic_masters/mosaic_frame.stl +0 -0
- {openbricks-2.6.0 → openbricks-2.6.2}/openbricks_sim/worlds/wro_2026_senior_mosaic_masters/props/cement_bowl.ldr +0 -0
- {openbricks-2.6.0 → openbricks-2.6.2}/openbricks_sim/worlds/wro_2026_senior_mosaic_masters/props/cement_element.ldr +0 -0
- {openbricks-2.6.0 → openbricks-2.6.2}/openbricks_sim/worlds/wro_2026_senior_mosaic_masters/props/masonry_trowel.ldr +0 -0
- {openbricks-2.6.0 → openbricks-2.6.2}/openbricks_sim/worlds/wro_2026_senior_mosaic_masters/props/mosaic_tile.ldr +0 -0
- {openbricks-2.6.0 → openbricks-2.6.2}/openbricks_sim/worlds/wro_2026_senior_mosaic_masters/props/rect_trowel.ldr +0 -0
- {openbricks-2.6.0 → openbricks-2.6.2}/openbricks_sim/worlds/wro_2026_senior_mosaic_masters/props/senior_barrier_black_red.ldr +0 -0
- {openbricks-2.6.0 → openbricks-2.6.2}/openbricks_sim/worlds/wro_2026_senior_mosaic_masters/props/senior_barrier_red_blue.ldr +0 -0
- {openbricks-2.6.0 → openbricks-2.6.2}/openbricks_sim/worlds/wro_2026_senior_mosaic_masters/world.xml +0 -0
- {openbricks-2.6.0 → openbricks-2.6.2}/pyproject.toml +0 -0
- {openbricks-2.6.0 → openbricks-2.6.2}/setup.cfg +0 -0
- {openbricks-2.6.0 → openbricks-2.6.2}/setup.py +0 -0
- {openbricks-2.6.0 → openbricks-2.6.2}/tests/test_chassis.py +0 -0
- {openbricks-2.6.0 → openbricks-2.6.2}/tests/test_cibuildwheel_config.py +0 -0
- {openbricks-2.6.0 → openbricks-2.6.2}/tests/test_cli.py +0 -0
- {openbricks-2.6.0 → openbricks-2.6.2}/tests/test_color_sensor.py +0 -0
- {openbricks-2.6.0 → openbricks-2.6.2}/tests/test_distance_sensor.py +0 -0
- {openbricks-2.6.0 → openbricks-2.6.2}/tests/test_docs_cli.py +0 -0
- {openbricks-2.6.0 → openbricks-2.6.2}/tests/test_flash.py +0 -0
- {openbricks-2.6.0 → openbricks-2.6.2}/tests/test_imu.py +0 -0
- {openbricks-2.6.0 → openbricks-2.6.2}/tests/test_lego_mjcf.py +0 -0
- {openbricks-2.6.0 → openbricks-2.6.2}/tests/test_line_follow_sim.py +0 -0
- {openbricks-2.6.0 → openbricks-2.6.2}/tests/test_log.py +0 -0
- {openbricks-2.6.0 → openbricks-2.6.2}/tests/test_mpycompile.py +0 -0
- {openbricks-2.6.0 → openbricks-2.6.2}/tests/test_native_drivebase.py +0 -0
- {openbricks-2.6.0 → openbricks-2.6.2}/tests/test_native_motor_process.py +0 -0
- {openbricks-2.6.0 → openbricks-2.6.2}/tests/test_native_observer.py +0 -0
- {openbricks-2.6.0 → openbricks-2.6.2}/tests/test_native_servo.py +0 -0
- {openbricks-2.6.0 → openbricks-2.6.2}/tests/test_native_trajectory.py +0 -0
- {openbricks-2.6.0 → openbricks-2.6.2}/tests/test_no_stale_names.py +0 -0
- {openbricks-2.6.0 → openbricks-2.6.2}/tests/test_nus.py +0 -0
- {openbricks-2.6.0 → openbricks-2.6.2}/tests/test_pasteprobe.py +0 -0
- {openbricks-2.6.0 → openbricks-2.6.2}/tests/test_project_urls.py +0 -0
- {openbricks-2.6.0 → openbricks-2.6.2}/tests/test_randomization.py +0 -0
- {openbricks-2.6.0 → openbricks-2.6.2}/tests/test_release_tags.py +0 -0
- {openbricks-2.6.0 → openbricks-2.6.2}/tests/test_robot.py +0 -0
- {openbricks-2.6.0 → openbricks-2.6.2}/tests/test_run.py +0 -0
- {openbricks-2.6.0 → openbricks-2.6.2}/tests/test_runtime.py +0 -0
- {openbricks-2.6.0 → openbricks-2.6.2}/tests/test_scan.py +0 -0
- {openbricks-2.6.0 → openbricks-2.6.2}/tests/test_sdist_build.py +0 -0
- {openbricks-2.6.0 → openbricks-2.6.2}/tests/test_servo_id.py +0 -0
- {openbricks-2.6.0 → openbricks-2.6.2}/tests/test_shim.py +0 -0
- {openbricks-2.6.0 → openbricks-2.6.2}/tests/test_signing.py +0 -0
- {openbricks-2.6.0 → openbricks-2.6.2}/tests/test_sim_cli.py +0 -0
- {openbricks-2.6.0 → openbricks-2.6.2}/tests/test_stop.py +0 -0
- {openbricks-2.6.0 → openbricks-2.6.2}/tests/test_upload.py +0 -0
- {openbricks-2.6.0 → openbricks-2.6.2}/tests/test_wheel_bundles_worlds.py +0 -0
- {openbricks-2.6.0 → openbricks-2.6.2}/tests/test_world.py +0 -0
|
@@ -3,6 +3,39 @@
|
|
|
3
3
|
Versions the unified `openbricks` PyPI package (CLI + MuJoCo sim).
|
|
4
4
|
Firmware versions are tracked separately on the `v*` tag namespace.
|
|
5
5
|
|
|
6
|
+
## 2.6.2 — done requires standstill; per-axis settle diagnostics
|
|
7
|
+
|
|
8
|
+
Bench (the twitch that survived 2.6.0, now measured): the final
|
|
9
|
+
curve expired with a 94-wheel-deg tracking deficit; the robot
|
|
10
|
+
stalled short, the landing walked it in — and done latched the
|
|
11
|
+
moment POSITION was close, while the landing reference still
|
|
12
|
+
carried speed, so the automatic then="coast" dispatch released the
|
|
13
|
+
wheels mid-motion: stop, lurch, abrupt stop. Two fixes:
|
|
14
|
+
|
|
15
|
+
* **pbio's standstill rule**: done additionally requires the
|
|
16
|
+
correction reference to be slow (<60 dps) — the missing half of
|
|
17
|
+
their on-target condition. Wheels are never released at speed.
|
|
18
|
+
* **Diagnostics**: `db_settle_stats()` now reports per-axis —
|
|
19
|
+
(res_sum, res_diff, landings, integ_sum_dps, integ_diff_dps) at
|
|
20
|
+
profile expiry — and the landing count survives the stop dispatch
|
|
21
|
+
(2.6.1 kept the residual but wiped the count). The next bench
|
|
22
|
+
read says WHICH axis lags and what the integral was supplying.
|
|
23
|
+
|
|
24
|
+
The 94-wheel-deg deficit itself (why the integral didn't absorb it
|
|
25
|
+
during the approach) is the open root cause the new numbers will
|
|
26
|
+
pin down. Both sides move: flash 2.6.2 AND `pipx upgrade
|
|
27
|
+
openbricks`.
|
|
28
|
+
|
|
29
|
+
## 2.6.1 — settle stats survive the stop dispatch
|
|
30
|
+
|
|
31
|
+
`db_settle_stats()` read (0.0, 0) on every standard-path move:
|
|
32
|
+
`done()` dispatches `stop()` before the user's move call returns,
|
|
33
|
+
and the stop wiped the diagnostics with the rest of the move state
|
|
34
|
+
— the instrument destroyed its own evidence (bench 2026-08-17,
|
|
35
|
+
while chasing the end-of-run twitch). Expiry residual + landing
|
|
36
|
+
count now reset only when the NEXT move arms; integrals and the
|
|
37
|
+
landing budget still die with the move. Firmware-side: flash 2.6.1.
|
|
38
|
+
|
|
6
39
|
## 2.6.0 — PID + landing settle: no more end-of-move jerk
|
|
7
40
|
|
|
8
41
|
Bench report: at the end of a mission the robot stopped, abruptly
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: openbricks
|
|
3
|
-
Version: 2.6.
|
|
3
|
+
Version: 2.6.2
|
|
4
4
|
Summary: openbricks — host-side CLI + MuJoCo-backed simulator for the openbricks MicroPython firmware. Flash, list, run, upload, log; ``openbricks sim`` for the physics simulator.
|
|
5
5
|
Author: openbricks contributors
|
|
6
6
|
License: MIT
|
|
@@ -61,6 +61,10 @@ void ob_drivebase_init(ob_drivebase_t *db,
|
|
|
61
61
|
db->landing_active = false;
|
|
62
62
|
db->landing_best_err = 0.0;
|
|
63
63
|
db->expiry_residual = 0.0;
|
|
64
|
+
db->expiry_res_sum = 0.0;
|
|
65
|
+
db->expiry_res_diff = 0.0;
|
|
66
|
+
db->expiry_integ_sum_dps = 0.0;
|
|
67
|
+
db->expiry_integ_diff_dps = 0.0;
|
|
64
68
|
db->expiry_captured = false;
|
|
65
69
|
}
|
|
66
70
|
|
|
@@ -76,6 +80,10 @@ static void db_move_state_reset(ob_drivebase_t *db) {
|
|
|
76
80
|
db->landing_active = false;
|
|
77
81
|
db->landing_best_err = 0.0;
|
|
78
82
|
db->expiry_residual = 0.0;
|
|
83
|
+
db->expiry_res_sum = 0.0;
|
|
84
|
+
db->expiry_res_diff = 0.0;
|
|
85
|
+
db->expiry_integ_sum_dps = 0.0;
|
|
86
|
+
db->expiry_integ_diff_dps = 0.0;
|
|
79
87
|
db->expiry_captured = false;
|
|
80
88
|
}
|
|
81
89
|
|
|
@@ -355,7 +363,20 @@ void ob_drivebase_stop(ob_drivebase_t *db) {
|
|
|
355
363
|
db->turn_active = false;
|
|
356
364
|
db->done = true;
|
|
357
365
|
db->settling = false;
|
|
358
|
-
|
|
366
|
+
// Integrals and the landing budget die with the move — but NOT
|
|
367
|
+
// the settle diagnostics: done() dispatches stop() before the
|
|
368
|
+
// user's move call even returns, so wiping expiry stats here
|
|
369
|
+
// made db_settle_stats() read (0.0, 0) on every standard-path
|
|
370
|
+
// move (bench 2026-08-17 — the diagnostic destroyed its own
|
|
371
|
+
// evidence). Stats reset only when the NEXT move arms.
|
|
372
|
+
db->integ_sum = 0.0;
|
|
373
|
+
db->integ_diff = 0.0;
|
|
374
|
+
db->landing_active = false;
|
|
375
|
+
db->landing_best_err = 0.0;
|
|
376
|
+
// db->landings is DIAGNOSTIC state alongside expiry_residual —
|
|
377
|
+
// it survives the stop dispatch (bench read (94.4, 0): the
|
|
378
|
+
// landing count wiped while the residual survived) and resets
|
|
379
|
+
// at the next arm.
|
|
359
380
|
}
|
|
360
381
|
|
|
361
382
|
|
|
@@ -510,8 +531,16 @@ void ob_drivebase_tick(ob_drivebase_t *db, long now_ms) {
|
|
|
510
531
|
ob_float_t de_now = db->turn_hold - diff_pos;
|
|
511
532
|
se_now = (se_now < 0) ? -se_now : se_now;
|
|
512
533
|
de_now = (de_now < 0) ? -de_now : de_now;
|
|
534
|
+
// ...and pbio's STANDSTILL condition: the landing's own
|
|
535
|
+
// feed-forward must be slow before done may latch, or a
|
|
536
|
+
// plant crossing the window at speed gets its wheels
|
|
537
|
+
// released mid-motion by the then= dispatch.
|
|
538
|
+
ob_float_t vf = (fwd_ff_vel < 0) ? -fwd_ff_vel : fwd_ff_vel;
|
|
539
|
+
ob_float_t vt = (turn_ff_vel < 0) ? -turn_ff_vel : turn_ff_vel;
|
|
513
540
|
if (se_now < (ob_float_t)OB_DRIVEBASE_DONE_TOL_WHEEL_DEG
|
|
514
|
-
&& de_now < (ob_float_t)OB_DRIVEBASE_DONE_TOL_WHEEL_DEG
|
|
541
|
+
&& de_now < (ob_float_t)OB_DRIVEBASE_DONE_TOL_WHEEL_DEG
|
|
542
|
+
&& vf < (ob_float_t)OB_DRIVEBASE_ARRIVAL_SPEED_TOL_DPS
|
|
543
|
+
&& vt < (ob_float_t)OB_DRIVEBASE_ARRIVAL_SPEED_TOL_DPS) {
|
|
515
544
|
db->fwd_active = false;
|
|
516
545
|
db->turn_active = false;
|
|
517
546
|
db->landing_active = false;
|
|
@@ -573,6 +602,10 @@ void ob_drivebase_tick(ob_drivebase_t *db, long now_ms) {
|
|
|
573
602
|
if (!db->expiry_captured) {
|
|
574
603
|
db->expiry_captured = true;
|
|
575
604
|
db->expiry_residual = worst;
|
|
605
|
+
db->expiry_res_sum = se;
|
|
606
|
+
db->expiry_res_diff = de;
|
|
607
|
+
db->expiry_integ_sum_dps = db->ki * db->integ_sum;
|
|
608
|
+
db->expiry_integ_diff_dps = db->ki * db->integ_diff;
|
|
576
609
|
}
|
|
577
610
|
// Landing settle (2.6.0): residual above arrival
|
|
578
611
|
// tolerance gets a SHAPED mini-trajectory back to the
|
|
@@ -741,8 +774,14 @@ void ob_drivebase_gyro_frame_reset(ob_drivebase_t *db) {
|
|
|
741
774
|
// took. The bench reads this to decide whether the integral gains
|
|
742
775
|
// need another look — measured numbers, not guesses.
|
|
743
776
|
void ob_drivebase_settle_stats(const ob_drivebase_t *db,
|
|
744
|
-
ob_float_t *
|
|
745
|
-
|
|
746
|
-
|
|
747
|
-
|
|
777
|
+
ob_float_t *res_sum,
|
|
778
|
+
ob_float_t *res_diff,
|
|
779
|
+
int *landings,
|
|
780
|
+
ob_float_t *integ_sum_dps,
|
|
781
|
+
ob_float_t *integ_diff_dps) {
|
|
782
|
+
*res_sum = db->expiry_res_sum;
|
|
783
|
+
*res_diff = db->expiry_res_diff;
|
|
784
|
+
*landings = (int)db->landings;
|
|
785
|
+
*integ_sum_dps = db->expiry_integ_sum_dps;
|
|
786
|
+
*integ_diff_dps = db->expiry_integ_diff_dps;
|
|
748
787
|
}
|
|
@@ -92,6 +92,14 @@
|
|
|
92
92
|
// machinery is the backstop for a genuinely stuck robot.
|
|
93
93
|
#define OB_DRIVEBASE_LANDING_DPS 120.0
|
|
94
94
|
#define OB_DRIVEBASE_MAX_LANDINGS 3
|
|
95
|
+
// Arrival additionally requires the reference to be SLOW — pbio's
|
|
96
|
+
// standstill condition for zero-end-speed maneuvers. Without it, a
|
|
97
|
+
// plant that crosses the position window mid-landing (still
|
|
98
|
+
// carrying the landing ramp's speed) latched done at speed, and
|
|
99
|
+
// the automatic then="coast" dispatch released the wheels while
|
|
100
|
+
// they were turning: stop, lurch, abrupt stop (bench 2026-08-17,
|
|
101
|
+
// the twitch that survived 2.6.0).
|
|
102
|
+
#define OB_DRIVEBASE_ARRIVAL_SPEED_TOL_DPS 60.0
|
|
95
103
|
|
|
96
104
|
|
|
97
105
|
typedef struct {
|
|
@@ -164,6 +172,14 @@ typedef struct {
|
|
|
164
172
|
bool landing_active; // a landing profile is in flight
|
|
165
173
|
ob_float_t landing_best_err; // best worst-axis err seen at a gate
|
|
166
174
|
ob_float_t expiry_residual;
|
|
175
|
+
// Per-axis diagnostics at the same capture point: which axis
|
|
176
|
+
// carries the lag, and how much the integral was supplying (in
|
|
177
|
+
// dps) when the profile expired — the numbers that say whether
|
|
178
|
+
// the integral did its job during the approach.
|
|
179
|
+
ob_float_t expiry_res_sum;
|
|
180
|
+
ob_float_t expiry_res_diff;
|
|
181
|
+
ob_float_t expiry_integ_sum_dps;
|
|
182
|
+
ob_float_t expiry_integ_diff_dps;
|
|
167
183
|
bool expiry_captured;
|
|
168
184
|
} ob_drivebase_t;
|
|
169
185
|
|
|
@@ -255,8 +271,11 @@ ob_float_t ob_drivebase_body_to_wheel_diff(const ob_drivebase_t *db,
|
|
|
255
271
|
// Settle diagnostics: residual at the last move's first profile
|
|
256
272
|
// expiry (wheel-deg, worst axis) and shaped-landing count.
|
|
257
273
|
void ob_drivebase_settle_stats(const ob_drivebase_t *db,
|
|
258
|
-
ob_float_t *
|
|
259
|
-
|
|
274
|
+
ob_float_t *res_sum,
|
|
275
|
+
ob_float_t *res_diff,
|
|
276
|
+
int *landings,
|
|
277
|
+
ob_float_t *integ_sum_dps,
|
|
278
|
+
ob_float_t *integ_diff_dps);
|
|
260
279
|
|
|
261
280
|
|
|
262
281
|
// Reset the gyro-mode absolute frame (turn_hold + override slot).
|
|
@@ -819,10 +819,11 @@ static PyObject *RawDriveBase_curve(RawDriveBaseObject *self,
|
|
|
819
819
|
|
|
820
820
|
static PyObject *RawDriveBase_settle_stats(RawDriveBaseObject *self,
|
|
821
821
|
PyObject *Py_UNUSED(ignored)) {
|
|
822
|
-
ob_float_t
|
|
822
|
+
ob_float_t rs, rd, is_, id_;
|
|
823
823
|
int n;
|
|
824
|
-
ob_drivebase_settle_stats(&self->core, &
|
|
825
|
-
return Py_BuildValue("
|
|
824
|
+
ob_drivebase_settle_stats(&self->core, &rs, &rd, &n, &is_, &id_);
|
|
825
|
+
return Py_BuildValue("ddidd", (double)rs, (double)rd, n,
|
|
826
|
+
(double)is_, (double)id_);
|
|
826
827
|
}
|
|
827
828
|
|
|
828
829
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: openbricks
|
|
3
|
-
Version: 2.6.
|
|
3
|
+
Version: 2.6.2
|
|
4
4
|
Summary: openbricks — host-side CLI + MuJoCo-backed simulator for the openbricks MicroPython firmware. Flash, list, run, upload, log; ``openbricks sim`` for the physics simulator.
|
|
5
5
|
Author: openbricks contributors
|
|
6
6
|
License: MIT
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{openbricks-2.6.0 → openbricks-2.6.2}/openbricks_sim/worlds/wro_2026_junior_heritage_heroes/mat.png
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{openbricks-2.6.0 → openbricks-2.6.2}/openbricks_sim/worlds/wro_2026_senior_mosaic_masters/README.md
RENAMED
|
File without changes
|
{openbricks-2.6.0 → openbricks-2.6.2}/openbricks_sim/worlds/wro_2026_senior_mosaic_masters/mat.png
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{openbricks-2.6.0 → openbricks-2.6.2}/openbricks_sim/worlds/wro_2026_senior_mosaic_masters/world.xml
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|