CD Mapping & Control
Paper Machine Cross-Direction Control
PRBS Identification • Adaptive Shrinkage • MPC Control
Stec Corporation
System Architecture
- Two-process architecture over ZeroMQ REQ/REP
- automap4.py: REP controller (binds port 5555)
- PRBS identification, MPC control, mapping
- modeldriver.py: REQ simulator (connects)
- Paper machine simulation, scan generation
- Key principle: automap4 discovers everything
- Transport delay, gain, response width
- modeldriver keeps its secrets (like real machine)
- Message schema identical for sim/live machine
Mapping Matrix G[i,j]
- N_act × N_box matrix (96 × 500 default)
- Each row = actuator response profile
- Row sum = 1.0 (area-normalised)
- Process gain recovered separately:
gain = √(2π) × σ
- Negative gain for dilution actuators
(opening valve decreases basis weight)
- Initial mapping: fallback S-curve + Gaussians
G[i,j] = response of actuator i at databox j
PRBS Identification
- Pseudo-Random Binary Sequence
- Values: {-1, 0, +1}
- Probabilities: P(-1)=0.25, P(0)=0.5, P(+1)=0.25
- Sequence length: 511 per actuator
- All 96 zones excited simultaneously
- Amplitude: 3% of full stroke (configurable 1-20%)
- Uncorrelated excitation across actuators
- Learning rate α = 0.05 (PRBS)
u(t) = clamp(50 + A × PRBS(t), 0, 100)
Cross-Correlation & Response Extraction
- Transport delay D scans (initially 2, auto-estimated)
- Profile change: Δy(t) = y_CD(t) - y_CD(t-D-1)
- Response window: ±35 databoxes around centre
- Sign correction: PROCESS_GAIN_SIGN × sign(PRBS_i)
- Gaussian filter: σ = 1.5 databoxes
- Normalise to sum = 1
- Window positioned at hardcoded S-curve centre
(prevents divergence feedback loop)
r_i = sign(PRBS_i) × Δy[c_i - W : c_i + W]
EWMA Update Rules
- Exponential Weighted Moving Average:
G_i[window] = (1-α) × G_i[window] + α × response
- Two learning rates:
- α = 0.05 for PRBS identification
- α = 0.20 for control-time refinement
- Row re-normalised after each update
- Quality metric: Q_i = min(1.0, count_i / 5.0)
- Progress: P = (ΣQ_i + N_unlearned × 0.5) / N_act
G_i ← (1 - α) · G_i + α · r_i / Σ(r_i)
Shrinkage Model (S-Curve)
- Non-linear edge shrinkage from angled jet trajectory
- 3rd-order polynomial: s(x) = C₃x³ + C₁x
- Initial coefficients: C₃ = -0.4, C₁ = 0.95
- Normalised actuator position: x = i/(N_act-1) - 0.5
- Expected centre: c_i = 250 + s(x) × 460
- Polynomial fitted from learned response centres
- Fallback S-curve used for window positioning
(NOT learned model — prevents divergence)
s(x) = -0.4x³ + 0.95x
Transport Delay Auto-Estimation
- Cross-correlate actuator moves with profile changes
- Uses act_history (actual positions, not PRBS {-1,0,1})
- For each actuator with ≥3 bumps:
- Weighted centre: c = Σ(x × row) / Σ(row)
- Extract profile time series at centre
- Cross-correlate: corr = correlate(Δmeas, Δact)
- Average correlation across actuators
- Peak lag = transport delay in scans
- Updates every 5 scans during PRBS
delay = argmax(corr(Δact, Δmeas))
Coordinate System & Normalisation
- Raw profiles: absolute databox coordinates [0, 499]
- Sheet wander shifts edges → different raw positions
- Normalise to sheet coordinate frame:
x_norm = linspace(left_edge, right_edge, N_box)
profile_norm = interp(x_norm, raw_profile)
- Raw-to-normalised index conversion:
norm_idx = (raw_pos - left) / (right - left) × 499
- Critical fix: edge zones now learn correctly
(previously missed responses by 40+ databoxes)
MPC Supervisory Control
- SLSQP optimiser (Sequential Least Squares)
- Objective: J = Q·Σ(error²) + R·Σ(Δu²) + S·Σ(bending²)
- Q = 1.0 (target tracking)
- R = 4.0 (move suppression)
- S = 8.0 (bending penalty)
- Constraints: |Δu| ≤ 10%, |Δu_adj| ≤ 25%
- Control interval: transport_delay + 1 scan
- Process gain: √(2π) × σ (converts normalised to raw)
J = Q·||y + G·Δu - y_tgt||² + R·||Δu||² + S·||D²u||²
Wander Detection & Feed-Forward
- EWMA-smoothed edge positions (α = 0.02)
- Wander = (left + right)/2 - 250.0 databoxes
- FFT frequency estimation (Hann-windowed rFFT)
- 200-scan history
- Dominant frequency in cycles/scan
- Confidence: (peak/background - 1) / 9 × 100%
- Green if confidence ≥ 90% threshold
- Feed-forward: project 1 scan ahead
- Compensate before wander appears in profile
Stale Scan Protection
- Monitor time between consecutive scans
- If gap > 40s (configurable):
- skip_mapping = True
- Hold last setpoints (PRBS frozen)
- Log: 'SKIP: Xs gap exceeds max Ys'
- Automatic resume when fresh scans arrive
- Tested via modeldriver standardisation:
- Interval: 90 min (configurable)
- Duration: 30 s (configurable)
Setpoint Ownership & Bumpless Transfer
- automap4 owns setpoints
- Initialised from actuator positions at init
(first_after_init=True in setpoint_poll)
- Priority: stale > PRBS > control > idle > manual
- _last_setpoints cached for mid-scan polls
- modeldriver snaps positions immediately
- Simulator transport delay handles timing
- Manual bump: exclude zones from PRBS
prbs_vals[manual_mask] = 0
CSV Tuning Log
- Record button (Ctrl+R) starts/stops logging
- Core: scan_number, timestamp, mode, progress
- Wander: wander_db, freq, confidence, edge_mode
- Controller: horizon, R, S, Q, max_delta_u
estimated_gain, width, tau, tc
- Truth (SIM only): centre_err, width_est vs true
- View > CSV Report: printable HTML summary
- Enables offline tuning analysis
Key Parameter Relationships
- Process gain: √(2π) × σ
- Transport delay: cross-correlation peak lag
- Control interval: delay + (0 or 1 scan)
- MPC horizon: max(3, delay + 1)
- Progress: (Σquality + unlearned×0.5) / N_act
- Wander confidence: (peak/bg - 1)/9 × 100%
- Shrinkage: y = -0.4x³ + 0.95x
- Response window: ±35 databoxes
- EWMA: α=0.05 (PRBS), α=0.20 (control)
PaperMachineSimulator Constants
- N_act = 96, N_box = 500 (defaults)
- FOOTPRINT_STD_DEV = 4.5 databoxes
- S-curve: C₃ = -0.4, C₁ = 0.95
- WANDER_AMPLITUDE = 6.0 databoxes
- machine_speed = 1.5 m/s
- L = 40.0 m (transport distance)
- NOISE_STD_DEV = 0.8
- Negative gain: -exp() footprint
- These are modelstdcom.py's secrets!
Field Report Example
This is the auto report generated during the PRBS phase.