MATLABの内部構造を解析する
MATLABには、ユーザーが独自にMATLABのユーザーインターフェースをカスタマイズするための仕組みが用意されています。(独自メニューを追加するとか、既存メニューを見えなくするとか)。Simulinkブロックをすばやく配置できたでご紹介したツールなんかも、その仕組みを使ってSimulinkに右クリックメニューを追加しています。
それはたいがい、「m-fileでコールバック関数を書いておくと、MATLABがそれを呼び出してくれる」という形式を取るのですが、そのコールバック関数の仕様はしっかりとドキュメント化されていない事が多いです。
たとえば、Simulinkに右クリックメニューを追加したとしましょう。その「右クリックメニュー」がクリックされたら、MATLABは(ユーザーが書いた)コールバック関数を呼び出すようになっています。そのコールバック関数の中に「特定のSimulinkブロックを、右クリックされた場所に配置する」というような処理を書くことで、Simulinkブロックをすばやく配置できたでご紹介したツールが出来上がります。
さて、そのコールバック関数には引数が渡されるのですが、それがどんな情報をもっているのかドキュメントにハッキリと書かれてはいません。上記の例であれば「ユーザーがどの座標で右クリックしたのか?」はぜひ知りたいところです。(クリックされた座標に、ブロックを置きたい)。ところが、それをどうやって知れば良いのかはドキュメント化されていないようです。
こういったケースでは、マスワークスさんに問い合わせをするか、自分で調べるかしないといけません。今回の記事のテーマは、「どうやって、コールバック関数の引数が持つ構造を、自分で調べたらいいだろう?」です。
先に答えを書いてしまうと、「ブレークポイント入れおくといいよ。ブレークがかかった時に、ワークスペース変数のビューを見るとすべて分かるから」です。これで納得されてしまった方は・・・ここでお別れです。
MATLABのデバッガを使うには
MATLABには、m-fileで書いたスクリプトをデバッグするための機能が備わっています。デバッガで出来ることは、
- m-fileの特定位置でブレーク(一時停止)する
- ブレーク時に、MATLAB変数をモニターする
などです。(本当はもっといっぱいあります。ご興味があれば、調べてみてください。)
さて、デバッガを使おうとする場合、はじめにやるのは「ブレークポイントの設定」です。ブレークポイントというのは、下図のようにm-fileの特定行に対して指定するもので、MATLABがこの行(ブレークポイントが設定された行)を実行しようとするときに、一時停止するようになります。(ちなみに、一時停止するタイミングは「赤丸のついた行を実行する直前」です。)
MATLABのエディタでm-fileを開いたところ
ブレークポイントを設定するには、MATLABのエディタでm-fileを開きます。そして、行番号の右どなりをクリックします。すると、上図のような赤丸がつきます。(もう1回クリックすると解除)
やるべき事は、これだけです。あらかじめブレークポイントさえ指定しておけば、m-fileが実行されたタイミングで自動的にブレークがかかります。
実行されたタイミングとは、MATLABのコマンドウィンドウから実行されたとか、コールバック関数として呼び出されたとか、色々です。デバッグをするのだから特別なm-file呼び出し方法をしなくっちゃ、というような心配は無用で、ブレークポイントさえ指定しておけばどんな場合でもフツーに一時停止してくれます。
コールバックにブレークポイントを入れ、引数を解析する
さて、Simulinkブロックをすばやく配置できたで使用した sl_customization.m を例に、コールバック関数の内容を解析してみましょう。やることは簡単で、コールバック関数のところにブレークポイントを入れる(赤丸をつける)だけです。
実は、前章に掲載した図がそれで、sl_customization.mの127行目にブレークポイントを入れてあります。
124行目から始まっている、function placeBlock( callbackInfo ) というのが着目しているコールバック関数で、これはユーザーが右クリックメニューをクリックしたときに呼び出されます。そして、ここに渡される引数 callbackInfo の中身を知りたいと思っています。というのも、右クリックのコールバック関数なんだから、クリック位置情報くらい持ってるんじゃないかなぁ。。。と思えるからです。
さっそくやってみましょう。127行目に赤丸を入れた状態で、Simulinkモデルを右クリックし、「Scopeを配置する」メニューをクリックしてみます。すると、次のような画面になります。赤丸の隣に、「緑色の矢印」があるのが見えますでしょうか?これが、「今、ここで一時停止してるよ」というしるしです。
127行目でブレークしている
さて、ここでMATLAB画面のほうを開き、ワークスペース変数が並んでいるビューを見てみます。すると、こんな感じになっています。
変数 callbackInfo が存在する
ここで、callbackInfoをダブルクリックすると、その中身が見られます。
4つのメンバーが存在する
むむむ? mouseClickPosition というのもがあるじゃないですが。んー、すごくそれっぽい!ということで、黄色の田マークをクリックしてみますと・・・
変数が2つ
X-Y座標っぽい!まず間違いないでしょう。
とまぁ、こんなノリで欲しい情報を探していきます。
なお、解析がすんだらブレークポイントは外しておく事をお忘れなく。そして、エディタ画面にて「F5」キーを押すことで、一時停止が解除されm-fileの続きが実行されます。
まとめ
今回のテーマは、「どうやって、コールバック関数の引数が持つ構造を、自分で調べたらいいだろう?」というものでした。それに対する答えは、「デバッガを使って動かしてみる事で、変数の内容を実際にみてみよう」というものです。
こんな感じで、MATLABにはドキュメント化されていない領域がいくつもあり、それに対しては独自に調べるしかないケースも多々あります。こうしてこれまで調べまくった色々な情報がノウハウとなって、ツール屋さんとしてのメシのタネになったりしています。
とは言え、こういうのはあまり本質的なノウハウではなく、ちょっと調べれば誰でも分かってしまうものです。ですから、あまり隠すつもりもありません。機会があれば、また何かご紹介できたらと思っています。
やっぱり、MATLABってドキュメントになっていないものって結構あるんですね。まぁ、もしかしたら、だからサポートは切らずに保守しましょうという作戦なのかもしれませんが^^;
ドキュメントも重要なのですが、やはりこういう困ったときは、どうやって調べるかもコツが必要で、ある程度スキルを積めば、こうやって調べればあたりがつけられるとかもありますが、何よりも初心者にとっては、なんという単語でグーグル先生に聞けば、答えにありつけるかが難しいですよね。右クリックとかsimulinkとかメニューとかだと、大量にひっかかってしまいますし。。
このようなテクニックなどを享受できるサイトは私のような初心者には、大変ありがたい情報で今回も吉武さまに感謝です。
コメントありがとうございます。とても励みになります。
「困ったときにどうやって調べるか」も重要というのは、まさしく通りすがりのSL初心者様のおっしゃる通りですね。
仮にMATLABのすべてがドキュメント化されていたとしても、膨大な資料をあたるのは面倒ですし ^^;
いつもお世話になっております。とても面白いお話でしたのでコメントを…
VBAレベルの話で恐縮なのですが、昔、仕事でWordの本文とヘッダとフッタがそれぞれ別のルールでバラバラにパラメータを保持している事に気づくのに似た経験をしました。
MicrosoftもMWと同じ様な事を考えていたのかなぁと一瞬思いましたが、Excelがあれだけ綺麗にパラメータを管理しているのを思うと、やっぱりOOP過渡期の混乱の名残なのでしょうか。。。
とても勉強になりました、ありがとうございます。
いつもお世話になっております。コメントありがとうございます。
Word開発チームとExcel開発チームは、メンバーから開発方針まで完全に別々のようです。おっしゃるとおり、狙ってやっている訳ではないような気がしますね。。。(もちろん、MWさんもワザとしてる訳じゃないと思います)