生存戦略、社会貢献、自己実現、もの作り

はじめに

 

修士の二年間も終わり、春が近づき、また新たな生活が始まろうとしています。自分は就職ではなく博士進学を(積極的に)選んだのですが、博士をちゃんと取得し、また今後の人生をより良いものにしていくために、そろそろ真面目にキャリアプランやら研究プランやらを考えなければならなくなってきました。

 

これまでの人生は「より良い(楽しい)場所に置かれる」「置かれた場所で咲く」ことを概ね考えているだけでなんとかなったし、それなりの成果も得られてきました。しかし、そのようにして次の三年間を過ごしてしまえば、就職のための実績も無し、就業経験も無し、金も無し、プランも無しの「自分は何かを手早く学習することが出来るから何とかなるだろう」と考えつついつの間にか同期と埋められない差を付けられている救えない27歳が生まれる気がしています。

 

人生で何を優先するか、何に貢献するか、何になりたいか、どのようにそれを達成するかを真剣に考える時期が来たようです。

 

しかしながら、今後の人生プランを考えるにあたり、考慮すべき物事を数え上げてみれば、頭一つでは整理しきれないほどの量が出てきました。就職はアカデミアか企業か、それとも起業するか?お金はどのくらい必要?人生をより楽しみ、より世界に貢献するには?パートナーに無理をさせないためには?人との繋がりをどう作るか?どのようにギバーになるか?博士課程で何をすれば楽しく、独創的で、質が良く、インパクトがあるか?今ある研究ネタのうち、どれが面白く、重要で、かつ結果が出せるか?どのような実績を持てば就職に有利か?研究者になるにして、どの競争的資金にどのタイミングで出していくか?どのような先輩になりたいか?どのようにラボの力を入れている部分と自分の興味をすり合わせるか?論文・コンテンツをどのように作っていくか?健康に生きるには?

 

自分の未来に選択肢があるうちに、選択をしなければなりません。このブログでは、上に書いたような諸々を考えて、纏め、今後の人生の(少なくとも博士三年分の)指針とすることを目指します。多分XR界隈のエンジニアかつクリエイターかつ研究者みたいな人にも役立つと思います。

 

前提: 24歳学生、XR・アバター系の研究に従事、体験・コンテンツ設計も好き、創作でいくつか受賞、学振有り、博士進学予定

 

 

どのように働くか、金を稼ぐか

働き方の選択肢としては、大別すると企業就職、アカデミア職、独立(起業)があります。

まず企業で働く場合、よほどお金が必要になる事が起きなければ、今の研究テーマに関連する職(か学士に関連する職?)に就くことになると思います。博士取ってコンサル行くような人も見ることには見るのですが、まあ積極的には目指しません。安定性や転職のしやすさを考えればベンチャーよりも大企業に行く方が良いと思います。よほど大企業ではできないテーマで、かつめちゃくちゃ頼れる人がいるならベンチャーも良いかも知れませんが、基本的にはそんな出会いは無さそうですね。博士就職の場合だと、業界就職というよりはジョブ型の、就く場所ややる仕事が決まっている場合が多そうな気はしますが、実際のところはどうなんでしょう。アカデミアや独立と比べて余り個人名が出にくいというのは、個人的にはデメリットではあります。クリエイターっぽいことをしたければ電通sony等にもクリエイター班みたいな部署があると聞きますが、まあそこに行くなら博士は要らなそうなので、勿体無さがあります。

 

アカデミアに残ることについては、研究自体は楽しいものの、プレイヤーでなくマネージャーとしてやっていけるか、またメンタル的に大丈夫かという点で不安が残ります。まず前者については、学生より上に行くと、研究のみならず予算を取って指導して大学業務をやって分野コミュニティを運営したりしないと行けないと聞きます。率直に言って、自分にはその適性が不安です。自分は他人に期待して自分と同程度の献身を求めてしまうタイプなので、めっちゃパワハラとかしてしまいそうでもあります。また他人に対して共感するトレーニングを積んできておらず、パートナーからも「解決を目的にすることを言い訳にして共感を積極的に諦めている態度は直した方がいいよ」と言われており、改善が必要だと思っています。これはアカデミア就職に限らないか。メンタル面に関しては、予算が落ちるとか、数年に一度評価されてクビになるとか、自分の分野を天才が焦土にしていくとか(?)、深夜に緊急の連絡が来るとか、共同研究がうまく動かないとか、そう言ったTwitterで流れてくるような点が不安ではあります。研究者としてやるには競争的予算とかにも出していく必要がありそうですが、「さきがけ」の感想文を読んでみると「パートナーに支えてもらい……」という文章が高頻度で出てきて不安になります。勿論、感謝を示している面もあるのでしょうが、パートナーの献身を前提として争うような業界に残って戦いたくはないですね。まあ、不安点の幾つかは博士の間で体験版を味わえそうなので、適性を見定めていこうと思います。研究インターン留学とかポスドク留学とかも機会があればしたいですね。

 

独立する場合は大学発ベンチャーの形が最も良いかなと考えています。卒業後直ぐもあり得ますが、ある程度研究を続けてからその開発物でもって起業する(ex. MPLUSPLUS社)のも良いですし、3年くらい企業で働いてシステムを学んでから起業するのもいいですね。学振の規定で期間中は起業できないので、結局ポスドク期間を挟んで準備することにはなりそうです。NPOとしてやっておくというのも良いですが。起業のネタには、単に大企業がやっていないことでなく、大企業でやれないことをやるべきだと聞きます。具体的には、今の研究の延長でやるか、VR体験設計をするかかなと考えています。自分の比較優位、或いはセンスを示すものとして、学振を取っていることとXR系のデカい賞を取っているというのがあり、大学発ベンチャーならそれらをお金や仲間を集めるのに活かせるかなーと思います。近頃はアカデミアそのものより産学の境目にお金が落ちやすいと聞きますので、金銭的にも魅力的ではあります。個人クリエイターとして(学位を活かさずに)業務委託などをしていく道は考えておらず、大学発ベンチャーとした方が、やることは変わらなくてもお金をより引っ張って来れそうだと考えています。部屋を安い料金で借りられる等といった、大学からの支援も得ることができます。

 

結局、進路の優先度や選択条件を考えれば以下のようになります。

1. 大学卒業→ポスドクor数年企業勤め→独立して大学発ベンチャーをやる(生活基盤に安定感がある場合)

2. アカデミアに骨を埋める (めちゃくちゃ適性がある場合)

3. 大企業に骨を埋める (安定が欲しい場合、やりたい事が少なくなった場合)

4. ベンチャー就職 (物凄く頼れるかつ自分より面白いことをやっている人がいた場合)

 

人生で何を為すか、どのようにコミュニティや世界に貢献していくか

好きなことをやりつつも、それがどのように貢献するのかを考るべき時が来ました。以前、建築系の博士の人から、「何のために研究をするの?社会に貢献するとか、考えたことないの?建築系だとそういう系の批判とかあるんだけどなぁ……」と言われて何も答えられず歯痒い思いをしたことがあります。この人が本気で日々社会に貢献することを考えているのか、もしくはそういった評価基準を競争的資金の獲得等を通して内在化してしまったのかは知りませんが、とにかく今後研究していく上では内発的な動機だけでは(競争的予算の獲得とかで)戦えなくて、社会貢献などの要素も考える必要があるようです。

 

どのようにして内発的な動機と社会貢献を繋げていけば良いのでしょうか。近年良いとされる価値観には、SDGsやウェル・ビーイング、多様性と相互理解などがあり、それらと研究を繋げること自体は出来ます。ChatGPTを使っても繋げられると思います。しかし、論文や申請書にそういった文章を書いたとしても、何となく上滑りしている感覚があります。そういった価値観を冷笑したいのではなく、自分なりに納得のいく形で、研究とそれらの価値観を繋げたいと思っています。


例えば、私が研究している非人型アバターの研究の価値としては、しばしば「このような身体特性の探索は、physicaly disabledな人々への新しい補助具になり、健常者には新しい身体の可能性を提示する」と記述しています。これはこれで良いのですが、まだ借り物の言葉な感があるため、もっと自分の内発的動機(アバター表現への興味)により近い形で価値を見出す必要がありそうです。

 

ある先輩からは、最初から世界規模の貢献を目指す必要はなく、まずは小さなコミュニティから貢献を始めることが大切だと言われました。具体的には、研究室から始め、次に学会、その次に地域社会といった具合に、だんだん自分事として考えられる範囲を広げていけば良いそうです。当面はこの方針で実践していきたいと思います。

 

人との繋がりをどう作るか

アカデミア就職にせよ企業就職にせよ起業にせよ、人との繋がりは大きな財産になります。繋がりを得る手段としては、学会や展示イベント、インターンハッカソンTwitter、人からの紹介などが考えられます。何かいい感じの賞を取ったりすれば、それは次の人間関係への引換券となります。

 

人と繋がる上では、自分が相手から何かを貰おうとするばかりでなく、自分が相手に何かをあげよう/一緒に成長しようという態度が大事っぽいと最近は実感しています。コミュニティの中で大事な人物になることも、顔を広める上で有利に働きます。展示会とかで作品も見ずに名刺交換と挨拶だけして「何か一緒にできたらいいですね〜」とか仰る愉快な人がいますが、信頼がない繋がりは次に繋がらないので価値が薄いです。一緒に何かをやって、それを良い経験にして、信頼を得、紹介を通じて繋がりの輪を拡大していくことが必要だと感じています。つまり、今ある繋がりを大事にして信頼を得ていくことを先ずは意識していきたいですね。

 

博士課程で何をするか

分野によって求められるものは違うとは思いますが、一般的には、少なくとも論文を3本書くことが必要だと聞きます。(自分が行く学際情報学府の卒業要件は調べてもでてこなかったけど厳しめらしい...... ) といってもデファクトスタンダード的な部分はそんなに問題ないと思っていて、むしろ博士課程入試面談の際に言われた「東大の博士なら不変の真理を見つけなければならない、学府の博士なら(純粋工学ではなく?)表現をやっていかないといけない」という部分が課題になりそうです。後半は別の言い方だったかもしれない。

 

色々な博士の人や先生から聞いた話では、博士課程では「新たな課題(=領域)を定義して」「それを塗りつぶす」ことが必要らしいです。前半は、自分のイメージでは、これまで人類が研究してきた大きな「既知の領域」があって、それの辺々に位置する「未知の領域」に対し、問い(クレーム)を立てることによってその一部を切り分け、明快な解くべき課題にする、といったイメージです。後半は、そうして立てた課題に対して、(複数の実験を通して)throughoutに解く、といった意味だと思います。修士課程では非人型アバターについて色々やったものの、微妙に方向性が違っていたために修論内で纏めるのに苦労しました。結局は4つのやったことから、再度分野と価値と課題を再定義する形で修論のまとめパートを書いたのですが、やはり自分では納得いってないので、博論では一気通貫した議論ができたらいいなと思います。

 

そのような博論を書くための戦略としては、先ずは「3年分くらいかけて取り組むべき大きな問いを見つける」ことが求められます。修論や学振で書いた視点をちょっと時間をかけて整理して、良い方針を見つけることが必要そうです。また、実際に取り組んでいく段階では、博論の要素を埋めるようにしつつも、必要に応じて問いを洗練させ方針を見直していくことになりそうです。また、実際に博論を書いた人によれば「結局自分の手札を並べ直して、議論を構成しなおす」ことになるらしいので、手札の数を増やしておくことも重要そうです。自分としてもやっと滑らかな論文の書き方が分かって来たし、重要度はともかくしてやりたいネタも沢山あるので、数をやっていきたい気持ちはあります。折角3年間は評価されずにいられるので、もう少し腰を落ち着けてデカいテーマをやる方がいいのでしょうか...?わからない......。まあ、デカいコンテンツを作りつつ、国内の学会参加や論文も増やしつつ、「分野を作るような論文」を一本でも出せることを狙っていきたいと思います。数を出すことは実績や自己アピールの上でも有用そうですし。

 

結局就職とかする上ではデファクトスタンダードも大事です。実績一覧に書けそうな実績はこんな感じだと思われます。

  • 研究発表系
    • 論文誌(国内、国際)
    • デモ発表
    • ポスター発表
    • それらの受賞
  • その他
    • 競争的資金
    • 特許
    • 登壇
    • 産業系の受賞
    • 本を書く、本の査読
  • 人間として
    • 研究会とか若手の会とかコミュニティの主催
    • 留学??
    • アウトリーチ的な部分とか

とりあえず博士課程の間に、国際論文誌と学会発表の受賞、特許、留学くらいは実績解除したいと思っています。修士の間に行った国ではオーストラリアが一番良かったので、オーストラリアに行きたいな。あと、ACT-Xとかにも出していきたい。具体的な研究課題を考えねば...

 

修士課程で「Mechanical Brain Hacking」という作品で(これもフルペ化しないといけない)実績を結構盛れたように、そのくらいの論文やコンテンツを博士でも2本くらい作りたいです。つまり、通算でホームランを三本打ちたい。研究室内では「三割打者を目指せ」、毎回ホームランを目指すのはやめとけと言われた記憶があります。これまでの実績的には、半年に一本くらいは国内論文や国際デモを出しているので、今後は国際論文をそのくらいのスピードで出せる能力を身に付けたいと思います。別に半年サイクルがいいと思っているわけではありませんが、それが出来る程度の研究筋を付けたいなと。

 

コンテンツを作る

XRコンテンツを作るのは楽しいですよね。特に自分は5~15分くらいの、XRデバイス以外のハードウェアとも組み合わせた、単発の体験のコンテンツを作るのが好きです。アテンドとかとも組み合わせて、体験者のモノの見方に不可逆的な変化を与えられるような作品を作りたいなと考えています。

 

自分の作品の元ネタは大体SF系から来ています。例えばMechanical Brain Hackingはテッド・チャンの「息吹」の中でロボットが自らの脳を開いて意識の所在を探索したシーンに大きく影響されていますし、新作のLLMエージェントを使った作品は打ち捨てられたアンドロイドがいつまでもマスターの帰りを待っている、みたいな絵からインスピレーションを受けて作りました。今の新技術で何を出来るかを理解し、未来を定義するようなプロトタイプを作ることが多分自分に合っているのだと思います。

 

おわりに

やりたいことが多すぎて、きっとやらないことを選ぶことも重要なのですが、やらないことを選ぶことはとにかくやることよりも難しいなと思っています。具体的な研究プランについてはここには書けなかったのですが、それ以外は大体整理されてきました。結局は、人との繋がりを作りつつ博論の構成を見据えて研究計画を立て、あとデファクトスタンダードも獲っていこう、って感じですね。また三年間楽しく過ごせたらと思います。

 

VRアプリをAR対応させて展示したら案外便利だった話 【Unity】【Quest3】【SIGGRAPH Asia 2023】

この記事は、Iwaken Lab.アドベントカレンダー2023の19日目の記事です。

prev→

【Stripe】超入門編:0から始める決済フォーム自動作成 #API - Qiita

next→
さくたまさん

 

はじめに

どうも、時化です。non-humanoidアバターとか身体編集に関する研究を大学院でやっております。

先日行われたSIGGRAPH Asia 2023というイベントで、AvatarForgeという没入型アプリを展示してきました。このアプリはVR空間内でノードベースかつリアルタイムにアバターの身体を編集できるというもので、だれでも簡単に整理された形で非人型アバター設計を行うことを可能にします。

AvatarForgeの動作の様子

このアプリの推しポイントには以下のようなものがあります。

アバターの構造とマッピングだけ作ってるので外見はCGerが後から創造的に作り直せる
アバター設計を構造化された形で記述でき、シェアや再編集も簡単
・非人型身体のプロトタイプを加速し、リハビリや人間拡張にも役立ちうる
・以前の作品(Mechanical Brain Hacking)から続けた「編集可能な身体感」

 

非人型アバター/身体のユースケースについては以前の記事をご覧ください。

shike-bengara.hatenablog.com

 

このアプリはVR空間で動作させて展示する予定でしたが、Oculus Integrationをベースに作成していたため、building blockを用いることでQuest3でのAR機能に簡単に対応させることができました。(AR開発については先日の土鍋君の記事をご覧ください。)

今回の記事は、そのAR表示に対応させたアプリを用いて展示してみたら、予定していたVRアプリの展示よりも色々便利だった、という話です。

 

 

AR展示にしてよかったこと

当初、今回の展示はUnity EditorとOculus Linkを繋いで、エディタ上でアプリを実行する予定でした。実行時にはディスプレイに体験者が操作するUntity画面が映るので、それを見つつ指示したりキーボード操作でちょっと体験者を手助けしたりすることが出来ます。

一方で、別の展示での体験から、動くのが一台だけではスループットが悪くなると考えたため、パソコンに繋がず単体で動作するビルド済みQuestを二個用意して置き、自由に体験を行って貰おうと考えました。なんとなくARで非人型アバター使えたら楽しそうだと考え、また現実世界での人間拡張のプロトタイプにも使えますよ~と説明するためにAR対応させておきました。

いざ展示が始まってみると、AR対応させたQuest3がアプリの説明にとても便利でした。お客さんがブースにやってきたら、先ずはアプリの説明をします。ここで、ARアプリであることによって、お客さんの顔を見つつ実際にデモを行うことが可能になっていました。画面はQuestのミラーリング機能を用いてPCにミラーリングし、それをディスプレイに映しました。また、体験者に安全にアプリを体験してもらうことも出来ました。VRアプリだとやはり歩き回ったり体を動かそうとした時にちょっと不安が残ります。外界が見えていることにより、安全に手を伸ばしたりすることができ、これによって「ちょっとブースの前で体験していってもらう」ことが可能になりました。更には、自分の連れに対して拡張した手を伸ばすような、AR的なインタラクションも確認されました。

今回の学会展示ではトーク発表も行う必要があったのですが、そこでも聴衆の反応を見つつリアルタイムデモを行うことが出来ました。

 

このように、VRで十分に動くものであっても、AR対応させることで展示に役立つ可能性があります。AR対応の利点を纏めると以下のようになります。

1. 聴衆の反応を見つつデモを行える

2.安全性が高い

3.AR的なインタラクションを行え、連れも暇しにくい

 

是非、皆さんの展示物もAR対応してみてください。よき開発研究ライフを。

 

おまけ:シドニー最高

今回の学会はオーストラリアのシドニーで開催されました。オーストラリア政府が補助金を出してるとかで、結構な数の学会がシドニーに誘致されていると聞きます。

シドニーは治安も良く、国籍豊かな人々が暮らしているためか英語が聞き取りやすく、会話が簡単であり、またご飯も美味しく、気候も快適そのものでした。ここ数年ではカナダ・アメリカ・韓国・フランスと行ったのですが、そのどれよりも楽しく過ごせました。また行きたいものです。

土着の鳥 アイビス

人体トラッキングによって人体から取り出せる情報量は何bitになるのか、という考察とポエム

全身をトラッキングしたい......したいのか?

 前回の記事で、特に手首から指先にかけてのトラッキングについて説明しました。

shike-bengara.hatenablog.com

そもそもこのようなトラッキングをする目的として、「何らかの身体動作を入力とし、何かを動かす」ことが挙げられます。例えば手のジェスチャーをトリガーとして音楽を再生したりとか、トラッキングされた動作をそのまま用いてアバターを動かしたりといった感じです。

 

身体動作を入力とする行動の整理

一旦、「測定対象」の測定結果を計算や機械学習によってよしなにして、「身体動作」をトラッキングし、それを「変換(フィルタリング?写像?操作?)」して「出力」を生む、としたフレームワークを用いて、身体動作を入力とする行動を理解しようとしてみましょう。

 

「測定対象(測定手段)」

  • 筋肉の電位(筋電センサ)
  • 画像(カメラ)
  • 深度画像(ステレオカメラ)
  • 慣性(慣性センサ)
  • 磁界(磁気センサ)
  • 曲げ(静電容量センサ)
  • 圧力(圧力センサ)(ex.つもり制御)
  • ボタン/スライダ入力(エンコーダ)(ex.ロータリーエンコーダで関節角を測る、とかVRコンのボタンを押しているときにその指が曲がっているものとする、とか)

「身体動作」

  • 完全な関節の移動、回転
  • 不完全な関節の移動、回転(指が曲がっている/曲がっていない くらいの精度 情報が落ちている)
  • ジェスチャー(さらに情報が落ちている)
  • 表情
  • 筋肉の動作、力(実際には関節が動いていないことも)

「変換」

  • 動作をそのまま再生する(連続値的に)
  • 動作を別の動作に変換する(連続値的に)
  • 動作を別の種類の動作に変換する(連続値的に)
    (ex.手の高さを音の高さに変換)
  • 動作をトリガーとする(ニ値的に)

「出力」

  • 人型のアバターの動作
  • 非人型のアバターの動作
  • その他の連続値の「滑らかな」操作
    • 音程とか音量とか
  • その他のシステムのニ値的な操作
    • ドアが開くとか
    • スティック入力みたいにも扱える

 

このフレームワークで全てが説明できるのか、chatGPTに人間の行動によって何かが動くシステムの例を出させて確かめてみます。

うーん...

人間が何かを入力してはいるものの、音声とかを入力にできるのは上で考えていませんでしたね。

 

勿論、人間がシステムを動かすためには、身体動作をトラッキングする入力の他にも音声入力やらキーボードやボタン・スライダを使う入力(の中で、特に操作者の身体動作自体を入力として復元しようとしていないもの)などが存在します。これらの入力方法と比べ、身体動作をトラッキングし、入力とするインタラクションが優れている面は何でしょうか。

 

一つには、操作学習をしやすく、無意識的に扱える、つまりインタラクションを身体化できる*1可能性が存在します。例えば、アバターやキャラクターやロボットアームを(一人称視点で)動かすためには、ボタン入力やスライダ入力によって操作するよりも、身体動作を入力としたインタラクションの方が直感的になることが考えられます。物体の表面座標を指し示すときも、十字ボタンで座標を指し示すよりも、人差し指でそれを指さす方が直感的でしょう。同じ自由度(ここでは、アバターの関節の回転角と移動の全体とか、二次元座標xyとか)を持つ対象を操作するときに、十字ボタンやスライダ、キーボードといった身体動作が捨象され自由度だけが別の形で取り出される入力を経由せず、身体の動作をそのまま用いることができれば、より操作対象を身体化できると考えられます*2

 

二つ目には、人間の身体が持つ独立する動作自由度を同時に入力と出来ることが利点として考えられます。例えば5本の指を入力とすれば、DJの同時再生と音量調節を5本同時に行うことが出来るようになります。また、クトゥルフの髭のような、めっちゃ自由度が大きいものを完全に操作するには、当然ながら人間から自由度を沢山取り出すことが必要になります(AIにサポートさせるのも方針として在り得るけれど)。しかしながら、このような「多自由度を入力としたい」場面が実生活の中であまりなく、それこそ身体拡張とかアバター操作の文脈でしか語れない点が弱くはあるんですが......

冷蔵庫を開けるとか動作に合わせてライトを付ける、のような簡単な操作は、ボタン入力とか「身体全体がこの領域に入ったか」のbool値の入力で十分です。世界の操作対象の大体は、身体の多自由度を活用しなくても十分な状態の数しか持っていないんですよね。良いユースケースを思いつきたい。

 

人間の体から沢山の操作の自由度を取り出せ

ここまで書いて気づいたのですが、身体動作を入力とした対象物の操作において重要となるのは、人間の体から独立且つ同時に取り出すことが可能な入力の数です。ここでは、これを自由度と呼ぶことにしましょう。情報量とか状態の数とかにも近いイメージです。

独立というのは、例えば足の指からは関節の配置的には沢山自由度をとれそうだけれど、実際には足の関節は連携して動くので自由度が縮退している、という感じです。

同時というのは、ラジコンのプロポの多チャンネル性みたいなものです。時系列方向の自由度を上手く活用すれば、1bitの操作入力でも理論上無限の操作を行うことが出来ますが、ある操作を行っているときに別の操作を行うことが難しくなったり、非直観的な操作になったりします。そんなわけで、同時に別のチャンネルの自由度を取り出すことが求められると考えています。

 

入力として取り出せる自由度は、「トラッキングする部位が潜在的に持つ自由度」が「トラッキングシステムの性能」に抑えられることにより求められると考えられます。具体的な話をすると、そもそも手指の自由度はめちゃくちゃ高いですが、Manus Quantiumグローブでは親指の第三関節が逆に曲がる動作などをトラッキングできない分少し入力として取れる自由度が下がります。Quest2のハンドトラッキングでは各指のミリmm以下の動作や小指の動作が正確に取れなくなったり、第三関節と第二関節の独立した動作を取りにくくなったりするので、入力として取れる自由度はさらに下がります。筋電トラッキングやIndexコントローラーによる指トラッキングでは、更に各指の動作の解像度が下がり、もはや各指の開閉の値(bool値×5)の5bitの情報しか取得できません。

当然ながら、取り出せる自由度が大きいほど、複雑なシステムを精確に操作できるようになります。人型のアバターはより精確に動かせるし、マッピング/リマッピングを行えばより多くのシステムや多くの身体パーツを持つ身体を操作できるようになります。

でも、本当にたくさんの自由度が必要?

自己批判

そうは言っても、操作されるシステム側を上手く組めば限られた入力の自由度でも十分ぢゃね?例えば蛇の身体を操作するときって自由度をめちゃくちゃ使って完全に操作しなくても、身体をスパースに操作すれば良くない?例えばメデューサの髪を操作したいときには、それぞれの蛇に沢山の自由度を使って操作する代わりに、蛇の頭の部分だけを操作して体の動きはIKで解けばいいし、さらには一部だけを操作して残りはアニメーションだけさせれば良くない??

 

解答:

操作対象の設計を工夫したりAIとか使ったりして、少ない入力自由度で多くのものを操作するアプローチも勿論大事だが、入力自由度を増やせば、さらに多くのもの、デカいシステム、複数の同時に独立したチャンネルで動くパーツを、主体的に操作することができる。

1bitの入力では、AIやら何やらを使ったとしても、アバターの手を主体性を持って動かすことは不可能である。(正確には、bool値をトリガーにグーパーを作ることは出来るし、時系列的に入力を行えば手をある程度動かすことは出来そうだけど、それぞれの指を独立させて自由に動かすことはどうあがいても不可能)。1bitのキーボードがあれば時系列的に様々な入力を行うことが出来そうだけど、そんなキーボードは使いたいか?ctrl+vを押す代わりに1bitのキーボードでモールス信号で「・--・- (ペースト)」を入力したいか?ある部位を操作している間に意思決定が更新されても、別の部位を操作できないのは辛くないか?つまり、多チャンネル入力はありがたいよねという話である。「音声入力で全部良くない?」っていう考え方も同様に否定される。

 

ある操作対象があった時に、それを主体性を持って、かつ操作対象の各部位を同時に直観的に精確に操作するために必要な最小の自由度が存在するはずである。そして、その操作対象がクソでかになっても主体的に操作できるようには、より多くの自由度を取り出す他ない。

 

そんなクソでか操作対象が実際に存在するのか?ユースケースは?と言われたら、難しいところである。隣の研究室の同期からそこが欠けているとHCIじゃなくない?と言われた。人間の可塑性の限界に迫りたい...

人間の可塑性の限界に迫る

そもそも私が興味がある部分はここで、「人間はどこまで非人型の身体を操作できるか」という問いを解きたいと思っている。この問いに関連し良くやられているのが、人間の体から自由度を取り出して別の身体にマッピングするという方法で、例えば手と足の操作を入れ替えたり右手の親指でバーチャルな左腕を操作したり、第三の腕を足で動かしたり、第六の指を拮抗筋の筋電を利用して動かしたりされている。自分が作ったMechanical Brain Hackingでは、ロボットアバタというメタファーを利用して、体験者自身に手足の操作のマッピングをリアルタイムに編集させたりしていた。

www.youtube.com

これらの手法では、入力の自由度を別の身体の動作自由度に変換するアルゴリズムを、どうするのが適切か、ということが一つの大きなトピックである(と私は考えている)。

 

しかしながら、この「マッピングの検討」だけでは、可塑性の限界という問いには到達できないと最近考え始めた。

クトウルフ(ファミ通)

例えばクトゥルフアバターの髭を触手のように完全に操作することは現状出来ない。人間の体から現時点の技術で取れる自由度を全て使ったとしても、操作のための自由度が不足しているからである。(触手は実はnパターンに動けば十分です!という結果があれば、もしかしたら足りているかもしれないけれど。)

本当に解きたい人間の可塑性という問いの中には、「人間が認知的にどこまで自由度が高い身体を操作できるか」も含まれているのに、結局人間の身体をトラッキングしてマッピングする以外の手法がないために、「人間からトラッキングできる自由度を用いて、どこまでの身体を操作できるか」という、トラッキング手法の限界に抑えられたより地に足のついた問いを解いているのが現状かなと思う。悲しいね。

 

よって、上の問いにアクセスするために、人間の体からより多くの自由度を取り出すことが必要だと考える。



理想的なBMIがあったら?

「独立且つ同時」な自由度をいくらでも人間が認知可能な限りで取り出すことができる、とても理想的なBMIがあったら、「人間が認知的にどこまで自由度が高い身体を操作できるか」の問いを遂に解くことが出来そうだ。

人間が身体以上の自由度を持つ身体を操作した時に意識は「大きく」なるのか?二値でアニメーション制御する尻尾と、連続値制御ができる尻尾の操作では意識の「大きさ」が違うのか?意識はどこまで「大きく」なれるのか?

現状のマッピングによる新たな身体の操作は、時系列的な切り替えを除いて考えれば、結局のところ人間の体から同時に取り出せる自由度の数によって新たな身体のデザインが抑えられている。その限界を突破したときに、個としての人間の意識はどこまで「大きく」なれるのだろうか。気になる~~~~~

 

youtu.be

まあ、そんなことを言っても現状のBMIから取れる自由度は僅かです*3。上の動画は2021年のNeuralinkの有名な動画で、猿がテーブルテニスのバーを上下にBMIで動かしている奴ですね。多分bool値×2チャンネルの2bitしか取れていないんじゃないかな...?ワイヤレスなのが凄い。

www.youtube.com

これは2018年くらいの石黒先生の研究室の研究ですが、結構アンドロイドの手を動かすことが出来てそう。凄い。

まあ、それにしても人間の身体をトラッキングして取り出せる以上の自由度をBMIにより取り出せたり、またそれがウェアラブルになって常にアクセスできる未来はまだ遠そうなので、まだ数年は身体をトラッキングしてマッピングを考える分野が生き残るんじゃないかなと思う。

 

自由度の質、評価

ところで、自由度自由度と言ってきたが、それは定量値であるように見えてどのように評価すればいいか分からない、結構あやふやな概念である。

例えば、人差し指と小指の第三関節(根元の関節)の開閉方向の回転だけを考えてみよう。それらの開閉を、0~1の連続値にマッピングすることは出来そうだ。しかし、人差し指の方が小指より精密に動く分だけ、解像度?濃度?のようなものが高く、それを入力として用いるときの情報量は大きくなるはずである。

また、連続値としての入力でなく、bool値としての入力しかトラッキングできない場合も存在する。上にも書いたが、例えばIndexコンによる指の開閉の入力はそんな感じである(本当は三段階くらい取れるっぽいけど)。手で握りこんでるコントローラー部分にタッチセンサがあって、それで各指を閉じているか開いているかを判定している。

www.youtube.com

他には、腕に付ける筋電センサなんかも結構取れる自由度の質は低く、指の開閉しかとれなていない。

 

ラッキング部位+トラッキング装置のペアは、一つの自由度を持つ。その自由度同士を比べるにはどうすればいいだろうか?あるペアは「ある解像度aの連続値A」と「ある解像度bの連続値B」と「ある解像度cの連続値C」をメンバ変数として持っており、他のペアは「ある解像度dの連続値D」と「ある解像度eの連続値E」をメンバ変数として持っているとして、これらから取り出せる自由度の大きさをどのように比較すべきか?

 

ある指の関節の駆動範囲が64度で、人間がその関節は1度ずつ動かせるとした場合、それは入力としては64段階=6bitの情報量を持つような気もする。(これは同時に6チャンネルでbool値を送れるという意味。)しかし、1度ずつ動かせることは1度単位でその関節の角度を指定できることとは異なり、例えば0度→40度→30度→60度の動きを一度の狂いもなく出来る人間は、その指関節にサーボモータを埋め込んでいるのでもない限り、いないと思う。(このような考え方をすると、ダンサーさんの身体は情報量を多く持てる?指関節は頑張っても8段階くらいにしか正確に切り替え可能に動かすことができず、そう考えると3bitの情報量しか持てないような気もする。人間の身体動作の入力をbit数で扱うとき、この関節は3bitと考えるべき?6bitと考えるべき?

勿論、トラッキングする手法の解像度によってもbit数は落ちる。2mmがトラッキングできる最小の解像度の場合だと、前者の手法で取得できるのは32段階/5bitになるし、後者の手法で入力できるのは3bitのままである。

(この辺りのことを考えていた翌日、篠田先生がハプティックスの講義の中で皮膚感覚のデジタル化の話をしており、皮膚感覚に関してほぼ同じアプローチでデジタル化を考えていたので個人的に盛り上がった。)

 

更には、薬指と小指の非独立性なども、自由度の大きさを落とす原因になりそうだけれど、どのように評価すればいいか見当もつかない。薬指が3bit、小指は2bitの情報を持てるけど、合わせたときには自由度が落ちて4bitになるかもしれない。

 

もしも、このような「トラッキングする部位」と「トラッキング手法」によって入力に使える自由度の大きさ、情報量を定量化する手法ができたら最高だし、恐らくbit数とかで記述することは出来ると思うが、今後の課題である。BMIによる入力とかと身体トラッキング入力を比較する手段としても使えそう。

 

この図に対しても、「この段階では何bitで、この段階で自由度が落ちてて....基本的に自由度は上から下で落ちていくよね」みたいな説明をより具体的に出来て嬉しそうである。

 

友人にこれを解きたい、と言ったら「マッピングに対する入力の部分を定量化するのはアツいけれど、結局ものを使うときにはマッピングの方が大事だし、操作する対象を意識しないとHCIじゃないんじゃない?」って言われた。HCIって何なんだよ。

 

主張まとめ

  • 人体トラッキングによって取得できる、システムへの入力として使える情報量や自由度はbit数とかで評価できそう
    • 指関節は0~1の連続値で動くけど、入力として使える情報量はトラッキングシステムの解像度の限界や指の動作の精密性の限界で抑えられる、と思う
  • 人間の魂から理想的なBMIを用いて取り出せる限界の情報量 >= 身体動作の持つ情報量 > トラッキングシステムによって取り出せる情報量, 今のBMIによって取り出せる情報量 >= システムの操作に必要な自由度 
    • 最後の>は操作に必要となる要件、それ以外の>は公理
  • 大きな自由度が操作に必要なシステムを操作するためには大きな自由度を取り出すことが求められる
    • 入力の自由度を用いて色々操作して出力(システムの操作)を行う部分の認知的に楽なマッピングの設計やフィードバックシステムの設計は別の問題
    • 現在はトラッキングによって取得できる自由度に限界があるため、操作できるシステムの大きさにも限界がある
      • (勿論、人間の認知がシステムの大きさのボトルネックになっていると考えられる例もあるけれど...)
  • 人間の意識から直接自由度を取り出せるようになれば、クトゥルフの触手など、操作により大きな自由度を有するものも手足のようにフルコントロールできる可能性があり、そのときに人間の意識や魂は「大きく」なるのかが気になる

*1:言葉の濫用

*2:要出典

*3:サーベイしないと

指トラッキング(Hand Tracking, Finger Tracking)概観

指をトラッキングしたい!!

手指は人間の身体の中で最も器用に扱える部位であり、それをトラッキングすることは、仮想環境でのインタラクションや機器への様々な非接触ジェスチャー入力など様々に役立ちます。

ペンフィールドの脳地図。感覚野でも運動野でも手や指が大きな部分を占めている。

自分のVR・HCIに関する研究でも指トラを用いたい場面が多くあります。しかしながら、指トラの手法はカメラ式のものやグローブ式のもの、筋電を使うものまで様々であり、またデバイスの選択肢も数多くあるので、初心者にとってはどの手法・デバイスを使うのが良いのか迷ってしまうことも多いでしょう。

 

そこで、本記事では指トラッキングの様々な手法・デバイスについて整理します。

この記事は私の研究室とは関係がない内容であり、あくまで個人的な意見や情報を提供するものです。また、記事中には自分でも検討中の項目が多く含まれるため、間違いが存在する可能性があります。

 

 

カメラトラッキング

恐らく最も手軽に手指をトラッキングできるのがこの手法です。この手法では、環境や身体に取り付けられたカメラの映像を用いて、指の姿勢を推定します。指に何も付けなくて良いため、日常の動作を阻害しない(拘束性が低い)ことが嬉しいです。また、値段も安い傾向にあります。

 

先ずはHMDにマウントされているカメラを用いた手法を紹介します。Meat Quest2,3やVarjo、Vive Pro等では、HMD前面に付けられたカメラを用いて指トラッキングを行うことが出来ます。ハンドトラッキングの精度は、ゲームなどには問題がありませんが、手の角度によってはズレが存在したり薬指や小指が大きくブレたりすることがあったりします。また、カメラの範囲外は当然ながらトラッキング出来ません。

 

VRに限らずより一般的に用いられるトラッキングバイスとして、Ultraleapが存在します。搭載された赤外線(Infrared, IR)LEDから出した光で手を照らし、赤外線カメラで撮っています。LeapMotionというデバイスの後継機であり、とても簡単にハンドトラッキングができ、また外部との連携も簡単なことが特徴です。

(世代によって結構形が違う)

Ultraleapは机の上などにセットする他に、HMDの前面にマウントすることもできます。

Ultraleap Hand Tracking for Pico Neo 3 Pro | bestware

机の上にセットした場合のトラッキング性能は結構良く、機械学習の学習データだったり新たなトラッキング手法を提案した時のベースラインとして使われていたりもします。HMDにマウントした場合の性能もそこそこ良く、Quest系に備え付けのカメラによるトラッキング結果よりも手の重なりに強く、また指の曲がりも精度良く取れている気がします。しかしながら、それでも尚角度によっては指にズレが生じたり、視界の外はトラッキングできないという問題があります。なお、前述のVarjoという高額なHMDにはUltraleapと同じハンドトラッキングプラットフォームが搭載されています。

 

MediaPipeなど、画像処理により通常のwebカメラの映像などから手の姿勢を推定するライブラリも存在します。2DのVtuberなどの実装に使われている印象です。カメラを一台しか使っていないので精度はそこそこです。

https://developers.google.com/mediapipe/solutions/vision/hand_landmarker

 

 

FingerTrak(2020)やDigits(2012)や石川グループ研究室のAnywhere Surface Touch(2014)など、手首に(IR)カメラを装着して指の動きをトラッキングしようとするプロジェクトも存在します。これらの手法は手の位置を自由に動かすことができ、トラッキングロストが少ないという利点を持ちます。期待できるユースケースとして、キーボードから解放された入力デバイスとして用いることが考えられます。しかしながら、まだこのような方式を採用したジェスチャ入力デバイスは私の知る限り発売されていません。使いたいのに......

youtu.be

youtu.be

光学式トラッキング

この手法では、指に何らかのマーカーを付けてトラッキングを行います。反射マーカー

例えばOptiTrackはよく全身トラッキングやオブジェクトトラッキングの為に用いられています。このような反射マーカーをスーツやオブジェクトに装着するもので任意のものをトラッキングでき、勿論指もトラッキングすることができます。他にはViconという製品もあります。

自分が使ったことはないのですが、トラッキング結果は結構精度よく時間分解能が高いと聞きます。例えばOptitrackをピアノの指のトラッキングに用いた研究が存在します。

https://mocap.jp/optitrack/finger/

しかしながら、光学式トラッキング手法はマーカーのオクルージョンに弱く、またマーカーを装着する必要があり拘束性が高く、更にはトラッキングカメラも環境側に存在しないといけないという欠点があります。上のピアノの研究はカメラの配置などを結構頑張ってると思います。

グローブトラッキング

この手法では指に色々なセンサが入ったグローブを付けて指をトラッキングします。磁気センサや圧力センサ、慣性センサなど、様々な種類のセンサが用いられています。

 

Quantum Metagloves | Manus グローブ型デバイス | 株式会社アスク

自分が使ったことがあるものの中では、Manus Quantum Metagloveは磁器センサを用いてトラッキングを行っています。指の先端に付けた磁力を持つチップによる磁界の変化を、手の甲側の装置で観測することで姿勢を推定します。精度はUltraleapよりも高く、指の姿勢のミリ単位での変化や、第三関節を曲げずに第二関節だけを曲げるような動作などを正確に取得することが出来ます。しかし、磁気に擾乱がある環境(PCの近く10cm以内など)では精度がちょっとだけ低下します(他の慣性式グローブや磁気式グローブはよりは良い印象です)。また、グローブでのトラッキングに共通する課題として、拘束性が高く指の動作を阻害するという点が存在します。例えばManus Quantumグローブでは指の先端のチップ同士が触れあうために手を握りこみ辛くなっています。

 

Perception Neuronは、右の慣性センサーを指先や手の甲のスリーブにはめ込んで動作させます。センサーはジャイロス、加速度、磁力を計測しており、それの組み合わせから姿勢が計算されます。指先に限った測定性能は、オクルージョンこそ発生しないものの、姿勢の精度自体はUltraleapと同程度だった印象です。Perception Neuronは全身トラッキングに用いますが、それの手部分だけを取り出したようなものがNoitom Hi5グローブになります。

 

StretchSenceは静電容量式の伸縮センサを用いており、手に良くフィットします。SIGGRAPHの会場で体験したのですが、結構精度も良く、第二関節の曲げまで測定できた印象です(Manus Quantumよりは精度低かった気もする)。オクルージョンとか磁気による干渉を受けないと公式サイトには書いてありました。

 

筋電トラッキング

筋電センサを用いて指先の動きを取得しようとする動きも存在するようです。

物を把持した状態における筋電センサを用いた ハンドジェスチャ入力の問題抽出と新手法の提案 より引用

電極の数が多くなるほど識別できるジェスチャ入力の数は増えるが、ウェアラブル性が薄くなるらしいです。ジェスチャを識別する研究については沢山あるようだが、指の一本一本の動きを正確に検出しようとする研究は簡単には見つからりませんでした。筋電によって動かされる義手も基本的にはジェスチャ入力、すなわちスイッチによるアニメーションの再生であるようです。

Unlimited Handでは筋電から指の動きのトラッキングをしているようですが、自由度は指の開閉しかないように見えます。

youtu.be

 

比較

以上のトラッキング手法を比較します。

個人的には、VR実験やHCI実験には基本的にHMD据え付けのカメラやUltraLeapで良く、小指や薬指や第二関節の運動を正確に取得したいならOptiTrackやManus Quantiumを使うのかなと考えます。また、これらのトラッキング精度と手指の非拘束性を両立したものは現状無さそうです。

 

よい指トラッキングライフを(?)

 

//TODO(その内追記する)

・手首の回転は取れるか

・筋電トラッキングの他の例(喉など)

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

映画を見る会用Slack botの作成

今回作ったもの

ラボで映画を定期的に見る会が立ったので、各人が見たい映画を各々追加し、またその映画リストの中からランダムな映画を推薦してくれるslack botを作成しました。

画像

こんな感じで動きます。

手順については大まかにしか記していませんが、GASのコードを残しておきますので、誰かの助けになればと思います。

機能:

  • cinema add <title>で映画を追加
  • cinema remove <title>で削除
  • cinema list で現在のリストを確認
  • cinema next で次に見る映画をランダムにレコメンド

構成:

Google スプレッドシート + GAS (Google Apps Script) + slack api 

 

参考:

GASでSlackのinteractive messageの作成 ① Webhookアプリ編 #Slack - Qiita

SlackBotへのメンションをトリガーにメール送信する方法 #Slack - Qiita

Slack Appの作り方を丁寧に残す【BotとEvent APIの設定編】

 

作成手順:

  1. https://api.slack.com/ からYour Appsを作成
    1. Create New App→From Scratch

    2. 適当に名前とアプリを入れたいワークスペースを追加します
    3. Basic InformationのAdd featurs and functionalityからIncoming webhhooksを追加



    4. 一番下のAdd New Webhook to Workspaceから、ワークスペースの中の投稿したいチャンネルを選択
      (ここまでで、メッセージをチャンネルに投稿できるようになる。Sample curl requestをターミナルで実行すれば、"Hello, world!"のメッセージがチャンネルに投稿されるはず。)

      アプリの名前とアイコンはBasic Informationの下の方から追加できます。
  2. Google スプレッドシートを開いて、webアプリを作成する
    1. スプレッドシートを作成
      今回は3列目をデータとして用いる。テスト用に適当なタイトルを入力しておく。
    2. 拡張機能のタブからApps Scriptを追加
    3. 以下の関数を作成
      function doPost(e) {
        // testMessage();
        var params = JSON.parse(e.postData.getDataAsString());
        var response = {};
        if (params.type === 'url_verification') {
          return ContentService.createTextOutput(params.challenge);
        } else if (params.type === 'event_callback') {
          if (params.event.type == 'message') {
            response = eventHandler(params.event);
          }
        }
        return {};
        // return ContentService.createTextOutput(response).setMimeType(ContentService.MimeType.JSON);
      }
       
      function eventHandler(event) {
        return {};
      }
      slackのEvent Subscriptionのチェックを通すために、送られてきたメッセージがurl_verificationだった時にchallengeを返すようにしておく。後でeventHandler内を実装し、メッセージに合わせて処理を行うようにする。
    4. アプリをデプロイする。アクセスできるユーザーの範囲を全員に広げておく(本当はもっと狭めるべきかもしれない)。
    5. デプロイしたアプリのurlをコピーしておく。
  3. スプシとslack apiを連携させる
    1. slackのアプリを作るwebサイトの方に戻って、Event Subscriptionを開く
    2. URLのところに先ほどのGASのwebアプリのurlを貼り、Verifiedされたら成功。失敗した場合はエラーメッセージをググる
    3. Subscribe to events on behalf of usersの所から、message.channelsに対するサブスクライブを行うように設定する。


      これでslack botがチャンネル内のメッセージを読み、GASに送信できるようになる。読むたびにdoPost()関数が実行される。
      function testMessage() {
        //Webhook URLを以下に入力
        const postUrl = "<your app url>";
        const sendMessage = "test";
        const jsonData = {
          "text": sendMessage
        };
        const payload = JSON.stringify(jsonData);
        const options = {
          "method": "post",
          "contentType": "application/json",
          "payload": payload
        };
        UrlFetchApp.fetch(postUrl, options);
      }
      こんな感じの関数をGASに追加してテストしてみる。この関数を実行すると、slackに"test"というメッセージが飛ぶ。

      GASの実行ボタンから関数を実行しても良いし、上のdoPost()関数のどこかに追加して実行されているか試してもいい。
  4. GASのスクリプトに処理を追加する。
    1. 最後に、読んだメッセージに合わせて映画リストを編集したりslackに投稿したりする機能を作成する。スクリプトは以下。
      function sendMessage(text) {
        //Webhook URLを以下に入力
        const postUrl = "<>";
       
        // メッセージを加工
        const formattedMessage = text + "\n ```" + createMessage()+ "```"; // 引用枠で囲まれたテキストとcreateMessage()の内容を結合

        const jsonData = {
          "text": formattedMessage
        };
        const payload = JSON.stringify(jsonData);
        const options = {
          "method": "post",
          "contentType": "application/json",
          "payload": payload
        };
        UrlFetchApp.fetch(postUrl, options);
      }


      function testMessage() {
        //Webhook URLを以下に入力
        const postUrl = "<>";
        const sendMessage = "test";
        const jsonData = {
          "text": sendMessage
        };
        const payload = JSON.stringify(jsonData);
        const options = {
          "method": "post",
          "contentType": "application/json",
          "payload": payload
        };
        UrlFetchApp.fetch(postUrl, options);
      }

      function chosenMessage(text) {
        //Webhook URLを以下に入力
        const postUrl = "<>";
        // メッセージを加工
        //最後の文字を幾つかのパターンからランダムに変える "お楽しみに!"など
        const lastMessages = ["お楽しみに!", "ポップコーンをお忘れなく!","いってらっしゃい!","研究ネタが見つかるかも!?","コーラをお忘れなく!","ピザでも頼む?","初めて見る?","アメージング!!","予定は空いてる?","CHILL OUT!","見たことあるかな?","これは教養だね!","これは必修だよね!"];
        const random = Math.floor(Math.random() * lastMessages.length);
        const lastMessage = lastMessages[random];
        const sendMessage = "次回の上映は *" + text + "* ですよ!\n" + lastMessage;
        const jsonData = {
          "text": sendMessage
        };
        const payload = JSON.stringify(jsonData);
        const options = {
          "method": "post",
          "contentType": "application/json",
          "payload": payload
        };
        UrlFetchApp.fetch(postUrl, options);
      }

      function createMessage() {
        const spreadsheet = SpreadsheetApp.getActiveSpreadsheet();
        const sheet = spreadsheet.getSheetByName("schedule");

        const data = sheet.getRange(2, 3, sheet.getLastRow() - 1, 1).getValues();
        const messages = ;

        for (const row of data) {
          if (row[0]) { // 空でないセルのみを処理
            messages.push(row[0]);
          }
        }

        return messages.join('\n');
      }

      function doPost(e) {
        // testMessage();
        var params = JSON.parse(e.postData.getDataAsString());
        var response = {};
        if (params.type === 'url_verification') {
          return ContentService.createTextOutput(params.challenge);
        } else if (params.type === 'event_callback') {
          if (params.event.type == 'message') {
            response = eventHandler(params.event);
          }
        }
        return {};
        // return ContentService.createTextOutput(response).setMimeType(ContentService.MimeType.JSON);
      }

      function eventHandler(event) {
        if (event.text.startsWith("cinema add")) {
          const valueToAdd = event.text.replace("cinema add", "").trim(); // メンション部分を削除
          // スプレッドシートにデータを追加
          addValueToSpreadsheet(valueToAdd);
          return sendMessage("追加したよ!");
        }

        if (event.text.startsWith("cinema list")) {
          return sendMessage("今後の上映予定は以下の通りだよ!\n" + createMessage());
        }

        if (event.text.startsWith("cinema remove")) {
          const valueToRemove = event.text.replace("cinema remove", "").trim(); // メンション部分を削除
          // スプレッドシートからデータを削除
          removeValueFromSpreadsheet(valueToRemove);
          return sendMessage("削除したよ!");
        }

        if (event.text.startsWith("cinema next")) { //ある映画リストから一つだけランダムに抜き出してそれをslackに返す、抜き出した後は削除
          return nextTitleFromSpreadsheet();
        }

        return {};
      }

      function nextTitleFromSpreadsheet(){
          const spreadsheet = SpreadsheetApp.getActiveSpreadsheet();
          const sheet = spreadsheet.getSheetByName("schedule");
          const data = sheet.getRange(2, 3, sheet.getLastRow() - 1, 1).getValues();
          const messages = ;
          for (const row of data) {
            if (row[0]) { // 空でないセルのみを処理
              messages.push(row[0]);
            }
          }
          const random = Math.floor(Math.random() * messages.length);
          const randomMessage = messages[random];
          removeValueFromSpreadsheet(randomMessage);
          chosenMessage(randomMessage);
      }

      function removeValueFromSpreadsheet(value){
          const spreadsheet = SpreadsheetApp.getActiveSpreadsheet();
          const sheet = spreadsheet.getSheetByName("schedule");
         
          // スプレッドシートから既存のデータを取得
          const data = sheet.getRange(2, 3, sheet.getLastRow() - 1, 1).getValues();
          // ↑ getRange 関数によって、3列目(C列)のセルからデータを取得し、
          // 2行目から始めて、最終行までのデータを取得します。
         
          // 値を削除
          for (let i = 0; i < data.length; i++) {
              if (data[i][0] === value) {
              // 値が一致した場合、そのセルを空白に設定
              sheet.getRange(i + 2, 3).setValue("");
              // ↑ i + 2 はスプレッドシートの行インデックス。i は配列のインデックスなので、+2 して行インデックスに変換します。
              break;
              }
          }
      }

      function addValueToSpreadsheet(value) {
        const spreadsheet = SpreadsheetApp.getActiveSpreadsheet();
        const sheet = spreadsheet.getSheetByName("schedule");

        // スプレッドシートから既存のデータを取得
        const data = sheet.getRange(2, 3, sheet.getLastRow() - 1, 1).getValues();
        // ↑ getRange 関数によって、3列目(C列)のセルからデータを取得し、
        // 2行目から始めて、最終行までのデータを取得します。

        let foundEmptyCell = false;

        // 最初の空白のセルに値を追加
        for (let i = 0; i < data.length; i++) {
          if (!data[i][0]) {
            // 空白のセルが見つかった場合、そのセルに値を設定
            sheet.getRange(i + 2, 3).setValue(value);
            // ↑ i + 2 はスプレッドシートの行インデックス。i は配列のインデックスなので、+2 して行インデックスに変換します。
            foundEmptyCell = true;
            break;
          }
        }

        if (!foundEmptyCell) {
          // 空白のセルが見つからなかった場合、新しい行に値を追加
          sheet.appendRow(["", "", value]);
        }
      }
      eventHandler内で、メッセージの最初の数文字に合わせて何らかの処理を行うようにしておく。これで完成。

 

最後に

今回は特定の文字列に対して反応するようにしたが、メンションに対して反応する方が正しい気がする。まあ最低限動いたので、一旦はこれで良しとしよう。

AnovaRMでエフェクトサイズ(partial eta squared)を出力したい Google Colab向け

論文を書いていたらAnovaRMはp値とF値は出力するものの、エフェクトサイズは出力しなくて困ってしまった。どうやらエフェクトサイズは書くものらしい。Rで計算しなおすのも一旦はいいや...ということで、AnovaRMを拡張してanova_tableにエフェクトサイズを出力させる。

 

[pystatsmodels] AnovaRM sum of squares to get effect size?

肝心のエフェクトサイズを出力するようにAnovaRMをカスタマイズするコードに関してはこちらのブログのものを流用した。このままではColabで使いにくいので、Colabでも実行できるようにする。

 

AnovaRMのサブクラスとしてCustomAnovaRMというクラスを作成、そこでfit()をオーバーライドする。

statsmodels/statsmodels/stats/anova.py at main · statsmodels/statsmodels · GitHub

これが元コードで、ここから色々importする。

! pip install patsy
import patsy
from scipy import stats
from statsmodels.stats.anova import  _not_slice
from statsmodels.stats.anova import AnovaRM
from statsmodels.stats.anova import AnovaResults
from statsmodels.stats.anova import _ssr_reduced_model
from statsmodels.regression.linear_model import OLS
class CustomAnovaRM(AnovaRM):

  def fit(self):
    """estimate the model and compute the Anova table

    Returns
    -------
    AnovaResults instance
    """
    y = self.data[self.depvar].values

    # Construct OLS endog and exog from string using patsy
    within = ['C(%s, Sum)' % i for i in self.within]
    subject = 'C(%s, Sum)' % self.subject
    factors = within + [subject]
    x = patsy.dmatrix('*'.join(factors), data=self.data)
    term_slices = x.design_info.term_name_slices
    for key in term_slices:
        ind = np.array([False] * x.shape[1])
        ind[term_slices[key]] = True
        term_slices[key] = np.array(ind)
    term_exclude = [':'.join(factors)]
    ind = _not_slice(term_slices, term_exclude, x.shape[1])
    x = x[:, ind]

    # Fit OLS
    model = OLS(y, x)
    results = model.fit()
    if model.rank < x.shape[1]:
        raise ValueError('Independent variables are collinear.')
    for i in term_exclude:
        term_slices.pop(i)
    for key in term_slices:
        term_slices[key] = term_slices[key][ind]
    params = results.params
    df_resid = results.df_resid
    ssr = results.ssr

    anova_table = pd.DataFrame(
        {'F Value': , 'Num DF': , 'Den DF': , 'Pr > F': })

    for key in term_slices:
        print(key)
        if self.subject not in key and key != 'Intercept':
            # Independent variables are orthogonal
            ssr1, df_resid1 = _ssr_reduced_model(
                y, x, term_slices, params, [key])
            df1 = df_resid1 - df_resid
            msm = (ssr1 - ssr) / df1

            if (key == ':'.join(factors[:-1]) or
                    (key + ':' + subject not in term_slices)):
                # Interaction effect ### Edit 04/10/2018
                mse = ssr / df_resid
                df2 = df_resid
                type_3_SS_error = ssr  # Edit 04/10/2018
            else:
                # Simple main effect
                ssr1, df_resid1 = _ssr_reduced_model(
                    y, x, term_slices, params,
                    [key + ':' + subject])
                df2 = df_resid1 - df_resid
                mse = (ssr1 - ssr) / df2
                type_3_SS_error = ssr1 - ssr  # Edit 04/10/2018

            F = msm / mse
            p = stats.f.sf(F, df1, df2)
            term = key.replace('C(', '').replace(', Sum)', '')
            anova_table.loc[term, 'F Value'] = F
            anova_table.loc[term, 'Num DF'] = df1
            anova_table.loc[term, 'Den DF'] = df2
            anova_table.loc[term, 'Pr > F'] = p
            # ---------------- Edit 04/10/2018 ----------------- #
            anova_table.loc[term, 'T3 SS'] = msm
            anova_table.loc[term, 'T3 SS (error)'] = type_3_SS_error

    # calculate effect sizes.
    ss_total = np.var(y) * (len(y) - 1)
    omega_squared = (msm - (df1 * mse)) / (ss_total + mse)  # omega squared
    eta_squared = msm / ss_total
    partial_eta_squared = msm / (msm + type_3_SS_error)

    anova_table.loc[term, 'eta^2'] = eta_squared
    anova_table.loc[term, 'par.eta^2'] = partial_eta_squared
    anova_table.loc[term, 'omega^2'] = omega_squared
    # ---------------- Edit 04/10/2018 ---------------- #

    return AnovaResults(anova_table.iloc[:, [4, 5, 1, 2, 0, 3, 6, 7, 8]])
 
これをセル上で実行すると、CustomAnovaRM()という関数が使えるようになる。
あとはAnovaRM()の代わりにCustomAnovaRM()を実行するだけ。
 
# モデルを作成する
data = df[['SubjectNumber', 'r_1_Score', 'r_2_Score', 'r_3_Score', 'r_4_Score']]

# データフレームを長い形式に変換する
data_melted = data.melt(id_vars=['SubjectNumber'], value_vars=['r_1_Score', 'r_2_Score', 'r_3_Score', 'r_4_Score'], var_name='Group', value_name='Score')

# Repeated Measures ANOVAを実行する
aovrm = CustomAnovaRM(data_melted, 'Score', 'SubjectNumber', within=['Group'])
res = aovrm.fit()
print(res.summary())
print(res.anova_table)
 
あとはAnovaRM()の代わりにCustomAnovaRM()を実行するだけ。
Before

After

計算方法自体の正確性はチェックしていないのでご注意ください。

non-humanoidアバター概観

人間、辞めたくないですか?

Twitter上には「猫になりたい」「にゃーん」等と発言している人々が多く存在します。

終わることのない競争社会に疲れた人々は、動物になりヒエラルキーの外側に立つことで、社会から逃避することを夢見るようになりました。

 

社会にすりつぶされ、来世も期待できず、今世で猫になることを選んだヒロイン

 

一方、非人型の身体能力への憧れという正のモチベーションが、人々を脱人間に駆り立てることもあります。ギリシャ神話の発明家ダイダロスは、空を飛ぶべく人工の翼を作りました。様々なファンタジーロールプレイングゲームにおいても、空や力への憧れから、人が鳥や虎やドラゴンの姿に変身する様は多く描かれています。

現実の例としては、動物のシステムや構造を解明して人工物に応用するバイオミメティクス分野や、人間の認知能力や作業能力を拡張する人間拡張分野において、動物の身体性やイメージを人間に取り込む/活用しようとする研究が行われています。

イカロスとダイダロス(Pyotr Ivanovich Sokolov, 1776)
迷宮から脱出しようとして息子だけ墜落した。

 

現代では、VR技術やロボット技術などを用いることで、現実の身体と異なる構造をした非人型身体を自分の身体のように操作することが可能になってきました。

 

学部二年の春、私は生のインターネットを求めて、VRchatの世界に降り立ちました。VRでは自らの肉体を自由に選択することができます。私はTRPGプレイヤーでもあり、亜人萌えを発症していたため、竜人っぽいアバターを作ろうと思い立ちました。blenderに100時間ほど費やして下のアバターを作成し、以降VRでの身体として使用しています。

筆者のアバター

 

現在、私は修士二年であり、身体の編集や非人型身体の操作をテーマに、楽しく研究を行っています。

VR空間内で壊れたロボットになり、自らの脳内を編集して身体改造を行うVRコンテンツ。脳内のつなぎ方により右手と左足の動作が入れ替わったりする。SIGGRAPH'23等。

本記事は、非人型アバターに関する議題や単語を整理するために書かれるものです。「非人型アバター/non-humanoid avatar」という研究テーマは、文脈が多く、また言葉の定義もはっきりしていなかったりしているため、研究者同士においても議論が行いにくいものになっています。論文にはBackgroundやRelated Worksが書かれている為に文脈や問題をフォーカス出来ますが、Slack上や口頭でのコミュニケーションにおいてはちょくちょく認識違いが発生してしまいます。本記事では、non-humanoidに対する複数の文脈を整理し、単語の定義を確認し、研究テーマを分類し、分野を概観することを試みます。

 

最初に注意点をお伝えします。この記事は私の研究室とは関係がない内容であり、あくまで個人的な意見や情報を提供するものです。また、記事中には自分でも検討中の項目が多く含まれるため、間違いが存在する可能性があります。出来るだけ情報源を貼るように努めますので、気になったトピックについては自分でも深掘ることをお勧めします。

 

 

 

non-humanoidの文脈

non-humanoidとは、大まかには人と外見や構造が異なる身体のことを指します。non-humanoid型身体は、主に「VR空間上の身体」「サイボーグ(人間-機械協調体)」「(完全な)機械身体」の3通りの組成で存在します。(もちろん自然界の動物や昆虫も非人型ですが、本記事では人工物のみを扱います。)また、研究分野としては「CG・アニメーション」「バーチャルリアリティ」「人間拡張」「(人が操作しない)ロボット」「テレイグジスタンス」などで研究されています。

 

主観分野マッピング

CG・アニメーション分野

この分野では、non-humanoidキャラクターをアニメーション表現に用いることをモチベーションに色々な研究がされています。

実写版美女と野獣のタンス

上の例のように、椅子やタンスなどの無機物をアニメーションさせたり、犬などの4足歩行動物をアニメーションさせる場面がよくあります。

 

KinEtre [Chen et al. 2012 UIST]の文章の初めに、以下のような一節があります。

Imagine you are asked to produce a 3D animation of a demonic armchair terrorizing an innocent desk lamp. You  may think about model rigging, skeleton deformation, and  keyframing.

Depending on your experience, you might imagine hours to days at the controls of Maya or Blender.

このように、non-humanoidのキャラクターを動かすことは、その特殊な構造のために大変な作業となります。この問題へのアプローチとして、非人型の3Dモデルへのリギング(ボーンを入れること)や、リグを上手く動かす様々なアプローチが研究されています。

キャラクターを上手く動作させるアプローチの中の一つに、操作者(通常は人間)の動作をnon-humanoidに合わせたものに変換することで、上手くアニメーションさせることを試みるものがあります。この変換の方法の一つに、関節と関節の動作を対応付けるマッピングと呼ばれるものがあり、下の章で説明します。

特にCG分野では、この人形劇的なアプローチのことをMotion Puppetryと呼ぶことが多いです(Creature Features[Seol et al. 2013 SCA]等)。日本では慶応大学の藤代先生が研究を行っていたようです。

 

バーチャルリアリティ分野

この分野では、non-humanoid身体をVR空間における代理の身体:アバターとして用いています。私のフォーカスしている分野の一つはここです。主に自己表現や特殊な体験のためにnon-humanoidアバターが使用されます。

VRゲームでは、自分がイカになって街を襲うゲームなどが存在します。

Tentacular on Oculus Quest 2 | Oculus

VRSNSでは様々な人が様々なアバターを装用しています。動物や無機物など、想像力と技術力の限り、どんな存在にでも成ることが出来ます。

 

写真中にはウサギやパフェといった骨格からhumanoidと異なるアバターや、人型のボーンを持っているが外見だけ人間ではない亜人やロボットっぽいアバターが見られます。この分野においては、humanoidとnon-humanoidの境目はかなり曖昧です。

 

VRにおけるnon-humanoidアバターの研究トピックとしては、アバターの装用による認知変容(プロテウス効果)や、non-humanoidボーンを持つアバターの操作方法などがあります。後者は人間拡張分野の方で説明します。

プロテウス効果とは、用いるアバターのイメージに紐づいて、人間の認知や知覚、行動が変容するといった現象を指します。有名な研究としては「陽気な褐色肌のアバターではよりボンゴを叩くようになる」「魅力的なアバターを使うとより社交的になる」といった効果を示したものがあります。non-humanoidアバターにおいては、「ドラゴンになることで高所への恐怖が減少する」「タコの外見を用いることで身体に柔らかさを感じる」などといった研究があります。また、論文中でプロテウス効果と明言されてはいませんが、「サンゴ礁や牛の体験をすることで環境意識が高まる」といった研究もあります。プロテウス効果は、人間を心理的にサポートする手段として使える可能性があり、様々に検討が始められています。

個人的には、プロテウス効果は難しい研究テーマだと思います。

例えば、VRchatでKawaiiアバターを着たときには社交的になる、というのはプロテウス効果と言えるでしょうか。外見に紐づくイメージではなく、装用者のアバターに対する態度やロールプレイへの積極的姿勢が影響を及ぼしている可能性があると考えられます。つまり、元から可愛かったり、あるいはKawaiiについてのイメージを持たない老人などは、効果が低い可能性があります。プロテウス効果は、個々人のアバターに対して持つイメージに依っているのに関わらず、そのイメージに個人差がある部分には余り着目されずに、悪い結果は統計上のエラーとしてのみ処理されている気がします。このような、議論なしにマイノリティを透明化して、結果を一般化する行為は批判すべきですね。

更には、プロテウス効果には本当に身体が必要なのかという疑問もあります。TRPGでは、社交性があるキャラクターを演じている人は社交的に振舞います。この効果は三次元の体が無くても、二次元の立ち絵すら無くても、役割さえ与えられていれば観察されます。当たり前ながら、行動は期待される役割に基づいて変化します。纏まらなくなってしまいましたが、指摘したいことは以下の3点です。

1.プロテウス効果には、人がそのアバターに対して抱くイメージが異なるために、文化差や個人差があると考えられるが、その部分があまり注目されていない。

2.プロテウス効果にはアバターの外見に応じて無意識的に発現するものと、アバターの外見で期待される役割に応じて意識的に発現するものがあると考えられるが、それらが分離されていない。

3.役割に応じて発現する方のプロテウス効果は、アバターの身体が必要ない可能性がある(アバターの身体が無い場合はプロテウス効果とは言わないけれど)

個人差、役割の有無、意識・無意識、時間経過、発現の機序などを整理して議論することが出来れば博論になる気もしますが、非人型の片手間でやることではないので自分は手を引きました。

テレイグジスタンス分野

テレイグジスタンス (telexistence:遠隔存在) とは、遠隔を意味するtelあるいはteleと、存在を意味するexistenceを合わせた造語で、人間が、自分自身が現存する場所とは異なった場所に実質的に存在し、その場所で自在に行動するという人間の存在拡張の概念であり、また、それを可能とするための技術体系です。

Tachi_Lab - テレイグジスタンス

テレイグジスタンス分野では、人間の運動や感覚の入出力を計測・提示し情報技術を用いてそれを遠隔地のロボットと繋ぐことにより、人間を偏在させます。(上のサイトでは情報空間での存在もテレイグジスタンスに含むと言っていますが、肌感に合わせ、この文中では遠隔ロボットの操作のみを指します。)

ここの人間とロボットの関係のような、主従がある制御をリーダーフォロワー制御と呼びます。昔はマスタースレーブと呼んでいましたがポリコレの波によって言い換えることになったと聞きます。

テレイグジスタンスシステム「TELESAR V」 上記サイトより

この分野においても、近年遠隔地で用いるアバターロボットとして、non-humanoidが検討され始めています。遠隔地の身体として非人型の身体を用いることで、その特殊な身体が持つ能力を活用した作業が行えるようになります。

個人的には人間拡張/human augmentation分野との重なりがあると思うのですが、下の論文中では一度もhuman augmentationという単語は出てきていませんでした.....

Piton: Investigating the Controllability of a Wearable  Telexistence Robot 

Iskandar et al. 2022, Sensors.

人間拡張分野

この分野は人間の色々な能力を工学的に拡張することを試みています。

"人間拡張工学の意味するところは何か、詳細は本書を通じて書き記したいと思うが、簡単に言えば人間がもともと持っている運動機能や感覚を拡張することで工学的にスーパーマンを作り出すことだ。"

「スーパーヒューマン誕生!人間はSFを超える」(稲見昌彦)

"様々な背景や価値観を持つ人々によるライフスタイルに応じた社会参画を実現するために、身体的能力、時間や距離といった制約を、身体的能力、認知能力及び知覚能力を技術的に強化することによって解決する。"

ムーンショット目標1
「2050年までに、人が身体、脳、空間、時間の制約から解放された社会を実現」

この分野では様々な面白い研究が行われていますが、その中の一つに、「自らと身体形状が異なる身体を操作する」というジャンルがあります。

KMD Embodied Media

Metalimb

この非人型身体は、機械だったり仮想身体だったり、人間の生得的な身体とくっついていたり離れていたりします。操作方法としては上で説明した関節動作のマッピングや、IK制御、AI制御等の機械学習的アプローチ、コマンド制御を複合することが多いです。二人羽織的に複数人の動作を融合させて一つの身体を操作する場合もあります。研究としては、操作方法の提案から実装、評価試験までを一通り行っているものが多く見られます。

個人的には、「現実の身体拡張デバイスのプロトタイプとしてバーチャルアバターを用いる」手法が好きです。

 

ロボット工学(人間が操作しないタイプの)

 

この分野については余り知らないのですが、一応non-humanoidに関連するので挙げておきます。

non-humanoid robotと検索すると、一般にはロボットアームとか謎の二頭身ロボットや動物型ロボットが出てきます。機械的-人間的という軸があって、non-humanoidかhumanoidかは相対的なもののようです。ロボットアームとかはnon-humanoidの代表、アシモとかペッパー君みたいなのはhumanoidの代表みたいですね。

The Social Perception of Humanoid and Non-Humanoid Robots: Effects of  Gendered and Machinelike Features | SpringerLink

The Social Perception of Humanoid and Non-Humanoid Robots: Effects of Gendered and Machinelike Features

この分野では、主にnon-humanoid robotとヒトとのインタラクションとか信頼性等が研究されているようです。当然ながら、シンプルな形状のnon-humanoidロボットは、humanoidロボットよりも作るのが簡単です。

A Non-Humanoid Robotic Object for Providing a Sense Of Security

Manorらは、非人型のロボットの利点として「シンプルで手に入れやすいこと」と「機械的な性格が明示的であり、人間の関係を置き換える他者ではなく、ツールとしてウェルビーイングを向上させることに利用できること」を挙げていました。この研究では、人の話を聞く様子のジェスチャーがsecurity(安心感)の構築に役立つという実験結果が得られていました。評価手法が面白いのでご一読ください。

接客無双(鳩胸つるん)

文脈まとめ

  • CG分野、バーチャルリアリティ分野、人間拡張分野、テレイグジスタンス分野、その他ロボット分野などでnon-humanoidが扱われている
    • 自分の身体として用いるのはバーチャルリアリティ分野、人間拡張分野、テレイグジスタンス分野
    • CG分野ではキャラクターとして用いる。自分の身体に合わせて動作させることがあるが、自分の身体の代理ではない
    • ロボット分野でもnon-humanoidがパートナーとか(人型である必要が無いor人型では不可能である)作業のために用いられる
    • 研究のみならず、工業やゲーム産業、更にはVRSNSなどの文脈もある
  • non-humanoidに関わる研究トピックは以下のようなものが存在
    • 操作方法、マッピング
    • 認知変容(プロテウス効果)
    • 新たな身体のデザイン
    • 信頼性
  • non-humanoidを用いることで、人間は新たな表現能力や作業能力、体験、認知能力を獲得できる

non-humanoidアバターの分類

non-humanoidアバターの主たる構成要素は、外見・構造・操作方法の3点です。

外見

上の図のように、同じボーン構造を持ちながらも、その外見が女の子型だったりロボットだったり、太っていたり痩せていたりします。外見は頂点とその間に貼られる面(メッシュ)で作られます。頂点がボーンに紐づいて動くことにより、メッシュが変形し、アバターが全体として動作します。

 

構造(structure)

ボーン(bone)、ボーン構造、骨格、リグ(rig)とかとも呼ばれます。たまにmorphologyという言葉がこれを指していることもあります。

IK向きのHumanoidボーン - Neos Wiki

一般的なhumanoidボーン Neos wikiより

これが通常のhumanoidアバターのボーン構造です。

Non-Humanoid Characters

https://cascadeur.com/help/rig/advanced_rigging/other_topics/non_humanoid_characters

完全にhumanoidからかけ離れたボーン構造を持つこともあります。このようなボーン構造を持っているアバターは、少なくともnon-humanoid avatarと言っていいでしょう。

VRchatやUnityでは、その骨格を基準に、通常のhumanoidの骨格をもつhumanoidアバターと特殊な骨格を持つgenericアバターが分けられています。しかしながら、この分類と一般に言われるhumanoid/non-humanoidアバターの分類は必ずしも一致しません。

 

操作方法

どのようなアバターでも、それを代理身体として用いるためには、操作者の動きをトラッキングしてアバターを動作させる必要があります。操作は一人称視点で行われることも3人称視点で行われることもあります。

通常のhumanoidアバターの場合は、人間の手足の位置や頭の位置とアバターのそれを1対1対応させれば済むので簡単です。

一方で、non-humanoidアバターの場合は、特殊な対応付けが必要になります。例えば天使の羽を、尻尾を、猫耳を持つアバターのそれらの部位はどのようにして動作させれば良いのでしょうか。ケンタウロスの後ろ足をどのように動かせば良いでしょうか。自分がドラゴンになったとしたら、翼や尻尾をどのように操作するべきでしょうか。

例えば、尻尾や猫耳や羽は前もって付けられたアニメーションに沿って動作させることができます。人間の動作をトリガーとして、あるいは人間の動作に合わせてアルゴリズム的に動作させることもできます。しかしながら、これらの自動的な操作には主体性がなく、面白さが半減します。

もっと主体性のある方法として、人間の関節動作などの運動自由度をアバターのそれに連続的に対応付ける、モーションマッピングという方法が存在します。

モーションマッピングのイメージ。

 

non-humanoidアバターの曖昧性

humanoidアバター、non-humanoidアバターとして合意を得られそうなもの

左側の、vroid製アバターはhumanoidアバターとして皆が認めると思われます。また、右側の猫(虎?)も皆にnon-humanoidアバターだと認められそうです。(正確には、右の猫はVRアバターとして用いられてはいない単なる3DCGキャラクターですが、分かりやすさの為に議論に含めています。以下も同様。)

 

しかしながら、以下のアバターたちは何方に含まれるでしょうか。

(左上)ろぽりこんちゃん

(中央上)ロボット

(右上)ストリートファイターVI

(左下)VRChat用の非人型(non-humanoid)アバターを人型リグでとりあえずなんとかした|450ch

(中央下)計数工学科

(右下)How do I Rig a Dinosaur In Blender? | Blender Tutorial | VFX_Blend - YouTube

CGソフト上でhumanoidとして扱われるか否という基準の他に、アバターの外見や、歪み具合もhumanoidアバターかnon-humanoidアバターかの判別に含まれてくると考えられます。

ろぽりこんちゃんは、通常のhumanoidリグに加え、耳や尻尾にもボーンが入っています。これはhumanoidアバターに含まれるでしょうか?少なくともUnityやVRchatでは、このようにhumanoidリグを基礎として持つアバターはhumanoidアバターとして扱われいます。VRでのアバター研究の大家Mel Slater先生はHuman Tails [Steptoe et al. 2013, IEEE]にて、このような「アバターが基本的に人間らしい形をしておりながら、さらに付属物を含む」アバターを、extended humanoidと名付けました。この態度に本記事も賛同します。

ロボットはどうでしょうか。このように、外見は非人間であるものの、humanoidボーンを持つアバターは、ソフトウェア上ではhumanoidアバターとして扱われますが、VRSNSでは人外/非人間として扱われることがあるほか、論文においてもnon-humanoidアバターとして扱う例があります。上の「ドラゴンになることで高所への恐怖が減少する」論文においても、ドラゴンアバターにはhumanoidリグが使われているように見えます(尻尾が生えている場合はextended-humanoidになります)。このように、動物や人工物を「擬人化」したアバターをhumanoidアバターに含むか、あるいは含まないかには議論の余地が残っています。擬人化されたアバターは、humanoidリグを持っているので、簡単に操作できます。

ドラゴンアバタを用いたプロテウス効果の生起による高所に対する恐怖の抑制

ここまで、大体humanoidリグが含まれていたら、humanoidアバター(もしくはextended-humanoidアバター)であるという態度を取ってきました。では、上のストリートファイターVIで作成できるキャラクターのような、ボーンの親子関係や構成/hierarchyは通常のhumanoidリグと同じで、しかしながら歪んだ身体を持つアバターはどうでしょうか。ここまで身体比が歪んでしまうと、通常のhumanoidアバターと同様なマッピングは難しくなり、アバターとして用いるためには特別なマッピングが必要になります。(実際にはこれはゲームキャラクターなので、他のhumanoidリグと同じアニメーションを流し込まれて動作すると思われます。)

また、右下の箱のようなアバターと中央下のみがわりミズゴロウは、Unity上でhumanoidと判定される構造を持っています。これらはhumanoidアバターに含めるべきでしょうか。結局、構造のみでhumanoid/non-humanoidを判断するのは不可能なのでしょうか。

仮にストリートファイターVIのキャラクター群をhumanoidと認めることにしましょう。その場合、右下のティラノサウルスはhumanoidになるのでしょうか。このティラノサウルスは、ボーンの親子関係自体は、hipから伸びる二本の足とspine、spineから伸びるchest、chestから伸びるneckと二つのshoulderと、実はhumanoidリグと殆ど同じボーンの親子関係、構成を持っているようです。上で歪んでいる分にはhumanoidだと認めたので、このティラノサウルスも尻尾が付いたextended-humanoidに含まれてしまいます。うーん、非直感的でよく分からない分類になってきました......

ここまでの議論を通じて、アバター群を外見、ボーン構成、ボーン構造の歪みの3軸くらいで分離できそうです。マッピングしてみましょう。

これらを基に、どこまでがhumanoidでどこからがextended-humanoid、non-humanoidかの(直感的に納得がいく)基準を考察しましょう。

まず、ボーンの構成・ヒエラルキーにhumanoid部が含まれない「猫」と「ロボットアーム」はnon-humanoidとして良さそうです。

次に、外見が人型を保っていない(四肢が無い/動かない)「ミズゴロウ」と「箱」もnon-humanoidとして良さそうですね。

残ったのは「ティラノ」「ストIV」「ろぽりこん」「ロボット」「人間」です。

ここからは程度問題のように思えます。つまり、文脈によりhumanoid/extended-humanoidとして扱うか、non-humanoidとして扱うかが左右されると考えられます。再度、主観的にhumanoidかnon-humanoidかをマッピングすると以下のようになります。また、extendedであるか否かは、humanoidとnon-humanoidの中間に位置させるよりも、humanoid部分を持っているアバターをhumanoidアバターとした上でそれのサブ属性として考える方が整理できると考えられます。

テクスチャの人間らしさを重視するか、身体比を重視するか、文脈によって「ストVI」と「ロボット」は逆転する可能性があります。ですが、大体納得のいく分類が出来ました。

(ここまでの議論では、髪や衣服のリグは一旦無視して考えていました。どこからが装飾でどこからが身体化をアバターに対して定義するのは難しい。)

 

分類まとめ

  • アバターはhumanoidアバターかnon-humanoidアバターかに分かれる。
  • humanoidアバターのサブ属性として、extendedであるか否かがある
    • (注:これは自論であり、extended-humanoidをnon-humanoid側に含む場合もある。特に人型-非人型の動作変換に着目する場合は。)
  • humanoidアバターかnon-humanoidアバターであるかを分ける基準には以下がある。
    • ボーンのヒエラルキー構成(≒CGソフト、3Dソフトでhumanoidと扱うか否か)
    • ボーンの通常humanoidからの歪み具合(身体比・回転・相対位置・配置など)
    • 外見(通常の人型っぽさ、人間らしさ)
  • humanoid/non-humanoidの別は文脈に依る
    • 誠実な姿勢を取るためには、例えばhumanoidリグで外見のみを動物にした「擬人化」アバターをnon-humanoidアバターとして扱いたい場合は、「非人型外見を持つ非人型アバター」のように補足すべきである

異なる構造間での動作マッピング

non-humanoidアバター及びextended-humanoidアバターのextended部分、あるいは非人型テレイグジスタンスアバターや第三の手のような人間拡張デバイスを自らの身体として主体性を持って操作するためには、操作者(おそらく人型)の一部あるいは全身の身体動作をnon-humanoidやextended等のそれに変換する、人型-非人型動作マッピングが必要になります。

マッピングはリマッピングとかマッチングとかリターゲティングとも呼ばれる場合もあります。

マッピング設計の困難性

マッピング設計の困難性は本質的に二つの要因に分かれます。

一つは、操作部位(人間側)と被操作部位(アバター側)の構造的な類似性が小さいことです。humanoidアバターは、動作入力の関節に対し同じ関節を対応付ければ良い(例えば、右手首の動作はアバターの右手首にマッピングすればいい)ため、マッピング設計自体は簡単です。しかしながら、non-humanoid身体に対しては、それは困難です。例えば、4足歩行の猫の右足に対して、人間の右手をマッピングしたとき、猫は猫らしい動作をするでしょうか。また、蛇アバターは身体をどのように再配置すればそれらしく動かせるでしょうか。

もう一つは、そもそもアバター身体を十全に動作させるだけの動作自由度を人間が持たないことです。天使の羽を動かすためにはどの身体部位をマッピングすれば良いでしょうか。腕をマッピングしてしまうと、腕が羽と独立して動かせなくなります。肩甲骨の上下動作をマッピングすると、楽しそうですが、結局日常動作を阻害します。

これらの問題を解決するために、先行研究では、様々な手法で操作の直感性を補助し、また運動自由度を補うことで、non-humanoid身体を動作させようとしています。

異なる構造間での様々なマッピング手法

異なる構造間でのマッピング手法は様々に存在します。本記事で注目しているのは操作者(人型)から非人型身体構造への人型-非人型動作マッピングですが、操作者の一部を用いて人型キャラクターの全身を動かす、操作者の右手で左手を動かすと言ったような、人型-別の人型動作マッピングも存在します。

また、アバターの腕を人間の腕を用いて動かすような、構造が類似していたり構造が異なっていても位置的に対応付いたりする部位間でのマッピング(cis-マッピング?)も存在すれば、人間の足を用いてアバターの腕を動かすような、動作自由度を分解して再構築するマッピング(trans-マッピング?)も存在します。

まず、最もよく使われる手法がジョイントマッチングです。これは、関節同士で対応を取り、操作者の各関節の回転や位置をアバターのそれに変換するものです。マッピングという言葉自体がこれを指していることもあります。対応付けは基本的には一対一で行われますが、行列の掛け算のように一対多で対応させることもあります。また、線形ではない操作を行うこともあります。

FIngerWalkでは、指のトラッキングデータを一旦6つほどのパラメータを持つ特徴ベクトルに落として、それを用いて適切にアニメーションを生成しています。これは、指運動とユーザーが望む全身運動の対応関係が運動の種類に大きく依存する(つまり、指で歩いている時と走っている時とで同じマッピングを用いられない)ためでした。

FingerWalking: motion editing with contact-based hand performance [Noah Lockwood and Karan Singh. 2012. EUROSCA'12: Proceedings of the 11th ACM SIGGRAPH ]

アニメーション情報に注目して動作の対応付けを行う手法もあります。Rhodinらは、人の手や顔、トラッキングスーツの点群データをターゲットの頂点変形と対応付けるアプローチを作成しました。この手法では、彼らはリギングを行っておらず、頂点を直接変形させています。他の研究では、人間の動作に合わせてボーンのアニメーションを再生・合成することも行われていました。

また、文脈は異なりますが、コマンド入力によって非人型身体や別の人型身体を操作する場合もあります(重機や格ゲーなど)。

6時間目 ~コマンドの基本~ | ストゼミ | 活動報告書 | CAPCOM:シャドルー格闘家研究所

6時間目 ~コマンドの基本~ | ストゼミ | 活動報告書 | CAPCOM:シャドルー格闘家研究所

脳波や筋電、力などの、非運動学的な値を入力に用いる場合もあります。

6th finger Projectより [Umezawa et al. 2022, Scientific Reports]

つもり制御 実はこの操縦桿は動かず、力を入力として行動意図を検出している。前田太郎先生の研究室。

また、複数人で一つの身体を動作させる場合もあります。

自在肢 [Yamamura et al. 2023, CHI]  リーダーフォロワー制御で動作しており、リーダー側は別の人が動かしている。

また、少し方向性は異なりますが、前述した「擬人化」のアプローチもnon-humanoid外見を活用するために使われています。すなわち、4足歩行の猫に対してマッピングを設計する代わりに、猫を人間らしくすることにより簡単な操作を獲得します。

現場猫 - Tomcat's Toy Box - BOOTH

現場猫 - Tomcat's Toy Box - BOOTH

 

 

マッピング設計まとめ

  • マッピング設計の課題は、構造的類似性の不足と自由度の不足

  • それらを解決するために、以下のようなアプローチが存在
    • ジョイントマッチング
    • アニメーション入力
    • コマンド入力
    • 筋電や脳波入力
    • 融合身体
    • 擬人化

 

実験・評価系

non-humanoid(or extended-humanoid)アバター/キャラクター/ロボット/身体は様々な観点から評価されています。

アバターに関わる評価系としては、以下のようなものがあります。

  •  装用体験の主観的評価のアンケートによる調査
    • 身体化の程度
    • プロテウス効果
    • ユーザー受容性
  • タスクパフォーマンス、運動性能の測定
  • 装用中の行動変化の測定(プロテウス効果)
  • 装用後の身体認知の変化の量的な調査
    • 手指の位置感覚の変化
  • Skin Conductanceの変化の測定による身体化度合の測定
  • 装用体験のインタビュー調査

アバターの身体的特性をあたかも自身の身体的特性であるかのように操作・知覚したときに感じる感覚を身体化 (Embodiment) といい、それの程度が7段階のリッカート尺度を用いたアンケートによって評価されることが多いです。他にも、プロテウス効果による主観的認知の変化や、アバターのユーザー受容性・選好などもアンケートにより調査されます。身体化や存在感の程度は、アバターに脅威提示したときの皮膚抵抗の変化を見る手法によっても調査されます。

Virtual Embodiment Questionnaire

アバターの操作性は、幾つかの運動タスクにより評価されます。非人型身体の特性を活用したタスクが設計されます。

アバターの外見のイメージに基づく行動変容も、何らかのタスクを通じて評価され、プロテウス効果の有無が調べられます。

アバターの体長や長さが人間のそれと異なる場合、アバターの装用後に身体の位置感覚が変容している可能性があるので、それが調査されることもあります。古くはRubber Hand Illusionという、ゴム手を身体化するタスクにおいて、手の位置感覚の変化(ドリフト)量が評価されていました。

また、脅威提示時の皮膚抵抗の変化を測定することにより、身体化の一要素である自己所有感を測ることがあります。所有感が高いほど、例えば腕にギロチンが落ちてきたときに、皮膚に汗を多くかくようになります。

装用体験全体をインタビューし、それから設計要素を得ようとする研究も存在します。

non-humanoidCGキャラクターについては、マッピング設計アルゴリズムを提案し、それで作ったアニメーションの自然さやアニメーションを作る手間などが測定されています。

non-humanoidロボットについては、人とのコミュニケーション能力や信頼性を測る研究が多いようです。

人体拡張デバイスについては、設計から評価までを全部行う研究が行われています(あやふや)。

non-humanoidの価値・不全

non-humanoid身体やアバターを用いることには、これまでの通り、新しい身体を用いた表現能力・作業能力・体験を操作者に提供します。

VR空間内で存在したい自分になる、義肢や義体などに新たな可能性を与える、動物や非生物を理解しそれらの能力を活用することなどによって、我々は我々はより豊かで自由な人生を送ることができるようになるでしょう。

しかしながら、人型にはない不都合も起こりえます。

操作の難しさに加えて、対人コミュニケーションについても不全がおこることが想像されます。例えば、目が存在しないアバターを用いた時には、目を持ちいたコミュニケーション、例えば話す順番を察し合うことなどが不可能になります。

このアバターを使った時には、前後が分からないと言われました。

ぷにるはかわいいスライム 40話

また、人間と規格が共有しにくくなることにより、汎用性が低下することも考えられます。

非人型アバターには人型の可能性を超えた表現・作業・インタラクション能力を人に与える可能性があるが、決してone-fits-allなアバターにはなり得なさそうです。

Ishiguro Lab. - テレノイド

関連する話題として、ロボットのコミュニケーションや信頼性について、阪大学の石黒研究室等で研究されています。人らしさには胴体や顔が必要である、その有無によって人がロボットに対してポジティブにかかわり続けるか否かが影響されるなどの結果が示されています。逆に言えば、これらの成果は非人型ロボットのコミュニケーション上での不利を表しています。非人型ロボットにコミュニケーション上の安心感を与えようとするという研究テーマは非人型ロボット界隈で盛んであるようです。

 

 

 

むすび

元々、我々の魂は、不当にも肉体という牢獄に囚われています。生まれつき与えられたものに満足し、それ以上のものを求めようとしないのは馬鹿馬鹿しくはないでしょうか?今こそ、自らの可能性を追求し、環境のみならず自らの在り方も変容させ、我々人類が新たな存在へと進化するべき時なのです。