taxi 自动驾驶画线
This commit is contained in:
@@ -38,6 +38,7 @@ dependencies {
|
||||
implementation fileTree(dir: "libs", include: ["*.jar"])
|
||||
implementation rootProject.ext.dependencies.androidxappcompat
|
||||
implementation rootProject.ext.dependencies.arouter
|
||||
implementation project(path: ':libraries:map-amap')
|
||||
annotationProcessor rootProject.ext.dependencies.aroutercompiler
|
||||
implementation rootProject.ext.dependencies.rxandroid
|
||||
implementation rootProject.ext.dependencies.androidxconstraintlayout
|
||||
|
||||
@@ -12,11 +12,13 @@ import com.mogo.cloud.passport.MoGoAiCloudClientConfig;
|
||||
import com.mogo.commons.data.BaseData;
|
||||
import com.mogo.commons.network.SubscribeImpl;
|
||||
import com.mogo.map.MogoLatLng;
|
||||
import com.mogo.map.location.MogoLocation;
|
||||
import com.mogo.map.navi.IMogoCarLocationChangedListener2;
|
||||
import com.mogo.module.common.MogoApisHandler;
|
||||
import com.mogo.module.common.constants.HostConst;
|
||||
import com.mogo.och.taxi.ui.OCHTaxiUiController;
|
||||
import com.mogo.service.adas.IMogoAdasOCHCallback;
|
||||
import com.mogo.service.adas.IMogoAdasRouteCallBack;
|
||||
import com.mogo.service.adas.RemoteControlAutoPilotParameters;
|
||||
import com.mogo.service.adas.entity.AdasOCHData;
|
||||
import com.mogo.service.connection.IMogoOnMessageListener;
|
||||
@@ -78,7 +80,6 @@ class MogoOCHTaxiModel {
|
||||
private OCHTaxiOrderResponse mCurrentOCHOrder;
|
||||
private OCHArriveNotifyCallback mNotifyCallback;
|
||||
private IMogoCarLocationChangedListener2 mCarLocationChangedListener2;
|
||||
|
||||
/**
|
||||
* 是否达到起始站点
|
||||
*/
|
||||
|
||||
@@ -0,0 +1,72 @@
|
||||
package com.mogo.och.taxi;
|
||||
|
||||
import android.content.Context;
|
||||
|
||||
import com.mogo.map.MogoLatLng;
|
||||
import com.mogo.map.location.MogoLocation;
|
||||
import com.mogo.map.overlay.IMogoOverlayManager;
|
||||
import com.mogo.map.overlay.IMogoPolyline;
|
||||
import com.mogo.map.overlay.MogoPolylineOptions;
|
||||
import com.mogo.module.common.MogoApisHandler;
|
||||
import com.mogo.module.common.utils.LocationUtils;
|
||||
import com.mogo.utils.ColorUtils;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
public class OCHTaxiOverlayManager {
|
||||
|
||||
|
||||
private IMogoPolyline mMoGoPolyline;
|
||||
// 连接线参数
|
||||
private MogoPolylineOptions mPolylineOptions;
|
||||
// 线路径集合
|
||||
private List<MogoLatLng> mPolylinePointList;
|
||||
// 渐变色
|
||||
private List<Integer> mPolylineColors;
|
||||
private Context mContext;
|
||||
IMogoOverlayManager mogoOverlayManager;
|
||||
public OCHTaxiOverlayManager(Context context) {
|
||||
mPolylineOptions = new MogoPolylineOptions();
|
||||
// 绘制路径集合
|
||||
mPolylinePointList = new ArrayList<>();
|
||||
// 引导线颜色
|
||||
mPolylineColors = new ArrayList<>();
|
||||
mContext = context;
|
||||
mogoOverlayManager = MogoApisHandler.getInstance().getApis().getMapServiceApi().getOverlayManager(mContext);
|
||||
}
|
||||
|
||||
/**
|
||||
* 绘制最优路线
|
||||
*
|
||||
* @param polylinePoint 要绘制的经纬度度集合
|
||||
*/
|
||||
public IMogoPolyline draw(MogoLocation carLocal, List<MogoLatLng> polylinePoint) {
|
||||
if (mMoGoPolyline != null) {
|
||||
mMoGoPolyline.remove();
|
||||
mPolylinePointList.clear();
|
||||
mPolylineColors.clear();
|
||||
}
|
||||
if (polylinePoint != null) {
|
||||
|
||||
// 将当前车辆位置放进去
|
||||
mPolylinePointList.add(new MogoLatLng(carLocal.getLatitude(), carLocal.getLongitude()));
|
||||
// 过滤后台推送的推荐路线集合
|
||||
for (MogoLatLng polyline : polylinePoint) {
|
||||
//需要剔除已经行驶过的经纬度,这里需要比对推荐路线集合中的点是否在当前车辆行驶方向前面如果不在则抛弃
|
||||
if (LocationUtils.isPointOnCarFront(carLocal, polyline)) {
|
||||
mPolylinePointList.add(polyline);
|
||||
}
|
||||
}
|
||||
mPolylineColors.addAll(ColorUtils.getGradientAlpha("#002965ED", "#FF2965ED", "#002965ED", mPolylinePointList.size()));
|
||||
// 替换路径集合
|
||||
mPolylineOptions.points(mPolylinePointList);
|
||||
// 线条粗细,渐变,渐变色值
|
||||
mPolylineOptions.width(25).useGradient(true).colorValues(mPolylineColors);
|
||||
// 绘制线
|
||||
mMoGoPolyline = mogoOverlayManager.addPolyline(mPolylineOptions);
|
||||
}
|
||||
return mMoGoPolyline;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -10,7 +10,9 @@ import androidx.annotation.NonNull;
|
||||
import com.mogo.cloud.commons.utils.CoordinateUtils;
|
||||
import com.mogo.commons.voice.AIAssist;
|
||||
import com.mogo.map.MogoLatLng;
|
||||
import com.mogo.map.location.MogoLocation;
|
||||
import com.mogo.map.navi.IMogoCarLocationChangedListener2;
|
||||
import com.mogo.map.overlay.MogoPolylineOptions;
|
||||
import com.mogo.module.common.MogoApisHandler;
|
||||
import com.mogo.och.BaseOchFragment;
|
||||
import com.mogo.och.taxi.IMogoADASAutoPilotStatusChangedListener;
|
||||
@@ -19,14 +21,17 @@ import com.mogo.och.taxi.IOperationChangedListener;
|
||||
import com.mogo.och.taxi.MogoOCHTaxiModel;
|
||||
import com.mogo.och.taxi.OCHOrderStatus;
|
||||
import com.mogo.och.taxi.OCHOrderStatusCallback;
|
||||
import com.mogo.och.taxi.OCHTaxiOverlayManager;
|
||||
import com.mogo.och.taxi.R;
|
||||
import com.mogo.och.view.SlidePanelView;
|
||||
import com.mogo.service.adas.IMogoAdasOCHCallback;
|
||||
import com.mogo.service.adas.entity.AdasOCHData;
|
||||
import com.mogo.service.adas.IMogoAdasRouteCallBack;
|
||||
import com.mogo.service.statusmanager.IMogoStatusChangedListener;
|
||||
import com.mogo.service.statusmanager.StatusDescriptor;
|
||||
import com.mogo.utils.logger.Logger;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public
|
||||
/**
|
||||
* @author congtaowang
|
||||
@@ -39,6 +44,7 @@ class OCHTaxiFragment extends BaseOchFragment< OCHTaxiView, OCHTaxiPresenter > i
|
||||
IMogoOCHTaxiArriveCallback,
|
||||
IMogoADASAutoPilotStatusChangedListener,
|
||||
IOperationChangedListener,
|
||||
IMogoAdasRouteCallBack,
|
||||
IMogoAdasOCHCallback,
|
||||
IMogoCarLocationChangedListener2 {
|
||||
|
||||
@@ -57,6 +63,8 @@ class OCHTaxiFragment extends BaseOchFragment< OCHTaxiView, OCHTaxiPresenter > i
|
||||
private TextView mStartStationName;
|
||||
private TextView mEndStationName;
|
||||
private TextView mDistance;
|
||||
|
||||
private MogoPolylineOptions mogoPolylineOptions;
|
||||
@Override
|
||||
public int getStationPanelViewId() {
|
||||
return R.layout.module_och_taxi_panel;
|
||||
@@ -82,7 +90,6 @@ class OCHTaxiFragment extends BaseOchFragment< OCHTaxiView, OCHTaxiPresenter > i
|
||||
// showPanel();
|
||||
hidPanel();
|
||||
initListeners();
|
||||
// TODO: 2021/6/18 调整接口刷新时间
|
||||
// updateOrderStatus();
|
||||
if ( MogoApisHandler.getInstance()
|
||||
.getApis()
|
||||
@@ -108,6 +115,7 @@ class OCHTaxiFragment extends BaseOchFragment< OCHTaxiView, OCHTaxiPresenter > i
|
||||
.getApis()
|
||||
.getRegisterCenterApi()
|
||||
.registerCarLocationChangedListener( TAG, this );
|
||||
MogoApisHandler.getInstance().getApis().getAdasControllerApi().addAdasAutopilotRouteCallBack(this);
|
||||
}
|
||||
|
||||
@NonNull
|
||||
@@ -348,12 +356,24 @@ class OCHTaxiFragment extends BaseOchFragment< OCHTaxiView, OCHTaxiPresenter > i
|
||||
}
|
||||
|
||||
private Location mLocation;
|
||||
|
||||
private MogoLocation mogoLocation;
|
||||
@Override
|
||||
public void onCarLocationChanged2( Location location ) {
|
||||
OCHTaxiUiController.getInstance().runOnUIThread( () -> {
|
||||
calculateTravelDistance( location );
|
||||
} );
|
||||
|
||||
//坐标转换
|
||||
MogoLocation loc = new MogoLocation();
|
||||
loc.setTime(loc.getTime());
|
||||
loc.setAccuracy(location.getAccuracy());
|
||||
loc.setSpeed(location.getSpeed());
|
||||
loc.setLongitude(location.getLongitude());
|
||||
loc.setLatitude(location.getLatitude());
|
||||
loc.setAltitude(location.getAltitude());
|
||||
loc.setBearing(location.getBearing());
|
||||
loc.setProvider(location.getProvider());
|
||||
mogoLocation = loc;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -418,6 +438,19 @@ class OCHTaxiFragment extends BaseOchFragment< OCHTaxiView, OCHTaxiPresenter > i
|
||||
updateOrderStatus();
|
||||
});
|
||||
}
|
||||
private OCHTaxiOverlayManager ochTaxiOverlayManager;
|
||||
@Override
|
||||
public void routeResult(List<MogoLatLng> routeList) {
|
||||
Logger.d("lianglihui","routeResult");
|
||||
if (routeList != null && routeList.size() >0){
|
||||
Logger.d("lianglihui","routeResult:"+routeList.size());
|
||||
//adas回调导航路径 绘制引导线
|
||||
if ( ochTaxiOverlayManager == null){
|
||||
ochTaxiOverlayManager = new OCHTaxiOverlayManager(this.getContext());
|
||||
}
|
||||
ochTaxiOverlayManager.draw(mogoLocation,routeList);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onArriveAt(AdasOCHData data) {
|
||||
|
||||
@@ -92,34 +92,49 @@ public abstract class BaseOchFragment<V extends IView, P extends Presenter<V>> e
|
||||
|
||||
// 模拟 不可自动驾驶,目前场景是刚开机,adas还未和工控机连接
|
||||
findViewById(R.id.btnAutopilotDisable).setOnClickListener(view ->
|
||||
MogoApisHandler.getInstance().getApis()
|
||||
.getAdasControllerApi()
|
||||
.mockOchStatus(IMogoAdasOCHCallback.STATUS_AUTOPILOT_DISABLE, "不能使用")
|
||||
{
|
||||
MogoApisHandler.getInstance().getApis()
|
||||
.getAdasControllerApi()
|
||||
.mockOchStatus(IMogoAdasOCHCallback.STATUS_AUTOPILOT_DISABLE, "不能使用");
|
||||
Logger.d("lianglihui","模拟 不可自动驾驶");
|
||||
}
|
||||
);
|
||||
|
||||
// 模拟 可自动驾驶,工控机连接正常,且处于人工干预状态
|
||||
findViewById(R.id.btnAutopilotEnable).setOnClickListener(view ->
|
||||
MogoApisHandler.getInstance().getApis()
|
||||
.getAdasControllerApi()
|
||||
.mockOchStatus(IMogoAdasOCHCallback.STATUS_AUTOPILOT_ENABLE, "能使用")
|
||||
{
|
||||
MogoApisHandler.getInstance().getApis()
|
||||
.getAdasControllerApi()
|
||||
.mockOchStatus(IMogoAdasOCHCallback.STATUS_AUTOPILOT_ENABLE, "能使用");
|
||||
|
||||
Logger.d("lianglihui","模拟 可自动驾驶");
|
||||
}
|
||||
);
|
||||
|
||||
// 模拟 自动驾驶能力,自动驾驶中,可能是停车,可能是行进,但是是机器在处理车的前进后退,不是人
|
||||
findViewById(R.id.btnAutopilotRunning).setOnClickListener(view ->
|
||||
MogoApisHandler.getInstance().getApis()
|
||||
.getAdasControllerApi()
|
||||
.mockOchStatus(IMogoAdasOCHCallback.STATUS_AUTOPILOT_RUNNING, "Running")
|
||||
{
|
||||
MogoApisHandler.getInstance().getApis()
|
||||
.getAdasControllerApi()
|
||||
.mockOchStatus(IMogoAdasOCHCallback.STATUS_AUTOPILOT_RUNNING, "Running");
|
||||
Logger.d("lianglihui","模拟 自动驾驶能力");
|
||||
}
|
||||
);
|
||||
|
||||
// 模拟 自动驾驶站
|
||||
findViewById(R.id.btnAutopilotArrive).setOnClickListener(view ->
|
||||
MogoApisHandler.getInstance().getApis()
|
||||
.getAdasControllerApi().mockOchStatus(-1, "Arrived")
|
||||
{
|
||||
MogoApisHandler.getInstance().getApis()
|
||||
.getAdasControllerApi().mockOchStatus(-1, "Arrived");
|
||||
|
||||
Logger.d("lianglihui","模拟 自动驾驶站");
|
||||
}
|
||||
);
|
||||
|
||||
// 模拟 站点下发工控
|
||||
findViewById(R.id.btnAutopilotControl).setOnClickListener(view ->
|
||||
{
|
||||
Logger.d("lianglihui","模拟 站点下发工控");
|
||||
RemoteControlAutoPilotParameters currentAutopilot = new RemoteControlAutoPilotParameters();
|
||||
currentAutopilot.isSpeakVoice = true;
|
||||
// 万集东门站
|
||||
|
||||
@@ -0,0 +1,31 @@
|
||||
package com.mogo.map.impl.amap.utils;
|
||||
|
||||
import android.content.Context;
|
||||
|
||||
import com.amap.api.maps.CoordinateConverter;
|
||||
import com.amap.api.maps.model.LatLng;
|
||||
import com.mogo.map.MogoLatLng;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
public class CoordinateConvertUtils {
|
||||
|
||||
public static MogoLatLng CoordinateConverterFrom84(Context mContext, MogoLatLng mogoLatLng){
|
||||
CoordinateConverter mCoordinateConverter = new CoordinateConverter(mContext);
|
||||
mCoordinateConverter.from(CoordinateConverter.CoordType.GPS);
|
||||
mCoordinateConverter.coord(new LatLng(mogoLatLng.lat,mogoLatLng.lon));
|
||||
LatLng latLng = mCoordinateConverter.convert();
|
||||
return new MogoLatLng(latLng.latitude,latLng.longitude);
|
||||
}
|
||||
|
||||
public static List<MogoLatLng> CoordinateConverterFrom84ForList(Context mContext, List<MogoLatLng> mogoLatLngList){
|
||||
|
||||
List<MogoLatLng> list = new ArrayList<>();
|
||||
for (MogoLatLng m:mogoLatLngList) {
|
||||
MogoLatLng mogoLatLng = CoordinateConverterFrom84(mContext,m);
|
||||
list.add(mogoLatLng);
|
||||
}
|
||||
return list;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,121 @@
|
||||
package com.mogo.module.common.utils;
|
||||
|
||||
import static java.lang.Math.PI;
|
||||
|
||||
/**
|
||||
* author : donghongyu
|
||||
* e-mail : 1358506549@qq.com
|
||||
* date : 2020/4/14 1:02 PM
|
||||
* desc : 计算车辆驾驶方向的工具类
|
||||
* version: 1.0
|
||||
*/
|
||||
public class DrivingDirectionUtils {
|
||||
|
||||
/**
|
||||
* 计算车辆行驶方向 与 poi点到车辆的连线 间的夹角
|
||||
*
|
||||
* @param carLon 车辆位置 lon
|
||||
* @param carLat 车辆位置 lat
|
||||
* @param poiLon poi 位置 lon
|
||||
* @param poiLat poi 位置 lat
|
||||
* @param carAngle 车辆行驶方向
|
||||
* @return
|
||||
*/
|
||||
public static int getDegreeOfCar2Poi(double carLon, double carLat, double poiLon, double poiLat, int carAngle) {
|
||||
int poiAngle = 0;
|
||||
// 以子午线作为y轴 计算两点的余切 再将余切值转化为角度
|
||||
double _angle = Math.atan2(Math.abs(carLon - poiLon), Math.abs(carLat - poiLat)) * (180 / PI);
|
||||
//Log.w(MODULE_NAME, "getDegreeOfCar2Poi_计算车辆行驶方向 与 poi点到车辆的连线 间的夹角_angle===" + _angle);
|
||||
if (poiLon > carLon) {
|
||||
// poi 在 车辆位置的第1象限
|
||||
if (poiLat > carLat) {
|
||||
poiAngle = (int) _angle;
|
||||
}
|
||||
// poi 在 车辆位置的第2象限
|
||||
else {
|
||||
poiAngle = 180 - (int) _angle;
|
||||
}
|
||||
} else {
|
||||
// poi 在 车辆位置的第3象限
|
||||
if (poiLat < carLat) {
|
||||
poiAngle = (int) _angle + 180;
|
||||
}
|
||||
// poi 在 车辆位置的第4象限
|
||||
else {
|
||||
poiAngle = 360 - (int) _angle;
|
||||
}
|
||||
}
|
||||
return calculationAngle(poiAngle, carAngle);
|
||||
}
|
||||
|
||||
/**
|
||||
* 计算两个行驶方向间的夹角 计算结果小于180度
|
||||
*
|
||||
* @param angle0
|
||||
* @param angle1
|
||||
* @return
|
||||
*/
|
||||
public static int calculationAngle(int angle0, int angle1) {
|
||||
// 获取两方向间夹角
|
||||
int angle = Math.abs(angle0 - angle1);
|
||||
if (angle > 180) {
|
||||
int minAngle = Math.min(angle0, angle1);
|
||||
int maxAngle = Math.max(angle0, angle1);
|
||||
return 180 - Math.abs(minAngle + 180 - maxAngle);
|
||||
} else {
|
||||
return angle;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 计算车辆行驶方向角度,起点&终点经纬度
|
||||
*
|
||||
* @param carLat 车辆位置 lat
|
||||
* @param carLon 车辆位置 lon
|
||||
* @param poiLat poi 位置 lat
|
||||
* @param poiLon poi 位置 lon
|
||||
*/
|
||||
public static int getCarAngle(double carLat, double carLon, double poiLat, double poiLon) {
|
||||
int poiAngle = 0;
|
||||
// 以子午线作为y轴 计算两点的余切 再将余切值转化为角度
|
||||
double _angle = Math.atan2(Math.abs(carLon - poiLon), Math.abs(carLat - poiLat)) * (180 / PI);
|
||||
|
||||
if (poiLon > carLon) {
|
||||
// poi 在 车辆位置的第1象限
|
||||
if (poiLat > carLat) {
|
||||
poiAngle = (int) _angle;
|
||||
}
|
||||
// poi 在 车辆位置的第2象限
|
||||
else {
|
||||
poiAngle = 180 - (int) _angle;
|
||||
}
|
||||
} else {
|
||||
// poi 在 车辆位置的第3象限
|
||||
if (poiLat < carLat) {
|
||||
poiAngle = (int) _angle + 180;
|
||||
}
|
||||
// poi 在 车辆位置的第4象限
|
||||
else {
|
||||
poiAngle = 360 - (int) _angle;
|
||||
}
|
||||
}
|
||||
|
||||
if (poiAngle >= 355) {
|
||||
poiAngle = 0;
|
||||
}
|
||||
return poiAngle;
|
||||
}
|
||||
|
||||
/**
|
||||
* 计算连两个角度差值
|
||||
*
|
||||
* @param angle1 角度1
|
||||
* @param angle2 角度2
|
||||
* @return 差值
|
||||
*/
|
||||
public static double getAngleDiff(double angle1, double angle2) {
|
||||
// 两个角度差值较小
|
||||
return 180 - Math.abs(Math.abs(angle1 - angle2) - 180);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,45 @@
|
||||
package com.mogo.module.common.utils;
|
||||
|
||||
import android.location.Location;
|
||||
import android.util.Log;
|
||||
|
||||
import com.mogo.map.MogoLatLng;
|
||||
import com.mogo.map.location.MogoLocation;
|
||||
|
||||
|
||||
/**
|
||||
* author : donghongyu
|
||||
* e-mail : 1358506549@qq.com
|
||||
* date : 2020/5/15 10:31 AM
|
||||
* desc : 基于位置工具类
|
||||
* version: 1.0
|
||||
*/
|
||||
public class LocationUtils {
|
||||
private static final String TAG = "LocationUtils";
|
||||
|
||||
|
||||
/**
|
||||
* 获取传入的经纬度在车辆的什么位置
|
||||
*
|
||||
* @return 顺时针,true-前,false-后
|
||||
*/
|
||||
public static boolean isPointOnCarFront(MogoLocation carLocal, MogoLatLng pointLocal) {
|
||||
double carLon = carLocal.getLongitude();
|
||||
double carLat = carLocal.getLatitude();
|
||||
double poiLon = pointLocal.getLon();
|
||||
double poiLat = pointLocal.getLat();
|
||||
float carAngle = carLocal.getBearing();
|
||||
|
||||
// 计算车辆与点之间的夹角
|
||||
int diffAngle = DrivingDirectionUtils.getDegreeOfCar2Poi(
|
||||
carLon, carLat, poiLon, poiLat, (int) carAngle);
|
||||
|
||||
if (diffAngle <= 90) {
|
||||
Log.i(TAG, "目标点在车辆--前方");
|
||||
return true;
|
||||
} else {
|
||||
Log.i(TAG, "目标点在车辆--后方");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
package com.mogo.service.adas;
|
||||
|
||||
import com.mogo.map.MogoLatLng;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public interface IMogoAdasRouteCallBack {
|
||||
// TODO: 2021/6/23 工控机经纬度 绘制时转成高德经纬度
|
||||
void routeResult(List<MogoLatLng> routeList);
|
||||
}
|
||||
Reference in New Issue
Block a user