Φιλτράρισμα Δεδομένων Αισθητήρων με ένα φίλτρο Kalman
Στην προσπάθεια να διαβάσω μετρήσεις από διάφορους αισθητήρες όπως επιταχυνσιόμετρα, μετρητές απόστασης και GPS βρέθηκα στη θέση όπου τα δεδομένα μου περιείχαν πολύ θόρυβο για να τα χρησιμοποιήσω όπως είναι.
Για παράδειγμα ένα gps έχει ακρίβεια 10m, άρα σε κάθε μέτρηση μπορεί να έχει πολύ μεγάλη απόκλιση από την πραγματική θέση Μπορεί δηλαδή να είμαστε εντελώς ακίνητοι αλλά λόγο της διαφορετικής μέτρησης να φαίνεται σα να κινούμαστε.
Πρέπει λοιπόν να βρούμε έναν τρόπο να απορρίπτουμε τις απότομες αλλαγές(θόρυβο) αλλά ταυτόχρονα να αντιλαμβανόμαστε έγκαιρα τις πραγματικές αλλαγές.
.
Μετά από κάποια ανεπιτυχή αποτελέσματα με χαμηλοπερατά φιλτρα επέλεξα να χρησιμοποιήσω ένα φίλτρο kalman. Το φίλτρο Kalman περιλαμβάνει πολλά περίπλοκα μαθηματικά Αλλά, ευτυχώς, χρειαζόμουν ένα απλό μονοδιάστατο Kalman Filter χωρίς καμία πληροφορία οδήγησης, γεγονός που καθιστά την κατασκευή πολύ ευκολότερη.
Εφαρμογή του φίλτρου Kalman
Εάν κοιτάξετε τους μαθηματικούς τύπους των φίλτρων kalman θα δείτε ότι απαιτούν πολλούς υπολογισμούς με πίνακες και διανυσματικά μαθηματικά. Αλλά μετά από λίγο ψάξιμο κατέληξα ότι ένα απλό μονοδιάστατο φίλτρο θα έκανε την δουλεία Για να χρησιμοποιηθεί σε ένα acceloremeter 3 αξόνων μπορούν να συνδυαστούν 3 μονοδιάστατα φίλτρα.
Έτσι καταλήγουμε σε αυτό το μικρο τύπο:
1 2 3 4 5 |
x = x; p = p + q; k = p / (+ p r); x = x + k * (μέτρηση - x); p = (1 - k) * p; |
Οι δύο πρώτοι τύποι αντιπροσωπεύουν την πρόβλεψη του Kalman Filter. Και δεδομένου ότι δεν υπάρχει καμία πληροφορία σχετικά με τις κινητήριες δυνάμεις είναι πολύ απλό. Ο δεύτεροι, τρεις τύποι, υπολογίζουν την ανανεωση των μετρήσεων. Οι μεταβλητές είναι x για το φιλτραρισμένο αποτέλεσμα, q για το θόρυβο της διεργασίας, r για το θόρυβο από τον αισθητήρα, p για το εκτιμώμενο σφάλμα και k για το κέρδος Kalman. Η κατάσταση του φίλτρου καθορίζεται από τις τιμές αυτών των μεταβλητών.
Το φίλτρο εφαρμόζεται σε κάθε μέτρηση και αρχικοποιείται με τον θόρυβο της διεργασίας q, r θόρυβος του αισθητήρα, αρχική εκτίμηση λάθους p και η αρχική τιμή x. Η αρχική τιμή για το p δεν είναι πολύ σημαντική, δεδομένου ότι προσαρμόζεται κατά τη διάρκεια της διαδικασίας. Πρέπει να είναι όμως αρκετά υψηλή για να περιοριστεί αργότερα Η αρχική τιμή για την μέτρηση δεν είναι επίσης πολύ σημαντική, δεδομένου ότι ανανεώνετε κατά τη διάρκεια της διαδικασίας.
Αλλά η ρύθμιση των τιμών για το θόρυβο της διεργασίας και του θορύβου του αισθητήρα είναι απαραίτητη για να πάρετε σαφείς και "καθαρές" μετρήσεις.
Ρύθμιση τιμών στο φίλτρο Kalman
Τα πρώτα αποτελέσματα ήταν αρκετά μακρυά από τα ιδανικά Γι 'αυτό και αποφάσισα να χρησιμοποιήσω για επεξεργασία την παλιά καλή μου πλακέτα ανάπτυξης LIS302DL ώστε να πάρω κάποια εικόνα για το βέλτιστο τιμών των διαφόρων παραμέτρων:
Πρώτα κοίταξα την σημασία του q θορύβου διεργασίας, ξεκινώντας από μια πολύ υψηλή τιμή των 128 (που είναι η μέγιστη απόδοση του επιταχυνσιομέτρου):
Βλέπετε σχεδόν δεν υπάρχει διαφορά μεταξύ των φιλτραρισμένων δεδομένων (λευκό) και τα αρχικά δεδομένα (γκρι) - δεδομένου ότι βλέπετε μόνο τη λευκή γραμμή.
Αν χαμηλώσουμε το θόρυβο διεργασίας, π.χ. σε μια τιμή του 4 τα πράγματα αρχίζουν να αλλάξουν:
Αν κοιτάξετε προσεκτικά θα δείτε ότι τα δεδομένα του αισθητήρα συχνά υπερβαίνουν την τιμή του φίλτρου. Η φιλτραρισμένη τιμή είναι πολύ κοντά στην πραγματική τιμή, αλλά έχει πολύ θόρυβο ακόμη.
Για την εφαρμογή μου χρειάζεται μια πιο σταθερή έξοδος, εξομαλύνοντας σχεδόν όλο το θόρυβο, με αποτέλεσμα ένα καθαρό και σταθερό σήμα. Έτσι ας χαμηλώσουμε την τιμή του θορύβου διεργασίας λίγο περισσότερο, π.χ. κάτι σε 0,125:
Τώρα έχουμε ένα πολύ καθαρό σήμα από μια αρκετά θορυβώδη πηγή. Υπάρχει μια μικρή καθυστέρηση από τα πραγματικά δεδομένα, αλλά δεν είναι κρίσιμη για την εφαρμογή μου. Σε σύγκριση πάντα με το ποσό της μείωσης του θορύβου, είναι ακόμη αρκετά γρήγορη απόκριση.
Μετά από αυτό ας παίξουμε λίγο με το θόρυβο του αισθητήρα r:
Ξεκινάμε στο r = 1:
Όπως ήταν αναμενόμενο αν χαμηλώσουμε τον εκτιμώμενο θόρυβο του αισθητήρα, το φίλτρο Kalman, «στηρίζεται» περισσότερο στα δεδομένα του αισθητήρα και δίνει πιο θορυβώδη αποτελέσματα. Αν αυξηθεί ο συντελεστής θορύβου του αισθητήρα σε 4 έχουμε ένα πιο σταθερό αποτέλεσμα και πάλι:
Αν πάμε σε μια ακραία τιμή με ένα επίπεδο θορύβου των 32 θα έχουμε το αναμενόμενο σταθερό αποτέλεσμα:
Όπως ήταν αναμενόμενο η φιλτραρισμένη τιμή υστερεί σημαντικά έναντι των πραγματικών μετρήσεων. Αλλά είναι ένα πολύ καθαρότερο σήμα. Είναι όμως αμφίβολο αν αυτό εξακολουθεί να είναι χρήσιμο.
Εφαρμογή Kalman σε C
Εφαρμογή αυτού του φίλτρο σε κωδικά C (π.χ. για ένα Arduino) είναι αρκετά απλή. Πρώτα απ' όλα ορίζουμε μια δομή για το φίλτρο Kalman:
1 2 3 4 5 6 7 |
typedef struct { double q; //process noise covariance double r; //measurement noise covariance double x; //value double p; //estimation error covariance double k; //kalman gain } kalman_state; |
Στη συνέχεια, χρειαζόμαστε μια ρουτίνα για να αρχικοποιηθεί το φίλτρο Kalman:
1 2 3 4 5 6 7 8 9 10 11 |
kalman_state kalman_init(double q, double r, double p, double intial_value) |
Και μια ρουτίνα για να ανανεώνεται η κατάσταση του φίλτρου, υπολογίζοντας μια πρόβλεψη και κάνοντας μια επαλήθευση με την πραγματική μέτρηση:
1 2 3 4 5 6 7 8 9 10 11 12 |
void kalman_update(kalman_state* state, double measurement) { //prediction update //omit x = x state->p = state->p + state->q; //measurement update state->k = state->p / (state->p + state->r); state->x = state->x + state->k * (measurement - state->x); state->p = (1 - state->k) * state->p; } |
Τι μαθαίνουμε από αυτό;
Πρώτα απ 'όλα το φίλτρο Kalman μπορεί να είναι ευκολότερο να εφαρμοστεί, εάν το υποκείμενο μοντέλο είναι απλό. Δεν είχαμε πολλές διαστάσεις, ούτε διαφορετικά δεδομένα από αισθητήρες για να συνδυάσετε. Τα αποτελέσματα είναι αρκετά καλά, αλλά είναι μια πρόκληση να βρούμε τις σωστές τιμές για τη διεργασία και το θόρυβο του αισθητήρα. Αντί απλώς να καταλήξουμε σε κάποιες εικασίες για τις τιμές, μπορεί φυσικά να υπολογιστούν, αλλά θα πρέπει να αρκεστούμε με το αποτέλεσμα της εκτίμησης.
Συνοψίζοντας αυτό είναι ένα καλό, εύρωστο και απλό φίλτρο (μίας διάστασης).
Νομίζω ότι στην περίπτωση που θέλατε να εξομαλύνεται τα αποτελέσματα μετρήσεων αισθητήρων ένα τέτοιο φίλτρο είναι ιδανικό.
Ή μήπως υπάρχει ένα πολύ πιο εύκολο στη χρήση φίλτρο για το πρόβλημά μου, που οδηγεί σε καλύτερα αποτελέσματα;
Ενδεικτικά αναφέρω το Moving average filter.
Επίσης να θυμάστε οτι ο καλύτερος τρόπος για να αφαιρέσουμε το θόρυβο από τις μετρήσεις μας είναι να αποφύγουμε το θόρυβο εξαρχής!
Προσέξτε τις γειωσεις και τις ενώσεις των καλωδίων, ενώ πολλές φορές τα αποτελέσματα μπορούν να βελτιωθούν σημαντικά κάνοντας χρήση απλών πυκνωτών εξομάλυνσης που είναι εξαιρετικά φθηνοί και δε θα σπαταλήσουν άδικα την πολύτιμη επεξεργαστική ισχύ του ελεγκτή σας.
Tο άρθρο είναι βασισμένο στο αγγλικό κείμενο εδώ.