dvrip_twin: X1.0, zoom-out levels, and the board's own focus before the pass - #39
Conversation
X1.0 is the wide stop, which every zoom-in level starts from, so no zoom-in
ever lands there and it was never measured, though it is where the old
majestic-af model failed ("X1.0 can't focus", on the degraded lens). A level is
now the moves that reach it from anywhere, the last one recorded: a zoom-in
level is the wide stop and its zoom-in, X1.0 is settling at X2.0 and then one
held zoom-out into the stop. The reference sweeps reach each level by the same
moves (by DVRIP on OpenIPC, by timed pulses on the stock board).
out-X4.0 .. out-X1.0 settle at the tele end, then zoom out for the full range less the level's zoom-in hold (out-X1.0 into the wide stop). A zoom-out drives focus the other way through the board's tracking, and lands differently. Each level also records the picture 1.5-2.8 s after the stop, before majestic-af's pass starts: where the lens board's own tracking left focus, on both cameras, reported as a fraction of the best.
…PROTOCOL: zoom-out focus - Tests for the out-X* moves and the board-only window. - README/TWIN.md: the zoom-out levels, the 'at +2s' columns, and two pitfalls: the OpenIPC reference reading over 100 % (irregular /ptz pulses) and the centre box disagreeing with the ISP's focus statistic. - PROTOCOL.md: a zoom-out leaves the board's focus well off (zoom gear slack); a 150-200 ms zoom-in after it fixes that; the stock firmware does not, and stays at 0-7 % of best. - captures: the in/out runs before and after majestic-af #18.
|
/review |
Code Review by Qodo
1.
|
PR Summary by QodoMeasure zoom-out focus and the wide stop in the DVRIP twin harness
AI Description
Diagram
High-Level Assessment
Files changed (7)
|
Code Review by Qodo
1. Custom zoom runs lose their chosen order
|
…he pictures match - --levels runs in the order given (a level named twice runs once: the report is keyed by level). - board_of_best only where the video and the full-size final_sharp show the same focus: no camera-side autofocus, or its pass finished in the video.
|
/review |
|
Code review by qodo was updated up to the latest commit 3b448aa |
Timed pulses on the wire move the stock lens less than the run's DVRIP holds (held 0.10-0.15 s longer), so two zoom-out references stopped 0.2 short of the run's zoom and the zoom-match guard dropped their % of best. The reference now nudges on in 0.1 s pulses, the same way, until the board reports the zoom the run reached (at most 4). The guard stays.
|
/review |
|
Code review by qodo was updated up to the latest commit 2eda2d1 |
…es the run's zoom)
…irmware's ONVIF PTZ (#41) The twin harness now drives both cameras over ONVIF as well as DVRIP. PROTOCOL.md records what the stock firmware does with ONVIF PTZ and Imaging calls on the lens wire. This is the ONVIF counterpart of #38/#39. The majestic side is widgetii/majestic#953 and the conformance tests are OpenIPC/onvif-tt#12, both merged. ### uart-bridge - **`scripts/onvif_ptz.py`** (new) offers the same `step`/`mark`/`close` as the DVRIP controller. - ZoomTile/ZoomWide go out as PTZ ContinuousMove at ±1 and then Stop. FocusNear/FocusFar go out as Imaging continuous Move at ±1 and then Imaging Stop. - SOAP goes through onvif-tt's `DUT`, imported from a checkout the way python-dvr is. - The hold is timed from the request, not from the answer. Stock can answer more than a second after its frame is already on the wire; timed from the answer, a 2.8 s hold zoomed for 4.07 s. - **`dvrip_twin.py`** gets `--transport dvrip|onvif`, `--onvif-tt`, `--stock-onvif-port` (8899) and `--openipc-onvif-port` (80, credentials from `--openipc-http`). The report records the transport; the verdict and table are unchanged. - **Tests:** a fake DUT checks that each step lands on the right service, that the hold is timed from the request, and that an unknown command is refused (74 passed). - **TWIN.md:** new section *7. Driving both cameras over ONVIF*. ### xm-uart/PROTOCOL.md: *Driven over ONVIF (stock)* Measured with the board's UART captured (`captures/onvif-stock.jsonl.gz`): - **PTZ ContinuousMove:** zoom ± sends zoom in/out once. Pan/tilt sends right/left/up/down at 0x3F. Speed and Timeout are ignored, and the move runs until Stop. Zoom and pan together send the pan frame, then the zoom frame. - **PTZ Stop** stops the lens whatever its flags. A zero velocity sends nothing. - **Imaging Move:** + is focus near (cmd2 0x80), − is far. - **RelativeMove, GotoHome and GotoPreset** move nothing. - **Timing:** frames go out 0.45–0.8 s after the request. The section also lists the stock firmware's ONVIF quirks and how majestic deliberately differs. ### Lockstep result: `captures/onvif-twin-ref.json` Command: `dvrip_twin.py --transport onvif --reference`, all levels. | Level | Stock zoom | OpenIPC zoom | OpenIPC AF done | |---|---|---|---| | X1.0 | 1.0 | 1.0 | 9.2 s | | X2.0 | 2.2 | 2.2 | 6.6 s | | X3.0 | 3.1 | 3.1 | 8.1 s | | X4.0 | 4.0 | 4.0 | 8.1 s | | X5.0 | 5.0 | 5.0 | 6.6 s | | out-X4.0 | 3.9 | 3.8 | 8.1 s | | out-X3.0 | 2.9 | 2.9 | 8.6 s | | out-X2.0 | 2.0 | 2.0 | 7.6 s | | out-X1.5 | 1.4 | 1.4 | 8.7 s | | out-X1.0 | 1.0 | 1.0 | 9.7 s | - **Zoom:** the two cameras land within 0.1 at every level, with the same commands over ONVIF. - **Focus nudge:** a manual focus nudge (an Imaging Move) moved both lenses, and neither was followed by a refocus.
Extends
uart-bridge/scripts/dvrip_twin.py(#38) with X1.0, zoom-out levels, and a measure of where each lens board's own tracking leaves focus.What's new
--levels out-X4.0 out-X3.0 out-X2.0 out-X1.5 out-X1.0. Each settles at the tele end, then zooms out for the full range less the level's zoom-in hold. The default run is still the zoom-in levels.at +2s. For each camera, the picture 1.5–2.8 s after the stop, before majestic-af's pass starts (3 s), as a fraction of that camera's best./ptzpulse moves this lens irregularly;What it found
The stock firmware stays blurred after a zoom-out, at 0–7 % of its best at X1.0–X2.8. Full-size centre sharpness:
On OpenIPC the board's own focus falls the same way, and majestic-af then fixes it.
The cause is the zoom gear's slack: the board sets focus from its zoom count, and after a zoom-out the lens falls short of that count. majestic-af #18 now ends every zoom-out with a short zoom-in. The board's own focus 2 s after a zoom-out, as a fraction of the settled picture:
Captures
xm-uart/captures/dvrip-twin-inout-before.json: zoom-in and zoom-out levels with references, majestic-af xm-uart: compute the focus checksum over the bytes actually sent #17.xm-uart/captures/dvrip-twin-inout-after.json: the same levels on majestic-af pelcodtui: add Pelco-D configuration interface #18.Tests
uv run pytest: 70 passed. New tests cover the zoom-out moves and the board-only window.