kopia lustrzana https://github.com/rt-bishop/Look4Sat
Replaced original SatPassTime class with my own
rodzic
37c5ebbf2e
commit
33d25d3c25
|
@ -17,7 +17,6 @@
|
|||
*/
|
||||
package com.rtbishop.look4sat.data.model
|
||||
|
||||
import com.github.amsacode.predict4java.SatPassTime
|
||||
import com.github.amsacode.predict4java.Satellite
|
||||
import com.rtbishop.look4sat.utility.PassPredictor
|
||||
|
||||
|
|
|
@ -0,0 +1,37 @@
|
|||
/*
|
||||
* Look4Sat. Amateur radio satellite tracker and pass predictor.
|
||||
* Copyright (C) 2019-2021 Arty Bishop (bishop.arty@gmail.com)
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package com.rtbishop.look4sat.data.model
|
||||
|
||||
import java.util.*
|
||||
|
||||
class SatPassTime(
|
||||
private val startTime: Date,
|
||||
private val endTime: Date,
|
||||
val aosAzimuth: Int,
|
||||
val losAzimuth: Int,
|
||||
val maxEl: Double
|
||||
) {
|
||||
|
||||
fun getStartTime(): Date {
|
||||
return Date(startTime.time)
|
||||
}
|
||||
|
||||
fun getEndTime(): Date {
|
||||
return Date(endTime.time)
|
||||
}
|
||||
}
|
|
@ -72,10 +72,10 @@ class PassesRepo @Inject constructor(
|
|||
this.time = refDate
|
||||
this.add(Calendar.HOUR, hoursAhead)
|
||||
}.time
|
||||
passes.removeAll { it.pass.startTime.after(dateFuture) }
|
||||
passes.removeAll { it.pass.endTime.before(refDate) }
|
||||
passes.removeAll { it.pass.getStartTime().after(dateFuture) }
|
||||
passes.removeAll { it.pass.getEndTime().before(refDate) }
|
||||
passes.removeAll { it.pass.maxEl < prefsRepo.getMinElevation() }
|
||||
passes.sortBy { it.pass.startTime }
|
||||
passes.sortBy { it.pass.getStartTime() }
|
||||
return passes
|
||||
}
|
||||
}
|
||||
|
|
|
@ -46,9 +46,9 @@ class PassesAdapter(private val shouldUseUTC: Boolean = false) :
|
|||
val satPass = iterator.next()
|
||||
if (!satPass.satellite.tle.isDeepspace) {
|
||||
if (satPass.progress < 100) {
|
||||
val timeStart = satPass.pass.startTime.time
|
||||
val timeStart = satPass.pass.getStartTime().time
|
||||
if (timeNow > timeStart) {
|
||||
val timeEnd = satPass.pass.endTime.time
|
||||
val timeEnd = satPass.pass.getEndTime().time
|
||||
val index = satPassList.indexOf(satPass)
|
||||
val deltaNow = timeNow.minus(timeStart).toFloat()
|
||||
val deltaTotal = timeEnd.minus(timeStart).toFloat()
|
||||
|
@ -115,9 +115,9 @@ class PassesAdapter(private val shouldUseUTC: Boolean = false) :
|
|||
passLeoAosAz.text = String.format(aosAzFormat, satPass.pass.aosAzimuth)
|
||||
passLeoMaxEl.text = String.format(maxElFormat, satPass.pass.maxEl)
|
||||
passLeoLosAz.text = String.format(losAzFormat, satPass.pass.losAzimuth)
|
||||
passLeoStart.text = startFormat.format(satPass.pass.startTime)
|
||||
passLeoStart.text = startFormat.format(satPass.pass.getStartTime())
|
||||
passLeoAlt.text = String.format(altFormat, satPos.altitude)
|
||||
passLeoEnd.text = endFormat.format(satPass.pass.endTime)
|
||||
passLeoEnd.text = endFormat.format(satPass.pass.getEndTime())
|
||||
passLeoProgress.progress = satPass.progress
|
||||
}
|
||||
|
||||
|
|
|
@ -100,12 +100,12 @@ class PassesFragment : Fragment(R.layout.fragment_passes) {
|
|||
private fun tickMainTimer(timeNow: Long) {
|
||||
if (passes.isNotEmpty()) {
|
||||
try {
|
||||
val nextPass = passes.first { it.pass.startTime.time.minus(timeNow) > 0 }
|
||||
val millisBeforeStart = nextPass.pass.startTime.time.minus(timeNow)
|
||||
val nextPass = passes.first { it.pass.getStartTime().time.minus(timeNow) > 0 }
|
||||
val millisBeforeStart = nextPass.pass.getStartTime().time.minus(timeNow)
|
||||
binding?.passesTimer?.text = millisBeforeStart.formatForTimer()
|
||||
} catch (e: NoSuchElementException) {
|
||||
val lastPass = passes.last()
|
||||
val millisBeforeEnd = lastPass.pass.endTime.time.minus(timeNow)
|
||||
val millisBeforeEnd = lastPass.pass.getEndTime().time.minus(timeNow)
|
||||
binding?.passesTimer?.text = millisBeforeEnd.formatForTimer()
|
||||
}
|
||||
} else {
|
||||
|
|
|
@ -30,7 +30,6 @@ import androidx.navigation.fragment.findNavController
|
|||
import androidx.recyclerview.widget.LinearLayoutManager
|
||||
import androidx.recyclerview.widget.SimpleItemAnimator
|
||||
import com.rtbishop.look4sat.R
|
||||
import com.rtbishop.look4sat.data.model.Result
|
||||
import com.rtbishop.look4sat.data.model.SatPass
|
||||
import com.rtbishop.look4sat.databinding.FragmentPolarBinding
|
||||
import com.rtbishop.look4sat.utility.RecyclerDivider
|
||||
|
@ -57,7 +56,7 @@ class PolarFragment : Fragment(R.layout.fragment_polar), SensorEventListener {
|
|||
binding = FragmentPolarBinding.bind(view)
|
||||
sensorManager = requireContext().getSystemService(Context.SENSOR_SERVICE) as SensorManager
|
||||
magneticDeclination = viewModel.getMagDeclination()
|
||||
observePasses()
|
||||
observePass()
|
||||
}
|
||||
|
||||
override fun onResume() {
|
||||
|
@ -92,15 +91,23 @@ class PolarFragment : Fragment(R.layout.fragment_polar), SensorEventListener {
|
|||
polarView?.rotation = -(roundedAzimuth + magneticDeclination)
|
||||
}
|
||||
|
||||
private fun observePasses() {
|
||||
viewModel.getPasses().observe(viewLifecycleOwner, { result ->
|
||||
if (result is Result.Success) {
|
||||
satPass = result.data[requireArguments().getInt("index")]
|
||||
polarView = PolarView(requireContext()).apply { setPass(satPass) }
|
||||
binding.frame.addView(polarView)
|
||||
observeTransmitters()
|
||||
}
|
||||
private fun observePass() {
|
||||
val passId = requireArguments().getInt("index")
|
||||
viewModel.getPass(passId).observe(viewLifecycleOwner, { pass ->
|
||||
satPass = pass
|
||||
polarView = PolarView(requireContext()).apply { setPass(pass) }
|
||||
binding.frame.addView(polarView)
|
||||
observeTransmitters()
|
||||
})
|
||||
|
||||
// viewModel.getPasses().observe(viewLifecycleOwner, { result ->
|
||||
// if (result is Result.Success) {
|
||||
// satPass = result.data[requireArguments().getInt("index")]
|
||||
// polarView = PolarView(requireContext()).apply { setPass(satPass) }
|
||||
// binding.frame.addView(polarView)
|
||||
// observeTransmitters()
|
||||
// }
|
||||
// })
|
||||
}
|
||||
|
||||
private fun observeTransmitters() {
|
||||
|
@ -148,13 +155,13 @@ class PolarFragment : Fragment(R.layout.fragment_polar), SensorEventListener {
|
|||
binding.altitude.text = String.format(polarAlt, satPos.altitude)
|
||||
|
||||
if (!satPass.satellite.tle.isDeepspace) {
|
||||
if (dateNow.before(satPass.pass.startTime)) {
|
||||
val millisBeforeStart = satPass.pass.startTime.time.minus(timeNow)
|
||||
if (dateNow.before(satPass.pass.getStartTime())) {
|
||||
val millisBeforeStart = satPass.pass.getStartTime().time.minus(timeNow)
|
||||
binding.polarTimer.text = millisBeforeStart.formatForTimer()
|
||||
} else {
|
||||
val millisBeforeEnd = satPass.pass.endTime.time.minus(timeNow)
|
||||
val millisBeforeEnd = satPass.pass.getEndTime().time.minus(timeNow)
|
||||
binding.polarTimer.text = millisBeforeEnd.formatForTimer()
|
||||
if (dateNow.after(satPass.pass.endTime)) {
|
||||
if (dateNow.after(satPass.pass.getEndTime())) {
|
||||
binding.polarTimer.text = 0L.formatForTimer()
|
||||
findNavController().popBackStack()
|
||||
}
|
||||
|
|
|
@ -92,13 +92,13 @@ class PolarView(context: Context) : View(context) {
|
|||
}
|
||||
|
||||
private fun drawPassTrajectory(cvs: Canvas, satPass: SatPass) {
|
||||
val startTime = satPass.pass.startTime
|
||||
val endTime = satPass.pass.endTime
|
||||
val startTime = satPass.pass.getStartTime()
|
||||
val endTime = satPass.pass.getEndTime()
|
||||
while (startTime.before(endTime)) {
|
||||
val satPos = satPass.predictor.getSatPos(startTime)
|
||||
val x = sph2CartX(satPos.azimuth, satPos.elevation, radius.toDouble())
|
||||
val y = sph2CartY(satPos.azimuth, satPos.elevation, radius.toDouble())
|
||||
if (startTime.compareTo(satPass.pass.startTime) == 0) {
|
||||
if (startTime.compareTo(satPass.pass.getStartTime()) == 0) {
|
||||
path.moveTo(x, -y)
|
||||
} else {
|
||||
path.lineTo(x, -y)
|
||||
|
|
|
@ -20,11 +20,14 @@ package com.rtbishop.look4sat.ui.polarScreen
|
|||
import androidx.lifecycle.ViewModel
|
||||
import androidx.lifecycle.asLiveData
|
||||
import androidx.lifecycle.liveData
|
||||
import com.rtbishop.look4sat.data.model.Result
|
||||
import com.rtbishop.look4sat.data.model.SatPass
|
||||
import com.rtbishop.look4sat.data.repository.PassesRepo
|
||||
import com.rtbishop.look4sat.data.repository.PrefsRepo
|
||||
import com.rtbishop.look4sat.data.repository.SatelliteRepo
|
||||
import dagger.hilt.android.lifecycle.HiltViewModel
|
||||
import kotlinx.coroutines.delay
|
||||
import kotlinx.coroutines.flow.collect
|
||||
import javax.inject.Inject
|
||||
|
||||
@HiltViewModel
|
||||
|
@ -41,6 +44,14 @@ class PolarViewModel @Inject constructor(
|
|||
}
|
||||
}
|
||||
|
||||
fun getPass(passId: Int) = liveData {
|
||||
passesRepo.passes.collect { passes ->
|
||||
if (passes is Result.Success) {
|
||||
emit(passes.data[passId])
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun getPasses() = passesRepo.passes.asLiveData()
|
||||
|
||||
fun shouldUseCompass(): Boolean {
|
||||
|
|
|
@ -18,19 +18,30 @@
|
|||
package com.rtbishop.look4sat.utility
|
||||
|
||||
import com.github.amsacode.predict4java.GroundStationPosition
|
||||
import com.github.amsacode.predict4java.SatPassTime
|
||||
import com.github.amsacode.predict4java.SatPos
|
||||
import com.github.amsacode.predict4java.Satellite
|
||||
import com.rtbishop.look4sat.data.model.SatPassTime
|
||||
import java.util.*
|
||||
|
||||
class PassPredictor(private val satellite: Satellite, private val qth: GroundStationPosition) {
|
||||
|
||||
private val oneQuarterOrbitMin = (24.0 * 60.0 / satellite.tle.meanmo / 4.0).toInt()
|
||||
private val speedOfLight = 2.99792458E8
|
||||
|
||||
fun getDownlinkFreq(freq: Long, date: Date): Long {
|
||||
val rangeRate = getSatPos(date).rangeRate
|
||||
return (freq.toDouble() * (speedOfLight - rangeRate * 1000.0) / speedOfLight).toLong()
|
||||
}
|
||||
|
||||
fun getUplinkFreq(freq: Long, date: Date): Long {
|
||||
val rangeRate = getSatPos(date).rangeRate
|
||||
return (freq.toDouble() * (speedOfLight + rangeRate * 1000.0) / speedOfLight).toLong()
|
||||
}
|
||||
|
||||
fun getSatPos(date: Date): SatPos {
|
||||
return satellite.getPosition(qth, date)
|
||||
}
|
||||
|
||||
|
||||
fun getPositions(refDate: Date, stepSeconds: Int, minBefore: Int, minAfter: Int): List<SatPos> {
|
||||
val positions = mutableListOf<SatPos>()
|
||||
val endDate = Date(refDate.time + minAfter * 60L * 1000L)
|
||||
|
@ -57,9 +68,10 @@ class PassPredictor(private val satellite: Satellite, private val qth: GroundSta
|
|||
do {
|
||||
if (count > 0) shouldWindBack = false
|
||||
val pass = nextNearEarthPass(startDate, shouldWindBack)
|
||||
lastAosDate = pass.startTime
|
||||
lastAosDate = pass.getStartTime()
|
||||
passes.add(pass)
|
||||
startDate = Date(pass.endTime.time + (oneQuarterOrbitMin * 3) * 60L * 1000L)
|
||||
startDate =
|
||||
Date(pass.getEndTime().time + (oneQuarterOrbitMin * 3) * 60L * 1000L)
|
||||
count++
|
||||
} while (lastAosDate < endDate)
|
||||
}
|
||||
|
@ -73,7 +85,7 @@ class PassPredictor(private val satellite: Satellite, private val qth: GroundSta
|
|||
val endDate = Date(refDate.time + 24 * 60L * 60L * 1000L)
|
||||
val azimuth = Math.toDegrees(satPos.azimuth).toInt()
|
||||
val maxEl = Math.toDegrees(satPos.elevation)
|
||||
return SatPassTime(startDate, endDate, "pole", azimuth, azimuth, maxEl)
|
||||
return SatPassTime(startDate, endDate, azimuth, azimuth, maxEl)
|
||||
}
|
||||
|
||||
private fun nextNearEarthPass(refDate: Date, windBack: Boolean = false): SatPassTime {
|
||||
|
@ -138,6 +150,6 @@ class PassPredictor(private val satellite: Satellite, private val qth: GroundSta
|
|||
val endDate = satPos.time
|
||||
val losAzimuth = Math.toDegrees(satPos.azimuth).toInt()
|
||||
val maxEl = Math.toDegrees(maxElevation)
|
||||
return SatPassTime(startDate, endDate, "pole", aosAzimuth, losAzimuth, maxEl)
|
||||
return SatPassTime(startDate, endDate, aosAzimuth, losAzimuth, maxEl)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
buildscript {
|
||||
ext {
|
||||
gradle_version = '4.1.2'
|
||||
gradle_version = '4.1.3'
|
||||
gradle_plugin_version = '1.4.31'
|
||||
material_version = '1.3.0'
|
||||
constraint_layout_version = '2.0.4'
|
||||
|
|
Ładowanie…
Reference in New Issue