RC
RoboControl Documentation

Math Module API

Control theory algorithms and mathematical utilities for robotics applications.

Advanced Controller Implementation

Anti-Windup PID with Derivative Filtering

Production-ready PID with integrator windup prevention and noise filtering.

Copy
var pid = new PidController(kp: 2.0, ki: 0.5, kd: 0.1)
{
    OutputMin = -127,
    OutputMax = 127,
    
    // Anti-windup protection
    AntiWindupMode = AntiWindupMode.BackCalculation,
    IntegralWindupThreshold = 100,
    
    // Derivative filter (1st-order lowpass)
    DerivativeFilterTf = 0.01,
    
    // Setpoint weighting for smoother transitions
    SetpointWeight = 1.0,
    DerivativeWeighting = 0.0  // don't react to setpoint jumps
};

while (true)
{
    double output = pid.Compute(setpoint: 100, measurement: 75, dt: 0.01);
    motor.Power = (int)output;
    
    if (pid.IsWindupActive)
        logger.LogWarning("Integrator saturated");
}

Model Predictive Control (MPC)

Constrained optimal control over receding horizon with preview of future references.

Copy
// MPC configuration with constraints
var mpc = new ModelPredictiveController(A, B, Q, R, horizonLength: 20)
{
    // Constraints on states and inputs
    StateMin = new[] { -100, -100, -5, -5 },   // x, y, vx, vy
    StateMax = new[] { 100, 100, 5, 5 },
    
    InputMin = new[] { -2, -2 },               // ax, ay
    InputMax = new[] { 2, 2 },
    
    // Rate limits on inputs (prevent jerky commands)
    InputRateMin = new[] { -0.5, -0.5 },
    InputRateMax = new[] { 0.5, 0.5 },
    
    // Solver tolerance
    SolverTolerance = 1e-4,
    MaxIterations = 100
};

// Solve optimization problem
var control = mpc.ComputeControl(currentState, referenceTrajectory);
System.Diagnostics.Debug.WriteLine($"Solve time: {mpc.LastSolveTime}ms");

LQR (Linear Quadratic Regulator)

Optimal linear feedback control minimizing quadratic cost with no constraints.

Copy
// Solve continuous-time LQR problem: min ∫(x'Qx + u'Ru)dt
var result = LqrDesign.SolveContinuous(A, B, Q, R);

if (result.Success)
{
    var K = result.K;          // Optimal feedback gain
    var P = result.P;          // Solution to Riccati equation
    var eigenvalues = result.EigenvaluesCL;  // Closed-loop poles
    
    // Apply control law: u = -K * (x - x_ref)
    var error = currentState - referenceState;
    var u = -K * error;
    
    // Check stability
    Console.WriteLine($"Max eigenvalue: {eigenvalues.Max().Real:F3}");
    if (eigenvalues.All(e => e.Real < 0))
        Console.WriteLine("System is stable");
}

State Estimation & Filtering

Extended Kalman Filter (EKF)

Nonlinear state estimation with multi-sensor fusion for robust odometry.

Copy
// EKF for robot localization with encoder + IMU fusion
var ekf = new ExtendedKalmanFilter(new Unicycle2DModel())
{
    // Initial state [x, y, theta]
    InitialState = new[] { 0.0, 0.0, 0.0 },
    
    // Process noise (model uncertainty)
    ProcessNoise = new[] { 0.01, 0.01, 0.001 },
    
    // Measurement noise (sensor uncertainty)
    MeasurementNoise = new[] { 0.1, 0.1, 0.05 }
};

// Main estimation loop
while (true)
{
    // Prediction from motion model
    ekf.Predict(
        input: new { LinearVel = encoderVel, AngularVel = gyroRate },
        dt: 0.01,
        processNoise: noiseQ
    );
    
    // Update with measurements
    ekf.Update(
        measurement: new { EncoderDist = distance, GyroHeading = heading },
        measurementNoise: noiseR
    );
    
    var state = ekf.State;
    Console.WriteLine($"Position: ({state[0]:F2}, {state[1]:F2}), Heading: {state[2]:F1}°");
    Console.WriteLine($"Covariance (position): {Math.Sqrt(ekf.Covariance[0, 0]):F4}");
}

Complementary Filter

Fast, low-latency fusion of accelerometer and gyroscope for attitude estimation.

Copy
// Complementary filter for IMU fusion
var filter = new ComplementaryFilter
{
    Alpha = 0.98,  // Weight for gyroscope (higher = trust gyro more)
    Beta = 0.02    // Weight for accelerometer
};

// Fast update at IMU rate (200+ Hz)
filter.Update(
    gyroscopeData: new Vector3(gx, gy, gz),
    accelerometerData: new Vector3(ax, ay, az),
    magnetometerData: new Vector3(mx, my, mz),  // optional
    dt: 0.005
);

var attitude = filter.GetAttitude();  // Euler angles or quaternion

Trajectory Generation

Polynomial Trajectory Planning

Smooth trajectory planning with boundary conditions.

Copy
// 5th-order polynomial with zero acceleration at endpoints
var trajectory = new QuinticTrajectory(
    startPos: 0, endPos: 100,
    startVel: 0, endVel: 0,
    startAcc: 0, endAcc: 0,
    duration: 5.0
);

for (double t = 0; t <= 5.0; t += 0.01)
{
    double pos = trajectory.GetPosition(t);
    double vel = trajectory.GetVelocity(t);
}