merge special relase to m1-p
@@ -85,6 +85,8 @@ public class AmapNaviToDestinationModel implements AMapNaviListener {
|
||||
public void destroyAmaNavi(){
|
||||
if (mAMapNavi != null){
|
||||
isPlay = false;
|
||||
sList.clear();
|
||||
eList.clear();
|
||||
mAMapNavi.stopNavi();
|
||||
mAMapNavi.destroy();
|
||||
mAMapNavi = null;
|
||||
|
||||
@@ -18,7 +18,7 @@ android {
|
||||
|
||||
javaCompileOptions {
|
||||
annotationProcessorOptions {
|
||||
arguments = [AROUTER_MODULE_NAME: project.getName()]
|
||||
arguments = [AROUTER_MODULE_NAME: project.getName(),"room.schemaLocation": "$projectDir/schemas".toString()]
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -52,6 +52,9 @@ dependencies {
|
||||
implementation rootProject.ext.dependencies.rxjava
|
||||
implementation rootProject.ext.dependencies.rxandroid
|
||||
implementation rootProject.ext.dependencies.androidxrecyclerview
|
||||
implementation rootProject.ext.dependencies.androidxcardview
|
||||
implementation rootProject.ext.dependencies.androidxroomruntime
|
||||
annotationProcessor rootProject.ext.dependencies.androidxroomcompiler
|
||||
|
||||
implementation project(":OCH:mogo-och-common-module")
|
||||
compileOnly project(":libraries:mogo-map")
|
||||
|
||||
@@ -11,10 +11,6 @@
|
||||
<category android:name="android.intent.category.DEFAULT" />
|
||||
</intent-filter>
|
||||
</receiver>
|
||||
<activity android:name=".ui.SweeperSwitchLineActivity"
|
||||
android:theme="@style/SwitchLineDialogStyle"
|
||||
android:launchMode="singleTask"
|
||||
android:screenOrientation="landscape" />/>
|
||||
</application>
|
||||
|
||||
</manifest>
|
||||
BIN
OCH/mogo-och-sweeper/src/main/assets/map_style.data
Normal file
BIN
OCH/mogo-och-sweeper/src/main/assets/map_style_extra.data
Normal file
@@ -5,9 +5,11 @@ import android.content.Context;
|
||||
|
||||
import androidx.fragment.app.Fragment;
|
||||
import androidx.fragment.app.FragmentActivity;
|
||||
import androidx.fragment.app.FragmentManager;
|
||||
|
||||
import com.alibaba.android.arouter.facade.annotation.Route;
|
||||
import com.mogo.eagle.core.utilcode.mogo.logger.CallerLogger;
|
||||
import com.mogo.map.uicontroller.IMogoMapUIController;
|
||||
import com.mogo.och.sweeper.constant.SweeperConst;
|
||||
import com.mogo.och.sweeper.fragment.SweeperFragment;
|
||||
|
||||
@@ -31,18 +33,24 @@ public class SweeperProvider implements IMogoOCH {
|
||||
@Override
|
||||
public void init(Context context) {
|
||||
}
|
||||
|
||||
private void showFragment() {
|
||||
FragmentManager supportFragmentManager = activity.getSupportFragmentManager();
|
||||
if (sweeperFragment == null) {
|
||||
CallerLogger.INSTANCE.d(TAG, "准备add fragment======");
|
||||
sweeperFragment = new SweeperFragment();
|
||||
activity.getSupportFragmentManager().beginTransaction().add(containerId, sweeperFragment).commitAllowingStateLoss();
|
||||
Fragment fragmentByTag = supportFragmentManager.findFragmentByTag(sweeperFragment.TAG);
|
||||
if (fragmentByTag instanceof SweeperFragment) {
|
||||
sweeperFragment = (SweeperFragment) fragmentByTag;
|
||||
} else {
|
||||
sweeperFragment = new SweeperFragment();
|
||||
}
|
||||
if(!sweeperFragment.isAdded()) {
|
||||
supportFragmentManager.beginTransaction().add(containerId, sweeperFragment, sweeperFragment.TAG).commitAllowingStateLoss();
|
||||
}
|
||||
return;
|
||||
}
|
||||
CallerLogger.INSTANCE.d(TAG, "准备show fragment");
|
||||
activity.getSupportFragmentManager().beginTransaction().show(sweeperFragment).commitAllowingStateLoss();
|
||||
supportFragmentManager.beginTransaction().show(sweeperFragment).commitAllowingStateLoss();
|
||||
}
|
||||
|
||||
private void hideFragment() {
|
||||
if (sweeperFragment != null) {
|
||||
CallerLogger.INSTANCE.d(TAG, "准备hide fragment");
|
||||
|
||||
@@ -0,0 +1,31 @@
|
||||
package com.mogo.och.sweeper.bean;
|
||||
|
||||
import com.mogo.eagle.core.data.BaseData;
|
||||
|
||||
public class BaseResponse<T> extends BaseData {
|
||||
private T data;
|
||||
|
||||
public int getCode() {
|
||||
return code;
|
||||
}
|
||||
|
||||
public void setCode(int code) {
|
||||
this.code = code;
|
||||
}
|
||||
|
||||
public String getMsg() {
|
||||
return msg;
|
||||
}
|
||||
|
||||
public void setMsg(String msg) {
|
||||
this.msg = msg;
|
||||
}
|
||||
|
||||
public T getData() {
|
||||
return data;
|
||||
}
|
||||
|
||||
public void setData(T data) {
|
||||
this.data = data;
|
||||
}
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
@@ -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:taxi,10: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;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
package com.mogo.och.sweeper.bean
|
||||
|
||||
import com.mogo.cloud.passport.MoGoAiCloudClientConfig
|
||||
|
||||
data class SubStartRequest(
|
||||
var carSn:String=MoGoAiCloudClientConfig.getInstance().sn,
|
||||
var taskId:Int,
|
||||
var startTime:Long,
|
||||
var isFirst:Boolean,
|
||||
var isEnd:Boolean
|
||||
)
|
||||
@@ -0,0 +1,14 @@
|
||||
package com.mogo.och.sweeper.bean
|
||||
|
||||
/**
|
||||
*
|
||||
* 清扫车任务信息
|
||||
*
|
||||
* @author tongchenfei
|
||||
*/
|
||||
data class SweeperMainTaskBean(
|
||||
var mainTaskId:Int = 0,
|
||||
var mainTaskName: String? = null,
|
||||
var subTaskTotal:Int = 0,
|
||||
var mainTaskStartTime: Long = 0
|
||||
)
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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:已出车
|
||||
|
||||
}
|
||||
}
|
||||
@@ -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 +
|
||||
'}';
|
||||
}
|
||||
}
|
||||
@@ -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 +
|
||||
'}';
|
||||
}
|
||||
}
|
||||
@@ -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; // 默认false;true:是否需要返回站点的行驶状态,对应返回的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;
|
||||
// }
|
||||
}
|
||||
@@ -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;//终点名称
|
||||
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
@@ -1,5 +1,6 @@
|
||||
package com.mogo.och.sweeper.bean;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
@@ -7,7 +8,7 @@ import java.util.List;
|
||||
*
|
||||
* 订单状态更新请求数据结构
|
||||
*/
|
||||
public class SweeperRoutePlanningUpdateReqBean {
|
||||
public class SweeperRoutePlanningUpdateReqBean implements Serializable {
|
||||
public String sn;
|
||||
public int lineId;
|
||||
public int startSiteId;
|
||||
|
||||
@@ -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 +
|
||||
'}';
|
||||
}
|
||||
}
|
||||
@@ -1,69 +0,0 @@
|
||||
package com.mogo.och.sweeper.bean;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 网约车小巴路线接口返回接口数据封装
|
||||
*
|
||||
* @author tongchenfei
|
||||
*/
|
||||
public class SweeperRoutesResult {
|
||||
private List<SweeperStationBean> sites;
|
||||
private int lineId;
|
||||
private String name;
|
||||
private int lineType; //线路类型,0:环形
|
||||
private String description;
|
||||
private int status;
|
||||
|
||||
//线路轨迹相关字段
|
||||
public String csvFileUrl = ""; //轨迹文件下载的cos url,默认“”
|
||||
public String csvFileMd5 = ""; //轨迹文件md5,默认“”
|
||||
public String txtFileUrl = ""; //打点文件下载的cos url,默认“”
|
||||
public String txtFileMd5 = ""; //轨迹文件md5,默认“”
|
||||
public long contrailSaveTime; //上传轨迹完成时间戳ms:用于MEC本地手动导入轨迹验证时不会被云端轨迹覆盖
|
||||
public String carModel = ""; //[optional] 车型号(如红旗H9),默认“”,暂不加入校验逻辑、用于人工排查问题
|
||||
public String csvFileUrlDPQP = ""; //轨迹文件下载的cos url,默认“”
|
||||
public String csvFileMd5DPQP = ""; //轨迹文件md5,默认“”
|
||||
public String txtFileUrlDPQP = ""; //打点文件下载的cos url,默认“”
|
||||
public String txtFileMd5DPQP = ""; //轨迹文件md5,默认“”
|
||||
public long contrailSaveTimeDPQP; //上传轨迹完成时间戳ms:用于MEC本地手动导入轨迹验证时不会被云端轨迹覆盖
|
||||
|
||||
public int getLineId() {
|
||||
return lineId;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public List<SweeperStationBean> getSites() {
|
||||
return sites;
|
||||
}
|
||||
|
||||
public void setSite(List<SweeperStationBean> site) {
|
||||
this.sites = sites;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "BusRoutesResult{" +
|
||||
"sites=" + sites +
|
||||
", lineId=" + lineId +
|
||||
", name='" + name + '\'' +
|
||||
", lineType=" + lineType +
|
||||
", description='" + description + '\'' +
|
||||
", status=" + status +
|
||||
", csvFileUrl='" + csvFileUrl + '\'' +
|
||||
", csvFileMd5='" + csvFileMd5 + '\'' +
|
||||
", txtFileUrl='" + txtFileUrl + '\'' +
|
||||
", txtFileMd5='" + txtFileMd5 + '\'' +
|
||||
", contrailSaveTime=" + contrailSaveTime +
|
||||
", carModel='" + carModel + '\'' +
|
||||
", csvFileUrlDPQP='" + csvFileUrlDPQP + '\'' +
|
||||
", csvFileMd5DPQP='" + csvFileMd5DPQP + '\'' +
|
||||
", txtFileUrlDPQP='" + txtFileUrlDPQP + '\'' +
|
||||
", txtFileMd5DPQP='" + txtFileMd5DPQP + '\'' +
|
||||
", contrailSaveTimeDPQP=" + contrailSaveTimeDPQP +
|
||||
'}';
|
||||
}
|
||||
}
|
||||
@@ -1,162 +0,0 @@
|
||||
package com.mogo.och.sweeper.bean;
|
||||
|
||||
/**
|
||||
* 单个网约车小巴车站信息
|
||||
*
|
||||
* @author tongchenfei
|
||||
*/
|
||||
public class SweeperStationBean {
|
||||
// private int lineId;
|
||||
// private int siteId;
|
||||
// private String siteName;
|
||||
// private String cityCode;
|
||||
// private String areaCode;
|
||||
// private String areaName;
|
||||
// private double lat;
|
||||
// private double lon;
|
||||
// private String siteDesc;
|
||||
// private int siteState;
|
||||
// private int isCurrentSite;// @see OchBusConst 是否是当前站 1:是 2:下一站 0:普通站
|
||||
// private int siteColor;
|
||||
// private String peoples;
|
||||
// private int ifStop; // 是否需要停靠、1需要、0不需要
|
||||
|
||||
|
||||
private String name;
|
||||
private String description;
|
||||
private String cityCode;
|
||||
private double lon; //高精坐标
|
||||
private double lat; //高精坐标
|
||||
private int businessType; //站点类型,9:taxi,10:bus
|
||||
private double gcjLon; //高德
|
||||
private double gcjLat; //高德
|
||||
private int status;
|
||||
private int siteId;
|
||||
private int seq;
|
||||
private int drivingStatus;//行驶信息,0初始值;1已经过;2当前站;3未到站
|
||||
private int ifStop = 1; // 是否需要停靠、1需要、0不需要 // TODO: 2021/10/19 原来站点里有设计是否需要停靠字段,现设计暂无,默认都需要停靠
|
||||
private boolean leaving;
|
||||
|
||||
public double getGcjLon() {
|
||||
return gcjLon;
|
||||
}
|
||||
|
||||
public double getGcjLat() {
|
||||
return gcjLat;
|
||||
}
|
||||
|
||||
public void setName(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
public void setDescription(String description) {
|
||||
this.description = description;
|
||||
}
|
||||
|
||||
public void setCityCode(String cityCode) {
|
||||
this.cityCode = cityCode;
|
||||
}
|
||||
|
||||
public void setLon(double lon) {
|
||||
this.lon = lon;
|
||||
}
|
||||
|
||||
public void setLat(double lat) {
|
||||
this.lat = lat;
|
||||
}
|
||||
|
||||
public void setBusinessType(int businessType) {
|
||||
this.businessType = businessType;
|
||||
}
|
||||
|
||||
public void setStatus(int status) {
|
||||
this.status = status;
|
||||
}
|
||||
|
||||
public void setSiteId(int siteId) {
|
||||
this.siteId = siteId;
|
||||
}
|
||||
|
||||
public void setSeq(int seq) {
|
||||
this.seq = seq;
|
||||
}
|
||||
|
||||
public void setDrivingStatus(int drivingStatus) {
|
||||
this.drivingStatus = drivingStatus;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public String getDescription() {
|
||||
return description;
|
||||
}
|
||||
|
||||
public String getCityCode() {
|
||||
return cityCode;
|
||||
}
|
||||
|
||||
|
||||
public int getBusinessType() {
|
||||
return businessType;
|
||||
}
|
||||
|
||||
public int getStatus() {
|
||||
return status;
|
||||
}
|
||||
|
||||
public int getSiteId() {
|
||||
return siteId;
|
||||
}
|
||||
|
||||
public int getSeq() {
|
||||
return seq;
|
||||
}
|
||||
|
||||
public int getDrivingStatus() {
|
||||
return drivingStatus;
|
||||
}
|
||||
|
||||
public double getLon() {
|
||||
return lon;
|
||||
}
|
||||
|
||||
public double getLat() {
|
||||
return lat;
|
||||
}
|
||||
|
||||
public void setIfStop(int ifStop) {
|
||||
this.ifStop = ifStop;
|
||||
}
|
||||
|
||||
public int getIfStop() {
|
||||
return ifStop;
|
||||
}
|
||||
|
||||
public void setLeaving(boolean leaving) {
|
||||
this.leaving = leaving;
|
||||
}
|
||||
|
||||
public boolean isLeaving() {
|
||||
return leaving;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "BusStationBean{" +
|
||||
"name='" + name + '\'' +
|
||||
", description='" + description + '\'' +
|
||||
", cityCode='" + cityCode + '\'' +
|
||||
", lon=" + lon +
|
||||
", lat=" + lat +
|
||||
", businessType=" + businessType +
|
||||
", status=" + status +
|
||||
", siteId=" + siteId +
|
||||
", seq=" + seq +
|
||||
", drivingStatus=" + drivingStatus +
|
||||
", ifStop=" + ifStop +
|
||||
", leaving=" + leaving +
|
||||
'}';
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,28 @@
|
||||
package com.mogo.och.sweeper.bean
|
||||
|
||||
/**
|
||||
* 子任务信息
|
||||
*/
|
||||
data class SweeperSubTaskBean(
|
||||
var taskId: Int = 0,
|
||||
var taskName: String?,
|
||||
var taskStartTime: Long = 0,
|
||||
var sort: Int = 1,
|
||||
var subList: MutableList<SubInfo>?
|
||||
)
|
||||
|
||||
data class SubInfo(
|
||||
var taskId: Int = 0,
|
||||
var taskName: String?,
|
||||
var mileage: Int = 0,
|
||||
var taskStatus: Int,// 状态1未执行 2执行中 3结束 4跳过
|
||||
var taskType: Int,//1自动驾驶 2人工驾驶
|
||||
var timeSpent: String,
|
||||
var startSiteName: String,//起点名称
|
||||
var startWgs84Lon: Double,//起点经度
|
||||
var startWgs84Lat: Double,//起点纬度
|
||||
var endSiteName: String,//终点名称
|
||||
var endWgs84Lon: Double,//终点经度
|
||||
var endWgs84Lat: Double,//终点纬度
|
||||
var sort: Int = 0,
|
||||
)
|
||||
@@ -0,0 +1,314 @@
|
||||
package com.mogo.och.sweeper.bean;
|
||||
|
||||
public class SweeperSubTaskDetailBean {
|
||||
private int id; //子任务id
|
||||
private int lineId; //线路id
|
||||
private String lineName;//线路名称
|
||||
private int sort;
|
||||
private int status;
|
||||
private int startSiteId; //子任务起点id
|
||||
private String startSiteName; //子任务起点名称
|
||||
private double startSiteLon; //子任务起点高德经度
|
||||
private double startSiteLat; //子任务起点高德纬度
|
||||
private double startSiteWgs64Lon;//子任务起点高精经度
|
||||
private double startSiteWgs64Lat;//子任务起点高精纬度
|
||||
private int endSiteId;//子任务终点id
|
||||
private String endSiteName;//子任务终点名称
|
||||
private double endSiteLon; //子任务终点高德经度
|
||||
private double endSiteLat;//子任务终点高德纬度
|
||||
private double endSiteWgs64Lon;//子任务终点高精经度
|
||||
private double endSiteWgs64Lat;//子任务终点高精纬度
|
||||
private String brand; //品牌
|
||||
private String carModel; //车辆型号
|
||||
private String csvFileUrl = ""; //轨迹文件csv文件url地址
|
||||
private String csvFileMd5 = ""; //轨迹文件csv md5
|
||||
private String csvFileName = "";//轨迹文件cvs名称
|
||||
private String txtFileUrl = ""; //轨迹文件txt url地址
|
||||
private String txtFileMd5 = ""; //轨迹文件txt md5
|
||||
private String txtFileName; //轨迹文件txt名称
|
||||
private long publishTime;
|
||||
private String contrailFileType; //轨迹文件类型
|
||||
private String publishStatus;//发布状态 1发布 2未发布 3 发布中
|
||||
private String csvFileUrlDPQP = ""; //轨迹文件下载的cos url,默认“”
|
||||
private String csvFileMd5DPQP = ""; //轨迹文件md5,默认“”
|
||||
private String txtFileUrlDPQP = ""; //打点文件下载的cos url,默认“”
|
||||
private String txtFileMd5DPQP = ""; //轨迹文件md5,默认“”
|
||||
private long publishTimeDPQP; //上传轨迹完成时间戳ms:用于MEC本地手动导入轨迹验证时不会被云端轨迹覆盖
|
||||
private long taskCreateTime;
|
||||
private String brandDPQP;
|
||||
private String carModelDPQP;
|
||||
|
||||
public int getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public void setId(int id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
public int getLineId() {
|
||||
return lineId;
|
||||
}
|
||||
|
||||
public void setLineId(int lineId) {
|
||||
this.lineId = lineId;
|
||||
}
|
||||
|
||||
public String getLineName() {
|
||||
return lineName;
|
||||
}
|
||||
|
||||
public void setLineName(String lineName) {
|
||||
this.lineName = lineName;
|
||||
}
|
||||
|
||||
public int getSort() {
|
||||
return sort;
|
||||
}
|
||||
|
||||
public void setSort(int sort) {
|
||||
this.sort = sort;
|
||||
}
|
||||
|
||||
public int getStatus() {
|
||||
return status;
|
||||
}
|
||||
|
||||
public void setStatus(int status) {
|
||||
this.status = status;
|
||||
}
|
||||
|
||||
public int getStartSiteId() {
|
||||
return startSiteId;
|
||||
}
|
||||
|
||||
public void setStartSiteId(int startSiteId) {
|
||||
this.startSiteId = startSiteId;
|
||||
}
|
||||
|
||||
public String getStartSiteName() {
|
||||
return startSiteName;
|
||||
}
|
||||
|
||||
public void setStartSiteName(String startSiteName) {
|
||||
this.startSiteName = startSiteName;
|
||||
}
|
||||
|
||||
public double getStartSiteLon() {
|
||||
return startSiteLon;
|
||||
}
|
||||
|
||||
public void setStartSiteLon(double startSiteLon) {
|
||||
this.startSiteLon = startSiteLon;
|
||||
}
|
||||
|
||||
public double getStartSiteLat() {
|
||||
return startSiteLat;
|
||||
}
|
||||
|
||||
public void setStartSiteLat(double startSiteLat) {
|
||||
this.startSiteLat = startSiteLat;
|
||||
}
|
||||
|
||||
public double getStartSiteWgs64Lon() {
|
||||
return startSiteWgs64Lon;
|
||||
}
|
||||
|
||||
public void setStartSiteWgs64Lon(double startSiteWgs64Lon) {
|
||||
this.startSiteWgs64Lon = startSiteWgs64Lon;
|
||||
}
|
||||
|
||||
public double getStartSiteWgs64Lat() {
|
||||
return startSiteWgs64Lat;
|
||||
}
|
||||
|
||||
public void setStartSiteWgs64Lat(double startSiteWgs64Lat) {
|
||||
this.startSiteWgs64Lat = startSiteWgs64Lat;
|
||||
}
|
||||
|
||||
public int getEndSiteId() {
|
||||
return endSiteId;
|
||||
}
|
||||
|
||||
public void setEndSiteId(int endSiteId) {
|
||||
this.endSiteId = endSiteId;
|
||||
}
|
||||
|
||||
public String getEndSiteName() {
|
||||
return endSiteName;
|
||||
}
|
||||
|
||||
public void setEndSiteName(String endSiteName) {
|
||||
this.endSiteName = endSiteName;
|
||||
}
|
||||
|
||||
public double getEndSiteLon() {
|
||||
return endSiteLon;
|
||||
}
|
||||
|
||||
public void setEndSiteLon(double endSiteLon) {
|
||||
this.endSiteLon = endSiteLon;
|
||||
}
|
||||
|
||||
public double getEndSiteLat() {
|
||||
return endSiteLat;
|
||||
}
|
||||
|
||||
public void setEndSiteLat(double endSiteLat) {
|
||||
this.endSiteLat = endSiteLat;
|
||||
}
|
||||
|
||||
public double getEndSiteWgs64Lon() {
|
||||
return endSiteWgs64Lon;
|
||||
}
|
||||
|
||||
public void setEndSiteWgs64Lon(double endSiteWgs64Lon) {
|
||||
this.endSiteWgs64Lon = endSiteWgs64Lon;
|
||||
}
|
||||
|
||||
public double getEndSiteWgs64Lat() {
|
||||
return endSiteWgs64Lat;
|
||||
}
|
||||
|
||||
public void setEndSiteWgs64Lat(double endSiteWgs64Lat) {
|
||||
this.endSiteWgs64Lat = endSiteWgs64Lat;
|
||||
}
|
||||
|
||||
public long getTaskCreateTime() {
|
||||
return taskCreateTime;
|
||||
}
|
||||
|
||||
public void setTaskCreateTime(long taskCreateTime) {
|
||||
this.taskCreateTime = taskCreateTime;
|
||||
}
|
||||
|
||||
public String getBrand() {
|
||||
return brand;
|
||||
}
|
||||
|
||||
public void setBrand(String brand) {
|
||||
this.brand = brand;
|
||||
}
|
||||
|
||||
public String getCarModel() {
|
||||
return carModel;
|
||||
}
|
||||
|
||||
public void setCarModel(String carModel) {
|
||||
this.carModel = carModel;
|
||||
}
|
||||
|
||||
public String getCsvFileUrl() {
|
||||
return csvFileUrl;
|
||||
}
|
||||
|
||||
public void setCsvFileUrl(String csvFileUrl) {
|
||||
this.csvFileUrl = csvFileUrl;
|
||||
}
|
||||
|
||||
public String getCsvFileMd5() {
|
||||
return csvFileMd5;
|
||||
}
|
||||
|
||||
public void setCsvFileMd5(String csvFileMd5) {
|
||||
this.csvFileMd5 = csvFileMd5;
|
||||
}
|
||||
|
||||
public String getCsvFileName() {
|
||||
return csvFileName;
|
||||
}
|
||||
|
||||
public void setCsvFileName(String csvFileName) {
|
||||
this.csvFileName = csvFileName;
|
||||
}
|
||||
|
||||
public String getTxtFileUrl() {
|
||||
return txtFileUrl;
|
||||
}
|
||||
|
||||
public void setTxtFileUrl(String txtFileUrl) {
|
||||
this.txtFileUrl = txtFileUrl;
|
||||
}
|
||||
|
||||
public String getTxtFileMd5() {
|
||||
return txtFileMd5;
|
||||
}
|
||||
|
||||
public void setTxtFileMd5(String txtFileMd5) {
|
||||
this.txtFileMd5 = txtFileMd5;
|
||||
}
|
||||
|
||||
public String getTxtFileName() {
|
||||
return txtFileName;
|
||||
}
|
||||
|
||||
public void setTxtFileName(String txtFileName) {
|
||||
this.txtFileName = txtFileName;
|
||||
}
|
||||
|
||||
public long getPublishTime() {
|
||||
return publishTime;
|
||||
}
|
||||
|
||||
public void setPublishTime(long publishTime) {
|
||||
this.publishTime = publishTime;
|
||||
}
|
||||
|
||||
public String getBrandDPQP() {
|
||||
return brandDPQP;
|
||||
}
|
||||
|
||||
public void setBrandDPQP(String brandDPQP) {
|
||||
this.brandDPQP = brandDPQP;
|
||||
}
|
||||
|
||||
public String getCarModelDPQP() {
|
||||
return carModelDPQP;
|
||||
}
|
||||
|
||||
public void setCarModelDPQP(String carModelDPQP) {
|
||||
this.carModelDPQP = carModelDPQP;
|
||||
}
|
||||
|
||||
public String getCsvFileUrlDPQP() {
|
||||
return csvFileUrlDPQP;
|
||||
}
|
||||
|
||||
public void setCsvFileUrlDPQP(String csvFileUrlDPQP) {
|
||||
this.csvFileUrlDPQP = csvFileUrlDPQP;
|
||||
}
|
||||
|
||||
public String getCsvFileMd5DPQP() {
|
||||
return csvFileMd5DPQP;
|
||||
}
|
||||
|
||||
public void setCsvFileMd5DPQP(String csvFileMd5DPQP) {
|
||||
this.csvFileMd5DPQP = csvFileMd5DPQP;
|
||||
}
|
||||
|
||||
public String getTxtFileUrlDPQP() {
|
||||
return txtFileUrlDPQP;
|
||||
}
|
||||
|
||||
public void setTxtFileUrlDPQP(String txtFileUrlDPQP) {
|
||||
this.txtFileUrlDPQP = txtFileUrlDPQP;
|
||||
}
|
||||
|
||||
public String getTxtFileMd5DPQP() {
|
||||
return txtFileMd5DPQP;
|
||||
}
|
||||
|
||||
public void setTxtFileMd5DPQP(String txtFileMd5DPQP) {
|
||||
this.txtFileMd5DPQP = txtFileMd5DPQP;
|
||||
}
|
||||
|
||||
public long getPublishTimeDPQP() {
|
||||
return publishTimeDPQP;
|
||||
}
|
||||
|
||||
public void setPublishTimeDPQP(long publishTimeDPQP) {
|
||||
this.publishTimeDPQP = publishTimeDPQP;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
@@ -1,9 +0,0 @@
|
||||
package com.mogo.och.sweeper.callback;
|
||||
|
||||
/**
|
||||
* @author: wangmingjun
|
||||
* @date: 2021/10/22
|
||||
*/
|
||||
public interface ICarOperationStatusCallback {
|
||||
void changeOperationStatus(boolean changeStatus);
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
package com.mogo.och.sweeper.callback;
|
||||
|
||||
import com.mogo.och.sweeper.constant.OperateStateEnum;
|
||||
|
||||
import chassis.ChassisStatesOuterClass;
|
||||
|
||||
/**
|
||||
* 上装状态回调
|
||||
*/
|
||||
public interface ICleaningModeStateCallback {
|
||||
void cleaningModeState(OperateStateEnum cleaningModeState, ChassisStatesOuterClass.SweeperFuTianTaskSystemStates cleanSystemState,boolean isSelectPureSweepMode);
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
@@ -1,9 +0,0 @@
|
||||
package com.mogo.och.sweeper.callback;
|
||||
|
||||
/**
|
||||
* @author: wangmingjun
|
||||
* @date: 2021/10/22
|
||||
*/
|
||||
public interface ISlidePannelHideCallback {
|
||||
void hideSlidePanel();
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
package com.mogo.och.sweeper.callback;
|
||||
|
||||
/**
|
||||
* Created on 2021/9/8
|
||||
*
|
||||
* Model->Presenter回调:ADAS相关(自动驾驶状态回调,到达终点等等)
|
||||
*/
|
||||
public interface ISweeperADASStatusCallback {
|
||||
//自驾返回失败
|
||||
void onStartAdasFailure();
|
||||
}
|
||||
@@ -1,12 +0,0 @@
|
||||
package com.mogo.och.sweeper.callback;
|
||||
|
||||
import com.mogo.och.sweeper.bean.SweeperQueryLinesResponse;
|
||||
|
||||
/**
|
||||
* @author: wangmingjun
|
||||
* @date: 2022/2/9
|
||||
*/
|
||||
public interface ISweeperLinesCallback {
|
||||
void onBusLinesChange(SweeperQueryLinesResponse lines);
|
||||
void onChangeLineIdSuccess();
|
||||
}
|
||||
@@ -0,0 +1,46 @@
|
||||
package com.mogo.och.sweeper.callback
|
||||
|
||||
import com.mogo.och.sweeper.bean.SweeperMainTaskBean
|
||||
import com.mogo.och.sweeper.bean.SweeperRoutePlanningUpdateReqBean
|
||||
import com.mogo.och.sweeper.bean.SweeperSubTaskBean
|
||||
import com.mogo.och.sweeper.bean.SweeperSubTaskDetailBean
|
||||
import com.mogo.och.sweeper.constant.SubTaskTypeEnum
|
||||
import com.mogo.och.sweeper.constant.TaskStatusEnum
|
||||
import java.util.ArrayList
|
||||
|
||||
/**
|
||||
* @author: wangmingjun
|
||||
* @date: 2021/10/22
|
||||
*/
|
||||
interface ISweeperTaskCallback {
|
||||
/**
|
||||
* 获取主任务列表
|
||||
*/
|
||||
fun setMainTaskList(mainTaskBeanList: MutableList<SweeperMainTaskBean>?,refresh:Boolean)
|
||||
|
||||
/**
|
||||
* 获取子任务列表
|
||||
*/
|
||||
fun setSubTaskBean(subTaskBean: SweeperSubTaskBean,isWorkingSubTask:Boolean)
|
||||
|
||||
/**
|
||||
* 更新子任务状态
|
||||
*/
|
||||
fun updateSubTaskStatus(typeEnum: TaskStatusEnum, isLastSubTask: Boolean)
|
||||
|
||||
/**
|
||||
* 主任务重置
|
||||
*/
|
||||
fun setMainTaskReset(isSuccess: Boolean)
|
||||
|
||||
/**
|
||||
* 获取子任务详情包括轨迹信息
|
||||
*/
|
||||
fun setSubTakDetail(subTaskDetailBean: SweeperSubTaskDetailBean,subTaskTypeEnum: SubTaskTypeEnum)
|
||||
|
||||
/**
|
||||
* 设置轨迹坐标点集合
|
||||
*/
|
||||
fun setRouteList(routeList: ArrayList<SweeperRoutePlanningUpdateReqBean.Result>)
|
||||
|
||||
}
|
||||
@@ -0,0 +1,15 @@
|
||||
package com.mogo.och.sweeper.callback
|
||||
|
||||
import com.amap.api.maps.model.LatLng
|
||||
import com.mogo.och.sweeper.bean.SweeperRoutePlanningUpdateReqBean
|
||||
import com.mogo.och.sweeper.database.bean.WeltDataBean
|
||||
import java.util.ArrayList
|
||||
|
||||
interface ISweeperTaskDataToFragmentCallback {
|
||||
fun setRouteList(routeList: ArrayList<SweeperRoutePlanningUpdateReqBean.Result>)
|
||||
fun setWeltData(weltDatas: ArrayList<WeltDataBean>?, distance: String)
|
||||
fun clearAllMarkerAndPolyline()
|
||||
fun setProgress(progress:String)
|
||||
fun setTaskListCoordinatesLatLng(coordinatesLatLng: ArrayList<LatLng>)
|
||||
fun setCurrentTaskCoordinatesLatLng(coordinatesLatLng: LatLng)
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
package com.mogo.och.sweeper.callback
|
||||
|
||||
import com.mogo.och.sweeper.bean.SweeperRoutePlanningUpdateReqBean
|
||||
import java.util.ArrayList
|
||||
|
||||
interface ISweeperTaskRouteCallback {
|
||||
fun setRouteList(routeList:ArrayList<SweeperRoutePlanningUpdateReqBean.Result>)
|
||||
}
|
||||
@@ -0,0 +1,5 @@
|
||||
package com.mogo.och.sweeper.callback
|
||||
|
||||
interface IWeltMapSwitchToSmallCallback {
|
||||
fun onWeltMapSwitchToSmall()
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
package com.mogo.och.sweeper.constant
|
||||
|
||||
/**
|
||||
* 上装面板操作状态
|
||||
*/
|
||||
enum class OperateStateEnum(val code: Int) {
|
||||
SYNCING_STATUS( 1),//清扫车底盘状态同步中
|
||||
STARTING_STATUS( 2),//上装中
|
||||
FAIL_STATUS( 3),//上装失败
|
||||
SUCCESS_STATUS(4),//上装成功
|
||||
NO_STATUS(-1);//暂无模式
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
package com.mogo.och.sweeper.constant
|
||||
|
||||
/**
|
||||
* 任务类型
|
||||
*/
|
||||
enum class SubTaskTypeEnum(val code: Int) {
|
||||
AUTOPILOT_SUBTYPE(1),//自动驾驶子任务
|
||||
MANUAL_DRIVING_SUBTYPE(2),//人工驾驶
|
||||
}
|
||||
@@ -13,34 +13,30 @@ class SweeperConst {
|
||||
|
||||
// 测试用的广播
|
||||
const val BROADCAST_TEST_SWEEPER_CONTROL_TYPE_EXTRA_KEY = "sceneType"
|
||||
// 无状态
|
||||
const val STATION_STATUS_IDLE = 0
|
||||
// 已过站(历史站)
|
||||
const val STATION_STATUS_LEAVING = 1
|
||||
// 到站(当前站)
|
||||
const val STATION_STATUS_STOPPED = 2
|
||||
// 未到站(未到站)
|
||||
const val STATION_STATUS_ARRIVING = 3
|
||||
|
||||
// 上报心跳轮询ms
|
||||
const val LOOP_PERIOD_60S = 60 * 1000L
|
||||
|
||||
// 开始服务启动自动驾驶等待时间(埋点上传)
|
||||
const val LOOP_PERIOD_15S = 15 * 1000L
|
||||
const val LOOP_PERIOD_1S = 1 * 1000L
|
||||
const val LOOP_DELAY = 100L
|
||||
|
||||
// 下发给MEC轨迹信息间隔时间 10秒
|
||||
const val LOOP_PERIOD_10S = 10 * 1000L
|
||||
const val LOOP_PERIOD_10S = 10 * 1000L
|
||||
|
||||
// 尝试下发给MEC轨迹最多10次
|
||||
const val LOOP_SEND_TRAJ_TIMES = 10
|
||||
|
||||
//起点UUID
|
||||
const val SWEEPER_START_MAP_MAKER = "sweeper_start_map_maker";
|
||||
|
||||
//终点UUID
|
||||
const val SWEEPER_END_MAP_MAKER = "sweeper_end_map_maker";
|
||||
|
||||
// 埋点key:接管后点击'自动驾驶'按钮启动
|
||||
const val EVENT_KEY_RESTART_AUTOPILOT = "event_key_och_sweeper_restart_autopilot"
|
||||
|
||||
// 埋点key:开始服务开启自动驾驶(成功/失败)
|
||||
const val EVENT_KEY_START_SERVICE = "event_key_och_sweeper_start_service"
|
||||
const val EVENT_PARAM_SN = "sn"
|
||||
@@ -49,9 +45,15 @@ 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类型
|
||||
*/
|
||||
@@ -61,5 +63,8 @@ class SweeperConst {
|
||||
|
||||
//围栏到站 暂定10米
|
||||
const val ARRIVE_AT_END_STATION_DISTANCE = 10
|
||||
|
||||
//非贴边
|
||||
const val NONWELT = -10000.0
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
package com.mogo.och.sweeper.constant
|
||||
|
||||
/**
|
||||
* 当前任务操作菜单
|
||||
*/
|
||||
enum class TaskStatusEnum(val code: Int) {
|
||||
JUMP_OVER_SUBTASK( 1),//跳过子任务
|
||||
END_TASK( 2),//结束主任务
|
||||
CANCEL_TASK( 3),//取消
|
||||
START_SUBTASK(4),//开始子任务
|
||||
END_SUBTASK(5),//结束子任务
|
||||
}
|
||||
@@ -0,0 +1,29 @@
|
||||
package com.mogo.och.sweeper.database;
|
||||
|
||||
import com.mogo.commons.AbsMogoApplication;
|
||||
import com.mogo.och.sweeper.database.bean.WeltDataBean;
|
||||
import com.mogo.och.sweeper.database.dao.WeltDataDao;
|
||||
|
||||
import androidx.room.Database;
|
||||
import androidx.room.Room;
|
||||
import androidx.room.RoomDatabase;
|
||||
|
||||
//注解Database告诉系统这是Room数据库对象
|
||||
//entities指定该数据库有哪些表,多张表就逗号分隔
|
||||
//version指定数据库版本号,升级时需要用到
|
||||
//数据库继承自RoomDatabase
|
||||
@Database(entities = {WeltDataBean.class}, version = 1)
|
||||
public abstract class MyDataBase extends RoomDatabase {
|
||||
private static final String DATABASE_NAME = "weltData_db";
|
||||
|
||||
//结合单例模式完成数据库实例创建
|
||||
public static MyDataBase getInstance() {
|
||||
return SingleTon.instance;
|
||||
}
|
||||
|
||||
private static class SingleTon {
|
||||
private static final MyDataBase instance =
|
||||
Room.databaseBuilder(AbsMogoApplication.getApp().getApplicationContext(), MyDataBase.class, DATABASE_NAME).build();
|
||||
}
|
||||
public abstract WeltDataDao getWeltDataDao();
|
||||
}
|
||||
@@ -0,0 +1,127 @@
|
||||
package com.mogo.och.sweeper.database.bean;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
import androidx.room.ColumnInfo;
|
||||
import androidx.room.Entity;
|
||||
import androidx.room.Index;
|
||||
import androidx.room.PrimaryKey;
|
||||
|
||||
@Entity(tableName = WeltDataBean.WeltDataTable, indices = {@Index(value = "id", unique = true)})
|
||||
public class WeltDataBean implements Serializable {
|
||||
|
||||
public static final String WeltDataTable = "welt_data_table";
|
||||
//ColumnInfo用于指定该字段存储在表中的名字,并指定类型
|
||||
|
||||
@PrimaryKey(autoGenerate = true)
|
||||
|
||||
@ColumnInfo(name = "id", typeAffinity = ColumnInfo.INTEGER)
|
||||
|
||||
private int id;
|
||||
|
||||
@ColumnInfo(name = "subTaskId", typeAffinity = ColumnInfo.INTEGER)//子任务id
|
||||
|
||||
private int subTaskId;
|
||||
|
||||
@ColumnInfo(name = "locLon", typeAffinity = ColumnInfo.REAL)
|
||||
|
||||
private double locLon;//自车RTK定位经度
|
||||
|
||||
@ColumnInfo(name = "locLat", typeAffinity = ColumnInfo.REAL)
|
||||
|
||||
private double locLat;//自车RTK定位纬度
|
||||
|
||||
@ColumnInfo(name = "weltDistance", typeAffinity = ColumnInfo.REAL)
|
||||
|
||||
private double weltDistance;//贴边距离
|
||||
|
||||
@ColumnInfo(name = "cleanMode", typeAffinity = ColumnInfo.INTEGER)
|
||||
|
||||
private int cleanMode;//清扫作业模式 1–纯扫 2--洗扫, 3--纯洗, 4--纯吸
|
||||
|
||||
@ColumnInfo(name = "cleanDirection", typeAffinity = ColumnInfo.INTEGER)
|
||||
|
||||
private int cleanDirection;//清扫方向 1--两侧, 2--左侧, 3--右侧
|
||||
|
||||
@ColumnInfo(name = "cleanIntensity", typeAffinity = ColumnInfo.INTEGER)
|
||||
|
||||
private int cleanIntensity;//清扫强度 1--两侧, 2--左侧, 3--右侧
|
||||
|
||||
public int getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public void setId(int id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
public int getSubTaskId() {
|
||||
return subTaskId;
|
||||
}
|
||||
|
||||
public void setSubTaskId(int subTaskId) {
|
||||
this.subTaskId = subTaskId;
|
||||
}
|
||||
|
||||
public double getLocLon() {
|
||||
return locLon;
|
||||
}
|
||||
|
||||
public void setLocLon(double locLon) {
|
||||
this.locLon = locLon;
|
||||
}
|
||||
|
||||
public double getLocLat() {
|
||||
return locLat;
|
||||
}
|
||||
|
||||
public void setLocLat(double locLat) {
|
||||
this.locLat = locLat;
|
||||
}
|
||||
|
||||
public double getWeltDistance() {
|
||||
return weltDistance;
|
||||
}
|
||||
|
||||
public void setWeltDistance(double weltDistance) {
|
||||
this.weltDistance = weltDistance;
|
||||
}
|
||||
|
||||
public int getCleanMode() {
|
||||
return cleanMode;
|
||||
}
|
||||
|
||||
public void setCleanMode(int cleanMode) {
|
||||
this.cleanMode = cleanMode;
|
||||
}
|
||||
|
||||
public int getCleanDirection() {
|
||||
return cleanDirection;
|
||||
}
|
||||
|
||||
public void setCleanDirection(int cleanDirection) {
|
||||
this.cleanDirection = cleanDirection;
|
||||
}
|
||||
|
||||
public int getCleanIntensity() {
|
||||
return cleanIntensity;
|
||||
}
|
||||
|
||||
public void setCleanIntensity(int cleanIntensity) {
|
||||
this.cleanIntensity = cleanIntensity;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "WeltDataBean{" +
|
||||
"id=" + id +
|
||||
", subTaskId='" + subTaskId + '\'' +
|
||||
", locLon=" + locLon +
|
||||
", locLat=" + locLat +
|
||||
", weltDistance=" + weltDistance +
|
||||
", cleanMode=" + cleanMode +
|
||||
", cleanDirection=" + cleanDirection +
|
||||
", cleanIntensity=" + cleanIntensity +
|
||||
'}';
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,28 @@
|
||||
package com.mogo.och.sweeper.database.dao;
|
||||
|
||||
import com.mogo.och.sweeper.database.bean.WeltDataBean;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import androidx.room.Dao;
|
||||
import androidx.room.Insert;
|
||||
import androidx.room.OnConflictStrategy;
|
||||
import androidx.room.Query;
|
||||
|
||||
import static com.mogo.och.sweeper.database.bean.WeltDataBean.WeltDataTable;
|
||||
|
||||
@Dao
|
||||
public interface WeltDataDao {
|
||||
//插入数据
|
||||
@Insert(onConflict = OnConflictStrategy.REPLACE)
|
||||
void insert(WeltDataBean fileInfo);
|
||||
|
||||
//删除所有数据
|
||||
@Query("DELETE FROM " + WeltDataTable)
|
||||
int deleteAllWeltData();
|
||||
|
||||
//查询所有数据
|
||||
@Query("SELECT * FROM " + WeltDataTable)
|
||||
List<WeltDataBean> loadAllWeltDataInfo();
|
||||
}
|
||||
@@ -0,0 +1,58 @@
|
||||
package com.mogo.och.sweeper.event;
|
||||
|
||||
import com.amap.api.maps.model.LatLng;
|
||||
import com.mogo.och.sweeper.database.bean.WeltDataBean;
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
||||
public class WeltDataEvent{
|
||||
private int type; //1.添加起点和终点 2.实时添加贴边数据 3.清除数据 4.任务进度 5:任务轨迹数据
|
||||
private ArrayList<WeltDataBean> weltDataBeanList;
|
||||
private ArrayList<LatLng> markers;
|
||||
private String distance;//贴边数据
|
||||
private String progress;//任务进度
|
||||
|
||||
public WeltDataEvent(int type) {
|
||||
this.type = type;
|
||||
}
|
||||
|
||||
public int getType() {
|
||||
return type;
|
||||
}
|
||||
|
||||
public void setType(int type) {
|
||||
this.type = type;
|
||||
}
|
||||
|
||||
public ArrayList<WeltDataBean> getWeltDataBeanList() {
|
||||
return weltDataBeanList;
|
||||
}
|
||||
|
||||
public void setWeltDataBeanList(ArrayList<WeltDataBean> weltDataBeanList) {
|
||||
this.weltDataBeanList = weltDataBeanList;
|
||||
}
|
||||
|
||||
public ArrayList<LatLng> getMarkers() {
|
||||
return markers;
|
||||
}
|
||||
|
||||
public void setMarkers(ArrayList<LatLng> markers) {
|
||||
this.markers = markers;
|
||||
}
|
||||
|
||||
public String getDistance() {
|
||||
return distance;
|
||||
}
|
||||
|
||||
public void setDistance(String distance) {
|
||||
this.distance = distance;
|
||||
}
|
||||
|
||||
public String getProgress() {
|
||||
return progress;
|
||||
}
|
||||
|
||||
public void setProgress(String progress) {
|
||||
this.progress = progress;
|
||||
}
|
||||
}
|
||||
@@ -1,58 +1,53 @@
|
||||
package com.mogo.och.sweeper.fragment;
|
||||
|
||||
import static com.mogo.eagle.core.utilcode.mogo.logger.scene.SceneConstant.M_BUS;
|
||||
import static com.mogo.och.sweeper.constant.SweeperConst.TIMER_START_AUTOPILOT_INTERVAL;
|
||||
|
||||
import android.animation.ObjectAnimator;
|
||||
import android.content.Intent;
|
||||
import android.os.Bundle;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.MotionEvent;
|
||||
import android.view.View;
|
||||
import android.view.animation.LinearInterpolator;
|
||||
import android.widget.FrameLayout;
|
||||
import android.widget.ImageView;
|
||||
import android.widget.LinearLayout;
|
||||
import android.widget.RelativeLayout;
|
||||
import android.widget.TextView;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
import androidx.constraintlayout.widget.Group;
|
||||
|
||||
import com.amap.api.maps.model.LatLng;
|
||||
import com.amap.api.navi.model.NaviLatLng;
|
||||
import com.mogo.commons.AbsMogoApplication;
|
||||
import com.mogo.commons.debug.DebugConfig;
|
||||
import com.mogo.commons.mvp.IView;
|
||||
import com.mogo.commons.mvp.MvpFragment;
|
||||
import com.mogo.commons.mvp.Presenter;
|
||||
import com.mogo.eagle.core.data.constants.DataTypes;
|
||||
import com.mogo.eagle.core.function.api.autopilot.IMoGoAutopilotRecordListener;
|
||||
import com.mogo.eagle.core.function.api.autopilot.IMoGoAutopilotStatusListener;
|
||||
import com.mogo.eagle.core.function.call.autopilot.CallerAutoPilotStatusListenerManager;
|
||||
import com.mogo.eagle.core.function.call.autopilot.CallerAutopilotRecordListenerManager;
|
||||
import com.mogo.eagle.core.function.call.devatools.CallerDevaToolsManager;
|
||||
import com.mogo.eagle.core.function.call.hmi.CallerHmiManager;
|
||||
import com.mogo.eagle.core.function.call.map.CallerMapUIServiceManager;
|
||||
import com.mogo.eagle.core.function.smp.view.SmallMapView;
|
||||
import com.mogo.eagle.core.function.hmi.ui.msgbox.DriverMsgBoxBubbleView;
|
||||
import com.mogo.eagle.core.function.hmi.ui.msgbox.DriverMsgBoxButtonView;
|
||||
import com.mogo.eagle.core.function.hmi.ui.msgbox.DriverMsgBoxListView;
|
||||
import com.mogo.eagle.core.function.view.MapBizView;
|
||||
import com.mogo.eagle.core.utilcode.mogo.logger.CallerLogger;
|
||||
import com.mogo.eagle.core.utilcode.mogo.view.OnPreventFastClickListener;
|
||||
import com.mogo.eagle.core.utilcode.util.ThreadUtils;
|
||||
import com.mogo.eagle.core.utilcode.util.UiThreadHandler;
|
||||
import com.mogo.map.listener.IMogoMapListener;
|
||||
import com.mogo.map.listener.MogoMapListenerHandler;
|
||||
import com.mogo.map.marker.IMogoMarkerManager;
|
||||
import com.mogo.map.uicontroller.IMogoMapUIController;
|
||||
import com.mogo.map.uicontroller.VisualAngleMode;
|
||||
import com.mogo.och.common.module.map.AmapNaviToDestinationModel;
|
||||
import com.mogo.och.sweeper.R;
|
||||
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.util.BDRouteDataTestUtils;
|
||||
import com.mogo.och.sweeper.view.SlidePanelView;
|
||||
import com.mogo.och.sweeper.bean.SweeperRoutePlanningUpdateReqBean;
|
||||
import com.mogo.och.sweeper.callback.ISweeperTaskDataToFragmentCallback;
|
||||
import com.mogo.och.sweeper.callback.IWeltMapSwitchToSmallCallback;
|
||||
import com.mogo.och.sweeper.database.bean.WeltDataBean;
|
||||
import com.mogo.och.sweeper.view.SweeperTrafficDataView;
|
||||
import com.mogo.och.sweeper.view.WeltSmallMapView;
|
||||
|
||||
import bag_manager.BagManagerOuterClass;
|
||||
import mogo.telematics.pad.MessagePad;
|
||||
import record_cache.RecordPanelOuterClass;
|
||||
import java.math.BigDecimal;
|
||||
import java.math.RoundingMode;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
import androidx.constraintlayout.widget.Group;
|
||||
import androidx.fragment.app.FragmentTransaction;
|
||||
|
||||
/**
|
||||
* 网约车基础Fragment,主要负责布局通用界面,处理站点面板和通话面板互斥情况
|
||||
@@ -61,47 +56,47 @@ import record_cache.RecordPanelOuterClass;
|
||||
*
|
||||
* @author tongchenfei
|
||||
*/
|
||||
public abstract class BaseSweeperTabFragment<V extends IView, P extends Presenter<V>> extends MvpFragment<V, P> implements IMogoMapListener, IMoGoAutopilotRecordListener {
|
||||
public abstract class BaseSweeperTabFragment<V extends IView, P extends Presenter<V>> extends MvpFragment<V, P> implements IMogoMapListener,
|
||||
View.OnClickListener, IWeltMapSwitchToSmallCallback, View.OnTouchListener {
|
||||
|
||||
private static final String TAG = "BaseSweeperTabFragment";
|
||||
|
||||
protected SlidePanelView slidePanelView;
|
||||
private RelativeLayout ctvAutopilotStatus;
|
||||
private ImageView ctvAutopilotStatusIv;
|
||||
private TextView ctvAutopilotStatusTv;
|
||||
protected TextView tvOperationStatus;
|
||||
protected RelativeLayout mSettingBtn;
|
||||
protected RelativeLayout mBadcaseBtn;
|
||||
protected RelativeLayout mAICollectBtn;
|
||||
public boolean isOperationStatus;//false-收车,true-出车
|
||||
private FrameLayout flStationPanelContainer;
|
||||
//地图放大缩小
|
||||
private ImageView mSwitchMapModeImage;
|
||||
//设置信息面板
|
||||
protected ImageView mSettingBtn;
|
||||
//安全员问题上报面板
|
||||
protected ImageView mCardBtn;
|
||||
//道路状况上报面板
|
||||
protected ImageView mAICollectBtn;
|
||||
//任务列表面板
|
||||
private FrameLayout flTaskListPanelContainer;
|
||||
private MapBizView mapBizView;
|
||||
private Group groupTestPanel;
|
||||
private FrameLayout flSpeed;
|
||||
// private BusArcView mouduleArc;
|
||||
//清扫车车辆基本信息 速度 档位 转向灯 红绿灯等
|
||||
private SweeperTrafficDataView mTrafficDataView;
|
||||
private ImageView mUpgradeTipIv;
|
||||
// private BusTrafficLightView mTrafficLightView;
|
||||
|
||||
//远景和中景的切换
|
||||
private ImageView mSwitchMapModeImage;
|
||||
private LinearLayout mSwitchMapModeLayout;
|
||||
|
||||
private SmallMapView smallMapView;
|
||||
|
||||
private ObjectAnimator autopilotLoadingAnimator;
|
||||
|
||||
public boolean isAnimateRunning = false;
|
||||
|
||||
/**
|
||||
* 滑动按钮触发的事件
|
||||
*/
|
||||
private final SlidePanelView.OnSlidePanelMoveToEndListener onSlideToEndListener = () -> {
|
||||
// 此处做一个代理,处理一下共有情况
|
||||
if (getSlidePanelOnEndListener() != null) {
|
||||
getSlidePanelOnEndListener().moveToEnd();
|
||||
}
|
||||
};
|
||||
//人工驾驶地图View组控制
|
||||
private Group mGroupNaviPanel;
|
||||
//人工驾驶地图Fragment
|
||||
private SweeperAmapNaviFragment mOchAmapNaviFragment;
|
||||
//关闭人工驾驶小地图
|
||||
private ImageView mCloseNavIcon;
|
||||
//刷新人工驾驶地图按钮
|
||||
private ImageView mRefreshNavi;
|
||||
//作业任务贴边数据展示图
|
||||
private WeltSmallMapView mMapWeltView;
|
||||
//任务作业全览图
|
||||
private WeltMapOverViewFragment mWeltMapOverViewFragment;
|
||||
private FrameLayout mFlWeltMapOverView;
|
||||
private DriverMsgBoxButtonView mViewDriverMsgBoxButton;
|
||||
private DriverMsgBoxListView mViewDriverMsgBoxList;
|
||||
private DriverMsgBoxBubbleView mViewDriverMsgBoxBubble;
|
||||
private ArrayList<WeltDataBean> mWeltDataBeanList;//存储贴边数据
|
||||
private ArrayList<LatLng> mSubTaskCoordinates;//存储当前大任务的所有子任务起点和终点
|
||||
// 当前子任务的终点坐标
|
||||
protected LatLng mCurrentTaskEndStation;
|
||||
private ArrayList<SweeperRoutePlanningUpdateReqBean.Result> mRouteList;//存储任务的坐标轨迹
|
||||
private String mProgress;
|
||||
private ISweeperTaskDataToFragmentCallback mTaskDataToFragmentCallback;
|
||||
|
||||
@Override
|
||||
protected int getLayoutId() {
|
||||
@@ -110,75 +105,32 @@ public abstract class BaseSweeperTabFragment<V extends IView, P extends Presente
|
||||
|
||||
private View panelView;
|
||||
|
||||
@Override
|
||||
public boolean onTouch(View v, MotionEvent event) {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void initViews() {
|
||||
mapBizView = findViewById(R.id.mapBizView);
|
||||
groupTestPanel = findViewById(R.id.groupTestPanel);
|
||||
slidePanelView = findViewById(R.id.module_mogo_och_slide_panel);
|
||||
ctvAutopilotStatus = findViewById(R.id.module_mogo_och_autopilot_status);
|
||||
ctvAutopilotStatusIv = findViewById(R.id.sweeper_autopilot_btn_iv);
|
||||
ctvAutopilotStatusTv = findViewById(R.id.sweeper_autopolot_btn_tv);
|
||||
flStationPanelContainer = findViewById(R.id.module_mogo_och_station_panel_container);
|
||||
|
||||
// mTrafficLightView = findViewById(R.id.bus_traffic_light_view);
|
||||
// CallerHmiManager.INSTANCE.setProxyTrafficLightView(mTrafficLightView);
|
||||
|
||||
tvOperationStatus = findViewById(R.id.module_mogo_och_operation_status);
|
||||
|
||||
flSpeed = (FrameLayout) findViewById(R.id.fl_speed);
|
||||
mGroupNaviPanel = findViewById(R.id.group_navi_panel);
|
||||
flTaskListPanelContainer = findViewById(R.id.module_mogo_och_task_list_container);
|
||||
mTrafficDataView = findViewById(R.id.sweeper_arc);
|
||||
|
||||
panelView = LayoutInflater.from(getContext()).inflate(getStationPanelViewId(), flStationPanelContainer);
|
||||
slidePanelView.setOnSlidePanelMoveToEndListener(onSlideToEndListener);
|
||||
|
||||
mSwitchMapModeLayout = findViewById(R.id.sweeper_switch_model_layout);
|
||||
panelView = LayoutInflater.from(getContext()).inflate(getTaskListPanelViewId(), flTaskListPanelContainer);
|
||||
mSwitchMapModeImage = findViewById(R.id.sweeper_switch_model_icon);
|
||||
updateSwitchMapIcon();
|
||||
|
||||
mSwitchMapModeLayout.setOnClickListener(new OnPreventFastClickListener() {
|
||||
|
||||
@Override
|
||||
public void onClickImpl(View v) {
|
||||
IMogoMapUIController controller = CallerMapUIServiceManager.INSTANCE.getMapUIController();
|
||||
IMogoMarkerManager markerManager = CallerMapUIServiceManager.INSTANCE.getMarkerManager(AbsMogoApplication.getApp());
|
||||
if (controller != null && markerManager != null) {
|
||||
//切换地图的远近视图
|
||||
if (controller.getCurrentMapVisualAngle().isLongSight()) {
|
||||
markerManager.visibleAllMarkers();
|
||||
controller.changeMapVisualAngle(VisualAngleMode.MODE_MEDIUM_SIGHT, null);
|
||||
mSwitchMapModeImage.setImageResource(R.drawable.sweeper_switch_map_medium);
|
||||
} else if (controller.getCurrentMapVisualAngle().isMediumSight()) {
|
||||
markerManager.inVisibleWithoutMarkers(DataTypes.TYPE_MARKER_ADAS, SweeperConst.TYPE_MARKER_SWEEPER_ORDER);
|
||||
controller.changeMapVisualAngle(VisualAngleMode.MODE_LONG_SIGHT, null);
|
||||
mSwitchMapModeImage.setImageResource(R.drawable.sweeper_switch_map_long);
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
if (DebugConfig.isDebug()) {
|
||||
mTrafficDataView.setLongClickable(true);
|
||||
mTrafficDataView.setOnLongClickListener(v -> {
|
||||
CallerLogger.INSTANCE.d(M_BUS + TAG, "长按显示状态工具栏");
|
||||
Intent intent = new Intent();
|
||||
intent.putExtra("oper", 52);
|
||||
return true;
|
||||
});
|
||||
}
|
||||
mSettingBtn = findViewById(R.id.sweeper_setting_model_icon);
|
||||
mCardBtn = findViewById(R.id.sweeper_card_model_icon);
|
||||
mAICollectBtn = findViewById(R.id.sweeper_collect_model_icon);
|
||||
mCloseNavIcon = findViewById(R.id.sweeper_close_navi_icon);
|
||||
mRefreshNavi = findViewById(R.id.sweeper_refresh_navi);
|
||||
mMapWeltView = findViewById(R.id.sweeper_task_welt_small_map);
|
||||
mFlWeltMapOverView = findViewById(R.id.sweeper_welt_map_overview);
|
||||
initListener();
|
||||
ctvAutopilotStatus.setOnClickListener(new OnPreventFastClickListener() {
|
||||
|
||||
@Override
|
||||
public void onClickImpl(View v) {
|
||||
// if (CallerAutoPilotStatusListenerManager.INSTANCE.getAutoPilotStatusInfo().getState() != IMoGoAutopilotStatusListener.STATUS_AUTOPILOT_DISABLE){
|
||||
restartAutopilot();
|
||||
// }else {
|
||||
// ToastUtils.showShort(getResources().getString(R.string.sweeper_auto_disable_tip));
|
||||
// }
|
||||
}
|
||||
});
|
||||
|
||||
setAutopilotBtnStatus(CallerAutoPilotStatusListenerManager.INSTANCE.getAutoPilotStatusInfo().getState());
|
||||
//设置消息盒子
|
||||
setMessageBox();
|
||||
//设置左下角四个按钮监听事件
|
||||
setBottomBtnListener();
|
||||
// 模拟 不可自动驾驶,目前场景是刚开机,adas还未和工控机连接
|
||||
findViewById(R.id.btnAutopilotDisable).setOnClickListener(view ->
|
||||
debugAutoPilotStatus(IMoGoAutopilotStatusListener.STATUS_AUTOPILOT_DISABLE)
|
||||
@@ -193,76 +145,87 @@ public abstract class BaseSweeperTabFragment<V extends IView, P extends Presente
|
||||
findViewById(R.id.btnAutopilotRunning).setOnClickListener(view ->
|
||||
debugAutoPilotStatus(IMoGoAutopilotStatusListener.STATUS_AUTOPILOT_RUNNING)
|
||||
);
|
||||
|
||||
// 模拟 自动驾驶网约车回调数据
|
||||
findViewById(R.id.btnAutopilotArrive).setOnClickListener(view ->
|
||||
debugArrivedStation()
|
||||
// 模拟 结束子任务
|
||||
findViewById(R.id.btnEndTask).setOnClickListener(view ->
|
||||
debugEndSubTask()
|
||||
);
|
||||
|
||||
findViewById(R.id.btnAutopilotRoute).setOnClickListener(view -> debugArrivedRoute());
|
||||
|
||||
tvOperationStatus.setOnClickListener(view -> {
|
||||
onChangeOperationStatus();
|
||||
mTrafficDataView.setOnLongClickListener(new View.OnLongClickListener() {
|
||||
@Override
|
||||
public boolean onLongClick(View v) {
|
||||
debugTestBar();
|
||||
return false;
|
||||
}
|
||||
});
|
||||
|
||||
mSettingBtn = findViewById(R.id.module_mogo_och_setting_layout);
|
||||
mSettingBtn.setOnClickListener(v -> {
|
||||
// TODO: 2021/12/9
|
||||
CallerHmiManager.INSTANCE.showToolsView();
|
||||
});
|
||||
|
||||
// mBadcaseBtn的visible显示逻辑在showBadcaseEntrance内处理
|
||||
mBadcaseBtn = findViewById(R.id.module_mogo_och_badcase_rl);
|
||||
// CallerHmiManager.INSTANCE.registerBadCaseCallback(
|
||||
// () -> { // onShow()
|
||||
// return mBadcaseBtn; },
|
||||
// () -> { // onHide()
|
||||
// return null; });
|
||||
|
||||
if (mBadcaseBtn != null) {
|
||||
CallerDevaToolsManager.INSTANCE.initBadCase(mBadcaseBtn);
|
||||
CallerAutopilotRecordListenerManager.INSTANCE.addListener(TAG, this);
|
||||
}
|
||||
|
||||
mAICollectBtn = findViewById(R.id.module_mogo_och_ai_collet_rl);
|
||||
if (mAICollectBtn != null) {
|
||||
CallerDevaToolsManager.INSTANCE.initAiCollect(mAICollectBtn);
|
||||
}
|
||||
|
||||
smallMapView = findViewById(R.id.smallMapView);
|
||||
}
|
||||
|
||||
private void updateSwitchMapIcon() {
|
||||
IMogoMapUIController controller = CallerMapUIServiceManager.INSTANCE.getMapUIController();
|
||||
if (controller != null) {
|
||||
if (controller.getCurrentMapVisualAngle().isLongSight()) {
|
||||
mSwitchMapModeImage.setImageResource(R.drawable.sweeper_switch_map_long);
|
||||
mSwitchMapModeImage.setImageResource(R.drawable.sweeper_switch_map_big_selector);
|
||||
} else if (controller.getCurrentMapVisualAngle().isMediumSight()) {
|
||||
mSwitchMapModeImage.setImageResource(R.drawable.sweeper_switch_map_medium);
|
||||
mSwitchMapModeImage.setImageResource(R.drawable.sweeper_switch_map_small_selector);
|
||||
} else {
|
||||
mSwitchMapModeImage.setImageResource(R.drawable.sweeper_switch_map_medium);
|
||||
mSwitchMapModeImage.setImageResource(R.drawable.sweeper_switch_map_small_selector);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置任务进度
|
||||
*
|
||||
* @param progress
|
||||
*/
|
||||
protected void setTaskProgress(String progress) {
|
||||
ThreadUtils.runOnUiThread(() -> {
|
||||
mMapWeltView.setTaskProgress(progress);
|
||||
mProgress = progress;
|
||||
if (mTaskDataToFragmentCallback != null) {
|
||||
mTaskDataToFragmentCallback.setProgress(progress);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void initViews(Bundle savedInstanceState) {
|
||||
super.initViews(savedInstanceState);
|
||||
mapBizView.onCreate(savedInstanceState);
|
||||
smallMapView.onCreateView(savedInstanceState);
|
||||
mMapWeltView.onCreateView(savedInstanceState);
|
||||
}
|
||||
|
||||
/**
|
||||
* 消息盒子
|
||||
*/
|
||||
private void setMessageBox() {
|
||||
mViewDriverMsgBoxButton = findViewById(R.id.viewDriverMsgBoxButton);
|
||||
mViewDriverMsgBoxList = findViewById(R.id.viewDriverMsgBoxList);
|
||||
mViewDriverMsgBoxBubble = findViewById(R.id.viewDriverMsgBoxBubble);
|
||||
//消息盒子
|
||||
mViewDriverMsgBoxButton.setClickListener(show -> {
|
||||
if (show) {
|
||||
mViewDriverMsgBoxList.setVisibility(View.VISIBLE);
|
||||
mViewDriverMsgBoxList.notifyData();
|
||||
mViewDriverMsgBoxBubble.setVisibility(View.GONE);
|
||||
mViewDriverMsgBoxBubble.isShowData(false);
|
||||
} else {
|
||||
mViewDriverMsgBoxList.setVisibility(View.GONE);
|
||||
mViewDriverMsgBoxBubble.setVisibility(View.VISIBLE);
|
||||
mViewDriverMsgBoxBubble.isShowData(true);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onPause() {
|
||||
super.onPause();
|
||||
smallMapView.onPause();
|
||||
mMapWeltView.onPause();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onResume() {
|
||||
super.onResume();
|
||||
mapBizView.onResume();
|
||||
smallMapView.onResume();
|
||||
mMapWeltView.onResume();
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -277,10 +240,6 @@ public abstract class BaseSweeperTabFragment<V extends IView, P extends Presente
|
||||
mapBizView.onLowMemory();
|
||||
}
|
||||
|
||||
private void debugArrivedRoute() {
|
||||
BDRouteDataTestUtils.converToRouteData();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDestroyView() {
|
||||
mapBizView.onDestroy();
|
||||
@@ -289,186 +248,27 @@ public abstract class BaseSweeperTabFragment<V extends IView, P extends Presente
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onAutopilotRecordResult(@Nullable RecordPanelOuterClass.RecordPanel recordPanel) {
|
||||
// if (!HmiBuildConfig.isShowBadCaseView && recordPanel != null && recordPanel.getType() == 1 && recordPanel.getStat() == 100) {
|
||||
// CallerDevaToolsManager.INSTANCE.onReceiveBadCaseRecord(recordPanel);
|
||||
// }
|
||||
}
|
||||
public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
|
||||
super.onViewCreated(view, savedInstanceState);
|
||||
view.setOnTouchListener(this);
|
||||
|
||||
@Override
|
||||
public void onAutopilotRecordConfig(@NonNull MessagePad.RecordDataConfig config) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onBagManagerResult(@NonNull BagManagerOuterClass.BagManager bagManager) {
|
||||
}
|
||||
|
||||
/**
|
||||
* 测试到站
|
||||
*/
|
||||
protected abstract void debugArrivedStation();
|
||||
|
||||
private void initListener() {
|
||||
MogoMapListenerHandler.Companion.getMogoMapListenerHandler().registerHostMapListener(TAG, this);
|
||||
}
|
||||
|
||||
protected void onChangeOperationStatus() {
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* 展示滑动按钮
|
||||
*
|
||||
* @param text 指定的文字
|
||||
*/
|
||||
public void showSlidePanle(String text) {
|
||||
if (isOperationStatus) {
|
||||
getActivity().runOnUiThread(() -> {
|
||||
slidePanelView.setText(text);
|
||||
slidePanelView.setVisibility(View.VISIBLE);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 隐藏滑动按钮
|
||||
*/
|
||||
public void hideSlidePanel() {
|
||||
getActivity().runOnUiThread(() -> {
|
||||
slidePanelView.setVisibility(View.GONE);
|
||||
mCloseNavIcon.setOnClickListener(this);
|
||||
mRefreshNavi.setOnClickListener(this);
|
||||
mMapWeltView.getSwitchToBig().setOnClickListener((v) -> {
|
||||
showOrHideOverMapViewFragment(true);
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* 改变自动驾驶状态
|
||||
*
|
||||
* @param autopilotStatus 0:不可用 1:可用状态 2:自动驾驶中
|
||||
*/
|
||||
public void onAutopilotStatusChanged(int autopilotStatus) {
|
||||
getActivity().runOnUiThread(() -> {
|
||||
changeAutopilotBtnView(autopilotStatus, isAnimateRunning);
|
||||
});
|
||||
}
|
||||
|
||||
public void setAutopilotBtnStatus(int autopilotStatus) {
|
||||
if (IMoGoAutopilotStatusListener.STATUS_AUTOPILOT_DISABLE
|
||||
== autopilotStatus) {//0不可用
|
||||
ctvAutopilotStatusTv.setTextColor(getResources().getColor(R.color.sweeper_autopilot_text_color_disable));
|
||||
ctvAutopilotStatusTv.setText(getResources().getString(R.string.sweeper_loading_autopilot_runnig_tv));
|
||||
ctvAutopilotStatusIv.setImageResource(R.drawable.sweeper_disable_autopilot_icon);
|
||||
ctvAutopilotStatus.setSelected(false);
|
||||
ctvAutopilotStatus.setFocusableInTouchMode(true);
|
||||
|
||||
} else {
|
||||
ctvAutopilotStatusTv.setTextColor(getResources().getColor(R.color.sweeper_autopilot_text_color_normal));
|
||||
ctvAutopilotStatusTv.setText(getResources().getString(R.string.sweeper_loading_autopilot_runnig_tv));
|
||||
ctvAutopilotStatusIv.setImageResource(R.drawable.sweeper_ic_autopilot);
|
||||
ctvAutopilotStatus.setFocusableInTouchMode(true);
|
||||
if (IMoGoAutopilotStatusListener.STATUS_AUTOPILOT_ENABLE == autopilotStatus) {//1可用
|
||||
ctvAutopilotStatus.setSelected(false);
|
||||
} else if (IMoGoAutopilotStatusListener.STATUS_AUTOPILOT_RUNNING == autopilotStatus) {
|
||||
ctvAutopilotStatus.setSelected(true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void updateAutopilotStatus(int autopilotStatus) {
|
||||
if (IMoGoAutopilotStatusListener.STATUS_AUTOPILOT_RUNNING
|
||||
== autopilotStatus) {//2 running
|
||||
ctvAutopilotStatusIv.setImageResource(R.drawable.sweeper_right_autopilot_icon);
|
||||
ctvAutopilotStatusTv.setTextColor(getResources().getColor(R.color.sweeper_autopilot_text_color_normal));
|
||||
ctvAutopilotStatusTv.setText(getResources().getString(R.string.sweeper_loading_autopilot_success_tv));
|
||||
ctvAutopilotStatus.setSelected(false);
|
||||
ctvAutopilotStatus.setFocusableInTouchMode(false);
|
||||
} else {
|
||||
ctvAutopilotStatusIv.setImageResource(R.drawable.sweeper_wrong_autopilot_icon);
|
||||
ctvAutopilotStatusTv.setTextColor(getResources().getColor(R.color.sweeper_autopilot_text_color_normal));
|
||||
ctvAutopilotStatusTv.setText(getResources().getString(R.string.sweeper_loading_autopilot_failure_tv));
|
||||
ctvAutopilotStatus.setFocusableInTouchMode(false);
|
||||
ctvAutopilotStatus.setSelected(false);
|
||||
}
|
||||
UiThreadHandler.postDelayed(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
setAutopilotBtnStatus(autopilotStatus);
|
||||
}
|
||||
}, 1000);
|
||||
}
|
||||
|
||||
private void changeAutopilotBtnView(int autopilotStatus, boolean isAnimateRunning) {
|
||||
CallerLogger.INSTANCE.d(M_BUS + TAG, "onStateChangeChangeAutopilotBtnView: "
|
||||
+ autopilotStatus + "isAnimateRunning = " + isAnimateRunning);
|
||||
if (isAnimateRunning && IMoGoAutopilotStatusListener.STATUS_AUTOPILOT_RUNNING
|
||||
!= autopilotStatus) {
|
||||
// 主动开启自动驾驶中,不为2(为0、1)则继续loading
|
||||
return;
|
||||
}
|
||||
if (isAnimateRunning) {
|
||||
stopAutopilotAnimation();
|
||||
updateAutopilotStatus(autopilotStatus);
|
||||
} else {
|
||||
setAutopilotBtnStatus(autopilotStatus);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* 隐藏【自动驾驶】按钮
|
||||
*/
|
||||
public void hideAutopilotBiz() {
|
||||
getActivity().runOnUiThread(() -> {
|
||||
// ctvAutopilotStatus.setVisibility(View.GONE);
|
||||
// slidePanelView.setVisibility(View.GONE);
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* 展示【自动驾驶】按钮
|
||||
*/
|
||||
public void showAutopilotBiz() {
|
||||
getActivity().runOnUiThread(() -> {
|
||||
ctvAutopilotStatus.setVisibility(View.VISIBLE);
|
||||
});
|
||||
}
|
||||
|
||||
public void hidPanel() {
|
||||
getActivity().runOnUiThread(() -> {
|
||||
flStationPanelContainer.setVisibility(View.GONE);
|
||||
});
|
||||
}
|
||||
|
||||
public void showPanel() {
|
||||
getActivity().runOnUiThread(() -> {
|
||||
flStationPanelContainer.setVisibility(View.VISIBLE);
|
||||
});
|
||||
}
|
||||
|
||||
public View getPanelView() {
|
||||
return panelView;
|
||||
}
|
||||
|
||||
public SlidePanelView.OnSlidePanelMoveToEndListener getSlidePanelOnEndListener() {
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取站点面板view,在{@link #initViews()}时候添加到container中
|
||||
* 清扫车任务列表面板view,在{@link #initViews()}时候添加到container中
|
||||
*
|
||||
* @return 站点面板view
|
||||
*/
|
||||
public abstract int getStationPanelViewId();
|
||||
|
||||
/**
|
||||
* 获取清扫车操作面板layout id
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public abstract int getSweepOperatePanelViewId();
|
||||
|
||||
/**
|
||||
* 重新开启自动驾驶
|
||||
*/
|
||||
public abstract void restartAutopilot();
|
||||
public abstract int getTaskListPanelViewId();
|
||||
|
||||
/**
|
||||
* 模拟自动驾驶返回状态
|
||||
@@ -477,54 +277,6 @@ public abstract class BaseSweeperTabFragment<V extends IView, P extends Presente
|
||||
*/
|
||||
public abstract void debugAutoPilotStatus(int status);
|
||||
|
||||
/**
|
||||
* 开启自动驾驶中间动画
|
||||
*/
|
||||
public void startAutopilotAnimation() {
|
||||
isAnimateRunning = true;
|
||||
ctvAutopilotStatusTv.setText(getResources().getString(R.string.sweeper_loading_autopilot_tv));
|
||||
ctvAutopilotStatusTv.setTextColor(getResources().getColor(R.color.sweeper_autopilot_text_color_normal));
|
||||
ctvAutopilotStatus.setSelected(false);
|
||||
ctvAutopilotStatus.setFocusableInTouchMode(true);
|
||||
ctvAutopilotStatusIv.setImageResource(R.drawable.sweeper_loading_autopilot_icon);
|
||||
if (autopilotLoadingAnimator == null) {
|
||||
autopilotLoadingAnimator = ObjectAnimator.ofFloat(ctvAutopilotStatusIv, "rotation", 0f, 360f);
|
||||
autopilotLoadingAnimator.setInterpolator(new LinearInterpolator());
|
||||
autopilotLoadingAnimator.setRepeatCount(-1);//无限循环
|
||||
autopilotLoadingAnimator.setDuration(1000);//设置持续时间
|
||||
}
|
||||
autopilotLoadingAnimator.start();//动画开始
|
||||
|
||||
startingAutoApilotCountDown();
|
||||
|
||||
}
|
||||
|
||||
private void startingAutoApilotCountDown() {
|
||||
//10s 若自动驾驶没有开启,则结束动画
|
||||
UiThreadHandler.postDelayed(new Runnable() {
|
||||
@Override
|
||||
public void run() { //未启动成功做处理
|
||||
if (isAnimateRunning) {// 只判断动画是否在进行,根据自动驾驶当前状态去设置自动驾驶状态
|
||||
stopAutopilotAnimation();
|
||||
updateAutopilotStatus(CallerAutoPilotStatusListenerManager.INSTANCE.getAutoPilotStatusInfo().getState());
|
||||
}
|
||||
}
|
||||
}, TIMER_START_AUTOPILOT_INTERVAL);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* 停止自动驾驶中间动画
|
||||
*/
|
||||
protected void stopAutopilotAnimation() {
|
||||
if (autopilotLoadingAnimator != null) {
|
||||
autopilotLoadingAnimator.end();
|
||||
ctvAutopilotStatusIv.clearAnimation();
|
||||
autopilotLoadingAnimator = null;
|
||||
isAnimateRunning = false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 迈速表实时更新
|
||||
*
|
||||
@@ -537,26 +289,35 @@ public abstract class BaseSweeperTabFragment<V extends IView, P extends Presente
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 车辆基本信息View
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public SweeperTrafficDataView getTrafficDataView() {
|
||||
return mTrafficDataView;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDestroy() {
|
||||
super.onDestroy();
|
||||
smallMapView.onDestroy();
|
||||
mMapWeltView.onDestroy();
|
||||
MogoMapListenerHandler.Companion.getMogoMapListenerHandler().unregisterHostMapListener(TAG);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onMapVisualAngleChanged(VisualAngleMode visualAngleMode) {
|
||||
if (visualAngleMode.isMediumSight()) {
|
||||
mSwitchMapModeLayout.setVisibility(View.VISIBLE);
|
||||
mSwitchMapModeImage.setVisibility(View.VISIBLE);
|
||||
} else if (visualAngleMode.isLongSight()) {
|
||||
mSwitchMapModeLayout.setVisibility(View.VISIBLE);
|
||||
mSwitchMapModeImage.setVisibility(View.VISIBLE);
|
||||
} else if (visualAngleMode.isCloseSight()) {
|
||||
mSwitchMapModeLayout.setVisibility(View.GONE);
|
||||
mSwitchMapModeImage.setVisibility(View.GONE);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* bus调试面板打开关闭
|
||||
* sweeper调试面板打开关闭
|
||||
*/
|
||||
public void debugTestBar() {
|
||||
if (groupTestPanel.getVisibility() == View.VISIBLE) {
|
||||
@@ -567,49 +328,278 @@ public abstract class BaseSweeperTabFragment<V extends IView, P extends Presente
|
||||
}
|
||||
|
||||
/**
|
||||
* Bus调试信息:线路、轨迹等信息
|
||||
* <p>
|
||||
* START
|
||||
* 底部四个按钮监听
|
||||
* 1.地图放大缩小
|
||||
* 2.设置面板
|
||||
* 3.安全员问题上报面板
|
||||
* 4.道路状况上报面板
|
||||
*/
|
||||
private View busTestBar;
|
||||
private TextView lineIdTV;
|
||||
private TextView trajMd5TV;
|
||||
private TextView stopMd5TV;
|
||||
private TextView trajMd5DPQPTV;
|
||||
private TextView stopMd5DPQPTV;
|
||||
|
||||
public void showHideTestBar() {
|
||||
if (busTestBar == null) {
|
||||
busTestBar = findViewById(R.id.module_mogo_och_sweeper_test_bar);
|
||||
lineIdTV = findViewById(R.id.sweeper_test_bar_current_line_id);
|
||||
trajMd5TV = findViewById(R.id.sweeper_test_bar_current_traj_md5);
|
||||
stopMd5TV = findViewById(R.id.sweeper_test_bar_current_stop_md5);
|
||||
trajMd5DPQPTV = findViewById(R.id.sweeper_test_bar_current_traj_md5_dpqp);
|
||||
stopMd5DPQPTV = findViewById(R.id.sweeper_test_bar_current_stop_md5_dpqp);
|
||||
private void setBottomBtnListener() {
|
||||
updateSwitchMapIcon();
|
||||
mSwitchMapModeImage.setOnClickListener(new OnPreventFastClickListener() {
|
||||
@Override
|
||||
public void onClickImpl(View v) {
|
||||
IMogoMapUIController controller = CallerMapUIServiceManager.INSTANCE.getMapUIController();
|
||||
IMogoMarkerManager markerManager = CallerMapUIServiceManager.INSTANCE.getMarkerManager(AbsMogoApplication.getApp());
|
||||
if (controller != null && markerManager != null) {
|
||||
//切换地图的远近视图
|
||||
if (controller.getCurrentMapVisualAngle().isLongSight()) {
|
||||
// 2.11.0去掉
|
||||
// MogoMarkerManager.getInstance(AbsMogoApplication.getApp()).visibleAllMarkers();
|
||||
controller.changeMapVisualAngle(VisualAngleMode.MODE_MEDIUM_SIGHT, null);
|
||||
mSwitchMapModeImage.setImageResource(R.drawable.sweeper_switch_map_small_selector);
|
||||
} else if (controller.getCurrentMapVisualAngle().isMediumSight()) {
|
||||
// 2.11.0去掉
|
||||
// MogoMarkerManager.getInstance(AbsMogoApplication.getApp())
|
||||
// .inVisibleWithoutMarkers(DataTypes.TYPE_MARKER_ADAS, BusConst.TYPE_MARKER_BUS_ORDER);
|
||||
controller.changeMapVisualAngle(VisualAngleMode.MODE_LONG_SIGHT, null);
|
||||
mSwitchMapModeImage.setImageResource(R.drawable.sweeper_switch_map_big_selector);
|
||||
} else {
|
||||
// 2.11.0去掉
|
||||
// MogoMarkerManager.getInstance(AbsMogoApplication.getApp()).visibleAllMarkers();
|
||||
controller.changeMapVisualAngle(VisualAngleMode.MODE_MEDIUM_SIGHT, null);
|
||||
mSwitchMapModeImage.setImageResource(R.drawable.sweeper_switch_map_big_selector);
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
mSettingBtn.setOnClickListener(v -> {
|
||||
// TODO: 2021/12/9
|
||||
CallerHmiManager.INSTANCE.showToolsView();
|
||||
});
|
||||
if (mCardBtn != null) {
|
||||
CallerDevaToolsManager.INSTANCE.initBadCase(mCardBtn);
|
||||
}
|
||||
if (mAICollectBtn != null) {
|
||||
CallerDevaToolsManager.INSTANCE.initAiCollect(mAICollectBtn);
|
||||
}
|
||||
}
|
||||
|
||||
if (busTestBar.getVisibility() == View.VISIBLE) {
|
||||
busTestBar.setVisibility(View.GONE);
|
||||
|
||||
/**
|
||||
* 展示人工驾驶地图导航
|
||||
*/
|
||||
protected void showAmapNaviToStationFragment(boolean isShow) {
|
||||
FragmentTransaction transaction = getChildFragmentManager().beginTransaction();
|
||||
if (isShow) {
|
||||
mGroupNaviPanel.setVisibility(View.VISIBLE);
|
||||
if (mOchAmapNaviFragment == null) {
|
||||
mOchAmapNaviFragment=SweeperAmapNaviFragment.newInstance();
|
||||
}
|
||||
if (mOchAmapNaviFragment.isHidden()) {
|
||||
transaction.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_OPEN)
|
||||
.show(mOchAmapNaviFragment).commitAllowingStateLoss();
|
||||
return;
|
||||
}
|
||||
if (mOchAmapNaviFragment.isAdded()) {
|
||||
transaction.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_OPEN)
|
||||
.show(mOchAmapNaviFragment).commitAllowingStateLoss();
|
||||
return;
|
||||
}
|
||||
transaction
|
||||
.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_OPEN)
|
||||
.add(R.id.module_mogo_och_navi_panel_container, mOchAmapNaviFragment)
|
||||
.show(mOchAmapNaviFragment).commitAllowingStateLoss();
|
||||
} else {
|
||||
SweeperRoutesResult routesResult = SweeperOrderModel.getInstance().getBusRoutesResult();
|
||||
lineIdTV.setText("lineId:" + (routesResult == null ? "" : String.valueOf(routesResult.getLineId())));
|
||||
trajMd5TV.setText("TMd5:" + (routesResult == null ? "" : routesResult.csvFileMd5));
|
||||
stopMd5TV.setText("SMd5:" + (routesResult == null ? "" : routesResult.txtFileMd5));
|
||||
trajMd5DPQPTV.setText("TMd5DPQP:" + (routesResult == null ? "" : routesResult.csvFileMd5DPQP));
|
||||
stopMd5DPQPTV.setText("SMd5DPQP:" + (routesResult == null ? "" : routesResult.txtFileMd5DPQP));
|
||||
busTestBar.setVisibility(View.VISIBLE);
|
||||
AmapNaviToDestinationModel.getInstance(getContext()).destroyAmaNavi();
|
||||
if (mOchAmapNaviFragment != null) {
|
||||
transaction.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_CLOSE)
|
||||
.hide(mOchAmapNaviFragment).commitAllowingStateLoss();
|
||||
}
|
||||
mGroupNaviPanel.setVisibility(View.GONE);
|
||||
}
|
||||
}
|
||||
|
||||
public void updateSweeperTestBarInfo() {
|
||||
if (busTestBar != null && busTestBar.getVisibility() == View.VISIBLE) {
|
||||
SweeperRoutesResult routesResult = SweeperOrderModel.getInstance().getBusRoutesResult();
|
||||
lineIdTV.setText("lineId:" + (routesResult == null ? "" : String.valueOf(routesResult.getLineId())));
|
||||
trajMd5TV.setText("TMd5:" + (routesResult == null ? "" : routesResult.csvFileMd5));
|
||||
stopMd5TV.setText("SMd5:" + (routesResult == null ? "" : routesResult.txtFileMd5));
|
||||
trajMd5DPQPTV.setText("TMd5DPQP:" + (routesResult == null ? "" : routesResult.csvFileMd5DPQP));
|
||||
stopMd5DPQPTV.setText("SMd5DPQP:" + (routesResult == null ? "" : routesResult.txtFileMd5DPQP));
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
int id = v.getId();
|
||||
if (id == R.id.sweeper_close_navi_icon) {
|
||||
showAmapNaviToStationFragment(false);
|
||||
} else if (id == R.id.sweeper_refresh_navi) {
|
||||
refreshNavi();
|
||||
}
|
||||
}
|
||||
|
||||
public abstract void refreshNavi();
|
||||
|
||||
/**
|
||||
* 设置作业任务全览图隐藏或者显示
|
||||
*
|
||||
* @param isShow
|
||||
*/
|
||||
public void showOrHideOverMapViewFragment(boolean isShow) {
|
||||
FragmentTransaction transaction = getChildFragmentManager().beginTransaction();
|
||||
if (isShow) {
|
||||
mFlWeltMapOverView.setVisibility(View.VISIBLE);
|
||||
if (mWeltMapOverViewFragment == null) {
|
||||
mWeltMapOverViewFragment = mWeltMapOverViewFragment.newInstance(
|
||||
(IWeltMapSwitchToSmallCallback) this,
|
||||
mCurrentTaskEndStation,
|
||||
mWeltDataBeanList,
|
||||
mSubTaskCoordinates,
|
||||
mRouteList,
|
||||
mProgress,
|
||||
(SweeperFragment) this);
|
||||
}
|
||||
if (mWeltMapOverViewFragment.isHidden()) {
|
||||
transaction.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_OPEN)
|
||||
.show(mWeltMapOverViewFragment).commitAllowingStateLoss();
|
||||
return;
|
||||
}
|
||||
if (mWeltMapOverViewFragment.isAdded()) {
|
||||
transaction.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_OPEN)
|
||||
.show(mWeltMapOverViewFragment).commitAllowingStateLoss();
|
||||
return;
|
||||
}
|
||||
transaction
|
||||
.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_OPEN)
|
||||
.add(R.id.sweeper_welt_map_overview, mWeltMapOverViewFragment)
|
||||
.show(mWeltMapOverViewFragment).commitAllowingStateLoss();
|
||||
} else {
|
||||
mFlWeltMapOverView.setVisibility(View.GONE);
|
||||
if (mWeltMapOverViewFragment != null) {
|
||||
transaction.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_CLOSE)
|
||||
.hide(mWeltMapOverViewFragment).commitAllowingStateLoss();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onWeltMapSwitchToSmall() {
|
||||
showOrHideOverMapViewFragment(false);
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置贴边数据到地图
|
||||
*
|
||||
* @param weltDataBeans
|
||||
*/
|
||||
public void setWeltDataToMap(ArrayList<WeltDataBean> weltDataBeans, Boolean isWeltData, String distance) {
|
||||
mWeltDataBeanList = weltDataBeans;
|
||||
ThreadUtils.getSinglePool().execute(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
if (mMapWeltView != null) {
|
||||
mMapWeltView.setWeltData(weltDataBeans, isWeltData, distance);
|
||||
}
|
||||
if (mTaskDataToFragmentCallback != null) {
|
||||
mTaskDataToFragmentCallback.setWeltData(weltDataBeans, distance);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public void setTaskListCoordinatesLatLng(ArrayList<LatLng> subTaskCoordinates) {
|
||||
this.mSubTaskCoordinates = subTaskCoordinates;
|
||||
if (mMapWeltView != null) {
|
||||
mMapWeltView.setTaskListCoordinatesLatLng(subTaskCoordinates);
|
||||
}
|
||||
if (mTaskDataToFragmentCallback != null) {
|
||||
mTaskDataToFragmentCallback.setTaskListCoordinatesLatLng(subTaskCoordinates);
|
||||
}
|
||||
}
|
||||
|
||||
public void setCurrentTaskEndMarker(LatLng subTaskCoordinate) {
|
||||
if (mMapWeltView != null) {
|
||||
mMapWeltView.setCurrentTaskCoordinatesLatLng(subTaskCoordinate);
|
||||
}
|
||||
if (mTaskDataToFragmentCallback != null) {
|
||||
mTaskDataToFragmentCallback.setCurrentTaskCoordinatesLatLng(subTaskCoordinate);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 清除marker标记和任务路线数据
|
||||
*/
|
||||
public void clearAllMarkerAndPolyline() {
|
||||
if (mMapWeltView != null) {
|
||||
mMapWeltView.clearAllMarkerAndPolyline();
|
||||
}
|
||||
if (mTaskDataToFragmentCallback != null) {
|
||||
mTaskDataToFragmentCallback.clearAllMarkerAndPolyline();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 导航去目的地
|
||||
*/
|
||||
public void startNaviToStation(Boolean isVoicePlay, double startLat, double startLng, double endLat, double endLng) {
|
||||
AmapNaviToDestinationModel.getInstance(getContext()).destroyAmaNavi();
|
||||
NaviLatLng startNaviLatLng = new NaviLatLng(startLat, startLng);
|
||||
NaviLatLng endNaviLatLng = new NaviLatLng(endLat, endLng);
|
||||
AmapNaviToDestinationModel.getInstance(getContext()).initAMapNavi(startNaviLatLng, endNaviLatLng);
|
||||
AmapNaviToDestinationModel.getInstance(getContext()).setVoiceIsMute(isVoicePlay);
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置任务轨迹点数据
|
||||
*/
|
||||
public void setTaskRouteList(ArrayList<SweeperRoutePlanningUpdateReqBean.Result> routeList) {
|
||||
mRouteList = routeList;
|
||||
ThreadUtils.getSinglePool().execute(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
mMapWeltView.setRouteList(routeList);
|
||||
if (mTaskDataToFragmentCallback != null) {
|
||||
mTaskDataToFragmentCallback.setRouteList(routeList);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public static String format(double value) {
|
||||
BigDecimal bd = new BigDecimal(value);
|
||||
bd = bd.setScale(2, RoundingMode.HALF_UP);
|
||||
return bd.toString();
|
||||
}
|
||||
|
||||
public void setTaskDataToFragmentCallback(ISweeperTaskDataToFragmentCallback mTaskDataToFragmentCallback) {
|
||||
this.mTaskDataToFragmentCallback = mTaskDataToFragmentCallback;
|
||||
}
|
||||
|
||||
/**
|
||||
* 结束子任务
|
||||
*/
|
||||
public void debugEndSubTask() {
|
||||
ArrayList<SweeperRoutePlanningUpdateReqBean.Result> resultArrayList = tempData();
|
||||
setTaskRouteList(resultArrayList);
|
||||
UiThreadHandler.postDelayed(() -> {
|
||||
ArrayList<SweeperRoutePlanningUpdateReqBean.Result> routeList =tempData1();
|
||||
ArrayList<WeltDataBean> weltDataBeans = new ArrayList<>();
|
||||
ArrayList<LatLng> subTaskCoordinates=new ArrayList<>();
|
||||
for (int i = 0; i < routeList.size(); i++) {
|
||||
WeltDataBean weltDataBean = new WeltDataBean();
|
||||
weltDataBean.setLocLon(routeList.get(i).longitude);
|
||||
weltDataBean.setLocLat(routeList.get(i).latitude);
|
||||
weltDataBean.setWeltDistance(Math.random() * 50);
|
||||
weltDataBeans.add(weltDataBean);
|
||||
subTaskCoordinates.add(new LatLng(routeList.get(i).latitude,routeList.get(i).longitude));
|
||||
}
|
||||
setTaskListCoordinatesLatLng(subTaskCoordinates);
|
||||
setWeltDataToMap(weltDataBeans, true, format(Math.random() * 50));
|
||||
}, 2000);
|
||||
}
|
||||
|
||||
private ArrayList<SweeperRoutePlanningUpdateReqBean.Result> tempData() {
|
||||
ArrayList<SweeperRoutePlanningUpdateReqBean.Result> results = new ArrayList<>();
|
||||
results.add(getRoute(116.41732262522,39.974576894194));
|
||||
results.add(getRoute(116.43963532201855,39.9752190287537));
|
||||
results.add(getRoute(116.4440910789222,39.96469276598098));
|
||||
results.add(getRoute(116.45254030604285,39.958762580403544));
|
||||
results.add(getRoute(116.46168616811329,39.94668171374373));
|
||||
return results;
|
||||
}
|
||||
private ArrayList<SweeperRoutePlanningUpdateReqBean.Result> tempData1() {
|
||||
ArrayList<SweeperRoutePlanningUpdateReqBean.Result> results = new ArrayList<>();
|
||||
results.add(getRoute(116.41732262522,39.974576894194));
|
||||
results.add(getRoute(116.43963532201855,39.9752190287537));
|
||||
results.add(getRoute(116.4440910789222,39.96469276598098));
|
||||
return results;
|
||||
}
|
||||
private SweeperRoutePlanningUpdateReqBean.Result getRoute(double longitude,double latitude){
|
||||
SweeperRoutePlanningUpdateReqBean.Result result = new SweeperRoutePlanningUpdateReqBean.Result();
|
||||
result.latitude = latitude;
|
||||
result.longitude =longitude;
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,50 @@
|
||||
package com.mogo.och.sweeper.fragment;
|
||||
|
||||
import android.os.Bundle;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
import androidx.fragment.app.Fragment;
|
||||
|
||||
/**
|
||||
* @author: wangmingjun
|
||||
* @date: 2021/9/9
|
||||
*/
|
||||
public abstract class BaseSweeperUIFragment extends Fragment {
|
||||
private View mRootView;
|
||||
@Nullable
|
||||
@Override
|
||||
public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
|
||||
if (mRootView == null) {
|
||||
mRootView = inflater.inflate(getLayoutId(), container, false);
|
||||
} else {
|
||||
ViewGroup viewGroup = (ViewGroup) mRootView.getParent();
|
||||
if (viewGroup != null) {
|
||||
viewGroup.removeView(mRootView);
|
||||
}
|
||||
}
|
||||
initViews(mRootView);
|
||||
initViews(savedInstanceState);
|
||||
return mRootView;
|
||||
}
|
||||
/**
|
||||
* 布局资源
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
protected abstract int getLayoutId();
|
||||
|
||||
protected abstract void initViews(View view);
|
||||
|
||||
protected void initViews(Bundle savedInstanceState) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDestroy() {
|
||||
super.onDestroy();
|
||||
mRootView = null;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,230 @@
|
||||
package com.mogo.och.sweeper.fragment;
|
||||
|
||||
import android.os.Bundle;
|
||||
import android.view.View;
|
||||
|
||||
import com.amap.api.navi.AMapNaviViewListener;
|
||||
import com.mogo.eagle.core.utilcode.mogo.logger.CallerLogger;
|
||||
import com.mogo.och.common.module.map.AmapNaviToDestinationModel;
|
||||
import com.mogo.och.common.module.map.CommonAmapNaviVIew;
|
||||
import com.mogo.och.common.module.map.ICommonNaviChangedCallback;
|
||||
import com.mogo.och.sweeper.R;
|
||||
|
||||
import static com.mogo.eagle.core.utilcode.mogo.logger.scene.SceneConstant.M_TAXI;
|
||||
|
||||
/**
|
||||
* @author: wangmingjun
|
||||
* @date: 2021/11/30
|
||||
*/
|
||||
public class SweeperAmapNaviFragment extends BaseSweeperUIFragment implements AMapNaviViewListener {
|
||||
|
||||
private CommonAmapNaviVIew mAMapNaviView;
|
||||
private ICommonNaviChangedCallback mNaviToStartInfoCallback;
|
||||
public static SweeperAmapNaviFragment newInstance() {
|
||||
|
||||
Bundle args = new Bundle();
|
||||
|
||||
SweeperAmapNaviFragment fragment = new SweeperAmapNaviFragment();
|
||||
fragment.setArguments(args);
|
||||
return fragment;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected int getLayoutId() {
|
||||
return R.layout.sweeper_amap_navi_view;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void initViews(View view) {
|
||||
mAMapNaviView = view.findViewById(R.id.navi_view);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void initViews(Bundle savedInstanceState) {
|
||||
super.initViews(savedInstanceState);
|
||||
if (mAMapNaviView != null)
|
||||
mAMapNaviView.onCreate(savedInstanceState);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onResume() {
|
||||
super.onResume();
|
||||
if (mAMapNaviView != null)
|
||||
mAMapNaviView.onResume();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onPause() {
|
||||
super.onPause();
|
||||
if (mAMapNaviView != null)
|
||||
mAMapNaviView.onPause();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onHiddenChanged(boolean hidden) {
|
||||
super.onHiddenChanged(hidden);
|
||||
if (hidden) { //不在最前端界面显示
|
||||
if (mAMapNaviView != null){
|
||||
mAMapNaviView.onPause();
|
||||
}
|
||||
} else { //重新显示到最前端
|
||||
if (mAMapNaviView != null){
|
||||
mAMapNaviView.onResume();
|
||||
}
|
||||
}
|
||||
}
|
||||
@Override
|
||||
public void onDestroy() {
|
||||
super.onDestroy();
|
||||
|
||||
AmapNaviToDestinationModel.getInstance(getContext()).setVoiceIsMute(false);
|
||||
if (mAMapNaviView != null){
|
||||
mAMapNaviView.onDestroy();
|
||||
}
|
||||
|
||||
if (mNaviToStartInfoCallback != null){
|
||||
mNaviToStartInfoCallback = null;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onNaviSetting() {
|
||||
//底部导航设置点击回调
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onNaviCancel() {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onNaviMapMode(int naviMode) {
|
||||
//导航态车头模式,0:车头朝上状态;1:正北朝上模式。
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onNaviTurnClick() {
|
||||
//转弯view的点击回调
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onNextRoadClick() {
|
||||
//下一个道路View点击回调
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void onScanViewButtonClick() {
|
||||
//全览按钮点击回调
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void onLockMap(boolean isLock) {
|
||||
//锁地图状态发生变化时回调
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onNaviViewLoaded() {
|
||||
CallerLogger.INSTANCE.d(M_TAXI + "wlx", "导航页面加载成功");
|
||||
CallerLogger.INSTANCE.d(M_TAXI + "wlx", "请不要使用AMapNaviView.getMap().setOnMapLoadedListener();会overwrite导航SDK内部画线逻辑");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onMapTypeChanged(int i) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onNaviViewShowMode(int i) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onNaviBackClick() {
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* 车道信息说明:
|
||||
* <p>
|
||||
* 0xFF, 无对应车道
|
||||
* 0, 直行
|
||||
* 1, 左转
|
||||
* 2, 直行+左转
|
||||
* 3, 右转
|
||||
* 4, 直行+右转
|
||||
* 5, 左掉头
|
||||
* 6, 左转+右转
|
||||
* 7, 直行+左转+右转
|
||||
* 8, 右掉头
|
||||
* 9, 直行+左掉头
|
||||
* 10, 直行+右掉头
|
||||
* 11, 左转+左掉头
|
||||
* 12, 右转+右掉头
|
||||
* 13, 直行+扩展
|
||||
* 14, 左转+左掉头+扩展
|
||||
* 15, 保留
|
||||
* 16, 直行+左转+左掉头
|
||||
* 17, 右转+左掉头
|
||||
* 18, 左转+右转+左掉头
|
||||
* 19, 直行+右转+左掉头
|
||||
* 20, 左转+右掉头
|
||||
* 21, 公交车道
|
||||
* 22, 空车道
|
||||
* 23 可变车道
|
||||
*/
|
||||
|
||||
String[] array = {
|
||||
"直行车道"
|
||||
, "左转车道"
|
||||
, "左转或直行车道"
|
||||
, "右转车道"
|
||||
, "右转或直行车道"
|
||||
, "左掉头车道"
|
||||
, "左转或者右转车道"
|
||||
, " 左转或右转或直行车道"
|
||||
, "右转掉头车道"
|
||||
, "直行或左转掉头车道"
|
||||
, "直行或右转掉头车道"
|
||||
, "左转或左掉头车道"
|
||||
, "右转或右掉头车道"
|
||||
, "直行并且车道扩展"
|
||||
, "左转+左掉头+扩展"
|
||||
, "不可以选择该车道"
|
||||
, "直行+左转+左掉头车道"
|
||||
, "右转+左掉头"
|
||||
, "左转+右转+左掉头"
|
||||
, "直行+右转+左掉头"
|
||||
, "左转+右掉头"
|
||||
, "公交车道"
|
||||
, "空车道"
|
||||
, "可变车道"
|
||||
};
|
||||
|
||||
String[] actions = {
|
||||
"直行"
|
||||
, "左转"
|
||||
, "左转或直行"
|
||||
, "右转"
|
||||
, "右转或这行"
|
||||
, "左掉头"
|
||||
, "左转或者右转"
|
||||
, " 左转或右转或直行"
|
||||
, "右转掉头"
|
||||
, "直行或左转掉头"
|
||||
, "直行或右转掉头"
|
||||
, "左转或左掉头"
|
||||
, "右转或右掉头"
|
||||
, "直行并且车道扩展"
|
||||
, "左转+左掉头+扩展"
|
||||
, "不可以选择"
|
||||
, "直行+左转+左掉头"
|
||||
, "右转+左掉头"
|
||||
, "左转+右转+左掉头"
|
||||
, "直行+右转+左掉头"
|
||||
, "左转+右掉头"
|
||||
, "公交车道"
|
||||
, "空车道"
|
||||
, "可变车道"
|
||||
};
|
||||
}
|
||||
@@ -1,398 +0,0 @@
|
||||
package com.mogo.och.sweeper.fragment;
|
||||
|
||||
import static com.mogo.eagle.core.utilcode.mogo.logger.scene.SceneConstant.M_BUS;
|
||||
|
||||
import android.content.Intent;
|
||||
import android.view.View;
|
||||
import android.widget.TextView;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
|
||||
import com.mogo.commons.AbsMogoApplication;
|
||||
import com.mogo.commons.debug.DebugConfig;
|
||||
import com.mogo.commons.voice.AIAssist;
|
||||
import com.mogo.eagle.core.data.map.CenterLine;
|
||||
import com.mogo.eagle.core.function.api.autopilot.IMoGoAutopilotStatusListener;
|
||||
import com.mogo.eagle.core.function.call.autopilot.CallerAutoPilotStatusListenerManager;
|
||||
import com.mogo.eagle.core.function.call.map.CallerMapUIServiceManager;
|
||||
import com.mogo.eagle.core.utilcode.mogo.logger.CallerLogger;
|
||||
import com.mogo.eagle.core.utilcode.util.ToastUtils;
|
||||
import com.mogo.map.marker.IMogoMarker;
|
||||
import com.mogo.map.marker.MogoMarkerOptions;
|
||||
import com.mogo.och.sweeper.R;
|
||||
import com.mogo.och.sweeper.bean.SweeperStationBean;
|
||||
import com.mogo.och.sweeper.constant.SweeperConst;
|
||||
import com.mogo.och.sweeper.presenter.SweeperPresenter;
|
||||
import com.mogo.och.sweeper.ui.SweeperSwitchLineActivity;
|
||||
import com.mogo.och.sweeper.view.SlidePanelView;
|
||||
import com.mogo.och.common.module.utils.OCHThreadPoolManager;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
|
||||
|
||||
/**
|
||||
* 网约车小巴界面
|
||||
*
|
||||
* @author tongchenfei
|
||||
*/
|
||||
public class SweeperFragment extends BaseSweeperTabFragment<SweeperFragment, SweeperPresenter>
|
||||
implements SlidePanelView.OnSlidePanelMoveToEndListener, View.OnClickListener {
|
||||
private static final String TAG = "SweeperFragment";
|
||||
|
||||
private TextView mCurrentStationName;
|
||||
private TextView mNextStationName;
|
||||
private TextView mCurrentTag;
|
||||
private TextView mNextTag;
|
||||
private TextView mSwitchLine; //切换路线
|
||||
private TextView mLineName;
|
||||
private int mCurrentStation = 0;
|
||||
|
||||
private View mSweepers;
|
||||
|
||||
private SweeperStationBean startStation = null;
|
||||
private SweeperStationBean endStation = null;
|
||||
|
||||
@Override
|
||||
public String getTagName() {
|
||||
return "SweepersFragment";
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void initViews() {
|
||||
super.initViews();
|
||||
mSweepers = findViewById(R.id.module_och_sweeper_tag);
|
||||
mCurrentStationName = findViewById(R.id.module_och_sweeper_current_station);
|
||||
mCurrentTag = findViewById(R.id.module_och_sweeper_current_station_anchor);
|
||||
mNextStationName = findViewById(R.id.module_och_sweeper_order_end_station);
|
||||
mNextTag = findViewById(R.id.module_och_sweeper_next_station_anchor);
|
||||
mSwitchLine = findViewById(R.id.switch_line_btn);
|
||||
mLineName = findViewById(R.id.module_och_sweeper_line_name);
|
||||
|
||||
if (DebugConfig.isDebug()) {
|
||||
mSweepers.setOnClickListener(view -> {
|
||||
ToastUtils.showShort("重置了车站状态");
|
||||
mPresenter.querySweepersRoutes();
|
||||
});
|
||||
|
||||
//debug下调用测试面板
|
||||
mCurrentStationName.setOnLongClickListener(v -> {
|
||||
debugTestBar();
|
||||
showHideTestBar();
|
||||
return true;
|
||||
});
|
||||
}
|
||||
|
||||
CallerLogger.INSTANCE.d(M_BUS + TAG, "initView: " + CallerAutoPilotStatusListenerManager.INSTANCE.getAutoPilotStatusInfo().getState());
|
||||
// 初始化的时候设置 UI 按钮状态
|
||||
switch (CallerAutoPilotStatusListenerManager.INSTANCE.getAutoPilotStatusInfo().getState()) {
|
||||
case IMoGoAutopilotStatusListener.STATUS_AUTOPILOT_DISABLE:
|
||||
hideAutopilotBiz();
|
||||
break;
|
||||
case IMoGoAutopilotStatusListener.STATUS_AUTOPILOT_ENABLE:
|
||||
showAutopilotBiz();
|
||||
onAutopilotStatusChanged(IMoGoAutopilotStatusListener.STATUS_AUTOPILOT_ENABLE);
|
||||
break;
|
||||
case IMoGoAutopilotStatusListener.STATUS_AUTOPILOT_RUNNING:
|
||||
showAutopilotBiz();
|
||||
onAutopilotStatusChanged(IMoGoAutopilotStatusListener.STATUS_AUTOPILOT_RUNNING);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
mSwitchLine.setOnClickListener(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void debugArrivedStation() {
|
||||
mPresenter.onAutopilotArriveAtStation(null);
|
||||
}
|
||||
|
||||
@NonNull
|
||||
@Override
|
||||
protected SweeperPresenter createPresenter() {
|
||||
return new SweeperPresenter(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onResume() {
|
||||
super.onResume();
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据站点列表信息刷新车站面板,滑块面板
|
||||
*
|
||||
* @param stationList 车站列表信息
|
||||
* @param currentStation 当前站点
|
||||
* @param nextStation 下个站点
|
||||
* @param isArrived 是否都站
|
||||
*/
|
||||
public void refreshSweeperStations(String lineName, List<SweeperStationBean> stationList
|
||||
, int currentStation, int nextStation, boolean isArrived) {
|
||||
mCurrentStation = currentStation;
|
||||
if (getActivity() == null) {
|
||||
return;
|
||||
}
|
||||
getActivity().runOnUiThread(() -> {
|
||||
if (stationList == null) {
|
||||
// 获取小巴数据失败
|
||||
return;
|
||||
}
|
||||
|
||||
// 渲染小巴路线数据
|
||||
renderCurrentStationStatus(lineName, stationList, currentStation, nextStation, isArrived);
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* 重新刷新站点信息 isArrived 是否到站
|
||||
*/
|
||||
private void renderCurrentStationStatus(String lineName, List<SweeperStationBean> stationList, int currentStation
|
||||
, int nextStation, boolean isArrived) {
|
||||
CallerLogger.INSTANCE.d(M_BUS + "MapMaker ", "currentStation=" + currentStation + ",nextStation=" + nextStation + "isArrived=" + isArrived);
|
||||
String currentStationName = null;
|
||||
String nextStationName = null;
|
||||
|
||||
boolean isArriveEndStation = false;
|
||||
boolean isArriveAtStation = false;
|
||||
boolean isArriveAtStartStation = false;
|
||||
|
||||
mLineName.setText(lineName);
|
||||
|
||||
// 获取当前站点的名称
|
||||
currentStationName = stationList.get(currentStation).getName();
|
||||
|
||||
startStation = stationList.get(0);
|
||||
endStation = stationList.get(stationList.size() - 1);
|
||||
|
||||
// 是否到达起点
|
||||
if (currentStation == 0) {
|
||||
isArriveAtStartStation = true;
|
||||
mCurrentTag.setText(getResources().getString(R.string.sweeper_arrive_to_end_start));
|
||||
|
||||
setOrRemoveMapMaker(true, SweeperConst.SWEEPER_START_MAP_MAKER, startStation.getLat()
|
||||
, startStation.getLon(), R.raw.star_marker);
|
||||
setOrRemoveMapMaker(true, SweeperConst.SWEEPER_END_MAP_MAKER, endStation.getLat()
|
||||
, endStation.getLon(), R.raw.end_marker);
|
||||
} else if (currentStation > 0 && currentStation < stationList.size() - 1) {// 是否到达站点
|
||||
isArriveAtStation = true;
|
||||
mCurrentTag.setText(getResources().getString(R.string.sweeper_arrive_to_current_tag));
|
||||
mNextTag.setText(getResources().getString(R.string.sweeper_arrive_to_next_tag));
|
||||
|
||||
setOrRemoveMapMaker(false, SweeperConst.SWEEPER_START_MAP_MAKER, startStation.getLat()
|
||||
, startStation.getLon(), R.raw.star_marker);
|
||||
setOrRemoveMapMaker(true, SweeperConst.SWEEPER_END_MAP_MAKER, endStation.getLat()
|
||||
, endStation.getLon(), R.raw.end_marker);
|
||||
} else if (currentStation == stationList.size() - 1) {// 是否到达终点
|
||||
isArriveEndStation = true;
|
||||
nextStationName = "--";
|
||||
mNextTag.setText(getResources().getString(R.string.sweeper_arrive_to_end_end));
|
||||
|
||||
setOrRemoveMapMaker(false, SweeperConst.SWEEPER_START_MAP_MAKER, startStation.getLat()
|
||||
, startStation.getLon(), R.raw.star_marker);
|
||||
|
||||
if (isArrived) {
|
||||
setOrRemoveMapMaker(false, SweeperConst.SWEEPER_END_MAP_MAKER, endStation.getLat()
|
||||
, endStation.getLon(), R.raw.end_marker);
|
||||
} else {
|
||||
setOrRemoveMapMaker(true, SweeperConst.SWEEPER_END_MAP_MAKER, endStation.getLat()
|
||||
, endStation.getLon(), R.raw.end_marker);
|
||||
}
|
||||
}
|
||||
|
||||
// 获取下一站点名称
|
||||
if (nextStation > currentStation && nextStation <= stationList.size() - 1) {
|
||||
nextStationName = stationList.get(nextStation).getName();
|
||||
}
|
||||
|
||||
// 是否到达终点
|
||||
if (nextStation == stationList.size() - 1 || nextStation == -1) {
|
||||
mNextTag.setText(getResources().getString(R.string.sweeper_arrive_to_end_end));
|
||||
} else {
|
||||
mNextTag.setText(getResources().getString(R.string.sweeper_arrive_to_next_tag));
|
||||
}
|
||||
|
||||
if (currentStation == 0 && isArrived) {
|
||||
showOrHideSwitchLineBtn(true);
|
||||
} else {
|
||||
showOrHideSwitchLineBtn(false);
|
||||
}
|
||||
|
||||
// 重置滑动按钮文字
|
||||
if (isArriveEndStation) {
|
||||
showSlidePanle("单程结束");
|
||||
} else if (isArriveAtStartStation) {
|
||||
showSlidePanle("滑动出发");
|
||||
} else if (isArriveAtStation) {
|
||||
showSlidePanle("滑动出发");
|
||||
}
|
||||
|
||||
mCurrentStationName.setText(currentStationName);
|
||||
mNextStationName.setText(nextStationName);
|
||||
updateSweeperTestBarInfo();
|
||||
}
|
||||
|
||||
private void showOrHideSwitchLineBtn(boolean isShow) {
|
||||
if (isShow) {
|
||||
mSwitchLine.setVisibility(View.VISIBLE);
|
||||
} else {
|
||||
mSwitchLine.setVisibility(View.GONE);
|
||||
}
|
||||
}
|
||||
|
||||
public void hideOchSweeper() {
|
||||
// tvNotice.setVisibility(View.GONE);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getStationPanelViewId() {
|
||||
return R.layout.fragment_och_sweeper;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getSweepOperatePanelViewId() {
|
||||
return R.layout.sweeper_operate_panel_view;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void restartAutopilot() {
|
||||
if (!isAnimateRunning) {
|
||||
mPresenter.restartAutopilot();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public SlidePanelView.OnSlidePanelMoveToEndListener getSlidePanelOnEndListener() {
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void moveToEnd() {
|
||||
// 开启自动驾驶到下一站
|
||||
if (isAnimateRunning) {
|
||||
stopAutopilotAnimation();
|
||||
}
|
||||
mPresenter.autoDriveToNextStation(false);
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置自动驾驶可用状态
|
||||
*/
|
||||
public void onAutopilotEnableChange(boolean isEnable) {
|
||||
if (isEnable) {
|
||||
showAutopilotBiz();
|
||||
} else {
|
||||
hideAutopilotBiz();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onChangeOperationStatus() {
|
||||
super.onChangeOperationStatus();
|
||||
mPresenter.onChangeOperationStatus();
|
||||
}
|
||||
|
||||
/**
|
||||
* 修改经营状态
|
||||
*
|
||||
* @param launch true-收车,false-出车
|
||||
*/
|
||||
public void changeOperationStatus(boolean launch) {
|
||||
isOperationStatus = launch;
|
||||
if (launch) {
|
||||
// 出车的时候重制站点状态
|
||||
mPresenter.querySweepersRoutes();
|
||||
tvOperationStatus.setText("收车");
|
||||
showPanel();
|
||||
} else {
|
||||
AIAssist.getInstance(getContext()).speakTTSVoice("已收车");
|
||||
tvOperationStatus.setText("出车");
|
||||
hideSlidePanel();
|
||||
hidPanel();
|
||||
|
||||
//移除起点终点
|
||||
if (null != startStation) {
|
||||
setOrRemoveMapMaker(false, SweeperConst.SWEEPER_START_MAP_MAKER, startStation.getLat()
|
||||
, startStation.getLon(), R.raw.star_marker);
|
||||
}
|
||||
if (null != endStation) {
|
||||
setOrRemoveMapMaker(false, SweeperConst.SWEEPER_END_MAP_MAKER, endStation.getLat()
|
||||
, endStation.getLon(), R.raw.end_marker);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* VR模式切换
|
||||
*
|
||||
* @param isVRMode
|
||||
*/
|
||||
public void onVRModeChanged(boolean isVRMode) {
|
||||
if (mRootView != null) {
|
||||
mRootView.setVisibility(isVRMode ? View.VISIBLE : View.GONE);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 绘制地图起点终点
|
||||
*
|
||||
* @param isAdd
|
||||
* @param uuid
|
||||
*/
|
||||
private void setOrRemoveMapMaker(boolean isAdd, String uuid, double lat, double longi, int resourceId) {
|
||||
if (isAdd) {
|
||||
Runnable setMapMarkerRunnable = () -> {
|
||||
CallerLogger.INSTANCE.d(M_BUS + "setMapMaker= " + Thread.currentThread().getName(),
|
||||
uuid + "=latitude=" + lat + ",longitude=" + longi);
|
||||
|
||||
MogoMarkerOptions options = new MogoMarkerOptions()
|
||||
.owner(SweeperConst.TYPE_MARKER_SWEEPER_ORDER)
|
||||
.anchor(0.5f, 0.5f)
|
||||
.set3DMode(true)
|
||||
.gps(true)
|
||||
.controlAngle(true)
|
||||
.icon3DRes(resourceId)
|
||||
.latitude(lat)
|
||||
.longitude(longi);
|
||||
IMogoMarker marker = Objects.requireNonNull(CallerMapUIServiceManager.INSTANCE.getMarkerManager(AbsMogoApplication.getApp())).addMarker(uuid, options);
|
||||
CenterLine centerLine = CallerMapUIServiceManager.INSTANCE.getMapUIController().getCenterLineInfo(
|
||||
longi, lat, -1);
|
||||
if (null != centerLine) { // 有可能鹰眼map为空没有角度。判空使用后可能造成maker角度跟道路角度不一致
|
||||
marker.setRotateAngle(centerLine.getAngle().floatValue());
|
||||
}
|
||||
};
|
||||
OCHThreadPoolManager.getsInstance().execute(setMapMarkerRunnable);
|
||||
} else {
|
||||
Runnable removeMapMarkerRunnable = () -> {
|
||||
CallerLogger.INSTANCE.d(M_BUS + "RemoveMapMaker=" + Thread.currentThread().getName(),
|
||||
uuid + "=latitude=" + lat + ",longitude=" + longi);
|
||||
Objects.requireNonNull(CallerMapUIServiceManager.INSTANCE.getMarkerManager(AbsMogoApplication.getApp())).removeMarkers(uuid);
|
||||
};
|
||||
|
||||
OCHThreadPoolManager.getsInstance().execute(removeMapMarkerRunnable);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void debugAutoPilotStatus(int status) {
|
||||
mPresenter.debugAutoPilotStatus(status);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
if (v.getId() == R.id.switch_line_btn) {//切换路线条件: 自动驾驶过程中,点击则toast提示:自动驾驶中,不可切换路线
|
||||
//本次行程未结束,不支持切换路线。点击则toast提示:当前行程未完成,不可切换路线
|
||||
if (CallerAutoPilotStatusListenerManager.INSTANCE.getAutoPilotStatusInfo().getState()
|
||||
== IMoGoAutopilotStatusListener.STATUS_AUTOPILOT_RUNNING) {
|
||||
ToastUtils.showLong(getResources().getString(R.string.sweeper_switch_line_btn_warning1));
|
||||
return;
|
||||
}
|
||||
if (mCurrentStation > 0) {
|
||||
ToastUtils.showLong(getResources().getString(R.string.sweeper_switch_line_btn_warning2));
|
||||
return;
|
||||
}
|
||||
Intent intent = new Intent(getContext(), SweeperSwitchLineActivity.class);
|
||||
startActivity(intent);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,528 @@
|
||||
package com.mogo.och.sweeper.fragment
|
||||
|
||||
import android.graphics.Color
|
||||
import android.os.Bundle
|
||||
import android.view.View
|
||||
import android.view.View.OnClickListener
|
||||
import androidx.lifecycle.lifecycleScope
|
||||
import androidx.recyclerview.widget.LinearLayoutManager
|
||||
import chassis.ChassisStatesOuterClass
|
||||
import com.amap.api.maps.model.LatLng
|
||||
import com.mogo.commons.AbsMogoApplication
|
||||
import com.mogo.eagle.core.data.map.MogoLocation
|
||||
import com.mogo.eagle.core.function.call.autopilot.CallerAutoPilotControlManager
|
||||
import com.mogo.eagle.core.function.call.autopilot.CallerAutoPilotStatusListenerManager
|
||||
import com.mogo.eagle.core.utilcode.mogo.logger.CallerLogger.d
|
||||
import com.mogo.eagle.core.utilcode.mogo.logger.scene.SceneConstant
|
||||
import com.mogo.eagle.core.utilcode.util.ClickUtils
|
||||
import com.mogo.eagle.core.utilcode.util.ToastUtils
|
||||
import com.mogo.och.common.module.utils.CoordinateCalculateRouteUtil
|
||||
import com.mogo.och.sweeper.R
|
||||
import com.mogo.och.sweeper.bean.*
|
||||
import com.mogo.och.sweeper.constant.SubTaskTypeEnum
|
||||
import com.mogo.och.sweeper.constant.TaskStatusEnum
|
||||
import com.mogo.och.sweeper.database.MyDataBase
|
||||
import com.mogo.och.sweeper.presenter.SweeperPresenter
|
||||
import com.mogo.och.sweeper.ui.adapter.TaskListAdapter
|
||||
import com.mogo.och.sweeper.ui.dialog.SweeperManualDrivingDialog
|
||||
import com.mogo.och.sweeper.ui.dialog.SweeperNoTitleCommonDialog
|
||||
import com.mogo.och.sweeper.ui.popwindow.MenuPopWindow
|
||||
import kotlinx.android.synthetic.main.fragment_och_sweeper.*
|
||||
import kotlinx.android.synthetic.main.sweeper_current_task_info.view.*
|
||||
import kotlinx.android.synthetic.main.sweeper_no_data_common_view.*
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.launch
|
||||
import kotlin.math.roundToInt
|
||||
|
||||
/**
|
||||
* 清扫车主界面
|
||||
*/
|
||||
class SweeperFragment : BaseSweeperTabFragment<SweeperFragment?, SweeperPresenter?>(), MenuPopWindow.OnMenuItemOnClickListener {
|
||||
|
||||
companion object {
|
||||
const val TAG = "SweeperFragment"
|
||||
}
|
||||
|
||||
private var mAdapter: TaskListAdapter? = null
|
||||
private var mCurrentSubPosition: Int = 0 //子任务下标
|
||||
private var mSubMutableList: MutableList<SubInfo>? = null
|
||||
private var mSubTaskBean: SweeperSubTaskBean? = null
|
||||
private var mSubTaskType: SubTaskTypeEnum = SubTaskTypeEnum.AUTOPILOT_SUBTYPE //1:自动驾驶子任务 2:人工驾驶子任务
|
||||
private var mCleanSystemState: ChassisStatesOuterClass.SweeperFuTianTaskSystemStates? = null
|
||||
private var mMainTask: SweeperMainTaskBean? = null
|
||||
private var mLocation: MogoLocation? = null
|
||||
private var mSubInfo: SubInfo? = null
|
||||
|
||||
override fun getTagName(): String {
|
||||
return "SweepersFragment"
|
||||
}
|
||||
|
||||
override fun initViews() {
|
||||
super.initViews()
|
||||
mAdapter = context?.let { TaskListAdapter() }
|
||||
val linearLayoutManager = LinearLayoutManager(context)
|
||||
linearLayoutManager.orientation = LinearLayoutManager.VERTICAL
|
||||
rvTaskList?.layoutManager = linearLayoutManager
|
||||
rvTaskList?.adapter = mAdapter
|
||||
mAdapter?.setOnTaskItemClickListener(onTaskItemClickListener)
|
||||
initListener()
|
||||
sweeper_cl_work_mode.setTrafficDataView(trafficDataView)
|
||||
sweeper_current_task_view.readyTaskBtn.setOnClickListener {
|
||||
if (ClickUtils.isFastClick()) {//防止重复点击
|
||||
if (mSubTaskType.code == SubTaskTypeEnum.MANUAL_DRIVING_SUBTYPE.code) {
|
||||
manualDriving(false)
|
||||
} else {
|
||||
//开始执行任务
|
||||
mSubInfo?.apply {
|
||||
presenter?.startTask(isFirstSubTask(), isLastSubTask(), taskId, mSubTaskType, taskStatus)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override fun createPresenter(): SweeperPresenter {
|
||||
return SweeperPresenter(this)
|
||||
}
|
||||
|
||||
override fun onActivityCreated(savedInstanceState: Bundle?) {
|
||||
super.onActivityCreated(savedInstanceState)
|
||||
mPresenter?.getCurrentTask()
|
||||
}
|
||||
|
||||
override fun getTaskListPanelViewId(): Int {
|
||||
return R.layout.fragment_och_sweeper
|
||||
}
|
||||
|
||||
/**
|
||||
* 任务列表面板隐藏或显示
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
private fun setShowTaskListPanelView(isShow: Boolean) {
|
||||
tvTaskConfirm.setTextColor(Color.parseColor("#66FFFFFF"))
|
||||
tvTaskConfirm.isSelected = false
|
||||
if (isShow) {
|
||||
sweeper_current_task_list_view.visibility = View.VISIBLE
|
||||
} else {
|
||||
sweeper_current_task_list_view.visibility = View.GONE
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 当前任务面板隐藏或显示
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
private fun setShowCurrentTaskPanelView(isShow: Boolean) {
|
||||
if (isShow) {
|
||||
sweeper_current_task_view.visibility = View.VISIBLE
|
||||
} else {
|
||||
sweeper_current_task_view.visibility = View.GONE
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* VR模式切换
|
||||
*
|
||||
* @param isVRMode
|
||||
*/
|
||||
fun onVRModeChanged(isVRMode: Boolean) {
|
||||
if (mRootView != null) {
|
||||
mRootView.visibility = if (isVRMode) View.VISIBLE else View.GONE
|
||||
}
|
||||
}
|
||||
|
||||
fun hideOchSweeper() {}
|
||||
override fun debugAutoPilotStatus(status: Int) {
|
||||
mPresenter?.debugAutoPilotStatus(status)
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据自动驾驶状态更新按钮
|
||||
*/
|
||||
fun startAutoBtn(autopilotState: Int) {
|
||||
sweeper_current_task_view.setStartAutoBtn(autopilotState)
|
||||
}
|
||||
|
||||
/**
|
||||
* 任务按钮状态
|
||||
*/
|
||||
fun setTaskBtn(isWorking: Boolean) {
|
||||
sweeper_current_task_view.setEnableClickBtn(isWorking)
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置各种监听事件
|
||||
*/
|
||||
private fun initListener() {
|
||||
tvTaskConfirm.setOnClickListener {
|
||||
mMainTask?.let { task ->
|
||||
mCurrentSubPosition = 0
|
||||
mSubTaskBean = SweeperSubTaskBean(task.mainTaskId, task.mainTaskName, task.mainTaskStartTime, 1, mSubMutableList)
|
||||
//获取当前子任务列表
|
||||
presenter?.getSubTaskList(task.mainTaskId, mSubTaskBean)
|
||||
mAdapter?.selectPosition(-1)
|
||||
}
|
||||
}
|
||||
//列表任务刷新
|
||||
ivTaskListRefresh.setOnClickListener {
|
||||
mPresenter?.getMainTaskList(true)
|
||||
}
|
||||
//无任务时刷新
|
||||
ivNoTaskRefresh.setOnClickListener {
|
||||
mPresenter?.getMainTaskList(true)
|
||||
}
|
||||
}
|
||||
|
||||
private val onTaskItemClickListener = object : TaskListAdapter.TaskItemClickListener {
|
||||
override fun onItemClick(position: Int, mainTask: SweeperMainTaskBean) {
|
||||
mAdapter?.selectPosition(position)
|
||||
tvTaskConfirm.isSelected = true
|
||||
tvTaskConfirm.setTextColor(Color.parseColor("#FFFFFFFF"))
|
||||
this@SweeperFragment.mMainTask = mainTask
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
override fun onMenuItemClick(itemType: TaskStatusEnum) {
|
||||
when (itemType.code) {
|
||||
TaskStatusEnum.JUMP_OVER_SUBTASK.code -> {//跳过任务
|
||||
mSubInfo?.let {
|
||||
//如果当前只有一个子任务,则isFirst设置为false
|
||||
presenter?.subTaskSkip(if (mSubMutableList?.size == 1) false else isFirstSubTask(), isLastSubTask(), it.taskId)
|
||||
}
|
||||
}
|
||||
TaskStatusEnum.END_TASK.code -> {//结束主任务
|
||||
endMainTask()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun onSweeperFutianCleanSystemState(cleanSystemState: ChassisStatesOuterClass.SweeperFuTianTaskSystemStates) {
|
||||
lifecycleScope.launch(Dispatchers.Main) {
|
||||
mCleanSystemState = cleanSystemState
|
||||
sweeper_cl_work_mode.setSweeperFutianCleanSystemState(mSubTaskType, cleanSystemState)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置当前主任务列表数据
|
||||
*/
|
||||
fun setMainTaskList(mainTaskBeanList: MutableList<SweeperMainTaskBean>?, refresh: Boolean) {
|
||||
setShowCurrentTaskPanelView(false)
|
||||
setShowTaskListPanelView(true)
|
||||
sweeper_cl_work_mode.visibility = View.GONE
|
||||
if (mainTaskBeanList != null && mainTaskBeanList.isNotEmpty()) {
|
||||
noTaskDataView.visibility = View.GONE
|
||||
sweeperListCl.visibility = View.VISIBLE
|
||||
mAdapter?.setTaskListData(mainTaskBeanList)
|
||||
} else {
|
||||
noTaskDataView.visibility = View.VISIBLE
|
||||
sweeperListCl.visibility = View.GONE
|
||||
}
|
||||
if (refresh) {
|
||||
ToastUtils.showLong("已刷新")
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置当前子任务列表数据
|
||||
*/
|
||||
fun setSubTaskBean(subTaskBean: SweeperSubTaskBean, isWorkingSubTask: Boolean) {
|
||||
this.mSubTaskBean = subTaskBean
|
||||
this.mSubTaskBean?.let {
|
||||
setShowCurrentTaskPanelView(true)
|
||||
setShowTaskListPanelView(false)
|
||||
sweeper_cl_work_mode.visibility = View.VISIBLE
|
||||
mCurrentSubPosition = if (isWorkingSubTask) {//如果是正在执行的子任务
|
||||
it.sort - 1
|
||||
} else {
|
||||
0
|
||||
}
|
||||
d(SceneConstant.M_SWEEPER + TAG, "setSubTaskBean mCurrentSubPosition:$mCurrentSubPosition")
|
||||
sweeper_current_task_view.setData(sweeper_cl_work_mode, it, mCurrentSubPosition, this, presenter)
|
||||
mSubMutableList = it.subList
|
||||
setSubTaskData()
|
||||
if (mSubTaskType.code == SubTaskTypeEnum.AUTOPILOT_SUBTYPE.code) {//自动驾驶子任务需要调用详情
|
||||
mSubInfo?.let { subInfo ->
|
||||
presenter?.getSubTaskDetail(isFirstSubTask(), isLastSubTask(), subInfo.taskId, mSubTaskType, false)//加载子任务详情包括轨迹信息
|
||||
}
|
||||
}
|
||||
mMainTask = SweeperMainTaskBean(it.taskId, it.taskName, 0, it.taskStartTime)
|
||||
clearAllMarkerAndPolyline()
|
||||
addWeltData()
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 更新子任务状态
|
||||
*/
|
||||
fun updateSubTaskStatus(typeEnum: TaskStatusEnum, isLastSubTask: Boolean) {
|
||||
if (isLastSubTask) {
|
||||
showAmapNaviToStationFragment(false)
|
||||
clearAllMarkerAndPolyline()
|
||||
//整个大任务结束,则删除它相关的贴边数据缓存
|
||||
lifecycleScope.launch(Dispatchers.IO) {
|
||||
MyDataBase.getInstance().weltDataDao.deleteAllWeltData()
|
||||
mPresenter?.clearRouteList()
|
||||
}
|
||||
setTaskProgress("0")
|
||||
|
||||
val builder = SweeperManualDrivingDialog.Builder()
|
||||
val endConfirmDialog = builder
|
||||
.tips("任务已完成")
|
||||
.confirmStr("确认")
|
||||
.build(requireContext())
|
||||
endConfirmDialog?.setClickListener(object: SweeperManualDrivingDialog.ClickListener{
|
||||
override fun confirm() {
|
||||
mPresenter?.getMainTaskList(false)
|
||||
}
|
||||
})
|
||||
endConfirmDialog?.show()
|
||||
return
|
||||
}
|
||||
when (typeEnum.code) {
|
||||
TaskStatusEnum.END_SUBTASK.code -> {//子任务结束
|
||||
mCurrentSubPosition++
|
||||
setSubTaskData()
|
||||
d(SceneConstant.M_SWEEPER + TAG, "END_SUBTASK mCurrentSubPosition:$mCurrentSubPosition")
|
||||
if (mSubTaskType.code == SubTaskTypeEnum.AUTOPILOT_SUBTYPE.code) {//自动驾驶子任务
|
||||
//关闭人工驾驶导航
|
||||
showAmapNaviToStationFragment(false)
|
||||
mSubInfo?.apply {
|
||||
presenter?.getSubTaskDetail(isFirstSubTask(), isLastSubTask(), taskId, mSubTaskType, true)
|
||||
}
|
||||
sweeper_current_task_view.setCurrentData(mCurrentSubPosition)
|
||||
} else {
|
||||
manualDriving(true)
|
||||
}
|
||||
}
|
||||
TaskStatusEnum.JUMP_OVER_SUBTASK.code -> { //子任务跳过
|
||||
//是否是最后一个子任务结束
|
||||
mCurrentSubPosition++
|
||||
setSubTaskData()
|
||||
d(SceneConstant.M_SWEEPER + TAG, "JUMP_OVER_SUBTASK mCurrentSubPosition:$mCurrentSubPosition")
|
||||
showAmapNaviToStationFragment(false)
|
||||
if (mSubTaskType.code == SubTaskTypeEnum.AUTOPILOT_SUBTYPE.code) {//自动驾驶子任务
|
||||
//关闭人工驾驶导航
|
||||
showAmapNaviToStationFragment(false)
|
||||
mSubInfo?.apply {
|
||||
presenter?.getSubTaskDetail(isFirstSubTask(), isLastSubTask(), taskId, mSubTaskType, true)
|
||||
}
|
||||
sweeper_current_task_view.setCurrentData(mCurrentSubPosition)
|
||||
} else {
|
||||
manualDriving(true)
|
||||
}
|
||||
}
|
||||
TaskStatusEnum.START_SUBTASK.code -> { //子任务开始
|
||||
setTaskBtn(true)
|
||||
sweeper_current_task_view.setTaskStatus(2)
|
||||
if (mSubTaskType == SubTaskTypeEnum.MANUAL_DRIVING_SUBTYPE) {
|
||||
sweeper_current_task_view.setCurrentData(mCurrentSubPosition)
|
||||
}
|
||||
}
|
||||
}
|
||||
setEndStationMarker()
|
||||
}
|
||||
|
||||
/**
|
||||
* 主任务重置
|
||||
*/
|
||||
fun setMainTaskReset(isSuccess: Boolean) {
|
||||
if (isSuccess) {
|
||||
//任务重置后,重新拉取任务列表数据
|
||||
mPresenter?.getMainTaskList(false)
|
||||
//清除任务全览图的marker和路线
|
||||
clearAllMarkerAndPolyline()
|
||||
showAmapNaviToStationFragment(false)
|
||||
setTaskProgress("0")
|
||||
//整个大任务结束,则删除它相关的贴边数据缓存
|
||||
lifecycleScope.launch(Dispatchers.IO) {
|
||||
MyDataBase.getInstance().weltDataDao.deleteAllWeltData()
|
||||
mPresenter?.clearRouteList()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置当前选中的子任务信息
|
||||
*/
|
||||
private fun setSubTaskData() {
|
||||
mSubMutableList?.let {
|
||||
mSubInfo = it[mCurrentSubPosition]
|
||||
mSubTaskType = if (it[mCurrentSubPosition].taskType == SubTaskTypeEnum.AUTOPILOT_SUBTYPE.code)
|
||||
SubTaskTypeEnum.AUTOPILOT_SUBTYPE else SubTaskTypeEnum.MANUAL_DRIVING_SUBTYPE
|
||||
//设置当前子任务信息
|
||||
presenter?.setSubtask(isFirstSubTask(), isLastSubTask(), it[mCurrentSubPosition].taskId, it[mCurrentSubPosition].taskType)
|
||||
}
|
||||
/**
|
||||
* 计算任务的进度
|
||||
*/
|
||||
lifecycleScope.launch(Dispatchers.IO) {
|
||||
mSubMutableList?.let {
|
||||
var sum: Double = 0.0
|
||||
for (index in it.indices) {
|
||||
sum += it[index].mileage
|
||||
}
|
||||
var completed: Double = 0.0
|
||||
for (index in it.indices) {
|
||||
if (index < mCurrentSubPosition) {
|
||||
// 已完成的子任务记入完成度,进行中的不计入
|
||||
completed += it[index].mileage
|
||||
}
|
||||
}
|
||||
val progress = "${((completed / sum) * 100.0).roundToInt()}%"
|
||||
setTaskProgress(progress)
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
/**
|
||||
* 结束主任务
|
||||
*/
|
||||
private fun endMainTask() {
|
||||
//结束任务
|
||||
val builder = SweeperNoTitleCommonDialog.Builder()
|
||||
val endConfirmDialog = builder
|
||||
.tips("是否结束任务?")
|
||||
.confirmStr("确认")
|
||||
.cancelStr("取消")
|
||||
.build(requireContext())
|
||||
endConfirmDialog?.setClickListener(object : SweeperNoTitleCommonDialog.ClickListener {
|
||||
override fun confirm() {
|
||||
mMainTask?.let {
|
||||
presenter?.mainTaskReset(it.mainTaskId)
|
||||
}
|
||||
}
|
||||
|
||||
override fun cancel() {
|
||||
endConfirmDialog?.dismiss()
|
||||
}
|
||||
})
|
||||
endConfirmDialog?.show()
|
||||
}
|
||||
|
||||
/**
|
||||
* 人工驾驶子任务
|
||||
*/
|
||||
private fun manualDriving(isCancelAutoPoilot: Boolean) {
|
||||
if (isCancelAutoPoilot) { // 人工子任务 先取消自动驾驶
|
||||
CallerAutoPilotStatusListenerManager.updateAutopilotControlParameters(null)
|
||||
CallerAutoPilotControlManager.cancelAutoPilot()
|
||||
}
|
||||
|
||||
mSubInfo?.apply {
|
||||
val builder = SweeperManualDrivingDialog.Builder()
|
||||
val endConfirmDialog = builder
|
||||
.tips("前方子任务${taskName}请人工驾驶至(${endSiteName})")
|
||||
.confirmStr("确认")
|
||||
.build(requireContext())
|
||||
endConfirmDialog?.setClickListener(object : SweeperManualDrivingDialog.ClickListener {
|
||||
override fun confirm() {
|
||||
presenter?.startTask(isFirstSubTask(), isLastSubTask(), taskId, mSubTaskType, taskStatus)
|
||||
val startPoint =
|
||||
CoordinateCalculateRouteUtil.coordinateConverterWgsToGcj(AbsMogoApplication.getApp(), startWgs84Lon, startWgs84Lat)
|
||||
val endPoint = CoordinateCalculateRouteUtil.coordinateConverterWgsToGcj(AbsMogoApplication.getApp(), endWgs84Lon, endWgs84Lat)
|
||||
startNaviToStation(
|
||||
true,
|
||||
startPoint.latitude,
|
||||
startPoint.longitude,
|
||||
endPoint.latitude,
|
||||
endPoint.longitude
|
||||
)
|
||||
showAmapNaviToStationFragment(true)
|
||||
}
|
||||
})
|
||||
endConfirmDialog?.show()
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 是否第一个子任务
|
||||
*/
|
||||
fun isFirstSubTask(): Boolean {
|
||||
return mCurrentSubPosition == 0
|
||||
}
|
||||
|
||||
/**
|
||||
* 是否最后一个子任务
|
||||
*/
|
||||
fun isLastSubTask(): Boolean {
|
||||
return mCurrentSubPosition == (mSubMutableList?.size?.minus(1))
|
||||
}
|
||||
|
||||
/**
|
||||
* 当前位置经纬度
|
||||
*/
|
||||
fun setCurrentLocation(location: MogoLocation) {
|
||||
this.mLocation = location
|
||||
}
|
||||
|
||||
override fun refreshNavi() {
|
||||
mSubInfo?.apply {
|
||||
mLocation?.let {
|
||||
val endPoint = CoordinateCalculateRouteUtil.coordinateConverterWgsToGcj(AbsMogoApplication.getApp(), endWgs84Lon, endWgs84Lat)
|
||||
startNaviToStation(true, it.latitude, it.longitude, endPoint.latitude, endPoint.longitude)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun addWeltData() {
|
||||
lifecycleScope.launch(Dispatchers.IO) {
|
||||
mSubMutableList?.let { subList ->
|
||||
if (subList.size <= 0) {
|
||||
return@launch
|
||||
}
|
||||
val dataList = ArrayList<LatLng>()
|
||||
for (index in subList.indices) {
|
||||
val startPoint = CoordinateCalculateRouteUtil.coordinateConverterWgsToGcj(
|
||||
AbsMogoApplication.getApp(),
|
||||
subList[index].startWgs84Lon,
|
||||
subList[index].startWgs84Lat
|
||||
)
|
||||
val startLatLng = LatLng(startPoint.latitude, startPoint.longitude)
|
||||
dataList.add(index,startLatLng)
|
||||
val endPoint = CoordinateCalculateRouteUtil.coordinateConverterWgsToGcj(
|
||||
AbsMogoApplication.getApp(),
|
||||
subList[index].endWgs84Lon,
|
||||
subList[index].endWgs84Lat
|
||||
)
|
||||
val endLatLng = LatLng(endPoint.latitude, endPoint.longitude)
|
||||
dataList.add(index+1,endLatLng)
|
||||
}
|
||||
setTaskListCoordinatesLatLng(dataList)
|
||||
setEndStationMarker()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun setEndStationMarker(){
|
||||
lifecycleScope.launch(Dispatchers.IO) {
|
||||
mSubInfo?.let {
|
||||
val endPoint = CoordinateCalculateRouteUtil.coordinateConverterWgsToGcj(
|
||||
AbsMogoApplication.getApp(),
|
||||
it.endWgs84Lon,
|
||||
it.endWgs84Lat
|
||||
)
|
||||
super.mCurrentTaskEndStation = endPoint
|
||||
setCurrentTaskEndMarker(endPoint)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
//模拟结束子任务
|
||||
override fun debugEndSubTask() {
|
||||
//mPresenter?.onArriveTaskEnd(null)
|
||||
super.debugEndSubTask()
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置路线轨迹
|
||||
*/
|
||||
override fun setTaskRouteList(routeList: ArrayList<SweeperRoutePlanningUpdateReqBean.Result>) {
|
||||
super.setTaskRouteList(routeList)
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,129 @@
|
||||
package com.mogo.och.sweeper.fragment
|
||||
|
||||
import android.os.Bundle
|
||||
import com.amap.api.maps.model.LatLng
|
||||
import com.mogo.commons.mvp.BaseFragment
|
||||
import com.mogo.och.sweeper.R
|
||||
import com.mogo.och.sweeper.bean.SweeperRoutePlanningUpdateReqBean
|
||||
import com.mogo.och.sweeper.callback.ISweeperTaskDataToFragmentCallback
|
||||
import com.mogo.och.sweeper.callback.IWeltMapSwitchToSmallCallback
|
||||
import com.mogo.och.sweeper.database.bean.WeltDataBean
|
||||
import kotlinx.android.synthetic.main.fragment_welt_map_overview.*
|
||||
import kotlinx.android.synthetic.main.sweeper_welt_map_overview.*
|
||||
|
||||
/**
|
||||
* 作业任务全览图
|
||||
*/
|
||||
class WeltMapOverViewFragment() : BaseFragment(), ISweeperTaskDataToFragmentCallback {
|
||||
private var mIWeltMapSwitchToSmallCallBack: IWeltMapSwitchToSmallCallback? = null
|
||||
private var mFragment: SweeperFragment? = null
|
||||
override fun getLayoutId(): Int = R.layout.fragment_welt_map_overview
|
||||
override fun getTagName(): String {
|
||||
return "WeltMapOverViewFragment"
|
||||
}
|
||||
|
||||
override fun initViews() {
|
||||
|
||||
}
|
||||
fun setWeltMapSwitchToSmallCallBack(iWeltMapSwitchToSmallCallback: IWeltMapSwitchToSmallCallback){
|
||||
this.mIWeltMapSwitchToSmallCallBack=iWeltMapSwitchToSmallCallback
|
||||
}
|
||||
fun setSweeperFragment(fragment: SweeperFragment){
|
||||
this.mFragment=fragment
|
||||
mFragment?.setTaskDataToFragmentCallback(this)
|
||||
}
|
||||
override fun initViews(savedInstanceState: Bundle?) {
|
||||
super.initViews(savedInstanceState)
|
||||
weltMapOverView.onCreateView(savedInstanceState)
|
||||
sweeperSwitchToSmall.setOnClickListener {
|
||||
mIWeltMapSwitchToSmallCallBack?.onWeltMapSwitchToSmall()
|
||||
}
|
||||
val bundle = arguments
|
||||
if (bundle != null) {
|
||||
val latLngs = bundle.getSerializable("subTaskCoordinates") as? ArrayList<LatLng>
|
||||
val latLng = bundle.getParcelable<LatLng>("subTaskEndCoordinates")
|
||||
val weltDataList = bundle.getSerializable("weltDataList") as? ArrayList<WeltDataBean>
|
||||
val routeList = bundle.getSerializable("routeList") as? ArrayList<SweeperRoutePlanningUpdateReqBean.Result>
|
||||
val progress = bundle.getString("progress")
|
||||
routeList?.let {
|
||||
weltMapOverView.setRouteList(it)
|
||||
}
|
||||
latLng?.let {
|
||||
setCurrentTaskCoordinatesLatLng(it)
|
||||
}
|
||||
latLngs?.let {
|
||||
setTaskListCoordinatesLatLng(it)
|
||||
}
|
||||
weltDataList?.let {
|
||||
setWeltData(it,"0.0")
|
||||
}
|
||||
progress?.let {
|
||||
weltMapOverView.setProgress(progress)
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
companion object {
|
||||
@JvmStatic
|
||||
fun newInstance(
|
||||
mIWeltMapSwitchToSmallCallBack: IWeltMapSwitchToSmallCallback,
|
||||
mCurrentTaskEndStation:LatLng?,
|
||||
weltDataList: ArrayList<WeltDataBean>?,
|
||||
latLngs: ArrayList<LatLng>?,
|
||||
routeList: ArrayList<SweeperRoutePlanningUpdateReqBean.Result>?,
|
||||
progress:String?,
|
||||
sweeperFragment: SweeperFragment
|
||||
): WeltMapOverViewFragment {
|
||||
val args = Bundle()
|
||||
args.putSerializable("weltDataList", weltDataList)
|
||||
args.putSerializable("subTaskCoordinates", latLngs)
|
||||
args.putParcelable("subTaskEndCoordinates", mCurrentTaskEndStation)
|
||||
args.putSerializable("routeList", routeList)
|
||||
args.putString("progress", progress)
|
||||
val fragment = WeltMapOverViewFragment()
|
||||
fragment.setWeltMapSwitchToSmallCallBack(mIWeltMapSwitchToSmallCallBack)
|
||||
fragment.setSweeperFragment(sweeperFragment)
|
||||
fragment.arguments = args
|
||||
return fragment
|
||||
}
|
||||
}
|
||||
|
||||
override fun onPause() {
|
||||
super.onPause()
|
||||
weltMapOverView.onPause()
|
||||
}
|
||||
|
||||
override fun onResume() {
|
||||
super.onResume()
|
||||
weltMapOverView.onResume()
|
||||
}
|
||||
|
||||
override fun onDestroy() {
|
||||
super.onDestroy()
|
||||
weltMapOverView.onDestroy()
|
||||
}
|
||||
override fun setTaskListCoordinatesLatLng(coordinatesLatLng: java.util.ArrayList<LatLng>) {
|
||||
weltMapOverView.setTaskListCoordinatesLatLng(coordinatesLatLng)
|
||||
}
|
||||
|
||||
override fun setCurrentTaskCoordinatesLatLng(coordinatesLatLng: LatLng) {
|
||||
weltMapOverView.setCurrentTaskCoordinatesLatLng(coordinatesLatLng)
|
||||
}
|
||||
|
||||
override fun clearAllMarkerAndPolyline() {
|
||||
weltMapOverView.clearAllMarkerAndPolyline()
|
||||
}
|
||||
|
||||
override fun setProgress(progress: String) {
|
||||
weltMapOverView.setProgress(progress)
|
||||
}
|
||||
|
||||
override fun setRouteList(routeList: java.util.ArrayList<SweeperRoutePlanningUpdateReqBean.Result>) {
|
||||
weltMapOverView.setRouteList(routeList)
|
||||
}
|
||||
|
||||
override fun setWeltData(weltDatas: java.util.ArrayList<WeltDataBean>?, distance: String) {
|
||||
weltMapOverView.setWeltData(weltDatas,true,distance)
|
||||
}
|
||||
}
|
||||
@@ -1,86 +0,0 @@
|
||||
package com.mogo.och.sweeper.model;
|
||||
|
||||
import android.content.Context;
|
||||
|
||||
import com.mogo.commons.AbsMogoApplication;
|
||||
import com.mogo.eagle.core.utilcode.util.NetworkUtils;
|
||||
import com.mogo.eagle.core.utilcode.util.ToastUtils;
|
||||
import com.mogo.och.sweeper.bean.SweeperQueryLinesResponse;
|
||||
import com.mogo.och.sweeper.bean.SweeperRoutesResponse;
|
||||
import com.mogo.och.sweeper.callback.ISweeperLinesCallback;
|
||||
import com.mogo.och.sweeper.net.SweeperServiceManager;
|
||||
import com.mogo.och.sweeper.net.ISweeperServiceCallback;
|
||||
|
||||
/**
|
||||
* @author: wangmingjun
|
||||
* @date: 2022/2/9
|
||||
*/
|
||||
public class SweeperLineModel {
|
||||
private static volatile SweeperLineModel sInstance;
|
||||
private Context mContext;
|
||||
private ISweeperLinesCallback mBusLinesCallback;
|
||||
public static SweeperLineModel getInstance() {
|
||||
if ( sInstance == null ) {
|
||||
synchronized ( SweeperLineModel.class ) {
|
||||
if ( sInstance == null ) {
|
||||
sInstance = new SweeperLineModel();
|
||||
}
|
||||
}
|
||||
}
|
||||
return sInstance;
|
||||
}
|
||||
private SweeperLineModel() {
|
||||
|
||||
}
|
||||
public void init() {
|
||||
mContext = AbsMogoApplication.getApp();
|
||||
}
|
||||
public void setBusLinesCallback(ISweeperLinesCallback callback){
|
||||
mBusLinesCallback = callback;
|
||||
}
|
||||
public void queryBusLines(){
|
||||
SweeperServiceManager.getInstance().queryBusLines(mContext, new ISweeperServiceCallback<SweeperQueryLinesResponse>() {
|
||||
@Override
|
||||
public void onSuccess(SweeperQueryLinesResponse data) {
|
||||
if (null == data && mBusLinesCallback != null) {
|
||||
mBusLinesCallback.onBusLinesChange(null);
|
||||
return;
|
||||
}
|
||||
|
||||
if (mBusLinesCallback != null){
|
||||
mBusLinesCallback.onBusLinesChange(data);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onFail(String failMsg) {
|
||||
if (!NetworkUtils.isConnected(mContext)) {
|
||||
ToastUtils.showShort("网络异常,请稍后重试");
|
||||
}else {
|
||||
ToastUtils.showShort("查询所有绑定路线失败:"+failMsg);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public void commitSwitchLineId(int lineId){
|
||||
SweeperServiceManager.getInstance().resetStationStatus(mContext,lineId, new ISweeperServiceCallback<SweeperRoutesResponse>() {
|
||||
@Override
|
||||
public void onSuccess(SweeperRoutesResponse o) {
|
||||
if (mBusLinesCallback != null){
|
||||
mBusLinesCallback.onChangeLineIdSuccess();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onFail(String failMsg) {
|
||||
if (!NetworkUtils.isConnected(mContext)) {
|
||||
ToastUtils.showShort("网络异常,请稍后重试");
|
||||
}else {
|
||||
ToastUtils.showShort("切换路线失败:"+failMsg);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,878 +0,0 @@
|
||||
package com.mogo.och.sweeper.model;
|
||||
|
||||
import static com.mogo.eagle.core.utilcode.mogo.logger.scene.SceneConstant.M_BUS;
|
||||
import static com.mogo.och.sweeper.constant.SweeperConst.STATION_STATUS_STOPPED;
|
||||
|
||||
import android.content.Context;
|
||||
import android.os.Handler;
|
||||
|
||||
import androidx.annotation.Nullable;
|
||||
|
||||
import com.amap.api.maps.model.LatLng;
|
||||
import com.elegant.network.utils.GsonUtil;
|
||||
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.commons.voice.AIAssist;
|
||||
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.data.map.MogoLocation;
|
||||
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.CallerChassisLocationGCJ02ListenerManager;
|
||||
import com.mogo.eagle.core.function.call.autopilot.CallerChassisLocationWGS84ListenerManager;
|
||||
import com.mogo.eagle.core.function.call.autopilot.CallerPlanningRottingListenerManager;
|
||||
import com.mogo.eagle.core.utilcode.mogo.logger.CallerLogger;
|
||||
import com.mogo.eagle.core.utilcode.mogo.logger.Logger;
|
||||
import com.mogo.eagle.core.utilcode.util.CoordinateUtils;
|
||||
import com.mogo.eagle.core.utilcode.util.NetworkUtils;
|
||||
import com.mogo.eagle.core.utilcode.util.ToastUtils;
|
||||
import com.mogo.och.common.module.utils.CoordinateCalculateRouteUtil;
|
||||
import com.mogo.och.sweeper.bean.QueryLeaveAwayPassengersResponse;
|
||||
import com.mogo.och.sweeper.bean.SweeperOperationStatusResponse;
|
||||
import com.mogo.och.sweeper.bean.SweeperRoutePlanningUpdateReqBean;
|
||||
import com.mogo.och.sweeper.bean.SweeperRoutesResponse;
|
||||
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.ISlidePannelHideCallback;
|
||||
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 com.mogo.och.sweeper.util.SweeperTrajectoryManager;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import io.reactivex.exceptions.UndeliverableException;
|
||||
import io.reactivex.functions.Consumer;
|
||||
import io.reactivex.plugins.RxJavaPlugins;
|
||||
import mogo.telematics.pad.MessagePad;
|
||||
|
||||
/**
|
||||
* @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 boolean mIsWorking = false;
|
||||
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 static final int VEHICLE_TYPE = 10;
|
||||
private static final int MSG_QUERY_BUS_STATION = 1001;
|
||||
private static final long QUERY_BUS_STATION_DELAY = 5000;
|
||||
|
||||
private ICarOperationStatusCallback carOperationStatusCallback;
|
||||
private IRefreshSweeperStationsCallback refreshBusStationsCallback;
|
||||
private ISlidePannelHideCallback slidePannelHideCallback;
|
||||
private ISweeperControllerStatusCallback mControllerStatusCallback; //Model->Presenter:VR mode等
|
||||
|
||||
List<SweeperRoutePlanningUpdateReqBean.Result> points = new ArrayList<>();//全路径信息
|
||||
|
||||
private boolean hadQueryLeaveAwayPassager = false;
|
||||
|
||||
private volatile boolean isArrivedStation = false;
|
||||
|
||||
private final Handler handler = new Handler(msg -> {
|
||||
if (msg.what == MSG_QUERY_BUS_STATION) {
|
||||
SweeperOrderModel.getInstance().querySweeperRoutes();
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
});
|
||||
|
||||
public static SweeperOrderModel getInstance() {
|
||||
if (sInstance == null) {
|
||||
synchronized (SweeperOrderModel.class) {
|
||||
if (sInstance == null) {
|
||||
sInstance = new SweeperOrderModel();
|
||||
}
|
||||
}
|
||||
}
|
||||
return sInstance;
|
||||
}
|
||||
|
||||
private SweeperOrderModel() {
|
||||
|
||||
}
|
||||
|
||||
public void init() {
|
||||
mContext = AbsMogoApplication.getApp();
|
||||
// 定位监听
|
||||
CallerChassisLocationGCJ02ListenerManager.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 setCarOperationStatusCallback(ICarOperationStatusCallback callback) {
|
||||
this.carOperationStatusCallback = callback;
|
||||
}
|
||||
|
||||
public void setRefreshBusStationsCallback(IRefreshSweeperStationsCallback callback) {
|
||||
this.refreshBusStationsCallback = callback;
|
||||
}
|
||||
|
||||
public void setSlidePannelHideCallback(ISlidePannelHideCallback callback) {
|
||||
this.slidePannelHideCallback = 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()));
|
||||
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);
|
||||
// 注销定位监听
|
||||
CallerChassisLocationGCJ02ListenerManager.INSTANCE.removeListener(TAG);
|
||||
|
||||
//自动驾驶路线规划接口
|
||||
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 MogoLocation 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(MogoLocation 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,
|
||||
CallerChassisLocationWGS84ListenerManager.INSTANCE.getChassisLocationWGS84().getLongitude(),
|
||||
CallerChassisLocationWGS84ListenerManager.INSTANCE.getChassisLocationWGS84().getLatitude());
|
||||
}
|
||||
|
||||
if (distance <= SweeperConst.ARRIVE_AT_END_STATION_DISTANCE) {
|
||||
onArriveAt(null); //无自动驾驶到站信息传null
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询小巴路线
|
||||
*/
|
||||
public void querySweeperRoutes() {
|
||||
CallerLogger.INSTANCE.d(M_BUS + TAG, "查询小巴路线");
|
||||
SweeperServiceManager.getInstance().queryBusRoutes(mContext, new ISweeperServiceCallback<SweeperRoutesResponse>() {
|
||||
@Override
|
||||
public void onSuccess(SweeperRoutesResponse data) {
|
||||
if (data == null
|
||||
|| data.getResult() == null
|
||||
|| data.getResult().getSites() == null
|
||||
|| data.getResult().getSites().isEmpty()) {
|
||||
return;
|
||||
}
|
||||
CallerLogger.INSTANCE.d(M_BUS + TAG, "获取到小巴路线数据: " + data);
|
||||
renderBusStationsStatus(data.getResult());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onFail(String failMsg) {
|
||||
// 重复请求小巴路线,直至成功
|
||||
queryBusStationDelay();
|
||||
}
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* 测试、重置站点状态
|
||||
*/
|
||||
public void debugResetStationStatus() {
|
||||
CallerLogger.INSTANCE.d(M_BUS + TAG, "测试、重置站点状态");
|
||||
SweeperServiceManager.getInstance().resetStationStatus(mContext, currentLineId
|
||||
, new ISweeperServiceCallback<SweeperRoutesResponse>() {
|
||||
@Override
|
||||
public void onSuccess(SweeperRoutesResponse o) {
|
||||
CallerLogger.INSTANCE.d(M_BUS + TAG, "获取到小巴路线数据: " + o);
|
||||
isGoingToNextStation = false;
|
||||
if (o.getResult() == null || o.getResult().getSites() == null || o.getResult().getSites().isEmpty()) {
|
||||
return;
|
||||
}
|
||||
renderBusStationsStatus(o.getResult());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onFail(String failMsg) {
|
||||
// 重复请求小巴路线,直至成功
|
||||
queryBusStationDelay();
|
||||
}
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* 离站上报
|
||||
*/
|
||||
public void leaveStation(boolean isOneWayOver, boolean isRestart) {
|
||||
CallerLogger.INSTANCE.d(M_BUS + TAG, "leaveStation-backgroundCurrentStationIndex = " + backgroundCurrentStationIndex);
|
||||
SweeperServiceManager.getInstance().leaveStation(mContext, stationList.get(backgroundCurrentStationIndex).getSeq()
|
||||
, stationList.get(backgroundCurrentStationIndex).getSiteId(), new ISweeperServiceCallback<SweeperRoutesResponse>() {
|
||||
@Override
|
||||
public void onSuccess(SweeperRoutesResponse o) {
|
||||
if (o.getResult() == null || o.getResult().getSites() == null || o.getResult().getSites().isEmpty()) {
|
||||
return;
|
||||
}
|
||||
isArrivedStation = false;
|
||||
if (!isOneWayOver) {
|
||||
CallerLogger.INSTANCE.d(M_BUS + TAG, "自动驾驶开启开往下一站====");
|
||||
//需要更改当前站和下一站的状态 然后渲染
|
||||
leaveStationSuccess(o.getResult(), isRestart);
|
||||
} else {
|
||||
CallerLogger.INSTANCE.d(M_BUS + TAG, "单程真的结束了====");
|
||||
isGoingToNextStation = false;
|
||||
backgroundCurrentStationIndex = 0;
|
||||
CallerAutoPilotControlManager.INSTANCE.cancelAutoPilot();
|
||||
querySweeperRoutes();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onFail(String failMsg) {
|
||||
if (!NetworkUtils.isConnected(mContext)) {
|
||||
ToastUtils.showShort("网络异常,请稍后重试");
|
||||
} else {
|
||||
ToastUtils.showShort("离站上报失败:" + failMsg);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* 离站上报成功后渲染站点
|
||||
* 服务端返回的OchBusRoutesResult逻辑, 离开站为当前站, 到达下一站后才会将下一站置为当前站,
|
||||
* 车机端展示是离开当前站,下一站设置为当前站, 所以服务端数据回来要做处理,不能直接渲染
|
||||
*/
|
||||
private void leaveStationSuccess(SweeperRoutesResult result, boolean isRestart) {
|
||||
renderBusStationsStatus(result);
|
||||
if (slidePannelHideCallback != null) {
|
||||
slidePannelHideCallback.hideSlidePanel();
|
||||
}
|
||||
//开启自动驾驶
|
||||
startAutopilot(isRestart);
|
||||
if (isGoingToNextStation) {
|
||||
// 为了避免恢复自动驾驶时重复的接口请求
|
||||
return;
|
||||
}
|
||||
isGoingToNextStation = true;
|
||||
AIAssist.getInstance(mContext).speakTTSVoice("欢迎乘坐’蘑菇车联‘无人驾驶小巴车,请您坐好,注意乘车安全,行程即将开始");
|
||||
}
|
||||
|
||||
/**
|
||||
* 开启自动驾驶
|
||||
*
|
||||
* @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));
|
||||
CallerAutoPilotControlManager.INSTANCE.startAutoPilot(parameters);
|
||||
|
||||
if (mControllerStatusCallback != null) {
|
||||
mControllerStatusCallback.startOpenAutopilot();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 到站后重置站点状态
|
||||
*/
|
||||
private void arriveSiteStation(boolean isRestart) {
|
||||
if (backgroundCurrentStationIndex + 1 > stationList.size() - 1) { //到站短时间内调用多次
|
||||
CallerLogger.INSTANCE.e(M_BUS + TAG, "数组越界");
|
||||
return;
|
||||
}
|
||||
int arrivedStationIndex = 0;
|
||||
if (!isRestart) {
|
||||
arrivedStationIndex = backgroundCurrentStationIndex + 1;
|
||||
}
|
||||
CallerLogger.INSTANCE.d(M_BUS + TAG, "arriveSiteStation-currentStationIndex = " + arrivedStationIndex);
|
||||
|
||||
SweeperServiceManager.getInstance().arriveSiteStation(mContext
|
||||
, stationList.get(arrivedStationIndex).getSeq(), stationList.get(arrivedStationIndex).getSiteId()
|
||||
, new ISweeperServiceCallback<BaseData>() {
|
||||
@Override
|
||||
public void onSuccess(BaseData o) {
|
||||
CallerLogger.INSTANCE.d(M_BUS + TAG, "arriveSiteStation success");
|
||||
if (!isRestart) {
|
||||
renderArriveBusStation();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onFail(String failMsg) {
|
||||
// if (!NetworkUtils.isConnected(mContext)) {
|
||||
// ToastUtils.showShort("网络异常,请稍后重试");
|
||||
// }else {
|
||||
// ToastUtils.showShort("离站上报失败:"+failMsg);
|
||||
// }
|
||||
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private void renderArriveBusStation() {
|
||||
List<SweeperStationBean> site = sweeperRoutesResult.getSites();
|
||||
if (site != null && site.size() > 0) {
|
||||
backgroundCurrentStationIndex++;
|
||||
if (refreshBusStationsCallback != null) {
|
||||
refreshBusStationsCallback.refreshBusStations(sweeperRoutesResult.getName(), stationList, backgroundCurrentStationIndex
|
||||
, getNextStopStation(), true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 收车
|
||||
*/
|
||||
public void stopTakeOrder() {
|
||||
SweeperServiceManager.getInstance().stopTakeOrder(mContext, new ISweeperServiceCallback<BaseData>() {
|
||||
@Override
|
||||
public void onSuccess(BaseData o) {
|
||||
mIsWorking = !mIsWorking;
|
||||
closeBeautificationMode();
|
||||
carOperationStatusCallback.changeOperationStatus(isWorking());
|
||||
startOrStopOrderLoop(mIsWorking);
|
||||
SweeperTrajectoryManager.getInstance().stopTrajReqLoop();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onFail(String failMsg) {
|
||||
if (!NetworkUtils.isConnected(mContext)) {
|
||||
ToastUtils.showShort("网络异常,请稍后重试");
|
||||
} else {
|
||||
ToastUtils.showShort("收车失败:" + failMsg);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* 关闭美化模式
|
||||
*/
|
||||
private void closeBeautificationMode() {
|
||||
if (FunctionBuildConfig.isDemoMode) {//收车结束美化
|
||||
FunctionBuildConfig.isIgnoreConditionsDrawAutopilotTrajectoryData = false;
|
||||
CallerAutoPilotControlManager.INSTANCE.setIPCDemoMode(false);
|
||||
CallerLogger.INSTANCE.d(M_BUS + TAG, "美化模式-ignore:置为false(收车)");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 出车
|
||||
*/
|
||||
public void startTakeOrder() {
|
||||
SweeperServiceManager.getInstance().startTakeOrder(mContext, new ISweeperServiceCallback<BaseData>() {
|
||||
@Override
|
||||
public void onSuccess(BaseData o) {
|
||||
mIsWorking = !mIsWorking;
|
||||
startOrStopOrderLoop(mIsWorking);
|
||||
if (stationList != null && stationList.size() > 0) {
|
||||
AIAssist.getInstance(mContext).speakTTSVoice("车辆已整备完毕,请前往"
|
||||
+ stationList.get(backgroundCurrentStationIndex).getName() + "站点");
|
||||
}
|
||||
carOperationStatusCallback.changeOperationStatus(isWorking());
|
||||
querySweeperRoutes();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onFail(String failMsg) {
|
||||
if (!NetworkUtils.isConnected(mContext)) {
|
||||
ToastUtils.showShort("网络异常,请稍后重试");
|
||||
} else {
|
||||
ToastUtils.showShort("出车失败:" + failMsg);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询运营状态
|
||||
*/
|
||||
public void queryOperationStatus() {
|
||||
CallerLogger.INSTANCE.d(M_BUS + TAG, "查询运营状态");
|
||||
SweeperServiceManager.getInstance().queryOperationStatus(mContext
|
||||
, new ISweeperServiceCallback<SweeperOperationStatusResponse>() {
|
||||
@Override
|
||||
public void onSuccess(SweeperOperationStatusResponse o) {
|
||||
if (o.data != null) {
|
||||
mIsWorking = o.data.serviceStatus == 1;
|
||||
CallerLogger.INSTANCE.d(M_BUS + TAG, "查询运营状态 result.status: " + o.data.serviceStatus);
|
||||
startOrStopOrderLoop(mIsWorking);
|
||||
}
|
||||
carOperationStatusCallback.changeOperationStatus(isWorking());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onFail(String failMsg) {
|
||||
if (!NetworkUtils.isConnected(mContext)) {
|
||||
ToastUtils.showShort("网络异常,请稍后重试");
|
||||
} else {
|
||||
ToastUtils.showShort("出车收车状态查询:" + failMsg);
|
||||
}
|
||||
// queryOperationStatus();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* 开启自动驾驶到下一站
|
||||
*/
|
||||
public void autoDriveToNextStation(boolean isRestart) {
|
||||
// if ( backgroundCurrentStationIndex >= stationList.size() - 1 ) {
|
||||
// // 当前站是最后一站,结束当前行程
|
||||
// travelOver();
|
||||
// return;
|
||||
// }
|
||||
// leaveStation(false,isRestart);
|
||||
startAutopilot(isRestart);
|
||||
}
|
||||
|
||||
/**
|
||||
* 渲染站点信息
|
||||
* 服务端返回的OchBusRoutesResult逻辑, 离开站为当前站, 到达下一站后才会将下一站置为当前站,
|
||||
* 车机端展示 离开站为当前站点,前往站为下一站, 下一站到站后在置为当前站
|
||||
*
|
||||
* @param result
|
||||
*/
|
||||
private void renderBusStationsStatus(SweeperRoutesResult result) {
|
||||
if (result == null) return;
|
||||
sweeperRoutesResult = result;
|
||||
List<SweeperStationBean> site = result.getSites();
|
||||
currentLineId = result.getLineId();
|
||||
stationList.clear();
|
||||
stationList.addAll(site);
|
||||
for (int i = 0; i < stationList.size(); i++) {
|
||||
SweeperStationBean s = stationList.get(i);
|
||||
|
||||
CallerLogger.INSTANCE.d(M_BUS + "renderBusStationsStatus--",
|
||||
"Index=" + i + " ,name = " + s.getName() + " ," + s.isLeaving() + "," + s.getDrivingStatus());
|
||||
|
||||
// 是否正在开往下一站
|
||||
if (s.isLeaving()) {
|
||||
isGoingToNextStation = true;
|
||||
}
|
||||
// 当前站点信息
|
||||
if (s.getDrivingStatus() == STATION_STATUS_STOPPED) {
|
||||
backgroundCurrentStationIndex = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
SweeperStationBean currentStation = stationList.get(backgroundCurrentStationIndex);
|
||||
|
||||
CallerLogger.INSTANCE.d(M_BUS + TAG,
|
||||
"渲染站点信息服务端currentStationIndex=" + backgroundCurrentStationIndex
|
||||
+ " isLeaving()=" + currentStation.isLeaving());
|
||||
|
||||
//当前站点是始发站,告诉服务端到达始发站。 如果没有这个节点, 服务器不知道始发站到达状态
|
||||
// ,订单开始站下在始发站的状态流转有问题
|
||||
if (backgroundCurrentStationIndex == 0 && !currentStation.isLeaving()) {
|
||||
arriveSiteStation(true);
|
||||
}
|
||||
|
||||
// 美化是否开始
|
||||
if (FunctionBuildConfig.isDemoMode && (backgroundCurrentStationIndex >= 0
|
||||
&& backgroundCurrentStationIndex <= stationList.size() - 1)
|
||||
&& stationList.get(backgroundCurrentStationIndex).isLeaving()) {//行驶过程中设置美化
|
||||
FunctionBuildConfig.isIgnoreConditionsDrawAutopilotTrajectoryData = true;
|
||||
CallerAutoPilotControlManager.INSTANCE.setIPCDemoMode(true);
|
||||
CallerLogger.INSTANCE.d(M_BUS + TAG, "美化模式-ignore:置为true(每次滑动出发)");
|
||||
}
|
||||
|
||||
if (refreshBusStationsCallback != null) {
|
||||
refreshBusStationsCallback.refreshBusStations(result.getName(), stationList
|
||||
, backgroundCurrentStationIndex, getNextStopStation(), !currentStation.isLeaving());
|
||||
}
|
||||
|
||||
if (currentStation.isLeaving() && slidePannelHideCallback != null) {
|
||||
slidePannelHideCallback.hideSlidePanel();
|
||||
}
|
||||
|
||||
//需放在currentStationIndex赋值之后
|
||||
SweeperTrajectoryManager.getInstance().syncTrajectoryInfo();
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据订单状态、获取下一站靠站的的站点
|
||||
*
|
||||
* @return -1 当前已是最后一个站点
|
||||
*/
|
||||
private int getNextStopStation() {
|
||||
if (backgroundCurrentStationIndex >= stationList.size() - 1) {
|
||||
return -1;
|
||||
}
|
||||
int nextStationIndex = backgroundCurrentStationIndex + 1;
|
||||
for (; nextStationIndex < stationList.size() - 1; nextStationIndex++) {
|
||||
if (stationList.get(nextStationIndex).getIfStop() == 1) {
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
return nextStationIndex;
|
||||
}
|
||||
|
||||
/**
|
||||
* 延时查询站点信心
|
||||
*/
|
||||
private void queryBusStationDelay() {
|
||||
handler.sendEmptyMessageDelayed(MSG_QUERY_BUS_STATION, QUERY_BUS_STATION_DELAY);
|
||||
}
|
||||
|
||||
/**
|
||||
* 在踩刹车、控制方向盘等操作后,会停止自动驾驶,重启自动驾驶的话相当于重新设置自动驾驶目的地
|
||||
*/
|
||||
public void restartAutopilot() {
|
||||
// CallerLogger.INSTANCE.d( M_BUS + TAG, "重启自动驾驶===" + isGoingToNextStation );
|
||||
// autoDriveToNextStation( true );
|
||||
//直接开启自动驾驶
|
||||
startAutopilot(true);
|
||||
}
|
||||
|
||||
/**
|
||||
* 播报下车乘客信息
|
||||
*
|
||||
* @param awayPassengersResponse
|
||||
*/
|
||||
private void playLeavePassengersMsg(QueryLeaveAwayPassengersResponse awayPassengersResponse) {
|
||||
CallerLogger.INSTANCE.d(M_BUS + TAG, "播报下车乘客信息currentStationIndex="
|
||||
+ String.valueOf(backgroundCurrentStationIndex + 1));
|
||||
|
||||
if (backgroundCurrentStationIndex + 1 > stationList.size() - 1) {
|
||||
return;
|
||||
}
|
||||
String station = stationList.get(backgroundCurrentStationIndex + 1).getName();
|
||||
StringBuilder builder = new StringBuilder("已到达");
|
||||
builder.append(station);
|
||||
if (!station.endsWith("站")) {
|
||||
builder.append("站");
|
||||
}
|
||||
if (awayPassengersResponse == null || awayPassengersResponse.data == null
|
||||
|| awayPassengersResponse.data.orders == null || awayPassengersResponse.data.orders.isEmpty()) {
|
||||
CallerLogger.INSTANCE.d(M_BUS + TAG, "播报下车乘客信息为null");
|
||||
} else {
|
||||
builder.append(",请尾号为 ");
|
||||
for (QueryLeaveAwayPassengersResponse.LeaveAwayPassenger leaveAwayPassenger : awayPassengersResponse.data.orders) {
|
||||
if (leaveAwayPassenger == null) {
|
||||
continue;
|
||||
}
|
||||
String tailNum = null;
|
||||
try {
|
||||
tailNum = leaveAwayPassenger.passengerPhone.substring(leaveAwayPassenger.passengerPhone.length() - 4);
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
tailNum = leaveAwayPassenger.passengerPhone;
|
||||
}
|
||||
builder.append(tailNum).append("。");
|
||||
}
|
||||
builder.append("的乘客下车");
|
||||
}
|
||||
builder.append(",带好随身物品,下车请注意安全");
|
||||
CallerLogger.INSTANCE.d(M_BUS + TAG, "TTS:" + builder.toString());
|
||||
AIAssist.getInstance(mContext).speakTTSVoice(builder.toString());
|
||||
}
|
||||
|
||||
/**
|
||||
* 修改小巴运营状态
|
||||
*/
|
||||
public void onChangeOperationStatus() {
|
||||
CallerLogger.INSTANCE.d(M_BUS + TAG, "修改小巴运营状态");
|
||||
if (isWorking()) {//收车
|
||||
stopTakeOrder();
|
||||
} else {//出车
|
||||
startTakeOrder();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 行程结束
|
||||
*/
|
||||
private void travelOver() {
|
||||
|
||||
if (backgroundCurrentStationIndex >= stationList.size()) {
|
||||
CallerLogger.INSTANCE.e(M_BUS + TAG, "travel over index out of station list");
|
||||
return;
|
||||
}
|
||||
CallerLogger.INSTANCE.d(M_BUS + TAG, "单程结束====");
|
||||
CallerAutoPilotControlManager.INSTANCE.cancelAutoPilot();
|
||||
AIAssist.getInstance(mContext).speakTTSVoice("感谢您体验'蘑菇车联'无人驾驶小巴车,请您携带好随身物品,我们下次再见");
|
||||
leaveStation(true, true);
|
||||
}
|
||||
|
||||
public boolean isWorking() {
|
||||
return mIsWorking;
|
||||
}
|
||||
|
||||
/**
|
||||
* 到站
|
||||
*
|
||||
* @param data
|
||||
*/
|
||||
public void onArriveAt(MessagePad.ArrivalNotification data) {
|
||||
// if ( backgroundCurrentStationIndex +1 > stationList.size() - 1 ) {
|
||||
// CallerLogger.INSTANCE.e( M_BUS + TAG, "到站异常,取消后续操作结束" );
|
||||
// return;
|
||||
// }
|
||||
|
||||
if (isArrivedStation) return;
|
||||
isArrivedStation = true;
|
||||
|
||||
if (FunctionBuildConfig.isDemoMode && backgroundCurrentStationIndex <= stationList.size() - 1) {//到达一站结束美化
|
||||
FunctionBuildConfig.isIgnoreConditionsDrawAutopilotTrajectoryData = false;
|
||||
CallerAutoPilotControlManager.INSTANCE.setIPCDemoMode(false);
|
||||
CallerLogger.INSTANCE.d(M_BUS + TAG, "美化模式-ignore:置为false(到最后一站)");
|
||||
}
|
||||
CallerLogger.INSTANCE.d(M_BUS + TAG, "到站====currentStationIndex=" + backgroundCurrentStationIndex);
|
||||
isGoingToNextStation = false;
|
||||
|
||||
// arriveSiteStation(false);//到站上报
|
||||
}
|
||||
|
||||
public boolean isGoingToNextStation() {
|
||||
return isGoingToNextStation;
|
||||
}
|
||||
|
||||
// 车机端上传心跳数据(只在出车状态时上传)
|
||||
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;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,903 @@
|
||||
package com.mogo.och.sweeper.model;
|
||||
|
||||
import static com.mogo.eagle.core.utilcode.mogo.logger.scene.SceneConstant.M_SWEEPER;
|
||||
|
||||
import android.content.Context;
|
||||
import android.util.Log;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
|
||||
import com.amap.api.maps.model.LatLng;
|
||||
import com.elegant.network.utils.GsonUtil;
|
||||
import com.mogo.aicloud.services.socket.IMogoOnMessageListener;
|
||||
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.data.map.MogoLocation;
|
||||
import com.mogo.eagle.core.function.api.autopilot.IMoGoAutopilotStatusListener;
|
||||
import com.mogo.eagle.core.function.api.autopilot.IMoGoChassisLocationGCJ02Listener;
|
||||
import com.mogo.eagle.core.function.api.autopilot.IMoGoPlanningRottingListener;
|
||||
import com.mogo.eagle.core.function.call.autopilot.CallerAutoPilotControlManager;
|
||||
import com.mogo.eagle.core.function.call.autopilot.CallerAutoPilotStatusListenerManager;
|
||||
import com.mogo.eagle.core.function.call.autopilot.CallerChassisLocationGCJ02ListenerManager;
|
||||
import com.mogo.eagle.core.function.call.autopilot.CallerPlanningRottingListenerManager;
|
||||
import com.mogo.eagle.core.utilcode.mogo.logger.CallerLogger;
|
||||
import com.mogo.eagle.core.utilcode.util.CoordinateUtils;
|
||||
import com.mogo.eagle.core.utilcode.util.NetworkUtils;
|
||||
import com.mogo.eagle.core.utilcode.util.ToastUtils;
|
||||
import com.mogo.och.common.module.biz.common.socketmessage.OCHSocketMessageManager;
|
||||
import com.mogo.och.common.module.biz.common.socketmessage.data.OCHOperationalMessage;
|
||||
import com.mogo.och.common.module.biz.network.OchCommonServiceCallback;
|
||||
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.common.module.utils.ToastUtilsOch;
|
||||
import com.mogo.och.common.module.voice.VoiceNotice;
|
||||
import com.mogo.och.sweeper.R;
|
||||
import com.mogo.och.sweeper.bean.BaseResponse;
|
||||
import com.mogo.och.sweeper.bean.SubInfo;
|
||||
import com.mogo.och.sweeper.bean.SweeperMainTaskBean;
|
||||
import com.mogo.och.sweeper.bean.SweeperRoutePlanningUpdateReqBean;
|
||||
import com.mogo.och.sweeper.bean.SweeperSubTaskBean;
|
||||
import com.mogo.och.sweeper.bean.SweeperSubTaskDetailBean;
|
||||
import com.mogo.och.sweeper.callback.ISweeperADASStatusCallback;
|
||||
import com.mogo.och.sweeper.callback.ISweeperControllerStatusCallback;
|
||||
import com.mogo.och.sweeper.callback.ISweeperTaskCallback;
|
||||
import com.mogo.och.sweeper.constant.SubTaskTypeEnum;
|
||||
import com.mogo.och.sweeper.constant.SweeperConst;
|
||||
import com.mogo.och.sweeper.constant.TaskStatusEnum;
|
||||
import com.mogo.och.sweeper.net.SweeperServiceManager;
|
||||
import com.mogo.och.sweeper.util.SweeperAnalyticsManager;
|
||||
import com.mogo.och.sweeper.util.SweeperTrajectoryManager;
|
||||
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import io.reactivex.exceptions.UndeliverableException;
|
||||
import io.reactivex.functions.Consumer;
|
||||
import io.reactivex.plugins.RxJavaPlugins;
|
||||
import mogo.telematics.pad.MessagePad;
|
||||
|
||||
/**
|
||||
* @author congtaowang
|
||||
* @since 2021/3/23
|
||||
* <p>
|
||||
* 清扫车任务管理
|
||||
*/
|
||||
public class SweeperTaskModel {
|
||||
private final String TAG = SweeperTaskModel.class.getSimpleName();
|
||||
private static volatile SweeperTaskModel sInstance;
|
||||
public double mLongitude = 0;
|
||||
public double mLatitude = 0;
|
||||
private Context mContext;
|
||||
// 运营类型
|
||||
private static final int VEHICLE_TYPE = 10;
|
||||
private ISweeperControllerStatusCallback mControllerStatusCallback; //Model->Presenter:VR mode等
|
||||
private ISweeperADASStatusCallback mADASStatusCallback;
|
||||
private ISweeperTaskCallback mSweeperTaskCallback;
|
||||
ArrayList<SweeperRoutePlanningUpdateReqBean.Result> points = new ArrayList<>();//全路径信息
|
||||
//当前子任务详情信息包括轨迹文件信息
|
||||
private SweeperSubTaskDetailBean mCurrentSubTaskDetail;
|
||||
//子任务是否正在进行中
|
||||
private boolean mIsSubTaskWorking = false;
|
||||
//自动驾驶是否到达子任务终点
|
||||
private boolean isAutopilotSubTaskArriveEndSite = false;
|
||||
//当前子任务id
|
||||
private int mSubTaskId = 0;
|
||||
//当前是否最后一个子任务
|
||||
private boolean mIsLastSubtask = false;
|
||||
//当前任务是否是第一个
|
||||
private boolean mIsFirstSubtask = false;
|
||||
//当前任务是否是第一个
|
||||
private int mSubTaskType = 0; //1自动驾驶 2.人工驾驶
|
||||
//0: 代表没有启动过 1代表是启动第一次,当>=1 代表是重试 每次子任务结束/主任务结束清空置为0
|
||||
private volatile int firstStartAutopilot = 0;
|
||||
private int mLineId;//路线id
|
||||
//自动驾驶状态
|
||||
private int mAutopilotState = IMoGoAutopilotStatusListener.STATUS_AUTOPILOT_DISABLE;
|
||||
|
||||
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();
|
||||
// 定位监听
|
||||
CallerChassisLocationGCJ02ListenerManager.INSTANCE.addListener(TAG, mMapLocationListener);
|
||||
|
||||
MogoStatusManager.getInstance().registerStatusChangedListener(TAG, StatusDescriptor.VR_MODE, mMogoStatusChangedListener);
|
||||
|
||||
//自动驾驶路线规划接口
|
||||
CallerPlanningRottingListenerManager.INSTANCE.addListener(TAG, moGoAutopilotPlanningListener);
|
||||
|
||||
//开启自驾后 异常信息返回
|
||||
OCHAdasAbilityManager.getInstance().setAdasStartFailureCallback(mAdasStartFailureListener);
|
||||
|
||||
OCHSocketMessageManager.INSTANCE.registerSocketMessageListener(
|
||||
OCHSocketMessageManager.msgMonitorType,
|
||||
mMogoOnMessageListener);
|
||||
|
||||
//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_SWEEPER + TAG, "UndeliverableException");
|
||||
}
|
||||
if ((e instanceof IOException)) {//
|
||||
// fine, irrelevant network problem or API that throws on cancellation
|
||||
CallerLogger.INSTANCE.d(M_SWEEPER + TAG, "IOException");
|
||||
return;
|
||||
}
|
||||
if (e instanceof InterruptedException) {
|
||||
// fine, some blocking code was interrupted by a dispose call
|
||||
CallerLogger.INSTANCE.d(M_SWEEPER + TAG, "InterruptedException");
|
||||
return;
|
||||
}
|
||||
if ((e instanceof NullPointerException) || (e instanceof IllegalArgumentException)) {
|
||||
// that's likely a bug in the application
|
||||
CallerLogger.INSTANCE.d(M_SWEEPER + 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_SWEEPER + TAG, "IllegalStateException");
|
||||
Thread.currentThread().getUncaughtExceptionHandler().uncaughtException(Thread.currentThread(), e);
|
||||
return;
|
||||
}
|
||||
CallerLogger.INSTANCE.d(M_SWEEPER + TAG, "Undeliverable exception");
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public void setAdasStatusCallback(ISweeperADASStatusCallback callback) {
|
||||
this.mADASStatusCallback = callback;
|
||||
}
|
||||
|
||||
public void setControllerStatusCallback(ISweeperControllerStatusCallback callback) {
|
||||
this.mControllerStatusCallback = callback;
|
||||
}
|
||||
|
||||
public void setSweeperTaskCallback(ISweeperTaskCallback callback) {
|
||||
this.mSweeperTaskCallback = callback;
|
||||
}
|
||||
|
||||
private final IMoGoPlanningRottingListener moGoAutopilotPlanningListener = new IMoGoPlanningRottingListener() {
|
||||
|
||||
@Override
|
||||
public void onAutopilotRotting(MessagePad.GlobalPathResp routeList) {
|
||||
if (null != routeList && routeList.getWayPointsList()!=null&&routeList.getWayPointsList().size() > 0) {
|
||||
if (mCurrentSubTaskDetail.getLineId() != mLineId) {//判断是否同一条路线
|
||||
mLineId = mCurrentSubTaskDetail.getLineId();
|
||||
points.addAll(coordinateConverterWgsToGcjList(mContext, routeList.getWayPointsList()));
|
||||
if (mSweeperTaskCallback != null) {
|
||||
mSweeperTaskCallback.setRouteList(points);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
public void setSubtask(boolean isFirstSubtask, boolean isLastSubtask, int subTaskId, int subTaskType) {
|
||||
this.mIsLastSubtask = isLastSubtask;
|
||||
this.mIsFirstSubtask = isFirstSubtask;
|
||||
this.mSubTaskId = subTaskId;
|
||||
this.mSubTaskType = subTaskType;
|
||||
}
|
||||
|
||||
/**
|
||||
* 清除路线缓存数据
|
||||
*/
|
||||
public void clearRouteList() {
|
||||
points.clear();
|
||||
mSubTaskType=0;
|
||||
}
|
||||
|
||||
/**
|
||||
* 保存自动驾驶状态
|
||||
*
|
||||
* @param autopilotState
|
||||
*/
|
||||
public void setAutopilotState(int autopilotState) {
|
||||
this.mAutopilotState = autopilotState;
|
||||
}
|
||||
|
||||
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);
|
||||
// 注销定位监听
|
||||
CallerChassisLocationGCJ02ListenerManager.INSTANCE.removeListener(TAG);
|
||||
//自动驾驶路线规划接口
|
||||
CallerPlanningRottingListenerManager.INSTANCE.removeListener(moGoAutopilotPlanningListener);
|
||||
OCHAdasAbilityManager.getInstance().setAdasStartFailureCallback(null);
|
||||
}
|
||||
|
||||
private Object readResolve() {
|
||||
// 阻止反序列化,必须实现 Serializable 接口
|
||||
return sInstance;
|
||||
}
|
||||
|
||||
private final IMogoOnMessageListener<OCHOperationalMessage> mMogoOnMessageListener =
|
||||
new IMogoOnMessageListener<OCHOperationalMessage>() {
|
||||
@Override
|
||||
public Class<OCHOperationalMessage> target() {
|
||||
return OCHOperationalMessage.class;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onMsgReceived(OCHOperationalMessage obj) {
|
||||
if (obj == null) {
|
||||
CallerLogger.INSTANCE.d(M_SWEEPER + TAG, "onMsgReceived = null");
|
||||
return;
|
||||
}
|
||||
CallerLogger.INSTANCE.d(M_SWEEPER + TAG, "onMsgReceived = " + obj.getMessage());
|
||||
OCHSocketMessageManager.INSTANCE.pushAppOperationalMsgBox(obj.getPushTimeStamp(),
|
||||
obj.getMessage());
|
||||
}
|
||||
};
|
||||
|
||||
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_SWEEPER + TAG, "mAdasStartFailureListener = " + startFailedMessage);
|
||||
mADASStatusCallback.onStartAdasFailure();
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
// 自车定位
|
||||
private final IMoGoChassisLocationGCJ02Listener mMapLocationListener = new IMoGoChassisLocationGCJ02Listener() {
|
||||
@Override
|
||||
public void onChassisLocationGCJ02(@Nullable MogoLocation gnssInfo) {
|
||||
if (null == gnssInfo) return;
|
||||
Log.d(M_SWEEPER + TAG, "高德定位到站:mLongitude = " + gnssInfo.getLongitude()
|
||||
+ ", mLatitude=" + gnssInfo.getLatitude() + ", mSubTaskType=" + mSubTaskType + ", mIsSubTaskWorking=" + mIsSubTaskWorking
|
||||
+ ", isAutopilotSubTaskArriveEndSite=" + isAutopilotSubTaskArriveEndSite
|
||||
);
|
||||
CallerLogger.INSTANCE.e(M_SWEEPER + TAG, "高德定位到站:mLongitude = " + gnssInfo.getLongitude()
|
||||
+ ", mLatitude=" + gnssInfo.getLatitude() + ", mSubTaskType=" + mSubTaskType +", mIsSubTaskWorking=" + mIsSubTaskWorking
|
||||
+ ", isAutopilotSubTaskArriveEndSite=" + isAutopilotSubTaskArriveEndSite
|
||||
);
|
||||
if (mControllerStatusCallback != null) {
|
||||
mControllerStatusCallback.onCarLocationChanged(gnssInfo);
|
||||
}
|
||||
if (SubTaskTypeEnum.MANUAL_DRIVING_SUBTYPE.getCode() == mSubTaskType) {//人工驾驶子任务需要手动跳过,不能自动结束
|
||||
addCoordinates(gnssInfo);
|
||||
return;
|
||||
}
|
||||
//子任务完成的围栏判断 子任务正在执行中,还未到达子任务终点
|
||||
if (mIsSubTaskWorking && !isAutopilotSubTaskArriveEndSite) {
|
||||
judgeArrivedStation(gnssInfo);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* 根据当前定位收集人工驾驶子任务轨迹点
|
||||
*
|
||||
* @param mogoLatLng
|
||||
*/
|
||||
private void addCoordinates(MogoLocation mogoLatLng) {
|
||||
String tempLongitude = NumberFormatUtil.cutOutNumber(mogoLatLng.getLongitude(), 5);
|
||||
String tempLatitude = NumberFormatUtil.cutOutNumber(mogoLatLng.getLatitude(), 5);
|
||||
//用于过滤车是否停在原地,经纬度相同的情况
|
||||
if (!tempLongitude.equals(mLongitude) && !tempLatitude.equals(mLatitude)) {
|
||||
mLongitude = mogoLatLng.getLongitude();
|
||||
mLatitude = mogoLatLng.getLatitude();
|
||||
SweeperRoutePlanningUpdateReqBean.Result result = new SweeperRoutePlanningUpdateReqBean.Result();
|
||||
result.latitude = mogoLatLng.getLatitude();
|
||||
result.longitude = mogoLatLng.getLongitude();
|
||||
points.add(result);
|
||||
if (mSweeperTaskCallback != null) {
|
||||
mSweeperTaskCallback.setRouteList(points);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//根据围栏判断,是否到达子任务终点
|
||||
private void judgeArrivedStation(MogoLocation location) {
|
||||
if (mCurrentSubTaskDetail == null) {
|
||||
Log.d(TAG, "行程日志-judgeArrivedStation() mCurrentSubTaskDetail is null");
|
||||
CallerLogger.INSTANCE.d(TAG, "行程日志-judgeArrivedStation() mCurrentSubTaskDetail is null");
|
||||
return;
|
||||
}
|
||||
double endSiteLon = mCurrentSubTaskDetail.getEndSiteLon();
|
||||
double endSiteLat = mCurrentSubTaskDetail.getEndSiteLat();
|
||||
double distance = CoordinateUtils.calculateLineDistance(
|
||||
endSiteLon, endSiteLat,
|
||||
location.getLongitude(), location.getLatitude());
|
||||
if (distance <= SweeperConst.ARRIVE_AT_END_STATION_DISTANCE) {
|
||||
CallerLogger.INSTANCE.d(M_SWEEPER + TAG, "行程日志-judgeArrivedStation() distance = " + distance
|
||||
+ " to " + mCurrentSubTaskDetail.getEndSiteName());
|
||||
Log.d(TAG, "行程日志-judgeArrivedStation() distance = " + distance
|
||||
+ " to " + mCurrentSubTaskDetail.getEndSiteName());
|
||||
isAutopilotSubTaskArriveEndSite = true;
|
||||
//到达子任务终点 结束子任务
|
||||
subTaskEnd(mIsFirstSubtask, mIsLastSubtask, mSubTaskId); //无自动驾驶到终点信息传null
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 在踩刹车、控制方向盘等操作后,会停止自动驾驶,重启自动驾驶的话相当于重新设置自动驾驶目的地
|
||||
*/
|
||||
public void startAutopilot() {
|
||||
CallerLogger.INSTANCE.d(M_SWEEPER + TAG, "行程日志-重启自动驾驶===" + mIsSubTaskWorking);
|
||||
//只去启动自动驾驶
|
||||
startAutopilot(firstStartAutopilot >= 1);
|
||||
}
|
||||
|
||||
/**
|
||||
* 开启自动驾驶
|
||||
*
|
||||
* @param isRestart
|
||||
*/
|
||||
private void startAutopilot(boolean isRestart) {
|
||||
if (!FunctionBuildConfig.isDemoMode && !OCHAdasAbilityManager.getInstance().getAutopilotAbilityStatus()) {
|
||||
ToastUtils.showLong(OCHAdasAbilityManager.getInstance().getAutopilotUnAbilityReason() +
|
||||
", 请稍候重试");
|
||||
triggerUnableStartAPReasonEvent();
|
||||
return;
|
||||
}
|
||||
firstStartAutopilot++;
|
||||
triggerStartServiceEvent(isRestart, false);
|
||||
AutopilotControlParameters parameters = initAutopilotControlParameters();
|
||||
if (null == parameters) {
|
||||
CallerLogger.INSTANCE.e(M_SWEEPER + TAG, "行程日志-AutopilotControlParameters is empty.");
|
||||
return;
|
||||
}
|
||||
CallerAutoPilotControlManager.INSTANCE.startAutoPilot(parameters);
|
||||
CallerLogger.INSTANCE.d(M_SWEEPER + TAG, "行程日志-开启自动驾驶====" + GsonUtil.jsonFromObject(parameters)
|
||||
+ " startLatLon=" + parameters.startName + ",endLatLon=" + parameters.endName +
|
||||
"isRestart = " + isRestart);
|
||||
|
||||
if (mControllerStatusCallback != null) {
|
||||
mControllerStatusCallback.startOpenAutopilot();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取任务子任务执行状态
|
||||
*/
|
||||
public boolean getSubWorking() {
|
||||
return mIsSubTaskWorking;
|
||||
}
|
||||
|
||||
public void setWorking(Boolean isWorking) {
|
||||
this.mIsSubTaskWorking = isWorking;
|
||||
}
|
||||
|
||||
/**
|
||||
* 关闭美化模式
|
||||
*/
|
||||
public void closeBeautificationMode() {
|
||||
if (FunctionBuildConfig.isDemoMode) {
|
||||
FunctionBuildConfig.isIgnoreConditionsDrawAutopilotTrajectoryData = false; //是否强制绘制引导线
|
||||
CallerAutoPilotControlManager.INSTANCE.setIPCDemoMode(false);//是否自动启动自驾
|
||||
CallerLogger.INSTANCE.d(M_SWEEPER + TAG, "美化模式-ignore:置为false");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 开启美化模式
|
||||
*/
|
||||
public void startBeautificationMode() {
|
||||
FunctionBuildConfig.isIgnoreConditionsDrawAutopilotTrajectoryData = true;//是否强制绘制引导线
|
||||
CallerAutoPilotControlManager.INSTANCE.setIPCDemoMode(true);//是否自动启动自驾
|
||||
CallerLogger.INSTANCE.d(M_SWEEPER + TAG, "美化模式-ignore:置为true");
|
||||
}
|
||||
|
||||
/**
|
||||
* @param data
|
||||
*/
|
||||
public void onArriveTaskEnd(MessagePad.ArrivalNotification data) {
|
||||
//MAP 280 每隔100ms左右返回一次到站, 导致在到达中间站后再次滑动出发后会有时间差,收到一次到站,出现问题
|
||||
//此处比对 自驾告诉的子任务终点坐标和本地应到子任务终点坐标, 一致时才表示子任务完成
|
||||
if (data != null && data.getEndLocation() != null && mCurrentSubTaskDetail != null) {
|
||||
Log.d(M_SWEEPER + TAG, "MAP到站通知:" + mCurrentSubTaskDetail.getEndSiteName() + " 经度:"
|
||||
+ data.getEndLocation().getLongitude() + " 纬度:" + data.getEndLocation().getLatitude());
|
||||
CallerLogger.INSTANCE.d(M_SWEEPER + TAG, "MAP到站通知:" + mCurrentSubTaskDetail.getEndSiteName() + " 经度:"
|
||||
+ data.getEndLocation().getLongitude() + " 纬度:" + data.getEndLocation().getLatitude());
|
||||
String latitude = NumberFormatUtil.cutOutNumber(data.getEndLocation().getLatitude(), 5); //wgs
|
||||
String longitude = NumberFormatUtil.cutOutNumber(data.getEndLocation().getLongitude(), 5);
|
||||
String arriveLat = NumberFormatUtil.cutOutNumber(mCurrentSubTaskDetail.getEndSiteWgs64Lat(), 5);
|
||||
String arriveLon = NumberFormatUtil.cutOutNumber(mCurrentSubTaskDetail.getEndSiteWgs64Lon(), 5);
|
||||
if (!latitude.equals(arriveLat) || !longitude.equals(arriveLon)) {
|
||||
CallerLogger.INSTANCE.e(M_SWEEPER + TAG, "行程日志-子任务终点拦截,自动子任务终点与本地子任务终点不一致");
|
||||
return;
|
||||
}
|
||||
}
|
||||
Log.d(M_SWEEPER + TAG, "MAP到站通知:mSubTaskType=" + mSubTaskType + " isAutopilotSubTaskArriveEndSite="
|
||||
+ isAutopilotSubTaskArriveEndSite + " mSubTaskId=" + mSubTaskId);
|
||||
CallerLogger.INSTANCE.d(M_SWEEPER + TAG, "MAP到站通知:mSubTaskType=" + mSubTaskType + " isAutopilotSubTaskArriveEndSite="
|
||||
+ isAutopilotSubTaskArriveEndSite + " mSubTaskId=" + mSubTaskId);
|
||||
if (SubTaskTypeEnum.MANUAL_DRIVING_SUBTYPE.getCode() == mSubTaskType) {//人工驾驶子任务需要手动跳过,不能自动结束
|
||||
return;
|
||||
}
|
||||
if (isAutopilotSubTaskArriveEndSite) {
|
||||
return;
|
||||
}
|
||||
isAutopilotSubTaskArriveEndSite = true;
|
||||
//到达子任务终点 结束子任务
|
||||
subTaskEnd(mIsFirstSubtask, mIsLastSubtask, mSubTaskId);
|
||||
}
|
||||
|
||||
public void triggerStartServiceEvent(boolean isRestart, boolean send) {
|
||||
if (mCurrentSubTaskDetail == null) {
|
||||
return;
|
||||
}
|
||||
SweeperAnalyticsManager.getInstance().triggerStartAutopilotEvent(isRestart, send,
|
||||
mCurrentSubTaskDetail.getStartSiteName(), mCurrentSubTaskDetail.getEndSiteName(), mCurrentSubTaskDetail.getLineId());
|
||||
}
|
||||
|
||||
public boolean isRestartAutopilot() {
|
||||
return firstStartAutopilot > 1;
|
||||
}
|
||||
|
||||
public void triggerUnableStartAPReasonEvent() {
|
||||
if (mCurrentSubTaskDetail == null) {
|
||||
return;
|
||||
}
|
||||
SweeperAnalyticsManager.getInstance().triggerUnableStartAPReasonEvent(
|
||||
mCurrentSubTaskDetail.getStartSiteName(), mCurrentSubTaskDetail.getEndSiteName(), mCurrentSubTaskDetail.getLineId(),
|
||||
OCHAdasAbilityManager.getInstance().getAutopilotUnAbilityReason());
|
||||
}
|
||||
|
||||
/**
|
||||
* 将轨迹文件信息同步到鹰眼
|
||||
*/
|
||||
private void updateAutopilotControlParameters() {
|
||||
|
||||
AutopilotControlParameters parameters = initAutopilotControlParameters();
|
||||
if (null == parameters) {
|
||||
CallerLogger.INSTANCE.e(M_SWEEPER + TAG, "AutopilotControlParameters is empty.");
|
||||
return;
|
||||
}
|
||||
CallerLogger.INSTANCE.d(M_SWEEPER + TAG, "AutopilotControlParameters" + GsonUtil.jsonFromObject(parameters));
|
||||
CallerLogger.INSTANCE.d(M_SWEEPER + TAG, "AutopilotControlParameters is update.");
|
||||
CallerAutoPilotStatusListenerManager.INSTANCE.updateAutopilotControlParameters(parameters);
|
||||
}
|
||||
|
||||
private void clearAutopilotControlParameters() {
|
||||
CallerLogger.INSTANCE.d(M_SWEEPER + TAG, "AutopilotControlParameters is clear.");
|
||||
CallerAutoPilotStatusListenerManager.INSTANCE.updateAutopilotControlParameters(null);
|
||||
}
|
||||
|
||||
private AutopilotControlParameters initAutopilotControlParameters() {
|
||||
AutopilotControlParameters parameters = new AutopilotControlParameters();
|
||||
if (mCurrentSubTaskDetail != null) {
|
||||
parameters.routeID = mCurrentSubTaskDetail.getLineId();
|
||||
parameters.routeName = mCurrentSubTaskDetail.getLineName();
|
||||
parameters.startName = PinYinUtil.getPinYinHeadChar(mCurrentSubTaskDetail.getStartSiteName());
|
||||
parameters.endName = PinYinUtil.getPinYinHeadChar(mCurrentSubTaskDetail.getEndSiteName());
|
||||
parameters.startLatLon = new AutopilotControlParameters
|
||||
.AutoPilotLonLat(mCurrentSubTaskDetail.getStartSiteWgs64Lat(), mCurrentSubTaskDetail.getStartSiteWgs64Lon());
|
||||
parameters.endLatLon = new AutopilotControlParameters
|
||||
.AutoPilotLonLat(mCurrentSubTaskDetail.getEndSiteWgs64Lat(), mCurrentSubTaskDetail.getEndSiteWgs64Lon());
|
||||
parameters.vehicleType = VEHICLE_TYPE;
|
||||
parameters.autoPilotLine = new AutopilotControlParameters.AutoPilotLine(
|
||||
mCurrentSubTaskDetail.getLineId(),
|
||||
mCurrentSubTaskDetail.getCsvFileUrl(), mCurrentSubTaskDetail.getCsvFileMd5(),
|
||||
mCurrentSubTaskDetail.getTxtFileUrl(), mCurrentSubTaskDetail.getTxtFileMd5(),
|
||||
mCurrentSubTaskDetail.getPublishTime(), mCurrentSubTaskDetail.getCarModel(),
|
||||
mCurrentSubTaskDetail.getCsvFileUrlDPQP(), mCurrentSubTaskDetail.getCsvFileMd5DPQP(),
|
||||
mCurrentSubTaskDetail.getTxtFileUrlDPQP(), mCurrentSubTaskDetail.getTxtFileMd5DPQP(),
|
||||
mCurrentSubTaskDetail.getPublishTimeDPQP());
|
||||
}
|
||||
return parameters;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取当前正在执行的任务
|
||||
*/
|
||||
public void getCurrentTask() {
|
||||
SweeperServiceManager.getCurrentTask(mContext, new OchCommonServiceCallback<BaseResponse<SweeperSubTaskBean>>() {
|
||||
@Override
|
||||
public void onSuccess(BaseResponse<SweeperSubTaskBean> data) {
|
||||
CallerLogger.INSTANCE.d(M_SWEEPER + TAG, "getCurrentTask:" + GsonUtil.jsonFromObject(data));
|
||||
if (mSweeperTaskCallback != null && data != null) {
|
||||
SweeperSubTaskBean sweeperSubTaskBean = data.getData();
|
||||
if (sweeperSubTaskBean != null && sweeperSubTaskBean.getSubList() != null && sweeperSubTaskBean.getSubList().size() > 0) {
|
||||
mSweeperTaskCallback.setSubTaskBean(sweeperSubTaskBean, true);
|
||||
} else {
|
||||
getMainTaskList(false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onError() {
|
||||
if (!NetworkUtils.isConnected(mContext)) {
|
||||
ToastUtils.showShort(mContext.getString(R.string.network_error_tip));
|
||||
} else {
|
||||
ToastUtils.showShort(mContext.getString(R.string.request_error_tip));
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onFail(int code, String msg) {
|
||||
if (ToastUtilsOch.isCustomFastClick(5000)) {
|
||||
if (!NetworkUtils.isConnected(mContext)) {
|
||||
ToastUtils.showShort("网络异常,请稍后重试");
|
||||
} else {
|
||||
ToastUtils.showShort(msg);
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取主任务列表
|
||||
*/
|
||||
public void getMainTaskList(boolean refresh) {
|
||||
SweeperServiceManager.getMainTaskList(mContext, new OchCommonServiceCallback<BaseResponse<List<SweeperMainTaskBean>>>() {
|
||||
@Override
|
||||
public void onSuccess(BaseResponse<List<SweeperMainTaskBean>> data) {
|
||||
CallerLogger.INSTANCE.d(M_SWEEPER + TAG, "getMainTaskList:" + GsonUtil.jsonFromObject(data));
|
||||
if (mSweeperTaskCallback != null && data != null && data.getCode() == 0) {
|
||||
List<SweeperMainTaskBean> list = data.getData();
|
||||
mSweeperTaskCallback.setMainTaskList(list, refresh);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onFail(int code, String msg) {
|
||||
if (ToastUtilsOch.isCustomFastClick(5000)) {
|
||||
if (!NetworkUtils.isConnected(mContext)) {
|
||||
ToastUtils.showShort("网络异常,请稍后重试");
|
||||
} else {
|
||||
ToastUtils.showShort(msg);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onError() {
|
||||
if (!NetworkUtils.isConnected(mContext)) {
|
||||
ToastUtils.showShort(mContext.getString(R.string.network_error_tip));
|
||||
} else {
|
||||
ToastUtils.showShort(mContext.getString(R.string.request_error_tip));
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取子任务列表
|
||||
*/
|
||||
public void getSubTaskList(int taskId, SweeperSubTaskBean sweeperSubTaskBean) {
|
||||
SweeperServiceManager.getSubTaskList(taskId, mContext, new OchCommonServiceCallback<BaseResponse<List<SubInfo>>>() {
|
||||
@Override
|
||||
public void onSuccess(BaseResponse<List<SubInfo>> data) {
|
||||
CallerLogger.INSTANCE.d(M_SWEEPER + TAG, "getSubTaskList:" + GsonUtil.jsonFromObject(data));
|
||||
if (mSweeperTaskCallback != null && data != null && data.getCode() == 0) {
|
||||
List<SubInfo> list = data.getData();
|
||||
if (list != null && list.size() > 0) {
|
||||
sweeperSubTaskBean.setSubList(list);
|
||||
mSweeperTaskCallback.setSubTaskBean(sweeperSubTaskBean, false);
|
||||
} else {
|
||||
getMainTaskList(false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onFail(int code, String msg) {
|
||||
if (ToastUtilsOch.isCustomFastClick(5000)) {
|
||||
if (!NetworkUtils.isConnected(mContext)) {
|
||||
ToastUtils.showShort("网络异常,请稍后重试");
|
||||
} else {
|
||||
ToastUtils.showShort(msg);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onError() {
|
||||
if (!NetworkUtils.isConnected(mContext)) {
|
||||
ToastUtils.showShort(mContext.getString(R.string.network_error_tip));
|
||||
} else {
|
||||
ToastUtils.showShort(mContext.getString(R.string.request_error_tip));
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取子任务详情包括轨迹文件信息
|
||||
*/
|
||||
public void getSubTaskDetail(boolean isFirst, boolean isEnd, int subTaskId, SubTaskTypeEnum subTaskType, boolean isStartSubtask) {
|
||||
SweeperServiceManager.getSubTaskDetail(subTaskId, mContext, new OchCommonServiceCallback<BaseResponse<SweeperSubTaskDetailBean>>() {
|
||||
@Override
|
||||
public void onSuccess(BaseResponse<SweeperSubTaskDetailBean> data) {
|
||||
CallerLogger.INSTANCE.d(M_SWEEPER + TAG, "getSubTaskDetail:" + GsonUtil.jsonFromObject(data));
|
||||
Log.d(M_SWEEPER + TAG, "getSubTaskDetail:" + GsonUtil.jsonFromObject(data));
|
||||
if (data != null) {
|
||||
mCurrentSubTaskDetail = data.getData();
|
||||
if (mCurrentSubTaskDetail != null) {
|
||||
mSweeperTaskCallback.setSubTakDetail(mCurrentSubTaskDetail, subTaskType);
|
||||
CallerLogger.INSTANCE.d(M_SWEEPER + TAG, "getSubTaskDetail:subTaskType=" + subTaskType
|
||||
+ ", isStartSubtask=" + isStartSubtask + ", mAutopilotState=" + mAutopilotState);
|
||||
Log.d(M_SWEEPER + TAG, "getSubTaskDetail:subTaskType=" + subTaskType
|
||||
+ ", isStartSubtask=" + isStartSubtask + ", mAutopilotState=" + mAutopilotState);
|
||||
if (subTaskType == SubTaskTypeEnum.AUTOPILOT_SUBTYPE) {//自动驾驶子任务
|
||||
//向自动驾驶发送要下载文件轨迹路径
|
||||
SweeperTrajectoryManager.getInstance().syncTrajectoryInfo(mCurrentSubTaskDetail);
|
||||
updateAutopilotControlParameters();
|
||||
// 不在启动驾驶状态也需要先开启子任务
|
||||
if (isStartSubtask) {//是否需要自动开始执行任务
|
||||
subTaskStart(isFirst, isEnd, subTaskId, subTaskType);
|
||||
if (mAutopilotState == IMoGoAutopilotStatusListener.STATUS_AUTOPILOT_RUNNING) {
|
||||
cancelAutoPilot();
|
||||
startAutopilot();
|
||||
|
||||
//提示必须是N档,且拉起手刹 才能进入自动驾驶
|
||||
VoiceNotice.showNotice(mContext.getString(R.string.sweeper_arrive_auto_start_next_subtask_tips));
|
||||
ToastUtils.showLong(mContext.getString(R.string.sweeper_arrive_auto_start_next_subtask_tips));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onFail(int code, String msg) {
|
||||
if (ToastUtilsOch.isCustomFastClick(5000)) {
|
||||
if (!NetworkUtils.isConnected(mContext)) {
|
||||
ToastUtils.showShort("网络异常,请稍后重试");
|
||||
} else {
|
||||
ToastUtils.showShort(msg);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onError() {
|
||||
if (!NetworkUtils.isConnected(mContext)) {
|
||||
ToastUtils.showShort(mContext.getString(R.string.network_error_tip));
|
||||
} else {
|
||||
ToastUtils.showShort(mContext.getString(R.string.request_error_tip));
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* 子任务开始上报
|
||||
*/
|
||||
public void subTaskStart(boolean isFirst, boolean isEnd, int subTaskId, SubTaskTypeEnum subTaskType) {
|
||||
SweeperServiceManager.subTaskStart(isFirst, isEnd, subTaskId, mContext, new OchCommonServiceCallback<BaseResponse<Boolean>>() {
|
||||
@Override
|
||||
public void onSuccess(BaseResponse<Boolean> data) {
|
||||
CallerLogger.INSTANCE.d(M_SWEEPER + TAG, "subTaskStart:" + GsonUtil.jsonFromObject(data));
|
||||
if (mSweeperTaskCallback != null && data != null) {
|
||||
if (data.getData()) {
|
||||
mIsSubTaskWorking = true;
|
||||
isAutopilotSubTaskArriveEndSite = false;
|
||||
mSweeperTaskCallback.updateSubTaskStatus(TaskStatusEnum.START_SUBTASK, false);
|
||||
if (subTaskType == SubTaskTypeEnum.AUTOPILOT_SUBTYPE) {//如果是自动驾驶子任务子开启自驾
|
||||
if (FunctionBuildConfig.isDemoMode) {//美化模式开启时
|
||||
SweeperTaskModel.getInstance().startBeautificationMode();
|
||||
}
|
||||
//ÏstartAutopilot(false);
|
||||
} else {
|
||||
if (FunctionBuildConfig.isDemoMode) {//美化模式开启时
|
||||
FunctionBuildConfig.isIgnoreConditionsDrawAutopilotTrajectoryData = true;//是否强制绘制引导线
|
||||
CallerAutoPilotControlManager.INSTANCE.setIPCDemoMode(false);//是否自动启动自驾
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onFail(int code, String msg) {
|
||||
if (ToastUtilsOch.isCustomFastClick(5000)) {
|
||||
if (!NetworkUtils.isConnected(mContext)) {
|
||||
ToastUtils.showShort("网络异常,请稍后重试");
|
||||
} else {
|
||||
ToastUtils.showShort(msg);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onError() {
|
||||
if (!NetworkUtils.isConnected(mContext)) {
|
||||
ToastUtils.showShort(mContext.getString(R.string.network_error_tip));
|
||||
} else {
|
||||
ToastUtils.showShort(mContext.getString(R.string.request_error_tip));
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* 子任务结束上报
|
||||
*/
|
||||
public void subTaskEnd(boolean isFirst, boolean isEnd, int subTaskId) {
|
||||
SweeperServiceManager.subTaskEnd(isFirst, isEnd, subTaskId, mContext, new OchCommonServiceCallback<BaseResponse<Boolean>>() {
|
||||
@Override
|
||||
public void onSuccess(BaseResponse<Boolean> data) {
|
||||
CallerLogger.INSTANCE.d(M_SWEEPER + TAG, "subTaskEnd:" +
|
||||
String.format("isFirst=%b; isEnd=%b; ", isFirst, isEnd) + GsonUtil.jsonFromObject(data));
|
||||
if (data != null) {
|
||||
if (data.getData()) {
|
||||
mIsSubTaskWorking = false;
|
||||
if (mSweeperTaskCallback != null) {
|
||||
mSweeperTaskCallback.updateSubTaskStatus(TaskStatusEnum.END_SUBTASK, isEnd);
|
||||
}
|
||||
if (isEnd) {
|
||||
if (FunctionBuildConfig.isDemoMode) {//美化模式开启时
|
||||
SweeperTaskModel.getInstance().closeBeautificationMode();
|
||||
}
|
||||
clearAutopilotControlParameters();
|
||||
//结束自动驾驶
|
||||
cancelAutoPilot();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onFail(int code, String msg) {
|
||||
if (ToastUtilsOch.isCustomFastClick(5000)) {
|
||||
if (!NetworkUtils.isConnected(mContext)) {
|
||||
ToastUtils.showShort("网络异常,请稍后重试");
|
||||
} else {
|
||||
if (isAutopilotSubTaskArriveEndSite) return;
|
||||
ToastUtils.showShort(msg);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onError() {
|
||||
if (!NetworkUtils.isConnected(mContext)) {
|
||||
ToastUtils.showShort(mContext.getString(R.string.network_error_tip));
|
||||
} else {
|
||||
ToastUtils.showShort(mContext.getString(R.string.request_error_tip));
|
||||
}
|
||||
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* 子任务跳过上报
|
||||
*/
|
||||
public void subTaskSkip(boolean isFirst, boolean isEnd, int subTaskId) {
|
||||
SweeperServiceManager.subTaskSkip(isFirst, isEnd, subTaskId, mContext, new OchCommonServiceCallback<BaseResponse<Boolean>>() {
|
||||
@Override
|
||||
public void onSuccess(BaseResponse<Boolean> data) {
|
||||
CallerLogger.INSTANCE.d(M_SWEEPER + TAG, "subTaskSkip:" +
|
||||
String.format("isFirst=%b; isEnd=%b; ", isFirst, isEnd)+ GsonUtil.jsonFromObject(data));
|
||||
if (mSweeperTaskCallback != null && data != null) {
|
||||
if (data.getData()) {
|
||||
mIsSubTaskWorking = false;
|
||||
// 跳过子任务也相当于开始并结束一个子任务,相关变量状态需要重置
|
||||
isAutopilotSubTaskArriveEndSite = false;
|
||||
mSweeperTaskCallback.updateSubTaskStatus(TaskStatusEnum.JUMP_OVER_SUBTASK, isEnd);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onFail(int code, String msg) {
|
||||
if (ToastUtilsOch.isCustomFastClick(5000)) {
|
||||
if (!NetworkUtils.isConnected(mContext)) {
|
||||
ToastUtils.showShort("网络异常,请稍后重试");
|
||||
} else {
|
||||
ToastUtils.showShort(msg);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onError() {
|
||||
if (!NetworkUtils.isConnected(mContext)) {
|
||||
ToastUtils.showShort(mContext.getString(R.string.network_error_tip));
|
||||
} else {
|
||||
ToastUtils.showShort(mContext.getString(R.string.request_error_tip));
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* 主任务重置
|
||||
*/
|
||||
public void mainTaskReset(int taskId) {
|
||||
SweeperServiceManager.mainTaskReset(taskId, mContext, new OchCommonServiceCallback<BaseResponse<Boolean>>() {
|
||||
@Override
|
||||
public void onSuccess(BaseResponse<Boolean> data) {
|
||||
CallerLogger.INSTANCE.d(M_SWEEPER + TAG, "mainTaskReset:" + GsonUtil.jsonFromObject(data));
|
||||
// 主任务重置 当前子任务也需重置
|
||||
mIsSubTaskWorking = false;
|
||||
isAutopilotSubTaskArriveEndSite = false;
|
||||
if (mSweeperTaskCallback != null && data != null) {
|
||||
mSweeperTaskCallback.setMainTaskReset(data.getData());
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onFail(int code, String msg) {
|
||||
if (ToastUtilsOch.isCustomFastClick(5000)) {
|
||||
if (!NetworkUtils.isConnected(mContext)) {
|
||||
ToastUtils.showShort("网络异常,请稍后重试");
|
||||
} else {
|
||||
ToastUtils.showShort(msg);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onError() {
|
||||
if (!NetworkUtils.isConnected(mContext)) {
|
||||
ToastUtils.showShort(mContext.getString(R.string.network_error_tip));
|
||||
} else {
|
||||
ToastUtils.showShort(mContext.getString(R.string.request_error_tip));
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
//结束自动驾驶
|
||||
public void cancelAutoPilot() {
|
||||
CallerAutoPilotControlManager.INSTANCE.cancelAutoPilot();
|
||||
}
|
||||
}
|
||||
@@ -1,14 +1,13 @@
|
||||
package com.mogo.och.sweeper.net;
|
||||
import com.mogo.eagle.core.data.BaseData;
|
||||
import com.mogo.och.sweeper.bean.SweeperOperationStatusRequest;
|
||||
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.SweeperQueryLineStationsRequest;
|
||||
import com.mogo.och.sweeper.bean.SweeperOperationStatusResponse;
|
||||
import com.mogo.och.sweeper.bean.SweeperResetDrivingLineRequest;
|
||||
import com.mogo.och.sweeper.bean.SweeperUpdateSiteStatusRequest;
|
||||
import com.mogo.och.sweeper.bean.BaseResponse;
|
||||
import com.mogo.och.sweeper.bean.SubInfo;
|
||||
import com.mogo.och.sweeper.bean.SubStartRequest;
|
||||
import com.mogo.och.sweeper.bean.SweeperSubTaskBean;
|
||||
import com.mogo.och.sweeper.bean.SweeperMainTaskBean;
|
||||
import com.mogo.och.sweeper.bean.SweeperSubTaskDetailBean;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import io.reactivex.Observable;
|
||||
import retrofit2.http.Body;
|
||||
@@ -17,101 +16,88 @@ import retrofit2.http.Header;
|
||||
import retrofit2.http.Headers;
|
||||
import retrofit2.http.POST;
|
||||
import retrofit2.http.Query;
|
||||
import retrofit2.http.QueryMap;
|
||||
|
||||
/**
|
||||
* 小巴车相关接口
|
||||
*
|
||||
* @author tongchenfei
|
||||
* <p>
|
||||
* wiki: http://wiki.zhidaohulian.com/pages/viewpage.action?pageId=48970072
|
||||
* 清扫车相关接口
|
||||
*/
|
||||
public interface ISweeperApiService {
|
||||
/**
|
||||
* 根据车机坐标获取所在区域全部站点信息
|
||||
*
|
||||
* @param request 请求参数
|
||||
* @return 接口返回数据
|
||||
*/
|
||||
@Headers( {"Content-Type:application/json;charset=UTF-8"} )
|
||||
@POST( "/autopilot-car-hailing/line/v2/driver/bus/lineDataWithDriver/query" )
|
||||
Observable<SweeperRoutesResponse> querySiteByCoordinate(@Header ("appId") String appId, @Header("ticket") String ticket, @Body SweeperQueryLineStationsRequest request);
|
||||
|
||||
/**
|
||||
* 重置巴士路线: 点击小巴车tab 或者出车后会使用
|
||||
*
|
||||
* @param request 请求参数{"destLine":1,"sn":"F803EB2046PZD00229"} 这个接口是重置bus线路的, 不是重置线路中站点的
|
||||
* @return 返回值是重置后的车站列表
|
||||
*/
|
||||
@Headers( {"Content-Type:application/json;charset=UTF-8"} )
|
||||
@POST( "/autopilot-car-hailing/car/v2/driver/bus/drivingLine/reset" )
|
||||
Observable<SweeperRoutesResponse> resetStationStatus(@Header ("appId") String appId, @Header("ticket") String ticket, @Body SweeperResetDrivingLineRequest request);
|
||||
|
||||
/**
|
||||
* 离站,通知服务器
|
||||
* @param request
|
||||
* @return
|
||||
*/
|
||||
@Headers({"Content-Type:application/json;charset=UTF-8"})
|
||||
@POST("/autopilot-car-hailing/car/v2/driver/bus/driving/away")
|
||||
Observable<SweeperRoutesResponse> leaveStation(@Header ("appId") String appId, @Header("ticket") String ticket, @Body SweeperUpdateSiteStatusRequest request);
|
||||
|
||||
/**
|
||||
* 到站 更新到站信息
|
||||
* @param request
|
||||
* @return
|
||||
*/
|
||||
@Headers({"Content-type:application/json;charset=UTF-8"})
|
||||
@POST("/autopilot-car-hailing/order/v2/driver/bus/driving/attachSite")
|
||||
Observable< BaseData > arriveSiteStation(@Header ("appId") String appId,@Header("ticket") String ticket,@Body SweeperUpdateSiteStatusRequest request);
|
||||
|
||||
/**
|
||||
* 出车
|
||||
* @param request
|
||||
* @return
|
||||
*/
|
||||
@Headers( {"Content-type:application/json;charset=UTF-8"} )
|
||||
@POST("/autopilot-car-hailing/car/v2/driver/bus/startTakeOrder")
|
||||
Observable<BaseData> startTakeOrder(@Header ("appId") String appId,@Header("ticket") String ticket,@Body SweeperOperationStatusRequest request);
|
||||
|
||||
/**
|
||||
* 收车
|
||||
* @param request
|
||||
* @return
|
||||
*/
|
||||
@Headers({"Content-type:application/json;charset=UTF-8"})
|
||||
@POST("/autopilot-car-hailing/car/v2/driver/bus/stopTakeOrder")
|
||||
Observable<BaseData> stopTakeOrder(@Header ("appId") String appId,@Header("ticket") String ticket,@Body SweeperOperationStatusRequest request);
|
||||
|
||||
/**
|
||||
* 查询小巴出车/收车状态
|
||||
* @param sn
|
||||
* @return
|
||||
*/
|
||||
@Headers({"Content-type:application/json;charset=UTF-8"})
|
||||
@GET("/autopilot-car-hailing/car/v2/driver/bus/takeOrderStatus/query")
|
||||
Observable<SweeperOperationStatusResponse> queryOperationStatus(@Header ("appId") String appId, @Header("ticket") String ticket, @Query("sn") String sn);
|
||||
|
||||
/**
|
||||
* 车机端上传心跳数据(只在出车状态时上传):包含高德坐标系经纬度
|
||||
* @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);
|
||||
|
||||
/**
|
||||
* 查询车辆配置的所有路线
|
||||
* 获取当前正在执行的任务
|
||||
* @param appId
|
||||
* @param ticket
|
||||
* @param sn
|
||||
* @param carSn
|
||||
* @return
|
||||
*/
|
||||
@GET("/autopilot-car-hailing/line/v2/driver/bus/bindLine/query")
|
||||
Observable<SweeperQueryLinesResponse> queryBusLines(@Header ("appId") String appId, @Header("ticket") String ticket, @Query("sn") String sn);
|
||||
@GET("/och-sweep/api/task/v1/currentTask")
|
||||
Observable<BaseResponse<SweeperSubTaskBean>> getCurrentTask(@Header ("appId") String appId, @Header("ticket") String ticket, @Query("carSn") String carSn);
|
||||
/**
|
||||
* 清扫车任务列表
|
||||
* @param appId
|
||||
* @param ticket
|
||||
* @param carSn
|
||||
* @return
|
||||
*/
|
||||
@GET("/och-sweep/api/task/v1/mainTaskList")
|
||||
Observable<BaseResponse<List<SweeperMainTaskBean>>> getMainTaskList(@Header ("appId") String appId, @Header("ticket") String ticket, @Query("carSn") String carSn);
|
||||
/**
|
||||
* 清扫车子任务列表
|
||||
* @param appId
|
||||
* @param ticket
|
||||
* @param map
|
||||
* @return
|
||||
*/
|
||||
@GET("/och-sweep/api/task/v1/subTaskList")
|
||||
Observable<BaseResponse<List<SubInfo>>> getSubTaskList(@Header ("appId") String appId, @Header("ticket") String ticket, @QueryMap Map<String, String> map);
|
||||
/**
|
||||
* 子任务详情 包括子任务轨迹信息
|
||||
* @param appId
|
||||
* @param ticket
|
||||
* @param map
|
||||
* @return
|
||||
*/
|
||||
@GET("/och-sweep/api/task/v1/subTaskInfo")
|
||||
Observable<BaseResponse<SweeperSubTaskDetailBean>> getSubTaskDetail(@Header ("appId") String appId, @Header("ticket") String ticket, @QueryMap Map<String, String> map);
|
||||
|
||||
@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);
|
||||
/**
|
||||
* 子任务开始
|
||||
* @param appId
|
||||
* @param ticket
|
||||
* @param subStartRequest
|
||||
* @return
|
||||
*/
|
||||
@Headers({"Content-type:application/json;charset=UTF-8"})
|
||||
@POST("/och-sweep/api/task/v1/subTaskStart")
|
||||
Observable<BaseResponse<Boolean>> subTaskStart(@Header ("appId") String appId, @Header("ticket") String ticket, @Body SubStartRequest subStartRequest);
|
||||
|
||||
/**
|
||||
* 子任务结束
|
||||
* @param appId
|
||||
* @param ticket
|
||||
* @param subStartRequest
|
||||
* @return
|
||||
*/
|
||||
@Headers({"Content-type:application/json;charset=UTF-8"})
|
||||
@POST("/och-sweep/api/task/v1/subTaskEnd")
|
||||
Observable<BaseResponse<Boolean>> subTaskEnd(@Header ("appId") String appId, @Header("ticket") String ticket, @Body SubStartRequest subStartRequest);
|
||||
/**
|
||||
* 子任务跳过
|
||||
* @param appId
|
||||
* @param ticket
|
||||
* @param subStartRequest
|
||||
* @return
|
||||
*/
|
||||
@Headers({"Content-type:application/json;charset=UTF-8"})
|
||||
@POST("/och-sweep/api/task/v1/subTaskSkip")
|
||||
Observable<BaseResponse<Boolean>> subTaskSkip(@Header ("appId") String appId, @Header("ticket") String ticket, @Body SubStartRequest subStartRequest);
|
||||
|
||||
/**
|
||||
* 主任务重置
|
||||
* @param appId
|
||||
* @param ticket
|
||||
* @return
|
||||
*/
|
||||
@GET("/och-sweep/api/task/v1/mainTaskReset")
|
||||
Observable<BaseResponse<Boolean>> mainTaskReset(@Header ("appId") String appId, @Header("ticket") String ticket,@QueryMap Map<String, String> map);
|
||||
}
|
||||
|
||||
|
||||
@@ -1,15 +0,0 @@
|
||||
package com.mogo.och.sweeper.net;
|
||||
|
||||
/**
|
||||
* @author: wangmingjun
|
||||
* @date: 2021/10/20
|
||||
*/
|
||||
public interface ISweeperServiceCallback< T >{
|
||||
void onSuccess(T o);
|
||||
|
||||
void onFail(String failMsg);
|
||||
|
||||
default void onError() {
|
||||
|
||||
}
|
||||
}
|
||||
@@ -1,225 +0,0 @@
|
||||
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.common.module.biz.constant.OchCommonConst;
|
||||
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.model.SweeperOrderModel;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import io.reactivex.android.schedulers.AndroidSchedulers;
|
||||
import io.reactivex.schedulers.Schedulers;
|
||||
|
||||
/**
|
||||
* @author: wangmingjun
|
||||
* @date: 2021/10/20
|
||||
*/
|
||||
public class SweeperServiceManager {
|
||||
|
||||
private static final String TAG = SweeperServiceManager.class.getSimpleName();
|
||||
|
||||
private final ISweeperApiService mService;
|
||||
|
||||
private static final class SingletonHolder {
|
||||
private static final SweeperServiceManager INSTANCE = new SweeperServiceManager();
|
||||
}
|
||||
|
||||
public static SweeperServiceManager getInstance(){
|
||||
return SingletonHolder.INSTANCE;
|
||||
}
|
||||
|
||||
private SweeperServiceManager(){
|
||||
mService = MoGoRetrofitFactory.getInstance(OchCommonConst.getBaseUrl()).create(ISweeperApiService.class);
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询小巴车线路
|
||||
* @param context
|
||||
* @param callback
|
||||
*/
|
||||
public void queryBusRoutes(Context context, ISweeperServiceCallback<SweeperRoutesResponse> callback) {
|
||||
//获取当前高德坐标
|
||||
|
||||
mService.querySiteByCoordinate(MoGoAiCloudClientConfig.getInstance().getServiceAppId()
|
||||
,MoGoAiCloudClientConfig.getInstance().getToken()
|
||||
, new SweeperQueryLineStationsRequest(SweeperOrderModel.getInstance().mLongitude
|
||||
, SweeperOrderModel.getInstance().mLatitude,true))
|
||||
.subscribeOn( Schedulers.io() ).observeOn( AndroidSchedulers.mainThread() )
|
||||
.subscribe( getSubscribeImpl(context,callback,"querySiteByCoordinate"));
|
||||
}
|
||||
|
||||
/**
|
||||
* 重置线路站点
|
||||
* @param context
|
||||
* @param lineId
|
||||
* @param callback
|
||||
*/
|
||||
public void resetStationStatus(Context context, int lineId, ISweeperServiceCallback<SweeperRoutesResponse> callback){
|
||||
mService.resetStationStatus(MoGoAiCloudClientConfig.getInstance().getServiceAppId()
|
||||
,MoGoAiCloudClientConfig.getInstance().getToken(),new SweeperResetDrivingLineRequest(lineId))
|
||||
.subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread())
|
||||
.subscribe(getSubscribeImpl(context,callback,"debugResetStationStatus"));
|
||||
}
|
||||
|
||||
/**
|
||||
* 离站上报
|
||||
* @param context
|
||||
* @param seq
|
||||
* @param siteId
|
||||
* @param callback
|
||||
*/
|
||||
public void leaveStation(Context context, int seq, int siteId, ISweeperServiceCallback<SweeperRoutesResponse> callback){
|
||||
mService.leaveStation(MoGoAiCloudClientConfig.getInstance().getServiceAppId()
|
||||
,MoGoAiCloudClientConfig.getInstance().getToken()
|
||||
,new SweeperUpdateSiteStatusRequest(seq,siteId, SweeperOrderModel.getInstance().mLongitude
|
||||
, SweeperOrderModel.getInstance().mLatitude))
|
||||
.subscribeOn( Schedulers.io() )
|
||||
.observeOn( AndroidSchedulers.mainThread() )
|
||||
.subscribe(getSubscribeImpl(context,callback,"leaveStation"));
|
||||
}
|
||||
|
||||
/**
|
||||
* 到站更新站点状态
|
||||
* @param context
|
||||
* @param seq
|
||||
* @param siteId
|
||||
* @param callback
|
||||
*/
|
||||
public void arriveSiteStation(Context context, int seq, int siteId, ISweeperServiceCallback<BaseData> callback){
|
||||
mService.arriveSiteStation(MoGoAiCloudClientConfig.getInstance().getServiceAppId()
|
||||
,MoGoAiCloudClientConfig.getInstance().getToken()
|
||||
,new SweeperUpdateSiteStatusRequest(seq,siteId
|
||||
, SweeperOrderModel.getInstance().mLongitude, SweeperOrderModel.getInstance().mLatitude))
|
||||
.subscribeOn( Schedulers.io() )
|
||||
.observeOn( AndroidSchedulers.mainThread() )
|
||||
.subscribe(getSubscribeImpl(context,callback,"leaveStation"));
|
||||
}
|
||||
|
||||
/**
|
||||
* 收车
|
||||
* @param context
|
||||
* @param callback
|
||||
*/
|
||||
public void stopTakeOrder(Context context, ISweeperServiceCallback<BaseData> callback){
|
||||
mService.stopTakeOrder(MoGoAiCloudClientConfig.getInstance().getServiceAppId()
|
||||
,MoGoAiCloudClientConfig.getInstance().getToken()
|
||||
,new SweeperOperationStatusRequest(SweeperOrderModel.getInstance().mLongitude
|
||||
, SweeperOrderModel.getInstance().mLatitude))
|
||||
.subscribeOn(Schedulers.io())
|
||||
.observeOn(AndroidSchedulers.mainThread())
|
||||
.subscribe(getSubscribeImpl(context,callback,"stopTakeOrder"));
|
||||
}
|
||||
|
||||
/**
|
||||
* 出车
|
||||
* @param context
|
||||
* @param callback
|
||||
*/
|
||||
public void startTakeOrder(Context context, ISweeperServiceCallback<BaseData> callback){
|
||||
mService.startTakeOrder(MoGoAiCloudClientConfig.getInstance().getServiceAppId()
|
||||
,MoGoAiCloudClientConfig.getInstance().getToken()
|
||||
,new SweeperOperationStatusRequest(SweeperOrderModel.getInstance().mLongitude
|
||||
, SweeperOrderModel.getInstance().mLatitude))
|
||||
.subscribeOn(Schedulers.io())
|
||||
.observeOn(AndroidSchedulers.mainThread())
|
||||
.subscribe(getSubscribeImpl(context,callback,"startTakeOrder"));
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询出车/收车状态
|
||||
* @param context
|
||||
* @param callback
|
||||
*/
|
||||
public void queryOperationStatus(Context context, ISweeperServiceCallback<SweeperOperationStatusResponse> callback){
|
||||
mService.queryOperationStatus(MoGoAiCloudClientConfig.getInstance().getServiceAppId()
|
||||
,MoGoAiCloudClientConfig.getInstance().getToken(),MoGoAiCloudClientConfig.getInstance().getSn())
|
||||
.subscribeOn( Schedulers.io() )
|
||||
.observeOn( AndroidSchedulers.mainThread() )
|
||||
.subscribe(getSubscribeImpl(context,callback,"queryOperationStatus"));
|
||||
}
|
||||
|
||||
|
||||
public void queryBusLines(Context context, ISweeperServiceCallback<SweeperQueryLinesResponse> callback){
|
||||
mService.queryBusLines(MoGoAiCloudClientConfig.getInstance().getServiceAppId()
|
||||
,MoGoAiCloudClientConfig.getInstance().getToken(),MoGoAiCloudClientConfig.getInstance().getSn())
|
||||
.subscribeOn(Schedulers.io())
|
||||
.observeOn(AndroidSchedulers.mainThread())
|
||||
.subscribe(getSubscribeImpl(context,callback,"queryBusLines"));
|
||||
}
|
||||
|
||||
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
|
||||
public void onSuccess(T o) {
|
||||
super.onSuccess(o);
|
||||
CallerLogger.INSTANCE.e(M_BUS + TAG,apiName + ": onSuccess() " + o.msg);
|
||||
if (callback != null) {
|
||||
callback.onSuccess(o);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onError(String message, int code) {
|
||||
super.onError(message, code);
|
||||
CallerLogger.INSTANCE.e(M_BUS + TAG,apiName + ": onError() " +"msg="+ message+" code="+code);
|
||||
if (callback != null) {
|
||||
callback.onFail("msg="+ message+" code="+code);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onError(Throwable e) {
|
||||
super.onError(e);
|
||||
CallerLogger.INSTANCE.e(M_BUS + TAG,apiName + ": onError() " +" e="+e.getMessage());
|
||||
if (callback != null) {
|
||||
callback.onFail(e.getMessage());
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,173 @@
|
||||
package com.mogo.och.sweeper.net
|
||||
|
||||
import android.content.Context
|
||||
import com.elegant.network.utils.GsonUtil
|
||||
import com.mogo.cloud.passport.MoGoAiCloudClientConfig
|
||||
import com.mogo.eagle.core.network.MoGoRetrofitFactory
|
||||
import com.mogo.eagle.core.utilcode.mogo.logger.CallerLogger.d
|
||||
import com.mogo.eagle.core.utilcode.mogo.logger.scene.SceneConstant
|
||||
import com.mogo.och.common.module.biz.network.OchCommonServiceCallback
|
||||
import com.mogo.och.common.module.biz.network.OchCommonSubscribeImpl
|
||||
import com.mogo.och.common.module.biz.network.interceptor.transformTry
|
||||
import com.mogo.och.sweeper.bean.*
|
||||
import com.mogo.och.sweeper.constant.SweeperConst.Companion.getBaseUrl
|
||||
import com.mogo.och.sweeper.model.SweeperTaskModel
|
||||
|
||||
object SweeperServiceManager {
|
||||
private val TAG = SweeperTaskModel::class.java.simpleName
|
||||
private val mService: ISweeperApiService = MoGoRetrofitFactory.getInstance(getBaseUrl()).create(
|
||||
ISweeperApiService::class.java
|
||||
)
|
||||
|
||||
/**
|
||||
* 获取当前正在执行的任务
|
||||
*/
|
||||
@JvmStatic
|
||||
fun getCurrentTask(context: Context, callback: OchCommonServiceCallback<BaseResponse<SweeperSubTaskBean>>?) {
|
||||
val map = hashMapOf<String, String>()
|
||||
map["serviceAppId"] = getServiceAppId()
|
||||
map["token"] = getToken()
|
||||
map["sn"] = getCarSN()
|
||||
d(SceneConstant.M_SWEEPER + TAG, "getCurrentTask:" + GsonUtil.jsonFromObject(map))
|
||||
mService.getCurrentTask(
|
||||
getServiceAppId(),
|
||||
getToken(),
|
||||
getCarSN()
|
||||
)
|
||||
.transformTry()
|
||||
.subscribe(OchCommonSubscribeImpl(context, callback, "getCurrentTask"))
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取主任务列表
|
||||
*/
|
||||
@JvmStatic
|
||||
fun getMainTaskList(context: Context, callback: OchCommonServiceCallback<BaseResponse<MutableList<SweeperMainTaskBean>>>?) {
|
||||
val map = hashMapOf<String, String>()
|
||||
map["serviceAppId"] = getServiceAppId()
|
||||
map["token"] = getToken()
|
||||
map["sn"] = getCarSN()
|
||||
d(SceneConstant.M_SWEEPER + TAG, "getMainTaskList:" + GsonUtil.jsonFromObject(map))
|
||||
mService.getMainTaskList(
|
||||
getServiceAppId(),
|
||||
getToken(),
|
||||
getCarSN()
|
||||
)
|
||||
.transformTry()
|
||||
.subscribe(OchCommonSubscribeImpl(context, callback, "getMainTaskList"))
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取子任务列表
|
||||
*/
|
||||
@JvmStatic
|
||||
fun getSubTaskList(taskId: Int, context: Context, callback: OchCommonServiceCallback<BaseResponse<MutableList<SubInfo>>>?) {
|
||||
val map = hashMapOf<String, String>()
|
||||
map["carSn"] = getCarSN()
|
||||
map["taskId"] = taskId.toString()
|
||||
d(SceneConstant.M_SWEEPER + TAG, "getSubTaskList:" + GsonUtil.jsonFromObject(map))
|
||||
mService.getSubTaskList(
|
||||
getServiceAppId(),
|
||||
getToken(),
|
||||
map
|
||||
)
|
||||
.transformTry()
|
||||
.subscribe(OchCommonSubscribeImpl(context, callback, "getSubTaskList"))
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取子任务详情包括轨迹文件信息
|
||||
*/
|
||||
@JvmStatic
|
||||
fun getSubTaskDetail(subTaskId: Int, context: Context, callback: OchCommonServiceCallback<BaseResponse<SweeperSubTaskDetailBean>>?) {
|
||||
val map = hashMapOf<String, String>()
|
||||
map["carSn"] = getCarSN()
|
||||
map["taskId"] = subTaskId.toString()
|
||||
d(SceneConstant.M_SWEEPER + TAG, "getSubTaskDetail:" + GsonUtil.jsonFromObject(map))
|
||||
mService.getSubTaskDetail(
|
||||
getServiceAppId(),
|
||||
getToken(),
|
||||
map
|
||||
)
|
||||
.transformTry()
|
||||
.subscribe(OchCommonSubscribeImpl(context, callback, "getSubTaskList"))
|
||||
}
|
||||
|
||||
/**
|
||||
* 子任务开始上报
|
||||
*/
|
||||
@JvmStatic
|
||||
fun subTaskStart(isFirst: Boolean, isEnd: Boolean, subTaskId: Int, context: Context, callback: OchCommonServiceCallback<BaseResponse<Boolean>>?) {
|
||||
val subStartRequest = SubStartRequest(getCarSN(), subTaskId, System.currentTimeMillis(), isFirst, isEnd)
|
||||
d(SceneConstant.M_SWEEPER + TAG, "subTaskStart:" + GsonUtil.jsonFromObject(subStartRequest))
|
||||
mService.subTaskStart(
|
||||
getServiceAppId(),
|
||||
getToken(),
|
||||
subStartRequest
|
||||
)
|
||||
.transformTry()
|
||||
.subscribe(OchCommonSubscribeImpl(context, callback, "subTaskStart"))
|
||||
}
|
||||
|
||||
/**
|
||||
* 子任务结束上报
|
||||
*/
|
||||
@JvmStatic
|
||||
fun subTaskEnd(isFirst: Boolean, isEnd: Boolean, subTaskId: Int, context: Context, callback: OchCommonServiceCallback<BaseResponse<Boolean>>?) {
|
||||
val subStartRequest = SubStartRequest(getCarSN(), subTaskId, System.currentTimeMillis(), isFirst, isEnd)
|
||||
d(SceneConstant.M_SWEEPER + TAG, "subTaskEnd:" + GsonUtil.jsonFromObject(subStartRequest))
|
||||
mService.subTaskEnd(
|
||||
getServiceAppId(),
|
||||
getToken(),
|
||||
subStartRequest
|
||||
)
|
||||
.transformTry()
|
||||
.subscribe(OchCommonSubscribeImpl(context, callback, "subTaskEnd"))
|
||||
}
|
||||
|
||||
/**
|
||||
* 子任务跳过上报
|
||||
*/
|
||||
@JvmStatic
|
||||
fun subTaskSkip(isFirst: Boolean, isEnd: Boolean, subTaskId: Int, context: Context, callback: OchCommonServiceCallback<BaseResponse<Boolean>>?) {
|
||||
val subStartRequest = SubStartRequest(getCarSN(), subTaskId, System.currentTimeMillis(), isFirst, isEnd)
|
||||
d(SceneConstant.M_SWEEPER + TAG, "subTaskSkip:" + GsonUtil.jsonFromObject(subStartRequest))
|
||||
mService.subTaskSkip(
|
||||
getServiceAppId(),
|
||||
getToken(),
|
||||
subStartRequest
|
||||
)
|
||||
.transformTry()
|
||||
.subscribe(OchCommonSubscribeImpl(context, callback, "subTaskSkip"))
|
||||
}
|
||||
|
||||
/**
|
||||
* 主任务重置
|
||||
*/
|
||||
@JvmStatic
|
||||
fun mainTaskReset(taskId: Int, context: Context, callback: OchCommonServiceCallback<BaseResponse<Boolean>>?) {
|
||||
val map = hashMapOf<String, String>()
|
||||
map["carSn"] = getCarSN()
|
||||
map["taskId"] = taskId.toString()
|
||||
d(SceneConstant.M_SWEEPER + TAG, "mainTaskReset:" + GsonUtil.jsonFromObject(map))
|
||||
mService.mainTaskReset(
|
||||
getServiceAppId(),
|
||||
getToken(),
|
||||
map
|
||||
)
|
||||
.transformTry()
|
||||
.subscribe(OchCommonSubscribeImpl(context, callback, "mainTaskReset"))
|
||||
}
|
||||
|
||||
private fun getCarSN(): String {
|
||||
return MoGoAiCloudClientConfig.getInstance().sn
|
||||
}
|
||||
|
||||
private fun getServiceAppId(): String {
|
||||
return MoGoAiCloudClientConfig.getInstance().serviceAppId
|
||||
}
|
||||
|
||||
private fun getToken(): String {
|
||||
return MoGoAiCloudClientConfig.getInstance().token
|
||||
}
|
||||
}
|
||||
@@ -1,79 +0,0 @@
|
||||
package com.mogo.och.sweeper.presenter;
|
||||
|
||||
import android.os.Looper;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.lifecycle.LifecycleOwner;
|
||||
|
||||
import com.mogo.commons.mvp.Presenter;
|
||||
import com.mogo.eagle.core.utilcode.util.UiThreadHandler;
|
||||
import com.mogo.och.sweeper.bean.SweeperQueryLinesResponse;
|
||||
import com.mogo.och.sweeper.callback.ISweeperLinesCallback;
|
||||
import com.mogo.och.sweeper.model.SweeperLineModel;
|
||||
import com.mogo.och.sweeper.model.SweeperOrderModel;
|
||||
import com.mogo.och.sweeper.ui.SweeperSwitchLineView;
|
||||
|
||||
/**
|
||||
* @author: wangmingjun
|
||||
* @date: 2022/2/9
|
||||
*/
|
||||
public class SweeperLinePresenter extends Presenter<SweeperSwitchLineView> implements ISweeperLinesCallback {
|
||||
|
||||
public SweeperLinePresenter(SweeperSwitchLineView view) {
|
||||
super(view);
|
||||
SweeperLineModel.getInstance().init();
|
||||
SweeperOrderModel.getInstance().init();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onCreate(@NonNull LifecycleOwner owner) {
|
||||
super.onCreate(owner);
|
||||
initListener();
|
||||
}
|
||||
|
||||
private void initListener() {
|
||||
SweeperLineModel.getInstance().setBusLinesCallback(this);
|
||||
}
|
||||
|
||||
private void runOnUIThread( Runnable executor ) {
|
||||
if ( executor == null ) {
|
||||
return;
|
||||
}
|
||||
if ( Looper.myLooper() != Looper.getMainLooper() ) {
|
||||
UiThreadHandler.post( executor );
|
||||
} else {
|
||||
executor.run();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onBusLinesChange(SweeperQueryLinesResponse lines) {
|
||||
runOnUIThread(() -> mView.onBusLinesChange(lines));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onChangeLineIdSuccess() {
|
||||
runOnUIThread(() -> mView.onChangeLineIdSuccess());
|
||||
}
|
||||
|
||||
public void queryBusLines(){
|
||||
SweeperLineModel.getInstance().queryBusLines();
|
||||
}
|
||||
|
||||
public void commitSwitchLineId(int lineId){
|
||||
SweeperLineModel.getInstance().commitSwitchLineId(lineId);
|
||||
}
|
||||
|
||||
public void removeListener(){
|
||||
SweeperLineModel.getInstance().setBusLinesCallback(null);
|
||||
}
|
||||
|
||||
public void queryBusRoutes(){
|
||||
SweeperOrderModel.getInstance().querySweeperRoutes();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDestroy(@NonNull LifecycleOwner owner) {
|
||||
super.onDestroy(owner);
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,37 +1,57 @@
|
||||
package com.mogo.och.sweeper.presenter;
|
||||
|
||||
import static com.mogo.eagle.core.utilcode.mogo.logger.scene.SceneConstant.M_BUS;
|
||||
|
||||
import android.os.Looper;
|
||||
import static com.mogo.eagle.core.utilcode.mogo.logger.scene.SceneConstant.M_SWEEPER;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
import androidx.lifecycle.LifecycleOwner;
|
||||
|
||||
import com.amap.api.maps.model.LatLng;
|
||||
import com.mogo.commons.AbsMogoApplication;
|
||||
import com.mogo.commons.mvp.Presenter;
|
||||
import com.mogo.eagle.core.data.autopilot.AutopilotStatusInfo;
|
||||
import com.mogo.eagle.core.data.config.FunctionBuildConfig;
|
||||
import com.mogo.eagle.core.data.map.MogoLocation;
|
||||
import com.mogo.eagle.core.function.api.autopilot.IMoGoAutopilotStatusListener;
|
||||
import com.mogo.eagle.core.function.api.autopilot.IMoGoSweeperFutianCleanSystemListener;
|
||||
import com.mogo.eagle.core.function.call.autopilot.CallerAutoPilotControlManager;
|
||||
import com.mogo.eagle.core.function.call.autopilot.CallerAutoPilotStatusListenerManager;
|
||||
import com.mogo.eagle.core.function.call.autopilot.CallerSweeperFutianCleanSystemListenerManager;
|
||||
import com.mogo.eagle.core.utilcode.mogo.logger.CallerLogger;
|
||||
import com.mogo.eagle.core.utilcode.util.UiThreadHandler;
|
||||
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.ISlidePannelHideCallback;
|
||||
import com.mogo.eagle.core.utilcode.util.ThreadUtils;
|
||||
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.sweeper.bean.SweeperMainTaskBean;
|
||||
import com.mogo.och.sweeper.bean.SweeperRoutePlanningUpdateReqBean;
|
||||
import com.mogo.och.sweeper.bean.SweeperSubTaskBean;
|
||||
import com.mogo.och.sweeper.bean.SweeperSubTaskDetailBean;
|
||||
import com.mogo.och.sweeper.callback.ISweeperADASStatusCallback;
|
||||
import com.mogo.och.sweeper.callback.ISweeperControllerStatusCallback;
|
||||
import com.mogo.och.sweeper.callback.ISweeperTaskCallback;
|
||||
import com.mogo.och.sweeper.callback.ISweeperTaskRouteCallback;
|
||||
import com.mogo.och.sweeper.constant.SubTaskTypeEnum;
|
||||
import com.mogo.och.sweeper.constant.SweeperConst;
|
||||
import com.mogo.och.sweeper.constant.TaskStatusEnum;
|
||||
import com.mogo.och.sweeper.database.MyDataBase;
|
||||
import com.mogo.och.sweeper.database.bean.WeltDataBean;
|
||||
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.SweeperFutianCmdUtil;
|
||||
import com.mogo.och.sweeper.util.SweeperTrajectoryManager;
|
||||
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.math.RoundingMode;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import chassis.ChassisStatesOuterClass;
|
||||
import mogo.telematics.pad.MessagePad;
|
||||
import mogo_msg.MogoReportMsg;
|
||||
import planning.RoboSweeperTaskIndexOuterClass;
|
||||
import system_master.SystemStatusInfo;
|
||||
|
||||
/**
|
||||
@@ -40,125 +60,59 @@ import system_master.SystemStatusInfo;
|
||||
* @author tongchenfei
|
||||
*/
|
||||
public class SweeperPresenter extends Presenter<SweeperFragment>
|
||||
implements ICarOperationStatusCallback, IRefreshSweeperStationsCallback, ISlidePannelHideCallback
|
||||
, IMoGoAutopilotStatusListener, ISweeperControllerStatusCallback {
|
||||
implements IMoGoAutopilotStatusListener, ISweeperControllerStatusCallback, ISweeperADASStatusCallback,
|
||||
IMoGoSweeperFutianCleanSystemListener, ISweeperTaskCallback, ISweeperTaskRouteCallback {
|
||||
|
||||
private static final String TAG = "BusPresenter";
|
||||
private static final String TAG = "SweeperPresenter";
|
||||
//当前子任务id
|
||||
private int mSubTaskId = 0;
|
||||
// 清扫模式回调时间间隔
|
||||
private static final long VEHICLE_STATE_INTERVAL_MILLIS = 500L;
|
||||
// 清扫模式当前时间戳
|
||||
private long mVehicleStateCurrentTimeMillis;
|
||||
|
||||
private int currentAutopilotStatus = -1;
|
||||
private List<SweeperStationBean> mStationList = new ArrayList<>();
|
||||
private int mCurrentStation = 0;
|
||||
private boolean isRestartAutopilot = false;
|
||||
// 贴边数据回调时间间隔
|
||||
private static final long WELT_DATA_INTERVAL_MILLIS = 1000L;
|
||||
// 贴边数据当前时间戳
|
||||
private long mWeltDataCurrentTimeMillis;
|
||||
|
||||
private String longitude;//经度
|
||||
private String latitude;//纬度
|
||||
|
||||
public SweeperPresenter(SweeperFragment view) {
|
||||
super(view);
|
||||
//2021.11.1 鹰眼架构整合,由IMoGoAutopilotStatusListener逐步替代IMogoAdasOCHCallback接口
|
||||
CallerAutoPilotStatusListenerManager.INSTANCE.addListener(TAG, this);
|
||||
SweeperOrderModel.getInstance().init();
|
||||
//清扫车模式和贴边数据回调监听
|
||||
CallerSweeperFutianCleanSystemListenerManager.INSTANCE.addListener(TAG, this);
|
||||
SweeperTaskModel.getInstance().init();
|
||||
OCHAdasAbilityManager.getInstance().init(AbsMogoApplication.getApp());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onCreate(@NonNull LifecycleOwner owner) {
|
||||
super.onCreate(owner);
|
||||
SweeperOrderModel.getInstance().queryOperationStatus();
|
||||
SweeperOrderModel.getInstance().querySweeperRoutes();
|
||||
initModelListener();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDestroy(@NonNull LifecycleOwner owner) {
|
||||
super.onDestroy(owner);
|
||||
SweeperOrderModel.getInstance().release();
|
||||
SweeperTaskModel.getInstance().release();
|
||||
releaseListener();
|
||||
}
|
||||
|
||||
public void initModelListener() {
|
||||
SweeperOrderModel.getInstance().setCarOperationStatusCallback(this);
|
||||
SweeperOrderModel.getInstance().setRefreshBusStationsCallback(this);
|
||||
SweeperOrderModel.getInstance().setSlidePannelHideCallback(this);
|
||||
SweeperOrderModel.getInstance().setControllerStatusCallback(this);
|
||||
SweeperTaskModel.getInstance().setControllerStatusCallback(this);
|
||||
SweeperTaskModel.getInstance().setAdasStatusCallback(this);
|
||||
SweeperTaskModel.getInstance().setSweeperTaskCallback(this);
|
||||
}
|
||||
|
||||
public void releaseListener() {
|
||||
SweeperOrderModel.getInstance().setCarOperationStatusCallback(null);
|
||||
SweeperOrderModel.getInstance().setRefreshBusStationsCallback(null);
|
||||
SweeperOrderModel.getInstance().setSlidePannelHideCallback(null);
|
||||
SweeperOrderModel.getInstance().setControllerStatusCallback(null);
|
||||
}
|
||||
|
||||
public void querySweepersRoutes() {
|
||||
SweeperOrderModel.getInstance().querySweeperRoutes();
|
||||
}
|
||||
|
||||
public void debugResetStationStatus() {
|
||||
SweeperOrderModel.getInstance().debugResetStationStatus();
|
||||
}
|
||||
|
||||
public void autoDriveToNextStation(boolean isRestart) {
|
||||
currentAutopilotStatus = -1;
|
||||
SweeperOrderModel.getInstance().autoDriveToNextStation(isRestart);
|
||||
isRestartAutopilot = false;
|
||||
}
|
||||
|
||||
public void restartAutopilot() {
|
||||
// if (SweeperOrderModel.getInstance().isGoingToNextStation()){
|
||||
currentAutopilotStatus = -1;
|
||||
SweeperOrderModel.getInstance().restartAutopilot();
|
||||
isRestartAutopilot = true;
|
||||
// }
|
||||
}
|
||||
|
||||
public void onChangeOperationStatus() {
|
||||
SweeperOrderModel.getInstance().onChangeOperationStatus();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void changeOperationStatus(boolean changeStatus) {
|
||||
if (mView != null) {
|
||||
runOnUIThread(() -> mView.changeOperationStatus(changeStatus));
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void refreshBusStations(String lineName,List<SweeperStationBean> stationList
|
||||
, int currentStation, int nextStation, boolean isArrived) {
|
||||
mStationList.clear();
|
||||
mStationList.addAll(stationList);
|
||||
mCurrentStation = currentStation;
|
||||
// functionDemoModeChange();
|
||||
CallerLogger.INSTANCE.d(M_BUS + "BusOrderModel =", " mCurrentStation =" + mCurrentStation);
|
||||
if (mView != null) {
|
||||
runOnUIThread(() -> mView.refreshSweeperStations(lineName,
|
||||
stationList, currentStation, nextStation, isArrived));
|
||||
}
|
||||
}
|
||||
|
||||
private void functionDemoModeChange() {
|
||||
// CallerLogger.INSTANCE.d(M_BUS + "BusOrderModel ="," functionDemoModeChange ="+mCurrentStation);
|
||||
if (FunctionBuildConfig.isDemoMode
|
||||
&& ((mCurrentStation > 0 && mCurrentStation < mStationList.size() - 1)
|
||||
|| ((mCurrentStation == 0 || mCurrentStation == mStationList.size() - 1)
|
||||
&& SweeperOrderModel.getInstance().isGoingToNextStation()))) {
|
||||
runOnUIThread(() -> mView.onAutopilotStatusChanged(
|
||||
IMoGoAutopilotStatusListener.STATUS_AUTOPILOT_RUNNING));
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void hideSlidePanel() {
|
||||
if (mView != null) {
|
||||
runOnUIThread(() -> mView.hideSlidePanel());
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onAutopilotArriveAtStation(MessagePad.ArrivalNotification arrivalNotification) {
|
||||
SweeperOrderModel.getInstance().onArriveAt(arrivalNotification);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onAutopilotSNRequest() {
|
||||
|
||||
SweeperTaskModel.getInstance().setControllerStatusCallback(null);
|
||||
SweeperTaskModel.getInstance().setAdasStatusCallback(null);
|
||||
SweeperTaskModel.getInstance().setSweeperTaskCallback(null);
|
||||
CallerSweeperFutianCleanSystemListenerManager.INSTANCE.removeListener(TAG);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -169,103 +123,88 @@ public class SweeperPresenter extends Presenter<SweeperFragment>
|
||||
@Override
|
||||
public void onAutopilotStatusResponse(@NotNull AutopilotStatusInfo autopilotStatusInfo) {
|
||||
if (autopilotStatusInfo == null) return;
|
||||
int state = autopilotStatusInfo.getState();
|
||||
// CallerLogger.INSTANCE.d(M_BUS + TAG, "onStateChange: " + state + "currentAutopilotStatus = " + currentAutopilotStatus);
|
||||
switch (state) {
|
||||
case IMoGoAutopilotStatusListener.STATUS_AUTOPILOT_ENABLE:
|
||||
if (currentAutopilotStatus != IMoGoAutopilotStatusListener.STATUS_AUTOPILOT_ENABLE) {
|
||||
if (currentAutopilotStatus == IMoGoAutopilotStatusListener.STATUS_AUTOPILOT_RUNNING) {//2-->1语音提示
|
||||
// AIAssist.getInstance( getContext() ).speakTTSVoice( "已进入人工驾驶模式" );
|
||||
CallerLogger.INSTANCE.d(M_SWEEPER + TAG, "onAutopilotStatusResponse state:" + autopilotStatusInfo.getState());
|
||||
SweeperTaskModel.getInstance().setAutopilotState(autopilotStatusInfo.getState());
|
||||
ThreadUtils.runOnUiThread(() -> mView.startAutoBtn(autopilotStatusInfo.getState()));
|
||||
switch (autopilotStatusInfo.getState()) {
|
||||
case IMoGoAutopilotStatusListener.STATUS_AUTOPILOT_DISABLE://不可自动驾驶
|
||||
break;
|
||||
case IMoGoAutopilotStatusListener.STATUS_AUTOPILOT_ENABLE://人工驾驶
|
||||
if (SweeperTaskModel.getInstance().getSubWorking()) {
|
||||
if (FunctionBuildConfig.isDemoMode) {//美化模式开启时
|
||||
SweeperTaskModel.getInstance().startBeautificationMode();
|
||||
}
|
||||
currentAutopilotStatus = IMoGoAutopilotStatusListener.STATUS_AUTOPILOT_ENABLE;
|
||||
// 设置UI【自动驾驶】按钮是否展示
|
||||
runOnUIThread(() -> mView.onAutopilotEnableChange(true));
|
||||
if (SweeperOrderModel.getInstance().isGoingToNextStation()) {
|
||||
runOnUIThread(() -> mView.hideSlidePanel());
|
||||
} else {
|
||||
if (FunctionBuildConfig.isDemoMode) {//美化模式开启时
|
||||
//关闭美化模式
|
||||
SweeperTaskModel.getInstance().closeBeautificationMode();
|
||||
}
|
||||
if (FunctionBuildConfig.isDemoMode
|
||||
&& (
|
||||
(mCurrentStation > 0 && mCurrentStation < mStationList.size() - 1)
|
||||
|| (
|
||||
(mCurrentStation == 0 || mCurrentStation == mStationList.size() - 1)
|
||||
&& SweeperOrderModel.getInstance().isGoingToNextStation()
|
||||
)
|
||||
)
|
||||
) {
|
||||
CallerLogger.INSTANCE.d(M_BUS + "BusOrderModel=", "有美化功能");
|
||||
return;
|
||||
}
|
||||
// 改变UI自动驾驶状态
|
||||
runOnUIThread(() -> mView.onAutopilotStatusChanged(currentAutopilotStatus));
|
||||
}
|
||||
break;
|
||||
case IMoGoAutopilotStatusListener.STATUS_AUTOPILOT_RUNNING:
|
||||
if (currentAutopilotStatus != IMoGoAutopilotStatusListener.STATUS_AUTOPILOT_RUNNING) {
|
||||
currentAutopilotStatus = IMoGoAutopilotStatusListener.STATUS_AUTOPILOT_RUNNING;
|
||||
// 改变UI自动驾驶状态
|
||||
runOnUIThread(() -> mView.onAutopilotStatusChanged(currentAutopilotStatus));
|
||||
SweeperOrderModel.getInstance().triggerStartServiceEvent(
|
||||
isRestartAutopilot, true);
|
||||
case IMoGoAutopilotStatusListener.STATUS_AUTOPILOT_RUNNING://自动驾驶中
|
||||
SweeperTaskModel.getInstance().triggerStartServiceEvent(
|
||||
SweeperTaskModel.getInstance().isRestartAutopilot(), true);
|
||||
if (SweeperTaskModel.getInstance().getSubWorking()) {
|
||||
if (FunctionBuildConfig.isDemoMode) {//美化模式开启时
|
||||
SweeperTaskModel.getInstance().startBeautificationMode();
|
||||
}
|
||||
}
|
||||
break;
|
||||
case IMoGoAutopilotStatusListener.STATUS_AUTOPILOT_DISABLE:
|
||||
if (currentAutopilotStatus != IMoGoAutopilotStatusListener.STATUS_AUTOPILOT_DISABLE) {
|
||||
if (currentAutopilotStatus == IMoGoAutopilotStatusListener.STATUS_AUTOPILOT_RUNNING) {//2-->0语音提示
|
||||
// AIAssist.getInstance( getContext() ).speakTTSVoice( "自动驾驶已停止,请人工接管" );
|
||||
case IMoGoAutopilotStatusListener.STATUS_PARALLEL_DRIVING://平行驾驶
|
||||
if (SweeperTaskModel.getInstance().getSubWorking()) {
|
||||
if (FunctionBuildConfig.isDemoMode) {//美化模式开启时
|
||||
FunctionBuildConfig.isIgnoreConditionsDrawAutopilotTrajectoryData = true;//是否强制绘制引导线
|
||||
CallerAutoPilotControlManager.INSTANCE.setIPCDemoMode(false);//是否自动启动自驾
|
||||
}
|
||||
currentAutopilotStatus = IMoGoAutopilotStatusListener.STATUS_AUTOPILOT_DISABLE;
|
||||
if (FunctionBuildConfig.isDemoMode
|
||||
&& (
|
||||
(mCurrentStation > 0 && mCurrentStation < mStationList.size() - 1)
|
||||
|| (
|
||||
(mCurrentStation == 0 || mCurrentStation == mStationList.size() - 1)
|
||||
&& SweeperOrderModel.getInstance().isGoingToNextStation()
|
||||
)
|
||||
)
|
||||
) {
|
||||
CallerLogger.INSTANCE.d(M_BUS + "BusOrderModel=", "有美化功能");
|
||||
return;
|
||||
} else {
|
||||
if (FunctionBuildConfig.isDemoMode) {//美化模式开启时
|
||||
//关闭美化模式
|
||||
SweeperTaskModel.getInstance().closeBeautificationMode();
|
||||
}
|
||||
runOnUIThread(() -> {
|
||||
mView.onAutopilotStatusChanged(currentAutopilotStatus);
|
||||
});
|
||||
}
|
||||
break;
|
||||
default:
|
||||
runOnUIThread(() -> mView.onAutopilotEnableChange(false));
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onVRModeChanged(boolean isVRMode) {
|
||||
runOnUIThread(() -> mView.onVRModeChanged(isVRMode));
|
||||
ThreadUtils.runOnUiThread(() -> mView.onVRModeChanged(isVRMode));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onCarLocationChanged(MogoLocation location) {
|
||||
if (null != location) {
|
||||
runOnUIThread(() -> mView.updateSpeedView((float) location.getGnssSpeed()));
|
||||
ThreadUtils.runOnUiThread(() -> mView.updateSpeedView((float) location.getGnssSpeed()));
|
||||
ThreadUtils.runOnUiThread(() -> mView.setCurrentLocation(location));
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void startOpenAutopilot() {
|
||||
//非美化模式下启动动画
|
||||
runOnUIThread(() -> mView.startAutopilotAnimation());
|
||||
|
||||
}
|
||||
/**
|
||||
* 清除路线缓存数据
|
||||
*/
|
||||
public void clearRouteList(){
|
||||
SweeperTaskModel.getInstance().clearRouteList();
|
||||
}
|
||||
public void startAutopilot() {
|
||||
SweeperTaskModel.getInstance().startAutopilot();
|
||||
}
|
||||
|
||||
private void runOnUIThread(Runnable executor) {
|
||||
if (executor == null) {
|
||||
return;
|
||||
}
|
||||
if (Looper.myLooper() != Looper.getMainLooper()) {
|
||||
UiThreadHandler.post(executor);
|
||||
} else {
|
||||
executor.run();
|
||||
}
|
||||
/**
|
||||
* 设置当前子任务信息
|
||||
*/
|
||||
public void setSubtask(boolean isFirstSubtask, boolean isLastSubtask, int subTaskId,int subTaskType) {
|
||||
this.mSubTaskId = subTaskId;
|
||||
SweeperTaskModel.getInstance().setSubtask(isFirstSubtask, isLastSubtask, subTaskId,subTaskType);
|
||||
}
|
||||
public void setWorking(boolean isWorking){
|
||||
SweeperTaskModel.getInstance().setWorking(isWorking);
|
||||
}
|
||||
|
||||
/**
|
||||
* 测试使用
|
||||
*
|
||||
@@ -290,4 +229,228 @@ public class SweeperPresenter extends Presenter<SweeperFragment>
|
||||
public void onAutopilotStatusRespByQuery(@NonNull SystemStatusInfo.StatusInfo status) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onAutopilotArriveAtStation(@Nullable MessagePad.ArrivalNotification arrivalNotification) {
|
||||
SweeperTaskModel.getInstance().onArriveTaskEnd(arrivalNotification);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onAutopilotSNRequest() {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onStartAdasFailure() {
|
||||
|
||||
}
|
||||
|
||||
public void onArriveTaskEnd(@Nullable MessagePad.ArrivalNotification arrivalNotification) {
|
||||
SweeperTaskModel.getInstance().onArriveTaskEnd(arrivalNotification);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onSweeperFutianCleanSystemState(@NonNull ChassisStatesOuterClass.SweeperFuTianTaskSystemStates cleanSystemState) {
|
||||
if (cleanSystemState == null) {
|
||||
return;
|
||||
}
|
||||
long current = System.currentTimeMillis();
|
||||
if (current - mVehicleStateCurrentTimeMillis <= VEHICLE_STATE_INTERVAL_MILLIS) {
|
||||
return;
|
||||
}
|
||||
mVehicleStateCurrentTimeMillis = current;
|
||||
boolean clean_open_requirement = cleanSystemState.getSecuMotWorkSts();
|
||||
// 洗扫
|
||||
boolean clean_mode_wash_sweep = cleanSystemState.getSecuModWashSweepSts();
|
||||
// 纯洗
|
||||
boolean clean_mode_pure_wash = cleanSystemState.getSecuModWashSts();
|
||||
// 纯吸
|
||||
boolean clean_mode_pure_draw = cleanSystemState.getSecuWorkTonSts();
|
||||
// 左侧
|
||||
boolean clean_direction_left_side = cleanSystemState.getSecuWorkLeftSts();
|
||||
// 右侧
|
||||
boolean clean_direction_right_side = cleanSystemState.getSecuWorkRightSts();
|
||||
// 两侧
|
||||
boolean clean_direction_both_side = cleanSystemState.getSecuWorkOnBothsidesSts();
|
||||
// 作业强度状态
|
||||
boolean clean_intensity_standard = cleanSystemState.getSecuWorkStandSts();
|
||||
boolean clean_intensity_strong = cleanSystemState.getSecuWorkStrongSts();
|
||||
|
||||
// 纯扫 模式判断:不是另外其他3个模式,同时有清扫方向,说明开启了纯扫模式
|
||||
boolean clean_mode_pure_sweep = SweeperFutianCmdUtil.checkIfCleanModePureSweep(cleanSystemState);
|
||||
|
||||
StringBuilder stringBuilder = new StringBuilder();
|
||||
stringBuilder.append("开关:")
|
||||
.append(clean_open_requirement)
|
||||
.append("\n")
|
||||
.append("纯扫:")
|
||||
.append(clean_mode_wash_sweep)
|
||||
.append("纯洗:")
|
||||
.append(clean_mode_pure_wash)
|
||||
.append("纯吸:")
|
||||
.append(clean_mode_pure_draw)
|
||||
.append("纯扫:")
|
||||
.append("\n")
|
||||
.append(clean_mode_pure_sweep)
|
||||
.append("左侧:")
|
||||
.append(clean_direction_left_side)
|
||||
.append("右侧:")
|
||||
.append(clean_direction_right_side)
|
||||
.append("两侧:")
|
||||
.append("\n")
|
||||
.append(clean_direction_both_side)
|
||||
.append("标准:")
|
||||
.append(clean_intensity_standard)
|
||||
.append("强力:")
|
||||
.append(clean_intensity_strong);
|
||||
|
||||
CallerLogger.INSTANCE.d(M_SWEEPER + TAG, "onSweeperFutianCleanSystemState:" + stringBuilder);
|
||||
mView.onSweeperFutianCleanSystemState(cleanSystemState);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onSweeperFutianTaskIndexData(@NonNull RoboSweeperTaskIndexOuterClass.RoboSweeperTaskIndex roboSweeperTaskIndex) {
|
||||
if (roboSweeperTaskIndex == null) {
|
||||
return;
|
||||
}
|
||||
long current = System.currentTimeMillis();
|
||||
if (current - mWeltDataCurrentTimeMillis <= WELT_DATA_INTERVAL_MILLIS) {
|
||||
return;
|
||||
}
|
||||
mWeltDataCurrentTimeMillis = current;
|
||||
StringBuilder stringBuilder = new StringBuilder();
|
||||
stringBuilder.append("清扫模式:")
|
||||
.append(roboSweeperTaskIndex.getCleanMode())
|
||||
.append("清扫方向:")
|
||||
.append(roboSweeperTaskIndex.getCleanDirection())
|
||||
.append("清扫强度:")
|
||||
.append(roboSweeperTaskIndex.getCleanIntensity())
|
||||
.append("贴边距离:")
|
||||
.append(roboSweeperTaskIndex.getDistToRefEdgePoint())
|
||||
.append("经度:")
|
||||
.append(roboSweeperTaskIndex.getLocLon())
|
||||
.append("纬度:")
|
||||
.append(roboSweeperTaskIndex.getLocLat());
|
||||
CallerLogger.INSTANCE.d(M_SWEEPER + TAG, "onSweeperFutianTaskIndexData:" + stringBuilder);
|
||||
String tempLongitude=NumberFormatUtil.cutOutNumber(roboSweeperTaskIndex.getLocLon(), 6);
|
||||
String tempLatitude=NumberFormatUtil.cutOutNumber(roboSweeperTaskIndex.getLocLat(), 6);
|
||||
//用于过滤车是否停在原地,经纬度相同的情况
|
||||
if (!tempLongitude.equals(longitude)&&!tempLatitude.equals(latitude)){
|
||||
latitude = NumberFormatUtil.cutOutNumber(roboSweeperTaskIndex.getLocLat(), 6);
|
||||
longitude = NumberFormatUtil.cutOutNumber(roboSweeperTaskIndex.getLocLon(), 6);
|
||||
//保存贴边数据到数据库中
|
||||
WeltDataBean weltDataBean = new WeltDataBean();
|
||||
//把wgs坐标系坐标转换成gcj坐标
|
||||
LatLng latLng = CoordinateCalculateRouteUtil.coordinateConverterWgsToGcj(AbsMogoApplication.getApp(), roboSweeperTaskIndex.getLocLon(),
|
||||
roboSweeperTaskIndex.getLocLat());
|
||||
weltDataBean.setLocLon(latLng.longitude);
|
||||
weltDataBean.setLocLat(latLng.latitude);
|
||||
int edgeCleanState = roboSweeperTaskIndex.getEdgeCleanState();
|
||||
if(edgeCleanState==0){
|
||||
weltDataBean.setWeltDistance(SweeperConst.NONWELT);
|
||||
}else {
|
||||
weltDataBean.setWeltDistance(roboSweeperTaskIndex.getDistToRefEdgePoint());
|
||||
}
|
||||
weltDataBean.setCleanMode(roboSweeperTaskIndex.getCleanMode());
|
||||
weltDataBean.setCleanDirection(roboSweeperTaskIndex.getCleanDirection());
|
||||
weltDataBean.setCleanIntensity(roboSweeperTaskIndex.getCleanIntensity());
|
||||
weltDataBean.setSubTaskId(mSubTaskId);
|
||||
MyDataBase.getInstance().getWeltDataDao().insert(weltDataBean);
|
||||
String distance = String.valueOf((Math.round(roboSweeperTaskIndex.getDistToRefEdgePoint() * 100)));//m->cm 四舍五入到整数
|
||||
mView.setWeltDataToMap((ArrayList<WeltDataBean>) MyDataBase.getInstance().getWeltDataDao().loadAllWeltDataInfo(), true, distance);
|
||||
}
|
||||
}
|
||||
|
||||
public static String format(double value) {
|
||||
BigDecimal bd = new BigDecimal(value);
|
||||
bd = bd.setScale(2, RoundingMode.HALF_UP);
|
||||
return bd.toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取当前正在执行的任务
|
||||
*/
|
||||
public void getCurrentTask() {
|
||||
SweeperTaskModel.getInstance().getCurrentTask();
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取主任务列表
|
||||
*/
|
||||
public void getMainTaskList(boolean refresh) {
|
||||
SweeperTaskModel.getInstance().getMainTaskList(refresh);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取子任务列表
|
||||
*/
|
||||
public void getSubTaskList(int taskId, SweeperSubTaskBean sweeperSubTaskBean) {
|
||||
SweeperTaskModel.getInstance().getSubTaskList(taskId, sweeperSubTaskBean);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取子任务详情包括轨迹文件信息
|
||||
*/
|
||||
public void getSubTaskDetail(boolean isFirst, boolean isEnd, int subTaskId, SubTaskTypeEnum subTaskType, boolean isStartSubtask) {
|
||||
SweeperTaskModel.getInstance().getSubTaskDetail(isFirst, isEnd, subTaskId, subTaskType, isStartSubtask);
|
||||
}
|
||||
|
||||
/**
|
||||
* 开始任务
|
||||
*/
|
||||
public void startTask(boolean isFirst, boolean isEnd, int subTaskId, SubTaskTypeEnum subTaskType, int subTaskStatus) {
|
||||
if (SubTaskTypeEnum.AUTOPILOT_SUBTYPE.getCode() == subTaskStatus) {
|
||||
SweeperTaskModel.getInstance().subTaskStart(isFirst, isEnd, subTaskId, subTaskType);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 子任务结束上报
|
||||
*/
|
||||
public void subTaskEnd(boolean isFirst, boolean isEnd, int subTaskId) {
|
||||
SweeperTaskModel.getInstance().subTaskEnd(isFirst, isEnd, subTaskId);
|
||||
}
|
||||
|
||||
/**
|
||||
* 子任务跳过上报
|
||||
*/
|
||||
public void subTaskSkip(boolean isFirst, boolean isEnd, int subTaskId) {
|
||||
SweeperTaskModel.getInstance().subTaskSkip(isFirst, isEnd, subTaskId);
|
||||
}
|
||||
|
||||
/**
|
||||
* 主任务重置
|
||||
*/
|
||||
public void mainTaskReset(int taskId) {
|
||||
SweeperTaskModel.getInstance().mainTaskReset(taskId);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setMainTaskList(List<SweeperMainTaskBean> mainTaskBeanList,boolean refresh) {
|
||||
mView.setMainTaskList(mainTaskBeanList,refresh);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setSubTaskBean(SweeperSubTaskBean subTaskBean, boolean isWorkingSubTask) {
|
||||
mView.setSubTaskBean(subTaskBean, isWorkingSubTask);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateSubTaskStatus(TaskStatusEnum typeEnum, boolean isLastSubTask) {
|
||||
mView.updateSubTaskStatus(typeEnum, isLastSubTask);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setMainTaskReset(boolean isSuccess) {
|
||||
mView.setMainTaskReset(isSuccess);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setSubTakDetail(@NonNull SweeperSubTaskDetailBean subTaskDetailBean, SubTaskTypeEnum subTaskTypeEnum) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setRouteList(@NonNull ArrayList<SweeperRoutePlanningUpdateReqBean.Result> routeList) {
|
||||
mView.setTaskRouteList(routeList);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -10,30 +10,32 @@ import static com.mogo.och.sweeper.util.SweeperFutianCmdUtil.CLEAN_MODE_PURE_SWE
|
||||
import static com.mogo.och.sweeper.util.SweeperFutianCmdUtil.CLEAN_MODE_PURE_WASH;
|
||||
import static com.mogo.och.sweeper.util.SweeperFutianCmdUtil.CLEAN_MODE_WASH_SWEEP;
|
||||
|
||||
import android.animation.ObjectAnimator;
|
||||
import android.content.Context;
|
||||
import android.content.DialogInterface;
|
||||
import android.os.Handler;
|
||||
import android.os.Message;
|
||||
import android.util.AttributeSet;
|
||||
import android.util.Log;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.animation.LinearInterpolator;
|
||||
import android.widget.CheckedTextView;
|
||||
import android.widget.FrameLayout;
|
||||
import android.widget.ImageView;
|
||||
import android.widget.LinearLayout;
|
||||
import android.widget.TextView;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
import androidx.appcompat.app.AlertDialog;
|
||||
|
||||
import com.mogo.eagle.core.function.api.autopilot.IMoGoSweeperFutianCleanSystemListener;
|
||||
import com.mogo.eagle.core.function.call.autopilot.CallerAutoPilotControlManager;
|
||||
import com.mogo.eagle.core.function.call.autopilot.CallerSweeperFutianCleanSystemListenerManager;
|
||||
import com.mogo.eagle.core.utilcode.mogo.view.OnPreventFastClickListener;
|
||||
import com.mogo.eagle.core.utilcode.util.ThreadUtils;
|
||||
import com.mogo.eagle.core.utilcode.util.ToastUtils;
|
||||
import com.mogo.och.sweeper.R;
|
||||
import com.mogo.och.sweeper.callback.ICleaningModeStateCallback;
|
||||
import com.mogo.och.sweeper.constant.OperateStateEnum;
|
||||
import com.mogo.och.sweeper.util.SweeperFutianCmdUtil;
|
||||
import com.mogo.och.sweeper.view.NoTouchConstraintLayout;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.HashMap;
|
||||
@@ -42,6 +44,11 @@ import java.util.List;
|
||||
import chassis.ChassisStatesOuterClass;
|
||||
import chassis.SpecialVehicleTaskCmdOuterClass;
|
||||
|
||||
import static com.mogo.och.sweeper.util.SweeperFutianCmdUtil.CLEAN_DIRECTION_CLOSE;
|
||||
import static com.mogo.och.sweeper.util.SweeperFutianCmdUtil.CLEAN_MODE_CLOSE;
|
||||
import static com.mogo.och.sweeper.util.SweeperFutianCmdUtil.CLEAN_WORK_CLOSE;
|
||||
import static com.mogo.och.sweeper.util.SweeperFutianCmdUtil.CLEAN_WORK_OPEN;
|
||||
|
||||
/**
|
||||
* 清扫车操作面板View
|
||||
*/
|
||||
@@ -50,6 +57,7 @@ public class SweeperOperatePanelView extends LinearLayout {
|
||||
private static final String TAG = "SweeperOperatePanelView";
|
||||
private static final int CMD_EXECUTE_TIMEOUT_SECONDS = 30;
|
||||
private static final int CMD_EXECUTE_MOCK_SUCCESS_SECONDS = 3;
|
||||
private boolean isFirst = false;
|
||||
|
||||
CheckedTextView mBtnCleanWorkOpenClose;//开关
|
||||
CheckedTextView mBtnCleanModePureSweep;//纯扫
|
||||
@@ -61,9 +69,10 @@ public class SweeperOperatePanelView extends LinearLayout {
|
||||
CheckedTextView mBtnCleanDirectionBothSide;//两侧
|
||||
CheckedTextView mBtnCleanIntensityStandard;//普通
|
||||
CheckedTextView mBtnCleanIntensityStrong;//强力
|
||||
LinearLayout mLoadingContainer;//loading container
|
||||
TextView mLoadingHintTop;//loading 提示-上面
|
||||
TextView mLoadingHintBottom;//loading 提示-下面
|
||||
FrameLayout mLoadingContainer;//loading container
|
||||
TextView mLoadingHint;//loading 文本提示
|
||||
ImageView mLoadingView;//loading 转圈动画
|
||||
NoTouchConstraintLayout mWorkmodePanelRootView;
|
||||
|
||||
// 作业模式相关操作按钮的id
|
||||
List<Integer> cleanModeBtnViewIds = Arrays.asList(
|
||||
@@ -109,6 +118,15 @@ public class SweeperOperatePanelView extends LinearLayout {
|
||||
put(R.id.btn_clean_intensity_strong, CLEAN_INTENSITY_STRONG);
|
||||
}
|
||||
};
|
||||
private boolean isSelectPureSweepMode = false;//用于标注是否选中纯扫
|
||||
|
||||
private ICleaningModeStateCallback cleaningModeStateCallback;
|
||||
|
||||
private OperateStateEnum operateStateEnum = OperateStateEnum.SYNCING_STATUS;
|
||||
|
||||
private ObjectAnimator objectAnimator;
|
||||
|
||||
private static ChassisStatesOuterClass.SweeperFuTianTaskSystemStates mCurrentCleanSystemState;//当前作业模式
|
||||
|
||||
public SweeperOperatePanelView(Context context) {
|
||||
super(context);
|
||||
@@ -132,6 +150,7 @@ public class SweeperOperatePanelView extends LinearLayout {
|
||||
private void initView(Context context) {
|
||||
LayoutInflater.from(context).inflate(R.layout.sweeper_operate_panel_view, this, true);
|
||||
mBtnCleanWorkOpenClose = (CheckedTextView) findViewById(R.id.btn_clean_work_open_close);
|
||||
mWorkmodePanelRootView = (NoTouchConstraintLayout) findViewById(R.id.work_mode_panel_root_view);
|
||||
mBtnCleanModePureSweep = (CheckedTextView) findViewById(R.id.btn_clean_mode_pure_sweep);
|
||||
mBtnCleanModePureWash = (CheckedTextView) findViewById(R.id.btn_clean_mode_pure_wash);
|
||||
mBtnCleanModeSweepWash = (CheckedTextView) findViewById(R.id.btn_clean_mode_sweep_wash);
|
||||
@@ -142,8 +161,8 @@ public class SweeperOperatePanelView extends LinearLayout {
|
||||
mBtnCleanIntensityStandard = (CheckedTextView) findViewById(R.id.btn_clean_intensity_standard);
|
||||
mBtnCleanIntensityStrong = (CheckedTextView) findViewById(R.id.btn_clean_intensity_strong);
|
||||
mLoadingContainer = findViewById(R.id.loading_hint_container);
|
||||
mLoadingHintTop = findViewById(R.id.loading_hint_top);
|
||||
mLoadingHintBottom = findViewById(R.id.loading_hint_bottom);
|
||||
mLoadingHint = findViewById(R.id.loading_hint);
|
||||
mLoadingView = findViewById(R.id.loading_view);
|
||||
initViewListener();
|
||||
}
|
||||
|
||||
@@ -193,21 +212,19 @@ public class SweeperOperatePanelView extends LinearLayout {
|
||||
|
||||
@Override
|
||||
public void onCmdSuccess() {
|
||||
runOnUIThread(() -> {
|
||||
if (isCloseAction) {
|
||||
mBtnCleanWorkOpenClose.setText("Open");
|
||||
mBtnCleanWorkOpenClose.setChecked(false);
|
||||
toggleCleanModeBtnsStatus(false);
|
||||
toggleCleanDirectionBtnsStatus(false);
|
||||
toggleCleanIntensityBtnsStatus(false);
|
||||
} else {
|
||||
mBtnCleanWorkOpenClose.setText("Close");
|
||||
mBtnCleanWorkOpenClose.setChecked(true);
|
||||
toggleCleanModeBtnsStatus(true);
|
||||
}
|
||||
hideLoadingMask();
|
||||
showCmdExecuteSuccessToast();
|
||||
});
|
||||
if (isCloseAction) {
|
||||
mBtnCleanWorkOpenClose.setText("打开");
|
||||
mBtnCleanWorkOpenClose.setChecked(false);
|
||||
toggleCleanModeBtnsStatus(false);
|
||||
toggleCleanDirectionBtnsStatus(false);
|
||||
toggleCleanIntensityBtnsStatus(false);
|
||||
} else {
|
||||
mBtnCleanWorkOpenClose.setText("关闭");
|
||||
mBtnCleanWorkOpenClose.setChecked(true);
|
||||
toggleCleanModeBtnsStatus(true);
|
||||
}
|
||||
hideLoadingMask();
|
||||
showCmdExecuteSuccessToast();
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -217,27 +234,23 @@ public class SweeperOperatePanelView extends LinearLayout {
|
||||
@Override
|
||||
public void onCmdTimeout() {
|
||||
//按钮样式恢复原样
|
||||
runOnUIThread(() -> {
|
||||
if (isCloseAction) {
|
||||
mBtnCleanWorkOpenClose.setText("Close");
|
||||
mBtnCleanWorkOpenClose.setChecked(true);
|
||||
} else {
|
||||
mBtnCleanWorkOpenClose.setText("Open");
|
||||
mBtnCleanWorkOpenClose.setChecked(false);
|
||||
}
|
||||
hideLoadingMask();
|
||||
showCmdExecuteTimeoutToast();
|
||||
});
|
||||
if (isCloseAction) {
|
||||
mBtnCleanWorkOpenClose.setText("关闭");
|
||||
mBtnCleanWorkOpenClose.setChecked(true);
|
||||
} else {
|
||||
mBtnCleanWorkOpenClose.setText("打开");
|
||||
mBtnCleanWorkOpenClose.setChecked(false);
|
||||
}
|
||||
hideLoadingMask();
|
||||
showCmdExecuteTimeoutToast();
|
||||
}
|
||||
};
|
||||
if (isCloseAction) {
|
||||
//关闭操作,点击时需要弹框提示确认后,关闭
|
||||
showConfirmCleanWorkCloseDialog(() -> {
|
||||
sendSweeperCmd(
|
||||
SweeperFutianCmdUtil.buildCleanWorkStopCmd(),
|
||||
cmdRequestCallback
|
||||
, CMD_EXECUTE_TIMEOUT_SECONDS);
|
||||
});
|
||||
sendSweeperCmd(
|
||||
SweeperFutianCmdUtil.buildCleanWorkStopCmd(),
|
||||
cmdRequestCallback
|
||||
, CMD_EXECUTE_TIMEOUT_SECONDS);
|
||||
} else {
|
||||
//打开操作,点击时打开
|
||||
sendSweeperCmd(
|
||||
@@ -271,7 +284,6 @@ public class SweeperOperatePanelView extends LinearLayout {
|
||||
boolean isPureSweepClick = currentClickView.getId() == R.id.btn_clean_mode_pure_sweep;
|
||||
//是否洗扫View
|
||||
boolean isWashSweepClick = currentClickView.getId() == R.id.btn_clean_mode_sweep_wash;
|
||||
|
||||
CmdRequestCallback cmdRequestCallback = new CmdRequestCallback() {
|
||||
@Override
|
||||
public void onSendCmd() {
|
||||
@@ -296,7 +308,7 @@ public class SweeperOperatePanelView extends LinearLayout {
|
||||
// 纯吸
|
||||
boolean clean_mode_pure_draw = cleanSystemState.getSecuWorkTonSts();
|
||||
// 纯扫 模式判断:不是另外其他3个模式,同时有清扫方向,说明开启了纯扫模式
|
||||
boolean clean_mode_pure_sweep = checkIfCleanModePureSweep(cleanSystemState);
|
||||
boolean clean_mode_pure_sweep = SweeperFutianCmdUtil.checkIfCleanModePureSweep(cleanSystemState);
|
||||
// 关闭作业模式(实际执行了3个操作: 关闭作业模式 关闭清扫方向 切换标准强度,实际以关闭作业模式成功为准)
|
||||
boolean clean_mode_close = !clean_mode_wash_sweep
|
||||
&& !clean_mode_pure_wash
|
||||
@@ -305,41 +317,44 @@ public class SweeperOperatePanelView extends LinearLayout {
|
||||
|
||||
if (isClickCurrentChoosedModeBtn && clean_mode_close) {// 关闭放第一判断
|
||||
success = clean_mode_close;
|
||||
isSelectPureSweepMode = false;
|
||||
} else if (isPureSweepClick) {
|
||||
//success = clean_mode_pure_sweep;
|
||||
//纯扫 这个模式实际在福田清扫车上没有这个按钮,只是发送指令给特种车端,默认此命令肯定是正确的
|
||||
success = true;
|
||||
isSelectPureSweepMode = true;
|
||||
} else if (isPureWashClick) {
|
||||
success = clean_mode_pure_wash;
|
||||
isSelectPureSweepMode = false;
|
||||
} else if (isWashSweepClick) {
|
||||
success = clean_mode_wash_sweep;
|
||||
isSelectPureSweepMode = false;
|
||||
} else if (isPureAbsorptionClick) {
|
||||
success = clean_mode_pure_draw;
|
||||
isSelectPureSweepMode = false;
|
||||
}
|
||||
return success;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onCmdSuccess() {
|
||||
runOnUIThread(() -> {
|
||||
((CheckedTextView) currentClickView).setChecked(!isClickCurrentChoosedModeBtn);
|
||||
toggleCleanModeBtnsByChoosedViewId(currentClickView.getId(), isClickCurrentChoosedModeBtn);
|
||||
if (isClickCurrentChoosedModeBtn) {
|
||||
((CheckedTextView) currentClickView).setChecked(!isClickCurrentChoosedModeBtn);
|
||||
toggleCleanModeBtnsByChoosedViewId(currentClickView.getId(), isClickCurrentChoosedModeBtn);
|
||||
if (isClickCurrentChoosedModeBtn) {
|
||||
toggleCleanDirectionBtnsStatus(false);
|
||||
toggleCleanIntensityBtnsStatus(false);
|
||||
} else {
|
||||
// 如果是纯吸,没有设置清扫方向,同时自动设置作业强度为标准
|
||||
if (isPureAbsorptionClick) {
|
||||
toggleCleanDirectionBtnsStatus(false);
|
||||
toggleCleanIntensityBtnsStatus(false);
|
||||
setCleanIntensityStandard();
|
||||
} else {
|
||||
// 如果是纯吸,没有设置清扫方向,同时自动设置作业强度为标准
|
||||
if (isPureAbsorptionClick) {
|
||||
toggleCleanDirectionBtnsStatus(false);
|
||||
setCleanIntensityStandard();
|
||||
} else {
|
||||
toggleCleanDirectionBtnsStatus(true);
|
||||
toggleCleanIntensityBtnsStatus(false);
|
||||
}
|
||||
toggleCleanDirectionBtnsStatus(true);
|
||||
toggleCleanIntensityBtnsStatus(false);
|
||||
}
|
||||
hideLoadingMask();
|
||||
showCmdExecuteSuccessToast();
|
||||
});
|
||||
}
|
||||
hideLoadingMask();
|
||||
showCmdExecuteSuccessToast();
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -348,11 +363,9 @@ public class SweeperOperatePanelView extends LinearLayout {
|
||||
|
||||
@Override
|
||||
public void onCmdTimeout() {
|
||||
runOnUIThread(() -> {
|
||||
((CheckedTextView) currentClickView).setChecked(isClickCurrentChoosedModeBtn);
|
||||
hideLoadingMask();
|
||||
showCmdExecuteTimeoutToast();
|
||||
});
|
||||
((CheckedTextView) currentClickView).setChecked(isClickCurrentChoosedModeBtn);
|
||||
hideLoadingMask();
|
||||
showCmdExecuteTimeoutToast();
|
||||
}
|
||||
};
|
||||
|
||||
@@ -388,8 +401,6 @@ public class SweeperOperatePanelView extends LinearLayout {
|
||||
boolean isLeftSide = currentClickView.getId() == R.id.btn_clean_direction_left_side;
|
||||
boolean isRightSide = currentClickView.getId() == R.id.btn_clean_direction_right_side;
|
||||
boolean isBothSide = currentClickView.getId() == R.id.btn_clean_direction_both_side;
|
||||
|
||||
|
||||
CmdRequestCallback cmdRequestCallback = new CmdRequestCallback() {
|
||||
@Override
|
||||
public void onSendCmd() {
|
||||
@@ -431,19 +442,17 @@ public class SweeperOperatePanelView extends LinearLayout {
|
||||
|
||||
@Override
|
||||
public void onCmdSuccess() {
|
||||
runOnUIThread(() -> {
|
||||
((CheckedTextView) currentClickView).setChecked(!isClickCurrentChoosedDirectionBtn);
|
||||
toggleCleanDirectionBtnsByChoosedViewId(currentClickView.getId(), isClickCurrentChoosedDirectionBtn);
|
||||
if (isClickCurrentChoosedDirectionBtn) {
|
||||
toggleCleanIntensityBtnsStatus(false);
|
||||
} else {
|
||||
toggleCleanIntensityBtnsStatus(true);
|
||||
// 一并设置作业强度为标准
|
||||
setCleanIntensityStandard();
|
||||
}
|
||||
hideLoadingMask();
|
||||
showCmdExecuteSuccessToast();
|
||||
});
|
||||
((CheckedTextView) currentClickView).setChecked(!isClickCurrentChoosedDirectionBtn);
|
||||
toggleCleanDirectionBtnsByChoosedViewId(currentClickView.getId(), isClickCurrentChoosedDirectionBtn);
|
||||
if (isClickCurrentChoosedDirectionBtn) {
|
||||
toggleCleanIntensityBtnsStatus(false);
|
||||
} else {
|
||||
toggleCleanIntensityBtnsStatus(true);
|
||||
// 一并设置作业强度为标准
|
||||
setCleanIntensityStandard();
|
||||
}
|
||||
hideLoadingMask();
|
||||
showCmdExecuteSuccessToast();
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -452,11 +461,9 @@ public class SweeperOperatePanelView extends LinearLayout {
|
||||
|
||||
@Override
|
||||
public void onCmdTimeout() {
|
||||
runOnUIThread(() -> {
|
||||
((CheckedTextView) currentClickView).setChecked(isClickCurrentChoosedDirectionBtn);
|
||||
hideLoadingMask();
|
||||
showCmdExecuteTimeoutToast();
|
||||
});
|
||||
((CheckedTextView) currentClickView).setChecked(isClickCurrentChoosedDirectionBtn);
|
||||
hideLoadingMask();
|
||||
showCmdExecuteTimeoutToast();
|
||||
}
|
||||
};
|
||||
if (isClickCurrentChoosedDirectionBtn) {
|
||||
@@ -476,6 +483,20 @@ public class SweeperOperatePanelView extends LinearLayout {
|
||||
}
|
||||
|
||||
private void onCleanIntensityBtnClick(final View currentClickView) {
|
||||
CheckedTextView currentChoosedModeBtnView = null;
|
||||
for (Integer viewId : cleanIntensityBtnViewIds) {
|
||||
CheckedTextView view = (CheckedTextView) findViewById(viewId);
|
||||
if (view.isChecked()) {
|
||||
currentChoosedModeBtnView = view;
|
||||
break;
|
||||
}
|
||||
}
|
||||
boolean isClickCurrentChoosedModeBtn = currentChoosedModeBtnView != null
|
||||
&& currentChoosedModeBtnView.getId() == currentClickView.getId();
|
||||
//作业强度如果已经选中,则重复点击时不需要再重复发送指令
|
||||
if (isClickCurrentChoosedModeBtn) {
|
||||
return;
|
||||
}
|
||||
boolean isStandardBtnClick = currentClickView.getId() == R.id.btn_clean_intensity_standard;
|
||||
boolean isStrongBtnClick = currentClickView.getId() == R.id.btn_clean_intensity_strong;
|
||||
CmdRequestCallback cmdRequestCallback = new CmdRequestCallback() {
|
||||
@@ -507,16 +528,14 @@ public class SweeperOperatePanelView extends LinearLayout {
|
||||
|
||||
@Override
|
||||
public void onCmdSuccess() {
|
||||
runOnUIThread(() -> {
|
||||
((CheckedTextView) currentClickView).setChecked(true);
|
||||
if (isStandardBtnClick) {
|
||||
setCleanIntensityStandard();
|
||||
} else {
|
||||
setCleanIntensityStrong();
|
||||
}
|
||||
hideLoadingMask();
|
||||
showCmdExecuteSuccessToast();
|
||||
});
|
||||
((CheckedTextView) currentClickView).setChecked(true);
|
||||
if (isStandardBtnClick) {
|
||||
setCleanIntensityStandard();
|
||||
} else {
|
||||
setCleanIntensityStrong();
|
||||
}
|
||||
hideLoadingMask();
|
||||
showCmdExecuteSuccessToast();
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -525,11 +544,9 @@ public class SweeperOperatePanelView extends LinearLayout {
|
||||
|
||||
@Override
|
||||
public void onCmdTimeout() {
|
||||
runOnUIThread(() -> {
|
||||
((CheckedTextView) currentClickView).setChecked(false);
|
||||
hideLoadingMask();
|
||||
showCmdExecuteTimeoutToast();
|
||||
});
|
||||
((CheckedTextView) currentClickView).setChecked(false);
|
||||
hideLoadingMask();
|
||||
showCmdExecuteTimeoutToast();
|
||||
}
|
||||
};
|
||||
int cmdValue = cleanIntensityBtnAndCmdValueMap.get(currentClickView.getId());
|
||||
@@ -636,36 +653,29 @@ public class SweeperOperatePanelView extends LinearLayout {
|
||||
* @param timeout
|
||||
*/
|
||||
private void showLoadingMask(int timeout) {
|
||||
showLoadingMask("执行中,请稍后。。。", timeout);
|
||||
}
|
||||
|
||||
/**
|
||||
* 发送命令后等待时,展示loading
|
||||
*
|
||||
* @param hint
|
||||
* @param timeout
|
||||
*/
|
||||
private void showLoadingMask(String hint, int timeout) {
|
||||
runOnUIThread(() -> {
|
||||
mLoadingContainer.setVisibility(View.VISIBLE);
|
||||
mLoadingHintTop.setText(hint);
|
||||
mLoadingHintBottom.setText(
|
||||
String.format(
|
||||
getContext().getApplicationContext().getString(R.string.sweeper_operate_panel_cmd_execute_timeout),
|
||||
timeout
|
||||
));
|
||||
mLoadingHintBottom.setVisibility(timeout < 0 ? View.INVISIBLE : View.VISIBLE);
|
||||
});
|
||||
mLoadingContainer.setVisibility(View.VISIBLE);
|
||||
mWorkmodePanelRootView.setInterceptTouchEvent(true);
|
||||
if (timeout < 0) {//状态同步中
|
||||
mLoadingHint.setText("状态同步中,请稍后");
|
||||
mLoadingView.setVisibility(View.GONE);
|
||||
} else {
|
||||
mLoadingHint.setText(timeout + "s");
|
||||
mLoadingView.setVisibility(View.VISIBLE);
|
||||
startRotation();
|
||||
}
|
||||
if (cleaningModeStateCallback != null && timeout > 0) {
|
||||
operateStateEnum = OperateStateEnum.STARTING_STATUS;
|
||||
cleaningModeStateCallback.cleaningModeState(operateStateEnum, mCurrentCleanSystemState, isSelectPureSweepMode);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 隐藏loading
|
||||
*/
|
||||
private void hideLoadingMask() {
|
||||
runOnUIThread(() -> {
|
||||
mSweeperOperateCmdHandler.removeMessages(MSG_CMD_EXECUTE_COUNT_DOWN);
|
||||
mLoadingContainer.setVisibility(View.GONE);
|
||||
});
|
||||
mSweeperOperateCmdHandler.removeMessages(MSG_CMD_EXECUTE_COUNT_DOWN);
|
||||
mLoadingContainer.setVisibility(View.GONE);
|
||||
mWorkmodePanelRootView.setInterceptTouchEvent(false);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -674,19 +684,19 @@ public class SweeperOperatePanelView extends LinearLayout {
|
||||
* @param timeout
|
||||
*/
|
||||
private void updateLoadingCountDown(int timeout) {
|
||||
runOnUIThread(() -> {
|
||||
mLoadingHintBottom.setText(
|
||||
String.format(
|
||||
getContext().getApplicationContext().getString(R.string.sweeper_operate_panel_cmd_execute_timeout),
|
||||
timeout
|
||||
));
|
||||
});
|
||||
mLoadingHint.setText(timeout + "s");
|
||||
}
|
||||
|
||||
/**
|
||||
* 命令执行成功toast
|
||||
*/
|
||||
private void showCmdExecuteSuccessToast() {
|
||||
if (cleaningModeStateCallback != null) {
|
||||
operateStateEnum = OperateStateEnum.SUCCESS_STATUS;
|
||||
cleaningModeStateCallback.cleaningModeState(operateStateEnum, mCurrentCleanSystemState, isSelectPureSweepMode);
|
||||
}
|
||||
//停止旋转动画
|
||||
stopRotation();
|
||||
ToastUtils.showLong("设备已响应,操作成功");
|
||||
}
|
||||
|
||||
@@ -694,51 +704,15 @@ public class SweeperOperatePanelView extends LinearLayout {
|
||||
* 命令执行超时toast
|
||||
*/
|
||||
private void showCmdExecuteTimeoutToast() {
|
||||
if (cleaningModeStateCallback != null) {
|
||||
operateStateEnum = OperateStateEnum.FAIL_STATUS;
|
||||
cleaningModeStateCallback.cleaningModeState(operateStateEnum, mCurrentCleanSystemState, isSelectPureSweepMode);
|
||||
}
|
||||
//停止旋转动画
|
||||
stopRotation();
|
||||
ToastUtils.showLong("超时未响应,操作失败");
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据底盘数据恢复操作面板中相关按钮状态 成功toast
|
||||
*/
|
||||
private void showRecoverPanelButtonStateSuccessToast() {
|
||||
ToastUtils.showLong("恢复操作面板状态成功");
|
||||
}
|
||||
|
||||
/**
|
||||
* 关闭清扫作业时,确认操作的弹框
|
||||
*
|
||||
* @param runnable
|
||||
*/
|
||||
private void showConfirmCleanWorkCloseDialog(Runnable runnable) {
|
||||
AlertDialog.Builder builder = new AlertDialog.Builder(getContext());
|
||||
builder.setMessage("是否关闭清扫作业?");
|
||||
builder.setCancelable(true);
|
||||
builder.setPositiveButton("确认", new DialogInterface.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(DialogInterface dialog, int which) {
|
||||
runnable.run();
|
||||
dialog.dismiss();
|
||||
}
|
||||
});
|
||||
builder.setNegativeButton("取消", new DialogInterface.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(DialogInterface dialog, int which) {
|
||||
dialog.dismiss();
|
||||
}
|
||||
});
|
||||
AlertDialog dialog = builder.create();
|
||||
dialog.show();
|
||||
}
|
||||
|
||||
private void runOnUIThread(Runnable runnable) {
|
||||
ThreadUtils.runOnUiThread(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
runnable.run();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private void setClickListener(View view, OnClickListener listener) {
|
||||
view.setOnClickListener(new OnPreventFastClickListener() {
|
||||
@Override
|
||||
@@ -748,57 +722,39 @@ public class SweeperOperatePanelView extends LinearLayout {
|
||||
});
|
||||
}
|
||||
|
||||
// 当前时间戳
|
||||
private long mCurrentTimeMillis;
|
||||
// 底盘数据回调时间间隔
|
||||
private static final long VEHICLE_STATE_INTERVAL_MILLIS = 500L;
|
||||
|
||||
/**
|
||||
* 底盘数据透传listener
|
||||
*/
|
||||
private final IMoGoSweeperFutianCleanSystemListener mIMoGoAutopilotVehicleStateListener = new IMoGoSweeperFutianCleanSystemListener() {
|
||||
|
||||
@Override
|
||||
public void onSweeperFutianCleanSystemState(@NonNull ChassisStatesOuterClass.SweeperFuTianTaskSystemStates cleanSystemState) {
|
||||
long current = System.currentTimeMillis();
|
||||
if (current - mCurrentTimeMillis <= VEHICLE_STATE_INTERVAL_MILLIS) {
|
||||
return;
|
||||
}
|
||||
mCurrentTimeMillis = current;
|
||||
|
||||
Log.d(TAG, "onSweeperFutianCleanSystemState");
|
||||
// 第一次进入时同步底盘状态,只拿第一次的数据
|
||||
if (mSyncingVehicleState) {
|
||||
onSyncVehicleStateCallBack(cleanSystemState);
|
||||
return;
|
||||
}
|
||||
// 有命令正在执行
|
||||
if (mCurrentCmdRequestCallback != null) {
|
||||
Log.d(TAG, "getSecuWorkLeftSts = " + cleanSystemState.getSecuWorkLeftSts());
|
||||
if (mCurrentCmdRequestCallback.onCheckIfCmdSuccess(cleanSystemState)) {
|
||||
mCurrentCmdRequestCallback.onCmdSuccess();
|
||||
mCurrentCmdRequestCallback = null;
|
||||
}
|
||||
public void setSweeperFutianCleanSystemState(ChassisStatesOuterClass.SweeperFuTianTaskSystemStates cleanSystemState,
|
||||
ICleaningModeStateCallback cleaningModeStateCallback) {
|
||||
this.cleaningModeStateCallback = cleaningModeStateCallback;
|
||||
// 有命令正在执行
|
||||
if (mCurrentCmdRequestCallback != null) {
|
||||
Log.d(TAG, "getSecuWorkLeftSts = " + cleanSystemState.getSecuWorkLeftSts());
|
||||
if (mCurrentCmdRequestCallback.onCheckIfCmdSuccess(cleanSystemState)) {
|
||||
mCurrentCmdRequestCallback.onCmdSuccess();
|
||||
mCurrentCmdRequestCallback = null;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
@Override
|
||||
protected void onAttachedToWindow() {
|
||||
super.onAttachedToWindow();
|
||||
CallerSweeperFutianCleanSystemListenerManager.INSTANCE.addListener(TAG, mIMoGoAutopilotVehicleStateListener);
|
||||
// 最终调试时需要打开
|
||||
syncVehicleStateAndRecoverOperatePanelStates();
|
||||
// Mock VehicleState 数据回调
|
||||
// UiThreadHandler.postDelayed(() -> {
|
||||
// onSyncVehicleStateCallBack(SweeperFutianCmdUtil.buildSweeperFuTionCleanSystemStateMockData());
|
||||
// }, 3000L);
|
||||
//正在上装中或者上装失败,则不更新面板内容
|
||||
if (operateStateEnum == OperateStateEnum.STARTING_STATUS) {
|
||||
return;
|
||||
}
|
||||
if (!isFirst) {
|
||||
isFirst = true;
|
||||
onSyncVehicleStateCallBack(cleanSystemState);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onDetachedFromWindow() {
|
||||
super.onDetachedFromWindow();
|
||||
CallerSweeperFutianCleanSystemListenerManager.INSTANCE.removeListener(TAG);
|
||||
/**
|
||||
* 设置是否展示状态同步中
|
||||
*
|
||||
* @param operateState
|
||||
*/
|
||||
public void showSyncing(OperateStateEnum operateState) {
|
||||
if (operateState == OperateStateEnum.SYNCING_STATUS) {
|
||||
syncVehicleStateAndRecoverOperatePanelStates();
|
||||
isFirst = false;
|
||||
} else {
|
||||
hideLoadingMask();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -806,13 +762,11 @@ public class SweeperOperatePanelView extends LinearLayout {
|
||||
*/
|
||||
private synchronized void syncVehicleStateAndRecoverOperatePanelStates() {
|
||||
// show sync loading
|
||||
showLoadingMask("状态同步中,请稍后", -1);
|
||||
mSyncingVehicleState = true;
|
||||
showLoadingMask(-1);
|
||||
}
|
||||
|
||||
private synchronized void onSyncVehicleStateCallBack(ChassisStatesOuterClass.SweeperFuTianTaskSystemStates cleanSystemState) {
|
||||
if (cleanSystemState == null) return;
|
||||
mSyncingVehicleState = false;
|
||||
// 清扫作业开启状态(以电机状态为true代表Open成功,实际控制端控制步骤为:1.发送远程控制上装指令 2.发送电机启动指令)
|
||||
boolean clean_open_requirement = cleanSystemState.getSecuMotWorkSts();
|
||||
// 作业模式状态
|
||||
@@ -832,97 +786,64 @@ public class SweeperOperatePanelView extends LinearLayout {
|
||||
boolean clean_direction_both_side = cleanSystemState.getSecuWorkOnBothsidesSts();
|
||||
|
||||
// 纯扫 模式判断:不是另外其他3个模式,同时有清扫方向,说明开启了纯扫模式
|
||||
boolean clean_mode_pure_sweep = checkIfCleanModePureSweep(cleanSystemState);
|
||||
boolean clean_mode_pure_sweep = SweeperFutianCmdUtil.checkIfCleanModePureSweep(cleanSystemState);
|
||||
|
||||
// 作业强度状态
|
||||
boolean clean_intensity_standard = cleanSystemState.getSecuWorkStandSts();
|
||||
boolean clean_intensity_strong = cleanSystemState.getSecuWorkStrongSts();
|
||||
if (clean_open_requirement) {
|
||||
// 打开状态
|
||||
mBtnCleanWorkOpenClose.setText("关闭");
|
||||
mBtnCleanWorkOpenClose.setChecked(true);
|
||||
} else {
|
||||
// 关闭状态
|
||||
mBtnCleanWorkOpenClose.setText("打开");
|
||||
mBtnCleanWorkOpenClose.setChecked(false);
|
||||
}
|
||||
if (clean_mode_pure_sweep) {
|
||||
//纯扫
|
||||
mBtnCleanModePureSweep.setChecked(true);
|
||||
mBtnCleanModePureSweep.setEnabled(true);
|
||||
toggleCleanModeBtnsByChoosedViewId(R.id.btn_clean_mode_pure_sweep, false);
|
||||
} else if (clean_mode_pure_wash) {
|
||||
//纯洗
|
||||
mBtnCleanModePureWash.setChecked(true);
|
||||
mBtnCleanModePureWash.setEnabled(true);
|
||||
toggleCleanModeBtnsByChoosedViewId(R.id.btn_clean_mode_pure_wash, false);
|
||||
} else if (clean_mode_wash_sweep) {
|
||||
//洗扫
|
||||
mBtnCleanModeSweepWash.setChecked(true);
|
||||
mBtnCleanModeSweepWash.setEnabled(true);
|
||||
toggleCleanModeBtnsByChoosedViewId(R.id.btn_clean_mode_sweep_wash, false);
|
||||
} else if (clean_mode_pure_draw) {
|
||||
//纯吸,需要disable作业方向
|
||||
mBtnCleanModePureAbsorption.setChecked(true);
|
||||
mBtnCleanModePureAbsorption.setEnabled(true);
|
||||
toggleCleanModeBtnsByChoosedViewId(R.id.btn_clean_mode_pure_absorption, false);
|
||||
toggleCleanDirectionBtnsStatus(false);
|
||||
}
|
||||
|
||||
runOnUIThread(() -> {
|
||||
if (clean_open_requirement) {
|
||||
// 打开状态
|
||||
mBtnCleanWorkOpenClose.setText("Close");
|
||||
mBtnCleanWorkOpenClose.setChecked(true);
|
||||
} else {
|
||||
// 关闭状态
|
||||
mBtnCleanWorkOpenClose.setText("Open");
|
||||
mBtnCleanWorkOpenClose.setChecked(false);
|
||||
if (!clean_mode_pure_draw) {// 非纯吸模式才有清扫方向
|
||||
if (clean_direction_left_side) {
|
||||
mBtnCleanDirectionLeftSide.setChecked(true);
|
||||
mBtnCleanDirectionLeftSide.setEnabled(true);
|
||||
toggleCleanDirectionBtnsByChoosedViewId(R.id.btn_clean_direction_left_side, false);
|
||||
} else if (clean_direction_right_side) {
|
||||
mBtnCleanDirectionRightSide.setChecked(true);
|
||||
mBtnCleanDirectionRightSide.setEnabled(true);
|
||||
toggleCleanDirectionBtnsByChoosedViewId(R.id.btn_clean_direction_right_side, false);
|
||||
} else if (clean_direction_both_side) {
|
||||
mBtnCleanDirectionBothSide.setChecked(true);
|
||||
mBtnCleanDirectionBothSide.setEnabled(true);
|
||||
toggleCleanDirectionBtnsByChoosedViewId(R.id.btn_clean_direction_both_side, false);
|
||||
}
|
||||
if (clean_mode_pure_sweep) {
|
||||
//纯扫
|
||||
mBtnCleanModePureSweep.setChecked(true);
|
||||
mBtnCleanModePureSweep.setEnabled(true);
|
||||
toggleCleanModeBtnsByChoosedViewId(R.id.btn_clean_mode_pure_sweep, false);
|
||||
} else if (clean_mode_pure_wash) {
|
||||
//纯洗
|
||||
mBtnCleanModePureWash.setChecked(true);
|
||||
mBtnCleanModePureWash.setEnabled(true);
|
||||
toggleCleanModeBtnsByChoosedViewId(R.id.btn_clean_mode_pure_wash, false);
|
||||
} else if (clean_mode_wash_sweep) {
|
||||
//洗扫
|
||||
mBtnCleanModeSweepWash.setChecked(true);
|
||||
mBtnCleanModeSweepWash.setEnabled(true);
|
||||
toggleCleanModeBtnsByChoosedViewId(R.id.btn_clean_mode_sweep_wash, false);
|
||||
} else if (clean_mode_pure_draw) {
|
||||
//纯吸,需要disable作业方向
|
||||
mBtnCleanModePureAbsorption.setChecked(true);
|
||||
mBtnCleanModePureAbsorption.setEnabled(true);
|
||||
toggleCleanModeBtnsByChoosedViewId(R.id.btn_clean_mode_pure_absorption, false);
|
||||
toggleCleanDirectionBtnsStatus(false);
|
||||
}
|
||||
|
||||
if (!clean_mode_pure_draw) {// 非纯吸模式才有清扫方向
|
||||
if (clean_direction_left_side) {
|
||||
mBtnCleanDirectionLeftSide.setChecked(true);
|
||||
mBtnCleanDirectionLeftSide.setEnabled(true);
|
||||
toggleCleanDirectionBtnsByChoosedViewId(R.id.btn_clean_direction_left_side, false);
|
||||
} else if (clean_direction_right_side) {
|
||||
mBtnCleanDirectionRightSide.setChecked(true);
|
||||
mBtnCleanDirectionRightSide.setEnabled(true);
|
||||
toggleCleanDirectionBtnsByChoosedViewId(R.id.btn_clean_direction_right_side, false);
|
||||
} else if (clean_direction_both_side) {
|
||||
mBtnCleanDirectionBothSide.setChecked(true);
|
||||
mBtnCleanDirectionBothSide.setEnabled(true);
|
||||
toggleCleanDirectionBtnsByChoosedViewId(R.id.btn_clean_direction_both_side, false);
|
||||
}
|
||||
}
|
||||
if (clean_intensity_standard) {
|
||||
setCleanIntensityStandard();
|
||||
} else if (clean_intensity_strong) {
|
||||
setCleanIntensityStrong();
|
||||
}
|
||||
hideLoadingMask();
|
||||
showRecoverPanelButtonStateSuccessToast();
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* 通过底盘数据判断是纯扫模式
|
||||
*
|
||||
* @param cleanSystemState
|
||||
* @return
|
||||
*/
|
||||
private boolean checkIfCleanModePureSweep(ChassisStatesOuterClass.SweeperFuTianTaskSystemStates cleanSystemState) {
|
||||
// 作业模式状态
|
||||
// 洗扫
|
||||
boolean clean_mode_wash_sweep = cleanSystemState.getSecuModWashSweepSts();
|
||||
// 纯洗
|
||||
boolean clean_mode_pure_wash = cleanSystemState.getSecuModWashSts();
|
||||
// 纯吸
|
||||
boolean clean_mode_pure_draw = cleanSystemState.getSecuWorkTonSts();
|
||||
|
||||
// 清扫方向状态
|
||||
// 左侧
|
||||
boolean clean_direction_left_side = cleanSystemState.getSecuWorkLeftSts();
|
||||
// 右侧
|
||||
boolean clean_direction_right_side = cleanSystemState.getSecuWorkRightSts();
|
||||
// 两侧
|
||||
boolean clean_direction_both_side = cleanSystemState.getSecuWorkOnBothsidesSts();
|
||||
|
||||
// 纯扫 模式判断:不是另外其他3个模式,同时有清扫方向,说明开启了纯扫模式
|
||||
boolean clean_mode_pure_sweep = (clean_direction_left_side || clean_direction_right_side || clean_direction_both_side)
|
||||
&& (!clean_mode_wash_sweep && !clean_mode_pure_wash && !clean_mode_pure_draw);
|
||||
return clean_mode_pure_sweep;
|
||||
}
|
||||
if (clean_intensity_standard) {
|
||||
setCleanIntensityStandard();
|
||||
} else if (clean_intensity_strong) {
|
||||
setCleanIntensityStrong();
|
||||
}
|
||||
hideLoadingMask();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -950,7 +871,7 @@ public class SweeperOperatePanelView extends LinearLayout {
|
||||
msg.obj = timeout;
|
||||
mSweeperOperateCmdHandler.sendMessage(msg);
|
||||
// Mock Cmd Success
|
||||
// mockSendCmdSuccess();
|
||||
//mockCleanModeSuccess(fuTianCleanCmd);
|
||||
}
|
||||
|
||||
private void mockSendCmdSuccess() {
|
||||
@@ -975,7 +896,6 @@ public class SweeperOperatePanelView extends LinearLayout {
|
||||
|
||||
private final static SweeperOperateCmdHandler mSweeperOperateCmdHandler = new SweeperOperateCmdHandler();
|
||||
private static CmdRequestCallback mCurrentCmdRequestCallback;//发送命令后的回调
|
||||
private boolean mSyncingVehicleState;//第一次进入页面时,同步底盘状态的标志位
|
||||
private static final int MSG_CMD_EXECUTE_COUNT_DOWN = 10001;
|
||||
private static final int MSG_CMD_EXECUTE_MOCK_SUCCESS = 10002;
|
||||
|
||||
@@ -1006,8 +926,10 @@ public class SweeperOperatePanelView extends LinearLayout {
|
||||
}
|
||||
} else if (msg.what == MSG_CMD_EXECUTE_MOCK_SUCCESS) {
|
||||
if (mCurrentCmdRequestCallback != null) {
|
||||
mCurrentCmdRequestCallback.onCmdSuccess();
|
||||
mCurrentCmdRequestCallback = null;
|
||||
if (mCurrentCmdRequestCallback.onCheckIfCmdSuccess(mCurrentCleanSystemState)) {
|
||||
mCurrentCmdRequestCallback.onCmdSuccess();
|
||||
mCurrentCmdRequestCallback = null;
|
||||
}
|
||||
}
|
||||
removeMessages(MSG_CMD_EXECUTE_COUNT_DOWN);
|
||||
}
|
||||
@@ -1028,4 +950,145 @@ public class SweeperOperatePanelView extends LinearLayout {
|
||||
void onCmdTimeout();
|
||||
}
|
||||
|
||||
/**
|
||||
* 开始旋转
|
||||
*/
|
||||
private void startRotation() {
|
||||
if (objectAnimator == null) {
|
||||
objectAnimator = ObjectAnimator.ofFloat(mLoadingView, "rotation", 0, 360f);
|
||||
objectAnimator.setDuration(1500);
|
||||
objectAnimator.setRepeatCount(-1);
|
||||
objectAnimator.setInterpolator(new LinearInterpolator());
|
||||
objectAnimator.start();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 停止旋转
|
||||
*/
|
||||
private void stopRotation() {
|
||||
if (objectAnimator != null && objectAnimator.isRunning()) {
|
||||
objectAnimator.end();
|
||||
objectAnimator = null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 模拟指令操作成功
|
||||
*/
|
||||
private void mockCleanModeSuccess(SpecialVehicleTaskCmdOuterClass.RoboSweeperFuTianTaskCmd fuTianTaskCmd) {
|
||||
ChassisStatesOuterClass.SweeperFuTianTaskSystemStates.Builder builder = ChassisStatesOuterClass.SweeperFuTianTaskSystemStates.newBuilder();
|
||||
chassis.SpecialVehicleTaskCmdOuterClass.RoboSweeperFuTianCleanCmd fuTianCleanCmd = fuTianTaskCmd.getRoboSweeperFutianCleanCmd();
|
||||
if (fuTianCleanCmd.getCleanOpenRequirement() == CLEAN_WORK_OPEN) {//打开
|
||||
builder.setSecuMotWorkSts(true);
|
||||
builder.setSecuModWashSweepSts(false);
|
||||
builder.setSecuModWashSts(false);
|
||||
builder.setSecuWorkTonSts(false);
|
||||
builder.setSecuWorkOnBothsidesSts(false);
|
||||
builder.setSecuWorkLeftSts(false);
|
||||
builder.setSecuWorkRightSts(false);
|
||||
builder.setSecuWorkStandSts(true);
|
||||
builder.setSecuWorkStrongSts(false);
|
||||
mCurrentCleanSystemState = builder.build();
|
||||
mockSendCmdSuccess();
|
||||
return;
|
||||
} else if (fuTianCleanCmd.getCleanOpenRequirement() == CLEAN_WORK_CLOSE) {//关闭
|
||||
builder.setSecuModWashSweepSts(false);
|
||||
builder.setSecuModWashSts(false);
|
||||
builder.setSecuWorkTonSts(false);
|
||||
builder.setSecuWorkOnBothsidesSts(false);
|
||||
builder.setSecuWorkLeftSts(false);
|
||||
builder.setSecuWorkRightSts(false);
|
||||
builder.setSecuWorkStandSts(true);
|
||||
builder.setSecuWorkStrongSts(false);
|
||||
builder.setSecuMotWorkSts(false);
|
||||
mCurrentCleanSystemState = builder.build();
|
||||
mockSendCmdSuccess();
|
||||
return;
|
||||
}
|
||||
if (fuTianCleanCmd.getCleanModeRequirement() == CLEAN_MODE_PURE_SWEEP) {//纯扫
|
||||
builder.setSecuModWashSweepSts(false);
|
||||
builder.setSecuModWashSts(false);
|
||||
builder.setSecuWorkTonSts(false);
|
||||
mCurrentCleanSystemState = builder.build();
|
||||
mockSendCmdSuccess();
|
||||
return;
|
||||
} else if (fuTianCleanCmd.getCleanModeRequirement() == CLEAN_MODE_WASH_SWEEP) {//洗扫
|
||||
builder.setSecuModWashSweepSts(!mCurrentCleanSystemState.getSecuModWashSweepSts());
|
||||
mCurrentCleanSystemState = builder.build();
|
||||
mockSendCmdSuccess();
|
||||
return;
|
||||
} else if (fuTianCleanCmd.getCleanModeRequirement() == CLEAN_MODE_PURE_WASH) {//纯洗
|
||||
builder.setSecuModWashSts(!mCurrentCleanSystemState.getSecuModWashSts());
|
||||
mCurrentCleanSystemState = builder.build();
|
||||
mockSendCmdSuccess();
|
||||
return;
|
||||
} else if (fuTianCleanCmd.getCleanModeRequirement() == CLEAN_MODE_PURE_DRAW) {//纯吸
|
||||
builder.setSecuWorkTonSts(!mCurrentCleanSystemState.getSecuWorkTonSts());
|
||||
builder.setSecuWorkStandSts(true);
|
||||
builder.setSecuWorkOnBothsidesSts(false);
|
||||
builder.setSecuWorkLeftSts(false);
|
||||
builder.setSecuWorkRightSts(false);
|
||||
mCurrentCleanSystemState = builder.build();
|
||||
mockSendCmdSuccess();
|
||||
return;
|
||||
} else if (fuTianCleanCmd.getCleanModeRequirement() == CLEAN_MODE_CLOSE) {
|
||||
builder.setSecuModWashSweepSts(false);
|
||||
builder.setSecuModWashSts(false);
|
||||
builder.setSecuWorkTonSts(false);
|
||||
builder.setSecuWorkOnBothsidesSts(false);
|
||||
builder.setSecuWorkLeftSts(false);
|
||||
builder.setSecuWorkRightSts(false);
|
||||
builder.setSecuWorkStandSts(true);
|
||||
builder.setSecuWorkStrongSts(false);
|
||||
mCurrentCleanSystemState = builder.build();
|
||||
mockSendCmdSuccess();
|
||||
return;
|
||||
}
|
||||
if (fuTianCleanCmd.getCleanDirectionRequirement() == CLEAN_DIRECTION_BOTH_SIDE) {//两侧
|
||||
builder.setSecuWorkOnBothsidesSts(!mCurrentCleanSystemState.getSecuWorkOnBothsidesSts());
|
||||
builder.setSecuWorkStandSts(true);
|
||||
builder.setSecuWorkStrongSts(false);
|
||||
mCurrentCleanSystemState = builder.build();
|
||||
mockSendCmdSuccess();
|
||||
return;
|
||||
} else if (fuTianCleanCmd.getCleanDirectionRequirement() == CLEAN_DIRECTION_LEFT_SIDE) {//左侧
|
||||
builder.setSecuWorkLeftSts(!mCurrentCleanSystemState.getSecuWorkLeftSts());
|
||||
builder.setSecuWorkStandSts(true);
|
||||
builder.setSecuWorkStrongSts(false);
|
||||
mCurrentCleanSystemState = builder.build();
|
||||
mockSendCmdSuccess();
|
||||
return;
|
||||
} else if (fuTianCleanCmd.getCleanDirectionRequirement() == CLEAN_DIRECTION_RIGHT_SIDE) {//右侧
|
||||
builder.setSecuWorkRightSts(!mCurrentCleanSystemState.getSecuWorkRightSts());
|
||||
builder.setSecuWorkStandSts(true);
|
||||
builder.setSecuWorkStrongSts(false);
|
||||
mCurrentCleanSystemState = builder.build();
|
||||
mockSendCmdSuccess();
|
||||
return;
|
||||
} else if (fuTianCleanCmd.getCleanDirectionRequirement() == CLEAN_DIRECTION_CLOSE) {
|
||||
builder.setSecuWorkLeftSts(false);
|
||||
builder.setSecuWorkRightSts(false);
|
||||
builder.setSecuWorkOnBothsidesSts(false);
|
||||
builder.setSecuWorkStandSts(true);
|
||||
builder.setSecuWorkStrongSts(false);
|
||||
mCurrentCleanSystemState = builder.build();
|
||||
mockSendCmdSuccess();
|
||||
return;
|
||||
}
|
||||
if (fuTianCleanCmd.getCleanIntensityRequirement() == CLEAN_INTENSITY_STRAND) {
|
||||
builder.setSecuWorkStrongSts(true);
|
||||
builder.setSecuWorkStandSts(false);
|
||||
mCurrentCleanSystemState = builder.build();
|
||||
mockSendCmdSuccess();
|
||||
return;
|
||||
} else if (fuTianCleanCmd.getCleanIntensityRequirement() == CLEAN_INTENSITY_STRONG) {
|
||||
builder.setSecuWorkStandSts(true);
|
||||
builder.setSecuWorkStrongSts(false);
|
||||
mCurrentCleanSystemState = builder.build();
|
||||
mockSendCmdSuccess();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,300 +0,0 @@
|
||||
package com.mogo.och.sweeper.ui;
|
||||
|
||||
import android.annotation.SuppressLint;
|
||||
import android.content.Context;
|
||||
import android.graphics.Point;
|
||||
import android.os.Bundle;
|
||||
import android.text.TextUtils;
|
||||
import android.view.Gravity;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.view.Window;
|
||||
import android.view.WindowManager;
|
||||
import android.widget.ImageView;
|
||||
import android.widget.TextView;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
import androidx.constraintlayout.widget.ConstraintLayout;
|
||||
import androidx.recyclerview.widget.LinearLayoutManager;
|
||||
import androidx.recyclerview.widget.RecyclerView;
|
||||
|
||||
import com.mogo.commons.mvp.MvpActivity;
|
||||
import com.mogo.eagle.core.utilcode.util.ToastUtils;
|
||||
import com.mogo.och.sweeper.R;
|
||||
import com.mogo.och.sweeper.bean.SweeperQueryLinesResponse;
|
||||
import com.mogo.och.sweeper.presenter.SweeperLinePresenter;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @author: wangmingjun
|
||||
* @date: 2022/2/8
|
||||
*/
|
||||
public class SweeperSwitchLineActivity extends MvpActivity<SweeperSwitchLineView, SweeperLinePresenter>
|
||||
implements View.OnClickListener, SweeperSwitchLineView {
|
||||
|
||||
private ImageView mClose;
|
||||
private ConstraintLayout mNoDatasView;
|
||||
private RecyclerView mLinesListView;
|
||||
private TextView mLineCommitBtn;
|
||||
private SwitchLineAdapter mAdapter;
|
||||
private List<SweeperQueryLinesResponse.Result> mData = new ArrayList<>();
|
||||
private int mSelectLineId = -1;
|
||||
|
||||
@Override
|
||||
protected int getLayoutId() {
|
||||
return R.layout.activity_sweeper_switch_line;
|
||||
}
|
||||
|
||||
@NonNull
|
||||
@Override
|
||||
protected SweeperLinePresenter createPresenter() {
|
||||
return new SweeperLinePresenter(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void initViews() {
|
||||
initWH();
|
||||
initView();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onCreate(@Nullable Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
initDatas();
|
||||
}
|
||||
|
||||
/**
|
||||
* 初始化view
|
||||
*/
|
||||
private void initView() {
|
||||
mClose = findViewById(R.id.switch_line_close);
|
||||
mClose.setOnClickListener(this);
|
||||
mNoDatasView = findViewById(R.id.no_order_data_view);
|
||||
|
||||
mLineCommitBtn = findViewById(R.id.switch_line_btn_commit);
|
||||
mLineCommitBtn.setOnClickListener(this);
|
||||
|
||||
mLinesListView = findViewById(R.id.switch_line_rv);
|
||||
mLinesListView.setLayoutManager(new LinearLayoutManager(this));
|
||||
mAdapter = new SwitchLineAdapter(getApplicationContext(),mData);
|
||||
mLinesListView.setAdapter(mAdapter);
|
||||
//设置item 点击事件
|
||||
mAdapter.setOnLineItemClickListener(new LineItemClickListener() {
|
||||
@Override
|
||||
public void onItemClick(int position) {
|
||||
if (mData.size() > position && !TextUtils.isEmpty(mData.get(position).startSiteName )
|
||||
&& !TextUtils.isEmpty(mData.get(position).endSiteName)){
|
||||
mSelectLineId = mData.get(position).lineId;
|
||||
}else {
|
||||
mSelectLineId = -1;
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置布局宽高
|
||||
*/
|
||||
private void initWH() {
|
||||
|
||||
Window window = getWindow();
|
||||
|
||||
WindowManager.LayoutParams params = window.getAttributes();
|
||||
WindowManager windowManager = (WindowManager)getSystemService(Context.WINDOW_SERVICE);
|
||||
Point point = new Point();
|
||||
windowManager.getDefaultDisplay().getSize(point);//用于获取屏幕高度
|
||||
|
||||
params.width = (int)(point.x * 0.375);
|
||||
params.height = ViewGroup.LayoutParams.MATCH_PARENT;
|
||||
window.setAttributes(params);
|
||||
window.setGravity(Gravity.LEFT|Gravity.BOTTOM);
|
||||
}
|
||||
|
||||
/**
|
||||
* 初始化数据
|
||||
*/
|
||||
private void initDatas() {
|
||||
mPresenter.queryBusLines();
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询返回绑定路线集合
|
||||
* @param data
|
||||
*/
|
||||
@Override
|
||||
public void onBusLinesChange(SweeperQueryLinesResponse data){
|
||||
if (null == data){
|
||||
showNoData(true);
|
||||
return;
|
||||
}
|
||||
if (data.data != null && data.data.size() > 0){
|
||||
showNoData(false);
|
||||
mData.clear();
|
||||
mData.addAll(data.data);
|
||||
mAdapter.notifyDataSetChanged();
|
||||
changeCommitBtnBg();
|
||||
}else {
|
||||
showNoData(true);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据路线选中情况设置提交按钮样式
|
||||
*/
|
||||
private void changeCommitBtnBg() {
|
||||
for (int i=0; i<mData.size();i++){
|
||||
if (mData.get(i).choose == 1){
|
||||
mLineCommitBtn.setBackgroundResource(R.drawable.sweeper_switch_line_btn_commit);
|
||||
mLineCommitBtn.setTextColor(getResources().getColor(R.color.sweeper_white));
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onChangeLineIdSuccess(){
|
||||
ToastUtils.showLong(getResources().getString(R.string.sweeper_change_line_commit_tip_s));
|
||||
mPresenter.queryBusRoutes();
|
||||
if (mAdapter != null){
|
||||
mAdapter.setOnLineItemClickListener(null);
|
||||
}
|
||||
mPresenter.removeListener();
|
||||
finish();
|
||||
}
|
||||
|
||||
/**
|
||||
* 有无数据UI显示
|
||||
* @param b
|
||||
*/
|
||||
private void showNoData(boolean b) {
|
||||
if (b){
|
||||
mLinesListView.setVisibility(View.GONE);
|
||||
mLineCommitBtn.setVisibility(View.GONE);
|
||||
mNoDatasView.setVisibility(View.VISIBLE);
|
||||
}else {
|
||||
mLinesListView.setVisibility(View.VISIBLE);
|
||||
mLineCommitBtn.setVisibility(View.VISIBLE);
|
||||
mNoDatasView.setVisibility(View.GONE);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
//关闭dialog
|
||||
if (v.getId() == R.id.switch_line_close){
|
||||
finish();
|
||||
return;
|
||||
}
|
||||
//切换路线提交
|
||||
if (v.getId() == R.id.switch_line_btn_commit){
|
||||
if (mSelectLineId > -1){
|
||||
mPresenter.commitSwitchLineId(mSelectLineId);
|
||||
}else {
|
||||
finish();
|
||||
}
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onDestroy() {
|
||||
super.onDestroy();
|
||||
}
|
||||
|
||||
/**
|
||||
* 路线列表adapter
|
||||
*/
|
||||
static class SwitchLineAdapter extends RecyclerView.Adapter<SwitchLineViewHolder>{
|
||||
|
||||
private Context mContext;
|
||||
private List<SweeperQueryLinesResponse.Result> mData;
|
||||
// RecyclerView设置点击事件
|
||||
private LineItemClickListener mItemClickListener ;
|
||||
private int clickPos = -1;
|
||||
|
||||
public SwitchLineAdapter(Context context, List<SweeperQueryLinesResponse.Result> data){
|
||||
mContext = context;
|
||||
mData = data;
|
||||
}
|
||||
|
||||
@NonNull
|
||||
@Override
|
||||
public SwitchLineViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
|
||||
View view = LayoutInflater.from(mContext).inflate(R.layout.sweeper_switch_line_list_item
|
||||
,parent,false);
|
||||
SwitchLineViewHolder viewHolder = new SwitchLineViewHolder(view);
|
||||
return viewHolder;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onBindViewHolder(@NonNull SwitchLineViewHolder holder, @SuppressLint("RecyclerView") int position) {
|
||||
SweeperQueryLinesResponse.Result line = mData.get(position);
|
||||
holder.lineName.setText(mContext.getString(R.string.sweeper_switch_line_name)+" "+line.name);
|
||||
holder.lineStartName.setText(mContext.getString(R.string.sweeper_line_start)+" "+line.startSiteName);
|
||||
holder.lineEndName.setText(mContext.getString(R.string.sweeper_line_end)+" "+line.endSiteName);
|
||||
|
||||
//设置item点击事件
|
||||
holder.itemView.setOnClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
if (mItemClickListener != null){
|
||||
mItemClickListener.onItemClick(position);
|
||||
clickPos = position;
|
||||
notifyDataSetChanged();
|
||||
}
|
||||
}
|
||||
});
|
||||
//选中绑定
|
||||
if (clickPos > -1){
|
||||
if (clickPos == position){
|
||||
holder.selectIv.setImageResource(R.drawable.sweeper_selected_btn);
|
||||
}else {
|
||||
holder.selectIv.setImageResource(R.drawable.sweeper_unselect_btn);
|
||||
}
|
||||
}else {
|
||||
if (line.choose == 1){//1:绑定 2:未绑定 默认绑定
|
||||
if (mItemClickListener != null) {
|
||||
mItemClickListener.onItemClick(position);
|
||||
}
|
||||
holder.selectIv.setImageResource(R.drawable.sweeper_selected_btn);
|
||||
}else {
|
||||
holder.selectIv.setImageResource(R.drawable.sweeper_unselect_btn);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getItemCount() {
|
||||
return mData.size();
|
||||
}
|
||||
public void setOnLineItemClickListener(LineItemClickListener itemClickListener){
|
||||
this.mItemClickListener = itemClickListener ;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
static class SwitchLineViewHolder extends RecyclerView.ViewHolder{
|
||||
|
||||
private ImageView selectIv;
|
||||
private TextView lineName; //线路名称
|
||||
private TextView lineStartName; //起点
|
||||
private TextView lineEndName; //终点
|
||||
|
||||
public SwitchLineViewHolder(@NonNull View itemView) {
|
||||
super(itemView);
|
||||
selectIv = itemView.findViewById(R.id.switch_line_item_select_iv);
|
||||
lineName = itemView.findViewById(R.id.switch_line_name);
|
||||
lineStartName = itemView.findViewById(R.id.switch_line_start_station);
|
||||
lineEndName = itemView.findViewById(R.id.switch_line_end_station);
|
||||
}
|
||||
}
|
||||
|
||||
public interface LineItemClickListener {
|
||||
void onItemClick(int position) ;
|
||||
}
|
||||
}
|
||||
@@ -1,15 +0,0 @@
|
||||
package com.mogo.och.sweeper.ui;
|
||||
|
||||
import com.mogo.commons.mvp.IView;
|
||||
import com.mogo.och.sweeper.bean.SweeperQueryLinesResponse;
|
||||
|
||||
/**
|
||||
* @author: wangmingjun
|
||||
* @date: 2022/2/10
|
||||
*/
|
||||
public interface SweeperSwitchLineView extends IView {
|
||||
|
||||
void onBusLinesChange(SweeperQueryLinesResponse data);
|
||||
void onChangeLineIdSuccess();
|
||||
}
|
||||
|
||||
@@ -0,0 +1,79 @@
|
||||
package com.mogo.och.sweeper.ui.adapter
|
||||
|
||||
import android.graphics.Color
|
||||
import android.view.LayoutInflater
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import android.widget.ImageView
|
||||
import android.widget.TextView
|
||||
import androidx.recyclerview.widget.RecyclerView
|
||||
import com.mogo.och.common.module.utils.DateTimeUtil
|
||||
import com.mogo.och.sweeper.R
|
||||
import com.mogo.och.sweeper.bean.SweeperMainTaskBean
|
||||
|
||||
class TaskListAdapter() : RecyclerView.Adapter<TaskListAdapter.TaskViewHolder>() {
|
||||
private var mItemClickListener: TaskItemClickListener? = null
|
||||
private var mSelectPosition: Int = -1
|
||||
private var data:MutableList<SweeperMainTaskBean>?=null
|
||||
fun setOnTaskItemClickListener(itemClickListener: TaskItemClickListener?) {
|
||||
mItemClickListener = itemClickListener
|
||||
}
|
||||
|
||||
class TaskViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {
|
||||
val selectIv: ImageView
|
||||
val taskName: TextView//任务名称
|
||||
val taskDesc: TextView//任务描述
|
||||
val tvTaskTime: TextView//任务时间
|
||||
|
||||
init {
|
||||
selectIv = itemView.findViewById(R.id.ivTaskSelect)
|
||||
taskName = itemView.findViewById(R.id.tvTaskName)
|
||||
taskDesc = itemView.findViewById(R.id.tvTaskDesc)
|
||||
tvTaskTime = itemView.findViewById(R.id.tvTaskTime)
|
||||
}
|
||||
}
|
||||
|
||||
fun selectPosition(position: Int) {
|
||||
this.mSelectPosition = position
|
||||
notifyDataSetChanged()
|
||||
}
|
||||
fun setTaskListData(data: MutableList<SweeperMainTaskBean>?){
|
||||
this.data=data
|
||||
notifyDataSetChanged()
|
||||
}
|
||||
interface TaskItemClickListener {
|
||||
fun onItemClick(position: Int,mainTask:SweeperMainTaskBean)
|
||||
}
|
||||
|
||||
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): TaskViewHolder {
|
||||
val view = LayoutInflater.from(parent.context).inflate(
|
||||
R.layout.sweeper_item_task_info, parent, false
|
||||
)
|
||||
return TaskViewHolder(view)
|
||||
}
|
||||
|
||||
override fun onBindViewHolder(holder: TaskViewHolder, position: Int) {
|
||||
data?.let { mainTask->
|
||||
holder.taskName.text= mainTask[position].mainTaskName
|
||||
holder.taskDesc.text= "全程包含${mainTask[position].subTaskTotal}个子任务"
|
||||
val calendar = DateTimeUtil.formatLongToCalendar(mainTask[position].mainTaskStartTime)
|
||||
if (DateTimeUtil.compareDateIsCurrentDay(calendar)){
|
||||
holder.tvTaskTime.text="今天${DateTimeUtil.formatCalendarToString(calendar, DateTimeUtil.TAXI_HH_mm)}"
|
||||
}else{
|
||||
holder.tvTaskTime.text=DateTimeUtil.formatCalendarToString(calendar, DateTimeUtil.TAXI_MM_dd_HH_mm)
|
||||
}
|
||||
holder.itemView.setOnClickListener {
|
||||
mItemClickListener?.onItemClick(position,mainTask[position])
|
||||
}
|
||||
}
|
||||
if (position == mSelectPosition) {
|
||||
holder.selectIv.visibility = View.VISIBLE
|
||||
holder.itemView.setBackgroundColor(Color.parseColor("#FF122B4E"))
|
||||
} else {
|
||||
holder.selectIv.visibility = View.GONE
|
||||
holder.itemView.setBackgroundColor(Color.parseColor("#00000000"))
|
||||
}
|
||||
}
|
||||
|
||||
override fun getItemCount(): Int = data?.size ?: 0
|
||||
}
|
||||
@@ -0,0 +1,70 @@
|
||||
package com.mogo.och.sweeper.ui.dialog
|
||||
|
||||
import android.content.Context
|
||||
import android.widget.TextView
|
||||
import androidx.lifecycle.LifecycleObserver
|
||||
import com.mogo.eagle.core.function.hmi.dialog.BaseFloatDialog
|
||||
import com.mogo.och.sweeper.R
|
||||
|
||||
/**
|
||||
* 不带带有title, tip,confirm,cancel的dialog
|
||||
*/
|
||||
class SweeperManualDrivingDialog: BaseFloatDialog, LifecycleObserver {
|
||||
|
||||
private var commonConfirm : TextView? = null
|
||||
private var commonTips : TextView? = null
|
||||
|
||||
private var clickListener: ClickListener? = null
|
||||
|
||||
constructor(builder: Builder,context: Context) : super(context) {
|
||||
commonTips?.text = builder.tipsStr
|
||||
commonConfirm?.text = builder.confirmStr
|
||||
}
|
||||
|
||||
init{
|
||||
setContentView(R.layout.dialog_sweeper_manual_driving)
|
||||
|
||||
setCanceledOnTouchOutside(false)
|
||||
|
||||
commonConfirm = findViewById(R.id.sweeper_common_confirm)
|
||||
commonTips = findViewById(R.id.sweeper_common_tips)
|
||||
|
||||
commonConfirm?.setOnClickListener{
|
||||
clickListener?.confirm()
|
||||
dismiss()
|
||||
}
|
||||
}
|
||||
|
||||
fun setClickListener(clickListener: ClickListener) {
|
||||
this.clickListener = clickListener
|
||||
}
|
||||
|
||||
fun showUpgradeDialog(){
|
||||
if(isShowing){
|
||||
return
|
||||
}
|
||||
show()
|
||||
}
|
||||
|
||||
interface ClickListener{
|
||||
fun confirm()
|
||||
}
|
||||
|
||||
class Builder{
|
||||
var tipsStr:String = ""
|
||||
var confirmStr:String = ""
|
||||
fun tips(tips: String) : Builder{
|
||||
this.tipsStr = tips
|
||||
return this
|
||||
}
|
||||
|
||||
fun confirmStr(commit: String) : Builder{
|
||||
this.confirmStr = commit
|
||||
return this
|
||||
}
|
||||
fun build(context: Context): SweeperManualDrivingDialog? {
|
||||
return SweeperManualDrivingDialog(this,context)
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,86 @@
|
||||
package com.mogo.och.sweeper.ui.dialog
|
||||
|
||||
import android.annotation.SuppressLint
|
||||
import android.content.Context
|
||||
import android.widget.TextView
|
||||
import androidx.lifecycle.LifecycleObserver
|
||||
import com.mogo.eagle.core.function.hmi.dialog.BaseFloatDialog
|
||||
import com.mogo.och.sweeper.R
|
||||
|
||||
/**
|
||||
* 不带带有title, tip,confirm,cancel的dialog
|
||||
*/
|
||||
class SweeperNoTitleCommonDialog: BaseFloatDialog, LifecycleObserver {
|
||||
|
||||
private var commonConfirm : TextView? = null
|
||||
private var commonCancel : TextView? = null
|
||||
private var commonTips : TextView? = null
|
||||
|
||||
private var clickListener: ClickListener? = null
|
||||
|
||||
constructor(builder: Builder,context: Context) : super(context) {
|
||||
commonTips?.text = builder.tipsStr
|
||||
commonCancel?.text = builder.cancelStr
|
||||
commonConfirm?.text = builder.confirmStr
|
||||
}
|
||||
|
||||
init{
|
||||
setContentView(R.layout.dialog_sweeper_no_title)
|
||||
|
||||
setCanceledOnTouchOutside(true)
|
||||
|
||||
commonConfirm = findViewById(R.id.sweeper_common_confirm)
|
||||
commonCancel = findViewById(R.id.sweeper_common_cancel)
|
||||
commonTips = findViewById(R.id.sweeper_common_tips)
|
||||
|
||||
commonConfirm?.setOnClickListener{
|
||||
clickListener?.confirm()
|
||||
dismiss()
|
||||
}
|
||||
commonCancel?.setOnClickListener {
|
||||
clickListener?.cancel()
|
||||
dismiss()
|
||||
}
|
||||
}
|
||||
|
||||
fun setClickListener(clickListener: ClickListener) {
|
||||
this.clickListener = clickListener
|
||||
}
|
||||
|
||||
fun showUpgradeDialog(){
|
||||
if(isShowing){
|
||||
return
|
||||
}
|
||||
show()
|
||||
}
|
||||
|
||||
interface ClickListener{
|
||||
fun confirm()
|
||||
fun cancel()
|
||||
}
|
||||
|
||||
class Builder{
|
||||
var tipsStr:String = ""
|
||||
var confirmStr:String = ""
|
||||
var cancelStr:String = ""
|
||||
fun tips(tips: String) : Builder{
|
||||
this.tipsStr = tips
|
||||
return this
|
||||
}
|
||||
|
||||
fun confirmStr(commit: String) : Builder{
|
||||
this.confirmStr = commit
|
||||
return this
|
||||
}
|
||||
|
||||
fun cancelStr(cancel: String) : Builder{
|
||||
this.cancelStr = cancel
|
||||
return this
|
||||
}
|
||||
|
||||
fun build(context: Context): SweeperNoTitleCommonDialog? {
|
||||
return SweeperNoTitleCommonDialog(this,context)
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,91 @@
|
||||
package com.mogo.och.sweeper.ui.popwindow
|
||||
|
||||
import android.content.Context
|
||||
import android.graphics.Color
|
||||
import android.graphics.drawable.ColorDrawable
|
||||
import android.view.LayoutInflater
|
||||
import android.view.View
|
||||
import android.view.ViewGroup.LayoutParams
|
||||
import android.widget.PopupWindow
|
||||
import android.widget.TextView
|
||||
import com.mogo.och.sweeper.R
|
||||
import com.mogo.och.sweeper.constant.TaskStatusEnum
|
||||
|
||||
/**
|
||||
* 当前任务操作菜单栏
|
||||
*/
|
||||
class MenuPopWindow : PopupWindow, View.OnClickListener{
|
||||
|
||||
private var mTvJumpOverTask: TextView? = null
|
||||
|
||||
private var mTaskJumpLineView: View? = null
|
||||
|
||||
private var mTvEndTask: TextView? = null
|
||||
|
||||
private var mTvCancelTask: TextView? = null
|
||||
|
||||
private var mMenuItemClickListener:OnMenuItemOnClickListener?=null
|
||||
|
||||
constructor(context: Context,menuItemClickListener:OnMenuItemOnClickListener) : super(context) {
|
||||
init(context)
|
||||
this.mMenuItemClickListener=menuItemClickListener
|
||||
}
|
||||
|
||||
/**
|
||||
* 初始化布局
|
||||
*/
|
||||
private fun init(context: Context) {
|
||||
setBackgroundDrawable(ColorDrawable(Color.TRANSPARENT))
|
||||
var view: View = LayoutInflater.from(context).inflate(R.layout.sweeper_task_menu, null)
|
||||
mTvJumpOverTask = view.findViewById(R.id.tvJumpOverTask)
|
||||
mTaskJumpLineView = view.findViewById(R.id.taskJumpLineView)
|
||||
mTvEndTask = view.findViewById(R.id.tvEndTask)
|
||||
mTvCancelTask = view.findViewById(R.id.tvCancelTask)
|
||||
mTvJumpOverTask?.setOnClickListener(this)
|
||||
mTvEndTask?.setOnClickListener(this)
|
||||
mTvCancelTask?.setOnClickListener(this)
|
||||
width = context.resources.getDimension(R.dimen.dp_174).toInt()
|
||||
height = LayoutParams.WRAP_CONTENT
|
||||
contentView = view
|
||||
isFocusable = true
|
||||
isOutsideTouchable = true
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置是否是手动任务
|
||||
* 1:云端自动驾驶任务
|
||||
* 2:云端手动驾驶任务
|
||||
* 3: 运营任务
|
||||
*/
|
||||
fun setMenuView(type: Int) {
|
||||
if (type == 1) {
|
||||
mTvJumpOverTask?.visibility = View.GONE
|
||||
mTaskJumpLineView?.visibility = View.GONE
|
||||
} else {
|
||||
mTvJumpOverTask?.visibility = View.VISIBLE
|
||||
mTaskJumpLineView?.visibility = View.VISIBLE
|
||||
}
|
||||
}
|
||||
|
||||
interface OnMenuItemOnClickListener {
|
||||
fun onMenuItemClick(itemType: TaskStatusEnum)
|
||||
}
|
||||
|
||||
override fun onClick(v: View) {
|
||||
when(v.id){
|
||||
R.id.tvJumpOverTask->{
|
||||
mMenuItemClickListener?.onMenuItemClick(TaskStatusEnum.JUMP_OVER_SUBTASK)
|
||||
dismiss()
|
||||
}
|
||||
R.id.tvEndTask->{
|
||||
mMenuItemClickListener?.onMenuItemClick(TaskStatusEnum.END_TASK)
|
||||
dismiss()
|
||||
}
|
||||
R.id.tvCancelTask->{
|
||||
mMenuItemClickListener?.onMenuItemClick(TaskStatusEnum.CANCEL_TASK)
|
||||
dismiss()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,59 @@
|
||||
package com.mogo.och.sweeper.ui.popwindow
|
||||
|
||||
import android.content.Context
|
||||
import android.graphics.Color
|
||||
import android.graphics.drawable.ColorDrawable
|
||||
import android.view.LayoutInflater
|
||||
import android.view.ViewGroup
|
||||
import android.widget.PopupWindow
|
||||
import chassis.ChassisStatesOuterClass
|
||||
import com.mogo.och.sweeper.R
|
||||
import com.mogo.och.sweeper.callback.ICleaningModeStateCallback
|
||||
import com.mogo.och.sweeper.constant.OperateStateEnum
|
||||
import com.mogo.och.sweeper.ui.SweeperOperatePanelView
|
||||
|
||||
/**
|
||||
* 清扫车面板浮窗
|
||||
*/
|
||||
class SweeperOperatePanelPopWindow : PopupWindow{
|
||||
|
||||
private var mOperatePanelView: SweeperOperatePanelView? = null
|
||||
|
||||
constructor(context: Context) : super(context) {
|
||||
init(context)
|
||||
}
|
||||
private fun init(context: Context) {
|
||||
setBackgroundDrawable(ColorDrawable(Color.TRANSPARENT))
|
||||
mOperatePanelView = LayoutInflater.from(context).inflate(R.layout.sweeper_popwindow_operate_panel, null) as SweeperOperatePanelView?
|
||||
width = ViewGroup.LayoutParams.WRAP_CONTENT
|
||||
height = ViewGroup.LayoutParams.WRAP_CONTENT
|
||||
contentView = mOperatePanelView
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置清扫模式数据
|
||||
*/
|
||||
fun setCleanSystemState(
|
||||
cleanSystemState: ChassisStatesOuterClass.SweeperFuTianTaskSystemStates?,
|
||||
cleaningModeStateCallback: ICleaningModeStateCallback
|
||||
) {
|
||||
mOperatePanelView?.setSweeperFutianCleanSystemState(cleanSystemState, cleaningModeStateCallback)
|
||||
}
|
||||
|
||||
/**.
|
||||
*
|
||||
* 设置是否让popWindow消失
|
||||
*/
|
||||
fun setIsOutsideTouchable(isOutsideTouchable:Boolean){
|
||||
this.isFocusable = isOutsideTouchable
|
||||
this.isOutsideTouchable = isOutsideTouchable
|
||||
this.isTouchable=isOutsideTouchable
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置是否展示状态同步中
|
||||
*/
|
||||
fun showSyncing(operateState: OperateStateEnum){
|
||||
mOperatePanelView?.showSyncing(operateState)
|
||||
}
|
||||
}
|
||||
@@ -1,13 +1,17 @@
|
||||
package com.mogo.och.sweeper.util;
|
||||
|
||||
import static com.mogo.eagle.core.utilcode.mogo.logger.scene.SceneConstant.M_SWEEPER;
|
||||
|
||||
import android.os.Build;
|
||||
import android.text.TextUtils;
|
||||
|
||||
import com.mogo.cloud.passport.MoGoAiCloudClientConfig;
|
||||
import com.mogo.commons.debug.DebugConfig;
|
||||
import com.mogo.commons.utils.MogoAnalyticUtils;
|
||||
import com.mogo.eagle.core.data.app.AppConfigInfo;
|
||||
import com.mogo.eagle.core.function.api.autopilot.IMoGoAutopilotStatusListener;
|
||||
import com.mogo.commons.utils.MogoAnalyticUtils;
|
||||
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;
|
||||
@@ -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);
|
||||
|
||||
MogoAnalyticUtils.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,14 +108,43 @@ public class SweeperAnalyticsManager {
|
||||
mStartAutopilotParams.put(SweeperConst.EVENT_PARAM_LINE_ID, lineId);
|
||||
|
||||
if (send) {
|
||||
if (mStartAutopilotParams.isEmpty()) return;
|
||||
// 开启成功,上报埋点
|
||||
if (startAutopilotRunnable != null) {
|
||||
UiThreadHandler.removeCallbacks(startAutopilotRunnable);
|
||||
}
|
||||
clearStartAutopilotFailureMSG();
|
||||
removeWaitingCallback();
|
||||
mStartAutopilotParams.put(SweeperConst.EVENT_PARAM_START_RESULT, true);
|
||||
MogoAnalyticUtils.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);
|
||||
MogoAnalyticUtils.INSTANCE.track(SweeperConst.EVENT_KEY_AP_UNABLE_START_REASON, params);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,23 +1,23 @@
|
||||
package com.mogo.och.sweeper.util;
|
||||
|
||||
import chassis.ChassisStatesOuterClass;
|
||||
import chassis.SpecialVehicleTaskCmdOuterClass;
|
||||
import chassis.VehicleStateOuterClass;
|
||||
|
||||
/**
|
||||
* 清扫车-福田,构建业务命令数据的工具类
|
||||
*/
|
||||
public class SweeperFutianCmdUtil {
|
||||
private static final int CLEAN_WORK_OPEN = 1; //清扫作业-开启
|
||||
private static final int CLEAN_WORK_CLOSE = 2;//清扫作业-关闭
|
||||
public static final int CLEAN_WORK_OPEN = 1; //清扫作业-开启
|
||||
public static final int CLEAN_WORK_CLOSE = 2;//清扫作业-关闭
|
||||
public static final int CLEAN_MODE_PURE_SWEEP = 1;//作业模式-纯扫
|
||||
public static final int CLEAN_MODE_WASH_SWEEP = 2;//作业模式-洗扫
|
||||
public static final int CLEAN_MODE_PURE_WASH = 3;//作业模式-纯洗
|
||||
public static final int CLEAN_MODE_PURE_DRAW = 4;//作业模式-纯吸
|
||||
private static final int CLEAN_MODE_CLOSE = 5;//作业模式-关闭
|
||||
public static final int CLEAN_MODE_CLOSE = 5;//作业模式-关闭
|
||||
public static final int CLEAN_DIRECTION_BOTH_SIDE = 1;//清扫方向-两侧
|
||||
public static final int CLEAN_DIRECTION_LEFT_SIDE = 2;//清扫方向-左侧
|
||||
public static final int CLEAN_DIRECTION_RIGHT_SIDE = 3;//清扫方向-右侧
|
||||
private static final int CLEAN_DIRECTION_CLOSE = 4;//清扫方向-关闭
|
||||
public static final int CLEAN_DIRECTION_CLOSE = 4;//清扫方向-关闭
|
||||
public static final int CLEAN_INTENSITY_STRAND = 1;//作业强度-标准
|
||||
public static final int CLEAN_INTENSITY_STRONG = 2;//作业强度-加强
|
||||
|
||||
@@ -131,13 +131,67 @@ public class SweeperFutianCmdUtil {
|
||||
.setRoboSweeperFutianCleanCmd(fuTianCleanCmd).build();
|
||||
}
|
||||
|
||||
/**
|
||||
* 判断是否有作业模式
|
||||
* @param cleanSystemState
|
||||
* @return true:没有作业模式 false:有作业模式
|
||||
*/
|
||||
public static boolean checkIfCleanMode(ChassisStatesOuterClass.SweeperFuTianTaskSystemStates cleanSystemState){
|
||||
return (!cleanSystemState.getSecuModWashSweepSts()&&!cleanSystemState.getSecuModWashSts()&&!cleanSystemState.getSecuWorkTonSts())&&
|
||||
(!cleanSystemState.getSecuWorkLeftSts()&&!cleanSystemState.getSecuWorkRightSts()&&!cleanSystemState.getSecuWorkOnBothsidesSts());
|
||||
}
|
||||
|
||||
/**
|
||||
* 判断是否有清扫方向
|
||||
* @param cleanSystemState
|
||||
* @return true:没有清扫方向 false:有清扫方向
|
||||
*/
|
||||
public static boolean checkIfCleanDirection(ChassisStatesOuterClass.SweeperFuTianTaskSystemStates cleanSystemState){
|
||||
return !cleanSystemState.getSecuWorkLeftSts()&&!cleanSystemState.getSecuWorkRightSts()&&!cleanSystemState.getSecuWorkOnBothsidesSts();
|
||||
}
|
||||
/**
|
||||
* 判断是否有作业强度
|
||||
* @param cleanSystemState
|
||||
* @return true:没有作业强度 false:有作业强度
|
||||
*/
|
||||
public static boolean checkIfCleanIntensity(ChassisStatesOuterClass.SweeperFuTianTaskSystemStates cleanSystemState){
|
||||
return !cleanSystemState.getSecuWorkStandSts()&&!cleanSystemState.getSecuWorkStrongSts();
|
||||
}
|
||||
/**
|
||||
* 判断是否纯扫模式
|
||||
*
|
||||
* @param cleanSystemState
|
||||
* @return
|
||||
*/
|
||||
public static boolean checkIfCleanModePureSweep(ChassisStatesOuterClass.SweeperFuTianTaskSystemStates cleanSystemState) {
|
||||
// 作业模式状态
|
||||
// 洗扫
|
||||
boolean clean_mode_wash_sweep = cleanSystemState.getSecuModWashSweepSts();
|
||||
// 纯洗
|
||||
boolean clean_mode_pure_wash = cleanSystemState.getSecuModWashSts();
|
||||
// 纯吸
|
||||
boolean clean_mode_pure_draw = cleanSystemState.getSecuWorkTonSts();
|
||||
|
||||
// 清扫方向状态
|
||||
// 左侧
|
||||
boolean clean_direction_left_side = cleanSystemState.getSecuWorkLeftSts();
|
||||
// 右侧
|
||||
boolean clean_direction_right_side = cleanSystemState.getSecuWorkRightSts();
|
||||
// 两侧
|
||||
boolean clean_direction_both_side = cleanSystemState.getSecuWorkOnBothsidesSts();
|
||||
|
||||
// 纯扫 模式判断:不是另外其他3个模式,同时有清扫方向,说明开启了纯扫模式
|
||||
boolean clean_mode_pure_sweep = (clean_direction_left_side || clean_direction_right_side || clean_direction_both_side)
|
||||
&& (!clean_mode_wash_sweep && !clean_mode_pure_wash && !clean_mode_pure_draw);
|
||||
return clean_mode_pure_sweep;
|
||||
}
|
||||
/**
|
||||
* 构建底盘Mock数据
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public static VehicleStateOuterClass.SweeperFuTianCleanSystemState buildSweeperFuTionCleanSystemStateMockData() {
|
||||
VehicleStateOuterClass.SweeperFuTianCleanSystemState.Builder builder = VehicleStateOuterClass.SweeperFuTianCleanSystemState.newBuilder();
|
||||
public static ChassisStatesOuterClass.SweeperFuTianTaskSystemStates buildSweeperFuTionCleanSystemStateMockData() {
|
||||
ChassisStatesOuterClass.SweeperFuTianTaskSystemStates.Builder builder = ChassisStatesOuterClass.SweeperFuTianTaskSystemStates.newBuilder();
|
||||
builder.setSecuMotWorkSts(true);
|
||||
builder.setSecuModWashSts(true);
|
||||
builder.setSecuWorkOnBothsidesSts(true);
|
||||
|
||||
@@ -0,0 +1,61 @@
|
||||
package com.mogo.och.sweeper.util;
|
||||
|
||||
|
||||
import android.content.Context;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
|
||||
/**
|
||||
* @author donghongyu
|
||||
* @date 12/18/20 5:37 PM
|
||||
*/
|
||||
public class SweeperMapAssetStyleUtil {
|
||||
|
||||
public static byte[] getAssetsStyle(Context context,String fileName) {
|
||||
byte[] buffer1 = null;
|
||||
InputStream is1 = null;
|
||||
try {
|
||||
is1 = context.getResources().getAssets().open(fileName); //eg. over_view_style.data
|
||||
int lenght1 = is1.available();
|
||||
buffer1 = new byte[lenght1];
|
||||
is1.read(buffer1);
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
} finally {
|
||||
try {
|
||||
if (is1 != null) {
|
||||
is1.close();
|
||||
}
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
return buffer1;
|
||||
}
|
||||
|
||||
|
||||
public static byte[] getAssetsExtraStyle(Context context, String fileName) {
|
||||
byte[] buffer1 = null;
|
||||
InputStream is1 = null;
|
||||
try {
|
||||
is1 = context.getResources().getAssets().open(fileName); //eg. over_view_style_extra.data
|
||||
int lenght1 = is1.available();
|
||||
buffer1 = new byte[lenght1];
|
||||
is1.read(buffer1);
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
} finally {
|
||||
try {
|
||||
if (is1 != null) {
|
||||
is1.close();
|
||||
}
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
return buffer1;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -1,24 +1,22 @@
|
||||
package com.mogo.och.sweeper.util;
|
||||
|
||||
import androidx.annotation.Nullable;
|
||||
|
||||
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.sweeper.bean.SweeperRoutesResult;
|
||||
import com.mogo.och.sweeper.bean.SweeperSubTaskDetailBean;
|
||||
import com.mogo.och.sweeper.constant.SweeperConst;
|
||||
import com.mogo.och.sweeper.model.SweeperOrderModel;
|
||||
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
import androidx.annotation.Nullable;
|
||||
import io.reactivex.Observable;
|
||||
import io.reactivex.android.schedulers.AndroidSchedulers;
|
||||
import io.reactivex.disposables.Disposable;
|
||||
import io.reactivex.schedulers.Schedulers;
|
||||
import mogo_msg.MogoReportMsg;
|
||||
|
||||
import static com.mogo.eagle.core.utilcode.mogo.logger.scene.SceneConstant.M_BUS;
|
||||
import static com.mogo.eagle.core.utilcode.mogo.logger.scene.SceneConstant.M_SWEEPER;
|
||||
|
||||
/**
|
||||
* Bus轨迹管理:给MEC下发用于轨迹下载的信息
|
||||
@@ -47,82 +45,63 @@ 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()) {
|
||||
CallerLogger.INSTANCE.d(M_BUS + TAG, "syncTrajectoryInfo() start.");
|
||||
startTrajReqLoop();
|
||||
public void syncTrajectoryInfo(SweeperSubTaskDetailBean sweeperSubTaskDetailBean) {
|
||||
if (sweeperSubTaskDetailBean != null) {
|
||||
CallerLogger.INSTANCE.d(M_SWEEPER + TAG, "syncTrajectoryInfo() start.");
|
||||
startTrajReqLoop(sweeperSubTaskDetailBean);
|
||||
} else {
|
||||
// 无路线信息or当前未在始发站
|
||||
CallerLogger.INSTANCE.d(M_BUS + TAG, "syncTrajectoryInfo() stop.");
|
||||
CallerLogger.INSTANCE.d(M_SWEEPER + TAG, "syncTrajectoryInfo() stop.");
|
||||
stopTrajReqLoop();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 接口MEC反馈的常规信息(MAP v2.5.0新增轨迹相关信息)
|
||||
*
|
||||
* @param guardianInfo
|
||||
*/
|
||||
public void onAutopilotGuardian(@Nullable MogoReportMsg.MogoReportMessage guardianInfo) {
|
||||
if (guardianInfo == null || !guardianInfo.hasCode()) return;
|
||||
if ("ISYS_INIT_TRAJECTORY_START".equals(guardianInfo.getCode())) {
|
||||
// 1. 轨迹管理_轨迹开始下载(本地已有对应轨迹也触发)
|
||||
CallerLogger.INSTANCE.d(M_BUS + TAG, "onAutopilotGuardian() 轨迹开始下载");
|
||||
CallerLogger.INSTANCE.d(M_SWEEPER + TAG, "onAutopilotGuardian() 轨迹开始下载");
|
||||
// ToastUtils.showShort("轨迹开始下载");
|
||||
stopTrajReqLoop();
|
||||
} else if ("ISYS_INIT_TRAJECTORY_SUCCESS".equals(guardianInfo.getCode())) {
|
||||
// 2. 轨迹管理_轨迹下载成功(本地已有对应轨迹也触发)
|
||||
CallerLogger.INSTANCE.d(M_BUS + TAG, "onAutopilotGuardian() 轨迹下载成功");
|
||||
CallerLogger.INSTANCE.d(M_SWEEPER + TAG, "onAutopilotGuardian() 轨迹下载成功");
|
||||
// ToastUtils.showShort("轨迹下载成功");
|
||||
stopTrajReqLoop();
|
||||
} else if ("ISYS_INIT_TRAJECTORY_FAILURE".equals(guardianInfo.getCode())) {
|
||||
// 3. 轨迹管理_轨迹下载失败,本地无对应轨迹
|
||||
CallerLogger.INSTANCE.d(M_BUS + TAG, "onAutopilotGuardian() " +
|
||||
CallerLogger.INSTANCE.d(M_SWEEPER + TAG, "onAutopilotGuardian() " +
|
||||
"轨迹下载失败,本地无对应轨迹");
|
||||
// ToastUtils.showShort("轨迹下载失败,本地无对应轨迹");
|
||||
} else if ("ISYS_INIT_TRAJECTORY_WARNING".equals(guardianInfo.getCode())) {
|
||||
// 4. 轨迹管理_轨迹下载失败,本地有对应轨迹,认为成功
|
||||
CallerLogger.INSTANCE.d(M_BUS + TAG, "onAutopilotGuardian() " +
|
||||
CallerLogger.INSTANCE.d(M_SWEEPER + TAG, "onAutopilotGuardian() " +
|
||||
"轨迹下载失败,本地有对应轨迹,认为成功");
|
||||
// ToastUtils.showShort("轨迹下载失败,本地有对应轨迹,认为成功");
|
||||
} else if ("ISYS_INIT_TRAJECTORY_TIMEOUT".equals(guardianInfo.getCode())) {
|
||||
// 5. 轨迹管理_轨迹下载超时
|
||||
CallerLogger.INSTANCE.d(M_BUS + TAG, "onAutopilotGuardian() 轨迹下载超时");
|
||||
CallerLogger.INSTANCE.d(M_SWEEPER + TAG, "onAutopilotGuardian() 轨迹下载超时");
|
||||
// ToastUtils.showShort("轨迹下载超时");
|
||||
}
|
||||
}
|
||||
|
||||
private void setupAutoPilotLine() {
|
||||
SweeperRoutesResult routesResult = SweeperOrderModel.getInstance().getBusRoutesResult();
|
||||
if (routesResult == null) {
|
||||
CallerLogger.INSTANCE.e(M_BUS + TAG,
|
||||
"setupAutoPilotLine(): routesResult is null.");
|
||||
private void setupAutoPilotLine(SweeperSubTaskDetailBean subTaskDetail) {
|
||||
if (subTaskDetail == null) {
|
||||
CallerLogger.INSTANCE.e(M_SWEEPER + TAG, "setupAutoPilotLine(): routesResult is null.");
|
||||
return;
|
||||
} else {
|
||||
if (mAutoPilotLine == null) {
|
||||
mAutoPilotLine = new AutopilotControlParameters.AutoPilotLine(routesResult.getLineId(),
|
||||
routesResult.csvFileUrl, routesResult.csvFileMd5,
|
||||
routesResult.txtFileUrl, routesResult.txtFileMd5,
|
||||
routesResult.contrailSaveTime, routesResult.carModel,
|
||||
routesResult.csvFileUrlDPQP, routesResult.csvFileMd5DPQP,
|
||||
routesResult.txtFileUrlDPQP, routesResult.txtFileMd5DPQP,
|
||||
routesResult.contrailSaveTimeDPQP);
|
||||
} else {
|
||||
mAutoPilotLine.setLineId(routesResult.getLineId());
|
||||
mAutoPilotLine.setTrajUrl(routesResult.csvFileUrl);
|
||||
mAutoPilotLine.setTrajMd5(routesResult.csvFileMd5);
|
||||
mAutoPilotLine.setStopUrl(routesResult.txtFileUrl);
|
||||
mAutoPilotLine.setStopMd5(routesResult.txtFileMd5);
|
||||
mAutoPilotLine.setTimestamp(routesResult.contrailSaveTime);
|
||||
mAutoPilotLine.setVehicleModel(routesResult.carModel);
|
||||
mAutoPilotLine.setTrajUrl_dpqp(routesResult.csvFileUrlDPQP);
|
||||
mAutoPilotLine.setTrajMd5_dpqp(routesResult.csvFileMd5DPQP);
|
||||
mAutoPilotLine.setStopUrl_dpqp(routesResult.txtFileUrlDPQP);
|
||||
mAutoPilotLine.setStopMd5_dpqp(routesResult.txtFileMd5DPQP);
|
||||
mAutoPilotLine.setTimestamp_dpqp(routesResult.contrailSaveTimeDPQP);
|
||||
}
|
||||
mAutoPilotLine = new AutopilotControlParameters.AutoPilotLine(subTaskDetail.getLineId(),
|
||||
subTaskDetail.getCsvFileUrl(), subTaskDetail.getCsvFileMd5(),
|
||||
subTaskDetail.getTxtFileUrl(), subTaskDetail.getTxtFileMd5(),
|
||||
subTaskDetail.getPublishTime(), subTaskDetail.getCarModel(),
|
||||
subTaskDetail.getCsvFileUrlDPQP(), subTaskDetail.getCsvFileMd5DPQP(),
|
||||
subTaskDetail.getTxtFileUrlDPQP(), subTaskDetail.getTxtFileMd5DPQP(),
|
||||
subTaskDetail.getPublishTimeDPQP());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -142,14 +121,14 @@ public class SweeperTrajectoryManager {
|
||||
mAutoPilotLine.setTimestamp_dpqp(0);
|
||||
}
|
||||
|
||||
private void startTrajReqLoop() {
|
||||
private void startTrajReqLoop(SweeperSubTaskDetailBean sweeperSubTaskDetailBean) {
|
||||
if (mSendReqDisposable != null && !mSendReqDisposable.isDisposed()) {
|
||||
return;
|
||||
}
|
||||
CallerLogger.INSTANCE.d(M_BUS + TAG, "startTrajReqLoop()");
|
||||
setupAutoPilotLine();
|
||||
CallerLogger.INSTANCE.d(M_SWEEPER + TAG, "startTrajReqLoop()");
|
||||
setupAutoPilotLine(sweeperSubTaskDetailBean);
|
||||
mSendReqDisposable = Observable.interval(SweeperConst.LOOP_DELAY,
|
||||
SweeperConst.LOOP_PERIOD_10S, TimeUnit.MILLISECONDS)
|
||||
SweeperConst.LOOP_PERIOD_10S, TimeUnit.MILLISECONDS)
|
||||
.map((aLong -> aLong + 1))
|
||||
.subscribeOn(Schedulers.io())
|
||||
.observeOn(AndroidSchedulers.mainThread())
|
||||
@@ -158,14 +137,14 @@ public class SweeperTrajectoryManager {
|
||||
stopTrajReqLoop();
|
||||
return;
|
||||
}
|
||||
CallerLogger.INSTANCE.d(M_BUS + TAG, "loop sendTrajectoryReq: " + aLong);
|
||||
CallerLogger.INSTANCE.d(M_SWEEPER + TAG, "loop sendTrajectoryReq: " + aLong);
|
||||
sendTrajectoryReq();
|
||||
});
|
||||
}
|
||||
|
||||
public void stopTrajReqLoop() {
|
||||
if (mSendReqDisposable != null) {
|
||||
CallerLogger.INSTANCE.d(M_BUS + TAG, "stopTrajReqLoop()");
|
||||
CallerLogger.INSTANCE.d(M_SWEEPER + TAG, "stopTrajReqLoop()");
|
||||
mSendReqDisposable.dispose();
|
||||
mSendReqDisposable = null;
|
||||
clearAutoPilotLine();
|
||||
@@ -174,7 +153,7 @@ public class SweeperTrajectoryManager {
|
||||
|
||||
private void sendTrajectoryReq() {
|
||||
if (mAutoPilotLine == null) {
|
||||
CallerLogger.INSTANCE.e(M_BUS + TAG, "sendTrajectoryReq(): mAutoPilotLine is null!!!");
|
||||
CallerLogger.INSTANCE.e(M_SWEEPER + TAG, "sendTrajectoryReq(): mAutoPilotLine is null!!!");
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -198,7 +177,7 @@ public class SweeperTrajectoryManager {
|
||||
// mAutoPilotLine.setVehicleModel("红旗H9");
|
||||
|
||||
CallerAutoPilotControlManager.INSTANCE.sendTrajectoryDownloadReq(mAutoPilotLine);
|
||||
CallerLogger.INSTANCE.d(M_BUS + TAG, "sendTrajectoryReq(): "
|
||||
CallerLogger.INSTANCE.d(M_SWEEPER + TAG, "sendTrajectoryReq(): "
|
||||
+ GsonUtils.toJson(mAutoPilotLine));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,32 @@
|
||||
package com.mogo.och.sweeper.view
|
||||
|
||||
import android.content.Context
|
||||
import android.util.AttributeSet
|
||||
import android.view.LayoutInflater
|
||||
import android.widget.LinearLayout
|
||||
import com.mogo.och.sweeper.R
|
||||
import kotlinx.android.synthetic.main.sweeper_item_legend.view.*
|
||||
|
||||
/**
|
||||
* 任务路线全览图图例
|
||||
*/
|
||||
class LegendItemView:LinearLayout {
|
||||
constructor(context: Context) : super(context) {}
|
||||
constructor(context: Context, attrs: AttributeSet?) : super(context, attrs) {
|
||||
initView(context)
|
||||
}
|
||||
constructor(context: Context, attrs: AttributeSet?, defStyleAttr: Int) : super(context, attrs, defStyleAttr) {}
|
||||
constructor(context: Context, attrs: AttributeSet?, defStyleAttr: Int, defStyleRes: Int) : super(context, attrs, defStyleAttr, defStyleRes) {}
|
||||
|
||||
private fun initView(context: Context) {
|
||||
LayoutInflater.from(context).inflate(R.layout.sweeper_item_legend, this)
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置数据
|
||||
*/
|
||||
fun setData(resId:Int,text:String){
|
||||
sweeperLegendIcon.setImageResource(resId)
|
||||
sweeperLegendText.text = text
|
||||
}
|
||||
}
|
||||
@@ -6,14 +6,14 @@ import android.view.MotionEvent;
|
||||
|
||||
import androidx.constraintlayout.widget.ConstraintLayout;
|
||||
|
||||
import com.mogo.commons.debug.DebugConfig;
|
||||
|
||||
/**
|
||||
* 强制拦截所有touch时间的约束布局
|
||||
*
|
||||
* @author tongchenfei
|
||||
*/
|
||||
public class NoTouchConstraintLayout extends ConstraintLayout {
|
||||
private boolean interceptTouchEvent = false;
|
||||
|
||||
public NoTouchConstraintLayout(Context context) {
|
||||
super(context);
|
||||
}
|
||||
@@ -28,10 +28,18 @@ public class NoTouchConstraintLayout extends ConstraintLayout {
|
||||
|
||||
@Override
|
||||
public boolean onInterceptTouchEvent(MotionEvent ev) {
|
||||
if(DebugConfig.isDebug()){
|
||||
return super.onInterceptTouchEvent(ev);
|
||||
}else {
|
||||
if (interceptTouchEvent) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置事件拦截
|
||||
*
|
||||
* @param interceptTouchEvent
|
||||
*/
|
||||
public void setInterceptTouchEvent(boolean interceptTouchEvent) {
|
||||
this.interceptTouchEvent = interceptTouchEvent;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,30 @@
|
||||
package com.mogo.och.sweeper.view;
|
||||
|
||||
import android.content.Context;
|
||||
import android.util.AttributeSet;
|
||||
import android.view.MotionEvent;
|
||||
import android.widget.FrameLayout;
|
||||
|
||||
/**
|
||||
* 强制拦截所有touch时间的约束布局
|
||||
*
|
||||
* @author tongchenfei
|
||||
*/
|
||||
public class NoTouchFrameLayout extends FrameLayout {
|
||||
public NoTouchFrameLayout(Context context) {
|
||||
super(context);
|
||||
}
|
||||
|
||||
public NoTouchFrameLayout(Context context, AttributeSet attrs) {
|
||||
super(context, attrs);
|
||||
}
|
||||
|
||||
public NoTouchFrameLayout(Context context, AttributeSet attrs, int defStyleAttr) {
|
||||
super(context, attrs, defStyleAttr);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onInterceptTouchEvent(MotionEvent ev) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,57 @@
|
||||
package com.mogo.och.sweeper.view
|
||||
|
||||
import android.content.Context
|
||||
import android.graphics.Color
|
||||
import android.util.AttributeSet
|
||||
import android.view.LayoutInflater
|
||||
import android.view.View
|
||||
import androidx.constraintlayout.widget.ConstraintLayout
|
||||
import com.mogo.och.common.module.utils.DateTimeUtil
|
||||
import com.mogo.och.sweeper.R
|
||||
import com.mogo.och.sweeper.bean.SubInfo
|
||||
import kotlinx.android.synthetic.main.sweeper_subtask_view.view.*
|
||||
|
||||
/**
|
||||
* 子任务View
|
||||
*/
|
||||
class SubTaskView : ConstraintLayout {
|
||||
constructor(context: Context) : super(context) {}
|
||||
constructor(context: Context, attrs: AttributeSet?) : super(context, attrs) {
|
||||
initView(context)
|
||||
}
|
||||
|
||||
constructor(context: Context, attrs: AttributeSet?, defStyleAttr: Int) : super(context, attrs, defStyleAttr) {}
|
||||
constructor(context: Context, attrs: AttributeSet?, defStyleAttr: Int, defStyleRes: Int) : super(context, attrs, defStyleAttr, defStyleRes) {}
|
||||
|
||||
private fun initView(context: Context) {
|
||||
LayoutInflater.from(context).inflate(R.layout.sweeper_subtask_view, this)
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置子任务信息
|
||||
*/
|
||||
fun setData(taskInfo: SubInfo, isSelect: Boolean = false, isLastTask: Boolean = false) {
|
||||
tvSubTaskName.text = taskInfo.taskName
|
||||
var mileage: String = if (taskInfo.mileage < 1000) {
|
||||
"${taskInfo.mileage}米"
|
||||
} else {
|
||||
"${taskInfo.mileage / 1000F}千米"
|
||||
}
|
||||
val time=taskInfo.timeSpent.toLong()
|
||||
var timeSpent=if(DateTimeUtil.secondsToHourStr(time)!=""){
|
||||
"${DateTimeUtil.secondsToHourStr(time)}小时${DateTimeUtil.secondsToMinuteStr(time)}分钟"
|
||||
}else{
|
||||
"${DateTimeUtil.secondsToMinuteStr(time)}分钟"
|
||||
}
|
||||
tvSubTaskDesc.text = "全程约${mileage},预计耗时$timeSpent"
|
||||
tvSubTaskName.setTextColor(if (isSelect) Color.parseColor("#3BD2FF") else Color.parseColor("#FFFFFF"))
|
||||
if (isSelect) {
|
||||
ivSubTaskSelect.visibility = View.VISIBLE
|
||||
ivSubTask.visibility = View.GONE
|
||||
} else {
|
||||
ivSubTaskSelect.visibility = View.GONE
|
||||
ivSubTask.visibility = View.VISIBLE
|
||||
}
|
||||
ivRightDownArrow.visibility = if (isLastTask) View.GONE else View.VISIBLE
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,233 @@
|
||||
package com.mogo.och.sweeper.view
|
||||
|
||||
import android.content.Context
|
||||
import android.graphics.Color
|
||||
import android.util.AttributeSet
|
||||
import android.view.LayoutInflater
|
||||
import android.view.View
|
||||
import androidx.constraintlayout.widget.ConstraintLayout
|
||||
import com.mogo.eagle.core.function.api.autopilot.IMoGoAutopilotStatusListener
|
||||
import com.mogo.eagle.core.utilcode.util.ClickUtils
|
||||
import com.mogo.eagle.core.utilcode.util.ToastUtils
|
||||
import com.mogo.och.common.module.utils.DateTimeUtil
|
||||
import com.mogo.och.sweeper.R
|
||||
import com.mogo.och.sweeper.bean.SubInfo
|
||||
import com.mogo.och.sweeper.bean.SweeperSubTaskBean
|
||||
import com.mogo.och.sweeper.constant.SubTaskTypeEnum
|
||||
import com.mogo.och.sweeper.presenter.SweeperPresenter
|
||||
import com.mogo.och.sweeper.ui.popwindow.MenuPopWindow
|
||||
import kotlinx.android.synthetic.main.sweeper_current_task_info.view.*
|
||||
|
||||
/**
|
||||
* 清扫车当前任务信息展示
|
||||
*/
|
||||
class SweeperCurrentTaskInfoView : ConstraintLayout {
|
||||
private val TAG: String = "SweeperCurrentTaskInfoView"
|
||||
|
||||
//当前任务操作菜单
|
||||
private var mTaskMenuPopWindow: MenuPopWindow? = null
|
||||
private var presenter: SweeperPresenter? = null
|
||||
private var mCurrentPosition = 0
|
||||
private var listTask: List<SubInfo>? = null
|
||||
private var mSubTaskType: SubTaskTypeEnum = SubTaskTypeEnum.AUTOPILOT_SUBTYPE
|
||||
private var mSubTaskStatus: Int = 1
|
||||
//当前自动驾驶状态
|
||||
private val mCurrentAutopilotStatus = 0
|
||||
|
||||
constructor(context: Context) : super(context) {}
|
||||
constructor(context: Context, attrs: AttributeSet?) : super(context, attrs) {
|
||||
initView(context)
|
||||
}
|
||||
|
||||
constructor(context: Context, attrs: AttributeSet?, defStyleAttr: Int) : super(context, attrs, defStyleAttr) {}
|
||||
constructor(context: Context, attrs: AttributeSet?, defStyleAttr: Int, defStyleRes: Int) : super(context, attrs, defStyleAttr, defStyleRes) {}
|
||||
|
||||
private fun initView(context: Context) {
|
||||
LayoutInflater.from(context).inflate(R.layout.sweeper_current_task_info, this)
|
||||
setEnableClickBtn(false)
|
||||
tvStartAuto.setOnClickListener {
|
||||
if (ClickUtils.isFastClick()){//防止重复点击
|
||||
if (mSubTaskStatus==1){
|
||||
ToastUtils.showLong("任务未开始无轨迹,无法启动自驾")
|
||||
return@setOnClickListener
|
||||
}
|
||||
if (mSubTaskType==SubTaskTypeEnum.MANUAL_DRIVING_SUBTYPE){
|
||||
ToastUtils.showLong("人工子任务无轨迹,无法启动自驾")
|
||||
return@setOnClickListener
|
||||
}
|
||||
if (mCurrentAutopilotStatus!=IMoGoAutopilotStatusListener.STATUS_PARALLEL_DRIVING){
|
||||
presenter?.startAutopilot()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置当前任务数据
|
||||
*/
|
||||
fun setData(
|
||||
workModePanelView: SweeperWorkModeView,
|
||||
subTaskBean: SweeperSubTaskBean?,
|
||||
currentPosition: Int,
|
||||
menuItemClickListener: MenuPopWindow.OnMenuItemOnClickListener,
|
||||
presenter: SweeperPresenter?
|
||||
) {
|
||||
this.presenter = presenter
|
||||
this.mCurrentPosition = currentPosition
|
||||
mTaskMenuPopWindow = MenuPopWindow(context, menuItemClickListener)
|
||||
subTaskBean?.apply {
|
||||
this@SweeperCurrentTaskInfoView.listTask = subList
|
||||
tvTaskName.text = taskName
|
||||
val calendar = DateTimeUtil.formatLongToCalendar(taskStartTime)
|
||||
tvTaskTime.text = DateTimeUtil.formatCalendarToString(calendar, DateTimeUtil.TAXI_HH_mm)
|
||||
}
|
||||
listTask?.let {
|
||||
mSubTaskStatus=it[currentPosition].taskStatus
|
||||
setEnableClickBtn(mSubTaskStatus==2)
|
||||
}
|
||||
setCurrentData(currentPosition)
|
||||
//任务操作菜单打开关闭处理
|
||||
ivMore.setOnClickListener {
|
||||
if (mTaskMenuPopWindow?.isShowing != true) {
|
||||
mTaskMenuPopWindow?.showAsDropDown(
|
||||
workModePanelView,
|
||||
resources.getDimension(R.dimen.dp_580).toInt(),
|
||||
resources.getDimension(R.dimen.dp_36).toInt()
|
||||
)
|
||||
} else {
|
||||
mTaskMenuPopWindow?.dismiss()
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置准备就绪按钮时都可以点击
|
||||
*/
|
||||
fun setEnableClickBtn(isWorking: Boolean) {
|
||||
readyTaskBtn.isClickable=!isWorking
|
||||
presenter?.setWorking(isWorking)
|
||||
if (isWorking) {
|
||||
tvTaskState.text = "正在作业"
|
||||
readyTaskBtn.text="任务中"
|
||||
readyTaskBtn.setTextColor(Color.parseColor("#FFFFFFFF"))
|
||||
tvTaskState.setBackgroundResource(R.drawable.bg_shape_task_state_working)
|
||||
readyTaskBtn.setBackgroundResource(R.drawable.sweeper_task_working)
|
||||
} else {
|
||||
tvTaskState.text = "暂未准备"
|
||||
readyTaskBtn.text="开始任务"
|
||||
readyTaskBtn.setTextColor(Color.parseColor("#66FFFFFF"))
|
||||
tvTaskState.setBackgroundResource(R.drawable.bg_shape_task_state_not_ready)
|
||||
readyTaskBtn.setBackgroundResource(R.drawable.sweeper_task_not_working)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置准备就绪按钮时都可以点击
|
||||
*/
|
||||
fun setStartAutoBtn(autopilotState: Int) {
|
||||
when (autopilotState) {
|
||||
IMoGoAutopilotStatusListener.STATUS_AUTOPILOT_DISABLE -> {
|
||||
tvStartAuto.text="自动驾驶"
|
||||
tvStartAuto.setTextColor(Color.parseColor("#66FFFFFF"))
|
||||
tvStartAuto.setBackgroundResource(R.drawable.sweeper_start_auto_not_running)
|
||||
}
|
||||
IMoGoAutopilotStatusListener.STATUS_AUTOPILOT_ENABLE -> {
|
||||
tvStartAuto.text="自动驾驶"
|
||||
tvStartAuto.setTextColor(Color.parseColor("#66FFFFFF"))
|
||||
tvStartAuto.setBackgroundResource(R.drawable.sweeper_start_auto_not_running)
|
||||
}
|
||||
IMoGoAutopilotStatusListener.STATUS_AUTOPILOT_RUNNING -> {
|
||||
tvStartAuto.text="自动驾驶"
|
||||
tvStartAuto.setTextColor(Color.parseColor("#FFFFFFFF"))
|
||||
tvStartAuto.setBackgroundResource(R.drawable.sweeper_start_auto_running)
|
||||
}
|
||||
IMoGoAutopilotStatusListener.STATUS_PARALLEL_DRIVING -> {
|
||||
tvStartAuto.text="平行驾驶"
|
||||
tvStartAuto.setTextColor(Color.parseColor("#FFFFFFFF"))
|
||||
tvStartAuto.setBackgroundResource(R.drawable.sweeper_start_auto_running)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 开始子任务
|
||||
*/
|
||||
private fun startSubTask() {
|
||||
listTask?.let {
|
||||
presenter?.startTask(
|
||||
isFirstSubTask(),
|
||||
isLastSubTask(),
|
||||
it[mCurrentPosition].taskId,
|
||||
if (it[mCurrentPosition].taskType == SubTaskTypeEnum.AUTOPILOT_SUBTYPE.code) SubTaskTypeEnum.AUTOPILOT_SUBTYPE else SubTaskTypeEnum.MANUAL_DRIVING_SUBTYPE,
|
||||
mSubTaskStatus
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 是否第一个子任务
|
||||
*/
|
||||
private fun isFirstSubTask(): Boolean {
|
||||
return mCurrentPosition == 0
|
||||
}
|
||||
|
||||
/**
|
||||
* 是否第一个子任务
|
||||
*/
|
||||
private fun isLastSubTask(): Boolean {
|
||||
return mCurrentPosition == (listTask?.size?.minus(1))
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置任务状态
|
||||
*/
|
||||
fun setTaskStatus(status: Int) {
|
||||
this.mSubTaskStatus = status
|
||||
}
|
||||
|
||||
/**
|
||||
* 填充数据
|
||||
*/
|
||||
fun setCurrentData(mCurrentPosition: Int) {
|
||||
listTask?.let {
|
||||
mSubTaskType =
|
||||
if (it[mCurrentPosition].taskType == SubTaskTypeEnum.AUTOPILOT_SUBTYPE.code) SubTaskTypeEnum.AUTOPILOT_SUBTYPE else SubTaskTypeEnum.MANUAL_DRIVING_SUBTYPE
|
||||
if (it.size == 1) {
|
||||
preSubTask.setData(it[mCurrentPosition], isSelect = true, isLastTask = true)
|
||||
currentSubTask.visibility = View.INVISIBLE
|
||||
lastSubTask.visibility = View.INVISIBLE
|
||||
} else if (it.size == 2) {
|
||||
if (mCurrentPosition == 0) {
|
||||
preSubTask.setData(it[mCurrentPosition], isSelect = true)
|
||||
currentSubTask.setData(it[1], isLastTask = true)
|
||||
} else {
|
||||
preSubTask.setData(it[mCurrentPosition - 1])
|
||||
currentSubTask.setData(it[mCurrentPosition], isSelect = true, isLastTask = true)
|
||||
}
|
||||
preSubTask.visibility=View.VISIBLE
|
||||
currentSubTask.visibility=View.VISIBLE
|
||||
lastSubTask.visibility=View.GONE
|
||||
} else {
|
||||
preSubTask.visibility=View.VISIBLE
|
||||
currentSubTask.visibility=View.VISIBLE
|
||||
lastSubTask.visibility=View.VISIBLE
|
||||
//当前正在执行的任务是第一个子任务
|
||||
if (mCurrentPosition == 0) {
|
||||
preSubTask.setData(it[mCurrentPosition], isSelect = true)
|
||||
currentSubTask.setData(it[1])
|
||||
lastSubTask.setData(it[2], isLastTask = true)
|
||||
//当前正在执行的任务是最后一个子任务
|
||||
} else if (mCurrentPosition == it.size - 1) {
|
||||
preSubTask.setData(it[mCurrentPosition - 2])
|
||||
currentSubTask.setData(it[mCurrentPosition - 1])
|
||||
lastSubTask.setData(it[mCurrentPosition], isSelect = true, isLastTask = true)
|
||||
} else {
|
||||
preSubTask.setData(it[mCurrentPosition - 1])
|
||||
currentSubTask.setData(it[mCurrentPosition], isSelect = true)
|
||||
lastSubTask.setData(it[mCurrentPosition + 1], isLastTask = true)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,151 +0,0 @@
|
||||
package com.mogo.och.sweeper.view;
|
||||
|
||||
import android.content.Context;
|
||||
import android.util.AttributeSet;
|
||||
import android.view.LayoutInflater;
|
||||
import android.widget.ImageView;
|
||||
import android.widget.TextView;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
import androidx.constraintlayout.widget.ConstraintLayout;
|
||||
|
||||
import com.mogo.eagle.core.function.api.autopilot.IMoGoChassisGearStateListener;
|
||||
import com.mogo.eagle.core.function.api.autopilot.IMoGoChassisLamplightListener;
|
||||
import com.mogo.eagle.core.function.api.autopilot.IMoGoChassisSteeringStateListener;
|
||||
import com.mogo.eagle.core.function.call.autopilot.CallerChassisGearStateListenerManager;
|
||||
import com.mogo.eagle.core.function.call.autopilot.CallerChassisLamplightListenerManager;
|
||||
import com.mogo.eagle.core.function.call.autopilot.CallerChassisSteeringStateListenerManager;
|
||||
import com.mogo.eagle.core.function.hmi.ui.widget.TapPositionView;
|
||||
import com.mogo.eagle.core.utilcode.mogo.logger.CallerLogger;
|
||||
import com.mogo.eagle.core.utilcode.util.ThreadUtils;
|
||||
import com.mogo.och.sweeper.R;
|
||||
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import chassis.Chassis;
|
||||
import chassis.VehicleStateOuterClass;
|
||||
|
||||
public class SweeperTrafficDataView extends ConstraintLayout
|
||||
implements IMoGoChassisLamplightListener,
|
||||
IMoGoChassisSteeringStateListener,
|
||||
IMoGoChassisGearStateListener {
|
||||
private static final String TAG = "SweeperTrafficDataView";
|
||||
private TapPositionView tapPositionView;//方向盘
|
||||
private ImageView speedImage;//速度图标
|
||||
private TextView speedTextView;//速度值
|
||||
private TurnSignalView sweeperTurnSignal;//转向灯
|
||||
private SweeperLimitingVelocityView sweeperLimitingVelocity;//限速
|
||||
|
||||
public SweeperTrafficDataView(@NonNull Context context) {
|
||||
this(context,null);
|
||||
}
|
||||
|
||||
public SweeperTrafficDataView(@NonNull Context context, @Nullable AttributeSet attrs) {
|
||||
this(context, attrs,0);
|
||||
}
|
||||
|
||||
public SweeperTrafficDataView(@NonNull Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
|
||||
this(context, attrs, defStyleAttr,0);
|
||||
}
|
||||
|
||||
public SweeperTrafficDataView(@NonNull Context context, @Nullable AttributeSet attrs, int defStyleAttr, int defStyleRes) {
|
||||
super(context, attrs, defStyleAttr, defStyleRes);
|
||||
initView(context);
|
||||
}
|
||||
private void initView(@NonNull Context context) {
|
||||
LayoutInflater.from(context).inflate(R.layout.sweeper_traffic_data, this,true);
|
||||
tapPositionView = findViewById(R.id.sweeperTrafficPosition);
|
||||
speedImage = findViewById(R.id.sweeperSpeedImage);
|
||||
speedTextView = findViewById(R.id.sweeperSpeedText);
|
||||
sweeperTurnSignal = findViewById(R.id.sweeperTurnSignal);
|
||||
sweeperLimitingVelocity = findViewById(R.id.sweeperLimitingVelocity);
|
||||
}
|
||||
@Override
|
||||
protected void onAttachedToWindow() {
|
||||
super.onAttachedToWindow();
|
||||
//添加 底盘灯光数据 监听
|
||||
CallerChassisLamplightListenerManager.INSTANCE.addListener(TAG, this);
|
||||
CallerChassisSteeringStateListenerManager.INSTANCE.addListener(TAG, this);
|
||||
CallerChassisGearStateListenerManager.INSTANCE.addListener(TAG, this);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onDetachedFromWindow() {
|
||||
super.onDetachedFromWindow();
|
||||
// 移除 底盘灯光数据 监听
|
||||
CallerChassisLamplightListenerManager.INSTANCE.removeListener(TAG);
|
||||
CallerChassisSteeringStateListenerManager.INSTANCE.removeListener(TAG);
|
||||
CallerChassisGearStateListenerManager.INSTANCE.removeListener(TAG);
|
||||
}
|
||||
|
||||
/**
|
||||
* 车辆转向灯
|
||||
* @param lightSwitch
|
||||
*/
|
||||
@Override
|
||||
public void onAutopilotLightSwitchData(@org.jetbrains.annotations.Nullable Chassis.LightSwitch lightSwitch) {
|
||||
ThreadUtils.runOnUiThread(() -> {
|
||||
//转向灯状态 0是正常 1是左转 2是右转
|
||||
if (lightSwitch != null) {
|
||||
CallerLogger.INSTANCE.d(TAG, "车辆转向灯:" + lightSwitch.toString());
|
||||
if (lightSwitch.getNumber()==1){
|
||||
sweeperTurnSignal.showLeftSignal();
|
||||
}else if(lightSwitch.getNumber()==2){
|
||||
sweeperTurnSignal.showRightSignal();
|
||||
}else{
|
||||
sweeperTurnSignal.showDirection();
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* 刹车灯
|
||||
* @param brakeLight
|
||||
*/
|
||||
@Override
|
||||
public void onAutopilotBrakeLightData(boolean brakeLight) {
|
||||
CallerLogger.INSTANCE.d(TAG, "刹车灯:" + brakeLight);
|
||||
}
|
||||
|
||||
/**
|
||||
* 方向盘转向角 左+右-
|
||||
* @param steering
|
||||
*/
|
||||
@Override
|
||||
public void onAutopilotSteeringData(float steering) {
|
||||
CallerLogger.INSTANCE.d(TAG, "steering原始值====" + steering);
|
||||
if (Math.abs(steering) < 1) {
|
||||
steering = 0;
|
||||
}
|
||||
CallerLogger.INSTANCE.d(TAG, "steering忽略小数点后====" + (int) steering);
|
||||
}
|
||||
|
||||
/**
|
||||
* 档位
|
||||
* @param gear
|
||||
*/
|
||||
@Override
|
||||
public void onAutopilotGearData(@NotNull Chassis.GearPosition gear) {
|
||||
CallerLogger.INSTANCE.d(TAG, "司机屏档位" + gear.toString());
|
||||
ThreadUtils.runOnUiThread(() -> {
|
||||
if (tapPositionView != null) {
|
||||
tapPositionView.updateWithGear(gear);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* 速度设置
|
||||
*/
|
||||
public void updateSpeedWithValue(int newSpeed) {
|
||||
if (speedTextView != null) {
|
||||
speedTextView.setText(String.valueOf(newSpeed));
|
||||
}
|
||||
if (speedImage != null) {
|
||||
speedImage.setBackgroundResource(newSpeed > 60 ? R.drawable.sweeper_traffic_data_speed_warning :R.drawable.sweeper_bg_traffic_data_speed);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,169 @@
|
||||
package com.mogo.och.sweeper.view
|
||||
|
||||
import android.annotation.SuppressLint
|
||||
import android.content.Context
|
||||
import android.util.AttributeSet
|
||||
import android.view.LayoutInflater
|
||||
import android.widget.ImageView
|
||||
import android.widget.TextView
|
||||
import androidx.constraintlayout.widget.ConstraintLayout
|
||||
import chassis.Chassis.GearPosition
|
||||
import chassis.Chassis.LightSwitch
|
||||
import chassis.ChassisStatesOuterClass.BMSSystemStates
|
||||
import chassis.ChassisStatesOuterClass.SweeperFuTianTaskSystemStates
|
||||
import com.elegant.utils.UiThreadHandler
|
||||
import com.mogo.eagle.core.function.api.autopilot.IMoGoBatteryManagementSystemListener
|
||||
import com.mogo.eagle.core.function.api.autopilot.IMoGoChassisGearStateListener
|
||||
import com.mogo.eagle.core.function.api.autopilot.IMoGoChassisLamplightListener
|
||||
import com.mogo.eagle.core.function.api.autopilot.IMoGoSweeperFutianCleanSystemListener
|
||||
import com.mogo.eagle.core.function.call.autopilot.*
|
||||
import com.mogo.eagle.core.function.hmi.ui.widget.TapPositionView
|
||||
import com.mogo.eagle.core.utilcode.mogo.logger.CallerLogger.d
|
||||
import com.mogo.eagle.core.utilcode.mogo.logger.scene.SceneConstant
|
||||
import com.mogo.eagle.core.utilcode.util.ThreadUtils
|
||||
import com.mogo.och.sweeper.R
|
||||
import planning.RoboSweeperTaskIndexOuterClass
|
||||
import kotlin.math.roundToInt
|
||||
|
||||
/**
|
||||
* 车辆基本信息:方向盘下方的档位 转向灯 限速 速度 电量 水量
|
||||
*/
|
||||
class SweeperTrafficDataView : ConstraintLayout,
|
||||
IMoGoBatteryManagementSystemListener,
|
||||
IMoGoChassisLamplightListener,
|
||||
IMoGoChassisGearStateListener,
|
||||
IMoGoSweeperFutianCleanSystemListener
|
||||
{
|
||||
private var tapPositionView //方向盘下方的档位
|
||||
: TapPositionView? = null
|
||||
private var speedImage //速度图标
|
||||
: ImageView? = null
|
||||
private var speedTextView //速度值
|
||||
: TextView? = null
|
||||
private var sweeperTurnSignal //转向灯
|
||||
: TurnSignalView? = null
|
||||
private var tvBattery //电量百分比展示
|
||||
: TextView? = null
|
||||
private var ivBgWaterWarning //水位预警背景图
|
||||
: ImageView? = null
|
||||
private var ivWater //水位图标
|
||||
: ImageView? = null
|
||||
|
||||
private val TAG = "SweeperTrafficDataView"
|
||||
|
||||
// 底盘数据回调时间间隔
|
||||
private val VEHICLE_STATE_INTERVAL_MILLIS = 500L
|
||||
|
||||
// 当前时间戳
|
||||
private var mCurrentTimeWaterMillis: Long = 0
|
||||
|
||||
private var mCurrentTimeBatteryMillis: Long = 0
|
||||
|
||||
constructor(context: Context) : super(context) {}
|
||||
constructor(context: Context, attrs: AttributeSet?) : super(context, attrs) {
|
||||
initView(context)
|
||||
}
|
||||
|
||||
constructor(context: Context, attrs: AttributeSet?, defStyleAttr: Int) : super(context, attrs, defStyleAttr) {}
|
||||
constructor(context: Context, attrs: AttributeSet?, defStyleAttr: Int, defStyleRes: Int) : super(context, attrs, defStyleAttr, defStyleRes) {}
|
||||
|
||||
private fun initView(context: Context) {
|
||||
LayoutInflater.from(context).inflate(R.layout.sweeper_traffic_data, this)
|
||||
tapPositionView = findViewById(R.id.sweeperTrafficPosition)
|
||||
speedImage = findViewById(R.id.sweeperSpeedImage)
|
||||
speedTextView = findViewById(R.id.sweeperSpeedText)
|
||||
sweeperTurnSignal = findViewById(R.id.sweeperTurnSignal)
|
||||
tvBattery = findViewById(R.id.tvBattery)
|
||||
ivBgWaterWarning = findViewById(R.id.sweeperIvBgWaterWarning)
|
||||
ivWater = findViewById(R.id.sweeperIvWater)
|
||||
}
|
||||
|
||||
override fun onAttachedToWindow() {
|
||||
super.onAttachedToWindow()
|
||||
//电量
|
||||
CallerBatteryManagementSystemListenerManager.addListener(TAG, this)
|
||||
//转向灯
|
||||
CallerChassisLamplightListenerManager.addListener(TAG, this)
|
||||
//档位
|
||||
CallerChassisGearStateListenerManager.addListener(TAG, this)
|
||||
//清扫车相关数据接口
|
||||
CallerSweeperFutianCleanSystemListenerManager.addListener(TAG, this)
|
||||
}
|
||||
|
||||
override fun onDetachedFromWindow() {
|
||||
super.onDetachedFromWindow()
|
||||
CallerBatteryManagementSystemListenerManager.removeListener(TAG )
|
||||
CallerChassisLamplightListenerManager.removeListener(TAG)
|
||||
CallerChassisGearStateListenerManager.removeListener(TAG)
|
||||
CallerSweeperFutianCleanSystemListenerManager.removeListener(TAG)
|
||||
}
|
||||
|
||||
override fun onSweeperFutianTaskIndexData(roboSweeperTaskIndex: RoboSweeperTaskIndexOuterClass.RoboSweeperTaskIndex) {}
|
||||
override fun onSweeperFutianCleanSystemState(cleanSystemState: SweeperFuTianTaskSystemStates) {
|
||||
val current = System.currentTimeMillis()
|
||||
if (current - mCurrentTimeWaterMillis <=VEHICLE_STATE_INTERVAL_MILLIS) {
|
||||
return
|
||||
}
|
||||
mCurrentTimeWaterMillis = current
|
||||
d(SceneConstant.M_SWEEPER + TAG, "水位:${cleanSystemState.hasSecuCleanWaterTankLow()}")
|
||||
UiThreadHandler.post {
|
||||
if (cleanSystemState.hasSecuCleanWaterTankLow()) { //清水箱水位低不能清洗作业报警信号
|
||||
ivBgWaterWarning?.visibility = VISIBLE
|
||||
ivWater?.isSelected = true
|
||||
} else {
|
||||
ivBgWaterWarning?.visibility = GONE
|
||||
ivWater?.isSelected = false
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@SuppressLint("SetTextI18n")
|
||||
override fun onBatteryManagementSystemStates(states: BMSSystemStates) {
|
||||
val current = System.currentTimeMillis()
|
||||
if (current - mCurrentTimeBatteryMillis <=VEHICLE_STATE_INTERVAL_MILLIS) {
|
||||
return
|
||||
}
|
||||
mCurrentTimeBatteryMillis = current
|
||||
d(SceneConstant.M_SWEEPER + TAG, "电量:${states.bmsSoc}")
|
||||
UiThreadHandler.post{
|
||||
tvBattery?.text = "${states.bmsSoc.roundToInt()}%"
|
||||
}
|
||||
}
|
||||
/**
|
||||
* 车辆转向灯
|
||||
* @param directionLight
|
||||
*/
|
||||
override fun onAutopilotLightSwitchData(lightSwitch: LightSwitch?) {
|
||||
//转向灯状态 0是正常 1是左转 2是右转
|
||||
if (lightSwitch != null) {
|
||||
sweeperTurnSignal?.setTurnLight(lightSwitch)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 刹车灯
|
||||
* @param brakeLight
|
||||
*/
|
||||
override fun onAutopilotBrakeLightData(brakeLight: Boolean) {
|
||||
d(TAG, "刹车灯:$brakeLight")
|
||||
}
|
||||
/**
|
||||
* 方向盘下方的档位
|
||||
* @param gear
|
||||
*/
|
||||
override fun onAutopilotGearData(gear: GearPosition) {
|
||||
d(TAG, "司机屏档位$gear")
|
||||
ThreadUtils.runOnUiThread {
|
||||
tapPositionView?.updateWithGear(gear)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 速度设置
|
||||
*/
|
||||
fun updateSpeedWithValue(newSpeed: Int) {
|
||||
speedTextView?.text = newSpeed.toString()
|
||||
speedImage?.setBackgroundResource(if (newSpeed > 60) R.drawable.sweeper_traffic_data_speed_warning else R.drawable.sweeper_bg_traffic_data_speed)
|
||||
}
|
||||
}
|
||||
@@ -64,7 +64,9 @@ class SweeperTrafficLightView @JvmOverloads constructor(
|
||||
override fun disableTrafficLight() {
|
||||
UiThreadHandler.post {
|
||||
mCurrentLightId = TrafficLightEnum.BLACK
|
||||
this@SweeperTrafficLightView.visibility = GONE
|
||||
sweeper_traffic_light_iv.setImageResource(R.drawable.sweeper_light_gay_nor)
|
||||
sweeper_traffic_light_time_tv.text = ""
|
||||
this@SweeperTrafficLightView.visibility = VISIBLE
|
||||
}
|
||||
}
|
||||
|
||||
@@ -121,18 +123,21 @@ class SweeperTrafficLightView @JvmOverloads constructor(
|
||||
UiThreadHandler.post {
|
||||
when (lightId) {
|
||||
TrafficLightEnum.RED -> {
|
||||
sweeper_traffic_light_iv.setBackgroundResource(R.drawable.sweeper_light_red_nor)
|
||||
sweeper_traffic_light_iv.setImageResource(R.drawable.sweeper_light_red_nor)
|
||||
this@SweeperTrafficLightView.visibility = VISIBLE
|
||||
}
|
||||
TrafficLightEnum.YELLOW -> {
|
||||
sweeper_traffic_light_iv.setBackgroundResource(R.drawable.sweeper_lightyellow_nor)
|
||||
sweeper_traffic_light_iv.setImageResource(R.drawable.sweeper_lightyellow_nor)
|
||||
this@SweeperTrafficLightView.visibility = VISIBLE
|
||||
}
|
||||
TrafficLightEnum.GREEN -> {
|
||||
sweeper_traffic_light_iv.setBackgroundResource(R.drawable.sweeper_light_green_nor)
|
||||
sweeper_traffic_light_iv.setImageResource(R.drawable.sweeper_light_green_nor)
|
||||
this@SweeperTrafficLightView.visibility = VISIBLE
|
||||
}
|
||||
else -> {
|
||||
sweeper_traffic_light_iv.setImageResource(R.drawable.sweeper_light_gay_nor)
|
||||
this@SweeperTrafficLightView.visibility = VISIBLE
|
||||
}
|
||||
else -> this@SweeperTrafficLightView.visibility = GONE
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,180 @@
|
||||
package com.mogo.och.sweeper.view
|
||||
|
||||
import android.content.Context
|
||||
import android.util.AttributeSet
|
||||
import android.view.LayoutInflater
|
||||
import android.view.View
|
||||
import androidx.constraintlayout.widget.ConstraintLayout
|
||||
import chassis.ChassisStatesOuterClass.SweeperFuTianTaskSystemStates
|
||||
import com.elegant.utils.UiThreadHandler
|
||||
import com.mogo.eagle.core.utilcode.mogo.logger.CallerLogger.d
|
||||
import com.mogo.eagle.core.utilcode.mogo.logger.scene.SceneConstant
|
||||
import com.mogo.och.sweeper.R
|
||||
import com.mogo.och.sweeper.callback.ICleaningModeStateCallback
|
||||
import com.mogo.och.sweeper.constant.OperateStateEnum
|
||||
import com.mogo.och.sweeper.constant.SubTaskTypeEnum
|
||||
import com.mogo.och.sweeper.ui.popwindow.SweeperOperatePanelPopWindow
|
||||
import com.mogo.och.sweeper.util.SweeperFutianCmdUtil
|
||||
import kotlinx.android.synthetic.main.sweeper_work_mode.view.*
|
||||
|
||||
/**
|
||||
* 清扫车模式信息展示
|
||||
*/
|
||||
class SweeperWorkModeView : ConstraintLayout, ICleaningModeStateCallback {
|
||||
|
||||
private var isSelectPureSweepMode: Boolean = false
|
||||
private val TAG = "SweeperWorkModeView"
|
||||
//清扫模式选择面板
|
||||
private var mOperatePanelPopWindow: SweeperOperatePanelPopWindow? = null
|
||||
|
||||
private var operateState: OperateStateEnum=OperateStateEnum.SYNCING_STATUS
|
||||
|
||||
constructor(context: Context) : super(context) {}
|
||||
constructor(context: Context, attrs: AttributeSet?) : super(context, attrs) {
|
||||
initView(context)
|
||||
}
|
||||
|
||||
constructor(context: Context, attrs: AttributeSet?, defStyleAttr: Int) : super(context, attrs, defStyleAttr) {}
|
||||
constructor(context: Context, attrs: AttributeSet?, defStyleAttr: Int, defStyleRes: Int) : super(context, attrs, defStyleAttr, defStyleRes) {}
|
||||
|
||||
private fun initView(context: Context) {
|
||||
LayoutInflater.from(context).inflate(R.layout.sweeper_work_mode, this)
|
||||
mOperatePanelPopWindow = SweeperOperatePanelPopWindow(context)
|
||||
setShowOrHideCleanSystemState(OperateStateEnum.SYNCING_STATUS,null)
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置view
|
||||
*/
|
||||
fun setTrafficDataView(trafficDataView: SweeperTrafficDataView){
|
||||
//清扫模式选择面板打开关闭处理
|
||||
ivOpenOperatePanel.setOnClickListener {
|
||||
if (mOperatePanelPopWindow?.isShowing != true) {
|
||||
mOperatePanelPopWindow?.showAsDropDown(
|
||||
trafficDataView,
|
||||
resources.getDimension(R.dimen.dp_600).toInt(),
|
||||
0
|
||||
)
|
||||
UiThreadHandler.postDelayed({
|
||||
d(SceneConstant.M_SWEEPER + TAG, "operateState:"+operateState.code)
|
||||
mOperatePanelPopWindow?.showSyncing(operateState)
|
||||
|
||||
},300)
|
||||
} else {
|
||||
mOperatePanelPopWindow?.dismiss()
|
||||
}
|
||||
}
|
||||
}
|
||||
/**
|
||||
* 设置清扫模式面板
|
||||
*/
|
||||
fun setSweeperFutianCleanSystemState(taskType: SubTaskTypeEnum, cleanSystemState: SweeperFuTianTaskSystemStates?) {
|
||||
// TODO:传递清扫车底盘数据给上装面板
|
||||
//mOperatePanelPopWindow?.setCleanSystemState(cleanSystemState, this@SweeperWorkModeView)
|
||||
if (this.operateState.code==OperateStateEnum.STARTING_STATUS.code){
|
||||
return
|
||||
}
|
||||
//如果状态是同步中,在底盘首次回调时把状态强制修改成成功
|
||||
if (this.operateState.code==OperateStateEnum.SYNCING_STATUS.code){
|
||||
this.operateState=OperateStateEnum.SUCCESS_STATUS
|
||||
d(SceneConstant.M_SWEEPER + TAG, "SystemState operateState:"+operateState.code)
|
||||
}
|
||||
//清扫车暂未选择清扫模式或者任务类型是人工驾驶子任务,则暂无清扫模式
|
||||
if (SweeperFutianCmdUtil.checkIfCleanMode(cleanSystemState) || taskType.code == SubTaskTypeEnum.MANUAL_DRIVING_SUBTYPE.code) {
|
||||
setShowOrHideCleanSystemState(OperateStateEnum.NO_STATUS, cleanSystemState)
|
||||
} else {
|
||||
setShowOrHideCleanSystemState(OperateStateEnum.SUCCESS_STATUS, cleanSystemState)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置清扫模式状态显示和隐藏
|
||||
*/
|
||||
private fun setShowOrHideCleanSystemState(operateState: OperateStateEnum, cleanSystemState: SweeperFuTianTaskSystemStates?) {
|
||||
when (operateState.code) {
|
||||
OperateStateEnum.SYNCING_STATUS.code -> {
|
||||
groupWorkModelPanel?.visibility = View.GONE
|
||||
tvNoDataDesc?.visibility = View.VISIBLE
|
||||
tvNoDataDesc?.text = "状态同步中,请稍后"
|
||||
mOperatePanelPopWindow?.setIsOutsideTouchable(true)
|
||||
}
|
||||
OperateStateEnum.FAIL_STATUS.code -> {
|
||||
groupWorkModelPanel?.visibility = View.GONE
|
||||
tvNoDataDesc?.visibility = View.VISIBLE
|
||||
tvNoDataDesc?.text = "上装启动失败"
|
||||
mOperatePanelPopWindow?.setIsOutsideTouchable(true)
|
||||
}
|
||||
OperateStateEnum.STARTING_STATUS.code -> {
|
||||
groupWorkModelPanel?.visibility = View.GONE
|
||||
tvNoDataDesc?.visibility = View.VISIBLE
|
||||
tvNoDataDesc?.text = "上装启动中..."
|
||||
mOperatePanelPopWindow?.setIsOutsideTouchable(false)
|
||||
}
|
||||
OperateStateEnum.NO_STATUS.code -> {
|
||||
groupWorkModelPanel?.visibility = View.GONE
|
||||
tvNoDataDesc?.visibility = View.VISIBLE
|
||||
tvNoDataDesc?.text = "暂无"
|
||||
mOperatePanelPopWindow?.setIsOutsideTouchable(true)
|
||||
}
|
||||
else -> {
|
||||
groupWorkModelPanel?.visibility = View.VISIBLE
|
||||
tvNoDataDesc?.visibility = View.GONE
|
||||
setCleanModeData(cleanSystemState)
|
||||
mOperatePanelPopWindow?.setIsOutsideTouchable(true)
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
override fun cleaningModeState(operateState: OperateStateEnum, cleanSystemState: SweeperFuTianTaskSystemStates?, isSelectPureSweepMode: Boolean) {
|
||||
this.isSelectPureSweepMode = isSelectPureSweepMode
|
||||
this.operateState=operateState
|
||||
setShowOrHideCleanSystemState(operateState, cleanSystemState)
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置清扫模式数据
|
||||
*/
|
||||
private fun setCleanModeData(cleanSystemState: SweeperFuTianTaskSystemStates?) {
|
||||
if (isSelectPureSweepMode) {
|
||||
tvCleaningMode?.text = "纯扫模式"
|
||||
groupWorkModelPanel?.visibility = View.VISIBLE
|
||||
tvNoDataDesc?.visibility = View.GONE
|
||||
} else {
|
||||
if (SweeperFutianCmdUtil.checkIfCleanMode(cleanSystemState)) {
|
||||
groupWorkModelPanel?.visibility = View.GONE
|
||||
tvNoDataDesc?.visibility = View.VISIBLE
|
||||
tvNoDataDesc?.text = "暂无"
|
||||
return
|
||||
} else {
|
||||
groupWorkModelPanel?.visibility = View.VISIBLE
|
||||
tvNoDataDesc?.visibility = View.GONE
|
||||
// 作业模式
|
||||
if (cleanSystemState?.secuModWashSweepSts == true) tvCleaningMode?.text = "洗扫模式"
|
||||
if (cleanSystemState?.secuModWashSts == true) tvCleaningMode?.text = "纯洗模式"
|
||||
if (cleanSystemState?.secuWorkTonSts == true) tvCleaningMode?.text = "纯吸模式"
|
||||
if (SweeperFutianCmdUtil.checkIfCleanModePureSweep(cleanSystemState)) tvCleaningMode?.text = "纯扫模式"
|
||||
}
|
||||
}
|
||||
//清扫方向
|
||||
if (SweeperFutianCmdUtil.checkIfCleanDirection(cleanSystemState)) {
|
||||
tvCleaningDirection.visibility = View.GONE
|
||||
} else {
|
||||
tvCleaningDirection.visibility = View.VISIBLE
|
||||
// 左侧
|
||||
if (cleanSystemState?.secuWorkLeftSts == true) tvCleaningDirection?.text = "左侧"
|
||||
// 右侧
|
||||
if (cleanSystemState?.secuWorkRightSts == true) tvCleaningDirection?.text = "右侧"
|
||||
// 两侧
|
||||
if (cleanSystemState?.secuWorkOnBothsidesSts == true) tvCleaningDirection?.text = "两侧"
|
||||
}
|
||||
if (SweeperFutianCmdUtil.checkIfCleanIntensity(cleanSystemState)) {
|
||||
tvCleaningIntensity.visibility = View.GONE
|
||||
} else {
|
||||
tvCleaningIntensity.visibility = View.VISIBLE
|
||||
// 作业强度
|
||||
if (cleanSystemState?.secuWorkStandSts == true) tvCleaningIntensity?.text = "标准"
|
||||
if (cleanSystemState?.secuWorkStrongSts == true) tvCleaningIntensity?.text = "强力"
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,62 +0,0 @@
|
||||
package com.mogo.och.sweeper.view;
|
||||
|
||||
import android.content.Context;
|
||||
import android.util.AttributeSet;
|
||||
import android.view.LayoutInflater;
|
||||
import android.widget.ImageView;
|
||||
import android.widget.LinearLayout;
|
||||
|
||||
import com.mogo.och.sweeper.R;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
|
||||
public class TurnSignalView extends LinearLayout {
|
||||
private ImageView turnLeftView;
|
||||
private ImageView turnRightView;
|
||||
public TurnSignalView(Context context) {
|
||||
super(context);
|
||||
}
|
||||
|
||||
public TurnSignalView(Context context, @Nullable AttributeSet attrs) {
|
||||
super(context, attrs);
|
||||
initView(context);
|
||||
}
|
||||
|
||||
public TurnSignalView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
|
||||
super(context, attrs, defStyleAttr);
|
||||
}
|
||||
|
||||
public TurnSignalView(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
|
||||
super(context, attrs, defStyleAttr, defStyleRes);
|
||||
}
|
||||
private void initView(@NonNull Context context) {
|
||||
LayoutInflater.from(context).inflate(R.layout.sweeper_turn_signal, this);
|
||||
turnLeftView = findViewById(R.id.turnLeftView);
|
||||
turnRightView = findViewById(R.id.turnRightView);
|
||||
}
|
||||
|
||||
/**
|
||||
* 展示左转向灯
|
||||
*/
|
||||
public void showLeftSignal(){
|
||||
turnLeftView.setSelected(true);
|
||||
turnRightView.setSelected(false);
|
||||
}
|
||||
|
||||
/**
|
||||
* 展示右转向灯
|
||||
*/
|
||||
public void showRightSignal(){
|
||||
turnLeftView.setSelected(false);
|
||||
turnRightView.setSelected(true);
|
||||
}
|
||||
|
||||
/**
|
||||
* 默认情况及其直行时
|
||||
*/
|
||||
public void showDirection(){
|
||||
turnLeftView.setSelected(false);
|
||||
turnRightView.setSelected(false);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,90 @@
|
||||
package com.mogo.och.sweeper.view
|
||||
|
||||
import android.animation.AnimatorSet
|
||||
import android.animation.ObjectAnimator
|
||||
import android.content.Context
|
||||
import android.util.AttributeSet
|
||||
import android.view.LayoutInflater
|
||||
import android.view.View
|
||||
import android.widget.ImageView
|
||||
import android.widget.LinearLayout
|
||||
import chassis.Chassis
|
||||
import com.mogo.och.sweeper.R
|
||||
import kotlinx.android.synthetic.main.sweeper_turn_signal.view.*
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.GlobalScope
|
||||
import kotlinx.coroutines.launch
|
||||
|
||||
class TurnSignalView : LinearLayout {
|
||||
constructor(context: Context?) : super(context) {}
|
||||
constructor(context: Context, attrs: AttributeSet?) : super(context, attrs) {
|
||||
initView(context)
|
||||
}
|
||||
|
||||
private var init: Boolean = false
|
||||
|
||||
constructor(context: Context?, attrs: AttributeSet?, defStyleAttr: Int) : super(
|
||||
context,
|
||||
attrs,
|
||||
defStyleAttr
|
||||
) {
|
||||
}
|
||||
|
||||
constructor(
|
||||
context: Context?,
|
||||
attrs: AttributeSet?,
|
||||
defStyleAttr: Int,
|
||||
defStyleRes: Int
|
||||
) : super(context, attrs, defStyleAttr, defStyleRes) {
|
||||
}
|
||||
|
||||
private fun initView(context: Context) {
|
||||
LayoutInflater.from(context).inflate(R.layout.sweeper_turn_signal, this)
|
||||
init = true
|
||||
}
|
||||
|
||||
/**
|
||||
* 转向灯动画
|
||||
*/
|
||||
fun setTurnLight(directionLight: Chassis.LightSwitch?) {
|
||||
GlobalScope.launch(Dispatchers.Main) {
|
||||
if (!init) {
|
||||
return@launch
|
||||
}
|
||||
//根据左右进行显示和隐藏,实际要判断每个来的时间和频度
|
||||
when (directionLight) {
|
||||
Chassis.LightSwitch.LIGHT_LEFT -> { //左转向
|
||||
leftSelectImage.visibility = View.VISIBLE
|
||||
rightSelectImage.visibility = View.GONE
|
||||
rightSelectImage.clearAnimation()
|
||||
setAnimation(leftSelectImage)
|
||||
}
|
||||
Chassis.LightSwitch.LIGHT_RIGHT -> { //右转向
|
||||
leftSelectImage.visibility = View.GONE
|
||||
rightSelectImage.visibility = View.VISIBLE
|
||||
leftSelectImage.clearAnimation()
|
||||
setAnimation(rightSelectImage)
|
||||
}
|
||||
else -> { //消失
|
||||
leftSelectImage.clearAnimation()
|
||||
rightSelectImage.clearAnimation()
|
||||
leftSelectImage.visibility = View.GONE
|
||||
rightSelectImage.visibility = View.GONE
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//实现图片闪烁效果
|
||||
private fun setAnimation(imageView: ImageView) {
|
||||
val animationSet = AnimatorSet()
|
||||
val valueAnimator = ObjectAnimator.ofFloat(imageView, "alpha", 0f, 1.0f)
|
||||
val valueAnimatorDisappare = ObjectAnimator.ofFloat(imageView, "alpha", 1.0f, 0f)
|
||||
valueAnimator.duration = 1000
|
||||
valueAnimatorDisappare.duration = 800
|
||||
valueAnimator.repeatCount = -1
|
||||
valueAnimatorDisappare.repeatCount = -1
|
||||
animationSet.playTogether(valueAnimatorDisappare, valueAnimator)
|
||||
animationSet.start()
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,342 @@
|
||||
package com.mogo.och.sweeper.view
|
||||
|
||||
import android.content.Context
|
||||
import android.graphics.Color
|
||||
import android.os.Bundle
|
||||
import android.util.AttributeSet
|
||||
import android.view.LayoutInflater
|
||||
import android.view.View
|
||||
import android.widget.ImageView
|
||||
import androidx.constraintlayout.widget.ConstraintLayout
|
||||
import androidx.core.content.ContextCompat
|
||||
import com.amap.api.maps.AMap
|
||||
import com.amap.api.maps.CameraUpdateFactory
|
||||
import com.amap.api.maps.model.*
|
||||
import com.mogo.eagle.core.data.map.MogoLocation
|
||||
import com.mogo.eagle.core.function.api.autopilot.IMoGoChassisLocationGCJ02Listener
|
||||
import com.mogo.eagle.core.function.call.autopilot.CallerChassisLocationGCJ02ListenerManager
|
||||
import com.mogo.eagle.core.utilcode.mogo.logger.CallerLogger
|
||||
import com.mogo.eagle.core.utilcode.mogo.logger.scene.SceneConstant
|
||||
import com.mogo.eagle.core.utilcode.util.CoordinateUtils
|
||||
import com.mogo.eagle.core.utilcode.util.ThreadUtils
|
||||
import com.mogo.och.sweeper.R
|
||||
import com.mogo.och.sweeper.bean.SweeperRoutePlanningUpdateReqBean
|
||||
import com.mogo.och.sweeper.constant.SweeperConst
|
||||
import com.mogo.och.sweeper.database.bean.WeltDataBean
|
||||
import com.mogo.och.sweeper.util.SweeperMapAssetStyleUtil
|
||||
import kotlinx.android.synthetic.main.sweeper_welt_map_overview.view.*
|
||||
|
||||
/**
|
||||
* 作业任务全览图
|
||||
*/
|
||||
class WeltMapOverView : ConstraintLayout, IMoGoChassisLocationGCJ02Listener {
|
||||
private var mTaskCoordinatesLatLng: MutableList<LatLng> = mutableListOf() //当前大任务的所有起终点集合
|
||||
private var mCarMarker: Marker? = null
|
||||
private var mAMap: AMap? = null
|
||||
private var mWeltPolylines: Polyline? = null
|
||||
private var mRoutePolylines: Polyline?=null
|
||||
// private val mLineMarkers: MutableList<Marker?> = mutableListOf()
|
||||
private var mEndStationMarker: Marker? = null
|
||||
private var mFirst: Boolean = false
|
||||
|
||||
//清扫车任务地图
|
||||
private val TAG = "WeltMapOverView"
|
||||
|
||||
constructor(context: Context) : super(context) {}
|
||||
constructor(context: Context, attrs: AttributeSet?) : super(context, attrs) {
|
||||
initView(context)
|
||||
}
|
||||
|
||||
constructor(context: Context, attrs: AttributeSet?, defStyleAttr: Int) : super(context, attrs, defStyleAttr) {}
|
||||
|
||||
constructor(context: Context, attrs: AttributeSet?, defStyleAttr: Int, defStyleRes: Int) : super(context, attrs, defStyleAttr, defStyleRes) {}
|
||||
|
||||
private fun initView(context: Context) {
|
||||
LayoutInflater.from(context).inflate(R.layout.sweeper_welt_map_overview, this)
|
||||
initAMapView()
|
||||
// 注册定位监听
|
||||
CallerChassisLocationGCJ02ListenerManager.addListener(TAG, this)
|
||||
CallerChassisLocationGCJ02ListenerManager.setListenerHz(TAG,5)
|
||||
}
|
||||
|
||||
private fun initAMapView() {
|
||||
mAMap = sweeperTextureMapView.map
|
||||
// 地图文字标注
|
||||
mAMap?.showMapText(true)
|
||||
//显示3D建筑物
|
||||
mAMap?.showBuildings(true)
|
||||
// 设置导航地图模式,aMap是地图控制器对象。
|
||||
mAMap?.mapType = AMap.MAP_TYPE_NIGHT
|
||||
// 关闭显示实时路况图层,aMap是地图控制器对象。
|
||||
mAMap?.isTrafficEnabled = false
|
||||
// 设置 锚点 图标
|
||||
mCarMarker = mAMap?.addMarker(
|
||||
MarkerOptions()
|
||||
.icon(BitmapDescriptorFactory.fromResource(R.drawable.sweeper_car_big))
|
||||
.anchor(0.5f, 0.5f)
|
||||
)
|
||||
// 设置地图的样式
|
||||
val uiSettings = mAMap?.uiSettings
|
||||
uiSettings?.isZoomControlsEnabled = false // 地图缩放级别的交换按钮
|
||||
uiSettings?.setAllGesturesEnabled(false) // 所有手势
|
||||
uiSettings?.isMyLocationButtonEnabled = false // 显示默认的定位按钮
|
||||
uiSettings?.setLogoBottomMargin(-150) //设置Logo下边界距离屏幕底部的边距,设置为负值即可
|
||||
// 加载自定义样式
|
||||
val customMapStyleOptions = CustomMapStyleOptions()
|
||||
.setEnable(true)
|
||||
.setStyleData(SweeperMapAssetStyleUtil.getAssetsStyle(context, "map_style.data"))
|
||||
.setStyleExtraData(SweeperMapAssetStyleUtil.getAssetsExtraStyle(context, "map_style_extra.data"))
|
||||
// 设置自定义样式
|
||||
mAMap?.setCustomMapStyle(customMapStyleOptions)
|
||||
//mAMap?.moveCamera(CameraUpdateFactory.zoomTo(15f))
|
||||
mAMap?.setOnMapLoadedListener(AMap.OnMapLoadedListener {
|
||||
//mAMap?.moveCamera(CameraUpdateFactory.zoomTo(15f))
|
||||
CallerLogger.d(SceneConstant.M_SWEEPER + TAG, "WeltView---onMapLoaded")
|
||||
// 加载自定义样式
|
||||
val customMapStyleOptions = CustomMapStyleOptions()
|
||||
.setEnable(true)
|
||||
.setStyleData(SweeperMapAssetStyleUtil.getAssetsStyle(context, "map_style.data"))
|
||||
.setStyleExtraData(SweeperMapAssetStyleUtil.getAssetsExtraStyle(context, "map_style_extra.data"))
|
||||
// 设置自定义样式
|
||||
mAMap?.setCustomMapStyle(customMapStyleOptions)
|
||||
// 实时路况图层关闭,必须添加在loaded结束之后,其他位置不生效
|
||||
mAMap?.isTrafficEnabled = false
|
||||
mAMap?.showBuildings(true)
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* 添加画线颜色值
|
||||
*/
|
||||
private fun getRouteColorList(weltData: MutableList<WeltDataBean>):MutableList<Int> {
|
||||
val colorList= mutableListOf<Int>()
|
||||
var nextWeltDataBean:WeltDataBean?=null
|
||||
for (i in weltData.indices) {
|
||||
val weltDataBean = weltData[i]
|
||||
if(i+1<weltData.size){
|
||||
nextWeltDataBean = weltData[i+1]
|
||||
val calculateLineDistance = CoordinateUtils.calculateLineDistance(
|
||||
nextWeltDataBean.locLon, nextWeltDataBean.locLat,
|
||||
weltDataBean.locLon, weltDataBean.locLat
|
||||
)
|
||||
// 大于10m
|
||||
if(calculateLineDistance>10){
|
||||
colorList.add(Color.TRANSPARENT)
|
||||
continue
|
||||
}
|
||||
}
|
||||
if (weltDataBean.weltDistance == SweeperConst.NONWELT) {//非贴边
|
||||
colorList.add(ContextCompat.getColor(context,R.color.sweeper_236299))
|
||||
} else if (weltDataBean.weltDistance < 0) {
|
||||
colorList.add(ContextCompat.getColor(context,R.color.sweeper_c22101))
|
||||
} else if (weltDataBean.weltDistance >= 0 && weltDataBean.weltDistance < 0.1) {
|
||||
colorList.add(ContextCompat.getColor(context,R.color.sweeper_4dffa4))
|
||||
} else if (weltDataBean.weltDistance >= 0.1 && weltDataBean.weltDistance < 0.2) {
|
||||
colorList.add(ContextCompat.getColor(context,R.color.sweeper_ffdd4d))
|
||||
} else if (weltDataBean.weltDistance >= 0.2) {
|
||||
colorList.add(ContextCompat.getColor(context,R.color.sweeper_ff912b))
|
||||
}
|
||||
}
|
||||
return colorList
|
||||
}
|
||||
|
||||
override fun onChassisLocationGCJ02(mogoLocation: MogoLocation?) {
|
||||
ThreadUtils.getSinglePool().run {
|
||||
mogoLocation?.let { gnssInfo ->
|
||||
val currentLatLng = LatLng(gnssInfo.latitude, gnssInfo.longitude)
|
||||
//更新车辆位置
|
||||
mCarMarker?.rotateAngle = (360 - gnssInfo.heading).toFloat()
|
||||
mCarMarker?.position = currentLatLng
|
||||
mCarMarker?.setToTop()
|
||||
//圈定地图显示范围
|
||||
val boundsBuilder = LatLngBounds.Builder()
|
||||
if (mTaskCoordinatesLatLng.size > 0) {
|
||||
//存放经纬度
|
||||
for (i in mTaskCoordinatesLatLng.indices) {
|
||||
val latLng = mTaskCoordinatesLatLng[i]
|
||||
boundsBuilder.include(latLng)
|
||||
}
|
||||
}
|
||||
mRoutePolylines?.points?.forEach {latLng->
|
||||
boundsBuilder.include(latLng)
|
||||
}
|
||||
boundsBuilder.include(currentLatLng)
|
||||
mAMap?.moveCamera(CameraUpdateFactory.newLatLngBoundsRect(boundsBuilder.build(), 100, 100, 100, 100))
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据贴边数据绘制任务路线
|
||||
*/
|
||||
fun drawablePolyline(weltDatas: MutableList<WeltDataBean>?) {
|
||||
weltDatas?.let {
|
||||
val colorList=getRouteColorList(it)
|
||||
val coordinatesLatLngs= mutableListOf<LatLng>()
|
||||
for (i in it.indices) {
|
||||
coordinatesLatLngs.add(LatLng(it[i].locLat,it[i].locLon))
|
||||
}
|
||||
if (coordinatesLatLngs.size > 2) {
|
||||
//设置线段纹理
|
||||
mWeltPolylines?.remove()
|
||||
val polylineOptions = PolylineOptions()
|
||||
polylineOptions.addAll(coordinatesLatLngs)
|
||||
polylineOptions.width(14f) //线段宽度
|
||||
polylineOptions.isUseTexture = false
|
||||
polylineOptions.lineCapType(PolylineOptions.LineCapType.LineCapSquare)
|
||||
polylineOptions.colorValues(colorList)
|
||||
polylineOptions.visible(true)
|
||||
// 绘制线
|
||||
mWeltPolylines = mAMap?.addPolyline(polylineOptions)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 绘制起点和终点的marker
|
||||
*/
|
||||
private fun drawStartAndEndMarker(startPoint: LatLng, endPoint: LatLng) {
|
||||
// val startMarker = mAMap?.addMarker(MarkerOptions().icon(BitmapDescriptorFactory.fromResource(R.drawable.sweeper_big_start_maker_icon)))
|
||||
// startMarker?.position = startPoint
|
||||
// mLineMarkers.add(startMarker)
|
||||
// val endMarker = mAMap?.addMarker(MarkerOptions().icon(BitmapDescriptorFactory.fromResource(R.drawable.sweeper_big_end_maker_icon)))
|
||||
// endMarker?.position = endPoint
|
||||
// mLineMarkers.add(endMarker)
|
||||
}
|
||||
|
||||
private fun drawEndMarker(endPoint: LatLng){
|
||||
mEndStationMarker?.remove()
|
||||
mEndStationMarker = mAMap?.addMarker(MarkerOptions().icon(BitmapDescriptorFactory.fromResource(R.drawable.sweeper_big_end_maker_icon)))
|
||||
mEndStationMarker?.position = endPoint
|
||||
}
|
||||
|
||||
/**
|
||||
* 清除所有标记和路线
|
||||
*/
|
||||
fun clearAllMarkerAndPolyline() {
|
||||
// for (i in mLineMarkers.indices) {
|
||||
// mLineMarkers[i]?.isVisible = false
|
||||
// mLineMarkers[i]?.remove()
|
||||
// }
|
||||
mEndStationMarker?.remove()
|
||||
mWeltPolylines?.remove()
|
||||
mRoutePolylines?.remove()
|
||||
// mLineMarkers.clear()
|
||||
//mFirst = false
|
||||
//showOrHiddenLegendData(false)
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置贴边数据
|
||||
*/
|
||||
fun setWeltData(weltDatas: MutableList<WeltDataBean>?, isWeltData: Boolean, distance: String?) {
|
||||
drawablePolyline(weltDatas)
|
||||
ThreadUtils.runOnUiThread {
|
||||
distance?.let {
|
||||
setDistance(it)
|
||||
}
|
||||
}
|
||||
//if (!mFirst && isWeltData) {
|
||||
// mFirst = true
|
||||
// showOrHiddenLegendData(true)
|
||||
//}
|
||||
}
|
||||
|
||||
/**
|
||||
* 任务轨迹数据
|
||||
*/
|
||||
fun setRouteList(routeList: ArrayList<SweeperRoutePlanningUpdateReqBean.Result>) {
|
||||
val routeCoordinatesLatLngs= mutableListOf<LatLng>()
|
||||
for (i in routeList.indices) {
|
||||
routeCoordinatesLatLngs.add(LatLng(routeList[i].latitude,routeList[i].longitude))
|
||||
}
|
||||
ThreadUtils.runOnUiThread {
|
||||
drawRouteListPolyline(routeCoordinatesLatLngs)
|
||||
}
|
||||
}
|
||||
|
||||
private fun drawRouteListPolyline(routeList: MutableList<LatLng>) {
|
||||
mRoutePolylines?.remove()
|
||||
val polylineOptions = PolylineOptions()
|
||||
polylineOptions.width(14f) //线段宽度
|
||||
polylineOptions.isUseTexture = false
|
||||
polylineOptions.lineCapType(PolylineOptions.LineCapType.LineCapSquare)
|
||||
polylineOptions.color(ContextCompat.getColor(context,R.color.sweeper_3ba1cc))
|
||||
polylineOptions.addAll(routeList)
|
||||
polylineOptions.visible(true)
|
||||
mRoutePolylines=mAMap?.addPolyline(polylineOptions)
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置当前大任务的所有子任务起终点集合
|
||||
*/
|
||||
fun setTaskListCoordinatesLatLng(coordinatesLatLng: MutableList<LatLng>) {
|
||||
ThreadUtils.runOnUiThread {
|
||||
this.mTaskCoordinatesLatLng = coordinatesLatLng
|
||||
if (mTaskCoordinatesLatLng.size > 0) {
|
||||
drawStartAndEndMarker(mTaskCoordinatesLatLng[0], mTaskCoordinatesLatLng[mTaskCoordinatesLatLng.size - 1])
|
||||
}
|
||||
}
|
||||
}
|
||||
/**
|
||||
* 设置当前大任务的所有子任务起终点集合
|
||||
*/
|
||||
fun setCurrentTaskCoordinatesLatLng(coordinatesLatLng: LatLng) {
|
||||
ThreadUtils.runOnUiThread {
|
||||
drawEndMarker(coordinatesLatLng)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置图例数据
|
||||
*/
|
||||
private fun showOrHiddenLegendData(isShow: Boolean) {
|
||||
groupLegend.visibility = if (isShow) View.VISIBLE else View.GONE
|
||||
sweeperLegend1.setData(R.drawable.sweeper_legend1, "a<0")
|
||||
sweeperLegend2.setData(R.drawable.sweeper_legend2, "0≤a<10")
|
||||
sweeperLegend3.setData(R.drawable.sweeper_legend3, "10≤a<20")
|
||||
sweeperLegend4.setData(R.drawable.sweeper_legend4, "a≥20")
|
||||
sweeperLegend5.setData(R.drawable.sweeper_legend5, "非贴边")
|
||||
sweeperLegend6.setData(R.drawable.sweeper_legend6, "未经过")
|
||||
}
|
||||
|
||||
private fun setDistance(distance: String) {
|
||||
taskWeltDistanceTv.text = "贴边:${distance}cm"
|
||||
}
|
||||
|
||||
fun setProgress(progress: String?) {
|
||||
progress?.let {
|
||||
if ("0" == progress) {
|
||||
taskProgressTv.visibility = View.GONE
|
||||
taskWeltDistanceTv.visibility = View.GONE
|
||||
showOrHiddenLegendData(false)
|
||||
} else {
|
||||
taskProgressTv.visibility = View.VISIBLE
|
||||
taskWeltDistanceTv.visibility = View.VISIBLE
|
||||
taskProgressTv.text = it
|
||||
showOrHiddenLegendData(true)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun onCreateView(savedInstanceState: Bundle?) {
|
||||
sweeperTextureMapView.onCreate(savedInstanceState)
|
||||
}
|
||||
|
||||
fun onResume() {
|
||||
sweeperTextureMapView.onResume()
|
||||
}
|
||||
|
||||
fun onPause() {
|
||||
sweeperTextureMapView.onPause()
|
||||
}
|
||||
|
||||
fun onDestroy() {
|
||||
sweeperTextureMapView.onDestroy()
|
||||
}
|
||||
|
||||
fun getSweeperSwitchToSmall(): ImageView {
|
||||
return sweeperSwitchToSmall
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,344 @@
|
||||
package com.mogo.och.sweeper.view
|
||||
|
||||
import android.content.Context
|
||||
import android.graphics.Color
|
||||
import android.os.Bundle
|
||||
import android.util.AttributeSet
|
||||
import android.view.LayoutInflater
|
||||
import android.view.View
|
||||
import android.widget.ImageView
|
||||
import androidx.constraintlayout.widget.ConstraintLayout
|
||||
import androidx.core.content.ContextCompat
|
||||
import com.amap.api.maps.AMap
|
||||
import com.amap.api.maps.CameraUpdateFactory
|
||||
import com.amap.api.maps.model.*
|
||||
import com.mogo.eagle.core.data.map.MogoLocation
|
||||
import com.mogo.eagle.core.function.api.autopilot.IMoGoChassisLocationGCJ02Listener
|
||||
import com.mogo.eagle.core.function.call.autopilot.CallerChassisLocationGCJ02ListenerManager
|
||||
import com.mogo.eagle.core.utilcode.mogo.logger.CallerLogger.d
|
||||
import com.mogo.eagle.core.utilcode.mogo.logger.scene.SceneConstant
|
||||
import com.mogo.eagle.core.utilcode.util.CoordinateUtils
|
||||
import com.mogo.eagle.core.utilcode.util.ThreadUtils
|
||||
import com.mogo.och.sweeper.R
|
||||
import com.mogo.och.sweeper.bean.SweeperRoutePlanningUpdateReqBean
|
||||
import com.mogo.och.sweeper.constant.SweeperConst
|
||||
import com.mogo.och.sweeper.database.bean.WeltDataBean
|
||||
import com.mogo.och.sweeper.util.SweeperMapAssetStyleUtil
|
||||
import kotlinx.android.synthetic.main.sweeper_welt_small_map_view.view.*
|
||||
|
||||
|
||||
/**
|
||||
* 作业任务小地图
|
||||
*/
|
||||
class WeltSmallMapView : ConstraintLayout, IMoGoChassisLocationGCJ02Listener {
|
||||
private var mTaskCoordinatesLatLng: MutableList<LatLng> = mutableListOf() //当前大任务的所有起终点集合
|
||||
private var mCarMarker: Marker? = null
|
||||
private var mAMap: AMap? = null
|
||||
private var mWeltPolylines: Polyline? = null
|
||||
private var mRoutePolylines: Polyline?=null
|
||||
// private val mLineMarkers: MutableList<Marker?> = mutableListOf()
|
||||
private var endStationMarker:Marker? = null
|
||||
|
||||
//清扫车任务地图
|
||||
private val TAG = "WeltMapView"
|
||||
|
||||
constructor(context: Context) : super(context) {}
|
||||
constructor(context: Context, attrs: AttributeSet?) : super(context, attrs) {
|
||||
initView(context)
|
||||
}
|
||||
|
||||
constructor(context: Context, attrs: AttributeSet?, defStyleAttr: Int) : super(context, attrs, defStyleAttr) {}
|
||||
constructor(context: Context, attrs: AttributeSet?, defStyleAttr: Int, defStyleRes: Int) : super(context, attrs, defStyleAttr, defStyleRes) {}
|
||||
|
||||
private fun initView(context: Context) {
|
||||
LayoutInflater.from(context).inflate(R.layout.sweeper_welt_small_map_view, this)
|
||||
initAMapView()
|
||||
// 注册定位监听
|
||||
CallerChassisLocationGCJ02ListenerManager.addListener(TAG, this)
|
||||
CallerChassisLocationGCJ02ListenerManager.setListenerHz(TAG,5)
|
||||
}
|
||||
|
||||
override fun onChassisLocationGCJ02(mogoLocation: MogoLocation?) {
|
||||
d(SceneConstant.M_SWEEPER + TAG, "mogoLocation:$mogoLocation")
|
||||
ThreadUtils.getSinglePool().run {
|
||||
mogoLocation?.let {
|
||||
val currentLatLng = LatLng(it.latitude, it.longitude)
|
||||
drawCarMarker(mogoLocation)
|
||||
//圈定地图显示范围
|
||||
val boundsBuilder = LatLngBounds.Builder()
|
||||
if (mTaskCoordinatesLatLng.size > 0) {
|
||||
//存放经纬度
|
||||
for (i in mTaskCoordinatesLatLng.indices) {
|
||||
boundsBuilder.include(mTaskCoordinatesLatLng[i])
|
||||
}
|
||||
}
|
||||
mRoutePolylines?.points?.forEach {latLng->
|
||||
boundsBuilder.include(latLng)
|
||||
}
|
||||
boundsBuilder.include(currentLatLng)
|
||||
mAMap!!.moveCamera(CameraUpdateFactory.newLatLngBoundsRect(boundsBuilder.build(), 100, 100, 100, 100))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 绘制自车
|
||||
*
|
||||
* @param location
|
||||
*/
|
||||
private fun drawCarMarker(location: MogoLocation?) {
|
||||
if (location == null) return
|
||||
val currentLatLng = LatLng(location.latitude, location.longitude)
|
||||
//更新车辆位置
|
||||
if (mCarMarker != null) {
|
||||
mCarMarker!!.rotateAngle = (360 - location.heading).toFloat()
|
||||
mCarMarker!!.position = currentLatLng
|
||||
mCarMarker!!.setToTop()
|
||||
}
|
||||
}
|
||||
|
||||
private fun initAMapView() {
|
||||
mAMap = sweeperSmallTextureMapView?.map
|
||||
// 地图文字标注
|
||||
mAMap?.showMapText(true)
|
||||
// 设置导航地图模式,aMap是地图控制器对象。
|
||||
mAMap?.mapType = AMap.MAP_TYPE_NIGHT
|
||||
// 关闭显示实时路况图层,aMap是地图控制器对象。
|
||||
mAMap?.isTrafficEnabled = false
|
||||
// 设置 锚点 图标
|
||||
mCarMarker = mAMap?.addMarker(
|
||||
MarkerOptions()
|
||||
.icon(BitmapDescriptorFactory.fromResource(R.drawable.sweeper_car_small))
|
||||
.anchor(0.5f, 0.5f)
|
||||
)
|
||||
// 设置地图的样式
|
||||
val uiSettings = mAMap?.uiSettings
|
||||
uiSettings?.isZoomControlsEnabled = false // 地图缩放级别的交换按钮
|
||||
uiSettings?.setAllGesturesEnabled(false) // 所有手势
|
||||
uiSettings?.isMyLocationButtonEnabled = false // 显示默认的定位按钮
|
||||
uiSettings?.setLogoBottomMargin(-150) //设置Logo下边界距离屏幕底部的边距,设置为负值即可
|
||||
// 加载自定义样式
|
||||
val customMapStyleOptions = CustomMapStyleOptions()
|
||||
.setEnable(true)
|
||||
.setStyleData(SweeperMapAssetStyleUtil.getAssetsStyle(context, "map_style.data"))
|
||||
.setStyleExtraData(SweeperMapAssetStyleUtil.getAssetsExtraStyle(context, "map_style_extra.data"))
|
||||
// 设置自定义样式
|
||||
mAMap?.setCustomMapStyle(customMapStyleOptions)
|
||||
mAMap?.setOnMapLoadedListener(AMap.OnMapLoadedListener {
|
||||
d(SceneConstant.M_SWEEPER + TAG, "WeltView---onMapLoaded")
|
||||
// 加载自定义样式
|
||||
val customMapStyleOptions = CustomMapStyleOptions()
|
||||
.setEnable(true)
|
||||
.setStyleData(SweeperMapAssetStyleUtil.getAssetsStyle(context, "map_style.data"))
|
||||
.setStyleExtraData(SweeperMapAssetStyleUtil.getAssetsExtraStyle(context, "map_style_extra.data"))
|
||||
// 设置自定义样式
|
||||
mAMap?.setCustomMapStyle(customMapStyleOptions)
|
||||
mAMap?.setPointToCenter(sweeperSmallTextureMapView.width / 2, sweeperSmallTextureMapView.height / 2)
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据贴边数据绘制任务路线
|
||||
*/
|
||||
private fun drawablePolyline(weltDatas: MutableList<WeltDataBean>?) {
|
||||
weltDatas?.let {
|
||||
val colorList = getRouteColorList(it)
|
||||
val coordinatesLatLngs = mutableListOf<LatLng>()
|
||||
for (i in it.indices) {
|
||||
coordinatesLatLngs.add(LatLng(it[i].locLat,it[i].locLon))
|
||||
}
|
||||
if (coordinatesLatLngs.size > 2) {
|
||||
//设置线段纹理
|
||||
mWeltPolylines?.remove()
|
||||
val polylineOptions = PolylineOptions()
|
||||
polylineOptions.addAll(coordinatesLatLngs)
|
||||
polylineOptions.width(14f) //线段宽度
|
||||
polylineOptions.isUseTexture = false
|
||||
polylineOptions.lineCapType(PolylineOptions.LineCapType.LineCapSquare)
|
||||
polylineOptions.colorValues(colorList)
|
||||
polylineOptions.visible(true)
|
||||
// 绘制线
|
||||
mWeltPolylines = mAMap?.addPolyline(polylineOptions)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 添加画线颜色值
|
||||
*/
|
||||
private fun getRouteColorList(weltData: MutableList<WeltDataBean>): MutableList<Int> {
|
||||
val colorList = mutableListOf<Int>()
|
||||
var nextWeltDataBean:WeltDataBean?=null
|
||||
for (i in weltData.indices) {
|
||||
val weltDataBean = weltData[i]
|
||||
if(i+1<weltData.size){
|
||||
nextWeltDataBean = weltData[i+1]
|
||||
val calculateLineDistance = CoordinateUtils.calculateLineDistance(
|
||||
nextWeltDataBean.locLon, nextWeltDataBean.locLat,
|
||||
weltDataBean.locLon, weltDataBean.locLat
|
||||
)
|
||||
// 大于10m
|
||||
if(calculateLineDistance>10){
|
||||
colorList.add(Color.TRANSPARENT)
|
||||
continue
|
||||
}
|
||||
}
|
||||
|
||||
if (weltDataBean.weltDistance == SweeperConst.NONWELT) {//非贴边
|
||||
colorList.add(ContextCompat.getColor(context,R.color.sweeper_236299))
|
||||
} else if (weltDataBean.weltDistance < 0) {
|
||||
colorList.add(ContextCompat.getColor(context,R.color.sweeper_c22101))
|
||||
} else if (weltDataBean.weltDistance >= 0 && weltDataBean.weltDistance < 0.1) {
|
||||
colorList.add(ContextCompat.getColor(context,R.color.sweeper_4dffa4))
|
||||
} else if (weltDataBean.weltDistance >= 0.1 && weltDataBean.weltDistance < 0.2) {
|
||||
colorList.add(ContextCompat.getColor(context,R.color.sweeper_ffdd4d))
|
||||
} else if (weltDataBean.weltDistance >= 0.2) {
|
||||
colorList.add(ContextCompat.getColor(context,R.color.sweeper_ff912b))
|
||||
}
|
||||
}
|
||||
return colorList
|
||||
}
|
||||
|
||||
/**
|
||||
* 添加起点和终点的marker
|
||||
*/
|
||||
private fun addStartAndEndMarker(startPoint: LatLng, endPoint: LatLng) {
|
||||
// for (i in mLineMarkers.indices) {
|
||||
// mLineMarkers[i]?.isVisible = false
|
||||
// mLineMarkers[i]?.remove()
|
||||
// }
|
||||
// mLineMarkers.clear()
|
||||
// val startMarker = mAMap?.addMarker(MarkerOptions().icon(BitmapDescriptorFactory.fromResource(R.drawable.sweeper_small_start_marker_icon)))
|
||||
// startMarker?.position = startPoint
|
||||
// mLineMarkers.add(startMarker)
|
||||
// val endMarker = mAMap?.addMarker(MarkerOptions().icon(BitmapDescriptorFactory.fromResource(R.drawable.sweeper_small_end_marker_icon)))
|
||||
// endMarker?.position = endPoint
|
||||
// mLineMarkers.add(endMarker)
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置当前大任务的所有子任务起终点集合
|
||||
*/
|
||||
fun setTaskListCoordinatesLatLng(coordinatesLatLng: MutableList<LatLng>) {
|
||||
this.mTaskCoordinatesLatLng = coordinatesLatLng
|
||||
// if (mTaskCoordinatesLatLng.size > 0) {
|
||||
// d(
|
||||
// SceneConstant.M_SWEEPER + TAG,
|
||||
// "startPoint:${mTaskCoordinatesLatLng[0]} endPoint:${mTaskCoordinatesLatLng[mTaskCoordinatesLatLng.size - 1]}"
|
||||
// )
|
||||
// addStartAndEndMarker(mTaskCoordinatesLatLng[0], mTaskCoordinatesLatLng[mTaskCoordinatesLatLng.size - 1])
|
||||
// }
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置当前大任务的所有子任务起终点集合
|
||||
*/
|
||||
fun setCurrentTaskCoordinatesLatLng(coordinatesLatLng: LatLng) {
|
||||
endStationMarker?.remove()
|
||||
endStationMarker = mAMap?.addMarker(MarkerOptions().icon(BitmapDescriptorFactory.fromResource(R.drawable.sweeper_small_end_marker_icon)))
|
||||
endStationMarker?.position = coordinatesLatLng
|
||||
}
|
||||
|
||||
/**
|
||||
* 清除所有标记和路线
|
||||
*/
|
||||
fun clearAllMarkerAndPolyline() {
|
||||
// for (i in mLineMarkers.indices) {
|
||||
// mLineMarkers[i]?.isVisible = false
|
||||
// mLineMarkers[i]?.remove()
|
||||
// }
|
||||
endStationMarker?.remove()
|
||||
mWeltPolylines?.remove()
|
||||
// mLineMarkers.clear()
|
||||
mRoutePolylines?.remove()
|
||||
//mFirst = false
|
||||
//showOrHiddenWelt(false)
|
||||
}
|
||||
|
||||
fun getSwitchToBig(): ImageView = sweeperSwitchToBig
|
||||
|
||||
/**
|
||||
* 显示或隐藏贴边
|
||||
*/
|
||||
private fun showOrHiddenWelt(isShow: Boolean) {
|
||||
taskProgressTv.visibility = if (isShow) View.VISIBLE else View.GONE
|
||||
taskWeltDistanceTv.visibility = if (isShow) View.VISIBLE else View.GONE
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置贴边数据
|
||||
*/
|
||||
fun setWeltData(weltDatas: MutableList<WeltDataBean>, isWeltData: Boolean, distance: String) {
|
||||
drawablePolyline(weltDatas)
|
||||
ThreadUtils.runOnUiThread {
|
||||
setWeltDistance(distance)
|
||||
}
|
||||
//if (!mFirst&&isWeltData) {
|
||||
// showOrHiddenWelt(true)
|
||||
// mFirst = true
|
||||
//}
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置贴边距离
|
||||
*/
|
||||
private fun setWeltDistance(distance: String) {
|
||||
taskWeltDistanceTv.text = "贴边:${distance}cm"
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置任务轨迹数据
|
||||
*/
|
||||
fun setRouteList(routeList: ArrayList<SweeperRoutePlanningUpdateReqBean.Result>) {
|
||||
val routeCoordinatesLatLngs = mutableListOf<LatLng>()
|
||||
for (i in routeList.indices) {
|
||||
routeCoordinatesLatLngs.add(LatLng(routeList[i].latitude, routeList[i].longitude))
|
||||
}
|
||||
ThreadUtils.runOnUiThread {
|
||||
drawRouteListPolyline(routeCoordinatesLatLngs)
|
||||
}
|
||||
}
|
||||
|
||||
private fun drawRouteListPolyline(routeList: MutableList<LatLng>) {
|
||||
mRoutePolylines?.remove()
|
||||
val polylineOptions = PolylineOptions()
|
||||
polylineOptions.addAll(routeList)
|
||||
polylineOptions.width(14f) //线段宽度
|
||||
polylineOptions.isUseTexture = false
|
||||
polylineOptions.lineCapType(PolylineOptions.LineCapType.LineCapSquare)
|
||||
polylineOptions.color(ContextCompat.getColor(context,R.color.sweeper_3ba1cc))
|
||||
polylineOptions.visible(true)
|
||||
mRoutePolylines=mAMap?.addPolyline(polylineOptions)
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置任务进度
|
||||
*/
|
||||
fun setTaskProgress(progress: String?) {
|
||||
if (progress == "0") {
|
||||
taskWeltDistanceTv.visibility = View.GONE
|
||||
taskProgressTv.visibility = View.GONE
|
||||
} else {
|
||||
taskWeltDistanceTv.visibility = View.VISIBLE
|
||||
taskProgressTv.visibility = View.VISIBLE
|
||||
taskProgressTv.text = progress
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
fun onCreateView(savedInstanceState: Bundle?) {
|
||||
sweeperSmallTextureMapView?.onCreate(savedInstanceState)
|
||||
}
|
||||
|
||||
fun onResume() {
|
||||
sweeperSmallTextureMapView?.onResume()
|
||||
}
|
||||
|
||||
fun onPause() {
|
||||
sweeperSmallTextureMapView?.onPause()
|
||||
}
|
||||
|
||||
fun onDestroy() {
|
||||
sweeperSmallTextureMapView?.onDestroy()
|
||||
}
|
||||
}
|
||||
@@ -1,4 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<selector xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<item android:color="@color/sweeper_autopilot_text_color_normal"/>
|
||||
</selector>
|
||||
|
After Width: | Height: | Size: 67 KiB |
|
After Width: | Height: | Size: 622 KiB |
|
Before Width: | Height: | Size: 5.0 KiB |
|
Before Width: | Height: | Size: 5.2 KiB |
|
Before Width: | Height: | Size: 6.7 KiB |
|
After Width: | Height: | Size: 544 B |
|
After Width: | Height: | Size: 29 KiB |
|
After Width: | Height: | Size: 29 KiB |
|
After Width: | Height: | Size: 351 B |
|
Before Width: | Height: | Size: 100 KiB |
|
After Width: | Height: | Size: 20 KiB |
|
After Width: | Height: | Size: 807 B |
|
After Width: | Height: | Size: 1000 B |