Modelo de hardware multinivel: sensores, tarjetas, sistemas
Sesion s32 · 2026-04-11 · Como se mapea el hardware fisico y simulado al DataPlane
1. Los tres niveles del hardware
El hardware de la plataforma LRU tiene una jerarquia natural de tres niveles. Esto aplica tanto al hardware fisico real como al simulado:
Nivel 3: SISTEMA (system)
Un sistema avionico completo — puede estar compuesto por multiples tarjetas
Ej: ADIRU (Air Data Inertial Reference Unit)
Engine Control (FADEC izq + FADEC der)
Electrical System (3 generadores + 2 TRUs + baterias)
Nivel 2: TARJETA / DISPOSITIVO (device)
Una tarjeta electronica, microcontrolador, o LRU fisica
Ej: ble_A92418 (ESP32 con BME280 + ADC + IMU + FPGA)
FADEC_L (controlador motor izquierdo)
ADR_1 (Air Data Reference modulo 1)
Nivel 1: SENSOR (sensor)
Un sensor individual que produce un valor numerico
Ej: adc1 (canal ADC 12-bit)
n1_l (RPM motor izquierdo, %)
alt_baro_capt (altitud barometrica, pies)
temp1 (temperatura BME280, °C)
El DataPlane aplana toda la jerarquia. No importa si un sensor pertenece a una tarjeta con 25 sensores o a un sistema con 3 tarjetas — en el DataPlane es un slot con un nombre unico:
Principio fundamental: el DataPlane no conoce niveles
El DataPlane solo conoce canales planos con un nombre unico compuesto de hw/{deviceId}/{sensorId}. No sabe si sim1_engine_l y sim1_engine_r son parte del mismo "sistema de motores" — esa agrupacion logica vive en el SIM_CATALOG (nivel de dominio), no en el DataPlane (nivel de transporte).
Clip manifest declara (modo channel para hardware enlazable):
needles: { "speed": { channel: "speed" } }
IB_04 en init:
1. Consulta el ORC: ¿que hwObj esta enlazado a este swObj, canal "speed"?
→ enlace activo: hwObjId = "ble_A92418", puerto = "adc1"
2. Resuelve el canal del DataPlane:
→ channelName = "hw/ble_A92418/adc1"
→ dpIndex = dp.indexOf("hw/ble_A92418/adc1") → slot 100
3. Busca metadatos del sensor:
→ SIM_CATALOG no tiene "adc1" de ble_A92418
→ Usa capabilities del hwObj (enviadas por firmware): min=0, max=4095
→ O usa cfg1 del ORC como fallback: valMin1In=0, valMax1In=4095
4. Cachea NeedleBinding:
{ sensorId: "adc1", dpIndex: 100, min: 0, max: 4095, clipRef: <aguja> }
IB_04 en tick:
raw = dp.read(100) → 2048.0
pct = (2048 - 0) / (4095 - 0) = 0.5
aguja.change1(0.5, 2048.0)
4.3 Sistema compuesto: ECAM con datos de multiples dispositivos
Clip manifest (ECAM Upper Display):
this.ib04 = {
swObj: "ECAM_Upper",
needles: {
"n1_l": { sensorId: "n1_l" }, // sim1_engine_l → slot 20
"n1_r": { sensorId: "n1_r" }, // sim1_engine_r → slot 30
"egt_l": { sensorId: "egt_l" }, // sim1_engine_l → slot 21
"egt_r": { sensorId: "egt_r" }, // sim1_engine_r → slot 31
"ff_l": { sensorId: "ff_l" }, // sim1_engine_l → slot 22
"ff_r": { sensorId: "ff_r" }, // sim1_engine_r → slot 32
}
};
IB_04 en init:
Resuelve cada sensorId independientemente:
· "n1_l" → SIM_CATALOG → system "engine_l" → device "sim1_engine_l" → slot 20
· "n1_r" → SIM_CATALOG → system "engine_r" → device "sim1_engine_r" → slot 30
· "egt_l" → SIM_CATALOG → system "engine_l" → device "sim1_engine_l" → slot 21
...
IB_04 NO necesita saber que "engine_l" y "engine_r" son parte del mismo
"sistema de motores". Cada NeedleBinding apunta a su slot y punto.
IB_04 en tick:
Recorre los 6 NeedleBindings, lee 6 slots, normaliza, llama 6× change1().
No importa que vengan de 2 dispositivos distintos — son 6 reads O(1).
5. Escenarios clave y como se resuelven
5.1 Tarjeta con muchos sensores (25 sensores, solo uso 3)
No hay desperdicio
La tarjeta ble_A92418 tiene 25 sensores, pero el AirSpeed solo usa 3 (adc1, adc2, adc3). IB_04 solo crea 3 NeedleBindings y solo lee 3 slots del DataPlane en cada tick. Los otros 22 sensores siguen existiendo en el DataPlane (otros instrumentos pueden leerlos), pero este clip los ignora. Zero overhead por sensores no usados.
Contraste con IB_03: recibia UN CustomEvent con los 25 puertos JSON-serializados, parseaba todo, y luego filtraba por channelMap.
5.2 Mismo sensor fisico en multiples instrumentos
Lectura compartida sin conflicto
alt_baro_capt puede estar en el PFD, en el Altimetro STBY, y en el ND simultaneamente. Los tres leen el mismo slot del DataPlane — es una lectura pura (Float64Array[21]), sin estado, sin locks, sin copia. Multiplicar lectores es gratis.
5.3 Cambiar entre hardware real y simulado
Solo cambia el dpIndex del NeedleBinding
Cuando el instructor cambia la fuente de un instrumento:
No importa si hay 1 tarjeta o 30. Cada tarjeta registra sus sensores en el DataPlane. Cada instrumento apunta sus agujas a los sensorIds que necesita. El DataPlane aplana todo. IB_04 solo ve slots planos.
6. El SIM_CATALOG como registro de metadatos
El SIM_CATALOG ya modela los tres niveles, aunque implicitamente:
Concepto catalogo
Nivel
Que contiene
DisplayDef
Vista / agrupacion por pantalla
id, label, lista de SystemDefs. Ej: "ecam", "pfd", "nd", "hw"
SystemDef
Nivel 2 (dispositivo logico)
id, label, lista de SensorDefs. Ej: "engine_l", "adiru_capt"
SensorDef
Nivel 1 (sensor)
id, label, min, max, unit, cruise, thresholds, puertoHwObj
Lo que IB_04 necesita del catalogo
// IB_04 solo necesita esto para resolver un sensorId:
interface SensorResolution {
sensorId: string; // "egt_l"
deviceId: string; // "sim1_engine_l" — para construir el canal DataPlane
min: number; // 0
max: number; // 1000
unit?: string; // "°C" — opcional, para change1(pct, rawValue) con texto
}
// Funcion de resolucion:
function resolveSensor(sensorId: string): SensorResolution | null {
for (const display of SIM_CATALOG.displays) {
for (const system of display.systems) {
const sensor = system.sensors.find(s => s.id === sensorId);
if (sensor) {
const isHw = display.id === 'hw';
const deviceId = isHw ? system.id : `sim1_${system.id}`;
return {
sensorId: sensor.id,
deviceId,
min: sensor.min,
max: sensor.max,
unit: sensor.unit,
};
}
}
}
return null; // no encontrado — quizas es hardware BLE, resolver via ORC
}
Resolucion en dos fases
Fase 1: Buscar en SIM_CATALOG. Si existe → tenemos deviceId, min, max. Resuelto.
Fase 2: Si no esta en el catalogo (es hardware BLE/MQTT real) → consultar ORC para enlace activo, usar cfg1/capabilities para min/max.
La mayoria de los sensorIds se resuelven en Fase 1 (todos los sensores de simulacion). Solo los sensores de hardware real enlazable necesitan Fase 2.
7. Registro de hardware real en el DataPlane
Cuando un dispositivo BLE real se conecta, sus sensores se registran en el DataPlane via el ORC:
1. ESP32 se conecta al broker MQTT
2. Envia capabilities: { sensores: ["adc1","adc2","temp1","pres1",...], ranges: {...} }
3. MqttAdapter.onMessage() → ORC.handleMqttEvent()
4. ORC registra hwObj "ble_A92418" con 25 sensores
5. DataPlane registra canales:
hw/ble_A92418/adc1 → slot auto-asignado
hw/ble_A92418/adc2 → slot auto-asignado
hw/ble_A92418/temp1 → slot auto-asignado
...
6. Datos llegan: { adc1: 2048, adc2: 3100, temp1: 23.5, ... }
7. ORC → ControlBus.allows() → DataPlane.fromRecord()
8. DataPlane.write(slot, valor)
9. IB_04 tick: dp.read(slot) — el valor ya esta ahi, listo para leer
Para el hardware simulado (sim1_*), el registro ocurre al inicializar la app — el SIM_CATALOG define todos los sensores de antemano y el SimService los registra en el DataPlane.
8. Tabla resumen: donde vive cada cosa
Pregunta
Respuesta
Donde vive
¿Que sensores tiene un dispositivo?
Lista de SensorDefs
SIM_CATALOG (sim) ó capabilities MQTT (hw)
¿Que dispositivos forman un sistema?
Agrupacion logica
SIM_CATALOG → DisplayDef agrupa SystemDefs
¿Cual es el rango de un sensor?
min, max, unit
SensorDef en SIM_CATALOG ó cfg1 en ORC
¿Que valor tiene un sensor ahora?
Float64
DataPlane → slot directo
¿De donde lee una aguja concreta?
sensorId → dpIndex
IB_04 → NeedleBinding
¿Que modo tiene un dispositivo?
Loc/Rnd/HwSim/HwReal
RouterService
¿Quien puede escribir en un sensor?
Fuente permitida por routerMode
ControlBus
¿El dispositivo esta online?
Estado de conexion
ORC → hwObj.status
¿Que enlace tiene un instrumento?
swObj → hwObj + channelMap
ORC → matrizEnlaces (solo para hw enlazable)
9. Conclusion: la jerarquia se aplana, no se destruye
Principio de diseno
Los tres niveles de hardware (sensor → dispositivo → sistema) existen en el dominio y se modelan en el SIM_CATALOG. Pero en el plano de transporte (DataPlane), todo se aplana a una lista plana de slots Float64. IB_04 trabaja en el plano aplanado — no necesita subir a los niveles superiores excepto durante la resolucion inicial (init).
Esto significa que:
· Anadir un nuevo dispositivo con 50 sensores = registrar 50 slots mas en el DataPlane. Zero cambios en IB_04.
· Un instrumento que lee de 5 dispositivos distintos = 5 NeedleBindings, cada uno con su dpIndex. Zero cambios en IB_04.
· Cambiar una aguja de simulacion a hardware real = cambiar un dpIndex. Zero cambios en IB_04.
· Un sistema compuesto de 10 tarjetas con 200 sensores = 200 slots en el DataPlane. Los instrumentos apuntan a los que necesitan. IB_04 no cambia.
El modelo escala horizontalmente sin limites porque el DataPlane es un array plano y IB_04 solo hace dp.read(index) — O(1) sin importar cuantos sensores existan en el universo.