3ad29356c9
集成通用机器人数值接口、本机控制桥、LeRobot 插件和统一键盘遥操作。采用离线 CoACD 全臂碰撞配方 revision 4、局部装配区切分与结构自接触,限制直接关节位姿写入并保留安全看门狗。同步版本号、变更记录、来源许可证和兼容性验证。
55 lines
2.3 KiB
Python
55 lines
2.3 KiB
Python
"""Run the installed upstream's pure methods, without constructing a hardware robot."""
|
|
|
|
import ast
|
|
import importlib.metadata
|
|
import json
|
|
import unittest
|
|
from pathlib import Path
|
|
from typing import Any
|
|
|
|
import numpy as np
|
|
|
|
|
|
class UpstreamKinematicsTests(unittest.TestCase):
|
|
def test_actual_061_methods_match_shared_wheel_fixture(self):
|
|
self.assertEqual(importlib.metadata.version("lerobot"), "0.6.1")
|
|
path = importlib.metadata.distribution("lerobot").locate_file(
|
|
"lerobot/robots/lekiwi/lekiwi.py"
|
|
)
|
|
tree = ast.parse(path.read_text())
|
|
robot = next(
|
|
node for node in tree.body if isinstance(node, ast.ClassDef) and node.name == "LeKiwi"
|
|
)
|
|
names = {"_degps_to_raw", "_raw_to_degps", "_body_to_wheel_raw", "_wheel_raw_to_body"}
|
|
methods = [
|
|
node for node in robot.body if isinstance(node, ast.FunctionDef) and node.name in names
|
|
]
|
|
self.assertEqual({node.name for node in methods}, names)
|
|
# Only the four audited numeric methods. No imports, constructors, buses or cameras.
|
|
cls = ast.ClassDef(
|
|
name="PureKinematics",
|
|
bases=[],
|
|
keywords=[],
|
|
body=methods,
|
|
decorator_list=[],
|
|
type_params=[],
|
|
)
|
|
namespace = {"np": np, "Any": Any}
|
|
module = ast.fix_missing_locations(ast.Module(body=[cls], type_ignores=[]))
|
|
exec(compile(module, str(path), "exec"), namespace)
|
|
pure = namespace["PureKinematics"]()
|
|
fixture = json.loads(
|
|
(
|
|
Path(__file__).resolve().parents[3] / "contracts/fixtures/lekiwi-kinematics.json"
|
|
).read_text()
|
|
)
|
|
for case in fixture["cases"]:
|
|
with self.subTest(body=case["body"]):
|
|
raw = pure._body_to_wheel_raw(*case["body"])
|
|
self.assertEqual(list(raw), fixture["wheelOrder"])
|
|
self.assertEqual(list(raw.values()), case["wheelRaw"])
|
|
if max(abs(v) for v in case["wheelRaw"]) < 3000:
|
|
body = pure._wheel_raw_to_body(*case["wheelRaw"])
|
|
for observed, expected in zip(body.values(), case["body"], strict=True):
|
|
self.assertAlmostEqual(observed, expected, delta=0.02)
|