File size: 2,471 Bytes
168e232 | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 | """The release's own promises: cards load and check, tunings cannot reach the model, the model runs, the doctor works."""
from pathlib import Path
import numpy as np
import pytest
from cablepilot.cardrun import SkillGap, apply_tuning, check
from cablepilot.core.cards import CardError, load_card_text
ROOT = Path(__file__).resolve().parents[1]
CARD = """
task: t
lineage: {parent: x, by: y, why: z}
roles: [hand, head_camera]
objects:
a: {kind: toy, role: held, shape: block, movable: true}
b: {kind: box, role: site, shape: open_container, movable: false}
parts:
b.interior: {of: b, part: interior}
stages:
- {name: s1, goals: [{pre_grasp: [hand, a]}]}
- {name: s2, goals: [{grasp: [hand, a]}]}
- {name: s3, goals: [{pre_inside: [a, b.interior]}]}
- {name: s4, goals: [{release: [hand, a]}]}
done: {inside: [a, b.interior]}
"""
def test_card_checks_and_lineage():
c = load_card_text(CARD)
assert c.lineage == {"parent": "x", "by": "y", "why": "z"}
assert [s for _, s in check(c)["stages"]] == ["approach", "grasp", "carry_over", "release"]
assert "lineage" in c.to_dict()
def test_lineage_keys_are_closed():
with pytest.raises(CardError):
load_card_text(CARD.replace("why: z", "why: z, run: rm"))
def test_skill_gap_is_reported():
c = load_card_text(CARD.replace("{pre_grasp: [hand, a]}", "{on_top: [a, b.interior]}"))
with pytest.raises(SkillGap, match="on_top"):
check(c)
def test_tuning_merges_and_avoid_only_raises():
tc = {"params": {"weights": {"furniture": 5.0, "walls": 5.0, "xy": 4.0}, "funnel": {"k_xy": 3.0}}}
c = load_card_text(CARD + "costs: {per_body: {cable: {avoid: 0.1}}}\n")
out = apply_tuning(tc, c, {"params": {"funnel": {"k_xy": 2.0}}})
assert out["params"]["funnel"]["k_xy"] == 2.0 and out["params"]["weights"]["furniture"] == 5.0 # never less
def test_model_rolls_out():
from cablepilot.model.learned import LearnedCDPRModel
wm = LearnedCDPRModel.load(ROOT / "weights/stringman_g1.pt", dt=0.2)
wm.set_room(np.array([[2, 2, 2.4], [-2, 2, 2.4], [-2, -2, 2.4], [2, -2, 2.4]], float))
x = np.zeros(14)
x[2] = 1.2
wm.reset_history(x, np.zeros(5))
out = wm.rollout(None, None, np.zeros((4, 10, 5)))
assert out.shape == (4, 10, 14)
assert float(np.abs(out[..., 0:2]).max()) < 0.05 # holding still stays (nearly) still
def test_doctor_quick():
from cablepilot.rig import doctor
assert doctor(None, quick=True)["ok"]
|