Commit dc53ac12 authored by p x's avatar p x
Browse files

调通车辆位姿

parent 1b8c1b49
......@@ -78,6 +78,7 @@ dependencies {
androidTestImplementation(libs.androidx.junit)
androidTestImplementation(libs.androidx.espresso.core)
implementation("io.github.cymchad:BaseRecyclerViewAdapterHelper4:4.1.7")
implementation("com.jakewharton.rxbinding4:rxbinding:4.0.0")
//屏幕适配
implementation("com.github.JessYanCoding:AndroidAutoSize:v1.2.1")
......
This diff is collapsed.
This source diff could not be displayed because it is too large. You can view the blob instead.
This source diff could not be displayed because it is too large. You can view the blob instead.
package com.sd.cavphmi.adapter
import android.content.Context
import android.view.LayoutInflater
import android.view.ViewGroup
import androidx.recyclerview.widget.RecyclerView
import com.chad.library.adapter4.BaseQuickAdapter
import com.sd.cavphmi.databinding.BindCarListBinding
class BindCarAdapter :
BaseQuickAdapter<String, BindCarAdapter.BcVh>() {
override fun onCreateViewHolder(
context: Context,
parent: ViewGroup,
viewType: Int
): BcVh {
return BcVh(parent)
}
override fun onBindViewHolder(
holder: BcVh,
position: Int,
item: String?
) {
holder.show(item!!)
}
inner class BcVh(
parent: ViewGroup,
val binding: BindCarListBinding = BindCarListBinding.inflate(
LayoutInflater.from(parent.context),
parent,
false
)
) : RecyclerView.ViewHolder(binding.root) {
private var tvPlate = binding.tvPlate
fun show(str: String) {
tvPlate.text = str
}
}
}
\ No newline at end of file
......@@ -9,12 +9,11 @@ package com.sd.cavphmi.bean
*/
data class AvpStatuBean(
val businessType: String,
val businessStatus: String,
val drivenDecision: DrivenDecision,
// val exceptionCode: Any,
// val exceptionMessage: Any,
val haulingNo: String,
// val haulingStageState: String,
// val haulingNo: String,
val haulingStageState: String,//任务状态
val space: Space,
val spaceId: String,
val vehicleContext: VehicleContext,
......
......@@ -32,7 +32,7 @@ class CarPanelBean {
var speed = ObservableField(0)
/***档位**/
var tapPos = ObservableField<Int>(-1)
var tapPos = ObservableField<Int>(7)
// var gear = ObservableField<Int>()
//剩余电量
......
......@@ -12,6 +12,7 @@ import androidx.databinding.BindingAdapter
import com.sd.cavphmi.R
import com.sd.cavphmi.bean.GearStatus
import com.sd.cavphmi.ui.view.HeadAngelView
import com.sd.cavphmi.utils.AvpContants
object ShowCarPanelObject {
......@@ -102,18 +103,29 @@ object ShowCarPanelObject {
}
/***是否自动驾驶***/
/***
* 驾驶模式
* UNKNOWN(0, "未知"),
* AUTOMATIC(1, "自动驾驶"),
* MANUAL(2, "人工驾驶"),
* REMOTE(3, "远程驾驶");
*/
@JvmStatic
@BindingAdapter("showAutoDri")
fun showAutoDri(tv: TextView, auto: Int) {
fun showAutoDri(tv: TextView, auto: String) {
when (auto) {
2, 6 -> {
AvpContants.DRIVE_MODE_UNKNOWN -> {
tv.text = "未知"
}
AvpContants.DRIVE_MODE_AUTOMATIC -> {
tv.text = "自动驾驶"
}
1, 3 -> {
AvpContants.DRIVE_MODE_MANUAL -> {
tv.text = "人工驾驶"
}
AvpContants.DRIVE_MODE_REMOTE -> {
tv.text = "远程驾驶"
}
}
}
......
......@@ -52,7 +52,6 @@ class SimpleSSEClient {
}
val request = build.build()
client.newCall(request).enqueue(object : Callback {
override fun onFailure(call: Call, e: IOException) {
listener?.onError(e)
......@@ -60,7 +59,7 @@ class SimpleSSEClient {
override fun onResponse(call: Call, response: Response) {
if (!response.isSuccessful) {
listener?.onError(IOException("HTTP ${response.code}"))
listener?.onError(IOException("HTTP ${response.code} ${response.message}"))
return
}
calls.add(call)
......@@ -92,11 +91,10 @@ class SimpleSSEClient {
}
}
} catch (e: IOException) {
e.printStackTrace()
} finally {
// response.closeQuietly()
}
}
})
}
......@@ -111,12 +109,14 @@ class SimpleSSEClient {
/**释放连接***/
fun cancelContect() {
CoroutineScope(Dispatchers.Default).launch {
// for (call in calls) {
// call.cancel()
// }
for (call in calls) {
call.cancel()
}
calls.clear()
for (body in responseBodys) {
body.closeQuietly()
}
responseBodys.clear()
}
}
......
......@@ -99,7 +99,7 @@ class AvpDataRepo @Inject constructor(
* 我们车辆位姿数据用的是 车俩基础信息的id 可绑车辆接口 返回的是 avp车俩id
* 所以这里的id 是绑定车辆列表返回的id
*/
fun getAvpStatus(body: RequestBody?, listener: SSESimpleListener?) {
fun getAvpStatus(url: String,body: RequestBody?, listener: SSESimpleListener?) {
simpleSSEClient.startSSE(
"${MyContants.HOST}/api/avpweb/hmi/monitor/v1/taskStatus",
body, listener
......@@ -107,12 +107,9 @@ class AvpDataRepo @Inject constructor(
}
/**获取车辆位姿****/
fun getCarPose(body: RequestBody?, listener: SSESimpleListener?) {
fun getCarPose(url: String, body: RequestBody?, listener: SSESimpleListener?) {
// try {
simpleSSEClient.startSSE(
"${MyContants.HOST}/api/avpweb/hmi/monitor/v1/monitorDrivenStatus",
body, listener
)
simpleSSEClient.startSSE(url, body, listener)
// } catch (e: HttpException) {
//// println("e.message = ${e.message}")
// } catch (e: Exception) {
......
......@@ -2,15 +2,12 @@ package com.sd.cavphmi.ui
import android.content.Intent
import android.os.Bundle
import android.util.TimeUtils
import android.widget.Toast
import androidx.activity.viewModels
import androidx.appcompat.app.AppCompatActivity
import com.jakewharton.rxbinding4.view.clicks
import com.sd.cavphmi.databinding.ActivityLoginBinding
import com.sd.cavphmi.ui.view.CustomListDialog
import com.sd.cavphmi.ui.dialog.SeleBindCarDialog
import com.sd.cavphmi.utils.MyContants
import com.sd.cavphmi.utils.SM4CryptoHelper
import com.sd.cavphmi.viewmodels.LoginVm
import com.sd.cavphmi.viewmodels.MainVm
import dagger.hilt.android.AndroidEntryPoint
......@@ -26,6 +23,10 @@ class LoginActivity : AppCompatActivity() {
private val PWD = "5803d205ac27f33ea5f53afed4eb81880bee49f06129ea5437c1b940d18da8f1"
//车牌号选择
// private lateinit var seleBindCarDialog: SeleBindCarDialog
private val seleBindCarDialog: SeleBindCarDialog by lazy { SeleBindCarDialog.newInstance() }
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
binding = ActivityLoginBinding.inflate(layoutInflater)
......@@ -39,7 +40,9 @@ class LoginActivity : AppCompatActivity() {
// var pp = SM4CryptoHelper.encryptECB(key, pwd.toByteArray())
loginVm.login(user, PWD, 285369).observe(this) {
//获取可绑定车辆
getBinderCars()
if (it == 1) {
getBinderCars()
}
}
}
// HTTP获取车位占用情况
......@@ -64,22 +67,36 @@ class LoginActivity : AppCompatActivity() {
//获取可绑定车辆
private fun getBinderCars() {
// seleBindCarDialog = SeleBindCarDialog.newInstance()
mainVm.getBindCar().observe(this) { bindCars ->
var plateNumbers = bindCars.map { it.plateNumber }
val dialog = CustomListDialog(this, "选择车辆", plateNumbers)
dialog.setOnItemClickListener(object : CustomListDialog.OnItemClickListener {
override fun onItemClick(position: Int, selectedItem: String) {
// Toast.makeText(
// this@LoginActivity,
// "点击了第${position + 1}项: $selectedItem",
// Toast.LENGTH_SHORT
// ).show()
seleBindCarDialog.setPlates(plateNumbers)
seleBindCarDialog.itemClickListener = object : SeleBindCarDialog.OnItemClickListener {
override fun onItemClick(position: Int) {
MyContants.VEHICLEID = bindCars.get(position).id
startActivity(Intent(this@LoginActivity, MainActivity::class.java))
finish()
}
})
dialog.show()
}
if (!seleBindCarDialog.isAdded){
seleBindCarDialog.showNow(supportFragmentManager, "seleBindCarDialog")
}
// val dialog = CustomListDialog(this, "选择车辆", plateNumbers)
// dialog.setOnItemClickListener(object : CustomListDialog.OnItemClickListener {
// override fun onItemClick(position: Int, selectedItem: String) {
//// Toast.makeText(
//// this@LoginActivity,
//// "点击了第${position + 1}项: $selectedItem",
//// Toast.LENGTH_SHORT
//// ).show()
// MyContants.VEHICLEID = bindCars.get(position).id
// startActivity(Intent(this@LoginActivity, MainActivity::class.java))
// finish()
// }
// })
// dialog.show()
}
}
......
......@@ -14,6 +14,7 @@ import com.sd.cavphmi.BR
import com.sd.cavphmi.R
import com.sd.cavphmi.base.BaseActivity
import com.sd.cavphmi.base.MyBaseViewModel
import com.sd.cavphmi.bean.CarVehicle
import com.sd.cavphmi.databinding.ActivityMainBinding
import com.sd.cavphmi.highmap.HighMapApi
import com.sd.cavphmi.highmap.LockStatu
......@@ -24,6 +25,7 @@ import com.sd.cavphmi.intfaces.OnConCan
import com.sd.cavphmi.net.SimpleSSEClient
import com.sd.cavphmi.ui.fragment.CarPanelFragment
import com.sd.cavphmi.ui.fragment.ExoPlayFragment
import com.sd.cavphmi.utils.AvpContants
import com.sd.cavphmi.utils.DisplayUtil
import com.sd.cavphmi.viewmodels.MainVm
import com.sd.cavphmi.viewmodels.MapOpt
......@@ -160,7 +162,11 @@ class MainActivity : BaseActivity<ActivityMainBinding, MyBaseViewModel>() {
override fun getToData() {
//开启websocket
// mainVm.startWS()
getTarget()
//开启2个HTTP sse
getCarVehicle()
getAvpStatus()
//获取车位占用情况
// getSpaceInfo()
}
......@@ -201,30 +207,39 @@ class MainActivity : BaseActivity<ActivityMainBinding, MyBaseViewModel>() {
mainVm.getAvpStatus().observe(this) { avpStatu ->
//业务类型
var businessType = avpStatu.businessType//NIL Park Call
if (businessType == AvpContants.NIL_TYPE)
return@observe
//业务状态
var businessStatus =
avpStatu.businessStatus//NIL WAITING PROCESSING COMPLETED CANCELLED FAILED
var businessStatus = avpStatu.haulingStageState
//获取档位
var gearType = avpStatu.vehicleContext.vehicleDynamic.gearType
//画全局路径,判断车是否到达停车点
//画全局路径
mapOpt.drawAllLines(avpStatu.drivenDecision)
//画小地图小车
mapOpt.drawNavingCar(avpStatu.drivenDecision)
//画终点
mapOpt.addEndMarker(avpStatu.drivenDecision.endPoint)
//小地图路线
mapOpt.drawSmallMapLine(avpStatu.drivenDecision)
//判断在泊车状态下的倒挡绘制倒车路线,改变镜头视角
mapOpt.drawReversePark(businessType, gearType, avpStatu.space)
//生成小地图路线以及二维坐标点
mapOpt.takeSmallMapLine(avpStatu.drivenDecision)
//判断在泊车状态下的倒挡绘制倒车路线,改变镜头视角,,判断车是否到达停车点
mapOpt.drawReversePark(businessStatus, businessType, gearType, avpStatu.space)
//是否显示车位流光效果
mapOpt.showParkLight(businessType, avpStatu.space)
//根据AVP状态判特效是否关闭
mapOpt.showEffectAvpStatu(businessStatus)
//根据AVP任务状态判特效是否关闭
mapOpt.showEffectAvpStatu(businessType, businessStatus)
//重置变量
// resetVariable(businessStatus)
// 是否关闭车内视频
if (businessStatus == "CANCELLED" || businessStatus == "COMPLETED" || businessStatus == "FAILED") {
exoPlayFragment.videoUrl = ""
showVideoFragment(false)
}
// if (businessStatus == "CANCELLED" || businessStatus == "COMPLETED" || businessStatus == "FAILED") {
// exoPlayFragment.videoUrl = ""
// showVideoFragment(false)
// }
}
}
/***重置变量**/
fun resetVariable(businessType: String) {
if (businessType == AvpContants.NIL_TYPE) {
mainVm.isGetVehDetail = false
mapOpt.smallMapLine = false
}
}
......@@ -232,9 +247,11 @@ class MainActivity : BaseActivity<ActivityMainBinding, MyBaseViewModel>() {
private fun getCarVehicle() {
mainVm.subVehicle().observe(this) { car ->
// var car = carBean
if (car.vehiclePos == null)
if (car.vehiclePos == null || car.vehiclePos.count() < 3)
return@observe
// setCarCamera(1)
//画小地图小车
mapOpt.drawSmallCar(car)
//刷新右下角小车位置
mapOpt.showNavingCarPosition(car)
//刷新右下角小地图路径
......@@ -308,11 +325,16 @@ class MainActivity : BaseActivity<ActivityMainBinding, MyBaseViewModel>() {
}
//获取车辆详情,取车内摄像头地址打开左下角的车内视频
private fun getVehDetail() {
private fun getVehDetail(car: CarVehicle?) {
if (car?.businessStatus.equals("EXITED")) {
exoPlayFragment.videoUrl = ""
showVideoFragment(false)
return
}
mainVm.getVehDetail().observe(this) { vehDetail ->
if (vehDetail.result.vehicleInfos.count() == 0)
return@observe
var cameraUrl = vehDetail.result.vehicleInfos?.get(0)?.vehicleVideoUrl
var cameraUrl = vehDetail.result.vehicleInfos.get(0).vehicleVideoUrl
println("---cameraUrl = ${cameraUrl}")
if (exoPlayFragment.videoUrl.isNotEmpty())
return@observe
......@@ -338,7 +360,7 @@ class MainActivity : BaseActivity<ActivityMainBinding, MyBaseViewModel>() {
}
// HTTP获取车辆详情
binding.btVehinfo.setOnClickListener {
getVehDetail()
getVehDetail(null)
}
//v2x 预警
binding.btV2x.setOnClickListener {
......@@ -398,7 +420,6 @@ class MainActivity : BaseActivity<ActivityMainBinding, MyBaseViewModel>() {
}
}
/**
* Show video play
* @param isHide false:隐藏 true:显示
......
package com.sd.cavphmi.ui.dialog
import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.LinearLayout
import androidx.fragment.app.DialogFragment
import com.sd.cavphmi.R
import com.sd.cavphmi.adapter.BindCarAdapter
import com.sd.cavphmi.databinding.SeleBindCarBinding
import com.sd.cavphmi.utils.DisplayUtil
import dagger.hilt.android.AndroidEntryPoint
import javax.inject.Inject
//private const val ARG_PARAM1 = "cars"
/***选择绑定车牌*/
class SeleBindCarDialog : DialogFragment() {
private lateinit var binding: SeleBindCarBinding
interface OnItemClickListener {
// fun onItemClick(position: Int, selectedItem: String)
fun onItemClick(position: Int)
}
var itemClickListener: OnItemClickListener? = null
private var bindCarAdapter: BindCarAdapter = BindCarAdapter()
//车牌号
private var plates: List<String>? = null
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
// window?.setDimAmount(0.5f) override fun onCreate(savedInstanceState: Bundle?) {
// arguments?.let {
// plates = it.getStringArrayList(ARG_PARAM1)
// }
// var dialogWidth = DisplayUtil.getScreenWidthPx().times(0.8).toInt()
// dialog?.window?.setLayout(dialogWidth, ViewGroup.LayoutParams.WRAP_CONTENT)
}
override fun onStart() {
super.onStart()
var window = dialog?.window
window?.setBackgroundDrawableResource(R.color.transparent)
var dialogWidth = DisplayUtil.getScreenWidthPx().times(0.6).toInt()
dialog?.window?.setLayout(
dialogWidth,
LinearLayout.LayoutParams.WRAP_CONTENT
)
}
override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
binding = SeleBindCarBinding.inflate(inflater, container, false)
return binding.root
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
binding.recyclerView.adapter = bindCarAdapter
bindCarAdapter.setOnItemClickListener { adapter, view, position ->
itemClickListener?.onItemClick(position)
dismissNow()
}
}
//设置车牌号
fun setPlates(plates: List<String>) {
this.plates = plates
bindCarAdapter.submitList(plates)
}
companion object {
@JvmStatic
fun newInstance() = SeleBindCarDialog()
// @JvmStatic
// fun newInstance(plates: ArrayList<String>) = SeleBindCarDialog().apply {
// arguments = Bundle().apply {
// putStringArrayList(ARG_PARAM1, plates)
// }
// }
}
}
\ No newline at end of file
......@@ -7,6 +7,7 @@ import com.sd.cavphmi.R
import com.sd.cavphmi.base.BaseFragment
import com.sd.cavphmi.base.MyBaseViewModel
import com.sd.cavphmi.databinding.FragmentCarPanelBinding
import com.sd.cavphmi.utils.AvpContants
import com.sd.cavphmi.viewmodels.CarPanelVM
import com.sd.cavphmi.viewmodels.MainVm
import dagger.hilt.android.AndroidEntryPoint
......@@ -48,10 +49,32 @@ class CarPanelFragment : BaseFragment<FragmentCarPanelBinding, MyBaseViewModel>(
mainVm.carVehicle.observe(this) {
carPanelVM.setCarPanelBean(it)
}
// mainVm.avpStatu.observe(this) {
// var gearType = it.vehicleContext.vehicleDynamic.gearType
// carPanelVM.setGearType(gearType)
// }
mainVm.avpStatu.observe(this) {
var dynamic = it.vehicleContext.vehicleDynamic
//速度
carPanelVM.carPanelBean.speed.set(dynamic.speed.toInt())
//驾驶模式
carPanelVM.carPanelBean.driveMode=dynamic.drivingMode
//档位
var gearType = dynamic.gearType
when (gearType) {
AvpContants.GEAR_NEUTRAL -> {
carPanelVM.carPanelBean.tapPos.set(0)
}
AvpContants.GEAR_PARK -> {
carPanelVM.carPanelBean.tapPos.set(1)
}
AvpContants.GEAR_DRIVE -> {
carPanelVM.carPanelBean.tapPos.set(2)
}
AvpContants.GEAR_REVERSE -> {
carPanelVM.carPanelBean.tapPos.set(3)
}
AvpContants.GEAR_UNKNOWN -> {
carPanelVM.carPanelBean.tapPos.set(7)
}
}
}
}
......
......@@ -13,6 +13,7 @@ import androidx.fragment.app.activityViewModels
import androidx.lifecycle.lifecycleScope
import com.sd.cavphmi.bean.AvpStatuBean
import com.sd.cavphmi.databinding.FragmentDistantTipBinding
import com.sd.cavphmi.utils.AvpContants
import com.sd.cavphmi.utils.MyMapUtils
import com.sd.cavphmi.viewmodels.MainVm
import kotlinx.coroutines.launch
......@@ -71,8 +72,7 @@ class DistantTipFragment : Fragment() {
//业务类型
var businessType = avpStatu.businessType//NIL Park Call
//业务状态
var businessStatus =
avpStatu.businessStatus//NIL WAITING PROCESSING COMPLETED CANCELLED FAILED
var businessStatus = avpStatu.haulingStageState
lifecycleScope.launch {
val vehicleDynamic = avpStatu.vehicleContext.vehicleDynamic
val endPoint = avpStatu.drivenDecision.trajectory.endPoint
......@@ -84,29 +84,23 @@ class DistantTipFragment : Fragment() {
endPoint.longitude
)
if (businessType == "Park") {
if (businessType == AvpContants.Park_TYPE) {
when (businessStatus) {
// "WAITING" -> {
// binding.tvTip.text = "正在前往您的车位,距离终点${distance}m"
// }
"PROCESSING" -> {
AvpContants.TRANSPORT_PROGRESS -> {
takeStr(distance, 1)
}
"COMPLETED" -> {
AvpContants.TRANSPORT_COMPLETED, AvpContants.TRANSPORT_CANCELED, AvpContants.TRANSPORT_ABNORMAL -> {
clearTipStr()
}
}
} else if (businessType == "Call") {
} else if (businessType == AvpContants.CALL_TYPE) {
when (businessStatus) {
// "WAITING" -> {
// binding.tvTip.text = "正在前往您召车点,距离乘客${distance}m"
// }
"PROCESSING" -> {
AvpContants.TRANSPORT_PROGRESS -> {
takeStr(distance, 2)
}
"COMPLETED" -> {
AvpContants.TRANSPORT_COMPLETED, AvpContants.TRANSPORT_CANCELED, AvpContants.TRANSPORT_ABNORMAL -> {
clearTipStr()
}
}
......
......@@ -72,8 +72,8 @@ class ExoPlayFragment : BaseFragment<FragmentExoPlayBinding, MyBaseViewModel>()
private var player: ExoPlayer? = null
var videoUrl = "https://itg-yz.cu-sc.com:13443/video/yizhuang/0b130981fd754f7e817797235f399264.live.flv"
// var videoUrl = ""
// var videoUrl = "https://itg-yz.cu-sc.com:13443/video/yizhuang/0b130981fd754f7e817797235f399264.live.flv"
var videoUrl = ""
//用于测试,实际可以传参进来
// private var videoUri = "https://faw.cuscavp.cn:8443/hdl/live/3.flv"
......
package com.sd.cavphmi.utils
/***AVP 常理**/
object AvpContants {
//业务类型
val NIL_TYPE = "NIL"
val CALL_TYPE = "CALL"
val Park_TYPE = "Park"
//档位
val GEAR_REVERSE = "REVERSE"
val GEAR_NEUTRAL = "NEUTRAL"
val GEAR_PARK = "PARK"
val GEAR_DRIVE = "DRIVE"
val GEAR_UNKNOWN = "UNKNOWN"
/***驾驶模式
* UNKNOWN(0, "未知"),
* AUTOMATIC(1, "自动驾驶"),
* MANUAL(2, "人工驾驶"),
* REMOTE(3, "远程驾驶");
* **/
val DRIVE_MODE_UNKNOWN = "UNKNOWN"
val DRIVE_MODE_AUTOMATIC = "AUTOMATIC"
val DRIVE_MODE_MANUAL = "MANUAL"
val DRIVE_MODE_REMOTE = "REMOTE"
//业务状态
/**
* 运输阶段
* 泊车有两个阶段 运输阶段(从起点到车位前的倒车入库点) 、停车阶段 (从倒车入库点到车位),召车只有一个阶段 运输阶段(从车位到终点)
*/
val TRANSPORT_INIT = "TRANSPORT_INIT"// 运输初始阶段
val TRANSPORT_SUSPEND = "TRANSPORT_SUSPEND"// 运输初始阶段
val TRANSPORT_PROGRESS = "TRANSPORT_PROGRESS" // 运输进行中
val TRANSPORT_WAIT = "TRANSPORT_WAIT" // 运输等待
val TRANSPORT_RESUMING = "TRANSPORT_RESUMING" // 恢复运输
val TRANSPORT_COMPLETED = "TRANSPORT_COMPLETED" // 运输完成
val TRANSPORT_CANCELED = "TRANSPORT_CANCELED"// 取消运输
val TRANSPORT_ABNORMAL = "TRANSPORT_ABNORMAL" // 运输异常
/**
* 停车阶段
*/
val PARK_INIT = "PARK_INIT" // 泊车初始阶段
val PARK_SUSPEND = "PARK_SUSPEND" // 泊车阶段挂起
val PARK_PROGRESS = "PARK_PROGRESS" // 泊车进行中
val PARK_WAIT = "PARK_WAIT" // 泊车等待
val PARK_RESUMING = "PARK_RESUMING" // 泊车恢复
val PARK_COMPLETED = "PARK_COMPLETED" // 泊车完成
val PARK_CANCELED = "PARK_CANCELED" // 取消泊车
val PARK_ABNORMAL = "PARK_ABNORMAL"// 泊车异常
/**
* 人工接管
*/
val MANUAL_TAKEOVER_COMPLETED = "MANUAL_TAKEOVER_COMPLETED"
}
\ No newline at end of file
......@@ -16,7 +16,7 @@ import javax.inject.Inject
class LoginVm @Inject constructor(private var avpDataRepo: AvpDataRepo) : ViewModel() {
//1= 登录成功 0 = 登录失败
var lLogin = MutableLiveData(-1)
var lLogin = MutableLiveData(0)
var loginData = MutableLiveData<String>()
get() = field
set(value) {
......@@ -36,17 +36,18 @@ class LoginVm @Inject constructor(private var avpDataRepo: AvpDataRepo) : ViewMo
pwd: String,
verifyCode: Int
): LiveData<Int> {
lLogin.value = 0
viewModelScope.launch {
var result = avpDataRepo.login(user, pwd, verifyCode)
when (result) {
is MyResult.Success<String> -> {
MyContants.HTTP_TOKEN = result.data
loginData.postValue("true")
lLogin.value = 1
// loginData.postValue("true")
lLogin.postValue(1)
}
else -> {
lLogin.value = 0
lLogin.postValue(0)
}
}
}
......
......@@ -39,7 +39,6 @@ import com.sd.cavphmi.websockets.V2xWSClient
import com.sd.cavphmi.websockets.VecLocWSClient
import dagger.hilt.android.lifecycle.HiltViewModel
import dagger.hilt.android.qualifiers.ApplicationContext
import kotlinx.coroutines.Job
import kotlinx.coroutines.delay
import kotlinx.coroutines.launch
import java.net.URI
......@@ -92,6 +91,9 @@ class MainVm @Inject constructor(
//车辆详情
var vehDetail = MutableLiveData<VehDetailBean>()
//是否获取过车辆详情
var isGetVehDetail = false
//感知目标物
var targetPre = MutableLiveData<PerceptionBean>()
......@@ -110,19 +112,6 @@ class MainVm @Inject constructor(
//获取已绑定车辆列表
var bindCars = MutableLiveData<List<BindResult>>()
// fun startWS() {
// val httpHeaders = mutableMapOf<String, String>()
// httpHeaders.put("Cookie", "username=nemo")
// try {
// client = MyWebSocketClient(URI(MyContants.WS_HOST))
// client?.onSocketCb = onSocketCb
// client?.onDataCb = onDataCb
// client?.connect()
// } catch (e: Exception) {
//
// }
// }
/***清理资源***/
fun cleanRes() {
sockets.forEach {
......@@ -134,8 +123,10 @@ class MainVm @Inject constructor(
//获取车辆详情 传{}就行,正常应该是传场地ID,但是亦庄这个和太和桥车是一样的,用于拿到车内视频
fun getVehDetail(id: String = ""): LiveData<VehDetailBean> {
if (isGetVehDetail)
return vehDetail
isGetVehDetail = true
viewModelScope.launch {
// while (isActive) {
var result = avpDataRepo.getVehDetail(id)
when (result) {
is MyResult.Success<VehDetailBean> -> {
......@@ -145,8 +136,6 @@ class MainVm @Inject constructor(
else -> {
}
}
delay(2000)
// }
}
return vehDetail
}
......@@ -173,12 +162,14 @@ class MainVm @Inject constructor(
//HTTP获取AVP状态
fun getAvpStatus(): LiveData<AvpStatuBean> {
if (isMock){
if (isMock) {
}else{
} else {
var url = "${MyContants.HOST}/api/avpweb/hmi/monitor/v1/taskStatus"
var body = RequestBodyUtil.toRequestBody(mapOf("id" to MyContants.VEHICLEID))
avpDataRepo.getAvpStatus(body, object : SimpleSSEClient.SSESimpleListener {
avpDataRepo.getAvpStatus(url, body, object : SimpleSSEClient.SSESimpleListener {
override fun onOpen() {
println("--------Http AVP状态 Sse open url = ${url}")
}
override fun onEvent(data: String) {
......@@ -193,6 +184,7 @@ class MainVm @Inject constructor(
}
override fun onError(throwable: Throwable) {
println("------getAvpStatus throwable = ${throwable}")
}
override fun onClosed() {
......@@ -210,17 +202,19 @@ class MainVm @Inject constructor(
*/
fun subVehicle(): LiveData<CarVehicle> {
if (isMock) {
mockVM.onVehicleMock(carVehicle)
mockVM.subVehicle(carVehicle)
} else {
var url = "${MyContants.HOST}/api/avpweb/hmi/monitor/v1/monitorDrivenStatus"
var body = RequestBodyUtil.toRequestBody(mapOf("id" to MyContants.VEHICLEID))
avpDataRepo.getCarPose(body, object : SimpleSSEClient.SSESimpleListener {
avpDataRepo.getCarPose(url, body, object : SimpleSSEClient.SSESimpleListener {
override fun onOpen() {
println("--------Http车辆位姿 Sse open url = ${url}")
}
override fun onEvent(data: String) {
viewModelScope.launch {
if (data.isNotEmpty()) {
println("-----车辆位姿 = ${data}")
// println("-----车辆位姿 = ${data}")
FileIoUtils.writeToFile(data, "CarVehicle.txt")
var result = gson.fromJson<CarVehicle>(data, CarVehicle::class.java)
carVehicle.postValue(result)
......@@ -518,6 +512,7 @@ class MainVm @Inject constructor(
ToastHelper.showCustViewShort(context, imgs.get("2")!!)
}
/*fun d1() {
try {
vecLocWSClient.onWebSocketCb = object : OnWebSocketCb {
......
......@@ -22,6 +22,7 @@ import com.sd.cavphmi.bean.Space
import com.sd.cavphmi.highmap.AllLine
import com.sd.cavphmi.highmap.HighMapApi
import com.sd.cavphmi.highmap.ReverCar
import com.sd.cavphmi.utils.AvpContants
import com.sd.cavphmi.utils.Proj4jCoord
import dagger.hilt.android.lifecycle.HiltViewModel
import dagger.hilt.android.qualifiers.ApplicationContext
......@@ -43,10 +44,10 @@ class MapOpt @Inject constructor(
//路径规划终点
private var pEndMarker: Marker? = null
//小地图点坐标集合
//小地图路径点坐标集合
private var sLatLngs: Array<Point>? = null
// 坐标点串 (02坐标系)
// 小地图路径坐标点串 (02坐标系)
private var coordinateSeries = ArrayList<DoubleArray>()
private var sPolyline: Polyline? = null
......@@ -54,7 +55,7 @@ class MapOpt @Inject constructor(
private var isReversePark = false
//是否生成小地图线
private var smallMapLine = false
var smallMapLine = false
//全局路径
private var allLines: List<AllLine>? = null
......@@ -75,8 +76,8 @@ class MapOpt @Inject constructor(
}
var arrived = drivenDecision.trajectory.arrived
if (arrived) {
HighMapApi.setCameraDistance(30f)
HighMapApi.setCarNavPath(emptyList())
// HighMapApi.setCameraDistance(30f)
// HighMapApi.setCarNavPath(emptyList())
}
}
......@@ -97,25 +98,51 @@ class MapOpt @Inject constructor(
}
}
/****根据车辆位置 画局部图小车*/
fun drawSmallCar(car: CarVehicle) {
synchronized(this) {
if (mSmallMapCar == null && car.vehiclePos != null) {
var point =
LatLng(car.vehiclePos.get(1), car.vehiclePos.get(0))
mSmallMapCar = MyLocationStyle("res/icons/carIconInSmallMap.png", true)
mSmallMapCar?.myLocationType(MyLocationStyle.LOCATION_TYPE_EXTERNAL)
val scaleFactor = -
Math.round(((10 * NativeEnv.getDpi() * 2) * 10 / (160 * 48)).toFloat())
.toFloat() / 10
mSmallMapCar?.scaleFactor(scaleFactor)
mSmallMapCar?.anchor(0.5f, 0.5f)
mSmallMapCar?.setPosition(point)
mMineMap?.setMyLocationStyle(mSmallMapCar)
}
}
}
/**
* 刷新右下角小车位置
*/
fun showNavingCarPosition(carVehicle: CarVehicle) {
if (carVehicle.vehiclePos == null)
return
synchronized(NativeEnv.SyncObject) {
var ndsLatLng = LatLng(carVehicle.vehiclePos!!.get(1), carVehicle.vehiclePos.get(0))
var heading = carVehicle.vehiclePos.get(2).toFloat()
//刷新小地图自车位置
if (mSmallMapCar != null) {
mSmallMapCar!!.orientAngle((heading + 40) % 360)
// mSmallMapCar!!.orientAngle((heading + 40) % 360)
mSmallMapCar!!.orientAngle(0f - 180f - heading)
// mSmallMapCar!!.orientAngle((heading + 180) % 360)
mSmallMapCar!!.setPositionNds(ndsLatLng)
}
}
}
//画小地图路线
fun drawSmallMapLine(drivenDecision: DrivenDecision) {
/***生成小地图路线 并转化为二维坐标系*/
fun takeSmallMapLine(drivenDecision: DrivenDecision) {
if (smallMapLine)
return
if (coordinateSeries.count() > 0)
return
if (drivenDecision.trajectory.points.count() > 0) {
smallMapLine = true
//转换小弟提路径点
......@@ -133,7 +160,7 @@ class MapOpt @Inject constructor(
//更新小地图路径
fun upSmallMapLine(carVehicle: CarVehicle) {
deleteSmapLine()
// deleteSmapLine()
viewModelScope.launch(Dispatchers.Default) {
if (coordinateSeries.count() > 0) {
//当前车辆位置
......@@ -148,13 +175,13 @@ class MapOpt @Inject constructor(
var temps = sLatLngs?.sliceArray(index..sLatLngs!!.lastIndex)
deleteSmapLine()
if (sLatLngs == null) {
sPolyline = Polyline(temps, false)
sPolyline?.setStrokeStyle(Overlay.StrokeStyle.solidWithButt)
sPolyline?.setWidth(8f)
sPolyline?.setColor(0xFF00B578.toInt())
mMineMap?.addOverlay(sPolyline)
}
// if (sPolyline == null) {
sPolyline = Polyline(temps, false)
sPolyline?.setStrokeStyle(Overlay.StrokeStyle.solidWithButt)
sPolyline?.setWidth(8f)
sPolyline?.setColor(0xFF00B578.toInt())
mMineMap?.addOverlay(sPolyline)
// }
}
}
}
......@@ -174,27 +201,38 @@ class MapOpt @Inject constructor(
}
//判断在泊车状态下的倒挡绘制倒车路线
fun drawReversePark(businessType: String, gearType: String, space: Space) {
if (businessType == "Park" && gearType == "REVERSE") {
//判断在泊车状态下的倒挡绘制倒车路线,改变视角
fun drawReversePark(
businessType: String,
businessStatus: String,
gearType: String,
space: Space
) {
if (businessType == AvpContants.Park_TYPE) {
if (businessStatus == AvpContants.TRANSPORT_COMPLETED) {
HighMapApi.setCameraDistance(30f)
HighMapApi.setCameraAngle(60f)
} else if (businessStatus == AvpContants.PARK_PROGRESS) {
HighMapApi.setCameraDistance(20f)
HighMapApi.setCameraAngle(90f)
var reverCar = ReverCar().apply {
this.cenLat = space.centerLatitude
this.cenLng = space.centerLongitude
this.code = space.code
}
HighMapApi.setParkRever(reverCar)
}
// if (isReversePark)
// return
// isReversePark = true
HighMapApi.setCameraDistance(20f)
var reverCar = ReverCar().apply {
this.cenLat = space.centerLatitude
this.cenLng = space.centerLongitude
this.code = space.code
}
HighMapApi.setParkRever(reverCar)
}
}
//是否显示车位流光效果
fun showParkLight(businessType: String, space: Space) {
if (businessType == "Park") {
if (businessType == AvpContants.Park_TYPE) {
HighMapApi.parkRoundLight(space.code)
} else {
// HighMapApi.parkRoundLight("")
......@@ -203,16 +241,23 @@ class MapOpt @Inject constructor(
//根据AVP状态判特效是否关闭
fun showEffectAvpStatu(businessStatus: String) {
if (businessStatus == "CANCELLED" || businessStatus == "COMPLETED" || businessStatus == "FAILED") {
HighMapApi.setCarNavPath(listOf())
HighMapApi.parkRoundLight("")
//消除泊车特效
HighMapApi.setParkComplete(true)
fun showEffectAvpStatu(businessType: String, businessStatus: String) {
//到达召,停车点
if (businessType == AvpContants.TRANSPORT_COMPLETED || businessType == AvpContants.TRANSPORT_CANCELED || businessType == AvpContants.TRANSPORT_ABNORMAL) {
HighMapApi.setCarNavPath(emptyList())//消除全局路径
//删除终点mark
deleteEndMarker()
} else {
//清除小地图路径数据
clearSmallLineData()
}
//倒车完成
if (businessType == AvpContants.Park_TYPE) {
if (businessStatus == AvpContants.PARK_COMPLETED) {
//消除车位流光特效
HighMapApi.parkRoundLight("")
//消除泊车特效
HighMapApi.setParkComplete(true)
}
}
}
......@@ -222,6 +267,8 @@ class MapOpt @Inject constructor(
*/
private fun deleteEndMarker() {
if (pEndMarker != null) {
mMineMap?.removeMarker(pEndMarker)
pEndMarker = null
}
......@@ -246,5 +293,11 @@ class MapOpt @Inject constructor(
}
}
//清除小地图路径数据
fun clearSmallLineData() {
coordinateSeries.clear()
sLatLngs?.toMutableList()?.clear()
}
}
\ No newline at end of file
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment