优化苏州四大场景,完成联调测试验收

This commit is contained in:
tongchenfei
2020-09-26 11:29:52 +08:00
parent a222903dc2
commit d5abc0b598
5 changed files with 169 additions and 62 deletions

View File

@@ -1,6 +1,9 @@
package com.zhidao.mogo.module.obu.obu
import android.os.Handler
import android.os.SystemClock
import android.util.ArrayMap
import com.google.gson.JsonObject
import com.mogo.commons.debug.DebugConfig
import com.mogo.utils.logger.Logger
import com.zhidao.mogo.module.obu.ObuConstant
@@ -8,6 +11,7 @@ import com.zhidao.mogo.module.obu.obu.bean.MogoObuEventInfo
import com.zhidao.mogo.module.obu.socket.IUdpSocketCallback
import com.zhidao.mogo.module.obu.socket.SimpleSocketManager
import com.zhidao.mogo.module.obu.socket.UdpSocketManager
import org.json.JSONException
import org.json.JSONObject
import java.lang.StringBuilder
import kotlin.concurrent.thread
@@ -20,14 +24,40 @@ import kotlin.experimental.xor
* @author tongchenfei
*/
class HualiObu : BaseObu(), IUdpSocketCallback {
// private val socketManager = UdpSocketManager(this)
// private val socketManager = UdpSocketManager(this)
private val socketManager = SimpleSocketManager(this)
private val eventCacheMap = ArrayMap<String, Long>()
companion object {
const val TAG = "HualiObu"
const val IP_ADDRESS = "192.168.8.10"
// const val IP_ADDRESS = "192.168.43.206"
const val IP_ADDRESS = "192.168.8.99"
// const val IP_ADDRESS = "172.31.3.18"
const val PORT = 10005
/**
* 红绿灯信息 key
* 绿波车速和闯红灯都是根据这个key来解析json同时这个key也用于[eventCacheMap],用来表示闯红灯预警和绿波车速
*/
const val KEY_RUSH_RED_LIGHT = "rush_redlight"
/**
* 交叉路口碰撞信息 key
*/
const val KEY_INTERSECTION_CRASH = "intersection_crash"
/**
* 行人碰撞预警 key
*/
const val KEY_PEDESTRAIN_INFORMATION = "pedestrain_information"
/**
* 事件上报事件间隔阈值
*/
const val EVENT_WARN_TIME_THRESHOLD = 25_000
}
private val handler = Handler()
@@ -40,10 +70,15 @@ class HualiObu : BaseObu(), IUdpSocketCallback {
override fun onMessageReceived(msg: ByteArray) {
// 处理数据
val m = String(msg)
Logger.d(TAG, "onMessageReceived: $m")
printByteArray(msg)
parseObuProtocol(msg)
// val m = String(msg)
// Logger.d(TAG, "onMessageReceived: $m")
// printByteArray(msg)
try {
parseObuProtocol(msg)
} catch (e: JSONException) {
e.printStackTrace()
Logger.e(TAG,e,"obu数据解析json异常")
}
}
/**
@@ -51,7 +86,7 @@ class HualiObu : BaseObu(), IUdpSocketCallback {
*
* @param ori 原始数据
*/
private fun parseObuProtocol(ori: ByteArray) {
private fun parseObuProtocol(ori: ByteArray) {
val effectiveData = if (DebugConfig.isUseMockObuData()) {
ori
} else {
@@ -59,81 +94,124 @@ class HualiObu : BaseObu(), IUdpSocketCallback {
}
if (effectiveData != null) {
val msg = String(effectiveData)
Logger.d(TAG, "收到obu数据: \n $msg")
Logger.d(TAG, "收到obu数据====${effectiveData.size}")
val json = JSONObject(msg)
val rushRedLight = json.optJSONObject("rush_redlight")
val rushRedLight = json.optJSONObject(KEY_RUSH_RED_LIGHT)
rushRedLight?.let {
// 有闯红灯告警信息,绿波车速信息
Logger.d(TAG, "收到闯红灯告警信息: \n $it")
val currentLineDir = it.optInt("current_lane_man")
Logger.d(TAG, "当前车道方向: $currentLineDir")
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?.let {
handler.post {
it.onEventInfoCallback(eventInfo)
var lastInfo: JSONObject? = null
for (i in 0 until info.length()) {
val j = info.optJSONObject(i)
val lineDir = j.optInt("led_direction")
val enable = j.optInt("lane_en", 0)
if (lineDir == currentLineDir && enable == 1) {
// 使能,且车道方向一致
lastInfo = j
}
}
lastInfo?.let { lightInfo ->
if (isWarnEnable(KEY_RUSH_RED_LIGHT)) {
val alert = lightInfo.optInt("rush_redlight_alarm", -1)
val eventInfo = MogoObuEventInfo()
when (alert) {
0 -> {
// 有闯红灯风险
Logger.d(TAG, "准备预警--闯红灯")
eventInfo.mogoEventId = ObuConstant.TYPE_RUSH_RED_LIGHT
eventInfo.describe = "当前车速经过路口会闯红灯,请减速!"
callback?.let {
handler.post {
it.onEventInfoCallback(eventInfo)
}
}
}
1 -> {
// 没有风险,给出建议车速,绿波车速
Logger.d(TAG, "准备预警--绿波车速")
eventInfo.mogoEventId = ObuConstant.TYPE_OPTIMAL_SPEED_ADVISORY
val optSpeedInterval = lastInfo.optJSONArray("advisory_speed")
val optSpeed = lastInfo.optInt("advisory_speed")
if (optSpeedInterval == null) {
// 不是速度区间,是具体速度值
Logger.d(TAG, "建议速度值: $optSpeed")
eventInfo.describe = "前方路口,建议车速 $optSpeed km/h"
} else {
Logger.d(TAG, "建议速度区间: ${optSpeedInterval[0]} ~ ${optSpeedInterval[1]}")
val start = optSpeedInterval[0].toString().toInt()
val end = optSpeedInterval[1].toString().toInt()
val notice = if (start == end) {
"前方路口,建议车速 $start km/h"
} else {
"前方路口,建议车速 $start$end km/h"
}
eventInfo.describe = notice
}
callback?.let {
handler.post {
it.onEventInfoCallback(eventInfo)
}
}
}
else -> {
Logger.e(TAG, "没有有效红绿灯预警信息")
}
}
}
1 -> {
// 没有风险,给出建议车速,绿波车速
Logger.d(TAG, "准备预警--绿波车速")
eventInfo.mogoEventId = ObuConstant.TYPE_OPTIMAL_SPEED_ADVISORY
val optSpeed = lastInfo.optInt("advisory_speed")
eventInfo.describe = "前方路口,建议车速 $optSpeed km/h"
callback?.let {
handler.post {
it.onEventInfoCallback(eventInfo)
}
}
}
else -> {
Logger.e(TAG, "没有有效红绿灯预警信息")
} else {
Logger.d(TAG, "已经报过闯红灯预警了,待会再报")
}
}
}
}
val intersectionCrash = json.optJSONObject("intersection_crash")
val intersectionCrash = json.optJSONObject(KEY_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?.let {
handler.post {
it.onEventInfoCallback(eventInfo)
if (isWarnEnable(KEY_INTERSECTION_CRASH)) {
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?.let {
handler.post {
it.onEventInfoCallback(eventInfo)
}
}
}
} else {
Logger.d(TAG, "已经提醒过交叉口碰撞了,等会儿再提醒")
}
}
val pedestrainInformation = json.optJSONObject("pedestrain_information")
val pedestrainInformation = json.optJSONObject(KEY_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
callback?.let {
handler.post {
it.onEventInfoCallback(eventInfo)
if (isWarnEnable(KEY_PEDESTRAIN_INFORMATION)) {
val alert = it.optInt("pedestrian_stauts", 0)
if (alert == 1) {
// 有人车冲突
Logger.d(TAG, "准备预警--行人碰撞")
val eventInfo = MogoObuEventInfo()
eventInfo.mogoEventId = ObuConstant.TYPE_ROAD_USER_COLLISION_WARNING
callback?.let {
handler.post {
it.onEventInfoCallback(eventInfo)
}
}
}
} else {
Logger.d(TAG, "已经上报过人车冲突,过会儿再上报")
}
}
@@ -155,6 +233,23 @@ class HualiObu : BaseObu(), IUdpSocketCallback {
}
}
/**
* 是否可以进行事件提醒
* 目前是根据时间间隔阈值进行判断,[EVENT_WARN_TIME_THRESHOLD]内,同一事件只播报一次
*
* @return true 可上报 false 忽略此事件
*/
private fun isWarnEnable(key: String): Boolean {
val time = eventCacheMap[key] ?: 0
val current = SystemClock.elapsedRealtime()
return if (time == 0L || current - time > EVENT_WARN_TIME_THRESHOLD) {
eventCacheMap[key] = current
true
} else {
false
}
}
/**
* 从原始数据中,根据数据长度字节,取出有效数据
*
@@ -164,9 +259,13 @@ class HualiObu : BaseObu(), IUdpSocketCallback {
private fun getEffectiveData(oriMsg: ByteArray): ByteArray? {
val dataLengthInfo = ByteArray(4)
System.arraycopy(oriMsg, 16, dataLengthInfo, 0, 4)
printByteArray(dataLengthInfo)
// printByteArray(dataLengthInfo)
val dataLength = convertTwoUnSignInt(dataLengthInfo)
Logger.d(TAG, "解析后的长度: $dataLength")
if (dataLength > oriMsg.size) {
Logger.e(TAG, "数据长度超限制")
return null
}
val parseData = ByteArray(dataLength + 21)
System.arraycopy(oriMsg, 0, parseData, 0, parseData.size)
return if (isAvailable(parseData)) {

View File

@@ -42,8 +42,10 @@ class SimpleSocketManager(private val callback: IUdpSocketCallback? = null) {
socket = Socket(address, port)
socket?.let {
Logger.d(TAG, "socket连接基本成功准备接受数据")
// 超时时间60秒
// it.soTimeout = 60_000
// 超时时间10秒
// it.soTimeout = 10_000
// Logger.d(TAG,"设置了超时时间")
val buffer = ByteArray(2048)
var result: Int
do {

View File

@@ -10,6 +10,7 @@ import android.util.ArrayMap;
import com.amap.api.maps.CoordinateConverter;
import com.amap.api.maps.model.LatLng;
import com.mogo.commons.debug.DebugConfig;
import com.mogo.commons.voice.AIAssist;
import com.mogo.map.location.MogoLocation;
import com.mogo.module.common.entity.V2XMessageEntity;
import com.mogo.module.common.entity.V2XObuEventEntity;
@@ -241,7 +242,6 @@ public class V2XObuManager implements IObuCallback, Handler.Callback {
// 交叉口碰撞预警
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);

View File

@@ -8,6 +8,7 @@ import android.view.View;
import androidx.constraintlayout.widget.ConstraintLayout;
import com.mogo.commons.voice.AIAssist;
import com.mogo.module.common.entity.V2XPushMessageEntity;
import com.mogo.module.v2x.R;
import com.mogo.module.v2x.V2XServiceManager;
@@ -59,6 +60,7 @@ public class V2XAnimationWindow extends ConstraintLayout implements IV2XWindow<V
@Override
public void show(V2XPushMessageEntity entity) {
Uri videoUri = null;
String tts = null;
switch (entity.getSceneId()) {
// 前车紧急制动告警
case "100005":
@@ -67,6 +69,7 @@ public class V2XAnimationWindow extends ConstraintLayout implements IV2XWindow<V
// 十字路口碰撞预警
case "100006":
videoUri = Uri.parse("android.resource://" + getContext().getPackageName() + "/raw/" + R.raw.video_left_right_car);
tts = "注意路口车辆";
break;
// 岔路口碰撞预警
case "100007":
@@ -102,6 +105,9 @@ public class V2XAnimationWindow extends ConstraintLayout implements IV2XWindow<V
vvCarAnimation.start();
Logger.w(MODULE_NAME, "开始播放动画。。。。。");
}
if (tts != null) {
AIAssist.getInstance(V2XServiceManager.getContext()).speakTTSVoice(tts);
}
}
@Override

View File

@@ -1,5 +1,5 @@
{
"sceneId": "100005",
"sceneId": "100006",
"alarmContent": "顺风车提醒",
"expireTime": 30000,
"sceneCategory": 0,