Merge branch 'dev_robotaxi-d_241112_6.8.1_dev' into dev_robotaxi-d_241210_6.9.0

This commit is contained in:
xuxinchao
2024-12-10 19:49:58 +08:00
40 changed files with 1498 additions and 135 deletions

View File

@@ -83,6 +83,7 @@ import com.zhjt.service.chain.ChainLog
import io.netty.channel.Channel
import mogo.telematics.pad.MessagePad
import mogo.yycp.paralleldriving.protocol.ParallelDrivingRequest
import system_master.SsmInfo
import java.util.*
import java.util.concurrent.TimeUnit
@@ -1508,4 +1509,36 @@ class MoGoAutopilotControlProvider :
return AdasManager.getInstance().sendSimulationWireFailure(isTrigger)>-1
}
/**
* SSM发送OTA升级提示请求响应
* @param token 域控发送OTA升级请求中的Token {@link SsmInfo.OtaDownloadRequest#getOtaToken()}
* @param ifUpgrade {@link SsmInfo.IfUpgrade#IMMEDIATELY}:立即
* {@link SsmInfo.IfUpgrade#DELAY}:推迟
*/
override fun sendSsmFuncOtaDownloadResponse(
token: String,
ifUpgrade: SsmInfo.IfUpgrade
): Boolean {
return AdasManager.getInstance().sendSsmFuncOtaDownloadResponse(token, ifUpgrade)>-1
}
/**
* 查询OTA状态
* @param token 域控发送OTA升级请求中的Token {@link SsmInfo.OtaDownloadRequest#getOtaToken()}
* 如果没有可以传null或""
*/
override fun sendSsmFuncOtaStatusQuery(token: String): Boolean {
return AdasManager.getInstance().sendSsmFuncOtaStatusQuery(token)>-1
}
/**
* 人工接管时获取前方和后方摄像头数据
* 一次请求域控回调次两次摄像头数据 根据{@link MessagePad.CaptureImgOnTakeOver#getUuid()}进行区分是否是哪次请求
* 例如下发uuid = 1 域控正常会回调两次响应接口 两次的uuid都是1通过isFront区分是前方还是后方摄像头
* 域控响应接口{@link OnAdasListener#onCaptureImgOnTakeOver(MessagePad.Header, boolean, MessagePad.CaptureImgOnTakeOver)}
*/
override fun sendCaptureImgReqOnTakeOver(uuid: Long): Boolean {
return AdasManager.getInstance().sendCaptureImgReqOnTakeOver(uuid)>-1
}
}

View File

@@ -83,6 +83,8 @@ import com.mogo.eagle.core.function.call.autopilot.CallerSweeperFutianCloudTaskL
import com.mogo.eagle.core.function.call.autopilot.CallerTakeoverListenerManager
import com.mogo.eagle.core.function.call.autopilot.CallerV2XListenerManager
import com.mogo.eagle.core.function.call.autopilot.CallerV2nNioEventListenerManager
import com.mogo.eagle.core.function.call.devatools.CallerCaptureImgManager
import com.mogo.eagle.core.function.call.devatools.CallerOTAManager
import com.mogo.eagle.core.function.call.msgbox.CallerMsgBoxManager
import com.mogo.eagle.core.function.call.obu.CallerObuMapMathListenerManager
import com.mogo.eagle.core.function.call.obu.CallerObuWarningRsiListenerManager
@@ -425,6 +427,67 @@ class MoGoAdasListenerImpl : OnAdasListener {
override fun onWarn(header: MessagePad.Header, warn: MessagePad.Warn?) {
}
/**
* SSM发送OTA升级提示请求
*
* @param header 头
* @param token PadSsmMsg唯一消息ID
* @param timestamp 消息发送时间 单位:毫秒
* @param request 数据 null表示 PadSsmMsg中的消息体为null
*/
override fun onOtaDownloadRequest(
header: MessagePad.Header?,
token: Long,
timestamp: Long,
request: SsmInfo.OtaDownloadRequest?
) {
if(request != null){
CallerOTAManager.invokeOtaDownloadRequest(request)
}
}
// /**
// * SSM上报OTA下载进度, 开始升级后定频上报
// *
// * @param header 头
// * @param token PadSsmMsg唯一消息ID
// * @param timestamp 消息发送时间 单位:毫秒
// * @param progress 数据 null表示 PadSsmMsg中的消息体为null
// */
// override fun onOtaLoadingProgress(
// header: MessagePad.Header?,
// token: Long,
// timestamp: Long,
// progress: SsmInfo.OtaLoadingProgess?
// ) {
// if(progress != null){
// CallerOTAManager.invokeOtaLoadingProgress(progress)
// }
// }
/**
* SSM上报OTA状态和查询OTA状态
* 冷启动状态变更上报以及查询状态
* 如果是查询到的结果,{@link SsmInfo.OtaStatus#getOtaInfo()}中的{@link SsmInfo.OtaDownloadRequest#getOtaToken()}==""表示不存在升级任务
*
* @param header 头
* @param token PadSsmMsg唯一消息ID
* @param timestamp 消息发送时间 单位:毫秒
* @param isQuery 是否是查询 ture查询响应的结果 false表示状态变动域控主动推送
* @param status 数据 null表示 PadSsmMsg中的消息体为null
*/
override fun onOtaStatus(
header: MessagePad.Header?,
token: Long,
timestamp: Long,
isQuery: Boolean,
status: SsmInfo.OtaStatus?
) {
if(status != null){
CallerOTAManager.invokeOtaStatus(status)
}
}
/**
* 冷启动状态变更上报以及查询状态
*
@@ -1283,6 +1346,21 @@ class MoGoAdasListenerImpl : OnAdasListener {
}
}
/**
* 接管时前方和后方摄像头数据请求的响应
*
* @param header 头
* @param isFront true前方摄像头 false后方摄像头
* @param data 数据
*/
override fun onCaptureImgOnTakeOver(
header: MessagePad.Header,
isFront: Boolean,
data: MessagePad.CaptureImgOnTakeOver
) {
CallerCaptureImgManager.invokeCaptureImgOnTakeOver(isFront, data)
}
/**
* 是否可以启动自动驾驶
* 使用方法查看app_ipc_monitoring/uiMainActivity/onAutopilotAbility

View File

@@ -73,6 +73,7 @@ import com.zhjt.mogo_core_function_devatools.mofang.MoGoMoFangProviderImpl
import com.zhjt.mogo_core_function_devatools.monitor.MonitorManager
import com.zhjt.mogo_core_function_devatools.monitor.db.MonitorDb
import com.zhjt.mogo_core_function_devatools.monitor.db.MonitorDb.Companion.getDb
import com.zhjt.mogo_core_function_devatools.ota.OTAUpgradeManager
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
@@ -204,6 +205,7 @@ class DevaToolsProvider : IDevaToolsProvider, IAppStateListener {
// apmEnvProvider.init(if(DebugConfig.isDebug()) "0" else "1", "${ DebugConfig.getNetMode() }", mDockerVersion ?: "")
BadCaseManager.init(mContext!!)
ColdStartManager.init(mContext!!)
OTAUpgradeManager.init(mContext!!)
if (DebugConfig.isDebug()) {
SdtManager.init(mContext!!, true, DetectResultImpl())
}

View File

@@ -5,6 +5,7 @@ import android.annotation.SuppressLint
import android.app.Activity
import android.content.Context
import android.graphics.Bitmap
import android.graphics.BitmapFactory
import android.os.Environment
import android.os.SystemClock
import android.util.Log
@@ -42,6 +43,7 @@ import com.mogo.eagle.core.function.api.autopilot.IMoGoChassisStatesListener
import com.mogo.eagle.core.function.api.autopilot.IMoGoTakeoverListener
import com.mogo.eagle.core.function.api.datacenter.IDataCenterBizListener
import com.mogo.eagle.core.function.api.datacenter.msgbox.IMsgBoxListener
import com.mogo.eagle.core.function.api.devatools.ICaptureImgListener
import com.mogo.eagle.core.function.api.devatools.IMoGoDevaToolsListener
import com.mogo.eagle.core.function.api.map.deva.IMoGoMapScreenListener
import com.mogo.eagle.core.function.call.autopilot.CallerAutoPilotControlManager
@@ -52,6 +54,7 @@ import com.mogo.eagle.core.function.call.autopilot.CallerChassisLocationWGS84Lis
import com.mogo.eagle.core.function.call.autopilot.CallerChassisStatesListenerManager
import com.mogo.eagle.core.function.call.autopilot.CallerTakeoverListenerManager
import com.mogo.eagle.core.function.call.datacenter.CallerDataCenterBizListener
import com.mogo.eagle.core.function.call.devatools.CallerCaptureImgManager
import com.mogo.eagle.core.function.call.devatools.CallerDevaToolsListenerManager
import com.mogo.eagle.core.function.call.map.CallerMapScreenListenerManager
import com.mogo.eagle.core.function.call.map.CallerMapUIServiceManager
@@ -72,6 +75,7 @@ import com.zhjt.mogo_core_function_devatools.badcase.util.RecordBitmapUtils
import com.zhjt.mogo_core_function_devatools.ext.enqueuePop
import com.zhjt.mogo_core_function_devatools.workorder.ReportTypeWindow
import me.jessyan.autosize.utils.AutoSizeUtils
import mogo.telematics.pad.MessagePad
import record_cache.RecordPanelOuterClass
import java.io.File
import java.util.Random
@@ -81,7 +85,7 @@ internal object BadCaseManager : LifecycleEventObserver, IMoGoAutopilotRecordLis
IMoGoChassisLocationGCJ02Listener, IMsgBoxListener, IMoGoDevaToolsListener,
IMogoStatusChangedListener, IMoGoMapScreenListener,
IMoGoChassisStatesListener, IMoGoAutopilotStatusListener,
IDataCenterBizListener, IMoGoTakeoverListener {
IDataCenterBizListener, IMoGoTakeoverListener, ICaptureImgListener {
const val TAG = "BadCase"
@@ -91,6 +95,7 @@ internal object BadCaseManager : LifecycleEventObserver, IMoGoAutopilotRecordLis
private var record: AutoPilotRecord? = null
private var recordKey: Long = 0 //主动录制bag包key
private var takeOverBagId: Long = 0 //接管录包Bag Id(key)
@SuppressLint("StaticFieldLeak")
private var reportTypeWindow: ReportTypeWindow ?= null
@@ -116,6 +121,8 @@ internal object BadCaseManager : LifecycleEventObserver, IMoGoAutopilotRecordLis
//消息盒子监听获取FM和Report信息
CallerMsgBoxListenerManager.addListener(TAG,this)
CallerDevaToolsListenerManager.addListener(TAG, this)
//接管时前方和后方摄像头数据请求响应回调监听
CallerCaptureImgManager.addListener(TAG, this)
// 云socket连接状态
MogoStatusManager.getInstance()
.registerStatusChangedListener(TAG, StatusDescriptor.CLOUD_SOCKET, this)
@@ -297,8 +304,6 @@ internal object BadCaseManager : LifecycleEventObserver, IMoGoAutopilotRecordLis
}else{
//进行录包,但不展示录包弹窗
BadCaseConfig.notDisplayBagWindow = true
//高精地图屏幕截图
CallerMapScreenListenerManager.addListener(TAG,this)
val recordKey = Random(SystemClock.elapsedRealtime()).nextInt().toLong()
CallerAutoPilotControlManager.recordPackage(BadCaseConfig.type,recordKey.toInt(),
BadCaseConfig.totalDuration, BadCaseConfig.previousDuration)
@@ -416,8 +421,6 @@ internal object BadCaseManager : LifecycleEventObserver, IMoGoAutopilotRecordLis
//保存录包状态
recordSet.add(recordPanel.key.toString())
BadCaseConfig.setInitiativeRecordSet(recordSet)
//开启高精地图截图
CallerMapUIServiceManager.getMapUIController()?.getMapScreenShot()
//将当次主动录包设置标签还原
BadCaseConfig.notDisplayBagWindow = false
}
@@ -457,6 +460,13 @@ internal object BadCaseManager : LifecycleEventObserver, IMoGoAutopilotRecordLis
val latLon = LatLonPoint(CallerChassisLocationWGS84ListenerManager.getChassisLocationWGS84().latitude, CallerChassisLocationWGS84ListenerManager.getChassisLocationWGS84().longitude)
val q = RegeocodeQuery(latLon,200f,GeocodeSearch.AMAP)
geocodeSearch.getFromLocationAsyn(q)
takeOverBagId = recordPanel.key
//触发域控前后120度摄像头截图和高精地图截图
CallerAutoPilotControlManager.sendCaptureImgReqOnTakeOver(recordPanel.key)
//高精地图屏幕截图
CallerMapScreenListenerManager.addListener(TAG,this)
//开启高精地图截图
CallerMapUIServiceManager.getMapUIController()?.getMapScreenShot()
}
}
}
@@ -578,42 +588,16 @@ internal object BadCaseManager : LifecycleEventObserver, IMoGoAutopilotRecordLis
override fun onMapScreen(bitmap: Bitmap) {
super.onMapScreen(bitmap)
//在截图上保存即时信息
val time = "时间:${millis2String(System.currentTimeMillis(), TimeUtils.getHourMinSecondFormat())}"
val lineId = "路线ID:${CallerAutoPilotStatusListenerManager.getLineId()}"
val state = when(CallerAutoPilotStatusListenerManager.getState()){
0->"自驾状态:不可自驾"
1->"自驾状态:可自驾"
2->"自驾状态:自驾中"
7->"自驾状态:平行驾驶中"
else->"自驾状态:未知"
}
val speed = "当前车速:${BadCaseConfig.currentSpeed}"
val site = if(CallerAutoPilotStatusListenerManager.getLineStartName().isNullOrEmpty() || CallerAutoPilotStatusListenerManager.getLineEndName().isNullOrEmpty()){
"路线起始点:无"
}else{
"路线起点:${CallerAutoPilotStatusListenerManager.getLineStartName()};终点:${CallerAutoPilotStatusListenerManager.getLineEndName()}"
}
val outBitmap = RecordBitmapUtils.drawTextOnBitmap(bitmap,time,lineId,state,speed,site,
BadCaseConfig.gpsStatus,BadCaseConfig.tracingStatus,BadCaseConfig.socketStatus
,BadCaseConfig.newFMInfoMsg,BadCaseConfig.newReportEntity)
//图片保存本地
val currentDay = millis2String(System.currentTimeMillis(), TimeUtils.getMdFormat())
val fileDir: String = Environment.getExternalStorageDirectory().absolutePath + File.separator+
"MapScreen" + File.separator+ currentDay + File.separator
val fileName = "$recordKey.png"
val fileName = "$takeOverBagId.png"
val path = fileDir + fileName
if (!File(fileDir).exists()) {
File(fileDir).mkdirs()
}
if(outBitmap != null){
RecordBitmapUtils.bitmap2Path(outBitmap,path)
}else{
RecordBitmapUtils.bitmap2Path(bitmap,path)
}
//遍历是否有非当日的文件并删除
RecordBitmapUtils.deleteExpiredFile(currentDay)
RecordBitmapUtils.bitmap2Path(bitmap,path)
//注销高精地图截图监听回调
CallerMapScreenListenerManager.removeListener(TAG)
}
@@ -648,4 +632,30 @@ internal object BadCaseManager : LifecycleEventObserver, IMoGoAutopilotRecordLis
}
/**
* 接管时前方和后方摄像头数据请求的响应
* @param isFront true前方摄像头 false后方摄像头
* @param data 数据
*/
override fun onCaptureImgOnTakeOver(isFront: Boolean, data: MessagePad.CaptureImgOnTakeOver) {
super.onCaptureImgOnTakeOver(isFront, data)
//将byte字节流转为Bitmap
val bitmap = BitmapFactory.decodeByteArray(data.data.toByteArray(),0,data.toByteArray().size)
//图片保存本地
val currentDay = millis2String(System.currentTimeMillis(), TimeUtils.getMdFormat())
val imageName = if(isFront){
"FrontCamera"
}else{
"RearCamera"
}
val fileDir: String = Environment.getExternalStorageDirectory().absolutePath + File.separator+
imageName + File.separator+ currentDay + File.separator
val fileName = "$takeOverBagId.png"
val path = fileDir + fileName
if (!File(fileDir).exists()) {
File(fileDir).mkdirs()
}
RecordBitmapUtils.bitmap2Path(bitmap,path)
}
}

View File

@@ -6,7 +6,6 @@ import android.graphics.Bitmap
import android.graphics.Color
import android.graphics.PixelFormat
import android.os.Bundle
import android.os.Environment
import android.os.Handler
import android.os.SystemClock
import android.util.DisplayMetrics
@@ -36,12 +35,9 @@ import com.mogo.eagle.core.function.api.autopilot.IMoGoAutopilotRecordListener
import com.mogo.eagle.core.function.api.devatools.badcase.BadCaseNetListener
import com.mogo.eagle.core.function.api.map.deva.IMoGoMapScreenListener
import com.mogo.eagle.core.function.call.autopilot.CallerAutoPilotControlManager
import com.mogo.eagle.core.function.call.autopilot.CallerAutoPilotStatusListenerManager
import com.mogo.eagle.core.function.call.autopilot.CallerAutopilotRecordListenerManager
import com.mogo.eagle.core.function.call.autopilot.CallerChassisLocationWGS84ListenerManager.getChassisLocationWGS84
import com.mogo.eagle.core.function.call.devatools.CallerDevaToolsNetManager
import com.mogo.eagle.core.function.call.map.CallerMapScreenListenerManager
import com.mogo.eagle.core.function.call.map.CallerMapUIServiceManager
import com.mogo.eagle.core.utilcode.mogo.logger.CallerLogger
import com.mogo.eagle.core.utilcode.mogo.logger.scene.SceneConstant.Companion.M_DEVA
import com.mogo.eagle.core.utilcode.mogo.toast.TipToast
@@ -75,7 +71,6 @@ import record_cache.RecordPanelOuterClass
import java.io.File
import java.util.*
import kotlin.collections.ArrayList
import kotlin.math.absoluteValue
/**
@@ -198,7 +193,7 @@ class InitiativeBadCaseWindow constructor(activity: Activity) : View.OnTouchList
BadCaseNetManager.badCaseNetManager.getRecordOption(1,AppConfigInfo.iPCMacAddress)
// BadCaseNetManager.badCaseNetManager.getRecordOption(1,"48:b0:2d:3a:9c:8f")
//高精地图屏幕截图
CallerMapScreenListenerManager.addListener(this.hashCode().toString(),this)
// CallerMapScreenListenerManager.addListener(this.hashCode().toString(),this)
//采集结果回调监听
CallerAutopilotRecordListenerManager.addListener(this.hashCode().toString(),this)
//主动录包采集原因回调监听
@@ -561,7 +556,7 @@ class InitiativeBadCaseWindow constructor(activity: Activity) : View.OnTouchList
//注销采集原因回调监听
CallerDevaToolsNetManager.removeListener(this.hashCode().toString())
//注销高精地图截图监听回调
CallerMapScreenListenerManager.removeListener(this.hashCode().toString())
// CallerMapScreenListenerManager.removeListener(this.hashCode().toString())
if (mFloatLayout.parent != null){
mWindowManager!!.removeView(mFloatLayout)
@@ -580,8 +575,8 @@ class InitiativeBadCaseWindow constructor(activity: Activity) : View.OnTouchList
//保存录包状态
recordSet.add(recordPanel.key.toString())
BadCaseConfig.setInitiativeRecordSet(recordSet)
//开启高精地图截图
CallerMapUIServiceManager.getMapUIController()?.getMapScreenShot()
// //开启高精地图截图
// CallerMapUIServiceManager.getMapUIController()?.getMapScreenShot()
}
if(recordFileName==null){
recordFileName = recordPanel.filename
@@ -702,44 +697,44 @@ class InitiativeBadCaseWindow constructor(activity: Activity) : View.OnTouchList
* 高精地图截图回调
*/
override fun onMapScreen(bitmap: Bitmap) {
//在截图上保存即时信息
val time = "时间:${millis2String(System.currentTimeMillis(), TimeUtils.getHourMinSecondFormat())}"
val lineId = "路线ID:${CallerAutoPilotStatusListenerManager.getLineId()}"
val state = when(CallerAutoPilotStatusListenerManager.getState()){
0->"自驾状态:不可自驾"
1->"自驾状态:可自驾"
2->"自驾状态:自驾中"
7->"自驾状态:平行驾驶中"
else->"自驾状态:未知"
}
val speed = "当前车速:${BadCaseConfig.currentSpeed}"
val site = if(CallerAutoPilotStatusListenerManager.getLineStartName().isNullOrEmpty() || CallerAutoPilotStatusListenerManager.getLineEndName().isNullOrEmpty()){
"路线起始点:无"
}else{
"路线起点:${CallerAutoPilotStatusListenerManager.getLineStartName()};终点:${CallerAutoPilotStatusListenerManager.getLineEndName()}"
}
val outBitmap = RecordBitmapUtils.drawTextOnBitmap(bitmap,time,lineId,state,speed,site,
BadCaseConfig.gpsStatus,BadCaseConfig.tracingStatus,BadCaseConfig.socketStatus
,BadCaseConfig.newFMInfoMsg,BadCaseConfig.newReportEntity)
//图片保存本地
val currentDay = millis2String(System.currentTimeMillis(), TimeUtils.getMdFormat())
val fileDir: String = Environment.getExternalStorageDirectory().absolutePath + File.separator+
"MapScreen" + File.separator+ currentDay + File.separator
val fileName = "$recordKey.png"
val path = fileDir + fileName
if (!File(fileDir).exists()) {
File(fileDir).mkdirs()
}
if(outBitmap != null){
RecordBitmapUtils.bitmap2Path(outBitmap,path)
}else{
RecordBitmapUtils.bitmap2Path(bitmap,path)
}
screenSavePath = path
//遍历是否有非当日的文件并删除
RecordBitmapUtils.deleteExpiredFile(currentDay)
// //在截图上保存即时信息
// val time = "时间:${millis2String(System.currentTimeMillis(), TimeUtils.getHourMinSecondFormat())}"
// val lineId = "路线ID:${CallerAutoPilotStatusListenerManager.getLineId()}"
// val state = when(CallerAutoPilotStatusListenerManager.getState()){
// 0->"自驾状态:不可自驾"
// 1->"自驾状态:可自驾"
// 2->"自驾状态:自驾中"
// 7->"自驾状态:平行驾驶中"
// else->"自驾状态:未知"
// }
// val speed = "当前车速:${BadCaseConfig.currentSpeed}"
// val site = if(CallerAutoPilotStatusListenerManager.getLineStartName().isNullOrEmpty() || CallerAutoPilotStatusListenerManager.getLineEndName().isNullOrEmpty()){
// "路线起始点:无"
// }else{
// "路线起点:${CallerAutoPilotStatusListenerManager.getLineStartName()};终点:${CallerAutoPilotStatusListenerManager.getLineEndName()}"
// }
//
// val outBitmap = RecordBitmapUtils.drawTextOnBitmap(bitmap,time,lineId,state,speed,site,
// BadCaseConfig.gpsStatus,BadCaseConfig.tracingStatus,BadCaseConfig.socketStatus
// ,BadCaseConfig.newFMInfoMsg,BadCaseConfig.newReportEntity)
//
// //图片保存本地
// val currentDay = millis2String(System.currentTimeMillis(), TimeUtils.getMdFormat())
// val fileDir: String = Environment.getExternalStorageDirectory().absolutePath + File.separator+
// "MapScreen" + File.separator+ currentDay + File.separator
// val fileName = "$recordKey.png"
// val path = fileDir + fileName
// if (!File(fileDir).exists()) {
// File(fileDir).mkdirs()
// }
// if(outBitmap != null){
// RecordBitmapUtils.bitmap2Path(outBitmap,path)
// }else{
// RecordBitmapUtils.bitmap2Path(bitmap,path)
// }
// screenSavePath = path
// //遍历是否有非当日的文件并删除
// RecordBitmapUtils.deleteExpiredFile(currentDay)
}
}

View File

@@ -37,7 +37,6 @@ import com.mogo.eagle.core.function.call.autopilot.CallerAutoPilotControlManager
import com.mogo.eagle.core.function.call.autopilot.CallerAutoPilotStatusListenerManager
import com.mogo.eagle.core.function.call.autopilot.CallerChassisLocationWGS84ListenerManager
import com.mogo.eagle.core.function.call.devatools.CallerDevaToolsNetManager
import com.mogo.eagle.core.function.call.map.CallerMapScreenListenerManager
import com.mogo.eagle.core.function.call.map.CallerMapUIServiceManager
import com.mogo.eagle.core.function.call.msgbox.CallerMsgBoxManager
import com.mogo.eagle.core.utilcode.mogo.logger.CallerLogger
@@ -180,7 +179,7 @@ class PassiveBadCaseWindow constructor(activity: Activity) : View.OnTouchListene
BadCaseNetManager.badCaseNetManager.getRecordOption(2,AppConfigInfo.iPCMacAddress)
// BadCaseNetManager.badCaseNetManager.getRecordOption(2,"48:b0:2d:3a:9c:8f")
//高精地图屏幕截图
CallerMapScreenListenerManager.addListener(this.hashCode().toString(),this)
// CallerMapScreenListenerManager.addListener(this.hashCode().toString(),this)
CallerDevaToolsNetManager.addListener(this.hashCode().toString(),this)
if(BadCaseConfig.windowNum<1){
BadCaseConfig.windowNum = 1
@@ -530,7 +529,7 @@ class PassiveBadCaseWindow constructor(activity: Activity) : View.OnTouchListene
fun hideFloatWindow() {
//注销高精地图截图监听回调
CallerMapScreenListenerManager.removeListener(this.hashCode().toString())
// CallerMapScreenListenerManager.removeListener(this.hashCode().toString())
//注销采集原因回调监听
CallerDevaToolsNetManager.removeListener(this.hashCode().toString())
// 移除 ADAS车辆状态&定位 监听
@@ -552,7 +551,7 @@ class PassiveBadCaseWindow constructor(activity: Activity) : View.OnTouchListene
receiveTime = msgBoxBean.timestamp.toString()
stat = recordBagMsg.stat.toString()
//获取高精地图截图
CallerMapUIServiceManager.getMapUIController()?.getMapScreenShot()
// CallerMapUIServiceManager.getMapUIController()?.getMapScreenShot()
}
fun setClickListener(clickListener: ClickListener) {
@@ -589,42 +588,42 @@ class PassiveBadCaseWindow constructor(activity: Activity) : View.OnTouchListene
*/
override fun onMapScreen(bitmap: Bitmap) {
//在截图上保存即时信息
val time = "时间:${millis2String(System.currentTimeMillis(), TimeUtils.getHourMinSecondFormat())}"
val lineId = "路线ID:${CallerAutoPilotStatusListenerManager.getLineId()}"
val state = when(CallerAutoPilotStatusListenerManager.getState()){
0->"自驾状态:不可自驾"
1->"自驾状态:可自驾"
2->"自驾状态:自驾中"
7->"自驾状态:平行驾驶中"
else->"自驾状态:未知"
}
val speed = "当前车速:${BadCaseConfig.currentSpeed}"
val site = if(CallerAutoPilotStatusListenerManager.getLineStartName().isNullOrEmpty() || CallerAutoPilotStatusListenerManager.getLineEndName().isNullOrEmpty()){
"路线起始点:无"
}else{
"路线起点:${CallerAutoPilotStatusListenerManager.getLineStartName()};终点:${CallerAutoPilotStatusListenerManager.getLineEndName()}"
}
val outBitmap = RecordBitmapUtils.drawTextOnBitmap(bitmap,time,lineId,state,speed,site,
BadCaseConfig.gpsStatus,BadCaseConfig.tracingStatus,BadCaseConfig.socketStatus
,BadCaseConfig.newFMInfoMsg,BadCaseConfig.newReportEntity)
//图片保存本地
val currentDay = millis2String(System.currentTimeMillis(), TimeUtils.getMdFormat())
val fileDir: String = Environment.getExternalStorageDirectory().absolutePath + File.separator+
"MapScreen" + File.separator+ currentDay + File.separator
val fileName = "$recordKey.png"
val path = fileDir + fileName
if (!File(fileDir).exists()) {
File(fileDir).mkdirs()
}
if(outBitmap != null){
RecordBitmapUtils.bitmap2Path(outBitmap,path)
}else{
RecordBitmapUtils.bitmap2Path(bitmap,path)
}
screenSavePath = path
//遍历是否有非当日的文件并删除
RecordBitmapUtils.deleteExpiredFile(currentDay)
// val time = "时间:${millis2String(System.currentTimeMillis(), TimeUtils.getHourMinSecondFormat())}"
// val lineId = "路线ID:${CallerAutoPilotStatusListenerManager.getLineId()}"
// val state = when(CallerAutoPilotStatusListenerManager.getState()){
// 0->"自驾状态:不可自驾"
// 1->"自驾状态:可自驾"
// 2->"自驾状态:自驾中"
// 7->"自驾状态:平行驾驶中"
// else->"自驾状态:未知"
// }
// val speed = "当前车速:${BadCaseConfig.currentSpeed}"
// val site = if(CallerAutoPilotStatusListenerManager.getLineStartName().isNullOrEmpty() || CallerAutoPilotStatusListenerManager.getLineEndName().isNullOrEmpty()){
// "路线起始点:无"
// }else{
// "路线起点:${CallerAutoPilotStatusListenerManager.getLineStartName()};终点:${CallerAutoPilotStatusListenerManager.getLineEndName()}"
// }
//
// val outBitmap = RecordBitmapUtils.drawTextOnBitmap(bitmap,time,lineId,state,speed,site,
// BadCaseConfig.gpsStatus,BadCaseConfig.tracingStatus,BadCaseConfig.socketStatus
// ,BadCaseConfig.newFMInfoMsg,BadCaseConfig.newReportEntity)
// //图片保存本地
// val currentDay = millis2String(System.currentTimeMillis(), TimeUtils.getMdFormat())
// val fileDir: String = Environment.getExternalStorageDirectory().absolutePath + File.separator+
// "MapScreen" + File.separator+ currentDay + File.separator
// val fileName = "$recordKey.png"
// val path = fileDir + fileName
// if (!File(fileDir).exists()) {
// File(fileDir).mkdirs()
// }
// if(outBitmap != null){
// RecordBitmapUtils.bitmap2Path(outBitmap,path)
// }else{
// RecordBitmapUtils.bitmap2Path(bitmap,path)
// }
// screenSavePath = path
// //遍历是否有非当日的文件并删除
// RecordBitmapUtils.deleteExpiredFile(currentDay)
}
/**

View File

@@ -0,0 +1,11 @@
package com.zhjt.mogo_core_function_devatools.ota
/**
* OTA升级配置
*/
object OTAUpgradeConfig {
@JvmField
var otaToken: String = ""
}

View File

@@ -0,0 +1,205 @@
package com.zhjt.mogo_core_function_devatools.ota
import android.content.Context
import android.util.Log
import com.mogo.eagle.core.data.deva.ota.OtaUpgradeInfo
import com.mogo.eagle.core.function.api.autopilot.IMoGoAutopilotStatusListener
import com.mogo.eagle.core.function.api.datacenter.IDataCenterBizListener
import com.mogo.eagle.core.function.api.devatools.IOTAListener
import com.mogo.eagle.core.function.call.autopilot.CallerAutoPilotControlManager
import com.mogo.eagle.core.function.call.autopilot.CallerAutoPilotStatusListenerManager
import com.mogo.eagle.core.function.call.datacenter.CallerDataCenterBizListener
import com.mogo.eagle.core.function.call.devatools.CallerOTAManager
import com.mogo.eagle.core.function.call.hmi.CallerHmiManager
import org.json.JSONArray
import org.json.JSONObject
import system_master.SsmInfo
/**
* OTA升级管理类
*/
object OTAUpgradeManager: IMoGoAutopilotStatusListener, IDataCenterBizListener, IOTAListener {
const val TAG = "OTAUpgradeManager"
fun init(context: Context){
CallerAutoPilotStatusListenerManager.addListener(TAG, this)
CallerDataCenterBizListener.addListener(TAG,this)
CallerOTAManager.addListener(TAG,this)
//查询OTA状态
CallerAutoPilotControlManager.sendSsmFuncOtaStatusQuery(OTAUpgradeConfig.otaToken)
}
/**
* 自动驾驶状态信息
* @param state 状态信息
* 0-不可自动驾驶adas与工控机没有链接或工控机异常
* 1-可自动驾驶,目前处于人工干预状态
* 2-自动驾驶中
* 7-平行驾驶中
*/
override fun onAutopilotStatusResponse(state: Int) {
super.onAutopilotStatusResponse(state)
}
/**
* 是否有订单
* @param inOrder true有订单 false没有订单
*/
override fun invokeOrderStatus(inOrder: Boolean) {
super.invokeOrderStatus(inOrder)
}
/**
* SSM发送OTA升级提示请求,主动触发
* @param request SSM发送OTA升级提示内容
*/
override fun onOtaDownloadRequest(request: SsmInfo.OtaDownloadRequest) {
super.onOtaDownloadRequest(request)
Log.i(TAG,"onOtaDownloadRequest otaToken"+request.otaToken)
Log.i(TAG,"onOtaDownloadRequest productName"+request.productName)
if(request.otaToken.isNotEmpty()){
if(OTAUpgradeConfig.otaToken != request.otaToken){
OTAUpgradeConfig.otaToken = request.otaToken
//触发升级提示
CallerHmiManager.showOTAUpgradeDialog()
}else{
//展示OTA升级提示
CallerHmiManager.showOTAUpgradeTipView(true)
}
}else{
//隐藏OTA升级提示
CallerHmiManager.showOTAUpgradeTipView(false)
}
//解析JSON
var upgradeComplete = true
val otaUpgradeList = ArrayList<OtaUpgradeInfo>()
val productArray = JSONArray(request.productName)
if(productArray.length() > 0){
for(index in 0 until productArray.length()){
val productInfo = productArray[index] as JSONObject
val token = productInfo.optString("token")
val productStatus = productInfo.optInt("status")
val failReason = productInfo.optString("fail_reason")
val upgradeReason = productInfo.optString("upgrade_reason")
val taskId = productInfo.optInt("task_id")
val taskItemId = productInfo.optInt("task_item_id")
val otaType = productInfo.optInt("ota_type")
val productName = productInfo.optString("product_name")
val needRestart = productInfo.optBoolean("need_restart")
val isDelay = productInfo.optBoolean("is_delay")
val curSize = productInfo.optDouble("cur_size")
val totalSize = productInfo.optDouble("total_size")
Log.i(TAG, "index=$index")
Log.i(TAG, "token=$token")
Log.i(TAG, "status=$productStatus")
Log.i(TAG, "fail_reason=$failReason")
Log.i(TAG, "upgrade_reason=$upgradeReason")
Log.i(TAG, "task_id=$taskId")
Log.i(TAG, "task_item_id=$taskItemId")
Log.i(TAG, "ota_type=$otaType")
Log.i(TAG, "product_name=$productName")
Log.i(TAG, "need_restart=$needRestart")
Log.i(TAG, "is_delay=$isDelay")
Log.i(TAG, "cur_size=$curSize")
Log.i(TAG, "total_size=$totalSize")
//// 状态 0:默认(未开始), 1:下载中, 2:下载完成, 3:升级完成, 4:升级失败
if(productStatus == 0 || productStatus == 1 || productStatus == 2){
upgradeComplete = false
}
val otaUpgradeInfo = OtaUpgradeInfo(token, productStatus,failReason,upgradeReason,
taskId,taskItemId,otaType,productName,needRestart,isDelay,curSize,totalSize)
otaUpgradeList.add(otaUpgradeInfo)
}
CallerHmiManager.showOTADownloadStatusDialog(otaUpgradeList)
if(upgradeComplete){
OTAUpgradeConfig.otaToken = ""
}
}
}
/**
* SSM上报OTA状态和查询OTA状态
* 冷启动状态变更上报以及查询状态
* 如果是查询到的结果,{@link SsmInfo.OtaStatus#getOtaInfo()}
* 中的{@link SsmInfo.OtaDownloadRequest#getOtaToken()}==""表示不存在升级任务
* @param status 冷启动状态变更上报以及查询状态
*/
override fun onOtaStatus(status: SsmInfo.OtaStatus) {
super.onOtaStatus(status)
Log.i(TAG,"onOtaStatus status.otaInfo.otaToken"+status.otaInfo.otaToken)
Log.i(TAG,"onOtaStatus status.otaInfo.productName"+status.otaInfo.productName)
if(status.otaInfo.otaToken.isNotEmpty()){
if(OTAUpgradeConfig.otaToken != status.otaInfo.otaToken){
OTAUpgradeConfig.otaToken = status.otaInfo.otaToken
//触发升级提示
CallerHmiManager.showOTAUpgradeDialog()
}else{
//展示OTA升级提示
CallerHmiManager.showOTAUpgradeTipView(true)
}
}else{
//隐藏OTA升级提示
CallerHmiManager.showOTAUpgradeTipView(false)
}
//解析JSON
val otaUpgradeList = ArrayList<OtaUpgradeInfo>()
val productArray = JSONArray(status.otaInfo.productName)
var upgradeComplete = true
if(productArray.length() > 0){
for(index in 0 until productArray.length()){
val productInfo = productArray[index] as JSONObject
val token = productInfo.optString("token")
val productStatus = productInfo.optInt("status")
val failReason = productInfo.optString("fail_reason")
val upgradeReason = productInfo.optString("upgrade_reason")
val taskId = productInfo.optInt("task_id")
val taskItemId = productInfo.optInt("task_item_id")
val otaType = productInfo.optInt("ota_type")
val productName = productInfo.optString("product_name")
val needRestart = productInfo.optBoolean("need_restart")
val isDelay = productInfo.optBoolean("is_delay")
val curSize = productInfo.optDouble("cur_size")
val totalSize = productInfo.optDouble("total_size")
Log.i(TAG, "index=$index")
Log.i(TAG, "token=$token")
Log.i(TAG, "status=$productStatus")
Log.i(TAG, "fail_reason=$failReason")
Log.i(TAG, "upgrade_reason=$upgradeReason")
Log.i(TAG, "task_id=$taskId")
Log.i(TAG, "task_item_id=$taskItemId")
Log.i(TAG, "ota_type=$otaType")
Log.i(TAG, "product_name=$productName")
Log.i(TAG, "need_restart=$needRestart")
Log.i(TAG, "is_delay=$isDelay")
Log.i(TAG, "cur_size=$curSize")
Log.i(TAG, "total_size=$totalSize")
//// 状态 0:默认(未开始), 1:下载中, 2:下载完成, 3:升级完成, 4:升级失败
if(productStatus == 0 || productStatus == 1 || productStatus == 2){
upgradeComplete = false
}
val otaUpgradeInfo = OtaUpgradeInfo(token, productStatus,failReason,upgradeReason,
taskId,taskItemId,otaType,productName,needRestart,isDelay,curSize,totalSize)
otaUpgradeList.add(otaUpgradeInfo)
}
CallerHmiManager.showOTADownloadStatusDialog(otaUpgradeList)
if(upgradeComplete){
OTAUpgradeConfig.otaToken = ""
}
}
}
}

View File

@@ -0,0 +1,27 @@
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
xmlns:app="http://schemas.android.com/apk/res-auto">
<ProgressBar
android:id="@+id/pbDownloadProgress"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent"
style="?android:attr/progressBarStyleHorizontal"
/>
<TextView
android:id="@+id/tvDownloadStatus"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toBottomOf="@id/pbDownloadProgress"
android:textSize="@dimen/sp_30"
/>
</androidx.constraintlayout.widget.ConstraintLayout>

View File

@@ -29,6 +29,7 @@ import com.mogo.eagle.core.data.constants.MogoServicePaths.PATH_FRAGMENT_HMI
import com.mogo.eagle.core.data.deva.bindingcar.IPCUpgradeStateInfo
import com.mogo.eagle.core.data.deva.bizconfig.FuncBizConfig.Companion.BIZ_RTS
import com.mogo.eagle.core.data.deva.bizconfig.FuncBizConfig.Companion.V2I
import com.mogo.eagle.core.data.deva.ota.OtaUpgradeInfo
import com.mogo.eagle.core.data.enums.EventTypeEnumNew
import com.mogo.eagle.core.data.enums.WarningDirectionEnum
import com.mogo.eagle.core.data.map.Infrastructure
@@ -58,6 +59,9 @@ import com.mogo.eagle.core.function.hmi.ui.setting.StatusView
import com.mogo.eagle.core.function.hmi.ui.setting.ToolsView.Companion.toolsView
import com.mogo.eagle.core.function.hmi.ui.tools.AdUpgradeDialog
import com.mogo.eagle.core.function.hmi.ui.tools.ModifyBindingCarDialog
import com.mogo.eagle.core.function.hmi.ui.tools.OTADownloadStatusDialog
import com.mogo.eagle.core.function.hmi.ui.tools.OTAUpgradeDialog
import com.mogo.eagle.core.function.hmi.ui.tools.OTAUpgradeTipView
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.utils.HmiActionLog
@@ -659,4 +663,59 @@ class MoGoHmiProvider : IMoGoHmiProvider {
CallerHmiViewControlListenerManager.invokeColdStartProcessView()
}
var otaUpgradeDialog: OTAUpgradeDialog ?= null
var otaDownloadStatusDialog: OTADownloadStatusDialog ?= null
var otaUpgradeTipView: OTAUpgradeTipView ?= null
/**
* 展示OTA升级弹窗
*/
override fun showOTAUpgradeDialog() {
ThreadUtils.runOnUiThread{
context?.let {
if(otaUpgradeDialog == null){
otaUpgradeDialog = OTAUpgradeDialog(it)
}
if(otaUpgradeDialog?.isShowing == false){
otaUpgradeDialog?.show()
}
}
}
}
/**
* 展示OTA升级下载状态弹窗
*/
override fun showOTADownloadStatusDialog(list: List<OtaUpgradeInfo>) {
ThreadUtils.runOnUiThread{
if(otaDownloadStatusDialog?.isShowing == true){
return@runOnUiThread
}
context?.let {
if(otaDownloadStatusDialog == null){
otaDownloadStatusDialog = OTADownloadStatusDialog(it)
}
otaDownloadStatusDialog?.notifyDownloadStatus(list)
}
}
}
/**
* 展示OTA升级提示
* @param visible 设置是否可见
*/
override fun showOTAUpgradeTipView(visible: Boolean) {
ThreadUtils.runOnUiThread{
if(otaUpgradeDialog?.isShowing == true){
return@runOnUiThread
}
if(otaUpgradeTipView == null){
context?.let {
otaUpgradeTipView = OTAUpgradeTipView(it)
}
}
otaUpgradeTipView?.setDisplayStatus(visible)
}
}
}

View File

@@ -0,0 +1,46 @@
package com.mogo.eagle.core.function.hmi.ui.tools
import android.content.Context
import androidx.lifecycle.LifecycleObserver
import androidx.recyclerview.widget.LinearLayoutManager
import com.mogo.eagle.core.data.deva.ota.OtaUpgradeInfo
import com.mogo.eagle.core.function.hmi.R
import com.mogo.eagle.core.function.hmi.dialog.BaseFloatDialog
import com.mogo.eagle.core.function.hmi.ui.tools.adapter.OTADownloadStatusAdapter
import kotlinx.android.synthetic.main.dialog_ota_download_status.rvDownloadStatus
/**
* OTA升级下载状态对话框
*/
class OTADownloadStatusDialog(context: Context) :
BaseFloatDialog(context,TAG), LifecycleObserver {
companion object {
private const val TAG = "OTADownloadStatusDialog"
}
private var otaDownloadStatusAdapter: OTADownloadStatusAdapter ?= null
init{
setContentView(R.layout.dialog_ota_download_status)
setCanceledOnTouchOutside(false)
initView()
}
private fun initView(){
val linearLayoutManager = LinearLayoutManager(context)
linearLayoutManager.orientation = LinearLayoutManager.VERTICAL
otaDownloadStatusAdapter = OTADownloadStatusAdapter(context)
rvDownloadStatus.adapter = otaDownloadStatusAdapter
rvDownloadStatus.layoutManager = linearLayoutManager
}
fun notifyDownloadStatus(list: List<OtaUpgradeInfo>){
if(!this.isShowing){
show()
}
otaDownloadStatusAdapter?.setData(list)
}
}

View File

@@ -0,0 +1,88 @@
package com.mogo.eagle.core.function.hmi.ui.tools
import android.content.Context
import android.os.CountDownTimer
import android.widget.TextView
import androidx.lifecycle.LifecycleObserver
import com.mogo.eagle.core.function.call.autopilot.CallerAutoPilotControlManager
import com.mogo.eagle.core.function.hmi.R
import com.mogo.eagle.core.function.hmi.dialog.BaseFloatDialog
import com.mogo.eagle.core.utilcode.util.ThreadUtils
import com.zhjt.mogo_core_function_devatools.ota.OTAUpgradeConfig
import kotlinx.android.synthetic.main.dialog_ota_upgrade.tv_upgrade_countdown
import kotlinx.android.synthetic.main.dialog_ota_upgrade.tv_upgrade_later
import kotlinx.android.synthetic.main.dialog_ota_upgrade.tv_upgrade_now
import system_master.SsmInfo
/**
* OTA升级对话框
*/
class OTAUpgradeDialog(context: Context) :
BaseFloatDialog(context,TAG), LifecycleObserver {
companion object {
private const val TAG = "OTAUpgradeDialog"
private const val UPGRADE_WAITING_TIME = 300000L //升级确认等待时间
private const val WAITING_TICK_TIME = 1000L //等待确认间隔时间
}
private var clickListener: ClickListener? = null
private var upgradeWaitingTimer: CountDownTimer ?= null //等待升级确认计时器
init{
setContentView(R.layout.dialog_ota_upgrade)
setCanceledOnTouchOutside(false)
initView()
}
private fun initView(){
//立即升级
tv_upgrade_now.setOnClickListener {
CallerAutoPilotControlManager.sendSsmFuncOtaDownloadResponse(OTAUpgradeConfig.otaToken,SsmInfo.IfUpgrade.IMMEDIATELY)
dismiss()
}
//稍后升级
tv_upgrade_later.setOnClickListener {
CallerAutoPilotControlManager.sendSsmFuncOtaDownloadResponse(OTAUpgradeConfig.otaToken,SsmInfo.IfUpgrade.DELAY)
dismiss()
}
upgradeWaitingTimer = object: CountDownTimer(UPGRADE_WAITING_TIME,WAITING_TICK_TIME){
override fun onTick(millisUntilFinished: Long) {
ThreadUtils.runOnUiThread {
tv_upgrade_countdown.text = millisUntilFinished.toInt().toString()
}
}
override fun onFinish() {
//立即升级
CallerAutoPilotControlManager.sendSsmFuncOtaDownloadResponse(OTAUpgradeConfig.otaToken,SsmInfo.IfUpgrade.IMMEDIATELY)
ThreadUtils.runOnUiThread {
dismiss()
}
}
}
upgradeWaitingTimer?.start()
}
fun setClickListener(clickListener: ClickListener) {
this.clickListener = clickListener
}
interface ClickListener{
//立即升级
fun upgradeNow()
//稍后升级
fun upgradeLater()
}
override fun onAttachedToWindow() {
super.onAttachedToWindow()
}
override fun onDetachedFromWindow() {
super.onDetachedFromWindow()
upgradeWaitingTimer?.cancel()
}
}

View File

@@ -0,0 +1,57 @@
package com.mogo.eagle.core.function.hmi.ui.tools
import android.content.Context
import android.util.AttributeSet
import android.view.LayoutInflater
import android.view.View
import androidx.constraintlayout.widget.ConstraintLayout
import com.mogo.eagle.core.function.call.hmi.CallerHmiManager
import com.mogo.eagle.core.function.hmi.R
import kotlinx.android.synthetic.main.view_ota_upgrade_tip.view.btn_upgrade
/**
* OTA升级任务标记提示
*/
class OTAUpgradeTipView @JvmOverloads constructor(
context: Context,
attrs: AttributeSet? = null,
defStyleAttr: Int = 0
) : ConstraintLayout(context, attrs, defStyleAttr){
companion object {
private const val TAG = "OTAUpgradeTipView"
}
init {
LayoutInflater.from(context).inflate(R.layout.view_ota_upgrade_tip, this, true)
initView()
}
private fun initView(){
btn_upgrade.setOnClickListener {
//打开升级弹窗
CallerHmiManager.showOTAUpgradeDialog()
}
}
/**
* 设置视图是否可见
* @param visible 是否可见
*/
fun setDisplayStatus(visible: Boolean){
if(visible){
if(this@OTAUpgradeTipView.visibility == View.VISIBLE){
return
}else{
this@OTAUpgradeTipView.visibility = View.VISIBLE
}
}else{
if(this@OTAUpgradeTipView.visibility != View.VISIBLE){
return
}else{
this@OTAUpgradeTipView.visibility = View.GONE
}
}
}
}

View File

@@ -0,0 +1,63 @@
package com.mogo.eagle.core.function.hmi.ui.tools.adapter
import android.content.Context
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.ProgressBar
import android.widget.TextView
import androidx.recyclerview.widget.RecyclerView
import com.mogo.eagle.core.data.deva.ota.OtaUpgradeInfo
import com.mogo.eagle.core.function.hmi.R
/**
* OTA升级下载状态适配器
*/
class OTADownloadStatusAdapter(private val context: Context): RecyclerView.Adapter<OTADownloadStatusAdapter.DownloadStatusHolder>() {
private var data: List<OtaUpgradeInfo> ?= null
fun setData(list: List<OtaUpgradeInfo>){
this.data = list
notifyDataSetChanged()
}
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): DownloadStatusHolder {
val view = LayoutInflater.from(parent.context)
.inflate(R.layout.item_ota_download_status, parent, false)
return DownloadStatusHolder(view)
}
override fun onBindViewHolder(holder: DownloadStatusHolder, position: Int) {
data?.let {
val otaUpgradeInfo = it[position]
holder.pbDownloadProgress.progress = (otaUpgradeInfo.cur_size*100/otaUpgradeInfo.total_size).toInt()
// 0:默认(未开始), 1:下载中, 2:下载完成, 3:升级完成, 4:升级失败
holder.tvDownloadStatus.text = when (otaUpgradeInfo.status) {
1 -> {
"下载中"
}
2 -> {
"下载完成"
}
3 -> {
"升级完成"
}
4 -> {
"升级失败"
}
else -> {
"默认(未开始)"
}
}
}
}
override fun getItemCount() = data?.size ?: 0
class DownloadStatusHolder(itemView: View) : RecyclerView.ViewHolder(itemView){
var pbDownloadProgress: ProgressBar = itemView.findViewById(R.id.pbDownloadProgress)
var tvDownloadStatus: TextView = itemView.findViewById(R.id.tvDownloadStatus)
}
}

View File

@@ -300,6 +300,14 @@ class ColdStartView @JvmOverloads constructor(
Log.i(TAG,"节点自上报冷启动状态="+it.eventStatus)
Log.i(TAG,"旧冷启动状态="+it.processStatus)
Log.i(TAG,"旧冷启动超时原因="+it.processTimeoutReason)
Log.i(TAG,"硬件故障Node数量="+it.hardwareNodeCount)
it.hardwareNodeList.forEach {startFlt->
Log.i(TAG,"硬件故障 startFlt.fltId="+ startFlt.fltId)
}
Log.i(TAG,"其他故障数量="+it.otherFltsCount)
it.otherFltsList.forEach {startFlt->
Log.i(TAG,"其他故障 startFlt.fltId="+startFlt.fltId)
}
ThreadUtils.runOnUiThread {
tvColdStartContent.text = getColdStartEventStatus(it.eventStatus)
if(it.eventStatus == SsmInfo.CSState.COLD_START_READY){
@@ -327,6 +335,12 @@ class ColdStartView @JvmOverloads constructor(
val nodeInfo = ColdStartNodeInfo(node.nodeName,node.eventCode,getColdStartNodeStatus(node.status),node.desc)
nodeList.add(nodeInfo)
}
Log.i(TAG,"nodeName="+node.nodeName+" status="+node.status+" desc="+node.desc+" eventCode="+node.eventCode)
Log.i(TAG,"node.haveFltCount="+node.haveFltCount)
node.haveFltList.forEach {str->
Log.i(TAG, "故障码=$str")
}
}
it.nodeList.forEach {node->
if(node.status == SsmInfo.NodeStatus.NODE_STARTING){

View File

@@ -0,0 +1,16 @@
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
xmlns:app="http://schemas.android.com/apk/res-auto">
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/rvDownloadStatus"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent"
/>
</androidx.constraintlayout.widget.ConstraintLayout>

View File

@@ -0,0 +1,96 @@
<?xml version="1.0" encoding="utf-8"?>
<com.mogo.eagle.core.widget.RoundConstraintLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="@dimen/dp_900"
android:layout_height="@dimen/dp_620"
android:background="@drawable/bg_bone_dialog"
app:roundLayoutRadius="@dimen/dp_50"
>
<TextView
android:id="@+id/tv_upgrade_title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent"
android:text="@string/application_upgrade"
android:textSize="56dp"
android:textColor="#FFFFFFFF"
android:layout_marginTop="50dp"
/>
<TextView
android:id="@+id/tv_upgrade_countdown"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:layout_constraintTop_toTopOf="@id/tv_upgrade_title"
app:layout_constraintBottom_toBottomOf="@id/tv_upgrade_title"
app:layout_constraintRight_toRightOf="parent"
android:layout_marginEnd="@dimen/dp_50"
android:textSize="@dimen/sp_30"
android:textColor="@color/white"
/>
<TextView
android:id="@+id/tv_upgrade_content"
android:layout_width="0dp"
android:layout_height="wrap_content"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toBottomOf="@id/tv_upgrade_title"
android:text="@string/application_upgrade_confirm"
android:textColor="#FFFFFFFF"
android:textSize="43dp"
android:gravity="start"
android:layout_marginStart="50dp"
android:layout_marginEnd="50dp"
android:layout_marginTop="50dp"
/>
<TextView
android:id="@+id/tv_upgrade_tip"
android:layout_width="0dp"
android:layout_height="wrap_content"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toBottomOf="@id/tv_upgrade_content"
app:layout_constraintBottom_toTopOf="@id/view_horizontal_line"
android:text="@string/application_upgrade_tips"
android:textColor="#FFFF4B1F"
android:textSize="36dp"
android:layout_marginStart="50dp"
android:layout_marginEnd="50dp"
android:layout_marginTop="30dp"
/>
<TextView
android:id="@+id/tv_upgrade_now"
android:layout_width="@dimen/dp_356"
android:layout_height="@dimen/dp_120"
android:gravity="center"
android:text="@string/ota_upgrade_now"
android:background="@drawable/bg_dialog_btn"
android:textColor="@color/color_2EACFF"
android:textSize="@dimen/dp_40"
android:layout_marginStart="@dimen/dp_65"
android:layout_marginBottom="@dimen/dp_62"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toLeftOf="parent" />
<TextView
android:id="@+id/tv_upgrade_later"
android:layout_width="@dimen/dp_356"
android:layout_height="@dimen/dp_120"
android:gravity="center"
android:text="@string/ota_upgrade_later"
android:textColor="@color/white"
android:textSize="@dimen/dp_40"
android:background="@drawable/bg_dialog_btn"
app:layout_constraintBottom_toBottomOf="parent"
android:layout_marginEnd="@dimen/dp_65"
android:layout_marginBottom="@dimen/dp_62"
app:layout_constraintRight_toRightOf="parent"/>
</com.mogo.eagle.core.widget.RoundConstraintLayout>

View File

@@ -141,6 +141,15 @@
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<com.mogo.eagle.core.function.hmi.ui.tools.OTAUpgradeTipView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
android:layout_marginTop="@dimen/dp_39"
/>
<!-- 事件弹框 -->
<com.mogo.eagle.core.function.hmi.ui.v2n.RoadV2NEventWindowView
android:id="@+id/roadV2NEventWindowView"

View File

@@ -0,0 +1,13 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="wrap_content"
android:layout_height="wrap_content">
<Button
android:id="@+id/btn_upgrade"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="OTA升级"
/>
</LinearLayout>

View File

@@ -248,4 +248,8 @@
<string name="cold_start_process">冷启动进度条</string>
<!--OTA升级-->
<string name="ota_upgrade_now">立即升级</string>
<string name="ota_upgrade_later">稍后升级</string>
</resources>

View File

@@ -1,7 +1,5 @@
package com.mogo.eagle.core.data.deva.coldstart
import android.os.CountDownTimer
/**
* 冷启动关键节点实体类
* @param nodeName 节点名称

View File

@@ -0,0 +1,20 @@
package com.mogo.eagle.core.data.deva.ota
/**
* OTA升级详情
* @param token 任务唯一标识
* @param status 状态 0:默认(未开始), 1:下载中, 2:下载完成, 3:升级完成, 4:升级失败
* @param fail_reason 升级失败原因
* @param upgrade_reason 升级原因
* @param task_id task_id
* @param task_item_id task_item_id
* @param ota_type ota type 1:镜像, 2:固件, 3:地图, 4:配置文件
* @param product_name 升级项目名称
* @param need_restart 升级是否需要重启
* @param is_delay 是否是延时升级
* @param cur_size 当前已下载文件大小
* @param total_size 下载文件总大小
*/
data class OtaUpgradeInfo(var token: String,var status: Int,var fail_reason: String,var upgrade_reason: String,
var task_id: Int,var task_item_id: Int,var ota_type: Int,var product_name: String,
var need_restart: Boolean,var is_delay: Boolean,var cur_size:Double,var total_size: Double)

View File

@@ -17,6 +17,7 @@ import com.zhjt.mogo.adas.data.sweeper.task.s_r.SweeperTaskSuspendResume.Suspend
import com.zhjt.mogo.adas.data.sweeper.task.stop.SweeperTaskStop.StopTaskResp
import mogo.telematics.pad.MessagePad
import mogo.yycp.paralleldriving.protocol.ParallelDrivingRequest
import system_master.SsmInfo
/**
* @author xiaoyuzhou
@@ -712,4 +713,28 @@ interface IMoGoAutopilotControlProvider : IMoGoFunctionServerProvider {
*/
fun sendSimulationWireFailure(isTrigger: Boolean): Boolean
/**
* SSM发送OTA升级提示请求响应
*
* @param token 域控发送OTA升级请求中的Token {@link SsmInfo.OtaDownloadRequest#getOtaToken()}
* @param ifUpgrade {@link SsmInfo.IfUpgrade#IMMEDIATELY}:立即
* {@link SsmInfo.IfUpgrade#DELAY}:推迟
*/
fun sendSsmFuncOtaDownloadResponse(token: String,ifUpgrade: SsmInfo.IfUpgrade): Boolean
/**
* 查询OTA状态
*
* @param token 域控发送OTA升级请求中的Token {@link SsmInfo.OtaDownloadRequest#getOtaToken()}
* 如果没有可以传null或""
*/
fun sendSsmFuncOtaStatusQuery(token: String): Boolean
/**
* 人工接管时获取前方和后方摄像头数据
* 一次请求域控回调次两次摄像头数据 根据{@link MessagePad.CaptureImgOnTakeOver#getUuid()}进行区分是否是哪次请求
* 例如下发uuid = 1 域控正常会回调两次响应接口 两次的uuid都是1通过isFront区分是前方还是后方摄像头
* 域控响应接口{@link OnAdasListener#onCaptureImgOnTakeOver(MessagePad.Header, boolean, MessagePad.CaptureImgOnTakeOver)}
*/
fun sendCaptureImgReqOnTakeOver(uuid: Long): Boolean
}

View File

@@ -0,0 +1,17 @@
package com.mogo.eagle.core.function.api.devatools
import mogo.telematics.pad.MessagePad
/**
* 接管时前方和后方摄像头数据请求响应回调
*/
interface ICaptureImgListener {
/**
* 接管时前方和后方摄像头数据请求的响应
* @param isFront true前方摄像头 false后方摄像头
* @param data 数据
*/
fun onCaptureImgOnTakeOver(isFront: Boolean, data: MessagePad.CaptureImgOnTakeOver){}
}

View File

@@ -0,0 +1,31 @@
package com.mogo.eagle.core.function.api.devatools
import system_master.SsmInfo
/**
* OTA升级接口
*/
interface IOTAListener {
/**
* SSM发送OTA升级提示请求
* @param request SSM发送OTA升级提示内容
*/
fun onOtaDownloadRequest(request: SsmInfo.OtaDownloadRequest){}
// /**
// * SSM上报OTA下载进度, 开始升级后定频上报
// * @param progress 下载进度
// */
// fun onOtaLoadingProgress(progress: SsmInfo.OtaLoadingProgess){}
/**
* SSM上报OTA状态和查询OTA状态
* 冷启动状态变更上报以及查询状态
* 如果是查询到的结果,{@link SsmInfo.OtaStatus#getOtaInfo()}
* 中的{@link SsmInfo.OtaDownloadRequest#getOtaToken()}==""表示不存在升级任务
* @param status 冷启动状态变更上报以及查询状态
*/
fun onOtaStatus(status: SsmInfo.OtaStatus){}
}

View File

@@ -7,6 +7,7 @@ import com.mogo.eagle.core.data.biz.dispatch.DispatchAdasAutoPilotLocReceiverBea
import com.mogo.eagle.core.data.biz.notice.NoticeNormalData
import com.mogo.eagle.core.data.biz.notice.NoticeTrafficStylePushData
import com.mogo.eagle.core.data.deva.bindingcar.IPCUpgradeStateInfo
import com.mogo.eagle.core.data.deva.ota.OtaUpgradeInfo
import com.mogo.eagle.core.data.enums.WarningDirectionEnum
import com.mogo.eagle.core.data.map.Infrastructure
import com.mogo.eagle.core.function.api.hmi.xiaozhi.event.Event
@@ -322,4 +323,20 @@ interface IMoGoHmiProvider :IProvider{
* 展示冷启动进度条
*/
fun showColdStartProcessView()
/**
* 展示OTA升级弹窗
*/
fun showOTAUpgradeDialog()
/**
* 展示OTA升级下载状态弹窗
*/
fun showOTADownloadStatusDialog(list: List<OtaUpgradeInfo>)
/**
* 展示OTA升级提示
* @param visible 设置是否可见
*/
fun showOTAUpgradeTipView(visible: Boolean)
}

View File

@@ -38,6 +38,7 @@ import com.zhjt.service.chain.ChainLog
import com.zhjt.service_biz.BizConfig
import kotlinx.coroutines.launch
import mogo.yycp.paralleldriving.protocol.ParallelDrivingRequest
import system_master.SsmInfo
import java.lang.StringBuilder
import kotlin.random.Random
@@ -1069,4 +1070,33 @@ object CallerAutoPilotControlManager {
return providerApi?.sendSimulationWireFailure(isTrigger)?:false
}
/**
* SSM发送OTA升级提示请求响应
* @param token 域控发送OTA升级请求中的Token {@link SsmInfo.OtaDownloadRequest#getOtaToken()}
* @param ifUpgrade {@link SsmInfo.IfUpgrade#IMMEDIATELY}:立即
* {@link SsmInfo.IfUpgrade#DELAY}:推迟
*/
fun sendSsmFuncOtaDownloadResponse(token: String,ifUpgrade: SsmInfo.IfUpgrade): Boolean{
return providerApi?.sendSsmFuncOtaDownloadResponse(token,ifUpgrade)?:false
}
/**
* 查询OTA状态
* @param token 域控发送OTA升级请求中的Token {@link SsmInfo.OtaDownloadRequest#getOtaToken()}
* 如果没有可以传null或""
*/
fun sendSsmFuncOtaStatusQuery(token: String): Boolean{
return providerApi?.sendSsmFuncOtaStatusQuery(token)?:false
}
/**
* 人工接管时获取前方和后方摄像头数据
* 一次请求域控回调次两次摄像头数据 根据{@link MessagePad.CaptureImgOnTakeOver#getUuid()}进行区分是否是哪次请求
* 例如下发uuid = 1 域控正常会回调两次响应接口 两次的uuid都是1通过isFront区分是前方还是后方摄像头
* 域控响应接口{@link OnAdasListener#onCaptureImgOnTakeOver(MessagePad.Header, boolean, MessagePad.CaptureImgOnTakeOver)}
*/
fun sendCaptureImgReqOnTakeOver(uuid: Long): Boolean{
return providerApi?.sendCaptureImgReqOnTakeOver(uuid)?:false
}
}

View File

@@ -0,0 +1,22 @@
package com.mogo.eagle.core.function.call.devatools
import com.mogo.eagle.core.function.api.devatools.ICaptureImgListener
import com.mogo.eagle.core.function.call.base.CallerBase
import mogo.telematics.pad.MessagePad
/**
* 接管时前方和后方摄像头数据请求响应回调管理
*/
object CallerCaptureImgManager: CallerBase<ICaptureImgListener>() {
/**
* 接管时前方和后方摄像头数据请求的响应
*/
fun invokeCaptureImgOnTakeOver(isFront: Boolean, data: MessagePad.CaptureImgOnTakeOver){
M_LISTENERS.forEach{
val listener = it.value
listener.onCaptureImgOnTakeOver(isFront, data)
}
}
}

View File

@@ -0,0 +1,48 @@
package com.mogo.eagle.core.function.call.devatools
import com.mogo.eagle.core.function.api.devatools.IOTAListener
import com.mogo.eagle.core.function.call.base.CallerBase
import system_master.SsmInfo
/**
* OTA升级接口回调管理
*/
object CallerOTAManager: CallerBase<IOTAListener>() {
/**
* SSM发送OTA升级提示请求
* @param request SSM发送OTA升级提示内容
*/
fun invokeOtaDownloadRequest(request: SsmInfo.OtaDownloadRequest){
M_LISTENERS.forEach {
val listener = it.value
listener.onOtaDownloadRequest(request)
}
}
// /**
// * SSM上报OTA下载进度, 开始升级后定频上报
// * @param progress 下载进度
// */
// fun invokeOtaLoadingProgress(progress: SsmInfo.OtaLoadingProgess){
// M_LISTENERS.forEach {
// val listener = it.value
// listener.onOtaLoadingProgress(progress)
// }
// }
/**
* SSM上报OTA状态和查询OTA状态
* 冷启动状态变更上报以及查询状态
* 如果是查询到的结果,{@link SsmInfo.OtaStatus#getOtaInfo()}
* 中的{@link SsmInfo.OtaDownloadRequest#getOtaToken()}==""表示不存在升级任务
* @param status 冷启动状态变更上报以及查询状态
*/
fun invokeOtaStatus(status: SsmInfo.OtaStatus){
M_LISTENERS.forEach {
val listener = it.value
listener.onOtaStatus(status)
}
}
}

View File

@@ -10,6 +10,7 @@ import com.mogo.eagle.core.data.biz.notice.NoticeNormalData
import com.mogo.eagle.core.data.biz.notice.NoticeTrafficStylePushData
import com.mogo.eagle.core.data.constants.MogoServicePaths
import com.mogo.eagle.core.data.deva.bindingcar.IPCUpgradeStateInfo
import com.mogo.eagle.core.data.deva.ota.OtaUpgradeInfo
import com.mogo.eagle.core.data.enums.WarningDirectionEnum
import com.mogo.eagle.core.data.enums.WarningDirectionEnum.ALERT_WARNING_NON
import com.mogo.eagle.core.data.map.Infrastructure
@@ -472,4 +473,26 @@ object CallerHmiManager {
hmiProviderApi?.showColdStartProcessView()
}
/**
* 展示OTA升级弹窗
*/
fun showOTAUpgradeDialog(){
hmiProviderApi?.showOTAUpgradeDialog()
}
/**
* 展示OTA升级下载状态弹窗
*/
fun showOTADownloadStatusDialog(list: List<OtaUpgradeInfo>){
hmiProviderApi?.showOTADownloadStatusDialog(list)
}
/**
* 展示OTA升级提示
* @param visible 设置是否可见
*/
fun showOTAUpgradeTipView(visible: Boolean){
hmiProviderApi?.showOTAUpgradeTipView(visible)
}
}

View File

@@ -95,6 +95,8 @@ public enum MessageType {
TYPE_RECEIVE_SSM_FUNC_MSG(MessagePad.MessageType.MsgTypeSSMFuncMsg, "SSM功能响应"),
TYPE_SEND_SSM_FUNC_STATUS_QUERY(MessagePad.MessageType.MsgTypeSSMFuncStatusQuery, "SSM功能状态查询"),
TYPE_RECEIVE_SSM_FUNC_STATUS_QUERY(MessagePad.MessageType.MsgTypeSSMFuncStatusQuery, "SSM功能状态响应"),
TYPE_SEND_CAPTURE_IMG_REQ_ON_TAKE_OVER(MessagePad.MessageType.MsgTypeCaptureImgReqOnTakeOver, "接管时摄像头数据请求"),
//TODO 透传原始pb文件中不存在以下type。由于Java中无法强转,所以在mogo-adas-data/message_pad.proto中放开注释
TYPE_RECEIVE_PLANNING_DECISION_STATE(MessagePad.MessageType.MsgTypePlanningDecisionState, "Planning决策状态"),
TYPE_RECEIVE_SWEEPER_TASK_INDEX_DATA(MessagePad.MessageType.MsgTypeSweeperTaskIndexData, "清扫车指标数据"),
@@ -106,6 +108,11 @@ public enum MessageType {
TYPE_RECEIVE_CAMERA_CALIB_CHECK_DATA120_BACK(MessagePad.MessageType.MsgTypeCameraCalibCheckData120Back, "相机标定检查视频120后"),
TYPE_RECEIVE_CAMERA_CALIB_CHECK_DATA120_LEFT(MessagePad.MessageType.MsgTypeCameraCalibCheckData120Left, "相机标定检查视频120左"),
TYPE_RECEIVE_CAMERA_CALIB_CHECK_DATA120_RIGHT(MessagePad.MessageType.MsgTypeCameraCalibCheckData120Right, "相机标定检查视频120右"),
TYPE_RECEIVE_CAPTURE_FRONT_IMG_ON_TAKE_OVER(MessagePad.MessageType.MsgTypeCaptureFrontImgOnTakeOver, "人工接管时给PAD发前摄像头数据响应"),
TYPE_RECEIVE_CAPTURE_BACK_IMG_ON_TAKE_OVER(MessagePad.MessageType.MsgTypeCaptureBackImgOnTakeOver, "人工接管时给PAD发后摄像头数据响应"),
;

View File

@@ -24,6 +24,8 @@ enum MessageType
MsgTypeCameraCalibCheckData120Back = 0x01004; //相机标定检查视频, 10hz, jpeg. image_raw_back
MsgTypeCameraCalibCheckData120Left = 0x01005; //相机标定检查视频, 10hz, jpeg. image_raw_left
MsgTypeCameraCalibCheckData120Right = 0x01006; //相机标定检查视频, 10hz, jpeg. image_raw_right
MsgTypeCaptureFrontImgOnTakeOver = 0x01007;//人工接管时给PAD发前摄像头数据响应
MsgTypeCaptureBackImgOnTakeOver = 0x01008;//人工接管时给PAD发后摄像头数据响应
MsgTypeTrajectory = 0x10000; //局部轨迹,车前引导线 定频10hz
MsgTypeTrackedObjects = 0x10001; //障碍物信息 定频10hz
@@ -97,6 +99,7 @@ enum MessageType
MsgTypePowerUnit = 0x1012e;//电源模块通信
MsgTypeSSMFuncMsg = 0x1012f;//SSM功能(上下行)
MsgTypeSSMFuncStatusQuery = 0x10130;//SSM功能状态查询及返回(上下行)
MsgTypeCaptureImgReqOnTakeOver = 0x10132;//人工接管时PAD请求前后摄像头数据
}
message Header
@@ -940,4 +943,11 @@ message CollisionReport
double longitude = 1;
double latitude = 2;
double timestamp = 3;//时间, 单位:秒
}
//message definition for MsgTypeCaptureImgReqOnTakeOver MsgTypeCaptureFrontImgOnTakeOver MsgTypeCaptureBackImgOnTakeOver
message CaptureImgOnTakeOver
{
uint64 uuid = 1;
bytes data = 2;
}

View File

@@ -21,7 +21,7 @@ enum AgentState {
enum ModeState {
MODE_STOP_UNREADY = 0; //停止模式-未就绪
MODE_STOP_READY = 1; //运行模式-就绪 (所有节点关闭)
MODE_STOP_READY = 1; //停止模式-就绪 (所有节点关闭)
MODE_RUN_UNREADY = 2; //运行模式-未就绪
MODE_RUN_READY = 3; //运行模式-就绪 (所有节点启动)
MODE_IDLE_UNREADY = 4; //空闲模式-未就绪
@@ -46,7 +46,7 @@ message SsmStatusInf {
optional string auto_pilot_unready_reason = 8; //自动驾驶状态未就绪原因描述
optional string remote_pilot_unready_reason = 9; //平行驾驶状态未就绪原因描述
repeated HealthInfo health_info=10; // 健康检查状态信息
optional uint64 cur_used_lineid = 20 [default = 0]; //0当前无可用轨迹需要下单other: 可用轨迹id
optional string hd_map_ver = 21; //高精地图版本
optional string slam_map_ver = 22; //slam地图版本
@@ -58,7 +58,7 @@ enum MessageType {
NOTIFICATION = 0; // ssm发送通知 msg:Notification
OTA_DOWNLOAD_REQUEST = 1; // ssm发送OTA升级提示请求 todo
OTA_DOWNLOAD_RESPONSE = 2; // pad下发OTA升级提示响应 todo
OTA_LOADING_PROGRESS = 3; // ssm上报OTA下载进度, 开始升级后定频上报 todo
OTA_LOADING_PROGRESS = 3; // ssm上报OTA下载进度, 开始升级后定频上报 todo 废弃 使用OTA_STATUS 定频推送的进度来为下载时是0.1Hz下载时是1Hz此接口无法表示多任务所以废弃
OTA_STATUS = 4; // ssm 上报OTA状态 todo
OTA_STATUS_QUERY = 5; // pad查询OTA状态 req:OtaToken resp:OtaStatus
COLD_START_STATUS_REPORT = 6; // 冷启动状态上报 msg:ColdStartState
@@ -91,13 +91,41 @@ enum OtaType {
MAP = 3;
PROFILE = 4;
}
//product_name中的数据
//[{
// "token": "12,34,56",
// "status": 0,// 与 UpgradeStatus 中的值相同
// "fail_reason": "",
// "upgrade_reason": "",
// "task_id": 0,
// "task_item_id": 0,
// "ota_type": 1,
// "product_name": "",
// "need_restart": false,
// "is_delay": false,
// "cur_size": 0,
// "total_size": 0
//}, {
// "token": "34,56,78",
// "status": 0,
// "fail_reason": "",
// "upgrade_reason": "",
// "task_id": 0,
// "task_item_id": 0,
// "ota_type": 1,
// "product_name": "",
// "need_restart": false,
// "is_delay": false,
// "cur_size": 0,
// "total_size": 0
//}]
message OtaDownloadRequest {
required string ota_token = 1; // ota token 唯一标识
required OtaType ota_type = 2; // ota type 1:镜像, 2:固件, 3:地图, 4:配置文件
required bool need_restart = 3; // 是否需要重启 True:需要, False:不需要
required OtaType ota_type = 2; // ota type 1:镜像, 2:固件, 3:地图, 4:配置文件 todo 废弃使用product_name json中的 ota_type
required bool need_restart = 3; // 是否需要重启 True:需要, False:不需要 todo 废弃使用product_name json中的 need_restart
required string product_name = 4; // 制品名称
optional double size = 5; // 文件大小 Mb
optional double size = 5; // 文件大小 Mb todo 废弃使用product_name json中的 cur_size total_size
}
enum IfUpgrade {
@@ -130,8 +158,8 @@ enum UpgradeStatus {
message OtaStatus {
required OtaDownloadRequest ota_info = 1; // 升级信息
required UpgradeStatus status = 2; // 状态 0:默认(未开始), 1:下载中, 2:下载完成, 3:升级完成, 4:升级失败
optional string reason = 3; // 失败原因
required UpgradeStatus status = 2; // 状态 0:默认(未开始), 1:下载中, 2:下载完成, 3:升级完成, 4:升级失败 todo 废弃使用product_name json中的 status
optional string reason = 3; // 失败原因 todo 废弃 todo 废弃使用product_name json中的 fail_reason
}
enum CSState {
@@ -153,7 +181,12 @@ message ColdStartNode {
required string node_name = 1; //节点名称
required string event_code = 2; //上报事件
required NodeStatus status = 3; //0:启动中, 1:启动成功, 2:启动失败, 3:启动超时
required string desc = 4; //事件描述
required string desc = 4; //事件描述
repeated string have_flt = 5; //故障码
}
message StartFlt {
required string flt_id = 1; //故障id
}
message ColdStartState {
@@ -161,6 +194,8 @@ message ColdStartState {
required CSState event_status = 2; //节点自上报冷启动状态
repeated ColdStartNode node = 3; //冷启动关键节点信息
optional string process_timeout_reason = 4; //旧冷启动超时原因
repeated StartFlt hardware_node = 5; //硬件关键节点故障信息
repeated StartFlt other_flts = 6; //其他关键节点故障信息
}
message AutoPilotInfo {

View File

@@ -2970,6 +2970,42 @@ public class AdasChannel implements IAdasNetCommApi, FpgaSocket.IWebSocketConnec
return sendPBMessage(messageType, req.toByteArray(), messageId);
}
/**
* SSM发送OTA升级提示请求响应
*
* @param token 域控发送OTA升级请求中的Token {@link SsmInfo.OtaDownloadRequest#getOtaToken()}
* @param ifUpgrade {@link SsmInfo.IfUpgrade#IMMEDIATELY}:立即
* {@link SsmInfo.IfUpgrade#DELAY}:推迟
* @return 消息是否添加到WS消息发送队列返回值为非0的正整数时表示下发消息的消息ID
* * >=0表示添加到WS发送消息队列
* * =0表示乘客屏模式添加到WS发送消息队列
* * -1L添加到WS发送消息队列失败
*/
@Override
public long sendSsmFuncOtaDownloadResponse(@NonNull String token, @NonNull SsmInfo.IfUpgrade ifUpgrade) {
SsmInfo.OtaDownloadResponse.Builder builder = SsmInfo.OtaDownloadResponse.newBuilder();
builder.setToken(TextUtils.isEmpty(token) ? "" : token);
builder.setIfUpgrade(ifUpgrade);
return sendSsmFuncMsg(false, system_master.SsmInfo.MessageType.OTA_DOWNLOAD_RESPONSE, builder.build().toByteString());
}
/**
* 查询OTA状态
*
* @param token 域控发送OTA升级请求中的Token {@link SsmInfo.OtaDownloadRequest#getOtaToken()}
* 如果没有可以传null或""
* @return 消息是否添加到WS消息发送队列返回值为非0的正整数时表示下发消息的消息ID
* * >=0表示添加到WS发送消息队列
* * =0表示乘客屏模式添加到WS发送消息队列
* * -1L添加到WS发送消息队列失败
*/
@Override
public long sendSsmFuncOtaStatusQuery(@Nullable String token) {
SsmInfo.OtaToken.Builder builder = SsmInfo.OtaToken.newBuilder();
builder.setToken(TextUtils.isEmpty(token) ? "" : token);
return sendSsmFuncMsg(true, system_master.SsmInfo.MessageType.OTA_STATUS_QUERY, builder.build().toByteString());
}
/**
* 查询冷启动状态
*
@@ -3011,6 +3047,26 @@ public class AdasChannel implements IAdasNetCommApi, FpgaSocket.IWebSocketConnec
return sendSsmFuncMsg(true, system_master.SsmInfo.MessageType.STATION_STATUS_QUERY, SsmInfo.OrderInfo.newBuilder().setOrderId(orderId).build().toByteString());
}
/**
* 人工接管时获取前方和后方摄像头数据
* 一次请求域控回调次两次摄像头数据 根据{@link MessagePad.CaptureImgOnTakeOver#getUuid()}进行区分是否是哪次请求
* 例如下发uuid = 1 域控正常会回调两次响应接口 两次的uuid都是1通过isFront区分是前方还是后方摄像头
* 域控响应接口{@link OnAdasListener#onCaptureImgOnTakeOver(MessagePad.Header, boolean, MessagePad.CaptureImgOnTakeOver)}
*
* @param uuid 消息id域控回调时会回复对应的值
* @return 消息是否添加到WS消息发送队列返回值为非0的正整数时表示下发消息的消息ID
* * >=0表示添加到WS发送消息队列
* * =0表示乘客屏模式添加到WS发送消息队列
* * -1L添加到WS发送消息队列失败
*/
@Override
public long sendCaptureImgReqOnTakeOver(long uuid) {
MessagePad.CaptureImgOnTakeOver.Builder builder = MessagePad.CaptureImgOnTakeOver.newBuilder()
.setUuid(uuid);
MessagePad.CaptureImgOnTakeOver req = builder.build();
return sendPBMessage(MessageType.TYPE_SEND_CAPTURE_IMG_REQ_ON_TAKE_OVER, req.toByteArray());
}
}

View File

@@ -42,6 +42,7 @@ import chassis.Chassis;
import chassis.SpecialVehicleTaskCmdOuterClass;
import mogo.telematics.pad.MessagePad;
import mogo.yycp.paralleldriving.protocol.ParallelDrivingRequest;
import system_master.SsmInfo;
/**
* @ProjectName: lib-adas-fpga
@@ -1782,6 +1783,37 @@ public class AdasManager implements IAdasNetCommApi {
return mChannel == null ? -1L : mChannel.sendPowerUnitReset();
}
/**
* SSM发送OTA升级提示请求响应
*
* @param token 域控发送OTA升级请求中的Token {@link SsmInfo.OtaDownloadRequest#getOtaToken()}
* @param ifUpgrade {@link SsmInfo.IfUpgrade#IMMEDIATELY}:立即
* {@link SsmInfo.IfUpgrade#DELAY}:推迟
* @return 消息是否添加到WS消息发送队列返回值为非0的正整数时表示下发消息的消息ID
* * >=0表示添加到WS发送消息队列
* * =0表示乘客屏模式添加到WS发送消息队列
* * -1L添加到WS发送消息队列失败
*/
@Override
public long sendSsmFuncOtaDownloadResponse(@NonNull String token, @NonNull SsmInfo.IfUpgrade ifUpgrade) {
return mChannel == null ? -1L : mChannel.sendSsmFuncOtaDownloadResponse(token, ifUpgrade);
}
/**
* 查询OTA状态
*
* @param token 域控发送OTA升级请求中的Token {@link SsmInfo.OtaDownloadRequest#getOtaToken()}
* 如果没有可以传null或""
* @return 消息是否添加到WS消息发送队列返回值为非0的正整数时表示下发消息的消息ID
* * >=0表示添加到WS发送消息队列
* * =0表示乘客屏模式添加到WS发送消息队列
* * -1L添加到WS发送消息队列失败
*/
@Override
public long sendSsmFuncOtaStatusQuery(@Nullable String token) {
return mChannel == null ? -1L : mChannel.sendSsmFuncOtaStatusQuery(token);
}
/**
* 查询冷启动状态
*
@@ -1823,6 +1855,23 @@ public class AdasManager implements IAdasNetCommApi {
return mChannel == null ? -1L : mChannel.sendSsmFuncQueryAutoPilotStation(orderId);
}
/**
* 人工接管时获取前方和后方摄像头数据
* 一次请求域控回调次两次摄像头数据 根据{@link MessagePad.CaptureImgOnTakeOver#getUuid()}进行区分是否是哪次请求
* 例如下发uuid = 1 域控正常会回调两次响应接口 两次的uuid都是1通过isFront区分是前方还是后方摄像头
* 域控响应接口{@link OnAdasListener#onCaptureImgOnTakeOver(MessagePad.Header, boolean, MessagePad.CaptureImgOnTakeOver)}
*
* @param uuid 消息id域控回调时会回复对应的值
* @return 消息是否添加到WS消息发送队列返回值为非0的正整数时表示下发消息的消息ID
* * >=0表示添加到WS发送消息队列
* * =0表示乘客屏模式添加到WS发送消息队列
* * -1L添加到WS发送消息队列失败
*/
@Override
public long sendCaptureImgReqOnTakeOver(long uuid) {
return mChannel == null ? -1L : mChannel.sendCaptureImgReqOnTakeOver(uuid);
}
/**
* 查询节点状态
*

View File

@@ -26,6 +26,7 @@ import bag_manager.BagManagerOuterClass;
import chassis.SpecialVehicleTaskCmdOuterClass;
import mogo.telematics.pad.MessagePad;
import mogo.yycp.paralleldriving.protocol.ParallelDrivingRequest;
import system_master.SsmInfo;
/**
* @author nie yunlong
@@ -1286,6 +1287,31 @@ public interface IAdasNetCommApi {
*/
long sendPowerUnitReset();
/**
* SSM发送OTA升级提示请求响应
*
* @param token 域控发送OTA升级请求中的Token {@link SsmInfo.OtaDownloadRequest#getOtaToken()}
* @param ifUpgrade {@link SsmInfo.IfUpgrade#IMMEDIATELY}:立即
* {@link SsmInfo.IfUpgrade#DELAY}:推迟
* @return 消息是否添加到WS消息发送队列返回值为非0的正整数时表示下发消息的消息ID
* * >=0表示添加到WS发送消息队列
* * =0表示乘客屏模式添加到WS发送消息队列
* * -1L添加到WS发送消息队列失败
*/
long sendSsmFuncOtaDownloadResponse(@NonNull String token, @NonNull SsmInfo.IfUpgrade ifUpgrade);
/**
* 查询OTA状态
*
* @param token 域控发送OTA升级请求中的Token {@link SsmInfo.OtaDownloadRequest#getOtaToken()}
* 如果没有可以传null或""
* @return 消息是否添加到WS消息发送队列返回值为非0的正整数时表示下发消息的消息ID
* * >=0表示添加到WS发送消息队列
* * =0表示乘客屏模式添加到WS发送消息队列
* * -1L添加到WS发送消息队列失败
*/
long sendSsmFuncOtaStatusQuery(@Nullable String token);
/**
* 查询冷启动状态
*
@@ -1318,6 +1344,20 @@ public interface IAdasNetCommApi {
*/
long sendSsmFuncQueryAutoPilotStation(@NonNull String orderId);
/**
* 人工接管时获取前方和后方摄像头数据
* 一次请求域控回调次两次摄像头数据 根据{@link MessagePad.CaptureImgOnTakeOver#getUuid()}进行区分是否是哪次请求
* 例如下发uuid = 1 域控正常会回调两次响应接口 两次的uuid都是1通过isFront区分是前方还是后方摄像头
* 域控响应接口{@link OnAdasListener#onCaptureImgOnTakeOver(MessagePad.Header, boolean, MessagePad.CaptureImgOnTakeOver)}
*
* @param uuid 消息id域控回调时会回复对应的值
* @return 消息是否添加到WS消息发送队列返回值为非0的正整数时表示下发消息的消息ID
* * >=0表示添加到WS发送消息队列
* * =0表示乘客屏模式添加到WS发送消息队列
* * -1L添加到WS发送消息队列失败
*/
long sendCaptureImgReqOnTakeOver(long uuid);
// TODO 需求暂停 待讨论
// boolean getRoutes();

View File

@@ -207,13 +207,47 @@ public interface OnAdasListener {
@Deprecated
void onWarn(MessagePad.Header header, MessagePad.Warn warn);
/**
* SSM发送OTA升级提示请求
*
* @param header 头
* @param token PadSsmMsg唯一消息ID
* @param timestamp 消息发送时间 单位:毫秒
* @param request 数据 null表示 PadSsmMsg中的消息体为null
*/
void onOtaDownloadRequest(MessagePad.Header header, long token, long timestamp, @Nullable SsmInfo.OtaDownloadRequest request);
// /**
// * SSM上报OTA下载进度, 开始升级后定频上报
// *
// * @param header 头
// * @param token PadSsmMsg唯一消息ID
// * @param timestamp 消息发送时间 单位:毫秒
// * @param progress 数据 null表示 PadSsmMsg中的消息体为null
// */
// void onOtaLoadingProgress(MessagePad.Header header, long token, long timestamp, @Nullable SsmInfo.OtaLoadingProgess progress);
/**
* SSM上报OTA状态和查询OTA状态
* 冷启动状态变更上报以及查询状态
* 如果是查询到的结果,{@link SsmInfo.OtaStatus#getOtaInfo()}中的{@link SsmInfo.OtaDownloadRequest#getOtaToken()}==""表示不存在升级任务
*
* @param header 头
* @param token PadSsmMsg唯一消息ID
* @param timestamp 消息发送时间 单位:毫秒
* @param isQuery 是否是查询 ture查询响应的结果 false表示状态变动域控主动推送
* @param status 数据 null表示 PadSsmMsg中的消息体为null
*/
void onOtaStatus(MessagePad.Header header, long token, long timestamp, boolean isQuery, @Nullable SsmInfo.OtaStatus status);
/**
* 冷启动状态变更上报以及查询状态
*
* @param header 头
* @param token 唯一消息ID
* @param token PadSsmMsg唯一消息ID
* @param timestamp 消息发送时间 单位:毫秒
* @param isQuery 是否是查询 ture查询应的结果 false表示状态变动域控主动推送
* @param isQuery 是否是查询 ture查询应的结果 false表示状态变动域控主动推送
* @param coldStartState 数据 null表示 PadSsmMsg中的消息体为null
*/
void onColdStartState(MessagePad.Header header, long token, long timestamp, boolean isQuery, @Nullable SsmInfo.ColdStartState coldStartState);
@@ -223,7 +257,7 @@ public interface OnAdasListener {
* 返回 是否首次进自驾、订单号、次数
*
* @param header 头
* @param token 唯一消息ID
* @param token PadSsmMsg唯一消息ID
* @param timestamp 消息发送时间 单位:毫秒
* @param autoPilotInfo 数据 null表示 PadSsmMsg中的消息体为null
*/
@@ -233,7 +267,7 @@ public interface OnAdasListener {
* 到站信息查询响应
*
* @param header 头
* @param token 唯一消息ID
* @param token PadSsmMsg唯一消息ID
* @param timestamp 消息发送时间 单位:毫秒
* @param autoPilotStation 数据 null表示 PadSsmMsg中的消息体为null
*/
@@ -604,6 +638,15 @@ public interface OnAdasListener {
*/
void onNodeStateInfo(@NonNull NodeStateInfo stateInfo);
/**
* 接管时前方和后方摄像头数据请求的响应
*
* @param header 头
* @param isFront true前方摄像头 false后方摄像头
* @param data 数据
*/
void onCaptureImgOnTakeOver(@NonNull MessagePad.Header header, boolean isFront, @NonNull MessagePad.CaptureImgOnTakeOver data);
/**
* 是否有能力启动自动驾驶
*

View File

@@ -0,0 +1,33 @@
package com.zhidao.support.adas.high.msg;
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.common.CupidLogUtils;
import com.zhidao.support.adas.high.protocol.RawData;
import com.zhjt.mogo.adas.common.MessageType;
import mogo.telematics.pad.MessagePad;
/**
* 接管时前方和后方摄像头数据请求的响应
*/
public class CaptureImgOnTakeOverMessage extends MyAbstractMessageHandler {
@Override
public void handlerMsg(RawData raw, OnAdasListener adasListener) throws InvalidProtocolBufferException {
MessagePad.CaptureImgOnTakeOver data = MessagePad.CaptureImgOnTakeOver.parser().parseFrom(raw.originalData.toByteArray(), raw.getOffsetValue(), raw.getPackageLengthValue() - raw.getOffsetValue());
AdasChannel.calculateTimeConsumingOnDispatchRaw("接管时前方和后方摄像头数据请求的响应", raw.receiveTime);
long nowTime = 0;
if (CupidLogUtils.isEnableLog())
nowTime = SystemClock.elapsedRealtime();
if (adasListener != null) {
MessagePad.Header header = raw.getHeader();
adasListener.onCaptureImgOnTakeOver(header, header.getMsgType() == MessageType.TYPE_RECEIVE_CAPTURE_FRONT_IMG_ON_TAKE_OVER.typeCode, data);
}
AdasChannel.calculateTimeConsumingBusiness("接管时前方和后方摄像头数据请求的响应", nowTime);
}
}

View File

@@ -55,6 +55,7 @@ public class MyMessageFactory implements IMyMessageFactory {
private IMsg laneMarksTranMessage;//车道线
private IMsg powerUnitMessage;//电源模块
private IMsg padSsmFuncMsgMessage;//SSM功能
private IMsg captureImgOnTakeOverMessage;//接管时前方和后方摄像头数据请求的响应
private final AutopilotReview autopilotReview;
private final TurnLightState lightLeft = new TurnLightState();
@@ -317,6 +318,12 @@ public class MyMessageFactory implements IMyMessageFactory {
padSsmFuncMsgMessage = new PadSsmFuncMsgMessage();
}
return padSsmFuncMsgMessage;
} else if (messageType == MessageType.TYPE_RECEIVE_CAPTURE_FRONT_IMG_ON_TAKE_OVER.typeCode || messageType == MessageType.TYPE_RECEIVE_CAPTURE_BACK_IMG_ON_TAKE_OVER.typeCode) {
//接管时正前方和后方摄像头数据请求的响应
if (captureImgOnTakeOverMessage == null) {
captureImgOnTakeOverMessage = new CaptureImgOnTakeOverMessage();
}
return captureImgOnTakeOverMessage;
} else {
//MessageType.TYPE_DEFAULT.typeCode
return null;

View File

@@ -53,6 +53,33 @@ public class PadSsmFuncMsgMessage extends MyAbstractMessageHandler {
if (adasListener != null) {
adasListener.onAutoPilotStation(raw.getHeader(), padSsmMsg.getToken(), timestamp, autoPilotStation);
}
} else if (type == SsmInfo.MessageType.OTA_DOWNLOAD_REQUEST) {
//SSM发送OTA升级提示请求
SsmInfo.OtaDownloadRequest request = null;
if (!data.isEmpty()) {
request = SsmInfo.OtaDownloadRequest.parseFrom(data);
}
if (adasListener != null) {
adasListener.onOtaDownloadRequest(raw.getHeader(), padSsmMsg.getToken(), timestamp, request);
}
} else if (type == SsmInfo.MessageType.OTA_LOADING_PROGRESS) {
// //SSM上报OTA下载进度, 开始升级后定频上报
// SsmInfo.OtaLoadingProgess progress = null;
// if (!data.isEmpty()) {
// progress = SsmInfo.OtaLoadingProgess.parseFrom(data);
// }
// if (adasListener != null) {
// adasListener.onOtaLoadingProgress(raw.getHeader(), padSsmMsg.getToken(), timestamp, progress);
// }
} else if (type == SsmInfo.MessageType.OTA_STATUS || type == SsmInfo.MessageType.OTA_STATUS_QUERY) {
//SSM上报OTA状态和查询OTA状态
SsmInfo.OtaStatus status = null;
if (!data.isEmpty()) {
status = SsmInfo.OtaStatus.parseFrom(data);
}
if (adasListener != null) {
adasListener.onOtaStatus(raw.getHeader(), padSsmMsg.getToken(), timestamp, type == SsmInfo.MessageType.OTA_STATUS_QUERY, status);
}
}
AdasChannel.calculateTimeConsumingBusiness("SSM功能", nowTime);
}