Операционная система из говна и палок

На «Гиктаймсе» опубликовали конспект первой лекции курса Олега Артамонова по программированию микроконтролеров. Курс, конечно, немного экзотический в сравнении с любым интернетовским руководством по тем же STM32 — в нем рассматривается программирование с использованием операционной системы RIOT. Никакого вам CubeMX, никакой FreeRTOS — но в целом материал не особо привязан к конкретной ОС и «железу» и ориентирован скорее на то, чтобы продемонстрировать подходы к программированию для микроконтролеров «вообще».

Для тех, кому проще воспринимать видео — на Youtube выкладываются и видеозаписи лекций:

https://www.youtube.com/playlist?list=PLJEYfuHbcEIApuZR4L5tRiBCwTZCYeTNY

Но при всех заявленных и видимых достоинствах этих лекций, хвалить их целиком пока рано — поэтому перейду к всякой ерунде. Как водится, половина удовольствия от чтения «околоэлектронных» материалов на «Хабре» и «Гиктаймсе» — это комментарии, где обычно ссаными тряпками гоняют ардуинщиков. В этот раз к «гонимым» добавились также те, кто не осилил ничего, кроме всевозможных HAL и StdPeriphLib от производителя, и те, кто почему-то считает микроконтролером Raspberry Pi. Но все это не заслуживало бы упоминания — если бы не один комментарий:

…например, в Contiki — там многозадачность с инвалидностью третьей группы, там надо в треде либо без switch-case, либо без сообщений жить. Этому в университете всех учить не надо, кому в жизни не посчастливится — сами научатся.

https://geektimes.ru/company/samsung/blog/299187/#comment_10699171

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

Для начала — вот такой хитрый пример кода, который обычно называется Duff’s device — «Прием Даффа», в честь Тома Даффа, обратившего внимание на то, что метки в конструкции switch языка C позволяют нарушать «блочную» структуру программы — например, перейти сразу внутрь цикла:

switch (count % 8) {
    case 0:    do { *to = *from++;
    case 7:         *to = *from++;
    case 6:         *to = *from++;
    case 5:         *to = *from++;
    case 4:         *to = *from++;
    case 3:         *to = *from++;
    case 2:         *to = *from++;
    case 1:         *to = *from++;
               } while ((count -= 8) > 0);
}

Кстати говоря, Duff’s Device упомянут [info]sharpc в известном «Теоретическом минимуме для программиста«. Конструкция довольно дикая, мало чем отличающаяся от GOTO — и хочу заметить, что особых преимуществ по скорости (в оригинале она использовалась для того, чтобы развернуть цикл в memcpy) на современных процессорах она не дает. Знать о ней, наверное, надо, а вот применять — только по необходимости.

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

volatile int counter;

int example( int *lc ) {
    switch ( *lc ) { case 0:

    printf( "First run!\n" );
    while ( 1 ) {
        *lc = 9; case 9: if ( !(counter > 10) ) return 0;
        printf( "Threshold reached\n" );
        counter = 0;
    }

    } *lc = 0; return 2;
}

Будем вызывать эту функцию примерно таким образом:

int main( void ) {
    int lc = 0;

    while ( 1 ) {
        example( &lc );
        printf( "Back in main, counter = %d\n", counter );
        counter++;
    }

    return 0;
}

Обратите внимание, что строчка First run! напечатается только один раз, несмотря на то, что функция вызывается многократно. Фактически, таким нехитрым приемом реализован механизм ожидания событий — нетрудно догадаться, что в промежутках между вызовами нашей функции counter может изменяться как угодно (на это я намекаю, объявив его volatile). А теперь определим несколько макросов:

struct pt {
    int lc;
};
#define PT_BEGIN(pt)          switch((pt)->lc) { case 0:
#define PT_WAIT_UNTIL(pt, c)  pt->lc = __LINE__; case __LINE__: if(!(c)) return 0
#define PT_END(pt)            } (pt)->lc = 0; return 2
#define PT_INIT(pt)           (pt)->lc = 0

И перепишем пример, используя их:

volatile int counter;

int example( struct pt *pt ) {
    PT_BEGIN( pt );

    printf( "First run!\n" );
    while ( 1 ) {
        PT_WAIT_UNTIL( pt, counter > 10 );
        printf( "Threshold reached\n" );
        counter = 0;
    }

    PT_END( pt );
}

int main( void ) {
    struct pt example_pt;
    PT_INIT( &example_pt );

    while ( 1 ) {
        example( &example_pt );
        printf( "Back in main, counter = %d\n", counter );
        counter++;
    }

    return 0;
}

Хочу добавить, что в компиляторе из Microsoft Visual Studio этот пример не работает, если при компиляции указан параметр /ZI (он по умолчанию установлен для конфигурации Debug) — можно заменить его на /Zi.

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

Какие же у этого подхода недостатки? Начну с очевидного — использовать одновременно и protothreads, и конструкцию switch нельзя. Другая нехорошая штука — при переходе потока в состояние ожидания и выходе в планировщик теряются значения всех локальных переменных внутри функции этого потока. Это довольно неприятно, так как требует постоянно держать в голове «нестандартное» поведение программы. Бороться с этим можно либо объявляя локальные переменные потока, как static, либо используя глобальные переменные. Наконец, ждать событий можно только в основной функции потока, что резко ограничивает «полет фантазии» в реализации какой-то нетривиальной логики.

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

Глазами ученого на Хабре

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

https://habrahabr.ru/post/349624/

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

PS И даже не знаю, какой из этих двух вариантов омерзительнее:

C и С++ изучают только программисты. Естественнонаучники (за очень редким исключением) учат программирование на Делфи, а потом всякие спецпакеты. Максимум пролог будет. Там не учат С98. Там не учат что памятью в принципе можно управлять. Тем более — что нужно. Учат так: вы придумываете правильный алгоритм, компьютер его выполняет. Учат как переписать алгоритм из головы на паскаль.

https://habrahabr.ru/post/349624/#comment_10682588

или

Я не знаю где вас учили, но на моём естественно-научном факультете сначала был курс C# (2 года). А теперь вообще идёт курс Java EE c Хадупами и всем фаршем.

https://habrahabr.ru/post/349624/#comment_10682700

Open Source как религия

Осознал между делом, что за фразой «Мы используем X, потому что это open source» могут быть две совершенно разные мотивации. Первая, «религиозная», встречается, например, у малолетних читателей журнала «Ксакеп». Вторая, «практическая», выражается словами — «можно сделать форк, если когда припрет«.

Особенно забавно, что когда «практики» все-таки задалбываются от кривых понятий «руководителей» опенсорсного проекта и наконец-то делают пресловутый форк, то «верующие» их всячески за это осуждают.

Продолжим поиски

По рекомендации Sergey из комментариев к недавней записи про Trac и Subversion посмотрел на систему контроля версий Mercurial. В принципе, понравилось — хотя TortoiseHg выглядит намного запутаннее TortoiseSVN; с другой стороны, принцип работы с DVCS немного закрывает некоторые из моих проблем — с частью проектов приходится работать без доступа к интернету.

Если рассмотреть переход на Mercurial — то список сервисов из той записи сожмется до двух вариантов (напомню, что цены приведены за 5 Гб места):

Xp-Dev 96$ = 5800 рублей/год Есть также git и Mercurial
repositoryhosting.com 108$ = 6500 рублей/год Есть также git и Mercurial; новости на сайте заканчиваются 2014 годом

Если продолжить в том же направлении — то зачем упираться в Trac? Может, появилось что-то еще? Предлагают использовать Jira — но по-моему, она предназначена для «управления проектами» в стиле Agile и прочего Scrum. Мне надо кое-что попроще — в «моих» проектах присутствует один (редко два) разработчика, он же в большинстве случаев сам себе и начальник, и тестер. Соответственно, надо:

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

Trac в принципе всем этим требованиям удовлетворяет — но на что еще стоит посмотреть? Ах да, еще одно требование — не хочется попадать, так сказать, на vendor lock-in — в Trac мне нравится то, что я могу забрать все содержимое «проекта» и развернуть его заново где угодно, хоть на собственной персоналке.

А где сейчас модно размещать хранилище Subversion?

Захотелось мне в очередной раз заиметь доступный через интернет сервер со всякими исходниками, вики, багтрекером и так далее. Я привык пользоваться Subversion и Trac, git так и не осилил.

Первый вариант: взять дешевый VDS; например, минимальный тарифный план у FirstVDS.ru — 199 рублей в месяц, или около 2400/год. За эти деньги предлагается виртуальный сервер с 1 Гб оперативной памяти и 30 Гб диска. Навскидку, такая конфигурация «потянет» Apache со всеми необходимыми причиндалами. Основной минус — надо самостоятельно все это администрировать, а мне это ох как не хочется. Не то, чтобы я сомневался в своих способностях делать все по мануалам — в конце концов, я ставил Trac и SVN на сервер с Windows — но просто не хочется лезть в администрирование.

Второй вариант — посмотреть в сторону специализированного хостинга Trac+Subversion. Нашел несколько разных сервисов, для сравнения возьму стоимость тарифного плана «на 5 Гб» (где-то он идет как минимальный, где-то, наоборот — почти самый крутой):

MySvn 1200 рублей/год Выглядит полумертвым
Xp-Dev 96$ = 5800 рублей/год Есть также git и Mercurial
ProjectLocker 228$ = 13700 рублей/год Не более 5 проектов; есть также git
demobereich 79 Евро = 5500 рублей/год Немцы со всем отсюда вытекающим; последние новости на сайте — за 2012 год
DevZing 144$ = 8600 рублей/год
ProjectHut 228$ = 13700 рублей/год Не более 20 проектов; есть также git
repositoryhosting.com 108$ = 6500 рублей/год Есть также git и Mercurial; новости на сайте заканчиваются 2014 годом

Тут, конечно, стоит обратить внимание на разброс по цене — в 10 раз, на порядок! «Средний» же хостинг с Trac и SVN стоит около 5-6 тысяч рублей. Очень привлекательно на общем фоне выглядит MySvn — но он производит впечатление полумертвого.

А кто что посоветует?

PS Гитхаб не предлагать.

Вы делаете это неправильно

По-моему, почти в каждый курс программирования входит задачка вроде «напишите программу, решающую квадратные уравнения». Обычно это второе или третье задание после «Hello, world!» — считается, что это хороший способ продемонстрировать нетривиальные инструкции ветвления. «Хорошее» решение сводится к вычислению дискриминанта и в случае, если он неотрицательный — вычислению корней квадратного трехчлена ax2+bx+c по формуле, известной из курса алгебры за седьмой, что ли, класс:

square1

Вот такой вариант решения обычно считается более-менее приемлемым (хотя его можно/нужно обвешать еще несколькими проверками — например, не равен ли коэффициент a нулю?):

int solve(double a, double b, double c, double *x1, double *x2){
	double d = b*b - 4.*a*c;
	if( d >= 0 ){
		d = sqrt(d);
		*x1 = (-b + d)/(2.*a);
		*x2 = (-b - d)/(2.*a);
		return 0;
	}
	return -1;
}

В чем проблема? На первый взгляд все более-менее хорошо, но… Давайте для тестирования будем подсовывать уравнения с известными корнями — используя для этого теорему Виета. А именно, зафиксируем коэффициент a=1, тогда уравнение с корнями x1 и x2 будет иметь коээффициенты b=-(x1+x2) и c=x1x2. Сравнивая корни, полученные при решении уравнения, с известными нам, оценим «качество» решения.

Если корни «нормальные» — те, с которыми справится шестиклассник — то все хорошо. Но что будет, если взять два «нехороших» корня — к примеру, x1=1, x2=10-14 (это для double; если вы пользуетесь float — то возьмите второй корень, равный 10-5)? Проверьте — не забыв включить вывод максимально возможного количества значащих цифр (в printf лучше всего использовать форматный спецификатор %g, при использовании вывода в стиле C++, через iostream, такой вывод включен по умолчанию). Ошибка при вычислении второго корня возникнет уже в четвертой значащей цифре, это, на самом деле, уже довольно неприлично.

В чем дело? Если обратить внимание на «обычную» формулу для вычисления корней квадратного уравнения, то мы увидим, что при вычислении меньшего корня корень из дискриминанта вычитается из b — а так как они в этом случае очень близки, то возникающая при этом вычислительная ошибка оказывается слишком большой.

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

square2

Выводится она абсолютно аналогичным образом, от «классической» отличается тем, что «не работает» при c=0.

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

— вычисляем дискриминант D=b2-4ac
— если дискриминант неотрицателен, то вычисляем

q

— корни уравнения равны q/a и c/q.

Как реализовать это в программе — довольно очевидно, это особо ее не усложнит.

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

Скажите, а с ARM все действительно так плохо?

В одном прожекте возникла необходимость беспроводной передачи неприличного количества данных с АЦП. Даже в самых оптимистичных сценариях получалось, что придется гнать без проводов поток данных порядка 150 кбит/с. Немного? Но при таком потоке «затыкаются» все легкодоступные радиоудлинители UART — неважно, какой там у них радиоинтерфейс — WiFi, Bluetooth, или что-то еще. Более того, большинству из них недоступна скорость выше 115200 бод, что «отсекает» их еще на этапе ознакомления с ТТХ.

В поисках какого-то более подходящего решения набрел на микроконтролер CC3200 производства Texas Instruments. Что мне понравилось? По пунктам:

— ядро Cortex-M4 (хотелось бы, конечно, Cortex-M4F, но и это сойдет);
— встроенный WiFi, по отзывам — действительно быстрый;
— встроенные раздельные модули SPI и SD-host (я сначала думал, изучая примеры, что обмен с SD-картой будет идти с использованием модуля SPI, судя по назначению выводов — но нет, они там никак не связаны);
— возможность переназначать выводы утилитой Pinmux — хочешь, заводи SD-карту на эту сторону микрухи, хочешь — на другую, в общем, все офигенно.

Ну, где у нас АЦП — там хорошо бы и обработать сигнал? Благо в ядре Cortex-M4, в отличие от распространенного Cortex-M3, присутствуют команды, упрощающие цифровую обработку сигналов — например, реализацию всевозможных цифровых фильтров. Но на этом этапе начались какие-то дикие танцы с бубнами :)

Для начала — есть библиотека CMSIS, унифицированная для всех ARM реализация некоторых часто используемых функций. Особенно мне была интересна CMSIS-DSP, часть библиотеки с реализацией функций для цифровой обработки сигнала. Да, я могу написать реализацию какого-нибудь там фильтра Баттерворта или быстрого преобразования Фурье — но оптимизировать его для ARM я вряд ли буду, да и зачем это делать, когда есть готовое общепринятое решение?

Но для использования этого готового решения требуется некоторая поддержка от производителя микроконтролера — и здесь все становится просто ужасно. У Texas Instruments используется своя среда разработки (на основе Eclipse) и свой же компилятор. Может, имей я больше опыта программирования под ARM, я бы настроил что-то более распространенное, но для начала я просто следовал пунктам из Quick Start Guide.

Так вот, основное преимущество Cortex-M4 над Cortex-M3 — поддержка «DSP instruction set» — вообще никак не афишируется производителем в случае CC3200. Да, есть «патч» для одной из относительно старых версий CMSIS, выпущенный Texas Instruments несколько лет назад — но применимость его в случае CC3200 не озвучивается (и действительно, если «втупую» применить этот «патч», ничего не выйдет). На просторах ютуба нашлось вот такое видео:

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

В конечном итоге CMSIS-DSP я собрал (откомпилированная библиотека из дистрибутива с компилятором TI не очень дружит) — хотя, конечно, некоторые вопросы остались. И главный из них — в заголовке. Неужели любой шаг в сторону от любовно подобранных примеров из SDK превращается в вот такой забег по граблям под руководством индусов?

Гугл, мать его

А что такое замечательное сделали в Android Studio, что она еле ворочается на относительно современном ноутбуке? Eclipse, например, в разы быстрее.

Math Toolkit for Real-Time Development

Прочитал совершенно замечательную книжку Jack Crenshaw «Math Toolkit for Real-Time Development». Хоть она и предназначена в первую очередь для программистов «встраиваемых систем» — читал с большим удовольствием. А почему? А просто потому, что она в первую очередь — про математику, а не про программирование.

Любой относительно нормальный программист почти не задумывается над тем, как реализованы функции из «стандартной» математической библиотеки. Крайне нечасто возникают и задачи, где надо как-то учитывать, скажем, ограниченную точность чисел с плавающей запятой. Во вводных курсах программирования такие вещи практически никогда не рассматривают, а если и рассматривают — то неправильно. Например, я был в свое время очень удивлен, когда узнал, что некоторые вполне себе профессиональные программисты не имеют никакого представления об IEEE 754, и искренне считают, что вещественные числа в Delphi ведут себя так же, как вещественные числа в школьной математике.

Почему речь идет именно про «встраиваемые системы»? Книжка написана в 2000 году, задолго до того, как появилось представление об Internet of Things — и встраиваемые системы оставались последним местом, где жила всякая экзотика типа восьми- и шестнадцатибитных процессоров. Сейчас это уже немного не так, всякие PIC и AVR в более-менее серьезных местах найти уже трудно, а даже самой простенькой техникой рулят микроконтроллеры, которые по своим характеристикам уже вплотную подбираются к моему первому компьютеру (и заметьте — начинал я отнюдь не со «Спектрума», я еще не настолько стар!). В общем, о практическом применении этой книжки можно и поспорить.

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

Что можно сказать про первую тему? Да, писать собственные синусы с косинусами приходится немногим. Но очень и очень немногие при необходимости смогут сделать это правильно. Из «остаточных знаний» второго семестра я смог бы навскидку назвать лишь пару-тройку из тех «подводных камней», что упоминаются в книге. О некоторых вещах речь вообще не заходила ни разу и они оказались для меня сюрпризом. Более того, даже для сравнительно простой задачи — вычисления квадратного корня — приводится несколько алгоритмов, отличающихся требованиями по точности, скорости, наличию или отсутствию математического сопроцессора. Если вам вдруг захочется реализовать вычисление квадратного корня на каком-нибудь AVR — есть и «целочисленный» алгоритм.

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

/* Bitlog function
*
* Invented by Tom Lehman at Invivo Research, Inc.,
* ca. 1990
*
* Gives an integer analog of the log function
* For large x,
*
* B(x) = 8*(log(base 2)(x) – 1)
*/
short bitlog(unsigned long n)
{
    short b;
    // shorten computation for small numbers
    if(n <= 8)
        return (short)(2 * n);
    // find the highest non-zero bit
    b=31;
    while((b > 2) && ((long)n > 0))
    {
        --b;
        n <<= 1;
    }
    n &= 0x70000000;
    n >>= 28;
    cout << b << ' ' << n << endl;
    return (short)n + 8 * (b - 1);
}

Впечатляет? А в книге описано, как подобные алгоритмы разрабатывать, с оценками точности и так далее.

Вторая группа вопросов, разобранных в этой книге - численные методы. Уровень математической строгости, конечно, уступает "кирпичу" Бахвалова, да и первой части этой же книги - но дело в том, что для понимания численного дифференцирования и интегрирования надо хотя бы немного знать о дифференцировании и интегрировании обычном - на что американский автор книги для программистов рассчитывать никак не может. Тем не менее, приводятся несколько формул численного дифференцирования и интегрирования с оценками их точности и читатель даже подводится к одному из способов построения таких формул - представить, что функция приближена многочленом, и добиться того, чтобы для многочленов рассматриваемая функция была бы точной.

Для дифференциальных уравнений довольно подробно рассматриваются методы Адамса (многошаговый) и Рунге-Кутты. Опять же, так как с точки зрения программирования они тривиальны, много внимания уделяется получению формул для расчетов. Это все вполне доступно второкурснику мехмата (или любому, кто осилил формулу Тейлора и азы программирования), так что вполне можно обозвать книжку "Кратким введением в численные методы".

Что очень важно - такого рода "элементарного" учебника на русском языке я припомнить не могу. Учебники по численным методам рассчитаны на студентов где-то 4 курса и обычно требуют неплохой математической подготовки вместе с серьезным "погружением" в предмет. Книги "для программистов" обходят численные методы стороной - тема эта все-таки довольно специфическая. Ценность же этой книги - в том, что в ней рассматриваются некоторые неочевидные приемы, о которых, как я помню, действительно упоминалось на семинарах - но они сохранились у меня в лучшем случае в виде "остаточных знаний", а в худшем - "вроде это было вот в той книжке" (а по численным методам пришлось почитать довольно много чего интересного, спасибо И. С. Григорьеву и его отношению к прогульщикам-халявщикам).

В общем, мне понравилось.

Нужно ли программисту высшее образование

Нашел весьма забавные «десять мнений»:

http://eax.me/education/

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

Опенсорс и правила хорошего тона

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

— отсутствие документации, даже более-менее полного Javadoc, не говоря уже о руководстве по использованию
— местами странная архитектура
— много кажущихся излишними функций
— полумертвое состояние проекта на github (коммит раз в месяц — это же мало, да?)

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

Короче говоря, сейчас у меня имеется полноценный форк чужой библиотеки. Мне откровенно не нравится ее теперешнее состояние, внутренний перфекционист требует переделывать ее чуть менее, чем полностью. Лицензия там довольно либеральная, позволяющая вытворять с библиотекой что угодно. Но я очень сомневаюсь, что смогу со своими представлениями о том, что должно быть, вписаться в сложившийся вокруг osmdroid «узкий круг ограниченных людей». Более того, у меня нет времени на то, чтобы отстаивать свою точку зрения (а она у меня явно отличается от «официальной») в спорах с нынешними разработчиками. А с другой стороны — я сомневаюсь, что у меня хватит времени на поддержание и доведение этого форка до приличного вида.

В общем, как положено поступать в таких случаях?

Я упоролся? Да, я упоролся!

Пытался тут найти способ прикрутить к osmdroid «другую» картографическую проекцию — а так как никакой документации, кроме неполного Javadoc и пары кривых примеров на эту библиотеку в принципе нет, то пришлось читать исходники. И чем дальше, тем больше я убеждался в том, что проще подправить пару-тройку мест в osmdroid, чем заниматься всякой ерундой типа «subclass MapView and return your own custom projection in getProjection()».

Короче говоря, для того, чтобы решить маленькую и простую задачу — показать в одном приложении карты Bing, OSM, Google и Яндекс — причем уже довольно удовлетворительно решенную, я принимаюсь ковыряться в недрах картографической библиотеки. И чем дальше, тем больше возникают мысли типа «да тут всю систему менять надо!».

Интересно, дойдет ли до форка Android?

Про карты в интернете

Пытаюсь соорудить приложение на Android, отображающее много разных карт :) Первая попытка — взять WebView, а в него запихать Leaflet, оказалась довольно геморной и неудачной — карта подтормаживала, а при неудачном стечении обстоятельств — выделялась в этом WebView и напрочь отказывалась работать. Более того, оценив размер геморроя, который возникнет, если я захочу, к примеру, перемещать карту вслед за GPS-координатами мобильника, я решил поискать другие решения. Да и вообще, слово Turducken в программировании считается ругательным (а в кулинарии — вовсе нет).

Правда, на Leaflet можно было работать с целой тучей карт. Загибайте пальцы — Bing (схема и спутник), Google (схема и спутник), куча вариаций OSM, ArcGIS (спутник, схема и карта высот), 2ГИС и, по моему опыту, один из лучших вариантов — три карты Яндекса — схема, спутник и «народная», одна из наиболее точных и удобных. Но недостатки, к сожалению, перевесили :(

На текущий момент я остановился на osmdroid (если наркоманский github все же прикроют — то что-то осталось на Google Code). Так как OSM — штука довольно популярная, то довольно легко удалось запихнуть туда все карты из перечисленных, кроме Яндекса (умники, которые сейчас начнут рассказывать о лицензионных соглашениях картографических сервисов, идут лесом на йух). Наш любимый поисковик решил выпендриться и использовать не сферическую проекцию Меркатора, как подавляющее большинство картографических сервисов в Интернете, а эллиптическую.

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

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

http://msdn.microsoft.com/en-us/library/bb259689.aspx

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

Номер второй — Google.

https://developers.google.com/maps/documentation/javascript/maptypes?hl=ru#MapCoordinates

А тут — ни единого примера кода, так как Google на безальтернативной основе требует использовать свой API. Ну хоть представление о нумерации тайлов карты есть, спасибо и на этом.

И наконец, гигант отечественного интернета, Яндекс:

https://tech.yandex.ru/maps/doc/theory/concepts/coordinates-docpage/

Довольно бессвязный текст, содержащий чертову тучу лишней информации. Особенно радуют соседствующие выражения типа «Яндекс.Карты, как и большинство других геоинформационных сервисов, используют проекцию Меркатора» — а рядом «В отличие от некоторых других картографических сервисов, Яндекс.Карты используют эллиптическую (согласно WGS 84), а не сферическую проекцию Меркатора». Ну и опять же — «используйте наш API».

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

Хранить вечно

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

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

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

Еще компьютерно-лингвистическое

[info]vitus_wagner пошутил, что

разницы между remote и deleted русские не понимают, используя и для того и для другого слово «удалённый»

В комментариях [info]gleb_kulikov подсказал прекрасный перевод для слова remote (во всяких там remote access и прочих вариантах употребления) — «отдаленный». Мне кажется, что вполне неплохо, а вам?

Национальная ОС в трехмесячный срок

Пишут:

И.о. президента Украины Александр Турчинов издал указ № 449/2014 о мерах по совершенствованию формирования и реализации государственной политики в сфере информационной безопасности Украины. В тексте документа предлагается проработать вопрос о создании национальной защищенной операционной системы и национального антивирусного программного обеспечения. Также предложено создать специальные программные и технические средства защиты государственных информационных ресурсов и информационно-коммуникационных сетей. Сделать это нужно в трехмесячный срок.

Также предлагается создать национальный медиа-холдинг для подготовки качественного конкурентоспособного информационного продукта. Который будет обеспечивать распространение в мире объективных сведений об общественно-политической ситуации в Украине.

http://biz.liga.net/all/it/novosti/2741965-turchinov-rasporyadilsya-sozdat-ukrainskie-os-i-antivirus.htm

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

Ну и вдогонку — вы когда-нибудь сомневались в том, что «компьютерное пиратство» — это жупел, придуманный для защиты политических интересов США? Не сомневались? И правильно делали:

Офис Торгового представителя (ОТП) США исключил Украину из списка интеллектуальных пиратов, сообщает Министерство иностранных дел (МИД) Украины. 30 апреля ОТП США обнародовал «Специальный доклад 301» о состоянии защиты прав интеллектуальной собственности в разных странах мира, в т.ч. в Украине. Офис Торгового представителя США решил исключить Украину из нынешнего доклада.

http://biz.liga.net/all/it/novosti/2741970-ssha-isklyuchili-ukrainu-iz-spiska-intellektualnykh-piratov.htm

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