...

суббота, 12 марта 2016 г.

[Из песочницы] Наблюдение об интернационализованных доменных именах и букве K

Контейнеры: Поиски «магического фреймворка» и почему им стал Kubernetes

Мы в «Латере» занимаемся созданием биллинга для операторов связи. В блоге на Хабре мы не только рассказываем об особенностях нашей системы и деталях ее разработки (например, обеспечении отказоустойчивости), но и публикуем материалы о работе с инфраструктурой в целом. Инженер проекта Haleby.se написал в блоге материал, в котором рассказал о причинах выбора в качестве инструмента оркестрации Docker-контейнеров технологии Kubernetes. Мы представляем вашему вниманию основные мысли этой заметки.

Предыстория


Инженерная команда проекта изначально использовала методологию непрерывного развертывания (continuous delivery) Jenkins для каждого сервиса. Это позволяло запускать по каждому коммиту интеграционные тесты, генерировать артефакт и образ Docker, после чего разворачивать его на тестовом сервере. С помощью одного клика любой образ можно было развернуть на «боевом» сервере. Схема выглядела примерно так:

В ячейках под названием John и Doe содержатся наборы Docker-контейнеров, развернутых на конкретном узле. Кроме того для провижининга применяется Ansible. В итоге создать новый облачный сервер и установить на него корректную версию Docker/Docker-Compose, сконфигурировать правила межсетевого экрана и выполнить прочие настройки можно с помощью одной команды. Для каждого работающего в Docker-контейнере сервиса есть сторожевые скрипты, которые «поднимают» его в случае сбоя. Но в такой конфигурации возможны и проблемы.

Если сервер Doe «сгорит» однажды ночью (или просто на нем произойдет кратковременный серьезный сбой), технической команде проекта придется подниматься среди ночи, чтобы вернуть систему в работоспособное состояние. Сервисы, установленные на Doe, автоматически не перемещаются на другой сервер — например, John, поэтому на некоторое время работа системы была бы прекращена.

Есть и другие сложности — расположение на одном узле максимального количества контейнеров, обнаружение сети (service discovery), «заливка» обновлений, агрегирование лог-данных. Нужно было как-то со всем этим справиться.

Нужен был некий волшебный фреймворк оркестрации (orchestration framework), с помощью которого можно было бы распределять контейнеры по узлам кластера. Нужно было добиться того, чтобы работать с множеством узлов можно было бы, как с одним-единственным. Нужно было, чтобы этому волшебному фреймворку можно было сказать «разверни 3 экземпляра вот такого Docker-контейнера где-нибудь в кластере и проследи, чтобы все работало». Отличный план! Дело оставалось за малым — найти такой фреймворк.

Список пожеланий


Технологии развиваются очень быстро, так что даже для соответствия весьма умеренным стандартам, все равно необходимо выбирать инструменты таким образом, чтобы они были живы и поддерживались на протяжении какого-то времени. Инженеры Haleby хотели бы, чтобы их «фреймворк мечты» использовал что-то вроде уже применявшегося ими docker-compose — это позволило бы избавиться от необходимости проведения большого количества работ по реконфигурации и настройке.

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

Помимо этого члены команды Haleby хотели бы, чтобы в выбранном инструменте присутствовала поддержка работы с контейнерами в нескольких облаках одновременно, а также наличие функциональности сетевого обнаружения. Также инженерам не хотелось тратить много времени на настройку, поэтому предпочтительным был бы вариант использования модели «framework as service».

Выбор фреймворка


Анализ существующих на рынке вариантов позволил выделить несколько фреймворков-кандидатов. В их числе:

AWS ECS


AWS ECS Container Service — это высокомасштабируемый и быстрый инструмент управления контейнерами, с помощью которого их можно запускать, останавливать и работать с контейнерами Docker в кластере инстансов Amazon EC2. Если какой-либо проект уже работает в этом облаке, то не рассмотреть данный вариант просто странно. Однако Haleby не работал на Amazon, поэтому переезд показался инженерам компании не самым лучшим решением.

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

Docker Swarm


Docker Swarm — это нативный инструмент кластеризации для Docker. Поскольку Swarm использует Docker API, то любое средство, умеющее работать с демоном Docker, может быть масштабировано с его помощью. Поскольку Haleby использует docker-compose, последняя опция звучала очень заманчиво. Кроме того, использование нативного инструмента знакомой технологии означало, что команде не придется изучать что-то новое.

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

Более того, обновление контейнеров также невозможно было бы провести в автоматическом режиме. Для этого пришлось бы, к примеру, настраивать Nginx в качестве балансировщика нагрузки на различные группы контейнеров. Также многие инженеры в интернете выражали сомнения в работоспособности Swarm — среди них, к примеру, сотрудники Google.

Mesosphere DCOS


После настройки DCOS (операционной системы дата-центра) на AWS и старта работы, Mesosphere кажется неплохим вариантом. С помощью удобного интерфейса можно получить всю информацию о кластере, включая запущенные сервисы, загрузку процессора и потребление памяти. DCOS может работать в любом облаке и сразу с несколькими облаками. Mesos же — это инструмент, проверенный работой в крупных кластерах. Также DCOS позволяет запускать не только контейнеры, но и отдельные приложения, вроде Ruby, а устанавливать важные сервисы можно с помощью простой команды dcos install (это как apt-get для дата-центра).

Более того, с помощью этого инструмента можно работать с несколькими кластерами одновременно — можно запустить Marathon, Kubernetes, Docker и Swarm в рамках одной системы.

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

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

Tutum


Команда проекта описывает его как «Docker-платформа для Dev и Ops», а слоган звучит как «стройте, разворачивайте и управляйте своими приложениями в любом облаке». Интерфейс выглядит вот так:

Кому-то он может показаться не столь эффектным, как у DCOS, но тем не менее система позволяет производить большинство нужных манипуляций с помощью простых кликов мышкой, хотя у Tutum есть и хорошая поддержка командной строки. Для начала работа с системой нужно установить Tutum-агент на каждом узле кластера, после чего узел начинает отображаться в административной панели. Интересный момент — Tutum использует формат объявления стэков из нескольких сервисов или контейнеров, который похож на docker-compose — поэтому специалистам, знакомым с Docker будет еще проще начать работу.

Кроме того, Tutum поддерживает тома с помощью интеграции в кластер Flocker. Тесты, в ходе которых определенные контейнеры «убивались» были пройдены успешно — они воссоздавались в том же состоянии (иногда на разных узлах). Еще одним плюсом стала функция создания ссылок между контейнерами — с ее помощью можно связывать определенные контейнеры в группе.

Для балансировки нагрузки используется HAProxy, который поддерживает виртуальные хосты, так что за одним экземпляром HAProxy можно размещать несколько сервисов. Развертывание сервисов также можно осуществлять разными способами, а для обновления Docker во всем кластере достаточно сделать пару кликов. В дальнейшем компания Docker купила сервис Tutum, так что в будущем он будет полностью интегрирован в экосистему.

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

Kubernetes


Команда Kubernetes описывает проект как инструмент для «управления кластером Linux-контейнеров в качестве единой системы для ускорения Dev и упрощения Ops». Это открытый проект, который поддерживает Google, также его развитием занимается ряд других компаний, в числе которых Red Hat, Microsoft, SaltStack, Docker, CoreOS, Mesosphere, IBM.

Что по-настоящему хорошо в Kubernetes, так это то, что в нем объединен десятилетний опыт Google по построению и работе с кластерами — и все это бесплатно! Запустить Kubernetes можно на своем железе или на мощностях облачных провайдеров вроде AWS для которого даже есть специальные шаблоны формаций.

Кроме того, Google предлагает managed-версию Kubernetes под названием Google Container Engine. Из-за недостатков интерфейса начать работать с ней не так легко, как к примеру с Tutum, однако после того, как пользователю удастся разобраться в системе, работать с ней становится просто.

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

Еще одним существенным плюсом Kubernetes стала возможность обновления всего кластера без прерывания работы. Также тесты подтвердили работоспособность сетевого обнаружения — нужно лишь вбить в адресную строку имя нужного сервиса (http://my-service), и Kubernetes создать подключение к нужному контейнеру. Kubernetes представляет собой модульную систему, компоненты которой можно комбинировать.

Есть у фреймворка и свои минусы — при работе с Google Container Engine система ограничивается одним дата-центром. Если с ним что-нибудь случится, ничего хорошего не будет. Из любой ситуации можно выйти, например, организовав несколько кластеров с помощью балансировщика нагрузки, но «из коробки» решения нет. Однако поддержка работы с несколькими ЦОД планируется в новых версиях более легкой версии фреймворка Ubernetes. Кроме того, Kubernetes использует свой yaml-формат, что приводит к необходимости конвертации файлов docker-compose. Помимо этого, проект еще не настолько развит, как тот же Mesos, который позволяет работать с большим количеством узлов.

Заключение


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

Комментарии (0)

Let's block ads! (Why?)

Как создать анимацию и переходы с помощью Motion UI

[Перевод] 4 способа сделать игровое обучение интересным

Новое поколение UX или самые полезные боты для Slack

Если взглянуть на эволюцию компьютерных интерфейсов, наблюдаются 3 конкретные вехи: командная строка, десктоп с мышкой и «трогательные» интерфейсы. С анонсом Siri и прочих голосовых ассистентвов породилось мнение, что появилась новая веха в этой истории. Я же убежден, что Siri и аналоги пока это только проба пера.

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

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


Meekan


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

Roundtable


Когда каждый из членов команды знает о рабочем статусе друг друга, производительность взлетает. Настало время распрощаться со старой системой отчетности. Roundtable с помощью ключевого слова «create» позволяет вести коллективный todo лист. Также бот автоматически запрашивает обновления о статусе задачи, что дает всему коллективу представление о том, что происходит и кому требуется помощь.

Statsbot


Любой рабочий диалог о статистике или поведенческих факторах требует выгрузки данных из соответствующих сервисов. Более того, часто необходимо живое присутствие нескольких человек перед одним экраном. Statsbot изменит ваше представление о командной работе с аналитическими инструментами. Бот интегрируется с Google Analytics, New Relic, Mixpanel и присылает различные метрики прямо в ваш корпоративный чат. Statsbot является одним из самых популярных ботов для Slack, которым уже пользуется свыше 4000 команд по всему миру.

Atomic Kit


Боитесь упустить наиболее значимые детали разговора? Atomic Kit не позволит потеряться важным сообщениям в вашей команде. Бот агрегирует сообщения помеченные звездочкой и отправляет их в виде email дайджеста всем участникам беседы по заданному расписанию.

Nikabot


Полезный инструмент для контроля рабочего процесса в компании. Nikabot опрашивает сотрудников, о том чем они занимаются и на основе полученных данных создает информативный и интерактивный отчет о проделанной работе для руководства. Стоит это всего 1$ в месяц.

Dbot


Задумывались ли вы когда нибудь о безопасности поступаемой информации в ваших каналах Slack? Встречайте первый антивирус для корпоративного чата — Dbot. Dbot работает в фоновом режиме и предупреждает о вредоносном и опасном контенте в ленте: IP адреса, файлы, URL, MD5 хэш и прочее.

Workbot


Бот предоставляет возможность работать с различными облачными приложения прямо в Slack. Нет просто парсить информацию (хотя и это конечно же тоже), а именно работать. Добавить подписчика в компанию на MailChimp, обновить лид в SalesForce, создать новый тикет в Github или Jira и все это не покидая Slack. Workbot понимает контекст и ассистирует вас, что позволяет взаимодействовать со всеми сервисами на интуитивно понятном уровне.

Для примера, если Workbot уведомляет вас о новом тикете, помеченным как задача с высоким приоритетом в Zendesk, бот спросит: «Не хотите ли вы увидеть больше информации об этом клиенте?». Если ответ будет «Да», то он отобразит информацию о профиле этого пользователя из SalesForce в Slack. Плюс ко всему добавить новую заметку о профиле это клиента, вы также сможете прямо в чате.

Relay


Ни для кого не секрет, что самые привлекательные продукты созданы командами, которые максимально близки к их клиентам. И Relay поможет вам в этом. Бот следит за пользовательской активностью вашего приложения и оповещает о всевозможных событиях в соответствующих каналах Slack. Relay работает на основе аналитической платформы Segment.com.

Growbot


Главной составляющей высокого показателя продуктивности сотрудника является его мотивация. Также для него не менее важно иметь четкое понимание результата от проделанной работы. И очень здорово когда в этом процессе присутствуют элементы геймификации. Growbot распознает слова (props, kudos и др) и присваивает очки к человеку, которому они относятся. Также хочеться упомянуть PlusPlus и HeyTaco.

Safelink


Safelink вводит дополнительный уровень безопасности для наиболее важной информации. Бот загружает сообщение или файл на удаленный сервер Amazon’s SSE-S3 о TLS with AES_256_CBC, которые будут доступны в течении 24 часов. Прочитать сообщение можно только после аутентификации через специальный код, высланный на телефонный номер.

Leo


Самый добрый бот, который измеряет и повышет уровень удовлетворенности ваших сотрудников. Leo анонимно задает ненавязчивые вопросы “Как вы оцените свои отношения с коллегами?”, “Получаете ли вы удовольствие от работы?”, “Понимаете ли вы поставленные перед вами задачи”.

Ace


Удобный и функциональный планировщик задач. Ace умеет не только составлять todo списки, но также бот позволяет делегировать задачи другим сотрудникам и проводить командные опросы. Для того, чтобы поставить задачу досточно указать в начале предложения “todo”.

Большое спасибо всем за внимание.

Считаете ли вы, что боты действительно стали/становятся/станут новым ответвлением в развитии пользовательских интерфейсов?

Проголосовало 55 человек. Воздержалось 12 человек.

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

Комментарии (0)

Let's block ads! (Why?)

пятница, 11 марта 2016 г.

[Перевод] Превью Android N: API и инструменты разработчиков

AlphaGo на пальцах

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

Disclaimer: пост написан на основе изрядно отредактированных логов чата closedcircles.com, отсюда и стиль изложения, и наличие уточняющих вопросов

Как все знают, компьютеры плохо играли в Го потому, что там очень много возможных ходов и пространство поиска настолько велико, что прямой перебор помогает мало.
Лучшие программы используют так называемый Monte Carlo Tree Search — поиск по дереву с оценкой нодов через так называемые rollouts, то есть быстрые симуляции результата игры из позиции в ноде.

AlphaGo дополняет этот поиск по дереву оценочными функциями на основе deep learning, чтобы оптимизировать пространство перебора. Статья изначально появилась в Nature (и она там за пейволлом), но в интернетах ее можно найти. Например тут — http://ift.tt/1phvva2

Сначала поговорим про составные кусочки, а потом как они комбинируются


Шаг 1: тренируем нейросеть, которая учится предсказывать ходы людей — SL-policy network


Берем 160K доступных в онлайне игр игроков довольно высокого уровня и тренируем нейросеть, которая предсказывает по позиции следующий ход человека.
Архитектура сети — просто 12 уровней convolution layers с нелинейностью и softmax на каждую клетку в конце. Такая глубина в целом сравнима с сетями для обработки изображений прошлого поколения (гугловский Inception-v1, VGG, все эти дела)
Важный момент — что нейросети дается на вход:

image

Для каждой клетки на вход дается 48 фич, они все есть в таблице (каждое измерение — это бинарная фича)
Набор интересный. На первый взгляд кажется, сети нужно давать только есть ли в клетке камень и если есть, то какой. Но фиг там!
Есть и тривиально вычисляющиеся фичи типа "количество степеней свободы камня", или "количество камней, которые будут взяты этим ходом"
Есть и формально неважные фичи типа "как давно было сделан ход"
И даже специальная фича для частого явления "ladder capture/ladder escape" — потенциально долгой последовательности вынужденных ходов.

а что за "всегда 1" и "всегда 0"?
Они просто чтобы добить количество фич до кратного 4-м, мне кажется.

И вот на этом всем сетка учится предсказывать человеческие ходы. Предсказывает с точностью 57% и к этому надо относиться осторожно — цель предсказания, человеческий ход, все же неоднозначен.
Авторы показывают, впрочем, что даже небольшие улучшения в точности сильно сказываются на силе в игре (сравнивая сетки разной мощности)

Предсказание этой натренированной SL-policy (SL — supervised learning) уже рвет все прошлые программы Го, без всяких деревьев и переборов.

Включая DeepForest Фейсбука?
С ней не сравнивали, непонятно.

Отдельно от SL-policy, тренируют fast rollout policy — очень быструю стратегию, которая является просто линейным классификатором.
Ей на вход дают еще больше заготовленных фич
image
То есть, ей дают фичи в виде заранее заготовленных паттернов
Она гораздо хуже, чем модель с глубокой сетью, но зато сверх-быстрая. Как она используется — будет понятно дальше

Шаг 2: тренируем policy еще лучше через игру с собой (reinforcement learning) — RL-policy network


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

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

(для любознательных — там чуть более тонко и градиент умножается на разницу между результатом и оценкой позиции через value network)

И вот повторяем и повторяем этот процесс — после этого RL-policy значительно сильнее SL-policy из первого шага.

Интересная деталь! В оригинальной статье пишется, что этот процесс делался всего 1 день (остальные тренировки — недели).

Шаг 3: натренируем сеть, которая "с одного взгляда" на расстановку говорит нам, какие у нас шансы выиграть! — Value network


Т.е. предсказывает всего одно значение от -1 до 1.
У нее ровно та же архитектура, что и у policy network (есть один лишний convolution layer, кажется) + естественно fully connected layer в конце.

То есть у нее те же фичи?
value network дают еще одну фичу — играет игрок черными или нет (policy network передают "свой-чужой" камень, а не цвет). Я так понимаю, это чтобы она могла учесть коми — дополнительные очки белым, за то что они ходят вторыми

Оказывается, что ее нельзя тренировать на всех позициях из игр людей — так как много позиций принадлежит игре с тем же результатом, такая сеть начинает оверфитить — т.е. запоминать, какая это партия, вместо того, чтобы оценивать позицию.
Поэтому ее обучают на синтетических данных — делают N ходов через SL network, потом делают случайный легальный ход, потом доигрывают через RL-network чтобы узнать результат, и обучают на ходе N+2 (!) — только на одной позицию за сгенерированную игру.

Итак, вот есть у нас эти обученные кирпичики. Как мы с их помощью играем?


Внимание, картинко!
image

Итак, у нас есть дерево позиций, в руте — текущая. Для каждой позиции есть некое значение Q, которое означает насколько она ведет к победе.
Мы на этом дереве параллельно проводим большое количество симуляций.

Каждая симуляция идет по дереву туда, где больше Q + m(P). m(P) — это специальная добавка, которая стимулирует exporation. Она больше, если policy network считает, что у этого хода большая вероятность и меньше, если по этому пути уже много ходили
(это вариация стандартной техники multi-armed bandit)

Когда симуляция дошла по дереву до листа, и хочет походить дальше, где ничего еще нет…
То новый созданный нод дерева оценивается двумя способами

  • во-первых, через описанный выше value network
  • во-вторых, играется до конца с помощью супер-быстрой модели из Шага 1 (это и называется rollout)

Результаты этих двух оценок смешиваются с неким весом (в релизе он натурально 0.5), и получившийся score записывается всем нодам дерева, через которые прошла симуляция, а Q в каждом ноде апдейтится как среднее от всех score для проходов через эту ноду.
(там совсем чуть-чуть сложнее, но можно пренебречь)
Т.е. каждая симуляция бежит по дереву в наиболее перспективную область (с учетом exploration), находит новую позицию, оценивает ее, записывает результат вверх по всем ходам, которые к ней привели. А потом Q в каждом ноде вычисляется как усреднение по всем симуляциям, которые через него бежали.

Собственно, все. Лучшим ходом объявляется нод, через который бегали чаще всех (оказывается, это чуть стабильнее чем этот Q-score). AlphaGo сдается, если у всех ходов Q-score < -0.8, т.е. вероятность выиграть меньше 10%.

TL;DR: Policy network предсказывает вероятные ходы чтобы уменьшить ширину перебора (меньше возможных ходов в ноде), value network предсказывает насколько выигрышна позиция, чтобы уменьшить необходимую глубину перебора

Интересная деталь! В пейпере для изначальных вероятностей ходов P использовалась не RL-policy, а более слабая SL-policy.
Эмпирически оказалось, что так чуть лучше (возможно, к матчу с Lee Sedol уже не оказалось), но вот с Fan Hui играли так, т.е. reinforcement learning нужен был только для того, чтобы обучить value network

Напоследок, что можно сказать про то, чем версия AlphaGo, которая играла с Fan Hui (и была описана в статье), отличалась от версии, которая играет с Lee Sedol:

  • Кластер стал больше — 176 GPUs против 280 GPUs
  • Похоже, стала больше тратить времени на ход (в статье все эстимейты даны для 2 секунд на ход) + добавился некий ML на тему менеджмента времени
  • Было больше времени на тренировку сетей. Мое личное подозрение — принципиально то, что больше времени на reinforcement learning. 1 день в изначальной статье это как-то даже не смешно.

Пожалуй, все. Ждем 5:0!

Комментарии (0)

Let's block ads! (Why?)

[Из песочницы] Автоматическое обновление расширений Firefox

Свежак для iOS-разработчиков — Digest MBLTdev

Анонс мероприятия Apple, 3D графика без OpenGL, как использовать UILayoutGuide из кода и война с AdBlock — об этом и не только рассказывает подборка свежих статей в 57 выпуске Digest MBLTdev.

Продолжаем публиковать Digest MBLTdev — полезные материалы для iOS-разработчиков за неделю собранные с просторов мирового интернета. Новости, коды, инструменты, дизайн и прочее.


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

Apple Announces March 21 Media Event
Apple вчера вечером официально анонсировала мероприятие 21 марта. iPhone SE? Новый iPad Pro? Релиз 9.3? Скоро узнаем!
macstories.net

Tunes Connect Adds Weekly Analytics Reports
По мне так им надо серьёзно поработать над самой аналитикой, а не добавлять недельный дайджест. Кажется, немногие на постоянной основе используют их аналитику как инструмент принятия решений.
macstories.net

iMessage Analyzer
Скорее для смеха. Может обработать БД сообщений и показать статистику.
github.com

Mobile Onboarding: Interact, Don’t Tell
Отличные развёрнутые рекомендации по созданию качественного онбординга.
uxplanet.org

View controller lifecycle behavior
Интересная мысль. Можно вынести какую-либо логику в чайлд контроллер и добавлять ее к нужному контроллеру простым вызовом addChildViewController. При этом чайлд контроллер будет получать все события родителя (appear, disappear, ...) даже если он не видим.
irace.me

Goodbye Spacer Views Hello Layout Guides
При работе с Autolayout часто применяется техника, когда пустые вью используются для того, чтобы задавать отступы между элементами, которые можно легко менять. В iOS 9 добавили UILayoutGuide, и теперь эта техника не нужна. К сожалению Interface Builder из Xcode 7.2.1 еще их не поддерживает. Из статьи вы узнаете, как использовать UILayoutGuide из кода.
useyourloaf.com

Using Xcode and Swift Package Manager Together
Чтобы подружить Xcode и Swift Package Manager, нужно всего лишь добавить простенький билд степ и указать, что надо собирать либы как динамические, и не забыть добавить их в проект.
cjwirth.com

Advance
Pure Swift framework для анимаций. Не использует CAAnimation и следовательно render server. Вместо этого при помощи CADisplayLink создается цикл, в котором вызываются колбеки зарегистрированных анимаций, а в этих колбеках уже можно поменять какие-то свойства леера. Таким образом этот фреймворк лучше всего подходит для интерактивных анимаций.
github.com

Swift Asserts
Mike Ash разобрал устройство свифтовых ассертов и объяснил, что все параметры у ассертов помечены как @autoclosure для того, чтобы не было накладных расходов на расчет значений, которые могут не понадобятся. А еще вы можете найти пример обертки над ассертом, которая позволяет навесить на него дополнительные функции, например показ значения выражения.
mikeash.com

Rounding numbers with Swift
Подборка полезных функций для округлений чисел на Swift.
globalnerdy.com

CloudKit Security model
Parse закрыли, но если вам нужна только одна платформа, возможно, подойдет CloudKit. Модель безопасности CloudKit описана плохо, и этот пост проясняет скрытые моменты.
blog.krzyzanowskim.com

The Fibonacci SequenceType
Различные способы представить и обработать последовательность Фибоначи.
bandes-stor.ch

dotSwift 2016 Highlights, part 1
Мы уже писали, что доступны видео с конференции dotSwift. Теперь еще можно почитать о том, какие презентации были самыми яркими.
medium.com

iTrace. Как пишутся буквы?
Шурик Бабаев в том числе разработчик приложения для обучения детей письму. В статье Шурик делится своим опытом и секретным алгоритмом проверки того, что ребенок рисует правильную букву.
habrahabr.ru

Swimat
Плагин для Xcode позволяющий форматировать Swift код. По большей части интересен как пример. Если соберетесь писать свой плагин, можете подсмотреть здесь.
github.com

StreamingKit
Библиотека для iOS и OS X. Умеет кучу всего для проигрывания музыки
github.com

Counting Objects
Вы, наверное, замечали строку «remote: Counting objects: xxx, done», появляющуюся при выполнении git clone. Если вам интересно узнать, что это за объекты, почему GitHub позволяет не дожидаться завершения подсчета и сразу приступить к клонированию, прочтите этот пост от инженера GitHub.
githubengineering.com

10 Years of thinking about Pair Programming
Выводы матерого разработчика, сделанные за 10 лет практики парного программирования.
salfreudenberg.wordpress.com

How OpenGL works: software renderer in 500 lines of code
Крутейший набор лекций, освоив который вы поймете как легко можно создавать 3D графику без OpenGL. Кстати, на Хабре можно найти локализованный вариант.
github.com

New data shows losing 80% of mobile users is normal, and why the best apps do better
Немного жёсткой правды о ретеншне. Читать больно и горько, но эта та реальность, с которой сталкивается большинство разработчиков.
andrewchen.co

Survey says 25 percent of smartphone owners have downloaded ad blockers
Тревожные новости для рекламной индустрии. Тут будет очень интересно посмотреть на предпринимаемые крупными рекламными площадками действия. Войну AdBlock'у в вебе они де-факто проиграли. Ждёт ли их такая же судьба в мобайле?
techcrunch.com

Contributing to open source Swift
Слайды с tryswiftconf, рассказывающие о том, что делать, если хочется контрибютить в Swift. Из интересного: описан pipeline и какие части кода за него отвечают; есть пометки, какими знаниями надо обладать, чтобы контрибютить.
speakerdeck.com

Предыдущие выпуски Digest MBLTDEV и подписка доступны на официальном сайте.
Всё бесплатно и никакого спама, честно!

Комментарии (0)

Let's block ads! (Why?)

Vision-based SLAM: стерео- и depth-SLAM

После небольшого перерыва мы продолжаем серию статей-уроков по SLAM. В предыдущих выпусках мы подготовили программное окружение, а также поработали с монокулярным SLAM. Под катом – урок по использованию SLAM на основе стереокамеры и камеры глубины. Мы расскажем о настройке пакетов и оборудования и дадим советы по использованию двух ROS-пакетов: ставшего традиционным RTAB-Map и свежего вкусного ElasticFusion.



RTAB-Map + стереокамера


Принцип работы


RTAB-Map (Real-Time Appearance-Based Mapping) — это алгоритм визуального графового SLAM, основанный на детекторе замыканий. Детектор использует алгоритм bag-of-words для определения степени подобия новых изображений с камеры изображениям уже посещённых локаций. Каждое такое замыкание добавляет в граф положений камеры новое ребро, после чего граф оптимизируется. Для достижения реалтайма алгоритм применяет хитрый способ управления памятью, ограничивающий количество используемых локаций. В статье разработчиков подробно описано, как все это работает.

Запуск


Настройку RTAB-Map с использованием сенсора Kinect мы рассмотрели на первом уроке, поэтому здесь займёмся настройкой этого пакета для использования со стереокамерой. В качестве таковой будем использовать две обычных USB веб-камеры.

Настройка и калибровка стереопары в ROS


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

Настройка камер в ROS

Мы воспользуемся пакетом usb_cam для получения видеопотока с камер. Создадим файл stereo_camera.launch со следующим содержанием:
<launch>
        <node name="left" ns="stereo" pkg="usb_cam" type="usb_cam_node" output="screen" >
                <param name="video_device" value="/dev/video0"/>
                <param name="image_width" value="640"/>
                <param name="image_height" value="480"/>
                         <param name="camera_frame_id" value="camera_link"/>
        </node>
        <node name="right" ns="stereo" pkg="usb_cam" type="usb_cam_node" output="screen" >
                <param name="video_device" value="/dev/video1"/>
                <param name="image_width" value="640"/>
                <param name="image_height" value="480"/>
                         <param name="camera_frame_id" value="camera_link"/>
        </node>
</launch>


где /dev/video0 следует заменить на идентификатор соответствующий левой/правой камере.
Если при запуске появляется ошибка вида:

[ERROR] [1455879780.737902972]: VIDIOC_STREAMON error 28, No space left on device

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

Удостовериться в том, что обе камеры работают, можно при помощи утилиты ROS rqt_image_view. Утилита должна показывать видео для топиков /stereo/left/image_raw и /stereo/right/image_raw.

Калибровка

Утилита camera_calibration в ROS поддерживает калибровку горизонтальной стереокамеры. Перед запуском нужно подготовить калибровочный образец — распечатать шахматный маркер. Запуск утилиты производится следующим образом:
rosrun camera_calibration cameracalibrator.py --size 8x6 --square 0.054 right:=/stereo/right/image_raw left:=/stereo/left/image_raw left_camera:=/stereo/left right_camera:=/stereo/right --approximate=0.01


где
--size 8x6 указывает количество внутренних углов шахматного узора (8х6 соответствует узору из 9х7 черных квадратов);
--square 0.054 — размер (стороны) квадрата шахматного узора в метрах;
--approximate=0.01 — в нашем случае используются неспециализированные камеры, поэтому необходимо указать параметр, который устанавливает допустимое время рассинхронизации между камерами в секундах.

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

Обработка стерео-изображения


После калибровки камер можно перейти к обработке стерео-изображения. Пакет stereo_image_proc выполняет ректификацию изображений с камер и строит карту диспаратности (disparity map). Запуск производится следующим образом:
rosrun stereo_image_proc stereo_image_proc __ns:=stereo _approximate_sync:=true


для проверки работоспособности можно запустить утилиту image_view со следующими параметрами:
rosrun image_view stereo_view stereo:=/stereo image:=image_rect_color _approximate_sync:=true


Параметры алгоритма обработки стерео-изображений можно настроить при помощи утилиты dynamic_reconfigure. Для запуска нужно выполнить команду:
rqt


и выбрать пункт Dynamic reconfigure в меню Plugins → Configuration.

stereo_image_proc поддерживает два алгоритма обработки: StereoBM (быстрее, первая картинка) и StereoSGBM (semi-global block matching, качественнее, медленнее, вторая картинка).

RTAB-Map


После того как камера была успешно откалибрована, и мы получили адекватную disparity map, можно запустить RTAB-Map. Подготовим launch-файл rtabmap.launch:
rtabmap.launch
<?xml version="1.0"?>
<launch>
   <arg name="pi/2" value="1.5707963267948966" />
   <arg name="optical_rotate" value="0 0 0 -$(arg pi/2) 0 -$(arg pi/2)" />
   <node pkg="tf" type="static_transform_publisher" name="camera_base_link"
        args="$(arg optical_rotate) base_link camera_link 100" /> 

<!-- Choose visualization -->
  <arg name="rtabmapviz"              default="true" /> 
  <arg name="rviz"                    default="false" />
  
  <!-- Corresponding config files -->
  <arg name="rtabmapviz_cfg"          default="-d $(find rtabmap_ros)/launch/config/rgbd_gui.ini" />
  <arg name="rviz_cfg"                default="-d $(find rtabmap_ros)/launch/config/rgbd.rviz" />
  
  <arg name="frame_id"                default="base_link"/>     <!-- Fixed frame id, you may set "base_link" or "base_footprint" if they are published -->
  <arg name="time_threshold"          default="0"/>             <!-- (ms) If not 0 ms, memory management is used to keep processing time on this fixed limit. -->
  <arg name="optimize_from_last_node" default="false"/>         <!-- Optimize the map from the last node. Should be true on multi-session mapping and when time threshold is set -->
  <arg name="database_path"           default="~/.ros/rtabmap.db"/>
  <arg name="rtabmap_args"            default="--delete_db_on_start"/>              
  
  <arg name="stereo_namespace"        default="/stereo"/>
  <arg name="left_image_topic"        default="$(arg stereo_namespace)/left/image_rect_color" />
  <arg name="right_image_topic"       default="$(arg stereo_namespace)/right/image_rect" />      <!-- using grayscale image for efficiency -->
  <arg name="left_camera_info_topic"  default="$(arg stereo_namespace)/left/camera_info" />
  <arg name="right_camera_info_topic" default="$(arg stereo_namespace)/right/camera_info" />
  <arg name="approximate_sync"        default="true"/>         <!-- if timestamps of the stereo images are not synchronized -->
  <arg name="compressed"              default="false"/>
   
  <arg name="subscribe_scan"          default="false"/>         <!-- Assuming 2D scan if set, rtabmap will do 3DoF mapping instead of 6DoF -->
  <arg name="scan_topic"              default="/scan"/>
   
  <arg name="visual_odometry"         default="true"/>          <!-- Generate visual odometry -->
  <arg name="odom_topic"              default="/odom"/>         <!-- Odometry topic used if visual_odometry is false -->
  
  <arg name="namespace"               default="rtabmap"/>
  <arg name="wait_for_transform"      default="0.1"/>
  
  <!-- Odometry parameters: -->
  <arg name="strategy"            default="0" />       <!-- Strategy: 0=BOW (bag-of-words) 1=Optical Flow -->
  <arg name="feature"             default="2" />       <!-- Feature type: 0=SURF 1=SIFT 2=ORB 3=FAST/FREAK 4=FAST/BRIEF 5=GFTT/FREAK 6=GFTT/BRIEF 7=BRISK -->
  <arg name="estimation"          default="0" />       <!-- Motion estimation approach: 0:3D->3D, 1:3D->2D (PnP) -->
  <arg name="nn"                  default="3" />       <!-- Nearest neighbor strategy : 0=Linear, 1=FLANN_KDTREE (SIFT, SURF), 2=FLANN_LSH, 3=BRUTEFORCE (ORB/FREAK/BRIEF/BRISK) -->
  <arg name="max_depth"           default="10" />      <!-- Maximum features depth (m) -->
  <arg name="min_inliers"         default="20" />      <!-- Minimum visual correspondences to accept a transformation (m) -->
  <arg name="inlier_distance"     default="0.1" />     <!-- RANSAC maximum inliers distance (m) -->
  <arg name="local_map"           default="1000" />    <!-- Local map size: number of unique features to keep track -->
  <arg name="odom_info_data"      default="true" />    <!-- Fill odometry info messages with inliers/outliers data. -->
  <arg name="variance_inliers"    default="true"/>    <!-- Variance from inverse of inliers count -->  
        
  <!-- Nodes -->
  <group ns="$(arg namespace)">
  
    <!-- Odometry -->
    <node if="$(arg visual_odometry)" pkg="rtabmap_ros" type="stereo_odometry" name="stereo_odometry" output="screen" args="--udebug">
      <remap from="left/image_rect"        to="$(arg left_image_topic)"/>
      <remap from="right/image_rect"       to="$(arg right_image_topic)"/>
      <remap from="left/camera_info"       to="$(arg left_camera_info_topic)"/>
      <remap from="right/camera_info"      to="$(arg right_camera_info_topic)"/>
          
      <param name="frame_id"                 type="string" value="$(arg frame_id)"/>
      <param name="wait_for_transform_duration"       type="double"   value="$(arg wait_for_transform)"/>
      <param name="approx_sync"              type="bool"   value="$(arg approximate_sync)"/>
          
      <param name="Odom/Strategy"            type="string" value="$(arg strategy)"/> 
      <param name="Odom/FeatureType"         type="string" value="$(arg feature)"/>  
      <param name="OdomBow/NNType"           type="string" value="$(arg nn)"/>
      <param name="Odom/EstimationType"      type="string" value="$(arg estimation)"/> 
      <param name="Odom/MaxDepth"            type="string" value="$(arg max_depth)"/>  
      <param name="Odom/MinInliers"          type="string" value="$(arg min_inliers)"/> 
      <param name="Odom/InlierDistance"      type="string" value="$(arg inlier_distance)"/>       
      <param name="OdomBow/LocalHistorySize" type="string" value="$(arg local_map)"/> 
      <param name="Odom/FillInfoData"        type="string" value="true"/>   
      <param name="Odom/VarianceFromInliersCount" type="string" value="$(arg variance_inliers)"/>
    </node>
  
    <!-- Visual SLAM (robot side) -->
    <!-- args: "delete_db_on_start" and "udebug" -->
    <node name="rtabmap" pkg="rtabmap_ros" type="rtabmap" output="screen" args="$(arg rtabmap_args)">
      <param name="subscribe_depth"     type="bool"   value="false"/>
      <param name="subscribe_stereo"    type="bool"   value="true"/>
      <param name="subscribe_laserScan"      type="bool"   value="$(arg subscribe_scan)"/>
      <param name="frame_id"            type="string" value="$(arg frame_id)"/>
      <param name="wait_for_transform_duration"  type="double"   value="$(arg wait_for_transform)"/>
      <param name="database_path"       type="string" value="$(arg database_path)"/>
      <param name="stereo_approx_sync"  type="bool"   value="$(arg approximate_sync)"/>
        
      <remap from="left/image_rect"        to="$(arg left_image_topic)"/>
      <remap from="right/image_rect"       to="$(arg right_image_topic)"/>
      <remap from="left/camera_info"       to="$(arg left_camera_info_topic)"/>
      <remap from="right/camera_info"      to="$(arg right_camera_info_topic)"/>
      <remap from="scan"                   to="$(arg scan_topic)"/>
      <remap unless="$(arg visual_odometry)" from="odom"  to="$(arg odom_topic)"/>
      
      <param name="Rtabmap/TimeThr"           type="string" value="$(arg time_threshold)"/>
      <param name="RGBD/OptimizeFromGraphEnd" type="string" value="$(arg optimize_from_last_node)"/>
      <param name="LccBow/MinInliers"         type="string" value="10"/>
      <param name="LccBow/InlierDistance"     type="string" value="$(arg inlier_distance)"/>
      <param name="LccBow/EstimationType"     type="string" value="$(arg estimation)"/> 
      <param name="LccBow/VarianceFromInliersCount" type="string" value="$(arg variance_inliers)"/>
      
      <!-- when 2D scan is set -->
      <param if="$(arg subscribe_scan)" name="RGBD/OptimizeSlam2D"          type="string" value="true"/>
      <param if="$(arg subscribe_scan)" name="RGBD/LocalLoopDetectionSpace" type="string" value="true"/>
      <param if="$(arg subscribe_scan)" name="LccIcp/Type"                  type="string" value="2"/> 
          <param if="$(arg subscribe_scan)" name="LccIcp2/CorrespondenceRatio"  type="string" value="0.25"/>
    </node>
  
    <!-- Visualisation RTAB-Map -->
    <node if="$(arg rtabmapviz)" pkg="rtabmap_ros" type="rtabmapviz" name="rtabmapviz" args="$(arg rtabmapviz_cfg)" output="screen">
      <param name="subscribe_depth"      type="bool"   value="false"/>
      <param name="subscribe_stereo"     type="bool"   value="true"/>
      <param name="subscribe_laserScan"       type="bool"   value="$(arg subscribe_scan)"/>
      <param name="subscribe_odom_info"  type="bool"   value="$(arg visual_odometry)"/>
      <param name="frame_id"             type="string" value="$(arg frame_id)"/>
      <param name="wait_for_transform_duration"   type="double"   value="$(arg wait_for_transform)"/>
    
      <remap from="left/image_rect"        to="$(arg left_image_topic)"/>
      <remap from="right/image_rect"       to="$(arg right_image_topic)"/>
      <remap from="left/camera_info"       to="$(arg left_camera_info_topic)"/>
      <remap from="right/camera_info"      to="$(arg right_camera_info_topic)"/>
      <remap from="scan"                   to="$(arg scan_topic)"/>
      <remap unless="$(arg visual_odometry)" from="odom"  to="$(arg odom_topic)"/>
    </node>
  
  </group>
  
  <!-- Visualization RVIZ -->
  <node if="$(arg rviz)" pkg="rviz" type="rviz" name="rviz" args="$(arg rviz_cfg)"/>
  <node if="$(arg rviz)" pkg="nodelet" type="nodelet" name="points_xyzrgb" args="standalone rtabmap_ros/point_cloud_xyzrgb">
    <remap from="left/image"        to="$(arg left_image_topic)"/>
    <remap from="right/image"       to="$(arg right_image_topic)"/>
    <remap from="left/camera_info"  to="$(arg left_camera_info_topic)"/>
    <remap from="right/camera_info" to="$(arg right_camera_info_topic)"/>
    <remap from="cloud"             to="voxel_cloud" />

    <param name="decimation"  type="double" value="2"/>
    <param name="voxel_size"  type="double" value="0.02"/>
    <param name="approx_sync" type="bool"   value="$(arg approximate_sync)"/>
  </node>

</launch>



Данный файл создан на основе стандартного файла конфигурации RTAB-Map для камеры Bumblebee. В нем устанавливается ориентация системы координат камер относительно глобальной системы координат, запускаются модули одометрии (stereo_odometry в нашем случае), SLAM (rtabmap) и визуализации (rtabmapviz или rviz).
Если при запуске отображается ошибка:

[FATAL] The stereo baseline (-0.177000) should be positive

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

Запустим RTAB-Map (эту команду нужно запускать из папки, содержащей rtabmap.launch):

roslaunch rtabmap.launch


Если все прошло хорошо, то мы увидим окно RTAB-Map:

Настройка параметров и возможные проблемы


RTAB-Map предоставляет следующие параметры для настройки работы алгоритма (их можно изменить в launch файле или передать через командную строку):
  1. strategy — алгоритм одометрии: 0=bag-of-words 1=оптический поток
  2. feature — тип детектора фич: 0=SURF 1=SIFT 2=ORB 3=FAST/FREAK 4=FAST/BRIEF 5=GFTT/FREAK 6=GFTT/BRIEF 7=BRISK. Лучше всего, по нашему мнению, себя показывает ORB, он и используется по умолчанию.
  3. estimation — режим работы одометрии: 0:3D, 1:2D.
  4. max_depth — максимальная используемая глубина фич из disparity map в метрах.
  5. inlier_distance — максимальное расстояние между фичами для RANSAC в метрах.
  6. local_map — максимальное сохраняемое количество фич в карте.

Когда использовать SLAM со стереокамерой?


После работы с монокулярными SLAM иметь возможность использовать две камеры — просто счастье, поскольку здесь нет никаких проблем с определением масштаба карты и локализации. Если у Вас есть стереокамера или хотя бы две одинаковых монокамеры — используйте их и стереоSLAM. Однако если Вы хотите добиться хорошего качества карты, то обязательно обзаведитесь настоящей стереокамерой, смонтированной в одном корпусе. Две веб-камеры на скотче — это забавное решение из разряда «я у мамы инженер» для написания урока по SLAM, но для настоящих задач необходимо настоящее оборудование.

ElasticFusion + RGB-D камера


Принцип работы


ElasticFusion позволяет строить плотные 3D-модели окружения на базе сурфелей (от англ. surface element). Алгоритм не использует граф посещённых локаций и полностью опирается только на построенную карту при локализации и поиске замыканий. Для поиска замыканий алгоритм случайно выбирает небольшие части карты, с которыми впоследствии сравниваются новые кадры. После нахождения замыкания участок карты деформируется в соответствии с ошибкой. Все остальные интересности можно увидеть в статье разработчиков. Сразу отметим, что алгоритм очень требователен к железу: для нормальной работы необходима видеокарта nVidia с производительностью более 3.5 TFlOPS, а также CPU вроде Intel Core i5 — i7.

Установка и запуск


Склонируйте репозиторий ElasticFusion в удобную Вам папку:
git clone http://ift.tt/1QLZPDJ


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

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

cd ElasticFusion
./build.sh


Волшебный скрипт сделает за нас почти всё. “Почти” — потому что из коробки ElasticFusion работает только с драйверами OpenNI2. Мы используем Kinect первой версии, и, к счастью, существует простой способ добавить его поддержку в OpenNI2. Для этого сначала соберём libfreenect (клонируйте её в ту же папку, что и ElasticFusion, рядышком):
git clone http://ift.tt/1QLZRLQ
cd libfreenect
mkdir build
cd build
cmake .. -DBUILD_OPENNI2_DRIVER=ON
make


Затем добавим ссылку на драйвер freenect в OpenNI2:
ln -s lib/OpenNI2-FreenectDriver/libFreenectDriver.so ../../ElasticFusion/deps/OpenNI2/Bin/x64-Release/OpenNI2/Drivers/


Ура, теперь мы можем запустить это чудо техники, если у нас подключён Kinect:
cd ElasticFusion/GUI
./ElasticFusion


Если все хорошо, то появится вот такое окно:

Настройка параметров и возможные проблемы


Алгоритм предоставляет пачку параметров для тонкой настройки, которые можно передать в командной строке (а некоторые можно покрутить прямо в GUI). Пока мы запустили ElasticFusion с параметрами по умолчанию. Насколько хорошо оно так будет работать, зависит от конфигурации Вашего вычислительного железа, а также от используемой камеры глубины. Алгоритм может работать только в реалтайме; вообще, Вас могут поджидать такие проблемы:
  1. медленное “заполнение” карты сурфелями. Решается использованием более мощного видеоадаптера, а также настройкой параметров:
    1. установкой меньшего значения Surfel confidence threshold (параметр -c), например, в 2 вместо дефолтных 10;
    2. включением Fast odometry (-fo);
    3. есть еще пара вариантов, которые можно посмотреть на странице проекта, но их использовать не советуем – сильно падает качество.
  2. нестабильное нахождение замыканий. Решается подстройкой параметров модуля поиска замыканий (-ic, -cv, -pt).

Также мы рекомендуем включить релокализацию (-rl), чтобы при потере трекинга алгоритм мог восстановиться сам, а также включить frame-to-frame RGB tracking (-ftf), что дает более плавное движение камеры. Кроме того, необходимо настроить процент использования двух используемых алгоритмом трекеров, что делается установкой параметра -i.
Для нашего железа (Core i5 + GeForce GTX Titan) и Kinect'а первой версии мы подобрали следующие параметры, позволяющие добиться весьма неплохой работы алгоритма:

./ElasticFusion -c 2 -d 4 -i 5 -fo -ftf -rl -ic 1000 -cv 1e-02 -pt 150


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

Когда использовать SLAM с камерой глубины?


Очень часто алгоритмы SLAM, использующие карты глубины, работают с плотными (dense) картами. Это неизбежно влечёт за собой существенные требования к вычислительным ресурсам, поэтому использование такого подхода, например, на малогабаритных роботах затруднено. Кроме того, область видимости таких сенсоров не слишком велика (конечно, если Вы не используете дорогущий 3D LiDAR), поэтому область применения ещё немного сужается. Если Вы не очень ограничены в вычислительных ресурсах, и Вам нужно решить задачу навигации в помещении — тогда проекты вроде ElasticFusion отлично Вам подойдут.
Также существуют и менее ресурсоемкие алгоритмы, например, тот же RTAB-Map может работать и с камерами глубины. Такое решение является компромиссным и отлично впишется в систему навигации менее умного робота.

Выводы и общие рекомендации по применению


  1. Использование стереокамеры или RGB-D сенсора позволяет устранить главную проблему монокулярных алгоритмов SLAM — принципиальную невозможность определения масштаба карты.
  2. В целом, требования алгоритмов к вычислительным ресурсам не зависят от того, что Вы используете — стерео или камеру глубины.
  3. Если Вам необходимо строить карту сцены с большой глубиной (например, вне помещений), то Вам нужна стереокамера (или LiDAR, что существенно дороже).
  4. По возможности используйте стереокамеры, уже произведённые в одном корпусе. Это единственный нормальный способ получить надёжную disparity map.

Этим мы завершаем серию уроков по визуальному SLAM. Не стесняйтесь уточнить/спросить/дополнить/опровергнуть/дискутировать, это для нас всегда приятно :)

Источники и ссылки


Статья 1: настройка окружения для работы со SLAM
Статья 2: монокулярный SLAM
Страница ElasticFusion на сайте разработчиков
Сайт RTAB-Map

Комментарии (0)

Let's block ads! (Why?)

Как подружить JMS Serializer и LiipImagineBundle

Я сейчас занимаюсь написанием API для front-end на AngularJS. Для этого я использую стандартную связку для Symfony:
У меня появилась задача отдавать ссылки на thumb и preview в объектах которые содержат картинки. Я уже использовал в коде LiipImagineBundle и для генерации ссылок в api тоже хотел использовать данный bundle. Проведя некий поиск нужного мне решения я удивился что нет никаких готовых bundlов для этого.

Сразу хочу сказать что я явно не фанат JMSSerializerBundle, так как проект активно не поддерживается что дает некие ограничения при работе с ним + он написан не совсем с учетом производительности. Symfony Serializer будет по лучше, но жизнь и не все так просто)

Также прошу заметить что API планируется быть открытым и ссылки на thumb должны быть присланы в ответе. Просто написать в доке используйте url http://ift.tt/1RUlmJj для получения thumb не подходит, да и не красиво как то)

Вернемся к теме. Поняв что нужно писать свой велосипед я приступил к его написанию. Так как проект для которого он был нужен не маленький пришлось делать так что б поддерживалась разная конфигурация. К примеру у картинки может быть несколько фильтров а может и не быть. Так как я использую для загрузки всего на сервер VichUploaderBundle, то пришлось сделать генерацию ссылок с учетом того что сериализуемое поле может быть полем этого bundle.

В JMSSerializerBundle есть два события которые вызываются при сериализации объект serializer.pre_serialize и serializer.post_serialize которые я использовал.

  • serializer.pre_serialize Используется если нам нужно изменить какую-то информацию в объекте. Например было поле picture с ссылкой на оригинальную картинку, а нужно в место этого туда вставить ссылку на thumb.
  • serializer.post_serialize Используется если нужно добавить результату сериализации дополнительную информацию. Например есть поле image с ссылкой на оригинал картинки и его нельзя перезаписывать, так как оно уже где-то используется тогда мы можем добавить новое поле image_thumb к примеру и положить в него ссылку на thumb.

Документация по использованию bundla и сам bundle находятся на GitHub LiipImagineSerializationBundle.

Комментарии (0)

Let's block ads! (Why?)

Badoo перешли на PHP7 и сэкономили $1M

[Из песочницы] Параметрическая идентификация линейной динамической системы

RetroShare — инструмент для приватного общения и обмена данными

После года пребывания в статусе beta и release candidate, состоялся финальный релиз Retroshare версии 0.6.0
Программа развивается в течение вот уже 10 лет. Предыдущая версия 0.5.5 была выпущена осенью 2013 года и приобрела немалую популярность среди специалистов по криптографии, энтузиастов децентрализованных сетей и рядовых пользователей сети Интернет, для которых безопасность файлообмена и общения не пустой звук. Однако следует отметить, что на одном из наиболее популярных ресурсов рунета нет ни одного материала о криптоплатформе RetroShare, пару упоминаний о ней удалось обнаружить лишь в комментариях. Нижеследующий текст можно считать скромной попыткой исправить это упущение.

Итак, Retroshare — криптографически защищенная децентрализованая платформа для анонимного общения и файлообмена. Система позволяет организовывать обособленные бессерверные Friend-to-Friend сети или одну глобальную сеть (что по факту и существует на сей день) с определённым кругом лиц — например, вашими друзьями, семьёй, коллегами или просто незнакомцами. Соединения устанавливаются напрямую только с теми участниками, которым вы дали разрешение. Это важная особенность, перемещающая подобные сети в рамки особого класса децентрализованных сетей, в которых несанкционированное подключение к вашему компьютеру запрещено без вашей на то доброй воли. Сети такого типа называются „Private p2p“, „Darknet“ или просто „Темная сеть“.

Темные сети наподобие RetroShare, среди прочего, обладают двумя важными характерными признаками:
1) затруднен мониторинг файлообменной и коммуникационной деятельности пользователя силами извне, то есть – со стороны потенциального противника, не подключенного к сети;
2) за пределами так называемого «ближнего» окружения сети RetroShare (и подобных – FreeNet, GNUnet) не представляется возможным достоверно определить даже факт подключения пользователя к такой сети.
Первый признак существенно отличает темные (приватные) анонимные сети от публичных анонимных сетей, где статистика, например, по IP-адресам узлов-участников набирается простым прямым наблюдением по подключению к сети или без него. Второй признак является прямым следствием того, что подключение к произвольному узлу сети невозможно без подтверждения такой операции со стороны контрагента.

Следует особо отметить, что даже в пределах так называемого «доверенного» окружения имеется возможность общаться и обмениваться данными через систему анонимных личностей, идентификатор которых не привязан к персональному сертификату пользователя. Количество создаваемых анонимных личностей не ограничивается; пользователь волен по мере необходимости и/или внешних факторов произвольно создавать и удалять свои личности.

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


Предоставляемые возможности:
— Мгновенные сообщения и почта
— Публичные и приватные чаты
— VoIP — Голосовая и видео связь
— Файлообмен
— Форумы
— Каналы

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

Обмен сообщениями возможен от имени анонимных личностей, так и непосредственно между сетевыми узлами. В первом случае доступна оффлайн доставка, применяется хранение сообщений на узлах общих друзей. Голосовая и видеосвязь доступна только для связи узлов из доверенного окружения. То есть – с теми узлами, с которыми ранее был осуществлен обмен сертификатами.

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

Форумы являются полностью распределенными, и распространяются по принципу подписки. Заинтересовавший вас форум зеркалируется на вашем узле и становится доступен всему вашему окружению. Любой из вашего окружения имеет возможность подписаться на интересующий его форум и, таким образом, ценный контент „расползается“ далеко по сети, а распространение сора затрудняется или блокируется вовсе. Форумы доступны оффлайн для чтения и постинга; синхронизация с другими участниками производится, разумеется, только при связи с ними.

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

Файлообмен похож больше на emule и direct connect, чем на bittorrent. Можно сказать, что от всех перечисленных систем были взяты лучшие свойства. Файлы идентифицируются по отдельности, по SHA-хешу и, следовательно, остаются доступными независимо от переименования и/или перемещения в пределах папки с открытым доступом. Ссылки на файл представляют простой текстовый блок с названием и хешем, похожи на ed2k и magnet.
Не требуются промежуточные меры как .torrent файлы. Но при желании можно организовать группу файлов в компактный вид, для чего реализована поддержка файлов-коллекций, содержащих набор ссылок в текстовой форме.
Файлы расшариваются целыми папками. Отдельным папкам можно давать разные права доступа, для этого имеется уникальная для децентрализованных сетей возможность объединения друзей в группы.
Папки могут быть расшарены как в явном режиме — друзьям доступен просмотр содержимого, так и в анонимном — просмотр недоступен. При этом файлы доступны для скачивания, если пользователь обнаружил их наличие в сети через мощный поисковый сервис.
Поиск возможен не только на узлах друзей, но и по всей доступной сети, благодаря механизму туннелирования данных. В наличии множество параметров для конкретизации поиска, например, по расширению, хэшу и т.п. Закачка ведётся в несколько потоков со всех доступных „направлений“.

Соединения устанавливаются по TCP/UDP IPv4, в разработке IPv6-транспорт. Имеется возможность работы через анонимизирующие сети tor/i2p. Для облегчения связи в случае динамических адресов применяются uPnP, DynDNS, DHT и система обмена контактными данными между общими друзьями. При необходимости все отключаемо.

Традиционный вопрос: а зачем нужна еще одна криптосистема?
Все дело в том, что Retroshare, пожалуй, первая платформа, которая предоставляет надежную и безопасную криптографию в относительно простом для использования виде. И это не просто вещь в себе, криптография ради криптографии. Она дает множество эффективно работающих и полезных сервисов сразу.
Двум людям достаточно один раз обменяться публичными ключами (любым удобным способом) – и после установления связи все возможности будут доступны.

Никаких Условий, звездочек и мелкого шрифта. Все это доступно бесплатно, без регистрации и смс :-). Open Source. Хозяин – Вы.

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

Также следует учитывать особенности распределенных и криптографических систем:
— Нет возможности удалить отправленные сообщения и посты.
— Нет возможности восстановить забытый пароль. Сменить его тоже нельзя.
— При утрате ключа или крахе диска с профилем нет возможности восстановить данные.
— В целях предотвращения бесконечного разрастания занимаемых объемов существуют ограничения на сроки хранения сообщений. Форумы — 1 год, каналы — 4 месяца. Справедливости ради, эти параметры могут быть пересмотрены в перспективе если свободное сообщество RetroShare примет такое решение.

Клиент с открытым исходным кодом, написан на Qt/C++, имеются сборки под все распространенные десктоп-операционки, есть опыт успешного запуска на Android. Имеется поддержка плагинов для расширения функциональности.

Имеется возможность работы в no-gui режиме, в наличии web-интерфейс.
В ближайшей перспективе разработка системы так называемых кругов, для разграничения доступа к ресурсам по группам друзей. В разработке распределенные wiki-сайты, в планах Стена (по аналогии с facebook), и еще масса полезностей, полный список которых доступен по ссылке. Несмотря на незначительное количество разработчиков, ведется активная работа по совершенствованию программы.

Ссылки
Официальный сайт: retroshare.sf.net
Блог разработчиков: retroshareteam.wordpress.com
Исходный код: http://ift.tt/1LW3lLr
Русскоязычный ресурс: adorabilis.wordpress.com
Инструкция по подключению: ru.retroshare.net
Серверы для доступа к публичным чатам: retroshare.rocks
См. также: Теория шести рукопожатий

Комментарии (0)

This entry passed through the Full-Text RSS service - if this is your content and you're reading it on someone else's site, please read the FAQ at http://ift.tt/jcXqJW.

Эксперимент: Использование Google Trends для прогнозирования обвалов фондового рынка

В нашем блоге на Хабре мы уже рассказывали о различных исследованиях, направленных на создание алгоритмов прогнозирования цен акций, к примеру, с помощью машинного обучения. Еще в 2013 году исследователи из бизнес-школы Уорика (Warwick Business School) опубликовали результаты эксперимента, в ходе которого в качестве инструмента для прогнозирования трендов фондового рынка использовался поисковик Google.

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

Как это работает


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

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

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

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

Самым надёжным для США оказалось слово «долг». Отслеживая рынки только по нему, учёные увеличили свой гипотетический портфель ценных бумаг на 326% всего за семь лет. При моделировании стандартной стратегии торгов, которая не учитывала частоту поисковых запросов, им удалось добиться прироста лишь в 16%.

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

Помимо данных Google Trends в ходе эксперимента использовались, к примеру, данные сервиса Amazon Mechanical Turk.

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

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

В документе приводится два исторических примера, подтверждающих эту теорию. Первый из них — случай знаменитого инвестора сэра Джеймса Голдсмита, который успел продать свои акции прямо перед обвалом 1987 года. Позднее он заявил, что в какой-то момент просто перестал понимать рынок, поэтому предпочел «выйти» из него.

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

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

Не только фондовый рынок


Подобный анализ популярности поисковых запросов помогает прогнозировать будущие события не только на фондовом рынке. К примеру, компания Google еще в 2013 году заявляла, что с помощью информации о поисковых запросов трейлеров выходящих фильмов может с вероятностью 94% предсказать кассовость ленты в первые дни проката. Анализ числа поисковых запросов в период четырех недель перед релизом позволяет с крайне высокой точностью прогнозировать сборы в первые выходные.

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

Тем не менее говорить о том, что подобное использование больших данных позволяет получать гарантированно точне предсказания, не приходится — неважно, идет ли речь о сфере финансов, киноиндустрии или здравоохранении. К примеру, ученые из Гарварда и Северо-восточного университета (North Eastern University) заявляли о том, что сервис Google Trends переоценивает степень распространения эпидемий гриппа в США. С критикой в адрес сервиса соглашался и его сооснователь Мэтт Хобебби, который заявлял о том, что его стоит рассматривать в качестве дополнительного инструмента, помогающего принять решение, а не в качестве самодостаточного средства создания прогнозов.

Комментарии (0)

This entry passed through the Full-Text RSS service - if this is your content and you're reading it on someone else's site, please read the FAQ at http://ift.tt/jcXqJW.

[Перевод] Создание отчетов в PowerShell

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

Секреты создания отчетов Глава 33


Эта глава содержит
  1. Работа с HTML фрагментами
  2. Создание стильных HTML отчетов
  3. Отправка отчетов поэлектронной почте

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

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

Листинг 33.1 Плохо спроектированный скрипт инвентаризации

param ($computername)
Write-Host '------- COMPUTER INFORMATION -------'
Write-Host "Computer Name: $computername"

$os = Get-WmiObject -Class Win32_OperatingSystem -ComputerName $computername
Write-Host " OS Version: $($os.version)"
Write-Host " OS Build: $($os.buildnumber)"
Write-Host " Service Pack: $($os.servicepackmajorversion)"

$cs = Get-WmiObject -Class Win32_ComputerSystem -ComputerName $computername
Write-Host " RAM: $($cs.totalphysicalmemory)"
Write-Host " Manufacturer: $($cs.manufacturer)"
Write-Host " Model: $($cd.model)"
Write-Host " Processors: $($cs.numberofprocessors)"

$bios = Get-WmiObject -Class Win32_BIOS -ComputerName $computername
Write-Host "BIOS Serial: $($bios.serialnumber)"
Write-Host ''
Write-Host '------- DISK INFORMATION -------'
Get-WmiObject -Class Win32_LogicalDisk -Comp $computername –Filt 'drivetype=3' |
Select-Object @{n='Drive';e={$_.DeviceID}},
@{n='Size(GB)';e={$_.Size / 1GB -as [int]}},
@{n='FreeSpace(GB)';e={$_.freespace / 1GB -as [int]}} | Format-Table –AutoSize


Код приведенный в листинге 33.1 произведет вывод подобный этому
image
Фигура 33.1 вывод, основанный на строках.

Как видно этот скрипт работает, Дон Джонс (один из авторов) видя вывод из скрипта чистыми строками гневно произносит поговорку с участием божества и щенков (наверное, ругательство в оригинале Don has a saying involving angry deities and puppies that he utters whenever he sees a script that outputs pure text like this). Прежде всего – этот сценарий может выводить только на экран, т.к. вывод ведется через Write-Host. В большинстве случаев, когда вы будете использовать Write-Host, вы будете делать это неправильно. Было бы неплохо если была бы возможность вывести эту информацию в файл, или в HTML? Вы можете добиться этого изменяя все Write-Host на Write-Output, но это по-прежнему будет неправильный путь.

Есть более эффективные способы формирования отчета, и это причина по которой мы написали эту главу. Во-первых, мы предложили бы для каждого блока или функции, где происходит генерация информации создавать один объект содержащий всю нужную информацию. Чем больше вы разобьете на блоки код, тем больше вы сможете повторно использовать эти блоки. В нашем плохом примере, первый раздел «информация о компьютере», должно осуществляться функцией которую мы напишем. Ее можно будет использовать во всех отчетах подобного вида. В разделе «информация о диске» данные указываются одним объектом, объединять информацию из разных источников не нужно, но все командлеты на Write должны уйти. (прим переводчика. Как надо делать смотрите в примере к разделу 33.2.1 Получение исходной информации)

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

Правила нарушающиеся в этих сценариях следующие

  1. Выход представляет собой смесь текста и объектов
  2. Вывод сразу отформатирован

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

33.2 Работа с HTML фрагментами и файлами
Хитрость нашего способа в том, что ConvertTo-HTML можно использовать двумя различными способами. Первый способ – производить полную HTML страницу, второй – производить HTML фрагмент. Этот фрагмент всего лишь HTML таблица с данными что были переданы в командлет, мы произведем каждую секцию отчета в виде фрагмента, а затем соберем фрагменты в полную HTML страницу.

33.2.1 Получение исходной информации
Мы начнем с того что соберем данные в объекты, по одному объекту для каждого раздела отчета. В нашем случае будет два объекта – информация о компьютере и информация о дисках. Условимся что для кротости и ясности мы пропустим обработку ошибок и другие тонкости. В реальных условиях мы добавили бы их. Get-WMIObject сама по себе производит объект содержащий информацию по дискам. Значит нужно еще создать функцию выдающую объект с информацией о компьютере.

function Get-CSInfo {
param($computername)
$os = Get-WmiObject -Class Win32_OperatingSystem -ComputerName $computername
$cs = Get-WmiObject -Class Win32_ComputerSystem -ComputerName $computername
$bios = Get-WmiObject -Class Win32_BIOS -ComputerName $computername

#property names with spaces need to be enclosed in quotes
$props = @{ComputerName = $computername
           'OS Version' = $os.version
           'OS Build' = $os.buildnumber
           'Service Pack' = $os.sevicepackmajorversion
           RAM = $cs.totalphysicalmemory
           Processors = $cs.numberofprocessors
           'BIOS Serial' = $bios.serialnumber}

$obj = New-Object -TypeName PSObject -Property $props

Write-Output $obj
}


Функция извлекает информацию из трех различных классов WMI. Создаем объект используя хеш таблицу, собранную из трех объектов т.к., хотим иметь возможность передавать вывод функции по конвейеру. Обычно мы предпочитаем давать свойствам имена без пробелов, сейчас отклонимся от этого правила потому что собираемся использовать имена в итоговом отчете.

33.2.2 Производство фрагментов HTML отчетов.

Теперь мы можем использовать написанную функцию чтобы получить отчет в HTML

$frag1 = Get-CSInfo –computername SERVER2 | ConvertTo-Html -As LIST -Fragment –PreContent '<h2>Computer Info</h2>' | Out-String


Мы долго двигались к этому трюку, так что его обязательно нужно разобрать:
1. Вы сохраняете вывод в виде фрагмента HTML в переменную с именем $frag1, позже мы сможем вставить его в нужное место вывода либо целиком сохранить в файл.
2. запускается Get-CSInfo, ему передается имя компьютера с которого мы хотим получить данные, сейчас мы прописываем имя компьютера жестко, в будущем мы заменим его на переменную.
3. Получившийся вывод подаем на ConvertTo-HTML, эта команда формирует на выходе фрагмент HTML в виде вертикального списка, а не горизонтально. Список будет имитировать вид старого отчета по негодной-технике-выводить-информацию.
4. Мы используем параметр –PreContent чтобы добавить надпись перед табличкой отчета. Мы добавили теги чтобы получился жирный заголовок.
5. Все что получилось – это и есть трюк – передается дальше на Out-String. Вы увидите что ConvertTo-HTML поставит кучу всего в конвейер. Вы видите, что в конвейер пишутся строки, коллекции строк, всякие разные другие объекты. Все это приведет в конце к проблемам, когда вы попытаетесь собрать это все в окончательную HTML страницу, вместо мы просто подали на Out-String и получили на выходе старую добрую строку.
 
Можно пойти дальше и произвести второй фрагмент. Это легче т.к. не нужно писать функцию, генерация HTML будет выглядеть точно также. Единственное отличие что мы соберем данные этой секции в таблицу, а не список: 
$frag2 = Get-WmiObject -Class Win32_LogicalDisk -Filter 'DriveType=3' -ComputerName SERVER2 |
Select-Object @{name='Drive';expression={$_.DeviceID}},
@{name='Size(GB)';expression={$_.Size / 1GB -as [int]}},
@{name='FreeSpace(GB)';expression={
$_.freespace / 1GB -as [int]}} | ConvertTo-Html -Fragment -PreContent '<h2>Disk Info</h2>' | Out-String


У нас есть оба фрагмента, можно приступить к формированию окончательного отчета.

33.2.3 Сборка финального HTML файла
Сборка включает в себя добавление ваших двух фрагментов, и таблицы стилей. Использование таблицы стилей CSS и языка выходит за рамки этой книги. Таблица стилей позволяет контролировать форматирование HTML страницы так чтобы она выглядела намного лучше. Если вы хотите хороший учебник и ссылки на дополнительные материалы по CSS, проверьте  http://ift.tt/TWl8De

$head = @'
<style>
body { background-color:#dddddd;
           font-family:Tahoma;
           font-size:12pt; }
td, th { border:1px solid black;
           border-collapse:collapse; }
th { color:white;
           background-color:black; }
           table, tr, td, th { padding: 2px; margin: 0px }
table { margin-left:50px; }
</style>
'@

ConvertTo-HTML -head $head -PostContent $frag1, $frag2 -PreContent "<h1>Hardware Inventory for SERVER2</h1>"


 Создается таблица стилей $head, в переменной типа строка описывается нужный стиль. Затем эта переменная передается в параметр –head, а ваши фрагменты перечисляются через запятую в параметре –PostContent. Также добавляется заголовок отчета в параметре –PreContent. Сохраните весь сценарий как C: \ Good.ps1 и запустите его следующим образом:
./good > Report.htm
Это перенаправит вывод в файл Report.htm, который будет красив, как на рисунке 33.2
 
image
Рисунок 33.2 отчет из нескольких фрагментов
 
Может быть это не произведение искусства, но это отчет который выглядит лучше чем отчет на экране которым начиналась эта глава. В листинге 33.2 показан завешенный скрипт, где вы можете задать имя компьютера, по умолчанию localhost. В заголовке прописан [CmdletBinding()], что позволяет использовать –verbose. В теле скрипта вставлены Write-Verbose, вы можете видеть что делает каждый шаг.
 
Листинг 33.2 скрипт HTML инвентаризации
<#
.DESCRIPTION
Retrieves inventory information and produces HTML
.EXAMPLE
./Good > Report.htm
.PARAMETER
The name of a computer to query. The default is the local computer.
#>
[CmdletBinding()]
param([string]$computername=$env:computername)
# function to get computer system info
function Get-CSInfo {
param($computername)

$os = Get-WmiObject -Class Win32_OperatingSystem -ComputerName $computername
$cs = Get-WmiObject -Class Win32_ComputerSystem -ComputerName $computername
$bios = Get-WmiObject -Class Win32_BIOS -ComputerName $computername
$props = @{'ComputerName'=$computername
           'OS Version'=$os.version
           'OS Build'=$os.buildnumber
           'Service Pack'=$os.sevicepackmajorversion
           'RAM'=$cs.totalphysicalmemory
           'Processors'=$cs.numberofprocessors
           'BIOS Serial'=$bios.serialnumber}
$obj = New-Object -TypeName PSObject -Property $props
Write-Output $obj
}
Write-Verbose 'Producing computer system info fragment'
$frag1 = Get-CSInfo -computername $computername | ConvertTo-Html -As LIST -Fragment -PreContent '<h2>Computer Info</h2>' | Out-String
Write-Verbose 'Producing disk info fragment'
$frag2 = Get-WmiObject -Class Win32_LogicalDisk -Filter 'DriveType=3' -ComputerName $computername |
Select-Object @{name='Drive';expression={$_.DeviceID}},
@{name='Size(GB)';expression={$_.Size / 1GB -as [int]}},
@{name='FreeSpace(GB)';expression={$_.freespace / 1GB -as [int]}} |
ConvertTo-Html -Fragment -PreContent '<h2>Disk Info</h2>' | Out-String

Write-Verbose 'Defining CSS'
$head = @'
<style>
body { background-color:#dddddd;
           font-family:Tahoma;
           font-size:12pt; }
td, th { border:1px solid black;
           border-collapse:collapse; }
th { color:white;
           background-color:black; }
table, tr, td, th { padding: 2px; margin: 0px }
table { margin-left:50px; }
</style>
'@
Write-Verbose 'Producing final HTML'
Write-Verbose 'Pipe this output to a file to save it'
ConvertTo-HTML -head $head -PostContent $frag1,$frag2 -PreContent "<h1>Hardware Inventory for $ComputerName</h1>"

Использование скрипта

PS C:\> $computer = SERVER01
PS C:\> C:\Scripts\good.ps1 -computername $computer |
>> Out-File "$computer.html"
>>
PS C:\> Invoke-Item "$computer.html"


Скрипт генерирует HTML файл, который можно использовать в будущем, и выводит на экран отчет. Имейте в ввиду что функция Get-CSInfo может использоваться повторно. Поскольку она выводит объект, а не текст вы можете его использовать в самых разных местах где потребуется выводить туже информацию.
Если вам понадобилось добавить добавить еще информации к отчету, то для добавления новой секции вам будет нужно:
  • Написать функцию или команду генерирующую объект, с информацией новой секции отчета.
  • Создать из этого объекта HTML фрагмент и сохранить в переменную.
  • Добавить эту переменную в список переменных команды сборки окончательного отчета. Таким образом вы дополните отчет.
  • Все

 Да этот отчет — это текст. В конечном счете каждый отчет будет текстом, потому что текст — это то что мы читаем. Сутью этого метода является то что все остается объектами до последнего момента. Вы позволяете PowerShell форматировать за вас. Рабочие элементы этого скрипта могут быть скопированы и использованы в другом месте, что невозможно сделать с помощью исходного текста в начале главы.
 
33.3 отправка электронного письма
Что может быть лучше HTML отчета? Отчет, который автоматически придет на email!
 
К частью PowerShell уже содержит командлет Send-MailMessage. Немного исправим наш скрипт:
Write-Verbose 'Producing final HTML'
Write-Verbose 'Pipe this output to a file to save it'
ConvertTo-HTML -head $head -PostContent $frag1,$frag2 -PreContent "<h1>Hardware Inventory for $ComputerName</h1>" | Out-File report.htm

Write-Verbose "Sending e-mail"
$params = @{'To'='whomitmayconcern@company.com'
           'From'='admin@company.com'
           'Subject'='That report you wanted'
           'Body'='Please see the attachment.'
           'Attachments'='report.htm'
           'SMTPServer'='mail.company.com'}

Send-MailMessage @params


мы изменили конец конвейера перенаправив вывод в файл. Затем использовали Send-MailMessage в качестве вложения. Можно отправить HTML как само тело сообщения. Вам не нужно для этого создавать файл на диске, вы можете взять вывод с конвейера непосредственно. Вот альтернативный пример
Write-Verbose 'Producing final HTML'
$body = ConvertTo-HTML -head $head -PostContent $frag1,$frag2 -PreContent "<h1>Hardware Inventory for $ComputerName</h1>" | Out-String

Write-Verbose "Sending e-mail"
$params = @{'To'='whomitmayconcern@company.com'
           'From'='admin@company.com'
           'Subject'='That report you wanted'
           'Body'=$Body
           'BodyAsHTML'=$True
           'SMTPServer'='mail.company.com'}

Send-MailMessage @params


Здесь мы построили параметры Send-MailMessage в хеш таблице и сохранили их в переменной $Param. Это позволяет использовать splat технику и скормить все параметры команде сразу. Нет никакой разницы что вы наберете их как параметры или укажете через хэш таблицу, работать будет в любом случае, но так лучше читать.
 
33.4 Итог
Построение отчетов, безусловно большая потребность для администраторов, мы хотели показать, что PowerShell хорошо подходит для этой задачи. Хитрость заключается в том, чтобы создавать отчеты таким образом, чтобы извлечение информации отделить от форматирования и создания выхода. На самом деле PowerShell способен предоставить большие возможности по форматированию и выводу при небольшом количество работы с вашей стороны.

Комментарии (0)

This entry passed through the Full-Text RSS service - if this is your content and you're reading it on someone else's site, please read the FAQ at http://ift.tt/jcXqJW.