Après d'intenses recherches PASSIONNANTES je suis en phase de validation de mon projet !
Un dolly automatique avec 2 bumpers aller/retour et un capteur RGB embarqué. Ce dernier permettra selon la couleur captée d’exécuter telle ou telle action (rotation de la caméra, pause) représentée en vert, gris et bleu sur mon schéma de principe.
vous vous compliquez peut-être la vie s'il n'y a que 2 couleurs toujours dans le même ordre, votre arduino saura si vous êtes sur la phase aller ou retour donc pourra décider de lui même lors du passage d'un poteau quelle action effectuer
A moins que vous n'ayez plein de couleur possibles et que vous vouliez donc suivant le poteau des actions différentes à l'aller et au retour ? --> oui, c'est possible et votre arduino lorsqu'il verra une couleur fait une action et s'il voit tout de suite après une autre couleur sans s'être bcp déplacé c'est qu'il sagit du même poteau et donc il l'ignorera... ça se code
Effectivement j'avais imagine un ensemble de couleur spécifique à l'aller et un autre pour le retour.
Pourquoi des poteaux ?
J'ai prévu des poteaux amovibles qu'on peut fixer n'importe où sur le rail pour que le cadrage et panoramique de la caméra s'adapte en fonction du placement du sujet. Ou comment remplacer un cadreur humain ou un opérateur avec un joystick
C'est l'astuce la plus évidente pour moi...
votre dolly bouge en fonction d'un séquencement donné (ou d'un bout à l'autre du chemin)
quel que soit le sens du déplacement, vous essayez de détecter une couleur
Si vous en voyez une:
vous regardez quand (ou où si vous mesurez le déplacement) pour la dernière fois vous avez vu une couleur
si c'est très récent, c'est le même poteau (voire la même couleur car vous n'avez pas assez avancé) et donc vous ne faites rien sinon c'est un nouveau poteau et vous déclenchez l'action associée à cette couleur (vous pouvez aussi détecter qu'il n'y avait plus de poteau et donc la prochaine couleur, même proche pourrait déclencher).
NB --> Il faut prévoir une couleur pour "pas d'action" car vos poteaux devront toujours comporter 2 actions sinon au retour vous aurez la même action qu'à l'aller
5 couleurs sont suffisantes pour ce projet et cela implique à mon avis une mise en ordre, en priorité des conditions que j'avais indiqué dan sinon 1er message.
Au final chaque sujet/cible dispose de 3 poteaux pour gérer le cadrage
Il faut prévoir une couleur pour "pas d'action"
Je pense qu'il s'agit du poteau gris si on nous nous comprenons bien
un bon point de départ c'est de lire les tutos d'eskimon
Pour bien comprendre les moteurs (et pour bien débuter avec l'arduino), c'est bien de lire Le mouvement grâce aux moteurs - les tutos d'eskimon. (commencez par la partie Le moteur à courant continu)
ensuite jouez avec votre capteur de couleur pour le maitriser
Oui je commence à bien assimiler cela et j'avais commencé par là en plus
Merci
Le seul point ou je coince est la mise en forme du codage car j'ai l'impression il y a comme une imbrication de conditions avec des priorités selon si elles sont vérifiées ou pas
programmation par machine à états
Ah ça tombe bien car j'ai découvert cette notion et je me suis dit que pourrait servir.
#include <Stepper.h>
const int stepsPerRevolution = 4096; // nombre de pas dans un tour pour le moteur unipolaire byj48 ou mettre 4076 a tester
// indique sur quels pins le moteur est branche:
Stepper myStepper(stepsPerRevolution, 8, 9, 10, 11);
void setup()
{
// set the speed at 60 rpm:
myStepper.setSpeed(60);
// initialize the serial port:
Serial.begin(9600);
}
void loop()
{
// la liste des états possible de notre système
// ainsi qu'une variable etatCourant prenant une de ces valeurs
enum {estrouge, estbleu, estjaune, estgris, estmauve} couleur;
switch (couleur) {
case estrouge:
// si rouge alors rotation antihoraire de 33 degres en divisant par 3
Serial.println("counterclockwise");
myStepper.step(stepsPerRevolution/3);
delay(15000); // la camera filme la cible pendant 15 sec ok
break;
case estbleu:
// faire quelque chose d'autre
break;
case estjaune:
// faire quelque chose d'autre
break;
case estgris:
// faire quelque chose d'autre
break;
case estmauve:
// faire quelque chose d'autre
break;
}
}
Merci
Hormis les actions définies par les couleurs, le dolly continue d'avancer lentement, dans un sens ou dans l'autre.
J'ai prévu que le dolly fasse marche arriere quand il arrive à la fin du rail grâce à un bumper switch monté dessus
Il y aura 2 bumper switch au total, un devant et un derriere, qui auront si je commence à comprendre le code, un nom différent.
Voici le code que j 'ai trouvé et modifié pour gérer les bumpers (j'ai enlevé la led qui ne me servira pas)
#include <Servo.h> // doublon
const int bumperavant = 2; // switch bumper avant du dolly sur le pin 2
const int bumperarriere = 3; // switch bumper arriere du dolly sur le pin 3
int pbavant = 0; // A modofier ou supprimer ou ceonserver
int pbarriere = 0; // A modofier ou supprimer ou conserver
Servo servoavantarriere; // Definit le seul servo marche et arriere
void setup() {
servoavantarriere.attach(9); // servo sur le pin D9
// Set pin modes
pinMode(bumperavant, INPUT);
pinMode(bumperarriere, INPUT);
}
void loop() {
forward(); // Start forward
// Test bumper switches
pbavant = digitalRead(bumperavant);
pbarriere = digitalRead(bumparriere);
// si le switch arriere du dolly est active alors le dolly avance
if (pbavant == HIGH) {
reverse();
delay(500);
}
// si le switch avant du dolly est active alors le dolly recule
if (pbarriere == HIGH) {
reverse();
delay(500);
}
}
// Motion routines
void forward() {
servoavantarriere.write(180); // chiffre a verifier
}
void reverse() {
servoavantarriere.write(360); // chiffre a verifier
}
void stopRobot() {
servoavantarriere.write(90); // chiffre a verifier
}
Si on regarde le dolly comme système il a quelques états
a l’arrêt
en pause
en marche avant ou arrière
en train de traiter un ordre couleur
Cette machine à état reçoit comme événement un ordre de démarrage par l’humain sans doute, l’ordre du bumper avant ou arrière et la détection d’une couleur.
Ensuite il y a un sous système camera qui a ses ordres particuliers (pan / tilt / zoom / etc). Cette machine à état s’exécute soit en parallèle de la première quand l’événement couleur est rencontré (si vous voulez pouvoir zoomer doucement pendant qu’on avance par exemple) ou si vous voulez simplifier vous mettez en pause le premier système pendant qu’un événement couleur est effectué
Petite question - c’est pour faire du Time lapse sur une petite distance avec un objet proche ou un paysage très loin (ie focus stable) ou c’est vraiment pour un plateau avec des rails qui ne sont pas forcément rectilignes sur une grande distance ? Dans ce second cas l’orientation de l’axe la caméra et la mise au point seraient aussi à gérer - ce qui nécessitent d’instrumenter encore plus la caméra
Pour gérer les boutons et détecteurs de fin de course (bumper) qui sont comme des boutons, éventuellement utilisez la librairie de @bricoleau
La structure du code pourrait resembler un peu à cela (tapé ici donc y'a sans doute des bugs
// exemple Arduino Forum http://forum.arduino.cc/index.php?topic=603997.msg4099871#msg4099871
// J-M-L
#include <AccelStepper.h> // https://www.airspayce.com/mikem/arduino/AccelStepper/index.html
AccelStepper stepper; // config par défaut d'AccelStepper::FULL4WIRE (4 pins) sur 2, 3, 4, 5
#include <simpleBouton.h> // http://forum.arduino.cc/index.php?topic=375232.0
const uint8_t pinBoutonDebut = 6;
const uint8_t pinBumperDebut = 7;
const uint8_t pinBumperFin = 8;
//Cablage des boutons : pin---bouton---GND
simpleBouton boutonDebut(pinBoutonDebut);
simpleBouton bumperDebut(pinBumperDebut);
simpleBouton bumperFin(pinBumperFin);
enum : uint8_t {DOLLY_ARRET, DOLLY_PAUSE, DOLLY_AVANT, DOLLY_ARRIERE, DOLLY_CAMERA_ACTION} etatDolly = DOLLY_ARRET, etatDollyMemoire = DOLLY_ARRET;
enum ordre_t : uint8_t {ORDRE_AUCUN, ORDRE_ROUGE, ORDRE_VERT, ORDRE_BLEU} etatCommande = ORDRE_AUCUN;
void dollyMarcheAvant()
{
// moteur en avant
// ..
etatDolly = DOLLY_AVANT;
}
void dollyMarcheArriere()
{
// moteur en arrière
// ..
etatDolly = DOLLY_ARRIERE;
}
void dollyStop()
{
stepper.stop(); // arret du moteur
etatDolly = DOLLY_ARRET;
}
void dollyPause()
{
stepper.stop(); // arret du moteur
etatDolly = DOLLY_PAUSE;
}
void conditionsInitiales()
{
dollyStop();
etatCommande = ORDRE_AUCUN;
etatDollyMemoire = DOLLY_ARRET;
stepper.setMaxSpeed(100);
stepper.setAcceleration(20);
}
void testerBoutons()
{
// on met à jour l'état des boutons
boutonDebut.actualiser();
bumperDebut.actualiser();
bumperFin.actualiser();
// on teste s'il faut faire quelque chose
if (boutonDebut.vientDEtreEnfonce()) {
//======= APPUI DU BOUTON ==========
// faudra être un peu plus précis que ça pour gérer la pause, ceci est un exemple
if (etatDolly == DOLLY_ARRET) dollyMarcheAvant();
else if (etatDolly == DOLLY_PAUSE) {
if (etatDollyMemoire == DOLLY_AVANT) dollyMarcheAvant();
else dollyMarcheArriere();
} else {
etatDollyMemoire = etatDolly; // pour pouvoir remettre le bon état après
dollyPause();
}
//==================================
} else if (bumperDebut.vientDEtreEnfonce()) {
//======= BUMPER DU DUBUT ==========
dollyMarcheAvant();
delay(10); // éventuellement un petit delay() pour quitter l'appui du bumper
//==================================
} else if (bumperFin.vientDEtreEnfonce()) {
//======= BUMPER DE FIN ==========
dollyMarcheArriere();
delay(10); // éventuellement un petit delay() pour quitter l'appui du bumper
//================================
}
}
ordre_t testerCouleur()
{
ordre_t ordre = ORDRE_AUCUN;
// tester si on lit une couleur et affecter ordre, et changer etatDolly pour DOLLY_CAMERA_ACTION
// ...
if (ordre != ORDRE_AUCUN) {
dollyPause(); // or arrête de bouger le temps de faire le changement sur la caméra
etatDollyMemoire = etatDolly; // pour pouvoir remettre le bon état après exécution de l'ordre caméra
etatDolly = DOLLY_CAMERA_ACTION;
}
return ordre;
}
void setup()
{
Serial.begin(115200);
conditionsInitiales();
}
void loop()
{
testerBoutons();
ordre_t ordreEnCours = testerCouleur();
switch (etatDolly) {
case DOLLY_ARRET:
break;
case DOLLY_PAUSE:
break;
case DOLLY_AVANT:
stepper.run(); // fait un pas si nécessaire
break;
case DOLLY_ARRIERE:
stepper.run(); // fait un pas si nécessaire
break;
case DOLLY_CAMERA_ACTION:
// faire ce qu'il faut (éventuellement en plusieurs tours de loop())
// ...
// une fois le boulot effectuer, remettre l'état à etatDollyMemoire
break;
}
// ici on peut faire autre chose si ça ne prend pas trop de temps
// ....
}
bien sûr faut rajouter tout ce qui concerne les moteurs et le pilotage de l'appareil photo / caméra et toute la logique applicative, gestion de mémoire des états et du timing etc.. donc y'a du boulot et sans doute dans certains états (par exemple quand on va en avant ou en arrière) le code sera factorisable (faire un pas moteur au bon moment si vous utilisez la librairie accelStepper par exemple)
:o alors ça c'est vraiment de l'assistance ! merci infiniment !
a l'arrêt
en pause
en marche avant ou arrière
en train de traiter un ordre couleur
Cette machine à état reçoit comme événement un ordre de démarrage par l'humain sans doute, l'ordre du bumper avant ou arrière et la détection d'une couleur.
Oui c'es exact, côté Arduino, j'ai prévu que :
2 bumpers
2 steppers pour la rotation de l'axe de la caméra et l'avance du dolly
un capteur RGB pour la gestion de la rotation.
un bouton on/off pour allumer le dolly avant le show
une batterie rechargeable avec suffisamment d'autonomie
Petite question - c'est pour faire du Time lapse sur une petite distance avec un objet proche ou un paysage très loin (ie focus stable) ou c'est vraiment pour un plateau avec des rails qui ne sont pas forcément rectilignes sur une grande distance ? Dans ce second cas l'orientation de l'axe la caméra et la mise au point seraient aussi à gérer - ce qui nécessitent d'instrumenter encore plus la caméra
Le dolly ne va pas servir à faire du time lapse, mais pour faire un travelling lent sur une scène pour filmer un groupe. Le dolly est autonome car alimenté avec sa propre batterie (je me renseigne sur la notion d'autonomie) et effectue des aller/retour sur le rail.
J'ai déjà retenu un moyen d'assemblage du rail qui permettra de garantir sa rectitude et horizontalité pour éviter notamment que l'image sursaute quand le dolly passe sur un nouveau rail.
Aucun contrôle de la camera n'est prévu car j'aimerai faire simple :
le smartphone ou camescope est simplement vissé, l’inclinaison fixe est simplement vérifiée avant le concert.
le démarrage de l'enregistrement et du dolly peut se faire quelques instants avant le show. Le dolly posé puis activé via les witch /On/Off commence à faire ses aller/retours et ce, peu importe la direction qu'il prendra. L'essentiel que les déclencheurs de bumper soient présents sur les rail en fin de course
OK donc vous aurez un smartphone ou une GoPro sur le dolly et l’appareil fera la mise au point en continu pour vous
Si le rail est rectiligne vous aurez sans doute (suivant la distance au centre de la scène) à régler L’orientation de la caméra. Il faudra réfléchir à comment vous décidez de faire cela.
Si le rail est rectiligne vous aurez sans doute (suivant la distance au centre de la scène) à régler L'orientation de la caméra. Il faudra réfléchir à comment vous décidez de faire cela.
Ce n'est pas prévu car le dolly aura pour mission de filmer les musiciens qui sont devant la scene d’où mon systeme de capteur et de poteaux pour gérer la rotation en face des sujets. L'idée est d'obtenir un joli travelling panoramique lent pour voir chaque musicien.
Une fois le panoramique effectué la camera revient à la position 180degres et filme ce qui est visible en fond de scene
Ce soir je vérifie s'il est possible d'alimenter tout cela en autonomie via une ou 2 grandes batteries et ensuite je commande les pièces, car pour le moment je code "dans le vide"
Je pense que j'ai suffisamment d'info pour me débrouiller.
Bonjour
J'ai reçu les composants samedi et depuis j'ai ENORMEMENT appris!
Actuellement, j'arrive à coder un dolly avec 2 limit switches comme suit:
#include <AccelStepper.h>
#define FULLSTEP 4
#define HALFSTEP 8
//declare variables for the motor pins
int motorPin1 = 4; // Blue - 28BYJ48 pin 1
int motorPin2 = 5; // Pink - 28BYJ48 pin 2
int motorPin3 = 6; // Yellow - 28BYJ48 pin 3
int motorPin4 = 7; // Orange - 28BYJ48 pin 4
// Red - 28BYJ48 pin 5 (VCC)
// The sequence 1-3-2-4 required for proper sequencing of 28BYJ48
//AccelStepper stepper2(FULLSTEP, motorPin1, motorPin3, motorPin2, motorPin4);
AccelStepper stepper1(HALFSTEP, motorPin1, motorPin3, motorPin2, motorPin4);
int cwpin = 2; //digital pin number for the cw button
int ccwpin = 3; //digital pin number for the ccw button
void setup() {
stepper1.setMaxSpeed(1000);
stepper1.setAcceleration(50);
stepper1.setMinPulseWidth(100);
pinMode(cwpin, INPUT_PULLUP);
pinMode(ccwpin, INPUT_PULLUP);
}
void loop() {
if (digitalRead(cwpin) == LOW) // if the input is LOW (button pushed)
{
delay(100); //pause de 10 secondes en fin de course
CW();//rotates cw direction
}
if (digitalRead(ccwpin) == LOW){ // if the input is LOW (button pushed)
delay(100); //pause de 10 secondes en fin de course
CCW ();//rotates ccw direction
}
}
void CW() {
while (digitalRead(cwpin) == LOW)
{
stepper1.setSpeed(700);
stepper1.runSpeed();
}
}
void CCW() {
while (digitalRead(ccwpin) == LOW)
{
stepper1.setSpeed(-700); // negative for ccw
stepper1.runSpeed();
}
}
}
ça fonctionne bien, mais cela ne suffit par rapport à mon objectif.
Je vais tester le capteur RGB des que possible.
En revanche je peine pour faire tourner le 2eme stepper : j'aimerai tester la notion la rotation avec un angle définitif des que j'appuie sur un bouton.
Je sais coder cela, mais je ne sais pas l'inclure dans le code deja existant...
Aprés 3 semaines d'apprentissage et de tatonnement, me voila au stade suivant:
Definition de 3 états : demarrage, aller (reculer), retour (avancer)
Ajout de 2 limit switches à chaque extrémité du parcours du dolly
Utilisation prévue d'un capteur d'obstacle pour gérer l'arret du dolly et la rotation de la camera.
C'est plus simple à implementer que le capteur de couleur prévu au départ
Le tout dans une machine à état assez rudimentaire :
le dolly change de sens quand le bouton est enfoncé (et non relâché, nuance que j'ai compris )
Pour le moment je m'occupe seulement du comportement du stepper stepper_ar
Pouvez-vous m'indiquer ce qui coince dans ce code ?
Avec un immense merci !!!
#include <AccelStepper.h>
#include "simpleBouton.h" // http://forum.arduino.cc/index.php?topic=375232.0
// Define Constants
// Define step constants
#define FULLSTEP 4
#define HALFSTEP 8
#define motorPin1 8 // Blue - 28BYJ48 pin 1
#define motorPin2 9 // Pink - 28BYJ48 pin 2
#define motorPin3 10 // Yellow - 28BYJ48 pin 3
#define motorPin4 11 // Orange - 28BYJ48 pin 4
#define motorPin5 4 // Blue - 28BYJ48 pin 1
#define motorPin6 5 // Pink - 28BYJ48 pin 2
#define motorPin7 6 // Yellow - 28BYJ48 pin 3
#define motorPin8 7 // Orange - 28BYJ48 pin 4
// Define two motor objects
// The sequence 1-3-2-4 is required for proper sequencing of 28BYJ48
AccelStepper stepper_ar(HALFSTEP, motorPin1, motorPin3, motorPin2, motorPin4);// moteur en charge de l'avance et recul du dolly
AccelStepper stepper_camera(HALFSTEP, motorPin5, motorPin7, motorPin6, motorPin8);//moteur pivotant la caméra, à coder plus tard
simpleBouton bouton_aller(2);
simpleBouton bouton_retour(3);
enum State_enum {DEMARRAGE, ALLER, RETOUR};//etat du dolly stepper_ar
enum Sensors_enum {NONE, BUMPER_ALLER, BUMPER_RETOUR};//etats des 2 bumper limit swicht
void state_machine_run(uint8_t sensors);
void demarrage();
void aller();
void retour();
uint8_t read_IR();
uint8_t state = DEMARRAGE;
void setup() {
//Serial.begin(9600);
//Serial.begin(9600);
stepper_ar.setMaxSpeed(700.0);
stepper_ar.setAcceleration(400.0);
stepper_camera.setMaxSpeed(700.0);
stepper_camera.setAcceleration(400.0);
}
void loop(){
state_machine_run(read_IR());
bouton_aller.actualiser();//limit switch 1
bouton_retour.actualiser();//limit switch 2
stepper_ar.run();
stepper_camera.run();
}
void state_machine_run(uint8_t sensors)
{
switch(state)
{
case ALLER:
if(sensors == BUMPER_RETOUR){
aller();
state = RETOUR;
}
break;
case RETOUR:
if(sensors == BUMPER_ALLER){
retour();
state = ALLER;
}
break;
}
}
void demarrage()//demarrage du dolly
{
stepper_ar.moveTo(1000);//4096 = 2 tours
stepper_ar.setSpeed(400);
}
void aller()//trajet aller apres avoir activé le bouton_aller
{
stepper_ar.moveTo(1000);//4096 = 2 tours
stepper_ar.setSpeed(400);
}
void retour()//trajet retour apres avoir activé le bouton_retour
{
stepper_ar.moveTo(-1000);//4096 = 2 tours
stepper_ar.setSpeed(-400);
}
uint8_t read_IR()
{
if (bouton_retour.vientDEtreRelache())aller();
if (bouton_aller.vientDEtreRelache())retour();
}