Não é compressão com perda "aceitável na média". É um contrato: |erro| ≤ ε, em toda amostra, verificado na decodificação.
O TUBE comprime telemetria de robôs — juntas, IMU, odometria, poses — dentro de um tubo de raio ε em volta do sinal original. Vocês escolhem o ε por canal (tipicamente abaixo do ruído do próprio sensor); o codec garante que a reconstrução nunca sai do tubo. Medido em voos, braços e bags reais, contra os compressores publicados e instaláveis que conseguimos rodar.
123×
drone real PX4, com seek
37×
manipulador real ALOHA, 14 juntas
21×
robô real ROS2/MCAP, via rosgate
≤ 1,00
erro/ε em toda amostra, verificado
O que fica em aberto é o destino dos terabytes — e a pergunta forense que ninguém consegue responder sem varrer tudo.
Um robô em operação gera rosbags na casa dos gigabytes por hora. Multiplique por frota e por meses de retenção: o custo de armazenar, e a banda robô→nuvem, viram a conta que cresce mais rápido que a operação.
Comprimir com zstd ajuda, mas trata o sinal como bytes opacos: paga a taxa cheia do ruído do sensor e não sabe nada sobre o que o dado significa. Comprimir com perda genérica (downsampling, float32) destrói exatamente o que importa numa investigação: ninguém sabe dizer quanto erro foi introduzido em cada amostra.
E quando algo dá errado em campo, a pergunta é sempre a mesma: "quando a junta 3 excedeu X rad? quando a corrente do motor passou de Y?" — hoje, responder isso significa decodificar o log inteiro.
Rosbags brutos são grandes demais para guardar por anos — e apagar é abrir mão da evidência.
Uplink de frota é caro e limitado. O que não cabe no link fica no robô — ou se perde.
"Quando o sinal passou de X?" deveria ser uma query barata, com resposta em que se pode confiar — não uma varredura completa.
Cada canal declara quanto erro tolera. O codec transforma essa declaração em contrato.
A engenharia do robô assina os bounds por canal — junta ±0,001 rad, giroscópio ±0,002 rad/s, corrente ±10 mA. A regra da casa: ε abaixo do ruído do sensor significa perda abaixo do que o sensor já mente. A partir daí, cinco mecanismos empilhados fazem a taxa:
Uma régua cujo menor traço é o erro que vocês aceitaram
O valor é quantizado em passos de 2×ε — o que garante, por construção, |original − reconstruído| ≤ ε. Erro máximo determinístico, não métrica média.
Sensor parado não fala
Só transmite quando o valor sai da banda do último valor transmitido. Robô segurando pose ≈ zero bytes de payload. No manipulador ALOHA, 67% das amostras ficam dentro da banda.
Como vídeo: quadros-chave e diferenças
A cada N amostras viaja um valor absoluto. Cada bloco decodifica sozinho: seek real sem descomprimir o resto, e perda de pacote limitada ao bloco.
O codec aprende o movimento e transmite só a surpresa
Regressão, Lorenzo ou modelo sazonal — escolhidos por trecho, antes da quantização, sem propagar ruído. O residual de um movimento previsível custa frações de bit.
O que sobra, empacotado no mínimo de bits
Range coder adaptativo com dois estágios à escolha do canal. Em robótica, onde zeros dominam após o deadband, o estágio bitplane rende −23%.
O contrato — E o contrato é conferido dos dois lados: toda decodificação verifica erro máximo contra o bound, caso a caso — a coluna maxerr/ε ≤ 1,00 dos nossos benchmarks não é suposição, é medição. Fazemos o mesmo com os concorrentes que rodamos.
Benchmark aberto, seed fixa, dados reais públicos (PX4, LeRobot/ALOHA, FAST-LIVO via MCAP, CMU mocap). Os números abaixo usam o formato com seek — o que faz sentido para arquivamento e streaming. O formato batch é ainda menor.
| Caso | Bound assinado (ε) | Bruto | TUBE | Taxa (com seek) | Deadband |
|---|---|---|---|---|---|
| Drone real (PX4 — IMU, EKF, motores) Voo real de quadricóptero. SZ3 fica 2,5× atrás mesmo afinado. | IMU no ruído do sensor · EKF ±2 cm · PWM exato | 1,4 MB | 12,1 KB | 123× | 86% |
| Manipulador real (ALOHA bimanual, 14 juntas) Robô de tarefa segura pose boa parte do tempo — o melhor regime robótico. ZFP fica 8,8× atrás. | juntas ±0,001 rad — abaixo do backlash do servo | 6,7 MB | 186,4 KB | 37× | 67% |
| Robô real (ROS2/MCAP, IMU Livox) Lido de rosbag2/MCAP nativo pelo nosso leitor rosgate (MCAP + CDR próprios, sem ROS instalado). Dispositivo handheld de SLAM — gira o tempo todo; robô de tarefa deve render mais. | gyro ±0,002 rad/s · accel ±0,05 m/s² | 1,4 MB | 68,8 KB | 21× | 49% |
| Mocap real (CMU, esqueleto de 62 DOFs @ 120 Hz) Replay de animação/biomecânica/VR em ~2,3 KB/s. O modo cross-channel explora a cadeia cinemática: −8% adicional em batch. | juntas ±0,05° · root ±2 mm — abaixo do ruído do mocap óptico | 5,0 MB | 237,5 KB | 22× | 42% |
| Replay de corpos rígidos (sintético, 200 corpos @ 60 Hz) O mundo do robô como stream de poses — mapa/replay compartilhado com bound métrico. | posição ±2 mm · yaw ±0,001 rad | 11,0 MB | 217,8 KB | 52× | 89% |
Em todos os casos, erro máximo medido na reconstrução = 1,00× o bound ou menos — a garantia cumprida em toda amostra, coberta por teste de propriedade.
Rodamos os concorrentes de verdade, nos mesmos canais, com o mesmo bound absoluto por canal — e verificamos a garantia deles decodificando, não assumindo. Os 15 casos do benchmark incluem os robóticos acima, mais satélite, ECG real, carro (CAN), medidores e replay de game.
| Concorrente | O que é | Resultado, mesmo bound, garantia conferida |
|---|---|---|
| SZ3 (afinado) | Referência acadêmica de compressão error-bounded — re-medido dando a ele best-of de algoritmo por canal e layout 2D | TUBE menor nos 15 de 15 casos; nos robóticos, SZ3 fica 1,4×–2,5× atrás |
| ZFP (LLNL) | Compressor error-bounded para campos científicos, modo fixed-accuracy | 7–50× atrás em série temporal 1D ruidosa — não é o habitat dele, e os números mostram |
| Swinging Door | O algoritmo dos historians industriais (PI System, ~30 anos de produção), mesmo bound | TUBE 1,8×–10,1× menor nos 15 casos — até nosso formato com seek ganha em todos |
| ModelarDB | O vizinho mais próximo em contrato: lossy com bound por amostra (crate oficial, Rust) | TUBE 2,1×–9,5× menor — e o ModelarDB viola o próprio bound (interno f32): em canais de valores grandes, erro de até 10⁸× o bound declarado |
| BUFF (PVLDB 2021) | Encoder canônico de float com precisão limitada, consultável in-situ | TUBE 1,55×–255× menor — o preço da grade decimal e da cegueira temporal, em números |
A frase que defendemos — nem mais, nem menos: melhor taxa com garantia por amostra contra tudo que é publicado e instalável que conseguimos rodar — SZ3 (afinado), ZFP, swinging door, ModelarDB e BUFF — com a garantia verificada dos dois lados.
O achado do ModelarDB é o argumento inteiro em miniatura: o concorrente mais próximo em contrato não honra o contrato em telemetria float64 real. Nós conferimos o bound em toda decodificação — a deles e a nossa.
Um índice de 2–4 bytes por bloco viaja ao lado do stream (que não muda um byte). A query de threshold poda os blocos irrelevantes com prova de exclusão, e cada amostra dos blocos tocados sai carimbada com a garantia herdada do ε:
O valor original está acima do threshold — garantido por construção.
A ±ε da fronteira — a zona de incerteza é explícita e mínima.
Abaixo do threshold, garantido — sem nem decodificar o bloco.
Zone maps de bancos colunares operam sobre dado lossless e pagam a taxa cheia; sketches dão erro probabilístico. Aqui a resposta vem com garantia determinística — é o que um laudo de incidente exige.
| Caso | Query (threshold no p97) | Blocos tocados | Bytes decodificados | Speedup |
|---|---|---|---|---|
| Manipulador ALOHA | quando left_waist excedeu o p97? | 15/215 | 9% | 10,8× |
| Carro (CAN) | quando a velocidade excedeu o p97? | 2/20 | 10% | 6,4× |
| Mocap CMU | quando root.0 excedeu o p97? | 4/42 | 12% | 8,8× |
| Satélite | quando a temperatura excedeu o p97? | 25/288 | 8% | 12,8× |
| Robô ROS2 (IMU) | quando gyro_x excedeu o p97? | 40/102 | 41% | 2,3× |
A leitura honesta está na última linha: a poda só existe quando o evento é localizado. Exceedance de junta em robô de tarefa é evento localizado (9% dos bytes tocados); giroscópio ruidoso de dispositivo em movimento contínuo cruza o threshold em quase todo bloco (41%). Quando não há o que podar, o índice não atrapalha — 2–4 bytes por bloco e a query equivale ao decode completo.
O princípio — Nenhum degrau toca o robô ou o caminho de controle. O TUBE não substitui nem modifica o ROS2 — entra ao lado, como qualquer ferramenta. Cada degrau é reversível (remover = apagar um binário ou um launch), tem critério de decisão numérico combinado antes, e o seguinte só acontece se o anterior provar valor nos dados de vocês.
Em ~1 semana devolvemos o bag de vocês como caso do benchmark aberto: tamanho TUBE vs MCAP+zstd vs gzip, erro máximo verificado na reconstrução, e uma pergunta forense de vocês respondida no domínio comprimido — com o carimbo. Relatório de 1 página com a leitura honesta, incluindo onde não ganhou.
Ferramenta única em Go puro, sem ROS instalado: archive (comprime + indexa), query (forense com prova) e verify (confere o bound, canal a canal, contra o bag original). Os bounds ficam num YAML versionado por vocês — o ε é decisão de engenharia de vocês, não nossa.
Nó ROS2 comum que assina os tópicos do YAML e grava arquivo + índice ao lado do gravador atual. O caminho de controle não passa por ele; se o nó morrer, o robô nem percebe. CPU/RAM medidos e publicados em tópico de diagnóstico; reconstruções auditadas contra o bag bruto. Rollback = remover o nó do launch.
Bruto vive numa janela curta (7–30 dias); longo prazo vira TUBE + índice, consultável e com garantia declarada. Plugin C++ nativo do rosbag2 é opcional e só se justifica com os volumes reais do degrau 2.
A cultura do projeto: hipótese refutada vira documentação, não rodapé. É assim que os números acima merecem confiança.
Como em codec de vídeo, a assimetria é deliberada: a decodificação é passada única e rápida (25–72 milhões de amostras/s por núcleo); o encode do formato batch paga uma busca exaustiva de modelos (0,03–0,4 Ma/s). O formato com seek codifica 10–80× mais rápido e é o indicado para gravação contínua — um robô gera milhares de amostras/s, ordens de grandeza abaixo do medido. No degrau 2, medimos no hardware de vocês.
Quando o bound é apertado ao nível do ruído do sensor (ECG real a ±1 LSB do conversor, IMU no ruído de fundo), o stream é dominado por aleatoriedade e nenhum preditor ajuda. O ganho cai para o piso honesto (19× no ECG real, 21× no IMU handheld). Quem escolhe o ε escolhe o ponto entre perícia e taxa — é decisão de política, não de código.
Estimamos 30–80× para medidores de energia "como no satélite" — a medição devolveu 7,2–14×, e o porquê (consumo residencial é ruidoso) está documentado no benchmark. A hipótese de que o modo cross-channel ganharia na cadeia cinemática do manipulador também foi refutada: empate exato com o formato por canal. O relatório do degrau 0 trata os dados de vocês com a mesma régua.
Threshold em sinal que cruza o limiar em todo bloco não poda nada (giroscópio ruidoso: 41% dos bytes; no drone, 91%). O índice nunca atrapalha, mas o speedup só aparece quando o evento é raro e localizado — como exceedance de junta em robô de tarefa.
Velocidade de encode em batch, maturidade de ecossistema e campos multidimensionais (o habitat do ZFP/SZ3 em HPC) não são o nosso jogo. E os bounds dos benchmarks foram escolhidos com folga realista, mas ainda não validados com engenheiros do domínio de cada caso — o degrau 0 existe exatamente para isso.
O que aprendemos construindo e medindo o TUBE — publicado com a mesma régua dos benchmarks: número medido, limite declarado.
Cifrar o downlink sem quebrar o contrato: AES-256-GCM por GOP com o bound autenticado no AAD (adulterar o ε quebra a tag), sessão híbrida X25519+ML-KEM-768 e manifesto assinado ML-DSA-65. E o achado medido: a 50–190× de compressão, o selo de 16 bytes por GOP passa a custar mais que o dado que protege — no satélite, +126% de overhead.
Ler a análise PDF técnico10 páginas A4: modelo de canal, os seis formatos, seção telecom (bytes no fio, GOP como unidade de perda, tubesec/PQC), índice certificado, as cinco tabelas de benchmark e os limites honestos — com fonte HTML regenerável no repositório.
Ler a análiseO degrau 0 não instala nada: um .mcap (ou .db3) de 10–30 minutos de operação representativa, meia hora de um engenheiro para assinar os bounds por canal, e em ~1 semana vocês recebem o relatório medido — taxa vs MCAP+zstd, garantia verificada na reconstrução e uma query forense de vocês respondida com carimbo. Incluindo onde não ganhou.
Benchmark aberto e reproduzível — os 15 casos, os concorrentes e a verificação de bound rodam em CI.