関数findのエラーについて 【MATLAB function Simulinkブロック】

find関数の後にERRORが発生してしまいます
Simulinkの診断ビューワーには、以下のような表示がされていました。
MATLABのプログラム初心者なので配列の何が問題なのかよく分かりません。
インデックスが配列の次元を超えています。インデックス値 2 は配列 dd の有効範囲 [1 ~ 1] を超えています。
Error in 'test/MATLAB Function1'
dd(k,1) = Td(1,zz(1,1));
function [a,b,c,d] = fcn(u, g, ms, x2, T, d)
amx=g*ms;
xd = -50:0.5:0;
yy2 = 1:0.25:4;
ny2 =length(yy2);
for k=1:ny2
y2 = yy2(1,k);
       y1=zeros(1,length(xd));
Td=zeros(1,length(xd));
Vr=zeros(1,length(xd));
Tr=zeros(1,length(xd));
for i=1:length(xd)
yd1(1,i) = -y2*xd(1,i)/(x2-xd(1,i))-d/2;
Td(1,i) = ((yd1(1,i))/100);
Vr(1,i) = amx * ((T^2+(-4*xd(1,i))/2));
Tr(1,i) = (-xd(1,i)/Vr(1,i));
end
zz = find(Td>Tr);
dd= zeros(length(k),1);  
dr = zeros(length(k),1);
dxpd = zeros(length(k),1);
dypd = zeros(length(k),1);
dVr = zeros(length(k),1);
dy2 = zeros(length(k),1);
dd(k,1) = Td(1,zz(1,1));     %% ※ERROR が発生する箇所
dr(k,1) = Tr(1,zz(1,1));     %% ※ERROR が発生する箇所
dxpd(k,1) = xd(1,zz(1,1));    %% ※ERROR が発生する箇所
dypd(k,1) = yd1(1,zz(1,1));    %% ※ERROR が発生する箇所
dVr(k,1) = Vr(1,zz(1,1))*3; %% ※ERROR が発生する箇所
dy2(k,1) = y2-1/2;
%{
~~~~プログラム途中省略~~~~~~
%}
end
y = u;

 Accepted Answer

michio
michio on 9 Dec 2019
for ループ内の
dd= zeros(length(k),1);
では dd は 1x1 の配列で定義されてしまっているので、dd(2,1) との参照ができないのかと思います。
dd= zeros(length(k),1);  
dr = zeros(length(k),1);
dxpd = zeros(length(k),1);
dypd = zeros(length(k),1);
dVr = zeros(length(k),1);
dy2 = zeros(length(k),1);
を k のループ開始前に length(k) を ny2 に変えて定義するというのはいかがでしょう?

11 Comments

s
s on 9 Dec 2019
ありがとうございます。
お陰様でシミュレーションが動作しました。
計算時間が長くなりましたが、MATLAB function は計算負荷が大きいのでしょうか?
よかったです。
MATLAB Function 自体が計算負荷が大きいというのは特に聞いたことがありませんが、、何と比較して速度が長くなりましたか?
s
s on 9 Dec 2019
スクリプト.mファイルと比較した場合です。
もともと、スクリプト.mファイル(出力された変数はワークスペースに定義)でしたが、Simulinkでもリアルタイムで演算してシミュレーションを動かすために今の改良を行っています。
そうなんですね。ワークスペースに定義された変数の処理と、Simulink と一緒に動かすのとでは厳密に比較は難しいかもしれません。
ただ記載して頂いたコードで改善できそうな点は2つあります。どれくらい速度に影響あるかは分かりませんが。
1つ目
y1=zeros(1,length(xd));
Td=zeros(1,length(xd));
Vr=zeros(1,length(xd));
Tr=zeros(1,length(xd));
は for ループの外側にだして繰り返さないようにしたほうがいいかもしれません。また、y1yd1 の間違いでしょうか。
2つ目
for i=1:length(xd)
yd1(1,i) = -y2*xd(1,i)/(x2-xd(1,i))-d/2;
Td(1,i) = ((yd1(1,i))/100);
Vr(1,i) = amx * ((T^2+(-4*xd(1,i))/2));
Tr(1,i) = (-xd(1,i)/Vr(1,i));
end
は以下のようにベクトル化したくなります。(同じ結果となるかどうかは確認ください)
yd1 = -y2*xd./(x2-xd)-d/2;
Td = yd1/100;
Vr = amx * ((T.^2+(-4*xd/2));
Tr = -xd./Vr;
失礼しました。
おっしゃるとおり y1→yd1 です。
すいません。もう1点ペーストミスがありました。
Vrの式にVr(1,i) = amx * (★T+(T^2+(-4*xd(1,i))/2));
の部分が抜けておりました。
for i=1:length(xd)
yd1(1,i) = -y2*xd(1,i)/(x2-xd(1,i))-d/2;
Td(1,i) = ((yd1(1,i))/100);
Vr(1,i) = amx * ((T^2+(-4*xd(1,i))/2));
Tr(1,i) = (-xd(1,i)/Vr(1,i));
end
yd1 = -y2*xd./(x2-xd)-d/2;
Td = yd1/100;
Vr = amx * (T+(T.^2+(-4*xd/2));
Tr = -xd./Vr;
この場合単純にT+するとおかしくなると思いますが、問題ないでしょうか?
michio
michio on 9 Dec 2019
Edited: michio on 10 Dec 2019
Vr = amx * (T+(T.^2+(-4*xd/2));
かっこの数が合っていないですね、すいません。適宜変更ください。
単純にT+でも、Tがスカラーであれば問題ないと思います。
s
s on 9 Dec 2019
Tは固定値でスカラーのはずで、カッコの数も合わせていますがエラーが出てしまいます。
michio
michio on 10 Dec 2019
どんなエラーメッセージが出ていますか?何か状況が分かるものがあれば。。
何度も申し訳ありません、色々プログラムと数式を精査をした最終的に以下の式になります。
Vr = amx*(-T+(T.^2+(-4*xd)/(2*amx))^0.5);
<エラー内容>
十分な情報がないため、このブロックの出力サイズを判別できません。以下のエラーに該当しないと考えられる場合は、ブロック入力の型やブロック出力のサイズを指定してみてください。
コンポーネント:MATLAB Function | カテゴリ:Coderエラー
正方行列でなければなりません。
関数 'MATLAB Function1' (#48.1713.1742)、行 42、列 25:
"(T.^2+(-4*xped)/(2*amax))^0.5"
診断レポートを起動してください。
試しに・・
Vr = amx*(-T+(T.^2+(-4*xd)/(2*amx)).^0.5);
と ^0.5 の前に . を追加するとどうですか?
s
s on 16 Dec 2019
ありがとうございます。最初のスクリプト.mファイルと同じ数値が算出できました。

Sign in to comment.

More Answers (0)

Categories

Find more on 一般分野への適用 in Help Center and File Exchange

Asked:

s
s
on 9 Dec 2019

Commented:

s
s
on 16 Dec 2019

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!