桌面 APP 下 ECAT motor 发送只走 pywebview ESF1→native TCP; 删除桥内 HTTP/JSON 回落。附延迟测量与 pack 自测脚本与规格文档。
4.7 KiB
4.7 KiB
feature, status, updated, branch, commits
| feature | status | updated | branch | commits |
|---|---|---|---|---|
| pdo-fast-send | delivered | 2026-09-23 | main | working-tree (uncommitted; dual-repo main authorized) |
PDO 快发(网页按钮 → 原生入队二进制直通)
Report
What was built — 桌面 APP(esp32_app)下,电机页 EtherCAT 链路的全部 motor
发送强制走 ESF1 二进制快发:JS desktopEcatSendRaw → GUI 进程
ecat_send_raw 打包 → native 持久 TCP 口(health.fast_send_port)入 g_cmd_q。
已堵死慢发:Python 桥删除 HTTP send_raw / JSON motor/send 回落;前端在
hasDesktopFastSend() 为真时失败直接 ok:false,不再 api("motor/send")。
浏览器无壳标签仍走 HTTP /ecat/api/motor/send(脚本/诊断同理)。布局:请求
magic ESF1 + nframes + 72B/帧;响应 FSOK 8 字节。
Verification —
build_native.batPASS;healthfast_send_port存在,loop=1 wkc=3scripts/test_esf_pack.pyPASS;py_compile esp32_server.pyPASSnode --checkdesktop-bridge / transport-ecat / transport / main PASSscripts/check_esf_latency.py:TCP FSOK p50≈0.046–0.08ms(HTTP 对照仍在 native 路由上)- 源码检查:
ecat_send_raw_frames无motor/send/http_send_raw回落;sendViaFastOrJson有桥时不调api("motor/send") test_motor_transport.mjs68/68 PASS(Node 无 pywebview → 走 HTTP 契约路径)test_motor_refresh.mjs62/62 PASS- 独立评审 CRITICAL/MAJOR(锁/静态缓冲/端口缓存)此前已修复
Journey log —
- 用户期望「纳秒进 PDO」不可达;可压的是控制面,入队后仍是 250µs 一拍 PDO
- pywebview JS→Python hop 仍在,TCP 快发已把 native 侧压到 ~50–80µs
- 沙箱拦
git worktree add→ 用户明确授权双仓 main - 持久 TCP 必须 send+recv 整段持锁,否则 FSOK 错配
- 2026-09-23:用户要求堵死慢发——桌面强制 ESF1、桥内删除 HTTP/JSON 回落; 浏览器/脚本仍保留 native HTTP 路由
[S1] Problem
电机控制台在 EtherCAT 链路上点发送时,信号要走很长控制面才进 ecat_native
的 g_cmd_q:浏览器 fetch→代理→JSON,桌面 APP 再叠 pywebview 桥。用户要
「一点按钮极短 CPU 周期内进 PDO」。纳秒不可达;native 入队后到总线由 PDO
周期决定(250µs 档),可压缩的是控制面。HTTP 路径还存在 8–12ms 调度尾部,
必须防止桌面壳误走慢路径。
[S2] Design
目标行为(2026-09-23 修订:堵死慢发)
- 桌面 APP + 桥可用:ECAT 全部 motor 发送 只走 ESF1 TCP;失败
ok:false, 无 HTTP/JSON 回落。 - Python
ecat_send_raw_frames:仅 TCP ESF1(失败可重探端口后再试 TCP 一次)。 - 浏览器标签(无 pywebview):仍走
/ecat/api/motor/send。 - native
/api/motor/send与/api/motor/send_raw保留(浏览器/诊断脚本)。 - UI 不新增专用开关;
sendHint/desktopBridgeLabel反映通道形态。 - 不承诺纳秒。
工作区(用户授权覆盖)
- ESP32 与 tools/ecat 均在 main 上改(2026-09-23 授权;沙箱拦 worktree add)。
- native:
tools/ecat/ecat_native.c+build_native.bat。
二进制帧布局(小端)
请求:
u32 magic = 0x31465345 /* ESF1 */
u8 nframes /* 1..64 */
u8 flags
u16 reserved
repeat nframes: /* 72B each */
u8 ch, u8 dlc, u16 pad, u32 id, u8 data[64]
响应:u32 FSOK(0x4B4F5346) | u8 ok | u8 queued | u16 backlog
Native
127.0.0.1bind(0)快发口;health 增加fast_send_port。- 持久连接读 ESF1 →
parse_esf→ 共用enqueue_frames→ FSOK。 - HTTP
/api/motor/send_raw与 JSON/api/motor/send仍服务浏览器/脚本。 send_raw解析缓冲为栈上(HTTP 多线程)。
GUI 桥(esp32_server.py)
pack_esf/unpack_fsok;_GuiApi.ecat_send_raw。- 仅持久 TCP;connect+sendall+recv 整段持锁。
- 失败:关 socket +
g_fast_send_port=0→ 重探后再试 TCP 一次 → 仍败则 ok:false。 - 无 HTTP/JSON 回落代码。
前端
desktop-bridge.js:desktopEcatSendRaw/hasDesktopFastSend。transport-ecat.js:sendViaFastOrJson有桥时只调快发。- 缓存版本
?v=20260923i。
Out of Scope
- 纳秒;共享内存;预装载+位触发;浏览器强制禁 HTTP;删除 native JSON 路由; 改 PDO 周期;WiFi 链路。
Tasks
- T1: native 快发口 +
/api/motor/send_raw+ health 字段 (covers: S2) - T2: Python 打包 +
ecat_send_rawTCP-only(无回落) (covers: S2; depends: T1) - T3: desktop-bridge + transport-ecat 有桥强制快发 (covers: S2; depends: T2)
- T4: 延迟脚本 + 文档 + 堵死慢发修订 (covers: S2; depends: T1)