movement: smooth animated moves (move duration, observable intermediate positions) + proactive cruise (glide while the LLM thinks, collision-safe, reported back); verified mission with gpt-5.6-luna

This commit is contained in:
opencode
2026-08-08 21:36:32 +03:00
parent 1cb3bdc46e
commit 315762363e
6 changed files with 201 additions and 11 deletions
+61
View File
@@ -1,7 +1,9 @@
"""Tests for the testbed bridge: tool behavior over the in-process transport."""
import asyncio
import base64
import io
import math
import pytest
from aicc.client import AICCClient
@@ -186,3 +188,62 @@ async def test_single_source_of_truth():
world = dumped["world"]
assert set(world.keys()) == {"name", "kind"}
assert "beacon" not in dumped
async def test_animated_move_is_smooth_and_observable(bridge):
"""A move with duration glides: a concurrent client sees intermediate
positions, and the final displacement is exact."""
# A transport is a single session: one per client.
t1 = InProcessTransport.start(bridge)
t2 = InProcessTransport.start(bridge)
async with t1, t2:
mover = AICCClient(t1)
viewer = AICCClient(t2)
async with mover, viewer:
await mover.handshake()
await viewer.handshake()
start = (await mover.call_tool("proprioception", {})).output["position"]
assert start["x"] == 1.5 and start["z"] == 1.5
move_task = asyncio.create_task(
mover.call_tool("move", {"forward": 2.0, "duration": 0.8})
)
await asyncio.sleep(0.25)
mid = (await viewer.call_tool("proprioception", {})).output["position"]
# Moving along the 45-degree diagonal: strictly between start and end.
assert 1.5 < mid["x"] < 3.5 and 1.5 < mid["z"] < 3.5
res = (await move_task).output
assert res["moved"] == pytest.approx(2.0, abs=1e-3)
assert res["position"]["x"] == pytest.approx(
1.5 + 2.0 * math.sin(math.radians(45)), abs=1e-3
)
assert res["duration"] == 0.8
async def test_animated_move_stops_on_collision(bridge):
t = InProcessTransport.start(bridge)
async with t:
client = AICCClient(t)
async with client:
await client.handshake()
bridge.world.capsule.yaw_deg = 180.0 # straight at the north wall
res = (
await client.call_tool("move", {"forward": 5.0, "duration": 0.6})
).output
assert res["collision"] is True
assert res["moved"] < 5.0
assert res["position"]["z"] == pytest.approx(
bridge.world.capsule.radius, abs=1e-3
)
async def test_move_accepts_duration_zero_default(bridge):
t = InProcessTransport.start(bridge)
async with t:
client = AICCClient(t)
async with client:
await client.handshake()
res = (await client.call_tool("move", {"forward": 1.0})).output
assert res["moved"] == pytest.approx(1.0)
assert res["duration"] == 0.0