A free, open-source AC Weighted Least-Squares State Estimator for power systems. Learn how SE works with the included Angular frontend and dual APIs.
The free Rusty Givens library ships with three core pieces: the SE kernel, I/O layer, and educational Angular frontend.
rusty-givens-core
Pure Gauss-Newton WLS solver. Zero I/O, zero serde. Sparse Cholesky, sparse LU, or dense Cholesky via faer.
Exposes the SeSolver trait for pluggable backends.
rusty-givens-io
JSON deserialization, format conversion, and load_case(). Loads network topology, measurements, and true state for validation.
frontend
Educational web UI: geo-referenced GB transmission grid, configurable factorization, tabular bus results. See the SE output in action.
pub trait SeSolver { fn estimate( &self, system: &PowerSystem, model: &AcModel, measurements: &MeasurementSet, config: &EstimationConfig, ) -> Result<EstimationResult, SolverError>; }
The heart of Rusty Givens: a deterministic Gauss-Newton WLS solver with configurable linear algebra.
Default factorization via faer. Exploits the SPD structure of the gain matrix for O(nnz) solves.
For non-SPD or numerically difficult gain matrices, seamlessly switch to sparse LU decomposition.
Small-system path via faer dense routines. Robust baseline for networks under ~200 buses.
The SeSolver trait allows swapping the Rust kernel for pandapower or any other solver.
Per-iteration timing (Jacobian, gain assembly, factorization) returned in the result — no stdout noise.
Sparsity pattern computed once, values array refilled each iteration. Avoids repeated allocation.
A web UI built for learning and teaching power system state estimation.
Interactive map of the GB 400/275 kV transmission network with bus positions and estimated voltage states.
Choose Sparse Cholesky, Sparse LU, or Dense Cholesky via the UI and run estimation on demand.
Per-bus estimated voltage magnitude (p.u.) and angle (deg), with optional true-state comparison for error analysis.
Convergence status, iteration count, solve time, and MAE/max error metrics at a glance.
Rusty Givens exposes the same core functionality over REST (JSON) and gRPC (protobuf). Choose the one that fits your stack.
HTTP/1.1 · JSON
GET /api/network — topology (buses, branches)
GET /api/true-state — reference power-flow state
POST /api/estimate — run WLS SE with config
GET /api/last-result — most recent estimation
HTTP/2 · Protobuf
EstimateService: GetNetwork, GetTrueState, RunEstimate, GetLastResult. Same endpoints as REST, typed and efficient for high-throughput scenarios.
curl -X POST http://localhost:3001/api/estimate \ -H 'Content-Type: application/json' \ -d '{"factorization":"SparseCholesky","max_iterations":50,"tolerance":1e-4}'
The kernel returns structured results that enable downstream analysis and integration.
Estimated voltage magnitude (p.u.) and angle (deg) for every bus. Indexed by bus label for easy mapping to the network.
Converged flag, iteration count, final increment norm, and solve time in seconds.
When true state is available: MAE and max error for V and θ for validation and benchmarking.
Echo of factorization, tolerance, and max iterations used.
struct BusResult { index: usize, label: usize, est_vm: f64, // estimated voltage magnitude (p.u.) est_va_deg: f64, // estimated voltage angle (deg) true_vm: f64, // true state (if available) true_va_deg: f64, vm_error: f64, // |est - true| va_error_deg: f64, }
Build the workspace, run the estimate service, and launch the Angular frontend.
# Build the workspace (release mode) cargo build --release # Run the estimate service (loads the GB network, REST on 3001, gRPC on 50051) cargo run --release -p estimate-service # In another terminal — run the Angular frontend cd frontend && npm install && npx ng serve # Run an estimation via REST curl -X POST http://localhost:3001/api/estimate \ -H 'Content-Type: application/json' \ -d '{"factorization":"SparseCholesky","max_iterations":50,"tolerance":1e-4}'
// Cargo.toml [dependencies] rusty-givens-core = { path = "crates/rusty-givens-core" } rusty-givens-io = { path = "crates/rusty-givens-io" } // main.rs use rusty_givens_core::kernel::{WlsSolver, SeSolver, EstimationConfig, Factorization}; use rusty_givens_core::model::build_ac_model; use rusty_givens_io::load_case; fn main() { let case = load_case(Path::new("case_study/gb_network.json")).unwrap(); let model = build_ac_model(&case.system); let cfg = EstimationConfig { factorization: Factorization::SparseCholesky, ..EstimationConfig::default() }; let result = WlsSolver.estimate(&case.system, &model, &case.measurements, &cfg) .expect("estimation failed"); println!("Converged in {} iterations", result.iterations); println!("Voltage magnitudes: {:?}", result.voltage_magnitude); }
The Cyber Guard palette — technical, modern, and serious. Use these tokens across all brand surfaces.