[8.0.0]自动探查进MogoMind

This commit is contained in:
xuxinchao
2025-05-06 18:03:34 +08:00
parent b2bd10127a
commit 81c480cf00
7 changed files with 283 additions and 4 deletions

View File

@@ -50,6 +50,7 @@ class AiView @JvmOverloads constructor(
private var pncActionsModel:PNCActionsViewModel ?= null
private var roadV2NEventModel:RoadV2NEventViewModel ?= null
private var roadCrossRoamModel:RoadCrossRoamViewModel ?= null
private var automaticExplorationModel:AutomaticExplorationViewModel ?= null
private var aiAnimator: BigFrameAnimatorContainer?=null
private var aiAnimatorBg: BigFrameAnimatorContainer?=null
@@ -235,6 +236,10 @@ class AiView @JvmOverloads constructor(
ViewModelProvider(it)[RoadCrossRoamViewModel::class.java]
}
roadCrossRoamModel?.init(context)
automaticExplorationModel = findViewTreeViewModelStoreOwner()?.let{
ViewModelProvider(it)[AutomaticExplorationViewModel::class.java]
}
automaticExplorationModel?.init()
}
private fun startListInfo(){

View File

@@ -0,0 +1,144 @@
package com.mogo.och.unmanned.passenger.ui.aiview
import android.os.CountDownTimer
import androidx.lifecycle.ViewModel
import com.mogo.eagle.core.data.msgbox.MsgBoxBean
import com.mogo.eagle.core.data.msgbox.MsgBoxType
import com.mogo.eagle.core.data.msgbox.MsgCategory
import com.mogo.eagle.core.function.api.datacenter.msgbox.IMsgBoxListener
import com.mogo.eagle.core.function.call.msgbox.CallerMsgBoxListenerManager
import com.mogo.eagle.core.utilcode.util.ThreadUtils
import com.mogo.och.data.taxi.BaseOrderBean
import com.mogo.och.data.taxi.TaxiOrderStatusEnum
import com.mogo.och.unmanned.passenger.ui.aiview.bean.AIMessage
import com.mogo.och.unmanned.taxi.utils.order.OrderListener
import com.mogo.och.unmanned.taxi.utils.order.OrderModel
/**
* 自动探查
*/
class AutomaticExplorationViewModel: ViewModel(), OrderListener, IMsgBoxListener {
companion object{
private const val TAG = "AutomaticExplorationViewModel"
private const val EXPLORATION_SHOW_TIME = 300000L //距离用户在触发上一次事件播报的时间5分钟后自动触发常规道路情况检测
}
private var showViewTimer: CountDownTimer?= null //展示自动探查倒计时
private var isCountingDown: Boolean = false //是否处于倒计时中
private var hasOrder: Boolean = false // 车当前是否有订单
fun init(){
OrderModel.setOrderStatusCallback(TAG,this)
CallerMsgBoxListenerManager.addListener(TAG,this)
}
override fun onCurrentOrderStatusChanged(order: BaseOrderBean?) {
if(order==null){
cancelTimer()
currentOrderStatus(false)
}else {
when (order.orderStatus) {
TaxiOrderStatusEnum.None.code -> {
cancelTimer()
currentOrderStatus(false)
}
TaxiOrderStatusEnum.OnTheWayToStart.code -> {
startShowTimer()
currentOrderStatus(true)
}
TaxiOrderStatusEnum.ArriveAtStart.code -> {
startShowTimer()
currentOrderStatus(true)
}
TaxiOrderStatusEnum.UserArriveAtStart.code -> {
startShowTimer()
currentOrderStatus(true)
}
TaxiOrderStatusEnum.OnTheWayToEnd.code -> {
startShowTimer()
currentOrderStatus(true)
}
TaxiOrderStatusEnum.ArriveAtEnd.code -> {
startShowTimer()
currentOrderStatus(true)
}
TaxiOrderStatusEnum.JourneyCompleted.code -> {
cancelTimer()
currentOrderStatus(false)
}
TaxiOrderStatusEnum.Cancel.code -> {
cancelTimer()
currentOrderStatus(false)
}
else -> {
cancelTimer()
currentOrderStatus(false)
}
}
}
}
override fun onDataChanged(category: MsgCategory, msgBoxList: MsgBoxBean) {
if(category == MsgCategory.NOTICE){
if(msgBoxList.type == MsgBoxType.V2X){
//重置倒计时时长
cancelTimer()
if(hasOrder){
startShowTimer()
}
}
}
}
/**
* 取消倒计时
*/
private fun cancelTimer(){
showViewTimer?.cancel()
showViewTimer = null
isCountingDown = false
}
/**
* 开始倒计时
*/
private fun startShowTimer(){
if(!isCountingDown){
ThreadUtils.runOnUiThread {
if(showViewTimer == null){
showViewTimer = object: CountDownTimer(EXPLORATION_SHOW_TIME,EXPLORATION_SHOW_TIME){
override fun onTick(millisUntilFinished: Long) {
}
override fun onFinish() {
if(hasOrder){
showAutoExploration()
}
isCountingDown = false
}
}
}
isCountingDown = true
showViewTimer?.start()
}
}
}
/**
* 设置当前订单状态
* @param orderStatus true有订单false没有订单
*/
private fun currentOrderStatus(orderStatus: Boolean){
hasOrder = orderStatus
}
private fun showAutoExploration(){
val automaticExploration = AIMessage.AutomaticExploration(System.currentTimeMillis().toString(),"")
AIMessageManager.post(automaticExploration)
}
}

View File

@@ -22,7 +22,8 @@ class AIMessageAdapter : ListAdapter<AIMessage, MessageViewHolder>(MessageDiffCa
AIMessage.TYPE_QA -> QAViewHolder(inflater.inflate(R.layout.item_ai_msg_qa, parent, false))
AIMessage.TYPE_PNC_ACTION -> PNCActionViewHolder(inflater.inflate(R.layout.item_ai_pnc_action,parent,false))
AIMessage.TYPE_ROAD_V2N -> RoadV2NEventViewHolder(inflater.inflate(R.layout.item_ai_road_v2n_event,parent,false))
AIMessage.TYPE_ROAD_CROSS ->RoadCrossRoamViewHolder(inflater.inflate(R.layout.item_ai_road_cross_roam,parent,false))
AIMessage.TYPE_ROAD_CROSS -> RoadCrossRoamViewHolder(inflater.inflate(R.layout.item_ai_road_cross_roam,parent,false))
AIMessage.TYPE_AUTOMATIC_EXPLORATION -> AutomaticExplorationViewHolder(inflater.inflate(R.layout.item_ai_automatic_exploration,parent,false))
else -> throw IllegalArgumentException("Invalid view type")
}
}
@@ -38,6 +39,7 @@ class AIMessageAdapter : ListAdapter<AIMessage, MessageViewHolder>(MessageDiffCa
is AIMessage.PNCAction -> AIMessage.TYPE_PNC_ACTION
is AIMessage.RoadV2NEvent -> AIMessage.TYPE_ROAD_V2N
is AIMessage.RoadCrossRoam -> AIMessage.TYPE_ROAD_CROSS
is AIMessage.AutomaticExploration -> AIMessage.TYPE_AUTOMATIC_EXPLORATION
else -> AIMessage.TYPE_EVENT
}
}

View File

@@ -4,6 +4,7 @@ import android.animation.ObjectAnimator
import android.animation.ValueAnimator
import android.content.Context
import android.graphics.Rect
import android.os.CountDownTimer
import android.text.TextUtils
import android.util.Log
import android.view.LayoutInflater
@@ -22,14 +23,17 @@ import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.RecyclerView
import com.bumptech.glide.Glide
import com.mogo.commons.voice.AIAssist
import com.mogo.eagle.core.data.notice.AutoExplorationEntity
import com.mogo.eagle.core.data.v2x.RoadV2NEventType
import com.mogo.eagle.core.function.call.autopilot.CallerChassisLocationWGS84ListenerManager
import com.mogo.eagle.core.function.hmi.ui.notice.exploration.AutomaticExplorationAdapter
import com.mogo.eagle.core.function.hmi.ui.v2n.RoadV2NEventLivePlayView
import com.mogo.eagle.core.function.view.MapRoamView
import com.mogo.eagle.core.function.view.RoadCrossRoamListAdapter
import com.mogo.eagle.core.utilcode.mogo.glide.GlideImageLoader
import com.mogo.eagle.core.utilcode.mogo.imageloader.MogoImageView
import com.mogo.eagle.core.utilcode.util.DateTimeUtils
import com.mogo.eagle.core.utilcode.util.ThreadUtils
import com.mogo.eagle.core.widget.RoundConstraintLayout
import com.mogo.och.common.module.wigets.OchRoundImageView
import com.mogo.och.unmanned.passenger.ui.aiview.bean.AIMessage
@@ -244,11 +248,9 @@ class RoadV2NEventViewHolder(binding: View) : MessageViewHolder(binding){
class RoadCrossRoamViewHolder(binding: View) : MessageViewHolder(binding){
private var ivZhiRoadRoamSet: ImageView = binding.findViewById(R.id.ivZhiRoadRoamSet)
private var ivZhiRoadRoamView: ImageView = binding.findViewById(R.id.ivZhiRoadRoamView)
private var tvRoadRoamTitle: TextView = binding.findViewById(R.id.tvRoadRoamTitle)
private var mapRoamView: MapRoamView = binding.findViewById(R.id.mapRoamView)
private var clScanningBg: ConstraintLayout = binding.findViewById(R.id.clScanningBg)
private var ivCoverRoam: ImageView = binding.findViewById(R.id.ivCoverRoam)
private var lvRoadCrossRoamTip: RecyclerView = binding.findViewById(R.id.lvRoadCrossRoamTip)
@@ -293,6 +295,63 @@ class RoadCrossRoamViewHolder(binding: View) : MessageViewHolder(binding){
}
class AutomaticExplorationViewHolder(binding: View) : MessageViewHolder(binding){
private var ivScan: ImageView = binding.findViewById(R.id.ivScan)
private var rvExplorationList: RecyclerView = binding.findViewById(R.id.rvExplorationList)
private lateinit var automaticExplorationAdapter: AutomaticExplorationAdapter
private var rotationAnim: ObjectAnimator ?= null
override fun bind(item: AIMessage, onItemClickListener: OnItemClickListener?) {
val linearLayoutManager = LinearLayoutManager(itemView.context)
linearLayoutManager.orientation = LinearLayoutManager.VERTICAL
automaticExplorationAdapter = AutomaticExplorationAdapter(itemView.context,1)
rvExplorationList.adapter = automaticExplorationAdapter
rvExplorationList.layoutManager = linearLayoutManager
initData()
}
private fun initData() {
val dataList = ArrayList<AutoExplorationEntity>(7)
dataList.add(AutoExplorationEntity("当前道路事件分析",2000L,false))
dataList.add(AutoExplorationEntity("前方车辆",2000L,false))
dataList.add(AutoExplorationEntity("两侧车辆",2600L,false))
dataList.add(AutoExplorationEntity("后方车辆",3000L,false))
dataList.add(AutoExplorationEntity("前方路口车辆流速分析",4000L,false))
dataList.add(AutoExplorationEntity("前方路口行人/非机动车分析",4300L,false))
dataList.add(AutoExplorationEntity("路侧视频分析",5000L,false))
automaticExplorationAdapter.setListener(object: AutomaticExplorationAdapter.CompleteListener{
override fun onComplete(entity: AutoExplorationEntity) {
var allComplete = true //所有探查项目都探查完毕
dataList.forEach {
if(it.explorationContent == entity.explorationContent){
it.explorationComplete = true
}
if(!it.explorationComplete){
allComplete = false
}
}
if(allComplete){
//停止左上角扫描动画
rotationAnim?.cancel()
}
}
})
automaticExplorationAdapter.setData(dataList)
//启动扫描
ivScan.let {
rotationAnim = ObjectAnimator.ofFloat(it, "rotation", 0f, 360f)
rotationAnim?.repeatCount = ValueAnimator.INFINITE
rotationAnim?.repeatMode = ValueAnimator.RESTART
rotationAnim?.duration = 2000
rotationAnim?.interpolator = LinearInterpolator()
rotationAnim?.start()
}
}
}
private class NoScrollLayoutManager(context: Context?) : LinearLayoutManager(context) {
override fun canScrollVertically(): Boolean {
return false

View File

@@ -24,6 +24,7 @@ sealed class AIMessage(
const val TYPE_PNC_ACTION = 6
const val TYPE_ROAD_V2N = 7
const val TYPE_ROAD_CROSS = 8
const val TYPE_AUTOMATIC_EXPLORATION = 9
}
data class Scan(
@@ -154,4 +155,9 @@ sealed class AIMessage(
override val title: String
): AIMessage(id,title)
data class AutomaticExploration(
override val id: String,
override val title: String
): AIMessage(id,title)
}

View File

@@ -0,0 +1,63 @@
<?xml version="1.0" encoding="utf-8"?>
<com.mogo.och.common.module.wigets.OCHBorderShadowLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="@dimen/dp_799"
android:layout_height="@dimen/dp_582"
app:shadowRadius="@dimen/dp_20"
app:shadowColor="#26666666"
app:xOffset="0dp"
app:yOffset="0dp"
app:blurRadius="@dimen/dp_26">
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<ImageView
android:id="@+id/ivScan"
android:layout_width="@dimen/dp_67"
android:layout_height="@dimen/dp_67"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
android:src="@drawable/icon_scan"
android:contentDescription="@string/exploration_scan"
android:layout_marginTop="@dimen/dp_32"
android:layout_marginStart="@dimen/dp_32"
/>
<ImageView
android:layout_width="@dimen/dp_50"
android:layout_height="@dimen/dp_50"
app:layout_constraintTop_toTopOf="@id/ivScan"
app:layout_constraintBottom_toBottomOf="@id/ivScan"
app:layout_constraintLeft_toLeftOf="@id/ivScan"
app:layout_constraintRight_toRightOf="@id/ivScan"
android:src="@drawable/icon_vehicle_lane"
android:contentDescription="@string/exploration_vehicle_lane"
/>
<TextView
android:id="@+id/tvExplorationTitle"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:layout_constraintTop_toTopOf="@id/ivScan"
app:layout_constraintBottom_toBottomOf="@id/ivScan"
app:layout_constraintStart_toEndOf="@id/ivScan"
android:textSize="@dimen/sp_32"
android:textColor="@color/color_131415"
android:text="@string/exploration_title"
android:layout_marginStart="@dimen/dp_23"
/>
<androidx.recyclerview.widget.RecyclerView
android:id="@id/rvExplorationList"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:layout_constraintTop_toBottomOf="@id/tvExplorationTitle"
app:layout_constraintLeft_toLeftOf="@id/tvExplorationTitle"
android:layout_marginTop="@dimen/dp_14"
/>
</androidx.constraintlayout.widget.ConstraintLayout>
</com.mogo.och.common.module.wigets.OCHBorderShadowLayout>

View File

@@ -21,7 +21,7 @@
android:id="@+id/tvExplorationContent"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="@dimen/sp_22"
android:textSize="@dimen/sp_26"
android:textColor="@color/auto_exploration_content_p"
android:layout_marginStart="@dimen/dp_13"
android:layout_gravity="center_vertical"