4
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

To workspaceブロックの変数名を取得してcsvで保存する

Posted at

はじめに

Simulinkの結果をcsvに保存するときにTo workspaceブロックを使っていますが、
そのときモデル上で配置した順に並べて保存したいというときのメモ。
ブロックから変数名を取得して、その配置順に変数名をラベルとして保存します。

環境

MATLAB2023b Simulink

手順

モデルファイルを準備する

To Workspaceブロックに入力と出力を保存しますが以下の設定で行います。
・モデル設定→単一のシミュレーション出力のチェックを外す
・To Workspaceブロックの保存形式を配列にする

今回は図のように左から右の順に1列ごとずつ保存します。 列はそろえておきます。
左側のモデルはてきとうです。
image.png

↓出力結果
image.png

ブロックのパス・変数名を取得する

mdl = 'GetVarName'; % モデル名
blockpaths = find_system(mdl, 'Type', 'Block')     % 確認用 すべてのブロックのパスを取得

ここでblockpathsの中身は以下のようにブロック名までのパスとなっています。

blockpaths =
    {'GetVarName/Clock'        }
    {'GetVarName/Demux'        }
    {'GetVarName/Demux1'       }
                ︙
    {'GetVarName/To Workspace' }
    {'GetVarName/To Workspace1'}
                ︙

ブロック名は変える可能性があるのでブロックの種類で判別します。
To WorkspaceBlockTypeToWorkspaceとなります。

blocktypes = get_param(blockpaths, 'BlockType')    % 確認用 ブロックの種類を取得
blocktypes =
                ︙
    {'ToWorkspace'}
    {'ToWorkspace'}

ということで、再びfind_systemを実行します。tw_pathsにはBlockTypeToWorkspaceのブロック名のみが入ります。

tw_paths = find_system(mdl, 'BlockType', 'ToWorkspace'); % To Workspaceのブロックのパスを取得

'DialogParameters'で設定できるパラメータを確認します。

tw_params = get_param(tw_paths,'DialogParameters'); % 確認用 使用できるパラメータを取得
tw_params{1} = 
     VariableName: [1×1 struct]
    MaxDataPoints: [1×1 struct]
                    ︙

このうちVariableNameが変数名に対応するため、これを取得します。セル配列となります。

tw_names = get_param(tw_paths, 'VariableName');     % To Workspaceブロックの変数名を取得
tw_names =
    {'x1'}
    {'t1'}
    {'x2'}
    {'y1'}
    {'y2'}

ブロックの位置を取得する

ブロックの位置を取得するときは'Position'プロパティを使います。

tw_positions = get_param(tw_paths, 'Position');         % To Workspaceブロックの位置を取得
tw_positions = 
    {[   955 47 1000 73]}
    {[    850 -25 905 5]}
    {[ 955 107 1000 133]}
    {[  1160 47 1205 73]}
    {[1160 107 1205 133]}

このようにセル配列で返ってきます。1つめがX座標、2つめがY座標の値になります。(左上と右下の座標?)
最初の図の順に保存したいので1列目を基準に並び替えます。
並び替えるときはsortrowsを使うと便利です。1列目に同じ値があるとき2列目を基準に並び替えるため自然と列ごとになります。cell2matでセル配列を行列に変換しています。
このとき、並び替えたインデックスを出力しておき、変数名のセル配列のインデックスとすることで同じ順番に並び替えることができます。

[~, sorted_idx] = sortrows(cell2mat(tw_positions), 1);  % 位置で並び変える
sorted_names = tw_names(sorted_idx);                    % 同じインデックス
sorted_names =
    {'t1'}
    {'x1'}
    {'x2'}
    {'y1'}
    {'y2'}

csvに保存する

Table型を使うと変数名をそのままラベルとして扱えるため、取得したTo Workspaceの変数名をevalに渡し実行します。そのままcsvに保存できます。

T = eval("table("+ strjoin(sorted_names,",") +")")      % 変数名からテーブルを作成
writetable(T, 'out.csv');                               % csvに出力

csvファイルを開くと変数名で保存されています。
image.png

ラベル名を追加・変更したければ、Table型のままでいろいろできます。

全文

mdl = 'GetVarName'; % モデル名

%blockpaths = find_system(mdl, 'Type', 'Block')     % 確認用 すべてのブロックのパスを取得
%blocktypes = get_param(blockpaths, 'BlockType')    % 確認用 ブロックの種類を取得

tw_paths = find_system(mdl, 'BlockType', 'ToWorkspace'); % To Workspaceのブロックのパスを取得

%tw_params = get_param(tw_paths,'DialogParameters'); % 確認用 使用できるパラメータを取得

tw_names = get_param(tw_paths, 'VariableName');     % To Workspaceブロックの変数名を取得

tw_positions = get_param(tw_paths, 'Position');         % To Workspaceブロックの位置を取得
[~, sorted_idx] = sortrows(cell2mat(tw_positions), 1);  % 位置で並び変える
sorted_names = tw_names(sorted_idx);                    % 同じインデックス

T = eval("table("+ strjoin(sorted_names,",") +")")      % 変数名からテーブルを作成
writetable(T, 'out.csv');                               % csvに出力

おわりに

ブロック1つ1つのパラメータも細かく取得できるんだなという感想。
順番を気にすることはないかもしれませんが、csvを中心に扱う場合は使えるかもしれません。

参考

4
3
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
4
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?