[8.1.2][feat]决策功能用动画实现

This commit is contained in:
chenfufeng
2025-07-10 14:37:29 +08:00
parent 64fcdc0422
commit 67ce8b1c8c
26 changed files with 843 additions and 111 deletions

View File

@@ -26,6 +26,9 @@ import com.mogo.map.overlay.core.Level
import com.mogo.map.overlay.point.Point import com.mogo.map.overlay.point.Point
import com.mogo.och.bridge.BridgeServiceManager import com.mogo.och.bridge.BridgeServiceManager
import com.mogo.och.bridge.R import com.mogo.och.bridge.R
import com.mogo.och.common.module.manager.loop.BizLoopManager
import com.mogo.och.common.module.manager.loop.LoopInfo
import io.reactivex.schedulers.Schedulers
import prediction2025.Prediction2025 import prediction2025.Prediction2025
import mogo.telematics.pad.MessagePad import mogo.telematics.pad.MessagePad
import kotlin.properties.Delegates import kotlin.properties.Delegates
@@ -54,6 +57,7 @@ object OchBridgeManager: IMoGoPlanningTrajectoryListener, IMoGoAutopilotIdentify
CallerPlanningTrajectoryListenerManager.addListener(TAG,this) CallerPlanningTrajectoryListenerManager.addListener(TAG,this)
CallerAutopilotIdentifyListenerManager.addListener(TAG,this) CallerAutopilotIdentifyListenerManager.addListener(TAG,this)
CallerPlanningActionsListenerManager.addListener(TAG, this) CallerPlanningActionsListenerManager.addListener(TAG, this)
BizLoopManager.setLoopFunction(TAG, LoopInfo(2, ::checkTimeout, immediately = false, scheduler = Schedulers.io()))
UiThreadHandler.postDelayed(timeRunnable, 1000) UiThreadHandler.postDelayed(timeRunnable, 1000)
} }
@@ -70,7 +74,6 @@ object OchBridgeManager: IMoGoPlanningTrajectoryListener, IMoGoAutopilotIdentify
CallerLogger.d(TAG,"haveTrajectoryInfo 发生变化:${newValue}") CallerLogger.d(TAG,"haveTrajectoryInfo 发生变化:${newValue}")
} }
trajectoryTime = System.currentTimeMillis() trajectoryTime = System.currentTimeMillis()
} }
// 是否有预测数据 // 是否有预测数据

View File

@@ -24,6 +24,7 @@ import kotlinx.android.synthetic.main.taxi_p_home.view.lbv_go2_center
import kotlinx.android.synthetic.main.taxi_p_home.view.leftEndGuideline import kotlinx.android.synthetic.main.taxi_p_home.view.leftEndGuideline
import kotlinx.android.synthetic.main.taxi_p_home.view.midContainer import kotlinx.android.synthetic.main.taxi_p_home.view.midContainer
import kotlinx.android.synthetic.main.taxi_p_home.view.midStartGuideline import kotlinx.android.synthetic.main.taxi_p_home.view.midStartGuideline
import kotlinx.android.synthetic.main.taxi_p_home.view.preContainer
class HomeView @JvmOverloads constructor( class HomeView @JvmOverloads constructor(
context: Context, context: Context,
@@ -87,37 +88,37 @@ class HomeView @JvmOverloads constructor(
fun onCreate(savedInstanceState: Bundle?) { fun onCreate(savedInstanceState: Bundle?) {
hdMapView.onCreate(savedInstanceState) hdMapView.onCreate(savedInstanceState)
// preContainer.onCreate(savedInstanceState) preContainer.onCreate(savedInstanceState)
// decContainer.onCreate(savedInstanceState) // decContainer.onCreate(savedInstanceState)
} }
fun onSaveInstanceState(outState: Bundle) { fun onSaveInstanceState(outState: Bundle) {
hdMapView.onSaveInstanceState(outState) hdMapView.onSaveInstanceState(outState)
// preContainer.onSaveInstanceState(outState) preContainer.onSaveInstanceState(outState)
// decContainer.onSaveInstanceState(outState) // decContainer.onSaveInstanceState(outState)
} }
fun onResume() { fun onResume() {
hdMapView.onResume() hdMapView.onResume()
// preContainer.onResume() preContainer.onResume()
// decContainer.onResume() // decContainer.onResume()
} }
fun onLowMemory() { fun onLowMemory() {
hdMapView.onLowMemory() hdMapView.onLowMemory()
// preContainer.onLowMemory() preContainer.onLowMemory()
// decContainer.onLowMemory() // decContainer.onLowMemory()
} }
fun onPause() { fun onPause() {
hdMapView.onPause() hdMapView.onPause()
// preContainer.onPause() preContainer.onPause()
// decContainer.onPause() // decContainer.onPause()
} }
fun onDestroy() { fun onDestroy() {
hdMapView.onDestroy() hdMapView.onDestroy()
// preContainer.onDestroy() preContainer.onDestroy()
// decContainer.onDestroy() // decContainer.onDestroy()
} }

View File

@@ -55,21 +55,19 @@ class HomeViewModel : ViewModel(), BridgeListener, OrderListener {
} }
private fun checkScreenChange(){ private fun checkScreenChange(){
// CallerLogger.d(TAG,"havePredictionInfos:${havePredictionInfos}--haveTrajectoryInfos:${haveTrajectoryInfos}--order:${order}") CallerLogger.d(TAG,"havePredictionInfos:${havePredictionInfos}--haveTrajectoryInfos:${haveTrajectoryInfos}--order:${order}")
// if(havePredictionInfos&&havePredictionInfos){//order!=null&& if(order!=null&&havePredictionInfos&&havePredictionInfos){
// FunctionBuildConfig.isDrawDecIdentifyData = true // 展示三联屏
// FunctionBuildConfig.isDrawPreIdentifyData = true BizLoopManager.runInMainThread{
// // 展示三联屏 this.viewCallback?.showThreeScreen()
// BizLoopManager.runInMainThread{ FunctionBuildConfig.isDrawPreIdentifyData = true
// this.viewCallback?.showThreeScreen() }
// } }else{
// }else{ FunctionBuildConfig.isDrawPreIdentifyData = false
// FunctionBuildConfig.isDrawDecIdentifyData = false // 展示二联屏幕
// FunctionBuildConfig.isDrawPreIdentifyData = false BizLoopManager.runInMainThread{
// // 展示二联屏幕 this.viewCallback?.showTwoScreen()
// BizLoopManager.runInMainThread{ }
// this.viewCallback?.showTwoScreen() }
// }
// }
} }
} }

View File

@@ -34,23 +34,23 @@
app:layout_constraintStart_toEndOf="@+id/midStartGuideline" app:layout_constraintStart_toEndOf="@+id/midStartGuideline"
app:layout_constraintTop_toTopOf="parent"> app:layout_constraintTop_toTopOf="parent">
<!-- <com.mogo.eagle.core.function.view.PredictionLayout--> <com.mogo.eagle.core.function.view.PredictionLayout
<!-- android:id="@+id/preContainer"--> android:id="@+id/preContainer"
<!-- android:layout_width="match_parent"--> android:layout_width="match_parent"
<!-- android:layout_height="@dimen/dp_676"--> android:layout_height="@dimen/dp_676"
<!-- android:background="@drawable/taxi_p_home_middle_top_bg"--> android:background="@drawable/taxi_p_home_middle_top_bg"
<!-- app:layout_constraintEnd_toEndOf="parent"--> app:layout_constraintEnd_toEndOf="parent"
<!-- app:layout_constraintStart_toStartOf="parent"--> app:layout_constraintStart_toStartOf="parent"
<!-- app:layout_constraintTop_toTopOf="parent" />--> app:layout_constraintTop_toTopOf="parent" />
<!-- <com.mogo.eagle.core.function.view.DecisionLayout--> <com.mogo.eagle.core.function.view.DecisionLayout
<!-- android:id="@+id/decContainer"--> android:id="@+id/decContainer"
<!-- android:layout_width="match_parent"--> android:layout_width="match_parent"
<!-- android:layout_height="@dimen/dp_676"--> android:layout_height="@dimen/dp_676"
<!-- android:background="@drawable/taxi_p_home_middle_bottom_bg"--> android:background="@drawable/taxi_p_home_middle_bottom_bg"
<!-- app:layout_constraintBottom_toBottomOf="parent"--> app:layout_constraintBottom_toBottomOf="parent"
<!-- app:layout_constraintEnd_toEndOf="parent"--> app:layout_constraintEnd_toEndOf="parent"
<!-- app:layout_constraintStart_toStartOf="parent" />--> app:layout_constraintStart_toStartOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout> </androidx.constraintlayout.widget.ConstraintLayout>

View File

@@ -105,24 +105,26 @@ class MapIdentifySubscriber private constructor() : IMoGoSubscriber,
predictionObjects.objsAppList.forEach { preObj -> predictionObjects.objsAppList.forEach { preObj ->
val points = ArrayList<MogoLatLng>() val points = ArrayList<MogoLatLng>()
if (preObj.mNid == 800000L) { if (preObj.mNid == 800000L) {
// 自车有2条轨迹一条概率大、一条概率小 // // 自车有2条轨迹一条概率大、一条概率小
if (preObj.predictionTrajectoryList == null || preObj.predictionTrajectoryList.size < 2) return@forEach // if (preObj.predictionTrajectoryList == null || preObj.predictionTrajectoryList.size < 2) return@forEach
carPoiList1 = preObj.predictionTrajectoryList[0].trajectoryPointsList // carPoiList1 = preObj.predictionTrajectoryList[0].trajectoryPointsList
carPoiList2 = preObj.predictionTrajectoryList[1].trajectoryPointsList // carPoiList2 = preObj.predictionTrajectoryList[1].trajectoryPointsList
location1 = LocationUtils.generateLocation(carPoiList1!![0].x, carPoiList1!![0].y, getLocationHeading()) // location1 = LocationUtils.generateLocation(carPoiList1!![0].x, carPoiList1!![0].y, getLocationHeading())
location2 = LocationUtils.generateLocation(carPoiList2!![0].x, carPoiList2!![0].y, getLocationHeading()) // location2 = LocationUtils.generateLocation(carPoiList2!![0].x, carPoiList2!![0].y, getLocationHeading())
if (location1 == null || location2 == null) return@forEach // if (location1 == null || location2 == null) return@forEach
probability1 = preObj.predictionTrajectoryList[0].predictionProbability // probability1 = preObj.predictionTrajectoryList[0].predictionProbability
probability2 = preObj.predictionTrajectoryList[1].predictionProbability // probability2 = preObj.predictionTrajectoryList[1].predictionProbability
CallerAutopilotIdentifyListenerManager.invokeProbabilityChanged(probability1, probability2) // CallerAutopilotIdentifyListenerManager.invokeProbabilityChanged(probability1, probability2)
PredictionDataManager.getInstance()?.updateData(carPoiList1!!, 0) // PredictionDataManager.getInstance()?.updateData(carPoiList1!!, 0)
PredictionDataManager.getInstance()?.updateData(carPoiList2!!, 2) // PredictionDataManager.getInstance()?.updateData(carPoiList2!!, 2)
} else { } else {
if (isUnKnownType(preObj.classtype) || preObj.predictionTrajectoryList.isNullOrEmpty() || mogoMap == null) return@forEach if (isUnKnownType(preObj.classtype) || preObj.predictionTrajectoryList.isNullOrEmpty() || mogoMap == null) return@forEach
point = preObj.predictionTrajectoryList[0].trajectoryPointsList[0] point = preObj.predictionTrajectoryList[0].trajectoryPointsList[0]
arr = mogoMap.switchData(point.x, point.y, false) arr = mogoMap.switchData(point.x, point.y, false)
arr?.let { lonLatArr -> arr?.let { lonLatArr ->
// 感知物不在当前视椎体内则不渲染其预测轨迹
if (!mogoMap.isInCurrentFrame(lonLatArr[0], lonLatArr[1])) return@forEach
val distance = com.mogo.eagle.core.utilcode.util.LocationUtils.getDistance(getWgs84Lat(), getWgs84Lon(), lonLatArr[1], lonLatArr[0]) val distance = com.mogo.eagle.core.utilcode.util.LocationUtils.getDistance(getWgs84Lat(), getWgs84Lon(), lonLatArr[1], lonLatArr[0])
if (distance > 28) return@forEach if (distance > 28) return@forEach
} }

View File

@@ -131,16 +131,12 @@ public class MogoRouteOverlayManager implements
// Log.d(TAG, "-- onChassisLocationGCJ02 -- 1 ---" + ":auto-mode:" + autoPilotState + ", isArriveAtStation: " + isArriveAtStation); // Log.d(TAG, "-- onChassisLocationGCJ02 -- 1 ---" + ":auto-mode:" + autoPilotState + ", isArriveAtStation: " + isArriveAtStation);
if (isArriveAtStation && autoPilotState != 2) { if (isArriveAtStation && autoPilotState != 2) {
RouteOverlayDrawer.getInstance().clearMogoRouteOverlay(); RouteOverlayDrawer.getInstance().clearMogoRouteOverlay();
PredictionOverlayDrawer2.getInstance().clearPreRouteOverlay();
PredictionOverlayDrawer3.getInstance().clearPreRouteOverlay();
return; return;
} }
// Log.d(TAG, "-- onChassisLocationGCJ02 -- 2 ---" + "auto-mode:" + autoPilotState + ", isDemoMode:" + FunctionBuildConfig.isDemoMode + ", force:" + FunctionBuildConfig.isForceDrawAutopilotTrajectoryByDebugSettingView); // Log.d(TAG, "-- onChassisLocationGCJ02 -- 2 ---" + "auto-mode:" + autoPilotState + ", isDemoMode:" + FunctionBuildConfig.isDemoMode + ", force:" + FunctionBuildConfig.isForceDrawAutopilotTrajectoryByDebugSettingView);
boolean force = hasGreenWave.get() || FunctionBuildConfig.isForceDrawAutopilotTrajectoryByDebugSettingView || FunctionBuildConfig.isDemoMode && FunctionBuildConfig.isIgnoreConditionsDrawAutopilotTrajectoryData; boolean force = hasGreenWave.get() || FunctionBuildConfig.isForceDrawAutopilotTrajectoryByDebugSettingView || FunctionBuildConfig.isDemoMode && FunctionBuildConfig.isIgnoreConditionsDrawAutopilotTrajectoryData;
if (!force && autoPilotState != 2) { if (!force && autoPilotState != 2) {
RouteOverlayDrawer.getInstance().clearMogoRouteOverlay(); RouteOverlayDrawer.getInstance().clearMogoRouteOverlay();
PredictionOverlayDrawer2.getInstance().clearPreRouteOverlay();
PredictionOverlayDrawer3.getInstance().clearPreRouteOverlay();
return; return;
} }
// Log.d(TAG, "-- onChassisLocationGCJ02 -- 3 ---"); // Log.d(TAG, "-- onChassisLocationGCJ02 -- 3 ---");

View File

@@ -148,7 +148,7 @@ public class PredictionOverlayDrawer {
builder.color(Color.argb(102,48,163,255)); builder.color(Color.argb(102,48,163,255));
builder.setIsGradient(true); builder.setIsGradient(true);
builder.setLightOn(false); builder.setLightOn(false);
builder.setIsDottedLine(true); builder.setIsDottedLine(false);
builder.isShowArrow(false); builder.isShowArrow(false);
builder.points(pps); builder.points(pps);
builder.setVisible(true); builder.setVisible(true);

View File

@@ -3,25 +3,40 @@ package com.mogo.eagle.core.function.view
import android.annotation.SuppressLint import android.annotation.SuppressLint
import android.content.Context import android.content.Context
import android.os.Bundle import android.os.Bundle
import android.os.SystemClock
import android.util.AttributeSet import android.util.AttributeSet
import android.view.LayoutInflater import android.view.LayoutInflater
import androidx.constraintlayout.widget.ConstraintLayout import androidx.constraintlayout.widget.ConstraintLayout
import com.mogo.eagle.core.function.api.autopilot.IMoGoAutopilotIdentifyListener import com.mogo.eagle.core.function.api.autopilot.IMoGoAutopilotIdentifyListener
import com.mogo.eagle.core.function.business.routeoverlay.DecisionDataManager import com.mogo.eagle.core.function.api.autopilot.IMoGoAutopilotPlanningActionsListener
import com.mogo.eagle.core.function.business.routeoverlay.PredictionDataManager
import com.mogo.eagle.core.function.call.autopilot.CallerAutopilotIdentifyListenerManager import com.mogo.eagle.core.function.call.autopilot.CallerAutopilotIdentifyListenerManager
import com.mogo.eagle.core.function.call.autopilot.CallerPlanningActionsListenerManager
import com.mogo.eagle.core.function.map.R import com.mogo.eagle.core.function.map.R
import com.mogo.eagle.core.utilcode.util.ThreadUtils import com.mogo.eagle.core.utilcode.util.ThreadUtils
import com.mogo.eagle.core.utilcode.util.UiThreadHandler import com.shuyu.gsyvideoplayer.GSYVideoManager
import com.shuyu.gsyvideoplayer.builder.GSYVideoOptionBuilder
import com.shuyu.gsyvideoplayer.model.VideoOptionModel
import com.shuyu.gsyvideoplayer.player.IjkPlayerManager
import com.shuyu.gsyvideoplayer.player.PlayerFactory
import com.shuyu.gsyvideoplayer.utils.GSYVideoType
import kotlinx.android.synthetic.main.layout_decision_container.view.tvPre1 import kotlinx.android.synthetic.main.layout_decision_container.view.tvPre1
import kotlinx.android.synthetic.main.layout_decision_container.view.tvPre2 import kotlinx.android.synthetic.main.layout_decision_container.view.tvPre2
import kotlinx.android.synthetic.main.layout_decision_container.view.tvPre3 import kotlinx.android.synthetic.main.layout_decision_container.view.tvPre3
import me.jessyan.autosize.utils.AutoSizeUtils import kotlinx.android.synthetic.main.layout_decision_video_container.view.decContent1
import kotlinx.android.synthetic.main.layout_decision_video_container.view.decContent2
import kotlinx.android.synthetic.main.layout_decision_video_container.view.decContent3
import kotlinx.android.synthetic.main.layout_decision_video_container.view.decMapView
import kotlinx.android.synthetic.main.layout_decision_video_container.view.preDetailView2
import kotlinx.android.synthetic.main.layout_decision_video_container.view.preDetailView3
import mogo.telematics.pad.MessagePad
import tv.danmaku.ijk.media.player.IjkMediaPlayer
import kotlin.random.Random
class DecisionLayout @JvmOverloads constructor( class DecisionLayout @JvmOverloads constructor(
context: Context, context: Context,
attrs: AttributeSet? = null attrs: AttributeSet? = null
) : ConstraintLayout(context, attrs), IMoGoAutopilotIdentifyListener { ) : ConstraintLayout(context, attrs), IMoGoAutopilotIdentifyListener,
IMoGoAutopilotPlanningActionsListener {
companion object { companion object {
private const val TAG = "DecisionLayout" private const val TAG = "DecisionLayout"
@@ -32,6 +47,21 @@ class DecisionLayout @JvmOverloads constructor(
private var carType = 0 private var carType = 0
private val gsyVideoOptionBuilder1 by lazy {
GSYVideoOptionBuilder()
}
private var lastUrl1 = ""
private val gsyVideoOptionBuilder2 by lazy {
GSYVideoOptionBuilder()
}
private var lastUrl2 = ""
private val gsyVideoOptionBuilder3 by lazy {
GSYVideoOptionBuilder()
}
private var lastUrl3 = ""
init { init {
initView(attrs) initView(attrs)
} }
@@ -40,21 +70,26 @@ class DecisionLayout @JvmOverloads constructor(
val typedArray = context.obtainStyledAttributes(attrs, R.styleable.CarMapLayout) val typedArray = context.obtainStyledAttributes(attrs, R.styleable.CarMapLayout)
carType = typedArray.getInt(R.styleable.CarMapLayout_car_type, 0) carType = typedArray.getInt(R.styleable.CarMapLayout_car_type, 0)
typedArray.recycle() typedArray.recycle()
when (carType) { // when (carType) {
0 -> LayoutInflater.from(context).inflate(R.layout.layout_decision_container, this, true) // 0 -> LayoutInflater.from(context).inflate(R.layout.layout_decision_container, this, true)
else -> LayoutInflater.from(context).inflate(R.layout.layout_b2_decision_container, this, true) // else -> LayoutInflater.from(context).inflate(R.layout.layout_b2_decision_container, this, true)
} // }
storeWidthAndHeight() LayoutInflater.from(context).inflate(R.layout.layout_decision_video_container, this, true)
// storeWidthAndHeight()
initViews()
initVideos()
} }
override fun onAttachedToWindow() { override fun onAttachedToWindow() {
super.onAttachedToWindow() super.onAttachedToWindow()
CallerAutopilotIdentifyListenerManager.addListener(TAG, this) CallerAutopilotIdentifyListenerManager.addListener(TAG, this)
CallerPlanningActionsListenerManager.addListener(TAG, this)
} }
override fun onDetachedFromWindow() { override fun onDetachedFromWindow() {
super.onDetachedFromWindow() super.onDetachedFromWindow()
CallerAutopilotIdentifyListenerManager.removeListener(TAG) CallerAutopilotIdentifyListenerManager.removeListener(TAG)
CallerPlanningActionsListenerManager.removeListener(TAG)
} }
fun onCreate(savedInstanceState: Bundle?) { fun onCreate(savedInstanceState: Bundle?) {
@@ -66,30 +101,6 @@ class DecisionLayout @JvmOverloads constructor(
fun onResume() { fun onResume() {
} }
@SuppressLint("SetTextI18n")
override fun onPredictionProbabilityChanged(pro1: Float, pro2: Float) {
if (System.currentTimeMillis() - lastTime >= 1000) {
ThreadUtils.runOnUiThread {
val prob1: Int
val prob2: Int
val prob3: Int
if (pro1 + pro2 < 50) {
prob1= (pro1*100).toInt()
prob3= (pro2*100).toInt()
prob2 = 100 - prob1 - prob3
} else {
prob1 = 15 * (pro1 / (pro1 + pro2)).toInt()
prob3 = 15 * (pro2 / (pro1 + pro2)).toInt()
prob2 = 100 - prob1 - prob3
}
tvPre1.text = "${prob1}%"
tvPre3.text = "${prob3}%"
tvPre2.text = "${prob2}%"
}
lastTime = System.currentTimeMillis()
}
}
fun onLowMemory() { fun onLowMemory() {
} }
@@ -99,25 +110,214 @@ class DecisionLayout @JvmOverloads constructor(
fun onDestroy() { fun onDestroy() {
} }
private fun storeWidthAndHeight() { private var state = -1
UiThreadHandler.post { private var action = -1
when (carType) { override fun pncActions(planningActionMsg: MessagePad.PlanningActionMsg) {
// 默认值为对应0不需要赋值 val actionMsg = planningActionMsg.actionMsg
1 -> { val s = actionMsg.drivingState.number
val decWid = AutoSizeUtils.dp2px(context, 110f) val a = actionMsg.drivingAction.number
val decHet = AutoSizeUtils.dp2px(context, 211f) if(s == state && a == action){
val mapWid = AutoSizeUtils.dp2px(context, 996f) return
val mapHet = AutoSizeUtils.dp2px(context, 650f) } else {
PredictionDataManager.getInstance()?.decWidth = decWid state = s
PredictionDataManager.getInstance()?.decHeight = decHet action = a
PredictionDataManager.getInstance()?.mapWidth = mapWid }
PredictionDataManager.getInstance()?.mapHeight = mapHet var type = -1
DecisionDataManager.getInstance()?.decWidth = decWid if (actionMsg.drivingState == MessagePad.DrivingState.START_UP && actionMsg.drivingAction == MessagePad.DrivingAction.DRIVING_ACTION_STATE_ONE) {
DecisionDataManager.getInstance()?.decHeight = decHet type = 0// 出站
DecisionDataManager.getInstance()?.mapWidth = mapWid } else if (actionMsg.drivingState == MessagePad.DrivingState.PULL_OVER && actionMsg.drivingAction == MessagePad.DrivingAction.DRIVING_ACTION_STATE_ONE) {
DecisionDataManager.getInstance()?.mapHeight = mapHet type = 1// 进站
} } else if (actionMsg.drivingState == MessagePad.DrivingState.LANKE_KEEP && actionMsg.drivingAction == MessagePad.DrivingAction.DRIVING_ACTION_STATE_ONE) {
type = 2// 车道保持
} else if (actionMsg.drivingState == MessagePad.DrivingState.FOLLOW_LANE_CHANGE_LEFT) {//actionMsg.drivingAction == MessagePad.DrivingAction.DRIVING_ACTION_STATE_TWO
type = 3// 向左变道
} else if (actionMsg.drivingState == MessagePad.DrivingState.FOLLOW_LANE_CHANGE_RIGHT) {
type = 4// 向右变道
} else if (actionMsg.drivingState == MessagePad.DrivingState.LANE_AVOID_LEFT) {
type = 5// 向左变道绕障
} else if (actionMsg.drivingState == MessagePad.DrivingState.LANE_AVOID_RIGHT) {
type = 6// 向右变道绕障
} else if (actionMsg.drivingState == MessagePad.DrivingState.TRAFFIC_LIGHT) {// 距离停止线前15m内且是红灯才会发送该状态
}
if (type >= 0) {
ThreadUtils.runOnUiThread {
updateAnim(type)
} }
} }
} }
@SuppressLint("SetTextI18n")
private fun updateAnim(type: Int) {
val randomNum = 80 + Random(SystemClock.elapsedRealtime()).nextInt(16)
val last = 100 - randomNum
val pre1 = Random(SystemClock.elapsedRealtime()).nextInt(last+1)
val pre2 = last - pre1
tvPre1.text = "${pre1}%"
tvPre3.text = "${randomNum}%"
tvPre2.text = "${pre2}%"
when (type) {
0 -> {
decContent1.text = "停车等待"
decContent2.text = "变道出站"
decContent3.text = "直行出站"
gsyVideoPlay(getRawPath(R.raw.wujuece))
gsyVideoPlay2(getRawPath(R.raw.zuohuandao))
gsyVideoPlay3(getRawPath(R.raw.zhixing))
}
1 -> {
decContent1.text = "车道保持"
decContent2.text = "进站停车"
decContent3.text = "向右变道"
gsyVideoPlay(getRawPath(R.raw.zhixing))
gsyVideoPlay2(getRawPath(R.raw.youhuandao))
gsyVideoPlay3(getRawPath(R.raw.youhuandao))
}
2 -> {
decContent1.text = "向左变道"
decContent2.text = "车道保持"
decContent3.text = "向右变道"
gsyVideoPlay(getRawPath(R.raw.zuohuandao))
gsyVideoPlay2(getRawPath(R.raw.zhixing))
gsyVideoPlay3(getRawPath(R.raw.youhuandao))
}
3 -> {
decContent1.text = "车道保持"
decContent2.text = "向左变道"
decContent3.text = "向右变道"
gsyVideoPlay(getRawPath(R.raw.zhixing))
gsyVideoPlay2(getRawPath(R.raw.zuohuandao))
gsyVideoPlay3(getRawPath(R.raw.youhuandao))
}
4 -> {
decContent1.text = "向左变道"
decContent2.text = "向右变道"
decContent3.text = "车道保持"
gsyVideoPlay(getRawPath(R.raw.zuohuandao))
gsyVideoPlay2(getRawPath(R.raw.youhuandao))
gsyVideoPlay3(getRawPath(R.raw.zhixing))
}
5 -> {
decContent1.text = "车道保持"
decContent2.text = "向左变道绕障"
decContent3.text = "向右变道绕障"
gsyVideoPlay(getRawPath(R.raw.zhixing))
gsyVideoPlay2(getRawPath(R.raw.zuobizhang))
gsyVideoPlay3(getRawPath(R.raw.youbizhang))
}
6 -> {
decContent1.text = "向左变道绕障"
decContent2.text = "向右变道绕障"
decContent3.text = "车道保持"
gsyVideoPlay(getRawPath(R.raw.zuobizhang))
gsyVideoPlay2(getRawPath(R.raw.youbizhang))
gsyVideoPlay3(getRawPath(R.raw.zhixing))
}
7 -> {
decContent1.text = "直行通过路口"
decContent2.text = "左转通过路口"
decContent3.text = "右转通过路口"
gsyVideoPlay(getRawPath(R.raw.zhixing))
gsyVideoPlay2(getRawPath(R.raw.lukouzuozhuan))
gsyVideoPlay3(getRawPath(R.raw.lukouyouzhuan))
}
8 -> {
decContent1.text = "左转通过路口"
decContent2.text = "直行通过路口"
decContent3.text = "右转通过路口"
gsyVideoPlay(getRawPath(R.raw.lukouzuozhuan))
gsyVideoPlay2(getRawPath(R.raw.lukouzhixing))
gsyVideoPlay3(getRawPath(R.raw.lukouyouzhuan))
}
9 -> {
decContent1.text = "左转通过路口"
decContent2.text = "右转通过路口"
decContent3.text = "直行通过路口"
gsyVideoPlay(getRawPath(R.raw.lukouzuozhuan))
gsyVideoPlay2(getRawPath(R.raw.lukouyouzhuan))
gsyVideoPlay3(getRawPath(R.raw.lukouzhixing))
}
}
}
private fun initViews() {
}
private fun initVideos() {
val list: MutableList<VideoOptionModel> = ArrayList()
list.add(VideoOptionModel(IjkMediaPlayer.OPT_CATEGORY_PLAYER, "reconnect", 3))
GSYVideoManager.instance().optionModelList = list
GSYVideoType.setShowType(GSYVideoType.SCREEN_MATCH_FULL)
GSYVideoType.setRenderType(GSYVideoType.TEXTURE)
PlayerFactory.setPlayManager(IjkPlayerManager::class.java)
}
private fun gsyVideoPlay(flvUrl: String) {
if (flvUrl == lastUrl1) return
lastUrl1 = flvUrl
gsyVideoOptionBuilder1.setUrl(flvUrl)
.setCacheWithPlay(false)
.setAutoFullWithSize(false)
.setIsTouchWigetFull(false)
.setIsTouchWiget(false)
.setLooping(true)
.setPlayTag(TAG)
.setPlayPosition(0)
.build(preDetailView2)
preDetailView2.startPlayLogic()
}
private fun gsyVideoPlay2(flvUrl: String) {
if (flvUrl == lastUrl2) return
lastUrl2 = flvUrl
gsyVideoOptionBuilder2.setUrl(flvUrl)
.setCacheWithPlay(false)
.setAutoFullWithSize(false)
.setIsTouchWigetFull(false)
.setIsTouchWiget(false)
.setLooping(true)
.setPlayTag(TAG)
.setPlayPosition(1)
.build(decMapView)
decMapView.startButton.performClick()
}
private fun gsyVideoPlay3(flvUrl: String) {
if (flvUrl == lastUrl3) return
lastUrl3 = flvUrl
gsyVideoOptionBuilder3.setUrl(flvUrl)
.setCacheWithPlay(false)
.setAutoFullWithSize(false)
.setIsTouchWigetFull(false)
.setLooping(true)
.setIsTouchWiget(false)
.setPlayTag(TAG)
.setPlayPosition(2)
.build(preDetailView3)
preDetailView3.startButton.performClick()
}
private fun getRawPath(resId: Int): String {
return "android.resource://${context.packageName}/$resId"
}
} }

View File

@@ -0,0 +1,136 @@
<?xml version="1.0" encoding="utf-8"?>
<merge xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:parentTag="androidx.constraintlayout.widget.ConstraintLayout">
<com.mogo.eagle.core.widget.media.video.MultiVideoPlayer
android:id="@+id/preDetailView2"
android:layout_width="238dp"
android:layout_height="458dp"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintBottom_toBottomOf="parent"
android:layout_marginStart="@dimen/dp_27"
android:layout_marginBottom="24dp"
/>
<com.mogo.eagle.core.widget.media.video.MultiVideoPlayer
android:id="@+id/decMapView"
android:layout_width="238dp"
android:layout_height="458dp"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintBottom_toBottomOf="parent"
android:layout_marginBottom="24dp"
app:map_index="1"
/>
<com.mogo.eagle.core.widget.media.video.MultiVideoPlayer
android:id="@+id/preDetailView3"
android:layout_width="238dp"
android:layout_height="458dp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintBottom_toBottomOf="parent"
android:layout_marginEnd="@dimen/dp_27"
android:layout_marginBottom="20dp"
app:map_index="2"
/>
<TextView
android:id="@+id/tvDecTitle"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="AI Decision-making"
android:textColor="#394047"
android:textSize="32dp"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="parent"
android:layout_marginTop="@dimen/dp_28"
/>
<TextView
android:id="@+id/tvPre1"
android:layout_width="62dp"
android:layout_height="wrap_content"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
android:gravity="center"
android:layout_marginStart="@dimen/dp_116"
android:layout_marginTop="@dimen/dp_70"
tools:text="11%"
android:textColor="#63707D"
android:textSize="33dp"
/>
<TextView
android:id="@+id/tvPre2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="parent"
android:layout_marginTop="@dimen/dp_70"
tools:text="86%"
android:textColor="#2EACFF"
android:textSize="33dp"
/>
<TextView
android:id="@+id/tvPre3"
android:layout_width="62dp"
android:layout_height="wrap_content"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="parent"
android:layout_marginEnd="@dimen/dp_116"
android:layout_marginTop="@dimen/dp_70"
android:gravity="center"
tools:text="3%"
android:textColor="#63707D"
android:textSize="33dp"
/>
<TextView
android:id="@+id/decContent1"
android:layout_width="156dp"
android:layout_height="wrap_content"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
android:layout_marginStart="@dimen/dp_68"
android:layout_marginTop="@dimen/dp_112"
android:gravity="center"
tools:text="向左变道绕障"
android:textColor="#63707D"
android:textSize="26dp"
/>
<TextView
android:id="@+id/decContent2"
android:layout_width="156dp"
android:layout_height="wrap_content"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="parent"
android:layout_marginTop="@dimen/dp_112"
android:gravity="center"
tools:text="向右变道绕障"
android:textColor="#2EACFF"
android:textSize="26dp"
/>
<TextView
android:id="@+id/decContent3"
android:layout_width="156dp"
android:layout_height="wrap_content"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="parent"
android:layout_marginEnd="@dimen/dp_68"
android:layout_marginTop="@dimen/dp_112"
android:gravity="center"
tools:text="直行"
android:textColor="#63707D"
android:textSize="26dp"
/>
</merge>

View File

@@ -84,7 +84,7 @@
<declare-styleable name="CarMapLayout"> <declare-styleable name="CarMapLayout">
<attr name="car_type" format="enum" > <attr name="car_type" format="enum" >
<enum name="Taxi" value="0" /> <enum name="Taxi" value="0" />
<enum name="B2" value="1" /> /> <enum name="B2" value="1" />
</attr> </attr>
</declare-styleable> </declare-styleable>
</resources> </resources>

View File

@@ -0,0 +1,183 @@
package com.mogo.eagle.core.widget.media.video
import android.app.Activity
import android.content.Context
import android.text.TextUtils
import android.view.View
import android.view.ViewGroup
import android.view.Window
import com.mogo.eagle.core.widget.R
import com.shuyu.gsyvideoplayer.GSYVideoBaseManager
import com.shuyu.gsyvideoplayer.player.IPlayerManager
import com.shuyu.gsyvideoplayer.player.IjkPlayerManager
import com.shuyu.gsyvideoplayer.utils.CommonUtil
import com.shuyu.gsyvideoplayer.video.base.GSYVideoPlayer
/**
* 多个播放的管理器
* Created by guoshuyu on 2018/1/31.
*/
class CustomManager : GSYVideoBaseManager() {
init {
init()
}
override fun getPlayManager(): IPlayerManager {
return IjkPlayerManager()
}
/**
* 暂停播放
*/
fun onPause(key: String?) {
if (getCustomManager(key).listener() != null) {
getCustomManager(key).listener().onVideoPause()
}
}
/**
* 恢复播放
*/
fun onResume(key: String?) {
if (getCustomManager(key).listener() != null) {
getCustomManager(key).listener().onVideoResume()
}
}
/**
* 恢复暂停状态
*
* @param seek 是否产生seek动作,直播设置为false
*/
fun onResume(key: String?, seek: Boolean) {
if (getCustomManager(key).listener() != null) {
getCustomManager(key).listener().onVideoResume(seek)
}
}
companion object {
val SMALL_ID: Int = R.id.custom_small_id
val FULLSCREEN_ID: Int = R.id.custom_full_id
var TAG: String = "GSYVideoManager"
private val sMap: MutableMap<String, CustomManager> = HashMap()
/**
* 退出全屏,主要用于返回键
*
* @return 返回是否全屏
*/
fun backFromWindowFull(context: Context?, key: String?): Boolean {
var backFrom = false
val vp =
CommonUtil.scanForActivity(context)
.findViewById<View>(Window.ID_ANDROID_CONTENT) as ViewGroup
val oldF = vp.findViewById<View>(FULLSCREEN_ID)
if (oldF != null) {
backFrom = true
CommonUtil.hideNavKey(context)
if (getCustomManager(key).lastListener() != null) {
getCustomManager(key).lastListener().onBackFullscreen()
}
}
return backFrom
}
/**
* 页面销毁了记得调用是否所有的video
*/
fun releaseAllVideos(key: String?) {
if (getCustomManager(key).listener() != null) {
getCustomManager(key).listener().onCompletion()
}
getCustomManager(key).releaseMediaPlayer()
}
/**
* 单例管理器
*/
@Synchronized
fun instance(): Map<String, CustomManager> {
return sMap
}
/**
* 单例管理器
*/
@Synchronized
fun getCustomManager(key: String?): CustomManager {
check(key != null && !TextUtils.isEmpty(key)) { "key not be empty" }
var customManager: CustomManager? = sMap[key]
if (customManager == null) {
customManager = CustomManager()
sMap[key] = customManager
}
return customManager
}
fun onPauseAll() {
if (sMap.isNotEmpty()) {
for ((key, value) in sMap.entries) {
value.onPause(key)
}
}
}
fun onResumeAll() {
if (sMap.isNotEmpty()) {
for ((key, value) in sMap.entries) {
value.onResume(key)
}
}
}
/**
* 恢复暂停状态
*
* @param seek 是否产生seek动作
*/
fun onResumeAll(seek: Boolean) {
if (sMap.isNotEmpty()) {
for ((key, value) in sMap.entries) {
value.onResume(key, seek)
}
}
}
fun clearAllVideo() {
if (sMap.isNotEmpty()) {
for ((key) in sMap.entries) {
releaseAllVideos(key)
}
}
sMap.clear()
}
fun removeManager(key: String?) {
sMap.remove(key)
}
/**
* 当前是否全屏状态
*
* @return 当前是否全屏状态, true代表是。
*/
fun isFullState(activity: Activity?): Boolean {
val vp =
CommonUtil.scanForActivity(activity)
.findViewById<View>(Window.ID_ANDROID_CONTENT) as ViewGroup
val full = vp.findViewById<View>(FULLSCREEN_ID)
var gsyVideoPlayer: GSYVideoPlayer? = null
if (full != null) {
gsyVideoPlayer = full as GSYVideoPlayer
}
return gsyVideoPlayer != null
}
}
}

View File

@@ -0,0 +1,205 @@
package com.mogo.eagle.core.widget.media.video
import android.content.Context
import android.graphics.Point
import android.media.AudioManager
import android.media.AudioManager.OnAudioFocusChangeListener
import android.text.TextUtils
import android.util.AttributeSet
import android.view.MotionEvent
import android.view.Surface
import android.view.View
import android.widget.ImageView
import com.mogo.eagle.core.widget.R
import com.shuyu.gsyvideoplayer.utils.Debuger
import com.shuyu.gsyvideoplayer.utils.GSYVideoType
import com.shuyu.gsyvideoplayer.video.StandardGSYVideoPlayer
import com.shuyu.gsyvideoplayer.video.base.GSYBaseVideoPlayer
import com.shuyu.gsyvideoplayer.video.base.GSYVideoViewBridge
/**
* 多个同时播放的播放控件
*/
class MultiVideoPlayer : StandardGSYVideoPlayer {
private lateinit var start: ImageView
private var mCoverOriginUrl: String? = null
private var mDefaultRes: Int = 0
var enableDoubleClick = false
/**
* 圆角尺寸
*/
var outLinePixel = 0f
constructor(context: Context?, fullFlag: Boolean?) : super(context, fullFlag)
constructor(context: Context?) : super(context)
constructor(context: Context?, attrs: AttributeSet?) : super(context, attrs)
override fun init(context: Context) {
super.init(context)
start = findViewById(R.id.start)
if (mThumbImageViewLayout != null &&
(mCurrentState == -1 || mCurrentState == CURRENT_STATE_NORMAL || mCurrentState == CURRENT_STATE_ERROR)
) {
mThumbImageViewLayout.visibility = VISIBLE
}
onAudioFocusChangeListener =
OnAudioFocusChangeListener { focusChange ->
when (focusChange) {
AudioManager.AUDIOFOCUS_GAIN -> {}
AudioManager.AUDIOFOCUS_LOSS -> {}
AudioManager.AUDIOFOCUS_LOSS_TRANSIENT -> {}
AudioManager.AUDIOFOCUS_LOSS_TRANSIENT_CAN_DUCK -> {}
}
}
}
override fun getGSYVideoManager(): GSYVideoViewBridge {
CustomManager.getCustomManager(key).initContext(context.applicationContext)
return CustomManager.getCustomManager(key)
}
override fun backFromFull(context: Context): Boolean {
return CustomManager.backFromWindowFull(context, key)
}
override fun releaseVideos() {
CustomManager.releaseAllVideos(key)
}
override fun getFullId(): Int {
return CustomManager.FULLSCREEN_ID
}
override fun getSmallId(): Int {
return CustomManager.SMALL_ID
}
override fun getLayoutId(): Int {
return R.layout.item_v2x_crossroad_live_video
}
override fun startWindowFullscreen(
context: Context,
actionBar: Boolean,
statusBar: Boolean
): GSYBaseVideoPlayer {
return super.startWindowFullscreen(context, actionBar, statusBar)
}
override fun changeUiToCompleteShow() {
super.changeUiToCompleteShow()
mBottomContainer?.visibility = View.INVISIBLE
mProgressBar?.visibility = View.GONE
}
override fun hideAllWidget() {
super.hideAllWidget()
mBottomContainer?.visibility = View.INVISIBLE
mProgressBar?.visibility = View.GONE
}
override fun changeUiToPrepareingClear() {
super.changeUiToPrepareingClear()
mBottomContainer?.visibility = View.INVISIBLE
mProgressBar?.visibility = View.GONE
}
override fun changeUiToPlayingBufferingClear() {
super.changeUiToPlayingBufferingClear()
mBottomContainer?.visibility = View.INVISIBLE
mProgressBar?.visibility = View.GONE
}
override fun changeUiToClear() {
super.changeUiToClear()
mBottomContainer?.visibility = View.INVISIBLE
mProgressBar?.visibility = View.GONE
}
override fun changeUiToCompleteClear() {
super.changeUiToCompleteClear()
mBottomContainer?.visibility = View.INVISIBLE
mProgressBar?.visibility = View.GONE
}
override fun showWifiDialog() {
//直接播放不显示WIFI对话框
startPlayLogic()
}
override fun updateStartImage() {
// do nothing
// 不显示暂停、开始等按钮
}
override fun onSurfaceUpdated(surface: Surface?) {
super.onSurfaceUpdated(surface)
if (mThumbImageViewLayout != null && mThumbImageViewLayout.visibility == View.VISIBLE) {
mThumbImageViewLayout.visibility = View.INVISIBLE
}
}
override fun onSurfaceAvailable(surface: Surface?) {
super.onSurfaceAvailable(surface)
mProgressBar?.visibility = View.GONE
if (GSYVideoType.getRenderType() != GSYVideoType.TEXTURE) {
if (mThumbImageViewLayout != null && mThumbImageViewLayout.visibility == View.VISIBLE) {
mThumbImageViewLayout.visibility = View.INVISIBLE
}
}
}
override fun touchDoubleUp(e: MotionEvent?) {
if (enableDoubleClick) {
super.touchDoubleUp(e)
}
}
override fun setViewShowState(view: View?, visibility: Int) {
if (view === mThumbImageViewLayout && visibility != View.VISIBLE) {
return
}
super.setViewShowState(view, visibility)
}
override fun showSmallVideo(
size: Point,
actionBar: Boolean,
statusBar: Boolean
): GSYBaseVideoPlayer {
//下面这里替换成你自己的强制转化
val multiSampleVideo = super.showSmallVideo(size, actionBar, statusBar) as MultiVideoPlayer
multiSampleVideo.mStartButton.visibility = GONE
multiSampleVideo.mStartButton = null
return multiSampleVideo
}
override fun onSizeChanged(w: Int, h: Int, oldw: Int, oldh: Int) {
super.onSizeChanged(w, h, oldw, oldh)
if (!mIfCurrentIsFullscreen && outLinePixel > 0) {
this.outlineProvider = TextureVideoViewOutlineProvider(outLinePixel)
this.clipToOutline = true
}
}
val key: String
get() {
if (mPlayPosition == -22) {
Debuger.printfError(javaClass.simpleName + " used getKey() " + "******* PlayPosition never set. ********")
}
if (TextUtils.isEmpty(mPlayTag)) {
Debuger.printfError(javaClass.simpleName + " used getKey() " + "******* PlayTag never set. ********")
}
return TAG + mPlayPosition + mPlayTag
}
companion object {
private const val TAG = "MultiSampleVideo"
}
}

View File

@@ -8,4 +8,6 @@
<item name="id_operate_panel" type="id" /> <item name="id_operate_panel" type="id" />
<item name="vs_operate_panel" type="id" /> <item name="vs_operate_panel" type="id" />
<item name="operate_panel_header_last_selected" type="id" /> <item name="operate_panel_header_last_selected" type="id" />
<item name="custom_full_id" type="id" />
<item name="custom_small_id" type="id" />
</resources> </resources>

View File

@@ -83,8 +83,8 @@ MOGO_TELEMATIC_VERSION=1.4.7.65
MOGO_SKIN_VERSION=1.4.7.50 MOGO_SKIN_VERSION=1.4.7.50
######## MogoAiCloudSDK Version ######## ######## MogoAiCloudSDK Version ########
# 自研地图 # 自研地图
MAP_SDK_VERSION=multi-3.5.0.4 MAP_SDK_VERSION=multi-3.5.0.6
MAP_SDK_CORE_VERSION=multi-3.5.0.4 MAP_SDK_CORE_VERSION=multi-3.5.0.5
MAP_SDK_DATA_VERSION=1.0.0.9 MAP_SDK_DATA_VERSION=1.0.0.9
MAP_SDK_OPERATION_VERSION=1.1.4.1 MAP_SDK_OPERATION_VERSION=1.1.4.1
# websocket # websocket

View File

@@ -80,4 +80,6 @@ interface IMogoMap {
fun toScreenLocations(data: List<LonLatPoint>): List<android.graphics.Point> fun toScreenLocations(data: List<LonLatPoint>): List<android.graphics.Point>
fun toScreenLocation(lon: Double, lat: Double): android.graphics.Point? fun toScreenLocation(lon: Double, lat: Double): android.graphics.Point?
fun isInCurrentFrame(lon: Double, lat: Double): Boolean
} }

View File

@@ -268,4 +268,8 @@ class AMapWrapper(map: MapAutoViewHelper?, mapView: MapAutoView, controller: IMo
} }
} }
} }
override fun isInCurrentFrame(lon: Double, lat: Double): Boolean {
return mMapView.getMapController()?.isInCurrentFrame(lon, lat) ?: false
}
} }