SlideShare uma empresa Scribd logo
1 de 111
Not eXactly C
Программируем LEGO-роботов

Александр Колотов

    alexandr.kolotov@gmail.com
    http://nnxt.blogspot.com

                    Тюмень, 2013
Давайте знакомиться!


                    Колотов
              Александр Васильевич

•   Нижний Новгород
•   4 года с LEGO-роботами
•   Тренер российской сборной World Robot Olympiad
•   http://nnxt.blogspot.com – самый полезный ресурс на
    русском языке по LEGO роботам
LEGO Mindstorms




   Если вы можете придумать
робота, вы можете его построить!
Поколения LEGO Mindstorms

• Первые наборы Lego Mindstorms
  начали выпускаться в 1998 году. Они
  были созданы на базе RCX блока.
• Следующая версия - Lego Mindstorms
  NXT - выпускается в 2006 году.
  Основа – NXT блок.
• Начиная с середины 2009, продается
  новая версия Lego Mindstorm NXT
  2.0. Новшества: цветовой датчик и
  математика с дробными числами
• 2013 год – начинается продажа LEGO
  Mindstorms EV3: более мощное
  «железо», новые датчики.
Программирование

• NXT даёт возможность
  программировать
  роботов, используя USB
  или Bluetooth
Программа на PC

           Команды на моторы


            Данные с сенсоров и
                енкодеров

MS Robotics Developer Studio  NI LabView
LEGO::NXT                     Robolab
NXT-Python                    Scratch
RWTH - Mindstorms NXT Toolbox for MATLAB
Программа на NXT

             Скомпилированный
             исполняемый файл




NXT-G                  NI LabView
leJOS NXJ              Robolab
Enchanting             RobotC
Not Exactly C (NXC)    NXT Byte Code (NBC)
Программа на телефоне

                        Программа-посредник

                 RPC


          Результаты вызова RPC

MINDroid – OpenSource проект от LEGO
Chatterbox – как инициировать общение со
стороны NXT блока
Конструкторы: MIT App Inventor, CATROID
Язык программирования
                Not eXactly C
• Not eXactly C (NXC) – язык
  программирования, специально придуманный для
  программирования LEGO-роботов.
• В основе языка NXC (ЭнИксСи) лежит популярный язык
  программирования С (Си), на котором создаются
  профессиональные программы.
• Язык NXC значительно проще своего предка, что
  позволяет изучить его очень быстро – можно написать
  первые программы для робота уже на первый день
  знакомства.
Язык программирования
                Not eXactly C
• Программирование на NXC доступно в:
    • Windows
       • Среды: Bricx Comand Center, RobotC Virtual World
    • Linux
       • Среды: nxcEditor, любой текстовый редактор
    • Mac OS X

• Официальный сайт: http://bricxcc.sourceforge.net/

• Компилятора языка NXC, как и среду BricxCC
  можно использовать бесплатно.
Среды программирования

Bricx Command Center



                       nxcEditor + nxcSimulator
Bricx Command Center

• Основа среды BricxCC (БрикИксСиСи) – текстовый
  редактор с подсветкой синтаксиса (конструкций языка)




• Среда поддерживает программирование RCX и NXT
  блоков. Идет разработка поддержки EV3 блоков.
Bricx Command Center

• Установка среды BricxCC
     • Скачать и установить офиц. версию:
       http://sourceforge.net/projects/bricxcc/files/bricxcc/
     • Разработчики все время добавляют новые функции
       в программу. Чтобы получить доступ к самым
       последним функциям, можно скачать тестовую
       стабильную сборку:
       http://bricxcc.sourceforge.net/test_releases/
     • Компьютер должен увидеть NXT блок, как
       устройство, поэтому нужно установить Fantom
       Driver от LEGO:
       http://mindstorms.lego.com/en-us/support/files/Driver.aspx
Bricx Command Center
                                    Если блок не
                                   подключен шаг
• Запуск среды программирования   можно пропустить
Bricx Command Center

• Подключение NXT блока




                        Выбрать порт
                      подключения USB
                        или BlueTooth
Bricx Command Center

• Среда поддерживает
  большое количество
  инструментов для
  работы с NXT блоком
Bricx Command Center

        • Инструменты для
          получения данных о
          состоянии NXT блока
Bricx Command Center

• Инструменты для
  работы с файлами на
  NXT блоке позволяют
  копировать файлы на
  блок, читатать файлы с
  блока, удалять их
Bricx Command Center

        • Специальный
          инструмент NeXT Screen
          позволет отображать в
          отдельном окне, то что
          выводится на экран
          блока.
Bricx Command Center

• В любой момент
  времени по каждой
  конструкции или
  функции языка
  можно получить
  справку, нажав <F1>
Самая простая программа



   /*  основная часть
       программы       */
   task main() {
       //Вывести на экран NXT блока строку
       TextOut(0, LCD_LINE1, "Start");
   }
Самая простая программа

       Многострочный комментарий
Открывающая часть - /*, закрывающая часть - */

                  /*  основная часть
                      программы       */
                  task main() {
                      //Вывести на экран NXT блока строку
                      TextOut(0, LCD_LINE1, "Start");
                  }
Самая простая программа

    Каждая
  программа
    должна
содержать, как   /*  основная часть
минимум, одну        программы       */
    задачу.      task main() {
   Основная          //Вывести на экран NXT блока строку
   задача в          TextOut(0, LCD_LINE1, "Start");
  программе      }
     всегда
  называется
    «main».
Самая простая программа

    Внутри задач содержится блок команд. Каждый
       блок команд в программе отделяется от
         другого блока фигурными скобками.
   /*  основная часть
       программы       */
   task main() {
       //Вывести на экран NXT блока строку
       TextOut(0, LCD_LINE1, "Start");
   }
Самая простая программа

   Можно использовать
однострочные комментарии.
     Начинаются с //.
                 /*  основная часть
                     программы       */
                 task main() {
                     //Вывести на экран NXT блока строку
                     TextOut(0, LCD_LINE1, "Start");
                 }
 Однострочные комментарии удобно
 использовать, чтобы временно
 «скрыть» часть программы: //TextOut(LCD_LINE1, "Start");
Самая простая программа



                 /*  основная часть
                     программы       */
                 task main() {
                     //Вывести на экран NXT блока строку
                     TextOut(0, LCD_LINE1, "Start");
                 }
  Функции в программе чувствительный к регистру: “TextOut” не
      тоже самое, что “textout”. Внутри скобок – параметры
настраивающие поведение функции. Каждая функция в программе
            отделяется от остальных точкой с запятой.
Компиляция

• Все программы для NXT блока представляют собой
  специальный набор инструкций - байткод, который
  исполняется интерпретатором, являющимся частью NXT
  firmware (набор программ стартующих при включении
  блока).
• Компилятор языка NXC преобразует исходный код
  программ в байткод понятный для NXT.
• После компиляции исполняемый файл должен быть
  скопирован на NXT блок.
Компиляция

 Просто скомпилировать    Cкомпилировать
программу. Используется     и загрузить      Запустить
для проверки на наличие    программу на    программу на
   ошибок синтаксиса.        NXT блок.       NXT блоке
          <F5>                 <F6>            <F7>
Компиляция

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

• Наиболее часто используемой функцией робота
  является «Движение».
• Двигаться может весь робот:
     • движение тележки
• Двигаться могут части робота:
     • движение манипулятора (рука, клешня)
     • движение сенсора
Программирование моторов

• Программирование моторов может происходить
  посредством одной из следующих функций:
   RotateMotor(outputs, pwr, angle) – поворот мотора с заданной мощностью
        на заданный угол
   RotateMotorEx(outputs, pwr, angle, turnpct, sync, stop) – аналогично
        RotateMotor, но позволяет контролировать распределение мощности
        между моторами, синхронизацию и тип остановки после окончания
        движения
   OnFwd(outputs, pwr) – включить моторы для движения вперед с заданной
        можностью и передать управление следующей команде
   OnRev(outputs, pwr) – то же, но с движением назад
   OnFwdSync(outputs, pwr, turnpct) – аналогично OnFwd, но позволяет
        контролировать распределение мощности
   OnRevSync(outputs, pwr, turnpct) – то же, но с движением назад
   Off(outputs) – торможение моторами
   Coast(outputs) – отключение энергии от моторов
Программирование моторов
  • Управляем количеством движения:
        RotateMotor(outputs, pwr, angle)
                                                                    Тормозить
Какие моторы вращать:                         Угол в градусах.      моторами
 OUT_A, OUT_B, OUT_C      Мощность:      Отрицательные значения –   или просто
   OUT_BC, OUT_AC          -100..100    поворот в противоположную   отключить
       OUT_AC                                     сторону            энергию

        RotateMotorEx(outputs, pwr, angle, turnpct, sync, stop)
Распределение мощности между двумя моторами             Вкл/выкл
        при использовании «спаренных»                сихнронизацию
 двигателей, например, A и B или B и С (-100..100)   между моторами

  • Пример:
          RotateMotor(OUT_A, 100, 275);
          RotateMotorEx(OUT_BC, -75, 720, -100, true, true);
Программирование моторов

• Строя последовательность из функций управления
  моторами с нужными параметрами можно добиться
  сложной траектории движения робота:
    task main() {
        //Движение вперед
        RotateMotor(OUT_BC, 100, 720);
        //Поворот вокург своей оси
        RotateMotorEx(OUT_BC, -75, 360, 100, true, true);
        //Движение назад
        RotateMotor(OUT_BC, -80, 1800);
        //Поворот одним двигателем
        RotateMotor(OUT_C, 75, -180);
    }
Программирование моторов

• Задание 1. Движение одним мотором.
    • Запрограммировать только один мотор у тележки через функцию
     RotateMotor
    • Пронаблюдать, как тележка двигается в зависимости от того какой мотор
      мы контролируем.
    • Пронаблюдать, как тележка двигается в зависимости от того какое
      направление движения мотора (вперед или назад) мы выбираем:
        • Изменять направления движения через указание отрицательной
          мощности и через отрицательное значение угла поворота.

                          Мотор и направление
                      Левый мотор, движение вперед
                      Правый мотор, движение вперед
           Левый мотор, движение назад (отрицательная мощность)
             Правый мотор, движение назад (отицательный угол)
Программирование моторов

• Задание 2а. Движение двумя моторами.
    • Составить программу для робота-тележки таким образом, чтобы робот
      проехал вперед, а потом назад, вернувшись на то же место
    • Изменяя мощность подаваемая на моторы, посмотрите как это влияет на
      скорость движения робота
    • За счет чего будет задаваться движение назад? За счет управления
      мощностью или за счет управления направлением угла поворота?
                              Мощность
                                 25%
                                 50%
                                100%

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

• Задание 2b. Движение двумя моторами.
    • Запрограммируйте робота таким образом, чтобы он проехал 30 см. (лист
      альбомной бумаги) – на сколько оборотов или градусов необходимо
      повернуть колеса тележки.
Программирование моторов

• Задание 2c. Движение двумя моторами.
    • Изучить, что произойдет, если запрограммировать робота ехать три
      оборота колес (1080 градусов), и в то же время руками остановить
      двигатели - искусственно создать ситуацию, когда робот натолкнулся на
      препятствие и колеса провернуться не могут.



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

• Задание 2d. Движение двумя моторами.
    • Изучить, как распределение мощности между двумя моторами влияет
      на движение тележки.

                                         turnpct
                                           0
                                           -25
                                           -50
  RotateMotorEx(OUT_BC, -75, 720,                  , true, true);
                                          -100
                                           25
                                           50
                                          100
Программирование моторов

• Задание 2e. Движение двумя моторами.
    • Подберите значение распределения мощности между двумя моторами
      для того, чтобы робот начал двигаться по каждой из указанных
      траекторий.
Программирование моторов

• Задание 3. Остановка.
    • Составить программу таким образом, чтобы тележка проехала вперед на
      максимальной скорости (максимальная мощность) в течение 4 оборотов
      двигателя. После окончания движения использовать торможение
      двигателем.

      RotateMotorEx(OUT_BC, 100, 1420, 0, true, true );

    • Изменить программу, чтобы использовать отключение питания от
      мотора в качестве торможения.

      RotateMotorEx(OUT_BC, 100, 1420, 0, true, false );
Программирование моторов

• Сложные траектории.
    • Одной из сложностей при программировании
      движения робота является определение нужного
      количества оборотов мотора для передвижения на
      заданное расстояние.
    • Например,
       • На сколько нужно повернуть моторы, чтобы робот повернул на 90
         градусов налево?
       • Как разворачиваться быстрее - повернуть на 90 градусов, включив
         только один мотор, или используя максимальное/минимальное
         значение распределения мощности между двумя моторами?
       • Подобрать экспериментальным путем, на сколько нужно повернуть
         моторы и какое нужно задать направление поворота, чтобы робот
         проехал полкруга с радиусом 30 сантиметров?
Программирование моторов

• Задание 4. Движение по квадрату.
    • Составьте программу для того, чтобы робот двигался по сторонам
      квадрата.
        • Как бы мы действовали, если бы мы двигались подобным образом?
Программирование моторов

• Задание 5. Движение по восьмерке.
    • Составьте программу для того, чтобы робот двигался по сторонам
      восьмерки.
    • Одной из трудностей в этой программе является возврат в то же место,
      откуда робот начал двигаться.
Программирование моторов
• Включаем моторы:
        OnFwd(outputs, pwr)
        OnRev(outputs, pwr)
                                       Распределение мощности между
 Какие моторы вращать:                двумя моторами при использовании
  OUT_A, OUT_B, OUT_C    Мощность:              «спаренных»
    OUT_BC, OUT_AC        -100..100   двигателей, например, A и B или B и
        OUT_AC                                   С (-100..100)
        OnFwdSync(outputs, pwr, turnpct)
        OnRevSync(outputs, pwr, turnpct)

• Пример:
     OnFwd(OUT_BC, 60);
     OnRev(OUT_A, 100);
     OnFwdSync(OUT_BC, -75, -100);
Программирование моторов

• Задание 6. Включение моторов.
    • Изучить, что произойдет, включить моторы и закончить программу.

              task main() {
                  OnFwd(OUT_BC, 100);
              }


      Цель эксперимента - показать, что функции включения
      моторов никак не определяют сколько будет включен
      мотор, сколько колеса тележки проедут.
      Также он показывает, что при заверешении программы
      моторы явно не останавливаются – вместо этого с них
      снимается энергия и моторы продолжают двигаться по
      инерции.
Ожидание

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

• В языке NXC задержку между двумя командами можно
  добавить с помощью функции:
    Wait(milliseconds)               Сколько
                                   миллисекунд
                                      ждать
• Специальные константы для упрощения задания задержек:
    SEC_1, SEC_2, ..., SEC_10, SEC_
                                                 MIN_1 - секунды
    15, SEC_20, SEC_30 - секунды

• Пример:
     Wait(1);         //Ждать   1 миллисекунду
     Wait(500);       //Ждать   полсекунды
     Wait(10000);     //Ждать   10 секунд
     Wait(SEC_10);    //Ждать   10 секунд
     Wait(SEC_2*5);   //Ждать   10 секунд
Программирование моторов
• Останавливаем моторы:
       Off(outputs)
       Coast(outputs)

     Какие моторы останавливать:
        OUT_A, OUT_B, OUT_C
       OUT_BC, OUT_AC, OUT_AC
              OUT_ABC


• Пример:
    Off(OUT_A);    //Затормозить мотор А
    Coast(OUT_BC); //Отключить энергию с моторов B и C
    Off(OUT_BC);   //Затормозить моторы B и C
Программирование моторов

• Задание 7. Еще одно движение по квадрату.
    • Составьте программу для того, чтобы робот двигался по сторонам
      квадрата. Но используйте функции включения/выключения моторов и
      временные задержки для того, чтобы определять сколько робот проедет
      и на сколько повернет.
        • Нужно ли останавливать двигатели перед поворотом?
        • Что произойдет, если во всей программе теперь изменить мощность
          на моторах в два раза?
Программирование моторов

• Задание 8. Блокировка колес.
    • Изучить, что произойдет, если запрограммировать робота ехать 5
      секунд, и в то же время руками остановить двигатели - искусственно
      создать ситуацию, когда робот натолкнулся на препятствие и колеса
      провернуться не могут.



       Цель эксперимента - показать, что не смотря на то, что
       колеса заблокированы и не могут двигаться, программа
       продолжит выполняться после истечения 5 секунд.
Работа с экраном



• Среда программирования
  предоставляет возможность
  выводить текстовую и
  графическую информацию на
  графический экран NXT блока
Работа с экраном

• Экран имеет разрешение 100x64 точки – или можно
  сказать, что он имеет 100 столбцов по 64 строчки
  каждый.                                          x = 99
                                                     y = 63




  координата Y
      строчки
                 x = 11
                  y=4


      x=0
      y=0
                          координата X
                            столбцы
Работа с экраном

• Помимо графической информации, на экран можно
  вывести 8 строк текста по 16 символов
• Поддерживаются только латинские символы, цифры

  строка 1
  строка 2                            Размер одного
  строка 3                             знакоместа
                                        6 x 8 точек
  строка 4
  строка 5
  строка 6
  строка 7
  строка 8
Работа с экраном

• Вывод текста и цифр на экран:
    TextOut(x, y, str) – вывести строку, начиная с заданных координат
    NumOut(x, y, value) – вывести число
• Для упрощения позиционирования вывода на экран в
  нужных строках можно использовать спец. константы:
    LCD_LINE1 – первая сверху строка, строка в самом верху экрана
    LCD_LINE2 – вторая сверху строка
    . . .
    LCD_LINE8 – последняя строка, строка в самом низу экрана

• Весь экран можно очистить:
    ClearScreen()

                TextOut(56, 0, "Hello");
• Пример:       NumOut(10, LCD_LINE2, 314159);
                TextOut(6*8, LCD_LINE3, "Robot");
Работа с экраном

• Задание 9. Вывод текста во время работы программы.
    • Изменить программу движения по восьмерке таким образом, чтобы
      робот печатал соответствующие направление движения или
      направление поворота на экране:
        • “Forward” – прямо
        • “Left” – налево
        • “Right” – направо
    • Каждая новая надпись должна выводиться в новой строчке.
Воспроизведение звуков


• NXT блок имеет встроенный
  динамик, через который
  можно выводить звук
  определенной частоты или
  звуковые файлы в
  специальном формате.
Воспроизведение звуков

• Воспроизведение звука:
    PlayTone(frequency, duration) – воспроизвести звук заданной
         частоты (frequency, в герцах) и заданной продолжительности
         (duration, в миллисекундах)
    PlayToneEx(frequency, duration, volume, loop) – аналогично
         PlayTone, но позволяет задать громкость (volume, 0..4) и
         повторяемость действия.
• Если нужно вывести конкретную ноту можно
  использовать спец. константы:
    TONE_C4   – нота ДО четвертой октавы, TONE_D4 – нота РЕ четвертой октавы
    TONE_E4   – нота МИ четвертой октавы, TONE_F4 – нота ФА четвертой октавы
    TONE_G4   – нота СОЛЬ четвертой октавы, TONE_A4 – нота ЛЯ четвертой октавы
    TONE_B4   – нота СИ четвертой октавы
                PlayTone(440, 250);
• Пример:       PlayTone(TONE_F4, 125);
                PlayToneEx(TONE_A4, 500, 4, false);
Воспроизведение звуков

• Задание 10. Звуки во время работы программы.
    • Изменить программу движения по восьмерке таким образом, чтобы
      робот воспроизводил звуки после завершения соответствующего
      движения прямо или поворота.
    • На повороте в лево звук должен быть отличным от звука на повороте в
      право.
Для чего нужны датчики?

• Основной функцией робота является движение или
  перемещение его частей
  (манипуляторы, захваты, ноги, сенсоры)
Для чего нужны датчики?

• Роботу необходимо изменять свое поведение
  (движение) в зависимости от внешних событий.
Для чего нужны датчики?

• Внешние события приходят роботу через сенсоры и
  датчики, от внутренних часов робота, от оператора, а
  также от других роботов.
Что такое состояние?

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

• Например, когда робот находился в состоянии
  движения, к нему приходит сигнал от датчика касания,
  что впереди перпятствие, и робот из состояния
  движения переходит в состояние бездействия.



                   Сигнал от датчика
      Движение                         Остановка
Ожидание событий

• Следовательно, робот будет продолжать находиться в
  предыдущем состоянии до тех пор, пока не получит
  сигнал на переход в следующее состояни.

• Робот должен ожидать возникновения сигнала – этот
  процесс можно назвать «Ожидание события»
Ожидание событий

• В языке NXC есть специальная конструкция для
  ожидания какого-то события:
    until(УСЛОВИЕ) – программа не идет к выполнению следующих команд,
         пока не наступит заданное условие.
• Конструкцию можно описать фразой: «выполнять
  предыдущее действие до тех пор, пока не случиться ...»
• УСЛОВИЕ - чаще всего сравнение текущих показаний
  датчиков с каким-то эталонным значением (точка
  срабатывания, предельное значение и т.п.). Сравнение
  происходит посредством конструкций:
    ЗНАЧЕНИЕ1 == ЗНАЧЕНИЕ2 – равныпрограмма не идет к выполнению
         следующих команд, пока не наступит заданное условие.
Ожидание событий

• УСЛОВИЕ - чаще всего, сравнение текущих показаний
  датчиков с каким-то эталонным значением (точка
  срабатывания, предельное значение и т.п.). Сравнение
  происходит посредством конструкций:
    ЗНАЧЕНИЕ1 == ЗНАЧЕНИЕ2 – условие справедливо, если значения равны
    ЗНАЧЕНИЕ1 != ЗНАЧЕНИЕ2 – условие справедливо, если значения не равны
    ЗНАЧЕНИЕ1 < ЗНАЧЕНИЕ2 – условие справедливо, если первое значение
         меньше второго
    ЗНАЧЕНИЕ1 > ЗНАЧЕНИЕ2 – условие справедливо, если первое значение
         больше второго
    ЗНАЧЕНИЕ1 <= ЗНАЧЕНИЕ2 – условие справедливо, если первое значение
         меньше или равно второму (не больше второго)
    ЗНАЧЕНИЕ1 >= ЗНАЧЕНИЕ2 – условие справедливо, если первое значение
         больше или равно второму (не меньше второго)
Датчик касания

• Датчик касания позволяет роботу
  воспринимать прикосновения и
  реагировать на внешние
  раздражители
• С помощью датчика касания робот
  может подбирать предметы
• Манипулятор, оснащенный датчиком касания, позволит
  роботу узнать, имеется ли объект, который можно взять
• Датчик касания по сути своей кнопка, у которой
  возможно два состояния - Нажато и Отжато.
Датчик касания

• Перед работой с любым датчиком в языке NXC его
  нужно инициализировать, то есть сказать программе к
  какому порту, какой именно датчик присоединен.
• Инициализация датчика касания:
    SetSensorTouch(port) – с этого времени работать с заданным
         портом, как с датчиком касания
• Тогда получить текущее значение в программе можно
  посредством опроса функции:
    Sensor(port) – если датчик нажат, функция вернет 1, если отжат, то
         возвращаемое значение будет 0.
• port – номер порта, к которому подключен
  датчик, задается константами:
    S1, S2, S3, S4 или IN_1, IN_2, IN_3, IN_4
Датчик касания

• Пример:
task main() {
    SetSensorTouch(S1);

    //Ничего не делать до тех пор, пока датчик не будет отпущен
    until(Sensor(S1) == 0);
    //Начать движение вперед
    OnFwd(OUT_BC, 100);
    //Двигаться до тех пор, пока датчик не будет нажат
    until(Sensor(S1) == 1);
    //Остановиться
    Off(OUT_BC);
}
Датчик касания

• Задание 11. Робот обнаруживает препятствие.
    • На роботе датчик касания «смотрит» вперед
    • Робот начинает двигаться
    • Как только обнаружится касание с препятствием, робот должен
      остановиться.




    • Остановился робот сразу после касания или сколько-то еще пытался
      продолжать двигаться?
    • За счет какого действия в программе нужно остановить робота, сразу
      после обнаружения нажатия?
Датчик касания

• Задание 12. Запуск робота c кнопки.
     • Изначально робот стоит и должен начать двигаться только после
       того, как происходит нажатие на датчик касания.
     • Робот останавливается после столкновения с препятствием.



                                   • Почему робот не поехал, а
                                     программа сразу завершилась?
Датчик касания

            Программа исполняется на NXT блоке быстрее, чем человек
            взаимодействует с роботом.
                                                  Человек нажал на
                                                       кнопку
                   task main() {
                       SetSensorTouch(S1);                 Моторы только начали
                                                         запускаться, и управление
                        until(Sensor(S1) == 1);           передалось следующей
                                                                 команде
                        OnFwd(OUT_BC, 100);
 Очень-очень быстро!                                        Человек еще не
Тысячные доли секунды                                       успел отдернуть
                        until(Sensor(S1) == 1);
                                                            руку от датчика
                        Off(OUT_BC);             Моторы
                   }                          остановились и
                                                программа
                                               завершилась
Датчик касания

• Вариант решения:
  task main() {                    Человек нажал на
      SetSensorTouch(S1);               кнопку

      until(Sensor(S1) == 1);                     За это время, кнопка
                                                       отжимается
      Wait(500);
      OnFwd(OUT_BC, 100);
                                                        Моторы
                                                      запускаются
      until(Sensor(S1) == 1);
                                          К этому времени датчик
      Off(OUT_BC);                       «освобожден» и ожидает
  }                                           сигнала касания
Минусы подхода:
   • Задержку надо подбирать индивидуально для человека
   • Запуск мотора происходит с видимой задержкой после нажатия
Датчик расстояния

                    • Датчик расстояния (ультразвуковой
                      датчик) позволяет роботу измерять
                      расстояние до объекта и
                      реагировать на движение



• Сенсор измеряет расстояние
  путем расчета времени, которое
  потребовалось звуковой волне
  для возвращения после
  отражения от объекта
Датчик расстояния

• Инициализация датчика расстояния:
    SetSensorLowspeed(port) – с этого времени работать с заданным
         портом, как с датчиком расстояния. В названии функции фигурирует
         «медленный датчик», потому что этот датчик цифровой и работает по
         I2C шине, которая не позволяет опрашивать датчик слишком часто.
• Текущее значение датчика:
    SensorUS(port) – расстояние в сантиметрах (6..255)
Датчик расстояния

• Пример:
task main() {
    SetSensorLowspeed(S4);

    //Начать вращение вокруг своей оси
    OnFwdSync(OUT_BC, 50, -100);
    //До тех пор, пока не возникнет препятствие ближе, чем 50 см.
    until(SensorUS(S4) < 50);
    //Остановить моторы
    Off(OUT_BC);

    //Начать движение и двигаться 3,5 секунды
    OnFwd(OUT_BC, 100); Wait(3500); Off(OUT_BC);
}
Датчик касания

• Задание 13. Робот обнаруживает препятствие.
    • Датчик расстояния на роботе «смотрит» вперед
    • Робот двигается до тех пор, пока не появится препятствие ближе, чем 20
      см.




                                                 20 см.
Датчик касания

• Задание 14. Робот-воин.
    • Роботу понадобятся два датчика: расстояния и касания
    • «Воин» крутится быстро на одном месте вокруг себя
    • Как только в его поле зрения появляется предмет ближе чем 50
      см., робот начинает двигаться к этому предмету и останавливается когда
      стукнется об него
Датчик касания

• Задание 15. Парковка.
    • Датчик расстояния смотрит в сторону
    • Робот должен найти пространство для парковки между двумя
      «автомобилями» и выполнить заезд в обнаруженное пространство




                      15 см.   ?? см.   15 см.
Датчик освещенности

         • Датчик освещенности (световой
           датчик) позволяет роботу
           различать яркость объектов,
           освещенность помещения и даже
           различать цвета.




• Что видит глаз человека
• Что видит робот через датчик освещенности
Датчик освещенности

• Инициализация датчика освещенности:
    SetSensorLight(port, active) – с этого времени работать с
         заданным портом, как с датчиком освещенности. Включать светодиод
         или нет, определяется в параметре active
• Включить/отключить светодиод можно также позднее с
  помощью функций:
    SetSensorType(port, SENSOR_TYPE_LIGHT_ACTIVE) – включить
    SetSensorType(port, SENSOR_TYPE_LIGHT_INACTIVE) – выключить
• Но тогда после функций выше надо вызвать
    ResetSensor(port) – firmware применит новую конфигурацию датчика
• Текущее значение датчика:
    Sensor(port) – освещенность в процентах: чем меньше, тем темнее.
         Если светодиод не включен, то покажет окружающую освещенность.
         Если включен, то будет происходить замер отраженного света.
Датчик освещенности

• Пример:
task main() {
    SetSensorLight(S3, true);

    //Начать движение
    OnFwd(OUT_BC, 80);
    //Ехать вперед до тех пор, пока не наедем на темный участок
    until(Sensor(S3) < 40);
    //Продолжать движение (эта команда не обязательна)
    OnFwd(OUT_BC, 80);
    //До тех пор, пока не наедем на светлый участок
    until(Sensor(S3) > 50);
    //Остановить моторы
    Off(OUT_BC);
}
Датчик освещенности

• Задание 16а. Отобразить показания датчика.
    • На экране NXT блока должно отображаться текущее значение
      окружающей освещенности (светодиод выключен).
    • Как избежать запуска программы каждый раз, когда мы пытаемся
      измерить новую освещенность?
Повтор одинаковых событий

• Иногда в программе возникает необходимость
  повторить несколько одинаковых операций друг за
  другом несколько раз:

                             1


                    2




                                 4


                        3
Повтор одинаковых событий

• Для повтора одинаковых действий в программах
  используются циклы. Например,
      while(УСЛОВИЕ) { тело цикла } – повторять команды, входящие в
           тело цикла, пока УСЛОВИЕ (условие существования цикла)
           справедливо
                                           Те действия, которые необходимо
                                           повторять несколько
while(Sensor(S1 == 0)) {                   раз, помещаются внутрь цикла. Они
    RotateMotor(OUT_BC, 100, 1800);        составляют тело цикла.
    RotateMotor(OUT_B, 50, 720);
}

            Как только действие последней команде в теле цикла
            заканчивается, программа проверяет еще раз УСЛОВИЕ и переходит к
            первой команде в теле цикла, если оно справедливо.
Повтор одинаковых событий

• Довольно часто нужно повторять часть программы
  бесконечно, пока целиком вся программа не будет
  прервана.
• Бесконечный цикл – в нем условие существование
  цикла всегда справедливо.

       while(true) {
           TextOut(0, LCD_LINE1, "Light Sensor:");
           NumOut(20, LCD_LINE2, Sensor(S3));
           Wait(500);
           ClearScreen();
       }
Датчик освещенности

• Задание 16b. Отобразить показания датчика.
    • На экране NXT блока должно отображаться текущее значение
      отраженного света (светодиод включен).
Датчик освещенности

• Задание 17а. Черно-белое движение.
      • Пусть робот доедет до темной области на поле и остановится.
                                     • Что будем измерять: окружающую
22%                                    освещенность или отраженный свет?
                                     • Как определить, что робот заехал на
   54%                                 темную область?
        Количество света, возвращенное в датчик на темной
        области зависит от окружающей освещенности, от высоты
        датчика, от цвета освещающего светодиода. Поэтому
        никогда не берите пограничное измеренное значение в
        условии генерации события. Обычно выбирают середину
        между показаниями на темной и светлой области.

                 22%                 38%                 54%
Датчик освещенности

• Задание 17b. Черно-белое движение.
    • Пусть робот доедет, до темной области, а затем съедет обратно на
      светлую




    • Как только получилось, добавьте цикл в программу - пусть робот
      перемещается вперед-назад попеременно, то на темную, то на светлую
      область.
Датчик освещенности

• Задание 17c. Движение вдоль линии.
    • Пусть робот перемещается попеременно, то на темную, то на светлую
      область, но теперь движение должно выполняться поочередно то
      одним, то другим колесом.




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



                             3 оборота
Поведение по-умолчанию,                  5 оборотов               Количество оборотов
Количество оборотов мотора                                        мотора после сброса
                                                      2 оборота
после старта
Датчик угла поворота оси
                    мотора
• Инициализация датчика угла поворота оси мотора
  (енкодера) не требуется.
• Получить текущее значение датчика:
    MotorRotationCount(output) – на какое количество градусов
         повернулся соответствующий мотор. Имеет смысл указывать только
         один мотор. Мотор задается одной из констант:
         OUT_A, OUT_B, OUT_C
• Сбросить датчик угла поворота:
    ResetAllTachoCounts(output)
Датчик угла поворота оси
                   мотора
• Пример:
task main () {
    RotateMotor(OUT_BC, 80, 720);
    //Вывести значения енкодеров
    NumOut(0, LCD_LINE1, MotorRotationCount(OUT_C));
    NumOut(0, LCD_LINE2, MotorRotationCount(OUT_B));
    //Сбросить значения енкодеров только на моторе С
    ResetAllTachoCounts(OUT_C);

    RotateMotor(OUT_BC, 80, 720);
    //Вывести новые значени енкодеров. Один будет
    //примерно в два раза больше другого.
    NumOut(0, LCD_LINE4, MotorRotationCount(OUT_C));
    NumOut(0, LCD_LINE5, MotorRotationCount(OUT_B));
}
Датчик угла поворота оси
                   мотора
• Задание 18. Непослушный робот.
    • Робот стоит на неизвестном расстоянии от черной линии.
    • После старта программы робот должен доехать до черной линии и
      остановиться.
    • Затем робот должен проехать назад ровно такое же расстояние
      так, чтобы оказаться на том же месте, откуда начал движение.




                                 ?
Состязание!

• Задание 19. Кегельринг.
     • Роботу понадобятся датчик расстояния и датчик освещенности
     • Задача робота обнаружить внутри ринга 8 кеглей (предметы
       обнаруживаемые датчиком расстояния) и вытолкнуть их за черную
       линию, ограничивающую ринг
     • Сам робот не должен выезжать за границу ринга больше, чем на 5
       секунд.
Принятие решений

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

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


                                      Включить
                                       моторы
       Узнать                          захвата
       какого
       цвета
        мяч
                                       Включить
                                      моторы для
                                       разворота
Принятие решений

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


                Стало              Поднять
                 тихо              занавес




                                    Подать
                Стало
                                   звуковой
                громко
                                    сигнал


               причины             действия
Принятие решений

• В языке NXC для анализа причины и выборе
  соотвестствующего действия используется конструкция:
    if (УСЛОВИЕ) { действия А и Б } else { действия В и Г } –
         если УСЛОВИЕ справедливо, то выполнять действия А и
         Б, иначе, если УСЛОВИЕ не верно, то выполнять действия В и Г.
• Можно использовать сокращенную запись, если не
  нужно выполнять никаких действий при
  несправедливости условия:
    if (УСЛОВИЕ) { действия А и Б }
Принятие решений

• В месте принятия решения происходит разветвление
  программы.
• В зависимости от решения, программа может пойти
  либо по одной, либо по другой ветке
  RotateMotor(OUT_BC, 60, 720);            • После выполнения
  if (Sensor(S1)<40) {
                                             действий внутри
      //Если на сенсоре маленькие значения   той или иной
      RotateMotor(OUT_A, 40, 90);            ветки, программа
  } else {
      //Если на сенсоре большие значения     вновь
      TextOut(0, LCD_LINE1, "Error");        возвращается в
      PlayTone(TONE_C4, MS_250);
  }                                          «основное русло».
  RotateMotor(OUT_BC, 60, -720);
Принятие решений

• Можно вкладывать конструкции друг в друга, для
  принятия сложных решений:
 if (Sensor(S1) < 40) {
     if (SensorUS(S4) > 25) {
         RotateMotor(OUT_B, 90, 360);
     } else {
         RotateMotor(OUT_C, 90, 360);
     }
     TextOut(0, LCD_LINE1, "Too bright");
 } else {
     TextOut(0, LCD_LINE1, "Error");
     PlayTone(TONE_C4, MS_250);
 }
Принятие решений

• Задание 20. Нажми кнопку!
    • После включения блок должен проверить нажат ли датчик касания.
    • В зависимости от того нажат или нет, вывести на экран “Yes” или “No”
    • После вывода на экран – остановить программу

                                                  YES



                                                   NO
Принятие решений

• Задание 21. Управляемая машинка
    • Датчик касания закреплен на длинном проводе
    • Если датчик нажат – робот-тележка стоит, если отжат – едет




    • Измените, программу так, чтобы при нажатом датчике робот вращался
      вокруг своей оси, а при отжатом – двигался вперед.
Принятие решений

• Задание 22. Азбука Морзе
    • Пусть тележка крутиться вокруг своей оси
    • Когда датчик находится на темной поверхности – издается звук, как
      только поверхность светлее – звук смолкает



                  L         E        G               O
Принятие решений

• Задание 22. Неудачный пешеходный переход
    • Робот-тележка должен пересекать черные полоски – дорожки, при
      пересечении издавать звук.
    • Как только перед роботом возникнет препятствие – он должен
      остановиться




    • Как сделать так, чтобы робот перестал выполнять цикл после
      обнаружения стены?
Выход из цикла по условию

• Типичная ситуация, когда цикл должен завершиться при
  по какому-то событию, из-за какой то причины.
• В начале цикла можно задать условие, которое будет
  определять, когда тело цикла все еще должно
  выполняться:
    while (УСЛОВИЕ) { тело цикла }.
• УСЛОВИЕ будет проверяться каждый раз, когда
  происходить переход от последней команды в теле
  цикла к первой. Если УСЛОВИЕ не справедливо, то цикл
  завершиться.
• После выхода из цикла будут выполняться
  команды, идущие сразу после закрывающей скобки.
Выход из цикла по условию

• Пример:
  while(SensorUS(S3) > 15) {

     if (Sensor(S3) > 40) {
         OnFwd(OUT_B); Coast(OUT_C);
     } else {
         OnFwd(OUT_C); Coast(OUT_B);
     }
  }
  //Переход к этой функции случиться, когда расстояние
  //станет меньше 15 см.
  Off(OUT_BC);
Принятие решений

• Задание 23а. Беспокойный любопытный робот
    • Робот должен находиться все время на одном расстоянии от руки (или
      другого предмета) – 25 см.
    • Если рука удаляется от робота, то робот придвигается к ней
    • Если рука приближается к роботу, то робот отъезжает назад.
Принятие решений

• Задание 23b. Опытный любопытный робот
    • В предыдущем задании, робот никогда не был в состоянии покая – он, то
      ехал вперед, то двигался назад
    • Нужно изменить программу так, чтобы робот был неподвижен при
      нахождении на определенном расстоянии
    • Задание нужно выполнить с использование вложенных условий

                           if (SensorUS(S4) < 24) {
                               OnFwd(OUT_BC, 60);
                           } else {
      24 см.
                               if (SensorUS(S4) < 26) {
      26 см.
                                   Off(OUT_BC);
                               } else {
                                   OnFwd(OUT_BC, -60);
                               }
                           }
Программирование LEGO
       роботов



   Ваши вопросы?

Mais conteúdo relacionado

Mais procurados

Владимир Алаев "Разработка на Node.js: инструменты, библиотеки, сервисы"
Владимир Алаев "Разработка на Node.js: инструменты, библиотеки, сервисы"Владимир Алаев "Разработка на Node.js: инструменты, библиотеки, сервисы"
Владимир Алаев "Разработка на Node.js: инструменты, библиотеки, сервисы"Yandex
 
CUDA Course 2010 at MSU
CUDA Course 2010 at MSUCUDA Course 2010 at MSU
CUDA Course 2010 at MSUlarhat
 
Применение фреймворка GStreamer в системе видеонаблюдения
Применение фреймворка GStreamer в системе видеонаблюденияПрименение фреймворка GStreamer в системе видеонаблюдения
Применение фреймворка GStreamer в системе видеонаблюденияcorehard_by
 
Hunting for a C++ package manager
Hunting for a C++ package managerHunting for a C++ package manager
Hunting for a C++ package managercorehard_by
 
Ферапонтов_Резюме
Ферапонтов_РезюмеФерапонтов_Резюме
Ферапонтов_РезюмеOleg Ferapontov
 
ekbpy'2012 - Михаил Коробов - Python 3
ekbpy'2012 - Михаил Коробов - Python 3ekbpy'2012 - Михаил Коробов - Python 3
ekbpy'2012 - Михаил Коробов - Python 3it-people
 
Семинар 12. Параллельное программирование на MPI (часть 5)
Семинар 12. Параллельное программирование на MPI (часть 5)Семинар 12. Параллельное программирование на MPI (часть 5)
Семинар 12. Параллельное программирование на MPI (часть 5)Mikhail Kurnosov
 
Modern neural net architectures - Year 2019 version
Modern neural net architectures - Year 2019 versionModern neural net architectures - Year 2019 version
Modern neural net architectures - Year 2019 versionGrigory Sapunov
 
Модульность и управляемая многопоточность встраиваемых С++ приложений - трудн...
Модульность и управляемая многопоточность встраиваемых С++ приложений - трудн...Модульность и управляемая многопоточность встраиваемых С++ приложений - трудн...
Модульность и управляемая многопоточность встраиваемых С++ приложений - трудн...corehard_by
 

Mais procurados (12)

Владимир Алаев "Разработка на Node.js: инструменты, библиотеки, сервисы"
Владимир Алаев "Разработка на Node.js: инструменты, библиотеки, сервисы"Владимир Алаев "Разработка на Node.js: инструменты, библиотеки, сервисы"
Владимир Алаев "Разработка на Node.js: инструменты, библиотеки, сервисы"
 
CUDA Course 2010 at MSU
CUDA Course 2010 at MSUCUDA Course 2010 at MSU
CUDA Course 2010 at MSU
 
Кратко о Linux
Кратко о LinuxКратко о Linux
Кратко о Linux
 
Multithreading in go
Multithreading in goMultithreading in go
Multithreading in go
 
Применение фреймворка GStreamer в системе видеонаблюдения
Применение фреймворка GStreamer в системе видеонаблюденияПрименение фреймворка GStreamer в системе видеонаблюдения
Применение фреймворка GStreamer в системе видеонаблюдения
 
Hunting for a C++ package manager
Hunting for a C++ package managerHunting for a C++ package manager
Hunting for a C++ package manager
 
Ферапонтов_Резюме
Ферапонтов_РезюмеФерапонтов_Резюме
Ферапонтов_Резюме
 
ekbpy'2012 - Михаил Коробов - Python 3
ekbpy'2012 - Михаил Коробов - Python 3ekbpy'2012 - Михаил Коробов - Python 3
ekbpy'2012 - Михаил Коробов - Python 3
 
Семинар 12. Параллельное программирование на MPI (часть 5)
Семинар 12. Параллельное программирование на MPI (часть 5)Семинар 12. Параллельное программирование на MPI (часть 5)
Семинар 12. Параллельное программирование на MPI (часть 5)
 
Mac os and ubuntu
 Mac os and ubuntu  Mac os and ubuntu
Mac os and ubuntu
 
Modern neural net architectures - Year 2019 version
Modern neural net architectures - Year 2019 versionModern neural net architectures - Year 2019 version
Modern neural net architectures - Year 2019 version
 
Модульность и управляемая многопоточность встраиваемых С++ приложений - трудн...
Модульность и управляемая многопоточность встраиваемых С++ приложений - трудн...Модульность и управляемая многопоточность встраиваемых С++ приложений - трудн...
Модульность и управляемая многопоточность встраиваемых С++ приложений - трудн...
 

Destaque

Кружок по робототехнике. Занятие #2. Lego Mindstorms NXT
Кружок по робототехнике. Занятие #2. Lego Mindstorms NXTКружок по робототехнике. Занятие #2. Lego Mindstorms NXT
Кружок по робототехнике. Занятие #2. Lego Mindstorms NXTAlexander Kolotov
 
Кружок по робототехнике. Занятие #8. Решение задач
Кружок по робототехнике. Занятие #8. Решение задачКружок по робототехнике. Занятие #8. Решение задач
Кружок по робототехнике. Занятие #8. Решение задачAlexander Kolotov
 
Кружок по робототехнике. Занятие #7. Решение задач
Кружок по робототехнике. Занятие #7. Решение задачКружок по робототехнике. Занятие #7. Решение задач
Кружок по робототехнике. Занятие #7. Решение задачAlexander Kolotov
 
Кружок по робототехнике. Занятие #6. Ветвления
Кружок по робототехнике. Занятие #6. Ветвления Кружок по робототехнике. Занятие #6. Ветвления
Кружок по робототехнике. Занятие #6. Ветвления Alexander Kolotov
 
Кружок по робототехнике. Занятие #5. Программируем датчики расстояния и цвета
Кружок по робототехнике. Занятие #5. Программируем датчики расстояния и цветаКружок по робототехнике. Занятие #5. Программируем датчики расстояния и цвета
Кружок по робототехнике. Занятие #5. Программируем датчики расстояния и цветаAlexander Kolotov
 
тропинка по лесу к голубому озеру
тропинка по лесу к голубому озерутропинка по лесу к голубому озеру
тропинка по лесу к голубому озеруAlexander Kolotov
 
Таблица соответствия робототехнических компетенций и возрастов
Таблица соответствия робототехнических компетенций и возрастовТаблица соответствия робототехнических компетенций и возрастов
Таблица соответствия робототехнических компетенций и возрастовAlexander Kolotov
 
шесть кадров
шесть кадровшесть кадров
шесть кадровpermskijkrai
 
Tutorial sencillo kompozer
Tutorial sencillo kompozerTutorial sencillo kompozer
Tutorial sencillo kompozerAngel Camargo
 
Анализ задания WRO 2015 "Поиск сокровищ"
Анализ задания WRO 2015 "Поиск сокровищ"Анализ задания WRO 2015 "Поиск сокровищ"
Анализ задания WRO 2015 "Поиск сокровищ"AlexVoron
 
Кружок по робототехнике. Занятие #2. Первый робот
Кружок по робототехнике. Занятие #2. Первый роботКружок по робототехнике. Занятие #2. Первый робот
Кружок по робототехнике. Занятие #2. Первый роботAlexander Kolotov
 
Кружок по робототехнике. Занятие #2. Программируем моторы
Кружок по робототехнике. Занятие #2. Программируем моторыКружок по робототехнике. Занятие #2. Программируем моторы
Кружок по робототехнике. Занятие #2. Программируем моторыAlexander Kolotov
 
Ev3 руководство пользователя
Ev3 руководство пользователяEv3 руководство пользователя
Ev3 руководство пользователяpermskijkrai
 
Дорожкина Н.Г. Модель батискафа из LEGO WeDo: инструкция по сборке
Дорожкина Н.Г. Модель батискафа из LEGO WeDo: инструкция по сборкеДорожкина Н.Г. Модель батискафа из LEGO WeDo: инструкция по сборке
Дорожкина Н.Г. Модель батискафа из LEGO WeDo: инструкция по сборкеfgos-igra
 
Manual oso de anteojos
Manual oso de anteojosManual oso de anteojos
Manual oso de anteojosJos Cruz
 

Destaque (19)

Кружок по робототехнике. Занятие #2. Lego Mindstorms NXT
Кружок по робототехнике. Занятие #2. Lego Mindstorms NXTКружок по робототехнике. Занятие #2. Lego Mindstorms NXT
Кружок по робототехнике. Занятие #2. Lego Mindstorms NXT
 
Кружок по робототехнике. Занятие #8. Решение задач
Кружок по робототехнике. Занятие #8. Решение задачКружок по робототехнике. Занятие #8. Решение задач
Кружок по робототехнике. Занятие #8. Решение задач
 
Кружок по робототехнике. Занятие #7. Решение задач
Кружок по робототехнике. Занятие #7. Решение задачКружок по робототехнике. Занятие #7. Решение задач
Кружок по робототехнике. Занятие #7. Решение задач
 
Кружок по робототехнике. Занятие #6. Ветвления
Кружок по робототехнике. Занятие #6. Ветвления Кружок по робототехнике. Занятие #6. Ветвления
Кружок по робототехнике. Занятие #6. Ветвления
 
Кружок по робототехнике. Занятие #5. Программируем датчики расстояния и цвета
Кружок по робототехнике. Занятие #5. Программируем датчики расстояния и цветаКружок по робототехнике. Занятие #5. Программируем датчики расстояния и цвета
Кружок по робототехнике. Занятие #5. Программируем датчики расстояния и цвета
 
тропинка по лесу к голубому озеру
тропинка по лесу к голубому озерутропинка по лесу к голубому озеру
тропинка по лесу к голубому озеру
 
Таблица соответствия робототехнических компетенций и возрастов
Таблица соответствия робототехнических компетенций и возрастовТаблица соответствия робототехнических компетенций и возрастов
Таблица соответствия робототехнических компетенций и возрастов
 
шесть кадров
шесть кадровшесть кадров
шесть кадров
 
Tutorial sencillo kompozer
Tutorial sencillo kompozerTutorial sencillo kompozer
Tutorial sencillo kompozer
 
Анализ задания WRO 2015 "Поиск сокровищ"
Анализ задания WRO 2015 "Поиск сокровищ"Анализ задания WRO 2015 "Поиск сокровищ"
Анализ задания WRO 2015 "Поиск сокровищ"
 
Кружок по робототехнике. Занятие #2. Первый робот
Кружок по робототехнике. Занятие #2. Первый роботКружок по робототехнике. Занятие #2. Первый робот
Кружок по робототехнике. Занятие #2. Первый робот
 
Кружок по робототехнике. Занятие #2. Программируем моторы
Кружок по робототехнике. Занятие #2. Программируем моторыКружок по робототехнике. Занятие #2. Программируем моторы
Кружок по робототехнике. Занятие #2. Программируем моторы
 
Ev3 руководство пользователя
Ev3 руководство пользователяEv3 руководство пользователя
Ev3 руководство пользователя
 
Cuentosilustrados
CuentosilustradosCuentosilustrados
Cuentosilustrados
 
Дорожкина Н.Г. Модель батискафа из LEGO WeDo: инструкция по сборке
Дорожкина Н.Г. Модель батискафа из LEGO WeDo: инструкция по сборкеДорожкина Н.Г. Модель батискафа из LEGO WeDo: инструкция по сборке
Дорожкина Н.Г. Модель батискафа из LEGO WeDo: инструкция по сборке
 
Manual oso de anteojos
Manual oso de anteojosManual oso de anteojos
Manual oso de anteojos
 
Wedo perro alegre
Wedo perro alegreWedo perro alegre
Wedo perro alegre
 
Cargador
CargadorCargador
Cargador
 
Instalacion wedo
Instalacion wedoInstalacion wedo
Instalacion wedo
 

Semelhante a Робототехника с Not eXactly C. Часть I

NPM и модульная архитектура приложения
NPM и модульная архитектура приложенияNPM и модульная архитектура приложения
NPM и модульная архитектура приложенияDenis Latushkin
 
IT-инфраструктура. FAQ для разработчика
IT-инфраструктура. FAQ для разработчикаIT-инфраструктура. FAQ для разработчика
IT-инфраструктура. FAQ для разработчикаMikhail Chinkov
 
Desktop app based on node js and html5
Desktop app based on node js and html5Desktop app based on node js and html5
Desktop app based on node js and html5Provectus
 
Асинхронность и сопрограммы
Асинхронность и сопрограммыАсинхронность и сопрограммы
Асинхронность и сопрограммыPlatonov Sergey
 
отладка Mpi приложений
отладка Mpi приложенийотладка Mpi приложений
отладка Mpi приложенийMichael Karpov
 
справка по по Lego
справка по по Legoсправка по по Lego
справка по по Legopermskijkrai
 
SECON'2016. Чубарь Алексей, Мобильные грабли Unity
SECON'2016. Чубарь Алексей, Мобильные грабли UnitySECON'2016. Чубарь Алексей, Мобильные грабли Unity
SECON'2016. Чубарь Алексей, Мобильные грабли UnitySECON
 
Continuous deployment Smartling event
Continuous deployment Smartling eventContinuous deployment Smartling event
Continuous deployment Smartling eventViktoriya Pridatko
 
Модульная структура. Цветцих Денис D2D Just.NET
Модульная структура. Цветцих Денис D2D Just.NETМодульная структура. Цветцих Денис D2D Just.NET
Модульная структура. Цветцих Денис D2D Just.NETDev2Dev
 
Модульная структура
Модульная структураМодульная структура
Модульная структураDenis Tsvettsih
 
Continuous Deployment (in Russian)
Continuous Deployment  (in Russian)Continuous Deployment  (in Russian)
Continuous Deployment (in Russian)Smartling
 
основы ооп на языке C#. часть 1. введение в программирование
основы ооп на языке C#. часть 1. введение в программированиеосновы ооп на языке C#. часть 1. введение в программирование
основы ооп на языке C#. часть 1. введение в программированиеYakubovichDA
 
Ievgen Kulyk - Advanced reverse engineering techniques in unpacking
Ievgen Kulyk - Advanced reverse engineering techniques in unpackingIevgen Kulyk - Advanced reverse engineering techniques in unpacking
Ievgen Kulyk - Advanced reverse engineering techniques in unpackingNoNameCon
 
XP.Party (iOS) - unit tests frameworks overview
XP.Party (iOS) - unit tests frameworks overviewXP.Party (iOS) - unit tests frameworks overview
XP.Party (iOS) - unit tests frameworks overviewAnton Katkov
 
Подходы и технологии, используемые в разработке iOS-клиента Viber, Кирилл Лаш...
Подходы и технологии, используемые в разработке iOS-клиента Viber, Кирилл Лаш...Подходы и технологии, используемые в разработке iOS-клиента Viber, Кирилл Лаш...
Подходы и технологии, используемые в разработке iOS-клиента Viber, Кирилл Лаш...Yandex
 
20090720 hpc exercise1
20090720 hpc exercise120090720 hpc exercise1
20090720 hpc exercise1Michael Karpov
 
Alexey Savchenko, Evangelist, Unreal Engine/ Epic Games
Alexey Savchenko, Evangelist, Unreal Engine/ Epic GamesAlexey Savchenko, Evangelist, Unreal Engine/ Epic Games
Alexey Savchenko, Evangelist, Unreal Engine/ Epic GamesWhite Nights Conference
 

Semelhante a Робототехника с Not eXactly C. Часть I (20)

NPM и модульная архитектура приложения
NPM и модульная архитектура приложенияNPM и модульная архитектура приложения
NPM и модульная архитектура приложения
 
IT-инфраструктура. FAQ для разработчика
IT-инфраструктура. FAQ для разработчикаIT-инфраструктура. FAQ для разработчика
IT-инфраструктура. FAQ для разработчика
 
L^2: LEGO и Linux
L^2: LEGO и LinuxL^2: LEGO и Linux
L^2: LEGO и Linux
 
Desktop app based on node js and html5
Desktop app based on node js and html5Desktop app based on node js and html5
Desktop app based on node js and html5
 
Lirc или домашний медиацентр
Lirc или домашний медиацентрLirc или домашний медиацентр
Lirc или домашний медиацентр
 
Net framework
Net frameworkNet framework
Net framework
 
Асинхронность и сопрограммы
Асинхронность и сопрограммыАсинхронность и сопрограммы
Асинхронность и сопрограммы
 
отладка Mpi приложений
отладка Mpi приложенийотладка Mpi приложений
отладка Mpi приложений
 
справка по по Lego
справка по по Legoсправка по по Lego
справка по по Lego
 
SECON'2016. Чубарь Алексей, Мобильные грабли Unity
SECON'2016. Чубарь Алексей, Мобильные грабли UnitySECON'2016. Чубарь Алексей, Мобильные грабли Unity
SECON'2016. Чубарь Алексей, Мобильные грабли Unity
 
Continuous deployment Smartling event
Continuous deployment Smartling eventContinuous deployment Smartling event
Continuous deployment Smartling event
 
Модульная структура. Цветцих Денис D2D Just.NET
Модульная структура. Цветцих Денис D2D Just.NETМодульная структура. Цветцих Денис D2D Just.NET
Модульная структура. Цветцих Денис D2D Just.NET
 
Модульная структура
Модульная структураМодульная структура
Модульная структура
 
Continuous Deployment (in Russian)
Continuous Deployment  (in Russian)Continuous Deployment  (in Russian)
Continuous Deployment (in Russian)
 
основы ооп на языке C#. часть 1. введение в программирование
основы ооп на языке C#. часть 1. введение в программированиеосновы ооп на языке C#. часть 1. введение в программирование
основы ооп на языке C#. часть 1. введение в программирование
 
Ievgen Kulyk - Advanced reverse engineering techniques in unpacking
Ievgen Kulyk - Advanced reverse engineering techniques in unpackingIevgen Kulyk - Advanced reverse engineering techniques in unpacking
Ievgen Kulyk - Advanced reverse engineering techniques in unpacking
 
XP.Party (iOS) - unit tests frameworks overview
XP.Party (iOS) - unit tests frameworks overviewXP.Party (iOS) - unit tests frameworks overview
XP.Party (iOS) - unit tests frameworks overview
 
Подходы и технологии, используемые в разработке iOS-клиента Viber, Кирилл Лаш...
Подходы и технологии, используемые в разработке iOS-клиента Viber, Кирилл Лаш...Подходы и технологии, используемые в разработке iOS-клиента Viber, Кирилл Лаш...
Подходы и технологии, используемые в разработке iOS-клиента Viber, Кирилл Лаш...
 
20090720 hpc exercise1
20090720 hpc exercise120090720 hpc exercise1
20090720 hpc exercise1
 
Alexey Savchenko, Evangelist, Unreal Engine/ Epic Games
Alexey Savchenko, Evangelist, Unreal Engine/ Epic GamesAlexey Savchenko, Evangelist, Unreal Engine/ Epic Games
Alexey Savchenko, Evangelist, Unreal Engine/ Epic Games
 

Робототехника с Not eXactly C. Часть I

  • 1. Not eXactly C Программируем LEGO-роботов Александр Колотов alexandr.kolotov@gmail.com http://nnxt.blogspot.com Тюмень, 2013
  • 2. Давайте знакомиться! Колотов Александр Васильевич • Нижний Новгород • 4 года с LEGO-роботами • Тренер российской сборной World Robot Olympiad • http://nnxt.blogspot.com – самый полезный ресурс на русском языке по LEGO роботам
  • 3. LEGO Mindstorms Если вы можете придумать робота, вы можете его построить!
  • 4. Поколения LEGO Mindstorms • Первые наборы Lego Mindstorms начали выпускаться в 1998 году. Они были созданы на базе RCX блока. • Следующая версия - Lego Mindstorms NXT - выпускается в 2006 году. Основа – NXT блок. • Начиная с середины 2009, продается новая версия Lego Mindstorm NXT 2.0. Новшества: цветовой датчик и математика с дробными числами • 2013 год – начинается продажа LEGO Mindstorms EV3: более мощное «железо», новые датчики.
  • 5. Программирование • NXT даёт возможность программировать роботов, используя USB или Bluetooth
  • 6. Программа на PC Команды на моторы Данные с сенсоров и енкодеров MS Robotics Developer Studio NI LabView LEGO::NXT Robolab NXT-Python Scratch RWTH - Mindstorms NXT Toolbox for MATLAB
  • 7. Программа на NXT Скомпилированный исполняемый файл NXT-G NI LabView leJOS NXJ Robolab Enchanting RobotC Not Exactly C (NXC) NXT Byte Code (NBC)
  • 8. Программа на телефоне Программа-посредник RPC Результаты вызова RPC MINDroid – OpenSource проект от LEGO Chatterbox – как инициировать общение со стороны NXT блока Конструкторы: MIT App Inventor, CATROID
  • 9. Язык программирования Not eXactly C • Not eXactly C (NXC) – язык программирования, специально придуманный для программирования LEGO-роботов. • В основе языка NXC (ЭнИксСи) лежит популярный язык программирования С (Си), на котором создаются профессиональные программы. • Язык NXC значительно проще своего предка, что позволяет изучить его очень быстро – можно написать первые программы для робота уже на первый день знакомства.
  • 10. Язык программирования Not eXactly C • Программирование на NXC доступно в: • Windows • Среды: Bricx Comand Center, RobotC Virtual World • Linux • Среды: nxcEditor, любой текстовый редактор • Mac OS X • Официальный сайт: http://bricxcc.sourceforge.net/ • Компилятора языка NXC, как и среду BricxCC можно использовать бесплатно.
  • 12. Bricx Command Center • Основа среды BricxCC (БрикИксСиСи) – текстовый редактор с подсветкой синтаксиса (конструкций языка) • Среда поддерживает программирование RCX и NXT блоков. Идет разработка поддержки EV3 блоков.
  • 13. Bricx Command Center • Установка среды BricxCC • Скачать и установить офиц. версию: http://sourceforge.net/projects/bricxcc/files/bricxcc/ • Разработчики все время добавляют новые функции в программу. Чтобы получить доступ к самым последним функциям, можно скачать тестовую стабильную сборку: http://bricxcc.sourceforge.net/test_releases/ • Компьютер должен увидеть NXT блок, как устройство, поэтому нужно установить Fantom Driver от LEGO: http://mindstorms.lego.com/en-us/support/files/Driver.aspx
  • 14. Bricx Command Center Если блок не подключен шаг • Запуск среды программирования можно пропустить
  • 15. Bricx Command Center • Подключение NXT блока Выбрать порт подключения USB или BlueTooth
  • 16. Bricx Command Center • Среда поддерживает большое количество инструментов для работы с NXT блоком
  • 17. Bricx Command Center • Инструменты для получения данных о состоянии NXT блока
  • 18. Bricx Command Center • Инструменты для работы с файлами на NXT блоке позволяют копировать файлы на блок, читатать файлы с блока, удалять их
  • 19. Bricx Command Center • Специальный инструмент NeXT Screen позволет отображать в отдельном окне, то что выводится на экран блока.
  • 20. Bricx Command Center • В любой момент времени по каждой конструкции или функции языка можно получить справку, нажав <F1>
  • 21. Самая простая программа /* основная часть программы */ task main() { //Вывести на экран NXT блока строку TextOut(0, LCD_LINE1, "Start"); }
  • 22. Самая простая программа Многострочный комментарий Открывающая часть - /*, закрывающая часть - */ /* основная часть программы */ task main() { //Вывести на экран NXT блока строку TextOut(0, LCD_LINE1, "Start"); }
  • 23. Самая простая программа Каждая программа должна содержать, как /* основная часть минимум, одну программы */ задачу. task main() { Основная //Вывести на экран NXT блока строку задача в TextOut(0, LCD_LINE1, "Start"); программе } всегда называется «main».
  • 24. Самая простая программа Внутри задач содержится блок команд. Каждый блок команд в программе отделяется от другого блока фигурными скобками. /* основная часть программы */ task main() { //Вывести на экран NXT блока строку TextOut(0, LCD_LINE1, "Start"); }
  • 25. Самая простая программа Можно использовать однострочные комментарии. Начинаются с //. /* основная часть программы */ task main() { //Вывести на экран NXT блока строку TextOut(0, LCD_LINE1, "Start"); } Однострочные комментарии удобно использовать, чтобы временно «скрыть» часть программы: //TextOut(LCD_LINE1, "Start");
  • 26. Самая простая программа /* основная часть программы */ task main() { //Вывести на экран NXT блока строку TextOut(0, LCD_LINE1, "Start"); } Функции в программе чувствительный к регистру: “TextOut” не тоже самое, что “textout”. Внутри скобок – параметры настраивающие поведение функции. Каждая функция в программе отделяется от остальных точкой с запятой.
  • 27. Компиляция • Все программы для NXT блока представляют собой специальный набор инструкций - байткод, который исполняется интерпретатором, являющимся частью NXT firmware (набор программ стартующих при включении блока). • Компилятор языка NXC преобразует исходный код программ в байткод понятный для NXT. • После компиляции исполняемый файл должен быть скопирован на NXT блок.
  • 28. Компиляция Просто скомпилировать Cкомпилировать программу. Используется и загрузить Запустить для проверки на наличие программу на программу на ошибок синтаксиса. NXT блок. NXT блоке <F5> <F6> <F7>
  • 29. Компиляция • При компиляции может выдаться ошибка о использовании не той версии NXT firmware. • Необходимо указать компилятору, чтобы он автоматически определял firmware у подключенного блока. • Сделать это можно в настройках компилятора.
  • 30. Программирование моторов • Наиболее часто используемой функцией робота является «Движение». • Двигаться может весь робот: • движение тележки • Двигаться могут части робота: • движение манипулятора (рука, клешня) • движение сенсора
  • 31. Программирование моторов • Программирование моторов может происходить посредством одной из следующих функций: RotateMotor(outputs, pwr, angle) – поворот мотора с заданной мощностью на заданный угол RotateMotorEx(outputs, pwr, angle, turnpct, sync, stop) – аналогично RotateMotor, но позволяет контролировать распределение мощности между моторами, синхронизацию и тип остановки после окончания движения OnFwd(outputs, pwr) – включить моторы для движения вперед с заданной можностью и передать управление следующей команде OnRev(outputs, pwr) – то же, но с движением назад OnFwdSync(outputs, pwr, turnpct) – аналогично OnFwd, но позволяет контролировать распределение мощности OnRevSync(outputs, pwr, turnpct) – то же, но с движением назад Off(outputs) – торможение моторами Coast(outputs) – отключение энергии от моторов
  • 32. Программирование моторов • Управляем количеством движения: RotateMotor(outputs, pwr, angle) Тормозить Какие моторы вращать: Угол в градусах. моторами OUT_A, OUT_B, OUT_C Мощность: Отрицательные значения – или просто OUT_BC, OUT_AC -100..100 поворот в противоположную отключить OUT_AC сторону энергию RotateMotorEx(outputs, pwr, angle, turnpct, sync, stop) Распределение мощности между двумя моторами Вкл/выкл при использовании «спаренных» сихнронизацию двигателей, например, A и B или B и С (-100..100) между моторами • Пример: RotateMotor(OUT_A, 100, 275); RotateMotorEx(OUT_BC, -75, 720, -100, true, true);
  • 33. Программирование моторов • Строя последовательность из функций управления моторами с нужными параметрами можно добиться сложной траектории движения робота: task main() { //Движение вперед RotateMotor(OUT_BC, 100, 720); //Поворот вокург своей оси RotateMotorEx(OUT_BC, -75, 360, 100, true, true); //Движение назад RotateMotor(OUT_BC, -80, 1800); //Поворот одним двигателем RotateMotor(OUT_C, 75, -180); }
  • 34. Программирование моторов • Задание 1. Движение одним мотором. • Запрограммировать только один мотор у тележки через функцию RotateMotor • Пронаблюдать, как тележка двигается в зависимости от того какой мотор мы контролируем. • Пронаблюдать, как тележка двигается в зависимости от того какое направление движения мотора (вперед или назад) мы выбираем: • Изменять направления движения через указание отрицательной мощности и через отрицательное значение угла поворота. Мотор и направление Левый мотор, движение вперед Правый мотор, движение вперед Левый мотор, движение назад (отрицательная мощность) Правый мотор, движение назад (отицательный угол)
  • 35. Программирование моторов • Задание 2а. Движение двумя моторами. • Составить программу для робота-тележки таким образом, чтобы робот проехал вперед, а потом назад, вернувшись на то же место • Изменяя мощность подаваемая на моторы, посмотрите как это влияет на скорость движения робота • За счет чего будет задаваться движение назад? За счет управления мощностью или за счет управления направлением угла поворота? Мощность 25% 50% 100% Помните, что при разном уровне заряда на батарейках, моторы будут вращаться с разной скоростью при одном и том же значении задаваемой мощности в программе.
  • 36. Программирование моторов • Задание 2b. Движение двумя моторами. • Запрограммируйте робота таким образом, чтобы он проехал 30 см. (лист альбомной бумаги) – на сколько оборотов или градусов необходимо повернуть колеса тележки.
  • 37. Программирование моторов • Задание 2c. Движение двумя моторами. • Изучить, что произойдет, если запрограммировать робота ехать три оборота колес (1080 градусов), и в то же время руками остановить двигатели - искусственно создать ситуацию, когда робот натолкнулся на препятствие и колеса провернуться не могут. Цель эксперимента - показать, что выполнение программы блокируется в ожидании поворота двигателей. Это важно помнить, при движении робота по поверхности с препятствиями или при выполнении поворотов.
  • 38. Программирование моторов • Задание 2d. Движение двумя моторами. • Изучить, как распределение мощности между двумя моторами влияет на движение тележки. turnpct 0 -25 -50 RotateMotorEx(OUT_BC, -75, 720, , true, true); -100 25 50 100
  • 39. Программирование моторов • Задание 2e. Движение двумя моторами. • Подберите значение распределения мощности между двумя моторами для того, чтобы робот начал двигаться по каждой из указанных траекторий.
  • 40. Программирование моторов • Задание 3. Остановка. • Составить программу таким образом, чтобы тележка проехала вперед на максимальной скорости (максимальная мощность) в течение 4 оборотов двигателя. После окончания движения использовать торможение двигателем. RotateMotorEx(OUT_BC, 100, 1420, 0, true, true ); • Изменить программу, чтобы использовать отключение питания от мотора в качестве торможения. RotateMotorEx(OUT_BC, 100, 1420, 0, true, false );
  • 41. Программирование моторов • Сложные траектории. • Одной из сложностей при программировании движения робота является определение нужного количества оборотов мотора для передвижения на заданное расстояние. • Например, • На сколько нужно повернуть моторы, чтобы робот повернул на 90 градусов налево? • Как разворачиваться быстрее - повернуть на 90 градусов, включив только один мотор, или используя максимальное/минимальное значение распределения мощности между двумя моторами? • Подобрать экспериментальным путем, на сколько нужно повернуть моторы и какое нужно задать направление поворота, чтобы робот проехал полкруга с радиусом 30 сантиметров?
  • 42. Программирование моторов • Задание 4. Движение по квадрату. • Составьте программу для того, чтобы робот двигался по сторонам квадрата. • Как бы мы действовали, если бы мы двигались подобным образом?
  • 43. Программирование моторов • Задание 5. Движение по восьмерке. • Составьте программу для того, чтобы робот двигался по сторонам восьмерки. • Одной из трудностей в этой программе является возврат в то же место, откуда робот начал двигаться.
  • 44. Программирование моторов • Включаем моторы: OnFwd(outputs, pwr) OnRev(outputs, pwr) Распределение мощности между Какие моторы вращать: двумя моторами при использовании OUT_A, OUT_B, OUT_C Мощность: «спаренных» OUT_BC, OUT_AC -100..100 двигателей, например, A и B или B и OUT_AC С (-100..100) OnFwdSync(outputs, pwr, turnpct) OnRevSync(outputs, pwr, turnpct) • Пример: OnFwd(OUT_BC, 60); OnRev(OUT_A, 100); OnFwdSync(OUT_BC, -75, -100);
  • 45. Программирование моторов • Задание 6. Включение моторов. • Изучить, что произойдет, включить моторы и закончить программу. task main() { OnFwd(OUT_BC, 100); } Цель эксперимента - показать, что функции включения моторов никак не определяют сколько будет включен мотор, сколько колеса тележки проедут. Также он показывает, что при заверешении программы моторы явно не останавливаются – вместо этого с них снимается энергия и моторы продолжают двигаться по инерции.
  • 46. Ожидание • Иногда бывает необходимо вставить задержку между двумя выполняющимися действиями. • Примеры: • Подождать, пока человек отреагирует на действие • Подождать, пока датчики будут готовы к работе • Подождать, пока тележка проедет какое-то расстояние
  • 47. Ожидание • В языке NXC задержку между двумя командами можно добавить с помощью функции: Wait(milliseconds) Сколько миллисекунд ждать • Специальные константы для упрощения задания задержек: SEC_1, SEC_2, ..., SEC_10, SEC_ MIN_1 - секунды 15, SEC_20, SEC_30 - секунды • Пример: Wait(1); //Ждать 1 миллисекунду Wait(500); //Ждать полсекунды Wait(10000); //Ждать 10 секунд Wait(SEC_10); //Ждать 10 секунд Wait(SEC_2*5); //Ждать 10 секунд
  • 48. Программирование моторов • Останавливаем моторы: Off(outputs) Coast(outputs) Какие моторы останавливать: OUT_A, OUT_B, OUT_C OUT_BC, OUT_AC, OUT_AC OUT_ABC • Пример: Off(OUT_A); //Затормозить мотор А Coast(OUT_BC); //Отключить энергию с моторов B и C Off(OUT_BC); //Затормозить моторы B и C
  • 49. Программирование моторов • Задание 7. Еще одно движение по квадрату. • Составьте программу для того, чтобы робот двигался по сторонам квадрата. Но используйте функции включения/выключения моторов и временные задержки для того, чтобы определять сколько робот проедет и на сколько повернет. • Нужно ли останавливать двигатели перед поворотом? • Что произойдет, если во всей программе теперь изменить мощность на моторах в два раза?
  • 50. Программирование моторов • Задание 8. Блокировка колес. • Изучить, что произойдет, если запрограммировать робота ехать 5 секунд, и в то же время руками остановить двигатели - искусственно создать ситуацию, когда робот натолкнулся на препятствие и колеса провернуться не могут. Цель эксперимента - показать, что не смотря на то, что колеса заблокированы и не могут двигаться, программа продолжит выполняться после истечения 5 секунд.
  • 51. Работа с экраном • Среда программирования предоставляет возможность выводить текстовую и графическую информацию на графический экран NXT блока
  • 52. Работа с экраном • Экран имеет разрешение 100x64 точки – или можно сказать, что он имеет 100 столбцов по 64 строчки каждый. x = 99 y = 63 координата Y строчки x = 11 y=4 x=0 y=0 координата X столбцы
  • 53. Работа с экраном • Помимо графической информации, на экран можно вывести 8 строк текста по 16 символов • Поддерживаются только латинские символы, цифры строка 1 строка 2 Размер одного строка 3 знакоместа 6 x 8 точек строка 4 строка 5 строка 6 строка 7 строка 8
  • 54. Работа с экраном • Вывод текста и цифр на экран: TextOut(x, y, str) – вывести строку, начиная с заданных координат NumOut(x, y, value) – вывести число • Для упрощения позиционирования вывода на экран в нужных строках можно использовать спец. константы: LCD_LINE1 – первая сверху строка, строка в самом верху экрана LCD_LINE2 – вторая сверху строка . . . LCD_LINE8 – последняя строка, строка в самом низу экрана • Весь экран можно очистить: ClearScreen() TextOut(56, 0, "Hello"); • Пример: NumOut(10, LCD_LINE2, 314159); TextOut(6*8, LCD_LINE3, "Robot");
  • 55. Работа с экраном • Задание 9. Вывод текста во время работы программы. • Изменить программу движения по восьмерке таким образом, чтобы робот печатал соответствующие направление движения или направление поворота на экране: • “Forward” – прямо • “Left” – налево • “Right” – направо • Каждая новая надпись должна выводиться в новой строчке.
  • 56. Воспроизведение звуков • NXT блок имеет встроенный динамик, через который можно выводить звук определенной частоты или звуковые файлы в специальном формате.
  • 57. Воспроизведение звуков • Воспроизведение звука: PlayTone(frequency, duration) – воспроизвести звук заданной частоты (frequency, в герцах) и заданной продолжительности (duration, в миллисекундах) PlayToneEx(frequency, duration, volume, loop) – аналогично PlayTone, но позволяет задать громкость (volume, 0..4) и повторяемость действия. • Если нужно вывести конкретную ноту можно использовать спец. константы: TONE_C4 – нота ДО четвертой октавы, TONE_D4 – нота РЕ четвертой октавы TONE_E4 – нота МИ четвертой октавы, TONE_F4 – нота ФА четвертой октавы TONE_G4 – нота СОЛЬ четвертой октавы, TONE_A4 – нота ЛЯ четвертой октавы TONE_B4 – нота СИ четвертой октавы PlayTone(440, 250); • Пример: PlayTone(TONE_F4, 125); PlayToneEx(TONE_A4, 500, 4, false);
  • 58. Воспроизведение звуков • Задание 10. Звуки во время работы программы. • Изменить программу движения по восьмерке таким образом, чтобы робот воспроизводил звуки после завершения соответствующего движения прямо или поворота. • На повороте в лево звук должен быть отличным от звука на повороте в право.
  • 59. Для чего нужны датчики? • Основной функцией робота является движение или перемещение его частей (манипуляторы, захваты, ноги, сенсоры)
  • 60. Для чего нужны датчики? • Роботу необходимо изменять свое поведение (движение) в зависимости от внешних событий.
  • 61. Для чего нужны датчики? • Внешние события приходят роботу через сенсоры и датчики, от внутренних часов робота, от оператора, а также от других роботов.
  • 62. Что такое состояние? • Смена состояния робота: • При программировании роботов часто говорят о состояниях. Например, робот находится в состоянии движения или робот находится в состоянии бездействия. • Чтобы перейти к следующему состоянию, робот должен получить указание на это через какое-то событие.
  • 63. Что такое состояние? • Например, когда робот находился в состоянии движения, к нему приходит сигнал от датчика касания, что впереди перпятствие, и робот из состояния движения переходит в состояние бездействия. Сигнал от датчика Движение Остановка
  • 64. Ожидание событий • Следовательно, робот будет продолжать находиться в предыдущем состоянии до тех пор, пока не получит сигнал на переход в следующее состояни. • Робот должен ожидать возникновения сигнала – этот процесс можно назвать «Ожидание события»
  • 65. Ожидание событий • В языке NXC есть специальная конструкция для ожидания какого-то события: until(УСЛОВИЕ) – программа не идет к выполнению следующих команд, пока не наступит заданное условие. • Конструкцию можно описать фразой: «выполнять предыдущее действие до тех пор, пока не случиться ...» • УСЛОВИЕ - чаще всего сравнение текущих показаний датчиков с каким-то эталонным значением (точка срабатывания, предельное значение и т.п.). Сравнение происходит посредством конструкций: ЗНАЧЕНИЕ1 == ЗНАЧЕНИЕ2 – равныпрограмма не идет к выполнению следующих команд, пока не наступит заданное условие.
  • 66. Ожидание событий • УСЛОВИЕ - чаще всего, сравнение текущих показаний датчиков с каким-то эталонным значением (точка срабатывания, предельное значение и т.п.). Сравнение происходит посредством конструкций: ЗНАЧЕНИЕ1 == ЗНАЧЕНИЕ2 – условие справедливо, если значения равны ЗНАЧЕНИЕ1 != ЗНАЧЕНИЕ2 – условие справедливо, если значения не равны ЗНАЧЕНИЕ1 < ЗНАЧЕНИЕ2 – условие справедливо, если первое значение меньше второго ЗНАЧЕНИЕ1 > ЗНАЧЕНИЕ2 – условие справедливо, если первое значение больше второго ЗНАЧЕНИЕ1 <= ЗНАЧЕНИЕ2 – условие справедливо, если первое значение меньше или равно второму (не больше второго) ЗНАЧЕНИЕ1 >= ЗНАЧЕНИЕ2 – условие справедливо, если первое значение больше или равно второму (не меньше второго)
  • 67. Датчик касания • Датчик касания позволяет роботу воспринимать прикосновения и реагировать на внешние раздражители • С помощью датчика касания робот может подбирать предметы • Манипулятор, оснащенный датчиком касания, позволит роботу узнать, имеется ли объект, который можно взять • Датчик касания по сути своей кнопка, у которой возможно два состояния - Нажато и Отжато.
  • 68. Датчик касания • Перед работой с любым датчиком в языке NXC его нужно инициализировать, то есть сказать программе к какому порту, какой именно датчик присоединен. • Инициализация датчика касания: SetSensorTouch(port) – с этого времени работать с заданным портом, как с датчиком касания • Тогда получить текущее значение в программе можно посредством опроса функции: Sensor(port) – если датчик нажат, функция вернет 1, если отжат, то возвращаемое значение будет 0. • port – номер порта, к которому подключен датчик, задается константами: S1, S2, S3, S4 или IN_1, IN_2, IN_3, IN_4
  • 69. Датчик касания • Пример: task main() { SetSensorTouch(S1); //Ничего не делать до тех пор, пока датчик не будет отпущен until(Sensor(S1) == 0); //Начать движение вперед OnFwd(OUT_BC, 100); //Двигаться до тех пор, пока датчик не будет нажат until(Sensor(S1) == 1); //Остановиться Off(OUT_BC); }
  • 70. Датчик касания • Задание 11. Робот обнаруживает препятствие. • На роботе датчик касания «смотрит» вперед • Робот начинает двигаться • Как только обнаружится касание с препятствием, робот должен остановиться. • Остановился робот сразу после касания или сколько-то еще пытался продолжать двигаться? • За счет какого действия в программе нужно остановить робота, сразу после обнаружения нажатия?
  • 71. Датчик касания • Задание 12. Запуск робота c кнопки. • Изначально робот стоит и должен начать двигаться только после того, как происходит нажатие на датчик касания. • Робот останавливается после столкновения с препятствием. • Почему робот не поехал, а программа сразу завершилась?
  • 72. Датчик касания Программа исполняется на NXT блоке быстрее, чем человек взаимодействует с роботом. Человек нажал на кнопку task main() { SetSensorTouch(S1); Моторы только начали запускаться, и управление until(Sensor(S1) == 1); передалось следующей команде OnFwd(OUT_BC, 100); Очень-очень быстро! Человек еще не Тысячные доли секунды успел отдернуть until(Sensor(S1) == 1); руку от датчика Off(OUT_BC); Моторы } остановились и программа завершилась
  • 73. Датчик касания • Вариант решения: task main() { Человек нажал на SetSensorTouch(S1); кнопку until(Sensor(S1) == 1); За это время, кнопка отжимается Wait(500); OnFwd(OUT_BC, 100); Моторы запускаются until(Sensor(S1) == 1); К этому времени датчик Off(OUT_BC); «освобожден» и ожидает } сигнала касания Минусы подхода: • Задержку надо подбирать индивидуально для человека • Запуск мотора происходит с видимой задержкой после нажатия
  • 74. Датчик расстояния • Датчик расстояния (ультразвуковой датчик) позволяет роботу измерять расстояние до объекта и реагировать на движение • Сенсор измеряет расстояние путем расчета времени, которое потребовалось звуковой волне для возвращения после отражения от объекта
  • 75. Датчик расстояния • Инициализация датчика расстояния: SetSensorLowspeed(port) – с этого времени работать с заданным портом, как с датчиком расстояния. В названии функции фигурирует «медленный датчик», потому что этот датчик цифровой и работает по I2C шине, которая не позволяет опрашивать датчик слишком часто. • Текущее значение датчика: SensorUS(port) – расстояние в сантиметрах (6..255)
  • 76. Датчик расстояния • Пример: task main() { SetSensorLowspeed(S4); //Начать вращение вокруг своей оси OnFwdSync(OUT_BC, 50, -100); //До тех пор, пока не возникнет препятствие ближе, чем 50 см. until(SensorUS(S4) < 50); //Остановить моторы Off(OUT_BC); //Начать движение и двигаться 3,5 секунды OnFwd(OUT_BC, 100); Wait(3500); Off(OUT_BC); }
  • 77. Датчик касания • Задание 13. Робот обнаруживает препятствие. • Датчик расстояния на роботе «смотрит» вперед • Робот двигается до тех пор, пока не появится препятствие ближе, чем 20 см. 20 см.
  • 78. Датчик касания • Задание 14. Робот-воин. • Роботу понадобятся два датчика: расстояния и касания • «Воин» крутится быстро на одном месте вокруг себя • Как только в его поле зрения появляется предмет ближе чем 50 см., робот начинает двигаться к этому предмету и останавливается когда стукнется об него
  • 79. Датчик касания • Задание 15. Парковка. • Датчик расстояния смотрит в сторону • Робот должен найти пространство для парковки между двумя «автомобилями» и выполнить заезд в обнаруженное пространство 15 см. ?? см. 15 см.
  • 80. Датчик освещенности • Датчик освещенности (световой датчик) позволяет роботу различать яркость объектов, освещенность помещения и даже различать цвета. • Что видит глаз человека • Что видит робот через датчик освещенности
  • 81. Датчик освещенности • Инициализация датчика освещенности: SetSensorLight(port, active) – с этого времени работать с заданным портом, как с датчиком освещенности. Включать светодиод или нет, определяется в параметре active • Включить/отключить светодиод можно также позднее с помощью функций: SetSensorType(port, SENSOR_TYPE_LIGHT_ACTIVE) – включить SetSensorType(port, SENSOR_TYPE_LIGHT_INACTIVE) – выключить • Но тогда после функций выше надо вызвать ResetSensor(port) – firmware применит новую конфигурацию датчика • Текущее значение датчика: Sensor(port) – освещенность в процентах: чем меньше, тем темнее. Если светодиод не включен, то покажет окружающую освещенность. Если включен, то будет происходить замер отраженного света.
  • 82. Датчик освещенности • Пример: task main() { SetSensorLight(S3, true); //Начать движение OnFwd(OUT_BC, 80); //Ехать вперед до тех пор, пока не наедем на темный участок until(Sensor(S3) < 40); //Продолжать движение (эта команда не обязательна) OnFwd(OUT_BC, 80); //До тех пор, пока не наедем на светлый участок until(Sensor(S3) > 50); //Остановить моторы Off(OUT_BC); }
  • 83. Датчик освещенности • Задание 16а. Отобразить показания датчика. • На экране NXT блока должно отображаться текущее значение окружающей освещенности (светодиод выключен). • Как избежать запуска программы каждый раз, когда мы пытаемся измерить новую освещенность?
  • 84. Повтор одинаковых событий • Иногда в программе возникает необходимость повторить несколько одинаковых операций друг за другом несколько раз: 1 2 4 3
  • 85. Повтор одинаковых событий • Для повтора одинаковых действий в программах используются циклы. Например, while(УСЛОВИЕ) { тело цикла } – повторять команды, входящие в тело цикла, пока УСЛОВИЕ (условие существования цикла) справедливо Те действия, которые необходимо повторять несколько while(Sensor(S1 == 0)) { раз, помещаются внутрь цикла. Они RotateMotor(OUT_BC, 100, 1800); составляют тело цикла. RotateMotor(OUT_B, 50, 720); } Как только действие последней команде в теле цикла заканчивается, программа проверяет еще раз УСЛОВИЕ и переходит к первой команде в теле цикла, если оно справедливо.
  • 86. Повтор одинаковых событий • Довольно часто нужно повторять часть программы бесконечно, пока целиком вся программа не будет прервана. • Бесконечный цикл – в нем условие существование цикла всегда справедливо. while(true) { TextOut(0, LCD_LINE1, "Light Sensor:"); NumOut(20, LCD_LINE2, Sensor(S3)); Wait(500); ClearScreen(); }
  • 87. Датчик освещенности • Задание 16b. Отобразить показания датчика. • На экране NXT блока должно отображаться текущее значение отраженного света (светодиод включен).
  • 88. Датчик освещенности • Задание 17а. Черно-белое движение. • Пусть робот доедет до темной области на поле и остановится. • Что будем измерять: окружающую 22% освещенность или отраженный свет? • Как определить, что робот заехал на 54% темную область? Количество света, возвращенное в датчик на темной области зависит от окружающей освещенности, от высоты датчика, от цвета освещающего светодиода. Поэтому никогда не берите пограничное измеренное значение в условии генерации события. Обычно выбирают середину между показаниями на темной и светлой области. 22% 38% 54%
  • 89. Датчик освещенности • Задание 17b. Черно-белое движение. • Пусть робот доедет, до темной области, а затем съедет обратно на светлую • Как только получилось, добавьте цикл в программу - пусть робот перемещается вперед-назад попеременно, то на темную, то на светлую область.
  • 90. Датчик освещенности • Задание 17c. Движение вдоль линии. • Пусть робот перемещается попеременно, то на темную, то на светлую область, но теперь движение должно выполняться поочередно то одним, то другим колесом. • Попробуйте теперь поставить робота на узкую черную линию.
  • 91. Датчик угла поворота оси мотора • B каждый мотор встроен датчик угла поворота оси (енкодер), который позволяет контролировать движение с высокой точностью – до 1 градуса. • Енкодеры автоматически используются в большинстве программ, когда задается проехать определенное количество движения или для того, чтобы обеспечить роботу движение прямо (оба колеса должны поворачиваться на одно и то же количество градусов в единицу времени).
  • 92. Датчик угла поворота оси мотора • По-умолчанию, показания датчика поворота накапливаются с момента старта робота. Т.е. можно в любой момент времени узнать, на какое расстояние робот уехал от зоны старта. Причем движение мотора вперед увеличивают это число, движение мотора назад уменьшает его. • Это поведение можно изменить, если в сбросить показания датчика - накопление будет происходить с момента, когда произошел сброс. Старт программы Сброс Замер показаний 3 оборота Поведение по-умолчанию, 5 оборотов Количество оборотов Количество оборотов мотора мотора после сброса 2 оборота после старта
  • 93. Датчик угла поворота оси мотора • Инициализация датчика угла поворота оси мотора (енкодера) не требуется. • Получить текущее значение датчика: MotorRotationCount(output) – на какое количество градусов повернулся соответствующий мотор. Имеет смысл указывать только один мотор. Мотор задается одной из констант: OUT_A, OUT_B, OUT_C • Сбросить датчик угла поворота: ResetAllTachoCounts(output)
  • 94. Датчик угла поворота оси мотора • Пример: task main () { RotateMotor(OUT_BC, 80, 720); //Вывести значения енкодеров NumOut(0, LCD_LINE1, MotorRotationCount(OUT_C)); NumOut(0, LCD_LINE2, MotorRotationCount(OUT_B)); //Сбросить значения енкодеров только на моторе С ResetAllTachoCounts(OUT_C); RotateMotor(OUT_BC, 80, 720); //Вывести новые значени енкодеров. Один будет //примерно в два раза больше другого. NumOut(0, LCD_LINE4, MotorRotationCount(OUT_C)); NumOut(0, LCD_LINE5, MotorRotationCount(OUT_B)); }
  • 95. Датчик угла поворота оси мотора • Задание 18. Непослушный робот. • Робот стоит на неизвестном расстоянии от черной линии. • После старта программы робот должен доехать до черной линии и остановиться. • Затем робот должен проехать назад ровно такое же расстояние так, чтобы оказаться на том же месте, откуда начал движение. ?
  • 96. Состязание! • Задание 19. Кегельринг. • Роботу понадобятся датчик расстояния и датчик освещенности • Задача робота обнаружить внутри ринга 8 кеглей (предметы обнаруживаемые датчиком расстояния) и вытолкнуть их за черную линию, ограничивающую ринг • Сам робот не должен выезжать за границу ринга больше, чем на 5 секунд.
  • 97. Принятие решений • В ходе выполнения задания перед роботом может стоять выбор, в какое состояние ему перейти. • Подобный выбор стоит перед богатырем на распутье. • Выбор может зависеть от показаний на сенсорах и датчиках, внутренних часов робота или от информации полученной от других роботов.
  • 98. Принятие решений • Например, робот, обнаружив красный мяч, должен отнести его в корзину, а синий оставить на месте. Включить моторы Узнать захвата какого цвета мяч Включить моторы для разворота
  • 99. Принятие решений • Также можно говорить о причинах и действиях, которые эти причины вызывают. Стало Поднять тихо занавес Подать Стало звуковой громко сигнал причины действия
  • 100. Принятие решений • В языке NXC для анализа причины и выборе соотвестствующего действия используется конструкция: if (УСЛОВИЕ) { действия А и Б } else { действия В и Г } – если УСЛОВИЕ справедливо, то выполнять действия А и Б, иначе, если УСЛОВИЕ не верно, то выполнять действия В и Г. • Можно использовать сокращенную запись, если не нужно выполнять никаких действий при несправедливости условия: if (УСЛОВИЕ) { действия А и Б }
  • 101. Принятие решений • В месте принятия решения происходит разветвление программы. • В зависимости от решения, программа может пойти либо по одной, либо по другой ветке RotateMotor(OUT_BC, 60, 720); • После выполнения if (Sensor(S1)<40) { действий внутри //Если на сенсоре маленькие значения той или иной RotateMotor(OUT_A, 40, 90); ветки, программа } else { //Если на сенсоре большие значения вновь TextOut(0, LCD_LINE1, "Error"); возвращается в PlayTone(TONE_C4, MS_250); } «основное русло». RotateMotor(OUT_BC, 60, -720);
  • 102. Принятие решений • Можно вкладывать конструкции друг в друга, для принятия сложных решений: if (Sensor(S1) < 40) { if (SensorUS(S4) > 25) { RotateMotor(OUT_B, 90, 360); } else { RotateMotor(OUT_C, 90, 360); } TextOut(0, LCD_LINE1, "Too bright"); } else { TextOut(0, LCD_LINE1, "Error"); PlayTone(TONE_C4, MS_250); }
  • 103. Принятие решений • Задание 20. Нажми кнопку! • После включения блок должен проверить нажат ли датчик касания. • В зависимости от того нажат или нет, вывести на экран “Yes” или “No” • После вывода на экран – остановить программу YES NO
  • 104. Принятие решений • Задание 21. Управляемая машинка • Датчик касания закреплен на длинном проводе • Если датчик нажат – робот-тележка стоит, если отжат – едет • Измените, программу так, чтобы при нажатом датчике робот вращался вокруг своей оси, а при отжатом – двигался вперед.
  • 105. Принятие решений • Задание 22. Азбука Морзе • Пусть тележка крутиться вокруг своей оси • Когда датчик находится на темной поверхности – издается звук, как только поверхность светлее – звук смолкает L E G O
  • 106. Принятие решений • Задание 22. Неудачный пешеходный переход • Робот-тележка должен пересекать черные полоски – дорожки, при пересечении издавать звук. • Как только перед роботом возникнет препятствие – он должен остановиться • Как сделать так, чтобы робот перестал выполнять цикл после обнаружения стены?
  • 107. Выход из цикла по условию • Типичная ситуация, когда цикл должен завершиться при по какому-то событию, из-за какой то причины. • В начале цикла можно задать условие, которое будет определять, когда тело цикла все еще должно выполняться: while (УСЛОВИЕ) { тело цикла }. • УСЛОВИЕ будет проверяться каждый раз, когда происходить переход от последней команды в теле цикла к первой. Если УСЛОВИЕ не справедливо, то цикл завершиться. • После выхода из цикла будут выполняться команды, идущие сразу после закрывающей скобки.
  • 108. Выход из цикла по условию • Пример: while(SensorUS(S3) > 15) { if (Sensor(S3) > 40) { OnFwd(OUT_B); Coast(OUT_C); } else { OnFwd(OUT_C); Coast(OUT_B); } } //Переход к этой функции случиться, когда расстояние //станет меньше 15 см. Off(OUT_BC);
  • 109. Принятие решений • Задание 23а. Беспокойный любопытный робот • Робот должен находиться все время на одном расстоянии от руки (или другого предмета) – 25 см. • Если рука удаляется от робота, то робот придвигается к ней • Если рука приближается к роботу, то робот отъезжает назад.
  • 110. Принятие решений • Задание 23b. Опытный любопытный робот • В предыдущем задании, робот никогда не был в состоянии покая – он, то ехал вперед, то двигался назад • Нужно изменить программу так, чтобы робот был неподвижен при нахождении на определенном расстоянии • Задание нужно выполнить с использование вложенных условий if (SensorUS(S4) < 24) { OnFwd(OUT_BC, 60); } else { 24 см. if (SensorUS(S4) < 26) { 26 см. Off(OUT_BC); } else { OnFwd(OUT_BC, -60); } }
  • 111. Программирование LEGO роботов Ваши вопросы?