open-standards/aac/spec/access_model.md

38 lines
5.4 KiB
Markdown

# AAC sub-spec — The access model
Normative refinement of [SPEC §5](../SPEC.md). Reference: `aac_core::{AccessMethod, MotorProfile, ScanConfig, ScanMode, DwellConfig}`.
Every access method is a first-class input. The method and its tuning travel with the **user**, not the board: a board authored for eye-gaze MUST still open under touch or a switch (SPEC §5.3).
## 1. Access method — `AccessMethod`
`DirectTouch` (default) · `EyeGaze` · `HeadTracking` · `SwitchScan { switches: u8 }` · `Joystick` · `Bci` · `PartialVoice` · `Pointer`. `SwitchScan` carries the number of switches available (1, 2, or more); a 1-switch user relies on auto-scan timing, a 2-switch user steps and selects manually.
## 2. Motor profile — `MotorProfile`
The user's physical capabilities, used to adapt targets and timing: `fine_motor` and `sustained_press` (`Full | Limited | None`), `tremor_level` (`None | Mild | Moderate | Severe`), `min_target_mm: f32`, optional `max_reach_mm`, and `preferred_side`. A client SHOULD derive target size and dwell/scan timing from this profile and MUST NOT render a target smaller than `min_target_mm`.
## 3. Switch scanning — `ScanConfig`
A conforming scanner MUST support at minimum the `Linear`, `RowColumn`, and `Group` modes of `ScanMode` (also defined: `Block`, and inverse scanning). It MUST honor:
- `scan_rate_ms` — highlight dwell per step;
- `start_delay_ms` — delay before auto-scan begins after a press;
- `max_cycles` — complete cycles before stopping (`0` = infinite);
- `auto_restart` — whether scanning restarts after a selection.
What moves the highlight is `advance` (`ScanAdvance`): `Auto` (the scan rate; a press selects), `Step` (the person's switch moves it one step, another selects — two-switch step scanning), or `Hold` (it moves at the scan rate while the switch is held, and letting go selects — inverse scanning). With `Step` and `Hold`, `max_cycles` does not apply: the scan never stops under the person. `resume_from_last` starts each pass at the unit (row, group, block or cell, or the group beside the grid) that held the last choice, on the same board; it only turns the visiting order. A third and fourth switch MAY move the highlight back one step (`retreat`) and leave a row for the rows (`back_out`). The groups beside the grid — the message bar (`bar`) and the navigation, Back, Home and Help (`nav`) — are placed with `BarPlacement` (`After | Before | Off`) each, the bar first when both are on one side (SPEC §5.5, §5.6). The switches themselves — which key, gamepad button or touch is which — are the person's (SPEC §5.7) and are kept by the client, not in `ScanConfig`.
`scan_rate_ms` is the person's to set (SPEC §5.1). `adaptive_rate` MUST default to `false`. A rate recommended, proposed or applied from measured responses MUST follow SPEC §5.2: at least 10 recorded responses, at least `max(⌊100·M/65⌋, P95)` of their response times, clamped to `[300, 5000]` ms. Without opt-in the scanner MAY only *propose* that rate (`proposed_scan_rate_ms`, which offers nothing within 10% of the current rate); with opt-in it MAY apply it. A client that measures responses MUST time them from the moment a highlight appears to the press.
## 4. Dwell / eye-gaze — `DwellConfig`
Gaze selection MUST use a configurable dwell time (`base_dwell_ms`, with the dwell in force in `effective_dwell_ms`) with **visible progress feedback** (`DwellFeedback`) and a `tolerance_px` radius within which gaze may wander without resetting. A selection MUST NOT fire before the effective dwell elapses.
A dwell rests on a `DwellTarget`: a cell, or a control beside the grid (a button of the bar or the navigation, or of an open panel; SPEC §5.6), which always takes the person's own dwell. With `look_away`, a target just selected is not selected again until gaze (or the pointer) has left it; `chosen_otherwise` ends a dwell when a tap, a click or a switch chose instead (SPEC §5.8). A pointer (a head mouse, an eye tracker that moves the pointer) dwells as gaze does, when the person chooses it: an ordinary mouse is the same input.
The dwell is the person's to set (SPEC §5.1; the reference's `set_dwell_ms`, clamped to `[150, max_dwell_ms]`). `fatigue_adaptation` — the reference's name for automatic dwell adjustment — MUST default to `false`. Proposals (`proposed_dwell_ms`) follow SPEC §5.3: one ladder step longer when more than 20% of recent selections were undone; one step shorter when fewer than 5% were undone and more than 20% of attempts were abandoned late (gaze left after at least half the dwell); never from fewer than 10 selections, never shorter than 300 ms. A client counts an undo when the person removes a word within a few seconds of selecting it by dwell. The dwell engine reads a monotonic clock that MUST work on the client's platform (the reference uses `web-time`, since `std::time::Instant` panics in browsers).
## 5. Universality
No access method MAY be a precondition for opening or reading a board (SPEC §5, item 3). Choosing an access method is best done by the person with their team, and it is never a prerequisite for starting (SPEC §11); the standard guarantees that whichever method is chosen is a first-class, fully-specified input — never a bolt-on. A client SHOULD start the chosen method as soon as it is chosen (scanning over the board on screen, the camera for gaze) and stop what it no longer needs — in particular, release the camera when gaze is no longer in use.