(veuillez lire la mise à jour 3 à la fin) Je développe une application qui fonctionne continuellement avec les capteurs du périphérique, fonctionne avec Les accéléromètres peuvent mettre à jour des centaines de fois une seconde ... p>
BlockQuote> Je ne dois pas perdre de données que les capteurs rapportent et je souhaite également faire des opérations de consommation de temps sur ces données (récupérer l'orientation, puis effectuer des calculs ...). J'ai décidé de résoudre mon problème en utilisant et p> maintenant je Ramassez mon appareil et faites-le pivoter à environ 90 degrés à droite puis retournez-le à la première position rapide (par exemple en 1,5 seconde), mais lorsque je regarde les orientations enregistrées dans l'appareil que je vois par exemple: 0,1,2 , 3,4,5 ......., 40,39,38,37, ...., 0 p> Je veux juste dire que aucune idée, Solution ?! P> Cordialement! P> Mise à jour 1: Strong> J'ai fait une autre expérience avec mon appareil et obtenu des résultats choquants! Si je fais pivoter mon appareil sur un axe de 90 degrés rapidement (moins d'une seconde), je peux voir tous les degrés dans mon résultat: 0,1,2,3, ...., 89,90 (par exemple) mais si je Faites-les pivoter à 90 degrés puis faites pivoter à sa première position, le résultat serait de 0,1,2, ..., 36,37,36, ... 2,1,0 (par exemple) ... vraiment Confusion! P> Mise à jour 2: strong> i Docalculations mises à jour () Méthode pour être plus claire ce que j'ai fait P> Mise à jour 3: Je pense que nous pouvons peut-être résoudre le problème d'une autre manière! J'ai clairement des objectifs pour ce code. Veuillez consulter Ce . je
ont mentionné ce qui va se passer, j'ai besoin de détecter un spécifique
geste de mouvement. alors peut-être que tout ce que j'ai choisi (le
La technique ci-dessus n'est pas un bon moyen de résoudre ce problème. peut être
il vaut mieux détecter ce geste en utilisant d'autres capteurs ou en utilisant le
mêmes capteurs dans l'autre sens. que pensez-vous? strong> p>
blockQuote> p> accéléromètre code> et
des capteurs magnétiques code> pour récupérer le L'orientation de l'appareil (le but est mentionné ici < / a>). En d'autres termes, mon application doit connaître l'orientation de l'appareil en temps réel (mais cela n'est jamais possible, le plus rapidement possible, mais aussi vite que possible fort>!). Comme mentionné dans Professional Android 4 Développement d'applications de Reto Meier em>:
linkedblockingqueue code>: p>
7 Réponses :
- Changer la déclaration de variable: li> ol>
xxx pré>
- à l'intérieur de la runnable: li> ol> blockQuote>
xxx pré> blockquote>
LinkedBlockinQueue est conçu pour gérer plusieurs threads mais pas les fils amotiques où vous mettez et lisez et supprimez en même temps. combinaison syncronizedlist et itérateur fonctionnent.
Merci, je vais l'essayer demain et vous laissera savoir le résultat :)
Comme vous pouvez le constater dans mon code, le Runnable est exécuté une fois, vous avez maintenant mis itérateur
L'itérateur à l'intérieur de votre (;;) pour (;;) {Ici le code en mode boucle. }
Votre code a 2 problèmes: 1.Vous ne supprimez jamais aucun élément de array code> 2.J'ai lu
itérateur code> Documentation, il n'est pas recommandé pour la synchronisation, il est à des fins de débogage. .
@toto qui n'a aucun sens: BlockingQuuesues est déjà en sécurité (et par la manière dont la boucle que vous proposez n'est pas ...).
On dirait donc que vous essayez de trouver une solution à haut débit à faible latence pour un problème standard de "producteur-consommateur". Fondamentalement, l'idée est assez simple: diminuer les frais de manipulation des données, les données de traitement en parallèle. Les suggestions sont les suivantes: p>
N'importe laquelle de ces solutions vous permettra de sauver beaucoup de cycles CPU. P>
Il y a une surcharge à chaque fois que vous soumettez un emploi. Le traitement par lots peut être vraiment utile. P>
Traiter les données de manière continue. Remarque, Par exemple, supprimez-vous de Performance de piste tout le temps afin d'identifier de bonnes et de mauvaises solutions. Expérimenter. P>
codage heureux. P>
p>
p>
exécuteur.execute code> consommera beaucoup. Plusieurs consommateurs de longue date pourraient aider. P>
if-else-si code> en faveur du commutateur
code>. P>
Les choses que vous avez suggéré sont très utiles pour résoudre des problèmes de latence, mais en ce moment, sur la base des expériences que j'ai mentionnées ci-dessus et que je connaisse au moins, je peux être sûr que rien n'est perdu, ou laissez-moi dire que j'ai toutes les données que les capteurs donnent que les capteurs donnent moi parce que juste après avoir reçu de nouvelles données qui vient d'être enregistrées ... c'est pourquoi je suis fou et confus :(
Des idées intéressantes mais votre graphique n'inclut que des collections qui à ma connaissance ne sont pas en sécurité. Je ne sais pas combien de différence vous trouverez entre Java.Util.ConCurrent et le perturbateur par exemple. Il pourrait être utile d'essayer d'abord d'essayer d'autres implémentations de la file d'attente (ArrayBlockingQueue par exemple). Je suggère également d'essayer de vous débarrasser des variables partagées qui engagent une pénalité vs variables locales.
Juste pensant: veuillez essayer ce qui suit:
public void startSensors() { final Stack<Runnable> mStack = new Stack<Runnable>(); sensorListenerForOrientation = new SensorEventListener() { @Override public void onSensorChanged(SensorEvent event) { if (event.sensor.getType() == Sensor.TYPE_ACCELEROMETER) aValues = (event.values.clone()); else if (event.sensor.getType() == Sensor.TYPE_MAGNETIC_FIELD) mValues = (event.values.clone()); if (aValues != null && mValues != null) { mStack.push(new Calculater(new float[][] { aValues, mValues }); } } @Override public void onAccuracyChanged(Sensor sensor, int accuracy) { } }; Sensor aSensor = sm.getSensorList(Sensor.TYPE_ACCELEROMETER).get( sm.getSensorList(Sensor.TYPE_ACCELEROMETER).size() - 1); Sensor mSensor = sm.getSensorList(Sensor.TYPE_MAGNETIC_FIELD).get( sm.getSensorList(Sensor.TYPE_MAGNETIC_FIELD).size() - 1); sm.registerListener(sensorListenerForOrientation, aSensor, SensorManager.SENSOR_DELAY_FASTEST); sm.registerListener(sensorListenerForOrientation, mSensor, SensorManager.SENSOR_DELAY_FASTEST); new Thread() { public void run() { while(true) { try { Runnable r = mStack.pop(); r.run(); } catch(Exception ex){} } } }.start(); } private class Calculater implements Runnable { float[][] theValues; public Calculater(float[][] values) { theValues = values; } public void run() { int[] degrees= getOrientation(theValues[0], theValues[1]); Log.e("",String.valueOf(degrees[0])); } }
Merci, travaille bien, mais toujours le problème que j'ai mentionné dans la mise à jour 1 existe !!! Intéressant, pas ?!
Ce devrait être une file d'attente au lieu de la pile (ma faute). Si cela perd encore certaines valeurs, le problème est dans le capteur et non le code
C'est ce qui ne va pas avec votre code. Rapide que possible nécessite des techniques de codage rapides. Enregistrez le type de capteur au lieu de l'évaluer deux fois.
@Override public void onSensorChanged(SensorEvent event) { int i = event.sensor.getType(); if (i == Sensor.TYPE_ACCELEROMETER) aValues = (event.values.clone()); else if (i == Sensor.TYPE_MAGNETIC_FIELD) mValues = (event.values.clone()); }
Hein ... non - && code> retournera false si l'un des deux est null. Le court-circuit n'arrivera que si le premier est NULL (et reviendra faux). Quant à la micro optimisation que vous suggérez, il est probablement assez insignifiant pour peu importe
Mon mauvais sur le court-circuit. Je vais le modifier. Je vois que la micro optimisation est ce que vous avez demandé, mais aussi aussi vite que possible!). Comme mentionné dans Professional Android 4 Développement d'applications de Reto Meier: il enregistre 2 opérations 100 plus une seconde.
Votre code semble raisonnable. Un grand inconnu est la qualité des capteurs et de la fusion des capteurs dans votre appareil. Les lectures de changements à angle rapides s'appuient sur l'intégration de l'accélération angulaire ou d'un gyroscope physique avec des données magnétiques mélangées pour rendre le résultat alignement absolument avec la Terre. Les données magnétiques sont soumises à des environs. Si votre appareil dispose de capteurs de qualité inférieure ou des perturbations magnétiques dans votre environnement sont tout à fait possible de voir les types d'erreur que vous voyez. Les grosses structures métalliques et les équipements magnétiques (comme moteurs ou même des ballasts de lumière fluorescente) peuvent vider le champ ou introduire des erreurs arbitraires. Pour les utilisations normales, un périphérique n'a besoin que d'un accéléromètre pour déterminer avec précision quelle manière est en panne afin que les retourcisseurs d'écran soient précis. Cela doit seulement fonctionner lorsque l'appareil ne bouge pas, où un gyroscope n'a aucun rôle. Si vous avez un téléphone ou un comprimé avec des capteurs signifiait uniquement pour servir cet objectif - donc sans gyroscope ou inexact - vous voyez une limitation de périphérique. Les valeurs erratiques sont d'autres preuves que votre appareil est de mauvaise qualité et / ou que vous êtes dans un endroit où le champ magnétique de la Terre est déformé. Essayez le programme sur un autre périphérique (de préférence coûteux) à l'extérieur et à l'air libre, et voyez ce que vous obtenez. p>
Merci pour vos idées différentes i>, mais avez-vous lu la mise à jour 2? Je ne peux pas comprendre cela, pourquoi faire tourner sur un axe rapide me donne ce que je veux B> Cependant, peut-être de la latence, mais si je fais pivoter le dispositif, puis le retourne à la première position, les choses changent complètement et une autre choquante ( !) Le résultat est vu ...?
Pensez-vous qu'utiliser gyroscope capteur i> dans la récupération d'orientation peut aider?
@Soheil j'ai lu toutes les mises à jour. Le point est que si le périphérique dispose d'un système de capteur basse résolution sans gyroscope physique, seul le vecteur bas sera fiable et uniquement lorsque l'appareil est stationnaire. North sera raisonnablement correct si vous êtes loin du grand métal et des aimants. Il est possible que la rotation rapide fonctionne mieux avec du matériel bon marché, tandis que la rotation plus lente est soumise à plus d'erreur. Cela serait cohérent avec le périphérique sans matériel gyroscope. L'iPhone n'avait pas de gyroscope avant V4. Si votre appareil Android est vieux ou bon marché, cela peut ne pas en avoir un, non plus.
J'ai donc reçu que si je peux utiliser le capteur gyro à côté de l'accéléromètre et de magnétiques, je peux obtenir un meilleur résultat, mais cela n'est pas disponible dans tous les appareils.Correct ?!
Il semble que la façon dont j'ai choisi de résoudre mon problème (détecter un geste: Stackoverflow.com/Questtions/18811780/... ) n'est pas fiable et raisonnable et je dois penser différent . Qu'est-ce que tu penses? une idée?
@Soheil quelle est la grande image? Quel genre de logiciel est-ce? Jeu? Il y a une raison pour laquelle tous les écrivains de jeu étaient tellement excités lorsque l'iPhone 4 a ajouté un gyroscope matériel. Il a rendu des gestes beaucoup plus pratiques. Si votre appareil n'a pas de gyroscope, il sera difficile de résoudre tout type de résolution. Vous pouvez essayer d'écrire directement sur le développeur.android.com / Guide / Thèmes / Capteurs / ... API GYRO pour voir ce que vous obtenez.
Non, ce n'est pas un jeu, c'est une application simple qui veut détecter ce geste de mouvement. Comme tous les appareils n'ont pas de gyroscope, il n'est donc pas fiable d'utiliser un capteur gyroscope dans des calculs, d'autre part à l'aide de accéléromètre code> et
des capteurs magnétiques code> Sans résultat. Donc, je suis vraiment fou que de détecter ce geste avec les choses que nous avons dans nos mains !!!!
La chose habituelle à faire dans un bloc d'événement est de ne rien faire, car cela est vraiment rapide. "Presque" étant le mot important. Dans votre cas, l'événement peut simplement ajouter les données de l'événement (à partir du paramètre d'événement) à une structure de données (liste, pile, tampon circulaire ... votre choix). De cette façon, vous devriez perdre moins d'événements (le cas échéant). P>
Ce qui signifie que vous pouvez alors (par exemple) lire les événements stockés et décider si un geste a été fait. Cela signifie que vos calculs intensives sont faits moins souvent. Mais vous ne perdez aucun événement. Je pense que cela est acceptable à cause de votre objectif, qui est la reconnaissance de geste. Je suppose que cela n'a pas besoin d'être aussi rapide (c'est-à-dire que vous n'avez pas à le calculer à chaque fois que les mises à jour du capteur). P>
Remarque: il s'agit d'un moyen courant de le gérer dans le monde Linux. P>
Ce que vous avez suggéré n'équègue pas de résoudre le problème dans mon cas car je ne perds aucune donnée. Donc, la mauvaise chose qui peut arriver est la latence dans les calculs, mais les calculs sont effectués pour toutes les données. Votre suggestion peut m'aider avec la latence et c'est en fait une bonne idée de résoudre le problème de la latence, Thnax! Mais toujours le principal problème survit :(
Je vois. Merci de commenter, et je suis heureux que ma réponse soit quelque peu utile. Bonne chance pour vous résoudre de problème!
Juste une pensée. J'ai un problème similaire lorsque j'ai besoin de collecter plusieurs grandes tailles d'échantillons d'effectuer des calculs performants. Ma situation était probablement très différente de la vôtre car j'avais juste besoin d'accélération. Ce que j'ai fait était de créer une liste de matrices. Accélération calculée par chaque enregistrement rapporté:
@Override public void onSensorChanged(SensorEvent event) { float x = event.values[0]; float y = event.values[1]; float z = event.values[2]; float acceleration = FloatMath.sqrt((x * x) + (y * y) + (z * z));
Quelles sont les valeurs et les valeurs de votre auditeur? Variables partagées? Avez-vous essayé de vous connecter à chaque événement dans l'auditeur pour vérifier si vous vous manquez?
Variables globales: Valeurs du flotteur public [], valeurs;
Oui, j'ai compris que je ne manque rien, le problème est un peu où ... (Je vais mettre à jour mon poste maintenant et mentionner de nouvelles choses)
@assylia s'il vous plaît voir la mise à jour ...
Où obtenez-vous les valeurs de (1,2,3 ... 37,36, ...)? De connecter tous les événements sur la première ligne de votre auditeur? Si oui, alors c'est un problème avec le capteur / comment accéder à ses données, sinon cela pourrait être une question de concurrence. Veuillez indiquer clairement ce point.
@assylias j'ai mis à jour mon code (méthode de docalculation ())
Pourquoi n'essayez-vous pas de connecter tous les événements sur la première ligne de votre auditeur? Si les deux listes d'événements (dans l'auditeur et de la docalculation) sont les mêmes, le problème est avec l'auditeur / capteur, s'ils sont différents, le problème est avec votre code, probablement une question de concurrence. Au moins cela affaimera le problème.
@assylias j'ai essayé ce que vous avez suggéré. Les deux listes sont identiques! Donc, le problème semble provenir de capteurs. Mais lisez ce que j'ai mentionné dans le paragraphe de mise à jour, que je suis vraiment confondu :(
Votre dernière mise à jour (expérimentation) et votre dernier commentaire en font une question très intéressante. Je vous suggère de supprimer tout le code dans les docalculations et de connecter simplement les valeurs.
@ Shériifelkhatib Les résultats de la journalisation disent que rien n'est perdu, alors où le problème vient? Je ne sais pas :((((((
S'il vous plaît lire la mise à jour 3!