Видео отличное - все основные проблемы рассказаны. Ну и лица сплошь знакомые: Дэвид Оттен и Питер Харрисон. Хотя насчет "собрать робота в спальне" он немного покривил душой. Там и 3D печать, и у кого-то лазерный резак и еще много чего. Я подписался на их канал и посматриваю их видео, где они хвалятся своими инструментами, методами и технологиями.
С этим двигателем от RSLK у меня ничего путного не получается. У меня есть макетная плата - заменитель робота без механики, чтобы отлаживать код в поезде по пути на работу, так вот я её решил расширить - напаял драйвера двигателей. Подключил к ним двигатели - всё-равно есть ложные срабатывания. Так что плата дистрибуции, что стоит на шасси - не виновата. Пока могу обвинить только "эти двигатели". Тем более, что у них еще и люфт страшный. Надо было бы подарить эти комплекты каким-нибудь школьникам - пусть играются, но у меня есть тихая мечта, сделать этого робота таким быстрым, чтобы обогнать литовского конкурента. Думал как бы туда засунуть моторы micrometal. Прямо не получается - ось находится на уровне батарейного отсека, который и не позволяет там разместить двигатели. Но на алиэкспрессе нашел моторчики с перпендикулярным выходом оси. Но они тоже из серии маломощных (по данным: обороты на холостом ходу 450 rpm, редуктор 1:45, то сами моторчики дают всего 20 000 rpm). Попробовал подключить к лабораторному блоку питания - уж очень легко колесо пальцем останавливается. Нарисовал в CADе "адаптер", чтобы их можно было установить на шасси ROMI. Когда напечатаю - посмотрим, смогут ли они этого робота вообще сдвинуть.
А пока взялся за снятие характеристик робота на шасси Zumo:
Графики выглядят страшненько. Но что еще хуже, передаточая характеристика не особо линейная на начальном участке. В общем, я её аппроксимировал как 0,5 м/с на 1 вольт, со смещением 2.4 вольта. Постоянная времени 215 миллисекунд.
Но почему графики такие "неровные"? Подумал, что возможно, из-за гусениц. Попробовал снять гусеницы - графики остались точно такими же, только постоянная времени стала меньше.
Ну и ладно, теперь посмотрим на параметры вращения. Выполню те же тесты, но на один мотор буду подавать отрицательную полярность. Хотя тут вылезла бага. В старом контроллере скорости, контроллер текущую скорость вычислял как обратную величину от периода импульсов и в зависимости от флага направления менял знак. Но флаг направления имел 3 значения - Forward, Reverse и... Stop. Так вот при низких оборотах, если за цикл итерации не было ни одного импульса от таходатчика, то статус принимал значение Stop. А скорость меняла знак только при Reverse. В результате, при реверсе на малых оборотах скорость скакала между положительными и отрицательными значениями, хотя колесо на самом деле крутилось только обратно. В общем, пришлось в этом месте сделать нечто, навроде триггера Шмитта. Ну теперь снимаем характеристики:
График отображает скорость колеса по окружности, а сводный график скорость вращения в градусах в секунду. Можно заметить, что набираемая скорость в этом случае меньше, чем, если робот шел просто прямо. Т.е. видно, что даже при 6.5в на двигателях колеса не дают даже 1.5м/с. Так же, постоянная времени стала почти в два раза меньше. Была мысль, что батарейки сели или еще чего поломал, поэтому для сравнения сделал один прямолинейный тест и отобразил на этом же графике. Линия TestL (самая верхняя) - это прямолинейный ход при 6в питании. Видимо, это действительно так. Коэффициент усиления упал из-за бокового трения гусениц, а постоянная времени - из-за распределения массы?
Но такие скачки скорости всё-равно не дают покоя. Подумалось мне, а не поднять ли частоту ШИМ? Читал, конечно, что для двигателей частоту ШИМ особо увеличивать не стоит из-за увеличения индуктивного сопротивления. Задирать до 31кГц, как в UKMARSbot не стал, а повысил всего на порядок - до килогерца. Передаточная характеристика стала гораздо глаже, но коэффициент усиления упал с 0,5 м/с на вольт, до 0,38 м/с на вольт. Аналогично и скорость вращения.
Вот исходя из этих данных на базе кода UKMARSbot сделал контроллер позиции. Конечно, пришлось переназначить ресурсы. TIMER0 и 1 - теперь стали счетчиками энкодеров, потому что они 32 разрядные, хотя не уверен, что это реально необходимо. TIMER2 - ШИМ двигателей. Правда его я не мог вывести на нужный порт - пришлось для этого использовать PRS. Ну а TIMER3-4 генераторы главной последовательности - запуск АЦП для снятия темновых отсчетов, затем, включение боковых светодиодов и чуть позже снова запуск АЦП, далее, включение фронтальных и опять после паузы - запуск АЦП, ну и наконец - защелкивание состояния энкодеров в регистры захвата и вызов прерывания. Так как событий очень много, трёх регистров сравнения одного таймера было недостаточно, поэтому пришлось поставить второй работать синхронно с ведущим. Светодиоды детекторов стен включаю триггерами, построенными с помощью PRS. Поначалу была затея сделать тристабильный триггер, но, похоже, это съело бы 6 каналов PRS. Поэтому сделал просто два RS триггера, которые устанавливаются таймерами, а сбрасываются сигналом завершения работы АЦП. Правда, на выводы сигналы еще не вывел и работу не проверял. Пока эти таймеры делают просто захват состояния энкодеров и вызывают прерывание для контроллера движения.
Вот и начал тестировать движение. Как обычно, первое - настройка энкодеров. Пытаясь рукой робота прокатить заданное расстояние, посмотреть сколько импульсов таходатчика придёт. Но почему-то результат не совпал с расчетным - получалось так, что на оборот колеса робот проходил большее расстояние. Видимо, гусеница деформируется и решение для зубчатых ремней тут не годится. С другой стороны - деформация зависит от силы с которой робот давит на гусеницу, а я рукой давил достаточно сильно, чтобы при измерении гусеница не проскальзывала по поверхности стола. Так что, возможно, когда робот начнет сам бегать - придётся снова корректировать коэффициент между импульсами и пройденными миллиметрами.
Следующий на очереди PID контроллер. Робот два раза проезжает участок 200мм туда и обратно с линейным разгоном и торможением.
На графике представлена задаваемая скорость, напряжение подаваемое на моторы и позиция робота. Еще, попытался вычислить реальную скорость, но из-за большой дискретности таходатчиков и
округления отбрасывания дробной части у чисел с плавающей точкой - выглядит не очень, но тенденция видна. Коэффициенты ПИД можно считать достаточно правильными, так как напряжение подаваемое на двигатели меняется "плавно", а не скачет из одного крайнего положения в другое (было и такое, когда я пробовал подбирать Kp и Kd). Единственное, заметно, что робот в начале начинает двигаться с запаздыванием. Это из-за того, что там не организован полный FeedForward. В видео Питер Харрисон сказал, что добавить его - это "домашнее задание". Ну вот я его и добавил:
Несколько смущает, что при 4 вольтах напряжение перестаёт подниматься. Это напряжение не измеренное, а задаваемое. Но задаваемое относительно напряжения на выходе преобразователя, которое считается как неизменные 9 вольт. И у меня есть предположение, что на самом деле в момент старта напряжение на выходе преобразователя просаживается, поэтому в начальной фазе разгона вроде как подаётся чуть за высокое напряжение, а на самом деле несколько ниже.
Так как у этого робота расстояние, скорость и ускорение задаётся в миллиметрах и секундах, а напряжение в вольтах, то эти величины получаются дробными и приходится использовать плавующую точку. Для задания конфигурационных параметров, в интерпретатор добавил ввод чисел с плавающей точкой. Получилось довольно-таки просто. А вот как вывести эти числа... пока еще не придумал.
- Код:
Zumo>3.14 3.1415 3.141592 3.14159265 3.141592653 3.1415926535
Number overflow: 3.1415926535
Zumo>show
40490FDA
40490FDB
40490FD8
40490E56
4048F5C3
Интерпретация сделана тупо - введённые цифры пихаются в 32 битное число, которое просто делится на основание счисления столько раз, сколько "цифр за запятой". Поэтому невозможно ввести слишком точное число или слишком большое. С маленькими проблем нет ;-).
- Код:
Zumo>0.000000000066743 show
2E92C4F8
После чего начал тестировать, чтобы робот проезжал заданное расстояние. В результате чего выяснилось, что мой изначальный расчет импульсов на миллиметр был правильным, а измеренное, когда катал робота рукой - нет. А вот тест на вращение меня расстроил. Чтобы робот правильно поворачивал, необходимо знать, какого радиуса окружность описывают колёса, т.е. расстояние между точками касания. Введя значение измеренное штангенциркулем - давало на 1/8 меньше поворот, чем надо. Более того, поворот по часовой стрелке и против давал разные углы. И еще на разных поверхностях - разные. Но вот на оргалите - повороты были стабильные и я нашел, что расстояние между точками контакта равно 101мм. А 101мм - это максимальная ширина робота. Это не значит, что робот выполняет поворот касаясь внешними частями гусениц, а, скорее, то, что точки контакта образуют не прямой угол с осевой линией. И при поворотах на месте робот постоянно смещается влево. Еще предстоит посмотреть как робот будет выполнять плавный поворот, но из-за этой не повторяеиости поворотов начинаю думать, что надо делать другую кинематику.