Русский
Русский
English
Статистика
Реклама

Симулятор

Управляемость транспортного средства в симуляторе настраиваем коэффициенты модели

18.01.2021 22:06:54 | Автор: admin


Геймплей симулятора транспортного средства управление движением транспортного средства в пространстве с некоторым количеством степеней свободы. Действия игрока изменяют вектор мгновенного состояния системы в желаемом или не совсем желаемом направлении. Игра вряд ли сможет быть интересной, если объект слабо приспособлен к управлению игроком.

Приспособленность технической системы к управлению человеком (управляемость) довольно сложная и многогранная характеристика. Математической моделью поведения управляемого объекта занимается теория автоматического управления (ТАУ). Модели, принятые в ТАУ, могут описывать и поведение игрока человека-оператора, и поведение системы человек-машина.

Стоит отметить, что создаваемые модели человека всегда актуальны для ограниченного набора условий. По этой причине решение практических задач в области управляемости часто выходит за рамки ТАУ.

Управляемость машины относится к ее эргономическим свойствам, теряющим смысл в отрыве от контекста деятельности человека. Под катом представлен подход к настройке модели симулятора, основанный на экспериментальном исследовании процесса игры.

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

Оставляя в стороне задачу имитации реального объекта с заданным набором характеристик, отметим, что симулятор наверняка не проиграет от наличия субъективно определяемой физичности. Другими словами, даже объект, не существующий в природе, может соответствовать или не соответствовать ожиданиям игрока относительно его (объекта) поведения. Фактор естественности поведения объекта должен быть принят во внимание.

Постановка задачи


Для симулятора необходимо настроить коэффициенты математической модели транспортного средства так, чтобы обеспечивалась его наилучшая управляемость. Оптимизация должна выполняться на основе экспериментальных данных. Желательно получить модель, кажущуюся игроку естественной.

Описание системы


В экспериментах будем использовать симулятор с 3D-графикой.

Сложность математической модели реального транспортного средства ограничивается лишь принятым уровнем абстракции и грубостью используемых допущений. Сложность модели в решаемой здесь задаче определяется рациональным уровнем естественности игры.

Ниже будут применены следующие упрощения:

1. Направление движения объекта принимается совпадающим с его продольной осью.

2. Вращательное движение объекта может рассматриваться как сумма независимых составляющих вращательных движений относительно трех осей связанной с объектом системы координат (ССК).

3. Угловое ускорение в отдельном канале управления (вокруг отдельной оси ССК) определяется линейной комбинацией текущих значений управляющего действия и угловой скорости в этом канале.

Приемлемость первого упрощения в моделировании реальных объектов определяется свойствами системы и решаемой задачей. Например, общеизвестным свойством дротиков является их способность лететь после броска острием вперед. Этой простой модели достаточно, чтобы получить полезный вывод: не стоит подбрасывать дротик вверх над собой.



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

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

П. 2 устанавливает взаимную изолированность каналов управления, прикрепленных к осям ССК.



Оси ССК: продольная (X) направлена от хвоста к носу объекта, вертикальная (Y) направлена в плоскости симметрии объекта вверх при его начальном положении, боковая (Z) направлена перпендикулярно первым двум вправо. Соответственно, вращение вокруг оси X боковой канал, вокруг оси Y путевой канал, вокруг оси Z продольный канал.

В соответствии с п. 2 принятых упрощений между каналами управления объектом отсутствуют перекрестные связи. Реальные системы всегда соответствуют такой модели с некоторой ошибкой, обусловленной, например, наличием гироскопических моментов. Отсутствие перекрестных связей является преимуществом с точки зрения игрока.

П. 3 устанавливает наличие только двух крутящих моментов в каждом канале управления:

  • управляющий момент, пропорциональный сигналу от управления игрока;
  • момент демпфирования, пропорциональный текущей угловой скорости.

Дифференциальное уравнение вращения вокруг оси i выглядит следующим образом:



Здесь омега угловая скорость вращения, t время, x управляющий сигнал, а коэффициенты в правой части уравнения частные производные углового ускорения по управляющему сигналу и угловой скорости.

Первый коэффициент будем называть коэффициентом эффективности управления, второй коэффициентом демпфирования.

Угловое ускорение измеряется в [рад/с2], угловая скорость в [рад/с]. Управляющий сигнал обычно измеряется в единицах перемещения рычагов или усилий на них, реже в единицах положения промежуточных элементов системы управления, но для управления с клавиатуры примем эту величину безразмерной. Размерность коэффициента демпфирования [1/c], а коэффициента эффективности управления [рад/с2] с учетом принятой размерности управляющего сигнала.

Необходимые теоретические сведения
Система, описываемая уравнением (1), с точки зрения ТАУ является апериодическим звеном первого порядка. Ниже рассмотрим альтернативный набор параметров, определяющих свойства такого динамического звена. Роль всех параметров в поведении объекта оценим с помощью нескольких характеристик, принятых в ТАУ:

  • переходной функции;
  • амплитудной частотной характеристики (АЧХ);
  • фазовой частотной характеристики (ФЧХ).

Входной сигнал звена в уравнении (1) x, выходной угловая скорость. В стандартном виде уравнение апериодического звена первого порядка записывается следующим образом:



Здесь х(t) входной сигнал, y(t) выходной сигнал, точка над y производная по времени, k коэффициент усиления звена, T постоянная времени, характеризующая инерционность звена.

Сопоставление уравнений (1) и (2) приводит к следующим соотношениям:





Рассмотрим переходную функцию (переходный процесс) системы, описывающую ее реакцию на ступенчатый входной сигнал в виде функции Хевисайда. Значение такого сигнала равно нулю для отрицательных значений аргумента (времени) и единице для неотрицательных. Переходная функция зависимость от времени выходного сигнала.



Переходный процесс апериодического звена первого порядка описывается следующим уравнением:



Уравнение демонстрирует роли коэффициентов:

  • k соответствует установившемуся значению выходного сигнала;
  • T оправдывает название постоянная времени, например, за время t = 3T выходной сигнал достигает уровня 0,95k.

Переходному процессу можно дать следующее неформальное описание:

1. В начальный момент времени ускорение достигает максимального уровня (равно коэффициенту эффективности управления), скорость не успела получить приращения, и демпфирование на систему не влияет.

2. Скорость растет, рост скорости влечет за собой рост влияния демпфирования, суммарное ускорение снижается.

3. Демпфирование асимптотически приближается по своему уровню к управляющему действию, соответственно, ускорение становится пренебрежимо малым, а скорость приближается к значению коэффициента k.



Таким образом, ступенчатый входной сигнал управления приводит к плавному нарастанию угловой скорости до некоторого уровня. Достигаемое значение и плавность нарастания зависят от величин k и T.

Частотные характеристики описывают реакцию системы на входной сигнал в виде гармонических колебаний. АЧХ и ФЧХ являются функциями частоты входного сигнала.

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

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

Если входной сигнал имеет форму гармонических колебаний, то с изменением их частоты у выходного сигнала изменится не только частота колебаний, но и их амплитуда. Изменится и сдвиг фазы между колебаниями входного и выходного сигналов.




При заданной частоте входного сигнала значение АЧХ соответствует амплитуде установившихся колебаний выходного сигнала, отнесенной к амплитуде колебаний входного сигнала. Значение ФЧХ равно сдвигу фазы колебаний выходного сигнала относительно колебаний входного.

Значение АЧХ апериодического звена первого порядка при отсутствии колебаний (значение частоты равно нулю) соответствует значению k. Это свойство легко выводится из рассмотренной выше переходной характеристики.



Снижение амплитуды выходного сигнала с ростом частоты входного определяется значением T (или значением коэффициента демпфирования). Звено с меньшим значением T лучше пропускает сигнал.

ФЧХ определяется только значением коэффициента демпфирования (или T).



Фазовое отставание растет с увеличением частоты, асимптотически приближаясь к уровню минус ПИ/2. Меньшее фазовое отставание при равных частотах входа соответствует моделям с меньшими значениями T.

Частотные характеристики наглядно показывают роли коэффициента демпфирования и постоянной времени звена: слабое демпфирование (большие значения T) ведет к потере амплитуды выходного сигнала и росту его фазового отставания.

Условия эксперимента и критерии качества модели


Лучшая управляемость объекта должна обеспечивать более эффективное решение задачи игроком. Но разные задачи требуют разной управляемости: точное выдерживание параметров заданного режима движения существенно отличается от интенсивного маневрирования.

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

Для исследования будем использовать задачу посещения управляемым объектом максимального количества локаций из числа заданных за ограниченное время. Эффективное решение этой задачи требует интенсивного маневрирования.

Управление аппаратом будет осуществляться с ограничениями по углам крена и тангажа (60 градусов в обоих направлениях для обоих углов): выход за ограничения ведет к аварии. Также к аварии ведет столкновение с горизонтальной поверхностью, расположенной над объектом. Эта часть условий отвечает за составляющую выдерживания параметров в задаче игрока.

Значение модуля линейной скорости объекта принимается постоянным. Это означает, что управление акселератором, как и неравномерность сопротивления среды, в симуляторе отсутствует.

Показатель эффективности работы игрока количество локаций, посещенных до окончания времени (60 секунд) или до аварии. Чем больше посещено локаций, тем более качественной считается модель. С каждой моделью (набором значений коэффициентов) предусмотрено три прохождения игры с принятием в зачет медианного результата.

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

A, B, C N, O,
A, B, C N, O,
A, B, C N, O
.

Каждому экспериментальному прохождению предшествовала одна тренировочная игра с соответствующей моделью.

Симулятор


Экспериментировать с коэффициентами модели самостоятельно можно здесь.

Управление коэффициентами находится в правом верхнем углу экрана. Параметр efficiency коэффициент эффективности управления, параметр damping коэффициент демпфирования, взятый с обратным знаком.

Управление игрой:

  • Пробел старт игры;
  • W/S вращение вокруг оси Z ССК, нос вниз/нос вверх;
  • A/D вращение вокруг оси Y ССК, поворот влево/поворот вправо;
  • 4/6 на нумпаде вращение вокруг оси X ССК, крен левый/крен правый.

На индикаторе лобового стекла игрок видит искусственный горизонт, а также текущие значения курса (heading) и глубины (depth), то есть расстояния до опасной поверхности. Также показывается остаток времени игры и текущий результат (score) количество посещенных локаций.

Код симулятора написан на JavaScript с применением библиотеки Three.js. Значения параметров движения объекта обновляются в игровом цикле численным интегрированием уравнения (1) по методу Эйлера. В каждой итерации вызывается метод update() объекта vehicle, выполняющий вычисления для каждого канала управления:

vehicle.update = function () {    //определение интервала времени в секундах:    game.elapsed = (new Date() - game.time) / 1000;    game.time = new Date();    //другие действия...    //обновление значений угловой скорости в радианах в секунду:    vehicle.omegaX += (vehicle.epsilonX - vehicle.omegaX * vehicle.damping) * game.elapsed;    vehicle.omegaY += (vehicle.epsilonY - vehicle.omegaY * vehicle.damping) * game.elapsed;    vehicle.omegaZ += (vehicle.epsilonZ - vehicle.omegaZ * vehicle.damping) * game.elapsed;    //другие действия...}

Поля epsilonX, epsilonY и epsilonZ объекта vehicle содержат составляющие углового ускорения при отсутствии демпфирования. Значение каждого из этих полей получается умножением входного сигнала на коэффициент эффективности управления:

function init() {    //другие действия...    //ввод с клавиатуры:    document.addEventListener('keydown', function (event) {        if (game.state == "READINESS")            if (event.code == "Space") {                //запуск игры...            }        if (game.state == "RUN")            switch (event.code) {                case "KeyW":                    vehicle.epsilonZ = vehicle.efficiency;                    break;                case "KeyS":                    vehicle.epsilonZ = -vehicle.efficiency;                    break;                case "KeyA":                    vehicle.epsilonY = -vehicle.efficiency;                    break;                case "KeyD":                    vehicle.epsilonY = vehicle.efficiency;                    break;                case "Numpad4":                    vehicle.epsilonX = vehicle.efficiency;                    break;                case "Numpad6":                    vehicle.epsilonX = -vehicle.efficiency;                    break;            }    });    document.addEventListener('keyup', function (event) {        switch (event.code) {            case "KeyW":                vehicle.epsilonZ = 0;                break;            case "KeyS":                vehicle.epsilonZ = 0;                break;            case "KeyA":                vehicle.epsilonY = 0;                break;            case "KeyD":                vehicle.epsilonY = 0;                break;            case "Numpad4":                vehicle.epsilonX = 0;                break;            case "Numpad6":                vehicle.epsilonX = 0;                break;        }    });    //другие действия...}

Результаты эксперимента


Показатель качества модели будем рассматривать как функцию двух переменных. Соответственно, результаты исследования в графическом виде представляют собой 3D-поверхность, каждая точка которой определяет свою модель управляемого объекта.



Рассмотрим ключевые особенности некоторых моделей. На графике обсуждаемые модели обозначены латинскими буквами.

При минимальном значении коэффициента эффективности управления (0,5 рад/с2) существует модель с наилучшим значением коэффициента демпфирования (точка А). Модель А характеризуется слабой способностью объекта к динамичным маневрам.

Изменение модели А в сторону усиления демпфирования приводит к созданию моделей, имеющих крайне низкие максимальные значения угловой скорости. Объект окончательно теряет способность к маневрированию.

Изменение модели А в сторону снижения демпфирования частично улучшает маневренность объекта, но общее качество системы падает за счет ухудшения ее динамических свойств: возникает проблема раскачки, управление требует от игрока постоянных компенсирующих действий.

При отсутствии демпфирования существует модель с оптимальной эффективностью управления (В). Ее эффективность управления выше, чем у модели А, что обеспечивает хорошую маневренность. При этом проблема раскачки усугубляется по сравнению с моделью А, полностью лишенной демпфирования.

Изменение модели B в сторону повышения эффективности управления доводит проблему раскачки до уровня, когда борьбе с ней уделено все внимание игрока. Далее маневрирование без выхода за ограничения становится невозможным.

Модель C объединяет достоинства моделей A и B. Объект управляется достаточно эффективно, но без раскачки. Значение показателя результативности игры у модели C заметно выше, чем у предыдущих моделей. Тем не менее, эта модель не является наиболее результативной.

Форма изолиний результативности игры в окрестностях точки C показывает, что улучшению результата соответствует движение в направлении модели D.

Это движение соответствует снижению значения T при сохранении k на постоянном уровне (около 0,6 рад/с). Модели, расположенные между C и D, превосходят C по результативности игры. В игре с этими моделями объект управления более четко следует нажатиям клавиш.

При движении от модели C к модели D происходит еще одно изменение: ухудшение естественности поведения объекта. Постоянная времени приближается к уровню, при котором длительность переходного процесса и сдвиг фазы выходного сигнала перестают быть заметными для пользователя.

Изменение модели D в сторону дальнейшего снижения значения T при сохранении значения k уже не дает существенных улучшений, потому что сдвиг фазы выходного сигнала и длительность переходного процесса у модели D и без того достаточно малы для восприятия игрока.

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

Проведенный анализ позволяет сделать следующие выводы:

1. Оптимальные значения параметров модели соответствуют ее вырождению в усилительное звено (значение k составляет около 0,6 рад/с, T = 0 с) и потере естественности поведения объекта.

2. Модель, обеспечивающая хорошую управляемость при естественном поведении объекта, соответствует точке C на графике (коэффициент эффективности управления: от 2 до 3 рад/с2; коэффициент демпфирования: от -4,5 до -3,5 1/с).

3. Изменение модели C в направлении снижения значения T при k = const позволяет получить объект с улучшенной управляемостью за счет ухудшения естественности его поведения.

Неучтенные факторы


Вместе с упрощениями физики управляемого объекта на качество результатов исследования влияют и другие упрощения условий исследования:

1. Модель управляемости описывалась двумя значениями параметров, во всех каналах управления объект вел себя одинаково. Для получения точной картины следует варьировать значения шести параметров, поскольку нет оснований считать свойства игрока одинаковыми для всех каналов.

2. Полученные результаты актуальны для настроек поля зрения камеры, используемых в игре. Изменение этого параметра окажет заметное влияние на взаимодействие игрока с объектом.

Наиболее серьезный недостаток исследования отсутствие статистики. Любое эргономическое исследование должно ориентироваться на свойства целевой аудитории в целом. Более полные результаты могут быть получены при участии группы игроков.
Подробнее..

Как я делал систему оптического трекинга

20.01.2021 20:22:57 | Автор: admin

Дело было в далеком 2015 году. В продаже только появились очки виртуальной реальности Oculus DK2, рынок VR игр быстро набирал популярность.

Возможности игрока в таких играх были невелики. Отслеживалось всего 6 степеней свободы движений головы вращение (инерциалкой в очках) и перемещение в маленьком объеме в зоне видимости инфракрасной камеры, закрепленной на мониторе. Процесс игры представлял собой сидение на стуле с геймпадом в руках, вращение головой в разные стороны и борьбу с тошнотой.

Звучало не очень круто, но я увидел в этом возможность сделать что-то интересное, используя свой опыт в разработке электроники и жажду новых проектов. Как можно было эту систему улучшить?

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

Видел я это так:

  1. Берем несколько игроков, надеваем на них VR очки, ноутбук и датчики на руки, ноги и туловище.
  2. Берем помещение, состоящее из нескольких комнат, коридоров, дверей, оборудуем его системой трекинга, вешаем датчики и магнитные замки на двери, добавляем несколько интерактивных предметов и создаем игру, в которой геометрия виртуальной локации точно повторяет геометрию реального помещения.
  3. Создаем игру. Игра представляет собой многопользовательский квест, в котором несколько игроков надевают на себя оборудование и оказываются в виртуальном мире. В нем они видят себя, видят друг друга, могут ходить по локации, открывать двери и совместно решать игровые задачи.

Эту идею я рассказал своему товарищу, который неожиданно воспринял ее с большим энтузиазмом и предложил взять на себя организационные вопросы. Так мы решили мутить стартап.

Для реализации заявленного функционала, нужно было создать две основные технологии:

  1. костюм, состоящий из датчиков на руках, ногах и торсе, отслеживающий положения частей тела игрока
  2. система трекинга, отслеживающая игроков и интерактивные объекты в 3D пространстве.

Про разработку второй технологии и пойдет речь в этой статье. Может быть, позже напишу и про первую.

Система трекинга.


Бюджета на все это, конечно, у нас не было, поэтому нужно было сделать все из подручных материалов. Для задачи отслеживания игроков в пространстве я решил использовать оптические камеры и светодиодные маркеры, закрепленные на VR очках. Опыта подобных разработок у меня не было, но я уже что-то слышал про OpenCV, Python, и подумал, что справлюсь.

По задумке, если система знает где расположена камера и как она ориентирована, то по положению изображения маркера на кадре можно определить прямую в 3D пространстве, на которой этот маркер находится. Пересечение двух таких прямых дает итоговое положение маркера.



Соответственно, камеры нужно было закрепить на потолке так, чтобы каждая точка пространства просматривалась минимум двумя камерами (лучше больше, чтобы избежать перекрытия обзора телами игроков). Для покрытия трекингом предполагаемого помещения площадью около 100 кв.м., требовалось около 60 камер. Я выбрал первые попавшиеся дешевые на тот момент usb вебки.



Эти вебки нужно к чему-то подключать. Эксперименты показали, что при использовании usb удлинителей (по крайней мере, дешевых), камеры начинали глючить. Поэтому решил разделить вебки на группы по 8 штук и втыкать их в системники, закрепленные на потолке. На моем домашнем компе как раз было 10 usb портов, так что пришло время начинать разработку тестового стенда.

Архитектуру я придумал следующую:
На каждые очки вешается акриловый матовый шарик от гирлянды с вклеенным внутрь RGB светодиодом. Одновременно в игре предполагалось несколько игроков, так что для идентификации решил разделять их по цвету R, G, B, RG, RB, GB, RB. Вот так это выглядело:



Первая задача, которую нужно выполнить написать программу поиска шарика на кадре.

Поиск шарика на кадре

Мне нужно было в каждом кадре, пришедшем с камеры, искать координаты центра шарика и его цвет для идентификации. Звучит несложно. Качаю OpenCV под Python, втыкаю камеру в usb, пишу скрипт. Для минимизации влияния лишних объектов на кадре, выставляю экспозицию и выдержку на камере в самый минимум, а яркость светодиода делаю высокой, чтобы получить яркие пятна на темном фоне. В первой версии алгоритм был следующий:

  1. Переводим изображение в градации серого
  2. Бинаризуем по порогу (если яркость пикселя больше порога, он становится белым, иначе черным). При этом размытое пятно от шарика превращается в кластер белых пикселей на черном фоне
  3. Находим контуры кластеров и их центры. Это и есть координаты шарика на кадре
  4. Определяем усредненный цвет пикселей кластера (на исходном цветном изображении) в окрестности его центра для идентификации




Вроде, работает, но есть нюансы.

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

Во-вторых, разрешение камеры всего лишь 640*480, поэтому на некотором расстоянии (не очень большом) шарик виден как пара пикселей на кадре и алгоритм поиска контуров перестает нормально работать.

Пришлось придумывать новый алгоритм. В голову пришла следующая идея:

  1. Переводим изображение в градации серого
  2. Размываем картинку мощным Gaussian blur ом так, чтобы изображения светодиодов превратились в размытые пятна с градиентом яркости от центра к периферии
  3. Находим самые яркие пиксели на изображении, они должны соответствовать центрам пятен
  4. Так же определяем средний цвет кластера в окрестности центра


Так работает гораздо лучше, координаты центра при неподвижном шарике неподвижны, и работает даже при большом расстоянии от камеры.

Чтобы убедиться, что все это будет работать с 8-ю камерами на одном компе, нужно провести нагрузочный тест.

Нагрузочный тест

Подключаю 8 камер к своему десктопу, располагаю их так, чтобы каждая видела светящиеся точки и запускаю скрипт, где описанный алгоритм работает в 8-ми независимых процессах (спасибо питонской либе multiprocessing) и обрабатывает все потоки сразу.

И сразу натыкаюсь на фейл. Изображения с камер то появляются, то исчезают, framerate скачет от 0 до 100, кошмар. Расследование показало, что часть usb портов на моем компе подключены к одной шине через внутренний хаб, из-за чего скорость шины делится между несколькими портами и ее уже не хватает на битрейт камер. Втыкание камер в разные порты компа в разных комбинациях показало, что у меня всего 4 независимых usb шины. Пришлось найти материнку с 8-ю шинами, что было довольно непростым квестом.

Спойлер
Подошли материнки с чипсетом Intel B85, в них поддерживается аж 10 usb шин. Но для работы с 10-ю камерами, нужно перекомпилить OpenCV, т.к. в нем захардкожено ограничение на 8 источников видеосигнала (совпадение?)

Продолжаю нагрузочный тест. На этот раз все камеры подключились и выдают нормальные потоки, но сразу сталкиваюсь со следующей проблемой низкий fps. Процессор загружен на 100% и успевает обрабатывать лишь 8-10 кадров в секунду с каждой из восьми вебок.



Похоже, нужно оптимизировать код. Узким местом оказалось Гауссово размытие (оно и не удивительно, ведь нужно на каждый пиксель кадра производить свертку с матрицей 9*9). Уменьшение ядра не спасало ситуацию. Пришлось искать другой метод нахождения центров пятен на кадрах.

Решение удалось найти внезапно во встроенной в OpenCV функции SimpleBlobDetector. Она делает прямо то, что мне нужно и очень быстро. Преимущество достигается благодаря последовательной бинаризации изображения с разными порогами и поиску контуров. Результат максимальные 30 fps при загрузке процессора меньше 40%. Нагрузочный тест пройден!

Классификация по цвету

Следующая задача классификация маркера по его цвету. Усредненное значение цвета по пикселям пятна дает RGB компоненты, которые очень нестабильны и сильно меняются в зависимости от расстояния до камеры и яркости светодиода. Но есть отличное решение: перевод из RGB пространства с HSV (hue, saturation, value). В таком представлении пиксель вместо красный, синий, зеленый, раскладывается на компоненты тон, насыщенность, яркость. В этом случае насыщенность и яркость можно просто исключить и классифицировать только по тону.



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

Алгоритм такой:
  1. Указываю цвет маркера (например, R красный) и запускаю режим накопления
  2. Беру в руку соответствующий маркер и хаотично вожу им перед камерой, приближаю, отдаляю и тд. Параллельно наблюдаю как на интерфейсе на двумерном графике hue saturation появляются точки
  3. Завершаю режим накопления. Указываю следующий цвет маркера, прохожу еще одно накопление и так далее для каждого цвета.
  4. Вижу, как разноцветные точки на графике разбиты по кластерам, но эти кластеры немного пересекаются. Расстраиваюсь. Запускаю линейную регрессию, в процессе которой программа рассчитывает уравнения прямых, разделяющих кластеры наилучшим образом. Но т.к. облака точек пересекаются, толку с этих уравнений было мало. Понял, что по-модному сделать не получится, поэтому просто вручную на глаз разделил пространство на части вертикальными линиями и в области пересечений сделал мертвые зоны, где неопределившиеся точки будут просто игнорироваться.




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

Трекинг


Я использовал pinhole модель камеры, в которой все лучи падают на матрицу через точку, находящуюся на фокусном расстоянии от матрицы.



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

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

Калибровка трекинга

В первом варианте решил сделать калибровку трекинга максимально примитивной.

  1. Вешаю первый блок из восьми камер на потолок, подключаю их к системнику, висящему там же, направляю камеры так, чтобы ими покрывался максимальный игровой объем.
  2. С помощью лазерного нивелира и дальномера измеряю XYZ координаты всех камер в единой системе координат
  3. Для вычисления ориентаций и фокусных расстояний камер, измеряю координаты специальных стикеров. Стикеры вешаю следующим образом:
    • В интерфейсе отображения картинки с камеры рисую две точки. Одну в центре кадра, другую в 200 пикселях справа от центра
    • Если смотреть на кадр, эти точки падают куда-то на стену, пол или любой другой объект внутри помещения. Вешаю в соответствующие места бумажные наклейки и рисую на них точки маркером
    • Измеряю XYZ координаты этих точек с помощью тех же нивелира и дальномера. Итого для блока из восьми камер нужно измерить координаты самих камер и еще по две точки на каждую. Т.е. 24 тройки координат. А таких блоков должно быть около десяти. Получается долгая муторная работа. Но ничего, позже сделаю калибровку автоматизированной.
    • Запускаю процесс расчета на основе измеренных данных


Есть две системы координат: одна глобальная, связанная с помещением, другая локальная для каждой камеры. В моем алгоритме результатом для каждой камеры должна получиться матрица 4*4, содержащая ее местоположение и ориентацию, позволяющая преобразовать координаты из локальной в глобальную систему.



Идея следующая:

  1. Берем исходную матрицу с нулевыми поворотами и смещением.
  2. Берем единичный вектор в локальной системе камеры, который смотрит из объектива вперед и преобразуем его в глобальные координаты по исходной матрице.
  3. Берем другой вектор в глобальной системе, который из камеры смотрит на центральную точку на стене.
  4. С помощью градиентного спуска поворачиваем исходную матрицу так, чтобы после преобразования эти векторы были сонаправлены. Таким образом, мы зафиксировали направление камеры. Осталось зафиксировать вращение вокруг этого направления. Для этого и измерялась вторая точка в 200 пикселях от центра кадра. Поворачиваем матрицу вокруг главной оси, пока два вектора не станут достаточно параллельны.
  5. По расстоянию между этими двумя точками вычисляю фокусное расстояния в пикселях (учитывая, что расстояние между проекциями этих точек на кадре составляет 200 пикселей).

Наверняка эту задачу можно было решить аналитически, но для простоты я использовал численное решение на градиентном спуске. Это не страшно, т.к. вычисления будут проводиться один раз после монтажа камер.

Для визуализации результатов калибровки я сделал 2D интерфейс с картой, на которой скрипт рисует метки камер и направления, в которых они видят маркеры. Треугольником обозначаются ориентации камер и углы обзора.



Тестирование трекинга

Можно приступать к запуску визуализации, которая покажет правильно ли определились ориентации камер и правильно ли интерпретируются кадры. В идеале, линии, идущие из значков камер должны пересекаться в одной точке.

Вот что вышло:


Похоже на правду, но точность явно могла быть выше. Первая причина несовершенства, которая пришла в голову искажения в объективах камер. Значит, нужно эти искажения как-то компенсировать.

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



Результатом калибровки является матрица, содержащая фокусные расстояния по двум осям и смещение матрицы относительно оптического центра. Все это измеряется в пикселях.



А также вектор коэффициентов дисторсии



который позволяет компенсировать искажения объектива с помощью преобразований координат пикселей.

Применяя преобразования с этими коэффициентами к координатам маркера на кадре, можно привести систему к модели идеальной pinhole камеры.

Провожу новый тест трекинга:



Уже гораздо лучше! Выглядит настолько хорошо, что даже вроде будет работать.

Но процесс калибровки выходит очень муторным: напрямую измерить координаты каждой камеры, запустить отображение картинки с каждой камеры, повесить наклейки, измерить координаты каждой наклейки, записать результаты в таблицу, откалибровать объективы. Все это занимало пару дней и килограмм нервов. Решил разобраться с трекингом и написать что-то более автоматизированное.

Вычисление координат маркера

И так, я получил кучу прямых, разбросанных по пространству, на пересечениях которых должны находиться маркеры. Только вот прямые в пространстве на самом деле не пересекаются, а скрещиваются, т.е. проходят на некотором расстоянии друг от друга. Моя задача найти точку, максимально близкую к обеим прямым. Формально говоря, нужно найти середину отрезка, являющегося перпендикуляром к обеим прямым.



Длина отрезка AB тоже пригодится, т.к. она отражает качество полученного результата. Чем он короче, тем ближе друг к другу прямые, тем лучше результат.

Затем я написал алгоритм трекинга, который попарно вычисляет пересечения прямых (внутри одного цвета, от камер, находящихся на достаточном расстоянии друг от друга), ищет лучшее и использует его как координаты маркера. На следующих кадрах старается использовать ту же пару камер, чтобы избежать скачка координат при переходе на трекинг другими камерами.

Параллельно, при разработке костюма с датчиками, я обнаружил странное явление. Все датчики показывали разные значения угла рысканья (направления в горизонтальной плоскости), как будто у каждого был свой север. В первую очередь полез проверять не ошибся ли я в алгоритмах фильтрации данных или в разводке платы, но ничего не нашел. Потом решил посмотреть на сырые данные магнитометра и увидел проблему.
Магнитное поле в нашем помещении было направлено ВЕРТИКАЛЬНО ВНИЗ! Видимо, это связано с железом в конструкции здания.

Но ведь в VR очках тоже используется магнитометр. Почему у них такого эффекта нет? Иду проверять. Оказалось, что в очках он тоже есть Если сидеть неподвижно, можно заметить, как виртуальный мир медленно, но верно вращается вокруг тебя в рандомную сторону. За минут 10 он уезжает почти на 180 градусов. В нашей игре это неминуемо приведет к рассинхрону виртуальной и реальной реальностей и сломанным об стены очкам.

Похоже, что помимо координат очков, придется определять и их направление в горизонтальной плоскости. Решение напрашивается само ставить на очки не один, а два одинаковых маркера. Оно позволит определять направление с точностью до разворота на 180 градусов, но с учетом наличия встроенных инерциальных датчиков, этого вполне достаточно.



Система в целом работала, хоть и с небольшими косяками. Но было принято решение запустить квест, который как раз был близок к завершению нашим gamedev разработчиком, присоединившимся к нашей миникоманде. Была затречена вся игровая площадь, установлены двери с датчиками и магнитными замками, изготовлено два интерактивных предмета:



Игроки надевали очки, костюмы и рюкзаки-компьютеры и заходили в игровую зону. Координаты трекинга отсылались им по wi-fi и применялись для позиционирования виртуального персонажа. Все работало достаточно неплохо, посетители довольны. Приятнее всего было наблюдать ужас и крики особо впечатлительных посетителей в моменты, когда на них из темноты нападали виртуальные призраки =)



Масштабирование


Внезапно нам прилетел заказ на большой VR шутер на 8 игроков с автоматами в руках. А это 16 объектов, которые нужно тречить. Повезло, что сценарий предполагал возможность разделения трекинга на две зоны по 4 игрока, поэтому я решил, что проблем не будет, можно принимать заказ и ни о чем не волноваться. Протестировать систему в домашних условиях было невозможно, т.к. требовалась большая площадь и много оборудования, которое будет куплено заказчиком, поэтому до монтажа я решил потратить время на автоматизацию калибровки трекинга.

Автокалибровка

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

Первым делом нужно было централизовать всю систему. Вместо разделения игровой зоны на блоки по 8 камер, я сделал единый сервер, на который приходили координаты точек на кадрах всех камер сразу.

Идея следующая:

  1. вешаю камеры и на глаз направляю их в игровую область
  2. запускаю режим записи на сервере, в котором все приходящие с камер 2D точки сохраняются в файл
  3. хожу по темной игровой локации с маркером в руках
  4. останавливаю запись и запускаю расчет калибровочных данных, при котором вычисляются расположения, ориентации и фокусные расстояния всех камер.
  5. в результате предыдущего пункта получается единое пространство, наполненное камерами. Т.к. это пространство не привязано к реальным координатам, оно имеет случайное смещение и поворот, которое я вычитаю вручную.

Пришлось перелопатить огромное количество материала по линейной алгебре и написать многие сотни строк питонского кода. Настолько много, что я уже почти не помню как оно работает.





Вот так выглядит напечатанная на принтере специальная палка-калибровалка.

Тестирование большого проекта


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

Когда уровень кортизола в крови превысил теоретический максимум, я решил посмотреть на проблему с другой стороны. Как можно сократить количество разноцветных точек, не сокращая количество маркеров? Сделать трекинг активным. Пускай у каждого игрока, например, левый рог всегда корит красным. А второй иногда загорается зеленым по приходу команды с сервера так, что в один момент времени он горит только у одного игрока. Получается, что зеленая лампочка будет как-будто перепрыгивать с одного игрока на другого, обновляя привязку трекинга к красной лампочке и обнуляя ошибку ориентации магнитометра.

Для этого пришлось бежать в ближайший чипидип, покупать светодиоды, провода, транзисторы, паяльник, изоленту и на соплях навешивать функционал управления светодиодами на плату костюма, которая на это рассчитана не была. Хорошо, что при разводке платы я на всякий случай повесил пару свободных ног stm-ки на контактные площадки.



Алгоритмы трекинга пришлось заметно усложнить, но в итоге все заработало! Телепортации игроков друг в друга исчезли, нагрузка на процессор упала, засветки перестали мешать.


Проект был успешно запущен, первым делом я сделал новые платы костюмов с поддержкой активного трекинга, и мы произвели обновление оборудования.



Чем все закончилось?


За 3 года мы открыли множество развлекательных точек по всему миру, но коронавирус внес свои коррективы, что дало нам возможность сменить направление работы в более общественно-полезную сторону. Теперь мы довольно успешно занимаемся разработкой медицинских симуляторов в VR. Команда у нас все еще маленькая и мы активно стремимся расширять штат. Если среди читателей Хабра есть опытные разработчики под UE4, ищущие работу, пожалуйста, напишите мне.



Традиционный забавный момент в конце статьи:


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



Система в прямом смысле работала через задницу.
Подробнее..

Куда идут лучи под водой?

17.03.2021 08:06:08 | Автор: admin

В военное время значение синуса может достигать четырех

(С) Willebrord Snel van Royen, Cyclometricus, 1621

Приветствую вас, глубокоуважаемые!

Представьте, каким был бы наш мир, если бы условия распространения звука в нем были бы несколько иными. Например, иногда ваш крик был бы не слышен на расстоянии десяти метров, но становился бы вполне различим на сотне-другой и, скажем, на паре километров? А иногда, негромкий разговор или даже шепот разносился бы на километры от вас. Уверен, что пословица слово - не воробей.. - заиграла бы совершенно новыми красками!

А еще, все эти эффекты сильно зависели бы от времени года и суток, погоды и даже наклона вашей головы. Как бы нам жилось в таком мире?

К счастью, нам даже не придется напрягать воображение, потому что такой мир существует рядом с нами и сегодня я немного расскажу о нем.

Для тех, кто услышал мой шепот в современном потоке информации - добро пожаловать под кат, у нас сегодня не только ликбез и культпросвет, но модель с красивыми картинками, исходным кодом на двух языках и онлайн-симулятором, а также видео, где за 15 минут отображаются все научные морские экспедиции с 1961 по 2010 год.

Псевдопритча

Для всех нас должна быть поучительной жизнь и судьба мореплавателя Кристобаля Колона, который четырежды топтал земли нового света, пребывая в упрямой уверенности, что ступает то по благословенной индийской земле, то по беднейшей части восточного Китая. Так до самой смерти и не узнавший, что он стал первым из европейцев, кто бороздил просторы карибского и саргассова морей. Кто знает, может быть его бы и не расстроило, что на тихоокеанскую плиту наползает Северо-Американская, а не Северо-Колумбийская, но вот то, что доливкой кипятка в эспрессо получают Американо, а не Колумбиано - точно бы опечалило.

Поэтому, не то, чтобы необходимо, но исключительно важно:

  • понимать, где ты находишься

  • иметь связь, как минимум, чтобы спросить у того, кто понимает.

Конечно, Америго Веспуччи, или, по другим данным, Ричард Америке обошлись судя по всему и без этого, но это лишь делает им честь, которая на нас автоматически не экстраполируется.

Океан прекрасен, опасен и неясен.

И именно поэтому, так живучи дежурные фразы про то, что большая часть океана до сих пор не исследована, и то, что поверхность марса картирована лучше, чем поверхность земли.

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

Все задачи, которые на земле и в воздухе решаются при помощи радиоволн: GPS, радар, спутниковая связь и мобильная связь перекладываются на узкие, рахитичные плечики гидроакустики.

Кратко напомню, что глубина Бездны Челленжера (самой глубокой точки земных океанов) определена с точностью +/- 10 метров - и на сегодняшний день это все, что может современная наука.

А все потому, что скорость звука в океане не остается неизменной: она очень сильно зависит от температуры, солености и глубины. Это приводит к искривлению траектории распространения звуковых волн в вертикальной плоскости, говоря научным языком - к рефракции акустического поля. Сложная стратифицированность присуща не только океанической среде, но вполне наблюдается и в более мелких водоемах - вспомните хотя бы теплый, прогретый слой воды в речке летом.

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

Это не наш профиль

В прошлой статье мы уже познакомились с понятием профиля скорости звука: ученые непосредственно измеряют скорость звука по всей глубине, и затем интегрируют (суммируют) времена прохождения звука через слои и таким образом более точно определяют глубину.

Пару слов про источники данных. Наборы измерений CTD (температура/соленость) я брал у NOAA.

Я уже как-то рассказывал про эту кладезь и несметные сокровища в статье "Кто, как и на чем исследовал мировой океан". И было собирался написать вторую статью про эти данные, но утратил интерес. Поэтому предлагаю просто посмотреть результат работы - видео, которое в за пятнадцать минут отображает на карте 49 лет морских экспедиций с 1961 по 2010.

Примерно 20 дней в секунду. Цвет точки - температура поверхности, текущие измерения выделяются яркостью.

Профили могут быть самые разнообразные, и для иллюстрации этого я приведу пару примеров.

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

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

Лучано Поворотти (итал. Luciano Pоvоrotti) - буквально: Луч рефрагирует

Я уже упомянул о изгибании траектории звуковых волн, но давайте сначала порассуждаем на стихийно-бытовом уровне и вспомним школьные уроки физики:

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

Этот феномен описывается законом Снеллиуса, или Снелля. Он гласит, что:

Отношение синусов угла под которым волна падает на границу раздел сред и угла, под которым она покидает границу равно отношению скоростей распространения волны в этих средах.

sin \theta/sin\theta_1=c/c_1

Пока я не забыл, для нашего рассказа удобно ввести понятие луча - перпендикуляра к касательной, проведенной в какой-либо точке к фронту волны. В курсе школьной физике мы как раз и рисовали лучи. Давайте я нарисую парочку, для демонтсрации закона Снелля.

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

Вспомнить все!

Осознать закон Снелля очень просто. У нас есть два параллельных луча, которые падают на границу раздела под углом . Очевидно, что время хода второго луча на отрезке АB должно совпадать времени хода первого луча на отрезке АB - в противном случае пришлось бы принять, что они перестали быть параллельными.

Для обоих лучей это время равно отношению длины пройденного пути к скорости распространения волны:

t=A'B/c=AB'/c

Если взглянуть на два прямоугольных треугольника AAB и ABB, то окажется, что у них общая сторона AB, которую можно выразить двумя способами:

AB=A'B/sin\theta=AB'/sin\theta_1

Исключив из выражения отрезки AB и AB получаем закон Снелля, Снеллиуса или закон синусов:

sin\theta/sin\theta_1=c/c_1

Это очень глубокая штука. Я предлагаю тщательно ее обдумать, ведь фактически, волна решает оптимизационную задачу: она старается двигаться по пути наименьшего (экстремального) времени распространения. (Принцип Ферма).

Запомните это, дальше выяснится, что это приводит к неожиданным результатам.

Если вас пугают следовые количества математики, то можно смело пропустить спойлер ниже и сразу переходить к картинкам и обсуждению. Здесь же я кратко изложу, как и почему такие картинки получаются.

Лучи не боги изгибают

Детали реализации

Недавний случай из жизни

Где-то осенью 2020 года ко мне в линкедин постучался американский молодой разраб, с просьбой помочь ему с трассировкой лучей в подводе. В тот момент я не сильно интересовался темой (почему - станет понятно в конце статьи) и знал только, что качественную трассировку можно сделать винрарным приложением BELLHOP. Я вежливо отнекивался, ведь мне действительно нечем было ему помочь! Я упомянул невзначай про пресловутый BELLHOP, на что получил обескураживающий ответ: у меня не получилось запустить это приложение.

А ведь да, если просто запустить BELLHOP, то просто моргнет черное окно консоли. BELLHOP - утилита, работающая из командной строки, с кучей параметров, берущая на вход один файл и выдающая на выходе другой. По которому можно потом строить красивые картинки в Matlab.

Терпение, мы уже практически полностью вооружены всей необходимой математикой, чтобы это начать.

Нам понадобится только вспомнить совсем простое правило, что:

Угол падения равен углу отражения

И договориться о том, что мы считаем дно и поверхность воды совершенно плоским, но каждый раз, когда звук отражается ото дна или поверхности, энергия, им переносимая уменьшается определенным образом, скажем умножается на какой-нибудь коэффициент от 0 до 1.

Итак, о входных и выходных параметрах.

В качестве входных у нас будут:

  • Профиль скорости звука, как набор значений скорости звука с привязкой к глубине

  • Число лучей

  • Положение источника на оси Z (т.е. глубина)

  • Диаграмма направленности - угол, в пределах которого лучи выходят из источника

  • Интервал интегрирования по глубине

  • Максимальные значения по горизонтальной координате и длине луча - по достижении одного из этих параметров симуляция для данного луча останавливается

  • Коэффициенты отражения для дна и поверхности

С выходом все предельно понятно: мы хотим иметь траектории движения лучей. То есть последовательные наборы точек, где сопоставляются горизонтальная и вертикальные координаты, к которым можно добавить параметр, определяющий энергию луча в данной точек Напомню, в нашей упрощенной модели луч теряет энергию только при отражениях ото дна и от поверхности.

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

В проекте на C# это выполняется в методе BuildVSSP() класса Simulator.

После этого создаем список экземпляров класса Ray, каждому из которых передаем угол из заданного диапазона:

double dTheta_deg = thetaRange_deg / numRays;double theta_deg = -thetaRange_deg / 2;for (int i = 0; i < numRays; i++){   rays.Add(new Ray(Z0_m, profileZMax_m, theta_deg, GetSoundSpeed));   theta_deg += dTheta_deg;                }

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

Сама же симуляция выполняется таким образом:

bool finished = false;while (!finished){   finished = true;   foreach (var ray in rays)   {         if ((ray.XMax_m < maxX_m) && (ray.Path_m < maxPath_m))         {               ray.Step(dZ);               finished = false;          }                        }}

Сама же логика поведения луча заключена в методе Step() класса Ray, она-то и делает следующий шаг - решает каково будет следующее положение головы луча.

double z = rayPoints[rayPoints.Count - 1].Z_m;double x = rayPoints[rayPoints.Count - 1].X_m;double e = rayPoints[rayPoints.Count - 1].E;double theta_sign = Theta_rad > 0 ? 1 : -1;z += (dZ * theta_sign);if (z > ZMax_m){   if (z >= ZMax_m)   {      Theta_rad = -Theta_rad;      theta_sign = -theta_sign;      z = ZMax_m * 2 - z;      e *= EtaBottom;      // bottom reflection   }}else{   if (z <= 0)   {      Theta_rad = -Theta_rad;      theta_sign = -theta_sign;      z = -z;      e *= EtaSurface;      // surface reflection   }}            double rsn = dZ / Math.Abs(Math.Sin(Theta_rad));            double drn = Math.Sqrt(rsn * rsn - dZ * dZ);Path_m += Math.Abs(rsn);x += drn;c = getSoundSpeed(z);                        double cosTheta = Math.Cos(Theta_rad);double recipSinTheta = 1.0 / Math.Sin(Theta_rad);double cncp = cosTheta * c / cPrev;if ((Math.Abs(cncp) <= 1) && (!double.IsInfinity(recipSinTheta))){    prevTheta_deg_valid = Theta_rad;    Theta_rad = theta_sign * Math.Acos(cncp);}else{    Theta_rad = -prevTheta_deg_valid;}           cPrev = c;RayPoint newPoint = new RayPoint(x, z, e);rayPoints.Add(newPoint);return newPoint;

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

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

Один скользкий момент связан с тем случаем, когда угол скольжения становится близок к вертикали или горизонтали. Лучевая теория решительно не может нам здесь адекватно помочь: согласно ей тут происходит фокусировка и уровень сигнала стремится к бесконечности. В реальности, конечно, такого произойти не может.

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

Ну что ж, достаточно о реализации. Скучная часть окончена, перейдем к картинкам.

Все, что угодно за ваши лучезарные улыбки

Взяв на себя смелость я быстренько накидал простое приложение на С#, который мне ближе всего при разработке чего-нибудь для десктопа. Проект, как обычно, положил на наш гихаб.

И собрался было уже писать статью, как вспомнил, что на одну из таких статей с исходниками и скомпиленным релизом кто-то написал в комментариях: Открыл ссылку - а там win exe :(

Мне очень хотелось, чтобы поиграться с моделью для читателей было бы совсем просто, настолько, насколько я вообще могу себе представить. Вооружившись блокнотом я погрузился на пару дней в чуждый для меня мир JavaScript. Этим я как бы покупаю у вас индульгенцию на неряшливый код :)

Результатом стала онлайн версия трассировщика лучей.

Так давайте же уже запустим это!

Устанавливаю в поле Z значение 0.1 (глубина первого профиля всего 38 метров и разрешение по умолчанию в 1 метр нам будет недостаточно) и загружаем предустановленный профиль GR-553 при помощи одноименной кнопки.

В заголовке профиля указано где, когда и кем он был получен:

NODC Cruise ID              ,,GR-553         ,,,Latitude                    ,,         39.682,decimal degrees,,Longitude                   ,,        19.8750,decimal degrees,,Year                        ,,           1991,,,Month                       ,,              9,,,Day                         ,,              5,,,Time                        ,,          13.17,decimal hours (UT),,METADATA,Country                     ,,             GR,NODC code,GREECEPlatform                    ,,          9628.,OCL code,AEGAEO (R/V;call sign SXYY;built 12.1985;ex.AEGAIO 10.1994;IMO8412429),Institute                   ,,          1445.,NODC code,HELLENIC CENTRE FOR MARINE RESEARCH (HCMR); former NATIONAL CMR (06.2003),Bottom depth                ,,            38.,meters,,

Профиль был получен славными эллинами, 5 сенября 1991 года на вот этом исследовательском судне вот здесь.

Оно кстати, до сих пор бороздит просторы.

Нажимаем кнопку RUN SIMULATION и через некоторое время скрипт генерирует такую красоту:

Сентябрь, греческий Корфу, жаркий (наверное) полдень - теплая вода у поверхности и прохладная у дна. Я не был в греции, но могу сказать, что у нас на р. Пичуга под Волгоградом в самое июльское пекло на 15-20 метрах температура обычно 13-14С.

Слева мы видим сам профиль, значения скорости звука (зеленый график) почти 1 в 1 повторяют график температуры. Соленость не влияет совсем, т.к. меняется лишь незначительно от 38.3 до 38.5 PSU. Скорость звука же уменьшается от 1537 м/с на поверхности, достигая минимума в 1528 м/с у дна.

Все это приводит к тому, что звук, от расположенного на глубине Z0 = 2 метра источника, придет к поверхности не далее чем в 400 метрах от положения этого самого источника. Это будут т.н. прямые лучи. Все остальное - отражения от дна и многократные поверхность-дно-поверхность.

Мы видим, что лучи загибаются вниз. А что там такого, что им туда так хочется попасть? Вот здесь мы подходим к самому основному, фактически, это самый минимум, который я хочу, чтобы вы запомнили. Из этого выводится все остальное.

Траектории лучей загибаются в сторону уменьшения скорости звука.

Такие условия, когда минимум скорости звука лежит у дна называются отрицательной рефракцией. Это одни из самых неудобных условий для гидроакустической связи.

А помните, я обращал ваше внимание на то, что суть закона Снелля в том, что при преодолении границы раздела сред, волна идет путем экстремального (минимального) времени распространения? Ирония состоит в том, что волна, локально сокращая время распространения всегда стремится в область с меньшей скоростью звука, что в глобальном смысле наоборот увеличивает время распространения.

Чтобы закрепить, откроем следующий профиль NA-35, но немного изменим параметры симуляции: максимум по оси X установим равным 2000 метров. Что же мы видим?

Ого, глубина уже лодочная! А температура падает от 16С у поверхности до 6С у дна. И снова отрицательная рефракция, и снова звук стремится ко дну.

21 июня 1996 года. В России вовсю свирепствуют девяностые, я закончил 6 класс и наверное отдыхаю на даче с братьями, а судно под названием Dr. Fridtjof Nansen берет CTD пробы у берегов Намибии.

Необычайно прохладная для этих мест вода обязана холодному течению Бенгела.

Почему это важно? Мы, например, производим гидроакустические модемы, у которых среди характеристик указана т.н. энергетическая дальность - дальность, на которой два таких модема могут передать данные между собой. Для самых маленьких наших модемов она составляет 1000 метров. Длины лучей на картинке выше как раз и ограничены одним километром.

И сложно не заметить, что максимум, что можно получить опустив модемы чуть ниже поверхности воды - метров 400. А учитывая волнение и вовсе не гладкую поверхность воды - десятки метров. А вот если опустить приемник хотя бы метров на 10-20, можно уверенно получить фактическую дальность в районе километра.

Ладно, надоела уже эта отрицательная рефракция. Поехали дальше.

Профиль US-32437. Я поставил предел по оси Х и максимальную длину луча равными 2000 метров. Остальные условия те же.

30 января 2009 года. Исследовательское судно NOAA Delaware II на своем 41 году жизни берет пробы у восточной оконечности Лонг-Айленда. Невероятно, но факт: marinetraffic сообщает, что Delaware II до сих пор в строю в свои 53 года. Правда называется теперь Med Surveyor и ходит под флагом Панамы.

Ситуация с точностью до наоборот: минимум скорости звука на поверхности. В этом нет ничего удивительного: 30 января, северная атлантика. В нью-йорке, говорят, иногда идет снег. Когда упоминается Нью-Йорк, в моей голове сразу возникает Let it snow, let it snow, let it snow голосом Фрэнка Синатры.

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

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

И что же мы видим на картинке? Если наш робот находится глубже 30 метров и отошел от нас метров на 400 - связь может стать очень неустойчивой и даже полностью пропасть. На дальности более 1000 метров и глубине более 20 ничего, кроме возможных отражений от поверхности мы не поймаем. Кстати, большой привет тем, кто работает с УКБ и использует вертикальный угол прихода сигнала для определения глубины объекта.

Но скорее всего не поймаем даже эти отражения: январь, атлантика. Наверняка ветрено и большие волны, они явно больше длины волны нашего сигнала - вот и на отражения от поверхности можно не рассчитывать.

Тем временем, мы подходим к следующему профилю из онлайн-трассировщика. Я уменьшил угол диаграммы направленности до 60 и установил глубину источника в 60 метров. Вот что получается:

Этот профиль особенно примечателен. Мы видим, что график скорости звука (и температуры) имеет экстремумы. То есть главный минимум находится ни у дна ни у поверхности. К чему это приводит?

Звук, как мы уже выяснили, загибается в сторону уменьшения скорости распространения. И, будучи излученным под небольшими углами скольжения в области минимума скорости звука оказывается заперт: он обречен постоянно пересекать горизонт минимума и постоянно возвращаться к нему. Такую область называют каналом, а условия распространения - канальными.

Впервые описали и объяснили условия канального распространения звука в океане в 1947 году советские ученые во главе с академиком Бреховских и доктором технических наук Розенбергом.

Иногда упоминают, что на звукоподводный канал был открыт и описан немного раньше, в 1944 году Американскими учеными, правда, все было описано в закрытых работах.

Но вернемся к нашему профилю.

19 ноября 1996, легкий ледокол George R. Pearkes 1986 года постройки (все еще в строю) брал пробы в дельте реки Сент-Лоуренс, где она впадает в одноименный залив.

Давайте попробуем поугадывать, откуда взялся такой интересный профиль с двумя впадинами. Я бы сказал, что теплый летний слой не успел еще исчезнуть совсем (ноябрь все-таки), а вода у поверхности уже начала значительно охлаждаться. А еще, если обратить внимание на профиль солености - она значительно ниже у поверхности, что по всей видимости, связано с впадением пресной речной воды в океанические воды.

А теперь посмотрим, что происходит с лучами в канале. Для этого я увеличу предел по оси Х и максимальную длину луча до, скажем, 20 километров.

Вот что мы получим:

Лучи, вышедшие из источника под небольшими углами к горизонту остаются в пределах канала, не касаясь ни дна ни поверхности: звукоподводный канал на мелководье!

Звук распространяется совсем неглубоко и в верхней точки выходит на глубины порядка 20-25 метров. Так он может проходить десятки километров. Напомню: по оси Z всего около 170 метров, а по оси Х - 20 000. То есть фактическое соотношение сторон у графика более 1:100, это примерно как столешница, или лужа на асфальте.

Мы переходим к заключительному профилю, самому глубокому из рассмотренных нами: SU-7464.

22 апреля 1991 года. Судно "Прилив" (на marinetraffic я его не нашел), еще под советским флагом, управляющая организация - Тихоокеанский Океанологический Институт, г. Владивосток. Место взятия проб - камчатский залив.

Этот профиль и выполненная по нему симуляция иллюстрируют еще один занимательный феномен: так называемый, приповерхностный звуковой канал. Такое бывает, когда самые холодные слои воды находятся под поверхностью, что приводит к формированию приповерхностного слоя с минимальной скоростью звука между немного прогретым поверхностным и более теплыми глубокими слоями. Здесь мы также можем наблюдать пресловутый слой скачка - резкого изменения скорости звука, от которого как от зеркала отражаются лучи, идущие под пологими и средними углами к горизонту.

Луч - линия имеющая начало, но не имеющая конца

Наш луч, вопреки определению из школьного курса геометрии, здесь окончательно теряет энергию и вежливо намекает на то, что пора бы подвести итоги.

Что же у нас в сухом остатке?

  • Звук распространяется в водоемах не по прямым линиям, а изгибается в виду наличия слоев воды разной плотности, а соответственно - с разной скоростью звука

  • Звук всегда поворачивает в сторону минимума скорости звука, от чего при определенных условиях в водоемах могут образовываться каналы

  • Примерный (примерный!) характер траекторий звуковых волн можно получить используя очень простые закономерности

  • Диапазон условий необычайно широк, а конкретные условия в конкретном месте склонны иногда к быстрым изменениям

Добавлю, что мало знать профиль скорости звука, нужно знать условия на поверхности, профиль и материал дна. Еще хорошо бы понимать где на пути вашего сигнала проплывает косяк макрели, или какие-то другие объемные неоднородности, на которых звук рассеивается.

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

Закончить свое повествование хочу такими аналогиями:

  • Гидроакустическая связь, особенно на дальние расстояния, это всегда немножко попытка скинуть ключи с балкона 16 этажа человеку с завязанными глазами.

  • А гидроакустическая навигация - попытка измерять что-то постоянно извивающейся или как минимум провисшей рулеткой =)

P.S.

Традиционно благодарю за внимание, буду признателен за конструктивную критику и указание на ошибки.

Обратная связь позволяет не думать о своем труде, как о напрасном.

Подробнее..

Симуляторы компьютерных систем всем знакомый полноплатформенный симулятор и никому неизвестные потактовый и трассы

02.07.2020 20:17:59 | Автор: admin
Во второй части статьи о симуляторах компьютерных систем продолжу рассказывать в простой ознакомительной форме о компьютерных симуляторах, а именно о полноплатформенной симуляции, с которой чаще всего сталкивается обычный пользователь, а также о потактовой модели и трассах, которые больше распространены в кругах разработчиков.

image

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

Полноплатформенный симулятор (full platform simulator), или Один в поле не воин


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

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

Ниже приведена блок-диаграмма чипсета x58 от компании Intel. В полноплатформенном симуляторе компьютера на этом чипсете необходима реализация большинства перечисленных устройств, в том числе и тех, что находятся внутри IOH (Input/Output Hub) и ICH (Input/Output Controller Hub), не нарисованных детально на блок-диаграмме. Хотя, как показывает практика, не так уж мало устройств, которые не используются тем ПО, которое мы собираемся запускать. Модели таких устройств можно не создавать.

image

Чаще всего полноплатформенные симуляторы реализуются на уровне инструкций процессора (ISA, см. предыдущую статью). Это позволяет относительно быстро и недорого создать сам симулятор. Уровень ISA также хорош тем, что остается более или менее постоянным, в отличие от, например, уровня API/ABI, который меняется чаще. К тому же, реализация на уровне инструкций позволяет запускать так называемое немодифицированное бинарное ПО, то есть запускать уже скомпилированный код без каких-либо изменений, ровно в том виде как он используется на реальном железе. Другими словами, можно сделать копию (дамп) жесткого диска, указать его в качестве образа для модели в полноплатформенном симуляторе и вуаля! ОС и остальные программы загружаются в симуляторе без всяких дополнительных действий.

Производительность симуляторов



image

Как было упомянуто чуть выше, сам процесс симуляции всей системы целиком, то есть всех ее устройств, довольно небыстрое мероприятие. Если еще и реализовать все это на совсем детальном уровне, например, микроархитектурном или логическом, то выполнение станет экстремально медленным. А вот уровень инструкций является подходящим выбором и позволяет ОС и программам выполняться на скоростях, достаточных пользователю для комфортного взаимодействия с ними.

Здесь как раз уместно будет коснуться темы производительности симуляторов. Обычно ее измеряют в IPS (instructions per second), точнее в MIPS (millions IPS), то есть количестве инструкций процессора, выполняемых симулятором за одну секунду. В то же время скорость симуляции зависит и от производительности системы, на которой работает сама симуляция. Поэтому, возможно, правильнее говорить о замедлении (slowdown) симулятора по сравнению с оригинальной системой.

Наиболее распространенные на рынке полноплатформенные симуляторы, те же QEMU, VirtualBox или VmWare Workstation, имеют неплохую производительность. Для пользователя может быть даже не заметно, что работа идет в симуляторе. Так происходит благодаря реализованной в процессорах специальной возможности виртуализации, алгоритмам бинарной трансляции и другим интересным вещам. Это все тема для отдельной статьи, но если совсем коротко, то виртуализация это аппаратная возможность современных процессоров, позволяющая симуляторам не симулировать инструкции, а отдавать на исполнение напрямую в реальный процессор, если, конечно, архитектуры симулятора и процессора похожи. Бинарная трансляция это перевод гостевого машинного кода в хостовый и последующее исполнение на реальном процессоре. В результате симуляция лишь ненамного медленнее, раз в 5-10, а часто вообще работает с той же скоростью, что и реальная система. Хотя на это влияет очень много факторов. Например, если мы хотим симулировать систему с несколькими десятками процессоров, то скорость тут же упадет в эти несколько десятков раз. С другой стороны, симуляторы типа Simics в последних версиях поддерживают многопроцессорное хостовое железо и эффективно распараллеливают симулируемые ядра на ядра реального процессора.

Если говорить про скорость микроархитектурной симуляции, то это обычно на несколько порядков, примерно в 1000-10000 раз, медленнее выполнения на обычном компьютере, без симуляции. А реализации на уровне логических элементов медленнее еще на несколько порядков. Поэтому в качестве эмулятора на этом уровне используют FPGA, что позволяет существенно увеличить производительность.

График ниже показывает примерную зависимость скорости симуляции от детализации модели.

image

Потактовая симуляция


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

Простейший пример инструкция доступа в память. Если запрашиваемая ячейка памяти доступна в кэше, то время выполнения будет минимально. Если в кэше данной информации нет (промах кэша, cache miss), то это сильно увеличит время выполнения инструкции. Таким образом, для точной симуляции необходима модель кэша. Однако моделью кэша дело не ограничивается. Процессор не будет просто ждать получения данных из памяти при ее отсутствии в кэше. Вместо этого он начнет выполнять следующие инструкции, выбирая такие, которые не зависят от результата чтения из памяти. Это так называемое выполнение не по порядку (OOO, out of order execution), необходимое для минимизации времени простоя процессора. Учесть все это при расчете времени выполнения инструкций поможет моделирование соответствующих блоков процессора. Среди этих инструкций, выполняемых, пока ожидается результат чтения из памяти, может встретится операция условного перехода. Если результат выполнения условия неизвестен на данный момент, то опять-таки процессор не останавливает выполнение, а делает предположение, выполняет соответствующий переход и продолжает превентивно выполнять инструкции с места перехода. Такой блок, называемый branch predictor, также должен быть реализован в микроархитектурном симуляторе.

Картинка ниже показывает основные блоки процессора, ее знать необязательно, она приведена лишь для того, чтобы показать сложность микроархитектурной реализации.

image

Работа всех этих блоков в реальном процессоре синхронизуется специальными тактовыми сигналами, аналогично происходит и в модели. Такой микроархитектурный симулятор называют потактовым (cycle accurate). Основное его назначение точно спрогнозировать производительность разрабатываемого процессора и/или рассчитать время выполнения определенной программы, например, какого-либо бенчмарка. Если значения будут ниже необходимых, то потребуется дорабатывать алгоритмы и блоки процессора или оптимизировать программу.

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

При этом для симуляции остального времени работы программы используется функциональный симулятор. Как такое комбинированное использование происходит в реальности? Сначала запускается функциональный симулятор, на котором загружается ОС и все необходимое для запуска исследуемой программы. Ведь нас не интересует ни сама ОС, ни начальные стадии запуска программы, ее конфигурирование и прочее. Однако и пропустить эти части и сразу перейти к выполнению программы с середины мы тоже не можем. Поэтому все эти предварительные этапы прогоняются на функциональном симуляторе. После того, как программа исполнилась до интересующего нас момента, возможно два варианта. Можно заменить модель на потактовую и продолжить выполнение. Режим симуляции, при котором используется исполняемый код (т.е. обычные скомпилированные файлы программ), называют симуляцией по исполнению (execution driven simulation). Это самый распространенный вариант симуляции. Возможен также и другой подход симуляция на основе трасс (trace driven simulation).

Симуляция на основе трасс


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

Следующий шаг это проигрывание трассы, когда потактовый симулятор читает трассу и выполняет все инструкции, записанные в ней. В конце получаем время выполнения данного куска программы, а также различные характеристики этого процесса, например, процент попадания в кэш.

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

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

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

Использование компьютерных симуляторов. Утром софт, вечером железо

16.11.2020 22:16:56 | Автор: admin
После того, как мы здесь и здесь разобрали, что же такое компьютерные симуляторы и какими они бывают, настало время поговорить о том, как они используются. И начну я, пожалуй, с наиболее интересной области применения расскажу о том, как профессиональные программисты используют симуляторы при разработке ПО, чтобы написать и отладить софт для железа, которого еще даже не существует.

image

Речь пойдет об использовании моделей не самых простых устройств, таких как, например, SoC (System on Chip) или печатных плат со множеством интегрированных устройств на борту. В разработке самих этих устройств можно выделить два этапа. Сначала разрабатывается аппаратная часть. Это процесс небыстрый может занять и год, и больше.

После того как появляется первая ревизия физического устройства и проводятся базовые проверки, устройство передается разработчикам ПО. С этого момента начинается вторая фаза разработка софта для устройства. Это могут быть прошивки (firmware), BIOS, BSP/CSP (Board and CPU Support Package) для различных операционных систем, а также драйвера.

image
Кстати, в разработке чипов, которые часто называют силикон (silicon), эти фазы именуются пре-силикон (pre-silicon) и пост-силикон (post-silicon) или просто силикон.

Теоретически, разработка ПО возможна и до появления физического устройства. Однако, на практике так мало кто делает. Разработка без возможности промежуточных запусков и отладки, а для этого как раз и требуется устройство, дело сильно неблагодарное, я встречал мало таких мазохистов. Все ждут железо, а оно, как я написал выше, появится только через год.

Кроме того, с железом есть еще и другая проблема. Первую ревизию выпускают лимитированной серией и раздают по одной штуке в руки. Проще говоря, плат и чипов на всех не хватает. Возникают очереди, конфликты, доходит до рукоприкладства. А если ты случайно спалил устройство, что очень даже несложно, то вся разработка останавливается, пока не будет найдено другое устройство. Часто оно не находится, необходимо производить новое, а потом ждать доставку. Это сильно тормозит процесс.

И тогда на помощь разработчикам ПО приходят симуляторы!

Создание виртуальной модели устройства начинается одновременно с проектированием физического устройства. Но так как создание и выпуск модели существенно проще, первые релизы таких моделей появляются условно не через год, а много раньше. Используя такие модели, разработчики ПО могут сразу приступить к своим задачам, не дожидаясь железа.

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

image
При таком подходе разработчики моделей и софта используют общие спецификации. Запуская ПО на модели, они, по сути, проверяют работу друг друга.

Дополнительным плюсом является валидация железа при том, что самого железа еще даже нет. Это звучит удивительно на первый взгляд, но речь здесь идет об архитектурных ошибках при проектировании устройства, часть из которых может выявляться при запуске софта на модели. И это очень круто, так как есть возможность исправить эти ошибки в железе до того, как оно будет выпущено. В противном случае эти ошибки привели бы к необходимости перевыпуска следующих ревизий, а это довольно дорогое удовольствие.

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

Большие компании-производители устройств могут поддерживать целую экосистему, выстроенную вокруг своих продуктов. В такую экосистему входят множество других компаний, в том числе и тех, которые производят ПО для данного оборудования. Например, это могут быть производители BIOS, так называемые IBV (Independent BIOS Vendors), наиболее известные из которых AMI, Insyde, Phoenix. Такие компании также получают модели от производителя оборудования и начинают разработку до появления физического устройства. Например, для платформ Intel используется симулятор Simics, о чем подробнее можно прочитать в статье Ecosystem Partners Shift Left with Intel for Faster Time-to-Market.

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

Часто для сокращения затрат в модели реализуют не всю возможную функциональность, а только минимально необходимую для определенных сценариев использования устройства. Например, если сетевое устройство не планируется использовать в VLAN-ах, а только чтобы обновлять прошивку и делать загрузку по tftp, то логику с VLAN tag-ами реализовывать необязательно, а вот функциональность для сценариев загрузки устройства по сети и обновления прошивки надо реализовать в полном объеме.

Что в итоге получается?

Если принять, что время разработки железа и софта примерно равны друг другу (см. картинку выше), то использование моделей позволяет существенно, практически в 2 раза, сократить время вывода продукта на рынок (т.н. TTM Time To Market), так как разработка железа и софта ведется параллельно, а не последовательно. Для этого часто используют термин Shift Left, пришедший из области тестирования, где он означал как можно более раннее тестирование. Этот же термин применим и к разработке ПО, которая как бы сдвигается влево по шкале времени, когда выполняется на симуляторе.

К моменту появления первой ревизии оборудования останется только проверить работоспособность ПО на реальном железе. В идеале, ошибки и исправления не должны быть значительными и данный этап не вносит больших задержек, так как код уже написан и отлажен на модели.

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

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

Категории

Последние комментарии

  • Имя: Макс
    24.08.2022 | 11:28
    Я разраб в IT компании, работаю на арбитражную команду. Мы работаем с приламы и сайтами, при работе замечаются постоянные баны и лаги. Пацаны посоветовали сервис по анализу исходного кода,https://app Подробнее..
  • Имя: 9055410337
    20.08.2022 | 17:41
    поможем пишите в телеграм Подробнее..
  • Имя: sabbat
    17.08.2022 | 20:42
    Охренеть.. это просто шикарная статья, феноменально круто. Большое спасибо за разбор! Надеюсь как-нибудь с тобой связаться для обсуждений чего-либо) Подробнее..
  • Имя: Мария
    09.08.2022 | 14:44
    Добрый день. Если обладаете такой информацией, то подскажите, пожалуйста, где можно найти много-много материала по Yggdrasil и его уязвимостях для написания диплома? Благодарю. Подробнее..
© 2006-2024, personeltest.ru