This commit is contained in:
Дмитрий Соловьев
2026-05-25 14:23:52 +03:00
parent b3a6012ebb
commit d48ddd2657
1066 changed files with 104601 additions and 3 deletions
+165
View File
@@ -0,0 +1,165 @@
import ballistics.Ballistics
import ballistics.types.InitialConditions
import ballistics.types.IntegrationType
import ballistics.types.ModDVType
import ballistics.types.OrbitalPoint
import ballistics.utils.fromDateTime
import ballistics.utils.math.Vector3D
import ballistics.utils.toDateTime
import java.time.LocalDateTime
import java.time.ZoneOffset
fun main() {
var ts = System.currentTimeMillis()
val r = Ballistics()
r.modDVType = ModDVType.BARS // BARS
r.integrationType = IntegrationType.ADAMS7
val mnu = mutableListOf<InitialConditions>()
mnu.add(
InitialConditions(
OrbitalPoint(
LocalDateTime.of(2021, 12, 3, 0, 5, 45, 0).toEpochSecond(ZoneOffset.UTC).toDouble(),
1,
Vector3D(
-5357933.7872,
4328646.1787,
0.0,
),
Vector3D(
941.8995373,
1150.6919822,
7544.9920840,
),
),
0.0061,
125.0,
),
)
/*
mnu.add(InitialConditions(OrbitalPoint(1681135417.0,
1499,
6782429.138044466,
-1205586.994919729,
0.0,
-272.89561674108205,
-1460.1016031205972,
7539.209413654664),
0.0,
100.0)
)
mnu.add(InitialConditions(OrbitalPoint(1681203547.0,
1511,
2796871.797932365,
6295220.245166648,
0.0,
1351.432690993002,
-615.1950685524682,
7539.420044409451),
0.0,
100.0)
)
mnu.add(InitialConditions(OrbitalPoint(1681288710.0,
1526,
2219522.8066600505,
6520960.574145492,
0.0,
1401.0525909402313,
-491.90052480161194,
7539.654233369637),
0.0,
100.0)
)
mnu.add(InitialConditions(OrbitalPoint(1681373873.0,
1541,
1624190.3979707498,
6693858.330353258,
0.0,
1439.4621272728175,
-364.5959436771924,
7539.927000039702),
0.0,
100.0)
)
mnu.add(InitialConditions(OrbitalPoint(1681464714.0,
1557,
3663882.4989639986,
5832354.67692114,
0.0,
1249.158953470858,
-802.9876366520331,
7540.375561571017),
0.0,
100.0)
)
mnu.add(InitialConditions(OrbitalPoint(1681538522.0,
1570,
-2393483.7360840607,
6458206.838182452,
0.0,
1398.0568057512764,
501.055477122656,
7540.680958625912),
0.0,
100.0)
)
*/
mnu.sortBy { it.point.t }
// r.calculateOrbPoints(mnu.toTypedArray(), mnu.first().point.t, mnu.last().point.t+86400.0 * 5 )
r.calculateOrbPoints(mnu.toTypedArray(), mnu.first().point.t, mnu.first().point.t + 86400.0 * 5)
println("время расчета = ${System.currentTimeMillis() - ts}мс")
// for (p in r.points)
// println("${p.vit} ${LocalDateTime.ofEpochSecond(p.t.toLong(),0, ZoneOffset.UTC)} ${p.r.x} ${p.r.y} ${p.r.z} ${p.v.x} ${p.v.y} ${p.v.z}")
//
ts = System.currentTimeMillis()
r.calculateFlightLine(mnu.first().point.t, mnu.first().point.t + 86400.0 * 5)
println("время расчета = ${System.currentTimeMillis() - ts}мс")
// var p = r.points.last()
// println("${p.vit} ${LocalDateTime.ofEpochSecond(p.t.toLong(),0, ZoneOffset.UTC)} ${p.x} ${p.y} ${p.z} ${p.vx} ${p.vy} ${p.vz}")
//
// var st = r.getStepper()
// st?.let{
// var p = it.calculate(nu.point.t + 120.0)//452.4)
// p?.let {
// println(
// "${p.vit} ${
// LocalDateTime.ofEpochSecond(
// p.t.toLong(),
// 0,
// ZoneOffset.UTC
// )
// } ${p.x} ${p.y} ${p.z} ${p.vx} ${p.vy} ${p.vz}"
// )
// }
// } ?: println("is null")
//
// //
// // val ts2 = System.currentTimeMillis()
// var ppi = mutableListOf<PPI>(PPI(1000, 0, 0.36617007706841037, 1.8417344524829609,
// 0.0, 0.08726646259971647, 1.5707963267948966))
// try{
// r.calculateZRV(ppi, mnu.first().point.t, mnu.last().point.t+86400.0 * 5)
// println(r.zrv.size)
// }
// catch(e : Exception){
// println("err")
// }
// println("время расчета = ${System.currentTimeMillis()-ts}мс ЗРВ : ${r.zrv.size}")
}
@@ -0,0 +1,86 @@
package ballistics
import ballistics.orbitalPoints.timeStepper.TLEStepper
import ballistics.types.BallisticsError
import ballistics.types.EarthType
import ballistics.types.InitialConditions
import ballistics.types.OPKatObj
import ballistics.types.TLE
import org.junit.jupiter.api.Assertions.assertEquals
import org.junit.jupiter.api.Assertions.assertTrue
import org.junit.jupiter.api.Test
import java.time.LocalDateTime
import java.time.ZoneOffset
import kotlin.math.PI
internal class BallisticsTest {
@Test
fun parseTLE() {
var s1 = "1 51824U 22019A 22058.83400146 .00001503 00000-0 10000-3 0 9990"
var s2 = "2 51824 97.5213 135.6262 0019439 268.1769 91.7238 15.08515864 114"
var s = TLEStepper(s1, s2, EarthType.PZ90d02)
var r = s.baseEpoch
println("${ LocalDateTime.ofEpochSecond(r.toLong(),(r % 1 * 1e9).toInt(), ZoneOffset.UTC)} ")
var p = s.calculate(r)
println(
"${p.vit} ${ p.let { LocalDateTime.ofEpochSecond(p.t.toLong(),(p.t % 1 * 1e9).toInt(), ZoneOffset.UTC)} } " +
"${p.r.x} " +
" ${p.r.y} " +
"${p.r.z} " +
" ${p.v.x} " +
"${p.v.y} " +
" ${p.v.z}",
)
}
@Test
fun testTLE() {
val tle =
// TLE(
// "1 51824U 22019A 22058.83400146 .00001503 00000-0 10000-3 0 9990",
// "2 51824 97.5213 135.6262 0019439 268.1769 91.7238 15.08515864 114",
// )
TLE(
"1 45621U 11037Q 22018.21004500 .07428171 00000-0 19069+0 0 9999",
"2 45621 51.4607 277.9348 0211635 34.9395 326.5259 15.14655454 76661",
)
val bal1 = Ballistics()
val bal2 = Ballistics()
bal1.sunAngleMin = -90 * PI / 180
bal2.sunAngleMin = -90 * PI / 180
val op = bal1.parseTLE(tle)
val tn = op.t
val tk = tn + 86400 * 2
val r = bal1.calculateOrbPoints(tle, tn, tk)
assertTrue(r == BallisticsError.OK)
bal2.calculateOrbPoints(InitialConditions(op, 0.0, 0.0), tn, tk)
bal1.calculateFlightLine(tn, tk)
bal2.calculateFlightLine(tn, tk)
val objs = listOf<OPKatObj>(OPKatObj(1, 1, "t",1, 60 * PI / 180, 20 * PI / 180, 100.0, 0.0, 90.0, -90.0))
bal1.calculateMPL(tn, tk, objs)
bal2.calculateMPL(tn, tk, objs)
println("${bal1.mpl.count()} - ${bal2.mpl.count()}")
assertEquals(bal1.mpl.count(), bal2.mpl.count())
if (bal1.mpl.toList().isNotEmpty()) {
val v1 = bal1.mpl.first()
val v2 = bal2.mpl.first()
assertTrue(v1.traverz - v2.traverz < 60)
}
}
}
@@ -0,0 +1,134 @@
package ballistics.flightLine
import ballistics.Ballistics
import ballistics.types.BallisticsError
import ballistics.types.EarthType
import ballistics.types.InitialConditions
import ballistics.types.IntegrationType
import ballistics.types.ModDVType
import ballistics.types.OrbitalPoint
import ballistics.types.WorkCSType
import ballistics.utils.math.Vector3D
import org.junit.jupiter.api.Assertions.assertEquals
import org.junit.jupiter.api.Test
import java.time.LocalDateTime
import java.time.ZoneOffset
import kotlin.math.PI
internal class FlightLineCalculatorTest {
@Test
fun testFL() {
var r = Ballistics()
r.earthType = EarthType.PZ90d02
r.modDVType = ModDVType.FOTO
r.integrationType = IntegrationType.ADAMS7
r.workCoordinateSystem = WorkCSType.WCSOrbit
r.rollMax = 30 * PI / 180
var mnu = mutableListOf<InitialConditions>()
var tt1 = LocalDateTime.of(2023, 6, 20, 4, 18, 40, 180000000)
var tt2 = LocalDateTime.of(2023, 6, 19, 3, 17, 49, 251000000)
mnu.add(
InitialConditions(
OrbitalPoint(
tt1.toEpochSecond(ZoneOffset.UTC).toDouble(), // 1687238300.0,
18721,
Vector3D(
-6603039.949152646,
-1870023.1481177735,
0.0,
),
Vector3D(
-401.5289935173786,
1413.4309568106378,
7547.69556621523,
),
),
0.014542,
125.0,
),
)
mnu.add(
InitialConditions(
OrbitalPoint(
tt2.toEpochSecond(ZoneOffset.UTC).toDouble(), // 1687238300.0,
18705,
Vector3D(
-5880984.961878717,
-3535801.795084351,
0.0,
),
Vector3D(
-759.5481166352387,
1257.702405545223,
7548.463786464257,
),
),
0.014542,
125.0,
),
)
mnu.sortBy { it.point.t }
var t = LocalDateTime.now().toEpochSecond(ZoneOffset.UTC)
var rez = r.calculateOrbPoints(mnu.toTypedArray(), mnu.first().point.t, mnu.first().point.t + 86400.0 * 3)
var t2 = LocalDateTime.now().toEpochSecond(ZoneOffset.UTC)
println("расчет точек орибты за ${t2 - t} с")
// for (fl in r.points)
// println("${fl.vit} ${LocalDateTime.ofEpochSecond(fl.t.toLong(),0, ZoneOffset.UTC)} ${fl.r}")
if (rez == BallisticsError.OK) {
t = LocalDateTime.now().toEpochSecond(ZoneOffset.UTC)
var rezfl = r.calculateFlightLine(mnu.first().point.t, mnu.first().point.t + 86400.0 * 3)
t2 = LocalDateTime.now().toEpochSecond(ZoneOffset.UTC)
println("расчет ТП и ПО за ${t2 - t} с")
for (fl in r.flightLine) {
println(
"${fl.vit} ${LocalDateTime.ofEpochSecond(fl.t.toLong(),0, ZoneOffset.UTC)} " +
" ${fl.leftOuterSwath.lat * 180.0 / PI} ${fl.leftOuterSwath.long * 180 / PI} " +
" ${fl.flightLine.lat * 180.0 / PI} ${fl.flightLine.long * 180 / PI} " +
" ${fl.rightOuterSwath.lat * 180.0 / PI} ${fl.rightOuterSwath.long * 180 / PI}",
)
}
// assertEquals(/* expected = */BallisticsError.OK, /* actual = */rezfl )
}
/*var opKatObj = mutableListOf<OPKatObj>()
var b = -PI/ 2
var l = 0.0
while (b <= PI /2){
while (l <= PI * 2){
opKatObj.add(OPKatObj(1,1,1,b,l,0.0,0.0,PI/2,0.0))
l += 0.2 * PI / 180
}
b += 0.2 * PI / 180
l = 0.0
}
println(opKatObj.count())
t = LocalDateTime.now().toEpochSecond(ZoneOffset.UTC)
rez= r.calculateMPL(mnu.first().point.t, mnu.first().point.t+86400.0 * 3, opKatObj)
t2 = LocalDateTime.now().toEpochSecond(ZoneOffset.UTC)
println(r.mpl.count())
println("расчет МПЛ за ${t2-t}")*/
// println("$rez")
// for (t in r.mpl)
// println("${t.vit} ${LocalDateTime.ofEpochSecond(t.traverz.toLong(),(t.traverz %1 * 1e9).toInt(), ZoneOffset.UTC)} ${t.orientation.kren * 180.0 / PI}" +
// " ${t.range} ${t.sunAngle * 180 / PI}")
assertEquals(
// expected =
BallisticsError.OK,
// actual =
rez,
)
}
}
@@ -0,0 +1,115 @@
package ballistics.orbitalPoints
import ballistics.Ballistics
import ballistics.types.*
import ballistics.utils.math.Vector3D
import org.junit.jupiter.api.Assertions.assertEquals
import org.junit.jupiter.api.Assertions.assertTrue
import org.junit.jupiter.api.Test
import java.time.LocalDateTime
import java.time.ZoneOffset
import kotlin.math.PI
internal class OrbitalPointsIntegratorTest {
@Test
fun testMDBARS() {
val r = Ballistics()
r.earthType = EarthType.PZ90d02
r.modDVType = ModDVType.BARS
r.integrationType = IntegrationType.ADAMS7
val mnu = mutableListOf<InitialConditions>()
mnu.add(
InitialConditions(
OrbitalPoint(
LocalDateTime.of(2021, 12, 3, 0, 5, 45, 0).toEpochSecond(ZoneOffset.UTC).toDouble(),
1,
Vector3D(
-5357933.7872,
4328646.1787,
0.0,
),
Vector3D(
941.8995373,
1150.6919822,
7544.9920840,
),
),
0.0061,
125.0,
),
)
val rez = r.calculateOrbPoints(mnu.toTypedArray(), mnu.first().point.t, mnu.first().point.t + 86400.0 * 3)
for (p in r.revolutions) {
println(
"${p.vuz.vit} ${LocalDateTime.ofEpochSecond(p.vuz.t.toLong(),0, ZoneOffset.UTC)} " +
"${p.lVuz * 180.0 / PI} " +
" ${p.hVuz} " +
"${p.vuz.r.x} " +
" ${p.vuz.r.y} " +
"${p.vuz.r.z} " +
" ${p.vuz.v.x} " +
"${p.vuz.v.y} " +
" ${p.vuz.v.z}",
)
}
val p = r.points.last()
println(
"${p.vit} ${LocalDateTime.ofEpochSecond(
p.t.toLong(),
0,
ZoneOffset.UTC,
)} ${p.r.x} ${p.r.y} ${p.r.z} ${p.v.x} ${p.v.y} ${p.v.z}",
)
val rc = Vector3D(r.points.last().r.x, r.points.last().r.y, r.points.last().r.z)
val vc = Vector3D(r.points.last().v.x, r.points.last().v.y, r.points.last().v.z)
val rex = Vector3D(4723743.916, -4261060.842, -2647685.695)
val vex = Vector3D(-3168.702, 797.721, -6953.781)
val dr = (rc - rex).module()
val dv = (vex - vc).module()
println(dr)
println(dv)
assertEquals(
BallisticsError.OK,
rez,
)
assertTrue(
dr < 0.01,
"Ошибка прогноза по радиус-вектору",
)
assertTrue(dv < 0.01, "ошибка прогноза по вектору скорости")
}
// fun initOrekitData() {
// val dataDir = File("src/main/resources/orekit-data-main") // or absolute path
// if (!dataDir.exists()) {
// throw IllegalStateException("Orekit data directory not found at ${dataDir.absolutePath}")
// }
// val crawler = DirectoryCrawler(dataDir)
// DataProvidersManager.getInstance().addProvider(crawler)
// }
// @Test
// fun orekitTest(){
//
// initOrekitData()
//
// val l1 = "1 00666U 18111A 25349.99139990 .00002772 00000+0 11883-3 0 9999"
// val l2 = "2 43876 97.3687 252.5788 0001999 83.2822 276.8643 15.23576679386900"
//
// val tle = TLE(l1, l2)
// val sat = Satellite(org.nstart.dep265.tletools.zeptomoby.core.TLE("",l1, l2))
//
// assertTrue { sat.orbit.satId.toInt() == tle.satelliteNumber }
// }
}
@@ -0,0 +1,20 @@
package ballistics.types
import org.junit.jupiter.api.Assertions.assertEquals
import org.junit.jupiter.api.Test
internal class ModDVTypeTest {
/*!
Проветка приведения типов от Int к enum
*/
@Test
fun testMDFoto() {
val md1 = ModDVType.fromInt(1)
val md2 = ModDVType.fromInt(16)
val md3 = ModDVType.fromInt(100)
assertEquals(ModDVType.FOTO, md1)
assertEquals(ModDVType.BARS, md2)
assertEquals(ModDVType.FOTO, md3)
}
}
@@ -0,0 +1,103 @@
package ballistics.zrv
import ballistics.Ballistics
import ballistics.types.BallisticsError
import ballistics.types.EarthType
import ballistics.types.InitialConditions
import ballistics.types.IntegrationType
import ballistics.types.ModDVType
import ballistics.types.OrbitalPoint
import ballistics.types.PPI
import ballistics.types.TLE
import ballistics.utils.math.Vector3D
import org.junit.jupiter.api.Assertions.assertTrue
import org.junit.jupiter.api.Test
import java.time.LocalDateTime
import java.time.ZoneOffset
import kotlin.math.PI
internal class ZRVStepperCalculatorTest {
@Test
fun calculate() {
val r = Ballistics()
val p = r.getTLEParams(TLE("1 62141U 24224C 25324.24196334 .00027917 00000-0 10193-2 0 9998",
"2 62141 42.9988 56.0174 0001022 26.8436 333.2469 15.27609213 55582"), "test")
r.earthType = EarthType.PZ90d02
r.modDVType = ModDVType.BARS
r.integrationType = IntegrationType.ADAMS7
val mnu = mutableListOf<InitialConditions>()
mnu.add(
InitialConditions(
OrbitalPoint(
LocalDateTime.of(2021, 12, 3, 0, 5, 45, 0).toEpochSecond(ZoneOffset.UTC).toDouble(),
1,
Vector3D(
-5357933.7872,
4328646.1787,
0.0,
),
Vector3D(
941.8995373,
1150.6919822,
7544.9920840,
),
),
0.0061,
125.0,
),
)
var rez = r.calculateOrbPoints(mnu.toTypedArray(), mnu.first().point.t, mnu.first().point.t + 86400.0 * 3)
if (rez == BallisticsError.OK) {
rez =
r.calculateZRV(
listOf(
PPI(
1,
1,
55.15 * PI / 180,
38.39 * PI / 180,
0.0,
5 * PI / 180,
80 * PI / 180,
// shadowMin = listOf(
// ShadowAU(110.0 * PI / 180, 150 * PI / 180, 25 * PI / 180),
// ShadowAU(175.0 * PI / 180, 183 * PI / 180, 90 * PI / 180),
// ),
// shadowMax = listOf(
// ShadowAU(189.0 * PI / 180, 192 * PI / 180, 0 * PI / 180),
// )
),
),
mnu.first().point.t,
mnu.first().point.t + 86400.0 * 3,
)
if (rez == BallisticsError.OK) {
for (z in r.zrv)
println(
" ${z.vit} \t" +
" ${z.au} \t" +
" ${LocalDateTime.ofEpochSecond(z.zoneIn.t.toLong(), 0, ZoneOffset.UTC)} \t" +
" ${z.zoneIn.azimuth * 180 / PI} \t" +
" ${z.zoneIn.elevation * 180 / PI} \t" +
" ${LocalDateTime.ofEpochSecond(z.zoneOut.t.toLong(), 0, ZoneOffset.UTC)} \t" +
" ${z.zoneOut.azimuth * 180 / PI} \t" +
" ${z.zoneOut.elevation * 180 / PI} \t" +
" ${LocalDateTime.ofEpochSecond(z.zoneMax.t.toLong(), 0, ZoneOffset.UTC)} \t" +
" ${z.zoneMax.azimuth * 180 / PI} \t" +
" ${z.zoneMax.elevation * 180 / PI} \t",
)
}
}
assertTrue((rez == BallisticsError.OK))
}
}