[6.1.0][feat]新增平行驾驶状态View

This commit is contained in:
chenfufeng
2023-09-14 18:18:02 +08:00
parent a41b6d5708
commit cdd7da7838
8 changed files with 374 additions and 0 deletions

View File

@@ -0,0 +1,335 @@
package com.mogo.eagle.core.function.hmi.ui.widget
import android.annotation.SuppressLint
import android.content.Context
import android.graphics.Color
import android.util.AttributeSet
import android.view.LayoutInflater
import android.widget.ImageView
import android.widget.TextView
import androidx.constraintlayout.widget.ConstraintLayout
import com.mogo.cloud.passport.MoGoAiCloudClientConfig
import com.mogo.commons.voice.AIAssist
import com.mogo.eagle.core.function.api.autopilot.IMoGoAutopilotActionsListener
import com.mogo.eagle.core.function.api.autopilot.IMoGoAutopilotStatusListener
import com.mogo.eagle.core.function.api.autopilot.IMoGoParallelDrivingStatusListener
import com.mogo.eagle.core.function.call.autopilot.CallerAutoPilotControlManager
import com.mogo.eagle.core.function.call.autopilot.CallerAutoPilotStatusListenerManager
import com.mogo.eagle.core.function.call.autopilot.CallerAutopilotActionsListenerManager
import com.mogo.eagle.core.function.call.autopilot.CallerAutopilotActionsListenerManager.getUnableAutopilotReasons
import com.mogo.eagle.core.function.call.autopilot.CallerParallelDrivingListenerManager
import com.mogo.eagle.core.function.hmi.R
import com.mogo.eagle.core.utilcode.util.ThreadUtils
import com.mogo.eagle.core.utilcode.util.ToastUtils
import com.zhjt.mogo.adas.data.bean.UnableAutopilotReason
import com.zhjt.mogo.adas.data.bean.UnableAutopilotReason.SourceType
import mogo.yycp.paralleldriving.protocol.ParallelDrivingRequest.ParallelRequest
import mogo.yycp.paralleldriving.protocol.ParallelTaskProcessNoticeOuterClass
/**
* 平行驾驶状态View
*/
class ParallelDriveView @JvmOverloads constructor(
context: Context,
attrs: AttributeSet? = null,
defStyleAttr: Int = 0
) : ConstraintLayout(context, attrs, defStyleAttr), IMoGoAutopilotStatusListener,
IMoGoAutopilotActionsListener, IMoGoParallelDrivingStatusListener {
companion object {
private const val TAG = "ParallelDriveView"
private const val APP_REQUESTING = 1
private const val AD_REQUESTING = 2
private const val SYNCHRONIZING = 3
private const val PARALLEL_DRIVING = 4
private const val FAILURE = 5
private const val ONE_EXCEPTION = 6
private const val TWO_EXCEPTION = 7
private const val UNAVAILABLE = 8
}
//1:ready, 2:自动驾驶中, 7:平行驾驶中
@Volatile
private var autopilotState: Int = 1
// 初始状态为0
private var state: Int = 0
private lateinit var rootLayout: ConstraintLayout
private lateinit var statusIcon: ImageView
private lateinit var statusTitle: TextView
init {
LayoutInflater.from(context).inflate(R.layout.view_parallel_drive, this, true)
}
override fun onAttachedToWindow() {
super.onAttachedToWindow()
initView()
CallerAutoPilotStatusListenerManager.addListener(TAG, this)
CallerAutopilotActionsListenerManager.addListener(TAG, this)
CallerParallelDrivingListenerManager.addListener(TAG, this)
}
private fun initView() {
rootLayout = findViewById(R.id.parDriveLayout)
statusIcon = findViewById(R.id.ivStatusIcon)
statusTitle = findViewById(R.id.tvAutopilotContent)
rootLayout.setOnClickListener {
when (state) {
0 -> {
state = APP_REQUESTING
updateUI(APP_REQUESTING)
reqParaDrive()
}
APP_REQUESTING -> {
cancelParaDrive()
ToastUtils.showShort("请求已取消!")
checkAvailableAndUpdateUI()
}
UNAVAILABLE -> {
ToastUtils.showShort("请P档驻车并松开油门刹车后请求")
}
}
}
checkAvailableAndUpdateUI()
}
override fun onAutopilotStatusResponse(state: Int) {
super.onAutopilotStatusResponse(state)
if (state != autopilotState) {
synchronized(this) {
when (state) {
7 -> {
if (this.autopilotState != 7) {
ThreadUtils.runOnUiThread({
updateUI(PARALLEL_DRIVING)
}, ThreadUtils.MODE.QUEUE)
}
}
else -> {
if (this.autopilotState == 7 && this.autopilotState != state) {
ThreadUtils.runOnUiThread({
checkAvailableAndUpdateUI()
}, ThreadUtils.MODE.QUEUE)
}
}
}
this.autopilotState = state
}
}
}
override fun onAutopilotAbility(
isAutopilotAbility: Boolean,
unableAutopilotReasons: ArrayList<UnableAutopilotReason>?
) {
// 是否可平行驾驶
val isAvailable = isAvailable(unableAutopilotReasons)
if (!isAvailable) {
ThreadUtils.runOnUiThread({
updateUI(UNAVAILABLE)
}, ThreadUtils.MODE.QUEUE)
}
}
override fun onParallelDrivingResp(parallelTaskProcessNotice: ParallelTaskProcessNoticeOuterClass.ParallelTaskProcessNotice?) {
parallelTaskProcessNotice?.let {
ThreadUtils.runOnUiThread({
when (it.code) {
"START_SYNC" -> {// 同步中
state = SYNCHRONIZING
updateUI(SYNCHRONIZING)
}
"EXCEPTION_EXIT_SYNC" -> {// 同步异常结束
state = ONE_EXCEPTION
updateUI(ONE_EXCEPTION)
}
"TASK_REJECTED" -> {// 任务已被拒绝
state = FAILURE
updateUI(FAILURE)
AIAssist.getInstance(context).speakTTSVoice("请求已被拒绝")
}
"PARALLEL_EXCEPTION_MANUAL_DRIVING" -> {// 异常请人工驾驶
state = TWO_EXCEPTION
updateUI(TWO_EXCEPTION)
}
"EXCEPTION_EXIT_PARALLEL_DRIVING" -> {// 平行驾驶异常结束
state = ONE_EXCEPTION
updateUI(ONE_EXCEPTION)
}
"EXIT_SYNC" -> {// 同步结束
checkAvailableAndUpdateUI()
}
"UNABLE_TAKEOVER" -> {// 无法接管
state = ONE_EXCEPTION
updateUI(ONE_EXCEPTION)
}
"xxx" -> {// 请求中
state = AD_REQUESTING
updateUI(AD_REQUESTING)
}
}
}, ThreadUtils.MODE.QUEUE)
}
}
private fun isAvailable(unableAutopilotReasons: ArrayList<UnableAutopilotReason>?): Boolean {
var unavailable = false
unableAutopilotReasons?.forEach {
if (it.source.ordinal == SourceType.CHASSIS.ordinal) {
unavailable = true
}
}
return !unavailable
}
@SuppressLint("UseCompatLoadingForDrawables")
private fun updateUI(state: Int) {
when (state) {
0 -> {
rootLayout.isEnabled = true
statusIcon.background =
resources.getDrawable(R.drawable.icon_autopilot_status, null)
statusTitle.text = context.getString(R.string.parallel_drive)
statusTitle.setTextColor(Color.parseColor("#FFFFFF"))
statusIcon.imageAlpha = 255
rootLayout.background = resources.getDrawable(R.drawable.bg_auto_pilot, null)
}
APP_REQUESTING -> {
rootLayout.isEnabled = true
statusIcon.background =
resources.getDrawable(R.drawable.icon_para_requesting, null)
statusTitle.setTextColor(Color.parseColor("#FFFFFF"))
statusIcon.imageAlpha = 255
statusTitle.text = context.getString(R.string.parallel_drive_requesting)
rootLayout.background = resources.getDrawable(R.drawable.bg_auto_pilot, null)
}
AD_REQUESTING -> {
rootLayout.isEnabled = false
statusIcon.background =
resources.getDrawable(R.drawable.icon_para_requesting, null)
statusTitle.setTextColor(Color.parseColor("#FFFFFF"))
statusIcon.imageAlpha = 255
statusTitle.text = context.getString(R.string.parallel_drive_requesting)
rootLayout.background = resources.getDrawable(R.drawable.bg_auto_pilot, null)
}
SYNCHRONIZING -> {
rootLayout.isEnabled = false
statusIcon.background =
resources.getDrawable(R.drawable.icon_para_syn, null)
statusTitle.setTextColor(Color.parseColor("#FFFFFF"))
statusIcon.imageAlpha = 255
statusTitle.text = context.getString(R.string.parallel_drive_synchronizing)
rootLayout.background = resources.getDrawable(R.drawable.bg_auto_pilot, null)
}
PARALLEL_DRIVING -> {
rootLayout.isEnabled = false
statusIcon.background =
resources.getDrawable(R.drawable.icon_autopilot_status, null)
statusTitle.setTextColor(Color.parseColor("#FFFFFF"))
statusIcon.imageAlpha = 255
rootLayout.background =
resources.getDrawable(R.drawable.bg_auto_pilot_running, null)
statusTitle.text = context.getString(R.string.parallel_drive)
}
FAILURE -> {
rootLayout.isEnabled = false
rootLayout.postDelayed({
checkAvailableAndUpdateUI()
}, 1000)
statusTitle.setTextColor(Color.parseColor("#FFFFFF"))
statusIcon.imageAlpha = 255
statusIcon.background =
resources.getDrawable(R.drawable.icon_fail_start, null)
rootLayout.background = resources.getDrawable(R.drawable.bg_auto_pilot, null)
statusTitle.text = context.getString(R.string.parallel_drive_failure)
}
ONE_EXCEPTION -> {
rootLayout.isEnabled = false
rootLayout.postDelayed({
checkAvailableAndUpdateUI()
}, 1000)
statusTitle.setTextColor(Color.parseColor("#FFFFFF"))
statusIcon.imageAlpha = 255
statusIcon.background =
resources.getDrawable(R.drawable.icon_fail_start, null)
rootLayout.background = resources.getDrawable(R.drawable.bg_auto_pilot, null)
statusTitle.text = context.getString(R.string.parallel_drive_exception)
}
TWO_EXCEPTION -> {
rootLayout.isEnabled = false
rootLayout.postDelayed({
checkAvailableAndUpdateUI()
}, 2000)
statusTitle.setTextColor(Color.parseColor("#FFFFFF"))
statusIcon.imageAlpha = 255
statusIcon.background =
resources.getDrawable(R.drawable.icon_fail_start, null)
rootLayout.background = resources.getDrawable(R.drawable.bg_auto_pilot, null)
statusTitle.text = context.getString(R.string.parallel_drive_exception)
}
UNAVAILABLE -> {
rootLayout.isEnabled = false
statusIcon.background =
resources.getDrawable(R.drawable.icon_autopilot_status, null)
statusTitle.setTextColor(Color.parseColor("#66FFFFFF"))
statusIcon.imageAlpha = 102
rootLayout.background = resources.getDrawable(R.drawable.bg_auto_pilot, null)
statusTitle.text = context.getString(R.string.parallel_drive)
}
else -> {}
}
}
private fun reqParaDrive() {
val sn = MoGoAiCloudClientConfig.getInstance().sn
val parallelRequest = ParallelRequest.newBuilder()
.setSn(sn)
.setType(2)// 2:鹰眼请求
.setTakeover(1)// 1:请求平行驾驶接管
.setCode("PAD_ACTIVE")
parallelRequest.reason = "鹰眼请求"
CallerAutoPilotControlManager.sendParallelDrivingReq(
System.currentTimeMillis().toString(), parallelRequest.build()
)
}
private fun cancelParaDrive() {
val sn = MoGoAiCloudClientConfig.getInstance().sn
val parallelRequest = ParallelRequest.newBuilder()
.setSn(sn)
.setType(2)// 2:鹰眼请求
.setTakeover(2)// 2:取消平行驾驶接管
.setCode("PAD_ACTIVE")
parallelRequest.reason = "鹰眼请求"
CallerAutoPilotControlManager.sendParallelDrivingReq(
System.currentTimeMillis().toString(), parallelRequest.build()
)
}
private fun checkAvailableAndUpdateUI() {
if (isAvailable(getUnableAutopilotReasons())) {
state = 0
updateUI(0)
} else {
state = UNAVAILABLE
updateUI(UNAVAILABLE)
}
}
override fun onDetachedFromWindow() {
super.onDetachedFromWindow()
CallerAutoPilotStatusListenerManager.removeListener(TAG)
CallerAutopilotActionsListenerManager.removeListener(TAG)
CallerParallelDrivingListenerManager.removeListener(TAG)
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 62 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 65 KiB

View File

@@ -0,0 +1,34 @@
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/parDriveLayout"
android:layout_width="361dp"
android:layout_height="180dp"
android:background="@drawable/bg_auto_pilot"
>
<ImageView
android:id="@+id/ivStatusIcon"
android:layout_width="58dp"
android:layout_height="58dp"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
android:layout_marginStart="72dp"
android:layout_marginTop="56dp"
/>
<TextView
android:id="@+id/tvAutopilotContent"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="parent"
android:layout_marginEnd="72dp"
android:layout_marginTop="60dp"
android:textColor="#FFFFFF"
android:textSize="36sp"
tools:text="远程代驾"
/>
</androidx.constraintlayout.widget.ConstraintLayout>

View File

@@ -86,4 +86,9 @@
<string name="light_source_ai_cloud">云端下发</string>
<string name="light_source_perception">自车感知</string>
<string name="light_source_obu">\u2000OBU\u2000</string>
<string name="parallel_drive">远程代驾</string>
<string name="parallel_drive_requesting">请求中...</string>
<string name="parallel_drive_synchronizing">同步中...</string>
<string name="parallel_drive_failure">请求失败</string>
<string name="parallel_drive_exception">异常</string>
</resources>