Main Content

このページの翻訳は最新ではありません。ここをクリックして、英語の最新版を参照してください。

ThingSpeak ダッシュボードを使用したサーボ モーター ギア列のライブ RUL 推定

この例では、ThingSpeak™ ダッシュボードを設定して、サーボ モーター ギア列の残存耐用期間 (RUL) を推定および可視化する方法を説明します。ThingSpeak ダッシュボードは、関連するデータ ストリームと MATLAB 解析スクリプトで設定された ThingSpeak チャネルで構成されています。MATLAB スクリプトは、ThingSpeak でリアルタイムに実行されます。

この例では、サーボ内部のギア列の RUL を可視化して予測するために使用する、合成モーター電流信号データのセットを生成します。ホビー サーボ モーターを駆動する電流信号のモーター電流シグネチャ解析 (MCSA) を使用して、モーターとギア列の故障を示すいくつかの周波数の関心領域から、周波数領域 (スペクトル) の特徴を抽出します。1 つの特徴、または特徴の組み合わせを使用して、以降の RUL 推定に用いる健康インジケーター (HI) を構成します。MCSA は、サーボのギア列でトルクまたは回転数の変動を誘発し、相関しているモーター電流の変化につながる故障を診断するのに役立つ手法です。MCSA はモーターの電流信号のみが解析に必要とされ、高価な検出ハードウェアが追加で必要にならないため、モーターの故障解析に最適であると実証されています。特に、加速度計や他の振動センサーをもつ計器でのギア列へのアクセスが容易ではない場合、従来の振動センサーを使用したギア故障の検出は困難です。

データ ストリームとハードウェア セットアップの詳細については、ギア列故障検出のためのモーター電流シグネチャ解析およびThingSpeak を使用したサーボのギア列のライブ RUL 推定を参照してください。

サーボ モーター ギア列の RUL を推定および表示するための簡略化されたワークフローには、以下の手順が含まれます。

  1. ThingSpeak ダッシュボードを設定する

  2. サーボ モーター ギア列の特徴を定期的に生成する

  3. 特徴を生成しながら RUL を推定する

  4. ThingSpeak で RUL アラートを設定する

ダッシュボードの設定

ダッシュボードを作成する最初のステップは、データのストリーミング、解析、表示に適切なチャネル ID を持つ、ThingSpeak チャネルを設定することです。その後、この例の後続の節で説明されているように、関連する MATLAB 解析スクリプトを作成できます。ThingSpeak チャネルの設定とデータのストリーミングの詳細については、アカウントとチャネルの設定およびThingSpeak を使用したサーボのギア列のライブ RUL 推定を参照してください。

この例では、合成サーボ モーター データの RUL を実行、解析、表示するためにチャネル 1558487 が作成されています。次のコマンドを実行して、このダッシュボードにアクセスします。

web('https://thingspeak.com/channels/1558487')

ThingSpeak ダッシュボード - 残存耐用期間の推定

この例では、評価間でモデルの状態を保存する必要があるため、この例の RUL モデルに基づいて、チャネルの Metadata 設定を変更します。通常、ThingSpeak チャネルをユーザーが設定する場合には、Metadata の設定を変更する必要はありません。

この例では、ExponentialDegradationModel は、fit コマンドを使用して履歴データで学習したと仮定します。fit コマンドは、学習データの履歴記録に基づいてモデルのパラメーターの事前確率を推定します。学習済みモデルの Prior プロパティには推定されたモデル パラメーター ThetaBetaRho が含まれます。これらのモデル パラメーターの詳細については、exponentialDegradationModelを参照してください。

適合した指数劣化モデルからモデルの事前確率を抽出し、状態構造体の一部として固定パラメーター (Phi など) を追加します。学習 (履歴) データからモデル パラメーターを初期化する近似メソッドの使用例については、データの着信に応じた RUL 予測の更新を参照してください。

mdl = exponentialDegradationModel;
state = mdl.Prior;
state.Phi = 0.6931;

この例では、モデル パラメーターの事前確率を以下のように設定するとします。

state = struct( ...
  'Theta', 0.2790, ...
  'ThetaVariance', 0.0102, ...
  'Beta', 0.1686, ...
  'BetaVariance', 6.5073e-04, ...
  'Rho', -0.9863, ...
  'Phi', 0.6931);

状態構造体を文字列表現に変換し、チャネルの Metadata 設定に手動でコピーできるようにします。

state = jsonencode(state);

作成したモデル状態の文字列を、チャネルの Metadata 設定に手動で次のように保存します。

合成サーボ モーターの特徴の生成

この例では、次の手順として、合成サーボ モーターの特徴を生成し、その値を別々のフィールドとして ThingSpeak チャネルに保存します。使用例に応じて、クラウド ソースの特徴値を使用するか、リアルタイムのハードウェア ストリーミング データから計算できます。

この例で生成される合成モーター信号データは、以下のサーボ モーターとギア列の仕様を使用しています。下の図に示すように、サーボは、4 組の噛み合うナイロン製ギアで構成されています。DC モーター シャフト上のピニオン P1 は段付きギア G1 と噛み合います。ピニオン P2 は段付きギア G1 の成形部分であり、段付きギア G2 と噛み合います。ピニオン P3 はギア G2 の成形部分であり、段付きギア G3 と噛み合います。ピニオン P4 は G3 とともに成形されており、出力シャフトに取り付けられた最終ギア G4 と噛み合います。G1 と P2、G2 と P3、G3 と P4 の段付きギアの組は自由回転ギアです。すなわち、これらは各シャフトに固定されていません。ギアのセットは 278:1 の減速を行い、DC モーターを 5 V で駆動する場合、約 6117 rpm のモーター回転数を出力シャフトで約 22 rpm に減速します。

ハードウェア モデルの詳細については、ThingSpeak を使用したサーボのギア列のライブ RUL 推定を参照してください。

次の表に、歯数と、各ギア噛み合いにおける出力速度、ギアの噛み合い周波数、累積ギア減速比の理論値を示します。

この例の ThingSpeak ダッシュボードでは、以下の 3 つの MATLAB Analysis スクリプトを使用します。

  • 合成サーボ モーターの特徴の生成

  • 残存耐用期間推定の計算

  • RUL アラートの送信

MATLAB Analysis アプリを使用して、ThingSpeak チャネルに保存されているデータを調査および解析できます。詳細については、MATLAB Analysis アプリを参照してください。

チャネル 1558487 に関連する上記の MATLAB スクリプトは、この例の現在のディレクトリに掲載されています。

以下の MATLAB Analysis コードは、"合成サーボ モーターの特徴の生成" スクリプトに関連しています。TimeControl を使用して 5 分ごとにスクリプトを実行し、利用可能なデータまたは合成データから新しいサーボ モーターの特徴の計算をトリガーします。"合成サーボ モーターの特徴の生成" スクリプトは、次のように構成された "TimeControl" と関連付けられています。

"合成サーボ モーターの特徴の生成" スクリプトの内容は、次のとおりです。

時間領域のモーターの特徴のシミュレーション

この例で使用したサーボ モーターでは、モーターの巻線電流は 308 mA から 320 mA の間で変動し、速度は 20 rpm から 23 rpm の間で変動します。

motorCurrent = 308 + 12*rand(1);
rpm = 20 + 3*rand(1);

モーター電流の周波数領域の特徴のシミュレーション

モーター シャフト周波数 (1xFS1 および 2xFS1) のパワー スペクトルの振幅と合計帯域パワーを以下のようにシミュレーションしました。

パラメーターを入力し、サーボ モーターが 1 日間で完全に劣化するシミュレーションを行います。

dStart = dateshift(datetime, "start", "day");
dNow = datetime;
dayScale = seconds(dNow - dStart) / (24*3600);

モーター シャフト周波数の 1 番目の高調波 (1xFS1) におけるパワー スペクトルのピーク振幅は、劣化が進むにつれて -30 dB から 10 dB の間で直線的に変化します。ホワイト ノイズを追加して、より現実的なセンサー データをシミュレーションします。周波数の詳細については、ThingSpeak を使用したサーボのギア列のライブ RUL 推定を参照してください。

peak1FS1 = -30 + (10+30)*dayScale + randn(1);

モーター シャフト周波数の 2 番目の高調波 (2xFS1) におけるパワー スペクトルのピーク振幅は、劣化が進むにつれて -20 dB から 0 dB の間で直線的に変化します。ホワイト ノイズを追加して、より現実的なセンサー データをシミュレーションします。

peak2FS1 = -20 + (0+20)*dayScale + randn(1);

モーター電流の合計帯域パワーは、劣化が進むと 1 ~ 13 の間で指数的に変化し、しきい値 13 で故障が発生すると仮定します。ホワイト ノイズを追加して、より現実的なセンサー データをシミュレーションします。RUL 推定の健全性インデックスとして帯域パワーを使用します。

phi = 0.5;
theta = 0.5;
threshold = 13;
beta = log((threshold-phi) / theta);
bandPower = phi + theta * exp(beta*dayScale + randn(1)/10);

チャネル ID と API 書き込みキーの値の設定

チャネル ID の [] を置き換えて、ThingSpeak ダッシュボードにデータを次のように書き込みます。

writeChannelID = [];

次のように、Write API Key を引用符で囲んで入力します。

writeAPIKey = '';

writeChannelID 変数で指定されたチャネルに特徴を書き込みます。

features = [peak1FS1, peak2FS1, bandPower, motorCurrent, rpm];
fields = 1:numel(features);
thingSpeakWrite(writeChannelID, features, 'Fields', fields, 'WriteKey', writeAPIKey);

特徴は、ThingSpeak チャネルのフィールド 1 ~ 5 に次のように表示されます。

合計帯域パワーのチャート

残存耐用期間推定の計算

次に、モーター電流の合計帯域パワーを健康インジケーターとしてサーボ モーターの残存耐用期間を計算する MATLAB 解析スクリプトを設定します。また、このスクリプトは RUL 推定を ThingSpeak チャネルの [Remaining Useful Life (hr)] フィールドに保存します。

以下の MATLAB 解析コードは、"Calculate Remaining Useful Life Estimate" スクリプトに関連しています。チャネルの [合計帯域パワー] フィールドに新しい有効な特徴値が追加されるたびに実行される、React コントロールを使用します。

チャネル ID の設定と API キーの値の読み取り

チャネル ID の [] を置き換えて、ThingSpeak チャネルのデータを読み取ります。

readChannelID = [];

チャネルが非公開の場合は、"API 読み取りキー" を引用符で囲んで入力します。

readAPIKey = '';

この例では、"合計帯域パワー" 特徴がチャネルのフィールド 3 に保存されます。

fieldID = 3;

前回のサーボ モーター交換以降のデータの読み取り

この例では、サーボ モーターが故障し、24 時間ごとの午前 12 時に交換すると仮定します。

dStart = dateshift(datetime, "start", "day");
dNow = datetime;
range = [dStart, dNow];

特徴データを読み取り、無効な値や空の値を削除します。

data = thingSpeakRead(readChannelID, 'Fields', fieldID, ...
  'ReadKey', readAPIKey, 'DateRange', range, 'OutputFormat', 'timetable');
data = rmmissing(data);

サーボ モーターを交換した直後など、有効なデータがない場合は復帰します。

if isempty(data)
  return;
end

指数劣化モデルの作成

RUL 推定の健全性インデックスとして "合計帯域パワー" を使用し、サーボ モーターの現在の RUL 推定を計算します。チャネルの "Metadata" から、過去のデータを劣化モデルに近似させて得られたモデル パラメーターの初期状態を設定して再読み込みします。利用可能なデータから新しい RUL 値を推定する前に、事前確率パラメーターを使用して劣化モデルを初期化します。

state = loadModelState();
mdl = exponentialDegradationModel( ...
  'Theta', state.Theta, ...
  'ThetaVariance', state.ThetaVariance, ...
  'Beta', state.Beta, ...
  'BetaVariance', state.BetaVariance, ...
  'Phi', state.Phi, ...
  'Rho', state.Rho, ...
  'NoiseVariance', 0.1, ...
  'SlopeDetectionLevel', [], ...
  'LifeTimeVariable', data.Properties.DimensionNames{1}, ...
  'LifeTimeUnit', "hours", ...
  'DataVariables', data.Properties.VariableNames{1});

健全性インデックス (合計帯域パワー) の RUL 劣化しきい値を設定します。

threshold = 13;

ここでのデータは履歴データではなく、ThingSpeak チャネルのフィールドに記録されたサーボ モーターの特徴の最近のリアルタイムの観測値です。

サーボ モーターの前回の交換以降の利用可能な特徴値を使用して、劣化モデルを更新します。次に、故障のしきい値に基づいて、現在の RUL 推定を計算します。

update(mdl, data)
rul = hours(predictRUL(mdl, threshold));

チャネル ID と API 書き込みキーの値の設定

チャネル ID の [] を置き換えて、ThingSpeak チャネルにデータを次のように書き込みます。

writeChannelID = [];

次のように、"API 書き込みキー" を引用符で囲んで入力します。

writeAPIKey = '';

writeChannelID 変数で指定されたチャネルに更新された RUL 推定を書き込みます。この例では、RUL 推定値が ThingSpeak チャネルのフィールド 6 に保存されます。

fieldID = 6;
thingSpeakWrite(writeChannelID, rul, 'Fields', fieldID, 'WriteKey', writeAPIKey);

チャネルのフィールド 6 は、サーボ モーターの RUL 推定を次のように追跡します。

RUL 推定のチャート

[Field Value Gauge] ウィジェットを追加して、現在の RUL 推定を表示します。詳細については、Channel Display Widgets を参照してください。

RUL 推定ゲージ

RUL アラートの送信

また、MATLAB Analysis スクリプトを設定して、サーボの故障が差し迫っていることを、チャネルに RUL 状態アラートとして送信できます。

以下の MATLAB Analysis コードは、"Send RUL Alert" スクリプトに関連しています。React コントロールを使用して、差し迫った故障の現在の RUL 推定が 4 時間未満と判断される間は、10 分ごとにテキストメッセージによるアラートを (チャネル内のステータス更新として) 送信します。RUL 推定が 8 時間未満の場合は、警告メッセージが表示されます。

チャネル ID の値の設定

チャネル ID の [] を置き換えて、ThingSpeak チャネルのデータを読み取ります。

readChannelID = 1558487;

この例では、RUL 推定がチャネルのフィールド 6 に保存されます。

fieldID = 6;

最近の RUL 推定を読み取り、無効な値や空の値を削除します。

data = thingSpeakRead(readChannelID, 'Fields', fieldID, 'NumPoints', 10, ...
  'OutputFormat', 'timetable');
data = rmmissing(data);

API 書き込みキーの値の設定

次のように、"API 書き込みキー" の値を引用符で囲んで入力します。

writeAPIKey = '';

ThingSpeak チャネルにステータスの更新メッセージを投稿します。

url = sprintf('https://api.thingspeak.com/update.json');
if data.RemainingUsefulLifehr(end) <= 4 
  msg = sprintf("ALERT: %3.1f hours to failure detected at %s", ...
    data.RemainingUsefulLifehr(end), string(datetime));
elseif data.RemainingUsefulLifehr(end) <= 8
  msg = sprintf("WARNING: %3.1f hours to failure detected at %s", ...
    data.RemainingUsefulLifehr(end), string(datetime));
else
  msg = sprintf("HEALTHY: More than %3.0f hours to failure as of %s", ...
    data.RemainingUsefulLifehr(end), string(datetime));
end

try
  webwrite(url, 'api_key', writeAPIKey, 'status', msg);
catch E
  fprintf("Failed to send alert:\n %s\n", E.message);
end

保留中の障害に対するアラートは、[Channel Status Updates] ビューに表示されます。

チャネル ステータスの更新ウィンドウ

この機能は、テキスト メッセージ、電子メール、Twitter の更新を送信するコードに置き換えることができます。詳細については、ThingTweet アプリおよび ThingHTTP アプリを参照してください。

あるいは、次のコードを使用して、電子メールによるアラートを送信することもできます。詳細と例については、Alerts API および Analyze Channel Data to Send Email Notification を参照してください。

sendAlertEmail(data.RemainingUsefulLifehr(end));

電子メールによるアラート メッセージ

サポート関数

loadModelState 関数は、チャネルの "Metadata" 設定からモデルの状態 (すなわち、モデル パラメーターの事前確率) を読み込み、MATLAB 変数 (struct) に変換します。この例の作業ディレクトリで、以下の MATLAB スクリプトにアクセスできます。

function state = loadModelState()
% Configure the Channel ID.
% Replace the [] with channel ID to read data from:
readChannelID = [];

% Read the stored RUL model initialization state from the Metadata field of the
% channel specified by the 'readChannelID' variable.
url = sprintf('https://api.thingspeak.com/channels/%d/feeds.json', readChannelID);
response = webread(url, 'metadata', 'true', 'status', 'true', 'results', 30);

state = jsondecode(response.channel.metadata);
end

関数 sendALertEmail は、RUL 推定値を示すアラート電子メールを送信します。

function sendAlertEmail(rul)
alertMessage = sprintf("ALERT: %3.1f hours to failure detected.", rul);
alertSubject = sprintf("Pending servo motor failure");

% Configure the Alert API Key value.
% Enter the Alert API Key between the quotes below:
alertAPIKey = '';
options = weboptions("HeaderFields", ["ThingSpeak-Alerts-API-Key", alertAPIKey ]);

alertURL = "https://api.thingspeak.com/alerts/send";
try
  webwrite(alertURL, "body", alertMessage, "subject", alertSubject, options);
catch E
  fprintf("Failed to send alert:\n %s\n", E.message);
end
end

参考

| | | |

関連するトピック