From 952c5234cf779cbd110c9b19e8a7cbc8735dcc42 Mon Sep 17 00:00:00 2001 From: Sucan <632190820@qq.com> Date: Sat, 14 Mar 2026 11:43:53 +0800 Subject: [PATCH] =?UTF-8?q?feat(=E5=B7=A1=E9=80=BB):=20=E5=A2=9E=E5=BC=BA?= =?UTF-8?q?=E5=B7=A1=E9=80=BB=E5=8A=9F=E8=83=BD=E5=B9=B6=E6=94=AF=E6=8C=81?= =?UTF-8?q?=E5=BE=AA=E7=8E=AF=E3=80=81=E7=AD=89=E5=BE=85=E5=92=8C=E9=9D=9E?= =?UTF-8?q?=E5=81=9C=E6=AD=A2=E6=A8=A1=E5=BC=8F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 在 MqttManager 中解析巡逻命令的 times、waiting 和 nonStop 参数 - 修改 MainActivity.startPatrolMode 以接收新参数并管理巡逻循环 - 实现 moveToCurrentPatrolTarget 和 scheduleNextPatrolMove 方法以支持连续巡逻 - 添加离开 Home Base 的状态跟踪以避免逻辑冲突 - 注释掉原有的 NavPatrol 调用以准备自定义巡逻实现 --- .../lzwcai_terminal_temi/MainActivity.kt | 67 +++++++++++++++++-- .../lzwcai_terminal_temi/MqttManager.kt | 9 ++- .../lzwcai_terminal_temi/NavController.kt | 3 +- 3 files changed, 71 insertions(+), 8 deletions(-) diff --git a/app/src/main/java/com/example/lzwcai_terminal_temi/MainActivity.kt b/app/src/main/java/com/example/lzwcai_terminal_temi/MainActivity.kt index 78c3b76..cefb3ff 100644 --- a/app/src/main/java/com/example/lzwcai_terminal_temi/MainActivity.kt +++ b/app/src/main/java/com/example/lzwcai_terminal_temi/MainActivity.kt @@ -56,6 +56,11 @@ class MainActivity : AppCompatActivity(), OnRobotReadyListener, TtsListener, OnG private var receptionDestination: String = "" private var patrolRoute: List = emptyList() private var patrolIndex: Int = 0 + private var patrolLoopsRemaining: Int = 1 + private var patrolWaitingSeconds: Int = 3 + private var patrolNonStop: Boolean = false + private var patrolMoveJob: Job? = null + private var isLeavingHomeBase: Boolean = false @SuppressLint("SetTextI18n") override fun onCreate(savedInstanceState: Bundle?) { @@ -196,6 +201,7 @@ class MainActivity : AppCompatActivity(), OnRobotReadyListener, TtsListener, OnG return } if (isAbort) { + isLeavingHomeBase = false endNonSpecialTask("goTo aborted: $location, status=$status") return } @@ -203,6 +209,7 @@ class MainActivity : AppCompatActivity(), OnRobotReadyListener, TtsListener, OnG if (lastArrivalLocation == location && now - lastArrivalAt < 5000L) { return } + isLeavingHomeBase = false lastArrivalLocation = location lastArrivalAt = now prefs.edit().putString("current_location", location).apply() @@ -244,7 +251,7 @@ class MainActivity : AppCompatActivity(), OnRobotReadyListener, TtsListener, OnG } // Home Base logic - if (lastArrivalLocation?.lowercase() == "home base") { + if (currentTask == "" && lastArrivalLocation?.lowercase() == "home base" && !isLeavingHomeBase) { // Check if special task mode is enabled, if so, skip door logic if (isSpecialModeEnabled() && currentTask.isEmpty()) { Log.i("MainActivity", "Special task mode: Door logic skipped at Home Base.") @@ -331,15 +338,20 @@ class MainActivity : AppCompatActivity(), OnRobotReadyListener, TtsListener, OnG setCurrentTask("") } - fun startPatrolMode(route: List) { + fun startPatrolMode(route: List, times: Int = 1, waiting: Int = 3, nonStop: Boolean = false) { if (route.isEmpty()) { setCurrentTask("") return } patrolRoute = route patrolIndex = 0 + patrolLoopsRemaining = times.coerceAtLeast(1) + patrolWaitingSeconds = waiting.coerceAtLeast(0) + patrolNonStop = nonStop + patrolMoveJob?.cancel() setCurrentTask("patrol") Log.i("MainActivity", "Patrol mode started: route=${route.joinToString()}") + moveToCurrentPatrolTarget() } private fun handlePatrolArrival(location: String) { @@ -354,8 +366,50 @@ class MainActivity : AppCompatActivity(), OnRobotReadyListener, TtsListener, OnG patrolIndex = matchIndex + 1 } if (patrolIndex >= patrolRoute.size) { - Log.i("MainActivity", "Patrol route completed: ${patrolRoute.joinToString()}") - setCurrentTask("") + patrolLoopsRemaining -= 1 + if (patrolLoopsRemaining <= 0) { + Log.i("MainActivity", "Patrol route completed: ${patrolRoute.joinToString()}") + setCurrentTask("") + return + } + patrolIndex = 0 + } + scheduleNextPatrolMove() + } + + private fun moveToCurrentPatrolTarget() { + if (currentTask != "patrol") { + return + } + val target = patrolRoute.getOrNull(patrolIndex) ?: return + if (lastArrivalLocation?.equals(target, ignoreCase = true) == true) { + patrolIndex += 1 + if (patrolIndex >= patrolRoute.size) { + Log.i("MainActivity", "Patrol route completed: ${patrolRoute.joinToString()}") + setCurrentTask("") + return + } + moveToCurrentPatrolTarget() + return + } + Log.i("MainActivity", "Patrol moving to next target: $target") + if (lastArrivalLocation?.equals("home base", ignoreCase = true) == true && + !target.equals("home base", ignoreCase = true) + ) { + isLeavingHomeBase = true + } + navCon.goTo(target, false) + } + + private fun scheduleNextPatrolMove() { + patrolMoveJob?.cancel() + if (patrolNonStop || patrolWaitingSeconds <= 0) { + moveToCurrentPatrolTarget() + return + } + patrolMoveJob = mainScope.launch { + delay(patrolWaitingSeconds * 1000L) + moveToCurrentPatrolTarget() } } @@ -377,6 +431,11 @@ class MainActivity : AppCompatActivity(), OnRobotReadyListener, TtsListener, OnG if (finalTask != "patrol") { patrolRoute = emptyList() patrolIndex = 0 + patrolLoopsRemaining = 1 + patrolWaitingSeconds = 3 + patrolNonStop = false + patrolMoveJob?.cancel() + patrolMoveJob = null } } diff --git a/app/src/main/java/com/example/lzwcai_terminal_temi/MqttManager.kt b/app/src/main/java/com/example/lzwcai_terminal_temi/MqttManager.kt index 6ffe1de..b89b1ef 100644 --- a/app/src/main/java/com/example/lzwcai_terminal_temi/MqttManager.kt +++ b/app/src/main/java/com/example/lzwcai_terminal_temi/MqttManager.kt @@ -229,6 +229,9 @@ class MqttManager( "patrol" -> { speak("接到巡逻任务", "zh") val flag = obj.optBoolean("flag", true) + val times = obj.optInt("times", 1) + val waiting = obj.optInt("waiting", obj.optInt("wait", 3)) + val nonStop = obj.optBoolean("nonStop", obj.optBoolean("non_stop", false)) var patrolLocations: List = emptyList() if (flag) { Log.d(TAG, "navController.randomPatrol() called.") @@ -239,8 +242,8 @@ class MqttManager( val locations = List(locationsArray.length()) { locationsArray.getString(it) } - Log.d(TAG, "navController.NavPatrol() called with locations: $locations") - navController.NavPatrol(locations) + Log.d(TAG, "Patrol route received with locations: $locations") + // navController.NavPatrol(locations) patrolLocations = locations } else { Log.w(TAG, "Patrol command received without locations, falling back to random patrol.") @@ -250,7 +253,7 @@ class MqttManager( scope.launch(Dispatchers.Main) { val activity = context as? MainActivity if (patrolLocations.isNotEmpty()) { - activity?.startPatrolMode(patrolLocations) + activity?.startPatrolMode(patrolLocations, times, waiting, nonStop) } else { activity?.setCurrentTask("") } diff --git a/app/src/main/java/com/example/lzwcai_terminal_temi/NavController.kt b/app/src/main/java/com/example/lzwcai_terminal_temi/NavController.kt index 71e0065..f45a010 100644 --- a/app/src/main/java/com/example/lzwcai_terminal_temi/NavController.kt +++ b/app/src/main/java/com/example/lzwcai_terminal_temi/NavController.kt @@ -50,7 +50,8 @@ class NavController(private val robot: Robot) { val patrolCount = (3..minOf(6, availablePatrolLocations.size)).random() val patrolLocations = availablePatrolLocations.shuffled().take(patrolCount) Log.i(TAG, "Starting random patrol with $patrolCount locations: ${patrolLocations.joinToString()}.") - NavPatrol(patrolLocations, false, 1, 5) + // 官方 patrol 调用保留(部分版本可能无效) + // NavPatrol(patrolLocations, false, 1, 5) return patrolLocations } }