New Page 2
Моделирование систем. Урок 5. Модель "Маятник".
Это последний урок из серии "Моделирование систем", публикуемый в
бесплатном разделе. Начиная со следующего,
публикация уроков будет продолжена в платном
разделе. В бесплатном же разделе иногда, возможно, будут опубликованы
некоторые отдельные статьи, посвященные моделированию систем.
Исходники к уроку можно скачать
здесь.
Сегодня мы разработаем программу для моделирования простейшего пружинного
маятника. Сначала разработаем математическую модель. И так, маятник у нас имеет
массу m, в текущий момент времени он находиться в
положении x, имеет скорость v
и ускорение a. На него действует сила натяжения
пружины F, которая равна
F=-Fx * x
где Fx - удельная сила натяжения пружины. Знак минус
означает, что пружина тянет маятник в сторону, противоположную смещению маятника
из положения равновесия.
Сила натяжения пружины создает маятнику ускорение
a=F/m
Скорость маятника меняется по формуле:
v=v0+a*t
где v0 - старая скорость, a -
ускорение, t - размер кванта времени.
За квант времени t местоположение маятника меняется по
такому закону:
x=x+v*t
Теперь реализуем это программно:
class
Pendulum :
BaseClass
{
///
<summary>
///
Координата x маятника
///
</summary>
public
double x { get;
set; }
///
<summary>
///
Масса маятника
///
</summary>
public
double m { get;
set; }
///
<summary>
///
Удельная сила натяжения пружины
///
</summary>
public
double Fx { get;
set; }
private
double _F;
///
<summary>
///
Сила натяжения пружины
///
</summary>
public
double F
{
get
{
return
_F;
}
}
///
<summary>
///
Скорость движения маятника
///
</summary>
public
double v { get;
set; }
///
<summary>
///
Ускорение маятника
///
</summary>
public
double a { get;
set; }
///
<summary>
///
Размер кванта времени
///
</summary>
public
double quantumTimeSize {
get; set; }
///
<summary>
///
Отработка одного кванта времени
///
</summary>
public
void quantumTime()
{
v = v + a * quantumTimeSize;
//вычислим изменения скорости
x = x + v * quantumTimeSize;
//вычислим новое положение маятника на оси x
_F = - Fx * x;
//вычислим силу натяжения пружины
a = F / m;
//вычислим ускорение, создаваемое силой натяжения пружины
}
///
<summary>
///
Заголовок класса
///
</summary>
///
<returns>Заголовок
класса</returns>
public
override string
GetClassCaption()
{
return
"Маятник";
}
} |
для тестирования вновь создадим форму с Chart, как это
делали на
уроке 3:
Вот как у нас будет выглядеть процедура симуляции:
private void
btnSimul_Click(object sender,
EventArgs e)
{
Pendulum pend =
new Pendulum();
pend.a = Convert.ToDouble(tba.Text);
pend.Fx = Convert.ToDouble(tbFx.Text);
pend.m = Convert.ToDouble(tbm.Text);
pend.quantumTimeSize = Convert.ToDouble(tbquantumTimeSize.Text);
pend.v = Convert.ToDouble(tbv.Text);
pend.x = Convert.ToDouble(tbx.Text);
chart.Series.Clear();
chart.Series.Add("Коордианат
x");
chart.Series.Add("Скрость
v");
chart.Series.Add("Ускорение
a");
chart.Series[0].ChartType =
SeriesChartType.Line;
chart.Series[0].BorderWidth = 3;
chart.Series[1].ChartType =
SeriesChartType.Line;
chart.Series[1].BorderWidth = 3;
chart.Series[2].ChartType =
SeriesChartType.Line;
chart.Series[2].BorderWidth = 3;
int cn =
Convert.ToInt32(tbCount.Text);
for (int
i = 1; i < cn; i++)
{
chart.Series[0].Points.AddXY(i, pend.x);
chart.Series[1].Points.AddXY(i, pend.v);
chart.Series[2].Points.AddXY(i, pend.a);
pend.quantumTime();
}
} |
И вот как будет выглядеть график движения маятника:
теперь немножко усложним модель и добавим к ней внешнее воздействие -
кратковременные толчки силой Fp, длительностью
N квантов времени и периодичность M
квантов времени. Для этого нам надо немного переделать класс Pendulum:
using
System;
using
System.Collections.Generic;
using
System.Linq;
using
System.Text;
namespace
WindowsFormsApplication1
{
class Pendulum
: BaseClass
{
///
<summary>
///
Координата x маятника
///
</summary>
public
double x { get;
set; }
///
<summary>
///
Масса
маятника
///
</summary>
public double
m { get; set;
}
///
<summary>
///
Удельная сила натяжения пружины
///
</summary>
public
double Fx { get;
set; }
///
<summary>
///
Внешняя
сила
///
</summary>
public double
Fp { get; set;
}
///
<summary>
///
Длительность импульса внешней сила, квантов времени
///
</summary>
public double
N { get; set;
}
///
<summary>
///
Периодчиность следования импульстов, квантов времени
///
</summary>
public double
M { get; set;
}
private double
_F;
private double
_n;
private double
_m;
///
<summary>
///
Сила
натяжения
пружины
///
</summary>
public double
F
{
get
{
return _F;
}
}
///
<summary>
///
Скорость движения маятника
///
</summary>
public double
v { get; set;
}
///
<summary>
///
Ускорение
маятника
///
</summary>
public double
a { get; set;
}
///
<summary>
///
Размер кванта времени
///
</summary>
public
double quantumTimeSize {
get; set; }
public Pendulum()
{
_n = 0;
_m = 0;
}
///
<summary>
/// Отработка одного кванта времени
///
</summary>
public
void quantumTime()
{
double _Fp=0;
if (_m == 0)
{
_n = N;
_m = M;
}
else
{
_m = _m-1;
}
if (_n
!= 0)
{
_Fp = Fp;
_n = _n - 1;
}
else
{
_Fp = 0;
}
v = v + a * quantumTimeSize;
//вычислим изменения скорости
x = x + v * quantumTimeSize;
//вычислим новое положение маятника на оси x
_F = - Fx * x;
//вычислим силу натяжения пружины
a = (_Fp + F) / m;
//вычислим ускорение, создаваемое силой натяжения
пружины и внешней силой
}
///
<summary>
///
Заголовок класса
///
</summary>
///
<returns>Заголовок
класса</returns>
public
override string
GetClassCaption()
{
return
"Маятник";
}
}
} |
ну, и, соответственно, чуть чуть внесем изменения в процедуру симуляии:
private void
btnSimul_Click(object sender,
EventArgs e)
{
Pendulum pend =
new Pendulum();
pend.a = Convert.ToDouble(tba.Text);
pend.Fx = Convert.ToDouble(tbFx.Text);
pend.m = Convert.ToDouble(tbm.Text);
pend.quantumTimeSize = Convert.ToDouble(tbquantumTimeSize.Text);
pend.v = Convert.ToDouble(tbv.Text);
pend.x = Convert.ToDouble(tbx.Text);
pend.M = Convert.ToDouble(tb_M.Text);
pend.N = Convert.ToDouble(tbN.Text);
pend.Fp = Convert.ToDouble(tbFp.Text);
chart.Series.Clear();
chart.Series.Add("Коордианат
x");
chart.Series.Add("Скрость
v");
chart.Series.Add("Ускорение
a");
chart.Series[0].ChartType =
SeriesChartType.Line;
chart.Series[0].BorderWidth = 3;
chart.Series[1].ChartType =
SeriesChartType.Line;
chart.Series[1].BorderWidth = 3;
chart.Series[2].ChartType =
SeriesChartType.Line;
chart.Series[2].BorderWidth = 3;
int cn =
Convert.ToInt32(tbCount.Text);
for (int
i = 1; i < cn; i++)
{
chart.Series[0].Points.AddXY(i, pend.x);
chart.Series[1].Points.AddXY(i, pend.v);
chart.Series[2].Points.AddXY(i, pend.a);
pend.quantumTime();
}
} |
Теперь посмотрим, как будет вести себя система при разном значении частоты
толчков:
Если частота близка к резонансной:
Еще ближе к резонансу, почти резонанс:
Но лучше всего это видно в более глобальном масштабе:
Чем ближе частота к резонансной, тем в сильнее в итоге вырастет амплитуда
колебаний:
Скриншоты, приведенные в данной статье,
являются цитатами и иллюстрациями программного
продукта "Microsoft Visual Studio 2010", авторское право на
который принадлежит Microsoft.
|