家庭用ロボット開発におけるソフトウェアエンジニアの役割

この記事では、3年半に渡って家庭用ロボット開発をプロトタイピングから製品化まで経験した中で、ロボット開発におけるソフトウェアエンジニア[^1]の役割とはいったいどのようなものだったのかを考察しました。

## 試作フェーズにおけるソフトウェアエンジニア

ロボットの試作フェーズでは主にフィジビリティの検証と評価、そして試作機の開発を行います。開発するロボットの機能や複雑さ等によって試作回数や期間は異なりますが、このフェーズではハードウェア的な設計や試作と並行してソフトウェア面での検証が行われます。

### フィジビリティの検証

プロトタイプ開発のフェーズでは、ソフトウェアエンジニアは様々なフィジビリティの検証を行います。例えば、以下のような内容を検証し、全体の設計を進めていきます。

#### センサーの性能評価
- あるセンサーの性能(観測範囲、精度、観測周期など)がロボットの要求を満たすために十分かを評価する
- 要求を満たすために必要なセンサーの種類、数、配置などを検討・評価する

この辺りは必ずしもソフトウェアエンジニアの役割とは限りません。しかし、ロボット開発では往々にして、センサーフュージョンやデータの抽象化等のファームウェアレベルでは扱いきれない情報処理を行うため、ソフトウェアエンジニアもセンサー評価に携わることがあります。実際には評価用ツールの開発や認識モジュールの試作を行うことで、性能評価を進めていきます。

#### 認識機能の評価・開発
- 画像認識や音声認識等のライブラリ性能を評価・比較する
- センサーを各認識ライブラリと組み合わせて評価する
- 既存のライブラリでは要求を満たせない認識機能(センサーフュージョン、特殊なセンサーを利用する場合等)を試作する

ロボットの開発領域は非常に幅広いため、全ての機能をフルスクラッチで開発するということは滅多になく、既存のライブラリをチューニングして使いつつ、エンジニアは開発の肝になる領域に注力することが多いかと思います。画像認識や音声認識は既存のライブラリが充実しており、そのロボットのセンサーやユースケースにおいて性能(もしくはコストパフォーマンス/計算リソースに対するパフォーマンス)が高いものを選定して使うことも多いと思います。

一方で、一般的なライブラリの少ないマルチモーダルな認識機能や、そのロボットが注力したい特殊な領域の機能に関してはゼロからの開発になることが多いです。場合によっては特許化や、ライブラリ化して販売など、その認識機能自体が会社の資産になるケースもあります。このフェーズで構想の実現可能性が低いことが判明すると、ロボットのコンセプトの大幅修正が必要になることもあるかもしれません。

#### 全体のアーキテクチャの検討
- センサーや認識機能を実現するために必要なCPU/メモリ性能を試算する
- 全体の情報の流れを整理し、それらを実現するためのアーキテクチャを検討する

センサーの種類や数、それらを用いた認識ライブラリ等の目処が立ったら、こんどはそれらを処理するための計算機性能を試算します。性能が高いものが使えるならそれに越したことはないですが、多くの場合は予算や消費電力等の制約を受けます。要求を満たすために最低限必要な計算リソースを試算し、限られた候補の中から選択することになります。場合によっては、複数のCPUやボードを組み合わせて要求を実現するケースもあります。

リソースの試算と並行して全体のアーキテクチャの検討を行います。CPU負荷の高いプロセスやデータ帯域の大きいプロセス等を中心に、全体の情報の流れを整理し、限られたリソースの中で効率的に処理を行えるようなアーキテクチャを設計していきます。検討する内容は多種多様で、例えばOSの選定から、プロセス間通信に何を使うか、一時データや永続化データをどのように保管するか、どのようなプログラミング言語・ライブラリを使うかまで、幅広い内容を俎上に載せ検討します。

### プロトタイプの開発

上記のフィジビリティの検証を進めつつ、実際にプロトタイプの開発を行います。

#### PoCフェーズ

PoC(Proof of Concept)の開発では、ロボットのコンセプトの方向性が正しいのか、実現可能なのか等を検証できるよう、実際にロボットが一通り動く状態を作ります。そこで動く一つ一つのソフトウェアは粗挽きで、性能は低かったとしても、全体を動かすことで初めて気づく問題があるかもしれないので、一旦全てをつなげて動く状態を作り評価することが非常に重要です。

この"全て"というのがロボットの場合は非常に幅広く、OSやドライバー、認識、意思決定、出力制御、プロセス間通信、デバッグ用ツールなど、低レイヤーから高レイヤーまで多岐にわたる開発項目があります。これらをPoCのフェーズでは限られた人数で開発するため、各プレイヤーは浅く広く開発を行うことが求められます。実際自分の場合は、SLAM(地図作成や自己位置推定)のチューニングをしながら、マルチモーダルな認識機能やセーフティ機能を実装し、意思決定とふるまいの開発を行っていました。自分の専門性とは関係なく、来るものは拒まず、なんでもやりますという姿勢で臨むことが求められるフェーズでした。

#### PoC以降の試作フェーズ

PoC以降のフェーズでは、前回の試作の評価や反省を踏まえて、再びコンポーネントの評価・選定や設計の見直し、そして開発を進めていきます。開発内容は、前回試作のソフトウェアをベースにセンサーやアクチュエータの変更に対応するだけかもしれませんし、大胆な設計変更によるゼロからの再構築かもしれません。

また、新たな試作に取り組むタイミングというのは、センサーフュージョンや意思決定のような高次のレイヤーで抱えた課題を解決するため、センサー配置や種別の変更、計算リソースの増強等の低次のレイヤーにおける改善を行えるタイミングでもあります。時間やコストをかければソフトウェアだけで解決できる問題もあるかもしれませんが、使い勝手の良いハードで開発するほうが遥かに効率が良いので、ソフトウェア側の課題をハードウェア側にフィードバックすることが大切なタイミングです。

## 製品化フェーズにおけるソフトウェアエンジニア

製品化フェーズにおいては、ソフトウェアエンジニアはプロダクトを出荷可能な状態にするため、性能や要件を満たしているかを評価しながら、ソフトウェアを繰り返し改善していきます。

### パフォーマンスの改善

クラウド常時接続のロボットのような例外はあれど、家庭用のロボットの多くは限られた計算リソースの中で、上記のような幅広い機能を実現する必要があります。そのため、計算リソースの節約と分配が非常に重要になってきます。例えば、より多くのリソースを割くことで、より高い頻度や精度で人や音声を認識できるかもしれませんし、より多くのオプションから意思決定ができるようになるかもしれません。重要なのはそれらのバランスで、より商品性を高め魅力的なプロダクトするためにコスパの良いリソース配分を検討することになります。場合によってはロボットの置かれた状況に応じて計算リソースの配分を動的に変えることも検討します。

### 品質の担保

テストを書いてCIで実行したり、様々な環境で動作することを確認するためのQAを行ったりするのはソフトウェア開発の基本ですが、ロボット開発においても同様です。単体テストや結合テストの作成・実行は通常のソフトウェア開発と同じように行なえますが、一方で、家庭用ロボットのQAは非常に難しいです。これは、ロボットが使われる環境の多様性が原因です。

家庭用ロボットは様々な環境においてそれなりに動くことを求められます。例えば、音が反響して音源の方向が拾いづらい廊下や、西日が差し込んで顔認識が難しいリビング、センサーが反応しないガラスの扉やテーブル等の家具が置かれたダイニング等の過酷な環境です。

これらの環境下での動きをテストするために、実機を様々な場所へ持っていってテストをするのは大変です。そこで、シミュレータを用いたり 、実機のデータを記録したものを再生してテストを行ったりします。しかし、いわゆるソフトウェアのテストのようにデファクトスタンダードのツールがあるわけではないため、フリーのシミュレータを改変したり、フルスクラッチでツールを開発したりしながらテストの効率化を進めることになります。

また、コミュニケーションロボットにおいては、ロボット掃除機のように明確な目標や評価基準があるわけではなく、利用者がどのように感じるかといった曖昧な指標によって評価を行わざるを得ない場合があります。それらに影響しているのは、ロボットの反応のレイテンシやコミュニケーションのタイミングかもしれませんし、ロボットの表情や動きの良し悪し、もしくはそれらの複合要因かもしれません。実環境でテストをして何か不具合らしきことが起きたとしても、再現が非常に難しかったり、再現できても原因となる要因が多すぎるために究明が難航したりします。また、それぞれの人によって同じ動きに対しても感じ方が異なるため、意見が割れたときの摺り合せ方や合意形成に手間取る場合もあります。ここの難しさが幾許かでも解消されれば、さらに多くの家庭用ロボットが世の中に出てくるかもしれませんね。

## ロボット開発のソフトウェアエンジニアにとって重要なこと

このように、ロボットのソフトウェア開発は面白く、そして大変です。それでも、ロボット開発をする中で自分がいつも大切にしてきたマインドがあるので紹介します。万人にハマるスタイルというのはないと思うので、「こういう取り組み方もあるんだなー」くらいに捉えてもらえると幸いです。

### 幅広く興味を持つ

上記で述べたように、ロボットを構成する技術領域は非常に幅広く、その全てにキャッチアップしていくのは非常に大変です。それでも、自らの強みのある領域だけでなく、広く浅くでも関心を持つ姿勢が重要だと思っています。

例えば自分の場合は、USBカメラを接続するとどのようにしてOSから認識されるのか、ケーブルの中をどのようなデータが行き来しているのか等、普通にソフトウェアエンジニアをやっているだけでは興味すら持たなかったことを学ぶことができました。これらはロボット開発でしか使えない知識というわけではなく、コンピュータを構成するハードウェアやOSの仕組みといった一歩深い視点を持てることで、ロボット以外のソフトウェア開発においても役立っています。

そして、自らの関心の範囲を狭めてしまうのは単に学習の機会を失うだけでなく、自らの出来ることの範囲を狭めることに他なりません。作っているプロダクトの上から下までを幅広く知ることで、そのプロダクトの性能をフルに活かした開発を楽しめると思います。

### チームとチームをつなぐ

ソフトウェアだけでも広すぎる領域があるのに、実際のロボット開発ではハードウェアからビジネスまで幅広い人が携わるため、人と人、チームとチームがきちんと連携するのが非常に難しいと感じています。それでも、自分の業務範囲や強みのある領域から一歩外を見て、困っている人やチームに手を貸したり、誰も拾えていない領域を積極的に取りに行ったりすることが、全体として統一感のあるプロダクトを作り上げる上で非常に重要だと思います。

自分の場合はSlackで困っている人がいたら積極的にヘルプする、自分だけだと解決できないことがあれば別の人を巻き込んで解決へ導く、といった姿勢を心がけていました。そういう姿勢を保つことで色々な人との会話が生まれ、自然と情報が集まってくるので、さらにそういった動きがしやすくなるように感じられました。

## さいごに

本記事は自分なりの退職エントリでした。

3年半という長い期間に渡ってひとつのロボットを開発する中で、多くの学びを得て、技術面だけでなく人間的にも成長することができ、そのような環境を与えてくれた[GROOVE X](https://qiita.com/organizations/groove-x)には心から感謝しています。

20代のキャリアは全てロボットに費やしましたが、30歳になる節目の年で、次はロボットではない別の分野にチャレンジしようと思っています。ロボットからは少し距離を置きますが、ロボット産業がさらに盛り上がるのを楽しみにしています！

[^1]: ソフトウェアエンジニアをSWエンジニア、ハードウェアをHW、ファームウェアをFWと略することが多かったです