12/May/2025 1/4車体モデルによるシミュレーション(2)

1自由度モデル 書き直し

以下は、1自由度振動系のプログラムを線形システムとしての記述を意識して書きなおしたものである。

変更した項目

% sim_1dof.m を改良

%% 初期化
% ウィンドウを閉じる
clear;
close all;

%% 状態空間モデルを作成
m=1; c=1; k=10;

A=[0 1; -k/m -c/m];
B=[0; 1/m];
C=[1 0];
D=[0];

sys=ss(A,B,C,D);

figure(1);
set(gcf,'Position',[100 100 600 400]);
bode(sys);

%% ode関数の呼び出し
% 初期条件の定義
x0 =[0;0];
% シミュレーション時間の定義
time =[0:0.01:10];

% MATLABで関数を引数とする場合は、関数ハンドル@を利用する
% 4つめの引数はsolverのoption指定なので、ここでは空行列を定義したがお好みで
[t,x] = ode45(@(t,x) func_ss(t,x,sys,@(t) u(t)),time,x0,[]);    
    
% 数値積分結果を利用して出力ベクトルを算出
% 転置の操作が必要
% ode45の計算結果である t, x がどのようなサイズになるかを注意
y=(C*x'+D*u(t)')';

%% 入出力ベクトルを利用してグラフをプロット
figure(2);
set(gcf,'Position',[800 100 600 400]);

subplot(2,1,1)
plot(t,u(t));
ylabel('Force Input [N]');

subplot(2,1,2)
plot(t,y);
xlabel('Time [s]');
ylabel('Displacement [m]');

%% 状態空間モデルを利用した微分方程式の定義
function xdot = func_ss(t,x,sys,u)
xdot=sys.A*x+sys.B*u(t);
end

%% システムに対する入力を関数として定義
function ans = u(t)
% 入力をシミュレーション時間を表すベクトルとしているため
% 出力もベクトルとして定義する必要がある

% 強制振動の例
% ans = 10*sin(10*t);

% ステップ入力
% (for文を使っているのでいまいちカッコ悪い。もっとかっこよい書き方を募集中)
ans = zeros(length(t),1); % 入力ベクトルと同じ次数のゼロベクトルを作成

for i=1:length(t)
    if t(i)>1.0
        ans(i)=10;
    end
end

end

bode線図の見た目を良くする

MATLABで用意されているbodeコマンドを利用すると、ボード線図がrad/secでプロットされているが、これは機械の分野では一般的ではない。
そこで、以下のような方法で Hz に対しプロットする。ついでに見栄えも整える。
sim_1dof.m の bode(sys) の箇所を plot_bode(sys) に書き換えて実行せよ。
function plot_bode(sys)
% 少し見た目の整ったボード線図を描画

freq = logspace(-1,2,100); % 10^-1 〜 10^2 Hz の範囲で、対数的に等間隔となる配列を生成

% 周波数領域は角周波数として与える必要があることに注意
[mag, phase, w]=bode(sys, freq*2.0*pi);

% 出力される多次元配列を1次元配列に
mag=squeeze(mag);

% ボード線図をプロット
loglog(freq, mag, 'color', [0.0 0.0 1.0], 'linewidth', 2.0);

% 見た目をきれいに
set(gca, 'FontName','Arial');
set(gca, 'FontSize',9);
xlabel('Frequency [Hz]');
ylabel('Gain ');

grid on;

end

1/4車体モデルによるシミュレーション(2)

上のサンプルプログラムをベースに、以下をパラメータとした上下二自由度系について検討せよ。
m1 = 30.0;   m2 = 300.0;
             c2 = 2500;
k1 = 180000; k2 = 30000;
  1. 入力:路面変位, 出力:ばね上変位 としたときのボード線図を求めよ
  2. 入力:路面変位, 出力:ばね上加速度 としたときのボード線図を求めよ
  3. ばねのパラメータを k2 = 45000 および 60000 としたときのゲイン線図の変化を調べよ。
  4. ダンパのパラメータを c2 = 1500 および 3500 としたときのゲイン線図の変化を調べよ。
  5. ステップ応答・正弦波応答などをMATLABを利用してシミュレーションせよ。
  6. 実際のダンパは以下の図のような特性となっている。このダンパの特性を考慮したシミュレーションを実行せよ。

課題6 サンプルプログラム

% 非線形ダンパ特性を考慮したシミュレーション

%% 初期化
% ウィンドウを閉じる
clear;
close all;

%% 状態空間モデルを作成
% System Definition
m1 = 30.0; m2 = 300.0;
c2 = 0;
k1 = 180000; k2 = 30000;

sys=sysdef(m1,m2,c2,k1,k2);

v_dmp=[-0.250:0.01:0.250];

figure(1);
set(gcf, 'Position', [100 100 640 480]);
plot(1000*v_dmp,damper_fv(v_dmp),'Color',[0 0 1],'linewidth',3.0);
grid on;

plot_time_history(sys, [1 0 0],m1,m2);

%% 状態空間モデルの作成
function sys=sysdef(m1,m2,c2,k1,k2)
    A=[ 0 0 1 0;
    0 0 0 1;
    -(k1+k2)/m1 k2/m1 -c2/m1 c2/m1;
    k2/m2 -k2/m2 c2/m2 -c2/m2; ];
    
    B=[0; 0; k1/m1; 0];
    
    % 出力:ばね上変位
    C=[0 1 0 0];
    D=[0];
    
    sys=ss(A,B,C,D);
end

%% ode45を使った数値積分
function plot_time_history(sys,color,m1,m2)
    x0 = [0;0;0;0];
    time = [0:0.01:3];

    [t,x] = ode45(@(t,x) func_nl_damper(t,x,sys,@(t) u(t),m1,m2),time,x0,[]);
    % 出力ベクトルの計算
    y = (sys.C*x' + sys.D*u(t)')';

    % グラフのプロット
    figure(2);
    set(gcf, 'Position', [800 100 640 480]);
    plot(t,y,'Color',color,'linewidth',3.0); hold on;
    set(gca,'FontName','Arial');
    set(gca,'FontSize',14);
    xlabel('time[s]');
    ylabel('Displacement [m]');
    grid on;
end

%% 状態空間モデルを利用した微分方程式を応用
function xdot = func_nl_damper(t,x,sys,u,m1,m2)
    % ダンパのストロークスピード
    velo_damper = x(4)-x(3);

    xdot=sys.A*x+sys.B*u(t) ...
    + - [0 0 -1/m1 1/m2]'* damper_fv(velo_damper);
end

function force = damper_fv(velo_damper)
    for i=1:length(velo_damper)
        if velo_damper(i) > 0.025
            force(i) = 10000 * (velo_damper(i)-0.025) + 500;
        elseif velo_damper(i) > 0.000
            force(i) = 20000 * velo_damper(i);
        elseif velo_damper(i) > -0.025
            force(i) = 10000 * velo_damper(i);
        else
            force(i) = 5000 * (velo_damper(i)+0.025) -250;
        end
    end
end

%% システムに対する入力を関数として定義
function ans = u(t)
    % 強制振動
    ans = 0.010*sin(2*pi*1.5*t);
end