From 81c480cf005c9eca876e1702603c86e1016f5c09 Mon Sep 17 00:00:00 2001 From: xuxinchao Date: Tue, 6 May 2025 18:03:34 +0800 Subject: [PATCH] =?UTF-8?q?[8.0.0]=E8=87=AA=E5=8A=A8=E6=8E=A2=E6=9F=A5?= =?UTF-8?q?=E8=BF=9BMogoMind?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../unmanned/passenger/ui/aiview/AiView.kt | 5 + .../aiview/AutomaticExplorationViewModel.kt | 144 ++++++++++++++++++ .../ui/aiview/adapter/AIMessageAdapter.kt | 4 +- .../ui/aiview/adapter/AIMessageViewHolder.kt | 63 +++++++- .../ui/aiview/bean/AssistantMessage.kt | 6 + .../layout/item_ai_automatic_exploration.xml | 63 ++++++++ .../res/layout/item_auto_exploration_p.xml | 2 +- 7 files changed, 283 insertions(+), 4 deletions(-) create mode 100644 OCH/taxi/unmanned-passenger/src/main/java/com/mogo/och/unmanned/passenger/ui/aiview/AutomaticExplorationViewModel.kt create mode 100644 OCH/taxi/unmanned-passenger/src/main/res/layout/item_ai_automatic_exploration.xml diff --git a/OCH/taxi/unmanned-passenger/src/main/java/com/mogo/och/unmanned/passenger/ui/aiview/AiView.kt b/OCH/taxi/unmanned-passenger/src/main/java/com/mogo/och/unmanned/passenger/ui/aiview/AiView.kt index f1f18053bd..1087c5a359 100644 --- a/OCH/taxi/unmanned-passenger/src/main/java/com/mogo/och/unmanned/passenger/ui/aiview/AiView.kt +++ b/OCH/taxi/unmanned-passenger/src/main/java/com/mogo/och/unmanned/passenger/ui/aiview/AiView.kt @@ -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(){ diff --git a/OCH/taxi/unmanned-passenger/src/main/java/com/mogo/och/unmanned/passenger/ui/aiview/AutomaticExplorationViewModel.kt b/OCH/taxi/unmanned-passenger/src/main/java/com/mogo/och/unmanned/passenger/ui/aiview/AutomaticExplorationViewModel.kt new file mode 100644 index 0000000000..0f35b4c1f0 --- /dev/null +++ b/OCH/taxi/unmanned-passenger/src/main/java/com/mogo/och/unmanned/passenger/ui/aiview/AutomaticExplorationViewModel.kt @@ -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) + } + +} \ No newline at end of file diff --git a/OCH/taxi/unmanned-passenger/src/main/java/com/mogo/och/unmanned/passenger/ui/aiview/adapter/AIMessageAdapter.kt b/OCH/taxi/unmanned-passenger/src/main/java/com/mogo/och/unmanned/passenger/ui/aiview/adapter/AIMessageAdapter.kt index 5655944627..40d5794339 100644 --- a/OCH/taxi/unmanned-passenger/src/main/java/com/mogo/och/unmanned/passenger/ui/aiview/adapter/AIMessageAdapter.kt +++ b/OCH/taxi/unmanned-passenger/src/main/java/com/mogo/och/unmanned/passenger/ui/aiview/adapter/AIMessageAdapter.kt @@ -22,7 +22,8 @@ class AIMessageAdapter : ListAdapter(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(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 } } diff --git a/OCH/taxi/unmanned-passenger/src/main/java/com/mogo/och/unmanned/passenger/ui/aiview/adapter/AIMessageViewHolder.kt b/OCH/taxi/unmanned-passenger/src/main/java/com/mogo/och/unmanned/passenger/ui/aiview/adapter/AIMessageViewHolder.kt index ccd78303db..efcdf5b179 100644 --- a/OCH/taxi/unmanned-passenger/src/main/java/com/mogo/och/unmanned/passenger/ui/aiview/adapter/AIMessageViewHolder.kt +++ b/OCH/taxi/unmanned-passenger/src/main/java/com/mogo/och/unmanned/passenger/ui/aiview/adapter/AIMessageViewHolder.kt @@ -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(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 diff --git a/OCH/taxi/unmanned-passenger/src/main/java/com/mogo/och/unmanned/passenger/ui/aiview/bean/AssistantMessage.kt b/OCH/taxi/unmanned-passenger/src/main/java/com/mogo/och/unmanned/passenger/ui/aiview/bean/AssistantMessage.kt index d1ec4be663..1c72c3c7d9 100644 --- a/OCH/taxi/unmanned-passenger/src/main/java/com/mogo/och/unmanned/passenger/ui/aiview/bean/AssistantMessage.kt +++ b/OCH/taxi/unmanned-passenger/src/main/java/com/mogo/och/unmanned/passenger/ui/aiview/bean/AssistantMessage.kt @@ -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) + } \ No newline at end of file diff --git a/OCH/taxi/unmanned-passenger/src/main/res/layout/item_ai_automatic_exploration.xml b/OCH/taxi/unmanned-passenger/src/main/res/layout/item_ai_automatic_exploration.xml new file mode 100644 index 0000000000..66c0f0e8f7 --- /dev/null +++ b/OCH/taxi/unmanned-passenger/src/main/res/layout/item_ai_automatic_exploration.xml @@ -0,0 +1,63 @@ + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/core/function-impl/mogo-core-function-hmi/src/main/res/layout/item_auto_exploration_p.xml b/core/function-impl/mogo-core-function-hmi/src/main/res/layout/item_auto_exploration_p.xml index 120efa9776..675d31bf7e 100644 --- a/core/function-impl/mogo-core-function-hmi/src/main/res/layout/item_auto_exploration_p.xml +++ b/core/function-impl/mogo-core-function-hmi/src/main/res/layout/item_auto_exploration_p.xml @@ -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"