株式会社デジタル・フロンティア-Digital Frontier

Header

Main

  • TOP
  • DF TALK
  • crowdツールノウハウ ~Massiveでbrain、略してMassiverain~

crowdツールノウハウ ~Massiveでbrain、略してMassiverain~

2015/11/30

Tag: ,,

[あいさつ]

お久しぶりです。
最近はめっきりcrowdというよりもTD色が強まっている
crowdTDの 護守(ごのかみ) です。

11月ですね。
ということは今年も残すところわずかということですね。あ…
 
 

さて、今回はTD色が強まっている自分をちょっとcrowd色にゆり戻して、
さらには初心を振り返るということでちょっと前の記事を掘り起こし・掘り下げてみたいと思います。
題して、

『Massiveでbrain、略してMassiverain』

けっこうニッチな内容なんで、需要はあるのか怪しいですが、
私の記事は大抵ニッチですからね仕方ないですね。
 

前回の記事:
crowdツール共通のブレインの考え方 ~デザイナーでもわかる群集入門~

 
 

[導入]

日本でMassiveのノウハウ記事ってかなり珍しいんじゃないでしょうか?
もしかして、これが最初で最後かもしれませんね。
 
 
今回は車のbrainを作っていきます。

「車の…ブレイン…?」

って感じですが、要は道路をプロシ-ジャルで走る車を作ります。
この記事では基本的な考え方の部分だけを紹介します。

ひとつひとつのコネクションを見ていってもいいんですが、
ものすっごい長編になってしまうので、細かいつなぎ方とかは省きます。

ちなみにこれは、私がMassiveのbrainの勉強をしているときに作ったものなので
記憶が曖昧な部分もありますが、ご容赦を。
 
 
とりあえず先に結果だけ見せておきましょう。

 
 
 
 

1. 条件の確認

さて、まずはこの記事
crowdツール共通のブレインの考え方 ~デザイナーでもわかる群集入門~
でも書いたように条件を明らかにしていきます。
 

今回は題材が「道路を走る車」とちょっと曖昧ですので、
噛み砕いていく必要がありますね。

「道路を走る車」に最低限必要なルールを列挙していきます。

A. 道路をはみ出さない(道路に沿って走る)
B. レーンによって進行方向は統一
C. 他の車に衝突しない
D. 地面の傾斜に沿う

最低限としてはこんなところでしょうか。
実はこれでもまだ曖昧なところがあるので、これらを更に細分化していきます。
 
 
A. 道路をはみ出さない(道路に沿って走る)
・レーンの右側寄りになったら左側に修正(逆も然り)
・レーンをはみ出してしまった場合レーンに復帰

 
B. レーンによって進行方向は統一
・レーンの方向を取り、その方向に走る
・逆向きだった場合方向転換する

 
C. 他の車に衝突しない
・前方の近い位置に車があった場合回避
・前方の近い位置に車があった場合減速
・上記二つでも衝突しそうな場合は停止

 
D. 地面の傾斜に沿う
・地面の傾きを検知して車を傾かせる

 
 
 
B, Dは比較的簡単に実現できます。
この二つは、やり方がもはやテンプレートみたいなものなので、それに合わせてやればOKです。
レーンの向きや地面の傾きはMassive内で
チャンネル(MayaでいうAttrのようなもの)を使うことで簡単に取得できます。

何気に難しいのがA, Cです。
個人的にはAのはみ出してしまった場合の対処が一番手こずりました。
 
 
 
 

2. 制御構造の構築

さて次は実際に作っていくにあたっての制御構造を考えていく必要があります。
crowdツール共通のブレインの考え方 ~デザイナーでもわかる群集入門~
この記事での例は簡単な内容だったのでここをすっ飛ばしていますが、
今回は色々と複雑なのでここをしっかりと組みます。
 
 
まずは「制御構造とはなんぞや?」ってことなんですけど、
Agent自身を動かすための直接的な情報を統合する構造のことです。
以下具体例入れて説明しますが、文章がちょっと硬いので読み飛ばしてもらってもかまいません。
 

Agent自身が持っている情報はTranslate, Rotate, Scaleといったものがあります。
今回はroot以外に骨は考えていませんので、
この九つの情報(各三軸あるので3×3)をどのように出力していくかが重要となります。
1.で考えたルールに沿わせるためにTranslate, Rotate, Scaleに値を実際に出力していきます。
たとえば、車がレーンの右寄りの位置を走っていた場合、ルールAが適用されます。
ルールAを解決するため、必然的に車を今よりも左側に寄せないといけません。
つまり、出力としてはRotateYに左向き、つまりマイナスの値を入れることになります。
ところが、単純にRotateYにマイナスを入れるだけだと、左側の車にぶつかってしまいます。
というわけで、ルールCが適用されRotateYに反対の値プラスが入ります。
ここで、単純に上書きしてしまうとルールCを守るためにルールAが破られるというジレンマが発生します。
これを回避するために、これらを統合し同時に扱うためのものが制御構造というわけです。

 

わかりやすくいうと各ルールから来る情報を足し算なり掛け算なりして最終的な結果を出す構造ってことですね。
今回はScaleを考える必要がないので、実質TranslateとRotateだけを制御すれば問題ありません。
もっというと、車の構造上TranslateもZ軸だけ考えればいいですし、
Rotateも地面の傾き用のX軸とZ軸を除けば、Y軸だけを考えればいいんですね。
 
余談ですが、車の制御は「アクセルとハンドルという二つの少ないインプットで制御できるもの」
としてよく引き合いに出されます。
そのアクセルとハンドルがそれぞれTranslateZとRotateYに相当するということですね。
 
 
 
 
さて以上を踏まえて、それぞれのルールにおける制御で必要なものを割り出します。

A. RotateY
B. RotateY
C. TranslateZ, RotateY
D. RotateX, RotateZ

これを扱いやすい処理にしていきます。
RotateYにはHighとLowのプライオリティをつけて、
RotateYを合成するだけでなく各ルールの優先も決められるように準備しておきます。
TranslateZも同様にHighとLowのプライオリティなどを用意しておいて柔軟に対応できるようにしておきます。
制御構造は、後でモジュールを組み立てていく際に、必要になる値があったりして付け足したりすることがあるので、
とりあえずの構造だけ組み立てておけばOKです。


(クリックで拡大)
 
 
 
 

3. モジュールの組み立て

これで必要な情報がそろいました。
まずは1.の基本ルールから2.の制御構造へ渡す大まかな流れを組みます。

(クリックで拡大)
こんな感じになりました。
左側にあるのが基本ルール(1.)モジュールで、
右側にあるのが制御構造(2.)モジュールですね。
真ん中にあるSpeedというのは移動速度調整用のモジュールです。
このSpeedモジュールは単に遅い速いを調節するだけでなく
加速度や慣性っぽい動きをするための仕組みも組み込まれています。
 
 

Laneモジュール

このモジュールはルールA, B用になります。
レーンに関する情報を取得するものはここにまとめました。

(クリックで拡大)
一番下のノード群はレーンから外れたとき用の処理です。
レーンから外れてしまうと自分がレーンのどちら側にいるのかを判別できなくなってしまうので
レーンに復帰するというのが難しいんですよね。
これは、直前までの位置を取得して覚えさせることで解決しました。
 
 

Vehicular gapモジュール

いわゆる車間距離です。

(クリックで拡大)
ここでのポイントは目の前の車の求め方。
MassiveではvisionといってそのAgentから見た情報より
視界に何かあるかを判断する機能があります。
しかし、この機能は処理がかなり重くなってしまうため通常では使いません。
では、何を代わりに使うかというとsoundを使います。
Agentはそれぞれ音を発することができます。
音といっても実際に音を鳴らしているわけではなく、
自分の周囲にある情報を拡散することで自分の位置などの情報を他に報せているんですね。
それを総じてsoundとMassiveでは呼んでいます。
このsoundを利用して、自分の前方にいるものをとってきます。

ただ、ここで注意しないといけないのが、
前方といっても隣のレーンにいる車は取得しないようにすることです。
もし、とってしまうと対向車線に車が来たらその都度変な動きをしてしまうのです。
soundは聞こえてくる方向も取得できますので、その情報を利用します。
 
 

Speedモジュール

先程も述べましたが、スピード調整用のモジュールです。
加速度や慣性っぽい動きをするための仕組みをいれて、車っぽい動きになるようにしています。

(クリックで拡大)
 
 

付加要素

とりあえず上記の状態で実行するとこんな感じになります。

あとはちょこちょこと要素を足していきます。

・複数車線
・レーンの分岐・変更
・信号の解釈
・障害物を避ける
・交差点での減速
・カーブでの減速
・傾斜での減速・加速
・車線による車の優先度

これでもまだ足りないと思いますが、車を走らせるだけでもけっこうルールがあるのがわかると思います。
更には、それらをひとつひとつ実現するにも地味に工夫が要ります。
 

【複数車線】

デフォルトだと、レーンの真ん中しか走りませんので、
これをレーンの右側と左側を走れるようにします。
今、自分がレーンの左右どちら側にいるかを取ることができますので、
その情報を利用し、右寄りを真ん中、左寄りを真ん中と認識させることで2レーンを実現できます。
2レーン以上も同様の考え方でできます。
二車線の場合は、レーンを引くときに2レーン分引くとか工夫もできるんですが、
二つもレーン引くの面倒ですし、変更にも手間がかかるのでbrainで実現しました。
 

【レーンの分岐・変更】

単純に分岐するだけだと、分岐時にどのレーンを優先したらいいのかわからなくなります。
右にいくときは右に曲がるレーンを優先すればいんですが、どれが右のレーンかはAgentからはとりにくくなります。
なので、ここはルールとして、右は赤色のレーン左は青色のレーンと決めてしまいます。
ただ、これだけだと十字路の際に直進するAgentがうまく取得できないので
分岐地点のまっすぐな部分にも黄色の色をつけます。
それ以外の一本道にはさっきの三色以外の色をつけておきます。
このレーンの色で交差点を判断できるようになりますので、
減速も容易にできます。

Agentは現在の自分が上にいるレーンの色まで取得できますので、
これでうまいことレーンを変更することができます。
 

【信号の解釈】

これは、先程使ったsoundをここでも使用します。
ここでは信号の色の情報を音に置き換え発しています。
また、信号の向きも取得し判断するようにしています。
これは交差点で本来自分の車線にない信号の情報まで取ってしまうのを防ぐためです。

ちなみにこれを導入しても信号のAgentがないと意味がありませんので、別途作成します。
 

【障害物を避ける】

これも信号と同じような解釈で作成することができます。
ただ、信号のように向きとかまで考慮する必要がないので簡単にできます。
 

【カーブ・傾斜での減速】
これは単純です。
曲がるときにスピードを落とすように設定すればいいんですね。
傾斜も同じように、上るときは減速、下るときは加速にすればいいです。
 

【車線による車の優先度】

これは交差点での事故を防ぐ効果があります。
ここでのポイントはどの車が直進で左折や右折をしているのかを取得するところにあります。
自分から見て他の車がどのように進むかというのは非常に取りづらいです。
なので、ここでは逆転の発想で、自分が曲がるときにウィンカー、また直進の際にも直進のサインを出すようにします。

あとは他の車のウィンカーサインを取得して道を譲るようにしてあげれば完了です。
 
 
 
最終的にはこんな感じのノードコネクションになりました。

(クリックで拡大)
 
 
 
 

[おわりに]

こんな感じでMassiveのbrainを組んでいきます。
brainは一度組み方さえ理解してしまえば流用が効きますので積み重ねしやすいですよね。

これを組んでみて思ったのは
意外と信号機のアルゴリズムがめんどくさいってことですかね。
一瞬全部赤になるときがあったり、タイミングを調節しやすくしたりするのが意外と面倒です。

それから、レーンの組み方もしっかりとしてあげないと、
このbrainでもうまく制御できないんですよね。
右折左折レーンの作り方にもコツがあるのでこのコツを守らないと
うまく交差点の対応ができなかったりします。
裏を返せば、まだこのbrainでは柔軟に対応できてないところが多いということなんですよね。
 
 
突き詰めれば突き詰めるほど物事にはルールというものが存在しているというのがわかります。
また、そのルールを再現するためには、brainを作れるように見方を変える必要もあるというのがよくわかります。

とはいえ、私らがやっているのは結局のところエンターテイメントなんで
見栄えがよければOKなところもあります。
ということで、あんまり深く考え過ぎないのも大事ですね。
ちなみに今回のbrainもいい感じになるようなマジックナンバーを使用してたりするのでご愛嬌です。

 
 
 
 

それではまたどこかで(:3ノシ )ヘ
 
 
 
 

Pocket

コメント

コメントはありません

コメントフォーム

コメントは承認制ですので、即時に反映されません。ご了承ください。

*