diff --git a/core/function-impl/mogo-core-function-datacenter/src/main/java/com/mogo/eagle/core/function/datacenter/autopilot/MoGoAutopilotControlProvider.kt b/core/function-impl/mogo-core-function-datacenter/src/main/java/com/mogo/eagle/core/function/datacenter/autopilot/MoGoAutopilotControlProvider.kt index b98ddb313e..41e007e3b0 100644 --- a/core/function-impl/mogo-core-function-datacenter/src/main/java/com/mogo/eagle/core/function/datacenter/autopilot/MoGoAutopilotControlProvider.kt +++ b/core/function-impl/mogo-core-function-datacenter/src/main/java/com/mogo/eagle/core/function/datacenter/autopilot/MoGoAutopilotControlProvider.kt @@ -9,6 +9,7 @@ import com.alibaba.android.arouter.facade.annotation.Route import com.mogo.commons.debug.DebugConfig import com.mogo.commons.storage.SharedPrefsMgr import com.mogo.eagle.core.data.autopilot.AutopilotControlParameters +import com.mogo.eagle.core.data.autopilot.toAutoPilotCmdInfo import com.mogo.eagle.core.data.autopilot.toAutoPilotLine import com.mogo.eagle.core.data.autopilot.toRouteInfo import com.mogo.eagle.core.data.biz.trafficlight.TrafficLightResult @@ -66,6 +67,7 @@ import com.zhidao.support.adas.high.chain.AdasChain import com.zhidao.support.adas.high.common.Constants import com.zhidao.support.adas.high.common.CupidLogUtils import com.zhjt.mogo.adas.common.MessageType +import com.zhjt.mogo.adas.common.power.PowerUnitChannel import com.zhjt.mogo.adas.data.Adas import com.zhjt.mogo.adas.data.AdasConstants import com.zhjt.mogo.adas.data.bean.MogoReport @@ -391,12 +393,12 @@ class MoGoAutopilotControlProvider : private fun startAutoPilotWithNoParameter(source: Int) { if (AppIdentityModeUtils.isPassenger(FunctionBuildConfig.appIdentityMode)) { val invokeResult = AdasManager.getInstance() - .sendAutoPilotModeReq(1, source, null) + .sendAutoPilotModeReq(1, source, null, null) invokeAutoPilotResult(if (invokeResult > -1) "无参自动驾驶调用成功:${invokeResult}" else "自动驾驶调用失败, socket 或者 rawPack 可能为空") } else { if (AdasManager.getInstance().ipcConnectionStatus == AdasConstants.IpcConnectionStatus.CONNECTED) { val invokeResult = AdasManager.getInstance() - .sendAutoPilotModeReq(1, source, null) + .sendAutoPilotModeReq(1, source, null, null) invokeAutoPilotResult(if (invokeResult > -1) "无参自动驾驶调用成功:${invokeResult}" else "自动驾驶调用失败, socket 或者 rawPack 可能为空") } else { invokeAutoPilotResult("车机与工控机链接失败,无法开启自动驾驶 无参") @@ -407,13 +409,13 @@ class MoGoAutopilotControlProvider : private fun startAutoPilot(controlParameters: AutopilotControlParameters, source: Int): Long { if (AppIdentityModeUtils.isPassenger(FunctionBuildConfig.appIdentityMode)) { val invokeResult = AdasManager.getInstance() - .sendAutoPilotModeReq(1, source, controlParameters.toRouteInfo()) + .sendAutoPilotModeReq(1, source, controlParameters.toRouteInfo(), controlParameters.toAutoPilotCmdInfo()) invokeAutoPilotResult(if (invokeResult > -1) "自动驾驶调用成功:${invokeResult}" else "自动驾驶调用失败, socket 或者 rawPack 可能为空") return invokeResult } else { if (AdasManager.getInstance().ipcConnectionStatus == AdasConstants.IpcConnectionStatus.CONNECTED) { val invokeResult = AdasManager.getInstance() - .sendAutoPilotModeReq(1, source, controlParameters.toRouteInfo()) + .sendAutoPilotModeReq(1, source, controlParameters.toRouteInfo(), controlParameters.toAutoPilotCmdInfo()) invokeAutoPilotResult(if (invokeResult > -1) "自动驾驶调用成功:${invokeResult}" else "自动驾驶调用失败, socket 或者 rawPack 可能为空") return invokeResult } else { @@ -463,7 +465,7 @@ class MoGoAutopilotControlProvider : override fun cancelAutoPilot() { if (AdasManager.getInstance().ipcConnectionStatus == AdasConstants.IpcConnectionStatus.CONNECTED) { - val invokeResult = AdasManager.getInstance().sendAutoPilotModeReq(0, 1, null) + val invokeResult = AdasManager.getInstance().sendAutoPilotModeReq(0, 1, null, null) invokeAutoPilotResult(if (invokeResult > -1) "取消自动驾驶调用成功:${invokeResult}" else "取消自动驾驶调用失败, socket 或者 rawPack 可能为空") } else { invokeAutoPilotResult("车机与工控机链接失败,无法取消自动驾驶") @@ -1032,11 +1034,11 @@ class MoGoAutopilotControlProvider : */ override fun setControlAutopilotCarAuto(isEnable: Boolean) { if (isEnable) { - AdasManager.getInstance().sendAutoPilotModeReq(1, 0, null) + AdasManager.getInstance().sendAutoPilotModeReq(1, 0, null, null) } else { // 司机屏才可关闭自动驾驶 if (AppIdentityModeUtils.isDriver(FunctionBuildConfig.appIdentityMode)) { - AdasManager.getInstance().sendAutoPilotModeReq(0, 0, null) + AdasManager.getInstance().sendAutoPilotModeReq(0, 0, null, null) } } } @@ -1269,6 +1271,82 @@ class MoGoAutopilotControlProvider : return AdasManager.getInstance().sendSweeperCloudSuspendResumeTaskResp(reqNo, bigTaskActionResp) > -1 } + /** + * 发送电源状态查询请求 + * + * @return 消息是否添加到WS消息发送队列,返回值为非0的正整数时表示下发消息的消息ID + * * >=0:表示添加到WS发送消息队列 + * * =0:表示乘客屏模式添加到WS发送消息队列 + * * -1L:添加到WS发送消息队列失败 + */ + override fun sendPowerUnitSTSRequest(): Long { + return AdasManager.getInstance().sendPowerUnitSTSRequest() + } + + /** + * 发送单通道电源控制请求 + * + * @param channel 通道 + * @param cmd 0:关闭;1:打开; + * @return 消息是否添加到WS消息发送队列,返回值为非0的正整数时表示下发消息的消息ID + * * >=0:表示添加到WS发送消息队列 + * * =0:表示乘客屏模式添加到WS发送消息队列 + * * -1L:添加到WS发送消息队列失败 + */ + override fun sendPowerUnitSingleChannelControl(channel: PowerUnitChannel, cmd: Int): Long { + return AdasManager.getInstance().sendPowerUnitSingleChannelControl(channel,cmd) + } + + /** + * 发送电源控制重置请求 + * + * @return 消息是否添加到WS消息发送队列,返回值为非0的正整数时表示下发消息的消息ID + * * >=0:表示添加到WS发送消息队列 + * * =0:表示乘客屏模式添加到WS发送消息队列 + * * -1L:添加到WS发送消息队列失败 + */ + override fun sendPowerUnitReset(): Long { + return AdasManager.getInstance().sendPowerUnitReset() + } + + /** + * 查询冷启动状态 + * + * @return 消息是否添加到WS消息发送队列,返回值为非0的正整数时表示下发消息的消息ID + * * >=0:表示添加到WS发送消息队列 + * * =0:表示乘客屏模式添加到WS发送消息队列 + * * -1L:添加到WS发送消息队列失败 + */ + override fun sendSsmFuncQueryColdStartState(): Long { + return AdasManager.getInstance().sendSsmFuncQueryColdStartState() + } + + /** + * 查询自驾命令状态 + * 查询:是否首次进自驾、订单号、次数 + * + * @return 消息是否添加到WS消息发送队列,返回值为非0的正整数时表示下发消息的消息ID + * * >=0:表示添加到WS发送消息队列 + * * =0:表示乘客屏模式添加到WS发送消息队列 + * * -1L:添加到WS发送消息队列失败 + */ + override fun sendSsmFuncQueryAutoPilotInfo(): Long { + return AdasManager.getInstance().sendSsmFuncQueryAutoPilotInfo() + } + + /** + * 查询到站信息 + * + * @param orderId 订单号 + * @return 消息是否添加到WS消息发送队列,返回值为非0的正整数时表示下发消息的消息ID + * * >=0:表示添加到WS发送消息队列 + * * =0:表示乘客屏模式添加到WS发送消息队列 + * * -1L:添加到WS发送消息队列失败 + */ + override fun sendSsmFuncQueryAutoPilotStation(orderId: String): Long { + return AdasManager.getInstance().sendSsmFuncQueryAutoPilotStation(orderId) + } + override fun sendParallelDrivingReq( reqNo: String, parallelRequest: ParallelDrivingRequest.ParallelRequest diff --git a/core/function-impl/mogo-core-function-datacenter/src/main/java/com/mogo/eagle/core/function/datacenter/autopilot/adapter/MoGoAdasListenerImpl.kt b/core/function-impl/mogo-core-function-datacenter/src/main/java/com/mogo/eagle/core/function/datacenter/autopilot/adapter/MoGoAdasListenerImpl.kt index ca38830dba..0701b49141 100644 --- a/core/function-impl/mogo-core-function-datacenter/src/main/java/com/mogo/eagle/core/function/datacenter/autopilot/adapter/MoGoAdasListenerImpl.kt +++ b/core/function-impl/mogo-core-function-datacenter/src/main/java/com/mogo/eagle/core/function/datacenter/autopilot/adapter/MoGoAdasListenerImpl.kt @@ -8,8 +8,11 @@ import com.mogo.eagle.core.data.app.AppConfigInfo import com.mogo.eagle.core.data.config.HdMapBuildConfig import com.mogo.eagle.core.data.deva.chain.ChainConstant import com.mogo.eagle.core.data.deva.chain.ChainConstant.Companion.CHAIN_CODE_ADAS_ARRIVE +import com.mogo.eagle.core.data.deva.chain.ChainConstant.Companion.CHAIN_CODE_ADAS_ARRIVE_QUERY +import com.mogo.eagle.core.data.deva.chain.ChainConstant.Companion.CHAIN_CODE_ADAS_AUTOPILOT_INFO import com.mogo.eagle.core.data.deva.chain.ChainConstant.Companion.CHAIN_CODE_ADAS_CAR_CONFIG import com.mogo.eagle.core.data.deva.chain.ChainConstant.Companion.CHAIN_CODE_ADAS_CAR_LOC +import com.mogo.eagle.core.data.deva.chain.ChainConstant.Companion.CHAIN_CODE_ADAS_COLD_START_STATE import com.mogo.eagle.core.data.deva.chain.ChainConstant.Companion.CHAIN_CODE_ADAS_FM_MSG import com.mogo.eagle.core.data.deva.chain.ChainConstant.Companion.CHAIN_CODE_ADAS_FSM_MSG import com.mogo.eagle.core.data.deva.chain.ChainConstant.Companion.CHAIN_CODE_ADAS_GUARDIAN @@ -35,6 +38,8 @@ import com.mogo.eagle.core.data.msgbox.MsgBoxType import com.mogo.eagle.core.data.msgbox.SSMMsg import com.mogo.eagle.core.function.call.autopilot.CallerAutoPilotStatusListenerManager import com.mogo.eagle.core.function.call.autopilot.CallerAutoPilotStatusListenerManager.invokeArriveAtStation +import com.mogo.eagle.core.function.call.autopilot.CallerAutoPilotStatusListenerManager.invokeAutoPilotInfo +import com.mogo.eagle.core.function.call.autopilot.CallerAutoPilotStatusListenerManager.invokeAutoPilotStation import com.mogo.eagle.core.function.call.autopilot.CallerAutoPilotStatusListenerManager.invokeAutopilotGuardian import com.mogo.eagle.core.function.call.autopilot.CallerAutoPilotStatusListenerManager.invokeAutopilotSNRequest import com.mogo.eagle.core.function.call.autopilot.CallerAutoPilotStatusListenerManager.invokeAutopilotStatusRespByQuery @@ -58,6 +63,7 @@ import com.mogo.eagle.core.function.call.autopilot.CallerBackCameraVideoListener import com.mogo.eagle.core.function.call.autopilot.CallerChassisDoorStateListenerManager import com.mogo.eagle.core.function.call.autopilot.CallerChassisGnssListenerManager import com.mogo.eagle.core.function.call.autopilot.CallerChassisStatesListenerManager +import com.mogo.eagle.core.function.call.autopilot.CallerColdStartStateListenerManager import com.mogo.eagle.core.function.call.autopilot.CallerFaultManagementStateListenerManager import com.mogo.eagle.core.function.call.autopilot.CallerFsm2024ListenerManager import com.mogo.eagle.core.function.call.autopilot.CallerLocalizationStateListenerManager @@ -98,6 +104,7 @@ import com.zhjt.mogo.adas.data.bean.LaunchConditionData import com.zhjt.mogo.adas.data.bean.NodeStateInfo import com.zhjt.mogo.adas.data.bean.ReceivedAck import com.zhjt.mogo.adas.data.bean.UnableLaunchReason +import com.zhjt.mogo.adas.data.bean.power.PowerData import com.zhjt.mogo.adas.data.sweeper.bootable.SweeperBootable import com.zhjt.mogo.adas.data.sweeper.task.SweeperTask import com.zhjt.mogo.adas.data.sweeper.task.big.SweeperBigTaskStatus @@ -414,6 +421,160 @@ class MoGoAdasListenerImpl : OnAdasListener { override fun onWarn(header: MessagePad.Header, warn: MessagePad.Warn?) { } + /** + * 冷启动状态变更上报以及查询状态 + * + * @param header 头 + * @param token 唯一消息ID + * @param timestamp 消息发送时间 单位:毫秒 + * @param isQuery 是否是查询 ture:查询相应的结果 false:表示状态变动域控主动推送 + * @param coldStartState 数据 null表示 PadSsmMsg中的消息体为null + */ + override fun onColdStartState( + header: MessagePad.Header?, + token: Long, + timestamp: Long, + isQuery: Boolean, + coldStartState: SsmInfo.ColdStartState? + ) { + CallerColdStartStateListenerManager.invokeColdStartState( + token, + timestamp, + isQuery, + coldStartState + ) + if (coldStartState == null) { + coldStartStateError( + token, + timestamp, + isQuery, + "PadSsmMsg中的消息体为null" + ) + } else { + coldStartState( + token, + timestamp, + isQuery, + coldStartState + ) + } + } + + @ChainLog( + linkChainLog = CHAIN_TYPE_SOCKET_AUTOPILOT, + linkCode = CHAIN_SOURCE_ADAS, + nodeAliasCode = CHAIN_CODE_ADAS_COLD_START_STATE, + paramIndexes = [0, 1, 2, 3] + ) + private fun coldStartState( + token: Long, + timestamp: Long, + isQuery: Boolean, + coldStartState: SsmInfo.ColdStartState, + ) { + } + + @ChainLog( + linkChainLog = CHAIN_TYPE_SOCKET_AUTOPILOT, + linkCode = CHAIN_SOURCE_ADAS, + nodeAliasCode = CHAIN_CODE_ADAS_COLD_START_STATE, + paramIndexes = [0, 1, 2, 3] + ) + private fun coldStartStateError( + token: Long, + timestamp: Long, + isQuery: Boolean, + autoPilotInfo: String, + ) { + } + + /** + * 自驾命令状态查询响应 + * 返回 是否首次进自驾、订单号、次数 + * + * @param header 头 + * @param token 唯一消息ID + * @param timestamp 消息发送时间 单位:毫秒 + * @param autoPilotInfo 数据 null表示 PadSsmMsg中的消息体为null + */ + override fun onAutoPilotInfo( + header: MessagePad.Header?, + token: Long, + timestamp: Long, + autoPilotInfo: SsmInfo.AutoPilotInfo? + ) { + invokeAutoPilotInfo(token, timestamp, autoPilotInfo) + val msg: String + if (autoPilotInfo == null) { + msg = "PadSsmMsg中的消息体为null" + } else { + val temB: String = autoPilotInfo.firstAutopilotFlag.toString() + val temS: String = autoPilotInfo.orderId ?: "" + msg = "firstAutopilotFlag:" + temB + "orderId:" + temS + "count:" + autoPilotInfo.count + } + autoPilotInfoResponse( + token, + timestamp, + msg + ) + } + + @ChainLog( + linkChainLog = CHAIN_TYPE_SOCKET_AUTOPILOT, + linkCode = CHAIN_SOURCE_ADAS, + nodeAliasCode = CHAIN_CODE_ADAS_AUTOPILOT_INFO, + paramIndexes = [0, 1, 2] + ) + private fun autoPilotInfoResponse( + token: Long, + timestamp: Long, + autoPilotInfo: String, + ) { + } + + /** + * 到站信息查询响应 + * + * @param header 头 + * @param token 唯一消息ID + * @param timestamp 消息发送时间 单位:毫秒 + * @param autoPilotStation 数据 null表示 PadSsmMsg中的消息体为null + */ + override fun onAutoPilotStation( + header: MessagePad.Header?, + token: Long, + timestamp: Long, + autoPilotStation: SsmInfo.AutoPilotStation? + ) { + invokeAutoPilotStation(token, timestamp, autoPilotStation) + val msg: String + if (autoPilotStation == null) { + msg = "PadSsmMsg中的消息体为null" + } else { + val temB: String = autoPilotStation.arrivedStationFlag.toString() + val temS: String = autoPilotStation.orderId ?: "" + msg = "arrivedStationFlag:" + temB + "orderId:" + temS + } + autoPilotStationResponse( + token, + timestamp, + msg + ) + } + + @ChainLog( + linkChainLog = CHAIN_TYPE_SOCKET_AUTOPILOT, + linkCode = CHAIN_SOURCE_ADAS, + nodeAliasCode = CHAIN_CODE_ADAS_ARRIVE_QUERY, + paramIndexes = [0, 1, 2] + ) + private fun autoPilotStationResponse( + token: Long, + timestamp: Long, + autoPilotStation: String, + ) { + } + //到站回调 @ChainLog( linkChainLog = CHAIN_TYPE_SOCKET_AUTOPILOT, @@ -1052,6 +1213,20 @@ class MoGoAdasListenerImpl : OnAdasListener { } + /** + * 电源盒协议接口 + *
+ * {@link PowerData}使用方法
+ * 1.先判断数据中的{@link PowerData#protocolStatus} 是否是 {@link PowerProtocolStatus#SUCCEED} 如果是则表示数据解析正常可以正常使用,进行下一步
+ * 2.判断 {@link PowerData#frameType} 数据类型
+ *
+ * @param header 头
+ * @param data 数据
+ */
+ override fun onPowerUnit(header: MessagePad.Header, data: PowerData) {
+
+ }
+
/**
* 所连接的域控的节点状态信息
* 目前包含状态 节点是否存在;节点是否超时;
diff --git a/core/mogo-core-data/src/main/java/com/mogo/eagle/core/data/autopilot/AutopilotControlParameters.kt b/core/mogo-core-data/src/main/java/com/mogo/eagle/core/data/autopilot/AutopilotControlParameters.kt
index 6e65ee612a..46940aecc6 100644
--- a/core/mogo-core-data/src/main/java/com/mogo/eagle/core/data/autopilot/AutopilotControlParameters.kt
+++ b/core/mogo-core-data/src/main/java/com/mogo/eagle/core/data/autopilot/AutopilotControlParameters.kt
@@ -86,6 +86,12 @@ fun AutopilotControlParameters.toRouteInfo(): MessagePad.RouteInfo {
return routeInfo.build()
}
+fun AutopilotControlParameters.toAutoPilotCmdInfo(): MessagePad.CmdInfo {
+ val cmdInfo = MessagePad.CmdInfo.newBuilder()
+ cmdInfo.setFirstAutopilotFlag(firstAutopilotFlag).setOrderId(orderId)
+ return cmdInfo.build()
+}
+
fun AutopilotControlParameters.AutoPilotLine.toAutoPilotLine(): MessagePad.Line {
val line = MessagePad.Line.newBuilder()
line.lineId = this.lineId
@@ -145,6 +151,12 @@ class AutopilotControlParameters {
@JvmField
var autoPilotLine: AutoPilotLine? = null // 自动驾驶路线
+ @JvmField
+ var firstAutopilotFlag = true//是否首次进自驾
+
+ @JvmField
+ var orderId = ""//订单号
+
class AutoPilotLine {
var lineId = 0L
diff --git a/core/mogo-core-data/src/main/java/com/mogo/eagle/core/data/deva/chain/ChainConstant.kt b/core/mogo-core-data/src/main/java/com/mogo/eagle/core/data/deva/chain/ChainConstant.kt
index 8eeabaea5b..e2820b7d97 100644
--- a/core/mogo-core-data/src/main/java/com/mogo/eagle/core/data/deva/chain/ChainConstant.kt
+++ b/core/mogo-core-data/src/main/java/com/mogo/eagle/core/data/deva/chain/ChainConstant.kt
@@ -56,6 +56,7 @@ class ChainConstant {
const val CHAIN_CODE_ADAS_FM_MSG = "CHAIN_CODE_ADAS_FM_MSG"
const val CHAIN_CODE_ADAS_FSM_MSG = "CHAIN_CODE_ADAS_FSM_MSG"
const val CHAIN_CODE_ADAS_ARRIVE = "CHAIN_CODE_ADAS_ARRIVE"
+ const val CHAIN_CODE_ADAS_ARRIVE_QUERY = "CHAIN_CODE_ADAS_ARRIVE_QUERY"
const val CHAIN_CODE_ADAS_ROUTE = "CHAIN_CODE_ADAS_ROUTE"
const val CHAIN_CODE_ADAS_ROUTE_REQ = "CHAIN_CODE_ADAS_ROUTE_REQ"
const val CHAIN_CODE_ADAS_TRAJECTORY = "CHAIN_CODE_ADAS_ROUTE_REQ"
@@ -73,6 +74,8 @@ class ChainConstant {
const val CHAIN_CODE_ADAS_V2N_EVENT = "CHAIN_CODE_ADAS_V2N_EVENT"
const val CHAIN_CODE_ADAS_POWER_OFF = "CHAIN_CODE_ADAS_POWER_OFF"
const val CHAIN_CODE_ADAS_IPC_REBOOT = "CHAIN_CODE_ADAS_IPC_REBOOT"
+ const val CHAIN_CODE_ADAS_AUTOPILOT_INFO = "CHAIN_CODE_ADAS_AUTOPILOT_INFO"
+ const val CHAIN_CODE_ADAS_COLD_START_STATE = "CHAIN_CODE_ADAS_COLD_START_STATE"
const val CHAIN_CODE_RECORD_NATIVE_LEAK = "CHAIN_CODE_RECORD_NATIVE_LEAK"
const val CHAIN_CODE_RECORD_ANR = "CHAIN_CODE_RECORD_ANR"
diff --git a/core/mogo-core-function-api/src/main/java/com/mogo/eagle/core/function/api/autopilot/IMoGoAutopilotControlProvider.kt b/core/mogo-core-function-api/src/main/java/com/mogo/eagle/core/function/api/autopilot/IMoGoAutopilotControlProvider.kt
index 6370402b6c..a00b103231 100644
--- a/core/mogo-core-function-api/src/main/java/com/mogo/eagle/core/function/api/autopilot/IMoGoAutopilotControlProvider.kt
+++ b/core/mogo-core-function-api/src/main/java/com/mogo/eagle/core/function/api/autopilot/IMoGoAutopilotControlProvider.kt
@@ -5,7 +5,7 @@ import com.mogo.eagle.core.data.autopilot.AutopilotControlParameters
import com.mogo.eagle.core.data.biz.trafficlight.TrafficLightResult
import com.mogo.eagle.core.data.deva.badcase.BagManagerEntity
import com.mogo.eagle.core.function.api.base.IMoGoFunctionServerProvider
-import com.zhjt.mogo.adas.data.Adas
+import com.zhjt.mogo.adas.common.power.PowerUnitChannel
import com.zhjt.mogo.adas.data.AdasConstants
import com.zhjt.mogo.adas.data.bean.NodeStateInfo
import com.zhjt.mogo.adas.data.sweeper.bootable.SweeperBootable.IsBootable
@@ -551,6 +551,70 @@ interface IMoGoAutopilotControlProvider : IMoGoFunctionServerProvider {
*/
fun sendSweeperCloudSuspendResumeTaskResp(reqNo: String, bigTaskActionResp: BigTaskActionResp): Boolean
+ /**
+ * 发送电源状态查询请求
+ *
+ * @return 消息是否添加到WS消息发送队列,返回值为非0的正整数时表示下发消息的消息ID
+ * * >=0:表示添加到WS发送消息队列
+ * * =0:表示乘客屏模式添加到WS发送消息队列
+ * * -1L:添加到WS发送消息队列失败
+ */
+ fun sendPowerUnitSTSRequest(): Long
+
+ /**
+ * 发送单通道电源控制请求
+ *
+ * @param channel 通道
+ * @param cmd 0:关闭;1:打开;
+ * @return 消息是否添加到WS消息发送队列,返回值为非0的正整数时表示下发消息的消息ID
+ * * >=0:表示添加到WS发送消息队列
+ * * =0:表示乘客屏模式添加到WS发送消息队列
+ * * -1L:添加到WS发送消息队列失败
+ */
+ fun sendPowerUnitSingleChannelControl(channel: PowerUnitChannel, cmd: Int): Long
+
+ /**
+ * 发送电源控制重置请求
+ *
+ * @return 消息是否添加到WS消息发送队列,返回值为非0的正整数时表示下发消息的消息ID
+ * * >=0:表示添加到WS发送消息队列
+ * * =0:表示乘客屏模式添加到WS发送消息队列
+ * * -1L:添加到WS发送消息队列失败
+ */
+ fun sendPowerUnitReset(): Long
+
+ /**
+ * 查询冷启动状态
+ *
+ * @return 消息是否添加到WS消息发送队列,返回值为非0的正整数时表示下发消息的消息ID
+ * * >=0:表示添加到WS发送消息队列
+ * * =0:表示乘客屏模式添加到WS发送消息队列
+ * * -1L:添加到WS发送消息队列失败
+ */
+ fun sendSsmFuncQueryColdStartState(): Long
+
+ /**
+ * 查询自驾命令状态
+ * 查询:是否首次进自驾、订单号、次数
+ *
+ * @return 消息是否添加到WS消息发送队列,返回值为非0的正整数时表示下发消息的消息ID
+ * * >=0:表示添加到WS发送消息队列
+ * * =0:表示乘客屏模式添加到WS发送消息队列
+ * * -1L:添加到WS发送消息队列失败
+ */
+ fun sendSsmFuncQueryAutoPilotInfo(): Long
+
+ /**
+ * 查询到站信息
+ *
+ * @param orderId 订单号
+ * @return 消息是否添加到WS消息发送队列,返回值为非0的正整数时表示下发消息的消息ID
+ * * >=0:表示添加到WS发送消息队列
+ * * =0:表示乘客屏模式添加到WS发送消息队列
+ * * -1L:添加到WS发送消息队列失败
+ */
+ fun sendSsmFuncQueryAutoPilotStation(orderId: String): Long
+
/**
* 打开点云绘制
*
diff --git a/core/mogo-core-function-api/src/main/java/com/mogo/eagle/core/function/api/autopilot/IMoGoAutopilotStatusListener.kt b/core/mogo-core-function-api/src/main/java/com/mogo/eagle/core/function/api/autopilot/IMoGoAutopilotStatusListener.kt
index ee52f9c5de..24c51c006d 100644
--- a/core/mogo-core-function-api/src/main/java/com/mogo/eagle/core/function/api/autopilot/IMoGoAutopilotStatusListener.kt
+++ b/core/mogo-core-function-api/src/main/java/com/mogo/eagle/core/function/api/autopilot/IMoGoAutopilotStatusListener.kt
@@ -34,6 +34,32 @@ interface IMoGoAutopilotStatusListener {
*/
fun onAutopilotDockerInfo(dockerVersion:String){}
+ /**
+ * 自驾命令状态查询响应
+ * 返回 是否首次进自驾、订单号、次数
+ * 查询调用:CallerAutoPilotControlManager.sendSsmFuncQueryAutoPilotInfo()
+ *
+ * @param token 唯一消息ID
+ * @param timestamp 消息发送时间 单位:毫秒
+ * @param autoPilotInfo 数据 null表示 PadSsmMsg中的消息体为null
+ */
+ fun onAutoPilotInfo(token: Long, timestamp: Long, autoPilotInfo: SsmInfo.AutoPilotInfo?) {}
+
+ /**
+ * 到站信息查询响应
+ * 查询调用:CallerAutoPilotControlManager.sendSsmFuncQueryAutoPilotStation(orderId: String)
+ *
+ * @param token 唯一消息ID
+ * @param timestamp 消息发送时间 单位:毫秒
+ * @param autoPilotStation 数据 null表示 PadSsmMsg中的消息体为null
+ */
+ fun onAutoPilotStation(
+ token: Long,
+ timestamp: Long,
+ autoPilotStation: SsmInfo.AutoPilotStation?
+ ) {
+ }
+
/**
* 自动驾驶到站
*
diff --git a/core/mogo-core-function-api/src/main/java/com/mogo/eagle/core/function/api/autopilot/IMoGoColdStartStateListener.kt b/core/mogo-core-function-api/src/main/java/com/mogo/eagle/core/function/api/autopilot/IMoGoColdStartStateListener.kt
new file mode 100644
index 0000000000..824d37d843
--- /dev/null
+++ b/core/mogo-core-function-api/src/main/java/com/mogo/eagle/core/function/api/autopilot/IMoGoColdStartStateListener.kt
@@ -0,0 +1,25 @@
+package com.mogo.eagle.core.function.api.autopilot
+
+import system_master.SsmInfo
+
+
+/**
+ * 冷启动状态变更上报以及查询状态
+ */
+interface IMoGoColdStartStateListener {
+
+ /**
+ * 冷启动状态变更上报以及查询状态
+ *
+ * @param token 唯一消息ID
+ * @param timestamp 消息发送时间 单位:毫秒
+ * @param isQuery 是否是查询 ture:查询相应的结果 false:表示状态变动域控主动推送
+ * @param coldStartState 数据 null表示 PadSsmMsg中的消息体为null
+ */
+ fun onColdStartState(
+ token: Long,
+ timestamp: Long,
+ isQuery: Boolean,
+ coldStartState: SsmInfo.ColdStartState?
+ )
+}
\ No newline at end of file
diff --git a/core/mogo-core-function-call/src/main/java/com/mogo/eagle/core/function/call/autopilot/CallerAutoPilotControlManager.kt b/core/mogo-core-function-call/src/main/java/com/mogo/eagle/core/function/call/autopilot/CallerAutoPilotControlManager.kt
index 44e8ce8e7a..28e7280bca 100644
--- a/core/mogo-core-function-call/src/main/java/com/mogo/eagle/core/function/call/autopilot/CallerAutoPilotControlManager.kt
+++ b/core/mogo-core-function-call/src/main/java/com/mogo/eagle/core/function/call/autopilot/CallerAutoPilotControlManager.kt
@@ -22,6 +22,7 @@ import com.mogo.eagle.core.utilcode.mogo.AppIdentityModeUtils
import com.mogo.eagle.core.utilcode.mogo.logger.Logger
import com.mogo.eagle.core.utilcode.util.AppStateManager
import com.mogo.eagle.core.utilcode.util.ToastUtils
+import com.zhjt.mogo.adas.common.power.PowerUnitChannel
import com.zhjt.mogo.adas.data.Adas
import com.zhjt.mogo.adas.data.sweeper.bootable.SweeperBootable.IsBootable
import com.zhjt.mogo.adas.data.sweeper.task.SweeperTask.GetTaskReq
@@ -845,6 +846,82 @@ object CallerAutoPilotControlManager {
return providerApi?.sendParallelDrivingReq(reqNo, parallelRequest) ?: false
}
+ /**
+ * 发送电源状态查询请求
+ *
+ * @return 消息是否添加到WS消息发送队列,返回值为非0的正整数时表示下发消息的消息ID
+ * * >=0:表示添加到WS发送消息队列
+ * * =0:表示乘客屏模式添加到WS发送消息队列
+ * * -1L:添加到WS发送消息队列失败
+ */
+ fun sendPowerUnitSTSRequest(): Long {
+ return providerApi?.sendPowerUnitSTSRequest() ?: -1L
+ }
+
+ /**
+ * 发送单通道电源控制请求
+ *
+ * @param channel 通道
+ * @param cmd 0:关闭;1:打开;
+ * @return 消息是否添加到WS消息发送队列,返回值为非0的正整数时表示下发消息的消息ID
+ * * >=0:表示添加到WS发送消息队列
+ * * =0:表示乘客屏模式添加到WS发送消息队列
+ * * -1L:添加到WS发送消息队列失败
+ */
+ fun sendPowerUnitSingleChannelControl(channel: PowerUnitChannel, cmd: Int): Long {
+ return providerApi?.sendPowerUnitSingleChannelControl(channel, cmd) ?: -1L
+ }
+
+ /**
+ * 发送电源控制重置请求
+ *
+ * @return 消息是否添加到WS消息发送队列,返回值为非0的正整数时表示下发消息的消息ID
+ * * >=0:表示添加到WS发送消息队列
+ * * =0:表示乘客屏模式添加到WS发送消息队列
+ * * -1L:添加到WS发送消息队列失败
+ */
+ fun sendPowerUnitReset(): Long {
+ return providerApi?.sendPowerUnitReset() ?: -1L
+ }
+
+ /**
+ * 查询冷启动状态
+ *
+ * @return 消息是否添加到WS消息发送队列,返回值为非0的正整数时表示下发消息的消息ID
+ * * >=0:表示添加到WS发送消息队列
+ * * =0:表示乘客屏模式添加到WS发送消息队列
+ * * -1L:添加到WS发送消息队列失败
+ */
+ fun sendSsmFuncQueryColdStartState(): Long {
+ return providerApi?.sendSsmFuncQueryColdStartState() ?: -1L
+ }
+
+ /**
+ * 查询自驾命令状态
+ * 查询:是否首次进自驾、订单号、次数
+ *
+ * @return 消息是否添加到WS消息发送队列,返回值为非0的正整数时表示下发消息的消息ID
+ * * >=0:表示添加到WS发送消息队列
+ * * =0:表示乘客屏模式添加到WS发送消息队列
+ * * -1L:添加到WS发送消息队列失败
+ */
+ fun sendSsmFuncQueryAutoPilotInfo(): Long {
+ return providerApi?.sendSsmFuncQueryAutoPilotInfo() ?: -1L
+ }
+
+ /**
+ * 查询到站信息
+ *
+ * @param orderId 订单号
+ * @return 消息是否添加到WS消息发送队列,返回值为非0的正整数时表示下发消息的消息ID
+ * * >=0:表示添加到WS发送消息队列
+ * * =0:表示乘客屏模式添加到WS发送消息队列
+ * * -1L:添加到WS发送消息队列失败
+ */
+ fun sendSsmFuncQueryAutoPilotStation(orderId: String): Long {
+ return providerApi?.sendSsmFuncQueryAutoPilotStation(orderId) ?: -1L
+ }
+
/**
* 打开点云绘制
*/
diff --git a/core/mogo-core-function-call/src/main/java/com/mogo/eagle/core/function/call/autopilot/CallerAutoPilotStatusListenerManager.kt b/core/mogo-core-function-call/src/main/java/com/mogo/eagle/core/function/call/autopilot/CallerAutoPilotStatusListenerManager.kt
index c96fde4939..a9cdb83b1e 100644
--- a/core/mogo-core-function-call/src/main/java/com/mogo/eagle/core/function/call/autopilot/CallerAutoPilotStatusListenerManager.kt
+++ b/core/mogo-core-function-call/src/main/java/com/mogo/eagle/core/function/call/autopilot/CallerAutoPilotStatusListenerManager.kt
@@ -190,6 +190,42 @@ object CallerAutoPilotStatusListenerManager : CallerBase
+ * 整体判断是否有无故障使用{@link PowerUnitState#isNoneFault()}}
+ *
+ * 索引为51~66时调用 以下方法判断存在哪些故障
+ * {@link PowerUnitState#isTS()}}
+ * {@link PowerUnitState#isOC()}}
+ * {@link PowerUnitState#isOV()}}
+ * {@link PowerUnitState#isUV()}}
+ * 详情参见{@link PowerUnitState#getFaultState()}}
+ */
+ public final int faultState;
+
+ public PowerCommandExecuteState(PowerControlType controlType, boolean isSucceed) {
+ this(controlType, isSucceed, null, -1, -1, -1);
+ }
+
+ public PowerCommandExecuteState(PowerControlType controlType, boolean isSucceed, PowerUnitChannel channel, int sendPowerState, int actualPowerState, int faultState) {
+ this.controlType = controlType;
+ this.isSucceed = isSucceed;
+ this.channel = channel;
+ this.sendPowerState = sendPowerState;
+ this.actualPowerState = actualPowerState;
+ this.faultState = faultState;
+ }
+}
diff --git a/libraries/mogo-adas-data/src/main/java/com/zhjt/mogo/adas/data/bean/power/PowerData.java b/libraries/mogo-adas-data/src/main/java/com/zhjt/mogo/adas/data/bean/power/PowerData.java
new file mode 100644
index 0000000000..2f126a488f
--- /dev/null
+++ b/libraries/mogo-adas-data/src/main/java/com/zhjt/mogo/adas/data/bean/power/PowerData.java
@@ -0,0 +1,101 @@
+package com.zhjt.mogo.adas.data.bean.power;
+
+import com.zhjt.mogo.adas.common.power.PowerFrameType;
+import com.zhjt.mogo.adas.common.power.PowerProtocolStatus;
+
+import java.util.List;
+
+
+/**
+ * 电源原始数据协议
+ */
+public class PowerData {
+ /**
+ * 原始数据
+ */
+ public final byte[] originalData;
+ /**
+ * 数据拆包状态
+ */
+ public final PowerProtocolStatus protocolStatus;
+
+ /**
+ * 帧头 用于检查数据是否为正确数据
+ * mg=0xAA55
+ */
+ public final int frameHead;
+ /**
+ * 帧总长度
+ */
+ public final int totalLength;
+ /**
+ * 帧类型
+ */
+ public final PowerFrameType frameType;
+ /**
+ * 保留字节
+ */
+ public final int reserved;
+ /**
+ * 负载数据
+ */
+ public final byte[] dataBlocks;
+ /**
+ * 帧校验值
+ */
+ public final int checkValue;
+
+
+ private List
+ * 整体判断是否有无故障使用{@link PowerUnitState#isNoneFault()}}
+ *
+ * 索引为51~66时调用 以下方法判断存在哪些故障
+ * {@link PowerUnitState#isTS()}}
+ * {@link PowerUnitState#isOC()}}
+ * {@link PowerUnitState#isOV()}}
+ * {@link PowerUnitState#isUV()}}
+ */
+ private int faultState;
+
+ /**
+ * 索引1~46电流保护状态 null表示没有此参数
+ * ture:电流保护;false:为保护;
+ */
+ private Boolean currentProtectionState;
+
+ /**
+ * 索引1~46电流值 null表示没有此参数
+ * 单位:A
+ */
+ private Float currentValue;
+
+ public PowerUnitState(PowerUnitChannel channel) {
+ this.channel = channel;
+ }
+
+ public PowerUnitChannel getChannel() {
+ return channel;
+ }
+
+ public int getPowerState() {
+ return powerState;
+ }
+
+ public void setPowerState(int powerState) {
+ this.powerState = powerState;
+ }
+
+ public int getFaultState() {
+ return faultState;
+ }
+
+ public void setFaultState(int faultState) {
+ this.faultState = faultState;
+ }
+
+ public Boolean getCurrentProtectionState() {
+ return currentProtectionState;
+ }
+
+ public void setCurrentProtectionState(Boolean currentProtectionState) {
+ this.currentProtectionState = currentProtectionState;
+ }
+
+ public Float getCurrentValue() {
+ return currentValue;
+ }
+
+ public void setCurrentValue(Float currentValue) {
+ this.currentValue = currentValue;
+ }
+
+ /**
+ * 是否打开
+ * 索引1~46表示通电状态 false:关闭;ture:打开或底边打开
+ * 索引51~66表示连接状态 false:未连接;ture:已连接;
+ *
+ * @return 状态
+ */
+ public boolean isPowerOpen() {
+ return powerState != 0;
+ }
+
+ /**
+ * 是否无故障
+ * 索引1~46表示通电状态 true:无故障;false:对地短路或过流或故障;
+ * 索引51~66表示连接状态 true:无故障;false:过温或过流或过压或欠压;
+ *
+ * @return 有无故障
+ */
+ public boolean isNoneFault() {
+ return faultState == 0;
+ }
+
+ /**
+ * 索引51~66是否过温故障
+ *
+ * @return 是否过温故障
+ */
+ public boolean isTS() {
+ return (faultState & 8) == 8;
+ }
+
+ /**
+ * 索引51~66是否过流故障
+ *
+ * @return 是否过流故障
+ */
+ public boolean isOC() {
+ return (faultState & 4) == 4;
+ }
+
+ /**
+ * 索引51~66是否过压故障
+ *
+ * @return 是否过压故障
+ */
+ public boolean isOV() {
+ return (faultState & 2) == 2;
+ }
+
+ /**
+ * 索引51~66是否欠压故障
+ *
+ * @return 是否欠压故障
+ */
+ public boolean isUV() {
+ return (faultState & 1) == 1;
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ if (this == o) return true;
+ if (o == null || getClass() != o.getClass()) return false;
+ PowerUnitState that = (PowerUnitState) o;
+ return channel == that.channel;
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hashCode(channel);
+ }
+
+ @Override
+ public String toString() {
+ return "PowerUnitState{" +
+ "channel=" + channel +
+ ", powerState=" + powerState +
+ ", faultState=" + faultState +
+ ", currentProtectionState=" + currentProtectionState +
+ ", currentValue=" + currentValue +
+ '}';
+ }
+}
diff --git a/libraries/mogo-adas-data/src/main/java/com/zhjt/mogo/adas/utils/ByteUtil.java b/libraries/mogo-adas-data/src/main/java/com/zhjt/mogo/adas/utils/ByteUtil.java
index 015f877f82..c450e03f87 100644
--- a/libraries/mogo-adas-data/src/main/java/com/zhjt/mogo/adas/utils/ByteUtil.java
+++ b/libraries/mogo-adas-data/src/main/java/com/zhjt/mogo/adas/utils/ByteUtil.java
@@ -18,6 +18,13 @@ public class ByteUtil {
return bytes;
}
+ public static byte[] set16bitUnsignedValueLittleEndian(int num) {
+ byte[] bytes = new byte[2];
+ bytes[1] = (byte) (num >> 8);
+ bytes[0] = (byte) num;
+ return bytes;
+ }
+
public static byte[] set32bitUnsignedValue(long num) {
byte[] bytes = new byte[4];
bytes[0] = (byte) (num >> 24);
@@ -27,6 +34,15 @@ public class ByteUtil {
return bytes;
}
+ public static byte[] set32bitUnsignedValueValueLittleEndian(long num) {
+ byte[] bytes = new byte[4];
+ bytes[0] = (byte) num;
+ bytes[1] = (byte) (num >> 8);
+ bytes[2] = (byte) (num >> 16);
+ bytes[3] = (byte) (num >> 24);
+ return bytes;
+ }
+
public static byte[] set64bitUnsignedValue(long num) {
byte[] bytes = new byte[8];
bytes[0] = (byte) (num >> 56);
@@ -81,6 +97,25 @@ public class ByteUtil {
return value;
}
+ /**
+ * 无符号
+ * 合并 2 byte
+ * 使用后将 Index中的index移动到下一个数据的开始位
+ *
+ * @param data
+ * @return
+ */
+
+ public static int get16bitUnsignedValueLittleEndian(byte[] data) {
+ int value = 0;
+ if (data.length > 1) {
+ value = data[1] & 0xFF;
+ value = value << 8;
+ value = value | (data[0] & 0xFF);
+ }
+ return value;
+ }
+
/**
* 无符号
* 合并 4 byte
@@ -106,6 +141,30 @@ public class ByteUtil {
return value;
}
+ /**
+ * 无符号
+ * 合并 4 byte
+ * 使用后将 Index中的index移动到下一个数据的开始位
+ * *
+ *
+ * @param data
+ * @return
+ */
+
+ public static int get32bitUnsignedValueLittleEndian(byte[] data) {
+ int value = 0;
+ if (data.length > 3) {
+ value = data[3] & 0xFF;
+ value = value << 8;
+ value = value | (data[2] & 0xFF);
+ value = value << 8;
+ value = value | (data[1] & 0xFF);
+ value = value << 8;
+ value = value | (data[0] & 0xFF);
+ }
+ return value;
+ }
+
/**
* 无符号
* 合并 8 byte
@@ -374,4 +433,11 @@ public class ByteUtil {
(byte) ((b >> 6) & 0x1) +
(byte) ((b >> 7) & 0x1);
}
+
+
+ //b为传入的字节,i为第几位(范围0-7),如要获取bit0,则i=0
+ public static int getBit(byte b, int i) {
+ return (b >> i) & 0x1;
+ }
+
}
diff --git a/libraries/mogo-adas-data/src/main/proto/message_pad.proto b/libraries/mogo-adas-data/src/main/proto/message_pad.proto
index 560b6fd351..b9f77fc20f 100644
--- a/libraries/mogo-adas-data/src/main/proto/message_pad.proto
+++ b/libraries/mogo-adas-data/src/main/proto/message_pad.proto
@@ -93,6 +93,10 @@ enum MessageType
MsgTypeV2nNioOtherRetrogradeEvent = 0x1012a; //他车逆行(路侧)事件推送, 透传
MsgTypeV2nNioCongestionEvent = 0x1012b; //拥堵事件推送, 透传
MsgTypeLaneMarksTran = 0x1012c;//车道线上传
+ MsgTypeCollisionReport = 0x1012d;//碰撞上报
+ MsgTypePowerUnit = 0x1012e;//电源模块通信
+ MsgTypeSSMFuncMsg = 0x1012f;//SSM功能(上下行)
+ MsgTypeSSMFuncStatusQuery = 0x10130;//SSM功能状态查询及返回(上下行)
}
message Header
@@ -292,7 +296,7 @@ message TrackedSource
message TrackedObject
{
- uint32 type = 1; //物体类型, 0:Background, 1:Person, 2:Bicycle, 3:Car, 4:MotorCycle,
+ uint32 type = 1; //物体类型, 0:Background, 1:Person, 2:Bicycle, 3:Car, 4:MotorCycle,
//5:TrafficSign, 6:Bus, 7:CellPhone, 8:Truck, 9:Bottle, 10:TrafficLight,
//11:Rider, 12:TriangleRoadblock, 13:WarningTriangle, 100:Unknown,
//447:TAILBACK 501:RoadWork_occupy_0501, 502:RoadWork_break_0502,
@@ -351,7 +355,7 @@ message TrackedObjects
// message definition for MsgTypeGnssInfo
message GnssInfo
{
- double longitude = 1; //经度
+ double longitude = 1; //经度
double latitude = 2; //纬度
double altitude = 3; //海拔
double heading = 4; //航向角
@@ -393,7 +397,7 @@ message AutopilotState
// message definition for MessageType: MsgTypePlanningObjects
message PlanningObject
{
- uint32 uuid = 1;
+ uint32 uuid = 1;
uint32 type = 2; //影响自车决策的类型, 和感知的障碍物类型不是一回事 0是leading障碍物,1是避障和择机的障碍物
}
@@ -434,7 +438,7 @@ message TrajectoryDownloadReq
}
// message definition for MessageType: MsgTypeBasicInfoReq
-message BasicInfoReq
+message BasicInfoReq
{
bytes certification = 1;//域控ssl证书
}
@@ -462,7 +466,7 @@ message Location
message RouteInfo
{
- Location startLocation = 1;
+ Location startLocation = 1;
string startName = 2;
Location endLocation = 3;
string endName = 4;
@@ -478,12 +482,18 @@ message RouteInfo
bool isStation = 13; //20240523 用于表示判断是否是站点下单。默认false:起点下单,接管下单; true: 中间站点下单
}
+message CmdInfo {
+ bool first_autopilot_flag = 1; // 是否首次进自驾
+ string order_id = 2; // 订单号
+}
+
message SetAutopilotModeReq
{
uint32 mode = 1; //1: enter autopilot mode, 0: quit autopilot mode
uint32 source = 2; //命令来源: 0: pad模拟, 1: pad业务, 2:aicloud, 3:魔方(清扫车MAP Version==332以及MAP Version>=350,其他车型目前未上线)
RouteInfo routeInfo = 3; //自动驾驶路径信息
uint64 sessionId = 4; //autopilot cmd session ID
+ CmdInfo cmd_info = 5; //自驾命令信息
}
// message definition for MsgTypeSetDemoModeReq
@@ -505,7 +515,7 @@ message CarConfigResp
string macAddress = 3;
ProtocolVersion protocolVersion = 4; //通信协议版本
double speedLimit = 5; //自动驾驶限速, 单位:m/s
- double maxSpeedLimit = 6; //最大自动驾驶限速, 单位:m/s
+ double maxSpeedLimit = 6; //最大自动驾驶限速, 单位:m/s
double minAcceleration = 7; //最小加速度, 单位:m/s²
double maxAcceleration = 8; //最大加速度, 单位:m/s²
string carType = 9; //车辆类型
@@ -582,7 +592,7 @@ message TrafficLightDetail
message TrafficLightData
{
string crossID = 1; //roadID
- double latitude = 2;
+ double latitude = 2;
double longitude = 3;
string heading = 4; //红绿灯方向
string direction = 5; //路的航向角
@@ -794,7 +804,7 @@ message PlanningActionMsg
//message definition for MsgTypeSetParamReq
message SetOneParam
{
- uint32 type = 1; // 0:default 1:绕障类功能开关(bool) 2:变道绕障的目标障碍物速度阈值(double, m/s),针对低速绕行功能的
+ uint32 type = 1; // 0:default 1:绕障类功能开关(bool) 2:变道绕障的目标障碍物速度阈值(double, m/s),针对低速绕行功能的
// 3:AEB开关(bool) 0:关闭自动紧急制动功能 1:启用自动紧急制动功能
// 4:限制绕障开关(bool) 0:正常绕障 1:限制绕障 默认0
// 5:停车让行线前避让等待开关(bool) 0:停车让行线前无需等待 1:停车让行线前需要等待 默认0
@@ -810,7 +820,7 @@ message SetOneParam
// 15:座椅状态(int) 0:表示仅主驾位有人,1:表示仅副驾位有人,2:表示主驾和副驾同时有人,3:表示仅后排有人,4:表示主驾有人+后排有人,5:表示副驾有人+后排有人,6:表示主驾和副驾同时有人+后排有人,7: 所有座位都无人, 255:缺省
// 16: 超车的最大速度阈值(double, m/s) T1/T2: 范围[3, 12.5], 默认值10
// 17: 故障模拟指令(int) default:0, 1:线控失效
- // 18: 碰撞上报(null)
+ // 18: 碰撞上报(null) TODO 废弃,使用:message CollisionReport
// 19: 会车开关(bool) 0: off 1:on 默认0
// 20: 超车开关(bool) 0: off 1:on 默认0
string value = 2; // 转成字符串的值
@@ -923,3 +933,11 @@ message SessionInfo
//message definition for MsgTypeLocState
//refer to loc_state.proto
+
+//message definition for MsgTypeCollisionReport
+message CollisionReport
+{
+ double longitude = 1;
+ double latitude = 2;
+ double timestamp = 3;//时间, 单位:秒
+}
\ No newline at end of file
diff --git a/libraries/mogo-adas-data/src/main/proto/ssm_info.proto b/libraries/mogo-adas-data/src/main/proto/ssm_info.proto
index 1d9653c267..7e738f60d2 100644
--- a/libraries/mogo-adas-data/src/main/proto/ssm_info.proto
+++ b/libraries/mogo-adas-data/src/main/proto/ssm_info.proto
@@ -52,3 +52,128 @@ message SsmStatusInf {
optional string slam_map_ver = 22; //slam地图版本
optional string grid_map_ver = 23; //栅格地图版本
}
+
+
+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_STATUS = 4; // ssm 上报OTA状态 todo
+ OTA_STATUS_QUERY = 5; // pad查询OTA状态 req:OtaToken resp:OtaStatus
+ COLD_START_STATUS_REPORT = 6; // 冷启动状态上报 msg:ColdStartState
+ COLD_START_STATE_QUERY = 7; // 冷启动状态查询 req:None resp:ColdStartState
+ AUTO_PILOT_INFO = 8; // 自驾命令状态查询 resp:AutoPilotInfo
+ STATION_STATUS_QUERY = 9; //到站信息查询 req: OrderInfo resp:AutoPilotStation
+}
+
+message PadSsmMsg {
+ required uint64 token = 1; //消息唯一id
+ required MessageType msg_type = 2; //消息类型
+ required double timestamp = 3; //消息发送时间, 单位:秒
+ optional bytes data = 6; // 消息体
+}
+
+enum Level {
+ INFO_MSG = 0;
+ WARNING_MSG = 1;
+ ERROR_MSG = 2;
+}
+
+message Notification {
+ required Level level = 1; // 消息等级 0:info, 1:warning, 2:error
+ required string msg = 2; // 通知
+}
+
+enum OtaType {
+ IMAGE = 1;
+ FIRMWARE = 2;
+ MAP = 3;
+ PROFILE = 4;
+}
+
+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 string product_name = 4; // 制品名称
+ optional double size = 5; // 文件大小 Mb
+}
+
+enum IfUpgrade {
+ IMMEDIATELY = 1;
+ DELAY = 2;
+}
+
+message OtaToken {
+ required string token = 1; // ota token
+}
+
+message OtaDownloadResponse {
+ required string token = 1; // ota token
+ required IfUpgrade if_upgrade = 2; // 是否立即升级 1:立即升级 2:暂不升级
+}
+
+message OtaLoadingProgess {
+ required string ota_token = 1; // ota token
+ required double currentSize = 2; // 当前下载大小
+ required double totalSize = 3; // 总大小
+}
+
+enum UpgradeStatus {
+ UPGRADE_DEFAULT = 0;
+ UPGRADE_DOWNLOADING = 1;
+ UPGRADE_DOWNLOAD_FINISH = 2;
+ UPGRADE_FINSH = 3;
+ UPGRADE_FAIL = 4;
+}
+
+message OtaStatus {
+ required OtaDownloadRequest ota_info = 1; // 升级信息
+ required UpgradeStatus status = 2; // 状态 0:默认(未开始), 1:下载中, 2:下载完成, 3:升级完成, 4:升级失败
+ optional string reason = 3; // 失败原因
+}
+
+enum CSState {
+ COLD_START_DEFAULT = 0; // 未开始
+ COLD_START_STARTING = 1; // 启动中
+ COLD_START_READY = 2; // 就绪
+ COLD_START_UNREADY = 3; // 有异常未就绪
+ COLD_START_TIMEOUT = 4; // 超时
+}
+
+enum NodeStatus {
+ NODE_STARTING = 0; // 启动中
+ NODE_FINISH = 1; // 启动成功
+ NODE_FAILED = 2; // 启动失败
+ NODE_TIMEOUT = 3; // 启动超时
+}
+
+message ColdStartNode {
+ required string node_name = 1; //节点名称
+ required string event_code = 2; //上报事件
+ required NodeStatus status = 3; //0:启动中, 1:启动成功, 2:启动失败, 3:启动超时
+ required string desc = 4; //事件描述
+}
+
+message ColdStartState {
+ required CSState process_status = 1; //旧冷启动状态
+ required CSState event_status = 2; //节点自上报冷启动状态
+ repeated ColdStartNode node = 3; //冷启动关键节点信息
+ optional string process_timeout_reason = 4; //旧冷启动超时原因
+}
+
+message AutoPilotInfo {
+ required bool first_autopilot_flag = 1; // 是否首次进自驾
+ required string order_id = 2; // 订单号
+ required uint32 count = 3; // 次数
+}
+
+message OrderInfo{
+ required string order_id = 1; //订单号
+}
+
+message AutoPilotStation {
+ required bool arrived_station_flag = 1; //是否到站
+ optional string order_id = 2; //订单号
+}
\ No newline at end of file
diff --git a/libraries/mogo-adas/src/main/java/com/zhidao/support/adas/high/AdasChannel.java b/libraries/mogo-adas/src/main/java/com/zhidao/support/adas/high/AdasChannel.java
index 03783708cc..7e184cad1c 100644
--- a/libraries/mogo-adas/src/main/java/com/zhidao/support/adas/high/AdasChannel.java
+++ b/libraries/mogo-adas/src/main/java/com/zhidao/support/adas/high/AdasChannel.java
@@ -39,6 +39,7 @@ import com.zhidao.support.adas.high.protocol.PackData;
import com.zhidao.support.adas.high.protocol.RawData;
import com.zhidao.support.adas.high.protocol.RawPack;
import com.zhidao.support.adas.high.protocol.RawUnpack;
+import com.zhidao.support.adas.high.protocol.power.PowerRawPack;
import com.zhidao.support.adas.high.queue.WSByteQueueManager;
import com.zhidao.support.adas.high.queue.WebSocketQueueManager;
import com.zhidao.support.adas.high.socket.FpgaSocket;
@@ -46,6 +47,9 @@ import com.zhidao.support.adas.high.subscribe.SubscribeInterface;
import com.zhidao.support.adas.high.subscribe.SubscribeInterfaceOption;
import com.zhidao.support.adas.high.thread.DispatchHandler;
import com.zhjt.mogo.adas.common.MessageType;
+import com.zhjt.mogo.adas.common.power.PowerControlType;
+import com.zhjt.mogo.adas.common.power.PowerFrameType;
+import com.zhjt.mogo.adas.common.power.PowerUnitChannel;
import com.zhjt.mogo.adas.data.AdasConstants;
import com.zhjt.mogo.adas.data.AiCloudTask;
import com.zhjt.mogo.adas.data.bean.AdasParam;
@@ -70,7 +74,6 @@ import java.util.TimerTask;
import java.util.concurrent.atomic.AtomicBoolean;
import bag_manager.BagManagerOuterClass;
-import chassis.Chassis;
import chassis.SpecialVehicleTaskCmdOuterClass;
import common.HeaderOuterClass;
import function_state_management.FSMStatusReasonQueryOuterClass;
@@ -78,6 +81,7 @@ import mogo.telematics.ParamSetCmdOuterClass;
import mogo.telematics.pad.MessagePad;
import mogo.yycp.paralleldriving.protocol.ParallelDrivingRequest;
import okio.ByteString;
+import system_master.SsmInfo;
/**
* @ProjectName: lib-adas-fpga
@@ -150,6 +154,7 @@ public class AdasChannel implements IAdasNetCommApi, FpgaSocket.IWebSocketConnec
private final ReceivedAckManager receivedAckManager = new ReceivedAckManager();//消息回执
private final AtomicBoolean isInitConfigure = new AtomicBoolean(false);//是否进行配置初始化
+ private PowerRawPack powerRawPack;
public void setOnMultiDeviceListener(OnMultiDeviceListener onMultiDeviceListener) {
this.onMultiDeviceListener = onMultiDeviceListener;
@@ -1177,13 +1182,14 @@ public class AdasChannel implements IAdasNetCommApi, FpgaSocket.IWebSocketConnec
* @param mode 1: enter autopilot mode, 0: quit autopilot mode
* @param source 命令来源: 0: pad模拟, 1: pad业务, 2:aicloud, 3:魔方(清扫车MAP Version==332以及MAP Version>=350,其他车型目前未上线)
* @param routeInfo 自动驾驶路径信息
+ * @param cmdInfo 自驾命令信息(订单号,是否首次进自驾等)
* @return 消息是否添加到WS消息发送队列,返回值为非0的正整数时表示下发消息的消息ID和SessionID
* * >=0:表示添加到WS发送消息队列
* * =0:表示乘客屏模式添加到WS发送消息队列
* * -1L:添加到WS发送消息队列失败
*/
@Override
- public long sendAutoPilotModeReq(int mode, int source, MessagePad.RouteInfo routeInfo) {
+ public long sendAutoPilotModeReq(int mode, int source, @Nullable MessagePad.RouteInfo routeInfo, @Nullable MessagePad.CmdInfo cmdInfo) {
MessageId messageId = MessageId.build(MessageType.TYPE_SEND_SET_AUTOPILOT_MODE_REQ);
MessagePad.SetAutopilotModeReq.Builder builder = MessagePad.SetAutopilotModeReq.newBuilder();
builder.setMode(mode);
@@ -1191,6 +1197,9 @@ public class AdasChannel implements IAdasNetCommApi, FpgaSocket.IWebSocketConnec
if (routeInfo != null)
builder.setRouteInfo(routeInfo);
builder.setSessionId(messageId.id);
+ if (cmdInfo != null) {
+ builder.setCmdInfo(cmdInfo);
+ }
MessagePad.SetAutopilotModeReq req = builder.build();
if (autopilotReview != null) autopilotReview.onAutopilotCommandTrigger(req);
return sendPBMessage(MessageType.TYPE_SEND_SET_AUTOPILOT_MODE_REQ, req.toByteArray(), messageId);
@@ -1642,9 +1651,9 @@ public class AdasChannel implements IAdasNetCommApi, FpgaSocket.IWebSocketConnec
* 发送 轨迹下载请求
* 此方法存在域控回执,监听{@link OnAdasListener#onReceiveReceivedAck(ReceivedAck)}回调.使用方法:将此方法的返回值与{@link ReceivedAck#getMsgId()}进行比较,如果相同判断{@link ReceivedAck#getStatus()}是否等于{@link ReceivedAck.Status#NORMAL},详情参见CheckSystemView中的onReceiveReceivedAck
*
- * @param line 线路相关参数详情见PB message_pad.proto -> Line
- * @param downloadType 下载类型: 0:正常下载 1:预下载
- * @param routeInfo 20240523 进行自动算路,务必下单时候携带自动驾驶路径信息,否则可不填!
+ * @param line 线路相关参数详情见PB message_pad.proto -> Line
+ * @param downloadType 下载类型: 0:正常下载 1:预下载
+ * @param routeInfo 20240523 进行自动算路,务必下单时候携带自动驾驶路径信息,否则可不填!
* @return 消息是否添加到WS消息发送队列,返回值为非0的正整数时表示下发消息的消息ID
* * >=0:表示添加到WS发送消息队列
* * =0:表示乘客屏模式添加到WS发送消息队列
@@ -2874,5 +2883,117 @@ public class AdasChannel implements IAdasNetCommApi, FpgaSocket.IWebSocketConnec
return sendAiCloudTaskCmd(MessageType.TYPE_SEND_PARALLEL_DRIVING_REQ, AiCloudTask.MessageType.ParallelDrivingCmd, reqNo, parallelRequest.toByteString());
}
+ private long sendPowerUnit(PowerFrameType frameType, byte[] data) {
+ if (powerRawPack == null) {
+ powerRawPack = new PowerRawPack();
+ }
+ byte[] temp = powerRawPack.pack(frameType, data);
+ return sendPBMessage(MessageType.TYPE_SEND_POWER_UNIT, temp);
+ }
+
+ /**
+ * 发送电源状态查询请求
+ *
+ * @return 消息是否添加到WS消息发送队列,返回值为非0的正整数时表示下发消息的消息ID
+ * * >=0:表示添加到WS发送消息队列
+ * * =0:表示乘客屏模式添加到WS发送消息队列
+ * * -1L:添加到WS发送消息队列失败
+ */
+ @Override
+ public long sendPowerUnitSTSRequest() {
+ return sendPowerUnit(PowerFrameType.STS_REQUEST, null);
+ }
+
+ /**
+ * 发送单通道电源控制请求
+ *
+ * @param channel 通道
+ * @param cmd 0:关闭;1:打开;
+ * @return 消息是否添加到WS消息发送队列,返回值为非0的正整数时表示下发消息的消息ID
+ * * >=0:表示添加到WS发送消息队列
+ * * =0:表示乘客屏模式添加到WS发送消息队列
+ * * -1L:添加到WS发送消息队列失败
+ */
+ @Override
+ public long sendPowerUnitSingleChannelControl(PowerUnitChannel channel, int cmd) {
+ byte[] type = ByteUtil.set16bitUnsignedValueLittleEndian(PowerControlType.SINGLE_CHANNEL_CONTROL.value);
+ byte[] channelB = ByteUtil.set8bitUnsignedValue(channel.index);
+ byte[] cmdB = ByteUtil.set8bitUnsignedValue(cmd);
+ byte[] temp = ByteUtil.concatBytes(type, channelB);
+ temp = ByteUtil.concatBytes(temp, cmdB);
+ return sendPowerUnit(PowerFrameType.CMD_REQUEST, temp);
+ }
+
+ @Override
+ public long sendPowerUnitReset() {
+ byte[] type = ByteUtil.set16bitUnsignedValueLittleEndian(PowerControlType.RESET_CONTROL.value);
+ byte[] reserved = ByteUtil.set16bitUnsignedValueLittleEndian(0);
+ byte[] temp = ByteUtil.concatBytes(type, reserved);
+ return sendPowerUnit(PowerFrameType.CMD_REQUEST, temp);
+ }
+
+ /**
+ * 发送SSM功能消息
+ *
+ * @param isQuery 是否是查询功能
+ * @param data 数据
+ * @return
+ */
+ private long sendSsmFuncMsg(boolean isQuery, system_master.SsmInfo.MessageType type, @Nullable com.google.protobuf.ByteString data) {
+ MessageType messageType = isQuery ? MessageType.TYPE_SEND_SSM_FUNC_STATUS_QUERY : MessageType.TYPE_SEND_SSM_FUNC_MSG;
+ MessageId messageId = MessageId.build(messageType);
+ SsmInfo.PadSsmMsg.Builder builder = SsmInfo.PadSsmMsg.newBuilder();
+ builder.setToken(messageId.id);
+ builder.setMsgType(type);
+ builder.setTimestamp(System.currentTimeMillis() / 1000D);
+ if (data != null && !data.isEmpty()) {
+ builder.setData(data);
+ }
+ SsmInfo.PadSsmMsg req = builder.build();
+ return sendPBMessage(messageType, req.toByteArray(), messageId);
+ }
+
+ /**
+ * 查询冷启动状态
+ *
+ * @return 消息是否添加到WS消息发送队列,返回值为非0的正整数时表示下发消息的消息ID
+ * * >=0:表示添加到WS发送消息队列
+ * * =0:表示乘客屏模式添加到WS发送消息队列
+ * * -1L:添加到WS发送消息队列失败
+ */
+ @Override
+ public long sendSsmFuncQueryColdStartState() {
+ return sendSsmFuncMsg(true, system_master.SsmInfo.MessageType.COLD_START_STATE_QUERY, null);
+ }
+
+ /**
+ * 查询自驾命令状态
+ * 查询:是否首次进自驾、订单号、次数
+ *
+ * @return 消息是否添加到WS消息发送队列,返回值为非0的正整数时表示下发消息的消息ID
+ * * >=0:表示添加到WS发送消息队列
+ * * =0:表示乘客屏模式添加到WS发送消息队列
+ * * -1L:添加到WS发送消息队列失败
+ */
+ @Override
+ public long sendSsmFuncQueryAutoPilotInfo() {
+ return sendSsmFuncMsg(true, system_master.SsmInfo.MessageType.AUTO_PILOT_INFO, null);
+ }
+
+ /**
+ * 查询到站信息
+ *
+ * @param orderId 订单号
+ * @return 消息是否添加到WS消息发送队列,返回值为非0的正整数时表示下发消息的消息ID
+ * * >=0:表示添加到WS发送消息队列
+ * * =0:表示乘客屏模式添加到WS发送消息队列
+ * * -1L:添加到WS发送消息队列失败
+ */
+ @Override
+ public long sendSsmFuncQueryAutoPilotStation(@NonNull String orderId) {
+ return sendSsmFuncMsg(true, system_master.SsmInfo.MessageType.STATION_STATUS_QUERY, SsmInfo.OrderInfo.newBuilder().setOrderId(orderId).build().toByteString());
+ }
+
+
}
diff --git a/libraries/mogo-adas/src/main/java/com/zhidao/support/adas/high/AdasManager.java b/libraries/mogo-adas/src/main/java/com/zhidao/support/adas/high/AdasManager.java
index 49e3723e69..0796d7dd15 100644
--- a/libraries/mogo-adas/src/main/java/com/zhidao/support/adas/high/AdasManager.java
+++ b/libraries/mogo-adas/src/main/java/com/zhidao/support/adas/high/AdasManager.java
@@ -16,6 +16,7 @@ import com.zhidao.support.adas.high.common.MessageIdGenerator;
import com.zhidao.support.adas.high.common.ReceiveTimeoutManager;
import com.zhidao.support.adas.high.common.autopilot.ability.AutopilotAbilityManager;
import com.zhjt.mogo.adas.common.MessageType;
+import com.zhjt.mogo.adas.common.power.PowerUnitChannel;
import com.zhjt.mogo.adas.data.Adas;
import com.zhjt.mogo.adas.data.AdasConstants;
import com.zhjt.mogo.adas.data.bean.AdasParam;
@@ -397,14 +398,15 @@ public class AdasManager implements IAdasNetCommApi {
* @param mode 1: enter autopilot mode, 0: quit autopilot mode
* @param source 命令来源: 0: pad模拟, 1: pad业务, 2:aicloud, 3:魔方(清扫车MAP Version==332以及MAP Version>=350,其他车型目前未上线)
* @param routeInfo 自动驾驶路径信息
+ * @param cmdInfo 自驾命令信息(订单号,是否首次进自驾等)
* @return 消息是否添加到WS消息发送队列,返回值为非0的正整数时表示下发消息的消息ID和SessionID
* * >=0:表示添加到WS发送消息队列
* * =0:表示乘客屏模式添加到WS发送消息队列
* * -1L:添加到WS发送消息队列失败
*/
@Override
- public long sendAutoPilotModeReq(int mode, int source, MessagePad.RouteInfo routeInfo) {
- return mChannel == null ? -1L : mChannel.sendAutoPilotModeReq(mode, source, routeInfo);
+ public long sendAutoPilotModeReq(int mode, int source, @Nullable MessagePad.RouteInfo routeInfo, @Nullable MessagePad.CmdInfo cmdInfo) {
+ return mChannel == null ? -1L : mChannel.sendAutoPilotModeReq(mode, source, routeInfo, cmdInfo);
}
/**
@@ -1731,6 +1733,81 @@ public class AdasManager implements IAdasNetCommApi {
return mChannel == null ? -1L : mChannel.sendParallelDrivingReq(reqNo, parallelRequest);
}
+
+ /**
+ * 发送电源状态查询请求
+ *
+ * @return 消息是否添加到WS消息发送队列,返回值为非0的正整数时表示下发消息的消息ID
+ * * >=0:表示添加到WS发送消息队列
+ * * =0:表示乘客屏模式添加到WS发送消息队列
+ * * -1L:添加到WS发送消息队列失败
+ */
+ @Override
+ public long sendPowerUnitSTSRequest() {
+ return mChannel == null ? -1L : mChannel.sendPowerUnitSTSRequest();
+ }
+
+ /**
+ * 发送单通道电源控制请求
+ *
+ * @param channel 通道
+ * @param cmd 0:关闭;1:打开;
+ * @return 消息是否添加到WS消息发送队列,返回值为非0的正整数时表示下发消息的消息ID
+ * * >=0:表示添加到WS发送消息队列
+ * * =0:表示乘客屏模式添加到WS发送消息队列
+ * * -1L:添加到WS发送消息队列失败
+ */
+ @Override
+ public long sendPowerUnitSingleChannelControl(PowerUnitChannel channel, int cmd) {
+ return mChannel == null ? -1L : mChannel.sendPowerUnitSingleChannelControl(channel, cmd);
+ }
+
+ @Override
+ public long sendPowerUnitReset() {
+ return mChannel == null ? -1L : mChannel.sendPowerUnitReset();
+ }
+
+ /**
+ * 查询冷启动状态
+ *
+ * @return 消息是否添加到WS消息发送队列,返回值为非0的正整数时表示下发消息的消息ID
+ * * >=0:表示添加到WS发送消息队列
+ * * =0:表示乘客屏模式添加到WS发送消息队列
+ * * -1L:添加到WS发送消息队列失败
+ */
+ @Override
+ public long sendSsmFuncQueryColdStartState() {
+ return mChannel == null ? -1L : mChannel.sendSsmFuncQueryColdStartState();
+ }
+
+ /**
+ * 查询自驾命令状态
+ * 查询:是否首次进自驾、订单号、次数
+ *
+ * @return 消息是否添加到WS消息发送队列,返回值为非0的正整数时表示下发消息的消息ID
+ * * >=0:表示添加到WS发送消息队列
+ * * =0:表示乘客屏模式添加到WS发送消息队列
+ * * -1L:添加到WS发送消息队列失败
+ */
+ @Override
+ public long sendSsmFuncQueryAutoPilotInfo() {
+ return mChannel == null ? -1L : mChannel.sendSsmFuncQueryAutoPilotInfo();
+ }
+
+ /**
+ * 查询到站信息
+ *
+ * @param orderId 订单号
+ * @return 消息是否添加到WS消息发送队列,返回值为非0的正整数时表示下发消息的消息ID
+ * * >=0:表示添加到WS发送消息队列
+ * * =0:表示乘客屏模式添加到WS发送消息队列
+ * * -1L:添加到WS发送消息队列失败
+ */
+ @Override
+ public long sendSsmFuncQueryAutoPilotStation(@NonNull String orderId) {
+ return mChannel == null ? -1L : mChannel.sendSsmFuncQueryAutoPilotStation(orderId);
+ }
+
/**
* 查询节点状态
*
diff --git a/libraries/mogo-adas/src/main/java/com/zhidao/support/adas/high/IAdasNetCommApi.java b/libraries/mogo-adas/src/main/java/com/zhidao/support/adas/high/IAdasNetCommApi.java
index 2fdfa84f0d..5aecae3df7 100644
--- a/libraries/mogo-adas/src/main/java/com/zhidao/support/adas/high/IAdasNetCommApi.java
+++ b/libraries/mogo-adas/src/main/java/com/zhidao/support/adas/high/IAdasNetCommApi.java
@@ -7,6 +7,7 @@ import com.zhidao.support.adas.high.bean.VersionCompatibility;
import com.zhidao.support.adas.high.common.Constants;
import com.zhidao.support.adas.high.common.Define;
import com.zhjt.mogo.adas.common.MessageType;
+import com.zhjt.mogo.adas.common.power.PowerUnitChannel;
import com.zhjt.mogo.adas.data.AdasConstants;
import com.zhjt.mogo.adas.data.bean.AdasParam;
import com.zhjt.mogo.adas.data.bean.ReceivedAck;
@@ -22,7 +23,6 @@ import java.util.Map;
import java.util.Set;
import bag_manager.BagManagerOuterClass;
-import chassis.Chassis;
import chassis.SpecialVehicleTaskCmdOuterClass;
import mogo.telematics.pad.MessagePad;
import mogo.yycp.paralleldriving.protocol.ParallelDrivingRequest;
@@ -169,12 +169,13 @@ public interface IAdasNetCommApi {
* @param mode 1: enter autopilot mode, 0: quit autopilot mode
* @param source 命令来源: 0: pad模拟, 1: pad业务, 2:aicloud, 3:魔方(清扫车MAP Version==332以及MAP Version>=350,其他车型目前未上线)
* @param routeInfo 自动驾驶路径信息
+ * @param cmdInfo 自驾命令信息(订单号,是否首次进自驾等)
* @return 消息是否添加到WS消息发送队列,返回值为非0的正整数时表示下发消息的消息ID和SessionID
* * >=0:表示添加到WS发送消息队列
* * =0:表示乘客屏模式添加到WS发送消息队列
* * -1L:添加到WS发送消息队列失败
*/
- long sendAutoPilotModeReq(int mode, int source, MessagePad.RouteInfo routeInfo);
+ long sendAutoPilotModeReq(int mode, int source, @Nullable MessagePad.RouteInfo routeInfo, @Nullable MessagePad.CmdInfo cmdInfo);
/**
@@ -468,15 +469,15 @@ public interface IAdasNetCommApi {
* 发送 轨迹下载请求
* 此方法存在域控回执,监听{@link OnAdasListener#onReceiveReceivedAck(ReceivedAck)}回调.使用方法:将此方法的返回值与{@link ReceivedAck#getMsgId()}进行比较,如果相同判断{@link ReceivedAck#getStatus()}是否等于{@link ReceivedAck.Status#NORMAL},详情参见CheckSystemView中的onReceiveReceivedAck
*
- * @param line 线路相关参数详情见PB message_pad.proto -> Line
- * @param downloadType 下载类型: 0:正常下载 1:预下载
- * @param routeInfo 20240523 进行自动算路,务必下单时候携带自动驾驶路径信息,否则可不填!
+ * @param line 线路相关参数详情见PB message_pad.proto -> Line
+ * @param downloadType 下载类型: 0:正常下载 1:预下载
+ * @param routeInfo 20240523 进行自动算路,务必下单时候携带自动驾驶路径信息,否则可不填!
* @return 消息是否添加到WS消息发送队列,返回值为非0的正整数时表示下发消息的消息ID
* * >=0:表示添加到WS发送消息队列
* * =0:表示乘客屏模式添加到WS发送消息队列
* * -1L:添加到WS发送消息队列失败
*/
- long sendTrajectoryDownloadReq(MessagePad.Line line, int downloadType, MessagePad.RouteInfo routeInfo);
+ long sendTrajectoryDownloadReq(MessagePad.Line line, int downloadType, MessagePad.RouteInfo routeInfo);
/**
* 发送 状态查询请求
@@ -1241,6 +1242,70 @@ public interface IAdasNetCommApi {
*/
long sendParallelDrivingReq(@NonNull String reqNo, @NonNull ParallelDrivingRequest.ParallelRequest parallelRequest);
+ /**
+ * 发送电源状态查询请求
+ *
+ * @return 消息是否添加到WS消息发送队列,返回值为非0的正整数时表示下发消息的消息ID
+ * * >=0:表示添加到WS发送消息队列
+ * * =0:表示乘客屏模式添加到WS发送消息队列
+ * * -1L:添加到WS发送消息队列失败
+ */
+ long sendPowerUnitSTSRequest();
+
+ /**
+ * 发送单通道电源控制请求
+ *
+ * @param channel 通道
+ * @param cmd 0:关闭;1:打开;
+ * @return 消息是否添加到WS消息发送队列,返回值为非0的正整数时表示下发消息的消息ID
+ * * >=0:表示添加到WS发送消息队列
+ * * =0:表示乘客屏模式添加到WS发送消息队列
+ * * -1L:添加到WS发送消息队列失败
+ */
+ long sendPowerUnitSingleChannelControl(PowerUnitChannel channel, int cmd);
+
+ /**
+ * 发送电源控制重置请求
+ *
+ * @return 消息是否添加到WS消息发送队列,返回值为非0的正整数时表示下发消息的消息ID
+ * * >=0:表示添加到WS发送消息队列
+ * * =0:表示乘客屏模式添加到WS发送消息队列
+ * * -1L:添加到WS发送消息队列失败
+ */
+ long sendPowerUnitReset();
+
+ /**
+ * 查询冷启动状态
+ *
+ * @return 消息是否添加到WS消息发送队列,返回值为非0的正整数时表示下发消息的消息ID
+ * * >=0:表示添加到WS发送消息队列
+ * * =0:表示乘客屏模式添加到WS发送消息队列
+ * * -1L:添加到WS发送消息队列失败
+ */
+ long sendSsmFuncQueryColdStartState();
+
+ /**
+ * 查询自驾命令状态
+ * 查询:是否首次进自驾、订单号、次数
+ *
+ * @return 消息是否添加到WS消息发送队列,返回值为非0的正整数时表示下发消息的消息ID
+ * * >=0:表示添加到WS发送消息队列
+ * * =0:表示乘客屏模式添加到WS发送消息队列
+ * * -1L:添加到WS发送消息队列失败
+ */
+ long sendSsmFuncQueryAutoPilotInfo();
+
+ /**
+ * 查询到站信息
+ *
+ * @param orderId 订单号
+ * @return 消息是否添加到WS消息发送队列,返回值为非0的正整数时表示下发消息的消息ID
+ * * >=0:表示添加到WS发送消息队列
+ * * =0:表示乘客屏模式添加到WS发送消息队列
+ * * -1L:添加到WS发送消息队列失败
+ */
+ long sendSsmFuncQueryAutoPilotStation(@NonNull String orderId);
+
// TODO 需求暂停 待讨论
// boolean getRoutes();
diff --git a/libraries/mogo-adas/src/main/java/com/zhidao/support/adas/high/OnAdasListener.java b/libraries/mogo-adas/src/main/java/com/zhidao/support/adas/high/OnAdasListener.java
index 091535c69a..c58a5e6180 100644
--- a/libraries/mogo-adas/src/main/java/com/zhidao/support/adas/high/OnAdasListener.java
+++ b/libraries/mogo-adas/src/main/java/com/zhidao/support/adas/high/OnAdasListener.java
@@ -7,6 +7,7 @@ import com.google.protobuf.ByteString;
import com.mogo.support.obu.ObuScene;
import com.zhidao.support.adas.high.common.ProtocolStatus;
import com.zhjt.mogo.adas.common.MessageType;
+import com.zhjt.mogo.adas.common.power.PowerProtocolStatus;
import com.zhjt.mogo.adas.data.AdasConstants;
import com.zhjt.mogo.adas.data.AiCloudTask;
import com.zhjt.mogo.adas.data.bean.AdasParam;
@@ -15,6 +16,7 @@ import com.zhjt.mogo.adas.data.bean.LaunchConditionData;
import com.zhjt.mogo.adas.data.bean.NodeStateInfo;
import com.zhjt.mogo.adas.data.bean.ReceivedAck;
import com.zhjt.mogo.adas.data.bean.UnableLaunchReason;
+import com.zhjt.mogo.adas.data.bean.power.PowerData;
import com.zhjt.mogo.adas.data.sweeper.bootable.SweeperBootable;
import com.zhjt.mogo.adas.data.sweeper.task.SweeperTask;
import com.zhjt.mogo.adas.data.sweeper.task.big.SweeperBigTaskStatus;
@@ -205,6 +207,38 @@ public interface OnAdasListener {
@Deprecated
void onWarn(MessagePad.Header header, MessagePad.Warn warn);
+ /**
+ * 冷启动状态变更上报以及查询状态
+ *
+ * @param header 头
+ * @param token 唯一消息ID
+ * @param timestamp 消息发送时间 单位:毫秒
+ * @param isQuery 是否是查询 ture:查询相应的结果 false:表示状态变动域控主动推送
+ * @param coldStartState 数据 null表示 PadSsmMsg中的消息体为null
+ */
+ void onColdStartState(MessagePad.Header header, long token, long timestamp, boolean isQuery, @Nullable SsmInfo.ColdStartState coldStartState);
+
+ /**
+ * 自驾命令状态查询响应
+ * 返回 是否首次进自驾、订单号、次数
+ *
+ * @param header 头
+ * @param token 唯一消息ID
+ * @param timestamp 消息发送时间 单位:毫秒
+ * @param autoPilotInfo 数据 null表示 PadSsmMsg中的消息体为null
+ */
+ void onAutoPilotInfo(MessagePad.Header header, long token, long timestamp, @Nullable SsmInfo.AutoPilotInfo autoPilotInfo);
+
+ /**
+ * 到站信息查询响应
+ *
+ * @param header 头
+ * @param token 唯一消息ID
+ * @param timestamp 消息发送时间 单位:毫秒
+ * @param autoPilotStation 数据 null表示 PadSsmMsg中的消息体为null
+ */
+ void onAutoPilotStation(MessagePad.Header header, long token, long timestamp, @Nullable SsmInfo.AutoPilotStation autoPilotStation);
+
/**
* 到站提醒 自动驾驶站点
*
@@ -538,11 +572,23 @@ public interface OnAdasListener {
/**
* 车道线
*
- * @param header 头
+ * @param header 头
* @param laneMarks 数据
*/
void onLaneMarksTran(@NonNull MessagePad.Header header, @NonNull LaneMarkOuterClass.LaneMarks laneMarks);
+ /**
+ * 电源盒协议接口
+ *
+ * {@link PowerData}使用方法
+ * 1.先判断数据中的{@link PowerData#protocolStatus} 是否是 {@link PowerProtocolStatus#SUCCEED} 如果是则表示数据解析正常可以正常使用,进行下一步
+ * 2.判断 {@link PowerData#frameType} 数据类型
+ *
+ * @param header 头
+ * @param data 数据
+ */
+ void onPowerUnit(@NonNull MessagePad.Header header, @NonNull PowerData data);
+
/**
* 所连接的域控的节点状态信息
* 目前包含状态 节点是否存在;节点是否超时;
diff --git a/libraries/mogo-adas/src/main/java/com/zhidao/support/adas/high/msg/MyMessageFactory.java b/libraries/mogo-adas/src/main/java/com/zhidao/support/adas/high/msg/MyMessageFactory.java
index 1dc44cf498..b221e7746c 100644
--- a/libraries/mogo-adas/src/main/java/com/zhidao/support/adas/high/msg/MyMessageFactory.java
+++ b/libraries/mogo-adas/src/main/java/com/zhidao/support/adas/high/msg/MyMessageFactory.java
@@ -53,6 +53,8 @@ public class MyMessageFactory implements IMyMessageFactory {
private IMsg v2nNioOtherRetrogradeEventMessage;//V2N NIO他车逆行(路侧)
private IMsg v2nNioCongestionEventMessage;//V2N NIO拥堵事件
private IMsg laneMarksTranMessage;//车道线
+ private IMsg powerUnitMessage;//电源模块
+ private IMsg padSsmFuncMsgMessage;//SSM功能
private final AutopilotReview autopilotReview;
private final TurnLightState lightLeft = new TurnLightState();
@@ -303,6 +305,18 @@ public class MyMessageFactory implements IMyMessageFactory {
laneMarksTranMessage = new LaneMarksTranMessage();
}
return laneMarksTranMessage;
+ } else if (messageType == MessageType.TYPE_RECEIVE_POWER_UNIT.typeCode) {
+ //电源模块响应
+ if (powerUnitMessage == null) {
+ powerUnitMessage = new PowerUnitMessage();
+ }
+ return powerUnitMessage;
+ } else if (messageType == MessageType.TYPE_RECEIVE_SSM_FUNC_MSG.typeCode || messageType == MessageType.TYPE_RECEIVE_SSM_FUNC_STATUS_QUERY.typeCode) {
+ //SSM功能
+ if (padSsmFuncMsgMessage == null) {
+ padSsmFuncMsgMessage = new PadSsmFuncMsgMessage();
+ }
+ return padSsmFuncMsgMessage;
} else {
//MessageType.TYPE_DEFAULT.typeCode
return null;
diff --git a/libraries/mogo-adas/src/main/java/com/zhidao/support/adas/high/msg/PadSsmFuncMsgMessage.java b/libraries/mogo-adas/src/main/java/com/zhidao/support/adas/high/msg/PadSsmFuncMsgMessage.java
new file mode 100644
index 0000000000..f9df0a5746
--- /dev/null
+++ b/libraries/mogo-adas/src/main/java/com/zhidao/support/adas/high/msg/PadSsmFuncMsgMessage.java
@@ -0,0 +1,59 @@
+package com.zhidao.support.adas.high.msg;
+
+import android.os.SystemClock;
+
+import com.google.protobuf.ByteString;
+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 system_master.SsmInfo;
+
+/**
+ * SSM功能相关
+ */
+public class PadSsmFuncMsgMessage extends MyAbstractMessageHandler {
+
+ @Override
+ public void handlerMsg(RawData raw, OnAdasListener adasListener) throws InvalidProtocolBufferException {
+ SsmInfo.PadSsmMsg padSsmMsg = SsmInfo.PadSsmMsg.parser().parseFrom(raw.originalData.toByteArray(), raw.getOffsetValue(), raw.getPackageLengthValue() - raw.getOffsetValue());
+ AdasChannel.calculateTimeConsumingOnDispatchRaw("SSM功能", raw.receiveTime);
+ long nowTime = 0;
+ if (CupidLogUtils.isEnableLog())
+ nowTime = SystemClock.elapsedRealtime();
+ SsmInfo.MessageType type = padSsmMsg.getMsgType();
+ ByteString data = padSsmMsg.getData();
+ long timestamp = (long) (padSsmMsg.getTimestamp() * 1000L);
+ if (type == SsmInfo.MessageType.COLD_START_STATUS_REPORT || type == SsmInfo.MessageType.COLD_START_STATE_QUERY) {
+ //冷启动状态上报
+ SsmInfo.ColdStartState coldStartState = null;
+ if (!data.isEmpty()) {
+ coldStartState = SsmInfo.ColdStartState.parseFrom(data);
+ }
+ if (adasListener != null) {
+ adasListener.onColdStartState(raw.getHeader(), padSsmMsg.getToken(), timestamp, type == SsmInfo.MessageType.COLD_START_STATE_QUERY, coldStartState);
+ }
+ } else if (type == SsmInfo.MessageType.AUTO_PILOT_INFO) {
+ //自驾命令状态查询响应
+ SsmInfo.AutoPilotInfo autoPilotInfo = null;
+ if (!data.isEmpty()) {
+ autoPilotInfo = SsmInfo.AutoPilotInfo.parseFrom(data);
+ }
+ if (adasListener != null) {
+ adasListener.onAutoPilotInfo(raw.getHeader(), padSsmMsg.getToken(), timestamp, autoPilotInfo);
+ }
+ } else if (type == SsmInfo.MessageType.STATION_STATUS_QUERY) {
+ //到站信息查询响应
+ SsmInfo.AutoPilotStation autoPilotStation = null;
+ if (!data.isEmpty()) {
+ autoPilotStation = SsmInfo.AutoPilotStation.parseFrom(data);
+ }
+ if (adasListener != null) {
+ adasListener.onAutoPilotStation(raw.getHeader(), padSsmMsg.getToken(), timestamp, autoPilotStation);
+ }
+ }
+ AdasChannel.calculateTimeConsumingBusiness("SSM功能", nowTime);
+ }
+}
diff --git a/libraries/mogo-adas/src/main/java/com/zhidao/support/adas/high/msg/PowerUnitMessage.java b/libraries/mogo-adas/src/main/java/com/zhidao/support/adas/high/msg/PowerUnitMessage.java
new file mode 100644
index 0000000000..6723331fe1
--- /dev/null
+++ b/libraries/mogo-adas/src/main/java/com/zhidao/support/adas/high/msg/PowerUnitMessage.java
@@ -0,0 +1,38 @@
+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.zhidao.support.adas.high.protocol.power.PowerRawUnpack;
+import com.zhjt.mogo.adas.data.bean.power.PowerData;
+
+import okio.ByteString;
+
+/**
+ * 电源管理
+ */
+public class PowerUnitMessage extends MyAbstractMessageHandler {
+ private static final String TAG = PowerUnitMessage.class.getSimpleName();
+ private final PowerRawUnpack unpack = new PowerRawUnpack();
+
+ public PowerUnitMessage() {
+ }
+
+ @Override
+ public void handlerMsg(RawData raw, OnAdasListener adasListener) throws InvalidProtocolBufferException {
+ ByteString data = ByteString.of(raw.originalData.toByteArray(), raw.getOffsetValue(), raw.getPackageLengthValue() - raw.getOffsetValue());
+ PowerData rawData = unpack.unpack(data);
+ AdasChannel.calculateTimeConsumingOnDispatchRaw("电源盒", raw.receiveTime);
+ long nowTime = 0;
+ if (CupidLogUtils.isEnableLog())
+ nowTime = SystemClock.elapsedRealtime();
+ if (adasListener != null) {
+ adasListener.onPowerUnit(raw.getHeader(), rawData);
+ }
+ AdasChannel.calculateTimeConsumingBusiness("电源盒", nowTime);
+ }
+}
diff --git a/libraries/mogo-adas/src/main/java/com/zhidao/support/adas/high/protocol/power/PowerMessageProtocol.java b/libraries/mogo-adas/src/main/java/com/zhidao/support/adas/high/protocol/power/PowerMessageProtocol.java
new file mode 100644
index 0000000000..53ec9a9c64
--- /dev/null
+++ b/libraries/mogo-adas/src/main/java/com/zhidao/support/adas/high/protocol/power/PowerMessageProtocol.java
@@ -0,0 +1,92 @@
+package com.zhidao.support.adas.high.protocol.power;
+
+
+/**
+ * 电源管理协议
+ */
+public class PowerMessageProtocol {
+ public static final int FRAME_HEAD = 0xAA55;
+ public static final int CHANNEL_NORMAL_END_INDEX = 46;//普通通道最大索引值(包含46)
+ public static final int CHANNEL_CAMERA_START_INDEX = 51;//相机通道最小索引值(包含51)
+ public static final byte KEY_SEND = 0x4D;
+ public static final byte KEY_RECEIVE = 0x47;
+
+ public static void xor(byte[] data,byte key) {
+ for (int i = 0; i < data.length; i++) {
+ data[i] ^= key;
+ }
+ }
+
+
+ /**
+ * 帧头长度
+ * 固定为:0xAA55
+ *
+ * @return 字节个数
+ */
+
+ public int getFrameHeaderLength() {
+ return 2;
+ }
+
+
+ /**
+ * 帧总长度长度
+ * 最小值:12,对应于数据区长度为0的帧
+ *
+ * @return 字节个数
+ */
+
+ public int getTotalLengthLength() {
+ return 2;
+ }
+
+ /**
+ * 帧类型长度,(0x0000:保留,0xFFFF:保留)
+ * 客户端STS请求帧:0x0040,服务器响应正常帧:0x0840
+ * 客户端CMD请求帧:0x0044,服务器响应正常帧:0x0844
+ * 服务器检测到帧异常,响应异常ERR帧:0x0800
+ *
+ * @return 字节个数
+ */
+
+ public int getFrameTypeLength() {
+ return 2;
+ }
+
+
+ /**
+ * 保留字节长度
+ * 定为:0x0000
+ *
+ * @return 字节个数
+ */
+ public int getReservedLength() {
+ return 2;
+ }
+
+ /**
+ * 数据区长度
+ * 数据区长度必须为4的整倍数,可为0字节
+ *
+ * @param totalLength 数据包总长度
+ * @return 字节个数
+ */
+
+ public int getDataBlocksLength(int totalLength) {
+ return totalLength - getFrameHeaderLength() - getTotalLengthLength() - getFrameTypeLength() - getReservedLength() - getCheckValueLength();
+ }
+
+ /**
+ * 帧校验值长度,对校验值之前的所有数据进行校验,
+ * 校验值计算初步定为:
+ * 1:帧所有数据分割成32位长(4字节)的块;
+ * 2:对这些32位长的块进行二进制"异或"操作;
+ * 3:取"异或"操作的结果作为校验值。
+ *
+ * @return 字节个数
+ */
+ public int getCheckValueLength() {
+ return 4;
+ }
+}
diff --git a/libraries/mogo-adas/src/main/java/com/zhidao/support/adas/high/protocol/power/PowerRawPack.java b/libraries/mogo-adas/src/main/java/com/zhidao/support/adas/high/protocol/power/PowerRawPack.java
new file mode 100644
index 0000000000..e5e757fc1e
--- /dev/null
+++ b/libraries/mogo-adas/src/main/java/com/zhidao/support/adas/high/protocol/power/PowerRawPack.java
@@ -0,0 +1,72 @@
+package com.zhidao.support.adas.high.protocol.power;
+
+import androidx.annotation.NonNull;
+import androidx.annotation.Nullable;
+
+import com.zhjt.mogo.adas.common.power.PowerFrameType;
+import com.zhjt.mogo.adas.utils.ByteUtil;
+
+/**
+ * 数据打包
+ */
+public class PowerRawPack {
+ private static final String TAG = PowerRawPack.class.getSimpleName();
+ private final PowerMessageProtocol messageProtocol;
+ private final byte[] reservedData;
+
+
+ public PowerRawPack() {
+ messageProtocol = new PowerMessageProtocol();
+ reservedData = new byte[messageProtocol.getReservedLength()];
+ }
+
+
+ public synchronized byte[] pack(@NonNull PowerFrameType frameType, @Nullable byte[] data) {
+ if (frameType == PowerFrameType.UNKNOWN) return null;
+ int dataBlocksLength = 0;
+ if (data != null && data.length != 0) {
+ dataBlocksLength = data.length;
+ }
+ //除校验位4个字节所有的长度
+ int packageLength = messageProtocol.getFrameHeaderLength() + messageProtocol.getTotalLengthLength() + messageProtocol.getFrameTypeLength() + messageProtocol.getReservedLength() + dataBlocksLength;
+ byte[] msg = new byte[packageLength];
+ byte[] frameHeadData = ByteUtil.set16bitUnsignedValueLittleEndian(PowerMessageProtocol.FRAME_HEAD);
+ //添加帧头
+ System.arraycopy(frameHeadData, 0, msg, 0, messageProtocol.getFrameHeaderLength());
+
+ byte[] packageLengthData = ByteUtil.set16bitUnsignedValueLittleEndian(packageLength + messageProtocol.getCheckValueLength());
+ //添加总长度
+ System.arraycopy(packageLengthData, 0, msg, messageProtocol.getFrameHeaderLength(), messageProtocol.getTotalLengthLength());
+
+ byte[] type = ByteUtil.set16bitUnsignedValueLittleEndian(frameType.type);
+ //添加帧类型
+ System.arraycopy(type, 0, msg, messageProtocol.getFrameHeaderLength() + messageProtocol.getTotalLengthLength(), messageProtocol.getFrameTypeLength());
+
+ //添加保留位
+ System.arraycopy(reservedData, 0, msg, messageProtocol.getFrameHeaderLength() + messageProtocol.getTotalLengthLength() + messageProtocol.getFrameTypeLength(), messageProtocol.getReservedLength());
+
+ if (data != null && data.length != 0) {
+ PowerMessageProtocol.xor(data, PowerMessageProtocol.KEY_SEND);
+ System.arraycopy(data, 0, msg, messageProtocol.getFrameHeaderLength() + messageProtocol.getTotalLengthLength() + messageProtocol.getFrameTypeLength() + messageProtocol.getReservedLength(), data.length);
+ }
+ int xor = xorCheck(msg);
+
+ return ByteUtil.concatBytes(msg, ByteUtil.set32bitUnsignedValueValueLittleEndian(xor));
+ }
+
+ //异或校验
+ private int xorCheck(byte[] bytes) {
+ int xorChecksum = 0;
+ //异或校验
+ for (int i = 0; i < bytes.length; i += 4) {
+ byte[] tInt = new byte[4];
+ tInt[0] = bytes[i];
+ tInt[1] = bytes[i + 1];
+ tInt[2] = bytes[i + 2];
+ tInt[3] = bytes[i + 3];
+ int datum = ByteUtil.get32bitUnsignedValueLittleEndian(tInt);
+ xorChecksum ^= datum; // 对每个字节进行异或操作
+ }
+ return xorChecksum;
+ }
+}
diff --git a/libraries/mogo-adas/src/main/java/com/zhidao/support/adas/high/protocol/power/PowerRawUnpack.java b/libraries/mogo-adas/src/main/java/com/zhidao/support/adas/high/protocol/power/PowerRawUnpack.java
new file mode 100644
index 0000000000..6b5d2f2e0f
--- /dev/null
+++ b/libraries/mogo-adas/src/main/java/com/zhidao/support/adas/high/protocol/power/PowerRawUnpack.java
@@ -0,0 +1,290 @@
+package com.zhidao.support.adas.high.protocol.power;
+
+
+import androidx.annotation.NonNull;
+
+import com.zhjt.mogo.adas.common.power.PowerControlType;
+import com.zhjt.mogo.adas.common.power.PowerError;
+import com.zhjt.mogo.adas.common.power.PowerFrameType;
+import com.zhjt.mogo.adas.common.power.PowerProtocolStatus;
+import com.zhjt.mogo.adas.common.power.PowerUnitChannel;
+import com.zhjt.mogo.adas.data.bean.power.PowerCommandExecuteState;
+import com.zhjt.mogo.adas.data.bean.power.PowerData;
+import com.zhjt.mogo.adas.data.bean.power.PowerErrorData;
+import com.zhjt.mogo.adas.data.bean.power.PowerUnitState;
+import com.zhjt.mogo.adas.utils.ByteUtil;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import okio.ByteString;
+
+/**
+ * 电源管理数据拆包
+ */
+public class PowerRawUnpack {
+ private static final String TAG = PowerRawUnpack.class.getSimpleName();
+ private final PowerMessageProtocol messageProtocol;
+
+
+ public PowerRawUnpack() {
+ messageProtocol = new PowerMessageProtocol();
+ }
+
+ public PowerData unpack(@NonNull ByteString bytes) {
+ byte[] data = bytes.toByteArray();
+ int size = bytes.size();
+ if (size == 0) {
+ return PowerData.createError(data, PowerProtocolStatus.CHECK_FAILED_PACKAGE_LENGTH);
+ }
+ if (size % 4 != 0) {
+ return PowerData.createError(data, PowerProtocolStatus.DATA_LENGTH_NOT_NOTE_OF4);
+ }
+ int frameHeaderLength = messageProtocol.getFrameHeaderLength();
+ int totalLengthLength = messageProtocol.getTotalLengthLength();
+ int frameTypeLength = messageProtocol.getFrameTypeLength();
+ int reservedLength = messageProtocol.getReservedLength();
+ int checkValueLength = messageProtocol.getCheckValueLength();
+ try {
+ int localXor = xorCheck(bytes, checkValueLength);
+// Log.i(TAG, "计算得出的异域校验值=" + localXor);
+ ByteString xor = bytes.substring(size - checkValueLength, size);
+ int serverXor = ByteUtil.get32bitUnsignedValueLittleEndian(xor.toByteArray());
+// Log.i(TAG, "数据中的异域校验值=" + serverXor);
+ if (localXor != serverXor) {
+ return PowerData.createError(data, PowerProtocolStatus.XOR_CHECK_FAILED);
+ }
+ //读取FrameHeader
+ ByteString frameHeaderByteString;
+ if (size < frameHeaderLength) {
+ frameHeaderByteString = bytes;
+ } else {
+ frameHeaderByteString = bytes.substring(0, frameHeaderLength);
+ }
+ int frameHeader = ByteUtil.get16bitUnsignedValueLittleEndian(frameHeaderByteString.toByteArray());
+// Log.w(TAG, "WS frameHeader=" + frameHeaderByteString.hex());
+// Log.w(TAG, "WS frameHeader=" + frameHeader);
+ if (frameHeader == PowerMessageProtocol.FRAME_HEAD) {
+ ByteString totalLengthByteString = bytes.substring(frameHeaderLength, frameHeaderLength + totalLengthLength);
+ int totalLength = ByteUtil.get16bitUnsignedValueLittleEndian(totalLengthByteString.toByteArray());
+// Log.w(TAG, "WS TotalLength=" + totalLength);
+ if (size != totalLength) {
+ return PowerData.createError(data, PowerProtocolStatus.CHECK_FAILED_PACKAGE_LENGTH);
+ }
+ ByteString frameTypeByteString = bytes.substring(frameHeaderLength + totalLengthLength, frameHeaderLength + totalLengthLength + frameTypeLength);
+ int typeValue = ByteUtil.get16bitUnsignedValueLittleEndian(frameTypeByteString.toByteArray());
+ PowerFrameType frameType = PowerFrameType.getPowerFrameType(typeValue);
+// Log.w(TAG, "WS FrameType=" + frameType);
+ if (frameType == PowerFrameType.UNKNOWN) {
+ return PowerData.createError(data, PowerProtocolStatus.POWER_FRAME_TYPE_UNKNOWN);
+ }
+ ByteString reservedByteString = bytes.substring(frameHeaderLength + totalLengthLength + frameTypeLength, frameHeaderLength + totalLengthLength + frameTypeLength + reservedLength);
+ int reserved = ByteUtil.get16bitUnsignedValueLittleEndian(reservedByteString.toByteArray());
+ int dataBlocksLength = messageProtocol.getDataBlocksLength(totalLength);
+ ByteString dataBlocksByteString = bytes.substring(frameHeaderLength + totalLengthLength + frameTypeLength + reservedLength, frameHeaderLength + totalLengthLength + frameTypeLength + reservedLength + dataBlocksLength);
+ byte[] dataBlocks = dataBlocksByteString.toByteArray();
+ PowerMessageProtocol.xor(dataBlocks, PowerMessageProtocol.KEY_RECEIVE);
+ dataBlocksByteString = ByteString.of(dataBlocks);
+// Log.i(TAG, dataBlocks.length + " 负载数据=" + ByteUtil.byteArrToHex(dataBlocks));
+ PowerErrorData errorData = null;
+ List