multicalc
Scientific computing that fits on a microcontroller, built and tested from scratch in one integrated package. Estimation, control, kinematics, Lie groups, calculus, autodiff and linear algebra in stable no_std Rust with no heap, no panics and no unsafe.
Why use it
- 1 kHz loop rates: No heap, fixed-size types, bounded work per call. Results in a full robotics control loop at 1 kHz.
- Tested on six embedded targets: Every commit is built and tested on six targets:
the
x86_64andaarch64Linux hosts and on four bare-metal ABIs (thumbv7emsoft-float,thumbv7emhardware-FPU,thumbv6m, andriscv32imc), running the real math under QEMU.no_std, no-alloc, and no-panic rules hold on each target. - Measured against external references: Each module's results are verified against established libraries like
numpy,scipy, andfilterpyfixtures within ~1 ulp, thus validating the rust implementation. See the benchmarks. - Pure safe and panic-free.
#![forbid(unsafe_code)], no C dependencies, andunwrap/panicdenied on library paths; every fallible call returns a typed error. Types are fixed-size and stack-allocated, and iteration counts are bounded.
What it does
Robotics and control
- Estimation: linear, extended, and unscented
KalmanFilters (autodiff Jacobians, no hand-derived ones; the unscented one needs no derivatives at all), anErrorStateKalmanFilterthat fuses an IMU with position and heading fixes,MahonyFilterandMadgwickFilterfor attitude estimation, and aParticleFilterfor nonlinear, non-Gaussian problems (alloconly), with aMonte Carlo Localizationbuilt on top of it. - Control:
Pidcontrol, infinite horizonLqr,;GeometricAttitudeControllerfor drones, thepure pursuitpath-following law; andFollowTheGapreactive obstacle avoidance. - Spatial math:
Quaternion, theSO2/SE2/SO3/SE3Lie groups for 2D and 3D rotations and rigid-body transforms with left and right Jacobians and their inverses on all four, andTwist/Wrenchscrew-theory types. - Rigid-body dynamics:
RigidBodycomputes the motion of a single rigid body, from aSpatialInertiasaying how its mass is spread out and aFreeJointStatefor a body free to move in all six directions — loadable straight from MuJoCo model files withmulticalc-mjcf. - Plant: What sits between a command and the force a body actually feels —
MultirotorMixershares a wanted lift and turn out across the rotors, andRotorLagmodels the moment a rotor takes to catch up to what it was asked for. - Kinematics: differential-drive and unicycle maps between wheel and body motion, with exact SE(2) odometry.
- Motion:
PolylinePathfor waypoint paths with arc-length, closest-point, and lookahead queries, andMinimumSnapPlannerfor the smoothest trajectory through them. - Mapping: 2D
OccupancyGridandScanGeometry
Core math
- Automatic differentiation: Exact autodiff of any order (total and partial), plus Jacobian and Hessian matrices.
- Linear algebra: fixed-size, stack-allocated
MatrixandVectorwith LU, Cholesky, column-pivoted QR, SVD, symmetric eigendecomposition, and the matrix exponentialexpm. General N×N determinant and inverse, pseudo-inverse, eigenvalue clamping,solve_discrete_riccatiandsolve_discrete_lyapunov. - Least-squares optimization:
LevenbergMarquardtandGaussNewtonsolvers for nonlinear curve fitting. - Root finding: bracketed bisection and Newton solvers for scalar equations and square systems, with an optional damped line search.
- Polynomials:
Polynomialfor evaluation with any number of derivatives in one pass, arithmetic, calculus, fitting and real roots;PiecewisePolynomialfor curves made of pieces; andMultivariatePolynomialfor several variables with symbolic partial derivatives. - Integration: iterative Newton-Cotes rules (Boole, Simpson, Trapezoidal) and Gaussian quadrature (Legendre, Hermite, Laguerre) over finite, semi-infinite, and infinite limits.
- ODE integrators: fixed-step
Rk4and adaptiveRk45(Dormand-Prince 5(4)) with PI step control and dense output, plusExponentialMap, which is a purely orientation integrator. - Discretization: zero-order hold, Van Loan, and discrete white-noise models for continuous-time linear systems.
- Signal processing:
Biquadlow-pass, high-pass, band-pass, and notch filters; with cascades, motor-harmonic notches, and per-channel filtering. PlusMovingAverage,RunningMedian,SavitzkyGolaysmoothing,Deadband,HysteresisandSlewRateLimiterconditioning. - Vector calculus: curl, divergence, and line and flux integrals.
- Approximation: linear and quadratic Taylor models with goodness-of-fit metrics.
- Random:
Pcg32and theRandomSourcetrait, a seedableno_stdgenerator for the particle filter and for stochastic models.
Quick start
Two formulas, written once, carried through six modules, each step feeding the next:
use *;
use ;
use ;
Every fallible call propagates with ?: each module has its own error enum, and all of them
convert into the CalcError umbrella, so one return type covers a program that mixes modules.
Full tutorial
Refer to the tutorials for a comprehensive tutorial for each module. They show the full imports, expected outputs in comments, error-path notes, and pointers to runnable demos. Start there when you need the complete picture of a feature.
Accuracy
Verified against external-library fixtures (mpmath, numpy, scipy, filterpy) in
the multicalc-qa crate, with per-module tables generated from those fixtures. See
benchmarks/README.md
for the index, or go straight to
calculus,
linear_algebra,
optimization,
ode,
estimation,
or root_finding.
Runnable demos
Runnable, self-contained programs for each module live in the
demos/ crate. See
demos/README.md. Run one
with:
Feature flags
alloc(off by default): enables the heap-based methods for inputs too large for the stack. See Heap allocation.
Heap allocation
The library allocates nothing by default: every type is fixed-size and lives on the stack. Turning
on alloc pulls in extern crate alloc and unlocks exactly two things:
estimation::ParticleFilter, whose cloud of samples is sized at runtime and so cannot be a fixed-size stack type.numerical_derivative::jacobian::Jacobian::get_on_heap, which returns aVec<Vec<_>>for Jacobians too large to sit on the stack. The stack-allocatedgetis always available.
Nothing else changes: no_std, forbid(unsafe_code), and the no-panic rules hold either way, and
the feature never pulls in std.
MSRV and edition
Edition 2024, minimum supported Rust version 1.85.
Contributing
See CONTRIBUTING.md.
Acknowledgements
The least-squares solvers and QR factorization port the public-domain MINPACK routines lmder,
lmpar, qrfac, and qrsolv (Moré, Garbow, Hillstrom; netlib), following Moré (1978), "The
Levenberg-Marquardt algorithm: Implementation and theory", and Nocedal & Wright, Numerical
Optimization (chapters 4 and 10).
License
multicalc is licensed under the MIT license.