IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Algorithmes et structures de données Discussion :

Détection du changement de sens pour un capteur


Sujet :

Algorithmes et structures de données

  1. #1
    Membre régulier
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Novembre 2006
    Messages
    296
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Drôme (Rhône Alpes)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Matériel informatique

    Informations forums :
    Inscription : Novembre 2006
    Messages : 296
    Points : 99
    Points
    99
    Par défaut Détection du changement de sens pour un capteur
    Bonjour,
    Je cherche à détecter précisément le changement de sens de rotation d'un capteur.
    Actuellement je fais un filtre passe bas sur ce capteur puis je dérive cette valeur.
    Malheureusement la valeur de la dérivée m'amène beaucoup de bruit.
    En pièce jointe mon code ainsi qu'un log.
    Existe-t-il une autre manière de faire ?
    Mon code fonctionne dans un microcontrôleur en C.

    Merci

    Detection_sens_pot.zipLogCapteur.zip

  2. #2
    Modérateur
    Avatar de kolodz
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Avril 2008
    Messages
    2 211
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 36
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Produits et services télécom et Internet

    Informations forums :
    Inscription : Avril 2008
    Messages : 2 211
    Points : 8 316
    Points
    8 316
    Billets dans le blog
    52
    Par défaut
    Le filtre passe bas est une bonne ma manière de lissé le bruit.
    Après, tu peux aussi ajouter une seuil de détection.

    Donc avec ton logCateur en utilisant deux buffers de 30 points et une limite de détection de 5, j'obtiens le résultat suivant :
    On change de sens on diminue !
    Valuer actuelle : 916
    On change de sens on augment !
    Valuer actuelle : 57
    On change de sens on diminue !
    Valuer actuelle : 472
    On change de sens on augment !
    Valuer actuelle : 379
    On change de sens on diminue !
    Valuer actuelle : 624
    On change de sens on augment !
    Valuer actuelle : 327
    On change de sens on diminue !
    Valuer actuelle : 626
    On change de sens on augment !
    Valuer actuelle : 447
    On change de sens on diminue !
    Valuer actuelle : 549
    J'explique le fonctionnement :
    Quand j'ai une nouvelle valeur :
    Je place la valeur du buffer A dans le buffer B.
    Je place la nouvelle valeur dans le buffer A.
    (buffer glissant)
    Code java : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    int[] bufferOld = new int[size];
    int[] buffer = new int[size];
    int pos = 0;
    int previousMoyenne= 0;
    boolean isAugement = true;
    while ((line = buff.readLine()) != null) {
    	Integer value = Integer.parseInt(line);
    	if(value != null){
    		bufferOld[pos] = buffer[pos];
    		buffer[pos] = value;
    	}
    	pos++;
    	if(pos ==size){
    		pos =0;
    	}
    }
    Après avoir lus 60 valeur ou plus, j'ai donc mon buffer A contenant les 30 dernière valeurs et le Buffer B contenant les 30 précédents.
    En réalisant une moyenne des valeurs de du buffer A et du buffer B. On obtient un valeur lissé (filtre passe bas).
    Cela élimine une première partie du bruit. cependant si notre valeur stagne trop par rapport à notre échantillonnage, le bruit sera capable à lui seul faire bascule la moyenne de A au dessus de la moyenne de B alors que globalement, la valeur n'a pas bougé.
    C'est pour cela qu'on ajout un seuillé de détection :

    Code java : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    int delta = 5;
    if( getMoyen(buffer)> (getMoyen(bufferOld)+delta) ){
    	// on augemnent
    	if(!isAugement){
    		isAugement = true;
    		System.out.println("On change de sens on augment !");
    		System.out.println("Valuer actuelle : " +value);
    	}
    } else if(getMoyen(buffer)<(getMoyen(bufferOld)-delta)) {
    	// on diminue
    	if(isAugement){
    		isAugement = false;
    		System.out.println("On change de sens on diminue !");
    		System.out.println("Valuer actuelle : " +value);
    	}
    }

    Bien qu'il soit nécessaire de faire un calibrage de la taille des buffer et du seuil de détection. Cela fonctionne !par rapport à ce que tu fait, je n'ai globalement qu’ajouté un seuil et fait le filtre à la main.

    Cordialement,
    Patrick Kolodziejczyk.
    Si une réponse vous a été utile pensez à
    Si vous avez eu la réponse à votre question, marquez votre discussion
    Pensez aux FAQs et aux tutoriels et cours.

  3. #3
    Modérateur
    Avatar de ToTo13
    Homme Profil pro
    Chercheur en informatique
    Inscrit en
    Janvier 2006
    Messages
    5 793
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 45
    Localisation : Etats-Unis

    Informations professionnelles :
    Activité : Chercheur en informatique
    Secteur : Santé

    Informations forums :
    Inscription : Janvier 2006
    Messages : 5 793
    Points : 9 860
    Points
    9 860
    Par défaut
    Le signal semble très stable. Un lissage avec un gros médian pourrait rendre la courbe complètement monotone sur des grandes portions.
    Tu pourrais même fitter une spline.
    Ensuite, tu peux appliquer une dérivée, tu n'auras plus de bruit.
    Consignes aux jeunes padawans : une image vaut 1000 mots !
    - Dans ton message respecter tu dois : les règles de rédaction et du forum, prévisualiser, relire et corriger TOUTES les FAUTES (frappes, sms, d'aurteaugrafe, mettre les ACCENTS et les BALISES) => ECRIRE clairement et en Français tu DOIS.
    - Le côté obscur je sens dans le MP => Tous tes MPs je détruirai et la réponse tu n'auras si en privé tu veux que je t'enseigne.(Lis donc ceci)
    - ton poste tu dois marquer quand la bonne réponse tu as obtenu.

  4. #4
    Membre régulier
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Novembre 2006
    Messages
    296
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Drôme (Rhône Alpes)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Matériel informatique

    Informations forums :
    Inscription : Novembre 2006
    Messages : 296
    Points : 99
    Points
    99
    Par défaut
    Bonsoir,
    merci kolodz mais mon système doit fonctionner en temps réel donc je ne peux pas anticiper les valeurs pour créer des buffers PréValue et PostValue. Mais je garde ton code sous le coude.
    Merci Toto13 par contre je n'ai pas compris "fitter une spline" mais je suppose que c'est un post traitement.

    Merci

    edit:
    Je viens d'essayer le principe de moyenne flottante mais je trouve les même résultats après le calcul de la dérivée.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    size = 40;
    matrix = zeros(size,1);
    last =0;
    for k=2:s
        %decale le tableau
        for j=1:(size-1)
            matrix(size-j+1) = matrix(size-j);
        end
        %charge avec la nouvelle valeur
        matrix(1) = Pot(k);
        somme =0;
        for j=1:size
            somme = somme + matrix(j);
        end
        %calcule la moyenne
        somme = somme / size;
        Moy(k) = somme;
     
        %calcule la dérivée
        DeriveeMoy(k) = Moy(k)- last;    
        last = Moy(k);    
    end
     
    plot(Moy,'k');
     
    DeriveeMoy =DeriveeMoy *100;
    plot(DeriveeMoy,'c');
    Une autre idée

  5. #5
    Modérateur
    Avatar de kolodz
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Avril 2008
    Messages
    2 211
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 36
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Produits et services télécom et Internet

    Informations forums :
    Inscription : Avril 2008
    Messages : 2 211
    Points : 8 316
    Points
    8 316
    Billets dans le blog
    52
    Par défaut
    Avec ce que je te propose tu es en temps réel.
    Cependant, tu as un délai sur la détection des des changements de sens dû au filtre "passe bas" provoquer par la moyenne flottant.
    Personnellement, je trouve le résultat correct :
    Nom : Résultat.png
Affichages : 185
Taille : 156,8 KoNom : Résultat_zoom.png
Affichages : 197
Taille : 179,8 Ko
    Sachant que j'ai modifié la configuration à :
    size = 10
    seuil = 1

    Voici le code java correspondant :
    J'utilise ton fichier de log sans l'espace en début de chaque ligne comme entré
    Code java : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    140
    141
    142
    143
    144
    145
    146
    147
    148
    package aide.forum.developpez;
     
    import java.awt.Color;
    import java.io.BufferedReader;
    import java.io.File;
    import java.io.FileReader;
    import java.io.IOException;
     
    import org.jfree.chart.ChartFactory;
    import org.jfree.chart.ChartPanel;
    import org.jfree.chart.JFreeChart;
    import org.jfree.chart.plot.PlotOrientation;
    import org.jfree.chart.plot.XYPlot;
    import org.jfree.data.xy.XYDataset;
    import org.jfree.data.xy.XYSeries;
    import org.jfree.data.xy.XYSeriesCollection;
    import org.jfree.ui.ApplicationFrame;
    import org.jfree.ui.RefineryUtilities;
     
    public class Algo extends ApplicationFrame {
     
    	public Algo(String title) {
    		super(title);
    		final XYDataset dataset = createDataset();
    		final JFreeChart chart = createChart(dataset);
    		final ChartPanel chartPanel = new ChartPanel(chart);
    		chartPanel.setPreferredSize(new java.awt.Dimension(500, 270));
    		setContentPane(chartPanel);
    	}
     
    	/**
             * @param args
             */
    	public static void main(String[] args) {
    		// TODO Auto-generated method stub
    		final Algo demo = new Algo("Développez : Détection du changement de sens");
    		demo.pack();
    		RefineryUtilities.centerFrameOnScreen(demo);
    		demo.setVisible(true);
    	}
     
    	/**
             * Creates a sample dataset.
             * 
             * @return a sample dataset.
             */
    	private XYDataset createDataset() {
     
    		final XYSeries series1 = new XYSeries("Entré");
    		final XYSeries series2 = new XYSeries("Moyenne");
    		final XYSeries series3 = new XYSeries("Résultat");
    		File file = new File("C:\\devel\\test\\developpez\\LogCapteur.log");
    		try {
    			BufferedReader buff = new BufferedReader(new FileReader(file));
     
    			try {
    				String line;
    				int offset = 0;
    				int size = 10;
    				int pos =0;
    				int[] bufferOld = new int[size];
    				int[] buffer = new int[size];
    				boolean isAugement = true;
    				while ((line = buff.readLine()) != null) {
    					int value = Integer.parseInt(line);
    					series1.add(offset, value);
    					offset++;
    					bufferOld[pos] = buffer[pos];
    					buffer[pos] = value;
    					pos++;
    					if(pos ==size){
    						pos =0;
    					}
    					int delta = 1;
    					series2.add(offset, getMoyen(buffer));
    					if( getMoyen(buffer)> (getMoyen(bufferOld)+delta) ){
    						if(!isAugement){
    							isAugement = true;
    						}
    					} else if(getMoyen(buffer)<(getMoyen(bufferOld)-delta)) {
    						if(isAugement){
    							isAugement = false;
    						}
    					}
    					if(isAugement){
    						series3.add(offset, 1000);
    					} else{
    						series3.add(offset, 0);
    					}
    				}
    			} finally {
    				// dans tous les cas, on ferme nos flux
    				buff.close();
    			}
    		} catch (IOException ioe) {
    		}
     
    		final XYSeriesCollection dataset = new XYSeriesCollection();
    		dataset.addSeries(series1);
    		dataset.addSeries(series2);
    		dataset.addSeries(series3);
     
    		return dataset;
     
    	}
     
    	private int getMoyen(int[] buffer) {
    		int somme = 0;
    		for (int i = 0; i < buffer.length; i++) {
    			somme += buffer[i];
    		}
    		return somme/buffer.length;
    	}
     
    	/**
             * Creates a chart.
             * 
             * @param dataset
             *            the data for the chart.
             * 
             * @return a chart.
             */
    	private JFreeChart createChart(final XYDataset dataset) {
     
    		// create the chart...
    		final JFreeChart chart = ChartFactory.createXYLineChart(
    				"Développez : Détection du changement de sens", // chart title
    				"X", // x axis label
    				"Y", // y axis label
    				dataset, // data
    				PlotOrientation.VERTICAL, true, // include legend
    				true, // tooltips
    				false // urls
    				);
     
    		// NOW DO SOME OPTIONAL CUSTOMISATION OF THE CHART...
    		chart.setBackgroundPaint(Color.white);
     
    		// get a reference to the plot for further customisation...
    		final XYPlot plot = chart.getXYPlot();
    		plot.setBackgroundPaint(Color.lightGray);
    		plot.setDomainGridlinePaint(Color.white);
    		plot.setRangeGridlinePaint(Color.white);
     
    		return chart;
     
    	}
    }

    Cordialement,
    Patrick Kolodziejczyk
    Si une réponse vous a été utile pensez à
    Si vous avez eu la réponse à votre question, marquez votre discussion
    Pensez aux FAQs et aux tutoriels et cours.

  6. #6
    Membre régulier
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Novembre 2006
    Messages
    296
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Drôme (Rhône Alpes)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Matériel informatique

    Informations forums :
    Inscription : Novembre 2006
    Messages : 296
    Points : 99
    Points
    99
    Par défaut
    je vais essayer dans la journée, ça marche nickel reste plus qu'à voir en pratique.
    Merci

  7. #7
    Modérateur
    Avatar de ToTo13
    Homme Profil pro
    Chercheur en informatique
    Inscrit en
    Janvier 2006
    Messages
    5 793
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 45
    Localisation : Etats-Unis

    Informations professionnelles :
    Activité : Chercheur en informatique
    Secteur : Santé

    Informations forums :
    Inscription : Janvier 2006
    Messages : 5 793
    Points : 9 860
    Points
    9 860
    Par défaut
    Citation Envoyé par sdecorme Voir le message
    Merci Toto13 par contre je n'ai pas compris "fitter une spline" mais je suppose que c'est un post traitement.
    Faire passer une spline/courbe par les points.
    Consignes aux jeunes padawans : une image vaut 1000 mots !
    - Dans ton message respecter tu dois : les règles de rédaction et du forum, prévisualiser, relire et corriger TOUTES les FAUTES (frappes, sms, d'aurteaugrafe, mettre les ACCENTS et les BALISES) => ECRIRE clairement et en Français tu DOIS.
    - Le côté obscur je sens dans le MP => Tous tes MPs je détruirai et la réponse tu n'auras si en privé tu veux que je t'enseigne.(Lis donc ceci)
    - ton poste tu dois marquer quand la bonne réponse tu as obtenu.

  8. #8
    Membre régulier
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Novembre 2006
    Messages
    296
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Drôme (Rhône Alpes)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Matériel informatique

    Informations forums :
    Inscription : Novembre 2006
    Messages : 296
    Points : 99
    Points
    99
    Par défaut
    mais ça ne marche qu'en post-traitement ? pas ne temps réel je suppose.

  9. #9
    Modérateur
    Avatar de ToTo13
    Homme Profil pro
    Chercheur en informatique
    Inscrit en
    Janvier 2006
    Messages
    5 793
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 45
    Localisation : Etats-Unis

    Informations professionnelles :
    Activité : Chercheur en informatique
    Secteur : Santé

    Informations forums :
    Inscription : Janvier 2006
    Messages : 5 793
    Points : 9 860
    Points
    9 860
    Par défaut
    Tu la fais passer par les points précédents, tout comme tu traites les points déjà existants/connus.
    Consignes aux jeunes padawans : une image vaut 1000 mots !
    - Dans ton message respecter tu dois : les règles de rédaction et du forum, prévisualiser, relire et corriger TOUTES les FAUTES (frappes, sms, d'aurteaugrafe, mettre les ACCENTS et les BALISES) => ECRIRE clairement et en Français tu DOIS.
    - Le côté obscur je sens dans le MP => Tous tes MPs je détruirai et la réponse tu n'auras si en privé tu veux que je t'enseigne.(Lis donc ceci)
    - ton poste tu dois marquer quand la bonne réponse tu as obtenu.

Discussions similaires

  1. Algorithme d'évaluation pour détection de changement
    Par eviasra dans le forum Traitement d'images
    Réponses: 3
    Dernier message: 12/01/2012, 12h56
  2. détection de changement brusque des couleurs
    Par zidenne dans le forum Composants VCL
    Réponses: 2
    Dernier message: 07/02/2006, 21h26
  3. Réponses: 2
    Dernier message: 23/01/2006, 11h55
  4. Changement de tablespace pour une table
    Par slyv dans le forum Oracle
    Réponses: 5
    Dernier message: 28/04/2005, 20h46
  5. changement de type pour un champ dans une table
    Par Missvan dans le forum PostgreSQL
    Réponses: 2
    Dernier message: 23/02/2004, 15h26

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo