Comprendre la méthode d'analyse de variance Allan de manière simple et facile

1. Documents de référence

Comprendre le filtrage de Kalman en termes simples

2. Méthode d'analyse de la variance Allan

1. Introduction

Les indicateurs d'erreur traditionnels utilisent souvent l'erreur moyenne (reflétant si la séquence d'erreurs entière présente un biais macro), l'écart type (reflétant la fluctuation de la séquence d'erreurs entière) et la racine quadratique moyenne (RMS), qui peuvent être considérés comme une mesure du biais macro. et fluctuation. complet). Comme le montre la figure ci-dessous, ils reflètent tous la séquence d'erreursSituation globaleL'indicateur contient diverses composantes de changements rapides à court terme et de changements lents à long terme, et il est impossible de subdiviser les fluctuations d'erreur sur différentes échelles de temps .
insérer la description de l'image ici

La variance d'Allan est un concept relativement intuitif et sans prétention. Il a été initialement proposé en pratique pour répondre aux besoins de l'analyse de haute précision de la stabilité de l'horloge. La variance d'Allan convient à l'analyse de la navigation inertielle (et des horloges)Focus sur la stabilité à long termecapteur, paire de courbes de variance Allanéchelle de temps à moyen et long termeLes caractéristiques d'erreur sont très expressives. La variance d'Allan a l'avantage de mieux décrire les erreurs à long terme que la variance ordinaire .La variance Allan est utilisée comme méthode standard pour l’étalonnage du bruit IMU.

2. Le concept de variance d'Allan

Variance d'Allan, également connue sous le nom de variance d'Allan ou variance d'Allan , la méthode de variance d'Allan est une méthode d'analyse basée sur le domaine temporel proposée par David Allan de l'American National Bureau of Standards dans les années 1960 .

Le but de la conception de la méthode d'analyse de variance Allan est de réaliser une telle analyse : l'accent mis sur les erreurs des capteurs inertiels se reflète principalement dans l'incertitude et la stabilité, en particulier la stabilité des différentes échelles de temps. Par exemple, le domaine des armes tactiques s'intéresse à la stabilité des échelles de temps allant des secondes aux minutes, et le domaine des sous-marins s'intéresse à la stabilité des échelles de temps des jours, des axes et des mois. Alors, existe-t-il un moyen d'exprimer les incertitudes sur différentes échelles de temps dans différentes catégories ? Le professeur Allan a proposé la méthode d'analyse de variance Allan pour résoudre ce problème.

La variance d'Allan estanalyse temps-fréquenceetnavigation inertielleMéthode d'analyse des erreurs couramment utilisée dans le domaine, elle décrit efficacement le niveau de fluctuation (instabilité) de la série temporelle d'erreurs à étudier sur différentes échelles de temps, et peut être basée sur la courbe formée par la valeur de la variance d'Allan sur différentes échelles de temps. Caractéristiques de la forme pour identifier le modèle de processus stochastique qu'il contient. La méthode d’analyse de variance Allan a un fort pouvoir d’expression pour les fluctuations aléatoires à moyen et long terme, et elle peut être utilisée comme outil général d’analyse de séries chronologiques à étendre à d’autres domaines d’application.

Lorsque nous effectuons une analyse d'erreurs sur des dispositifs de navigation inertielle (gyroscopes et accéléromètres), la méthode d'analyse de variance Allan est souvent utilisée. C'est depuis le débutfréquence temporelleUn type emprunté au domaine (stabilité de fréquence des horloges de haute précision)Méthodes d'analyse des séries chronologiques, est très approprié pour la description quantitative et l'analyse des fluctuations à moyen et long terme (instabilité) , c'est donc exactement ce dont nous avons besoin pour l'analyse des erreurs des dispositifs inertiels.

3. Processus de calcul de l'écart Allan

La variance d'Allan extrait avec précision les fluctuations de la séquence d'erreurs sur une échelle de temps spécifiée. Les étapes de calcul spécifiques sont les suivantes :
insérer la description de l'image ici

Étape 1 : couplage

Selon la longueur de la fenêtreτ = ( n − 1 ) t 0 \tau=\left(\left.n-1\right.\right)t_0t=(n1)t0Diviser la séquence y en N c N_cNcBlocs (clusters), chaque bloc contient n points de données et il n'y a pas de chevauchement entre les blocs.

Étape 2 : Moyenne du bloc

Calculez respectivement la moyenne de n points de données dans chaque bloc, enregistrés comme : y ‾ k = 1 n ∑ i = ⁡ kk + n − 1 yi \begin{aligned}\overline{y}_k=\frac1n\sum_{i\ nom de l'opérateur{=}k}^{k+n-1}y_i\end{aligned}ouik=n1je=kk + n 1ouije

Étape 3 Calculer la variance d'Allan

Différence des valeurs moyennes des blocs adjacents.
σ 2 ( τ ) = 1 2 ( N c − 1 ) ∑ k = 1 N c − 1 ( y ˉ k + 1 − y ˉ k ) 2 \begin{aligned}\sigma^2(\tau)=\frac {1}{2(N_c-1)}\sum_{k=1}^{N_c-1}(\bar{y}_{k+1}-\bar{y}_k)^2\end{aligned }p2 (t)=2 ( Nc1 )1k = 1Nc 1(ouiˉk + 1ouiˉk)2

Étape 4 : Valeurs RMS des statistiques

Sur la base de la différence obtenue à l’étape 3, calculez la valeur RMS.

(Facultatif) Étape 5 Tracez la courbe de variance d'Allan

Modifiez la longueur du bloc, répétez 1 à 3 et tracez une courbe logarithmique de l'écart type d'Allan changeant avec la longueur du bloc, appelée courbe de variance d'Allan. On peut voir sur la figure que chaque bloc de temps correspond à une variance d'Allan. Tous les différents temps de bloc et les variances d'Allan correspondantes sont connectés pour tracer une courbe standard d'Allan. Ensuite, l’analyse de la variance d’Allan consiste à analyser la courbe standard d’Allan.

4. Coefficient d'erreur de lecture du tracé de variance d'Allan

La méthode de variance Allan peut être utilisée pour calibrer cinq types d’erreurs aléatoires :

  • Bruit de quantification : le coefficient d'erreur est QQQ , la lecture en ordonnée du point d'intersection de l'extension du segment de droite avec une pente de -1 sur la courbe logarithmique de variance d'Allan et t=1 est3 TQ \frac{\sqrt{3}}{T}QT3 Q ;
  • Marche aléatoire angulaire : son coefficient d'erreur NNN , la pente sur la courbe logarithmique de la variance d'Allan est− 1 / 2 -1/2 Extension de 1/2 segment de droite et t = 1 t=1t=1La lecture des ordonnées du point d'intersection estNT \frac{N}{\sqrt{T}}T N
  • Instabilité du biais nul : son coefficient d'erreur BBB , la lecture en ordonnée du point d'intersection de l'extension du segment de droite avec une pente de 0 sur la courbe logarithmique de la variance d'Allan et t=1 est2 ln ⁡ 2 π B \sqrt{\frac{2\ln2}{\pi} }BPi2l n2 B , prenez généralement la valeur minimale de la zone plate inférieure ou prenezt = 1 0 1 t=10^1t=1 01 out = 1 0 2 t=10^2t=1 0valeur à 2 ;
  • Marche aléatoire à taux angulaire : son coefficient d'erreur KKK , la droite d'extension du segment de droite de pente 1/2 ett = 1 t = 1t=1La lecture des ordonnées du point d'intersection estKT / 3 \frac{K}{\sqrt{T/3}}T /3 K
  • Rampe de taux angulaire : son coefficient d'erreur RRR , la ligne d'extension du segment de droite de pente 1 ett = 1 t=1t=1La lecture des ordonnées du point d'intersection estRT 2 \frac{RT}{\sqrt{2}}2 RT
    insérer la description de l'image ici

En supposant que les différentes sources d'erreur sont statistiquement indépendantes, la variance totale d'Allen est la somme des différentes sources d'erreur, qui est le carré du bruit de quantification σ Q σ_QpQ, angle de marche aléatoire au carré σ RAW σ_{RAW}pRAW _ _, le carré de l'instabilité du biais nul σ biais σ_{bias}pbiais _, le carré de la marche aléatoire de vitesse angulaire σ RRW σ_{RRW}pRR W, le carré de la pente de vitesse angulaire σ RR σ_{RR}pFRSomme.
insérer la description de l'image ici

5. Analyse de variance Allan

L'incertitude à court terme est supprimée en faisant la moyenne au sein d'un bloc ; l'incertitude à long terme est supprimée en faisant la moyenne entre des blocs adjacents.

Si nous nous intéressons uniquement aux erreurs sur une certaine échelle de temps (c'est-à-dire les fluctuations d'erreur), alors les changements détaillés sont inférieurs à cette échelle de temps (sauts rapides de courte durée) et les changements macro sont plus grands que cette échelle de temps (sauts lents de longue durée). ) ne sont pas préoccupants et, espérons-le, seront éliminés dans nos mesures d'erreur. La variance d'Allan se fait comme ceci :

  1. Déterminer la durée du bloc horaire à examiner par blocage ;

  2. Utilisez la moyenne intra-bloc pour effacer les composants (détails) qui changent rapidement et qui sont plus courts que la longueur du bloc ;

  3. Utilisez ensuite la méthode de recherche de la différence entre les blocs adjacents pour effacer tous les composants à évolution lente (macro) qui sont plus longs que la longueur de deux blocs ;

  4. Enfin, la valeur carrée de la séquence de différence est calculée (il s'agit d'une opération standard pour le traitement de tout échantillon aléatoire), de sorte que les fluctuations d'erreur soient calculées dans une plage de temps très étroite comprise entre 1 fois la longueur du bloc et 2 fois la longueur du bloc. . .

6. Courbe de variance d'Allan

Si nous sommes intéressés par les composants sur chaque échelle de temps de la séquence d'erreurs, nous pouvons "scanner" la longueur du bloc de court à long pour obtenir un ensemble de valeurs de variance d'Allan, puis tracer une courbe "variance d'Allan en fonction de la longueur du bloc". , afin qu'il puisse refléter pleinement les caractéristiques de la séquence d'erreurs étudiée. Plus précisément, il s'agit en fait d'une courbe double logarithmique de « déviation d'Allan (déviation d'Allan) par rapport à la longueur du bloc », afin d'avoir une expressivité plus forte dans une plage plus large. Ce qui suit est un diagramme de la variance Allan d'un gyroscope classique de haute précision.
insérer la description de l'image ici
insérer la description de l'image ici

À partir de la courbe de variance d'Allan, nous pouvons identifier différents types d'erreurs aléatoires (c'est-à-dire des modèles de processus aléatoires) et extraire leurs paramètres en fonction des caractéristiques de forme de la courbe. Par exemple : un segment de droite avec une pente de -1/2 représente un bruit blanc. Pour plus de détails, veuillez vous référer à l'annexe C d'une norme technique sur les tests de gyroscope développée par l'IEEE [1]. Cette annexe donne également un cas d'analyse de diverses erreurs aléatoires d'un gyroscope à partir de la courbe de variance d'Allan (comme le montre la figure ci-dessus). Mais je tiens à rappeler à tout le monde que la courbe de variance d'Allan réelle ne montre souvent que quelques deux ou trois types d'erreurs majeures, car d'autres erreurs sont submergées par ces erreurs majeures. Et comme notre souci d’ingénierie réside précisément dans les principales sources d’erreurs, cela ne nous dérange pas. Pour plus de précautions lors de l'utilisation de l'analyse de variance Allan, veuillez vous référer au billet de blog « Points clés de l'utilisation de l'analyse de variance Allan » rédigé par l'enseignant Yan Gongmin de NPU , qui est très précis et pragmatique.

7. Application de la variance Allan

La méthode ANOVA d'Allan ne se limite pas àAnalyse des centrales inertielles et des erreurs d'horloge, peut également être étendu à d'autresanalyse de séquence d'erreurs; Et cela ne se limite pas à l'analyse des séquences d'erreurs, mais peut également être appliqué à l'analyse de n'importe quelle série temporelle (telle que la déformation des bâtiments, l'évolution géologique, etc.).

8. Variance d'Allan et ROS

Ce qui suit est une image de la lecture du sac et de l'obtention de la variance Allen, et le graphique de variance Allen correspondant sera généré. Ici nous faisons principalement référence au fichier C++ correspondant à allan_variance_ros .

sudo pip install allantools
#!/usr/bin/env python
import rospy
import sys
import allantools
import rosbag
import numpy as np
import csv
import rospkg
import os
import matplotlib.pyplot as plt  # only for plotting, not required for calculations
import math

def getRandomWalkSegment(tau,sigma):

    m = -0.5 # slope of random walk
    """""""""""""""""""""""""""""""""
    " Find point where slope = -0.5 "
    """""""""""""""""""""""""""""""""
    randomWalk = None
    i = 1
    idx = 1
    mindiff = 999
    logTau = -999
    while (logTau<0):
        logTau = math.log(tau[i],10) 
        logSigma = math.log(sigma[i],10)
        prevLogTau = math.log(tau[i-1],10)
        prevLogSigma = math.log(sigma[i-1],10)
        slope = (logSigma-prevLogSigma)/(logTau-prevLogTau)# 随机漫步的斜率
        diff = abs(slope-m)# 当前斜率与目标斜率的差值
        if (diff<mindiff):
            mindiff = diff# 更新最小差值
            idx = i
        i = i + 1

    """"""""""""""""""""""""""""""
    " Project line to tau = 10^0 "
    """"""""""""""""""""""""""""""
    x1 = math.log(tau[idx],10)# 当前点的横坐标
    y1 = math.log(sigma[idx],10)# 当前点的纵坐标
    x2 = 0
    y2 = m*(x2-x1)+y1

    return (pow(10,x1),pow(10,y1),pow(10,x2),pow(10,y2))

def getBiasInstabilityPoint(tau,sigma):
    i = 1
    while (i<tau.size):
        if (tau[i]>1) and ((sigma[i]-sigma[i-1])>0): # only check for tau > 10^0
            break
        i = i + 1
    return (tau[i],sigma[i])

def main(args):

    rospy.init_node('allan_variance_node')

    t0 = rospy.get_time()

    """"""""""""""
    " Parameters "
    """"""""""""""
    bagfile = rospy.get_param('~bagfile_path','~/data/static.bag')# 输入的bag文件路径
    topic = rospy.get_param('~imu_topic_name','/imu')# 输入的imu topic名称
    axis = rospy.get_param('~axis',0)# 输入的轴,0为x轴,1为y轴,2为z轴
    sampleRate = rospy.get_param('~sample_rate',100)# 输入的采样频率
    isDeltaType = rospy.get_param('~delta_measurement',False)# 是否是delta measurement
    numTau = rospy.get_param('~number_of_lags',1000)# 输入的tau数目
    resultsPath = rospy.get_param('~results_directory_path',None)# 输出的结果路径

    """"""""""""""""""""""""""
    " Results Directory Path "
    """"""""""""""""""""""""""
    if resultsPath is None:
        paths = rospkg.get_ros_paths()
        path = paths[1] # path to workspace's devel
        idx = path.find("ws/")# 找到路径
        workspacePath = path[0:(idx+3)]# 取到workspace的路径
        resultsPath = workspacePath + 'av_results/'# 结果输出路径

        if not os.path.isdir(resultsPath):
            os.mkdir(resultsPath)

    print("\nResults will be save in the following directory: \n\n\t %s\n"%resultsPath)

    """"""""""""""""""
    " Form Tau Array "
    """"""""""""""""""
    taus = [None]*numTau# 初始化tau数组

    cnt = 0;
    for i in np.linspace(-2.0, 5.0, num=numTau): # lags will span from 10^-2 to 10^5, log spaced
        taus[cnt] = pow(10,i)# 将tau数组赋值,维度在10^-2 到 10^5
        cnt = cnt + 1

    """""""""""""""""
    " Parse Bagfile "
    """""""""""""""""
    bag = rosbag.Bag(bagfile)

    N = bag.get_message_count(topic) # 在bag文件中找到该topic的消息数量

    data = np.zeros( (6,N) ) # 初始化数据矩阵,维度为6*N

    if isDeltaType:
        scale = sampleRate
    else:
        scale = 1.0

    cnt = 0
    for topic, msg, t in bag.read_messages(topics=[topic]):# 遍历bag文件中的消息
        data[0,cnt] = msg.linear_acceleration.x * scale
        data[1,cnt] = msg.linear_acceleration.y * scale
        data[2,cnt] = msg.linear_acceleration.z * scale
        data[3,cnt] = msg.angular_velocity.x * scale
        data[4,cnt] = msg.angular_velocity.y * scale
        data[5,cnt] = msg.angular_velocity.z * scale
        cnt = cnt + 1

    bag.close()

    print ("[%0.2f seconds] Bagfile parsed\n"%(rospy.get_time()-t0))

    """"""""""""""""""
    " Allan Variance "
    """"""""""""""""""
    if axis is 0:
        currentAxis = 1 # 循环通过所有轴1-6
    else:
        currentAxis = axis # 只需循环一次,然后中断

    while (currentAxis <= 6):
        # taus_used 对应了是否可以使用taus的数组,adev是allan deviation degree的缩写,为allan偏差;adev_err是allan偏差的误差;adev_norm是allan偏差的标准化;
        (taus_used, adev, adev_err, adev_n) = allantools.oadev(data[currentAxis-1], data_type='freq', rate=float(sampleRate), taus=np.array(taus) )# 计算allan variance

        randomWalkSegment = getRandomWalkSegment(taus_used,adev)# 计算random walk segment
        biasInstabilityPoint = getBiasInstabilityPoint(taus_used,adev)# 计算bias instability point

        randomWalk = randomWalkSegment[3]# 获取random walk segment的纵坐标
        biasInstability = biasInstabilityPoint[1]# 获取bias instability point的纵坐标

        """""""""""""""
        " Save as CSV "
        """""""""""""""
        if (currentAxis==1):
            fname = 'allan_accel_x'
            title = 'Allan Deviation: Accelerometer X'
        elif (currentAxis==2):
            fname = 'allan_accel_y'
            title = 'Allan Deviation: Accelerometer Y'
        elif (currentAxis==3):
            fname = 'allan_accel_z'
            title = 'Allan Deviation: Accelerometer Z'
        elif (currentAxis==4):
            fname = 'allan_gyro_x'
            title = 'Allan Deviation: Gyroscope X'
        elif (currentAxis==5):
            fname = 'allan_gyro_y'
            title = 'Allan Deviation: Gyroscope Y'
        elif (currentAxis==6):
            fname = 'allan_gyro_z'
            title = 'Allan Deviation: Gyroscope Z'

        print ("[%0.2f seconds] Finished calculating allan variance - writing results to %s"%(rospy.get_time()-t0,fname))

        f = open(resultsPath + fname + '.csv', 'wt')

        try:
            writer = csv.writer(f)
            writer.writerow( ('Random Walk', 'Bias Instability') )
            writer.writerow( (randomWalk, biasInstability) )
            writer.writerow( ('Tau', 'AllanDev', 'AllanDevError', 'AllanDevN') )
            for i in range(taus_used.size):
                writer.writerow( (taus_used[i],adev[i],adev_err[i],adev_n[i])  )
        finally:
            f.close()

        """""""""""""""
        " Plot Result "
        """""""""""""""
        plt.figure(figsize=(12,8))
        ax = plt.gca()
        ax.set_yscale('log')
        ax.set_xscale('log')

        plt.plot(taus_used,adev)
        plt.plot([randomWalkSegment[0],randomWalkSegment[2]],
                 [randomWalkSegment[1],randomWalkSegment[3]],'k--')
        plt.plot(1,randomWalk,'rx',markeredgewidth=2.5,markersize=14.0)
        plt.plot(biasInstabilityPoint[0],biasInstabilityPoint[1],'ro')

        plt.grid(True, which="both")
        plt.title(title)
        plt.xlabel('Tau (s)')
        plt.ylabel('ADEV')

        for item in ([ax.title, ax.xaxis.label, ax.yaxis.label] +
                    ax.get_xticklabels() + ax.get_yticklabels()):
            item.set_fontsize(20)

        plt.show(block=False)

        plt.savefig(resultsPath + fname)

        currentAxis = currentAxis + 1 + axis*6 # increment currentAxis also break if axis is not =0

    inp=input("Press Enter key to close figures and end program\n")

if __name__ == '__main__':
  main(sys.argv)

おすすめ

転載: blog.csdn.net/m0_37605642/article/details/132635448