Fixed transmitters doppler frequency update logic

This commit is contained in:
Arty Bishop committed 2021-04-05 19:32:07 +01:00
1 parent 555c2fe626
commit db710c55c4
7 files changed
+108 -90

No files matched your search

+2 -2
View File
@@ -13,8 +13,8 @@ android {
applicationId "com.rtbishop.look4sat"
minSdkVersion 21
targetSdkVersion 30
versionCode 231
versionName "2.3.1"
versionCode 232
versionName "2.3.2"
kapt {
arguments {
arg("room.schemaLocation", "$projectDir/schemas")
@@ -26,8 +26,8 @@ data class SatTrans(
@PrimaryKey @field:Json(name = "uuid") val uuid: String,
@field:Json(name = "description") val info: String,
@field:Json(name = "alive") val isAlive: Boolean,
@field:Json(name = "downlink_low") val downlink: Long?,
@field:Json(name = "uplink_low") val uplink: Long?,
@field:Json(name = "downlink_low") var downlink: Long?,
@field:Json(name = "uplink_low") var uplink: Long?,
@field:Json(name = "mode") val mode: String?,
@field:Json(name = "invert") val isInverted: Boolean,
@field:Json(name = "norad_cat_id") val catNum: Int
@@ -40,17 +40,18 @@ class PolarFragment : Fragment(R.layout.fragment_polar) {
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
val binding = FragmentPolarBinding.bind(view)
val catNum = requireArguments().getInt("catNum")
val aosTime = requireArguments().getLong("aosTime")
viewModel.getPass(catNum, aosTime).observe(viewLifecycleOwner) { pass ->
polarView = PolarView(requireContext()).apply { setPass(pass) }
binding.frame.addView(polarView)
observeTransmitters(pass, binding)
FragmentPolarBinding.bind(view).apply {
val transAdapter = TransAdapter()
recycler.apply {
setHasFixedSize(true)
adapter = transAdapter
isVerticalScrollBarEnabled = false
layoutManager = LinearLayoutManager(context)
(itemAnimator as SimpleItemAnimator).supportsChangeAnimations = false
addItemDecoration(RecyclerDivider(R.drawable.rec_divider_dark))
}
setupObservers(transAdapter, this)
}
viewModel.azimuth.observe(viewLifecycleOwner, { trueNorthAzimuth ->
polarView?.rotation = -trueNorthAzimuth
})
}
override fun onResume() {
@@ -63,35 +64,41 @@ class PolarFragment : Fragment(R.layout.fragment_polar) {
viewModel.disableSensor()
}
private fun observeTransmitters(satPass: SatPass, binding: FragmentPolarBinding) {
viewModel.getSatTransmitters(satPass.catNum).observe(viewLifecycleOwner, { list ->
val transmitterAdapter = TransAdapter(satPass)
private fun setupObservers(transAdapter: TransAdapter, binding: FragmentPolarBinding) {
val catNum = requireArguments().getInt("catNum")
val aosTime = requireArguments().getLong("aosTime")
viewModel.getPass(catNum, aosTime).observe(viewLifecycleOwner) { pass ->
polarView = PolarView(requireContext()).apply { setPass(pass) }
binding.frame.addView(polarView)
observeTransmitters(pass, transAdapter, binding)
}
viewModel.azimuth.observe(viewLifecycleOwner, { trueNorthAzimuth ->
polarView?.rotation = -trueNorthAzimuth
})
}
private fun observeTransmitters(
satPass: SatPass,
transAdapter: TransAdapter,
binding: FragmentPolarBinding
) {
viewModel.transmitters.observe(viewLifecycleOwner, { list ->
if (list.isNotEmpty()) {
transmitterAdapter.setData(list)
binding.recycler.apply {
setHasFixedSize(true)
adapter = transmitterAdapter
isVerticalScrollBarEnabled = false
layoutManager = LinearLayoutManager(context)
(itemAnimator as SimpleItemAnimator).supportsChangeAnimations = false
addItemDecoration(RecyclerDivider(R.drawable.rec_divider_dark))
visibility = View.VISIBLE
}
transAdapter.submitList(list)
binding.recycler.visibility = View.VISIBLE
binding.noTransMsg.visibility = View.INVISIBLE
} else {
binding.recycler.visibility = View.INVISIBLE
binding.noTransMsg.visibility = View.VISIBLE
}
viewModel.getAppTimer().observe(viewLifecycleOwner, {
setPassText(it, satPass, binding)
polarView?.invalidate()
transmitterAdapter.tickTransmitters()
})
setPassText(satPass, binding)
polarView?.invalidate()
})
}
private fun setPassText(timeNow: Long, satPass: SatPass, binding: FragmentPolarBinding) {
val dateNow = Date(timeNow)
private fun setPassText(satPass: SatPass, binding: FragmentPolarBinding) {
val dateNow = Date()
val timeNow = System.currentTimeMillis()
val satPos = satPass.predictor.getSatPos(dateNow)
val polarAz = getString(R.string.pat_azimuth)
val polarEl = getString(R.string.pat_elevation)
@@ -18,12 +18,18 @@
package com.rtbishop.look4sat.ui.polarScreen
import androidx.lifecycle.*
import com.rtbishop.look4sat.data.model.SatPass
import com.rtbishop.look4sat.data.model.SatTrans
import com.rtbishop.look4sat.data.repository.PassesRepo
import com.rtbishop.look4sat.data.repository.SatelliteRepo
import com.rtbishop.look4sat.utility.PrefsManager
import dagger.hilt.android.lifecycle.HiltViewModel
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.delay
import kotlinx.coroutines.flow.collect
import kotlinx.coroutines.isActive
import kotlinx.coroutines.launch
import java.util.*
import javax.inject.Inject
@HiltViewModel
@@ -35,20 +41,18 @@ class PolarViewModel @Inject constructor(
) : ViewModel(), Orientation.OrientationListener {
private val magDeclination = prefsManager.getMagDeclination()
private val _transmitters = MutableLiveData<List<SatTrans>>()
private val _azimuth = MutableLiveData<Float>()
val transmitters: LiveData<List<SatTrans>> = _transmitters
val azimuth: LiveData<Float> = _azimuth
fun getAppTimer() = liveData {
while (true) {
emit(System.currentTimeMillis())
delay(1000)
}
}
fun getPass(catNum: Int, aosTime: Long) = liveData {
passesRepo.passes.collect { passes ->
val pass = passes.find { it.catNum == catNum && it.aosDate.time == aosTime }
pass?.let { emit(it) }
pass?.let { satPass ->
processTransmitters(satPass)
emit(satPass)
}
}
}
@@ -60,10 +64,28 @@ class PolarViewModel @Inject constructor(
if (prefsManager.shouldUseCompass()) orientation.stopListening()
}
fun getSatTransmitters(satId: Int) =
satelliteRepo.getSatTransmitters(satId).asLiveData(viewModelScope.coroutineContext)
override fun onOrientationChanged(azimuth: Float, pitch: Float, roll: Float) {
_azimuth.value = azimuth + magDeclination
}
private fun processTransmitters(satPass: SatPass) {
viewModelScope.launch {
satelliteRepo.getSatTransmitters(satPass.catNum).collect { transList ->
while (isActive) {
val timeNow = Date()
val copiedList = transList.map { it.copy() }
copiedList.forEach { transmitter ->
transmitter.downlink?.let {
transmitter.downlink = satPass.predictor.getDownlinkFreq(it, timeNow)
}
transmitter.uplink?.let {
transmitter.uplink = satPass.predictor.getUplinkFreq(it, timeNow)
}
}
_transmitters.postValue(copiedList.map { it.copy() })
delay(1000)
}
}
}
}
}
@@ -19,45 +19,44 @@ package com.rtbishop.look4sat.ui.polarScreen
import android.view.LayoutInflater
import android.view.ViewGroup
import androidx.recyclerview.widget.AsyncListDiffer
import androidx.recyclerview.widget.DiffUtil
import androidx.recyclerview.widget.RecyclerView
import com.rtbishop.look4sat.R
import com.rtbishop.look4sat.data.model.SatPass
import com.rtbishop.look4sat.data.model.SatTrans
import com.rtbishop.look4sat.databinding.ItemTransBinding
import com.rtbishop.look4sat.utility.PassPredictor
import java.util.*
class TransAdapter(private val pass: SatPass) : RecyclerView.Adapter<TransAdapter.TransHolder>() {
class TransAdapter : RecyclerView.Adapter<TransAdapter.TransHolder>() {
private var transmittersList = emptyList<SatTrans>()
private val diffCallback = object : DiffUtil.ItemCallback<SatTrans>() {
override fun areItemsTheSame(oldItem: SatTrans, newItem: SatTrans): Boolean {
return oldItem.uuid == newItem.uuid
}
fun setData(list: List<SatTrans>) {
transmittersList = list
notifyDataSetChanged()
}
fun tickTransmitters() {
if (!pass.isDeepSpace) {
notifyDataSetChanged()
override fun areContentsTheSame(oldItem: SatTrans, newItem: SatTrans): Boolean {
return oldItem.downlink == newItem.downlink
}
}
private val differ = AsyncListDiffer(this, diffCallback)
override fun getItemCount(): Int {
return transmittersList.size
fun submitList(transmitters: List<SatTrans>) {
differ.submitList(transmitters)
}
override fun getItemCount() = differ.currentList.size
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): TransHolder {
return TransHolder.from(parent)
}
override fun onBindViewHolder(holder: TransHolder, position: Int) {
holder.bind(transmittersList[position], pass)
holder.bind(differ.currentList[position])
}
class TransHolder private constructor(private val binding: ItemTransBinding) :
RecyclerView.ViewHolder(binding.root) {
private val dateNow = Date()
private val divider = 1000000f
private val strNo = itemView.context.getString(R.string.btn_no)
private val strYes = itemView.context.getString(R.string.btn_yes)
@@ -66,11 +65,22 @@ class TransAdapter(private val pass: SatPass) : RecyclerView.Adapter<TransAdapte
private val formatLinkNull = itemView.context.getString(R.string.trans_no_link)
private val isInverted = itemView.context.getString(R.string.trans_inverted)
fun bind(satTrans: SatTrans, satPass: SatPass) {
fun bind(satTrans: SatTrans) {
binding.description.text = satTrans.info
if (satPass.isDeepSpace) setRegularFreq(satTrans)
else setDopplerFreq(satTrans, satPass.predictor)
satTrans.downlink.let { downlink ->
if (downlink != null) {
val downlinkFreq = downlink / divider
binding.downlink.text = String.format(Locale.ENGLISH, formatLink, downlinkFreq)
} else binding.downlink.text = formatLinkNull
}
satTrans.uplink.let { uplink ->
if (uplink != null) {
val uplinkFreq = uplink / divider
binding.uplink.text = String.format(Locale.ENGLISH, formatLink, uplinkFreq)
} else binding.uplink.text = formatLinkNull
}
if (satTrans.mode != null) binding.mode.text = String.format(mode, satTrans.mode)
else binding.mode.text = String.format(mode, strNo)
@@ -79,30 +89,6 @@ class TransAdapter(private val pass: SatPass) : RecyclerView.Adapter<TransAdapte
else binding.isInverted.text = String.format(isInverted, strNo)
}
private fun setRegularFreq(satTrans: SatTrans) {
if (satTrans.downlink != null) {
val downFreq = satTrans.downlink / divider
binding.downlink.text = String.format(Locale.ENGLISH, formatLink, downFreq)
} else binding.downlink.text = formatLinkNull
if (satTrans.uplink != null) {
val upFreq = satTrans.uplink / divider
binding.uplink.text = String.format(Locale.ENGLISH, formatLink, upFreq)
} else binding.uplink.text = formatLinkNull
}
private fun setDopplerFreq(satTrans: SatTrans, predictor: PassPredictor) {
if (satTrans.downlink != null) {
val downlink = predictor.getDownlinkFreq(satTrans.downlink, dateNow) / divider
binding.downlink.text = String.format(Locale.ENGLISH, formatLink, downlink)
} else binding.downlink.text = formatLinkNull
if (satTrans.uplink != null) {
val uplink = predictor.getUplinkFreq(satTrans.uplink, dateNow) / divider
binding.uplink.text = String.format(Locale.ENGLISH, formatLink, uplink)
} else binding.uplink.text = formatLinkNull
}
companion object {
fun from(parent: ViewGroup): TransHolder {
val inflater = LayoutInflater.from(parent.context)