观测控制 本页只读过程数据缓存,不连接、不重启、不停 PDO 循环
未开始
链路 —
AL —
热改周期走 /api/motor/period(循环每拍重读的变量,全程喂狗不断流,随时可调、可反复调)。
低于 1ms 档后端自动用自旋节拍,会占满一个 CPU 核;从站固件修好前别低于 1ms —— 实测
0.25 / 0.125ms 档 GD32 顶到 99.5%,CAN 到帧率 λ 从 4000/s 塌到 149/s(瓶颈在从站不在主站,
只看主站达成率会整条看漏)。
刷新率 实测 = Δcycles/Δt;名义 = 1000/period_ms 仅作对照,两者差值就是软件调度开销
单电机状态刷新
—Hz
slot_period_ms —
CAN 到帧率 λ
—/s
Δglobal_seq (u32)
真丢帧
—帧/拍
主站 seq 空洞 · GD32 OVF(抽样单拍值)
从站 CPU 负载
—
load_perm · age —
撕裂 / 重入
—
rx_torn / pdo_reentry
本页请求耗时
—ms
本页→代理→native 最慢一个请求的往返(≠节拍耗时)
判读:达成率 < 100% = 节拍被软件拖住;λ ÷ 实测Hz = 每拍到达几帧 CAN(当前 1ms 档实测 6 帧/拍)。
drop 不判好坏:它是段 1/段 3 那个"最近一帧"单格被未取先覆的次数,
而单格每拍只能发布 1 帧;且自增点在 STATUS 过滤之前(ethercat_can_bridge.cpp:398
对 :435),所以每拍到的 6 帧全算进来 → 恒等于 λ − 实测Hz,零独立信息量。
这些帧并没有丢:STATUS 由段 2 按槽常驻上报,其余进段 4 覆盖窗口(实测 lost/OVF 均 0)。
drop 哪天才有权报警:让只走单格的帧(版本/节点应答)承担可靠投递时。
真丢帧逐层看:① CAN 控制器 err/TEC/REC;② CAN 软件 RX 队列满(深度 16)的
rx_drop_count —— 只在 ESP32 /can/feedback 有,过程数据里没有;
③ 段 4 覆盖窗口 主站侧按 seq 空洞算的 rx_batch.lost(step/2−1,
发布值恒为偶数,按 step−1 会把每帧虚报成丢 1 个);④ 段 4 GD32 侧未取先覆
rx_batch.pending(= OVF,与 ③ 是两个独立仪表,正常应当同步增长);
⑤ CAN 取帧撕裂 rx_torn。③④ 是本页 10Hz 抽样看到的单拍值,只能当下界。
撕裂 / 重入是饱和计数(到 65535 停),封顶时只能报下界。
实时曲线 滚动 90s · 紫 = 实测 PDO Hz(左轴) · 青 = 单拍 p50 µs(右轴)
总线与从站 /api/status · /api/native/health · state.head
窗口自适应:win_bases 是当前收缩出的接收窗口基址数,
单槽刷新 = period_ms × win_bases.length;开机首圈先扫全表(6 拍)。
桥接计数 state.bridge · 桥全局,无按通道拆分 / 无 TEC·REC
过程数据里没有逐通道 TEC/REC —— 没有的就显示 —,
不编 0 让"总线正常"和"没这个数据"长得一模一样。
收到的东西 ① 电机状态槽 state.motors[] · 48B STATUS 解码(DBC Motor_CAN_FD v0.74)
逐槽原始 hex(48B 全长,16B 一行、多列排)
—
「速度参考」= RT_Velocity,是内部斜坡参考值而非实测转速,
不能拿去回答"三轴实际是否同步"。InitStatus 显示 — 表示这条链路没送
B32-35 —— 补 0 会把"无数据"显示成"初始化正常"。
收到的东西 ② 密排整轮 + 长帧事件 rxraw.parsed · 1.6.21 密排:段2整轮槽 + 段3长帧变更
本拍新帧 / seq 空洞 / GD32 OVF —
本页帧样本 —
密排整轮槽(GD32 每拍原样拷出 count×56B:node ch online dlc seq + 48B STATUS)。
末列「本拍新数据」:是 = seq 比上一拍大(差分命中,状态真变了);否 = seq 未变,固件本拍跳过填充。
按子码汇总(每 sub 一行的采样次数 / 最近载荷)
密排整轮(1.6.21):接 N 个电机本拍就发 N 个状态,空槽不发送。
STATUS 全在上方状态槽解码;本表是同一拍的线级原样(seq / online / 前 8B 载荷),
用来核对"差分是否真的跳过了未变电机"。
长帧(CONFIG 24B / 版本应答):段 3「最近一帧」,内容变了才进上面的事件表
(主站按 ch/dlc/id/data 逐字节比对,相同不重复上报)。逐字节的真凭实据在下面第 ③ 区。
本表看不到的还有三层 —— CAN 控制器 err/TEC/REC、GD32 软件 RX 队列满丢(深度 16,
只在 ESP32 /can/feedback 有)、CAN 取帧撕裂 rx_torn。
逐层对账跑 scripts/can_bridge_reconcile.py。
收到的东西 ③ 原始接收窗口 + 长帧 + 逐拍环 /api/motor/rxraw · state.xrx · /api/motor/dbg(全为只读缓存拷贝)
layout:dense=1.6.21 密排整轮 / win=1.6.15 定长覆盖窗口 / slim=变长 / old=旧布局,
解析器必须按 layout 选,否则拿变长游标解定长窗口会整片错位。
xrx 长帧完整载荷(kv 里那行是截断的,这里不截)
—
逐拍环未开启。开启后实测每次约 160KB(后端 RING=2048 拍),
只在需要看抖动分布时开,别常年挂着 —— 仪表本身也是负载。
接收区原始字节 —— dense:8B 整轮头 + count×56B 槽;win:44B/槽 覆盖窗口
—