Военно-морской флот США готовится к испытаниям на воде электрической пушки будущего — рельсотрона

В 2016 году ВМС США приступят к испытаниям на воде рельсотрона. Рельсотрон, или рельсовая пушка — орудие, в котором снаряд выбрасывается не с помощью взрывчатого вещества, а с помощью очень мощного импульса тока. Снаряд располагается между двумя параллельными электродами — рельсами. Снаряд приобретает ускорение за счёт силы Лоренца, которая возникает при замыкании цепи. С помощью рельсотрона можно разогнать снаряд до гораздо больших скоростей, чем с помощью порохового заряда. Выстрел рельсотрона выглядит так:

Современные экспериментальные установки ВМС США способны разогнать снаряд весом в 2-3 килограмма до скорости в 2500 метров в секунду. На таких скоростях уже нет никакой необходимости во взрывчатке — кинетической энергии снаряда достаточно, чтобы нанести цели не меньший ущерб, чем заряд тротила. Сейчас дульную энергию рельсотронов удалось довести до 33 МДж. К 2025 году планируется достичь 64 МДж.

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

image
Эсминец «Замволт»

Несмотря на высокие требования к энергосистеме корабля, военные смотрят на рельсотрон в том числе и как на способ сократить издержки. Один снаряд рельсотрона стоит всего 25 000 долларов — это совсем немного на фоне обычных боеприпасов или, тем более, ракет. Кроме того, снаряды для рельсотрона намного компактнее и безопаснее при хранении. Дальность стрельбы рельсотрона может достигать 180, а в перспективе — 400 км. Это намного больше, чем у традиционной артиллерии и сравнимо с ракетами среднего радиуса действия, которые стоят порядка миллиона долларов за штуку.

Рельсотрон, не единственное электрическое нововведение на американском флоте. Уже летом этого года на борту USS Ponce, десантного корабля ВМФ США, будет установлена лазерная пушка, предназначенная для поражения мелких и подвижных целей — дронов или лодок. Один из главных стимулов к созданию такого оружия тоже является его дешевизна — одна небольшая зенитная ракета стоит несколько сотен тысяч долларов, а лазер требует для своей работы лишь несколько десятков киловатт электричества. Об испытаниях этого лазера писали на Хабре в прошлом году.

ссылка на оригинал статьи http://habrahabr.ru/post/213591/

Gentoo: настройка и подключение через /dev/loop файловой системы с компрессией на примере Reiser4

Есть у меня несколько VPS’ок с Gentoo, бегущих под VMWare, для которых я, пожадничав, выделил всего по 7G дискового пространства. Как-то раз, после выхода очередной версии gcc, на одной из них закончилось место. Покопавшись, я обнаружил, что главными потребителями были директории /usr/src и /usr/portage. Тут же родилась мысль переместить их на файловую систему с компрессией (ага, на NTFS) и выбор пал на Reiser4, так как эти данные идеально подходят для неё — очень много файлов и они все маленькие.

Про эту файловую систему в сети имеется множество противоречивой информации (2013), но, пожалуй, стоит почитать статью (2010) ведущего разработчика. Цитата из статьи:

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

Мал мала меньше Не надо её бояться…

Хочу особо подчеркнуть, так как их часто путают между собой, Reiser4 это не то же самое, что ReiserFS. Это две разных файловых системы! ReiserFS давно уже живет в основном транке ядра, а вот для Reiser4, хотя и появилась она на свет в далеком 2004 году, придется применять патч, который, надо заметить, регулярно обновляется для новых версий ядра.

Качаем и применяем патч в соответствии с вашей версией ядра (у меня в системе linux-3.10.25-gentoo) с этой страницы

Скажем, это можно сделать вот так:

cd /usr/src/linux wget -O reiser4-for-3.10.patch.gz 'http://downloads.sourceforge.net/project/reiser4/reiser4-for-linux-3.x/reiser4-for-3.10.patch.gz?r=http%3A%2F%2Fsourceforge.net%2Fprojects%2Freiser4%2Ffiles%2Freiser4-for-linux-3.x%2F&ts=1393599138&use_mirror=heanet' gunzip reiser4-for-3.10.patch.gz && patch -p1 < reiser4-for-3.10.patch 

Конфигурируем наше ядро. Обратите внимание — поддержка ReiserFS не требуется. Скрин моей конкретной системы, на вашей могут быть другие настройки, но нас сейчас интересует только:
File Systems -> Reiser4
image

и не забываем про:
Device Drivers > Block devices -> Loopback device support
image

Вот пример реальной последовательности команд и действий, которые я выполнял на своем сервере, вдруг, кому-то пригодится:

; Запускаем конфигуратор ядра make menuconfig ; Настраиваем функции ядра: ; Сохраняем новый конфиг, выходим и компилируем ядро make && make modules_install  ; Копируем новое ядро в /boot, кто как привык. Я делаю так: mount /boot && cp arch/x86_64/boot/bzImage /boot/kernel-3.10.25 && cp .config /boot/.config-3.10.25 

Так как я ставлю совсем новое ядро, то нужно подправить настройки загрузчика, я пользуюсь GRUB:

vi /boot/grub/grub.conf 

Рабочая запись для нового ядра выглядит так (просто для примера, у вас может быть всё совсем по-другому):

title Gentoo Linux 3.10.25 md0 root (hd0,0) kernel /boot/kernel-3.10.25 root=/dev/md0 net.ifnames=0 

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

Делаем контрольный замер свободного места на дисках:

df -h  ; Ответ (нас интересует только первая строчка) Filesystem      Size  Used Avail Use% Mounted on /dev/md0        7.4G  4.1G  2.9G  59% /  ; И отдельно наши прожорливые директории du  --summarize -h /usr/portage ; 2.2G    /usr/portage du  --summarize -h /usr/src ; 766M    /usr/src  

Запасаемся попкорном с валидолом и…

umount /boot && reboot 

Не забываем ручками выбрать новую конфигурацию ядра для загрузки:
image
Надеюсь, ваш сервер всё ещё с вами…

Первое и второе мы уже съели, переходим к десерту — созданию loop устройства и монтированием на него образа диска с Reiser4:

; Собираем утилиты для работы с Reiser4 emerge reiser4progs  ; Создаем файл контейнер для нашего образа диска cd /mnt && truncate -s 2G reiser4.img  ; Обратите внимание на размер файла du -h reiser4.img ; 0       reiser4.img du --apparent-size -h reiser4.img ;2.0G    reiser4.img  ; Связываем файл с блочным устройством /dev/loop0 losetup /dev/loop0 /mnt/reiser4.img  ; Создаем файловую систему с компрессией gzip (есть еще lzo, но я не проверял, говорят, что жмет хуже, но работает быстрее). Если кто знает, поделитесь пожалуйста ссылкой на документацию по параметрам для Reiser4 mkfs.reiser4 -f -o create=ccreg40,compress=gzip1 /dev/loop0 

image

Наконец, монтируем наш новый «диск»:

; Для начала, добавим его описание в /etc/fstab echo '/mnt/reiser4.img        /mnt/reiser4    reiser4         loop,noatime    0 0' >> /etc/fstab  ; Создаем точку монтирования mkdir reiser4  ; Барабанная дробь... монтаж... mount /mnt/reiser4  ; И... убедимся, что все хорошо mount | grep mnt ; Ответ - /mnt/reiser4.img on /mnt/reiser4 type reiser4 (rw,noatime) 

Перемещаем требуемые директории на новое место жительства (тут можно выпить чашечку кофе и поделать другие дела)

mv /usr/portage /mnt/reiser4 && ln -s /mnt/reiser4/portage /usr/portage mv /usr/src /mnt/reiser4 && ln -s /mnt/reiser4/src /usr/src 

Всё, можно сделать контрольный и подсчитывать профит:

df -h  ; Ответ - в зеленой зоне прибыли получили 1.2G  Filesystem      Size  Used Avail Use% Mounted on /dev/md0        7.4G  2.9G  4.2G  41% / devtmpfs       1004M     0 1004M   0% /dev tmpfs           201M  392K  201M   1% /run shm            1004M     0 1004M   0% /dev/shm cgroup_root      10M     0   10M   0% /sys/fs/cgroup /dev/loop1      2.0G  1.8G  191M  91% /mnt/reiser4  ; Наш файл-контейнер reiser4.img занимает 1.8G    ; Теперь можно сделать нашу новую конфигурацию ядра основной и перезагрузить систему с последующей проверкой: mount | grep mnt ; Ответ - /mnt/reiser4.img on /mnt/reiser4 type reiser4 (rw,noatime) ; и проверить portage, запустив emerge -p world  

Итого: наши исходники занимали 3.9G, после упаковки это значение уменьшилось до 1.8G, или 46% (сжались больше, чем в два раза!) от исходного размера. Мелочь, конечно, но приятно.

Такая конфигурация используется у меня около года без каких-либо проблем, 2G еще ни разу не закончились, ядро не паниковало, а CPU не расправился во время emerge -DNu world. Однако, все-таки есть один минус, если в таком контейнере закончится место, то для увеличения его размеров придется создавать новый файл большего размера и переливать в него все содержимое из старого файла. К сожалению, утилита resize_reiser4 все ещё никем не написана. Возможно, если кто-то знает другой способ увеличения размера этой файловой системы, то поделитесь пожалуйста в комментариях. И в каких файловых системах, кроме NTFS и BRTFS, есть поддержка прозрачного сжатия данных?

Цитата из статьи, ссылка на которую дана в начале поста:

The Reiser4 performance results were mixed but overall its performance was decent compared to EXT4/XFS/Btrfs given the limited manpower devoted to this out-of-tree file-system and its unfortunate history. Beyond porting the file-system to newer versions of the Linux kernel and fixing bugs, there’s been no major development progress on Reiser4 in months. At this time, however, it appears there are still no formal plans for merging Reiser4 into the mainline Linux kernel anytime soon.

ссылка на оригинал статьи http://habrahabr.ru/post/214255/

Термостатирование в доме

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

Введение

Современный загородный дом с автономным отоплением обычно предполагает наличие газового котла. В самом примитивном варианте управление отоплением осуществляется двумя способами:

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

При этом, современные котлы, как правило, поддерживают внешнее управление. Основная цель такой фичи – подключение различного рода терморегуляторов, которые позволяют выставлять мощность котла не в абстрактных градусах воды в батареях (одни и те же цифры температуры воды могут приводить к совершенно разным результатам в зависимости от внешних условий), а в терминах гораздо более понятной целевой температуры места, где установлен регулятор. «Внешнее управление» может означать все что угодно, но обычно это либо какой-то проприетарный протокол конкретного производителя техники (как, например, делает Bosch), либо одна из реализаций протокола OpenTherm.
Главная проблема упомянутых терморегуляторов для меня – цена. При стоимости котла порядка 25000 руб цена регулятора в 9000 руб кажется несколько завышенной.
В результате двухсторонних консультаций с жабой была согласована смета, в полтора порядка меньшая стоимости типичного коммерческого регулятора, после этого началась отработка вариантов реализации доморощенного регулятора.
Перед регулятором были поставлены следующие цели:

  1. Он должен поддерживать целевую температуру в месте, температурный датчик которого выбран в качестве контрольного, с точностью +-0.5 градуса
  2. Он должен позволять выставлять целевую температуру
  3. Он должен позволять мониторить базовые аспекты самого регулятора и котла

OpenTherm

Исследование возможностей построения началось с изучения возможностей котла по внешнему управлению. После снятия кожуха был обнаружен некий разъем, на котором висела перемычка. Изучение документации к котлу вселило надежду, что оно – и есть тот самый разъем для внешнего управления. Тут надо упомянуть особое усердие, с которым готовилась русскоязычная документация на мой итальянский котел Ferroli. В документации есть описание разъемов. Напротив интересующего меня значилась сакральная надпись «Единица среды». Интуиция настойчиво намекала, что это работа переводчиков, незнакомых с предметной областью, надо бы искать англоязычную документацию (уж на английский-то всяко должны были грамотнее перевести). После выкапывания из интернета PDF-ки с английской версией руководства к котлу все прояснилось, напротив того же разъема красовался текст «Room unit». Там же была ма-а-а-ахонькая иконка, которую при определенной доле фантазии можно было принять за логотип OpenTherm. «Это то, что нужно» — подумал я и стал планировать зверские эксперименты над котлом (за окном было -25, так что самое время было спалить электронику отопителя).
Тут надо сделать необходимый экскурс в OpenTherm. Протокол это не закрытый и не открытый. Не закрытый потому что, если у вас окажется спецификация, то никто вас преследовать не будет. Не открытый потому что никто вам спецификацию протокола просто так не даст. Вступите в OpenTherm Alliance за $$$$$$$, тогда получите доступ к телу протокола. Порывшись в глубинах интернета выцепил спецификацию OT2.2.
На физическом уровне OpenTherm – это две слаботочные линии с открытым напряжением порядка 42В. Управляющее устройство, будучи подключено к ним, может одновременно и питаться и контролировать ведомое.
Спецификация определяет два уровня протокола: OT/+ и OT/Lite.
Первый – это протокол в смысле, в котором это слово понимают большинство людей в IT. Т.е. это некий набор запросов и ответов, которые ходят между управляющим устройством (оно же master unit, оно же room unit, в нашем случае таковым является регулятор) и ведомым(оно же slave unit, это котел). Протокол делится на обязательную часть, в которую входят команды «включить/выключить горелку», «отрапортовать статус» и «установить ту самую температуру воды после контура нагрева (параметр называется setpoint)». В необязательной — куча других, начиная от управления модуляцией пламени до съема расхода газа, давления и скорости движения воды в контуре. При этом управляющее устройство управляет изменением напряжения в этих линиях, а ведомое отвечает изменением тока.
OT/Lite – это более простая штука. Если у вас не хватает ума реализовать OT/+, вы можете просто генерировать ШИМ-сигнал, в соответствии со скважностью которого котел будет управлять установкой setpoint.
Кроме того, спецификация определяет еще тестовый режим, при котором линии накоротко замкнуты. В этом режиме котел греется до тех пор, пока ему не надоест (читай, пока не будет достигнута верхняя планка температуры воды, установленная на самом котле). Так котел работает без внешнего регулятора (поэтому там при вскрытии висела перемычка).

OpenTherm, но не совсем

Сразу развею интригу и скажу, что рулить котлом по OpenTherm не получилось. Была собрана схема сопряжения и даже написана библиотека, реализующая довольно значительную часть OpenTherm, но котел упорно отказывался включаться в режим управления по OpenTherm и ничего не отвечал. Точнее сказать, микроконтроллер ничего не регистрировал в качестве ответа. Отвечал котел или нет, без осциллографа сказать невозможно. Как только пришло понимание этого факта, был заказан USB осциллограф (он же восьмиканальный логический анализатор, он же USB-бластер) за 40 вечнозеленых (который, имею сказать, — просто мегавещь!). Осциллограф, как полагается, должен был идти из Китая неопределенной время и прийти где-то весной, когда актуальность терморегулирования, хм, несколько меньше чем зимой. Поэтому было решено использовать ту самую тестовую фичу OpenTherm для управления котлом, чтобы хоть примерно посмотреть что из затеи может получиться.

Как рулить котлом

Созерцание котла долгими зимними вечерами привело к понимаю, что логика его работы довольно проста. Вы выставляете температуру воды (setpoint), скажем 55С. Он начинает греться, пока температура не достигнет 60C. Затем он выключается и вновь включается, когда температура воды достигнет 50C. Этакие качели с гистерезисом вокруг заданного значения. Имея «тестовую фичу», очень легко с помощью внешнего устройства управлять котлом, чтобы он работал ровно так же, как и без оного.
Еще одно последствие созерцания котла – понимание какую температуру воды нужно выставить на нем в зависимости от температуры на улице, чтобы в доме плюс-минус лапоть было комфортно.
Итак, управление котлом складывается из двух алгоритмов:

  1. Алгоритма включения-выключения горелки в зависимости от желаемого setpoint и текущей температуры воды
  2. Алгоритма вычисления setpoint на основе имеющихся температурных данных

Тут надо сделать необходимое отступление в принцип работы терморегуляторов, имеющихся на рынке. Они бывают двух родов:

  1. Классические. Принцип работы – холоднее, чем должно быть — надо греть, теплее – не надо греть. Второй принцип – если сильно холоднее, нужно сильно греть
  2. Так называемые регуляторы c OTC (outdoor temperature compensation), т.е. регуляторы с компенсацией температуры на улице. Эти устроены хитрее. Они позволяют задать пользователю зависимость setpoint от температуры на улице. Теоретически они должны рулить температурой в доме аккуратнее

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

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

Аппаратная часть

От аппаратной части требуется чтобы она:

  1. Принимала данные из эфира
  2. Позволяла выставлять целевую температуру в доме
  3. Выводила на экран базовые показатели
  4. Умела «закорачивать линию» управления котлом
  5. Посылать данные о своей работе и работе котла обратно в эфир, чтобы они могли быть пойманы центральным юнитом и затем визуализированы

Этими требованиями продиктована схема.
image
Начать стоит с самой простой части – части управления котлом. JP1 – разъем, к которому подключаются две линии управления котлом. S1 — тумблер, который закорачивает линии управления котлом и, таким образом, переводит его в автономный режим (мало ли чего с контроллером случится). Мост D1-D4 нужен для обеспечения толерантности по полярности подключения к котлу. Оптопара U1 выполняет роль реле и обеспечивает гальваническую развязку между высоковольтной линией управления котлом (напомню, в открытом состоянии это целых 42V) и TTL-частью схемы. R2 – ограничительный резистор, нужный для того, чтобы ток через вывод D5 (через который и осуществляется управление) микроконтроллера не был слишком большим. В принципе, эту часть можно было заменить слаботочным реле, но… В глубинах души теплится надежда, что котел поддерживает OT/+ и удастся управлять им цивилизованно. Реальная схема сопряжения с котлом несколько сложнее. Тут она описана лишь в мере, необходимой для управления котлом в режиме замкнуто/незамкнуто.
Температурный сенсор DS18B20 подключен к выводу 12 микроконтроллера. Между data-выводом DS18B20 и шиной питания в соответствии со спецификацией подключен резистор R4.
LCD экран на основе контроллера HD44780 – две строки по восемь символов. Схема включения классическая: Vcc – на шину питания, Vss – земля, на V0 подается опорное напряжение для регулировки контрастности, образованное делителем в лице построечного резистора R3. R3 можно один раз подкрутить по вкусу и забыть. Вывод R/W посажен на землю. Остальные выводы подключены так: RS->вывод 11 контроллера, Enable -> 10, DB4->4, DB5->7, DB6->8, DB7->9.
Приемник подключен к выводу 2, передатчик – к выводу 3.
К выводу A0 подключен переменный резистор, образующий делитель. На основании напряжения на выводе A0 прошивка контроллера будет делать вывод о целевой температуре в доме.

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

Алгоритм работы выглядит так:
image
В основном МК проводит время, ожидая сообщения в эфире. Если в течение заданного времени сообщение не пришло, алгоритм все равно выполняет основное тело(ведь за это время могла измениться температура воды в контуре и, возможно, пришла пора включить или выключить горелку).
Параллельно с этим по таймеру происходит измерение напряжения на A0, в соответствии с которым устанавливается целевая температура в доме. Напряжению 0 соответствует температура 18C, напряжению Vcc соответствует температура 26C. Если температура меняется, т.е. пользователь в данный момент крутит ручку, то происходит обновление экрана, на котором всегда отображаются три параметра: целевая температура в комнате, температура воды в контуре, целевая температура воды в контуре на текущий момент.
Целевая температура воды в контуре считается по следующей формуле:
Trrw = 20 + (Trr-To) + (Tr-Trr)*30, где
Trrw- целевая температура воды в контуре
Trr – целевая температура в доме
To – температура на улице
Tr – температура в доме
Как видно, есть некоторое слагаемое сдвига 20 (подобранное эвристически), слагаемое OTC (Trr-To) которое тем больше, чем больше разница между целевой температурой в комнате и температурой на улице и штраф за недостижение целевой температуры в комнате (Tr-Trr)*30.
Реализация алгоритма довольно тривиальна, понять можно, посмотрев скетч прошивки.

Скетч

#include <TimerTwo.h>
#include <OneWire.h>
#include <DallasTemperature.h>
#include <VirtualWire.h>
#include <EEPROM.h>
#include <WirelessSensorPipe.h>
#include <LiquidCrystal.h>

#define DEBUG
#define INVALID_TEMPERATURE (1000)

/* hardware configuration */
#define DSPIN 12
#define TRANSMITPIN 3
#define RECEIVEPIN 2
#define HEATERCONTROLPIN 5
#define TARGETTEMPCONTROLPIN A0
//LCD pin mapping
#define LCDRS 11
#define LCDENABLE 10
#define LCDD4 4
#define LCDD5 7
#define LCDD6 8
#define LCDD7 9

#define RECEIVETIMEOUT 30 // wireless receive timeout

bool heater_enabled = false;
void enable_heater()
{
digitalWrite(HEATERCONTROLPIN, HIGH);
heater_enabled = true;
}

void disable_heater()
{
digitalWrite(HEATERCONTROLPIN, LOW);
heater_enabled = false;
}

float target_room_temperature, previous_target_room_temperature;
/*reads target room temperature from the potentiometer and returns true if the value changed*/
bool updateTargetRoomTemp()
{
uint16_t potentiometer_value = analogRead(TARGETTEMPCONTROLPIN);
target_room_temperature = 22 + 4 / 1024.0 * potentiometer_value;
if (fabs(target_room_temperature — previous_target_room_temperature) < 0.1)
{
return false;
}
previous_target_room_temperature = target_room_temperature;
return true;
}

uint16_t cycle_counter = 0;
void targetTempChangeChecker()
{
if (cycle_counter++ % 16 == 0) //max period of timer2 is 16ms, so we throttle out 15 cycles of 16 to update target temp value approx 4 times per second
{
if(updateTargetRoomTemp())
updateOnScreenInfo();
}
}

#define OUTSIDE_SENSOR_ID 27327
#define ROOM_SENSOR_ID 13467
#define TEMPERATURE_HYSTERESIS 5
#define HEATER_MAX_TEMP 80
#define HEATER_MIN_TEMP 30

float room_temperature = INVALID_TEMPERATURE;
float outside_temperature = INVALID_TEMPERATURE;
float RW_temperature;
float target_RW_temperature = 30;

OneWire one_wire(DSPIN);
DallasTemperature sensor(&one_wire);
void updateTargetRWTemperature()
{
sensor.requestTemperatures();
RW_temperature = sensor.getTempCByIndex(0);
target_RW_temperature = 20 + (target_room_temperature — outside_temperature) + (target_room_temperature — room_temperature) * 30;
target_RW_temperature = min(target_RW_temperature, HEATER_MAX_TEMP);
target_RW_temperature = max(target_RW_temperature, HEATER_MIN_TEMP);
}

LiquidCrystal lcd(LCDRS, LCDENABLE, LCDD4, LCDD5, LCDD6, LCDD7);
void updateOnScreenInfo()
{
char floatBuffer[7];
lcd.setCursor(0,0);
lcd.print(F(«Room»));
lcd.print(dtostrf(target_room_temperature, 2, 1, floatBuffer));
lcd.setCursor(0,1);
lcd.print(F(«W»));
lcd.print((int)RW_temperature);
lcd.print(F(" TW"));
lcd.print((int)target_RW_temperature);
}

WirelessSensorPipe pipe;
void setup ()
{
#ifdef DEBUG
Serial.begin(9600);
Serial.println(F(«Entered setup»));
#endif
pinMode(HEATERCONTROLPIN, OUTPUT);
sensor.begin();
pipe.begin(TRANSMITPIN, RECEIVEPIN, 13);

#ifdef DEBUG
Serial.print(F(«Sensor id:»));
Serial.println(pipe.id());
#endif

updateTargetRoomTemp();
updateTargetRWTemperature();
TimerTwo::init(16384, targetTempChangeChecker);
TimerTwo::start();

lcd.begin(8, 2);
}

int current_transmission_phase = 0;
void loop()
{
#ifdef DEBUG
Serial.print(F(«Timestamp:»));
Serial.println(millis()/1000);

Serial.print(F(«RW temperature: „));
Serial.println(RW_temperature);
Serial.print(F(“target_RW temperature: „));
Serial.println(target_RW_temperature);
Serial.print(F(“outside temperature: „));
Serial.println(outside_temperature);
Serial.print(F(“room temperature: „));
Serial.println(room_temperature);
Serial.print(F(“target room temperature: „));
Serial.println(target_room_temperature);

// blink the LED to indicate that the readings are done
//digitalWrite(13, HIGH);
//delay(100);
//digitalWrite(13, LOW);
#endif
updateTargetRoomTemp();
lcd.begin(8,2); // periodically LCD goes crazy for some reason, so this is a temporary hack to get off of this state. shall be removed when the reason for such behaviour become clear.
lcd.clear();
updateOnScreenInfo();
WirelessSensorPipe::Packet packet;
if (pipe.receive(packet, RECEIVETIMEOUT * 1000))
{
if(packet.type == WirelessSensorPipe::TEMPERATURE)
{
switch (packet.id)
{
case OUTSIDE_SENSOR_ID:
outside_temperature = packet.value;
break;
case ROOM_SENSOR_ID:
room_temperature = packet.value;
break;
}
}
return; //we skip the rest of the code to avoid sending our data and conflicting with other devices sending data in series. In other words we listen until someone transmits and doing the rest of the work if no one transmits
}
updateTargetRWTemperature();
if (RW_temperature >= target_RW_temperature + TEMPERATURE_HYSTERESIS && target_RW_temperature < HEATER_MAX_TEMP )
{
disable_heater();
}
if (RW_temperature <= target_RW_temperature — TEMPERATURE_HYSTERESIS && target_RW_temperature > HEATER_MIN_TEMP)
{
enable_heater();
}

switch(current_transmission_phase++)
{
case 0:
pipe.send(WirelessSensorPipe::TEMPERATURE, room_temperature);
break;
case 1:
pipe.send(WirelessSensorPipe::HEATERSETPOINT, target_RW_temperature);
break;
case 2:
pipe.send(WirelessSensorPipe::HEATERRWTEMPERATURE, RW_temperature);
break;
case 3:
pipe.send(WirelessSensorPipe::HEATERTARGETROOMTEMPERATURE, target_room_temperature);
break;
case 4:
pipe.send(WirelessSensorPipe::HEATERFLAMEENABLED, heater_enabled);
current_transmission_phase = 0;
break;
}
}

Надо упомянуть, что больше всего проблем доставила работа с экраном. Детские болячки, вроде неправильного подключения и инициализации описывать не буду, а вот проблемы, связанные с неаккуратным использованием таймера, упомянуть можно. Дело в том, что первые реализации по таймеру считывали A0, вычисляли температуру и безусловно обновляли экран. Частота обновления была довольно высокая – 2Гц, а процедура обновления экрана достаточно длительная. Это приводило к тому, что основная петля алгоритма (которая основную часть времени проводит в попытке принять что-то из эфира) часто и надолго прерывалась обработчиком таймера. Это приводило к тому, что программная часть приемника ничего не могла принять из эфира, поскольку много пропускала во время отвлечения на выполнение обработчика таймера. Кроме того, экран эпизодически сходит с ума и его нужно переинициализировать, чтобы вернуть к жизни. С чем связано такое поведение, я пока не понял.
Вторая проблема, с которой я столкнулся – первое место, куда был установлен контроллер, оказалось местом жестокой радиотени.
Эти две проблемы отняли у меня приличное количество вечеров в попытках понять, почему контроллер ничего не принимает. Самое же противное в том, что устранение любой из них не улучшало ситуацию, надо было решать одновременно обе, поэтому я довольно долго находился в заблуждениях типа «радиотень тут не причем» и «с приемной частью все в порядке».
Еще очень плохой затеей оказалась передача всех контролируемых параметров скопом в радиоэфир на каждой итерации алгоритма. В передаваемых параметрах значатся: температура в комнате, температура на улице (просто повтор в целях контроля), установленная целевая температура в доме, вычисленное целевое значение температуры воды, текущее значение температуры воды, замкнута ли цепь управления котлом или нет. Поскольку выполнение одной итерации алгоритма занимает порядка 30 секунд, два раза в минуту в эфир вываливалась куча пакетов, что приводило к повышению вероятности коллизий. Поэтому пришлось модифицировать прошивку так, чтобы она за одну итерацию посылала в эфир только один параметр. Таким образом, каждый параметр стал обновляться раз в 3 минуты.

Part list

Arduino Pro Mini – 100 руб за штуку
DS18B20 – 34 руб за штуку
Передатчик + приемник 433MHz – 40 руб за штуку
LCD WH0802A-NGG-CT – 125 руб за штуку
4N35 — 9 руб за штуку
Диодный мост DB107 — 5.5 руб за штуку
Резисторы – всего на 5 руб
Тумблер (куплен оффлайн) – 20 руб
Корпус КР-606-ПС – 40 руб
Итог – с учетом припоя, макетной платы, проводов и амортизации паяльника – около 450 руб. Если б заказал LCD на Ebay, получилось бы еще на 80 руб дешевле.

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

Фотографии самого контроллера и котла под спойлером. Прошу прощения за неровно вырезанное окошко под LCD.

Фото

image
image

А вот к выходу котла прикручен DS18B20

Фото

image

Фотография того, как «контрольная панель» смотрится на том же Стрике.

Фото

image

Как я уже сказал, было реализовано две схемы управления – классическая, т.е. «Не достаточно жарко? Жарим!», и с компенсацией уличной температуры.
В принципе, первая удовлетворяла требованиям, изначально предъявленным к системе статирования, т.е. обеспечивала температуру в помещении в пределах полуградуса от целевого значения. Однако недостатком являлись колебания вокруг этого самого целевого значения с амплитудой почти полградуса. Т.е. температура в комнате осциллировала вокруг цели, причем эта осцилляция явно не могла быть вызвана внешними факторами, поскольку они были стабильны.
Но вот введение OTC дало неожиданный хороший результат. Работа по алгоритму в соответствии с формулой выше стабилизировала температуру в пределах -0.2+0.1 градуса от цели. Надо отметить, что провалы в 0.2 градуса связаны даже не с особенностями процесса терморегулирования, а с тем, что когда кто-то открывает горячую воду (например, моется полчаса) котел занят тем, что обеспечивает нагрев горячей воды в контуре подачи горячей воды. Контур отопления при этом не греется.
image
Контроллер в таком режиме работает уже полмесяца, полет нормальный, отказов не было. Могу сказать, что термостатирование прилично повышает психологический комфорт. Если раньше нужно было как минимум каждые вечер и утро выставлять температуру воды в соответствии с текущей температурой на улице, прогнозом и показаниями собственной интуиции, что требовало некоторых усилий, то сейчас мы даже не вспоминаем, что у нас стоит котел – работает себе и работает.
В планах значится дожать OT/+, благо заказанный осциллограф пришел, с его помощью я уже выяснил, что даже посылал в сторону котла не то (была банальная опечатка в коде, которую я десятки раз перепроверял и не видел – глаз замылился), а о приеме я вообще молчу. В принципе, работу термостата это не улучшит, но позволит снимать больше диагностики. К тому же это теперь принципиальная проблема из разряда «кто кого».

ссылка на оригинал статьи http://habrahabr.ru/post/214257/

Уведомления окончаний fabric задач, с декораторами и детальной информацией

В существующем проекте есть долгоиграющие fab-задачки — получения дампов с удаленных серверов, агрегация данных, етс. Запускаешь задачу, отвлекаешься в соседнее окошко, через N минут(а то и через час) вспоминаешь, проверяешь… неэффективно.
Захотелось сделать всплывающие уведомления на десктоп по завершении задачи, а тут и статья про notify-send подвернулась. Решил сделать декоратор на fab-функции — самое ему место.

Для начала пишем простую функцию уведомления

from django.conf import settings as django_settings from fabric.operations import local  def _notify(message):     if django_settings.FAB_NOTIFY_TASK_ENDS:         local(u'notify-send --expire-time=10000 "Fabric notify" "{}"'.format(message)) 

Да, у меня джанга и настройку «показывать ли подсказки» вынеcем в настройки.

Использование _notify тоже простое:

from fab_utils import _notify  def mongo_get_from_remote(server='', date='', collection=''):     u"""Загрузить базы монго c удаленного сервера"""     ...     _notify(u"Базы загружены") 

Но в каждой функции писать вызов в конце… как-то не «сухо» (DRY рулит). Напишем декоратор

def notified(wrapped):     def internal(*args, **kwargs):         res = wrapped(*args, **kwargs)         params = [unicode(a) for a in args]         params.extend([u'{}={}'.format(k, v) for k, v in kwargs.iteritems()])         params = [_limit_str(p) for p in params]         message = "{}({}) ended!!!".format(wrapped.__name__, ', '.join(params))         _notify(message)         return res     return internal 

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

from fab_utils import notified  @notified def mongo_get_from_remote(server='', date='', collection=''):     u"""Загрузить базы монго c удаленного сервера"""     ... 

Все бы хорошо, но перестала выводится справка по команде 🙁

wad@wad-vaio:~/aggregator (develop)$ bin/fab.sh -d mongo_get_from_remote Displaying detailed information for task 'mongo_get_from_remote':      No docstring provided     Arguments: 

Что же делать? надо переопределить докстринг!

def notified(wrapped):     def internal(*args, **kwargs):         ...         return res     internal.__doc__ = wrapped.__doc__     return internal 

wad@wad-vaio:~/aggregator (develop!)$ bin/fab.sh -d mongo_get_from_remote Displaying detailed information for task 'mongo_get_from_remote':      Загрузить базы монго c удаленного сервера server='', date='', collection=''     Arguments: 

Уже лучше, но где же аргументы? За ними пришлось лезть в кишочки fabric — как он их определяет?

В файле env/local/lib/python2.7/site-packages/fabric/main.py:466 нашлось

def display_command(name):     """     Print command function's docstring, then exit. Invoked with -d/--display.     """     ...     if hasattr(command, '__details__'):         task_details = command.__details__()     else:         task_details = get_task_details(command)     ... 

Ага, если у функции есть __details__ то он вызовется для определения аргументов. Отлично!

Итоговый код декоратора таков

from fabric.tasks import get_task_details  def notified(wrapped):      def internal(*args, **kwargs):         res = wrapped(*args, **kwargs)         params = [unicode(a) for a in args]         params.extend([u'{}={}'.format(k, v) for k, v in kwargs.iteritems()])         params = [_limit_str(p) for p in params]         message = "{}({}) ended!!!".format(wrapped.__name__, ', '.join(params))         _notify(message)         return res      def _details():         return get_task_details(wrapped)      internal.__doc__ = wrapped.__doc__     internal.__details__ = _details     return internal  

И описание fab-задачки на месте

wad@wad-vaio:~/aggregator (develop!)$ bin/fab.sh -d mongo_get_from_remote Displaying detailed information for task 'mongo_get_from_remote':      Загрузить базы монго c удаленного сервера server='', date='', collection=''     Arguments: server='', date='', collection=''  

Люблю python 🙂

ссылка на оригинал статьи http://habrahabr.ru/post/214259/

Конференция ProfsoUX-2013 — обзор-классификация + видеозаписи

В прошлом году я снимал и транслировал питерскую конференцию ProfsoUX-2013, посвященную исключительно юзабилити. Все записи были оперативно смонтированы («докладчик+экран+зал») и через неделю опубликованы.
Но только сейчас у меня дошли руки посмотреть их самому, и предложить краткий обзор-классификацию, с ссылками на видео, так, чтобы вы могли посмотреть именно то, что вас потенциально интересует (увы, кроме меня никто обзор не написал, все приходится делать самому). Впрочем, UX — штука фундаментальная и все идеи-мысли-решения до сих пор актуальны.
Все доклады были короткие (<20 минут) и динамичные, отрасль молодая, нет академических свадебных стариков-генералов, только молодые профессионалы, ведущие UX-собаководы, мастера айтрекеров и нейротрансмиттеров, обзор тоже попробую сделать кратким, не растекаясь мыслью по древу, оформив простой самодельной классификацией.

Философия UX

Тут доклады про глобальное и стратегическое: тренды, концепты, подходы.

«Маленькие советы дизайнерам» — Импозантный Максим Ткачук, одетый в стиле «стивджобс, да еще в дизайнерских очках», размышлял об эволюции, как в дизайне и UX, так и о эволюции карьеры правильного юзабилиста. История дизайна, как осознанного конкурентного преимущества, об основных трендах и их причинах («послевоенный минимализм», «айпад породил адаптивный дизайн»), и собственно, практические советы как по проектированию («Small First»), так и по карьере («Zoom Out», удалите фотошоп и переходите на темную бизнес-сторону). Кстати, ему дали главный приз конференции.


«Секонд-хэнд проектирование» — Да, все знают, что «Un artista copia, un gran artista roba»©, что в мире дизайна давно превратилось в «воруй@процветай», и тут как раз о том, как сделать это правильно, чтобы не стать посмешищем и жертвой карго («говносайты под Win8»), и наоборот, где можно расслабится с исследованиями, и доверится трендам («карусели или параллакс?», «скеоморфизм или delicious flat chest?»…) дополнив лишь «одушевляющими» мелочами.


«NUI или почему не устанет рука» — Эволюция интерфейсов от старой доброй командной строки к неведомому Natural UI. Истории о носимых компьютерах, дополненной реальности, айтрекер-интерфейсы для инвалидов и нейроинтерфейсы для дополнительной невербалики. Размышления о том, где это может быть необходимо, а где не пришей вероятно излишне. Жаль только, что хоть докладчик и принес коробочку с Leap Motion, живьем ничего не демонстрировалось. Очень рекомендую докладчикам на эту тему, делать Тру-демонстрации → вот, еще в 2011 году на WUD были живые демонстрации NUI c самописным софтом. К сожалению, также не было четкого ответа — к чему собственно готовится UX-проектировщиках — тут я, пользуясь случаем, порекомендую развлечься сериалом «Black Mirror».


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

Best practices

Тут конкретные рассказы об аспектах и практиках, как делать это правильно.

Начнем с проектирования — ««Методики описания и визуализации UX» — как делать это эффективно? Тупо описывать действия персонажей? Долго и муторно. «Story Mapping» — выделять цели, декомпозировать на задачи, и искать базис UX-инструментов для решения? «Вопрос—ответ»? «Customer Journey»? Или вообще бросить писать, и побольше рисовать комиксов — это «Story Boarding».


После описательного-рисовательного проектирования важно начинать получать фидбек и прокачивать гипотезы на работоспособность — и об этом «Быстрое прототипирование для веб и мобильных устройств» — доклад канадского специалиста на английском, но с крутым почти-синхронным переводом (по наблюдению, перевод местами удачней исходного доклада). Тут и Философия Прототипа (а то некоторые неучи путают прототип с информационной архитектурой, макетом, наброском-wireframe, и первыми версиями софта), до конкретных советов по инструментам — от Powerpoint+Keynote (очень спорная идея, имхо) до, вероятно, самого популярного Axure (более половины зала подняли руки), и более модных вебсервисов, типа proto.io.


Как улучшать продукт, когда первые ступени техзаданий и прототипов уже отброшены, продукт живой и в полете? — «Рука об руку с эффективностью — сплит-тесты». Не тратьте время на субъективные фокус-группы — A/B-тестирование на всей настоящей аудитории даст самый правильный ответ. Больше конверсии, больше! Grow Hacking! Собственно тут да, маркетинг, тоже смежная с UX область, но все же другая — вряд ли хоть один дизайнер и UX-ер сможет использовать в своей презентации Comic Sans (аудитория была в шоке, твиттер взорвался, а докладчица интересовалась в кулуарах «а что такого?»).


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


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


Ну и конечно, отдельный мир интерфейсов — игры. Тут был свежий взгляд на игромир с точки зрения классического вебUXера —«Сможет ли проектировщик взаимодействия в вебе стать проектировщиком в игровой индустрии?». C одной стороны, вроде сложнее, и навороченные миры, и неприменимы классические метрики и вообще много гитик, с другой — это Среда, которая рулит пользователем (тут я рекомендую Пелевинский «Шлем Минотавра», как мистическую UX-философию компьютерных сред), и да, тут реально рулят «шлемилем», хитрым образом меняя ракурсы камеры, не давая отвлечься постоянной анимацией, пугая его звуком, страшно подумать, что будет, когда в массы придут настоящие шлемы/3D-очки.
Отдельная тема — сервисные интерфейсы игр, которые тоже можно неслабо геймифицировать. У них до сих пор неразгаданная загадка — «Очень часто игроки перед началом боя заглядывают в дуло своему танку, по непонятной нам причине» — может кто объяснит в комментах?
Кстати, на тему «юзабилити и World of Tanks» я снимал и другие доклады → «Год в ТАНКЕ. Хроники UX-лаборатории», «Проектирование взаимодействия в многопользовательских он-лайн играх».

Процесс

Тут скорее околоюиксовые доклады, о том, где собственно живет UX, какое его место в разработке, как выстроить взаимодействие и разрулить конфликты с и заказчиками, и с командой — тестировщиками, аналитиками/проектировщиками и разработчиками, проектными и продуктовыми менеджерами.

«UX исследования на всех этапах разработки продукта» — финансово-бухгалтерский софт, но разрабатываемой уже давно (См. «Экстремальный аджайл — танцуют все») единой большой командой с юзабилистами внутри. Нужна ли медицински холодная юзабилити-лаборатория, или домашний уют, какие конфликты были у юзабилистов с кодерами и проектировщиками, и как удалось победить («программисты сами попросили об исследовании!»), как внедрять юзабилити, и где на это выбивать ресурсы. Рассказ в картинках и фотографиях, все визуально, хотя местами грустно видеть плотнозабитый опенспейс команды — неужели в таких тяжких условиях можно сделать красивый дизайн?


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


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


«Исследования интерфейсов в Яндексе» — Ну и это вершина процесса, когда у ребят есть ВСЕ, и можно позволить себе сделать Идеальный Research-процесс (только исследование, никаких рекомендаций, строгая научная чистота и отстраненность — проектирование это удел касты инженеров). В то время, как большинство компаний только мечтает о исследованиях, а наиболее крутые записываются в очередь на аренду пары часов в оборудованную лабораторию с айтрекером (если кто не в курсе — эти девайсы стоят десятки тыщ, Tobii X120 $40K-$70K), тут, повторюсь, есть все. И оборудованная лаборатория с односторонними зеркалами и кучей айтрекеров (для выездов есть тревожные чемоданчики с портативными айтрекерами) + нейротрекеры +…. Собственная база пользователей и детективное агенство подрядчики для розыска специальных экземпляров («45 летний пользователь айфона с десятью лямами в кармане собирающийся купить квартиру», «Ах, как сложно было найти пользователя, у которого основным поиском был мейл.ру»). В общем, хорошо быть богатым и здоровым + умным и красивым. Позавидуем, ОК.
Рассматривались и нетривиальные кейсы — «слепая девочка ведет блог, иллюстрируя его картинками из поиска». Кстати, почти никто не подходит к такому сложному снаряду, как компьютерные интерфейсы для слепых, и тут, пользуясь случаем, дам ссылку на доклад с описанием полноценного рабочего стола для слепых, написанного самим слепым программистом → «Luwrain. ОС для людей с проблемами зрения».


Вот. Надеюсь, кто-нибудь себе что-нибудь выберет посмотреть на эти выходные.
Но не все попало на записи — были и блиц-доклады в холле (я там тоже выступал про двухпанельники), и секция мастер-классов (не снимал, ибо по опыту, в мастер-классах участвовать интересно, а смотреть не очень), и общение в кулуарах, где можно было отловить реальных ответственных за безумный по вашему мнению интерфейс какого-нибудь продукта и сервиса. Еще, участников там награждали за активность (вопросы, конкурсы там всякие и т.п.),так что подумайте — может разумно поучаствовать вживую?
Ну, а мне интересно — стоит съездить и поснимать видео ProfsoUX в этом году, или нет?

ссылка на оригинал статьи http://habrahabr.ru/post/214253/