[6.4.0][启自驾指引] 部分代码提交

This commit is contained in:
renwj
2024-04-16 19:09:14 +08:00
parent e2967a2c04
commit e4de6ab743
41 changed files with 948 additions and 88 deletions

View File

@@ -59,6 +59,8 @@ import com.zhjt.mogo_core_function_devatools.perf.MoGoCpuUsageProviderImpl
import com.zhjt.mogo_core_function_devatools.report.IPCReportManager.Companion.iPCReportManager
import com.zhjt.mogo_core_function_devatools.scene.SceneManager.Companion.sceneManager
import com.zhjt.mogo_core_function_devatools.status.StatusManager
import com.zhjt.mogo_core_function_devatools.status.ui.AutoPilotLaunchBeforeView
import com.zhjt.mogo_core_function_devatools.status.ui.StatusView
import com.zhjt.mogo_core_function_devatools.strict.*
import com.zhjt.mogo_core_function_devatools.trace.TraceManager.Companion.traceManager
import com.zhjt.mogo_core_function_devatools.tts.TtsManager.Companion.ttsManager
@@ -66,6 +68,7 @@ import com.zhjt.mogo_core_function_devatools.upgrade.UpgradeManager.Companion.up
import com.zhjt.mogo_core_function_devatools.weaknetwork.DetectResultImpl
import com.zhjt.mogo_core_function_devatools.weaknetwork.WeakNetworkStrategy
import com.zhjt.service.chain.ChainLog
import java.lang.ref.WeakReference
@Route(path = MogoServicePaths.PATH_DEVA_TOOLS)
class DevaToolsProvider : IDevaToolsProvider {
@@ -80,7 +83,6 @@ class DevaToolsProvider : IDevaToolsProvider {
private val strictModeProvider by lazy { StrictModeProviderImpl() }
private val lookAroundDataProvider by lazy { MoGoLookAroundProviderImpl() }
private val mofangProvider by lazy { MoGoMoFangProviderImpl() }
@@ -94,6 +96,8 @@ class DevaToolsProvider : IDevaToolsProvider {
@Volatile
private var mDockerVersion: String? = null
private var container: WeakReference<ViewGroup>? = null
override fun init(context: Context) {
mContext = context
}
@@ -471,4 +475,20 @@ class DevaToolsProvider : IDevaToolsProvider {
override fun setNetworkMode(isDebug: Boolean) {
WeakNetworkStrategy.setDebug(isDebug)
}
override fun attachAutopilotStatusView(ctx: Context, group: ViewGroup) {
if (group.childCount > 0) {
if (group.visibility != View.VISIBLE) {
group.visibility = View.VISIBLE
}
return
}
this.container = WeakReference(group)
val child = AutoPilotLaunchBeforeView(ctx)
group.addView(child, ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT))
}
override fun getExceptionStatusBeforeLaunchAutopilot(): Int {
return StatusManager.getExceptionStatusBeforeLaunchAutopilot()
}
}

View File

@@ -23,6 +23,12 @@ import com.zhjt.mogo_core_function_devatools.status.entity.*
import com.zhjt.mogo_core_function_devatools.status.model.StatusModel
import com.zhjt.mogo_core_function_devatools.status.flow.IFlow
import com.zhjt.mogo_core_function_devatools.status.flow.OverViewImpl
import com.zhjt.mogo_core_function_devatools.status.flow.autopilot.AcceleratorImpl
import com.zhjt.mogo_core_function_devatools.status.flow.autopilot.BrakeImpl
import com.zhjt.mogo_core_function_devatools.status.flow.autopilot.DoubleFlashImpl
import com.zhjt.mogo_core_function_devatools.status.flow.autopilot.GearImpl
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.gps.GpsImpl
import com.zhjt.mogo_core_function_devatools.status.flow.ipc.IpcImpl
@@ -33,17 +39,21 @@ import kotlinx.coroutines.*
import kotlinx.coroutines.flow.*
import java.lang.ref.*
import java.util.concurrent.*
import java.util.concurrent.ThreadPoolExecutor.DiscardOldestPolicy
object StatusManager {
private const val TAG = "StatusManager"
private lateinit var model: StatusModel
private var hasInit = false
private val listeners by lazy { CopyOnWriteArrayList<IStatusListener>() }
private val listeners by lazy { ConcurrentHashMap<String, IStatusListener>() }
private var container: WeakReference<ViewGroup>? = null
private val dispatcher by lazy {
ThreadPoolExecutor(1, 2, 1, TimeUnit.MINUTES, LinkedBlockingQueue(128), Executors.defaultThreadFactory(), DiscardOldestPolicy()).asCoroutineDispatcher() + CoroutineName("stats-manager-impl")
}
private val flows: ArrayList<IFlow<out Status>> by lazy {
ArrayList()
}
@@ -77,10 +87,16 @@ object StatusManager {
is TracingStatus -> TracingImpl(ctx)
is RTKStatus -> RTKImpl(ctx)
is OverViewStatus -> OverViewImpl(ctx)
is SteerStatus -> SteerImpl(ctx)
is AcceleratorStatus -> AcceleratorImpl(ctx)
is BrakeStatus -> BrakeImpl(ctx)
is DoubleFlashStatus -> DoubleFlashImpl(ctx)
is GearStatus -> GearImpl(ctx)
is SpeedStatus -> SpeedImpl(ctx)
}
}.also { flows += it }
for (f in flows) {
ctx.lifeCycleScope.launch(Dispatchers.Default) {
ctx.lifeCycleScope.launch(dispatcher) {
f.asFlow().collect {
model.update(it)
}
@@ -89,7 +105,7 @@ object StatusManager {
}
model.status.observe(ctx.lifeCycleOwner) {
listeners.forEach { itx ->
listeners.values.forEach { itx ->
itx.onStatusChanged(it.second, it.first != null)
}
}
@@ -120,6 +136,30 @@ object StatusManager {
flows.clear()
}
fun addListener(tag: String, listener: IStatusListener) {
if (listeners.containsKey(tag)) {
return
}
listeners[tag] = listener
}
fun removeListener(tag: String) {
listeners.remove(tag)
}
fun getExceptionStatusBeforeLaunchAutopilot(): Int {
var ret = 0
model.status.value?.second?.filter {
it is IAutopilotPreLaunchStatus
}?.forEachIndexed { index, status ->
val shl = 1 shl index
if (status.isException()) {
ret = ret or shl
}
}
return ret
}
interface IStatusListener {
fun onStatusChanged(data: List<Status>, hasException: Boolean)
}

View File

@@ -1,8 +1,5 @@
package com.zhjt.mogo_core_function_devatools.status.entity
import com.mogo.eagle.core.data.status.StatusSummaryEntity
import com.mogo.eagle.core.function.api.autopilot.*
import com.mogo.eagle.core.function.call.autopilot.*
import com.zhjt.mogo_core_function_devatools.status.entity.TracingStatus.Tracing
import com.zhjt.mogo_core_function_devatools.status.entity.TracingStatus.Tracing.*
@@ -250,7 +247,7 @@ class OverViewStatus(var hasException: Boolean = false): Status() {
fun String.toState(msg: String?): Tracing? {
val ss = msg?.split("|")
var extra: Map<String, String>? = null
if (ss != null && ss.isNotEmpty()) {
if (!ss.isNullOrEmpty()) {
val sb = StringBuilder()
for (element in ss) {
sb.append(element)
@@ -290,3 +287,70 @@ fun String.toState(msg: String?): Tracing? {
else -> null
}
}
interface IAutopilotPreLaunchStatus
/**
* 速度
*/
data class SpeedStatus(val speed: Float): Status(), IAutopilotPreLaunchStatus {
override fun isException(): Boolean {
return false
}
}
/**
* 方向盘转角
*/
data class SteerStatus(val angle: Float, var isError: Boolean = false): Status(), IAutopilotPreLaunchStatus {
override fun isException(): Boolean {
return isError
}
}
/**
* 油门
*/
data class AcceleratorStatus(val angle: Float, var isError: Boolean = false): Status(), IAutopilotPreLaunchStatus {
override fun isException(): Boolean {
return isError
}
}
/**
* 刹车
*/
data class BrakeStatus(val angle: Float, var isError: Boolean = false): Status(), IAutopilotPreLaunchStatus {
override fun isException(): Boolean {
return isError
}
}
/**
* 双闪
*/
data class DoubleFlashStatus(val type: Int, var isError: Boolean = false): Status(), IAutopilotPreLaunchStatus {
override fun isException(): Boolean {
return isError
}
}
/**
* 挡位
*/
data class GearStatus(val value: Int, var isError: Boolean = false): Status(), IAutopilotPreLaunchStatus {
override fun isException(): Boolean {
return isError
}
}

View File

@@ -0,0 +1,57 @@
package com.zhjt.mogo_core_function_devatools.status.flow.autopilot
import android.content.Context
import com.mogo.eagle.core.function.api.autopilot.IMoGoAutopilotActionsListener
import com.mogo.eagle.core.function.api.autopilot.IMoGoChassisThrottleStateListener
import com.mogo.eagle.core.function.call.autopilot.CallerAutopilotActionsListenerManager
import com.mogo.eagle.core.function.call.autopilot.CallerChassisThrottleStateListenerManager
import com.mogo.eagle.core.utilcode.mogo.logger.Logger
import com.zhjt.mogo.adas.data.bean.UnableLaunchData
import com.zhjt.mogo.adas.data.bean.UnableLaunchReason
import com.zhjt.mogo.adas.data.bean.UnableLaunchReason.UnableType.CHASSIS_THROTTLE
import com.zhjt.mogo_core_function_devatools.status.entity.AcceleratorStatus
import com.zhjt.mogo_core_function_devatools.status.flow.IFlow
internal class AcceleratorImpl(ctx: Context): IFlow<AcceleratorStatus>(ctx), IMoGoChassisThrottleStateListener, IMoGoAutopilotActionsListener {
companion object {
private const val TAG = "AcceleratorImpl"
}
@Volatile
private var last: Float? = null
@Volatile
private var isError: Boolean = false
override fun onCreate() {
CallerChassisThrottleStateListenerManager.addListener(TAG, this)
CallerAutopilotActionsListenerManager.addListener(TAG, this)
}
override fun onDestroy() {
super.onDestroy()
CallerChassisThrottleStateListenerManager.removeListener(TAG)
CallerAutopilotActionsListenerManager.removeListener(TAG)
}
override fun onAutopilotThrottle(throttle: Float) {
super.onAutopilotThrottle(throttle)
if (last != throttle) {
send(AcceleratorStatus(throttle, isError))
last = throttle
}
}
override fun onAutopilotAbility(isAutopilotAbility: Boolean, unableLaunchData: UnableLaunchData?, unableAutopilotReasons: ArrayList<UnableLaunchReason>?) {
Logger.d(TAG, "onAutopilotAbility->($isAutopilotAbility, $unableLaunchData, ${unableAutopilotReasons?.joinToString(",")}")
if (!isAutopilotAbility && unableAutopilotReasons != null && unableAutopilotReasons.find { it.unableType == CHASSIS_THROTTLE } != null) {
isError = true
send(AcceleratorStatus(last ?: 0.0f, true))
} else {
isError = false
send(AcceleratorStatus(last ?: 0.0f, false))
}
}
}

View File

@@ -0,0 +1,60 @@
package com.zhjt.mogo_core_function_devatools.status.flow.autopilot
import android.content.Context
import com.mogo.eagle.core.function.api.autopilot.IMoGoAutopilotActionsListener
import com.mogo.eagle.core.function.api.autopilot.IMoGoChassisBrakeStateListener
import com.mogo.eagle.core.function.call.autopilot.CallerAutopilotActionsListenerManager
import com.mogo.eagle.core.function.call.autopilot.CallerChassisBrakeStateListenerManager
import com.mogo.eagle.core.utilcode.mogo.logger.Logger
import com.zhjt.mogo.adas.data.bean.UnableLaunchData
import com.zhjt.mogo.adas.data.bean.UnableLaunchReason
import com.zhjt.mogo.adas.data.bean.UnableLaunchReason.UnableType.CHASSIS_BRAKE
import com.zhjt.mogo.adas.data.bean.UnableLaunchReason.UnableType.CHASSIS_THROTTLE
import com.zhjt.mogo_core_function_devatools.status.entity.AcceleratorStatus
import com.zhjt.mogo_core_function_devatools.status.entity.BrakeStatus
import com.zhjt.mogo_core_function_devatools.status.flow.IFlow
import com.zhjt.mogo_core_function_devatools.status.flow.autopilot.AcceleratorImpl.Companion
internal class BrakeImpl(ctx: Context): IFlow<BrakeStatus>(ctx), IMoGoChassisBrakeStateListener, IMoGoAutopilotActionsListener {
companion object {
private const val TAG = "BrakeImpl"
}
@Volatile
private var last: Float = 0.0f
@Volatile
private var isError: Boolean = false
override fun onCreate() {
CallerChassisBrakeStateListenerManager.addListener(TAG, this)
CallerAutopilotActionsListenerManager.addListener(TAG, this)
}
override fun onDestroy() {
super.onDestroy()
CallerChassisBrakeStateListenerManager.removeListener(TAG)
CallerAutopilotActionsListenerManager.removeListener(TAG)
}
override fun onAutopilotBrake(brake: Float) {
super.onAutopilotBrake(brake)
if (last != brake) {
send(BrakeStatus(brake, isError))
last = brake
}
}
override fun onAutopilotAbility(isAutopilotAbility: Boolean, unableLaunchData: UnableLaunchData?, unableAutopilotReasons: ArrayList<UnableLaunchReason>?) {
Logger.d(TAG, "onAutopilotAbility->($isAutopilotAbility, $unableLaunchData, ${unableAutopilotReasons?.joinToString(",")}")
if (!isAutopilotAbility && unableAutopilotReasons != null && unableAutopilotReasons.find { it.unableType == CHASSIS_BRAKE } != null) {
isError = true
send(BrakeStatus(last, true))
} else {
isError = false
send(BrakeStatus(last, false))
}
}
}

View File

@@ -0,0 +1,58 @@
package com.zhjt.mogo_core_function_devatools.status.flow.autopilot
import android.content.Context
import chassis.Chassis.LightSwitch
import chassis.Chassis.LightSwitch.LIGHT_FLASH
import com.mogo.eagle.core.function.api.autopilot.IMoGoAutopilotActionsListener
import com.mogo.eagle.core.function.api.autopilot.IMoGoChassisLamplightListener
import com.mogo.eagle.core.function.call.autopilot.CallerAutopilotActionsListenerManager
import com.mogo.eagle.core.function.call.autopilot.CallerChassisLamplightListenerManager
import com.mogo.eagle.core.utilcode.mogo.logger.Logger
import com.zhjt.mogo.adas.data.bean.UnableLaunchData
import com.zhjt.mogo.adas.data.bean.UnableLaunchReason
import com.zhjt.mogo.adas.data.bean.UnableLaunchReason.UnableType.CHASSIS_HAZARD_LIGHTS
import com.zhjt.mogo.adas.data.bean.UnableLaunchReason.UnableType.CHASSIS_THROTTLE
import com.zhjt.mogo_core_function_devatools.status.entity.AcceleratorStatus
import com.zhjt.mogo_core_function_devatools.status.entity.DoubleFlashStatus
import com.zhjt.mogo_core_function_devatools.status.flow.IFlow
internal class DoubleFlashImpl(ctx: Context): IFlow<DoubleFlashStatus>(ctx), IMoGoChassisLamplightListener, IMoGoAutopilotActionsListener {
companion object {
private const val TAG = "DoubleFlashImpl"
}
@Volatile
private var isError: Boolean = false
override fun onCreate() {
CallerChassisLamplightListenerManager.addListener(TAG, this)
CallerAutopilotActionsListenerManager.addListener(TAG, this)
}
override fun onDestroy() {
super.onDestroy()
CallerChassisLamplightListenerManager.removeListener(TAG)
CallerAutopilotActionsListenerManager.removeListener(TAG)
}
override fun onAutopilotLightSwitchData(lightSwitch: LightSwitch?) {
super.onAutopilotLightSwitchData(lightSwitch)
Logger.d(TAG, "-- onAutopilotLightSwitchData --: $lightSwitch")
if (lightSwitch == LIGHT_FLASH) {
send(DoubleFlashStatus(lightSwitch.number, isError))
}
}
override fun onAutopilotAbility(isAutopilotAbility: Boolean, unableLaunchData: UnableLaunchData?, unableAutopilotReasons: ArrayList<UnableLaunchReason>?) {
Logger.d(TAG, "onAutopilotAbility->($isAutopilotAbility, $unableLaunchData, ${unableAutopilotReasons?.joinToString(",")}")
if (!isAutopilotAbility && unableAutopilotReasons != null && unableAutopilotReasons.find { it.unableType == CHASSIS_HAZARD_LIGHTS } != null) {
isError = true
send(DoubleFlashStatus(LIGHT_FLASH.number, true))
} else {
isError = false
send(DoubleFlashStatus(LIGHT_FLASH.number, false))
}
}
}

View File

@@ -0,0 +1,57 @@
package com.zhjt.mogo_core_function_devatools.status.flow.autopilot
import android.content.Context
import chassis.Chassis.GearPosition
import chassis.Chassis.GearPosition.GEAR_NONE
import com.mogo.eagle.core.function.api.autopilot.IMoGoAutopilotActionsListener
import com.mogo.eagle.core.function.api.autopilot.IMoGoChassisGearStateListener
import com.mogo.eagle.core.function.call.autopilot.CallerAutopilotActionsListenerManager
import com.mogo.eagle.core.function.call.autopilot.CallerChassisGearStateListenerManager
import com.mogo.eagle.core.utilcode.mogo.logger.Logger
import com.zhjt.mogo.adas.data.bean.UnableLaunchData
import com.zhjt.mogo.adas.data.bean.UnableLaunchReason
import com.zhjt.mogo.adas.data.bean.UnableLaunchReason.UnableType.CHASSIS_GEAR
import com.zhjt.mogo_core_function_devatools.status.entity.GearStatus
import com.zhjt.mogo_core_function_devatools.status.flow.IFlow
internal class GearImpl(ctx: Context): IFlow<GearStatus>(ctx), IMoGoChassisGearStateListener, IMoGoAutopilotActionsListener {
companion object {
private const val TAG = "GeerImpl"
}
@Volatile
private var last: GearPosition = GEAR_NONE
@Volatile
private var isError: Boolean = false
override fun onCreate() {
CallerChassisGearStateListenerManager.addListener(TAG, this)
CallerAutopilotActionsListenerManager.addListener(TAG, this)
}
override fun onDestroy() {
super.onDestroy()
CallerChassisGearStateListenerManager.removeListener(TAG)
CallerAutopilotActionsListenerManager.removeListener(TAG)
}
override fun onAutopilotGearData(gear: GearPosition) {
if (last != gear) {
send(GearStatus(gear.number, isError))
last = gear
}
}
override fun onAutopilotAbility(isAutopilotAbility: Boolean, unableLaunchData: UnableLaunchData?, unableAutopilotReasons: ArrayList<UnableLaunchReason>?) {
Logger.d(TAG, "onAutopilotAbility->($isAutopilotAbility, $unableLaunchData, ${unableAutopilotReasons?.joinToString(",")}")
if (!isAutopilotAbility && unableAutopilotReasons != null && unableAutopilotReasons.find { it.unableType == CHASSIS_GEAR } != null) {
isError = true
send(GearStatus(last.number, true))
} else {
isError = false
send(GearStatus(last.number, false))
}
}
}

View File

@@ -0,0 +1,44 @@
package com.zhjt.mogo_core_function_devatools.status.flow.autopilot
import android.content.Context
import com.mogo.eagle.core.data.map.MogoLocation
import com.mogo.eagle.core.function.api.autopilot.IMoGoAutopilotActionsListener
import com.mogo.eagle.core.function.api.autopilot.IMoGoChassisLocationGCJ02Listener
import com.mogo.eagle.core.function.api.autopilot.IMoGoChassisThrottleStateListener
import com.mogo.eagle.core.function.call.autopilot.CallerAutopilotActionsListenerManager
import com.mogo.eagle.core.function.call.autopilot.CallerChassisLocationGCJ02ListenerManager
import com.mogo.eagle.core.function.call.autopilot.CallerChassisThrottleStateListenerManager
import com.mogo.eagle.core.utilcode.mogo.logger.Logger
import com.zhjt.mogo.adas.data.bean.UnableLaunchData
import com.zhjt.mogo.adas.data.bean.UnableLaunchReason
import com.zhjt.mogo.adas.data.bean.UnableLaunchReason.UnableType.CHASSIS_THROTTLE
import com.zhjt.mogo_core_function_devatools.status.entity.AcceleratorStatus
import com.zhjt.mogo_core_function_devatools.status.entity.SpeedStatus
import com.zhjt.mogo_core_function_devatools.status.flow.IFlow
internal class SpeedImpl(ctx: Context): IFlow<SpeedStatus>(ctx), IMoGoChassisLocationGCJ02Listener {
companion object {
private const val TAG = "SpeedImpl"
}
@Volatile
private var last: Float? = null
override fun onCreate() {
CallerChassisLocationGCJ02ListenerManager.addListener(TAG, this)
}
override fun onDestroy() {
super.onDestroy()
CallerChassisLocationGCJ02ListenerManager.removeListener(TAG)
}
override fun onChassisLocationGCJ02(mogoLocation: MogoLocation?) {
if (last != mogoLocation?.gnssSpeed) {
send(SpeedStatus(mogoLocation?.gnssSpeed ?: 0f))
last = mogoLocation?.gnssSpeed
}
}
}

View File

@@ -0,0 +1,50 @@
package com.zhjt.mogo_core_function_devatools.status.flow.autopilot
import android.content.Context
import com.mogo.eagle.core.function.api.autopilot.IMoGoAutopilotActionsListener
import com.mogo.eagle.core.function.api.autopilot.IMoGoChassisSteeringStateListener
import com.mogo.eagle.core.function.call.autopilot.CallerAutopilotActionsListenerManager
import com.mogo.eagle.core.function.call.autopilot.CallerChassisSteeringStateListenerManager
import com.mogo.eagle.core.utilcode.mogo.logger.Logger
import com.zhjt.mogo.adas.data.bean.UnableLaunchData
import com.zhjt.mogo.adas.data.bean.UnableLaunchReason
import com.zhjt.mogo.adas.data.bean.UnableLaunchReason.UnableType.CHASSIS_STEERING
import com.zhjt.mogo_core_function_devatools.status.entity.SteerStatus
import com.zhjt.mogo_core_function_devatools.status.flow.IFlow
internal class SteerImpl(ctx: Context): IFlow<SteerStatus>(ctx), IMoGoChassisSteeringStateListener, IMoGoAutopilotActionsListener {
companion object {
private const val TAG = "SteerImpl"
}
@Volatile
private var last: Float = 0f
override fun onCreate() {
CallerChassisSteeringStateListenerManager.addListener(TAG, this)
CallerAutopilotActionsListenerManager.addListener(TAG, this)
}
override fun onDestroy() {
super.onDestroy()
CallerChassisSteeringStateListenerManager.removeListener(TAG)
CallerAutopilotActionsListenerManager.removeListener(TAG)
}
override fun onAutopilotSteeringData(steering: Float) {
if (last != steering) {
send(SteerStatus(steering))
last = steering
}
}
override fun onAutopilotAbility(isAutopilotAbility: Boolean, unableLaunchData: UnableLaunchData?, unableAutopilotReasons: ArrayList<UnableLaunchReason>?) {
Logger.d(TAG, "onAutopilotAbility->($isAutopilotAbility, $unableLaunchData, ${unableAutopilotReasons?.joinToString(",")}")
if (!isAutopilotAbility && unableAutopilotReasons != null && unableAutopilotReasons.find { it.unableType == CHASSIS_STEERING } != null) {
send(SteerStatus(last, true))
} else {
send(SteerStatus(last, false))
}
}
}

View File

@@ -4,7 +4,6 @@ import androidx.lifecycle.*
import com.mogo.eagle.core.function.call.autopilot.*
import com.zhjt.mogo_core_function_devatools.status.entity.*
//import com.zhjt.mogo_core_function_devatools.status.entity.NetStatus
import com.zhjt.mogo_core_function_devatools.status.entity.TracingStatus.Tracing.UNKNOWN
import java.util.concurrent.atomic.*
import kotlin.Pair
@@ -21,6 +20,12 @@ internal class StatusModel : ViewModel() {
it += RTKStatus("", -1)
// it += NetStatus(false)
// it += GpsStatus(enabled = false, isGranted = false)
it += SteerStatus(0.0f)
it += AcceleratorStatus(0.0f)
it += BrakeStatus(0.0f)
it += DoubleFlashStatus(0)
it += GearStatus(0)
it += SpeedStatus(0f)
})
}

View File

@@ -0,0 +1,112 @@
package com.zhjt.mogo_core_function_devatools.status.ui
import android.content.Context
import android.util.AttributeSet
import android.view.LayoutInflater
import android.widget.LinearLayout
import androidx.core.content.ContextCompat
import chassis.Chassis.GearPosition
import chassis.Chassis.GearPosition.GEAR_D
import chassis.Chassis.GearPosition.GEAR_N
import chassis.Chassis.GearPosition.GEAR_NONE
import chassis.Chassis.GearPosition.GEAR_P
import chassis.Chassis.GearPosition.GEAR_R
import com.zhjt.mogo_core_function_devatools.R
import com.zhjt.mogo_core_function_devatools.status.StatusManager
import com.zhjt.mogo_core_function_devatools.status.StatusManager.IStatusListener
import com.zhjt.mogo_core_function_devatools.status.entity.AcceleratorStatus
import com.zhjt.mogo_core_function_devatools.status.entity.BrakeStatus
import com.zhjt.mogo_core_function_devatools.status.entity.DoubleFlashStatus
import com.zhjt.mogo_core_function_devatools.status.entity.GearStatus
import com.zhjt.mogo_core_function_devatools.status.entity.IAutopilotPreLaunchStatus
import com.zhjt.mogo_core_function_devatools.status.entity.SpeedStatus
import com.zhjt.mogo_core_function_devatools.status.entity.Status
import com.zhjt.mogo_core_function_devatools.status.entity.SteerStatus
import kotlinx.android.synthetic.main.layout_autopilot_launch_before.view.gear_d
import kotlinx.android.synthetic.main.layout_autopilot_launch_before.view.gear_n
import kotlinx.android.synthetic.main.layout_autopilot_launch_before.view.gear_p
import kotlinx.android.synthetic.main.layout_autopilot_launch_before.view.gear_r
import kotlinx.android.synthetic.main.layout_autopilot_launch_before.view.iv_brake_or_accelerator
import kotlinx.android.synthetic.main.layout_autopilot_launch_before.view.iv_double_flash
import kotlinx.android.synthetic.main.layout_autopilot_launch_before.view.iv_steer
import kotlinx.android.synthetic.main.layout_autopilot_launch_before.view.speed
import kotlinx.android.synthetic.main.layout_autopilot_launch_before.view.tv_brake_or_accelerator
class AutoPilotLaunchBeforeView: LinearLayout, IStatusListener {
companion object {
private const val TAG = "AutoPilotLaunchBeforeView"
}
constructor(context: Context?) : this(context, null)
constructor(context: Context?, attrs: AttributeSet?) : this(context, attrs, 0)
constructor(context: Context?, attrs: AttributeSet?, defStyleAttr: Int) : super(context, attrs, defStyleAttr) {
LayoutInflater.from(context).inflate(R.layout.layout_autopilot_launch_before, this, true)
background = ContextCompat.getDrawable(context!!, R.drawable.bg_autopilot_launch_before)
}
override fun onAttachedToWindow() {
super.onAttachedToWindow()
StatusManager.addListener(TAG, this)
}
override fun onDetachedFromWindow() {
super.onDetachedFromWindow()
StatusManager.removeListener(TAG)
}
override fun onStatusChanged(data: List<Status>, hasException: Boolean) {
data.filter { it is IAutopilotPreLaunchStatus }.forEach { status ->
when(status) {
is GearStatus -> {
val position = try { GearPosition.valueOf(status.value) } catch (ignore: Throwable) { GEAR_NONE }
gear_n?.isPressed = false
gear_n?.isSelected = false
gear_p?.isPressed = false
gear_p?.isSelected =false
gear_r?.isPressed = false
gear_r?.isSelected = false
gear_d?.isPressed = false
gear_d?.isSelected = false
if (position != GEAR_NONE) {
val isError = status.isError
when(position) {
GEAR_N -> if (isError) gear_n?.isPressed = true else gear_n?.isSelected = true
GEAR_R -> if (isError) gear_r?.isPressed = true else gear_r?.isSelected = true
GEAR_P -> if (isError) gear_p?.isPressed = true else gear_p?.isSelected = true
GEAR_D -> if (isError) gear_d?.isPressed = true else gear_d?.isSelected = true
else -> {}
}
}
}
is AcceleratorStatus -> {
val isError = status.isError
val angle = status.angle
iv_brake_or_accelerator?.isSelected = isError
tv_brake_or_accelerator?.text = "a: $angle"
}
is BrakeStatus -> {
val isError = status.isError
val angle = status.angle
iv_brake_or_accelerator?.isSelected = isError
tv_brake_or_accelerator?.text = "a: -$angle"
}
is DoubleFlashStatus -> {
val isError = status.isError
iv_double_flash?.isSelected = isError
}
is SteerStatus -> {
val isError = status.isError
iv_steer?.isSelected = isError
}
is SpeedStatus -> {
speed?.text = "${status.speed.toInt()}"
}
else -> {
throw IllegalStateException()
}
}
}
}
}

View File

@@ -9,6 +9,7 @@ import androidx.recyclerview.widget.*
import com.mogo.eagle.core.utilcode.kotlin.*
import com.mogo.eagle.core.utilcode.rv.divider.*
import com.zhjt.mogo_core_function_devatools.R
import com.zhjt.mogo_core_function_devatools.status.entity.IAutopilotPreLaunchStatus
import com.zhjt.mogo_core_function_devatools.status.entity.Status
import com.zhjt.mogo_core_function_devatools.status.model.StatusModel
import com.zhjt.mogo_core_function_devatools.status.ui.adapter.StatusAdapter
@@ -47,12 +48,13 @@ internal class StatusView(private val model: StatusModel, ctx: Context): Constra
.horizontalInnerSpace(10.PX)
.build()
)
val adapter = model.status.value?.let { data -> StatusAdapter(context, data.second) }?.also { adapter -> itx.adapter = adapter }
val adapter = model.status.value?.let { data -> StatusAdapter(context, data.second.filter { it !is IAutopilotPreLaunchStatus }) }?.also { adapter -> itx.adapter = adapter }
adapter?.let { _ ->
model.status.observeForever(Observer<Pair<Status?, ArrayList<Status>>> { data ->
val old = adapter.data
val result = DiffUtil.calculateDiff(StatusDiffCallback(old, data.second))
adapter.data = data.second
val update = data.second.filter { it !is IAutopilotPreLaunchStatus }
val result = DiffUtil.calculateDiff(StatusDiffCallback(old, update))
adapter.data = update
result.dispatchUpdatesTo(adapter)
}.also { observer = it })
}

View File

@@ -18,7 +18,7 @@ import com.zhjt.mogo_core_function_devatools.status.entity.TracingStatus.Tracing
import com.zhjt.mogo_core_function_devatools.status.ui.adapter.StatusAdapter.StatusViewHolder
import me.jessyan.autosize.AutoSizeCompat
internal class StatusAdapter(val ctx: Context, var data: ArrayList<Status>): RecyclerView.Adapter<StatusViewHolder>() {
internal class StatusAdapter(val ctx: Context, var data: List<Status>): RecyclerView.Adapter<StatusViewHolder>() {
companion object {
const val TAG = "StatusAdapter"
@@ -169,6 +169,9 @@ internal class StatusAdapter(val ctx: Context, var data: ArrayList<Status>): Rec
is OverViewStatus -> {
""
}
else -> {
throw AssertionError()
}
}
}
}

View File

@@ -3,7 +3,7 @@ package com.zhjt.mogo_core_function_devatools.status.ui.diff
import androidx.recyclerview.widget.*
import com.zhjt.mogo_core_function_devatools.status.entity.Status
internal class StatusDiffCallback(private val old: ArrayList<Status>, private val update: ArrayList<Status>): DiffUtil.Callback() {
internal class StatusDiffCallback(private val old: List<Status>, private val update: List<Status>): DiffUtil.Callback() {
override fun getOldListSize(): Int = old.size

View File

@@ -0,0 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:color="@color/white" android:state_selected="true" />
<item android:color="#F73B3C" android:state_pressed="true" />
<item android:color="#343C63" />
</selector>

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.0 KiB

View File

@@ -0,0 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_selected="true" android:drawable="@drawable/icon_brake_or_accelerator_red" />
<item android:drawable="@drawable/icon_brake_or_accelerator_blue" />
</selector>

View File

@@ -0,0 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_selected="true" android:drawable="@drawable/icon_double_flash_red" />
<item android:drawable="@drawable/icon_double_flash_blue" />
</selector>

View File

@@ -0,0 +1,32 @@
<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
<item android:width="@dimen/dp_560" android:height="@dimen/dp_200">
<shape
android:shape="rectangle">
<gradient
android:startColor="#387BD4"
android:centerColor="#0D1578"
android:endColor="#387BD4"
android:angle="-45"/>
<corners
android:topLeftRadius="@dimen/dp_66"
android:bottomRightRadius="@dimen/dp_66"
android:topRightRadius="@dimen/dp_26"
android:bottomLeftRadius="@dimen/dp_26"/>
</shape>
</item>
<item android:width="@dimen/dp_556" android:height="@dimen/dp_196" android:left="@dimen/dp_2" android:top="@dimen/dp_2">
<shape
android:shape="rectangle">
<solid android:color="#000936" />
<corners
android:topLeftRadius="@dimen/dp_66"
android:bottomRightRadius="@dimen/dp_66"
android:topRightRadius="@dimen/dp_26"
android:bottomLeftRadius="@dimen/dp_26"/>
</shape>
</item>
</layer-list>

View File

@@ -0,0 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_selected="true" android:drawable="@drawable/icon_steer_red" />
<item android:drawable="@drawable/icon_steer_blue" />
</selector>

View File

@@ -0,0 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle">
<solid android:color="#141B47" />
<corners android:radius="@dimen/dp_60" />
</shape>

View File

@@ -0,0 +1,34 @@
<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
<item android:width="@dimen/dp_184" android:height="@dimen/dp_200">
<shape
android:shape="rectangle">
<corners
android:topLeftRadius="@dimen/dp_66"
android:bottomRightRadius="@dimen/dp_66"
android:topRightRadius="@dimen/dp_26"
android:bottomLeftRadius="@dimen/dp_26"/>
<gradient
android:startColor="#9FC8FF"
android:centerColor="#1F318E"
android:endColor="#9FC8FF"
android:angle="-90"/>
</shape>
</item>
<item android:width="@dimen/dp_180" android:height="@dimen/dp_196" android:left="@dimen/dp_2" android:top="@dimen/dp_2">
<shape
android:shape="rectangle">
<corners
android:topLeftRadius="@dimen/dp_65"
android:bottomRightRadius="@dimen/dp_65"
android:topRightRadius="@dimen/dp_25"
android:bottomLeftRadius="@dimen/dp_25"/>
<gradient
android:startColor="#231CDE"
android:centerColor="#000936"
android:endColor="#892B5AD7"
android:angle="-90"/>
</shape>
</item>
</layer-list>

View File

@@ -0,0 +1,4 @@
<?xml version="1.0" encoding="utf-8"?>
<color xmlns:android="http://schemas.android.com/apk/res/android" android:color="@color/white">
</color>

View File

@@ -0,0 +1,126 @@
<?xml version="1.0" encoding="utf-8"?>
<merge xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
tools:parentTag="android.widget.LinearLayout"
tools:layout_width="wrap_content"
tools:layout_height="wrap_content"
tools:orientation="horizontal"
tools:background="@drawable/bg_autopilot_launch_before">
<LinearLayout
android:id="@+id/speed_chart_parent"
android:layout_width="@dimen/dp_184"
android:layout_height="@dimen/dp_200"
android:gravity="center"
android:orientation="vertical"
android:background="@drawable/bg_speed_chart">
<TextView
android:id="@+id/speed"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="@dimen/dp_74"
android:textColor="@color/white"
tools:text="65"
android:layout_marginBottom="@dimen/dp_2"/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="@dimen/dp_32"
android:text="Km/h"
android:textColor="@color/white"/>
</LinearLayout>
<LinearLayout
android:layout_width="0dip"
android:layout_height="@dimen/dp_200"
android:layout_weight="1"
android:orientation="vertical"
android:gravity="center_vertical">
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:layout_marginStart="@dimen/dp_34"
android:background="@drawable/bg_geer_position"
android:paddingStart="@dimen/dp_53"
android:paddingEnd="@dimen/dp_53"
android:paddingTop="@dimen/dp_6"
android:paddingBottom="@dimen/dp_6">
<TextView
android:id="@+id/gear_p"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="P"
android:textSize="@dimen/dp_36"
android:layout_marginEnd="@dimen/dp_32"
android:textColor="@color/color_geer_position_selector"/>
<TextView
android:id="@+id/gear_r"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="R"
android:textSize="@dimen/dp_36"
android:layout_marginEnd="@dimen/dp_32"
android:textColor="@color/color_geer_position_selector"/>
<TextView
android:id="@+id/gear_n"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="N"
android:textSize="@dimen/dp_36"
android:layout_marginEnd="@dimen/dp_32"
android:textColor="@color/color_geer_position_selector"/>
<TextView
android:id="@+id/gear_d"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="D"
android:textSize="@dimen/dp_36"
android:textColor="@color/color_geer_position_selector"/>
</LinearLayout>
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="@dimen/dp_34"
android:gravity="center_vertical"
android:layout_marginTop="@dimen/dp_23">
<ImageView
android:id="@+id/iv_steer"
android:layout_width="@dimen/dp_55"
android:layout_height="@dimen/dp_55"
android:layout_marginEnd="@dimen/dp_20"
android:src="@drawable/bg_autopilot_steer"/>
<ImageView
android:id="@+id/iv_double_flash"
android:layout_width="@dimen/dp_55"
android:layout_height="@dimen/dp_55"
android:layout_marginEnd="@dimen/dp_20"
android:src="@drawable/bg_autopilot_double_flash"/>
<ImageView
android:id="@+id/iv_brake_or_accelerator"
android:layout_width="@dimen/dp_55"
android:layout_height="@dimen/dp_55"
android:src="@drawable/bg_autopilot_brake_or_accelerator"
android:layout_marginEnd="@dimen/dp_14"/>
<TextView
android:id="@+id/tv_brake_or_accelerator"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="@dimen/dp_34"
android:layout_marginTop="-1dp"
android:textColor="@color/white"
tools:text="a:0.0"/>
</LinearLayout>
</LinearLayout>
</merge>