terça-feira, 3 de novembro de 2026

Modelo não linear F16

Untitled
O modelo não-linear encontra-se disponível no livro do Stevens e Lewis, Airfract Control and Simulation. Possuo as 2ª e 3ª edições do livro, e não há variação no código existente entre elas. O código disponibilizado no livro para a dinâmica não linear do F16 está escrito em Fortran e para facilitar um pouco a vida eu a transcrevi para o Matlab. Hoje em dia com a IA você consegue fazer isso num tapa, mas a versão por mim programada pode ser encontrada no meu github por meio deste link. O modelo utiliza o referencial NED (North-East-Down). Você pode, por exemplo, utilizar o ENU (East-North-Up), caso deseje, por questões de opção de referencial, mas isso não consta no programação realizada em Matlab.
Há de convir que eu procurei tentar separar o que pega no sistema de modelagem matemática. Tentei separar em subsistemas de modo a deixar a programação separada em massa, momentos de inercia, coeficientes aerodinâmicos, influência de momento rotor (turbina, por exemplo), entre outros, e deixar as equações de força, momento, cinemática e dinâmica um pouco mais direto para quem deseja entender o passo a passo da modelagem.
A modelagem considera a terra plana, mas dá para realizar algumas adaptações nesse código de modo a considerar a terra esférica (e as influências de Corioli e força centrífuga) na modelagem. Isso é um preciosismo, mas para a tarefa de obtenção de malhas de controle por agora não tem muuuuito ganho.
Considerações de carater geral:
  • As condicionantes de massa em uma aeronave, drone com propulsão sólida/líquida varia com o passar do tempo, pelo consumo do agente propulsor. No caso da dinâmica F16 modelado e programado no livro do Lewis, essa massa não varia. No seu programa mais refinado, para a dinâmica que você irá desenvolver de modo mais profissional, leve em consideração as variações de massa total do seu sistema. Se seu sistema possui baterias elétricas, essa variação não tem fundamentação, pois não há variação mássica e apenas consumo de energia;
  • Equivalentemente, há alteração de momento de inércia do seu sistema com variação da condição de voo (flaps baixados, variações devido às deflexões de empenas, devido à própria variação de massa, alijamento de algum partes não necessárias mais durante o voo). Isso deve ser levado em consideração na sua abordagem quando da simulação para o caso mais geral;
  • Além disso, em se considerando a terra esférica, deve-se considerar variações no parâmetro de gravidade com a latitude, como mesmo abordado no livro do Lewis;
  • Os parâmetros aerodinâmicos (tabelas aerodinâmicas) e as de desempenho do turbina do F16 vêm diretamente das tabelas presentes no livro do Lewis. No caso de sua simulação de aeronave, drone você tem que derivar essas tabelas aerodinâmicas por CFD, análise numérica ou qualquer outro tipo aplicável. Aqui eu não fiz juízo de valor sobre se elas estão corretas ou se os seus parâmetros possuem equivalência com o mundo real. Apenas as usei;
  • A equação para o F16 já foi construída tendo por base o parâmetro t, que num caso geral toma por referência o consumo ou alguma máquina de estados do sistema em condição após certo instante de tempo, por exemplo.
Existem alguns códigos disponíveis na internet, até com novas tabelas aerodinâmicas. Existe também alguns trabalhos, livros e afins que consideram o modelo do F16 uma base para desenvolvimento e estudos na área de controle, otimização numérica, simulação de dinâmica etc. Esse é o código, como dito anteriormente, escrito por mim, e se tiver erro, faz parte. Me aponte onde, por favor, que eu ajusto tão logo ele seja a mim chegado.
O modelo foi escrito basicamente seguindo as diretrizes disponíveis no livro. O código a seguir irá esclarecer as etapas do desenvolvimento. É possível observar que existem alguns comentários no código, que fazem referência direta à equação tal do livro, disponível na página tal. Segue o código.
Figura 1: Num contexto mais geral, a sua função matemática irá cuspir uma massa, peso e matriz J, referente ao momento de inércia do sistema, condizente com a condição de voo em que o sistema se encontra. No fim das contas, é um parâmetro dependente do parâmetro t.
Figura 2: Parâmetros específicos da aeronave F16 apresentados no livro do Lewis. Num sistema complexo, esses parâmetros podem, e com certeza, devem variar.
Figura 3: Estado instantâneo do sistema para as variáveis de estado e controle.
Figura 4: Análise do sistema num pré-cálculo de variáveis que serão empregadas no transcorrer do código.
Figura 5: Modelo aerodinâmico do sistema na condição ISA + 0 apresentado no livro do Lewis. Para um modelo mais completo, é interessante realizar a inserção do parâmetro de temperatura local para adaptar para as demais ISA's.
Figura 6: Modelo propulsivo do F16 apresentado pelo Lewis. Aqui o buraco é mais embaixo num sistema complexo, em se considerando rendimento, momento angular induzido entre outros parâmetros. No livro do Lewis está tudo basicamente em formato de tabela.
Figura 7: Etapa de processamento dos parâmetros aerodinâmicos. Em sistemas não lineares é comum encontrar tabelas e análise nesse formato, mais ou menos complexas, e levando em considerações as diversas fases de uma aeronave, drone em seus mais diversos estágios de voo.
Figura 8: Equações de Força do sistema.Ela está diferente daquela apresentada no livro do Lewis de modo a deixar o desenvolvimento mais direto com as equações disponíveis.
Figura 9: Equações de cinemática. Aqui a coisa não muda muito do que já existe. Tem que se levar em considerações a possibilidade de divisão por zero em alguns termos. No futuro, interessante modificar para quaternions para evitar problemas numéricos.
Figura 10: Equações de momento. Observe a consideração de momento induzida pelos motores. No caso mais geral, há também a dinâmica do momento de inércia , que será derivado a posteriori em outro post com mais detalhes de como o fazer matematicamente.
Figura 11: Equações de navegação, tendo por referência o padrão NED. Fica a critério do cliente aqui apresentar os parâmetros derivados.
Figura 12: Saídas de interesse, a critério do desenvolvedor e das malhas as quais ele deseja obter para o desempenho do seu sistema.
Bom, esse é omodelo simplificado do F16 disponível no livro do Lewis. É possível, por exemplo, criar um s-function no Simulink ou mesmo derivar, bloco a bloco, para no próprio Simulink, para deixar a coisa mais impessoal. O código gera os parâmetros apresentados no livro, quando da verificação de modelo. Há um pequeno "erro" para a variável , desprezíveis quando da análise de um contexto mais geral e de testes para aprendizado do problema. Vi alguns códigos e coisas do tipo em C++ na internet e também em Matlab. Quero deixar disponível no blog apenas para consulta futura minha, caso se faça necessário.
Ah, para entender melhor as funções que são chamadas durante o programa, clica no link, deixa de preguiça e olha dentro das pastas para você entender o que foi feito. É isso aí. Vlw.

terça-feira, 25 de novembro de 2025

Calibração de girômetros numa IMU

1. X+
Modelo matemático para girômetro
Esse modelo eu peguei no livro do Noureldin (Fundamentals of Inertial Navigation, Satellite-based, Positioning ant their Integration, Springer, 2013.), presente na seção 4.11.
em que:
: é o valor medido diretamente pelo girômetro, ou seja, o que a gente ler do hardware;
é o valor verdadeiro a ser empregado no desenvolvimento das equações de mecanização;
: é a matriz que condensa os fatores de escala linear;
: é a matriz que representa a não ortogonalidade da tríade de girômetro; e
: é o vetor que representa os erros dos ruídos dos sensores.
A seguir, as matrizes e seus termos:
e
OBS: o subscrito "m" nos termos de dizem respeito à medida realizada (measurement).
Desenvolvendo a equação acima, em seus termos, tem-se que:
Que desenvolvidas, termo a termo, fornecem os seguintes resultados para cada um dos eixos.
DIferentemente da calibração do acelerômetro, a ideia aqui é posicionar o sistema a ser calibrado alinhado ao eixo de referência e incidir sobre ele uma rotação constante na plataforma. No caso, eu desenvolvi um sistema de calibração que possibilita a rotação do sistema na velocidade de 60º/s. Essa, portanto, será a referência de rotação. Para deixar o sistema adaptável à qualquer velocidade de seu interesse, mas de preferência que não seja nula. Para fins de código, será adotado o parâmetro .

1. X+

Posicionando o girômetro com o eixo X com a direção para cima, é só. Nessa condição, a medida de referência para a calibração deve ser + para o eixo X. Desse modo, as equações ficam representadas da seguinte forma:
Nessa posição, com o sistema fixo e sem nenhuma parturbação, coleta-se vários dados dos sensores e tira-se a média de cada um deles (basicamente para tentar eliminar os erros de medida):
A ideia agora é guardar essas equações e tentar encontrar similares para os demais eixos e orientações possíveis.

2. X-

Após a coleta de bastante dados, tira-se a média das medidas (para basicamente eliminar o parâmetro de erro):

3. Y+

De modo similar ao que fora realizado para o eixo X, tem-se que:
Após bastante dados, tira-se a média (para basicamente eliminar o parâmetro de erro):

4. Y-

Após bastante dados, tira-se a média (para basicamente eliminar o parâmetro de erro):

5. Z+

De modo similar ao que fora realizado para os eixos X e Y, tem-se que:
Após bastante dados, tira-se a média (para basicamente eliminar o parâmetro de erro):

6. Z-

Após bastante dados, tira-se a média (para basicamente eliminar o parâmetro de erro):
Com base nesses parâmetros e médias do sistema, a ideia é tentar organizar os parâmetros em matrizes e encontrar a solução que melhor se acomoda ao sistema. Para tal a gente realizará o seguinte algoritmo.
  1. Coloca o IMU fixo com o eixo X apontado para cima (X up) durante um tempo considerável (>10min, por exemplo). Salva o resultado das medidas de aceleração em um arquivo do tipo "gyro_x_up.txt".
  2. Coloca o IMU fixo com o eixo X apontado para baixo (X down) durante um tempo considerável (>10min, por exemplo). Salva o resultado das medidas de aceleração em um arquivo do tipo "giro_x_down.txt".
  3. Coloca o IMU fixo com o eixo Y apontado para cima (Y up) durante um tempo considerável (>10min, por exemplo). Salva o resultado das medidas de aceleração em um arquivo do tipo "gyro_y_up.txt".
  4. Coloca o IMU fixo com o eixo Y apontado para baixo (Y down) durante um tempo considerável (>10min, por exemplo). Salva o resultado das medidas de aceleração em um arquivo do tipo "gyro_y_down.txt".
  5. Coloca o IMU fixo com o eixo Z apontado para cima (Z up) durante um tempo considerável (>10min, por exemplo). Salva o resultado das medidas de aceleração em um arquivo do tipo "gyro_z_up.txt".
  6. Coloca o IMU fixo com o eixo Z apontado para baixo (Z down) durante um tempo considerável (>10min, por exemplo). Salva o resultado das medidas de aceleração em um arquivo do tipo "gyro_z_down.txt".
  7. Carrega todos os dados num software de mais alto nível (Matlab, Python) ou mesmo em C/C++ (fica a seu critério) para separação das médias dos sistemas.
Após a coleta de dados do sistema, a ideia é tentar organizar os parâmetros de forma que a gente consiga buscar uma solução ótima para todos os parâmetros do sistema (ou seja, a de menor custo). A forma encontrada de fazer isso foi organizar os dados no formato matricial:
em que é a matriz que condensa as medidas de médias das velocidades angulares encontradas para cada eixo, X representa a matriz que desejamos encontrar. Em específico, para o meu caso, fiz a seguinte organização e sequência:
1º) Reescrever todas as equações acima apresentadas. Todas as variáveis a serem determinadas estão em negrito.
São ao todo 12 parâmetros a serem determinados, todos eles organizandos na variável X a seguir (você pode escolher a sua própria organização):
2º) Rearranjar as variáveis acima, de modo a separar as variáveis a serem determinadas, tem-se que:
O que equivale a escrevermos em produtos de matrizes:
% ===========================================================
% Definição da variável de velocidade angular de referência
% ===========================================================
omega_rot = 60; % em º/s.
 
% Matriz de medidas dos girômetros.
Yg = [omega_x_x_up - 2*omega_rot;
omega_y_x_up;
omega_z_x_up;
omega_x_x_down + 2*omega_rot;
omega_y_x_down;
omega_z_x_down;
omega_x_y_up;
omega_y_y_up - 2*omega_rot;
omega_z_y_up;
omega_x_y_down;
omega_y_y_down + 2*omega_rot;
omega_z_y_down;
omega_x_z_up;
omega_y_z_up;
omega_z_z_up - 2*omega_rot;
omega_x_z_down;
omega_y_z_down;
omega_z_z_down + 2*omega_rot;];
 
% Matriz de construção para os girômetros.
A = [ 1, 0, 0, w_rot, 0, 0, 0, 0, 0, 0, 0, 0;
0, 1, 0, 0, 0, 0, 0, 0, w_rot, 0, 0, 0;
0, 0, 1, 0, 0, 0, 0, 0, 0, 0, w_rot, 0;
1, 0, 0, -w_rot, 0, 0, 0, 0, 0, 0, 0, 0;
0, 1, 0, 0, 0, 0, 0, 0, -w_rot, 0, 0, 0;
0, 0, 1, 0, 0, 0, 0, 0, 0, 0, -w_rot, 0;
1, 0, 0, 0, 0, 0, w_rot, 0, 0, 0, 0, 0;
0, 1, 0, 0, w_rot, 0, 0, 0, 0, 0, 0, 0;
0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, w_rot;
1, 0, 0, 0, 0, 0, -w_rot, 0, 0, 0, 0, 0;
0, 1, 0, 0, -w_rot, 0, 0, 0, 0, 0, 0, 0;
0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, -w_rot;
1, 0, 0, 0, 0, 0, 0, w_rot, 0, 0, 0, 0;
0, 1, 0, 0, 0, 0, 0, 0, 0, w_rot, 0, 0;
0, 0, 1, 0, 0, w_rot, 0, 0, 0, 0, 0, 0;
1, 0, 0, 0, 0, 0, 0, -w_rot, 0, 0, 0, 0;
0, 1, 0, 0, 0, 0, 0, 0, 0, -w_rot, 0, 0;
0, 0, 1, 0, 0, -w_rot, 0, 0, 0, 0, 0, 0;];
 
%%% Solução da equação.
Y = inv(A'*A) * A' * Yg;
 
%%% Separação da solução.
b = [Y(1); Y(2); Y(3)] % BIAS
S = [Y(4), 0, 0;
0, Y(5), 0;
0, 0, Y(6)]
N = [ 1, Y( 7), Y( 8);
Y( 9), 1, Y(10);
Y(11), Y(12), 1]
 
%%% Cálculo do sistema (matriz inversa).
M = inv(N + S + eye(3));
É basicamente isso que a gente faz na tarefa de calibração dos acelerômetros, com a determinação dos 12 parâmetros possíveis nessa caracterização do sistema.
Nesse ponto o que resta é simplesmente a obtenção dos parâmetros do giro dado que as variáveis de calibração já foram determinadas. Isso pode ser feito por meio de:
Como os parâmetros das matrizes a seguir são determinados offline, a gente pode simplesmente realizar a obtenção dos parâmetros de forma direta.