[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
|
||||
|
||||
Reference in New Issue
Block a user