feat: G6 analog/digital-out protocol commands + designer field validation - #126
Merged
Conversation
…mands Expose the two experiment-relevant I/O commands from PR #123's G6 console (SET_AO_VOLTAGE 0xA0, SET_DIGITAL_OUT 0xAA) as controller commands in the YAML protocol. These drive native G6 controller-board hardware (BNC J27 DAC, DO1/DO2 TTL), so they are controller commands (not plugins) and are gated G6-only. All other new console commands (SD mgmt, firmware/ISP, STREAM_FRAME, GET_* reads) are operator/setup and stay out of the protocol. Web-runner-only for v1: YAML stays forward-compatible (unknown-key passthrough) so the MATLAB runner tolerates the keys until coordinated separately. The web runner wiring (arena-runner-g6.js) is deferred until PR #123's wire encoders land on main. - plugin-registry.js: register setAnalogOut {mv}, setDigitalOut {channel,state}; add G6_ONLY_COMMANDS set + isG6OnlyCommand() - protocol-yaml-v3.js: mv/channel/state as first-class keys; collectExportWarnings gains an optional arenaGeneration arg that soft-warns (never blocks) on a G6-only command targeting a non-G6 arena - protocol-yaml.js: v1/v2 emit for the new fields (round-trip) - experiment_designer_v3.html: rigGeneration() gates the add-command dropdown + card badge (permissive — hide/badge only when generation is KNOWN non-G6); add mv/channel/state to renderCommandCard detailKeys so fields render - experiment_designer.html: v2 forward-compat defaults - tests: v3_g6_io.yaml fixture + Suite 33 (19 checks); npm test green (663/663 v3) Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Now that PR #123's wire encoders (encodeSetAoVoltage/encodeSetDigitalOut) are on main, complete the web-runner path for the two G6-only I/O controller commands. - arena-runner-g6.js: add setAnalogOut/setDigitalOut to RUNNABLE_CONTROLLER_COMMANDS + the mirrored emit-list comment; translateCommand emits {op:'setAnalogOut',mv} / {op:'setDigitalOut',channel,state} with range validation (mv 0-5000 int; channel 1|2; state 0|1) → {op:'error'} on bad input; _runIR dispatches to W.encodeSetAoVoltage / W.encodeSetDigitalOut (instantaneous, no clock advance). - test-arena-runner-g6.js: translateCommand IR + range-error checks; runSequence byte-level test (setDigitalOut(2,1)->03 aa 02 01; setAnalogOut(2500)->03 a0 c4 09). - test-arena-wire-g6.js: golden vectors + range-throw checks for both encoders. pixi run test green (runner 130/130, wire 112/112). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Numeric fields in the v3 designer previously accepted any value (only NaN/empty
was rejected); an out-of-range value like mv=9999 was silently saved and only
failed at run time. Now illegal values are impossible to commit.
- plugin-registry.js: add min/max/step/integer to controller command params
(mv 0-5000, gain -128..127 int8, frame_rate/frame_index/posX 0..65535,
pattern_ID 1..65535, duration >=0) and integer:true to backlight power /
panel_num (which already had min/max). Add pure clampToSchema(value,schema)
-> {value,changed,reason}.
- experiment_designer_v3.html: renderEditableField now sets native min/max/step
on number inputs, shows the allowable range + integer in the hover tooltip
(numFieldTooltip), and clamps/rounds to the schema on commit via clampToSchema,
surfacing a transient toast (showToast) explaining the correction. wait.duration
gets a {min:0} schema so it validates too. Plugin params inherit this for free
(they already declared min/max and route through the same renderer).
- tests/test-plugin-registry.js (new, wired into pixi test): clampToSchema +
isG6OnlyCommand unit coverage (require()-of-ESM under Node >= 22.12).
pixi run test green (plugin-registry 15/15). Browser-verified: mv 9999->5000,
wait -5->0, gain clamps, floats round, range tooltips present.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
…hanges v3 Experiment Designer v0.36 → v0.37; v2 Experiment Designer v0.9 → v0.9.1. Timestamp 2026-07-01 00:57 ET. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
These suites were only covered by the local `pixi run test` task. Add them to the roundtrip CI workflow (plain node, Node 24 already set) plus their source-file triggers (js/arena-wire-g6.js, js/arena-runner-g6.js) so the G6 I/O + clampToSchema coverage runs on push/PR instead of silently rotting. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
mbreiser
added a commit
that referenced
this pull request
Jul 2, 2026
* docs(arena-studio): unification design + wireframes v1–v5 + handover Consolidated onto current main. v5 is the approved density/ergonomics pass over v4 (one 44px bar; Console essentials + collapsible foot-gun groups; 150px collapsible run-log) with content re-synced to shipped main: ArenaSession broker shipped, run-log module built-but-unwired, plus #126 analog/digital-out, #129 run-whole-condition, #130 0x88 + panel-display-mode, #131 FicTrac. Handover refreshed to the verified 2026-07-01 shipped-vs-pending table. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> * arena-studio: ISP firmware-push handoff + same-origin dev artifacts Groundwork for Arena Studio's "push official builds to panels" flow: - docs/development/arena-studio-isp-firmware-push-handoff.md — catalog schema (isp_file/isp_sha256, firmware repo PR #17), the 0xE0/0xE3/0xC8/ 0xC9 wire flow (encoders already in js/arena-wire-g6.js), UX notes from the real fleet reflash, gotchas (CORS: Pages yes / Release assets no). - flasher/firmware/manifest-dev.json — schema-identical dev catalog to develop against until PR #17 + a release tag publish the real one. - Dev builds (same-origin): isp-progress-display 23d66af (progress bar while ISP-flashing + first-boot smiley), both revs, .bin + .uf2; plus the current fleet build (dd7d3f9) ISP bins. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Adds the two experiment-relevant G6 I/O commands from #123's console (
SET_AO_VOLTAGE0xA0 → BNC J27 DAC;SET_DIGITAL_OUT0xAA → DO1/DO2 TTL) to the YAML experiment protocol as G6-only controller commands, wired end-to-end, plus a designer-wide clamp-to-legal field-validation pass. The other 16 new console commands (SD pattern mgmt, firmware/ISP,STREAM_FRAME,GET_*reads) are operator/setup and stay out of the protocol.Hardware-verified on a real G6 (2026-07-01): AO (J27 → 2.5 V) and DO1 (J3 toggle) confirmed via both
arena_console.htmland the v3 designer full-sequence runner.What's included
setAnalogOut {mv}/setDigitalOut {channel,state}inplugin-registry.js; first-class YAML keys + a soft export-warning when used on a non-G6 rig (protocol-yaml-v3.js); v1/v2 emit (protocol-yaml.js).arena-runner-g6.jstranslates + sends both via Fictrac bridge #123's encoders with range validation; instantaneous (no clock advance).min/max/integeron commit, show the allowable range in the hover tooltip, and toast the correction. Covers all command scalar fields (controller + plugin + wait). Pure exportedclampToSchema().tests/test-plugin-registry.js; all wired into the CI workflow.pixi run testgreen.Scope / follow-ups (not in this PR)
maDisplayTools) runner support + final command-name lock-in are a separate, later task; YAML stays forward-compatible so MATLAB ignores the new keys.🤖 Generated with Claude Code