суббота, 24 сентября 2016 г.

EV3 Music Station

В нашем новом проекте мы вновь коснемся музыкальной темы. Ранее мы уже строили несколько музыкальных "роботов": NXT-гитару, EV3-гитару, EV3-скрипку, NXT робота для тренировки чувства ритма, Arduino-барабанную установку и EV3-секвенсор. Каждый из них выполнял одну, специфическую функцию, ради которой собственно и создавался.


В проекте EV3 Music Station мы создадим робота-универсала, который сможет стать полноценным участником на ваших музыкальных репетициях. Хотя наш робот и построен на базе LEGO Mindstorms EV3, но использует в своем составе компоненты других наборов - пару моторов от NXT, пару датчиков-кнопок от него же, кроме этого применяются детали LEGO Technic. Традиционно мы подготовили для вас инструкцию по сборке в формате LEGO Digital Designer, которую можно скачать по ссылке.


Если у вас нет каких-то деталей - не беда, проявите фантазию и замените их имеющимися - так строить гораздо интереснее.
Программировать робота мы будем на EV3 Basic, к которому уже успели привыкнуть. В этом проекте мы освоим в нем новые функции - работу с файлами и текстовыми строками.

Ритм


Как гласит музыкальная теория, музыка состоит из мелодии, гармонии и ритма, которые в свою очередь состоят из звуков и звукосочетаний различной высоты и длительности и образуют внешнюю форму музыкального произведения.
Начнем, пожалуй, с ритма. Наш робот должен уметь колотить по барабанам, в качестве которых мы будем использовать жестяные банки, так как от них много шума :) Количество моторов, которое можно подключить к одному блоку EV3 ограничено 4-мя, а робот должен не только барабанить, но и выполнять другие прикольные вещи, поэтому для ритма мы будем использовать только два мотора и две барабанные палочки, в качестве которых возьмем пару простых карандашей. Жестяные банки-барабаны возьмем специально разные, большая банка будет рабочим барабаном, мелкая банка - чем-то вроде тарелки.




Первый режим, в котором сможет работать наш робот - режим ритм-лупера. Настучав по паре кнопок нужный нам ритм, мы предлагаем роботу его повторить, зациклив таким образом, чтобы он представлял собой законченный ритмический рисунок. Человек - существо аналоговое, настучать, да еще и по кнопкам ровно сможет далеко не каждый, поэтому мы будем программно выравнивать удары по барабанам, привязываясь к ближайшим долям такта.


Посмотрите, для примера, как настучал бы человек ритм для двух барабанов (синим цветом - моменты нажатия первой кнопки, красным - второй). Так как нотная запись - точная наука, мы будем привязывать эти нажатия к ближайшим долям такта, выравнивая ритм. Для того, чтобы зациклить ритмический рисунок, последний удар барабана должен повторять первый, это важно. Его мы отбросим, а вот длительность паузы перед ним нам нужна.

Давайте посмотрим на программу ритм-лупера:

' инициализируем датчики-кнопки
Sensor.SetMode(1,0)
Sensor.SetMode(2,0)
' плавно опускаем барабанные палочки в течении 5 секунд
Motor.Start("BC",-3)
Program.Delay(5000)
' останавливаем моторы и сбрасываем энкодеры
Motor.Stop("BС","False")
Motor.ResetCount("BC")
' поднимаем палочки в исходное положение
drum_start = 45
Motor.Move("BC",50,drum_start,"True")

' drum1 и drum2 - логические управляющие сигналы - поднять/опустить палочку
drum1 = "False"
drum2 = "False"
' reg1 и reg2 - верхние положения палочек
reg1 = drum_start 
reg2 = drum_start
' пропорциональный коэф-т регуляторов
k = 0.8

' процедура Drums будет выполняться в параллельном процессе, содержит в себе регуляторы, управляющие положением палочек
Sub Drums
  While "True"
    ' если поступил сигнал поднять/опустить 1-ю палочку - изменяем reg1
    If drum1 = "True" Then
      reg1 = 0
    Else  
      reg1 = drum_start                  
    EndIf
    ' если поступил сигнал поднять/опустить 2-ю палочку - изменяем reg2
    If drum2 = "True" Then
      reg2 = 0
    Else  
      reg2 = drum_start
    EndIf
    
    ' рассчитываем ошибку 1-го регулятора
    e1 = reg1 - Motor.GetCount("B")
    ' рассчитываем управляющее воздействие 1-го регулятора
    v1 = e1 * k
    ' Если палочка поднялась, останавливаем ее
    If Math.Abs(Motor.GetCount("B")) > 40 And drum1 = "False" Then
      Motor.Stop("B","False")
    Else  
    ' иначе подаем управляющее воздействие на мотор
      Motor.Start("B",v1)
    EndIf
    
    ' все тоже самое со вторым регулятором и вторым мотором
    e2 = reg2 - Motor.GetCount("C")
    v2 = e2 * k
    If Math.Abs(Motor.GetCount("C")) > 40 And drum2 = "False" Then
      Motor.Stop("C","False")
    Else     
      Motor.Start("C",v2)  
    EndIf
    
    ' Если палочка опустилась ниже порога, устанавливаем drum1 в "False", тем самым подавая сигнал поднять палочку
    If Motor.GetCount("B") < 20 Then
      drum1 = "False"
    EndIf

    ' тоже самое со вторым мотором, поговое значение отличается, так как банки у нас разные и стучать нужно с разной силой
    If Motor.GetCount("C") < 10 Then
      drum2 = "False"
    EndIf
  EndWhile
EndSub

' запускаем вышеописанную процедуру как параллельный процесс
Thread.Run = Drums  

' создаём переменные
n1 = 0
n2 = 0
' время начала такта
tn = 0
' время конца такта
tc = 0
' время начала "прослушивания" кнопок
d = EV3.Time
n = 0
trigger1 = "False"
trigger2 = "False"

' "прослушиваем" кнопки в течении 8 секунд
While EV3.Time < d + 8000
' если кнопка нажата и не была нажата
  If Sensor.ReadPercent(1) = 100 And trigger1 = "False" Then
  ' если это первое нажатие
    If n = 0 Then
      n = EV3.Time
    EndIf  
    ' запоминаем что кнопка уже нажата
    trigger1 = "True"
    ' в массив n1 заносим время нажатия
    b1[n1] = EV3.Time - n   
    ' переходим к следующему элементу массива
    n1 = n1 + 1
  Else
    ' если кнопка отжата - сбрасываем триггер
    If Sensor.ReadPercent(1) = 0 Then   
      trigger1 = "False"
    EndIf
  EndIf  
  ' повторяем для второй кнопки и массива n2
  If Sensor.ReadPercent(2) = 100 And trigger2 = "False" Then
    If n = 0 Then
      n = EV3.Time
    EndIf    
    trigger2 = "True"
    b2[n2] = EV3.Time - n
    n2 = n2 + 1
  Else
    If Sensor.ReadPercent(2) = 0  Then
      trigger2 = "False"
    EndIf
  EndIf    
EndWhile

' определяем начало и конец такта
If b1[0] < b2[0] Then
  tn = b1[0]  
Else  
  tn = b2[0]
EndIf  
If b1[n1-1] > b2[n2-1] Then
  tc = b1[n1-1]  
Else  
  tc = b2[n2-1]
EndIf  
' определяем длительность такта
dt = tc - tn  

' создаем пустые массивы с 16-ми долями такта для каждого барабана
For r = 0 To 16
  d1[r] = 0
  d2[r] = 0
EndFor  

' привязываем время нажатия кнопок к ближайшим долям такта
For e = 0 To n1 - 1
  d1[Math.Round(b1[e]/dt*16)] = 1
EndFor
For e2 = 0 To n2 - 1
  d2[Math.Round(b2[e2]/dt*16)] = 1
EndFor

' выводим на экран содержимое массивов d1 и d2 для контроля

LCD.Clear()

x = 0
y = 0
For u = 0 To 16
  LCD.Text(1,x,y,1,d1[u])
  x = x + 10
EndFor  
x2 = 0
y2 = 10
For u2 = 0 To 16
  LCD.Text(1,x2,y2,1,d2[u2])
  x2 = x2 + 10
EndFor
' любуемся результатом на экране в течении 10 секунд
Program.Delay(10000)  

' начинаем проигрывать ритм в цикле
While "True"
  For i = 0 To 15
    ' если в ячейке массива d1 единица - отсылаем процессу Drums сигнал drum1 = "True"
    If d1[i] = 1  Then 
      drum1 = "True"
    EndIf
    ' если в ячейке массива d2 единица - отсылаем процессу Drums сигнал drum2 = "True"
    If d2[i] = 1  Then 
      drum2 = "True"    
    EndIf
  ' ждем 1/16 такта
  Program.Delay(dt/16)
  EndFor
EndWhile



Мелодия


Контроллер EV3 обладает довольно развитыми звуковыми возможностями, на нем вполне можно слушать музыку, синтезировать речь. Например в проекте "EV3 Internet Radio Receiver" мы слушали с его помощью онлайн-радио. Однако базовая LEGO-прошивка таких крутых возможностей нам не дает и в данном проекте мы ограничимся использованием одноголосного спикера, который может воспроизводить ноты в пределах нескольких октав.


Записывать последовательность вызовов Speaker.Note в программу мы конечно же не будем, а попробуем использовать ранее не испытанные возможности EV3 Basic по работе с файлами и текстовыми строками.
Для начала определимся с форматом файла. Мы придумали вот такой вот простейший формат хранения (см. ниже).

90
4 4
1
0000000000001000
0000000000000000
Ps  4  Ps  4  Ps  4  A5  4 
Ps  1 
2
1010101010101010
1000100010101000
E5  4  A5  4  E5  4  A5  4 
Ps  1 

Первая строка в файле - bpm - удары в минуту - показатель, определяющий скорость исполнения или воспроизведения композиции. BPM — это количество четвертных нот в минуту, например, 120 BPM означает, что в минуту играется 120 четвертных нот (следовательно, 2 четверти в секунду), или 120 четвертных ударов метронома в минуту.
Вторая строка - размер (4/4, 3/4 и т.п.).
Далее идут такты, первая строка такта содержит его номер.
Вторая строка - удары первого барабана (тарелки) в 16-х долях такта.
Третья строка - удары второго барабана (рабочего) в 16-х долях такта
Четвертая строка содержит 7-символьные текстовые последовательности воспроизводимых нот мелодии - первые три символа - нота с указанием октавы, разделитель, длительность ноты в долях такта. Ps - пауза.
Пятая строка зарезервирована под аккорды гармонии.
Файл завершается номером такта 999.

Чтобы открыть файл для чтения будем использовать следующую конструкцию:

MyFile = EV3File.OpenRead("/home/root/lms2012/prjs/EV3MusicStation/file.txt")

Считать текстовую строку из него можно так

size = EV3File.ReadLine(MyFile)

Полный листинг программы, которая кроме ритма воспроизводит синхронно с ним мелодию мы приводить не будем, так как он достаточно объемный. Программу вы можете скачать по ссылке.

Гармония


Мы добавили нашему роботу интересную функцию - отображение текущего аккорда гармонии. По ходу воспроизведения композиции робот показывает  тонику текущего аккорда и его надстройку (минор, мажор, септаккорд, пауэр-аккорд), тем самым давая подсказку другим музыкантам, какой аккорд использовать в аккомпанементе или что им обыгрывать.


Пятая, зарезервированная строка в каждом такте может содержать аккорды гармонии

3
1010101010101010
1000100010001000
C5  8  C5  8  C5  8  B4  4  C5  4  Ps 8
C   1

Формат такой же, 7-символьный, тоника аккорда указывается в первом символе, причем "С" - чистое "До", а "с" - До-диез. Следующий два символа - возможная надстройка аккорда, например минор - "m", септаккорды - "7", "m7", пауэр-аккорд - "5". В конце длительность, в течении которой он действует. Ps - все также пауза.

Пример строки гармонии: "Ps  8  Am  4  Dm  4  C   8  Ps  4  "

В скачанном архиве вы найдете кроме инструкции по сборке и программы еще и несколько файлов с примерами композиций, которые сможет "настучать и напеть" наш робот. Разобравшись с форматом файла вы сможете поручить ему играть любую другую, даже вашу собственную песню. Ну а теперь давайте посмотрим, как работает наш робот:



В заключение хотелось бы отметить, что EV3 Basic, в отличии от официального ПО LEGO отлично работает с массивами строк. Это очень важная особенность, существенно расширяющая применимость данного инструментария.

В ходе работы над проектом мы обнаружили интересную особенность - штатная прошивка LEGO с легкостью выполняет функции, которых нет в официальном ПО от LEGO, например функции работы со строками

Text.GetSubText() - вырезать кусок подстроки
Text.GetLength() - вычислить дkину строки

Кроме этого прекрасно работает перевод строки в число с помощью функции EV3File.ConvertToNumber(). Такая возможность была в LEGO NXT-G, а вот в ПО LEGO EV3 ее очень недоставало. Из новых функций, которые мы использовали в проекте также стоит отметить Math.Remainder() - остаток от деления и Math.Round() - округление до ближайшего целого. Примеры применения всех этих функций вы можете посмотреть в исходном коле программы.

Чтение и обработка текста из файл оказалась довольно неторопливой, что не позволяла использовать их в реальном времени (между тактами образовывались неприятные паузы), поэтому мы сначала считываем композицию из текстового файла в массивы с ритмом, мелодией и гармонией, а затем воспроизводим композицию используя эти структуры данных.

суббота, 20 августа 2016 г.

EV3 Gunstick

Если вы помните, в одной из наших ранних серий мы строили NXT-джойстик и управляли с его помощью компьютером. С тех пор нас неоднократно просили сделать что-то подобное на платформе EV3. Времена теперь уже не те и проводной контроллер - это не интересно, поэтому мы замахнулись сразу на Bluetooth-джойстик.



Наверное все знают, что слово Joystick образовано из двух слов Joy - радость, Stick - палка, связано это с тем, что первые джойстики для игровых автоматов выглядели именно nак -  рукоятка, которую нужно было бодро дергать и при этом громко вопить от радости.



В нашем сегодняшнем проекте джойстик будет необычным, он будет представлять собой ружье (Gun), подобное построенному нами в проекте EV3 Doom, однако это будет именно джойстик, с которым мы будем бегать в мрачных лабиринтах настоящего, олдскульного Doom2. Отсюда и название проекта - EV3 Gunstick.


Конструкция "пушки" довольно проста и незатейлива, инструкцию по сборке в формате LEGO Difital Designer вы можете скачать по ссылке. Мы используем три датчика касания (кнопки) для перемещения вперед, выстрела и "стрейфа" (удерживая эту кнопку можно двигаться боком, уклоняясь от выстрелов и выглядывать из-за углов). Для разворота влево-вправо мы сначала попробовали использовать гироскоп, в принципе играть с помощью его можно, если бы не два "но" - во первых в пылу битвы сложно контролировать точно горизонтальное расположение нашего Gunstick, поэтому гироскоп начинает врать, другая проблема - наличие у него "дрейфа" - набегания ошибки со временем. Так же мы попробовали использовать ИК-дальномер в режиме поиска маяка - с ним играть лучше, "дрейфа" нет, центровка относительно центра экрана не слетает, но есть другая проблема - может быть это проблема именно нашего датчика, но время от времени он зависает на полсекунды (перестает обновлять показания), впрочем затем продолжая нормально работать. Смена канала, порта датчиков, проводов не помогла. Попробуйте, возможно Вам повезет больше - нам кажется ИК+маяк - был бы наилучшим вариантом для этого проекта. В итоге мы стали использовать датчик компаса Hitechnic, с ним все заработало стабильно. Еще как запасной вариант, для тех у кого есть IR Seeker и ИК-мяч - их тоже можно использовать в данном проекте вместо ИК-датчика и EV3-маяка.

Датчики подключены так:
1 - кнопка выстрела
2 - кнопка "вперед"
3 - кнопка "стрейф"
4 - компас (ИК-дальномер, гироскоп и т.п.)

Программу на стороне блока мы написали в стандартной среде EV3. В последнее время нам больше по душе EV3 Basic, но. к сожалению. в нем невозможно отправлять числовые значения по Bluetooth, только текст, что для нашего проекта не совсем удобно.

Программа устроена довольно просто. Установив соединение с компьютером по Bluetooth, мы в бесконечном цикле собираем показания с датчиков и формируем из них пакет данных следующим образом:

По умолчанию передаваемый пакет (целое число) равно 1000000.
Если нажата кнопка на блоке "Вверх" (в игре используется для открывания дверей), прибавляем к нему 100000.
Если нажата кнопка "Выстрел", прибавляем 10000.
Если нажата кнопка "идти вперед" - прибавляем 1000.
Если нажата кнопка "стрейф" (движение боком) +100.


Далее нам нужна информация об ориентации игрока в пространстве, ее мы собираем с датчика компас (гироскоп, ИК-дальномер+ маяк и т.д.). Ограничив максимальное отклонение +/-50 градусов и прибавив к нему 50 получаем число в интервале 0..99, которое прибавляем также к пакету данных.


В итоге в результирующем, передаваемом не компьютер единственном числе, например 1011025, передается информация о том, что игрок в данный момент движется вперед с легким разворотом влево и стреляет.


Программу, принимающую пакеты данных на компьютере мы написали на языке Processing, его свободно можно скачать по ссылке.
Для эмуляции нажатия кнопок на клавиатуре и перемещений указателя мыши в программе используется класс Robot модуля java.awt
После подключения вашего EV3 по Bluetooth к компьютеру на ПК появится пара вируальных COM-портов. Для настройки на нужный порт введите в строке с Serial.list()[0] порядковый номер входящего EV3 COM-порта на вашем компьютере.

void setup() 
{
  keySim = new KeystrokeSimulator(); 

  try { 
    robot = new Robot();
    robot.setAutoDelay(0);
  } 
  catch (Exception e) {
    e.printStackTrace();
  }

  String portName = Serial.list()[0];
  myPort = new Serial(this, portNam, 115200); 
}

Давайте посмотрим как работает наш "робот". Углы поворотов конечно не идеальны, впрочем это и не было целью проекта, мы хотели проработать принцип формирования пакетов данных и передачи их на ПК и это получилось в полном объеме.


Скачать инструкцию по сборке и исходные коды программ.

суббота, 23 июля 2016 г.

EV3 Параллельная парковка

В этом сезоне в одной из категорий Всероссийской Робототехнической Олимпиады "Роботраффик" нам запомнилась интересная задачка, "параллельная парковка". Мы подумали что было бы интересно решить ее с использованием платформы LEGO Mindstorms EV3.



Техническое задание звучало так: создать автономное роботизированное транспортное средство, способное самостоятельно провести процедуру парковки в случае наличия свободного места в зоне парковки. 



Двигаясь вдоль парковочной зоны ТС должно определить место, достаточное для парковки, и занять это место.


Для решения задачи мы решили воспользоваться распространенным робо-реквизитом: кругом для сумо (кегельринга) в качестве трассы, кеглями и банками - в качестве макетов ТС, стоящих на обочине.
Автономное роботизированное транспортное средство, которое мы собрали для решения данной задачи основано на шасси от бонусной модели RAC3 TRUCK из домашней версии EV3. Мы доработали рулевое управление модели для достижения больших углов разворота и установили датчики - пару датчиков освещенности для движения по линии и ИК-датчик расстояния для определения макетов транспортных средств на обочине.


Вероятно вы тоже захотите поэкспериментировать с движением по линии и парковкой с использованием рулевого управления, поэтому наш проект традиционно содержит свободно распространяемую инструкцию по сборке модели и программу, которые вы можете скачать по ссылке.

Моторы и датчики подключены так:
  • Мотор А - рулевое управление, моторы B и С - ходовые
  • Порты 1 и 2 - датчики линии, порт 4 - ИК-дальномер
Программу для робота мы написали в среде EV3 Basic. Выглядит она следующим образом:

' инициализируем датчики
Sensor.SetMode(1,0)
Sensor.SetMode(2,0)
Sensor.SetMode(4,0)

' переменные - коэф-ты для регулятора
k = 2
Pk = 7
Dk = 10  
Popr = 12
Ug = 0
M = "A"
e_o = 0

' триггер для подсчета банок
trigger = "False"

' запускаем ходовые моторы
Motor.Start("B",-75)
Motor.Start("C",-75)

While "True"
  While "True"
    ' разница в показаниях датчиков с учетом поправки  
    r = Sensor.ReadPercent(1)-(Sensor.ReadPercent(2)+Popr)
    ' требуемый угол разворота колес
    Ug = r * k
    ' ошибка регулятора - разница требуемого угла и текущего
    e = Ug - Motor.GetCount("A")
    ' подаем управляющее воздействие на рулевой мотор  
    Motor.Start(M,e*Pk+Dk*(e-e_o))
    ' сохраняем ошибку для работы дифференциальной компоненты регулятора
    e_o = e
    
    ' определяем расстояние ИК-датчиком
    tmp = Sensor.ReadPercent(4)
    
    If tmp < 22 Then
      ' если банка "первая"
      If trigger = "False" Then
        ' сбрасываем энкодеры и запоминаем в триггере
        Motor.ResetCount("BC")
        trigger = "True"
      Else
        ' иначе проверяем - умещается ли ТС в промежутке
        if (Motor.GetCount("B") + Motor.GetCount("C")) / 2 < -979 Then
          ' если да - паркуемся
          Goto parkovka
          trigger = "False"
        Else
          ' если нет - считаем эту банку "первой"
          Motor.ResetCount("BC")
          trigger = "True"
        EndIf
      EndIf
    EndIf
       
  EndWhile    
  
  ' маневр парковки
  parkovka:
  
  Speaker.Note(100,"C4",500)
  
  Motor.ResetCount("BC")
  
  ' проезжаем вперед по линии "500 градусов"
  While (Motor.GetCount("B") + Motor.GetCount("C"))/2 > -500
    r = Sensor.ReadPercent(1)-(Sensor.ReadPercent(2)+Popr)
    Ug = r * k
    e = Ug - Motor.GetCount("A")  
    Motor.Start(M,e*Pk+Dk*(e-e_o))
    e_o = e
  EndWhile
  
  ' маневр заезда на парковочное место
  Motor.Schedule("A",30,0,90,0,"True")
  Motor.Schedule("BC",30,0,530,0,"True")
  Motor.Wait("ABC")
  Motor.Schedule("A",-30,0,115,0,"True")
  Motor.Schedule("BC",30,0,950,0,"True")
  Motor.Wait("ABC")
  
  Motor.Stop("BC","True")
  Program.Delay(1000)
  
  ' маневр выезда из парковочного места
  Motor.Schedule("A",50,0,15,0,"False")
  Motor.Schedule("BC",-30,0,730,0,"True")
  Motor.Wait("ABC")
  Motor.Schedule("A",30,0,65,0,"True")
  Motor.Schedule("BC",-30,0,250,0,"True")
  Motor.Wait("ABC")
  
  Motor.Start("B",-75)
  Motor.Start("C",-75)

EndWhile

воскресенье, 10 июля 2016 г.

Большой железный робот. Часть 4. Добавим еще железа

Давненько не было вестей от нашего большого железного робота. Не смотря на плотный график подготовки к соревнованиям (ВРО) работы по проекту все же двигались, хотя и не так быстро, как нам хотелось бы. Вот так вот наш робот выглядит в данный момент:


Первым делом мы установили П-образный каркас, из того же алюминиевого профиля 25x25x2, из которого ранее собирали раму. Крепление каркаса выполнено Г-образными мебельными уголками и болтами М6. В высоту каркас от уровня пола в верхней точке - 65 см.



На каркас смонтировали сервоподвес с двумя степенями свободы, это будущая "шея" робота, этот механизм будет двигать головой. Голову планируем собирать в следующий раз, хотим смонтировать на ней камеру, микрофон, динамик-твиттер и антенны wi-fi.




Сервоприводы использовали с металлическими редукторами, MG995.


Электронные компоненты решили разделить на группы, разместив их в разных отсеках. Наш робот - учебный, поэтому важно чтобы все в нем было наглядным. Исходя из этого мы выделили следующие 4 группы компонентов:

1) "Силовой отсек" содержит драйверы двигателей, усилитель мощности звука. Об этих штуковинах мы писали в предыдущих частях статьи.





Так как эти компоненты достаточно прилично греются при работе, в отсеке предусмотрели активное охлаждение, программно завязанное на цифровой датчик температуры DS18B20. Вентилятор, управляемый через мосфет IRF530N, включается, когда температура в отсеке превышает 40 градусов и его обороты пропорциональны превышению температуры над этим порогом. 


2) "Отсек питания" содержит разводку силового питания, кнопку включения робота, предохранитель.



3) "Мозговой центр" содержит Raspberry Pi 2 и Arduino Mega 2560, соединенные по USB. В Raspberry Pi 2 вставлен Wi-Fi адаптер. Кроме этого здесь мы разместили датчики напряжения и силы тока. 




Дял получения стабильных 5В используем преобразователь DC-DC на 5А
Датчик напряжения позволит контролировать заряд батареи, чтобы не допустить слишком сильного ее разряда. 
Датчик силы тока ACS712 ACS712ELC-30A позволит контролировать потребление энергии роботом, на основании этих данных можно прогнозировать время, которое он еще сможет проработать, программно снижать токи потребления (замедлять моторы в режим экономии при низком заряде аккумулятора).


4) "Отсек управления сервоприводами". Здесь будут сосредоточены компоненты для управления сервоприводами "шеи" и, возможно, "рук" робота (манипуляторов). Кроме этого здесь планируется разместить электронный компас. Питание сервоприводам будет обеспечивать отдельный DC-DC преобразователь.




Монтажные отсеки соединены гофрированными трубками для проводов (сливной шланг для стиральной машины).


Каркас собран с использованием металлопластиковых труб, болтов и шпилек М6.




В процессе работы над дизайном корпуса попробовали использовать технологию "стеклоткань+эпоксидная смола" по болванке, склеенной из пенопласта и монтажной пены, но отказались от нее, корпус выходил слишком "монолитным". Вероятно для конечного устройства это будет неплохим вариантом, но нам пока хочется иметь быстрый доступ к любым компонентам робота. чтобы с удобством в них покопаться.



понедельник, 27 июня 2016 г.

Немного о футболе роботов WRO gen.III. Часть 4

В третьей части статьи наш робот-нападающий, проанализировав доступные ему данные смог выбрать верное направление на ворота соперников и нанести по ним удар. Чем большим объемом данных он располагает и чем данные более свежие, тем удар будет точнее.



Пусть вас не удивляет этот странный робот, он тоже футболист! У нас нет еще двух наборов для создания команды-оппонента для тренировок, поэтому наши оппоненты на тренировках управляются с пульта (телефона). Этот забавный робот имеет в своем составе пару LEGO Technic моторов, LEGO Technic ИК-приемник и батарейный блок. Управлять им с ИК-пульта LEGO Technic не получится - излучение мяча полностью забивает ИК-спектр, поэтому приемник мы спрятали внутри картонной коробочки, дополнительно содержащую Arduino Nano, Bluetooth-модуль к ней и ИК-светодиод. Питается этот рукотворный RF-IR конвертер от того же LEGO Technic блока. Приняв сигнал по Bluetooth, конвертер преобразует его в формат IR Power Function и отсылает ИК-приемнику, расположенному тут же, в этой же самой коробочке. Плюсы решения - сделать его можно за полчаса перед тренировкой.

Вратарь


А теперь давайте поговорим о втором роботе в команде, о вратаре. Его роль в игре - неоценима, ведь он не только защищает ворота команды, но и оценивает ситуацию на поле и помогает нападающему в ориентации на ворота соперников.
Давайте опять представим себя на месте робота и встанем на защиту воображаемых ворот. Мяч на поле и все взоры устремляются на него. Робот-вратарь, как и нападающий, "видит" мяч датчиком IR Seeker, и, в принципе, может спокойно стоять на месте до момента приближения мяча. Есди Вы смотрели игры в WRO-футбол, то явно не согласитесь с тем, что стоять на месте - очень хорошая идея. Обычно роботы-вратари очень подвижны, они отслеживают направление на мяч и разворашиваются к нему. Зачем это нужно? Причин тому несколько:
1) робот вратарь "скорее широкий чем длинный", поэтому развернувшись на мяч он закрывает своей вертикальной проекцией большую часть ворот, чем в соучае, если бы он смотрел на мяч искоса.
2) при приближении мяча робот сумеет быстрее отреагировать, выехав к нему навстречу
3) робот выглядит более вовлеченным в игру :)


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

При приближении мяча вратарь обязан выехать в попытке отбить его от ворот - так гласят правила. Причем робот должен выехать именно на мяч (маневры 1,2), а не например сместиться в штрафной зоне в попытке перекрыть ему путь к воротам (маневр 3 - запрещен!).


Определить точное расстояние до мяча робот не может, хотя бы потому, что сила излучения мяча - величина не постоянная, так как мяч работает в режиме пульсирующего излучения. В связи с этим расстояние, начиная с которого вратарю нужно выезжать на мяч будет им выбрано достаточно приблизительно.

Важным моментом является факт того, что робот не должен выезжать с позиции защиты в сторону собственных ворот - иначе он рискует забить гол сам себе. Чтобы ограничить сектор защиты вратаря необходимо использовать показания датчика компаса, опираться следует на заранее откалиброванные азимуты, ограничивающие сектор защиты.

Итак, мяч подкатился достаточно близко к воротам, сила его излучения превысила некое пороговое значение, заданное в программе вратаря и он прерывает защиту и переходит к активной обороне. Движение на мяч в целом не отличается от того, которое использует нападающий с той лишь разницей, что оно должно быть прервано, "если робот не успел".

...

Далее статья прерывается, к сожалению времени ее дописать совершенно не было, а потом мы оказались на Российском этапе Всемирной Олимпиады Роботов в г.Иннополис.


В этом году мы готовили две команды, на "Футбол роботов" и на "Лабиринт: туда и обратно". Обе команды прошли региональный отбор, показав на нем лучшие результаты, но в Иннополис отправилась только одна наша команда. Организаторы ВРО в последний момент приняли решение переиграть состав объявленных ими еще зимой состязаний, и наша младшая команда, как, впрочем, и сотня ребят из других регионов, "пахавших" последние полгода без выходных, остались со своими лабиринтами дома. Это ничего, ведь главное подготовка и полученные ими знания, ведь правда? А организационные просчеты наверняка будут учтены на будущее.

В этом сезоне команды, прибывшие на футбол роботов в Иннополис, наконец-то научились играть по новым правилам, не просто ездить на мяч, как это было в прошлом году, а выполнять маневры по его объезду и подталкиванию к воротам соперников. В связи с этим игры получились очень интересными и фактор случайности уже не так влиял на перевес сил на полях. Нас порадовало, что то тут, то там в разговорах участников слышна была наша терминология, "орбита", "точка схода". Был даже робот, почти полный клон нашей прошлогодней конструкции. Представляете каких трудов стоило этой команде собрать его, ориентируясь только на видео и на пару фото.


"Аналоговость" футбольных правил, в отличии от основной и свободной категории, заставляла находиться в постоянном напряжении. От судьи и от того, "чьи" команды на поле зависело насколько строго к ним будет применено то или иное "нежесткое" правило, которое тем не менее могло внести существенный вклад в  игру. К примеру 5 секунд ожидания, рекомендованные на брифинге могли превратиться в строгие 3 или в полушутливые 7. Наклейки с символикой области нам внезапно предложили отодрать от роботов, разрешив приклеить, если получится, оставшиеся от них лоскуты после сборки. Наклейки якобы позволяют промаркировать моторы, зато детали в составе роботов-соперников, раскрашенные маркером оказались вполне годными и даже не модифицированными.

Самое печальное - обстановка, "тренер тренеру волк". Семейных/дворовых команд не так много, в основном все выступают от образовательных учреждений, в которых зачастую полученная тренером грамота "кормит его еще целый год". В интернет сообществах единицы всем известных тренеров свободно делятся своими наработками, остальные их придерживают, чтобы применить вновь и вновь. На страницах всем известного блога, которым зачитывались робототехники всей страны, новых статей не выходило уже больше года, материалы и наработки по соревновательной робототехнике доступны за деньги, тренерам, приехавшим на курсы повышения квалификации. Покупка знаний тренеров из других регионов уже не выглядит чем-то странным, главное продвинуть своих ребят.
Похоже третья наша попытка найти единомышленников по свободному обмену опытом, наработками и идеями (сначала канал Youtube, затем сообщество ВК и блог) снова не нашла отклика.







Самое популярное