mirror of
https://github.com/atsunatsu/Look4Sat.git
synced 2026-10-02 03:15:37 +00:00
fix: reuse main page pass list for mutual search
findMutualPasses was computing passes independently with its own search algorithm, which produced different results from the main page's getLeoPass. Now it directly reuses satelliteRepo.passes, which is the same list shown on the main passes page. The only additional computation is refining the common window for station B and sampling elevation/azimuth curves.
This commit is contained in:
1 parent
43788ba7a7
commit
86ee3dcbac
1 file changed
+48
-51
+48
-51
@@ -210,63 +210,60 @@ class MutualViewModel(
|
|||||||
val endTime = time + hours * 60L * 60L * 1000L
|
val endTime = time + hours * 60L * 60L * 1000L
|
||||||
val sampleInterval = 5_000L // 5 seconds between samples for smooth curves
|
val sampleInterval = 5_000L // 5 seconds between samples for smooth curves
|
||||||
|
|
||||||
for (sat in satellites) {
|
// Reuse the main page's pass list (calculated by getLeoPass/getGeoPass)
|
||||||
if (sat.data.meanmo < 1e-8) continue
|
// so the mutual pass times match the main page exactly.
|
||||||
var searchStart = time
|
val existingPasses = satelliteRepo.passes.value
|
||||||
// Find ALL mutual passes for this satellite
|
for (pass in existingPasses) {
|
||||||
while (true) {
|
if (pass.losTime <= time || pass.aosTime >= endTime) continue
|
||||||
val t = findNextMutualPass(sat, posA, posB, searchStart, endTime)
|
if (pass.isDeepSpace) continue
|
||||||
if (t == null) break
|
if (pass.orbitalObject.data.meanmo < 1e-8) continue
|
||||||
val (aos, los) = t
|
|
||||||
|
|
||||||
// Refine AOS: finer search near the edge (0° horizon, like the main radar)
|
val sat = pass.orbitalObject
|
||||||
val refinedAos = refineEdge(sat, posA, posB, aos, step = 1_000L, goingUp = true)
|
// Refine the common window: AOS = max(A's AOS, B's horizon crossing)
|
||||||
// Refine LOS: finer search near the edge
|
val refinedAos = refineEdge(sat, posA, posB, pass.aosTime, 1_000L, goingUp = true)
|
||||||
val refinedLos = refineEdge(sat, posA, posB, los, step = 1_000L, goingUp = false)
|
val refinedLos = refineEdge(sat, posA, posB, pass.losTime, 1_000L, goingUp = false)
|
||||||
|
if (refinedLos <= refinedAos) continue
|
||||||
|
|
||||||
val samples = mutableListOf<Pair<Long, Pair<Double, Double>>>()
|
val samples = mutableListOf<Pair<Long, Pair<Double, Double>>>()
|
||||||
val tracks = mutableListOf<TrackSample>()
|
val tracks = mutableListOf<TrackSample>()
|
||||||
var maxElevA = 0.0
|
var maxElevA = 0.0
|
||||||
var maxElevB = 0.0
|
var maxElevB = 0.0
|
||||||
|
|
||||||
var tSample = refinedAos
|
var tSample = refinedAos
|
||||||
while (tSample <= refinedLos) {
|
while (tSample <= refinedLos) {
|
||||||
val fullA = sat.getFullPosition(posA, tSample)
|
val fullA = sat.getFullPosition(posA, tSample)
|
||||||
val fullB = sat.getFullPosition(posB, tSample)
|
val fullB = sat.getFullPosition(posB, tSample)
|
||||||
val elevA = fullA.elevation * 180.0 / PI
|
val elevA = fullA.elevation * 180.0 / PI
|
||||||
val elevB = fullB.elevation * 180.0 / PI
|
val elevB = fullB.elevation * 180.0 / PI
|
||||||
if (elevA > maxElevA) maxElevA = elevA
|
if (elevA > maxElevA) maxElevA = elevA
|
||||||
if (elevB > maxElevB) maxElevB = elevB
|
if (elevB > maxElevB) maxElevB = elevB
|
||||||
samples.add(tSample to (elevA to elevB))
|
samples.add(tSample to (elevA to elevB))
|
||||||
tracks.add(
|
tracks.add(
|
||||||
TrackSample(
|
TrackSample(
|
||||||
time = tSample,
|
time = tSample,
|
||||||
azimuthA = fullA.azimuth * 180.0 / PI,
|
azimuthA = fullA.azimuth * 180.0 / PI,
|
||||||
elevationA = elevA,
|
elevationA = elevA,
|
||||||
azimuthB = fullB.azimuth * 180.0 / PI,
|
azimuthB = fullB.azimuth * 180.0 / PI,
|
||||||
elevationB = elevB
|
elevationB = elevB
|
||||||
)
|
|
||||||
)
|
)
|
||||||
tSample += sampleInterval
|
)
|
||||||
}
|
tSample += sampleInterval
|
||||||
|
}
|
||||||
|
|
||||||
// Both stations must reach their own min elevation for a usable mutual pass
|
// Both stations must reach their own min elevation for a usable mutual pass
|
||||||
if (maxElevA > minElevADeg && maxElevB > minElevBDeg) {
|
if (maxElevA > minElevADeg && maxElevB > minElevBDeg) {
|
||||||
results.add(
|
results.add(
|
||||||
MutualPass(
|
MutualPass(
|
||||||
catNum = sat.data.catnum,
|
catNum = pass.catNum,
|
||||||
name = sat.data.name,
|
name = pass.orbitalObject.data.name,
|
||||||
startTime = refinedAos,
|
startTime = refinedAos,
|
||||||
endTime = refinedLos,
|
endTime = refinedLos,
|
||||||
maxElevationA = (maxElevA * 10).roundToInt() / 10.0,
|
maxElevationA = (maxElevA * 10).roundToInt() / 10.0,
|
||||||
maxElevationB = (maxElevB * 10).roundToInt() / 10.0,
|
maxElevationB = (maxElevB * 10).roundToInt() / 10.0,
|
||||||
elevationSamples = samples,
|
elevationSamples = samples,
|
||||||
trackSamples = tracks
|
trackSamples = tracks
|
||||||
)
|
|
||||||
)
|
)
|
||||||
}
|
)
|
||||||
// Advance past this pass and keep searching
|
|
||||||
searchStart = refinedLos + 120_000L
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return results
|
return results
|
||||||
|
|||||||
Reference in new issue
Block a user