[6.1.0] 刹车/平行驾驶介入, 自动启动自驾、任务状态流转逻辑处理

This commit is contained in:
wangmingjun
2023-09-18 18:01:50 +08:00
parent 174b2db510
commit d03481e391
11 changed files with 389 additions and 29 deletions

View File

@@ -0,0 +1,148 @@
package com.mogo.och.common.module.wigets
import android.os.CountDownTimer
import android.util.Log
/**
* @author: wangmingjun
* @date: 2023/9/18
* 支持pause的倒计时, 由CountDownTimer实现的
* 注意CountdownTimer的源码start(),pause(),cancel()方法都是用message和handler实现的
* 如果是在子线程中执行要加调用Looper.prepare()及Looper.loop()
* 或者是使用 runOnMainThread 使其在主线程中执行
**/
abstract class CountDownTimerExt(
private var millisInFuture: Long,
/**
* 间隔
*/
private var mInterval: Long
) {
/**
* 倒计时实现类
*/
private var countDownTimer: CountDownTimer? = null
private var isTimerPaused = true
var remainingTime: Long
/**
* @param millisInFutureIn 总时长
* @param interval onTick间隔
*/
init {
remainingTime = millisInFuture
}
fun start() {
startIt(remainingTime, mInterval)
}
fun start(millisInFutureIn: Long, remainingTimeIn: Long, interval: Long) {
millisInFuture = millisInFutureIn
remainingTime = remainingTimeIn
mInterval = interval
start()
}
@Synchronized
fun startIt(millisInFutureIn: Long, interval: Long) {
remainingTime = millisInFutureIn
mInterval = interval
if (millisInFuture > 0L && interval > 0L) {
if (!isTimerPaused) {
// 有运行中的先stop
stop()
}
if (isTimerPaused) {
// 有暂停或未运行的创建CountDownTimer实现, 确保运行在主线程
countDownTimer = object : CountDownTimer(remainingTime, mInterval) {
override fun onFinish() {
onTimerFinish()
stop()
}
override fun onTick(millisUntilFinished: Long) {
// 这里会记录剩余的时长保存到remainingTime, 方便暂停后能再恢复
remainingTime = millisUntilFinished
onTimerTick(millisUntilFinished)
}
}
try {
countDownTimer?.start()
} catch (e: Exception) {
e.printStackTrace()
}
isTimerPaused = false
} else {
Log.d(TAG, "ignore start")
}
} else {
Log.d(TAG, "invalid parameter")
}
}
/**
* 停止
*/
fun stop() {
try {
countDownTimer?.cancel()
} catch (e: Exception) {
e.printStackTrace()
}
isTimerPaused = true
remainingTime = millisInFuture
}
/**
* 暂停
*/
fun pause() {
if (!isTimerPaused) {
try {
countDownTimer?.cancel()
} catch (e: Exception) {
e.printStackTrace()
}
isTimerPaused = true
onTimerPause()
}
}
/**
* 恢复
*/
fun resume() {
if (!isRunning) {
// 通过remainingTime得到剩余的时长
startIt(remainingTime, mInterval)
onTimerResume(remainingTime)
}
}
private val isRunning: Boolean
/**
* 运行中
* @return
*/
get() = !isTimerPaused
/**
* 每次触发倒计时回调
* @param value
*/
abstract fun onTimerTick(value: Long)
/**
* 倒计时完成回调
*/
abstract fun onTimerFinish()
abstract fun onTimerPause()
abstract fun onTimerResume(remainingTime: Long)
companion object {
private const val TAG = "CountDownTimerExt"
}
}

View File

@@ -32,10 +32,13 @@ class StartAutopilotAnimationView @JvmOverloads constructor(
private const val TAG = "StartAutopilotAnimationView"
}
private var startTimer: CountDownTimer? = null
private var startTimer: CountDownTimerExt? = null
private val mContext: Context
private var mTimerListener: AnimationViewTimerListener? = null
private val closeWarningTask: Runnable = Runnable {
//开始倒计时
countDownTimer()
showWarning(DirectionEnum.ALERT_WARNING_NON)
}
@@ -58,17 +61,36 @@ class StartAutopilotAnimationView @JvmOverloads constructor(
super.onAttachedToWindow()
}
fun show(direction: DirectionEnum, time: Long) {
fun show(direction: DirectionEnum, time: Long,listener: AnimationViewTimerListener) {
mTimerListener = listener
//开始倒计时
countDownTimer()
showWarning(direction, time)
}
fun pause(){
pauseWarning()
}
private fun pauseWarning() {
startTimer?.pause()
}
fun resume(){
resumeWarning()
}
private fun resumeWarning() {
startTimer?.resume()
}
fun dismiss(direction: DirectionEnum) {
dismissWarning(direction)
cancelCountdown()
}
fun cancelCountdown(){ //防止内存泄漏
startTimer?.cancel()
startTimer?.stop()
startTimer = null
}
@@ -78,8 +100,6 @@ class StartAutopilotAnimationView @JvmOverloads constructor(
* @see WarningDirectionEnum
*/
private fun showWarning(direction: DirectionEnum, time: Long = ALL_CLOSE_TIMER) {
//开始倒计时
countDownTimer()
// 如果传入的不是关闭显示,则设置倒计时,定时关闭红框警示
if (oldDirection.get() == direction) {
@@ -131,6 +151,26 @@ class StartAutopilotAnimationView @JvmOverloads constructor(
}
}
private fun pauseWarning(direction: DirectionEnum) {
if (direction == DirectionEnum.ALERT_WARNING_NON) {
return
}
removeCallbacks(closeWarningTask)
post {
when (direction) {
DirectionEnum.ALERT_WARNING_TOP -> {
startAutopilotTipImg.visibility = View.VISIBLE
startAutopilotTip.visibility = View.VISIBLE
}
else -> {
CallerLogger.d("$M_HMI$TAG", "Not Support Direction")
}
}
clearAnimation()
this.oldDirection.set(null)
}
}
override fun onDetachedFromWindow() {
super.onDetachedFromWindow()
}
@@ -148,21 +188,37 @@ class StartAutopilotAnimationView @JvmOverloads constructor(
startAutopilotTip.visibility = VISIBLE
startTimer = object : CountDownTimer(ALL_CLOSE_TIMER, 1000L) {// 5倒计时后开启自驾
startTimer = object : CountDownTimerExt(ALL_CLOSE_TIMER, 1000L) {// 5倒计时后开启自驾
@SuppressLint("SetTextI18n")
override fun onTick(millisUntilFinished: Long) {
override fun onTimerTick(value: Long) {
// 倒计时
UiThreadHandler.post {
startAutopilotTip.text = "${(millisUntilFinished/1000).toInt()} 车辆即将自动开启自动驾驶"
startAutopilotTip.text = "${(value/1000).toInt()} 车辆即将自动开启自动驾驶"
}
playDI()
}
override fun onFinish() {
override fun onTimerFinish() {
//倒计时结束了...
UiThreadHandler.post {
startAutopilotTip.text = "车辆正在自动开启自动驾驶"
dismiss(DirectionEnum.ALERT_WARNING_TOP)
}
}
override fun onTimerPause() {
//倒计时暂停
UiThreadHandler.post {
pauseWarning(DirectionEnum.ALERT_WARNING_TOP)
mTimerListener?.onTimerPause()
}
}
override fun onTimerResume(remainingTime: Long) {
//倒计时继续对动画UI处理
UiThreadHandler.post {
showWarning(DirectionEnum.ALERT_WARNING_TOP, remainingTime)
mTimerListener?.onTimerResume(remainingTime)
}
}
}
@@ -170,4 +226,9 @@ class StartAutopilotAnimationView @JvmOverloads constructor(
startTimer?.start()
}
interface AnimationViewTimerListener{
fun onTimerResume(remainingTime: Long)
fun onTimerPause()
}
}

View File

@@ -19,4 +19,7 @@ public interface ITaxiControllerStatusCallback {
//自动开启自动驾驶
void startOpenAutopilotNonManual();
//停止启动自动驾驶
void stopOpenAutopilotNonManual();
}

View File

@@ -11,7 +11,9 @@ interface ITaxiTaskWithOrderCallback {
fun onOrderArriveAtEnd(orderNo: String)
fun onOrderTripInfoChanged(mileage: Float, duration: Int)
fun onOrderJourneyCompleted()
fun onStartAutopilot()
fun onStartAutopilot(postDelayTime: Long)
fun onPauseStartAutopilot()
fun onStopAutopilot()
fun onStartPrepareTaskUI(delayTime: Long, isStart: Boolean)
fun onTaskTripInfoLocalCalculateChanged(meters:Long, timeInSecond:Long)
}

View File

@@ -21,6 +21,7 @@ import com.mogo.eagle.core.function.call.devatools.CallerDevaToolsManager.initBa
import com.mogo.eagle.core.function.call.hmi.CallerHmiManager.showToolsView
import com.mogo.eagle.core.function.call.map.CallerMapUIServiceManager.getMapUIController
import com.mogo.eagle.core.function.hmi.ui.msgbox.DriverMsgBoxButtonView
import com.mogo.eagle.core.function.hmi.ui.widget.ParallelDriveView
import com.mogo.eagle.core.utilcode.mogo.logger.CallerLogger.d
import com.mogo.eagle.core.utilcode.mogo.logger.scene.SceneConstant
import com.mogo.eagle.core.utilcode.mogo.view.OnPreventFastClickListener
@@ -48,6 +49,7 @@ import kotlinx.android.synthetic.main.taxi_base_fragment.module_och_autopilot_tv
import kotlinx.android.synthetic.main.taxi_base_fragment.module_och_taxi_badcase_ll
import kotlinx.android.synthetic.main.taxi_base_fragment.module_och_taxi_setting_layout
import kotlinx.android.synthetic.main.taxi_base_fragment.module_och_taxi_swich_map_layout
import kotlinx.android.synthetic.main.taxi_base_fragment.parallelDriveView
import kotlinx.android.synthetic.main.taxi_base_fragment.smallMapView
import kotlinx.android.synthetic.main.taxi_base_fragment.startAutopilotAnimationView
import kotlinx.android.synthetic.main.taxi_base_fragment.taxi_close_navi_icon
@@ -188,6 +190,13 @@ abstract class BaseTaxiTabFragment<V : IView, P : Presenter<V>> : MvpFragment<V,
showToolsView()
}
//点击主动请求平行驾驶: 若在倒计时请求自驾中, 取消请求
parallelDriveView.setClickEventListener(object: ParallelDriveView.ClickEventListener{
override fun onReqClick() {
stopAutoStartAutopilot()
}
})
// mBadCaseBtn的visible显示逻辑在showBadcaseEntrance内处理
if (module_och_taxi_badcase_ll != null) {
initBadCase(module_och_taxi_badcase_ll)
@@ -258,6 +267,8 @@ abstract class BaseTaxiTabFragment<V : IView, P : Presenter<V>> : MvpFragment<V,
})
}
abstract fun stopAutoStartAutopilot()
override fun initViews(savedInstanceState: Bundle?) {
super.initViews(savedInstanceState)
mapBizView.onCreate(savedInstanceState)
@@ -610,15 +621,37 @@ abstract class BaseTaxiTabFragment<V : IView, P : Presenter<V>> : MvpFragment<V,
fun showStartAutopilotBlinkAnimation() {
startAutopilotAnimationView.show(
StartAutopilotAnimationView.DirectionEnum.ALERT_WARNING_TOP,
START_AUTOPILOT_ANIMATION_INTERVAL
)
START_AUTOPILOT_ANIMATION_INTERVAL,
object : StartAutopilotAnimationView.AnimationViewTimerListener{
override fun onTimerResume(remainingTime: Long) {
resumeStartAutopilot(remainingTime)
}
UiThreadHandler.postDelayed({
stopStartAutopilotBlinkAnimation()
}, START_AUTOPILOT_ANIMATION_INTERVAL)
override fun onTimerPause() {
pauseStartAutopilot()
}
}
)
}
abstract fun pauseStartAutopilot()
abstract fun resumeStartAutopilot(remainingTime: Long)
fun stopAutopilotBlinkAnimation(){
stopStartAutopilotBlinkAnimation()
}
private fun stopStartAutopilotBlinkAnimation() {
startAutopilotAnimationView.dismiss(StartAutopilotAnimationView.DirectionEnum.ALERT_WARNING_TOP)
}
fun pauseAutopilotBlinkAnimation(){
startAutopilotAnimationView.pause()
}
fun resumeAutopilotBlinkAnimation(){
startAutopilotAnimationView.resume()
}
}

View File

@@ -109,6 +109,14 @@ class TaxiFragment : BaseTaxiTabFragment<TaxiFragment, TaxiPresenter>(),
}
}
override fun pauseStartAutopilot() {
mPresenter.pauseStartAutopilot()
}
override fun resumeStartAutopilot(remainingTime: Long) {
mPresenter.resumeStartAutopilot(remainingTime)
}
override fun startNaviToEndStation(isShow: Boolean) {
mPresenter.startNaviToEndStation(isShow)
}
@@ -122,6 +130,10 @@ class TaxiFragment : BaseTaxiTabFragment<TaxiFragment, TaxiPresenter>(),
initOrderDebugView()
}
override fun stopAutoStartAutopilot() {
mPresenter.stopAutoStartAutopilot()
}
private fun initFragment() {
taskTabFragment = WeakReference(TaxiTaskTabFragment.newInstance())
val transaction: FragmentTransaction = childFragmentManager.beginTransaction()
@@ -235,7 +247,7 @@ class TaxiFragment : BaseTaxiTabFragment<TaxiFragment, TaxiPresenter>(),
it.order!!.orderLine
else
it.lineId
)
,true)
}
}

View File

@@ -166,6 +166,15 @@ public class TaxiPresenter extends Presenter<TaxiFragment> implements ITaxiADASS
});
}
@Override
public void stopOpenAutopilotNonManual() {
runOnUIThread(() -> {
mView.startOrStopLoadingAnim(false);
mView.stopAutopilotBlinkAnimation();
});
}
@Override
public void loginSuccess(DriverStatusQueryRespBean data) {
//设置 接单状态
@@ -191,4 +200,16 @@ public class TaxiPresenter extends Presenter<TaxiFragment> implements ITaxiADASS
@Override
public void loginFail(boolean isLogin) {
}
public void stopAutoStartAutopilot() {
TaxiTaskModel.INSTANCE.stopAutoStartAutopilot();
}
public void pauseStartAutopilot() {
TaxiTaskModel.INSTANCE.pauseStartAutopilot();
}
public void resumeStartAutopilot(long remainingTime) {
TaxiTaskModel.INSTANCE.resumeStartAutopilot(remainingTime);
}
}

View File

@@ -195,7 +195,13 @@ public class DebugView @JvmOverloads constructor(
override fun onOrderJourneyCompleted() {
}
override fun onStartAutopilot() {
override fun onStartAutopilot(postDelayTime: Long) {
}
override fun onPauseStartAutopilot() {
}
override fun onStopAutopilot() {
}
override fun onStartPrepareTaskUI(delayTime: Long, isStart: Boolean) {

View File

@@ -12,6 +12,7 @@ import com.mogo.eagle.core.utilcode.util.UiThreadHandler
import com.mogo.och.common.module.biz.network.OchCommonServiceCallback
import com.mogo.och.common.module.utils.ToastUtilsOch
import com.mogo.och.common.module.voice.VoiceNotice
import com.mogo.och.common.module.wigets.StartAutopilotAnimationView
import com.mogo.och.taxi.R
import com.mogo.och.taxi.base.BaseViewModel
import com.mogo.och.taxi.base.IUiIntent
@@ -143,7 +144,7 @@ class TaxiCurrentTaskViewModel : BaseViewModel<UnmannedState, TaskUiIntent>(),
}
}
private fun startTask() {
private fun startTask(isStartAutopilot: Boolean = true) {
if (!TaxiTaskModel.checkCurrentTaskCondition()) {
ToastUtils.showShort("无任务!")
return
@@ -155,7 +156,7 @@ class TaxiCurrentTaskViewModel : BaseViewModel<UnmannedState, TaskUiIntent>(),
it.order!!.orderLine
else
it.lineId
)
,isStartAutopilot)
}
}
@@ -288,11 +289,25 @@ class TaxiCurrentTaskViewModel : BaseViewModel<UnmannedState, TaskUiIntent>(),
}
}
override fun onStartAutopilot() {
UiThreadHandler.postDelayed({
startTask() //状态流转
VoiceNotice.showNotice("车辆正在自动开启自动驾驶")
}, TaxiUnmannedConst.START_AUTOPILOT_COUNTDOWN_INTERVAL) // 10s后开启自驾, 状态流转
override fun onStartAutopilot(postDelayTime: Long) {
UiThreadHandler.postDelayed(startTaskRunnable, postDelayTime) // 10s后或者倒计时继续开启自驾, 状态流转
}
private val startTaskRunnable: Runnable = Runnable {
startTask() //状态流转
VoiceNotice.showNotice("车辆正在自动开启自动驾驶")
}
/**
* 主动请求平行驾驶, 停止启动自驾命令, 任务状态需向下流转
*/
override fun onStopAutopilot() {
UiThreadHandler.removeCallbacks(startTaskRunnable)
startTask(false)
}
override fun onPauseStartAutopilot() {
UiThreadHandler.removeCallbacks(startTaskRunnable)
}
/**

View File

@@ -20,14 +20,17 @@ import com.mogo.eagle.core.data.deva.chain.ChainConstant
import com.mogo.eagle.core.data.map.MogoLocation
import com.mogo.eagle.core.function.api.autopilot.IMoGoAutopilotStatusListener
import com.mogo.eagle.core.function.api.autopilot.IMoGoChassisLocationGCJ02Listener
import com.mogo.eagle.core.function.api.autopilot.IMoGoParallelDrivingActionsListener
import com.mogo.eagle.core.function.api.autopilot.IMoGoPlanningRottingListener
import com.mogo.eagle.core.function.call.autopilot.CallerAutoPilotControlManager
import com.mogo.eagle.core.function.call.autopilot.CallerAutoPilotStatusListenerManager
import com.mogo.eagle.core.function.call.autopilot.CallerAutoPilotStatusListenerManager.updateAutopilotControlParameters
import com.mogo.eagle.core.function.call.autopilot.CallerChassisLocationGCJ02ListenerManager
import com.mogo.eagle.core.function.call.autopilot.CallerChassisLocationGCJ02ListenerManager.getChassisLocationGCJ02
import com.mogo.eagle.core.function.call.autopilot.CallerParallelDrivingActionsListenerManager
import com.mogo.eagle.core.function.call.autopilot.CallerPlanningRottingListenerManager
import com.mogo.eagle.core.network.utils.GsonUtil
import com.mogo.eagle.core.utilcode.mogo.logger.CallerLogger
import com.mogo.eagle.core.utilcode.mogo.logger.CallerLogger.d
import com.mogo.eagle.core.utilcode.mogo.logger.CallerLogger.e
import com.mogo.eagle.core.utilcode.mogo.logger.CallerLogger.i
@@ -76,6 +79,7 @@ import com.mogo.och.taxi.ui.debug.DebugView
import com.mogo.och.taxi.utils.RxJavaUtils
import com.mogo.och.taxi.utils.TaxiAnalyticsManager
import com.mogo.och.taxi.utils.TaxiTrajectoryManager
import com.zhjt.mogo.adas.data.bean.UnableLaunchReason
import com.zhjt.service.chain.ChainLog
import io.reactivex.Observable
import io.reactivex.android.schedulers.AndroidSchedulers
@@ -225,6 +229,8 @@ object TaxiTaskModel {
AbnormalFactorsLoopManager.startLoopAbnormalFactors(mContext)
TrajectoryAndDistanceManager.addDistanceListener(TAG, localCalculateDistanceListener)
TrajectoryAndDistanceManager.addTrajectoryListener(TAG, localCalculateTrajectoryListener)
//3.6.0后平行驾驶.刹车. 3.6.0前没有
CallerParallelDrivingActionsListenerManager.addListener(TAG,mParallelDrivingActionsListener)
}
private fun releaseListeners() {
@@ -241,6 +247,34 @@ object TaxiTaskModel {
CallerPlanningRottingListenerManager.removeListener(mMogoAutopilotPlanningListener)
OCHAdasAbilityManager.getInstance().setAdasStartFailureCallback(null)
AbnormalFactorsLoopManager.stopLoopAbnormalFactors()
CallerParallelDrivingActionsListenerManager.removeListener(TAG)
}
// 监听平行驾驶、刹车, 试用于MAP3.6.0以上
private val mParallelDrivingActionsListener: IMoGoParallelDrivingActionsListener =
object : IMoGoParallelDrivingActionsListener {
override fun onParallelDrivingAbility(
isParallelDrivingAbility: Boolean,
unableParallelDrivingReasons: ArrayList<UnableLaunchReason>?
) {
if (unableParallelDrivingReasons != null) {
if (unableParallelDrivingReasons.toString().contains(UnableLaunchReason.SourceType.CHASSIS.name)
&& unableParallelDrivingReasons.toString().contains(UnableLaunchReason.UnableType.BRAKE.name)) {
//刹车变化回调
d(TAG,"onParallelDrivingAbility = $isParallelDrivingAbility," +
" unableParallelDrivingReasons = ${unableParallelDrivingReasons.toString()}" )
handleBrakeStatusChange(isParallelDrivingAbility)
}
}
}
}
/**
* brakeStatus: true: 恢复启动自驾
* false: 暂停启动自驾
*/
private fun handleBrakeStatusChange(brakeStatus: Boolean) {
}
private val mMogoAutopilotStatusListener: IMoGoAutopilotStatusListener =
@@ -763,7 +797,7 @@ object TaxiTaskModel {
mControllerStatusCallback?.startOpenAutopilotNonManual()
mTaxiTaskWithOrderCallbackMap.forEach {
val listener = it.value
listener.onStartAutopilot()
listener.onStartAutopilot(TaxiUnmannedConst.START_AUTOPILOT_COUNTDOWN_INTERVAL)
}
}
}
@@ -874,7 +908,7 @@ object TaxiTaskModel {
})
}
fun startTask(lineId: Long) {
fun startTask(lineId: Long, isStartAutopilot: Boolean) {
DebugView.printInfoMsg("[开始任务] 准备发送请求lindId=$lineId")
TaxiTaskWithOrderServiceManager.startTask(
mContext,
@@ -882,7 +916,9 @@ object TaxiTaskModel {
object : OchCommonServiceCallback<BaseData> {
override fun onSuccess(data: BaseData?) {
DebugView.printInfoMsg("[开始任务] 请求successlindId=$lineId")
startAutoPilot() //自驾开启
if (isStartAutopilot){
startAutoPilot() //自驾开启
}
d(TAG, "startTask onSuccess: data=${GsonUtil.jsonFromObject(data)}")
}
@@ -1078,7 +1114,7 @@ object TaxiTaskModel {
if (QueryCurrentTaskRespBean.isStartTaskType(mCurrentTaskWithOrder)) {
startAutoPilot()
}else if (QueryCurrentTaskRespBean.isGetTaskType(mCurrentTaskWithOrder)){
startTask(mCurrentTaskWithOrder!!.lineId)
startTask(mCurrentTaskWithOrder!!.lineId, true)
}else{
e(TAG, "task currentStatus is not StartTask.")
DebugView.printInfoMsg("[启自驾] task currentStatus is not StartTask")
@@ -1442,4 +1478,26 @@ object TaxiTaskModel {
}
startAutoPilot()
}
fun stopAutoStartAutopilot() {
mControllerStatusCallback?.stopOpenAutopilotNonManual()
mTaxiTaskWithOrderCallbackMap.forEach {
val listener = it.value
listener.onStopAutopilot()
}
}
fun pauseStartAutopilot(){
mTaxiTaskWithOrderCallbackMap.forEach {
val listener = it.value
listener.onPauseStartAutopilot()
}
}
fun resumeStartAutopilot(remainingTime: Long){
mTaxiTaskWithOrderCallbackMap.forEach {
val listener = it.value
listener.onStartAutopilot(remainingTime)
}
}
}

View File

@@ -185,6 +185,7 @@
app:layout_constraintTop_toBottomOf="@id/viewDriverMsgBoxButton" />
<com.mogo.eagle.core.function.hmi.ui.widget.ParallelDriveView
android:id="@+id/parallelDriveView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:layout_constraintTop_toTopOf="parent"