Petit problème pour faire fonctionner un vehicule autonome...

Bonjour à toutes et tous,

Je débute dans la programmation Arduino, mon projet est de construire un véhicule autonome basé sur un arduino et un Pixhawk PX4 avec GPS et le piloter à travers de mon PC via l'application QGroundControl ou Mission planner, ceci me permettant d'avoir une télémétrie complète et un suivi sur une carte en temps réel ainsi qu'une possibilité de planifier des missions.

Pour le moment, je fais des tests avec une version basique sans le Pixhawk, donc mon véhicule est équipe de d'un arduino Mega, d'un sheld moteur arduino 2A, de 2 moteurs, un servo moteur et d'un capteur ultrason.

Le véhicule fonctionne pas trop mal.

il y aurait 2 moyens de coupler les deux systèmes

Le premier: (celui qui me semble le plus simple)

Récupérer les sorties PWM de commande moteur du PX4, les traiter et les intégrer dans le programme déjà existant.

Le second: (le plus complexe mais également le plus pro en résultat)

rajouter le module ArduPilot qui est compatible avec mes deux logiciels.

N'ayant pas franchement les compétences pour attaquer ce type de programmation, je vais m'orienter sur la première solution.

Ma question:

Je comptais utiliser les entrées analogiques pour intégrer les signaux venant du pixhawk, mais comment traiter ce signale pour avoir la proportionnalité que permet le pixhawk seul?

Je vous mets mon code actuel à disposition que vous puissiez m'aider à améliorer mon code.

//Tests robot autonome 

// Déclaration de la bibliotech servo
#include <Servo.h> 
 
//Déclaration des points de sortie
const int trigPin = 6;
const int echoPin = 5;
const int mgV=3;
const int mdV=11;
const int mgS=12;
const int mdS=13;
const int brkD=9;
const int brkG=8;
const int servoPin=7;


//Déclaration du servo
Servo cmdsonar;

// Déclaration des variables
long duration;
int distance;
int distance_a;
int distance_d;
int distance_g;
int distance_mini=50;
int distance_secu=30;

void setup() {
pinMode(trigPin, OUTPUT); // Parmettrage du triger en sortie
pinMode(echoPin, INPUT); // Parmettrage de l'echo en entrée

// Déclaration des sorties de commande des moteurs
pinMode(mgV,OUTPUT);
pinMode(mdV,OUTPUT);
pinMode(mgS,OUTPUT);
pinMode(mdS,OUTPUT);
pinMode(brkD,OUTPUT);
pinMode(brkG,OUTPUT);

// Initialisation de la position de base du servomoteur
cmdsonar.attach(servoPin);
cmdsonar.write(90);

}

void loop() {
      distance_a=sonar();
  // conditions d'oriantation
    if(distance_a > distance_mini){
     avant();
     delay(300);
   }else{
      Stop();
      get_Distance();
      if(distance_g > distance_mini){
        droite();
        delay(200);
        avant_lent();
      }else if(distance_d > distance_mini){
        gauche();
        delay(200);
        avant_lent();
      }else if (distance_a < distance_mini){
        arriere();
        delay(200);
      }else{
        Stop();
      }
   }
}

// Définition du sonar
int sonar(){
  // Mise à l'état bas de l'entrée triger
  digitalWrite(trigPin, LOW);
  delayMicroseconds(2);
  // Mise à l'état haut de l'entrée triger pour 10 us et passage à l'état bas
  digitalWrite(trigPin, HIGH);
  delayMicroseconds(10);
  digitalWrite(trigPin, LOW);
  // Lecture de l'entrée echo 
  int temp = pulseIn(echoPin, HIGH);
  // Calcul de la distance en fonction du temps parcouru par le son
  distance= temp*0.0343/2;
  return distance;
}


//Déclaration des fonctions des moteurs avec leur vitesse
void avant_lent(){
    digitalWrite(mgS,HIGH); 
    digitalWrite(mdS,HIGH);
    analogWrite(mgV,300);
    analogWrite(mdV,290);
}
void avant(){
    digitalWrite(mgS,HIGH);
    digitalWrite(mdS,HIGH);
    analogWrite(mgV,700);
    analogWrite(mdV,690);
}
void arriere(){
    digitalWrite(mgS,LOW);
    digitalWrite(mdS,LOW);
    analogWrite(mgV,-500);
    analogWrite(mdV,-490);
}
void gauche(){
    digitalWrite(mgS,LOW);
    digitalWrite(mdS,HIGH);
    analogWrite(mgV,-400);
    analogWrite(mdV,400);
}
void droite(){
    digitalWrite(mgS,HIGH);
    digitalWrite(mdS,LOW);
    analogWrite(mgV,400);
    analogWrite(mdV,-400);
}
void Stop(){
    digitalWrite(mgS,LOW);
    digitalWrite(mdS,LOW);
    analogWrite(mgV,0);
    analogWrite(mdV,0);
    analogWrite (brkD,HIGH);
    analogWrite (brkG,HIGH);
}

//Détection de la distance

//sonar à droite
void get_Distance(){
  cmdsonar.write(0);
  delay(500);
  int temp_d1=sonar();
  cmdsonar.write(45);
  delay(500);
  int temp_d2=sonar();
  if(temp_d1<temp_d2){
    distance_d=temp_d1;
  }else{
    distance_d=temp_d2;
  }
 //sonar au centre
  cmdsonar.write(90);
  delay(500);
  distance_a=sonar();
  
 //sonar à gauche
  cmdsonar.write(135);
  delay(500);
  int temp_g1=sonar();
  cmdsonar.write(180);
  delay(500);
  int temp_g2=sonar();
  if(temp_g1<temp_g2){
    distance_g=temp_g1;
  }else{
    distance_g=temp_g2;
  }
  cmdsonar.write(90);
  
}

Merci pour votre aide

Salut

J'ai besoin que tu m'expliques ceci:

analogWrite(mgV,-500);
analogWrite(mdV,-490);

Est-ce que tu commandes du PWM, là?

kammo:
J'ai besoin que tu m'expliques ceci:

analogWrite(mgV,-500);
analogWrite(mdV,-490);

Est-ce que tu commandes du PWM, là?

Bien vu !
Les autres aussi : analogWrite prend un argument entre 0 et 255.

J'm'ennuie pffff
Personne a un problème avec un servo ? ^^

Y en a plein ici !! :slight_smile:

Ah ouais en effet!
Mais j'en peux plus de l'angliche...

Bonjour à tous,

lors d'un tuto sur la commande de moteur CC j'avais lu que l'argument pour la commande d'un shield moteur allait de -1000 à + 1000 pour faire varier la vitesse des moteur je me suis peut-être mélangé les pinceaux entre les différents tutos que j'ai lu...

analogWrite(mgV,-500);
analogWrite(mdV,-490);

Il sagit de la marche arrière du véhicule.

Comme je l'avais précisé dans mon premier poste je n'ai réalisé que la première partie, c'est à dire le déplacement et l'évitement d'obstacle. (contôle des moteurs et du capteur ultrason.)
Le but est de rajouter un contrôleur de navigation de rover le Pixhawk qui lui prend en charge la planification de mission avec GPS.

Les signaux de sorties son du type PWM commande servo moteur.

Bonne journée à tous

Merci de m'avoir mis le doigt sur mes erreurs

J'essaye de m'en sortir, mais par moment je m’embrouille quelque peu... l'age et 3 enfants n'aident pas...

Pour les moteurs, marche avant et marche arrière, un bon tuto chez openclassrooms (non Kammo, je n'ai pas d'actions chez eux non plus :slight_smile: )

Pour le shield, il est peut-être spécial et utilise une bibliothèque spécifique : quelle est sa référence ? Peux-tu poster une photo ?

Sur ton driver tu as EN1 et EN2, c'est ça le PWM, de 0 à 255, point barre, c'est comme ça et pis c'est tout ^^
La marche avant/arrière c'est les 4 HIGH/LOW que tu as sur I1,I2,I3,I4

C'est vraiment chouette de vouloir faire un truc autonome avec GPS et tout ça, mais commence par le début.

Tu dois maîtriser ce point, il est primordial, surtout le jour où tu te demanderas pourquoi ton robot tourne toujours en ronds à gauche au lieu d'aller tout droit.
Si tu incrémentes le PWM, apprends aussi à utiliser map() et constrain(), ça t'évitera des heures à te demander pourquoi ça marche pas quand tu incrémentes ou décrémentes tes variables de commande PWM.

De véhicule interstellaire autonome, redescends un peu pour faire un petit robot, cette étape passée, tu pourras aller plus loin.

Tu vas utiliser les ultrasons, c'est pas compliqué, mais entre un code optimal et rapide et un code pourri tout trouvé dans un tuto bidon, tu verras l'écart qu'il y a... Ces modules peuvent ne renvoyer que des erreurs sij on prend pas bien soin d'eux.

Pense aussi à la qualité du montage, que ça soit coller tes moteurs ou faire tes soudures, tes couleurs de câbles ou le choix des composants. Un truc bien fait, bien documenté, c'est une saleté à recommencer en moins. je suis fortiche pour faire des montages foireux, j'en sais un bout ^^

Tu ne feras jamais un rover autonome si ton bidule va pas droit ^^

Prends ton temps.
Coup de bol, le PWM et les servos, c'est les seuls trucs où je suis pas ridicule ^^

Note: j'attends du matos pour faire un bloc de capteurs IR en i²c, pareil avec les hc-sr04...

Voici mon code modifié:

//Tests robot autonome sur base à chenilles

// Déclaration de la bibliotech servo
#include <Servo.h> 
 
//Déclaration des points de sortie
const int trigPin = 6;
const int echoPin = 5;
const int mgV=3;
const int mdV=11;
const int mgS=12;
const int mdS=13;
const int brkD=9;
const int brkG=8;
const int servoPin=7;


//Déclaration du servo
Servo cmdsonar;

// Déclaration des variables
long duration;
int distance;
int distance_a;
int distance_d;
int distance_g;
int distance_mini=50;
int distance_secu=30;

void setup() {
pinMode(trigPin, OUTPUT); // Parmettrage du triger en sortie
pinMode(echoPin, INPUT); // Parmettrage de l'echo en entrée

// Déclaration des sorties de commande des moteurs

pinMode(mgS,OUTPUT);
pinMode(mdS,OUTPUT);
pinMode(brkD,OUTPUT);
pinMode(brkG,OUTPUT);

// Initialisation de la position de base du servomoteur
cmdsonar.attach(servoPin);
cmdsonar.write(90);

}

void loop() {
      distance_a=sonar();
  // conditions d'oriantation
    if(distance_a > distance_mini){
     avant();
     delay(300);
   }else{
      Stop();
      get_Distance();
      if(distance_g > distance_mini){
        droite();
        delay(200);
        avant_lent();
      }else if(distance_d > distance_mini){
        gauche();
        delay(200);
        avant_lent();
      }else if (distance_a < distance_mini){
        arriere();
        delay(200);
      }else{
        Stop();
      }
   }
}

// Définition du sonar
int sonar(){
  // Mise à l'état bas de l'entrée triger
  digitalWrite(trigPin, LOW);
  delayMicroseconds(2);
  // Mise à l'état haut de l'entrée triger pour 10 us et passage à l'état bas
  digitalWrite(trigPin, HIGH);
  delayMicroseconds(10);
  digitalWrite(trigPin, LOW);
  // Lecture de l'entrée echo 
  int temp = pulseIn(echoPin, HIGH);
  // Calcul de la distance en fonction du temps parcouru par le son
  distance= temp*0.0343/2;
  return distance;
}


//Déclaration des fonctions des moteurs avec leur vitesse
void avant_lent(){
    digitalWrite(mgS,HIGH); 
    digitalWrite(mdS,HIGH);
    digitalWrite(brkD,LOW);
    digitalWrite(brkD,LOW);
    analogWrite(mgV,100);
    analogWrite(mdV,100);
}
void avant(){
    digitalWrite(mgS,HIGH);
    digitalWrite(mdS,HIGH);
    digitalWrite(brkD,LOW);
    digitalWrite(brkD,LOW);
    analogWrite(mgV,200);
    analogWrite(mdV,200);
}
void arriere(){
    digitalWrite(mgS,LOW);
    digitalWrite(mdS,LOW);
    digitalWrite(brkD,LOW);
    digitalWrite(brkD,LOW);
    analogWrite(mgV,123);
    analogWrite(mdV,123);
}
void gauche(){
    digitalWrite(mgS,LOW);
    digitalWrite(mdS,HIGH);
    digitalWrite(brkD,LOW);
    digitalWrite(brkD,LOW);
    analogWrite(mgV,123);
    analogWrite(mdV,123);
}
void droite(){
    digitalWrite(mgS,HIGH);
    digitalWrite(mdS,LOW);
    digitalWrite(brkD,LOW);
    digitalWrite(brkD,LOW);
    analogWrite(mgV,123);
    analogWrite(mdV,123);
}
void Stop(){
    digitalWrite(mgS,LOW);
    digitalWrite(mdS,LOW);
    digitalWrite(brkD,HIGH);
    digitalWrite(brkD,HIGH);
    analogWrite(mgV,0);
    analogWrite(mdV,0);

}

//Détection de la distance

//meusure à droite
void get_Distance(){
  cmdsonar.write(0);
  delay(200);
  int temp_d1=sonar();
  cmdsonar.write(45);
  delay(200);
  int temp_d2=sonar();
  if(temp_d1<temp_d2){
    distance_d=temp_d1;
  }else{
    distance_d=temp_d2;
  }
 //meusure au centre
  cmdsonar.write(90);
  delay(200);
  distance_a=sonar();
  
 //meusure à gauche
  cmdsonar.write(135);
  delay(200);
  int temp_g1=sonar();
  cmdsonar.write(180);
  delay(200);
  int temp_g2=sonar();
  if(temp_g1<temp_g2){
    distance_g=temp_g1;
  }else{
    distance_g=temp_g2;
  }
  cmdsonar.write(90);
  
}

Salut^^

Pourquoi tu fais bouger le servo en deux temps ?

 //meusure à gauche
  cmdsonar.write(135);
  delay(200);
  int temp_g1=sonar();
  cmdsonar.write(180);

Je vois que tu sais utiliser les fonctions, alors pour la marche avant, pourquoi ne pas utiliser un appel du genre MarcheAvant(lent) par exemple? Tu gagnes une fonction et des lignes de code.
Mieux, ma commande est faites comme ceci MarcheAvant(vitesse), ça permet de faire évoluer ton code facilement plus tard (le moteur peut être commandé jusqu'à 255, tu vas jusque 123)

Tes déclarations de pins sont correctes, mais on peut les faire avec #define, ça prend moins de mémoire.

Aussi, je vois que tu déclares toutes tes variables proprement en début de code. C'est clair et bien fait, mais il vaut mieux en général utiliser des variables locales, que tu déclares dans ta fonction, et qui disparaissent de la mémoire ensuite. Moins on a de variables, mieux c'est. Quand il t'en faut une, tu la déclares dans la fonction qui en a besoin.

Aussi, pour GetDistance, tu peux faire une seule fonction, sur le même principe
GetDistance(gauche);
getDistance(droite);
GetDistance(devant);

Du coup, tu n'as plus qu'une fonction pour trois actions!

La place en mémoire, tant qu'on en a on s'en balance, mais si tu veux faire un robot polyvalent avec du GPS et tout ça, tu vas finir par en manquer.

Merci beaucoup Kammo pour votre aide, c'est super.
Je vais retravailler mon code en conséquence.

Ca fait que deux mois que je code quand j'ai le temps, je ne connaissais absolument pas le C++ Arduino, je m’étais arrêté au basic il y a 35 ans...
Concernant la partie autonome avec le GPS, je vais utiliser le signal venant d'une carte type Ardupilot qui s'interface à merveille avec mes logiciels que j'utilise déjà sur des drones.
Cette carte fait l’acquisition des points GPS en fonction de la mission à effectuer et je récupère également la télémétrie en temps réel sur écran et sur PC avec l'ensemble des logs mémorisés.
L'arduino ne me sert qu'à l'acquisition d'obstacle et pour la gestion de la propulsion et tout ça dans le périmètre d'évolution en fonction des trajectoires programmés.
L'interfaçage des deux systèmes va m'imposer la mise en place d’interruptions et des sauts dans le programme de l'arduino.
sachant que le signal PWM que je récupère commande normalement des servos, je me demandais si je pouvais les faire rentrer sur les entrées analogiques?

en attendant, voici les photos de mon petit proto avec mon petit shield maison pour le servo et le capteur ultrason.

Bonne soirée

A priori, tu peux rentrer un signal PWM dans une entrée analogique. Tu n'auras pas un byte de 0 à 255, mais un float ou un entier.
Si c'est pour récupérer le signal sur une seconde carte arduino, il faudra les calibrer, mieux vaut passer par un port de communication pour davantage de précision. Il existe une entrée PWM il me semble, j'ai pas encore essayé...
Tout dépend ce que tu veux en faire, et avec quoi tu veux la récupérer...