Теперь нам нужно запрограммировать нашу Arduino UNO, чтобы сбалансировать робота. Здесь происходит вся магия; концепция, стоящая за ней, проста. Мы должны проверить, наклоняется ли бот к передней или к задней части с помощью MPU6050, а затем, если он наклоняется к передней части, мы должны вращать колеса в прямом направлении, и если он наклоняется к задней части, мы должны вращать колеса в обратном направлении.
В то же время мы также должны контролировать скорость вращения колес, если бот слегка дезориентирован из центрального положения, колеса вращаются медленно, а скорость увеличивается, когда она больше удаляется от центрального положения. Для достижения этой логики мы используем алгоритм PID, который имеет центральное положение в качестве заданного значения и уровень дезориентации в качестве выходного.
Чтобы узнать текущее положение бота, мы используем MPU6050, который представляет собой 6-осевой акселерометр и датчик гироскопа. Чтобы получить достоверное значение положения от датчика, нам нужно использовать значение как акселерометра, так и гироскопа, поскольку значения от акселерометра имеют проблемы с шумом, а значения из гироскопа со временем дрейфуют. Таким образом, мы должны объединить оба и получить значение шага рыскания и крена нашего робота, из которого мы будем использовать только значение рыскания.
Теперь у нас есть библиотеки, добавленные в нашу среду разработки Arduino. Давайте начнем программирование для нашего Self-балансирующего робота. Как и всегда, полный код для проекта приведен в конце этой страницы, здесь я просто объясняю наиболее важные фрагменты кода. Ранее сообщалось, что код построен поверх примера кода MPU6050, мы просто собираемся оптимизировать код для нашей цели и добавить PID и технологию управления для нашего самобалансирующегося робота.
Сначала мы включаем библиотеки, которые необходимы для работы этой программы. Они включают встроенную библиотеку I2C, библиотеку PID и библиотеку MPU6050, которые мы только что загрузили.
Затем мы объявляем переменные, которые необходимы для получения данных от датчика MPU6050. Мы читаем как значения гравитационного вектора, так и значения кватерниона, а затем вычисляем значение угла и угла поворота бота. Конечный результат будет иметь массив float ypr [3].
Далее идет очень важный сегмент кода, и именно здесь вы будете тратить много времени на настройку нужного набора значений. Если ваш робот построен с очень хорошим центром тяжести, а компоненты симметрично расположены (что в большинстве случаев нет), тогда значение вашего уставки будет равно 180. Просто подключите ваш бот к серийному монитору Arduino и наклоните его до положения балансировки, прочитайте значение, отображаемое на последовательном мониторе, и это ваше заданное значение. Значение Kp, Kd и Ki должно быть настроено в соответствии с вашим ботом. Никакие два одинаковых бота не будут иметь одинаковых значений Kp, Kd и Ki, поэтому от него не уйти.
В следующей строке мы инициализируем алгоритм PID, передавая входные переменные input, output, set point, Kp, Ki и Kd. Из них мы уже установили значения заданного значения Kp, Ki и Kd в приведенном выше фрагменте кода. Значение входа будет текущим значением рыскания, которое считывается с датчика MPU6050, а значением выхода будет значение, которое рассчитывается по алгоритму PID. Таким образом, в основном алгоритм PID даст нам выходное значение, которое должно использоваться для коррекции значения Input, чтобы оно было близко к заданной точке.
Внутри функции void setup мы инициализируем MPU6050, настроив DMP (Digital Motion Processor). Это поможет нам объединить данные акселерометра с данными гироскопа и обеспечить надежное значение Yaw, Pitch and Roll. Мы не будем углубляться в это, так как это будет далеко за пределами темы. Во всяком случае, один сегмент кода, который вы должны искать в функции настройки, представляет собой значения смещения гироскопа. Каждый датчик MPU6050 имеет собственные значения смещений, вы можете использовать этот эскиз Arduino для расчета значения смещения вашего датчика и соответственно обновить следующие строки в вашей программе.
Мы также должны инициализировать контакты PWM Digital, которые мы используем для подключения наших двигателей. В нашем случае это D6, D9, D10 и D11. Таким образом, мы инициализируем эти контакты, поскольку выходные выводы делают их LOW по умолчанию.
Внутри основной функции цикла мы проверяем, готовы ли данные из MPU6050 для чтения. Если да, то мы используем его для вычисления значения PID, а затем отображаем входное и выходное значение PID на последовательном мониторе, чтобы проверить, как реагирует PID. Затем, основываясь на значении вывода, мы решаем, должен ли бот двигаться вперед или назад или стоять на месте.
Поскольку мы предполагаем, что MPU6050 вернет 180, когда бот будет вертикально. Мы получим положительные значения коррекции, когда бот падает вперед, и мы получим значения отрицательными, если бот падает назад. Поэтому мы проверяем это условие и вызываем соответствующие функции для перемещения бота вперед или назад.
Выходная переменная PID также определяет, как быстро двигатель должен вращаться. Если бот вот-вот упадет, мы сделаем небольшую коррекцию, медленно вращая колесо. Если эти незначительные корректировки работают, и все еще, если бот падает, мы увеличиваем скорость двигателя. Значение того, как быстро вращаются колеса, будет определяться алгоритмом PI. Заметим, что для функции Reverse мы умножили значение вывода с -1, чтобы мы могли преобразовать отрицательное значение в положительное.
geekhouse.tech
Кружки робототехники в наше время определенно пользуются успехом. Лего, ардуино, скретчи и много чего еще доступно современным детям (я уверен, многие, как и я, в этом плане завидуют нынешней детворе). Будучи преподавателем робототехники, решил поделиться некоторым материалом, который у меня накопился за пару лет работы, а именно довольно простым роботом и несколькими занятиями с ним.
Данные агрегаты используется мною на занятиях для того, чтобы объяснить детям принципы работы драйвера двигателя, датчика линии и дальномера. Дети, которых настигло изучение данного робота, уже как правило отучились год и имеют минимальные представления об Arduino, моторах и электротехнике в целом. В интернете много проектов с данными комплектующими, но разработать свою машинку меня мотивировало две вещи – хотелось использовать отсек под 4 батарейки АА и иметь возможность надежно прикрепить к роботу практически любой датчик (для этого в конструкции есть несколько дополнительных крепежных отверстий).
Управляется робот платой Arduino Uno с motor shield l293d, из датчиков я ставил дальномер HC-SR04 и два датчика линии tcrt5000 (имеет как цифровой, так и аналоговый вывод).
Корпус робота состоит из 3 деталей (не считая необязательных креплений под датчики), которые печатаются на 3D-принтере. Для сборки понадобится крепеж М3, все необходимые элементы я описал в документе, лежащем с файлами для 3D-принтера.
Программируется робот, как и в стандартной среде Arduino IDE (дети постарше), так и в программе miniBloq (для младших групп). Для стандартной среды используется библиотека AFMotor, которая необходима для работы с шилдом драйверов двигателя. В miniBloq-е для работы необходимо выбрать в разделе оборудование робота «ta-bot v1», использующего аналогичный драйвер.
Имея на борту дальномер и датчики линии, робот годится для участия в соревнованиях по многим дисциплинам, но создан был именно для обучения, занять призовые места с ним не получится.
Занятия, которые с ним можно провести:
В папке с деталями также можно найти несколько готовых занятий из вышеперечисленного списка.
habr.com
Существует множество подходов для решения задачи следования по линии. Выбор одного из них зависит от конкретной конструкции робота, от количества сенсоров, их расположения относительно колёс и друг друга.
В нашем примере будет собран робот на лёгкой платформе с двумя колёсами и двумя датчиками линии, расположенными на днище робота перед колёсами.
В результате выглядеть он будет так:
Для нашего примера понадобятся следующие детали:
Вообще говоря, лучше было бы использовать NiMH-аккумуляторы: они лучше отдают ток и значительно дольше держат напряжение, но для целей этого проекта одной батарейки на 9 В вполне хватило.
Сначала соберём робота, установим всю механику и электронику.
Для начала прикрепим колёса к моторам.
Затем с помощью пластиковых П-образных креплений прикручиваем моторчики к платформе. Обратите внимание на взаимное расположение крепления и моторчики: в креплении есть небольшие углубления, так что если всё соединить правильно, то моторчики будут крепко держаться и никуда не выскочат.
Теперь крепим балансировочный шар.
Отлично! Платформа собрана. Если вам кажется, что колёсам отведено слишком мало места и они трутся о платформу, то скорее всего вам нужно посильнее надавить на колёса, чтобы они плотнее сели на вал мотора.
Закрепим их, как показано на фото:
Можно было бы выбрать и другое место. Это могло бы сделать контроль проще или сложнее, а самого робота более или менее эффективным. Оптимальное расположение — вопрос серии экспериментов. Для этого проекта просто был выбран такой способ крепления.
Arduino закрепим с противоположной стороны двумя винтиками и гайками.
Опять же, можно выбрать и другое место. Например над колёсами, если приподнять Arduino на латунных стойках. Это изменило бы положение центра масс и повлияло бы на эффективность робота в лучшую или худшую сторону.
Установим Motor Shield на Arduino и подсоединим соединительные провода. Обратите внимание, чтобы соотвествовать программному коду из примера ниже, моторчики соединены с Motor Shield так: правый — к клеммам M1 с прямой полярностью (плюс к плюсу), а левый — к M2 с обратной (плюс к минусу).
В этом проекте, для экономии времени концы соединительных проводов просто скручены с контактами моторов. При работе «начисто» стоит жёстко припаять провода к моторам.
Присоединяем сверху Troyka Shield и подключаем датчики к 8 и 9 цифровым контактам. В итоге получаем следующую конструкцию:
Теперь напишем программу, которая заставит собранную конструкцию двигаться по нарисованной линии. В проекте мы будем использовать чёрную линию, напечатанную на белых листах бумаги.
Пусть у нас усть белое поле, и на нём чёрным нарисован трек для нашего робота. Используемые датчики линии выдают логический ноль, когда «видят» чёрное и единицу, когда «видят» белое.
На прямой робот должен пропускать трек между сенсоров, то есть оба сенсора должны показывать единички.
При повороте траектории направо, правый сенсор наезжает на трек и начинает показывать логический ноль. При повороте налево, ноль показывает левый сенсор.
Таким образом получаем простую систему с тремя состояниями:
STATE_FORWARD
— нужно ехать вперёд
STATE_RIGHT
— нужно поворачиваться направо
STATE_LEFT
— нужно поворачиваться налево
На вход системы поступает информация с сенсоров. Получаем следующую логику переходов:
Левый | Правый | Целевое состояние |
---|---|---|
0 | 0 | STATE_FORWARD |
0 | 1 | STATE_RIGHT |
1 | 0 | STATE_LEFT |
1 | 1 | STATE_FORWARD |
// Моторы подключаются к клеммам M1+,M1-,M2+,M2- // Motor shield использует четыре контакта 6,5,7,4 для управления моторами #define SPEED_LEFT 6 #define SPEED_RIGHT 5 #define DIR_LEFT 7 #define DIR_RIGHT 4 #define LEFT_SENSOR_PIN 8 #define RIGHT_SENSOR_PIN 9 // Скорость, с которой мы движемся вперёд (0-255) #define SPEED 35 // Коэффициент, задающий во сколько раз нужно затормозить // одно из колёс для поворота #define BRAKE_K 4 #define STATE_FORWARD 0 #define STATE_RIGHT 1 #define STATE_LEFT 2 int state = STATE_FORWARD; void runForward() { state = STATE_FORWARD; // Для регулировки скорости `SPEED` может принимать значения от 0 до 255, // чем болше, тем быстрее. analogWrite(SPEED_LEFT, SPEED); analogWrite(SPEED_RIGHT, SPEED); // Если в DIR_LEFT или DIR_RIGHT пишем HIGH, мотор будет двигать соответствующее колесо // вперёд, если LOW - назад. digitalWrite(DIR_LEFT, HIGH); digitalWrite(DIR_RIGHT, HIGH); } void steerRight() { state = STATE_RIGHT; // Замедляем правое колесо относительно левого, // чтобы начать поворот analogWrite(SPEED_RIGHT, SPEED / BRAKE_K); analogWrite(SPEED_LEFT, SPEED); digitalWrite(DIR_LEFT, HIGH); digitalWrite(DIR_RIGHT, HIGH); } void steerLeft() { state = STATE_LEFT; analogWrite(SPEED_LEFT, SPEED / BRAKE_K); analogWrite(SPEED_RIGHT, SPEED); digitalWrite(DIR_LEFT, HIGH); digitalWrite(DIR_RIGHT, HIGH); } void setup() { // Настраивает выводы платы 4,5,6,7 на вывод сигналов for(int i = 4; i <= 7; i++) pinMode(i, OUTPUT); // Сразу едем вперёд runForward(); } void loop() { // Наш робот ездит по белому полю с чёрным треком. В обратном случае не нужно // инвертировать значения с датчиков boolean left = !digitalRead(LEFT_SENSOR_PIN); boolean right = !digitalRead(RIGHT_SENSOR_PIN); // В какое состояние нужно перейти? int targetState; if (left == right) { // под сенсорами всё белое или всё чёрное // едем вперёд targetState = STATE_FORWARD; } else if (left) { // левый сенсор упёрся в трек // поворачиваем налево targetState = STATE_LEFT; } else { targetState = STATE_RIGHT; } if (state == targetState) { // мы уже делаём всё что нужно, // делаем измерения заново return; } switch (targetState) { case STATE_FORWARD: runForward(); break; case STATE_RIGHT: steerRight(); break; case STATE_LEFT: steerLeft(); break; } // не позволяем сильно вилять на прямой delay(50); }
Однако если выставить скорость моторов побольше, мы столкнёмся со следующей проблемой: наш робот будет вылетать с трека, не успевая отреагировать на поворот. Это связано с тем, что наши моторчики не умеют тормозить мгновенно.
В этом легко убедиться поставив следующий эксперимент: с заданной скоростью робот будет двигаться по поверхности, и в некоторый момент будет установлена нулевая скорость и измерен тормозной путь робота. Пусть робот разгоняется по монотонной поверхности и тормозится при фиксировании импровизированной стоп-линии.
Эксперимент проведём для разных скоростей. Код программы для эксперимента таков:
#define LEFT_SENSOR_PIN 8 #define RIGHT_SENSOR_PIN 9 #define SPEED_LEFT 6 #define SPEED_RIGHT 5 #define DIR_LEFT 7 #define DIR_RIGHT 4 // Для того чтобы убедиться, что именно тормозной путь долог, а не команда остановиться // приходит слишком поздно, будем включать светодиод, когда отдаётся команда. #define LED_PIN 13 int currSpeed = 40; void setup() { for(int i = 4; i <= 7; ++i) pinMode(i, OUTPUT); analogWrite(SPEED_RIGHT, currSpeed); digitalWrite(DIR_RIGHT, HIGH); analogWrite(SPEED_LEFT, currSpeed); digitalWrite(DIR_LEFT, HIGH); pinMode(LED_PIN, OUTPUT); } void loop() { if (currSpeed > 120) return; boolean white[] = { !digitalRead(LEFT_SENSOR_PIN), !digitalRead(RIGHT_SENSOR_PIN) }; if (white[0] && white[1]) { // едем пока не упрёмся return; } // зажигаем светодиод, останавливаем моторы // и наблюдаем digitalWrite(LED_PIN, HIGH); analogWrite(SPEED_RIGHT, 0); analogWrite(SPEED_LEFT, 0); delay(5000); // повторяем эксперимент, увеличивая скорость // на 10 пунктов currSpeed += 10; if (currSpeed > 120) return; digitalWrite(LED_PIN, LOW); analogWrite(SPEED_RIGHT, currSpeed); analogWrite(SPEED_LEFT, currSpeed); }
На той поверхности, на которой проводился эксперимент, были получены следующие результаты:
Таким образом, начиная с некоторого момента у нашего робота нет никакой возможности успеть среагировать и остаться на треке.
Что можно сделать?! После того, как сенсоры улавливают поворот, можно остановиться и вернуться назад на некоторое расстояние, зависящее от скорости перед остановкой. Однако мы можем отдать команду роботу ехать с какой-то скоростью, но не можем приказать ему проехать какое-то расстояние.
Для того, чтобы понять зависимость расстояния при заднем ходе от времени, был проведён ещё один замер:
#define SPEED_LEFT 6 #define SPEED_RIGHT 5 #define DIR_LEFT 7 #define DIR_RIGHT 4 void go(int speed, bool reverseLeft, bool reverseRight, int duration) { analogWrite(SPEED_LEFT, speed); analogWrite(SPEED_RIGHT, speed); digitalWrite(DIR_LEFT, reverseLeft ? LOW : HIGH); digitalWrite(DIR_RIGHT, reverseRight ? LOW : HIGH); delay(duration); } void setup() { for(int i = 4; i <= 7; ++i) pinMode(i, OUTPUT); } void loop() { // Задержка 5 секунд после включения питания delay(5000); for (int i = 200; i <= 1000; i += 100) { // Несколько сотен мс вперёд go(50, false, false, 200); go(0, false, false, 0); // Задержка 5 секунд delay(5000); } // Остановка до ресета или выключения питания go(0, false, false, 0); // Приехали while (true) ; }
На скорости 50, например, робот проделывал путь, зависящий от времени следующим образом:
Полученные две зависимости были линейно аппроксимированы, затем была выведена формула зависимости времени, которое надо двигаться назад, от скорости перед остановкой.
Обратим внимание на то, что у вас значения могут оказаться другими: из-за особенностей сборки либо из-за поверхности, поэтому в общем случае лучше провести все измерения самостоятельно.
Перед финальным экспериментом произведём ещё несколько поправок.
Во-первых, нам необязательно давать команду ехать назад перед каждым поворотом, как мы помним, на маленькой скорости робот прекрасно справляется и без этого. К тому же лучше ему двигаться не прямо назад, а немного поворачивая, всё-таки робот находится перед поворотом.
Во-вторых, нам стоит различать состояния робота: когда он движется по прямой, и ничто ему не мешает ускоряться; и когда робот входит в поворот. В первом случае действительно будем увеличивать скорость робота для более динамичного прохождения трека, во втором случае будем сбрасывать скорость до значения, достаточного для успешного прохождения поворота, и будем держать эту скорость ещё какое-то время.
В итоге наш код будет выглядит следующим образом:
// Моторы подключаются к клеммам M1+,M1-,M2+,M2- // Motor shield использует четыре контакта 6,5,7,4 для управления моторами #define SPEED_LEFT 6 #define SPEED_RIGHT 5 #define DIR_LEFT 7 #define DIR_RIGHT 4 #define LEFT_SENSOR_PIN 8 #define RIGHT_SENSOR_PIN 9 // Скорость, с которой мы движемся вперёд (0-255) #define SPEED 100 // Скорость прохождения сложных участков #define SLOW_SPEED 35 #define BACK_SLOW_SPEED 30 #define BACK_FAST_SPEED 50 // Коэффициент, задающий во сколько раз нужно затормозить // одно из колёс для поворота #define BRAKE_K 4 #define STATE_FORWARD 0 #define STATE_RIGHT 1 #define STATE_LEFT 2 #define SPEED_STEP 2 #define FAST_TIME_THRESHOLD 500 int state = STATE_FORWARD; int currentSpeed = SPEED; int fastTime = 0; void runForward() { state = STATE_FORWARD; fastTime += 1; if (fastTime < FAST_TIME_THRESHOLD) { currentSpeed = SLOW_SPEED; } else { currentSpeed = min(currentSpeed + SPEED_STEP, SPEED); } analogWrite(SPEED_LEFT, currentSpeed); analogWrite(SPEED_RIGHT, currentSpeed); digitalWrite(DIR_LEFT, HIGH); digitalWrite(DIR_RIGHT, HIGH); } void steerRight() { state = STATE_RIGHT; fastTime = 0; // Замедляем правое колесо относительно левого, // чтобы начать поворот analogWrite(SPEED_RIGHT, 0); analogWrite(SPEED_LEFT, SPEED); digitalWrite(DIR_LEFT, HIGH); digitalWrite(DIR_RIGHT, HIGH); } void steerLeft() { state = STATE_LEFT; fastTime = 0; analogWrite(SPEED_LEFT, 0); analogWrite(SPEED_RIGHT, SPEED); digitalWrite(DIR_LEFT, HIGH); digitalWrite(DIR_RIGHT, HIGH); } void stepBack(int duration, int state) { if (!duration) return; // В зависимости от направления поворота при движении назад будем // делать небольшой разворот int leftSpeed = (state == STATE_RIGHT) ? BACK_SLOW_SPEED : BACK_FAST_SPEED; int rightSpeed = (state == STATE_LEFT) ? BACK_SLOW_SPEED : BACK_FAST_SPEED; analogWrite(SPEED_LEFT, leftSpeed); analogWrite(SPEED_RIGHT, rightSpeed); // реверс колёс digitalWrite(DIR_RIGHT, LOW); digitalWrite(DIR_LEFT, LOW); delay(duration); } void setup() { // Настраивает выводы платы 4,5,6,7 на вывод сигналов for(int i = 4; i <= 7; i++) pinMode(i, OUTPUT); // Сразу едем вперёд runForward(); } void loop() { // Наш робот ездит по белому полю с чёрным треком. В обратном случае не нужно // инвертировать значения с датчиков boolean left = !digitalRead(LEFT_SENSOR_PIN); boolean right = !digitalRead(RIGHT_SENSOR_PIN); // В какое состояние нужно перейти? int targetState; if (left == right) { // под сенсорами всё белое или всё чёрное // едем вперёд targetState = STATE_FORWARD; } else if (left) { // левый сенсор упёрся в трек // поворачиваем налево targetState = STATE_LEFT; } else { targetState = STATE_RIGHT; } if (state == STATE_FORWARD && targetState != STATE_FORWARD) { int brakeTime = (currentSpeed > SLOW_SPEED) ? currentSpeed : 0; stepBack(brakeTime, targetState); } switch (targetState) { case STATE_FORWARD: runForward(); break; case STATE_RIGHT: steerRight(); break; case STATE_LEFT: steerLeft(); break; } }
Представленный алгоритм оставляет множество возможностей для улучшения и оптимизации. Скорость поворота можно так же менять адаптивно. Можно добавить контроль заноса. Можно поиграть с расположением сенсоров и центром масс. В конце концов можно получить непобедимого на треке робота.
Нет ничего лучше, чем обставить оппонента на секунду-другую.
wiki.amperka.ru
Чтобы наработать опыт в работе с платой Arduino, так сказать в качестве учебного опыта и просто для интереса был создан этот проект. Целью проекта было создать автомобиль, который может автономно перемещаться, объезжая различные препятствия и не сталкиваясь с ними.
1. Игрушечная Машинка с радиоуправлением (radio controlled).
Стоит эта штука около 20 баксов, если у вас есть возможность потратить больше, то можете использовать и получше.
2. Arduino Uno микроконтроллер — 25 долларов
3. Motor shield для контроля электромоторов — 20 долларов
4. GPS для навигации. Adafruit Ultimate GPS Shield — 50 долларов
5. Магнитометр в качестве компаса для навигации. Adafruit HMC5883 Magnetometer — 10 долларов
6. Ультразвуковой датчик расстояния, чтобы избегать препятствия. HC-SR04 — 6 долларов
7. ЖК-дисплей для отображения состояния транспортного средства и информации. LCD Display Blue 1602 IIC, I2C TWI — 6 долларов (можете использовать другой)
8. Инфракрасный датчик и пульт.
9. Arduino sketch (программа C++).
10. Тонкая древесная плита в качестве монтажной платформы.
11. Макетные платы. Одна длинная и узкая, а другая маленькая, чтобы отдельно установить на ней магнитометр подальше от других элементов.
12. Перемычки.
13. Набор для монтажа ультразвукового датчика — 12 долларов
14. Паяльник и припой.
15. Дрель.
Итак, в общем на всё ушло около 150 долларов, это при условии, если закупать все эти компоненты, поскольку возможно у вас уже что то имеется из этого.
Радиоуправление изъяли из ненужной игрушки, которая стоила 15 баксов.
Машинка здесь с двумя двигателями. С помощью одного движка пультом контролируется скорость движения робота, а с помощью другого контролируется рулевое управления.
Использовалась тонкая доска в качестве монтажной поверхности, на которой были прикреплены макетные платы, Arduino, ЖК и т.д. Батарейки размещены под доской и провода пропущены через просверленные отверстия.
Arduino управляется через программу С ++.
RC_Car_Test_2014_07_20_001.ino
1. TH — Задача, курс к текущей маршрутной точки
2. CH — Текущее направление робота
3. Err — Направление по компасу, показывает в каком направлении движется робот (влево или вправо)
4. Dist — Фокусное расстояние (в метрах) до текущей маршрутной точки
5. SNR — Sonar расстояние, то есть расстояние до любых объектов в передней части робота
6. Spd — Скорость робота
7. Mem — Память (в байтах). В памяти Arduino имеется 2 КБ
8. WPT n OF x — Показывает, где робот находится в списке маршрутных точек
Чтобы робот избегал препятствий, здесь использовался ультразвуковой датчик » Ping». Было решено совместить его с библиотекой Arduino NewPing, поскольку она лучше, чем простая PIng библиотека.
Библиотека была взята отсюда: https://github.com/fmbfla/Arduino/tree/master/NewPing
Датчик был установлен на бампере робота.
Для навигации курса, нам нужно управление различными точками. Был создан простой WaypointClass, который содержит значения долготы и широты. Затем создали WaypointClass для хранения маршрутных точек, и переменную currentWaypoint, чтобы отслеживать текущие маршрутные точки.
waypointClass.h
GPS используется для обнаружения расположения робота. При помощи навигации можно рассчитать курс и расстояние маршрутной точки.
Для GPS использовалась Adafruit Ultimate GPS Shield.
Использовалась библиотека: https://github.com/adafruit/Adafruit-GPS-Library
Образец кода: https://github.com/adafruit/Adafruit-GPS-Library/tree/master/examples/parsing
Для расчёта расстояния до точки: https://github.com/mikalhart/TinyGPS
GPS работает отлично и подходит для предоставления точных данных о местоположении, но масштаб, на котором работает этот проект слишком мал для того, чтобы обеспечить точную информацию.
Использовался цифровой магнитометр (который предоставлен коде как «компас»). «Компас» выполняет быстрое считывание с текущего направления транспорта. С помощью GPS вычисляется курс и куда поворачивать (влево или вправо).
Можете использовать машинку с более широким размахом рулевого управления (то есть более маневренную). Здесь использовалась дешёвая игрушка и поэтому робот ограничен в управлении.
Магнитометр был установлен подальше от моторов и прочих элем
payaem.ru
Материалы:
— Ультразвуковые датчики 2 шт (4 шт для модернизации в дальнейшем)
— Сервоприводы 4 шт
— Arduino (автор использует модель Uno)
— Макетная плата
— Провода
— Аккумуляторы 9,6В 2 шт
— Батарея 9В
— Колёса 4 шт
— Изолента
— Гайки, болты и т.д.
Шаг первый. Механическая часть.
В первую очередь роботу требуется прочное шасси. В статье имеются фото робота, но какое шасси использовать и как его делать не имеет значения. Автор делал три разных варианта робота. В статье рассмотрены только два варианта, так как третий был не особо удачным. Первый вариант робота имел форму, напоминающую грузовик. Он имел большой размер, но имел довольно малую скорость и плохо разворачивался. Кроме того, большого робота не очень удобно использовать. Второй вариант сделан более продумано, он получился намного меньше и компактнее.
Сначала на шасси ставят сервоприводы, таким образом, чтоб на их валы была возможность надеть колёса. Автор использует четыре колеса. Если взять мощные сервоприводы, тогда вообще можно использовать два колеса. Но шасси при этом нужно устроить так чтобы хватило места для аккумуляторов, печатной платы и Arduino.
После установки сервоприводов на них ставят колёса. Автор установил на вал после колеса дополнительную защиту от схода колеса. На передней части робота дополнительно поставлены два колеса, которые смогут помочь роботу заезжать на бордюры или иные небольшие препятствия если он в них упрётся. Для уменьшения трения на задние колёса добавили изоленту.
Далее, устанавливается батарейный отсек. Автор взял зарядное устройство Vex, и модифицировал его для питания двигателей, а не зарядки батарей. Теперь берётся плата, с неё отпаиваются провода «плюс» и GND, которые пойдут в разъём для зарядки батарей. Потом чёрные провода от двух батарей припаивают к проводу зарядки GND, а красные провода от батарей к положительному проводу зарядного устройства. Затем эти провода подключают к плате. После этого автор делает крепления для установки датчиков ультразвука на передней части робота. Если понадобится добавить дополнительные датчики потребуется удлинить крепление.
Шаг второй. Электронная часть.
Для этого шага больший знаний в электронике не потребуется. Аккумуляторы 9,6В соединяются параллельно, если же используется батарейный отсек от зарядного устройства, то ничего делать не потребуется, так как это уже сделано. Далее, согласно схеме, расположенной ниже, подключаются все компоненты. Следует учесть что в зависимости от длины шасси требуется подбирать провода, или же удлинять их, так как они могут недоставать до платы. Один сигнальный провод используют для первого и второго сервоприводов, а для третьего и четвёртого другой. Сделано это для синхронной работы первого и второго сервоприводов, потому что они расположены на одной стороне, то же самое касается третьего и четвёртого сервоприводов.
Для добавления дополнительных датчиков или сервоприводов всё делается по тому же принципу — к Arduino подключается сигнальный провод, GND к чёрному, а питание 5В к красному проводу. Следует помнить что GND от двигателей обязан быть подключён к GND батареи и Arduino.
Шаг третий. Программная часть.
Для написания кода автор использовал Processing. Для навигации используется двумерный массив (arraything), в него вводятся значения 0 или 1. Если ввести 1 это будет обозначать объект, значит, робот будет ездить только по 0. Код можно скачать ниже.
Получайте на почту подборку новых самоделок. Никакого спама, только полезные идеи!
*Заполняя форму вы соглашаетесь на обработку персональных данных
Становитесь автором сайта, публикуйте собственные статьи, описания самоделок с оплатой за текст. Подробнее здесь.usamodelkina.ru
Что такое библиотека?
Библиотека значительно упрощает управление роботом. Проект рассчитан на людей не особо сильных в программировании, но с желанием делать простых роботов. Для создания такой модели не требует знаний в области управления мотором. Библиотека сделает всё сама, сведёт программу до простейших команд «свернуть направо и ехать одну секунду» или же «ехать вперёд три секунды после чего ускорится». В библиотеке имеются примеры программ, которые помогут настроить CARduino.
Что делать если нет в наличии таких же материалов?
Собрать такого робота можно не имея таких материалов. Библиотека имеет возможность работать практически на любой сборке. Например, можно использовать другие колёса или материал для шасси, главное, чтобы изменённые детали выполняли такую же функцию.
Что может делать робот?
Функциональность робота практически безгранична. С помощью данной библиотеки написание программы для Arduino становится довольно лёгкой задачей. Макетная плата даёт возможность установить разнообразные датчики.
Стоимость робота
Автор живёт в США и поэтому посчитал что сборка робота с нуля обойдётся около 100$, имея большинство деталей, он потратил на проект 30$. Если есть возможность заказа компонентов в Китае можно сократить расходы примерно в 5 раз.
Использованные материалы:
— Arduino Uno — R3
— Макетная плата 30х10
— Держатель для Arduino и макетной платы
— Дальномер Sharp GP2Y0A02YK0F
— Микромоторы 2 шт
— Два колеса 49х12 мм
— Кронштейны для двигателя 2 шт
— Шариковые колёса 2 шт
— Драйверы моторов для Arduino 2 шт
— Основа для шасси (дерево) 15х10.75 см (размер подбирался согласно размеру держателя для Arduino и макетной платы)
— Небольшие саморезы по дереву
— Батарея 9В 1 шт
Шаг первый. Подготовительные работы.
Прежде чем приступить к сборке робота автор подготавливает компоненты. В первую очередь из большего чем нужно деревянного бруска вырезает прямоугольник нужного размера. Далее, собирает шариковые колёса, так как их доставили в разобранном виде, для сборки пользуется инструкцией к ним. Колёса присоединяет к моторам, и Arduino с макетной платой помещает в держатель для них.
Шаг второй. Установка шариковых колёс.
Эти колёса было решено установить с одной из сторон основы шасси, пользуясь карандашом, автор отметил по 0,5 см с каждой стороны доски. Для закрепления использовались саморезы по дереву.
Шаг третий. Установка моторов.
Этот шаг был довольно простым. Все что требовалось сделать, это вставить двигатели в кронштейны и закрепить их суперклеем на краях доски. Также можно использовать паяльник, важно не перепутать отрицательные и положительные контакты.
Шаг четвёртый. Установка Arduino и Bredboard.
Для начала потребовалось отметить расположение компонентов. Макетная плата помещается на переднюю часть держателя, а Arduino соответственно на заднюю, прикрепляются они саморезами на имеющихся отверстиях. Сам держатель помещается на шасси с помощью двух саморезов в центре.
Шаг пятый. Установка датчика.
Этот шаг тоже довольно простой. Спереди в центре отмечаются отверстия, и датчик крепится саморезами. Обязательно использовать оба отверстия датчика для крепления. При креплении автор ставит датчик так чтоб выводы на нём находились сверху. Затем JST провод вставляется в датчик и подсоединяется к макетной плате, красный к положительному контакту, чёрный к отрицательному, и желтый размещается в любой части платы.
Шаг шестой. Подключение драйвера моторов.
Драйвера просто выравниваются и ставятся на Arduino.
Шаг седьмой. Припой к двигателям.
Далее, происходит обычный припой проводов, важно только запомнить какие провода положительные, а какие отрицательные.
Шаг седьмой. Подключение колёс.
Теперь, автор подключает провода от двигателей к драйверу таким образом:
— К отрицательному контакту драйвера А подключается положительный контакт правого двигателя.
— К положительному контакту драйвера А подключается отрицательный контакт правого двигателя.
— К отрицательному контакту драйвера B подключается положительный контакт левого двигателя.
— К положительному контакту драйвера B подключается отрицательный контакт левого двигателя.
Шаг восьмой. Подключение датчика и питания.
Питание 5В подключили к + макетной платы, GND к GND. К аналоговому пину 2 подключается жёлтый провод датчика.
Шаг девятый. Установка батареи.
Батарею автор просто приклеил суперклеем к задней части робота. Затем просто соединил положительные и отрицательные провода к положительным и отрицательным выводам Carduino.
Библиотека
На этом сборка стандартного робота окончена. На нём будет работать библиотека и примеры программ, скачать её можно под статьёй. В архиве также есть описание некоторых функций. Загружается библиотека в Arduino IDE по пути -> import library -> Carduino. После загрузки программы проект полностью готов.
Видео с примером работы Carduino:
Получайте на почту подборку новых самоделок. Никакого спама, только полезные идеи!
*Заполняя форму вы соглашаетесь на обработку персональных данных
Становитесь автором сайта, публикуйте собственные статьи, описания самоделок с оплатой за текст. Подробнее здесь.usamodelkina.ru
Но наступил 2015 год, и фантастическая сага получила долгожданное продолжение, правда, уже в ином исполнении и с новой философией студии Уолта Диснея. Наши фанаты «Звездных войн» вновь увидели своих любимых роботов и решили, что пришло время и им создать нечто подобное. Это были Георгий Фомичев и Сергей Миронов – основатели робототехнического стартапа Endurance.
Итак, с чего все началось?
На фото руководитель Endurance Георгий Фомичев справа.
С разработки робота СелфиБот в 2015г, который в апреле 2016 г. стал open-source, и теперь любой человек может сделать своего робота по технологии Endurance.
Селфибот – это, в первую очередь, персональный робот, которого может собрать каждый, используя недорогую электронику, программу и прошивку Endurance. Главное, что собранного робота можно реально использовать, например, как удобную подставку под телефон для видеотрансляций или видеозаписи. Большим плюсом устройства является его способность поворачиваться вслед за вами. Эта функция, использующая Google API, называется follow me.
Вообще варианты использования робота по сути очень разнообразные, но вернемся к нашему Bb8…
Чтобы его собрать, нам потребуется 3D-принтер.
Мы использовали обычный WanHao Duplicator i3. Он вполне подходит для печати пластиком PLA.
Еще нужно иметь желание разобраться в схемотехнике, чтобы собрать плату. Можно, конечно, собрать все на макетной/контактной плате, но мы используем печатную плату. Так надежнее.
Итак, скачиваем готовую модель Bb8 для печати по ссылке: http://www.thingiverse.com/thing:789759
Ставим на печать (предварительно увеличив до нужных нам размеров).
Пластика потребуется около 500 грамм.
Заказываем всю электронику на Ebay или Aliexpress… Тут ее немного, можно купить и в обычном радиомагазине. Но там намного дороже. Если есть желание сделать быстрее, то можно купить готовый комплект электроники у Endurance за 95 долларов, чтобы не заморачиваться, покупая все по частям.
После чего аккуратно делаем печатную плату, описанную на сайте.
Сделав плату, прошиваем ее.
Прошивка для Arduino также выложена на сайте Endurance.
Что получилось? Корпус готов, электроника готова.
Чтобы управлять Bb8, нам потребуется Android телефон. Любой подойдет, лишь бы версия операционной системы была 4.1.x и выше…
С приложением, все довольно просто.
Его нужно скачать и установить на телефон.
После чего важно связать, т.е. спарить Bluetooth телефона и Bluetooth электроники, предназначенной для нашего Bb8.
Пока можно проверить только механическую часть и убедиться, что сервоприводы вращаются и все работает.
Теперь начинается не вполне тривиальная работа.
Она связана с тем, что изначально мы распечатали только корпус Bb8, не задумываясь о внутренних крепежах и креплениях. Это, конечно, минус, но не беда. Готовим внутренние крепежи.
Для этого используем основу из обычного пластика или из акрила.
Теперь нужно закрепить сервоприводы, причем так, чтобы обеспечить вращение в 2-х осях и чтобы один сервопривод удерживал другой. Для этого сделаем чертеж соединительного механизма.
Данная конструкция хоть и не супер технологична, но она работает.
Дальше наша задача собрать это все воедино.
Подключаем питание 12 вольт. Включаем приложение на телефоне и вуаля — демо режим, чтобы проверить, все ли работает.
Робот начинает поворачивать головой.
Ну что ж, будем считать, что в рамках проекта DIY SelfieBot мы все для первого раза сделали.
Для следующего раза можно:
1. Попробовать обработать корпус и сделать его более красивым
2. Придумать какую-нибудь защиту или фартук в месте соединения головы робота и корпуса.
3. Попробовать сделать робота менее шумным.
Все это и не только мы опишем в следующей статье.
Напоминаем, что все, кто хочет присоединиться к программе DIY SelfieBot, милости просим.
endurancerobots.com/en/robots/diy-selfiebot
Все открыто. Open – source. Комплектующие недорогие.
Чтобы каждый из вас смог собрать своего робота. Может быть, кто-то сделает робота на базе R2D2 или C3PO.
Рады сообщить, что уже 6 университетов присоединилось к программе DIY SelfieBot.
Подробнее
endurancerobots.com/en/robots/diy-selfybot
+7 916 3603210
И на канале Фомичева Георгия www.youtube.com/channel/UCzziBor2UytyKZ2RCPjXvCA
www.ixbt.com