Rusty Givens

Rusty Givens

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.

Rust FOSS REST + gRPC
Get Started GitHub →

FOSS Components

The free Rusty Givens library ships with three core pieces: the SE kernel, I/O layer, and educational Angular frontend.

SE Kernel

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.

I/O Layer

rusty-givens-io

JSON deserialization, format conversion, and load_case(). Loads network topology, measurements, and true state for validation.

📺

Angular Frontend

frontend

Educational web UI: geo-referenced GB transmission grid, configurable factorization, tabular bus results. See the SE output in action.

Trait contract — rusty-givens-core
pub trait SeSolver {
    fn estimate(
        &self,
        system: &PowerSystem,
        model:  &AcModel,
        measurements: &MeasurementSet,
        config: &EstimationConfig,
    ) -> Result<EstimationResult, SolverError>;
}

SE Kernel

The heart of Rusty Givens: a deterministic Gauss-Newton WLS solver with configurable linear algebra.

Sparse Cholesky (LLT)

Default factorization via faer. Exploits the SPD structure of the gain matrix for O(nnz) solves.

Sparse LU Fallback

For non-SPD or numerically difficult gain matrices, seamlessly switch to sparse LU decomposition.

Dense Cholesky

Small-system path via faer dense routines. Robust baseline for networks under ~200 buses.

Pluggable Backends

The SeSolver trait allows swapping the Rust kernel for pandapower or any other solver.

Structured Diagnostics

Per-iteration timing (Jacobian, gain assembly, factorization) returned in the result — no stdout noise.

Zero-Copy Gain Cache

Sparsity pattern computed once, values array refilled each iteration. Avoids repeated allocation.

Angular Frontend

A web UI built for learning and teaching power system state estimation.

Geo-referenced Grid

Interactive map of the GB 400/275 kV transmission network with bus positions and estimated voltage states.

Configurable Factorization

Choose Sparse Cholesky, Sparse LU, or Dense Cholesky via the UI and run estimation on demand.

Tabular Results

Per-bus estimated voltage magnitude (p.u.) and angle (deg), with optional true-state comparison for error analysis.

Summary Metrics

Convergence status, iteration count, solve time, and MAE/max error metrics at a glance.

Two APIs

Rusty Givens exposes the same core functionality over REST (JSON) and gRPC (protobuf). Choose the one that fits your stack.

📜

REST API

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

📠

gRPC API

HTTP/2 · Protobuf

EstimateService: GetNetwork, GetTrueState, RunEstimate, GetLastResult. Same endpoints as REST, typed and efficient for high-throughput scenarios.

Example: REST
curl -X POST http://localhost:3001/api/estimate \
  -H 'Content-Type: application/json' \
  -d '{"factorization":"SparseCholesky","max_iterations":50,"tolerance":1e-4}'

SE Output Data

The kernel returns structured results that enable downstream analysis and integration.

📊 Understanding what the SE kernel outputs is key. These results can drive Bad Data Detection, observability analysis, and other SCADA/EMS capabilities.

Per-bus State

Estimated voltage magnitude (p.u.) and angle (deg) for every bus. Indexed by bus label for easy mapping to the network.

Convergence Metrics

Converged flag, iteration count, final increment norm, and solve time in seconds.

Error Metrics

When true state is available: MAE and max error for V and θ for validation and benchmarking.

Solver Configuration

Echo of factorization, tolerance, and max iterations used.

Example: BusResult (per-bus output)
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,
}

Quick Start

Build the workspace, run the estimate service, and launch the Angular frontend.

Terminal
# 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}'
Using the kernel as a library
// 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);
}

Colour Palette

The Cyber Guard palette — technical, modern, and serious. Use these tokens across all brand surfaces.

Circuit Board Blue
#003B5C
Logo, Headings, Nav, Buttons
Oxide Orange
#E67E22
CTAs, Code, Alerts, Accents
Graphite Gray
#2C3E50
Code Blocks, Borders, Containers
Algorithm Silver
#ECF0F1
Page Background, Light Accents