Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
38 commits
Select commit Hold shift + click to select a range
bacb44f
Wire pinokin CollisionChecker into motion-command pre-flight checks
Jepson2k May 12, 2026
dd96c7b
Add SYS_SELF_COLLISION catalog template + joint_commands guard wiring…
Jepson2k May 12, 2026
8479f8a
Wire collision guards into cartesian_commands + config + Robot public…
Jepson2k May 12, 2026
5177634
Add COLLISION_* config knobs + Robot public collision methods
Jepson2k May 12, 2026
8ffa7b3
Skip collision integration tests when CollisionChecker is unavailable
Jepson2k May 12, 2026
2644187
Build matching-branch pinokin from source in CI (no graceful degradat…
Jepson2k May 12, 2026
4a4fc16
Apply ruff-format to PAROL6_ROBOT.py + joint_commands.py
Jepson2k May 12, 2026
3b0f5f9
Apply ruff-format to cartesian_commands.py
Jepson2k May 12, 2026
0d8e6ac
Apply ruff-format to config.py + robot.py
Jepson2k May 12, 2026
875824b
Collision: simplified meshes, named pairs, tool auto-attach, SRDF audit
Jepson2k May 14, 2026
6d3a371
Cleaner SYS_SELF_COLLISION message phrasing
Jepson2k May 14, 2026
f4a636f
Collision: address deep-review findings
Jepson2k Jun 13, 2026
fe139e8
Collision: curved-move guard, escape-from-collision, fail-loud init, …
Jepson2k Jun 21, 2026
e262df2
deps: cap numpy<2.5 for numba compatibility
Jepson2k Jun 23, 2026
27bc80a
collision: fix Windows mesh path + ty unresolved-import on pinokin
Jepson2k Jun 23, 2026
dd95d0c
Merge main into collision: bump waldoctl pin to v0.4.0, resolve tests…
Jepson2k Jun 24, 2026
b9a02c1
ci: drop shell:bash so Install runs in the conda env
Jepson2k Jun 24, 2026
968cd5e
WC: report self-collision pairs to the frontend via status
Jepson2k Jun 29, 2026
a0cb14f
WC: add SET_SHAPES — workspace keep-out shapes synced to the checkers
Jepson2k Jun 29, 2026
130f7fb
WC: collision clearance + jog speed-buffer + joint self-collision gre…
Jepson2k Jun 30, 2026
69c5625
WC: gate joint greying on the full checker (covers tool + shapes)
Jepson2k Jun 30, 2026
ac1c5a0
Dedup the disabled-checker guard across Robot collision methods
Jepson2k Jun 30, 2026
16195b8
Review fixes: uniform intake collision-clear + _pose_to_matrix why-co…
Jepson2k Jul 2, 2026
949422c
IK worker owns the enablement collision gate; add cartesian gating
Jepson2k Jul 2, 2026
7ad5814
Client Robot: sync tool geometry + shapes onto the process checker
Jepson2k Jul 2, 2026
d362a0f
Jog collision semantics: check the streamed config, clamp lookahead, …
Jepson2k Jul 4, 2026
eed2702
Enablement gates: escape parity when inside a keep-out; syncs can't k…
Jepson2k Jul 4, 2026
203fcdf
SET_SHAPES is a SystemCommand with explicit planner sync; sync wrappe…
Jepson2k Jul 4, 2026
fbde304
Round-3 review fixes: shape validation, dry-run parity, hot-path allo…
Jepson2k Jul 4, 2026
7560ba8
Shapes: canonical Shape in-process, acked SET_SHAPES, readback, insta…
Jepson2k Jul 5, 2026
1ecb605
Round-5: escape new-pairs parity, tool geom vocabulary, MoveIt-style …
Jepson2k Jul 7, 2026
f31d47f
CI: pre-install ruckig from fixed upstream SHA
Jepson2k Jul 8, 2026
7152f30
Merge remote-tracking branch 'origin/main' into claude/add-collision-…
Jepson2k Jul 8, 2026
6d2d7f6
ty: assert IK limit caches non-None before the njit safety check
Jepson2k Jul 8, 2026
fe9dd81
deps: bump waldoctl to v0.5.0, pinokin to v0.1.7 release wheels
Jepson2k Jul 8, 2026
6b6391a
deps: bump pinokin to v0.1.8 (deterministic macosx_15_0 wheels)
Jepson2k Jul 9, 2026
292d298
StatusBuffer: cart_en as a declared field, not a property
Jepson2k Jul 9, 2026
1c87409
Comments: trim narration to one-line whys
Jepson2k Jul 9, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
67 changes: 64 additions & 3 deletions .github/workflows/tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,9 @@ jobs:
shell: bash
run: |
python -m pip install --upgrade pip
# ruckig 0.17.3 sdist doesn't build under scikit-build-core 1.0;
# pre-install the fixed commit until a release lands (pantor/ruckig#262).
pip install "ruckig @ git+https://github.com/pantor/ruckig@2249d57ffaa19ecdadeaab62daf97857813629ff"
pip install -e ".[dev]"
# Override the pinned waldoctl with the matching feature branch if one
# exists, AFTER ".[dev]" (and with --force-reinstall) so the pinned tag
Expand All @@ -36,31 +39,79 @@ jobs:
fi
- name: Run pre-commit
uses: pre-commit/action@v3.0.1

test:
name: ${{ matrix.os }} / Python ${{ matrix.python-version }}
runs-on: ${{ matrix.os }}
timeout-minutes: 30
timeout-minutes: 45
strategy:
fail-fast: false
matrix:
os: [ubuntu-latest, windows-latest, macos-latest]
python-version: ['3.11', '3.12', '3.13', '3.14']

defaults:
run:
shell: bash -l {0}

steps:
- name: Checkout repository (with submodules)
uses: actions/checkout@v4

- name: Setup Python
- name: Detect matching pinokin branch
id: pinokin
shell: bash
run: |
BRANCH="${GITHUB_HEAD_REF:-${GITHUB_REF_NAME}}"
if git ls-remote --heads https://github.com/Jepson2k/pinokin.git "$BRANCH" 2>/dev/null | grep -q .; then
echo "matching=true" >> "$GITHUB_OUTPUT"
echo "branch=$BRANCH" >> "$GITHUB_OUTPUT"
else
echo "matching=false" >> "$GITHUB_OUTPUT"
fi

# ----------------------------------------------------------------------
# Path A: matching pinokin branch -> conda env (provides libpinocchio +
# libcoal headers/libs) so pinokin can be built from source. We install
# PAROL6 first (which pulls in the pinned pinokin v0.1.6 wheel) and
# then override pinokin with the source-built wheel from the matching
# branch. This is the only way to exercise unreleased pinokin features
# before a release lands.
# ----------------------------------------------------------------------
- name: Setup Miniforge (matching pinokin branch)
if: steps.pinokin.outputs.matching == 'true'
uses: conda-incubator/setup-miniconda@v3
with:
miniforge-version: latest
python-version: ${{ matrix.python-version }}
conda-remove-defaults: true
activate-environment: parol6-test

- name: Clone matching pinokin branch
if: steps.pinokin.outputs.matching == 'true'
run: |
git clone --depth=1 --branch="${{ steps.pinokin.outputs.branch }}" https://github.com/Jepson2k/pinokin.git pinokin-src
conda env update -n parol6-test -f pinokin-src/environment.yml

# ----------------------------------------------------------------------
# Path B: no matching pinokin branch -> plain pip with the pinned
# release wheel. Anything in PAROL6 that requires a newer pinokin
# feature will fail loudly here (intended).
# ----------------------------------------------------------------------
- name: Setup Python (pinned pinokin)
if: steps.pinokin.outputs.matching != 'true'
uses: actions/setup-python@v5
with:
python-version: ${{ matrix.python-version }}
cache: pip
cache-dependency-path: pyproject.toml

- name: Install package
shell: bash
run: |
python -m pip install --upgrade pip
# ruckig 0.17.3 sdist doesn't build under scikit-build-core 1.0;
# pre-install the fixed commit until a release lands (pantor/ruckig#262).
pip install "ruckig @ git+https://github.com/pantor/ruckig@2249d57ffaa19ecdadeaab62daf97857813629ff"
pip install -e ".[dev]" pytest-timeout
# Override the pinned waldoctl with the matching feature branch if one
# exists, AFTER ".[dev]" (and with --force-reinstall) so the pinned tag
Expand All @@ -72,6 +123,16 @@ jobs:
pip install --force-reinstall "waldoctl @ git+https://github.com/Jepson2k/waldoctl.git@${BRANCH}"
fi

# Override the pinned pinokin v0.1.6 wheel with the matching-branch
# source build. --force-reinstall + --no-deps swaps just pinokin
# without disturbing other resolved dependencies.
- name: Override pinokin with matching-branch source build
if: steps.pinokin.outputs.matching == 'true'
run: |
cd pinokin-src
pip install . --no-build-isolation --force-reinstall --no-deps
python -c "from pinokin import CollisionChecker; print('CollisionChecker available')"

- name: Show environment
run: |
python -V
Expand Down
11 changes: 11 additions & 0 deletions CLAUDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -132,6 +132,7 @@ For streamable commands (`streamable = True`), `do_setup()` also runs at high fr
## Code Style

- **Comments**: Describe the final code state, not what changed. Avoid "changed X to Y" or "added this because..." comments.
- **Never ship declared-but-unimplemented API surface.** No "reserved" fields or params, no docstrings saying "not yet applied" — implement it or don't declare it.
- **Type annotations**: Fix type errors properly instead of using `# type: ignore`. Prefer:
- `@overload` decorators for functions with different return types based on input
- `assert` statements to narrow types after None checks
Expand All @@ -148,3 +149,13 @@ Prefer fewer, comprehensive integration tests that mimic manual testing over a l
- **Test results are in `test-results.xml`.** Pytest writes JUnit XML to `test-results.xml` automatically. When diagnosing failures, read this file — it contains test names, durations, failure messages, and captured output. This is more reliable than parsing console output.
- **NEVER run parol6 and web commander test suites in parallel** — no proper isolation, they share resources and have timing issues when resource-constrained. Always run sequentially.
- **NEVER allow subagents to run tests.** Many tests are timing-sensitive and the system doesn't have enough resources for agents and tests to run simultaneously. Only the main conversation should run tests, and only after all agents have completed.

### No testing theatre

- Default to real components (fake-serial controller, simulator). A hand-rolled fake is a last resort.
- Never fake a contract you haven't read — match the real code's raise-vs-return behavior, return types/codes, and signatures.
- If a fake must mimic protocol behavior (acks, return codes, ordering, lifecycle), the test is at the wrong layer — use the real path. Fakes are for one-line oracles only (e.g. a distance function feeding gate-logic tests).
- Enter through the real path (command dispatch / client call), not internal helpers fed hand-built inputs.
- Derive cases from the requirement, not the code under test — "rejects invalid input" means NaN/inf/negative/zero, not the cases the code already handles.
- Assert outcomes, not interactions — "the fake was called" proves nothing.
- A regression test must fail against the bug before the fix. Born-green regression tests are theatre.
Loading
Loading