Keigan Motor の動作撮影するに Node-RED を操作する手が足りないので Power Automate Desktop に操作をまかせるメモ

Keigan Motor の動作撮影するに Node-RED を操作する手が足りないので Power Automate Desktop に操作をまかせるメモです。

Keigan Motor を角度指示させたツイート

Windows PC で Node-RED からシリアル接続に Keigan Motor の ローレベル API の命令をして動かせた!というとツイートをしました。

一応、YouTube も置いておきます。

image

Node-RED は、このようなフローです。

Node-RED の JSON フローも置いておきます。

[{"id":"7a9de5c7a129250a","type":"inject","z":"2390dfc73f8bb635","name":"60 度","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"60","payloadType":"num","x":290,"y":300,"wires":[["678992a237c12336"]]},{"id":"b75d32a636225ee6","type":"inject","z":"2390dfc73f8bb635","name":"0 度","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"0","payloadType":"num","x":290,"y":460,"wires":[["678992a237c12336"]]},{"id":"678992a237c12336","type":"function","z":"2390dfc73f8bb635","name":"moveTo 絶対角度指示","func":"// moveTo 絶対角度指示\n// https://docs.keigan-motor.com/software_dev/lowapis/motor_action#0x66\nconst commandNum = 0x66;\n\n// まず命令するためにバッファを用意\nlet buffer = new ArrayBuffer(9);\n\n// moveTo コマンド指定\nnew DataView(buffer).setUint8(0,commandNum);\n\n// タスク管理用ID\n// ひとまず 0 を入れておく\nconst cid = 0;\nnew DataView(buffer).setUint16(1,cid);\n\n// 角度から radian 指定\nconst radian = msg.payload * 0.017453292519943295;\nnew DataView(buffer).setFloat32(3,radian);\n\n// 巡回冗長検査\n// こちらもひとまず 0 を入れておく\nnew DataView(buffer).setUint16(7,0);\n\n// ArrayBuffer から Buffer に変換\n// Keigan にシリアル経由でに流すデータの確定\nmsg.payload = Buffer.from(buffer);\n\nreturn msg;","outputs":1,"noerr":0,"initialize":"","finalize":"","libs":[],"x":520,"y":300,"wires":[["4331b71422919b27"]]},{"id":"29d50ca39bb7fb1d","type":"inject","z":"2390dfc73f8bb635","name":"180 度","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"180","payloadType":"num","x":290,"y":380,"wires":[["678992a237c12336"]]},{"id":"f9b2c3c408351034","type":"function","z":"2390dfc73f8bb635","name":"enable モーター許可","func":"// モーター動作を許可\n// https://docs.keigan-motor.com/software_dev/lowapis/motor_action#0x51\nconst commandNum = 0x51;\n\n// まず命令するためにバッファを用意\nlet buffer = new ArrayBuffer(5);\n\n// enable コマンド指定\nnew DataView(buffer).setUint8(0,commandNum);\n\n// タスク管理用ID\n// ひとまず 0 を入れておく\nconst cid = 0;\nnew DataView(buffer).setUint16(1,cid);\n\n// 巡回冗長検査\n// こちらもひとまず 0 を入れておく\nnew DataView(buffer).setUint16(3,0);\n\n// ArrayBuffer から Buffer に変換\n// Keigan にシリアル経由でに流すデータの確定\nmsg.payload = Buffer.from(buffer);\n\nreturn msg;","outputs":1,"noerr":0,"initialize":"","finalize":"","libs":[],"x":520,"y":100,"wires":[["4331b71422919b27"]]},{"id":"b8cc8240393e5611","type":"inject","z":"2390dfc73f8bb635","name":"許可","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"1","payloadType":"num","x":290,"y":100,"wires":[["f9b2c3c408351034"]]},{"id":"4331b71422919b27","type":"serial out","z":"2390dfc73f8bb635","name":"","serial":"79b7585d97706561","x":750,"y":100,"wires":[]},{"id":"f6dfa2de1e579dc7","type":"function","z":"2390dfc73f8bb635","name":"speed 回転速度指定","func":"// speed 回転速度指定\n// https://docs.keigan-motor.com/software_dev/lowapis/motor_action#0x58\nconst commandNum = 0x58;\n\n// まず命令するためにバッファを用意\nlet buffer = new ArrayBuffer(9);\n\n// speed コマンド指定\nnew DataView(buffer).setUint8(0,commandNum);\n\n// タスク管理用ID\n// ひとまず 0 を入れておく\nconst cid = 0;\nnew DataView(buffer).setUint16(1,cid);\n\n// 回転速度指定\nconst degree = 360;\nconst radian = degree * 0.017453292519943295;\nconst speed = msg.payload;\nconst radian_speed = radian / speed;\nnew DataView(buffer).setFloat32(3,radian_speed);\n\n// 巡回冗長検査\n// こちらもひとまず 0 を入れておく\nnew DataView(buffer).setUint16(7,0);\n\n// ArrayBuffer から Buffer に変換\n// Keigan にシリアル経由でに流すデータの確定\nmsg.payload = Buffer.from(buffer);\n\nreturn msg;","outputs":1,"noerr":0,"initialize":"","finalize":"","libs":[],"x":520,"y":200,"wires":[["4331b71422919b27"]]},{"id":"4c4b83dfe592636f","type":"inject","z":"2390dfc73f8bb635","name":"","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"1","payloadType":"num","x":290,"y":200,"wires":[["f6dfa2de1e579dc7"]]},{"id":"79b7585d97706561","type":"serial-port","serialport":"COM4","serialbaud":"115200","databits":"8","parity":"none","stopbits":"1","waitfor":"","dtr":"none","rts":"none","cts":"none","dsr":"none","newline":"\\n","bin":"false","out":"char","addchar":"","responsetimeout":"10000"}]

さて、こちら、実はまともにやると右手と左手だけではうまくいかないんです。

  • 左手
    • Keigan Motor を持つ
  • 右手
    • Node-RED の映っているディスプレイと Keigan Motor を撮影
  • ???(3 番目の操作担当)
    • Node-RED 自体を inject ノードをポチポチ押して操作する

そう。3 番目の操作担当が必要なんです。もちろん、誰かに手伝ってもらったり、無理やり Keigan Motor を固定するという手もありますが、今回はそのような手法はやっていません。

Power Automate Desktop に操作担当させた

では、1 人でどうしたかというと、このようにNode-RED 自体を inject ノードをポチポチ押して操作するは、Power Automate Desktop にお願いしました。

image

動画をよく見てみると、このように、自動操作してます。

image

こんな感じです。

image

最初の 4 ステップで、まず、最初の 5 秒は実行直後に Power Automate Desktop も表示させて撮影できる状態を作っています。次のタイミングでマウスクリックとマウス移動をすることによって、ブラウザをクリックすることで Power Automate Desktop がブラウザよりも後ろに隠れて撮影しやすくしています。

そして、次の 5 秒の待ちで、Node-RED の映っているディスプレイと Keigan Motor を撮影するカメラを構えて撮影開始するという流れ。

image

以降は、それぞれの inject ノードをクリックするためにマウス移動+クリック+待ち時間を繰り返しています。

image

マウスの移動について、 Control + Shift で今いるマウスの位置を拾えるので、これでクリックしたい inject ノードのボタンに合わせて調整出来たので、とってもやりやすかったです。前の位置からのマウス移動についても、アニメーションができたり、一瞬でパッと動く指定ができたりと、見せ方が調整できました。

いやー、今回の仕組みができたときに、はたと「これ地味に撮影できないやつ?」と焦った時に、自動操作すればいいじゃん!と Power Automate Desktop を思いつけてよかったです。

結構、デバイス撮影時に、手が足りなくなることが多いので、今後も使いそうな予感ですし、何より面白いですね!