Почему я пишу свои алгоритмы в 95% случаев, и буду и дальше разрабатывать кодовые велосипеды
Так почему я пишу свои алгоритмы в 95% случаев и буду их и дальше писать?
Дабы быть кратким, сразу приведу конкретику в моем случае (весьма экзотическом), но отмечу что есть немало случаев-аналогов. Если в вашей практике нет случая-аналога — поздравляю, вам не нужно заморачиваться велосипедами. Возьмите с полки пирож. Возьмите готовый код, это реально отличный вариант для RAD, да и просто для потоковой разработки, где время — деньги, а специальные требования отсутствуют.
Я разработчик экспериментальной системы управления крылатым беспилотником.
1. В моем коде не должно быть никаких «черных ящиков»Речь даже не идет про скомпилированные библиотеки (они табу изначально: весьма вероятен неэффективный и грязный код, да и потенциально возможны «закладки» в нем). Речь про фрагменты кода, найденные в интернете, которые не до конца понимаю. Моя система должна быть абсолютно понятной по алгоритму работы в первую очередь мне, как ведущему разработчику, т.к. именно я должен буду находить проблемное место и исправлять его.
2. У меня есть всего 160 мегагерц и 300 кб ОЗУЯ не могу позволить себе в первую очередь тратить мегагерцы, а во вторую килобайты.
Современные разработчики под «большие машины» избалованы обилием ресурсов. Они не оптимизируют код и склонны делать избыточные конструкции в стиле «и так работает шустро/компилятор все оптимизирует». Это расслабляет, и зачастую делает боле-менее нормальный код для больших компьютеров, нежизнеспособным в чужой экосистеме (например, на микроконтроллерах (МК)).
Код для МК потому должен максимально полно раскрывать и рассчитывать все, что используется не раз в коде. Чтото вроде очень глобальной оптимизации. Потому даже если берется решение «из форумов и stackoverflow», оно проверяется и оптимизируется (простейший пример такой оптимизации — замена обычных тригонометрических функций на табличные, предрасчитанные).
Внутри моего кода используется очень много абсолютных переходов типа goto, и все лишние расчеты максимально срезаются. Хороший чужой код, как правило, медлителен и неповоротлив. Например, техзрение. Отличная библиотека OpenCV — но куда мне ее впихивать? Это же кодовый монстр! От всего богатства функций технического зрения мне надо всего лишь определять расстояние до движущихся объектов и их границы. Причем на высокой частоте. Изучайте чужой опыт, но пишите свое.
3. Мой код должен быть быстрым и безопасным с точки зрения ошибок в логикеОчень тяжело проверять чужие коды на безопасность и устойчивость. И всякие cppcheck не помогут. Это хорошие инструменты, но они обнаруживают только технические, но не алгоритмические ошибки, которые в чужих кодах встречаются. Чаще проще написать с нуля, понимая идею и решение, чем адаптировать и переписывать к своим требованиям чужое. Да, это занимает время, но на выходе получаем очень эффективный и безопасный код. Заточенный именно под нужную задачу.
И немножко к личному опыту по изучаемой теме.
4. Еще одна причина работы с велосипедами сугубо отраслеваяВ моей индустрии нет готовых (открытых) решений, едва мы уходим от проторенной open source автопилотами дорожки. Например, проблема управления полетом на низком уровне (когда мы уже знаем, какая должна быть траектория и нужно всего лишь совместить положение борта с ней) описана в теоретических трудах как обычная PID цепочка. Все в целом просто, но el diablo скрывается в деталях. В сотнях мелких деталей. Что если отказал двигатель? Если у борта GPS ушел гулять на +-150м? Если инерциальный датчик горизонта из-за вибрации показывает направление на горизонт в районе полярной звезды? И так далее и тому подобное. Вы можете сказать: причем тут PID? Это выходит за его рамки! И будете правы, но задача-то итоговая — именно управление, потому вы смешиваете разные алгоритмы и их элементы в разных функциях. И потому все алгоритмы создаются с нуля, шлифуются и идеализируются именно под конкретную задачу в контексте автоматического управления БПЛА. Получается довольно ядреная спагетти-смесь из кодов, весьма сложная в изменениях, но крайне эффективно решающая задачу.
Известная истина, которую часто забывают (или ленятся вспомнить): эффективность/скорость — это противоположность универсализации. Не прямое противопоставление, но они не на одной чаше весов. Когда создается софт для очень экономичной экосистемы, образно говоря, каждый синус на счету. А уж тем более использование delay(), за которое надо некоторых авторов библиотек «расстреливать» (творческая аллегория) с этим самым delay(), чтобы растягивать процесс. Потому все быстрые функции пишутся in situ, с ограниченной универсальностью, а не берутся готовыми универсальными.
Коллеги, не стесняйтесь создавать велосипеды. Это держит мозг в тонусе и часто позволяет получать нетривиальные решения.