ml/gen: 确定性老师(碰撞次数计时 + resetSession)、pos 任务冻结 J6、--consensus 邻域共识过滤、Dr 类、README(高性能机器运行说明)
This commit is contained in:
+20
-2
@@ -1,5 +1,7 @@
|
||||
/* M1 数据生成器(2026-10-17,方案 §4)
|
||||
* node ml/gen/gen_dataset.cjs --n 500 --seed 1 --out ml/data/shard_0001.jsonl
|
||||
* node ml/gen/gen_dataset.cjs --n 500 --seed 1 --out ml/data/shard_0001.jsonl [--consensus 4]
|
||||
* --consensus k:邻域共识过滤。起点不变、目标位置各扰动 5 mm 造 k 个邻居跑老师,原任务路径若与多数邻居
|
||||
* 不在同一绕行类(pathdev.sameClass),整条样本 keep=false(why=consensus)。成本约 (1+k) 倍。
|
||||
* 每行一条任务:采样 → 老师 → 距离下界认证过滤 → 局部时间律(50 Hz)→ 写出。
|
||||
* 认证不过的样本也写出(keep=false + 原因),供 stats 统计丢弃率;训练只用 keep=true。 */
|
||||
'use strict';
|
||||
@@ -9,6 +11,8 @@ const N = +args.n || 100, SEED = +args.seed || 1, OUT = args.out || 'ml/data/sha
|
||||
const { S, ArmIK } = require('../../tests/route_bench_setup.cjs')();
|
||||
const sampler = require('./sampler.cjs')(S, SEED * 7919 + 13);
|
||||
const teach = require('./teacher.cjs')(S, ArmIK);
|
||||
const { sameClass } = require('./pathdev.cjs');
|
||||
const K_CONS = +args.consensus || 0;
|
||||
const LEVER = S.leverBounds(4000);
|
||||
const cert = require('./cert.cjs')(S, { lever: LEVER });
|
||||
const { timeParam } = require('./timelaw.cjs');
|
||||
@@ -24,12 +28,26 @@ for (let i = 0; i < N; i++) {
|
||||
q0: task.q0.map(r3), T: task.T.map(r3), R: task.R, fp };
|
||||
if (!t.ok) { rec.keep = false; rec.why = t.why; fs.writeSync(fd, JSON.stringify(rec) + '\n'); continue; }
|
||||
const c0 = performance.now();
|
||||
const c = cert.path(t.pts);
|
||||
let c = null;
|
||||
if (t.ptsJ6Frozen) { const cf = cert.path(t.ptsJ6Frozen); if (cf.ok) { t.pts = t.ptsJ6Frozen; t.travel = t.travelOf(t.pts); c = cf; rec.j6Frozen = true; } }
|
||||
if (!c) c = cert.path(t.pts);
|
||||
if (task.cat === 'D' && t.reached) rec.cat = 'Dr'; // "不可达"采样其实可达:单独记类,不当停靠样本
|
||||
Object.assign(rec, { path: t.pts.map(q => q.map(r3)), reached: t.reached, err: r3(t.err), oerr: r3(t.oerr), travel_deg: r3(t.travel),
|
||||
plan_ms: Math.round(t.ms), blocked: t.blocked, poseRelaxed: t.poseRelaxed, detour: t.detour,
|
||||
cert: { ok: c.ok, queries: c.queries, minGap: r3(c.minGap), ms: Math.round(performance.now() - c0), why: c.why || null, failAt: c.failAt == null ? null : c.failAt } });
|
||||
/* 训练可用:认证通过;D 类允许未到达(停靠),其余类必须到达;poseRelaxed 的 pose 样本降为 pos */
|
||||
rec.keep = c.ok && (t.reached || task.cat === 'D');
|
||||
if (rec.keep && K_CONS > 0 && t.reached) {
|
||||
let agree = 0, valid = 0;
|
||||
for (let k = 0; k < K_CONS; k++) {
|
||||
const u = [sampler.rnd() - 0.5, sampler.rnd() - 0.5, sampler.rnd() - 0.5], n = Math.hypot(u[0], u[1], u[2]);
|
||||
const nb = teach(Object.assign({}, task, { T: task.T.map((v, j) => v + 5 * u[j] / n) }));
|
||||
if (!nb.ok || !nb.reached) continue;
|
||||
valid++; if (sameClass(t.pts, nb.ptsJ6Frozen && rec.j6Frozen ? nb.ptsJ6Frozen : nb.pts, task.mode)) agree++;
|
||||
}
|
||||
rec.consensus = { agree, valid };
|
||||
if (valid >= 2 && agree * 2 < valid) { rec.keep = false; rec.why = 'consensus'; }
|
||||
}
|
||||
if (t.poseRelaxed && task.mode === 'pose') { rec.mode = 'pos'; rec.R = null; rec.demoted = true; rec.reached = t.err < 1; }
|
||||
if (rec.keep) { const tp = timeParam(t.pts); rec.traj = tp.traj.map(q => q.map(r3)); rec.exec_s = r3(tp.steps * 0.02); }
|
||||
fs.writeSync(fd, JSON.stringify(rec) + '\n');
|
||||
|
||||
Reference in New Issue
Block a user