Оглавление:

Как сделать Robo-Bellhop: 3 шага
Как сделать Robo-Bellhop: 3 шага

Видео: Как сделать Robo-Bellhop: 3 шага

Видео: Как сделать Robo-Bellhop: 3 шага
Видео: Как получить расу В3 в Блокс Фрутс Роблокс? Пробуждение Гайд для новичков в Blox Fruits Roblox. 2024, Ноябрь
Anonim

Подписаться Еще от автора:

Как принять участие в мини-конкурсе iRobot Create Scholarship
Как принять участие в мини-конкурсе iRobot Create Scholarship
Как принять участие в мини-конкурсе iRobot Create Scholarship
Как принять участие в мини-конкурсе iRobot Create Scholarship
Как сделать LOLCats, мем-кота, макрос кота или картинки кота с забавными подписями
Как сделать LOLCats, мем-кота, макрос кота или картинки кота с забавными подписями
Как сделать LOLCats, мем-кота, макрос кота или картинки кота с забавными подписями
Как сделать LOLCats, мем-кота, макрос кота или картинки кота с забавными подписями

О себе: Мне нравится разбирать вещи и выяснять, как они работают. После этого я вообще теряю интерес. Подробнее о Джеффрифе »

В этом руководстве показано, как использовать iRobot Create для создания движущегося коридорного. Это было полностью снято с разрешения инструкций carolDancer, и я представил его как образец записи для нашего конкурса. Robo-BellHop может быть вашим личным помощником, чтобы нести ваши сумки, продукты, стирку и т. Д., Поэтому у вас нет к. Базовая модель Create имеет корзину, прикрепленную к верхней части, и использует два встроенных ИК-детектора, чтобы следить за ИК-передатчиком своего владельца. С помощью очень простого программного кода C пользователь может закрепить тяжелые продукты, большое количество белья или вашу ночную сумку на Robo-BellHop и заставить робота следовать за вами по улице, через торговый центр, по коридору или через аэропорт. - куда бы пользователь ни пошел. Основные операции1) Нажмите кнопку сброса, чтобы включить командный модуль и проверить срабатывание датчиков1a) светодиод Play должен загореться, когда он видит, что ИК-передатчик следует за вами 1b) светодиод Advance должен загореться, когда робот находится на очень близком расстоянии 2) Нажмите черную программную кнопку, чтобы запустить программу Robo-BellHop 3) Прикрепите ИК-передатчик к лодыжке и убедитесь, что он включен. Затем загрузите корзину и вперед! 4) Логика Robo-BellHop следующая: 4a) Когда вы идете, если обнаруживается ИК-сигнал, робот будет двигаться с максимальной скоростью 4b) Если ИК-сигнал выходит из диапазон (слишком далеко или слишком острый угол), робот будет проходить небольшое расстояние с низкой скоростью в случае повторного приема сигнала4c) Если ИК-сигнал не обнаруживается, робот будет поворачиваться влево и вправо в попытаться найти сигнал снова 4d) Если ИК-сигнал обнаружен, но робот наткнется на препятствие, робот попытается объехать препятствие4e) Если робот подойдет очень близко к ИК-сигналу, робот остановится, чтобы избежать столкновения с препятствием. Виртуальный настенный прибор iRobot - 301 доллар США от RadioShack - 31 доллар DB-9 штекерный разъем от Radio Shack - 44 доллара 6-32 винта от Home Depot - 2,502 доллара 3 В батарейки, я использовал корзину для белья D1 от Target - 51 доллар за дополнительное колесо для установки задняя часть робота Create Электрическая лента, проволока и припой

Шаг 1: прикрытие ИК-датчика

Прикрепите изоленту, чтобы закрыть все, кроме небольшой щели ИК-датчика на передней панели робота Create. Разберите виртуальный настенный блок и извлеките небольшую монтажную плату в передней части блока. Это немного сложно, потому что есть много скрытых винтов и пластиковых креплений. ИК-передатчик находится на печатной плате. Накройте ИК-передатчик куском папиросной бумаги, чтобы избежать ИК-отражений. Прикрепите печатную плату к ремешку или резинке, которые можно обернуть вокруг вашей лодыжки. Подключите батареи к печатной плате, чтобы вы могли расположить батареи в удобном месте (я сделал так, чтобы я мог положить батареи в карман).

Подключите 2-й ИК-датчик к разъему DB-9 и вставьте в грузовой отсек контакт 3 (сигнал) и контакт 5 (заземление) в грузовом отсеке. Прикрепите второй ИК-датчик к верхней части существующего ИК-датчика на Create и накройте его парой слоев папиросной бумаги, пока второй ИК-датчик не увидит излучатель на расстоянии, которое вы хотите, чтобы робот Create остановился, чтобы удержать от удара по тебе. Вы можете проверить это после того, как нажмете кнопку сброса и увидите, как загорится светодиод Advance, когда вы находитесь на дистанции остановки.

Шаг 2: прикрепите корзину

Закрепите корзину винтами 6-32. Я просто установил корзину на верхнюю часть робота Create. Также сдвиньте заднее колесо, чтобы вес находился на задней части робота Create.

Примечания: - Робот может нести небольшую нагрузку, по крайней мере, 30 фунтов. - Маленький размер казался самым сложным в том, чтобы заставить его перевозить любой багаж - ИК очень темпераментен. Возможно, использование изображений лучше, но это намного дороже

Шаг 3: Загрузите исходный код

Загрузите исходный код
Загрузите исходный код

Исходный код прилагается в текстовом файле:

/ *********************************************** ******************** follow.c ** -------- ** запускается на Create Command Module ** закрывает все, кроме небольшого отверстия на передней панели ИК-датчика ** Create будет следовать за виртуальной стеной (или любым ИК-излучателем, посылающим ** сигнал силового поля) и, надеюсь, избежать препятствий в процессе ***************** ************************************************* ** / # 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) // состояния # 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 // Глобальные переменныеv изменчивый uint16_t timer_cnt = 0; изменчивый uint8_t timer_on = 0; изменчивый uint8_t sizes_flag = 0; изменчивый uint8_t sensor_index = 0; изменчивый uint8_t sizes_in [Sen6Size]; изменчивый uint8_t датчики [Sen6Size]; изменчивый угол int16_t int16; volatile uint8_t inRange = 0; // Функцииvoid byteTx (значение uint8_t); void delayMs (uint16_t time_ms); void delayAndCheckIR (uint16_t time_ms); void delayAndUpdateSensors (unsigned int time_ms); void void initialize (power void); baud (uint8_t baud_code); void drive (int16_t velocity, int16_t radius); uint16_t randomAngle (void); void defineSongs (void); int main (void) {// state variable uint8_t state = Ready; int found = 0; int wait_counter = 0; // Настраиваем Create и moduleinitialize (); LEDBothOff; powerOnRobot (); byteTx (CmdStart); baud (Baud28800); byteTx (CmdControl); byteTx (CmdFull); // устанавливаем ввод-вывод для второго ИК-датчика DDRB & = ~ 0x01; // устанавливаем вывод 3 ePort грузового отсека как inputPORTB | = 0x01; // установить включение нагрузки ePort pin3 // программа loop while (TRUE) {// Остановить в качестве меры предосторожностиdrive (0, RadStraight); // установить LEDsbyteTx (CmdLeds); byteTx (((датчики [SenVWall])? LEDPlay: 0x00) | (inRange? LEDAdvance: 0x00)); byteTx (сенсоры [SenCharge1]); byteTx (64); IRDetected? LED2On: LED2Off; inRange? LED1On: LED1Off; // ищем пользовательскую кнопку, часто проверяемdelayAndUpdateIRCheckCheck (10); delayAndUpdateIRCheckSensors (10); (10); if (UserButtonPressed) {delayAndUpdateSensors (1000); // активный цикл while (! (UserButtonPressed) && (! Сенсоры [SenCliffL]) && (! Сенсоры [SenCliffFL]) && (! Сенсоры [SenCliffFR]) && (! сенсоры [SenCliffR])) {byteTx (CmdLeds); byteTx (((сенсоры [SenVWall])? LEDPlay: 0x00) | (inRange? LEDAdvance: 0x00)); byteTx (сенсоры [SenCharge1]); byteTx (255); IRDetected ? LED2On: LED2Off; inRange? LED1On: LED1Off; switch (state) {case Ready: if (Sensor [SenVWall]) {// проверяем приближение к leaderif (inRange) {drive (0, RadStraight);} else {// вести прямой привод (SlowSpeed, RadStraight); state = Follow;}} else {// ищем угол луча = 0; расстояние = 0; wait_counter = 0; найдено = ЛОЖЬ; привод (SearchSpeed, RadCCW); состояние = SearchingLeft;} перерыв; case Далее: если (датчики [SenBumpDrop] & BumpRight) {distance = 0; angle = 0; drive (-SlowSpeed, RadStraight); state = BackingTraceLeft;} else if (columns [SenBumpDrop] & BumpLeft) {distance = 0; angle = 0; drive (-SlowSpeed, RadStraight); state = BackingTraceRight;} else if (sizes [SenVWall]) {// проверяем наличие близость к leaderif (inRange) {drive (0, RadStraight); state = Ready;} else {// ехать по прямой (FullSpeed, RadStraight); state = Follow;}} else {// просто потеряли сигнал, продолжайте медленно cycledistance = 0; drive (SlowSpeed, RadStraight); state = WasFollowing;} break; case WasFollowing: if (sensor [SenBumpDrop] & BumpRight) {distance = 0; angle = 0; drive (-SlowSpeed, RadStraight); state = BackingTraceLeft;} else if (сенсоры [SenBumpDrop] & BumpLeft) {distance = 0; angle = 0; drive (-SlowSpeed, RadStraight); state = BackingTraceRight;} else if (sensor [SenVWall]) {// проверяем близость к лидерифу (inRange) {drive (0, RadStraight); state = R eady;} else {// ехать по прямой (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 (sensor [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 = Следование;} else {drive (SearchSpeed, RadCW);}} else if (sensor [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 (sensor [SenBumpDrop] & BumpRight) {distance = 0; angle = 0; drive (-SlowSpeed, RadStraight); state = BackingTraceLeft;} else if (columns [SenBumpDrop] & BumpLeft) {drive (0, RadStraight); state = Ready;} else if (sizes [SenVWall]) {// проверяем для близости к leaderif (inRange) {drive (0, RadStraight); state = Ready;} else {// ехать по прямой (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 (sensor [SenBumpDrop] & BumpRight) {drive (0, RadStraight); state = Ready;} else if (sensor [SenBumpDrop] & BumpLeft) {distance = 0; angle = 0; drive (- SlowSpeed, RadStraight); state = BackingTraceRight;} else if (сенсоры [SenVWall]) {// проверяем близость к leaderif (inRang e) {drive (0, RadStraight); state = Ready;} else {// ехать по прямой (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 (датчики [SenVWall] && inRange) {привод (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 (сенсоры [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);} // Обнаружен обрыв или пользовательская кнопка, разрешить стабилизацию состояния (например, отпустить кнопку) drive (0, RadStraight); delayAndUpdateSensors (2000);}}} // Прерывание последовательного приема для сохранения значений датчиков SIGNAL (SIG_USART_RECV) {uint8_t temp; temp = UDR0; if (sensor_flag) {sensor_in [sizes_index ++] = temp; if (sensor_index> = Sen6Size) Sensor_flag = 0;}} // Прерывание от таймера 1 к временным задержкам в msSIGNAL (SIG_OUTPUT_COMPARE1A) {if (timer_cnt) timer_cnt -; elsetimer_on = 0;} // Передаем байт через последовательный портvoid byteTx (значение uint8_t) {while (! (UCSR0A & _BV (UDRE0))); UDR0 = value;} // Задержка на указанное время в мс без обновления значений датчиков. Избегайте задержки Ms (uint16_t time_ms) {timer_on = 1; timer_cnt = time_ms; ИК-детекторvoid 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));} // Задержка на указанное время в мс и обновление значений датчиков, чтобы избежать delayAndUpdateSensors (uint16_t time_ms) {uint8_t temp; timer_on = 1; timer_cnt = time_ms; while (timer_on) {если (! flags_flag) {для (temp = 0; temp Sen6Size; temp ++) сенсоры [temp] = сенсоры_в [temp]; // Обновление промежуточных итогов расстояния и углового расстояния + = (int) ((сенсоры [SenDist1] 8) | сенсоры [SenDist0]); angle + = (int) ((сенсоры [SenAng1] 8) | сенсоры [SenAng0]); byteTx (CmdSensors); byteTx (6); sensor_index = 0; sensor_flag = 1;}}} // Инициализирует микроконтроллер Mind Control & aposs ATmega168void initialize (void) {cli (); // Установить контакты ввода-вывода DDRB = 0x10; PORTB = 0xCF; DDRC = 0x00; PORTC = 0xFF; DDRD = 0xE6; PORTD = 0x7D; // Настроить таймер 1 для генерации прерывания каждые 1 мс TCCR1A = 0x00; TCCR1B = (_BV (WGM12) | _BV (CS12)); OCR1A = 71; TIMSK1 = _BV (OCIE1A); // Настраиваем последовательный порт с помощью прерывания rxUBRR0 = 19; UCSR0B = (_BV (RXCIE0) | _BV (TXEN0) | _BV (RXEN0))); UCSR0C = (_BV (UCSZ00) | _BV (UCSZ01)); // Включить interruptssei ();} void powerOnRobot (void) {// Если питание Create & aposs выключено, включите его if (! RobotIsOn) {while (! RobotIsOn) {RobotPwrToggleLow; delayMs (500); // Задержка в этом состоянииRobotPwrToggleHigh; // Переход от низкого к высокому для переключения powerdelayMs (100); // Задержка в этом состоянии RobotPwrToggleLow;} delayMs (3500); // Задержка для запуска}} // Переключаем скорость передачи для Create и modulevoid baud (uint8_t baud_code) {if (baud_code = 11) {byteTx (CmdBaud); UCSR0A | = _BV (TXC0); byteTx (baud_code); / / Подождите, пока передача завершится, пока (! (UCSR0A & _BV (TXC0))); cli (); // Переключение регистра скорости передачи if (baud_code == Baud115200) UBRR0 = Ubrr115200; иначе if (baud_code == Baud57600) UBRR0 = Ubrr57600; иначе if (baud_code == Baud38400) UBRR0 = Ubrr38400; else if (baud_code == Baud28800) UBRR0 = Ubrr28800; else if (baud_code == Baud19200) UBRR0 = Ubrr19200; else if (baud_code == BaudR140400) UBrRR1 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) if (else UBRR0) baud_code == Baud600) UBRR0 = Ubrr600; else if (baud_code == Baud300) UBRR0 = Ubrr300; sei (); delayMs (100);}} // Отправить команды создания привода с точки зрения скорости и радиуса привода (int16_t velocity, int16_t радиус) {byteTx (CmdDrive); byteTx ((uint 8_t) ((скорость >> 8) & 0x00FF)); byteTx ((uint8_t) (скорость & 0x00FF)); byteTx ((uint8_t) ((радиус >> 8) & 0x00FF)); byteTx ((uint8_t) (радиус & 0x00FF));}

Рекомендуемые: