Шедевры мирового моддинга

Много лет моим главным увлечением был моддинг компьютеров. Я следил за всеми новинками, помогал вести тематические ресурсы, да и сам создал несколько работ (одну из них даже можно найти на Хабре).

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

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

Моя подборка максимально субъективна, и в неё, конечно, вошло далеко не всё, о чём стоило бы рассказать. Но если затея вам понравится, обязательно будут и следующие выпуски. Итак, поехали!

1. Pyramid

Автор: Gup (Henk Hamers)
Год: 2010
Ворклог

Необычный кастом (то есть корпус, созданный с нуля) по мотивам фильма «Звёздные врата». Он оснащён механизированной передней панелью, за которой скрывается дисплей, отображающий параметры компьютера. Благодаря удачной подсветке и покраске корпус смотрится не хуже, чем декорации из фильма.

2. FuG-01/ET

Автор: Sheyr (Marcin Krup)
Год: 2005
Ворклог

Этот кейсмод в стиле старой немецкой аппаратуры больше известен просто как «Wolfenstein Case Mod». Возможно, сейчас он смотрится уже не так впечатляюще, как на момент создания, но тогда сочетание состаренного металла, сложной покраски и оригинальных ретро-деталей сильно выделяло его среди робких поделок, где весь моддинг сводился к вырезанию окна в боковой стенке. Лично мне этот корпус особенно дорог ещё и потому, что именно он побудил меня попробовать свои силы в этом деле.

Небольшое интервью с автором на русском языке

3. Recycle Your Computer

Автор: BeWize (Алексей Чистов)
Год: 2004
Ворклог

Когда несколько лет назад появился новый Mac Pro в цилиндрическом корпусе, только ленивый не пошутил, что он похож на мусорное ведро. Но всё новое — это хорошо забытое старое! Необычный корпус, изготовленный из самой настоящей корзины для бумаг, занял первое место в конкурсе журнала «Домашний ПК» и породил немало подражателей. Опять же, никаких проблем с отводом нагретого воздуха…

Фоторепортаж с выставки

4. The Weapon of Mass Destruction

Автор: G-gnome (Peter Dickinson)
Год: 2005
Ворклог

Это самая настоящая бомба — как по внешнему виду, так и по эффекту, который она произвела в моддинг-сообществе. Обязательно посмотрите ворклог, благо в нём сохранились фотографии. Это просто гимн металлообработке.

Примечательно, что многие детали были изготовлены вручную.

5. Zenith Antique 5-S-29 Radio

Автор: Gary Voigt
Год: 2010
Ворклог

«Внимание, внимание! Говорит Нью-Йорк! Работают все радиостанции Соединённых Штатов Америки!..» Возможно, вы подумали, что перед вами компьютер, встроенный в старинный радиоприёмник. Это не так: ни одна историческая вещь при создании данного мода не пострадала. Автор с нуля изготовил копию понравившейся ему модели ретро-радио, да ещё и ухитрился разместить внутри мощный компьютер с системой водяного охлаждения. Такому подходу можно только аплодировать.

6. Cosmos Cruizer

Автор: Boddaker (Brian Carter)
Год: 2015
Ворклог

Это самая свежая работа в моей подборке, но её автор — очень уважаемый моддер «старой школы». На этот раз он взял за основу корпус Cooler Master Cosmos II и превратил его в подобие автомобиля в стиле «хот-род». Из стеклоткани были смоделированы новые боковые стенки, благодаря которым граница между наружной и внутренней частями корпуса стирается.

7. Orac³

Автор: G-gnome (Peter Dickinson)
Год: 2004
Ворклог

Даже не верится, что этот футуристический проект был создан 17 лет назад! В нём возведена в абсолют идея кабель-менеджмента — и это в то время, когда признаком хорошего мода считалось уже использование скруглённых шлейфов.

У автора получился прекрасный образец стиля «киберпанк», который и сегодня было бы нестыдно использовать как декорацию к игре или фильму.

Авторский рендер:

Ворклог на русском языке

8. Fire Sound System

Автор: Strannik (Алексей Леонтьев)
Год: 2008

Подобно тому, как Микеланджело, окинув взглядом глыбу мрамора, мог увидеть в ней будущую скульптуру, Алексей Леонтьев, взглянув на старые огнетушители, увидел в них… колонки! Качество звучания, по словам создателя, получилось вполне приличным, так что через них можно запускать не только запись пожарной сирены, но и зажигательную музыку. И, кажется, я знаю, какую композицию группы Scooter автор включил первой!

9. Grey Tower

Автор: Grizly
Год: 2011
Ворклог

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

10. Project Mars City

Автор: Crimson Sky
Год: 2007
Ворклог

За десятилетия, прошедшие с момента выхода первого Doom, было создано множество кейсмодов в стиле этой культовой игры. Но непревзойдённым по сей день остаётся шедевр от мастера Crimson Sky.

Общие очертания, мелкие детали, покраска, подвижные элементы… придраться просто не к чему.

Думаю, не преувеличу, если скажу, что история моддинга делится на два периода — до «Project Mars City» и после.

Заключение

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

Просто, мне кажется, сегодня уже сформировался некий «канон», и большинство проектов похожи друг на друга. А вот конец 2000-х и начало 2010-х — это было время безудержного полёта фантазии и смелых экспериментов. Потому многие тогдашние работы способны удивить и сегодня. А какие моддинг-проекты больше всего нравятся вам?

ссылка на оригинал статьи https://habr.com/ru/company/ruvds/blog/552192/

Northrop Grumman запустила на орбиту уже вторую сервисную станцию, которая оживляет спутники связи без топлива

Космическая индустрия продолжает развиваться, это касается не только пусков ракет, о чем мы недавно писали, но и спутников, включая спутники связи. Впереди планеты всей компания Northrop Grumman со своими роботизированными сервисными станциями MEV.

Эти станции способны стыковаться на орбите со старыми спутниками, продлевая их срок жизни. Соответственно, владельцы/операторы спутников получают возможность не «хоронить» аппараты после того, как у тех заканчивается топливо, а, доплатив за услуги партнера, эксплуатировать систему еще около пяти лет. О том, как это происходит, — под катом.

В чем проблема со спутниками?

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

Когда объем оставшегося топлива спутника приближается к расчетному лимиту, его необходимо отправить на специальное космическое “кладбище”. То есть на определенную орбиту, где отработавшие свое аппараты остаются навечно, не представляя опасности для «живых» и рабочих систем.

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

Решение от Northrop Grumman


АЗС нет, но зато появились сервисные станции с автономным запасом топлива, которые способны передвигать спутники с орбиты на орбиту. Это относительно новое решение от Northrop Grumman, которая впервые опробовала его в прошлом году.

Станция не одноразовая, как можно было подумать. Ее срок службы составляет около 15 лет. То есть после того, как основной спутник уже не может использоваться, хотя бы в силу морального устаревания, станция отстыковывается и перебирается к другому «клиенту».

MEV-1

25 февраля 2020 года на околоземной орбите сервисная станция MEV-1 впервые состыковалась с телекоммуникационным спутником Intelsat 901. Она оснащена электрическими движками, специально спроектированным механическим захватом и визуальной системой наблюдения для корректировки стыковки. У станции есть и запас топлива для того, чтобы выполнять маневры — автономно или вместе со спутником, который нужно «возродить».

MEV-1 состыковалась с отработавшим свой срок космическим аппаратом Intelsat 901 как раз на «кладбище». Он работал с 2001 по 2016 годы. Получается, спустя пять лет он вновь вернулся к работе и компания сможет эксплуатировать его еще пять лет. После завершения этого срока MEV-1 снова отбуксирует спутник на вечный покой.

MEV-2

Вторая станция была запущена из космодрома Куру во Французской Гвиане в августе 2020 года. На то, чтобы подняться до расчетной орбиты, у MEV-2 ушло полгода. Ее основной целью был 17-летний спутник связи IS-10-02. На тот момент он находился на геостационарной орбите. Как и у предыдущего «пациента», у него закончилось топливо, необходимое для совершения маневров. Если бы не станция, его тоже пришлось бы отправить на космическое кладбище.

12 марта 2021 года станция начала стыковочный процесс с IS-10-02. Это довольно долго, ведь нужно не только выполнить сложную стыковку, но и проверить работу систем. По словам одного из представителей проекта, все прошло хорошо, и теперь спутник связи сможет проработать еще около 5 лет, прежде чем его выведут из эксплуатации.

Стоимость изготовления и запуска сервисной станции пока что неизвестна, но, похоже, она вполне устраивает клиентов компании. Во всяком случае, вице-президент Intelsat заявил о том, что контракт с Northrop — это win-win.

Как и MEV-1, вторая станция после завершения пятилетнего периода работы со своим спутником выведет его на внешнюю орбиту, отстыкуется и отправится к новому «пациенту».

Что дальше?

Сейчас компания Northrop разрабатывает усовершенствованную версию спутниковой сервисной станции, которая получила название Mission Robotic Vehicle (MRV). По сравнению с MEV, MRV гораздо более продвинутая система. Она будет устанавливать на спутниках «модули первой помощи», которые станут выполнять те же задачи, что и MEV. Каждый MRV сможет нести на себе 6 модулей, так что один запуск MRV — это 6 возвращенных к жизни спутников, спасенных от забвения.

ссылка на оригинал статьи https://habr.com/ru/company/selectel/blog/551460/

Интервью с техдиректором ElectroNeek: от написания кода к управлению процессами

image

Я пообщался с основателями стартапа ElectroNeek: Сергеем (CEO), Дмитрием (CIO) и Михаилом (CTO). В конце интервью — видео, где в прямом эфире собирают робота.

— Дмитрий, пришли, пожалуйста фотку для КДПВ, где вы все вместе.
— Не поверишь, мы так вживую и не встретились еще все за два года)

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

RPA  (роботизированная автоматизация процессов) — это технология, которая помогает автоматизировать повседневные, повторяющиеся задачи. RPA позволяет эмулировать действия обычного пользователя за компьютером, в буквальном смысле. Вы навели мышку на кнопку и кликнули, потом клавиатурой ввели текст и нажали «Enter». Ровно это и есть RPA. По мере увеличения спроса RPA-вендоры стали развивать свои решения, чтобы предоставить более гибкие механизмы автоматизации. Появились интеграции с языками программирования, с технологиями вроде OCR, всерьез думают о внедрении машинного обучения. Роботов теперь можно запускать одновременно, по расписанию, удаленно и т.д. Примеры кейсов: раз, два, три, четыре, пять.

— Что такое робот?

Михаил: Роботизация — это эмуляция человека. Человека можно эмулировать в разных ипостасях. Можно физически. Робот ходит как человек. Робот кликает по монитору как человек. Набирает текст как человек. Никогда нет полной эмуляции человека. Но аспект эмуляции человека и есть роботизация.

— Михайл, вас хантил Яндекс, но вы всё же решили работать в ElectroNeek, какая у вас мотивация работать в стартапе, а не на теплом гарантированном месте?

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

— Михаил, как тебя схантили?

Михаил:К тому моменту, я уже год как ушел из Акрониса, я перестал видеть свой вектор развития, хотел изучал разные технологии, делал pet-проекты. Мне хотелось делать что-то своё и я искал себе команду. А тем временем Димитрий и Сергей искали себе CTO и кинули клич по своим знакомым. Я был знаком с Дмитрием с университета, хотя особо и не общались, так и сконтачились. Я был готов к этому предложению. 

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

Мы ещё раз созвонились, уже втроём. С Сергеем мы в живую рядом сидели, а Дмитрий в это время был в Америке. Мы общались о продукте, как они это видят, куда планируют развиваться, для кого это, за счёт чего мы будет выделяться и зачем на рынке «ещё один конструктор роботов». 

Я увидел, что спрос есть, как минимум, в России. Дмитрий рассказал о глобальном рынке, в частности про США. Он до этого работал в Ernst & Young и занимался там RPA для Fortune 500 rкомпаний, так что хорошо представлял себе спрос.

Сергей и Дмитрий решили отличаться от конкурентов простым и удобным UX, сделать роботизацию более доступной для компаний любого размера. Мне нужно было знать, понимают ли мои потенциальные кофаундеры, какой будет интерфейс, в чем именно его классность. Я услышал честный ответ «Мы не знаем». Ребята в моменте не знали, что именно должно быть, но планировали пробовать и выяснять.

Для меня была важна такая честность и открытость. Мне понравилось, что они честно рассказали о ситуации. Это важно для будущих взаимоотношений. Сказать всё как есть, и если человек адекватный, он поймёт. Когда вы честны, если где-то косяк вылезет, сразу можно смотреть на то, как решать проблему, независимо от того, кто накосячил.

— Как выглядел Electroneek до твоего прихода в проект?

Михаил:До меня был рабочий прототип, который можно было показывать. Это был проект на GitHub, чтобы показать, что они примерно хотят сделать.

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

— В чем особенность разработки RPA продукта от остальных?

Сергей: Чем отличается разработка RPA-платформы от продукта «сам в себе». RPA платформа, в частности ElectroNeek — это средство разработки. Средство по созданию чего-то по взаимодействию с чем-то третьим. Это не отдельный продукт как CRM, которая сама в себе и только иногда по API взаимодействует с чем-то третьим.

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

— Зачем ещё один RPA-продукт на рынке?

Сергей: часто к нам приходят люди и говорят: «Зачем вы разрабатываете, когда можно зайти на какой-нибудь веб сайт, скачать готовый модуль RPA кликера и его делать?». Да он сможет открыть блокнот, освоится с интернет-эксплорером, откроет Гугл. Но как только ты пойдешь дальше (как только появится XPath или селекторы), разные варианты сайтов, государственных или SaaS экосистем, ты столкнешься с тем, что оно не готово и не работает. А дальше, если ты занимаешься развитием собственной платформы, тебе это нужно подстраиваться под изменения, а если всё уже зашито намертво, то ты не можешь гибко подстраиваться к изменениям. Это у нас было на пилоте.

— Как выбирали стэк технологий?

Михаил: Проект подразумевал, что будет и десктопная и web-части, классический front, классический back и десктопное приложение. И по-началу, проект не подразумевал большую команду. Я понимал, что первые несколько месяцев я буду один, расширения грандиозными темпами мы не планировали.

Мне нужно было обеспечить какую-то многостаночность, чтобы 1-3 человека могли делать всё. Потому мы выбрали Electron. Он позволяет на одном и том же языке (у нас это TypeScript) писать десктопное приложение, backend и frontend.

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

Как правило есть проблема переключения контекста с бекэнда на фронтенд. К примеру, бэк на питоне, фронт на JavaScript, популярная комбинация. И даже если это совмещает в себе один человек, ему затратно и тяжело будет переключаться с одного языка на другой. А когда решаешь одну задачу, то переключаешься часто, это не удобно. Мы от этого избавились, при переключении ничего не меняется: один язык, один подход, даже выглядит все одинаково.

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

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

Я взял готовую библиотеку для визуализации. У нас основной продукт — это среда разработки, и там есть визуализация блок-схем. Естественно, я не писал её сам, а взял открытую библиотеку joinjs. Она позволяет работать на уровне svg. С помощью векторных картинок рисовать интерфейсы.

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

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

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

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

Я взял стандартную библиотеку на C# UIAvtomation, ею же в тот момент пользовались наши конкуренты. Недавно мы ее заменили на более современную.

У этой библиотеки была обертка, довольно узкий API, который мы использовали. Потом мы эту библиотеку смогли выкинуть, прикрепить новую и адаптером к этому API приклеить. Это быстро безболезненно происходит, так и надо делать.

— Как реализовывали фичи?

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

Буквально через месяц или два мы начали делать пилотный проект для Почты России.

Мы решили для них задачу по автоматизации выгрузки. У них было десктопное приложение для HR по управлению резюме. Там не было никакого интерфейса, а нужно было вытащить оттуда все резюмешки. Там не было API, базы данных и они не могли их вытащить.

Мы просто прокликивали это приложение, скрэпили данные оттуда и складывали на диск.

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

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

Когда приложение уже большое, на каждую фичу нужно обсуждение. На что фича повлияет, не сломает ли она что-то, а есть ли у нас другой способ. На старте пилить фичи легко, они ничего не ломают, потому что ломать ещё нечего.

— Какой масштаб работы был для почты России?

Михаил: Приложение содержало всех сотрудников Почты России по всей стране. Руками это прокликать невозможно.

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

Пилот был обоюдно-бесплатный и до состояния продакшн мы доводить не стали. Для себя мы сделали proof of concept: на платформе можно решать такие-то задачи, можно с этим идти привлекать деньги, можно клиентам продавать и на ходу допиливать. Этим мы и стали заниматься.

— Как привлекали инвестиции?

Михаил: Нам нужен был рабочий прототип, который бы впечатлял инвесторов. Интерфейс решения для Почты России не был красивым, его делал я, а я не дизайнер. Я сделал под себя, IDE WebStorm Dark mode.

Ранние этапы прототипа

ElectroNeek в 2021

Инвесторы умеют применять фантазию. Им можно показать кривой прототип и рассказать, как он изменится и они поймут. Прототип может быть даже забагованный и глючить, но главное — это показать зерно смысла, чтобы инвестор уловил суть. Клиентам надо показывать уже готовый и красивый продукт. Адекватные люди понимают отличие MVP от конечного продукта. А с неадекватными лучше не работать. Инвесторов «берешь надолго», с адекватными людьми работать приятно.

— Что из себя представляли демонстрации инвесторам?

Михаил: Допустим, я написал новый функционал, и завтра с утра его надо демонстрировать инвесторам. Я понимаю, что в таком виде это показывать нельзя. Может подглючивает что-то, может примера хорошего нет, чтобы показать функционал. Сижу дописываю ночью, придумываю примеры, вылавливаю баги, чтобы утром это хорошо выглядело. Утром прихожу не спавши на демонстрацию. Показываю инвесторам продукт. Почти без сна, зато успешно.

Первое время без этого никак. Нет нормального процесса разработки, когда есть полноценная dev среда, тестовая среда, стендинг, продакшн. Есть только одна среда, она тебе и стендинг и продакшн. Ты один и твоя задача делать быстрее. И работаешь ты как хирург, который только приготовился к операции и «вскрыл» код, а ему говорят: «ну, давай зашивай быстрее и пошли».

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

Сергей: У нас были ограниченные ресурсы, мы получили всего 150 000 долларов из них наличными дошло 70 000. Это все что было, чтобы допилить прототип до нормального продукта и показать первые продажи в России и в США. Потом подняли 0,5 млн долларов. Мы показали быстрые продажи. В нас поверили инвесторы.

Михаил: Как только появились деньги — стали расширять команду, чтобы сделать побыстрее хороший продукт. Что значит «хороший»? На ранней стадии не нужен идеальный продукт, хотя его можно сделать. Это ошибка. Многие умеют делать идеально, но это долго. Если быстро и хорошо, то слишком дорого. Все сразу невозможно. Соответственно, здесь надо сделать достаточно хорошо. Достаточно хорошо — чтобы продавалось.

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

— Как вы нанимаете разработчиков?

Михаил: Я больше обращаю внимание на способности, а не на опыт. Опыт важен, но разработка — дело такое, где постоянно надо чему-то учиться. Когда в проект придётся затащить новую библиотеку, вероятность того, что ты ее знаешь, будет не очень высока. Знания важны базовые. Нам нужно было знание TypeScript, переучивать на другой язык долго. Фреймворк желательно знать. Мы используем от Angular.

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

Часто бывает, что люди пишут программу, а о каких-то кейсах просто не подумали. А кто он них будет думать? QA о них тоже может не подумать. А потом они стрельнут. При этом изначальных данных достаточно, чтобы эти корнер-кейсы предугадать. Это для меня отличие перспективного разработчика от неперспективного: какое количество корнер-кейсов на старте он способен предвосхитить.

— Сколько сейчас людей?

Михаил: Шесть человек — ядровая разработка, которые непосредственно платформу делают. Четыре человека, которые на платформе делают переиспользуемые решения. Они используют именно платформу, плюс дополнительные инструменты на скриптовых языках, и делают конкретные проекты. Я сейчас только про разработчиков говорю. Ещё есть отдел QA, отдельно продуктовая команда. 

— Как ты перешел от написания кода к управленческим обязанностям CTO?

Михаил: После получения инвестиций я ещё несколько месяцев активно писал код. QA мы хоть и наняли, но я в них особо не был уверен. Я сам писал код-ревью.

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

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

— Вот вы смирились с падением качества, что дальше?

Михаил: Смотрим, нет у меня больше опции ревьюить код, это мы уже проходили. Что я ещё могу? Теперь можно процессные вещи налаживать.

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

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

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

В идеале, если я в отхожу в сторону, то всё работает. На старте так невозможно. Шаг в сторону, все сломалось. А сейчас должно быть так, что я на месяц отошёл и ничего не сломалось.

— Как понять когда надо нанимать специального человека?

Михаил: Хватает ли на это узкое горлышко человека? Если человек хотя на 70% будет загружен этой задачей, то можно нанять. Если человек тебе нужен на 5% времени, то наверно, ты пока сам с этим справишься.

— Чем ты сейчас занимаешься?

Михаил: Я по прежнему занимаюсь процессами. И ещё долго буду ими заниматься.
Занимаюсь обсуждением фичей, как и Сергей. Это то, куда растёт наш продукт. Он пропускает это через свою призму, я через свою.

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

— Как ты учишься?

Михаил: Сначала я  четко формулирую проблему. Жизненный опыт многое уже позволяет решать. Я уже знаю гораздо больше, чем на момент выпуска из университета, но все равно есть проблемы, которые я не понимаю как решить.
Для начала я разбираюсь в чем проблема. Допустим, у меня нет какого-то инструмента. Гуглю, смотрю YouTube или какой-то курс, выясняю, как делают профессионалы в конкретной области.

Например, как тестировать большие приложения, когда очень много ручного тестирования? Не успеваем, что делать?

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

Все знать невозможно. Задача любого руководителя научится все, что возможно, делегировать и так, чтобы оставить за собой контрольную функцию.

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

Если на проде какая-то проблема, решение может быть принято без меня. QA говорит, что задача критичная и может принять решение откатить. Мне не нужно для этого просыпаться. Главное, чтобы люди понимали рамки.

— Совет самому себе в молодости?

Михаил: Мне на старте казалось, что сначала надо очень многому научиться. Чего-то я ещё не знаю. Не умею писать веб-сайт, не умею писать бекэнд.  Мне хотелось сначала курс какой-то пройти или университет закончить. На самом деле нет. Возьми и попробуй. Гугл отличный инструмент, там вообще все есть. Решай проблемы точечно. Не умеешь конкретно это делать, конкретно это и научись делать. Не умеешь ты nginx настраивать, вот конкретно это и изучи.

Всего не изучишь. Слишком трудозатратно проходить многонедельный курс по программированию. Лучше начни программировать. Те проблемы, которые будут у тебя возникать, их и решай. Так быстрее. А ещё сильнее погружаешься в проблему, чем читая книжку. Если прочитал от корки до корки 600 страниц, то знания будут поверхностные. На опыте знания глубже.  

Я «открыл для себя Гугл», в том смысле, что я могу со своими знаниями, делать сложные вещи, гугля, и находя точечные решения для затыков. Я так и развивался в дальнейшем.

Книги я читал выборочно. Когда решал проблему, находил фрагмент, где описывается решение. Статьи так же. Лекции тоже можно не целиком смотреть. Лекции бывают на 4 часа. Найди тайм код, посмотри только интересный фрагмент, его может быть достаточно.

— Расскажите про Service Organization Controls (SOС)?

Сергей: Если вы хотите делать приложение  SaaS на американском рынке, особенно что-то, что будет работать в компаниях больше 200-500 человек, сразу возникнет вопрос про SOC (Security Organization Control). Пока его у тебя нет, все его спрашивают. Это история, которая причесывает политики организации распределение по уровню прав и доступа, как проектировать код, приходят аудиторы, проверяют.

Пока его у тебя нет, все нормальные клиенты его спрашивают и не подписывают договор. Как только он появляется, и ты говоришь «вот он у нас есть, хотите пришлем отчет», клиенты отвечают, что не надо, «не хотим читать отчет».

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

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

Если наш клиент — крупная организация, то отсутствие SOС, может быть для них проблемой. Их регламент не позволяет работать с тобой. Поэтому в определенный момент у нас это всплыло.

Либо у тебя есть эта сертификация, SOС (она ещё дорого стоит для начинающего стартапа), либо компания присылают тебе многостраничный опросник о том, как у вас обеспечена безопасность. Ты его читаешь и половину из этого не понимаешь.

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

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

Эта сертификация — мониторинг, непрерывный процесс. Не то, что ты один раз сделал и все. Ты должен регулярно проставлять какие-то «галочки». У тебя данные всегда шифруются при передаче. У тебя данные, которые на серверах всегда в зашифрованном виде, на случай, если на жесткий диск куда-то пропадёт, то никто оттуда ничего не вытащит. Таких примеров там много и более изощренных тоже.

Когда начинаешь гуглить, как этого добиться, находишь простыню на 60 листов А4, что и как нужно делать. И каждый пункт нужно разбирать, потому что ты его не понимаешь. Выглядит как очень долгая работа.

Окей, таким путём мы будем долго идти. А может найдём компанию, которая нам упростит жизнь? Наши компанию. На тот момент мы уже были в Y Combinator. Мы задали этот вопрос ребятам оттуда, нам подсказали выпускников YC, которые автоматизируют эту историю. Услуга не бесплатная, но мы купили у них услугу. Это некоторая админка, в которую ты интегрируешь все свои сервисы. JetSuit, Bitbucket, Gitlab, Jira, AWS, Azure, у кого что. Программа сама изучает, где у тебя какие настройки, и говорит что и где тебе не хватает. Ты точечно исправляешь и автоматом закрываются все пункты, что в этой простыне есть.

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

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

— Расскажи про Y Combinator глазами разработчика?

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

Если говорить по результату. Мы получили больше бизнесовых преимуществ. Так же помогли техническими ресурсами и до сих пор помогают. Сделали более правильную инфраструктуру в облаке.

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

Мы закончили YC в марте 2020, закрыли раунд 2,5 млн долларов. Начался существенный рост и команды разработки, и задач.

— Как вы пришли к той продуктовой команде которая есть сейчас?

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

Сергей: Мы за последние 4-5 месяцев с марта по август, сначала взяли одного продакт-менеджера который имел опыт в RPA. Мы поработали с ним несколько месяцев и не получили результата. Мы не нанимали продакт-менеджера из серии «мы тебя наймем и сразу польется золото», мы хотели прийти к четкому пониманию, какие фичи мы делаем, они нужны для захвата будущего рынка, для решения конкретных проблем клиента, для апсейла. Мы брали продакта на вполне измеряемые метрики и это обговаривали. К сожалению, оба продакта скатывались. Наша вина тоже в этом есть. Мы нанимали людей которые предлагали сделать фичу, «потому что она красивая.» А сколько она денег принесет? Ну, тяжело посчитать… А кому она поможет? Как она поможет выигрывать текущие сделки или хотя бы их не проигрывать? У нас не получалось выстроить такую историю.

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

У нас есть UX-продакт-менеджер, технологический продакт-менеджер, у нас есть Head of Engineering, есть CTO, есть CEO как представитель бизнеса. У нас сформирован продуктовый офис, где продукт «нарезан» на разные части. UX, анализ новых фич, инжиниринг. Мы с Михаилом выполняем роль фасилитаторов в случае приоритезации. Я еще отвечаю за sales-фичи. Дмитрий смотрит на то, как продуктовые фичи транслируются или могут транслироваться в маркетинговые возможности и инструменты, такие как наша глобальная библиотека ботов, созданных клиентами и партнерами.

У нас возникают спонтанные сессии для обсуждения серьезных задач. У нас также есть еженедельный полуторачасовой звонок, где мы планируем следующий спринт, который уже распределен по приоритетам внутри компании. Новые фичи у нас залетают по трем трекам: баги — чиним то, что не работает, тормозит продажу или мешает текущим клиентам; UX — чиним текущее, потому что мы знаем, что продукт всегда можно улучшить; добавляем новое в продукт, что позволит в будущем быть более эффективными. В таком фреймворке и работаем. Мы бы хотели прийти к одному человеку, который занимается всем продактом, но пока нам кажется, что это тяжело.

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

— Можно ли при помощи вашего робота фармить в компьютерных играх, клики в ютюбе?

Дмитрий: На нашей базе один клиент сделал робота, который включает чайник.

Сергей: Робот любую кнопку может нажать. Мы даем средство разработки. Что на нём строят клиенты — это на ответственности людей. Можно построить всё что угодно.

Сергей: Была у нас одна история. Клиент купил услугу, а потом написал: «Я специально выбрал самую не развитую в ИТ направлении девушку в нашей компании, „Олю“. И вот „Оля“ смогла с помощью ElectroNeek создать робота. Если „Оля“ смогла, то любой  в моей компании сможет. Я у вас покупаю продукт!» Это высокий показатель простоты использования. Хотя в основном у нас пользуются разработчики junior или middle уровня. Они получают продукт, в любом стэке (веб, десктоп, есть API или нет), создать приложение (робота?), это свобода, которую дает наш продукт.

Дмитрий: Когда попадает продукт к инвесторам на раннеей стадии, то там историия с «Олей» повторялась, есть свои «Оли» среди инвесторов. Были ситуации когда в продукт залезали партнеры топовых американских фондов (Гэри Тэн из Initialized, бывший партнер YC и инвестор в Coinbase и Instacart). Партнер руками начал собирать робота.

Бонус: собираем робота в прямом эфире

Читать еще

ссылка на оригинал статьи https://habr.com/ru/post/552236/

Реализация Undo в Snackbar на Jetpack Compose

Пользовательский опыт (UX — User Experience) — это то, как пользователи воспринимают продукт и какие впечатления получают от взаимодействия с ним.

В процессе разработки мобильного приложения важно делать акцент на пользовательском опыте в ситуациях, когда от пользователя требуется подтверждение каких-либо действий (или, наоборот, отмена уже совершённого действия). Если приложение будет выводить AlertDialog по поводу и без, пользователю это вряд ли понравится.

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

Чем хорош снэкбар:

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

  • не прерывает взаимодействие пользователя с приложением,

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

Используем Snackbar

В Jetpack Compose уже есть реализация снэкбара. В примере ниже он отображается после нажатия на кнопку:

@Composable fun SnackbarSample() {     val snackbarHostState = remember { SnackbarHostState() }     val coroutineScope = rememberCoroutineScope()     val modifier = Modifier      Box(modifier.fillMaxSize()) {         Button(onClick = {             coroutineScope.launch {                 snackbarHostState.showSnackbar(message = "This is a Snackbar")             }         }) {             Text(text = "Click me!")         }          SnackbarHost(             hostState = snackbarHostState,             modifier = Modifier.align(Alignment.BottomCenter)         )     } } 

В коде два основных компонента: SnackbarHost и SnackbarHostState. Их использование позволяет правильно отображать, скрывать и закрывать снэкбар — в соответствии с гайдлайнами материального дизайна.

Единовременно может отображаться один снэкбар — остальные будут ждать в очереди.

Добавляем Undo в Snackbar

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

Упрощённый пример:

@Composable fun HomeList(taskViewModel: ListViewModel = viewModel()) {     Scaffold {         val list by remember(taskViewModel) {             taskViewModel.taskList         }.collectAsState()          LazyColumn {             items(                 items = list,                 itemContent = { task ->                     ListItem(                         task = task,                         onCheckedChange = taskViewModel::onCheckedChange                     )                 }             )         }     } }  @Composable private fun ListItem(task: Task, onCheckedChange: (Task) -> Unit) {     Row(         modifier = Modifier             .fillMaxWidth()             .height(64.dp)             .padding(8.dp),         verticalAlignment = Alignment.CenterVertically     ) {         Checkbox(checked = task.isCompleted, onCheckedChange = { onCheckedChange(task) })         Spacer(Modifier.width(8.dp))         Text(text = task.title)     } }

Наша composable-функция получает на вход ViewModel, который, в свою очередь, подгружает список задач (viewModel.taskList) и вызывает функцию проверки их статуса (viewModel.onCheckedChange).

Scaffold используется для построения правильной структуры лэйаута. Далее по тексту станет понятно, как она будет связана со снэкбаром. А пока мы имеем такой результат:

Наше приложение должно реализовывать следующее бизнес-правило: в списке отображаются только незавершённые задачи. После нажатия на чекбокс, задача должна сразу же удаляться из списка. За реализацию этой логики отвечает ViewModel.

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

@Composable fun HomeList(taskViewModel: ListViewModel = viewModel()) {     val coroutineScope = rememberCoroutineScope()     val scaffoldState = rememberScaffoldState()     val onShowSnackbar: (Task) -> Unit = { task ->         coroutineScope.launch {             val snackbarResult = scaffoldState.snackbarHostState.showSnackbar(                 message = "${task.title} completed",                 actionLabel = "Undo"             )             when (snackbarResult) {                 SnackbarResult.Dismissed -> Timber.d("Snackbar dismissed")                 SnackbarResult.ActionPerformed -> taskViewModel.onCheckedChange(task)             }         }     }   ... }

Разберём код:

  • Строка #3: сохраняем CoroutineScope (потребуется позже при показе снэкбара)

  • Строка #4: сохраняем ScaffoldState, который содержит настроенный SnackbarHostState.

  • Строка #6: вызываем лямбда-функцию, когда пользователь нажимает на чекбокс. В качестве входного параметра она получает задачу, выбранную в списке.

  • Строка #8: вызываем suspend-функцию showSnackbar() и показываем снэкбар. Используя SnackbarResult, понимаем, какие произошли изменения (как изменилось состояние).

  • Строки #12-14: обрабатываем два возможных результата (Dismissed и ActionPerformed). Если кнопку не нажали, пишем сообщение в лог. Если кнопку нажали, ViewModel меняет значение boolean-переменной isCompleted на противоположное (с false на true). Когда значение переменной isCompleted опять будет false, задача вернётся в список.

Описание ViewModel
data class Task(val id: Long, val title: String, var isCompleted: Boolean)  class ListViewModel : ViewModel() {      private val list = mutableListOf(         Task(1L, "Buy milk", false),         Task(2L, "Watch 'Call Me By Your Name'", false),         Task(3L, "Listen 'Local Natives'", false),         Task(4L, "Study about 'fakes instead of mocks'", false),         Task(5L, "Congratulate Rafael", false),         Task(6L, "Watch Kotlin YouTube Channel", false)     )      private val _taskList: MutableStateFlow<List<Task>> = MutableStateFlow(list)      val taskList: StateFlow<List<Task>>         get() = _taskList.stateIn(viewModelScope, SharingStarted.WhileSubscribed(), listOf())      fun onCheckedChange(task: Task) {         list.find { it.id == task.id }?.isCompleted = task.isCompleted.not()         _taskList.value = list.filter { it.isCompleted.not() }     } }

Теперь мы можем связать наш снэкбар с Scaffold и вызывать лямбда-функцию в качестве параметра в методе onCheckedChange:

Scaffold(scaffoldState = scaffoldState) {     ...     ListItem(         task = task,         onCheckedChange = { task ->             taskViewModel.onCheckedChange(task)             onShowSnackbar(task)         }     ) }

Так как у ScaffoldState уже есть SnackbarHostState, который мы определили ранее, мы просто передаём его в виде параметра и получаем желаемый результат:

И ещё кое-что

В процессе разработки я столкнулся с тем, что после нажатия на чекбокс снэкбар появлялся и тут же исчезал. Решить её мне помог Адам Пауэлл на Kotlinlang в Slack.

Проблема заключалась в следующем: снэкбар удалялся из очереди, когда вызов showSnackbar отменялся. Изначально я объявлял rememberCoroutineScope в compose-функции ListItem, которая формировала элементы списка задач. Проблему решил перенос её объявления выше Scaffold.

Что дальше?

Полный исходный код для это статьи доступен в этом gist-репозитории (и в конце статьи). Не пинайте сильно за реализацию ViewModel. Она примитивна, да, и она здесь лишь для имитации «живых данных». В реальном приложении данные будут поступать, например, из Flow, связанного с Room.

Для своего приложения реализацию Undo в снэкбаре я добавил в этом пул-реквесте. Если есть желание, посмотрите.

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

Полный исходный код
@Composable fun HomeList(taskViewModel: ListViewModel = viewModel()) {     val coroutineScope = rememberCoroutineScope()     val scaffoldState = rememberScaffoldState()      val onShowSnackbar: (Task) -> Unit = { task ->         coroutineScope.launch {             val snackbarResult = scaffoldState.snackbarHostState.showSnackbar(                 message = "${task.title} completed",                 actionLabel = "Undo"             )             when (snackbarResult) {                 SnackbarResult.Dismissed -> Timber.d("Snackbar dismissed")                 SnackbarResult.ActionPerformed -> taskViewModel.onCheckedChange(task)             }         }     }      Scaffold(         scaffoldState = scaffoldState,         topBar = { HomeTopBar() }     ) {         val list by remember(taskViewModel) { taskViewModel.taskList }.collectAsState()          LazyColumn {             items(                 items = list,                 key = { it.id },                 itemContent = { task ->                     ListItem(                         task = task,                         onCheckedChange = { task ->                             taskViewModel.onCheckedChange(task)                             onShowSnackbar(task)                         }                     )                 }             )         }     } }  @Composable private fun ListItem(task: Task, onCheckedChange: (Task) -> Unit) {     Row(         modifier = Modifier             .fillMaxWidth()             .height(64.dp)             .padding(8.dp),         verticalAlignment = Alignment.CenterVertically     ) {         Checkbox(             checked = task.isCompleted,             onCheckedChange = { onCheckedChange(task) }         )         Spacer(Modifier.width(8.dp))         Text(             text = task.title,             style = MaterialTheme.typography.body1,             overflow = TextOverflow.Ellipsis,             maxLines = 1         )     } }  @Composable private fun HomeTopBar() {     TopAppBar {         Box(modifier = Modifier.fillMaxSize()) {             Text(                 modifier = Modifier.align(Alignment.Center),                 style = MaterialTheme.typography.h5,                 text = "My tasks"             )         }     } }  data class Task(val id: Long, val title: String, var isCompleted: Boolean)  class ListViewModel : ViewModel() {      private val list = mutableListOf(         Task(1L, "Buy milk", false),         Task(2L, "Watch 'Call Me By Your Name'", false),         Task(3L, "Listen 'Local Natives'", false),         Task(4L, "Study about 'fakes instead of mocks'", false),         Task(5L, "Congratulate Rafael", false),         Task(6L, "Watch Kotlin YouTube Channel", false)     )      private val _taskList: MutableStateFlow<List<Task>> = MutableStateFlow(list)      val taskList: StateFlow<List<Task>>         get() = _taskList.stateIn(viewModelScope, SharingStarted.WhileSubscribed(), listOf())      fun onCheckedChange(task: Task) {         list.find { it.id == task.id }?.isCompleted = task.isCompleted.not()         _taskList.value = list.filter { it.isCompleted.not() }     } }

От переводчика: комментарии и правки приветствуются.

ссылка на оригинал статьи https://habr.com/ru/post/551856/

Edge платы для домашнего Computer Vision

Я люблю делать всякие странные штуки с Computer Vision. Из того, что я выкладывал на Хабре — умная кормушку для птиц и камера для слежения за ребенком. По работе примерно тем же занимаюсь. Так что слежу за актуальным рынком embedded устройств для ComputerVision. Прошлый обзор я делал полтора года назад. Для Embedded это долго. В этом я сосредоточусь на устройствах которые вышли недавно + некоторый анализ что из этих устройств можно использовать дома/для хобби.

Рассказ будет построен следующим образом:

  • Продуктовые железки которые стали классикой продакшна / железки которые почти доросли до таких. Их можно взять и запустить из коробки. Большие OpenSource комьюнити/персональные фреймворки. Время развертывания обученной сети на такой железке в 1-2 дня.

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

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

  • Железка есть информации почти нет/нельзя получить без запросов. На рынке нет истории использования/успеха.

Сразу несколько дисклеймеров, чтобы не возвращаться к ним:

  • Далеко не все из перечисленного я лично использовал/тестировал

  • Далеко не все перечислено. Я уверен что забыл/не знаю многое. И очень надеюсь что в комментарии накидаете чего-нибудь интересного

  • Я фокусируюсь на устройствах где есть GPU/NPU или прочие ускорители инференса. Безусловно, есть всякие FPGA, и прочее, но я не считаю их применимыми для хоббийных проектов. (что такое NPU GPU TPU и другие аббревиатуры — можно прочитать в этой замечательной статье)

Часть 1. Ближе всего к продукту

С одной стороны, весь этот раздел можно было бы свести к простому перечислению:

  • Jetson

  • Intel

  • Coral

  • Android телефоны

  • Прочие Embedded, устройства с хорошим процессором, без NPU/GPU

И в этом списке за последние 2 года появился бы лишь Coral. Но, в реальности, все сильно интереснее. Появились не только и не столько новые архитектуры, как имплементации/доработки старых. О чем мы и поговорим.

В мире Jetson’ов новинок нет. Сейчас в продаже:

  • jetson nano

  • jetson xavier nx

  • jetson agx

  • jetson tx2

12ого началась конференция GTC от NVIDIA, но ничего нового на ней не объявили, так что, скорее всего, на следующий год ничего нового не будет.

Встречаются имплементации Jetson’а, под другие экосистемы. Самое известное —  AWS Panorama. Jetson находящийся внутри экосистемы Амазона.

Panorama
Panorama

Jetson, безусловно, одна из самых удобных плат для хобби. Есть разводка GPIO, много кода который работает из коробки. Нейронные сети можно никуда не конвертировать, используя в оригинальном фреймворке.
Cтоит понимать, что из всех четырех Jetson’ов для хобби лучше всего подходит Nano. Он стоит лишь 100$, что значительно меньше следующего в серии NX, стоящего 400$. В теории, TX2в середине, но его почти нет в продаже + менее удобная плата. Проектов на Jetson очень много. Например из того что было в медийном пространстве — 1, 2. Вот тут есть неплохая подборка.
Лично я участвовал где-то в 5-7 проектах где Jetson был основной платформой. 2-3 из них переросли в полноценные продукты. Но, вынужден сказать, что для хобби его не использовал ни разу. Почему? Какая-то совокупность факторов всегда. Nano у меня был первой серии, там были баги по питанию. Иногда была не нужна производительность дополнительная. Иногда хотелось опробовать чего-то нового.

В отличие от Jetson, на базе Movidius появляются интересные штуки. В первую очередь это M.2 и mPCIe карты. Какие-то даже уже были, когда я писал прошлый обзор: 1, 2, 3
Сейчас их очень много от разных производителей.

Удобны ли ли они для каких-нибудь прототипов и хобийных проектов? Мне кажется, что ниша есть, но очень узкая:

  • Когда надо много производительности (есть сборки где есть несколько мовидиусов)

  • Когда USB соединение слишком нестабильно, но M.2/PCIe хватит (переносные устройства)

Во вторую очередь — это ряд устройств от luxonis. Они устраивали большую компанию на кикстартере про OAK и OAK-D. OAK это платы где movidius воткнут не на материнскую плату, а на плату с камерой. Кроме того, у них есть несколько устройств с movidius когда он стоит на плате 1, 2. Я не буду вдаваться подробнее тут, кому интересно —  про них я делал более подробный обзор у себя в блоге/на Youtube:

Кому лень читать/смотреть — вот краткая выдержка:

  • + Минус одно USB соединение + к стабильности — для части проектов полезно

  • — От USB все равно не уйти — до прода скорее всего не дойдет

  • + Неплохой дизайн, неплохой корпус

  • — Заменили хороший OpenVino на какой-то мутный DepthAI

  • — Дорого. Дороже чем собрать такое с оригинальным Movidius’ом, дороже чем с Jetson Nano

  • — В камере хорошее разрешение, но провален куда более полезный функционал для машинного зрения (ИК диапазон, нормальное управление выдержкой/частотой, синхронизация с вспышкой, и.т.д.)

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

Кроме luxonis до movidius’а в камере догадался FLIR, достаточно крупный производитель камер. Они выпустили FireFly DL, который явно на порядки более продуктовый чем OAK, а стоит только на 100$ дороже (+объектив).

Чтобы закончить с Movidius окончательно. По простоте использования/наличию документации/комментариям и поддержке — на мой взгляд Movidius — это один из самых разумных ускорителей для своих проектов на нейронных сетях. Его минус — сложный переход с продакшну, и необходимость конвертации сети. То что вышло за последние годы — расширяет возможности использования. Но все же мне не хватает плат сравнимых с RPi3 где мовидиус бы стоял напрямую на плате.

Google Coral. Вот тут много нового. В своем прошлом обзоре я был крайне недоволен им — очень ограниченные платы, очень бажные. Но прогресс. Баги пофикшены, выпущена новая линейка. Есть почти все то же самое что и в movidius, только напрямую от производителя — отдельные платы, стики, M.2, pci-e, чистые чипы, и.т.д..

В качестве основного фреймворка — специальный tflite, где уже сильно меньше потерь на конвертации. Но, как видно, слоев все равно сильно меньше чем в том же ONNX.
Из плюсов, про которые не сказал — на базе Coral уже сторонние производители создают свои решения. Например Asus. Из минусов — считанные разы слышал что его использовали в продакшене. И, обычно, для каких-то простых задач.
Для себя я понимаю почему я избегаю Coral — при прочих равных не хочу трогать TensorFlow. А по текущим характеристикам он нигде не превосходит вариантов выше.

Телефоны. Так же, стоит отметить, многие телефоны получили поддержку из плат сопроцессоров для нейронных сетей. Есть несколько фреймфорков для инференса моделей на них. Например тут и тут описывал. Зачастую телефон стал удобнее чем embedded для пилота и хобби. Основной минус — отсутствие периферии. Второй серьезный минус для меня — внутренняя инфраструктура приложений. Конечно, Unity и Flutter упрощают логику использования. Но все же, лично для меня, телефоны сильно сложнее чем Linux-системы.
С другой стороны, в телефоне уже есть и камера и акселерометр, и интернет.

Прочее. Под «прочим» я в первую очередь подразумеваю системы где заход в нейронные сети идет со стороны процессора. Например в процессорах Intel за счет OpenVino можно сильно оптимизировать сети. На некоторых процессорах, например на RaspberryPI есть оптимизация под инструкции Neon. RPi4 вполне может справляться с какими-то задачами детекции и трекинга в реальном времени. Так что если вам нужно с помощью машинного зрения раз в день проверять рассаду — думаю подойдет.

Часть 2. Работает, но мало информации

Есть такая забавная штука. В ML сейчас 90% знаний открыто. Есть статьи, большая часть публикаций с OpenSource. Подробнейшие фреймворки на Nvidia и Intel. Но рынок аппаратных платформ был исторически не такой. Хотите подключить камеру по csi-mpi к своей платформе? Будьте добры купите дорогущий мануал по протоколу. Хотите разрабатывать на нашей платформе? Для этого вам нужно специальное программное обеспечение которое просто так вы не скачаете. И много фирм по производству железа по-другому и не мыслят. Как результат мы имеем полтора гайда на платформу до её покупки. Невозможность протестировать до покупки. Отсутствие форумов по теме. И проблему с каждой функцией где что-то пошло не так.

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

  • RockChip

  • Gyrfalcon

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

RochChip. Основная платформа на которой все делается — Rockchip 3399Pro. Самая популярная реализация, наверное — Firefly, RockPiN10 или Toybrick.

Что забавно, у того же ASUS есть версия не только на базе Google Coral, но и на базе RockChip.
Сейчас разрабатывается новая версия — 1, 2.
В целом, плюс RockChip’а — это плата которую любят все разработчики железа. Есть референсный дизайн, комплектующие, и.т.д. Собрать продукт проще и быстрее чем на Jetson.
Но перенос сети весьма непредсказуем. Документация куцая и полукитайская. Как поддерживается — не понятно. Я видел несколько проектов где сети все же перенесли. Но, гарантировать что это всегда можно, нельзя.

Gyrfalcon. Вторым примером закрытой архитектуры, но на базе которой я видел проекты — является Gyrfalcon

Забавно, что платы на его базе в продаже почти отсутствуют. Что-то из того что есть: 1, 2, 3 .

Если я правильно понимаю, Gyrfalcon ориентирован на корпоративный рынок. Отсюда и закрытость инфраструктуры  и мало число девайсов в продаже. Глобально, с прошлой моей статьи ничего особо не поменялось.

Делать ли свои проекты на базе этих платформ? Подходят ли они для хобби? В целом, такое мне кажется возможным. Главное чтобы были простые сетки. Классификация/базовая детекция, и.т.д.
По цене такие платформы достаточно дешевы и сравнимы с OpenVino|Jetson вариантами.
Но надо серьезно понимать зачем так делать. Это может быть:

  • желание сделать продукт из своей разработки

  • желание распаять свою систему

  • нехватка в Jetson|RPi каких-то возможностей

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

Часть 3. Внешне все выглядит неплохо, есть какая-то документация, но примеров нет

Пожалуй, сюда я отнесу только одну плату Khadas VIM3 . Много кто о ней знает, но не видел ни одного человека который бы что-то на ней сделал. Есть в открытой продаже, просто купить. Заявлены неплохие параметры по скорости.

Судя по документации перенос моделей достаточно простой. Но, так как никто не пробовал/не тестировал, — не понятны ограничения. Сама плата собрана на базе процессора Amlogic A311D, который содержит NPU модуль. Amlogic многие позиционируют как конкурент RockChip, сравнивая их. Но сравнений именно NPU модулей — нет.

Все что я говорил в прошлом раздели про проекты — глобально справедливо и тут. Единственное, внешне мне приятнее подход Khadas — документация открыта, поддерживаемые гиты, вроде все на русском английском. Возможно как-нибудь возьму попробовать, но пока лень. По цене выглядит неплохо, на уровне Jetson.

Часть 4. Железки есть, информации нет

Большая часть плат тут имеет очень слабую документацию. Часть плат — это отладочные платы для мобильных платформ. Другая часть — платы специально под ML, но по которым очень мало информации и данных в интернете.

BeagleV. Плата которая пока не вышла, но выглядит неплохо. Разработана на базе процессора U74 от SiFive. Используется RISC-V архитектура.

BeagleBoard — странная плата с комьюнити вокруг. Именно вокруг этого комьюнити частично построена плата BeagleV. Плата сделана на базе NPU модуля от Texas Instruments. Вроде даже какие-то репозитории есть:

  1. Фреймворк от TI для обучения нейронных сетей. Аж 55 звезд на гитхабе.

  2. Репозиторий платы. Аж 88 звезд.

Считать ли это «популярным» решением — не уверен. Но, возможно, какие-то базовые сети запустить будет можно.

Пример настоящего Edge (минимальное использование ЦПУ и энергоэффективности) это — Sipeed Maixduino и Grove AI Hat. Но, разработка на них, судя по отзывам, которые я слышал, ужасна. Сети плохо поддерживаются, мало производительности. Вот тут пример использования. Ну, по сути все проблемы обычного Arduino.
Я видел людей которые делали и адекватные проекты на их базе, и хоббийные. Но я не готов:)

Глобально, Qualcomm — это, конечно, производитель процессоров для мобильных. Но, на их же базе, есть какое-то количество именно embedded платформ. При этом, Qualcomm — имеет свой SDK, и свою платформу для исполнения нейронных сетей. Года 2.5 назад я сталкивался с ней. И тогда там была жесть. Простейший слой сложения не поддерживался. Что там говорить про сплиты или объединения. По сути работал лишь VGG на трехканальный вход.
Сейчас, судя по слухам все лучше. К тому же, должен нормально работать Tensorflow lite.
Но вот с платами под эмбеддед у Qualcomm плохо. Есть вот такое (но стоит почти 500 баксов). Или вот такое (мало информации, но выглядит прикольно, за 300 баксов камера + корпус + ускоритель = неплохо).

Примерно так же себя ведет Huawei. Есть фреймворк. Не пользовался, и не знаю. Есть какое-то количество плат. Должен работать Tensorflow lite.
Но, мне сложно придумать где такая плата будет иметь смысл на использование.

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

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

P.S.

Про девайсы которые попадают мне в руки/про которые я читаю — иногда пишу у себя в блоге (telegramm, vk). Наверное, через год-два проапдейчу тут что накопится.
Прошлый апдейт делал на ютубе.

ссылка на оригинал статьи https://habr.com/ru/company/recognitor/blog/551552/