matlabで直動型倒立振子をしたいですM = 4.4; m = 0.1; l = 0.115; g = 9.81; b = 5; o = 0.006; J = m*l^2/3;Ts = 0.001; T = 10; N = round(T/Ts)+1; t = (0:N-1)*Ts; x = [0; 0; 181*pi/180; 0]; XX = zeros(4, N); XX(:,1) = x; U = zeros(1,N); THDD = zeros(1,N); function dx = dynamics_with_u(x, u, M, m, l, g, b, o, J) zd = x(2); th = x(3); thd = x(4); MM = [M+m, m*l*cos(th); m*l*cos(th), J+m*l^2]; RHS = [ m*l*thd^2*sin(th) - b*zd + u; m*g*l*sin(th) - o*thd ]; acc = MM \\ RHS; dx = [zd; acc(1); thd; acc(2)]; end U(N) = U(N-1); THDD(N) = THDD(N-1); A = [1 0 0 0; 0 M+m 0 m*l; 0 0 1 0; 0 m*l 0 J+m*l^2;]; B = [0 1 0 0; 0 -b 0 0; 0 0 0 1; 0 0 m*g*l o;]; C = [0; 1; 0; 0;]; Q = [0.1,0,0,0; 0,1,0,0; 0,0,1,0; 0,0,0,1;]; R = 1; F = lqr(A\\B,C,Q,R); %% --- 時間ループ --- for k_idx = 1:N-1 th = x(3); thd = x(4); z = x(1); acc_now = dynamics_with_u(x, 0, M, m, l, g, b, o, J); thdd_now = acc_now(4); x_ctrl = x; x_ctrl(3) = wrapToPi(x(3)); if abs(z) \u0026lt;= 0.75 if abs(wrapToPi(th)) \u0026gt;= 20*pi/180 if abs(th-pi) \u0026lt;= abs(90*pi/180) u = 5.5*thd; else u = 0; end else u = F*x_ctrl; end else u = 0; end if abs(u) \u0026lt; 1e-1 x(2) = 0; end % --- RK4で状態更新 --- f = @(x_in) dynamics_with_u(x_in, u, M, m, l, g, b, o, J); k1 = f(x); k2 = f(x + Ts/2*k1); k3 = f(x + Ts/2*k2); k4 = f(x + Ts*k3); x = x + Ts/6*(k1 + 2*k2 + 2*k3 + k4); THDD(k_idx) = k1(4); XX(:,k_idx+1) = x; U(k_idx) = u; end th_wrapped = wrapToPi(XX(3,:)); % --- グラフ表示 --- figure('Color','w'); subplot(3,1,1) plot(t,XX(3,:)*180/pi, 'LineWidth',1) yline(0,'k--'); yline(360,'k--'); yline(180,'k--'); ylabel('\\theta [deg]') title('振子の角度') grid on subplot(3,1,2) plot(t, U, 'LineWidth',1) ylabel('u [N]') title('入力') grid on subplot(3,1,3) plot(t, XX(1,:), 'LineWidth',1) yline(+0.75,'k--');yline(-0.75,'k--'); ylabel('z [m]') xlabel('時間 [s]') title('位置') grid on自分でやってみたのですが何もかもダメダメです ろくに制御方法も使えてなくてごり押しです 誰か正しい倒立振子のコード教えて下さいお願いします 調べてもわかりませんでした。

1件の回答

回答を書く

1283938

2026-01-29 00:05

+ フォロー

MATLABでの直動型倒立振子のシンプルなLQR制御例を示します。

あなたのコードは状態空間やLQR設計、制御入力の計算が混乱しているので、整理したものを提示します。



matlab

% --- パラメータ ---

M = 4.4; m = 0.1; l = 0.115; g = 9.81; b = 5; o = 0.006; J = m*l^2/3;

Ts = 0.001; T = 10; N = round(T/Ts)+1; t = (0:N-1)*Ts;



% --- 初期状態 [位置; 速度; 角度; 角速度] ---

x = [0; 0; pi + 1*pi/180; 0]; % 小さく傾けて開始

XX = zeros(4,N); XX(:,1) = x;

U = zeros(1,N);



% --- 状態空間線形化(倒立振子線形モデル) ---

A = [0 1 0 0;

0 -b/(M+m) m*g/(M+m) 0;

0 0 0 1;

0 -b*l/(J+m*l^2) m*g*l/(J+m*l^2) -o/(J+m*l^2)];

B = [0; 1/(M+m); 0; l/(J+m*l^2)];



Q = diag([10,1,100,1]);

R = 0.01;



% --- LQRゲイン計算 ---

F = lqr(A,B,Q,R);



% --- 動的シミュレーション(非線形モデル) ---

for k = 1:N-1

th = x(3); thd = x(4);

x_lin = x;

x_lin(3) = wrapToPi(th); % 角度を[-pi,pi]に正規化

u = -F*x_lin;

U(k) = u;



% --- 非線形RK4 ---

f = @(x,u) [

x(2);

(u - b*x(2) + m*l*x(4)^2*sin(x(3)))/(M+m);

x(4);

(m*g*l*sin(x(3)) - o*x(4) + u*l - m*l*x(4)^2*sin(x(3))*l)/(J+m*l^2)

];

k1 = f(x,u);

k2 = f(x + Ts/2*k1,u);

k3 = f(x + Ts/2*k2,u);

k4 = f(x + Ts*k3,u);

x = x + Ts/6*(k1 + 2*k2 + 2*k3 + k4);

XX(:,k+1) = x;

end



% --- グラフ表示 ---

figure('Color','w');

subplot(3,1,1)

plot(t, wrapToPi(XX(3,:))*180/pi, 'LineWidth',1)

ylabel('\\theta [deg]'); grid on; title('振子の角度')



subplot(3,1,2)

plot(t, U, 'LineWidth',1)

ylabel('u [N]'); grid on; title('入力')



subplot(3,1,3)

plot(t, XX(1,:), 'LineWidth',1)

yline(0.75,'k--'); yline(-0.75,'k--');

ylabel('z [m]'); xlabel('時間 [s]'); grid on; title('カート位置')





ポイント:



* LQR設計は倒立振子線形化モデルで計算

* 非線形シミュレーションはRK4で更新

* 角度は wrapToPi で [-pi,pi] に正規化

* 状態フィードバックは
u = -F*x

うったえる有益だ(0シェアするブックマークする

Copyright © 2026 AQ188.com All Rights Reserved.

博識 著作権所有