TechCraft – エンジニアのためのスキルアップメモ

エンジニアのスキルアップを少しでも加速する技術ブログ

MCFBをC++エンジニアが理解する

MCFB(Motion Control Function Block)をC++エンジニア視点で理解する

〜PLCopen Motion Control規格に見る「制御OOP」の完成形〜

1. はじめに:Motion Control Function Blockとは?

MCFB(Motion Control Function Block)は、
PLCopen Motion Control for IEC 61131-3 で定義された、
モーション制御のための標準化されたファンクションブロック群です。

目的は、

ベンダーを超えて“同じFBで同じ動きをするモーション制御”を実現すること。

つまり、C++でいう共通インターフェース規格(IFクラス)を
PLCの世界で実現したもの、と考えると理解が早いです。


2. 背景:なぜMCFBが生まれたのか?

モーション制御では、ベンダーごとに命令体系がバラバラでした。

メーカー 命令名
Siemens MC_MoveAbsolute()
Mitsubishi MvAbsPos()
Omron P_MoveAbs()
Beckhoff AXIS_MoveAbsolute()

→ 結果、装置の移植や保守が難しい。
→ これを解決するために、PLCopen Motion Control Working Group が標準仕様を作成。

それが「Motion Control Function Block(MCFB)」です。
IEC 61131-3 準拠で、以下のようなFBを統一しました。


3. MCFBの構成(階層的分類)

PLCopen Motion Controlでは、MCFBを以下のカテゴリに分類しています。

レベル 代表FB 説明
Level 1 MC_Power, MC_Home, MC_MoveAbsolute, MC_MoveVelocity 単軸制御(1軸基本動作)
Level 2 MC_CamIn, MC_GearIn, MC_SyncMotion 同期・ギア・カム制御
Level 3 MC_GroupEnable, MC_GroupReadStatus 複数軸のグループ制御
Level 4 MC_ReadParameter, MC_WriteParameter 設定・診断系
Level 5 ユーザ定義拡張FB 高度な動作(補間、パス制御など)

C++で言えば:

class MotionBase {};                  // 抽象インターフェース
class MCFB_MoveAbsolute : public MotionBase {}; 
class MCFB_MoveVelocity : public MotionBase {}; 
class MCFB_Home : public MotionBase {};

というように、「動作単位のクラス群」として理解できます。


4. 基本形:MC_MoveAbsolute の例(STコード)

FUNCTION_BLOCK MC_MoveAbsolute
VAR_INPUT
    Execute : BOOL;
    Position : LREAL;
    Velocity : LREAL;
    Acceleration : LREAL;
    Deceleration : LREAL;
    Jerk : LREAL;
    BufferMode : INT;
    Axis : AXIS_REF;
END_VAR
VAR_OUTPUT
    Done : BOOL;
    Busy : BOOL;
    Active : BOOL;
    CommandAborted : BOOL;
    Error : BOOL;
    ErrorID : UDINT;
END_VAR

このFBをC++で表現すると、ほぼ以下の構造と一致します。


5. C++で理解する MCFB 構造

class AxisRef {
public:
    double position = 0.0;
    void setTarget(double pos) { position = pos; }
};

class MC_MoveAbsolute {
    bool busy = false, done = false, error = false;
    double targetPos = 0, velocity = 0, accel = 0, decel = 0;
    AxisRef* axis = nullptr;
public:
    void Execute(AxisRef* a, double pos, double vel, double acc, double dec) {
        axis = a;
        targetPos = pos;
        velocity = vel;
        accel = acc;
        decel = dec;
        busy = true;
        // ここで制御コマンド発行
    }

    void Update(double dt) {
        if (busy) {
            // 仮想的に軸を移動させる
            axis->position += velocity * dt;
            if (axis->position >= targetPos) {
                axis->position = targetPos;
                busy = false;
                done = true;
            }
        }
    }

    bool Done() const { return done; }
    bool Busy() const { return busy; }
    bool Error() const { return error; }
};

→ 完全にオブジェクト指向。
MCFBは内部に「状態(Busy, Done, Error)」を持ち、
周期的に呼び出されて状態遷移を管理するステートマシンとして動作します。


6. MCFBは「状態機械(State Machine)」である

MCFBは単なる関数ではなく、内部に状態を保持しています。
C++で言えば、クラスのメンバー変数で状態管理するStateパターン。

典型的な状態遷移:

IDLE → BUSY → DONE
  │      │       │
  └────→ ERROR ←─┘

これがPLC上では、スキャンごとにFBの内部ロジックで更新されます。

たとえば:

IF Execute AND NOT Busy THEN
    Busy := TRUE;
    // move command issued
ELSIF Busy THEN
    IF Axis.Pos >= Position THEN
        Busy := FALSE;
        Done := TRUE;
    END_IF
END_IF

C++のUpdate()メソッドと全く同じ動作構造。


7. OOP的な視点:MCFBは“ポリモーフィック制御ブロック”

各MCFB(例:MC_MoveAbsolute, MC_MoveVelocity)は、
同じ基本インターフェースを実装しています。

INTERFACE IMotionControl
    METHOD Execute
    METHOD Reset
    METHOD GetStatus : INT;
END_INTERFACE

C++で言えば:

class IMotionControl {
public:
    virtual void Execute() = 0;
    virtual void Reset() = 0;
    virtual int GetStatus() = 0;
};

この構造により、モーションコントローラは 多態性(Polymorphism) を持ち、
「どのFBを使っても同じI/Fで扱える」ようになります。


8. MCFBの実際の利用:TwinCAT, Omron, Codesys

✅ TwinCAT 3(Beckhoff)

  • FB名:MC_MoveAbsolute, MC_Home, MC_Power
  • ライブラリ:Tc2_MC2
  • 設定例: iecst fbMoveAbs(Execute := TRUE, Position := 1000, Velocity := 100); fbMoveAbs(Axis := Axis1); IF fbMoveAbs.Done THEN fbMoveAbs.Execute := FALSE; END_IF

✅ Omron Sysmac

  • 名前空間:MC_系FB群(同一仕様)
  • 動作・入出力名はほぼ同一。

✅ CODESYS

  • 同様にPLCopen Motion標準を完全実装。
  • MC_で始まる命令はベンダー間で共通。

つまり、C++で言えば「共通ヘッダで定義されたインターフェースを各ベンダーが実装している」ようなものです。


9. MCFBが優れている理由(OOPとの比較)

観点 C++ MCFB
状態保持 クラスメンバ FB内VAR
実行更新 Updateメソッド スキャン周期
継承・拡張 class継承 EXTENDS構文
抽象化 Interfaceクラス INTERFACE定義
ライフサイクル コンストラクタ/デストラクタ Init/Resetメソッド
イベント制御 ステートマシン Execute/Done/Busy

MCFBは、OOPの原理(カプセル化・多態性・状態遷移)を制御FBに最適化した設計思想です。
つまり「リアルタイムシステム向けOOPの実用形」。


10. MCFBを使ったアーキテクチャ例(単軸制御)

PROGRAM MAIN
VAR
    fbPower : MC_Power;
    fbMove : MC_MoveAbsolute;
    Axis : AXIS_REF;
END_VAR

fbPower(Axis := Axis, Enable := TRUE);
fbMove(Axis := Axis, Execute := TRUE, Position := 1000.0, Velocity := 100.0);

IF fbMove.Done THEN
    fbMove.Execute := FALSE;
END_IF

C++的に表現すると:

AxisRef axis;
MC_Power power(axis);
MC_MoveAbsolute move(axis);

power.Enable(true);
move.Execute(1000.0, 100.0);

while(!move.Done())
    move.Update(0.01);  // 毎周期呼び出し

→ PLCスキャン ≒ Update()ループ。
MCFBは“リアルタイムオブジェクト指向制御”そのもの。


11. まとめ:C++で理解するMCFBの本質

要点 内容
MCFBは「モーション制御の標準OOP」 各制御命令を独立オブジェクト化し、状態を保持
内部はステートマシン構造 Done/Busy/Errorで状態遷移を管理
共通インターフェースによる多態性 MC_MoveAbsolute, MC_Home, MC_GearIn などを共通操作
ベンダーを越える互換性 Siemens, Beckhoff, Omron 等で共通実装可能
C++的視点で理解可能 FB = クラス, VAR = メンバ, METHOD = 関数, Execute = Update

MCFBは制御工学のOOP化。
C++で学んだ抽象化・状態管理のすべてが、PLC制御に生きている。


📚 参考