[fea]
[Vlm 接入]
This commit is contained in:
yangyakun
2025-06-20 11:24:27 +08:00
parent 05582f4415
commit 981d2e7f24
29 changed files with 514 additions and 179 deletions

View File

@@ -10,10 +10,14 @@ import com.mogo.eagle.core.utilcode.util.CoordinateUtils
import com.mogo.och.bridge.autopilot.location.OchLocationManager
import com.mogo.och.bridge.distance.TrajectoryAndDistanceManager
import com.mogo.och.bridge.bridge.OchBridgeManager
import com.mogo.och.bridge.bridge.OchVlmManager
import com.mogo.och.bridge.trajectory.TrajectoryManager
import com.mogo.och.common.module.biz.birdge.BridgeService
import com.mogo.och.common.module.biz.birdge.BridgeListener
import com.mogo.och.common.module.biz.birdge.data.RoadMsg
import com.mogo.och.common.module.biz.birdge.data.VlmData
import com.mogo.och.common.module.constant.OchCommonConst
import com.mogo.och.common.module.manager.EnvManager
/**
@@ -29,7 +33,16 @@ class BridgeProvider : BridgeService, CallerBase<BridgeListener>() {
override fun init(context: Context?) {
this.context = context
OchBridgeManager.load()
// 车前引导线+预测数据
if(EnvManager.isB2Passenger()||EnvManager.isT1T2Passenger()){
OchBridgeManager.load()
}
// if(EnvManager.isT1T2Passenger()){
OchVlmManager.load()
// }
TrajectoryManager.load()
}
@@ -92,5 +105,17 @@ class BridgeProvider : BridgeService, CallerBase<BridgeListener>() {
}
}
fun invokeVlmDataDispatch(vlmData:VlmData){
M_LISTENERS.forEach {
it.value.onVlmDataListener(vlmData)
}
}
fun inVokeNdeData(title: String, desc: String, sortedList: List<RoadMsg>) {
M_LISTENERS.forEach {
it.value.onNdeDataListener(title,desc,sortedList)
}
}
}

View File

@@ -3,13 +3,10 @@ package com.mogo.och.bridge
import android.annotation.SuppressLint
import com.alibaba.android.arouter.launcher.ARouter
import com.mogo.eagle.core.data.map.MogoLocation
import com.mogo.eagle.core.utilcode.mogo.logger.CallerLogger
import com.mogo.eagle.core.utilcode.mogo.logger.scene.SceneConstant.Companion.M_OCHCOMMON
import com.mogo.och.common.module.biz.birdge.data.RoadMsg
import com.mogo.och.common.module.biz.birdge.data.VlmData
import com.mogo.och.common.module.constant.OchCommonConst
import com.mogo.och.common.module.manager.loop.BizLoopManager
import com.mogo.och.common.module.manager.loop.LoopInfo
import io.reactivex.schedulers.Schedulers
import kotlin.properties.Delegates
object BridgeServiceManager {
@@ -19,52 +16,12 @@ object BridgeServiceManager {
private var bridgeService: BridgeProvider? =
ARouter.getInstance().build(OchCommonConst.BIZ_Bridge).navigation() as BridgeProvider
private var trajectoryTime = 0L
private var predictionTime = 0L
init {
BizLoopManager.setLoopFunction(TAG,
LoopInfo(2, ::checkTimeout, immediately = false, scheduler = Schedulers.io())
)
}
// 是否有车前引导线
private var haveTrajectoryInfo: Boolean by Delegates.observable(false) { _, oldValue, newValue ->
if (oldValue != newValue) {
bridgeService?.invokeTrajectoryHaveDataListener(newValue)
CallerLogger.d(TAG,"haveTrajectoryInfo 发生变化:${newValue}")
}
trajectoryTime = System.currentTimeMillis()
}
// 是否有预测数据
private var havePredictionInfo: Boolean by Delegates.observable(false) { _, oldValue, newValue ->
if (oldValue != newValue) {
bridgeService?.invokePredictionHavaData(newValue)
CallerLogger.d(TAG,"havePredictionInfo 发生变化:${newValue}")
}
predictionTime = System.currentTimeMillis()
}
fun checkTimeout(){
if(System.currentTimeMillis() - trajectoryTime>2_000){
haveTrajectoryInfo = false
CallerLogger.d(TAG,"超时设置为falsehaveTrajectoryInfo ${haveTrajectoryInfo}")
}
if(System.currentTimeMillis() - predictionTime>2_000){
havePredictionInfo = false
CallerLogger.d(TAG,"超时设置为falsehavePredictionInfo ${havePredictionInfo}")
}
}
fun invokePlanningListener(haveTrajectoryInfos:Boolean){
this.haveTrajectoryInfo = haveTrajectoryInfos
bridgeService?.invokeTrajectoryHaveDataListener(haveTrajectoryInfos)
}
fun invokePredictionHaveData(havePredictionInfos:Boolean){
this.havePredictionInfo = havePredictionInfos
bridgeService?.invokePredictionHavaData(havePredictionInfos)
}
fun invokeTrajectoryPoints(trajectoryList: MutableList<MogoLocation>){
@@ -78,4 +35,15 @@ object BridgeServiceManager {
this.bridgeService?.invokeTrajectoryPointAndDistance(trajectoryList, distance)
}
/**
* 分发vmData
*/
fun invokeVlmData(vlmData: VlmData){
this.bridgeService?.invokeVlmDataDispatch(vlmData)
}
fun invokeNdeData(title: String, desc: String, sortedList: List<RoadMsg>) {
this.bridgeService?.inVokeNdeData(title,desc,sortedList)
}
}

View File

@@ -0,0 +1,42 @@
package com.mogo.och.bridge.bridge
data class VlmImageData(val imageSourceTimestamp: Double ,var image: ByteArray?) {
override fun equals(other: Any?): Boolean {
if (this === other) return true
if (javaClass != other?.javaClass) return false
other as VlmImageData
return imageSourceTimestamp == other.imageSourceTimestamp
}
override fun hashCode(): Int {
return imageSourceTimestamp.hashCode()
}
override fun toString(): String {
return "VlmImageData(imageSourceTimestamp=$imageSourceTimestamp)"
}
}
data class VlmMessageData(val messageSourceTimestamp: Double ,val id:Int?,val message:String?){
override fun equals(other: Any?): Boolean {
if (this === other) return true
if (javaClass != other?.javaClass) return false
other as VlmMessageData
// if (messageSourceTimestamp != other.messageSourceTimestamp) return false
if (id != other.id) return false
return true
}
override fun hashCode(): Int {
var result = messageSourceTimestamp.hashCode()
result = 31 * result + (id ?: 0)
return result
}
}

View File

@@ -4,24 +4,62 @@ import com.mogo.eagle.core.function.api.autopilot.IMoGoAutopilotIdentifyListener
import com.mogo.eagle.core.function.api.autopilot.IMoGoPlanningTrajectoryListener
import com.mogo.eagle.core.function.call.autopilot.CallerAutopilotIdentifyListenerManager
import com.mogo.eagle.core.function.call.autopilot.CallerPlanningTrajectoryListenerManager
import com.mogo.eagle.core.function.call.base.CallerBase
import com.mogo.eagle.core.utilcode.mogo.logger.CallerLogger
import com.mogo.eagle.core.utilcode.mogo.logger.scene.SceneConstant.Companion.M_OCHCOMMON
import com.mogo.och.bridge.BridgeServiceManager
import com.mogo.och.common.module.manager.loop.BizLoopManager
import com.mogo.och.common.module.manager.loop.LoopInfo
import io.reactivex.schedulers.Schedulers
import prediction2025.Prediction2025
import mogo.telematics.pad.MessagePad
import kotlin.properties.Delegates
object OchBridgeManager: CallerBase<IMoGoPlanningTrajectoryListener>(),
IMoGoPlanningTrajectoryListener, IMoGoAutopilotIdentifyListener {
object OchBridgeManager: IMoGoPlanningTrajectoryListener, IMoGoAutopilotIdentifyListener {
private val TAG = "${M_OCHCOMMON}OchPlanningListenerManager"
private var trajectoryTime = 0L
private var predictionTime = 0L
fun load(){
CallerPlanningTrajectoryListenerManager.addListener(TAG,this)
CallerAutopilotIdentifyListenerManager.addListener(TAG,this)
BizLoopManager.setLoopFunction(TAG, LoopInfo(2, ::checkTimeout, immediately = false, scheduler = Schedulers.io()))
}
fun release(){
CallerPlanningTrajectoryListenerManager.removeListener(TAG)
CallerAutopilotIdentifyListenerManager.removeListener(TAG)
}
// 是否有车前引导线
private var haveTrajectoryInfo: Boolean by Delegates.observable(false) { _, oldValue, newValue ->
if (oldValue != newValue) {
BridgeServiceManager.invokePlanningListener(newValue)
CallerLogger.d(TAG,"haveTrajectoryInfo 发生变化:${newValue}")
}
trajectoryTime = System.currentTimeMillis()
}
// 是否有预测数据
private var havePredictionInfo: Boolean by Delegates.observable(false) { _, oldValue, newValue ->
if (oldValue != newValue) {
BridgeServiceManager.invokePredictionHaveData(newValue)
CallerLogger.d(TAG,"havePredictionInfo 发生变化:${newValue}")
}
predictionTime = System.currentTimeMillis()
}
fun checkTimeout(){
if(System.currentTimeMillis() - trajectoryTime>2_000){
haveTrajectoryInfo = false
CallerLogger.d(TAG,"超时设置为falsehaveTrajectoryInfo $haveTrajectoryInfo")
}
if(System.currentTimeMillis() - predictionTime>2_000){
havePredictionInfo = false
CallerLogger.d(TAG,"超时设置为falsehavePredictionInfo $havePredictionInfo")
}
}
/**
@@ -29,17 +67,20 @@ object OchBridgeManager: CallerBase<IMoGoPlanningTrajectoryListener>(),
*/
override fun onAutopilotTrajectory(trajectoryInfos: MutableList<MessagePad.TrajectoryPoint>) {
if(trajectoryInfos.isEmpty()){
BridgeServiceManager.invokePlanningListener(false)
haveTrajectoryInfo = false
}else{
BridgeServiceManager.invokePlanningListener(true)
haveTrajectoryInfo = true
}
}
/**
* 预测信息
*/
override fun onPredictionObstacleTrajectory(predictionObjects: Prediction2025.mPredictionObjects) {
if (predictionObjects.objsAppList==null) {
BridgeServiceManager.invokePredictionHaveData(false)
havePredictionInfo = false
}else{
BridgeServiceManager.invokePredictionHaveData(true)
havePredictionInfo = true
}
}

View File

@@ -0,0 +1,84 @@
package com.mogo.och.bridge.bridge
import com.mogo.eagle.core.function.api.autopilot.IMoGoAutopilotIdentifyListener
import com.mogo.eagle.core.function.call.autopilot.CallerAutopilotIdentifyListenerManager
import com.mogo.eagle.core.function.call.autopilot.CallerVlmManager
import com.mogo.eagle.core.utilcode.mogo.logger.scene.SceneConstant.Companion.M_OCHCOMMON
import com.mogo.och.bridge.BridgeServiceManager
import com.mogo.och.common.module.biz.birdge.data.RoadMsg
import mogo.telematics.pad.MessagePad.TrackedObject
object OchNdeManager : IMoGoAutopilotIdentifyListener {
private val TAG = "${M_OCHCOMMON}OchVlmManager"
fun load(){
CallerAutopilotIdentifyListenerManager.addListener(TAG, this)
}
fun release(){
CallerVlmManager.removeListener(TAG)
}
private var lastMap2 = HashMap<Int, String>()
private var lastTime = 0L
override fun onAutopilotIdentifyDataUpdate(trafficData: List<TrackedObject>?){
super.onAutopilotIdentifyDataUpdate(trafficData)
handleCheLong(trafficData)
}
private fun handleCheLong(trafficData: List<TrackedObject>?) {
var hasCheLong = false
var isNewData = false
val roadMsgList = ArrayList<RoadMsg>()
val curMap = HashMap<Int, String>()
if (lastTime > 0 && System.currentTimeMillis() - lastTime > 60000) {
lastMap2.clear()// 清除上次车龙事件的缓存
}
var lastLocStr: String? = ""
trafficData?.forEach { obj ->
if (obj.type == 707) {// 当前方向所有车道
if (obj.polygonCount > 1) {// 当次数据有车龙事件
lastLocStr = lastMap2[obj.laneNum]
// 1. 上次无车龙但此次有车龙,认为是新车龙事件
// 2. 两次都有车龙,则判断车龙的长度是否相同
if (lastLocStr == null || lastLocStr == "0" || lastLocStr != "${obj.polygonList[0]}-${obj.polygonList[obj.polygonCount - 1]}") {
isNewData = true
}
hasCheLong = true
// key: 车道号value: 非0代表有车龙且首、尾两个点可计算车龙长度
curMap[obj.laneNum] =
"${obj.polygonList[0]}-${obj.polygonList[obj.polygonCount - 1]}"
} else {// 当次没有车龙
if (lastMap2[obj.laneNum] != null && lastMap2[obj.laneNum] != "0") {// 3. 上次有车龙,这次无车龙
isNewData = true
}
// key: 车道号value: 0代表无车龙
curMap[obj.laneNum] = "0"
}
// 保存所有车道信息
roadMsgList.add(RoadMsg(
obj.arrowType,
laneNum = obj.laneNum,
isRecommend = obj.suggestedLanes,
isCheLong = obj.polygonCount > 1
)
)
}
}
if (isNewData) {
// 清除上次车道信息
lastMap2.clear()
if (hasCheLong) {
// 缓存当次车龙事件所有车道信息
lastMap2.putAll(curMap)
lastTime = System.currentTimeMillis()
val sortedList = roadMsgList.sortedWith(compareByDescending { it.laneNum })
BridgeServiceManager.invokeNdeData("路口车龙","前方路口有车龙",sortedList)
}
}
}
}

View File

@@ -0,0 +1,58 @@
package com.mogo.och.bridge.bridge
import com.mogo.eagle.core.function.api.autopilot.IVlmListener
import com.mogo.eagle.core.function.call.autopilot.CallerVlmManager
import com.mogo.eagle.core.utilcode.mogo.logger.CallerLogger
import com.mogo.eagle.core.utilcode.mogo.logger.scene.SceneConstant.Companion.M_OCHCOMMON
import com.mogo.och.bridge.BridgeServiceManager
import com.mogo.och.common.module.biz.birdge.data.VlmData
import vllm.Vlm
import kotlin.properties.Delegates
object OchVlmManager : IVlmListener {
private val TAG = "${M_OCHCOMMON}OchVlmManager"
fun load(){
CallerVlmManager.addListener(TAG,this)
}
fun release(){
CallerVlmManager.removeListener(TAG)
}
//
private var vllmImageData: VlmImageData by Delegates.observable(VlmImageData(0.0,null)) { _, oldValue, newValue ->
if (oldValue != newValue) {
if(newValue.imageSourceTimestamp == vllmData.messageSourceTimestamp){
CallerLogger.d(TAG," message先来 图片后来 发送message和图片 ${newValue.imageSourceTimestamp}---${vllmData.messageSourceTimestamp}")
BridgeServiceManager.invokeVlmData(VlmData(vllmData.id,vllmData.message,newValue.image))
}
}
}
private var vllmData: VlmMessageData by Delegates.observable(VlmMessageData(0.0,0,"")) { _, oldValue, newValue ->
if (oldValue != newValue) {
if(newValue.messageSourceTimestamp== vllmImageData.imageSourceTimestamp){
// 图片先来 发送message和图片
BridgeServiceManager.invokeVlmData(VlmData(newValue.id,newValue.message,
vllmImageData.image)
)
CallerLogger.d(TAG,"messsage后来 图片先来 发送message和图片 ${newValue.message}----${newValue.messageSourceTimestamp}---${newValue.id}")
}else{
// message 先来 单独发送message 图片来了后 再次发送出去
BridgeServiceManager.invokeVlmData(VlmData(newValue.id,newValue.message,null))
CallerLogger.d(TAG,"message先来 图片后来 发送message ${newValue.message}---${newValue.messageSourceTimestamp}---${newValue.id}")
}
}
}
override fun onVllm(sourceTimestamp: Double, vllm: Vlm.VLLMObject) {
if(this.vllmData.id!=vllm.workZone.id){
this.vllmData = VlmMessageData(sourceTimestamp,vllm.workZone.id,vllm.workZone.sceneExplantion)
}
}
override fun onVllmImage(sourceTimestamp: Double, image: ByteArray) {
this.vllmImageData = VlmImageData(sourceTimestamp,image)
}
}