feat(lekiwi): release V0.10.1 初步集成 LeKiwi,优化碰撞模型
集成通用机器人数值接口、本机控制桥、LeRobot 插件和统一键盘遥操作。采用离线 CoACD 全臂碰撞配方 revision 4、局部装配区切分与结构自接触,限制直接关节位姿写入并保留安全看门狗。同步版本号、变更记录、来源许可证和兼容性验证。
This commit is contained in:
@@ -0,0 +1,55 @@
|
||||
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());
|
||||
}
|
||||
});
|
||||
Reference in New Issue
Block a user