协议解析基本完成
This commit is contained in:
@@ -35,4 +35,9 @@ public class ObuConstant {
|
||||
* 为vip车辆变灯提醒
|
||||
*/
|
||||
public static final int TYPE_CHANGE_LIGHT_FOR_VIP = 116;
|
||||
|
||||
/**
|
||||
* 闯红灯预警
|
||||
*/
|
||||
public static final int TYPE_RUSH_RED_LIGHT = 117;
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
package com.zhidao.mogo.module.obu.obu
|
||||
|
||||
open class BaseObu : IObu {
|
||||
abstract class BaseObu : IObu {
|
||||
protected var callback: IObuCallback? = null
|
||||
override fun init() {
|
||||
}
|
||||
|
||||
@@ -1,47 +1,177 @@
|
||||
package com.zhidao.mogo.module.obu.obu
|
||||
|
||||
import com.mogo.utils.logger.Logger
|
||||
import com.zhidao.mogo.module.obu.ObuConstant
|
||||
import com.zhidao.mogo.module.obu.obu.bean.MogoObuEventInfo
|
||||
import com.zhidao.mogo.module.obu.socket.IUdpSocketCallback
|
||||
import com.zhidao.mogo.module.obu.socket.UdpSocketManager
|
||||
import org.json.JSONObject
|
||||
import java.lang.StringBuilder
|
||||
import kotlin.concurrent.thread
|
||||
import kotlin.experimental.and
|
||||
import kotlin.experimental.xor
|
||||
|
||||
/**
|
||||
* 华砺智行obu 苏州演示项目用到的
|
||||
*
|
||||
* @author tongchenfei
|
||||
*/
|
||||
class HualiObu : BaseObu(),IUdpSocketCallback {
|
||||
class HualiObu : BaseObu(), IUdpSocketCallback {
|
||||
private val socketManager = UdpSocketManager(this)
|
||||
companion object{
|
||||
|
||||
companion object {
|
||||
const val TAG = "HualiObu"
|
||||
const val IP_ADDRESS = "172.30.31.44"
|
||||
const val PORT = 10005
|
||||
}
|
||||
|
||||
override fun init() {
|
||||
super.init()
|
||||
socketManager.receiveMsgFrom(IP_ADDRESS, PORT)
|
||||
socketManager.sendMsgTo("Hello ssokit", IP_ADDRESS, PORT)
|
||||
Logger.d(TAG, "init")
|
||||
thread {
|
||||
var count = 0
|
||||
while (true) {
|
||||
Logger.d(TAG,"准备发送测试数据===")
|
||||
socketManager.sendMsgTo("Hello ssokit===$count", IP_ADDRESS, PORT)
|
||||
count++
|
||||
Thread.sleep(1000)
|
||||
if (count == 1000) {
|
||||
Logger.d(TAG, "测试数据结束")
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override fun onMessageReceived(msg: ByteArray) {
|
||||
// todo 处理数据
|
||||
val m = String(msg)
|
||||
Logger.d(TAG, "onMessageReceived: $msg")
|
||||
|
||||
Logger.d(TAG, "onMessageReceived: $m")
|
||||
parseObuProtocol(msg)
|
||||
}
|
||||
|
||||
/**
|
||||
* 解析obu数据
|
||||
*
|
||||
* @param ori 原始数据
|
||||
*/
|
||||
private fun parseObuProtocol(ori: ByteArray) {
|
||||
val effectiveData = getEffectiveData(ori)
|
||||
if (effectiveData != null) {
|
||||
val msg = String(effectiveData)
|
||||
Logger.d(TAG, "收到obu数据: \n $msg")
|
||||
val json = JSONObject(msg)
|
||||
val rushRedLight = json.optJSONObject("rush_redlight")
|
||||
rushRedLight?.let {
|
||||
// 有闯红灯告警信息,绿波车速信息
|
||||
Logger.d(TAG, "收到闯红灯告警信息: \n $it")
|
||||
val glosaInfo = it.optJSONArray("glosa_info")
|
||||
glosaInfo?.let { info ->
|
||||
Logger.d(TAG, "收到红绿灯信息: $info")
|
||||
val lastInfo = info.getJSONObject(0)
|
||||
val alert = lastInfo.optInt("rush_redlight_alarm", -1)
|
||||
val eventInfo = MogoObuEventInfo()
|
||||
when (alert) {
|
||||
0 -> {
|
||||
// 有闯红灯风险
|
||||
Logger.d(TAG,"准备预警--闯红灯")
|
||||
eventInfo.mogoEventId = ObuConstant.TYPE_RUSH_RED_LIGHT
|
||||
eventInfo.describe = "当前车速经过路口会闯红灯,请减速!"
|
||||
callback?.onEventInfoCallback(eventInfo)
|
||||
}
|
||||
1 -> {
|
||||
// 没有风险,给出建议车速,绿波车速
|
||||
Logger.d(TAG,"准备预警--绿波车速")
|
||||
eventInfo.mogoEventId = ObuConstant.TYPE_OPTIMAL_SPEED_ADVISORY
|
||||
val optSpeed = lastInfo.optInt("advisory_speed")
|
||||
eventInfo.describe = "前方路口,建议车速 $optSpeed km/h"
|
||||
callback?.onEventInfoCallback(eventInfo)
|
||||
}
|
||||
else -> {
|
||||
Logger.e(TAG,"没有有效红绿灯预警信息")
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
val intersectionCrash = json.optJSONObject("intersection_crash")
|
||||
intersectionCrash?.let {
|
||||
// 有交叉路口碰撞预警信息
|
||||
Logger.d(TAG, "收到交叉路口碰撞信息: \n $it")
|
||||
val alert = it.optInt("intersection_crash_alarm", 0)
|
||||
if (alert == 1) {
|
||||
// 有碰撞预警
|
||||
Logger.d(TAG,"准备预警--交叉口碰撞")
|
||||
val eventInfo = MogoObuEventInfo()
|
||||
eventInfo.mogoEventId = ObuConstant.TYPE_CROSS_COLLISION_WARNING
|
||||
callback?.onEventInfoCallback(eventInfo)
|
||||
}
|
||||
|
||||
}
|
||||
val pedestrainInformation = json.optJSONObject("pedestrain_information")
|
||||
pedestrainInformation?.let {
|
||||
// 有人车冲突信息
|
||||
Logger.d(TAG, "收到人车冲突信息: \n $it")
|
||||
val alert = it.optInt("pedestrian_crash_alarm", 0)
|
||||
if (alert == 1) {
|
||||
// 有人车冲突
|
||||
Logger.d(TAG,"准备预警--行人碰撞")
|
||||
val eventInfo = MogoObuEventInfo()
|
||||
eventInfo.mogoEventId = ObuConstant.TYPE_ROAD_USER_COLLISION_WARNING
|
||||
}
|
||||
|
||||
}
|
||||
val position = json.optJSONObject("position_3d")
|
||||
position?.let {
|
||||
// 定位信息
|
||||
Logger.d(TAG, "收到定位信息: \n $it")
|
||||
|
||||
}
|
||||
|
||||
val motion = json.optJSONObject("motion")
|
||||
motion?.let {
|
||||
// 行驶信息
|
||||
Logger.d(TAG, "收到行驶信息: \n $it")
|
||||
|
||||
}
|
||||
} else {
|
||||
Logger.e(TAG, "有效数据为空,无法解析")
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 从原始数据中,根据数据长度字节,取出有效数据
|
||||
*
|
||||
* @param oriMsg 原始数据
|
||||
* @return 有效数据
|
||||
*/
|
||||
private fun getEffectiveData(oriMsg: ByteArray): ByteArray? {
|
||||
val dataLengthInfo = ByteArray(4)
|
||||
System.arraycopy(oriMsg, 16, dataLengthInfo, 0, 4)
|
||||
printByteArray(dataLengthInfo)
|
||||
val dataLength = convertTwoUnSignInt(dataLengthInfo)
|
||||
Logger.d(TAG, "解析后的长度: $dataLength")
|
||||
val parseData = ByteArray(dataLength + 21)
|
||||
System.arraycopy(oriMsg, 0, parseData, 0, parseData.size)
|
||||
return if (isAvailable(parseData)) {
|
||||
val msg = ByteArray(dataLength)
|
||||
System.arraycopy(parseData, 20, msg, 0, dataLength)
|
||||
msg
|
||||
} else {
|
||||
null
|
||||
}
|
||||
}
|
||||
|
||||
private fun isAvailable(msg: ByteArray): Boolean {
|
||||
val checkSum = msg.last()
|
||||
var check = msg[0].xor(0xff.toByte())
|
||||
for (i in 1 until msg.size - 1) {
|
||||
check = check.xor(msg[i])
|
||||
}
|
||||
return checkSum == check
|
||||
}
|
||||
|
||||
private fun printByteArray(array: ByteArray) {
|
||||
val arrayBuilder = StringBuilder()
|
||||
array.forEach {
|
||||
val res = it.toInt() and 0xff
|
||||
arrayBuilder.append("0x")
|
||||
if (res < 10) {
|
||||
arrayBuilder.append("0")
|
||||
}
|
||||
arrayBuilder.append(it.toString(16)).append(", ")
|
||||
}
|
||||
Logger.d(TAG, arrayBuilder.toString())
|
||||
}
|
||||
|
||||
private fun convertTwoUnSignInt(byteArray: ByteArray): Int =
|
||||
(byteArray[0].toInt() shl 24) or (byteArray[1].toInt() and 0xFF) or (byteArray[2].toInt() shl 8) or (byteArray[3].toInt() and 0xFF)
|
||||
|
||||
}
|
||||
@@ -14,4 +14,5 @@ interface IObu {
|
||||
* 注册数据回调
|
||||
*/
|
||||
fun registerObuCallback(callback: IObuCallback)
|
||||
|
||||
}
|
||||
@@ -1,5 +1,6 @@
|
||||
package com.zhidao.mogo.module.obu.obu.bean
|
||||
|
||||
import com.zhidao.mogo.module.obu.ObuConstant
|
||||
import com.zhidao.smartv2x.model.obu.CarEventInfo
|
||||
|
||||
/**
|
||||
@@ -9,8 +10,13 @@ import com.zhidao.smartv2x.model.obu.CarEventInfo
|
||||
*/
|
||||
class MogoObuEventInfo(){
|
||||
var typeCode:String? = null
|
||||
set(value){
|
||||
mogoEventId = parseObuEvent(value)
|
||||
field = value
|
||||
}
|
||||
var type:String? = null
|
||||
var describe:String? = null
|
||||
var mogoEventId:Int = 0
|
||||
override fun toString(): String {
|
||||
return "MogoObuEventInfo(typeCode=$typeCode, type=$type, describe=$describe)"
|
||||
}
|
||||
@@ -21,4 +27,18 @@ class MogoObuEventInfo(){
|
||||
this.describe = info.describe
|
||||
}
|
||||
|
||||
private fun parseObuEvent(type: String?): Int {
|
||||
return when (type) {
|
||||
"06" -> // 紧急制动预警
|
||||
ObuConstant.TYPE_URGENCY_COLLISION_WARNING
|
||||
"13" -> // 绿波车速引导
|
||||
ObuConstant.TYPE_OPTIMAL_SPEED_ADVISORY
|
||||
"39" -> // 行人碰撞预警
|
||||
ObuConstant.TYPE_ROAD_USER_COLLISION_WARNING
|
||||
"vip变灯提醒" -> ObuConstant.TYPE_CHANGE_LIGHT_FOR_VIP
|
||||
null -> -1
|
||||
else -> type.toInt()
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -18,6 +18,7 @@ import com.mogo.module.v2x.scenario.scene.obu.V2XObuEventScenario;
|
||||
import com.mogo.module.v2x.utils.ADASUtils;
|
||||
import com.mogo.module.v2x.utils.DrivingDirectionUtils;
|
||||
import com.mogo.module.v2x.utils.ObuConfig;
|
||||
import com.mogo.module.v2x.utils.TestOnLineCarUtils;
|
||||
import com.mogo.utils.logger.Logger;
|
||||
import com.zhidao.mogo.module.obu.ObuConstant;
|
||||
import com.zhidao.mogo.module.obu.ObuManager;
|
||||
@@ -31,7 +32,10 @@ import org.json.JSONObject;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
import androidx.localbroadcastmanager.content.LocalBroadcastManager;
|
||||
|
||||
import static com.mogo.module.v2x.V2XConst.MODULE_NAME;
|
||||
import static com.mogo.module.v2x.V2XServiceManager.getContext;
|
||||
import static com.mogo.module.v2x.scenario.scene.obu.V2XObuEventScenario.ACTION_LAUNCHER_ADAS_APP_BIZ;
|
||||
|
||||
/**
|
||||
@@ -143,7 +147,7 @@ public class V2XObuManager implements IObuCallback, Handler.Callback {
|
||||
Logger.d(MODULE_NAME, "发送红绿灯广播: " + data);
|
||||
intent.putExtra("data", data);
|
||||
intent.putExtra("type", 2);
|
||||
V2XServiceManager.getContext().sendBroadcast(intent);
|
||||
getContext().sendBroadcast(intent);
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
Logger.e(MODULE_NAME, e, "发送红绿灯广播异常==");
|
||||
@@ -166,7 +170,8 @@ public class V2XObuManager implements IObuCallback, Handler.Callback {
|
||||
if (last == null) {
|
||||
last = 0L;
|
||||
}
|
||||
int eventType = parseObuEvent(info.getTypeCode());
|
||||
// int eventType = parseObuEvent(info.getTypeCode());
|
||||
int eventType = info.getMogoEventId();
|
||||
if (eventType == ObuConstant.TYPE_OPTIMAL_SPEED_ADVISORY) {
|
||||
// 加一个容错机制,如果已经驶过绿波车速路口,那么再收到绿波车速obu事件,就不再上报
|
||||
MogoLocation currentLocation = V2XLocationListener.getInstance().getLastCarLocation();
|
||||
@@ -213,7 +218,7 @@ public class V2XObuManager implements IObuCallback, Handler.Callback {
|
||||
entity.setTts("前方行人,注意减速");
|
||||
entity.setExpireTime(30_000);
|
||||
entity.setAlarmContent("前方行人,注意减速");
|
||||
ADASUtils.broadcastToADAS(V2XServiceManager.getContext(), entity);
|
||||
ADASUtils.broadcastToADAS(getContext(), entity);
|
||||
break;
|
||||
case ObuConstant.TYPE_CHANGE_LIGHT_FOR_VIP:
|
||||
// vip变灯提醒
|
||||
@@ -223,6 +228,23 @@ public class V2XObuManager implements IObuCallback, Handler.Callback {
|
||||
messageEntity.setContent(changeLightEvent);
|
||||
V2XObuEventScenario.getInstance().init(messageEntity);
|
||||
break;
|
||||
case ObuConstant.TYPE_RUSH_RED_LIGHT:
|
||||
// 闯红灯预警
|
||||
V2XObuEventEntity rushRedLightEvent = new V2XObuEventEntity();
|
||||
rushRedLightEvent.setType(ObuConstant.TYPE_RUSH_RED_LIGHT);
|
||||
rushRedLightEvent.setDesc(info.getDescribe());
|
||||
messageEntity.setContent(rushRedLightEvent);
|
||||
V2XObuEventScenario.getInstance().init(messageEntity);
|
||||
break;
|
||||
case ObuConstant.TYPE_CROSS_COLLISION_WARNING:
|
||||
// 交叉口碰撞预警
|
||||
V2XMessageEntity<V2XPushMessageEntity> v2XMessageEntity =
|
||||
TestOnLineCarUtils.getV2XScenarioCrossCrash();
|
||||
|
||||
Intent intent = new Intent(V2XConst.BROADCAST_SCENE_HANDLER_ACTION);
|
||||
intent.putExtra(V2XConst.BROADCAST_SCENE_EXTRA_KEY, v2XMessageEntity);
|
||||
LocalBroadcastManager.getInstance(getContext()).sendBroadcast(intent);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
@@ -234,7 +256,7 @@ public class V2XObuManager implements IObuCallback, Handler.Callback {
|
||||
if (ObuConfig.useObuLocation) {
|
||||
MogoLocation currentLocation = new MogoLocation();
|
||||
|
||||
CoordinateConverter converter = new CoordinateConverter(V2XServiceManager.getContext());
|
||||
CoordinateConverter converter = new CoordinateConverter(getContext());
|
||||
converter.from(CoordinateConverter.CoordType.GPS);
|
||||
LatLng latLng = new LatLng(locationInfo.getLat(), locationInfo.getLon());
|
||||
converter.coord(latLng);
|
||||
|
||||
@@ -88,6 +88,12 @@ public class V2XObuEventWindow extends FrameLayout implements IV2XWindow<V2XObuE
|
||||
tvType.setText("优先通行");
|
||||
tvType.setBackgroundResource(R.drawable.bg_v2x_event_type_green);
|
||||
break;
|
||||
case ObuConstant.TYPE_RUSH_RED_LIGHT:
|
||||
ivTypeIcon.setImageResource(R.drawable.v2x_icon_obu_rush_red_light);
|
||||
tvDesc.setText(entity.getDesc());
|
||||
tvType.setText("红灯警告");
|
||||
tvType.setBackgroundResource(R.drawable.bg_v2x_event_type_read);
|
||||
break;
|
||||
default:
|
||||
Logger.w(MODULE_NAME, "其他obu类型,暂不处理: " + entity.getType());
|
||||
break;
|
||||
|
||||
@@ -189,6 +189,39 @@ public class TestOnLineCarUtils {
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* 模拟H5推送场景--十字路口碰撞
|
||||
*/
|
||||
public static V2XMessageEntity<V2XPushMessageEntity> getV2XScenarioCrossCrash() {
|
||||
try {
|
||||
InputStream inputStream = V2XUtils.getApp()
|
||||
.getResources()
|
||||
.openRawResource(R.raw.scenario_push_cross_crash);
|
||||
ByteArrayOutputStream baos = new ByteArrayOutputStream();
|
||||
int len = -1;
|
||||
byte[] buffer = new byte[1024];
|
||||
while ((len = inputStream.read(buffer)) != -1) {
|
||||
baos.write(buffer, 0, len);
|
||||
}
|
||||
inputStream.close();
|
||||
|
||||
// 加载数据源
|
||||
V2XPushMessageEntity v2xRoadEventEntity = GsonUtil.objectFromJson(baos.toString(), V2XPushMessageEntity.class);
|
||||
|
||||
V2XMessageEntity<V2XPushMessageEntity> v2xMessageEntity = new V2XMessageEntity<>();
|
||||
// 控制类型
|
||||
v2xMessageEntity.setType(V2XMessageEntity.V2XTypeEnum.ALERT_ANIMATION_WARNING);
|
||||
// 设置数据
|
||||
v2xMessageEntity.setContent(v2xRoadEventEntity);
|
||||
// 控制展示状态
|
||||
v2xMessageEntity.setShowState(true);
|
||||
return v2xMessageEntity;
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* 模拟 疲劳驾驶
|
||||
*/
|
||||
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 12 KiB |
@@ -0,0 +1,21 @@
|
||||
{
|
||||
"sceneId": "100006",
|
||||
"alarmContent": "十字路口碰撞",
|
||||
"expireTime": 30000,
|
||||
"sceneCategory": 0,
|
||||
"sceneDescription": "",
|
||||
"sceneName": "",
|
||||
"sceneLevel": 0,
|
||||
"videoUrl": "",
|
||||
"videoChannel": "C_1",
|
||||
"videoSn": "ZD801B1932L00041",
|
||||
"tts": "周围有路人发起顺风车",
|
||||
"zoom": true,
|
||||
"zoomScale": 15,
|
||||
"location": {
|
||||
"lat": 39.9754100000,
|
||||
"lon": 116.4178276100
|
||||
},
|
||||
"userHead": "https://yycp-static-1255510688.cos.ap-beijing.myqcloud.com/defaultUserHeadImg/5.png",
|
||||
"msgImgUrl": "https://upload.jianshu.io/users/upload_avatars/7663825/7c28763e-002b-4e89-8dea-5b8da210ef2c.jpg"
|
||||
}
|
||||
Reference in New Issue
Block a user