Add Lambert solver, transfer matrix, Dijkstra routing, and route planner UI
- Lambert's problem solver using universal variable method with bisection (handles elliptic, parabolic, hyperbolic transfers + anti-podal cases) - Transfer matrix: precompute pairwise station transfers over time window using Lambert solver with configurable launch velocity - Dijkstra routing on time-expanded graph (station × week nodes, transfer + wait edges) to find minimum-time routes - Route Planner UI: from/to station dropdowns, search window selector (1-10 years), "Find Optimal Route" button with results card - Route visualization: orange dashed trajectory lines with arrow heads and leg numbers on the 2D canvas - Tested: Mercury L1 → Jupiter L1 computes 6-month direct transfer at 30 km/s — physically reasonable Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -1,5 +1,8 @@
|
||||
use mass_driver_core::router;
|
||||
use mass_driver_core::station;
|
||||
use mass_driver_core::transfer_matrix;
|
||||
use orbital_mechanics::bodies;
|
||||
|
||||
use orbital_mechanics::orbits;
|
||||
use wasm_bindgen::prelude::*;
|
||||
|
||||
@@ -98,3 +101,59 @@ pub fn get_station_names(stations_json: &str) -> String {
|
||||
let names: Vec<&str> = stations.iter().map(|s| s.name.as_str()).collect();
|
||||
serde_json::to_string(&names).unwrap()
|
||||
}
|
||||
|
||||
/// Compute transfer matrix and find optimal route between two stations.
|
||||
///
|
||||
/// This is the main computation function. It:
|
||||
/// 1. Computes the transfer matrix for the given stations over a time window
|
||||
/// 2. Runs Dijkstra to find the optimal route
|
||||
///
|
||||
/// Returns JSON-serialized RouteResult, or empty string if no route found.
|
||||
///
|
||||
/// # Arguments (all as JSON)
|
||||
/// * `stations_json` - Station configuration
|
||||
/// * `from_station` - Source station index
|
||||
/// * `to_station` - Destination station index
|
||||
/// * `launch_velocity_kms` - Max launch velocity in km/s
|
||||
/// * `start_jd` - Start of search window (Julian Date)
|
||||
/// * `week_window` - Number of weeks to search
|
||||
#[wasm_bindgen]
|
||||
pub fn compute_route(
|
||||
stations_json: &str,
|
||||
from_station: usize,
|
||||
to_station: usize,
|
||||
launch_velocity_kms: f64,
|
||||
start_jd: f64,
|
||||
week_window: usize,
|
||||
) -> String {
|
||||
let stations: Vec<station::Station> = match serde_json::from_str(stations_json) {
|
||||
Ok(s) => s,
|
||||
Err(_) => return String::new(),
|
||||
};
|
||||
|
||||
// Compute transfer matrix (the heavy part)
|
||||
let matrix = transfer_matrix::compute_transfer_matrix(
|
||||
&stations,
|
||||
launch_velocity_kms,
|
||||
start_jd,
|
||||
week_window,
|
||||
|_completed, _total| {
|
||||
// Progress callback — in WASM we can't easily report progress
|
||||
// to the main thread without Web Workers. For now, just run.
|
||||
},
|
||||
);
|
||||
|
||||
// Find optimal route
|
||||
let route = router::find_optimal_route(
|
||||
&matrix,
|
||||
from_station,
|
||||
to_station,
|
||||
0,
|
||||
week_window.saturating_sub(1),
|
||||
);
|
||||
|
||||
match route {
|
||||
Some(r) => serde_json::to_string(&r).unwrap_or_default(),
|
||||
None => String::new(),
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user