修改绘制感知数据方式为批量更新数据,尝试解决绘制卡顿的问题

Signed-off-by: donghongyu <donghongyu@zhidaoauto.com>
This commit is contained in:
donghongyu
2022-01-12 17:57:36 +08:00
parent 351bda6e8a
commit 2856494644
10 changed files with 250 additions and 192 deletions

View File

@@ -1,46 +1,42 @@
package com.mogo.module.common.drawer;
import static com.mogo.cloud.socket.entity.SocketDownDataHelper.FROM_ADAS;
import android.content.Context;
import android.text.TextUtils;
import com.mogo.commons.AbsMogoApplication;
import com.mogo.commons.debug.DebugConfig;
import com.mogo.eagle.core.data.map.MogoLatLng;
import com.mogo.eagle.core.data.enums.TrafficTypeEnum;
import com.mogo.eagle.core.data.traffic.TrafficData;
import com.mogo.map.marker.IMogoMarker;
import com.mogo.map.marker.MogoMarkerOptions;
import com.mogo.module.common.MogoApisHandler;
import com.mogo.module.common.constants.AdasRecognizedType;
import com.mogo.module.common.constants.DataTypes;
import com.mogo.utils.logger.Logger;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.TimeUnit;
/**
* @author xiaoyuzhou
* @date 2021/10/19 10:45 上午
* 域控制器识别信息绘制
*/
public class IdentifyDataDrawer extends BaseDrawer {
public class IdentifyDataDrawer {
private static final String TAG = "IdentifyDataDrawer";
protected final Context mContext;
private static volatile IdentifyDataDrawer sInstance;
/**
* 上一帧数据的缓存
*/
private static Map<String, IMogoMarker> mMarkersCaches = new ConcurrentHashMap<>();
private static ConcurrentHashMap<String, TrafficData> mMarkersCaches = new ConcurrentHashMap<>();
/**
* 最后一帧数据的缓存
* 已经感知不到的脏数据
*/
private final Map<String, TrafficData> mLastPositions = new ConcurrentHashMap<>();
private final ConcurrentHashMap<String, TrafficData> mDirtyPositions = new ConcurrentHashMap<>();
private IdentifyDataDrawer() {
super();
mContext = AbsMogoApplication.getApp();
addPreVehicleModel();
}
public static IdentifyDataDrawer getInstance() {
@@ -63,8 +59,7 @@ public class IdentifyDataDrawer extends BaseDrawer {
*
* @param resultList adas感知融合数据
*/
public void renderAdasRecognizedResult(List<TrafficData> resultList) {
final long start = System.nanoTime();
public void renderAdasRecognizedResult(ArrayList<TrafficData> resultList) {
if (resultList == null || resultList.isEmpty() || !DebugConfig.isUseAdasRecognize()) {
clearOldMarker();
return;
@@ -76,95 +71,33 @@ public class IdentifyDataDrawer extends BaseDrawer {
return;
}
Map<String, IMogoMarker> newAdasRecognizedMarkersCaches = new ConcurrentHashMap<>();
List<TrafficData> newDiffSet = new ArrayList<>();
for (TrafficData recognizedListResult : resultList) {
// 循环将集合中的数据提取记录
ArrayList<String> trafficDataUuidList = new ArrayList<>();
for (TrafficData trafficData : resultList) {
trafficDataUuidList.add(trafficData.getUuid());
}
if (isUselessValue(recognizedListResult)) {
continue;
}
if (AdasRecognizedType.valueFrom(recognizedListResult.getType().getType()) == AdasRecognizedType.classIdUnKnow) {
continue;
}
// 复用之前存在的 marker
String uniqueKey = recognizedListResult.getUuid();
IMogoMarker marker = mMarkersCaches.remove(uniqueKey);
if (marker != null && !marker.isDestroyed()) {
//Log.d(TAG, "发现缓存marker id : " + uniqueKey);
updateCacheMarkerRes(marker, recognizedListResult);
renderAdasOneFrame(marker, uniqueKey, recognizedListResult, newAdasRecognizedMarkersCaches);
} else {
// 新增添加进差集
newDiffSet.add(recognizedListResult);
// 找出上一针数据中已经不在本次数据中存在的数据
for (String uuid : mMarkersCaches.keySet()) {
if (!trafficDataUuidList.contains(uuid)) {
mDirtyPositions.put(uuid, mMarkersCaches.get(uuid));
}
}
removeUselessMarker(mMarkersCaches);
removeUselessLastRecord();
int newDiffSetSize = newDiffSet.size();
// Log.d(TAG, "原数据量 " + resultList.size() + " 新增marker数量 " + newDiffSetSize);
// 复用过期 marker
if (newDiffSetSize > 0) {
for (int i = 0; i < newDiffSetSize; i++) {
TrafficData recognizedListResult = newDiffSet.get(i);
if (AdasRecognizedType.valueFrom(recognizedListResult.getType().getType()) == AdasRecognizedType.classIdUnKnow) {
continue;
}
String uniqueKey = recognizedListResult.getUuid();
IMogoMarker marker = drawAdasRecognizedDataMarker(recognizedListResult);
if (marker == null) {
continue;
}
//Log.d(TAG, "新增marker id : " + uniqueKey);
renderAdasOneFrame(marker, uniqueKey, recognizedListResult, newAdasRecognizedMarkersCaches);
}
}
mMarkersCaches.clear();
mMarkersCaches = newAdasRecognizedMarkersCaches;
// Log.d(TAG, "ADAS数据延时绘制 render 接收数据 -> 处理结束 " + TimeUnit.NANOSECONDS.toMillis((System.nanoTime() - start)) + "ms");
}
/**
* todo 后面涉及到此类变化的数据均改动
* 更新缓存Marker的资源
*
* @param marker
* @param recognizedListResult
*/
private void updateCacheMarkerRes(IMogoMarker marker, TrafficData recognizedListResult) {
// 获取3D资源文件
int resId = getModelRes(recognizedListResult.getType().getType());
String resIdVal = resId + "";
// 查询缓存中是否存在
String resName = mMarkerCachesResMd5Values.get(resIdVal);
// 缓存存在直接试用,节省内存
if (!TextUtils.isEmpty(resName)) {
if (!TextUtils.equals(resName, marker.getMarkerResName())) {
marker.use3DResource(resName);
}
} else {
// 缓存不存在,取出名称进行缓存
resName = marker.use3DResource(resId);
mMarkerCachesResMd5Values.put(resIdVal, resName);
}
}
// // 移除脏数据
// for (String uuid : mDirtyPositions.keySet()) {
// MogoApisHandler.getInstance().getApis()
// .getMapServiceApi()
// .getMarkerManager(mContext)
// .removeMarker(uuid);
// }
// 绘制新数据
MogoApisHandler.getInstance().getApis()
.getMapServiceApi()
.getMarkerManager(mContext)
.updateBatchMarkerPosition(resultList);
/**
* // todo 最好重新设计一个数据结构用于多线程数据过期失效的场景参见redis数据过期
* 移除工控机长时间没有下发的数据
*/
private void removeUselessLastRecord() {
if (mLastPositions.isEmpty()) {
return;
}
Iterator<TrafficData> iterator = mLastPositions.values().iterator();
// Log.d(TAG, "EmArrow removeUselessLastRecord size : " + mLastPositions.size());
while (iterator.hasNext()) {
TrafficData result = iterator.next();
long internal = result.getSatelliteTime() - getCurSatelliteTime();
if (internal > 3000) { //防止帧率过低导致误删除上一个节点对象,从而出现跳跃现象
iterator.remove();
}
}
}
/**
@@ -177,74 +110,10 @@ public class IdentifyDataDrawer extends BaseDrawer {
if (recognizedListResult == null) {
return true;
}
if (nonRenderType(recognizedListResult.getType().getType())) {
return true;
}
String uniqueKey = recognizedListResult.getUuid();
return TextUtils.isEmpty(uniqueKey);
}
/**
* 绘制某个物体的一个数据
*
* @param recognizedListResult {@link TrafficData}
* @param newAdasRecognizedMarkersCaches 缓存集合
*/
private void renderAdasOneFrame(IMogoMarker marker,
String uniqueKey,
TrafficData recognizedListResult,
Map<String, IMogoMarker> newAdasRecognizedMarkersCaches) {
final long start = System.nanoTime();
TrafficData lastPosition = mLastPositions.remove(uniqueKey);
mLastPositions.put(uniqueKey, recognizedListResult);
long interval = 45;
if (lastPosition != null) {
interval = computeAnimDuration(lastPosition.getSatelliteTime(), recognizedListResult.getSatelliteTime());
}
final MogoLatLng renderLoc = new MogoLatLng(recognizedListResult.getLat(), recognizedListResult.getLon());
long cost = TimeUnit.NANOSECONDS.toMillis(System.nanoTime() - start);
//Log.d(TAG, "ADAS动画数据 cost : " + cost);
final long intervalRef = interval - cost;
//Log.d(TAG, "ADAS动画数据 最终赋值 : " + intervalRef + " 两帧间隔 : " + interval + " uuid : " + recognizedListResult.getUuid());
marker.addDynamicAnchorPosition(renderLoc, (float) recognizedListResult.getHeading(), intervalRef);
String carColor = getModelRenderColor(recognizedListResult.getType().getType(), FROM_ADAS, recognizedListResult.getThreatLevel());
marker.setAnchorColor(carColor);
newAdasRecognizedMarkersCaches.put(uniqueKey, marker);
}
/**
* 创建一个新 marker
*
* @param recognizedListResult {@link TrafficData}
* @return {@link IMogoMarker}
*/
private IMogoMarker drawAdasRecognizedDataMarker(TrafficData recognizedListResult) {
if (recognizedListResult == null) {
return null;
}
int resId = getModelRes(recognizedListResult.getType().getType());
String resIdVal = resId + "";
String carColor = getModelRenderColor(recognizedListResult.getType().getType(), FROM_ADAS, recognizedListResult.getThreatLevel());
MogoMarkerOptions options = new MogoMarkerOptions()
.owner(DataTypes.TYPE_MARKER_ADAS)
.anchor(0.5f, 0.5f)
.set3DMode(true)
.gps(true)
.anchorColor(carColor)
.controlAngle(true)
.resName(mMarkerCachesResMd5Values.get(resIdVal))
.icon3DRes(resId)
.rotate((float) recognizedListResult.getHeading())
.position(new MogoLatLng(recognizedListResult.getLat(), recognizedListResult.getLon()));
IMogoMarker marker = MogoApisHandler.getInstance().getApis().getMapServiceApi().getMarkerManager(mContext).addMarker(DataTypes.TYPE_MARKER_ADAS, options);
cacheMarkerIconResMd5Val(resIdVal, marker);
return marker;
}
/**
* 清除旧的 marker 数据
*/
@@ -252,6 +121,45 @@ public class IdentifyDataDrawer extends BaseDrawer {
if (mMarkersCaches != null) {
mMarkersCaches.clear();
}
mLastPositions.clear();
}
private void addPreVehicleModel() {
MogoApisHandler.getInstance().getApis()
.getMapServiceApi()
.getMarkerManager(mContext)
.addPreVehicleModel(TrafficTypeEnum.TYPE_TRAFFIC_ID_WEI_ZHI.getType(),
TrafficTypeEnum.TYPE_TRAFFIC_ID_WEI_ZHI.getTraffic3DIconId());
MogoApisHandler.getInstance().getApis()
.getMapServiceApi()
.getMarkerManager(mContext)
.addPreVehicleModel(TrafficTypeEnum.TYPE_TRAFFIC_ID_PEOPLE.getType(),
TrafficTypeEnum.TYPE_TRAFFIC_ID_PEOPLE.getTraffic3DIconId());
MogoApisHandler.getInstance().getApis()
.getMapServiceApi()
.getMarkerManager(mContext)
.addPreVehicleModel(TrafficTypeEnum.TYPE_TRAFFIC_ID_BICYCLE.getType(),
TrafficTypeEnum.TYPE_TRAFFIC_ID_BICYCLE.getTraffic3DIconId());
MogoApisHandler.getInstance().getApis()
.getMapServiceApi()
.getMarkerManager(mContext)
.addPreVehicleModel(TrafficTypeEnum.TYPE_TRAFFIC_ID_TA_CHE.getType(),
TrafficTypeEnum.TYPE_TRAFFIC_ID_TA_CHE.getTraffic3DIconId());
MogoApisHandler.getInstance().getApis()
.getMapServiceApi()
.getMarkerManager(mContext)
.addPreVehicleModel(TrafficTypeEnum.TYPE_TRAFFIC_ID_MOTO.getType(),
TrafficTypeEnum.TYPE_TRAFFIC_ID_MOTO.getTraffic3DIconId());
MogoApisHandler.getInstance().getApis()
.getMapServiceApi()
.getMarkerManager(mContext)
.addPreVehicleModel(TrafficTypeEnum.TYPE_TRAFFIC_ID_BUS.getType(),
TrafficTypeEnum.TYPE_TRAFFIC_ID_BUS.getTraffic3DIconId());
MogoApisHandler.getInstance().getApis()
.getMapServiceApi()
.getMarkerManager(mContext)
.addPreVehicleModel(TrafficTypeEnum.TYPE_TRAFFIC_ID_TRUCK.getType(),
TrafficTypeEnum.TYPE_TRAFFIC_ID_TRUCK.getTraffic3DIconId());
}
}