読者です 読者をやめる 読者になる 読者になる

【Arduino】重心コントローラの作成レポート

Programming Arduino

ふとしたことからVRでセグウェイ乗りたいなという気持ちが沸きあがってきたので、作ってみる事にしました。

構成

f:id:VirtualNoodle:20160924220904p:plain

こんな感じのふわっとしたものを想定。
僕の環境ではOculusRift、Unity、自作の重心コントローラ(後述)によって実現する。
人間は僕です。

結果

といってもブログみたいなメディアで示すことは難しい。

f:id:VirtualNoodle:20160924221539p:plain

とりあえずこういうシーンを作って、それで重心移動によってこの世界の中をどうにかこうにか移動する事ができた。

作成手法、内容


・材料
Arduino、または互換機
今回は細かいスペースに回路を仕込みたいという気持ちがあったのでProMicroを使用。
別に普通のArduino UNO諸々でも多分できる(試してないけど)
eBayで5枚購入した。1枚当たりお値段4ドルぐらい。
SwitchScienceさん2500円とか高すぎますわ・・・

Hx711 ADC
なんか微弱な電圧をアンプしてデジタル変換してくれるやつ。
AmazonDIP基板のヤツを購入した。
これも価格がバラバラでSwitchScienceだと1200円ぐらいするし、Amazonでも同等のものが700円ぐらいしていたが、僕が購入した奴は163円なり。
まとめ売りでもしてんのか?って価格差だが、ちろっと見た限りではそうでもない。
中間搾取の恐ろしさを垣間見た気がする。
回路で使うのは二枚。

デジタル体重計
四か所に歪みゲージが付いているようなタイプのものが良い。
体重を計る以外の、例えば体脂肪率なんかを計るような機能は要らない。
歪みゲージ付きの金属が四つついて、かつナイスな位置に配置されている。
お値段も歪みゲージ金属四個セットを買うより安い(Amazonでしか比較していないが)

回路

重量計りADCモジュール - aitendo

大体ここの回路と、Hx711のデータシートを参考にする。
セグウェイみたいな動作を実現するには前後の重心情報があればよいので、前二つ、後ろ二つの歪みゲージをそれぞれ対辺2ゲージ法で接続。
割と固定抵抗は適当でもいいらしく、もしズレていたとしてもパラメータ2つならプログラム側で調整すればよいと心算していた。

また、Hx711のRATEはにはHIGHを入力して80Hzにしてある。
DIP基板の種類によってはGNDから足を上げて隣のVCCにひん曲げて繋げるとかいう職人芸が必要なので注意。
10Hzだと流石に遅い。

具体的な写真は下。
f:id:VirtualNoodle:20160924225148j:plain

この写真を見ても何もわからないが、左右にあるのが歪みゲージで、後の回路は大体上のリンクのものと同じ。
ブリッジ回路の式から計算も一応はしたが、アナログ回路なのであまり信用できない。
大体プログラム側で調整できるだろうと思っているので適当。

ソースコード

leoJoyとHx711のライブラリを使っているので、このままコピペしても普通は動かない。
leoJoyに関しては昔に調べて、色々と設定ファイルを弄っていたが、忘れてしまった。
Hx711のライブラリは以下のものを使用。無改造。

ライブラリ内でHx711との通信待ちが発生しており、Hx711を二つ使う場合は待ち時間にロスが生まれてしまう(気がする)のだが、適当にやってみたところ案外使えた。
改善の余地は多分あるので覚えておく。

ちなみにコードはテスト上とりあえず動かすことを目的としている程度には超適当で、改善の余地はありまくり。

GitHub - bogde/HX711: An Arduino library to interface the Avia Semiconductor HX711 24-Bit Analog-to-Digital Converter (ADC) for Weight Scales.

#include "HX711.h"
HX711 front;
HX711 back;

JoyState_t joySt;

void setup() {
  Serial.begin(38400);
  front.begin(16,14);//first dout second sck  dout is DigIn sck is DigOut
  back.begin(15,A0);

  front.set_offset(front.read_average(32));
  back.set_offset(back.read_average(32));

  front.set_scale(2280.f);                      // this value is obtained by calibrating the scale with known weights; see the README for details
  front.tare();    
  back.set_scale(2280.f);                      // this value is obtained by calibrating the scale with known weights; see the README for details
  back.tare();    
  
  joySt.xAxis = 127;
  joySt.yAxis = 127;
  joySt.zAxis = 127;
  joySt.xRotAxis = 127;
  joySt.yRotAxis = 127;
  joySt.zRotAxis = 127;
  joySt.throttle = 0;
  joySt.rudder = 0;
  joySt.hatSw1 = 0;
  joySt.hatSw2 = 0;
  joySt.buttons = 0;
}

void loop() {
  // put your main code here, to run repeatedly:
  long frontData = (front.read_average(5) ) / front.get_scale() - front.get_offset() / front.get_scale();
  long backData = (back.read_average(5) ) / back.get_scale() - back.get_offset() / back.get_scale();
  double balance = 127.0;
  if(frontData + backData != 0){
    balance = (double)backData / (double)(frontData + backData) * 255.0;
  }

  if(balance > 255.0)
    balance = 255.0;
  else if (balance < 0)
    balance = 0.0;
  
  Serial.println("====data====");
  Serial.print("front : "); Serial.println(frontData);
  Serial.print("back  : "); Serial.println(backData);
  Serial.print("balance : "); Serial.println(balance);//てきとう

  joySt.yAxis = balance;

  front.power_down();
  back.power_down();
  delay(100);
  front.power_up();
  back.power_up();

  Joystick.setState(&joySt);
}
問題点

・動作が不安定
→たまにゲージに反応しなくなる。
QIで圧着したが、もともとの線が細く、電気的に途切れてしまっている可能性が高い。
ちゃんと半田流し込むぐらいはした方がよい。

考察

重心コントローラと言えば2007年にWiiFit、およびバランスWiiボードが発売され、何かと研究にも使われたりするぐらい精度がよろしいらしい。あんまり詳しく知らないけど。
WiiFitをVR内での移動デバイスとして利用しようという試みはもう何年も前からあるし、UnityだとMac向けのアセットが存在するぐらいだ。
Windowsでの利用方法もググれば何件か良さそうなのが出てくるし、正直下位互換である今回の製作物を作る価値というのはあまり無いように見える。

それでもまぁ、利用したこともないバランスボードに対して幾つか自作する事のメリットを挙げておきたい。

・安い
詭弁である。
自作重心計の経費は4000円未満に抑えてあるが、バランスボードをもっと安価に手に入れる手法はいくらでもある。

・軽い
体重計とバランスWiiボードを比較すると、勿論体重計の方が軽い。
これは誇るべきメリットである。

・拡張ができる
バランスWiiボードは完成された製品であり、精度が高い。
が、完成された製品であるが故に、重心を計る事しかできないのである。
これは自作の強みであり、ソフトウェアもハードウェアもかなり自由にできる。
例えばバランスWiiボードは振動しないが、自作重心計に振動モータを仕込むことで振動させたりもできるのだ。
他にもボリュームとか傾きとか色々センサを付けることもできる。
これがメリットに思えるかどうかは作るコンテンツ次第なのだが。

・ペアリングの必要が無い
Bluetoothバイスであるが故の欠点。
ペアリングが切れる度に接続のやり直しをしないといけないのは結構なストレスだと思う。
その点Arduinoを使っているのだからこちらは有線だ。電源だってUSBから供給できる。

とまぁ、こんなものだろうか。自作する価値を認めてもらえるかどうかは微妙だが。

デメリットも挙げておこう。
・デザインが体重計依存
スタイリッシュな体重計なんていうものはあまりない。
大してバランスWiiボードのなんとカッコいい事か。本当に9年前のデザイン?

・自作する必要がある
これをデメリットに入れてしまうのは全否定に他ならないのだが、自作と言うのは自己責任で手間がかかるもの。
電子工作は見た目よりは簡単、なんて言われることがままあるとはいえ、初期投資も要るし中々ハードルが高いのである。

・1軸しかない。
やろうと思えば2軸にできる。できるのだが、非常に回路がめんどくさくなるし、ADCが4枚に増える。
めんどくさい。


結論

もし同じことをしようとしている人がいるなら、電子工作が好きだ!ってのでない限りは僕はバランスWiiボードの利用を推しておきます。