メインコンテンツ

このページは機械翻訳を使用して翻訳されました。最新版の英語を参照するには、ここをクリックします。

CAN 通信用の Simulink モデルをプログラムで構築する

この例では、CAN DBC ファイルを使用して CAN または CAN FD 通信を導入するための Simulink ® モデルをプログラムで構築する方法を示します。Simulink の add_block (Simulink) 関数と set_param (Simulink) 関数を使用すると、Vehicle Network Toolbox ™ ブロックを追加して完全に構成し、基本アルゴリズムにネットワーク通信を追加できます。DBC ファイルには、CAN メッセージと信号の詳細が含まれています。主な焦点は、CAN および CAN FD の Pack および Unpack ブロック パラメータをプログラムで構成することです。これにより、モデル構築の効率が大幅に向上します。

アルゴリズムモデル

サンプルモデル AlgorithmModel.slx には、「アルゴリズム」と呼ばれるサブシステム ブロックが含まれています。このブロックは、Simulink で開発された任意のアプリケーション アルゴリズムを表します。値が 2 の Gain (Simulink) ブロックは、デモンストレーションの目的でこのサブシステム内にあります。このサブシステムには、「In1」という名前の CAN 信号入力があります。この入力値はゲイン値によってスケーリングされます。スケールされた値は、このサブシステムの「Out1」という名前の出力として与えられます。実験のために、ゲイン値を変更したり、Gain ブロックを別のアルゴリズムに置き換えたりすることができます。

CANデータベースファイルアクセス

canDatabase 関数を使用して、CAN DBC ファイルの内容にアクセスできます。この関数により、ネットワーク ノード、メッセージ、信号に関する詳細情報を入手できます。

db = canDatabase("CANBus.dbc")
db = 
  Database with properties:

             Name: 'CANBus'
             Path: 'C:\Users\jpyle\Documents\MATLAB\Examples\vnt-ex60686316\CANBus.dbc'
            Nodes: {'ECU'}
         NodeInfo: [1×1 struct]
         Messages: {2×1 cell}
      MessageInfo: [2×1 struct]
       Attributes: {}
    AttributeInfo: [0×0 struct]
         UserData: []

以下に示すように、サンプル CAN DBC ファイルではノード「ECU」が定義されています。

node = nodeInfo(db,"ECU")
node = struct with fields:
             Name: 'ECU'
          Comment: ''
       Attributes: {}
    AttributeInfo: [0×0 struct]

ノードは、信号「InitialValue」を含む CAN メッセージ「AlgInput」を受信します。信号「InitialValue」はアルゴリズムへの入力です。

messageInfo(db,"AlgInput")
ans = struct with fields:
             Name: 'AlgInput'
     ProtocolMode: 'CAN'
          Comment: ''
               ID: 100
         Extended: 0
            J1939: []
           Length: 1
              DLC: 1
              BRS: 0
          Signals: {'InitialValue'}
       SignalInfo: [1×1 struct]
          TxNodes: {0×1 cell}
       Attributes: {}
    AttributeInfo: [0×0 struct]

ノードは、信号「ScaledValue」を含む CAN メッセージ「AlgOutput」を送信します。信号「ScaledValue」はアルゴリズムの出力です。

messageInfo(db,"AlgOutput")
ans = struct with fields:
             Name: 'AlgOutput'
     ProtocolMode: 'CAN'
          Comment: ''
               ID: 200
         Extended: 0
            J1939: []
           Length: 2
              DLC: 2
              BRS: 0
          Signals: {'ScaledValue'}
       SignalInfo: [1×1 struct]
          TxNodes: {'ECU'}
       Attributes: {}
    AttributeInfo: [0×0 struct]

プログラムでモデルを構築する

モデル例を開く

設定するサンプルモデルを開きます。

open AlgorithmModel

CAN Configurationブロックの追加と設定

モデルに CAN Configuration ブロックを追加して配置します。

add_block("canlib/CAN Configuration","AlgorithmModel/CAN Configuration")
set_param("AlgorithmModel/CAN Configuration","position",[50,330,250,410])

モデルが MathWorks ® 仮想 CAN デバイスを使用するように、「デバイス」パラメータを設定します。

set_param("AlgorithmModel/CAN Configuration","Device","MathWorks Virtual 1 (Channel 1)")

CAN Receiveブロックの追加と設定

モデルに CAN Receive ブロックを追加して配置します。

add_block("canlib/CAN Receive","AlgorithmModel/CAN Receive")
set_param("AlgorithmModel/CAN Receive","position",[50,200,250,280])

Terminator (Simulink) ブロックを追加して配置します。これは、CAN Receive ブロックの関数ポートを接続するために使用されます。この例では、単純なメッセージ受信が実行されます。一般的に、CAN ブロックを使用してモデリングする場合、CAN Receive を Function-Call Subsystem (Simulink) 内に配置するのが推奨されるアプローチです。

add_block("simulink/Sinks/Terminator","AlgorithmModel/Terminator")
set_param("AlgorithmModel/Terminator","position",[310,210,330,230])

モデルが MathWorks 仮想 CAN デバイスを使用するように、「デバイス」パラメータを設定します。

set_param("AlgorithmModel/CAN Receive","Device","MathWorks Virtual 1 (Channel 1)")

CAN Unpack ブロックの追加と設定

モデルに CAN Unpack ブロックを追加して配置します。デフォルトでは、ブロックは「Raw Data」モードになっています。

add_block("canlib/CAN Unpack","AlgorithmModel/CAN Unpack")
set_param("AlgorithmModel/CAN Unpack","position",[350,220,600,300])

1 回の関数呼び出しで、CAN Unpack ブロックに次のパラメータを設定します。

  • DataFormat

  • CANdbファイル

  • MsgList

set_param("AlgorithmModel/CAN Unpack","DataFormat","CANdb specified signals","CANdbFile",db.Path,"MsgList","AlgInput")

ブロックに「DataFormat」および「CANdbFile」パラメータがすでに設定されている場合、「MsgList」パラメータを追加するだけで選択したメッセージを変更できます。

CAN Pack ブロックの追加と設定

モデルに CAN Pack ブロックを追加して配置します。

add_block("canlib/CAN Pack","AlgorithmModel/CAN Pack")
set_param("AlgorithmModel/CAN Pack","position",[1000,220,1250,300])

1 回の関数呼び出しで、CAN Pack ブロックに次のパラメータを設定します。

  • DataFormat

  • CANdbファイル

  • MsgList

set_param("AlgorithmModel/CAN Pack","DataFormat","CANdb specified signals","CANdbFile",db.Path,"MsgList","AlgOutput")

CAN Transmit ブロックの追加と設定

モデルに CAN Transmit ブロックを追加して配置します。

add_block("canlib/CAN Transmit","AlgorithmModel/CAN Transmit")
set_param("AlgorithmModel/CAN Transmit","position",[1350,220,1550,300])

モデルが MathWorks 仮想 CAN デバイスを使用するように、「デバイス」パラメータを設定します。また、デフォルトのタイミングで定期送信が有効になります。

set_param("AlgorithmModel/CAN Transmit","Device","MathWorks Virtual 1 (Channel 1)")
set_param("AlgorithmModel/CAN Transmit", "EnablePeriodicTransmit", "on")

ブロック間の接続を作成する

モデルに追加された CAN ブロックとアルゴリズム ブロックを接続する必要があります。すべての CAN ブロックのポート座標が必要です。

canRxPort = get_param("AlgorithmModel/CAN Receive","PortConnectivity");
canUnpackPort = get_param("AlgorithmModel/CAN Unpack","PortConnectivity");
subSystemPort = get_param("AlgorithmModel/Subsystem","PortConnectivity");
canPackPort = get_param("AlgorithmModel/CAN Pack","PortConnectivity");
canTxPort = get_param("AlgorithmModel/CAN Transmit","PortConnectivity");
terminatorPort = get_param("AlgorithmModel/Terminator","PortConnectivity");

[canRxPortFunc,canRxPortMsg] = canRxPort.Position;
[canUnpackPortIn,canUnpackPortOut] = canUnpackPort.Position;
[subSystemPortIn,subSystemPortOut] = subSystemPort.Position;
[canPackPortIn,canPackPortOut] = canPackPort.Position;
canTxPortMsg = canTxPort.Position;
terminatorPortIn = terminatorPort.Position;

すべてのブロックを適切な順序で接続する線を追加します。

add_line("AlgorithmModel",[canRxPortMsg ; canUnpackPortIn])
add_line("AlgorithmModel",[canUnpackPortOut ; subSystemPortIn])
add_line("AlgorithmModel",[subSystemPortOut ; canPackPortIn])
add_line("AlgorithmModel",[canPackPortOut ; canTxPortMsg])
add_line("AlgorithmModel",[canRxPortFunc ; terminatorPortIn])

完成モデル

モデルの構築と構成後の外観は次のようになります。

構築したモデルをテストする

アルゴリズムモデルとの通信用にMATLABのCANチャネルを構成する

MathWorks 仮想 CAN デバイスのチャネル 2 を使用して、MATLAB ® に CAN チャネルを作成します。モデル内の CAN チャネルと通信します。また、CAN データベースを MATLAB チャネルに接続して、受信した CAN データを自動的に復号化するようにします。

canCh = canChannel("MathWorks","Virtual 1",2);
canCh.Database = db;

MATLAB からモデルへの送信では、CAN データベースを使用して、アルゴリズムへの入力として CAN メッセージを準備します。

algInputMsg = canMessage(canCh.Database,"AlgInput");

アルゴリズムモデルを実行する

シミュレーション時間を割り当ててシミュレーションを開始する

set_param("AlgorithmModel","StopTime","inf")
set_param("AlgorithmModel","SimulationCommand","start")

シミュレーションが完全に開始されるまで一時停止します。

while strcmp(get_param("AlgorithmModel","SimulationStatus"),"stopped")
end

MATLABコードを実行する

MATLAB CAN チャネルを開始します。

start(canCh);

モデルへの入力として、異なる信号データを持つ複数の CAN メッセージを送信します。

for value = 1:5
    algInputMsg.Signals.InitialValue = value*value;
    transmit(canCh,algInputMsg)
    pause(1)
end

バスからのすべてのメッセージを受信します。「AlgInput」および「AlgOutput」メッセージのインスタンス、それらのタイミング、および信号値に注意してください。

msg = receive(canCh,Inf,"OutputFormat","timetable")
msg=10×8 timetable
        Time        ID     Extended        Name            Data        Length      Signals       Error    Remote
    ____________    ___    ________    _____________    ___________    ______    ____________    _____    ______

    0.009728 sec    100     false      {'AlgInput' }    {[      1]}      1       {1×1 struct}    false    false 
    0.15737 sec     200     false      {'AlgOutput'}    {1×2 uint8}      2       {1×1 struct}    false    false 
    1.0121 sec      100     false      {'AlgInput' }    {[      4]}      1       {1×1 struct}    false    false 
    1.1574 sec      200     false      {'AlgOutput'}    {1×2 uint8}      2       {1×1 struct}    false    false 
    2.0146 sec      100     false      {'AlgInput' }    {[      9]}      1       {1×1 struct}    false    false 
    2.1574 sec      200     false      {'AlgOutput'}    {1×2 uint8}      2       {1×1 struct}    false    false 
    3.0177 sec      100     false      {'AlgInput' }    {[     16]}      1       {1×1 struct}    false    false 
    3.1574 sec      200     false      {'AlgOutput'}    {1×2 uint8}      2       {1×1 struct}    false    false 
    4.0219 sec      100     false      {'AlgInput' }    {[     25]}      1       {1×1 struct}    false    false 
    4.1574 sec      200     false      {'AlgOutput'}    {1×2 uint8}      2       {1×1 struct}    false    false 

canSignalTimetable 関数は、CAN メッセージの信号値をそれぞれ個別の timetable に分離して整理する効率的な方法を提供します。

signalTimeTable = canSignalTimetable(msg)
signalTimeTable = struct with fields:
     AlgInput: [5×1 timetable]
    AlgOutput: [5×1 timetable]

signalTimeTable.AlgInput
ans=5×1 timetable
        Time        InitialValue
    ____________    ____________

    0.009728 sec          1     
    1.0121 sec            4     
    2.0146 sec            9     
    3.0177 sec           16     
    4.0219 sec           25     

signalTimeTable.AlgOutput
ans=5×1 timetable
       Time        ScaledValue
    ___________    ___________

    0.15737 sec         2     
    1.1574 sec          8     
    2.1574 sec         18     
    3.1574 sec         32     
    4.1574 sec         50     

CAN チャネルを停止します。

stop(canCh)

アルゴリズムモデルを停止する

set_param("AlgorithmModel","SimulationCommand","stop")

信号データをプロットする

仮想バス上で発生したタイムスタンプに対して、CAN メッセージの初期信号値とスケーリングされた信号値をプロットします。MATLAB によって送信された値の変化と、モデルによって実行されたデータのスケーリングに注意してください。

plot(signalTimeTable.AlgInput.Time,signalTimeTable.AlgInput.InitialValue,"Marker","square","MarkerIndices",1:5)
hold on
plot(signalTimeTable.AlgOutput.Time,signalTimeTable.AlgOutput.ScaledValue,"Marker","square","MarkerIndices",1:5)
hold off
xlabel("TimeStamp");
ylabel("CAN Signal Value");
legend("Initial Value","Scaled Value","Location","northeastoutside");
legend("boxoff");