9
votes

Fonctions trigonométriques sur le système embarqué

sin et cos Les fonctions sont lentes et nécessitent beaucoup de ressources pour exécuter des systèmes embarqués. Comment calculer sin et cos fonctionne d'une manière plus économe de ressources et plus rapide?


1 commentaires

Si l'argument d'entrée est «angle», la table de recherche est bonne, mais s'il ne s'agit que d'Opp-côté et d'hypoténuse, vous pouvez simplement utiliser la division avec une précision réduite


11 Réponses :


16
votes

Pour calculer un Taylor ou La série Fourier va toujours prendre du temps.

Dans un système intégré, vous devriez penser à Tables de recherche .

Il peut également y avoir des informations intéressantes sur le "NET sur la manière dont Hewlett-Packard a optimisé de tels calculs dans leurs calculatrices scientifiques précoce.

Je me souviens de voir de telles choses à l'heure


9 commentaires

Une simple table de 256 éléments vous donnera une petite section de sinus; Tout le reste peut être dérivé à travers des règles de symétrie simples.


Oui, il semble que je me souvienne de voir ce genre de chose décrit dans l'explication de HP de leurs algorithmes de calculatrice.


Pour clarifier, le problème avec une série Taylor n'est pas une vitesse, mais une précision de vitesse combinée. C'est probablement la méthode la plus rapide pour les calculs de faible précision, mais ne fonctionne pas trop bien si vous voulez de nombreux décimaux. Les séries de Fourier ne sont pas pertinentes ici.


Oui, les tables de recherche sont idéales. +1


Si je me souviens bien d'une table de recherche d'entrée 512 pour 0..90 °, normalisé à 0..2 ^ 15 donne - avec une interpolation linéaire - jusqu'à 21 bits de précision. Ce n'est que deux morceaux qui mène qu'un sinistre approprié.


Et il n'y a bien sûr aucune raison de s'en tenir à une interpolation linéaire. Le péché (x) est plutôt bien élevé, une interpolation donc plus élevée fonctionne également. En substance, il y a un continuum complet entre "toutes les données, aucune interpolation" et "sin (0) = 0, sin (90) = 1, interpolez tout le reste".


Vous n'avez besoin que de 0 à 45 ° avec une table. Tout le reste est symétrique à cela. 256 entrées dans le tableau vous donne 0,17 ° étapes. De combien de résolution avez-vous besoin?


Il y a de bonnes chances avec un système intégré que vous n'ayez pas besoin d'intrants arbitraires non plus. Si cela provient d'un codeur mécanique, combien d'angles uniques pourriez-vous obtenir? Une table de recherche est la réponse naturelle.


@ S.Lott - Pouvez-vous clarifier le bit "0 à 45 °"? J'imagine que vous auriez besoin de 0 à 45 ° pour des tables sinusoïdales et de cosinus, ou de 0 à 90 ° pour une table sinusoïdale.



0
votes

Il semble y avoir une belle pseudocode exemple ici et code explicite < Un href = "http://bytes.com/topic/c/answers/554487-utilisateur-taylor-series" rel = "nofollow noreferrer"> ici .

Cependant, comme @unwind suggérait, vous pouvez essayer de précalculer ces tables sur un ordinateur décent et de charger les tables sur le périphérique incorporé.

Si votre réponse ne doit pas nécessairement être très exacte, la table de recherche serait plutôt petite, et vous pourrez le stocker dans la mémoire de votre appareil. Si vous avez besoin d'une plus grande précision, vous devrez le calculer dans l'appareil. C'est un compromis entre la mémoire, le temps et la précision requise; La réponse repose sur la nature spécifique de votre projet.


0 commentaires

2
votes
  1. Tables Lookup
  2. Taylor Series , comme vous dites

    Notez que avec des tables de recherche, vous pouvez souvent optimiser les choses en limitant le domaine, par exemple. Représenter l'angle comme un caractère non signé, vous donnant seulement 256 marches autour du cercle, mais aussi une table très compacte. Des choses similaires peuvent être faites à la valeur, comme utiliser un point fixe.


0 commentaires

4
votes

dépend de ce que vous en avez besoin. Si vous n'êtes pas très préparé à propos de votre précision d'angle (par exemple, votre diplôme le plus proche est correct), utilisez simplement une table de valeurs de recherche. Si vous n'avez pas de FPU, travaillez dans point fixe .

Un moyen simple de Calculer Les fonctions SIN / COS sont avec la série Taylor (comme indiqué sous les fonctions trigonométriques ici ). Les moins de termes que vous utilisez, moins les valeurs sont précises, mais plus les calculs sont plus rapides.

Les calculs de la série Fourier exigent que certaines valeurs SIN / COS soient connues. Si vous stockez des choses dans le domaine de fréquence la plupart du temps, cependant, vous pouvez potentiellement économiser sur Calculs - en fonction de ce que vous faites.


0 commentaires

10
votes

Une table de recherche avec interpolation serait sans aucun doute la solution la plus efficace. Si vous souhaitez utiliser moins de mémoire toutefois, Cordic est un algorithme assez efficace pour calculer les valeurs de trigle fonctions et est couramment implémentée dans des calculatrices de poche.

En tant que point secondaire, il n'a aucun sens de représenter ces fonctions à l'aide de séries Fourier, car vous créez un problème circulaire de la manière dont vous évaluez ensuite les termes SIN / COS de la série. Une série Taylor est une méthode d'approximation bien connue, mais l'erreur s'avère inacceptable dans de nombreux cas.

Vous voudrez peut-être aussi vérifier Cette question et ses réponses , En ce qui concerne les fonctions trigonométriques rapides pour Java (le code pourrait donc être porté facilement). Il mentionne à la fois les approximations cordies et chebyshev, entre autres. L'un d'entre eux conviendra sans aucun doute vos besoins.


1 commentaires

Y a-t-il un lien manquant pour "Consulter cette question"?



2
votes

Voir la question de dépassement de pile Comment fonctionner les fonctions trigonométriques? La réponse acceptée Il explique certains détails de la réduction de la portée, puis d'utiliser Cordic, puis de faire d'autres optimisations.


0 commentaires

4
votes

Cet article du Dr Dobb: Optimiser les applications à forte intensité de mathématiques avec arithmétique à point fixe a Une bonne explication des algorithmes cordies et fournit un code source complet pour la bibliothèque discutée dans l'article.


0 commentaires

0
votes

Dans certains cas, on peut gérer avec juste filtre IIR, réglé sur la résonance sur la fréquence requise. Regardez ici: http: // www. ee.ac.ac.uk/pcheung/Teaching/ee3_study_project/sinewave%20Generation(708).pdf


0 commentaires

0
votes

Cela peut être d'une certaine aide / inspiration: racine carrée magique dans la Quake III


3 commentaires

Les racines carrées ont peu à voir avec le péché / cos. Ils sont plutôt triviaux à calculer. Un peu lent si vous le faites de manière simple, mais trivial. Pour le péché / COS, la méthode pour calculer des racines carrées serait inutile, comme vous ne pouviez pas améliorer vos approximations sans, disons, une table de sinistres. Et pour le règlement de la séisme ... Oooboy. Ce n'est pas utile du tout en dehors du contexte de trouver une racine carrée. C'est pure hackery, pas un vrai exemple de mathématiques utiles.


Je réalise SQRT! = SINS / COS, c'était plus sur le processus de pensée derrière le code et que la possibilité de compromettre la précision de la vitesse en utilisant des approximations intelligentes pour une application donnée.


John, je viens de lire cet article et quelques-uns quelques-uns d'associés concernant l'itération NR et la constante magique. Thx pour le lien. Cela m'a certainement donné des inspirations sur l'utilisation de solutions intelligentes. +1



0
votes

Vous pouvez jeter un coup d'œil à cette bibliothèque de points fixe arbitraire pour les microcontrôleurs AVR 8 bits: https://community.atmel.com/projects/afp-arbitra- Correction-Point-Lib

Modifier: Link Mise à jour


2 commentaires

Ces deux liens sont morts. Aurait été super de copier des bibliothèques ici.


J'ai mis à jour le lien. La source est trop grosse pour copier / coller ici.



0
votes

Je suis un peu en retard à la fête, mais de toute façon je veux partager une solution efficace à l'emploi qui utilise une table de recherche (générateur de table incluse): dftrig .

dftrig se compose de deux parties:

  • Générateur de table de recherche TABLEN (écrit en Java, mais cela n'a pas beaucoup d'importance) qui reçoit plusieurs options et produit Code C (ConstTR STRY avec la table de recherche)
  • petit module C qui fonctionne avec la table de recherche générée par tableggen .

    Bien sûr, la table de recherche ne contient que des informations minimales: Valeurs sinusoïdales pour un seul quadrant, c'est-à-dire [0, 90] degrés. C'est assez assez pour calculer le sinus pour n'importe quel angle.

    Le comportement est tout à fait personnalisable. Vous pouvez spécifier:

    • facteur par lequel chaque élément de la table de recherche est multiplié (à la base de la table);
    • pas en degrés entre chaque élément du tableau (sur la base de la table); Type d'éléments dans le tableau (commun pour l'ensemble du projet C).

      Donc, en fonction de vos besoins, vous pouvez:

      • génère une table unique pour l'ensemble de l'application avec un facteur max, de sorte que tout sous-système de votre projet C puisse utiliser cette seule table, fournissant facteur souhaité, et il sera recalculé si le facteur demandé est autre que celui de la table;
      • Générez plusieurs tables, chacun avec facteur ad hoc, et chaque sous-système de votre projet C utilise sa table dédiée. Ensuite, les valeurs peuvent être renvoyées de la table commee, sans recalculation; cela fonctionne plus rapidement.

        Je l'utilise dans mes projets intégrés, cela fonctionne bien.


0 commentaires