[2.13.0-arch-opt] merge
This commit is contained in:
@@ -5,11 +5,7 @@ import com.alibaba.android.arouter.facade.annotation.Route
|
||||
import com.mogo.eagle.core.data.config.FunctionBuildConfig
|
||||
import com.mogo.eagle.core.data.constants.MogoServicePaths.PATH_V2X_MODULE
|
||||
import com.mogo.eagle.core.function.api.base.IMoGoFunctionServerProvider
|
||||
import com.mogo.eagle.core.function.call.trafficlight.CallerTrafficLightManager
|
||||
import com.mogo.eagle.core.function.v2x.events.V2XEventManager
|
||||
import com.mogo.eagle.core.function.v2x.speedlimit.SpeedLimitDataManager
|
||||
import com.mogo.eagle.core.function.v2x.trafficlight.core.TrafficLightDispatcher
|
||||
import com.mogo.eagle.core.function.v2x.vip.VipCarManager
|
||||
import com.mogo.eagle.core.utilcode.mogo.AppIdentityModeUtils
|
||||
|
||||
@Route(path = PATH_V2X_MODULE)
|
||||
@@ -19,29 +15,18 @@ class V2XProvider : IMoGoFunctionServerProvider {
|
||||
get() = "V2XProvider"
|
||||
|
||||
override fun init(context: Context) {
|
||||
CallerTrafficLightManager.getTrafficLightProvider().initTrafficLightServer(context)
|
||||
VipCarManager.INSTANCE.initServer(context)
|
||||
SpeedLimitDataManager.getInstance().start()
|
||||
TrafficLightDispatcher.INSTANCE.initServer(context)
|
||||
|
||||
if (AppIdentityModeUtils.isBus(FunctionBuildConfig.appIdentityMode) && AppIdentityModeUtils.isPassenger(FunctionBuildConfig.appIdentityMode)) {
|
||||
//不处理
|
||||
} else {
|
||||
V2XEventManager.init(context)
|
||||
}
|
||||
|
||||
// RedLightWarningManager.INSTANCE.listenTrafficLight()
|
||||
}
|
||||
|
||||
override fun onDestroy() {
|
||||
VipCarManager.INSTANCE.destroy()
|
||||
TrafficLightDispatcher.INSTANCE.destroy()
|
||||
if (AppIdentityModeUtils.isBus(FunctionBuildConfig.appIdentityMode) && AppIdentityModeUtils.isPassenger(FunctionBuildConfig.appIdentityMode)) {
|
||||
//不处理
|
||||
} else {
|
||||
V2XEventManager.onDestroy()
|
||||
}
|
||||
|
||||
// RedLightWarningManager.INSTANCE.onDestroy()
|
||||
}
|
||||
}
|
||||
@@ -1,286 +0,0 @@
|
||||
package com.mogo.eagle.core.function.v2x.redlightwarning
|
||||
|
||||
import android.util.Log
|
||||
import com.mogo.eagle.core.data.deva.bizconfig.FuncBizConfig.Companion.BIZ_IVP
|
||||
import com.mogo.eagle.core.data.deva.bizconfig.FuncBizConfig.Companion.BIZ_IVP_GREEN
|
||||
import com.mogo.eagle.core.data.deva.bizconfig.FuncBizConfig.Companion.V2I
|
||||
import com.mogo.eagle.core.data.enums.EventTypeEnum
|
||||
import com.mogo.eagle.core.data.map.MogoLatLng
|
||||
import com.mogo.eagle.core.data.msgbox.MsgBoxBean
|
||||
import com.mogo.eagle.core.data.msgbox.MsgBoxType
|
||||
import com.mogo.eagle.core.data.msgbox.V2XMsg
|
||||
import com.mogo.eagle.core.data.trafficlight.*
|
||||
import com.mogo.eagle.core.data.trafficlight.TrafficLightStatusHelper.getCurrentRoadTrafficLight
|
||||
import com.mogo.eagle.core.function.api.autopilot.IMoGoChassisLocationGCJ02Listener
|
||||
import com.mogo.eagle.core.function.api.trafficlight.IMoGoTrafficLightListener
|
||||
import com.mogo.eagle.core.function.api.vip.IMoGoVipSetListener
|
||||
import com.mogo.eagle.core.function.call.autopilot.CallerChassisLocationGCJ20ListenerManager
|
||||
import com.mogo.eagle.core.function.call.hmi.CallerHmiManager
|
||||
import com.mogo.eagle.core.function.call.map.CallerMapLocationListenerManager
|
||||
import com.mogo.eagle.core.function.call.map.CallerMapUIServiceManager
|
||||
import com.mogo.eagle.core.function.call.msgbox.CallerMsgBoxManager
|
||||
import com.mogo.eagle.core.function.call.trafficlight.CallerTrafficLightListenerManager
|
||||
import com.mogo.eagle.core.function.call.vip.CallVipSetListenerManager
|
||||
import com.mogo.eagle.core.function.v2x.trafficlight.core.MogoTrafficLightManager
|
||||
import com.mogo.eagle.core.utilcode.mogo.logger.CallerLogger
|
||||
import com.mogo.eagle.core.utilcode.mogo.logger.scene.SceneConstant.Companion.M_V2X
|
||||
import com.mogo.eagle.core.utilcode.util.LocationUtils
|
||||
import com.mogo.eagle.core.utilcode.util.ThreadUtils
|
||||
import com.zhjt.service_biz.BizConfig
|
||||
import mogo.telematics.pad.MessagePad
|
||||
import kotlin.math.abs
|
||||
import kotlin.math.ceil
|
||||
import kotlin.math.floor
|
||||
import kotlin.math.min
|
||||
|
||||
|
||||
class RedLightWarningManager : IMoGoTrafficLightListener, IMoGoVipSetListener,
|
||||
IMoGoChassisLocationGCJ02Listener {
|
||||
|
||||
private var vip: Boolean = false
|
||||
|
||||
// 是否第一次进入道路100m处
|
||||
private var isFirst = true
|
||||
|
||||
// 是否已进入到路口(停止线处)
|
||||
private var isEnter = false
|
||||
|
||||
private var mLocation: MessagePad.GnssInfo? = null
|
||||
|
||||
companion object {
|
||||
|
||||
const val TAG = "RedLightWarningManager"
|
||||
|
||||
val INSTANCE: RedLightWarningManager by lazy(mode = LazyThreadSafetyMode.SYNCHRONIZED) {
|
||||
RedLightWarningManager()
|
||||
}
|
||||
}
|
||||
|
||||
override fun onTrafficLightStatus(trafficLightResult: TrafficLightResult) {
|
||||
// 到路口100m时回调
|
||||
CallerLogger.d("$M_V2X$TAG", "处理路口交通数据:是否是第一次处理:${isFirst}是否进入路口:${isEnter}")
|
||||
if (trafficLightResult.currentRoadIsRight()) {
|
||||
CallerLogger.d("$M_V2X$TAG", "当前道路右转,不处理")
|
||||
return
|
||||
}
|
||||
if (isFirst && !isEnter) {
|
||||
getCurrentRoadTrafficLight(trafficLightResult)?.let {
|
||||
handleRedLightWarning(it, trafficLightResult)
|
||||
}
|
||||
isFirst = false
|
||||
}
|
||||
}
|
||||
|
||||
override fun onEnterCrossRoad(enter: Boolean) {
|
||||
CallerLogger.d("$M_V2X$TAG", "回调是否进入路口:$enter")
|
||||
isEnter = enter
|
||||
if (enter) {
|
||||
isFirst = true
|
||||
}
|
||||
}
|
||||
|
||||
override fun onVipSet(status: Boolean) {
|
||||
vip = status
|
||||
}
|
||||
|
||||
fun listenTrafficLight() {
|
||||
CallerTrafficLightListenerManager.addListener(TAG, this)
|
||||
CallerChassisLocationGCJ20ListenerManager.addListener(TAG, this)
|
||||
CallVipSetListenerManager.addListener(TAG, this)
|
||||
}
|
||||
|
||||
private fun handleRedLightWarning(
|
||||
trafficLightStatus: TrafficLightStatus,
|
||||
trafficLightResult: TrafficLightResult
|
||||
) {
|
||||
// 如果是Vip则不处理
|
||||
if (vip) {
|
||||
CallerLogger.w("$M_V2X$TAG", "Vip用户不处理闯红灯、绿灯通行预警逻辑!")
|
||||
return
|
||||
}
|
||||
// 路口100m闯红灯预警
|
||||
mLocation?.let {
|
||||
// 单位m/s
|
||||
val speed = it.vehicleSpeed
|
||||
// 车停止或者速度非常慢,可能返回负数或者很小的值,需要过滤
|
||||
CallerLogger.d("$M_V2X$TAG", "speed is:$speed")
|
||||
if (speed <= 2.5f) return// 小于等于9km/h不处理
|
||||
// 由于到路口100m时回调不准,手动计算直线距离
|
||||
val roadResult = MogoTrafficLightManager.INSTANCE.getRoadResult()
|
||||
val distance = if (roadResult != null && roadResult.rectLatLngs.size >= 2) {
|
||||
getMinDistance(roadResult.rectLatLngs, it.latitude, it.longitude)
|
||||
} else {
|
||||
CallerMapUIServiceManager.getMapUIController()?.calculateLineDistance(
|
||||
MogoLatLng(it.latitude, it.longitude),
|
||||
MogoLatLng(trafficLightResult.lat, trafficLightResult.lon)
|
||||
) ?: 0f
|
||||
}
|
||||
CallerLogger.d(
|
||||
"$M_V2X$TAG",
|
||||
"路口经度为:${trafficLightResult.lon},纬度为:${trafficLightResult.lat};车的经度为:${it.longitude},纬度为:${it.latitude};两点距离为:${distance}"
|
||||
)
|
||||
val remainTime = trafficLightStatus.remain
|
||||
val arriveTime = distance / speed
|
||||
CallerLogger.d(
|
||||
"$M_V2X$TAG",
|
||||
"speed is:$speed,remainTime is:$remainTime,arriveTime is:$arriveTime,yellowTime is:${trafficLightResult.flashYellow}"
|
||||
)
|
||||
|
||||
when {
|
||||
trafficLightStatus.isRed() -> {
|
||||
CallerLogger.d("$M_V2X$TAG", "=====当前为红灯=====")
|
||||
// 到达路口时红灯还没走完(由于多个数据有偏差,红灯预警延长1s,绿灯提示条件延长1.5s,多报出错不如少报且准)
|
||||
if (arriveTime <= remainTime + 1) {
|
||||
redLightWarning()
|
||||
} else if (arriveTime > remainTime + trafficLightResult.flashYellow + 1.5) {// 到达时红、黄灯都走完
|
||||
// 单位Km/h,当前为红灯,推荐速度越慢越容易绿灯通过,且要满足[10,50]
|
||||
val originRemainSpeed =
|
||||
floor(distance / (remainTime + trafficLightResult.flashYellow + 1.5) * 3.6).toInt()
|
||||
when {
|
||||
originRemainSpeed > 50 -> greenLightWarning("10到50")
|
||||
originRemainSpeed in 10..50 -> greenLightWarning("10到$originRemainSpeed")
|
||||
}
|
||||
}
|
||||
}
|
||||
trafficLightStatus.isYellow() -> {
|
||||
CallerLogger.d("$M_V2X$TAG", "=====当前为黄灯=====")
|
||||
// 到达路口时黄灯还没走完(由于多个数据有偏差,红灯预警延长1s,绿灯提示延长1.5s,多报出错不如少报且准)
|
||||
if (arriveTime <= remainTime + 1) {
|
||||
redLightWarning()
|
||||
} else if (arriveTime > remainTime + 1.5) {
|
||||
// 单位Km/h,当前为黄灯,推荐速度越慢越容易绿灯通过,且要满足[10,50]
|
||||
val originRemainSpeed = floor(distance / (remainTime + 1.5) * 3.6).toInt()
|
||||
when {
|
||||
originRemainSpeed > 50 -> greenLightWarning("10到50")
|
||||
originRemainSpeed in 10..50 -> greenLightWarning("10到$originRemainSpeed")
|
||||
}
|
||||
}
|
||||
}
|
||||
trafficLightStatus.isGreen() -> {
|
||||
CallerLogger.d("$M_V2X$TAG", "=====当前为绿灯=====")
|
||||
// 到达路口时绿灯已经走完(由于多个数据有偏差,多报出错不如少报且准,绿灯时间减少一点)
|
||||
if (arriveTime >= remainTime - 1) {
|
||||
redLightWarning()
|
||||
} else if (arriveTime < remainTime - 1.5) {
|
||||
// 单位Km/h,当前为绿灯,推荐速度越快越容易绿灯通过,且要满足[10,50]
|
||||
val originRemainSpeed = ceil(distance / (remainTime - 1.5) * 3.6).toInt()
|
||||
when {
|
||||
originRemainSpeed < 10 -> greenLightWarning("10到50")
|
||||
originRemainSpeed in 10..50 -> greenLightWarning("${originRemainSpeed}到50")
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
} ?: run {
|
||||
CallerLogger.e("$M_V2X$TAG", "CurrentLocation is null!")
|
||||
}
|
||||
}
|
||||
|
||||
private fun getMinDistance(points: List<MogoLatLng>, lat: Double, lon: Double): Float {
|
||||
// 到路口100m时才计算,赋值一个较大值
|
||||
var minValue = 9999.9
|
||||
val size = points.size
|
||||
for (i in 0..size step 2) {
|
||||
if (i < size) {
|
||||
// 自车到0-1、2-3、4-5、6-7组成的线段的最小距离
|
||||
minValue = min(
|
||||
minValue,
|
||||
LocationUtils.pointToLine(
|
||||
points[i].lon,
|
||||
points[i].lat,
|
||||
points[i + 1].lon,
|
||||
points[i + 1].lat,
|
||||
lon,
|
||||
lat
|
||||
)
|
||||
)
|
||||
}
|
||||
}
|
||||
return if (minValue > 9999) 0f else minValue.toFloat()
|
||||
}
|
||||
|
||||
/**
|
||||
* 闯红灯预警
|
||||
*/
|
||||
@BizConfig(V2I, "", BIZ_IVP)
|
||||
private fun redLightWarning() {
|
||||
CallerLogger.d("$M_V2X$TAG", "=====闯红灯预警=====")
|
||||
ThreadUtils.runOnUiThread {
|
||||
CallerMsgBoxManager.saveMsgBox(
|
||||
MsgBoxBean(
|
||||
MsgBoxType.V2X,
|
||||
V2XMsg(
|
||||
EventTypeEnum.TYPE_USECASE_ID_IVP.poiType,
|
||||
EventTypeEnum.TYPE_USECASE_ID_IVP.content,
|
||||
EventTypeEnum.TYPE_USECASE_ID_IVP.tts
|
||||
)
|
||||
)
|
||||
)
|
||||
CallerHmiManager.warningV2X(
|
||||
EventTypeEnum.TYPE_USECASE_ID_IVP.poiType,
|
||||
EventTypeEnum.TYPE_USECASE_ID_IVP.content,
|
||||
EventTypeEnum.TYPE_USECASE_ID_IVP.tts,
|
||||
EventTypeEnum.TYPE_USECASE_ID_IVP.poiType,
|
||||
null,
|
||||
true,
|
||||
5000L
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 绿灯通行提示
|
||||
*/
|
||||
@BizConfig(V2I, "", BIZ_IVP_GREEN)
|
||||
private fun greenLightWarning(speed: String = "50") {
|
||||
CallerLogger.d("$M_V2X$TAG", "=====绿灯通行预警=====")
|
||||
ThreadUtils.runOnUiThread {
|
||||
val content = String.format(
|
||||
EventTypeEnum.getWarningContent(EventTypeEnum.TYPE_USECASE_ID_IVP_GREEN.poiType),
|
||||
speed
|
||||
)
|
||||
val tts = String.format(
|
||||
EventTypeEnum.getWarningTts(EventTypeEnum.TYPE_USECASE_ID_IVP_GREEN.poiType),
|
||||
speed
|
||||
)
|
||||
if (content.isNullOrEmpty() || tts.isNullOrEmpty()) {
|
||||
Log.d("MsgBox-RedLightWarManaG", "alertContent或ttsContent为空!")
|
||||
}
|
||||
CallerMsgBoxManager.saveMsgBox(
|
||||
MsgBoxBean(
|
||||
MsgBoxType.V2X,
|
||||
V2XMsg(
|
||||
EventTypeEnum.TYPE_USECASE_ID_IVP_GREEN.poiType,
|
||||
content,
|
||||
tts
|
||||
)
|
||||
)
|
||||
)
|
||||
CallerHmiManager.warningV2X(
|
||||
EventTypeEnum.TYPE_USECASE_ID_IVP_GREEN.poiType,
|
||||
content,
|
||||
tts,
|
||||
EventTypeEnum.TYPE_USECASE_ID_IVP_GREEN.poiType,
|
||||
null,
|
||||
true,
|
||||
5000L
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
private fun fEqual(a: Float, b: Float): Boolean {
|
||||
return abs(a - b) < 0.000001
|
||||
}
|
||||
|
||||
fun onDestroy() {
|
||||
CallVipSetListenerManager.removeListener(TAG)
|
||||
CallerTrafficLightListenerManager.removeListener(TAG)
|
||||
CallerMapLocationListenerManager.removeListener(TAG, false)
|
||||
}
|
||||
|
||||
override fun onChassisLocationGCJ02(gnssInfo: MessagePad.GnssInfo?) {
|
||||
gnssInfo?.let {
|
||||
mLocation = it
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,82 +0,0 @@
|
||||
package com.mogo.eagle.core.function.v2x.speedlimit;
|
||||
|
||||
import static com.mogo.eagle.core.data.config.HmiBuildConfig.isShowObuLimitSpeedView;
|
||||
import static com.mogo.eagle.core.data.deva.bizconfig.FuncBizConfig.BIZ_SLW;
|
||||
import static com.mogo.eagle.core.data.deva.bizconfig.FuncBizConfig.V2I;
|
||||
|
||||
import androidx.annotation.Nullable;
|
||||
|
||||
import com.mogo.eagle.core.function.api.autopilot.IMoGoChassisLocationGCJ02Listener;
|
||||
import com.mogo.eagle.core.function.call.autopilot.CallerChassisLocationGCJ20ListenerManager;
|
||||
import com.mogo.eagle.core.function.call.hmi.CallerHmiManager;
|
||||
import com.mogo.eagle.core.function.call.map.CallerMapUIServiceManager;
|
||||
import com.mogo.eagle.core.function.call.v2x.CallLimitingVelocityListenerManager;
|
||||
import com.mogo.eagle.core.utilcode.util.UiThreadHandler;
|
||||
import com.zhjt.service_biz.BizConfig;
|
||||
|
||||
import java.util.Timer;
|
||||
import java.util.TimerTask;
|
||||
|
||||
import mogo.telematics.pad.MessagePad;
|
||||
|
||||
/**
|
||||
* 限速
|
||||
*
|
||||
* @author mogoauto
|
||||
*/
|
||||
public class SpeedLimitDataManager implements IMoGoChassisLocationGCJ02Listener {
|
||||
|
||||
private final static String TAG = "SpeedLimitDataManager";
|
||||
private static SpeedLimitDataManager instance;
|
||||
private MessagePad.GnssInfo mLocation;
|
||||
|
||||
private SpeedLimitDataManager() {
|
||||
}
|
||||
|
||||
public static SpeedLimitDataManager getInstance() {
|
||||
if (instance == null) {
|
||||
synchronized (SpeedLimitDataManager.class) {
|
||||
if (instance == null) {
|
||||
instance = new SpeedLimitDataManager();
|
||||
}
|
||||
}
|
||||
}
|
||||
return instance;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onChassisLocationGCJ02(@Nullable MessagePad.GnssInfo gnssInfo) {
|
||||
mLocation = gnssInfo;
|
||||
}
|
||||
|
||||
private class SpeedTimerTask extends TimerTask {
|
||||
@Override
|
||||
public void run() {
|
||||
if (mLocation != null) {
|
||||
if(CallerMapUIServiceManager.INSTANCE.getMapUIController()!=null){
|
||||
getSpeedLimit();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@BizConfig(biz = V2I, dependentBizNode = "", bizNode = BIZ_SLW)
|
||||
private void getSpeedLimit() {
|
||||
if (!isShowObuLimitSpeedView) {
|
||||
int speedLimit = CallerMapUIServiceManager.INSTANCE.getMapUIController().getLimitSpeed(mLocation.getLongitude(), mLocation.getLatitude(), (float) mLocation.getHeading());
|
||||
UiThreadHandler.post(() -> {
|
||||
if (speedLimit > 0) {
|
||||
CallerHmiManager.INSTANCE.showLimitingVelocity(speedLimit);
|
||||
CallLimitingVelocityListenerManager.INSTANCE.invokeOnLimitingVelocityChange(speedLimit);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void start() {
|
||||
CallerChassisLocationGCJ20ListenerManager.INSTANCE.addListener(TAG, this);
|
||||
Timer mTimer = new Timer();
|
||||
mTimer.schedule(new SpeedTimerTask(), 3000, 1000);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,11 +0,0 @@
|
||||
package com.mogo.eagle.core.function.v2x.trafficlight
|
||||
|
||||
class TrafficLightConst {
|
||||
|
||||
companion object {
|
||||
const val MODULE_NAME = "MODULE_V2X_TRAFFIC_LIGHT"
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,65 +0,0 @@
|
||||
package com.mogo.eagle.core.function.v2x.trafficlight
|
||||
|
||||
import com.mogo.eagle.core.data.trafficlight.*
|
||||
import com.mogo.eagle.core.function.call.hmi.CallerHmiManager
|
||||
|
||||
class TrafficLightHMIManager {
|
||||
|
||||
companion object {
|
||||
const val TAG = "TrafficLightHMIManager"
|
||||
|
||||
val INSTANCE: TrafficLightHMIManager by lazy(mode = LazyThreadSafetyMode.SYNCHRONIZED) {
|
||||
TrafficLightHMIManager()
|
||||
}
|
||||
}
|
||||
|
||||
private var initView: Boolean = false
|
||||
|
||||
fun isWarningTrafficLightShow(): Boolean {
|
||||
return CallerHmiManager.isWarningTrafficLightShow()
|
||||
}
|
||||
|
||||
fun updateTrafficLight(trafficLightResult: TrafficLightResult) {
|
||||
val currentTrafficLight = trafficLightResult.currentRoadTrafficLight()
|
||||
currentTrafficLight?.let {
|
||||
if (!initView) {
|
||||
initView = true
|
||||
CallerHmiManager.showWarningTrafficLight(0,1)
|
||||
}
|
||||
callerHMIToChangeLight(it)
|
||||
}
|
||||
}
|
||||
|
||||
private fun callerHMIToChangeLight(trafficLightStatus: TrafficLightStatus) {
|
||||
val remain = if (trafficLightStatus.remain > 99) {
|
||||
99
|
||||
} else {
|
||||
trafficLightStatus.remain
|
||||
}
|
||||
when {
|
||||
trafficLightStatus.isGreen() || trafficLightStatus.isFlashGreen() -> {
|
||||
CallerHmiManager.showWarningTrafficLight(3,1)
|
||||
CallerHmiManager.changeCountdownGreen(remain)
|
||||
// CallerHmiManager.changeCountdownRed(-1)
|
||||
// CallerHmiManager.changeCountdownYellow(-1)
|
||||
}
|
||||
trafficLightStatus.isYellow() -> {
|
||||
CallerHmiManager.showWarningTrafficLight(2,1)
|
||||
CallerHmiManager.changeCountdownYellow(remain)
|
||||
// CallerHmiManager.changeCountdownGreen(-1)
|
||||
// CallerHmiManager.changeCountdownRed(-1)
|
||||
}
|
||||
trafficLightStatus.isRed() -> {
|
||||
CallerHmiManager.showWarningTrafficLight(1,1)
|
||||
CallerHmiManager.changeCountdownRed(remain)
|
||||
// CallerHmiManager.changeCountdownGreen(-1)
|
||||
// CallerHmiManager.changeCountdownYellow(-1)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun hideTrafficLight() {
|
||||
initView = false
|
||||
CallerHmiManager.disableWarningTrafficLight()
|
||||
}
|
||||
}
|
||||
@@ -1,52 +0,0 @@
|
||||
package com.mogo.eagle.core.function.v2x.trafficlight
|
||||
|
||||
import android.content.Context
|
||||
import com.alibaba.android.arouter.facade.annotation.Route
|
||||
import com.mogo.eagle.core.data.constants.MogoServicePaths
|
||||
import com.mogo.eagle.core.data.trafficlight.TrafficLightControl
|
||||
import com.mogo.eagle.core.data.trafficlight.TrafficLightDetail
|
||||
import com.mogo.eagle.core.function.api.trafficlight.ITrafficLightProvider
|
||||
import com.mogo.eagle.core.function.v2x.trafficlight.TrafficLightConst.Companion.MODULE_NAME
|
||||
import com.mogo.eagle.core.function.v2x.trafficlight.core.MogoTrafficLightManager
|
||||
|
||||
@Route(path = MogoServicePaths.PATH_TRAFFIC_LIGHT)
|
||||
class TrafficLightProvider : ITrafficLightProvider {
|
||||
|
||||
override val functionName: String
|
||||
get() = MODULE_NAME
|
||||
|
||||
override fun init(context: Context) {
|
||||
|
||||
}
|
||||
|
||||
override fun initTrafficLightServer(context: Context) {
|
||||
MogoTrafficLightManager.INSTANCE.initServer(context)
|
||||
}
|
||||
|
||||
override fun getTrafficLightCurrentState(): TrafficLightDetail? {
|
||||
return MogoTrafficLightManager.INSTANCE.getTrafficLightCurrentState()
|
||||
}
|
||||
|
||||
override fun turnLightToGreen(
|
||||
lightId: Int,
|
||||
crossingNo: String,
|
||||
heading: Double,
|
||||
controlTime: Int,
|
||||
onSuccess: ((TrafficLightControl) -> Unit),
|
||||
onError: ((String) -> Unit)
|
||||
) {
|
||||
return MogoTrafficLightManager.INSTANCE.turnLightToGreen(
|
||||
lightId,
|
||||
crossingNo,
|
||||
heading,
|
||||
controlTime,
|
||||
onSuccess,
|
||||
onError
|
||||
)
|
||||
}
|
||||
|
||||
override fun onDestroy() {
|
||||
MogoTrafficLightManager.INSTANCE.onDestroy()
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,191 +0,0 @@
|
||||
package com.mogo.eagle.core.function.v2x.trafficlight.core
|
||||
|
||||
import android.content.Context
|
||||
import android.os.Handler
|
||||
import android.os.Looper
|
||||
import com.mogo.eagle.core.data.trafficlight.*
|
||||
import com.mogo.eagle.core.function.api.autopilot.IMoGoChassisLocationGCJ02Listener
|
||||
import com.mogo.eagle.core.function.call.autopilot.CallerChassisLocationGCJ20ListenerManager
|
||||
import com.mogo.eagle.core.function.call.map.CallerMapUIServiceManager
|
||||
import com.mogo.eagle.core.function.call.trafficlight.CallerTrafficLightListenerManager
|
||||
import com.mogo.eagle.core.function.v2x.trafficlight.TrafficLightHMIManager
|
||||
import com.mogo.eagle.core.function.v2x.trafficlight.core.TrafficLightThreadHandler.Companion.MSG_WHAT_LOOP_SEARCH_CROSS_ROAD
|
||||
import com.mogo.eagle.core.function.v2x.trafficlight.core.TrafficLightThreadHandler.Companion.MSG_WHAT_LOOP_SEARCH_TRAFFIC_LIGHT
|
||||
import com.mogo.eagle.core.function.v2x.trafficlight.core.TrafficLightThreadHandler.Companion.MSG_WHAT_STOP_SEARCH_CROSS_ROAD
|
||||
import com.mogo.eagle.core.function.v2x.trafficlight.core.TrafficLightThreadHandler.Companion.MSG_WHAT_STOP_SEARCH_TRAFFIC_LIGHT
|
||||
import com.mogo.eagle.core.function.v2x.trafficlight.network.TrafficLightNetWorkModel
|
||||
import com.mogo.eagle.core.utilcode.mogo.logger.CallerLogger
|
||||
import com.mogo.eagle.core.utilcode.mogo.logger.scene.SceneConstant.Companion.M_V2X
|
||||
import mogo.telematics.pad.MessagePad
|
||||
|
||||
class MogoTrafficLightManager : IMoGoChassisLocationGCJ02Listener {
|
||||
|
||||
companion object {
|
||||
|
||||
const val TAG = "MogoTrafficLightManager"
|
||||
|
||||
val INSTANCE: MogoTrafficLightManager by lazy(mode = LazyThreadSafetyMode.SYNCHRONIZED) {
|
||||
MogoTrafficLightManager()
|
||||
}
|
||||
}
|
||||
|
||||
private var mContext: Context? = null
|
||||
private val trafficLightNetWorkModel = TrafficLightNetWorkModel()
|
||||
private var mLocation: MessagePad.GnssInfo? = null
|
||||
private var roadIDResult: RoadIDResult? = null
|
||||
private var trafficLightResult: TrafficLightResult? = null
|
||||
|
||||
private var inRange: Boolean = false
|
||||
private var firstLoopCrossRoad: Boolean = true //开启循环请求路口
|
||||
|
||||
private var mThreadHandler: Handler? = null
|
||||
|
||||
fun initServer(context: Context) {
|
||||
mContext = context
|
||||
CallerChassisLocationGCJ20ListenerManager.addListener(TAG, this)
|
||||
mThreadHandler =
|
||||
TrafficLightThreadHandler(Looper.getMainLooper(), {
|
||||
//第一次查询路口时,如果红绿灯显示,则隐藏掉
|
||||
if (firstLoopCrossRoad && TrafficLightHMIManager.INSTANCE.isWarningTrafficLightShow()) {
|
||||
TrafficLightHMIManager.INSTANCE.hideTrafficLight()
|
||||
CallerTrafficLightListenerManager.resetTrafficLightData()
|
||||
}
|
||||
firstLoopCrossRoad = false
|
||||
mLocation?.let { it ->
|
||||
val tileId = CallerMapUIServiceManager.getMapUIController()
|
||||
?.getTileId(it.longitude, it.latitude) ?: 0
|
||||
trafficLightNetWorkModel.requestRoadID(
|
||||
tileId, it.latitude, it.longitude, it.heading,
|
||||
{
|
||||
mThreadHandler?.sendEmptyMessage(MSG_WHAT_STOP_SEARCH_CROSS_ROAD)
|
||||
roadIDResult = it
|
||||
},
|
||||
{
|
||||
//CallerLogger.w(M_V2X + TAG, "request road id error : $it")
|
||||
})
|
||||
}
|
||||
}, {
|
||||
//stop loop search road id
|
||||
trafficLightNetWorkModel.cancelRequestRoadID()
|
||||
//开始请求红绿灯
|
||||
mThreadHandler?.sendEmptyMessage(MSG_WHAT_LOOP_SEARCH_TRAFFIC_LIGHT)
|
||||
}, {
|
||||
//start loop traffic light
|
||||
mLocation?.let {
|
||||
val road =
|
||||
if (roadIDResult?.rsCrossId.isNullOrBlank()) "" else roadIDResult?.rsCrossId
|
||||
trafficLightNetWorkModel.requestTrafficLight(
|
||||
it.latitude, it.longitude, it.heading, road, { result ->
|
||||
trafficLightResult = result
|
||||
// TrafficLightHMIManager.INSTANCE.updateTrafficLight(result)
|
||||
CallerTrafficLightListenerManager.invokeTrafficLightStatus(result)
|
||||
},
|
||||
{ errorMsg ->
|
||||
//如果没有获取到正确的红绿灯数据,则取消读灯,继续读路口,防止出现一直读灯的情况
|
||||
CallerLogger.e(M_V2X + TAG, "request Traffic Light error : $errorMsg")
|
||||
//stop loop traffic light
|
||||
trafficLightNetWorkModel.cancelRequestTrafficLight()
|
||||
//未查到红绿灯,加入2秒延时请求路口ID
|
||||
mThreadHandler?.let { handler ->
|
||||
if (handler.hasMessages(MSG_WHAT_LOOP_SEARCH_TRAFFIC_LIGHT)) {
|
||||
handler.removeMessages(MSG_WHAT_LOOP_SEARCH_TRAFFIC_LIGHT)
|
||||
}
|
||||
if (handler.hasMessages(MSG_WHAT_LOOP_SEARCH_CROSS_ROAD)) {
|
||||
handler.removeMessages(MSG_WHAT_LOOP_SEARCH_CROSS_ROAD)
|
||||
}
|
||||
handler.sendEmptyMessageDelayed(
|
||||
MSG_WHAT_LOOP_SEARCH_CROSS_ROAD,
|
||||
2_000L
|
||||
)
|
||||
}
|
||||
if (TrafficLightHMIManager.INSTANCE.isWarningTrafficLightShow()) {
|
||||
TrafficLightHMIManager.INSTANCE.hideTrafficLight()
|
||||
CallerTrafficLightListenerManager.resetTrafficLightData()
|
||||
}
|
||||
CallerTrafficLightListenerManager.invokeTrafficRequestError()
|
||||
|
||||
})
|
||||
}
|
||||
}, {
|
||||
//stop loop traffic light
|
||||
trafficLightNetWorkModel.cancelRequestTrafficLight()
|
||||
//刚经过红绿灯,加入3秒延时请求路口ID
|
||||
mThreadHandler?.let {
|
||||
if (it.hasMessages(MSG_WHAT_LOOP_SEARCH_CROSS_ROAD)) {
|
||||
it.removeMessages(MSG_WHAT_LOOP_SEARCH_CROSS_ROAD)
|
||||
}
|
||||
it.sendEmptyMessageDelayed(MSG_WHAT_LOOP_SEARCH_CROSS_ROAD, 2_000L)
|
||||
}
|
||||
})
|
||||
mThreadHandler?.sendEmptyMessageDelayed(MSG_WHAT_LOOP_SEARCH_CROSS_ROAD, 5_000L)
|
||||
}
|
||||
|
||||
private fun checkOutOfRange() {
|
||||
mLocation?.let { loc ->
|
||||
roadIDResult?.let {
|
||||
// 检测是否开过路口,开过路口则停止读灯。并重置 trafficLightResult 值为 null
|
||||
if (trafficLightResult != null && it.isInRange(loc.latitude, loc.longitude)) {
|
||||
inRange = true
|
||||
// CallerLogger.d(M_V2X + TAG, "进入路口")
|
||||
CallerTrafficLightListenerManager.invokeEnterCrossRoad(true)
|
||||
return
|
||||
}
|
||||
if (inRange) {
|
||||
// CallerLogger.d(M_V2X + TAG, "离开路口")
|
||||
CallerTrafficLightListenerManager.invokeEnterCrossRoad(false)
|
||||
inRange = false
|
||||
trafficLightResult = null
|
||||
firstLoopCrossRoad = true
|
||||
mThreadHandler?.sendEmptyMessage(MSG_WHAT_STOP_SEARCH_TRAFFIC_LIGHT)
|
||||
TrafficLightHMIManager.INSTANCE.hideTrafficLight()
|
||||
CallerTrafficLightListenerManager.resetTrafficLightData()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun getTrafficLightCurrentState(): TrafficLightDetail? {
|
||||
trafficLightResult?.let {
|
||||
return it.laneList
|
||||
}
|
||||
return null
|
||||
}
|
||||
|
||||
fun getRoadResult(): RoadIDResult? {
|
||||
return roadIDResult
|
||||
}
|
||||
|
||||
fun turnLightToGreen(
|
||||
lightId: Int,
|
||||
crossingNo: String,
|
||||
heading: Double,
|
||||
controlTime: Int,
|
||||
onSuccess: ((TrafficLightControl) -> Unit),
|
||||
onError: ((String) -> Unit)
|
||||
) {
|
||||
trafficLightNetWorkModel.turnLightToGreen(
|
||||
lightId,
|
||||
crossingNo,
|
||||
heading,
|
||||
controlTime,
|
||||
onSuccess,
|
||||
onError
|
||||
)
|
||||
}
|
||||
|
||||
fun onDestroy() {
|
||||
mThreadHandler = null
|
||||
mContext = null
|
||||
mLocation = null
|
||||
trafficLightResult = null
|
||||
}
|
||||
|
||||
override fun onChassisLocationGCJ02(gnssInfo: MessagePad.GnssInfo?) {
|
||||
gnssInfo?.let {
|
||||
mLocation = it
|
||||
checkOutOfRange()
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -1,127 +0,0 @@
|
||||
package com.mogo.eagle.core.function.v2x.trafficlight.core
|
||||
|
||||
import android.content.Context
|
||||
import android.os.Handler
|
||||
import com.mogo.eagle.core.data.trafficlight.TrafficLightResult
|
||||
import com.mogo.eagle.core.function.api.autopilot.IMoGoAutopilotIdentifyListener
|
||||
import com.mogo.eagle.core.function.api.trafficlight.IMoGoTrafficLightListener
|
||||
import com.mogo.eagle.core.function.call.autopilot.CallerAutopilotIdentifyListenerManager
|
||||
import com.mogo.eagle.core.function.call.hmi.CallerHmiManager
|
||||
import com.mogo.eagle.core.function.call.trafficlight.CallerTrafficLightListenerManager
|
||||
import com.mogo.eagle.core.function.v2x.trafficlight.TrafficLightHMIManager
|
||||
import perception.TrafficLightOuterClass
|
||||
import perception.TrafficLightOuterClass.TrafficLight
|
||||
|
||||
/**
|
||||
* @author XuXinChao
|
||||
* @description 对多个红绿灯信号来源进行统一调度(AI云、工控机)
|
||||
* @since: 2022/4/28
|
||||
*/
|
||||
class TrafficLightDispatcher : IMoGoAutopilotIdentifyListener , IMoGoTrafficLightListener {
|
||||
|
||||
companion object{
|
||||
const val TAG = "TrafficLightDispatcher"
|
||||
val INSTANCE: TrafficLightDispatcher by lazy(mode = LazyThreadSafetyMode.SYNCHRONIZED){
|
||||
TrafficLightDispatcher()
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private var mContext: Context? = null
|
||||
//是否有AI获取红绿灯灯态
|
||||
private var hasAiLightStatus: Boolean = false
|
||||
|
||||
fun initServer(context: Context){
|
||||
mContext = context
|
||||
//注册监听AI云获取红绿灯状态,注册监听AI云进入路口,注册监听红绿灯请求失败
|
||||
CallerTrafficLightListenerManager.addListener(TAG, this)
|
||||
//注册监听工控机感知红绿灯
|
||||
CallerAutopilotIdentifyListenerManager.addListener(TAG, this)
|
||||
}
|
||||
|
||||
/**
|
||||
* 工控机感知红绿灯
|
||||
* @param trafficLights 感知红绿灯
|
||||
*/
|
||||
override fun onAutopilotPerceptionTrafficLight(trafficLights: TrafficLightOuterClass.TrafficLights?) {
|
||||
if(!hasAiLightStatus){
|
||||
trafficLights?.let { it ->
|
||||
var light :TrafficLight?= null
|
||||
if(it.hasStraight()){
|
||||
light = it.straight
|
||||
}else if(it.hasLeft()){
|
||||
light = it.left
|
||||
}else if(it.hasRight()){
|
||||
light = it.right
|
||||
}else if(it.hasUTurn()){
|
||||
light = it.uTurn
|
||||
}
|
||||
if(light == null){
|
||||
//隐藏红绿灯显示
|
||||
TrafficLightHMIManager.INSTANCE.hideTrafficLight()
|
||||
}else{
|
||||
when (light.state) {
|
||||
TrafficLightOuterClass.LightState.STATE_RED -> {
|
||||
//红灯
|
||||
CallerHmiManager.showWarningTrafficLight(1,2)
|
||||
CallerHmiManager.changeCountdownGreen(0)
|
||||
}
|
||||
TrafficLightOuterClass.LightState.STATE_YELLOW -> {
|
||||
//黄灯
|
||||
CallerHmiManager.showWarningTrafficLight(2,2)
|
||||
CallerHmiManager.changeCountdownGreen(0)
|
||||
}
|
||||
TrafficLightOuterClass.LightState.STATE_GREEN -> {
|
||||
//绿灯
|
||||
CallerHmiManager.showWarningTrafficLight(3,2)
|
||||
CallerHmiManager.changeCountdownGreen(0)
|
||||
}
|
||||
TrafficLightOuterClass.LightState.STATE_OFF -> {
|
||||
//黑灯,隐藏红绿灯显示
|
||||
TrafficLightHMIManager.INSTANCE.hideTrafficLight()
|
||||
}
|
||||
else -> {}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* AI云获取红绿灯状态
|
||||
*/
|
||||
override fun onTrafficLightStatus(trafficLightResult: TrafficLightResult) {
|
||||
TrafficLightHMIManager.INSTANCE.updateTrafficLight(trafficLightResult)
|
||||
hasAiLightStatus = true
|
||||
}
|
||||
|
||||
/**
|
||||
* 车辆进入路口
|
||||
*/
|
||||
override fun onEnterCrossRoad(enter: Boolean) {
|
||||
if(!enter){
|
||||
Handler().postDelayed({
|
||||
hasAiLightStatus = false
|
||||
}, 5000)
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* 红绿灯接口请求失败
|
||||
*/
|
||||
override fun onTrafficRequestError() {
|
||||
hasAiLightStatus = false
|
||||
}
|
||||
|
||||
|
||||
fun destroy(){
|
||||
//取消注册监听AI云获取红绿灯状态,取消注册监听红绿灯请求失败,取消注册监听AI云进入路口
|
||||
CallerTrafficLightListenerManager.removeListener(TAG)
|
||||
//取消注册监听工控机感知红绿灯
|
||||
CallerAutopilotIdentifyListenerManager.removeListener(TAG)
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,61 +0,0 @@
|
||||
package com.mogo.eagle.core.function.v2x.trafficlight.core
|
||||
|
||||
import android.os.Handler
|
||||
import android.os.Looper
|
||||
import android.os.Message
|
||||
|
||||
class TrafficLightThreadHandler : Handler {
|
||||
|
||||
private var loopSearchCrossRoad: (() -> Unit)? = null
|
||||
private var stopSearchCrossRoad: (() -> Unit)? = null
|
||||
private var loopSearchTrafficLight: (() -> Unit)? = null
|
||||
private var stopSearchTrafficLight: (() -> Unit)? = null
|
||||
|
||||
constructor(
|
||||
looper: Looper,
|
||||
loopSearchCrossRoad: (() -> Unit),
|
||||
stopSearchCrossRoad: (() -> Unit),
|
||||
loopSearchTrafficLight: (() -> Unit),
|
||||
stopSearchTrafficLight: (() -> Unit)
|
||||
) : super(looper) {
|
||||
this.loopSearchCrossRoad = loopSearchCrossRoad
|
||||
this.stopSearchCrossRoad = stopSearchCrossRoad
|
||||
this.loopSearchTrafficLight = loopSearchTrafficLight
|
||||
this.stopSearchTrafficLight = stopSearchTrafficLight
|
||||
}
|
||||
|
||||
companion object {
|
||||
const val MSG_WHAT_LOOP_SEARCH_CROSS_ROAD = 1
|
||||
const val MSG_WHAT_STOP_SEARCH_CROSS_ROAD = 2
|
||||
const val MSG_WHAT_LOOP_SEARCH_TRAFFIC_LIGHT = 3
|
||||
const val MSG_WHAT_STOP_SEARCH_TRAFFIC_LIGHT = 4
|
||||
}
|
||||
|
||||
override fun handleMessage(msg: Message) {
|
||||
super.handleMessage(msg)
|
||||
when (msg.what) {
|
||||
MSG_WHAT_LOOP_SEARCH_CROSS_ROAD -> {
|
||||
//handler轮询,后续从地图处获取到车道线(前提获取车道线没有异步调用),来优化轮询时长
|
||||
sendEmptyMessageDelayed(MSG_WHAT_LOOP_SEARCH_CROSS_ROAD,300L)
|
||||
loopSearchCrossRoad?.invoke()
|
||||
}
|
||||
MSG_WHAT_STOP_SEARCH_CROSS_ROAD -> {
|
||||
if(hasMessages(MSG_WHAT_LOOP_SEARCH_CROSS_ROAD)){
|
||||
removeMessages(MSG_WHAT_LOOP_SEARCH_CROSS_ROAD)
|
||||
}
|
||||
stopSearchCrossRoad?.invoke()
|
||||
}
|
||||
MSG_WHAT_LOOP_SEARCH_TRAFFIC_LIGHT -> {
|
||||
sendEmptyMessageDelayed(MSG_WHAT_LOOP_SEARCH_TRAFFIC_LIGHT,700L)
|
||||
loopSearchTrafficLight?.invoke()
|
||||
}
|
||||
MSG_WHAT_STOP_SEARCH_TRAFFIC_LIGHT -> {
|
||||
if(hasMessages(MSG_WHAT_LOOP_SEARCH_TRAFFIC_LIGHT)){
|
||||
removeMessages(MSG_WHAT_LOOP_SEARCH_TRAFFIC_LIGHT)
|
||||
}
|
||||
stopSearchTrafficLight?.invoke()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,28 +0,0 @@
|
||||
package com.mogo.eagle.core.function.v2x.trafficlight.network
|
||||
|
||||
import com.mogo.eagle.core.data.BaseResponse
|
||||
import com.mogo.eagle.core.data.trafficlight.RoadIDResult
|
||||
import com.mogo.eagle.core.data.trafficlight.TrafficLightControl
|
||||
import com.mogo.eagle.core.data.trafficlight.TrafficLightResult
|
||||
import retrofit2.http.FieldMap
|
||||
import retrofit2.http.FormUrlEncoded
|
||||
import retrofit2.http.POST
|
||||
|
||||
interface TrafficLightApiService {
|
||||
|
||||
//获取前方路口RoadID
|
||||
@FormUrlEncoded
|
||||
@POST("ai-roadInfo-service/cross/near")
|
||||
suspend fun getFrontRoadID(@FieldMap roadID: Map<String, String>): BaseResponse<RoadIDResult>
|
||||
|
||||
//获取前方红绿灯状态
|
||||
@FormUrlEncoded
|
||||
@POST("mec-etl-server/light/bgd/channel/realTime")
|
||||
suspend fun getTrafficLight(@FieldMap status: Map<String, String>): BaseResponse<TrafficLightResult>
|
||||
|
||||
//变灯
|
||||
@FormUrlEncoded
|
||||
@POST("mec-etl-server/light/bdg/newTask")
|
||||
suspend fun changeLight(@FieldMap turnLight: Map<String, String>): BaseResponse<TrafficLightControl>
|
||||
|
||||
}
|
||||
@@ -1,137 +0,0 @@
|
||||
package com.mogo.eagle.core.function.v2x.trafficlight.network
|
||||
|
||||
import com.mogo.cloud.passport.MoGoAiCloudClientConfig
|
||||
import com.mogo.eagle.core.data.BaseResponse
|
||||
import com.mogo.eagle.core.data.trafficlight.*
|
||||
import com.mogo.eagle.core.network.MoGoRetrofitFactory
|
||||
import com.mogo.eagle.core.network.apiCall
|
||||
import com.mogo.eagle.core.network.cancel
|
||||
import com.mogo.eagle.core.network.request
|
||||
import com.mogo.commons.constants.HostConst.CITY_HOST
|
||||
import com.mogo.eagle.core.utilcode.util.GsonUtils
|
||||
|
||||
class TrafficLightNetWorkModel {
|
||||
|
||||
private fun getNetWorkApi(baseUrl: String = CITY_HOST): TrafficLightApiService {
|
||||
return MoGoRetrofitFactory.getInstanceNoCallAdapter(baseUrl)
|
||||
.create(TrafficLightApiService::class.java)
|
||||
}
|
||||
|
||||
fun requestRoadID(
|
||||
tileID: Long,
|
||||
lat: Double,
|
||||
lon: Double,
|
||||
bearing: Double,
|
||||
onSuccess: ((RoadIDResult) -> Unit),
|
||||
onError: ((String) -> Unit),
|
||||
) {
|
||||
request<BaseResponse<RoadIDResult>>("requestRoadID") {
|
||||
val map = hashMapOf<String, String>()
|
||||
start {
|
||||
val roadIDRequestData = RoadIDRequestData(tileID, lat, lon, bearing)
|
||||
map["sn"] = MoGoAiCloudClientConfig.getInstance().sn
|
||||
map["data"] = GsonUtils.toJson(roadIDRequestData)
|
||||
}
|
||||
loader {
|
||||
apiCall {
|
||||
getNetWorkApi().getFrontRoadID(map)
|
||||
}
|
||||
}
|
||||
onSuccess {
|
||||
if (it?.result != null) {
|
||||
if (!it.result.rsCrossId.isNullOrEmpty() && !it.result.rectLatLngs.isNullOrEmpty()) {
|
||||
onSuccess.invoke(it.result)
|
||||
} else {
|
||||
onError.invoke("requestRoadID result rsCrossId is null")
|
||||
}
|
||||
} else {
|
||||
onError.invoke("requestRoadID result is null")
|
||||
}
|
||||
}
|
||||
onError {
|
||||
if (it.message != null) {
|
||||
onError.invoke(it.message!!)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun cancelRequestRoadID() {
|
||||
cancel("requestRoadID")
|
||||
}
|
||||
|
||||
fun requestTrafficLight(
|
||||
lat: Double,
|
||||
lon: Double,
|
||||
bearing: Double,
|
||||
roadId: String?,
|
||||
onSuccess: ((TrafficLightResult) -> Unit),
|
||||
onError: ((String) -> Unit),
|
||||
) {
|
||||
request<BaseResponse<TrafficLightResult>>("requestTrafficLight") {
|
||||
val map = hashMapOf<String, String>()
|
||||
start {
|
||||
if (roadId == null) {
|
||||
return@start
|
||||
}
|
||||
val trafficLightRequestData = TrafficLightRequestData(lat, lon, bearing, roadId)
|
||||
map["sn"] = MoGoAiCloudClientConfig.getInstance().sn
|
||||
map["data"] = GsonUtils.toJson(trafficLightRequestData)
|
||||
}
|
||||
loader {
|
||||
apiCall {
|
||||
getNetWorkApi().getTrafficLight(map)
|
||||
}
|
||||
}
|
||||
onSuccess {
|
||||
if (it.result != null) {
|
||||
onSuccess.invoke(it.result)
|
||||
} else {
|
||||
onError.invoke(it.msg ?: "返回result数据为null")
|
||||
}
|
||||
}
|
||||
onError {
|
||||
if (it.message != null) {
|
||||
onError.invoke(it.message!!)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun cancelRequestTrafficLight() {
|
||||
cancel("requestTrafficLight")
|
||||
}
|
||||
|
||||
fun turnLightToGreen(
|
||||
lightId: Int,
|
||||
crossingNo: String,
|
||||
heading: Double,
|
||||
controlTime: Int,
|
||||
onSuccess: ((TrafficLightControl) -> Unit),
|
||||
onError: ((String) -> Unit)
|
||||
) {
|
||||
request<BaseResponse<TrafficLightControl>> {
|
||||
val map = hashMapOf<String, String>()
|
||||
start {
|
||||
val trafficLightRequestData =
|
||||
ChangeLightRequestData(lightId, crossingNo, heading, controlTime)
|
||||
map["sn"] = MoGoAiCloudClientConfig.getInstance().sn
|
||||
map["data"] = GsonUtils.toJson(trafficLightRequestData)
|
||||
}
|
||||
loader {
|
||||
apiCall {
|
||||
getNetWorkApi().changeLight(map)
|
||||
}
|
||||
}
|
||||
onSuccess {
|
||||
onSuccess.invoke(it.result)
|
||||
}
|
||||
onError {
|
||||
if (it.message != null) {
|
||||
onError.invoke(it.message!!)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,302 +0,0 @@
|
||||
package com.mogo.eagle.core.function.v2x.vip
|
||||
|
||||
import android.content.Context
|
||||
import android.os.Handler
|
||||
import android.os.Looper
|
||||
import android.os.Message
|
||||
import android.util.Log
|
||||
import com.mogo.aicloud.services.socket.IMogoOnMessageListener
|
||||
import com.mogo.aicloud.services.socket.MogoAiCloudSocketManager
|
||||
import com.mogo.cloud.passport.MoGoAiCloudClientConfig
|
||||
import com.mogo.eagle.core.data.deva.bizconfig.FuncBizConfig.Companion.BIZ_VIP
|
||||
import com.mogo.eagle.core.data.deva.bizconfig.FuncBizConfig.Companion.V2N
|
||||
import com.mogo.eagle.core.data.enums.EventTypeEnum
|
||||
import com.mogo.eagle.core.data.msgbox.MsgBoxBean
|
||||
import com.mogo.eagle.core.data.msgbox.MsgBoxType
|
||||
import com.mogo.eagle.core.data.msgbox.V2XMsg
|
||||
import com.mogo.eagle.core.data.trafficlight.TrafficLightResult
|
||||
import com.mogo.eagle.core.data.trafficlight.currentRoadTrafficLight
|
||||
import com.mogo.eagle.core.data.trafficlight.isGreen
|
||||
import com.mogo.eagle.core.data.trafficlight.isRed
|
||||
import com.mogo.eagle.core.data.v2x.VipMessage
|
||||
import com.mogo.eagle.core.function.api.hmi.warning.IMoGoWarningStatusListener
|
||||
import com.mogo.eagle.core.function.api.trafficlight.IMoGoTrafficLightListener
|
||||
import com.mogo.eagle.core.function.call.hmi.CallerHmiManager
|
||||
import com.mogo.eagle.core.function.call.map.CallerMapLocationListenerManager
|
||||
import com.mogo.eagle.core.function.call.msgbox.CallerMsgBoxManager
|
||||
import com.mogo.eagle.core.function.call.trafficlight.CallerTrafficLightListenerManager
|
||||
import com.mogo.eagle.core.function.call.vip.CallVipSetListenerManager
|
||||
import com.mogo.eagle.core.function.v2x.trafficlight.core.MogoTrafficLightManager
|
||||
import com.mogo.eagle.core.function.v2x.vip.network.VipNetWorkModel
|
||||
import com.mogo.eagle.core.utilcode.mogo.logger.CallerLogger
|
||||
import com.mogo.eagle.core.utilcode.mogo.logger.scene.SceneConstant.Companion.M_V2X
|
||||
import com.mogo.eagle.core.utilcode.util.ToastUtils
|
||||
import com.mogo.eagle.core.utilcode.util.UiThreadHandler
|
||||
import com.zhjt.service_biz.BizConfig
|
||||
|
||||
class VipCarManager : IMogoOnMessageListener<VipMessage>, IMoGoTrafficLightListener,
|
||||
Handler.Callback {
|
||||
|
||||
companion object {
|
||||
|
||||
const val TAG = "VipCarManager"
|
||||
private const val MSG_WHAT_VIP_SEARCH = 1
|
||||
private const val MSG_WHAT_VIP_CANCEL = 2
|
||||
|
||||
val INSTANCE: VipCarManager by lazy(mode = LazyThreadSafetyMode.SYNCHRONIZED) {
|
||||
VipCarManager()
|
||||
}
|
||||
}
|
||||
|
||||
private var mContext: Context? = null
|
||||
private var turnLight = false
|
||||
private var vip: Boolean = false
|
||||
|
||||
@Volatile
|
||||
private var exit: Boolean = false
|
||||
|
||||
private var result: TrafficLightResult? = null
|
||||
|
||||
private val vipNetWorkModel = VipNetWorkModel()
|
||||
private val handler = Handler(Looper.getMainLooper(), this)
|
||||
|
||||
fun initServer(context: Context) {
|
||||
mContext = context
|
||||
MogoAiCloudSocketManager.getInstance(context)
|
||||
.registerOnMessageListener(401025, this)
|
||||
|
||||
//首次进入应用查询是否为VIP车辆
|
||||
requestVip()
|
||||
}
|
||||
|
||||
override fun handleMessage(msg: Message): Boolean {
|
||||
when (msg.what) {
|
||||
MSG_WHAT_VIP_SEARCH -> {
|
||||
requestVip()
|
||||
}
|
||||
MSG_WHAT_VIP_CANCEL -> {
|
||||
cancelVip()
|
||||
}
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
override fun target(): Class<VipMessage> {
|
||||
return VipMessage::class.java
|
||||
}
|
||||
|
||||
@BizConfig(V2N, "", BIZ_VIP)
|
||||
override fun onMsgReceived(vipMessage: VipMessage?) {
|
||||
CallerLogger.d("$M_V2X$TAG", "onMsgReceived vipMessage : ${vipMessage.toString()}")
|
||||
vipMessage?.let {
|
||||
when (it.vipType) {
|
||||
0 -> { //取消VIP
|
||||
cancelVip()
|
||||
}
|
||||
1 -> { //设置VIP
|
||||
CallerLogger.d(
|
||||
"$M_V2X$TAG",
|
||||
"设置handler超时时间 " + ", time : ${System.currentTimeMillis() - vipMessage.timeOut}"
|
||||
)
|
||||
setVip(vipMessage.timeOut)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override fun onTrafficLightStatus(trafficLightResult: TrafficLightResult) {
|
||||
if (!vip) {
|
||||
return
|
||||
}
|
||||
|
||||
if (exit) {
|
||||
CallerLogger.d("$M_V2X$TAG", "驶离路口,返回 , then resetConditions")
|
||||
resetConditions()
|
||||
exit = false
|
||||
return
|
||||
}
|
||||
|
||||
if (trafficLightResult.currentRoadTrafficLight() == null) {
|
||||
CallerLogger.d(
|
||||
"$M_V2X$TAG",
|
||||
"vip 获取到灯态,但没找到对应车道数据 trafficLightResult : $trafficLightResult , then resetConditions"
|
||||
)
|
||||
resetConditions()
|
||||
return
|
||||
}
|
||||
|
||||
val currentResult = trafficLightResult.currentRoadTrafficLight()
|
||||
val lastResult = result?.currentRoadTrafficLight()
|
||||
CallerLogger.d(
|
||||
"$M_V2X$TAG",
|
||||
"检查是否变灯 last.remain : ${lastResult?.remain} , color : ${lastResult?.color} , current.remain : ${currentResult?.remain} , color : ${currentResult?.color}, turnLight : $turnLight"
|
||||
)
|
||||
|
||||
this.result = trafficLightResult
|
||||
|
||||
if (!turnLight) {
|
||||
// 首次判断,变灯
|
||||
turnLight = true
|
||||
val controlTime = if (currentResult!!.isGreen()) 45 - currentResult.remain else 45
|
||||
CallerLogger.d("$M_V2X$TAG", "触发变灯 , controlTime : $controlTime")
|
||||
turnLight(controlTime)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private fun resetConditions() {
|
||||
turnLight = false
|
||||
result = null
|
||||
}
|
||||
|
||||
@BizConfig(V2N, "", BIZ_VIP)
|
||||
private fun setVip(cancelDelayTime: Long) {
|
||||
vip = true
|
||||
handler.sendEmptyMessageDelayed(
|
||||
MSG_WHAT_VIP_CANCEL,
|
||||
cancelDelayTime - System.currentTimeMillis()
|
||||
)
|
||||
CallerHmiManager.vipIdentification(true)
|
||||
CallVipSetListenerManager.invokeVipSetStatus(true)
|
||||
CallerTrafficLightListenerManager.addListener(TAG, this)
|
||||
}
|
||||
|
||||
private fun cancelVip() {
|
||||
vip = false
|
||||
if (handler.hasMessages(MSG_WHAT_VIP_CANCEL)) {
|
||||
handler.removeMessages(MSG_WHAT_VIP_CANCEL)
|
||||
}
|
||||
resetConditions()
|
||||
CallerHmiManager.vipIdentification(false)
|
||||
CallVipSetListenerManager.invokeVipSetStatus(false)
|
||||
CallerTrafficLightListenerManager.removeListener(TAG)
|
||||
}
|
||||
|
||||
private fun requestVip() {
|
||||
vipNetWorkModel.requestVip({
|
||||
if (handler.hasMessages(MSG_WHAT_VIP_SEARCH)) {
|
||||
handler.removeMessages(MSG_WHAT_VIP_SEARCH)
|
||||
}
|
||||
if (it.vipStatus) {
|
||||
setVip(it.cancelDelayTime)
|
||||
} else {
|
||||
cancelVip()
|
||||
}
|
||||
}, {
|
||||
CallerLogger.e("$M_V2X$TAG", "获取VIP信息失败, 准备间隔5秒重新获取")
|
||||
handler.sendEmptyMessageDelayed(MSG_WHAT_VIP_SEARCH, 5_000L)
|
||||
})
|
||||
}
|
||||
|
||||
override fun onEnterCrossRoad(enter: Boolean) {
|
||||
super.onEnterCrossRoad(enter)
|
||||
UiThreadHandler.post {
|
||||
this.exit = !enter
|
||||
}
|
||||
}
|
||||
|
||||
fun turnLight(controlTime: Int) {
|
||||
if (result == null || mContext == null) return
|
||||
val mogoLocation = CallerMapLocationListenerManager.getCurrentLocation()
|
||||
if (mogoLocation != null) {
|
||||
val bearing = mogoLocation.bearing.toDouble()
|
||||
CallerLogger.d("$M_V2X$TAG", "-- turnLight -- ")
|
||||
MogoTrafficLightManager.INSTANCE.turnLightToGreen(
|
||||
result!!.lightId, result!!.crossId, bearing, controlTime,
|
||||
// 100445, "10037", 90.0, controlTime, //衡阳25号路口测试数据
|
||||
{
|
||||
// 请求变灯成功,直接提示
|
||||
if (it.sn == MoGoAiCloudClientConfig.getInstance().sn && it.code == 0) {
|
||||
CallerLogger.d("$M_V2X$TAG", "变灯请求成功")
|
||||
val light = this.result?.currentRoadTrafficLight()
|
||||
if (light != null && light.isGreen()) {
|
||||
showWarning(
|
||||
EventTypeEnum.TYPE_VIP_IDENTIFICATION_EXTEND.poiType,
|
||||
EventTypeEnum.TYPE_VIP_IDENTIFICATION_EXTEND.content,
|
||||
EventTypeEnum.TYPE_VIP_IDENTIFICATION_EXTEND.tts,
|
||||
EventTypeEnum.TYPE_VIP_IDENTIFICATION_EXTEND.poiType
|
||||
)
|
||||
} else {
|
||||
showWarning(
|
||||
EventTypeEnum.TYPE_VIP_IDENTIFICATION_PASS.poiType,
|
||||
EventTypeEnum.TYPE_VIP_IDENTIFICATION_PASS.content,
|
||||
EventTypeEnum.TYPE_VIP_IDENTIFICATION_PASS.tts,
|
||||
EventTypeEnum.TYPE_VIP_IDENTIFICATION_PASS.poiType
|
||||
)
|
||||
}
|
||||
return@turnLightToGreen
|
||||
}
|
||||
|
||||
// 请求变灯失败,根据灯态来提示。 此处灯态未获取到
|
||||
if (this.result == null || this.result?.currentRoadTrafficLight() == null) {
|
||||
showWarning(
|
||||
EventTypeEnum.TYPE_VIP_ERROR_IDENTIFICATION.poiType,
|
||||
EventTypeEnum.TYPE_VIP_ERROR_IDENTIFICATION.content + ", 稍后重试",
|
||||
EventTypeEnum.TYPE_VIP_ERROR_IDENTIFICATION.tts,
|
||||
EventTypeEnum.TYPE_VIP_ERROR_IDENTIFICATION.poiType
|
||||
)
|
||||
return@turnLightToGreen
|
||||
}
|
||||
|
||||
// 如果当前为红灯,则提示
|
||||
if (this.result!!.currentRoadTrafficLight()!!.isRed()) {
|
||||
val time = if (it.countDown / 60 >= 1) {
|
||||
"${it.countDown / 60}分${it.countDown % 60}秒后重试"
|
||||
} else {
|
||||
val temp = if (it.countDown == 0) {
|
||||
1
|
||||
} else {
|
||||
it.countDown
|
||||
}
|
||||
"${temp}秒后重试"
|
||||
}
|
||||
showWarning(
|
||||
EventTypeEnum.TYPE_VIP_ERROR_IDENTIFICATION.poiType,
|
||||
EventTypeEnum.TYPE_VIP_ERROR_IDENTIFICATION.content + time,
|
||||
EventTypeEnum.TYPE_VIP_ERROR_IDENTIFICATION.tts,
|
||||
EventTypeEnum.TYPE_VIP_ERROR_IDENTIFICATION.poiType
|
||||
)
|
||||
} else {
|
||||
CallerLogger.d(
|
||||
"$M_V2X$TAG",
|
||||
"变灯请求失败,当前为非红灯不做展示 , light : ${result.toString()} , trafficLightControl : $it"
|
||||
)
|
||||
}
|
||||
},
|
||||
{ errorMsg ->
|
||||
CallerLogger.e("$M_V2X$TAG", "变灯请求失败 msg : $errorMsg")
|
||||
ToastUtils.showLong("服务异常,请稍后重试")
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
private fun showWarning(
|
||||
v2xType: String,
|
||||
alertContent: CharSequence,
|
||||
ttsContent: String,
|
||||
tag: String
|
||||
) {
|
||||
if (alertContent.toString().isEmpty() || ttsContent.isEmpty()) {
|
||||
Log.d("MsgBox-VipCarManager", "alertContent或ttsContent为空!")
|
||||
}
|
||||
CallerMsgBoxManager.saveMsgBox(
|
||||
MsgBoxBean(MsgBoxType.V2X, V2XMsg(v2xType, alertContent.toString(), ttsContent))
|
||||
)
|
||||
CallerHmiManager.warningV2X(
|
||||
v2xType, alertContent, ttsContent, tag,
|
||||
object : IMoGoWarningStatusListener {
|
||||
override fun onShow() {}
|
||||
override fun onDismiss() {}
|
||||
},
|
||||
true,
|
||||
5000L
|
||||
)
|
||||
}
|
||||
|
||||
fun destroy() {
|
||||
MogoAiCloudSocketManager.getInstance(mContext)
|
||||
.unregisterLifecycleListener(401025)
|
||||
mContext = null
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,13 +0,0 @@
|
||||
package com.mogo.eagle.core.function.v2x.vip.network
|
||||
|
||||
import com.mogo.eagle.core.data.BaseResponse
|
||||
import com.mogo.eagle.core.data.v2x.VipRequest
|
||||
import retrofit2.http.*
|
||||
|
||||
interface VipApiService {
|
||||
|
||||
//查询是否为VIP车辆
|
||||
@GET("/dataService/carUser/getVipStatusBySn")
|
||||
suspend fun requestVip(@Query("sn") sn: String): BaseResponse<VipRequest>
|
||||
|
||||
}
|
||||
@@ -1,41 +0,0 @@
|
||||
package com.mogo.eagle.core.function.v2x.vip.network
|
||||
|
||||
import com.mogo.cloud.passport.MoGoAiCloudClientConfig
|
||||
import com.mogo.eagle.core.data.BaseResponse
|
||||
import com.mogo.eagle.core.data.v2x.VipRequest
|
||||
import com.mogo.eagle.core.network.MoGoRetrofitFactory
|
||||
import com.mogo.eagle.core.network.apiCall
|
||||
import com.mogo.eagle.core.network.request
|
||||
import com.mogo.commons.constants.HostConst.DATA_SERVICE_HOST
|
||||
|
||||
|
||||
class VipNetWorkModel {
|
||||
|
||||
private fun getNetWorkApi(baseUrl: String = DATA_SERVICE_HOST): VipApiService {
|
||||
return MoGoRetrofitFactory.getInstanceNoCallAdapter(baseUrl)
|
||||
.create(VipApiService::class.java)
|
||||
}
|
||||
|
||||
fun requestVip(onSuccess: ((VipRequest) -> Unit), onError: ((String) -> Unit)) {
|
||||
request<BaseResponse<VipRequest>> {
|
||||
loader {
|
||||
apiCall {
|
||||
getNetWorkApi().requestVip(MoGoAiCloudClientConfig.getInstance().sn)
|
||||
}
|
||||
}
|
||||
onSuccess {
|
||||
if (it.result != null) {
|
||||
onSuccess.invoke(it.result)
|
||||
} else {
|
||||
onError.invoke("requestRoadID result is null")
|
||||
}
|
||||
}
|
||||
onError {
|
||||
if (it.message != null) {
|
||||
onError.invoke(it.message!!)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user