Main Content

Cette page a été traduite par traduction automatique. Cliquez ici pour voir la dernière version en anglais.

moyenne

Rotation moyenne des quaternions

Depuis R2019b

Description

exemple

quatAverage = meanrot(quat) renvoie la rotation moyenne des éléments de quat le long de la première dimension du tableau dont la taille n'est pas égale à 1.

  • Si quat est un vecteur, meanrot(quat) renvoie la rotation moyenne des éléments.

  • Si quat est une matrice, meanrot(quat) renvoie un vecteur ligne contenant la rotation moyenne de chaque colonne.

  • Si quat est un tableau multidimensionnel, alors mearot(quat) opère le long de la première dimension du tableau dont la taille n'est pas égale à 1, traitant les éléments comme des vecteurs. Cette dimension devient 1 tandis que les tailles de toutes les autres dimensions restent les mêmes.

La fonction meanrot normalise les quaternions d'entrée, quat, avant de calculer la moyenne.

quatAverage = meanrot(quat,dim) renvoie la rotation moyenne le long de la dimension dim. Par exemple, si quat est une matrice, alors meanrot(quat,2) est un vecteur colonne contenant la moyenne de chaque ligne.

quatAverage = meanrot(___,nanflag) spécifie s'il faut inclure ou omettre les valeurs NaN du calcul pour l'une des syntaxes précédentes. meanrot(quat,"includenan") inclut toutes les valeurs NaN dans le calcul tandis que mean(quat,"omitnan") les ignore.

Exemples

réduire tout

Créez une matrice de quaternions correspondant à trois ensembles d'angles d'Euler.

eulerAngles = [40 20 10; ...
               50 10 5; ...
               45 70 1];

quat = quaternion(eulerAngles,"eulerd","ZYX","frame");

Déterminez la rotation moyenne représentée par les quaternions. Convertissez la rotation moyenne en angles d'Euler en degrés pour plus de lisibilité.

quatAverage = meanrot(quat)
quatAverage = quaternion
      0.88863 - 0.062598i +  0.27822j +  0.35918k

eulerAverage = eulerd(quatAverage,"ZYX","frame")
eulerAverage = 1×3

   45.7876   32.6452    6.0407

Utilisez meanrot sur une séquence de quaternions pour faire la moyenne du bruit additif.

Créez un vecteur de quaternions 1e6 dont la distance, telle que définie par la fonction dist , du quaternion(1,0,0,0) est normalement distribuée. Tracez les angles d'Euler correspondant au vecteur quaternion bruyant.

nrows = 1e6;
ax = 2*rand(nrows,3) - 1;   
ax = ax./sqrt(sum(ax.^2,2));
ang = 0.5*randn(size(ax,1),1);
q = quaternion(ax.*ang ,"rotvec");

noisyEulerAngles = eulerd(q,"ZYX","frame");

figure(1)

subplot(3,1,1)
plot(noisyEulerAngles(:,1))
title("Z-Axis")
ylabel("Rotation (degrees)")
hold on

subplot(3,1,2)
plot(noisyEulerAngles(:,2))
title("Y-Axis")
ylabel("Rotation (degrees)")
hold on

subplot(3,1,3)
plot(noisyEulerAngles(:,3))
title("X-Axis")
ylabel("Rotation (degrees)")
hold on

Figure contains 3 axes objects. Axes object 1 with title Z-Axis, ylabel Rotation (degrees) contains an object of type line. Axes object 2 with title Y-Axis, ylabel Rotation (degrees) contains an object of type line. Axes object 3 with title X-Axis, ylabel Rotation (degrees) contains an object of type line.

Utilisez meanrot pour déterminer le quaternion moyen étant donné le vecteur des quaternions. Convertissez en angles d'Euler et tracez les résultats.

qAverage = meanrot(q);

qAverageInEulerAngles = eulerd(qAverage,"ZYX","frame");

figure(1)

subplot(3,1,1)
plot(ones(nrows,1)*qAverageInEulerAngles(:,1))
title("Z-Axis")

subplot(3,1,2)
plot(ones(nrows,1)*qAverageInEulerAngles(:,2))
title("Y-Axis")

subplot(3,1,3)
plot(ones(nrows,1)*qAverageInEulerAngles(:,3))
title("X-Axis")

Figure contains 3 axes objects. Axes object 1 with title Z-Axis, ylabel Rotation (degrees) contains 2 objects of type line. Axes object 2 with title Y-Axis, ylabel Rotation (degrees) contains 2 objects of type line. Axes object 3 with title X-Axis, ylabel Rotation (degrees) contains 2 objects of type line.

L'algorithme meanrot

La fonction meanrot génère un quaternion qui minimise la norme de Frobenius au carré de la différence entre les matrices de rotation. Considérons deux quaternions :

  • q0 ne représente aucune rotation.

  • q90 représente une rotation de 90 degrés autour de l'axe  x .

q0 = quaternion([0 0 0],"eulerd","ZYX","frame");
q90 = quaternion([0 0 90],"eulerd","ZYX","frame");

Créez un balayage quaternion, qSweep, qui représente des rotations de 0 à 180 degrés autour de l'axe  x .

eulerSweep = (0:1:180)';
qSweep = quaternion([zeros(numel(eulerSweep),2),eulerSweep], ...
    "eulerd","ZYX","frame");

Convertissez q0, q90 et qSweep en matrices de rotation. Dans une boucle, calculez la métrique à minimiser pour chaque membre du balayage quaternion. Tracez les résultats et renvoyez la valeur du balayage d'Euler qui correspond au minimum de la métrique.

r0     = rotmat(q0,"frame");
r90    = rotmat(q90,"frame");
rSweep = rotmat(qSweep,"frame");

metricToMinimize = zeros(size(rSweep,3),1);
for i = 1:numel(qSweep)
    metricToMinimize(i) = norm((rSweep(:,:,i) - r0),"fro").^2 + ...
                          norm((rSweep(:,:,i) - r90),"fro").^2;
end

plot(eulerSweep,metricToMinimize)
xlabel("Euler Sweep (degrees)")
ylabel("Metric to Minimize")

Figure contains an axes object. The axes object with xlabel Euler Sweep (degrees), ylabel Metric to Minimize contains an object of type line.

[~,eulerIndex] = min(metricToMinimize);
eulerSweep(eulerIndex)
ans = 45

Le minimum de la métrique correspond au balayage d'angle d'Euler à 45 degrés. Autrement dit, meanrot définit la moyenne entre quaterion([0 0 0],"ZYX","frame") et quaternion([0 0 90],"ZYX","frame") comme quaternion([0 0 45],"ZYX","frame"). Appelez meanrot avec q0 et q90 pour vérifier le même résultat.

eulerd(meanrot([q0,q90]),"ZYX","frame")
ans = 1×3

         0         0   45.0000

Limites

La métrique utilisée par meanrot pour déterminer la rotation moyenne n'est pas unique pour les quaternions très éloignés les uns des autres. Répétez l’expérience ci-dessus pour les quaternions séparés de 180 degrés.

q180 = quaternion([0 0 180],"eulerd","ZYX","frame");
r180 = rotmat(q180,"frame");

for i = 1:numel(qSweep)
    metricToMinimize(i) = norm((rSweep(:,:,i) - r0),"fro").^2 + ...
                          norm((rSweep(:,:,i) - r180),"fro").^2;
end

plot(eulerSweep,metricToMinimize)
xlabel("Euler Sweep (degrees)")
ylabel("Metric to Minimize")

Figure contains an axes object. The axes object with xlabel Euler Sweep (degrees), ylabel Metric to Minimize contains an object of type line.

[~,eulerIndex] = min(metricToMinimize);
eulerSweep(eulerIndex)
ans = 159

Les moyennes des quaternions sont généralement calculées pour des rotations proches les unes des autres, ce qui rend le cas limite présenté dans cet exemple peu probable dans les applications du monde réel. Pour faire la moyenne de deux quaternions très éloignés l'un de l'autre, utilisez la fonction slerp . Répétez l'expérience en utilisant slerp et vérifiez que la moyenne des quaternions renvoyée est plus intuitive pour les grandes distances.

qMean = slerp(q0,q180,0.5);
q0_q180 = eulerd(qMean,"ZYX","frame")
q0_q180 = 1×3

         0         0   90.0000

Arguments d'entrée

réduire tout

Quaternion pour lequel calculer la moyenne, spécifié comme un objet quaternion ou un tableau d'objets quaternion de n'importe quelle dimensionnalité.

Dimension sur laquelle opérer, spécifiée sous la forme d'un scalaire entier positif. Si aucune valeur n'est spécifiée, la valeur par défaut est la première dimension du tableau dont la taille n'est pas égale à 1.

La dimension dim indique la dimension dont la longueur se réduit à 1. Le size(quatAverage,dim) est 1, tandis que les tailles de toutes les autres dimensions restent les mêmes.

Types de données : double | single

Condition NaN , spécifiée comme l'une de ces valeurs :

  • "includenan" –– Inclut les valeurs NaN lors du calcul de la rotation moyenne, ce qui donne NaN.

  • "omitnan" –– Ignorer toutes les valeurs NaN dans l’entrée.

Types de données : char | string

Arguments de sortie

réduire tout

Rotation moyenne du quaternion, renvoyée sous la forme d'un objet quaternion ou d'un tableau d'objets quaternion .

Algorithmes

meanrot détermine une moyenne de quaternion, q¯, selon [1]. q¯ est le quaternion qui minimise la norme de Frobenius au carré de la différence entre les matrices de rotation :

q¯=argminqS3i=1nA(q)A(qi)F2

Références

[1] Markley, F. Landis, Yang Chen, John Lucas Crassidis, and Yaakov Oshman. "Average Quaternions." Journal of Guidance, Control, and Dynamics. Vol. 30, Issue 4, 2007, pp. 1193-1197.

Capacités étendues

Génération de code C/C++
Générez du code C et C++ avec MATLAB® Coder™.

Historique des versions

Introduit dans R2019b