Alexandre Pirotte
/
Nucleo_filtrage
LUIS
Revision 0:7a912bfb5a4e, committed 2018-10-05
- Comitter:
- pirottealex
- Date:
- Fri Oct 05 14:54:02 2018 +0000
- Commit message:
- a
Changed in this revision
diff -r 000000000000 -r 7a912bfb5a4e digital_filter.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/digital_filter.cpp Fri Oct 05 14:54:02 2018 +0000 @@ -0,0 +1,122 @@ +/** + * digital_filter.h + * + * Auteur : Ferdinand Piette (Avril 2011) + * Version : 1.0b + * + * Fourni des fonctions permettant d'appliquer des filtres numériques + * ayant pour fonction de transfert : + * + * b0*z + b1*z^-1 + ... + bN*z^-N + * H(z) = -------------------------------- + * 1 + a1*z^-1 + ... + aM*z^-M + */ + +#include <stdlib.h> +#include <stdio.h> + +#include "digital_filter.h" + +/** + * Initialise les coefficiants du filtre + * @param coef_a : les coefficients ai de la fonction de transfert du filtre + * @param coef_b : les coefficients bj de la fonction de transfert du filtre + * @param coef_a_size : le nombre de coefficients ai. Correspond à M dans la fonction de transfert du filtre + * @param coef_b_size : le nombre de coefficients bi. Correspond à N dans la fonction de transfert du filtre + * @param transfert_function : un pointeur vers la structure digital_filter_coefficient à initialiser + * Si coef_a_size = 0, alors on a la fonction de transfert d'un filtre RIF, sinon, on a celle d'un filtre RII + */ +void init_digital_filter_coefficient(struct digital_filter_coefficient * transfert_function, double * coef_a, int coef_a_size, double * coef_b, int coef_b_size) +{ + int i; + + // Création du tableau des coefficients a + transfert_function->numberOfCoef_a = coef_a_size; + transfert_function->coef_a = (double *)malloc(transfert_function->numberOfCoef_a * sizeof * transfert_function->coef_a); + for(i = 0; i < transfert_function->numberOfCoef_a; i++) + transfert_function->coef_a[i] = coef_a[i]; + + // Création du tableau des coefficients b + transfert_function->numberOfCoef_b = coef_b_size; + transfert_function->coef_b = (double *)malloc(transfert_function->numberOfCoef_b * sizeof * transfert_function->coef_b); + for(i = 0; i < transfert_function->numberOfCoef_b; i++) + transfert_function->coef_b[i] = coef_b[i]; +} + +/** + * Initialise le filtre + * @param coef_a : les coefficients ai de la fonction de transfert du filtre + * @param coef_b : les coefficients bj de la fonction de transfert du filtre + * @param coef_a_size : le nombre de coefficients ai. Correspond à M dans la fonction de transfert du filtre + * @param coef_b_size : le nombre de coefficients bi. Correspond à N dans la fonction de transfert du filtre + * @param filter : un pointeur vers la structure digital_filter à initialiser + * Si coef_a_size = 0, alors on se ramène à un filtre RIF, sinon, on a un filtre RII + */ +void init_digital_filter(struct digital_filter * filter, double * coef_a, int coef_a_size, double * coef_b, int coef_b_size) +{ + // Initialise les coefficients du filtre + init_digital_filter_coefficient(&filter->transfert_function, coef_a, coef_a_size, coef_b, coef_b_size); + + // Alloue l'espace mémoire pour les échantillons et les résultats + filter->samples = (double *)calloc(filter->transfert_function.numberOfCoef_b, sizeof * filter->samples); + filter->results = (double *)calloc(filter->transfert_function.numberOfCoef_a, sizeof * filter->results); + + // Initialise les pointeurs des tableaux d'échantillons et de résultats + filter->current_sample = 0; + filter->previous_result = filter->transfert_function.numberOfCoef_a-1; +} + +/** + * Calcul l'échantillon après filtrage + * @param sample : le nouvel échantillon que l'on veut filtrer + * @param filter : un pointeur vers la structure digital_filter contenant les informations du filtre (fonction de transfert et mémoire des échantillons précédents) + * @return l'échantillon après filtrage + */ +double filter_next_sample(digital_filter * filter, double sample) +{ + double result = 0; + int i; + + // Stocke en mémoire le nouvel échantillon + filter->samples[filter->current_sample] = sample; + + // Calcul le résultat du filtrage pour un filtre RIF ou RII + // (Prise en compte des échantillons précédent) + for(i = 0; i < filter->transfert_function.numberOfCoef_b; i++) + result += filter->transfert_function.coef_b[i] * filter->samples[modulo((filter->current_sample-i),filter->transfert_function.numberOfCoef_b)]; + + // Calcul le résultat du filtrage pour un filtre RII + // (Correction avec le résultat du filtrage des échantillons précédents) + for(i = 0; i < filter->transfert_function.numberOfCoef_a; i++) + result -= filter->transfert_function.coef_a[i] * filter->results[modulo((filter->previous_result-i),filter->transfert_function.numberOfCoef_a)]; + + // Met à jours les pointeurs des tableaux d'échantillons et de résultats + filter->current_sample = (filter->current_sample + 1) % filter->transfert_function.numberOfCoef_b; + if(filter->transfert_function.numberOfCoef_a > 0) + { + filter->previous_result = (filter->previous_result + 1) % filter->transfert_function.numberOfCoef_a; + filter->results[filter->previous_result] = result; // Garde en mémoire le résultat pour l'échantillon en cours + } + + return result; +} + +/** + * Définie l'opération de modulo dans les négatifs pour manipuler des buffers circulaires + * @param number : le nombre modulé + * @param n : le nombre modulant + * @return number modulo n + * modulo(-1, 3) = 2 + */ +int modulo(int number, int n) +{ + if(number >= 0) + return number%n; + + int result = (-1*number)%n; + + if(result > 0) + return n-result; + + return 0; +}
diff -r 000000000000 -r 7a912bfb5a4e digital_filter.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/digital_filter.h Fri Oct 05 14:54:02 2018 +0000 @@ -0,0 +1,47 @@ +/** + * digital_filter.h + * + * Auteur : Ferdinand Piette (Avril 2011) + * Version : 1.0b + * + * Fourni des fonctions permettant d'appliquer des filtres numériques + * ayant pour fonction de transfert : + * + * b0*z + b1*z^-1 + ... + bN*z^-N + * H(z) = -------------------------------- + * 1 + a1*z^-1 + ... + aM*z^-M + */ + +#ifndef DEF_digital_filter +#define DEF_digital_filter + + /** + * Structure stockant les coefficients du filtre + */ + typedef struct digital_filter_coefficient + { + double * coef_a; // Les coefficients a1..aN + double * coef_b; // Les coefficients b0..bM + int numberOfCoef_a; // Le nombre de coefficients a + int numberOfCoef_b; // Le nombre de coefficients b + } digital_filter_coefficient; + + /** + * Structure stockant les coefficiants du filtre et les échantillons et résultats nécessaires + */ + typedef struct digital_filter + { + double * samples; // Les échantillons en entrées du filtre + double * results; // Le résultat de la sortie du filtre + int current_sample; // L'indice du tableau où se trouvera le prochain échantillon + int previous_result; // L'indice du tableau où se trouve la sortie du filtre pour l'échantillon courrant + struct digital_filter_coefficient transfert_function; // La structure stockant les coefficients du filtre + } digital_filter; + + void init_digital_filter_coefficient(struct digital_filter_coefficient *, double *, int, double * , int); // Initialise les coefficients du filtre + void init_digital_filter(struct digital_filter *, double *, int, double * , int); // Initialise le filtre + double filter_next_sample(digital_filter *, double); // Calcule la sortie du filtre pour un nouvel échantillon + + int modulo(int, int); // Fonction modulo pour buffer circulaire (modulo(-1, 3) = 2) + +#endif
diff -r 000000000000 -r 7a912bfb5a4e main.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/main.cpp Fri Oct 05 14:54:02 2018 +0000 @@ -0,0 +1,28 @@ +#include "mbed.h" +#include "digital_filter.h" + + +Serial pc(USBTX,USBRX); + +int main() +{ + pc.baud(460800); + + double coef_b[4] = {0.0408, 0.1224, 0.1224, 0.0408}; // Les 4 coefficients ai + double coef_a[3] = {-1.2978, 0.7875, -0.1632}; // Les 3 coefficients bj + double echantillons[32] = {0.7362, 0.2071, 1.2774, 1.0, 0.5703, 1.2071, 0.0291, 0.0, -0.0291, -1.2071, -0.5703, -1.0, -1.2774, -0.2071, -0.7362, 0.0, + 0.7362, 0.2071, 1.2774, 1.0, 0.5703, 1.2071, 0.0291, 0.0, -0.0291, -1.2071, -0.5703, -1.0, -1.2774, -0.2071, -0.7362, 0.0}; + digital_filter mon_filtre; + + init_digital_filter(&mon_filtre, coef_a, 4, coef_b, 3); // Initialisation du filtre avec les coefficients de la fonction de transfert + + for(char i = 0; i < 32; i++) + { // On filtre les échantillons + pc.printf("Echantillon numero %d : %lf\t | Apres filtrage : %lf\n\r", i, echantillons[i], filter_next_sample(&mon_filtre, echantillons[i])); + } + + while(1) + { + wait(1); + } +}
diff -r 000000000000 -r 7a912bfb5a4e mbed.bld --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed.bld Fri Oct 05 14:54:02 2018 +0000 @@ -0,0 +1,1 @@ +https://os.mbed.com/users/mbed_official/code/mbed/builds/5aab5a7997ee \ No newline at end of file