175 lines
4.5 KiB
Matlab
Executable File
175 lines
4.5 KiB
Matlab
Executable File
function [DNS,DEO,Dz,becc,roll,imba,q,qy]=QuaternioniASE(axb,ayb,azb,mxb,myb,mzb,SP,MEMS,FileName)
|
|
|
|
% OPERAZIONI PRELIMINARI
|
|
% calcola la norma dell'accelerazione e del campo magnetico
|
|
Na = (axb^2+ayb^2+azb^2)^0.5;
|
|
Nm = (mxb^2+myb^2+mzb^2)^0.5;
|
|
% normalizzo l'accelerazione
|
|
axbN = axb/Na;
|
|
aybN = ayb/Na;
|
|
azbN = azb/Na;
|
|
% normalizzo il campo magnetico
|
|
mxbN = mxb/Nm;
|
|
mybN = myb/Nm;
|
|
mzbN = mzb/Nm;
|
|
|
|
if MEMS == 1 % Correggo i segni degli assi
|
|
% correggo la direzione degli assi del sistema di coordinate
|
|
% aggiornato al 15 febbraio 2016
|
|
axsN = axbN;
|
|
aysN = aybN;
|
|
azsN = -azbN;
|
|
% anche per il campo magnetico...
|
|
mxsN = -mxbN;
|
|
mysN = -mybN;
|
|
mzsN = mzbN;
|
|
elseif MEMS == 2
|
|
% correggo la direzione degli assi del sistema di coordinate
|
|
% aggiornato al 09 febbraio 2017
|
|
axsN = axbN;
|
|
aysN = aybN;
|
|
azsN = -azbN;
|
|
% anche per il campo magnetico...
|
|
mxsN = -mxbN;
|
|
mysN = -mybN;
|
|
mzsN = mzbN;
|
|
elseif MEMS == 3
|
|
% correggo la direzione degli assi del sistema di coordinate
|
|
% aggiornato al 10 ottobre 2022
|
|
axsN = axbN;
|
|
aysN = aybN;
|
|
azsN = azbN;
|
|
% anche per il campo magnetico...
|
|
mxsN = mybN;
|
|
mysN = mxbN;
|
|
mzsN = -mzbN;
|
|
end
|
|
|
|
% trovo i vettori dei campi gravitazionale e magnetico
|
|
VaN = [axsN aysN azsN];
|
|
VmN = [mxsN mysN mzsN];
|
|
|
|
% CONTI SECONDO YUN
|
|
[qy,~,~] = fqa(VaN',VmN');
|
|
qy = qy';
|
|
|
|
% determino i relativi quaternioni
|
|
qaN = [0 VaN];
|
|
qmN = [0 VmN];
|
|
|
|
% calcolo il coseno del beccheggio
|
|
% gamma = acos(azsN); gamma non viene mai usato
|
|
COSteta = (1-axsN^2)^0.5;
|
|
|
|
% VERIFICA DELLA SINGOLARITA'
|
|
% impongo un epsilon piccolo a piacere
|
|
epsilon = 0.1;
|
|
if COSteta <= epsilon
|
|
% 20 deg espresso in radianti
|
|
alpha = 0.3491;
|
|
else
|
|
alpha = 0;
|
|
end
|
|
|
|
SENalphamezzi = sign(sin(alpha))*((1-cos(alpha))/2)^0.5;
|
|
COSalphamezzi = ((1+cos(alpha))/2)^0.5;
|
|
|
|
%% calcolo il quaternione qalpha e il suo coniugato
|
|
qalpha = [COSalphamezzi 0 SENalphamezzi 0];
|
|
qalphaC = quatconj(qalpha);
|
|
|
|
% modifico il vettore accelerazione...
|
|
qacc = quatmultiply(qalpha,qaN);
|
|
qacc = quatmultiply(qacc,qalphaC);
|
|
|
|
% ...e quello campo magnetico
|
|
qmag = quatmultiply(qalpha,qmN);
|
|
qmag = quatmultiply(qmag,qalphaC);
|
|
|
|
%% CALCOLA IL QUATERNIONE ELEVAZIONE
|
|
% NB: il valore di COSteta sarà riscritto
|
|
SENteta = qacc(2);
|
|
COSteta = (1-SENteta^2)^0.5;
|
|
SENtetamezzi = sign(SENteta)*((1-COSteta)/2)^0.5;
|
|
COStetamezzi = ((1+COSteta)/2)^0.5;
|
|
qe = [COStetamezzi 0 SENtetamezzi 0];
|
|
|
|
%% CALCOLA IL QUATERNIONE ROLLIO
|
|
SENphi = -qacc(3)/COSteta;
|
|
COSphi = -qacc(4)/COSteta;
|
|
% caso in cui l'asse x sia orientato verticalmente
|
|
if COSteta == 0
|
|
SENphi = 0;
|
|
COSphi = 1;
|
|
end
|
|
% determinazione degli elementi di qr
|
|
if COSphi == -1
|
|
SENphimezzi = 1*((1-COSphi)/2)^0.5;
|
|
COSphimezzi = 0;
|
|
else
|
|
SENphimezzi = sign(SENphi)*((1-COSphi)/2)^0.5;
|
|
COSphimezzi = ((1+COSphi)/2)^0.5;
|
|
if isreal(SENphimezzi)
|
|
elseif imag(SENphimezzi)<0.001
|
|
SENphimezzi=0;
|
|
text = 'SENphi/2 corrected';
|
|
fileID = fopen(FileName,'a');
|
|
fmt = '%s \r';
|
|
fprintf(fileID,fmt,text);
|
|
fclose(fileID);
|
|
end
|
|
end
|
|
% scrittura di qr
|
|
qr = [COSphimezzi SENphimezzi 0 0];
|
|
|
|
%% CALCOLA IL QUATERNIONE AZIMUTALE
|
|
% Campo magnetico nel sistema di coordinate Earth
|
|
qaus = quatmultiply(qe,qr);
|
|
qauC = quatconj(qaus);
|
|
qEm = quatmultiply(qaus,qmag);
|
|
qEm = quatmultiply(qEm,qauC);
|
|
% Campo magnetico di riferimento
|
|
Nx = 1;
|
|
Ny = 0;
|
|
% Normalizzazione delle componenti orizzontali del campo magnetico misurato
|
|
mxmearot = qEm(2);
|
|
mymearot = qEm(3);
|
|
Mx = (1/(mxmearot^2+mymearot^2)^0.5)*mxmearot;
|
|
My = (1/(mxmearot^2+mymearot^2)^0.5)*mymearot;
|
|
|
|
% determino coseno e seno dell'angolo di imbardata
|
|
COSpsi = Mx*Nx+My*Ny;
|
|
SENpsi = -My*Nx+Mx*Ny;
|
|
% determinazione degli elementi di qa
|
|
SENpsimezzi = sign(SENpsi)*((1-COSpsi)/2)^0.5;
|
|
COSpsimezzi = ((1+COSpsi)/2)^0.5;
|
|
% scrittura di qa
|
|
qa = [COSpsimezzi 0 0 SENpsimezzi];
|
|
|
|
% QUATERNIONE FINALE
|
|
q = quatmultiply(qa,qe);
|
|
q = quatmultiply(q,qr);
|
|
qINV = [q(:,1) q(:,2).*-1 q(:,3).*-1 q(:,4).*-1];
|
|
|
|
% RIPERCORRE AL CONTRARIO LA ROTAZIONE IMPOSTA PER EVITARE LA SINGOLARITA'
|
|
q = quatmultiply(q,qalpha);
|
|
Q0 = q(1);
|
|
Q1 = q(2);
|
|
Q2 = q(3);
|
|
Q3 = q(4);
|
|
|
|
% CALCOLO GLI ANGOLI DAI QUATERNIONI
|
|
roll = atan2(2*(Q0*Q1+Q2*Q3),(1-2*(Q1^2+Q2^2)));
|
|
becc = asin(2*(Q0*Q2-Q3*Q1));
|
|
imba = atan2(2*(Q0*Q3+Q1*Q2),(1-2*(Q2^2+Q3^2)));
|
|
|
|
% Calcolo degli spostamenti relativi al nodo
|
|
qVett = [0 0 0 SP];
|
|
qVettR = quatmultiply(q,qVett);
|
|
qVettR = quatmultiply(qVettR,qINV);
|
|
|
|
DNS = qVettR(2);
|
|
DEO = qVettR(3);
|
|
Dz = qVettR(4);
|
|
|
|
end |