Mini robot
Aller à la navigation
Aller à la recherche
Projet réalisé par gogomichoud.
En cours
Présentation
L'objectif de ce projet est de faire un petit robot d'expérimentation avec les moyens du bord (peu d'achat). L'idée est de découvrir et d'appliquer les notions de robotique (pilotage moteurs, PID, cinématique inverse, intégration capteur, autonomie...)
Le but n'est pas encore défini, mais j'aimerais bien avoir un contrôle distant (télécommande, ordi, app smartphone, ...). Dans un second temps implémenter ROS2 pour faire du pathfinding, de la simulation, etc.
L'idée de ce robot est d’apprendre par expérimentation pour par la suite rejoindre ou former une équipe pour participer à la coupe de France de Robotique, et avoir déjà un peu de bouteille ;-)
BOM
- Arduino Nano
- CNC Shield V.4
- 2 NEMA 17
- Batterie LiPo 3S
Lien utile
- Cours de déplacement, asservissement polaire, location, etc. de RCVA
- Doc de la bibliothèque AccelStepper.h
- Documentation de ROS2
- Capteur ultra-son avec interruption Home DIY Electronics
- Vidéo de James Bruton : Building a ROS Robot for Mapping and Navigation #1
- Cours payant : The construct
- Documentation sur le TurtleBot3 (pdf du livre gartuit) : Robotis.com
- Forum de Planète Science : Propulsion de robot avec des moteurs Pas à Pas
- Explication complète sur les interruptions : Gammon.com.au
- Contrôleur pas à pas Pololu avec rampe d'accélération incluse Tic Stepper Motor Controllers
- La maxi liste ressources Eurobot
Cahier de bord
À expliciter
- J'ai acheté le livre Learning Robotics using Python (Lentin Joseph), beaucoup de chose intéressante, mais pas forcément adapté pour ROS2. Je n'ai pas encore trop d'avis sur si c'est un bon livre ou non.
- Premier sertissage
- Nucleo F303K8 cramé : l'emplacement du connecteur USB sur un Nucléo est à l'opposé de celui sur les Arduino nano (relativement aux connecteurs sur les bords). Du coup les 12V d'alimentation se sont retrouvé sur la broche D12... J'ai eu le droit à de la magic smoke !
- Galère avec les bibliothèques de gestion de pas à pas : l'utilisation de driver type DRV8825 pour contrôler des moteurs pas à pas nécessite l'envoie d'un signal pour chaque pas, d'une durée mini de 2 μs, ce qui bloque l’exécution du programme pendant ces 2 μs... L’exécution d'autre tache devient difficile, car pour garder une vitesse de rotation constance, il est nécessaire d'appeler le plus régulièrement possible une fonction pour faire tourner les roues. À cause de cela, je n'ai pas réussi à utiliser un capteur de distance ultra-son type HC-SR04, car pour son fonctionnement il est aussi nécessaire d'avoir des microDelay. Est-ce qu'un µC plus rapide (comme le STM32F303 que j'ai cramé héhé) résoudrait ce souci ? Le temps d'exécution des autres calculs étant plus rapide ?
- Découverte de ROS
- Installation en MV
- …
Code
#include <Arduino.h>
#include <AccelStepper.h>
#include <MultiStepper.h>
#define stepsPerRevolution 400 //200*2 micro-step
#define MOTORS_ENABLE_PIN 8
#define DIR_X 2
#define STEP_X 5
#define DIR_Y 3
#define STEP_Y 6
#define DIR_Z 7
#define STEP_Z 4
#define WEEL_DIAMETER 0.064 //m
#define AXE_TRACK 0.22 //m
#define MAX_ACCELERATION 1 //m/s²
#define MAX_SPEED 0.5 //m/s
//Define both left and right motors
AccelStepper stepperLeft(1, STEP_X, DIR_X);
AccelStepper stepperRight(1, STEP_Y, DIR_Y);
MultiStepper steppers;
//Define an array of AccelSteppes from stepperLeft and stepperRight objects to use them in loops
AccelStepper *Steppers[2] = {&stepperLeft, &stepperRight};
UltraSonicDistanceSensor distanceSensor(12, 9); // Initialize sensor that uses digital pins 12 and 13.
int speedToStepsPerS(float V);
int distanceToSteps (float D);
void initializeMotors();
void pivotTurnRight();
void pivotTurnLeft();
void setup() {
Serial.begin(115200);
Serial.println("Let's go!!");
// put your setup code here, to run once:
pinMode(LED_BUILTIN, OUTPUT);
for (int i = 0; i < 6; i++)
{
digitalWrite(LED_BUILTIN, HIGH);
delay(20);
digitalWrite(LED_BUILTIN, LOW);
delay(20);
}
initializeMotors();
}
void loop() {
pivotTurnRight();
delay(1000);
pivotTurnLeft();
delay(1000);
}
void initializeMotors() {
for (int i = 0; i < 2; i++)
{
Steppers[i]->setEnablePin(MOTORS_ENABLE_PIN);
Steppers[i]->setPinsInverted(false, false, true);
Steppers[i]->enableOutputs();
Steppers[i]->setMinPulseWidth(2);
Steppers[i]->setAcceleration(speedToStepsPerS(MAX_ACCELERATION));
Steppers[i]->setMaxSpeed(speedToStepsPerS(MAX_SPEED));
}
steppers.addStepper(stepperLeft);
steppers.addStepper(stepperRight);
}
int speedToStepsPerS(float V) {
int S = (V*stepsPerRevolution/(WEEL_DIAMETER*PI)); //S[steps/s]; V[m/s]; WEEL_DIAMETER[m]
return S;
}
int distanceToSteps(float D) {
int S = D*stepsPerRevolution/(PI*WEEL_DIAMETER); //S[steps]; D[m]; WEEL_DIAMETER[m]
return S;
}
void pivotTurnRight() {
long position[2];
position[0] = distanceToSteps(PI*AXE_TRACK/8);
position[1] = distanceToSteps(-PI*AXE_TRACK/8);
steppers.moveTo(position);
steppers.runSpeedToPosition();
}
void pivotTurnLeft() {
long position[2];
position[0] = distanceToSteps(-PI*AXE_TRACK/8);
position[1] = distanceToSteps(PI*AXE_TRACK/8);
steppers.moveTo(position);
steppers.runSpeedToPosition();
}