[清扫车]删除无用代码及其修改部分逻辑

This commit is contained in:
bxb
2023-01-29 11:28:08 +08:00
parent ab27f9ee44
commit 21a7e59b82
32 changed files with 746 additions and 1060 deletions

View File

@@ -1,26 +0,0 @@
package com.mogo.och.sweeper.bean;
import com.mogo.och.sweeper.constant.SweeperConst;
import java.util.UUID;
/**
* Created on 2021/9/16
*
* 上传车机心跳信息请求数据
*/
public class CarHeartbeatReqBean {
public String sn;
public double lon; //经度
public double lat; //纬度
public String msgId; //心跳信息唯一标识
public int interval; //上报间隔单位秒非必传默认60秒
public CarHeartbeatReqBean(String sn, double lon, double lat) {
this.sn = sn;
this.lon = lon;
this.lat = lat;
this.msgId = UUID.randomUUID().toString();
this.interval = (int) (SweeperConst.LOOP_PERIOD_60S / 1000);
}
}

View File

@@ -1,36 +0,0 @@
package com.mogo.och.sweeper.bean;
import com.mogo.cloud.passport.MoGoAiCloudClientConfig;
/**
* 查询下车乘客请求参数
*
* @author tongchenfei
*/
public class QueryLeaveAwayPassengersRequest {
private String sn;
private int seq; //站点在线路中的序号
private int siteId; //站点id
public QueryLeaveAwayPassengersRequest(int seq, int siteId) {
this.sn = MoGoAiCloudClientConfig.getInstance().getSn();
this.seq = seq;
this.siteId = siteId;
}
public void setSeq(int seq) {
this.seq = seq;
}
public void setSiteId(int siteId) {
this.siteId = siteId;
}
public int getSeq() {
return seq;
}
public int getSiteId() {
return siteId;
}
}

View File

@@ -1,60 +0,0 @@
package com.mogo.och.sweeper.bean;
import com.mogo.eagle.core.data.BaseData;
import java.util.List;
public
/**
* @author congtaowang
* @since 2021/3/26
*
* 到站查询下车乘客
*/
class QueryLeaveAwayPassengersResponse extends BaseData {
public Result data;
public static class Result {
public List< LeaveAwayPassenger > orders;
}
public static class LeaveAwayPassenger {
/**
* orderNo: 订单no
* orderStatus: 订单状态
* orderType订单类型0及时1预约
* bookingTime预计用车时间
* businessType订单运营类型 9:taxi10:bus
* startSiteId 起点站点id
* userPhone: 乘客联系方式
* startSitePoint开始站点坐标
* startSiteAddr开始地址
* endSiteId结束站点id
* endSitePoint结束站点坐标
* carNumber车牌号
* createTime: 创建时间
* startTime开始时间
* startSiteGcjPoint高精坐标
* endSiteGcjPoint
*/
//todo 目前是需要乘客电话来通知乘客下车 目前后台没有乘客信息userPhone
public String orderNo;
public int orderStatus;
public int orderType;
public long bookingTime;
public int businessType;
public int startSiteId;
public String passengerPhone;
public List<Double> startSitePoint;
public String startSiteAddr;
public int endSiteId;
public List<Double> endSitePoint;
public String carNumber;
public long createTime;
public long startTime;
public List< Double > startSiteGcjPoint;
public List< Double > endSiteGcjPoint;
}
}

View File

@@ -1,42 +0,0 @@
package com.mogo.och.sweeper.bean;
import com.mogo.cloud.passport.MoGoAiCloudClientConfig;
public
/**
* @author congtaowang
* @since 2021/3/22
*
* 小巴车运营状态请求参数
*/
class SweeperOperationStatusRequest {
private String sn;
private double lat;
private double lon;
public SweeperOperationStatusRequest(double lon, double lat) {
this.sn = MoGoAiCloudClientConfig.getInstance().getSn();
this.lat = lat;
this.lon = lon;
}
public void setLat(double lat) {
this.lat = lat;
}
public void setLon(double lon) {
this.lon = lon;
}
public String getSn() {
return sn;
}
public double getLat() {
return lat;
}
public double getLon() {
return lon;
}
}

View File

@@ -1,20 +0,0 @@
package com.mogo.och.sweeper.bean;
import com.mogo.eagle.core.data.BaseData;
/**
* @author congtaowang
* @since 2021/3/22
*
* 小巴车运营状态返回参数
*/
public class SweeperOperationStatusResponse extends BaseData {
public Result data;
public static class Result {
public int serviceStatus;//0:已收车1:已出车
}
}

View File

@@ -1,86 +0,0 @@
package com.mogo.och.sweeper.bean;
/**
* @author congtaowang
* @since 2021/3/23
* <p>
* 小巴订单
*/
public class SweeperOrderBean {
/**
* orderNo number
* passengerPhone string 下单用户电话
* startStationId integer 开始站点
* startStationName string
* endStationId integer 结束站点
* endStationName string
*/
private String orderNo;
private String passengerPhone;
private int startStationId;//乘客上车点
private String startStationName;
private String endStationName;
private int endStationId;//乘客下车点
public void setOrderNo(String orderNo) {
this.orderNo = orderNo;
}
public void setPassengerPhone(String passengerPhone) {
this.passengerPhone = passengerPhone;
}
public void setStartStationId(int startStationId) {
this.startStationId = startStationId;
}
public void setStartStationName(String startStationName) {
this.startStationName = startStationName;
}
public void setEndStationName(String endStationName) {
this.endStationName = endStationName;
}
public void setEndStationId(int endStationId) {
this.endStationId = endStationId;
}
public String getOrderNo() {
return orderNo;
}
public String getPassengerPhone() {
return passengerPhone;
}
public int getStartStationId() {
return startStationId;
}
public String getStartStationName() {
return startStationName;
}
public String getEndStationName() {
return endStationName;
}
public int getEndStationId() {
return endStationId;
}
@Override
public String toString() {
return "BusOrderBean{" +
"orderNo=" + orderNo +
", passengerPhone='" + passengerPhone + '\'' +
", startStationId=" + startStationId +
", startStationName='" + startStationName + '\'' +
", endStationName='" + endStationName + '\'' +
", endStationId=" + endStationId +
'}';
}
}

View File

@@ -1,23 +0,0 @@
package com.mogo.och.sweeper.bean;
import com.mogo.eagle.core.data.BaseData;
import java.util.List;
/**
* @author: wangmingjun
* @date: 2021/10/19
*/
public class SweeperOrdersResponse extends BaseData {
public Result data;
public static class Result{
public List<SweeperOrderBean> orders;
}
@Override
public String toString() {
return "BusOrdersResponse{" +
"data=" + data +
'}';
}
}

View File

@@ -1,61 +0,0 @@
package com.mogo.och.sweeper.bean;
import com.mogo.cloud.passport.MoGoAiCloudClientConfig;
/**
* @author congtaowang
* @since 2021/3/22
*
* 根据车机行驶线路站点信息
*/
public class SweeperQueryLineStationsRequest {
private String sn;
private double lat;
private double lon;
private boolean markDrivingStatus; // 默认falsetrue:是否需要返回站点的行驶状态对应返回的drivingStatus
// 0 - 关闭、1 - 启动
// public String status;
public SweeperQueryLineStationsRequest(double lon, double lat, boolean markDrivingStatus) {
this.sn = MoGoAiCloudClientConfig.getInstance().getSn();
this.lat = lat;
this.lon = lon;
this.markDrivingStatus = markDrivingStatus;
}
public boolean isMarkDrivingStatus() {
return markDrivingStatus;
}
public void setMarkDrivingStatus(boolean markDrivingStatus) {
this.markDrivingStatus = markDrivingStatus;
}
public void setLat(double lat) {
this.lat = lat;
}
public void setLon(double lon) {
this.lon = lon;
}
public String getSn() {
return sn;
}
public double getLat() {
return lat;
}
public double getLon() {
return lon;
}
// public BusOperationStatusRequest shutdown() {
// status = "0";
// return this;
// }
//
// public BusOperationStatusRequest launch() {
// status = "1";
// return this;
// }
}

View File

@@ -1,23 +0,0 @@
package com.mogo.och.sweeper.bean;
import com.mogo.eagle.core.data.BaseData;
import java.util.List;
/**
* @author: wangmingjun
* @date: 2022/2/9
*/
public class SweeperQueryLinesResponse extends BaseData {
public List<Result> data;
public static class Result {
public int lineId;//线路id
public String name;//线路名字
public int choose; // 1:绑定 2:未被绑定
public String startSiteName;//始发站名称
public String endSiteName;//终点名称
}
}

View File

@@ -1,17 +0,0 @@
package com.mogo.och.sweeper.bean;
import com.mogo.cloud.passport.MoGoAiCloudClientConfig;
/**
* @author: wangmingjun
* @date: 2021/10/18
*/
public class SweeperResetDrivingLineRequest {
public String sn;
public int lineId; //切换到的线路id
public SweeperResetDrivingLineRequest(int lineId) {
sn = MoGoAiCloudClientConfig.getInstance().getSn();
this.lineId = lineId;
}
}

View File

@@ -1,27 +0,0 @@
package com.mogo.och.sweeper.bean;
import com.mogo.eagle.core.data.BaseData;
/**
* 网约车小巴路线接口请求响应结果
*
* @author tongchenfei
*/
public class SweeperRoutesResponse extends BaseData {
private SweeperRoutesResult data;
public SweeperRoutesResult getResult() {
return data;
}
public void setResult(SweeperRoutesResult data) {
this.data = data;
}
@Override
public String toString() {
return "BusRoutesResponse{" +
"data=" + data +
'}';
}
}

View File

@@ -8,7 +8,7 @@ import java.util.List;
* @author tongchenfei
*/
public class SweeperRoutesResult {
private List<SweeperStationBean> sites;
private List<SweeperTaskBean> sites;
private int lineId;
private String name;
private int lineType; //线路类型0:环形
@@ -36,11 +36,11 @@ public class SweeperRoutesResult {
return name;
}
public List<SweeperStationBean> getSites() {
public List<SweeperTaskBean> getSites() {
return sites;
}
public void setSite(List<SweeperStationBean> site) {
public void setSite(List<SweeperTaskBean> site) {
this.sites = sites;
}

View File

@@ -5,7 +5,7 @@ package com.mogo.och.sweeper.bean;
*
* @author tongchenfei
*/
public class SweeperStationBean {
public class SweeperTaskBean {
// private int lineId;
// private int siteId;
// private String siteName;

View File

@@ -1,26 +0,0 @@
package com.mogo.och.sweeper.bean;
import com.mogo.cloud.passport.MoGoAiCloudClientConfig;
/**
* @author congtaowang
* @since 2021/3/22
*
* 小巴车运营状态请求参数
*/
public class SweeperUpdateSiteStatusRequest {
public String sn;
public int seq;//站点序号
public int siteId;//站点id
public double lon;
public double lat;
public SweeperUpdateSiteStatusRequest(int seq, int siteId, double lon, double lat) {
this.sn = MoGoAiCloudClientConfig.getInstance().getSn();
this.seq = seq;
this.siteId = siteId;
this.lon = lon;
this.lat = lat;
}
}

View File

@@ -1,9 +0,0 @@
package com.mogo.och.sweeper.callback;
/**
* @author: wangmingjun
* @date: 2021/10/22
*/
public interface ICarOperationStatusCallback {
void changeOperationStatus(boolean changeStatus);
}

View File

@@ -1,13 +0,0 @@
package com.mogo.och.sweeper.callback;
import com.mogo.och.sweeper.bean.SweeperStationBean;
import java.util.List;
/**
* @author: wangmingjun
* @date: 2021/10/22
*/
public interface IRefreshSweeperStationsCallback {
void refreshBusStations(String lineName, List<SweeperStationBean> stationList, int currentStation, int nextStation, boolean isArrived);
}

View File

@@ -0,0 +1,18 @@
package com.mogo.och.sweeper.callback;
import com.mogo.och.sweeper.bean.SweeperTaskBean;
import java.util.List;
/**
* @author: wangmingjun
* @date: 2021/10/22
*/
public interface IRefreshSweeperTaskCallback {
void updateSweeperTaskStatus(String lineName, List<SweeperTaskBean> taskList, int currentTask,boolean isFinishedSubTask);
/**
* 结束清理一遍、选择任务后清理一遍
*/
void clearSweeperTasksMarkers();
}

View File

@@ -0,0 +1,11 @@
package com.mogo.och.sweeper.callback;
/**
* Created on 2021/9/8
*
* Model->Presenter回调ADAS相关自动驾驶状态回调到达终点等等
*/
public interface ISweeperADASStatusCallback {
//自驾返回失败
void onStartAdasFailure();
}

View File

@@ -55,8 +55,13 @@ class SweeperConst {
const val EVENT_PARAM_END_NAME = "end_name"
const val EVENT_PARAM_LINE_ID = "line_id"
const val EVENT_PARAM_START_RESULT = "start_autopilot" // true/false
const val EVENT_PARAM_START_FAILURE_CODE = "start_autopilot_failure_code" // 启动自驾失败code
const val EVENT_PARAM_START_FAILURE_MSG = "start_autopilot_failure_msg" // 启动自驾失败原因
const val EVENT_PARAM_PLATE_NUM = "plate_number" // 车牌号
const val EVENT_PARAM_ENV_ONLINE = "env_online" // 是否线上环境true/false
// 埋点key开启自动驾驶前已识别的异常会导致无法开启自驾
const val EVENT_KEY_AP_UNABLE_START_REASON = "event_key_och_bus_ap_unable_start_reason"
const val EVENT_PARAM_UNABLE_START_REASON = "unable_start_reason";
/**
* 订单起终点Marker类型

View File

@@ -70,6 +70,14 @@ class SweeperFragment : BaseSweeperTabFragment<SweeperFragment?, SweeperPresente
mPresenter?.debugAutoPilotStatus(status)
}
/**
* 改变自动驾驶状态
*
* @param autopilotStatus 0:不可用 1:可用状态 2:自动驾驶中
*/
fun onAutopilotStatusChanged(autopilotStatus:Int) {
}
/**
* 设置各种监听事件
*/

View File

@@ -0,0 +1,51 @@
package com.mogo.och.sweeper.model;
import java.util.List;
public interface ISweeperTask<T> {
/**
* 获取任务列表
* @return
*/
List<T> getTaskList();
/**
* 设置任务列表
* @param taskList
*/
void setTaskList(List<T> taskList);
/**
* 获取当前任务
* @return
*/
T getCurrentTask();
/**
* 设置当前任务
* @param currentTask
*/
void setCurrentTask(T currentTask);
/**
* 开始任务
*/
void startTask();
/**
* 暂停任务
*/
void pauseTask();
/**
* 跳过任务
*/
void jumpOverTask();
/**
* 结束任务
*/
void endTask();
}

View File

@@ -0,0 +1,40 @@
package com.mogo.och.sweeper.model
import com.mogo.och.sweeper.bean.TaskInfoBean
/**
* 运营任务
*/
class OperationalTask : ISweeperTask<TaskInfoBean> {
override fun getTaskList(): MutableList<TaskInfoBean> {
return mutableListOf()
}
override fun startTask() {
}
override fun pauseTask() {
}
override fun jumpOverTask() {
}
override fun endTask() {
}
override fun setTaskList(taskList: MutableList<TaskInfoBean>?) {
}
override fun getCurrentTask(): TaskInfoBean {
return TaskInfoBean(1, "", 1)
}
override fun setCurrentTask(currentTask: TaskInfoBean?) {
}
}

View File

@@ -1,393 +0,0 @@
package com.mogo.och.sweeper.model;
import android.content.Context;
import com.amap.api.maps.model.LatLng;
import com.elegant.network.utils.GsonUtil;
import com.mogo.cloud.commons.utils.CoordinateUtils;
import com.mogo.commons.AbsMogoApplication;
import com.mogo.commons.module.status.IMogoStatusChangedListener;
import com.mogo.commons.module.status.MogoStatusManager;
import com.mogo.commons.module.status.StatusDescriptor;
import com.mogo.eagle.core.data.BaseData;
import com.mogo.eagle.core.data.autopilot.AutopilotControlParameters;
import com.mogo.eagle.core.data.config.FunctionBuildConfig;
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.CallerAutoPilotManager;
import com.mogo.eagle.core.function.call.autopilot.CallerAutoPilotStatusListenerManager;
import com.mogo.eagle.core.function.call.autopilot.CallerChassisLocationGCJ20ListenerManager;
import com.mogo.eagle.core.function.call.autopilot.CallerPlanningRottingListenerManager;
import com.mogo.eagle.core.function.call.map.CallerMapLocationListenerManager;
import com.mogo.eagle.core.utilcode.mogo.logger.CallerLogger;
import com.mogo.eagle.core.utilcode.mogo.logger.Logger;
import com.mogo.och.common.module.utils.CoordinateCalculateRouteUtil;
import com.mogo.och.sweeper.bean.SweeperRoutePlanningUpdateReqBean;
import com.mogo.och.sweeper.bean.SweeperRoutesResult;
import com.mogo.och.sweeper.bean.SweeperStationBean;
import com.mogo.och.sweeper.callback.ICarOperationStatusCallback;
import com.mogo.och.sweeper.callback.IRefreshSweeperStationsCallback;
import com.mogo.och.sweeper.callback.ISweeperControllerStatusCallback;
import com.mogo.och.sweeper.constant.SweeperConst;
import com.mogo.och.sweeper.net.ISweeperServiceCallback;
import com.mogo.och.sweeper.net.SweeperServiceManager;
import com.mogo.och.sweeper.presenter.SweeperModelLoopManager;
import com.mogo.och.sweeper.util.SweeperAnalyticsManager;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import androidx.annotation.Nullable;
import io.reactivex.exceptions.UndeliverableException;
import io.reactivex.functions.Consumer;
import io.reactivex.plugins.RxJavaPlugins;
import mogo.telematics.pad.MessagePad;
import static com.mogo.eagle.core.utilcode.mogo.logger.scene.SceneConstant.M_BUS;
/**
* @author congtaowang
* @since 2021/3/23
* <p>
* 小巴订单管理
*/
public class SweeperOrderModel {
private final String TAG = SweeperOrderModel.class.getSimpleName();
private int currentLineId = -1;
private int backgroundCurrentStationIndex = 0;//A->B 此处值是A站点索引
private static volatile SweeperOrderModel sInstance;
public double mLongitude = 0;
public double mLatitude = 0;
private Context mContext;
private final List<SweeperStationBean> stationList = new ArrayList<>();
private SweeperRoutesResult sweeperRoutesResult = null;
/**
* 用来表示是否正在开往下一站
*/
private boolean isGoingToNextStation = false;
private boolean mIsWorking = false;
private ISweeperControllerStatusCallback mControllerStatusCallback; //Model->PresenterVR mode等
List<SweeperRoutePlanningUpdateReqBean.Result> points = new ArrayList<>();//全路径信息
private boolean hadQueryLeaveAwayPassager = false;
private volatile boolean isArrivedStation = false;
public static SweeperOrderModel getInstance() {
if (sInstance == null) {
synchronized (SweeperOrderModel.class) {
if (sInstance == null) {
sInstance = new SweeperOrderModel();
}
}
}
return sInstance;
}
private SweeperOrderModel() {
}
public boolean isGoingToNextStation() {
return isGoingToNextStation;
}
public void init() {
mContext = AbsMogoApplication.getApp();
// 定位监听
CallerChassisLocationGCJ20ListenerManager.INSTANCE.addListener(TAG, mMapLocationListener);
MogoStatusManager.getInstance().registerStatusChangedListener(TAG, StatusDescriptor.VR_MODE, mMogoStatusChangedListener);
//自动驾驶路线规划接口
CallerPlanningRottingListenerManager.INSTANCE.addListener(TAG, moGoAutopilotPlanningListener);
//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(new Consumer<Throwable>() {
@Override
public void accept(Throwable e) {
if (e instanceof UndeliverableException) {
e = e.getCause();
CallerLogger.INSTANCE.d(M_BUS + TAG, "UndeliverableException");
}
if ((e instanceof IOException)) {//
// fine, irrelevant network problem or API that throws on cancellation
CallerLogger.INSTANCE.d(M_BUS + TAG, "IOException");
return;
}
if (e instanceof InterruptedException) {
// fine, some blocking code was interrupted by a dispose call
CallerLogger.INSTANCE.d(M_BUS + TAG, "InterruptedException");
return;
}
if ((e instanceof NullPointerException) || (e instanceof IllegalArgumentException)) {
// that's likely a bug in the application
CallerLogger.INSTANCE.d(M_BUS + TAG, "NullPointerException or IllegalArgumentException");
Thread.currentThread().getUncaughtExceptionHandler().uncaughtException(Thread.currentThread(), e);
return;
}
if (e instanceof IllegalStateException) {
// that's a bug in RxJava or in a custom operator
CallerLogger.INSTANCE.d(M_BUS + TAG, "IllegalStateException");
Thread.currentThread().getUncaughtExceptionHandler().uncaughtException(Thread.currentThread(), e);
return;
}
CallerLogger.INSTANCE.d(M_BUS + TAG, "Undeliverable exception");
}
});
}
public void setControllerStatusCallback(ISweeperControllerStatusCallback callback) {
this.mControllerStatusCallback = callback;
}
private final IMoGoPlanningRottingListener moGoAutopilotPlanningListener = new IMoGoPlanningRottingListener() {
@Override
public void onAutopilotRotting(MessagePad.GlobalPathResp routeList) {
if (null != routeList && routeList.getWayPointsList().size() > 0) {
points.clear();
points.addAll(coordinateConverterWgsToGcjList(mContext, routeList.getWayPointsList()));
updateOrderRoute();
}
}
};
public static List<SweeperRoutePlanningUpdateReqBean.Result> coordinateConverterWgsToGcjList(Context mContext,
List<MessagePad.Location> mogoLatLngList) {
List<SweeperRoutePlanningUpdateReqBean.Result> points = new ArrayList<>();
for (MessagePad.Location m : mogoLatLngList) {
LatLng mogoLatLng = CoordinateCalculateRouteUtil.coordinateConverterWgsToGcj(mContext, m);
SweeperRoutePlanningUpdateReqBean.Result result = new SweeperRoutePlanningUpdateReqBean.Result();
result.latitude = mogoLatLng.latitude;
result.longitude = mogoLatLng.longitude;
points.add(result);
}
return points;
}
/**
* 上报订单全路径规划数据
*/
public void updateOrderRoute() {
if (!isGoingToNextStation || backgroundCurrentStationIndex + 1 >= stationList.size() || points.size() == 0) {
return;
}
SweeperStationBean currentStation = stationList.get(backgroundCurrentStationIndex);
SweeperStationBean nextStation = stationList.get(backgroundCurrentStationIndex + 1);
SweeperServiceManager.getInstance().updateOrderRoute(mContext, currentLineId, currentStation.getSiteId()
, nextStation.getSiteId(), points, new ISweeperServiceCallback<BaseData>() {
@Override
public void onSuccess(BaseData o) {
}
@Override
public void onFail(String failMsg) {
if (isGoingToNextStation) {//重试
updateOrderRoute();
}
}
});
}
public void debugUpdateOrderRoute(List<MessagePad.Location> list) {
points.clear();
points.addAll(coordinateConverterWgsToGcjList(mContext, list));
updateOrderRoute();
}
public void release() {
startOrStopOrderLoop(false);
MogoStatusManager.getInstance().unregisterStatusChangedListener(TAG, StatusDescriptor.VR_MODE, mMogoStatusChangedListener);
// 注销定位监听
CallerMapLocationListenerManager.INSTANCE.removeListener(TAG, false);
//自动驾驶路线规划接口
CallerPlanningRottingListenerManager.INSTANCE.removeListener(moGoAutopilotPlanningListener);
}
private Object readResolve() {
// 阻止反序列化,必须实现 Serializable 接口
return sInstance;
}
private final IMogoStatusChangedListener mMogoStatusChangedListener = new IMogoStatusChangedListener() {
// VR mode变更回调
@Override
public void onStatusChanged(StatusDescriptor descriptor, boolean isTrue) {
if (StatusDescriptor.VR_MODE == descriptor) {
if (mControllerStatusCallback != null) {
mControllerStatusCallback.onVRModeChanged(isTrue);
}
}
}
};
// 自车定位
private final IMoGoChassisLocationGCJ02Listener mMapLocationListener = new IMoGoChassisLocationGCJ02Listener() {
@Override
public void onChassisLocationGCJ02(@Nullable MessagePad.GnssInfo gnssInfo) {
if (null == gnssInfo) return;
mLongitude = gnssInfo.getLongitude();
mLatitude = gnssInfo.getLatitude();
if (mControllerStatusCallback != null) {
mControllerStatusCallback.onCarLocationChanged(gnssInfo);
}
//是否到站的围栏判断 离站状态并且自动驾驶还未触发到站
if (isGoingToNextStation && !isArrivedStation) {
judgeStartStation(gnssInfo);
}
}
};
//根据围栏判断,是否到达起点
private void judgeStartStation(MessagePad.GnssInfo location) {
if (backgroundCurrentStationIndex + 1 > stationList.size() - 1) {
return;
}
SweeperStationBean upcomingStation = stationList.get(backgroundCurrentStationIndex + 1);
double startLon = upcomingStation.getGcjLon();
double startLat = upcomingStation.getGcjLat();
double distance = CoordinateUtils.calculateLineDistance(
startLon, startLat,
location.getLongitude(), location.getLatitude());
Logger.i(TAG, "judgeStartStation() distance = " + distance);
if (distance > SweeperConst.ARRIVE_AT_END_STATION_DISTANCE) {
distance = CoordinateUtils.calculateLineDistance(startLon, startLat,
CallerAutoPilotStatusListenerManager.INSTANCE.getCurWgs84Lon(),
CallerAutoPilotStatusListenerManager.INSTANCE.getCurWgs84Lat());
}
if (distance <= SweeperConst.ARRIVE_AT_END_STATION_DISTANCE) {
//onArriveAt(null); //无自动驾驶到站信息传null
return;
}
}
/**
* 开启自动驾驶
*
* @param isRestart
*/
private void startAutopilot(boolean isRestart) {
triggerStartServiceEvent(isRestart, false);
isArrivedStation = false;
// SweeperStationBean currentStation = stationList.get( backgroundCurrentStationIndex);
// SweeperStationBean nextStation = stationList.get( backgroundCurrentStationIndex + 1);
// if (IMoGoAutopilotStatusListener.STATUS_AUTOPILOT_DISABLE
// == CallerAutoPilotStatusListenerManager.INSTANCE.getAutoPilotStatusInfo().getState()) {
// ToastUtils.showShort("自动驾驶状态为不可用!");
// }
AutopilotControlParameters parameters = new AutopilotControlParameters();
// parameters.isSpeakVoice = !isRestart;
// parameters.routeID = sweeperRoutesResult.getLineId();
// parameters.routeName = sweeperRoutesResult.getName();
// parameters.startName = PinYinUtil.getPinYinHeadChar(currentStation.getName());
// parameters.endName = PinYinUtil.getPinYinHeadChar(nextStation.getName());
// parameters.startLatLon = new AutopilotControlParameters
// .AutoPilotLonLat( currentStation.getLat(), currentStation.getLon() );
// parameters.endLatLon = new AutopilotControlParameters
// .AutoPilotLonLat( nextStation.getLat(), nextStation.getLon() );
// parameters.vehicleType = VEHICLE_TYPE;
// if (parameters.autoPilotLine == null) {
// parameters.autoPilotLine = new AutopilotControlParameters.AutoPilotLine(
// sweeperRoutesResult.getLineId(),
// sweeperRoutesResult.csvFileUrl, sweeperRoutesResult.csvFileMd5,
// sweeperRoutesResult.txtFileUrl, sweeperRoutesResult.txtFileMd5,
// sweeperRoutesResult.contrailSaveTime, sweeperRoutesResult.carModel,
// sweeperRoutesResult.csvFileUrlDPQP, sweeperRoutesResult.csvFileMd5DPQP,
// sweeperRoutesResult.txtFileUrlDPQP, sweeperRoutesResult.txtFileMd5DPQP,
// sweeperRoutesResult.contrailSaveTimeDPQP);
// }
// CallerLogger.INSTANCE.d( M_BUS + TAG, "开启自动驾驶====" + GsonUtil.jsonFromObject(parameters)
// +" startLatLon="+currentStation.getName()+"endLatLon="+nextStation.getName());
CallerLogger.INSTANCE.d(M_BUS + TAG, "开启自动驾驶====" + GsonUtil.jsonFromObject(parameters));
CallerAutoPilotManager.INSTANCE.startAutoPilot(parameters);
if (mControllerStatusCallback != null) {
mControllerStatusCallback.startOpenAutopilot();
}
}
public boolean isWorking() {
return mIsWorking;
}
/**
* 关闭美化模式
*/
private void closeBeautificationMode() {
if (FunctionBuildConfig.isDemoMode) {//收车结束美化
FunctionBuildConfig.isIgnoreConditionsDrawAutopilotTrajectoryData = false;
CallerAutoPilotManager.INSTANCE.setIPCDemoMode(false);
CallerLogger.INSTANCE.d(M_BUS + TAG, "美化模式-ignore置为false收车");
}
}
/**
* 在踩刹车、控制方向盘等操作后,会停止自动驾驶,重启自动驾驶的话相当于重新设置自动驾驶目的地
*/
public void restartAutopilot() {
// CallerLogger.INSTANCE.d( M_BUS + TAG, "重启自动驾驶===" + isGoingToNextStation );
// autoDriveToNextStation( true );
//直接开启自动驾驶
startAutopilot(true);
}
// 车机端上传心跳数据(只在出车状态时上传)
public void runCarHeartbeat() {
SweeperServiceManager.getInstance().runCarHeartbeat(mContext, mLongitude, mLatitude,
new ISweeperServiceCallback<BaseData>() {
@Override
public void onSuccess(BaseData data) {
}
@Override
public void onFail(String failMsg) {
}
});
}
private void startOrStopOrderLoop(boolean start) {
CallerLogger.INSTANCE.d(M_BUS + TAG, "startOrStopOrderLoop() " + start);
if (start) {
SweeperModelLoopManager.getInstance().startHeartbeatLoop();
} else {
SweeperModelLoopManager.getInstance().stopHeartbeatLoop();
}
}
public void triggerStartServiceEvent(boolean isRestart, boolean send) {
if (stationList == null || backgroundCurrentStationIndex >= stationList.size() - 1) {
return;
}
SweeperStationBean currentStation = stationList.get(backgroundCurrentStationIndex);
SweeperStationBean nextStation = stationList.get(backgroundCurrentStationIndex + 1);
SweeperAnalyticsManager.getInstance().triggerStartAutopilotEvent(isRestart, send,
currentStation.getName(), nextStation.getName(), currentLineId);
}
public SweeperRoutesResult getBusRoutesResult() {
return sweeperRoutesResult;
}
public int getCurrentStationIndex() {
return backgroundCurrentStationIndex;
}
}

View File

@@ -0,0 +1,481 @@
package com.mogo.och.sweeper.model;
import android.content.Context;
import com.amap.api.maps.model.LatLng;
import com.elegant.network.utils.GsonUtil;
import com.mogo.cloud.commons.utils.CoordinateUtils;
import com.mogo.commons.AbsMogoApplication;
import com.mogo.commons.module.status.IMogoStatusChangedListener;
import com.mogo.commons.module.status.MogoStatusManager;
import com.mogo.commons.module.status.StatusDescriptor;
import com.mogo.eagle.core.data.autopilot.AutopilotControlParameters;
import com.mogo.eagle.core.data.config.FunctionBuildConfig;
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.CallerAutoPilotManager;
import com.mogo.eagle.core.function.call.autopilot.CallerAutoPilotStatusListenerManager;
import com.mogo.eagle.core.function.call.autopilot.CallerChassisLocationGCJ20ListenerManager;
import com.mogo.eagle.core.function.call.autopilot.CallerPlanningRottingListenerManager;
import com.mogo.eagle.core.function.call.map.CallerMapLocationListenerManager;
import com.mogo.eagle.core.utilcode.mogo.logger.CallerLogger;
import com.mogo.eagle.core.utilcode.util.ToastUtils;
import com.mogo.och.common.module.callback.OchAdasStartFailureCallback;
import com.mogo.och.common.module.manager.OCHAdasAbilityManager;
import com.mogo.och.common.module.utils.CoordinateCalculateRouteUtil;
import com.mogo.och.common.module.utils.NumberFormatUtil;
import com.mogo.och.common.module.utils.PinYinUtil;
import com.mogo.och.sweeper.bean.SweeperRoutePlanningUpdateReqBean;
import com.mogo.och.sweeper.bean.SweeperRoutesResult;
import com.mogo.och.sweeper.bean.SweeperTaskBean;
import com.mogo.och.sweeper.callback.IRefreshSweeperTaskCallback;
import com.mogo.och.sweeper.callback.ISweeperADASStatusCallback;
import com.mogo.och.sweeper.callback.ISweeperControllerStatusCallback;
import com.mogo.och.sweeper.constant.SweeperConst;
import com.mogo.och.sweeper.util.SweeperAnalyticsManager;
import org.jetbrains.annotations.NotNull;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import io.reactivex.exceptions.UndeliverableException;
import io.reactivex.functions.Consumer;
import io.reactivex.plugins.RxJavaPlugins;
import mogo.telematics.pad.MessagePad;
import static com.mogo.eagle.core.utilcode.mogo.logger.scene.SceneConstant.M_BUS;
/**
* @author congtaowang
* @since 2021/3/23
* <p>
* 清扫车任务管理
*/
public class SweeperTaskModel {
private final String TAG = SweeperTaskModel.class.getSimpleName();
private int currentLineId = -1;
private int backgroundCurrentTaskIndex = 0;//A->B 此处值是A任务索引
private static volatile SweeperTaskModel sInstance;
public double mLongitude = 0;
public double mLatitude = 0;
private Context mContext;
private final List<SweeperTaskBean> stationList = new ArrayList<>();
private SweeperRoutesResult busRoutesResult = null;
/**
* 用来表示是否正在开往下一站
*/
private boolean isGoingToNextStation = false;
// 运营类型
private static final int VEHICLE_TYPE = 10;
private ISweeperControllerStatusCallback mControllerStatusCallback; //Model->PresenterVR mode等
private ISweeperADASStatusCallback mADASStatusCallback;
private IRefreshSweeperTaskCallback mRefreshSweeperTaskCallback;
List<SweeperRoutePlanningUpdateReqBean.Result> points = new ArrayList<>();//全路径信息
private volatile boolean isArrivedStation = false;
//0: 代表没有启动过 1代表是启动第一次当>=1 代表是重试 每次到站/路线结束清空置为0
private volatile int firstStartAutopilot = 0;
public static SweeperTaskModel getInstance() {
if (sInstance == null) {
synchronized (SweeperTaskModel.class) {
if (sInstance == null) {
sInstance = new SweeperTaskModel();
}
}
}
return sInstance;
}
private SweeperTaskModel() {
}
public void init() {
mContext = AbsMogoApplication.getApp();
// 定位监听
CallerChassisLocationGCJ20ListenerManager.INSTANCE.addListener(TAG, mMapLocationListener);
MogoStatusManager.getInstance().registerStatusChangedListener(TAG, StatusDescriptor.VR_MODE, mMogoStatusChangedListener);
//自动驾驶路线规划接口
CallerPlanningRottingListenerManager.INSTANCE.addListener(TAG, moGoAutopilotPlanningListener);
//开启自驾后 异常信息返回
OCHAdasAbilityManager.getInstance().setAdasStartFailureCallback(mAdasStartFailureListener);
//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(new Consumer<Throwable>() {
@Override
public void accept(Throwable e) {
if (e instanceof UndeliverableException) {
e = e.getCause();
CallerLogger.INSTANCE.d(M_BUS + TAG, "UndeliverableException");
}
if ((e instanceof IOException)) {//
// fine, irrelevant network problem or API that throws on cancellation
CallerLogger.INSTANCE.d(M_BUS + TAG, "IOException");
return;
}
if (e instanceof InterruptedException) {
// fine, some blocking code was interrupted by a dispose call
CallerLogger.INSTANCE.d(M_BUS + TAG, "InterruptedException");
return;
}
if ((e instanceof NullPointerException) || (e instanceof IllegalArgumentException)) {
// that's likely a bug in the application
CallerLogger.INSTANCE.d(M_BUS + TAG, "NullPointerException or IllegalArgumentException");
Thread.currentThread().getUncaughtExceptionHandler().uncaughtException(Thread.currentThread(), e);
return;
}
if (e instanceof IllegalStateException) {
// that's a bug in RxJava or in a custom operator
CallerLogger.INSTANCE.d(M_BUS + TAG, "IllegalStateException");
Thread.currentThread().getUncaughtExceptionHandler().uncaughtException(Thread.currentThread(), e);
return;
}
CallerLogger.INSTANCE.d(M_BUS + TAG, "Undeliverable exception");
}
});
}
public void setAdasStatusCallback(ISweeperADASStatusCallback callback){
this.mADASStatusCallback = callback;
}
public void setControllerStatusCallback(ISweeperControllerStatusCallback callback) {
this.mControllerStatusCallback = callback;
}
private final IMoGoPlanningRottingListener moGoAutopilotPlanningListener = new IMoGoPlanningRottingListener() {
@Override
public void onAutopilotRotting(MessagePad.GlobalPathResp routeList) {
if (null != routeList && routeList.getWayPointsList().size() > 0) {
points.clear();
points.addAll(coordinateConverterWgsToGcjList(mContext, routeList.getWayPointsList()));
}
}
};
public static List<SweeperRoutePlanningUpdateReqBean.Result> coordinateConverterWgsToGcjList(Context mContext, List<MessagePad.Location> mogoLatLngList) {
List<SweeperRoutePlanningUpdateReqBean.Result> points = new ArrayList<>();
for (MessagePad.Location m : mogoLatLngList) {
LatLng mogoLatLng = CoordinateCalculateRouteUtil.coordinateConverterWgsToGcj(mContext, m);
SweeperRoutePlanningUpdateReqBean.Result result = new SweeperRoutePlanningUpdateReqBean.Result();
result.latitude = mogoLatLng.latitude;
result.longitude = mogoLatLng.longitude;
points.add(result);
}
return points;
}
public void release() {
MogoStatusManager.getInstance().unregisterStatusChangedListener(TAG, StatusDescriptor.VR_MODE, mMogoStatusChangedListener);
// 注销定位监听
CallerMapLocationListenerManager.INSTANCE.removeListener(TAG,false);
//自动驾驶路线规划接口
CallerPlanningRottingListenerManager.INSTANCE.removeListener(moGoAutopilotPlanningListener);
OCHAdasAbilityManager.getInstance().setAdasStartFailureCallback(null);
}
private Object readResolve() {
// 阻止反序列化,必须实现 Serializable 接口
return sInstance;
}
private final IMogoStatusChangedListener mMogoStatusChangedListener = new IMogoStatusChangedListener() {
// VR mode变更回调
@Override
public void onStatusChanged(StatusDescriptor descriptor, boolean isTrue) {
if (StatusDescriptor.VR_MODE == descriptor) {
if (mControllerStatusCallback != null) {
mControllerStatusCallback.onVRModeChanged(isTrue);
}
}
}
};
private final OchAdasStartFailureCallback mAdasStartFailureListener = new OchAdasStartFailureCallback() {
@Override
public void onStartAutopilotFailure(@NotNull String startFailedCode, @NonNull String startFailedMessage) {
SweeperAnalyticsManager.getInstance().triggerStartAutopilotFailureEventByAdas(startFailedCode, startFailedMessage);
if (mADASStatusCallback != null && !FunctionBuildConfig.isDemoMode){
CallerLogger.INSTANCE.e( M_BUS + TAG, "mAdasStartFailureListener = "+startFailedMessage );
mADASStatusCallback.onStartAdasFailure();
}
}
};
// 自车定位
private final IMoGoChassisLocationGCJ02Listener mMapLocationListener = new IMoGoChassisLocationGCJ02Listener() {
@Override
public void onChassisLocationGCJ02(@Nullable MessagePad.GnssInfo gnssInfo) {
if (null == gnssInfo) return;
mLongitude = gnssInfo.getLongitude();
mLatitude = gnssInfo.getLatitude();
if (mControllerStatusCallback != null) {
mControllerStatusCallback.onCarLocationChanged(gnssInfo);
}
//是否到站的围栏判断 离站状态并且自动驾驶还未触发到站
if (isGoingToNextStation && !isArrivedStation) {
judgeArrivedStation(gnssInfo);
}
}
};
//根据围栏判断,是否到达站点
private void judgeArrivedStation(MessagePad.GnssInfo location) {
if (backgroundCurrentTaskIndex + 1 > stationList.size() - 1) {
CallerLogger.INSTANCE.e(M_BUS + TAG, "到站数组越界");
return;
}
SweeperTaskBean upcomingStation = stationList.get(backgroundCurrentTaskIndex + 1);
double startLon = upcomingStation.getGcjLon();
double startLat = upcomingStation.getGcjLat();
double distance = CoordinateUtils.calculateLineDistance(
startLon, startLat,
location.getLongitude(), location.getLatitude());
if (distance <= SweeperConst.ARRIVE_AT_END_STATION_DISTANCE) {
CallerLogger.INSTANCE.d(M_BUS + TAG, "行程日志-judgeArrivedStation() distance = " + distance
+ " to " + upcomingStation.getName());
onArriveAt(null); //无自动驾驶到站信息传null
return;
}
}
private void onStartAutopilot(int leaveIndex) {
//开启自动驾驶 2.10.0: 如果自动驾驶状态下开启, 非自动驾驶状态下不开启,需手动点击自动驾驶按钮开启
isGoingToNextStation = true;
if (CallerAutoPilotStatusListenerManager.INSTANCE.getAutoPilotStatusInfo().getState()
== IMoGoAutopilotStatusListener.STATUS_AUTOPILOT_RUNNING) {
startAutopilot(false, leaveIndex);
} else {
firstStartAutopilot = 0;
}
}
/**
* 开启自动驾驶
*
* @param isRestart
*/
private void startAutopilot(boolean isRestart, int leaveIndex) {
if (!FunctionBuildConfig.isDemoMode && !OCHAdasAbilityManager.getInstance().getAutopilotAbilityStatus()) {
ToastUtils.showLong(OCHAdasAbilityManager.getInstance().getAutopilotUnAbilityReason() +
", 请稍候重试");
triggerUnableStartAPReasonEvent();
return;
}
firstStartAutopilot++;
triggerStartServiceEvent(isRestart, false);
AutopilotControlParameters parameters = initAutopilotControlParameters(leaveIndex);
if (null == parameters) {
CallerLogger.INSTANCE.e(M_BUS + TAG, "行程日志-AutopilotControlParameters is empty.");
return;
}
CallerAutoPilotManager.INSTANCE.startAutoPilot(parameters);
CallerLogger.INSTANCE.d(M_BUS + TAG, "行程日志-开启自动驾驶====" + GsonUtil.jsonFromObject(parameters)
+ " startLatLon=" + parameters.startName + "endLatLon=" + parameters.endName +
"isRestart = " + isRestart);
if (mControllerStatusCallback != null) {
mControllerStatusCallback.startOpenAutopilot();
}
}
/**
* 关闭美化模式
*/
public void closeBeautificationMode() {
if (FunctionBuildConfig.isDemoMode) {
FunctionBuildConfig.isIgnoreConditionsDrawAutopilotTrajectoryData = false; //是否强制绘制引导线
CallerAutoPilotManager.INSTANCE.setIgnoreConditionDraw(false);// 同步给乘客屏
CallerAutoPilotManager.INSTANCE.setIPCDemoMode(false);//是否自动启动自驾
CallerLogger.INSTANCE.d(M_BUS + TAG, "美化模式-ignore置为false");
}
}
private void clearStartAutopilotTag() {
firstStartAutopilot = 0;
}
/**
* 开启美化模式
*/
private void startBeautificationMode() {
FunctionBuildConfig.isIgnoreConditionsDrawAutopilotTrajectoryData = true;
CallerAutoPilotManager.INSTANCE.setIPCDemoMode(true);
}
public void clearBusStationData() {
if (mRefreshSweeperTaskCallback != null) {
mRefreshSweeperTaskCallback.clearSweeperTasksMarkers();
}
}
/**
* 在踩刹车、控制方向盘等操作后,会停止自动驾驶,重启自动驾驶的话相当于重新设置自动驾驶目的地
*/
public void restartAutopilot() {
CallerLogger.INSTANCE.d(M_BUS + TAG, "行程日志-重启自动驾驶===" + isGoingToNextStation);
//只去启动自动驾驶,不再去上报离站
startAutopilot(firstStartAutopilot >= 1, -1);
}
public boolean isRestartAutopilot() {
return firstStartAutopilot > 1;
}
/**
* task正常结束
*/
private void endTask() {
if (backgroundCurrentTaskIndex >= stationList.size()) {
CallerLogger.INSTANCE.e(M_BUS + TAG, "travel over index out of station list");
return;
}
CallerLogger.INSTANCE.d(M_BUS + TAG, "单程结束====");
CallerAutoPilotManager.INSTANCE.cancelAutoPilot();
CallerLogger.INSTANCE.d(M_BUS + TAG, "任务正常走完endTask()");
}
/**
* 到站
*
* @param data
*/
public void onArriveAt(MessagePad.ArrivalNotification data) {
if (backgroundCurrentTaskIndex + 1 > stationList.size() - 1) {
CallerLogger.INSTANCE.e(M_BUS + TAG, "行程日志-到站异常,取消后续操作结束");
return;
}
//MAP 280 每隔100ms左右返回一次到站 导致在到达中间站后再次滑动出发后会有时间差,收到一次到站,出现问题
//此处比对 自驾告诉的到站站点坐标和本地应到站站点坐标, 一致时才能到站
if (data != null && data.getEndLocation() != null) {
String latitude = NumberFormatUtil.cutOutNumber(data.getEndLocation().getLatitude(), 5); //wgs
String longitude = NumberFormatUtil.cutOutNumber(data.getEndLocation().getLongitude(), 5);
int arrivedStationIndex = backgroundCurrentTaskIndex + 1;
SweeperTaskBean arriveStation = stationList.get(arrivedStationIndex);
String arriveLat = NumberFormatUtil.cutOutNumber(arriveStation.getLat(), 5);
String arriveLon = NumberFormatUtil.cutOutNumber(arriveStation.getLon(), 5);
if (!latitude.equals(arriveLat) || !longitude.equals(arriveLon)) {
CallerLogger.INSTANCE.e(M_BUS + TAG, "行程日志-到站拦截,到站坐标不一致");
return;
}
}
if (isArrivedStation) return;
CallerLogger.INSTANCE.d(M_BUS + TAG, "行程日志-当前==backgroundCurrentTaskIndex="
+ backgroundCurrentTaskIndex);
}
public boolean isGoingToNextStation() {
return isGoingToNextStation;
}
public void triggerStartServiceEvent(boolean isRestart, boolean send) {
if (stationList == null || backgroundCurrentTaskIndex >= stationList.size() - 1) {
return;
}
SweeperTaskBean currentStation = stationList.get(backgroundCurrentTaskIndex);
SweeperTaskBean nextStation = stationList.get(backgroundCurrentTaskIndex + 1);
SweeperAnalyticsManager.getInstance().triggerStartAutopilotEvent(isRestart, send,
currentStation.getName(), nextStation.getName(), currentLineId);
}
public void triggerUnableStartAPReasonEvent() {
if (stationList == null || backgroundCurrentTaskIndex >= stationList.size() - 1) {
return;
}
SweeperTaskBean currentStation = stationList.get(backgroundCurrentTaskIndex);
SweeperTaskBean nextStation = stationList.get(backgroundCurrentTaskIndex + 1);
SweeperAnalyticsManager.getInstance().triggerUnableStartAPReasonEvent(
currentStation.getName(), nextStation.getName(), currentLineId,
OCHAdasAbilityManager.getInstance().getAutopilotUnAbilityReason());
}
public SweeperRoutesResult getBusRoutesResult() {
return busRoutesResult;
}
public int getCurrentStationIndex() {
return backgroundCurrentTaskIndex;
}
/**
* 将业务订单信息保存,鹰眼可取用
*/
private void updateAutopilotControlParameters() {
AutopilotControlParameters parameters = initAutopilotControlParameters(-1);
if (null == parameters) {
CallerLogger.INSTANCE.e(M_BUS + TAG, "AutopilotControlParameters is empty.");
return;
}
CallerLogger.INSTANCE.d(M_BUS + TAG, "AutopilotControlParameters is update.");
CallerAutoPilotStatusListenerManager.INSTANCE.updateAutopilotControlParameters(parameters);
}
private void clearAutopilotControlParameters() {
CallerLogger.INSTANCE.d(M_BUS + TAG, "AutopilotControlParameters is clear.");
CallerAutoPilotStatusListenerManager.INSTANCE.updateAutopilotControlParameters(null);
}
private AutopilotControlParameters initAutopilotControlParameters(int leaveIndex) {
SweeperTaskBean currentStation = null;
SweeperTaskBean nextStation = null;
if (leaveIndex < 0) {
if (backgroundCurrentTaskIndex + 1 > stationList.size() - 1 || !isGoingToNextStation) {
CallerLogger.INSTANCE.e(M_BUS + TAG, "行程日志-mismatch condition1.");
return null;
}
currentStation = stationList.get(backgroundCurrentTaskIndex);
nextStation = stationList.get(backgroundCurrentTaskIndex + 1);
} else {
if (leaveIndex + 1 > stationList.size() - 1 || !isGoingToNextStation) {
CallerLogger.INSTANCE.e(M_BUS + TAG, "行程日志-mismatch condition2.");
return null;
}
currentStation = stationList.get(leaveIndex);
nextStation = stationList.get(leaveIndex + 1);
}
AutopilotControlParameters parameters = new AutopilotControlParameters();
parameters.routeID = busRoutesResult.getLineId();
parameters.routeName = busRoutesResult.getName();
parameters.startName = PinYinUtil.getPinYinHeadChar(currentStation.getName());
parameters.endName = PinYinUtil.getPinYinHeadChar(nextStation.getName());
parameters.startLatLon = new AutopilotControlParameters
.AutoPilotLonLat(currentStation.getLat(), currentStation.getLon());
parameters.endLatLon = new AutopilotControlParameters
.AutoPilotLonLat(nextStation.getLat(), nextStation.getLon());
parameters.vehicleType = VEHICLE_TYPE;
if (parameters.autoPilotLine == null) {
parameters.autoPilotLine = new AutopilotControlParameters.AutoPilotLine(
busRoutesResult.getLineId(),
busRoutesResult.csvFileUrl, busRoutesResult.csvFileMd5,
busRoutesResult.txtFileUrl, busRoutesResult.txtFileMd5,
busRoutesResult.contrailSaveTime, busRoutesResult.carModel,
busRoutesResult.csvFileUrlDPQP, busRoutesResult.csvFileMd5DPQP,
busRoutesResult.txtFileUrlDPQP, busRoutesResult.txtFileMd5DPQP,
busRoutesResult.contrailSaveTimeDPQP);
}
return parameters;
}
}

View File

@@ -1,7 +1,6 @@
package com.mogo.och.sweeper.net;
import com.mogo.eagle.core.data.BaseData;
import com.mogo.och.sweeper.bean.CarHeartbeatReqBean;
import com.mogo.och.sweeper.bean.SweeperRoutePlanningUpdateReqBean;
import io.reactivex.Observable;
@@ -11,26 +10,10 @@ import retrofit2.http.Headers;
import retrofit2.http.POST;
/**
* 小巴车相关接口
*
* @author tongchenfei
* <p>
* wiki: http://wiki.zhidaohulian.com/pages/viewpage.action?pageId=48970072
* 清扫车相关接口
*/
public interface ISweeperApiService {
/**
* 车机端上传心跳数据(只在出车状态时上传):包含高德坐标系经纬度
*
* @param data
* @return
*/
@Headers({"Content-type:application/json;charset=UTF-8"})
@POST("/autopilot-car-hailing/location/v2/driver/bus/heartbeat")
Observable<BaseData> runCarHeartbeat(@Header("appId") String appId, @Header("ticket") String ticket, @Body CarHeartbeatReqBean data);
@Headers({"Content-type:application/json;charset=UTF-8"})
@POST("/autopilot-car-hailing/location/v2/driver/bus/saveLineCoordinate")
Observable<BaseData> updateOrderRoute(@Header("appId") String appId, @Header("ticket") String ticket,
@Body SweeperRoutePlanningUpdateReqBean data);
}

View File

@@ -1,30 +1,15 @@
package com.mogo.och.sweeper.net;
import static com.mogo.eagle.core.utilcode.mogo.logger.scene.SceneConstant.M_BUS;
import android.content.Context;
import com.mogo.cloud.passport.MoGoAiCloudClientConfig;
import com.mogo.eagle.core.data.BaseData;
import com.mogo.eagle.core.network.MoGoRetrofitFactory;
import com.mogo.eagle.core.network.RequestOptions;
import com.mogo.eagle.core.network.SubscribeImpl;
import com.mogo.eagle.core.utilcode.mogo.logger.CallerLogger;
import com.mogo.och.sweeper.bean.SweeperQueryLinesResponse;
import com.mogo.och.sweeper.bean.SweeperRoutePlanningUpdateReqBean;
import com.mogo.och.sweeper.bean.SweeperRoutesResponse;
import com.mogo.och.sweeper.bean.CarHeartbeatReqBean;
import com.mogo.och.sweeper.bean.SweeperOperationStatusRequest;
import com.mogo.och.sweeper.bean.SweeperOperationStatusResponse;
import com.mogo.och.sweeper.bean.SweeperQueryLineStationsRequest;
import com.mogo.och.sweeper.bean.SweeperResetDrivingLineRequest;
import com.mogo.och.sweeper.bean.SweeperUpdateSiteStatusRequest;
import com.mogo.och.sweeper.constant.SweeperConst;
import com.mogo.och.sweeper.model.SweeperOrderModel;
import java.util.List;
import io.reactivex.android.schedulers.AndroidSchedulers;
import io.reactivex.schedulers.Schedulers;
import static com.mogo.eagle.core.utilcode.mogo.logger.scene.SceneConstant.M_BUS;
/**
* @author: wangmingjun
@@ -47,36 +32,6 @@ public class SweeperServiceManager {
private SweeperServiceManager(){
mService = MoGoRetrofitFactory.getInstance(SweeperConst.getBaseUrl()).create(ISweeperApiService.class);
}
public void updateOrderRoute(Context context,int lineId, int startSiteId, int endSiteId
, List< SweeperRoutePlanningUpdateReqBean.Result > points
, ISweeperServiceCallback<BaseData> callback){
mService.updateOrderRoute(MoGoAiCloudClientConfig.getInstance().getServiceAppId()
,MoGoAiCloudClientConfig.getInstance().getToken()
,new SweeperRoutePlanningUpdateReqBean(MoGoAiCloudClientConfig.getInstance().getSn()
,lineId,startSiteId,endSiteId, points))
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(getSubscribeImpl(context,callback,"updateOrderRoute"));
}
/**
* 车机端上传心跳数据(只在出车状态时上传):包含高德坐标系经纬度
* @param context
* @param lon
* @param lat
* @param callback
*/
public void runCarHeartbeat(Context context, double lon, double lat,
ISweeperServiceCallback<BaseData> callback) {
mService.runCarHeartbeat(MoGoAiCloudClientConfig.getInstance().getServiceAppId()
,MoGoAiCloudClientConfig.getInstance().getToken(),new CarHeartbeatReqBean(
MoGoAiCloudClientConfig.getInstance().getSn(), lon, lat))
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(getSubscribeImpl(context, callback, "runCarHeartbeat"));
}
private <T extends BaseData> SubscribeImpl getSubscribeImpl(Context context, ISweeperServiceCallback<T> callback, String apiName){
return new SubscribeImpl<T>(RequestOptions.create(context)){
@Override

View File

@@ -1,55 +0,0 @@
package com.mogo.och.sweeper.presenter;
import static com.mogo.eagle.core.utilcode.mogo.logger.scene.SceneConstant.M_BUS;
import com.mogo.eagle.core.utilcode.mogo.logger.CallerLogger;
import com.mogo.och.sweeper.constant.SweeperConst;
import com.mogo.och.sweeper.model.SweeperOrderModel;
import java.util.concurrent.TimeUnit;
import io.reactivex.Observable;
import io.reactivex.android.schedulers.AndroidSchedulers;
import io.reactivex.disposables.Disposable;
import io.reactivex.schedulers.Schedulers;
/**
* Created on 2021/11/22
*
* 管理轮询逻辑(订单轮询、新单轮询、新单抢单结果轮询等等)
*/
public class SweeperModelLoopManager {
private static final String TAG = SweeperModelLoopManager.class.getSimpleName();
private static final class SingletonHolder {
private static final SweeperModelLoopManager INSTANCE = new SweeperModelLoopManager();
}
public static SweeperModelLoopManager getInstance() {
return SingletonHolder.INSTANCE;
}
private Disposable mHeartbeatDisposable; //心跳轮询
public void startHeartbeatLoop() {
if (mHeartbeatDisposable != null && !mHeartbeatDisposable.isDisposed()) {
return;
}
CallerLogger.INSTANCE.i(M_BUS + TAG, "startHeartbeatLoop()");
mHeartbeatDisposable = Observable.interval(SweeperConst.LOOP_DELAY,
SweeperConst.LOOP_PERIOD_60S, TimeUnit.MILLISECONDS)
.map((aLong -> aLong + 1))
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(aLong -> SweeperOrderModel.getInstance().runCarHeartbeat());
}
public void stopHeartbeatLoop() {
if (mHeartbeatDisposable != null) {
CallerLogger.INSTANCE.i(M_BUS + TAG, "stopHeartbeatLoop()");
mHeartbeatDisposable.dispose();
mHeartbeatDisposable = null;
}
}
}

View File

@@ -2,22 +2,21 @@ package com.mogo.och.sweeper.presenter;
import android.os.Looper;
import com.mogo.commons.AbsMogoApplication;
import com.mogo.commons.mvp.Presenter;
import com.mogo.eagle.core.data.autopilot.AutopilotStatusInfo;
import com.mogo.eagle.core.function.api.autopilot.IMoGoAutopilotStatusListener;
import com.mogo.eagle.core.function.call.autopilot.CallerAutoPilotStatusListenerManager;
import com.mogo.eagle.core.utilcode.util.UiThreadHandler;
import com.mogo.och.sweeper.bean.SweeperStationBean;
import com.mogo.och.common.module.manager.OCHAdasAbilityManager;
import com.mogo.och.sweeper.callback.ISweeperADASStatusCallback;
import com.mogo.och.sweeper.callback.ISweeperControllerStatusCallback;
import com.mogo.och.sweeper.fragment.SweeperFragment;
import com.mogo.och.sweeper.model.SweeperOrderModel;
import com.mogo.och.sweeper.model.SweeperTaskModel;
import com.mogo.och.sweeper.util.SweeperTrajectoryManager;
import org.jetbrains.annotations.NotNull;
import java.util.ArrayList;
import java.util.List;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.lifecycle.LifecycleOwner;
@@ -31,20 +30,19 @@ import system_master.SystemStatusInfo;
* @author tongchenfei
*/
public class SweeperPresenter extends Presenter<SweeperFragment>
implements IMoGoAutopilotStatusListener, ISweeperControllerStatusCallback {
implements IMoGoAutopilotStatusListener, ISweeperControllerStatusCallback, ISweeperADASStatusCallback{
private static final String TAG = "BusPresenter";
private int currentAutopilotStatus = -1;
private List<SweeperStationBean> mStationList = new ArrayList<>();
private int mCurrentStation = 0;
private boolean isRestartAutopilot = false;
public SweeperPresenter(SweeperFragment view) {
super(view);
//2021.11.1 鹰眼架构整合由IMoGoAutopilotStatusListener逐步替代IMogoAdasOCHCallback接口
CallerAutoPilotStatusListenerManager.INSTANCE.addListener(TAG, this);
SweeperOrderModel.getInstance().init();
SweeperTaskModel.getInstance().init();
OCHAdasAbilityManager.getInstance().init(AbsMogoApplication.getApp());
}
@Override
@@ -56,21 +54,23 @@ public class SweeperPresenter extends Presenter<SweeperFragment>
@Override
public void onDestroy(@NonNull LifecycleOwner owner) {
super.onDestroy(owner);
SweeperOrderModel.getInstance().release();
SweeperTaskModel.getInstance().release();
releaseListener();
}
public void initModelListener() {
SweeperOrderModel.getInstance().setControllerStatusCallback(this);
SweeperTaskModel.getInstance().setControllerStatusCallback(this);
SweeperTaskModel.getInstance().setAdasStatusCallback(this);
}
public void releaseListener() {
SweeperOrderModel.getInstance().setControllerStatusCallback(null);
SweeperTaskModel.getInstance().setControllerStatusCallback(null);
SweeperTaskModel.getInstance().setAdasStatusCallback(null);
}
public void restartAutopilot() {
currentAutopilotStatus = -1;
SweeperOrderModel.getInstance().restartAutopilot();
SweeperTaskModel.getInstance().restartAutopilot();
isRestartAutopilot = true;
}
@Override
@@ -79,13 +79,34 @@ public class SweeperPresenter extends Presenter<SweeperFragment>
int state = autopilotStatusInfo.getState();
switch (state) {
case IMoGoAutopilotStatusListener.STATUS_AUTOPILOT_ENABLE:
if (currentAutopilotStatus != IMoGoAutopilotStatusListener.STATUS_AUTOPILOT_ENABLE) {
currentAutopilotStatus = IMoGoAutopilotStatusListener.STATUS_AUTOPILOT_ENABLE;
}
// 改变UI自动驾驶状态
runOnUIThread(() -> mView.onAutopilotStatusChanged(currentAutopilotStatus));
break;
case IMoGoAutopilotStatusListener.STATUS_AUTOPILOT_RUNNING:
if (currentAutopilotStatus != IMoGoAutopilotStatusListener.STATUS_AUTOPILOT_RUNNING) {
currentAutopilotStatus = IMoGoAutopilotStatusListener.STATUS_AUTOPILOT_RUNNING;
SweeperTaskModel.getInstance().triggerStartServiceEvent(
SweeperTaskModel.getInstance().isRestartAutopilot(), true);
}
// 改变UI自动驾驶状态
runOnUIThread(() -> mView.onAutopilotStatusChanged(currentAutopilotStatus));
break;
case IMoGoAutopilotStatusListener.STATUS_AUTOPILOT_DISABLE:
if (currentAutopilotStatus != IMoGoAutopilotStatusListener.STATUS_AUTOPILOT_DISABLE) {
currentAutopilotStatus = IMoGoAutopilotStatusListener.STATUS_AUTOPILOT_DISABLE;
}
// 改变UI自动驾驶状态
runOnUIThread(() -> mView.onAutopilotStatusChanged(currentAutopilotStatus));
break;
default:
case IMoGoAutopilotStatusListener.STATUS_PARALLEL_DRIVING:
if (currentAutopilotStatus != IMoGoAutopilotStatusListener.STATUS_PARALLEL_DRIVING) {
currentAutopilotStatus = IMoGoAutopilotStatusListener.STATUS_PARALLEL_DRIVING;
}
// 改变UI自动驾驶状态
runOnUIThread(() -> mView.onAutopilotStatusChanged(currentAutopilotStatus));
break;
}
}
@@ -152,4 +173,9 @@ public class SweeperPresenter extends Presenter<SweeperFragment>
public void onAutopilotSNRequest() {
}
@Override
public void onStartAdasFailure() {
}
}

File diff suppressed because one or more lines are too long

View File

@@ -1,5 +1,6 @@
package com.mogo.och.sweeper.util;
import android.os.Build;
import android.text.TextUtils;
import com.mogo.cloud.passport.MoGoAiCloudClientConfig;
@@ -8,12 +9,15 @@ import com.mogo.eagle.core.data.app.AppConfigInfo;
import com.mogo.eagle.core.function.api.autopilot.IMoGoAutopilotStatusListener;
import com.mogo.eagle.core.function.call.analytics.AnalyticsManager;
import com.mogo.eagle.core.function.call.autopilot.CallerAutoPilotStatusListenerManager;
import com.mogo.eagle.core.utilcode.mogo.logger.CallerLogger;
import com.mogo.eagle.core.utilcode.util.DateTimeUtils;
import com.mogo.eagle.core.utilcode.util.UiThreadHandler;
import com.mogo.och.sweeper.constant.SweeperConst;
import java.util.HashMap;
import static com.mogo.eagle.core.utilcode.mogo.logger.scene.SceneConstant.M_SWEEPER;
/**
* OCH sweeper埋点工具
*
@@ -29,18 +33,55 @@ public class SweeperAnalyticsManager {
return SweeperAnalyticsManager.SingletonHolder.INSTANCE;
}
private String mStartAutopilotKey;
private HashMap<String, Object> mStartAutopilotParams = new HashMap<>();
private Runnable startAutopilotRunnable = () -> {
// 15s内未开启上报失败埋点
triggerStartAutopilotFailureEvent("", "15s后app等待超时");
};
public void triggerStartAutopilotFailureEventByAdas(String failCode, String failMsg){
removeWaitingCallback();
triggerStartAutopilotFailureEvent(failCode, failMsg);
}
private void triggerStartAutopilotFailureEvent(String failCode, String failMsg){
if (mStartAutopilotParams.isEmpty()) return;
CallerLogger.INSTANCE.e( M_SWEEPER + "triggerStartAutopilotFailureEvent", failMsg );
if (CallerAutoPilotStatusListenerManager.INSTANCE.getAutoPilotStatusInfo().getState() !=
IMoGoAutopilotStatusListener.STATUS_AUTOPILOT_RUNNING){
mStartAutopilotParams.put(SweeperConst.EVENT_PARAM_START_FAILURE_CODE, failCode);
mStartAutopilotParams.put(SweeperConst.EVENT_PARAM_START_FAILURE_MSG, failMsg);
}
mStartAutopilotParams.put(SweeperConst.EVENT_PARAM_START_RESULT
, CallerAutoPilotStatusListenerManager.INSTANCE.getAutoPilotStatusInfo().getState() ==
IMoGoAutopilotStatusListener.STATUS_AUTOPILOT_RUNNING);
AnalyticsManager.INSTANCE.track(mStartAutopilotKey, mStartAutopilotParams);
};
clearStartAutopilotParams();//清空参数数据,防止误传
}
private void removeWaitingCallback() {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
if (startAutopilotRunnable != null &&
UiThreadHandler.getsUiHandler().hasCallbacks(startAutopilotRunnable)) {
UiThreadHandler.removeCallbacks(startAutopilotRunnable);
}
}
}
public void clearStartAutopilotFailureMSG(){
mStartAutopilotParams.put(SweeperConst.EVENT_PARAM_START_FAILURE_CODE, "");
mStartAutopilotParams.put(SweeperConst.EVENT_PARAM_START_FAILURE_MSG, "");
}
private void clearStartAutopilotParams(){
mStartAutopilotParams.clear();
}
/**
* 触发'开启自动驾驶'埋点流程
@@ -67,15 +108,43 @@ public class SweeperAnalyticsManager {
mStartAutopilotParams.put(SweeperConst.EVENT_PARAM_LINE_ID, lineId);
if (send) {
if (mStartAutopilotParams.isEmpty()) return;
// 开启成功,上报埋点
if (startAutopilotRunnable != null &&
UiThreadHandler.getsUiHandler().hasCallbacks(startAutopilotRunnable)) {
UiThreadHandler.removeCallbacks(startAutopilotRunnable);
}
clearStartAutopilotFailureMSG();
removeWaitingCallback();
mStartAutopilotParams.put(SweeperConst.EVENT_PARAM_START_RESULT, true);
AnalyticsManager.INSTANCE.track(mStartAutopilotKey, mStartAutopilotParams);
clearStartAutopilotParams();//清空参数数据,防止误传
} else {
UiThreadHandler.postDelayed(startAutopilotRunnable, SweeperConst.LOOP_PERIOD_15S);
}
}
/**
* 触发"无法开启自驾已知异常"埋点
* @param startName
* @param endName
* @param lineId
*/
public void triggerUnableStartAPReasonEvent(String startName, String endName, int lineId,
String reason) {
String sn = MoGoAiCloudClientConfig.getInstance().getSn();
String plateNum = AppConfigInfo.INSTANCE.getPlateNumber();
String dateTime = DateTimeUtils.getTimeText(
System.currentTimeMillis(), DateTimeUtils.yyyy_MM_dd_HH_mm_ss);
HashMap<String, Object> params = new HashMap<>();
params.put(SweeperConst.EVENT_PARAM_SN, sn);
params.put(SweeperConst.EVENT_PARAM_PLATE_NUM, TextUtils.isEmpty(plateNum) ? "" : plateNum);
params.put(SweeperConst.EVENT_PARAM_ENV_ONLINE,
DebugConfig.getNetMode() == DebugConfig.NET_MODE_RELEASE ? true : false);
params.put(SweeperConst.EVENT_PARAM_TIME, dateTime);
params.put(SweeperConst.EVENT_PARAM_START_NAME, startName);
params.put(SweeperConst.EVENT_PARAM_END_NAME, endName);
params.put(SweeperConst.EVENT_PARAM_LINE_ID, lineId);
params.put(SweeperConst.EVENT_PARAM_UNABLE_START_REASON, reason);
AnalyticsManager.INSTANCE.track(SweeperConst.EVENT_KEY_AP_UNABLE_START_REASON, params);
}
}

View File

@@ -8,7 +8,7 @@ import com.mogo.eagle.core.utilcode.mogo.logger.CallerLogger;
import com.mogo.eagle.core.utilcode.util.GsonUtils;
import com.mogo.och.sweeper.bean.SweeperRoutesResult;
import com.mogo.och.sweeper.constant.SweeperConst;
import com.mogo.och.sweeper.model.SweeperOrderModel;
import com.mogo.och.sweeper.model.SweeperTaskModel;
import java.util.concurrent.TimeUnit;
@@ -48,10 +48,10 @@ public class SweeperTrajectoryManager {
* 同步Bus路线信息
*/
public void syncTrajectoryInfo() {
SweeperRoutesResult routesResult = SweeperOrderModel.getInstance().getBusRoutesResult();
if (SweeperOrderModel.getInstance().isWorking() && routesResult != null
&& SweeperOrderModel.getInstance().getCurrentStationIndex() == 0
&& !SweeperOrderModel.getInstance().isGoingToNextStation()) {
SweeperRoutesResult routesResult = SweeperTaskModel.getInstance().getBusRoutesResult();
if (routesResult != null
&& SweeperTaskModel.getInstance().getCurrentStationIndex() == 0
&& !SweeperTaskModel.getInstance().isGoingToNextStation()) {
CallerLogger.INSTANCE.d(M_BUS + TAG, "syncTrajectoryInfo() start.");
startTrajReqLoop();
} else {
@@ -95,7 +95,7 @@ public class SweeperTrajectoryManager {
}
private void setupAutoPilotLine() {
SweeperRoutesResult routesResult = SweeperOrderModel.getInstance().getBusRoutesResult();
SweeperRoutesResult routesResult = SweeperTaskModel.getInstance().getBusRoutesResult();
if (routesResult == null) {
CallerLogger.INSTANCE.e(M_BUS + TAG,
"setupAutoPilotLine(): routesResult is null.");

View File

@@ -4,7 +4,8 @@
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginTop="@dimen/dp_72">
android:layout_marginTop="@dimen/dp_72"
android:id="@+id/sweeper_root_View">
<!--车辆基本交通信息-->
<com.mogo.och.sweeper.view.SweeperTrafficDataView
android:id="@+id/sweeper_arc"