feat(巡逻): 增强巡逻功能并支持循环、等待和非停止模式
- 在 MqttManager 中解析巡逻命令的 times、waiting 和 nonStop 参数 - 修改 MainActivity.startPatrolMode 以接收新参数并管理巡逻循环 - 实现 moveToCurrentPatrolTarget 和 scheduleNextPatrolMove 方法以支持连续巡逻 - 添加离开 Home Base 的状态跟踪以避免逻辑冲突 - 注释掉原有的 NavPatrol 调用以准备自定义巡逻实现
This commit is contained in:
@@ -56,6 +56,11 @@ class MainActivity : AppCompatActivity(), OnRobotReadyListener, TtsListener, OnG
|
||||
private var receptionDestination: String = ""
|
||||
private var patrolRoute: List<String> = 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<String>) {
|
||||
fun startPatrolMode(route: List<String>, 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) {
|
||||
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
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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<String> = 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("")
|
||||
}
|
||||
|
||||
@@ -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
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user