2019年3月31日日曜日

robot_localization全然わからん。

robot_localizationを使って、roombaのwheel odometryと、realsense T265(VSLAMカメラ)によるVisual odometryを統合しようとしたら見事にハマったのでメモ。

http://docs.ros.org/melodic/api/robot_localization/html/index.html


T265のカメラがはき出すodometry座標系を利用して、その上にmapを置く構成の絶対座標を使っています。T265はroombaの端っこに載っているので、camera_pose_frameの下にbase_linkがずれた位置に存在しているというstatic TFを書いています。

後述のにように、このズレがたぶん色々な元凶な気ももします。
ということでTFとか楽勝なツヨツヨな方にチェックしていただければなぁ~。

暗黙のbase_link(本命)

Odometryのchild_frame情報をここで捨てている。
すなわち、Odometryのchild_framが暗黙のうちにbase_linkであることを仮定しているが、
VSLAMカメラは機体の端っこについているのでその分ずれる。
一応、座標変換ノードを入れれば対処可能?
https://github.com/cra-ros-pkg/robot_localization/blob/melodic-devel/src/ros_filter.cpp#L1690-L1701


差分とったら、元がなんであれframe_idはbase_linkだよね??(ついで)

differentialモードの時の話。
https://github.com/cra-ros-pkg/robot_localization/blob/melodic-devel/src/ros_filter.cpp#L2763

child_fram==base_linkだとして話すると、前回のodometoryPoseからの差分( poseTmp.setData(prevMeasurement.inverseTimes(poseTmp)) )の
frame_idはbase_linkだよね。そして、「twistPtr->header.frame_id = baseLinkFrameId_;」という風にたしかにbase_linkを設定している。
しかし、なぜか追加の回転「poseTmp.mult(targetFrameTrans, poseTmp)」をかけている
このへんが謎。

2019年2月21日木曜日

続ROS#と戦ってみた

とりあえずの戦況報告。
前回、BSON化してLaserScanを送るという所までできました。
その後、細々とした修正をに加え、PointCloudを扱うコードを追加したりしてました。

とりあえずの移動ロボット可視化には十分つかえそうな感じです。
もし要望があるようならば、そのうち解説をかこうかなと思っています。

2019年1月26日土曜日

ROS#と戦ってみた

期待から始まるが・・・

UnityからROSを使いたくて、ROS#に手を出してみた。独シーメンス社のオープンソースということで、勤め先内部的にインパクトがあるっていう下心はもちろんあるんだけど。
ARCore/Hololens上のUnityからロボットにアクセスしたかったので、UWPとかにも対応させたかった。ROS.NETのほうがTFも使えて多機能なんだけど、その辺の移植が死にそうなので諦めて、同様にROSSharpも諦めた。(うろ覚えだけどXML周り)
TFが使えないので同期がとれてるフレームを切りだすとかできないけど、ROS側でTFを解決してPoseStampで投げつけるかぁ。という感じで割り切りました。

ROS#のしくみ

ROS#がUWPに移植出来たりするのは中身が単純だからなのです。ROSデータの中身は単純なTCPで垂れ流し状態なのですが、それが何処にあるのか?を問い合わせるのにROS_MASTER(roscore)にお伺いを立てる必要があります。その時に使うXML-RPCのライブラリが.NETFrameworkにゴリゴリに依存してるとUWP(.NET Core)に移植しづらいという事になります。ここでrosbridge_serverの登場です。rosbridge_serverは全ての通信のwebsocketで受けとめてくれる。proxyサーバです。通信すべき相手の場所がどこか?という事は気にする必要はありません。また通信内容はJSON(オプションでBSON)なのでUWPだろうがUnityだろうが実績がある方法が転がっています。

デメリットもあって、JSONなのでデータがデカくなる上に、折角分散通信できるようなROSの設計ですが、rosbridgeというproxyに一旦データが集中して集まる事になります。平たくいって余り通信速度を求めてはいけません。

第一の壁NTP on Android in 化石社内ネットワーク

ロボットは複数のセンサの結果の整合性を保つため、センサ値や座標情報にはミリ秒精度のタイムスタンプが打たれます。この時間を同期するシステムは実はROSにはなくOSの時間をNTP等でミリ秒単位で合わせろという無茶振りをしてくるのがROSなのです。(ROS2はどうだか知らない)
さて、化石のような頭の硬い会社でROSを使いましょう。社内ネットワークにNTPは立っているが何故か平気で秒単位でNTP時刻からずれています。社外のNTPは使えません。ここまでは問題はないです。そこにAndroid端末がやってきます、Andoroidは社内の怪しいNTPサーバで時刻合わせなんてしてくれません。つまり、タイムスタンプが合わないのです。古すぎるor未来の時刻のデータは捨てられてしまい、通信不能に陥ってしまいます。
 そこでOSの時間を合わせるのを諦めて、アプリケーション(Unity)内でNTPをつかってUNIX時間を作ります。なお、NTPサーバはpythonのサンプルがあったので流用しました。(myntp.py
メッセセージヘッダにセットするのはROS#がよく考えられていて、StandardHeaderExtensions.cs にExtensionとして時刻をセットする関数を作るだけです。なお、NTPに時刻同期はNtpTime.csのように10秒に一回程度の頻度で時差を取り寄せています。

第二の壁 座標合わせ

壁というよりは、どうしようもなく出てくる仕様なのですが、何らかの方法で座標を合わせる必要があります。その座標計算に使うTransform行列がUnityがMatrix*Vectorな順番なのに対して、ROSのTF2ライブラリでつかえるPyKDLがVector*Matrixな順番で頭が混乱するといった程度なのですが、その辺の行列を生で触るのは初めてだったので半日潰してます。

第三の壁 マイペースなgazebo

実機を持ち出すとぬくぬくしたパソコンの前じゃなくて、クソ寒い工場に追い出されます。なのでギリギリめんえgazeboシミュレータでの物理シミュレーションを使った開発をします。当面gazeboで物理シミュレーション、ROSでロボット制御、Unityで可視化という流れです。折角NTPに対応したので、use_sim_timeパラメータをfalseにして、リアルタイムのシミュレーション結果にROSの時間をあてがうようにします。普通に動いたので安心してLIDAR(LaserScan)の可視化をしようとすると、データが見当たりません。gazeboからの位置情報などは正しい時間をさしているものの、センサだけはシミュレーション時間をさしています。設定で逃げれるものではなく、ソースをかきかえなければいけない状況だったので、こんな感じにセンサーの時刻を現在時刻に書き換えるROSノードをでっちあげました。

第四の壁 JSON、NaN食べない。

これでようやく、LIDAR可視化できるぞ!とおもったらUnity 上ではウンともスンとも言いません。Subscribeしてるのに、一つもメッセージがきません。と思ったらWebsocketを流れるJSON に観測値に混ざって「null」という見慣れない文字。JSONの数値はNaN,Infが扱えないので、rosbridge側で勝手にnull値をいれていました。このnull問題、LIDARの性質上10cm以下や10m以上は欠測なのでInfやNaNが結構入ります。ros-sharpのissues読んでるとこれもproxyノードで適当な値をいれて逃げてますが、LIDARはともかく他のセンサまで考えると、欠測は欠測だろ。数字を入れるのは美しくない・・・。という気もします。そこで馬鹿正直な方法としては「float」型を「float?」型にするという手があります。するとJSON.NETではnullable(null値を取る事ができる)floatとして処理されます(ただし処理オーバーヘッドがある)。確かにこれで解決はできるのですが、ソースコード中のfloatを片っ端からfloat?に書き換えて、nullチェックを全てに足すのは流石に面倒。
ということで、rosbridgeの実装を眺めてるとBSONという文字をソースコードに発見。rosbridgeにbson_only_modeという機能があるのに気が付いたのでした。BSONの場合数値をdouble型にするので、NaNもInfも表現できます。ただ、rosbridgeがBSONの時も無駄にnull置換をしていたので、BSONモードの時にかぎってnull置換をしないようにしました。ROS#側はJSON.NETがそもそもBSON使えるというのがあって、Serialize/Deserialize部分をちょっと書き換えるだけでした。

 第五の壁 まともにテストされてない・・・

これで晴れてLIDARが表示されました!でもなんかへん?LIDARの表示は球体・線・エリア塗りつぶしの3種類あるんだけど、球体だけがまともで残り二つは明後日の向きになる。と思ったら、残り二つはUnityのtransformの使い方、つまりlocalPositionとPositionの使い分けがきちんとできてない感じでした。そして二つの間違え方が違うので、不慣れなメンバーが混じってたのでしょう・・・。映ったからOK!でいろんな角度でのテストまではしなかったのかな?

 まとめ

 色々はまり所はありましたが、ROS-sharpは単機能な分トラブルシュートは簡単なのかなという感じです。ちゃんとARCore実機でカクつくこともなく動いたし。Buggyなのを除けば十分選択肢にはいるのかなという感じです。今回作ったのをプルリクするのか細々とforkしていくのかどっちが良いかは悩み所です。(BSONはオプションで切り替えとかじゃないとだめなかなぁ?)ご意見があれば嬉しいです。



2018年11月18日日曜日

IVRC2018決勝体験レポート

IVRC2018の決勝大会も無事全作品体験できました。なので、体験レポートを。
なお、動画はIVRC公式YouTubeのものです。

なんでもじゃらし

一人暮らしの部屋で、猫じゃらしでを使って家具をじゃらす体験。特にイスの動きが変態はいってる位にうごきまくる。また、他の家具をじゃらすと今までじゃらされていた家具が嫉妬の雨をふらせる等のマンガ的表現が印象的だった。手元のデバイスは自由には回転できる偏心錘がついており、しなる感じを呈示できていた。ただし、猫じゃらしというよりも、もう少し重たい感じのもの。

打上げ花火、下から見るか?指から打つか?

ガスバーナーで肘にある導火線に火をつけると、ブルブルふるえる何かが腕の中を通り、指先から花火として飛んでいく作品。リストバンドで圧迫しつつ、振動を加える。さらに複数のリストバンドをつけて順に振動位置を切り替えることで、皮膚下でなにかが震えて動いているように感じる(ファントムセンセーションにより、物体が連続的に移動していってるように感じる)。 映像と組み合わせて見ると自然に移動しているように感じるのがキーポイント。なお、バンドなどで圧迫した上で振動をあたえると体内の振動だと勘違いするのはIVRCではもはや伝統芸になりつつある。

ARCO Avoid the Risks of CO

火災現場で一酸化炭素を吸わないように、煙のある場所では息をとめて駆け抜けるゲーム。簡易CO2センサを口元において呼吸数を計測している。煙の多い所では一酸化炭素(CO)を吸ってダメージを受けるというシナリオになっている。VR歩行のためのデバイスを畳とシリコンワックスで実現している。歩行の方向、歩数は歩行デバイス内にしこまれた16個の磁気センサーとスリッパに貼られた磁石で検出している(方向別歩数カウント方式)。VR関係者にはこの歩行デバイスのデキの良さが高く評価されていた。また、面白い着眼点としてCO中毒の際にはめまいがする事と、VR酔いのめまいの類似点を利用して、COが多い場合にはわざと画面を揺動させVR酔いを発生させている。ほかにも視野がせまくなっていく、歩く速度が落ちるといった症状も再現していた。

Suspense Creeping Bomb

ほふく前進でダクトの中をくぐりぬけ、爆弾を解体する作品。 ほふく前進は床のベルトを回して行うのだが、手袋の手首部分をつかって、かつ体重をかけないとちゃんと動けないという、匍匐前進を正しくしないと前に進めないシステム。また、移動中の傾斜にあわせて、台座の確度も変わる。爆弾解体失敗時には、パワフルな傾斜システムをいかして、土台を揺らし、スモークを焚く(HMDをしているので体験終了後のスモークにびっくりするというしかけ)。大きなシステムを比較的安定に動かしていたが、ダクト途中での分岐選択が矢印に選択になっている点が唯一残念だった。

L'Allumeur de Reveberes

星の王子様の点灯夫の話にインスパイアされた作品。空中にうかんだ島々の街灯に灯りを灯す点灯夫が落ちてしまわないように手前のブロックで助けてあげる作品。ブロックはプロジェクタの所に設置された、深度情報つきカメラ(RealSense)でその位置を取得している。実際にはブロックが作った影を点灯夫が歩く事になる。彼らはこの光と影の関係に着目しており、例えば人間がプロジェクタの光を遮って街灯を覆ってしまうと、せっかく点灯した街灯が消えてしまう。フランスちーむらしい、美しい描画の作品。

ピノーズ

鼻を引っ張り、CGでも鼻を伸ばす事で、鼻がのびた感じを出す作品。予選の時にくらべ安定稼働するようになっていた。鼻でリンゴをつつくとコツンと鼻の根元に振動が来るのだが、人によってはうまくフィットしておらず何も感じ無い人もいた。また猫が鼻にじゃれついてくるシーンでは鼻が左右に揺さぶられる。たしかに猫のいるあたりで力を加えたんだろうなという感じはでているが、肌触りを感じ無いぐらい柔らかいもので動かされた感があった。ほかにも鼻の位置にあわせて匂いをかぐ機能など自然な体験ができるようになっていたのが印象的だった。なお、嘘をつくと鼻が温かくなるという研究に応じて、鼻部分に

天獄渡り

セグウェイでビルの間に渡された空中の通路を渡っていく作品。予選にあった膝が震える機能にくわえ、振動スピーカー(Vp4)で偽の心拍(ドキドキ)を呈示して恐怖感をさらに出していた。また、以前は漠然とビルの間を走っている間があったが、今回は燃えさかり、倒壊しつつあるビル群からの脱出というシナリオに加え、それに相応しいCG描写が追加され、より没入しやすくなっていた。

鼻腕

アゴで像の鼻を操作する作品。以外に普通に操作できるようになってしまう。という事に加え、操作形態がアゴを上にあげると、鼻が遠くにいき、アゴを下にさげると(つまり口をあけると)鼻が口元まで近づく操作によって、リンゴをつかんで食べる事ができるようになっていたのが面白い設計だった。なお鼻による物体の吸引は呼吸によって行うが、呼吸はマイクに乗る呼吸ノイズから判定している。またアゴを左右にうごかして鼻を動かす事ができ、左右にうごかした際には鼻の根元が振動子「グギギっ」感をだしている(が、私はHMDのあたりが悪く僅かにしか感じ無かった、別の友人には凄いグギギ感があったらしい)。

ブレインツリー

頭にのせた植物から根っこが生える感覚を体験できる作品。まず鏡で頭に謎の植物が居るのを確認させてから、液晶モニタにある模式図を対応付けて見せるといった体験上の工夫がされていたりと、相当にデモンストレーションの練習をしたんだろうな。と感じさせた。水をかけると、ひんやりする。自分の体液が吸われるときは植木鉢もあったかくなるといった細かい演出もあるが、メインは頭に根っこがはえる感覚である。頭皮マッサージの器具に振動子が取り付けられている。頭に根っこが絡みついてくるゾワゾワ感がするのは予選とかわらないが、今回は風がふいた時に根っこが横にすべってしまう演出が素晴らしかった。根っこ(マッサージ器)は上下にしか動かないのだが、ぐるりととりつけられた振動子を特定方向のみ振動させることで、根っこが横に移動したかのような感じを生み出していた。使いどころはいまから見つける事になるが、応用範囲が広そうな錯覚であるとチームのメンバーも述べていた。

出血体験

狼に噛まれることで、できた出血を体験する作品。出血のズキズキとした痛みを感じるのがメイン。予選にあった弓矢のくだりはなく、かわりにイスに縛り付けられており、より現実の体勢(イスに座っている)に寄せた体験となっていた。また振動体験装置のHapBeatにより、心拍を感じるようになっていた。痛みは予選同様に、温度差のある物体を触らせる事によって痛覚を発生させるサーマルグリル現象を用いている。断続的に痛みを呈示することで、ズキズキ感を出せているのに加え、この体験の後もしばらく痛みの余韻を感じれるが個人的にはよかったと感じている。

孤独をFoot Bath

波面をつかって、そこに人がいる存在感を示す作品。足湯を少女の幽霊が歩いて入ってくるという設定であった。確かに水面を通して何かがあるいていく感じがあった。ただ、CGではすり足のように動いて居たが足で感じる感覚としては、足を高くあげて歩いているように私は感じた。また予選では水面の波動のみでの感覚呈示であったが、水を掛け合うための機構(小さなシャワー)が追加されていた。

TeleSight

HMDとマネキンが連動していて、外にいる人にとってはマネキンこそが攻撃を担当するプレイヤーとなっている作品。外にいる人はプレイヤーが攻撃されたら目を守ってあげる。プレイヤーの攻撃技は目からビームなので、ずっと覆いっぱなしではいけない。なお、手で覆っている間も、実際のプレイヤー視界が覆われるわけではないという配慮がされているが、どちらがより良いのかは正直判断がつかなかった。予選では頭部にプロジェクタを搭載していたため、覆うときに若干影ができたりする事もあったが、本選では視線方向を計算して、CG合成でスクリーンに視界をつくっていた。この変更でマネキンが軽くなったせいか動きはかなりしっかりしたものとなっている。プレイスタイルは「外から察して上げる」か中から「声をだして助けを求める」という風な感じになっていた。

Be Bait!〜求めよ、さらば食べられん〜

自分が釣りエサになって、魚に食べられて釣り上げるという作品。予選との変更点で興味深かったのが、ストーリーの変更。魚となって泳いで食べられる。という体験から「揺れて、魅力的に見せて魚を誘って食べられる」という釣りのルアーのような体験に変更されていた。体験時間の短縮とともに、プレイヤーが「えっ?結局泳いで、何したらいいの?」と戸惑うのを大部減らせたと感じた。また、つり上げられる体験として足をロープで引っ張る機構も追加されていた。表彰では映像表現での工夫(大量の魚群をCompute shader駆使して書いたり、海中光源用のshader開発したり)という点も評価されていた。魚群はたしかに見ていて気持ちが良かった。

蹴球インパクト

マンガにある、タメの表現をともなったシュートができる作品。最初数回は普通のシュートが打てて、最後にミラクルシュートを打つという体験になっている(おそらく、VRシュートの世界に慣れるため普通のシュートが必要)。予選ではダイラタント流体で自然のタイマーリリース機構をつくったり、ストッパーと足の間をゴムヒモで繋いだりしていたが、決勝では自転車のブレーキで足につながれたヒモを掴み、ヒモもゴム製のものではなく普通のヒモにちかいものになっていた。その他のシューズ周りも丈夫につくり替えられており、体験に必要な表現を損なう事なくできるだけ丈夫で簡易な機構にかえていた。もちろん、足が急にギュッと止まる事によるミラクルシュート感はきちんと体験できていた。

無限滑り台

お尻のベルトと手すりの滑りで無限に滑り台を滑っている感じをだす作品。予選との違いはCGが大幅に改良されたこと。色々な世界を滑って回れるという感じがしました。手すり部分のローラーが大型化して、手すりのふりしてるけどローラーじゃん!感を減らすように改良されていた。CGがかなり急な下りなので、リアル側も速度感や傾斜がもっとあっても良いのでは?という気がしたが、安全生・実装容易性とのトレードオフだったのかもしれない。一周すると丁度お尻が熱くなってそろそろ降りたいという感じになるコースの長さ設定は程よく狙われいたと感じた。

2018年9月27日木曜日

IVRC2018体験報告

今年もIVRCの予選作品を全部体験する事に成功したので、全作品の感想を。チームへのヒアリングをしたりもしていますが、私の主観で書いてますので、各チームの思いとは乖離している場合があります。ご了承ください。

孤独をFoot Bath

水面に波を作る事で、HMDごしに見える足湯で少女とのインタラクションを楽しめるというものです。横を歩いて行く時に、視界には入ってないものの、確かに人が通った!という感触がありました。人間は無意識に水面を良く捉えているんだなと気が付かされました。ただ、その後少女と水面を揺らしあって遊ぶのですが、その際には水面のCGと実際の波面が一致いるとも感じられず、少し残念でした。横を通り過ぎる時の存在感に絞ったほうが評価が上がったかも知れません。

ブレインツリー

頭に根っこが映えてくる感覚は、頭部マッサージ用の針金で出来たアレを押し込むだけなのですが、CGとあいまって「何かが頭皮を這い回ってきている」感がすごいあります。また水を与えると首回りをチューブで水冷するのですが、確かに湿った土に首をうずめたらこんな感じだろうなぁ。という感じがしました。そういった触覚・温覚・湿度感はよく表現できてるなと感じました。ストーリーとしては頭に生やした木を育てて最後に引っこ抜くという話なのですが・・・体験がの刺激に集中してしまうせいか、ストーリーにはイマイチピンと来なかったです。

天獄渡り

セグウェイに乗って、高い場所を運転していくVRゲームなので、ゲーム内容としては割と普通。工夫している点は膝に振動モータを取り付けて、膝が震える感覚を出していた点。震える事で実は恐いのでは?という錯覚を出したかったとの事だが、「あ、ふるえてる」に留まってしまった。私の筋肉の緊張感が足りなかったのかもしれない。また下を見ると震える設定になっているという事だったので、ゲームクリアに集中して遠くを見ると中々震えを体験できない。というのがちょっと残念だった。長時間の震えを経験したらもしかしたら恐怖を錯覚したのかもしれない。

Be Bait!

自分が釣りエサになって食べられに行くというゲーム。エサになるので当然泳ぐ必要がある。ハンモックを二分割にして人間をつるシステムは乗り降りも楽だし、下半身の振動が上半身に伝搬する事がないので自然に水中浮遊の体験ができた。ただ、泳ぎ方が体を横にゆらせば泳げるというシステムだったので、ゲーム設定である「人間がエサになって海に飛び込む」ではなくて、人間が小魚になって、エサになりに行くという感じだった。見事サメに食べられると、上の黒い板が落ちてきて食べられちゃった感を提示するのだが、全然痛くはないけど、「覆われたぞ!」感はちゃんとある絶妙な重さだったのが印象的だった。

蹴球インパクト


PKをVRで体験できるシステム。足の甲に振動がくる以外は普通にありそうなVR体験になってしまっていた。というのも私が体験したときは「スーパーキック」ができるシステムが故障中だったので、一番の売りが体験できなかった。本当ならば、一旦ゴムチューブで足の動きを引き留め、力をためてから一気に解放されてシュートを決めるというスーパーキックができる予定だったとの事。キャプテン翼の足にぐにょっと変形して貼り付くボールの表現だったとの事だった。何となく想像では楽しそう。本選ではちゃんとスーパーキックを体験したい。

出血体験

冷たいものと熱いものが同時に触ると痛みを感じるという錯覚を利用して傷口の痛みを体感するシステム。狼に腕を引っかかれて出血する体験なのだが、上の錯覚のさいに副次的感じる熱を、血がドクドクと吹き出すときの熱としての表現に上手く再利用していた。コンテンツとしてはボーガンを左手でかまえて、右手で狼をねらってると左手を狼に噛まれてしまうというものだったが、特にその導入はあまりピンとこなかった。左手を固定されているというのとボーガンの相性が余りよくなかったのかもしれない。

鼻腕

自分が象のような鼻がついていて、アゴを動かすと鼻が操作できる。鼻息でモノを掴んだりもできるという体験ができる装置。指示されたタスクを淡々とこなすコンテンツになっていた。割と苦労するのかな?とおもいきや、違和感なく鼻の操作がすぐにできるようになるというのが面白かった。鼻の先に思いものをもつとヘルメットの上のお守りで前方が重くなるようになっていたが、そちらの重みに関しては鼻で操作してるぞ感が少なく、首で頑張ってるぞ感があった。

ピノーズ

こちらも鼻の作品だが、物理的に鼻を引っ張ると共に、鼻のCGが伸びて、自分の鼻が伸びたかのように感じる作品。CGとともに提示されるので、伸びたかなという感じは確かにあった。途中で、ものに鼻があたるとコツンとなったりもする。 なぜか、鼻を左右に揺さぶってびっくりさせる機能がついていたが、これに関してはどう解釈してよいかわからなかった。

無限滑り台

ベルトコンベアの上にソリをおいて無限にすべりおりる感覚を提示しているVR装置。手すりの丸い装置も回転して、手すりをすべっている感じをだしている。また手すり自体がそれぞれ回転することで、カーブを曲がっている状態を提示する事を狙っている。 一番滑り台感をかんじたのはベルトコンベアの継ぎ目を通過するときで、継ぎ目のある滑り台あるよね!って感じだった。しかしこの継ぎ目は狙って作ったものじゃなく偶然の産物であったという事だった。また滑り台は途中で曲がるのだが、このとき手すりが回転する。物理的に考えれば無茶苦茶な挙動だが、これによって自然に体のバランスがくずれお尻がベルトコンベアのずれた位置に行ってしまう。このお尻がずれたことでカーブ感がでていた。私の体感としては手すりはお尻をずらす、きっかけにすぎなかったのだ。狙って作ったのなら凄いが、そうじゃない気もする。ちなみにCGの滑り台カーブは90度カーブだったがさすがにそんなにはカーブした感じはしなくて、お尻は30度ぐらいに感じた。

TeleSight

HMDを被ってる人の動きを仮面がコピーしていて、外にいる人はHMDかぶっている人が「どっち」方向にある「何」をみているのかが解るようになっている。コンテンツはシューティングゲームになっており、防御する際には外の人に人形の目を隠して貰うという、外と内で相互に影響を与えるゲームになっている。「中の人」と「外の人」両方体験して初めて意味がわかる作品。中の人からは外の人がHMDのせいで見えないし、外の人もプロジェクタが不鮮明である事や、所詮はロボットの目線なので追いにくいという事から、お互いの動きが「ある程度解る」というものだった。そのため結局声で指示を出すことになるのだが、目でやろうとしてた時のもどかしさの対比で、声を出してコミュニケーションする事の大事さを実感した作品だった。(本人は多分そっちは意図してない?)

とうめいなおかいもの

こちらも両方を体験しないとわからないシリーズ。足跡だけが見える店舗模型と、その中で買い物タスクをこなすHMDを被った人という作品。透明人間がお店にいますよ。という設定だったのだが、透明人間である必然性は謎だった。とにかく足跡だけみて何しているか想像を巡らせて見ましょうというもので、後でHMD被って体験すると「あ、これしてたのね」という感じだった。後でヒアリングしたところ、ハリーポッターの足跡が見える本にインスパイアされたものだという事だった。ハリーポッターでは足跡をつかってライバルを出し抜いてやろう!だとか、憧れののあの子の足跡だ〜♪的な事前情報があるので足跡だけで楽しめるモノがあったんだと思う。そう考えるとコンテンツにもう一ひねりほしかった。

目からビーム

熱をまぶたに一定時間感じるとビームが出せるようになるので、それで目からビームをだして敵を倒そうというゲーム。残念ながらシステムが上手く動かず部分的な体験になった。目からビームの前にまぶたに力がたまるのを表現するのに外部から赤外線でまぶた付近をあっためているのだが、外からの熱であって内からわき出る力感がなかったのが少し残念だった。とはいえ、顔の熱を狭い範囲感じさせようという熱意はすさまじく、もういっぽ何かできたのかな。という気がした。

めざせドラムマスター

見たまんま、ドラムの音ゲー(ただし、3DCGが空中にういている)であるが、ドラムが上手く叩けた時だけタイコの皮が張っているというものだった。タイミングがうまくあった時だけ気持ちよく叩けるというコンセプトは面白いし、実際に張っている時と張ってない時の違いを感じる事はできたが、今ひとつ太鼓の皮の張りが弱く、そもそも「気持ちよく叩ける!」が体験できなかったのがちょっと残念だった。

ハコニワールド

キューブを触るとCGの中のビルを操作できて振り回す事ができるという作品。ネタとしてはIVRC2008のふしぎデスクの亜種なのだが、CGと現物模型のサイズが合わせ込めてなかったのが少し残念だった。

金縛り布団VR

部屋の中でくつろいでいると、幽霊がやってきて、布団の上に飛び乗ってくるという作品なのだが、映像が非常に映画的に作ってあった。具体的には、ほぼモノクロの世界で幽霊はパッと現れては消え、次ぎにはもっと近い所に現れては、一瞬にしてまた消え。と繰り返して最後にベッドの上に現れる。その時、錘が同時に足の上に落ちてきてビビらせる(幽霊に押さえられた表現)。 途中にカメラブレなどをいれたりして映画的表現を頑張って3Dの中に作っているのだが、HMDで映画的な表現を見ると不思議と、テレビで見るよりも他人感がでて、逆に没入できなくなるんだな。ある意味失敗なんだけれども学びの多い作品だった。

ウォーターストライダー

水面をアメンボになって移動していく体験ができる作品。人間の重さに耐えながら手足を上下に揺動させる(+傾ける)ハードを軽く作るのに涙ぐましい努力をしていた。ただCGの波の振動周期と手足の揺動の周期が合ってなかったため、ゆれているが何故ゆれているかがわかりにくかったのが残念だった。

夢をバクバク

口をあけると空気をブシュッっと打ち込まれ、口の中に何かが入った感じを出す装置。口を閉める必要がないコンテンツ体験だったので、何故わざわざ口の開閉をセンサーで検知する必要があったのか?と疑問は色々あるが、空気の塊が口に入ってきた!という感じはちゃんとあった。また空気の塊をつっこむ時意外も弱く空気を流しておくことで違和感を無くすという事をしていたのは、面白い試みだった。画面中で自分が移動しているので、確かに全体的に違和感がなくなっている気はした。がっつり不透明度100%のオブジェクトが入ってきた!って感じには鳴らなかったので、感覚にCGを合わせるなら不透明度20%ぐらいにおさえたほうが良いのかも?とは感じた。

華麗なる回転

スケートで4回転ジャンプをするCGにあわせて、人力で台座を90度回すことで4回転まわった感じがするという技能系の作品。私が体験したときは、タイミングがずれたせいか1回転したかな?という感じだった。それでも90度にくらべれば4倍なので健闘していた。
ちなみに自力で滑る方向・速度は決められない、追体験専用であった。

ガラスクラッシャー

ガラスを割る感覚を楽しむ作品。CGは間に合わなかったようだが、割る触覚の体験はできた。ガラス・・・ではないが、昔割ったことのある素材の感覚がした。フィルム強化されたガラスあるいは、飴のように、割ったあとに何回かたたいて崩さないといけない感じのもの。ガラスとしては残念だったが思い出せないけれども、なんかある!この割りくずしていく感覚!という作品だった。

異世界(あちら)のお客様から

Vtuberにカウンターでお酒をすべらせて渡す作品。たったそれだけだが、受け取ってくれると嬉しい。ちなみに裏にほんとうにVtuberが控えている。こういったコミュニティ要素のある作品は、短時間のデモでは難しいが果敢によく挑戦したと思う。ぶっちゃけVtuberの反応で価値が大きく変わるので、今後に期待。

リトルウォークメア

超音波で手のひらに触感を発生させて、手のひらの上をコビトが歩く感じを体験させるコンテンツ。ちょっと出力が弱かったのが残念。あとわりと有名なデモも多くあるので、レッドオーシャンで戦う必要があるのが大変そうだった。

回路のお医者さん

ブレッドボードなんだけど、電線のかわりに特殊なチューブで信号をつないで、ロボットを動かすシステム。
デバイスとしては、すごく良く出来ていて、チューブば律動するし、チューブをつかんでる力を検出して、出力を調整するしくみもよくできていた。信号源や、信号を反転する素子があったりして、教育用途を目指しているのかな?という感じも見受けられた。
ただ、それで行うデモが、ロボットの手足を振るだけに見えてしまう所もあった。もっと色々使えそう!!というモヤモヤが残る作品だった。

2018年6月10日日曜日

YDLidar X4 をESP32で使ってみた

1万円LidarのYDLidar X4を使ってみた記録です。

概要

・YDLidar X4のシリアル信号デューティ比問題を改造で乗り切り、ESP32を含む様々なシリアルに繋ぎやすくした。
・ESP-IDF向けの実装でデータを取得できるようにした。
・角度計算の式を近似式で軽量化した。


ハードウェアの修正

YDLidar X4にはシリアルのデューティ比が狂うという問題があります。以下のオシロの図はLow/High/Low/Highとなっていますが、真ん中のHiとLowの幅をみると長さが違います。これを修正する必用があります。
この問題を修正する改造ポイントが以下になります。ここは赤外線で来た鈍った信号を閾値で0/1に変換するコンパレータが入っています。矢印の先が閾値を決定する12kの抵抗(
2個)です。

 上の図でP2の位置の電圧を可変にするために、既存の抵抗をとっぱらった後に、
抵抗とポテンショを以下のように繋ぎます。
P1==[R4.7k]==[POT 10k]==[R4.7k]==P3
ポテンショの中点をP2に接続すればOKです。
調整はオシロがあれば、良いのですが、なければ以下の私の実装だと、check sum errorをESP_LOGEで出力しているので、そのerrorが減るように真ん中付近からポテンショを動かしてみて下さい。

ESP-IDF用の実装

オフィシャルにはArduino用の実装があります。(https://github.com/EAIBOT/ydlidar_arduino)しかし、この実装はIO待ちをループで実装しているため、ESP-IDFにはむきません。ということで、実装してみました。
 https://bitbucket.org/akira_you/esp-ydlidarx4/

使い方はmain.c及びydlidarTask.hを見て下さい。C言語でのインターフェイスで呼び出しています。複数のYDLidarを使うにはydlidar_beginの中身を参考にYDLidarクラスを直接呼び出して下さい。

計算高速化(興味ある人向け余談)

 ESP32で使う上で残る問題が計算量です。YDLidar X4のデータは「角度」と「距離」からなりますがこの角度は、距離に依存して補正するAngCorrectという関数で補正をかける必要があります。こいつがatanを含んでいるのですが、5kHzでatanを計算するのはESP32には余裕というわけではないです。
角度補正式

このAngCorrectは十分にDistanceがあれば、1/(a*[Distance]+b)-cという式の形に近似できます。Cは無限遠時の値、約-7.99に固定できるのでa,bを以下のスクリプトで120mmから10mの範囲で最適化しました。(ちなみに120mmは最小測定距離)
  https://gist.github.com/akirayou/3fd54239e6bbd4abb416c8bea73ad1f0




YDLidarX4は罠の多い製品ですが、1万円ならないよかましですよね。
以上


 

2018年5月23日水曜日

デザイナにはデータを構造化して渡そう

イベントのスケジュール欄とかの印刷物を作っていると、後から後から修正が来て結局修正漏れになったりする事って多いですよね。ということで西院フェス(音楽フェス)のパンフ作成でやって上手く行ったワークフローの紹介です。
 イメージ的にこんなやつです。このミュージシャンが変更になった、バンド名に「.」が抜けていたとかいう連絡さ五月雨式にやってきます。

ステップ1:情報を一カ所に集める

西院フェスの場合は、Webで全てを管理してますが、いきなりハードル高いデスよね。Google docなんかでエクセルを共有するだけでも良いかと思います。
エクセルでやるならばvlookupなどを使って、スケジュール一覧にバンドIDいれれば、そこから各種データを切り出せるよ!っていうセルマクロが要るとは思います。

ただし全員がそのデータを見て「便利」と思わないと積極的に更新してくれません。各自の連絡をうけて一人で更新すると気が滅入るので、各ブッキング担当・会場担当が自分で更新してくれる空気作りに数年かかりますが、できちゃうと超楽です。
西院フェスでは以下のように一カ所のデータを多面的に使う事で、全員がソコに有るデータが原本という風に認識しています。

  1. ブッキング担当の音源選考用データベース(音源が貼り付けてあって聴ける)
  2. Webに載せる用のライブスケジュール(自動で連動)
  3. パンフ/ポスター担当がスケジュール及び、ミュージシャン/会場一覧覧をGET
  4. 出演時間の交渉のための各会場担当用の連絡先一覧
  5. PA番長が会場ごとに機材仕込むための要望機材一覧表
  6. PAマンが会場で使う出演順のセッティング図一覧
ちなみに、西院フェスでは以下のようにJSONでスケジュール一覧をGETできるサービスを持っているので、ソレをつかってパンフ担当は仕事をします。

https://saifes.net/joinA/artist_json.php?e=2017spring

ステップ2:データを流し込む

データをイラレのスクリプトを使って流し込みます。文字列がはみ出たりするけれども、どうせフォント縮小でいくのか、改行でいくのかパンフ担当が拘りたいところなので、何もせずはみ出たまま流し込みます。
この時流し込む座標はスケージュール時間と、テンプレートとなるイラレファイルから計算して座標を求めています。なので既に作ったスケジュール枠の上にレイヤーを重ねれば左上の絶対位置は正しいという風になります。


ステップ3:差分を自動生成する 

流し込みができたので完成と思いがちですが、字詰めも終わったぞ〜〜って時に変更依頼がきたりします。ここでゼロから流し込みするわけにはいきません。
ということで、差分情報を元に変更一覧を作ってあげます。この変更一覧は上の流し込みにつかったjsonを流し込みした日付を付与して保存しておくことで解決です。その流し込みからの差分をしりたいので、二つのjsonをひかくするだけでOKです。diffsche.pyという専用のプログラムで差分があったスケジュールだけを出してくれるので、そこだけ修正漏れがないかを確認すればOKです。
会場担当がバンド名やジャンルを修正して、それをパンフ担当に伝えてなかったって事がよくあるのですが、そういう伝達漏れの心配はこれでなくなります。


そして、デザイナの作業も変わります。五月雨式に対応するのではなく、デザイナが作業するタイミングで差分データの作成をデータ提供者に要求するのです。確認工数が減るとともに、工数が読みやすくなります。


参考

ソースコードはここに置きました。以上の事を発注者側が全部やるのは無理にしても、こういう管理ができるように、せめて、デザイナには一貫されたフォーマットで矛盾のないデータを作って渡してあげましょうね。
https://bitbucket.org/akira_you/saifes_nagasikomi