Category Archives: ForeceFeedback

フライトシムからデータを取出しアクチュエータを動かす。

フライトシミュレータでいつか実現したいものに、フォースフィードバックとモーションシミュレータがあります。
OpenStickのフォースフィードバック対応については私の技術力と英語力では苦戦している事を何度か書きました。
一方、モーションシミュレータはというと敷居が高そうで今まであまり検討しませんでした。置き場所も問題ですし。

でも今回急にやりたくなったんですよね。いきなり人間が乗れるものを作るのは大変なので、まずはシミュレータからデータを取出してラジコンサーボを動かしてみるというところから始めました。

使用するシミュレータはマイクロソフトのFlightSimulatorXです。ここからデータを取出すには、世の中ではFSUIPCという追加ソフトで取出すパターンが多い様です。これはこれで気になりますが、まずは今あるものを使ってみてから考えるという事で今回はFlightSimulatorXに標準で入っているSimConnectを使用してみます。(たぶんFSUIPCも内部でSimConnectを使っているのだと思います)。

SimConnect

SimConnectはFlightSimulatorXに標準で付いているSDK(ソフトウェア開発キット)の一部で、シミュレータ内の各種数値を読み書きする事で計器やコントローラ等を制御できるツールです。FlightSimulatorXのDVDにSDKのインストーラが含まれており、これをインストールしました(もしかするとFSXと共にインストール済なのに上書きインストールをしたのかもしれませんが今となっては判りません)。このSDKの中にはSimConnect以外にも色々な機能が含まれており、これらもいつか試してみたいと思います。
で、SimConnect の実体はSimConnect.hとSimConnect.libで、VisualStudioC++からインポート&リンクして使用します。

VisualStudio

ウチのPCにはVisualStudio2010 ExpressEdition(要はお金のかからないヤツね)がインストール済なのでこれを使います。SDKのマニュアルによるとVisualStuio2005以降に対応しているとの事なので大丈夫でしょう。

サンプルソース

SDKには多数のサンプルが付いています。この中の’Request Data’というサンプルを元にして必要な情報が取れる様に修正していきます。

プロジェクト作成/コンパイル

まずVisualStudioでWin32コンソールアプリケーションとしてプロジェクトを作成します。そしてSDKの説明に従いヘッダとライブラリを指定します。そしてコンパイルするとプリコンパイル済ヘッダのエラーが出たので安直にプリコンパイル済ヘッダを使用しない設定に変えてしまいました。これでとりあえずはコンパイルも通ってプログラムを実行できる様になりました。
→実験プログラム(VisualC++のプロジェクトツリー一式です。色々関係ないデータも取出していますが結局ロール、ピッチ、方位しか使っていません)

データ取得

‘Request Data’はシミュレータと通信し、高度、緯度、経度を取出してDOS窓に表示するサンプルプログラムです。これを変更して機体のピッチ、ロール、方位を取出し、カンマ区切りで出力します。これらの値は浮動小数点型で単位はラジアンですが、このままArduinoに送っても扱い辛いので単位を度数に変換し、更に数値を10倍して少数以下を切り捨てました。これによりArduino側では整数で扱えます。
また’Request Data’サンプルは一回データを出力したら終りでしたが、これを定期的に出力する様に変更しました。

データをArduinoに転送

これまた安直にDOS窓状で’コマンド名>COM3:’ を実行し、リダイレクトにより仮想シリアルポートに送ります。最終的にはもうちょっとマトモなやり方に変えたいと思いますが、まずは実験です。

Arduinoでの処理

カンマ区切りを分解してロールとピッチのデータを得ます(今回2軸なので方位データは捨てています)。 そして各値をサーボ用の値に変換してサーボライブラリに送ります。
→実験プログラム

サーボ

サーボは随分前にロボットを製作した時の残りのGWSのMicro2BBMGを使用しました。これはかなりトルクがあるサーボなので今回の用途にはちょっと無駄です。実は4グラムサーボも手持ちがありますが、こちらはラジコン飛行機に乗せたいので取っておきます。

リンケージ

サーボから釣り糸をリンケージに使って棒の上の円盤を傾けます。棒と円盤とは熱収縮チューブで接続しているので自由に傾ける事ができます。円盤の上には模型のセスナ172(ThingiVerseからダウンロードしてプリントしました)を乗せています。

Fusion360でレンダリングしてみました。

PlaneDisplay1

Fusion360で描いてみます。

そして実体化。動画です。

この後・・・

今回は機体の傾きをそのままサーボの角度で表していますがモーションシミュレータとなると体にかかる加速度(重力も含めて)を再現しなければなりません。SimConnectで取り出せる変数には加速度データもあるのですが、表示させると何だか思ったものと違う様です。もしかすると速度を微分して計算するしかないのかもしれません。また本当に人が乗れるヤツを作ろうと思ったらアクチュエータをどうするか、また置き場所をどうするかという大問題もあります。

・・・という事で、これまたぼちぼちやります(多分途中でくじけます)。


OpenStickでフォースフィードバックができないか

前々からOpenStickでフォースフィードバックができないかと考えており調べています。
フォースフィードバックが出来るとフライトヨークにグイグイ力を加えたり、ヨットシミュレータで風の強さを手元に感じたりと夢が広がります。

が・・・
単純に入力だけのジョイスティックと比べて格段に難しいです。情報も少ないし、
このあたりを読んでも解らない事だらけです(しかも英語なんです)。

まず、普通のHIDデバイスはUSBのクラスIDは3番ですが、フォースフィードバック(PIDデバイス)の場合はどうなのでしょう?5番という記述も見るのですが、HIDと違う番号でPC側は問題ないのでしょうか?・・・といったところからして解りません。

そもそもウチにあるフォースフィードバックデバイスといえば「SideWinder Force Feedbak Pro」という古いジョイスティックがあるのですが、これはゲームポート&MIDIポートに接続する仕様の為、参考になりません(どこに仕舞ったかわからず写真も取れません)。

そこで何かフォースフィードバックのUSBデバイスが欲しいと思い、これを買ってきました。

BUFFALO BSGP1204

BUFFALO BSGP1204 ¥1980-

とりあえずPC(Windows7)に挿してみます。しかし暫く待っても認識されませんでした。ジョイスティックはドライバなぞ要らないもんだと思っていましたが、これは駄目なようです。そこで付属のCDからドライバを入れました(ドライバを入れた後も認識に暫くかかっていたので、もしかするとそのまま待っていれば認識したのかもしれません)。
OpenStickでフォースフィードバックデバイスを実現できたとして、PC側に何らかのドライバを書く必要があるのでしょうか?

コントロールパネルの「デバイスとプリンター」からデバイスの設定画面を出してみると下の様な派手なのが出ました。

BSGP1204Setting

セッティング画面

「バイブレーション」タブを押すと次の様な画面に変わります。

BSGP1204Setting2

バイブレーション設定画面

ここで「左側が振動」とか「右側が振動」とかをクリックするとゲームパッドがぶるぶると震えるので動作はしている様です。

次にこのデバイスのディスクリプタ類を見てみます。以前やったのと同様にLinuxマシンに挿して・・・

まずlsusbコマンドでベンダID,プロダクトIDを見ます。

$ lsusb
     : 
     : 
Bus 001 Device 005: ID 1dd8:000f

IDは「1dd8:000f」の様です。次に-v,-dオプションをつけてディスクリプタを見ます。
-vは詳細情報出力の意味、-dは指定デバイスのみ表示するオプションです。

$ lsusb -v -d 1dd8:000f

Bus 001 Device 005: ID 1dd8:000f
Device Descriptor:
  bLength                18
  bDescriptorType         1
  bcdUSB               1.10
  bDeviceClass            0 (Defined at Interface level)
  bDeviceSubClass         0
  bDeviceProtocol         0
  bMaxPacketSize0         8
  idVendor           0x1dd8
  idProduct          0x000f
  bcdDevice            1.00
  iManufacturer           0
  iProduct                2
  iSerial                 0
  bNumConfigurations      1
  Configuration Descriptor:
    bLength                 9
    bDescriptorType         2
    wTotalLength           34
    bNumInterfaces          1
    bConfigurationValue     1
    iConfiguration          0
    bmAttributes         0x80
      (Bus Powered)
    MaxPower              300mA
    Interface Descriptor:
      bLength                 9
      bDescriptorType         4
      bInterfaceNumber        0
      bAlternateSetting       0
      bNumEndpoints           1
      bInterfaceClass         3 Human Interface Device
      bInterfaceSubClass      0 No Subclass
      bInterfaceProtocol      0 None
      iInterface              0
        HID Device Descriptor:
          bLength                 9
          bDescriptorType        33
          bcdHID               1.10
          bCountryCode            0 Not supported
          bNumDescriptors         1
          bDescriptorType        34 Report
          wDescriptorLength      94
         Report Descriptors:
           ** UNAVAILABLE **
      Endpoint Descriptor:
        bLength                 7
        bDescriptorType         5
        bEndpointAddress     0x81  EP 1 IN
        bmAttributes            3
          Transfer Type            Interrupt
          Synch Type               None
          Usage Type               Data
        wMaxPacketSize     0x0008  1x 8 bytes
        bInterval              10
cannot read device status, Operation not permitted (1)

見たかったのはInterface Descriptor:内のbInterfaceClassです。
これは上に書いたクラスIDを示すものですが5番ではなく、やはり3番になっている様です。
また、良くわからないのはEndpointが入力用の1つだけである事です。想像では出力用にもう一つEndpointがあるものと思っていました。

余計にわからなくなってきました。
一旦これは置いときます。

いづれにせよPCからフォースフィードバック機器がどの様に見えるのかを知っておく必要があると思い、まずは振動を送るプログラムを書いてみようしてこちらもハマっています。

道は遠そうなのでぼちぼちやります。
どなたか詳しい方にアドバイスを頂けるとうれしいのですが・・。