diff --git a/core/function-impl/mogo-core-function-devatools/src/main/java/com/zhjt/mogo_core_function_devatools/status/StatusManager.kt b/core/function-impl/mogo-core-function-devatools/src/main/java/com/zhjt/mogo_core_function_devatools/status/StatusManager.kt index 76baf933df..85480dad7a 100644 --- a/core/function-impl/mogo-core-function-devatools/src/main/java/com/zhjt/mogo_core_function_devatools/status/StatusManager.kt +++ b/core/function-impl/mogo-core-function-devatools/src/main/java/com/zhjt/mogo_core_function_devatools/status/StatusManager.kt @@ -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) diff --git a/core/function-impl/mogo-core-function-devatools/src/main/java/com/zhjt/mogo_core_function_devatools/status/entity/Status.kt b/core/function-impl/mogo-core-function-devatools/src/main/java/com/zhjt/mogo_core_function_devatools/status/entity/Status.kt index 9a51c2a21c..221f0e1c0b 100644 --- a/core/function-impl/mogo-core-function-devatools/src/main/java/com/zhjt/mogo_core_function_devatools/status/entity/Status.kt +++ b/core/function-impl/mogo-core-function-devatools/src/main/java/com/zhjt/mogo_core_function_devatools/status/entity/Status.kt @@ -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总线 */ diff --git a/core/function-impl/mogo-core-function-devatools/src/main/java/com/zhjt/mogo_core_function_devatools/status/flow/fsm/FSMImpl.kt b/core/function-impl/mogo-core-function-devatools/src/main/java/com/zhjt/mogo_core_function_devatools/status/flow/fsm/FSMImpl.kt new file mode 100644 index 0000000000..13f33e6228 --- /dev/null +++ b/core/function-impl/mogo-core-function-devatools/src/main/java/com/zhjt/mogo_core_function_devatools/status/flow/fsm/FSMImpl.kt @@ -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(ctx), IMoGoAutopilotStatusListener, + IMoGoFsm2024Listener { + + companion object { + const val TAG = "FSMImpl" + } + + private val fsmStateMsg by lazy { + AtomicReference(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) + } +} \ No newline at end of file diff --git a/core/function-impl/mogo-core-function-devatools/src/main/java/com/zhjt/mogo_core_function_devatools/status/model/StatusModel.kt b/core/function-impl/mogo-core-function-devatools/src/main/java/com/zhjt/mogo_core_function_devatools/status/model/StatusModel.kt index 15a5e480ca..1e254e84e9 100644 --- a/core/function-impl/mogo-core-function-devatools/src/main/java/com/zhjt/mogo_core_function_devatools/status/model/StatusModel.kt +++ b/core/function-impl/mogo-core-function-devatools/src/main/java/com/zhjt/mogo_core_function_devatools/status/model/StatusModel.kt @@ -14,6 +14,7 @@ internal class StatusModel : ViewModel() { const val TAG = "StatusModel" val DEFAULTS = Pair(null, ArrayList().also { it += OverViewStatus() + it += FSMStatus(FSMStateCode.IpcNotConnected, "") it += IpcStatus(CallerAutoPilotStatusListenerManager.isConnect()) it += CanStatus(false) // it += TracingStatus(UNKNOWN) diff --git a/core/function-impl/mogo-core-function-devatools/src/main/java/com/zhjt/mogo_core_function_devatools/status/ui/adapter/StatusAdapter.kt b/core/function-impl/mogo-core-function-devatools/src/main/java/com/zhjt/mogo_core_function_devatools/status/ui/adapter/StatusAdapter.kt index a1c611de11..31703d7969 100644 --- a/core/function-impl/mogo-core-function-devatools/src/main/java/com/zhjt/mogo_core_function_devatools/status/ui/adapter/StatusAdapter.kt +++ b/core/function-impl/mogo-core-function-devatools/src/main/java/com/zhjt/mogo_core_function_devatools/status/ui/adapter/StatusAdapter.kt @@ -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): 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): 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() } diff --git a/core/function-impl/mogo-core-function-devatools/src/main/res/drawable-xhdpi/icon_dev_status_fsm_error.png b/core/function-impl/mogo-core-function-devatools/src/main/res/drawable-xhdpi/icon_dev_status_fsm_error.png new file mode 100644 index 0000000000..cc007561ff Binary files /dev/null and b/core/function-impl/mogo-core-function-devatools/src/main/res/drawable-xhdpi/icon_dev_status_fsm_error.png differ diff --git a/core/function-impl/mogo-core-function-devatools/src/main/res/drawable-xhdpi/icon_dev_status_fsm_normal.png b/core/function-impl/mogo-core-function-devatools/src/main/res/drawable-xhdpi/icon_dev_status_fsm_normal.png new file mode 100644 index 0000000000..84fe2a8c11 Binary files /dev/null and b/core/function-impl/mogo-core-function-devatools/src/main/res/drawable-xhdpi/icon_dev_status_fsm_normal.png differ diff --git a/core/function-impl/mogo-core-function-devatools/src/main/res/drawable-xhdpi/icon_dev_status_fsm_not_exist.png b/core/function-impl/mogo-core-function-devatools/src/main/res/drawable-xhdpi/icon_dev_status_fsm_not_exist.png new file mode 100644 index 0000000000..2adb8592f8 Binary files /dev/null and b/core/function-impl/mogo-core-function-devatools/src/main/res/drawable-xhdpi/icon_dev_status_fsm_not_exist.png differ