Aller au contenu


Contenu de Serveurperso

Il y a 392 élément(s) pour Serveurperso (recherche limitée depuis 04-mai 13)



#96632 Variable 8 bits et dépassement

Posté par Serveurperso sur 24 juin 2018 - 05:58 dans Programmation

T'es encore perché dans les langages de haut niveau:) En C ou C++ quand t'as tout les 11111111 dans une variable de type de base 8-bits (uint8_t) et que t'ajoute 1 ça fait le résultat "100000000" cependant comme le premier 1 dépasse des 8-bits ça fait simplement zéro.

En signé ça reboucle de 127 à -128 et réciproquement.

 

Ce comportement est valable pour des type signé ou non signés 8, 16, 32, 64 etc. bits




#96637 Variable 8 bits et dépassement

Posté par Serveurperso sur 24 juin 2018 - 08:43 dans Programmation

Pourquoi faire "compter le nombre de fois ou ça reboucle" ?

 

Imagine une calculatrice à roue (voir la vidéo du weekend de Micmaths à ce sujet lol )

 

Tu peux additionner et soustraire autant que tu veux bien au delà de la limite d'affichage de la machine, tant que que résultat final y rentre sans déborder : il sera nickel juste !

 

Chez moi un résultat final qui déborde revient à une erreur d'asservissement de >65536 impulsions ce qui signifie une cinquantaine de rotations complètes de roues (65536 / ROUECPR dans notre code avec jojo), et c'est impossible à atteindre car elle est clampé à ERREURMAX

En gros mon PID essai de rattraper l'erreur tant que celle ci est <ERREURMAX sinon seule une erreur = à ERREURMAX sera rattrapée et une alerte visuelle apparaît sur l'interface du robot (= roue bloquée provoquant une erreur > 15 degrés et un énorme pic de consommation).




#96633 Variable 8 bits et dépassement

Posté par Serveurperso sur 24 juin 2018 - 06:16 dans Programmation

C'est grâce à ça que les roues de mon robot peuvent tourner dans le même sens pendant un temps "illimité" en stockant simplement les positions des encodeurs dans 16-bits.

 

J'ai pas mis 8-bits car sur 256 il n'y à pas assez d'espace de stockage pour calculer par exemple la largeur de l'erreur possible (retard entre la consigne et la position effective).

 

Pas besoin de 32-bits car dans les mathématique que j'utilise rien n'a besoin de plus de 65536 d'espace

Et aussi en 32 bits le wrap ne se produit pas assez souvent pour être certain que l’algorithme se comporte de façon transparente pendant le wrap justement.

 

Pourtant sur un microcontrôleur 32 bits tout peux travailler en 32 bits sans différences de vitesse mais comme je veux garder mon code portable et optimisé au maximum sur d'autres puces (comme de l'Arduino en AVR 8-bits) je préfère toujours bosser avec l'espace minimum pour les variable.

 

Un code dont les variables "tournent en rond" fréquemment sur 8 ou 16 bits est forcément plus fiable qu'un code ayant 32 bits d'espace ou le wrap ne se produit presque jamais car ce "presque" être source d'une belle surprise !

 

Un tableau de 256 de taille (0 à 255) dont l'index est stocké sur 8 bits ne débordera jamais et le code C ne pourra jamais planter de façon bizarre (écriture en dehors d'un tableau = possibilité d'écrasement aléatoire d'autres variables en mémoire).




#96629 Variable 8 bits et dépassement

Posté par Serveurperso sur 24 juin 2018 - 05:33 dans Programmation

ça https://fr.wikipedia...sement_d'entieret ça permet des puissantes optimisations sur beaucoup d'algos

 

exemple en 8 bits non signé 255 + 1 = 0




#99919 Un "jeu" pc ou on contrôle des véhicules a distance en temps reel

Posté par Serveurperso sur 08 novembre 2018 - 01:29 dans Bric-à-brac

Décors absolument époustouflant.
Tout est possible même de refaire ce genre de jeu, mais il incombe aux Utilisateurs de respecter les CGU 😂 c'est a dire pas de robomitraillettes ni de chasses au chat ou à la belle mère avec les robots vigibot ! Le système permettra de faire des groupes d'amis privés avec des robots ou des caméras vitrines pour les visiteurs inscrits ou non...



#96482 SLAMTEC RPLIDAR A2: développement en C d'un driver 4K ultra rapide

Posté par Serveurperso sur 17 juin 2018 - 07:44 dans Programmation

C'est bon je l'ai flashé sur mes 2 robots qui fonctionnent toujours en 4K de la même façon qu'avant, sauf que le protocole bas niveau 8K est maintenant dispo. Il reste à coder le driver 8K au besoin (mais sur le PIC32 8000 mesures par secondes faut pas pousser).

 

Maintenant le bit de "start" fonctionne quand le moteur se relance des qu'on bloque la rotation or qu'avant il était complètement ératique et rarement mis à 1...

 

1.png

2.png

 




#94626 SLAMTEC RPLIDAR A2: développement en C d'un driver 4K ultra rapide

Posté par Serveurperso sur 18 avril 2018 - 08:15 dans Programmation

C'est justement cette partie qu'il nous manque pour synchroniser le 0 au début du tableau.

 

Ton analyse du dessus va me servir de base pour la version optimisée du code

Va falloir entrer dans la table de sinus directement en 16 bits

Bosser en Q16 permet d'avoir 16 bits de mantisse et 16 bits d'exposant.




#94585 SLAMTEC RPLIDAR A2: développement en C d'un driver 4K ultra rapide

Posté par Serveurperso sur 17 avril 2018 - 09:47 dans Programmation

Ah mais si ça se trouve j'ai inversé les bits MSB et LSB du deltaAngles !!!!!

 

Code de Path

		const cabin = {};

		const byte0 = buffer[0];
		const distance1LSB = (byte0 & 0b11111100) >>> 2;
		const deltaAngle1Q3MSB = byte0 & 0b00000011;

		const distance1MSB = buffer[1];
		cabin.distance1 = (distance1MSB << 6) | distance1LSB;

		const byte2 = buffer[2];
		const distance2LSB = (byte2 & 0b11111100) >>> 2;
		const deltaAngle2Q3MSB = byte2 & 0b00000011;

		const distance2MSB = buffer[3];
		cabin.distance2 = (distance2MSB << 6) | distance2LSB;

		const byte4 = buffer[4];
		const deltaAngle2Q3LSB = (byte4 & 0xF0) >>> 4;
		const deltaAngle1Q3LSB = byte4 & 0x0F;

		let deltaAngle1Q3 = (deltaAngle1Q3MSB << 4) | deltaAngle1Q3LSB;	
		let deltaAngle2Q3 = (deltaAngle2Q3MSB << 4) | deltaAngle2Q3LSB;

		if(deltaAngle1Q3 & 0b00100000) {
			deltaAngle1Q3 = deltaAngle1Q3 & 0b00011111;
			deltaAngle1Q3 = ~deltaAngle1Q3 + 1;
		}
		cabin.deltaAngle1 = deltaAngle1Q3 / 8;


		if(deltaAngle2Q3 & 0b00100000) {
			deltaAngle2Q3 = deltaAngle2Q3 & 0b00011111;
			deltaAngle2Q3 = ~deltaAngle2Q3 + 1;
		}
		cabin.deltaAngle2 = deltaAngle2Q3 / 8;




#94584 SLAMTEC RPLIDAR A2: développement en C d'un driver 4K ultra rapide

Posté par Serveurperso sur 17 avril 2018 - 09:43 dans Programmation

Pour répondre à ta question sur l'autre sujet, oui, les angles sont bons. J'ai laissé les 3 axes du repère sur la restitution pour vérifier tout ça. Les distances sont bonnes et les formes que les points reproduisent sont très fidèles.

 

ça confirme que j'ai une boulette de rotation de bit dans ce code... Mais OU ??? C'est ça qui est fou, c'est très simple à comprendre ce code mais comme je baigne dedans je ne vois pas la connerie...




#94587 SLAMTEC RPLIDAR A2: développement en C d'un driver 4K ultra rapide

Posté par Serveurperso sur 17 avril 2018 - 09:55 dans Programmation

Je vais tester de suite.

Mais dit moi page 19 du datachiotte la Cabin : Mike me dit qu'il ne vois qu'un seul bit de deltaTheta à droite des bits de distance !!! il a pas raison ???




#94727 SLAMTEC RPLIDAR A2: développement en C d'un driver 4K ultra rapide

Posté par Serveurperso sur 22 avril 2018 - 09:41 dans Programmation

Voila je lui ai tordu le coup, c'est terminé.

 

Il suffisait juste de détecter le passage par zéro sur l'angle non compensé !!!

 

Il faut quand même avouer que :

if(oldAngleBrutQ6 > angleBrutQ6)

 

C'est quand même beaucoup beaucoup plus facile à comprendre que :

syncBit[0] = (( (currentAngle_raw_q16 + angleInc_q16) % (360<<16)) < angleInc_q16 )?1:0;"

 

Qu'ils nous on pondu dans le code d'origine, et sans parler du reste !!! Le développeur de robotpeak devait être drogué...

 

Voila l'algo terminé, et sans aucun charabia :

    #define NBMESURESCABINES 32
    #define UNTOURQ6 (360 << 6)

    // Ici le code machine d'état pour l'en-tête...

    diffAngleQ6 = startAngleQ6 - oldStartAngleQ6;                                      // Calcul l'angle entre deux mesures de référence
    if(oldStartAngleQ6 > startAngleQ6)
     diffAngleQ6 += UNTOURQ6;

    diffAngleTotalQ6 = 0;
    for(uint8_t i = 0; i < NBMESURESCABINES; i++) {

     angleBrutQ6 = (oldStartAngleQ6 + diffAngleTotalQ6 / NBMESURESCABINES) % UNTOURQ6; // Calcul de l'angle non compensé et sans débordement
     diffAngleTotalQ6 += diffAngleQ6;

     if(oldAngleBrutQ6 > angleBrutQ6) {                                                // Détection du passage par zéro de l'angle non compensé
      // Remise à zéro de la position d'enregistrement dans les tableaux
     }
     oldAngleBrutQ6 = angleBrutQ6;

     if(distances[i]) {                                                                // Si la lecture est valide
      angle = angleBrutQ6 - (deltaAnglesQ3[i] << 3);                                   // Compensation de l'angle
      angle = angle * 65536 / UNTOURQ6;                                                // Remise à l'échelle de l'angle

      // Ici enregistrement cartésien etc...

     }
    }
    oldStartAngleQ6 = startAngleQ6;

    // Ici le code machine d'état pour l'en-tête...



#94607 SLAMTEC RPLIDAR A2: développement en C d'un driver 4K ultra rapide

Posté par Serveurperso sur 18 avril 2018 - 06:34 dans Programmation

Vu que mike a vu qu'ils ne gèrent pas le bit de signe dans le code d'origine j'ai fait la même chose, j'ai juste viré le signe de mon type deltaAnglesQ5, le bit de signe du lidar est toujours claqué sur mon bit de poid le plus fort mais vu que c'est un UINT et plus un INT ça ne passe jamais en négatif, et ça semble fonctionner ?!?!?! plus d'erreur de rotation ni de S ou cassure quand on approche !

 

 static uint8_t deltaAnglesQ5[RPLIDARNBSAMPLES];
 static uint16_t distances[RPLIDARNBSAMPLES];
 

 

 

pasDeSigne.png




#94581 SLAMTEC RPLIDAR A2: développement en C d'un driver 4K ultra rapide

Posté par Serveurperso sur 17 avril 2018 - 09:23 dans Programmation

bool readLidar() {
 uint8_t current;                  // Octet courant récupéré dans le FIFO, on while la dessus tant qu'il y en a.
 static uint8_t n = 0;             // Etat courant de la state machine
 static uint8_t checksum;          // Checksum présent dans la trame lidar
 static uint8_t sum = 0;           // Variable de calcul du checksum
 static uint16_t oldStartAngleQ6;  // Ancien angle de référence
 static uint16_t startAngleQ6 = 0; // Comporte l'angle de référence complet
 //static bool start;              // Pas utile
 static uint16_t diffAngleQ6;      // Calcul 
 static uint8_t m = 0;             // Etat courant de la sous-state machine pour le décodage des cabines
 static uint8_t s = 0;             // Compteur des mesures de cabines, 32 mesures entre les angles de références

 static int8_t deltaAnglesQ5[RPLIDARNBSAMPLES]; // Comporte les 32 compensations angulaires
 static uint16_t distances[RPLIDARNBSAMPLES];   // Comporte les 32 mesures de distances

 // Résultats, a passer en arithmétique entière quand ce sera OK
 float distance;
 float angle;
 float lidarx;
 float lidary;

 static uint16_t j = 0; // Position d’écriture des tableaux comportant les résultats.
 lidarReady = true;     // Globale qui devra indiquer si le lidar fonctionne ou pas (pas encore fait en 4K)



 while(RXLIDAR.available()) {
  current = RXLIDAR.read();

  switch(n) {

   case 0:                     // Figure 4-11 offset +0
    if(current >> 4 == 0xA) {
     checksum = current & 0xF;
     n = 1;
    }
    break;

   case 1:                     // Figure 4-11 offset +1
    if(current >> 4 == 0x5) {
     checksum |= current << 4;
     n = 2;
    } else
     n = 0;
    break;

   case 2:                     // Figure 4-11 offset +2
    sum ^= current;
    oldStartAngleQ6 = startAngleQ6;
    startAngleQ6 = current;
    n++;
    break;

   case 3:                     // Figure 4-11 offset +3
    sum ^= current;
    startAngleQ6 |= (current & 0x7F) << 8;
    /*start = current >> 7;
    if(start)
     TXDEBUG.println("start");*/







    // Voir début de la page 23, c'est juste pour obtenir l'angle relatif entre 2 bloc de 32 mesures !
    // Le test sert juste à soustraire le wrap quand le lidar passe par Theta = zéro.
    // Je bosse directement en Q6 (partie déjà optimisée)

    if(oldStartAngleQ6 > startAngleQ6)
     diffAngleQ6 = (360 << 6) + startAngleQ6 - oldStartAngleQ6;
    else
     diffAngleQ6 = startAngleQ6 - oldStartAngleQ6;





    // On boucle sur les 32 mesures #define RPLIDARNBSAMPLES 32 à renommer (lol)
    // Le but est d'ajouter l'angle de compensation à chaque mesures
    // par rapport à l'angle complet donné qu'une fois toute les 32 mesures


    for(uint8_t i = 0; i < RPLIDARNBSAMPLES; i++) {
     distance = distances[i];
     if(distance) {                                                       // Si la lecture est valide

      // Calcul de l'angle en float
      angle = (
                float(oldStartAngleQ6) +                                   // Je prend l'ancienne valeur de l'angle absolu initial car on bosse avec une nouvelle entête.
                float(diffAngleQ6) * float(i) / float(RPLIDARNBSAMPLES) -  // Calcul de l'angle théorique par division bêtes...
                (float(deltaAnglesQ5[i]) * 2)                              // Petite correction angulaire "pour prendre en compte les variations de vitesse du moteur" le "* 2" c'est juste pour passer de Q5 en Q6
               ) / 64.0 * PI / 180.0;





/*                              Ici c'est la même chose en plus bourrin (comme le datasheet)
      angle = (
                (float(oldStartAngleQ6) / 64.0) +
                (float(diffAngleQ6) / 64.0) * float(i) / float(RPLIDARNBSAMPLES)//-
                //(float(deltaAnglesQ5[i]) * 2.0 / 64.0)
               ) * PI / 180.0;
*/




      // Cette partie est propre à nos robots, on stock les données brutes et les données cartésiennes.
      lidarx = POSITIONLIDARX + distance * sinFloat(angle);
      lidary = POSITIONLIDARY + distance * cosFloat(angle);
      if(lidarx > POSITIONSROBOTXMAX || lidarx < POSITIONSROBOTXMIN ||
         lidary > POSITIONSROBOTYMAX || lidary < POSITIONSROBOTYMIN) { // Si la lecture est hors du robot
       lidarsx[j] = int(lidarx);
       lidarsy[j] = int(lidary);
       lidarsCartex[j] = int(lidarx * cosFloat(theta) + lidary * sinFloat(theta) + odometriex * 1000.0);
       lidarsCartey[j] = int(-lidarx * sinFloat(theta) + lidary * cosFloat(theta) + odometriey * 1000.0);
       j++;
       if(j == NBMESURESMAX)
        j = 0;
      }
     }
    }

    n++;       // On passe en mode cabine (case default:)
    break;


   // Mode cabine !
   default:
    sum ^= current;
    switch(m) {
     case 0:                                         // Figure 4-11 offset +0 d'une cabine
      deltaAnglesQ5[s] = (current & 0b11) << 6;
      distances[s] = current >> 2;
      m++;
      break;
     case 1:                                         // Figure 4-11 offset +1 d'une cabine
      distances[s] |= current << 6;
      m++;
      break;
     case 2:                                         // Figure 4-11 offset +2 d'une cabine
      deltaAnglesQ5[s + 1] = (current & 0b11) << 6;
      distances[s + 1] = current >> 2;
      m++;
      break;
     case 3:                                         // Figure 4-11 offset +3 d'une cabine
      distances[s + 1] |= current << 6;
      m++;
      break;
     case 4:                                         // Figure 4-11 offset +4 d'une cabine
      deltaAnglesQ5[s] |= (current & 0b1111) << 2;
      deltaAnglesQ5[s + 1] |= (current & 0b11110000) >> 2;
      m = 0;
      s += 2;
      if(s == RPLIDARNBSAMPLES) {
       /*if(sum != checksum) {
        TXDEBUG.print(sum);
        TXDEBUG.print(" ");
        TXDEBUG.println(checksum);
       }*/
       n = 0; // On sort du mode cabine...
       s = 0;
       sum = 0;
      }
      break;
    }
    break;

  }
 }

}


Image(s) jointe(s)

  • Rubber_duck_assisting_with_debugging.jpg



#94608 SLAMTEC RPLIDAR A2: développement en C d'un driver 4K ultra rapide

Posté par Serveurperso sur 18 avril 2018 - 07:17 dans Programmation

Conclusion, ça fonctionne parfaitement après quelques heures de debug à deux :D j'optimise le code et le colle ici

 

Du coup Path t'as forcément un truc pourri étrange dans ton code:D

Pas besoin d'appliquer de signe à deltaAnglesQ3

J'ai plus besoin non plus de le passer en Q5:)




#94623 SLAMTEC RPLIDAR A2: développement en C d'un driver 4K ultra rapide

Posté par Serveurperso sur 18 avril 2018 - 07:46 dans Programmation

C'est cette partie du code la plus intéressante, et c'est déjà optimisé à mort en fait, tellement qu'on comprend rien de premier abord en fait "c'est neuneu"




#94615 SLAMTEC RPLIDAR A2: développement en C d'un driver 4K ultra rapide

Posté par Serveurperso sur 18 avril 2018 - 06:09 dans Programmation

Il n'y a aucun signe c'est une erreur de la doc (y'en a eu d'autres) la preuve : le code d'origine n'en comporte pas et l'affichage fonctionne nickel avec un entier non signé...




#94726 SLAMTEC RPLIDAR A2: développement en C d'un driver 4K ultra rapide

Posté par Serveurperso sur 22 avril 2018 - 06:24 dans Programmation

DEBOUT à 7h !!!

Truc pondu à froid au réveil : Ne prendre que le front descendant de l'impulsion pour éviter que ce soit vrais durant toute la durée des 32 derniers enregistrements des 16 cabines.

static bool oldPulse;
static bool pulse = 0;
oldPulse = pulse;
pulse = (angleBrutQ6 + diffAngleQ6) % (360 << 6) < diffAngleQ6;

if(!pulse && oldPulse) {
  // Ecrire un MESURENULLE et retour au début du stockage
}

Et la tout fonctionne à 100% en 4K :D Je vais quand même réfléchir aux moindre optimisation sans dégrader la lisibilité / ou amélioration uniquement de la lisibilité / amélioration de l'élégance du code...




#94583 SLAMTEC RPLIDAR A2: développement en C d'un driver 4K ultra rapide

Posté par Serveurperso sur 17 avril 2018 - 09:40 dans Programmation

Dites-moi les enfants,

j'ai beau programmer (c'est mon métier) depuis XX années, connaitre les sujets techniques que vous abordez (les PIC, la radio, le numérique, l'analogique) - et quand je dis connaître c'est pratiquer -  et je suis plutôt à l'aise pour parler technique (sauf Linux, c'est comme ça, chacun son truc)

Et bien voyez-vous j'ai un souci : je comprend pas tout. Que dalle en fait. Ça doit venir de moi ... C'est grave docteur ?

 

Non c'est pas toi, j'ai essayé de résumer le problème au maximum mais ça suffit pas car nous on baigne dedans et du coup c'est plus facile qu'il n'y parait.

 

Le but c'est de lire un à un les bytes en provenance d'un UART (PIN RX du PIC32) qui est reliée au TX du RPLIDAR.

Le RPLIDAR est un produit qui comporte un télémètre laser rotatif, qui balance la distance et l'angle, la vitesse du moteur est non asservie, il tourne librement et donc l'angle est une donnée critique pour repositionner le point.

 

Aussi et c'est la le problème : pour pouvoir envoyer 4000 mesures par secondes en 115200 baud, RPLIDAR doit compresser les données redondantes.

 

Il s'agit d'un bug dans mon algorithme de décompression des données que j'essai de corriger avec l'aide de Mike.




#95884 SLAMTEC RPLIDAR A2: développement en C d'un driver 4K ultra rapide

Posté par Serveurperso sur 29 mai 2018 - 07:57 dans Programmation

Hop good new ils ont pondu une MAJ du firmware RPLIDAR A2 pour supporter le 8K sur le même hardware:D

Je vais tenter cette semaine.

http://www.slamtec.com/cn/Support#rplidar-a2

https://wiki.slamtec...pageId=16154735

 




#94567 SLAMTEC RPLIDAR A2: développement en C d'un driver 4K ultra rapide

Posté par Serveurperso sur 17 avril 2018 - 08:15 dans Programmation

Bonjour les roboticiens !

 

Pour ceux qui ne savent pas, je bosse avec Mike118 sur un framework complet de robot web autonome à faible latence. Du hardware en passant par le système d'exploitation jusqu’à l'interface web. Mettant en avant la plus faible réactivité possible et des déplacements rapides et précis...

 

Mike m'aide souvent à créer des algos avec des partie mathématique que je n'ai pas en tête et je l'en remercie.

Ce logiciel existe sur 3 robots au monde actuellement, les 2 miens et le sien, c'est tout. J'ouvre ce thread comme un "BLOG" de suivi sur l'avancement de ce problème sur lequel je rame depuis maintenant 2 jours, avec en prime ce driver de parcing 4K ulta-optimisé et fonctionnel à la fin...

 

Suite à l'implémentation d'arithmétique entière et d'une table de sinus 16-bits/16-bits dans la mémoire flash de notre PIC32 qui ne dispose pas d'une FPU, la puissance de traitement disponible à été démultipliée et du coup le mode 4K de ce LIDAR devient intéressant pour améliorer les perfs de nos algos de localisation:D

J'ai donc re-testé mon algo de décodage RPLIDAR 4K et il toujours bugué, le vilain bug n'est toujours pas mort malgré tout ce temps lol

Par contre niveau ressources dispo sur le PIC32 c'est la fête, il faut donc qu'on trouve ce problème absolument !

 

Le thread de Path qui à déjà fait le décodage 4K mais en JavaScript :

http://www.robot-maker.com/forum/topic/11759-le-rp-lidar-a2/

Le code concerné que je connais presque par coeur mais qui ne m'a pas aidé a résoudre mon bug :

https://github.com/P...express-scan.js

 

Les pages du datasheet RPLIDAR A2 qui nous intéressent vont de 19 à 23. Pour rappel :

 

La trame :

Cabin.png Format.png

 

Description des donnés :

Format1.png Format2.png

 

Le calcul de l'angle :

Maths.png

 

Le BUG :

Les points verts sont les impacts lasers avec un historique de quelques milliers de points = plusieurs frames lidar complètes.

Les lignes blanches sont celles qui sont affichées en ce moment = un fragment d'une trame lidar, soit 30 points (limitation bande passante radio)

 

0) L'algo 2K fonctionne parfaitement, mais pas en 4K

1) L'angle correct est horizontal, le robot est perpendiculaire au mur de devant, il est aligné à la pièce.

2) Une partie des mesures, si il en existe qui sont à une petite distance du robot sont correctes, on visualise les mystérieux décrochages de chaque côtés quand la distance augmente.

3) Le reste du nuage de point est en retard de 9 degrés !

 

Je recule légèrement le robot du mur de charge :

1.png 2.png

 

Et encore plus loin :

3.png

 

Et sur cette capture, avec le robot au centre de la pièce, on vois bien les 9 degrés d'erreur niveau affichage du Theta

La pièce est inclinée or que le robot est parfaitement aligné :

Erreur9deg.png




#94582 SLAMTEC RPLIDAR A2: développement en C d'un driver 4K ultra rapide

Posté par Serveurperso sur 17 avril 2018 - 09:32 dans Programmation


En regardant les photo de pascal ( serveurperso ) je me dit que le problème n'est pas en lien avec le fait de sauter une cabine ou une sous cabine ... 

On voit clairement que la zone qui diffère des autres n'est pas " angulairement constante " ce qui serait le cas je pense si c'était un problème de lecture de cabine ... 
Par contre il semblerait que le problème soit lié à la distance de l'obstacle ...  En gros j'ai l'impression qu'on observe le décalage pour tous les points de lidar dont la distance est inférieur à une certaine limite ...  Ce qui permet d'expliquer l'écart angulaire variable en fonction de la distance du robot par rapport au mur ...

 

 

En poussant le raisonnement j'ai envie de supposer que dès que la distance mesurée est top grande le calcul de la virgule se fait mal ... Et 9° est ajouté à l'angle au lieu de 0,9° ou 10° au lieu de 0,1° ...  Ou un truc du genre ce qui expliquerait le décalage décalage de 9 à 10° ... 

 

J'ai même testé de garder le tableau deltaAngles en Q3 pour faire le changement de signe à la mano comme Path... Exactement le même bug


   default:
    sum ^= current;
    switch(m) {
     case 0:
      deltaAnglesQ3[s] = (current & 0b11) << 4;
      distances[s] = current >> 2;
      m++;
      break;
     case 1:
      distances[s] |= current << 6;
      m++;
      break;
     case 2:
      deltaAnglesQ3[s + 1] = (current & 0b11) << 4;
      distances[s + 1] = current >> 2;
      m++;
      break;
     case 3:
      distances[s + 1] |= current << 6;
      m++;
      break;
     case 4:





      // Test pour faire comme Path, c'est à dire faire le changement de signe à la mano plutôt qu'en décalant les bits directement au bons endroits...

      deltaAnglesQ3[s] |= current & 0b1111;
      if(deltaAnglesQ3[s] & 0b100000) {
       deltaAnglesQ3[s] &= 0b11111;
       deltaAnglesQ3[s] = ~deltaAnglesQ3[s] + 1;
      }

      deltaAnglesQ3[s + 1] |= (current & 0b11110000) >> 4;
      if(deltaAnglesQ3[s + 1] & 0b100000) {
       deltaAnglesQ3[s + 1] &= 0b11111;
       deltaAnglesQ3[s + 1] = ~deltaAnglesQ3[s + 1] + 1;
      }





      m = 0;
      s += 2;
      if(s == RPLIDARNBSAMPLES) {
       /*if(sum != checksum) {
        TXDEBUG.print(sum);
        TXDEBUG.print(" ");
        TXDEBUG.println(checksum);
       }*/
       n = 0;
       s = 0;
       sum = 0;
      }
      break;
    }
    break;




#94620 SLAMTEC RPLIDAR A2: développement en C d'un driver 4K ultra rapide

Posté par Serveurperso sur 18 avril 2018 - 06:57 dans Programmation

En fait c'est pas pour toi je peste contre leurs code moisi qui ne respecte pas du tout la doc et qui utilise des types non stricts (uint8_t int8_t etc...)




#94576 SLAMTEC RPLIDAR A2: développement en C d'un driver 4K ultra rapide

Posté par Serveurperso sur 17 avril 2018 - 08:59 dans Programmation

En fait j'ai pas fini de rédiger ni le premier post ni celui avec tout le code ultra commenté ligne à ligne (façon debug canard jaune) !!!

ça arrive:)

 

 

 

Content que tu n'aies pas vu de bug dans le javascript ^^ Si t'as des remarques, n'hésites pas. Je le partage pour ça :)

 

Ton code, c'est toujours celui-là ? http://www.robot-maker.com/forum/topic/10903-hector/?p=90957

 

De mémoire, j'avais un pb du même genre (décalage plus de petites distorsion) avant que je gère bien le bit de signe. (http://www.robot-maker.com/forum/topic/10903-hector/?p=91236) Mais chez toi, il ne semble pas y avoir de distorsions comme j'avais.

 

En fait j'ai que la remarque du code en double pour ton javascript mais il est hyper clair plus que le mien qui se veux optimisé a mort

En fait c'est exactement ce que j'ai fait a l'époque mais en moins condensé.




#94616 SLAMTEC RPLIDAR A2: développement en C d'un driver 4K ultra rapide

Posté par Serveurperso sur 18 avril 2018 - 06:17 dans Programmation

Par contre maintenant on ouvre un autre sous sujet pour ce driver : détecter le passage de l'angle par 0 pour que les tableaux de stockage démarrent toujours à la même position, et la mike à trouvé un calcul bizarre pas indiqué dans la doc ou il faut comprendre ce qui se passe




#94618 SLAMTEC RPLIDAR A2: développement en C d'un driver 4K ultra rapide

Posté par Serveurperso sur 18 avril 2018 - 06:46 dans Programmation

On ne recopie pas des bits n'importe comment dans un type non strict, un int c'est 16 bits minimum, couramment 32 bits ou plus selon l'architecture... si tu balances un bit de signe en plein milieu d'un int au pif bah le nombre ne sera jamais négatif !