0d986f60bd
web-platform-ci / Standalone decision service (no cloud credentials) (push) Has been cancelled
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
集成服务器托管模型、自然语言移动与有界抓放、内置 LeKiwi URL 导入和双摄像头;同步部署契约与指定域名 iframe 白名单,保留原有物理安全、会话及调用预算防护。 更新 npm 包及锁文件版本、CHANGELOG 与发布文档。提交前 typecheck、120 项定向前端测试和 44 项后端测试通过(3 项可选跳过);真实 v2 云模型抓放仍待单独验收,不包含运行密钥或构建产物。
100 lines
3.3 KiB
Python
100 lines
3.3 KiB
Python
import unittest
|
|
|
|
from decision_server.commands import checked as motion_checked
|
|
from decision_server.language_tasks import checked, resolve_target
|
|
from decision_server.protocol import (
|
|
LANGUAGE_PRECONDITIONS,
|
|
LANGUAGE_SKILLS,
|
|
VERSION,
|
|
DecisionError,
|
|
validate_jev,
|
|
validate_plan,
|
|
)
|
|
from decision_server.protocol import (
|
|
LANGUAGE_VERSION as V,
|
|
)
|
|
|
|
|
|
def command(**changes):
|
|
return (
|
|
dict(
|
|
version=V,
|
|
action="pick_place",
|
|
value=0,
|
|
summary="搬运方块",
|
|
objectId="block",
|
|
targetId="B",
|
|
position=[],
|
|
supportId="table",
|
|
)
|
|
| changes
|
|
)
|
|
|
|
|
|
class LanguageTests(unittest.TestCase):
|
|
def test_named_and_coordinates(self):
|
|
self.assertEqual(
|
|
checked(command(), "抓起方块并搬到B区放下", motion_checked)["targetId"], "B"
|
|
)
|
|
for text, values in [
|
|
("搬到(25,50)厘米", [0.25, 0.5]),
|
|
("搬到 X=0.25 Y=0.50 Z=0.128", [0.25, 0.5, 0.128]),
|
|
]:
|
|
result = checked(command(targetId="coordinates", position=values), text, motion_checked)
|
|
self.assertEqual(
|
|
resolve_target(result["targetId"], result["position"]),
|
|
([0.25, 0.5, 0.128], "table"),
|
|
)
|
|
|
|
def test_bad_targets_and_mismatch(self):
|
|
for pos in ([0.8, 0.5], [0.25, 0.5, 0.5], [float("nan"), 0.5]):
|
|
with self.assertRaises(DecisionError):
|
|
resolve_target("coordinates", pos)
|
|
with self.assertRaisesRegex(DecisionError, "command_mismatch"):
|
|
checked(
|
|
command(targetId="coordinates", position=[0.25, 0.6]),
|
|
"搬到(0.25,0.50)",
|
|
motion_checked,
|
|
)
|
|
for text in [
|
|
"不要搬到 B 区",
|
|
"搬到指定位置",
|
|
"前进0.5米然后搬到 B 区",
|
|
"搬到 A 区或者 B 区",
|
|
]:
|
|
self.assertEqual(checked(command(), text, motion_checked)["action"], "clarify")
|
|
|
|
def test_multiple_or_contradictory_coordinates_rejected(self):
|
|
for instruction in ["搬到(0.25,0.5)然后到(0.25,0.6)", "搬到 B 区 (0.25,0.5)"]:
|
|
with self.assertRaises(DecisionError):
|
|
checked(command(), instruction, motion_checked)
|
|
|
|
def test_v2_does_not_weaken_v1(self):
|
|
plan = dict(
|
|
version=V,
|
|
objectId="block",
|
|
goalId="placement",
|
|
summary="计划",
|
|
steps=[
|
|
dict(skill=s, precondition=LANGUAGE_PRECONDITIONS[s], onFailure="stop")
|
|
for s in LANGUAGE_SKILLS
|
|
],
|
|
)
|
|
validate_plan(plan, LANGUAGE_SKILLS, V)
|
|
with self.assertRaises(DecisionError):
|
|
validate_plan(plan, LANGUAGE_SKILLS, VERSION)
|
|
d = dict(
|
|
version=V,
|
|
choice="stow",
|
|
grasp="empty",
|
|
diagnosis="none",
|
|
recovery="continue",
|
|
noul="allow",
|
|
score="good",
|
|
reason="verified_progress",
|
|
)
|
|
validate_jev(d, ["stow", "stop"], V)
|
|
for field, value in [("noul", "yes"), ("score", 100), ("choice", "carry")]:
|
|
with self.assertRaises(DecisionError):
|
|
validate_jev(d | {field: value}, ["stow", "stop"], V)
|