Files
Mujoco_WASM/web_platform/e2e/lekiwi.gripper.spec.ts
T
chenlin 3ad29356c9
web-platform-ci / TypeScript, lint, unit, build (push) Has been cancelled
web-platform-ci / Playwright E2E (push) Has been cancelled
lekiwi-compatibility / cpu-compatibility (push) Has been cancelled
feat(lekiwi): release V0.10.1 初步集成 LeKiwi,优化碰撞模型
集成通用机器人数值接口、本机控制桥、LeRobot 插件和统一键盘遥操作。采用离线 CoACD 全臂碰撞配方 revision 4、局部装配区切分与结构自接触,限制直接关节位姿写入并保留安全看门狗。同步版本号、变更记录、来源许可证和兼容性验证。
2026-09-20 14:42:30 +08:00

56 lines
2.5 KiB
TypeScript

import { expect, test } from '@playwright/test';
import { resolve } from 'node:path';
import { writeFile } from 'node:fs/promises';
import type {} from '../physics/runner';
test('真实 WASM:夹爪两侧指尖覆盖、开度方向和物体阻挡,不能只检查关节数值', async ({
page,
}, info) => {
const errors: string[] = [];
page.on('pageerror', (error) => errors.push(error.message));
await page.goto('/physics/runner.html');
await page.waitForFunction(() => Boolean(window.lekiwiPhysics));
await page.evaluate((path) => window.lekiwiPhysics.boot(path), `/@fs${resolve('build/lekiwi')}`);
try {
const result = await page.evaluate(() => window.lekiwiPhysics.gripperCollisionChecks());
console.log('gripper contacts', JSON.stringify(result));
await writeFile(info.outputPath('gripper-contacts.json'), JSON.stringify(result, null, 2));
await writeFile(
info.outputPath('gripper-scene.xml'),
await page.evaluate(() => window.lekiwiPhysics.xml()),
);
expect(result.finite).toBe(true);
for (const tip of result.coverage) {
expect(
tip.contacts.some((c) =>
c.other.startsWith(
tip.name === 'fixed_tip'
? '__lekiwi_cad_Wrist_Roll_08c-v1__'
: '__lekiwi_cad_Moving_Jaw_08d-v1__',
),
),
tip.name,
).toBe(true);
}
for (const state of result.openings) {
expect(Math.abs(state.actual - state.target)).toBeLessThan(0.01);
expect(state.contacts).toEqual([]);
}
expect(result.openings[0].separation).toBeGreaterThan(0);
expect(result.openings[0].separation).toBeLessThan(0.002);
expect(result.openings[1].separation).toBeGreaterThan(result.openings[0].separation + 0.02);
expect(result.openings[2].separation).toBeGreaterThan(result.openings[1].separation + 0.01);
expect(result.gapContacts).toEqual([]); // a hull must not seal the open space
expect(result.obstruction.maxContacts).toBeGreaterThan(0);
expect(result.obstruction.maxPenetration).toBeLessThan(0.0015);
expect(result.obstruction.actual).toBeGreaterThan(result.obstruction.target + 0.03);
expect(result.obstruction.contacts.length).toBeGreaterThan(0);
for (const contact of result.obstruction.contacts)
expect(contact.distance).toBeGreaterThan(-0.0002);
expect(result.fingerSelfContacts).toBeGreaterThan(0);
expect(errors).toEqual([]);
} finally {
await page.evaluate(() => window.lekiwiPhysics.dispose());
}
});