Если ваш вопрос не влез ни в одну из вышеперечисленных тем, вам сюда.
Ответить

Re: RSLK от TI (Robotic System Learning Kit)

Вс сен 26, 2021 12:25:34

Борьба с i2c. Совершенно не понимаю, что происходит. Итак, плата с EFM32GG12. Всё работало хорошо, до тех пор пока я не вздумал прилепить сенсор цвета. Что-то вроде такого: TCS34725. Только у меня плата не синего, а сиреневого цвета, возможно не оригинальный adafruit. Так вот нашел я место для него на шасси, изготовил кабель воткнул в разъём и всё связанное с i2c перестало работать. Вообще, на i2c у меня ничего особого нет, помимо этого сенсора в данный момент только "клавиатура" - 3 кнопки подключенные к i2c расширителю портов PCA9536. Ну в общем, отладчиком я быстро выяснил, что программа зависает в функции i2c_rd в ожидании окончания транзакции. Все транзакции дут по прерываниям. Делал отладочный вывод вызовов прерываний и выяснил, что выполняется Start, посылка адреса и... всё. Нет ни NAK, если бы адрес был бы недоступен, ни прерывания по чтению байта. Выяснить, передаётся ли реально байт или нет, мне не удалось. Пытался осциллографом выловить "последнюю транзакцию", но мне это не удавалось. Проблема еще и в том, что это зависание происходит не сразу. Особенно, если не нажимать кнопки на клавиатуре. Т.е. если считываются все 0 - проблем нет. Если нажать на кнопку, то считываются коды в которых присутствует 1. И вот тогда появляются проблемы. Еще скорость возникновения пробемы падала при подключении щупов осциллографа. Скорость падала, если я шлейф втыкал в другое гнездо. На плате Romi у меня есть 3 гнезда с i2c интерфейсом: 2 спереди и одно сзади. Хуже всего работает заднее гнздо, а лучше всего переднее левое. Сенсор, по-случайности, тоже находится спереди слева, но кабель-то не меняется!

Что еще... У меня не было резисторов подтяжки. С одним i2c устройством спокойно справлялись внутренние подтяжки в микроконтроллере. Ну хорошо, приделал подтяжки по 3к. Хотя не знаю, на плате сенсора цвета этих подтяжек полно. Проблема именно с этой платой. Причем, я к ней даже не обращаюсь! Пробовал прицеплять плату от второго робота на VEML6040 - проблем нет. Что с этим сенсором не так? Главное отличие в том, что этот модуль для ардуины. Т.е. он расчитан на питание и логику 5в, а не 3.3в, как у меня. Хотя, написано, что на Vin можно подавать от 3.3в до 5в. Вот я и подаю 3.3в. Ну и для работы 5в логики на плате собран level shift для i2c.

Потом я подумал, что мой драйвер глюканутый, давай, возьмём от производителя. Ок, поставил соответствующий software component, переделал функции. Начал тестировать. Сначала показалось, что всё заработало... ан нет. Работает, если вставлен USB провод отладчика! Если вынуть, глючит как обычно. И точно так же зависает. Ну тут я вообще в непонимании. Схема питания у меня примерно такая:
Изображение Изображение Изображение
Сверху плата шасси Romi, снизу EFM32 кит. Для "развязки" я поставил диод шоттки, чтобы 5в от USB не пытались войти в выход TPS56320. В обратном направлении ток врядли пойдёт, так как после падения на диоде на шине остаётся 4,65в. Вот единственное отличие питания от батарей или USB. При USB на входе LDO стабилизатора LP3982 4.95, от батарей - 4.65. На линии 3.3в заметить изменение напряжения мне не удалось. мой тестер показывал 3.31в. Правда, есть нюанс. PCA9536 запитывается от 3.3в с платы EFM32, а TCS34725 - от платы ROMI. Замер напряжения R3V3 показал 3.29в. Неужели, эти 2 сотых вольта имеют значение?

Для проверки поставил еще одно гнездо с i2c на плате EFM32 - там питание для i2c берется тоже самое, что и у микроконтроллера с выхода LP3982. Хм, работает...

Теперь даже не знаю куда копать и что делать. Пока единственное, что могу обвинить, это level shifter на плате сенсора и более высокий уровень порога лог1 у EFM по сравнению с MSP432?

Re: RSLK от TI (Robotic System Learning Kit)

Сб окт 23, 2021 12:25:29

С сенсором TCS34725 пока поступил так: выпаял транзисторы level-shift-ера и заместо них запаял просто перемычки. Работоспособность шины i2c восстановлена. Клавиатура, во всяком случае работает без сбоев. А вот цвета распознать что-то не удаётся. Я, конечно, слегка повысил чувствительность, чтобы показания сенсоров были в районе тысяч, а не в пределах 10, как было изначально. Но если показания яркости хорошие, то показания насыщенности цвета - плохие. Ну и бывает так, что никаких показаний нет, если устройство питается от USB, когда подключено к компьютеру. Тут, снова проблема с питанием. У меня на линии R3v3 (последняя схема в предыдущем сообщении) напряжения нет, если не включены батарейки, а цветовой сенсор питается именно от этой линии. При подключении платы Launchpad - на этой линии через доп-разъём на эту шину подаётся 3.3в. Получается "в зад" обесточенной TLV1117, хотя логичнее было бы подавать на вход этой TLV1117 сразу после диода 5в от USB. Почему так не сделали - не понятно. Ну, да ладно - буду потом думать.

Зато продолжил запуск сенсора линии. Так как сигнал на фототранзисторе при выключении подсветки падает дольше, чем поднимается при включении (вернее наоборот, при выключении поднимается, а при включении падает), я решил сделать так, что первое измерение делается без подсветки, а второе с подсветкой. Всё это делает таймер:
Код:
  TIMER2->TOP = (REFL_PERIOD*50/8) - 1; // Period is 2.5ms

  TIMER2->CC[2].CTRL = TIMER_CC_CTRL_MODE_PWM | TIMER_CC_CTRL_PRSCONF_PULSE;
  TIMER2->CC[2].CCV = (REFL_PERIOD-200)*50 / 8;  // Считывание за 50 мкс до включения подсветки
  TIMER2->CC[0].CTRL = TIMER_CC_CTRL_MODE_PWM | TIMER_CC_CTRL_PRSCONF_LEVEL;
  TIMER2->CC[0].CCV = (REFL_PERIOD-150)*50 / 8;  // Подсветку включаем за 150 мкс до конца цикла
  TIMER2->CC[1].CTRL = TIMER_CC_CTRL_MODE_PWM | TIMER_CC_CTRL_PRSCONF_PULSE;
  TIMER2->CC[1].CCV = (REFL_PERIOD-50)*50 / 8;  // Считывание через 100 мкс после включения подсветки
                                                //  (и за 50 мкс до выключения)
Правда, поначалу у меня были всякие глюки. Так как оба считывания обслуживаются одной "загрузкой" DMA, у меня иногда менялись местами данные считанные без подсветки и с подсветкой. Иногда просто сдвигались на 3 позиции. Никак не мог понять в чем дело. Может, из-за того, что не был установлен приоритет обработки прерывания от DMA по окончанию трансфера? Но с момента окончания трансфера до следующего запроса на передачу данных почти 2 миллисекунды! Или может, это из-за того что приоритет DMA обслуживающего дисплей выше чем канал считывающий ADC? Но к тому времени, как я подготовил необходимый инструментарий для выявления проблемы, перепаял выводы в соответствии с порядком сканирования АЦП.... - проблема, похоже, исчезла. Приоритеты DMA я так и не изменил (хотя подготовил такую возможность), только установил приоритет прерывания 5 (пока самый низкий в системе) для LDMA.


Так вот, для чего всё это строилось? Это делалось для того, чтобы попытаться "вычитать" паразитную засветку. Сделал журналирование в течение 5 секунд (по 400 отсчетов в секунду = 2000 отсчетов) и провел утром, когда в окно светит солнце, эксперимент. Робота поставил на линию наискосок, чтобы разные сенсоры были в разных позициях от полностью над линией и полностью на белом фоне и "от солнца" закрыл ширмой. И включив тест плавно убрал ширму, чтобы паразитная засветка плавно нарастала. После чего слил показания и в экселе нарисовал график:
Изображение
Каждый отсчет расположен по оси X - показание без подсветки, по оси Y - с подсветкой. Собственно, получается что серии 1-4 - над черной линией, а 6-8 - над белым полем. 5 - промежуточное.

А вот теперь вопрос: как, зная "координаты" точки, решить - она над линией или нет?

Долго пялился на вышеприведённый график... С одной стороны, всё, что меньше 20 - вроде, явно на белом фоне. Но Серия "6" она тоже на белом фоне, но при отсутствии внешней паразитной засветки она превышает как отметку 20, так и 40 (самая верхняя отметка 171, 49). Поэтому, я провел две черты: горизонтальную по уровню 20 и "диагональную" через координаты (80, 0) (230, 120), получилось Y = 0.8*(x-80). И всё что выше этих обоих линий считать черным, всё остальное - белым. В программе, первую линию обозначил старым параметром Threshold, а вторую линию пока "захардкодил":
Код:
  unsigned int mask = 0x01;
  for (unsigned int ii = 0; ii < 8; ii++) {
      if (photo_array[ii+8] < (data.threshold >> 3)) current_sensor &=  ~mask;
      else  if ((photo_array[ii] > 100) && (((photo_array[ii]-80)*8ul/10) > photo_array[ii+8])) {
          current_sensor &= ~mask;
      } else {
          current_sensor |= mask;
      }
      mask <<= 1;
  }
photo_array с 0 до 7 - "темновые" отсчеты, а с 8 до 15 - с включенной подсветкой. current_sensor - байт с установленными битами соответсвующими сенсорам над черным полем.

Сегодня утром провел проверку на той же "мишени" на которой снимал графики - результатом доволен. Однако, вопрос, а как эти сенсоры будут вести себя на других мишенях? Нужно ли сделать настраиваемыми параметры "диагональной" границы?

Перед тем как прийти к этому решению, решил освежить информацию, которую видел на сайте micromouseonline.com. Правда, там это делалось для измерения расстояния до стены. И обнаружилось отличие - у меня фотосенсор находится в нижнем плече делителя, а там - в верхнем плече. И там влияние "засветки" вроде и не сильное. Как пишет автор: "засвечивание лампой 60W даёт ошибку от 1 до 3 мм". Так что, как пишет автор:
So, it should be possible to adjust for this at the contest. I am not sure if I will make the adjustment by changing the offset of the curve automatically or manually. This is an area I am way behind compared to other people since I have not had to deal with it before – all suggestions for what works and doesn’t work are greatly appreciated!


Так же, решил себе облегчить жизнь - сделал подачу 5в на TLV1117-33 со своей платы, если есть питание от USB разъёма дебаггера. Для этого добавил еще один разъём. и 5в подаю сразу на вход (после диода). До диода на линию 5в шасси Romi подавать нельзя. Так как у TPS568230 вроде есть такая фича, как закорачивание выхода при выключении и превышении выходного напряжения. Так что этим своим соединением, сделал так, что сенсор цвета теперь работает без батареек, но сенсор линии - нет (как и в случае с платой LaunchPad).

Re: RSLK от TI (Robotic System Learning Kit)

Вс дек 12, 2021 14:05:34

Вот так бывает... Мучаешься с сенсором, мучаешься, а он, оказывается просто неисправен. Это я про TCS34725. Помог случай. Как-то был разом включивши обоих роботов, на MSP432 и EFMGG12 и, вдруг, заметил, что светодиод подсветки цветового сенсора на одном светит ярко, а на втором, довольно тускло. Были там разные идеи насчет перепаять светодиод или еще что-нибудь. По схеме помню, что там стоял транзисторный ключ, который этот светодиод должен включать. Но тот вывод идущий на затвор, вроде, можно было оставлять в воздухе, так как на плате должна была быть подтяжка к + питания. И вот как-то включил я этот модуль и попробовал этот вход управления светодиодом пинцетом позамыкать на массу и на плюс питания. Замыкаю на массу - ничего не происходит - светодиод не погас. Начал сомневаться, а правильно ли я помню про эту подтяжку? Может, она не на плюс а на массу? Но смотрю старые фотографии - не вижу, чтобы у меня там был еще один провод. Да и схему модуля скачал - подтяжка точно к плюсу. Померял напряжение на затворе - 0.12в. Ну явно транзистор просто пробит. Выпаял я его и просто закоротил сток на массу. Теперь светодиод светит нормально. Даже задранную чувствительность вернул на место: время измерения 30мс и усиление 1х. А может, и транзисторы level-shift у меня тоже были пробиты?

Правда с распознованием цвета пришлось повозиться... Тут возникла идея сделать "баланс белого": поставил робота на белый лист бумаги и считал значения сенсоров. После чего "коэффициентами усиления" выровнял так, чтобы получились близкие значения. Правда, всё-равно, зелёный цвет никак не определялся. Но, покрутив в экселе цифрами, понял что просто надо изменить порог насыщенности цвета. Так как у меня, если насыщенность недостаточная возвращается черный или белый цвет, в зависимости от интенсивности. И вот установив следующие параметры получил нормальное определение красного и зеленого:
Код:
ColorRed      970
ColorGreen    1024
ColorBlue     1200
ColorThr      512
Saturation    900
Ура?

Помня про прочитанное о журналировании в SPI FRAM, летом был прикупивши по дешевке пару микросхем MR45V200A (256 кБ) в DIP корпусе. Одну распаял на макетку и снова попытался с ней поработать. И вот тут я не понял. По результату у меня получилось то же самое, что и год назад, когда я поключал EEPROM. Обмен сделал по прерыванию. И если год назад я столкнулся с потерей данных, то в этот раз - почему-то нет! Конечно, в этот раз я не пытался в прерывании организовать часть протокола обмена, а сделал просто 3 функции: начать запись/чтение, записать/прочитать кусок, завершить. И еще ни разу не получил флаг UCOR - переполнение чтения. Правда, за раз я больше килобайта не считывал.

Когда я первый раз просматривал информацию об SPI FRAM, вот только не помню какого производителя, там было написано, что при попытке записи в защищённую область, запись прекращается. Пытался вычитать в даташите про этот кристалл - что-то такого не нашел. Но провел эксперимент. Оказалось, защищенную от записи область он не испортил, но когда адреса "врапнулись" спокойно продолжил писать с нулевого адреса. А я та хотел разместить конфигурацию в "верхних" адресах, включить защиту и журнал писать с нулевого адреса. А когда дойдёт до защищенной области запись журнала автоматически завершится и не нужно контролировать объём записанных данных. Но, не повезло. Ага, нашел - эта фича была у инфинеоновских FRAM:
When a burst write reaches a protected block address, the automatic address increment stops and all the subsequent data bytes received for write will be ignored by the device.

Была еще мысль эту микросхему впаять взамен SPI EEPROM, но это мне пока не даёт никаких преимуществ. Во-первых у FRAM объём в два раза меньше, а во вторых, то журналирование, что сделано у меня, ориентировано на EEPROM и для FRAM не оптимально. Так что надо будет всё переделывать.

Поэтому, я пытаюсь сделать еще одно журналирование уже в FRAM. Собственно, эта мысль у меня уже давно крутится и хочу применить для Line Follower роботов, но это надо делать новую плату (а у меня еще эта плата ни в одних соревнованиях не поучавствовала!). Мысль состоит в том, чтобы соединить BGM модуль с микроконтроллером через SPI и пусть микроконтроллер с некоторым интервалом некий объём характерных переменных шлёт в BlueTooth модуль. А дальше, я эти данные уже могу получать через bluetooth в свой пульт управления по выбору. И вот точно также эту информацию таким же образом хочу заливать в FRAM. Пока проблема в том, что эти данные раскиданы по разным программным модулям и не могу решить, сделать одну структуру, которой будут пользоваться модули или для журналирования "собирать" данные в одну кучу для отправки.

Еще начитавшись micromouseonline.com тоже решил попробовать GIT-Hub и выложил проект своего робота в публичный доступ. Кто хочет - пользуйтесь. Попутно посмотрел, и оказалось, что на git-hub-е уже есть несколько проектов посвященных RSLK. Пока из всех меня заинтересовал проект балансирующего робота. Надо будет, как-нибудь попробовать его.

Re: RSLK от TI (Robotic System Learning Kit)

Сб янв 01, 2022 18:54:12

Хм. как-то новый год пришел незаметно... Посмотрим, что получится.

Я тут сделал журналирование в SPI FRAM. И встал вопрос, а что туда зажурналить? Ну, у меня наблюдалась пара проблем. проблема один: питание. Уже писал, что у меня батареи АЦП постоянно считывает и эта информация постоянно есть в памяти. А так же, в АЦП запрограммировано так, что если отсчет напряжения питания оказывается вне заданного окна выставляется флаг. Этот флаг при отображении напряжения считывается и если он был установлен, то выдаётся на дисплей надпись "Battery Low". Так вот у меня эта надпись повлялась практически постоянно, когда бы я у робота не смотрел состояние батареи. И в какой-то момент заметил, что эта надпись появляется, когда я робота ложу просто на стол. Начал проверять - да, достаточно слегка стунуть роботом о что-то твёрдое, как выскакивает эта надпись. Причиной такого поведения оказалось то, что у батарей пропадал контакт, потому как батареи могли слегка "шевелиться" в батарейном отсеке. Поэтому я на крышку наклеил "уплотнитеть" - мягкий скотч, чтобы при надетой крышке батареи прижимались крепче к днищу отсека и не могли свободно двигаться.
Изображение

Это устранило появление сообщения при "постукивании" роботом поверхности стола, но после заезда по лабиринту надпись всё-равно появлялась. Кстати, нижний порог я поставил 6.3в. Поэтому решил журналировать напряжение питания и параметры скорости: задаваемая, реальная и состояние одометра для левого и правого колеса. Хм... вот тут всплыла куча проблем.

для иллюстрации фрагмент движения робота между двумя поворотами. Т.е поворот вправо, движение по сегменту и снова поворот вправо и следующий сегмент
Изображение
Верхний график - напряжение батареи, нижний задаваемая (синяя линия) и реальная (красная линия) скорость левого мотора. Примерно можно заметить, что провал напряжения происходит в конце поворота, когда робот должен закончить поворот и перейти к прямолинейному движению по сегменту. Когда я делал "плавный разгон и торможение" при выполнении поворота, поначалу был сделавши 45 градусов разгон, 45 градусов (или сколько там осталось) торможение. Но мне этот режим показался "вялым" и я переместил точку торможения на 60 градусов. Результат виден на графике - к концу торможения скорость на успевает опуститься даже до 100 rpm, как моторам устанавливается нулевая скорость и происходит довольно сильное торможение, подачей противоположной полярности, из-за чего видно, что мотор какое-то время крутится даже в обратную сторону. Хм, не знаю даже, как на такой перегруз будут реагировать щетки двигателей. С одной стороны такая "резвость" при повороте меня устраивает...

Еще один момент - на графике помечен стрелочкой вниз. Внезапно, в конце сегмента двигателю даётся команда не только снизить обороты, но и реверсировать двигатель. Это сделал ПИД, удерживающий робота на линии. Получив от сенсоров данные он и дал такую команду. А данные следующие:
Изображение
Робот начал видеть левую ветвь (это красные квадратики справа) Т-образного перекрёстка, поэтому "центр" линии сместился и ПИД пытается робота "поставить на место". Вообще-то, надо бы как-то это дело отфильтровать, но пока не могу придумать как. В принципе, тут тоже работает "фильтр". Чтобы принять решение об окончании сегмента и начале перекрёстка, должны быть подряд два считывания с активными боковыми сенсорами. Когда начался режим прохода перекрёстка можно увидеть по задаваемой скорости 6000 - по перекрёстку робот идёт просто так без ПИД регулировки.

Были еще одна проблема - в некоторых случаях робот по перекрёстку шел не на скорости 60 rpm, а "делал рывок". На графике я нашел, что задавалась скорость 120 rpm, нашел в коде место где это проскакивало и устранил. Но возникла другая проблема. При быстром проходе по "решенному" лабиринту (у меня два режима: исследование лабиринта, когда робот движется со скорость 60 rpm и решение лабиринта, когда робот идёт на максимально возможной скорости) робот "вылетал" на перекрёстках так, что терял ориентацию. Для устранения этого сначала увеличил значение "тормозного пути" - расстояние до конца сегмента, когда роботу пора начинать тормозить. Но это вызвало то, что при проходе сегмента на малой скорости делало торможение слишком за рано. И тут я решил отказаться от задания длины тормозного пути и перейти к вычислению его исходя из максимальной скорости.

Т.е. если задано, что скорость по сегменту максимальная - 160 rpm, то по формуле (Vm^2 - Vk^2)/2a - получаем расстояние, сколько будет робот с ускорением a сбавлять скорость с Vm (160rpm) до скорости на которой проходим перекрёсток Vk (60 rpm). Правда есть одна проблема, если робот не успеет к "этому месту" набрать эту максимальную скорость, то получится что робот слишком рано сбавит скорость и будет ползти оставшийся участок на пониженной. А вот как вычислить, где в таком случае должна быть точка перегиба? Я эту задачку еще, хоть она и для шестого класса школы, еще не решил. Собственно, вот график полного прохода робота при "решении" лабиринта от начала до конца:
Изображение
Можно заметить, что в первом и втором сегментах не набирается максимальная скорость и до конца сегмента (можно видеть по характерному "выбросу") робот тащится на малой скорости.

Еще добавлю. То что "графики" очень иззубренные - это из-за того, что ПИД постоянно корректирует положение робота: одно колесо крутит быстрее, второе - медленнее. Но суммарная скорость боле-менее константная. Вот график со среднеарифметической задаваемой и реальной скоростью:
Изображение
Можно видеть, что задаваемая скорость практически линейная. "Провалы" есть только в тех местах, где отклонение от линии превысило некий порог и из-за этого для выполнения коррекции скорость должна была упасть. Но меня беспокоят "провалы" и "всплески" реальной скорости. Я несколько мест отметил зелеными стрелочками. Собственно, это всё еще та же проблема, с которой я столкнулся год назад. Это неправильные данные с правого мотора. Вот фрагмент чистых данных с журнала:
Код:
Время          напряж.   задаваемая       реальная        одометр
Время                   левый правый   левый правый    левый правый
6035       #      67   15266   16000   13923   15030   8936   9467   15633   14477
6040       #      69   15266   16000   14581   15648   8938   9469   15633   15115
6045       #      70   15266   16000   14581   15648   8940   9471   15633   15115
6050       #      69   15266   16000   14209   -16871   8942   9473   15633   -1331
6055       #      67   15266   16000   14209   -16871   8944   9475   15633   -1331
6060       #      68   15266   16000   14893   18475   8947   9478   15633   16684
6065       #      70   15266   16000   14893   18475   8949   9480   15633   16684
6070       #      70   15266   16000   14587   16370   8951   9482   15633   15479
Видно, что внезапно реальная скорость правого мотора стала отрицательной. Точно такие же изменения данных и в других подобных местах. При этом, если посмотреть на столбик одометра - там шаги нормально увеличиваются.

Попробовал решить задачку шестиклассника. Вроде, даже что-то получилось. Если кому не лень - проверьте, не накосячил ли? Ой, там в формулах Vf = Vk - это конечная скорость на участке, Vs - стартовая, a - ускорение, Vm - максимальная. Ну и длина участка S состоит из двух частей: разгона Ss и торможения Sf
Сначала выводим максимальную скорость на участке:
Изображение
Тут максимальную скорость подставляем в формулу длины тормозного участка:
Изображение
Простой контрольный выстрел: если начальная и конечная скорости равны, то точка перегиба должна быть ровно по середине
Код:
Sf = 2aS/4a = S/2

Re: RSLK от TI (Robotic System Learning Kit)

Сб янв 15, 2022 19:32:36

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

хм, оказывается, этот сторонний ресурс картинки формул не хранит. Хорошо, придётся их сюда перетаскивать.

Попробовал погонять робота с реализованными этими затеями - вроде, движется нормально. Более глубокий анализ пока не делал, так как считать данные, загрузить в excel и сделать визуализацию - много времени требует. Хотя, я еще нашел что можно улучшить. Сделал работу с картой, таким образом, что в режиме решения лабиринта, робот "сверяется" с картой и если найденный узел совпадает с тем, что есть на карте - используются данные карты. Хотел сделать, чтобы при обратном проходе робот мог использовать известные длины сегментов и проходить их на повышенной скорости - пока не получилось. Я там с одной переменной слишком вольно обращаюсь - надо бы привести в порядок...

С другой стороны, хотел сделать "соревновательным" роботом робота на EFM32, из-за того, что на нём сенсоры линии имеют вычитание паразитной засветки. Но у этого робота больше нет контактов чтобы подключить FRAM, BGX. За эти две недели задействовал последний контакт для ввода напряжения батареи на АЦП - теперь и на этом роботе вижу состояние батарей. Была мысль сделать свою платку... Но рынок лихорадит и нет возможности купить что хочешь. Например на фарнеле в данные момент в наличии из EFM32GG* есть только efm32gg510 в qfp64. Маузер efm32 мне не продаёт. Говорит:"This product may require additional documentation to export from the United States". Я тут перед новым годом сломал свой JLink - наступил ногой нечаянно. Так вот его маузер мне продавать отказался. Говорит "restricted". Хотя класс из 12 таких - бери, ограничений нет. Пришлось делать заказ на фарнеле. Знакомому этот же маузер перед новым годом на попытку купить 90 каких-то ширпотребных транзисторов сказал: "в одни руки не более 60 транзисторов в месяц! Следующие вы сможете купить после (указанной даты)". Так вот если делать свою плату - надо бы мост USB-Serial и я заложился на CP2102, а их на фарнеле не было. Вот у меня и не комплект.

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

Был купивши на Aliexpress пару моторчиков с оптическим энкодером - 30 импульсов на оборот. Но они довольно медленные. Вот снял его характеристики на холостом ходу:
3в - 750 имп/с = 25 об/с = 1500 rpm
4в - 1150
5в - 1500
6в - 1870
7в - 2190
8в - 2550
9в - 2910
10в- 3250
Пока не могу представить, какой ему редуктор и на какие колёса делать. И от скольки вольт его питать. Продавец его называл "6-12volt". Хочу попробовать сделать "тележку" - 4 колеса (по 2 с каждой стороны) и через шестерёнки их соединить с двигателем. Допустим, колесо будет диаметром 32мм (я думаю надеть pololoвскую покрышку). И если использовать шестерёнки с модулем 1, то на колёсах могут стоять шестерёнки с меньшим числом зубьев чем диаметр колеса. Скажем, 28. Тогда "приводная" шестерёнка должна иметь большее число зубьев, чем расстояние между этими шестерёнками. Скажем два колеса по 32мм и 1мм зазор между ними. тогда между 28 зубыми шестерёнками будет 4+4+1 = 9мм. Т.е. на мотор надо ставить минимум 10 зубую шестерёнку. Т.е. самый большой коэффициент редукции при одном переносе получается чуть меньше 3. И вот исходя из этих данных надо придумать, какую маршевую скорость роботу запланировать. И хватит ли ему сил с этой скоростью бегать.

Собственно, идея, куда двигаться, у меня внезапно появилась. Так как у нас соревнований не было уже больше года, дёрнуло меня поинтересоваться, а что там с Robotex? Оказалось, что несмотря на короновирусные ограничения, он состоялся 5-7 ноября. Конечно, чтобы участвовать надо 50€ + НДС и ещё примерно столько же обойдётся топливо чтобы съедить туда и обратно. Без учета гостиницы и питания. А еще и вакцинироваться надо, чтобы по приезду не сидеть 10 дней в изоляции. Ну и надо сделать робота для таких соревнований. А значит надо делать полигон. И сделать решение еще и такого лабиринта. Теперешние решения для этих соревнований не годятся, так как в наших соревнованиях выход может быть где угодно, а тут, вроде, точно определено - в центре. Поэтому, надо бы подогнать алгоритм так, чтобы он целенаправленно двигался к центру. Хотел просмотреть запись трансляции, но она начинается с награждения победителей лабиринта - т.е. сами соревнования в запись не попали. Да и на видео соревнований folkrace часть лабиринта (они расположены рядом) видна и я её срисовал, но это только половина - вторую половину я так и не увидел.

Re: RSLK от TI (Robotic System Learning Kit)

Сб фев 19, 2022 18:26:58

Надо начинать с чтения правил соревнований. Там указано, что старт находится в углу из которого есть только одно направление (но не указано, как в правилах других соревнований, что это всегда нижний левый угол!) и финиш находится в центре.
The start of the maze is located at one of the four corners. The start square is
bounded on three sides by walls. The start line is located between the first and
second squares. The destination goal is the four 18 cm × 18 cm cells at the centre of
the maze. The finish line is at the entrance to the destination square.
Конечно, то что финиш находится строго в центре, облегчает жизнь, но если правила изменятся? В других соревнованиях финиш обозначается только как 4 клеточки в любом месте лабиринта и на одних соревнованиях (кажется, в японии) даже имел 2 входа! Пока я не придумал способа, как определить что найден финиш в таком "общем" случае. Пока финиш определяется просто: если координата стала X=(7 или 8) и Y=(7 или 8) , то первое совпадение и является финишной точкой.

Стремление к выходу тоже пока сделал тривиально: на развилках измеряется расстояние от клеточек за развилкой до центра, как ΔX² + ΔY² и выбирается направление с меньшим значением. Но если значения равны, только тогда действуют другие установки. Правда, как мне показалось, это не очень хорошо - очень быстро найти выход. Потому как надо найти оптимальнейший маршрут. А тут моя затея сгенерить маршрут по открытому лабринту и ехать проверять, можно ли там реально проехать, оказалось совершенно неприемлемой. Это хорошо работало на лабиринтах с "бутылочным горлышком", но на квадратном показало полную нерациональность - робот постоянно бегал из одного конца лабиринта к другому, вместо того, чтобы проверить один участок и только тогда перейти к другому. Поэтому я этот модуль отключил.

Зато развил модуль предсказаний и возврата по пройденному маршруту. В предсказания добавил возможность избегать тупики. Если по данным исследования соседних ячеек известно, что впереди будут ячейки с двумя стенами и в конце с тремя стенами (тупик), то весь этот ход объявляется тупиком и робот туда суваться не будет. Вот для примера:
Изображение Изображение
Справа исходный лабиринт, слева как его будет видеть робот после исследования.
Желтыми цифрами отмечены ячейки куда робот не заходил благодаря этому модулю прогнозирования тупиков. Примечателен тупик "2" - нам не интересно как далеко туда можно пройти, так как всё-равно окажемся в тупике. Тупик под номером 5 (для меня) интересен тем, что он был заблокирован при виртуальном движении назад. Когда робот первый раз подошел к той развилке, наличие стены в конце ячейки не было известно и при возвращении его следовало бы посетить, но когда робот начал возвращаться - наличие стены у той ячейки стало известно и путь назад расчитывался уже зная что там тупик и не посещая ту развилку второй раз. Это сэкономило очень длинный кусок хода назад! Оранжевыми цифрами отмечены ячейки которые не посещались, так как по алгоритму Люка-Тремо нужно было бы вернуться. И если кусок "8" был сделан давно (явный прямой ход без вариантов), то я еще добавил обработку и поворотов, за счет чего появилась блокировка "3", "4" и "7". Кстати, тут нет такой ситуации, но "изогнутые" тупики также обрабатываются. Ну а участок "9" не посещался, так как к моменту, когда его следовало бы посетить, алгоритм нашел, что он уже ни на что не влияет.

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

Хм, а что делать когда он прибежит к старту? Снова правила:
The contestants are allowed to:
 change switch positions;
 adjust sensors;
 make repairs in case the Micromouse breaks down.
Вопрос, насколько широко это можно трактовать. Можно ли подключать конфигурационный дисплей? или это нарушение пункта, что "The Micromouse shall be self-contained"? или так как он отключаемый, то нарушается пункт, что "The Micromouse shall not leave any part of its body behind". Про работу через блютус, похоже речь не идёт - явно указано - "no remote control". Правда, полагаю, что за телеметрию бить не будут. Хотя кто знает. Ну по крайней мере, один переключатель надо поставить, для указания с какого угла лабиринта я стартую (вернее указатель направления север или восток, так как стартовая координата в любом случае [0:0].

В общем, на крыльях идеи сделать робота с минималистичным управлением, решил вернуться к давней идее, как переделать робота на PSoC5 для linefollower в решателя лабиринта. Моторы с энкодерами у него есть, фотосенсоры - тоже. Нужен еще сенсор цвета и немножко энергонезависимой памяти - набортного 1K EEPROM маловато для моих аппетитов. В общем, так как память и сенсор цвета - оба работают через i2c - я их и посадил на разъем для i2c и оставил возможность туда же подключать дисплей с кнопками:
Изображение Изображение Изображение
Это вид робота без источника питания
Изображение

Re: RSLK от TI (Robotic System Learning Kit)

Вс мар 27, 2022 11:57:02

Тут еще по поводу правил соревнований: душещипательная история как китайская команда не получила первое место на TechFest 2018 из-за особенностей местных правил соревнований (правда, год спустя в UK всё же изменили правила ближе к международным). Так что правила нужно изучать внимательно.

Занялся подготовкой модулей нового робота (фото в предыдущем сообщении). Так как этот робот собран на базе linefollower, который у меня уже бегает, то использовал как основу тот же проект. Различие только в двигателях. У linefollower двигатели с редуктором 1:10, а у этого поставил чуть помедленнее - 1:30. Первое чем занялся - ПИД моторов. Пока решил, в качестве параметров как и в RSLK задавать обороты колеса в 0.01 rpm. Правда, это создало мне проблему с модудем конфигурирования. Так как обороты колеса достигают 1200 rpm, то для задания максимальной скорости (120000) мне 5 цифр уже не хватает, поэтому пришлось корректировать программу ввода, чтобы оперировать шестиразрядными числами.

Следом всплыла еще проблема. Люди ленивы и code reusing используется повсеместно. Собственно язык C так и позиционируется, как переносимый между платформами. Поэтому я для ПИД мотора использовал код от RSLK. Конечно, подвергая его небольшой ревизии. И тут, я выясняю, что у меня в ПИД контроллер моторов передаётся усреднённое значение периода импульсов с таходатчика. Хотя, я точно помню, что как-то пытался делать усреднение и получил плохую стабилизацию оборотов и там я был отказавшись от усреднения. Поэтому пошел и в RSLK роботе убрал усреднение периодов. Робот стал неуправляемым - по трассе пройти вообще не мог. Пришлось всё вернуть на место. Как у меня было сделано усреднение? Когда датчик холла фиксирует фронт, происходит в таймере захват значения таймера, и факт захвата вызывает прерывание. В прерывании рассчитывается интервал между захваченным сейчас значением и захваченным в предыдущий раз и результат записывается в переменную хранящую период. При этом проверяется, считал ли кто-нибудь предыдущее значение. Если считывания не было, то вычисляется среднее арифметическое из всех не считанных занчений и записывается в переменную хранящую период. Пока считываением периода занимется только один процесс - ПИД контроллер мотора - проблем, вроде нет. Но тут я решил отвязаться от факта считывания, а делать просто усреднение нескольких последних отсчетов. Что-то типа LPF, только частота среза у него зависит от оборотов двигателя. Пустил робота - он поехал, но уж очень странно - скорость его колёс постоянно менялась. Хотя линию пытался удержать. Ну так как я уже имел небольшой опыт, подумал, что виной такого поведения является возбуждение ПИД контроллера, поэтому снизил коэффициент интегральной составляющей в два раза и всё нормализовалось. Хм, может, когда у пробовал убрать усреднение надо было тоже покрутить коэфиициенты, только в большую сторону? Но пока оставлю так.

Когда слегка разобрался с ПИД, решил проверить работу модуля измеряющего расстояние и направление вращения. И тут оказалось, что при движении робота вперед, робот считает назад. Ну, вроде мелочь, поменяем фазы энкодеров. Поменял назначение выводов микроконтроллером местами скомпилировал, загрузил - всё нормально. А вот направление вращения теперь показывает неправильно - пришлось входы триггера тоже поменять местами. Но простите, я же брал за основу готовый проект от linefollower! Может там тоже расстояние считается не правильно? Или это различие в редукторах двигателя. Когда я рассматривал возможность прикупить на pololu.com робота 3Pi+, там были 3 модификации с разными редукторами: 1:75, 1:30 и 1:15. Так вот про последний было написано, что у него направление вращения колёс противоположное по сравнению другими. Но я нигде не нашел в какой-нибудь сводной таблице такой информации. Конечно, может оказаться, что я просто двигатели припаял в другой полярности, но по внешним признакам этого не наблюдаю. И даже рассматривая редуктор, похоже, что у 1:30 и 1:10 вращаются в одинаковую сторону. В общем, требуется еще и ревизия linefollower робота.

Теперь, когда могу управлять моторами, надо бы начать двигаться. Но двигаться так как у меня двигается RSLK мне не хочется. Там код довольно-таки прямолинейный - логика верхнего уровня перемешана с низкоуровневыми операциями, которые еще и повторяются. А вот у других, я нашел, что есть специальный motion controller. Например, у робота Primus5 это функция profiler(). Верхний уровень создаёт очередь заданий типа 3 клеточки вперёд, 90 градусов вправо, 5 клеточек вперед итд, а этот profiler его исполняет. Исходники можно найти там: https://micromouseonline.com/2007/12/04 ... nd-moving/ Правда, я не разобрался как этот profiler взаимодействует с верхним уровнем, которого там в исходниках, разумеется, нет. Но начал пытаться рисовать. Нарисовал работу с очередью команд и начал писать исполнение. Сначала взялся за прямолинейные участки. И сделал так, что робот считав команду двигаться прямо с ожидаемым расстоянием считывает и следующую команду. И если следующая тоже двигаться прямо, то позиция начала торможения расчитывается уже из суммы этих двух (или сколько там окажется) кусков. Пока всё было красиво. Но у меня прямолинейное движение по сегменту состоит из трёх этапов. Первый этап, робот стоит так, что центр тяжести (ЦТ) находится над перекрёстком и движется вперед пока не заметит следующий. Тогда начинается второй этап - распознование конфигурации следующего перекрёстка. По окончании этого этапа, следовало бы как-то сообщить верхнему уровню информацию о конфигурации перекрёстка и или длину сегмента, что только что проехали или координаты узла. Ну и проблема с третьим этапом - выравнивание. Так как сенсор стоит на удалении от ЦТ, необходимо проехать вперед, чтобы ЦТ встал над центром перекрёстка и можно было бы выполнять следующую команду. Но тут есть неопределёность. Если следующая команда известна и является движением прямо, то скорость сбавлять нет надобности, если же следующая команда поворот, то надо тормозить, чтобы робот остановился над перекрёстком. А если происходит изучение лабиринта? В общем случае получится движение рывками как на видео в конце этого сообщения. Сейчас, мой RSLK робот идёт гораздо ровнее. Но это за счет того, что после получения конфигурации перекрёстка сразу происходит принятие решения и робот не сбавляет скорость, если принято решение двигаться прямо. Но вот как это дело организовать, если законодательная власть работает совершенно независимо от исполнительной? Поэтому я сейчас застрял.

Пока нахожусь в ступоре, ко мне приехал OLED дисплейчик с разрешаловкой 128*128. Правда RGB. И я попытался его оживить. Конечно пришлось здорово повозиться, но картинки показывать я его заставил:
Изображение
На таком дисплее лабиринт отображается куда внятнее. Но вот только пока еще не решил на какой робот его прикручивать. Да и есть проблемы - надо будет переписывать весь вывод. Сейчас у меня всё изображение формируется в ОЗУ и потом весь кадр заливается в дисплей. Здесь я так поступить не могу, так весь экран занимает 32 килобайта, а у MSP432 DMA может за раз переслать всего 1 килобайт. Можно было бы его поставить на робот с EFM32 - там есть 2D трансфер, но у этого дисплея надо чтобы команда передавалась с низким уровнем на выводе DC, а параметры команды с высоким (в отличии от SSD1306, у которой команда и параметры передаются с одинаковым уровнем). Поэтому передача данных там довольно муторное дело. Надо было покупать не RGB, а Ч/Б дисплей на SSD1327. Но они почему-то дороже этого цветного...

Re: RSLK от TI (Robotic System Learning Kit)

Вс май 08, 2022 14:42:45

Время летит вперед и до 25 ноября остаётся всего полгода. Это дата следующих соревнований Robotex в этом году (25-26 ноября). Может, надо попробовать успеть, хотя, ничего еще не начато. Но пока это время трачу на отработку различных узлов. Собственно, планирую делать всё-же классический вариант. Моторы micrometal gear 1:30 с моими силиконовыми колёсами и передним опорным шариком и 3 пары оптических дальномерных сенсоров для определения расстояния до боковых стен, фронтальной стены и боковых впереди. В принципе, получится тот-же самый робот, что сейчас для лабиринта из линий, только вместо 8 сенсоров линии будет 6 дальномеров. Микроконтроллер будет силиконлабовский EFM32GG12.

Мне очень нравится этот микроконтроллер. Особенно, после того как до меня дошло, как можно применять его Linked DMA. Оказалось, это очень мощная штука. Особенно, с учетом того, что можно добавить дескрипторы прямой записи. Например, так как у меня через SPI работает и дисплей, и EEPROM, мне при переходе с одного на другой надо менять роутинг вывода CS SPI. И оказалось, что это можно заставить делать DMA самостоятельно. Просто перед трансфером добавляется прямая запись в регистры USART3->ROUTELOC0:
Код:
  EEdescLinktx[1] = (LDMA_Descriptor_t)LDMA_DESCRIPTOR_LINKREL_WRITE(USART_ROUTELOC0_CLKLOC_LOC0 | USART_ROUTELOC0_CSLOC_LOC1 |
                                                                     USART_ROUTELOC0_RXLOC_LOC0 | USART_ROUTELOC0_TXLOC_LOC0,
                                                                     &USART3->ROUTELOC0, 1);
  EEdescLinktx[2] = (LDMA_Descriptor_t)LDMA_DESCRIPTOR_LINKREL_WRITE(USART_CMD_RXEN | USART_CMD_CLEARRX, &USART3->CMD, 1);
  EEdescLinktx[3] = (LDMA_Descriptor_t)LDMA_DESCRIPTOR_LINKREL_M2P_BYTE(cmd_ptr, &USART3->TXDATA, cmd_count, 1);
  EEdescLinktx[4] = (LDMA_Descriptor_t)LDMA_DESCRIPTOR_SINGLE_M2P_BYTE(send_data_ptr, &USART3->TXDATA, count);
Вот обращение для передачи данных в EEPROM. Делаем две записи в конфигурацию USART3, передаём 4 байта команды и данные. Тут еще больше! Так как ресурс разделённый, то надо использовать флаги, чтобы пока идёт один трансфер не начался бы другой, поэтому по окончании трансфера необходимо сбросить флаг занятости. Обычно в простых DMA это делается в прерывании по окончанию трансфера, но тут этим можно озаботить сам DMA.
Код:
  EEdescLinkrx[0] = (LDMA_Descriptor_t)LDMA_DESCRIPTOR_LINKREL_P2M_BYTE(&USART3->RXDATA, cmd_ptr, cmd_count, 1);
  EEdescLinkrx[1] = (LDMA_Descriptor_t)LDMA_DESCRIPTOR_LINKREL_P2M_BYTE(&USART3->RXDATA, send_data_ptr, count, 1);
  EEdescLinkrx[2] = (LDMA_Descriptor_t)LDMA_DESCRIPTOR_SINGLE_WRITE(0, &tx_busy);
Как только все данные из EEPROM придут, в переменную tx_busy будет записан ноль.

Так более того. Этим способом, возможно переключать сигнал Data/Command# OLED дисплея. И при этом не сидеть в пустом цикле ожидая окончания передачи первой части данных (команды дисплея). Для этого там есть еще и дескриптор синхронизации. Вот дескрипторы для полного обновления экрана OLED: надо послать команду, переключить сигнал D/C# и послать 1024 байт данных:

Код:
LDMA_Descriptor_t tx_descriptor[] = {
    LDMA_DESCRIPTOR_LINKREL_SYNC(0, 0x80, 0x00, 0x00, 1),
    LDMA_DESCRIPTOR_LINKREL_WRITE(USART_CMD_RXDIS, &USART3->CMD, 1),
    LDMA_DESCRIPTOR_LINKREL_WRITE(USART_ROUTELOC0_CLKLOC_LOC0 | USART_ROUTELOC0_CSLOC_LOC0 |
                                  USART_ROUTELOC0_RXLOC_LOC0 | USART_ROUTELOC0_TXLOC_LOC0,
                                  &USART3->ROUTELOC0, 1),
    LDMA_DESCRIPTOR_LINKREL_WRITE(0, &GPIO->P[gpioPortA].DOUT, 1),
    LDMA_DESCRIPTOR_LINKREL_M2P_BYTE(start_col, &USART3->TXDATA, sizeof(start_col), 1),
    LDMA_DESCRIPTOR_LINKREL_SYNC(0, 0x80, 0x80, 0x80, 1),
    LDMA_DESCRIPTOR_LINKREL_WRITE(USART_CMD_RXDIS, &USART3->CMD, 1),
    LDMA_DESCRIPTOR_LINKREL_WRITE(USART_ROUTELOC0_CLKLOC_LOC0 | USART_ROUTELOC0_CSLOC_LOC0 |
                                  USART_ROUTELOC0_RXLOC_LOC0 | USART_ROUTELOC0_TXLOC_LOC0,
                                  &USART3->ROUTELOC0, 1),
    LDMA_DESCRIPTOR_LINKREL_WRITE(0, &GPIO->P[gpioPortA].DOUT, 1),
    LDMA_DESCRIPTOR_LINKREL_M2P_BYTE(buffer, &USART3->TXDATA, sizeof(buffer), 1),
    LDMA_DESCRIPTOR_SINGLE_WRITE(0, &tx_busy)
};
Первый SYNC сбрасывает оставшийся от предыдущих трансферов флаг синхронизации. Далее конфигурируется SPI, устанавливается вывод порта A и производится первый трансфер, затем ожидается появление флага синхронизации, делается следующая запись в порт A и передаются данные. Ну и по завершении сбрасывается флаг занятости ресурса tx_busy. Флаг синхронизации устанавливает прерывание SPI "transfer complete":
Код:
void USART3_TX_IRQHandler(void) {
  if(USART3->IF & USART_IF_TXC) {
      USART3->IFC = USART_IFC_TXC;
      BUS_RegMaskedSet(&LDMA->SYNC, 0x80);
  }
}
Правда, в референс мануале про эту синхронизацию написано мутно и несколько недостоверно. Вернее, там наверное еще должны быть кой-какие само-собой подразумевающиеся вещи, но с точки зрения формальной логики там дана противоречивая информация.

То что в дескрипторе в порт A пишется в обоих случаях 0 - это просто заготовка. В функции запускающей этот трансфер в те места прописываются нужные значения. Дело в том, что DMA не может изменить один бит порта, так как области памяти BITBAND, SET и CLEAR для DMA недоступны. Но так как у меня на этом порту еще сидят 3 светодиода, сигнал Reset дисплея, о, и еще подключение USART-USB_CDC (PA15), приходится комбинировать эти данные. Все биты, кроме состояния светодиодов, заранее дефинированы и проблем не вызывают. Со светодиодами может случиться так, что если я их во время первого трансфера поменяю, то при начале второго трансфера они вернутся в исходное состояние - но с этим придётся смириться, тем более, что это просто вспомогательная индикация и на основной функционал не влияет.

Ну вот, после того как у меня улучшилось настроение, когда сделал такое улучшение в работе SPI через DMA, занялся контроллером движения. У меня сейчас 3 робота: два на шасси ROMI (классический RSLK с MSP432 и с EFM32GG12) и на PSoC5. Так как первые два в массогабаритном плане одинаковые, то разработку начал на EFM32 используя параметры зависимые от механики из RSLK. А после, уже готовый код переносил на PSoC5, только изменяя те же параметры связанные с механикой. Не обошлось без курьёзов. В какой-то момент времени мне взбрело в голову, что робот идя по линии не должен реверсировать моторы, потому ограничил минимальные обороты двигателя. Результатом стало то, что робот не успевал после поворота выровняться на линии достаточно быстро, как заканчивался "защитный" промежуток и робот вдруг ложно опознавал следующий "узел". Когда я добился того, что робот начал стабильно выполнять заданный маршрут:
начал перенос этого кода на PSoC5. И тут возник облом. Я решил задавать скорость аналогично, как на роботах с шасси ROMI в 0,01 rpm... А так как у меня робот может бежать со скоростью выше чем 1200rpm, то я мог бы задавать скорость 120000. Но при вычислении позиции с которой надо тормозить мне нужно считать разницу квадратов скоростей. А 120000 в квадрате уже вылазит за 32 бита. Поэтому пришлось урезать осетра и скорость задавать в 0,1rpm.

Когда и этот робот начал выполнять вышезаданный маршрут, возник вопрос о передаче данных верхнему уровню. Ну я там сделал набор переменных с флагом и когда данные есть флаг взводится и основная программа заметив взведённый флаг считывала проеханное расстояние и конфигурацию обнаруженного перекрёстка. С расстоянием возникла проблема. Второй прямой сегмент всегда был на "дюйм" длиннее. Собственно, такая же проблема есть и у моего классического RSLK. Это связано с моментом, когда и где ставятся "вешки" по которым измеряется расстояние. Немного унифицировав это дело, получил довольно неплохую точность в пределах 5мм. правда, я не учитываю еще ширину самой линии (15мм).

Теперь, когда есть движение, начал писать решение лабиринта. И снова, взял код с RSLK и повыкидывал все относящееся к движению и заменил на вызовы функции загружающие в очередь команды. После того как получил проход по лабиринту аналогчный RSLK (и даже лучше - по уже известным сегментам робот стал ходить в ускоренном режиме), решил добавить возможность срезать маршрут.
Изображение
Вот для примера простая петля. робот следуя из узла 1 в 2 видит развилку и выбирает, например, движение прямо. Далее следует по узлам 3-4-5 и снова оказывается у узла 2. По алгоритму люка-тремо, робот должен видя перед собой узел который однажды пересечен развернуться и ехать назад. Это показывает красная линия. Оказавшись снова у узла 2 - он уже не будет "однажды пересеченный", так как мы там уже побывали 2 раза. поэтому надо выбрать или проход, куда мы еще ни разу не ходили, или если такого нет, туда где были один раз. У нас есть проход в сторону узла 6 поэтому нам надо свернуть в ту сторону. Но, мы оказались там, где уже были и весь путь помеченный красным совершенно излишний. Поэтому, я хочу чтобы робот этот момент выполнял оптимальнее. Ну в таком тривиальном случае видно, что надо просто ничего не делать, а двигаться прямо. Но, если, допустим, другой вариант:
Изображение
В этом случае видно, что вместо того, чтобы разворачиваться и обходить "квадрат" по трём сторонам, оптимальнее повернуть налево и пройти только одну сторону. Вот с этими ситуациями и пытается работать мой алгоритм: вычисляет до куда надо вернуться и вычисляет кратчайший маршрут до той точки и перемещает робота туда. Одна из главных проблем была в том, что маршрут я составить то могу и передать на исполнение, тоже могу. Но как я буду знать, что он выполнен? Выполнен успешно? И вообще, где я нахожусь? Пришлось, конечно, помучаться, пока не удалось эти процессы интегрировать друг в друга. Пока есть уже рабочий код, который с моим домашним лабиринтом (из 9 узлов) вполне справляется заезжая с любого из трёх входов. Вот только хотелось бы еще сделать виртуальный "движок", чтобы посмотреть, как этот алгоритм работает на более сложных лабиринтах.

И хотя, тут почти всё идеально - контроль движения работает исключительно по прерываниям, "верхний" уровень сделан так, что его можно интегрировать в силабовский app.c, т.е. он не обязан захватывать всё процессорное время (собственно, большую часть времени он сидит и ждёт флага, что profiler нашел узел, тогда делает вычисления, кидает одну или две следующих команд и снова ждёт флаг), но есть ложка дёгтя. Как определить цвет поля в тупике? Дело в том, что из profiler я не могу обратиться к сенсору цвета. Сенсор цвета доступен по i2c, а как я могу из прерывания начать i2c транзакцию? Вдруг, какой из верхних уровней сейчас с этим i2c работает? Например, кнопки опрашивает.

И вот это одна из причин, почему я не могу придумать, как сделать перемещение робота на основе сенсоров работающих по i2c типа vl6180, OPT31xx.

С цветом, я конечно, поступаю просто. Получив, информацию, что найден тупик, программа просто стоит и ждёт пока статус profiler-а станет в ожидании следующей команды. Это будет означать, что не только обнаружен тупик, но и робот спозиционирован так, что его ЦТ находится над самым концом линии. А значит, сенсор цвета уже на несколько санттиметров находится над цветным полем.

Re: RSLK от TI (Robotic System Learning Kit)

Вс май 29, 2022 09:59:09

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

Еще из новшеств придумал, как лучше выполнять "подгонку результатов". Так как, как правило, на соревнованиях лабиринт с клеточками одинаковой величины есть желание координаты узлов ставить в заданную сетку. Но первая идея у меня не пошла. Проблему вызывали стартовая и финишная клетки. Они линию не содержат, поэтому расстояние от старта до первого узла и от узла до финиша робот видит только как половину длины сетки. И если я раньше пытался привязываться к "предыдущим" координатам, то теперь я решил явно задавать шаг сетки и исходя из пройденного пути. Измеренный путь округляется до ближайшего кратного. Ну и, естесственно, если в результате округления получается 0 (как в случае стартовой и финишной клеток), считается что робот проехал одну клетку. Конечно, задав шаг клетки равной нулю, робот работает по старому алгоритму - без выравнивания.

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

Подозреваемых толпы: сам профайлер, сенсор линии, драйвер моторов, таходатчики, сами моторы, повреждение памяти? Первое что попробовал - поменять моторы местами - не помогло. Всё равно ведет влево. Даже пересадил плату на другое шасси, где был MSP432 - не помогло. В общем, колёса пинал, стёкла протирал, капот поднимал... ничего не помогло. Теперь, думаю, надо бы как-то сделать запись данных для проверки разных параметров. Увы, у этого робота уже ничего подключить не могу, ни FRAM, ничего - свободных выводов нет. Единственное, есть куча ОЗУ и можно туда писать лог. Выделил я под это дело 120 000 байт (400 отсчетов в секунду, 30 секунд и 10 байт - т.е. в течении 30 секунд я могу записать 5 переменных int16_t). Понаставил в профайлер записи в журнал показаний датчиков, значение ошибки, результат воздействия и задаваемой моторам скорости. Проехал, слил данные в таблицу и повторил расчет - всё считается правильно - ни одного ошибочного результата. Ну и сенсоры тоже вне подозрения - робот видит, что его ведет в сторону и пытается этому противодействовать, но безуспешно. Видно, что в тот момент двигателям задаётся скорость левому 160rpm, а правому 130-120rpm. Было подозрение на стек. Увеличил в два раза... и робот прошел трассу без ошибок! повторил - снова без проблем, но на третий раз - опять его повело влево. Решил зажурналить положение вершины стека - может, память где "протекает"? Увы, вершина держится в пределах нормы и используется порядка 3/4 килобайта от стека, поэтому увеличение его до 8 килобайт значения не имеет и то, что робот два раза проехал - просто совпадение?

Пока тут боролся с этим явлением, думал, как у целевого робота сделать журналирование. И тут я снова вспомнил про QuadSPI. Оказалось, что EEPROM подключенная через этот интерфейс сможет мне записать за фрейм (2.5мс) 256 байт данных и я могу взять микросхему ёмкостью 16 или 32 Мегабайта и стоит она меньше евро. В отличие от FRAM где мегабайтная микросхема стоит под 30 евро! Подумалось, что сначала надо бы это дело проверить на макетке - может не всё так здорово как мне показалось? Решил купить еще одну SLTB009 и одну EEPROM и попробовать. Хмммм. оказалось, что на этом ките, "быстрые" выводы QSPI не выведены наружу. Но потом оказалось всё еще хуже. Тот микроконтроллер, что я закупил - EFM32GG12B510 - не имеет на борту этого интерфейса вообще. Оно есть у 8хх (как на плате кита SLTB0009) и у 4xx. Пошел посмотреть что можно купить - а ничего нельзя купить. В продаже на складе есть только 510-е кристаллы. И снова я на распутье.

Пока рассматривал плату на предмет подключения EEPROM, заметил, что у меня на портуA есть еще несколько подключенных сигналов! Почему порт A? А я же переделал вывод на OLED дисплей через ПДП (в предыдущем сообщении) и писал, что этот вывод мне может портить данные на портуA. Так вот на PA8 находится "выключатель" PDM микрофонов что стоят на плате и подключаются к тем же контактам, где у меня идёт ШИМ на моторы. Может там проблема? а нет, там активный уровень 1 для включения микрофонов, а 0 для выключения. Так что я там пишу всегда 0, значит конфликта с микрофонами у меня нет. Ой, оказывается у меня на PA6 подключен сигнал направления вращения (правда, правого) двигателя. Хотя это не так страшно - PI контроллер двигателей обновляет там сигналы каждые 5 мс. Но, надо будет этим озаботиться...

Так как журналирование профайлера мне ничего не дало, решил зажурналить PI контроллер. Ну и записал значения задаваемой скорости и вычисленной из периода таходатчиов реальной скорости для обоих двигателей. Графически это выглядит так, синяя линия задавемая скорость, красная - реальная. Верхний график левый мотор, нижний - правый:
Изображение
Видно, что вроде графики следуют друг за другом, но с 20-й секунды (на графике стоит отметка 10 секунд - это я не переделал после перехода с одного журнала на другой. Первый журнал писался каждые 2.5мс, а этот с шагом около 5мс) левый двигатель идёт вразнос. Причину этого всё еще не отыскал. В коде криминала никакого не вижу. Функции для левого и правого моторов идентичны. Сейчас на подозрении только разъёмы в цепи таходатчиков. Но, еще не придумал как выявить, что там происходит.

Еще, раз уж залез в таходатчики, вспомнил о затее, почему бы пройденное расстояние считать не 32 битным счетчиком WTIMER, а 16 битным PCNT. Проблема в том, что переполнение может наступить слишком быстро. тут у меня 1 оборот колеса даёт 220мм, редуктор 1:120 и оборот мотора даёт 6 импульсов: 720 имп. на 220 мм. 16 битный счетчик считатает до 32767 - получаем 10 метров. А проход по лабиринту, что был в Сигулде, порядка 40 метров полный и 16 с половиной метров кратчайший. Но фишка в том, что мне нужно считать только расстояние пройденное прямо. А прямо там не больше 4 метров (13 клеточек по 30 сантиметров). Поэтому на каждом повороте я могу одометр сбрасывать и таким образом переполнение не сможет наступить.

Re: RSLK от TI (Robotic System Learning Kit)

Вс июн 19, 2022 08:34:15

Вопрос, а почему я захотел считать расстояние 16 битным счетчиком? А всё просто - мне потребовалось освободить хотя бы один 32 битный счетчик. Всё началось с того, что когда настраивал ПИ контроллер двигателя робота на PSoC5 получил следующий график оборотов моторов при тестовом прогоне на 25, 50 и 75% PWM (примерно. на самом деле там задавлись обороты 260, 650 и 1200 rpm).
Изображение
Смотреть на синюю линию, про красную чуть позже. Вроде всё красиво, но на последнем участке есть некрасивый "провал". Этот провал образовался из-за того, что периоды импульсов измеряются 16 битным счетчиком и захват произошел буквально перед самым переполнением счетчика. И эти два прерывания наложились друг на друга. Сначала обработалось прерывание по переполнению, а затем выполняя прерывание по захвату было учтено это ложное переполнение и в результате период получился длиннее, чем он был на самом деле. И тут я не вижу, как эту ситацию разрешить - если я поменяю приоритеты, я получу в другой ситуации просто противоположный эффект. И этот эффект может случиться каждые 5 с небольшим миллисекунд.

Единственное, кардинальное решение этой проблемы - увеличить период цикла счетчика так, чтобы он больше не попадал в диапазон рабочих периодов тахометра. Можно это получить или понизив тактовую частоту, что повысит уровень шума квантования, или увеличив разрядность. Что я и сделал - поменял 16 битный счетчик на 32 битный. Теперь цикл счетчика составяет 6 минут, что совсем не пересекается с периодами которые мне выдаёт таходатчик (Периоды больше 10мс считаются остановкой двигателя). После этого таких вот всплесков/провалов я больше не наблюдал.

Поэтому и было решено у робота на EFM32 высвободить 32 битный таймер WTIMER0 и использовать для измерения периодов таходатчиков вместо 16 битного TIMER0. А расстояния измеряются используя Pulse Counter PCNT0 и PCNT1 для левого и правого колеса. Правое колесо я тоже перевел ня 16 битный счетчик просто для однообразия. Но у PCNT нет такой штуки как "сброс". Есть загрузка топового значения. Поэтому "сброс" загружает 0xFFFF, что интерпретируется как -1. Но это проблему не вызывает, так как расстояние у меня измеряется со знаком. В результате получилась забавная конструкция с приведениями типов, если раскрыть все дефайны:
Код:
count = (int32_t)((int16_t)PCNT0->CNT) + (int32_t)((int16_t)PCNT1->CNT)
Так что если период одного колеса получился 10 метров, то с учетом обоих - 20 метров. Таким образом к критическим граням нет возможности приблизиться.

А тут, после трёхлетнего перерыва, появилась очередная статья на micromouseonline.com. Про эффект проскальзывания колес при разгоне и торможении. Главное, что в коментарии была ссылка на статью по поводу определения перепадов уровней (edges) в сигнале. Так вот, в этой статье вычитал про экспоненциальный фильтр и решил его применить для фильтрации данных с таходатчиков. До этого у меня был простой LPF. Анализ как изменились данные я не делал, но в работе робота ухудшений не заметил. А для иллюстрации, выполнил такую же фильтрацию с данными предстваленными на вышепомянутом графике - вот результат фильтрации и показан красной линией.

Кстати, по поводу глюков с левым мотором - они пропали. Когда я разобрал всё на предмет проверки нет ли где холодных паек на платах и, собирая обратно, подогнул разъёмы для более надёжного контакта - глюки больше пока не возникали.

Гоняя робота по лабиринту, обнаружил непрятную вещь - сенсор цвета TCS34725 далеко не каждый раз правильно определяет цвет в тупиках. Т.е. заехав на красное поле, выдавал информацию, что поле желтого цвета (цвет основания моей трассы так опознаётся). В то же время, запустив тест получаю правильные цвета. проблемой оказался бит в регистре статуса Data Valid. После инициализации в управляющий регистр прописывается PON (power ON), а в первом тупике туда же записывается (PON | AEN) (Power ON | ARGBC Enable) и ожидается статус Data Valid. Вот это единственный раз когда цвет в тупике прочитывается правильно. Проблема в том, что сигнал AEN остаётся активным и сенсор продолжает преобразования (желаемое поведение), но флаг Data Valid не сбрасывается. А когда он, вообще, сбрасывается? Поэтому в следующем тупике моя команда (PON | AEN) никакого эффекта не производит, а флаг Data Valid уже стоит и я имею право прочитать данные. Вот только эти данные могут быть созданы не в момент когда робот остановился в тупике, а гораздо раньше, когда сенсор еще не находился над цветным полем. Попытка после каждого чтения снимать сигнал AEN даёт правильное определение цвета, но сильно увеличивает время которое робот тратит в тупике. Кстати, на видео, видно, что в самом конце перед выездом из лабиринта робот странно дёргается - это вот пауза на определение цвета - так как это тупик, даётся команда на останов, ожидается остановка, затем запрашивается цвет поля и уже после этого алгоритм определяет, что лабиринт исследован и даёт команду выполнить "финиш" - выехать из лабиринта. Так вот в случае снятия AEN в этом месте остановка робота была явно видна.

Были испробованы разные варианты. Вдобавок выяснилось, что из-за неправильно поставленной скобки в формуле реальное время интегрирования сенсора было не 30мс, а почти 300. Пытался уменьшить время интегрирования - пока получилась боле-менее нормальная чувствительность при 75мс с усилением 4x. Конечно, если я ночью гоняю робота в темноте, встроенной подсветки сенсора в этом режиме недостаточно для надёжного определения зелёного цвета, но красный определяется нормально. Но опять же - это всё зависит еще и от материала и краски мишени.

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

Еще для интереса сделал в профайлере команду типа "финиш" - выехать из лабиринта, но задним ходом. Подумал, было бы неплохо, когда робот в режиме исследования лабиринта находит финиш с красным полем, чтобы он въехал на это поле и остановился. Это нужно, чтобы проезд был "засчитан" - так как по правилам время измеряется от старта до полной остановки робота на финишном поле. А затем после паузы, робот пусть возвращается в лабиринт и продолжает исследование. Почему заезжать задом? Потому что я не могу развернуть робота не видя линии. Да и видя линию, робот выезжает из лабиринта немного криво. Поэтому, в тупике, определив цвет, робот разворачивается (ЦТ находится на границе линии и финишного поля) сдаёт назад на 10см, чтобы полностью встать на поле, ждёт 2 секунды и снова возвращается в лабиринт и продолжает исследование. Чтобы вслепую развернуться, надо работающий гироскоп. Но моя первая попытка подключить старый гироскоп ITG3205 успехом не увенчалась. Почему-то линейный разгон этот сенсор тоже воспринимал как поворот. Таким образом, малейшее смещение от центра вращения, как получаю сильные погрешности.

На днях размечтался, что удастся приобрести кристалл с QSPI - EFM32GG12B410 - на фарнеле увидел, что ожидаемый срок поставки 14 июня. Даже нотификейшн установил, чтобы получить письмо, как появится. Увы, 13 июня никакого письма не пришло, а срок у этой позиции уже стоит 19 октября. Что ж, придётся делать на 510-м кристалле и использовать обычный SPI. Вот только еще не решил, тратиться на FRAM или нет.

Re: RSLK от TI (Robotic System Learning Kit)

Пт июн 24, 2022 21:18:11

Поставьте прерывание на переполнение 16-ти битного счётчика и сделайте в нём инкремент 32 битной переменной. Получите 48 битный счётчик :)
Я бы добавил поддержку переполнения вниз, чтобы счётчик был реверсивным, но надеюсь, это лишнее.

Re: RSLK от TI (Robotic System Learning Kit)

Сб июн 25, 2022 07:26:30

Ну на PSoC5 так оно и сделано - 16 бит аппаратно и 16 бит программно по прерыванию. Прерывание по переопустошению нужно обязательно. Но на EFM32 можно было бы сделать еще круче - там можно используя систему PRS эти счетчики каскадировать:
И тут чисто аппаратно получается 32 битный счетчик. Правда, со всеми вытекающими проблемами, как избежать того, что после прочтения младшей части, произойдёт инкремент старшей (и робот телепортируется на 10 метров вперед). Ну и проблема еще и в том, что этих Pulse Counter-ов в системе всего 3 - т.е. две пары не сделать. Хотя опять же - используя эту PRS можно так соединить не только PCNT, но и TIMER, WTIMER - они все могут быть квадратурными счетчиками и каскадироваться.

Но как уже упоминал, мне оно в данном случае не нужно, так как измерения 10 метров мне хватает, поэтому в наращивании разрядности надобности нет. И даже у linefollower роботов могу обойтись - надо только на каждом перекрёстке или сбрасывать счетчик, или просто использовать 16 битную арифметику. Может, при другой конфигурации моторов, колеёс и редукторов это потребуется, но пока нет. Я тут пытаюсь прорабатывать разные варианты. Один вариант на готовом шасси, а другой вариант на самодельном:
Изображение
Тут я сделал хабы под покрышки от колёс pololu-3407 с зубчатой передачей. При печати одно колесо не напечаталось и еще станина не начерчена, чтобы и её изготовить. Колёса к станине будут крепиться при помощи shoulder screw. Ведущая шестерёнка 7 зубьев, на колёсах - 28. Так что редуктор получился 1:4. У мотора стоит оптический таходатчик - 30 импульсов на оборот. Т.е 120 импульсов на оборот колеса. При диаметре колеса 32мм, шестнадцатибитного счетчика хватает на ±27 метров - десятикратный запас для micromouse лабиринта.

Re: RSLK от TI (Robotic System Learning Kit)

Сб июл 30, 2022 13:22:54

Вот не знаю, как другие роботостроители делают задачу параметров, при помощи которых подбирается оптимальный режим работы робота. Но у меня, этих параметров становится очень много и возникает проблема, что параметры могут начать противоречить друг другу. Вот я ввёл шаг клетки, а если окажется, что защитный интервал больше этого шага? Тогда робот будет пропускать развилки и повороты. Или вот еще проблема нарисовалась: при исследовании лабиринта робот движется с некоей минимальной скоростью и обнаружив узел, должен остановиться, так, чтобы ЦТ оказался бы над центром узла. Развилку робот видит за несколько миллиметров (например, 75), на которые сенсор вынесен вперед и при заданной начально скорости и заданном ускорении робот должен успеть за это расстояние остановиться. Так что если ускорение недосаточно - робот проскочит мимо,начальная скорость за высокая - робот тоже не успеет затормозить. Поэтому, пришлось добавлять функцию валидации параметров.

Так же, размышляя о параметрах, подумалось, что для расчета маршрута по лабиринту не правильно использовать в расчетах "фиктивные стоимости" поворотов, узлов итд. Ведь, единственный критерий для оптимизации маршрута - это время. Поэтому стоит вопрос, как из расстояния получить время. Время получается исходя из ускорения и максимальной скорости. Т.е. после поворота робот начинает ускоряться с заданным ускорением, пока не достигнет максимальной скорости и часть пути следует с этой скоростью, а затем начинает тормозить с всё тем же ускорением до полной остановки. При этом, расстояние, необходимое для разгона и торможения - одинаковое и его можно вычислить заранее. Поэтому формула получается очень простой. S - длина прямого участка, Sbr - длина тормозного (разгонного) пути, vm - максимальная скорость:

Изображение

Кстати, если в 3 формулу подставить 4 формулу, то получится формула t = S/v + v/a. Получается, что время равно проезду этого участка с максимальной скоростью плюс время разгона до этой скорости. Звучит пока странно, но ошибки в выводе этой формулы не нашел. Но! это для случая, если участок достаточной длины для полного разгона до максимальной скорости и торможения до полной остановки.

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

Как-то читал я об этой проблеме (взятие квадратного корня) и уяснил, что в МК с FPU нет смысла извращаться с целочисленными методами, проще перевести в плавующую запятую, взять корень и перевести обратно в целое число. Поэтому, не мудрствуя лукаво, просто воспользовался библиотечной функцией sqrt(). Конечно, пришлось еще научиться подключать библиотеку в которой эта функция находится (Libm). Еще в Code Compose Studio ULP advisor начал настаивать на переносе кода использующего FPU из флеша в ОЗУ. Хорошо, даже научился как линкеру это втолковать. Правда, предупреждение так и не исчезло, несмотря на то, что по репортам и сама библиотека, и моя функция, вызывающая эту библиотеку, находится в ОЗУ. Похоже, очередной баг?

В коде, эта формула выглядит гораздо страшнее, так как надо странные аргументы привести к такому виду, чтобы время считалось в единицах, удобных для сравнения. Ну я выбрал время считать в миллисекундах, поэтому скорость из оборотов в минуту надо было переводить в миллиметры в миллисекунду и аналогично с ускорением. Вообще, это был стратегический просчет, то, что я скорость задаю в оборотах колеса в минуту. Это пошло с лабораторной работы №16 - Тахометры. Там из периода импульсов таходатчика получали rpm поделив 2 000 000 на период. А вот если бы с учетом длины окружности колеса делили бы 7 3333 333 на период, то получалась бы скорость в миллиметрах в секунду. Которую можно было бы отмасштабировать в 100 раз и диапазон задаваемых скоростей был бы от 11189 до 53000 (0,11м/с до 0,53м/с). В принципе, об этом надо подумать...

Так что еще осталось? А, время требуемое для поворота. Тут оказывается, что для поворота, каждое колесо должно пройти четверть окружности - одно колесо вращаясь вперед, другое назад. А если бы они вращались в одну сторону, то это было бы эквивалентно проезду прямо по участку длиной "ширина колеи умножить на Пи и поделить на 4". Так как ширина колеи у меня 143мм (причем, у всех троих роботов), то поворот равен проезду по прямой 112мм.

Таким образом удалось почти полностью избавиться от "стоимостей" поворота, прохода через узел итд. Конечно, такой расчет маршрута требует много времени (видел значения больше 50мс и даже 100мс), поэтому этот расчет производится тогда, когда робот находится вне лабиринта. Внутри лабиринта, маршрут для "срезания углов" делается просто по кратчайшему расстоянию. Разница в этих расчетах в том, что расстояния линейны, поэтому расчитываются расстояния только от текущего узла до соседнего. При расчете по времени, расчет идёт от текущего узла до всех узлов доступных на одной прямой, так как время требуемое для разных расстояний не суммируется как расстояние. И из-за этого оказалось, что в зависимости от отношения длины "клеточки" к тормозному пути получаются разные маршруты. Вот для примера варианты в лабиринте с длиной клеточки 30см, максимальная скорость 160 rpm (586,66 мм/с) и ускорениями 40, 70 и 150 *0.01 rpm за 2.5мс:
Изображение Изображение Изображение
Собственно, чем выше ускорение и, соответственно, меньше тормозной путь, тем маршрут больше стремится к кратчайшему по расстоянию и длинные прямые участки обесцениваются.

Этот код был перенесен на все 3 робота. Единственное, что при переносе кода на PSoC5 надо было заменить вызовы записи-чтения SPI EEPROM на I2C EEPROM. Ну и так же написать функцию инициализации таблицы расстояний через DMA (для однообразия). И что приятно, код решения лабиринта без проблем заработал и на этом роботе. Правда, сначала не хотел цвет тупика опознать, но это из-за того, что не был проинициализирован сенсор. Как и нет встроенного теста для его проверки. Пробовал сделать с командной строки возможность считать, но при воткнутом USB кабеле, робот не стоит на колёсах, т.е. условия не эквивалентны роботу на трассе. Вообще, слишком уж хотел выпендриться, размещая этот разъём снизу. В результате, получился "паркетный" робот - малейшая неровность и этот разъём за неё цепляется. Особенно за лист с "красным полем", который я прикладываю к трассе, чтобы обозначить финиш. Надо будет когда-нибудь попробовать чуть повыше колёса изготовить (и опять переделать все расчеты расстояний, скорости, ускорения и времени).

Re: RSLK от TI (Robotic System Learning Kit)

Вт окт 04, 2022 20:04:45

У меня соревнования в Таллине отменяются - я ничего не сделал и не готов. Немного заболел и целый месяц лечился. А потом еще отходил от лечения. У нас же с соревнованиями что-то подозрительно тихо.

Пока лежал в больнице, подумал, что необходимо сделать, чтобы перейти от задания скорости в rpm к миллиметрам в секунду. Первое, я уже писал, измеренным периодом между импульсами таходатчика надо делить не 200 000 000, а 733 333 333. Откуда берется это число? это сколько импульсов придёт на таймер если колесо вращается/движется со скоростью 0,01 rpm (раньше) или 0,01мм/с (теперь) при частоте тактовых импульсов 12 МГц и длине окружности колеса 220мм. Интересно, что эти числа примерно одного порядка и различаются в 3,66(6) раз. Собственно, 220(мм) делить на 60(сек) = 3,666.

Хорошо, мы таким образом получили скорость в 0,01 мм/с. Что еще необходимо изменить? Во-первых, все скорости в конфигурации надо перевести из prm в мм/с умножив их на 3,66. Во-вторых, надо озаботиться коэффициентами ПИД регулировок. Например, так как скорость численно "возросла" в 3,66 раз, а ширина импульсов ШИМ двигателя осталась той же, то коэффициенты должны обеспечить это. Следовательно, их надо тоже пропорционально уменьшить. Думал что делать с ПИД регулировкой удерживающей робота на линии. Вроде тут снова - отклонение от линии даёт ту же самую величину, а скорость должна пропорционально вырасти - значит надо их увеличить. Но это не так. Эти коэффициенты дают пропорциональное изменение скорости каждого колеса от текущей маршевой скорости всего робота, поэтому, оказалось, их менять не нужно - пропорция остаётся той же самой.

Ну и третье, надо еще переделать все формулы, для расчета тормозного пути и времени проезда заданного расстояния. А это тяжело - вспомнить все места, где эти расчеты ведутся. И у меня пока нет идей как это дело параметризовать. Ведь задаваемые коэффициенты - дробные числа. Для получения скорости из задаваемого параметра в мм/с раньше надо было считать как speed*220мм/100/60с, а ускорение еще и умножать на 400. И в каждой формуле, нужно было спланировать как целочисленно это посчитать, чтобы не потерять точность и не вляпаться в переполнение. Теперь же одни сотни, тысячи итд. Правда, 400 всё-равно всплывает в тех формулах, где есть ускорение, так как ускорение задается как изменение скорости за 1/400 секунды.

Взял, на гит-хабе, сделал еще одну ветку проекта и попытался всё это реализовать. С моторами получилось нормально - тест моторов проходил правильно. А вот движение по лабиринту не пошло. Робот, при входе в лабиринт начинал двигаться нормально, но, завидя линию внезапно останавливался и медленно начинал катиться назад. Похоже, что где-то наступало переполнение. Поэтому эту ветку пришлось гикнуть. В общем, я тут нашел, что в самом начале некоторые переменные я использовал 16 битные и в функции передавал такие же аргументы. Повыдирал эти атавизмы - и со второй попытки всё заработало.

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

А у робота на EFM32 для измерения напряжения на батарее попытался воспользоваться встроенным в микроконтроллер операционным усилителем. Почитал даташит и начал пробовать. Оказалось, совсем не сложно. Правда, так как я подключал вход АЦП прямо к выходу операционного усилителя, была возможность задействовать только OPA2. Т.е. не ко всем усилителям можно напрямик подключиться. Возможно, используя передачу через аналоговую шину можно воспользоваться и другими операционниками, но не пробовал.
Код:
void init_battery(void) {
  GPIO_PinModeSet(gpioPortA, 6, gpioModeDisabled, 0);
  CMU_ClockEnable(cmuClock_VDAC0, 1);
  VDAC0->OPA[2].MUX = VDAC_OPA_MUX_POSSEL_APORT1XCH6 | VDAC_OPA_MUX_NEGSEL_UG | VDAC_OPA_MUX_RESINMUX_DISABLE;
  VDAC0->OPA[2].OUT = 0;
  VDAC0->CMD = VDAC_CMD_OPA2EN;

  ADC0->SINGLECTRL = ADC_SINGLECTRL_CMPEN | ADC_SINGLECTRL_AT_256CYCLES |
//    ADC_SINGLECTRL_POSSEL_APORT1XCH6 | ADC_SINGLECTRL_REF_2V5 | ADC_SINGLECTRL_RES_12BIT;
      ADC_SINGLECTRL_POSSEL_OPA2 | ADC_SINGLECTRL_REF_2V5 | ADC_SINGLECTRL_RES_12BIT;
  ADC0->SINGLECTRLX = ADC_SINGLECTRLX_FIFOOFACT_OVERWRITE | ADC_SINGLECTRLX_VREFSEL_VBGR;

  BUS_RegMaskedSet(&ADC0->IEN, ADC_IEN_SINGLE);
  NVIC_SetPriority(ADC0_IRQn, ADC0_IRQ_Priority);
  NVIC_EnableIRQ(ADC0_IRQn);
}
Закоментированная строчка подключала АЦП прямо к выводу без ОУ. Попробовал на макете, с делителем 130кОм/390кОм и используя 1% резисторы - измерение было достаточно точным (в пределах двух значащих цифр) и никакой коррекции не потребовалось.

После того как удалось "завести" операционный усилитель, подумал, что можно было бы это же сделать в LineFollower с BGM13. Но...тут меня посетила внезапно другая идея. В том LineFollower стоят два микроконтроллера - один бежать по линии, а второй BlueTooth обслуживать. А зачем так много? Неужели один не справится? Поэтому у меня сейчас затея сделать робота на одном модуле BGM22. Выводов у него, конечно, маловато. Но, робот укладывается, особенно, если взять с буквами BGM220PC22WGA2 - там 25 GPIO доступно (а у меня в наличии есть BGM220PC22HNA2). Правда, у BGM22 унутре нет операционника.
А так по выводам получается так:
энкодеры - 4
Два мотора ШИМ, направление, выкл - 5
Сенсоры - 8
вкл/выкл подсветки сенсоров - 1
I²C - 2
SWD - 3
Vbat - 1
Кнопка старт - 1

Итого - 25.

Вот только плата получилась у меня не сбалансированной - много компонентов с левой стороны и почти пусто - с правой. Возникла затея там же еще разместить USB разъём с CP2102, но выводов, куда подключить, у микроконтроллера больше нет. Хотя, можно попытаться последовательный порт шарить с интерфейсом отладки и программирования. Ведь, после, можно прошивку менять через BlueTooth.
Изображение

Форма платы кажется странной? А это потому, что оно для шасси Zumo от той же Pololu. Как-то рылся по этому сайту и вздумалось мне почитать про это шасси. Это шасси является базой для двух продуктов: Ардуино шилд и Zumo робот. Каждого имеется в двух вариантах. Старый Шилд был с выводными элементами, новый - максимально поверхностный монтаж. Старый робот был с ЖКИ, новый - с OLED дисплеем. Хотя само шасси, по-сути, гадюшник с колёсиками батарейный отсек с колёсиками, на которые одеты гусеницы.
Изображение

Робот меня не прельстил - атмега. Поэтому возникла идея попробовать сделать нечто своё.

Проблема купить. Как-то не хотелось снова связываться с растаможиванием, поэтому решил попробовать купить в tme.eu. Начал смотреть что есть в наличии. Оказалось, шасси нет, но есть ардуиновский шилд. Старая версия. Одна (надо полагать, последняя) штука. Мне так очень хотелось, что плюнул и купил этот вариант. Плату выброшу или, может, скрещу с Cypress PSoC4 китом. Правда, с налогами он оказался около 70 евро. Ну ладно, разместил заказ вместе с другими компонентами, что я там попутно заказал - сижу, жду.

Приходит посылка, распаковываю, смотрю: ага, вот детали шасси... вот нож для сумо. А где плата? Вместо платы пустой пупырчатый кулёк, чтобы не гремело и не заметили, что что-то кто-то уволок. Ну я в расстройствах. Сама плата мне нафик не нужна, но я же за неё заплатил. И стоит она больше чем шасси с этим ножом вместе взятые! Пошел писать в tme претензию. Ну они претензию рассмотрели, и так как для замены такого комплекта у них больше нет - вернули мне полную стоимость. Так что я оказался владельцем шасси почти задаром. Если не считать потраченные нервы и огорчения.

Re: RSLK от TI (Robotic System Learning Kit)

Ср окт 05, 2022 04:04:23

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

Не помню выкладывал-ли сюда проект шагающего робота моего студента 2-х годичной давности. Это по поводу справится-ли BGM13/22 с управлением. В BGM22, правда, RAM в 2 раза меньше, но зато уже появили в продаже модули на BGM240, где флеша и RAMa с избытком. Наш робот также собран на BGM13 модуле и управляет 8 сервами помимо реализации управления роботом по Bluetooth на том-же модуле. Код студента из серии корявее не бывает с флоатами и тригонометрическими функциями, короче всё как не надо делать. Далее прототипа развитие не пошло, хотя первоначально планировали заложить в него больше функционала. Однако, как не удивительно, производительности процессора на всё хватает, по крайней мере просто для хотьбы.

Робот на Zumo предполагаете использовать для езды по лабиринту? Посмотрел на комплект - там, вроде, моторы не включены и имеется несколько вариантов их выбора. Какие моторы используете? Интересно кому понадобилось вытаскивать эту плату из пакета. Полагаю, что изначально был недокомплект в последнем экземпляре.

Re: RSLK от TI (Robotic System Learning Kit)

Ср окт 05, 2022 19:30:32

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

Шасси, что идет отдельно от роботов моторами не комплектуется. Готовые роботы (сборки не требующие) собраны с микрометал моторами с разными редукторами. В зависимости от коэффициента передачи достижима разная максимальная скорость. Для редукторов 1:100 - 0.5м/с, 1:75 - 0.65м/с, 1:50 - 1м/с. Но в ознакомительном видео, там же на сайте, упоминается, что для использования этого робота в соревнованиях LineFollower можно поставить моторы с редуктором 1:30. Ну, у меня как раз такие были, причем типа HPCB - High Power Carbon Brush, поэтому я планирую ставить именно их. Посмотрим, как быстро мне удастся их разогнать. Я надеюсь получить хотя бы 1.5м/с. На сайте pololu не нашел такой важной информации, как шаг робота - какое расстояние робот пройдёт выполнив 1 оборот ведущего колеса. Возможно, это каждый меряет для себя и по-своему. Для шасси Romi я использовал число, что указал Валвано в своём curriculum. Но тут можно попробовать воспользоваться тем что у нас гусеница напоминает зубчатый ремень - использовать решение именно для таких ремней. Когда-то я решал такую задачку сколько зубьев должно быть у ремня, подающего и приёмного шкива, чтобы расстояние между осей укладывалось в допустимый диапазон и вообще мог сущестовать в природе. В интернете такие калькуляторы тоже есть. Этим я занимался, когда привод экструдера на 3D принтере хотел перевести с шестеренки на ремень. Но, если подающий и приёмный шкив имеют одинаковое число зубьев - эта задача становится тривиальной.
Изображение
Итак, имеем гусеницу 22 зуба и два колеса по 12 зубьев. Ясно, что каждое колесо охватывет по 6 зубьев. 22 - 2*6 = 10. Значит, расстояние между осями равно 10/2 = 5 зубьев - 5 сверху и 5 снизу (что чертёж в даташите на эти гусеницы подтверждает). На том же чертеже указано расстояние между осями 48мм - значит шаг зубьев - 9.6мм. Ну а так как на колесе 12 зубьев, то шаг будет 9.6 * 12 = 115.2 миллиметра. А теперь можно вычислить теоретически возможную скорость. Возьмём, максимальные обороты двигателя 30000 об/мин, через редуктор 1:30 получаем обороты колеса 1000 об/мин, что за секунду будет 166.666 оборотов. Умножаем на шаг и получаем 1920 мм/с = 1.92 м/с.

Для разгона этих двигателей, левую часть платы у меня занимает boost преобразователь, который из батарейных 4.8 - 6.0 вольт будет делать 9 вольт. Нарисовал его на тексасовском преобразователе TPS61089 (Хм, почему не взял простую LM2577?). Вторую половину левой стороны занимает "latching circuit", для включения/выключения робота кнопкой без фиксации. По центру BT модуль и драйвер двигателей. Спасибо, что напомнили про BGM240. Когда был вебинар по AI/ML они упоминались, но в продаже их еще не видел - только предзаказ, а сейчас, их явно "завезли" - каждой позиции ровно по 200 штук на складе. Буду переразводить плату под этот модуль - там доступно 26 GPIO - смогу USB-Serial штатно подключить. Еще на плате спереди будет подключаемый сменный модуль сенсоров. Сейчас разведен сенсор линии, а позже будет сенсор дистанции до препятствия (когда наконец построю полигон со стенами). Причем, сенсор препятствий будет схемотехнически аналогичный, только излучатели и приемники будут другие и ориентироаны соответственно, чтобы смотреть по сторонам, а не вниз.

Еще я слизал идею с pololu-вских роботов 3Pi и этого же Zumo с расположением датчиков холла для тахометра. Там они расположены не на двигателе, а на печатной плате, на которую двигатели установлены. Еще минус четыре соединенительных провода на каждый двигатель. Вот на ардуиновском шилде этих датчиков нет.

У этого шасси Zumo есть пара неприятных моментов. Во-первых, ленивое колесо. Там просто пластмассовое колесо скользит по металлическому винту (shoulder screw). Вот не знаю, на сколько долго его хватит. С другой стороны, а не будет ли это колесо пытаться открутить этот винт. Причем у этого подозрения есть основания, так как в иструкции по сборке специально предупреждено, что "если вы будете этот винт ставить на фиксатор, сначала проверьте, не растворяет ли фиксатор материал шасси". Еще это колесо имеет небольшой люфт вдоль оси. Потому как плечо винта 8мм, а ширина колеса - 7.2мм. Я пока для себя в том месте поставил по одной пластиковой шайбе - когда-то, для чего-то, уже не помню, покупал - 4мм внутренний диаметр и толщиной где-то 0.3-0.4мм. Была бы фторопластовая - было бы идеально. А второй момент, возможно, из-за того, что у меня очень ранняя версия или так как шасси шло в составе кита, надеюсь, что в более новых это исправлено - нет никакого крепления для терминальных лепестков батарейных контактов. Для тех перемычек, что последовательно соединяют элементы питания - для них есть, а для тех, с которых уже надо брать напряжение - нет. Поэтому я не мог "вставить лепесток, припаять проводок и навести на свою макетку", хотя это подразумевалось. Вот когда лепесток будет впаян в плату и плата прикручена к шасси - тогда другое дело - он будет держаться.

Re: RSLK от TI (Robotic System Learning Kit)

Чт окт 06, 2022 04:06:53

Полагаю, что в плане занятости модулей под приложение пользователя для BGM22/240 результаты будут ещё лучше, поскольку в отличии от модулей первого поколения они 2-х ядерные и одно ядро используестя исключительно для нужд Bluetooth стека.

Непомнили Вы мне про летний AI/ML вебинар на xG24. У меня после него было много проблем, когда я летом вникал в использование ML на старых платах Thunderboard Sense 2, которые заметно дешевле xG24. Никак не получалось добиться устойчивой работы библиотеки от SensiML для этого модуля. Я тогда даже в тех-support написал, но ответа не получил. Проблема разрешилась на сентябрьской силлабовской конференции Works With, когда я им задал вопрос в online и тамошние инженеры предложили поговорить со мной отдельно. Оказалось, у них в тестовом приложении на гитхабе ошибка. После того, как они мне на неё указали, всё заработало.

Посмотрел на моторы. У Pololu нет таких скоростных моторов, у Вас наверное свой какой-то. Насчёт лепестков крепления батарей - как-то они мне не внушают доверия. Как-бы контакт не отошёл в самый неподходящий момент из-за тряски, что может привести к сбросу МК. Почему не поставить "нормальные" battery holders?

Re: RSLK от TI (Robotic System Learning Kit)

Чт окт 06, 2022 19:39:05

Моторы есть. Вот полная таблица. И все эти моторы в зависимости от мощности дают от 25 до 36 тыся оборотов в минуту, а затем встроенным редуктором эти обороты понижаются. К сожалению, эти моторы не дешевые, а в этом году на tme.eu они подорожали чуть ли не в 2 раза (с 15 до 25 евро за каждый, если брать минимум 3 штуки) , но горят точно так же как и все остальные. Сгорают щётки коллектора в тех моделях, где они из металла. Сейчас я покупаю только те, у которых графитные щётки - посмотрим, насколько они живучее. Такие же двигатели производят и "китайцы". Раньше я покупал там какие-то неизвестные моторы. Но у них, как правило, нет сзади выхода вала мотора, на который можно насадить магнитный диск для тахометра, потому я больше в ту сторону не смотрю. В коробке всё еще лежат 4 одинаковых и 2 штуки "не парных" - пока нет идей куда их применить.

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

Батарейный отсек по сути и есть Battery Holder и не хуже, чем то что можно купить под таким же названием. И, мне кажется, что у Pololu эта арматура унифицированна. Во всяком случае арматура от шасси Romi выглядит точно так же. И, кстати, в Romi есть направляющие для конечных терминалов. А батарейки могут терять контакт. Вот интересный блог от Erich Styger. Там он описывает ситуацию, когда батарейки сдвигаются при соударении сумо-роботов.

Еще немного посмотрел его сообщения - он делал робота на Freescale микроконтроллере. Там было видео, как робот решая лабиринт и найдя тупик не разворачивается, а катится назад до ближайшего пересечения и только там поворачивается в нужную сторону. Сначала подумал взять на вооружение, но роботы на шасси Romi ходят настолько криво, что я не представляю, как его удержать на линии задним ходом. С другой стороны, для опознания перекрёстка робот должен проехать за него, а затем вернуться вперед, чтобы ЦТ встал над перекрёстком. Мне кажется, что на этом маневре потребуется больше времени, чем просто развернуться в тупике. Хотя на сайте https://micromouseonline.com/ упоминался симметричный робот (MITEE Дэвида Оттена), у которого оба конца одинаковые и он в зависимости от направления движения использовал сенсоры с одной или другой стороны.

Re: RSLK от TI (Robotic System Learning Kit)

Чт окт 06, 2022 21:19:59

Да, в условиях столкновения роботов я-бы тоже поостерёгся применять пружинные battery holders. Помню, на старом семинаре Freescale (когда она ещё была не под NXP) рассказывали о приключениях сбора данных с акселерометров в самолёте. Цель нашего задания на семинаре была определить момент отрыва самолёта от ВЗП по собранным данным. Но при сборе данных оказалось, что без пайки выводов батареи не обойтись - МК иногда сбрасывался из-за тряски. Почему Вы не хотите запаять литиевый аккум в робот? У Вас в лабиринтных роботах наверное ускорения не малые во время движения(?)

Re: RSLK от TI (Robotic System Learning Kit)

Пт окт 07, 2022 22:06:40

Раньше хотел... теперь, я на литиевые элементы смотрю несколько скептически. Они требуют для себя слишком много внимания. А если про них забудешь, то придётся их выкидывать и покупать новые. Уже так несколько выбросил. И из-за этого начинаю в роботы обязательно вводить контроль батареи. Сейчас, опять же надо проверить, как поживают два года спустя с последних соревнований батареи, что я тогда поставил на хранение.

Насчет припаять тоже есть негативные моменты. Если их припаять, то получится электромобиль - 100км едешь и три часа заряжаешься. А на соревнованиях так или иначе время ограничено. И хочется иметь возможность для финального рывка вставить комплект свежезаряженных батарей, а не ждать, пока встроенные зарядятся. Да и встраивать зарядный контроллер в каждый робот, та еще проблема. С одним элементом проблемы нет, но для двух надо еще и балансир городить.

Хотя у литиевых аккамуляторов с потерей контактов проблем меньше, чем с "пальчиковыми" элементами. Но! У каждого производителя и каждого устройства свой разъём питания! Первый аккамулятор, что приобрёл был с Т-образным коннектором. Хорошо, купил ему ответную часть. Но этот разъём большой и громоздкий. А когда купил чуть по-меньше батареи- там уже другой разъём. Снова надо искать ему ответную часть. А после того, как в 2018 году на соревнованиях в Рижском техническом университете это разъём подвёл так, что пришлось срочно искать паяльник и припаиваться напрямую, плюнул на те разъёмы и после покупки их просто обрезаю и кремпирую обычные JST двухконтактные разъёмы. Вот с ними еще ни разу проблем не было.

Но это можно сделать у тех аккамуляторов, у которых выводы сделаны в виде гибких проводов. Но я тут приобрёл по-дешевке кучку LiFePo элементов. А вот у них разъём неизвестного типа встроен прямо в корпус. Хотя, когда только появилясь эта задумка с Zumo, была мысль поставить еще один разъём, чтобы в батарейный отсек бросить литий-полимерный аккамулятор. Но это было до того, как я решился попытаться поставить буст-преобразователь. Всё-таки LiPo 2S даёт 7.4-8.4в, а не 5в как 4 "пальчика". Если буст заработает, в этом нужды не будет. А "пальчиковые" аккамуляторы, если купить "правильные" очень даже не плохо себя ведут. Раньше у меня было одно расстройство со всякими Sony, NEXCell итп. А как купил икеевские LADDA (с ихним зарядником) - так проблем больше нет.

По поводу ускорений... вы слишком хорошего обо мне мнения. Пока что роботы на шасси Romi бегают с ускорением "70-100". Что на человеческом языке означает всего 1 - 1.5 м/с². Мне еще далеко до 1-2g, как у Питера Харрисона. Собственно, главная причина ограничения ускорения - недопущение проскальзывания. Причем, если я по домашней трассе бегаю с таким ускорением, то не факт, что на трассе на соревнованиях удастся бежать так же. Может даже придётся снизить. Проблема, как определить есть проскальзывание или нет?

Когда я написал контроллер движения, у меня в голове крутится мысль, чтобы сделать тест. А тест состоит в том, что на трассе выбирается длинный прямой участок, робот ставится в его конце и запускается. Робот должен идти вперед, пока есть прямой проход и запоминает длины пройденных сегментов. Проход делается на скорости "поиска", т.е. минимальной. Дойдя до узла без хода прямо, робот останавливается, разворачивается и на максимальной скорости возвращается, снова фиксируя все длины сегментов. А потом эти длины сравниваются и Если их отличие очень значительное, то надо думать о снижении скорости/ускорения, так как проскальзывание чрезмерное. Пока не придумал как эти разницы визуализировать, потому еще этот тест не сделал.
Ответить