trouver la longueur d’un arc sur un cercle

J’ai un problème intéressant (pour moi en tout cas). Je travaille sur OpenServo.org pour la V4 et j’essaie de déterminer la longueur d’un arc de déplacement et sa direction.

J’ai un encodeur magnétique qui renvoie la position de l’arbre de 0 à 4095.

Le servo a deux extrémités logiques, appelées MAX et MIN. Elles sont définies dans le logiciel et peuvent être changées à tout moment. L’arbre doit tourner (c.-à-d. Se déplacer) sur un arc entre les positions MAX et MIN. Par exemple, dans l’illustration, l’arc bleu est valide, mais le rouge ne s’applique pas à tous les déplacements compris entre MIN et MAX.

J’essaie d’élaborer un algorithme simple utilisant uniquement des mathématiques entières pouvant me dire la distance entre deux points quelconques A et B pouvant se trouver n’importe où sur la circonférence, délimités par MIN et MAX et avec A comme lieu actuel et B comme emplacement actuel. la position cible, ou B est le lieu actuel et A est la cible (ce qui correspond à une distance négative de B à A). Notez que le côté que j’ai autorisé à voyager est connu, c’est soit le “rouge”, soit le “bleu”.

Le problème est que lorsque 4095/0 existe dans l’ARC, les calculs deviennent un peu intéressants.

entrez la description de l'image ici

Voici un algorithme simple:

#include  #include  #include  int rotate_diff(int a, int b, bool * clockwise); int main(void) { int degrees_rotated, a, b; bool clockwise; a = 4040; b = 1060; degrees_rotated = rotate_diff(a, b, &clockwise); printf("A = %d, B = %d, rotation = %d degrees, direction = %s\n", a, b, degrees_rotated, (clockwise ? "clockwise" : "counter-clockwise")); return EXIT_SUCCESS; } int rotate_diff(int a, int b, bool * clockwise) { static const int min = 2000; if ( a <= min ) { a += 4096; } if ( b <= min ) { b += 4096; } int degrees_rotated = b - a; if ( degrees_rotated > 0 ) { *clockwise = false; } else { degrees_rotated = -degrees_rotated; *clockwise = true; } return degrees_rotated * 360 / 4096; } 

Notez que cela vous donne les degrés parcourus, mais pas la distance parcourue, car vous ne nous dites pas quelles sont les dimensions de l’arbre. Pour obtenir la distance parcourue, multipliez évidemment la circonférence par les degrés parcourus divisée par 360. Si vos points 0 à 4095 sont une sorte d’unités connues, ignorez simplement la conversion en degrés dans l’algorithme ci-dessus et modifiez les noms des variables en conséquence.

Vous devez ajuster toutes vos coordonnées afin qu’elles se trouvent du même côté de vos points limites. Comme c’est un système circulaire, vous pouvez append 4096 sans affecter la position absolue.

 lowest = min(MIN, MAX); if (A < lowest) A += 4096; if (B < lowest) B += 4096; distance = B - A; /* or abs(B - A) */ 

Dans votre exemple, A ne serait pas ajusté mais B serait ajusté à 5156. La différence serait un 1116 positif.

Dans votre deuxième exemple avec A = 3000 et B = 2500, ils sont tous deux supérieurs à 2000, aucun des deux n’a besoin d’être ajusté. La différence est de -500.

À moins que quelque chose ne me manque, cela devrait donner le résultat qu’il vous faut:

 if MIN < A,B < MAX distance = A - B else if A > MAX and B < MIN distance = A - (B + 4096) else if B > MAX and A < MIN distance = (A + 4096) - B else distance = A - B 

(obtenez la valeur absolue de la distance si vous n'avez pas besoin de la direction)