Trigonométrie à point fixe pour les applications intégrées

9

J'ai besoin de faire des transformations rotationnelles (et autres) dans une application embarquée, nécessitant les fonctions sin () cos () et tan (). Je sais que vous pouvez utiliser des tables de recherche, et c'est la seule solution que je pourrais trouver en faisant mes propres recherches, mais y a-t-il une bonne bibliothèque de trig à virgule fixe?

Je pense utiliser un cortex M3 pour l'application, donc je veux rester le plus loin possible de la virgule flottante pour garder les applications zippées.

Bob
la source
Deux réflexions: une implémentation primitive traditionnelle de la rotation est l'algorithme CORDIC. Vous pouvez également voir si votre fournisseur propose désormais un Cortex M4 compétitif avec le M3 que vous envisagiez.
Chris Stratton
4
Pourquoi ne voulez-vous pas utiliser des tables de recherche? Cela fonctionne très bien pour le péché et le cos. Faire du péché et du cos par algorithme va prendre plus de temps. Le seul avantage est peut-être moins d'espace mémoire utilisé, mais est-ce vraiment important dans votre application?
Olin Lathrop du
@OlinLathrop, je veux savoir ce que les autres ont trouvé: peut-être un moyen efficace de résoudre rapidement le problème avec peu d'erreur tout en économisant de l'espace mémoire existe que je n'ai pas trouvé? D'après ce que je sais (et je peux me tromper), le plus gros problème pour résoudre algorithmiquement avec les bibliothèques standard est que tout le calcul est fait en virgule flottante, et sans FPU, tout doit être fait numériquement, ce qui est terriblement inefficace. .. Le plus gros problème avec les tables de recherche est: à quel point dois-je être précis? Et si cette précision change, aurai-je encore suffisamment de mémoire programme?
Bob
De quelle précision avez-vous besoin? Des tables de recherche de taille modeste sont tout à fait suffisantes pour la plupart des besoins de sin / cos intégrés. Avec 1025 entrées de table, vous obtenez une résolution d'angle de 4096. À ce stade, l'interoplation linéaire vous donne une bonne précision entre les entrées de table. Il semble y avoir beaucoup de mythes incorrects sur la recherche de sinus. Voir ma réponse sur electronics.stackexchange.com/a/16516/4512 pour plus de détails.
Olin Lathrop du
J'entends ce que vous dites et je comprends l'idée de la table de recherche pour la fonction sinus, mais si je suis limité en code (les projets remplissent toujours l'espace de code), existe-t-il une manière plus compacte de gérer cela? C'est pourquoi j'ai demandé: il y a beaucoup de gens talentueux qui contribuent et j'aimerais savoir s'ils ont trouvé mieux.
Bob

Réponses:

6

Une bonne approche pour faire de la trigonométrie dans des applications embarquées consiste à utiliser des approximations polynomiales des fonctions dont vous avez besoin. Le code est compact, les données se composent de quelques coefficients et les seules opérations requises sont la multiplication et l'addition / la soustraction. De nombreux systèmes embarqués ont des multiplicateurs matériels, ce qui donne de bonnes performances.

Dave Tweed
la source
1
Quelqu'un a-t-il publié une version de cela en C optimisée pour les applications intégrées n'utilisant pas d'instructions à virgule flottante? L'erreur élevée de chaque côté de l'approximation polynomiale se prête à l'utilisation d'astuces pour utiliser différents polynômes pour différents segments afin de réduire l'erreur, ou une autre astuce ...
Bob
1
Le C générique ne prend pas directement en charge les types de données à virgule fixe non entiers et les opérations, les optimisations pour ce type de données ont donc tendance à être assez spécifiques à la plate-forme. Par exemple, la plupart des DSP prennent en charge un type de données fractionnaire à virgule fixe directement dans leur matériel. Depuis C, vous y accédez via des bibliothèques propriétaires.
Dave Tweed
Le C générique gagne en prise en charge via le type de données _Fract, mais la plupart des implémentations de microcontrôleurs ont des bibliothèques spécifiques au fournisseur. J'utilise libmathq15 pour tous mes besoins en virgule fixe. A fait le travail jusqu'à présent.
légèrement
_Fractest un morceau de merde IMHO; Je déteste le fait qu'il ait été "standardisé" par le comité C. Cela vous oblige à utiliser Q15 ou Q31 pour tout, ce qui n'a pas de sens dans de nombreuses situations, et vous laisse bloqué sans aide pour ces situations.
Jason S
3

Êtes-vous opposé à l'utilisation des bibliothèques Cortex à virgule fixe pour cela?

q31_t arm_sin_q31 (q31_t x)
Approximation rapide de la fonction sinus trigonométrique pour les données Q31.

de:

CMSIS-DSP: Collection de bibliothèques DSP avec plus de 60 fonctions pour différents types de données: point fixe (fractionnaire q7, q15, q31) et virgule flottante simple précision (32 bits). La bibliothèque est disponible pour Cortex-M0, Cortex-M3 et Cortex-M4.

Il utilise une table de recherche avec interpolation quadratique, mais c'est assez rapide. Vous pouvez l'adapter à une interpolation linéaire pour une vitesse plus rapide mais plus d'erreurs.

Notez également que même Cortex M4 n'a pas nécessairement de FPU. Je les ai vus appelés "M4F" s'ils le font.

endolith
la source