Продолжение поста «Киберпанк, который мы заслужили»42
Робот-собака DOGZILLA YAHBOOM для Raspberry Pi 5
Робот-собака DOGZILLA YAHBOOM для Raspberry Pi 5
Микроконтроллер RP2040, использованы библиотеки helix mp3 и adafruit_floppy
Сегодня хочу рассказать про одного из своих роботов, которого я собирал еще до открытия мастерской.
Однажды у меня была температура, и я не мог уснуть. Мозг счел это самым подходящим временем чтобы объяснить мне, что жить так дальше нельзя, нужно что-то менять. А следом он убедил меня, что самым правильным способом изменения жизни будет создание колесного беспилотника и запуск его в сторону Ханты-Мансийска по тундре.
Голоса в голове говорили: беспилотник будет ехать, делать фотографии российской тундры, а я буду эти фотографии продавать в журналы. Вот тебе и деньги. Нужно было только решить вопрос со связью и защитой от белых медведей.
Все логично, че.
Как ни странно, идея с беспилотником не отпустила меня и после выздоровления. И я начал изучать вопрос.
Первая версия была на Arduino, с управлением через nrf24l01.
Затем я открыл для себя Ardupilot. У него есть версия Ardurover для колесных и гусеничных беспилотников.
Был куплен полетный контроллер Pixhawk 2.4.8 и три гироскутера. Из гироскутеров я выдрал колеса.
Сварил раму их профильной трубы. По итогу получился такой агрегат:
Этот уже уверенно колесил по лесу и огороду. Соседи смотрели сквозь забор и очковали.
При загрузке полетного (или проездного) задания мой агрегат уже пытался ехать в заданную точку. Результатом одной такой поездки оказался контакт с соседским Опелем. Пришлось платить деньги за ремонт. Теперь уже очковал я.
Забрать такую большую штуку в съемную однушку было нельзя, и я снял с него автопилот. Была сделана гусеничная версия меньшего размера. На видео есть звук, можно послушать как робот пока еще подчиняется мне.
Тут я уже прицепил компьютер-компаньон Raspberry PI 5 и микрофон. Была установлена ROS2 Humble. Общение между полетный контроллером Pixhawk 2.4.8 и Raspberry осуществляется по протоколу pymavlink. Были реализованы топики по приему сигналов с пульта и голосовых команд. Для распознавания голосовых команд использовал нейросеть Vosk.
Дополнительно поставил лидар, но он пока не настроен. Так же приобрел камеру глубины. На видео камеры нет, но я настраивал простое поведение: при появлении в камере человека робот снимается с охраны (disarm) и готов к движению. Для распознавания объектов использовал нейросеть YOLO8.
Сейчас робот на модернизации. Так как у меня появились чпу и другое оборудование, я хочу сделать уже версию в металле. Эта собрана из станочного профиля и пластиковых деталей, отпечатанных на 3D-принтере. Гусеницы печатал из TPU, остальное из PETG.
Если есть вопросы - задавайте. Буду рад ответить.
На алике сейчас продают гиковские часы производства небезызвестной LCTech (компания разрабатывает SBC и всякие DIY ништяки). Их основная фишка в том, что с ними в комплекте нет прошивки (кроме референсной) - предполагается что гик напишет ее сам под свои нужды.
Схемотехника часов предельно простая, но в целом грамотная. На доске расположился сам микроконтроллер RP2040, состоящий из двух ядер Cortex-M0+, способных работать на частоте до ~300МГц, SPI-флэшка объемом аж в 4МБ (это хороший объем), чарджер литиевых аккумуляторов TP4056, LDO, опорный кварц и гироскоп QMI8658. Fuel gauge нет - вместо него VBat подключен к ADC микроконтроллера через 10k делитель.
Референсная прошивка написана на C, есть также сэмпл на MicroPython. Но как мы с вами знаем, я не пишу прошивки на китайских фреймворках и для DIY пилю все с нуля - в том числе и драйверы для периферии. Сейчас буду потихоньку разбираться, писать для них прошивку и затем выпущу здоровенный материал. Такой же, как в свое время про GamePi :)
Цена таких часиков - 1900 рублей, в комплекте есть ремешок, но нет корпуса. Очевидно что это устройство исключительно для гиков и не подойдёт обычному юзеру.
Как узнал про overlay filesystem — и спешу поделиться с вами
Или история о том, как я перестал хоронить SD-карты каждый год
Фабула
Перепробовав кучу одноплатников — Orange Pi, Banana Pi, несколько Raspberry Pi — я каждый раз упирался в одну и ту же проблему: microSD-карта дохнет меньше чем за год. Полгода-год, и игрушка молча умирает: то SSH не пускает, то читает-пишет через раз.
И как-то всё руки не доходили заняться проблемой. Пока недавно не вылетела очередная SD-карта. Сегодня я узнал про overlay-filesystem — и спешу поделиться находкой.
Опытные линуксоиды, конечно, улыбнутся, но этот опыт я хочу запечатлеть прежде всего для себя — а вдруг ещё кому пригодится. Также, стараюсь описать все максимально подробно - для совсем новичков. Статья, конечно, на 70% состоит из возни с разделами файловой системы, про overlay тут только в самом конце, но это может тоже кому то пригодиться.
Операционка в read‑only — корневая файловая система монтируется только на чтение. Ничего не пишется на SD-карту без явного на то желания пользователя.
Всё временное — в оперативку. Логи, настройки, эксперименты, содержимое /var и /tmp — живут в памяти и бесследно исчезают после выключения. Никакого мусора.
Откат при перезагрузке. После ребута система как новенькая — никаких хвостов от случайно установленного пакета или кривого конфига.
Простота доработки. Поставить пакет, поправить конфиг, обновиться — без плясок с монтированием. Как это сделать — расскажу ниже.
Отдельный rw‑раздел для данных — «на всякий случай». Туда можно спокойно копировать файлы по SSH, не думая о том, поместятся ли они в оперативку. Этот раздел будет переживать перезагрузки.
Raspberry Pi Zero W
Raspberry Pi OS Lite
SD-карточка на 32Gb (8Gb на операционку, остальное - в RW разделе)
Ubuntu server 26.04 на виртуальной машине VirtualBox (просто уже стояла, подойдет любой современный дистрибутив)
Думаю, что тут справится любой, кто имел хоть какое-то знакомство с Raspberry Pi. Скачиваем Raspberry Pi imager, вставляем SD-карту в компьютер, выбираем нашу версию платы, настраиваем, ждем, пока образ запишется на карту.
После этого вставляем SD-карточку в Raspberry Pi, дожидаемся загрузки (логина по ssh или появления десктопа), выключаем, вытаскиваем карточку. Тут можно, конечно, сделать сразу все необходимые манипуляции с операционкой - установить пакеты, настроить, но мы можем это сделать и потом.
Грузим виртуалку, выводим список доступных /dev/sd*, подключаем SD-карточку, находим искомое устройство:
$ ls -la /dev/sd*
brw-rw---- 1 root disk 8, 0 May 9 18:48 /dev/sda
brw-rw---- 1 root disk 8, 1 May 9 18:48 /dev/sda1
brw-rw---- 1 root disk 8, 2 May 9 18:48 /dev/sda2
<подключаем SD-карту>
$ ls -la /dev/sd*
brw-rw---- 1 root disk 8, 0 May 9 18:48 /dev/sda
brw-rw---- 1 root disk 8, 1 May 9 18:48 /dev/sda1
brw-rw---- 1 root disk 8, 2 May 9 18:48 /dev/sda2
brw-rw---- 1 root disk 8, 16 May 9 18:49 /dev/sdb
brw-rw---- 1 root disk 8, 17 May 9 18:49 /dev/sdb1
brw-rw---- 1 root disk 8, 18 May 9 18:49 /dev/sdb2
Paspberry Pi при записи образа создает два раздела - один для удобной настройки (файловая система FAT), другой - непосредственно системный (ext4). Их мы и видим в списке: /dev/sdb1 и /dev/sdb2.
Вероятнее всего, нам нужен второй раздел, но на всякий случай перепроверим: подмонтируем его, проверим размер и отмонтируем:
# sudo mount /dev/sdb2 /mnt
$ df -h /mnt
Filesystem Size Used Avail Use% Mounted on
/dev/sdb2 29G 2.3G 25G 9% /mnt
# sudo umount /dev/sdb2
Видим, что общий размер 29Gb, занято системой ~2.3Gb. Оно.
Правильный порядок действий при изменении размера (особенно уменьшении) выглядит так:
Проверилиr файловую систему
Уменьшили саму файловую систему
Уменьшили раздел так, чтобы он совпал с новым размером ФС
Начнем с проверки файловой системы. Запускаем и ждём завершения:
# sudo e2fsck -f /dev/sdb2
e2fsck 1.47.2 (1-Jan-2025)
Pass 1: Checking inodes, blocks, and sizes
Pass 2: Checking directory structure
Pass 3: Checking directory connectivity
Pass 4: Checking reference counts
Pass 5: Checking group summary information
rootfs: 74119/1847360 files (0.2% non-contiguous), 715247/7506944 blocks
После завершения - задаем новой размер файловой системы в 8Gb:
# sudo resize2fs /dev/sdb2 8G
resize2fs 1.47.2 (1-Jan-2025)
Resizing the filesystem on /dev/sdb2 to 2097152 (4k) blocks.
The filesystem on /dev/sdb2 is now 2097152 (4k) blocks long.
Наша файловая система занимает 2097152 блоков размером 4К (или 4096 байт). Эти числа нам пригодятся в будущем. Теперь нужно разделить диск на 2 части - одну оставить для системы, вторую - для нашего RW раздела. Итак, запускаем fdisk на устройстве /dev/sdb
#sudo fdisk /dev/sdb
Welcome to fdisk (util-linux 2.41.3).
Changes will remain in memory only, until you decide to write them.
Be careful before using the write command.
Command (m for help): __
Утилита запускается, и просит ввести команду. Сначала перепроверим разделы и узнаем их номера. Вводим команду p (печать разделов):
Command (m for help): p
Disk /dev/sdb: 29.14 GiB, 31293702144 bytes, 61120512 sectors
Disk model: STORAGE DEVICE
Units: sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disklabel type: dos
Disk identifier: 0x9298fc3d
Device Boot Start End Sectors Size Id Type
/dev/sdb1 16384 1064959 1048576 512M c W95 FAT32 (LBA)
/dev/sdb2 1064960 61120511 60055552 28.6G 83 Linux
Мы видим boot раздел в FAT32 (для настройки параметров raspberry pi) и linux-раздел с основной файловой системой. Также видим, что размер сектора тут - 512 байт. Это тоже нам пригодится.
Теперь аккуратно удаляем второй раздел:
Command (m for help): d
Partition number (1,2, default 2): 2
Partition 2 has been deleted.
Теперь нужно создать новый раздел нужного размера (8Gb). Для этого нужно знать его начало (в секторах по 512 байт) и его конец (также в секторах по 512 байт).
Начало раздела мы знаем из результата выполнения команды p выше: 1064960. Нужно расчитать конец. Из результата выполнения команды resize2fs нам известно, что наша файловая система занимает 2097152 4096-байтных блоков.
Пересчитаем это в 512-байтные: 2097152 * 4096 / 512 = 16777216.
Добавив к этому значению начало сектора, получим номер конечного сектора:
16777216 + 1064960 = 17842176
Создадим новый системный раздел взамен удалённого ранее командой n, указав, что нужен primary-раздел (p) и номер 2. Введем номер первого сектора 1064960 и последнего 17842176.
Важно - см. последнюю строку!
Не удаляем предыдущую сигнатуру, иначе файловая система будет уничтожена -> вводим N!
Command (m for help): n
Partition type
p primary (1 primary, 0 extended, 3 free)
e extended (container for logical partitions)
Select (default p): p
Partition number (2-4, default 2): 2
First sector (2048-61120511, default 2048): 1064960
Last sector, +/-sectors or +/-size{K,M,G,T,P} (1064960-61120511, default 61120511): 17842176
Created a new partition 2 of type 'Linux' and of size 8 GiB.
Partition #2 contains a ext4 signature.
Do you want to remove the signature? [Y]es/[N]o: N
Теперь создаем новый раздел - для пользовательских данных (RW) на всю оставшуюся часть флешки. Номер раздела - третий. Начальный сектор будет (конечный-для-раздела-2 + 1), то есть 17842176 + 1 = 17842177, а конечный - пустой. fdisk автоматически подставит последний доступный сектор:
Command (m for help): n
Partition type
p primary (2 primary, 0 extended, 2 free)
e extended (container for logical partitions)
Select (default p): p
Partition number (3,4, default 3): 3
First sector (2048-61120511, default 2048): 17842177
Last sector, +/-sectors or +/-size{K,M,G,T,P} (17842177-61120511, default 61120511):
Created a new partition 3 of type 'Linux' and of size 20.6 GiB.
Все, что мы делали выше - пока не записалось на флешку и эти изменения только запланированы. Перед записью изменений еще раз все перепроверим, введя команду p снова:
Command (m for help): p
Disk /dev/sdb: 29.14 GiB, 31293702144 bytes, 61120512 sectors
Disk model: STORAGE DEVICE
Units: sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disklabel type: dos
Disk identifier: 0x9298fc3d
Device Boot Start End Sectors Size Id Type
/dev/sdb1 16384 1064959 1048576 512M c W95 FAT32 (LBA)
/dev/sdb2 1064960 17842176 16777217 8G 83 Linux
/dev/sdb3 17842177 61120511 43278335 20.6G 83 Linux
Все верно. boot раздел на месте, у системного начальный сектор остался тем же, размр изменился. Появился новый третий раздел на остаток. Запишем изменения, введя команду w:
Command (m for help): w
The partition table has been altered.
Calling ioctl() to re-read partition table.
Syncing disks.
Готово.
Теперь создадим файловую систему на новом разделе командой mkfs.ext4:
# sudo mkfs.ext4 /dev/sdb3
mke2fs 1.47.2 (1-Jan-2025)
Creating filesystem with 5409791 4k blocks and 1354560 inodes
Filesystem UUID: 378e7266-5fa3-4591-a2e5-5b5732bb047d
Superblock backups stored on blocks:
32768, 98304, 163840, 229376, 294912, 819200, 884736, 1605632, 2654208,
4096000
Allocating group tables: done
Writing inode tables: done
Creating journal (32768 blocks): done
Writing superblocks and filesystem accounting information: done
Извлекаем готовую флешку, выключаем виртуалку, она больше не понадобиться:
# sudo eject /dev/sdb
# sudo shutdown
Вставляем флешку в Raspberry Pi, включаем, логинимся.
Здесь я хочу сделать следующее: примонтировать user-раздел, сделать автоматическое монтирование при загрузке, включить overlay-режим файловой системы и сделать автоматическую перезагрузку устройства, дабы чистить память. Поехали!
В Raspberry Pi разделы флешки называются иначе, вот они:
$ ls -la /dev/mmcblk0*
brw-rw---- 1 root disk 179, 0 May 8 22:04 /dev/mmcblk0
brw-rw---- 1 root disk 179, 1 May 8 22:05 /dev/mmcblk0p1
brw-rw---- 1 root disk 179, 2 May 8 22:04 /dev/mmcblk0p2
brw-rw---- 1 root disk 179, 3 May 8 22:04 /dev/mmcblk0p3
/dev/mmcblk0 - устройство
/dev/mmcblk0p1 - boot-раздел
/dev/mmcblk0p2 - системный раздел
/dev/mmcblk0p3 - большой раздел для данных, RW.
Создаем новую точку монтирования для RW-раздела (/dev/mmcblk0p3). Я хочу, чтобы она была в корне файловой системы и открытая для записи от текущего пользователя:
# sudo mkdir /work
# sudo chown $(whoami):$(whoami) /work
# sudo chmod 700 /work
Создаем скрипт автоматического монтирования и открываем его на редактирования:
# sudo nano /etc/systemd/system/work.mount
ВАЖНО! Имя файла .mount должно строго соответствовать пути монтирования, в котором символы / заменяются на - (дефис), а начальный слэш опускается.
Примеры:
/work -> work.mount
/mnt/data -> mnt-data.mount
/var/lib/docker -> var-lib-docker.mount
Содержимое файла:
[Unit]
Description=Mount /dev/mmcblk0p3 on /work
DefaultDependencies=no
After=systemd-udevd.service
Requires=systemd-udevd.service
Before=local-fs.target
Before=umount.target
Conflicts=umount.target
[Mount]
What=/dev/mmcblk0p3
Where=/work
Type=ext4
Options=defaults,noatime
[Install]
WantedBy=local-fs.target
Нажимаем Ctrl + X, подтверждаем сохранение, Y:
Включаем mount-юнит, перезагружаемся чтобы проверить:
# sudo systemctl enable work.mount
Created symlink '/etc/systemd/system/local-fs.target.wants/work.mount' → '/etc/systemd/system/work.mount'.
# sudo reboot
Проверяем:
$ df -h
Filesystem Size Used Avail Use% Mounted on
...
/dev/mmcblk0p2 7.9G 2.3G 5.3G 30% /
/dev/mmcblk0p3 21G 2.1M 20G 1% /work
/dev/mmcblk0p1 505M 78M 427M 16% /boot/firmware
...
Все три раздела - там, где им нужно быть.
# sudo raspi-config
Идём в Perfomance options -> P2 Overlay file system Enable/disable read only file system
Стрелкой влево выбираем Yes:
Ждем пока доставятся пакеты ... Процесс завершился успешно:
Нажимаем Yes, если нам не нужно менять информацию на /boot разделе внутри самой системы (если вытащить флешку и вставить в компьютер - все будет работать в режиме чтения-записи):
Две стрелки вправо - <Finish>, соглашаемся с перезагрузкой...
После этого все изменения в системном разделе будут в оперативной памяти. Это очень удобно для экспериментов - пробуем что то настроить - не получается - перезагрузка и система "девственная".
Для того, чтобы перейди в "write" режим (записать конфиг, обновить систему, доставить пакеты и так далее ..) необходимо просто выполнить команду:
# sudo overlayroot-chroot
Сделать все необходимые действия и выйти из режима, на всякий случай сделав синхронизацию
# cd /
# sync
: Эти изменения запишуться в системный раздел.
Конечно же, система в процессе работы что-то записывает. И все эти записи помещаются в оперативку. На одноплатниках с оперативкой обычно довольно грустно, поэтому для автоматической очистки проще всего создать скрипт, который будет раз в сутки перезагружать нашу малину.
Откроем на запись наш системный раздел и добавим crontab, который выполняет автоматическую перезагрузку, например, в 4:00 ночи:
# sudo overlayroot-chroot
# crontab -e
Дописываем в конец:
0 4 * * * /usr/sbin/reboot
Ctrl+X, соглашаемся на запись ( Y ), видим что новый crontab установлен, синхронизируемся и выходим.
crontab: installing new crontab
# cd /
# sync
# exit
Вот и всё. Теперь ваша SD-карта живёт спокойно, система загружается в read-only, любые эксперименты умирают вместе с перезагрузкой, а для важных данных есть отдельный /work.
Если захотите что-то обновить или поставить — sudo overlayroot-chroot, сделали дело, вышли. Несложно.
Надеюсь, эта инструкция сэкономит вам пару нервных клеток и одну SD-карту в год.
Про железку:
купил я вот такую штуку - STM32H723ZGT6 (https://www.ozon.ru/product/1-sht-modul-otladochnoy-platy-s-...). Здоровая, сука!
И программатор к ней - клон ST-link V2 (https://www.ozon.ru/product/programmator-st-link-stlink-st-l...).
Через CUbeIDE прошить не могу - он наотрез отказывается скачивать что-то с интернета. В PlatformIO такой камень отсутствует, но есть Nucleo H723. Попробовал его с ST-link - не идет - ошибка. Вшитая с завода "мигалка светодиодом" успешно слетела, новая не встает, камень в защите. Выходит из защиты только если сделать st-info --probe с зажатым RESET, а потом отпустить и еще раз. Попытка стирания флеша проваливается. Или стирается, но новую прошивку не принимает.
Прошил rpi-pico на picoprobe, подключил через SWD, шил через openocd. Перешил на micropython, шил скриптом через uart. Никак.
Info : Listening on port 3333 for gdb connections [stm32h7x.cpu0]
halted due to debug-request, current mode: Thread
xPSR: 0x01000000 pc: 0xfffffffe msp: 0xfffffffc
Info : Device: STM32H72x/73x Info : flash size probed value 1024k Info : STM32H7 flash has a single bank Info : Bank (0) size is 1024 kb, base address is 0x08000000
Info : Bank (0) size is 1024 kb, base address is 0x08000000 Error: [stm32h7x.cpu0] clearing lockup after double fault [stm32h7x.cpu0] halted due to debug-request, current mode: Handler HardFault xPSR: 0x01000003 pc: 0xfffffffe msp: 0xffffffd8
В общем вот так. Основная проблема - не получается зашить в этот камень хоть что-то.
Чего делать то, выкинуть нахер?
Кто-нибудь уже успешно шил такую фигню?
Три года я делал браузерную игру, в которой игроки управляли настоящими RC‑машинками через браузер. В итоге у меня получилось: 9 самодельных машинок, помещение 110 м², около 70 м² трассы, RFID‑навигация, чекпоинты, видеострим с задержкой около 200 мс и полноценный запуск. За месяц зарегистрировалось около 500 человек. Платежей было примерно на 3000 рублей. Это история о том, как проект технически заработал, но как бизнес — нет. Расскажу, как я собирал машинки, боролся с видеозадержкой, клеил RFID‑метки на пол и какие выводы сделал после запуска.
Видео игры
Началось всё с игрового проекта в GTA Criminal Russia в 2012г., я просто купил у другого человека, готовый проект-код и поставил его на игровой хостинг и люди сами стали мне платить… длилось это 5 лет, ума и опыта как это масштабировать у меня не было, пришли более крупные игроки этого рынка и меня конкуренция не пощадила.
Продолжил я искать спрос… и нашёл игру у которой нет многопользовательского режима, связанная с городской ездой (виртуальная игра по типу гонок и свободной езды). На форумах этой игры сформировалась небольшая команда энтузистов, частью которой я стал. И так появился мод позволяющий сделать игру многопользовательской. К сожалению, мод долго не просуществовал, издатель игры дал ясно понять, что мододелы оскверняют его продукт. 3 года я потратил на данный проект.
В 2022 году, учась на 4-м курсе своего университета мне пришла идея, не покупать или заимствовать чужие наработки, а создать полностью свою игру! Полностью, с чистого листа, с нуля и в одиночку! И пришла в голову мне эта идея, когда я прочитал статью о проекте «Isotopium» и концепции игр Remote Reality я 100 раз перечитывал данную статью, и в этой части хочу поблагодарить администрацию хабра за существование такой площадки для таких Гиков как мы все с вами 😊.
Потратив много времени на теорию прочтения статей и информации о микрокомпьютерах, микроконтроллерах, WebRTC технологии, 3D-печати и прочего… я начал подсчитывать бюджет, сроки и свои возможности, изначально мне было ясно что для работы проекта, нужно следующее:
Помещение 100-200 м²
5 машинок, оснащённых камерами
Мощный роутер из бизнес сегмента
Компьютер
Фанера или гипсокартон с обклеенной фотопечатью на ней
1 год времени
Начать решил с машинок: пошёл я на популярный китайский маркет искать машинки, купив пару вариантов и поездив по дому, я достаточно быстро пришёл к выводу, что шасси моих машинок должны быть полноприводными и «танковыми» способными разворачиваться на месте, чтобы радиус разворота был около нулевым. Я потратил неделю поисков и не нашёл подходящего варианта.
Прочитав теорию о видеотрансляциях и стримингах видео, я пришёл к выводу, что ардуинки мне не хватит, уж больно слабые они, а суть в том, чтобы игра была комфортной и качество картинки было не менее 720p и 25 FPS и при этом задержка видео была бы не более 333мс. ( мне удалось достичь 250мс внутри города и 200мс внутри локалки), такие требования я взял из воздуха к самому себе. Я параллельно писал дипломную работу в своём вузе «Северо-Кавказский федеральный университет» и тема работы, как раз и был данный проект. Много ли студентов настолько увлеченно пишут дипломные работы, что сами в одиночку делают на эту тему проект и доводят его до рабочего коммерческого продукта? – а я довёл, уж не умею я бросать дело на полпути и очень дотошный я. Заказал я китайскую шасси, малинку и…. нашёл я такую статью с готовым кодом для малинки и вот что у меня получилось:
Raspberry pi 3b+
Серво SG90
Обычный самый дешёвый моторчик DC
Батарейный блок с батарейками
Пауэрбанк для питания малинки
Понижающий модуль напряжения DC
L298N драйвер моторов
Камера для малинки со шлейфом
Провода
И всё заработало, без танцев с бубном, ураа… однако, дьявол кроется в деталях!
Вид машинки «непродажный»
Ненадёжные моторы как и сама конструкция
Нету на моторчиках датчиков холла, из-за чего, когда жмёшь вперёд машинка реагирует не сразу, а с подлагом, постепенно увеличивая напряжение на моторы, а если машинка будет на склоне? Игрок подумает, что игра зависла! Игра должна сразу реагировать на действие пользователя. Вариант подавать сразу большое напряжение я не рассматривал, всё таки это игра, и в любых гоночках транспорт постепенно набирает скорость
Нет рук для возможности вернуться на колёса если перевернулся
Трафик видеотрансляции огромный, 20мб/с при 720p 😔
Снова ознакомившись с материалами уже запущенного и заброшенного проекта «Isotopium», я решил, что надо идти про уже протоптанной дорожке. Чтобы было более понятно читателям, я немного расскажу о своём опыте в технической отрасли:
Я ни разу не держал паяльник в руках до старта данного проекта
У меня никогда не было опыта работы ни с ардуинкой, ни с микроконтроллерами, ни микрокомпьютерами
У меня была мечта – сделать хороший качественный игровой продукт
У меня был небольшой опыт с робототехникой в вузе, мне дали стенд с рукой, с которой никто не хотел (или не мог) работать и мне сказали, литературы нет, документации нет, преподавателя, который даст ей ума тоже нет. Делай что хочешь, только сделай что-нибудь, красочное, чтобы можно было продемонстрировать руководству или делегациям. Пришлось произвести небольшой реверс-инжиниринг данного оборудования 😊. Буквально, через неделю я её сломал…вдребезги, мне были интересны минимумы и максимумы движения моторчиков данной руки, кто же знал, что если моторчики не смогут достичь необходимого заданного положения, то появится эффект джиттера и они снесут стол, на котором стоят… однако, железная рука робота оказалась слабее железного стенда. Старшекурсники и другие лаборанты, склеили её, но она, мягко говоря, стала нерабочей. Как и у любой другой техники должна быть кнопка экстренного отключения!? Да, она была, но не была подключена, я на ней прыгал, прыгал, а она не работала и не сработала. Помните! Проверяйте периодически системы экстренной остановки станков, роботов и прочего, возможно эти кнопки просто стоят, для галочки 😊.
Я на этапе награждения за победу в олимпиаде по дисциплине веб дизайн и разработка 18-22, и с антропоморфным роботом
Вот сама рука, которой я занимался в вузе, да у меня были мысли и наработки и возможно готовый код есть, чтобы использовать руку по её прямому предназначению, как использовал Говард из сериала «Теория большого взрыва».
Моя самая первая печать, после популярнейшего кораблика, были домино с кошачьими мордочками.
После нескольких экспериментов с разными материалами пластика, я остановился на ABS+(eSUN), моделировал я в Fusion 360, ну а слайсерил в cura.
По видеоурокам я самостоятельно научился моделировать, вот примерно так я себе представил самую простую модель шасси. Моторчики и колёса я взял из предыдущего набора мной купленного шасси, шестерёнки и валы -> всё напечатано из ABS+ пластика.
Первую версию напечатанной машинки, я решил делать, крайне, топорно, методом бутерброда. Первый этаж ходовая, понижающий модуль напряжения и драйер мотора, второй этаж малинка и батарейный блок, третий этаж камера и серво.
Батарейный блок я нашёл готовый на маркетплейсе, для работы с 18650 аккумуляторами, его уникальность в том, что он на выходе даёт 12в 3A (методом измерений, мне было достаточно 2A для силовых моторов) + USB выход для малинки, имеет индикатор уровня заряда и ещё можно подключить адаптер для зарядки и цена ему была всего 10$.
После тестовых заездов, были выявлены недостатки:
В ходовой, зубцы шестерёнок скалывались и ходовые валы просто расслаивалис, буквально после нескольких часов езды.
Центр тяжести был на втором этаже, а должен быть как можно ниже к полу, тем самым машинка была неустойчивой и здесь я понял, что машинке надо делать лапки, чтобы она могла сама встать на колёса, а не бегать к каждой машинке каждые 5 минут.
Моторчики, что я использовал были слишком громоздкими и были слишком мощными.
Камера должна быть жестко зафиксирована, а не болтаться только на серво.
Нужны бампера и боковая защита колёс, чтобы при ударе они не выламывались.
Обнаружил баг в видеотрансляции ровно каждую минуту изображение зависало на 2-3 секунды, и ровно через 1 минуту это повторялось. Баг был в том, что по какой-то причине если ПО на малинке стоит с графическим интерфейсом то, есть такой баг, а если управление через консоль, то бага нет – у меня ушло 2 недели, чтобы выявить причину.
Если робот заезжал за угол, сигнал падал и начинались «тормоза» в видеотрансляции. Окончательно решил проблему, установив внешнюю антенну на малинку путём распайки дорожки wifi антенны и припаивания U.FL разъёма. Разумеется, роутер пришлось «подобрать» из сегмента бизнес-решений с мощным процессором – выбрал «MikroTik».
Для придания продажного вида роботу-машинки: я решил вдохновляться популярнейшим автомобилем «Bugatti».
Проблему с переворотами машинки я решил с помощью мощных серво, по левому и правому борту машинки сделал лапки. Камеру посадил на подшипник с толстым слоем пластика.
На счёт ходовой, было много танцев с бубном… я стремился сделать продукт максимально качественным и дешёвым, подходящего моторчика ни в магазинах, ни в маркетплейсах я найти не смог за адекватную цену, приходилось ждать доставку из Китая и с третьего заказа я получил, идеальный моторчик «Bringsmart» 250rpm, с датчиком холла, он обошёлся 7.5$ за единицу.
Ходовую и шестерёнки же я решил печатать из композита нейлона PA-CF. Я пробовал сломать ходовую методом полного газа и резкого заднего хода 10 часов без остановки, после этого времени ходовая моей машинки осталась в прежнем неизношенном состоянии, а вот смазка из самого моторчика потекла и он очень перегрелся, но после остывания, он вновь был исправен.
Проблему слишком тяжёлого трафика видеотрансляции исправил, переведя трансляцию на CV2, в данной библиотеки для малинки есть много параметров изображения и трафик упал с 20➔10 мб/с при 720p и 25fps формат видеотрансляции MJPEG, далее на компьютере, который выступает сервером видео проходит преобразование ffmpeg -mpeg1video кодеком и на выходе получаем 4-5мб/с трафик видеоизображения на 1 машинку, что уже допустимо, задержка при этом 200мс в локальной сети, трансляция прямо в браузер без дополнительных библиотек в MJPEG.
Как и любая другая игра, должна быть миникарта, где будут позиционироваться все игроки. Для этого, выбрал rfid датчик с расстоянием действия до 1 метра и преобразователем через usb-ttl, питается он от этого же usb. Идея была в том, чтобы расклеить много-много меток на полу и покрасить весь пол в один цвет, чтобы их не было видно, датчик разместить на дне машинок и метки внести в базу данных. И это сработало у меня в квартире на паркетном полу.
Я немного увлёкся и сделал 9 машинок, вместо 5 как предполагал изначально, на некоторые комплектующие за партию в десяток китайцы давали неплохую скидку.
Себестоимость 1 машинки вышла в 20-25 тыс руб. или около 300$, на 3D принтер паяльник и прочий перебор деталей ушло порядка 400 тыс руб. или 5000$
Итог, потрачено на этот этап разработки прототипа и автопарка:
400тыс на разработку + 200тыс на машинки (9шт) = 600 000руб;
15 месяцев суммарного времени (1 человека - меня).
Отдельную благодарность хочу выразить своему любимому коту «Барнику», без его помощи, у меня ничего бы не получилось!
Изначально, я думал взять помещение в аренду, но… я принципиально исходил из того, что мне надо будет покрасить полы в один цвет, из-за RFID меток навигации. Желающих арендодателей, которые согласились бы на то, что я изменю их напольное покрытие не нашлось. Брать помещение в аренду без ремонта, для проекта, который ещё ни рубля прибыли не принёс тоже, весьма сомнительно.
Выбор пал на покупку помещения, подвала, и как раз, проходил аукцион приватизация имущества у моего города, в котором я и принял участие. Суммарно на помещение и его ремонт под мой проект ушло около 1’200’000руб. Ремонт помещения делали своими руками, мне помогали в этом несколько моих родственников, но иногда приходилось для ремонта и нанимать рабочую силу местами, это был первый объект недвижимости который я купил в своей жизни и тем более, в котором я делал ремонт (я никогда в руках и дрель то, не держал до этого)!
Пол я покрасил в асфальтный серый цвет, алкидно-уретановой краской в 2 слоя. Тесты с метками, показали, что из-за краски читаемость меток с 80-100см уменьшилось до 10-15см и путём вычислений мне потребовалось вместо ожидаемых 8-9 меток на м², 36 меток на м². Мы с моей женой потратили неделю на обклейку 70 м², дальше, просто устали… и решили запускать проект как есть. Общая площадь помещения 110 м².
После ремонта помещения, я смоделировал площадку, по которой будут ездить машинки, при этом так, чтобы везде могли они разъехаться, даже в случае саботажной игры одного из игроков. Я спроектировал: аркаду, домики, парковку… На уровне машинок мы расклеили пейзаж многоквартирных домов, на постеры и «домики» ушло порядка 100 000руб. Всю площадку, было решено делать из фанеры, я заказал распилы у фрезеровщика на чпу станке, после просто забрал и на саморезах всё скрутил.
Ещё на этапе разработки, нужны были игроки для проведения тестовых заездов, по квартире. Потратив неделю на поиски блогера, которые за бесплатно или вменяемые деньги прорекламировал бы, я нашёл одного и за очень адекватные деньги он сделал интеграцию. Но увы, никто не записался на тестовый заезд. Решил, видоизменить подход, и платить за тестовую езду игрокам, по 1 рублю за 1 минуту игры, и сработало, при новом подходе, пришло 30 человек на тестовый заезд от блогера у которого было всего 10 000 просмотров под его видео с интеграцией, все машинки были задействованы, и таким образом, я ещё заказал несколько интеграций у этого же блогера и «добил» число подписчиков в телеграмм группе до 100 человек.
После открытия проекта, всем игрокам было интересно, что же получилось, но никто не захотел платить за игру! Я попробовал ещё у двоих блогеров заказать рекламу, но увы, удалось добиться только 150 подписчиков в телеграмме и 50 в дискорде и на этом всё, буквально. Суммарно написал около 300 разным блогерам, на email, инстаграм, в facebook и воз и ныне там. Меня просто везде игнорят, тотально, а рекламные агенства хотят неадекватно большие деньги. Суммарно на рекламу я потратил порядка 50 000руб. И расчёт был, что хотя бы 1/3 от суммы отобьётся, однако этого не произошло.
Я топорно пошёл по твичу рекламироваться в чатах у стримеров, и нашёл блогера, который прошёл по ссылке и целых 2 часа играл у меня на проекте со своими зрителями (в тот день, была бесплатная игра без ограничений с целью рекламы). Очередь на игру была 60-70 человек при 9 машинках, я был уверен, что это успех, однако на следующий день пришло 0. Этот блогер на мои сообщения и попытки договориться о дальнейшим сотрудничестве ответил полным игнором.
Сюжет игры был в собирании контрольных точек – нужно было мордочкой машинки ударяться в белые коробочки (они на Arduino с светодиодом внутри), раскинутые на карте. В тот момент, когда они загорались разными цветами, их можно было собрать, в них находится датчик чтения RFID, а в бамперах машинках обычные пропускные карточки с метками. При собирании начислялись монетки, которые можно было обменять на дополнительное время игры.
Игру я назвал «Remote Race» или «RemRace» (Дистанционная гонка/заезд), за полный месяц работы (работал с 15:00-21:00 каждый день), зарегистрировалось, около 500 человек. Было получено порядка 3 000руб(35$) платежей. Стоимость одного интернета обходилось мне в 3500руб/мес + коммуналка 6000руб + моей время.
Суммарно на весь проект, помещение и коммунальные платежи, я потратил порядка 2млн руб. и 3 года. Для меня это огромная сумма денег, я её откладывал с 15 лет…
И на этом мой энтузиазм умер, работал я с 15 ноября по 15 декабря 2025г. В среднем, в игру заходило 1-2 человека за весь день, минут на 20 суммарно, заходили на бесплатный пробный заезд – 5 минут бесплатно я давал всем при регистрации, смотрели все и уходили. Стоимость платной игры была всего 2 руб. за 1 минуту. Что пошло не так, я не знаю, видимо мне не удалось добиться привлекательной, продающей картинки. Из-за ИИ я потерял работу, с которой я и спонсировал весь этот проект.
На данный момент проект выключен, и я нахожусь в поисках: инвестиций, или медиа поддержки, чтобы привлечь игроков, или работы для себя – сейчас я уже 4 месяца нахожусь в активном поиске работы, и ото всюду одни отказы. Машинки я выставил на продажу и продаю, за 10 000руб, как и домики свои я тоже продаю.
P.S. Ещё есть возможность, вернуть проект в рабочее состояние, если появится партнёр, который окажет медиа или финансовую поддержку проекту.
Raspberry Pi 5 2ГБ/4ГБ/8ГБ RAM на Али, 16ГБ RAM, NVME тоже можно поставить через адаптер
Реклама: АЛИБАБА КОМ (РУ) ИНН 7703380158
На базе этой крохи можно сделать
✅Частную систему умного дома, которая не будет зависеть от внешних серверов.
✅Домашний NAS с собствнной коллекцией фильмов, сериалов и музыки тоже независимый от интернета и сторонних серверов.
✅Локальную систему видеонаблюдения которая тоже будет изолирована от внешнего вмешательства.
✅Игровую приставку с эмуляторами всевозможных консолей и тысячами игр к ним.
✅Тв приставку с любой оболочкой которая вам по душе.
✅Мини-сервер для хостинга ботов, сайтов и приложений.
✅Аппаратный межсетевой экран, маршрутизатор, VPN шлюз и тд.
✅Почти любую автоматику, роботизировать что-нибудь, обучить частную нейройнку с собственными агентами заточенными под конкрентные задачи...типо Джарвиса или сделать полностью автономную Алису, которая не зависит от интернета или подписок.
И еще куча всего другого интересного. И всё это на платке размером с ладошку, которая еще и потребляет немного.