From dc92bf1ab12dcac1443aaa1d7ad9613e34942573 Mon Sep 17 00:00:00 2001 From: Arty Bishop Date: Sun, 5 Sep 2021 20:34:38 +0100 Subject: [PATCH] Various changes to predict4kotlin classes --- .../satMapScreen/SatMapViewModel.kt | 2 +- .../domain/predict4kotlin/PassPredictor.kt | 39 +++++++++++ .../look4sat/domain/predict4kotlin/SatPos.kt | 65 ++++-------------- .../domain/predict4kotlin/SatelliteFactory.kt | 66 +++++++++++++++++++ .../com/rtbishop/look4sat/QthConverterTest.kt | 2 +- 5 files changed, 118 insertions(+), 56 deletions(-) create mode 100644 core/src/main/java/com/rtbishop/look4sat/domain/predict4kotlin/SatelliteFactory.kt diff --git a/app/src/main/java/com/rtbishop/look4sat/presentation/satMapScreen/SatMapViewModel.kt b/app/src/main/java/com/rtbishop/look4sat/presentation/satMapScreen/SatMapViewModel.kt index 1ae4d04e..8e53ba3e 100644 --- a/app/src/main/java/com/rtbishop/look4sat/presentation/satMapScreen/SatMapViewModel.kt +++ b/app/src/main/java/com/rtbishop/look4sat/presentation/satMapScreen/SatMapViewModel.kt @@ -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) diff --git a/core/src/main/java/com/rtbishop/look4sat/domain/predict4kotlin/PassPredictor.kt b/core/src/main/java/com/rtbishop/look4sat/domain/predict4kotlin/PassPredictor.kt index 51a904fb..815256dd 100644 --- a/core/src/main/java/com/rtbishop/look4sat/domain/predict4kotlin/PassPredictor.kt +++ b/core/src/main/java/com/rtbishop/look4sat/domain/predict4kotlin/PassPredictor.kt @@ -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 { + val satPos = getSatPos(date) + val positions = mutableListOf() + 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 diff --git a/core/src/main/java/com/rtbishop/look4sat/domain/predict4kotlin/SatPos.kt b/core/src/main/java/com/rtbishop/look4sat/domain/predict4kotlin/SatPos.kt index fe9dc1af..4e1e3d90 100644 --- a/core/src/main/java/com/rtbishop/look4sat/domain/predict4kotlin/SatPos.kt +++ b/core/src/main/java/com/rtbishop/look4sat/domain/predict4kotlin/SatPos.kt @@ -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 { - val positions = mutableListOf() - 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() +) diff --git a/core/src/main/java/com/rtbishop/look4sat/domain/predict4kotlin/SatelliteFactory.kt b/core/src/main/java/com/rtbishop/look4sat/domain/predict4kotlin/SatelliteFactory.kt new file mode 100644 index 00000000..09096c1b --- /dev/null +++ b/core/src/main/java/com/rtbishop/look4sat/domain/predict4kotlin/SatelliteFactory.kt @@ -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): 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): 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 { + val elementArray = arrayOf(String(), String(), String()) + val importedElements = mutableListOf() + 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 + } +} \ No newline at end of file diff --git a/core/src/test/java/com/rtbishop/look4sat/QthConverterTest.kt b/core/src/test/java/com/rtbishop/look4sat/QthConverterTest.kt index 28c3d140..538a6c6c 100644 --- a/core/src/test/java/com/rtbishop/look4sat/QthConverterTest.kt +++ b/core/src/test/java/com/rtbishop/look4sat/QthConverterTest.kt @@ -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) }