Simplified SatPass.kt, predictor now returns this class
This commit is contained in:
1 parent
33d25d3c25
commit
a882a73b8e
15 files changed
+134
-157
No files matched your search
@@ -17,12 +17,31 @@
|
||||
*/
|
||||
package com.rtbishop.look4sat.data.model
|
||||
|
||||
import com.github.amsacode.predict4java.Satellite
|
||||
import com.rtbishop.look4sat.utility.PassPredictor
|
||||
import java.util.*
|
||||
|
||||
data class SatPass(
|
||||
val catNum: Int,
|
||||
val name: String,
|
||||
val isDeepSpace: Boolean,
|
||||
private val aosTime: Long,
|
||||
val aosAzimuth: Double,
|
||||
private val losTime: Long,
|
||||
val losAzimuth: Double,
|
||||
private val tcaTime: Long,
|
||||
val tcaAzimuth: Double,
|
||||
val altitude: Double,
|
||||
val maxElevation: Double,
|
||||
val predictor: PassPredictor
|
||||
) {
|
||||
val startDate: Date
|
||||
get() = Date(aosTime)
|
||||
|
||||
val endDate: Date
|
||||
get() = Date(losTime)
|
||||
|
||||
val tcaDate: Date
|
||||
get() = Date(tcaTime)
|
||||
|
||||
class SatPass(
|
||||
val satellite: Satellite,
|
||||
val predictor: PassPredictor,
|
||||
val pass: SatPassTime,
|
||||
var progress: Int = 0
|
||||
)
|
||||
}
|
||||
@@ -1,37 +0,0 @@
|
||||
/*
|
||||
* 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)
|
||||
}
|
||||
}
|
||||
@@ -62,8 +62,7 @@ class PassesRepo @Inject constructor(
|
||||
private fun getPasses(satellite: Satellite, refDate: Date): MutableList<SatPass> {
|
||||
val predictor = satellite.getPredictor(prefsRepo.getStationPosition())
|
||||
val passes = predictor.getPasses(refDate, prefsRepo.getHoursAhead(), true)
|
||||
val passList = passes.map { SatPass(satellite, predictor, it) }
|
||||
return passList as MutableList<SatPass>
|
||||
return passes as MutableList<SatPass>
|
||||
}
|
||||
|
||||
private fun filterPasses(passes: MutableList<SatPass>, refDate: Date): MutableList<SatPass> {
|
||||
@@ -72,10 +71,10 @@ class PassesRepo @Inject constructor(
|
||||
this.time = refDate
|
||||
this.add(Calendar.HOUR, hoursAhead)
|
||||
}.time
|
||||
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.getStartTime() }
|
||||
passes.removeAll { it.startDate.after(dateFuture) }
|
||||
passes.removeAll { it.endDate.before(refDate) }
|
||||
passes.removeAll { it.maxElevation < prefsRepo.getMinElevation() }
|
||||
passes.sortBy { it.startDate }
|
||||
return passes
|
||||
}
|
||||
}
|
||||
@@ -46,7 +46,8 @@ class EntriesViewModel @Inject constructor(
|
||||
|
||||
private val satDataState = MutableSharedFlow<Result<List<SatItem>>>(replay = 0)
|
||||
private val satDataFlow = satelliteRepo.getAllSatItems().map { Result.Success(it) }
|
||||
val satData = flowOf(satDataState, satDataFlow).flattenMerge().asLiveData()
|
||||
val satData =
|
||||
flowOf(satDataState, satDataFlow).flattenMerge().asLiveData(viewModelScope.coroutineContext)
|
||||
|
||||
fun importSatDataFromFile(uri: Uri) {
|
||||
viewModelScope.launch {
|
||||
|
||||
@@ -44,11 +44,11 @@ class PassesAdapter(private val shouldUseUTC: Boolean = false) :
|
||||
val iterator = satPassList.listIterator()
|
||||
while (iterator.hasNext()) {
|
||||
val satPass = iterator.next()
|
||||
if (!satPass.satellite.tle.isDeepspace) {
|
||||
if (!satPass.isDeepSpace) {
|
||||
if (satPass.progress < 100) {
|
||||
val timeStart = satPass.pass.getStartTime().time
|
||||
val timeStart = satPass.startDate.time
|
||||
if (timeNow > timeStart) {
|
||||
val timeEnd = satPass.pass.getEndTime().time
|
||||
val timeEnd = satPass.endDate.time
|
||||
val index = satPassList.indexOf(satPass)
|
||||
val deltaNow = timeNow.minus(timeStart).toFloat()
|
||||
val deltaTotal = timeEnd.minus(timeStart).toFloat()
|
||||
@@ -69,7 +69,7 @@ class PassesAdapter(private val shouldUseUTC: Boolean = false) :
|
||||
}
|
||||
|
||||
override fun getItemViewType(position: Int): Int {
|
||||
return if (satPassList[position].satellite.tle.isDeepspace) 1
|
||||
return if (satPassList[position].isDeepSpace) 1
|
||||
else 0
|
||||
}
|
||||
|
||||
@@ -104,20 +104,19 @@ class PassesAdapter(private val shouldUseUTC: Boolean = false) :
|
||||
private val endFormat = SimpleDateFormat(endTimeFormat, Locale.getDefault())
|
||||
|
||||
fun bind(satPass: SatPass, position: Int, shouldUseUTC: Boolean) {
|
||||
val satPos = satPass.predictor.getSatPos(Date())
|
||||
binding.apply {
|
||||
if (shouldUseUTC) {
|
||||
startFormat.timeZone = timeZoneUTC
|
||||
endFormat.timeZone = timeZoneUTC
|
||||
}
|
||||
passLeoSatName.text = satPass.satellite.tle.name
|
||||
passLeoSatId.text = String.format(satIdFormat, satPass.satellite.tle.catnum)
|
||||
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.getStartTime())
|
||||
passLeoAlt.text = String.format(altFormat, satPos.altitude)
|
||||
passLeoEnd.text = endFormat.format(satPass.pass.getEndTime())
|
||||
passLeoSatName.text = satPass.name
|
||||
passLeoSatId.text = String.format(satIdFormat, satPass.catNum)
|
||||
passLeoAosAz.text = String.format(aosAzFormat, satPass.aosAzimuth)
|
||||
passLeoMaxEl.text = String.format(maxElFormat, satPass.maxElevation)
|
||||
passLeoLosAz.text = String.format(losAzFormat, satPass.losAzimuth)
|
||||
passLeoStart.text = startFormat.format(satPass.startDate)
|
||||
passLeoAlt.text = String.format(altFormat, satPass.altitude)
|
||||
passLeoEnd.text = endFormat.format(satPass.endDate)
|
||||
passLeoProgress.progress = satPass.progress
|
||||
}
|
||||
|
||||
@@ -146,13 +145,12 @@ class PassesAdapter(private val shouldUseUTC: Boolean = false) :
|
||||
private val elevFormat = itemView.context.getString(R.string.pat_elevation)
|
||||
|
||||
fun bind(satPass: SatPass, position: Int) {
|
||||
val satPos = satPass.predictor.getSatPos(Date())
|
||||
binding.apply {
|
||||
passGeoSatName.text = satPass.satellite.tle.name
|
||||
passGeoSatId.text = String.format(satIdFormat, satPass.satellite.tle.catnum)
|
||||
passGeoAz.text = String.format(azFormat, Math.toDegrees(satPos.azimuth))
|
||||
passGeoAlt.text = String.format(altFormat, satPos.altitude)
|
||||
passGeoEl.text = String.format(elevFormat, Math.toDegrees(satPos.elevation))
|
||||
passGeoSatName.text = satPass.name
|
||||
passGeoSatId.text = String.format(satIdFormat, satPass.catNum)
|
||||
passGeoAz.text = String.format(azFormat, satPass.tcaAzimuth)
|
||||
passGeoAlt.text = String.format(altFormat, satPass.altitude)
|
||||
passGeoEl.text = String.format(elevFormat, satPass.maxElevation)
|
||||
}
|
||||
|
||||
itemView.setOnClickListener {
|
||||
|
||||
@@ -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.getStartTime().time.minus(timeNow) > 0 }
|
||||
val millisBeforeStart = nextPass.pass.getStartTime().time.minus(timeNow)
|
||||
val nextPass = passes.first { it.startDate.time.minus(timeNow) > 0 }
|
||||
val millisBeforeStart = nextPass.startDate.time.minus(timeNow)
|
||||
binding?.passesTimer?.text = millisBeforeStart.formatForTimer()
|
||||
} catch (e: NoSuchElementException) {
|
||||
val lastPass = passes.last()
|
||||
val millisBeforeEnd = lastPass.pass.getEndTime().time.minus(timeNow)
|
||||
val millisBeforeEnd = lastPass.endDate.time.minus(timeNow)
|
||||
binding?.passesTimer?.text = millisBeforeEnd.formatForTimer()
|
||||
}
|
||||
} else {
|
||||
|
||||
@@ -26,7 +26,6 @@ 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 kotlinx.coroutines.launch
|
||||
import javax.inject.Inject
|
||||
|
||||
@@ -37,13 +36,11 @@ class PassesViewModel @Inject constructor(
|
||||
private val passesRepo: PassesRepo
|
||||
) : ViewModel() {
|
||||
|
||||
val passes = passesRepo.passes.asLiveData()
|
||||
val passes = passesRepo.passes.asLiveData(viewModelScope.coroutineContext)
|
||||
|
||||
init {
|
||||
viewModelScope.launch {
|
||||
satelliteRepo.getSelectedSatellitesFlow().collect { selectedSatellites ->
|
||||
passesRepo.calculatePasses(selectedSatellites)
|
||||
}
|
||||
passesRepo.calculatePasses(satelliteRepo.getSelectedSatellites())
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -99,19 +99,10 @@ class PolarFragment : Fragment(R.layout.fragment_polar), SensorEventListener {
|
||||
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() {
|
||||
viewModel.getTransmittersForSat(satPass.satellite.tle.catnum)
|
||||
viewModel.getSatTransmitters(satPass.catNum)
|
||||
.observe(viewLifecycleOwner, { list ->
|
||||
transmitterAdapter = TransAdapter(satPass)
|
||||
if (list.isNotEmpty()) {
|
||||
@@ -154,14 +145,14 @@ class PolarFragment : Fragment(R.layout.fragment_polar), SensorEventListener {
|
||||
binding.distance.text = String.format(polarRng, satPos.range)
|
||||
binding.altitude.text = String.format(polarAlt, satPos.altitude)
|
||||
|
||||
if (!satPass.satellite.tle.isDeepspace) {
|
||||
if (dateNow.before(satPass.pass.getStartTime())) {
|
||||
val millisBeforeStart = satPass.pass.getStartTime().time.minus(timeNow)
|
||||
if (!satPass.isDeepSpace) {
|
||||
if (dateNow.before(satPass.startDate)) {
|
||||
val millisBeforeStart = satPass.startDate.time.minus(timeNow)
|
||||
binding.polarTimer.text = millisBeforeStart.formatForTimer()
|
||||
} else {
|
||||
val millisBeforeEnd = satPass.pass.getEndTime().time.minus(timeNow)
|
||||
val millisBeforeEnd = satPass.endDate.time.minus(timeNow)
|
||||
binding.polarTimer.text = millisBeforeEnd.formatForTimer()
|
||||
if (dateNow.after(satPass.pass.getEndTime())) {
|
||||
if (dateNow.after(satPass.endDate)) {
|
||||
binding.polarTimer.text = 0L.formatForTimer()
|
||||
findNavController().popBackStack()
|
||||
}
|
||||
|
||||
@@ -72,7 +72,7 @@ class PolarView(context: Context) : View(context) {
|
||||
canvas.translate(polarCenter, polarCenter)
|
||||
drawRadarView(canvas)
|
||||
drawRadarText(canvas)
|
||||
if (!satPass.satellite.tle.isDeepspace) drawPassTrajectory(canvas, satPass)
|
||||
if (!satPass.isDeepSpace) drawPassTrajectory(canvas, satPass)
|
||||
drawSatellite(canvas, satPass)
|
||||
}
|
||||
|
||||
@@ -92,13 +92,13 @@ class PolarView(context: Context) : View(context) {
|
||||
}
|
||||
|
||||
private fun drawPassTrajectory(cvs: Canvas, satPass: SatPass) {
|
||||
val startTime = satPass.pass.getStartTime()
|
||||
val endTime = satPass.pass.getEndTime()
|
||||
val startTime = satPass.startDate
|
||||
val endTime = satPass.endDate
|
||||
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.getStartTime()) == 0) {
|
||||
if (startTime.compareTo(satPass.startDate) == 0) {
|
||||
path.moveTo(x, -y)
|
||||
} else {
|
||||
path.lineTo(x, -y)
|
||||
|
||||
@@ -20,8 +20,8 @@ package com.rtbishop.look4sat.ui.polarScreen
|
||||
import androidx.lifecycle.ViewModel
|
||||
import androidx.lifecycle.asLiveData
|
||||
import androidx.lifecycle.liveData
|
||||
import androidx.lifecycle.viewModelScope
|
||||
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
|
||||
@@ -52,8 +52,6 @@ class PolarViewModel @Inject constructor(
|
||||
}
|
||||
}
|
||||
|
||||
fun getPasses() = passesRepo.passes.asLiveData()
|
||||
|
||||
fun shouldUseCompass(): Boolean {
|
||||
return prefsRepo.shouldUseCompass()
|
||||
}
|
||||
@@ -62,5 +60,6 @@ class PolarViewModel @Inject constructor(
|
||||
return prefsRepo.getMagDeclination()
|
||||
}
|
||||
|
||||
fun getTransmittersForSat(satId: Int) = satelliteRepo.getSatTransmitters(satId).asLiveData()
|
||||
fun getSatTransmitters(satId: Int) =
|
||||
satelliteRepo.getSatTransmitters(satId).asLiveData(viewModelScope.coroutineContext)
|
||||
}
|
||||
@@ -25,7 +25,6 @@ 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 com.rtbishop.look4sat.utility.getDopplerFreq
|
||||
import java.util.*
|
||||
|
||||
class TransAdapter(private val pass: SatPass) : RecyclerView.Adapter<TransAdapter.TransHolder>() {
|
||||
@@ -38,13 +37,8 @@ class TransAdapter(private val pass: SatPass) : RecyclerView.Adapter<TransAdapte
|
||||
}
|
||||
|
||||
fun tickTransmitters() {
|
||||
if (!pass.satellite.tle.isDeepspace) {
|
||||
val iterator = transmittersList.listIterator()
|
||||
while (iterator.hasNext()) {
|
||||
val trans = iterator.next()
|
||||
val index = transmittersList.indexOf(trans)
|
||||
notifyItemChanged(index)
|
||||
}
|
||||
if (!pass.isDeepSpace) {
|
||||
notifyDataSetChanged()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -63,6 +57,7 @@ class TransAdapter(private val pass: SatPass) : RecyclerView.Adapter<TransAdapte
|
||||
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)
|
||||
@@ -74,7 +69,7 @@ class TransAdapter(private val pass: SatPass) : RecyclerView.Adapter<TransAdapte
|
||||
fun bind(satTrans: SatTrans, satPass: SatPass) {
|
||||
binding.description.text = satTrans.description
|
||||
|
||||
if (satPass.satellite.tle.isDeepspace) setRegularFreq(satTrans)
|
||||
if (satPass.isDeepSpace) setRegularFreq(satTrans)
|
||||
else setDopplerFreq(satTrans, satPass.predictor)
|
||||
|
||||
if (satTrans.mode != null) binding.mode.text = String.format(mode, satTrans.mode)
|
||||
@@ -97,18 +92,14 @@ class TransAdapter(private val pass: SatPass) : RecyclerView.Adapter<TransAdapte
|
||||
}
|
||||
|
||||
private fun setDopplerFreq(satTrans: SatTrans, predictor: PassPredictor) {
|
||||
val dateNow = Date()
|
||||
|
||||
if (satTrans.downlinkLow != null) {
|
||||
val rangeRate = predictor.getSatPos(dateNow).rangeRate
|
||||
val freq = satTrans.downlinkLow.getDopplerFreq(rangeRate, true) / divider
|
||||
binding.downlink.text = String.format(Locale.ENGLISH, formatLink, freq)
|
||||
val downlink = predictor.getDownlinkFreq(satTrans.downlinkLow, dateNow) / divider
|
||||
binding.downlink.text = String.format(Locale.ENGLISH, formatLink, downlink)
|
||||
} else binding.downlink.text = formatLinkNull
|
||||
|
||||
if (satTrans.uplinkLow != null) {
|
||||
val rangeRate = predictor.getSatPos(dateNow).rangeRate
|
||||
val freq = satTrans.uplinkLow.getDopplerFreq(rangeRate, false) / divider
|
||||
binding.uplink.text = String.format(Locale.ENGLISH, formatLink, freq)
|
||||
val uplink = predictor.getUplinkFreq(satTrans.uplinkLow, dateNow) / divider
|
||||
binding.uplink.text = String.format(Locale.ENGLISH, formatLink, uplink)
|
||||
} else binding.uplink.text = formatLinkNull
|
||||
}
|
||||
|
||||
|
||||
@@ -51,15 +51,6 @@ fun Long.formatForTimer(): String {
|
||||
return String.format(format, hours, minutes, seconds)
|
||||
}
|
||||
|
||||
fun Long.getDopplerFreq(rangeRate: Double, isDownlink: Boolean): Long {
|
||||
val speedOfLight = 2.99792458E8
|
||||
return if (isDownlink) {
|
||||
(this.toDouble() * (speedOfLight - rangeRate * 1000.0) / speedOfLight).toLong()
|
||||
} else {
|
||||
(this.toDouble() * (speedOfLight + rangeRate * 1000.0) / speedOfLight).toLong()
|
||||
}
|
||||
}
|
||||
|
||||
fun Double.round(decimals: Int): Double {
|
||||
var multiplier = 1.0
|
||||
repeat(decimals) { multiplier *= 10 }
|
||||
|
||||
@@ -20,7 +20,7 @@ package com.rtbishop.look4sat.utility
|
||||
import com.github.amsacode.predict4java.GroundStationPosition
|
||||
import com.github.amsacode.predict4java.SatPos
|
||||
import com.github.amsacode.predict4java.Satellite
|
||||
import com.rtbishop.look4sat.data.model.SatPassTime
|
||||
import com.rtbishop.look4sat.data.model.SatPass
|
||||
import java.util.*
|
||||
|
||||
class PassPredictor(private val satellite: Satellite, private val qth: GroundStationPosition) {
|
||||
@@ -53,9 +53,9 @@ class PassPredictor(private val satellite: Satellite, private val qth: GroundSta
|
||||
}
|
||||
return positions
|
||||
}
|
||||
|
||||
fun getPasses(refDate: Date, hoursAhead: Int, windBack: Boolean): List<SatPassTime> {
|
||||
val passes = mutableListOf<SatPassTime>()
|
||||
|
||||
fun getPasses(refDate: Date, hoursAhead: Int, windBack: Boolean): List<SatPass> {
|
||||
val passes = mutableListOf<SatPass>()
|
||||
val endDate = Date(refDate.time + hoursAhead * 60L * 60L * 1000L)
|
||||
var startDate = refDate
|
||||
var shouldWindBack = windBack
|
||||
@@ -68,34 +68,45 @@ class PassPredictor(private val satellite: Satellite, private val qth: GroundSta
|
||||
do {
|
||||
if (count > 0) shouldWindBack = false
|
||||
val pass = nextNearEarthPass(startDate, shouldWindBack)
|
||||
lastAosDate = pass.getStartTime()
|
||||
lastAosDate = pass.startDate
|
||||
passes.add(pass)
|
||||
startDate =
|
||||
Date(pass.getEndTime().time + (oneQuarterOrbitMin * 3) * 60L * 1000L)
|
||||
Date(pass.endDate.time + (oneQuarterOrbitMin * 3) * 60L * 1000L)
|
||||
count++
|
||||
} while (lastAosDate < endDate)
|
||||
}
|
||||
}
|
||||
return passes
|
||||
}
|
||||
|
||||
private fun nextDeepSpacePass(refDate: Date): SatPassTime {
|
||||
|
||||
private fun nextDeepSpacePass(refDate: Date): SatPass {
|
||||
val satPos = getSatPos(refDate)
|
||||
val startDate = Date(refDate.time - 24 * 60L * 60L * 1000L)
|
||||
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, azimuth, azimuth, maxEl)
|
||||
val id = satellite.tle.catnum
|
||||
val name = satellite.tle.name
|
||||
val isDeep = satellite.tle.isDeepspace
|
||||
val aos = Date(refDate.time - 24 * 60L * 60L * 1000L).time
|
||||
val los = Date(refDate.time + 24 * 60L * 60L * 1000L).time
|
||||
val tca = Date((aos + los) / 2).time
|
||||
val az = Math.toDegrees(satPos.azimuth)
|
||||
val elev = Math.toDegrees(satPos.elevation)
|
||||
val alt = satPos.altitude
|
||||
return SatPass(id, name, isDeep, aos, az, los, az, tca, az, alt, elev, this)
|
||||
}
|
||||
|
||||
private fun nextNearEarthPass(refDate: Date, windBack: Boolean = false): SatPassTime {
|
||||
|
||||
private fun nextNearEarthPass(refDate: Date, windBack: Boolean = false): SatPass {
|
||||
val calendar = Calendar.getInstance(TimeZone.getTimeZone("UTC")).apply {
|
||||
clear()
|
||||
timeInMillis = refDate.time
|
||||
}
|
||||
var maxElevation = 0.0
|
||||
val id = satellite.tle.catnum
|
||||
val name = satellite.tle.name
|
||||
val isDeep = satellite.tle.isDeepspace
|
||||
|
||||
var elevation: Double
|
||||
|
||||
var maxElevation = 0.0
|
||||
var alt = 0.0
|
||||
var tcaAz = 0.0
|
||||
|
||||
// wind back time 1/4 of an orbit
|
||||
if (windBack) calendar.add(Calendar.MINUTE, -oneQuarterOrbitMin)
|
||||
var satPos = getSatPos(calendar.time)
|
||||
@@ -115,7 +126,11 @@ class PassPredictor(private val satellite: Satellite, private val qth: GroundSta
|
||||
calendar.add(Calendar.SECOND, 60)
|
||||
satPos = getSatPos(calendar.time)
|
||||
elevation = satPos.elevation
|
||||
if (elevation > maxElevation) maxElevation = elevation
|
||||
if (elevation > maxElevation) {
|
||||
maxElevation = elevation
|
||||
alt = satPos.altitude
|
||||
tcaAz = Math.toDegrees(satPos.azimuth)
|
||||
}
|
||||
} while (satPos.elevation < 0.0)
|
||||
|
||||
// refine to 3 seconds
|
||||
@@ -124,18 +139,26 @@ class PassPredictor(private val satellite: Satellite, private val qth: GroundSta
|
||||
calendar.add(Calendar.SECOND, 3)
|
||||
satPos = getSatPos(calendar.time)
|
||||
elevation = satPos.elevation
|
||||
if (elevation > maxElevation) maxElevation = elevation
|
||||
if (elevation > maxElevation) {
|
||||
maxElevation = elevation
|
||||
alt = satPos.altitude
|
||||
tcaAz = Math.toDegrees(satPos.azimuth)
|
||||
}
|
||||
} while (satPos.elevation < 0.0)
|
||||
|
||||
val startDate = satPos.time
|
||||
val aosAzimuth = Math.toDegrees(satPos.azimuth).toInt()
|
||||
val aos = satPos.time.time
|
||||
val aosAz = Math.toDegrees(satPos.azimuth)
|
||||
|
||||
// find when sat goes below
|
||||
do {
|
||||
calendar.add(Calendar.SECOND, 30)
|
||||
satPos = getSatPos(calendar.time)
|
||||
elevation = satPos.elevation
|
||||
if (elevation > maxElevation) maxElevation = elevation
|
||||
if (elevation > maxElevation) {
|
||||
maxElevation = elevation
|
||||
alt = satPos.altitude
|
||||
tcaAz = Math.toDegrees(satPos.azimuth)
|
||||
}
|
||||
} while (satPos.elevation > 0.0)
|
||||
|
||||
// refine to 3 seconds
|
||||
@@ -144,12 +167,17 @@ class PassPredictor(private val satellite: Satellite, private val qth: GroundSta
|
||||
calendar.add(Calendar.SECOND, 3)
|
||||
satPos = getSatPos(calendar.time)
|
||||
elevation = satPos.elevation
|
||||
if (elevation > maxElevation) maxElevation = elevation
|
||||
if (elevation > maxElevation) {
|
||||
maxElevation = elevation
|
||||
alt = satPos.altitude
|
||||
tcaAz = Math.toDegrees(satPos.azimuth)
|
||||
}
|
||||
} while (satPos.elevation > 0.0)
|
||||
|
||||
val endDate = satPos.time
|
||||
val losAzimuth = Math.toDegrees(satPos.azimuth).toInt()
|
||||
val maxEl = Math.toDegrees(maxElevation)
|
||||
return SatPassTime(startDate, endDate, aosAzimuth, losAzimuth, maxEl)
|
||||
val los = satPos.time.time
|
||||
val losAz = Math.toDegrees(satPos.azimuth)
|
||||
val tca = Date((aos + los) / 2).time
|
||||
val elev = Math.toDegrees(maxElevation)
|
||||
return SatPass(id, name, isDeep, aos, aosAz, los, losAz, tca, tcaAz, alt, elev, this)
|
||||
}
|
||||
}
|
||||
@@ -22,9 +22,9 @@
|
||||
|
||||
<string name="passes_error">Нет предстоящих пролётов</string>
|
||||
|
||||
<string name="pass_aosAz">НПС - %2d°</string>
|
||||
<string name="pass_aosAz">НПС - %.1f°</string>
|
||||
<string name="pass_maxEl">МаксЭлев: %.1f°</string>
|
||||
<string name="pass_losAz">%2d° - КПС</string>
|
||||
<string name="pass_losAz">%.1f° - КПС</string>
|
||||
|
||||
<string name="trans_mode">Модуляция: %s</string>
|
||||
<string name="trans_no_mode">Модуляция: нет</string>
|
||||
|
||||
@@ -30,9 +30,9 @@
|
||||
|
||||
<string name="pass_satName" translatable="false">%s</string>
|
||||
<string name="pass_satId" translatable="false">Id:%d</string>
|
||||
<string name="pass_aosAz">AOS - %2d°</string>
|
||||
<string name="pass_aosAz">AOS - %.1f°</string>
|
||||
<string name="pass_maxEl">MaxEl: %.1f°</string>
|
||||
<string name="pass_losAz">%2d° - LOS</string>
|
||||
<string name="pass_losAz">%.1f° - LOS</string>
|
||||
<string name="pass_startTime" translatable="false">HH:mm:ss - EEE</string>
|
||||
<string name="pass_endTime" translatable="false">EEE - HH:mm:ss</string>
|
||||
|
||||
|
||||
Reference in new issue
Block a user