支持传感器独立校准文件与批量配置启动
保留逐台添加,并通过显式配置一次连接全组;失败时撤销本批新增连接。通过 35 项回归测试、真实 SDK 校准与 1–4 路验证、Ruff 和文档检查。
This commit is contained in:
+76
-8
@@ -1,8 +1,8 @@
|
||||
# UART finger service
|
||||
|
||||
Start the service first, then manually add 1-4 camera sources through UART.
|
||||
Each successful `add` opens and warms up one source. Send `start` when the set
|
||||
is ready. There is no camera discovery, hot-plug monitoring or automatic connection.
|
||||
Connect 1-4 sources individually through UART, or load an explicit setup file
|
||||
with their configurations and calibration paths. There is no camera discovery
|
||||
or hot-plug monitoring; every source is selected by the user.
|
||||
|
||||
## Start the service and add cameras
|
||||
|
||||
@@ -40,17 +40,80 @@ No sensor count is declared in advance. A failed addition replies `ERR add ...`,
|
||||
closes its newly opened runtime if one exists, and leaves existing cameras and
|
||||
IDs unchanged. It does not consume an ID. The service remains available for retry.
|
||||
|
||||
To select this sensor's force calibration, append `--calibration`:
|
||||
|
||||
```text
|
||||
add /dev/video0 --calibration "/home/radxa/calibrations/finger/DD02-14.json"
|
||||
```
|
||||
|
||||
An optional config still works: `add SOURCE CONFIG --calibration PATH`.
|
||||
Explicit calibration paths are passed to SDK `FingerRuntime.open(cal_path=...)`.
|
||||
A missing or invalid file fails the addition, without falling back to raw values.
|
||||
Without the option, normal SDK calibration selection applies. This does not
|
||||
replace calibration on a camera already added; restart to change that mapping.
|
||||
|
||||
The Windows example `D:\orisys_ws\data\calibrations\finger\DD02-14.json` refers
|
||||
to a file on that computer. Copy it to the Q6A before using a board-local path.
|
||||
Quote Windows paths in UART commands, or use forward slashes. The user must
|
||||
match each camera to its physical sensor's calibration; no serial-number discovery
|
||||
is performed.
|
||||
|
||||
The TTL login console and data UART must use **different ports**. Data defaults
|
||||
to `/dev/ttyHS1`, 115200 baud, 8N1 without flow control. It must not be occupied
|
||||
by getty or another serial program. The script does not configure UART pins.
|
||||
Logs stay in the login console; protocol records go to the data UART.
|
||||
`--show` is optional local desktop debugging.
|
||||
|
||||
## Batch setup and one-command startup
|
||||
|
||||
Copy [sensors.example.json](../serial/sensors.example.json), then replace its
|
||||
camera paths and calibration filenames with the real mappings. `SENSOR-2` through
|
||||
`SENSOR-4` are placeholders. The JSON format is:
|
||||
|
||||
```json
|
||||
{
|
||||
"sensors": [
|
||||
{"source": "/dev/video0", "config": "finger", "calibration": "calibrations/finger/DD02-14.json"},
|
||||
{"source": "/dev/video2", "calibration": "calibrations/finger/SENSOR-2.json"}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
List 1-4 entries. `source` is required; `config` defaults to startup `--config`.
|
||||
An omitted/null `calibration` uses normal SDK selection. Relative file paths
|
||||
resolve from the setup file's directory, independently of the working directory.
|
||||
Named configs such as `finger` remain names. Unknown fields are rejected.
|
||||
|
||||
Once saved as `sensors.json`, one terminal command connects the whole set and
|
||||
starts continuous UART output:
|
||||
|
||||
```bash
|
||||
python serial/example_uart.py --port /dev/ttyHS1 --setup sensors.json --start
|
||||
```
|
||||
|
||||
Omit `--start` to connect and wait for UART commands. With neither option, empty
|
||||
manual startup is unchanged. `--start` requires `--setup`. Preparation failure
|
||||
rolls back the entire startup set and exits before opening the UART.
|
||||
|
||||
An already-running service can also load the file:
|
||||
|
||||
```text
|
||||
load "/home/radxa/sensors.json"
|
||||
OK loaded 1 2
|
||||
start
|
||||
```
|
||||
|
||||
`load` only connects; it does not start output. It can extend manually added
|
||||
sensors, up to four total. Batch failure removes only that batch's new sensors
|
||||
and leaves previously added cameras unchanged. `add` and `load` require stopped
|
||||
output. Wait for each reply before proceeding.
|
||||
|
||||
## Commands and output
|
||||
|
||||
| Command | Behavior |
|
||||
|---|---|
|
||||
| `add SOURCE [CONFIG]` | Open and prepare one source while output is stopped; reply `OK added ID`. Optional config overrides the startup `--config` for this sensor only. |
|
||||
| `add SOURCE [CONFIG] [--calibration PATH]` | Prepare one source while output is stopped; reply `OK added ID`. Config/calibration apply only to this sensor. |
|
||||
| `load SETUP.json` | Add the sources and calibration mappings in a setup file while stopped; reply `OK loaded ID ...`. |
|
||||
| `start` | Begin continuous output for all added sensors; requires at least one sensor. Reply `OK start`. |
|
||||
| `stop` | Pause continuous output for the whole set; keep all cameras open. Reply `OK stop`. |
|
||||
| `read` | Publish one complete processing round; requires a sensor and preserves streaming state on success. |
|
||||
@@ -70,8 +133,7 @@ OK start
|
||||
`add` while streaming replies `ERR add stop streaming first` and opens no source.
|
||||
A fifth source or duplicate source is rejected. Removing/replacing cameras requires
|
||||
quitting and starting a fresh service. `start`, `stop`, `read` and `quit` take no
|
||||
arguments and always act on the full set. The older commands and automatic
|
||||
startup options are removed.
|
||||
arguments and always act on the full set. The older protocol commands remain removed.
|
||||
|
||||
Commands are case-insensitive UTF-8 lines terminated by LF, CR or CRLF. Partial
|
||||
lines survive read timeouts. Lines exceeding 1024 bytes are discarded through
|
||||
@@ -109,7 +171,7 @@ from finger_api import FingerSensorBank
|
||||
|
||||
bank = FingerSensorBank(config="finger")
|
||||
try:
|
||||
first_id = bank.add(0)
|
||||
first_id = bank.add(0, cal_path="/home/radxa/calibrations/finger/DD02-14.json")
|
||||
second_id = bank.add(2, config="finger")
|
||||
for reading in bank.read_all():
|
||||
print(reading.sensor_id, reading.normal, reading.shear_x, reading.shear_y, reading.units)
|
||||
@@ -125,6 +187,8 @@ sources succeed. File EOF raises `EOFError`; capture/processing failure raises
|
||||
and SDK units; older SDKs without a units property report `unknown`. `close()`
|
||||
attempts every runtime and clears the camera set. The API caller must pause its
|
||||
own processing loop before adding; the UART service enforces this for commands.
|
||||
`bank.add_setup("sensors.json")` uses the same transactional batch loader as the
|
||||
CLI and UART. `bank.calibration_paths` records explicit calibration paths by ID.
|
||||
|
||||
## Backend evidence and remaining limits
|
||||
|
||||
@@ -135,12 +199,16 @@ recorded sources were added incrementally, with complete readings after each
|
||||
addition and three final rounds for each count. Existing runtime identities were
|
||||
preserved; capture handles and sensor objects were distinct, and optical-flow
|
||||
arrays did not share memory. Resources were released after each case.
|
||||
The explicit `DD02-14.json` calibration was also tested on 1-4 recorded sources:
|
||||
each instance loaded its assigned file and reported three calibrated `N` axes.
|
||||
Four-source JSON loading passed, and invalid explicit calibration was rejected
|
||||
without altering an existing sensor. This validates software binding, not physical accuracy.
|
||||
|
||||
To rerun with a recording containing at least 12 frames, put generated clips and
|
||||
caches in an isolated task scratch directory:
|
||||
|
||||
```bash
|
||||
python tests/check_backend.py --recording /path/to/recording.avi --scratch .scratch/uart-manual-add/backend-run
|
||||
python tests/check_backend.py --recording /path/to/recording.avi --calibration /path/to/DD02-14.json --scratch .scratch/uart-calibration-setup/backend-run
|
||||
python -m unittest discover -s tests -v
|
||||
```
|
||||
|
||||
|
||||
Reference in New Issue
Block a user