Скачать статью в виде документа Mathematica (NB), CDF-файла или PDF.
NXT — процессор общего назначения, который используется для управления двигателями и датчиками; он идеально подходит для создания автономных роботов. Он также может сообщаться с более сложным программным обеспечением на компьютере посредством Bluetooth. В этой статье мы покажем, как правильно взаимодействовать с NXT через язык Wolfram Language (Mathematica), посылая корректные сигналы. Мы также представим пакет, который управляет всеми взаимодействиями между функциями. Эти функции могут использоваться в сочетании с динамическими ячейками для отображения статуса робота и управления его двигателем.
Введение
Роботы являются идеальными объектами для проверки когнитивных теорий, таких как обучение, адаптация, а так же для классификации воздействий среды. Ключевым элементом большинства роботов является центральный процессор, который получает данные среды посредством сенсоров и воздействует на среду с помощью моторов. С этой целью в 2006-м году LEGO представила новый программируемый конструктор — LEGO MINDSTORMS NXT. Этот конструктор, оборудованный четырьмя сенсорами и тремя моторами, имеет 256 Кбайт флэш памяти для хранения данных. Он может запускать программы, скомпилированные специально для этого конструктора (файлы с расширением .rxe, скомпилированные посредством LEGO LabVIEW или сторонними компиляторами, такими как NBC или NXC). Универсальность и низкая стоимость этого конструктора делают его идеальным объектом для проектов по разработке роботов.
NXT хорошо подходит для разработки автономных роботов, в том числе и разведывательных. Так же можно исследовать алгоритмы обучения; к примеру, можно найти более оптимальные способы решения задачи поиска выхода из лабиринта, нежели обычным методом проб и ошибок. Наконец, NXT также может быть использован для изучения социальных когнитивных моделей, в которых многочисленные роботы должны взаимодействовать, чтобы повысить выживаемость группы.
В этой статье показывается, как управлять конструктором посредством Bluetooth. Мы также представим пакет Math4NXT, который облегчает ряд задач. Используясь в сочетании со встроенной функцией Dynamic в Mathematica, управление роботом LEGO становится очень простым.
Создание линии связи
В первый раз, когда Вы запустите NXT, используйте Bluetooth на Вашем компьютере, чтобы найти его и создать связь. Что касается самого первого использования, Вам нужно будет ввести пароль на конструкторе (по умолчанию – “1234″) и компьютере. Затем Вам нужно будет выбрать сервис «Dev», доступный на конструкторе. Тем самым COM порт выделяется в качестве линии связи между компьютером и конструктором. Имя COM порта задается как переменная (к примеру, COM11), однако остается постоянным для конкретной пары компьютер-NXT (более подробные инструкции по созданию пары можно найти в [1]). После того, как Вы задали определённый COM порт, Вам больше не нужно будет повторять этот процесс.
Конструктор NXT имеет операционную систему (прошивку), которая сразу же обрабатывает запросы, получаемые от COM порта. Он это делает, даже если в данный момент на конструкторе запущена программа. Данные команды в документации LEGO [2] называются прямыми. Прямые команды включают в себя операции над файлами, управление мотором, настройку сенсоров и считывание с них данных, взаимодействие между разными конструкторами. Команды передаются через COM порт посредством сообщений, представляющих из себя последовательность байтов (числа от 0 до 255). Некоторые команды подразумевают ответ конструктора, который высылается так же в виде сообщения. Перед каждым сообщением отправляется информация о длине этого сообщения, на которую выделяется 2 байта. Таким образом, управление конструктором NXT представляет собой отправку определённых байтов в определённом порядке через последовательный порт.
Для того, чтобы использовать последовательный COM порт, следует использовать пакет для Mathematica под названием SerialIO [3]. Этот пакет состоит из двух частей. Первый — это исполняемая программа, предназначенная для вашего компьютера и операционной системы. SerialIO представляет такие программы для Linux, Windows (32- и 64-разрядных), а также для OS X. Вторая часть содержит функции Mathematica, которые могут быть использованы в Вашем проекте. Она включает в себя команды SerialOpen и SerialClose, для открытия и закрытия канала связи на данном COM порте, а SerialWrite и SerialRead записывает или считывает данные с COM порта. Представленный ниже рисунок показывает различные уровни, через которые информация поступает во время сообщения между NXT и компьютером.
Рисунок 1. Архитектура программного обеспечения, с помощью которой сообщаются NXT и компьютер. Последние три окна справа представляют программы Mathematica, а остальные два выдаются пакетом Math4NXT, о котором будет сказано далее.
Скачайте пакет SerialIO из Wolfram Library Archive и установите его в выбранную Вами папку (лучшего всего в AddOns Mathematica, которая находится в папке ExtraPackages). Для большего удобства Вы можете поместить свою рабочую папку по этому адресу, в результате чего MathLink-совместимые программы будут автоматически туда сохраняться.
Далее следует загрузить пакет посредством Needs.
Если команда будет выполнена успешно, то Вы сможете увидеть процесс SeriallO, работающий на Вашем компьютере в фоновом режиме. Следующая команда открывает COM-порт и устанавливает канал связи с конструктором (он должен быть включен).
Если у вас есть конструктор NXT и Вы хотите вычислить ячейки кода, которые представлены в данной статье, то Вам нужно выбрать какую-то ячейку, удерживая клавишу Alt, таким образом будут выделены все ячейки. Далее, из главного меню Mathematica необходимо выбрать Cell ▶ Cell Properties ▶ Evaluatable. Без подключённого NXT выполнение этих команд вернёт сообщение об ошибке и невычисленную ячейку.
Чтобы убедиться, что соединение открыто, посмотрите на дисплей на конструкторе, который находится в верхнем левом углу. Если вы видите <, то это значит, что соединение не установлено. А <> означает, что соединение установлено. Переменная mybrick содержит дескриптор потока данных с СОМ порта и используется во всех последующих сообщениях. Закрытие COM порта осуществляется с помощью следующей команды.
Выход из Mathematica (или прекращение работы ядра) закрывает COM порт и завершает процесс SeriallO, который работает в фоновом режиме.
Отправка сообщения и получение ответа
Пакет SerialIO был сделан, чтобы отправлять текст через СОМ-порт (или отдельные символы/строки текста). Однако, что касается управления NXT, имеет больше смысла отправить числа напрямую. Следовательно, нам нужно преобразовывать числа в соответствующие символы в ASCII-коде до того, как мы их отправим. Это немного неудобно, и мы предложим позже более аккуратнее решение.
Сообщение всегда начинается с байта, который указывает, следует ли NXT отвечать на него. Тут уж как кому удобнее, но многие команды, посылаемые конструктору, возвращают только байт состояния (0 — успешное выполнение, в противном случае — сообщение об ошибке). В случае ответного сообщения в виде байта состояния ответ является довольно таки бесполезным. Чтобы запросить ответ, первый байт должен быть равен 0; 128 означает, что NXT не должен отвечать.
Второй байт сообщения всегда является номером команды. Всё это представлено в документации LEGO Group [2]. Последующие байты зависят от отправленной команды.
Например, запрос к NXT проиграть звук задаётся прямой командой PlayTone. Номер этой команды — 3. Затем должны быть заданы два параметра: частота тона (число от 200 до 14000) и длительность тонов (в миллисекундах, число от 0 до 65535). Эти два параметра закодированы как UWORD (беззнаковое слово — WORD), то есть выделяется более двух байтов, наименее значащий байт ставится сначала. Для удобства, мы напишем функцию преобразования toUWORD.
Таким образом, частота тона в 480 Гц и продолжительность в две секунды соответствуют следующей последовательности байтов.
Всё сообщение выглядело бы так.
Перед самим сообщением должна быть указана его длина, которую можно получить посредством следующей команды.
Мы соединяем две части, чтобы получить полное сообщение и получить список символов, соответствующих их номерам (такие символы могут быть недоступны для просмотра на Вашем компьютере) в этой строке кода.
Давайте отправим эти символы конструктору NXT один за одним.
Теперь Вы можете услышать звуковой сигнал. Поскольку мы запросили ответ (первый байт был нулевым), нам нужно прочитать его.
Опять же, ответ состоит из текста (символы могут быть недоступны для просмотра). Давайте преобразуем их в список номеров.
Байты возвращаются в следующем порядке: длина возвращаемого сообщения, закодированная в более чем двух байтах в UWORD (в данном случае 3, 0 означает длину сообщения в 3 символа), второй байт показывает, что это ответное сообщение; третий байт указывает номер команды, которая выдала ответ (в данном случае команда Playtone) и, наконец, статус команды (где 0 указывает на успех). Команда PlayTone не возвращает другую информацию; некоторые прямые команды могут возвращать более сложные сообщения.
В качестве примера, мы отправляем команду GetBatteryLevel. Эта команда имеет номер 11 и не требует никаких параметров/дополнительной информации. Если ответ запрошен (но бессмысленно отправлять эту команду и не просить ответ) она возвращает статус команды (0 для успеха), за которым следуют два байта, указывающих напряжение батарей на NXT в милливольтах. Чтобы расшифровать напряжение, давайте создадим другую функцию преобразования – fromUWORD.
Давайте соберём всё сообщение, объединим с его длиной, сконвертируем это в список символов и отправим их.
Теперь давайте прочитаем ответ и преобразуем его в числа.
Первые два байта означают длину ответа (5 байт); 2 и 11 показывают, что это ответ на команду GetBatteryLevel; 0 указывает, что команда была успешно выполнена; и, наконец, 247 и 27 показывают напряжение аккумулятора, который мы преобразуем в число командой fromUWORD, описанной выше.
Таким образом, батареи имеют напряжение 7,16 вольт, что гораздо ниже ожидаемых 9 вольт для свежих батарей.
Переопределение SerialWrite, для отправки целых чисел или их списков
Поскольку удобнее представлять числа, а не символы, которые отправляются к конструктору, мы расширяем команду SerialWrite, содержащуюся в пакете SerialIO, чтобы иметь возможность отправки как отдельных целых чисел от 0 до 255 (байты), так и их списков.
С этим расширением всё сообщение (которое состоит из байтов) может быть передано одним вызовом SerialWrite. К примеру, следующие инструкции собирают повторно команду PlayTone (на этот раз без ответа).
Всё сообщение отправлено с помощью вызова одной команды.
Прямые команды, представленные в Math4NXT
Вышеупомянутое показывает, как какая-либо команда может отправляться к конструктору NXT, а его ответ — считываться. Потом, это просто вопрос сборки сообщения в правильном порядке и с нужной информацией, и, если потребуется, чтение ответа и его интерпретация. Для этих целей документация, предоставленная LEGO Group (особенно приложение 2 в [2]), является довольно полной.
Для большей простоты мы кодировали все прямые команды в пакете под названием Math4NXT. Сначала следует получить пакет Math4NXT. Так как он использует пакет SerialIO в фоновом режиме, также установите его в директорию, в которой осуществляет поиск Mathematica (например, FileNameJoin[{$ InstallationDirectory, «AddOns», «ExtraPackages», «SerialIO»}]). Затем загрузите Math4NXT с помощью следующей команды.
Поскольку мы поместили пакет Math4NXT не в одну из тех папок, по которым осуществляет поиск Mathematica, нам необходимо задать путь посредством команды Needs. Затем следует открыть последовательный порт (если это ещё не было сделано), как было показано ранее.
Все прямые команды начинаются с букв NXT. Следовательно, команда для чтения уровня батарей в пакете будет называться NXTGetBatteryLevel.
По умолчанию, команда возвращает ответ, используя именованные строки (например, «Status»). Вы можете извлечь какую-то часть информации обычным способом.
Этот формат может быть изменен, например, на raw (т. е. на выдачу в байтах, как и в двух предыдущих разделах), используя опцию ResultFormat.
С другой стороны, переданные и полученные байты могут быть отображены в отдельном окне с помощью опции .
Эта опция открывает окно сообщений.
Рисунок 2. Окно с сообщением открывается автоматически, когда опция используется.
Все прямые команды доступны.
Расширение прямых команд
Прямые команды имеют много ограничений. Во-первых, из-за природы СОМ порта, сообщение не может быть длиннее 253 байт. Это является большим ограничением при работе с файлами, которые могут быть гораздо больше. Кроме того, датчики LEGO работают весьма по-разному; некоторые датчики являются пассивными, не требующими питания, в то время как другие являются активными, а третьи являются программируемыми — как датчики I2C. Чтобы использовать команды единообразно и избежать ограничения по длине, мы задали команды более высокого уровня, внутри которых решаются эти проблемы.
Имена всех этих команд начинаются с M4N.
Одним из примеров является команда M4NFileNames которая перечисляет все файлы, присутствующие на конструкторе (опционально — с размером файла).
Эта команда работает, вызывая прямые команды NXTFindFirst (номер команды 134), NXTFindNext (135), и NXTClose (132), с помощью алгоритма, приведенного в Программе 1. Чтобы увидеть несколько вызовов команд NXT, используйте опцию в M4NFileNames.
res=NXTFindFirst[mybrick,"*.*"];
While [("Status"/.res)=0,
res=NXTFindNext[mybrick,"Handle"/.res]
]
NXTClose[mybrick];
Программа 1. M4NFileNames использует общий алгоритм для получения всех имён файлов, присутствующих на NXT. Этот алгоритм не показывает, как собрать имена файлов (содержащихся в виде байтов в res) в список.
Аналогичным образом, чтобы облегчить использование датчиков, имеется команда, которая передаёт сообщение в Mathematica о типах подключённых датчиков. Чтение с датчика впоследствии производится в соответствии с его типом. Чтобы установить тип датчика, используйте M4NSetSensor.
После этого чтение с датчика производится универсальной командой M4NReadSensor. Чтобы соответствовать стилю прямых команд, первый датчик ставится на порт 0 входа NXT.
Результат представляется либо как 1 для «нажатого» состояния, либо 0 как для «ненажатого». Эта команда работает одинаково вне зависимости от типа подключенного датчика. Поэтому, если Вы подключите ультразвуковой датчик на третий вход, Вы можете запустить следующие две команды.
Ультразвуковой датчик — сложный датчик, созданный для обнаружения расстояния до препятствий перед ним (в см). Он оснащен микропроцессором, который работает по протоколу I2C. Он должен быть сначала включён, и после его загрузки с него можно начать считывать данные. Используя опцию , Вы увидите, что для для инициализации ультразвукового датчика требуется гораздо больше обмена информацией, чем при инициализации сенсорного датчика. Тем не менее, весь этот обмен информацией совершенно невидим с командами M4N.
Работа с моторами
Другое ограничение прямых команд прошивки NXT касается управления двигателем. Новые моторы LEGO содержат встроенные счётчики оборотов, которые отслеживают количество вращательного движения. Однако, прямая команда может только остановить двигатель при достижении определенного количества пройденных градусов, после чего мотор меняет направление вращения.
PID-регулятор мотора является более эффективным способом контроля вращения. Он устанавливает количество градусов и регулирует мощность двигателя так, чтобы он замедлялся, когда цель почти достигнута (с помощью интеграла и производной; см. [4, 5]).
Авторы [5] разработали PID-регулятор для NXT. Этот контроллер находится на NXT; компьютер посылает заданное движение, после чего контроллер берет на себя управление двигателем, регулируя силу до тех пор, пока число градусов поворота не будет достигнуто. Программа контроллера называется MotorControl22.rxe, для версии 2.2.
Возьмите программу MotorControl22.rxe и отправьте её на конструктор. Чтобы сделать это, импортируйте содержимое файла в Mathematica и загрузите его в NXT. После установки (этот шаг может занять несколько минут при передаче через Bluetooth — файл весит 37 килобайт) можно запустить контроллер. Вот команды для выполнения этого; первая часть проверяет, что файл ещё не на конструкторе.
Наконец, посредством M4NSetMotor сообщите Вашей программе, какие у Вас типы двигателей и через какой порт они связаны.
Кстати, M4NSetMotor загружает MotorControl22.rxe, если он не присутствует на конструкторе и запускает эту программу, если она ещё не запущена. Следовательно, Вы можете не беспокоиться об этих деталях и можете полагаться только на M4NSetMotor.
Теперь, когда контроллер запущен и работает, вы можете отправить ему указания с помощью команд, связанных с моторами.
M4NRunMotor, M4NStopMotor и M4NBrakeMotor могут использоваться как на обычных двигателях, так и на двигателях со счётчиком оборотов (тахометром). Однако, M4NRunMotorFor может использоваться только с моторами, оснащёнными тахометром и PID-контроллером. Если двигатель управляется PID-контроллером, то Вам не стоит отправлять какие-то другие инструкции. Следовательно, M4NRunMotorFreeQ может использоваться для проверки контроллера.
Следующий набор команд запускает два мотора.
Остановить моторы можно с использованием двух различных режимов (M4NBrakeMotor блокирует двигатель, в то время как M4NStopMotor перестает питать двигатель).
Следующие команды проверяют, что мотор MOTORA свободен — до движения, во время движения (10 полных оборотов) и через шесть секунд после того, как движение начиналось.
Настройка робота
На уровне программы, робот имеет конкретную конфигурацию, которая определяет какие датчики соединены со входом и какие моторы имеются на выходе. Ранее мы показали две команды, которые могут быть использованы для определения датчиков и моторов.
Мы создали обобщённую команду M4NInitialize, целью которой является установка всех этих элементов в одной команде. Кроме того, она также может использоваться для установки уровня громкости и присвоения имени конструктору (если у вас их много, то было бы неплохо переименовать по имени COM порта, к которому они подключены).
Помимо этого M4NInitialize проверяет — совместима-ли версия прошивки на NXT с этим пакетом и что батарея имеет достаточный уровень заряда (в противном случае возвращает предупреждение). Также можно задать путь к папке, содержащей контроллер MotorControl22.rxe с помощью опции MotorControlPath, в случае, если она всё еще не находится на NXT.
Динамическое управление роботом
Команды M4N и NXT могут использоваться динамически. Например, чтобы получить текущее состояние сенсорных датчиков, следует выполнить следующие шаги.
Во-первых, инициализировать датчики, используя M4NInitialize или M4NSetSensor.
Функция ShowSensor создает панель с элементами On и Off, которые выставляются в зависимости от значения датчика. Эта функция использует некоторые опции только в целях удобства.
Затем, мы можем использовать ShowSensor четыре раза подряд, чтобы получить строку с индикаторами.
Опция UpdateInterval определяет, через какой промежуток времени сообщаться с датчиками.
В качестве последнего примера мы создалим джойстик который управляет двумя моторами. Скорость вращения мотора (отрегулированная опцией MotorPower) зависит от положения джойстика (вертикальная ось). Кроме того, двигатели движутся синхронно, если положение джойстика центрировано по горизонтальной оси.
Сначала мы определим расширенную функцию ClickPane, которая работает с большим количеством событий, чем обычная функция ClickPane.
Мы должны не забыть инициализировать моторы (чтобы PID контроллер включён).
Вот и все. Следующий пример отображает панель с красной точкой (верхняя часть джойстика). Таким образом мы постоянно задаём мощность двигателя, чтобы она была пропорциональна положению джойстика. Кроме того, если джойстик отпущен, он возвращается к центру с показательной функцией, представленной переменной mult. Наконец, если вы нажмете на панель в любом месте, джойстик мгновенно возвратится к центру со звуковым сигналом.
Робот, движущийся по заданной траектории
Чтобы проиллюстрировать простой пример автономного робота, мы создадим робота, движущегося по определённой траектории. Цель этого робота состоит в том, чтобы следовать по краю определённой линии. Линия должна быть тёмной на светлом фоне (или наоборот); контрастность на границе является важным фактором. Чтобы добиться этого, Вам понадобится робот, оснащённый спереди датчиком света (см., например, указания по сборке, данные на стр. 33 обучающей брошюры MINDSTORMS [2]).
Для этого проекта нам потребуются датчик света и два мотора, которые мы инициализировали.
На первом этапе мы должны откалибровать датчик так, чтобы показания на светлых и темных поверхностях были заданы. Используйте представленный ниже код, чтобы получить 100 показаний при движении робота по светлой поверхности.
Затем воспользуйтесь этим кодом при движении робота по тёмной поверхности.
Среднее вышеприведённых двух значений — критическое значение. Если робот, который следует по левому краю тёмной линии, наблюдает более светлый участок, чем среднее значение, нам нужно, чтобы он шёл вправо (и наоборот).
Следующая короткая программа перемещает робота на умеренной скорости (переменная basespeed имеет значение 20) и регулирует базовую скорость в соответствии с разностью между показанием о токе и среднем значении.
Константа mult используется для контроля коэффициента рулевого управления. Большие значения приводят к произведению роботом резких изменений направления. Эта величина должна быть небольшой для плавного движения. Тем не менее, если на траектории есть крутые повороты, малый множитель не даёт возможности роботу повернуться на достаточный угол, чтобы найти край снова. В выводах будут представлены некоторые подробности.
Технические ограничения
Есть несколько прямых команд, которые мы решили не реализовывать в этом пакете. Они связаны с перезагрузкой NXT, изменением его прошивки, стиранием флэш-памяти, выполнением сброса. В сущности, эти команды уничтожают робота.
С командами M4N и NXT робот может управляться очень эффективно и легко. Однако, COM порт не очень быстр. Важно отметить, что каждое переключение направления передачи сигнала порта занимает 6 мс. Это причина, почему ответов следует избегать, если они не являются действительно необходимыми. В некоторых приложениях эти задержки могут быть настолько важными, что программа должна быть перемещена в конструктор полностью или частично. PID контроллер MotorControl22.rxe является примером, в котором программа распределена между двумя машинами: компьютер задаёт необходимые движения, и конструктор исполняет решения миллисекунда за миллисекундой для достижения цели.
Выводы
Есть одна новая теория в когнитивной науке — теория воплощений. Она утверждает, что когнитивная система должна быть в интерактивной связи с внешним миром, чтобы разработать осмысленное представление о мире. Этот взгляд противоречит классическому взгляду на искусственный интеллект (ИИ), в котором утверждается, что когнитивные агенты манипулируют признаками или символами, которые могут быть не связаны с аспектами внешнего мира. Следовательно, с точки зрения ИИ, датчики и приводы не зависят от когнитивных функций и могут быть построены отдельно. Этот взгляд имеет силу, когда мы разрабатываем когнитивные системы в виртуальном мире (например, основанные на компьютерном моделировании). Тем не менее, когда роботы получают физическое воплощение, мы видим, как трудно удержать эту позицию.
Простая программа следования траектории показывает это. В виртуальной среде робот, следующий траектории, может работать на полной скорости, и повороты могут быть резкие, потому что нет инерции и риска, что робот упадёт. Когда робот получает физическое воплощение, данные аспекты становится очень серьёзными проблемами. Конечно, программист адаптирует программу, чтобы учесть эти риски (снижение скорости и уменьшение фактора усиления). Кроме того, данные о светлых и тёмных участках откалиброваны программистом весьма простым способом. Тем не менее, если внешнее освещение меняется, калибровка должна быть сделана снова. Кроме того, как было сказано раньше, если множитель mult имеет слишком маленькое значение, робот может не иметь возможности перемещаться достаточно быстро вокруг резкой кривой. Наконец, робот, следующий траектории, использует колёса. Если бы он использовал ноги вместо этого, гибкость и ограничения мышц вступили бы в силу.
Все вышеприведённые проблемы могут рассматриваться в худшем случае, как неудобства, а в лучшем случае как вызовы для программиста. Тем не менее, простейшие животные невосприимчивы ко всем этим проблемам. Теория воплощений утверждает, что организмы создали надлежащие представления о мире, взаимодействуя с ним, и что эти представления стали надежными в отношении всех возможных источников неисправности. Представления и алгоритмы, заданные программистом, с другой стороны, могут не отвечать требованиям реального мира, какими бы простыми и элегантными они не были.
NXT является простой, но полноценной платформой для испытания роботов в реальной жизни. В сочетании с вычислительной мощностью системы Mathematica, легко разрабатывать адаптивные алгоритмы, такие как нейронные сети и наблюдать, какие представления о мире получает робот. Ещё предстоит выяснить, как выглядит простейшая адаптивная программа робота, который следует по заданной траектории.
Благодарности
Автор хотел бы поблагодарить Vincent Brault, Dominic Langlois и Sylvain Chartier из CONEC laboratory (Оттавский университет) за их помощь в разработке пакета Math4NXT.
Использованная литература
[1] MathWorks. “Set Up a Bluetooth Connection.” (Feb 4, 2013) www.mathworks.com/help/simulink/ug/bluetooth-communications.html.
[2] The LEGO Group. “LEGO MINDSTORMS NXT Bluetooth Developer Kit.” (Jan 7, 2013) mindstorms.LEGO.com/en-us/support/files/default.aspx.
[3] R. Raguet-Schofield. “SerialIO.” Wolfram Library Archive. (Jan 7, 2013) library.wolfram.com/infocenter/MathSource/5726.
[4] J. Sluka. “A PID Controller For LEGO MINDSTORMS Robots.” (Jan 7, 2013) www.inpharmix.com/jps/PID_Controller_For _Lego _Mindstorms _Robots.html.
[5] Institute of Imaging & Computer Vision. “RWTH—MINDSTORMS NXT Toolbox.” (Jan 7, 2013) www.mindstorms.rwth-aachen.de/trac/wiki/MotorControl.
D. Cousineau, “Controlling Robots Built with the LEGO® MINDSTORMS® NXT Brick,” The Mathematica Journal, 2013. dx.doi.org/doi:10.3888/tmj.15-3.
Об авторе
Denis Cousineau является профессором Оттавского университета в области когнитивной психологии. Он проводит исследования в области искусственного интеллекта и процесса классификации объектов человеком.
Контактные данные: École de psychologie, Université d’Ottawa, 136, rue Jean-Jacques Lussier, Ottawa (ON), K1N 6N5, CANADA, e-mail: Denis.Cousineau@UOttawa.ca
Автор: OsipovRoman