Merge branch 'main' of ssh://892887cvmk08.aicp.io:24928/orisys-tech/orisys-app

This commit is contained in:
ykcheungab
2026-09-23 10:00:13 +08:00
21 changed files with 1200 additions and 59 deletions
+48
View File
@@ -57,6 +57,54 @@ the wrong runtime version is the kind of fault that looks like a working machine
until it moves, so the override is authoritative: if it does not contain
`zauxdll.dll`, the app refuses to connect instead of quietly falling back.
One contract in `shared/src/orisys_app_shared/zmotion/client.py` is worth
knowing before touching it: `ZAux_Execute` **must** be given a reply buffer.
Passing `NULL` with a zero length is a write through a null pointer inside the
DLL — a native crash the worker thread cannot catch — and the buffer is also
how a refused online command explains itself, because `ZAux_Execute` returns 0
for a `RUN` whose file the controller does not have.
## Bring-up sequence
The vendor sequence, with the checks AutoCal's own state machine adds. P1 of
`docs/workflow.md` is this list in the workflow's vocabulary.
1. **Connect** (`eth` + the controller's IP). On success the app adopts any BAS
program the controller is already running from a previous session instead of
claiming the bus is uninitialised; `BUS_TYPE` is read immediately, and
`Bus_InitStatus` on the first poll.
2. **Download only if the bus type is unknown.** `ECAT.bas` / `RTEX.bas` are
chosen from `config/bas/` (the vendor requires a non-Chinese path) and
written to ROM. A controller that still has the program needs no download.
3. **Wait for `Bus_InitStatus`** — `−1` running, `1` success, `0` failed —
inside the vendor's 25 s window, then a timeout message naming the ZDevelop
diagnostic (`?*ETHERCAT`).
4. **Re-initialise** re-runs the program without re-downloading it:
`STOPTASK <task>` then `RUN "<file>",<task>`. The task number is
`bas_task` in `preference.json` (default **4**, the task the vendor
reference uses); the file name comes from this session's download, or from the
remembered `bas_path` when the session adopted a running program (the
controller does not report the name). The controller answers a `RUN` for a
file it does not have with **code 0** and the refusal in its reply text, so
that text is checked and shown rather than reported as an initialisation in
progress.
5. **Enable, then jog.** Motion stays refused until step 3 reports success.
### Connection and error codes
`ZAux_*` returns two unrelated families of code, and they need different answers:
| Range | Family | What the operator should do |
|---|---|---|
| `0` | success | — |
| `20000–29999` | PC-library fault (handshake, socket, address) | check the cable/segment and the IP, make sure nothing else holds the connection, then retry. Frequently transient: a first open on a cold route can fail and succeed on the next attempt, which is why an Ethernet connect makes up to 3 attempts before reporting. |
| `30000+` | the auxiliary block `zauxdll2.h` documents | the message names it (`无应答`, `参数错误`, …) |
| anything else | the controller's own code | look it up in ZDevelop's table |
A **host-library** code is never sent to ZDevelop's table, because that table
cannot contain it. Observed at the bench: `20008` from `ZAux_OpenEth` on a first,
transient attempt that succeeded immediately afterwards.
## Safety model
The guards live in `motion/service.py`, not in the UI, so they hold whatever