bywind
Sailing-route optimisation over real wind data.
bywind decodes GRIB2 weather files (UGRD/VGRD at 10 m above ground),
bakes the time-varying wind into a regular spatial grid, then runs a
particle-swarm search for a fuel-vs-time-optimal route between two
points. Landmass avoidance comes from an embedded Natural Earth
coastline dataset rasterised into a signed-distance field and pre-A*-d
for fast sea-path baseline construction.
The crate is the headless engine. There's a binary CLI
(bywind-cli) and an egui-based
GUI editor (bywind-viz) that
build on top of it.
Install
[]
= "0.1"
What's in the crate
- Wind data.
WindMap(one frame, AoS over(lon, lat, sample)),TimedWindMap(a stack of frames at a fixed step),BakedWindMap(a search-side regular grid with Cartesian(u, v)wind, built once per search). - I/O.
bywind::io::loadauto-dispatches by extension between GRIB2 (read-only) andwind_av1(.wcav, the crate's AV1 near-lossless binary format for fast restart-from-cache and the bundled GUI sample). - GFS fetch.
bywind::fetch::fetch_to_grib2pulls UGRD/VGRD-at-10m messages from NOAA's public GFS S3 bucket via.idxsidecars + HTTP Range requests, producing a concatenated GRIB2 stream the rest of the pipeline ingests unchanged. A couple of MB per frame instead of the ~500 MB full-file size. Driven by the CLI'sbywind-cli fetchsubcommand; usable directly for custom batch / scheduled-download workflows. - Search entry points.
run_search_blockingruns the full outer-position + inner-time PSO and returns the gbest route plus an A*+time-PSO benchmark for context.run_time_reopt_blockingruns only the time-PSO holding a path's xy fixed (the GUI uses it after drag-edits). - Config schemas.
BoatConfig(polar / fuel rates),SearchConfig(PSO sizing + coefficients),SearchWeights(time / fuel / land trade-off). All serde-derived;bywind::scenario::CliConfigFilelayers TOML files + CLI overrides for the CLI / GUI. - Bounds derivation.
MapBounds::from_wind_mapplusderive_route_bbox(an A*-probed bbox that detours around continents) for the "I just have origin + destination, give me a sensible search domain" case. - Landmass.
landmass_grid()returns the lazily-initialised default Natural Earth grid (SDF_RESOLUTION_DEG = 0.5°, embedded asassets/ne_50m_land.geojson).landmass_grid_at_resolution(deg)returns a grid at a caller-chosen cell size, cached per distinct resolution;SearchConfig::sdf_resolution_degplumbs that through the search. swarmkit-sailingre-exports.Boat,SearchSettings,RouteBounds,LonLatBbox,Topologyare re-exported at the crate root so the common case (load wind, run search) needs only abywinddependency. The two crates ship in lockstep;pub usepreserves type identity for callers that do also depend onswarmkit-sailingdirectly.
Minimal usage
use Path;
use ;
For a complete walkthrough — wind-map loading, error handling, summary
output — see bywind-cli's search.rs. For a graphical view of the
swarm's evolution, see bywind-viz.
Features
profile-timers— forwards through toswarmkit-sailingand turns on sub-stageInstant::nowcounters in the search hot paths. Default off (atomic-add traffic at every call site).
License
Dual-licensed under either of
- Apache License, Version 2.0 (
LICENSE-APACHE) - MIT license (
LICENSE-MIT)
at your option.