diff --git a/.idea/misc.xml b/.idea/misc.xml index c74f9c1030..c453c35421 100644 --- a/.idea/misc.xml +++ b/.idea/misc.xml @@ -13,6 +13,7 @@ + diff --git a/README.md b/README.md index 438d86a6a0..956623bd8c 100644 --- a/README.md +++ b/README.md @@ -19,7 +19,7 @@ adb shell am broadcast -a com.hmi.v2x.notification --ez v2xIsShow false --es ta adb shell am broadcast -a com.hmi.v2x.trafficlight --ez trafficLightIsShow true --ei trafficLightCheckType 1 adb shell am broadcast -a com.hmi.v2x.trafficlight --ez trafficLightIsShow false -// 控制红绿灯 +// 控制限速 adb shell am broadcast -a com.hmi.v2x.limitingvelocity --ez limitingVelocityIsShow true --ei limitingVelocitySpeed 60 adb shell am broadcast -a com.hmi.v2x.limitingvelocity --ez limitingVelocityIsShow false diff --git a/modules/mogo-module-common/build.gradle b/modules/mogo-module-common/build.gradle index 1ca6db6bb2..b5dc35c5e6 100644 --- a/modules/mogo-module-common/build.gradle +++ b/modules/mogo-module-common/build.gradle @@ -1,6 +1,10 @@ -apply plugin: 'com.android.library' -apply plugin: 'kotlin-android' -apply plugin: 'kotlin-android-extensions' +plugins { + id 'com.android.library' + id 'kotlin-android' + id 'kotlin-android-extensions' + id 'kotlin-kapt' + id 'com.alibaba.arouter' +} android { compileSdkVersion rootProject.ext.android.compileSdkVersion diff --git a/modules/mogo-module-common/src/main/java/com/mogo/module/common/drawer/TrafficMarkerDrawer.kt b/modules/mogo-module-common/src/main/java/com/mogo/module/common/drawer/TrafficMarkerDrawer.kt new file mode 100644 index 0000000000..50bc4cdcb4 --- /dev/null +++ b/modules/mogo-module-common/src/main/java/com/mogo/module/common/drawer/TrafficMarkerDrawer.kt @@ -0,0 +1,201 @@ +package com.mogo.module.common.drawer + +import android.annotation.SuppressLint +import android.content.Context +import android.os.Handler +import android.os.Message +import com.mogo.commons.AbsMogoApplication +import com.mogo.map.MogoLatLng +import com.mogo.map.marker.IMogoMarker +import com.mogo.map.marker.MogoMarkerOptions +import com.mogo.module.common.MogoApisHandler +import com.mogo.module.common.constants.DataTypes +import com.mogo.module.common.drawer.bean.TrafficData +import com.mogo.utils.WorkThreadHandler +import java.util.concurrent.ConcurrentHashMap + +/** + * @author xiaoyuzhou + * @date 2021/8/18 11:12 上午 + * 交通元素 2D\3D绘制 + */ +@SuppressLint("StaticFieldLeak") +object TrafficMarkerDrawer { + + private val TAG = "TrafficMarkerDrawer" + + private var mContext: Context? = null + + // 动画持续时间 + private val stepTime = 100L + + // 维护Obu识别的他车集合 + private val mTrafficMap = ConcurrentHashMap() + + // 地图内部资源md5缓存,便于资源复用 + private val mMarkerCachesResMd5Values = ConcurrentHashMap() + + // 上一帧数据的缓存,用来做移动动画 + private val mMarkersCaches = ConcurrentHashMap() + + // 维护一个线程定时轮询数据进行地图绘制 + private val mDrawerHandler: Handler = + object : Handler(WorkThreadHandler.newInstance("other_traffic_drawer").looper) { + override fun handleMessage(msg: Message) { + super.handleMessage(msg) + drawerTrafficInfo() + // 延时50毫秒重复发送自己,定时轮询进行车辆绘制,可以及时将已经不存在车辆删除 + sendEmptyMessageDelayed(0, 100L) + } + } + + init { + mContext = AbsMogoApplication.getApp() + mDrawerHandler.sendEmptyMessageDelayed(1, 0L) + } + + /** + * 添加识别的数据 + */ + fun addTrafficInfo(trafficData: TrafficData) { + mTrafficMap[trafficData.uuid] = trafficData + } + + /** + * 更新识别数据,V2V预警的时候需要修改车辆颜色 + */ + fun updateITrafficInfo(trafficData: TrafficData) { + mTrafficMap[trafficData.uuid] = trafficData + } + + /** + * 移除识别的数据 + */ + fun removeCvxRvInfoIndInfo(key: String) { + if (mTrafficMap.containsKey(key)) { + mTrafficMap.remove(key) + } + } + + /** + * 绘制 + */ + private fun drawerTrafficInfo() { + // 数据为空的时候清除所有数据 + if (mTrafficMap.isEmpty()) { + mMarkersCaches.forEach { + it.value.remove() + } + mMarkersCaches.clear() + } else { + // 循环绘制识别的数据 + mTrafficMap.forEach { + //Logger.d(TAG, "drawerCvxRvInfo:${it.value}") + + // 如果数据已经存在 Marker,取出做动画 + if (mMarkersCaches[it.key] != null) { + mMarkersCaches[it.key]?.let { it1 -> + changeDynamicMarker(it1, it.value) + } + } + // 不存在的添加Marker绘制 + else { + drawObuRecognizedDataMarker(it.value) + } + } + } + } + + + /** + * 绘制单条 + */ + private fun drawObuRecognizedDataMarker(trafficData: TrafficData) { + if (trafficData.type != null) { + val resId: Int = trafficData.type.traffic3DIconId + + val resIdVal = resId.toString() + "" + + val options = MogoMarkerOptions() + .owner(DataTypes.TYPE_MARKER_ADAS) + .anchor(0.5f, 0.5f) + .set3DMode(true) + .gps(true) + .controlAngle(true) + .resName(mMarkerCachesResMd5Values[resIdVal]) + .icon3DRes(resId) + .rotate(trafficData.heading.toFloat()) + .position( + MogoLatLng( + trafficData.lat, + trafficData.lon + ) + ) + + // 修改颜色 + when (trafficData.threatLevel) { + 1 -> { + mMarkersCaches[trafficData.uuid]?.setAnchorColor("#D8D8D8FF") + } + 2 -> { + mMarkersCaches[trafficData.uuid]?.setAnchorColor("#FFD53EFF") + } + 3 -> { + mMarkersCaches[trafficData.uuid]?.setAnchorColor("#FF3C45FF") + } + else -> { + mMarkersCaches[trafficData.uuid]?.setAnchorColor("#D8D8D8FF") + } + } + + val marker = MogoApisHandler.getInstance().apis + .mapServiceApi + .getMarkerManager(mContext) + .addMarker(DataTypes.TYPE_MARKER_OBU_DATA, options) + + // 缓存3D资源 + mMarkerCachesResMd5Values[resIdVal] = marker.markerResName + // 缓存数据 + mMarkersCaches[trafficData.uuid] = marker + } + } + + /** + * 带动画的修改Marker + */ + private fun changeDynamicMarker( + marker: IMogoMarker, + trafficData: TrafficData + ) { + val resId: Int = trafficData.type.traffic3DIconId + val resIdVal = resId.toString() + "" + val options = marker.mogoMarkerOptions + options.resName(mMarkerCachesResMd5Values[resIdVal]) + .icon3DRes(resId) + + // 修改颜色 + when (trafficData.threatLevel) { + 1 -> { + mMarkersCaches[trafficData.uuid]?.setAnchorColor("#D8D8D8FF") + } + 2 -> { + mMarkersCaches[trafficData.uuid]?.setAnchorColor("#FFD53EFF") + } + 3 -> { + mMarkersCaches[trafficData.uuid]?.setAnchorColor("#FF3C45FF") + } + else -> { + mMarkersCaches[trafficData.uuid]?.setAnchorColor("#D8D8D8FF") + } + } + + marker.addDynamicAnchorPosition( + MogoLatLng( + trafficData.lat, + trafficData.lon + ), + trafficData.heading.toFloat(), + stepTime + ) + } +} \ No newline at end of file diff --git a/modules/mogo-module-common/src/main/java/com/mogo/module/common/drawer/bean/TrafficData.java b/modules/mogo-module-common/src/main/java/com/mogo/module/common/drawer/bean/TrafficData.java new file mode 100644 index 0000000000..a7707482d3 --- /dev/null +++ b/modules/mogo-module-common/src/main/java/com/mogo/module/common/drawer/bean/TrafficData.java @@ -0,0 +1,77 @@ +package com.mogo.module.common.drawer.bean; + +import com.mogo.module.common.enums.TrafficTypeEnum; + +/** + * @author xiaoyuzhou + * @date 2021/8/17 8:41 下午 + * 交通元素数据, + */ +public class TrafficData { + + /** + * 交通元素类型, 车、人、摩托、大巴车、卡车、自行车 + */ + public TrafficTypeEnum type; + + /** + * 识别物体唯一标识 + */ + public String uuid; + + /** + * 识别物体的纬度 + */ + public double lat; + + /** + * 识别物体的经度 + */ + public double lon; + + /** + * 车头朝向 + */ + public double heading; + + /** + * 系统时间 + */ + public long systemTime; + + /** + * 定位卫星时间 + */ + public long satelliteTime; + + /** + * 海拔 + */ + public double alt; + + /** + * 速度 + */ + public double speed; + + /** + * 莫顿码 + */ + public long mortonCode; + + /** + * 实际距离 + * 使用distanceX和distanceY计算 + */ + public double distance; + + /** + * 危险等级 + * range(0..3) + * 0x00: 保留 + * 0x01: 模型原始颜色 + * 0x02: 通知 -- 黄 + * 0x03: 警告 -- 红 + */ + public int threatLevel; +} diff --git a/modules/mogo-module-common/src/main/java/com/mogo/module/common/enums/TrafficTypeEnum.kt b/modules/mogo-module-common/src/main/java/com/mogo/module/common/enums/TrafficTypeEnum.kt new file mode 100644 index 0000000000..ea16d88c29 --- /dev/null +++ b/modules/mogo-module-common/src/main/java/com/mogo/module/common/enums/TrafficTypeEnum.kt @@ -0,0 +1,61 @@ +package com.mogo.module.common.enums + +import com.mogo.module.common.R + +/** + * @author xiaoyuzhou + * @date 2021/8/18 11:39 上午 + * 交通元素类型 + */ +enum class TrafficTypeEnum( + var type: Int, + var desc: String, + var traffic2DIconId: Int, + var traffic3DIconId: Int +) { + + TYPE_TRAFFIC_ID_WEI_ZHI( + 0, + "未知数据", + R.raw.tache, + R.raw.tache + ), + TYPE_TRAFFIC_ID_PEOPLE( + 1, + "人", + R.raw.people, + R.raw.people + ), + TYPE_TRAFFIC_ID_BICYCLE( + 2, + "自行车", + R.raw.zixingche, + R.raw.zixingche + ), + TYPE_TRAFFIC_ID_TA_CHE( + 3, + "他车", + R.raw.tachexiaoche, + R.raw.tachexiaoche + ), + TYPE_TRAFFIC_ID_MOTO( + 4, + "摩托", + R.raw.motorbike, + R.raw.motorbike + ), + TYPE_TRAFFIC_ID_BUS( + 6, + "大巴", + R.raw.bus, + R.raw.bus + ), + TYPE_TRAFFIC_ID_TRUCK( + 8, + "卡车", + R.raw.daba, + R.raw.daba + ) + + +} \ No newline at end of file diff --git a/modules/mogo-module-common/src/main/java/com/mogo/module/common/enum/WarningTypeEnum.kt b/modules/mogo-module-common/src/main/java/com/mogo/module/common/enums/WarningTypeEnum.kt similarity index 99% rename from modules/mogo-module-common/src/main/java/com/mogo/module/common/enum/WarningTypeEnum.kt rename to modules/mogo-module-common/src/main/java/com/mogo/module/common/enums/WarningTypeEnum.kt index 3dc8066914..292d8a55c4 100644 --- a/modules/mogo-module-common/src/main/java/com/mogo/module/common/enum/WarningTypeEnum.kt +++ b/modules/mogo-module-common/src/main/java/com/mogo/module/common/enums/WarningTypeEnum.kt @@ -1,4 +1,4 @@ -package com.mogo.module.common.enum +package com.mogo.module.common.enums import com.mogo.module.common.R import com.zhidao.support.obu.constants.ObuConstants diff --git a/modules/mogo-module-hmi/src/main/java/com/mogo/module/hmi/receiver/V2XWarningBroadcastReceiver.kt b/modules/mogo-module-hmi/src/main/java/com/mogo/module/hmi/receiver/V2XWarningBroadcastReceiver.kt index 4ee2f44b1f..827332db4e 100644 --- a/modules/mogo-module-hmi/src/main/java/com/mogo/module/hmi/receiver/V2XWarningBroadcastReceiver.kt +++ b/modules/mogo-module-hmi/src/main/java/com/mogo/module/hmi/receiver/V2XWarningBroadcastReceiver.kt @@ -4,7 +4,7 @@ import android.content.BroadcastReceiver import android.content.Context import android.content.Intent import com.alibaba.android.arouter.launcher.ARouter -import com.mogo.module.common.enum.WarningTypeEnum +import com.mogo.module.common.enums.WarningTypeEnum import com.mogo.module.hmi.WaringConst import com.mogo.service.IMogoServiceApis import com.mogo.service.MogoServicePaths diff --git a/modules/mogo-module-hmi/src/main/java/com/mogo/module/hmi/ui/MoGoWarningFragment.kt b/modules/mogo-module-hmi/src/main/java/com/mogo/module/hmi/ui/MoGoWarningFragment.kt index e9dc572f86..96f84c0c73 100644 --- a/modules/mogo-module-hmi/src/main/java/com/mogo/module/hmi/ui/MoGoWarningFragment.kt +++ b/modules/mogo-module-hmi/src/main/java/com/mogo/module/hmi/ui/MoGoWarningFragment.kt @@ -8,7 +8,7 @@ import android.view.WindowManager import android.view.animation.OvershootInterpolator import com.mogo.commons.mvp.MvpFragment import com.mogo.commons.voice.AIAssist -import com.mogo.module.common.enum.WarningTypeEnum +import com.mogo.module.common.enums.WarningTypeEnum import com.mogo.module.hmi.R import com.mogo.module.hmi.notification.WarningFloat import com.mogo.module.hmi.notification.anim.DefaultAnimator diff --git a/modules/mogo-module-obu-mogo/src/main/java/com/mogo/module/obu/mogo/MogoPrivateObuManager.kt b/modules/mogo-module-obu-mogo/src/main/java/com/mogo/module/obu/mogo/MogoPrivateObuManager.kt index ea8fa589f0..53b1c55f23 100644 --- a/modules/mogo-module-obu-mogo/src/main/java/com/mogo/module/obu/mogo/MogoPrivateObuManager.kt +++ b/modules/mogo-module-obu-mogo/src/main/java/com/mogo/module/obu/mogo/MogoPrivateObuManager.kt @@ -2,9 +2,9 @@ package com.mogo.module.obu.mogo import android.content.Context import com.alibaba.android.arouter.launcher.ARouter -import com.mogo.module.common.enum.WarningTypeEnum -import com.mogo.module.obu.mogo.map.ObuRecognizedResultDrawer -import com.mogo.module.obu.mogo.map.ObuVulnerableGroupsDrawer +import com.mogo.module.common.drawer.TrafficMarkerDrawer +import com.mogo.module.common.enums.WarningTypeEnum +import com.mogo.module.obu.mogo.utils.TrafficDataConvertUtils import com.mogo.service.IMogoServiceApis import com.mogo.service.MogoServicePaths import com.mogo.service.warning.IMoGoWaringProvider @@ -34,11 +34,6 @@ class MogoPrivateObuManager private constructor() { val icw_data = "02000114010000000000001effd7892b11a4440af70100142a03000907e506100e2917019000005662010a45000b0000220847162c000037970010000a17f6215c459478b6010347ac045000090a0006012c01f4009600080073007300730073000b000000000000000000000000000000002b000037780000247300003261000000000000426c827f47001200100000000000000000000021220000349a006c0010000a17f63ecb45947ba301030000332c0010000a17f642e945947bea010300004d580010000a17f6435545947e4e0103000054c40010000a17f6413a45947f96010300005c300010000a17f62c2845947d140103000070e40010000a17f5fdb14594786001030000992000060004ffec2710" - // Obu 识别他车绘制 - private var mObuRecognizedResultDrawer: ObuRecognizedResultDrawer? = null - - // Obu 弱势群体预警绘制 - private var mObuVulnerableGroupsDrawer: ObuVulnerableGroupsDrawer? = null private var mContext: Context? = null fun init(context: Context?) { @@ -50,9 +45,6 @@ class MogoPrivateObuManager private constructor() { // 获取预警模块的接口 mIMoGoWaringProvider = mMogoServiceApis!!.waringProviderApi - mObuRecognizedResultDrawer = ObuRecognizedResultDrawer() - mObuVulnerableGroupsDrawer = ObuVulnerableGroupsDrawer() - //自研obu MogoObuManager.getInstance().connect(context, "192.168.1.199") MogoObuManager.getInstance().registerListener(mogoObuListener) @@ -118,8 +110,10 @@ class MogoPrivateObuManager private constructor() { override fun onCvxRvInfoIndInfo(info: CvxRvInfoIndInfo) { Logger.d(MogoObuConst.TAG_MOGO_OBU, "onCvxRvInfoIndInfo ------> $info") mContext?.let { SharedPrefsMgr.getInstance(it).putBoolean("OBU_RV", true) } - // 更新周边车辆 - mObuRecognizedResultDrawer?.addCvxRvInfoIndInfo(info) + // 更新数据 + TrafficDataConvertUtils.cvxRvInfoIndInfo2TrafficData(info)?.let { + TrafficMarkerDrawer.updateITrafficInfo(it) + } } // 道路事件预警信息:CVX_RTI_THREAT_IND 车与其他,obu与rsu @@ -203,15 +197,21 @@ class MogoPrivateObuManager private constructor() { when (info.status) { // 添加 ObuConstants.STATUS.ADD -> { - mObuVulnerableGroupsDrawer?.addCvxRvInfoIndInfo(info) + // 更新数据 + TrafficDataConvertUtils.cvxPtcInfoIndInfo2TrafficData(info)?.let { + TrafficMarkerDrawer.updateITrafficInfo(it) + } } // 删除 ObuConstants.STATUS.DELETE -> { - mObuVulnerableGroupsDrawer?.removeCvxPtcInfoIndInfo(info.id) + TrafficMarkerDrawer.removeCvxRvInfoIndInfo(info.id) } // 更新 else -> { - mObuVulnerableGroupsDrawer?.updateCvxPtcInfoIndInfo(info) + // 更新数据 + TrafficDataConvertUtils.cvxPtcInfoIndInfo2TrafficData(info)?.let { + TrafficMarkerDrawer.updateITrafficInfo(it) + } } } } @@ -339,7 +339,7 @@ class MogoPrivateObuManager private constructor() { * * @param appId 使用WarningTypeEnum获取icon、提示内容、tts内容 * - * @see com.mogo.module.common.enum.WarningTypeEnum + * @see com.mogo.module.common.enums.WarningTypeEnum */ private fun handleSdkObu( appId: Int, @@ -466,19 +466,23 @@ class MogoPrivateObuManager private constructor() { appId.toString() ) //更新周边车辆进行预警颜色变换,车辆实时移动和变色 - mObuRecognizedResultDrawer?.updateCvxRvInfoIndInfo(level, info) + TrafficDataConvertUtils.cvxV2vThreatIndInfo2TrafficData(info)?.let { + TrafficMarkerDrawer.updateITrafficInfo(it) + } } // 删除 ObuConstants.STATUS.DELETE -> { // 移除顶部弹窗 mIMoGoWaringProvider?.disableWarningV2X(appId.toString()) // 移除地图元素 - mObuRecognizedResultDrawer?.removeCvxRvInfoIndInfo(info.vehicle_id) + TrafficMarkerDrawer.removeCvxRvInfoIndInfo(info.vehicle_id) } // 更新 else -> { //更新周边车辆进行预警颜色变换,车辆实时移动和变色 - mObuRecognizedResultDrawer?.updateCvxRvInfoIndInfo(level, info) + TrafficDataConvertUtils.cvxV2vThreatIndInfo2TrafficData(info)?.let { + TrafficMarkerDrawer.updateITrafficInfo(it) + } } } } diff --git a/modules/mogo-module-obu-mogo/src/main/java/com/mogo/module/obu/mogo/utils/TrafficDataConvertUtils.kt b/modules/mogo-module-obu-mogo/src/main/java/com/mogo/module/obu/mogo/utils/TrafficDataConvertUtils.kt new file mode 100644 index 0000000000..d3123e2b0c --- /dev/null +++ b/modules/mogo-module-obu-mogo/src/main/java/com/mogo/module/obu/mogo/utils/TrafficDataConvertUtils.kt @@ -0,0 +1,97 @@ +package com.mogo.module.obu.mogo.utils + +import com.mogo.module.common.drawer.bean.TrafficData +import com.mogo.module.common.enums.TrafficTypeEnum +import com.zhidao.support.obu.model.CvxPtcInfoIndInfo +import com.zhidao.support.obu.model.CvxRvInfoIndInfo +import com.zhidao.support.obu.model.CvxV2vThreatIndInfo + +/** + * @author xiaoyuzhou + * @date 2021/8/18 2:30 下午 + */ +object TrafficDataConvertUtils { + + /** + * OBU 远车 转换交通元素数据 + */ + fun cvxRvInfoIndInfo2TrafficData(info: CvxRvInfoIndInfo): TrafficData? { + if (info.basic_info == null || info.basic_info.position == null || info.threat_infos != null) { + return null + } + val trafficData = TrafficData() + trafficData.type = TrafficTypeEnum.TYPE_TRAFFIC_ID_TA_CHE + trafficData.uuid = info.vehicle_id + trafficData.lat = info.basic_info.position.latitude + trafficData.lon = info.basic_info.position.longitude + trafficData.heading = info.basic_info.heading + trafficData.speed = info.basic_info.speed + + // 判断车辆V2X预警级别,调整车辆颜色 + if (!info.threat_infos.isNullOrEmpty()) { + trafficData.threatLevel = info.threat_infos.first().threat_level + } + + return trafficData + } + + /** + * OBU 预警事件 转换交通元素数据 + */ + fun cvxV2vThreatIndInfo2TrafficData(info: CvxV2vThreatIndInfo): TrafficData? { + if (info.basic_info == null || info.basic_info.position == null || info.threat_info == null) { + return null + } + val trafficData = TrafficData() + trafficData.type = TrafficTypeEnum.TYPE_TRAFFIC_ID_TA_CHE + trafficData.uuid = info.vehicle_id + trafficData.lat = info.basic_info.position.latitude + trafficData.lon = info.basic_info.position.longitude + trafficData.heading = info.basic_info.heading + trafficData.speed = info.basic_info.speed + // 判断车辆V2X预警级别,调整车辆颜色 + trafficData.threatLevel = info.threat_info.threat_level + + return trafficData + } + + /** + * OBU 弱势交通参与者信息 转换交通元素数据 + */ + fun cvxPtcInfoIndInfo2TrafficData(info: CvxPtcInfoIndInfo): TrafficData? { + if (info.basic_info == null || info.basic_info.position == null || info.threat_infos != null) { + return null + } + val trafficData = TrafficData() + + trafficData.uuid = info.id + trafficData.lat = info.basic_info.position.latitude + trafficData.lon = info.basic_info.position.longitude + trafficData.heading = info.basic_info.heading + trafficData.speed = info.basic_info.speed + + when (info.ptc_type) { + // 未知 + 0x0 -> { + trafficData.type = TrafficTypeEnum.TYPE_TRAFFIC_ID_WEI_ZHI + } + // 非机动车 + 0x1 -> { + trafficData.type = TrafficTypeEnum.TYPE_TRAFFIC_ID_BICYCLE + } + // 行人 + 0x2 -> { + trafficData.type = TrafficTypeEnum.TYPE_TRAFFIC_ID_PEOPLE + } + } + + // 判断车辆V2X预警级别,调整车辆颜色 + if (!info.threat_infos.isNullOrEmpty()) { + trafficData.threatLevel = info.threat_infos.first().threat_level + } + + return trafficData + } + + +} \ No newline at end of file