Modelo multi-avion, sensores de velocidad y unidades

Diseno arquitectonico para soportar multiples modelos de aeronave · Sesion s33 · 2026-04-11

1. Problema

El catalogo actual (sim-catalog.ts) tiene los valores del A320 CFM56-5B hardcoded. Pero los instrumentos son reutilizables — un velocimetro funciona igual en un A320 que en un B737 o un C172, solo cambian los rangos, limites y umbrales. Necesitamos separar que se mide (sensores universales) de con que limites (perfil del avion).

Ademas, el velocimetro actual conecta las 3 agujas (speed, vmo, bug) al mismo sensor IAS. En la realidad, cada una tiene una fuente distinta: IAS viene del ADC, VMO es un limite operacional que varia con altitud, y el bug es el valor seleccionado por el piloto en el FCU.

2. Sensores nuevos para airdata

2.1. Inventario actual del sistema airdata

IDLabelUnitMinMaxCruiseEstado
IASIndicated Airspeedkt0400250EXISTE
MachMach Number010.78EXISTE
ALTBarometric Altitudeft04500035000EXISTE
VSVertical Speedft/m-600060000EXISTE
QNHQNH SettinghPa95010601013EXISTE
SelSpdSelected Speed (FCU)kt0400250EXISTE (en fdr_auto)

2.2. Sensores nuevos propuestos

IDLabelUnitMinMaxCruise A320Notas
TASTrue Airspeedkt0600480NUEVO Derivado de IAS + ALT + SAT. Esencial para ND y conversiones.
SATStatic Air Temp°C-8050-56NUEVO ISA a FL350 = -56.5°C. Necesario para Mach↔IAS.
TATTotal Air Temp°C-8060-28NUEVO SAT + calentamiento por ram. TAT = SAT × (1 + 0.2·M²).
VMOMax Operating Speedkt0400350NUEVO A320: VMO=350kt, MMO=0.82. Varia con altitud (cross-over).
VFEMax Flap Extendedkt03000FUTURO Depende de configuracion de flaps. Arco ambar en PFD.
VS1GStall Speed 1Gkt02500FUTURO Franja roja inferior. Depende de peso y config.
GSpdGround Speedkt0600480EXISTE (en nd_route)

Los sensores VMO, TAS, SAT, TAT son los prioritarios. VMO porque alimenta directamente la aguja vmo del velocimetro. TAS y SAT porque son la base para las conversiones de unidades y para el calculo de Mach. TAT porque es lo que muestra el piloto en la pantalla.

3. Modelo multi-avion

3.1. Concepto: AircraftProfile

Un AircraftProfile es un objeto que contiene todos los valores que varian entre modelos de avion. El catalogo de sensores sigue siendo universal (IAS es IAS en cualquier avion), pero el perfil define los rangos operativos, umbrales, y limites para un modelo concreto.

interface AircraftProfile {
  id: string;                    // 'a320', 'b737ng', 'c172', 'a350'
  name: string;                  // 'Airbus A320-214'
  family: string;                // 'A320' | 'B737' | 'Cessna' | 'A350'
  engines: string;               // 'CFM56-5B' | 'CFM LEAP-1A' | 'Lycoming IO-360'
  category: 'transport' | 'ga' | 'military';

  // ── Limites de velocidad ──
  vmo: number;                   // kt — Max Operating Speed
  mmo: number;                   // Mach — Max Operating Mach
  crossoverAlt: number;          // ft — altitud donde VMO=MMO (A320: ~FL310)
  vfe: Record<string, number>;   // flap config → max speed: { 'CONF1': 230, 'CONF2': 215, ... }
  vle: number;                   // kt — max speed landing gear extended

  // ── Rangos de instrumentos ──
  iasRange: [number, number];    // [0, 400] A320, [0, 300] C172
  altRange: [number, number];    // [0, 45000] A320, [0, 14000] C172
  vsRange: [number, number];     // [-6000, 6000] A320, [-2000, 2000] C172

  // ── Umbrales ECAM/PFD ──
  thresholds: Record<string, SensorThresholds>;
  // 'IAS': { c: [340,350], w: [350,400], cLow: [180,210], wLow: [0,180] }  // A320
  // 'IAS': { w: [163,200], wLow: [0,40] }                                   // C172

  // ── Motores ──
  n1Range: [number, number];     // [0, 110] jet, [0, 2800] piston (RPM)
  egtRange: [number, number];    // [0, 1000] jet, [0, 900] piston (°C)

  // ── Otros ──
  mtow: number;                  // kg — para calculo de VS1G
  weights: { oew: number; mzfw: number; mtow: number; mlw: number };
}

3.2. Perfiles de ejemplo

Airbus A320-214 ACTUAL
VMO: 350kt · MMO: 0.82 · Crossover: FL310 · IAS: 0-400kt · ALT: 0-45000ft
N1: 0-110% · EGT: 0-1000°C · CFM56-5B · MTOW: 78000kg
Boeing 737-800 FUTURO
VMO: 340kt · MMO: 0.82 · Crossover: FL260 · IAS: 0-400kt · ALT: 0-41000ft
N1: 0-110% · EGT: 0-1000°C · CFM56-7B · MTOW: 79016kg
Cessna 172SP FUTURO
VNE: 163kt · IAS: 0-200kt · ALT: 0-14000ft · VS: ±2000ft/m
RPM: 0-2800 · CHT: 0-500°F · Lycoming IO-360 · MTOW: 1111kg
Airbus A350-900 FUTURO
VMO: 340kt · MMO: 0.89 · IAS: 0-400kt · ALT: 0-43100ft
N1: 0-110% · EGT: 0-1100°C · Trent XWB-84 · MTOW: 280000kg

3.3. Donde vive el perfil en la arquitectura

Hay dos niveles de datos:

CATALOGO (universal)

Define que sensores existen y sus propiedades base. No cambia entre aviones. IAS siempre es velocidad indicada en knots, ALT siempre es altitud en feet.

Fichero: sim-catalog.ts

PERFIL (por modelo)

Define los limites operacionales de un modelo concreto. VMO, rangos de instrumentos, umbrales de alerta, configs de flaps. Overridea los defaults del catalogo.

Fichero nuevo: aircraft-profiles.ts

El flujo es: al seleccionar un modelo de avion, el perfil sobreescribe los min/max/th del catalogo para los sensores que define. Los sensores que el perfil no menciona mantienen los defaults del catalogo. Esto permite que un C172 redefina IAS.max = 200 sin tocar los sensores de hidraulica que no tiene.

4. Unidades de velocidad

4.1. Unidades relevantes en aviacion

UnidadIDUsoConversion desde kt
KnotsktUnidad base internacional× 1
km/hkmhRusia, China, algunos GA× 1.852
mphmphAviacion GA en USA (raro)× 1.15078
m/smsMeteorologia, planeadores× 0.51444
MachmachCrucero jets. Depende de SATIAS / (a₀ × √(T/T₀)) — no lineal
ft/minfpmVelocidad vertical (VS)N/A (unidad propia)

4.2. Donde se convierte

Las conversiones simples (kt↔km/h↔mph) son multiplicaciones lineales y pueden vivir en cualquier capa. Pero la conversion IAS↔Mach↔TAS depende de altitud y temperatura — es un calculo aerodinamico que necesita multiples sensores.

Propuesta: crear un modulo units.ts en src/simulation/ con funciones puras de conversion. IB_04 no convierte — el clip recibe rawValue en la unidad base del sensor (kt para IAS) y tiene todo lo que necesita. Si el clip quiere mostrar km/h, llama a la funcion de conversion en su change1:

// En units.ts (nuevo)
export const ktToKmh = (kt: number) => kt * 1.852;
export const ktToMph = (kt: number) => kt * 1.15078;
export const ktToMs  = (kt: number) => kt * 0.51444;

// Conversion IAS → Mach (simplificada, valida hasta FL350)
// Necesita SAT (Static Air Temperature en °C)
export function iasMach(ias: number, sat: number): number {
  const T = sat + 273.15;          // Kelvin
  const a = 340.3 * Math.sqrt(T / 288.15);  // velocidad del sonido local
  return ias / a;                  // aproximacion subsonica
}

// Conversion IAS → TAS
// Necesita altitud presion (ft) y SAT (°C)
export function iasTas(ias: number, altFt: number, sat: number): number {
  const rho0 = 1.225;             // densidad nivel del mar kg/m³
  const T = sat + 273.15;
  const T0 = 288.15;
  const lapseRate = 0.0065;       // °C/m en troposfera
  const altM = altFt * 0.3048;
  const rho = rho0 * Math.pow(1 - lapseRate * altM / T0, 4.256);
  return ias * Math.sqrt(rho0 / rho);
}

4.3. En el clip

Un clip futuro con display multi-unidad podria hacer:

// frame_0 del contenedor
// import no funciona en clips Animate, pero units.ts expone en window
var units = window.LRU_UNITS || {};

// En la aguja speed
this.change1 = function(pct, rawKt) {
  _this.rotation = angMin + pct * rango;
  // Display en la unidad seleccionada por el usuario
  var displayUnit = window.LRU_SPEED_UNIT || 'kt';
  var val = displayUnit === 'kmh' ? units.ktToKmh(rawKt)
          : displayUnit === 'mph' ? units.ktToMph(rawKt)
          : rawKt;
  if (_this.parent && _this.parent.txtSpeed) {
    _this.parent.txtSpeed.text = Math.round(val) + '';
  }
};

5. Manifiesto nativo completo para airSpeed_01

Con sensores reales diferenciados por aguja:

// frame_0 del contenedor AirSpeed2Det
var _this = this;

_this.ib04 = {
  swObj: "AirSpeed1",
  needles: {
    speed: { sensorId: "IAS" },      // velocidad indicada — ADC
    vmo:   { sensorId: "VMO" },      // limite operacional — perfil avion
    bug:   { sensorId: "SelSpd" },   // bug velocidad — FCU piloto
  },
  meta: {
    type: "gauge",
    label: "Airspeed Indicator",
    ata: "34",
    unit: "kt",
    arcRange: [15, 345],
  }
};

Cada aguja apunta a su verdadero sensor. Cuando el perfil del avion cambie de A320 a B737, el sensor VMO automaticamente tendra un valor diferente (350→340kt), y la aguja vmo se movera al nuevo limite sin tocar el clip.

6. Plan de implementacion

Fase 1 — s33/s34: Sensores nuevos + clip piloto nativo

#ItemEsfuerzo
1Anadir VMO, TAS, SAT, TAT al sistema airdata en sim-catalog.ts~20 lineas
2SimService: calcular VMO segun altitud (crossover VMO/MMO)~15 lineas
3SimService: calcular TAS y TAT derivados de IAS+ALT+SAT~20 lineas
4Migrar clip airSpeed_01 en Adobe Animate a manifiesto .ib04Manual en Animate
5Crear units.ts con conversiones basicas~40 lineas
6Actualizar sim-bridges.ts: AirSpeed1 con sensorIds reales~5 lineas

Fase 2 — futuro: aircraft-profiles.ts

#ItemEsfuerzo
7Crear aircraft-profiles.ts con tipo AircraftProfile~100 lineas
8Perfil A320-214 (extraer valores hardcoded del catalogo)~60 lineas
9Mecanismo de override: perfil sobreescribe th/min/max del catalogo~40 lineas
10UI selector de modelo de avion (Sim1Header o Settings)Componente React
11Segundo perfil (B737-800 o C172) para validar el modelo~60 lineas

Fase 3 — futuro: unidades configurables

#ItemEsfuerzo
12Preferencia de unidad de velocidad en settings (kt/kmh/mph)Zustand store
13Exponer window.LRU_UNITS y window.LRU_SPEED_UNIT~10 lineas en init
14Clips con display numerico multi-unidadEn cada clip migrado

7. Decisiones de diseno abiertas

D1. VMO: sensor fisico o calculado? En un avion real, VMO no viene de un sensor — es un valor computado por el FMC segun altitud. Propuesta: SimService lo calcula cada tick y lo escribe al DataPlane como un sensor mas. El clip no sabe ni le importa si viene de un ADC o de un calculo.

D2. Perfil de avion: donde se selecciona? Opciones: (a) en Sim1Header junto al selector de escenario, (b) en Settings global (aplica a toda la sesion), (c) en EscenariosContext (cada escenario puede definir su modelo). La opcion (c) es la mas flexible — un escenario de "takeoff A320" define su modelo, y otro de "VFR C172" define el suyo.

D3. Conversiones IAS↔Mach: precision vs simplicidad? La formula exacta usa la ecuacion de Saint-Venant y requiere calibracion. Para entrenamiento una aproximacion subsonica es suficiente y mucho mas simple. Si en el futuro se necesita precision (SimBridge con MSFS), se puede mejorar sin cambiar la interfaz.