ソースに絡まるエスカルゴ

貧弱プログラマの外部記憶装置です。

【Blender】ベルトコンベアの作り方と物理演算

 タイトルにある通りBlenderでベルトコンベアを作り、物理演算でベルトコンベア上のオブジェクトを動かすというのをやってみました。
f:id:rikoubou:20180331035809g:plain

 こんな感じのものをBlenderで作る方法を備忘録として残しておきます。


1:ベルトコンベアの軌道を作成する
 Blenderを起動させたら、3Dモデル上にマウスカーソルを持って来て「Xキー」を押して邪魔なCubeを削除します。
f:id:rikoubou:20180331003520p:plain

 次に3D Cursorが原点にある状態で3D View画面左側にある「Create」タブを左クリックし、Curveの項目の中にある「Nurbs Circle」を左クリックします。
f:id:rikoubou:20180331004341p:plain

 3D View画面上に「BezierCircle」という名前の輪が作成されます。
f:id:rikoubou:20180331004556p:plain

 この「BezierCircle」を選択した状態(選択されていない場合は右クリックで選択)で箱のような見た目のオブジェクトボタンをクリックします。出て来た項目にあるTransformのRotationのXを「90」、ScaleのXを「0.7」、Yを「0.05」と入力します。
 すると3D View画面上のBezierCircleがこのような形になり、ベルトコンベアの軌道が作成できました。(マウスのホイールを使って拡大させたり、ホイールをクリックした状態で動かして見たい角度にしてください)
f:id:rikoubou:20180331020237p:plain

 また3D View画面上にマウスカーソルがある状態でテンキーの「1キー」を押すと、BezierCircleの楕円を真正面から見ることができます。
f:id:rikoubou:20180331020355p:plain

2:ベルトコンベアの1つ分のパーツを作る
 1でベルトコンベアの軌道を作成したので、次はパーツを作ります。

 3D Cursorが原点にある状態で3D View画面左側にある「Create」タブを左クリックし、Meshの項目の中にある「Plane」を左クリックします。
f:id:rikoubou:20180331010639p:plain

 3D View画面上に「Plane」という名前でオブジェクトが作成されます。
f:id:rikoubou:20180331010819p:plain

 この「Plane」を選択した状態で箱のような見た目のオブジェクトボタンをクリックします。出て来た項目にあるTransformのScaleのXとYをそれぞれ「0.02」、「0.05」と入力します。
f:id:rikoubou:20180331020504p:plain

 すると「Plane」はこのような形になります。これが複数あるとベルトコンベアっぽい感じになるのがイメージできると思います。
f:id:rikoubou:20180331020544p:plain

 このScaleの値を基準とさせるため、3D Viewの左下にある「Object」を左クリックし「Apply」、そして「Scale」と左クリックで選択します。
f:id:rikoubou:20180331013417p:plain

 これで「Plane」の形はそのままでScaleの値が全て1に設定されます。
f:id:rikoubou:20180331020653p:plain

 しかしこのままでは厚みがないため「Plane」に厚みを持たせます。「Plane」を選択した状態でスパナのような見た目のModifierボタンを左クリックし「Add Modifier」プルダウンの中から「Solidify」を左クリックで選択します。
f:id:rikoubou:20180331011649p:plain

「Offset」に「1」、「Thickness」という項目の値を適当な値として「0.01」と入力して「Apply」ボタンを左クリックして適用させます。
f:id:rikoubou:20180331020844p:plain

 これで「Plane」に厚みが適用され、1つ分のパーツが完成です。
f:id:rikoubou:20180331020923p:plain


3:軌道に沿ってパーツを配置させる
 2で作成した「Plane」を選択した状態でスパナのような見た目のModifierボタンを左クリックし「Add Modifier」プルダウンの中から「Array」を左クリックで選択します。
f:id:rikoubou:20180331012523p:plain

 追加されたArrayの中にあるFit Typeのプルダウンを左クリックし「Fit Curve」を左クリックで選択します。
f:id:rikoubou:20180331012706p:plain

 でてきたCurveの項目を左クリックして1で作成した軌道の「BezierCircle」を左クリックで選択します。
f:id:rikoubou:20180331012952p:plain

 すると「Plane」が大量に出て来るので、Relative Offsetの一番上の値を調節して幅を持たせます。(ここでは値を1.1にしました)
f:id:rikoubou:20180331021115p:plain

 次に「Plane」を選択した状態でもう一度「Add Modifier」プルダウンを左クリックし「Curve」を選択します。
f:id:rikoubou:20180331014011p:plain

 追加されたCurveのObjectの箱部分を左クリックして「BezierCircle」を左クリックで選択します。
f:id:rikoubou:20180331021252p:plain
f:id:rikoubou:20180331021428p:plain

 すると1で作成した楕円に沿って2のパーツである「Plane」が配置されます。
f:id:rikoubou:20180331021521p:plain

 この状態で「Plane」を選択し、オブジェクトのLocationのX座標を左右にドラッグして値を変更させてください。Xの値によって回転します。
f:id:rikoubou:20180331024231g:plain

 これで見かけ上のベルトコンベアは完成です。単純に動かすだけであればすでに完成していますが、物理演算をさせるためには他にも設定が必要になります。


4:作成したベルトコンベアの剛体設定をする
 3までできたら「Plane」を選択した状態でスパナのような見た目のModifierボタンを左クリックし、すでに追加されているArrayにある「Apply」ボタンを左クリックして適用させます。これでArrayで配置させたもの全てがPlaneとして一つのオブジェクトになります。
f:id:rikoubou:20180331024830p:plain

 次に「Plane」を選択した状態でチェックマークのような見た目のPhysicsボタンを左クリックして「Rigid Body」ボタンを左クリックします。これでオブジェクトが「剛体」になります。
f:id:rikoubou:20180331025051p:plain

 Rigid bodyの項目にあるプルダウンを左クリックして「Passive」を選択し、Animatedにチェックを入れます。特にこのAnimatedのチェックは忘れないでください。
f:id:rikoubou:20180331025435p:plain

 Passiveは外部からの力を受けない限り動かないという剛体の設定、Animatedはアニメーションをさせる(任意に移動させるなどの)場合にチェックを入れるというものです。つまりこの設定で「静止した状態でX座標を任意に変化させてベルトコンベアを回す」という剛体ができたことになります。


5:ベルトコンベア上にCubeを落として動きを確かめる
 剛体のベルトコンベアが作成できたので、上からCubeを落として動きを見てみましょう。
 3D View画面の左側にある「Create」タブを左クリックし、Meshにある「Cube」を左クリックします。
f:id:rikoubou:20180331030445p:plain

 かなりでかいCubeが作成されるので、作成されたCubeを選択した状態で箱のような見た目をしているオブジェクトボタンを左クリックし、TransformのScaleを調節します。ここでは全て0.05にしてあります。
f:id:rikoubou:20180331030755p:plain

 大きさの調節ができたらCubeの剛体設定を行います。

 Cubeを選択した状態で、先ほどと同じようにPhysicsボタンを左クリックし、「Rigid Body」ボタンを左クリックします。
f:id:rikoubou:20180331031025p:plain

 Cubeの場合はRigid Bodyの設定は特になにもいじらないままにします。(ActiveかつDynamicにチェックが入っていることで「自由落下をする剛体」という設定になります)
f:id:rikoubou:20180331031223p:plain

 ここまでできたらCubeを選択した状態で箱のような見た目をしているオブジェクトボタンを左クリックし、TransformのLocationの各座標を調節してベルトコンベアの少し上に来るようにします。
f:id:rikoubou:20180331031918p:plain

 準備ができたら再生ボタンを左クリックしてください。
f:id:rikoubou:20180331031700p:plain

 するとCubeが落下してベルトコンベアに当たります。その後「Plane」を選択した状態でTransformのLocationのX座標を変化させると、その変化量に応じてベルトコンベアに乗っているCubeも動きます。ベルトコンベアの端に行ったり、Cubeのバランスが悪いと下へと落下します。
f:id:rikoubou:20180331032414g:plain

 これでベルトコンベアの物理演算ができました。


6:アニメーションとしてのベルトコンベア物理演算
 物理演算はできましたが、毎回手動で座標を変化させるなんてことはできないのでアニメーションでずっと回転させるようにします。

 タイムラインの一番左下にあるプルダウンを左クリックし、「DopeSheet」を左クリックで選択します。
f:id:rikoubou:20180331032903p:plain

 DopeSheet画面はこのようになっています。緑色の線にある現在のフレームが「1」であることを確認してください。「1」でない場合は数字の書かれている緑の部分を左クリックのドラッグで移動させてください。
f:id:rikoubou:20180331033033p:plain

 ベルトコンベアが表示されている3D View画面にマウスが乗っている状態で「Plane」を選択して、TransformのLocationのX座標を「0」に戻しておきます。
f:id:rikoubou:20180331033258p:plain

「Plane」を選択し、3D View画面にマウスが乗っている状態で「iキー」を押して「Location」を左クリックします。
f:id:rikoubou:20180331033504p:plain

 これで1フレーム目にX、Y、Zの座標が登録できました。登録された項目が黄色になっていることで確認できます。
f:id:rikoubou:20180331033843p:plain

 次に24フレーム目までドラッグします。
f:id:rikoubou:20180331034210p:plain

 再び「Plane」の「Location」を以下の値にします。
f:id:rikoubou:20180331034328p:plain

 この状態で再び「iキー」を押して24フレーム目に「Location」をキーフレームとして登録します。
f:id:rikoubou:20180331034447p:plain

 一度タイムラインに戻って1フレーム目から再生させましょう。
f:id:rikoubou:20180331034556p:plain

 すると24フレームまではベルトコンベアが回転していることがわかると思います。しかし24フレーム目から先は設定されてないので止まってしまい、その勢いでCubeが落ちてしまっています。
f:id:rikoubou:20180331034916g:plain

 これでは困るので、再びDope Sheetに戻りアニメーションのループ設定を行います。

 24フレーム目であることを確認し、Dope Sheetの「Channel」、「Extrapolation_Mode」、「Make Cyclic」を左クリックで選択します。
f:id:rikoubou:20180331035409p:plain
f:id:rikoubou:20180331035350p:plain

 これでアニメーションのループ設定が完了です。

 もう一度タイムラインに戻って再生してみるとこのようになります。
f:id:rikoubou:20180331035809g:plain

 ちょっとつっかえてたりはしましたが、ちゃんと一番端までCubeが自動的に送られました。


 長々となってしまいましたが、以上がBlenderにおけるベルトコンベアの作り方と物理演算です。
 アニメーションについてはループよりも一定量ずっと変化みたいなのが「Extrapolation_Mode」から選択できそうなのでもっと滑らかにできるかもしれません。方法を知っていたら教えていただきたいです。
 また「Rigid Body」の設定値として摩擦係数などの設定もできるようなので、その値を調節することでよりリアルなシミュレーションも行えるようです。

 ベルトコンベアを縦横に並べてダンボールなどの仕分け作業ごっこみたいなのをやるのも楽しいかもしれません。


・2018/06/30追記
 最後に書いた一定量の変化は以下の操作をすればできることがわかりました。
f:id:rikoubou:20180630020111p:plain

 これで一定量の変化となり、その後に「Make Cyclic」を行えばよいです。

 またベルトコンベアを2つ作成し、L字の直角になるように配置して物を動かすというシミュレーションをしたい場合があります。

 基本的には個別の微調整でどうにかするしかないのですが、ベルトコンベア自体のオブジェクト(Plane)のRigid body Collisionsの設定は以下のようにしておくと調節しやすいです(多分)。
f:id:rikoubou:20180630015312p:plain

 一応ちゃんと物理演算で動いたベルトコンベアL字の.blendファイルも公開しておきます。


おまけ:3D Cursorの原点合わせ
 3D Viewの右端にある「+」となっている部分を左クリックします。
f:id:rikoubou:20180331010007p:plain

 でてきたものをスクロールしていくと「3D Cursor」という項目あるので、これら全ての座標に0を入力すれば原点に合わせることができます。
f:id:rikoubou:20180331010346p:plain


・参考資料

【Blender】取り込んだモデルをアニメーションさせる

rikoubou.hatenablog.com

 前回の記事でSculptrisで作成したモデルをBlenderに取り込むところまでをやりました。
 今回はこのモデルを動かすところまでやっていこうと思います。


1:取り込んだモデルのポリゴン数を削減する
f:id:rikoubou:20180213182410p:plain

 前回の記事で上記画面のモデルとテクスチャを取り込んだ状態にまでなっていると思います。
 しかしこのままではポリゴン数が多く、アニメーションを設定する際にPCの性能によっては処理が重くなってしまいます。

 そこでポリゴン数を削減してモデル自体のデータ量を抑える必要が出て来ます。

 右上にあるモデルを選択し、「Modifiersのアイコン(レンチのようなアイコン)」をクリックします。
 「Add Modifier」をクリックし「Decimate」を選択します。
f:id:rikoubou:20180213183300p:plain

 追加された中にある「Ratio」を左ドラッグや直接数値を打ち込むとポリゴン数が増減します。
 「Apply」ボタンを押すと変更したポリゴン数が反映されます。
f:id:rikoubou:20180213183913p:plain

 自分の場合はかなり減らして9000ポリゴンぐらいまで落として「Apply」しました。
f:id:rikoubou:20180213184455p:plain


2:モデルの位置を移動させ、モデルを見やすくする
 3D View画面上にマウスカーソルがある状態でテンキーの「1キー」を押すと正面、「3キー」を押すと真横の表示になります。
f:id:rikoubou:20180331114224p:plain
f:id:rikoubou:20180331114324p:plain

 これらカメラの位置切り替えを使いながらモデルの位置合わせを行います。

 右上にあるモデルを選択し、「Objectのアイコン(ボックスのようなアイコン)」をクリックします。
「Transform」の「Location」や「Rotation」の値を左ドラッグしたり、数値を打ち込んだりしてモデル中心の真下に原点が来るように調節します。
f:id:rikoubou:20180331114945p:plain
f:id:rikoubou:20180331115011p:plain

 位置の調節が済んだら現在の座標や回転、大きさをデフォルトの値として登録します。

 左下にある「Object」から「Apply」の中にある「Location」を左クリックで選択して座標を登録します。
f:id:rikoubou:20180331115658p:plain

 次に「Object」から「Apply」の中にある「Rotation & Scale」を左クリックで選択して回転と大きさを登録します。
f:id:rikoubou:20180331115749p:plain

 これでTransformの値が変更され、デフォルトの値になりました。
f:id:rikoubou:20180331115907p:plain


3:アニメーションさせるためのボーンを追加する
 モデルを動かすための骨となるボーンの追加を行います。
 始めに3D View上の十字のマークが原点にあることを確認してください。
f:id:rikoubou:20180331120751p:plain

 ↑の画像のように原点にない場合は3D View画面の右上にある「+」のボタンをクリックします。
f:id:rikoubou:20180331120850p:plain

 スクロールしていくと「3D Cursor」という項目が出て来るので座標全てに0を入力します。
f:id:rikoubou:20180331120905p:plain

 十字のマークが入力された座標である原点に移動します。
f:id:rikoubou:20180331120952p:plain

 そこまでできたら3D View上にマウスカーソルがある状態で「Shift + Aキー」を押して「Armature」、「Single Bone」を選択します。
f:id:rikoubou:20180331121105p:plain

 モデルに被ってわかりにくいですが、十字マークがあるところにボーンが作成されます。
f:id:rikoubou:20180331121321p:plain

 右側にある「Armature」を選択し、「Armatureのアイコン(人型のアイコン)」をクリックします。「Display」の「X-Ray」にチェックを入れるとモデルを貫通してボーンが表示されるようになります。
f:id:rikoubou:20180331121750p:plain

 ボーンの先がTip、ボーンの根元がRootと呼び、このボーンを複数繋げてモデルの骨格を作り上げていきます。
f:id:rikoubou:20180331122245p:plain

 左下にあるモードを「Edit Mode」に切り替えます。
f:id:rikoubou:20180331122336p:plain

 Edit Modeに切り替えたら左側にある「Options」から「X-Axis Mirror」にチェックを入れます。
f:id:rikoubou:20180331122641p:plain

 これでX軸を中心として左右対称のボーンが設定できるようになりました。次に一番最初のボーンを基準となる位置(背骨あたり)に移動させます。

 三角の部分を右クリックでボーン全体を選択し、各軸の矢印を左ドラッグで移動させて背骨あたりに移動させます。TransfomのRotationの値を変更することで回転させることもできます。
f:id:rikoubou:20180331123513p:plain

 またTipやRootのみを選択した状態で動かしたり縮小、拡大させることもできます。
f:id:rikoubou:20180331123906p:plain

 今回はモチーフが亀なので最初のボーンはこのあたりに移動させました。
f:id:rikoubou:20180331124016p:plain


4:ボーンの押し出しを行って骨格を作成する
 基準となるボーンを作成したら、TipまたはRootを選択して「Eキー+左ドラッグ」を行うと選択した場所から新たなボーンが生えて来ます。軸に沿って伸ばしたい場合はX、Y、Zのそれぞれのキーを押すと軸が固定されます。ちょうど良い位置まで伸ばしたら左クリックで確定させます。
f:id:rikoubou:20180331124358g:plain


 左右対称にボーンを伸ばしたい場合は「Shift+Eキー+左ドラッグ」で左右対称にボーンを生やすことができます。
f:id:rikoubou:20180331124812g:plain

 位置確定させた後でもTisやRoot、ボーン全体を選択してからの位置調整もできます。

 上記の方法を繰り返して動かしたい(関節としたい)部分だけボーンを追加して骨格を作成していきます。

 今回のモデルでは以下のようにしました。
f:id:rikoubou:20180331125724p:plain


5:各ボーンの名称をつける
 どれがどのボーンかがわからないのでわかりやすいように命名していきます。

 左側の「Armature」から辿っていくとど追加したボーンが出て来きます。
f:id:rikoubou:20180331125913p:plain

 名称を設定したいボーンのところでダブルクリックして名称変更します。
f:id:rikoubou:20180331130059p:plain


6:モデルと骨格をペアリングする
 アーマチュアの骨格までは作成しましたが、まだモデルと関連付けはされてないのでメッシュとアーマチュアのペアリングを行います。

 はじめに左下にあるところから「Edit Mode」から「Object Mode」に切り替えます。
f:id:rikoubou:20180331130634p:plain

 モデルのメッシュを左クリックで選択した後、Shiftを押しながらArmatureを左クリックして両方選択した状態にします。
f:id:rikoubou:20180331130955p:plain

 この状態で3D View上で「Ctrl+Pキー」を押して「With Automatic Weights」を左クリックします。
f:id:rikoubou:20180331131334p:plain

 するとArmatureのところにメッシュが移動します。これでモデルと骨格のペアリングが完了です。


7:ポーズモードでポーズをとらせる
 メッシュとアーマチュアのペアリングが完了したら、左下のところから「Pose Mode」を選択してポーズモードに切り替えます。
f:id:rikoubou:20180331131629p:plain

 右クリックでボーンを選択して座標を移動させてみると、ボーンの動きに合わせてモデルも変化します。
f:id:rikoubou:20180331131905g:plain

 直前の動きは「Ctrl+Zキー」でやり直しができます。
 ボーンを初期位置に戻したい場合は、3D View上で「Aキー」で全ボーンを選択した状態で「Alt+Gキー」で位置、「Alt+Rキー」で回転、「Alt+Sキー」で拡縮を元に戻すことができます。


8:マスターボーンを追加する
 現状のままではボーンが一体となっていないので、マスターボーンを追加して全てのボーンの親にします。

 左下のところから「Edit Mode」を選択して編集モードにします。
f:id:rikoubou:20180331132418p:plain

 適当なわかりやすい位置のTipを右クリックで選択し、そこから目立つ方向へボーンを追加します。追加したボーンの名称は「master」に変更します。マスターボーンの場所はどこでも良いのですが、自分はこのようにしました。
f:id:rikoubou:20180331132956p:plain

 マスターボーンを選択した状態で「Boneアイコン(骨のアイコン)」をクリックして、その項目の中にある「Relations」の「Parent」の「×」マークを左クリックして独立したボーンにします。
f:id:rikoubou:20180331133343p:plain

 これでマスターボーンが独立したボーンになりました。
f:id:rikoubou:20180331133656p:plain

 今度はマスターボーンを親にしていきます。Armatureの直下に表示されているボーン(上記の画像ではbase、tail1、legL、legRの4つ)の一つを選択して「Relations」の「Parent」でmasterを選択します。
f:id:rikoubou:20180331134014p:plain

 これをArmature直下に表示されているボーン全てに行います。全て行うと以下のように全部のボーンがmasterの子になります。
f:id:rikoubou:20180331134205p:plain

 これでアニメーションをさせる準備が完了です。


9:アニメーションを作成する
 一番左下にあるところから「Dope Sheet」を選択します。
f:id:rikoubou:20180331134501p:plain

 Dope Sheetの画面になったら、Modeのところから「Action Editor」を選択します。
f:id:rikoubou:20180331134638p:plain

 Newボタンをクリックしてモーションを作成します。
f:id:rikoubou:20180331134913p:plain

 モーションの名前を設定し、「Fボタン」をクリックします。(「Fボタン」のクリックを忘れないように!
f:id:rikoubou:20180331135002p:plain

 ここまでできたら「Pose Mode」に変更します。
f:id:rikoubou:20180331135051p:plain

 Pose Modeの状態でボーンを様々動かして1フレーム目としてのポーズを作成します。

 最初の状態としてのポーズができたら「Aキー」を押して全ボーンを選択した状態で「iキー」を押して「LocRotScale」を選択します。
f:id:rikoubou:20180331135750p:plain

 すると1フレーム目に各ボーンの位置、角度、大きさが記録されます。 
f:id:rikoubou:20180331135928p:plain

 1フレーム目は左足を前に出している状態ですが、歩くためには左右対称のポーズをとったフレームも必要です。

 任意のフレームをコピーしたい場合は「Dope Sheet Summary」の行のところを右クリックで選択して「Ctrl+C」でフレームごとコピーします。
f:id:rikoubou:20180331140353p:plain

 そしてコピーしたいフレームまで移動させて「Shift+Ctrl+Vキー」でコピーフレームの左右反転させたものを登録することも可能です。
 左右反転のフレームコピーがおかしくなる場合は、素直に手づけでフレームを作成しましょう。

 このようなモーションを作成しました。
f:id:rikoubou:20180331142555g:plain

 モーションができたら左下にあるところから「Timeline」を選択します。
f:id:rikoubou:20180331142725p:plain

 タイムラインの画面になったら「|◀︎◀︎」のマークで1フレーム目まで戻し「▶︎」マークで再生します。
f:id:rikoubou:20180331143051p:plain

 再生しても動かない場合は「Edit Mode」になっているので「Object Mode」か「Pose Mode」にしてから再生してください。
f:id:rikoubou:20180331143449g:plain

 ボーンを見せたくない場合は「Armature」を選択した状態で「Boneアイコン」の「Display」の「Hide」にチェックを入れると見えなくなります。
f:id:rikoubou:20180331144237p:plain



 長々となりましたが、以上で取り込んだモデルをアニメーションさせるところまでいけました。
 慣れて来るとそうでもないのですが、ちゃんと説明しようとすると操作が複雑なので手順が多くなってしまうところが考えものです。しかしBlenderは本当に色々できるので、扱えるようになれば強力なツールであることには間違いないです。

 これからも少しずついじっていこうと思います。


・参考資料

【Unity/Arduino】UnityとArduinoの加速度センサを連携してみた

rikoubou.hatenablog.com

 前にUnityとArduinoをSerialで連携させるのをやってみました。

 今度は照度センサではなく、加速度センサを連携させてUnity上の立方体をぐりぐり動かすというのをやっていこうと思います。


1:材料/開発環境
■開発環境

■材料


2:Arduino側の準備
 以下のように回路を組みます。加速度センサのデータシート通りの回路です。
f:id:rikoubou:20180208161502p:plain

 ArduinoUnoに以下のスケッチを書き込みます。

/**
 * Arduino UnoでのKXSC7-2050加速度センサーのスケッチ
 */
const int X_PIN = A3;
const int Y_PIN = A4;
const int Z_PIN = A5;

/* 加速度センサの値の構造体 */
struct Coordinate {
  long cx;
  long cy;
  long cz;
};

/* 角度の構造体 */
struct Angle {
  int ax;
  int ay;
  int az;
};

void setup() {
  Serial.begin(115200) ;
}

void loop() {
  Coordinate c = getCoordinate();
  // showCoordinate(c); // ここのコメントアウトを外して最大値・最小値を記録してください
  Angle a = angleCalculation(c);
  showAngle(a);

  delay(50) ;
}

/**
 * 加速度センサーの値を取得する関数
 */
Coordinate getCoordinate() {
  Coordinate c;
  long x = 0, y = 0, z = 0;

  // 各データを100回読込んで平均化する
  for (int i = 0; i < 100; i++) {
    x = x + analogRead(X_PIN);  // X軸を読込む
    y = y + analogRead(Y_PIN);  // Y軸を読込む
    z = z + analogRead(Z_PIN);  // Z軸を読込む
  }

  c.cx = x / 100;
  c.cy = y / 100;
  c.cz = z / 100;
  return c;
}

/**
 * センサの値から各座標の角度を計算する関数
 */
Angle angleCalculation(Coordinate c){
  // 以下のx,y,zの最大値最小値は各自で測定してください
  int MAX_X = 524, MAX_Y = 514, MAX_Z = 526;
  int MIN_X = 222, MIN_Y = 214, MIN_Z = 227;

  // 各座標の1度あたりの角度を計算
  float oneAngleX = (MAX_X - MIN_X) / 180.000;
  float oneAngleY = (MAX_Y - MIN_Y) / 180.000;
  float oneAngleZ = (MAX_Z - MIN_Z) / 180.000;

  // 各座標の角度を計算
  Angle a;
  a.ax = (c.cx - MIN_X) / oneAngleX - 90;
  a.ay = (c.cy - MIN_Y) / oneAngleY - 90;
  a.az = (c.cz - MIN_Z) / oneAngleZ - 90;
  return a;
}

/**
 * 角度を表示する関数
 */
void showAngle(Angle a) {
  Serial.print(a.ax);
  Serial.print(",");
  Serial.print(a.ay);
  Serial.print(",");
  Serial.println(a.az);
}

/**
 * 加速度センサーの値を表示する関数
 */
void showCoordinate(Coordinate c) {
  Serial.print("x:");
  Serial.print(c.cx);
  Serial.print(" y:");
  Serial.print(c.cy);
  Serial.print(" z:");
  Serial.println(c.cz);
}

 Aduino IDEのシリアルモニタを立ち上げて「115200bps」を選択するとコンマ区切りでx,y,zの角度が表示されます。

 角度を計算する関数「angleCalculation」での各座標の最大値、最小値が環境によってブレがあるので、loop関数内でコメントアウトしてあるところを有効にし、加速度センサを傾けて各自で計測して書き換えてください。


3:Unity側のシリアル読み込み準備
rikoubou.hatenablog.com
 前回の記事の3、4の手順でSerialHandlerのスクリプトをアタッチさせたGame Objectまで作成します。


4:TextとCubeを追加する
 Hierarchyで右クリックをし、UI→Textを選択してTextを追加します。
f:id:rikoubou:20180208172027p:plain

 位置やフォントサイズなどを適宜調節して画面上で見えるようにします。
 自分は以下のように設定しました。
f:id:rikoubou:20180208172308p:plain

 続いてHierarchyで右クリックをし、3D Object→Cubeを選択してCubeを追加します。
f:id:rikoubou:20180208172349p:plain

 このCubeの位置や大きさなども適宜調節します。
 自分は以下のように設定しました。
f:id:rikoubou:20180208172634p:plain


5:加速度の値を反映させるための空のGameObjectを作成する
 Hierarchyで右クリックをし、Create Emptyを選択してからのGameObjectを追加し、名前を「SerialCube」に変更します。
f:id:rikoubou:20180208172759p:plain

 次にScriptフォルダを右クリックし、Create→C# Scriptを選択して「SerialCube」という名前でスクリプトファイルを作成します。

 SerialCubeを開いて以下のソースコードを記述します。

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;

public class SerialCube : MonoBehaviour {

	public SerialHandler serialHandler;
	public Text text;
	public GameObject cube;

	// Use this for initialization
	void Start () {
		//信号を受信したときに、そのメッセージの処理を行う
		serialHandler.OnDataReceived += OnDataReceived;
	}

	// Update is called once per frame
	void Update () {

	}

	/*
	 * シリアルを受け取った時の処理
	 */
	void OnDataReceived(string message) {
		try {
			string[] angles = message.Split(',');
			text.text = "x:" + angles[0] + "\n" + "y:" + angles[1] + "\n" + "z:" + angles[2] + "\n"; // シリアルの値をテキストに表示

			// Vectorは前から順番にx,y,zだけど、そのままセットすると
			// Unity上の回転の見た目が変になるので、y,zの値を入れ替えている。
			Vector3 angle = new Vector3(float.Parse(angles[0]), float.Parse(angles[2]), float.Parse(angles[1]));
			cube.transform.rotation = Quaternion.Euler(angle);
		} catch (System.Exception e) {
			Debug.LogWarning(e.Message);
		}
	}
}

 SerialCubeの記述が完了したら、SerialCubeのソースをHierarchyの「SerialCube」にドラッグ&ドロップして追加します。
f:id:rikoubou:20180208173409p:plain

 追加したらHierarchyの「SerialCube」を選択し、InspectorにあるSerialHander、Text、CubeにそれぞれのGameObjectを設定します。
f:id:rikoubou:20180208173503p:plain


6:Unityで実行する
 ArduinoとPCをUSBケーブルで接続した状態で作成したUnityのプロジェクトを実行します。
 加速度センサを傾けると以下のようにUnity上のCubeも傾きます。


 以上がUnityと加速度センサを連携してみた結果です。
 現実の傾きと画面上の傾きが連動するというただそれだけですが、実際にやってみるとなかなか楽しかったです。


・参考資料

【Blender/Sculptris】Sculptrisで作成したモデルとテクスチャをBlenderに取り込む

rikoubou.hatenablog.com

 前回の記事でSculptrisでモデルを作成してモデル本体の「.objファイル」とテクスチャの「.pngファイル」を作成しました。

 今回はそれらのファイルをBlenderに取り込むまでをやっていこうと思います。


1:Blenderをインストールする
www.blender.org

 上記Blenderの公式ページからOSに合ったBlenderをダウンロードしてインストールします。(※自分はMacOSBlender 2.79の環境でやっています)


2:Blenderを立ち上げて.objファイルをインポートする

 Blenderをインストールして起動させると以下のような画面になります。
f:id:rikoubou:20180129133635p:plain

 左上にある「File」→「import」→「Wavefront(.obj)」をクリックし、読み込ませたい.objファイルを選択してインポートします。
f:id:rikoubou:20180129133825p:plain

 するとキューブに埋没してますが、.objファイルが読み込まれて画面に表示されます。
f:id:rikoubou:20180129134200p:plain

 キューブが邪魔なので右側にあるアウトライナーの「Cubeを右クリックしてDelete」もしくは「Cubeの横にある目のアイコンをクリックして非表示」にします。(以下の画像ではCube自体をDeleteで削除しています)
f:id:rikoubou:20180129134516p:plain

 これでキューブが消えて読み込んだモデルのみになります。
f:id:rikoubou:20180129134711p:plain


3:Blenderにテクスチャファイルを読み込ませる

 モデルの読み込みができたので、今度は作成したテクスチャファイルを読み込ませます。

 右側にあるアウトライナーのモデルを選択、テクスチャのアイコンをクリックして「Newボタン」をクリックします。
f:id:rikoubou:20180129135624p:plain

 するとTextureが追加されます。追加されたTextureの「Openボタン」をクリックして、読み込ませたいテクスチャファイル(.png)を開きます。
f:id:rikoubou:20180129140037p:plain

 読み込ませるとPreviewのところにテクスチャが表示されます。
f:id:rikoubou:20180129140230p:plain

 ただこれだけではモデルに反映されないので、次の手順でモデルにテクスチャを適用させます。


4:Blenderのモデルにテクスチャファイルを適用させる

 3の手順まで終わったら、Defaultと表示されている右側のアイコンをクリックして「UV Editing」を選択します。
f:id:rikoubou:20180129140538p:plain

 すると以下のようなUV(テクスチャ)編集画面になります。
f:id:rikoubou:20180129140749p:plain

 右下にある「Object Mode」を「Edit Mode」に切り替えます。
f:id:rikoubou:20180129140943p:plain

 Edit Modeに切り替えたら、その横にある「Mesh」→「UV Unwrap」→「Unwrap」を選択します。
f:id:rikoubou:20180129141408p:plain

 次に左画面の下にある「Open」をクリックして再び同じテクスチャファイル(.png)を開きます。
f:id:rikoubou:20180129141650p:plain

 ここまでできたら「Default」画面に切り替えます。
f:id:rikoubou:20180129141805p:plain

 Default画面に切り替わると、こんな感じになっているはずです。
f:id:rikoubou:20180129142016p:plain

 モデルが表示されている画面の下にある「Edit Mode」を「Object Mode」に切り替えます。
f:id:rikoubou:20180129142111p:plain

 「Object Mode」と表示されている右横のシェーダーをクリックし「Material」を選択します。
f:id:rikoubou:20180129142414p:plain

 これでようやくモデルにテクスチャが適用されて色がつきます。やったー!
f:id:rikoubou:20180129142601p:plain


 以上がSculptrisで作成したモデルとテクスチャをBlenderに取り込んだ流れです。

 テクスチャの取り込み部分が手順が多いですが、これでBlenderへの取り込みができるようになりました。

 別のソフトで作成したファイルでも拡張子が対応していれば同じ手順で取り込みが可能だと思います(未検証)。


 次の記事では取り込んだこのモデルをアニメーションさせるところまでやりたいと思っています。


・参考資料

【Sculptris】Sculptrisで3Dモデリングやってみた

 こんにちは、割と早いスパンでの更新です。

 昨今バーチャルYoutuberというのが流行ってますね。自分も最近彼ら彼女らの動画を見ていて「3Dやってみるか」と思い立ちました。

 何もわからないままとりあえずググってみたところ、Sculptrisという無料のモデリングツールを紹介しているページを見つけ、それに従ってなんとかモデルを作成するところまでできました。

 今回は全く3Dをやったことがない素人の自分がモデリングをやってみたその備忘録です。


1:Sculptrisをインストールする
pixologic.com
 上記がSculptrisの公式ページです。「Free Download」ボタンをクリックしてOSを選択した後、いくつかの情報を入力するとダウンロードが開始されます。
 ダウンロード後はインストーラーに従ってインストールすればOKです。


2:Sculptrisでモデルを作成する
yamakatu.blog.so-net.ne.jp
 こちらのブログ様の「モデリングソフト Sculptris 使い方 1〜7」に従って操作をしていけばモデルを作成することができます。

 ちなみに2時間程度で作成した自分の人生初モデルはこちらです。
f:id:rikoubou:20180120215248p:plain

 適当にペイントまでしたのがこちら。
f:id:rikoubou:20180120215312p:plain


3:Sculptrisで作成したモデルデータを保存する
yamakatu.blog.so-net.ne.jp
 こちらの「他のソフトで引き続きモデリングする時は」の記事に従って.objファイルとして保存します。この.objファイルは「物体の情報のみで色情報は含まれていない」ので注意が必要です。
 色の情報はPAINTモードで「show advanced tools」をオンにして「SAVE TEXMAP」をクリックすることで色データの.pngファイルを保存します。

 これら.obj、.pngのファイルを別のソフトに読み込ませることで、作成したモデルを動かしたりすることができるようになります。


 以上が人生初の3Dモデリングの備忘録です。調べれば素人の自分でも簡単に3Dモデリングができる今の時代は素晴らしいと感じました。非常にわかりやすい操作説明をまとめていただいた引用元のブログ様に感謝です。

 次はこのモデルをBlenderに読み込ませて簡単なアニメーションをさせるところまでやりたいと思っています。


・参考資料


・次の記事
rikoubou.hatenablog.com

【Unity/Arduino】UnityとArduinoを連携してみた

 明けましておめでとうござます。ブログのネタがないまま放置していたら気づいたら年が明けていました。

 久々の記事ですがタイトルにある通りUnityとArduinoを連携させてみました。

 具体的にはArduinoで取得した照度センサーの値をシリアルでUSBから送り、Unityの画面上に表示させるというものです。

 では説明していきます。


1:材料/開発環境
■開発環境

■素材


2:Arduino側の準備
 以下のようにArduino側の回路を組みます。
f:id:rikoubou:20180116164959p:plain

 Arduino Unoに以下のスケッチを書き込みます。

void setup() {
  Serial.begin(115200);
}
 
void loop() {
  int v = analogRead(0);
  Serial.println(v);
  delay(1000);
}

 Aduino IDEのシリアルモニタを立ち上げて「115200bps」を選択すると
1秒ごとに照度センサーの値が表示されます。

 照度センサーのところを指で押し付けたり離したりすると値が変化します。


3:Unityで新しいプロジェクトを作成&ビルド設定
 Arduino側の準備ができたら次にUnityを立ち上げて新しいプロジェクトを作成します。

 新しいプロジェクトを作成したらFile→Build Settingsをクリックします。
f:id:rikoubou:20180116170258p:plain

 立ち上がった画面の下にあるPlayer Settingsボタンをクリックして
出てきたInspectorのOther Settingsにある「Api Compatibility Level」を
「.NET 2.0」に変更します。
f:id:rikoubou:20180116170525p:plain


4:空のGameObjectを作成しSerialHandlerスクリプトをアタッチする
 Hierarchyを右クリックし「Create Empty」を選択して空のGameObjectを追加します。
 その空のGameObjectの名前を「SerialHandler」に変更します。

 次にAssetsを右クリックし、Create→FolderでScriptフォルダを作成します。

 そのフォルダの中に入って再び右クリックし、Create→C#Scriptを選択して
「SerialHandler」の名前でスクリプトファイルを作成します。

 作成されたスクリプトファイルをダブルクリックして以下のようにソースを記述します。(ポート名のところは適宜変更してください)

using UnityEngine;
using System.Collections;
using System.IO.Ports;
using System.Threading;

public class SerialHandler : MonoBehaviour
{
	public delegate void SerialDataReceivedEventHandler(string message);
	public event SerialDataReceivedEventHandler OnDataReceived;

	public string portName = "/dev/tty.usbmodem1421"; // ポート名(Macだと/dev/tty.usbmodem1421など)
	public int baudRate    = 115200;  // ボーレート(Arduinoに記述したものに合わせる)

	private SerialPort serialPort_;
	private Thread thread_;
	private bool isRunning_ = false;

	private string message_;
	private bool isNewMessageReceived_ = false;

	void Awake()
	{
		Open();
	}

	void Update()
	{
		if (isNewMessageReceived_) {
			OnDataReceived(message_);
		}
		isNewMessageReceived_ = false;
	}

	void OnDestroy()
	{
		Close();
	}

	private void Open()
	{
		serialPort_ = new SerialPort(portName, baudRate, Parity.None, 8, StopBits.One);
		//または
		//serialPort_ = new SerialPort(portName, baudRate);
		serialPort_.Open();

		isRunning_ = true;

		thread_ = new Thread(Read);
		thread_.Start();
	}

	private void Close()
	{
		isNewMessageReceived_ = false;
		isRunning_ = false;

		if (thread_ != null && thread_.IsAlive) {
			thread_.Join();
		}

		if (serialPort_ != null && serialPort_.IsOpen) {
			serialPort_.Close();
			serialPort_.Dispose();
		}
	}

	private void Read()
	{
		while (isRunning_ && serialPort_ != null && serialPort_.IsOpen) {
			try {
				message_ = serialPort_.ReadLine();
				isNewMessageReceived_ = true;
			} catch (System.Exception e) {
				Debug.LogWarning(e.Message);
			}
		}
	}

	public void Write(string message)
	{
		try {
			serialPort_.Write(message);
		} catch (System.Exception e) {
			Debug.LogWarning(e.Message);
		}
	}
}

 ソースの記述が終了したらSerialHandlerのスクリプトファイルを
SerialHandlerのオブジェクトにドラッグ&ドロップしてアタッチします。
f:id:rikoubou:20180116171948p:plain


5:Textを作成しSerialLightスクリプトをアタッチする
 Hierarchyを右クリックしUI→Textを選択してTextを追加します。
 追加したTextをクリックしInspectorのFontSizeや座標位置、表示範囲などを調整します。

 自分の設定値はこんな感じにしました。
f:id:rikoubou:20180116172840p:plain

 次にAssetsのScriptフォルダを右クリックし、Create→C#Scriptを選択して
「SerialLight」の名前でスクリプトファイルを作成します。
 作成されたスクリプトファイルをダブルクリックして以下のようにソースを記述します。

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;

public class SerialLight : MonoBehaviour {

	public SerialHandler serialHandler;
	public Text text;

	// Use this for initialization
	void Start () {
		//信号を受信したときに、そのメッセージの処理を行う
		serialHandler.OnDataReceived += OnDataReceived;
	}
	
	// Update is called once per frame
	void Update () {
		
	}

	/*
	 * シリアルを受け取った時の処理
	 */
	void OnDataReceived(string message) {
		try {
			text.text = message; // シリアルの値をテキストに表示
		} catch (System.Exception e) {
			Debug.LogWarning(e.Message);
		}
	}
}

 ソースの記述が終了したらSerialLightのスクリプトファイルを
Textのオブジェクトにドラッグ&ドロップしてアタッチします。
f:id:rikoubou:20180116173335p:plain

 次にアタッチしたTextオブジェクトをクリックしてInspectorを表示させます。
 SerialHandlerとTextのところの右にある○をクリックして
それぞれオブジェクトを対応させます。
f:id:rikoubou:20180116173700p:plain
f:id:rikoubou:20180116173708p:plain


6:Unityで実行する
 ArduinoとPCをUSBケーブルで接続した状態で作成したUnityのプロジェクトを実行します。
 すると以下のようにTextオブジェクト部分に照度センサーの値が表示されるようになります。
f:id:rikoubou:20180116174040p:plain

 センサー部分を指で押し付けたり離したりすると値が変動するのがわかると思います。


 以上がArduinoとUnityを連携してみた内容です。
 シリアルの値をUnity上で取得して反映できることがわかったので、色々なことに使えそうですね。


・追記
 以下の記事で今度は加速度センサと連携させてみました。
rikoubou.hatenablog.com


・参考資料

【mbed】mbedでLチカをやってみた

www.switch-science.com

 スイッチサイエンスなどで売られているmbedを手に入れたので、とりあえずボードに載っているLEDをLチカさせてみました。その時の備忘録です。

mbedを始めましょう!("Let's get started!" in Japanese)

 基本的には上記ページにある通りにやっていけばOKです。大まかな手順としては次のようになります。

  1. mbedのアカウントを作成する
  2. ソースコードを検索する
  3. コードをコンパイルしてダウンロードする
  4. mbedにダウンロードしたファイルをコピーし、実行する

 ではそれぞれの解説です。


1:mbedのアカウントを作成する
 最初にmbedとPCをUSBケーブルで繋ぎます。するとUSBメモリとして認識されるので、その中にある「MBED.HTM」をダブルクリックして開きます。
f:id:rikoubou:20171030131506p:plain

 するとmbedのログインページが開かれるので、右側にある「Sign up」をクリックしてアカウントを作成します。アカウント作成はmbedを始めましょう!のページを参考にしてください。
mbedを始めましょう!("Let's get started!" in Japanese)


2:ソースコードを検索する
 アカウントが作成が終了した先のページの上部にある「Code」をクリックします。
f:id:rikoubou:20171030132121p:plain

 検索欄に「HelloWorld」と入力して検索し、一番上に出てきたソースコードをクリックします。
f:id:rikoubou:20171030132701p:plain

 表示されたページの右側にある「Import into Compiler」をクリックします。
f:id:rikoubou:20171030132909p:plain

 色々尋ねられますが、何も変更せずimportボタンをクリックします。これでソースコードのインポートは完了です。
f:id:rikoubou:20171030133035p:plain


3:コードをコンパイルしてダウンロードする
 今回importしたソースコードはmbedの表面に実装されているLEDをチカチカさせるものです。importした中にある「main.cpp」ファイルがその中身になります。
 mbedに書き込むためには画面上部にある「コンパイル」をクリックします。
f:id:rikoubou:20171030133259p:plain

 コンパイルに成功すると「○○.bin」というファイルがダウンロードされます。


4:mbedにダウンロードしたファイルをコピーし、実行する
 3でダウンロードしたbinファイルをmbedの「MBED.HTM」があるところにコピーします。
 コピーが完了した後、mbedの真ん中あたりにあるリセットボタンを押すと、binファイルが実行されます。
(ここではLチカのソースコードを書き込んでいるのでLEDが点滅します)


 以上がmbedでのLチカまでの方法です。PCがネットに繋がってさえいれば開発環境をインストールする必要がないので、手軽に電子工作を始められる感じはあります。
 ただArduinoなどに比べると値段が5000円以上とちょっと高いので悩みどころという印象です。

 しかし、環境構築をしなくてよい上にソースコードを検索してすぐに試すことができるのは非常に強力だと思うので、mbedもこれから触っていきたいと思います。