Robot Rabbit

#195

Параллельно с deeproute попробовали научить нейросеть разводить платы так, как это делают люди. Все за один день, 11 октября, на арендованных H100 и H200 в Runpod.

Данные: 52 233 платы KiCad с GitHub, GitLab, Codeberg и открытых бенчмарков, 6.56 млн шагов разводки. Каждую трассу человека режем на шаги «направление, длина, слой или переход» и учим модель угадывать следующий шаг. Платы, похожие на тестовые, из выборки выкинули, а Rabbit в обучение вообще не попадал.

Что попробовали:

  • CNN по картинке 64×64 вокруг конца трассы: следующий шаг угадывает в 72% случаев
  • ViT по картинке в трех масштабах: 72.7%
  • RouteTok, трансформер не по пикселям, а по объектам платы (площадки, дорожки, отверстия), 14.6M параметров: 73.8% на 4 тысячах плат, 79.5% на 26 тысячах, 80.2% на 52 тысячах
  • та же модель на 40M параметров: 78.4%, хуже маленькой
  • Qwen3-0.6B как основа: с предобученными весами 66.9%, со случайными 69.5%. Знание текста геометрии только мешает
  • DAgger: модель сама ведет трассу, а классический A* на каждом шаге подсказывает, как было бы правильно. Это лучшее, что сработало: доля соединений, которые нейросеть разводит сама, выросла с 77% до 93%
  • обучение с подкреплением GRPO: модель разводила больше соединений сама, но занимала место, и плата в целом разводилась хуже. Классический обман награды
  • LLM, которая пишет координаты текстом: в 45 раз больше токенов, около 2% законченных трасс, бросили сразу

Главные выводы: решают данные, а не размер модели. Точность угадывания шага почти ничего не говорит о том, разведет ли модель плату. И честно: лучшая сеть оставляет 35 неразведенных связей на 46 тестовых платах, классический алгоритм 2. Поэтому все рекорды deeproute ставит классическое ядро, а нейросети пока остаются исследовательской веткой.

Цена всего этого по счету Runpod: $115.76, из них $103.69 за GPU, примерно 23-24 GPU-часа (H100 около 17 часов, H200 около 6). Одна модель на 14.6M учится примерно час на H100 и стоит пару долларов. Датасеты на диске: 64 ГБ сырых плат и около 50 ГБ подготовленных токенов.

Параллельно с deeproute попробовали научить нейросеть… (фото 1) Параллельно с deeproute попробовали научить нейросеть… (фото 2)
#194

Плата развелась полностью: 0 неразведенных связей, 0 ошибок DRC. В прошлый раз fastroute уперся в 24 связи и 5 ошибок, и я думал, что дальше только руками.

Пока он крутился, в соседнем окне Claude Code за один день написал свой трассировщик, deeproute: 14 тысяч строк на Rust, 115 коммитов. Идея другая, чем у Freerouting: все цепи разводятся сразу, им разрешено пересекаться, а за каждое пересечение растет штраф, пока они не разойдутся. Потом оставшиеся цепи вырываются вместе с теми, кто им мешает, и разводятся заново. На моей плате он за 4 минуты дошел до 15 неразведенных и 0 ошибок.

Дальше два агента начали работать друг с другом. Мой агент гонял DRC и находил ошибки, deeproute после каждой правил роутер:

  • силовые дорожки нельзя сужать до 0.15 мм в середине пути, только у самого вывода: сразу стало 69 неразведенных
  • выводы контроллеров на силовых цепях это датчики, а не силовой путь, им хватит 0.25 мм: 53
  • перекроили силовой слой по его диагностике (отдельная медь под Raspberry Pi, руку и запасной выход 5 V): 22
  • вырывать застрявшие цепи вместе с соседями: 10

Он еще нашел, что KiCad при экспорте режет углы у L-образных площадок драйверов моторов, а я у него, что он ставит переходные отверстия в 0.04 мм друг от друга, что завод не сделает. Самое смешное: две связи никто не мог развести, потому что запретная зона вокруг выреза под шлейф камеры накрывала два резистора. Последние 10 связей добил руками и маленьким A*.

Потом два независимых ревью. Питание: роутер честно ставил одно переходное отверстие там, где из заливки в слой питания идут 15 A. Добавил по 3-8 штук. Производство: медь заходила в неметаллизированный вырез, а внутренние сигнальные слои были залиты на 4% против 90% у силовых, и плата толщиной 2 мм могла выгнуться. Залил их землей.

Цифры deeproute на открытом наборе из 1113 плат: 86.6% разведены чисто, у fastroute 69%, у Freerouting 66%, и в 5 раз быстрее Freerouting. Машинное обучение для роутера тоже пробовали, на 52 тысячах плат с GitHub, но рекорды выше ставит классическое ядро.

Файлы для JLCPCB готовы: черная маска, металлизированный край, 8 слоев, 2 мм.

Плата развелась полностью: 0 неразведенных связей, 0… (фото 1) Плата развелась полностью: 0 неразведенных связей, 0… (фото 2) Плата развелась полностью: 0 неразведенных связей, 0… (фото 3) Плата развелась полностью: 0 неразведенных связей, 0… (фото 4)
#193

Плата для завода оказалась сложнее, чем думал. Она заменяет RoboClaw, понижайки, драйвер сервоприводов и кучу проводов: STM32, два драйвера моторов, Raspberry Pi прямо на плате, у каждой нагрузки свой электронный предохранитель с измерением тока, рука xArm, 6 ToF датчиков, 3 лидара.

Самое интересное началось на трассировке. Сначала взяли Freerouting: на этой плате он только раскладывал выводы под переходные отверстия 37 минут. Нашли fastroute, порт Freerouting на Rust: тот же этап за 25 секунд. Дальше гоняли эксперименты и смотрели, сколько связей остается неразведенными:

  • 6 слоев, силовые заливки отданы трассировщику как препятствия: 350 неразведенных после 4 часов
  • 8 слоев и заливки после трассировки: 91
  • разделенный силовой слой, а цепи на 10-15 A только по внешней меди 2 oz: 76
  • выкинули 92 детали из 763, обновили fastroute с 0.1.7 до 0.1.13: плато то же, но в 1.5-2 раза быстрее
  • расширили плату до колес и удлинили хвост, +30% площади, подкрутили правила трассировщика: 56
  • расстановку деталей с нуля сделал Fable: блок микроконтроллера ушел в хвост, вокруг мелких QFN кольцо 2 мм, между драйвером и разъемом мотора пустая полоса под медь: 27

Интересно, что новая расстановка дала больше, чем лишние слои и площадь вместе. И Fable отдельно поймал, что дорожка 1.2 мм на 10 A сгорит, хотя DRC ее спокойно пропускает. Последние 27 связей добиваем руками.

Делать будем на JLCPCB одним заказом, и руками там почти ничего: скрипт сам выгружает файлы для завода и сверяет каждую из 166 позиций со складом через их API, завод паяет все с обеих сторон. В ту же посылку едут 10 плат для датчиков, которые агент спроектировал за вечер (выяснилось, что VL53L8CX не живет от 3.3 V, нужен свой стабилизатор на 1.8 V и преобразователь уровней), и нейлоновые уголки, напечатанные там же. По прикидке ~$1.5-1.8k.

Плата для завода оказалась сложнее, чем думал (фото 1) Плата для завода оказалась сложнее, чем думал (фото 2) Плата для завода оказалась сложнее, чем думал (фото 3)
#192

Как устроен процесс. Все, что можно, это код, а агенты гоняют цикл «поправил, собрал, проверил»:

  • механика: build123d поверх OpenCascade, живой просмотрщик на three.js, проверка пересечений через manifold3d за 3 секунды вместо 8 минут на точных булевых операциях, рендеры для меня
  • плата: схема и расстановка в design.py, KiCad собирает плату из скрипта, разводит fastroute (порт Freerouting на Rust, раскладка выводов за 25 s вместо 37 минут), DRC и файлы для завода через kicad-cli, склад и цены через API JLCPCB
  • модели: Claude делает работу, независимые агенты делают ревью по даташитам, Fable дает второе мнение, Jev от TypeSafe сверял названия деталей шасси
  • все даташиты теперь лежат в репозитории, и каждая цифра в схеме ссылается на страницу

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

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

Посчитал по логам, сколько это стоит. Со 2 по 11 октября 8 сессий за 6 рабочих дней: 3.3 млрд токенов, почти все это повторное чтение контекста из кэша, и 3.1 млн токенов ответов. Без подписки по ценам API Opus 5.5 это было бы ~$1200-1500.

Как устроен процесс (фото)
#191

Теперь дизайн робота меняют агенты. Модель шасси из STEP разобрали на 134 детали с именами, а все свое описано кодом на Python, так что любую правку можно собрать, измерить и проверить на пересечения за пару секунд.

Самое прикольное это датчики приближения. Я сказал «хочу 8 по кругу», Claude написал трассировщик лучей: из каждой точки края платы пускает 8x8 зон датчика сквозь всю модель, с колесами, повернутыми на ±30°. Борта оказались закрыты колесами, редукторами и тягами на 20-100%, так что осталось 6 датчиков: спереди и сзади по центру и на скосах. Потом я сказал «хочу, чтобы уголки стояли ровно по краю», и плата поменяла форму: скосы развернулись ровно под датчики, нос вытянулся на 21 мм под камеру ZED 2i, а хвост на 23 мм.

Теперь дизайн робота меняют агенты (фото 1) Теперь дизайн робота меняют агенты (фото 2)
#190

Хотел перейти на BLDC моторы, чтобы робот ездил быстрее и тише. Условие одно: drop-in, то есть встать в штатные кронштейны 37D без переделок.

  • с Claude прошерстили всех, кто делает 37 мм BLDC. Готовых «как родной» с энкодером A/B нет: китайские JGB37 BLDC идут только с Холлами, Hiwonder их вообще не продает
  • из maxon скачали весь каталог на 73 MB и разобрали в JSON все моторы, редукторы и энкодеры, чтобы подобрать комбинацию под 1.25 m/s. Победил ECX FLAT 22 + GPX 22 + ENX 22, но это €430 за штуку плюс переходная пластина, которую надо фрезеровать
  • поставили maxon в 3D модель робота и проверили зазоры до палубы: 4.3 мм, влезает

А потом посчитал, что для квартиры 1.25 m/s и так хватает родным моторам. Вернулся к штатным JGB37 и просто выкинул RoboClaw, моторами теперь управляет своя плата.

Хотел перейти на BLDC моторы, чтобы робот ездил быстрее и… (фото)
#189

Средний этаж робота теперь будет не акрилом с кучей модулей и проводов, а платой той же формы. Контур и отверстия под стойки сняли прямо с 3D модели шасси, так что она встает на место акрила без переделок.

На плате Raspberry Pi, RoboClaw, понижайки, предохранители на каждую ветку, INA4235 с шунтами, PCA9685 для руля, часы и все разъемы по краям, каждый смотрит в сторону своего устройства. Снизу пусто, там Jetson и моторы. 4 слоя, батарейная цепь держит ~16 A.

Самое прикольное, что ее никто не рисовал мышкой. Плата описана кодом на Python, KiCad собирает ее из скрипта, сигналы разводит Freerouting, а проверки и файлы для завода делает kicad-cli. Поменял что-то в коде, перезапустил, получил новую плату. 5 штук с монтажом на JLCPCB выходят ~$200-260.

Моторную часть специально собрали в одном углу: хочу перейти на BLDC моторы и потом заменить RoboClaw контроллером прямо на плате, не двигая все остальное.

Средний этаж робота теперь будет не акрилом с кучей… (фото 1) Средний этаж робота теперь будет не акрилом с кучей… (фото 2)
#188

Расчертили с Claude всю проводку для новой архитектуры: каждый провод, пин, протокол и сечение. Пока разбирались, нашлось несколько прикольных вещей:

  • аварийный стоп у RoboClaw по умолчанию защелкивается, а вход подтянут вверх, то есть оборванный провод означает «можно ехать». Сделали наоборот: Pi держит линию, только пока жив процесс защиты, а обрыв или зависание это стоп
  • бамперы на стоп не заводим, иначе робот, который уперся в стену, не сможет от нее отъехать
  • в даташите RoboClaw прямо написано, что USB в шумной среде отваливается и сам не восстанавливается. Основной канал будет UART
  • четыре ToF датчика сидят каждый на своей I2C шине, так не нужно менять адреса, и одна зависшая шина не убивает остальные
  • LD19 сняли с производства, лидар будет RPLIDAR C1

Список покупок вышел на ~A$825, больше половины всего уже есть.

Расчертили с Claude всю проводку для новой архитектуры… (фото 1) Расчертили с Claude всю проводку для новой архитектуры… (фото 2)
#187

Хочу переделать робота на новую архитектуру. Сейчас на одном Jetson крутится все: камера, карты, навигация, база данных, веб и туннель, а 8 GB памяти на всех вместе с GPU. Плюс сзади робот слепой, отсюда и 70 секунд упора задом в стену.

Идея разделить на мозг и тело. Jetson оставить только то, что требует GPU: камеру, глубину, локализацию, карту и планировщик. А мой старый Raspberry Pi 4 на 8 GB станет телом: моторы, руль, питание, лидар 360°, ToF датчики и бамперы, задняя камера, Forge, HUD и видео. И главное, защита от столкновений на Pi не будет зависеть от того, жив ли процесс камеры.

Заодно разобрал по телеметрии питание. Понижайка на 12 V для моторов на стартах упирается в свой предел и проседает до 11.3 V, а датчик тока батареи показал 7.6 A при потолке 8.2 A, то есть пики он, скорее всего, просто обрезал. В новой схеме у каждой ветки свой предохранитель, а Pi может выключить и перезапустить зависший Jetson. И будет нормальная кнопка выключения: 93 из 104 загрузок Jetson были после того, как просто выдернули питание.

Хочу переделать робота на новую архитектуру (фото)
#186

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

  • перенес робота в другую комнату, и он 10 минут не мог понять где находится. Пылесос в такой ситуации честно просит построить карту заново
  • камера иногда уверенно сообщает что робот улетел на 133 метра. Пришлось писать фильтр, который не верит прыжкам больше полуметра
  • спереди слепая зона 30 см, сзади не видно вообще ничего. Робот 70 секунд упирался задом в стену и думал что едет. Теперь понятно зачем пылесосу бампер, который он постоянно пинает: это самый дешевый и надежный датчик
  • исследуя квартиру робот уезжает из комнаты, не доделав углы, а потом возвращается. Ровно как пылесос

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

#185

Отдельно про то, как делили ресурсы. У Orin Nano 6 ядер и 8 GB памяти на все, включая GPU, а в начале одна камера ела почти два ядра.

  • все прерывания сидели на CPU0 и он был загружен на 100%. Раскидал: USB камеры на CPU2, UART RoboClaw на CPU4, I2C на CPU5. Прерывание Wi-Fi сдвинуть нельзя, на этой платформе оно приколочено к нулевому ядру
  • py-spy показал что 90% CPU процесса камеры это не мой Python, а оптимизатор трекинга внутри SDK. Переписывать на C++ смысла нет, его надо просто реже звать
  • у камеры три режима: 30 fps когда что-то едет, 5 fps когда открыт UI, 1 fps когда никто не смотрит. Глубина на каждом втором кадре: GPU с 34% до 19%, потребление с 13.6 до 12.4 W. А ограничение в 15 fps наоборот убрал: CPU тот же, а поза приходит на 55 ms позже
  • карту строит nvblox на GPU: 184 MB и ~2 ms на кадр, у встроенной карты ZED было +2.1 GB
  • ClickHouse делал insert каждую секунду в каждую таблицу и ел 75% ядра. Раз в 10 секунд и нагрузка в два раза меньше

Камера с 170-250% упала до 30-100%, память с 6+ GB до 4. Узким местом оказалась именно память, GPU загружен всего на 20-25%. Во время записи SVO памяти осталось мало, nvblox не смог выделить кусок на GPU и уронил процесс камеры. На Jetson видеопамять это та же оперативка.

Отдельно про то, как делили ресурсы (фото)
#184

Сказал «давай все перепишем», робот не в продакшене. Сначала бенчмарк на записанных проездах. RTAB-Map находит себя на карте другого проезда за 0.5-2.6 секунды. GEN_3 в одну сторону за 6.7, а в другую не нашел себя вообще. Из 40 «включений где попало» RTAB-Map привязался в 35, один раз ошибся на 86 см. cuVSLAM считает одометрию за 2.5 ms на кадр. Но эталона пока нет, так что надо наклеить на пол метки из малярного скотча.

Сказал «давай все перепишем», робот не в продакшене (фото)
#183

Задал вопрос: не изобретаем ли мы велосипед? Агент сделал обзор и ответил что в навигации нет, а в локализации да. Nav2 из ROS например не умеет разные радиусы поворота влево и вправо, так что свой Hybrid A* оставляем. А вся обвязка вокруг GEN_3 (таймауты, фильтр миллиметров, архивы карт, сбросы) это латание черного ящика, у которого одна поза одновременно и одометрия и глобальная привязка.

Первый шаг: разделил позу на odom и map. Навигация теперь едет по непрерывной одометрии, а прыжки карты ее не дергают. На проезде 2.8 м с поворотом расхождение 3 мм.

#182

Вчера были полтора часа пониженных частот и я думал это throttling по току. Оказалось сам себе устроил: при отключении GNOME systemctl isolate multi-user.target перезапустил nvpmodel, а тот вернул дефолтные минимальные частоты, то есть откатил тот самый jetson_clocks из #164. Теперь после nvpmodel всегда запускается jetson_clocks. Настоящий over-current тоже есть, но это штатная история: 1-2 раза в секунду частота падает вдвое примерно на миллисекунду, в сумме около 0.5% производительности.

#181

Выключил робота на ночь, но перед этим выгрузил все данные дня в Parquet, и агент ночью разбирался без робота. Нашел шикарное: ZED SDK несколько секунд после релокализации отдает координаты в миллиметрах, хотя в настройках стоят метры. За день 21 576 таких поз. Отсюда в логах «прыжки» на 4 километра и испорченная карта с препятствиями там где робот только что проехал. Еще статус KNOWN_MAP через 5-8 секунд снова сменяется на INITIALIZING, так что «нашел себя» теперь засчитывается только после 10 секунд стабильного статуса.

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

def update(self, now, position):
    if self.accepted is None or self.reachable(self.accepted, now, position):
        self.accepted = (now, position)
        self.pending = None
        return True
    if self.pending is not None and self.reachable(self.pending[1:], now, position):
        if now - self.pending[0] >= self.settle_s:
            self.accepted = (now, position)
            return True
        return False
    self.pending = (now, now, position)
    return False
Выключил робота на ночь, но перед этим выгрузил все данные… (фото)
#180

«Подъедь к холодильнику» раньше не работало, потому что у агента в чате не было планировщика и он отправлял робота вслепую. Теперь отдельная нода строит маршрут Hybrid A* по сетке проходимости, которую nvblox считает на GPU за 1-5 ms (раньше на CPU до 3 секунд). Маршрут строится за 5-30 ms и перестраивается если на пути что-то появилось.

С холодильником было весело: сначала робот остановился перед углом стены, потом в 2.26 м от холодильника, а в удачной поездке 6 раз передумывал между коротким маршрутом и объездом через всю квартиру. В итоге 5.35 м за 52 секунды и остановка в 30-40 см от дверцы.

«Подъедь к холодильнику» раньше не работало, потому что у… (фото)
#179

Нашли баг в ZED SDK 5.5: трекинг GEN_3 копит keyframes даже когда робот просто стоит. 265 штук за 9 минут, CPU с 31% до 135%, файл карты распух до 70-80 MB. Обходной путь: по умолчанию камера только локализуется в готовой карте, а расширяет ее только для новой карты или во время исследования. В покое процесс камеры теперь 17-45% CPU вместо 134-185%.

#178

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

Заодно карта стала из вокселей 5 см, прям как мир в minecraft о котором писал в #161. Сначала робот ехал по торчащим из пола кирпичикам: пол лежал ровно на границе вокселя и шум в ±1 см выталкивал его в ряд выше. Сдвинул сетку на полвокселя и кирпичиков стало 2% вместо 14%.

Поставил робота на стол и увидел в UI как он проваливается… (фото)
#177

Днем в одном репо и на одном роботе работали три агента одновременно: один переносил карту на nvblox, второй делал детектор, третий голос. Договаривались между собой сообщениями «беру камеру», «отдаю камеру» и «не деплойте, у меня образ еще собирается». Один все-таки сделал локальный vite build, чужой деплой увез его на робота и публичный UI отвалился с CORS. Прямо как в нормальной команде.

#176

Добавил голос. OpenAI Realtime прямо в UI, все те же тулы что и в чате, графики появляются в той же ленте. Сначала он отвечал только по-английски, потому что в общем промпте было «always write in English».

Миссию можно подтвердить голосом, но решение принимает код по транскрипту моей фразы, а не модель: только короткие фразы, и любое отрицание побеждает, то есть «да нет, отмена» это отказ.

Добавил голос (фото)
#175

Добавил распознавание объектов. Перебрали кучу вариантов от облачных моделей до обычного YOLO на COCO, но камера стоит на высоте 13 см и такой ракурс модели почти не видели: тумбу под телевизор называли скамейкой, а телевизор доской. В итоге YOLOE с открытым словарем, 58 классов зашиты в ONNX, а ZED SDK сам строит TensorRT, считает 3D боксы и трекает объекты. Класс «low wooden cabinet» пришлось добавить отдельно, иначе тумбу не находил. Первая сборка TensorRT engine заняла 9 минут.

Добавил распознавание объектов (фото 1) Добавил распознавание объектов (фото 2)
#174

Вчера ради встроенного spatial mapping из ZED SDK я выкинул старый nvblox (#160) целиком вместе с самосборным torch. Сегодня он вернулся, но уже правильно.

Процесс камеры ел 185% CPU и 3.4 GB памяти. Профилирование показало что Python тут ни при чем: почти все время внутри SDK, в оптимизаторе трекинга. Заодно агент подцепился к живому процессу камеры через gdb и заморозил ее на 2 минуты, теперь gdb на камере под запретом. Дальше записали SVO и прогнали один и тот же проезд через разные конфигурации: карта ZED это +2.1 GB памяти, а nvblox строит более полную карту за 184 MB и ~2 ms на кадр на GPU. Агент собрал nvblox на джетсоне и написал маленькое C++/CUDA расширение через nanobind, которое берет глубину с камеры и отдает блоки меша в том же формате что и раньше. Процесс камеры похудел с 3.4 GB до 1.4 GB.

#173

Робот теперь доступен из интернета через Cloudflare tunnel: live.rabbit0.dev. Потом подумал что любой с этой ссылкой может кататься на роботе и сбрасывать карту, и сделал персональные ссылки. Даю ссылку другу, он играется, потом я ее удаляю и через 5 секунд у него все отваливается.

#172

Утром карта пропала с UI. Трекинг убежал на -138 метров, а вершины меша я передавал как int16 в миллиметрах, то есть максимум ±32 метра, и все переполнилось. Теперь у каждого чанка свой origin. Почему трекинг убежал так и не понял.

#171

Ушел спать и оставил агентов работать на ночь: ревью кода, перформанс UI, Forge в docker compose. Утром 12 коммитов. Ревьюер, кстати, нашел что после любой отклоненной миссии все защиты (столкновение, застревание) тихо отключались. Хорошо что нашел он, а не стена.

#170

Попросил сделать команду, чтобы робот сам построил карту квартиры. Все готовые пакеты для этого завязаны на ROS, так что опять свое: frontier exploration и Hybrid A* под Аккермана с передним и задним ходом.

Сначала робот вообще никуда не ехал. Я подкрутил пороги глубины ради красивой карты, и перед белой стеной в полумраке камера стала выкидывать 80-90% точек. Робот считал себя слепым. Вернул пороги назад и он проехал 6 метров за 46 секунд. Чистая карта и плотные препятствия питаются одной и той же глубиной и тут приходится выбирать.

Попросил сделать команду, чтобы робот сам построил карту… (фото)
#169

Робот врезался в стену. Дважды. Защита должна была остановить его за 15 см, но камера не видит глубину ближе ~30 см (про слепую зону писал еще в #154). Стена просто исчезала из скана прямо перед контактом и робот решал что путь свободен. Теперь стоп на 30 см и препятствия запоминаются в мировых координатах на несколько секунд.

#168

В какой-то момент джетсон сам перезагрузился прямо во время маневров. После этого RoboClaw переехал с /dev/ttyACM0 на /dev/ttyACM1 и нода упала, а камера зависла на поиске себя в сохраненной карте. Самое веселое было дальше: моторы тянули по 6 A и робот «не двигался», я уже думал что что-то заклинило. А он ехал, просто поза камеры замерла.

#167

Первые автономные поездки. Очередь миссий живет на роботе: «развернись и проедь метр вперед» работает, разворачивается на 180° с точностью до градуса. Кликаешь в 3D сцену и робот едет туда, а если точка сзади, то разворачивается в несколько приемов туда-сюда.

Первые автономные поездки (фото)
#166

UI переписан полностью: теперь это одна 3D сцена с роботом в стиле Crysis, панели телеметрии, камера от третьего лица и чат с AI прямо в интерфейсе. В чате можно спросить про данные и получить график, а можно попросить проехать, но любое движение требует нажать APPROVE. Модель зайчика с ушами тоже нарисовал агент.

UI переписан полностью: теперь это одна 3D сцена с роботом… (фото)
#165

Параллельно начал Forge. Идея простая: писать вообще все что публикует робот в ClickHouse на одних часах и прикрутить агента, который отвечает на вопросы по этим данным. Для частых вопросов есть заранее проверенные запросы (назвал их slabs), для остальных агент пишет SQL сам, но он проходит статическую проверку и EXPLAIN перед запуском. Плюс поиск аномалий через Chronos-2, это foundation модель для временных рядов: она предсказывает каким должен быть сигнал, а аномалия это когда он вылезает за коридор прогноза. На следующий день Forge переехал прямо на джетсон, так что запись больше не зависит от того включен ли мой мак.

#164

Больше года ничего не писал. Робот все это время в основном стоял: когда я его включил, docker показывал что все контейнеры вышли 5 месяцев назад. Решил вернуться к нему с новым подходом: почти весь код теперь пишут агенты Claude Code, а я ставлю задачи, смотрю что получается, ставлю робота на пол и переношу его с места на место.

Первая находка сразу смешная: ZED не держал 30 fps потому что CPU сидел на 730 MHz из 1728, а GPU на 306 из 1020. Просто никто не запустил jetson_clocks. Одна команда и захват кадра с 34 ms упал до 14 ms.

#163

Добрался до дифференциала. Реализовал и откалибровал. Теперь радиус разворота минимальный и колеса не проскальзывают при поворотах.

Добрался до дифференциала (видео)
#162

Дальше на основе этой карты можно строить графы. Узлы это воксели с весами, зная cost можно использовать его для планирования маршрутов, объезжая дорогие участки, например чтобы робот не приближался сильно к стенам или не врезался в них. Дальше дейкстра или a* и робот может искать путь от своей позиции до цели использую pure pursuit.

Пока оно очень кривое и не точное, надо калибровать и фиксить баги. Но сам факт того что e2e пайплайн уже офигенно хотя столько боли и времени а продвинулся наверное только на 5% цели реализации локальной навигации.

#161

Следующим шагом встроил в пайплайн зрения робота. Сначала думал писать в шареный файл карты глубин и гадры но NATS спокойно переваривает поток на низком разрешении. В итоге камера шлёт rgb + depth в топик а nvblox нода подписывается на них. Для высокого разрешения надо будет думать дальше, но пока хватает. Интринсики камеры и поза обновляет kv стор а не просто шлет сообщения в топики, это оказалось гораздо более удобно (хотя под капотом это одно и то же)

nvblox берёт глубину и положение и на gpu в реальном времени строит tsdf (поле расстояний до поверхности). Оно сглаживает шум объединяет много кадров и даёт карту со свободными и занятыми областями. Из этого можно получить воксельную карту прям как мир в minecraft.

Следующим шагом встроил в пайплайн зрения робота (видео)
#160

Собрал nvblox под jetson. Готового torch пакета нет поэтому пришлось собирать самому. Три раза падало по разным причинам в итоге включение свопа помогло, у jetson не хватает памяти чтобы собрать пакет. Сборка плюсов с cuda и питоном тоже боль, даже несмотря на докер контейнер в котором можно все собрать оно не гермитичное разваливается.

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

#158

Все больше и больше использую NATS в проекте. Накидал простенький UI для управлением настройками камеры через UI. Для этого решил немного отойти от идеи использовать pub sub для всего и посмотреть в сторону jetstream. По дефолту NATS core не имеет персистентности но это можно включить включив jetstream. По сути это один флаг и у тебя появлятся персистентный KV стор, object store и некоторые гарантии доставки. Все это очень полезно и очень удобно использовать. Например настройки камеры это просто KV. И клиент и робот подписаны на этот ключ (все в jetstream это те же subjects) и могут реагировать на изменение, оба они могет так же менять значение и все клиенты мнговенно на них реагируют, а после перезагрузки состояние восстанавливается.

Все больше и больше использую NATS в проекте (видео)
#157

Решил по быстрому накидать блог на английском чтобы был. Буду туда дублировать все из robotrabbit0 сюда. https://rabbit0.dev

#156

Давно ничего писал но это не означает что ничего не делал. Пока был в Byron Bay робота не было под рукой поэтому занимался генератором контента для блога.

  • Все посты из телеги попадают в маркдаун файл, с метадатой на каждый пост.
  • Переводится каждый пост через api ChatGPT
  • Все картинки сжимаються в webp
  • Для каждого видео генерится превью через ffmpeg и тоже сжимается в webp
  • Хотел сделать без javascript вообще
  • Деплоится в cloudflare.
  • Source code тут rabbit0.dev
#155

У меня прям горит от того что NVIDIA выпилила аппаратный энкодер h264 из jetson хотя позиционирует его как edge ai device с двумя csi портами под камеры. Софтварным кодеком нагрузка на CPU на 1080p@30fps доходит до 40% и потребление ватт сильно взлетает.

Немного изучив топик сложилось ощущение что rapsberry pi 5 тоже лишился аппаратного энкодера из за шортэджа кристаллов, но rpi4 все еще имеет его. У меня кстати он есть и использовался в роботе пока я не переработал его на jetson. На том же разрешении и частоте кадров rpi4 потребляет на больше 5W и загрузка CPU не больше 5% переваривая поток без затыков.

Теперь появляются мысли о том, что разгрузить jetson перенеся все узлы для контроля механикой и стриминг камеры с jetson на rpi объединив их в кластер не такая уж и плохая идея. Кажется что дополнительные 5W погоду не сделают но освободят все ресурсы для Хуанга.

Возникает вопрос как объединить их вместе так как где то должен подниматься сервер NATS. Ethernet + мини свитч или ethernet over usb?

#154

Из за того что baseline стереопары довольно широкий она может измерять глубину только от 30см. Что создает слепой участок перед роботом. Терпимо но не очень приятно. Возможно можно подумать в сторону лидара или или проксимити сенсора для obsticle avoidance.

#153

Не удержался и решил поиграться с points cloud и depth measurment. Пока попробовал самую легкую модель.

То что на экране снизу это еще не SLAM а просто stateless point cloud который с частотой 30hz паблишится из робота в nats и рисуется с помощью treejs в браузере. Чем дальше точка тем ближе она к зеленому. Это всего лишь для удобства но в кода это просто 3 или 4 мерная матрица (4 если хочется сохранить оригинальный цвет с камеры)

Из сложного оказалось что 1280x720 слишком тяжело и просто байтовый блоб этой матрицы весит 70+Mb. Прокачивать такой массив 30 раз в секунду невозможно из за ограничения в 64Mb на сообщение и ограничения канала. Уменьшив разрешения до 320p и сжав его zlib получилось получить пару сотен килобайт что выглядит ок. Плюс эта матрица sparse поэтому можно еще выкинуть нули из нее. Хотя может и нет смысла если все равно сжимать.

Не удержался и решил поиграться с points cloud и depth… (видео)
#152

Теперь приходится схлопнуть все обратно в один узел который эксклюзивно имеет доступ к камере и делает все.

#151

Из за этого идея вытекают несколько других проблем. Изначально я думал сделать несколько узлов которые работают с камерой. Из за того что к камере может иметь доступ только один процесс я подумал о локальном стриминге через ZED SDK. То есть к камере коннектится один процесс и стримит пожатый h264 поток. Так же SDK позволяет и читать все другие параметры через стриминг словно используешь камеру локально. Но проблема в том что стриминг через SDK сильно завязан на аппаратное сжатие и без него крашится и не работает.

#150

Очередное разочарование, в NVIDIA Jetson Orin nano нет аппаратного сжатия h264.

#149

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

Как минимум хочется прямо сейчас закончить механику чтобы перейти к perception.

  • переделать руль
  • укрепить второй этаж (нарезать лазером акриловую пластину и пересобрать на новой площадке)
  • поменять задние моторы или поднять немного оси и купить колеса побольше
  • подрегулировать ускорение или распределить весь лучше (сейчас рэббит слегка подпрыгивает при резком ускорении)
#148

Большой мэилстоун. Он может передвигаться и управляться удаленно.

  • работает от батареи
  • видео стримится в реалтайме в 720p@30
  • задержки контроллера минимальные

Из проблем:

  • руль очень нервный
  • передаточное число редукторов слишком больше и робот очень медленный и шумный (bldc?)
  • видео не сжато h264, я беру каждый кадр и сжимаю в jpeg из за чего перегоняться много гигабайт, что не будет работать в 4g
  • углы руля очень маленькие, надо переделывать ступицу и линки
Большой мэилстоун (видео)
#147

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

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

Сегодня развел все провода и компоненты (фото)
#146

Завайрил контроллер задних моторов, сенсор напряжения, 2 step down регулятора, один для серво руля, другой для моторов и контроллера и запустил от батареи. Кажется ничего не задымилось, хороший знак.

Завайрил контроллер задних моторов, сенсор напряжения, 2… (фото)
#145

Перфекционизм - главный враг продуктивности

Перфекционизм - главный враг продуктивности (фото)
#144

Слегка напоминает на робота из фильма «ВАЛЛ-И». В целом я доволен как выглядит и как все влезло. Теперь надо подключить провода и проверить что все работает.

Слегка напоминает на робота из фильма «ВАЛЛ-И» (фото)
#143

Батарея конечно делает его горбатеньким а стереокамера добавляет выражение лица. С рукой будет еще забавнее смотреться. Перед немного пустоват но там будет контроллер руки. В будущем еще будет лидар но это чуть позже. Проблема что камера имеет предел измерения глубины от 30см, то есть прям перед роботом у него слепая зона. Эту проблему надо будет тоже как то решать.

Батарея конечно делает его горбатеньким а стереокамера… (фото 1) Батарея конечно делает его горбатеньким а стереокамера… (фото 2) Батарея конечно делает его горбатеньким а стереокамера… (фото 3) Батарея конечно делает его горбатеньким а стереокамера… (фото 4) Батарея конечно делает его горбатеньким а стереокамера… (фото 5) Батарея конечно делает его горбатеньким а стереокамера… (фото 6)
#142

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

Собрал все вместе но еще не соединял провода (фото)
#141

Дальше четырехканальная INA. Про нее чуть позже напишу. Сегодня запаял 4 шунта по 0.01 Ом для измерения тока и напряжения на разных узлах.

Дальше четырехканальная INA (фото 1) Дальше четырехканальная INA (фото 2) Дальше четырехканальная INA (фото 3)
#140

С jetson чуть посложнее так как у него нет отверстий на dev board. Пришлось просверлить дырки, надеюсь ничего не задел и он все еще работает.

С jetson чуть посложнее так как у него нет отверстий на… (фото 1) С jetson чуть посложнее так как у него нет отверстий на… (фото 2) С jetson чуть посложнее так как у него нет отверстий на… (фото 3)
#139

Получилась такая пластина со стендоффами на которые буду монтировать компоненты.

Получилась такая пластина со стендоффами на которые буду… (фото 1) Получилась такая пластина со стендоффами на которые буду… (фото 2) Получилась такая пластина со стендоффами на которые буду… (фото 3)
#138

После этого нарезал резьбу чтобы не закручивать гайки с обратной стороны.

После этого нарезал резьбу чтобы не закручивать гайки с… (фото 1) После этого нарезал резьбу чтобы не закручивать гайки с… (фото 2)
#137

CAD я не осилил и решил все разрисовать в Figma. Почти на все компоненты были даташиты с размерами но некоторые пришлось измерять вручную чтобы точно разместить отверстия. Потом сходил к Денису и распечатал расположение компонентов и дырок. Приклеил к листам которые нарезал лазером и просверлил отверстия.

CAD я не осилил и решил все разрисовать в Figma (фото 1) CAD я не осилил и решил все разрисовать в Figma (фото 2) CAD я не осилил и решил все разрисовать в Figma (фото 3)
#136

Сегодня весь день не выходил из дома и занимался роботом. После 2 недель без прогресса снова загорелся и продвинулся неплохо так вперед. Нашел оптимальный лейаут компонентов чтобы минимизировать провода и уместить все компакненько.

Сегодня весь день не выходил из дома и занимался роботом (фото)
#135

Весь робот в сборке будет около 3.5кг. Нифигово так конечно.

Весь робот в сборке будет около 3.5кг (фото)
#133

Есть конечно еще шанс что спеки батареи врут и в реальности она отдает гораздо меньше. Очень не хочется этого потому что возвращаться на RC lipo с большой токотдачей из за возни с зарядкой BMS и всякими другими защитами и безопасностью.

#132

Попробовал еще несколько heavy workloads. Jetson стабильно репортит «System throttled due to over-current». Я сомневаюсь что она жалуется на слишком большой ток вызванный включение GPU. Скорее всего это просто стандартная ошибка защиты и реальная проблема - under voltage. Батарея по спекам должна спокойно отдавать 10A а в пике даже больше что должно хватить за глаза джетсону. Прична может быть в слишком тонких и длинных проводах. Я купил barrel jack не глядя на толщину кабелей. Приехали AWG22 метровой длины. Падение напряжения на таком сетапе при скачках тока может доходить до 1V что точно будет заметно и скорее всего jetson включает throttling даже несмотря на то, что напряжения ему хватает.

На выходных попробую померить токи и напряжения при разной нагрузке. В лучшем случае обрежу провода. Если не поможет и причина реально в проводах то надо будет уже в 4 раз заказать новый barrel jack с AWG18.

#131

В SDK есть модели для построения point cloud которые будут полезны для SLAM (одновременная локализация и маппинг) когда робот определяет свое положение и поддерживает карту местности.

В SDK есть модели для построения point cloud которые будут… (видео)
#128

При устанвке ZED SDK он решил что надо оптимизировать neural depth models что повысило потребление до 7W и 1.4A

При устанвке ZED SDK он решил что надо оптимизировать… (фото)
#127

При минимальной нагрузке на режиме питания MAXN_SUPER потребление не больше 1A. Попробую нагрузить его камерой и посмотреть сколько он один проработает от батареи.

При минимальной нагрузке на режиме питания MAXN_SUPER… (фото)
#126

С 3 раза заказал правильный барель джек для питания и dupont коннекторы. По быстрому обжал и проверил как оно работать. По спеке dev борда может питаться 9-20V. Батарея на 96% выдает 16.2V что в пределах поэтому можно питать без step down конверторов.

#125

Как же бесит что nvidia так хреново тестирует jetpack. Вчера я окончательно сломал свой jetson и решил заново его прошить. После часа свежий jetpack не смог запустить chrome и любой другой браузер. После пары часов разговоров с chat gpt и claude ни к чему не пришел кроме как установить chrome из flatpak.

Решил попробовать gemini + deep research сегодня с утра и оно прям 🔥. Проблема в snap и самый простой способ решить ее откатом snap на версию назад. Это уже второй раз когда очень простой юзкейс ломается в jetpack и решается простым откатом версий.

Как же бесит что nvidia так хреново тестирует jetpack (фото)
#124

Из других обновлений так же дождался 5G гейтвей. Уже разобрал так он более компактный и удобнее крепить плату на стендоффы на корпус робота. Думал в комплекте будут GNSS и 5G антенны но их не оказалось, придется заказывать отдельно.

Из других обновлений так же дождался 5G гейтвей (фото)
#123

Забрал сегодя послыку из штатов в которой пришла стереокамера ZED 2i. Выглядит она конечно офигенно. Моя версия с фокусным расстоянием 2.1mm, я подумал что в помещении это будет чуть лучше чем 4mm. Из интересных оснобенностей:

  • SDK не работает в parallels так как собрано только x86 и не работает на windows arm
  • SDK надо качать с сайта и его нет в репозиториях питона что не очень удобно, чтобы запустить простой захват изображения надо тоже помучаться но из хорошего у них уже есть готовый docker образ под l4t и jetpack
  • она откзалась работать со всеми USB кабелями кроме родного а это прям бесит потому что ты дебажишь софтовую часть и в последнюю очередь думаешь о usb кабелях
  • не сказать что я в восторге от качества но у нее очень много других плюсов, прямо в ней есть IMU и fusion и несколько других сесоров и с ними достаточно просто работать
  • в итоге посидев 4 часа я завел ее и застримил картинку и телеметрию с сенсоров через nats в браузер
Забрал сегодя послыку из штатов в которой пришла… (фото)
#122

Решил немного обновить интерфейс и порефакторить кода. Хочу сделать UI в ретро стиле и немного пиксель арта. Накидал базовых компонентов, определился с шрифтами, накидал встроенный отладочный терминал (думаю использовать его для отправки кастомных сообщений в nats) и добавил няшный лоадер.

Решил немного обновить интерфейс и порефакторить кода (видео) Решил немного обновить интерфейс и порефакторить кода (фото)
#121

Плюс для сенсоров и телеметрии nats -> telegraf -> influxdb -> grafana просто офигенно просто

#120

После пары дней которые я просидел с nats я в восторге от него. Настолько простой, легкий и удобный что я не понимаю как я до сих пор не пересекался с ним. У меня ощущение что это nginx из мира pubsub.

#119

Вздохнул свежим воздухом и перешел полностью на nats. Это мне дало:

  • выкинул webrtc (это прям гигантский кусок)

  • сигналинг сервер для webrtc

  • ros2 (куча кода)

  • странные билд скрипты для того чтобы запускать ros2 в докере и локально

  • на клиенте теперь websocket и nats

  • доступ ко всем топикам на клиенте

  • отсутствие сборки кастомных сообщений

  • видео передаются как кадры отдельными сообщениями

  • все отлично работает в докере и мониторится стандартными средствами типо prometheus и influxdb

  • узлы робота на любом языке в том числе typescript

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

  • выкинуть ros2 стало лучшим решением

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

  • из минусов пришлось отказаться от foxglove, но я думаю что попробу написать для него bridge

#118

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

Вчера я удалил полностью из репозитория весь код который я и ллм написали за неделю (несколько тысяч строк).

#117

Спустя примерно неделю изучения и ROS2 как фреимворка и экосистемы я сдался и пока забил на него. Меня удивляет как это стало стандартом индустрии. Я попробовал отделить ощущения которые я испытывал из за отвержения чего то нового от реальных сложностей которые новички испытывают при изучении ROS2.

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

#116

Начинается веселье с jetson orin nano. Свежий docker не работает и падает с ошибкой:

failed to solve: process "/bin/sh -c uv sync" did not complete successfully: failed to create endpoint laixim2p0a4udq2v8p15ez4p2 on network bridge: Unable to enable DIRECT ACCESS FILTERING - DROP rule:  (iptables failed: iptables --wait -t raw -A PREROUTING -d 172.17.0.2 ! -i docker0 -j DROP: iptables v1.8.7 (legacy): can't initialize iptables table `raw': Table does not exist (do you need to insmod?)
Perhaps iptables or your kernel needs to be upgraded.

https://forums.developer.nvidia.com/t/iptables-error-message/333007

Советуют

downgrade the docker to avoid the error

#114

На сегодня пока все. Он все еще не ездит но кажется что следующий мэилстон уже виден.

На сегодня пока все (фото 1) На сегодня пока все (фото 2) На сегодня пока все (фото 3)
#113

При этом серво руля подключается через PCA9685 и напрямую к пинам jetson. Но распаивать много проводов не очень хочется поэтому купил i2c expansion board. Удобно еще добавлю i2c. К тому же ground гребенка оказалась очень удобной чтобы замкнуть все GND вместе на всех платках.

При этом серво руля подключается через PCA9685 и напрямую… (фото)
#112

Хочу 4 таких сенсора. Один между роботом и батареей, и 3 других после step down dc конверторов:

  • задние моторы
  • nvidia jetson
  • все серво приводы (рука и руль) но может разделю их потом

4 сенсора и все они по умолчанию имеют один и тот же i2c адрес. Это можно поменять запаяв перемычки на breakout плате. Но мне не очень нравится. Поэтому я купил i2c multiplexer. Изначально я думал что этот мультиплексор работает как роутер и поддерживает виртуальные адреса. То есть например сам мультиплексор имеет адрес 0x40 и поддерживает внутреннее виртуальные пространство адресов и позволяет подключать чипы с одними именами обращаясь к ним по индексам групп пинов при этом можно писать и читать во все устройства одновременно. Но это работает не так. По сути это просто 8 канальный свитч который программно можно переключать. Но это тоже не проблема потому что чтение со всех сенсоров можно очень просто реализовать циклом который проходит по всем включенным каналом читает показание с одного и того же адреса и записывает в ros2 топик и потом в influxdb. Все это примерно 20 строк на питоне и можно запустить в отдельном докер контейнере.

#111

Разобрался как работает ina226 - сенсор тока который можно читать по i2c. Все достаточно несложно но по умолчанию в китайской breakout board идет R100 шунт что слишком много для измерения токов больших 819.175 mA. Хотя мощности хватает и с ним ничего не будет но данные будут отрезаны. Но это очень просто пофиксить перепаяв шунт на R010 (мΩ). После этого за счет падения точности можно будет мерить токи до 8.2A. Это конечно оверкилл то но 0.8A тоже слишком мало. Заказал R010 2512 (в SMD форм факторе) на алике потому что в jaycar как обычно ничего нету.

Разобрался как работает ina226 - сенсор тока который можно… (фото 1) Разобрался как работает ina226 - сенсор тока который можно… (фото 2)
#109

Заказал новые с Амазона уже нужного размера. Через несколько дней пришли такого же размера🤦‍♂️ как блин так получается?

#108

Надо написать setup.sh чтобы бутстрапить робота с нуля. В четвертый раз настраивать ssh, wg и все пакеты я не осилю.

#107

Прикинул все платы на акриле и закрепил некоторые из них на стендоффы. Вроде все влезло, но надо будет еще подумать над лейаутом.

Прикинул все платы на акриле и закрепил некоторые из них… (фото 1) Прикинул все платы на акриле и закрепил некоторые из них… (фото 2) Прикинул все платы на акриле и закрепил некоторые из них… (фото 3)
#106

Еще сегодня забрал порезанный лазером акрил. Получилось идеально и очень аккуратно. Для этой версии буду сверлить отверстия вручную, а для следующий версии разрисую в CAD все отверстия чтобы все получилось идеально.

Еще сегодня забрал порезанный лазером акрил (фото 1) Еще сегодня забрал порезанный лазером акрил (фото 2) Еще сегодня забрал порезанный лазером акрил (фото 3) Еще сегодня забрал порезанный лазером акрил (фото 4)
#105

Пытался подружить камеру от rpi с jetson но ничего не получилось. Ну да ладно, дождусь zed и тогда уже сделаю нормально.

Пытался подружить камеру от rpi с jetson но ничего не… (фото 1) Пытался подружить камеру от rpi с jetson но ничего не… (фото 2) Пытался подружить камеру от rpi с jetson но ничего не… (фото 3)
#104

Доехала литиевая смазка. Смазал все двигающие части.

Доехала литиевая смазка (фото 1) Доехала литиевая смазка (фото 2)
#102

Чет не очень нравится как получается резать листы акрилла лобизком. Решил попробовать заказать лазерную резку.

Чет не очень нравится как получается резать листы акрилла… (фото)
#101

Поменял пластиковые ступицы рулевого управления на алюминиевые и под цвет механической руки.

Поменял пластиковые ступицы рулевого управления на… (фото 1) Поменял пластиковые ступицы рулевого управления на… (фото 2) Поменял пластиковые ступицы рулевого управления на… (фото 3)
#100

На сегодня все, вот так это пока выглядит, но будет еще будет еще промежуточный этаж где будет находится nvidia jetson и пара других плат.

На сегодня все, вот так это пока выглядит, но будет еще… (фото)
#99

Дальше хочу разместить все платы на акриловых пластинах. Выпилил лобзиком нужную форму, просверлил дырки и нарезал резьбу чтобы вкрутить стендоффы.

Дальше хочу разместить все платы на акриловых пластинах (фото 1) Дальше хочу разместить все платы на акриловых пластинах (фото 2) Дальше хочу разместить все платы на акриловых пластинах (фото 3) Дальше хочу разместить все платы на акриловых пластинах (фото 4) Дальше хочу разместить все платы на акриловых пластинах (фото 5)
#98

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

Вот так это выгляди в первом приближении (видео)
#97

Очень повезло с тем что отверстия на металлической пластине почти идеально совпали с v plate. Единственное для надежности просверлил пару дырок M4.

Очень повезло с тем что отверстия на металлической… (фото 1) Очень повезло с тем что отверстия на металлической… (фото 2)
#96

Разобрал полностью робота и начал собирать руку

Разобрал полностью робота и начал собирать руку (фото 1) Разобрал полностью робота и начал собирать руку (фото 2) Разобрал полностью робота и начал собирать руку (фото 3) Разобрал полностью робота и начал собирать руку (фото 4) Разобрал полностью робота и начал собирать руку (фото 5) Разобрал полностью робота и начал собирать руку (фото 6)
#95

Кажется пришла пора разбирать первый прототип и начать собирать новый v0.0.2

Кажется пришла пора разбирать первый прототип и начать… (фото)
#94

И последнее - диски по металлу и тапы для нарезания резьбы. Попробую разместить все электронику компактно и надежно.

И последнее - диски по металлу и тапы для нарезания резьбы (фото)
#93

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

И наконец доехали шариковые наконечники для рулевого линка (фото)
#92

Так как i2c поддерживает адресацию можно просто распараллелить пины поменяв адреса устройств. Для этого есть такой маленький и удобный 10 канальный девайс.

Так как i2c поддерживает адресацию можно просто… (фото)
#91

Из более интересного - ina226 i2c. Простыми словами сенсор напряжения чтобы читать напряжение и ток по i2c и выводить напряжение на дешборде робота. Телеметрии никогда не бывает много.

Из более интересного - ina226 i2c (фото)
#90

Так же продолжался с barel jack для питания jetson. Приехал не тот диаметр 🤦‍♂️

Так же продолжался с barel jack для питания jetson (фото)
#89

Так же доехали короткие провода dupont и разноцветные пины. Не терпится уже начать сборку версии 0.0.2

Так же доехали короткие провода dupont и разноцветные пины (фото)
#88

Каждый раз заказывая с AliExpress я получаю что то не то. Это уже становится смешно. Я хотел чуть получше развести gpio пины и заказ 40 пиновый хедер. Но вместо это получил хедер с двумя рядами по 40 вместо 40 суммарно. Окей, til.

Каждый раз заказывая с AliExpress я получаю что то не то (фото)
#87

А это безумный контроллер моторов roboclaw 2x30 который поддерживает до 30 ампер и может работать с энкодерами через uart или usb. Можно было бы наверное обойтись чем то попроще но выглядит он конечно внушительно и классно.

А это безумный контроллер моторов roboclaw 2x30 который… (фото)
#86

Силиконовые standoffs оказались невероятно удобными для монтажа плат на роботе.

Силиконовые standoffs оказались невероятно удобными для… (фото)
#85

Просто незаменимая вещь при прототипировании. Даже не знаю что бы без нее делал.

Просто незаменимая вещь при прототипировании (фото)
#84

Немного еще фоток которые забыл запостить в самом начале процесса

Немного еще фоток которые забыл запостить в самом начале… (фото)
#83

Вот кстати зарядник с балансировкой для lipo который мне уже не нужен. Может быть когда нибудь займусь дронами или rc машинами тогда может еще пригодиться.

Вот кстати зарядник с балансировкой для lipo который мне… (фото)
#82

Спустя 2 дня разобрался с webrtc протоколам который собираюсь использовать для стрима картинки с камеры робота и управления роботом из браузера. Конечно это не просто http сервер с запросами и ответами. К этому моменту уже наткнулся на кучу эджкейсов и поведении при реконнектах и перезагрузках. Начинал с умного сигналинг сервера но пришел к тупому бродкасту сообщение через websocket.

Результат на экране. Терминал снизу слева это скрипт на питоне который шлет offer, браузер слева - ui робота к которому подключен dualsense. После установки соединения команды с джойстика отправляются через webrtc в python скрипт через data channel и там пока просто логируются.

Спустя 2 дня разобрался с webrtc протоколам который… (видео)
#81

Очень долго пытался подружить эти rpi csi камеру с ubuntu но нифига не получилось. Решил попробовать с официальным линуксом для rpi и все завелось с первого раза. Видимо долго еще я буду с ней мучаться пока не накоплю денег на zed 2i. Плюс у jetson немного другой разъем под csi и придется заказывать переходник.

Очень долго пытался подружить эти rpi csi камеру с ubuntu… (видео)
#80

GPD WIN4 выглядит как идеальный контроллер для робота. Цена конечно конская но полноценный компьютер с клавой довольно привлекательный.

GPD WIN4 выглядит как идеальный контроллер для робота (фото)
#79

Вот кстати jetson в recovery mode при перепрошивке. Для перевода в этот режим надо замкнуть 2 контакта.

Вот кстати jetson в recovery mode при перепрошивке (фото)
#78

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

Она довольно тяжелая и высокая, поэтому придется завести… (фото 1) Она довольно тяжелая и высокая, поэтому придется завести… (фото 2)
#77

Так же я взял V plate к ней чтобы надежно закрепить его на роботе.

Так же я взял V plate к ней чтобы надежно закрепить его на… (фото 1) Так же я взял V plate к ней чтобы надежно закрепить его на… (фото 2) Так же я взял V plate к ней чтобы надежно закрепить его на… (фото 3)
#76

Насчет питания. Изначально я думал использовать rc lipo на 7000mah но решил отойти от этой идеи. Меня немного напрягает что эти батареи могут быть (хотя и маловероятно) довольно опасными. Заряжать их надо под присмотром, в них нет встроенного BMS. Но они дают куда больший ток разрядки (мне скорее всего не надо будет > 10А) и намного легче чем стопка 18650. Долго выбирал и в итоге наткнулся на V mount батареи которые используются в профессиональной видеосъемке. Это уже собранные аккумы 18650 со встроенной BMS. Они могут выжать 14.45В при 14А что выглядит более чем достаточно при этом имеют очень неплохой объем.

Насчет питания (фото)
#75

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

В конечном итоге увидел этот заветный экран (фото)
#74

Смог прошить его только с 3 раза, при этом каждый раз это занимало минут 30. Каждый раз отваливалось что то новые. Оказалось проблемы были из за wireguard, ufw то ssh отвалится.

Смог прошить его только с 3 раза, при этом каждый раз это… (фото)
#73

В итоге вернулся к варианту с nvidia sdk manager

В итоге вернулся к варианту с nvidia sdk manager (фото)
#72

Для этого использовал свой cube с ubuntu. Из за того что у cube только 1 слот под nvme m.2 пришлось загружать систему со флешки используя try ubuntu. После этого поправил конфиги лоадера и bios. Но система отказывалась загружаться. Посидев часа 2 с ChatGPT так и не смог пофиксить это.

Для этого использовал свой cube с ubuntu (фото)
#71

Потратил 2 дня чтобы поставить L4T на jetson. Это оказалось куда сложнее чем я думал. Сначала наивно полагал что смогу просто нарезать образ для SD карты на nvme и подправить BIOS чтобы загрузиться с него но это не получилось.

Потратил 2 дня чтобы поставить L4T на jetson (фото 1) Потратил 2 дня чтобы поставить L4T на jetson (фото 2)
#70

Обзовется NVIDIA Jetson Orin Nano super dev kit. Пока не столько из за того что уперся в потолок rpi4 а скорее чтобы представлять размер и будущее расположение печатных плат на роботе.

Обзовется NVIDIA Jetson Orin Nano super dev kit (фото)
#69

Расписал и разрисовал немого схему и план того что делаю чтобы не теряться во всем этом

Расписал и разрисовал немого схему и план того что делаю… (фото)
#67

Чтобы понимать примерно лейаут располжения компонентов надо было примерно определиться с батарей. Пока остановился на следующих моделях из котрыйх скорее всего посмотрю на Gens Ace Redline 4S от 5000mAh с bullet разъемом. Хотя мне не надо такой большой ток разрадки но найти что то меньше с похожим объекмом сложно. Gens Ace Redline 4S

#66

Кривая разряда батарей не совсем линейная но тем не менее можно примерно оценить оставшийся заряд в процентах. Этот экран будет стоять на роботе чтобы примерно представлять не глядя в UI. Для отображения телеметрии на дешборде надо будет добавить делитель напряжения и АЦП. Он будет через I2C отправлять данные на rpi где уже будет простая математика чтобы посчитать проценты по вольтажу и отправлять данные в топик ros2. Откуда оно уже будет читаться дешбордами или контролплейном.

Кривая разряда батарей не совсем линейная но тем не менее… (фото)
#65

На реле можно задать параметры напряжения UP/DOWN. Реле включается если напряжение больше 11.4V и выключается при напряжении ниже 10.5V. Такой своеобразный гистерезис чтобы не мигать при переходе через порог.

На реле можно задать параметры напряжения UP/DOWN (видео)
#64

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

Возвращаясь к электрике (фото)
#63

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

#62

Кажется я начинаю уходить в сторону и распыляться на такие штуки. Это не плохо но надо бы сначала доделать базовую кинематику и уже потом заниматься такой тонкой доработкой.

#61

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

#60

Будет классно конечно переделать весь руль и избавиться от пластика совсем

#59

С линками тоже нет проблем и стоят копейки

С линками тоже нет проблем и стоят копейки (фото)
#58

Надо посмотреть по размер и форме но найти алюминиевый или медный кулачок вроде не проблема.

Надо посмотреть по размер и форме но найти алюминиевый или… (фото)
#57

Немного подбешивает что steering knuckle и steering linkage пластиковые и хлипкие. Особенно кулачок в steering linkage. Мне кажется я уже сорвал с него резьбу пока несколько раз разбирал рулевой механизм пока настраивал и менял серво. Решил посмотреть что есть на алике и открыл для себя целый новый мир.

#56

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

#55

Думаю купить несколько акриловых пластин и вырезать в аккурат с этой пластиной чтобы было аккуратнее и сделать многослойную вафлю и маунтить компоненты с обоих сторон.

Думаю купить несколько акриловых пластин и вырезать в… (фото)
#54

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

Я освободил переднюю часть чтобы чуть позже установить… (фото)
#53

Так же дождался наконец то с алика 3 штуки которые хотел спаять до перевода робота на lipo 4s

Слево discharge контроллер с экраном на который можно вывести напряжение и процент заряда и эстимейт по времени если задать параметры батареи. При достижении нижнего порога реле обесточивает цепь чтобы не переразряжать батарею. Это не очень полезно для lipo.

Снизу просто массив выключателей чтобы можно было питать все ноды по отдельности и выключать некоторые при необходимости. Их уже сейчас 4 а скоро будет минимум 8.

И справа АЦП (ADC) чтобы воткнуть его в цепь уже считывать напряжение на rpi и слать в топик ros2. Чтобы няшно отображать уровень батареи в UI.

Так же дождался наконец то с алика 3 штуки которые хотел… (фото)
#49

Список покупок:

  • pan tilt servo kit
  • xArm ESP32 Bus Servo Robotic Arm
#48

Как раз у меня еще много свободных пинов в в PCA9685.

#47

Идея разместить ее на 2 серво чтобы управлять обзором через стик джоя. Называется это pan tilt servo kit.

#46

Нашел у себя CSI камеру для rpi которую купил для какого то проекта но никогда не использовал. Попробовал подключить и написать простенький webrtc сервер чтобы стримить поток в браузер на девайс с джоем. После 3 часов пока что получил только зеленый экран.

#45

Dualsense отличный джой но там нет экрана что не очень удобно. Кажется неплохой кандидат - анберник на линуксе и запуск UI в вебе rg552

#44

На следующей неделе попробую перевести проект на ros2 но без их сборщика и структуры проекта. Попробую использовать docker и ros2 как библиотеку.

#43

Идея что джой шлет события в трубу и другие ноды просто подписываются на топики и реагирует прекрасна.

#42

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

#41

Есть еще docker compose watch mode но пока чет не разобрался с ним, может вернусь попозже

#40

Перевел весть проект на docker compose и uv стало попроще менеджить зависимости и можно удобно прокнить девайсы через маппинг:

services:
  rabbit:
    build: .
    volumes:
      - ./src:/app/src
    devices:
      - '/dev/input/event0:/dev/joy'
      - '/dev/ttyAMA0:/dev/roboclaw'
    privileged: true
    command: uv run /app/src/main.py
    stdin_open: true
    tty: true
#39

Надо бы закрепить PCBишки на vertical/horizontal mount на акрилловую или другую пластину на которой можно будет легко сверлить отверстия и прикрутить к ней другие компоненты. При этом шасси робота не будет сверлиться и не будет повреждено в случае переделки.

#38

По идее можно заменить моторы и поставить bldc но надо будет менять контроллер.

#37

Первая поездка. Руль немного не сбалансирован, угол поворота слишком маленький, надо бы увеличить и подрегулировать импульсы pwm. Моторы чет медленные, надо или увеличить колеса или взять другие редукторы. Но в целом очень рад что он поехал.

Первая поездка (видео)
#36

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

Сервы я уже тестировал до этого но сейчас нормально… (видео)
#35

Для питания LM2596 step down dc dc на 6V

Для питания LM2596 step down dc dc на 6V (фото)
#34

Управлять сервой буду через PWM, i2c и PCA9685

#33

Серво у меня 1501MG довольно дешевая и громкая. Как придет поменяю но пока что есть.

#32

А да, я сначала начал писать код прямо на rpi через ssh но многие вещи не работали нормально в vscode поэтому решил разрабатывать локально на mac но синкать файлы с помощью mutagen. Довольно простая и классная тулза. Еще один инструмент в тулбокс.

#31

Теперь надо заняться серво и подружить его со стиками.

#30

Я добавил настроку в 1с таймаута в roboclaw чтобы моторы останавливался если контроллер не получал команды в течении 1 секунды. Это надо чтобы избежать залипаний если вдруг программа крашится или есть как то баг.

#29

В итоге получился просто питон скрипт с 3 классами (rabbit, joy и roboclaw) и 2 треда с циклами (один слушает джой обновляя стейт, другой посылает команды в бесконечном цикле в roboclaw по UART)

#28

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

#27

Подключить контроллер оказалось просто и завелось все с первого раза. На R2 курок думаю сделать движение вперед. Диапазон значений от 0 до 255 можно нормализовать для диапазона для roboclaw (-32767, 32767) простой формулой.

#26

Для управления через PS5 dualsense пока решил не заморачиваться с bluetooth тем более что конечная цель - управление через интернет для bluetooth.

#25

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

#24

Резисторы для 5V -> 3.3V делителя. Пришлось вспомнить закон Ома 🤔

Резисторы для 5V -> 3.3V делителя (фото 1) Резисторы для 5V -> 3.3V делителя (фото 2)
#23

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

Первый запуск прошел не очень удачно так как один провод… (видео)
#22

Сначала думал питать rpi напрямую от gpio 2 или 4 но решил отказаться от этой идеи чтобы случайно не спалить. В итоге взял степ даун регулятор polou 5V D24V90F5 и распаял usbc кабель чтобы соединить их. Наверное это тоже можно сделать чуть аккуратнее.

Сначала думал питать rpi напрямую от gpio 2 или 4 но решил… (фото)
#21

До этого еще распаял делитель напряжения чтобы соединить RX rpi и roboclaw из за того что они работают на разных уровнях: 3V и 5V. Но уже заменил на понижайку.

До этого еще распаял делитель напряжения чтобы соединить… (фото)
#20

Для сервы добавил LM2596 и настроил его на 6В как посоветовал папа. Надо будет заказать еще несколько таких только с экранчиком чтобы было удобно мониторить вольтаж без мультиметра.

Для сервы добавил LM2596 и настроил его на 6В как… (видео)
#19

Распаял общий GND для всех элементов по дупонт пины

Распаял общий GND для всех элементов по дупонт пины (фото 1) Распаял общий GND для всех элементов по дупонт пины (фото 2)
#18

Немного пришлось увеличить дырки под M3

Немного пришлось увеличить дырки под M3 (фото)
#17

rpi я разобрал сняв с него heating sink но наклеив радиаторы

rpi я разобрал сняв с него heating sink но наклеив радиаторы (фото)
#16

Возвращаясь назад к плате. Я очень удачно заказал с амазона нейлоновые стендоффы. Во первых я пофиксил рулевой механизм немного удлинив плечи. Во вторых с помощью них очень удобно разместить все pcbишки на прототипной борде.

Возвращаясь назад к плате (фото 1) Возвращаясь назад к плате (фото 2) Возвращаясь назад к плате (фото 3)
#15

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

May 25 01:36:39 rabbit kernel: hwmon hwmon2: Undervoltage detected!
May 25 01:36:41 rabbit kernel: hwmon hwmon2: Voltage normalised

что говорит о проблеме. Попробую поднять максимум до 3 - 4 А и посмотрим как пойдет дело.

Про это немного позже, но оказалось что забыл повысить… (видео)
#14

Сегодня прям неплохой прогресс. Купил 3 прототайп борты и соединил вместе.

Сегодня прям неплохой прогресс (фото)
#13

Пока думаю остановиться на prototype board и пока все собрать на ней. Хотя бы будет понятен лейаут и будет чуть проще потом разложить все.

#12

Начал задумываться над кастомной PCB и расчехлить лазерный утюг. Посидел с KiCad и понял, что пока рано - слишком много деталей я пока не понимаю. Отложу, пока не появятся MCP для PCB-CAD или не созрею окончательно. Может, Claude когда-нибудь научится разводить платы.

#10

Пока конечно все на соплях и макетке - надо наверное все это распаять на нормальном текстолите с правильными дорожками вместо проводов. Но сначала надо хотя бы заставить это все ехать. Один шаг за раз!

#9

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

#8

Проблема была в том, что я по глупости купил TXB0104, думая, что этот преобразователь уровней заработает с UART и позволит подключить RX RoboClaw (который работает на 5V), но не получилось. Отключил и оставил только TX 3.3V от Raspberry Pi.

#6

RoboClaw не останавливается, если скрипт крашнулся - опасно! Надо обязательно включать RC timeout и слать команды в цикле.

#5

Узнал, что есть 2 способа работать с DualSense из браузера: Gamepad API (стандартный, но ограниченный) и WebHID API (полный доступ к всем фичам).

#4

Как оказалось, у Raspberry Pi всего один PWM-выход, что ОК для тестов, но я все-таки заказал 16-канальный PWM-драйвер PCA9685, чтобы уж наверняка на случай, если еще добавлю серво. Лучше переборщить, чем потом паять костыли.

#3

Планировал сегодня запустить рулевой серво и попробовать его повернуть через Raspberry Pi, но Amazon не довез олово, и придется подождать с пайкой.

#2

Заказал с AliExpress и Amazon некоторые базовые компоненты и инструменты для сборки.

Заказал с AliExpress и Amazon некоторые базовые компоненты… (фото)
#1

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