feat: synchronize CH1 vehicle control and feedback
This commit is contained in:
@@ -177,7 +177,7 @@ class SeatServiceIntegrationTests(unittest.TestCase):
|
||||
route = next(event for event in result["trace_events"] if event["stage"] == "domain_route")
|
||||
self.assertEqual(route["details"]["domains"], ["climate"])
|
||||
|
||||
def test_openai_output_is_not_rewritten_by_local_semantic_planner(self) -> None:
|
||||
def test_openai_unscoped_passenger_target_is_rewritten_to_driver_ch1(self) -> None:
|
||||
model_output = {
|
||||
"detected_domains": ["seat"],
|
||||
"requests": [
|
||||
@@ -199,26 +199,31 @@ class SeatServiceIntegrationTests(unittest.TestCase):
|
||||
|
||||
with patch.object(self.service.openai, "interpret", return_value=model_output) as interpret:
|
||||
parsed, provider, notice = self.service._interpret(
|
||||
"车上太闷了", "openai", context
|
||||
"关闭座椅通风", "openai", context
|
||||
)
|
||||
|
||||
self.assertEqual(parsed["decision_summary"], ["model-owned-plan"])
|
||||
self.assertEqual(parsed["model_requests"], model_output["requests"])
|
||||
self.assertEqual(parsed["actions"], [])
|
||||
self.assertEqual(
|
||||
parsed["actions"],
|
||||
parsed["deferred_requests"],
|
||||
[
|
||||
{
|
||||
"target": "passenger",
|
||||
"function": "ventilation",
|
||||
"state": "off",
|
||||
"requested_level": None,
|
||||
"domain": "seat",
|
||||
"capability": "seat.set_driver_ventilation_native",
|
||||
"target_scope": "driver",
|
||||
"desired_change": "deactivate",
|
||||
"requested_value": "off",
|
||||
"parameters": {"state": "off"},
|
||||
"reason": "model-owned-plan",
|
||||
"execution_backend": "native_can",
|
||||
}
|
||||
],
|
||||
)
|
||||
self.assertEqual(provider, f"openai:{self.service.openai.model}")
|
||||
self.assertIsNone(notice)
|
||||
interpret.assert_called_once_with(
|
||||
"车上太闷了", context, self.service.capability_context
|
||||
"关闭座椅通风", context, self.service.capability_context
|
||||
)
|
||||
|
||||
def test_explicit_gpt_failure_falls_back_to_local_rules(self) -> None:
|
||||
@@ -680,7 +685,7 @@ class SeatServiceIntegrationTests(unittest.TestCase):
|
||||
conversation_id,
|
||||
)
|
||||
second = self.service.process(
|
||||
"靠背再向后一点", "openai", conversation_id
|
||||
"副驾靠背再向后一点", "openai", conversation_id
|
||||
)
|
||||
saved = self.service.process(
|
||||
"将当前状态保存为零重力模式", "openai", conversation_id
|
||||
@@ -767,24 +772,35 @@ class SeatServiceIntegrationTests(unittest.TestCase):
|
||||
apply_context = interpret.call_args_list[4].args[1]
|
||||
self.assertEqual(apply_context["presets"][0]["name"], "零重力模式")
|
||||
|
||||
def test_missing_target_defaults_to_passenger(self) -> None:
|
||||
def test_missing_target_defaults_to_driver_ch1(self) -> None:
|
||||
result = self.service.process("打开座椅通风", provider="local")
|
||||
|
||||
self.assertEqual(result["status"], "succeeded")
|
||||
operation = result["function_config"]["spec"]["operations"][0]
|
||||
self.assertEqual(operation["target"]["instance"], "passenger")
|
||||
self.assertEqual(operation["target"]["zone"], "driver")
|
||||
self.assertEqual(
|
||||
operation["capability"], "seat.set_driver_ventilation_native"
|
||||
)
|
||||
self.assertEqual(
|
||||
result["command_plan"]["spec"]["commands"][0]["bus"],
|
||||
"body_can",
|
||||
)
|
||||
|
||||
def test_explicit_driver_target_is_rejected(self) -> None:
|
||||
def test_explicit_driver_target_uses_ch1_native_can(self) -> None:
|
||||
result = self.service.process("打开主驾座椅通风", provider="local")
|
||||
|
||||
self.assertEqual(result["status"], "needs_confirmation")
|
||||
self.assertIsNone(result["function_config"])
|
||||
questions = [
|
||||
item["question"] for item in result["intent_ir"]["spec"]["ambiguities"]
|
||||
]
|
||||
self.assertTrue(any("仅控制副驾" in question for question in questions))
|
||||
self.assertEqual(result["status"], "succeeded")
|
||||
operation = result["function_config"]["spec"]["operations"][0]
|
||||
self.assertEqual(operation["target"]["zone"], "driver")
|
||||
self.assertEqual(
|
||||
operation["capability"], "seat.set_driver_ventilation_native"
|
||||
)
|
||||
command = result["command_plan"]["spec"]["commands"][0]
|
||||
self.assertEqual(command["bus"], "body_can")
|
||||
self.assertEqual(command["signals"]["frame_id"], "0x431")
|
||||
self.assertEqual(command["signals"]["feedback_ids"], "0x4FA")
|
||||
|
||||
def test_model_driver_target_is_rejected(self) -> None:
|
||||
def test_model_driver_target_is_replaced_by_ch1_native_can(self) -> None:
|
||||
model_output = {
|
||||
"detected_domains": ["seat"],
|
||||
"requests": [
|
||||
@@ -808,12 +824,13 @@ class SeatServiceIntegrationTests(unittest.TestCase):
|
||||
"打开主驾座椅通风", "openai", "conv-driver-rejected"
|
||||
)
|
||||
|
||||
self.assertEqual(result["status"], "needs_confirmation")
|
||||
self.assertIsNone(result["function_config"])
|
||||
questions = [
|
||||
item["question"] for item in result["intent_ir"]["spec"]["ambiguities"]
|
||||
]
|
||||
self.assertTrue(any("仅控制副驾" in question for question in questions))
|
||||
self.assertEqual(result["status"], "succeeded")
|
||||
operation = result["function_config"]["spec"]["operations"][0]
|
||||
self.assertEqual(operation["target"]["zone"], "driver")
|
||||
self.assertEqual(
|
||||
operation["capability"], "seat.set_driver_ventilation_native"
|
||||
)
|
||||
self.assertFalse(result["deferred_requests"])
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
|
||||
@@ -476,7 +476,7 @@ class ProtocolSignatureFakeBus:
|
||||
self.received: deque[CanFrame] = deque()
|
||||
self.closed = False
|
||||
if signature:
|
||||
self.received.append(CanFrame(0x301, bytes.fromhex("10 00 00 00 00 00 F0 D0")))
|
||||
self.received.append(CanFrame(0x301, bytes.fromhex("10 00 00 00 00 00 F0 F0")))
|
||||
for motor in range(4):
|
||||
self.received.append(
|
||||
CanFrame(0x302, bytes([motor, 0, 0x08, 0, 0, 0, 0, 0]))
|
||||
@@ -1684,7 +1684,7 @@ class T2GHardwareTests(unittest.TestCase):
|
||||
|
||||
self.assertIs(prepared, bus)
|
||||
self.assertFalse(telemetry["programmed_this_request"])
|
||||
self.assertEqual(telemetry["firmware_revision"], 13)
|
||||
self.assertEqual(telemetry["firmware_revision"], 15)
|
||||
self.assertEqual(bus.sent, [])
|
||||
self.assertEqual(telemetry["max_hall_counts"], [480, 374, 917, 647])
|
||||
self.assertFalse(bus.closed)
|
||||
@@ -1755,7 +1755,7 @@ class T2GHardwareTests(unittest.TestCase):
|
||||
guard.prepare_bus()
|
||||
|
||||
message = str(raised.exception)
|
||||
self.assertIn("firmware_revision=0 (expected 13)", message)
|
||||
self.assertIn("firmware_revision=0 (expected 15)", message)
|
||||
self.assertIn("missing_frame_ids=0x306", message)
|
||||
self.assertIn("max_hall_counts=480,374,917,647", message)
|
||||
self.assertTrue(bus.closed)
|
||||
|
||||
Reference in New Issue
Block a user