taxi 自动驾驶画线

This commit is contained in:
lianglihui
2021-06-24 12:18:57 +08:00
parent 604a2b78c5
commit e8e39e9e69
9 changed files with 344 additions and 15 deletions

View File

@@ -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

View File

@@ -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;
/**
* 是否达到起始站点
*/

View File

@@ -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;
}
}

View File

@@ -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) {

View File

@@ -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;
// 万集东门站

View File

@@ -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;
}
}

View File

@@ -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);
}
}

View File

@@ -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;
}
}
}

View File

@@ -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);
}