# PULSEGRID F01 — черновик протокола управления

Версия 0.2, для P1/P2. Все численные пределы считаются конфигурацией испытательного стенда, а не клиническими значениями.

## Топология

```text
Hand Controller → Central Safety Controller → CAN FD → Module[0..N]
                                                └────→ independent E-STOP line
```

- Центральный цикл pressure engine: 100 Гц.
- Контур safety supervisor: 1 кГц.
- Локальный force loop: 1 кГц.
- CAN FD nominal/data rate для P1: 500 кбит/с / 2 Мбит/с.
- Каждый модуль — 16 исполнительных каналов.

## Координатная модель

В записи и в API хранится нормализованное поле стопы, а не аппаратные команды. Координаты `x,y ∈ [0,1]`; начало — медиальный край пятки, ориентация задаётся полем `foot`.

```json
{
  "schema": "pgf/1",
  "time_ms": 1240,
  "foot": "left",
  "frame_id": 39510,
  "points": [
    {"id": 17, "force_n": 0.8},
    {"id": 18, "force_n": 1.4},
    {"id": 19, "force_n": 1.1},
    {"id": 33, "force_n": 0.5}
  ],
  "limits_profile": "P1_BENCH_03"
}
```

## CAN ID proposal

| CAN ID | Направление | Назначение | Период |
|---:|---|---|---:|
| `0x080` | Central → all | SYNC + monotonic frame counter | 10 мс |
| `0x100 + node` | Central → module | 4 целевые силы, segment 0..3 | 10 мс |
| `0x200 + node` | Module → central | 4 измеренные силы, segment 0..3 | 10 мс |
| `0x300 + node` | Module → central | status, temperature, supply, fault bits | 100 мс |
| `0x380 + node` | Central → module | limits profile hash + arm/disarm | on change |
| `0x3F0` | Any → all | emergency zero-force broadcast | event |
| `0x400 + node` | Service ↔ module | calibration/service frames | service only |

Сегментирование по 4 каналам сохраняет простые кадры и позволяет критичным значениям быть продублированными. На P2 следует сравнить это с одним CAN FD кадром на 16 каналов.

## Target Force frame, 16 bytes

```text
byte 0..1   frame_counter   uint16
byte 2      segment        uint8  (0..3)
byte 3      flags          bit0 armed, bit1 zero_all, bit2 calibration
byte 4..11  force[4]       uint16, 0.01 N/LSB
byte 12..13 limits_hash    uint16
byte 14..15 CRC16          safety CRC independent of CAN CRC
```

Каждый модуль принимает команду только когда:

1. аппаратная линия E-STOP разрешена;
2. node state = `ARMED`;
3. `frame_counter` монотонен;
4. получены четыре сегмента одного frame counter;
5. limits hash совпадает;
6. CRC16 корректен;
7. локальные температура, питание и sensors plausible.

Иначе модуль переходит в `FAULT_RETRACT`.

## Состояния модуля

```text
BOOT → SELF_TEST → DISARMED → ARMING → ARMED
  └──────────────→ FAULT_RETRACT → FAULT_LATCHED
                                  └─ manual reset → SELF_TEST
```

- `BOOT`: выходы физически выключены.
- `SELF_TEST`: проверка памяти, ADC, датчиков, клапанов/драйверов и возврата.
- `DISARMED`: давление/позиция равны нулю.
- `ARMING`: получен актуальный профиль лимитов и непрерывный heartbeat.
- `ARMED`: принимает целевые силы.
- `FAULT_RETRACT`: немедленный vent/retract; кратковременное состояние.
- `FAULT_LATCHED`: силовые выходы заблокированы до физического/сервисного reset.

## Fault bits

| Bit | Код | Реакция |
|---:|---|---|
| 0 | HEARTBEAT_TIMEOUT | zero + retract |
| 1 | CAN_COUNTER | zero + retract |
| 2 | FORCE_OVER_LIMIT | zero affected point; then latch module |
| 3 | FORCE_SENSOR_IMPLAUSIBLE | zero affected point; degraded mode forbidden for human use |
| 4 | TEMPERATURE_HIGH | controlled zero, then latch |
| 5 | SUPPLY_FAULT | hardware disable + latch |
| 6 | ACTUATOR_STUCK | zero/vent + latch |
| 7 | ESTOP_ACTIVE | hardware disable + latch |
| 8 | CALIBRATION_INVALID | arm forbidden |
| 9 | FOOT_MOVEMENT | zero all points on foot |

## Watchdog timing proposal

- Central SYNC timeout: 30 мс.
- Complete target frame timeout: 25 мс.
- Local force sensor freshness: 5 мс.
- Central MCU independent watchdog: 20 мс.
- Module independent watchdog: 15 мс.
- E-STOP hardware path bypasses software and is asynchronous.

Фактические значения верифицируются fault-injection тестами P1/P2.

## Запись программы

Файл `.pgf` содержит metadata, ограничения автора и последовательность нормализованных pressure fields. Он не содержит PWM, valve timing, motor steps или calibration offsets конкретного устройства. При воспроизведении все поля заново проходят актуальный safety supervisor.

## Обязательные P1 tests

1. Потеря каждого CAN сегмента.
2. Повтор, скачок и rollover frame counter.
3. Потеря центрального контроллера во время 5 Н.
4. Зависание клапана/драйвера и недостоверный sensor feedback.
5. Аппаратный E-STOP при максимальной разрешённой суммарной силе.
6. Brownout локального MCU.
7. Перегрев и обрыв датчика температуры.
8. Сбой EEPROM/CRC калибровки.
9. Одновременный fault двух соседних модулей.

Протокол не считается production-ready до тестов worst-case bus load, EMC и независимого review safety state machine.
