Тег ‘программирование’

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

На “Гиктаймсе” опубликовали конспект первой лекции курса Олега Артамонова по программированию микроконтролеров. Курс, конечно, немного экзотический в сравнении с любым интернетовским руководством по тем же 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 Гитхаб не предлагать.

Про музыку

Лучшее музыкальное сопровождение процесса установки Visual Studio – какой-нибудь убойный NSBM.

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

По-моему, почти в каждый курс программирования входит задачка вроде “напишите программу, решающую квадратные уравнения”. Обычно это второе или третье задание после “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 курса и обычно требуют неплохой математической подготовки вместе с серьезным "погружением" в предмет. Книги "для программистов" обходят численные методы стороной - тема эта все-таки довольно специфическая. Ценность же этой книги - в том, что в ней рассматриваются некоторые неочевидные приемы, о которых, как я помню, действительно упоминалось на семинарах - но они сохранились у меня в лучшем случае в виде "остаточных знаний", а в худшем - "вроде это было вот в той книжке" (а по численным методам пришлось почитать довольно много чего интересного, спасибо И. С. Григорьеву и его отношению к прогульщикам-халявщикам).

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

Хочется напомнить

Московский районный суд г. Калининграда подкинул повод перечитать Falsehoods Programmers Believe About Names. Кто не читал – рекомендую.

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

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

http://eax.me/education/

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

Таджикоанглийский

jamshoot-telegram

Один ли я, читая Release Notes на этой картинке, вспоминаю Равшана и Джамшута?

А вот вопросик

А никто не пользовался хостингами SVN+Trac? Например, что скажете про http://www.mysvn.ru/?

GitHub не хочу “по религиозным соображениям”.

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

Продолжаю упарываться по 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

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