Да, так оно и есть. Естественно при добавления трения динамическая модель измениться — регулятор будет себя вести несколько по другому. Вообще с трением все же проще.
Но есть другой момент — задержки: допустим мы получаем значение pv всегда с какой-то задержкой, да и период опросов тоже повлияет
Ну к слову сказать выпускников ТАУ не так уж и много. У меня в универе всего 2 кафедры выпускали таких (а сейчас вообще одна только осталась), причем там только часть специализировалась именно на ТАУ, там реально капля в море.
А у остальных ТАУ если проходиться, то как-то совсем мимо. Да еще ТАУ требует хорошую математическую подготовку, а её… эээ… не все вузы могут обеспечить. На моей памяти, по крайней мере раньше, всех тауведов расхватывали еще на стадии студенческой скамьи, как щас я правда хз.
На самом деле я вообще сомневаюсь, что с ПИД-регуляторами можно что-то реально стабильное замутить — там уже по его общей форме передаточной характеристики видно что он нифига не стабилен. Все же оптимальные регуляторы это что-то другое
Но я когда-то давно использовал NSGA для настройки ПИД-регулятора: на выходе получал кучу вариантов настройки с учетом всех критериев качества. Вроде даже работало, вот только у меня была достаточно точная математическая модель динамической системы, поэтому я могу гонять NSGA в онлайне и уже потом применял полученные результаты на готовом устройстве.
А вот чтоб прям в онлайне он автотюнинлся… не ну есть такое, но это все под патентами и там куча яйцеголовых, в том же Сименсе над этим трудится.
1) В родной среде исполнения вроде бы будет все норм, а вот в Mono были времена когда начинался боксинг-анбоксинг. Сам удивился когда обнаружил.
2) За LINQ-сахаром будет скрыт тот же for на самом деле: иного пути в поиске просто нет — надо перебирать элементы коллекции, разве что можно извратиться и сделать, например, бинарный поиск (сложность которого логарифмическая, а не линейная, т.е. работать он будет быстрее) или еще чего.
Да и вообще LINQ-инструкции сложно-отслеживаемые в дебаггере и имеют вредную особенность подталкивать к говнокоду (вот уже на многих проектах такое замечал), да и вообще, в какой-то момент времени код становится трудно-сопровождаемым. Так что да — берем и пишем процедуру поиска элемента в коллекции, хуже (по производительности) работать не будет, это точно.
3) for Добавлю еще, что foreach не совсем таки безопасный, я бы сказал, что он совсем не безопасный. Enumerator не отслеживает состояние родительской коллекции после своего создания и может вернуть (при перечислении) объекты, которых там уже нет. О чем собственно упоминается в msdn. Исключения вылетающие на foreach — наверное самые частые которые мне приходилось разгребать в чужом коде и заменять foreach на for в таких ситуациях.
Ну и да, применение foreach подразумевает, что:
создается новый объект — итератор;
на каждой итерации идет вызов метода MoveNext;
на каждой итерации идет обращение к свойству Current, что равносильно вызову метода;
Конечно же родной JIT компиляторе в родной среде исполнения вумный и попытается соптимизировать. Но получается не всегда, а уж Mono так вообще такое не гарантирует (хотя последние версии пытаются), а древний Mono (вроде бы 2-ой) работающий под капотом Unity3D так вообще даже не попытается этого сделать. Хотя буквально пару месяцев назад вот наталкивался на ситуацию, когда foreach натурально сводил сума GC, который начинал молотить как сумашедший и всем становилось хорошо. И это было в .NET 4.6 под родимой виндой
В то время как глупый for просто обращается по индексу и все. Никаких премудростей и работать он будет везде одинаково, независимо от платформы, версии .NET, положения звезд, фазы Луны и т.д.
4) Я еще добавлю про var. Во-первых, опять таки это делает код трудно читаемым
натыкаешься на:
var a = Petja.GetUnknowVar();
И сидишь и думаешь, а это что вообще такое? Строка, циферка или какой-то класс, а может структура? Лезешь внутрь метода, а там снова Var на Var'e и Var'ом погоняет. Так и сидишь, ковыряешься в чужих потрохах.
Реально, var оправдан только тогда, когда нужно работать со всякими анонимнымными типами и прочих лямбда-ситуациях, т.е. тогда, когда частота порождения говнокода выше чем обычно. Вес остальное от лени, а поощрение лени плохо сочетается с самодисциплиной => говнокод. Я вот var обычно по пятницам использую, потом в понедельник что-нибудь ломается…
Хорошо шо хоть var проверяется еще на этапе компиляции. Правда тоже на умность компилятор надеется не стоит, напишите var i = 5 — и компилятор подставит int32, а на переполнения из-за Var я уже тоже натыкался. А вот dynamic… а применение динамических типов ОТКРЫВАЕТ ДВЕРИ АДА. То есть, оно говорит компилятору, что это динамический ВЫЗОВ АДСКОГО СОТОНЫ, и надо перенести все проверки типа (и ошибки соответственно) на время выполнения(с). Правда к Unity3D это вроде бы еще пока отношение не имеет
Не для того Хейлсберг создал строго-типизируемый язык программирования, что бы потом на нем пытаться писать «как буд-то это ЖабаСкрипт».
В общем когда сахара много, наступает момент когда код и его исполнение становится трудно предсказуемым
Вообще, ИМХО, вот именно так и надо писать правильную архитекутру (не вседа правда получается). Все слои программы должны быть максимально абстрагированы друг от друга: UI ничего не знает о бизнес логике, внутри бизнес-логики сущности ничего не подозревают друг о друге, если мы исключим из программы UI, то она должна скомпилироваться и работать, ну и т.д.
Это удобно, модульно, масштабируемо и конфигируруемо.
В противном же случае мы получим настоящий ад зависимостей и хрупки классы. Начнем что-нибудь исправлять и получим по лбу. В Unity3D собственно старая-новая система анимации (Меканим что ли она называется) вот прям ИМХО яркий пример того как не надо делать: если все делать как по учебнику, то анимация и игровая логика будут прибиты друг к другу гвоздями, фиг потом отдерешь.
Вся проблема только в том, как только продумать такую архитектуру.
Собственно да, самый простой пример использования нейросетей — выбор поведения, действительно легко вставляется и работает. Собственно гейм-дизайнеру остается только подбить таблицу где перечислены варианты желаемого поведения в разных ситуациях (одна проблема, таблица должна быть как можно больше, причем, чем больше нейронов в первом слое, тем больше нужно скормить примеров), а дальше нейросеть сама все выучит и сможет находить решения уже в других ситуациях, причем это достигается без всяких if'ов.
Вот только это надо бы до логического конца довести, когда будет время — хз.
YНу опрос больше для того, что бы посомтреть, чего народ больше интересует. По возможности то наверное я постараюсь по всем темам пройтись до которых руки доберуться. Например, по алгоритмам самонаведения ракет, все уже собственно есть:
Алгоритмы разные, в последнем видео исторически самый первый алгоритм, которым можно попадать только по прямо-летящим целям :-) Первый и второй и спользуются уже в современных ракетах (например AIM-120 и AIM-9).
Есть и другие варианты. На самом деле ничего сложного — алгоритмы простые и эффективные и записываются в пару строчек кода, только вот информации по ним нихрена нет (точнее она есть, но очень мало и писец как заумно, а уж на русском языке я вообще не знаю ни одной книги по автонавигации).
По-моему у меня даже уже специальный проект на базе стнардартного Unity3D (где там с самолетиками) уже запилен. Так что только причесать и вперед.
Вот с другими вопросами несколько сложнее, например с нейросетями, а их же можно использовать по-разному: самый простой вариант — выбор поведения в зависимости от текущей ситуации, а обучение — по специальной таблице, в которой мы описываем несколько желаемых шаблонов поведения — далее back-propogation и вперед, еще и в процессе игры можно дообучать немного. Другой вариант — использование нейроэволюции — это уже долго, т.к. процесс обучения это повторяющиеся раунды, зато можно запилить совсем прямое управление, которые иммитируют нажатие кнопок игроком:
Видео уже не мое, но сам принцип демонстрирует, собственно используемый в видео NEAT в качестве халявного Ассета для Юнити уже даже появился.
В общем там тоже технологий много, самых разных и надо бы это дело таки добить, только время нужно.
По ПИД-регуляторам: надо думать — еще больше примеров и прикинуть как бы по-проще реализовать простую автонастройку.
На самом деле тема «оптимальный синтез ПИД-регуляторов» еще открыта и я думаю там люди до сих пор диссертации защищают. Собственно ключевое преимущество ПИД-регуляторов, в том что они легко реализуемы (на самом деле ПИД-регулятор в идеальной форме в общем-то нереализуем, но народ итак живет и не жалуется) и их можно быстро настроить ручками, отсюда такое их повальное распространение. Собственно имея более-менее корректно реализованный ПИД-регулятор его можно быстренько на глазок настроить не углубляясь в математику — это большой плюс. Тут правда наверное следуют все же запилить какой-то тулкит для редактора Unity3D, шоб можно было результаты своих настроек посмотреть на графиках.
А так подходов несколько:
— характеристические методы по данным полученным в результате испытания в разомкнутом контуре, собственно тот же метод Циглера-Никольса
— аналитический синтез, формулы там несложные, вот только нужная точная модель объекта управления
— синтез на основе частотных характеристик, и опять таки, эти частотные характеристики САУ надо откуда-то получить
— и собственно оптимальный численный синтез, но и там нужно как-то идентифицировать наш объект управления.
В общем виде придется делать так:
1. Идентифицировать систему (допустим наш корабль), ну там хз, подавать ступенчатые воздействия или еще какие более хитрые, прям в самой игре. А на их основе построить модель: ПИД-регуляторы могут работать с моделями первого и второго рода, их форма известно, нужно только параметры как-то подобрать.
2. Ну а потом уже имея модельку, мы можем численно оптимизировать параметры ПИД-регулятора отдельно от игрового цикла Юнити.
Вот только тут тоже есть проблемка — критериев качества много: максимизировать скорость нарастания переходного процесса, минимизировать ошибку перерегулирования и автоколебания, минимизировать длительность переходного процесса. В общем куча критериев, которые еще друг другу противоречат — увеличиваем реакцию системы (например, скорость поворота) и появляются колебания, уменьшаем колебаний — увеличивается время реакции, ну и т.д.
Т.е. этих более менее оптимальных ПИД-регуляторов только на один объект управления будет не один, а дохрена и все простые и классические методы оптимизации идут лесом, тут нужно уже что-то посложнее. Хотя в принципе можно обойтись и оптимизации по критерию стабильности САУ.
Всякие хитры методы автонастройки/оптимизации ПИД-регуляторов — патентуют все кому не лень и хотят за это много денег.
В общем тут надо еще подумать, как бы получше и попроще запилить тулкит именно для ПИД-регуляторов игровых объектов в Unity3D. Либо это действительно будет метод Циглера-Никольса где как раз и используется стандартная форма ПИД-регулятора, которую я выше привел — правда в примере с космическим кораблем он не заработает — он всегда устойчиво колебается, когда нет трения (а вот когда есть — таки заработает), так что не получится найти критическое значение Kp и соответствующий ему период колебаний Tu. Либо же это будет какой-то сугубо численный метод оптимизации, шоб был простым и эффективным. Это вот предпочтительнее ИМХО, но надо думать.
Это не так. Можно говорить, что в механических системах и при наличии трения это похоже на правду, но не в общем случае.
Вот как раз здесь пример именно, что без трения — можете собрать такой же проект на Unity3D и сидеть ждать, когда положение корабля стабилизируется после поворота — если использовать только один П-регулятор, то это случится… никогда, ну я по крайней мере не дожадлся :-), да и в Octave тоже самое получается.
А вот при наличии углового трения, уже да, колебания корабля во время поворотов станут затухающими и он сможет стабилизироваться в заданном положении, через какое-то время, но это будет равносильно тому, что для случая без трения мы добавили еще один контур П-регулирования по скорости (как в самом конце статьи).
А вот если мы выкинем из модели всю динамику вращательного и поступательного движения, т.е., например, будем напрямую и мгновенно менять положение, то тогда да, тогда с П-законом вообще никаких проблем не будет. Но это уже будет другая динамическая система и совсем другая модель. Вот только тут не понятно что общее, а что частное: мое мнение такое, что в принципе все физические процессы инертны, да еще такие неприятные моменты, как задержки в контуре управления и т.д., т.е П-составляющая всегда будет вносить некоторую колебательность, но для некоторых частных случаев все будет хорошо.
Вот это вообще на столько не так, что я даже теряюсь, откуда это. Никакой ошибки смещения нормально сделанная интегральная составляющая вносить не будет (разве что в каком-то очень искусственном примере, но я не смог с ходу такого придумать).
Что значит «нормально сделанная»?
Это же фундаментальная особенность именно операции «интегрирования»: на всем интервале наблюдения (интегрирования) все значения [ошибок в нашем случае] будут просуммированы и накоплены.
Можно посмотреть на это по другому — звено интегратора найдет площадь криволинейной трапеции, описываемой функции ошибки, и эта площадь на всем интервале наблюдения почти всегда будет отличная от нуля.
Это разве что ли прикрутить какой-нибудь костыль, например, сбрасывать аккумулятор через определенные интервалы времени или еще чего.
Просто в реальной жизни астатичные системы встречаются редко и обычно имеют дело со статичными САУ, у которых всегда имеется некоторая установившееся ошибка после переходного процесса. И вот интегральное звено эту ошибку компенсирует и повысит степень астатизма САУ. Осталось только придумать такую динамическую систему, которую можно было бы (и имел бы смысл) использовать в игре.
Что касается примеров того, где интегральная составляющая вносит смещение, то пожалуйста: собственно сабж — сделайте Ki, отличную от нуля и всегда будете получать некоторую ошибку, вот прям здесь это хорошо видно на примере регулятора угловых скоростей youtu.be/oVL0tvluUe8?t=48 но и с регулятором угла будет такая же ситуация. А уж в совсем запущенных случаях (при большом коэффициенте) интегратор так вообще раскачает корабль и выведет его из равновесия.
А вот если если снова добавить трение, то интегратор будет уже не таким страшным — только толку от него все равно никакого не будет, только длительность переходного процесса увеличит, а корабль итак без смещения выставляется в нужный угол.
Так что тут остается только вносить в программную модельку, блин я даже так с ходу хз, например, какую-то постоянную ошибку при определении скоростей или позиции, шумы там какие-нибудь, то тогда да, тогда интегральная составляющая будет работать. Вопрос только — а надо ли это? Я вот хз, например, в том же KSP я не замечал что они там моделируют какие-то ошибки управления и шумы и т.д.
В общем все зависит исключительно от того какую динамическую систему мы пытаемся регулировать. Вот можно было бы сейчас повыдумывать разные динамические системы из игр, впихнуть их в Unity3D и расширить статью, вот в тех примерах, которые я приводил — рулят исключительно П- и ПД-регуляторы (что в случае наличия трения, что без оного).
Может если сюда заглянет какой-нибудь разработчик и расскажет где какие у него проблемы или что он использует. Просто те же повороты в Unity3D можно реализовать без этих всяких регуляторов: заморозили оси вращения и и используем Qunaternion.Lerp и все (пример я тоже тут привел), еще и контроллировать параметры игровых объектов будет проще. А вот, например, если управление осуществляется честно только за счет физики (т.е. прикладывая разные силы к объектам), тут вот у народа возникают вопросы, как реализовать повороты и круиз-контроль (вот хотел его тоже добавить, но сил не хватило, может потом расширю статью), еще и при разных параметрах физики (с трением/без трения, со всякими материалами и т.д.).
Какие еще примеры можно выдумать?
Вот в случае… эээ… наведения ракеты на маневрирующую цель с переменным ускорением, вот там как раз можно впихнуть интегратор и будет работать точнее и надежнее, но это точно уже другая статья и отдельная тема по алгоритмам навигации (а их несколько), по которой кстати тоже вопросы «как это сделать в Unity3D» постоянно задаются forum.unity.com/threads/augmented-proportional-navigation.392427 и на них не особенно охотно отвечают, зато продают ассеты :-)
Фильтр Калмана и наблюдатели в этой задаче ни при чём, они используются для оценивания недоступных измерению состояний объекта.
Ну, например, я вот не особо в курсе, что за динамическая система типа Ship у меня в итоге получилась: если массу, предположим, я задаю ручками, то вот какой момент инерции получается — я хз, потому что твердое тело сложной формы (и Unity3D это все же учитывает). А знал бы какой момент инерции, то смог бы тогда синтезировать оптимальный регулятор контроля поворота или еще чего. Тем более еще под большим вопросом, что твориться внутри физического движка Unity3D, тут вот на Хабре есть целая статья, где народ выяснял как там работает трение (с RigidBody2D проще, т.к. Unity3D использует Box2D для таких тел и в его исходном коде можно порыться, но опять таки большое хз, чего там своего авторы Unity3D могли наворотить, а их мануал вообще нихрена не раскрывает того, что твориться под капотом).
В общем, тут бы по-хорошему еще бы пройтись по идентификации динамической системы в Unity3D.
Да уже почти 50 лет как нет. :) Годов с 70-х прошлого века, наверное.
Я хз, как крутили-вертели Фурье, Лапласом, Гильбертом и Z-преобразованием, так и крутят-вертят дальше.
Вообще-то нет, можно и без упорядоченного набора обойтись, просто вы наверное никогда не слышали про Spatial hashing — это кстати куда тривиальнее чем работать с деревьями.
Проблемы хэш-таблиц вроде бы уже передавали. Куда уж конкретнее? Хотите увидеть вживую — попадете к нам, подпишете NDA и увидите.
Выше целый класс задач указан где хэш-таблицы в принципе себя плохо чувствуют, могу повториться: а) Любые приложения работающие в реальном времени, б) если и количестве информации ничего не известно наперед и требуется неограниченная масштабируемость.
Вы же сами один из примеров и привели. А знайте как дэдосят, например, абоненты сотовой связи — уууу, это их нормальный режим работы.
Или например, для collision detected в физическом движке какого-нибудь несчастного платформера будут использоваться именно деревья, но можете извратиться и попробовать обойтись хэш-таблицами. В QTCustomPlot тоже используются для хранения именно красно-черные деревья (хотя для таких задач еще и порядок будет иметь значение, но не всегда), а у компонент от Dundas (эти занимаются Business Intelligence) во всю используются те же деревья и skip list. Интересно, почему?
Xor, не-xor: Любая хэш-функция плохая, если заведомо наперед НЕ известен весь набор ключей. Вот когда известен, вот тогда да, тогда хэширование может стать идеальным :-) Любые условия с накладываемыми ограничениями на память тоже плохие. Хэш-таблицы это хорошо, когда у вас здоровенный массив простых данных к которым обращения не такие уж и частые и
На любых хэш-таблицах в худшем случае операция удаления, вставки и поиска занимает O(n) времени — это их фундаментальный недостаток: хэш-функция не гарантирует уникальность ключей, а идеальную хэш-функцию еще пока не придумали, так что в любом случае наступит момент коллизии, и тогда в случае открытой адресации придется тыкаться по всему списку — например, для почти полностью заполненной таблицы, каждое пробирование займет уже вроде чойт порядка 0.63*N + const. Собственно в случае заполненной таблице, например, при вставке нового элемента окажется, что вы вышли за пределы диапазона и придется все перехешировать заново, что вообще-то тоже не дешевая операция. В методе цепочек вставлять Вы конечно будете за O(1+const), вот только поиск и удаление уже потребуют перебора всех элементов цепочки
Помимо этого, есть еще такие неприятные вещи как:
1) Кэш процессора — он вообще-то не резиновый, так что, например, для того же метода цепочек это может оказаться бутылочным горлышком
2) Плохое распределение ссылок в памяти.
В общем да, с памятью у них проблемы, иногда это критично.
Ну а собственно, «хорошие» хэш-функции, которые нас должны спасать от коллизий — тоже не бесплатные. Можно, конечно, исхитрятся, разменивая память на скорость, это вот прям целая специалаьная олимпиада: кто напишет самую быструю хэш-таблицу, но в случае если:
1) время выполнения критично, ну т.е. даже вероятность в 0.001% что случится неприятный момент и операция займет в N раз больше времени уже не канает.
2) порядок имеет значение
3) природа, т.е. количество и распределения поступающих данных хз какая и иих еще надо постоянно вставлять/удалять
то хэш-таблицы использовать неприемлемо, есть куда более замечательные деревья, которые всегда дают O(N*logN).
Это все косяки менеджмента, причем ползучие.
Например давно-давно был у меня пространный случай: Меня 2 часа опрашивали по книги Рихтера, т.е.
1) Да реально последовательно перебирали оглавление книги. Зачем? Почему именно Рихтер?
2)Да. Вообще я шел не на .NET погроммиста. Шел я на того, кого обычно называют Algorithm Engineer. ИМХО тут все же должны быть акцент явно не на вопросы по конкретной технологии, конкретного языка.
3) Потом уже, я случайно наткнулся на собеседовавшего в LinkedIn: Забавно, но на тот момент это было первое его место работы, причем работал там он меньше года, вообще чувак оказался заметно младше, но уже Сениор, но вскоре ушел, причем он вообще за все это время нигде больше года не задерживался и везде Сениор.
Вообще это все странно выглядит, вот прям все: Скороспелые сениоры сразу после универа, текучка (ну вот не отпускают просто так ведущих сотрудников), странные собеседования. При этом конторы вообще-то не Рога и Копыта
А. Ну да. Есть такой подход. Тут только вопрос как правильно задачки формулировать.
Вот когда мне представлялась возможность подбирать людей — всегда ходил по пути наименьшего сопротивления — если для погромистов, то это набор задачек на обход графа, кластеризацию или даже преобразование Фурье, которые надо реализовать в задании (дистанционно) где на вход программы подается А, а на выходе получается В, а дальше как хотите — полная свобода действий. Например, достаточно стандартная задача для программиста, который учился именно на программиста: Найти кратчайший путь из точки А в точку В. Ну понятное дело обычно там идут алгоритмы Дейкстры, алгоритм Ли и А*. Но вот присылали, например, реализацию с использование Q-learning или например с возможностью использовать разные метрики: Евклидовое расстояние или манхэтенноское. Ну и да, стиль программирования и оформление кода не менее важен.
Для не совсем погромистов — ну там другие люди примерно по тому же принципу составляли, собственно я так сам и устраивался: Решал тестовые задачи.
Есть еще один кстати момент. Много раз доводилось работать с людьми, которые, мягко говоря… эээ… интроверты. В общем устные беседы таким людям даются тяжело, хотя вообще-то они оказываются крутыми специалистами
Если честно я уже чего только не видел, особенно на этих многоуровневых собеседованиях. На люки, например, натыкался несколько на точно, при этом я видел в живую треугольные люки :-) Гномы какие-то попадались, просили возвести 2 в 32 степени, мыши какие-то.
Или например после долгого скрининга по всяким регуляризациям в методах оптимизации или там хитрым вопросам по ML, на следующем этапе всплывали ВНЕЗАПНО например контейнеры C++ или еще какая фигня (например, потому что такое было в нескольких местах, и внезапно потому что… ну потому что внезапно).
Так шо я даже хз. Я уже перестал понимать логику современного рекрутинга.
Вообще на тему рекрутинга мериканцы исписали тонны макулатуры в научных журналах.
Я даже по памяти попытаюсь вспомнить, какие методы самые надежные:
1) Тест на IQ или GMA,
2) Тест на лояльность (как бы грустно это не было, но это так)
3) Выполнение практических тестовых задач
4) Структурированное интервью
В общем умение по памяти на литрчке записать алгоритм Дейкстры сюда не входит, хотя его и можно впихнуть в структурированное интервью, вот только корреляция эффективности работы и успешность в прохождении теста на IQ будет все равно выше, а он как известно не требует наличия специальных знаний: Кружочки, квадратики, циферки да буковки.
Тут просто надо уяснить, что вопросы про бинарные деревья не более чем тест на эрудицию и хорошую память — это конечно навыки полезные, также как и умение разбивать головой бутылки и решать на скорость олимпиадные задачки, но далеко не ключевые.
Меня когда напрягают "прособеседовать" — то я принимаю решение исключительно по выполнению тестовых домашних заданий, которые отправляю еще до того как увижу человека вживую. Собственно у нас в конторе это итак основной подход (по крайней мере в моем департаменте).
А спрашивать определение ппроизводной или чем отличается стринг от стирнгбилдера человека с диплом и опытом работы как-то стремно это ИМХО, вроде как не на экзамене в университете/на курсах. Я бы сказал, что даже неэтично.
Ну я думаю формальное знание интеграла не является достаточным условием спасения от того что решение разойдется.
А самое главное — Вы никак не проверите: Знает он или не знает с помощью листочка и ручки за 15 минут.
Тем более интегралов много, а численных способов еще больше: Чего спрашивать то надо? Я вот и не вспомню формулу Симпсона — она мне просто не нужна, у меня последнее время сплошное Монте-Карло, а формулу трапеций мне кажется практически любой сможет вывести на обывательском уровне.
Ну т.е. глубину Вы никак проверить не сможете, в лучшем случае только по верхам пройтись сможете, но это ничего не гарантирует.
Ну мне кажется, что разрывные функции должны как минимум быть интегрируемыми по Лебегу, даже такие, как функция Дирихле, например, а некоторые из них вполне себе будут интегрируемы по Риману на сегменте. Но вообще IRL все задачи невыпуклые, а все функции разрывные, так что в любом случае будет грустно и все будут лажать :-)
Но есть другой момент — задержки: допустим мы получаем значение pv всегда с какой-то задержкой, да и период опросов тоже повлияет
А у остальных ТАУ если проходиться, то как-то совсем мимо. Да еще ТАУ требует хорошую математическую подготовку, а её… эээ… не все вузы могут обеспечить. На моей памяти, по крайней мере раньше, всех тауведов расхватывали еще на стадии студенческой скамьи, как щас я правда хз.
Но я когда-то давно использовал NSGA для настройки ПИД-регулятора: на выходе получал кучу вариантов настройки с учетом всех критериев качества. Вроде даже работало, вот только у меня была достаточно точная математическая модель динамической системы, поэтому я могу гонять NSGA в онлайне и уже потом применял полученные результаты на готовом устройстве.
А вот чтоб прям в онлайне он автотюнинлся… не ну есть такое, но это все под патентами и там куча яйцеголовых, в том же Сименсе над этим трудится.
2) За LINQ-сахаром будет скрыт тот же for на самом деле: иного пути в поиске просто нет — надо перебирать элементы коллекции, разве что можно извратиться и сделать, например, бинарный поиск (сложность которого логарифмическая, а не линейная, т.е. работать он будет быстрее) или еще чего.
Да и вообще LINQ-инструкции сложно-отслеживаемые в дебаггере и имеют вредную особенность подталкивать к говнокоду (вот уже на многих проектах такое замечал), да и вообще, в какой-то момент времени код становится трудно-сопровождаемым. Так что да — берем и пишем процедуру поиска элемента в коллекции, хуже (по производительности) работать не будет, это точно.
3) for Добавлю еще, что foreach не совсем таки безопасный, я бы сказал, что он совсем не безопасный. Enumerator не отслеживает состояние родительской коллекции после своего создания и может вернуть (при перечислении) объекты, которых там уже нет. О чем собственно упоминается в msdn. Исключения вылетающие на foreach — наверное самые частые которые мне приходилось разгребать в чужом коде и заменять foreach на for в таких ситуациях.
Ну и да, применение foreach подразумевает, что:
Конечно же родной JIT компиляторе в родной среде исполнения вумный и попытается соптимизировать. Но получается не всегда, а уж Mono так вообще такое не гарантирует (хотя последние версии пытаются), а древний Mono (вроде бы 2-ой) работающий под капотом Unity3D так вообще даже не попытается этого сделать. Хотя буквально пару месяцев назад вот наталкивался на ситуацию, когда foreach натурально сводил сума GC, который начинал молотить как сумашедший и всем становилось хорошо. И это было в .NET 4.6 под родимой виндой
В то время как глупый for просто обращается по индексу и все. Никаких премудростей и работать он будет везде одинаково, независимо от платформы, версии .NET, положения звезд, фазы Луны и т.д.
4) Я еще добавлю про var. Во-первых, опять таки это делает код трудно читаемым
натыкаешься на:
И сидишь и думаешь, а это что вообще такое? Строка, циферка или какой-то класс, а может структура? Лезешь внутрь метода, а там снова Var на Var'e и Var'ом погоняет. Так и сидишь, ковыряешься в чужих потрохах.
Реально, var оправдан только тогда, когда нужно работать со всякими анонимнымными типами и прочих лямбда-ситуациях, т.е. тогда, когда частота порождения говнокода выше чем обычно. Вес остальное от лени, а поощрение лени плохо сочетается с самодисциплиной => говнокод. Я вот var обычно по пятницам использую, потом в понедельник что-нибудь ломается…
Хорошо шо хоть var проверяется еще на этапе компиляции. Правда тоже на умность компилятор надеется не стоит, напишите var i = 5 — и компилятор подставит int32, а на переполнения из-за Var я уже тоже натыкался. А вот dynamic… а применение динамических типов ОТКРЫВАЕТ ДВЕРИ АДА. То есть, оно говорит компилятору, что это динамический ВЫЗОВ АДСКОГО СОТОНЫ, и надо перенести все проверки типа (и ошибки соответственно) на время выполнения(с). Правда к Unity3D это вроде бы еще пока отношение не имеет
Не для того Хейлсберг создал строго-типизируемый язык программирования, что бы потом на нем пытаться писать «как буд-то это ЖабаСкрипт».
В общем когда сахара много, наступает момент когда код и его исполнение становится трудно предсказуемым
Это удобно, модульно, масштабируемо и конфигируруемо.
В противном же случае мы получим настоящий ад зависимостей и хрупки классы. Начнем что-нибудь исправлять и получим по лбу. В Unity3D собственно старая-новая система анимации (Меканим что ли она называется) вот прям ИМХО яркий пример того как не надо делать: если все делать как по учебнику, то анимация и игровая логика будут прибиты друг к другу гвоздями, фиг потом отдерешь.
Вся проблема только в том, как только продумать такую архитектуру.
Вот только это надо бы до логического конца довести, когда будет время — хз.
Алгоритмы разные, в последнем видео исторически самый первый алгоритм, которым можно попадать только по прямо-летящим целям :-) Первый и второй и спользуются уже в современных ракетах (например AIM-120 и AIM-9).
Есть и другие варианты. На самом деле ничего сложного — алгоритмы простые и эффективные и записываются в пару строчек кода, только вот информации по ним нихрена нет (точнее она есть, но очень мало и писец как заумно, а уж на русском языке я вообще не знаю ни одной книги по автонавигации).
По-моему у меня даже уже специальный проект на базе стнардартного Unity3D (где там с самолетиками) уже запилен. Так что только причесать и вперед.
Вот с другими вопросами несколько сложнее, например с нейросетями, а их же можно использовать по-разному: самый простой вариант — выбор поведения в зависимости от текущей ситуации, а обучение — по специальной таблице, в которой мы описываем несколько желаемых шаблонов поведения — далее back-propogation и вперед, еще и в процессе игры можно дообучать немного. Другой вариант — использование нейроэволюции — это уже долго, т.к. процесс обучения это повторяющиеся раунды, зато можно запилить совсем прямое управление, которые иммитируют нажатие кнопок игроком:
Видео уже не мое, но сам принцип демонстрирует, собственно используемый в видео NEAT в качестве халявного Ассета для Юнити уже даже появился.
В общем там тоже технологий много, самых разных и надо бы это дело таки добить, только время нужно.
По ПИД-регуляторам: надо думать — еще больше примеров и прикинуть как бы по-проще реализовать простую автонастройку.
А так подходов несколько:
— характеристические методы по данным полученным в результате испытания в разомкнутом контуре, собственно тот же метод Циглера-Никольса
— аналитический синтез, формулы там несложные, вот только нужная точная модель объекта управления
— синтез на основе частотных характеристик, и опять таки, эти частотные характеристики САУ надо откуда-то получить
— и собственно оптимальный численный синтез, но и там нужно как-то идентифицировать наш объект управления.
В общем виде придется делать так:
1. Идентифицировать систему (допустим наш корабль), ну там хз, подавать ступенчатые воздействия или еще какие более хитрые, прям в самой игре. А на их основе построить модель: ПИД-регуляторы могут работать с моделями первого и второго рода, их форма известно, нужно только параметры как-то подобрать.
2. Ну а потом уже имея модельку, мы можем численно оптимизировать параметры ПИД-регулятора отдельно от игрового цикла Юнити.
Вот только тут тоже есть проблемка — критериев качества много: максимизировать скорость нарастания переходного процесса, минимизировать ошибку перерегулирования и автоколебания, минимизировать длительность переходного процесса. В общем куча критериев, которые еще друг другу противоречат — увеличиваем реакцию системы (например, скорость поворота) и появляются колебания, уменьшаем колебаний — увеличивается время реакции, ну и т.д.
Т.е. этих более менее оптимальных ПИД-регуляторов только на один объект управления будет не один, а дохрена и все простые и классические методы оптимизации идут лесом, тут нужно уже что-то посложнее. Хотя в принципе можно обойтись и оптимизации по критерию стабильности САУ.
Всякие хитры методы автонастройки/оптимизации ПИД-регуляторов — патентуют все кому не лень и хотят за это много денег.
В общем тут надо еще подумать, как бы получше и попроще запилить тулкит именно для ПИД-регуляторов игровых объектов в Unity3D. Либо это действительно будет метод Циглера-Никольса где как раз и используется стандартная форма ПИД-регулятора, которую я выше привел — правда в примере с космическим кораблем он не заработает — он всегда устойчиво колебается, когда нет трения (а вот когда есть — таки заработает), так что не получится найти критическое значение Kp и соответствующий ему период колебаний Tu. Либо же это будет какой-то сугубо численный метод оптимизации, шоб был простым и эффективным. Это вот предпочтительнее ИМХО, но надо думать.
Вот как раз здесь пример именно, что без трения — можете собрать такой же проект на Unity3D и сидеть ждать, когда положение корабля стабилизируется после поворота — если использовать только один П-регулятор, то это случится… никогда, ну я по крайней мере не дожадлся :-), да и в Octave тоже самое получается.
А вот при наличии углового трения, уже да, колебания корабля во время поворотов станут затухающими и он сможет стабилизироваться в заданном положении, через какое-то время, но это будет равносильно тому, что для случая без трения мы добавили еще один контур П-регулирования по скорости (как в самом конце статьи).
А вот если мы выкинем из модели всю динамику вращательного и поступательного движения, т.е., например, будем напрямую и мгновенно менять положение, то тогда да, тогда с П-законом вообще никаких проблем не будет. Но это уже будет другая динамическая система и совсем другая модель. Вот только тут не понятно что общее, а что частное: мое мнение такое, что в принципе все физические процессы инертны, да еще такие неприятные моменты, как задержки в контуре управления и т.д., т.е П-составляющая всегда будет вносить некоторую колебательность, но для некоторых частных случаев все будет хорошо.
Что значит «нормально сделанная»?
Это же фундаментальная особенность именно операции «интегрирования»: на всем интервале наблюдения (интегрирования) все значения [ошибок в нашем случае] будут просуммированы и накоплены.
Можно посмотреть на это по другому — звено интегратора найдет площадь криволинейной трапеции, описываемой функции ошибки, и эта площадь на всем интервале наблюдения почти всегда будет отличная от нуля.
Это разве что ли прикрутить какой-нибудь костыль, например, сбрасывать аккумулятор через определенные интервалы времени или еще чего.
Просто в реальной жизни астатичные системы встречаются редко и обычно имеют дело со статичными САУ, у которых всегда имеется некоторая установившееся ошибка после переходного процесса. И вот интегральное звено эту ошибку компенсирует и повысит степень астатизма САУ. Осталось только придумать такую динамическую систему, которую можно было бы (и имел бы смысл) использовать в игре.
Что касается примеров того, где интегральная составляющая вносит смещение, то пожалуйста: собственно сабж — сделайте Ki, отличную от нуля и всегда будете получать некоторую ошибку, вот прям здесь это хорошо видно на примере регулятора угловых скоростей youtu.be/oVL0tvluUe8?t=48 но и с регулятором угла будет такая же ситуация. А уж в совсем запущенных случаях (при большом коэффициенте) интегратор так вообще раскачает корабль и выведет его из равновесия.
А вот если если снова добавить трение, то интегратор будет уже не таким страшным — только толку от него все равно никакого не будет, только длительность переходного процесса увеличит, а корабль итак без смещения выставляется в нужный угол.
Так что тут остается только вносить в программную модельку, блин я даже так с ходу хз, например, какую-то постоянную ошибку при определении скоростей или позиции, шумы там какие-нибудь, то тогда да, тогда интегральная составляющая будет работать. Вопрос только — а надо ли это? Я вот хз, например, в том же KSP я не замечал что они там моделируют какие-то ошибки управления и шумы и т.д.
В общем все зависит исключительно от того какую динамическую систему мы пытаемся регулировать. Вот можно было бы сейчас повыдумывать разные динамические системы из игр, впихнуть их в Unity3D и расширить статью, вот в тех примерах, которые я приводил — рулят исключительно П- и ПД-регуляторы (что в случае наличия трения, что без оного).
Может если сюда заглянет какой-нибудь разработчик и расскажет где какие у него проблемы или что он использует. Просто те же повороты в Unity3D можно реализовать без этих всяких регуляторов: заморозили оси вращения и и используем Qunaternion.Lerp и все (пример я тоже тут привел), еще и контроллировать параметры игровых объектов будет проще. А вот, например, если управление осуществляется честно только за счет физики (т.е. прикладывая разные силы к объектам), тут вот у народа возникают вопросы, как реализовать повороты и круиз-контроль (вот хотел его тоже добавить, но сил не хватило, может потом расширю статью), еще и при разных параметрах физики (с трением/без трения, со всякими материалами и т.д.).
Какие еще примеры можно выдумать?
Вот в случае… эээ… наведения ракеты на маневрирующую цель с переменным ускорением, вот там как раз можно впихнуть интегратор и будет работать точнее и надежнее, но это точно уже другая статья и отдельная тема по алгоритмам навигации (а их несколько), по которой кстати тоже вопросы «как это сделать в Unity3D» постоянно задаются forum.unity.com/threads/augmented-proportional-navigation.392427 и на них не особенно охотно отвечают, зато продают ассеты :-)
Ну, например, я вот не особо в курсе, что за динамическая система типа Ship у меня в итоге получилась: если массу, предположим, я задаю ручками, то вот какой момент инерции получается — я хз, потому что твердое тело сложной формы (и Unity3D это все же учитывает). А знал бы какой момент инерции, то смог бы тогда синтезировать оптимальный регулятор контроля поворота или еще чего. Тем более еще под большим вопросом, что твориться внутри физического движка Unity3D, тут вот на Хабре есть целая статья, где народ выяснял как там работает трение (с RigidBody2D проще, т.к. Unity3D использует Box2D для таких тел и в его исходном коде можно порыться, но опять таки большое хз, чего там своего авторы Unity3D могли наворотить, а их мануал вообще нихрена не раскрывает того, что твориться под капотом).
В общем, тут бы по-хорошему еще бы пройтись по идентификации динамической системы в Unity3D.
Я хз, как крутили-вертели Фурье, Лапласом, Гильбертом и Z-преобразованием, так и крутят-вертят дальше.
Вообще-то нет, можно и без упорядоченного набора обойтись, просто вы наверное никогда не слышали про Spatial hashing — это кстати куда тривиальнее чем работать с деревьями.
Проблемы хэш-таблиц вроде бы уже передавали. Куда уж конкретнее? Хотите увидеть вживую — попадете к нам, подпишете NDA и увидите.
Выше целый класс задач указан где хэш-таблицы в принципе себя плохо чувствуют, могу повториться: а) Любые приложения работающие в реальном времени, б) если и количестве информации ничего не известно наперед и требуется неограниченная масштабируемость.
Вы же сами один из примеров и привели. А знайте как дэдосят, например, абоненты сотовой связи — уууу, это их нормальный режим работы.
Или например, для collision detected в физическом движке какого-нибудь несчастного платформера будут использоваться именно деревья, но можете извратиться и попробовать обойтись хэш-таблицами. В QTCustomPlot тоже используются для хранения именно красно-черные деревья (хотя для таких задач еще и порядок будет иметь значение, но не всегда), а у компонент от Dundas (эти занимаются Business Intelligence) во всю используются те же деревья и skip list. Интересно, почему?
Xor, не-xor: Любая хэш-функция плохая, если заведомо наперед НЕ известен весь набор ключей. Вот когда известен, вот тогда да, тогда хэширование может стать идеальным :-) Любые условия с накладываемыми ограничениями на память тоже плохие. Хэш-таблицы это хорошо, когда у вас здоровенный массив простых данных к которым обращения не такие уж и частые и
Помимо этого, есть еще такие неприятные вещи как:
1) Кэш процессора — он вообще-то не резиновый, так что, например, для того же метода цепочек это может оказаться бутылочным горлышком
2) Плохое распределение ссылок в памяти.
В общем да, с памятью у них проблемы, иногда это критично.
Ну а собственно, «хорошие» хэш-функции, которые нас должны спасать от коллизий — тоже не бесплатные. Можно, конечно, исхитрятся, разменивая память на скорость, это вот прям целая специалаьная олимпиада: кто напишет самую быструю хэш-таблицу, но в случае если:
1) время выполнения критично, ну т.е. даже вероятность в 0.001% что случится неприятный момент и операция займет в N раз больше времени уже не канает.
2) порядок имеет значение
3) природа, т.е. количество и распределения поступающих данных хз какая и иих еще надо постоянно вставлять/удалять
то хэш-таблицы использовать неприемлемо, есть куда более замечательные деревья, которые всегда дают O(N*logN).
Это все косяки менеджмента, причем ползучие.
Например давно-давно был у меня пространный случай: Меня 2 часа опрашивали по книги Рихтера, т.е.
1) Да реально последовательно перебирали оглавление книги. Зачем? Почему именно Рихтер?
2)Да. Вообще я шел не на .NET погроммиста. Шел я на того, кого обычно называют Algorithm Engineer. ИМХО тут все же должны быть акцент явно не на вопросы по конкретной технологии, конкретного языка.
3) Потом уже, я случайно наткнулся на собеседовавшего в LinkedIn: Забавно, но на тот момент это было первое его место работы, причем работал там он меньше года, вообще чувак оказался заметно младше, но уже Сениор, но вскоре ушел, причем он вообще за все это время нигде больше года не задерживался и везде Сениор.
Вообще это все странно выглядит, вот прям все: Скороспелые сениоры сразу после универа, текучка (ну вот не отпускают просто так ведущих сотрудников), странные собеседования. При этом конторы вообще-то не Рога и Копыта
А. Ну да. Есть такой подход. Тут только вопрос как правильно задачки формулировать.
Вот когда мне представлялась возможность подбирать людей — всегда ходил по пути наименьшего сопротивления — если для погромистов, то это набор задачек на обход графа, кластеризацию или даже преобразование Фурье, которые надо реализовать в задании (дистанционно) где на вход программы подается А, а на выходе получается В, а дальше как хотите — полная свобода действий. Например, достаточно стандартная задача для программиста, который учился именно на программиста: Найти кратчайший путь из точки А в точку В. Ну понятное дело обычно там идут алгоритмы Дейкстры, алгоритм Ли и А*. Но вот присылали, например, реализацию с использование Q-learning или например с возможностью использовать разные метрики: Евклидовое расстояние или манхэтенноское. Ну и да, стиль программирования и оформление кода не менее важен.
Для не совсем погромистов — ну там другие люди примерно по тому же принципу составляли, собственно я так сам и устраивался: Решал тестовые задачи.
Есть еще один кстати момент. Много раз доводилось работать с людьми, которые, мягко говоря… эээ… интроверты. В общем устные беседы таким людям даются тяжело, хотя вообще-то они оказываются крутыми специалистами
Если честно я уже чего только не видел, особенно на этих многоуровневых собеседованиях. На люки, например, натыкался несколько на точно, при этом я видел в живую треугольные люки :-) Гномы какие-то попадались, просили возвести 2 в 32 степени, мыши какие-то.
Или например после долгого скрининга по всяким регуляризациям в методах оптимизации или там хитрым вопросам по ML, на следующем этапе всплывали ВНЕЗАПНО например контейнеры C++ или еще какая фигня (например, потому что такое было в нескольких местах, и внезапно потому что… ну потому что внезапно).
Так шо я даже хз. Я уже перестал понимать логику современного рекрутинга.
Вообще на тему рекрутинга мериканцы исписали тонны макулатуры в научных журналах.
Я даже по памяти попытаюсь вспомнить, какие методы самые надежные:
1) Тест на IQ или GMA,
2) Тест на лояльность (как бы грустно это не было, но это так)
3) Выполнение практических тестовых задач
4) Структурированное интервью
В общем умение по памяти на литрчке записать алгоритм Дейкстры сюда не входит, хотя его и можно впихнуть в структурированное интервью, вот только корреляция эффективности работы и успешность в прохождении теста на IQ будет все равно выше, а он как известно не требует наличия специальных знаний: Кружочки, квадратики, циферки да буковки.
Тут просто надо уяснить, что вопросы про бинарные деревья не более чем тест на эрудицию и хорошую память — это конечно навыки полезные, также как и умение разбивать головой бутылки и решать на скорость олимпиадные задачки, но далеко не ключевые.
Меня когда напрягают "прособеседовать" — то я принимаю решение исключительно по выполнению тестовых домашних заданий, которые отправляю еще до того как увижу человека вживую. Собственно у нас в конторе это итак основной подход (по крайней мере в моем департаменте).
А спрашивать определение ппроизводной или чем отличается стринг от стирнгбилдера человека с диплом и опытом работы как-то стремно это ИМХО, вроде как не на экзамене в университете/на курсах. Я бы сказал, что даже неэтично.
Ну я думаю формальное знание интеграла не является достаточным условием спасения от того что решение разойдется.
А самое главное — Вы никак не проверите: Знает он или не знает с помощью листочка и ручки за 15 минут.
Тем более интегралов много, а численных способов еще больше: Чего спрашивать то надо? Я вот и не вспомню формулу Симпсона — она мне просто не нужна, у меня последнее время сплошное Монте-Карло, а формулу трапеций мне кажется практически любой сможет вывести на обывательском уровне.
Ну т.е. глубину Вы никак проверить не сможете, в лучшем случае только по верхам пройтись сможете, но это ничего не гарантирует.
Ну мне кажется, что разрывные функции должны как минимум быть интегрируемыми по Лебегу, даже такие, как функция Дирихле, например, а некоторые из них вполне себе будут интегрируемы по Риману на сегменте. Но вообще IRL все задачи невыпуклые, а все функции разрывные, так что в любом случае будет грустно и все будут лажать :-)