explain.maker

explain.maker

Собираю проекты с помощью ИИ и показываю, что получилось на практике. Автор Братана — домашнего робота из пылесоса и старого телефона. Код и модели: github.com/explAIn-channel/bratan-robot
На Пикабу
102 рейтинг 1 подписчик 0 подписок 1 пост 0 в горячем
3

Домашний робот из пылесоса своими руками⁠⁠

Всем привет! Расскажу, как я без опыта в электронике собрал домашнего робота на базе б/у робота-пылесоса и старого смартфона. Робот строит карту квартиры, ездит по ней, сам возвращается на зарядку, определяет направление на голос и разговаривает. Дальше по порядку: из чего он собран, как устроен софт и какие проблемы пришлось решать по дороге.

Итоговая версия. Снизу б/у пылесос, сверху разбитый телефон, между ними 25 напечатанных деталей. Справа главный тестировщик.

Итоговая версия. Снизу б/у пылесос, сверху разбитый телефон, между ними 25 напечатанных деталей. Справа главный тестировщик.

Для начала исходные данные. Опыта в робототехнике и электронике у меня не было, код такого уровня я не пишу. Поэтому роли распределились так. Код писали нейросети Codex и Claude Code, а я выбирал железо, собирал, проводил живые испытания и проверял, соответствует ли каждое заявленное исправление реальному поведению робота. Соответствовало не всегда.

Началось всё 10 августа. Я увидел ролик про чужого робота на колёсах с языковой моделью в голове и спросил у ChatGPT, что нужно, чтобы собрать такое же, и сколько это будет стоить. Через несколько минут появился третий вопрос, можно ли вместо Raspberry Pi использовать мой старый телефон.

Планирование

Чтобы робот мог жить в квартире, ему нужно три вещи:

  • Тело. Ездить, понимать, где он находится, и возвращаться на зарядку, пока не сел.

  • Голова. Камера, микрофон, динамик, экран и процессор, на котором всё это считается.

  • Мозг. Решать, куда ехать и что сказать. Тут без языковой модели не обойтись.

Начал с тела, потому что без надёжной платформы остальное проверять не на чем.

Тело, вариант первый

Первый план был по учебнику. Raspberry Pi 5, ROS 2, моторы, колёса, датчики и аккумулятор отдельно, плюс лидар, чтобы робот видел комнату. По расчёту для эксперимента это выходило дорого, в первую очередь из-за лидара.

Тело, вариант второй

Альтернативой стал робот-пылесос. Это уже готовая мобильная платформа, и в нём есть всё, что я собирался покупать по отдельности.

Арифметика, после которой набор на Ардуино отпал сам.

Арифметика, после которой набор на Ардуино отпал сам.

Критериев выбора было три. Лидар на борту, родная зарядная база и открытая документация на протокол платы, чтобы не сниффить UART вслепую. Смотрел Roborock S6 Pure, Mop 2S и первый Mi Robot, а остановился вот на чём:

  • Xiaomi Mi Robot Vacuum-Mop P (STYTJ02YM) на платформе CRL-200S. Это само шасси, его протокол разобран в открытом проекте VacuumTiger.

  • Allwinner A33, главная плата пылесоса. Четыре ядра Cortex-A7 по 1,2 ГГц, 512 МБ памяти и свой Linux.

  • GD32, микроконтроллер, который крутит колёса и читает энкодеры, гироскоп, бампер и контакты зарядки. С A33 общается по UART на 115 200 бод.

  • Delta-2D, лидар на 360 лучей за оборот, примерно шесть оборотов в секунду.

С ревизией платы надо быть осторожным: восьмая при попытке получить root превращается в кирпич. Подходящую нашёл на барахолке примерно за $50.

Перед любыми экспериментами снял бэкап всех девяти разделов памяти пылесоса. Root получил через сервисный micro-USB. Кабель пришлось переподключать раз пятнадцать, потому что окно, в котором плата отвечает, очень короткое.

К вечеру того же дня колёса уже вращались по командам с компьютера. Заодно аккумулятор разрядился в ноль: контроля заряда тогда ещё не было.

Препарирование.

Препарирование.

Телефон вместо компьютера

Покупать мини-компьютер я не стал. Камера, микрофон, динамик, экран, Wi-Fi и Bluetooth уже лежали у меня в ящике в одном корпусе. Это старый Meizu 16th на Snapdragon 845 с 8 ГБ памяти. Экран разбит, работает только верхняя треть, но для отображения лица робота этого достаточно.

На телефон поставили Magisk для root-доступа и Ubuntu 24.04 в chroot. Это обычный Linux, который живёт внутри Android и пользуется его железом. Python и ONNX Runtime работают так же, как на компьютере.

Производительность удобно оценить по детектору YOLO26n с кадром 320 пикселей:

1 поток: 115 мс

2 потока: 70 мс

4 больших ядра A75: 50 мс

4 малых ядра A55: 134 мс

Получается около 10 кадров в секунду только на процессоре. Для одноплатного компьютера сопоставимого класса это хороший результат, а телефон у меня уже был. Ещё у Android есть ограничение заряда. Телефон держит батарею между 75 и 80%, чтобы аккумулятор не деградировал от постоянной зарядки на базе.

Выглядела первая версия так:

Телефон в прозрачной подставке, подставка на пылесосе. Пронзительный взгляд.

Телефон в прозрачной подставке, подставка на пылесосе. Пронзительный взгляд.

Первые выезды

Софт сначала строился на стандартном стеке ROS 2 Jazzy, Nav2 и SLAM Toolbox. Прямо на телефоне работали Whisper для речи, небольшая Qwen 2.5 на 1,5 миллиарда параметров и YOLO11n. Робота тогда звали Гермес.

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

  • Коэффициенты команд скорости оказались неверными в 3,84 раза.

  • Развороты недотягивали на 43%, потому что колёса проскальзывают. Помогло верить гироскопу, а не энкодерам.

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

  • Процент батареи оказался просто напряжением. 13,5 В это ноль, 15,5 В это сто, а под нагрузкой показания проседают пунктов на тридцать.

Через несколько дней калибровки рулетка показала 0,600 м, а одометрия 0,599. Часть калибровки нейросеть провела самостоятельно. Около пяти часов она гоняла робота вперёд и назад и по изображению с камеры сверяла фактически пройденное расстояние.

Рулетка в кадре для красоты.

Корпус

Без корпуса телефон держался на шасси ненадёжно. Однажды робот заехал под кровать, и телефон упал. Нужен был корпус, в котором поместятся телефон, лидар, подсветка и проводка. По внешнему виду выбрал стилизацию под корги.

Модель шла ревизиями от R2 до R5, каждую отдельно проверял чат-аудитор. Для одной из версий я поставил условие «делай что хочешь, но добейся меньше килограмма». Посадка колёсной базы в первой модели оказалась неверной, и её восстанавливали заново по листу бумаги с тремя отмеченными точками и линейке.

Печать корпуса на заказ стоила дороже б/у принтера, поэтому я купил Anycubic Kobra 3 примерно за $170. Под его стол 250 на 250 мм корпус и порезали на детали. В первый же вечер калибровка принтера выдала ошибку 101-29 по компенсации вибраций, поэтому печатали без неё. Печать шла в основном ночью под наблюдением веб-камеры.

3D-модель корпуса, 13 белых деталей каркаса и 12 оранжевых накладок.

Что пошло не так:

  • Чаша под лидар была рассчитана неверно, детали не сошлись по пазам. Минус 20 часов печати.

  • Передняя панель раз за разом выходила с дефектом в одном и том же месте. Дефект закрыла оранжевая накладка, которая в итоге вошла в финальную модель.

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

  • Лидар после переезда в корпус поднялся до 25 сантиметров и развернулся на 86,3 градуса. Никто об этом не знал, пока не нашли на ночной отладке. При этом поза зарядной базы была записана ещё до переноса.

  • Микроконтроллер отказывался ехать вперёд, потому что датчики обрыва пола после переделки смотрели не туда. Передние ИК-датчики в итоге развернули вперёд и сделали из них датчики близости. Они видят препятствие с 18 см на белом, с 14 на тёмном и с 10 на коже.

    Все 25 деталей. Около двух катушек PLA.

Переписывание с нуля

С августа по начало октября код писали посменно Codex и Claude Code. Когда у одного кончались лимиты, работу отдавали другому.

В сентябре проект один раз уже начинали заново. Я написал техзадание для нового разработчика, где описал железо, датчики, протокол GD32 и калибровки. Отдельным файлом приложил разрешение свободно изменять, заменять или полностью удалять любые программные части. К октябрю набралось 284 релиза.

Режим жизни тогда выглядел так. Часы бодрствования с 11 до 23, скорость не выше 0,16 м/с, 36 инструментов для модели и намерения в SQLite. Робот работал нестабильно. На просьбу подъехать на полметра робот мог ответить, что основной мозг недоступен. В режиме следования за человеком он терял меня из виду, делал полный оборот и прекращал поиск.

Были и чисто системные сбои. Телефон перестал отвечать по SSH, а на плате пылесоса раздел журналов оказался заполнен на 100%, потому что штатный WiFiManager писал логи по 5 МБ.

Независимый аудит в конце сентября заключил: модули есть, отдельные действия получаются, но то, что система устойчиво живёт сама, не доказано. Приёмку из 10 сценариев робот так и не прошёл.

Пятого октября я отдал проект Claude Code целиком. За первый час он нашёл, почему всё тормозит:

  • Камерная служба Android с 24 сентября копила утечку памяти и разрослась до 2,95 ГБ, swap был забит на 100%.

  • Энергосбережение Wi-Fi на телефоне давало 51 переподключение за 85 минут.

  • Промпт планировщика занимал 12 700 токенов на каждое решение.

Кроме того, голосовой процесс за двое суток перестал нормально работать, и каждая фраза уходила в локальный синтез с задержкой 10-40 секунд. А ключ подписи Android-приложения, которое рисует лицо робота, потерялся ещё в сентябре, и без него приложение было не обновить. Сделали новые ключи и переустановили.

На следующий день я попросил переписать весь код с нуля, на плате и на телефоне. Что получилось:

  • Старый код занимал около 35 тысяч строк Python, новый около 18 тысяч.

  • За шесть дней сделали 171 коммит, из них 67 в первый день.

  • Тестов было 863, к концу проекта стало 4 877.

  • Робот получил новое имя Братан.

Программная часть

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

Три уровня. Плата и телефон ездят и без интернета, а разговаривать и принимать решения без облака он не умеет.

Три уровня. Плата и телефон ездят и без интернета, а разговаривать и принимать решения без облака он не умеет.

На плате пылесоса родные службы уборки остановлены. Вместо них работает одна программа body.c на C без зависимостей, около 700 строк. Её главный цикл опрашивает четыре канала сразу, это сервер, GD32, лидар и телефон. Каждые 20 миллисекунд программа шлёт микроконтроллеру скорости колёс, плавно ограничивает ускорение и на разворотах подтягивает отстающие колёса по гироскопу. Ограничение скорости в 0,24 м/с стоит прямо в той функции, которая пишет в моторы, поэтому никакой код выше его не обойдёт.

Защита на плате от телефона не зависит. Если 0,75 секунды нет команды, колёса стоят. Если нет пять секунд, гаснет лидар, чтобы зависший телефон не посадил батарею. Второй экземпляр программы просто не запустится. Отдельно выяснилось, что без регулярных команд плата A33 перезагружается примерно каждые четыре минуты, поэтому программа шлёт их постоянно.

С телефоном плата общается по Wi-Fi с задержкой около 3 мс. Протокол текстовый. Телефон каждые 40 мс в движении присылает строку с номером команды, скоростью, поворотом и курсом, а плата 50 раз в секунду отвечает состоянием колёс, одометрией, бампером и напряжением и на каждом обороте отдаёт скан лидара. Номер команды строго растёт, поэтому опоздавшая команда просто отбрасывается.

Пакет лидара Delta-2D покрывает сектор 22,5 градуса, это 25 отсчётов. Контрольная сумма считается как простая сумма байтов, её проверили на трёх с лишним тысячах живых пакетов подряд. Ноль лидара смотрит назад, а углы идут по часовой стрелке, поэтому плата их пересчитывает, а поворот крепления на 86 градусов учитывается уже на телефоне.

На телефоне работают процесс-надсмотрщик и три дочерних, у каждого свои ядра:

  • body на cpu4 с повышенным приоритетом. Связь с платой, локализация, маршруты, защита.

  • eyes на cpu5-7. Камера, детектор, лица, жесты, мимика.

  • voice на cpu0-1. Микрофоны, распознавание, синтез.

  • mind на cpu2-3. Потребности, память, обращения к модели.

Общаются они через общую шину на Unix-сокете короткими JSON-строками. Медленный подписчик отключается и не тормозит остальных, а упавший процесс надсмотрщик поднимает заново. Android-приложение с лицом робота наружу не открыто вообще. Его серверы слушают только локальный адрес телефона, и для камеры, микрофона и динамика у них отдельные токены.

Решения в облаке принимает языковая модель DeepSeek V4.1 Flash. Её будят события. Например, робот увидел собаку, открылась дверь, его позвали по имени или сел аккумулятор. Без событий она просыпается раз в 40-60 секунд, а в режиме сна на базе до получаса. В ответ модель присылает один JSON с мыслью, фразой, действиями, условиями и выражением лица на экране. Действия она выбирает только из закрытого списка, в нём 21 действие тела и 17 действий ума. Команды «стоп» и «на базу» идут мимо модели вообще.

Навигация

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

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

Чтобы понять, где он находится, робот на каждом обороте лидара подгоняет 240 точек скана к полю расстояний до стен методом Гаусса-Ньютона. Это занимает около 2 мс. После четырёх промахов подряд он признаёт, что потерялся, и за несколько секунд перебирает варианты по всей карте.

Маршрут строит A* по клеткам со штрафом за тесноту, а в тесных местах Hybrid-A*, который учитывает, что робот не ездит боком. По маршруту ведёт алгоритм pure pursuit. Робот смотрит на точку чуть впереди на пути и рулит к ней. Перед каждой командой контур корпуса мысленно протягивается вперёд на 0,7 секунды, и если он задевает хоть одну точку лидара, команда не проходит.

Почему всё шло так долго

Вот из-за чего робот ездил плохо или не ездил вовсе. Первым был узкий проём с порогом. На правильной линии там запас 8 см, а по живому скану было свободно 0,247 м при нужных 0,254, и алгоритмы три раза подряд отказались ехать. В итоге я ставлю робота руками в точку заезда и выезда, он запоминает линию и проезжает по ней на 0,24 м/с с точностью до сантиметра. Если застрял на 2,5 секунды, сдаёт назад по той же линии и пробует снова, до трёх раз.

В коридоре у солнечной двери робот ездил туда-сюда на пустом месте. Опыт с поворотом на 360 градусов показал, что слабые одиночные отражения всегда смотрят на окно. Это были блики, для них добавили фильтр.

Три дня поиск выбирал направление поворота случайно, причём заново 50 раз в секунду. За 8 секунд робот поворачивал на 0,17 радиана вместо 3,4.

Пружинные контакты базы отталкивали робота на 3 см, и он стоял на зарядке без контакта. Добавили дожим и проверку, что заряд держится три секунды. А сама база была записана со сдвигом на 30 см вбок и на 24 градуса, поэтому робот терялся на каждом съезде. Первое исправление координат базы оказалось ошибочным, сработало второе.

Однажды робот упёрся носом в белую панель у колонки и потерял место на карте. Защита не давала развернуться, а модуль принятия решений 96 раз подряд командовал ехать на базу и получал в ответ, что робот потерялся, пока не села батарея. Теперь в такой ситуации он сначала отъезжает назад до 60 см.

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

Нейросеть для езды

В начале сентября я обучил собственную нейросеть езды. Это маленький перцептрон на 228 входов и 2 выхода с тремя скрытыми слоями. На входе три снимка лидара за текущий момент, 0,3 и 2 секунды назад, каждый сжат до 72 секторов, плюс пять точек маршрута и текущие скорости. На выходе линейная и угловая скорость.

Сначала она подражала обычному геометрическому алгоритму на 96 тысячах примеров. Потом 12 виртуальных роботов доучивали её методом PPO, это 800 обновлений и 1 228 800 шагов симуляции.

Двенадцать виртуальных роботов учатся ездить по копии квартиры.

Лучшей оказалась модель после первого же обновления PPO. Она доехала в 120 из 120 эпизодов без препятствий и в 116 из 120 с неподвижными препятствиями. К 800-му обновлению успешность упала до 88%, а столкновения выросли до 12%. Дальнейшее обучение делало только хуже.

На живом роботе колёсами в итоге рулит не она, а pure pursuit. Нейросеть загружается и получает сканы, но команд не выдаёт. По одной оценке в симуляторе доверять ей управление в квартире не стали.

Слух и микрофонная решётка

Первым распознавателем речи был офлайн-Vosk. Качество было низким. Вместо «поезжай в зал» он распознавал «поесть, пожалуйста, в зал», а вместо приветствия «бросаем привет». Фразы перевели на облачный Azure, а Vosk оставили ловить только имя по маленькой грамматике из нескольких слов.

Потом выяснилось, что робот слышит сам себя. Своё «стою» он принимал за команду «стой», а «состыковался» за «остановись».

Микрофоны телефона расположены слишком близко друг к другу, чтобы по ним определять направление на звук. Поэтому я добавил отдельную микрофонную решётку:

  • Одна плата ESP32 снимает звук и отправляет его на телефон.

  • Три MEMS-микрофона INMP441 с цифровым выходом I2S.

  • Микрофоны стоят в готовых проёмах корпуса без сверления, один спереди под телефоном и два по бокам.

    Схема проводки из репозитория. Мест под микрофоны четыре, стоит три. Четвёртый застрял в доставке, и я решил без него.

Направление считается по разнице во времени прихода звука, а это доли миллисекунды. Значит, все каналы должны писаться строго синхронно. На ESP32 работают две шины I2S с общим тактом, ведущая и ведомая, и стартуют они одновременно. Звук пишется на 16 кГц в 24 битах, проходит фильтр высоких частот на 60 Гц и сжимается до 4 бит. Три канала занимают около 25 КБ/с по UDP, а если Wi-Fi теряет пакеты, звук идёт запасным путём через Bluetooth.

Определение направления по самому громкому микрофону не сработало, потому что третий микрофон всегда давал больший уровень. Перешли на задержки по началам слогов. Эхо от стен приходит позже и уже не сбивает. Робот различает все восемь направлений, медианная ошибка 12-16 градусов.

В домашнем тесте по десять фраз решётка распознала 91% слов с метра против 83% у телефона и 86% против 75% с двух метров. Суммирование трёх каналов выигрыша не дало. Лучший микрофон давал 82%, сумма 80%, поэтому сложение выключили.

Свой голос робот теперь гасит пространственно. По трём каналам он запоминает, как звучит его динамик, и подавляет именно это направление. До этого он заглушал меня на 37 дБ, и перебить его было невозможно. Последней поймали ошибку, когда моё «подожди» засчитывалось как его «дожди» с совпадением 83%.

С железом тоже были проблемы:

  • Провода Dupont отваливались примерно семь раз за день.

  • Ряды проводов надели зеркально, у одного микрофона вывод L/R висел без земли.

  • Одну плату я сжёг, вероятно перепутав полярность. Сначала вышел из строя USB-чип, затем плата целиком.

  • Прошивка с приоритетом Bluetooth полностью заблокировала Wi-Fi платы, хотя сигнал и так падал до -85, а местами до -93 дБм. Спасали перепрошивкой по проводу. Теперь новая прошивка по воздуху подтверждается, только если 60 секунд держит Wi-Fi, иначе плата откатывается на старую.

Языковые модели и стоимость

Модели менялись почти каждую неделю. В конце августа мысли перевели на DeepSeek. В октябре разговором занимался GPT-Live, потом Claude Haiku 5.5 с первым словом через 0,6 секунды. К концу проекта разговор, мысли и сны перевели на DeepSeek V4.1 Flash.

Деньги кончались три раза. DeepSeek ответил ошибкой 402. У OpenAI кредиты закончились посреди голосового теста, и робот просто замолчал. Баланс OpenRouter ушёл в ноль, $77,06 из $77, но почти всё съели другие ключи аккаунта, а сам робот за месяц потратил около $2. Одна его мысль на дешёвой модели стоит около $0,00008, ответ в разговоре примерно в семь раз дешевле, чем на Haiku.

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

Память

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

В памяти накопились 14 кроватей, 11 духовок и 7 холодильников, а мою собаку Таффу детектор упорно считал кошкой. Написали правило чистки, и оно стёрло 30 настоящих вещей, включая кровать с 510 наблюдениями. Восстанавливали из ночной копии. Теперь предмет забывается, только если робот смотрит при свете на его место и не видит его.

Характер и потребности тоже считаются кодом, а модели передаются словами. Ночью сон двигает черты характера. После того как осторожность за несколько ночей выросла с 0,86 до 0,92, а 37% мыслей были про закрытые двери, изменение черт ограничили 0,03 за ночь.

Осторожность растёт, любопытство падает, робот почти не уезжает с базы.

Сколько стоило

Пылесос, б/у: $50

Телефон: был, похожий на барахолке стоил около $40

ESP32 и микрофоны: около $3

Bluetooth-подсветка: $3

Вентилятор для телефона: $2

Пластик, около 2 катушек: около $20

Итого робот: около $80

3D-принтер, б/у: около $170

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

Облачная модель по моей оценке обходится в пару долларов в месяц, а при прямом подключении к API ближе к пяти. Подписки на нейросети, которые писали код, у меня и так были. Так что $80 это только железо, без облачной модели и подписок.

Выводы

Что я для себя вынес:

  • Отчёт нейросети ещё не результат. Слова «исправлено и проверено» ничего не значат, пока робот не проедет по полу.

  • Защиту надо ставить в самый низ. Ограничение скорости и сторож связи стоят на плате, в единственном месте записи в моторы. Всё, что выше, может зависнуть.

  • Бэкапы нужно делать до экспериментов. Девять разделов пылесоса перед рутом, память робота каждую ночь, ключ подписи приложения. Последнее я как раз не сделал вовремя.

  • Для решения, куда поехать и что сказать, самая дешёвая модель справилась не хуже дорогих.

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

Есть и то, что пока не работает. Долгая жизнь без присмотра не доказана. Лидар на высоте 25 см не видит низкие предметы. Лестниц и обрывов защита не учитывает. В темноте камера теряет людей и собаку. Без интернета робот ездит, но не разговаривает. А карту, калибровки и заученные проезды под другую квартиру придётся снимать заново.

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

Код и модели корпуса: https://github.com/explAIn-channel/bratan-robot

Полное видео с роботом: https://www.youtube.com/watch?v=ZXrSBQ9Vc9g

В планах четвёртый микрофон и проезд порогов без ручной разметки. Если вы переделывали роботы-пылесосы под свои проекты, буду рад узнать, на какой платформе остановились и что сделали бы иначе.

Показать полностью 6 5
Отличная работа, все прочитано!

Темы

Политика

Теги

Популярные авторы

Сообщества

18+

Теги

Популярные авторы

Сообщества

Игры

Теги

Популярные авторы

Сообщества

Юмор

Теги

Популярные авторы

Сообщества

Отношения

Теги

Популярные авторы

Сообщества

Здоровье

Теги

Популярные авторы

Сообщества

Путешествия

Теги

Популярные авторы

Сообщества

Спорт

Теги

Популярные авторы

Сообщества

Хобби

Теги

Популярные авторы

Сообщества

Сервис

Теги

Популярные авторы

Сообщества

Природа

Теги

Популярные авторы

Сообщества

Бизнес

Теги

Популярные авторы

Сообщества

Транспорт

Теги

Популярные авторы

Сообщества

Общение

Теги

Популярные авторы

Сообщества

Юриспруденция

Теги

Популярные авторы

Сообщества

Наука

Теги

Популярные авторы

Сообщества

IT

Теги

Популярные авторы

Сообщества

Животные

Теги

Популярные авторы

Сообщества

Кино и сериалы

Теги

Популярные авторы

Сообщества

Экономика

Теги

Популярные авторы

Сообщества

Кулинария

Теги

Популярные авторы

Сообщества

История

Теги

Популярные авторы

Сообщества

Недвижимость и ремонт

Теги

Популярные авторы

Сообщества