refactor: 重构行为决策逻辑以集中控制特殊状态行为

将特殊状态检查和行为决策集中到 `resolveBehaviorDecision` 方法中
- 新增 `BehaviorDecision` 数据类封装行为决策
- 在到达、检测状态变化等场景中使用统一决策逻辑
- 修复特殊状态下自动充电未正确取消的问题
This commit is contained in:
2026-04-24 19:11:06 +08:00
parent b5b5d0ad5b
commit fb9dba913d

View File

@@ -55,6 +55,12 @@ class MainActivity : AppCompatActivity(), OnRobotReadyListener, TtsListener, OnG
OnDetectionStateChangedListener, OnReposeStatusChangedListener, SharedPreferences.OnSharedPreferenceChangeListener, OnDetectionStateChangedListener, OnReposeStatusChangedListener, SharedPreferences.OnSharedPreferenceChangeListener,
OnRequestPermissionResultListener, OnBatteryStatusChangedListener, OnMovementStatusChangedListener, OnRequestPermissionResultListener, OnBatteryStatusChangedListener, OnMovementStatusChangedListener,
OnCurrentPositionChangedListener { OnCurrentPositionChangedListener {
private data class BehaviorDecision(
val skipArrivalAnnouncement: Boolean,
val allowAutoRecharge: Boolean,
val allowDoorWorkflow: Boolean,
val allowIdleGreeting: Boolean
)
private lateinit var robot: Robot private lateinit var robot: Robot
private lateinit var binding: ActivityMainBinding private lateinit var binding: ActivityMainBinding
@@ -431,16 +437,22 @@ class MainActivity : AppCompatActivity(), OnRobotReadyListener, TtsListener, OnG
if (taskController.handleNotificationArrival(location)) { if (taskController.handleNotificationArrival(location)) {
return return
} }
if (isSpecialStateEnabled() && taskController.currentTask.isEmpty()) { val behavior = resolveBehaviorDecision()
if (behavior.skipArrivalAnnouncement) {
Log.i("MainActivity", "Special state: arrival announcement skipped at $location.") Log.i("MainActivity", "Special state: arrival announcement skipped at $location.")
if (behavior.allowAutoRecharge) {
scheduleAutoRechargeAfterIdleArrival()
}
return return
} }
val text = "已到达$location" val text = "已到达$location"
val ttsRequest = TtsRequest.create(text, false, language = TtsRequest.Language.ZH_CN) val ttsRequest = TtsRequest.create(text, false, language = TtsRequest.Language.ZH_CN)
robot.speak(ttsRequest) robot.speak(ttsRequest)
Log.i("MainActivity", "Arrived at $location, announcement sent.") Log.i("MainActivity", "Arrived at $location, announcement sent.")
if (behavior.allowAutoRecharge) {
scheduleAutoRechargeAfterIdleArrival() scheduleAutoRechargeAfterIdleArrival()
} }
}
override fun onDetectionStateChanged(state: Int) { override fun onDetectionStateChanged(state: Int) {
latestDetectionState = state latestDetectionState = state
@@ -490,10 +502,9 @@ class MainActivity : AppCompatActivity(), OnRobotReadyListener, TtsListener, OnG
Log.i("MainActivity", "Detection event handled by task controller.") Log.i("MainActivity", "Detection event handled by task controller.")
return return
} }
val isSpecialState = isSpecialStateEnabled() val behavior = resolveBehaviorDecision()
val isIdleTask = taskController.currentTask.isEmpty() || taskController.currentTask == "speech"
val atHomeBase = robotEventHandler.normalizeLocation(lastArrivalLocation) == "homebase" val atHomeBase = robotEventHandler.normalizeLocation(lastArrivalLocation) == "homebase"
val canHandleDoor = isIdleTask && atHomeBase && !taskController.isLeavingHomeBase && !isSpecialState val canHandleDoor = behavior.allowDoorWorkflow && atHomeBase && !taskController.isLeavingHomeBase
if (canHandleDoor) { if (canHandleDoor) {
when (state) { when (state) {
DETECTED -> { DETECTED -> {
@@ -522,7 +533,7 @@ class MainActivity : AppCompatActivity(), OnRobotReadyListener, TtsListener, OnG
} }
} }
} }
if (isIdleTask && !atHomeBase && state == DETECTED && !isSpecialState && !isTtsSpeaking) { if (behavior.allowIdleGreeting && !atHomeBase && state == DETECTED && !isTtsSpeaking) {
val hour = java.util.Calendar.getInstance().get(java.util.Calendar.HOUR_OF_DAY) val hour = java.util.Calendar.getInstance().get(java.util.Calendar.HOUR_OF_DAY)
val greeting = when (hour) { val greeting = when (hour) {
in 6..11 -> "早上好" in 6..11 -> "早上好"
@@ -586,6 +597,9 @@ class MainActivity : AppCompatActivity(), OnRobotReadyListener, TtsListener, OnG
if (key == specialStateKey) { if (key == specialStateKey) {
val isSpecial = isSpecialStateEnabled() val isSpecial = isSpecialStateEnabled()
Log.i("MainActivity", "Special state pref changed: $isSpecial, currentTask: ${taskController.currentTask}") Log.i("MainActivity", "Special state pref changed: $isSpecial, currentTask: ${taskController.currentTask}")
if (isSpecial) {
cancelAutoRecharge("special_state_enabled")
}
} }
if (key == LiveKitManager.PREF_KEY_URL || if (key == LiveKitManager.PREF_KEY_URL ||
key == LiveKitManager.PREF_KEY_ROOM || key == LiveKitManager.PREF_KEY_ROOM ||
@@ -749,7 +763,7 @@ class MainActivity : AppCompatActivity(), OnRobotReadyListener, TtsListener, OnG
} }
private fun scheduleAutoRechargeAfterIdleArrival() { private fun scheduleAutoRechargeAfterIdleArrival() {
if (!isAutoRechargeAllowedTask()) { if (!shouldAutoRechargeAfterIdleArrival()) {
return return
} }
if (robotEventHandler.normalizeLocation(lastArrivalLocation) == "homebase") { if (robotEventHandler.normalizeLocation(lastArrivalLocation) == "homebase") {
@@ -758,7 +772,7 @@ class MainActivity : AppCompatActivity(), OnRobotReadyListener, TtsListener, OnG
autoRechargeJob?.cancel() autoRechargeJob?.cancel()
autoRechargeJob = mainScope.launch { autoRechargeJob = mainScope.launch {
delay(10_000L) delay(10_000L)
if (!isAutoRechargeAllowedTask()) { if (!shouldAutoRechargeAfterIdleArrival()) {
return@launch return@launch
} }
if (robotEventHandler.normalizeLocation(lastArrivalLocation) == "homebase") { if (robotEventHandler.normalizeLocation(lastArrivalLocation) == "homebase") {
@@ -769,11 +783,26 @@ class MainActivity : AppCompatActivity(), OnRobotReadyListener, TtsListener, OnG
} }
} }
private fun isAutoRechargeAllowedTask(): Boolean { private fun shouldAutoRechargeAfterIdleArrival(): Boolean {
if (isSpecialStateEnabled()) {
return false
}
val task = taskController.currentTask.trim().lowercase() val task = taskController.currentTask.trim().lowercase()
return task.isEmpty() || task == "speech" return task.isEmpty() || task == "speech"
} }
private fun resolveBehaviorDecision(): BehaviorDecision {
val task = taskController.currentTask.trim().lowercase()
val isSpecialState = isSpecialStateEnabled()
val isIdleTask = task.isEmpty() || task == "speech"
return BehaviorDecision(
skipArrivalAnnouncement = isSpecialState && task.isEmpty(),
allowAutoRecharge = !isSpecialState && isIdleTask,
allowDoorWorkflow = !isSpecialState && isIdleTask,
allowIdleGreeting = !isSpecialState && isIdleTask
)
}
private fun cancelAutoRecharge(reason: String) { private fun cancelAutoRecharge(reason: String) {
if (autoRechargeJob?.isActive == true) { if (autoRechargeJob?.isActive == true) {
Log.i("MainActivity", "Auto recharge canceled: $reason") Log.i("MainActivity", "Auto recharge canceled: $reason")