[6.5.0][道路事件] 绿波通行业务逻辑

This commit is contained in:
renwj
2024-07-03 19:50:49 +08:00
parent fd087758c9
commit de4d758930
10 changed files with 190 additions and 31 deletions

View File

@@ -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)
}
}

View File

@@ -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) }
}
}

View File

@@ -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()
}
}

View File

@@ -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