Suavizador de Kalman
Visão geral
Um suavizador de Kalman (Kalman smoother) é o contraparte “fora de linha (offline)” do Filtro de Kalman (Kalman Filter). Enquanto um Filtro de Kalman estima o estado atual usando medições até o instante atual, um suavizador estima estados em todos os passos de tempo usando tanto medições passadas quanto futuras. Isso torna a suavização (smoothing) especialmente valiosa quando você pode processar um conjunto de dados (dataset) depois que ele foi coletado — algo comum em registros (logs) de robótica, pipelines de mapeamento e back-ends de SLAM (SLAM back-ends).
Em um modelo linear gaussiano em espaço de estados (linear Gaussian state-space model), a suavização de Kalman calcula a distribuição a posteriori (posterior distribution):
[ p(x_t \mid y_{1:T}) ]
para todo tempo (t), onde (x_t) é o estado latente (latent state) e (y_{1:T}) são todas as medições do tempo 1 até (T). Em contraste, a filtragem (filtering) calcula:
[ p(x_t \mid y_{1:t}) ]
A suavização geralmente reduz ruído, resolve atraso (lag) e corrige erros anteriores ao “revisitar” estimativas de estado passadas quando novas evidências chegam.
Modelo linear gaussiano em espaço de estados (LGSSM)
Suavizadores de Kalman assumem o sistema dinâmico linear padrão:
Dinâmica (modelo de processo): [ x_t = F_t x_{t-1} + B_t u_t + w_t,\quad w_t \sim \mathcal{N}(0, Q_t) ]
Medições (modelo de observação): [ y_t = H_t x_t + v_t,\quad v_t \sim \mathcal{N}(0, R_t) ]
Onde:
- (x_t \in \mathbb{R}^n): estado oculto (por exemplo, posição/velocidade)
- (y_t \in \mathbb{R}^m): medição (por exemplo, GPS, observação de marco)
- (F_t): matriz de transição de estado
- (H_t): matriz de medição
- (Q_t): covariância do ruído de processo
- (R_t): covariância do ruído de medição
- (u_t): entrada de controle conhecida (opcional)
Como tudo é linear e gaussiano, as posteriores relevantes também são gaussianas. Portanto, um suavizador retorna, para cada (t):
- Média suavizada (\hat{x}{t\mid T} = \mathbb{E}[x_t \mid y{1:T}])
- Covariância suavizada (P_{t\mid T} = \mathrm{Cov}(x_t \mid y_{1:T}))
Alguns suavizadores também calculam covariâncias cruzadas (cross-covariances) (P_{t,t-1\mid T}), úteis para aprender parâmetros do sistema via maximização de expectativa (Expectation-Maximization, EM) ou para certos otimizadores de back-end (back-end optimizers).
Filtragem vs suavização (intuição e consequências)
Filtragem: causal, em tempo real
A filtragem é em linha (online) e causal (causal):
- Usa apenas (y_{1:t})
- Projetada para rastreamento (tracking) e controle com baixa latência
- Não consegue “corrigir o passado”
Isso é ideal para loops de controle robótico em tempo real.
Suavização: acausal, em lote ou com atraso
A suavização é fora de linha ou com atraso:
- Usa todas as medições (y_{1:T})
- Produz uma estimativa de trajetória globalmente consistente
- Pode reduzir retrospectivamente deriva (drift) e ruído de medição
Isso é ideal para:
- Pós-processamento de dados de sensores registrados
- Mapeamento e back-ends de SLAM
- Estimativa de trajetória de alta qualidade para avaliação e geração de dados de treinamento
Uma intuição concreta: se uma medição de GPS no tempo (t=100) indica que você provavelmente estava 5 metros à direita, a suavização pode ajustar não apenas (x_{100}), mas também estados anteriores (x_{90}, x_{80}, \dots) de forma estatisticamente consistente.
Formulações comuns de suavização de Kalman
A suavização de Kalman aparece em algumas variantes padrão, dependendo de que parte da trajetória você quer refinar.
Suavização de intervalo fixo (fixed-interval smoothing) (mais comum)
Estime todos os estados em uma janela completa (t=1\dots T): (p(x_t\mid y_{1:T})).
O suavizador Rauch–Tung–Striebel (RTS) é o algoritmo clássico aqui.
Suavização de atraso fixo (fixed-lag smoothing)
Estime (x_{t-L}) usando medições até o tempo (t): (p(x_{t-L}\mid y_{1:t})).
Isso troca um pequeno atraso (lag (L)) por melhor acurácia, ainda operando de forma quase em linha.
Suavização de ponto fixo (fixed-point smoothing)
Estime um estado específico (x_\tau) (um “ponto”) usando todas as medições (y_{1:T}), frequentemente usado em diagnósticos ou quando apenas um instante particular importa.
Suavizador Rauch–Tung–Striebel (RTS)
O suavizador RTS é amplamente usado porque é simples, eficiente e construído diretamente sobre o Filtro de Kalman.
Ideia-chave: filtro para frente + passagem para trás
Passagem para frente (forward pass): execute um Filtro de Kalman padrão em (t=1\dots T), produzindo:
- Média/covariância filtradas: (\hat{x}{t\mid t}, P{t\mid t})
- Média/covariância previstas: (\hat{x}{t+1\mid t}, P{t+1\mid t})
Passagem para trás (backward pass): refine cada estado usando informação do futuro.
Equações do RTS
Defina o ganho do suavizador (smoother gain): [ G_t = P_{t\mid t} F_{t+1}^\top (P_{t+1\mid t})^{-1} ]
Então a média e a covariância suavizadas são calculadas de trás para frente:
[ \hat{x}{t\mid T} = \hat{x}{t\mid t} + G_t\left(\hat{x}{t+1\mid T} - \hat{x}{t+1\mid t}\right) ]
[ P_{t\mid T} = P_{t\mid t} + G_t\left(P_{t+1\mid T} - P_{t+1\mid t}\right)G_t^\top ]
Inicialização no tempo final: [ \hat{x}{T\mid T} = \hat{x}{T\mid T}, \quad P_{T\mid T} = P_{T\mid T} ]
Por que funciona (visão de alto nível)
A filtragem fornece a melhor estimativa usando dados passados. A passagem para trás adiciona uma correção proporcional ao quanto o estado “suavizado pelo futuro” (x_{t+1}) discorda da previsão de um passo a partir do tempo (t). O ganho do suavizador (G_t) determina quanta informação deve fluir para trás através da dinâmica.
Complexidade
Para dimensão de estado (n) e horizonte (T), o RTS é tipicamente:
- Tempo: (O(T \cdot n^3)) devido a inversões/resoluções de matrizes
- Memória: (O(T \cdot n^2)) para armazenar covariâncias filtradas e previstas
Na prática, você evita inversões explícitas de matrizes resolvendo sistemas lineares (por exemplo, resoluções baseadas em Cholesky) para estabilidade numérica.
Exemplo prático: suavizando uma trajetória 1D com velocidade constante
Imagine rastrear um robô em uma linha com estado (x_t = [p_t, v_t]^\top) (posição e velocidade). Você observa medições ruidosas de posição (y_t \approx p_t).
Dinâmica com passo de tempo (\Delta t): [ F = \begin{bmatrix} 1 & \Delta t\ 0 & 1 \end{bmatrix},\quad H = \begin{bmatrix} 1 & 0 \end{bmatrix} ]
A filtragem estimará (p_t, v_t) em linha, mas, se as medições forem ruidosas, a trajetória filtrada pode tremer. Um suavizador RTS vai “tirar a média” dessa tremulação usando medições futuras para inferir melhor velocidades e posições passadas.
Esboço mínimo em estilo Python (RTS sobre Filtro de Kalman)
import numpy as np
def rts_smoother(x_filt, P_filt, x_pred, P_pred, F_list):
"""
RTS fixed-interval smoother.
Inputs (lists length T):
x_filt[t] = x_{t|t} (n,)
P_filt[t] = P_{t|t} (n,n)
x_pred[t] = x_{t|t-1} (n,) (with x_pred[0] unused or prior)
P_pred[t] = P_{t|t-1} (n,n)
F_list[t] = F_t mapping x_{t-1} -> x_t (so use F_list[t] for step t)
Returns:
x_smooth[t] = x_{t|T}
P_smooth[t] = P_{t|T}
"""
T = len(x_filt)
n = x_filt[0].shape[0]
x_smooth = [None] * T
P_smooth = [None] * T
x_smooth[-1] = x_filt[-1]
P_smooth[-1] = P_filt[-1]
for t in range(T - 2, -1, -1):
F_next = F_list[t + 1]
# G_t = P_{t|t} F_{t+1}^T (P_{t+1|t})^{-1}
# Prefer solve over explicit inverse:
G = P_filt[t] @ F_next.T @ np.linalg.inv(P_pred[t + 1])
x_smooth[t] = x_filt[t] + G @ (x_smooth[t + 1] - x_pred[t + 1])
P_smooth[t] = P_filt[t] + G @ (P_smooth[t + 1] - P_pred[t + 1]) @ G.T
return x_smooth, P_smooth
Em código de produção, substitua inv por uma resolução linear (por exemplo, scipy.linalg.cho_factor/cho_solve) para melhorar a estabilidade.
Suavizadores de dois filtros e outras variantes
Embora o RTS seja o padrão em muitas aplicações, ele não é o único suavizador.
Suavizador de dois filtros (e.g., Bryson–Frazier)
Essa abordagem calcula:
- Um filtro para frente (forward filter) de (1 \to T)
- Um filtro de informação (information filter) para trás de (T \to 1)
Então, combina ambos para obter a posterior suavizada. Métodos de dois filtros podem ser atraentes em certos cenários numéricos ou quando você já trabalha na forma de informação (information form), mas o RTS é mais comumente ensinado e implementado.
Suavizadores de raiz quadrada (square-root smoothers)
Implementações de raiz quadrada (fator de Cholesky) propagam fatores de matriz em vez de covariâncias diretamente, melhorando a estabilidade numérica — importante em problemas de alta dimensionalidade ou mal condicionados.
Suavizadores não lineares
Se a dinâmica ou as medições forem não lineares, você tipicamente usa extensões:
- Suavizadores baseados em EKF (RTS aplicado a linearizações), relacionados ao Filtro de Kalman Estendido (Extended Kalman Filter, EKF)
- Suavizadores unscented (UKS)
- Suavizadores baseados em otimização (linearização iterada), comuns em back-ends de SLAM
Para problemas fortemente não gaussianos, considere suavizadores por partículas relacionados ao Filtro de Partículas (Particle Filter).
Suavização de Kalman em rastreamento e fusão de sensores
Rastreamento (refinamento fora de linha)
Em rastreamento por radar/visão, a suavização é usada para gerar trajetórias de alta qualidade a partir de sequências gravadas:
- Remover tremulação de detecções ruidosas
- Recuperar velocidade/aceleração com mais precisão
- Melhorar detecção de eventos (por exemplo, detectar paradas/curvas)
Um fluxo de trabalho comum:
- Execute um filtro em linha para necessidades em tempo real.
- Armazene os resultados do filtro.
- Execute um suavizador fora de linha para gerar trilhas “finais” para relatórios ou para treinar modelos a jusante.
Fusão de sensores: IMU + GPS (conceitual)
Considere um veículo com:
- IMU de alta taxa (boas restrições de movimento no curto prazo, com deriva)
- GPS de baixa taxa (posição absoluta, ruidoso)
A filtragem combina isso em linha. A suavização melhora a trajetória completa ao permitir que correções de GPS posteriores corrijam a deriva anterior de modo estatisticamente consistente. Isso é particularmente eficaz quando o GPS é intermitente: futuras reaquisições podem “puxar” toda a trajetória de volta ao alinhamento.
Como a suavização difere da filtragem em back-ends de SLAM
Em SLAM, você frequentemente ouve “SLAM baseado em filtro” vs “SLAM baseado em suavização”.
SLAM baseado em filtro (estado em linha)
Um filtro mantém uma crença sobre o estado atual (e às vezes um mapa) e atualiza conforme novas medições chegam. Isso está conceitualmente alinhado com (p(x_t \mid y_{1:t})).
SLAM baseado em suavização (otimização de trajetória + mapa)
Back-ends modernos de SLAM frequentemente resolvem um problema de estimação em lote (batch) ou em janela deslizante (sliding-window) sobre muitos estados de uma vez — conceitualmente alinhado com a suavização (p(x_{1:T} \mid y_{1:T})) ou com a estimação MAP (MAP estimation) de toda a trajetória.
Isso está intimamente conectado a:
- Formulações por grafo de fatores (factor graph)
- Solucionadores de mínimos quadrados esparsos (sparse least-squares solvers)
- Otimização no estilo “ajuste de feixe (bundle adjustment)” em SLAM visual
Se você quiser um enquadramento probabilístico: a suavização de Kalman é a solução gaussiana em forma fechada para um grafo de fatores com estrutura em cadeia. Back-ends de SLAM generalizam essa ideia para modelos não lineares e estruturas de grafo mais complexas. Veja Localização e Mapeamento Simultâneos (SLAM) e Grafos de Fatores.
Janela deslizante = suavização de atraso fixo na prática
Muitos sistemas de SLAM em tempo real não suavizam todo o histórico (caro demais). Em vez disso, eles usam um suavizador de atraso fixo:
- Mantêm uma janela das (N) poses mais recentes
- Reotimizam essas poses conforme novas restrições entram
- Marginalizam estados mais antigos para manter o custo computacional limitado
Isso é essencialmente o análogo não linear, baseado em grafos, da suavização de Kalman com atraso fixo.
Quando (e quando não) usar um suavizador de Kalman
Boa adequação
Use suavização de Kalman quando:
- O modelo é linear (ou bem aproximado como linear)
- O ruído é aproximadamente gaussiano
- Você quer trajetórias de melhor estimativa (pós-processamento, mapeamento, analytics)
- A latência é aceitável (fora de linha ou com atraso)
Limitações e modos de falha
- Não linearidade: o RTS assume dinâmica/medições lineares. Suavizadores baseados em linearização podem ter dificuldades com não linearidade forte ou más suposições iniciais.
- Ruído não gaussiano / outliers: algumas medições ruins podem distorcer toda a trajetória suavizada. Alternativas robustas incluem modelos de medição com caudas pesadas ou rejeição de outliers.
- Incompatibilidade de modelo: (Q) e (R) incorretos podem levar a super-suavização (confiança excessiva) ou sub-suavização.
Dicas práticas para implementação
- Evite inversões explícitas: compute (G_t) via resolução de sistemas lineares para estabilidade numérica.
- Armazene o que você precisa: o RTS requer covariâncias filtradas e previstas (e tipicamente médias) em cada passo de tempo.
- Ajuste (Q) e (R): a qualidade da suavização depende fortemente de modelos de ruído corretos. Se (Q) for pequeno demais, a trajetória fica irrealisticamente “rígida”.
- Considere formas de raiz quadrada em alta dimensionalidade ou quando as covariâncias se tornam mal condicionadas.
- Use suavização de atraso fixo para sistemas em tempo real que precisam de acurácia melhor do que a de um filtro sem o custo total de um lote.
Resumo
Métodos de suavização de Kalman estendem a filtragem de Kalman ao estimar a trajetória inteira do estado usando todas as medições, produzindo (p(x_t\mid y_{1:T})) em vez de (p(x_t\mid y_{1:t})). O suavizador RTS é o suavizador de intervalo fixo mais comum: execute um Filtro de Kalman padrão para frente e, em seguida, faça uma recursão para trás que propaga informação de medições futuras de volta no tempo.
Em robótica, a suavização é central para estimativa de trajetória de alta qualidade e sustenta a intuição por trás de back-ends de SLAM: combinar muitas restrições ao longo do tempo para produzir uma estimativa globalmente consistente. Para sistemas não lineares, a mesma ideia de suavização aparece via suavizadores baseados em EKF/UKF ou por otimização não linear em grafos de fatores.