feat: integrate calibration extension and self-repair modules
This commit is contained in:
@@ -0,0 +1,91 @@
|
||||
from __future__ import annotations
|
||||
|
||||
import tempfile
|
||||
import time
|
||||
from pathlib import Path
|
||||
|
||||
import pytest
|
||||
|
||||
from cognitive_agent.application.calibration import protocol
|
||||
from cognitive_agent.application.calibration.service import CalibrationService
|
||||
|
||||
|
||||
def test_protocol_matches_android_golden_vectors() -> None:
|
||||
assert protocol.crc8(b"123456789") == 0x4B
|
||||
vectors = (
|
||||
(
|
||||
protocol.command(0x00, protocol.OP_HELLO, protocol.AXIS_ALL),
|
||||
"A1 00 01 FF 00 00 00 55",
|
||||
),
|
||||
(
|
||||
protocol.command(0x01, protocol.OP_ARM, protocol.AXIS_ALL, 0x4E37),
|
||||
"A1 01 02 FF 37 4E 00 0A",
|
||||
),
|
||||
(
|
||||
protocol.command(0x23, protocol.OP_CALIBRATE, protocol.AXIS_ALL),
|
||||
"A1 23 10 FF 00 00 00 33",
|
||||
),
|
||||
(
|
||||
protocol.command(0x24, protocol.OP_MOVE_PERMILLE, 0, 1000),
|
||||
"A1 24 11 00 E8 03 00 78",
|
||||
),
|
||||
(
|
||||
protocol.command(0x25, protocol.OP_STOP, protocol.AXIS_ALL),
|
||||
"A1 25 12 FF 00 00 00 6E",
|
||||
),
|
||||
)
|
||||
for actual, expected in vectors:
|
||||
assert actual == bytes.fromhex(expected)
|
||||
|
||||
|
||||
def test_protocol_parses_status_and_rejects_bad_crc() -> None:
|
||||
ack = protocol.parse(0x621, bytes.fromhex("B1 22 10 02 00 07 01 A9"))
|
||||
assert isinstance(ack, protocol.Ack)
|
||||
assert ack.accepted
|
||||
|
||||
controller = protocol.parse(0x622, bytes.fromhex("C1 01 00 17 07 FF 02 4E"))
|
||||
assert isinstance(controller, protocol.ControllerStatus)
|
||||
assert controller.can_ready
|
||||
assert controller.motor_ready
|
||||
assert controller.armed
|
||||
|
||||
frame = bytearray.fromhex("D1 00 F0 00 E0 01 17 40")
|
||||
frame[2] ^= 1
|
||||
with pytest.raises(protocol.ProtocolError):
|
||||
protocol.parse(0x630, bytes(frame))
|
||||
|
||||
|
||||
def test_simulation_uses_real_wire_boundary_and_generates_pose() -> None:
|
||||
with tempfile.TemporaryDirectory() as directory:
|
||||
service = CalibrationService(Path(directory))
|
||||
service.start()
|
||||
try:
|
||||
initial = service.snapshot()
|
||||
assert initial["transport"] == {
|
||||
"mode": "hardware",
|
||||
"state": "disconnected",
|
||||
"detail": "尚未连接",
|
||||
}
|
||||
|
||||
connected = service.connect_can({"mode": "simulation"})
|
||||
assert connected["transport"]["state"] == "online"
|
||||
assert connected["controller"]["can_ready"]
|
||||
assert connected["controller"]["motor_ready"]
|
||||
assert [axis["range"] for axis in connected["axes"]] == [480, 647, 917, 373]
|
||||
|
||||
service.move(0, 800)
|
||||
time.sleep(0.2)
|
||||
moving = service.snapshot()
|
||||
assert moving["controller"]["armed"]
|
||||
assert moving["axes"][0]["moving"]
|
||||
|
||||
time.sleep(0.45)
|
||||
pose = service.snapshot()["mqtt"]
|
||||
assert pose["state"] == "simulated"
|
||||
assert pose["count"] >= 1
|
||||
assert "Seat_cushion" in pose["areas"]
|
||||
|
||||
stopped = service.stop()
|
||||
assert not stopped["controller"]["armed"]
|
||||
finally:
|
||||
service.close()
|
||||
Reference in New Issue
Block a user