Introduction to Spot programming (with ROS)

# Introduction to Spot programming (with ROS)

こんにちは、東大のJSKでBoston Dynamics社のSpotというロボットをベースにシステムを作ってるsktometometoです。
この記事では、開発者がSpotを使ってどんなことができるのか、開発者はどのようなプログラミングインターフェースが用意されているのかについて、僕個人の見解を交えながら解説していきます。
(追記予定)

参考ページ類

- [Spot SDK](https://dev.bostondynamics.com/)
- [spot-sdk (github)](https://github.com/boston-dynamics/spot-sdk)
- [Knowledge Center](https://support.bostondynamics.com/s/knowledge-center-)
- [Community Forum](https://support.bostondynamics.com/s/community-forum)
- [spot_ros](https://github.com/clearpathrobotics/spot_ros)

## Spotができること

皆さんご存知の通り、Spotは4脚の移動ロボットです。4脚移動ロボットはこの世に多くあれど、Spotほど一般のユーザーが使用することを意識し開発されたロボットはまだ珍しいです。

一般的なユーザーはSpotをコントローラ(専用APPのインストールされたAndroidタブレット)で操作することを意図されており、コントローラを用いてSpotを移動させたり、自律移動のための地図を作ったり、自律移動のタスクを編集したりすることができます。

基本的な使い方については、以下の公式のTutorialsを見るとわかりやすいです。

- [Getting started](https://support.bostondynamics.com/s/spot/getting-started)
- [Mobility](https://support.bostondynamics.com/s/spot/mobility)
- [Autowalk](https://support.bostondynamics.com/s/spot/autowalk)
- [Sensor integration](https://support.bostondynamics.com/s/spot/sensor-integration)
- [Application](https://support.bostondynamics.com/s/spot/application)

ユーザーはそれと意識することなく、環境認識結果に基づく歩行をロボットにさせることができるので、段差の昇り降りや障害物の回避についてはロボットに自動で行わせつつ大体の移動方向を指示するのみでロボットに移動させることができます。

このように、環境認識・コントロール・ナビゲーションなどのロボットを動作させるために必要な各要素についてユーザーが注意することなく、監視などの必要な仕事を行わせることができるようなシステムになっているのですが、一方で開発者が利用できるSpotの機能には制限があります。

もっとも大きい制約のうちの一つは脚の関節へ関節角度指令を送ることができない点(参考:[Separate movement of Spot's limbs
](https://support.bostondynamics.com/s/question/0D54X00006kgCBgSAM/separate-movement-of-spots-limbs))で、開発者はSpotの関節角度・トルクの情報を取得することはできるもの、関節角度・トルクなど低レベルの指令を送ることができません。開発者が送ることのできる最も低レベルな指令は、[2次元平面内での速度指令](https://dev.bostondynamics.com/python/bosdyn-client/src/bosdyn/client/robot_command#bosdyn.client.robot_command.RobotCommandBuilder.synchro_velocity_command)、[bodyリンクの高さ・姿勢の指令](https://dev.bostondynamics.com/python/bosdyn-client/src/bosdyn/client/robot_command#bosdyn.client.robot_command.RobotCommandBuilder.synchro_stand_command)、[足の配置を微調整する指令](https://dev.bostondynamics.com/python/bosdyn-client/src/bosdyn/client/robot_command#bosdyn.client.robot_command.RobotCommandBuilder.stance_command)、[与えられた位置まで移動する指令](https://dev.bostondynamics.com/python/bosdyn-client/src/bosdyn/client/robot_command#bosdyn.client.robot_command.RobotCommandBuilder.synchro_trajectory_command_in_body_frame)あたりになります。
また、より上位の指令についても、[自律移動機能であるGraphnavを用いて地図上の目的のノードまで移動する指令](https://dev.bostondynamics.com/python/bosdyn-client/src/bosdyn/client/graph_nav#bosdyn.client.graph_nav.GraphNavClient.navigate_to)などであり、Spot内部で使用されている歩行動作生成機能やナビゲーションのプランニング・コントロール機能、障害物認識や[HeightMap生成](https://dev.bostondynamics.com/python/bosdyn-client/src/bosdyn/client/local_grid)などの認識機能、自律移動機能における経路計画や地図についても、用意されたいくつかのパラメータをいじることはできるものの、開発者はある機能を単体で利用したり、部分的に機能を自前のものに置き換えて動かしたりすることはできません。

これは、歩行制御だったり、動作の学習だったりの研究にSpotを使用することはできないことを意味していて、そのためかシミュレータ等でもSpotのモデルを使って遊んでいるのはあまり見かけない気がします。お金のある大富豪がハックして好き勝手いじれるようになるのが待たれます。
このため、脚で移動するため階段や多少の不整地でも移動することのできるという点では特殊ですが、開発者側からすると一般的な台車ロボット同様、移動する機能そのものはすでにあるとして、それを利用してどのようなアプリケーションを構築するかという点に着目するべきものだと思います。

## Spot Programming

上記のリンク先にあるように、タブレットからの操作により、平地を移動させたり、階段を昇り降りしたり、自律移動用の地図を構築したりすることができます。タブレットから実行可能なものは開発者用のインターフェースとしても用意されており、開発者はPythonのクライアントライブラリである[spot-sdk](https://github.com/boston-dynamics/spot-sdk)を用いてSpotへ指令を送ったり、Spotから情報を取得するようになっています。

[Concepts](https://dev.bostondynamics.com/docs/concepts/readme) より転載
![Concept of Spot API](https://d33wubrfki0l68.cloudfront.net/f34bcc5ff400782c699351096b289ed9f943164a/32716/_images/api_top_level.png)

このクライアントライブラリを用いる際には、Spot本体と外部制御用PCとをWi-FiやEthernet経由のIPネットワークで接続し、gRPCにより通信することでロボットとの情報をやり取りします。
一般的には、Spot本体背面に[Spot CORE](https://support.bostondynamics.com/s/article/About-the-Spot-CORE-system)等の開発用PCを取り付け、PCとSpot本体とをEthernetで接続し、開発用PC上でクライアントライブラリを使用するPythonスクリプトを実行することによりロボットを動作させることが想定されているようです。

[hello_spot.py](https://github.com/boston-dynamics/spot-sdk/blob/master/python/examples/hello_spot/hello_spot.py)はロボットを動作させるプログラムの一例です。
この中では、ロボットをAPIを通じて動作させるための認証・時刻合わせ・権限の獲得の他、RobotCommandを用いてパラメータを変更させつつstandさせたり、カメラのセンサ情報を取得させたりしています。

APIを通じてロボットを動作させる際に、ロボットに動作指令を送る権限を取得できるPythonプロセスは一つのみなので、ロボットにある動作を行わせる際には、[Spot Detection and Followのサンプル](https://github.com/boston-dynamics/spot-sdk/tree/master/python/examples/spot_detect_and_follow)のようにあるPythonプロセスでデータの取得・認識の計算・ロボットへの指令を送るなどやや面倒なPythonスクリプトを書く必要があるようです。

ただ、Spot内部の機能と連携して動作させるにはこのAPIを利用する必要があり、例えばSpotのもともとの機能として、自律移動タスク中にObject Detectionを利用するには、外部からAPIを用いて通信する認識サーバーを立てる必要があります。[Network Compute Bridge](https://github.com/boston-dynamics/spot-sdk/tree/master/python/examples/network_compute_bridge)

## Spot Programming with ROS

上記のように、Boston Dynamicsにより用意されている開発者用プログラミングインターフェースは、pythonクライアントライブラリを用いたスクリプトにより、gRPCでSpot本体と通信してロボットを動かすというものですが、各種センサーのインテグレーションだったり、既存の認識機能の流用だったり、RVizを用いた可視化だったりを考えると、開発者としてはROSを利用したくなります。
たとえば、JSKでは[coral_usb_rosパッケージ](https://github.com/knorth55/coral_usb_ros)を用いた認識機能を組み合わせることで、人を見つけてインタラクションするなどしています。

spot-sdkのROSドライバーはいくつか実装がありますが、JSKでは[clearpathrobotics]()の[spot_ros](https://github.com/clearpathrobotics/spot_ros)を利用しています。
spot_ros は spot-sdk のROSインターフェースを提供する形になるので、利用できる機能は spot-sdk + ROSの域を出ません。2021/12/1現在のところ、以下のような機能があります。

- camera, joint, battery などのロボット体内・センサ情報の取得
- ロボットのodometry情報
- 速度指令・位置指令・姿勢指令などの移動に関する指令
- 階段モードON/OFFなどの移動パラメータの変更
- Docking Station への Dock/Undock 指令
- Autowalk の記録・再生指令

/cmd_velによる速度指令インターフェースや/odomのオドメトリトピック、ロボットの/odom -> /base_link のTFなどはあるため、move_baseのような形式でロボットを移動させるのに十分なインターフェースは用意されています。
まだROSのインターフェースが用意されていない機能もあり、

- Armや各種Payload特有の機能
- choreography機能

などがあります。spotをROSで利用する際、欲しい機能があれば是非contributionしてみてください。