[630][adas] 特种车辆命令下发添加数据来源,增加回执功能,MAP380开始支持

This commit is contained in:
xinfengkun
2024-02-27 20:23:58 +08:00
parent a79598bd57
commit 90c14abd8b
30 changed files with 1326 additions and 519 deletions

View File

@@ -57,7 +57,7 @@ import com.zhidao.support.adas.high.chain.AdasChain
import com.zhidao.support.adas.high.common.Constants
import com.zhidao.support.adas.high.common.Constants.IPC_CONNECTION_STATUS
import com.zhidao.support.adas.high.common.CupidLogUtils
import com.zhidao.support.adas.high.common.MessageType
import com.zhjt.mogo.adas.common.MessageType
import com.zhjt.mogo.adas.data.AdasConstants
import com.zhjt.mogo.adas.data.bean.MogoReport
import com.zhjt.mogo.adas.data.sweeper.bootable.SweeperBootable
@@ -98,6 +98,7 @@ class MoGoAutopilotControlProvider :
override fun init(context: Context) {
CallerLogger.i("$M_D_C$TAG", "初始化工控机连接……")
mContext = context
AdasManager.getInstance().init(context)
runCatching {
// 初始化ADAS 域控制器
CupidLogUtils.setEnableLog(false)
@@ -115,15 +116,15 @@ class MoGoAutopilotControlProvider :
// .setMessageTypes(messageTypes).build()
// "192.168.1.102"
val options = AdasOptions.Builder()
.setIpcConnectionMode(AdasOptions.IPC_CONNECTION_MODE.FIXATION)
.setIpcFixationIP(AdasManager.getInstance().getIPCFixationIPList(mContext))
.setClient(false)
val options = AdasOptions.newBuilder()
.setConnectionMode(AdasOptions.IPC_CONNECTION_MODE.PING)
.setPingAddressList(AdasManager.getInstance().ipcFixationIPList)
.setPassenger(false)
.setUnableLaunchAutopilotGear(FunctionBuildConfig.unableLaunchAutopilotGear)
// .setSubscribeInterfaceOptions(subscribeInterfaceOptions)//
.build()
AdasManager.getInstance().create(context, options, MoGoAdasMsgConnectStatusListenerImpl())
AdasManager.getInstance().create(options, MoGoAdasMsgConnectStatusListenerImpl())
//////////////////////////////////注意先后顺序AdasManager.getInstance().create后才可以设置监听/////////////////////////////////////////////
// 监听ADAS-SDK获取到的工控机数据
AdasManager.getInstance().setOnAdasListener(MoGoAdasListenerImpl())
@@ -213,12 +214,12 @@ class MoGoAutopilotControlProvider :
directConnect(context)
} else {
val options = AdasOptions
.Builder()
.setClient(true)
.newBuilder()
.setPassenger(true)
.setUnableLaunchAutopilotGear(FunctionBuildConfig.unableLaunchAutopilotGear)
.build()
AdasManager.getInstance()
.create(context, options, MoGoAdasMsgConnectStatusListenerImpl())
.create(options, MoGoAdasMsgConnectStatusListenerImpl())
// 监听ADAS-SDK获取到的工控机数据
AdasManager.getInstance().setOnAdasListener(MoGoAdasListenerImpl())
// 接收司机屏发过来的感知、定位等数据
@@ -243,13 +244,13 @@ class MoGoAutopilotControlProvider :
private fun directConnect(context: Context) {
val options = AdasOptions
.Builder()
.setIpcConnectionMode(AdasOptions.IPC_CONNECTION_MODE.FIXATION)
.setIpcFixationIP(AdasManager.getInstance().getIPCFixationIPList(mContext))
.setClient(false)// 乘客端直连工控机改为false
.newBuilder()
.setConnectionMode(AdasOptions.IPC_CONNECTION_MODE.PING)
.setPingAddressList(AdasManager.getInstance().ipcFixationIPList)
.setPassenger(false)// 乘客端直连工控机改为false
.setUnableLaunchAutopilotGear(FunctionBuildConfig.unableLaunchAutopilotGear)
.build()
AdasManager.getInstance().create(context, options, MoGoAdasMsgConnectStatusListenerImpl())
AdasManager.getInstance().create(options, MoGoAdasMsgConnectStatusListenerImpl())
//////////////////////////////////注意先后顺序AdasManager.getInstance().create后才可以设置监听/////////////////////////////////////////////
// 监听ADAS-SDK获取到的工控机数据
AdasManager.getInstance().setOnAdasListener(MoGoAdasListenerImpl())
@@ -303,12 +304,19 @@ class MoGoAutopilotControlProvider :
SharedPrefsMgr.getInstance().putString(MoGoConfig.AUTOPILOT_IP, autoPilotIp)
}
// 设置IP地址
AdasManager.getInstance().adasOptions.isClient = false
AdasManager.getInstance().adasOptions.ipcConnectionMode =
AdasOptions.IPC_CONNECTION_MODE.ASSIGN
AdasManager.getInstance().adasOptions.ipcAssignIP = autoPilotIp
// 打开通讯连接
AdasManager.getInstance().connect()
val options = AdasOptions.newBuilder()
.setPassenger(false)
.setConnectionMode(AdasOptions.IPC_CONNECTION_MODE.SPECIFIED)
.setSpecifiedAddress(autoPilotIp)
.build()
AdasManager.getInstance().create(options, MoGoAdasMsgConnectStatusListenerImpl())
// AdasManager.getInstance().adasOptions.isClient = false
// AdasManager.getInstance().adasOptions.ipcConnectionMode =
// AdasOptions.IPC_CONNECTION_MODE.ASSIGN
// AdasManager.getInstance().adasOptions.ipcAssignIP = autoPilotIp
// // 打开通讯连接
// AdasManager.getInstance().connect()
return ""
}

View File

@@ -60,6 +60,7 @@ import com.zhjt.mogo.adas.data.bean.AdasParam
import com.zhidao.support.adas.high.common.ProtocolStatus
import com.zhjt.mogo.adas.data.AiCloudTask
import com.zhjt.mogo.adas.data.bean.AutopilotStatistics
import com.zhjt.mogo.adas.data.bean.ReceivedAck
import com.zhjt.mogo.adas.data.bean.UnableLaunchData
import com.zhjt.mogo.adas.data.bean.UnableLaunchReason
import com.zhjt.mogo.adas.data.sweeper.bootable.SweeperBootable
@@ -930,6 +931,16 @@ class MoGoAdasListenerImpl : OnAdasListener {
CallerParallelDrivingActionsListenerManager.invokeParallelDrivingAbility(isParallelDrivingAbility)
}
/**
* 回执消息
* PAD发送数据到域控的回执消息是否存在回执详情参见{@link MessageType} 枚举 TYPE_SEND_XXX_XXX 消息回执超时时间大于0的表示需要回执
*
* @param receivedAck 回执
*/
override fun onReceiveReceivedAck(receivedAck: ReceivedAck) {
CallerReceiveReceivedAckListenerManager.invokeReceiveReceivedAck(receivedAck)
}
@ChainLog(
linkChainLog = CHAIN_TYPE_SOCKET_AUTOPILOT,
linkCode = CHAIN_SOURCE_ADAS,

View File

@@ -0,0 +1,17 @@
package com.mogo.eagle.core.function.api.autopilot
import com.zhjt.mogo.adas.data.bean.ReceivedAck
/**
* 回执消息
* PAD发送数据到域控的回执消息是否存在回执详情参见{@link MessageType} 枚举 TYPE_SEND_XXX_XXX 消息回执超时时间大于0的表示需要回执
*/
interface IMoGoReceiveReceivedAckListener {
/**
* 回执消息
*
* @param receivedAck 回执
*/
fun onReceiveReceivedAck(receivedAck: ReceivedAck)
}

View File

@@ -0,0 +1,22 @@
package com.mogo.eagle.core.function.call.autopilot
import com.mogo.eagle.core.function.api.autopilot.IMoGoReceiveReceivedAckListener
import com.mogo.eagle.core.function.call.base.CallerBase
import com.zhjt.mogo.adas.data.bean.ReceivedAck
/**
* 回执消息
* PAD发送数据到域控的回执消息是否存在回执详情参见{@link MessageType} 枚举 TYPE_SEND_XXX_XXX 消息回执超时时间大于0的表示需要回执
*/
object CallerReceiveReceivedAckListenerManager : CallerBase<IMoGoReceiveReceivedAckListener>() {
/**
* 金旅M1
*/
fun invokeReceiveReceivedAck(receivedAck: ReceivedAck) {
M_LISTENERS.forEach {
val listener = it.value
listener.onReceiveReceivedAck(receivedAck)
}
}
}

View File

@@ -1,13 +1,11 @@
package com.zhidao.support.adas.high.common;
package com.zhjt.mogo.adas.common;
import mogo.telematics.pad.MessagePad;
/**
* 工控机发送或接收的类型
* 工控机接收接口必须包含TYPE_RECEIVE
* 目前收发相同的Type
* * MessagePad.MessageType.MsgTypeBagManagerCmd
* * MessagePad.MessageType.MsgTypeTaskCmd
* 工控机接收接口必须包含TYPE_RECEIVE
* 消息回执文档http://wiki.zhidaohulian.com/pages/viewpage.action?pageId=119731359
*
* @author nie yunlong
* @description 请求值
@@ -35,14 +33,14 @@ public enum MessageType {
TYPE_RECEIVE_BASIC_INFO_REQ(MessagePad.MessageType.MsgTypeBasicInfoReq, "自动驾驶设备基础信息请求"),
TYPE_SEND_BASIC_INFO_RESP(MessagePad.MessageType.MsgTypeBasicInfoResp, "自动驾驶设备基础信息应答"),
TYPE_SEND_SET_AUTOPILOT_MODE_REQ(MessagePad.MessageType.MsgTypeSetAutopilotModeReq, "设置自动驾驶模式 启动自动驾驶"),
TYPE_SEND_SET_DEMO_MODE_REQ(MessagePad.MessageType.MsgTypeSetDemoModeReq, "设置演示模式"),
TYPE_SEND_SET_AUTOPILOT_MODE_REQ(MessagePad.MessageType.MsgTypeSetAutopilotModeReq, "设置自动驾驶模式 启动自动驾驶", 5000),
TYPE_SEND_SET_DEMO_MODE_REQ(MessagePad.MessageType.MsgTypeSetDemoModeReq, "设置演示模式", 5000),
TYPE_SEND_CAR_CONFIG_REQ(MessagePad.MessageType.MsgTypeCarConfigReq, "车机基础信息请求"),
TYPE_RECEIVE_CAR_CONFIG_RESP(MessagePad.MessageType.MsgTypeCarConfigResp, "车机基础信息应答"),
TYPE_SEND_RECORD_CAUSE(MessagePad.MessageType.MsgTypeRecordCause, "记录人工接管原因"),
TYPE_SEND_RECORD_DATA(MessagePad.MessageType.MsgTypeRecordData, "数据采集请求"),
TYPE_RECEIVE_RECORD_RESULT(MessagePad.MessageType.MsgTypeRecordResult, "数据采集结果"),
TYPE_SEND_SET_AUTOPILOT_SPEED_REQ(MessagePad.MessageType.MsgTypeSetAutopilotSpeedReq, "设置自动驾驶最大速度"),
TYPE_SEND_SET_AUTOPILOT_SPEED_REQ(MessagePad.MessageType.MsgTypeSetAutopilotSpeedReq, "设置自动驾驶最大速度", 5000),
TYPE_SEND_GLOBAL_PATH_REQ(MessagePad.MessageType.MsgTypeGlobalPathReq, "自动驾驶路径请求"),
TYPE_RECEIVE_GLOBAL_PATH_RESP(MessagePad.MessageType.MsgTypeGlobalPathResp, "自动驾驶路径应答"),
@Deprecated//MAP290开始此接口弃用
@@ -50,32 +48,38 @@ public enum MessageType {
@Deprecated
TYPE_RECEIVE_WARN(MessagePad.MessageType.MsgTypeWarn, "预警数据"),
TYPE_RECEIVE_ARRIVAL_NOTIFICATION(MessagePad.MessageType.MsgTypeArrivalNotification, "到站提醒"),
TYPE_SEND_SYSTEM_CMD_REQ(MessagePad.MessageType.MsgTypeSystemCmdReq, "系统命令请求, 比如系统重启,启用新镜像"),
TYPE_SEND_TRAJECTORY_DOWNLOAD_REQ(MessagePad.MessageType.MsgTypeTrajectoryDownloadReq, "轨迹下载请求"),
TYPE_SEND_SYSTEM_CMD_REQ(MessagePad.MessageType.MsgTypeSystemCmdReq, "系统命令请求", 5000),
TYPE_SEND_TRAJECTORY_DOWNLOAD_REQ(MessagePad.MessageType.MsgTypeTrajectoryDownloadReq, "轨迹下载请求", 5000),
@Deprecated//HQM1 MAP350开始弃用其他车型MAP360开始弃用
TYPE_SEND_STATUS_QUERY_REQ(MessagePad.MessageType.MsgTypeStatusQueryReq, "状态查询请求"),
@Deprecated//HQM1 MAP350开始弃用其他车型MAP360开始弃用
TYPE_RECEIVE_STATUS_QUERY_RESP(MessagePad.MessageType.MsgTypeStatusQueryResp, "状态查询应答"),
TYPE_SEND_SET_RAIN_MODE_REQ(MessagePad.MessageType.MsgTypeSetRainModeReq, "设置雨天模式"),
TYPE_SEND_SET_RAIN_MODE_REQ(MessagePad.MessageType.MsgTypeSetRainModeReq, "设置雨天模式", 5000),
TYPE_SEND_RECORD_DATA_CONFIG_REQ(MessagePad.MessageType.MsgTypeRecordDataConfigReq, "数据采集配置查询"),
TYPE_RECEIVE_RECORD_DATA_CONFIG_RESP(MessagePad.MessageType.MsgTypeRecordDataConfigResp, "数据采集配置"),
TYPE_SEND_OPERATOR_CMD_REQ(MessagePad.MessageType.MsgTypeOperatorCmdReq, "操控指令"),
TYPE_SEND_SUBSCRIBE_DATA_REQ(MessagePad.MessageType.MsgTypeSubscribeDataReq, "数据订阅、取消订阅请求"),
TYPE_SEND_SPECIAL_VEHICLE_TASK_CMD(MessagePad.MessageType.MsgTypeSpecialVehicleTaskCmd, "特种车辆命令"),
TYPE_SEND_SET_PARAM_REQ(MessagePad.MessageType.MsgTypeSetParamReq, "设置参数命令"),
TYPE_SEND_OPERATOR_CMD_REQ(MessagePad.MessageType.MsgTypeOperatorCmdReq, "操控指令", 5000),
TYPE_SEND_SUBSCRIBE_DATA_REQ(MessagePad.MessageType.MsgTypeSubscribeDataReq, "数据订阅、取消订阅请求", 5000),
TYPE_SEND_SPECIAL_VEHICLE_TASK_CMD(MessagePad.MessageType.MsgTypeSpecialVehicleTaskCmd, "特种车辆命令", 5000),
TYPE_SEND_SET_PARAM_REQ(MessagePad.MessageType.MsgTypeSetParamReq, "设置参数命令", 5000),
TYPE_SEND_TRIP_INFO_REQ(MessagePad.MessageType.MsgTypeTripInfoEvent, "行程信息"),
TYPE_SEND_BAG_MANAGER_CMD(MessagePad.MessageType.MsgTypeBagManagerCmd, "Bag管理请求"),
TYPE_RECEIVE_BAG_MANAGER_CMD(MessagePad.MessageType.MsgTypeBagManagerCmd, "Bag管理应答"),
TYPE_SEND_PLANNING_CMD(MessagePad.MessageType.MsgTypePlanningCmd, "给Planning指令"),
TYPE_SEND_SET_PARAM_REQ_V2(MessagePad.MessageType.MsgTypeSetParamReqV2, "设置参数命令V2"),
TYPE_SEND_PLANNING_CMD(MessagePad.MessageType.MsgTypePlanningCmd, "给Planning指令", 5000),
TYPE_SEND_SET_PARAM_REQ_V2(MessagePad.MessageType.MsgTypeSetParamReqV2, "设置参数命令V2", 5000),
TYPE_RECEIVE_V2N_CONGESTION_EVENT(MessagePad.MessageType.MsgTypeV2nCongestionEvent, "主车附近事件推送"),
TYPE_RECEIVE_V2N_GLOBAL_PATH_EVENTS(MessagePad.MessageType.MsgTypeV2nGlobalPathEvents, "主车路径全局事件推送"),
TYPE_SEND_GET_PARAM_REQ(MessagePad.MessageType.MsgTypeGetParamReq, "参数获取请求"),
TYPE_RECEIVE_GET_PARAM_RESP(MessagePad.MessageType.MsgTypeGetParamResp, "参数获取应答"),
TYPE_SEND_SWEEPER_CLOUD_TASK_CMD(MessagePad.MessageType.MsgTypeTaskCmd, "发送清扫车指令到云控"),
TYPE_RECEIVE_SWEEPER_CLOUD_TASK_CMD(MessagePad.MessageType.MsgTypeTaskCmd, "云控下发清扫车任务指令"),
TYPE_SEND_SWEEPER_CLOUD_TASK_CMD(MessagePad.MessageType.MsgTypeTaskCmd, "发送清扫车指令到云控", 5000),
TYPE_RECEIVE_SWEEPER_CLOUD_TASK_CMD(MessagePad.MessageType.MsgTypeTaskCmd, "云控下发清扫车任务指令", 5000),
TYPE_SEND_FSM_STATUS_REASON_QUERY_REQ(MessagePad.MessageType.MsgTypeFSMStatusReasonQueryReq, "FSM状态原因查询"),
TYPE_RECEIVE_FSM_STATUS_REASON_QUERY_RESP(MessagePad.MessageType.MsgTypeFSMStatusReasonQueryResp, "FSM状态原因查询应答"),
TYPE_SEND_PARALLEL_DRIVING_REQ(MessagePad.MessageType.MsgTypeParallelDrivingCmd, "平行驾驶请求"),
TYPE_RECEIVE_PARALLEL_DRIVING_STATUS(MessagePad.MessageType.MsgTypeParallelDrivingCmd, "平行驾驶状态"),
TYPE_SEND_GET_DEBUG_INFO_REQ(MessagePad.MessageType.MsgTypeGetDebugInfo, "Debug信息请求"),
TYPE_RECEIVE_GET_DEBUG_INFO_RESP(MessagePad.MessageType.MsgTypeGetDebugInfo, "Debug信息应答"),
TYPE_SEND_PARALLEL_DRIVING_REQ(MessagePad.MessageType.MsgTypeParallelDrivingCmd, "平行驾驶请求", 5000),
TYPE_RECEIVE_PARALLEL_DRIVING_STATUS(MessagePad.MessageType.MsgTypeParallelDrivingCmd, "平行驾驶状态", 5000),
TYPE_SEND_RECEIVED_ACK(MessagePad.MessageType.MsgTypeReceivedAck, "发送消息回执"),
TYPE_RECEIVE_RECEIVED_ACK(MessagePad.MessageType.MsgTypeReceivedAck, "接收消息回执"),
//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, "清扫车指标数据"),
@@ -92,9 +96,19 @@ public enum MessageType {
*/
public final String desc;
/**
* 消息回执超时时间 毫秒 0表示不需要回执
*/
public final long timeoutMillis;
MessageType(MessagePad.MessageType typeCode, String desc) {
this(typeCode, desc, 0);
}
MessageType(MessagePad.MessageType typeCode, String desc, long timeoutMillis) {
this.typeCode = typeCode;
this.desc = desc;
this.timeoutMillis = timeoutMillis;
}

View File

@@ -0,0 +1,85 @@
package com.zhjt.mogo.adas.data.bean;
import com.google.protobuf.TextFormat;
import com.zhjt.mogo.adas.common.MessageType;
import com.zhjt.mogo.adas.utils.ByteUtil;
import mogo.telematics.pad.MessagePad;
/**
* 消息回执
*/
public class ReceivedAck {
/**
* 是否超时,如果超时 receiveTime和receivedAck不会被赋值
* 超时时间定义在{@link MessageType}中,根据定义的超时时间实际返回的超时时间 ±1 秒内
*/
private boolean isTimeout = false;
private final long sendTime;//数据发送时间
private long receiveTime;//回执接收时间
private final long msgId;//消息ID
private final MessageType messageType;//具体消息
private final byte[] sendData;//发送的数据
private MessagePad.ReceivedAck receivedAck;//回执的数据
public ReceivedAck(long sendTime, long msgId, MessageType messageType, byte[] sendData) {
this.sendTime = sendTime;
this.msgId = msgId;
this.messageType = messageType;
this.sendData = sendData;
}
public boolean isTimeout() {
return isTimeout;
}
public void setTimeout(boolean timeout) {
isTimeout = timeout;
}
public long getSendTime() {
return sendTime;
}
public long getReceiveTime() {
return receiveTime;
}
public void setReceiveTime(long receiveTime) {
this.receiveTime = receiveTime;
}
public long getMsgId() {
return msgId;
}
public MessageType getMessageType() {
return messageType;
}
public byte[] getSendData() {
return sendData;
}
public MessagePad.ReceivedAck getReceivedAck() {
return receivedAck;
}
public void setReceivedAck(MessagePad.ReceivedAck receivedAck) {
this.receivedAck = receivedAck;
}
@Override
public String toString() {
return "{" +
"是否超时=" + isTimeout +
", 发送时间=" + sendTime +
", 接收时间=" + receiveTime +
", 消息ID=" + msgId +
", 消息类型=" + messageType +
", 发送数据=" + (sendData == null ? null : ByteUtil.byteArrToHex(sendData)) +
", 回执数据=" + (receivedAck == null ? null : TextFormat.printer().escapingNonAscii(false).printToString(receivedAck)) +
'}';
}
}

View File

@@ -13,28 +13,30 @@ enum MessageType
{
MsgTypeDefault = 0;
MsgTypePlanningDecisionState = 0x00001; //planning决策状态, 透传
MsgTypeSweeperTaskIndexData = 0x00002; //清扫车指标数据
MsgTypeObuWarningData = 0x00003; //obu预警事件
//透传消息列表,不需要明确消息定义, 仅作记录,供鹰眼使用
MsgTypePlanningDecisionState = 0x00001; //planning决策状态, 透传 定频10hz
MsgTypeSweeperTaskIndexData = 0x00002; //清扫车指标数据 定频10hz
MsgTypeObuWarningData = 0x00003; //obu预警事件 不定频
MsgTypeTrajectory = 0x10000; //局部轨迹,车前引导线
MsgTypeTrackedObjects = 0x10001; //障碍物信息
MsgTypeGnssInfo = 0x10002; //惯导信息
MsgTypeVehicleState = 0x10003; //底盘信息, 透传底盘状态pb参考底盘
MsgTypeAutopilotState = 0x10004; //自动驾驶状态
MsgTypeReportMessage = 0x10005; //监控事件报告
MsgTypePerceptionTrafficLight = 0x10006; //感知红绿灯
MsgTypePredictionObstacleTrajectory = 0x10007; //他车轨迹预测
MsgTypePointCloud = 0x10008; //点云透传
MsgTypePlanningObjects = 0x10009; //planning障碍物
MsgTypeOBU = 0x1000a; //OBU
MsgTypeChassisStates = 0x1000b; //重构后的底盘状态, 透传
MsgTypeFunctionStates = 0x1000c; //重构后的功能状态, 透传
MsgTypeBackCameraVideo = 0x1000d; //后部摄像头视频 10hz
MsgTypeM1StitchedVideo = 0x1000e; //m1拼接视频 10hz
MsgTypeSSMState = 0x1000f; //ssm 系统状态 1hz hq m1 MAP350开始支持其他车型MAP360开始支持
MsgTypeFMState = 0x10010; //FM状态 1hz bus和清扫车是MAP370开始支持其他车型MAP360开始支持
MsgTypeTrajectory = 0x10000; //局部轨迹,车前引导线 定频10hz
MsgTypeTrackedObjects = 0x10001; //障碍物信息 定频10hz
MsgTypeGnssInfo = 0x10002; //惯导信息 定频20hz
MsgTypeVehicleState = 0x10003; //底盘信息, 透传底盘状态pb参考底盘 定频20hz
MsgTypeAutopilotState = 0x10004; //自动驾驶状态 定频20hz
MsgTypeReportMessage = 0x10005; //系统事件 不定频
MsgTypePerceptionTrafficLight = 0x10006; //感知红绿灯 定频10hz
MsgTypePredictionObstacleTrajectory = 0x10007; //他车轨迹预测 定频10hz
MsgTypePointCloud = 0x10008; //点云透传 定频1hz
MsgTypePlanningObjects = 0x10009; //planning障碍物 定频10hz
MsgTypeOBU = 0x1000a; //OBU红绿灯, 宜宾df专用, 非常态, 有则定频10hz
MsgTypeChassisStates = 0x1000b; //重构后的底盘状态, 透传 定频20hz
MsgTypeFunctionStates = 0x1000c; //重构后的功能状态, 透传 定频1hz
MsgTypeBackCameraVideo = 0x1000d; //清扫车后部摄像头视频 定频10hz
MsgTypeM1StitchedVideo = 0x1000e; //m1拼接视频 定频10hz
MsgTypeSSMState = 0x1000f; //ssm 系统状态 定频1hz hq m1 MAP350开始支持其他车型MAP360开始支持
MsgTypeFMState = 0x10010; //FM状态 定频1hz bus和清扫车是MAP370开始支持其他车型MAP360开始支持
//### 以下消息全部不定频 ###
MsgTypeBasicInfoReq = 0x10100; //自动驾驶设备基础信息请求
MsgTypeBasicInfoResp = 0x10101; //自动驾驶设备基础信息应答
MsgTypeSetAutopilotModeReq = 0x10102; //设置自动驾驶模式
@@ -47,8 +49,8 @@ enum MessageType
MsgTypeSetAutopilotSpeedReq = 0x10109; //设置自动驾驶最大速度
MsgTypeGlobalPathReq = 0x1010a; //自动驾驶路径请求
MsgTypeGlobalPathResp = 0x1010b; //自动驾驶路径应答
MsgTypeTrafficLightData = 0x1010c; //发送红绿灯数据到工控机
MsgTypeWarn = 0x1010d; //预警数据
MsgTypeTrafficLightData = 0x1010c; //发送红绿灯数据到工控机 废弃
MsgTypeWarn = 0x1010d; //预警数据 废弃
MsgTypeArrivalNotification = 0x1010e; //到站提醒
MsgTypeSystemCmdReq = 0x1010f; //系统命令请求, 比如系统重启,启用新镜像
MsgTypeTrajectoryDownloadReq = 0x10110; //轨迹下载请求
@@ -74,6 +76,7 @@ enum MessageType
MsgTypeFSMStatusReasonQueryResp = 0x10124; //fsm状态原因查询应答
MsgTypeGetDebugInfo = 0x10125; //debug信息查询 pad->telematics
MsgTypeParallelDrivingCmd = 0x10126; //无人化场景,平行驾驶请求相关指令及状态反馈, 云控<->鹰眼双向透传
MsgTypeReceivedAck = 0x10127; //消息接收ack, 表示消息已接收到
}
message Header
@@ -82,6 +85,13 @@ message Header
MessageType msgType = 2; //消息类型
double timestamp = 3; //消息发送时间, 单位:秒
double sourceTimestamp = 4; //数据源消息发送时间, 单位:秒
uint32 needAck = 5; //是否需要接收回执,仅重要消息使用 0: 不需要 1: 需要
}
// message definition for MsgTypeReceivedAck
message ReceivedAck
{
repeated uint64 msgids = 1; //确认收到的msgid列表
}
// message definition for MsgTypeTrajectory
@@ -111,13 +121,14 @@ enum AdditionalAttribute
ATTR_ROAD_CONSTRUCTION = 2; // 道路施工区域
ATTR_STATIC = 3; // 静止障碍物
ATTR_ACCIDENT = 4; // 事故车
ATTR_ROAD_CONGESTION = 5; // 车辆拥堵
}
// message definition for MsgTypeTrackedObjects
message SubSource
{
uint32 source = 1; // TrackedSource=1:1-lidar 2-camera 3-radar 4-vidar 5-falcon
// TrackedSource=2:1-v2v_bsm 2-v2i_rsm 3-v2v_ssm 4-v2n_rsm 5-v2n_rsi 6-v2i_ssm
// TrackedSource=2:1-v2v_bsm 2-v2i_rsm 3-v2v_ssm 4-v2n_rsm 5-v2n_rsi 6-v2i_ssm 7-v2i_rsi
string id = 2; //HEX_string -bsm_id
}
@@ -132,7 +143,8 @@ message TrackedObject
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,
//501:RoadWork_occupy_0501, 502:RoadWork_break_0502
//447:TAILBACK 501:RoadWork_occupy_0501, 502:RoadWork_break_0502,
//707:ROAD_CONGESTION
double longitude = 2; //经度
double latitude = 3; //纬度
double altitude = 4; //海拔
@@ -155,7 +167,8 @@ message TrackedObject
}
message LocalizationInfo{
message LocalizationInfo
{
double stamp = 1; //seconds
float longitude = 2;
float latitude = 3;
@@ -175,6 +188,7 @@ message TrackedObjects
{
repeated TrackedObject objs = 1;
BlindAreaData blindAreaData = 2;
uint32 collision_risk = 3; //0: no risk 1: risk with a < -5m/s2 2: collision detected
}
// message definition for MsgTypeGnssInfo
@@ -228,7 +242,7 @@ message PlanningObject
message PlanningObjects
{
repeated PlanningObject objs = 1;
repeated PlanningObject objs = 1;
}
// message definition for MessageType: MsgTypeOBU
@@ -437,11 +451,15 @@ enum SystemCmdType
{
SYSTEMCMD_NONE = 0;
SYSTEMCMD_REBOOT = 1;
SYSTEMCMD_START_NODE = 2;
SYSTEMCMD_STOP_NODE = 3;
SYSTEMCMD_POWER_OFF = 4;//MAP 410上线
}
message SystemCmdReq
{
SystemCmdType cmdType = 1; //
SystemCmdType cmdType = 1;
uint32 node = 2; //0: default, 1: 前向camera 30 2: lidar 3: 左前radar 4: calib_check nodeMAP 410上线
}
// message definition for MsgTypeStatusQueryReq
@@ -544,6 +562,8 @@ enum DrivingState
LANE_AVOID_LEFT_RSI_TRIANGLE = 29; //V2N 三角锥主动向左绕行状态: driving_action1 表示触发绕行driving_action:2 表示执行绕行driving_action:3 表示绕行取消driving_action:4 表示绕行完成
LANE_AVOID_RIGHT_RSI_TRIANGLE = 30; //V2N 三角锥主动向右绕行状态: driving_action1 表示触发绕行driving_action:2 表示执行绕行driving_action:3 表示绕行取消driving_action:4 表示绕行完成
WAITING_RSI_TRIANGLE = 31; //V2N 三角锥正在等待变道避让施工场景/静止障碍物: driving_action1 表示正在等待driving_action:2 表示等待超时请求平行驾驶
OUT_OF_ODD = 32; //超出设计运行范围(北京牌照考试): driving_action:1 表示红灯ODD快速路信号灯和绕障ODD静止车占用部分车道对向车辆借道行驶
}
enum DrivingAction
@@ -604,7 +624,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
@@ -617,8 +637,9 @@ message SetOneParam
// 12: 融合v2n开关(bool) 0:不发给PnC 1:发给Pnc /telematics/fusion/v2n_flag
// 13: 融合v2i开关(bool) 0:不发给PnC和鹰眼 1:发给Pnc和鹰眼默认0 /telematics/fusion/v2i_flag
// 14: 融合模式(int) 1:全融合模式 2:盲区模式 3:超视距模式 4:透传模式 5:纯路侧模式默认1 /telematics/fusion/fusion_mode
// 15: 座椅状态(int) 0:表示仅主驾位有人,1:表示仅副驾位有人,2:表示主驾和副驾同时有人,3:表示仅后排有人,4:表示主驾有人+后排有人,5:表示副驾有人+后排有人,6:表示主驾和副驾同时有人+后排有人,7: 所有座位都无人, 255:缺省
// 16: 超车的最大速度阈值(double, m/s, 范围[3, 12.5])
// 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:线控失效
string value = 2; // 转成字符串的值
}

View File

@@ -0,0 +1,17 @@
syntax = "proto3";
package mogo.telematics.pad;
option java_package = "com.zhjt.mogo.adas.data";
import "message_pad.proto";
//发送的数据ID持久化只保留最后一条的消息id每天重新累计
message LastMessage{
uint64 msgID = 1; //消息唯一id
uint64 timestamp = 2;//消息发送时间 单位:毫秒
mogo.telematics.pad.MessageType msgType = 3;//消息类型
}
message MessageIdInfo{
map<uint64, LastMessage> lastMessages = 1;// keydata日期 value数据
}

View File

@@ -51,4 +51,5 @@ message SpecialVehicleTaskCmd {
optional RoboSweeperFuTianTaskCmd robo_sweeper_futian_task_cmd = 2; // 福田清扫车业务指令
optional RoboVanSkywellTaskCmd robo_van_skywell_task_cmd = 3; // 开沃小巴业务指令
optional RoboBusJinlvM1Cmd robo_bus_jinlv_m1_cmd = 4; //金旅定制车m1指令
optional uint32 source = 5; //消息来源, 0:鹰眼, 1:云端
}

View File

@@ -76,7 +76,7 @@ message DoorState {
message DoorStateV2 {
optional DoorNumber number = 1; // 车门编号
optional uint32 status = 2; // 车门开闭状态(0-关, 1-开)
optional uint32 status = 2; // 车门开闭状态(0-关, 1-开, 2-unknown 底盘通信有问题)
}
message LightState {
@@ -121,13 +121,13 @@ message VehicleState {
optional bool steer_inference = 23 [default = false]; //方向盘干预
optional bool brake_inference = 24 [default = false]; //制动踏板干预
optional bool accel_inference = 25 [default = false]; //加速踏板干预
optional bool gear_switch_inference = 26 [default = false]; //档位切换干预
optional bool gear_switch_inference = 26 [default = false]; //档位切换干预
optional bool location_missing = 27 [default = false]; //未收到定位
optional bool trajectory_missing = 28 [default = false]; //未收到轨迹
optional bool chassis_status_missing = 29 [default = false]; //未收到车辆底盘反馈信息
optional bool brake_light_status = 30 [default = false]; //自驾模式下制动灯状态
optional bool pilot_mode_condition_met = 31 [default = false];
optional float steeringSpd = 32 [default = 0]; // steering angle speed in degrees/s
optional float leftFrontWheelAngle = 33 [default = 0];//左前轮角度deg,左负右正

View File

@@ -85,6 +85,7 @@ dependencies {
implementation rootProject.ext.dependencies.mogoservicebiz
//okhttp3的依赖
implementation 'com.squareup.okhttp3:okhttp:3.12.3'
implementation 'com.tencent:mmkv:1.2.14'
implementation project(':libraries:mogo-adas-data')
}

View File

@@ -23,15 +23,14 @@ import androidx.annotation.Nullable;
import com.google.protobuf.InvalidProtocolBufferException;
import com.zhidao.support.adas.high.bean.VersionCompatibility;
import com.zhidao.support.adas.high.common.AutopilotReview;
import com.zhjt.mogo.adas.utils.ByteUtil;
import com.zhidao.support.adas.high.common.Constants;
import com.zhidao.support.adas.high.common.CupidLogUtils;
import com.zhidao.support.adas.high.common.Define;
import com.zhidao.support.adas.high.common.IPCFixationIPHelper;
import com.zhidao.support.adas.high.common.MessageType;
import com.zhidao.support.adas.high.common.ParallelDrivingManager;
import com.zhidao.support.adas.high.common.ProtocolStatus;
import com.zhidao.support.adas.high.common.ReceiveTimeoutManager;
import com.zhidao.support.adas.high.common.ReceivedAckManager;
import com.zhidao.support.adas.high.common.RegexUtils;
import com.zhidao.support.adas.high.common.autopilot.ability.AutopilotAbilityManager;
import com.zhidao.support.adas.high.msg.IMsg;
@@ -43,18 +42,21 @@ import com.zhidao.support.adas.high.queue.WSByteQueueManager;
import com.zhidao.support.adas.high.queue.WebSocketQueueManager;
import com.zhidao.support.adas.high.socket.FpgaSocket;
import com.zhidao.support.adas.high.subscribe.SubscribeInterface;
import com.zhidao.support.adas.high.subscribe.SubscribeInterfaceOptions;
import com.zhidao.support.adas.high.subscribe.SubscribeInterfaceOption;
import com.zhidao.support.adas.high.thread.DispatchHandler;
import com.zhjt.mogo.adas.common.MessageType;
import com.zhjt.mogo.adas.data.AdasConstants;
import com.zhjt.mogo.adas.data.AiCloudTask;
import com.zhjt.mogo.adas.data.bean.AdasParam;
import com.zhjt.mogo.adas.data.bean.AutopilotStatistics;
import com.zhjt.mogo.adas.data.bean.ReceivedAck;
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.cloud.s_r.SweeperTaskCloudSuspendResume;
import com.zhjt.mogo.adas.data.sweeper.task.confirm.SweeperTaskConfirm;
import com.zhjt.mogo.adas.data.sweeper.task.s_r.SweeperTaskSuspendResume;
import com.zhjt.mogo.adas.data.sweeper.task.stop.SweeperTaskStop;
import com.zhjt.mogo.adas.utils.ByteUtil;
import com.zhjt.service.chain.ChainLog;
import java.util.HashMap;
@@ -67,6 +69,7 @@ import java.util.TimerTask;
import java.util.concurrent.atomic.AtomicInteger;
import bag_manager.BagManagerOuterClass;
import chassis.Chassis;
import chassis.SpecialVehicleTaskCmdOuterClass;
import common.HeaderOuterClass;
import function_state_management.FSMStatusReasonQueryOuterClass;
@@ -123,7 +126,7 @@ public class AdasChannel implements IAdasNetCommApi, FpgaSocket.IWebSocketConnec
/**
* 工控机连接配置
*/
private final AdasOptions adasOptions;
private AdasOptions adasOptions;
/**
* 已经链接成功的工控机IP 未连接未null
@@ -146,6 +149,8 @@ public class AdasChannel implements IAdasNetCommApi, FpgaSocket.IWebSocketConnec
private Timer carConfigReqTimer;//车辆基础信息请求 多次请求防止无法收到基础信息情况出现
private Context context;
private final ReceivedAckManager receivedAckManager = new ReceivedAckManager();//消息回执
public void setOnMultiDeviceListener(OnMultiDeviceListener onMultiDeviceListener) {
this.onMultiDeviceListener = onMultiDeviceListener;
}
@@ -174,27 +179,41 @@ public class AdasChannel implements IAdasNetCommApi, FpgaSocket.IWebSocketConnec
* 创建对象时会自动连接工控机如果使用setListener 会出现 listener=null而调用回调的情况所以将所使用到的接口
*
* @param options
* @param onAdasConnectStatusListener
* @param listener
*/
AdasChannel(Context context, AdasOptions options, OnAdasConnectStatusListener onAdasConnectStatusListener) {
AdasChannel(Context context, @Nullable AdasOptions options, @Nullable OnAdasConnectStatusListener listener) {
this.context = context;
this.adasConnectStatusListener = onAdasConnectStatusListener;
this.adasConnectStatusListener = listener;
setAdasOptions(options);
initData();
if (!adasOptions.isPassenger() && listener != null)
connect();
}
public void setAdasOptions(AdasOptions options) {
//配置为null默认是乘客屏幕
if (options == null) {
this.adasOptions = new AdasOptions.Builder().setClient(true).build();
buildAdasOptions(AdasOptions.newBuilder());
} else {
this.adasOptions = options;
}
initData();
if (!adasOptions.isClient()) {
initSocket();
}
ReceiveTimeoutManager.getInstance().setEnable(adasOptions.isEnableTimeoutDetection(), getIpcConnectionStatus());
setUnableLaunchAutopilotGear(adasOptions.getUnableLaunchAutopilotGear());
}
/**
* 构建 AdasOptions
*
* @param builder builder
*/
private void buildAdasOptions(@NonNull AdasOptions.Builder builder) {
this.adasOptions = builder.build();
}
private void initData() {
//原始数据解析类
rawUnpack = new RawUnpack();
rawPack = new RawPack();
rawPack = new RawPack(receivedAckManager);
autopilotReview = new AutopilotReview(onAutopilotReviewListener);
//消息工厂
myMessageFactory = new MyMessageFactory(autopilotReview);
@@ -207,6 +226,19 @@ public class AdasChannel implements IAdasNetCommApi, FpgaSocket.IWebSocketConnec
statusQueryRespDispatchHandler.start();
}
});
receivedAckManager.setListener(new ReceivedAckManager.OnReceivedAckListener() {
@Override
public void onReceiveReceivedAck(@NonNull ReceivedAck receivedAck) {
if (mAdasListener != null) {
mAdasListener.onReceiveReceivedAck(receivedAck);
}
}
@Override
public void onSendReceivedAck(MessageType messageType, byte[] bytes) {
sendPBMessage(messageType, bytes);
}
});
}
/**
@@ -287,16 +319,18 @@ public class AdasChannel implements IAdasNetCommApi, FpgaSocket.IWebSocketConnec
nodeAliasCode = CHAIN_CODE_ADAS_INIT,
paramIndexes = {-1})
private void initSocket() {
mSocket = new FpgaSocket(context);
context = null;
mSocket.setWebSocketListener(this);
if (isUseQueue) {
WebSocketQueueManager.getInstance().registerWebSocketListener(this);
WebSocketQueueManager.getInstance().initDector();
WSByteQueueManager.getInstance().registerWebSocketListener(this);
WSByteQueueManager.getInstance().initDector();
if (mSocket == null) {
mSocket = new FpgaSocket(context);
context = null;
mSocket.setWebSocketListener(this);
if (isUseQueue) {
WebSocketQueueManager.getInstance().registerWebSocketListener(this);
WebSocketQueueManager.getInstance().initDector();
WSByteQueueManager.getInstance().registerWebSocketListener(this);
WSByteQueueManager.getInstance().initDector();
}
}
connect();
// mSocket.setReconnectCount(adasOptions.getReconnectCount());
}
@ChainLog(linkChainLog = CHAIN_TYPE_INIT_STATUS,
@@ -329,6 +363,16 @@ public class AdasChannel implements IAdasNetCommApi, FpgaSocket.IWebSocketConnec
return usedSsmSource;
}
@Override
public void setUnableLaunchAutopilotGear(Set<Chassis.GearPosition> unableLaunchAutopilotGear) {
AutopilotAbilityManager.getInstance().setUnableLaunchAutopilotGear(unableLaunchAutopilotGear);
}
public void setSupportReceivedAck(int version) {
receivedAckManager.setSupport(version);
}
/**
* 发送ws消息
*
@@ -345,16 +389,19 @@ public class AdasChannel implements IAdasNetCommApi, FpgaSocket.IWebSocketConnec
* @param data 数据
* @return boolean
*/
private boolean sendPBMessage(MessagePad.MessageType msgType, byte[] data) {
private boolean sendPBMessage(MessageType msgType, byte[] data) {
if (rawPack != null) {
byte[] bytes = rawPack.pack(msgType, data);
//司机屏工控机数据转发
if (adasOptions.isClient()) {
if (onMultiDeviceListener != null)
onMultiDeviceListener.onForwardingPassengerIPCMessage(bytes);
if (adasOptions.isPassenger()) {
if (onMultiDeviceListener != null) {
onMultiDeviceListener.onForwardingPassengerIPCMessage(rawPack.pack(msgType, data));
}
return true;
} else {
return sendWsMessage(bytes);
if (mSocket == null || !mSocket.isConnected()) {
return false;
}
return sendWsMessage(rawPack.pack(msgType, data));
}
}
return false;
@@ -362,7 +409,7 @@ public class AdasChannel implements IAdasNetCommApi, FpgaSocket.IWebSocketConnec
@Override
public boolean sendWsMessage(byte[] bytes) {
if (mSocket == null || bytes == null || bytes.length <= 0) {
if (mSocket == null || !mSocket.isConnected() || bytes == null || bytes.length == 0) {
return false;
}
ByteString byteString = ByteString.of(bytes);
@@ -399,8 +446,12 @@ public class AdasChannel implements IAdasNetCommApi, FpgaSocket.IWebSocketConnec
if (raw.getProtocolStatus() == ProtocolStatus.SUCCEED) {
MessagePad.Header header = MessagePad.Header.parser().parseFrom(byteString.toByteArray(), raw.getOutHeaderLength(), raw.getOffsetValue() - raw.getOutHeaderLength());
raw.setHeader(header);
if (header.getNeedAck() == 1) {
//需要回执
receivedAckManager.sendReceivedAck(header.getMsgID());
}
//司机端刷新心跳
if (!adasOptions.isClient())
if (!adasOptions.isPassenger())
ReceiveTimeoutManager.getInstance().refreshLast(header.getTimestamp());
// CupidLogUtils.w("--->websocket byte read header = " + messageType.toString());
MessagePad.MessageType messageType = header.getMsgType();
@@ -481,12 +532,19 @@ public class AdasChannel implements IAdasNetCommApi, FpgaSocket.IWebSocketConnec
if (raw.getProtocolStatus() == ProtocolStatus.SUCCEED) {
MessagePad.Header header = raw.getHeader();
MessagePad.MessageType messageType = header.getMsgType();
IMsg iMsg = myMessageFactory.createMessage(messageType);
if (iMsg == null) {
callError(ProtocolStatus.MESSAGE_TYPE_UNKNOWN, raw.originalData.toByteArray());
return;
if (messageType == MessageType.TYPE_RECEIVE_RECEIVED_ACK.typeCode) {
//消息回执
long time = System.currentTimeMillis();
MessagePad.ReceivedAck ack = MessagePad.ReceivedAck.parser().parseFrom(raw.originalData.toByteArray(), raw.getOffsetValue(), raw.getPackageLengthValue() - raw.getOffsetValue());
receivedAckManager.receiveReceivedAck(time, ack);
} else {
IMsg iMsg = myMessageFactory.createMessage(messageType);
if (iMsg == null) {
callError(ProtocolStatus.MESSAGE_TYPE_UNKNOWN, raw.originalData.toByteArray());
return;
}
iMsg.handlerMsg(raw, mAdasListener);
}
iMsg.handlerMsg(raw, mAdasListener);
} else {
callError(raw.getProtocolStatus(), raw.originalData.toByteArray());
}
@@ -504,7 +562,7 @@ public class AdasChannel implements IAdasNetCommApi, FpgaSocket.IWebSocketConnec
@Override
public AdasOptions getAdasOptions() {
return adasOptions == null ? new AdasOptions.Builder().build() : adasOptions;
return adasOptions;
}
/**
@@ -513,15 +571,16 @@ public class AdasChannel implements IAdasNetCommApi, FpgaSocket.IWebSocketConnec
@Override
public void connect() {
//当是司机屏才启用
if (!adasOptions.isClient()) {
if (!adasOptions.isPassenger()) {
initSocket();
if (ipcConnectionStatus.get() == Constants.IPC_CONNECTION_STATUS.DISCONNECTED ||
ipcConnectionStatus.get() == Constants.IPC_CONNECTION_STATUS.NOT_FOUND_ADDRESS) {
switch (adasOptions.getIpcConnectionMode()) {
case AdasOptions.IPC_CONNECTION_MODE.FIXATION:
ipcFixationIPHelper(adasOptions.getIpcFixationIP());
switch (adasOptions.getConnectionMode()) {
case AdasOptions.IPC_CONNECTION_MODE.PING:
ipcFixationIPHelper(adasOptions.getPingAddressList());
break;
case AdasOptions.IPC_CONNECTION_MODE.ASSIGN:
onConnectionAddress(adasOptions.getIpcAssignIP());
case AdasOptions.IPC_CONNECTION_MODE.SPECIFIED:
onConnectionAddress(adasOptions.getSpecifiedAddress());
break;
}
}
@@ -536,7 +595,7 @@ public class AdasChannel implements IAdasNetCommApi, FpgaSocket.IWebSocketConnec
if (ipcFixationIPHelper != null) {
ipcFixationIPHelper.stop();
}
if (!adasOptions.isClient()) {
if (!adasOptions.isPassenger()) {
if (mSocket != null)
mSocket.closeWebSocket();
if (isUseQueue) {
@@ -561,9 +620,18 @@ public class AdasChannel implements IAdasNetCommApi, FpgaSocket.IWebSocketConnec
updateConnectStatus(Constants.IPC_CONNECTION_STATUS.CONNECTED, "已连接");
//根据连接配置 进行接口订阅或取消订阅配置
if (adasOptions != null) {
SubscribeInterfaceOptions options = adasOptions.getSubscribeInterfaceOptions();
if (options != null && options.getMessageTypes() != null && !options.getMessageTypes().isEmpty()) {
subscribeInterface.subscribeInterface(options.getRole(), options.getType(), options.getMessageTypes());
Set<SubscribeInterfaceOption> options = adasOptions.getSubscribeInterfaceOptions();
if (options != null && !options.isEmpty()) {
for (SubscribeInterfaceOption option : options) {
MessageType messageType = option.getMessageType();
if (messageType != null) {
subscribeInterface.subscribeInterface(option.getRole(), option.getType(), messageType);
}
Set<MessageType> messageTypes = option.getMessageTypes();
if (messageTypes != null) {
subscribeInterface.subscribeInterface(option.getRole(), option.getType(), messageTypes);
}
}
}
}
}
@@ -575,6 +643,7 @@ public class AdasChannel implements IAdasNetCommApi, FpgaSocket.IWebSocketConnec
subscribeInterface = null;
usedChassisSource = AdasConstants.ChassisSource.CHASSIS_UNKNOWN;
usedSsmSource = AdasConstants.SsmSource.SSM_UNKNOWN;
receivedAckManager.stop();
updateConnectStatus(Constants.IPC_CONNECTION_STATUS.DISCONNECTED, t == null ? "" : t);
}
@@ -598,7 +667,7 @@ public class AdasChannel implements IAdasNetCommApi, FpgaSocket.IWebSocketConnec
nowTime = SystemClock.elapsedRealtime();
decoderRaw(receiveTime, bytes);
//司机屏工控机数据转发
if (!adasOptions.isClient() && onMultiDeviceListener != null) {
if (!adasOptions.isPassenger() && onMultiDeviceListener != null) {
onMultiDeviceListener.onForwardingDriverIPCMessage(bytes.toByteArray());
}
calculateTimeConsumingOnMessage(nowTime);
@@ -876,7 +945,7 @@ public class AdasChannel implements IAdasNetCommApi, FpgaSocket.IWebSocketConnec
builder.setCertification(com.google.protobuf.ByteString.copyFrom(certification));
}
MessagePad.BasicInfoResp resp = builder.build();
return sendPBMessage(MessageType.TYPE_SEND_BASIC_INFO_RESP.typeCode, resp.toByteArray());
return sendPBMessage(MessageType.TYPE_SEND_BASIC_INFO_RESP, resp.toByteArray());
}
/**
@@ -896,7 +965,7 @@ public class AdasChannel implements IAdasNetCommApi, FpgaSocket.IWebSocketConnec
builder.setRouteInfo(routeInfo);
MessagePad.SetAutopilotModeReq req = builder.build();
if (autopilotReview != null) autopilotReview.onAutopilotCommandTrigger(req);
return sendPBMessage(MessageType.TYPE_SEND_SET_AUTOPILOT_MODE_REQ.typeCode, req.toByteArray());
return sendPBMessage(MessageType.TYPE_SEND_SET_AUTOPILOT_MODE_REQ, req.toByteArray());
}
/**
@@ -911,7 +980,7 @@ public class AdasChannel implements IAdasNetCommApi, FpgaSocket.IWebSocketConnec
.newBuilder()
.setEnable(enable)
.build();
return sendPBMessage(MessageType.TYPE_SEND_SET_DEMO_MODE_REQ.typeCode, req.toByteArray());
return sendPBMessage(MessageType.TYPE_SEND_SET_DEMO_MODE_REQ, req.toByteArray());
}
/**
@@ -924,7 +993,7 @@ public class AdasChannel implements IAdasNetCommApi, FpgaSocket.IWebSocketConnec
MessagePad.CarConfigReq req = MessagePad.CarConfigReq
.newBuilder()
.build();
return sendPBMessage(MessageType.TYPE_SEND_CAR_CONFIG_REQ.typeCode, req.toByteArray());
return sendPBMessage(MessageType.TYPE_SEND_CAR_CONFIG_REQ, req.toByteArray());
}
/**
@@ -954,7 +1023,7 @@ public class AdasChannel implements IAdasNetCommApi, FpgaSocket.IWebSocketConnec
.setReason(reason)
.setReasonID(reasonID)
.build();
return sendPBMessage(MessageType.TYPE_SEND_RECORD_CAUSE.typeCode, resp.toByteArray());
return sendPBMessage(MessageType.TYPE_SEND_RECORD_CAUSE, resp.toByteArray());
}
@Override
@@ -1028,7 +1097,7 @@ public class AdasChannel implements IAdasNetCommApi, FpgaSocket.IWebSocketConnec
builder.addAllTopics(topics);
}
MessagePad.RecordData req = builder.build();
return sendPBMessage(MessageType.TYPE_SEND_RECORD_DATA.typeCode, req.toByteArray());
return sendPBMessage(MessageType.TYPE_SEND_RECORD_DATA, req.toByteArray());
}
/**
@@ -1043,7 +1112,7 @@ public class AdasChannel implements IAdasNetCommApi, FpgaSocket.IWebSocketConnec
.newBuilder()
.setSpeedLimit(speedLimit)
.build();
return sendPBMessage(MessageType.TYPE_SEND_SET_AUTOPILOT_SPEED_REQ.typeCode, req.toByteArray());
return sendPBMessage(MessageType.TYPE_SEND_SET_AUTOPILOT_SPEED_REQ, req.toByteArray());
}
/**
@@ -1062,7 +1131,7 @@ public class AdasChannel implements IAdasNetCommApi, FpgaSocket.IWebSocketConnec
MessagePad.GlobalPathReq req = MessagePad.GlobalPathReq
.newBuilder()
.build();
return sendPBMessage(MessageType.TYPE_SEND_GLOBAL_PATH_REQ.typeCode, req.toByteArray());
return sendPBMessage(MessageType.TYPE_SEND_GLOBAL_PATH_REQ, req.toByteArray());
}
/**
@@ -1110,7 +1179,7 @@ public class AdasChannel implements IAdasNetCommApi, FpgaSocket.IWebSocketConnec
builder.setLaneDetail(laneDetail);
builder.setTimestamp(timestamp);
MessagePad.TrafficLightData req = builder.build();
return sendPBMessage(MessageType.TYPE_SEND_TRAFFIC_LIGHT_DATA.typeCode, req.toByteArray());
return sendPBMessage(MessageType.TYPE_SEND_TRAFFIC_LIGHT_DATA, req.toByteArray());
}
/**
@@ -1132,7 +1201,7 @@ public class AdasChannel implements IAdasNetCommApi, FpgaSocket.IWebSocketConnec
MessagePad.SystemCmdReq.Builder builder = MessagePad.SystemCmdReq.newBuilder();
builder.setCmdType(type);
MessagePad.SystemCmdReq req = builder.build();
return sendPBMessage(MessageType.TYPE_SEND_SYSTEM_CMD_REQ.typeCode, req.toByteArray());
return sendPBMessage(MessageType.TYPE_SEND_SYSTEM_CMD_REQ, req.toByteArray());
}
/**
@@ -1157,7 +1226,7 @@ public class AdasChannel implements IAdasNetCommApi, FpgaSocket.IWebSocketConnec
builder.setDownloadType(downloadType);
}
MessagePad.TrajectoryDownloadReq req = builder.build();
return sendPBMessage(MessageType.TYPE_SEND_TRAJECTORY_DOWNLOAD_REQ.typeCode, req.toByteArray());
return sendPBMessage(MessageType.TYPE_SEND_TRAJECTORY_DOWNLOAD_REQ, req.toByteArray());
}
/**
@@ -1178,7 +1247,7 @@ public class AdasChannel implements IAdasNetCommApi, FpgaSocket.IWebSocketConnec
MessagePad.StatusQueryReq req = MessagePad.StatusQueryReq
.newBuilder()
.build();
return sendPBMessage(MessageType.TYPE_SEND_STATUS_QUERY_REQ.typeCode, req.toByteArray());
return sendPBMessage(MessageType.TYPE_SEND_STATUS_QUERY_REQ, req.toByteArray());
}
@@ -1194,7 +1263,7 @@ public class AdasChannel implements IAdasNetCommApi, FpgaSocket.IWebSocketConnec
.newBuilder()
.setEnable(enable)
.build();
return sendPBMessage(MessageType.TYPE_SEND_SET_RAIN_MODE_REQ.typeCode, req.toByteArray());
return sendPBMessage(MessageType.TYPE_SEND_SET_RAIN_MODE_REQ, req.toByteArray());
}
/**
@@ -1214,13 +1283,13 @@ public class AdasChannel implements IAdasNetCommApi, FpgaSocket.IWebSocketConnec
if (topicsNeedToCache != null && !topicsNeedToCache.isEmpty())
builder.addAllTopicsNeedToCache(topicsNeedToCache);
MessagePad.RecordDataConfigReq req = builder.build();
return sendPBMessage(MessageType.TYPE_SEND_RECORD_DATA_CONFIG_REQ.typeCode, req.toByteArray());
return sendPBMessage(MessageType.TYPE_SEND_RECORD_DATA_CONFIG_REQ, req.toByteArray());
}
/**************************************注册接口相关*******************************************/
@Override
public boolean onSendSubscribe(byte[] bytes) {
return sendPBMessage(MessageType.TYPE_SEND_SUBSCRIBE_DATA_REQ.typeCode, bytes);
return sendPBMessage(MessageType.TYPE_SEND_SUBSCRIBE_DATA_REQ, bytes);
}
/**
@@ -1328,7 +1397,7 @@ public class AdasChannel implements IAdasNetCommApi, FpgaSocket.IWebSocketConnec
build.setLaneChangeCmd(MessagePad.LaneChangeCmd.newBuilder().setCmd(laneChangeCmd));
}
MessagePad.PlanningCmd planningCmd = build.build();
return sendPBMessage(MessageType.TYPE_SEND_PLANNING_CMD.typeCode, planningCmd.toByteArray());
return sendPBMessage(MessageType.TYPE_SEND_PLANNING_CMD, planningCmd.toByteArray());
}
/**
@@ -1481,8 +1550,9 @@ public class AdasChannel implements IAdasNetCommApi, FpgaSocket.IWebSocketConnec
.setFrameId("special_vehicle_task_cmd")
.setModuleName("EagleEye")
.build();
cmdBuild.setHeader(header);
return sendPBMessage(MessageType.TYPE_SEND_SPECIAL_VEHICLE_TASK_CMD.typeCode, cmdBuild.build().toByteArray());
cmdBuild.setHeader(header)
.setSource(0);
return sendPBMessage(MessageType.TYPE_SEND_SPECIAL_VEHICLE_TASK_CMD, cmdBuild.build().toByteArray());
}
@@ -1498,7 +1568,7 @@ public class AdasChannel implements IAdasNetCommApi, FpgaSocket.IWebSocketConnec
.setCmdType(MessagePad.OperatorCmdType.OPERATOR_CMD_CHANGE_LANE)
.setValue(1)
.build();
return sendPBMessage(MessageType.TYPE_SEND_OPERATOR_CMD_REQ.typeCode, req.toByteArray());
return sendPBMessage(MessageType.TYPE_SEND_OPERATOR_CMD_REQ, req.toByteArray());
}
/**
@@ -1513,7 +1583,7 @@ public class AdasChannel implements IAdasNetCommApi, FpgaSocket.IWebSocketConnec
.setCmdType(MessagePad.OperatorCmdType.OPERATOR_CMD_CHANGE_LANE)
.setValue(2)
.build();
return sendPBMessage(MessageType.TYPE_SEND_OPERATOR_CMD_REQ.typeCode, req.toByteArray());
return sendPBMessage(MessageType.TYPE_SEND_OPERATOR_CMD_REQ, req.toByteArray());
}
/**
@@ -1529,7 +1599,7 @@ public class AdasChannel implements IAdasNetCommApi, FpgaSocket.IWebSocketConnec
.setCmdType(MessagePad.OperatorCmdType.OPERATOR_CMD_SET_ACCELERATED_SPEED)
.setValue(acc)
.build();
return sendPBMessage(MessageType.TYPE_SEND_OPERATOR_CMD_REQ.typeCode, req.toByteArray());
return sendPBMessage(MessageType.TYPE_SEND_OPERATOR_CMD_REQ, req.toByteArray());
}
/**
@@ -1545,7 +1615,7 @@ public class AdasChannel implements IAdasNetCommApi, FpgaSocket.IWebSocketConnec
.setCmdType(MessagePad.OperatorCmdType.OPERATOR_CMD_SET_HORN)
.setValue(value)
.build();
return sendPBMessage(MessageType.TYPE_SEND_OPERATOR_CMD_REQ.typeCode, req.toByteArray());
return sendPBMessage(MessageType.TYPE_SEND_OPERATOR_CMD_REQ, req.toByteArray());
}
/**
@@ -1583,7 +1653,7 @@ public class AdasChannel implements IAdasNetCommApi, FpgaSocket.IWebSocketConnec
.newBuilder()
.addReqs(oneParam)
.build();
return sendPBMessage(MessageType.TYPE_SEND_SET_PARAM_REQ.typeCode, req.toByteArray());
return sendPBMessage(MessageType.TYPE_SEND_SET_PARAM_REQ, req.toByteArray());
}
/**
@@ -1600,7 +1670,7 @@ public class AdasChannel implements IAdasNetCommApi, FpgaSocket.IWebSocketConnec
builder.setBoolValue((Boolean) value);
}
ParamSetCmdOuterClass.ParamSetCmd req = builder.build();
return sendPBMessage(MessageType.TYPE_SEND_SET_PARAM_REQ_V2.typeCode, req.toByteArray());
return sendPBMessage(MessageType.TYPE_SEND_SET_PARAM_REQ_V2, req.toByteArray());
}
/**
@@ -1647,7 +1717,7 @@ public class AdasChannel implements IAdasNetCommApi, FpgaSocket.IWebSocketConnec
}
if (builder.getReqsCount() > 0) {
MessagePad.SetParamReq req = builder.build();
isV1 = sendPBMessage(MessageType.TYPE_SEND_SET_PARAM_REQ.typeCode, req.toByteArray());
isV1 = sendPBMessage(MessageType.TYPE_SEND_SET_PARAM_REQ, req.toByteArray());
}
return isV1 && isV2BlindArea && isV2V2N && isV2V2NI;
}
@@ -1861,7 +1931,7 @@ public class AdasChannel implements IAdasNetCommApi, FpgaSocket.IWebSocketConnec
}
req = builder.build();
}
return sendPBMessage(MessageType.TYPE_SEND_GET_PARAM_REQ.typeCode, req.toByteArray());
return sendPBMessage(MessageType.TYPE_SEND_GET_PARAM_REQ, req.toByteArray());
}
/**
@@ -1894,7 +1964,7 @@ public class AdasChannel implements IAdasNetCommApi, FpgaSocket.IWebSocketConnec
}
}
MessagePad.TripInfoEvent req = builder.build();
return sendPBMessage(MessageType.TYPE_SEND_TRIP_INFO_REQ.typeCode, req.toByteArray());
return sendPBMessage(MessageType.TYPE_SEND_TRIP_INFO_REQ, req.toByteArray());
}
/**
@@ -1905,7 +1975,7 @@ public class AdasChannel implements IAdasNetCommApi, FpgaSocket.IWebSocketConnec
*/
@Override
public boolean sendBagManagerCmd(BagManagerOuterClass.BagManager bagManager) {
return sendPBMessage(MessageType.TYPE_SEND_BAG_MANAGER_CMD.typeCode, bagManager.toByteArray());
return sendPBMessage(MessageType.TYPE_SEND_BAG_MANAGER_CMD, bagManager.toByteArray());
}
/**
@@ -1921,7 +1991,7 @@ public class AdasChannel implements IAdasNetCommApi, FpgaSocket.IWebSocketConnec
FSMStatusReasonQueryOuterClass.FSMStatusReasonQuery query = FSMStatusReasonQueryOuterClass.FSMStatusReasonQuery.newBuilder()
.setType(type)
.build();
return sendPBMessage(MessageType.TYPE_SEND_FSM_STATUS_REASON_QUERY_REQ.typeCode, query.toByteArray());
return sendPBMessage(MessageType.TYPE_SEND_FSM_STATUS_REASON_QUERY_REQ, query.toByteArray());
}
/**
@@ -1944,7 +2014,7 @@ public class AdasChannel implements IAdasNetCommApi, FpgaSocket.IWebSocketConnec
builder.setPayload(payload);
}
AiCloudTask.AiCloudPadMessage message = builder.build();
return sendPBMessage(padMessageType.typeCode, message.toByteArray());
return sendPBMessage(padMessageType, message.toByteArray());
}
/**

View File

@@ -6,12 +6,15 @@ import android.text.TextUtils;
import androidx.annotation.NonNull;
import com.zhidao.support.adas.high.bean.VersionCompatibility;
import com.zhidao.support.adas.high.common.AppPreferenceHelper;
import com.zhidao.support.adas.high.common.Constants;
import com.zhidao.support.adas.high.common.CupidLogUtils;
import com.zhidao.support.adas.high.common.Define;
import com.zhidao.support.adas.high.common.MessageType;
import com.zhidao.support.adas.high.common.MMKVUtils;
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.data.Adas;
import com.zhjt.mogo.adas.data.AdasConstants;
import com.zhjt.mogo.adas.data.bean.AdasParam;
import com.zhjt.mogo.adas.data.sweeper.bootable.SweeperBootable;
@@ -30,6 +33,7 @@ import java.util.regex.Matcher;
import java.util.regex.Pattern;
import bag_manager.BagManagerOuterClass;
import chassis.Chassis;
import chassis.SpecialVehicleTaskCmdOuterClass;
import mogo.telematics.pad.MessagePad;
import mogo.yycp.paralleldriving.protocol.ParallelDrivingRequest;
@@ -57,6 +61,7 @@ public class AdasManager implements IAdasNetCommApi {
private final Pattern pattern = Pattern.compile("\\d+\\.\\d+\\.\\d+");
private AdasChannel mChannel;
private Context context;//不持有create之后会置null
public static AdasManager getInstance() {
if (ourInstance == null) {
@@ -75,6 +80,9 @@ public class AdasManager implements IAdasNetCommApi {
public synchronized void setCarConfig(MessagePad.CarConfigResp carConfig) {
this.carConfig = carConfig;
if (carConfig != null && mChannel != null) {
mChannel.setSupportReceivedAck(carConfig.getMapVersion());
}
}
/**
@@ -99,20 +107,31 @@ public class AdasManager implements IAdasNetCommApi {
}
}
/**
* 初始化
* TODO 必须在调用任意方法之前初始化
*
* @param context
*/
public void init(Context context) {
this.context = context;
MMKVUtils.getInstance().init(context);
}
/**
* 创建一个连接
*
* @param options 连接参数
* @param onAdasConnectStatusListener 连接状态监听
*/
public synchronized void create(Context context, AdasOptions options, OnAdasConnectStatusListener onAdasConnectStatusListener) {
public synchronized void create(AdasOptions options, OnAdasConnectStatusListener onAdasConnectStatusListener) {
if (mChannel != null) {
mChannel.disconnect();
carConfig = null;
mChannel = null;
}
mChannel = new AdasChannel(context, options, onAdasConnectStatusListener);
context = null;
}
/**
@@ -295,6 +314,16 @@ public class AdasManager implements IAdasNetCommApi {
return mChannel == null ? AdasConstants.SsmSource.SSM_UNKNOWN : mChannel.getUsedSsmSource();
}
/**
* 设置不能启动自动驾驶的档位
*
* @param unableLaunchAutopilotGear 不能起自驾档位
*/
@Override
public void setUnableLaunchAutopilotGear(Set<Chassis.GearPosition> unableLaunchAutopilotGear) {
AutopilotAbilityManager.getInstance().setUnableLaunchAutopilotGear(unableLaunchAutopilotGear);
}
/**
* 自动驾驶设备基础信息应答
*
@@ -1234,8 +1263,8 @@ public class AdasManager implements IAdasNetCommApi {
*
* @return 返回默认工控机IP列表
*/
public HashSet<String> getIPCFixationIPList(Context context) {
return AppPreferenceHelper.getInstance(context).getIPCFixationIPList();
public HashSet<String> getIPCFixationIPList() {
return Constants.getIPCFixationIPList();
}
/**
@@ -1243,8 +1272,8 @@ public class AdasManager implements IAdasNetCommApi {
*
* @param ipcIP IP
*/
public boolean addIPCFixationIP(Context context, String ipcIP) {
return AppPreferenceHelper.getInstance(context).addIPCFixationIP(ipcIP);
public boolean addIPCFixationIP(String ipcIP) {
return Constants.addIPCFixationIP(ipcIP);
}
/**
@@ -1252,15 +1281,26 @@ public class AdasManager implements IAdasNetCommApi {
*
* @param ipcIP IP
*/
public boolean delIPCFixationIP(Context context, String ipcIP) {
return AppPreferenceHelper.getInstance(context).delIPCFixationIP(ipcIP);
public boolean delIPCFixationIP(String ipcIP) {
return Constants.delIPCFixationIP(ipcIP);
}
/**
* 删除所有工控机固定IP
*/
public void delIPCFixationIP(Context context) {
AppPreferenceHelper.getInstance(context).delIPCFixationIP();
public void delIPCFixationIP() {
Constants.delIPCFixationIP();
}
/**
* 获取全部已存储的消息ID
* LastMessage中的msgID如果是0表明今日还未下发任何数据
*
* @return key日期毫秒值 value最后一条消息的相关信息
*/
public Map<Long, Adas.LastMessage> getAllSendMessageId() {
return MessageIdGenerator.getInstance().getAllSendMessageId();
}
/**

View File

@@ -1,7 +1,6 @@
package com.zhidao.support.adas.high;
import com.zhidao.support.adas.high.common.autopilot.ability.AutopilotAbilityManager;
import com.zhidao.support.adas.high.subscribe.SubscribeInterfaceOptions;
import com.zhidao.support.adas.high.subscribe.SubscribeInterfaceOption;
import java.util.HashSet;
import java.util.Set;
@@ -14,117 +13,289 @@ import chassis.Chassis;
* 更换链接方式必须先断开与工控机的连接
*/
public class AdasOptions {
public interface DEFAULT {
boolean IS_PASSENGER = true;//默认乘客端
int CONNECTION_MODE = IPC_CONNECTION_MODE.PING;//默认PING方式
boolean IS_ENABLE_TIMEOUT_DETECTION = true;//默认启动超时检测
int RECONNECT_COUNT = 0;//默认无限重连 -1用不重连0无限重连非0正整数指定重连次数
boolean IS_CERTIFICATION = false;//默认不启用证书
boolean IS_AUTO_CONNECT = true;//默认自动连接(调用初始化后自动连接)
}
/**
* 链接方式
*/
public interface IPC_CONNECTION_MODE {
/**
* 固定IP 根据存储的IP进行轮询
* 提供一个地址列表通过PING的方式进行选择
* 主要作用是存在不同网段
*/
int FIXATION = 0;
int PING = 0;
/**
* 指定IP
* 指定地址方式
*/
int ASSIGN = 1;
int SPECIFIED = 1;
}
/**
* 是否是客户端 true客户度乘客屏 false服务端司机屏
* 当是乘客端的情况下 ipcConnectionMode ipcAssignIP ipcFixationIPSet 均无效
*/
private boolean isClient;
private final boolean isPassenger;
private final int connectionMode;
private final String specifiedAddress;
private final HashSet<String> pingAddressList;
private final boolean isEnableTimeoutDetection;
private final int reconnectCount;
private final boolean isCertification;
private final String rootCrt;
private final boolean isAutoConnect;
private final Set<SubscribeInterfaceOption> subscribeInterfaceOptions;
private final Set<Chassis.GearPosition> unableLaunchAutopilotGear;
/**
* 链接工控机方式
* 如果是司机屏默认 固定IP方式
*/
private int ipcConnectionMode = IPC_CONNECTION_MODE.FIXATION;
/**
* 指定工控机IP
*/
private String ipcAssignIP;
/**
* 工控机固定IP集合 通过Ping方式尝试
*/
private HashSet<String> ipcFixationIP;
/**
* 订阅相关配置
*/
private SubscribeInterfaceOptions subscribeInterfaceOptions;
private AdasOptions() {
private AdasOptions(Builder builder) {
this.isPassenger = builder.isPassenger;
this.connectionMode = builder.connectionMode;
this.specifiedAddress = builder.specifiedAddress;
this.pingAddressList = builder.pingAddressList;
this.isEnableTimeoutDetection = builder.isEnableTimeoutDetection;
this.reconnectCount = builder.reconnectCount;
this.isCertification = builder.isCertification;
this.rootCrt = builder.rootCrt;
this.isAutoConnect = builder.isAutoConnect;
this.subscribeInterfaceOptions = builder.subscribeInterfaceOptions;
this.unableLaunchAutopilotGear = builder.unableLaunchAutopilotGear;
}
public boolean isPassenger() {
return isPassenger;
}
public String getSpecifiedAddress() {
return specifiedAddress;
}
public int getConnectionMode() {
return connectionMode;
}
public HashSet<String> getPingAddressList() {
return pingAddressList;
}
public boolean isEnableTimeoutDetection() {
return isEnableTimeoutDetection;
}
public int getReconnectCount() {
return reconnectCount;
}
public boolean isCertification() {
return isCertification;
}
public String getRootCrt() {
return rootCrt;
}
public boolean isAutoConnect() {
return isAutoConnect;
}
public Set<SubscribeInterfaceOption> getSubscribeInterfaceOptions() {
return subscribeInterfaceOptions;
}
public Set<Chassis.GearPosition> getUnableLaunchAutopilotGear() {
return unableLaunchAutopilotGear;
}
public static Builder newBuilder() {
return new Builder();
}
public Builder toBuilder() {
return new Builder(this);
}
/**
* 静态内部类
*/
public static class Builder {
AdasOptions options;
private boolean isPassenger = DEFAULT.IS_PASSENGER;
private int connectionMode = DEFAULT.CONNECTION_MODE;
private String specifiedAddress;
private HashSet<String> pingAddressList;
private boolean isEnableTimeoutDetection = DEFAULT.IS_ENABLE_TIMEOUT_DETECTION;
private int reconnectCount = DEFAULT.RECONNECT_COUNT;
private boolean isCertification = DEFAULT.IS_CERTIFICATION;
private String rootCrt;
private boolean isAutoConnect = DEFAULT.IS_AUTO_CONNECT;
private Set<SubscribeInterfaceOption> subscribeInterfaceOptions;
private Set<Chassis.GearPosition> unableLaunchAutopilotGear;
// 首先获得一个默认的配置
public Builder() {
this(getDefaultOptions());
private Builder() {
}
public Builder(AdasOptions defaultOptions) {
options = defaultOptions;
private Builder(AdasOptions options) {
this.isPassenger = options.isPassenger;
this.connectionMode = options.connectionMode;
this.specifiedAddress = options.specifiedAddress;
this.pingAddressList = options.pingAddressList;
this.isEnableTimeoutDetection = options.isEnableTimeoutDetection;
this.reconnectCount = options.reconnectCount;
this.isCertification = options.isCertification;
this.rootCrt = options.rootCrt;
this.isAutoConnect = options.isAutoConnect;
this.subscribeInterfaceOptions = options.subscribeInterfaceOptions;
this.unableLaunchAutopilotGear = options.unableLaunchAutopilotGear;
}
/**
* 设置当前是客户端还是服务
* 设置当前是司机端还是乘客
* 默认乘客端
* 当乘客端时以下参数均无效:
* *ipcConnectionMode
* *ipcAssignIP
* *ipcFixationIP
* *isEnableTimeoutDetection
* *reconnectCount
* *isCertification
* *rootCrt
* *isAutoConnect
* *subscribeInterfaceOptions
* *unableLaunchAutopilotGear
*
* @param isClient true客户度 false服务
* @return
* @param isPassenger true乘客端 false司机
* @return Builder
*/
public Builder setClient(boolean isClient) {
options.isClient = isClient;
public Builder setPassenger(boolean isPassenger) {
this.isPassenger = isPassenger;
return this;
}
/**
* 配置连接方式
* 配置工控机连接方式
* isPassenger=false 时默认是固定IP方式{@link IPC_CONNECTION_MODE#PING}
* *
* 配置固定IP方式{@link IPC_CONNECTION_MODE#PING}时必须配置工控机IP地址列表{@link Builder#setPingAddressList(HashSet)}
* 配置指定IP方式{@link IPC_CONNECTION_MODE#SPECIFIED}时必须配置工控机IP地址{@link Builder#setSpecifiedAddress(String)}
*
* @param ipcConnectionMode
* @return
* @param connectionMode 连接方式
* @return Builder
*/
public Builder setIpcConnectionMode(int ipcConnectionMode) {
options.ipcConnectionMode = ipcConnectionMode;
public Builder setConnectionMode(int connectionMode) {
this.connectionMode = connectionMode;
return this;
}
/**
* 设置IPC主机地址
*
* @param ipcAssignIP
* @return
* @param specifiedAddress ip
* @return Builder
*/
public Builder setIpcAssignIP(String ipcAssignIP) {
options.ipcAssignIP = ipcAssignIP;
public Builder setSpecifiedAddress(String specifiedAddress) {
this.specifiedAddress = specifiedAddress;
return this;
}
/**
* 设置IPC 固定IP
* 设置工控机固定IP
* 通过ping方式逐一检查连通性
*
* @param ipcFixationIP
* @return
* @param pingAddressList 固定IP列表
* @return Builder
*/
public Builder setIpcFixationIP(HashSet<String> ipcFixationIP) {
options.ipcFixationIP = ipcFixationIP;
public Builder setPingAddressList(HashSet<String> pingAddressList) {
this.pingAddressList = pingAddressList;
return this;
}
/**
* 接口注册参数
* 是否启用超时检测
* 默认启用
*
* @param subscribeInterfaceOptions
* @return
* @return Builder
*/
public Builder setSubscribeInterfaceOptions(SubscribeInterfaceOptions subscribeInterfaceOptions) {
options.subscribeInterfaceOptions = subscribeInterfaceOptions;
public Builder setEnableTimeoutDetection(boolean enable) {
this.isEnableTimeoutDetection = enable;
return this;
}
/**
* 重连次数
* -1不重连
* 0无限重连
* >0重连指定次数
* 默认0
*
* @return Builder
*/
public Builder setReconnectCount(int count) {
this.reconnectCount = count;
return this;
}
/**
* 是否启用SSL认证
* 目前默认禁用
*
* @return Builder
*/
public Builder setEnableCertification(boolean enable) {
this.isCertification = enable;
return this;
}
/**
* ROOT证书
* 启用认证必须传
*
* @param rootCrt root证书
* @return Builder
*/
public Builder setRootCrt(String rootCrt) {
this.rootCrt = rootCrt;
return this;
}
/**
* 是否自动连接
* create之后是否自动连接域控
*
* @param isAutoConnect 是否自动连接
* @return Builder
*/
public Builder setAutoConnect(boolean isAutoConnect) {
this.isAutoConnect = isAutoConnect;
return this;
}
/**
* 接口订阅参数
*
* @param subscribeInterfaceOption 订阅参数
* @return Builder
*/
public Builder addSubscribeInterfaceOption(SubscribeInterfaceOption subscribeInterfaceOption) {
if (subscribeInterfaceOptions == null) {
subscribeInterfaceOptions = new HashSet<>();
}
subscribeInterfaceOptions.add(subscribeInterfaceOption);
return this;
}
/**
* 接口订阅参数
*
* @param subscribeInterfaceOptions 订阅参数
* @return Builder
*/
public Builder setSubscribeInterfaceOptions(Set<SubscribeInterfaceOption> subscribeInterfaceOptions) {
this.subscribeInterfaceOptions = subscribeInterfaceOptions;
return this;
}
@@ -132,75 +303,15 @@ public class AdasOptions {
* 不能启动自驾的档位
*
* @param unableLaunchAutopilotGear 档位
* @return
* @return Builder
*/
public Builder setUnableLaunchAutopilotGear(Set<Chassis.GearPosition> unableLaunchAutopilotGear) {
options.setUnableLaunchAutopilotGear(unableLaunchAutopilotGear);
this.unableLaunchAutopilotGear = unableLaunchAutopilotGear;
return this;
}
public AdasOptions build() {
return options;
return new AdasOptions(this);
}
}
/**
* 获取默认的配置
* 默认配置是乘客端
*
* @return
*/
public static AdasOptions getDefaultOptions() {
AdasOptions options = new AdasOptions();
options.isClient = true;
options.ipcAssignIP = null;
options.ipcFixationIP = null;
options.subscribeInterfaceOptions = null;
options.setUnableLaunchAutopilotGear(null);
return options;
}
public boolean isClient() {
return isClient;
}
public String getIpcAssignIP() {
return ipcAssignIP;
}
public int getIpcConnectionMode() {
return ipcConnectionMode;
}
public HashSet<String> getIpcFixationIP() {
return ipcFixationIP;
}
public SubscribeInterfaceOptions getSubscribeInterfaceOptions() {
return subscribeInterfaceOptions;
}
public void setIpcAssignIP(String ipcAssignIP) {
this.ipcAssignIP = ipcAssignIP;
}
public void setClient(boolean client) {
isClient = client;
}
public void setIpcConnectionMode(int ipcConnectionMode) {
this.ipcConnectionMode = ipcConnectionMode;
}
public void setIpcFixationIP(HashSet<String> ipcFixationIP) {
this.ipcFixationIP = ipcFixationIP;
}
public void setSubscribeInterfaceOptions(SubscribeInterfaceOptions subscribeInterfaceOptions) {
this.subscribeInterfaceOptions = subscribeInterfaceOptions;
}
public void setUnableLaunchAutopilotGear(Set<Chassis.GearPosition> unableLaunchAutopilotGear) {
AutopilotAbilityManager.getInstance().setUnableLaunchAutopilotGear(unableLaunchAutopilotGear);
}
}

View File

@@ -5,7 +5,7 @@ import androidx.annotation.NonNull;
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.zhidao.support.adas.high.common.MessageType;
import com.zhjt.mogo.adas.common.MessageType;
import com.zhjt.mogo.adas.data.AdasConstants;
import com.zhjt.mogo.adas.data.sweeper.bootable.SweeperBootable;
import com.zhjt.mogo.adas.data.sweeper.task.SweeperTask;
@@ -19,6 +19,7 @@ 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;
@@ -83,6 +84,13 @@ public interface IAdasNetCommApi {
*/
AdasConstants.SsmSource getUsedSsmSource();
/**
* 设置不能启动自动驾驶的档位
*
* @param unableLaunchAutopilotGear 不能起自驾档位
*/
void setUnableLaunchAutopilotGear(Set<Chassis.GearPosition> unableLaunchAutopilotGear);
/**
* 自动驾驶设备基础信息应答
*

View File

@@ -4,12 +4,13 @@ import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import com.mogo.support.obu.ObuScene;
import com.zhidao.support.adas.high.common.MessageType;
import com.zhidao.support.adas.high.common.ProtocolStatus;
import com.zhjt.mogo.adas.common.MessageType;
import com.zhjt.mogo.adas.data.AdasConstants;
import com.zhjt.mogo.adas.data.AiCloudTask;
import com.zhjt.mogo.adas.data.bean.AdasParam;
import com.zhjt.mogo.adas.data.bean.AutopilotStatistics;
import com.zhjt.mogo.adas.data.bean.ReceivedAck;
import com.zhjt.mogo.adas.data.bean.UnableLaunchData;
import com.zhjt.mogo.adas.data.bean.UnableLaunchReason;
import com.zhjt.mogo.adas.data.sweeper.bootable.SweeperBootable;
@@ -483,6 +484,14 @@ public interface OnAdasListener {
*/
void onParallelDrivingAbility(boolean isParallelDrivingAbility);
/**
* 回执消息
* PAD发送数据到域控的回执消息是否存在回执详情参见{@link MessageType} 枚举 TYPE_SEND_XXX_XXX 消息回执超时时间大于0的表示需要回执
*
* @param receivedAck 回执
*/
void onReceiveReceivedAck(@NonNull ReceivedAck receivedAck);
/**
* 启动自动驾驶失败回调
* 根据MAP 系统监控状态返回过滤

View File

@@ -1,83 +0,0 @@
package com.zhidao.support.adas.high.common;
import android.content.Context;
import android.content.SharedPreferences;
import com.google.gson.reflect.TypeToken;
import java.util.HashSet;
/**
* Created by nie yunlong on 2018/4/13.
* sharePreference 操作
* 根据 具体情况来写
*/
public class AppPreferenceHelper implements IPreferencesHelper {
public static AppPreferenceHelper appPreferenceHelper;
/**
* 保存deviceId 文件名称
*/
private final static String SP_NAME = "adas_config";
/**
* 手机Id
*/
private SharedPreferences ipcPre;
private HashSet<String> ipcFixationIPSet;//工控机固定IP列表
public static AppPreferenceHelper getInstance(Context context) {
if (appPreferenceHelper == null) {
appPreferenceHelper = new AppPreferenceHelper(context.getApplicationContext());
}
return appPreferenceHelper;
}
private AppPreferenceHelper(Context context) {
ipcPre = context.getSharedPreferences(SP_NAME, Context.MODE_PRIVATE);
getIPCFixationIPList();
}
@Override
public HashSet<String> getIPCFixationIPList() {
if (ipcFixationIPSet == null || ipcFixationIPSet.isEmpty()) {
String json = ipcPre.getString("ipc_fixation_ip", Constants.DEFAULT_IPC_FIXATION_IP);
ipcFixationIPSet = JsonUtil.fromJson(json, new TypeToken<HashSet<String>>() {
}.getType());
}
return ipcFixationIPSet;
}
@Override
public boolean addIPCFixationIP(String ipcIP) {
if (ipcFixationIPSet == null)
ipcFixationIPSet = new HashSet<>();
if (!ipcFixationIPSet.contains(ipcIP)) {
ipcFixationIPSet.add(ipcIP);
ipcPre.edit().putString("ipc_fixation_ip", JsonUtil.toJson(ipcFixationIPSet)).apply();
return true;
}
return false;
}
@Override
public boolean delIPCFixationIP(String ipcIP) {
if (ipcFixationIPSet != null && ipcFixationIPSet.contains(ipcIP)) {
ipcFixationIPSet.remove(ipcIP);
ipcPre.edit().putString("ipc_fixation_ip", JsonUtil.toJson(ipcFixationIPSet)).apply();
return true;
}
return false;
}
@Override
public void delIPCFixationIP() {
ipcPre.edit().remove("ipc_fixation_ip").apply();
}
}

View File

@@ -1,5 +1,9 @@
package com.zhidao.support.adas.high.common;
import com.google.gson.reflect.TypeToken;
import java.util.HashSet;
/**
* @ProjectName: lib-adas-fpga
* @Package: PACKAGE_NAME
@@ -132,4 +136,43 @@ public class Constants {
*/
int MO_FANG = 3;
}
private static HashSet<String> ipcFixationIPSet;//工控机固定IP列表
public static HashSet<String> getIPCFixationIPList() {
if (ipcFixationIPSet == null || ipcFixationIPSet.isEmpty()) {
String json = MMKVUtils.getInstance().getString("ipc_fixation_ip", Constants.DEFAULT_IPC_FIXATION_IP);
ipcFixationIPSet = JsonUtil.fromJson(json, new TypeToken<HashSet<String>>() {
}.getType());
}
return ipcFixationIPSet;
}
public static boolean addIPCFixationIP(String ipcIP) {
if (ipcFixationIPSet == null) {
getIPCFixationIPList();
}
if (ipcFixationIPSet == null) {
ipcFixationIPSet = new HashSet<>();
}
if (!ipcFixationIPSet.contains(ipcIP)) {
ipcFixationIPSet.add(ipcIP);
return MMKVUtils.getInstance().put("ipc_fixation_ip", JsonUtil.toJson(ipcFixationIPSet));
}
return false;
}
public static boolean delIPCFixationIP(String ipcIP) {
if (ipcFixationIPSet != null && ipcFixationIPSet.contains(ipcIP)) {
ipcFixationIPSet.remove(ipcIP);
return MMKVUtils.getInstance().put("ipc_fixation_ip", JsonUtil.toJson(ipcFixationIPSet));
}
return false;
}
public static void delIPCFixationIP() {
MMKVUtils.getInstance().removeKey("ipc_fixation_ip");
}
}

View File

@@ -53,17 +53,7 @@ public class CupidLogUtils {
Log.e("[tag=" + tag + "]", "[data=" + msg + "]");
}
public static void e(String msg) {
if (!mIsEnableLog) {
return;
}
Log.e("[tag=elita_lib]", "[data=" + msg + "]");
}
public static void w(String msg) {
if (!mIsEnableLog) {
return;
}
Log.e("[tag=elita_lib]", "[data=" + msg + "]");
public static void log(String tag, String msg) {
Log.i("[tag=" + tag + "]", "[data= " + msg + "]");
}
}

View File

@@ -1,39 +0,0 @@
package com.zhidao.support.adas.high.common;
import java.util.HashSet;
/**
* Created by nie yunlong on 2018/4/13.
*/
public interface IPreferencesHelper {
/**
* 获取工控机固定IP列表
*
* @return
*/
HashSet<String> getIPCFixationIPList();
/**
* 增加工控机固定IP
*
* @param ipcIP
*/
boolean addIPCFixationIP(String ipcIP);
/**
* 删除指定的工控机固定IP
*
* @param ipcIP
*/
boolean delIPCFixationIP(String ipcIP);
/**
* 删除所有工控机固定IP
*/
void delIPCFixationIP();
}

View File

@@ -0,0 +1,156 @@
package com.zhidao.support.adas.high.common;
import android.content.Context;
import android.os.Parcelable;
import com.tencent.mmkv.MMKV;
import java.util.Collections;
import java.util.Set;
/**
* MMKV Utils
*/
public class MMKVUtils {
private static volatile MMKV mmkv;
private static volatile MMKVUtils INSTANCE;
private MMKVUtils() {
}
public static MMKVUtils getInstance() {
if (INSTANCE == null) {
synchronized (MMKVUtils.class) {
if (INSTANCE == null) {
INSTANCE = new MMKVUtils();
}
}
}
return INSTANCE;
}
public void init(Context context) {
if (mmkv == null) {
MMKV.initialize(context);
// mmkv = MMKV.defaultMMKV(MMKV.MULTI_PROCESS_MODE, null);//多进程模式
mmkv = MMKV.defaultMMKV();
}
}
/**
* 写入基本数据类型缓存
*
* @param key 键
* @param object 值
*/
public boolean put(String key, Object object) {
if (object instanceof String) {
return mmkv.encode(key, (String) object);
} else if (object instanceof Integer) {
return mmkv.encode(key, (Integer) object);
} else if (object instanceof Boolean) {
return mmkv.encode(key, (Boolean) object);
} else if (object instanceof Float) {
return mmkv.encode(key, (Float) object);
} else if (object instanceof Long) {
return mmkv.encode(key, (Long) object);
} else if (object instanceof Double) {
return mmkv.encode(key, (Double) object);
} else if (object instanceof byte[]) {
return mmkv.encode(key, (byte[]) object);
} else {
return mmkv.encode(key, object.toString());
}
}
public void putSet(String key, Set<String> sets) {
mmkv.encode(key, sets);
}
public void putParcelable(String key, Parcelable obj) {
mmkv.encode(key, obj);
}
public Integer getInt(String key) {
return mmkv.decodeInt(key, 0);
}
public Integer getInt(String key, int defaultValue) {
return mmkv.decodeInt(key, defaultValue);
}
public Double getDouble(String key) {
return mmkv.decodeDouble(key, 0.00);
}
public Double getDouble(String key, double defaultValue) {
return mmkv.decodeDouble(key, defaultValue);
}
public Long getLong(String key) {
return mmkv.decodeLong(key, 0L);
}
public Long getLong(String key, long defaultValue) {
return mmkv.decodeLong(key, defaultValue);
}
public Boolean getBoolean(String key) {
return mmkv.decodeBool(key, false);
}
public Boolean getBoolean(String key, boolean defaultValue) {
return mmkv.decodeBool(key, defaultValue);
}
public Float getFloat(String key) {
return mmkv.decodeFloat(key, 0F);
}
public Float getFloat(String key, float defaultValue) {
return mmkv.decodeFloat(key, defaultValue);
}
public byte[] getBytes(String key) {
return mmkv.decodeBytes(key);
}
public byte[] getBytes(String key, byte[] defaultValue) {
return mmkv.decodeBytes(key, defaultValue);
}
public String getString(String key) {
return mmkv.decodeString(key, "");
}
public String getString(String key, String defaultValue) {
return mmkv.decodeString(key, defaultValue);
}
public Set<String> getStringSet(String key) {
return mmkv.decodeStringSet(key, Collections.<String>emptySet());
}
public Parcelable getParcelable(String key) {
return mmkv.decodeParcelable(key, null);
}
/**
* 移除某个key对
*
* @param key
*/
public void removeKey(String key) {
mmkv.removeValueForKey(key);
}
/**
* 清除所有key
*/
public void clearAll() {
mmkv.clearAll();
}
}

View File

@@ -0,0 +1,125 @@
package com.zhidao.support.adas.high.common;
import com.google.protobuf.InvalidProtocolBufferException;
import com.zhjt.mogo.adas.data.Adas;
import java.util.Calendar;
import java.util.Collections;
import java.util.Map;
import mogo.telematics.pad.MessagePad;
/**
* 发送数据时ID生成器
* 每天生成的ID重1开始自增也可以表示为发送的数量
*/
public class MessageIdGenerator {
private static final String TAG = "MessageIdGenerator";
private static volatile MessageIdGenerator INSTANCE;
private final static int DEFAULT_COUNT = 30;//默认保留数量
private final static String KEY_NAME = "send_message_id";//序列化名称
private final Adas.MessageIdInfo.Builder messageIdInfoBuilder;
private Adas.LastMessage lastMessage = null;
private final long data;//日期long值
public static MessageIdGenerator getInstance() {
if (INSTANCE == null) {
synchronized (MessageIdGenerator.class) {
if (INSTANCE == null) {
INSTANCE = new MessageIdGenerator();
}
}
}
return INSTANCE;
}
private MessageIdGenerator() {
Calendar calendar = Calendar.getInstance();
// 设置时间为当天的 00:00:00
calendar.set(Calendar.HOUR_OF_DAY, 0);
calendar.set(Calendar.MINUTE, 0);
calendar.set(Calendar.SECOND, 0);
calendar.set(Calendar.MILLISECOND, 0);
data = calendar.getTimeInMillis();
Adas.MessageIdInfo messageIdInfo = null;
byte[] bytes = MMKVUtils.getInstance().getBytes(KEY_NAME);
if (bytes != null) {
try {
messageIdInfo = Adas.MessageIdInfo.parseFrom(bytes);
} catch (InvalidProtocolBufferException e) {
e.printStackTrace();
}
}
if (messageIdInfo == null) {
messageIdInfoBuilder = Adas.MessageIdInfo.newBuilder();
} else {
messageIdInfoBuilder = messageIdInfo.toBuilder();
if (messageIdInfoBuilder.getLastMessagesCount() >= DEFAULT_COUNT) {
long minValue = Collections.min(messageIdInfoBuilder.getLastMessagesMap().keySet());
messageIdInfoBuilder.removeLastMessages(minValue);
save();
}
}
initLastMessageData();
}
/**
* 获取全部已存储的消息ID
* LastMessage中的msgID如果是0表明今日还未下发任何数据
*
* @return key日期毫秒值 value最后一条消息的相关信息
*/
public Map<Long, Adas.LastMessage> getAllSendMessageId() {
return messageIdInfoBuilder.getLastMessagesMap();
}
// private void test() {
// SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd", Locale.getDefault());
//
// for (long l : messageIdInfoBuilder.getLastMessagesMap().keySet()) {
// Log.i("ddddddddddd", "====" + formatter.format(new Date(l)));
// }
// Log.i("ddddddddddd", "===========================");
//
//// Log.i("ddddddddddd", "日期=" + formatter.format(new Date(data)));
//// lastMessage = messageIdInfoBuilder.getLastMessagesOrDefault(data, null);
//// if (lastMessage != null) {
//// Log.i("ddddddddddd", "消息ID=" + lastMessage.getMsgID());
//// Log.i("ddddddddddd", "消息类型=" + (lastMessage.getMsgType() == null ? null : lastMessage.getMsgType().name()));
//// Log.i("ddddddddddd", "发送时间=" + (lastMessage.getTimestamp() == 0 ? null : formatter.format(new Date(lastMessage.getTimestamp()))));
//// }
// }
private void initLastMessageData() {
lastMessage = messageIdInfoBuilder.getLastMessagesOrDefault(data, null);
if (lastMessage == null) {
lastMessage = Adas.LastMessage.newBuilder().setMsgID(0).build();
messageIdInfoBuilder.putLastMessages(data, lastMessage);
}
}
private void save() {
MMKVUtils.getInstance().put(KEY_NAME, messageIdInfoBuilder.build().toByteArray());
}
/**
* TODO 10000次存储平均耗时=0.2036132830000002毫秒
*
* @param timestamp
* @param type
* @return
*/
public long getId(long timestamp, MessagePad.MessageType type) {
long id = lastMessage.getMsgID() + 1;
CupidLogUtils.i(TAG, "自增ID=" + id);
lastMessage = lastMessage.toBuilder().setTimestamp(timestamp).setMsgType(type).setMsgID(id).build();
messageIdInfoBuilder.putLastMessages(data, lastMessage);
save();
// test();
return id;
}
}

View File

@@ -0,0 +1,153 @@
package com.zhidao.support.adas.high.common;
import androidx.annotation.NonNull;
import com.zhjt.mogo.adas.common.MessageType;
import com.zhjt.mogo.adas.data.bean.ReceivedAck;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Iterator;
import java.util.List;
import java.util.Timer;
import java.util.TimerTask;
import java.util.concurrent.atomic.AtomicBoolean;
import mogo.telematics.pad.MessagePad;
/**
* 回执消息管理
*/
public class ReceivedAckManager {
private static final String TAG = ReceivedAckManager.class.getSimpleName();
private volatile Timer timer;
private final List<ReceivedAck> list = Collections.synchronizedList(new ArrayList<>());
private final AtomicBoolean isSupport = new AtomicBoolean(false);//是否支持回执功能
private OnReceivedAckListener listener;
public void setListener(OnReceivedAckListener listener) {
this.listener = listener;
}
public interface OnReceivedAckListener {
/**
* 回执消息
*
* @param receivedAck 回执
*/
void onReceiveReceivedAck(@NonNull ReceivedAck receivedAck);
/**
* 发送回执消息
*
* @param bytes
*/
void onSendReceivedAck(MessageType messageType, byte[] bytes);
}
public void setSupport(int version) {
isSupport.set(version >= 30800);
CupidLogUtils.log(TAG, version + " 是否支持回执功能=" + isSupport.get());
if (!isSupport.get()) {
stop();
}
}
/**
* 添加需要回执的消息
*
* @param sendTime
* @param msgId
* @param messageType
* @param sendData
*/
public void addNeedAckData(long sendTime, long msgId, MessageType messageType, byte[] sendData) {
if (isSupport.get()) {
start();
list.add(new ReceivedAck(sendTime, msgId, messageType, sendData));
} else {
stop();
}
}
/**
* 接收到回执
*
* @param time 接收时间
* @param receivedAck 回执数据
*/
public void receiveReceivedAck(long time, MessagePad.ReceivedAck receivedAck) {
int count = receivedAck.getMsgidsCount();
if (!list.isEmpty() && count > 0) {
Iterator<ReceivedAck> iterator = list.iterator();
while (iterator.hasNext()) {
ReceivedAck ack = iterator.next();
for (int i = 0; i < count; i++) {
long msgId = receivedAck.getMsgids(i);
if (msgId == ack.getMsgId()) {
iterator.remove();
ack.setTimeout(false);
ack.setReceiveTime(time);
ack.setReceivedAck(receivedAck);
if (listener != null) {
listener.onReceiveReceivedAck(ack);
}
break;
}
}
}
}
}
private synchronized void start() {
if (timer == null) {
timer = new Timer();
timer.schedule(new TimerTask() {
@Override
public void run() {
if (!list.isEmpty()) {
long time = System.currentTimeMillis();
Iterator<ReceivedAck> iterator = list.iterator();
while (iterator.hasNext()) {
ReceivedAck ack = iterator.next();
if (time - ack.getSendTime() > ack.getMessageType().timeoutMillis) {
//超时
iterator.remove();
ack.setTimeout(true);
if (listener != null) {
listener.onReceiveReceivedAck(ack);
}
}
}
}
}
}, 2000L, 1000L);
}
}
public void stop() {
if (!list.isEmpty()) {
list.clear();
}
if (timer != null) {
timer.cancel();
timer = null;
}
}
/**
* 打包回执数据
*
* @param msgID 要回复的消息ID
*/
public void sendReceivedAck(long msgID) {
MessagePad.ReceivedAck receivedAck = MessagePad.ReceivedAck.newBuilder()
.addMsgids(msgID)
.build();
if (listener != null) {
listener.onSendReceivedAck(MessageType.TYPE_SEND_RECEIVED_ACK, receivedAck.toByteArray());
}
}
}

View File

@@ -34,7 +34,7 @@ public class CarConfigRespMessage extends MyAbstractMessageHandler {
adasListener.onCarConfigResp(raw.getHeader(), carConfigResp);
}
AdasChannel.calculateTimeConsumingBusiness("车机基础信息应答", nowTime);
CupidLogUtils.e("车机基础信息应答--->" + carConfigResp);
CupidLogUtils.e("CarConfigRespMessage", "车机基础信息应答--->" + carConfigResp);
}
/**

View File

@@ -1,7 +1,7 @@
package com.zhidao.support.adas.high.msg;
import com.zhidao.support.adas.high.common.AutopilotReview;
import com.zhidao.support.adas.high.common.MessageType;
import com.zhjt.mogo.adas.common.MessageType;
import mogo.telematics.pad.MessagePad;

View File

@@ -1,9 +1,10 @@
package com.zhidao.support.adas.high.protocol;
import com.zhjt.mogo.adas.utils.ByteUtil;
import com.zhidao.support.adas.high.common.Constants;
import java.util.concurrent.atomic.AtomicLong;
import com.zhidao.support.adas.high.common.MessageIdGenerator;
import com.zhidao.support.adas.high.common.ReceivedAckManager;
import com.zhjt.mogo.adas.common.MessageType;
import com.zhjt.mogo.adas.utils.ByteUtil;
import mogo.telematics.pad.MessagePad;
@@ -17,24 +18,30 @@ import mogo.telematics.pad.MessagePad;
public class RawPack {
private static final String TAG = RawPack.class.getSimpleName();
private final DefaultMessageProtocol messageProtocol;
private final AtomicLong msgID = new AtomicLong(0L);
private final ReceivedAckManager receivedAckManager;
public RawPack() {
public RawPack(ReceivedAckManager receivedAckManager) {
this.receivedAckManager = receivedAckManager;
messageProtocol = new DefaultMessageProtocol();
}
public synchronized byte[] pack(MessagePad.MessageType msgType, byte[] data) {
public synchronized byte[] pack(MessageType msgType, byte[] data) {
if (msgType == null) {
return null;
}
double time = System.currentTimeMillis() / 1000.0;
long timeMillis = System.currentTimeMillis();
MessagePad.MessageType type = msgType.typeCode;
double time = timeMillis / 1000.0;
boolean isNeedAck = msgType.timeoutMillis > 0;
long msgId = MessageIdGenerator.getInstance().getId(timeMillis, type);
//封装Header
MessagePad.Header.Builder headerBuilder = MessagePad.Header.newBuilder();
headerBuilder.setMsgID(msgID.incrementAndGet());//消息唯一ID生成数据累加。从1开始连接未重新初始化就一直累加
headerBuilder.setMsgType(msgType);
headerBuilder.setMsgID(msgId);//消息唯一ID生成数据累加。从1开始连接未重新初始化就一直累加
headerBuilder.setMsgType(type);
headerBuilder.setTimestamp(time);
headerBuilder.setSourceTimestamp(time);
headerBuilder.setNeedAck(isNeedAck ? 1 : 0);
MessagePad.Header headerPb = headerBuilder.build();
int lengthValue = messageProtocol.getOutHeaderLength() + headerPb.getSerializedSize();//数据总长度
byte[] offset = getOffset(lengthValue);
@@ -56,6 +63,9 @@ public class RawPack {
if (data != null && data.length > 0) {
System.arraycopy(data, 0, msg, messageProtocol.getOutHeaderLength() + header.length, data.length);
}
if (isNeedAck) {
receivedAckManager.addNeedAckData(timeMillis, msgId, msgType, msg);
}
return msg;
}

View File

@@ -15,12 +15,12 @@ import androidx.annotation.NonNull;
import com.google.protobuf.InvalidProtocolBufferException;
import com.zhidao.support.adas.high.AdasChannel;
import com.zhjt.mogo.adas.utils.ByteUtil;
import com.zhidao.support.adas.high.common.CupidLogUtils;
import com.zhidao.support.adas.high.common.ReceiveTimeoutManager;
import com.zhidao.support.adas.high.common.ReconnectManager;
import com.zhidao.support.adas.high.queue.WSByteQueueManager;
import com.zhidao.support.adas.high.queue.WebSocketQueueManager;
import com.zhjt.mogo.adas.utils.ByteUtil;
import com.zhjt.service.chain.ChainLog;
import java.util.Locale;
@@ -61,7 +61,7 @@ public class FpgaSocket implements IWebSocket {
private String wsHost;
private String ipAddress;
private int port;
private boolean isEnableReconnect = true;//是否启用重连机制
/**
* 是否是用户主动关闭socket
*/
@@ -79,12 +79,18 @@ public class FpgaSocket implements IWebSocket {
* 接收数据超时原因 null时表示不是接收数据超时的原因
*/
private volatile String receiveTimeoutReason = null;
private Context context;
public FpgaSocket(Context context) {
init(context);
this.context = context;
init();
}
private void init(Context context) {
public boolean isConnected() {
return isConnected.get();
}
private void init() {
listener = new EchoWebSocketListener();
OkHttpClient.Builder okBuilder = new OkHttpClient.Builder();
okBuilder.writeTimeout(4, TimeUnit.SECONDS)
@@ -97,15 +103,29 @@ public class FpgaSocket implements IWebSocket {
onPassiveClose(1001, receiveTimeoutReason);
}
});
reconnectManager = new ReconnectManager(context, new ReconnectManager.OnReconnectListener() {
@Override
public void onReconnection(String tag) {
connect("重连中(" + tag + "");
}
});
client = okBuilder.build();
}
//配置是否启用重连
public void setEnableReconnect(boolean enableReconnect) {
isEnableReconnect = enableReconnect;
Log.i(TAG, "是否启动自动重连=" + enableReconnect);
if (isEnableReconnect) {
if (reconnectManager == null)
reconnectManager = new ReconnectManager(context, new ReconnectManager.OnReconnectListener() {
@Override
public void onReconnection(String tag) {
connect("重连中(" + tag + "");
}
});
} else {
if (reconnectManager != null) {
reconnectManager.stop();
reconnectManager = null;
}
}
}
@Override
public void connectWebSocket(String address, int port) {
this.ipAddress = address;
@@ -124,18 +144,30 @@ public class FpgaSocket implements IWebSocket {
Request request = new Request.Builder()
.url(wsHost)
.build();
mWebSocket = new RealWebSocket(request, listener, new Random(), 0);
mWebSocket = new RealWebSocket(request, listener, new Random(), client.pingIntervalMillis());
mWebSocket.connect(client);
// mWebSocket = client.newWebSocket(request, listener);
}
}
private void reconnectCmd(boolean isStart) {
if (reconnectManager != null) {
if (isStart) {
if (isEnableReconnect) {
reconnectManager.start();
}
} else {
reconnectManager.stop();
}
}
}
/**
* 重连
*/
private void reconnect() {
if (!isUserClose.get()) {
reconnectManager.start();
reconnectCmd(true);
} else {
isUserClose.set(false);
}
@@ -149,7 +181,7 @@ public class FpgaSocket implements IWebSocket {
}
isUserClose.set(true);
isPassiveClose.set(false);
reconnectManager.stop();
reconnectCmd(false);
if (mWebSocket != null) {
close(true, 1000);
} else {
@@ -214,7 +246,7 @@ public class FpgaSocket implements IWebSocket {
if (!isConnect) {
onPassiveClose(1001, "協議不匹配");
} else {
reconnectManager.stop();
reconnectCmd(false);
ReceiveTimeoutManager.getInstance().start();
CupidLogUtils.i(TAG, "WebSocket 连接成功");
if (mWebSocketConnectListener != null)

View File

@@ -1,10 +1,11 @@
package com.zhidao.support.adas.high.subscribe;
import androidx.annotation.NonNull;
import com.zhidao.support.adas.high.common.Constants;
import com.zhidao.support.adas.high.common.Define;
import com.zhidao.support.adas.high.common.MessageType;
import com.zhjt.mogo.adas.common.MessageType;
import java.util.HashMap;
import java.util.Map;
@@ -36,6 +37,7 @@ public class SubscribeInterface {
public SubscribeInterface(@NonNull OnSubscribeInterfaceListener listener) {
this.listener = listener;
if (listener == null) throw new RuntimeException();
init();
}
@@ -61,8 +63,10 @@ public class SubscribeInterface {
* @param role 角色 详情参见{@link Constants.TERMINAL_ROLE}
* @param type 注册类型 详情参见{@link Constants.SUBSCRIBE_TYPE}
* @param messageTypes 要操作的接口
* @return
*/
public boolean subscribeInterface(@Define.TerminalRole int role, @Define.SubscribeType int type, @NonNull Set<MessageType> messageTypes) {
if (messageTypes == null) return false;
MessagePad.SubscribeDataReq.Builder builder = MessagePad.SubscribeDataReq.newBuilder();
builder.setRole(role).setReqType(type);
Map<MessageType, Integer> temp = new HashMap<>();
@@ -86,6 +90,8 @@ public class SubscribeInterface {
}
}
}
return isSendSucceed;
}
@@ -98,6 +104,7 @@ public class SubscribeInterface {
* @return 是否加入ws发送队列
*/
public boolean subscribeInterface(@Define.TerminalRole int role, @Define.SubscribeType int type, @NonNull MessageType messageType) {
if (messageType == null) return false;
MessagePad.SubscribeDataReq.Builder builder = MessagePad.SubscribeDataReq.newBuilder();
builder.setRole(role).setReqType(type).addDataTypes(messageType.typeCode.getNumber());
boolean isSendSucceed = listener.onSendSubscribe(builder.build().toByteArray());

View File

@@ -0,0 +1,49 @@
package com.zhidao.support.adas.high.subscribe;
import androidx.annotation.NonNull;
import com.zhidao.support.adas.high.common.Constants;
import com.zhidao.support.adas.high.common.Define;
import com.zhjt.mogo.adas.common.MessageType;
import java.util.Set;
/**
* 订阅参数
*/
public class SubscribeInterfaceOption {
@Define.TerminalRole
private int role = Constants.TERMINAL_ROLE.DRIVER;
@Define.SubscribeType
private int type = Constants.SUBSCRIBE_TYPE.UNSUBSCRIBE;
private MessageType messageType = null;//操作一个接口
private Set<MessageType> messageTypes = null;//操作多个接口
public SubscribeInterfaceOption(@Define.TerminalRole int role, @Define.SubscribeType int type, @NonNull MessageType messageType) {
this.role = role;
this.type = type;
this.messageType = messageType;
}
public SubscribeInterfaceOption(@Define.TerminalRole int role, @Define.SubscribeType int type, @NonNull Set<MessageType> messageTypes) {
this.role = role;
this.type = type;
this.messageTypes = messageTypes;
}
public int getRole() {
return role;
}
public int getType() {
return type;
}
public MessageType getMessageType() {
return messageType;
}
public Set<MessageType> getMessageTypes() {
return messageTypes;
}
}

View File

@@ -1,71 +0,0 @@
package com.zhidao.support.adas.high.subscribe;
import com.zhidao.support.adas.high.common.Constants;
import com.zhidao.support.adas.high.common.Define;
import com.zhidao.support.adas.high.common.MessageType;
import java.util.Set;
/**
* 订阅参数
*/
public class SubscribeInterfaceOptions {
@Define.TerminalRole
private int role = Constants.TERMINAL_ROLE.DRIVER;
@Define.SubscribeType
private int type = Constants.SUBSCRIBE_TYPE.UNSUBSCRIBE;
private Set<MessageType> messageTypes;
private SubscribeInterfaceOptions() {
}
public int getRole() {
return role;
}
public int getType() {
return type;
}
public Set<MessageType> getMessageTypes() {
return messageTypes;
}
public static Builder newBuilder() {
return new Builder();
}
public static class Builder {
@Define.TerminalRole
private int role;
@Define.SubscribeType
private int type;
private Set<MessageType> messageTypes;
private Builder() {
}
public Builder setRole(@Define.TerminalRole int role) {
this.role = role;
return this;
}
public Builder setType(@Define.SubscribeType int type) {
this.type = type;
return this;
}
public Builder setMessageTypes(Set<MessageType> messageTypes) {
this.messageTypes = messageTypes;
return this;
}
public SubscribeInterfaceOptions build() {
SubscribeInterfaceOptions options = new SubscribeInterfaceOptions();
options.role = role;
options.type = type;
options.messageTypes = messageTypes;
return options;
}
}
}