ml: 数据生成 + 可微运动学对拍 + MeanFlow/WTA 策略与闭环仿真 + APG/挖错/ONNX 导出与运行手册

- M1 数据生成器:采样/老师/距离下界认证/时间律/统计/一致性门禁;确定性老师(碰撞次数计时 + resetSession)、pos 任务冻结 J6、--consensus 邻域共识过滤、Dr 类。
- 全流程代码与运行手册:数据打包/可微运动学与对拍/MeanFlow+WTA 模型/闭环仿真/APG/挖错循环/ONNX 导出;webapp 策略运行时 ik-policy.js、?policy=1 接入、tests/policy_bench.cjs;ik-solver 增 pairList/clusterExport/criticalPairs/pairGap/leverTable。
This commit is contained in:
Hark
2026-10-18 06:40:23 +08:00
committed by cbb
parent cc43b3d3be
commit 2a0a2e55ad
56 changed files with 2990 additions and 97 deletions
+21
View File
@@ -0,0 +1,21 @@
/* M1 统计:node ml/gen/stats.cjs ml/data/shard_*.jsonl > ml/data/stats.json */
'use strict';
const fs = require('fs');
const files = process.argv.slice(2);
const by = {}; let total = 0, keep = 0, steps = 0, samples = 0, padTail = 0;
const q = a => { a.sort((x, y) => x - y); return a.length ? { p50: +a[a.length >> 1].toFixed(1), p90: +a[Math.floor(a.length * 0.9)].toFixed(1), max: +a[a.length - 1].toFixed(1) } : null; };
const plan = [], certMs = [], travel = [], exec = [], gaps = [];
for (const f of files) for (const line of fs.readFileSync(f, 'utf8').split('\n')) {
if (!line) continue; const r = JSON.parse(line); total++;
const k = r.cat + '/' + r.mode; const b = by[k] = by[k] || { n: 0, reached: 0, certFail: 0, keep: 0, demoted: 0, consensusDrop: 0, j6Frozen: 0 };
b.n++; if (r.reached) b.reached++; if (r.cert && !r.cert.ok) b.certFail++; if (r.demoted) b.demoted++; if (r.why === 'consensus') b.consensusDrop++; if (r.j6Frozen) b.j6Frozen++;
if (r.plan_ms != null) plan.push(r.plan_ms); if (r.cert) certMs.push(r.cert.ms); if (r.cert) gaps.push(r.cert.minGap);
if (r.keep) { b.keep++; keep++; travel.push(r.travel_deg); exec.push(r.exec_s);
const n = r.traj.length - 1; steps += n; const s = Math.floor(n / 3) + 1; samples += s;
for (let t = 0; t <= n; t += 3) if (t + 16 > n) padTail++; }
}
const out = { tasks: total, keep, keepRate: +(keep / total).toFixed(3), byCatMode: by,
planMs: q(plan), certMs: q(certMs), vertexMinGapMm: q(gaps), travelDeg: q(travel), execS: q(exec),
samplesEvery3: samples, samplesPerTask: +(samples / keep).toFixed(1), paddedSampleShare: +(padTail / samples).toFixed(3),
projectedSamplesFor50k: Math.round(samples / total * 50000) };
console.log(JSON.stringify(out, null, 1));