Browse Source
- Rewrite precalc_moon_orbits.py to output orbit params as dotted keys
(orbit.semi_major_axis = ...) instead of nested tables, conforming
to TOML 1.0 spec for Python compatibility
- Add print_cpp_expected_values() helper to script output
- Add new test_moon_orbits.cpp replacing old_tests version:
* MoonData struct now carries int parent_index instead of pointer
* Eliminate opaque pointer arithmetic for parent index comparison
* Collect failures in vector during sim loops, assert once at end
(reduces assertions from 763,230 to 43 per test)
- Add test_moon_orbits.toml generated from precalc script
test-refactor
3 changed files with 497 additions and 17 deletions
@ -0,0 +1,273 @@ |
|||||||
|
#include <catch2/catch_test_macros.hpp> |
||||||
|
#include <catch2/matchers/catch_matchers_floating_point.hpp> |
||||||
|
#include "../src/physics.h" |
||||||
|
#include "../src/simulation.h" |
||||||
|
#include "../src/config_loader.h" |
||||||
|
#include "../src/test_utilities.h" |
||||||
|
#include <cmath> |
||||||
|
#include <vector> |
||||||
|
#include <string> |
||||||
|
|
||||||
|
using Catch::Matchers::WithinAbs; |
||||||
|
|
||||||
|
// === Helper: run sim loop, collect failures, assert once at end ===
|
||||||
|
static std::string fmt_time(double t) { |
||||||
|
char buf[32]; |
||||||
|
snprintf(buf, sizeof(buf), "t=%.0fs", t); |
||||||
|
return std::string(buf); |
||||||
|
} |
||||||
|
|
||||||
|
static std::string fmt_drift(double d) { |
||||||
|
char buf[32]; |
||||||
|
snprintf(buf, sizeof(buf), "drift=%.4f", d); |
||||||
|
return std::string(buf); |
||||||
|
} |
||||||
|
|
||||||
|
// === Per-moon period tolerances (0.5% of analytical period, from precalc) ===
|
||||||
|
static const double MOON_PERIOD_TOL = 11861.4; // Moon
|
||||||
|
static const double IO_PERIOD_TOL = 764.6; // Io
|
||||||
|
static const double EUROPA_PERIOD_TOL = 1534.5; // Europa
|
||||||
|
static const double GANYMEDE_PERIOD_TOL = 3091.1; // Ganymede
|
||||||
|
static const double CALLISTO_PERIOD_TOL = 7210.6; // Callisto
|
||||||
|
static const double TITAN_PERIOD_TOL = 6889.9; // Titan
|
||||||
|
|
||||||
|
|
||||||
|
// === Drift tolerance for distance checks (10% bound) ===
|
||||||
|
static const double DRIFT_REL_TOL = 0.1; |
||||||
|
|
||||||
|
SCENARIO("Multi-body moon orbital stability and period measurements", |
||||||
|
"[moon][earth][jupiter][saturn][galilean][titan]" |
||||||
|
"[stability][period][integration][inclined][geometry]") { |
||||||
|
// === Fixture ===
|
||||||
|
const double TIME_STEP = 60.0; |
||||||
|
const double SECONDS_PER_DAY = 86400.0; |
||||||
|
|
||||||
|
SimulationState* sim = create_simulation(20, 0, 0, TIME_STEP); |
||||||
|
REQUIRE(load_system_config(sim, "tests/test_moon_orbits.toml")); |
||||||
|
|
||||||
|
CelestialBody* earth = &sim->bodies[2]; |
||||||
|
CelestialBody* moon = &sim->bodies[8]; |
||||||
|
|
||||||
|
struct MoonData { |
||||||
|
int index; |
||||||
|
const char* name; |
||||||
|
double expected_seconds; |
||||||
|
double max_days; |
||||||
|
double min_time_days; |
||||||
|
double period_tol; |
||||||
|
int parent_index; |
||||||
|
}; |
||||||
|
|
||||||
|
const MoonData galilean[] = { |
||||||
|
{9, "Io", 152928.62, 5.0, 1.0, IO_PERIOD_TOL, 4}, |
||||||
|
{10, "Europa", 306909.10, 10.0, 2.0, EUROPA_PERIOD_TOL, 4}, |
||||||
|
{11, "Ganymede", 618227.12, 15.0, 5.0, GANYMEDE_PERIOD_TOL, 4}, |
||||||
|
{12, "Callisto", 1442117.30, 25.0, 10.0, CALLISTO_PERIOD_TOL, 4}, |
||||||
|
}; |
||||||
|
|
||||||
|
const MoonData all_moons[] = { |
||||||
|
{8, "Moon", 2372274.33, 35.0, 5.0, MOON_PERIOD_TOL, 2}, |
||||||
|
{9, "Io", 152928.62, 5.0, 1.0, IO_PERIOD_TOL, 4}, |
||||||
|
{10, "Europa", 306909.10, 10.0, 2.0, EUROPA_PERIOD_TOL, 4}, |
||||||
|
{11, "Ganymede", 618227.12, 15.0, 5.0, GANYMEDE_PERIOD_TOL, 4}, |
||||||
|
{12, "Callisto", 1442117.30, 25.0, 10.0, CALLISTO_PERIOD_TOL, 4}, |
||||||
|
{13, "Titan", 1377976.07, 25.0, 10.0, TITAN_PERIOD_TOL, 5}, |
||||||
|
}; |
||||||
|
|
||||||
|
// === Helper lambdas ===
|
||||||
|
// Run sim loop without assertions; collect failures; assert once at end.
|
||||||
|
// This tests every timestep but produces only 1 assertion per call.
|
||||||
|
auto check_parent_stability = [&](CelestialBody* body, int expected_parent, |
||||||
|
double max_days) { |
||||||
|
double max_time = max_days * SECONDS_PER_DAY; |
||||||
|
std::vector<std::string> failures; |
||||||
|
while (sim->time < max_time) { |
||||||
|
update_simulation(sim); |
||||||
|
if (body->parent_index != expected_parent) { |
||||||
|
failures.push_back(fmt_time(sim->time) + ": " + |
||||||
|
std::string(body->name) + |
||||||
|
" parent=" + std::to_string(body->parent_index) + |
||||||
|
" (expected " + std::to_string(expected_parent) + ")"); |
||||||
|
} |
||||||
|
} |
||||||
|
REQUIRE(failures.empty()); |
||||||
|
}; |
||||||
|
|
||||||
|
auto measure_period = [&](int body_index, int parent_index, |
||||||
|
double max_days, double min_time_days) { |
||||||
|
sim->time = 0.0; |
||||||
|
OrbitTracker* tracker = create_orbit_tracker_with_min_time( |
||||||
|
body_index, min_time_days * SECONDS_PER_DAY); |
||||||
|
double max_time = max_days * SECONDS_PER_DAY; |
||||||
|
|
||||||
|
while (sim->time < max_time && !tracker->orbit_completed) { |
||||||
|
update_simulation(sim); |
||||||
|
update_orbit_tracker(tracker, &sim->bodies[body_index], |
||||||
|
&sim->bodies[parent_index], sim->time); |
||||||
|
} |
||||||
|
|
||||||
|
double period = tracker->orbit_completed |
||||||
|
? tracker->time_at_completion : -1.0; |
||||||
|
destroy_orbit_tracker(tracker); |
||||||
|
return period; |
||||||
|
}; |
||||||
|
|
||||||
|
auto check_distance_drift = [&](CelestialBody* body, int parent_index, |
||||||
|
double max_days) { |
||||||
|
CelestialBody* parent = &sim->bodies[parent_index]; |
||||||
|
Vec3 initial_rel = vec3_sub(body->global_position, parent->global_position); |
||||||
|
double initial_r = vec3_magnitude(initial_rel); |
||||||
|
double max_time = max_days * SECONDS_PER_DAY; |
||||||
|
|
||||||
|
std::vector<std::string> failures; |
||||||
|
while (sim->time < max_time) { |
||||||
|
update_simulation(sim); |
||||||
|
Vec3 rel = vec3_sub(body->global_position, parent->global_position); |
||||||
|
double r = vec3_magnitude(rel); |
||||||
|
double drift = std::fabs(r - initial_r) / initial_r; |
||||||
|
if (drift > DRIFT_REL_TOL) { |
||||||
|
failures.push_back(fmt_time(sim->time) + ": " + |
||||||
|
std::string(body->name) + " " + |
||||||
|
fmt_drift(drift)); |
||||||
|
} |
||||||
|
} |
||||||
|
REQUIRE(failures.empty()); |
||||||
|
}; |
||||||
|
|
||||||
|
auto wait_for_all_orbits = [&](int count) { |
||||||
|
OrbitTracker* trackers[6] = {}; |
||||||
|
for (int i = 0; i < count; i++) { |
||||||
|
trackers[i] = create_orbit_tracker_with_min_time( |
||||||
|
all_moons[i].index, all_moons[i].min_time_days * SECONDS_PER_DAY); |
||||||
|
} |
||||||
|
|
||||||
|
double max_time = 60.0 * SECONDS_PER_DAY; |
||||||
|
int completed_count = 0; |
||||||
|
|
||||||
|
while (sim->time < max_time && completed_count < count) { |
||||||
|
update_simulation(sim); |
||||||
|
for (int i = 0; i < count; i++) { |
||||||
|
if (!trackers[i]->orbit_completed) { |
||||||
|
update_orbit_tracker(trackers[i], &sim->bodies[all_moons[i].index], |
||||||
|
&sim->bodies[all_moons[i].parent_index], sim->time); |
||||||
|
if (trackers[i]->orbit_completed) { |
||||||
|
completed_count++; |
||||||
|
double period = trackers[i]->time_at_completion / SECONDS_PER_DAY; |
||||||
|
INFO(all_moons[i].name << " completed orbit at " |
||||||
|
<< period << " days"); |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
for (int i = 0; i < count; i++) { |
||||||
|
REQUIRE(trackers[i]->orbit_completed); |
||||||
|
destroy_orbit_tracker(trackers[i]); |
||||||
|
} |
||||||
|
}; |
||||||
|
|
||||||
|
// === Sections ===
|
||||||
|
|
||||||
|
SECTION("Moon maintains Earth as parent throughout simulation") { |
||||||
|
check_parent_stability(moon, 2, 35.0); |
||||||
|
} |
||||||
|
|
||||||
|
SECTION("Moon distance from Earth stays within 10% of initial") { |
||||||
|
check_distance_drift(moon, 2, 35.0); |
||||||
|
} |
||||||
|
|
||||||
|
SECTION("Moon completes orbit in ~27.3 days") { |
||||||
|
double period = measure_period(8, 2, 35.0, 5.0); |
||||||
|
INFO("Measured Moon period: " << period / SECONDS_PER_DAY |
||||||
|
<< " days (expected: ~27.3)"); |
||||||
|
REQUIRE_THAT(period, WithinAbs(2372274.33, MOON_PERIOD_TOL)); |
||||||
|
} |
||||||
|
|
||||||
|
SECTION("Galilean moons maintain Jupiter as parent") { |
||||||
|
for (const auto& m : galilean) { |
||||||
|
check_parent_stability(&sim->bodies[m.index], 4, 25.0); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
SECTION("Galilean moons complete orbits in expected periods") { |
||||||
|
for (const auto& m : galilean) { |
||||||
|
double period = measure_period(m.index, m.parent_index, |
||||||
|
m.max_days, m.min_time_days); |
||||||
|
INFO(m.name << " period: " << period / SECONDS_PER_DAY |
||||||
|
<< " days (expected: " << m.expected_seconds / SECONDS_PER_DAY |
||||||
|
<< ")"); |
||||||
|
REQUIRE_THAT(period, WithinAbs(m.expected_seconds, m.period_tol)); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
SECTION("Galilean moons stay within 10% of initial distance") { |
||||||
|
for (const auto& m : galilean) { |
||||||
|
check_distance_drift(&sim->bodies[m.index], m.parent_index, 25.0); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
SECTION("Titan maintains Saturn as parent") { |
||||||
|
check_parent_stability(&sim->bodies[13], 5, 25.0); |
||||||
|
} |
||||||
|
|
||||||
|
SECTION("Titan completes orbit in ~15.95 days") { |
||||||
|
double period = measure_period(13, 5, 25.0, 10.0); |
||||||
|
INFO("Measured Titan period: " << period / SECONDS_PER_DAY |
||||||
|
<< " days (expected: ~15.95)"); |
||||||
|
REQUIRE_THAT(period, WithinAbs(1377976.07, TITAN_PERIOD_TOL)); |
||||||
|
} |
||||||
|
|
||||||
|
SECTION("Titan distance from Saturn stays within 10%") { |
||||||
|
check_distance_drift(&sim->bodies[13], 5, 25.0); |
||||||
|
} |
||||||
|
|
||||||
|
SECTION("All moons maintain correct parents over 60-day simulation") { |
||||||
|
double max_time = 60.0 * SECONDS_PER_DAY; |
||||||
|
std::vector<std::string> failures; |
||||||
|
while (sim->time < max_time) { |
||||||
|
update_simulation(sim); |
||||||
|
for (int i = 0; i < 6; i++) { |
||||||
|
int idx = all_moons[i].index; |
||||||
|
int expected = all_moons[i].parent_index; |
||||||
|
if (sim->bodies[idx].parent_index != expected) { |
||||||
|
failures.push_back(fmt_time(sim->time) + ": " + |
||||||
|
std::string(all_moons[i].name) + |
||||||
|
" parent=" + |
||||||
|
std::to_string(sim->bodies[idx].parent_index) + |
||||||
|
" (expected " + std::to_string(expected) + ")"); |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
REQUIRE(failures.empty()); |
||||||
|
} |
||||||
|
|
||||||
|
SECTION("All moons complete at least one orbit") { |
||||||
|
wait_for_all_orbits(6); |
||||||
|
} |
||||||
|
|
||||||
|
SECTION("Moon inclined orbit produces non-zero z-coordinate") { |
||||||
|
double max_time = 10.0 * SECONDS_PER_DAY; |
||||||
|
while (sim->time < max_time) { |
||||||
|
update_simulation(sim); |
||||||
|
} |
||||||
|
|
||||||
|
Vec3 rel = vec3_sub(moon->global_position, earth->global_position); |
||||||
|
double z = rel.z; |
||||||
|
INFO("Moon z-coordinate relative to Earth: " << z << " m"); |
||||||
|
INFO("Moon orbital inclination: " |
||||||
|
<< (moon->orbit.inclination * 180.0 / M_PI) << " degrees"); |
||||||
|
REQUIRE_THAT(z, !WithinAbs(0.0, 10000000.0)); |
||||||
|
} |
||||||
|
|
||||||
|
SECTION("Moon orbital elements loaded correctly from config") { |
||||||
|
REQUIRE_THAT(moon->orbit.eccentricity, WithinAbs(0.055, E_TOL)); |
||||||
|
REQUIRE_THAT(moon->orbit.inclination, |
||||||
|
WithinAbs(5.16 * M_PI / 180.0, ANG_TOL)); |
||||||
|
REQUIRE_THAT(moon->orbit.longitude_of_ascending_node, |
||||||
|
WithinAbs(125.08 * M_PI / 180.0, ANG_TOL)); |
||||||
|
REQUIRE_THAT(moon->orbit.argument_of_periapsis, |
||||||
|
WithinAbs(318.15 * M_PI / 180.0, ANG_TOL)); |
||||||
|
} |
||||||
|
|
||||||
|
destroy_simulation(sim); |
||||||
|
} |
||||||
@ -0,0 +1,184 @@ |
|||||||
|
# Moon Orbits Test Configuration |
||||||
|
# Auto-generated by scripts/precalc_moon_orbits.py |
||||||
|
# Data source: docs/planetary_data.md (JPL planetary facts) |
||||||
|
# Mean anomaly converted to true anomaly via Kepler's equation |
||||||
|
|
||||||
|
[[bodies]] |
||||||
|
name = "Sun" |
||||||
|
mass = 1.989e+30 |
||||||
|
radius = 696000000.0 |
||||||
|
parent_index = -1 |
||||||
|
color = { r = 1.0, g = 1.0, b = 0.0 } |
||||||
|
orbit.semi_major_axis = 0.0 |
||||||
|
orbit.eccentricity = 0.0 |
||||||
|
orbit.true_anomaly = 0.0 |
||||||
|
|
||||||
|
[[bodies]] |
||||||
|
name = "Venus" |
||||||
|
mass = 4.87e+24 |
||||||
|
radius = 6052000.0 |
||||||
|
parent_index = 0 |
||||||
|
color = { r = 0.5, g = 0.5, b = 0.5 } |
||||||
|
orbit.semi_major_axis = 1.081608e+11 |
||||||
|
orbit.eccentricity = 0.007 |
||||||
|
orbit.inclination = 0.059166661642608 |
||||||
|
orbit.longitude_of_ascending_node = 1.338318470429252 |
||||||
|
orbit.argument_of_periapsis = 0.958534825195286 |
||||||
|
orbit.true_anomaly = 0.890141231198106 |
||||||
|
|
||||||
|
[[bodies]] |
||||||
|
name = "Earth" |
||||||
|
mass = 5.97e+24 |
||||||
|
radius = 6378000.0 |
||||||
|
parent_index = 0 |
||||||
|
color = { r = 0.5, g = 0.5, b = 0.5 } |
||||||
|
orbit.semi_major_axis = 1.496000e+11 |
||||||
|
orbit.eccentricity = 0.017 |
||||||
|
orbit.inclination = 0.000000000000000 |
||||||
|
orbit.longitude_of_ascending_node = 0.000000000000000 |
||||||
|
orbit.argument_of_periapsis = 1.796641932002963 |
||||||
|
orbit.true_anomaly = 6.238578647164619 |
||||||
|
|
||||||
|
[[bodies]] |
||||||
|
name = "Mars" |
||||||
|
mass = 6.42e+23 |
||||||
|
radius = 3396000.0 |
||||||
|
parent_index = 0 |
||||||
|
color = { r = 0.5, g = 0.5, b = 0.5 } |
||||||
|
orbit.semi_major_axis = 2.279904e+11 |
||||||
|
orbit.eccentricity = 0.093 |
||||||
|
orbit.inclination = 0.032288591161895 |
||||||
|
orbit.longitude_of_ascending_node = 0.864985177288390 |
||||||
|
orbit.argument_of_periapsis = 5.000368306963754 |
||||||
|
orbit.true_anomaly = 0.407676817724149 |
||||||
|
|
||||||
|
[[bodies]] |
||||||
|
name = "Jupiter" |
||||||
|
mass = 1.898e+27 |
||||||
|
radius = 71492000.0 |
||||||
|
parent_index = 0 |
||||||
|
color = { r = 0.5, g = 0.5, b = 0.5 } |
||||||
|
orbit.semi_major_axis = 7.783688e+11 |
||||||
|
orbit.eccentricity = 0.049 |
||||||
|
orbit.inclination = 0.022863813201126 |
||||||
|
orbit.longitude_of_ascending_node = 1.753532299478703 |
||||||
|
orbit.argument_of_periapsis = 4.786565473594449 |
||||||
|
orbit.true_anomaly = 0.378299755400337 |
||||||
|
|
||||||
|
[[bodies]] |
||||||
|
name = "Saturn" |
||||||
|
mass = 5.683e+26 |
||||||
|
radius = 60268000.0 |
||||||
|
parent_index = 0 |
||||||
|
color = { r = 0.5, g = 0.5, b = 0.5 } |
||||||
|
orbit.semi_major_axis = 1.426735e+12 |
||||||
|
orbit.eccentricity = 0.057 |
||||||
|
orbit.inclination = 0.043458698374659 |
||||||
|
orbit.longitude_of_ascending_node = 1.983741227816755 |
||||||
|
orbit.argument_of_periapsis = 5.915618966709580 |
||||||
|
orbit.true_anomaly = 5.457583789473037 |
||||||
|
|
||||||
|
[[bodies]] |
||||||
|
name = "Uranus" |
||||||
|
mass = 8.68e+25 |
||||||
|
radius = 25559000.0 |
||||||
|
parent_index = 0 |
||||||
|
color = { r = 0.5, g = 0.5, b = 0.5 } |
||||||
|
orbit.semi_major_axis = 2.870824e+12 |
||||||
|
orbit.eccentricity = 0.046 |
||||||
|
orbit.inclination = 0.013439035240356 |
||||||
|
orbit.longitude_of_ascending_node = 1.291892712326203 |
||||||
|
orbit.argument_of_periapsis = 1.691922176883303 |
||||||
|
orbit.true_anomaly = 2.537061863932694 |
||||||
|
|
||||||
|
[[bodies]] |
||||||
|
name = "Neptune" |
||||||
|
mass = 1.02e+26 |
||||||
|
radius = 24764000.0 |
||||||
|
parent_index = 0 |
||||||
|
color = { r = 0.5, g = 0.5, b = 0.5 } |
||||||
|
orbit.semi_major_axis = 4.498472e+12 |
||||||
|
orbit.eccentricity = 0.01 |
||||||
|
orbit.inclination = 0.030892327760300 |
||||||
|
orbit.longitude_of_ascending_node = 2.299994888278127 |
||||||
|
orbit.argument_of_periapsis = 4.767890450598109 |
||||||
|
orbit.true_anomaly = 4.516812758860357 |
||||||
|
|
||||||
|
[[bodies]] |
||||||
|
name = "Moon" |
||||||
|
mass = 7.35e+22 |
||||||
|
radius = 1738000.0 |
||||||
|
parent_index = 2 |
||||||
|
color = { r = 0.7, g = 0.7, b = 0.7 } |
||||||
|
orbit.semi_major_axis = 3.844000e+08 |
||||||
|
orbit.eccentricity = 0.055 |
||||||
|
orbit.inclination = 0.090058989402907 |
||||||
|
orbit.longitude_of_ascending_node = 2.183057828394507 |
||||||
|
orbit.argument_of_periapsis = 5.552765015219959 |
||||||
|
orbit.true_anomaly = 2.434643529152418 |
||||||
|
|
||||||
|
[[bodies]] |
||||||
|
name = "Io" |
||||||
|
mass = 8.93e+23 |
||||||
|
radius = 1822000.0 |
||||||
|
parent_index = 4 |
||||||
|
color = { r = 0.7, g = 0.7, b = 0.7 } |
||||||
|
orbit.semi_major_axis = 4.218000e+08 |
||||||
|
orbit.eccentricity = 0.004 |
||||||
|
orbit.inclination = 0.000000000000000 |
||||||
|
orbit.longitude_of_ascending_node = 0.000000000000000 |
||||||
|
orbit.argument_of_periapsis = 0.856956662729216 |
||||||
|
orbit.true_anomaly = 5.771386752330690 |
||||||
|
|
||||||
|
[[bodies]] |
||||||
|
name = "Europa" |
||||||
|
mass = 4.8e+23 |
||||||
|
radius = 1561000.0 |
||||||
|
parent_index = 4 |
||||||
|
color = { r = 0.7, g = 0.7, b = 0.7 } |
||||||
|
orbit.semi_major_axis = 6.711000e+08 |
||||||
|
orbit.eccentricity = 0.009 |
||||||
|
orbit.inclination = 0.008726646259972 |
||||||
|
orbit.longitude_of_ascending_node = 3.211405823669566 |
||||||
|
orbit.argument_of_periapsis = 0.785398163397448 |
||||||
|
orbit.true_anomaly = 6.023780086902404 |
||||||
|
|
||||||
|
[[bodies]] |
||||||
|
name = "Ganymede" |
||||||
|
mass = 1.48e+24 |
||||||
|
radius = 2631000.0 |
||||||
|
parent_index = 4 |
||||||
|
color = { r = 0.7, g = 0.7, b = 0.7 } |
||||||
|
orbit.semi_major_axis = 1.070400e+09 |
||||||
|
orbit.eccentricity = 0.001 |
||||||
|
orbit.inclination = 0.003490658503989 |
||||||
|
orbit.longitude_of_ascending_node = 1.021017612416683 |
||||||
|
orbit.argument_of_periapsis = 3.460987906704756 |
||||||
|
orbit.true_anomaly = 5.667675367373862 |
||||||
|
|
||||||
|
[[bodies]] |
||||||
|
name = "Callisto" |
||||||
|
mass = 1.08e+24 |
||||||
|
radius = 2410000.0 |
||||||
|
parent_index = 4 |
||||||
|
color = { r = 0.7, g = 0.7, b = 0.7 } |
||||||
|
orbit.semi_major_axis = 1.882700e+09 |
||||||
|
orbit.eccentricity = 0.007 |
||||||
|
orbit.inclination = 0.005235987755983 |
||||||
|
orbit.longitude_of_ascending_node = 5.394812717914473 |
||||||
|
orbit.argument_of_periapsis = 0.764454212373516 |
||||||
|
orbit.true_anomaly = 1.539408451124606 |
||||||
|
|
||||||
|
[[bodies]] |
||||||
|
name = "Titan" |
||||||
|
mass = 1.35e+24 |
||||||
|
radius = 2575000.0 |
||||||
|
parent_index = 5 |
||||||
|
color = { r = 0.7, g = 0.7, b = 0.7 } |
||||||
|
orbit.semi_major_axis = 1.221900e+09 |
||||||
|
orbit.eccentricity = 0.029 |
||||||
|
orbit.inclination = 0.005235987755983 |
||||||
|
orbit.longitude_of_ascending_node = 1.371828792067543 |
||||||
|
orbit.argument_of_periapsis = 1.366592804311560 |
||||||
|
orbit.true_anomaly = 0.216397080390910 |
||||||
|
|
||||||
Loading…
Reference in new issue