优化前端,优化前端指令,优化自定义控制

This commit is contained in:
minghanchen
2026-08-24 09:40:16 +08:00
parent fff7657fea
commit 8d05815773
130 changed files with 5543 additions and 2206 deletions
+154
View File
@@ -1,6 +1,8 @@
from __future__ import annotations
import json
import os
import tempfile
import unittest
from pathlib import Path
from unittest.mock import patch
@@ -109,6 +111,8 @@ class DriverSeatNativeCanTests(unittest.TestCase):
"seat.set_driver_heating_native",
"seat.set_driver_massage_native",
"seat.set_driver_axis_native",
"seat.set_driver_position_native",
"seat.recall_driver_memory_native",
},
)
for capability in capabilities.values():
@@ -151,6 +155,16 @@ class DriverSeatNativeCanTests(unittest.TestCase):
{"axis": "height", "direction": "stop", "duration_ms": 500},
"driver",
),
"seat driver position 3": (
"seat.set_driver_position_native",
{"slot": 3},
"driver",
),
"seat driver memory recall 2": (
"seat.recall_driver_memory_native",
{"slot": 2},
"driver",
),
}
for utterance, expected in cases.items():
with self.subTest(utterance=utterance):
@@ -196,6 +210,10 @@ class DriverSeatNativeCanTests(unittest.TestCase):
"seat.set_driver_axis_native",
{"axis": "height", "direction": "up", "duration_ms": 500},
),
"主驾座椅调整到记忆位置3": (
"seat.recall_driver_memory_native",
{"slot": 3},
),
}
for utterance, expected in cases.items():
with self.subTest(utterance=utterance):
@@ -356,6 +374,142 @@ class DriverSeatNativeCanTests(unittest.TestCase):
self.assertEqual(command["repeat"], {"count": 3, "period_ms": 100})
self.assertNotIn("special_handler", command["signals"])
def test_memory_aliases_compile_the_same_learned_twenty_frame_sequence(self) -> None:
commands = []
for capability in (
"seat.set_driver_position_native",
"seat.recall_driver_memory_native",
):
with self.subTest(capability=capability):
_, plan = self._compile(capability, {"slot": 3})
command = plan["spec"]["commands"][0]
commands.append(command)
self.assertEqual(command["signals"]["frame_id"], "0x4C1")
self.assertEqual(
command["signals"]["special_handler"],
"driver_seat_memory_recall",
)
special = json.loads(command["signals"]["special_parameters"])
self.assertEqual(len(special["frame_sequence"]), 20)
self.assertEqual(
special["frame_sequence"][0::2],
["16 9A 66 3C 76 04 06 00"] * 10,
)
self.assertEqual(
special["frame_sequence"][1::2],
["15 02 C6 3E 2A C8 FF FF"] * 10,
)
self.assertEqual(special["period_ms"], 50)
public = self.runtime.command_frame_public(command)
self.assertEqual(public["sequence"]["frame_count"], 20)
self.assertTrue(
public["sequence"]["requires_fresh_initialized_0x494"]
)
self.assertEqual(
commands[0]["signals"]["special_parameters"],
commands[1]["signals"]["special_parameters"],
)
def test_memory_executor_requires_initialized_status_and_alternates_frames(self) -> None:
config, plan = self._compile(
"seat.recall_driver_memory_native", {"slot": 2}
)
initialized = CanFrame(
0x494,
bytes((0, 0, 0, 0, 0, 0, 0, 0x3C)),
channel=1,
is_fd=True,
bitrate_switch=True,
)
bus = _FakeBus([initialized, initialized])
with patch("cognitive_agent.application.native_can_runtime.time.sleep"):
report = NativeCanExecutor(
lambda: bus, feedback_timeout_ms=1, feedback_required=False
).execute(self.runtime, plan, config)
self.assertEqual(report["spec"]["status"], "succeeded")
self.assertEqual(len(bus.sent), 20)
self.assertTrue(all(frame.is_fd and frame.bitrate_switch for frame in bus.sent))
self.assertEqual(
[frame.data[0] for frame in bus.sent], [0x16, 0x15] * 10
)
self.assertEqual(
[frame.data for frame in bus.sent[0::2]],
[bytes.fromhex("16 9A 66 3C 76 04 06 00")] * 10,
)
self.assertEqual(
[frame.data for frame in bus.sent[1::2]],
[bytes.fromhex("15 02 A6 AE 00 C8 FF FF")] * 10,
)
telemetry = report["spec"]["results"][0]["telemetry"]
self.assertFalse(telemetry["physical_effect_confirmed"])
self.assertEqual(len(telemetry["sent_frames"]), 20)
uninitialized_bus = _FakeBus(
[CanFrame(0x494, bytes(8), channel=1, is_fd=True)]
)
rejected = NativeCanExecutor(
lambda: uninitialized_bus,
feedback_timeout_ms=1,
feedback_required=False,
).execute(self.runtime, plan, config)
self.assertEqual(rejected["spec"]["status"], "failed")
self.assertFalse(uninitialized_bus.sent)
def test_memory_sequence_stops_immediately_on_send_failure(self) -> None:
config, plan = self._compile(
"seat.set_driver_position_native", {"slot": 1}
)
initialized = CanFrame(
0x494, bytes((0, 0, 0, 0, 0, 0, 0, 0x3C)), channel=1
)
bus = _FakeBus([initialized], fail_on_calls={4})
with patch("cognitive_agent.application.native_can_runtime.time.sleep"):
report = NativeCanExecutor(
lambda: bus, feedback_timeout_ms=1, feedback_required=False
).execute(self.runtime, plan, config)
self.assertEqual(report["spec"]["status"], "failed")
self.assertEqual(bus.send_calls, 4)
self.assertEqual(len(bus.sent), 3)
def test_memory_compile_rejects_missing_or_malformed_learned_slots(self) -> None:
with tempfile.TemporaryDirectory() as directory:
path = Path(directory) / "driver_memory.json"
path.write_text(
json.dumps(
{
"version": 1,
"positions": {
"1": {
"payload_15": "15 00",
"payload_16": "16 00 00 00 00 00 00 00",
}
},
}
),
encoding="utf-8",
)
with patch.dict(
os.environ,
{"COGNITIVE_AGENT_DRIVER_SEAT_MEMORY_PATH": str(path)},
):
config = self.runtime.build_function_config(
"seat",
[_native_action("seat.recall_driver_memory_native", {"slot": 1})],
"req-bad-memory",
"local_rules",
)
with self.assertRaisesRegex(NativeCanCompileError, "8-byte"):
self.runtime.compile(config)
missing = self.runtime.build_function_config(
"seat",
[_native_action("seat.recall_driver_memory_native", {"slot": 2})],
"req-missing-memory",
"local_rules",
)
with self.assertRaisesRegex(NativeCanCompileError, "has not been learned"):
self.runtime.compile(missing)
def test_compiler_fails_closed_for_wrong_seat_or_invalid_parameters(self) -> None:
for target in ("passenger", "front_right"):
action = _native_action(