Приложение для Digispark Attiny85 с ИК датчиком температуры Melexis
Репозитории
Приложение для Digispark Attiny85 с ИК датчиком температуры Melexis
Репозитории
Код GRPC содержит пример асинхронного сервиса с потоком сообщений от сервиса клиенту. В нем сервис отправляет сообщения клиенту по одному методом респондера Write() из массива, а когда все элементы массива оказываются отправлены, сервис вызывает метод респондера Finish().
В асинхронном сервисе GRPC использует очередь респондеров. Респондер- это объект, который может взаимодействовать с очередью- а именно, самостоятельно размещаться в очереди после завершения операций чтения/записи Read()/Write(), которые асинхронны. Поскольку RPC вызов включает в себя, как правило, и Read(), и Write(), то есть он выполняется за несколько проходов в очереди, объект из очереди должен хранить свое состояние. Когда все взаимодействие с клиентом завершается, объект нало уничтожить.
Мне нужно было реализовать RPC с потоком сообщений от сервиса клиенту, которые сначала отправлялись сразу, как в примере, а после этого, по мере возникновения событий на сервере отсылались клиенту бесконечно (пока клиент не разорвет связь). Эти события могут произойти в любое время, или вовсе не произойти. Так как события нечастые, реализовывать синхронные сервис показалось накладным. Я не нашел примеров, как это делать, поэтому пишу тут, как можно это реализовал.
Отдельный поток (thread) ждет наступления события, и, когда это происходит, нужно вызвать метод Write() респондеров. В сервисе при вызове такого «долгоиграющего» метода респондеры записываются в массив. Массив, таким образом, хранит «коннекты» клиентов.
Первая, неудачная реализация непосредственно вызывала методы Write() респондеров из отдельного потока. Это работало, но тогда, когда клиент разрывал соединение, из-за гонки при иногда объект с респондеров успевал уничтожиться между временем, когда обхект с респондером был размещен в очереди, но очередь до него не дошла, а раньше, сработало событие отключения, которое уничтожило объект респондера.
Кроме того, может произойти assert в методе респондера Write(), когда два потока одновременно его вызовут.
Вторая реализация- это использование мьютексов для защиты.
Третья реализация выглядит лучше- она не использует мьютексы, а использует саму очередь. Идея в том, что очередь выполняется последовательно, что и обеспечивает защиту. Это также предотвратит неожиданный assert в методе респондера Write(), когда два потока одновременно его вызовут.
Для этого в момент события в очередь размещается объект-«планировщик очереди». Этот объект, когда до него дойдет очередь, выполняет работу по размещению в очередь респондеров клиентов для извещения . Теперь, если какой-то клиент отвалится, очередь на уничтожение связанного респондера будет выполнена позже респондеров для извещения, и сервис не упадет.
В коде ниже показано, что в методе, отвечающим клиенту на RPC запрос, когда все накопленные ранее сообщения отправлены, вместо вызова Finish() респондера указатель на респондер записывается в массив указателей на респондеры, ждущие события вызовом preorderService->clientsListenOrders.put(this);.
void ListenOrderData::Proceed(bool successfulEvent) { switch (status) { case CREATE: status = LISTEN_ORDERS; service->Requestlistenorder(&ctx, &rq, &responder, cq, cq, this); break; case LISTEN_ORDERS: if (!new_responder_created) { new ListenOrderData(preorderService); new_responder_created = true; preorderService->clientsListenOrders.put(this); break; } if (!hasData) { status = FINISH; preorderService->clientsListenOrders.rm(this); responder.Finish(grpc::Status(), (void*) this); break; } responder.Write(result, (void*) this); hasData = false; status = LISTEN_ORDERS_SENT; break; case LISTEN_ORDERS_SENT: status = LISTEN_ORDERS; break; case FINISH: delete this; break; } }
Член hasData нужен, чтобы различать «нормальное» событие от события отсоединения клиента.
Чтобы ловить событие отсоединения, нужно указать GRPC (например, в конструкторе объекта с респондером ListenOrderData), что нужно эти события отлавливать:
ctx.AsyncNotifyWhenDone(this);
Когда уничтожается респондер (объект, его содержащий), нужно удалить из массива ссылку на респондер (или его содержащий объект), это можно сделать в деструкторе, или в Proceed(successful)
Замечание 1: Параметр successful = false указывает на то, что не было чтения или записи, или они завершились ошибкой.
Замечание 2: метод ctx.IsCancelled() указывает, было ли разорвано соединение. Вызвать его можно только после ctx.AsyncNotifyWhenDone(), иначе сервис упадет.
Все хорошо, но, оказывается нельзя просто так взять и добавить в очередь объект.
К счастью есть способ обойти это. используя grpc::Alarm:
alarm.Set(cq, gpr_now(gpr_clock_type::GPR_CLOCK_REALTIME), this);
С помощью этого трюка можно выполнить вставку в очередь объекта, который вставит другие объекты в очередь.
I got Wi-Fi USB stick (from Aliexpress) with Realtek 8811 chip.
In Linux (Ubuntu 16.04) I turn USB mode from the CD-ROM with Windows setup program to Wi-Fi network card mode using usb_modeswitch.
And, of course I need to install driver itself.
1. Install driver rtl8821/8811:
2. Install sub_modewitch with patch:
3. Restart desktop:
After the system kernel is updated, you need to reinstall the rtl8821CU driver.
11 июля 2019 г.
Камеры глубины (Microsoft Kinect, iPhone X, Huawei P30 [“3D фото”], линейка камер Intel) позволяют создавать видео с картой глубины [habr] с небольшим потреблением вычислительных ресурсов, в сравнении с алгоритмами получения карты глубины со стереопары (opencv).
Поэтому возможен рост контента с псевдо-стерео изображением.
Отображение 3D контента без очков существует, но пока не массово [обзор] и требует специальных мониторов с разделением изображения на два глаза, к тому же желательно знать расположение зрителя относительно экрана, что требует датчиков положения зрителя.
Все больше медиа потребляется на мобильных устройствах, на которых нельзя ожидать появления экранов для стереоизображений в ближайшее время. Мобильные устройства можно наклонять (гиросокопы, акселерометры), примеры 3D parallax wallpaper на мобильных можно видеть здесь [youtube].
Предположительно, не все люди видят стереоскопически, особенно вдали- трехмерная картинка на большой глубине создается не оптически, а на основе опыта. Также большая часть людей лучше замечают движущиеся объекты. Поэтому динамическое изменение положения или угла зрения зрителя относительно видимой картинки создает иллюзию трехмерного изображения с эффектом параллакса. Это называется 2d-3d преобразованием или псевдостерео [технология] и применяется, например, для создания стерео календариков. Во всяком случае вау эффект какое время возможен.
Что можно сделать?
Картинка или кадр видео- это двумерный массив цветовых значений, создающей плоскую картинку. Если добавить к изображению (кадру видео) карту глубины, можно пересчитывать (изменять параллакс, применять размытие в зависимости от глубины и другие эффекты) в зависимости от положения глаз зрителя, получаемых с датчиков положения зрителя или устройства.
Это не полноценное 3d (псевдо-стерео), углы обзора будут ограничены и заглянуть за экран очень силно не получится.
Но этого достаточно для создания эффекта параллакса наклонами и применения эффектов, как размытие фона, и может быть в ближайшем будущем массово генерироваться новыми мобильными камерами.
Возможное применение- видео контент (фильмы, ролики), видеочаты, IM, пользовательский интерфейс с “3D” кнопками и другими элементами управления.
Форматы картинок можно дополнить слоем глубины, можно делать баннеры с эффектом параллакса в формате png, например, при поддержке браузером или плагином браузера.
Форматы видео можно, например, дополнить отдельными картами глубины (в отдельных файлах gray scale, как субтитры).
Программное обеспечение с датчиков или вручную пересчитывает картинку, создавая эффект параллакса, меняет фокус камеры (размывает изображение не в фокусе).
GUI использует Z индекс для отрисовки преркоывающихся областей. Виджеты (элементы интерфейса) могут иметь разную высоту, что может быть задано в guideline, как, например, в material design все виджеты имеют высоту 1dp.
Модификация GUI библиотек, тулкитов, и высоту виджетов с добавлением высоты виджетов может быть сделана для получения параллакс эффекта и теней пир изменении положения зрителя.
Facebook 3d photo [видео] [как сделать]
Даже при выключенном WiFi многие iPhone и часть Android смартфонов обнаруживаются точками доступа, в том числе Soft AP, поскольку смартфоны активно сканируют точки доступа, посылая пакеты Probe Request, независимо от того, включен или выключен Wi-Fi на телефоне.
Это делается, в частности, для того, чтобы делать быстрое подключение к точке доступа при включении Wi-Fi, так как отправка Probe Request и получение ответов от точек доступа не потребляет много энергии, но делает включение Wi-Fi быстрым и приятным.
Программная точка доступа hostapd очень популярна, установлена она и в Android телефонах, чтобы раздавать Интернет по Wi-Fi.
Вставляем в USB порт Wi-Fi свисток, устанавливаем и настраиваем hostapd и начинаем смотреть журнал hostapd.
В журнале hostapd фиксируются пакеты Probe Request- видны MAC адрес устройства и уровень сигнала.
В результате набирается довольно много статистики по производителям, помимо телефонов, есть какие-то изделия Ford Motors Company, и очень экзотичные устройства, для чего они предназначены, трудно догадаться.
По реестру IEEE с помощью скрипта определяется производитель телефона, но не всегда. Лучше всего с этим у Samsung.
Небольшое изменение в hostapd (его придется собрать из исходов) позволяет передать событие, когда мобильное устройство отправляет пакет discovery, в другую программу.
В небольшом open source проекте https://gitlab.com/commandus/wacs событие передается другим процессам по TCP или через shared memory с использованием библиотеки nanomsg, чтобы сделать какую-нибудь полезную его обработку.
Очевидное применение, это отслеживать присутствие людей в радиусе действия точки доступа.
Присоединяйтесь к open source проекту.
В новом приложении Уведомления для PC я столкнулся с такой проблемой- сервис, который должен получать уведомления из статусбара, их не получал.
Причина оказалась в том, что Андроид не отслеживает завершение работы сервиса, и при повторном запуске не делает bind сервиса, поэтому, по идее, могли бы помочь перезагрузка телефона, удаление и повторная установка из магазина придожения.
Мне помогло только переименовывание имени класса сервиса ;(
Что будет происходить, если система будет останавливать сервис приложения, или приложение будет крэшиться?
Ошибки «numpad» хеша (http://uri2dec.sourceforge.net/) — 6% по списку доменов в зоне .com на 2015 год.
На графике по оси абсцисс- число попадания имен в зоне .com в хеш, по оси ординат- число доменных имен. Для 94% доменных имен хеш не дает ошибок.
Добавил в github пример курсора для прокрутки ListView из источника данных, отдающих строки по одному или страницами. Не нашел ничего подходящего, пришлось написать свой.
Пример здесь https://www.openhub.net/p/proto-sql