Merge branch 'dev_robotaxi-d_240801_6.5.2' into dev_robotaxi-d_240807_6.6.0

This commit is contained in:
xuxinchao
2024-08-07 15:48:39 +08:00
52 changed files with 1990 additions and 16 deletions

View File

@@ -636,6 +636,76 @@ class MoGoAutopilotControlProvider :
return AdasManager.getInstance().sendDetouringSpeed(speed) > -1
}
/**
* AEB开关
* isEnable = true 开启
* isEnable = false 关闭
* @return boolean
*/
override fun sendAebCmd(isEnable: Boolean): Boolean {
return if(isEnable){
AdasManager.getInstance().sendAebCmd(1) > -1
}else{
AdasManager.getInstance().sendAebCmd(0) > -1
}
}
/**
* 限制绕障开关
* isEnable = true 限制绕障
* isEnable = false 正常绕障
* @return boolean
*/
override fun sendLaneChangeRestrainValid(isEnable: Boolean): Boolean {
return if(isEnable){
AdasManager.getInstance().sendLaneChangeRestrainValid(1) > -1
}else{
AdasManager.getInstance().sendLaneChangeRestrainValid(0) > -1
}
}
/**
* 停车让行线前避让等待开关
* isEnable = true 停车让行线前需要避让等待
* isEnable = false 停车让行线前无需避让等待
* @return boolean
*/
override fun sendStopYieldValid(isEnable: Boolean): Boolean {
return if(isEnable){
AdasManager.getInstance().sendStopYieldValid(1) > -1
}else{
AdasManager.getInstance().sendStopYieldValid(0) > -1
}
}
/**
* 地图限速功能开关
* isEnable = true 使用地图限速功能
* isEnable = false 不使用地图限速功能
* @return boolean
*/
override fun sendHadmapSpeedLimitValid(isEnable: Boolean): Boolean {
return if(isEnable){
AdasManager.getInstance().sendHadmapSpeedLimitValid(1) > -1
}else{
AdasManager.getInstance().sendHadmapSpeedLimitValid(0) > -1
}
}
/**
* 环岛模式开关
* isEnable = true 环岛模式
* isEnable = false 普通模式
* @return boolean
*/
override fun sendRampThetaValid(isEnable: Boolean): Boolean {
return if(isEnable){
AdasManager.getInstance().sendRampThetaValid(1) > -1
}else{
AdasManager.getInstance().sendRampThetaValid(0) > -1
}
}
/**
* 弱网减速停车策略开关
* isEnable = true 使用弱网减速停车策略
@@ -1243,7 +1313,38 @@ class MoGoAutopilotControlProvider :
return AdasManager.getInstance().sendRoboBusJinlvM1TaskCmd(roboBusJinlvM1Cmd) > -1
}
@ChainLog(
linkChainLog = AdasChain.CHAIN_TYPE_SOCKET_AUTOPILOT,
linkCode = AdasChain.CHAIN_SOURCE_ADAS,
nodeAliasCode = AdasChain.CHAIN_CODE_ADAS_SEND_PLANNING_CMD,
paramIndexes = [0]
)
override fun sendPlanningCmd(cmd: Int): Boolean {
return AdasManager.getInstance().sendPlanningCmd(cmd) > -1
}
@ChainLog(
linkChainLog = AdasChain.CHAIN_TYPE_SOCKET_AUTOPILOT,
linkCode = AdasChain.CHAIN_SOURCE_ADAS,
nodeAliasCode = AdasChain.CHAIN_CODE_ADAS_SEND_PLANNING_CMD,
paramIndexes = [0]
)
override fun sendPlanningLineChangeCmd(cmd: Int): Boolean {
return AdasManager.getInstance().sendPlanningLaneChangeCmd(cmd) > -1
}
override fun sendPlanningPullOverCmd(pullOverCmd: Int): Boolean {
return AdasManager.getInstance().sendPlanningPullOverCmd(pullOverCmd) > -1
}
/**
* 设置座椅压力接口
* @param driver 主驾是否有人
* @param copilot 副驾是否有人
* @param backRow 后排是否有人
*/
override fun sendSeatPressure(driver: Boolean, copilot: Boolean, backRow: Boolean): Boolean {
return AdasManager.getInstance().sendSeatPressure(driver, copilot, backRow) > -1
}
}

View File

@@ -22,6 +22,7 @@ import com.mogo.eagle.core.data.deva.report.WorkOrderReportInfo
import com.mogo.eagle.core.data.deva.scene.SceneModule
import com.mogo.eagle.core.data.deva.scene.SceneTAG
import com.mogo.eagle.core.data.msgbox.MsgBoxBean
import com.mogo.eagle.core.data.takeover.TakeOverAnnotation
import com.mogo.eagle.core.function.api.devatools.IDevaToolsProvider
import com.mogo.eagle.core.function.api.devatools.block.IMoGoBlockProvider
import com.mogo.eagle.core.function.api.devatools.download.DownloadType
@@ -73,6 +74,7 @@ import com.zhjt.mogo_core_function_devatools.status.entity.RouteDownloadStatus
import com.zhjt.mogo_core_function_devatools.status.entity.Status
import com.zhjt.mogo_core_function_devatools.status.ui.AutoPilotLaunchBeforeView
import com.zhjt.mogo_core_function_devatools.strict.StrictModeProviderImpl
import com.zhjt.mogo_core_function_devatools.takeover.TakeOverManager
import com.zhjt.mogo_core_function_devatools.trace.TraceManager.Companion.traceManager
import com.zhjt.mogo_core_function_devatools.tts.TtsManager.Companion.ttsManager
import com.zhjt.mogo_core_function_devatools.upgrade.UpgradeManager.Companion.upgradeManager
@@ -647,4 +649,8 @@ class DevaToolsProvider : IDevaToolsProvider, IAppStateListener {
override fun setRouteDynamicColorEnable(enable: Boolean) {
mapRouteProvider?.setRouteDynamicColorEnable(enable)
}
override fun takeOver(@TakeOverAnnotation takeOverAnnotation: Int) {
TakeOverManager.takeOverManager.takeOver(takeOverAnnotation)
}
}

View File

@@ -0,0 +1,19 @@
package com.zhjt.mogo_core_function_devatools.takeover
import com.mogo.eagle.core.data.takeover.TakeOverAnnotation
import com.zhjt.mogo_core_function_devatools.takeover.network.TakeOverNetWorkModel
class TakeOverManager {
companion object {
val takeOverManager: TakeOverManager by lazy(LazyThreadSafetyMode.SYNCHRONIZED) {
TakeOverManager()
}
}
private val takeOverNetWorkModel = TakeOverNetWorkModel()
fun takeOver(@TakeOverAnnotation takeOverAnnotation: Int) {
}
}

View File

@@ -0,0 +1,13 @@
package com.zhjt.mogo_core_function_devatools.takeover.network
import com.mogo.eagle.core.data.BaseResponse
import retrofit2.http.*
interface TakeOverApiService {
//云端接管
@Headers("Content-Type:application/json;charset=UTF-8")
@POST("/paralleldriving-service/autocars")
suspend fun takeOver(@Body map: MutableMap<String, Any>): BaseResponse<Any>
}

View File

@@ -0,0 +1,22 @@
package com.zhjt.mogo_core_function_devatools.takeover.network
import com.mogo.commons.debug.DebugConfig
class TakeOverHost {
companion object{
private const val HOST_DEV = "http://dzt-test.zhidaozhixing.com/"
private const val HOST_RELEASE = "http://dzt.zhidaozhixing.com/"
fun get(): String{
return when (DebugConfig.getNetMode()) {
DebugConfig.NET_MODE_DEV -> HOST_DEV
DebugConfig.NET_MODE_QA -> HOST_DEV
DebugConfig.NET_MODE_DEMO -> HOST_RELEASE
DebugConfig.NET_MODE_RELEASE -> HOST_RELEASE
else -> HOST_RELEASE
}
}
}
}

View File

@@ -0,0 +1,288 @@
package com.zhjt.mogo_core_function_devatools.takeover.network
import com.mogo.cloud.passport.MoGoAiCloudClientConfig
import com.mogo.eagle.core.data.BaseResponse
import com.mogo.eagle.core.data.app.AppConfigInfo
import com.mogo.eagle.core.data.takeover.*
import com.mogo.eagle.core.network.MoGoRetrofitFactory
import com.mogo.eagle.core.network.apiCall
import com.mogo.eagle.core.network.request
import java.util.concurrent.ConcurrentHashMap
class TakeOverNetWorkModel {
private fun getNetWorkApi(baseUrl: String = TakeOverHost.get()): TakeOverApiService {
return MoGoRetrofitFactory.getInstanceNoCallAdapter(baseUrl)
.create(TakeOverApiService::class.java)
}
private val retryMap: ConcurrentHashMap<Int, Int> = ConcurrentHashMap<Int, Int>()
fun manualControl(onSuccess: (() -> Unit), onError: ((String) -> Unit)) {
request<BaseResponse<Any>> {
start {
retryMap[MANUAL_CONTROL] = retryMap[MANUAL_CONTROL] ?: 0 + 1
}
loader {
apiCall {
val map = mutableMapOf<String, Any>()
map["sn"] = MoGoAiCloudClientConfig.getInstance().sn
map["type"] = MANUAL_CONTROL
map["plateNumber"] = AppConfigInfo.plateNumber ?: ""
getNetWorkApi().takeOver(map)
}
}
onSuccess {
if (it.result != null) {
retryMap.remove(MANUAL_CONTROL)
onSuccess.invoke()
} else {
if (retryMap[MANUAL_CONTROL]!! <= 3) {
retryMap[MANUAL_CONTROL] = retryMap[MANUAL_CONTROL]!! + 1
manualControl(onSuccess, onError)
} else {
onError.invoke("manualControl result is null")
}
}
}
onError {
if (retryMap[MANUAL_CONTROL]!! <= 3) {
retryMap[MANUAL_CONTROL] = retryMap[MANUAL_CONTROL]!! + 1
manualControl(onSuccess, onError)
} else if (it.message != null) {
onError.invoke(it.message!!)
}
}
}
}
fun overTake(onSuccess: (() -> Unit), onError: ((String) -> Unit)) {
request<BaseResponse<Any>> {
start {
retryMap[OVER_TAKE] = retryMap[OVER_TAKE] ?: 0 + 1
}
loader {
apiCall {
val map = mutableMapOf<String, Any>()
map["sn"] = MoGoAiCloudClientConfig.getInstance().sn
map["type"] = OVER_TAKE
map["plateNumber"] = AppConfigInfo.plateNumber ?: ""
getNetWorkApi().takeOver(map)
}
}
onSuccess {
if (it.result != null) {
retryMap.remove(OVER_TAKE)
onSuccess.invoke()
} else {
if (retryMap[OVER_TAKE]!! <= 3) {
retryMap[OVER_TAKE] = retryMap[OVER_TAKE]!! + 1
manualControl(onSuccess, onError)
} else {
onError.invoke("overTake result is null")
}
}
}
onError {
if (retryMap[OVER_TAKE]!! <= 3) {
retryMap[OVER_TAKE] = retryMap[OVER_TAKE]!! + 1
manualControl(onSuccess, onError)
} else if (it.message != null) {
onError.invoke(it.message!!)
}
}
}
}
fun lineToLeft(onSuccess: (() -> Unit), onError: ((String) -> Unit)) {
request<BaseResponse<Any>> {
start {
retryMap[LINE_TO_LEFT] = retryMap[LINE_TO_LEFT] ?: 0 + 1
}
loader {
apiCall {
val map = mutableMapOf<String, Any>()
map["sn"] = MoGoAiCloudClientConfig.getInstance().sn
map["type"] = LINE_TO_LEFT
map["plateNumber"] = AppConfigInfo.plateNumber ?: ""
getNetWorkApi().takeOver(map)
}
}
onSuccess {
if (it.result != null) {
retryMap.remove(LINE_TO_LEFT)
onSuccess.invoke()
} else {
if (retryMap[LINE_TO_LEFT]!! <= 3) {
retryMap[LINE_TO_LEFT] = retryMap[LINE_TO_LEFT]!! + 1
manualControl(onSuccess, onError)
} else {
onError.invoke("lineToLeft result is null")
}
}
}
onError {
if (retryMap[LINE_TO_LEFT]!! <= 3) {
retryMap[LINE_TO_LEFT] = retryMap[LINE_TO_LEFT]!! + 1
manualControl(onSuccess, onError)
} else if (it.message != null) {
onError.invoke(it.message!!)
}
}
}
}
fun lineToRight(onSuccess: (() -> Unit), onError: ((String) -> Unit)) {
request<BaseResponse<Any>> {
start {
retryMap[LINE_TO_RIGHT] = retryMap[LINE_TO_RIGHT] ?: 0 + 1
}
loader {
apiCall {
val map = mutableMapOf<String, Any>()
map["sn"] = MoGoAiCloudClientConfig.getInstance().sn
map["type"] = LINE_TO_RIGHT
map["plateNumber"] = AppConfigInfo.plateNumber ?: ""
getNetWorkApi().takeOver(map)
}
}
onSuccess {
if (it.result != null) {
retryMap.remove(LINE_TO_RIGHT)
onSuccess.invoke()
} else {
if (retryMap[LINE_TO_RIGHT]!! <= 3) {
retryMap[LINE_TO_RIGHT] = retryMap[LINE_TO_RIGHT]!! + 1
manualControl(onSuccess, onError)
} else {
onError.invoke("lineToRight result is null")
}
}
}
onError {
if (retryMap[LINE_TO_RIGHT]!! <= 3) {
retryMap[LINE_TO_RIGHT] = retryMap[LINE_TO_RIGHT]!! + 1
manualControl(onSuccess, onError)
} else if (it.message != null) {
onError.invoke(it.message!!)
}
}
}
}
fun pullOver(onSuccess: (() -> Unit), onError: ((String) -> Unit)) {
request<BaseResponse<Any>> {
start {
retryMap[PULL_OVER] = retryMap[PULL_OVER] ?: 0 + 1
}
loader {
apiCall {
val map = mutableMapOf<String, Any>()
map["sn"] = MoGoAiCloudClientConfig.getInstance().sn
map["type"] = PULL_OVER
map["plateNumber"] = AppConfigInfo.plateNumber ?: ""
getNetWorkApi().takeOver(map)
}
}
onSuccess {
if (it.result != null) {
retryMap.remove(PULL_OVER)
onSuccess.invoke()
} else {
if (retryMap[PULL_OVER]!! <= 3) {
retryMap[PULL_OVER] = retryMap[PULL_OVER]!! + 1
manualControl(onSuccess, onError)
} else {
onError.invoke("pullOver result is null")
}
}
}
onError {
if (retryMap[PULL_OVER]!! <= 3) {
retryMap[PULL_OVER] = retryMap[PULL_OVER]!! + 1
manualControl(onSuccess, onError)
} else if (it.message != null) {
onError.invoke(it.message!!)
}
}
}
}
fun emergencyStop(onSuccess: (() -> Unit), onError: ((String) -> Unit)) {
request<BaseResponse<Any>> {
start {
retryMap[EMERGENCY_STOP] = retryMap[EMERGENCY_STOP] ?: 0 + 1
}
loader {
apiCall {
val map = mutableMapOf<String, Any>()
map["sn"] = MoGoAiCloudClientConfig.getInstance().sn
map["type"] = EMERGENCY_STOP
map["plateNumber"] = AppConfigInfo.plateNumber ?: ""
getNetWorkApi().takeOver(map)
}
}
onSuccess {
if (it.result != null) {
retryMap.remove(EMERGENCY_STOP)
onSuccess.invoke()
} else {
if (retryMap[EMERGENCY_STOP]!! <= 3) {
retryMap[EMERGENCY_STOP] = retryMap[EMERGENCY_STOP]!! + 1
manualControl(onSuccess, onError)
} else {
onError.invoke("emergencyStop result is null")
}
}
}
onError {
if (retryMap[EMERGENCY_STOP]!! <= 3) {
retryMap[EMERGENCY_STOP] = retryMap[EMERGENCY_STOP]!! + 1
manualControl(onSuccess, onError)
} else if (it.message != null) {
onError.invoke(it.message!!)
}
}
}
}
fun takeOverRequest(onSuccess: (() -> Unit), onError: ((String) -> Unit)) {
request<BaseResponse<Any>> {
start {
retryMap[TAKE_OVER_REQUEST] = retryMap[TAKE_OVER_REQUEST] ?: 0 + 1
}
loader {
apiCall {
val map = mutableMapOf<String, Any>()
map["sn"] = MoGoAiCloudClientConfig.getInstance().sn
map["type"] = TAKE_OVER_REQUEST
map["plateNumber"] = AppConfigInfo.plateNumber ?: ""
getNetWorkApi().takeOver(map)
}
}
onSuccess {
if (it.result != null) {
retryMap.remove(TAKE_OVER_REQUEST)
onSuccess.invoke()
} else {
if (retryMap[TAKE_OVER_REQUEST]!! <= 3) {
retryMap[TAKE_OVER_REQUEST] = retryMap[TAKE_OVER_REQUEST]!! + 1
manualControl(onSuccess, onError)
} else {
onError.invoke("takeOverRequest result is null")
}
}
}
onError {
if (retryMap[TAKE_OVER_REQUEST]!! <= 3) {
retryMap[TAKE_OVER_REQUEST] = retryMap[TAKE_OVER_REQUEST]!! + 1
manualControl(onSuccess, onError)
} else if (it.message != null) {
onError.invoke(it.message!!)
}
}
}
}
}

View File

@@ -17,7 +17,6 @@ class StartUpTraceNetWorkModel {
.create(TraceStartUpApiService::class.java)
}
private var retryTime = 0
private var success: ((String) -> Unit)? = null
private var error: ((String) -> Unit)? = null
@Volatile
@@ -29,7 +28,8 @@ class StartUpTraceNetWorkModel {
onError: ((String) -> Unit)? = null
) {
request<BaseResponse<String>> {
var map: MutableMap<String, Any> = mutableMapOf()
var retryTime = 0
var map: MutableMap<String, Any>
start {
if (success == null) {
success = onSuccess
@@ -54,11 +54,13 @@ class StartUpTraceNetWorkModel {
onSuccess {
if (it.result != null) {
onSuccess?.invoke(it.result)
traceId = ""
} else {
if (retryTime < 3) {
retryTime += 1
report()
report(id)
} else {
traceId = ""
error?.invoke("startUp report error msg is null")
}
}
@@ -66,13 +68,13 @@ class StartUpTraceNetWorkModel {
onError {
if (retryTime < 3) {
retryTime += 1
report()
report(id)
} else if (it.message != null) {
traceId = ""
error?.invoke(it.message ?: "startUp report error msg is null")
}
}
}
}
}

View File

@@ -0,0 +1,79 @@
package com.mogo.eagle.core.function.hmi.ui.setting
import android.content.Context
import android.util.AttributeSet
import android.view.LayoutInflater
import androidx.constraintlayout.widget.ConstraintLayout
import com.mogo.eagle.core.function.call.autopilot.CallerAutoPilotControlManager
import com.mogo.eagle.core.function.call.setting.CallerSeatPressureManager
import com.mogo.eagle.core.function.hmi.R
import kotlinx.android.synthetic.main.view_seat_pressure_setting.view.tb_co_driver
import kotlinx.android.synthetic.main.view_seat_pressure_setting.view.tb_main_driver
import kotlinx.android.synthetic.main.view_seat_pressure_setting.view.tb_rear_row
/**
* 座椅压力设置页面(设座位是否有人)
*/
class SeatPressureSettingView @JvmOverloads constructor(
context: Context,
attrs: AttributeSet? = null,
defStyleAttr: Int = 0
) : ConstraintLayout(context, attrs, defStyleAttr) {
companion object {
const val TAG = "SeatPressureSettingView"
}
private var mainDriverStatus = false //主驾是否有人,默认没人
private var coDriverStatus = false //副驾是否有人,默认没人
private var rearRowStatus = false //后排是否有人,默认没人
init {
LayoutInflater.from(context).inflate(R.layout.view_seat_pressure_setting, this, true)
initView()
}
private fun initView(){
//主驾
tb_main_driver.isChecked = mainDriverStatus
tb_main_driver.setOnCheckedChangeListener{compoundButton, isChecked ->
if(!compoundButton.isPressed){
return@setOnCheckedChangeListener
}
mainDriverStatus = isChecked
CallerAutoPilotControlManager.sendSeatPressure(mainDriverStatus,coDriverStatus,rearRowStatus)
updateBtnBg(mainDriverStatus,coDriverStatus,rearRowStatus)
}
//副驾
tb_co_driver.isChecked = coDriverStatus
tb_co_driver.setOnCheckedChangeListener{compoundButton, isChecked ->
if(!compoundButton.isPressed){
return@setOnCheckedChangeListener
}
coDriverStatus = isChecked
CallerAutoPilotControlManager.sendSeatPressure(mainDriverStatus,coDriverStatus,rearRowStatus)
updateBtnBg(mainDriverStatus,coDriverStatus,rearRowStatus)
}
//后排
tb_rear_row.isChecked = rearRowStatus
tb_rear_row.setOnCheckedChangeListener{compoundButton, isChecked ->
if(!compoundButton.isPressed){
return@setOnCheckedChangeListener
}
rearRowStatus = isChecked
CallerAutoPilotControlManager.sendSeatPressure(mainDriverStatus,coDriverStatus,rearRowStatus)
updateBtnBg(mainDriverStatus,coDriverStatus,rearRowStatus)
}
}
private fun updateBtnBg(driver: Boolean,copilot: Boolean,backRow: Boolean){
if(driver || copilot || backRow){
//主驾、副驾、后排只要有一个位置有人则开关按钮就显示有人状态
CallerSeatPressureManager.invokeUpdateBgEvent(true)
}else{
//所有座位都没有人则显示无人状态
CallerSeatPressureManager.invokeUpdateBgEvent(false)
}
}
}

View File

@@ -1,6 +1,7 @@
package com.mogo.eagle.core.function.hmi.ui.vehicle
import android.content.Context
import android.os.CountDownTimer
import android.util.AttributeSet
import android.util.TypedValue.COMPLEX_UNIT_PX
import android.view.LayoutInflater
@@ -21,6 +22,7 @@ import com.mogo.eagle.core.function.call.autopilot.CallerAutoPilotStatusListener
import com.mogo.eagle.core.function.call.autopilot.CallerPlanningActionsListenerManager
import com.mogo.eagle.core.function.call.v2x.CallerTrafficLightListenerManager
import com.mogo.eagle.core.function.hmi.R
import com.mogo.eagle.core.utilcode.util.SoundPoolUtils
import com.mogo.eagle.core.utilcode.util.UiThreadHandler
import com.zhjt.service_biz.BizConfig
import kotlinx.android.synthetic.main.view_pnc_actions.view.*
@@ -122,6 +124,24 @@ class PncActionsView @JvmOverloads constructor(
AppCompatResources.getDrawable(context, bgResources)
tvHmiPncActions.text = actions
}
//voice tip
if(actions == "已超出ODD"){
val countDownTimer = object : CountDownTimer(3000, 1000){
override fun onTick(p0: Long) {
try {
SoundPoolUtils.getSoundPool().playSoundWithRedId(context,R.raw.weak_net_tips)
}catch (e: Exception){
e.printStackTrace()
}
}
override fun onFinish() {
}
}
countDownTimer.start()
}
} else {
tvHmiPncActions.background = null
tvHmiPncActions.text = ""

View File

@@ -0,0 +1,259 @@
package com.mogo.eagle.core.function.hmi.ui.vehicle
import android.annotation.SuppressLint
import android.app.Activity
import android.graphics.PixelFormat
import android.util.DisplayMetrics
import android.view.Gravity
import android.view.LayoutInflater
import android.view.MotionEvent
import android.view.View
import android.view.WindowManager
import android.widget.Button
import android.widget.ToggleButton
import com.mogo.eagle.core.data.enums.EventTypeEnumNew
import com.mogo.eagle.core.data.msgbox.AutopilotMsg
import com.mogo.eagle.core.data.msgbox.MsgBoxBean
import com.mogo.eagle.core.data.msgbox.MsgBoxType
import com.mogo.eagle.core.data.takeover.TAKE_OVER_REQUEST
import com.mogo.eagle.core.function.api.hmi.warning.IMoGoWarningStatusListener
import com.mogo.eagle.core.function.call.autopilot.CallerAutoPilotControlManager
import com.mogo.eagle.core.function.call.devatools.CallerDevaToolsManager
import com.mogo.eagle.core.function.call.hmi.CallerHmiManager
import com.mogo.eagle.core.function.call.msgbox.CallerMsgBoxManager
import com.mogo.eagle.core.function.call.setting.CallerTakeOverManager
import com.mogo.eagle.core.function.hmi.R
import com.mogo.eagle.core.utilcode.util.BarUtils
import com.mogo.eagle.core.utilcode.util.SPUtils
import com.mogo.eagle.core.utilcode.util.SoundUtils
import kotlinx.android.synthetic.main.view_remote_take_over_autopilot.view.*
import kotlinx.android.synthetic.main.view_sop_setting.view.*
class TakeOverAutopilotView constructor(activity: Activity):View.OnTouchListener {
private var takeOverRequest: Boolean = false
private var mActivity: Activity = activity
private lateinit var mFloatLayout: View
private var mWindowParams: WindowManager.LayoutParams? = null
private var mWindowManager: WindowManager? = null
private var mInViewX = 0f
private var mInViewY = 0f
private var mInScreenX = 0f
private var mInScreenY = 0f
private lateinit var btnManualControl: Button
private lateinit var btnOverTake: Button
private lateinit var btnLineToLeft: Button
private lateinit var btnLineToRight: Button
private lateinit var btnPullOver: Button
private lateinit var btnEmergencyStop: Button
private lateinit var btnTakeOverRequest: Button
private lateinit var btnTakeOverRecover: Button
private lateinit var tbLaneChange: ToggleButton
private lateinit var tbAeb: ToggleButton
private lateinit var tbStopYield: ToggleButton
private lateinit var tbMapSpeed: ToggleButton
private lateinit var tbRamp: ToggleButton
init {
initView()
}
private fun initView() {
mFloatLayout = LayoutInflater.from(mActivity).inflate(R.layout.view_remote_take_over_autopilot, null) as View
mFloatLayout.setOnTouchListener(this)
btnManualControl = mFloatLayout.findViewById(R.id.btn_manual_control)
btnOverTake = mFloatLayout.findViewById(R.id.btn_over_take)
btnLineToLeft = mFloatLayout.findViewById(R.id.btn_line_to_left)
btnLineToRight = mFloatLayout.findViewById(R.id.btn_line_to_right)
btnPullOver = mFloatLayout.findViewById(R.id.btn_pull_over)
btnEmergencyStop = mFloatLayout.findViewById(R.id.btn_emergency_stop)
btnTakeOverRequest = mFloatLayout.findViewById(R.id.btn_take_over_request)
btnTakeOverRecover = mFloatLayout.findViewById(R.id.btn_take_over_recover)
tbLaneChange = mFloatLayout.findViewById(R.id.tb_lane_change)
tbAeb = mFloatLayout.findViewById(R.id.tb_aeb)
tbStopYield = mFloatLayout.findViewById(R.id.tb_stop_yield)
tbMapSpeed = mFloatLayout.findViewById(R.id.tb_map_speed)
tbRamp = mFloatLayout.findViewById(R.id.tb_ramp)
//人工接管
btnManualControl.setOnClickListener {
// 退出自驾
CallerAutoPilotControlManager.cancelAutoPilot()
// CallerDevaToolsManager.takeOver(MANUAL_CONTROL)
}
//超车
btnOverTake.setOnClickListener {
// 超车
CallerAutoPilotControlManager.sendPlanningLineChangeCmd(3)
// CallerDevaToolsManager.takeOver(OVER_TAKE)
}
btnLineToLeft.setOnClickListener {
// 向左变道
CallerAutoPilotControlManager.sendPlanningLineChangeCmd(1)
// CallerDevaToolsManager.takeOver(LINE_TO_LEFT)
}
btnLineToRight.setOnClickListener {
// 向右变道
CallerAutoPilotControlManager.sendPlanningLineChangeCmd(2)
// CallerDevaToolsManager.takeOver(LINE_TO_RIGHT)
}
btnPullOver.setOnClickListener {
// 靠边停车
CallerAutoPilotControlManager.sendPlanningPullOverCmd(1)
// CallerDevaToolsManager.takeOver(PULL_OVER)
}
btnEmergencyStop.setOnClickListener {
// 紧急停车
CallerAutoPilotControlManager.sendPlanningPullOverCmd(3)
// CallerDevaToolsManager.takeOver(EMERGENCY_STOP)
}
//接管请求
btnTakeOverRequest.setOnClickListener {
// takeOverRequest 执行时,避免多次提示
if (takeOverRequest) {
return@setOnClickListener
}
// 接管请求提示
CallerDevaToolsManager.takeOver(TAKE_OVER_REQUEST)
CallerHmiManager.warningV2X(
EventTypeEnumNew.TAKE_OVER_EVENT.poiType,
EventTypeEnumNew.TAKE_OVER_EVENT.content,
EventTypeEnumNew.TAKE_OVER_EVENT.tts,
object : IMoGoWarningStatusListener {
override fun onShow() {
takeOverRequest = true
CallerTakeOverManager.invokeTakeOverEvent(true)
//加入消息盒子
CallerMsgBoxManager.saveMsgBox(
MsgBoxBean(
MsgBoxType.AUTOPILOT, AutopilotMsg(
EventTypeEnumNew.TAKE_OVER_EVENT.poiType.toInt(),
EventTypeEnumNew.TAKE_OVER_EVENT.content,
EventTypeEnumNew.TAKE_OVER_EVENT.tts,
System.currentTimeMillis()
)
)
)
}
override fun onDismiss() {
takeOverRequest = false
CallerTakeOverManager.invokeTakeOverEvent(false)
}
},expireTime =3000L, isFromObu = false
)
SoundUtils.playRing(mActivity)
}
//恢复自动决策
btnTakeOverRecover.setOnClickListener {
CallerAutoPilotControlManager.sendPlanningLineChangeCmd(4)
return@setOnClickListener
}
//AEB开关
tbAeb.isChecked = SPUtils.getInstance().getBoolean("aeb",false)
tbAeb.setOnCheckedChangeListener{ compoundButton, isChecked ->
if(!compoundButton.isPressed){
return@setOnCheckedChangeListener
}
CallerAutoPilotControlManager.sendAebCmd(isChecked)
SPUtils.getInstance().put("aeb",isChecked)
}
//绕障开关
tbLaneChange.isChecked = SPUtils.getInstance().getBoolean("lane_change",false)
tbLaneChange.setOnCheckedChangeListener{ compoundButton, isChecked ->
if(!compoundButton.isPressed){
return@setOnCheckedChangeListener
}
CallerAutoPilotControlManager.sendLaneChangeRestrainValid(isChecked)
SPUtils.getInstance().put("lane_change",isChecked)
}
//停车让行开关
tbStopYield.isChecked = SPUtils.getInstance().getBoolean("stop_yield",false)
tbStopYield.setOnCheckedChangeListener{ compoundButton, isChecked ->
if(!compoundButton.isPressed){
return@setOnCheckedChangeListener
}
CallerAutoPilotControlManager.sendStopYieldValid(isChecked)
SPUtils.getInstance().put("stop_yield",isChecked)
}
//地图限速开关
tbMapSpeed.isChecked = SPUtils.getInstance().getBoolean("map_speed",false)
tbMapSpeed.setOnCheckedChangeListener { compoundButton, isChecked ->
if(!compoundButton.isPressed){
return@setOnCheckedChangeListener
}
CallerAutoPilotControlManager.sendHadmapSpeedLimitValid(isChecked)
SPUtils.getInstance().put("map_speed",isChecked)
}
//环岛模式
tbRamp.isChecked = SPUtils.getInstance().getBoolean("ramp",false)
tbRamp.setOnCheckedChangeListener { compoundButton, isChecked ->
if(!compoundButton.isPressed){
return@setOnCheckedChangeListener
}
CallerAutoPilotControlManager.sendRampThetaValid(isChecked)
SPUtils.getInstance().put("ramp",isChecked)
}
mWindowParams = WindowManager.LayoutParams()
mWindowManager = mActivity.windowManager
mWindowParams?.let {
it.format = PixelFormat.RGBA_8888
it.flags = WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL
it.gravity = Gravity.START or Gravity.TOP
it.width = 700
it.height = 900
it.alpha = 1.0f
}
}
@SuppressLint("ClickableViewAccessibility")
override fun onTouch(v: View?, motionEvent: MotionEvent?): Boolean {
when (motionEvent?.action) {
MotionEvent.ACTION_DOWN -> {
// 获取相对View的坐标即以此View左上角为原点
mInViewX = motionEvent.x
mInViewY = motionEvent.y
// 获取相对屏幕的坐标,即以屏幕左上角为原点
mInScreenX = motionEvent.rawX
mInScreenY = motionEvent.rawY
}
MotionEvent.ACTION_MOVE -> {
// 更新浮动窗口位置参数
mInScreenX = motionEvent.rawX
mInScreenY = motionEvent.rawY
// if(((mInScreenX - mInViewX)-mWindowParams!!.x).absoluteValue>150 || ((mInScreenY - mInViewY)-mWindowParams!!.y).absoluteValue>150){
// return true
// }
mWindowParams!!.x = (mInScreenX - mInViewX).toInt()
mWindowParams!!.y = (mInScreenY - mInViewY).toInt()
// 手指移动的时候更新小悬浮窗的位置
mWindowManager!!.updateViewLayout(mFloatLayout, mWindowParams)
}
}
return true
}
fun showFloatWindow() {
if (mFloatLayout.parent == null) {
val metrics = DisplayMetrics()
// 默认固定位置,靠屏幕右边缘的中间
mWindowManager!!.defaultDisplay.getMetrics(metrics)
mWindowParams!!.x = metrics.widthPixels
mWindowParams!!.y = metrics.heightPixels - BarUtils.getStatusBarHeight()-1140
mWindowManager!!.addView(mFloatLayout, mWindowParams)
}
}
fun hideFloatWindow() {
if (mFloatLayout.parent != null){
mWindowManager!!.removeView(mFloatLayout)
}
}
}

View File

@@ -14,10 +14,12 @@ import com.mogo.eagle.core.data.msgbox.V2XMsg
import com.mogo.eagle.core.function.api.autopilot.IMoGoAutopilotStatusListener
import com.mogo.eagle.core.function.api.autopilot.IMoGoParallelDrivingStatusListener
import com.mogo.eagle.core.function.api.hmi.warning.IMoGoWarningStatusListener
import com.mogo.eagle.core.function.api.setting.ITakeOverEventListener
import com.mogo.eagle.core.function.call.autopilot.CallerAutoPilotStatusListenerManager
import com.mogo.eagle.core.function.call.autopilot.CallerParallelDrivingListenerManager
import com.mogo.eagle.core.function.call.hmi.CallerHmiManager
import com.mogo.eagle.core.function.call.msgbox.CallerMsgBoxManager.saveMsgBox
import com.mogo.eagle.core.function.call.setting.CallerTakeOverManager
import com.mogo.eagle.core.function.hmi.R
import com.mogo.eagle.core.utilcode.mogo.AppIdentityModeUtils
import com.mogo.eagle.core.utilcode.mogo.logger.CallerLogger
@@ -33,7 +35,7 @@ class TakeOverView @JvmOverloads constructor(
attrs: AttributeSet? = null,
defStyleAttr: Int = 0
) : ConstraintLayout(context, attrs, defStyleAttr), IMoGoAutopilotStatusListener,
IMoGoParallelDrivingStatusListener {
IMoGoParallelDrivingStatusListener,ITakeOverEventListener {
companion object {
const val TAG = "TakeOverView"
@@ -54,6 +56,7 @@ class TakeOverView @JvmOverloads constructor(
super.onAttachedToWindow()
CallerAutoPilotStatusListenerManager.addListener(TAG, this)
CallerParallelDrivingListenerManager.addListener(TAG,this)
CallerTakeOverManager.addListener(TAG,this)
}
override fun onAutopilotStatusResponse(state: Int) {
@@ -169,6 +172,7 @@ class TakeOverView @JvmOverloads constructor(
super.onDetachedFromWindow()
CallerAutoPilotStatusListenerManager.removeListener(TAG)
CallerParallelDrivingListenerManager.removeListener(TAG)
CallerTakeOverManager.removeListener(TAG)
}
/**
@@ -300,4 +304,14 @@ class TakeOverView @JvmOverloads constructor(
}
}
override fun onTakeOverEvent(isShow: Boolean) {
ThreadUtils.runOnUiThread {
if(isShow){
this@TakeOverView.visibility = View.VISIBLE
}else{
this@TakeOverView.visibility = View.GONE
}
}
}
}

View File

@@ -0,0 +1,10 @@
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle">
<corners android:radius="@dimen/dp_20" />
<gradient
android:startColor="#323C6F"
android:endColor="#323C6F"
android:angle="315"
/>
</shape>

View File

@@ -0,0 +1,8 @@
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android">
<gradient
android:startColor="#A7D3F6"
android:endColor="#8C9AFF"
/>
<corners android:radius="20px" />
</shape>

View File

@@ -0,0 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android">
<solid android:color="@color/color_80FFFFFF"/>
<corners android:radius="20px" />
</shape>

View File

@@ -0,0 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android">
<solid android:color="#FFFFFF"/>
<corners android:radius="20px" />
</shape>

View File

@@ -0,0 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android">
<solid android:color="#80FFFFFF"/>
<corners android:radius="@dimen/dp_20" />
</shape>

View File

@@ -0,0 +1,8 @@
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android">
<gradient
android:startColor="#029DFF"
android:endColor="#0056FF"
/>
<corners android:radius="@dimen/dp_20" />
</shape>

View File

@@ -0,0 +1,7 @@
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:drawable="@drawable/seat_pressure_item_press_bg" android:state_pressed="true"/>
<item android:drawable="@drawable/seat_pressure_item_press_bg" android:state_checked="true"/>
<item android:drawable="@drawable/seat_pressure_item_normal_bg" android:state_pressed="false"/>
<item android:drawable="@drawable/seat_pressure_item_normal_bg" />
</selector>

View File

@@ -0,0 +1,7 @@
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:drawable="@drawable/remote_take_over_item_press_bg" android:state_pressed="true"/>
<item android:drawable="@drawable/remote_take_over_item_press_bg" android:state_checked="true"/>
<item android:drawable="@drawable/remote_take_over_item_bg" android:state_pressed="false"/>
<item android:drawable="@drawable/remote_take_over_item_bg" />
</selector>

View File

@@ -0,0 +1,199 @@
<?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"
android:layout_width="@dimen/dp_700"
android:layout_height="@dimen/dp_900"
android:background="@drawable/bg_remote_take"
>
<Button
android:id="@+id/btn_manual_control"
style="?android:attr/borderlessButtonStyle"
android:layout_width="@dimen/dp_502"
android:layout_height="@dimen/dp_90"
android:layout_marginTop="@dimen/dp_20"
android:background="@drawable/remote_take_over_autopilot_bg"
android:gravity="center"
android:text="@string/hmi_take_over"
android:textColor="#FF181D6D"
android:textSize="@dimen/sp_34"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<Button
android:id="@+id/btn_over_take"
android:layout_width="@dimen/dp_147"
android:layout_height="@dimen/dp_90"
android:layout_marginTop="@dimen/dp_30"
android:background="@drawable/selector_take_over_item"
android:gravity="center"
android:text="@string/hmi_over_take"
android:textColor="#FF181D6D"
android:textSize="@dimen/sp_30"
app:layout_constraintStart_toStartOf="@+id/btn_manual_control"
app:layout_constraintTop_toBottomOf="@+id/btn_manual_control" />
<Button
android:id="@+id/btn_line_to_left"
android:layout_width="@dimen/dp_147"
android:layout_height="@dimen/dp_90"
android:layout_marginTop="@dimen/dp_30"
android:gravity="center"
android:background="@drawable/selector_take_over_item"
android:text="@string/hmi_line_to_left"
android:textColor="#FF181D6D"
android:textSize="@dimen/sp_30"
app:layout_constraintEnd_toStartOf="@+id/btn_line_to_right"
app:layout_constraintStart_toEndOf="@+id/btn_over_take"
app:layout_constraintTop_toBottomOf="@+id/btn_manual_control" />
<Button
android:id="@+id/btn_line_to_right"
android:layout_width="@dimen/dp_147"
android:layout_height="@dimen/dp_90"
android:layout_marginTop="@dimen/dp_30"
android:gravity="center"
android:background="@drawable/selector_take_over_item"
android:text="@string/hmi_line_to_right"
android:textColor="#FF181D6D"
android:textSize="@dimen/sp_30"
app:layout_constraintEnd_toEndOf="@+id/btn_manual_control"
app:layout_constraintTop_toBottomOf="@+id/btn_manual_control" />
<Button
android:id="@+id/btn_pull_over"
android:layout_width="@dimen/dp_147"
android:layout_height="@dimen/dp_90"
android:layout_marginTop="@dimen/dp_30"
android:gravity="center"
android:background="@drawable/selector_take_over_item"
android:text="@string/hmi_pull_over"
android:textColor="#FF181D6D"
android:textSize="@dimen/sp_30"
app:layout_constraintStart_toStartOf="@+id/btn_manual_control"
app:layout_constraintTop_toBottomOf="@+id/btn_over_take" />
<Button
android:id="@+id/btn_emergency_stop"
android:layout_width="@dimen/dp_147"
android:layout_height="@dimen/dp_90"
android:layout_marginTop="@dimen/dp_30"
android:gravity="center"
android:background="@drawable/selector_take_over_item"
android:text="@string/hmi_emergency_stop"
android:textColor="#FF181D6D"
android:textSize="@dimen/sp_30"
app:layout_constraintEnd_toStartOf="@+id/btn_line_to_right"
app:layout_constraintStart_toEndOf="@+id/btn_over_take"
app:layout_constraintTop_toBottomOf="@+id/btn_line_to_left" />
<Button
android:id="@+id/btn_take_over_request"
android:layout_width="@dimen/dp_147"
android:layout_height="@dimen/dp_90"
android:layout_marginTop="@dimen/dp_30"
android:gravity="center"
android:background="@drawable/selector_take_over_item"
android:text="@string/hmi_take_over_request"
android:textColor="#FF181D6D"
android:textSize="@dimen/sp_30"
app:layout_constraintEnd_toEndOf="@+id/btn_manual_control"
app:layout_constraintTop_toBottomOf="@+id/btn_line_to_right" />
<Button
android:id="@+id/btn_take_over_recover"
android:layout_width="@dimen/dp_230"
android:layout_height="@dimen/dp_90"
android:layout_marginTop="@dimen/dp_30"
android:gravity="center"
android:background="@drawable/selector_take_over_item"
android:text="@string/hmi_take_over_recover"
android:textColor="#FF181D6D"
android:textSize="@dimen/sp_30"
app:layout_constraintTop_toBottomOf="@+id/btn_emergency_stop"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toLeftOf="@id/tb_lane_change"
/>
<ToggleButton
android:id="@+id/tb_lane_change"
android:layout_width="@dimen/dp_230"
android:layout_height="@dimen/dp_90"
android:layout_marginTop="@dimen/dp_30"
app:layout_constraintTop_toBottomOf="@id/btn_emergency_stop"
app:layout_constraintLeft_toRightOf="@id/btn_take_over_recover"
app:layout_constraintRight_toRightOf="parent"
android:background="@drawable/selector_take_over_item"
android:textOff="@string/hmi_open_lane_change"
android:textOn="@string/hmi_close_lane_change"
android:textColor="#FF181D6D"
android:textSize="@dimen/sp_30"
android:gravity="center"
/>
<ToggleButton
android:id="@+id/tb_aeb"
android:layout_width="@dimen/dp_230"
android:layout_height="@dimen/dp_90"
android:layout_marginTop="@dimen/dp_30"
app:layout_constraintTop_toBottomOf="@id/tb_lane_change"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toLeftOf="@id/tb_stop_yield"
android:background="@drawable/selector_take_over_item"
android:textOff="@string/hmi_open_aeb"
android:textOn="@string/hmi_close_aeb"
android:textColor="#FF181D6D"
android:textSize="@dimen/sp_30"
android:gravity="center"
/>
<ToggleButton
android:id="@+id/tb_stop_yield"
android:layout_width="@dimen/dp_230"
android:layout_height="@dimen/dp_90"
android:layout_marginTop="@dimen/dp_30"
app:layout_constraintTop_toBottomOf="@id/tb_lane_change"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintLeft_toRightOf="@id/tb_aeb"
android:background="@drawable/selector_take_over_item"
android:textOff="@string/hmi_open_stop_yield"
android:textOn="@string/hmi_close_stop_yield"
android:textColor="#FF181D6D"
android:textSize="@dimen/sp_30"
android:gravity="center"
/>
<ToggleButton
android:id="@+id/tb_map_speed"
android:layout_width="@dimen/dp_230"
android:layout_height="@dimen/dp_90"
android:layout_marginTop="@dimen/dp_30"
app:layout_constraintTop_toBottomOf="@id/tb_aeb"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toLeftOf="@id/tb_ramp"
android:background="@drawable/selector_take_over_item"
android:textOff="@string/hmi_open_map_speed"
android:textOn="@string/hmi_close_map_speed"
android:textColor="#FF181D6D"
android:textSize="@dimen/sp_30"
android:gravity="center"
/>
<ToggleButton
android:id="@+id/tb_ramp"
android:layout_width="@dimen/dp_230"
android:layout_height="@dimen/dp_90"
android:layout_marginTop="@dimen/dp_30"
app:layout_constraintTop_toBottomOf="@id/tb_aeb"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintLeft_toRightOf="@id/tb_map_speed"
android:background="@drawable/selector_take_over_item"
android:textOff="@string/hmi_open_ramp"
android:textOn="@string/hmi_close_ramp"
android:textColor="#FF181D6D"
android:textSize="@dimen/sp_30"
android:gravity="center"
/>
</androidx.constraintlayout.widget.ConstraintLayout>

View File

@@ -0,0 +1,49 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:background="@drawable/bg_seat_pressure_setting"
>
<ToggleButton
android:id="@+id/tb_main_driver"
android:layout_width="@dimen/dp_180"
android:layout_height="@dimen/dp_80"
android:textOff="@string/hmi_main_driver"
android:textOn="@string/hmi_main_driver"
android:textColor="@color/white"
android:textSize="@dimen/sp_30"
android:gravity="center"
android:background="@drawable/selector_seat_pressure_item"
android:layout_margin="@dimen/dp_20"
/>
<ToggleButton
android:id="@+id/tb_co_driver"
android:layout_width="@dimen/dp_180"
android:layout_height="@dimen/dp_80"
android:textOff="@string/hmi_co_driver"
android:textOn="@string/hmi_co_driver"
android:textColor="@color/white"
android:textSize="@dimen/sp_30"
android:gravity="center"
android:background="@drawable/selector_seat_pressure_item"
android:layout_margin="@dimen/dp_20"
/>
<ToggleButton
android:id="@+id/tb_rear_row"
android:layout_width="@dimen/dp_180"
android:layout_height="@dimen/dp_80"
android:textOff="@string/hmi_rear_row"
android:textOn="@string/hmi_rear_row"
android:textColor="@color/white"
android:textSize="@dimen/sp_30"
android:gravity="center"
android:background="@drawable/selector_seat_pressure_item"
android:layout_margin="@dimen/dp_20"
/>
</LinearLayout>

View File

@@ -46,7 +46,7 @@
<color name="foreground_debug">#FF333333</color>
<color name="foreground_info">#FF333333</color>
<color name="foreground_warn">#FFCCCCCC</color>
<color name="color_80FFFFFF">#80FFFFFF</color>

View File

@@ -130,4 +130,27 @@
<string name="road_cross_live_tip">蘑菇为您实时护航中,请放心驾驶!</string>
<string name="hmi_take_over">人工接管</string>
<string name="hmi_over_take">超车</string>
<string name="hmi_line_to_left">向左变道</string>
<string name="hmi_line_to_right">向右变道</string>
<string name="hmi_pull_over">靠边停车</string>
<string name="hmi_emergency_stop">应急停车</string>
<string name="hmi_take_over_request">接管请求</string>
<string name="hmi_take_over_recover">恢复自动决策</string>
<string name="hmi_open_lane_change">障碍物模式</string>
<string name="hmi_close_lane_change">障碍物模式</string>
<string name="hmi_open_aeb">制动模式</string>
<string name="hmi_close_aeb">制动模式</string>
<string name="hmi_open_stop_yield">停车</string>
<string name="hmi_close_stop_yield">停车</string>
<string name="hmi_open_map_speed">限速模式</string>
<string name="hmi_close_map_speed">限速模式</string>
<string name="hmi_open_ramp">环岛模式</string>
<string name="hmi_close_ramp">环岛模式</string>
<string name="hmi_main_driver">主驾</string>
<string name="hmi_co_driver">副驾</string>
<string name="hmi_rear_row">后排</string>
</resources>