[6.5.0][道路事件] 绿波通行业务逻辑
This commit is contained in:
@@ -3,8 +3,10 @@ package com.mogo.eagle.function.biz.v2x.v2n.pnc
|
||||
import android.os.Handler
|
||||
import android.os.HandlerThread
|
||||
import android.os.Message
|
||||
import android.text.TextUtils
|
||||
import android.util.Log
|
||||
import androidx.core.util.Pair
|
||||
import com.mogo.commons.voice.AIAssist
|
||||
import com.mogo.eagle.core.data.config.FunctionBuildConfig
|
||||
import com.mogo.eagle.core.data.enums.CommunicationType
|
||||
import com.mogo.eagle.core.data.enums.DataSourceType
|
||||
@@ -33,6 +35,7 @@ import com.mogo.eagle.core.function.call.map.CallerVisualAngleManager
|
||||
import com.mogo.eagle.core.function.call.msgbox.CallerMsgBoxManager.saveMsgBox
|
||||
import com.mogo.eagle.core.utilcode.mogo.AppIdentityModeUtils
|
||||
import com.mogo.eagle.core.utilcode.mogo.logger.CallerLogger
|
||||
import com.mogo.eagle.core.utilcode.util.AppStateManager
|
||||
import com.mogo.eagle.core.utilcode.util.CoordinateTransform
|
||||
import com.mogo.eagle.core.utilcode.util.CoordinateUtils
|
||||
import com.mogo.eagle.core.utilcode.util.DrivingDirectionUtils
|
||||
@@ -41,14 +44,17 @@ import com.mogo.eagle.function.biz.v2x.v2n.scenario.scene.airoad.AiRoadMarker
|
||||
import com.mogo.eagle.function.biz.v2x.v2n.scenario.scene.airoad.AiRoadMarker.Marker
|
||||
import com.mogo.eagle.function.biz.v2x.v2n.utils.V2NUtils
|
||||
import com.mogo.eagle.function.biz.v2x.v2n.utils.V2XEventAnalyticsManager
|
||||
import com.mogo.map.MapDataWrapper
|
||||
import com.mogo.map.entities.Lane
|
||||
import mogo.telematics.pad.MessagePad
|
||||
import mogo.telematics.pad.MessagePad.Header
|
||||
import mogo.telematics.pad.MessagePad.TrackedObject
|
||||
import mogo.telematics.pad.MessagePad.V2nCrossSpeed
|
||||
import mogo.v2x.MogoV2X
|
||||
import mogo.v2x.MogoV2X.RSI_PB
|
||||
import mogo.v2x.MogoV2X.RTEData_PB
|
||||
import java.util.concurrent.TimeUnit.SECONDS
|
||||
import kotlin.math.abs
|
||||
|
||||
/**
|
||||
* V2N上车相关事件绘制
|
||||
@@ -60,6 +66,7 @@ internal object V2NIdentifyDrawer {
|
||||
private const val MSG_WHAT_DRAW_SHIGONE = 0x1010 // 道路施工
|
||||
private const val MSG_WHAT_DRAW_SHIGU = 0x1011 // 交通事故
|
||||
private const val MSG_WHAT_DRAW_YONGDU = 0x1012 // 交通拥堵
|
||||
private const val MSG_WHAT_DRAW_GREEN_WAVE = 0x1013 // 绿波通行
|
||||
|
||||
private val callback = Handler.Callback { msg ->
|
||||
if (msg.what == MSG_WHAT_DRAW_SHIGONE || msg.what == MSG_WHAT_DRAW_SHIGU) {
|
||||
@@ -150,33 +157,6 @@ internal object V2NIdentifyDrawer {
|
||||
)
|
||||
)
|
||||
)
|
||||
// CallerHmiManager.warningV2X(
|
||||
// poiType,
|
||||
// alertContent,
|
||||
// ttsContent,
|
||||
// object : IMoGoWarningStatusListener {
|
||||
// override fun onShow() {
|
||||
// super.onShow()
|
||||
// runCatching { CallerHmiManager.notifyXiaoZhiStatusChanged(V2N(EventTypeEnumNew.getEnumType(poiType)), State.START) }
|
||||
// CallerVisualAngleManager.changeAngle(
|
||||
// RoadEvent(
|
||||
// itx.longitude,
|
||||
// itx.latitude,
|
||||
// itx.angle
|
||||
// )
|
||||
// )
|
||||
// }
|
||||
//
|
||||
// override fun onDismiss() {
|
||||
// super.onDismiss()
|
||||
// runCatching { CallerHmiManager.notifyXiaoZhiStatusChanged(V2N(EventTypeEnumNew.getEnumType(poiType)), State.STOP) }
|
||||
// CallerVisualAngleManager.changeAngle(Default())
|
||||
// }
|
||||
// },
|
||||
// ALERT_WARNING_TOP,
|
||||
// 10000,
|
||||
// false
|
||||
// )
|
||||
if (polygon.isNotEmpty()) {
|
||||
val decision = V2NUtils.computeOccupyLanesInfo(Triple(car.longitude, car.latitude, car.heading.toFloat()), Triple(itx.longitude, itx.latitude, itx.heading.toFloat()), polygon.map { kotlin.Pair(it.first, it.second) })
|
||||
if (decision != null) {
|
||||
@@ -321,6 +301,41 @@ internal object V2NIdentifyDrawer {
|
||||
}.receive()
|
||||
}
|
||||
}
|
||||
|
||||
if (msg.what == MSG_WHAT_DRAW_GREEN_WAVE) {
|
||||
val data = msg.obj as? V2nCrossSpeed ?: return@Callback true
|
||||
val destX = data.lng
|
||||
val destY = data.lat
|
||||
val id = "${destX}_${destY}"
|
||||
AiRoadMarker.aiMakers.getOrPut(id) {
|
||||
AiRoadMarker().apply {
|
||||
try {
|
||||
val location = CallerChassisLocationWGS84ListenerManager.getChassisLocationWGS84()
|
||||
val current = abs(location.gnssSpeed) * 3.6f.toInt()
|
||||
val min = abs(data.speedStraightMin * 3.6f).toInt()
|
||||
val max = abs(data.speedStraightMax * 3.6f).toInt()
|
||||
marker(Marker(id, EventTypeEnumNew.TYPE_SOCKET_ROAD_GREE_WAVE.poiType, destX, destY, 0.0, null, null, null), drawMarker = false, false)
|
||||
if (AppIdentityModeUtils.isDriver(FunctionBuildConfig.appIdentityMode)) {
|
||||
AppStateManager.currentActivity()?.let {
|
||||
val speakText = StringBuilder("保持当前车速即可通过路口,好丝滑!")
|
||||
if (current < min) {
|
||||
speakText.setLength(0)
|
||||
speakText.append("蘑菇推荐您提升车速至${min}千米每小小, 当前车速${current}千米每小时")
|
||||
}
|
||||
if (current > max) {
|
||||
speakText.setLength(0)
|
||||
speakText.append("蘑菇推荐您降低车速至${max}千米每小时, 当前车速${current}千米每小时")
|
||||
}
|
||||
AIAssist.getInstance(it).speakTTSVoice(speakText.toString())
|
||||
}
|
||||
}
|
||||
CallerHmiManager.showGreenWave(min, max, computeCrossCountBetween(Triple(location.longitude, location.latitude, location.heading), kotlin.Pair(destX, destY)))
|
||||
} finally {
|
||||
receive()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
true
|
||||
}
|
||||
|
||||
@@ -390,6 +405,21 @@ internal object V2NIdentifyDrawer {
|
||||
}
|
||||
}
|
||||
|
||||
private fun computeCrossCountBetween(start: kotlin.Triple<Double, Double, Double>, end: kotlin.Pair<Double, Double>): Int {
|
||||
val points = V2NUtils.generateIntermediatePoints(kotlin.Pair(start.first, start.second), end, 10.0 * 1e-7)
|
||||
var crossId = MapDataWrapper.getCrossRoad(start.first, start.second, start.third)?.cross_id_end
|
||||
val angle = start.third
|
||||
var count = 1
|
||||
for (p in points) {
|
||||
val crossRoad = MapDataWrapper.getCrossRoad(p.first, p.second, angle)
|
||||
if (crossRoad != null && !TextUtils.isEmpty(crossRoad.cross_id) && !TextUtils.equals(crossId, crossRoad.cross_id)) {
|
||||
count++
|
||||
crossId = crossRoad.cross_id
|
||||
}
|
||||
}
|
||||
return count
|
||||
}
|
||||
|
||||
private fun getAlertContent(poiType: String, distance: Double): String {
|
||||
return when (poiType) {
|
||||
EventTypeEnumNew.TYPE_SOCKET_ROAD_SHIGONG.poiType -> {
|
||||
@@ -474,23 +504,36 @@ internal object V2NIdentifyDrawer {
|
||||
}
|
||||
}
|
||||
|
||||
private fun drawGreenWave(crossSpeed: V2nCrossSpeed) {
|
||||
Log.d("V2NIdentifyDrawer", "---drawGreenWave---: $crossSpeed, [${FunctionBuildConfig.v2nMainSwitch}, ${FunctionBuildConfig.isNewV2NData}]")
|
||||
if (V2NCarTypeCheck.verifyCarType() && FunctionBuildConfig.v2nMainSwitch && FunctionBuildConfig.isNewV2NData) {
|
||||
handler.removeMessages(MSG_WHAT_DRAW_GREEN_WAVE)
|
||||
handler.sendMessage(Message.obtain(handler, MSG_WHAT_DRAW_GREEN_WAVE, crossSpeed))
|
||||
}
|
||||
}
|
||||
|
||||
private val nioEventListener = object : IMoGoV2nNioEventListener {
|
||||
override fun onV2nNioCongestionEvent(congestion: MessagePad.V2nCongestion) {
|
||||
super.onV2nNioCongestionEvent(congestion)
|
||||
V2XBizTrace.onAck(congestion, "onV2nNioCongestionEvent", true)
|
||||
}
|
||||
|
||||
override fun onV2nNioCrossoverEvent(event: MessagePad.Event) {
|
||||
super.onV2nNioCrossoverEvent(event)
|
||||
V2XBizTrace.onAck(event,"onV2nNioCrossoverEvent", true)
|
||||
//TODO renwj
|
||||
}
|
||||
|
||||
override fun onV2nNioGreenWavePassageEvent(crossSpeed: MessagePad.V2nCrossSpeed) {
|
||||
override fun onV2nNioGreenWavePassageEvent(crossSpeed: V2nCrossSpeed) {
|
||||
super.onV2nNioGreenWavePassageEvent(crossSpeed)
|
||||
V2XBizTrace.onAck(crossSpeed, "onV2nNioGreenWavePassageEvent", true)
|
||||
drawGreenWave(crossSpeed)
|
||||
}
|
||||
|
||||
override fun onV2nNioOtherRetrogradeEvent(event: MessagePad.Event) {
|
||||
super.onV2nNioOtherRetrogradeEvent(event)
|
||||
CallerLogger.i(TAG, "onV2nNioOtherRetrogradeEvent --> ${event.toString()}")
|
||||
|
||||
V2XBizTrace.onAck(event, "onV2nNioOtherRetrogradeEvent", true)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -7,8 +7,11 @@ import com.mogo.map.entities.Lane
|
||||
import com.zhidaoauto.map.data.road.CenterLine
|
||||
import org.locationtech.jts.geom.Coordinate
|
||||
import org.locationtech.jts.geom.GeometryFactory
|
||||
import org.locationtech.jts.geom.LineString
|
||||
import org.locationtech.jts.linearref.LengthIndexedLine
|
||||
import java.util.concurrent.CountDownLatch
|
||||
|
||||
|
||||
object V2NUtils {
|
||||
|
||||
private const val TAG = "V2NUtils"
|
||||
@@ -42,4 +45,25 @@ object V2NUtils {
|
||||
}
|
||||
|
||||
data class Decision(val laneId: Int? = null,val total: List<Lane>, val occupy: List<Lane>)
|
||||
|
||||
|
||||
fun generateIntermediatePoints(head: Pair<Double, Double>, tail: Pair<Double, Double>, interval: Double): List<Pair<Double, Double>> {
|
||||
val geometryFactory = GeometryFactory()
|
||||
val start = Coordinate(head.first, head.second)
|
||||
val end = Coordinate(tail.first, tail.second)
|
||||
val line: LineString = geometryFactory.createLineString(arrayOf(start, end))
|
||||
val indexedLine = LengthIndexedLine(line)
|
||||
val lineLength = indexedLine.endIndex
|
||||
val result: MutableList<Coordinate> = ArrayList()
|
||||
var i = 0.0
|
||||
while (i <= lineLength) {
|
||||
val p = indexedLine.extractPoint(i)
|
||||
result.add(p)
|
||||
i += interval
|
||||
}
|
||||
if (result[result.size - 1].distance(end) > 0.0001) {
|
||||
result.add(end)
|
||||
}
|
||||
return result.map { Pair(it.x, it.y) }
|
||||
}
|
||||
}
|
||||
@@ -4,6 +4,7 @@ import android.content.Context
|
||||
import android.text.TextUtils
|
||||
import android.view.Gravity
|
||||
import android.view.ViewGroup
|
||||
import android.view.WindowManager
|
||||
import androidx.lifecycle.ProcessLifecycleOwner
|
||||
import androidx.lifecycle.lifecycleScope
|
||||
import com.alibaba.android.arouter.facade.annotation.Route
|
||||
@@ -30,6 +31,7 @@ import com.mogo.eagle.core.function.call.hmi.CallerHmiViewControlListenerManager
|
||||
import com.mogo.eagle.core.function.call.v2x.CallerTrafficLightListenerManager
|
||||
import com.mogo.eagle.core.function.call.v2x.CallerTurnLightListenerManager
|
||||
import com.mogo.eagle.core.function.hmi.ui.camera.RoadVideoDialog
|
||||
import com.mogo.eagle.core.function.hmi.ui.greenwave.GreenWaveView
|
||||
import com.mogo.eagle.core.function.hmi.ui.lookaround.M1LookAroundView
|
||||
import com.mogo.eagle.core.function.hmi.ui.notice.DispatchDialogManager
|
||||
import com.mogo.eagle.core.function.hmi.ui.notice.NoticeCheckDialog
|
||||
@@ -83,6 +85,8 @@ class MoGoHmiProvider : IMoGoHmiProvider {
|
||||
|
||||
private val xiaozhi by lazy { XiaoZhiStateManager() }
|
||||
|
||||
private val greenWave by lazy { AtomicReference<MoGoPopWindow>() }
|
||||
|
||||
|
||||
override fun init(context: Context?) {
|
||||
this.context = context
|
||||
@@ -403,4 +407,29 @@ class MoGoHmiProvider : IMoGoHmiProvider {
|
||||
override fun notifyXiaoZhiStatusChanged(event: Event, state: State) {
|
||||
xiaozhi.notify(event, state)
|
||||
}
|
||||
|
||||
override fun showGreenWave(min: Int, max: Int, cross: Int) {
|
||||
val activity = AppStateManager.currentActivity() ?: return
|
||||
greenWave.get()?.hide()
|
||||
val content = GreenWaveView(activity)
|
||||
MoGoPopWindow.Builder()
|
||||
.contentView(content)
|
||||
.width(WindowManager.LayoutParams.WRAP_CONTENT)
|
||||
.height(WindowManager.LayoutParams.WRAP_CONTENT)
|
||||
.attachToActivity(activity)
|
||||
.gravityInActivity(Gravity.END)
|
||||
.onDismissed {
|
||||
greenWave.set(null)
|
||||
}
|
||||
.onShowed {
|
||||
content.bind(min, max, cross)
|
||||
}
|
||||
.build().also {
|
||||
greenWave.set(it)
|
||||
}.show()
|
||||
}
|
||||
|
||||
override fun dismissGreenWave() {
|
||||
greenWave.get()?.hide()
|
||||
}
|
||||
}
|
||||
@@ -1,7 +1,6 @@
|
||||
package com.mogo.eagle.core.function.hmi.ui.greenwave
|
||||
|
||||
import android.content.Context
|
||||
import android.os.Looper
|
||||
import android.util.AttributeSet
|
||||
import android.view.LayoutInflater
|
||||
import android.view.MotionEvent
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
package com.mogo.eagle.core.data.enums
|
||||
|
||||
import android.view.View
|
||||
import com.mogo.eagle.core.data.R
|
||||
import com.mogo.eagle.core.data.config.FunctionBuildConfig
|
||||
import com.mogo.eagle.core.utilcode.mogo.AppIdentityModeUtils
|
||||
@@ -518,6 +519,13 @@ enum class EventTypeEnumNew(
|
||||
content = "前方%s米有车辆异常倒车/逆行,蘑菇提醒您注意观察小心通过",
|
||||
tts = "前方%s米有车辆异常倒车/逆行,蘑菇提醒您注意观察小心通过"
|
||||
),
|
||||
TYPE_SOCKET_ROAD_GREE_WAVE(
|
||||
"100063",
|
||||
"绿波通行",
|
||||
poiTypeSrcVr = View.NO_ID,
|
||||
content = "保持当前车速即可通过路口,好丝滑!",
|
||||
tts = "保持当前车速即可通过路口,好丝滑!"
|
||||
),
|
||||
TYPE_ERROR(
|
||||
0.toString(),
|
||||
"未知/错误/异常",
|
||||
|
||||
@@ -217,4 +217,14 @@ interface IMoGoHmiProvider :IProvider{
|
||||
* 通知小智形象要变化了
|
||||
*/
|
||||
fun notifyXiaoZhiStatusChanged(event: Event, state: State)
|
||||
|
||||
/**
|
||||
* 展示绿波通行弹窗
|
||||
*/
|
||||
fun showGreenWave(min: Int, max: Int, cross: Int)
|
||||
|
||||
/**
|
||||
* 隐藏绿波通弹窗
|
||||
*/
|
||||
fun dismissGreenWave()
|
||||
}
|
||||
@@ -317,4 +317,18 @@ object CallerHmiManager {
|
||||
fun notifyXiaoZhiStatusChanged(event: Event, state: State) {
|
||||
hmiProviderApi?.notifyXiaoZhiStatusChanged(event, state)
|
||||
}
|
||||
|
||||
/**
|
||||
* 展示绿波通行弹窗
|
||||
*/
|
||||
fun showGreenWave(min: Int, max: Int, cross: Int) {
|
||||
hmiProviderApi?.showGreenWave(min, max, cross)
|
||||
}
|
||||
|
||||
/**
|
||||
* 隐藏绿波通行弹窗
|
||||
*/
|
||||
fun dismissGreenWave() {
|
||||
hmiProviderApi?.dismissGreenWave()
|
||||
}
|
||||
}
|
||||
@@ -2,6 +2,7 @@ package com.mogo.map
|
||||
|
||||
import com.mogo.eagle.core.data.map.MogoLocation
|
||||
import com.mogo.map.entities.BusStation
|
||||
import com.mogo.map.entities.CrossRoad
|
||||
import com.mogo.map.entities.Lane
|
||||
import com.mogo.map.entities.RoadInfo
|
||||
import com.zhidaoauto.map.data.point.LonLatPoint
|
||||
@@ -121,4 +122,9 @@ interface IMogoData {
|
||||
* 获取公交站点集合
|
||||
*/
|
||||
fun getBusStation(routeList: ArrayList<LonLatPoint>): List<BusStation>
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取路口数据
|
||||
*/
|
||||
fun getCrossRoad(lon: Double, lat: Double, angle: Double): CrossRoad?
|
||||
}
|
||||
|
||||
@@ -0,0 +1,9 @@
|
||||
package com.mogo.map.entities
|
||||
|
||||
data class CrossRoad(
|
||||
val status: Int, // 0: 不在路口 1: 在路口
|
||||
val tile_id: String, // 起始路口瓦片id或者当前路口的瓦片id
|
||||
val cross_id: String, // 起始路口id或当前路口id
|
||||
val tile_id_end: String, //
|
||||
val cross_id_end: String
|
||||
)
|
||||
@@ -6,11 +6,13 @@ import com.mogo.eagle.core.utilcode.mogo.logger.Logger
|
||||
import com.mogo.eagle.core.utilcode.mogo.logger.scene.SceneConstant.Companion.M_MAP
|
||||
import com.mogo.map.MogoData.Companion.mogoMapData
|
||||
import com.mogo.map.entities.BusStation
|
||||
import com.mogo.map.entities.CrossRoad
|
||||
import com.mogo.map.entities.Lane
|
||||
import com.mogo.map.location.GDLocationClient.Companion.gdLocationClient
|
||||
import com.mogo.map.utils.HDMapUtils.getHDCityCode
|
||||
import com.zhidaoauto.map.data.point.LonLatPoint
|
||||
import com.zhidaoauto.map.data.road.CenterLine
|
||||
import com.zhidaoauto.map.data.road.RoadCross
|
||||
import com.zhidaoauto.map.data.road.RoadNameInfo
|
||||
import com.zhidaoauto.map.data.road.RoadRectInfos
|
||||
import com.zhidaoauto.map.data.road.RoutePath
|
||||
@@ -21,6 +23,7 @@ import com.zhidaoauto.map.sdk.open.abs.OnHdDataDownByCityListener
|
||||
import com.zhidaoauto.map.sdk.open.data.CityInfo
|
||||
import com.zhidaoauto.map.sdk.open.data.MapDataApi
|
||||
import java.util.concurrent.CountDownLatch
|
||||
import java.util.concurrent.atomic.AtomicReference
|
||||
|
||||
/**
|
||||
* 地图数据工具,涉及到数据调用可能会有耗时,建议IO操作
|
||||
@@ -303,4 +306,18 @@ object MapDataWrapper : IMogoData {
|
||||
latch.await()
|
||||
return resultList
|
||||
}
|
||||
|
||||
override fun getCrossRoad(lon: Double, lat: Double, angle: Double): CrossRoad? {
|
||||
val latch = CountDownLatch(1)
|
||||
val temp = AtomicReference<CrossRoad>()
|
||||
MapDataApi.getCrossRoad(lon, lat, angle.toFloat(), object : IResult<RoadCross> {
|
||||
|
||||
override fun result(code: Int, result: RoadCross?) {
|
||||
temp.set(CrossRoad(result?.status ?: 0, result?.tile_id ?: "", result?.cross_id ?: "", result?.tile_id_end ?: "", result?.cross_id_end ?: ""))
|
||||
latch.countDown()
|
||||
}
|
||||
})
|
||||
latch.await()
|
||||
return temp.get()
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user