Aller au contenu


Mike118

Inscrit(e) (le) 26 janv. 2012
Déconnecté Dernière activité hier, 21:58
*****

#95605 Service d'impression 3D

Posté par Mike118 - 20 mai 2018 - 09:50

Bonjour à tous, 

Ouverture officielle du service d'impression 3D. 
Pour le moment le prix est très attractif mais je ne garantis pas qu'il perdure.
On va dire que c'est une phase de test et en fonction du test j'aviserais par la suite =)

 

Le but c'est de permettre à ceux qui n'ont pas accès à une imprimante 3D de pouvoir faire imprimer leurs pièces à un coût raisonnable et de le commander en même temps qu'ils commandent les moteurs etc... Il peut même y avoir des discussion pour vérifier que tel moteur rentre bien dans tel pièces imprimée par exemple =)

 

Le lien pour payer le service : Impression 3D PLA

Pour le moment oui c'est que du PLA mais différentes couleurs sont disponible.

 

Les premières pièces qui ont été imprimées : 

20180517_235901.jpg

 

Si vous avez des remarques ou des questions n'hésitez pas !




#95603 Glenn Robot Humanoide

Posté par Mike118 - 20 mai 2018 - 09:39

Tu peux reprendre depuis le debut, on commence a plus suivre. :)  (38 pages sur le sujet... :) )

 

Met nous une liste du matos que tu utilise.

Met nous des photos de ton ou tes montages (le must serait un schéma :)

 

Mais courage ca va marcher bientôt ^^ 

 

C'est à ça que ça sert un blog  x) 




#95595 Position et orientation précises d'un robot (à l'aide !)

Posté par Mike118 - 20 mai 2018 - 06:44

En effet uniquement l'odométrie avec des codeurs optique ( Beaucoup de pulses par tours de roue ) permet de mesurer une position 2D sans trop de problèmes. 
C'est la technique majoritairement employez pour les robots de la coupe de robotique =) 

 

les formules intéressantes pour ce genre de chose sont présentées rapidement sur ce sujet : 

 

Robot 2WD homologable pour la coupe de france de Robotique plus précisément cette partie : 
 

  x += ((speedDroit + speedGauche) * PERIMETREROUE * cos(theta)) / ROUEPPR ; // variable en mm
  y += ((speedDroit + speedGauche) * PERIMETREROUE * sin(theta)) / ROUEPPR ;
  theta += atan2((speedDroit - speedGauche) * PERIMETREROUE / (ROUEPPR ), ENTRAXE);  // Peu précis préférer utiliser un Imu si on a le temps ...
  if( theta> 2* PI) theta -= 2 * PI;
  else if (theta < 0) theta += 2 * PI;

Après comme indiquée en commentaire dans le code, au vu des moteurs utilisé dans le sujet cette méthode est peu précise est utiliser une IMU serait beaucoup mieux ... 

 

 

L'accéléromètre mesure les accélération dont la force exercé par la gravité, cela permet donc de connaitre un angle pour les deux autres axes mais pas pour le lacet malheureusement. 

Une boussole magnétique ( magnétomètre 3 axe ) pourrait être utilisée mais ce genre de composant est facilement perturbé.. 
Si votre environnement est " clair " de toute perturbation ce capteur peut être exploité =) 

Pour l'utilisation du Gyro, un gyromètre mesure une vitesse angulaire il faut donc " intégrer le résultat " ... 
 

// En faisant très rapidement des mesures 
angle + = vitesseAngulaire * dt;    // dt étant l'intervalle de temps entre deux prise de mesure

if( angle > 2 * PI) angle -= 2 * PI;
else if (angle < 0 ) angle += 2 * PI;



Le seule inconvénient c'est que bien que cela soit plus précis puis qu'on fait une " intégration " cela intègre les erreurs ... 
Il est important de recaler ce résultat si on veut l'utiliser très longtemps ...




#95573 Glenn Robot Humanoide

Posté par Mike118 - 20 mai 2018 - 01:49

En fait je pense que tu devrais arrête ta modélisation et faire plein de teste avec du matériel... Genre tout câbler et tout faire bouger ... ça t'éclaircira les idées ! =)




#95532 Formation Robotique à thème ça vous intéresse?

Posté par Mike118 - 18 mai 2018 - 05:03

LOL

 

Vu le temps que j'ai passé pour faire le tome 1 et le début du tome 2 ( qui est pas fini) pour apprendre à utiliser arduino et faire des montages on est pas sortis de l'auberge ! x)




#95515 La coupe de France de robotique 2018

Posté par Mike118 - 17 mai 2018 - 12:33

La coupe de france de robotique 2018 est passée ! Que de bons souvenirs ! =) 
à peine fini qu'on se dit vivement l'année prochaine ! 

En attendant : 

 

Voici un album de photographies prises pendant la coupe de France de robotique 2018 : 
Lien vers l'album photo prises par RCO pour la coupe de france de robotique 2018

 

Quelques photo  : 

 

La coupe c'est ... 

 

Des robots : 

robottechlegend.jpg

l'équipe robot tech legend qui a fini 1 ère sur la coupe de france et 3ème au niveau européen étendu =)

 

Des équipes passionnées : 

equipe.jpg

 

des matchs tout en couleur : 

match.JPG

 

 

Des gens qui travaillent sur un robot : 

20180510_002431.jpg

C'est bizarre il me dit quelque chose ce robot ... ;)

 

Un jolie abeille imprimée en 3D : 
20180511_081927.jpg
 

Des mignons : 

20180511_084505.jpg

 

Le fameux repas offert et sa longue file d'attente : 

20180511_212247.jpg

Mais cette attente c'est l'occasion idéale pour discuter avec des gens ! =)

 

Les stands où les équipent présentent leur robots: 

20180512_115706.jpg

 

 

Et plus encore ! 
Rendez vous pour l'édition 2019 ! =)

 

Si vous avez participer à la coupe de france de robotique et que vous souhaitez partager les photo et vidéo que vous avez prises n'hésitez pas ! Uplodez comme des malades =) ou balancez vos liens ;)




#95491 Formation Robotique à thème ça vous intéresse?

Posté par Mike118 - 16 mai 2018 - 12:53

En fait si tu veux savoir... La moyenne d'age sur le forum est d'environ 40 ans ! 

Mais oui je pense que la majeur partie des participants sont des passionnés / hobbyiste... 
Cependant avec cette demande je cible plus spécifiquement les simples " visiteurs" =) 

Dans le lot il y a par exemple des professeurs qui suite à des évolutions doivent maintenant faire des cours de programmation avec arduino par exemple ... Ou proposer de TP avec des thématique sympas sur des choses qu'ils ne maîtrisent pas forcément bien ... 
Oui les cours de technologie ça a beaucoup évolué en 5 ans ...

 

Il peut aussi y avoir des "entrepreneurs" qui ont une idée mais à qui il manque un petit truc pour se lancer ... 

Bref ... 

 

Je laisse ça en l'air =) On verra ce que ça donnera =)
 




#95475 Solenoïde 1.2A Alimentation Arduino

Posté par Mike118 - 15 mai 2018 - 08:35

simple et efficace : 

Un kit lipo tout prêt! =)

kit-lipo-complet.jpg




#95464 Robot en mecanno avec une tourelle

Posté par Mike118 - 15 mai 2018 - 09:39

 

 

-que veut dire:"uint8_t" ??? demande le Mega débutant que je suis

 

 

 

Il n'y a aucune honte à être débutant on est tous passé par là un moment ou un autre ;)

et pour cette première question Jekert t'a très bien répondu en pointant vers un tutoriel que j'ai rédigé exprès pour répondre à cette question ;)

 

 

Mais si tu as plus de questions spécifique sur ce sujet hésite pas à les poser en commentaire du tutoriel ;) 

 

 

 

-donc dans mon setup j'enregistre avant tout les angle c'est sa?

 

 

J'ai pas compris ta question ... 

quels angles ? 

Après pour tout te dire je n'ai pas compris pourquoi tu voulais faire le tableau en deux dimensions qui stock les angles ... 
Car de base si tu prend 10 mesures sur 90° tu sais que le premier angle ça sera 0, le suivant, 10, le suivant 20 puis 30, 40 50 60 70 80 et 90° ... et ça sera toujours pareil donc pas besoin de stocker l'angle ...et dans ce cas l'angle i vaut 10* i ... avec i de 0 à 9 ...  

 

 

 

-Ton morceau code veut dire que je n'utilise plus la fonction max?

 

 

non mon morceau de code n'utilise pas la fonction max car mon but est de savoir lequel des deux est le plus grand pour travailler au niveau de l'indice ... Très utile quand tu as un tableau à plusieurs dimensions quand on ne veut pas stocker les max de chaque dimension à chaque étape de la vérification... Mais si tu avais un tableau de une dimension tu pourrais sans problème utiliser la fonction max... Bref c'était surtout pour montrer une autre façon de faire =)

 

 

 

-Et comment a tu fais pour insérer ton code dans la réponse ?

 

 

 

Pour ça je te recommande de lire ce tutoriel qui explique comment intégrer du contenu sur le forum

 

et je te recommande aussi de jeter un oeil sur vous êtes nouveau sur robot maker




#95431 Robot en mecanno avec une tourelle

Posté par Mike118 - 14 mai 2018 - 08:31

Pourquoi faire un tableau en deux dimensions ? 

Pourquoi ne pas placer le capteur droit devant, mesurer en continu la présence éventuelle d'un obstacle, si obstacle on s'arrête, on bouge la tourelle à droite et à gauche, on regarde quelle valeur et la plus grande et on tourne du côté où la valeur est la plus grande ... Simple et efficace qu'en dis tu ?




#95417 Robot 2WD homologable pour la coupe de france de robotique réalisé au dernier...

Posté par Mike118 - 13 mai 2018 - 06:19

Il est fort ce Mike ^^

Il y a un sticker robot maker sur le robot de l'équipe LesKaribous 

https://twitter.com/...590577936171008

 

 

[Edit encore] :) Il est fort ce Mike

https://twitter.com/...3373826/photo/1

 

 

Le robot vainqueur

 

 attachicon.gifDbzCM42XkAEJRh3.jpg

 

Les Karibous sont une des équipes sponsorisées pas Robot Maker, ( Même si en tout honnêteté on ne leur a pas fournis grand chose ... ) J'espère qu'on pourra faire un peu plus l'an prochain ;)

 

 

Il en sont où dans la course ?

 

Pour tout te dire je ne sais même pas il faut que je check sur internet... De ce que je sais Estia System n'est pas allé très loin niveau des points... Une fois la décision prise par l'équipe que suite aux problèmes rencontrés ils souhaitaient utiliser le robot pour marquer des points je n'y ai plus touché =)  

Les Karibous eux sont beaucoup mieux placés ;)

Et puis comme je tenais tout seul mon petit stand ... Avec Briel qui faisait des pas de danse =), j'ai pas eu beaucoup de temps =)
D'ailleurs promis je poste des vidéos bientôt de BRIEL ! =) ( Mais ceux qui étaient présents ont pu voir le robot faire sa danse ;)




#95316 Salut la compagnie!

Posté par Mike118 - 10 mai 2018 - 09:33

Bienvenue en tout cas ! =) Si jamais tu ne l'as pas vu je te recommande de jeter un oeil à : Vous êtes nouveau ? 

Bonne continuation à toi et relaxe toi bien ;)




#95310 Robot 2WD homologable pour la coupe de france de robotique réalisé au dernier...

Posté par Mike118 - 10 mai 2018 - 09:03

Bon finalement le robot a été adopté par l'équipe ESTIA SYSTEM qui a eu quelques soucis avec son robot et le robot a été réellement homologué en tant que robot secondaire hier avant minuit ! =) Il participera à son premier match demain ! Et visiblement son arme de prédilection c'est la paire de ciseau ! :o

 

20180510_002431.jpg

 

 

Du coup moi je ne touche plus au robot ! :)  Et on espère que le robot principal de l'équipe sera rapidement de nouveau sur roue ;) Je leur souhaite bon courage ;) 
 

Le code d'homologation : 


// Manipulation des ports
// PIND :  RX TX 2 3 4 5 6 7
// https://www.arduino.cc/en/Reference/PortManipulation




// général 

//IO
#define COULEUR 10 
#define GO 11

bool couleur;   
#define VERT 0
#define ORANGE 1

// évitement : 

#include <NewPing.h>

#define TRIGGER_PIN  13  // Arduino pin tied to trigger pin on the ultrasonic sensor.
#define ECHO_PIN     12  // Arduino pin tied to echo pin on the ultrasonic sensor.
#define MAX_DISTANCE 100 // Maximum distance we want to ping for (in centimeters). Maximum sensor distance is rated at 400-500cm.

NewPing sonar(TRIGGER_PIN, ECHO_PIN, MAX_DISTANCE); // NewPing setup of pins and maximum distance.


// asservissement en vitesse des moteurs 

#include <PID_v1.h>   // Pour le PID
#include <TimerOne.h> // Pour le timer

// commande du moteur droit
#define ENCODEURDROITA 2
#define ENCODEURDROITB 4
#define MOTEURDROITA 5       // contrôle vitesse moteur 1; PWM
#define MOTEURDROITB 8       // controle direction moteur 1

// commande du moteur 2
#define ENCODEURGAUCHEA 3
#define ENCODEURGAUCHEB 7
#define MOTEURGAUCHEA 6       // contrôle vitesse moteur 2; PWM
#define MOTEURGAUCHEB 9      // controle direction moteur 2

double SetpointDroit, InputDroit, OutputDroit;
double SetpointGauche, InputGauche, OutputGauche;

double Kp = 0.8, Ki = 5, Kd = 0.1;

PID PIDDROIT(&InputDroit, &OutputDroit, &SetpointDroit, Kp, Ki, Kd, DIRECT);
PID PIDGAUCHE(&InputGauche, &OutputGauche, &SetpointGauche, Kp, Ki, Kd, DIRECT);

// volatile => pour toute variable qui sera utilise dans les interruptions

volatile int8_t countDroit = 0; /* comptage de tick d'encoder qui sera incrémenté sur interruption " On change " sur l'interruption 0 */
volatile int8_t countGauche = 0; /* comptage de tick d'encoder qui sera incrémenté sur interruption " On change " sur l'interruption 1 */

volatile double speedDroit = 0; // vitesse du moteur
volatile double speedGauche = 0; // vitesse du moteur

unsigned long time0 = 0; // stock un temps à un instant donné
unsigned long timer = 0; // variable qui va contenir le dernier temps enregistré via millis

int8_t valeur = 50;  //lecture de la consigne via le moniteur serie

bool go = 0;

uint16_t obstacle = 0;

void setup()
{
  //initialisation moniteur serie
  Serial.begin(9600);       // facultatif uniquement pour feedback
  
  // on initialise les entrées et sorties
  pinMode(ENCODEURDROITA, INPUT_PULLUP);
  pinMode(ENCODEURDROITB, INPUT_PULLUP);
  pinMode(ENCODEURGAUCHEA, INPUT_PULLUP);
  pinMode(ENCODEURGAUCHEB, INPUT_PULLUP);

  pinMode(MOTEURDROITA, OUTPUT);
  pinMode(MOTEURDROITB, OUTPUT);
  pinMode(MOTEURGAUCHEA, OUTPUT);
  pinMode(MOTEURGAUCHEB, OUTPUT);

  pinMode(COULEUR, INPUT);
  pinMode(GO, INPUT);

  // moteurs à l'arret
  stopMotors();

  // Encoder quadrature counter
  attachInterrupt(0, counterDroit, CHANGE); // lorsqu'il y une modification sur le pin 2, on interrompte le programme pour enclencher le comptage
  attachInterrupt(1, counterGauche, CHANGE); // lorsqu'il y une modification sur le pin 3, on interrompte le programme pour enclencher le comptage

  Timer1.initialize(80000);            // set a timer of length 100000 microseconds = 0.1 sec - or 10Hz
  Timer1.attachInterrupt( timerIsr );

  // PID
  InputDroit = 0;
  SetpointDroit = 0;
  InputGauche = 0;
  SetpointGauche = 0;
  //active le PID
  PIDDROIT.SetMode(AUTOMATIC);
  PIDDROIT.SetOutputLimits(-255, 255);
  PIDGAUCHE.SetMode(AUTOMATIC);
  PIDGAUCHE.SetOutputLimits(-255, 255);

  
   while(!go) { 
   time0 = millis(); 
   go = digitalRead(GO);
  }
  
}

void loop() {
   
   if (Serial.available()) {   // test
    time0 = timer;
    valeur = Serial.parseInt(); //récupération des caractères sur le port série
  }
  obstacle =  sonar.ping_cm();
  if( obstacle==0 || obstacle > 10 ) {   // le capteur retourne zéro si il n'y a pas d'obstacle ...
  runMotorSpeed(valeur,valeur);
  } 
  else {
    valeur = 0 ;
    stopMotors();
  }
  
  timer = millis();
  if ( (timer - time0) > 90000) { //Timeout !
    valeur = 0 ;
    stopMotors();
    time0 = timer;
  }

  Serial.println("speed1");
  Serial.println(speedDroit);                 // à commenter, utilisé pour débug
  Serial.println("speed2");
  Serial.println(speedGauche);                 // à commenter, utilisé pour débug
  Serial.println("'''''''''''''''''");    // à commenter, utilisé pour débug

}



void counterDroit()
{
  byte state = PIND;
  (((state >> ENCODEURDROITA) & 1) ^ ((state >> ENCODEURDROITB) & 1)) ? countDroit-- : countDroit++; // régler ++ et -- pour que faire avancer => +
}

// Encoder counter 2

void counterGauche()
{
  byte state = PIND;
  (((state >> ENCODEURGAUCHEA) & 1 ) ^ ((state >> ENCODEURGAUCHEB) & 1)) ? countGauche++ : countGauche--; // régler ++ et -- pour que faire avancer => +
}


// Timer pour calculer la vitesse grace aux encodeurs

void timerIsr()
{
  // asservissement en vitesse
  speedDroit = countDroit;
  countDroit = 0;
  speedGauche = countGauche;
  countGauche = 0;
}

void stopMotors() {
  digitalWrite(MOTEURDROITA, HIGH);
  digitalWrite(MOTEURDROITB, HIGH);
  digitalWrite(MOTEURGAUCHEA, HIGH);
  digitalWrite(MOTEURGAUCHEB, HIGH);
}


void test() {

  digitalWrite(MOTEURDROITA, LOW);
  digitalWrite(MOTEURDROITB, LOW); // low fait avancer
  digitalWrite(MOTEURGAUCHEA, HIGH);
  digitalWrite(MOTEURGAUCHEB, LOW); // Low fait reculer

  Serial.println("speed1");
  Serial.println(speedDroit);                 // à commenter, utilisé pour débug
  Serial.println("speed2");
  Serial.println(speedGauche);                 // à commenter, utilisé pour débug
  Serial.println("'''''''''''''''''");    // à commenter, utilisé pour débug
}

void avancerMoteurDroit(uint8_t a) // En avant
{
  analogWrite (MOTEURDROITA, a); // Contrôle de vitesse en PWM, moteur 1
  digitalWrite(MOTEURDROITB, LOW); // sens de marche avec HIGH
}
void avancerMoteurGauche(uint8_t a) // En avant
{
  analogWrite (MOTEURGAUCHEA, 255 - a); // Contrôle de vitesse en PWM, moteur 2
  digitalWrite(MOTEURGAUCHEB, HIGH);
}

void reculerMoteurDroit (uint8_t a) // En arrière
{
  analogWrite (MOTEURDROITA, 255 - a);
  digitalWrite(MOTEURDROITB, HIGH);
}
void reculerMoteurGauche (uint8_t a) // En arrière
{
  analogWrite (MOTEURGAUCHEA, a);
  digitalWrite(MOTEURGAUCHEB, LOW);
}


void runMotorSpeed( int8_t commandeMoteurDroit, int8_t commandeMoteurGauche) {

  SetpointDroit = commandeMoteurDroit;
  SetpointGauche = commandeMoteurGauche;

  InputDroit = speedDroit;
  InputGauche = speedGauche;

  PIDDROIT.Compute();
  PIDGAUCHE.Compute();

  int outputDroit = (int)OutputDroit;
  int outputGauche = (int)OutputGauche;

  //utilisation de la sortie du PID pour asservir les moteurs
  if (outputDroit >= 0) {
    avancerMoteurDroit(outputDroit);
  }
  if (outputDroit < 0) {
    reculerMoteurDroit(-outputDroit);
  }
  if (outputGauche >= 0) {
    avancerMoteurGauche(outputGauche);
  }
  if (outputGauche < 0) {
    reculerMoteurGauche(-outputGauche);
  }
  // à commenter, utilisé pour débug
  Serial.println("output1");
  Serial.println(outputDroit);                
  Serial.println("output2");
  Serial.println(outputGauche);                
  Serial.println("'''''''''''''''''");        
}





Comme vous pourrez le constater ça a un peut taillé dans le gras ^^ 

Le robot attend son signal de départ puis avance tout droit à environ 40% de sa vitesse, et dégomme un réservoir avec sa paire de ciseaux et puis s'arrête et il s'arrête si on embête son capteur ultrason en chemin ! =) 

C'est pas grande chose mais c'est suffisant pour être homologué ! =)




#95290 Robot 2WD homologable pour la coupe de france de robotique réalisé au dernier...

Posté par Mike118 - 09 mai 2018 - 12:29

Bon bon quand faut y aller il faut y aller ! 

Le robot est pas complètement fini , j'ai mis de côté le déplacement pour le moment afin de mettre les éléments nécessaire pour être homologué ! 

Petite photo vite fait : 

20180509_132108.jpg


On retrouve donc la batterie dans son sac ignifuge, un capteur à ultrason pour éviter la colision frontal ... Bon ok le robot n'a qu'un pauvre capteur et donc il ne fera que avancer ... mais bon on a fait avec le délais impartis... 


Après vous remarquerez que le robot n'est bien entendu pas fini ^^ Il sera fini sur place il reste encore deux trois trucs à câbler dont la carte qui permet de faire démarrer le robot ( et qui indique aussi au robot de quel côté il est :)

=> 

 20180509_132231.jpg

 

ça a été soudé sur une véroboard

veroboard.jpg

 

puis découpé à la pince coupante 

dessus il y a entre autre un interrupteur miniature 

 

Le schémas fait à l'arrache avec paint  qui va avec : 

Schemas sélecteur de couleur et go.png

 

J'espère que le fonctionnement est claire ... 

Quand on retire le jumper le pin Go passe à 5V => Départ du match 
En fonction de la position de l'interrupteur , la led verte est allumée ou non ... 

Vert allumé => on est vert et le pin couleur est à 0V ! 

J'espère que ça aidera des équipes à la coupe ! 

Sur ce je clos là mon aventure de cette nuit .

 

Plutôt satisfait de ce qui a été fait =) Les prochaines news seront après la coupe ! =)

 

 




#95283 Robot 2WD homologable pour la coupe de france de robotique réalisé au dernier...

Posté par Mike118 - 09 mai 2018 - 08:44

Bah, être homologué en poussant des cubes !  ^^ Le truc le plus bateau...

ça avance ça avance le robot commence à avoir un soupçon d'intelligence pour aller au point demandé ... 

Petite vidéo " trichée" où je lui demande juste d'aller à un point qui est devant lui en corrigeant son angle si il dévie ...

 

 

Pas encore eu le temps de régler quoi que ce soit ...

 

Je pense qu'il faudrait une IMU pour l'angle ...

 

 

En attendant la 3 ème pièce imprimée vient d'être sortie : 

 

20180509_093411.jpg

 

c'est le dessus du robot qui permet de tenir le bouton d'arrêt d'urgence ainsi que la petite carte relais déjà câblée pour pouvoir couper le robot ! =) 

AU.jpg

 

le schémas fait à la va vite sous paint qui va avec : 

Schémas carte relais.png

 

Je vous laisse deviner comment ça marche ;)  Sachant que le but c'est de couper les moteurs lorsqu'on appuie sur le bouton d'arrêt d'urgence =)

 

 

 

 

Je pense qu'il est difficile de faire plus simple et efficace...

pour info le diamètre que j'ai fais pour ce bouton c'est du 22mm mais on peut faire un petit peu plus gros

 

 

Le code qui a beaucoup de points à revoir et qui est actuellement sur le robot  ... => attention c'est juste un SnapShot il est pas utilisable en l'état ! ça permet d'avoir un aperçu du code en mode brouillon à un instant t =)


// Manipulation des ports
// PIND :  RX TX 2 3 4 5 6 7
// https://www.arduino.cc/en/Reference/PortManipulation




// général 

//IO
#define COULEUR 10 
#define GO 11

bool couleur;   
#define VERT 0
#define ORANGE 1

// évitement : 

#include <NewPing.h>

#define TRIGGER_PIN  13  // Arduino pin tied to trigger pin on the ultrasonic sensor.
#define ECHO_PIN     12  // Arduino pin tied to echo pin on the ultrasonic sensor.
#define MAX_DISTANCE 100 // Maximum distance we want to ping for (in centimeters). Maximum sensor distance is rated at 400-500cm.

NewPing sonar(TRIGGER_PIN, ECHO_PIN, MAX_DISTANCE); // NewPing setup of pins and maximum distance.


// asservissement en vitesse des moteurs 

#include <PID_v1.h>   // Pour le PID
#include <TimerOne.h> // Pour le timer

// commande du moteur droit
#define ENCODEURDROITA 2
#define ENCODEURDROITB 4
#define MOTEURDROITA 5       // contrôle vitesse moteur 1; PWM
#define MOTEURDROITB 8       // controle direction moteur 1

// commande du moteur 2
#define ENCODEURGAUCHEA 3
#define ENCODEURGAUCHEB 7
#define MOTEURGAUCHEA 6       // contrôle vitesse moteur 2; PWM
#define MOTEURGAUCHEB 9      // controle direction moteur 2

double SetpointDroit, InputDroit, OutputDroit;
double SetpointGauche, InputGauche, OutputGauche;

double Kp = 0.8, Ki = 5, Kd = 0.1;

PID PIDDROIT(&InputDroit, &OutputDroit, &SetpointDroit, Kp, Ki, Kd, DIRECT);
PID PIDGAUCHE(&InputGauche, &OutputGauche, &SetpointGauche, Kp, Ki, Kd, DIRECT);

// volatile => pour toute variable qui sera utilise dans les interruptions

volatile int8_t countDroit = 0; /* comptage de tick d'encoder qui sera incrémenté sur interruption " On change " sur l'interruption 0 */
volatile int8_t countGauche = 0; /* comptage de tick d'encoder qui sera incrémenté sur interruption " On change " sur l'interruption 1 */

volatile double speedDroit = 0; // vitesse du moteur
volatile double speedGauche = 0; // vitesse du moteur


// asservissement en position du robot 

#define X0ORANGE 90
#define X0VERT (3000 - 90)
#define THETA0ORANGE 0
#define THETA0VERT 0 // PI
#define Y0 0//100

#define PPR  22                                 
#define GEARBOXRATIO 21                          
#define ROUEPPR (PPR * GEARBOXRATIO)  
                       
#define DIAMETREROUE 65 // en mm 
#define PERIMETREROUE ( PI * DIAMETREROUE ) 

#define ENTRAXE 160

#define TOLERANCE 20 // 2cm de tolérance pour le positionnement => Mettre une tolerance pour éviter les oscillation autour de la positon d'arrivée ...
#define TOLERANCETHETA PI/10 

volatile int32_t x, y; // variable en mm
volatile float theta;  // variable radian 

int32_t cibleX, cibleY; 

double SetpointLineaire, InputLineaire, OutputLineaire;
double SetpointAngulaire, InputAngulaire, OutputAngulaire;

double KpL = 0.015, KiL = 0.000, KdL = 0.00;
double KpA = 2, KiA = 0, KdA = 0;

PID PIDLINEAIRE (&InputLineaire, &OutputLineaire, &SetpointLineaire, KpL, KiL, KdL, DIRECT);
PID PIDANGULAIRE(&InputAngulaire, &OutputAngulaire, &SetpointAngulaire, KpA, KiA, KdA, DIRECT);



unsigned long time0 = 0; // stock un temps à un instant donné
unsigned long timer = 0; // variable qui va contenir le dernier temps enregistré via millis

int8_t valeur = 40;  //lecture de la consigne via le moniteur serie


void setup()
{
  //initialisation moniteur serie
  Serial.begin(9600);       // facultatif uniquement pour feedback
  
  // on initialise les entrées et sorties
  pinMode(ENCODEURDROITA, INPUT_PULLUP);
  pinMode(ENCODEURDROITB, INPUT_PULLUP);
  pinMode(ENCODEURGAUCHEA, INPUT_PULLUP);
  pinMode(ENCODEURGAUCHEB, INPUT_PULLUP);

  pinMode(MOTEURDROITA, OUTPUT);
  pinMode(MOTEURDROITB, OUTPUT);
  pinMode(MOTEURGAUCHEA, OUTPUT);
  pinMode(MOTEURGAUCHEB, OUTPUT);

  pinMode(COULEUR, INPUT);
  pinMode(GO, INPUT);

  // moteurs à l'arret
  stopMotors();

  // Encoder quadrature counter
  attachInterrupt(0, counterDroit, CHANGE); // lorsqu'il y une modification sur le pin 2, on interrompte le programme pour enclencher le comptage
  attachInterrupt(1, counterGauche, CHANGE); // lorsqu'il y une modification sur le pin 3, on interrompte le programme pour enclencher le comptage

  Timer1.initialize(80000);            // set a timer of length 100000 microseconds = 0.1 sec - or 10Hz
  Timer1.attachInterrupt( timerIsr );

  // PID
  InputDroit = 0;
  SetpointDroit = 0;
  InputGauche = 0;
  SetpointGauche = 0;
  //active le PID
  PIDDROIT.SetMode(AUTOMATIC);
  PIDDROIT.SetOutputLimits(-255, 255);
  PIDGAUCHE.SetMode(AUTOMATIC);
  PIDGAUCHE.SetOutputLimits(-255, 255);
  PIDLINEAIRE.SetMode(AUTOMATIC);
  PIDLINEAIRE.SetOutputLimits(-60, 60);
  PIDANGULAIRE.SetMode(AUTOMATIC);
  PIDANGULAIRE.SetOutputLimits(-15, 15);

  y = Y0;
  if( digitalRead(COULEUR) ) {  // On est orange 
    x= X0ORANGE;
    theta = THETA0ORANGE;
  }
  else {
    x= X0VERT;
    theta = THETA0VERT;
  }
  /* while(!go) { 
   time0 = millis(); 
   go = digitalRead(GO);
  }*/
}

void loop() {
   rotation(PI);
   stopMotors();
   while(1);
  //while(1){test();} // test

  if (Serial.available()) {   // test
    time0 = timer;
    valeur = Serial.parseInt(); //récupération des caractères sur le port série
  }
  //goToPosition(1500, 0);

  
 

  /* If obstacle 
  {
    stopMotors();
  }
  */
  timer = millis();
  if ( (timer - time0) > 90000) { //Timeout !
    valeur = 0 ;
    stopMotors();
    time0 = timer;
  }

  Serial.println("speed1");
  Serial.println(speedDroit);                 // à commenter, utilisé pour débug
  Serial.println("speed2");
  Serial.println(speedGauche);                 // à commenter, utilisé pour débug
  Serial.println("'''''''''''''''''");    // à commenter, utilisé pour débug

}



void counterDroit()
{
  byte state = PIND;
  (((state >> ENCODEURDROITA) & 1) ^ ((state >> ENCODEURDROITB) & 1)) ? countDroit-- : countDroit++; // régler ++ et -- pour que faire avancer => +
}

// Encoder counter 2

void counterGauche()
{
  byte state = PIND;
  (((state >> ENCODEURGAUCHEA) & 1 ) ^ ((state >> ENCODEURGAUCHEB) & 1)) ? countGauche++ : countGauche--; // régler ++ et -- pour que faire avancer => +
}


// Timer pour calculer la vitesse grace aux encodeurs

void timerIsr()
{
  // asservissement en vitesse
  speedDroit = countDroit;
  countDroit = 0;
  speedGauche = countGauche;
  countGauche = 0;

  //asservissement en position
  x += ((speedDroit + speedGauche) * PERIMETREROUE * cos(theta)) / ROUEPPR ; // variable en mm
  y += ((speedDroit + speedGauche) * PERIMETREROUE * sin(theta)) / ROUEPPR ;
  theta += atan2((speedDroit - speedGauche) * PERIMETREROUE / (ROUEPPR ), ENTRAXE);  // Peu précis préférer utiliser un Imu si on a le temps ...
  if( theta> 2* PI) theta -= 2 * PI;
  else if (theta < 0) theta += 2 * PI;
}

void stopMotors() {
  digitalWrite(MOTEURDROITA, HIGH);
  digitalWrite(MOTEURDROITB, HIGH);
  digitalWrite(MOTEURGAUCHEA, HIGH);
  digitalWrite(MOTEURGAUCHEB, HIGH);
}


void test() {

  digitalWrite(MOTEURDROITA, LOW);
  digitalWrite(MOTEURDROITB, LOW); // low fait avancer
  digitalWrite(MOTEURGAUCHEA, HIGH);
  digitalWrite(MOTEURGAUCHEB, LOW); // Low fait reculer

  Serial.println("speed1");
  Serial.println(speedDroit);                 // à commenter, utilisé pour débug
  Serial.println("speed2");
  Serial.println(speedGauche);                 // à commenter, utilisé pour débug
  Serial.println("'''''''''''''''''");    // à commenter, utilisé pour débug
}

void avancerMoteurDroit(uint8_t a) // En avant
{
  analogWrite (MOTEURDROITA, a); // Contrôle de vitesse en PWM, moteur 1
  digitalWrite(MOTEURDROITB, LOW); // sens de marche avec HIGH
}
void avancerMoteurGauche(uint8_t a) // En avant
{
  analogWrite (MOTEURGAUCHEA, 255 - a); // Contrôle de vitesse en PWM, moteur 2
  digitalWrite(MOTEURGAUCHEB, HIGH);
}

void reculerMoteurDroit (uint8_t a) // En arrière
{
  analogWrite (MOTEURDROITA, 255 - a);
  digitalWrite(MOTEURDROITB, HIGH);
}
void reculerMoteurGauche (uint8_t a) // En arrière
{
  analogWrite (MOTEURGAUCHEA, a);
  digitalWrite(MOTEURGAUCHEB, LOW);
}


void runMotorSpeed( int8_t commandeMoteurDroit, int8_t commandeMoteurGauche) {

  SetpointDroit = commandeMoteurDroit;
  SetpointGauche = commandeMoteurGauche;

  InputDroit = speedDroit;
  InputGauche = speedGauche;

  PIDDROIT.Compute();
  PIDGAUCHE.Compute();

  int outputDroit = (int)OutputDroit;
  int outputGauche = (int)OutputGauche;

  //utilisation de la sortie du PID pour asservir les moteurs
  if (outputDroit >= 0) {
    avancerMoteurDroit(outputDroit);
  }
  if (outputDroit < 0) {
    reculerMoteurDroit(-outputDroit);
  }
  if (outputGauche >= 0) {
    avancerMoteurGauche(outputGauche);
  }
  if (outputGauche < 0) {
    reculerMoteurGauche(-outputGauche);
  }
  // à commenter, utilisé pour débug
  Serial.println("output1");
  Serial.println(outputDroit);                
  Serial.println("output2");
  Serial.println(outputGauche);                
  Serial.println("'''''''''''''''''");        
}


bool goToPosition(int32_t xCible, int32_t yCible) {
  
  int32_t deltaX = xCible - x; 
  int32_t deltaY = yCible - y;
  int8_t commandeMoteurDroit = 0;
  int8_t commandeMoteurGauche = 0;
  float deltaAngle;
  
  SetpointLineaire = sqrt( deltaX * deltaX + deltaY * deltaY);
  SetpointAngulaire = atan2(deltaY , deltaX);
  deltaAngle = SetpointAngulaire - theta;

  InputLineaire = 0;
  InputAngulaire = theta;

  PIDLINEAIRE.Compute();
  PIDANGULAIRE.Compute();
  Serial.println("setpoint Lineaire");    // à commenter, utilisé pour débug
  Serial.println(SetpointLineaire);    // à commenter, utilisé pour débug
  Serial.println("setpoint Angulaire");    // à commenter, utilisé pour débug
  Serial.println(SetpointAngulaire);    // à commenter, utilisé pour débug
  Serial.println("'''''''''''''''''");    // à commenter, utilisé pour débug
  Serial.println("x");
  Serial.println(x);                 // à commenter, utilisé pour débug
  Serial.println("y");
  Serial.println(y);                 // à commenter, utilisé pour débug
  Serial.println("Angle");
  Serial.println(theta);                 // à commenter, utilisé pour débug
  Serial.println("'''''''''''''''''");    // à commenter, utilisé pour débug
  Serial.println("deltax");
  Serial.println(deltaX);                 // à commenter, utilisé pour débug
  Serial.println("deltay");
  Serial.println(deltaY);                 // à commenter, utilisé pour débug
  Serial.println("deltaAngle");
  Serial.println(deltaAngle);                 // à commenter, utilisé pour débug
  Serial.println("'''''''''''''''''");    // à commenter, utilisé pour débug

  if( abs(deltaAngle)  < TOLERANCETHETA ) {
    commandeMoteurDroit = (int)(OutputLineaire  + OutputAngulaire);
    commandeMoteurGauche = (int)(OutputLineaire  - OutputAngulaire);
    runMotorSpeed( commandeMoteurDroit, commandeMoteurGauche); 
  }
  else {
    commandeMoteurDroit = (int)( OutputAngulaire);
    commandeMoteurGauche = (int)(- OutputAngulaire);
    runMotorSpeed( commandeMoteurDroit, commandeMoteurGauche); 
  }
  
  if( abs(deltaX) < TOLERANCE && abs(deltaY) < TOLERANCE) 
   return 1;

  return 0;
}

void rotation(float angleConsigne){
  while(1){
  SetpointAngulaire = angleConsigne;
  InputAngulaire = theta;
  PIDANGULAIRE.Compute();
  runMotorSpeed((int)( OutputAngulaire), (int)(- OutputAngulaire)); 
  Serial.println("setpoint Angulaire");    // à commenter, utilisé pour débug
  Serial.println(SetpointAngulaire);    // à commenter, utilisé pour débug
  Serial.println("Angle");
  Serial.println(theta);                 // à commenter, utilisé pour débug
  Serial.println("'''''''''''''''''");    // à commenter, utilisé pour débug
  Serial.println("Angleconsigne");
  Serial.println(angleConsigne);                 // à commenter, utilisé pour débug
  Serial.println("'''''''''''''''''");    // à commenter, utilisé pour débug
  }
}

Bon maintenant je commence un peu à préparer les sacs ... 

C'était pas un bon plan de relever le défi ! x) 

 

Mais oui ça va je suis large ! :P J'ai qu'une heure de route à faire ! ^^