import React, { useState } from 'react'; import { num } from '../../api/useXplane.js'; // ============================================================================ // Citation X — Honeywell Primus 2000 Autopilot / Flight Guidance Controller. // Exact button layout per the manual (pages 26-28): // col1: HDG NAV APP BC col2: ALT VNAV BANK STBY // col3: FLC C/O VS center: PITCH WHEEL (NOSE DN / NOSE UP) // col4: AP YD M TRIM PFD SEL // Mode lamps read the per-mode *_status datarefs (0 off · 1 armed · 2 active), // the same reliable source the PFD uses. Buttons fire X-Plane AP commands. // ============================================================================ export default function CitAP({ xp }) { const V = xp.values || {}; const cmd = xp.command; const stat = (k) => num(V[k]); // 0 off · 1 armed · 2 active const apOn = num(V.apEngaged) > 0 || num(V.apMode) >= 2; const ydOn = num(V.ydOn) > 0 || apOn; const [bank, setBank] = useState(false); // BANK (low-bank 17°) — annunc only const [mtrim, setMtrim] = useState(true); // M TRIM (mach trim) — annunc only const [pfdSel, setPfdSel] = useState('PILOT'); // PFD SEL — pilot/copilot guidance // active mode strings for the annunciator bar (matches the PFD) const lateral = stat('aprStatus') ? ['APP', stat('aprStatus')] : stat('navStatus') ? ['NAV', stat('navStatus')] : stat('bcStatus') ? ['BC', stat('bcStatus')] : stat('hdgStatus') ? ['HDG', stat('hdgStatus')] : ['ROL', 2]; const vertical = stat('gsStatus') ? ['GS', stat('gsStatus')] : stat('vnavStatus') ? ['VNAV', stat('vnavStatus')] : stat('flcStatus') ? ['FLC', stat('flcStatus')] : stat('vsStatus') ? ['VS', stat('vsStatus')] : stat('altStatus') ? ['ALT', stat('altStatus')] : ['PIT', 2]; // A mode button: green lamp when its status is active(2), amber when armed(1). const lamp = (k) => (stat(k) >= 2 ? 'active' : stat(k) === 1 ? 'armed' : ''); const Btn = ({ label, cmd: c, on, cls = '', onClick }) => ( ); const sel = num(V.apAltBug); return (
{/* selected references row (alt / hdg / spd / vs) */}
ALT SEL{Math.round(num(V.apAltBug))}
HDG{String(Math.round(num(V.apHdgBug)) % 360).padStart(3, '0')}
IAS/M{num(V.mach) >= 0.4 ? num(V.mach).toFixed(2) : Math.round(num(V.apSpdBug))}
VS{Math.round(num(V.apVsBug))}
{/* FMA annunciator bar (active = green, armed = white) */}
= 2 ? 'fma-act' : 'fma-arm'}>{lateral[0]} {apOn ? 'AP' : 'FD'}{ydOn ? ' · YD' : ''} = 2 ? 'fma-act' : 'fma-arm'}>{vertical[0]}
setBank((v) => !v)} /> cmd('apStby')} />
{}} />
{/* PITCH WHEEL — VS rate (in VS) or IAS/Mach target (in FLC) */}
NOSE UP
NOSE DN
setMtrim((v) => !v)} /> setPfdSel((p) => (p === 'PILOT' ? 'COPILOT' : 'PILOT'))} />
AP MASTER engages Yaw Damper automatically · PITCH WHEEL sets V/S rate or FLC speed · PFD SEL: {pfdSel} guidance{bank ? ' · LOW BANK 17°' : ''}{mtrim ? ' · MACH TRIM' : ''}
); }