ロボット開発を支えるDevOps

この記事はCyberAgent Developers Advent Calendar 2020の22日目に書くはずだった記事です。大変申し訳ございませんでした!!


Web系エンジニアからロボット系エンジニアに転身して2年が経ちました。

過去どんな経緯があったのか、ロボットを使って何に取り組んでいるのかについては、この辺の記事をご覧いただけると幸いです。

昨年から今年にかけてはCOVID-19の到来によって一年のうちの大半をリモートワークで過ごしつつ、時にはリアルなフィールドに赴いてロボットを稼働させるということも並行してやってました。

ロボットプロダクト開発から運用までを基本的に遠隔コミュニケーションでこなすというのはなかなか前代未聞でしたが、原状の課題と効率化に向き合ういい機会にもなり、あれこれと工夫を凝らしていく中でロボットを扱う開発ならではのDevOpsといえるような取組みを徐々に始められました。

昨年末に開催された社内カンファレンスにて発表した内容から、一部を抜粋してご紹介していきたいと思います。

ロボットプロダクトの開発プロセス

ざっくりとしてますが、ロボットサービス事業部での開発プロセスの流れを整理してみました。 設計から始まって保守に至るまでのパイプラインの流れこそ一般的だと思いますが、中身はロボットプロダクトならではのユニークな実務が多いですね。デプロイにいたってはほぼ物理的な力仕事で、いい運動になります。

ハイライトされている部分について今回は詳しく紹介していきます。

モーションの作成

ロボットが人とコミュニケーションを行う上で、動きによる表現はとても大切な要素だと考えています。 感情や意図、リアクションの強調など、言語だけでは表現できない部分をカバーすることでより説得力や親しみやすさを演出できます。

基本的には、様々なモーションアセットや制御インタフェースを標準で提供している市販のロボット(PepperやSotaなど)を採用するケースが多いですが、最近では環境やコンセプトに合わせてロボットそのものを自作する機会も出てきました。

大人の事情によりロボットの現物は公開できませんが、複数のサーボモーターを組み合わせて機体を回転・上下させることで簡単な仕草を表現しています。

例えば挨拶の際にはお辞儀を行い、通常発話は縦運動を入れて喋ってる感を出すなど、 セリフのコンテキストに合わせて稼働させるモーターを使い分けています。

基本的には各セリフパターンごとに動きをつけるのですが、自作ロボットとなるとモーションは全て自前で用意するしかないですし、セリフの数に比例してモーション作成の工数が増大していきます。

このモーション作成を効率化するためにhamonicaというツールを作りました。


(大人の事情によりこの動画では架空の3Dモデルを使用しています)


機能としてはMMDBlenderでお馴染みのアニメーションエディタに近いです。任意のキーフレーム(再生位置)ごとの各モーターの回転角度を定義できます。 セリフの音声データを読み込み、音声波形を確認したり試聴しながら動きを決めていくことができます。

また3Dアニメーションでのプレビュー機能を提供しており、作成中のモーションを音声と合わせて確認することができます。

hamonicaはElectron + React.jsで実装しており、プレビュー機能はUnityで作成したものをWebGLビルドして取り込んでいます。

作成したモーションを定義ファイルとしてexportしておき、専用アプリケーションが定義ファイルの内容に基づいて逐一Arduinoに命令することでモーターを稼働させています。

hamonicaがもたらした恩恵には以下のようなものがあります。

実機が手元になくてもモーションが作れる

ロボットの動きを3Dアニメーションでシミュレートできるため、モーション作成工程において実機は不要になりました。

フルリモート下では手元にロボットがない状況も多く、また複数人で作成を分担したいこともあったため、実機なしでモーションが作れるというのは非常に強力でした。

実機での危険な動きを未然に防ぐことができる

バリデーションサポートや3Dアニメーションで動きを確認できることにより、実機に対して負荷のかかるような動きを事前に確認して防ぐことができていました。

定義を使いまわすことで作業を短縮できる

一度作ったモーションを部分的に再利用できるようにすることでモーション一つ一つをフルスクラッチで作る必要がなくなり、作成工数をショートカットできました。

hamonicaは今後もアップデートを施していく予定です。 アニメーションエディタを1から内製するのは投資的なチャレンジでしたが、必要に応じて機能を好きなように拡張できることが大きな強みとなっています。 将来的には音声の加工やミキシングなどもこのエディタ上から行えるようになれば、発話と振る舞いのデザインに特化した唯一無二のツールへと昇華できそうな手応えがあります。

インタラクションの確認

ロボットとのインタラクションシナリオはユーザの行動やコンテキストによって様々なパターンに分岐していきます。

分岐のパターンごとに狙い通りの自然な体験になっていることが重要なので、一通りのフローを繰り返し確認しながら調整していくことになります。 この作業を効率的にすすめる上でインタラクションデバッガー(仮)を用意しました。

  • 現在のインタラクションの再生位置を可視化
  • 任意の位置からインタラクションを再生可能
  • 人物の各種行動イベント(出現や離脱、操作など)を仮想的にトリガーできる
  • 実機なしの場合でも一通りのフローをシミュレーション可能

このツールによって分岐の多いシナリオパターンも効率的に確認できますし、対話モデルを作り込む前のシミュレーション(例えばWoZ法のような)に活かす使いみちもあります。

将来的にはエディタの機能も統合することでGUIプログラミング感覚でインタラクションを構築できるツールに仕上げられるとよいなと考えています。

センシングパラメータの最適化

ロボットを設置する現場においてはさまざまなセンサを活用しています。特にどの現場でもたいてい必須になるのが人物のセンシングで、RealSenseのような三次元カメラなどを使って人物を追跡するアルゴリズムを実装しています。

各センサがイベントを伝搬する上では様々なしきい値を実装しており、人物のセンシングだけでも追跡を行う範囲や精度立ち止まった/離れたとみなすまでの移動距離や時間など様々あります。 センサとロボットの配置環境や周辺の障害物、人の動きの傾向などを考慮してチューニングする要素も多くあり、現地のデプロイ作業と合わせてこれらパラメータの最適化を実施することになります。

実際のチューニング風景はこんな感じです。

この作業は地味ですがとても重要で、曖昧にしてしまうとインタラクション全体の破綻を招きます。 せっかく念入りに組んだセリフやモーションパターンも適切なタイミングで再生されなければ狙い通りの体験にはなりません。 とはいえ現地で活動可能な時間には限りがあり、長時間の滞留は周囲の方々への迷惑になりかねないシチュエーションも多く、この作業は時間との戦いになりがちです。

そこで、短時間で効率的にセンサのチューニングを行うためのGUIコンソールを開発しています。

操作したしきい値は即座に反映され、上で紹介したインタラクションデバッガーと組み合わせることで更新部分をすぐに再確認できます。 人物センシング関連ではRealSenseから取得した映像にガイドをオーバーレイ表示することで現在のしきい値がどう反映されているのかを可視化しています。

これらのサポートによってパラメータチューニングはだいぶ余裕をもって進められるようになりました。 しかしチューニング項目が今後も増えるとその分手間がかかってくるので、プリセットを複数パターン用意するなどのアプローチも今後進めていきたいところです。

システムの死活監視とレポーティング

例によってアプリケーション上で発生した例外はSlackに通知しています。

アプリケーションプロセスの死活状況も監視しており、例えばロボットアプリケーションの異常終了を検知した場合はサイネージ端末などと自動連携してロボットがメンテナンスのため利用できない旨を周囲に告知することもできます。

内部監視だけでなく外形監視も重要です。リアルなフィールドでは電源が抜かれてマシンまるごとシャットダウンしてしまうような事態が起きてもおかしくはありません。

外形監視の方法ですが、アプリケーションの起動/終了ログやインタラクションフローの遷移ログなどをAWSのS3バケットに集積し、Athenaでログ検索基盤を構築、CloudWatch Eventで定期的にログの集計を行っています。

ログが途絶えていたり不自然なログを発見した場合はSlackに通知しており、これによって現地システム側が何も通知を飛ばせず異常終了した場合(停電など)にも気づくことができます。


ログ検索基盤はプロダクトの評価指標の計測にも役立っており、ロボットの利用実績やユーザの滞在時間など様々なメトリクスを一定時間毎にレポーティングしています。

障害発生時の自動アラートコールと通話接続によるサポート

前述の通り障害発生時にはSlack通知を行いますが、メンテナーメンバーが即座に反応できるようにする上で別途アラートコールも実施しています。

この仕組みはTwilioのAPIを用いて自前で構築しており、単純なアラートコールだけに終わらずアラートコールを受け取った人同士の通話をそのまま繋ぐというユニークな機能を搭載しています。

障害に気づいたメンテナーはリモートデスクトップSSH接続等で現地システムに入り、障害の原因や影響範囲を調査し、まず遠隔から対処を試みます。そして原因不明ないしは遠隔からの対処が困難な場合、最終的に現地に向かうことを考えなければなりません。

全員がフルリモート下にいる状況では特に「いま誰がどこまで調査・対応できてるのか?」「現地にいく必要がありそうか?」「現地に行くのは誰か?」など、色々と確認をとりながら進めたほうがいい事柄が多くあり、アラートコールからそのまま通話が始まってくれればスムーズで最高かなと考えてこの仕組みを作りました。

メンテナー同士の作業が衝突して二次災害が起きる可能性を防げるのも大きいですし、障害対応中の孤独感がなくなるのも精神衛生上よかったなと思います。

この仕組みの実現方法は以前にも記事に書いたので興味のある方はご覧ください。

USB接続機器のトラブルシューティング

現地システムは様々な周辺機器によって構成されており、一部の機器はメインマシンとUSBによって接続され、通信や電源の供給などが行なわれています。

USB機器を定常的に使っていると、USBデバイスが突然認識されなくなったり通信できなくなるなどの不具合が起きることがあります。 原因は機器によっても様々ですが、厄介なのはUSBを物理的に抜き差ししない限り復旧できないケースです。

これを解決してくれたのがUSB troubleshooterでした。

https://www.amazon.co.jp/dp/B078BP3JJL

メインマシンとUSBデバイスの間にUSB troubleshooterを取り付けておくと、ソフトウェアを使って抜き差しをエミュレートすることができます。

これにより、遠隔地からUSB接続のトラブルを解消できるようになりました。 USBを指し直すためだけに現地に向かうのはなんとしても避けたかったので非常に重宝しています。


今回はロボットプロダクト開発ならではのDevOpsをピックアップして紹介しました。いかがでしたでしょうか。

ほとんど内製したツールの話なのでSaaSの活用事例とかを期待してた方々にはなんか申し訳ない感じですが、長期的な投資をしてでもこうしたツール群を開発している背景は「より多くの人が"価値を届けられる"ロボットサービスをデザインできる」ことの実現であり、ロボットをもっと世で活躍させていく上でもこれが重要だと考えています。自分たちはこれらのツールのファーストユーザでもあるという感覚を大事にしています。

社会のライフスタイルの変化も交えながら一層様々なフィールドやテーマでの取り組みが続きますが、しっかりとした実践と検証をサポートできるソリューションを今後も磨き上げていきます。最後までご覧いただきありがとうございました。