Various changes to predict4kotlin classes

pull/70/head
Arty Bishop 2021-09-05 20:34:38 +01:00
rodzic 5460ed2a6c
commit dc92bf1ab1
5 zmienionych plików z 118 dodań i 56 usunięć

Wyświetl plik

@ -154,7 +154,7 @@ class SatMapViewModel @Inject constructor(
private suspend fun setSelectedSatFootprint(sat: Satellite, gsp: StationPosition, date: Date) {
withContext(defaultDispatcher) {
val satFootprint = sat.getPosition(gsp, date).getRangeCircle().map { rangePos ->
val satFootprint = sat.getPredictor(gsp).getRangeCircle(date).map { rangePos ->
val osmLat = clipLat(rangePos.latitude)
val osmLon = clipLon(rangePos.longitude)
Position(osmLat, osmLon)

Wyświetl plik

@ -18,11 +18,50 @@
package com.rtbishop.look4sat.domain.predict4kotlin
import java.util.*
import kotlin.math.*
class PassPredictor(private val satellite: Satellite, private val stationPos: StationPosition) {
private val oneQuarterOrbitMin = (24.0 * 60.0 / satellite.tle.meanmo / 4.0).toInt()
private val speedOfLight = 2.99792458E8
private val earthRadiusKm = 6378.16
fun getRangeCircle(date: Date): List<Position> {
val satPos = getSatPos(date)
val positions = mutableListOf<Position>()
val lat = satPos.latitude
val lon = satPos.longitude
// rangeCircleRadiusKm
// earthRadiusKm * acos(earthRadiusKm / (earthRadiusKm + satPos.altitude))
val beta = acos(earthRadiusKm / (earthRadiusKm + satPos.altitude))
var tempAzimuth = 0
while (tempAzimuth < 360) {
val azimuth = tempAzimuth / 360.0 * 2.0 * Math.PI
var rangelat = asin(sin(lat) * cos(beta) + cos(azimuth) * sin(beta) * cos(lat))
val num = (cos(beta) - (sin(lat) * sin(rangelat)))
val den = cos(lat) * cos(rangelat)
var rangelon = if (tempAzimuth == 0 && (beta > ((Math.PI / 2.0) - lat))) {
lon + Math.PI
} else if (tempAzimuth == 180 && (beta > ((Math.PI / 2.0) - lat))) {
lon + Math.PI
} else if (abs(num / den) > 1.0) {
lon
} else {
if ((180 - tempAzimuth) >= 0) {
lon - acos(num / den)
} else {
lon + acos(num / den)
}
}
while (rangelon < 0.0) rangelon += Math.PI * 2.0
while (rangelon > Math.PI * 2.0) rangelon -= Math.PI * 2.0
rangelat = Math.toDegrees(rangelat)
rangelon = Math.toDegrees(rangelon)
positions.add(Position(rangelat, rangelon))
tempAzimuth += 1
}
return positions
}
fun getDownlinkFreq(freq: Long, date: Date): Long {
val rangeRate = getSatPos(date).rangeRate

Wyświetl plik

@ -18,58 +18,15 @@
package com.rtbishop.look4sat.domain.predict4kotlin
import java.util.*
import kotlin.math.*
class SatPos {
private val earthRadiusKm = 6378.16
// Radians
var azimuth = 0.0
var elevation = 0.0
var latitude = 0.0
var longitude = 0.0
var altitude = 0.0
var range = 0.0
var rangeRate = 0.0
var theta = 0.0
var time = Date()
fun getRangeCircleRadiusKm(): Double {
return earthRadiusKm * acos(earthRadiusKm / (earthRadiusKm + altitude))
}
fun getRangeCircle(incrementDegrees: Double = 1.0): List<Position> {
val positions = mutableListOf<Position>()
val lat = this.latitude
val lon = this.longitude
val beta = getRangeCircleRadiusKm() / earthRadiusKm
var tempAzimuth = 0
while (tempAzimuth < 360) {
val azimuth = tempAzimuth / 360.0 * 2.0 * Math.PI
var rangelat = asin(sin(lat) * cos(beta) + cos(azimuth) * sin(beta) * cos(lat))
val num = (cos(beta) - (sin(lat) * sin(rangelat)))
val den = cos(lat) * cos(rangelat)
var rangelon = if (tempAzimuth == 0 && (beta > ((Math.PI / 2.0) - lat))) {
lon + Math.PI
} else if (tempAzimuth == 180 && (beta > ((Math.PI / 2.0) - lat))) {
lon + Math.PI
} else if (abs(num / den) > 1.0) {
lon
} else {
if ((180 - tempAzimuth) >= 0) {
lon - acos(num / den)
} else {
lon + acos(num / den)
}
}
while (rangelon < 0.0) rangelon += Math.PI * 2.0
while (rangelon > Math.PI * 2.0) rangelon -= Math.PI * 2.0
rangelat = Math.toDegrees(rangelat)
rangelon = Math.toDegrees(rangelon)
positions.add(Position(rangelat, rangelon))
tempAzimuth += incrementDegrees.toInt()
}
return positions
}
}
data class SatPos(
var azimuth: Double = 0.0,
var elevation: Double = 0.0,
var latitude: Double = 0.0,
var longitude: Double = 0.0,
var altitude: Double = 0.0,
var range: Double = 0.0,
var rangeRate: Double = 0.0,
var theta: Double = 0.0,
var time: Date = Date()
)

Wyświetl plik

@ -0,0 +1,66 @@
package com.rtbishop.look4sat.domain.predict4kotlin
import java.io.InputStream
import kotlin.math.pow
object SatelliteFactory {
fun createSat(tle: TLE?): Satellite? {
return when {
tle == null -> null
tle.isDeepspace -> DeepSpaceSat(tle)
else -> NearEarthSat(tle)
}
}
fun createSat(array: Array<String>): Satellite? {
val importedElement = importElement(array)
return createSat(importedElement)
}
fun createDummySat(): Satellite? {
val elementArray = arrayOf(
"ISS (ZARYA)",
"1 25544U 98067A 21242.56000419 .00070558 00000-0 12956-2 0 9996",
"2 25544 51.6433 334.9559 0003020 334.9496 106.9882 15.48593918300128"
)
return createSat(importElement(elementArray))
}
fun importElement(array: Array<String>): TLE? {
if (array.size != 3) return null
try {
val name: String = array[0].trim()
val epoch: Double = array[1].substring(18, 32).toDouble()
val meanmo: Double = array[2].substring(52, 63).toDouble()
val eccn: Double = 1.0e-07 * array[2].substring(26, 33).toDouble()
val incl: Double = array[2].substring(8, 16).toDouble()
val raan: Double = array[2].substring(17, 25).toDouble()
val argper: Double = array[2].substring(34, 42).toDouble()
val meanan: Double = array[2].substring(43, 51).toDouble()
val catnum: Int = array[1].substring(2, 7).trim().toInt()
val bstar: Double = 1.0e-5 * array[1].substring(53, 59).toDouble() /
10.0.pow(array[1].substring(60, 61).toDouble())
return TLE(name, epoch, meanmo, eccn, incl, raan, argper, meanan, catnum, bstar)
} catch (exception: Exception) {
return null
}
}
fun importElements(stream: InputStream): List<TLE> {
val elementArray = arrayOf(String(), String(), String())
val importedElements = mutableListOf<TLE>()
var line = 0
stream.bufferedReader().forEachLine {
if (line != 2) {
elementArray[line] = it
line++
} else {
elementArray[line] = it
importElement(elementArray)?.let { tle -> importedElements.add(tle) }
line = 0
}
}
return importedElements
}
}

Wyświetl plik

@ -53,7 +53,7 @@ class QthConverterTest {
}
@Test
fun `Given invalid location returns null`() {
fun `Given invalid POS returns null`() {
assert(qthConverter.positionToQTH(91.0542, -170.1142) == null)
assert(qthConverter.positionToQTH(89.0542, -240.1142) == null)
}