Table des matières:

Comment faire un robot-bellhop : 3 étapes
Comment faire un robot-bellhop : 3 étapes

Vidéo: Comment faire un robot-bellhop : 3 étapes

Vidéo: Comment faire un robot-bellhop : 3 étapes
Vidéo: 1- Algorithme de Bellman-Ford: Application sur un exemple 2024, Novembre
Anonim

Par jeffreyfSuivez plus par l'auteur:

Comment participer au mini-concours iRobot Create Scholarship
Comment participer au mini-concours iRobot Create Scholarship
Comment participer au mini-concours iRobot Create Scholarship
Comment participer au mini-concours iRobot Create Scholarship
Comment créer des LOLCats, des chats Meme, des macros de chat ou des images de chat avec des légendes amusantes
Comment créer des LOLCats, des chats Meme, des macros de chat ou des images de chat avec des légendes amusantes
Comment créer des LOLCats, des chats Meme, des macros de chat ou des images de chat avec des légendes amusantes
Comment créer des LOLCats, des chats Meme, des macros de chat ou des images de chat avec des légendes amusantes

À propos: J'aime démonter les choses et comprendre comment elles fonctionnent. Je perds généralement tout intérêt après cela. En savoir plus sur Jeffreyf »

Ce Instructable montre comment utiliser l'iRobot Create pour faire un groom en mouvement. Cela a été entièrement levé avec la permission des instructions de carolDancer, et je l'ai mis en place comme exemple de participation à notre concours. Robo-BellHop peut être votre propre assistant personnel pour transporter vos sacs, épicerie, linge, etc., vous n'avez donc pas à. Le Create de base a un bac fixé sur le dessus et utilise deux détecteurs IR intégrés pour suivre l'émetteur IR de son propriétaire. Avec un code logiciel C très basique, l'utilisateur peut sécuriser des courses lourdes, une grande charge de linge ou votre sac de voyage sur Robo-BellHop et demander au robot de vous suivre dans la rue, dans le centre commercial, dans le couloir ou à travers l'aéroport - - partout où l'utilisateur doit aller. Fonctionnement de base1) Appuyez sur le bouton de réinitialisation pour allumer le module de commande et vérifiez que les capteurs s'enclenchent1a) la LED Play doit s'allumer lorsqu'elle voit l'émetteur IR vous suivre1b) la LED Advance doit s'allumer lorsque le le robot est très proche2) Appuyez sur le bouton noir pour exécuter la routine Robo-BellHop3) Fixez l'émetteur IR à la cheville et assurez-vous qu'il est allumé. Chargez ensuite le panier et partez !4) La logique du Robo-BellHop est la suivante:4a) Pendant que vous vous promenez, si le signal IR est détecté, le robot roulera à vitesse maximale4b) Si le signal IR sort de (en étant trop éloigné ou à un angle trop prononcé), le robot parcourra une courte distance à faible vitesse au cas où le signal serait capté à nouveau4c) Si le signal IR n'est pas détecté, le robot tournera à gauche et à droite dans un tenter de retrouver le signal4d) Si le signal IR est détecté mais que le robot heurte un obstacle, le robot tentera de contourner l'obstacle4e) Si le robot s'approche très près du signal IR, le robot s'arrêtera pour éviter de heurter le chevilles du propriétaireMatériel1 unité murale virtuelle iRobot - 301 $ détecteur IR de RadioShack - 31 $ connecteur mâle DB-9 de Radio Shack - 44 $ 6-32 vis de Home Depot - 2,502 $ piles 3V, j'ai utilisé le panier à linge D1 de Target - 51 $ roue supplémentaire sur le dos du robot CreateRuban électrique, fil et soudure

Étape 1: Recouvrir le capteur IR

Attachez du ruban électrique pour couvrir tout sauf une petite fente du capteur infrarouge à l'avant du robot Create. Démontez l'unité murale virtuelle et extrayez le petit circuit imprimé à l'avant de l'unité. C'est un peu délicat car il y a beaucoup de vis cachées et de supports en plastique. L'émetteur IR est sur le circuit imprimé. Couvrez l'émetteur IR avec un morceau de papier de soie pour éviter les reflets IR. Attachez le circuit imprimé à une sangle ou à une bande élastique qui peut s'enrouler autour de votre cheville. Branchez les batteries au circuit imprimé afin que vous puissiez avoir les batteries dans un endroit confortable (je l'ai fait pour que je puisse mettre les batteries dans ma poche).

Câblez le 2e détecteur IR au connecteur DB-9 et insérez-le dans la broche 3 (signal) et la broche 5 (masse) du Cargo Bay ePort. Fixez le 2e détecteur IR au sommet du capteur IR existant sur Create et recouvrez-le de quelques couches de papier de soie jusqu'à ce que le 2e détecteur IR ne voie pas l'émetteur à une distance que vous souhaitez que le robot Create arrête de garder de vous frapper. Vous pouvez tester cela après avoir appuyé sur le bouton Reset et regarder la LED Advance s'allumer lorsque vous êtes à la distance d'arrêt.

Étape 2: Fixez le panier

Fixez le panier à l'aide des vis 6-32. Je viens de monter le panier sur le dessus du robot Create. Faites également glisser la roue arrière pour placer un poids à l'arrière du robot Create.

Remarques: - Le robot peut supporter une charge assez importante, au moins 30 lb. - La petite taille semblait être la partie la plus difficile pour transporter des bagages - IR est très capricieux. Peut-être qu'il est préférable d'utiliser l'imagerie, mais c'est beaucoup plus cher

Étape 3: Téléchargez le code source

Téléchargez le code source
Téléchargez le code source

Le code source suit et est joint dans un fichier texte:

/****************************************************** ******************** follow.c ** -------- ** fonctionne sur le module de commande Create ** couvre tout sauf une petite ouverture sur le devant du capteur IR ** Create suivra un mur virtuel (ou tout IR envoyant le ** signal de champ de force) et, espérons-le, évitera les obstacles dans le processus ******************* ******************************************************** **/#include interrupt.h>#include io.h>#include#include "oi.h"#define TRUE 1#define FALSE 0#define FullSpeed 0x7FFF#define SlowSpeed 0x0100#define SearchSpeed 0x0100#define ExtraAngle 10#define SearchLeftAngle 125#define SearchRightAngle (SearchLeftAngle - 1000)#define CoastDistance 150#define TraceDistance 250#define TraceAngle 30#define BackDistance 25#define IRDetected (~PINB & 0x01)//states#define Ready 0#define Follow 1#define WasFollowing 2 #define SearchingLeft 3#define SearchingRight 4#define TracingLeft 5#define TracingRight 6#define BackingTraceLeft 7#define BackingTraceRight 8// Variables globalesv olatile uint16_t timer_cnt = 0;volatile uint8_t timer_on = 0;volatile uint8_t capteurs_flag = 0;volatile uint8_t capteurs_index = 0;volatile uint8_t capteurs_in[Sen6Size];volatile uint6_tize capteurs; volatile uint8_t inRange = 0;// Fonctionsvoid byteTx(uint8_t value);void delayMs(uint16_t time_ms);void delayAndCheckIR(uint16_t time_ms);void delayAndUpdateSensors(unsigned int time_ms);void initialize(void);void powerOnRo baud(uint8_t baud_code);void drive(int16_t speed, int16_t radius);uint16_t randomAngle(void);void defineSongs(void);int main (void){//state variableuint8_t state = Ready;int found = 0;int wait_counter = 0;// Configurer Create et moduleinitialize();LEDBothOff;powerOnRobot();byteTx(CmdStart);baud(Baud28800);byteTx(CmdControl);byteTx(CmdFull);// définir l'entrée/sortie pour le deuxième capteur IRDDRB &= ~0x01; //définir la broche 3 de l'ePort de la soute à cargaison comme un inputPORTB |= 0x01; //définir le pullup de la broche 3 de l'ePort du fret activé//la boucle du programme(VRAI){//Arrêter juste par précautiondrive(0, RadStraight);//définir LEDsbyteTx(CmdLeds);byteTx(((capteurs[SenVWall])?LEDPlay:0x00) | (inRange?LEDAdvance:0x00));byteTx(sensors[SenCharge1]);byteTx(64);IRDetected?LED2On:LED2Off;inRange?LED1On:LED1Off;//à la recherche du bouton utilisateur, vérifiez souventdelayAndUpdateSensors(10);delayAndCheckIR (10);if(UserButtonPressed) {delayAndUpdateSensors(1000);//boucle active(!(UserButtonPressed)&&(!sensors[SenCliffL])&&(!sensors[SenCliffFL])&&(!sensors[SenCliffFR])&&(! capteurs[SenCliffR])) {byteTx(CmdLeds);byteTx(((sensors[SenVWall])?LEDPlay:0x00) | (inRange?LEDAdvance:0x00));byteTx(sensors[SenCharge1]);byteTx(255);IRDetected ?LED2On:LED2Off;inRange?LED1On:LED1Off;switch(state) {case Ready:if(sensors[SenVWall]) {//vérifier la proximité avec le leaderif(inRange) {drive(0, RadStraight);} else {// drive straightdrive(SlowSpeed, RadStraight);state = Follow;}} else {//search for the beamangle = 0;distance = 0;wait_counter = 0;found = FALSE;drive(SearchSpeed, RadCCW);state = SearchingLeft;}break;case Suite:if(capteurs[SenBumpDrop] & BumpRight) {distance = 0;angle = 0;drive(-SlowSpeed, RadStraight); state=BackingTraceLeft;} else if(sensors[SenBumpDrop] & BumpLeft) {distance = 0;angle = 0;drive(-SlowSpeed, RadStraight);state=BackingTraceRight;} else if(sensors[SenVWall]) {//check for proximité de leaderif(inRange) {drive(0, RadStraight);state = Ready;} else {//drive straightdrive(FullSpeed, RadStraight);state = Follow;}} else {//juste perdu le signal, continuez lentement un cycledistance = 0;drive(SlowSpeed, RadStraight);state = WasFollowing;}break;case WasFollowing:if(sensors[SenBumpDrop] & BumpRight) {distance = 0;angle = 0;drive(-SlowSpeed, RadStraight);state=BackingTraceLeft;} else if(sensors[SenBumpDrop] & BumpLeft) {distance = 0;angle = 0;drive(-SlowSpeed, RadStraight);state=BackingTraceRight;} else if (sensors[SenVWall]) {//vérifier la proximité avec le leaderif (inRange) {drive(0, RadStraight);state = R eady;} else {//drive straightdrive(FullSpeed, RadStraight);state = Follow;}} else if (distance >= CoastDistance) {drive(0, RadStraight);state = Ready;} else {drive(SlowSpeed, RadStraight);}break;case SearchingLeft:if(found) {if (angle >= ExtraAngle) {drive(SlowSpeed, RadStraight);state = Follow;} else {drive(SearchSpeed, RadCCW);}} else if (capteurs[SenVWall]) {found = TRUE;angle = 0;if (inRange) {drive(0, RadStraight);state = Ready;} else {drive(SearchSpeed, RadCCW);}} else if (angle >= SearchLeftAngle) {drive(SearchSpeed, RadCW);wait_counter = 0;state = SearchingRight;} else {drive(SearchSpeed, RadCCW);}break;case SearchingRight:if(found) {if (-angle >= ExtraAngle) {drive(SlowSpeed, RadStraight);state = Suivant;} else {drive(SearchSpeed, RadCW);}} else if (sensors[SenVWall]) {found = TRUE;angle = 0;if (inRange) {drive(0, RadStraight);state = Ready;} else {drive(SearchSpeed, RadCCW);}} else if(wait_counter > 0) {wait_counter -= 20;drive(0, RadStraight);} else if (angle = Search RightAngle) {drive(0, RadStraight);wait_counter = 5000;angle = 0;} else {drive(SearchSpeed, RadCW);}break;case TracingLeft:if(sensors[SenBumpDrop] & BumpRight) {distance = 0;angle = 0;drive(-SlowSpeed, RadStraight);state=BackingTraceLeft;} else if(sensors[SenBumpDrop] & BumpLeft) {drive(0, RadStraight);state=Ready;} else if (capteurs[SenVWall]) {//check pour la proximité du leaderif(inRange) {drive(0, RadStraight);state = Ready;} else {//drive straightdrive(SlowSpeed, RadStraight);state = Follow;}} else if (!(distance >= TraceDistance)) { drive(SlowSpeed, RadStraight);} else if (!(-angle >= TraceAngle)) {drive(SearchSpeed, RadCW);} else {distance = 0;angle = 0;drive(SlowSpeed, RadStraight);state = Ready; }break;case TracingRight:if(sensors[SenBumpDrop] & BumpRight) {drive(0, RadStraight);state=Ready;} else if(sensors[SenBumpDrop] & BumpLeft) {distance = 0;angle = 0;drive(- SlowSpeed, RadStraight);state=BackingTraceRight;} else if (sensors[SenVWall]) {//vérifier la proximité du leaderif(inRang e) {drive(0, RadStraight);state = Ready;} else {//drive straightdrive(SlowSpeed, RadStraight);state = Follow;}} else if (!(distance >= TraceDistance)) {drive(SlowSpeed, RadStraight);} else if (!(angle >= TraceAngle)) {drive(SearchSpeed, RadCCW);} else {distance = 0;angle = 0;drive(SlowSpeed, RadStraight);state = Ready;}break;case BackingTraceLeft: if (sensors[SenVWall] && inRange) {drive(0, RadStraight);state = Ready;} else if (angle >=TraceAngle) {distance = 0;angle = 0;drive(SlowSpeed, RadStraight);state = TracingLeft; } else if (-distance >= BackDistance) {drive (SearchSpeed, RadCCW);} else {drive(-SlowSpeed, RadStraight);}break;case BackingTraceRight:if (sensors[SenVWall] && inRange) {drive(0, RadStraight);state = Ready;} else if (-angle >=TraceAngle) {distance = 0;angle = 0;drive(SlowSpeed, RadStraight);state = TracingRight;} else if (-distance >= BackDistance) {drive (SearchSpeed, RadCW);} else {drive(-SlowSpeed, RadStraight);}break;default://stopdrive(0, RadStraight);state = Re ady;break;}delayAndCheckIR(10);delayAndUpdateSensors(10);}//falaise ou bouton utilisateur détecté, permet à la condition de se stabiliser (par exemple, le bouton doit être relâché)drive(0, RadStraight);delayAndUpdateSensors(2000);}}} // Interruption de réception série pour stocker les valeurs des capteursSIGNAL(SIG_USART_RECV){uint8_t temp;temp = UDR0;if(sensors_flag){sensors_in[sensors_index++] = temp;if(sensors_index >= Sen6Size)sensors_flag = 0;}}// Timer 1 interruption aux délais dans msSIGNAL(SIG_OUTPUT_COMPARE1A){if(timer_cnt)timer_cnt--;elsetimer_on = 0;}// Transmettre un octet sur le port série void byteTx(uint8_t value){while(!(UCSR0A & _BV(UDRE0))); UDR0 = value;}// Retard pour le temps spécifié en ms sans mettre à jour les valeurs du capteurvoid delayMs(uint16_t time_ms){timer_on = 1;timer_cnt = time_ms;while(timer_on);}// Retard pour le temps spécifié en ms et vérifier la seconde Détecteur IRvoid delayAndCheckIR(uint16_t time_ms){uint8_t timer_val = 0;inRange = 0;timer_on = 1;timer_cnt = time_ms;while(timer_on) {if(!(timer_val == timer_cnt)) {inRange + = IRDetected;timer_val = timer_cnt;}}inRange = (inRange>=(time_ms>>1));}// Retard pour le temps spécifié en ms et mise à jour des valeurs du capteurvoid delayAndUpdateSensors(uint16_t time_ms){uint8_t temp;timer_on = 1; timer_cnt = time_ms;while(timer_on){if(!sensors_flag){for(temp = 0; temp Sen6Size; temp++)sensors[temp] = sensor_in[temp];// Mettre à jour les totaux cumulés de la distance et de l'angledistance += (int)((sensors[SenDist1] 8) | sensor[SenDist0]);angle += (int)((sensors [SenAng1] 8) | sensor[SenAng0]);byteTx(CmdSensors);byteTx(6);sensors_index = 0;sensors_flag = 1;}}}// Initialiser le microcontrôleur Mind Control&aposs ATmega168 void initialize(void){cli(); // Définir les broches d'E/S DDRB = 0x10;PORTB = 0xCF;DDRC = 0x00;PORTC = 0xFF;DDRD = 0xE6;PORTD = 0x7D;// Configurer le temporisateur 1 pour générer une interruption toutes les 1 msTCCR1A = 0x00;TCCR1B = (_BV (WGM12) | _BV(CS12));OCR1A = 71;TIMSK1 = _BV(OCIE1A);// Configurer le port série avec rx interruptUBRR0 = 19;UCSR0B = (_BV(RXCIE0) | _BV(TXEN0) | _BV(RXEN0));UCSR0C = (_BV(UCSZ00) | _BV(UCSZ01));// Activer interruptssei();}void powerOnRobot(void){// Si Create&aposs power est éteint, allumez-le si(!RobotIsOn){while(!RobotIsOn){RobotPwrToggleLow;delayMs(500); // Retard dans cet étatRobotPwrToggleHigh; // Transition de bas en haut pour basculer powerdelayMs(100); // Retard dans cet étatRobotPwrToggleLow;}delayMs(3500); // Retard pour le démarrage}}// Bascule le débit en bauds sur Create et modulevoid baud(uint8_t baud_code){if(baud_code = 11){byteTx(CmdBaud);UCSR0A |= _BV(TXC0);byteTx(baud_code);/ / Attendez que la transmission soit terminée while(!(UCSR0A & _BV(TXC0)));cli();// Changez le registre de débit en baudsif(baud_code == Baud115200)UBRR0 = Ubrr115200;else if(baud_code == Baud57600)UBRR0 = Ubrr57600;else if(baud_code == Baud38400)UBRR0 = Ubrr38400;else if(baud_code == Baud28800)UBRR0 = Ubrr28800;else if(baud_code == Baud19200)UBRR0 = Ubrr19200;else if(baud_code == Baud14400)14400r0;else if(baud_code == Baud9600)UBRR0 = Ubrr9600;else if(baud_code == Baud4800)UBRR0 = Ubrr4800;else if(baud_code == Baud2400)UBRR0 = Ubrr2400;else if(baud_code == Baud1200)UBRR0 = Ubrr1200;else if(baud_code == Baud600)UBRR0 = Ubrr600;else if(baud_code == Baud300)UBRR0 = Ubrr300;sei();delayMs(100);}}// Send Créer des commandes d'entraînement en termes de vitesse et de radiusvoid drive (int16_t vitesse, int16_t rayon){byteTx(CmdDrive);byteTx((uint 8_t)((vitesse >> 8) & 0x00FF));byteTx((uint8_t)(vitesse & 0x00FF));byteTx((uint8_t)((rayon >> 8) & 0x00FF));byteTx((uint8_t)(rayon & 0x00FF));}

Conseillé: