[6.6.0][FSM] feat: 状态栏增加 FSM 状态展示;

This commit is contained in:
aibingbing
2024-08-13 18:48:17 +08:00
parent 1edb4392c9
commit a419361def
8 changed files with 228 additions and 27 deletions

View File

@@ -32,6 +32,7 @@ import com.zhjt.mogo_core_function_devatools.status.flow.autopilot.RouteDownload
import com.zhjt.mogo_core_function_devatools.status.flow.autopilot.SpeedImpl
import com.zhjt.mogo_core_function_devatools.status.flow.autopilot.SteerImpl
import com.zhjt.mogo_core_function_devatools.status.flow.can.CanImpl
import com.zhjt.mogo_core_function_devatools.status.flow.fsm.FSMImpl
import com.zhjt.mogo_core_function_devatools.status.flow.gps.GpsImpl
import com.zhjt.mogo_core_function_devatools.status.flow.ipc.IpcImpl
import com.zhjt.mogo_core_function_devatools.status.flow.rtk.RTKImpl
@@ -91,6 +92,7 @@ object StatusManager {
is GpsStatus -> GpsImpl(ctx)
is TracingStatus -> TracingImpl(ctx)
is RTKStatus -> RTKImpl(ctx)
is FSMStatus -> FSMImpl(ctx)
is OverViewStatus -> OverViewImpl(ctx)
is SteerStatus -> SteerImpl(ctx)
is AcceleratorStatus -> AcceleratorImpl(ctx)

View File

@@ -6,7 +6,16 @@ import com.zhjt.mogo_core_function_devatools.status.entity.RouteState.RouteFaile
import com.zhjt.mogo_core_function_devatools.status.entity.RouteState.RouteNone
import com.zhjt.mogo_core_function_devatools.status.entity.RouteState.RouteStart
import com.zhjt.mogo_core_function_devatools.status.entity.TracingStatus.Tracing
import com.zhjt.mogo_core_function_devatools.status.entity.TracingStatus.Tracing.*
import com.zhjt.mogo_core_function_devatools.status.entity.TracingStatus.Tracing.MAP_DATA_EXIST
import com.zhjt.mogo_core_function_devatools.status.entity.TracingStatus.Tracing.MAP_DATA_NOT_EXIST
import com.zhjt.mogo_core_function_devatools.status.entity.TracingStatus.Tracing.MAP_TRA_TYPE
import com.zhjt.mogo_core_function_devatools.status.entity.TracingStatus.Tracing.ROUTE_FAILED
import com.zhjt.mogo_core_function_devatools.status.entity.TracingStatus.Tracing.ROUTE_LOADED
import com.zhjt.mogo_core_function_devatools.status.entity.TracingStatus.Tracing.TRACK_FINDED
import com.zhjt.mogo_core_function_devatools.status.entity.TracingStatus.Tracing.TRACK_LOADED
import com.zhjt.mogo_core_function_devatools.status.entity.TracingStatus.Tracing.TRACK_LOAD_FAIL
import com.zhjt.mogo_core_function_devatools.status.entity.TracingStatus.Tracing.TRACK_NOT_EXIST
import com.zhjt.mogo_core_function_devatools.status.entity.TracingStatus.Tracing.UNKNOWN
sealed class Status(var rawData: Any? = null) {
@@ -119,6 +128,46 @@ class RTKStatus(var desc: String = "", var state: Int): Status() {
override fun isException(): Boolean = desc.isEmpty() || (desc == "RTK") && state != 0
}
/**
* FSM模块状态码定义
*/
enum class FSMStateCode {
IpcNotConnected,
NoneExist,
Normal,
Error
}
/**
* FSM模块状态
*/
class FSMStatus(var state: FSMStateCode, var desc: String = ""): Status() {
override fun equals(other: Any?): Boolean {
if (javaClass != other?.javaClass) return false
other as FSMStatus
if (desc != other.desc) {
return false
}
if (state != other.state) {
return false
}
return true
}
override fun hashCode(): Int {
var result = desc.hashCode()
result = 31 * result + state.hashCode()
return result
}
override fun toString(): String {
return "FSMStatus(state=$state, desc='$desc', raw_data=$rawData)"
}
override fun isException(): Boolean = state == FSMStateCode.Error
}
/**
* Can总线
*/

View File

@@ -0,0 +1,91 @@
package com.zhjt.mogo_core_function_devatools.status.flow.fsm
import android.content.Context
import com.mogo.eagle.core.function.api.autopilot.IMoGoAutopilotStatusListener
import com.mogo.eagle.core.function.api.autopilot.IMoGoFsm2024Listener
import com.mogo.eagle.core.function.call.autopilot.CallerAutoPilotControlManager
import com.mogo.eagle.core.function.call.autopilot.CallerAutoPilotStatusListenerManager
import com.mogo.eagle.core.function.call.autopilot.CallerFsm2024ListenerManager
import com.mogo.eagle.core.utilcode.mogo.logger.CallerLogger
import com.mogo.eagle.core.utilcode.mogo.logger.scene.SceneConstant.Companion.M_DEVA
import com.zhjt.mogo.adas.data.AdasConstants
import com.zhjt.mogo_core_function_devatools.status.entity.FSMStateCode
import com.zhjt.mogo_core_function_devatools.status.entity.FSMStatus
import com.zhjt.mogo_core_function_devatools.status.flow.IFlow
import fsm.Fsm2024
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
import java.util.concurrent.atomic.AtomicReference
internal class FSMImpl(ctx: Context) : IFlow<FSMStatus>(ctx), IMoGoAutopilotStatusListener,
IMoGoFsm2024Listener {
companion object {
const val TAG = "FSMImpl"
}
private val fsmStateMsg by lazy {
AtomicReference<Fsm2024.FSMStateMsg>(null)
}
private fun getDesc(): String {
return fsmStateMsg.get()?.pilotNotStandbyReason ?: ""
}
private fun getStateCode(): FSMStateCode {
val isIpcConnected = CallerAutoPilotStatusListenerManager.isConnect()
if (!isIpcConnected) {
return FSMStateCode.IpcNotConnected
} else if (fsmStateMsg.get()?.pilotStandbyFlag == true) {
// TODO 判断是否有 FSM 模块
return FSMStateCode.Normal
} else {
return FSMStateCode.Error
}
}
override fun onCreate() {
send(FSMStatus(getStateCode(), getDesc()))
CallerLogger.d("$M_DEVA$TAG", "-- onCreate --")
CallerAutoPilotStatusListenerManager.addListener(TAG, this)
CallerFsm2024ListenerManager.addListener(TAG, this)
}
override fun onAutopilotIpcConnectStatusChanged(
status: AdasConstants.IpcConnectionStatus,
reason: String?
) {
super.onAutopilotIpcConnectStatusChanged(status, reason)
if (!CallerAutoPilotStatusListenerManager.isConnect()) {
CallerLogger.d("$M_DEVA$TAG", "工控机断开了....")
fsmStateMsg.set(null)
send(FSMStatus(FSMStateCode.IpcNotConnected, "工控机断开了"))
} else {
CallerLogger.d("$M_DEVA$TAG", "工控机已连接....")
launch(Dispatchers.Default) {
CallerAutoPilotControlManager.sendStatusQueryReq()
}
}
}
override fun onFSM2024State(fsmState: Fsm2024.FSMStateMsg) {
CallerLogger.d(
"$M_DEVA$TAG",
"-- fsmState[pilotStandbyFlag=${fsmState.pilotStandbyFlag}, pilotNotStandbyReason=${fsmState.pilotNotStandbyReason}] --"
)
fsmStateMsg.set(fsmState)
// TODO 判断是否有 FSM 模块
if (fsmState.pilotStandbyFlag) {
send(FSMStatus(FSMStateCode.Normal, ""))
} else {
send(FSMStatus(FSMStateCode.Error, fsmState.pilotNotStandbyReason))
}
}
override fun onDestroy() {
super.onDestroy()
CallerLogger.d("$M_DEVA$TAG", "-- onDestroy --")
CallerAutoPilotStatusListenerManager.removeListener(TAG)
CallerFsm2024ListenerManager.removeListener(TAG)
}
}

View File

@@ -14,6 +14,7 @@ internal class StatusModel : ViewModel() {
const val TAG = "StatusModel"
val DEFAULTS = Pair(null, ArrayList<Status>().also {
it += OverViewStatus()
it += FSMStatus(FSMStateCode.IpcNotConnected, "")
it += IpcStatus(CallerAutoPilotStatusListenerManager.isConnect())
it += CanStatus(false)
// it += TracingStatus(UNKNOWN)

View File

@@ -1,20 +1,37 @@
package com.zhjt.mogo_core_function_devatools.status.ui.adapter
import android.content.*
import android.view.*
import android.widget.*
import androidx.core.content.*
import androidx.recyclerview.widget.*
import android.content.Context
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.ImageView
import androidx.core.content.ContextCompat
import androidx.recyclerview.widget.RecyclerView
import com.mogo.eagle.core.function.call.hmi.CallerHmiManager
import com.mogo.eagle.core.utilcode.kotlin.*
import com.mogo.eagle.core.utilcode.mogo.logger.*
import com.mogo.eagle.core.utilcode.kotlin.onClick
import com.mogo.eagle.core.utilcode.mogo.logger.CallerLogger
import com.mogo.eagle.core.utilcode.mogo.logger.scene.SceneConstant.Companion.M_DEVA
import com.zhjt.mogo_core_function_devatools.R
import com.zhjt.mogo_core_function_devatools.R.drawable
import com.zhjt.mogo_core_function_devatools.status.entity.*
import com.zhjt.mogo_core_function_devatools.status.entity.CanStatus
import com.zhjt.mogo_core_function_devatools.status.entity.FSMStateCode
import com.zhjt.mogo_core_function_devatools.status.entity.FSMStatus
import com.zhjt.mogo_core_function_devatools.status.entity.GpsStatus
import com.zhjt.mogo_core_function_devatools.status.entity.IpcStatus
import com.zhjt.mogo_core_function_devatools.status.entity.OverViewStatus
import com.zhjt.mogo_core_function_devatools.status.entity.RTKStatus
import com.zhjt.mogo_core_function_devatools.status.entity.Status
import com.zhjt.mogo_core_function_devatools.status.entity.TracingStatus.Tracing.*
import com.zhjt.mogo_core_function_devatools.status.entity.TracingStatus
import com.zhjt.mogo_core_function_devatools.status.entity.TracingStatus.Tracing.MAP_DATA_EXIST
import com.zhjt.mogo_core_function_devatools.status.entity.TracingStatus.Tracing.MAP_DATA_NOT_EXIST
import com.zhjt.mogo_core_function_devatools.status.entity.TracingStatus.Tracing.MAP_TRA_TYPE
import com.zhjt.mogo_core_function_devatools.status.entity.TracingStatus.Tracing.ROUTE_FAILED
import com.zhjt.mogo_core_function_devatools.status.entity.TracingStatus.Tracing.ROUTE_LOADED
import com.zhjt.mogo_core_function_devatools.status.entity.TracingStatus.Tracing.TRACK_FINDED
import com.zhjt.mogo_core_function_devatools.status.entity.TracingStatus.Tracing.TRACK_LOADED
import com.zhjt.mogo_core_function_devatools.status.entity.TracingStatus.Tracing.TRACK_LOAD_FAIL
import com.zhjt.mogo_core_function_devatools.status.entity.TracingStatus.Tracing.TRACK_NOT_EXIST
import com.zhjt.mogo_core_function_devatools.status.entity.TracingStatus.Tracing.UNKNOWN
import com.zhjt.mogo_core_function_devatools.status.ui.adapter.StatusAdapter.StatusViewHolder
import me.jessyan.autosize.AutoSizeCompat
@@ -116,6 +133,22 @@ internal class StatusAdapter(val ctx: Context, var data: List<Status>): Recycler
iv.background = ContextCompat.getDrawable(itemView.context, drawable.icon_dev_status_rtk_unknow)
}
}
is FSMStatus -> {
when (status.state) {
FSMStateCode.IpcNotConnected -> {
iv.setImageDrawable(null)
}
FSMStateCode.NoneExist -> {
iv.background = ContextCompat.getDrawable(itemView.context, drawable.icon_dev_status_fsm_not_exist)
}
FSMStateCode.Normal -> {
iv.background = ContextCompat.getDrawable(itemView.context, drawable.icon_dev_status_fsm_normal)
}
FSMStateCode.Error -> {
iv.background = ContextCompat.getDrawable(itemView.context, drawable.icon_dev_status_fsm_error)
}
}
}
is OverViewStatus -> {
if (status.hasException) {
iv.scaleType = ImageView.ScaleType.FIT_CENTER
@@ -128,47 +161,72 @@ internal class StatusAdapter(val ctx: Context, var data: List<Status>): Recycler
}
}
private fun getText(status: Status): String = when(status) {
is CanStatus -> "CAN:${ if (status.enabled) "状态正常" else "非正常连接" }"
is GpsStatus -> "GPS:${ if (status.enabled) "状态正常" else "非正常连接" }"
is IpcStatus -> "工控机:${ if (status.enabled) "状态正常" else "非正常连接" }"
private fun getText(status: Status): String = when (status) {
is CanStatus -> "CAN:${if (status.enabled) "状态正常" else "非正常连接"}"
is GpsStatus -> "GPS:${if (status.enabled) "状态正常" else "非正常连接"}"
is IpcStatus -> "工控机:${if (status.enabled) "状态正常" else "非正常连接"}"
// is NetStatus -> "WIFI:${ if (status.enabled) "${status.name}" else "非正常连接" }"
is RTKStatus -> when(status.desc) {
is RTKStatus -> when (status.desc) {
"RTK" ->
when(status.state) {
when (status.state) {
0 -> "RTK定位状态良好"
1 -> "RTK定位定位不可信"
2 -> "RTK定位误差增大到米级"
else -> "RTK定位状态异常"
}
"SLAM" ->
"SLAM定位状态良好"
else ->
"定位异常"
}
is FSMStatus -> when (status.state) {
FSMStateCode.IpcNotConnected -> {
"FSM:非正常连接"
}
FSMStateCode.NoneExist -> {
"FSM:无FSM模块"
}
FSMStateCode.Normal -> {
"FSM:状态正常"
}
FSMStateCode.Error -> {
"FSM:状态异常"
}
}
is TracingStatus -> {
val extra = status.state.extra
val extraDesc = if (extra != null && extra.isNotEmpty()) extra.values.joinToString(",") else ""
CallerLogger.d("$M_DEVA$TAG", "traceing_state: $status -> extra: $extraDesc :: extra: $extra")
when(status.state) {
val extraDesc =
if (extra != null && extra.isNotEmpty()) extra.values.joinToString(",") else ""
CallerLogger.d(
"$M_DEVA$TAG",
"traceing_state: $status -> extra: $extraDesc :: extra: $extra"
)
when (status.state) {
//"轨迹类型:${ if (status.state == TRACK_LOADED) "循迹" else if (status.state == ROUTE_LOADED) "自主算路" else "暂无轨迹" }"
MAP_TRA_TYPE -> {
"暂无轨迹"
}
MAP_DATA_EXIST -> "地图数据存在,正在加载${ if(extraDesc.isNotEmpty()) "\n[$extraDesc]" else "" }"
MAP_DATA_NOT_EXIST -> "地图数据存在${ if(extraDesc.isNotEmpty()) "\n[$extraDesc]" else "" }"
TRACK_FINDED -> "轨迹类型:循迹(已找到轨迹)${ if(extraDesc.isNotEmpty()) "\n[$extraDesc]" else "" }"
TRACK_LOADED -> "轨迹类型:循迹(加载成功)${ if(extraDesc.isNotEmpty()) "\n[$extraDesc]" else "" }"
TRACK_NOT_EXIST -> "轨迹类型:循迹(未找到轨迹)${ if(extraDesc.isNotEmpty()) "\n[$extraDesc]" else "" }"
TRACK_LOAD_FAIL -> "轨迹类型:循迹(加载失败)${ if(extraDesc.isNotEmpty()) "\n[$extraDesc]" else "" }"
ROUTE_LOADED -> "轨迹类型:自主算路(加载成功)${ if(extraDesc.isNotEmpty()) "\n[$extraDesc]" else "" }"
ROUTE_FAILED -> "轨迹类型:自主算路(加载失败)${ if(extraDesc.isNotEmpty()) "\n[$extraDesc]" else "" }"
MAP_DATA_EXIST -> "地图数据存在,正在加载${if (extraDesc.isNotEmpty()) "\n[$extraDesc]" else ""}"
MAP_DATA_NOT_EXIST -> "地图数据不存在${if (extraDesc.isNotEmpty()) "\n[$extraDesc]" else ""}"
TRACK_FINDED -> "轨迹类型:循迹(已找到轨迹)${if (extraDesc.isNotEmpty()) "\n[$extraDesc]" else ""}"
TRACK_LOADED -> "轨迹类型:循迹(加载成功)${if (extraDesc.isNotEmpty()) "\n[$extraDesc]" else ""}"
TRACK_NOT_EXIST -> "轨迹类型:循迹(未找到轨迹)${if (extraDesc.isNotEmpty()) "\n[$extraDesc]" else ""}"
TRACK_LOAD_FAIL -> "轨迹类型:循迹(加载失败)${if (extraDesc.isNotEmpty()) "\n[$extraDesc]" else ""}"
ROUTE_LOADED -> "轨迹类型:自主算路(加载成功)${if (extraDesc.isNotEmpty()) "\n[$extraDesc]" else ""}"
ROUTE_FAILED -> "轨迹类型:自主算路(加载失败)${if (extraDesc.isNotEmpty()) "\n[$extraDesc]" else ""}"
UNKNOWN -> "暂无轨迹"
}
}
is OverViewStatus -> {
""
}
else -> {
throw AssertionError()
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.8 KiB