🎱

myCobotをM5StickCで操作してみた

2023/05/07に公開

前回ではMQTTを使ってmyCobotを動かせるようにしました。

これによりMQTTに対応した他のデバイス、アプリケーションとロボットが連携するようになります。

その例として今回は、M5StickCをAWS IoTに接続してmyCobotを操作してみたいと思います。

先に動かしているところ

前回軽く紹介しているので今回作ったもののデモ動画をのせておきます。

地味ですが、M5StickC内臓のIMUの傾きに応じてmyCobotが横方向に角度を変えるようになります。(縦方向はバランスを崩してすぐ倒れるので、イベント用には使わないようにしました。)

https://twitter.com/k_miura_io/status/1654004289461977088

用意するもの

  • myCobot Pi 280(OS: Ubuntu 20.04, ROS: Noetic)
  • M5StickC(現在は販売終了しているのでこの記事の内容を試したくて購入する場合は上位互換のStickC Plusを選ぶといいです)

AWS IoT Coreの設定

以下のドキュメントを参考にAWS IoTにmyCobotとM5Stackをそれぞれモノとして登録して、証明書を作成します。

https://docs.aws.amazon.com/ja_jp/iot/latest/developerguide/iot-moisture-create-thing.html

証明書を作成した後に以下のファイルをダウンロードしておきます。

  • デバイス証明書
  • パブリックキーファイル(不要ですが、ダウンロードしないと完了にできないのでダウンロードしておきます)
  • プライベートキーファイル
  • CA1のルートCA証明書(myCobotでmqtt_bridgeを使って接続するために必要です)

また、設定タブからデバイスデータエンドポイントをメモしておきます。

M5StickCのプログラム

プログラムはUI Flowを使います。

プログラムの内容はM5StickCに内蔵されたIMUの傾きに合わせてmyCobotの姿勢をAWS IoT CoreにPublishするという内容です。

コピペ用のフローのソースはこちらです。以下の内容を .m5f の拡張子にして保存します。

{"components":[{"id":"_stickscreen","createTime":1683177003904,"name":"screen","x":0,"y":0,"width":120,"height":240,"backgroundColor":"#111111","backgroundImage":"","size":0,"screenType":"default","type":"screen"},{"id":"=B#4DFLFx3yu^gZQ","createTime":1683178633880,"isCoreInk":false,"isPaper":false,"name":"title0","x":0,"y":0,"width":213,"height":13,"color":"#FFFFFF","backgroundColor":"#0000FF","text":"myCobot","textOffset":3,"font":"lcd.FONT_Default","screenType":"default","type":"title","layer":4},{"id":"dd&uaHXdwbsflFKm","createTime":1683178674806,"isCoreTwo":false,"isPaper":false,"name":"xaxis","x":0,"y":48,"color":"#FFFFFF","text":"0","font":"lcd.FONT_Default","rotation":0,"screenType":"default","type":"label","layer":7},{"id":"A$n2TaRx%6WO`^9e","createTime":1683178695491,"isCoreTwo":false,"isPaper":false,"name":"yaxis","x":0,"y":93,"color":"#FFFFFF","text":"0","font":"lcd.FONT_Default","rotation":0,"screenType":"default","type":"label","layer":9}],"type":"stick-C","versions":"Beta","units":[],"hats":[],"stamps":[],"blockly":"<block type=\"basic_on_setup\" id=\"setup_block\" deletable=\"false\" x=\"50\" y=\"50\"><next><block type=\"aws_init\" id=\"^VbQfe4kvqJ|yLp^7LRh\"><mutation key=\"m5pem.key\" cert=\"m5.pem.crt\"></mutation><value name=\"things_name\"><shadow type=\"text\" id=\";@MwvTbz;-C{ksp:YiE3\"><field name=\"TEXT\">m5stickC</field></shadow></value><value name=\"host\"><shadow type=\"text\" id=\"w{@;kPK5@m{2:d9_^nFF\"><field name=\"TEXT\">sample.iot.ap-northeast-1.amazonaws.com</field></shadow></value><value name=\"port\"><shadow type=\"math_number\" id=\"`RTS{?!07YG-;JwE71gf\"><field name=\"NUM\">8883</field></shadow></value><value name=\"keepalive\"><shadow type=\"math_number\" id=\"(-?Mc`mYf~r%O:DT4U~x\"><field name=\"NUM\">600</field></shadow></value><next><block type=\"aws_start\" id=\"_|$.Y[E9(_Ky1VJaA.ax\"><next><block type=\"controls_whileUntil\" id=\"s7g^!dX)1RG72HP(Sxwq\"><field name=\"MODE\">WHILE</field><value name=\"BOOL\"><block type=\"logic_boolean\" id=\"wNUbV5YW*qOI16)YtBqS\"><field name=\"BOOL\">TRUE</field></block></value><statement name=\"DO\"><block type=\"label_set_text\" id=\"Bejlik`XSY@y8?5zkfYm\"><field name=\"COMPONENT\">xaxis</field><value name=\"TEXT\"><shadow type=\"text\" id=\"qLRSU-!p}+8vV^Q)6qdJ\"><field name=\"TEXT\">Hello M5</field></shadow><block type=\"IMU_GET_ACC_X\" id=\"uZ?4ViFV}0/DsiM[K[uT\"></block></value><next><block type=\"label_set_text\" id=\"bjJ8P,*t3dgFB(j[2a[r\"><field name=\"COMPONENT\">yaxis</field><value name=\"TEXT\"><shadow type=\"text\" id=\"@M?1ai*9^P4v6eFCMy4v\"><field name=\"TEXT\">Hello M5</field></shadow><block type=\"IMU_GET_ACC_Y\" id=\"PK.!De__xnp3Sf=44w$`\"></block></value><next><block type=\"aws_publish\" id=\"Epj-C@@lAL=@^vFWySC8\"><value name=\"FROM\"><shadow type=\"text\" id=\"`BJ=`}NQV`rz4wRfeEtl\"><field name=\"TEXT\">/pose</field></shadow></value><value name=\"MSG\"><shadow type=\"text\" id=\"?g0#@M-@JiPFByojRcn^\"><field name=\"TEXT\"></field></shadow><block type=\"dumps_json\" id=\"^}|Z((rvX@U?sdnZ=84%\"><value name=\"JSON_VAR\"><block type=\"map_on_loop\" id=\"O]XaG;n$CkYu6k;t^PJT\"><statement name=\"LOOP\"><block type=\"create_map_key\" id=\"Rr[hpZ,n;aK2j++vR@cO\"><value name=\"key\"><block type=\"text\" id=\"GXKDFobC{@Ya_K{2E!C@\"><field name=\"TEXT\">name</field></block></value><value name=\"value\"><block type=\"lists_create_with\" id=\"mdAbS-Z#(}Bx9o]7yaK2\"><mutation items=\"6\"></mutation><value name=\"ADD0\"><block type=\"text\" id=\"H|0GV+@2NTK7t.`^r3Rf\"><field name=\"TEXT\">joint2_to_joint1</field></block></value><value name=\"ADD1\"><block type=\"text\" id=\"L@W@xLL^5R?HZ?~/F^u`\"><field name=\"TEXT\">joint3_to_joint2</field></block></value><value name=\"ADD2\"><block type=\"text\" id=\"A^%CAB/YF6^I!_rLuCLp\"><field name=\"TEXT\">joint4_to_joint3</field></block></value><value name=\"ADD3\"><block type=\"text\" id=\"yFVTO*9,+)C*vs/-rk6Q\"><field name=\"TEXT\">joint5_to_joint4</field></block></value><value name=\"ADD4\"><block type=\"text\" id=\"DbN8:qcWO}s@$iD2+y,E\"><field name=\"TEXT\">joint6_to_joint5</field></block></value><value name=\"ADD5\"><block type=\"text\" id=\"N#;cP4*yI*A.GBEA|J7e\"><field name=\"TEXT\">joint6output_to_joint6</field></block></value></block></value><next><block type=\"create_map_key\" id=\"G`DE{yRt0au,RPtk-aeW\"><value name=\"key\"><block type=\"text\" id=\"kiN?tTSl#f)XK04T{#T,\"><field name=\"TEXT\">position</field></block></value><value name=\"value\"><block type=\"lists_create_with\" id=\"Vj~P8ac-y7u@zgo(Xw[y\"><mutation items=\"6\"></mutation><value name=\"ADD0\"><block type=\"IMU_GET_ACC_X\" id=\"`7}jMS)ptXQI/@:u#hAE\"></block></value><value name=\"ADD1\"><block type=\"math_number\" id=\"gnCTZ9xjT?x5V{Ts4kv`\"><field name=\"NUM\">0</field></block></value><value name=\"ADD2\"><block type=\"math_number\" id=\"h4vRJYWpukzM{sp`R7la\"><field name=\"NUM\">0</field></block></value><value name=\"ADD3\"><block type=\"math_number\" id=\"^q_Zg{2,-CrvK?6i%}ju\"><field name=\"NUM\">0</field></block></value><value name=\"ADD4\"><block type=\"math_number\" id=\"8a~wKR$!16.03EDR-~h^\"><field name=\"NUM\">0</field></block></value><value name=\"ADD5\"><block type=\"math_number\" id=\"qHuk#I?}q@[68-s5J?9#\"><field name=\"NUM\">0</field></block></value></block></value></block></next></block></statement></block></value></block></value><next><block type=\"timer_delay\" id=\"yxK217|2+a!%Gqh_:8}C\"><value name=\"DELAY\"><shadow type=\"math_number\" id=\"xP-yvo[L.7678Vc]:lgL\"><field name=\"NUM\">5</field></shadow></value></block></next></block></next></block></next></block></statement></block></next></block></next></block></next></block>","Blockly.Remotes":[],"Blockly.RemotePlus":[{"id":"__title","blockId":"","createTime":1683394114907,"name":"M5RemoteTitle","dragAndDrop":false,"resizable":false,"options":{"minWidth":1,"minHeight":1,"maxWidth":6,"maxHeight":10,"defaultWidth":2,"defaultHeight":1},"w":2,"h":1,"bgColor":"#0080FF","color":"#fff","fontsize":"M","label":"M5Remote","interval":3000,"code":"","event":"","dataSource":"none","ezdataToken":"","topic":"","needShadow":false,"type":"title","x":0,"y":0}],"modules":["imu"],"cbIdList_":[],"eventCBIdList_":[],"apikey":"76E775E4","uuid":"c9ba80ee-805a-4882-9dc2-88e45f44e11e"}

AWSに接続するために以下の設定を行います。

  • Init things name: モノを登録するときに設定したモノの名前
  • host: AWS IoTの設定画面で確認したデバイスデータエンドポイント
  • 証明書ファイル、キーファイルをファイルアップロードアイコンからそれぞれアップロードして keyFilecertFileでそれぞれ該当するファイルを選択しておきます

myCobot側の設定

そして、設定ファイル~/catkin_ws/src/mqtt_bridge/config/mycobot_config.yaml の中身を以下の通り書き換えます。

mqtt:
  client:
    protocol: 4      # MQTTv311
  connection:
    host: 【デバイスデータエンドポイント】 
    port: 8883  # ←ポートを8883に設定
    keepalive: 60
serializer: json:dumps
deserializer: json:loads
bridge:
  # pose joint_state
  - factory: mqtt_bridge.bridge:RosToMqttBridge
    msg_type: sensor_msgs.msg:JointState
    topic_from: /joint_states
    topic_to: pose
  - factory: mqtt_bridge.bridge:MqttToRosBridge
    msg_type: sensor_msgs.msg:JointState
    topic_from: ~/pose
    topic_to: /joint_states

AWS IoTで生成したmyCobot用のキーファイル、証明書ファイルをmyCobot内蔵のRaspberry Piの任意のファイルに保存します。

さらにそれらの証明書ファイルを読み込むための追加の設定として ~/catkin_ws/src/mqtt_bridge/config/tls_params.yaml を以下の内容に書き換えます。

tls:
  ca_certs: 【CA証明書のファイルパス】
  certfile: 【デバイス証明書のファイルパス】
  keyfile: 【プライベートキーのファイルパス】
  tls_insecure: true

動かしてみる

それでは実際に動かしてみます。

myCobotのRaspberry Piのターミナルで以下のコマンドを実行してmqtt_bridgeのノードを起動します(前回作成したmycobot.launchを使用します)

MQTT connectedが表示されれば、AWS IoTに正常に接続されています。もし、MQTT disconnected が先に表示されて MQTT connectedとなっている場合は、接続に失敗しているので、一度ノードを止めて再度立ち上げる必要があります。

roslaunch mqtt_bridge mycobot.launch use_tls:=true

別ターミナルで実機を動かすためのノードを起動します。

rosrun mycobot_280 slider_control.py _port:=/dev/ttyAMA0 _baud:=1000000

M5StickC側はUI Flowにファームウェアを書き込むかブラウザ上で実行させると、M5StickCの傾きに合わせてmyCobotの角度が変わるようになります。(縦方向は入れてませんが、y軸方向の値もアームの姿勢情報を送信するときに入れてあげることで、アームの姿勢を自由に設定できるようになります)

Discussion