[6.5.0]融合红绿灯

This commit is contained in:
xuxinchao
2024-06-28 16:34:35 +08:00
parent c2f258c3c4
commit fabf1996fd
8 changed files with 267 additions and 71 deletions

View File

@@ -39,8 +39,8 @@ fun TrafficLightStatus.convert(): TrafficLightEnum {
}
}
fun FusionTrafficLightOuterClass.FusionTrafficLight.convert(): TrafficLightEnum {
return when (this.state) {
fun convert(state: FusionTrafficLightOuterClass.FusionLightState): TrafficLightEnum {
return when (state) {
FusionTrafficLightOuterClass.FusionLightState.STATE_GREEN_FUSION -> TrafficLightEnum.GREEN
FusionTrafficLightOuterClass.FusionLightState.STATE_YELLOW_FUSION -> TrafficLightEnum.YELLOW
FusionTrafficLightOuterClass.FusionLightState.STATE_RED_FUSION -> TrafficLightEnum.RED
@@ -78,6 +78,10 @@ class TrafficLightDispatcher : IMoGoAutopilotIdentifyListener, IMoGoTrafficLight
@Volatile
private var hasAutopilotPerception: Boolean = false
//是否有融合带有下一和下二灯态的红绿灯数据
@Volatile
private var hasFusionLightStatus: Boolean = false
//红绿灯定时器,超时未更新隐藏红绿灯
@Volatile
private var lightCountDownTimer: CountDownTimer? = null
@@ -125,19 +129,29 @@ class TrafficLightDispatcher : IMoGoAutopilotIdentifyListener, IMoGoTrafficLight
if (!hasAutopilotPerception) {
hasAutopilotPerception = true
}
if (HmiBuildConfig.isShowCarSourceTrafficLightView) {
var lightRemain = light.duration.toInt()
val source = when (trafficLights.source) {
1 -> DataSourceType.TELEMATIC_UNION_V2I
2 -> DataSourceType.TELEMATIC_UNION_V2N
else -> {
lightRemain = 0
DataSourceType.TELEMATIC
if(light.nextState == null || light.nextState == FusionTrafficLightOuterClass.FusionLightState.STATE_OFF_FUSION
|| light.nextTwoState == null || light.nextTwoState == FusionTrafficLightOuterClass.FusionLightState.STATE_OFF_FUSION){
if (HmiBuildConfig.isShowCarSourceTrafficLightView) {
var lightRemain = light.duration.toInt()
val source = when (trafficLights.source) {
1 -> DataSourceType.TELEMATIC_UNION_V2I
2 -> DataSourceType.TELEMATIC_UNION_V2N
else -> {
lightRemain = 0
DataSourceType.TELEMATIC
}
}
onTrafficLightPlusSource(convert(light.state), lightRemain, source)
} else {
onTrafficLightPlusSource(convert(light.state), 0, DataSourceType.TELEMATIC)
}
onTrafficLightPlusSource(light.convert(), lightRemain, source)
} else {
onTrafficLightPlusSource(light.convert(), 0, DataSourceType.TELEMATIC)
}else{
//有下一和下二灯态则为融合V2N红绿灯数据
onFusionTrafficLight(convert(light.state),light.duration.toInt(),
convert(light.nextState),light.nextDuration.toInt(),
convert(light.nextTwoState),light.nextTwoDuration.toInt(),
DataSourceType.TELEMATIC_UNION_V2N
)
}
}
}
@@ -248,6 +262,34 @@ class TrafficLightDispatcher : IMoGoAutopilotIdentifyListener, IMoGoTrafficLight
CallerTrafficLightListenerManager.disableTrafficLight()
}
/**
* 融合V2N红绿灯数据带有下一下二灯态
*/
@ChainLog(
linkChainLog = ChainConstant.CHAIN_TYPE_SOCKET_TRAFFIC_LIGHT,
linkCode = ChainConstant.CHAIN_SOURCE_ADAS,
nodeAliasCode = ChainConstant.CHAIN_CODE_ADAS_TRAFFIC_LIGHT,
paramIndexes = [0, 1, 2,3,4,5,6,7]
)
override fun onFusionTrafficLight(
currentState: TrafficLightEnum, currentDuration: Int,
nextState: TrafficLightEnum, nextDuration: Int,
nextTwoState: TrafficLightEnum, nextTwoDuration: Int,
lightSource: DataSourceType
) {
super.onFusionTrafficLight(currentState, currentDuration, nextState, nextDuration,
nextTwoState, nextTwoDuration, lightSource)
if (filterTelematicUnion(lightSource)) {
return
}
hasObuLightStatus = false
hasAutopilotPerception = false
hasAiLightStatus = false
hasFusionLightStatus = true
CallerTrafficLightListenerManager.showFusionTrafficLight(currentState, currentDuration, nextState, nextDuration,
nextTwoState, nextTwoDuration, lightSource)
}
/**
* OBU红绿灯数据
*/

View File

@@ -3,8 +3,14 @@ package com.mogo.eagle.core.function.hmi.ui.widget
import android.content.Context
import android.util.AttributeSet
import android.view.LayoutInflater
import android.view.View
import androidx.constraintlayout.widget.ConstraintLayout
import com.mogo.eagle.core.data.enums.DataSourceType
import com.mogo.eagle.core.data.enums.TrafficLightEnum
import com.mogo.eagle.core.function.api.datacenter.union.IMoGoTrafficLightListener
import com.mogo.eagle.core.function.call.v2x.CallerTrafficLightListenerManager
import com.mogo.eagle.core.function.hmi.R
import com.mogo.eagle.core.utilcode.util.UiThreadHandler
/**
* 融合红绿灯View
@@ -14,20 +20,61 @@ class FusionTrafficLightView @JvmOverloads constructor(
context: Context,
attrs: AttributeSet? = null,
defStyleAttr: Int = 0
) : ConstraintLayout(context, attrs, defStyleAttr){
) : ConstraintLayout(context, attrs, defStyleAttr), IMoGoTrafficLightListener {
companion object {
private const val TAG = "FusionTrafficLightView"
}
private var mCurrentLightId = TrafficLightEnum.BLACK
override fun onAttachedToWindow() {
super.onAttachedToWindow()
LayoutInflater.from(context).inflate(R.layout.hmi_view_fusion_traffic_light, this, true)
CallerTrafficLightListenerManager.addListener(TAG, this)
}
override fun onDetachedFromWindow() {
super.onDetachedFromWindow()
CallerTrafficLightListenerManager.removeListener(TAG)
}
/**
* 关闭红绿灯预警展示,并重制灯态
*/
override fun disableTrafficLight() {
super.disableTrafficLight()
UiThreadHandler.post{
mCurrentLightId = TrafficLightEnum.BLACK
this@FusionTrafficLightView.visibility = GONE
}
}
/**
* 展示融合带有下一下二灯态的红绿灯
* @param currentState 当前灯态
* @param currentDuration 当前灯态倒计时
* @param nextState 下一灯态
* @param nextDuration 下一灯态倒计时
* @param nextTwoState 下二灯态
* @param nextTwoDuration 下二灯态倒计时
* @param lightSource 数据来源
*/
override fun showFusionTrafficLight(
currentState: TrafficLightEnum, currentDuration: Int,
nextState: TrafficLightEnum, nextDuration: Int,
nextTwoState: TrafficLightEnum, nextTwoDuration: Int,
lightSource: DataSourceType
) {
super.showFusionTrafficLight(currentState, currentDuration, nextState,
nextDuration, nextTwoState, nextTwoDuration, lightSource)
//如果当前红绿灯视图为隐藏状态则设置为显示状态
if(this@FusionTrafficLightView.visibility == View.GONE){
this@FusionTrafficLightView.visibility = View.VISIBLE
//首次展示,需要将当前、下一、下二灯态的时间占比绘制出来,只绘制一次
}
}
}

View File

@@ -0,0 +1,113 @@
package com.mogo.eagle.core.function.hmi.ui.widget;
import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.util.AttributeSet;
import android.view.View;
import androidx.annotation.Nullable;
import com.mogo.eagle.core.function.hmi.R;
import me.jessyan.autosize.utils.AutoSizeUtils;
/**
* 融合红绿灯红、黄、绿时间占比示意View
* 鹰眼6.5.0需求
*/
public class ProportionChartView extends View {
private static int DEFAULT_RING_WIDTH = 5;
private float mRingWidth = 0;
private Paint mRingPaint;
private float mRadius;
// private List<Float>
public ProportionChartView(Context context) {
super(context);
initSize(context);
init();
}
public ProportionChartView(Context context, @Nullable AttributeSet attrs) {
super(context, attrs);
initAttr(context, attrs);
initSize(context);
init();
}
public ProportionChartView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
initAttr(context, attrs);
initSize(context);
init();
}
private void initAttr(Context context, AttributeSet attrs){
if (attrs == null) {
return;
}
TypedArray array = context.obtainStyledAttributes(attrs, R.styleable.ProportionChartView);
int n = array.getIndexCount();
for (int i = 0; i < n; i++) {
int attr = array.getIndex(i);
if (attr == R.styleable.ProportionChartView_ringWidth) {
mRingWidth = array.getDimension(attr, AutoSizeUtils.dp2px(context, DEFAULT_RING_WIDTH));
}
}
array.recycle();
}
/**
* 初始化Size
* @param context 上下文
*/
private void initSize(Context context){
if (mRingWidth == 0) {
mRingWidth = AutoSizeUtils.dp2px(context, AutoSizeUtils.dp2px(context, DEFAULT_RING_WIDTH));
}
}
/**
* 初始化画笔
*/
private void init(){
mRingPaint = new Paint();
//抗锯齿
mRingPaint.setAntiAlias(true);
//防抖动
mRingPaint.setDither(true);
//仅描边(圆环)
mRingPaint.setStyle(Paint.Style.STROKE);
//圆环宽度
mRingPaint.setStrokeWidth(mRingWidth);
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
int size = Math.max(MeasureSpec.getSize(widthMeasureSpec), MeasureSpec.getSize(widthMeasureSpec));
setMeasuredDimension(size, size);
}
@Override
protected void onSizeChanged(int w, int h, int oldw, int oldh) {
super.onSizeChanged(w, h, oldw, oldh);
//宽和高分别去掉padding值取min的一半即圆的半径(这里demo没有用到可自行做一些其他计算使用)
mRadius = Math.min(w - getPaddingLeft() - getPaddingRight(), h - getPaddingTop() - getPaddingBottom()) / 2f;
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
drawRingView(canvas);
}
/**
* 画Ring
*/
private void drawRingView(Canvas canvas){
float sweepAngle = 0f;
float startAngle = 0f;
}
}

View File

@@ -1,50 +0,0 @@
package com.mogo.eagle.core.function.hmi.ui.widget
import android.content.Context
import android.graphics.Canvas
import android.graphics.Paint
import android.graphics.RectF
import android.util.AttributeSet
import android.view.View
import com.mogo.eagle.core.function.hmi.R
/**
* 融合红绿灯红、黄、绿时间占比示意View
* 鹰眼6.5.0需求
*/
class TrafficLightProportionView constructor(
context: Context,
attrs: AttributeSet
) : View(context, attrs){
private var mCanvas: Canvas? = null
private var mRingPaint: Paint? = null
private var mRectF: RectF? = null
private var proportionList =ArrayList<Int>()
init {
}
override fun onMeasure(widthMeasureSpec: Int, heightMeasureSpec: Int) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec)
val size = MeasureSpec.getSize(widthMeasureSpec)
.coerceAtLeast(MeasureSpec.getSize(widthMeasureSpec))
setMeasuredDimension(size, size)
}
override fun onDraw(canvas: Canvas?) {
super.onDraw(canvas)
}
private fun initAttr(context: Context,attrs: AttributeSet?){
if(null == attrs){
return
}
val array = context.obtainStyledAttributes(attrs, R.styleable.TrafficLightProportionView)
//TODO
array.recycle()
}
}

View File

@@ -118,7 +118,7 @@
<attr name="roma_change_dis_color" format="boolean"/>
</declare-styleable>
<declare-styleable name="TrafficLightProportionView">
<declare-styleable name="ProportionChartView">
<attr name="ringWidth" format="reference|dimension"/>
</declare-styleable>

View File

@@ -30,6 +30,15 @@ interface IMoGoTrafficLightListener {
}
/**
* 融合红绿灯,带有下一灯态和下二灯态
*/
fun onFusionTrafficLight(
currentState: TrafficLightEnum,currentDuration: Int = -1,
nextState: TrafficLightEnum,nextDuration: Int = -1,
nextTwoState: TrafficLightEnum,nextTwoDuration: Int = -1,
lightSource: DataSourceType){}
/**
* obu红绿灯状态
*/
@@ -48,6 +57,21 @@ interface IMoGoTrafficLightListener {
*/
fun showTrafficLight(checkLightId: TrafficLightEnum, lightSource: DataSourceType) {}
/**
* 展示融合带有下一下二灯态的红绿灯
* @param currentState 当前灯态
* @param currentDuration 当前灯态倒计时
* @param nextState 下一灯态
* @param nextDuration 下一灯态倒计时
* @param nextTwoState 下二灯态
* @param nextTwoDuration 下二灯态倒计时
* @param lightSource 数据来源
*/
fun showFusionTrafficLight(currentState: TrafficLightEnum, currentDuration: Int,
nextState: TrafficLightEnum, nextDuration: Int,
nextTwoState: TrafficLightEnum, nextTwoDuration: Int,
lightSource: DataSourceType){}
/**
* @param redNum 红灯倒计时
* @param yellowNum 黄灯倒计时

View File

@@ -71,6 +71,26 @@ object CallerTrafficLightListenerManager : CallerBase<IMoGoTrafficLightListener>
}
}
/**
* 展示融合带有下一下二灯态的红绿灯
* @param currentState 当前灯态
* @param currentDuration 当前灯态倒计时
* @param nextState 下一灯态
* @param nextDuration 下一灯态倒计时
* @param nextTwoState 下二灯态
* @param nextTwoDuration 下二灯态倒计时
* @param lightSource 数据来源
*/
fun showFusionTrafficLight(currentState: TrafficLightEnum, currentDuration: Int,
nextState: TrafficLightEnum, nextDuration: Int,
nextTwoState: TrafficLightEnum, nextTwoDuration: Int,
lightSource: DataSourceType){
M_LISTENERS.forEach{
val listener = it.value
listener.showFusionTrafficLight(currentState,currentDuration,nextState,nextDuration,nextTwoState,nextTwoDuration,lightSource)
}
}
fun changeCountdownTrafficLightNum(redNum: Int, yellowNum: Int, greenNum: Int) {
M_LISTENERS.forEach {
val listener = it.value

View File

@@ -22,12 +22,12 @@ enum FusionLightState {
message FusionTrafficLight {
optional int64 id = 1;
optional FusionLightType type = 2 [default = TYPE_DEFAULT_FUSION];
optional FusionLightState state = 3 [default = STATE_OFF_FUSION];
optional float duration = 4; // seconds since the last state changed
optional FusionLightState next_state = 5 [default = STATE_OFF_FUSION];
optional float next_duration = 6 [default = -1.0]; // seconds since the last state changed
optional FusionLightState next_two_state = 7 [default = STATE_OFF_FUSION];
optional float next_two_duration = 8 [default = -1.0]; // seconds since the last state changed
optional FusionLightState state = 3 [default = STATE_OFF_FUSION]; //当前灯态
optional float duration = 4; // seconds since the last state changed //当前灯态倒计时
optional FusionLightState next_state = 5 [default = STATE_OFF_FUSION]; //下一灯态
optional float next_duration = 6 [default = -1.0]; // seconds since the last state changed 下一灯态倒计时
optional FusionLightState next_two_state = 7 [default = STATE_OFF_FUSION]; //下二灯态
optional float next_two_duration = 8 [default = -1.0]; // seconds since the last state changed 下二灯态倒计时
}
message FusionTrafficLights {