Main Content

外部ハードウェアへの生成された C コードの展開: Raspberry Pi の例

MATLAB® Coder™ を使用して MATLAB の基本アルゴリズムまたは高度なアルゴリズムの C コードを生成してから、アルゴリズムを外部ハードウェア プラットフォームに展開します。これらの例は、Raspberry Pi® プラットフォームの展開シナリオを示しています。Raspberry Pi などのプラットフォームを使用して、より複雑または大規模な展開ワークフローのプロトタイプを作成できます。Raspberry Pi は 32 ビット Linux® オペレーティング システム環境を ARM® プロセッサ上で実行します。

次の図は、Raspberry Pi で実行しているバネ マス ダンパー アルゴリズムの生成コードによって作成されたイメージを示しています。このアルゴリズムの C の main 関数は Linux デバイス ファイル インターフェイスを使用して、USB マウス入力を取得します。

前提条件

  • Raspberry Pi Model 3 B+。Raspberry Pi ハードウェアの古いモデルではパフォーマンスが低下することがあります。

  • ネットワーク アクセスまたは microSD カード リーダーなどの別のファイル転送メカニズム。

  • リモート デスクトップ接続または外部モニター。

  • レイテンシが低い入力用の有線 USB マウス。

ハードウェア実行パラメーター

外部ハードウェアのコードを生成する場合、コード ジェネレーターには coder.HardwareImplementation オブジェクトで指定されたようにハードウェアとプラットフォーム設定の知識が必要です。このオブジェクトには、コード ジェネレーターによって作成された仮定に影響する実装パラメーターが含まれており、予期される動作を実現するために重要です。

たとえば、32 ビット Linux と 8 ビット Arduino® プラットフォームを実行している Raspberry Pi について考えます。Arduino 上の C コンパイラは int に 16 ビットを割り当てますが、Raspberry Pi の場合、C コンパイラは 32 ビットを割り当てます。int 変数宣言を使用する C コードを生成する場合、両方のプラットフォームで同じコードを実行すると、整数オーバーフローの動作が異なる可能性があります。

これらのプラットフォームの違いがあるため、生成されたコードを実行する予定のプラットフォームに固有のハードウェア実行パラメーターを設定します。既定では、パラメーターは MATLAB ホスト プラットフォームに設定されます。MATLAB Coder アプリまたはコマンド ラインを使用してハードウェア パラメーターを設定することも、ハードウェア サポート パッケージを使用することもできます。

アプリまたはコマンド ラインを使用したパラメーターの設定

ハードウェア実行パラメーターを coder.HardwareImplementation から設定するには、MATLAB Coder アプリで構成オブジェクトを開きます。次に例を示します。

cfg = coder.config('lib');
open cfg;

Raspberry Pi の実装パラメーターを設定します。[ハードウェア] ペインをクリックして、[デバイス ベンダー][ARM Compatible] として、[デバイス タイプ][ARM Cortex] として選択します。この選択は、次を入力するのと同じです。

cfg.HardwareImplementation.ProdHWDeviceType = 'ARM Compatible->ARM Cortex';

ProdHWDeviceType パラメーターを設定すると、その他すべての coder.HardwareImplementation パラメーターの適切な設定がトリガーされます。

ハードウェア サポート パッケージを使用したパラメーターの設定

MATLAB Support Package for Raspberry Pi Hardware にアクセスできる場合、Raspberry Pi への接続を MATLAB 環境内から設定できます。coder.HardwareImplementation 設定は、MATLAB Coder アプリで [ハードウェア ボード] メニューから [Raspberry Pi] を選択するか、コマンド ラインに次のように入力すると設定できます。

cfg = coder.config('lib');
hwObj = coder.hardware('Raspberry Pi');
cfg.Hardware = hwObj; 

関数 coder.hardware により coder.Hardware オブジェクトが作成されます。coder.Hardware オブジェクトを構成オブジェクトに割り当てると、それに合わせてハードウェア実行パラメーターが設定されます。

Hello World の例

外部ハードウエアに対する C ソース コードの生成

基本的な MATLAB 関数 Hello World について考えます。

function helloworld %#codegen
fprintf('Hello world!\n');

構成オブジェクトを作成し、ソース コードの生成を指定します。Raspberry Pi のハードウェア実行パラメーターを設定します。

cfg = coder.config('lib','ecoder',false);
cfg.GenCodeOnly = true;
cfg.HardwareImplementation.ProdHWDeviceType = 'ARM Compatible->ARM Cortex';

コードを生成します。

codegen -config cfg helloworld -report

デバイスへのファイルの転送

関数 packNGo を使用して、ファイル転送の生成コードをパッケージ化できます。この関数は必要な生成コード ファイルが含まれる zip ファイルを作成します。関数 packNGo には、実行可能ファイルにコードをコンパイルするために使用できる生成されたメイン ファイルの例は含まれません。生成されたメイン ファイルの例または独自の手書きのメイン ファイルを個別に移動します。

codegen コマンドを入力したディレクトリから、展開用のファイルを収集します。

myBuildInfoFile = 'codegen/lib/helloworld/buildInfo.mat';
load(myBuildInfoFile);
packNGo(buildInfo);

movefile ./codegen/lib/helloworld/examples/main.c
movefile ./codegen/lib/helloworld/examples/main.h

MATLAB を実行しているホスト マシンから外部ハードウェア ターゲットにファイルを転送します。プラットフォームのファイル転送プログラムまたは Raspberry Pi の宛先 IP アドレスを指定した scp などの直接的なコマンドを使用できます。

デバイスのコードのビルド

ファイルをディレクトリに転送したら、ターミナルから、zip ファイルで unzip を実行します。次に、Linux gcc ビルド ツールを使用して実行可能ファイルを作成します。-o オプションを指定して helloworld という名前を付けます。

gcc helloworld.c helloworld_initialize.c helloworld_terminate.c main.c -o helloworld

実行可能ファイルを実行して正常にビルドされたことを確認するには、次のように入力します。

./helloworld

ターミナルに次のような出力が表示されます。

Hello world!

バネ マス ダンパー システムの例

バネ マス ダンパー システムのソース コードの生成

この例は、Raspberry Pi をビルドして実行できるバネ マス ダンパー システムの C ソース コードを生成する方法を示しています。

バネ マス ダンパー モデル

減衰を伴うバネ マス システムは、力学および動力学における基本的なシステムです。運動方程式を使用することにより、さまざまな初期条件と外力に対応して質量の変位の解を求めることができます。

関数 springMassEqns は 2 つの 1 次線形微分方程式の形式で運動方程式をエンコードします。変数 dxdt(1) と変数 dxdt(2) はそれぞれ質量の速度と加速度です。変数 x(1) は質量の位置を表します。

function dxdt = springMassEqns(t,x,x0,k,m,c,F)
dxdt = zeros(2,1);
dxdt(1) = x(2);
dxdt(2) = F/m - k/m*(x(1)-x0) - c/m*x(2);

MATLAB アルゴリズム

時間の関数として変位をシミュレートするために、関数 springMassStep は ODE ソルバー ode45 を運動方程式に適用します。

function [x] = springMassStep(xi,vi,ti,dt,g) %#codegen
% Set spring equilibrium position 
x0 = 1; 
% Set spring, mass, damper constants
k = 1000;
m = 10; 
c = 25; 
% Scale acceleration g like a gravity force
F = m*g;
% Solve ODE for displacement at ti + dt
initCond = [xi vi];
tspan = [ti ti+dt];
[~,x] = ode45(@(t,x) springMassEqns(t,x,x0,k,m,c,F),tspan,initCond);

関数 springMassTakeStep は関数 springMassStep を呼び出し、一定の時間間隔の最後に最終的な変位を返します。

function [xf, vf] = springMassTakeStep(xi,vi,ti,dt,g) %#codegen
% Function springMassTakeStep acts as a wrapper for the ODE solving function, step.
% It takes the same input parameters as springMassStep, but only outputs the final 
% position and velocity. 
x = springMassStep(xi,vi,ti,dt,g);
xf = x(end,1);
vf = x(end,2);

アルゴリズムの結果

モデルの一般的な動作とアルゴリズムを理解するために、スクリプト springMassSim は標準的なパラメーター範囲でシステムをシミュレートします。出力結果に、質量の変位が時間の関数として示されます。初期条件、モデル パラメーター、強制関数を調整して、モデルがどのように応答するかを確認することができます。

springMassSim

C ソース コードの生成

MATLAB モデルが予想どおりに動作することを確認したら、展開用に C ソース コードを生成します。

xi = 0.5;
vi = 0;
ti = 0;
dt = .01;
g = 0;

cfg = coder.config('lib','ecoder',false);
cfg.GenCodeOnly = true;
cfg.HardwareImplementation.ProdHWDeviceType = 'ARM Compatible->ARM Cortex';
codegen springMassTakeStep -args {xi,vi,ti,dt,g} -config cfg -report
Code generation successful: To view the report, open('codegen/lib/springMassTakeStep/html/report.mldatx')

デバイスへのファイルの転送

アルゴリズムの C ソース コードを生成した後、アプリケーション用に例の main.c ファイルと main.h ファイルを変更できます。この例では、添付ファイル springMass_main.c に生成されたコードの使用方法が示されます。対応するヘッダー ファイル springMass_main.h も、サポート ファイルと共に前の例に添付されます。

コードを生成したディレクトリから、展開用のファイルを収集します。

myBuildInfoFile = 'codegen/lib/springMassTakeStep/buildInfo.mat';
load(myBuildInfoFile);
packNGo(buildInfo);

zip ファイルおよび main の .c ファイルと .h ファイルを MATLAB を実行しているホスト マシンからターゲットに転送します。プラットフォームのファイル転送プログラムまたは Raspberry Pi の宛先 IP アドレスを指定した scp などの直接的なコマンドを使用できます。

デバイスのコードのビルド

メイン ファイル.  main 関数 springMass_main.c は生成されたコードを実行して、バネ マス ダンパー システムの変位を経時的にシミュレートします。関数は Raspberry Pi からの USB マウス入力を使用して、質量に力を与えます。力の強度は水平方向のマウス移動の速度に比例します。マウスを動かさない場合、この例は束縛のないダイナミクスをシミュレートします。ダイナミクスの可視化を提供するために、メイン ファイルに質量の位置を経時的に出力するルーチンを含みます。

デバイス ファイル.  マウス入力を使用するには、システムでマウスに対応するデバイス ファイルを特定しなければなりません。Linux プラットフォームの場合、外部 USB デバイス入力は /dev/input/ フォルダーに格納されるデバイス ファイルに記録されます。/dev/input/ フォルダーには通常、複数の入力デバイスのファイルが含まれています。USB マウスに対応するファイルを特定するには、各ファイルの od コマンドを使用して、マウス移動に対応して更新されるファイルを確認します。

od filename

ビルド.  Linux ターミナルからコードをビルドするには、ファイルを転送した場所に移動します。zip ファイルを解凍します。gcc コマンドを使用して、バネ マスの例からすべての .c ファイルを指定します。

gcc *.c -o springMassSim -lm

-lm フラグは必要な C 数学ライブラリにリンクするようコンパイラに指示します。実行可能ファイルを実行するには、前に特定した USB マウスのデバイス ファイルを指定しますが、ここでは、event0 と仮定します。

./springMassSim /dev/input/event0

マウスを移動して、力を質量に適用し、結果のダイナミクスを表示します。質量がマウス移動に応答しない場合、別のデバイス ファイルを指定してみてください。実行中に ctrl + c を入力し、プログラムを終了します。

参考

| |

関連するトピック