Detecciones de IA DJI a bordo de la aeronave
Las aeronaves DJI Dock 3 incluyen una funcionalidad de reconocimiento de objetivos por IA a bordo (personas, coches, embarcaciones). Cuando está habilitada, la aeronave incrusta cajas delimitadoras de detección en el bitstream H.264 como mensajes SEI (Supplemental Enhancement Information). ARGUS parsea esos mensajes SEI en el navegador y renderiza cajas de superposición en vivo sobre el tile del stream del dron.
Habilitar IA en la aeronave
- Abre el tile del stream del dron para una aeronave Dock 3 en la vista de operaciones.
- Abre el cajón de Ajustes del dron (icono de engranaje, esquina superior derecha del tile).
- Desplázate a Percepción → IA a bordo de DJI y conmuta a on.
- ARGUS llama al servicio DRC
drc_ai_identifyconon=1, ruteado a través de argus-dji como una publicación MQTT a la aeronave. Los mensajes SEI empiezan a aparecer en el bitstream en ~1–2 segundos.
Opcional: en Dock 3 con múltiples modelos de reconocimiento
cargados, elige el modelo activo del dropdown debajo del toggle.
ARGUS publica drc_ai_model_select con el índice elegido. El
predeterminado es modelo 0 (el detector de propósito general de
persona + vehículo + embarcación).
Cómo funciona el pipeline SEI
Las detecciones de IA de DJI no son un canal de datos separado — cabalgan dentro del propio bitstream H.264. El decoder ve un frame de vídeo normal; ARGUS extrae el payload de detección a nivel de bytes:
- Escaneo Annex-B. El buffer entrante es una unidad de acceso
H.264 — una o más unidades NAL separadas por códigos de inicio
00 00 01o00 00 00 01.iterateNalUnitsproduce cada cuerpo NAL. - NAL tipo 6 (SEI). Sólo las unidades NAL donde
(byte[0] & 0x1f) === 6llevan SEI. Las demás se omiten. - Strip de prevención de emulación. Por RFC 3984 §5.4,
cualquier secuencia
00 00 03dentro de un NAL tiene el03insertado para evitar que el payload se parezca a un código de inicio.stripEmulationPreventionelimina todos esos escapes antes del parseo — leer el NAL crudo como bytes daría offsets equivocados en caso contrario. - Decodificación de longitud multi-byte. H.264 §7.3.2.3.1
codifica tanto
payload_typecomopayload_sizecomo la suma de bytes0xFFiniciales más un byte final <0xFF.readMultiByteLengthdecodifica ambos. - Tipo de payload DJI. DJI usa
payload_type = 5(user_data_unregistered); algunos builds de dev también emiten tipo 4. - Marcador de transporte. El primer byte del payload DJI
distingue el transporte:
0xF5→ WebRTC (firmware post-Dock 3, la ruta moderna).0x65→ Agora (transporte legacy, mantenido para firmware antiguo).- cualquier otro → fallback crudo, el caller puede inspeccionar los bytes sin parsear.
- Decodificación de struct DJI. Layout little-endian — magic
DJIFopcional, byte de versión, conteo de objetivos, timestamp de 64 bits, luego N × (índice de objetivo, tipo de objeto, confianza, x, y, w, h, estado, reservado). Las coordenadas son fijo-punto de 12 bits 0–4095, relativas al frame — no coordenadas de píxel. El parser divide por 4095 para devolver rectángulos normalizados 0–1 para que el renderer de superposición no necesite conocer la resolución del vídeo.
Todo esto corre en TypeScript puro — sin dependencia nativa de decodificación.
Tipos de objeto
| Valor | Tipo |
|---|---|
| 1 | UNKNOWN |
| 2 | PERSON |
| 3 | CAR |
| 4 | BOAT |
El tipo de objeto determina el color de la caja de superposición — persona verde, coche cian, embarcación azul, desconocido gris.
Estados de objetivo
Cuando el gestor de seguimiento de la aeronave está activo, cada detección lleva un estado por objetivo:
| Valor | Estado |
|---|---|
| 0 | TRACKED — bloqueo estable frame-a-frame. |
| 1 | LOST — el tracker perdió el objetivo; la caja desaparecerá en el siguiente frame. |
| 2 | NEW — primera aparición, aún no estable. |
| 3 | OBSCURED — parcialmente oculto; el tracker mantiene la última posición conocida. |
El estado determina el estilo de borde de la caja — sólido para
TRACKED, discontinuo para NEW, contorno ámbar para OBSCURED,
atenuado para LOST.
Normalización de confianza
DJI emite la confianza en una de dos convenciones dependiendo del
firmware: 0–100 (porcentaje) o 0–10000 (basis points). El parser
auto-detecta — si el byte crudo es mayor que 100, se trata como
basis-points y se divide por 10000; de lo contrario porcentaje y se
divide por 100. La salida se limita a [0, 1].
Renderizado de superposición
Cada detección se renderiza como una caja de color más una etiqueta
en la esquina PERSON 87% (o similar). Hacer clic en una caja
selecciona el objetivo — su targetIndex se convierte en el
tracker activo. Acciones posteriores:
- Spotlight-zoom opcional (Dock 3 con payload de foco) — ARGUS
llama a
drc_ai_spotlight_zoom_trackcon el índice de objetivo seleccionado. El gimbal de la aeronave auto-sigue y el foco acompaña. - Doble clic en una caja — suelta un banderín de mapa en el centroide de espacio-mundo de la detección (ray-cast desde la pose de la cámara a través del centro de la caja sobre el terreno Cesium). Útil para marcar una persona de interés o un vehículo sospechoso.
Cableado upstream — parcial
La mitad downstream de este pipeline (parseo SEI → flujo de detección → renderizado de superposición) está cableada y se entrega. La mitad upstream — extraer los bytes de unidad de acceso H.264 fuera de un receptor WebRTC en vivo para que el parser pueda ingerirlos — es parcial. Existen dos rutas por navegador, y la correcta la elige el componente de vista que posee el stream:
RTCRtpScriptTransform(Chrome, Edge, Firefox-nightly) — adjunta un worker de transform alRTCRtpReceiverentrante. El worker recibeRTCEncodedVideoFrames cuyo.datason los bytes NAL H.264 crudos. Aliméntalos aDjiAiDetectionsService.ingestAnnexB(buf, meta).VideoDecoder+MediaStreamTrackProcessor(Chrome + Edge hoy, Safari 17+) — extrae chunks codificados en el hilo principal, parsea SEI, y luego re-decodifica normalmente para visualización. Más portable pero cuesta un salto de decodificación en hilo principal.- Parseo del lado del servidor (fallback) — argus-dji se suscribe al ingreso WHIP, extrae SEI de RTP, publica detecciones parseadas en el canal de datos TACLINK. Funciona en cada navegador pero necesita un parser C/GStreamer de H.264; programado por separado si las rutas de navegador resultan frágiles.
Aspiracional hasta que el upstream esté finalizado. Hoy, las detecciones se renderizan en navegadores donde la ruta
RTCRtpScriptTransformestá cableada para la familia específica de firmware del dock (Dock 3 post-04.00). En Safari, la rutaVideoDecoderes el fallback planificado. Espera huecos en navegadores más antiguos hasta que aterrice la ruta del lado del servidor.
Reinicio entre streams
Cuando el operador cambia cámaras (p. ej. wide → zoom) o el stream
se desmantela y re-aprovisiona, DjiAiDetectionsService.clear()
vacía el historial de detección y resetea el último frame — para
que las cajas obsoletas del stream previo no persistan en el nuevo
vídeo.
Relacionado
- DRC — el pipeline de comandos usado para conmutar la IA a bordo de la aeronave y seleccionar el modelo de reconocimiento.
- Tile del dock — el tile padre que hospeda la superposición del stream del dron.
- Auto-stream — la capa de ingreso sobre la que cabalgan los mensajes SEI.