Henrik Muehe ec40429dec Z-A coupling interlock: prevent collision between Z and A tools
The auxiliary A axis carries a tool that hangs below the Z spindle.
Beyond a small Z descent the two physically collide unless A drops
with Z. Enforce in machine coords:

    A_machine - Z_machine <= K
    K = (A_home_mm - z_home_mm) + couple_z_clearance_mm

With our setup K = (134 - 0) + 22 = 156. At rest A=134 Z=0, A-Z=134
which is fine. Z can descend 22mm before the rule starts forcing A
down with it.

Two complementary layers:

(1) AuxPreprocessor injection (auto-fix uploaded files)
    Tracks modal Z, A and distance mode (G90/G91) while scanning the
    file. When a line would put A above Z by more than the clearance
    we emit a 'G0 A<safe>' BEFORE the line so A is already at the
    safe position when Z descends. Endpoint check is sufficient
    because Z moves monotonically along a single line.

    Errors are raised (not silently auto-fixed) when:
      - the line lifts A above the safe band while Z stays put
        (would require auto-injecting a Z-up which could swing
        through a fixture)
      - the line endpoint targets an A above the safe band

    G91 disables injection with a one-shot warning; the runtime
    check still applies.

(2) Runtime check (ExternalAxis.check_coupling)
    Single source of truth for live motion. Hooked into:
      * Planner.__encode for every line block (covers MDI and
        running programs - gplan emits machine-coord targets)
      * ExternalAxis.execute_to_mm/enqueue_target_mm/enqueue_line
        for direct A motion (covers UI jog/move and planner-A
        dispatch)
    Raises ExternalAxisError on violation; gplan and the API both
    surface the message. Skipped when coupling is disabled or the
    axis isn't homed (mirrors the soft-limit gate).

    Continuous Z jog from the AVR is not gated - it's an active
    operator action without a pre-known endpoint. Operator-driven
    over-travel during continuous jog will be caught by the next
    MDI/file-load attempt.

Configuration in aux.json:
    couple_z_enabled        bool   default true (per agreed setup)
    couple_z_clearance_mm   float  default 22.0
    z_home_mm               float  default 0.0

Surfaced in the new Z-A Coupling section of the A Axis settings
page with a description of the rule. Existing aux.json files get
the new keys via the merged-defaults path on read.

Tested locally with synthetic gcode covering Z descent, combined
moves, A lift while Z deep, G92 reset, G91 mode, and combined
Z+A target violations.
2026-05-03 15:10:26 +02:00
2020-08-27 23:20:27 -04:00
2020-08-27 23:20:27 -04:00
2020-08-27 23:20:27 -04:00
2025-09-21 01:57:17 +05:30
2025-09-21 01:57:17 +05:30
2020-08-27 23:20:27 -04:00
2020-08-27 23:20:27 -04:00

OneFinity CNC Controller Firmware (A-axis fork)

This is the community-fork firmware (V09 UI, FA6, cold-boot work, macOS dev tooling) with a virtual A axis driven by an auxcnc ESP32 over USB serial. See docs/AUX_A_AXIS.md for the design and config.

Layout

src/avr/        AVR firmware (motion controller, AtxMega)
src/boot/       AVR bootloader
src/bbserial/   Linux kernel module for the bbserial driver
src/py/bbctrl/  Python control daemon (Tornado + websockets)
src/js/         Vue.js UI (legacy)
src/svelte-components/  Newer Svelte UI for dialogs and settings
src/pug/        Pug templates compiled into build/http/index.html
src/resources/  Static assets and config templates
scripts/        Install / update / RPi build helpers
docs/           Architecture, dev setup, A-axis docs

Build & flash (quick path, macOS or Linux)

The full build (make) requires avr-gcc, but the controller and UI only depend on the Python + web parts. If you're shipping a UI/Python change you don't need the AVR toolchain.

Prerequisites

  • Node.js (any recent LTS) with npm
  • Python 3 with setuptools
  • npm install once at the project root (this is wired into the node_modules Make target, but on a fresh checkout it's clearer to do it explicitly)
npm install
(cd src/svelte-components && npm install)

macOS gotcha: esbuild platform pin

The Pi build leaves node_modules/esbuild pinned to linux-arm64, which won't run on Darwin. If npm run build inside src/svelte-components complains about esbuild, reinstall it for the host:

cd src/svelte-components
rm -rf node_modules/esbuild
npm install esbuild@0.14.49 --no-save

(Use the version that matches package-lock.json.)

Build the web UI + Python sdist

# Build the Svelte components
(cd src/svelte-components && npm run build)

# Render pug templates and copy assets into build/http
make all          # AVR step will fail without avr-gcc; safe to ignore
                  # if you didn't change anything under src/avr or src/boot

# Package
./setup.py sdist
ls dist/bbctrl-*.tar.bz2

make pkg is the canonical target but it tries to build AVR first. On hosts without avr-gcc, run the steps above directly.

If bbctrl-*.tar.bz2 is missing src/bbserial/bbserial.ko, copy the prebuilt .ko from a previous official release into src/bbserial/ before running setup.py sdist (the install script on the controller just installs the existing module if a newer one isn't shipped).

Flash to a controller

curl -X PUT -H "Content-Type: multipart/form-data" \
  -F "firmware=@dist/bbctrl-1.6.7.tar.bz2" \
  -F "password=onefinity" \
  http://onefinity.local/api/firmware/update

…or use the Make target:

make update HOST=onefinity.local PASSWORD=onefinity

The controller stops bbctrl, untars the package, runs scripts/install.sh, and brings the service back up. Total downtime is ~30-45s. Watch progress at http://<host>/ (you'll get 404s while bbctrl restarts, then the new UI).

Verify the flash

curl -s http://onefinity.local/ | grep -c "OneFinity"
curl -s http://onefinity.local/api/diag/timing | head
curl -s http://onefinity.local/api/aux/status   # if A axis is enabled

Build & flash (full path, Debian/Linux)

For AVR + GPlan rebuilds, see docs/development.md. That path uses qemu + chroot to cross-compile gplan for ARM and needs the gcc-avr / avr-libc toolchain.

A axis (auxcnc)

This fork adds a virtual A axis. See docs/AUX_A_AXIS.md for:

  • G-code surface (G28 A0, G1 A25, etc.)
  • The G-code preprocessor and hook architecture
  • aux.json keys
  • REST API (/api/aux/*)
  • UI surface (jog row in Control, settings panel in Settings)
  • Edge cases (ESP reboot mid-job, limit closed at home start, …)
Description
Onefinity CNC controller firmware (fork of OneFinityCNC/onefinity-firmware) with W axis (auxcnc) integration, hooks, build/flash docs, and V09 UX redesign.
Readme GPL-2.0 9.6 MiB
Languages
C 37.4%
JavaScript 22.5%
Python 22.5%
Pug 5.3%
Svelte 4%
Other 8.2%