[3.3.0][M1] 360环视需求代码提交
This commit is contained in:
0
app/bugly/BuglySymtabLog.txt
Normal file
0
app/bugly/BuglySymtabLog.txt
Normal file
0
app/bugly/BuglyUploadLog.txt
Normal file
0
app/bugly/BuglyUploadLog.txt
Normal file
@@ -56,6 +56,7 @@ import com.zhidao.support.adas.high.common.Constants
|
||||
import com.zhidao.support.adas.high.common.Constants.IPC_CONNECTION_STATUS
|
||||
import com.zhidao.support.adas.high.common.CupidLogUtils
|
||||
import com.zhidao.support.adas.high.common.MessageType
|
||||
import com.zhjt.mogo.adas.data.AdasConstants
|
||||
import com.zhjt.mogo.adas.data.bean.MogoReport
|
||||
import com.zhjt.mogo.adas.data.sweeper.bootable.SweeperBootable
|
||||
import com.zhjt.mogo.adas.data.sweeper.task.SweeperTask
|
||||
@@ -559,7 +560,7 @@ class MoGoAutopilotControlProvider :
|
||||
|
||||
/**
|
||||
* 获取全部参数
|
||||
* 结果回调{@link OnAdasListener#onGetParamResp(MessagePad.Header, MessagePad.SetParamReq)}
|
||||
* 结果回调{@link OnAdasListener#onGetParamResp(MessagePad.Header, MessagePad.SetParamReq, AdasParam)}
|
||||
*
|
||||
* @return boolean
|
||||
*/
|
||||
@@ -569,12 +570,12 @@ class MoGoAutopilotControlProvider :
|
||||
|
||||
/**
|
||||
* 参数获取请求
|
||||
* 结果回调{@link OnAdasListener#onGetParamResp(MessagePad.Header, MessagePad.SetParamReq)}
|
||||
* 结果回调{@link OnAdasListener#onGetParamResp(MessagePad.Header, MessagePad.SetParamReq, AdasParam)}
|
||||
*
|
||||
* @param paramType 参数类型{@link com.zhidao.support.adas.high.common.Constants.PARAM_TYPE}
|
||||
* @param paramType 参数类型:libraries/mogo-adas-data/src/main/proto/personal/adas_constants.proto
|
||||
* @return boolean
|
||||
*/
|
||||
override fun sendGetParamReq(paramType: Int): Boolean {
|
||||
override fun sendGetParamReq(paramType: AdasConstants.MapSystemParamType): Boolean {
|
||||
return AdasManager.getInstance().sendGetParamReq(paramType)
|
||||
}
|
||||
|
||||
|
||||
@@ -60,7 +60,7 @@ import com.mogo.eagle.core.utilcode.mogo.logger.Logger
|
||||
import com.mogo.support.obu.ObuScene
|
||||
import com.zhidao.support.adas.high.AdasManager
|
||||
import com.zhidao.support.adas.high.OnAdasListener
|
||||
import com.zhidao.support.adas.high.bean.AdasParam
|
||||
import com.zhjt.mogo.adas.data.bean.AdasParam
|
||||
import com.zhidao.support.adas.high.common.ProtocolStatus
|
||||
import com.zhjt.mogo.adas.data.bean.AutopilotStatistics
|
||||
import com.zhjt.mogo.adas.data.sweeper.SweeperCloudTask
|
||||
@@ -796,6 +796,7 @@ class MoGoAdasListenerImpl : OnAdasListener {
|
||||
* @param adasParam 解析后的配置参数
|
||||
*/
|
||||
override fun onGetParamResp(header: MessagePad.Header, getParamResp: MessagePad.SetParamReq, adasParam: AdasParam) {
|
||||
CallerAutopilotGetParamResponseDispatcher.dispatchResponse(header, getParamResp, adasParam)
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -20,6 +20,7 @@ import com.mogo.eagle.core.function.api.devatools.apm.*
|
||||
import com.mogo.eagle.core.function.api.devatools.strict.*
|
||||
import com.mogo.eagle.core.function.call.map.*
|
||||
import com.mogo.eagle.core.function.api.devatools.download.*
|
||||
import com.mogo.eagle.core.function.api.lookaround.*
|
||||
import com.mogo.eagle.core.utilcode.mogo.logger.CallerLogger
|
||||
import com.mogo.eagle.core.utilcode.mogo.logger.CallerLogger.w
|
||||
import com.tencent.matrix.Matrix
|
||||
@@ -42,6 +43,7 @@ import com.zhjt.mogo_core_function_devatools.funcconfig.FuncConfigCenter.Compani
|
||||
import com.zhjt.mogo_core_function_devatools.funcconfig.FuncConfigImpl
|
||||
import com.zhjt.mogo_core_function_devatools.koom.KoomInitTask
|
||||
import com.zhjt.mogo_core_function_devatools.logcatch.MogoLogCatchManager
|
||||
import com.zhjt.mogo_core_function_devatools.lookaround.*
|
||||
import com.zhjt.mogo_core_function_devatools.matrix.DynamicConfigImpl
|
||||
import com.zhjt.mogo_core_function_devatools.mofang.MoFangManager.Companion.moFangManager
|
||||
import com.zhjt.mogo_core_function_devatools.monitor.MonitorManager
|
||||
@@ -72,6 +74,9 @@ class DevaToolsProvider : IDevaToolsProvider {
|
||||
|
||||
private val strictModeProvider by lazy { StrictModeProviderImpl() }
|
||||
|
||||
|
||||
private val lookAroundDataProvider by lazy { MoGoLookAroundProviderImpl() }
|
||||
|
||||
@Volatile
|
||||
private var mDockerVersion: String? = null
|
||||
|
||||
@@ -105,6 +110,7 @@ class DevaToolsProvider : IDevaToolsProvider {
|
||||
// 监听弱网
|
||||
WeakNetworkStrategy.startListen()
|
||||
}
|
||||
lookAroundDataProvider.init(mContext!!)
|
||||
}
|
||||
|
||||
override fun checkMonitorDb() {
|
||||
@@ -356,4 +362,6 @@ class DevaToolsProvider : IDevaToolsProvider {
|
||||
return upgradeManager.upgradeProvider()
|
||||
}
|
||||
override fun strict(): IStrictModeProvider = strictModeProvider
|
||||
|
||||
override fun lookAroundDataProvider(): IMoGoLookAroundProvider = lookAroundDataProvider
|
||||
}
|
||||
@@ -0,0 +1,160 @@
|
||||
package com.zhjt.mogo_core_function_devatools.lookaround
|
||||
|
||||
import android.content.*
|
||||
import android.graphics.BitmapFactory
|
||||
import android.util.*
|
||||
import androidx.core.util.Pools
|
||||
import com.mogo.eagle.core.data.config.*
|
||||
import com.mogo.eagle.core.function.api.autopilot.*
|
||||
import com.mogo.eagle.core.function.api.lookaround.*
|
||||
import com.mogo.eagle.core.function.api.lookaround.data.*
|
||||
import com.mogo.eagle.core.function.call.autopilot.*
|
||||
import com.mogo.eagle.core.utilcode.mogo.*
|
||||
import com.zhjt.mogo.adas.data.*
|
||||
import com.zhjt.mogo.adas.data.bean.*
|
||||
import kotlinx.coroutines.*
|
||||
import kotlinx.coroutines.channels.*
|
||||
import kotlinx.coroutines.channels.Channel.Factory.CONFLATED
|
||||
import kotlinx.coroutines.flow.*
|
||||
import mogo.telematics.pad.MessagePad.Header
|
||||
import mogo.telematics.pad.MessagePad.SetParamReq
|
||||
import java.util.concurrent.atomic.AtomicInteger
|
||||
import kotlin.concurrent.*
|
||||
|
||||
internal class MoGoLookAroundProviderImpl: IMoGoLookAroundProvider, IMoGoSweeperFutianBackCameraVideoListener, IMoGoRoboBusJinlvM1StitchedVideoListener, IMoGoGetParamResponseListener {
|
||||
|
||||
companion object {
|
||||
private const val TAG = "MoGoLookAroundProvider"
|
||||
}
|
||||
|
||||
@OptIn(ExperimentalCoroutinesApi::class)
|
||||
private var channel: Channel<LookAroundData> = Channel(CONFLATED)
|
||||
get() {
|
||||
return if (field.isClosedForReceive || field.isClosedForSend) {
|
||||
Channel(CONFLATED)
|
||||
} else {
|
||||
field
|
||||
}
|
||||
}
|
||||
|
||||
private val pool by lazy { Pools.SynchronizedPool<LookAroundData>(10) }
|
||||
|
||||
private val bitmapWidth by lazy { AtomicInteger(0) }
|
||||
|
||||
private val bitmapHeight by lazy { AtomicInteger(0) }
|
||||
|
||||
//276,319,147,366
|
||||
private val targetX by lazy { AtomicInteger(0) }
|
||||
|
||||
private val targetY by lazy { AtomicInteger(0) }
|
||||
|
||||
private val targetWidth by lazy { AtomicInteger(0) }
|
||||
|
||||
private val targetHeight by lazy { AtomicInteger(0) }
|
||||
|
||||
private val scope by lazy { CoroutineScope(Dispatchers.IO + SupervisorJob()) }
|
||||
|
||||
@Volatile
|
||||
private var job: Job? = null
|
||||
|
||||
override fun init(ctx: Context) {
|
||||
CallerSweeperFutianBackCameraVideoListenerManager.addListener(TAG, this)
|
||||
CallerRoboBusJinlvM1StitchedVideoListenerManager.addListener(TAG, this)
|
||||
CallerAutopilotGetParamResponseDispatcher.addListener(TAG, this)
|
||||
if (AppIdentityModeUtils.isM1(FunctionBuildConfig.appIdentityMode)) {
|
||||
sendReqForParamPeriod()
|
||||
}
|
||||
}
|
||||
|
||||
private fun sendReqForParamPeriod() {
|
||||
scope.launch {
|
||||
while (targetX.get() == 0 || targetY.get() == 0) {
|
||||
CallerAutoPilotControlManager.sendGetParamReq(AdasConstants.MapSystemParamType.M1_STITCHED_VIDEO_SELF_VEHICLE_PARAM)
|
||||
delay(2000)
|
||||
}
|
||||
}.also {
|
||||
job = it
|
||||
}
|
||||
}
|
||||
|
||||
@OptIn(ExperimentalCoroutinesApi::class)
|
||||
override fun flow(): Flow<LookAroundData> = channelFlow {
|
||||
val iterator = this@MoGoLookAroundProviderImpl.channel.iterator()
|
||||
while (iterator.hasNext()) {
|
||||
send(iterator.next())
|
||||
}
|
||||
}.flowOn(Dispatchers.IO)
|
||||
|
||||
override fun onRoboBusJinlvM1StitchedVideo(data: ByteArray) {
|
||||
if (bitmapWidth.get() == 0 || bitmapHeight.get() == 0) {
|
||||
val options = BitmapFactory.Options()
|
||||
options.inJustDecodeBounds = true
|
||||
BitmapFactory.decodeByteArray(data,0 , data.size, options)
|
||||
bitmapWidth.set(options.outWidth)
|
||||
bitmapHeight.set(options.outHeight)
|
||||
}
|
||||
Log.d(TAG, "-- onRoboBusJinlvM1StitchedVideo -- bitmap:[${bitmapWidth.get()}, ${bitmapHeight.get()}] -- data: ${data.size}")
|
||||
var old = pool.acquire()
|
||||
try {
|
||||
if (old == null) {
|
||||
old = LookAroundData(data, bitmapWidth.get(), bitmapHeight.get(), targetX.get(), targetY.get(), targetWidth.get(), targetHeight.get())
|
||||
} else {
|
||||
old.data = data
|
||||
old.bitmapWidth = bitmapWidth.get()
|
||||
old.bitmapHeight = bitmapHeight.get()
|
||||
old.targetX = targetX.get()
|
||||
old.targetY = targetY.get()
|
||||
old.targetWidth = targetWidth.get()
|
||||
old.targetHeight = targetHeight.get()
|
||||
}
|
||||
channel.trySend(old)
|
||||
} finally {
|
||||
if (old != null) {
|
||||
pool.release(old)
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
override fun onSweeperFutianBackCameraVideo(data: ByteArray) {
|
||||
if (bitmapWidth.get() == 0 || bitmapHeight.get() == 0) {
|
||||
val options = BitmapFactory.Options()
|
||||
options.inJustDecodeBounds = true
|
||||
BitmapFactory.decodeByteArray(data,0 , data.size, options)
|
||||
bitmapWidth.set(options.outWidth)
|
||||
bitmapHeight.set(options.outHeight)
|
||||
}
|
||||
Log.d(TAG, "-- onSweeperFutianBackCameraVideo -- bitmap:[${bitmapWidth.get()}, ${bitmapHeight.get()}] -- data: ${data.size}")
|
||||
var old = pool.acquire()
|
||||
try {
|
||||
if (old == null) {
|
||||
old = LookAroundData(data, bitmapWidth.get(), bitmapHeight.get(), targetX.get(), targetY.get(), targetWidth.get(), targetHeight.get())
|
||||
} else {
|
||||
old.data = data
|
||||
old.bitmapWidth = bitmapWidth.get()
|
||||
old.bitmapHeight = bitmapHeight.get()
|
||||
old.targetX = targetX.get()
|
||||
old.targetY = targetY.get()
|
||||
old.targetWidth = targetWidth.get()
|
||||
old.targetHeight = targetHeight.get()
|
||||
}
|
||||
channel.trySend(old)
|
||||
} finally {
|
||||
if (old != null) {
|
||||
pool.release(old)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override fun onGetParamResp(header: Header, getParamResp: SetParamReq, adasParam: AdasParam) {
|
||||
Log.d(TAG, "-- onGetParamResp -- 1 --")
|
||||
val parse = adasParam.m1StitchedVideoSelfVehicleParamParse
|
||||
if (parse != null) {
|
||||
targetX.set(parse.x)
|
||||
targetY.set(parse.y)
|
||||
targetWidth.set(parse.width)
|
||||
targetHeight.set(parse.height)
|
||||
Log.d(TAG, "-- onGetParamResp -- 2 --:[x: ${parse.x}, y: ${parse.y}, width: ${parse.width}, height: ${parse.height}]")
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -8,16 +8,13 @@ import androidx.lifecycle.*
|
||||
import androidx.lifecycle.Lifecycle.Event
|
||||
import androidx.lifecycle.Lifecycle.Event.ON_CREATE
|
||||
import androidx.lifecycle.Lifecycle.Event.ON_DESTROY
|
||||
import com.mogo.eagle.core.function.api.autopilot.IMoGoAutopilotStatusListener
|
||||
import com.mogo.eagle.core.function.call.autopilot.*
|
||||
import com.mogo.eagle.core.utilcode.kotlin.*
|
||||
import com.mogo.eagle.core.utilcode.mogo.logger.*
|
||||
import com.mogo.eagle.core.utilcode.mogo.logger.scene.SceneConstant.Companion.M_DEVA
|
||||
import com.mogo.eagle.core.utilcode.util.*
|
||||
import com.zhjt.mogo_core_function_devatools.status.entity.CanStatus
|
||||
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.NetStatus
|
||||
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
|
||||
@@ -26,13 +23,11 @@ import com.zhjt.mogo_core_function_devatools.status.flow.IFlow
|
||||
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
|
||||
//import com.zhjt.mogo_core_function_devatools.status.flow.nets.NetsImpl
|
||||
import com.zhjt.mogo_core_function_devatools.status.flow.rtk.RTKImpl
|
||||
import com.zhjt.mogo_core_function_devatools.status.flow.trace.TracingImpl
|
||||
import com.zhjt.mogo_core_function_devatools.status.ui.StatusView
|
||||
import kotlinx.coroutines.*
|
||||
import kotlinx.coroutines.flow.*
|
||||
import mogo_msg.MogoReportMsg
|
||||
import java.lang.ref.*
|
||||
import java.util.concurrent.*
|
||||
|
||||
@@ -42,52 +37,14 @@ object StatusManager {
|
||||
private const val TAG = "StatusManager"
|
||||
|
||||
private lateinit var model: StatusModel
|
||||
// private var timer: Job? = null
|
||||
private var hasInit = false
|
||||
private val listeners by lazy { CopyOnWriteArrayList<IStatusListener>() }
|
||||
private var container: WeakReference<ViewGroup>? = null
|
||||
|
||||
// private val listener = object : IMoGoAutopilotStatusListener {
|
||||
// override fun onAutopilotGuardian(guardianInfo: MogoReportMsg.MogoReportMessage?) {
|
||||
// super.onAutopilotGuardian(guardianInfo)
|
||||
// guardianInfo?.code?.takeIf {
|
||||
// CallerLogger.d("$M_DEVA$TAG", "-- onAutopilotGuardian ---: code: $it")
|
||||
// it.contains("RTK_STATUS", true) || it.contains("CAN", true) || it == "ILCT_RTK_OR_SLAM_CHANGE"
|
||||
// }?.run {
|
||||
// CallerLogger.d("$M_DEVA$TAG", "-- onAutopilotGuardian trigger req ---: code: $this")
|
||||
// req()
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
|
||||
// private val appStateListener = object : IAppStateListener {
|
||||
//
|
||||
// override fun onAppStateChanged(isForeground: Boolean) {
|
||||
// if (isForeground) {
|
||||
// req()
|
||||
// } else {
|
||||
// timer?.cancel()
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
|
||||
private val flows: ArrayList<IFlow<out Status>> by lazy {
|
||||
ArrayList()
|
||||
}
|
||||
|
||||
// private fun req() {
|
||||
// timer?.cancel()
|
||||
// model.viewModelScope.launch(Dispatchers.IO) {
|
||||
// CallerAutoPilotManager.sendStatusQueryReq()
|
||||
// while (true) {
|
||||
// delay(60000) //一分钟主动请求一次
|
||||
// CallerAutoPilotManager.sendStatusQueryReq()
|
||||
// }
|
||||
// }.also {
|
||||
// timer = it
|
||||
// }
|
||||
// }
|
||||
|
||||
fun init(ctx: Context) {
|
||||
if (hasInit) {
|
||||
return
|
||||
@@ -109,14 +66,10 @@ object StatusManager {
|
||||
|
||||
private fun onCreate(ctx: Context) {
|
||||
val values = model.status.value?.second ?: throw IllegalStateException("state is not right.")
|
||||
// CallerAutoPilotStatusListenerManager.addListener(TAG, listener)
|
||||
// AppStateManager.registerAppStateListener(appStateListener)
|
||||
// req()
|
||||
values.map {
|
||||
when (it) {
|
||||
is CanStatus -> CanImpl(ctx)
|
||||
is IpcStatus -> IpcImpl(ctx)
|
||||
// is NetStatus -> NetsImpl(ctx)
|
||||
is GpsStatus -> GpsImpl(ctx)
|
||||
is TracingStatus -> TracingImpl(ctx)
|
||||
is RTKStatus -> RTKImpl(ctx)
|
||||
@@ -138,16 +91,6 @@ object StatusManager {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
fun registerListener(listener: IStatusListener) {
|
||||
listeners.add(listener)
|
||||
}
|
||||
|
||||
|
||||
fun unRegisterListener(listener: IStatusListener) {
|
||||
listeners.remove(listener)
|
||||
}
|
||||
|
||||
fun show(container: ViewGroup) {
|
||||
if (container.childCount > 0) {
|
||||
if (container.visibility != View.VISIBLE) {
|
||||
@@ -166,9 +109,6 @@ object StatusManager {
|
||||
|
||||
private fun onDestroy(ctx: Context) {
|
||||
hasInit = false
|
||||
// CallerAutoPilotStatusListenerManager.removeListener(TAG)
|
||||
// AppStateManager.unRegisterAppStateListener(appStateListener)
|
||||
// timer?.cancel()
|
||||
flows.forEach {
|
||||
it.onDestroy()
|
||||
}
|
||||
|
||||
@@ -23,7 +23,6 @@ internal class StatusModel : ViewModel() {
|
||||
it += CanStatus(false)
|
||||
it += TracingStatus(UNKNOWN)
|
||||
it += RTKStatus("", -1)
|
||||
// it += NetStatus(false)
|
||||
it += GpsStatus(enabled = false, isGranted = false)
|
||||
})
|
||||
}
|
||||
|
||||
@@ -3,7 +3,10 @@ package com.mogo.eagle.core.function.hmi.ui
|
||||
import android.content.Context
|
||||
import android.text.TextUtils
|
||||
import android.util.*
|
||||
import android.view.ViewGroup
|
||||
import android.view.*
|
||||
import android.view.ViewGroup.LayoutParams
|
||||
import android.widget.FrameLayout
|
||||
import androidx.core.view.*
|
||||
import androidx.lifecycle.ProcessLifecycleOwner
|
||||
import androidx.lifecycle.lifecycleScope
|
||||
import com.alibaba.android.arouter.facade.annotation.Route
|
||||
@@ -22,9 +25,10 @@ import com.mogo.eagle.core.data.biz.notice.NoticeNormalData
|
||||
import com.mogo.eagle.core.data.biz.notice.NoticeTrafficStylePushData
|
||||
import com.mogo.eagle.core.function.api.hmi.warning.IMoGoHmiProvider
|
||||
import com.mogo.eagle.core.function.api.hmi.warning.IMoGoWarningStatusListener
|
||||
import com.mogo.eagle.core.function.call.hmi.CallerHmiViewControlListenerManager
|
||||
import com.mogo.eagle.core.function.call.hmi.*
|
||||
import com.mogo.eagle.core.function.call.v2x.CallerV2XWarningListenerManager
|
||||
import com.mogo.eagle.core.function.hmi.ui.camera.RoadVideoDialog
|
||||
import com.mogo.eagle.core.function.hmi.ui.lookaround.*
|
||||
import com.mogo.eagle.core.function.hmi.ui.notice.DispatchDialogManager
|
||||
import com.mogo.eagle.core.function.hmi.ui.notice.NoticeCheckDialog
|
||||
import com.mogo.eagle.core.function.hmi.ui.notice.traffic.NoticeTrafficDialog
|
||||
@@ -35,15 +39,17 @@ import com.mogo.eagle.core.function.hmi.ui.tools.ModifyBindingCarDialog
|
||||
import com.mogo.eagle.core.function.hmi.ui.tools.ToBindingCarDialog
|
||||
import com.mogo.eagle.core.function.hmi.ui.tools.UpgradeAppDialog
|
||||
import com.mogo.eagle.core.function.hmi.ui.widget.StatusBarView
|
||||
import com.mogo.eagle.core.utilcode.floating.*
|
||||
import com.mogo.eagle.core.utilcode.kotlin.safeCancel
|
||||
import com.mogo.eagle.core.utilcode.mogo.AppIdentityModeUtils
|
||||
import com.mogo.eagle.core.utilcode.mogo.logger.CallerLogger
|
||||
import com.mogo.eagle.core.utilcode.mogo.logger.scene.SceneConstant
|
||||
import com.mogo.eagle.core.utilcode.mogo.logger.scene.SceneConstant.Companion.M_HMI
|
||||
import com.mogo.eagle.core.utilcode.util.ThreadUtils
|
||||
import com.mogo.eagle.core.utilcode.util.*
|
||||
import com.zhjt.service_biz.BizConfig
|
||||
import kotlinx.coroutines.*
|
||||
import kotlinx.coroutines.selects.*
|
||||
import java.lang.ref.WeakReference
|
||||
import java.util.concurrent.atomic.AtomicReference
|
||||
|
||||
/**
|
||||
@@ -62,6 +68,11 @@ class MoGoHmiProvider : IMoGoHmiProvider {
|
||||
private var lastShowV2XJob: Job? = null
|
||||
private var context: Context? = null
|
||||
|
||||
/**
|
||||
* 360环视窗口引用
|
||||
*/
|
||||
private val lookAround by lazy { AtomicReference<MoGoPopWindow>() }
|
||||
|
||||
private val scope by lazy { CoroutineScope(Dispatchers.Default + SupervisorJob()) }
|
||||
|
||||
override fun init(context: Context?) {
|
||||
@@ -312,4 +323,38 @@ class MoGoHmiProvider : IMoGoHmiProvider {
|
||||
}
|
||||
}
|
||||
|
||||
override fun show360LookAround() {
|
||||
val activity = AppStateManager.currentActivity() ?: return
|
||||
val old = lookAround.get()
|
||||
if (old != null && old.isShowing()) {
|
||||
return
|
||||
}
|
||||
old?.hide()
|
||||
MoGoPopWindow.Builder()
|
||||
.attachToActivity(activity)
|
||||
.contentView(M1LookAroundView(activity))
|
||||
.draggable(true)
|
||||
.isDismissOnTouchOutside(false)
|
||||
.gravityInActivity(Gravity.CENTER)
|
||||
.width(700)
|
||||
.height(1400)
|
||||
.onDismissed {
|
||||
lookAround.set(null)
|
||||
}
|
||||
.build().also {
|
||||
lookAround.set(it)
|
||||
}.show()
|
||||
}
|
||||
|
||||
override fun hide360LookAround() {
|
||||
val old = lookAround.get()
|
||||
if (old == null || !old.isShowing()) {
|
||||
return
|
||||
}
|
||||
old.hide()
|
||||
}
|
||||
|
||||
override fun is360LookAroundShowing(): Boolean {
|
||||
return lookAround.get()?.isShowing() ?: false
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,347 @@
|
||||
package com.mogo.eagle.core.function.hmi.ui.lookaround
|
||||
|
||||
import android.content.*
|
||||
import android.graphics.*
|
||||
import android.graphics.Paint.Style.STROKE
|
||||
import android.os.Handler
|
||||
import android.os.HandlerThread
|
||||
import android.os.SystemClock
|
||||
import android.util.*
|
||||
import android.view.SurfaceHolder
|
||||
import android.view.SurfaceView
|
||||
import android.widget.Toast
|
||||
import com.mogo.eagle.core.function.api.autopilot.*
|
||||
import com.mogo.eagle.core.function.api.lookaround.data.*
|
||||
import com.mogo.eagle.core.function.call.autopilot.*
|
||||
import com.mogo.eagle.core.function.call.devatools.*
|
||||
import com.mogo.eagle.core.utilcode.kotlin.*
|
||||
import com.mogo.eagle.core.utilcode.util.ThreadUtils
|
||||
import com.mogo.eagle.core.utilcode.util.Utils
|
||||
import kotlinx.coroutines.*
|
||||
import kotlinx.coroutines.Runnable
|
||||
import kotlinx.coroutines.flow.*
|
||||
import java.util.concurrent.atomic.AtomicReference
|
||||
import kotlin.math.*
|
||||
|
||||
class M1LookAroundView: SurfaceView, SurfaceHolder.Callback, Runnable, IMoGoChassisSteeringStateListener {
|
||||
|
||||
constructor(context: Context?) : super(context)
|
||||
constructor(context: Context?, attrs: AttributeSet?) : super(context, attrs)
|
||||
constructor(context: Context?, attrs: AttributeSet?, defStyleAttr: Int) : super(context, attrs, defStyleAttr)
|
||||
|
||||
companion object {
|
||||
private const val TAG = "M1LookAroundView"
|
||||
|
||||
private const val BROKE_LINE_LENGTH = 40f
|
||||
|
||||
private const val VEHICLE_STEERING_RATIO = 21
|
||||
}
|
||||
|
||||
init {
|
||||
holder.addCallback(this)
|
||||
}
|
||||
|
||||
private val handler by lazy { AtomicReference<Handler>() }
|
||||
|
||||
private val bitmapPaint by lazy { Paint(Paint.ANTI_ALIAS_FLAG or Paint.FILTER_BITMAP_FLAG).also { it.xfermode = null } }
|
||||
|
||||
private val routerPaint = Paint().also {
|
||||
it.color = Color.RED
|
||||
it.isAntiAlias = true
|
||||
it.style = STROKE
|
||||
it.strokeWidth = 5f
|
||||
}
|
||||
|
||||
private val brokePaint = Paint().also {
|
||||
it.color = Color.RED
|
||||
it.isAntiAlias = true
|
||||
it.style = STROKE
|
||||
it.strokeJoin = Paint.Join.ROUND
|
||||
it.strokeWidth = 5f
|
||||
}
|
||||
|
||||
private val brokePath by lazy { Path() }
|
||||
|
||||
private val routerPath = Path()
|
||||
|
||||
private val innerRect by lazy { RectF() }
|
||||
|
||||
private val outerRect by lazy { RectF() }
|
||||
|
||||
/**
|
||||
* 方向盘转角
|
||||
*/
|
||||
@Volatile
|
||||
private var steering: Float = 0f
|
||||
|
||||
@Volatile
|
||||
private var surfaceWidth = 0
|
||||
|
||||
@Volatile
|
||||
private var surfaceHeight = 0
|
||||
|
||||
@Volatile
|
||||
private var isSurfaceValid = false
|
||||
|
||||
@Volatile
|
||||
private var data: LookAroundData? = null
|
||||
|
||||
override fun surfaceCreated(holder: SurfaceHolder?) {
|
||||
val old = handler.get()
|
||||
if (old == null) {
|
||||
handler.set(HandlerThread("look-around-drawer").let { it.start(); Handler(it.looper) })
|
||||
} else {
|
||||
old.looper.quitSafely()
|
||||
handler.set(HandlerThread("look-around-drawer").let { it.start(); Handler(it.looper) })
|
||||
}
|
||||
handler.get()?.removeCallbacks(this)
|
||||
handler.get()?.post(this)
|
||||
isSurfaceValid = true
|
||||
}
|
||||
|
||||
override fun surfaceChanged(holder: SurfaceHolder?, format: Int, width: Int, height: Int) {
|
||||
this.surfaceWidth = width
|
||||
this.surfaceHeight = height
|
||||
}
|
||||
|
||||
override fun surfaceDestroyed(holder: SurfaceHolder?) {
|
||||
isSurfaceValid = false
|
||||
}
|
||||
|
||||
override fun run() {
|
||||
var isTimedBlock = false
|
||||
try {
|
||||
Log.d(TAG, "--- 1 ---")
|
||||
if (!isSurfaceValid) {
|
||||
isTimedBlock = true
|
||||
return
|
||||
}
|
||||
if (this.surfaceWidth <= 0 || this.surfaceHeight <= 0) {
|
||||
Log.d(TAG, "--- 2 ---")
|
||||
isTimedBlock = true
|
||||
return
|
||||
}
|
||||
Log.d(TAG, "--- 3 ---")
|
||||
val data = this.data ?: return
|
||||
val targetX = data.targetX
|
||||
val targetY = data.targetY
|
||||
val targetWidth = data.targetWidth
|
||||
val targetHeight = data.targetHeight
|
||||
val bitmapWidth = data.bitmapWidth
|
||||
val bitmapHeight = data.bitmapHeight
|
||||
val scaleX = this.surfaceWidth * 1.0f / bitmapWidth
|
||||
val scaleY = this.surfaceHeight * 1.0f / bitmapHeight
|
||||
val bytes = data.data
|
||||
if (bytes == null) {
|
||||
isTimedBlock = true
|
||||
Log.d(TAG, "--- 4 ---")
|
||||
return
|
||||
}
|
||||
Log.d(TAG, "--- 5 ---")
|
||||
val canvas = holder.lockCanvas()
|
||||
try {
|
||||
if (canvas == null) {
|
||||
Log.d(TAG, "--- 6 ---")
|
||||
isTimedBlock = true
|
||||
return
|
||||
}
|
||||
//1. 绘制图片
|
||||
var startTime = SystemClock.elapsedRealtime()
|
||||
val bitmap = BitmapFactory.decodeByteArray(bytes, 0, bytes.size)
|
||||
Log.d(TAG, "--- cost for decode bitmap: ${SystemClock.elapsedRealtime() - startTime}ms.")
|
||||
if (bitmap == null) {
|
||||
Log.d(TAG, "--- 7 ---")
|
||||
isTimedBlock = true
|
||||
return
|
||||
}
|
||||
try {
|
||||
startTime = SystemClock.elapsedRealtime()
|
||||
canvas.save()
|
||||
canvas.scale(scaleX, scaleY)
|
||||
canvas.drawBitmap(bitmap, 0f, 0f, bitmapPaint)
|
||||
} finally {
|
||||
canvas.restore()
|
||||
if (!bitmap.isRecycled) {
|
||||
bitmap.recycle()
|
||||
}
|
||||
Log.d(TAG, "--- draw decoded bitmap cost: ${SystemClock.elapsedRealtime() - startTime}ms.")
|
||||
}
|
||||
//2. 绘制车的信息
|
||||
Log.d(TAG, "--- 8 ---")
|
||||
val newTargetX = targetX * scaleX
|
||||
val newTargetY = targetY * scaleY
|
||||
val newTargetWidth = targetWidth * scaleX
|
||||
val newTargetHeight = targetHeight * scaleY
|
||||
try {
|
||||
//2.1 绘制车前的转向角
|
||||
canvas.save()
|
||||
var steering = this.steering
|
||||
if (abs(steering) < 1) {
|
||||
steering = 0f
|
||||
}
|
||||
if (steering == 0f) {
|
||||
canvas.translate(newTargetX + newTargetWidth * 0.5f, newTargetY)
|
||||
routerPath.reset()
|
||||
val halfX = newTargetWidth * 0.5f
|
||||
var startX = - halfX
|
||||
val startY= 0f
|
||||
routerPath.moveTo(startX, startY)
|
||||
var endX = startX
|
||||
val endY = - newTargetY
|
||||
routerPath.lineTo(endX, endY)
|
||||
canvas.drawPath(routerPath, routerPaint)
|
||||
startX += newTargetWidth
|
||||
endX += newTargetWidth
|
||||
routerPath.reset()
|
||||
routerPath.moveTo(startX, startY)
|
||||
routerPath.lineTo(endX, endY)
|
||||
canvas.drawPath(routerPath, routerPaint)
|
||||
} else {
|
||||
val outerAngle = abs(steering * 1.0 / VEHICLE_STEERING_RATIO)
|
||||
val radians = Math.toRadians(outerAngle)
|
||||
val d = (newTargetHeight / tan(radians)).toFloat()
|
||||
if (steering < 0) {
|
||||
// 左打轮
|
||||
// 将坐标原点平移到圆心
|
||||
canvas.translate(newTargetX - (d - newTargetWidth), newTargetY + newTargetHeight)
|
||||
//外圆半径
|
||||
val outerR = (newTargetHeight / sin(radians)).toFloat()
|
||||
//内圆半径
|
||||
val innerR = sqrt((newTargetHeight * 1.0).pow(2.0) + ((d - newTargetWidth) * 1.0).pow(2.0)).toFloat()
|
||||
val innerAngle = Math.toDegrees(asin(newTargetHeight / innerR) * 1.0)
|
||||
outerRect.set(-outerR, -outerR, outerR, outerR)
|
||||
innerRect.set(-innerR, -innerR, innerR, innerR)
|
||||
canvas.drawArc(outerRect, -outerAngle.toFloat(), -60f, false, routerPaint)
|
||||
canvas.drawArc(innerRect, -innerAngle.toFloat(), -60f, false, routerPaint)
|
||||
}
|
||||
|
||||
if (steering > 0) {
|
||||
//右打轮
|
||||
// 将坐标原点平移到圆心
|
||||
canvas.translate(newTargetX + d, newTargetY + newTargetHeight)
|
||||
//外圆半径
|
||||
val outerR = (newTargetHeight / sin(radians)).toFloat()
|
||||
//内圆半径
|
||||
val innerR = sqrt((newTargetHeight * 1.0).pow(2.0) + ((d - newTargetWidth) * 1.0).pow(2.0)).toFloat()
|
||||
val innerAngle = Math.toDegrees(asin(newTargetHeight / innerR) * 1.0)
|
||||
outerRect.set(-outerR, -outerR, outerR, outerR)
|
||||
innerRect.set(-innerR, -innerR, innerR, innerR)
|
||||
canvas.drawArc(outerRect, 180f + outerAngle.toFloat(), 60f, false, routerPaint)
|
||||
canvas.drawArc(innerRect, 180f + innerAngle.toFloat(), 60f, false, routerPaint)
|
||||
}
|
||||
}
|
||||
} finally {
|
||||
canvas.restore()
|
||||
}
|
||||
|
||||
try {
|
||||
//2.2 绘制车周围盲区标定
|
||||
canvas.save()
|
||||
canvas.translate(newTargetX + newTargetWidth * 0.5f, newTargetY)
|
||||
Log.d(TAG, "--- 9 ---:[$targetX:$newTargetX, $targetY:$newTargetY, $targetWidth:$newTargetWidth, $targetHeight:$newTargetHeight]")
|
||||
val halfTargetWidth = newTargetWidth * 0.5f
|
||||
var startX = -halfTargetWidth
|
||||
var startY = BROKE_LINE_LENGTH
|
||||
var endX = startX
|
||||
var endY = 0f
|
||||
// 绘制左上角
|
||||
brokePath.reset()
|
||||
brokePath.moveTo(startX, startY)
|
||||
brokePath.lineTo(endX, endY)
|
||||
endX += BROKE_LINE_LENGTH
|
||||
brokePath.lineTo(endX, endY)
|
||||
canvas.drawPath(brokePath, brokePaint)
|
||||
|
||||
// 绘制右上角
|
||||
startX = halfTargetWidth - BROKE_LINE_LENGTH
|
||||
startY = 0f
|
||||
|
||||
endX = halfTargetWidth
|
||||
endY = 0f
|
||||
brokePath.reset()
|
||||
brokePath.moveTo(startX, startY)
|
||||
brokePath.lineTo(endX, endY)
|
||||
endY += BROKE_LINE_LENGTH
|
||||
brokePath.lineTo(endX, endY)
|
||||
canvas.drawPath(brokePath, brokePaint)
|
||||
|
||||
//绘制左下角
|
||||
startX = -halfTargetWidth
|
||||
startY = newTargetHeight - BROKE_LINE_LENGTH
|
||||
endX = startX
|
||||
endY = newTargetHeight
|
||||
brokePath.reset()
|
||||
brokePath.moveTo(startX, startY)
|
||||
brokePath.lineTo(endX, endY)
|
||||
endX += BROKE_LINE_LENGTH
|
||||
brokePath.lineTo(endX, endY)
|
||||
canvas.drawPath(brokePath, brokePaint)
|
||||
|
||||
//绘制右下角
|
||||
startX = halfTargetWidth - BROKE_LINE_LENGTH
|
||||
startY = newTargetHeight
|
||||
endX = halfTargetWidth
|
||||
endY = startY
|
||||
brokePath.reset()
|
||||
brokePath.moveTo(startX, startY)
|
||||
brokePath.lineTo(endX, endY)
|
||||
endY -= BROKE_LINE_LENGTH
|
||||
brokePath.lineTo(endX, endY)
|
||||
canvas.drawPath(brokePath, brokePaint)
|
||||
} finally {
|
||||
canvas.restore()
|
||||
}
|
||||
} finally {
|
||||
if (canvas != null) {
|
||||
holder.unlockCanvasAndPost(canvas)
|
||||
}
|
||||
}
|
||||
} finally {
|
||||
if (isTimedBlock) {
|
||||
try {
|
||||
Thread.sleep(2000)
|
||||
} catch (ignore: Exception) { }
|
||||
}
|
||||
handler.get().post(this)
|
||||
}
|
||||
}
|
||||
|
||||
override fun onAttachedToWindow() {
|
||||
super.onAttachedToWindow()
|
||||
CallerChassisSteeringStateListenerManager.addListener(TAG, this)
|
||||
Log.d(TAG, "--- 发起订阅 ---")
|
||||
CallerAutoPilotControlManager.setIsSubscribeM1StitchedVideo(true)
|
||||
scope.launch(ThreadUtils.getCpuPool().asCoroutineDispatcher()) {
|
||||
CallerDevaToolsManager.lookAroundProvider()?.flow()?.also { flow ->
|
||||
flow.onEach {
|
||||
Log.d(TAG, "-- onEach ---:$it")
|
||||
if (it.isValid()) {
|
||||
data = it
|
||||
}
|
||||
}.collect()
|
||||
}
|
||||
}
|
||||
|
||||
// 订阅后,5秒内未收到有效数据, 提示用户当前MAP版本不支持
|
||||
scope.launch {
|
||||
delay(5000)
|
||||
val d = data
|
||||
if (d == null || !d.isValid()) {
|
||||
Toast.makeText(Utils.getApp(), "当前MAP版本不支持360环视,请升级MAP版本", Toast.LENGTH_SHORT).show()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override fun onDetachedFromWindow() {
|
||||
super.onDetachedFromWindow()
|
||||
CallerChassisSteeringStateListenerManager.removeListener(TAG)
|
||||
Log.d(TAG, "--- 取消订阅 ---")
|
||||
CallerAutoPilotControlManager.setIsSubscribeM1StitchedVideo(false)
|
||||
handler.get()?.looper?.quitSafely()
|
||||
}
|
||||
|
||||
override fun onAutopilotSteeringData(steering: Float) {
|
||||
Log.d(TAG, "--- onAutopilotSteeringData --: steering: $steering")
|
||||
this.steering = steering
|
||||
}
|
||||
}
|
||||
@@ -223,6 +223,23 @@ internal class SOPSettingView @JvmOverloads constructor(
|
||||
FunctionBuildConfig.isNewV2NData = isChecked
|
||||
}
|
||||
|
||||
// M1 360度环视
|
||||
tbNew360LookAround?.also {
|
||||
if (!AppIdentityModeUtils.isM1(FunctionBuildConfig.appIdentityMode)) {
|
||||
it.isEnabled = false
|
||||
} else {
|
||||
it.isEnabled = true
|
||||
it.setOnCheckedChangeListener { _, isChecked ->
|
||||
if (isChecked) {
|
||||
CallerHmiManager.showM1360LookAround()
|
||||
} else {
|
||||
CallerHmiManager.hidM1360LookAround()
|
||||
}
|
||||
}
|
||||
it.isChecked = CallerHmiManager.isM1360LookAroundShowing()
|
||||
}
|
||||
}
|
||||
|
||||
//变道绕障的目标障碍物速度阈值
|
||||
tvSpeed.text = "${FunctionBuildConfig.detouringSpeed} m/s"
|
||||
ivSpeedReduce.setOnClickListener {
|
||||
|
||||
@@ -1,87 +0,0 @@
|
||||
package com.mogo.eagle.core.function.hmi.ui.widget;
|
||||
|
||||
|
||||
import android.content.Context;
|
||||
import android.graphics.Bitmap;
|
||||
import android.graphics.drawable.Drawable;
|
||||
import android.util.AttributeSet;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
import androidx.appcompat.widget.AppCompatImageView;
|
||||
|
||||
import com.bumptech.glide.Priority;
|
||||
import com.bumptech.glide.load.engine.DiskCacheStrategy;
|
||||
import com.bumptech.glide.request.RequestOptions;
|
||||
import com.bumptech.glide.request.target.CustomTarget;
|
||||
import com.bumptech.glide.request.transition.Transition;
|
||||
import com.mogo.eagle.core.function.api.autopilot.IMoGoSweeperFutianBackCameraVideoListener;
|
||||
import com.mogo.eagle.core.function.call.autopilot.CallerSweeperFutianBackCameraVideoListenerManager;
|
||||
import com.mogo.eagle.core.utilcode.mogo.glide.GlideApp;
|
||||
import com.mogo.eagle.core.utilcode.util.ThreadUtils;
|
||||
|
||||
/**
|
||||
* 清扫车摄像头展示View
|
||||
*/
|
||||
public class SweeperVideoView extends AppCompatImageView implements IMoGoSweeperFutianBackCameraVideoListener {
|
||||
private static final String TAG = SweeperVideoView.class.getSimpleName();
|
||||
private final RequestOptions requestOptions = new RequestOptions()
|
||||
.priority(Priority.HIGH)
|
||||
.skipMemoryCache(true)
|
||||
.diskCacheStrategy(DiskCacheStrategy.NONE)
|
||||
.dontAnimate();
|
||||
|
||||
public SweeperVideoView(@NonNull Context context) {
|
||||
super(context);
|
||||
}
|
||||
|
||||
public SweeperVideoView(@NonNull Context context, @Nullable AttributeSet attrs) {
|
||||
super(context, attrs);
|
||||
}
|
||||
|
||||
public SweeperVideoView(@NonNull Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
|
||||
super(context, attrs, defStyleAttr);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onAttachedToWindow() {
|
||||
super.onAttachedToWindow();
|
||||
CallerSweeperFutianBackCameraVideoListenerManager.INSTANCE.addListener(TAG, this);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onDetachedFromWindow() {
|
||||
super.onDetachedFromWindow();
|
||||
CallerSweeperFutianBackCameraVideoListenerManager.INSTANCE.removeListener(this);
|
||||
}
|
||||
|
||||
private final CustomTarget<Bitmap> target = new CustomTarget<Bitmap>() {
|
||||
@Override
|
||||
public void onResourceReady(@NonNull Bitmap resource, @Nullable Transition<? super Bitmap> transition) {
|
||||
//回调内容
|
||||
if (!resource.isRecycled()) {
|
||||
SweeperVideoView.this.setImageBitmap(resource);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onLoadCleared(@Nullable Drawable placeholder) {
|
||||
//这个方法在target被回收时调用,如果在除了imageView以外的地方引用了imageView中的bitmap,在这里清除引用以避免崩溃
|
||||
}
|
||||
};
|
||||
|
||||
@Override
|
||||
public void onSweeperFutianBackCameraVideo(@NonNull byte[] data) {
|
||||
ThreadUtils.runOnUiThread(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
GlideApp.with(SweeperVideoView.this)
|
||||
.asBitmap()
|
||||
.load(data)
|
||||
.placeholder(SweeperVideoView.this.getDrawable())
|
||||
.apply(requestOptions)
|
||||
.into(target);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent">
|
||||
|
||||
<com.mogo.eagle.core.function.hmi.ui.widget.MogoVideoView
|
||||
android:id="@+id/mogo_video_view"
|
||||
android:layout_width="0dip"
|
||||
android:layout_height="0dip"
|
||||
app:layout_constraintTop_toTopOf="parent"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintEnd_toEndOf="parent"/>
|
||||
|
||||
<com.mogo.eagle.core.function.hmi.ui.lookaround.BezierView
|
||||
android:id="@+id/mogo_bezier_view"
|
||||
android:layout_width="0dip"
|
||||
android:layout_height="0dip"
|
||||
android:background="@android:color/transparent"
|
||||
app:layout_constraintTop_toTopOf="@+id/mogo_video_view"
|
||||
app:layout_constraintBottom_toBottomOf="@+id/mogo_video_view"
|
||||
app:layout_constraintStart_toStartOf="@+id/mogo_video_view"
|
||||
app:layout_constraintEnd_toEndOf="@+id/mogo_video_view"/>
|
||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||
@@ -261,6 +261,19 @@
|
||||
app:layout_constraintRight_toLeftOf="@id/verticalGuideLine"
|
||||
/>
|
||||
|
||||
<androidx.appcompat.widget.SwitchCompat
|
||||
android:id="@+id/tbNew360LookAround"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="360环视"
|
||||
android:paddingTop="25dp"
|
||||
android:paddingBottom="25dp"
|
||||
android:scaleY="1.2"
|
||||
android:scaleX="1.2"
|
||||
app:layout_constraintTop_toBottomOf="@id/tbIPCReport"
|
||||
app:layout_constraintLeft_toRightOf="@+id/verticalGuideLine"
|
||||
app:layout_constraintRight_toRightOf="parent" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/tvSpeedThresholdTitle"
|
||||
android:layout_width="wrap_content"
|
||||
|
||||
@@ -11,6 +11,7 @@ import com.zhjt.mogo.adas.data.sweeper.task.SweeperTask.StartTaskResp
|
||||
import com.zhjt.mogo.adas.data.sweeper.task.SweeperTaskSuspendResume.SuspendResumeTaskReq
|
||||
import com.zhjt.mogo.adas.data.sweeper.task.confirm.SweeperTaskConfirm.TaskConfirmResp
|
||||
import com.zhjt.mogo.adas.data.sweeper.task.stop.SweeperTaskStop.StopTaskResp
|
||||
import com.zhjt.mogo.adas.data.AdasConstants
|
||||
|
||||
/**
|
||||
* @author xiaoyuzhou
|
||||
@@ -208,7 +209,7 @@ interface IMoGoAutopilotControlProvider : IMoGoFunctionServerProvider {
|
||||
* @param paramType 参数类型{@link com.zhidao.support.adas.high.common.Constants.PARAM_TYPE}
|
||||
* @return boolean
|
||||
*/
|
||||
fun sendGetParamReq(paramType: Int): Boolean
|
||||
fun sendGetParamReq(paramType: AdasConstants.MapSystemParamType): Boolean
|
||||
|
||||
/**
|
||||
* 获取数据采集录制模式配置列表
|
||||
|
||||
@@ -0,0 +1,20 @@
|
||||
package com.mogo.eagle.core.function.api.autopilot
|
||||
|
||||
import com.zhjt.mogo.adas.data.bean.*
|
||||
import mogo.telematics.pad.*
|
||||
|
||||
|
||||
interface IMoGoGetParamResponseListener {
|
||||
|
||||
/**
|
||||
* 参数获取应答
|
||||
* <p>
|
||||
* 调用{@link AdasManager#sendGetAllParamReq()}或{@link AdasManager#sendGetParamReq(int)}
|
||||
* 如果对应的value是空串,说明没有这个param或者get失败了。重启后值还是在redis里
|
||||
*
|
||||
* @param header 头
|
||||
* @param getParamResp 配置参数
|
||||
* @param adasParam 解析后的配置参数
|
||||
*/
|
||||
fun onGetParamResp(header: MessagePad.Header, getParamResp: MessagePad.SetParamReq, adasParam: AdasParam)
|
||||
}
|
||||
@@ -14,6 +14,7 @@ import com.mogo.eagle.core.data.msgbox.MsgBoxBean
|
||||
import com.mogo.eagle.core.function.api.devatools.apm.*
|
||||
import com.mogo.eagle.core.function.api.devatools.strict.*
|
||||
import com.mogo.eagle.core.function.api.devatools.download.*
|
||||
import com.mogo.eagle.core.function.api.lookaround.*
|
||||
import com.mogo.eagle.core.function.api.upgrade.*
|
||||
|
||||
/**
|
||||
@@ -205,4 +206,10 @@ interface IDevaToolsProvider : IProvider {
|
||||
fun upgradeProvider(): IMoGoUpgradeProvider?
|
||||
|
||||
fun strict(): IStrictModeProvider
|
||||
|
||||
|
||||
/**
|
||||
* 360环视数据提供者
|
||||
*/
|
||||
fun lookAroundDataProvider(): IMoGoLookAroundProvider
|
||||
}
|
||||
@@ -133,4 +133,19 @@ interface IMoGoHmiProvider :IProvider{
|
||||
fun updateStatusBarDownloadView(insert: Boolean, tag: String, progress: Int)
|
||||
|
||||
|
||||
/**
|
||||
* 展示360环视弹窗,主要用于M1车型
|
||||
*/
|
||||
fun show360LookAround()
|
||||
|
||||
/**
|
||||
* 隐藏360环视弹窗,主要用于M1车型
|
||||
*/
|
||||
fun hide360LookAround()
|
||||
|
||||
|
||||
/**
|
||||
* 360环视弹窗是否正在展示
|
||||
*/
|
||||
fun is360LookAroundShowing(): Boolean
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
package com.mogo.eagle.core.function.api.lookaround
|
||||
|
||||
import android.content.Context
|
||||
import com.mogo.eagle.core.function.api.lookaround.data.*
|
||||
import kotlinx.coroutines.flow.*
|
||||
|
||||
interface IMoGoLookAroundProvider {
|
||||
|
||||
fun init(ctx: Context)
|
||||
|
||||
fun flow(): Flow<LookAroundData>
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
package com.mogo.eagle.core.function.api.lookaround.data
|
||||
|
||||
data class LookAroundData(var data: ByteArray?, var bitmapWidth: Int, var bitmapHeight: Int, var targetX: Int = 0, var targetY: Int = 0, var targetWidth: Int = 0, var targetHeight: Int = 0) {
|
||||
|
||||
override fun toString(): String {
|
||||
return "LookAroundData(data=${data?.size}, bitmapWidth=$bitmapWidth, bitmapHeight=$bitmapHeight, targetX=$targetX, targetY=$targetY, targetWidth=$targetWidth, targetHeight=$targetHeight)"
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
fun LookAroundData.isValid(): Boolean {
|
||||
return this.data != null && this.bitmapWidth > 0 && this.bitmapHeight > 0 && targetX > 0 && targetY > 0 && targetWidth > 0 && targetHeight > 0
|
||||
}
|
||||
@@ -20,6 +20,7 @@ import com.zhjt.mogo.adas.data.sweeper.task.SweeperTask.StartTaskResp
|
||||
import com.zhjt.mogo.adas.data.sweeper.task.SweeperTaskSuspendResume.SuspendResumeTaskReq
|
||||
import com.zhjt.mogo.adas.data.sweeper.task.confirm.SweeperTaskConfirm.TaskConfirmResp
|
||||
import com.zhjt.mogo.adas.data.sweeper.task.stop.SweeperTaskStop.StopTaskResp
|
||||
import com.zhjt.mogo.adas.data.AdasConstants
|
||||
import com.zhjt.service.chain.ChainLog
|
||||
import com.zhjt.service.chain.TracingConstants
|
||||
import com.zhjt.service_biz.BizConfig
|
||||
@@ -273,7 +274,7 @@ object CallerAutoPilotControlManager {
|
||||
|
||||
/**
|
||||
* 获取全部参数
|
||||
* 结果回调{@link OnAdasListener#onGetParamResp(MessagePad.Header, MessagePad.SetParamReq)}
|
||||
* 结果回调{@link OnAdasListener#onGetParamResp(MessagePad.Header, MessagePad.SetParamReq, AdasParam)}
|
||||
*
|
||||
* @return boolean
|
||||
*/
|
||||
@@ -283,12 +284,12 @@ object CallerAutoPilotControlManager {
|
||||
|
||||
/**
|
||||
* 参数获取请求
|
||||
* 结果回调{@link OnAdasListener#onGetParamResp(MessagePad.Header, MessagePad.SetParamReq)}
|
||||
* 结果回调{@link OnAdasListener#onGetParamResp(MessagePad.Header, MessagePad.SetParamReq, AdasParam)}
|
||||
*
|
||||
* @param paramType 参数类型{@link com.zhidao.support.adas.high.common.Constants.PARAM_TYPE}
|
||||
* @param paramType 参数类型:libraries/mogo-adas-data/src/main/proto/personal/adas_constants.proto
|
||||
* @return boolean
|
||||
*/
|
||||
fun sendGetParamReq(paramType: Int): Boolean? {
|
||||
fun sendGetParamReq(paramType: AdasConstants.MapSystemParamType): Boolean? {
|
||||
return providerApi?.sendGetParamReq(paramType)
|
||||
}
|
||||
/**
|
||||
|
||||
@@ -0,0 +1,17 @@
|
||||
package com.mogo.eagle.core.function.call.autopilot
|
||||
|
||||
import com.mogo.eagle.core.function.api.autopilot.*
|
||||
import com.mogo.eagle.core.function.call.base.*
|
||||
import com.zhjt.mogo.adas.data.bean.*
|
||||
import mogo.telematics.pad.*
|
||||
|
||||
object CallerAutopilotGetParamResponseDispatcher: CallerBase<IMoGoGetParamResponseListener>() {
|
||||
|
||||
|
||||
fun dispatchResponse(header: MessagePad.Header, getParamResp: MessagePad.SetParamReq, adasParam: AdasParam) {
|
||||
M_LISTENERS.forEach {
|
||||
val listener = it.value
|
||||
listener.onGetParamResp(header, getParamResp, adasParam)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -17,6 +17,7 @@ import com.mogo.eagle.core.function.api.devatools.apm.*
|
||||
import com.mogo.eagle.core.function.api.devatools.download.*
|
||||
import com.mogo.eagle.core.function.api.upgrade.*
|
||||
import com.mogo.eagle.core.function.api.devatools.strict.*
|
||||
import com.mogo.eagle.core.function.api.lookaround.*
|
||||
import com.mogo.eagle.core.function.call.base.CallerBase
|
||||
import com.mogo.eagle.core.utilcode.mogo.AppIdentityModeUtils
|
||||
|
||||
@@ -255,4 +256,6 @@ object CallerDevaToolsManager {
|
||||
fun upgradeProvider(): IMoGoUpgradeProvider? = devaToolsProviderApi?.upgradeProvider()
|
||||
|
||||
fun strict(): IStrictModeProvider? = devaToolsProviderApi?.strict()
|
||||
|
||||
fun lookAroundProvider(): IMoGoLookAroundProvider? = devaToolsProviderApi?.lookAroundDataProvider()
|
||||
}
|
||||
@@ -198,4 +198,25 @@ object CallerHmiManager {
|
||||
fun updateStatusBarDownloadView(insert: Boolean, tag: String, progress: Int) {
|
||||
hmiProviderApi?.updateStatusBarDownloadView(insert, tag, progress)
|
||||
}
|
||||
|
||||
/**
|
||||
* 展示M1车型的360环视控件
|
||||
*/
|
||||
fun showM1360LookAround() {
|
||||
hmiProviderApi?.show360LookAround()
|
||||
}
|
||||
|
||||
/**
|
||||
* 隐藏M1车型的360环视控件
|
||||
*/
|
||||
fun hidM1360LookAround() {
|
||||
hmiProviderApi?.hide360LookAround()
|
||||
}
|
||||
|
||||
/**
|
||||
* 返回M1车型的360环视弹窗是否正在展示
|
||||
*/
|
||||
fun isM1360LookAroundShowing(): Boolean {
|
||||
return hmiProviderApi?.is360LookAroundShowing() ?: false
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,307 @@
|
||||
package com.mogo.eagle.core.utilcode.floating
|
||||
|
||||
import android.annotation.*
|
||||
import android.app.Activity
|
||||
import android.graphics.Rect
|
||||
import android.graphics.drawable.ColorDrawable
|
||||
import android.util.Log
|
||||
import android.view.Gravity
|
||||
import android.view.LayoutInflater
|
||||
import android.view.MotionEvent
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import android.view.WindowManager
|
||||
import android.widget.PopupWindow
|
||||
import androidx.annotation.LayoutRes
|
||||
import androidx.core.view.doOnAttach
|
||||
import com.mogo.eagle.core.utilcode.kotlin.lifeCycleScope
|
||||
import com.mogo.eagle.core.utilcode.util.*
|
||||
import java.util.concurrent.atomic.AtomicBoolean
|
||||
|
||||
class MoGoPopWindow private constructor(builder: Builder){
|
||||
|
||||
|
||||
private val content: View = builder.content ?: throw AssertionError("要填充的View不能为空")
|
||||
|
||||
private val pop: PopupWindow by lazy { PopupWindow(builder.width, builder.height) }
|
||||
|
||||
private val offsetX: Int = builder.offsetX
|
||||
|
||||
private var offsetY: Int = builder.offsetY
|
||||
|
||||
private var gravityInActivity: Int = builder.gravityInActivity
|
||||
|
||||
private val activity: Activity = builder.attachToActivity ?: throw AssertionError("要依附Activity实例不能为空")
|
||||
|
||||
private val isDraggable: Boolean = builder.isDraggable
|
||||
|
||||
private val isDismissOnTouchOutside: Boolean = builder.isDismissOnTouchOutside
|
||||
|
||||
private val isPendingShow by lazy { AtomicBoolean(false) }
|
||||
|
||||
private val onDismissed: (() -> Unit)? = builder.onDismissed
|
||||
|
||||
private val onShowed: (() -> Unit)? = builder.onShowed
|
||||
|
||||
private val onTouchInterceptorInDrag: ((child: View, event: MotionEvent) -> Boolean)? = builder.onTouchInterceptorInDrag
|
||||
|
||||
private val onViewAttachedToWindow: ((content: View) -> Unit)? = builder.onViewAttachedToWindow
|
||||
|
||||
@SuppressLint("ClickableViewAccessibility") fun show() {
|
||||
if (isPendingShow.get() || pop.isShowing) {
|
||||
return
|
||||
}
|
||||
isPendingShow.set(true)
|
||||
activity.lifeCycleScope.launchWhenResumed {
|
||||
val parent = activity.findViewById<View>(android.R.id.content) ?: throw AssertionError("附着的Activity上的ID为[android.R.id.content]的控件不存在.")
|
||||
pop.contentView = content
|
||||
pop.isAttachedInDecor = true
|
||||
pop.setBackgroundDrawable(ColorDrawable())
|
||||
content.doOnAttach {
|
||||
onViewAttachedToWindow?.invoke(content)
|
||||
onShowed?.invoke()
|
||||
}
|
||||
pop.setOnDismissListener {
|
||||
onDismissed?.invoke()
|
||||
}
|
||||
pop.isTouchable = true
|
||||
if (isDismissOnTouchOutside) {
|
||||
pop.isFocusable = true
|
||||
pop.isOutsideTouchable = true
|
||||
} else {
|
||||
pop.isFocusable= false
|
||||
pop.isOutsideTouchable = false
|
||||
}
|
||||
if (isDraggable) {
|
||||
val outer = Rect()
|
||||
var oldRawX = 0f
|
||||
var oldRawY = 0f
|
||||
var isDownConsumed = false
|
||||
pop.setTouchInterceptor { _, event ->
|
||||
if (event == null) {
|
||||
return@setTouchInterceptor false
|
||||
}
|
||||
val rawX = event.rawX
|
||||
val rawY = event.rawY
|
||||
if (event.actionMasked == MotionEvent.ACTION_DOWN) {
|
||||
val child = findChildInContent(content.parent as? ViewGroup, event.x, event.y) ?: content
|
||||
Log.d(TAG, "child -> : ${child.javaClass.simpleName}")
|
||||
if (onTouchInterceptorInDrag?.invoke(child, event) == true) {
|
||||
isDownConsumed = true
|
||||
return@setTouchInterceptor false
|
||||
}
|
||||
if (outer.isEmpty) {
|
||||
val location = IntArray(2)
|
||||
parent.getLocationOnScreen(location)
|
||||
val left = location[0]
|
||||
val top = location[1]
|
||||
val right = left + parent.width
|
||||
val bottom = top + parent.height
|
||||
outer.set(left,top, right, bottom)
|
||||
}
|
||||
oldRawX = rawX
|
||||
oldRawY = rawY
|
||||
}
|
||||
if (event.actionMasked == MotionEvent.ACTION_MOVE) {
|
||||
if (!isDownConsumed) {
|
||||
val dx = (rawX - oldRawX).toInt()
|
||||
val dy = (rawY - oldRawY).toInt()
|
||||
val params = content.rootView.layoutParams as WindowManager.LayoutParams
|
||||
val oldX = params.x
|
||||
val oldY = params.y
|
||||
val newX = oldX + dx
|
||||
val newY = oldY + dy
|
||||
if (outer.contains(rawX.toInt(), rawY.toInt())) {
|
||||
pop.update(newX, newY, content.width, content.height)
|
||||
}
|
||||
oldRawX = rawX
|
||||
oldRawY = rawY
|
||||
}
|
||||
}
|
||||
|
||||
if (event.actionMasked == MotionEvent.ACTION_UP || event.actionMasked == MotionEvent.ACTION_CANCEL) {
|
||||
if (isDownConsumed) {
|
||||
isDownConsumed = false
|
||||
}
|
||||
}
|
||||
false
|
||||
}
|
||||
}
|
||||
pop.showAtLocation(parent, gravityInActivity, offsetX, offsetY)
|
||||
}
|
||||
}
|
||||
|
||||
private tailrec fun findChildInContent(group: ViewGroup?, x: Float, y: Float): View? {
|
||||
if (group == null) {
|
||||
return null
|
||||
}
|
||||
val count = group.childCount
|
||||
if (count == 0) {
|
||||
return null
|
||||
}
|
||||
for (i in (count - 1) downTo 0) {
|
||||
val child = group.getChildAt(i)
|
||||
val location = IntArray(2)
|
||||
child.getLocationInWindow(location)
|
||||
val rect = Rect(location[0], location[1], location[0] + child.width, location[1] + child.height)
|
||||
val intX = x.toInt()
|
||||
val intY = y.toInt()
|
||||
if (child is ViewGroup) {
|
||||
if (rect.contains(intX, intY)) {
|
||||
return findChildInContent(child, x, y)
|
||||
}
|
||||
continue
|
||||
}
|
||||
if (rect.contains(intX, intY)) {
|
||||
return child
|
||||
}
|
||||
}
|
||||
return null
|
||||
}
|
||||
|
||||
fun hide() {
|
||||
if (!pop.isShowing) {
|
||||
return
|
||||
}
|
||||
activity.lifeCycleScope.launchWhenResumed {
|
||||
pop.dismiss()
|
||||
}
|
||||
}
|
||||
|
||||
fun isShowing(): Boolean = isPendingShow.get() || pop.isShowing
|
||||
|
||||
class Builder {
|
||||
|
||||
/**
|
||||
* 内容控件实例,设置了此字段,不能再设置[layoutId]
|
||||
*/
|
||||
internal var content: View? = null
|
||||
|
||||
/**
|
||||
* 内容控件的布局ID,设置了此字段,不能再设置[content]
|
||||
*/
|
||||
internal var layoutId: Int? = null
|
||||
|
||||
/**
|
||||
* 当前窗口是否可拖拽
|
||||
*/
|
||||
internal var isDraggable: Boolean = false
|
||||
|
||||
/**
|
||||
* 点击弹窗外部区域,是否消失
|
||||
*/
|
||||
internal var isDismissOnTouchOutside: Boolean = false
|
||||
|
||||
/**
|
||||
* 依附的Activity实例
|
||||
*/
|
||||
internal var attachToActivity: Activity? = null
|
||||
|
||||
/**
|
||||
* 相对于父控件X方向上的偏移量
|
||||
*/
|
||||
internal var offsetX: Int = 0
|
||||
|
||||
/**
|
||||
* 相对于父控件Y方向上的偏移量
|
||||
*/
|
||||
internal var offsetY: Int = 0
|
||||
|
||||
/**
|
||||
* 相对于父控件的布局位置
|
||||
*/
|
||||
internal var gravityInActivity: Int = Gravity.NO_GRAVITY
|
||||
|
||||
internal var width: Int = WindowManager.LayoutParams.WRAP_CONTENT
|
||||
|
||||
internal var height: Int = WindowManager.LayoutParams.WRAP_CONTENT
|
||||
|
||||
internal var onShowed:(()-> Unit)? = null
|
||||
|
||||
internal var onDismissed: (()-> Unit)? = null
|
||||
|
||||
/**
|
||||
* 当处于拖拽状态时,是响应拖拽还是当前窗口自己的事件
|
||||
*/
|
||||
internal var onTouchInterceptorInDrag: ((childInContent: View, event: MotionEvent) -> Boolean)? = null
|
||||
|
||||
|
||||
/**
|
||||
* 当控件被attach到窗口的时候,回调
|
||||
*/
|
||||
internal var onViewAttachedToWindow: ((content: View) -> Unit)? = null
|
||||
|
||||
fun contentView(content: View) = apply {
|
||||
this.content = content
|
||||
}
|
||||
|
||||
fun layoutId(@LayoutRes id: Int) = apply {
|
||||
this.layoutId = id
|
||||
}
|
||||
|
||||
fun draggable(draggable: Boolean) = apply {
|
||||
this.isDraggable = draggable
|
||||
}
|
||||
|
||||
fun isDismissOnTouchOutside(flag: Boolean) = apply {
|
||||
this.isDismissOnTouchOutside = flag
|
||||
}
|
||||
|
||||
fun attachToActivity(activity: Activity) = apply {
|
||||
this.attachToActivity = activity
|
||||
}
|
||||
|
||||
fun offsetX(x: Int) = apply {
|
||||
this.offsetY = x
|
||||
}
|
||||
|
||||
fun offsetY(y: Int) = apply {
|
||||
this.offsetY = y
|
||||
}
|
||||
|
||||
fun width(w: Int) = apply {
|
||||
this.width = w
|
||||
}
|
||||
|
||||
fun height(h: Int) = apply {
|
||||
this.height = h
|
||||
}
|
||||
|
||||
fun gravityInActivity(gravity: Int) = apply {
|
||||
this.gravityInActivity = gravity
|
||||
}
|
||||
|
||||
fun onTouchInterceptorInDrag(block: (childInContent: View, event: MotionEvent) -> Boolean) = apply {
|
||||
this.onTouchInterceptorInDrag = block
|
||||
}
|
||||
|
||||
fun onShowed(block: () -> Unit) = apply {
|
||||
this.onShowed = block
|
||||
}
|
||||
|
||||
fun onDismissed(block: () -> Unit) = apply {
|
||||
this.onDismissed = block
|
||||
}
|
||||
|
||||
fun onViewAttachedToWindow(block: (content: View) -> Unit) = apply {
|
||||
this.onViewAttachedToWindow = block
|
||||
}
|
||||
|
||||
fun build() : MoGoPopWindow {
|
||||
val activity = attachToActivity ?: throw AssertionError("依附的activity不能为空")
|
||||
if (content != null && layoutId != null) {
|
||||
throw AssertionError("两者不能同时设置")
|
||||
}
|
||||
if (content == null && layoutId == null) {
|
||||
throw AssertionError("两者不能都不设置,至少设置一个")
|
||||
}
|
||||
if (content == null) {
|
||||
content = LayoutInflater.from(activity).inflate(layoutId!!, null)
|
||||
}
|
||||
if (content != null && content?.parent != null) {
|
||||
throw AssertionError("内容控件不允许包含父控件.")
|
||||
}
|
||||
return MoGoPopWindow(this)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,223 @@
|
||||
package com.mogo.eagle.core.utilcode.mogo.floating
|
||||
|
||||
import android.annotation.*
|
||||
import android.content.*
|
||||
import android.content.res.*
|
||||
import android.os.*
|
||||
import android.util.*
|
||||
import android.view.*
|
||||
import android.widget.*
|
||||
import androidx.annotation.*
|
||||
|
||||
abstract class AbsFloatingView: FrameLayout {
|
||||
|
||||
private var mPortraitY = 0f
|
||||
|
||||
private var mWindowWidth: Int = 0
|
||||
|
||||
private var mWindowHeight: Int = 0
|
||||
|
||||
private var mAnimator: AutoMoveEdgeAnimator? = null
|
||||
|
||||
/**
|
||||
* 系统状态栏的高度
|
||||
*/
|
||||
private var mStatusBarHeight: Int = 0
|
||||
|
||||
private var mOldX: Float = 0f
|
||||
|
||||
private var mOldY: Float = 0f
|
||||
|
||||
private var mOldRawX: Float = 0f
|
||||
|
||||
private var mOldRawY: Float = 0f
|
||||
|
||||
companion object {
|
||||
private const val MARGIN_EDGE = 13
|
||||
}
|
||||
|
||||
|
||||
constructor(context: Context) : this(context, null)
|
||||
constructor(context: Context, attrs: AttributeSet?) : this(context, attrs, 0)
|
||||
constructor(context: Context, attrs: AttributeSet?, defStyleAttr: Int) : this(context, attrs, defStyleAttr, 0)
|
||||
constructor(context: Context, attrs: AttributeSet?, defStyleAttr: Int, defStyleRes: Int) : super(context, attrs, defStyleAttr, defStyleRes) {
|
||||
isClickable = true
|
||||
isFocusable = true
|
||||
mStatusBarHeight = getStatusBarHeight()
|
||||
}
|
||||
|
||||
@SuppressLint("InternalInsetResource")
|
||||
private fun getStatusBarHeight(): Int {
|
||||
val resourceId = context.resources.getIdentifier("status_bar_height", "dimen", "android")
|
||||
if (resourceId > 0) {
|
||||
return context.resources.getDimensionPixelSize(resourceId)
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
|
||||
@CallSuper
|
||||
override fun onAttachedToWindow() {
|
||||
super.onAttachedToWindow()
|
||||
val layoutId = getLayoutId()
|
||||
if (layoutId == 0) {
|
||||
throw AssertionError("view: ${this::class.java.simpleName}'s getLayoutId() return a invalid resID: 0")
|
||||
}
|
||||
val child = LayoutInflater.from(context).inflate(layoutId, this, true)
|
||||
onChildInflated(child)
|
||||
if (autoMoveToEdge()) {
|
||||
mAnimator = AutoMoveEdgeAnimator()
|
||||
}
|
||||
}
|
||||
|
||||
@CallSuper
|
||||
override fun onDetachedFromWindow() {
|
||||
if (autoMoveToEdge()) {
|
||||
mAnimator?.stop()
|
||||
}
|
||||
super.onDetachedFromWindow()
|
||||
}
|
||||
|
||||
@SuppressLint("ClickableViewAccessibility")
|
||||
final override fun onTouchEvent(event: MotionEvent?): Boolean {
|
||||
if (!isDragEnabled()) {
|
||||
return super.onTouchEvent(event)
|
||||
}
|
||||
if (event == null) {
|
||||
return false
|
||||
}
|
||||
when(event.actionMasked) {
|
||||
MotionEvent.ACTION_DOWN -> {
|
||||
mOldX = x
|
||||
mOldY = y
|
||||
mOldRawX = event.rawX
|
||||
mOldRawY = event.rawY
|
||||
updateSize()
|
||||
if (autoMoveToEdge()) {
|
||||
mAnimator?.stop()
|
||||
}
|
||||
}
|
||||
MotionEvent.ACTION_MOVE -> {
|
||||
updateViewPosition(event)
|
||||
}
|
||||
MotionEvent.ACTION_UP -> {
|
||||
mPortraitY = 0f
|
||||
if (autoMoveToEdge()) {
|
||||
moveToEdge()
|
||||
}
|
||||
}
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
private fun updateViewPosition(event: MotionEvent) {
|
||||
var destX = mOldX + event.rawX - mOldRawX
|
||||
if (!autoMoveToEdge()) {
|
||||
if (destX < 0f) {
|
||||
destX = 0f
|
||||
} else {
|
||||
val widthLeft = mWindowWidth - width
|
||||
if (destX > widthLeft) {
|
||||
destX = widthLeft.toFloat()
|
||||
}
|
||||
}
|
||||
}
|
||||
x = destX
|
||||
var destY = mOldY + event.rawY - mOldRawY
|
||||
if (destY < mStatusBarHeight) {
|
||||
destY = mStatusBarHeight.toFloat()
|
||||
}
|
||||
val heightLeft = mWindowHeight - height
|
||||
if (destY > heightLeft) {
|
||||
destY = heightLeft.toFloat()
|
||||
}
|
||||
y = destY
|
||||
}
|
||||
|
||||
private fun moveToEdge() {
|
||||
moveToEdge(isNearestLeft(), context.resources.configuration.orientation == Configuration.ORIENTATION_LANDSCAPE)
|
||||
}
|
||||
|
||||
private fun moveToEdge(isLeft: Boolean, isLandscape: Boolean) {
|
||||
val moveDistance = if (isLeft) MARGIN_EDGE else mWindowWidth - MARGIN_EDGE
|
||||
if (!isLandscape && mPortraitY != 0f) {
|
||||
y = mPortraitY
|
||||
mPortraitY = 0f
|
||||
}
|
||||
mAnimator?.start(moveDistance.toFloat(), 0f.coerceAtLeast(y).coerceAtMost((mWindowHeight - height).toFloat()))
|
||||
}
|
||||
|
||||
private fun isNearestLeft(): Boolean {
|
||||
val middle = mWindowWidth / 2
|
||||
return x < middle
|
||||
}
|
||||
|
||||
private fun updateSize() {
|
||||
val group = parent as? ViewGroup ?: return
|
||||
mWindowWidth = group.width
|
||||
mWindowHeight = group.height
|
||||
}
|
||||
|
||||
override fun onConfigurationChanged(newConfig: Configuration?) {
|
||||
super.onConfigurationChanged(newConfig)
|
||||
if (parent != null) {
|
||||
val isLandscape = newConfig?.orientation == Configuration.ORIENTATION_LANDSCAPE
|
||||
if (isLandscape) {
|
||||
mPortraitY = y
|
||||
}
|
||||
post {
|
||||
updateSize()
|
||||
moveToEdge(isNearestLeft(), isLandscape)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@LayoutRes
|
||||
abstract fun getLayoutId(): Int
|
||||
|
||||
protected open fun isDragEnabled(): Boolean = true
|
||||
|
||||
protected open fun autoMoveToEdge(): Boolean = false
|
||||
|
||||
protected open fun onChildInflated(child: View) { }
|
||||
|
||||
private fun move(deltaX: Float, deltaY: Float) {
|
||||
x += deltaX
|
||||
y += deltaY
|
||||
}
|
||||
|
||||
private inner class AutoMoveEdgeAnimator: Runnable {
|
||||
|
||||
private val handler by lazy { Handler(Looper.getMainLooper()) }
|
||||
|
||||
private var destX: Float = 0f
|
||||
|
||||
private var destY: Float = 0f
|
||||
|
||||
private var startTime: Long = 0L
|
||||
|
||||
override fun run() {
|
||||
if (rootView == null || rootView.parent == null) {
|
||||
return
|
||||
}
|
||||
val progress = 1f.coerceAtMost((SystemClock.elapsedRealtime() - startTime) / 400f)
|
||||
val deltaX = (destX - x) * progress
|
||||
val deltaY = (destY - y) * progress
|
||||
move(deltaX, deltaY)
|
||||
if (progress < 1) {
|
||||
handler.post(this)
|
||||
}
|
||||
}
|
||||
|
||||
fun start(x: Float, y: Float) {
|
||||
this.destX = x
|
||||
this.destY = y
|
||||
startTime = SystemClock.elapsedRealtime()
|
||||
handler.post(this)
|
||||
}
|
||||
|
||||
fun stop() {
|
||||
handler.removeCallbacks(this)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -2,4 +2,5 @@
|
||||
<resources>
|
||||
<item name="tag_click_time" type="id" />
|
||||
<item name="view_lifecycle_owner" type="id" />
|
||||
<item name="mogo_pop_window" type="id" />
|
||||
</resources>
|
||||
@@ -1,8 +1,9 @@
|
||||
package com.zhidao.support.adas.high.bean;
|
||||
package com.zhjt.mogo.adas.data.bean;
|
||||
|
||||
import android.text.TextUtils;
|
||||
import android.util.Log;
|
||||
|
||||
import com.zhidao.support.adas.high.common.Constants;
|
||||
import com.zhjt.mogo.adas.data.AdasConstants;
|
||||
|
||||
import mogo.telematics.pad.MessagePad;
|
||||
|
||||
@@ -52,6 +53,19 @@ public class AdasParam {
|
||||
*/
|
||||
public final int weakNetSlowDown;
|
||||
|
||||
/**
|
||||
* m1拼接视频自车位置参数(string),格式:x,y,width,height
|
||||
* MAP发出的原始数据
|
||||
*/
|
||||
public final String m1StitchedVideoSelfVehicleParam;
|
||||
|
||||
/**
|
||||
* m1拼接视频自车位置参数
|
||||
* 解析后的数据
|
||||
* 为空的原因:未查询此数据、工控机不存在此数据、解析失败
|
||||
*/
|
||||
public final M1StitchedVideoSelfVehicleParam m1StitchedVideoSelfVehicleParamParse;
|
||||
|
||||
public AdasParam(MessagePad.SetParamReq param) {
|
||||
int detouringCmd = -1;
|
||||
double detouringSpeed = -1.0;
|
||||
@@ -61,6 +75,8 @@ public class AdasParam {
|
||||
int hadmapSpeedLimitValid = -1;
|
||||
int rampThetaValid = -1;
|
||||
int weakNetSlowDown = -1;
|
||||
String m1StitchedVideoSelfVehicleParam = null;
|
||||
M1StitchedVideoSelfVehicleParam m1StitchedVideoSelfVehicleParamParse = null;
|
||||
if (param != null) {
|
||||
int size = param.getReqsCount();
|
||||
if (size > 0) {
|
||||
@@ -68,38 +84,49 @@ public class AdasParam {
|
||||
MessagePad.SetOneParam oneParam = param.getReqs(i);
|
||||
int type = oneParam.getType();
|
||||
String value = oneParam.getValue();
|
||||
if (type == Constants.PARAM_TYPE.DETOURING) {
|
||||
if (type == AdasConstants.MapSystemParamType.DETOURING_VALUE) {
|
||||
if (!TextUtils.isEmpty(value)) {
|
||||
detouringCmd = Integer.parseInt(value);
|
||||
}
|
||||
} else if (type == Constants.PARAM_TYPE.DETOURING_SPEED) {
|
||||
} else if (type == AdasConstants.MapSystemParamType.DETOURING_SPEED_VALUE) {
|
||||
if (!TextUtils.isEmpty(value)) {
|
||||
detouringSpeed = Double.parseDouble(value);
|
||||
}
|
||||
} else if (type == Constants.PARAM_TYPE.AEB) {
|
||||
} else if (type == AdasConstants.MapSystemParamType.AEB_VALUE) {
|
||||
if (!TextUtils.isEmpty(value)) {
|
||||
aebCmd = Integer.parseInt(value);
|
||||
}
|
||||
} else if (type == Constants.PARAM_TYPE.LANE_CHANGE_RESTRAIN_VALID) {
|
||||
} else if (type == AdasConstants.MapSystemParamType.LANE_CHANGE_RESTRAIN_VALID_VALUE) {
|
||||
if (!TextUtils.isEmpty(value)) {
|
||||
laneChangeRestrainValid = Integer.parseInt(value);
|
||||
}
|
||||
} else if (type == Constants.PARAM_TYPE.STOP_YIELD_VALID) {
|
||||
} else if (type == AdasConstants.MapSystemParamType.STOP_YIELD_VALID_VALUE) {
|
||||
if (!TextUtils.isEmpty(value)) {
|
||||
stopYieldValid = Integer.parseInt(value);
|
||||
}
|
||||
} else if (type == Constants.PARAM_TYPE.HADMAP_SPEED_LIMIT_VALID) {
|
||||
} else if (type == AdasConstants.MapSystemParamType.HADMAP_SPEED_LIMIT_VALID_VALUE) {
|
||||
if (!TextUtils.isEmpty(value)) {
|
||||
hadmapSpeedLimitValid = Integer.parseInt(value);
|
||||
}
|
||||
} else if (type == Constants.PARAM_TYPE.RAMP_THETA_VALID) {
|
||||
} else if (type == AdasConstants.MapSystemParamType.RAMP_THETA_VALID_VALUE) {
|
||||
if (!TextUtils.isEmpty(value)) {
|
||||
rampThetaValid = Integer.parseInt(value);
|
||||
}
|
||||
} else if (type == Constants.PARAM_TYPE.WEAK_NET_SLOW_DOWN) {
|
||||
} else if (type == AdasConstants.MapSystemParamType.WEAK_NET_SLOW_DOWN_VALUE) {
|
||||
if (!TextUtils.isEmpty(value)) {
|
||||
weakNetSlowDown = Integer.parseInt(value);
|
||||
}
|
||||
} else if (type == AdasConstants.MapSystemParamType.M1_STITCHED_VIDEO_SELF_VEHICLE_PARAM_VALUE) {
|
||||
if (!TextUtils.isEmpty(value)) {
|
||||
m1StitchedVideoSelfVehicleParam = value;
|
||||
try {
|
||||
String[] s = value.split(",");
|
||||
m1StitchedVideoSelfVehicleParamParse = new M1StitchedVideoSelfVehicleParam(Integer.parseInt(s[0]), Integer.parseInt(s[1]), Integer.parseInt(s[2]), Integer.parseInt(s[3]));
|
||||
} catch (Exception e) {
|
||||
Log.e("AdasParam", "M1拼接视频自车位置参数解析失败", e);
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -112,6 +139,8 @@ public class AdasParam {
|
||||
this.hadmapSpeedLimitValid = hadmapSpeedLimitValid;
|
||||
this.rampThetaValid = rampThetaValid;
|
||||
this.weakNetSlowDown = weakNetSlowDown;
|
||||
this.m1StitchedVideoSelfVehicleParam = m1StitchedVideoSelfVehicleParam;
|
||||
this.m1StitchedVideoSelfVehicleParamParse = m1StitchedVideoSelfVehicleParamParse;
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -123,6 +152,21 @@ public class AdasParam {
|
||||
"\n停车让行线前避让等待开关=" + (stopYieldValid == -1 ? "未知" : stopYieldValid == 0 ? "无需等待" : "等待") +
|
||||
"\n地图限速功能开关=" + (hadmapSpeedLimitValid == -1 ? "未知" : hadmapSpeedLimitValid == 0 ? "不使用" : "使用") +
|
||||
"\n环岛模式开关=" + (rampThetaValid == -1 ? "未知" : rampThetaValid == 0 ? "普通模式" : "环岛模式") +
|
||||
"\n弱网减速停车策略开关=" + (weakNetSlowDown == -1 ? "未知" : weakNetSlowDown == 0 ? "关闭" : "使用");
|
||||
"\n弱网减速停车策略开关=" + (weakNetSlowDown == -1 ? "未知" : weakNetSlowDown == 0 ? "关闭" : "使用") +
|
||||
"\nm1拼接视频自车位置参数=" + (m1StitchedVideoSelfVehicleParam == null ? "未知" : m1StitchedVideoSelfVehicleParam);
|
||||
}
|
||||
|
||||
public static class M1StitchedVideoSelfVehicleParam {
|
||||
public final int x;
|
||||
public final int y;
|
||||
public final int width;
|
||||
public final int height;
|
||||
|
||||
public M1StitchedVideoSelfVehicleParam(int x, int y, int width, int height) {
|
||||
this.x = x;
|
||||
this.y = y;
|
||||
this.width = width;
|
||||
this.height = height;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -6,7 +6,7 @@ import "geometry.proto";
|
||||
enum ProtocolVersion
|
||||
{
|
||||
Defaultver = 0;
|
||||
CurrentVersion = 12; //每次修改proto文件增加1
|
||||
CurrentVersion = 10; //每次修改proto文件增加1
|
||||
}
|
||||
|
||||
enum MessageType
|
||||
|
||||
@@ -0,0 +1,18 @@
|
||||
syntax = "proto3";
|
||||
package com.zhjt.mogo.adas.data;
|
||||
|
||||
|
||||
//MAP系统参数类型
|
||||
enum MapSystemParamType{
|
||||
DEFAULT_TYPE = 0;
|
||||
DETOURING = 1;//绕障类功能开关
|
||||
DETOURING_SPEED = 2;//变道绕障的目标障碍物速度阈值
|
||||
AEB = 3;//AEB开关
|
||||
LANE_CHANGE_RESTRAIN_VALID = 4;//限制绕障开关
|
||||
STOP_YIELD_VALID = 5;//停车让行线前避让等待开关
|
||||
HADMAP_SPEED_LIMIT_VALID = 6;//地图限速功能开关
|
||||
RAMP_THETA_VALID = 7;//环岛模式开关
|
||||
WEAK_NET_SLOW_DOWN = 8;//弱网减速停车策略开关
|
||||
M1_STITCHED_VIDEO_SELF_VEHICLE_PARAM = 9;//m1拼接视频自车位置参数(string), 格式:x,y,width,height
|
||||
}
|
||||
|
||||
@@ -21,6 +21,7 @@ import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
|
||||
import com.google.protobuf.InvalidProtocolBufferException;
|
||||
import com.zhjt.mogo.adas.data.bean.AdasParam;
|
||||
import com.zhidao.support.adas.high.bean.VersionCompatibility;
|
||||
import com.zhidao.support.adas.high.common.AutopilotReview;
|
||||
import com.zhidao.support.adas.high.common.ByteUtil;
|
||||
@@ -44,6 +45,7 @@ import com.zhidao.support.adas.high.socket.FpgaSocket;
|
||||
import com.zhidao.support.adas.high.subscribe.SubscribeInterface;
|
||||
import com.zhidao.support.adas.high.subscribe.SubscribeInterfaceOptions;
|
||||
import com.zhidao.support.adas.high.thread.DispatchHandler;
|
||||
import com.zhjt.mogo.adas.data.AdasConstants;
|
||||
import com.zhjt.mogo.adas.data.bean.AutopilotStatistics;
|
||||
import com.zhjt.mogo.adas.data.sweeper.SweeperCloudTask;
|
||||
import com.zhjt.mogo.adas.data.sweeper.bootable.SweeperBootable;
|
||||
@@ -1552,7 +1554,7 @@ public class AdasChannel implements IAdasNetCommApi, FpgaSocket.IWebSocketConnec
|
||||
*/
|
||||
@Override
|
||||
public boolean sendDetouring(int enable) {
|
||||
return sendSetParamReq(Constants.PARAM_TYPE.DETOURING, String.valueOf(enable));
|
||||
return sendSetParamReq(AdasConstants.MapSystemParamType.DETOURING_VALUE, String.valueOf(enable));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1563,7 +1565,7 @@ public class AdasChannel implements IAdasNetCommApi, FpgaSocket.IWebSocketConnec
|
||||
*/
|
||||
@Override
|
||||
public boolean sendDetouringSpeed(double speed) {
|
||||
return sendSetParamReq(Constants.PARAM_TYPE.DETOURING_SPEED, String.valueOf(speed));
|
||||
return sendSetParamReq(AdasConstants.MapSystemParamType.DETOURING_SPEED_VALUE, String.valueOf(speed));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1575,7 +1577,7 @@ public class AdasChannel implements IAdasNetCommApi, FpgaSocket.IWebSocketConnec
|
||||
*/
|
||||
@Override
|
||||
public boolean sendAebCmd(int enable) {
|
||||
return sendSetParamReq(Constants.PARAM_TYPE.AEB, String.valueOf(enable));
|
||||
return sendSetParamReq(AdasConstants.MapSystemParamType.AEB_VALUE, String.valueOf(enable));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1587,7 +1589,7 @@ public class AdasChannel implements IAdasNetCommApi, FpgaSocket.IWebSocketConnec
|
||||
*/
|
||||
@Override
|
||||
public boolean sendLaneChangeRestrainValid(int enable) {
|
||||
return sendSetParamReq(Constants.PARAM_TYPE.LANE_CHANGE_RESTRAIN_VALID, String.valueOf(enable));
|
||||
return sendSetParamReq(AdasConstants.MapSystemParamType.LANE_CHANGE_RESTRAIN_VALID_VALUE, String.valueOf(enable));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1599,7 +1601,7 @@ public class AdasChannel implements IAdasNetCommApi, FpgaSocket.IWebSocketConnec
|
||||
*/
|
||||
@Override
|
||||
public boolean sendStopYieldValid(int enable) {
|
||||
return sendSetParamReq(Constants.PARAM_TYPE.STOP_YIELD_VALID, String.valueOf(enable));
|
||||
return sendSetParamReq(AdasConstants.MapSystemParamType.STOP_YIELD_VALID_VALUE, String.valueOf(enable));
|
||||
}
|
||||
|
||||
|
||||
@@ -1612,7 +1614,7 @@ public class AdasChannel implements IAdasNetCommApi, FpgaSocket.IWebSocketConnec
|
||||
*/
|
||||
@Override
|
||||
public boolean sendHadmapSpeedLimitValid(int enable) {
|
||||
return sendSetParamReq(Constants.PARAM_TYPE.HADMAP_SPEED_LIMIT_VALID, String.valueOf(enable));
|
||||
return sendSetParamReq(AdasConstants.MapSystemParamType.HADMAP_SPEED_LIMIT_VALID_VALUE, String.valueOf(enable));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1624,7 +1626,7 @@ public class AdasChannel implements IAdasNetCommApi, FpgaSocket.IWebSocketConnec
|
||||
*/
|
||||
@Override
|
||||
public boolean sendRampThetaValid(int enable) {
|
||||
return sendSetParamReq(Constants.PARAM_TYPE.RAMP_THETA_VALID, String.valueOf(enable));
|
||||
return sendSetParamReq(AdasConstants.MapSystemParamType.RAMP_THETA_VALID_VALUE, String.valueOf(enable));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1635,46 +1637,47 @@ public class AdasChannel implements IAdasNetCommApi, FpgaSocket.IWebSocketConnec
|
||||
*/
|
||||
@Override
|
||||
public boolean sendWeakNetSlowDown(int enable) {
|
||||
return sendSetParamReq(Constants.PARAM_TYPE.WEAK_NET_SLOW_DOWN, String.valueOf(enable));
|
||||
return sendSetParamReq(AdasConstants.MapSystemParamType.WEAK_NET_SLOW_DOWN_VALUE, String.valueOf(enable));
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取全部参数
|
||||
* 结果回调{@link OnAdasListener#onGetParamResp(MessagePad.Header, MessagePad.SetParamReq)}
|
||||
* 结果回调{@link OnAdasListener#onGetParamResp(MessagePad.Header, MessagePad.SetParamReq, AdasParam)}
|
||||
*
|
||||
* @return boolean
|
||||
*/
|
||||
@Override
|
||||
public boolean sendGetAllParamReq() {
|
||||
return sendGetParamReq(Constants.PARAM_TYPE.UNKNOWN);
|
||||
return sendGetParamReq(null);
|
||||
}
|
||||
|
||||
/**
|
||||
* 参数获取请求
|
||||
* 结果回调{@link OnAdasListener#onGetParamResp(MessagePad.Header, MessagePad.SetParamReq)}
|
||||
* 结果回调{@link OnAdasListener#onGetParamResp(MessagePad.Header, MessagePad.SetParamReq, AdasParam)}
|
||||
*
|
||||
* @param paramType 参数类型{@link Constants.PARAM_TYPE}
|
||||
* @param paramType 参数类型:libraries/mogo-adas-data/src/main/proto/personal/adas_constants.proto
|
||||
* @return boolean
|
||||
*/
|
||||
@Override
|
||||
public boolean sendGetParamReq(@Define.ParamType int paramType) {
|
||||
public boolean sendGetParamReq(AdasConstants.MapSystemParamType paramType) {
|
||||
MessagePad.SetParamReq req;
|
||||
if (paramType == Constants.PARAM_TYPE.UNKNOWN) {
|
||||
if (paramType == null || paramType == AdasConstants.MapSystemParamType.DEFAULT_TYPE) {
|
||||
req = MessagePad.SetParamReq
|
||||
.newBuilder()
|
||||
.addReqs(MessagePad.SetOneParam.newBuilder().setType(Constants.PARAM_TYPE.DETOURING))
|
||||
.addReqs(MessagePad.SetOneParam.newBuilder().setType(Constants.PARAM_TYPE.DETOURING_SPEED))
|
||||
.addReqs(MessagePad.SetOneParam.newBuilder().setType(Constants.PARAM_TYPE.AEB))
|
||||
.addReqs(MessagePad.SetOneParam.newBuilder().setType(Constants.PARAM_TYPE.LANE_CHANGE_RESTRAIN_VALID))
|
||||
.addReqs(MessagePad.SetOneParam.newBuilder().setType(Constants.PARAM_TYPE.STOP_YIELD_VALID))
|
||||
.addReqs(MessagePad.SetOneParam.newBuilder().setType(Constants.PARAM_TYPE.HADMAP_SPEED_LIMIT_VALID))
|
||||
.addReqs(MessagePad.SetOneParam.newBuilder().setType(Constants.PARAM_TYPE.RAMP_THETA_VALID))
|
||||
.addReqs(MessagePad.SetOneParam.newBuilder().setType(Constants.PARAM_TYPE.WEAK_NET_SLOW_DOWN))
|
||||
.addReqs(MessagePad.SetOneParam.newBuilder().setType(AdasConstants.MapSystemParamType.DETOURING_VALUE))
|
||||
.addReqs(MessagePad.SetOneParam.newBuilder().setType(AdasConstants.MapSystemParamType.DETOURING_SPEED_VALUE))
|
||||
.addReqs(MessagePad.SetOneParam.newBuilder().setType(AdasConstants.MapSystemParamType.AEB_VALUE))
|
||||
.addReqs(MessagePad.SetOneParam.newBuilder().setType(AdasConstants.MapSystemParamType.LANE_CHANGE_RESTRAIN_VALID_VALUE))
|
||||
.addReqs(MessagePad.SetOneParam.newBuilder().setType(AdasConstants.MapSystemParamType.STOP_YIELD_VALID_VALUE))
|
||||
.addReqs(MessagePad.SetOneParam.newBuilder().setType(AdasConstants.MapSystemParamType.HADMAP_SPEED_LIMIT_VALID_VALUE))
|
||||
.addReqs(MessagePad.SetOneParam.newBuilder().setType(AdasConstants.MapSystemParamType.RAMP_THETA_VALID_VALUE))
|
||||
.addReqs(MessagePad.SetOneParam.newBuilder().setType(AdasConstants.MapSystemParamType.WEAK_NET_SLOW_DOWN_VALUE))
|
||||
.addReqs(MessagePad.SetOneParam.newBuilder().setType(AdasConstants.MapSystemParamType.M1_STITCHED_VIDEO_SELF_VEHICLE_PARAM_VALUE))
|
||||
.build();
|
||||
} else {
|
||||
req = MessagePad.SetParamReq
|
||||
.newBuilder()
|
||||
.addReqs(MessagePad.SetOneParam.newBuilder().setType(paramType))
|
||||
.addReqs(MessagePad.SetOneParam.newBuilder().setType(paramType.getNumber()))
|
||||
.build();
|
||||
}
|
||||
return sendPBMessage(MessageType.TYPE_SEND_GET_PARAM_REQ.typeCode, req.toByteArray());
|
||||
|
||||
@@ -5,6 +5,7 @@ import android.text.TextUtils;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
|
||||
import com.zhjt.mogo.adas.data.bean.AdasParam;
|
||||
import com.zhidao.support.adas.high.bean.VersionCompatibility;
|
||||
import com.zhidao.support.adas.high.common.AppPreferenceHelper;
|
||||
import com.zhidao.support.adas.high.common.Constants;
|
||||
@@ -17,6 +18,7 @@ import com.zhjt.mogo.adas.data.sweeper.task.SweeperTask;
|
||||
import com.zhjt.mogo.adas.data.sweeper.task.SweeperTaskSuspendResume;
|
||||
import com.zhjt.mogo.adas.data.sweeper.task.confirm.SweeperTaskConfirm;
|
||||
import com.zhjt.mogo.adas.data.sweeper.task.stop.SweeperTaskStop;
|
||||
import com.zhjt.mogo.adas.data.AdasConstants;
|
||||
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
@@ -914,7 +916,7 @@ public class AdasManager implements IAdasNetCommApi {
|
||||
|
||||
/**
|
||||
* 获取全部参数
|
||||
* 结果回调{@link OnAdasListener#onGetParamResp(MessagePad.Header, MessagePad.SetParamReq)}
|
||||
* 结果回调{@link OnAdasListener#onGetParamResp(MessagePad.Header, MessagePad.SetParamReq, AdasParam)}
|
||||
*
|
||||
* @return boolean
|
||||
*/
|
||||
@@ -925,13 +927,13 @@ public class AdasManager implements IAdasNetCommApi {
|
||||
|
||||
/**
|
||||
* 参数获取请求
|
||||
* 结果回调{@link OnAdasListener#onGetParamResp(MessagePad.Header, MessagePad.SetParamReq)}
|
||||
* 结果回调{@link OnAdasListener#onGetParamResp(MessagePad.Header, MessagePad.SetParamReq, AdasParam)}
|
||||
*
|
||||
* @param paramType 参数类型{@link Constants.PARAM_TYPE}
|
||||
* @param paramType 参数类型:libraries/mogo-adas-data/src/main/proto/personal/adas_constants.proto
|
||||
* @return boolean
|
||||
*/
|
||||
@Override
|
||||
public boolean sendGetParamReq(@Define.ParamType int paramType) {
|
||||
public boolean sendGetParamReq(AdasConstants.MapSystemParamType paramType) {
|
||||
return mChannel != null && mChannel.sendGetParamReq(paramType);
|
||||
}
|
||||
|
||||
|
||||
@@ -11,6 +11,7 @@ import com.zhjt.mogo.adas.data.sweeper.task.SweeperTask;
|
||||
import com.zhjt.mogo.adas.data.sweeper.task.SweeperTaskSuspendResume;
|
||||
import com.zhjt.mogo.adas.data.sweeper.task.confirm.SweeperTaskConfirm;
|
||||
import com.zhjt.mogo.adas.data.sweeper.task.stop.SweeperTaskStop;
|
||||
import com.zhjt.mogo.adas.data.AdasConstants;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
@@ -571,10 +572,10 @@ public interface IAdasNetCommApi {
|
||||
/**
|
||||
* 参数获取请求
|
||||
*
|
||||
* @param paramType
|
||||
* @param paramType 参数类型:libraries/mogo-adas-data/src/main/proto/personal/adas_constants.proto
|
||||
* @return boolean
|
||||
*/
|
||||
boolean sendGetParamReq(@Define.ParamType int paramType);
|
||||
boolean sendGetParamReq(AdasConstants.MapSystemParamType paramType);
|
||||
|
||||
|
||||
/**
|
||||
|
||||
@@ -4,12 +4,12 @@ import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
|
||||
import com.mogo.support.obu.ObuScene;
|
||||
import com.zhidao.support.adas.high.bean.AdasParam;
|
||||
import com.zhjt.mogo.adas.data.AdasConstants;
|
||||
import com.zhidao.support.adas.high.common.MessageType;
|
||||
import com.zhidao.support.adas.high.common.ProtocolStatus;
|
||||
import com.zhjt.mogo.adas.data.bean.AdasParam;
|
||||
import com.zhjt.mogo.adas.data.bean.AutopilotStatistics;
|
||||
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import com.zhjt.mogo.adas.data.sweeper.SweeperCloudTask;
|
||||
import com.zhjt.mogo.adas.data.sweeper.bootable.SweeperBootable;
|
||||
import com.zhjt.mogo.adas.data.sweeper.task.SweeperTask;
|
||||
@@ -377,7 +377,7 @@ public interface OnAdasListener {
|
||||
* @param header 头
|
||||
* @param rsi 数据
|
||||
*/
|
||||
void onV2nCongestionEvent(@NotNull MessagePad.Header header, @NotNull MogoV2X.RSI_PB rsi);
|
||||
void onV2nCongestionEvent(@NonNull MessagePad.Header header, @NonNull MogoV2X.RSI_PB rsi);
|
||||
|
||||
/**
|
||||
* 主车路径全局事件推送
|
||||
@@ -389,19 +389,19 @@ public interface OnAdasListener {
|
||||
* @param congestion 拥堵
|
||||
* @param parkingViolation 违停 ---包含 静态障碍车
|
||||
*/
|
||||
void onV2nGlobalPathEvents(@NotNull MessagePad.Header header, @NotNull RoadOverviewEvents.RoadOverviewData roadOverview, @Nullable MogoV2X.RSI_PB construct, @Nullable MogoV2X.RSI_PB triangle, @Nullable MogoV2X.RSI_PB congestion, @Nullable MogoV2X.RSM_PB parkingViolation);
|
||||
void onV2nGlobalPathEvents(@NonNull MessagePad.Header header, @NonNull RoadOverviewEvents.RoadOverviewData roadOverview, @Nullable MogoV2X.RSI_PB construct, @Nullable MogoV2X.RSI_PB triangle, @Nullable MogoV2X.RSI_PB congestion, @Nullable MogoV2X.RSM_PB parkingViolation);
|
||||
|
||||
/**
|
||||
* 参数获取应答
|
||||
* <p>
|
||||
* 调用{@link AdasManager#sendGetAllParamReq()}或{@link AdasManager#sendGetParamReq(int)}
|
||||
* 调用{@link AdasManager#sendGetAllParamReq()}或{@link AdasManager#sendGetParamReq(AdasConstants.MapSystemParamType)}
|
||||
* 如果对应的value是空串,说明没有这个param或者get失败了。重启后值还是在redis里
|
||||
*
|
||||
* @param header 头
|
||||
* @param getParamResp 配置参数
|
||||
* @param adasParam 解析后的配置参数
|
||||
* @param adasParam 解析后的配置参数
|
||||
*/
|
||||
void onGetParamResp(@NotNull MessagePad.Header header, @NotNull MessagePad.SetParamReq getParamResp, @NotNull AdasParam adasParam);
|
||||
void onGetParamResp(@NonNull MessagePad.Header header, @NonNull MessagePad.SetParamReq getParamResp, @NonNull AdasParam adasParam);
|
||||
|
||||
/**
|
||||
* M1拼接视频 10Hz
|
||||
|
||||
@@ -120,18 +120,4 @@ public class Constants {
|
||||
int OLD_CHASSIS = 1;//老底盘
|
||||
}
|
||||
|
||||
/**
|
||||
* 参数类型
|
||||
*/
|
||||
public interface PARAM_TYPE {
|
||||
int UNKNOWN = -1;
|
||||
int DETOURING = 1;//绕障类功能开关
|
||||
int DETOURING_SPEED = 2;//变道绕障的目标障碍物速度阈值
|
||||
int AEB = 3;//AEB开关
|
||||
int LANE_CHANGE_RESTRAIN_VALID = 4;//限制绕障开关
|
||||
int STOP_YIELD_VALID = 5;//停车让行线前避让等待开关
|
||||
int HADMAP_SPEED_LIMIT_VALID = 6;//地图限速功能开关
|
||||
int RAMP_THETA_VALID = 7;//环岛模式开关
|
||||
int WEAK_NET_SLOW_DOWN = 8;//弱网减速停车策略开关
|
||||
}
|
||||
}
|
||||
|
||||
@@ -55,11 +55,4 @@ public final class Define {
|
||||
public @interface AutopilotStartStatus {
|
||||
}
|
||||
|
||||
@IntDef(flag = true, value = {Constants.PARAM_TYPE.DETOURING, Constants.PARAM_TYPE.DETOURING_SPEED,
|
||||
Constants.PARAM_TYPE.AEB, Constants.PARAM_TYPE.LANE_CHANGE_RESTRAIN_VALID,
|
||||
Constants.PARAM_TYPE.STOP_YIELD_VALID, Constants.PARAM_TYPE.HADMAP_SPEED_LIMIT_VALID,
|
||||
Constants.PARAM_TYPE.RAMP_THETA_VALID, Constants.PARAM_TYPE.WEAK_NET_SLOW_DOWN})
|
||||
@Retention(RetentionPolicy.SOURCE)
|
||||
public @interface ParamType {
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5,7 +5,7 @@ import android.os.SystemClock;
|
||||
import com.google.protobuf.InvalidProtocolBufferException;
|
||||
import com.zhidao.support.adas.high.AdasChannel;
|
||||
import com.zhidao.support.adas.high.OnAdasListener;
|
||||
import com.zhidao.support.adas.high.bean.AdasParam;
|
||||
import com.zhjt.mogo.adas.data.bean.AdasParam;
|
||||
import com.zhidao.support.adas.high.common.CupidLogUtils;
|
||||
import com.zhidao.support.adas.high.protocol.RawData;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user