From b31c109be0f1c4ddecd8c527bb007ef8caeb32bc Mon Sep 17 00:00:00 2001 From: wangmingjun Date: Thu, 24 Aug 2023 19:59:30 +0800 Subject: [PATCH] =?UTF-8?q?[6.0.0]=201=E3=80=81=E9=A2=84=E5=8A=A0=E8=BD=BD?= =?UTF-8?q?=E8=BD=A8=E8=BF=B9=E9=80=BB=E8=BE=91=E5=A4=84=E7=90=86=202?= =?UTF-8?q?=E3=80=81=E5=8E=BB=E9=99=A4=E8=B5=B7=E7=82=B9=E5=9B=B4=E6=A0=8F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../mogo/och/taxi/ui/task/TaxiTaskModel.kt | 1739 ++++++++--------- .../och/taxi/utils/TaxiTrajectoryManager.java | 30 +- 2 files changed, 824 insertions(+), 945 deletions(-) diff --git a/OCH/taxi/unmanned-driver/src/main/java/com/mogo/och/taxi/ui/task/TaxiTaskModel.kt b/OCH/taxi/unmanned-driver/src/main/java/com/mogo/och/taxi/ui/task/TaxiTaskModel.kt index 425e110c91..d013c8e749 100644 --- a/OCH/taxi/unmanned-driver/src/main/java/com/mogo/och/taxi/ui/task/TaxiTaskModel.kt +++ b/OCH/taxi/unmanned-driver/src/main/java/com/mogo/och/taxi/ui/task/TaxiTaskModel.kt @@ -1,4 +1,4 @@ -package com.mogo.och.taxi.ui.task +package com.mogo.och.taxi.model import android.annotation.SuppressLint import android.content.Context @@ -7,7 +7,6 @@ import android.text.TextUtils import com.alibaba.android.arouter.launcher.ARouter import com.amap.api.maps.model.LatLng import com.mogo.aicloud.services.socket.IMogoOnMessageListener -import com.mogo.commons.AbsMogoApplication import com.mogo.commons.module.intent.IMogoIntentListener import com.mogo.commons.module.intent.IntentManager import com.mogo.commons.module.status.IMogoStatusChangedListener @@ -23,9 +22,13 @@ 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.IMoGoPlanningRottingListener import com.mogo.eagle.core.function.call.autopilot.CallerAutoPilotControlManager +import com.mogo.eagle.core.function.call.autopilot.CallerAutoPilotControlManager.cancelAutoPilot +import com.mogo.eagle.core.function.call.autopilot.CallerAutoPilotControlManager.setIPCDemoMode +import com.mogo.eagle.core.function.call.autopilot.CallerAutoPilotControlManager.setIgnoreConditionDraw 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.addListener import com.mogo.eagle.core.function.call.autopilot.CallerChassisLocationGCJ02ListenerManager.getChassisLocationGCJ02 import com.mogo.eagle.core.function.call.autopilot.CallerPlanningRottingListenerManager import com.mogo.eagle.core.network.utils.GsonUtil @@ -40,100 +43,96 @@ import com.mogo.eagle.core.utilcode.util.NetworkUtils import com.mogo.eagle.core.utilcode.util.ToastUtils import com.mogo.eagle.core.utilcode.util.UiThreadHandler import com.mogo.och.common.module.biz.common.socketmessage.OCHSocketMessageManager +import com.mogo.och.common.module.biz.common.socketmessage.OCHSocketMessageManager.pushAppOperationalMsgBox +import com.mogo.och.common.module.biz.common.socketmessage.OCHSocketMessageManager.registerSocketMessageListener +import com.mogo.och.common.module.biz.common.socketmessage.OCHSocketMessageManager.releaseSocketMessageListener import com.mogo.och.common.module.biz.common.socketmessage.data.OCHOperationalMessage -import com.mogo.och.common.module.biz.constant.LoginStatusManager import com.mogo.och.common.module.biz.constant.OchCommonConst import com.mogo.och.common.module.biz.network.OchCommonServiceCallback import com.mogo.och.common.module.biz.provider.LoginService import com.mogo.och.common.module.callback.OchAdasStartFailureCallback -import com.mogo.och.common.module.manager.AbnormalFactorsLoopManager +import com.mogo.och.common.module.manager.AbnormalFactorsLoopManager.startLoopAbnormalFactors +import com.mogo.och.common.module.manager.AbnormalFactorsLoopManager.stopLoopAbnormalFactors import com.mogo.och.common.module.manager.OCHAdasAbilityManager import com.mogo.och.common.module.manager.distancemamager.IDistanceListener import com.mogo.och.common.module.manager.distancemamager.ITrajectoryListener -import com.mogo.och.common.module.manager.distancemamager.TrajectoryAndDistanceManager +import com.mogo.och.common.module.manager.distancemamager.TrajectoryAndDistanceManager.addDistanceListener +import com.mogo.och.common.module.manager.distancemamager.TrajectoryAndDistanceManager.addTrajectoryListener import com.mogo.och.common.module.manager.distancemamager.TrajectoryAndDistanceManager.setStationPoint import com.mogo.och.common.module.map.AmapNaviToDestinationModel import com.mogo.och.common.module.utils.CoordinateCalculateRouteUtil.coordinateConverterWgsToGcjLocations import com.mogo.och.common.module.voice.VoiceNotice +import com.mogo.och.taxi.bean.ContrailListRespBean import com.mogo.och.taxi.bean.OrderDetail -import com.mogo.och.taxi.bean.PrepareTaskRespBean -import com.mogo.och.taxi.bean.QueryCarOrderByNoRespBean import com.mogo.och.taxi.bean.QueryCurrentTaskRespBean +import com.mogo.och.taxi.bean.Site import com.mogo.och.taxi.bean.StartServiceRespBean -import com.mogo.och.taxi.bean.TrajectoryListRespBean import com.mogo.och.taxi.callback.IOCHTaxiAutopilotPlanningCallback import com.mogo.och.taxi.callback.ITaxiADASStatusCallback import com.mogo.och.taxi.callback.ITaxiControllerStatusCallback import com.mogo.och.taxi.callback.ITaxiOrderStatusCallback -import com.mogo.och.taxi.callback.ITaxiTaskCallback import com.mogo.och.taxi.constant.TaskStatusEnum -import com.mogo.och.taxi.constant.TaskTypeEnum -import com.mogo.och.taxi.constant.TaxiCarServingStatusManager import com.mogo.och.taxi.constant.TaxiOrderStatusEnum import com.mogo.och.taxi.constant.TaxiOrderStatusEnum.Companion.valueOf import com.mogo.och.taxi.constant.TaxiUnmannedConst import com.mogo.och.taxi.constant.TaxiUnmannedConst.Companion.BUSINESSTYPE -import com.mogo.och.taxi.constant.TaxiUnmannedConst.Companion.START_AUTOPILOT_COUNTDOWN_INTERVAL -import com.mogo.och.taxi.network.TaxiTaskWithOrderServiceManager -import com.mogo.och.taxi.utils.RxJavaUtils +import com.mogo.och.taxi.constant.TaxiUnmannedConst.Companion.COUNTDOWN_INTERVAL +import com.mogo.och.taxi.network.CarServiceManager +import com.mogo.och.taxi.network.CarServiceManager.arriveSite +import com.mogo.och.taxi.network.CarServiceManager.startTask import com.mogo.och.taxi.utils.TaxiAnalyticsManager import com.mogo.och.taxi.utils.TaxiTrajectoryManager import com.zhjt.service.chain.ChainLog -import io.reactivex.Observable -import io.reactivex.android.schedulers.AndroidSchedulers -import io.reactivex.disposables.Disposable -import io.reactivex.schedulers.Schedulers +import io.reactivex.exceptions.UndeliverableException +import io.reactivex.functions.Consumer +import io.reactivex.plugins.RxJavaPlugins +import mogo.telematics.pad.MessagePad import mogo.telematics.pad.MessagePad.ArrivalNotification import mogo.telematics.pad.MessagePad.GlobalPathResp import mogo_msg.MogoReportMsg.MogoReportMessage import system_master.SsmInfo import system_master.SystemStatusInfo -import java.util.concurrent.TimeUnit +import java.io.IOException /** * @author: wangmingjun * @date: 2023/7/25 */ @SuppressLint("StaticFieldLeak") -object TaxiTaskModel { +object TaxiModel { - private val TAG = SceneConstant.M_TAXI + TaxiTaskModel::class.java.simpleName + private val TAG = TaxiModel::class.java.simpleName - private lateinit var mContext: Context + private var mContext: Context? = null - private var mQueryTaskWithOrderDisposable: Disposable? = null + private var mCurrentTaskAndOrder: QueryCurrentTaskRespBean.Result? = null //当前任务和订单 - var loginService: LoginService? = null + /** + * 标定站点的任务, 在没有到站之前, 轮询接口是没有的. + * 到站后, 轮询的任务会显示到站站点为这个虚拟站点,任务状态为到站 + */ + private var mUntruthTask: StartServiceRespBean.Result? = null // 前往出车点的伪任务, 后台并不算做真正的任务 - //Model->Presenter:自动驾驶状态相关 - private var mADASStatusCallback: ITaxiADASStatusCallback? = null + private var mOrderContrails: MutableList? = + null // 运营单(接驾任务和送驾任务的轨迹集合) - //Model->Presenter/ViewModel:VR mode等 - private var mControllerStatusCallback: ITaxiControllerStatusCallback? = null + private var mCurTaskContrail: ContrailListRespBean.Result? = null //当前在跑的任务的轨迹信息 - //Model->Presenter/ViewModel:订单变更 - private var mOrderStatusCallback: ITaxiOrderStatusCallback? = null + private var mADASStatusCallback //Model->Presenter:自动驾驶状态相关 + : ITaxiADASStatusCallback? = null + private var mControllerStatusCallback //Model->Presenter:VR mode等 + : ITaxiControllerStatusCallback? = null + private var mOrderStatusCallback //Model->Presenter:订单变更 + : ITaxiOrderStatusCallback? = null private var mAutopilotPlanningCallback: IOCHTaxiAutopilotPlanningCallback? = null - private var mTaxiTaskCallback: ITaxiTaskCallback? = null - - //当前任务和订单 - private var mCurrentTaskWithOrder: QueryCurrentTaskRespBean.Result? = null - - //开始车辆到标定站点的特殊任务 - private var mDriveToNearestStationTask: StartServiceRespBean.Result? = null - - //运营单(接驾任务和送驾任务的轨迹集合) - private var mTaskTrajectoryList: MutableList = mutableListOf() - - //当前在跑的任务的轨迹信息 - private var mCurrentTaskTrajectory: TrajectoryListRespBean.Result? = null - @Volatile private var isRestartAutopilot = false - private val mCurrentTaskRoutePointsGcj: MutableList = ArrayList() + private val mRoutePoints: MutableList? = ArrayList() + + var loginService: LoginService? = null fun setMoGoAutopilotPlanningListener(moGoAutopilotPlanningCallback: IOCHTaxiAutopilotPlanningCallback?) { mAutopilotPlanningCallback = moGoAutopilotPlanningCallback @@ -151,16 +150,51 @@ object TaxiTaskModel { mOrderStatusCallback = callback } - fun setTaskCallback(callback: ITaxiTaskCallback) { - mTaxiTaskCallback = callback - } - fun init(context: Context) { mContext = context.applicationContext + initListeners() loginService = ARouter.getInstance().build(OchCommonConst.LOGINSERVICE).navigation() as LoginService - initListeners() - RxJavaUtils.setErrorHandler(TAG) + + //2022.1.28 + // 调用Disposable.dispose() 时候会出现InterruptedException 导致出现崩溃 + // The exception could not be delivered to the consumer because it has already canceled/disposed the flow or the excTeption has nowhere to go to begin with + RxJavaPlugins.setErrorHandler(Consumer { e -> + var e = e + if (e is UndeliverableException) { + e = (e.cause)!! + d(SceneConstant.M_TAXI + TAG, "UndeliverableException") + } + if ((e is IOException)) { // + // fine, irrelevant network problem or API that throws on cancellation + d(SceneConstant.M_TAXI + TAG, "IOException") + return@Consumer + } + if (e is InterruptedException) { + // fine, some blocking code was interrupted by a dispose call + d(SceneConstant.M_TAXI + TAG, "InterruptedException") + return@Consumer + } + if ((e is NullPointerException) || (e is IllegalArgumentException)) { + // that's likely a bug in the application + d(SceneConstant.M_TAXI + TAG, "NullPointerException or IllegalArgumentException") + Thread.currentThread().uncaughtExceptionHandler?.uncaughtException( + Thread.currentThread(), + e + ) + return@Consumer + } + if (e is IllegalStateException) { + // that's a bug in RxJava or in a custom operator + d(SceneConstant.M_TAXI + TAG, "IllegalStateException") + Thread.currentThread().uncaughtExceptionHandler?.uncaughtException( + Thread.currentThread(), + e + ) + return@Consumer + } + d(SceneConstant.M_TAXI + TAG, "Undeliverable exception") + }) } fun release() { @@ -170,30 +204,51 @@ object TaxiTaskModel { private fun initListeners() { // 2021.11.1重构自动驾驶 实现接口 IMoGoAutopilotStatusListener 注册监听 替换IMogoAdasOCHCallback接口 - CallerAutoPilotStatusListenerManager.addListener(TAG, mMogoAutopilotStatusListener) - //定位监听, 传false是高德坐标系 - CallerChassisLocationGCJ02ListenerManager.addListener(TAG, 10, mMapLocationListener) - //2021.11.1 自动驾驶路线规划接口 - CallerPlanningRottingListenerManager.addListener(TAG, mMogoAutopilotPlanningListener) - //开启自驾后 异常信息返回 - OCHAdasAbilityManager.getInstance() - .setAdasStartFailureCallback(mAdasStartAutopilotFailureListener) - OCHSocketMessageManager.registerSocketMessageListener( - OCHSocketMessageManager.msgMonitorType, - mMogoOnSocketMessageListener - ) + CallerAutoPilotStatusListenerManager.addListener(TAG, mGoAutopilotStatusListener) + IntentManager.getInstance() + .registerIntentListener(ConnectivityManager.CONNECTIVITY_ACTION, mNetWorkIntentListener) MogoStatusManager.getInstance().registerStatusChangedListener( TAG, StatusDescriptor.VR_MODE, mMogoStatusChangedListener ) - IntentManager.getInstance() - .registerIntentListener(ConnectivityManager.CONNECTIVITY_ACTION, mNetWorkIntentListener) - AbnormalFactorsLoopManager.startLoopAbnormalFactors(mContext) - TrajectoryAndDistanceManager.addDistanceListener(TAG, localCalculateDistanceListener) - TrajectoryAndDistanceManager.addTrajectoryListener(TAG, localCalculateTrajectoryListener) + + //定位监听, 传false是高德坐标系 + addListener(TAG, 10, mMapLocationListener) + + //2021.11.1 自动驾驶路线规划接口 + CallerPlanningRottingListenerManager.addListener(TAG, moGoAutopilotPlanningListener) + + //开启自驾后 异常信息返回 + OCHAdasAbilityManager.getInstance().setAdasStartFailureCallback(mAdasStartFailureListener) + registerSocketMessageListener( + OCHSocketMessageManager.msgMonitorType, + mMogoOnMessageListener + ) + startLoopAbnormalFactors(mContext!!) + addDistanceListener(TAG, distanceListener) + addTrajectoryListener(TAG, trajectoryListener) } + private val mMogoOnMessageListener = + object : IMogoOnMessageListener { + override fun target(): Class { + return OCHOperationalMessage::class.java + } + + override fun onMsgReceived(obj: OCHOperationalMessage) { + if (obj == null) { + d(SceneConstant.M_TAXI + TAG, "onMsgReceived = null") + return + } + d(SceneConstant.M_TAXI + TAG, "onMsgReceived = " + obj.message) + pushAppOperationalMsgBox( + obj.pushTimeStamp, + obj.message, OCHSocketMessageManager.OPERATION_SYSTEM + ) + } + } + private fun releaseListeners() { MogoStatusManager.getInstance().unregisterStatusChangedListener( TAG, @@ -203,14 +258,516 @@ object TaxiTaskModel { // 注销地图监听 CallerChassisLocationGCJ02ListenerManager.removeListener(TAG) - OCHSocketMessageManager.releaseSocketMessageListener(OCHSocketMessageManager.msgMonitorType) - CallerAutoPilotStatusListenerManager.removeListener(mMogoAutopilotStatusListener) - CallerPlanningRottingListenerManager.removeListener(mMogoAutopilotPlanningListener) + releaseSocketMessageListener(OCHSocketMessageManager.msgMonitorType) + CallerAutoPilotStatusListenerManager.removeListener(mGoAutopilotStatusListener) + CallerPlanningRottingListenerManager.removeListener(moGoAutopilotPlanningListener) OCHAdasAbilityManager.getInstance().setAdasStartFailureCallback(null) - AbnormalFactorsLoopManager.stopLoopAbnormalFactors() + stopLoopAbnormalFactors() } - private val mMogoAutopilotStatusListener: IMoGoAutopilotStatusListener = + // 获取当前订单状态 + fun getCurOrderStatus(): TaxiOrderStatusEnum? { + if (mCurrentTaskAndOrder == null) TaxiOrderStatusEnum.None + val order: OrderDetail = mCurrentTaskAndOrder!!.order!! + return valueOf(order.orderStatus) + } + + fun getCurTaskStatus(): Int? { + if (mCurrentTaskAndOrder == null) TaskStatusEnum.None + return mCurrentTaskAndOrder?.currentStatus + } + + fun getCurTaskAndOrder(): QueryCurrentTaskRespBean.Result? { + return mCurrentTaskAndOrder + } + + fun getCurUntruthTask(): StartServiceRespBean.Result? { + return mUntruthTask + } + + fun getCurOrderContrails(): MutableList? { + return mOrderContrails + } + + fun getCurTaskContrail(): ContrailListRespBean.Result? { + return mCurTaskContrail + } + + //更新本地currentOrder信息,并保存订单到本地避免车机重启丢失数据 + private fun updateNativeCurrentOrder(data: QueryCurrentTaskRespBean.Result?) { + if (data == null) { + return + } + mCurrentTaskAndOrder = data + + SharedPrefsMgr.getInstance(mContext!!).putString( + TaxiUnmannedConst.SP_KEY_OCH_TAXI_ORDER, + GsonUtil.jsonFromObject(data) + ) + + val currentOrder = mCurrentTaskAndOrder!!.order + + if (currentOrder != null) { + if (currentOrder!!.orderStatus == TaxiOrderStatusEnum.OnTheWayToEnd.code) { + if (FunctionBuildConfig.isDemoMode) { + // 当美化模式(演示模式)开启时: 订单对应自动驾驶开启后,置true + FunctionBuildConfig.isIgnoreConditionsDrawAutopilotTrajectoryData = true + setIgnoreConditionDraw(true) + setIPCDemoMode(true) + d(SceneConstant.M_TAXI + TAG, "美化模式-ignore:置为true(更新本地order信息)") + } + updateAutopilotControlParameters() + } + if (currentOrder!!.orderStatus == TaxiOrderStatusEnum.ArriveAtEnd.code) { + if (FunctionBuildConfig.isDemoMode) { + d(SceneConstant.M_TAXI + TAG, "setIPCDemoMode:false") + setIPCDemoMode(false) + } + clearAutopilotControlParameters() + } + } else { + if (FunctionBuildConfig.isDemoMode) { + d(SceneConstant.M_TAXI + TAG, "setIPCDemoMode:false") + setIPCDemoMode(false) + } + clearAutopilotControlParameters() + } + } + + /** + * 将业务订单信息保存,鹰眼可取用 + */ + private fun updateAutopilotControlParameters() { + val parameters = initAutopilotControlParameters() + if (null == parameters) { + e(SceneConstant.M_TAXI + TAG, "AutopilotControlParameters is empty.") + return + } + d(SceneConstant.M_TAXI + TAG, "AutopilotControlParameters is update.") + updateAutopilotControlParameters(parameters) + } + + private fun clearAutopilotControlParameters() { + d(SceneConstant.M_TAXI + TAG, "AutopilotControlParameters is clear.") + updateAutopilotControlParameters(null) + } + + fun updateCurrentTaskAndOrder(result: QueryCurrentTaskRespBean.Result?) { + mCurrentTaskAndOrder = result + updateNativeCurrentOrder(result) + } + + fun updateUntruthTask(untruthTask: StartServiceRespBean.Result?) { + mUntruthTask = untruthTask + } + + //清除任务订单信息 + fun clearCurrentOCHOrder() { + mCurrentTaskAndOrder = null + clearAutopilotControlParameters() + TaxiTrajectoryManager.getInstance().syncTrajectoryInfo() + SharedPrefsMgr.getInstance(mContext!!).remove(TaxiUnmannedConst.SP_KEY_OCH_TAXI_ORDER) + isRestartAutopilot = false + if (FunctionBuildConfig.isDemoMode) { + // 当美化模式(演示模式)开启时: 取消或订单已完成时,置false + FunctionBuildConfig.isIgnoreConditionsDrawAutopilotTrajectoryData = false + setIgnoreConditionDraw(false) + setIPCDemoMode(false) + d(SceneConstant.M_TAXI + TAG, "美化模式-ignore:置为false(已完成or清除当前订单)") + } + } + + //检测当前任务 + fun checkCurrentTask(): Boolean { + return mCurrentTaskAndOrder != null && mCurrentTaskAndOrder!!.startSite != null + && mCurrentTaskAndOrder!!.endSite != null + } + + private fun checkCurrentOrder(): Boolean { + return mCurrentTaskAndOrder != null && mCurrentTaskAndOrder!!.order != null + } + + /** + * 以当前订单为基础,开启自动驾驶 + */ + @ChainLog( + linkChainLog = ChainConstant.CHAIN_TYPE_SOCKET_AUTOPILOT, + linkCode = ChainConstant.CHAIN_SOURCE_ADAS, + nodeAliasCode = ChainConstant.CHAIN_CODE_OCH_TAXI_START_AUTOPILOT, + paramIndexes = [-1] + ) + fun startAutoPilot() { + if (!checkCurrentTask()) { + e(SceneConstant.M_TAXI + TAG, "no order or order is empty.") + ToastUtils.showShort("当前订单不存在或异常!") + return + } + + if (mCurTaskContrail == null) { + e(SceneConstant.M_TAXI + TAG, "no order or order is empty.") + ToastUtils.showShort("轨迹信息不存在!") + } + + //根据开关和后台是否发布轨迹启动自驾 + if (FunctionBuildConfig.isPassStartAutopilotCommand && mCurTaskContrail != null && TextUtils.isEmpty( + mCurTaskContrail!!.csvFileUrl + ) + && TextUtils.isEmpty(mCurTaskContrail!!.csvFileUrlDPQP) + ) { + ToastUtils.showLong("无发布轨迹, 请发布后重试") + e( + SceneConstant.M_TAXI + TAG, "isPassStartAutopilotCommand = " + + FunctionBuildConfig.isPassStartAutopilotCommand + + "busRoutesResult.csvFileUrl = " + mCurTaskContrail!!.csvFileUrl + + "busRoutesResult.csvFileUrlDPQP = " + mCurTaskContrail!!.csvFileUrlDPQP + ) + return + } + e( + SceneConstant.M_TAXI + TAG, "isPassStartAutopilotCommand = " + + FunctionBuildConfig.isPassStartAutopilotCommand + ) + if (!FunctionBuildConfig.isDemoMode && !OCHAdasAbilityManager.getInstance().autopilotAbilityStatus) { + ToastUtils.showLong( + OCHAdasAbilityManager.getInstance().autopilotUnAbilityReason + + ", 请稍候重试" + ) + TaxiAnalyticsManager.getInstance().triggerUnableStartAPReasonEvent( + mCurrentTaskAndOrder!!.startSite!!.siteName, + mCurrentTaskAndOrder!!.endSite!!.siteName, + mCurrentTaskAndOrder!!.lineId.toString(), // todo 这里原来传的是订单号, 现在是任务没有订单号,传了路线id + OCHAdasAbilityManager.getInstance().autopilotUnAbilityReason + ) + return + } + + //点击开始自动驾驶按钮订单状态去流转, 不再与自动驾驶是否启动成功挂钩 + isRestartAutopilot = mCurrentTaskAndOrder!!.currentStatus != TaskStatusEnum.StartTask.code + + val parameters = initAutopilotControlParameters() + if (null == parameters) { + e(SceneConstant.M_TAXI + TAG, "AutopilotControlParameters is empty.") + return + } + CallerAutoPilotControlManager.startAutoPilot(parameters) + d( + SceneConstant.M_TAXI + TAG, "start autopilot with parameter: %s", + GsonUtil.jsonFromObject(parameters) + + " ,startSiteName=" + mCurrentTaskAndOrder?.startSite?.siteName + + " ,endSiteName=" + mCurrentTaskAndOrder?.endSite?.siteName + + "isRestartAutopilot = " + isRestartAutopilot + ) + TaxiAnalyticsManager.getInstance().triggerStartAutopilotEvent( + isRestartAutopilot, + false, + mCurrentTaskAndOrder!!.startSite!!.siteName, + mCurrentTaskAndOrder!!.endSite!!.siteName, + mCurrentTaskAndOrder!!.lineId, + if (mCurrentTaskAndOrder!!.order != null) mCurrentTaskAndOrder!!.order!!.orderNo else "" + ) + if (mControllerStatusCallback != null) { + mControllerStatusCallback!!.startOpenAutopilot() + } + } + + private fun initAutopilotControlParameters(): AutopilotControlParameters? { + if (!checkCurrentTask()) { + e(SceneConstant.M_TAXI + TAG, "no order or order is empty.") + return null + } + + if (mCurTaskContrail == null) { + e(SceneConstant.M_TAXI + TAG, "curTaskContrail is empty.") + return null + } + + val parameters = AutopilotControlParameters() + + val startWgsLon = mCurrentTaskAndOrder!!.startSite!!.wgs84Lon + val startWgsLat = mCurrentTaskAndOrder!!.startSite!!.wgs84Lat + val endWgsLon = mCurrentTaskAndOrder!!.endSite!!.wgs84Lon + val endWgsLat = mCurrentTaskAndOrder!!.endSite!!.wgs84Lat + parameters.vehicleType = BUSINESSTYPE + parameters.startName = mCurrentTaskAndOrder!!.startSite!!.siteName // 8.10 拼音首字母大写 改为直接传中文 + parameters.endName = mCurrentTaskAndOrder!!.endSite!!.siteName // 8.10 拼音首字母大写 改为直接传中文 + parameters.startLatLon = + AutopilotControlParameters.AutoPilotLonLat(startWgsLat, startWgsLon) + parameters.endLatLon = AutopilotControlParameters.AutoPilotLonLat(endWgsLat, endWgsLon) + if (parameters.autoPilotLine == null) { + parameters.autoPilotLine = AutopilotControlParameters.AutoPilotLine( + mCurTaskContrail!!.lineId, + mCurTaskContrail!!.lineName, + mCurTaskContrail!!.csvFileUrl, + mCurTaskContrail!!.csvFileMd5, + mCurTaskContrail!!.txtFileUrl, + mCurTaskContrail!!.txtFileMd5, + mCurTaskContrail!!.contrailSaveTime, + "", // todo 这里原来传的是carModel, 现在没有这个信息 + mCurTaskContrail!!.csvFileUrlDPQP, + mCurTaskContrail!!.csvFileMd5DPQP, + mCurTaskContrail!!.txtFileUrlDPQP, + mCurTaskContrail!!.txtFileMd5DPQP, + mCurTaskContrail!!.contrailSaveTimeDPQP + ) + } + return parameters + } + + //结束自动驾驶 + fun cancelAutopilot() { + try { + cancelAutoPilot() + d(SceneConstant.M_TAXI + TAG, "结束自动驾驶") + } catch (e: Exception) { + e.printStackTrace() + } + } + + //根据围栏判断,是否到达起点 + private fun judgeTaskStartStation(location: MogoLocation) { + if (checkCurrentTask()) { + val startSite = mCurrentTaskAndOrder!!.startSite ?: return + val startLon = startSite.gcjLon + val startLat = startSite.gcjLat + val distance = CoordinateUtils.calculateLineDistance( + startLon, startLat, + location.longitude, location.latitude + ).toDouble() + i(SceneConstant.M_TAXI + TAG, "judgeTaskStartStation() distance = $distance") + if (distance <= TaxiUnmannedConst.ARRIVE_AT_START_STATION_DISTANCE) { + arriveSite(startSite.siteId, false) + } + } + } + + //监听网络变化,避免启动机器时无网导致无法更新订单信息 + private val mNetWorkIntentListener: IMogoIntentListener = + IMogoIntentListener { intentStr, _ -> + d(SceneConstant.M_TAXI + TAG, "onIntentReceived = %s", intentStr) + if ((ConnectivityManager.CONNECTIVITY_ACTION == intentStr)) { + if (NetworkUtils.isConnected(mContext)) { + loginService!!.queryLoginStatusByNet() + } + } + } + + private val mAdasStartFailureListener: OchAdasStartFailureCallback = + object : OchAdasStartFailureCallback { + override fun onStartAutopilotFailure( + startFailedCode: String, + startFailedMessage: String + ) { + TaxiAnalyticsManager.getInstance() + .triggerStartAutopilotFailureEventByAdas(startFailedCode, startFailedMessage) + if (mADASStatusCallback != null && !FunctionBuildConfig.isDemoMode) { + e( + SceneConstant.M_TAXI + TAG, + "mAdasStartFailureListener = $startFailedMessage" + ) + mADASStatusCallback!!.onStartAdasFailure() + } + } + } + + private val mMogoStatusChangedListener: IMogoStatusChangedListener = + IMogoStatusChangedListener { descriptor, isTrue -> + + // VR mode变更回调 + if (StatusDescriptor.VR_MODE == descriptor) { + if (mControllerStatusCallback != null) { + mControllerStatusCallback!!.onVRModeChanged(isTrue) + } + } + } + + // 自车定位 + private val mMapLocationListener: IMoGoChassisLocationGCJ02Listener = + object : IMoGoChassisLocationGCJ02Listener { + override fun onChassisLocationGCJ02(mogoLocation: MogoLocation?) { + //位置变化时,通过围栏判断是否到达x点 + if (null == mogoLocation) return + + if (mUntruthTask != null) { + judgeUntruthStation(mUntruthTask, mogoLocation) + } + + if (checkCurrentTask() && mCurrentTaskAndOrder?.currentStatus == TaskStatusEnum.StartTask.code) { +// judgeTaskStartStation(mogoLocation) + judgeTaskEndSiteStation(mogoLocation) + } + + if (mControllerStatusCallback != null) { + mControllerStatusCallback!!.onCarLocationChanged(mogoLocation) + } + } + } + + private fun judgeUntruthStation( + virtualTask: StartServiceRespBean.Result?, + currentLocation: MogoLocation + ) { + if (mUntruthTask == null || virtualTask == null) return + val distance = CoordinateUtils.calculateLineDistance( + virtualTask.gcjLon, virtualTask.gcjLat, + currentLocation.longitude, currentLocation.latitude + ).toDouble() + i( + SceneConstant.M_TAXI + TAG, + "judgeEndStation() ${virtualTask.siteName} distance = $distance" + ) + if (distance <= TaxiUnmannedConst.ARRIVE_AT_START_STATION_DISTANCE) { // 15米内到站 + arriveSite(virtualTask.siteId, true) + } + } + + /** + * 到站(起点、终点) + * isArriveEndSite true 终点, false 起点 + */ + fun arriveSite(siteId: Long, isArriveEndSite: Boolean) { + i( + SceneConstant.M_TAXI + TAG, + "arriveSite ${siteId}" + ) + arriveSite(mContext!!, siteId, object : OchCommonServiceCallback { + override fun onSuccess(data: BaseData?) { + if (data == null || data.code != 0) return + d(SceneConstant.M_TAXI + TAG, GsonUtil.jsonFromObject(data)) + mUntruthTask = null + if (isArriveEndSite) { + cleanStation() + //2020.8.23 到站后不再调用取消自驾. 原因是取消自驾,D档位会溜车 +// cancelAutopilot() + } + } + + override fun onFail(code: Int, msg: String?) { + d(SceneConstant.M_TAXI + TAG, "$code $msg") + } + + }) + } + + private fun startTask(lineId: Long) { + startTask(mContext!!, lineId, object : OchCommonServiceCallback { + override fun onSuccess(data: BaseData?) { + d(SceneConstant.M_TAXI + TAG, GsonUtil.jsonFromObject(data)) + } + + override fun onFail(code: Int, msg: String?) { + d(SceneConstant.M_TAXI + TAG, "$code $msg") + } + + }) + } + + private fun judgeTaskEndSiteStation(currentLocation: MogoLocation) { + i(SceneConstant.M_TAXI + TAG, "judgeEndStation() judgeTaskEndSiteStation") + if (!checkCurrentTask()) { + return + } + val endSite = mCurrentTaskAndOrder!!.endSite ?: return + + val endLon = endSite.gcjLon + val endLat = endSite.gcjLat + val distance = CoordinateUtils.calculateLineDistance( + endLon, endLat, + currentLocation.longitude, currentLocation.latitude + ).toDouble() + i(SceneConstant.M_TAXI + TAG, "judgeEndStation() distance = $distance") + if (distance <= TaxiUnmannedConst.ARRIVE_AT_START_STATION_DISTANCE) { //1、当前位置和站点围栏15m内 + + //2、开始计算当前位置和站点的向量角度 < 90度 未经过 >90度 经过 + val stationAngle = DrivingDirectionUtils.getDegreeOfCar2Poi( + currentLocation.longitude, + currentLocation.latitude, + endLon, + endLat, currentLocation.heading.toInt() + ).toDouble() + i( + SceneConstant.M_TAXI + TAG, + "judgeEndStation() stationAngle = $stationAngle" + ) + + //3、刚过站且过站距离在15m内, 提交到站 + if (stationAngle > 90 && distance <= TaxiUnmannedConst.ARRIVE_AT_START_STATION_DISTANCE) { + if ((!checkCurrentTask() + || (getCurTaskStatus() == TaskStatusEnum.StartTask.code)) + ) { + i(SceneConstant.M_TAXI + TAG, "task null or TaskStatus = ${getCurTaskStatus()}") + return + } + i(SceneConstant.M_TAXI + TAG, "judgeEndStation() = 刚过站且在15m内") + arriveSite(endSite.siteId, true) + } + } + } + + + /** + * 查询当前任务的轨迹 + */ + fun queryTaskContrail(planningLines: Array?) { + if (planningLines == null) return + CarServiceManager.contrailList(mContext!!, planningLines, + object : OchCommonServiceCallback { + override fun onSuccess(data: ContrailListRespBean?) { + d(SceneConstant.M_TAXI + TAG, "queryTaskContrail: ${GsonUtil.jsonFromObject(data?.data)}") + if (data == null || data.code != 0) return + mCurTaskContrail = data.data?.get(0) + + TaxiTrajectoryManager.getInstance().syncTrajectoryInfo() + } + + override fun onFail(code: Int, msg: String?) { + d(SceneConstant.M_TAXI + TAG, "queryTaskContrail code=$code,msg=$msg") + } + + }) + } + fun setArriveAtUntruthStation() { + if (mUntruthTask == null) { + ToastUtils.showShort("无虚拟站点!") + return + } + arriveSite(mUntruthTask!!.siteId, false) + } + + fun setArriveAtEndStation() { + if (!checkCurrentTask()) { + ToastUtils.showShort("无任务!") + return + } +// arriveSite(mCurrentTaskAndOrder?.endSite!!.siteId, true) + arriveTerminal() + } + + fun toStartTask() { + if (!checkCurrentTask()) { + ToastUtils.showShort("无任务!") + return + } + + //当前订单状态若为20 , 则使用的lineId为订单信息的 + mCurrentTaskAndOrder?.let { startTask( + if (it.order != null && it.order!!.orderStatus >= TaxiOrderStatusEnum.ArriveAtStart.code) + it.order!!.orderLine + else + it.lineId + ) } + } + + /** + * 测试开启自动驾驶 + */ + fun setOnTheWayToEndStation() { + if (!checkCurrentOrder()) { + ToastUtils.showShort("订单状态不匹配该操作!") + } + startAutoPilot() + } + + private val mGoAutopilotStatusListener: IMoGoAutopilotStatusListener = object : IMoGoAutopilotStatusListener { override fun onAutopilotDockerInfo(dockerVersion: String) {} override fun onAutopilotRouteLineId(lineId: Long) {} @@ -222,50 +779,48 @@ object TaxiTaskModel { override fun onAutopilotStatusResponse(autoPilotStatusInfo: AutopilotStatusInfo) {} override fun onAutopilotStatusResponse(state: Int) { if (state == IMoGoAutopilotStatusListener.STATUS_AUTOPILOT_RUNNING) { - mADASStatusCallback?.onAutopilotRunning() - if ((QueryCurrentTaskRespBean.isOrderOnTheWayToEnd(mCurrentTaskWithOrder))) { + if (mADASStatusCallback != null) { + mADASStatusCallback!!.onAutopilotRunning() + } + if ((mCurrentTaskAndOrder != null && mCurrentTaskAndOrder!!.order != null + && TaxiOrderStatusEnum.OnTheWayToEnd.code == mCurrentTaskAndOrder!!.order!!.orderStatus) + ) { TaxiAnalyticsManager.getInstance().triggerStartAutopilotEvent( isRestartAutopilot, true, - mCurrentTaskWithOrder!!.order!!.orderStartSite!!.siteName, - mCurrentTaskWithOrder!!.order!!.orderEndSite!!.siteName, - mCurrentTaskWithOrder!!.lineId, - mCurrentTaskWithOrder!!.order!!.orderNo + mCurrentTaskAndOrder!!.order!!.orderStartSite!!.siteName, + mCurrentTaskAndOrder!!.order!!.orderEndSite!!.siteName, + mCurrentTaskAndOrder!!.lineId, + mCurrentTaskAndOrder!!.order!!.orderNo ) if (FunctionBuildConfig.isDemoMode) { // 当美化模式(演示模式)开启时: 订单对应自动驾驶开启后,置true FunctionBuildConfig.isIgnoreConditionsDrawAutopilotTrajectoryData = true - CallerAutoPilotControlManager.setIgnoreConditionDraw(true) - CallerAutoPilotControlManager.setIPCDemoMode(true) + setIgnoreConditionDraw(true) + setIPCDemoMode(true) d( - TAG, + SceneConstant.M_TAXI + TAG, "美化模式-ignore:置为true(到达出发点且已开启自动驾驶)" ) } } } else if (state == IMoGoAutopilotStatusListener.STATUS_AUTOPILOT_ENABLE) { if ((FunctionBuildConfig.isDemoMode - && checkCurrentTaskCondition() - && (QueryCurrentTaskRespBean.isOrderOnTheWayToEnd( - mCurrentTaskWithOrder - ) - || QueryCurrentTaskRespBean.isOrderArriveAtEnd( - mCurrentTaskWithOrder - ))) + && checkCurrentTask() + && ((getCurOrderStatus() === TaxiOrderStatusEnum.OnTheWayToEnd + || getCurOrderStatus() === TaxiOrderStatusEnum.ArriveAtEnd))) ) { // 当美化模式(演示模式)开启时:且有订单、且为去往目的地状态,维持自动驾驶icon开启状态 return } - mADASStatusCallback?.onAutopilotEnable() + if (mADASStatusCallback != null) { + mADASStatusCallback!!.onAutopilotEnable() + } } else if (state == IMoGoAutopilotStatusListener.STATUS_AUTOPILOT_DISABLE) { if ((FunctionBuildConfig.isDemoMode - && checkCurrentTaskCondition() - && (QueryCurrentTaskRespBean.isOrderOnTheWayToEnd( - mCurrentTaskWithOrder - ) - || QueryCurrentTaskRespBean.isOrderArriveAtEnd( - mCurrentTaskWithOrder - ))) + && checkCurrentTask() + && ((getCurOrderStatus() === TaxiOrderStatusEnum.OnTheWayToEnd + || getCurOrderStatus() === TaxiOrderStatusEnum.ArriveAtEnd))) ) { // 当美化模式(演示模式)开启时:且有订单、且为去往目的地状态,维持自动驾驶icon开启状态 return @@ -275,43 +830,46 @@ object TaxiTaskModel { } } else if (state == IMoGoAutopilotStatusListener.STATUS_PARALLEL_DRIVING) { if (FunctionBuildConfig.isDemoMode) { - if ((checkCurrentTaskCondition() - && (QueryCurrentTaskRespBean.isOrderOnTheWayToEnd( - mCurrentTaskWithOrder - ) - || QueryCurrentTaskRespBean.isOrderArriveAtEnd( - mCurrentTaskWithOrder - ))) - ) { //订单中 + if ((checkCurrentTask() + && (getCurOrderStatus() === TaxiOrderStatusEnum.OnTheWayToEnd + || getCurOrderStatus() === TaxiOrderStatusEnum.ArriveAtEnd)) + ) { //订单中 // 当美化模式(演示模式)开启时:且有订单、且为去往目的地状态,维持自动驾驶icon开启状态 } else { //美化模式下没订单,显示人工驾驶 - mADASStatusCallback?.onAutopilotDisable() + if (mADASStatusCallback != null) { + mADASStatusCallback!!.onAutopilotDisable() + } } return } - mADASStatusCallback?.onParallelDrivingStatus() + if (mADASStatusCallback != null) { + mADASStatusCallback!!.onParallelDrivingStatus() + } } } override fun onAutopilotSNRequest() {} override fun onAutopilotArriveAtStation(arrivalNotification: ArrivalNotification?) { - i(TAG, "onAutopilotArriveAtStation = ${arrivalNotification.toString()}") - if (arrivalNotification == null || !checkCurrentTaskCondition() || - mCurrentTaskWithOrder?.currentStatus == TaskStatusEnum.CompleteTask.code - ) { + i( + SceneConstant.M_TAXI + TAG, + "onAutopilotArriveAtStation = " + arrivalNotification.toString() + ) + if (arrivalNotification == null || !checkCurrentTask() || + mCurrentTaskAndOrder!!.currentStatus == TaskStatusEnum.CompleteTask.code) { i( - TAG, "onAutopilotArriveAtStation = arrivalNotification or task null" + - "or task currentStatus = ${mCurrentTaskWithOrder?.currentStatus}" + SceneConstant.M_TAXI + TAG, + "onAutopilotArriveAtStation = arrivalNotification or task null" + + "or task currentStatus = ${mCurrentTaskAndOrder!!.currentStatus}" ) return } - autopilotArriveAtStation() + arriveTerminal() if (FunctionBuildConfig.isDemoMode) { // 当美化模式(演示模式)开启时: 到达目的地,置false // 2022.10.08 到达目的地时候取消自动起自驾, 服务完成取消引导线和自动驾驶按钮状态 // FunctionBuildConfig.isIgnoreConditionsDrawAutopilotTrajectoryData = false; // CallerAutoPilotManager.INSTANCE.setIgnoreConditionDraw(false); - CallerAutoPilotControlManager.setIPCDemoMode(false) + setIPCDemoMode(false) d(SceneConstant.M_TAXI + TAG, "美化模式-ignore:置为false(到达目的地)") } } @@ -321,127 +879,119 @@ object TaxiTaskModel { override fun onSystemStatus(statusInf: SsmInfo.SsmStatusInf) {} } - private val mMogoStatusChangedListener: IMogoStatusChangedListener = - IMogoStatusChangedListener { descriptor, isTrue -> - // VR mode变更回调 - if (StatusDescriptor.VR_MODE == descriptor) { - mControllerStatusCallback?.onVRModeChanged(isTrue) - } + private fun arriveTerminal() { + if (!checkCurrentTask()) return + i( + SceneConstant.M_TAXI + TAG, + "onAutopilotArriveAtStation = arriveTerminal() = ${mCurrentTaskAndOrder!!.endSite}" + ) + val endSite = mCurrentTaskAndOrder!!.endSite + if (endSite != null) { + arriveSite(endSite.siteId, true) } + } - // 自车定位 - private val mMapLocationListener: IMoGoChassisLocationGCJ02Listener = - object : IMoGoChassisLocationGCJ02Listener { - override fun onChassisLocationGCJ02(mogoLocation: MogoLocation?) { - //位置变化时,通过围栏判断是否到达x点 - if (null == mogoLocation) return - - if (mDriveToNearestStationTask != null) { - judgeUntruthStation(mDriveToNearestStationTask, mogoLocation) - } - - if (checkCurrentTaskCondition()) { - judgeTaskStartStation(mogoLocation) - judgeTaskEndSiteStation(mogoLocation) - } - - mControllerStatusCallback?.onCarLocationChanged(mogoLocation) - } - } - - private val mMogoAutopilotPlanningListener: IMoGoPlanningRottingListener = + private val moGoAutopilotPlanningListener: IMoGoPlanningRottingListener = object : IMoGoPlanningRottingListener { override fun onAutopilotRotting(globalPathResp: GlobalPathResp?) { - globalPathResp?.wayPointsList?.also { + if (null != globalPathResp && globalPathResp.wayPointsList != null) { d( - TAG, "getWayPointsList.Size = ${globalPathResp.wayPointsList.size}" + SceneConstant.M_TAXI + TAG, ("getWayPointsList = " + + globalPathResp.wayPointsList.size) ) - if (it.size > 0) { - // 本地计算全路径长度(实时更新剩余距离,剩余时间,预计到达时间) - if (checkCurrentTaskCondition()) { - d(TAG, "--------本地开始计算全路径数据---------- ") - //转换成高德坐标系 - if (mCurrentTaskRoutePointsGcj!!.size > 0) { - mCurrentTaskRoutePointsGcj.clear() - } - mCurrentTaskRoutePointsGcj.addAll( - coordinateConverterWgsToGcjLocations( - mContext, - it - ) - ) - // MAP返回route时关闭高德相关的 - AmapNaviToDestinationModel.getInstance(mContext).destroyAmaNavi() - mOrderStatusCallback?.onNaviToEnd(false, false) - } - } + } + if (null != globalPathResp && globalPathResp.wayPointsList.size > 0) { + updateOrderRouteInfo(globalPathResp.wayPointsList) } } } - private val mAdasStartAutopilotFailureListener: OchAdasStartFailureCallback = - object : OchAdasStartFailureCallback { - override fun onStartAutopilotFailure( - startFailedCode: String, - startFailedMessage: String - ) { - TaxiAnalyticsManager.getInstance() - .triggerStartAutopilotFailureEventByAdas(startFailedCode, startFailedMessage) - if (mADASStatusCallback != null && !FunctionBuildConfig.isDemoMode) { - e( - TAG, - "onStartAutopilotFailure: startFailedMessage=$startFailedMessage" - ) - mADASStatusCallback?.onStartAdasFailure() - } + /** + * 设置路径规划起终点 + * + */ + fun setRouteLineMarker() { + val curTaskAndOrder = getCurTaskAndOrder() + if (curTaskAndOrder != null) { + if (curTaskAndOrder.startSite == null || curTaskAndOrder.endSite == null) { + cleanLineMarker() + return } - } - - private val mMogoOnSocketMessageListener = - object : IMogoOnMessageListener { - override fun target(): Class { - return OCHOperationalMessage::class.java - } - - override fun onMsgReceived(obj: OCHOperationalMessage) { - if (obj == null) { - d(TAG, "onMsgReceived = null") - return - } - d(TAG, "onMsgReceived = $obj.message") - OCHSocketMessageManager.pushAppOperationalMsgBox( - obj.pushTimeStamp, - obj.message, OCHSocketMessageManager.OPERATION_SYSTEM - ) - } - } - - //监听网络变化,避免启动机器时无网导致无法更新订单信息 - private val mNetWorkIntentListener: IMogoIntentListener = - IMogoIntentListener { intentStr, _ -> - d(TAG, "mNetWorkIntentListener: onIntentReceived=$intentStr") - if ((ConnectivityManager.CONNECTIVITY_ACTION == intentStr)) { - if (NetworkUtils.isConnected(mContext)) { - loginService?.queryLoginStatusByNet() - } - } - } - - private val localCalculateDistanceListener: IDistanceListener = object : IDistanceListener { - override fun distanceCallback(lastSumLength: Float) { - val lastTime = lastSumLength / TaxiUnmannedConst.TAXI_AVERAGE_SPEED * 3.6 //秒 - d( - TAG, - "dynamicCalculateRouteInfo: lastSumLength=$lastSumLength, lastTime=$lastTime, threadName=Thread.currentThread().name" + val startStation = LatLng( + curTaskAndOrder.startSite!!.gcjLat, + curTaskAndOrder.startSite!!.gcjLon ) - mOrderStatusCallback?.onCurrentOrderDistToEndChanged( + val endStation = LatLng( + curTaskAndOrder.endSite!!.gcjLat, + curTaskAndOrder.endSite!!.gcjLon + ) + if (mAutopilotPlanningCallback != null) { + mAutopilotPlanningCallback!!.setLineMarker(startStation, endStation) + } + } + } + + private fun cleanLineMarker() { + if (mAutopilotPlanningCallback != null) { + mAutopilotPlanningCallback!!.setLineMarker(null, null) + } + } + + /** + * 计算全路径长度,以及实时更新剩余距离,剩余时间,预计时间 + * + * @param models + */ + fun updateOrderRouteInfo(models: List) { + if (models.isEmpty()) return + if (mCurrentTaskAndOrder == null || mCurrentTaskAndOrder!!.startSite == null + || mCurrentTaskAndOrder!!.endSite == null) return + d(SceneConstant.M_TAXI + TAG, "--------计算出sumLength开始---------- ") + + //转换成高德坐标系 + if (mRoutePoints!!.size > 0) { + mRoutePoints.clear() + } + mRoutePoints.addAll(coordinateConverterWgsToGcjLocations(mContext, models)) + startDynamicCalculateRouteInfo() + } + + private fun startDynamicCalculateRouteInfo() { + d( + SceneConstant.M_TAXI + TAG, + "--------mCurrentTaskAndOrder---------- $mCurrentTaskAndOrder" + ) + d(SceneConstant.M_TAXI + TAG, "--------mRoutePoints.size---------- " + mRoutePoints!!.size) + AmapNaviToDestinationModel.getInstance(mContext).destroyAmaNavi() + if (mOrderStatusCallback != null) { + mOrderStatusCallback!!.onNaviToEnd(false, false) + } + } + + private fun updateDistance(lastSumLength: Float) { + val lastTime = lastSumLength / TaxiUnmannedConst.TAXI_AVERAGE_SPEED * 3.6 //秒 + d( + SceneConstant.M_TAXI + "dynamicCalculateRouteInfo", + ("---lastSumLength: " + lastSumLength + "----lastTime : " + lastTime + + " thread = " + Thread.currentThread().name) + ) + if (mOrderStatusCallback != null) { + mOrderStatusCallback!!.onCurrentOrderDistToEndChanged( lastSumLength.toLong(), lastTime.toLong() ) } } - private val localCalculateTrajectoryListener: ITrajectoryListener = + private val distanceListener: IDistanceListener = object : IDistanceListener { + override fun distanceCallback(distance: Float) { + updateDistance( + distance + ) + } + } + + private val trajectoryListener: ITrajectoryListener = object : ITrajectoryListener { override fun trajectoryCallback( routeArrivied: MutableList, @@ -478,726 +1028,15 @@ object TaxiTaskModel { } } - private fun autopilotArriveAtStation() { - if (!checkCurrentTaskCondition()) return - i( - TAG, - "autopilotArriveAtStation = ${mCurrentTaskWithOrder?.endSite}" - ) - mCurrentTaskWithOrder?.endSite?.also { - submitArriveSite(it.siteId, true) - } - } - - /** - * 到站(起点、终点)上报后端 - * @siteId : 站点id - * @isArriveAtEndSite: true 终点, false 起点 - */ - fun submitArriveSite(siteId: Long, isArriveAtEndSite: Boolean) { - i(TAG, message = "submitArriveSite: siteId=$siteId isArriveAtEndSite=$isArriveAtEndSite") - TaxiTaskWithOrderServiceManager.arriveSite( - mContext, - siteId, - object : OchCommonServiceCallback { - override fun onSuccess(data: BaseData?) { - if (data == null || data.code != 0) return - d(TAG, "submitArriveSite-onSuccess data=" + GsonUtil.jsonFromObject(data)) - mDriveToNearestStationTask = null - if (isArriveAtEndSite) { - updateLocalCalculateStation() - //到站后不再调用取消自驾. 原因是取消自驾,D档位会溜车 - //cancelAutopilot() - } - } - - override fun onFail(code: Int, msg: String?) { - d(TAG, "code=$code msg=$msg") - } - }) - } - - /** - * 检测当前任务的必备条件: - * 1.有当前任务 - * 2.有任务起点 - * 3.有任务终点 - */ - fun checkCurrentTaskCondition(): Boolean { - return mCurrentTaskWithOrder != null && mCurrentTaskWithOrder!!.startSite != null - && mCurrentTaskWithOrder!!.endSite != null - } - - fun startQueryCurrentTaskWithOrderLoop() { - if (mQueryTaskWithOrderDisposable != null - && !mQueryTaskWithOrderDisposable!!.isDisposed - ) { - return - } - i(TAG, "startQueryCurrentTaskWithOrderLoop()") - mQueryTaskWithOrderDisposable = Observable.interval( - TaxiUnmannedConst.LOOP_DELAY, - TaxiUnmannedConst.LOOP_PERIOD_2S, - TimeUnit.MILLISECONDS - ) - .map { aLong: Long -> aLong + 1 } - .subscribeOn(Schedulers.io()) - .observeOn(AndroidSchedulers.mainThread()) - .subscribe { queryCurrentTaskOnce() } - } - - fun stopQueryCurrentTaskWithOrderLoop() { - if (mQueryTaskWithOrderDisposable != null) { - i(TAG, "stopQueryCurrentTaskWithOrderLoop()") - mQueryTaskWithOrderDisposable?.dispose() - mQueryTaskWithOrderDisposable = null - } - } - - /** - * 查询当前车辆的任务和对应绑定的订单 - */ - private fun queryCurrentTaskOnce() { - if (!LoginStatusManager.isLogin()) { - d(TAG, "queryCurrentTaskOnce: 当前未登陆,跳过本次查询") - return - } - - TaxiTaskWithOrderServiceManager.queryCurrentTask( - AbsMogoApplication.getApp().applicationContext, - object : OchCommonServiceCallback { - override fun onSuccess(data: QueryCurrentTaskRespBean?) { - if (data?.data == null) { - d( - TAG, - "queryCurrentTaskOnce onSuccess: data.code != 0 || data === null || data.data === null" - ) - return - } - val result: QueryCurrentTaskRespBean.Result = data.data!! - d( - TAG, - "queryCurrentTaskOnce onSuccess:result=${GsonUtil.jsonFromObject(result)}" - ) - d( - TAG, - "queryCurrentTaskOnce onSuccess:mCurrentTaskWithOrder=${ - GsonUtil.jsonFromObject(mCurrentTaskWithOrder) - }" - ) - - //本地根据订单 orderNo 去查询下(乘客取消订单) - if (mCurrentTaskWithOrder != null - && mCurrentTaskWithOrder?.order != null - && result != null && result.order == null - ) { - d( - TAG, - "queryCurrentTaskOnce: result order is empty, query order by orderNo!" - ) - queryOrderByOrderNo(mCurrentTaskWithOrder!!.order!!.orderNo) - return - } - - //订单或者伪任务更新, 都去刷新下界面 - if (mCurrentTaskWithOrder == null - || mCurrentTaskWithOrder!! != result - ) { - d(TAG, "queryCurrentTaskOnce: 更新本地数据") - if (result?.endSite == null && result?.order == null) { - mCurrentTaskWithOrder = null - } - - //当前任务完成且订单状态到达乘客上车点, 则立马去拉取任务 不再等30s,否则送驾任务要等30s后才能去执行 - if (result?.currentStatus == TaskStatusEnum.CompleteTask.code) { - mTaxiTaskCallback?.onTaskCompleted( - QueryCurrentTaskRespBean.isOrderArriveAtStart( - result - ), - result.endSite!!.siteId - ) - } - - updateLocalCalculateStation() - - //达到终点后查询全程里程和用时 - if (QueryCurrentTaskRespBean.isOrderArriveAtEnd(result)) { - d(TAG, "queryCurrentTaskOnce ArriveAtEnd") - mTaxiTaskCallback?.onOrderArriveAtEnd(result.order!!.orderNo) - } - - //根据lineId集合去查轨迹集合, 返回的只是接驾任务的line集合, 没有送驾任务 - var linesIds = arrayListOf() - linesIds.add(result.lineId) - result.order?.also { - linesIds.addAll(it.planningLines) - linesIds.add(it.orderLine) - } - queryTaskTrajectoryByLineIds(linesIds.toTypedArray(), result.lineId) - - //自动去启动自驾 - if (result.currentStatus == TaskStatusEnum.GetTask.code && - result.taskType <= TaskTypeEnum.ToOrderStartTask.code - ) { - if (result.order == null || result.order!!.orderStatus < TaxiOrderStatusEnum.ArriveAtStart.code) { - d(TAG, "queryCurrentTaskOnce autoStartDriving") - autoStartDriving() - } - } - } - } - - override fun onFail(code: Int, msg: String?) { - d(TAG, "queryCurrentTaskOnce onFail: code=$code, msg=$msg") - } - }) - } - - fun updateLocalCalculateStation() { - if (mCurrentTaskWithOrder == null) return - if (mCurrentTaskWithOrder!!.startSite != null && mCurrentTaskWithOrder!!.endSite != null - && mCurrentTaskWithOrder!!.currentStatus <= TaskStatusEnum.StartTask.code - ) { - val curTaskAndOrder = getCurTaskAndOrder() ?: return - if (curTaskAndOrder.startSite != null && curTaskAndOrder.endSite != null) { - val startStation = MogoLocation() - startStation.longitude = curTaskAndOrder.startSite!!.gcjLon - startStation.latitude = curTaskAndOrder.startSite!!.gcjLat - val endStation = MogoLocation() - endStation.longitude = curTaskAndOrder.endSite!!.gcjLon - endStation.latitude = curTaskAndOrder.endSite!!.gcjLat - setStationPoint(startStation, endStation, curTaskAndOrder.lineId) - } - } else { - setStationPoint(null, null, -1L) - } - } - - fun queryOrderByOrderNo(orderNo: String) { - TaxiTaskWithOrderServiceManager.queryCarOrderByOrderNo(mContext, orderNo, - object : OchCommonServiceCallback { - override fun onSuccess(data: QueryCarOrderByNoRespBean?) { - d(TAG, "queryOrderByOrderNo onSuccess: data=${GsonUtil.jsonFromObject(data)}") - if (data == null) return - when (data.data.orderStatus) { - TaxiOrderStatusEnum.Cancel.code -> { - mTaxiTaskCallback?.onOrderCancel() - //更新本地标志位 - mCurrentTaskWithOrder?.order = null - } - - TaxiOrderStatusEnum.ArriveAtEnd.code -> { - mTaxiTaskCallback?.onOrderTotalMileAndDurationChanged( - data.data.mileage, - data.data.duration.toInt() - ) - } - - TaxiOrderStatusEnum.JourneyCompleted.code -> { - mTaxiTaskCallback?.onOrderJourneyCompleted() - //更新本地标志位 - mCurrentTaskWithOrder?.order = null - } - } - } - - override fun onFail(code: Int, msg: String?) { - d( - TAG, - "queryOrderByOrderNo: code=$code,msg=$msg" - ) - } - }) - } - - fun prepareNextTask(siteId: Long) { - TaxiTaskWithOrderServiceManager.prepareTask( - mContext, - siteId, - object : OchCommonServiceCallback { - override fun onSuccess(data: PrepareTaskRespBean?) { - d( - TAG, - "prepareNextTask onSuccess:${GsonUtil.jsonFromObject(data)}, " + - "isCarServingStatus = ${TaxiCarServingStatusManager.isCarServingStatus()}" - ) - if (data?.data == null) return - //去下载轨迹, 下发给工控机下载 - queryTaskTrajectoryByLineIds( - Array(1) { data.data!!.lineId }, - data.data!!.lineId - ) - } - - override fun onFail(code: Int, msg: String?) { - d(TAG, "prepareNextTask onFail: code=$code ,msg=$msg") - if (LoginStatusManager.isLogin() && TaxiCarServingStatusManager.isCarServingStatus()) { - startPrepareTask120S(siteId) - } - } - }) - } - - fun startPrepareTask120S(siteId: Long) { - UiThreadHandler.postDelayed({ - prepareNextTask(siteId) - }, TaxiUnmannedConst.TIMER_PREPARE_TASK_INTERVAL_120S) - } - - /** - * 查询当前任务的轨迹 - */ - fun queryTaskTrajectoryByLineIds(planningLineIds: Array, currentTaskLineId: Long) { - TaxiTaskWithOrderServiceManager.queryTrajectoryByLindIds( - mContext, - planningLineIds, - object : OchCommonServiceCallback { - override fun onSuccess(data: TrajectoryListRespBean?) { - d( - TAG, - "queryTaskTrajectoryByLineIds onSuccess: ${GsonUtil.jsonFromObject(data?.data)}" - ) - data?.data?.also { - mTaskTrajectoryList.addAll(it) - mCurrentTaskTrajectory = it.first { currentTaskLineId == it.lineId } - } - mTaxiTaskCallback?.onTaskTrajectoryDataChanged(data) - } - - override fun onFail(code: Int, msg: String?) { - d(TAG, "queryTaskTrajectoryByLineIds onFail: code=$code, msg=$msg") - } - }) - } - - // 获取当前订单状态 - fun getCurOrderStatus(): TaxiOrderStatusEnum? { - if (mCurrentTaskWithOrder == null) TaxiOrderStatusEnum.None - val order: OrderDetail = mCurrentTaskWithOrder!!.order!! - return valueOf(order.orderStatus) - } - - private fun getCurTaskStatus(): Int? { - if (mCurrentTaskWithOrder == null) TaskStatusEnum.None - return mCurrentTaskWithOrder?.currentStatus - } - - fun getCurTaskAndOrder(): QueryCurrentTaskRespBean.Result? { - return mCurrentTaskWithOrder - } - - fun getCurUntruthTask(): StartServiceRespBean.Result? { - return mDriveToNearestStationTask - } - - fun getCurrentOrderTrajectoryList(): MutableList? { - return mTaskTrajectoryList - } - - fun getCurrentTaskTrajectory(): TrajectoryListRespBean.Result? { - return mCurrentTaskTrajectory - } - - //更新本地currentOrder信息,并保存订单到本地避免车机重启丢失数据 - private fun updateNativeCurrentOrder(data: QueryCurrentTaskRespBean.Result?) { - if (data == null) { - return - } - mCurrentTaskWithOrder = data - - SharedPrefsMgr.getInstance(mContext!!).putString( - TaxiUnmannedConst.SP_KEY_OCH_TAXI_ORDER, - GsonUtil.jsonFromObject(data) - ) - - val currentOrder = mCurrentTaskWithOrder!!.order - - if (currentOrder != null) { - if (currentOrder!!.orderStatus == TaxiOrderStatusEnum.OnTheWayToEnd.code) { - if (FunctionBuildConfig.isDemoMode) { - // 当美化模式(演示模式)开启时: 订单对应自动驾驶开启后,置true - FunctionBuildConfig.isIgnoreConditionsDrawAutopilotTrajectoryData = true - CallerAutoPilotControlManager.setIgnoreConditionDraw(true) - CallerAutoPilotControlManager.setIPCDemoMode(true) - d(SceneConstant.M_TAXI + TAG, "美化模式-ignore:置为true(更新本地order信息)") - } - updateAutopilotControlParameters() - } - if (currentOrder!!.orderStatus == TaxiOrderStatusEnum.ArriveAtEnd.code) { - if (FunctionBuildConfig.isDemoMode) { - d(SceneConstant.M_TAXI + TAG, "setIPCDemoMode:false") - CallerAutoPilotControlManager.setIPCDemoMode(false) - } - clearAutopilotControlParameters() - } - } else { - if (FunctionBuildConfig.isDemoMode) { - d(SceneConstant.M_TAXI + TAG, "setIPCDemoMode:false") - CallerAutoPilotControlManager.setIPCDemoMode(false) - } - clearAutopilotControlParameters() - } - } - - /** - * 将业务订单信息保存,鹰眼可取用 - */ - private fun updateAutopilotControlParameters() { - val parameters = initAutopilotControlParameters() - if (null == parameters) { - e(SceneConstant.M_TAXI + TAG, "AutopilotControlParameters is empty.") - return - } - d(SceneConstant.M_TAXI + TAG, "AutopilotControlParameters is update.") - updateAutopilotControlParameters(parameters) - } - - private fun clearAutopilotControlParameters() { - d(SceneConstant.M_TAXI + TAG, "AutopilotControlParameters is clear.") - updateAutopilotControlParameters(null) - } - - fun updateUntruthTask(untruthTask: StartServiceRespBean.Result?) { - mDriveToNearestStationTask = untruthTask - } - - //清除任务订单信息 - fun clearCurrentOCHOrder() { - mCurrentTaskWithOrder = null - clearAutopilotControlParameters() - TaxiTrajectoryManager.getInstance().syncTrajectoryInfo() - SharedPrefsMgr.getInstance(mContext!!).remove(TaxiUnmannedConst.SP_KEY_OCH_TAXI_ORDER) - isRestartAutopilot = false - if (FunctionBuildConfig.isDemoMode) { - // 当美化模式(演示模式)开启时: 取消或订单已完成时,置false - FunctionBuildConfig.isIgnoreConditionsDrawAutopilotTrajectoryData = false - CallerAutoPilotControlManager.setIgnoreConditionDraw(false) - CallerAutoPilotControlManager.setIPCDemoMode(false) - d(SceneConstant.M_TAXI + TAG, "美化模式-ignore:置为false(已完成or清除当前订单)") - } - } - - private fun checkCurrentOrder(): Boolean { - return mCurrentTaskWithOrder != null && mCurrentTaskWithOrder!!.order != null - } - - /** - * 以当前订单为基础,开启自动驾驶 - */ - @ChainLog( - linkChainLog = ChainConstant.CHAIN_TYPE_SOCKET_AUTOPILOT, - linkCode = ChainConstant.CHAIN_SOURCE_ADAS, - nodeAliasCode = ChainConstant.CHAIN_CODE_OCH_TAXI_START_AUTOPILOT, - paramIndexes = [-1] - ) - fun startAutoPilot() { - if (!checkCurrentTaskCondition()) { - e(SceneConstant.M_TAXI + TAG, "no order or order is empty.") - ToastUtils.showShort("当前订单不存在或异常!") - return - } - - if (mCurrentTaskTrajectory == null) { - e(SceneConstant.M_TAXI + TAG, "no order or order is empty.") - ToastUtils.showShort("轨迹信息不存在!") - } - - //根据开关和后台是否发布轨迹启动自驾 - if (FunctionBuildConfig.isPassStartAutopilotCommand && mCurrentTaskTrajectory != null && TextUtils.isEmpty( - mCurrentTaskTrajectory!!.csvFileUrl - ) - && TextUtils.isEmpty(mCurrentTaskTrajectory!!.csvFileUrlDPQP) - ) { - ToastUtils.showLong("无发布轨迹, 请发布后重试") - e( - SceneConstant.M_TAXI + TAG, "isPassStartAutopilotCommand = " + - FunctionBuildConfig.isPassStartAutopilotCommand - + "busRoutesResult.csvFileUrl = " + mCurrentTaskTrajectory!!.csvFileUrl - + "busRoutesResult.csvFileUrlDPQP = " + mCurrentTaskTrajectory!!.csvFileUrlDPQP - ) - return - } - e( - SceneConstant.M_TAXI + TAG, "isPassStartAutopilotCommand = " + - FunctionBuildConfig.isPassStartAutopilotCommand - ) - if (!FunctionBuildConfig.isDemoMode && !OCHAdasAbilityManager.getInstance().autopilotAbilityStatus) { - ToastUtils.showLong( - OCHAdasAbilityManager.getInstance().autopilotUnAbilityReason + - ", 请稍候重试" - ) - TaxiAnalyticsManager.getInstance().triggerUnableStartAPReasonEvent( - mCurrentTaskWithOrder!!.startSite!!.siteName, - mCurrentTaskWithOrder!!.endSite!!.siteName, - mCurrentTaskWithOrder!!.lineId.toString(), // todo 这里原来传的是订单号, 现在是任务没有订单号,传了路线id - OCHAdasAbilityManager.getInstance().autopilotUnAbilityReason - ) - return - } - - //点击开始自动驾驶按钮订单状态去流转, 不再与自动驾驶是否启动成功挂钩 - isRestartAutopilot = mCurrentTaskWithOrder!!.currentStatus != TaskStatusEnum.StartTask.code - - val parameters = initAutopilotControlParameters() - if (null == parameters) { - e(SceneConstant.M_TAXI + TAG, "AutopilotControlParameters is empty.") - return - } - CallerAutoPilotControlManager.startAutoPilot(parameters) - d( - SceneConstant.M_TAXI + TAG, "start autopilot with parameter: %s", - GsonUtil.jsonFromObject(parameters) - + " ,startSiteName=" + mCurrentTaskWithOrder?.startSite?.siteName - + " ,endSiteName=" + mCurrentTaskWithOrder?.endSite?.siteName - + "isRestartAutopilot = " + isRestartAutopilot - ) - TaxiAnalyticsManager.getInstance().triggerStartAutopilotEvent( - isRestartAutopilot, - false, - mCurrentTaskWithOrder!!.startSite!!.siteName, - mCurrentTaskWithOrder!!.endSite!!.siteName, - mCurrentTaskWithOrder!!.lineId, - if (mCurrentTaskWithOrder!!.order != null) mCurrentTaskWithOrder!!.order!!.orderNo else "" - ) - if (mControllerStatusCallback != null) { - mControllerStatusCallback!!.startOpenAutopilot() - } - } - - private fun initAutopilotControlParameters(): AutopilotControlParameters? { - if (!checkCurrentTaskCondition()) { - e(SceneConstant.M_TAXI + TAG, "no order or order is empty.") - return null - } - - if (mCurrentTaskTrajectory == null) { - e(SceneConstant.M_TAXI + TAG, "curTaskContrail is empty.") - return null - } - - val parameters = AutopilotControlParameters() - - val startWgsLon = mCurrentTaskWithOrder!!.startSite!!.wgs84Lon - val startWgsLat = mCurrentTaskWithOrder!!.startSite!!.wgs84Lat - val endWgsLon = mCurrentTaskWithOrder!!.endSite!!.wgs84Lon - val endWgsLat = mCurrentTaskWithOrder!!.endSite!!.wgs84Lat - parameters.vehicleType = BUSINESSTYPE - parameters.startName = mCurrentTaskWithOrder!!.startSite!!.siteName // 8.10 拼音首字母大写 改为直接传中文 - parameters.endName = mCurrentTaskWithOrder!!.endSite!!.siteName // 8.10 拼音首字母大写 改为直接传中文 - parameters.startLatLon = - AutopilotControlParameters.AutoPilotLonLat(startWgsLat, startWgsLon) - parameters.endLatLon = AutopilotControlParameters.AutoPilotLonLat(endWgsLat, endWgsLon) - if (parameters.autoPilotLine == null) { - parameters.autoPilotLine = AutopilotControlParameters.AutoPilotLine( - mCurrentTaskTrajectory!!.lineId, - mCurrentTaskTrajectory!!.lineName, - mCurrentTaskTrajectory!!.csvFileUrl, - mCurrentTaskTrajectory!!.csvFileMd5, - mCurrentTaskTrajectory!!.txtFileUrl, - mCurrentTaskTrajectory!!.txtFileMd5, - mCurrentTaskTrajectory!!.contrailSaveTime, - "", // todo 这里原来传的是carModel, 现在没有这个信息 - mCurrentTaskTrajectory!!.csvFileUrlDPQP, - mCurrentTaskTrajectory!!.csvFileMd5DPQP, - mCurrentTaskTrajectory!!.txtFileUrlDPQP, - mCurrentTaskTrajectory!!.txtFileMd5DPQP, - mCurrentTaskTrajectory!!.contrailSaveTimeDPQP - ) - } - return parameters - } - - //结束自动驾驶 - fun cancelAutopilot() { - try { - CallerAutoPilotControlManager.cancelAutoPilot() - d(SceneConstant.M_TAXI + TAG, "结束自动驾驶") - } catch (e: Exception) { - e.printStackTrace() - } - } - - //根据围栏判断,是否到达起点 - private fun judgeTaskStartStation(location: MogoLocation) { - if (checkCurrentTaskCondition()) { - val startSite = mCurrentTaskWithOrder!!.startSite ?: return - val startLon = startSite.gcjLon - val startLat = startSite.gcjLat - val distance = CoordinateUtils.calculateLineDistance( - startLon, startLat, - location.longitude, location.latitude - ).toDouble() - i(SceneConstant.M_TAXI + TAG, "judgeTaskStartStation() distance = $distance") - if (distance <= TaxiUnmannedConst.ARRIVE_AT_START_STATION_DISTANCE) { - submitArriveSite(startSite.siteId, false) - } - } - } - - - private fun judgeUntruthStation( - virtualTask: StartServiceRespBean.Result?, - currentLocation: MogoLocation - ) { - if (mDriveToNearestStationTask == null || virtualTask == null) return - val distance = CoordinateUtils.calculateLineDistance( - virtualTask.gcjLon, virtualTask.gcjLat, - currentLocation.longitude, currentLocation.latitude - ).toDouble() - i( - SceneConstant.M_TAXI + TAG, - "judgeEndStation() ${virtualTask.siteName} distance = $distance" - ) - if (distance <= TaxiUnmannedConst.ARRIVE_AT_START_STATION_DISTANCE) { // 15米内到站 - submitArriveSite(virtualTask.siteId, true) - } - } - - private fun startTask(lineId: Long) { - TaxiTaskWithOrderServiceManager.startTask( - mContext, - lineId, - object : OchCommonServiceCallback { - override fun onSuccess(data: BaseData?) { - d(SceneConstant.M_TAXI + TAG, GsonUtil.jsonFromObject(data)) - } - - override fun onFail(code: Int, msg: String?) { - d(SceneConstant.M_TAXI + TAG, "$code $msg") - } - - }) - } - - private fun judgeTaskEndSiteStation(currentLocation: MogoLocation) { - if (!checkCurrentTaskCondition()) { - return - } - val endSite = mCurrentTaskWithOrder!!.endSite ?: return - - val endLon = endSite.gcjLon - val endLat = endSite.gcjLat - val distance = CoordinateUtils.calculateLineDistance( - endLon, endLat, - currentLocation.longitude, currentLocation.latitude - ).toDouble() - i(SceneConstant.M_TAXI + TAG, "judgeEndStation() distance = $distance") - if (distance <= TaxiUnmannedConst.ARRIVE_AT_START_STATION_DISTANCE) { //1、当前位置和站点围栏15m内 - - //2、开始计算当前位置和站点的向量角度 < 90度 未经过 >90度 经过 - val stationAngle = DrivingDirectionUtils.getDegreeOfCar2Poi( - currentLocation.longitude, - currentLocation.latitude, - endLon, - endLat, currentLocation.heading.toInt() - ).toDouble() - i( - SceneConstant.M_TAXI + TAG, - "judgeEndStation() stationAngle = $stationAngle" - ) - - //3、刚过站且过站距离在15m内, 提交到站 - if (stationAngle > 90 && distance <= TaxiUnmannedConst.ARRIVE_AT_START_STATION_DISTANCE) { - if ((!checkCurrentTaskCondition() - || (getCurTaskStatus() == TaskStatusEnum.StartTask.code)) - ) { - i(SceneConstant.M_TAXI + TAG, "task null or TaskStatus = ${getCurTaskStatus()}") - return - } - i(SceneConstant.M_TAXI + TAG, "judgeEndStation() = 刚过站且在15m内") - submitArriveSite(endSite.siteId, true) - } - } - } - - - fun setArriveAtUntruthStation() { - if (mDriveToNearestStationTask == null) { - ToastUtils.showShort("无虚拟站点!") - return - } - submitArriveSite(mDriveToNearestStationTask!!.siteId, false) - } - - fun setArriveAtEndStation() { - if (!checkCurrentTaskCondition()) { - ToastUtils.showShort("无任务!") - return - } -// arriveSite(mCurrentTaskAndOrder?.endSite!!.siteId, true) - autopilotArriveAtStation() - } - - fun toStartTask() { - if (!checkCurrentTaskCondition()) { - ToastUtils.showShort("无任务!") - return - } - - //当前订单状态若为20 , 则使用的lineId为订单信息的 - mCurrentTaskWithOrder?.let { - startTask( - if (it.order != null && it.order!!.orderStatus >= TaxiOrderStatusEnum.ArriveAtStart.code) - it.order!!.orderLine - else - it.lineId - ) - } - } - - /** - * 测试开启自动驾驶 - */ - fun setOnTheWayToEndStation() { - if (!checkCurrentOrder()) { - ToastUtils.showShort("订单状态不匹配该操作!") - } - startAutoPilot() - } - - - /** - * 设置路径规划起终点 - */ - fun setRouteLineMarker() { - val curTaskAndOrder = getCurTaskAndOrder() - if (curTaskAndOrder != null) { - if (curTaskAndOrder.startSite == null || curTaskAndOrder.endSite == null) { - cleanLineMarker() - return - } - val startStation = LatLng( - curTaskAndOrder.startSite!!.gcjLat, - curTaskAndOrder.startSite!!.gcjLon - ) - val endStation = LatLng( - curTaskAndOrder.endSite!!.gcjLat, - curTaskAndOrder.endSite!!.gcjLon - ) - if (mAutopilotPlanningCallback != null) { - mAutopilotPlanningCallback!!.setLineMarker(startStation, endStation) - } - } - } - - private fun cleanLineMarker() { - if (mAutopilotPlanningCallback != null) { - mAutopilotPlanningCallback!!.setLineMarker(null, null) - } - } - // 登出 fun logout() { - loginService!!.loginOut( - getChassisLocationGCJ02().latitude, - getChassisLocationGCJ02().longitude - ) + loginService!!.loginOut(getChassisLocationGCJ02().latitude, getChassisLocationGCJ02().longitude) } //导航去订单终点目的地 fun startNaviToEndStation(isShow: Boolean) { - if (mCurrentTaskRoutePointsGcj == null) return - if (mCurrentTaskRoutePointsGcj.size > 0) { //使用自驾轨迹 + if (mRoutePoints == null) return + if (mRoutePoints.size > 0) { //使用自驾轨迹 if (mOrderStatusCallback != null) { mOrderStatusCallback!!.onNaviToEnd(false, isShow) } @@ -1206,15 +1045,45 @@ object TaxiTaskModel { mOrderStatusCallback!!.onNaviToEnd(true, true) } else { UiThreadHandler.postDelayed({ - if (mCurrentTaskRoutePointsGcj.size == 0 && mOrderStatusCallback != null) { + if (mRoutePoints.size == 0 && mOrderStatusCallback != null) { mOrderStatusCallback!!.onNaviToEnd(true, false) } }, 2000L) } } } + fun updateStation() { + if (mCurrentTaskAndOrder == null) return + if (mCurrentTaskAndOrder!!.startSite != null && mCurrentTaskAndOrder!!.endSite != null + && mCurrentTaskAndOrder!!.currentStatus <= TaskStatusEnum.StartTask.code){ + setStation() + }else{ + cleanStation() + } + } - fun autoStartDriving() { + private fun setStation() { + val curTaskAndOrder = getCurTaskAndOrder() ?: return + if (curTaskAndOrder.startSite != null && curTaskAndOrder.endSite != null) { + val startStation = MogoLocation() + startStation.longitude = curTaskAndOrder.startSite!!.gcjLon + startStation.latitude = curTaskAndOrder.startSite!!.gcjLat + val endStation = MogoLocation() + endStation.longitude = curTaskAndOrder.endSite!!.gcjLon + endStation.latitude = curTaskAndOrder.endSite!!.gcjLat + setStationPoint(startStation, endStation, curTaskAndOrder.lineId) + } + } + + private fun cleanStation() { + setStationPoint(null, null, -1L) + } + + fun updateOrderContrails(contrails: MutableList?) { + mOrderContrails = contrails + } + + fun autoStartDriving(){ //启动动画+文字 if (mControllerStatusCallback != null) { mControllerStatusCallback!!.startOpenAutopilotNonManual() @@ -1224,6 +1093,6 @@ object TaxiTaskModel { toStartTask() //状态流转 startAutoPilot() //自驾开启 VoiceNotice.showNotice("车辆正在自动开启自动驾驶") - }, START_AUTOPILOT_COUNTDOWN_INTERVAL) // 10s后开启自驾, 状态流转 + },COUNTDOWN_INTERVAL) // 10s后开启自驾, 状态流转 } } \ No newline at end of file diff --git a/OCH/taxi/unmanned-driver/src/main/java/com/mogo/och/taxi/utils/TaxiTrajectoryManager.java b/OCH/taxi/unmanned-driver/src/main/java/com/mogo/och/taxi/utils/TaxiTrajectoryManager.java index 11ea80ca52..34d7c687d8 100644 --- a/OCH/taxi/unmanned-driver/src/main/java/com/mogo/och/taxi/utils/TaxiTrajectoryManager.java +++ b/OCH/taxi/unmanned-driver/src/main/java/com/mogo/och/taxi/utils/TaxiTrajectoryManager.java @@ -6,12 +6,13 @@ import com.mogo.eagle.core.data.autopilot.AutopilotControlParameters; import com.mogo.eagle.core.function.call.autopilot.CallerAutoPilotControlManager; import com.mogo.eagle.core.utilcode.mogo.logger.CallerLogger; import com.mogo.eagle.core.utilcode.util.GsonUtils; -import com.mogo.och.taxi.bean.TrajectoryListRespBean; +import com.mogo.och.taxi.bean.ContrailListRespBean; import com.mogo.och.taxi.bean.OrderDetail; import com.mogo.och.taxi.bean.QueryCurrentTaskRespBean; +import com.mogo.och.taxi.bean.Site; import com.mogo.och.taxi.constant.TaskStatusEnum; import com.mogo.och.taxi.constant.TaxiUnmannedConst; -import com.mogo.och.taxi.ui.task.TaxiTaskModel; +import com.mogo.och.taxi.model.TaxiModel; import java.util.List; import java.util.concurrent.TimeUnit; @@ -66,7 +67,7 @@ public class TaxiTrajectoryManager { * 同步订单信息 */ public void syncTrajectoryInfo() { - QueryCurrentTaskRespBean.Result taskAndOrder = TaxiTaskModel.INSTANCE.getCurTaskAndOrder(); + QueryCurrentTaskRespBean.Result taskAndOrder = TaxiModel.INSTANCE.getCurTaskAndOrder(); if (taskAndOrder == null || taskAndOrder.getCurrentStatus() >= TaskStatusEnum.StartTask.getCode()) { CallerLogger.d(M_TAXI + TAG, "syncTrajectoryInfo() stop."); stopTrajReqLoop(); @@ -115,7 +116,7 @@ public class TaxiTrajectoryManager { } private void setupAutoPilotLine() { - QueryCurrentTaskRespBean.Result taskAndOrder = TaxiTaskModel.INSTANCE.getCurTaskAndOrder(); + QueryCurrentTaskRespBean.Result taskAndOrder = TaxiModel.INSTANCE.getCurTaskAndOrder(); if (taskAndOrder == null || taskAndOrder.getEndSite() == null) { CallerLogger.e(M_TAXI + TAG, @@ -128,7 +129,7 @@ public class TaxiTrajectoryManager { * 4、若不存在,说明当前的执行的任务是与订单无关的演练任务,通知下载加载当前任务的轨迹以及预加载订单轨迹集合的第一个 */ - final TrajectoryListRespBean.Result curTaskContrail = TaxiTaskModel.INSTANCE.getCurrentTaskTrajectory(); + final ContrailListRespBean.Result curTaskContrail = TaxiModel.INSTANCE.getCurTaskContrail(); if (curTaskContrail == null) return; long curLineId = taskAndOrder.getLineId(); @@ -156,20 +157,29 @@ public class TaxiTrajectoryManager { } final OrderDetail orderDetail = taskAndOrder.getOrder(); - TrajectoryListRespBean.Result preloadContrail = null; //预加载的轨迹 - final List orderContrails = TaxiTaskModel.INSTANCE.getCurrentOrderTrajectoryList(); + ContrailListRespBean.Result preloadContrail = null; //预加载的轨迹 + int preLoadIndex = -1; + + //包含接驾任务和送驾任务的轨迹, 且集合是有顺序的 , 最后一个是送驾任务轨迹 + final List orderContrails = TaxiModel.INSTANCE.getCurOrderContrails(); if (orderDetail != null && orderContrails != null && orderContrails.size() != 0 ){ for (int i = 0; i< orderContrails.size() ; i++){ if (orderContrails.get(i).getLineId() == curLineId){ //预加载轨迹是curLineId索引的下一个 int index = i + 1; - if (orderContrails.size()-1 >= index){ + if (orderContrails.size() == index){ + //说明找到的是集合最后一个, 最后一个为送驾轨迹,即送驾轨迹和当前的任务轨迹是一样的,不再预加载 + preLoadIndex = index; + break; + }else if (orderContrails.size()-1 >= index){ preloadContrail = orderContrails.get(index); + preLoadIndex = index; + break; } } } - if (preloadContrail == null){ - //不包含预加载轨迹直接是集合第一个 + + if (preLoadIndex == -1){ //说明当前任务轨迹在接驾/送驾轨迹集合里没有, 直接加载轨迹集合第一个 preloadContrail = orderContrails.get(0); } }