• Регистрация
Streltsov_ma
Streltsov_ma 0.00
н/д

Ошибки симуляции математических моделей с тригонометрическими функциями в Matlab&Simulink

23.03.2020

Рассмотрены два вида построения математической модели:

  1.  Используя Matlab function, с определением в ней функции sin
  2.  Используя тригонометрическую функцию sin

graphs

В связи с этим возникает вопрос - как правильно завести данную модель ?

Модели прикладываю. Дифференциальное уравнение вида : dx/dt=sin(x+pi); x(0)=0

Теги

    23.03.2020

    Ответы

    • aBoomest
      aBoomest+942.89
      23.03.2020 04:59

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

      • Spin7ion
        Spin7ion0.00
        23.03.2020 08:35

        Так-то scope должен показать 0 без колебаний. Решение дифференциального уравнения: x(t)=0

        • aBoomest
          aBoomest+942.89
          23.03.2020 08:45

          там у вас что-то в духе минус 16 степень

          • Spin7ion
            Spin7ion0.00
            23.03.2020 08:54

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

            Хочется понять, что делать в подобных ситуациях.

            • aBoomest
              aBoomest+942.89
              23.03.2020 08:59

              С "синтетическим" примером вроде все ок.
              Анализировать работу, искать ощибки. (имхо)

              • Streltsov_ma
                Streltsov_ma0.00
                23.03.2020 09:01

                Какие ошибки могут быть в sin(pi)=0 ?

                • aBoomest
                  aBoomest+942.89
                  23.03.2020 09:51

                  1. А вы попробуйте синус пи в командной строке просто введите.
                  2. Матлаб это машина делающая численные вычисления. Любые алгоритмы имеюют точность. Это вы в курсе, что синус пи это ноль. А в машине обычно алгоритм на общий случай любого аргумента.

                  • aBoomest
                    aBoomest+942.89
                    23.03.2020 10:30

                    3. Самое занятное, что даже числа пи вы тоже не знаете, а только с какой-то точностью.

                    • Spin7ion
                      Spin7ion0.00
                      23.03.2020 11:06

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

                      Поможет ли zero-crossing, как его настроить?

                      • Павел Рословец
                        Павел Рословец +239.28
                        23.03.2020 11:17

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

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

      • Павел Рословец
        Павел Рословец +239.28
        23.03.2020 11:11

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

        Начнем с модели BUG_1, где синус выполнен в виде MATLAB-функции. В настройках модели стоит решатель auto, и Simulink автоматически выбирает решатель ode45 с максимальным шагом 0.2 с, что отображается в нижнем правом углу модели.

        На выходе вы получаете график, который прислали.

        Да он не нулевой, как ожидалось, но обратите внимание на порядок величин - 3e-16, что вполне согласуется с точностью чисел типа double и является всего лишь допустимой погрешностью расчета, которой можно пренебречь. Более того, если вы попробуете другие решатели (например, fixed step ode4), то графики и погрешность расчета будут отличаться, но, в любом случае, результат будет около нуля.

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

        Теперь модель BUG_2. Когда я открыл ее и запустил, симуляция остановилась с ошибкой на 0,0119 секунде. Дело в том, что у нее тоже стоит решатель auto, но в данной модели Simulink атвоматически ставит решатель ode15s с огромным шагом интегрирования 2 с. И получается, что этот решатель с такими настройками не способен справиться с задачей.

        Для простоты поставим для этой модели решатель ode45 с максимальным шагом 0.2 - как в предыдущей модели.

        Получаем вот такой страшный график

        Возникает 2 вопроса:

        - Почему график так сильно отличется от первой модели, если и там и там - всего лишь синус, хоть и задан он по-разному?

        - Почему по графику получается такая дикая погрешность - 4e-4? Это уже никак не соотносится с погрешностью типа double

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

        Если в Approximation method поставить None и запустить симуляцию на 10 секундах, то получим точно такой же график, что и в первой модели.

        Итак, мы выяснили, что при одинаковых настройках решателя, обе модели работают одинаково, с допустимой точостью, которой мы можете управлять путем тонкой настройки решателя. В данном случае, я бы рекомендовал использовать второй вариант с блоком Trigonometric Function, чтобы не переусложнять модель кодом MATLAB.

        И в качестве бонуса хочу обратить ваше внимание на еще один важный момент. Дело тут ведь не только в решателях.

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

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

        Если же вам принципиально получить чистый ноль в демонстрационных целях - замените в блоке MATLAB Function функцию sin на sind, которая принимает на вход не радианы, а градусы. Соответственно в модели замените константу pi на 180.

        Получите идеальную прямую линию.

        ВЫВОДЫ:

        1) ошибок тут нет, все работает, как должно

        2) правильно выбирайте и настраивайте решатели. Вот инструкция:

        https://www.mathworks.com/help/simulink/ug/choose-a-solver.html

        https://docs.exponenta.ru/simulink/ug/choose-a-solver.html

        3) погрешность есть всегда и с ней приходится мириться, а также ей можно управлять

        4) Иногда погрешность можно свести к нулю, используя правильные блоки

        Спасибо за интересный вопрос! У самого на заре работы в Simulink возникали подобные проблемы, пришлось быстро понять, что решатель  - это не какая-то непонятная штука, а очень важная вещь, которую не нужно бояться и которой нужно управлять.

        P.S. Приходите к нам не тренинги, на SLBE мы подробно разбираем особенности численных расчетов и работы решателей

        https://exponenta.ru/SLBE

        • aBoomest
          aBoomest+942.89
          23.03.2020 11:13

          Это зависит от того, чем оно вам мешает. Если у вас на фоне таких нулей (что обычно на првктике и имеет место) есть еще реальные не нулевые величины, то -16 степень в принципе не видна.

          Можно блок ифо-кейса вляпать (if block). Т.е. если значение мешьше к.л. значения (1е-9 например), то на выход отправлять ноль.