feat(lekiwi): release V0.10.1 初步集成 LeKiwi,优化碰撞模型
集成通用机器人数值接口、本机控制桥、LeRobot 插件和统一键盘遥操作。采用离线 CoACD 全臂碰撞配方 revision 4、局部装配区切分与结构自接触,限制直接关节位姿写入并保留安全看门狗。同步版本号、变更记录、来源许可证和兼容性验证。
This commit is contained in:
@@ -0,0 +1,65 @@
|
||||
import copy
|
||||
import json
|
||||
import unittest
|
||||
from pathlib import Path
|
||||
|
||||
from mujoco_control_bridge import protocol as p
|
||||
from mujoco_control_bridge.client import SimRobotClient
|
||||
|
||||
FIXTURE = json.loads(
|
||||
(Path(__file__).resolve().parents[2] / "contracts/fixtures/single-joint.json").read_text()
|
||||
)
|
||||
|
||||
|
||||
class ProtocolTests(unittest.TestCase):
|
||||
def test_shared_fixture(self):
|
||||
descriptor = p.descriptor(FIXTURE["descriptor"])
|
||||
p.observation(FIXTURE["observation"], descriptor)
|
||||
action = p.action(FIXTURE["validAction"], descriptor)
|
||||
p.same_identity(action, FIXTURE["identity"])
|
||||
for invalid in FIXTURE["invalidActions"]:
|
||||
with self.subTest(invalid["label"]), self.assertRaises(p.RobotError) as caught:
|
||||
action = p.action({**FIXTURE["validAction"], **invalid["patch"]}, descriptor)
|
||||
p.same_identity(action, FIXTURE["identity"])
|
||||
self.assertEqual(caught.exception.code, invalid["code"])
|
||||
|
||||
def test_finite_clamp_and_extra_fields(self):
|
||||
for value in (float("nan"), float("inf"), True, "0", 10**1000):
|
||||
with self.subTest(value=str(value)[:20]), self.assertRaises(p.RobotError):
|
||||
p.values({"slider.position": value}, FIXTURE["descriptor"]["actionChannels"])
|
||||
self.assertEqual(
|
||||
p.values({"slider.position": 20}, FIXTURE["descriptor"]["actionChannels"], True),
|
||||
{"slider.position": 1},
|
||||
)
|
||||
for raw in ('{"x":1,"x":2}', '{"x":NaN}', '{"x":Infinity}', "["):
|
||||
with self.assertRaises(p.RobotError):
|
||||
p.loads(raw)
|
||||
|
||||
def test_unknown_units_capabilities_versions(self):
|
||||
for mutation in ("unit", "frame", "capability", "fingerprint"):
|
||||
descriptor = copy.deepcopy(FIXTURE["descriptor"])
|
||||
if mutation == "unit":
|
||||
descriptor["actionChannels"][0]["unit"] = "deg"
|
||||
elif mutation == "frame":
|
||||
descriptor["frame"] = "unknown"
|
||||
elif mutation == "fingerprint":
|
||||
descriptor["modelFingerprint"] = "not-sha"
|
||||
else:
|
||||
descriptor["capabilities"]["training"] = True
|
||||
with self.subTest(mutation), self.assertRaises(p.RobotError):
|
||||
p.descriptor(descriptor)
|
||||
|
||||
def test_only_local_endpoints_and_token_not_in_url(self):
|
||||
for endpoint in (
|
||||
"https://127.0.0.1",
|
||||
"http://evil.test",
|
||||
"http://user:token@127.0.0.1",
|
||||
"http://localhost/?token=secret",
|
||||
"http://localhost/path",
|
||||
):
|
||||
with self.subTest(endpoint), self.assertRaises(ValueError):
|
||||
SimRobotClient(endpoint, token="test-only-not-a-real-secret")
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
unittest.main()
|
||||
Reference in New Issue
Block a user