仮想ジョイスティックビューが動かないことがある

仮想ジョイスティックビューが動かないことがある

Tankチュートリアルを進めていたところ、ステップ3: ゲームパッドによる砲塔の制御において、仮想ジョイスティックビューが動かない(ビュー内のボタンを押してもTankの砲塔が動かない)という現象に遭遇しました。

環境

  • OS: Ubuntu 16.04 LTS
  • Choreonoid: バージョン1.7(開発版)
    • 2018年5月23日にgit clone https://github.com/s-nakaoka/choreonoid.gitで取得
    • ソースディレクトリは~/choreonoid
    • ビルドディレクトリは~/choreonoid/build
    • Tankチュートリアル用のプロジェクトファイル(*.cnoidファイル)の場所は~/choreonoid/ext/tank

詳細

バグを疑う前に、以下の事項を確認しました。

  • コントローラ(TurretController2)のコードはチュートリアルを見ながら自分で書いたので、書き間違いがないか確認しましたが、問題ありませんでした。
  • マニュアルに「キーボードフォーカスが入っていないと機能しない」との注意書きがあったのでその辺も確認しましたが、ビューをマウスでクリックしてフォーカスを入れても動きませんでした。

何度か試していると、仮想ジョイスティックビューはいつも動かないわけではなく、動くときと動かないときとがあることが分かりました。

試行錯誤の末、動くときと動かないときの条件の違いは、特定の操作を行う順番の違いであることが分かりました。
以下にそれを示します。

動かないときの操作手順

  1. ビルドディレクトリに入る(端末上でcd ~/choreonoid/buildコマンドを実行)
  2. Choreonoidを立ち上げる(端末上でbin/choreonoidコマンドを実行)
  3. プロジェクトファイルを読み込む(メインメニューの[ファイル]→[プロジェクトの読み込み]を選択し、「Choreonoidプロジェクトファイルの読み込み」ダイアログでファイル名を指定して[読み込み]ボタンを押す)
  4. 仮想ジョイスティックビューを表示させる(メインメニューの[表示]→[ビューの表示]→[仮想ジョイスティック]を選択)
  5. シミュレーションを開始する(ツールバー領域のシミュレーションバーの[初期位置からのシミュレーションを開始]ボタンを押す)
  6. 仮想ジョイスティックビューを操作する
  7. 操作してもTankモデルの砲塔は動かない

動くときの操作手順

  1. ビルドディレクトリに入る
  2. Choreonoidを立ち上げる
  3. 仮想ジョイスティックビューを表示させる
  4. プロジェクトファイルを読み込む
  5. プロジェクトを読み込むと何故か仮想ジョイスティックビューが消えてしまう
  6. 再びメインメニューから仮想ジョイスティックビューを表示させる
  7. シミュレーションを開始する
  8. 仮想ジョイスティックビューを操作する
  9. 操作に従ってTankモデルの砲塔が動く

両者の違いは、仮想ジョイスティックビューを表示させる操作をプロジェクトファイルを読み込む前に行うかどうかです。
仮想ジョイスティックビューを表示させる前にプロジェクトファイルを読み込んでしまうと、仮想ジョイスティックが動かなくなるようです。

なお、ここではTankチュートリアルのステップ3を例に書きましたが、チュートリアルのステップ4以降でも同様で、「動かないときの操作手順」ではTankモデルの砲塔やクローラやライトを仮想ジョイスティックビューで操作することができません。

報告ありがとうございます。
プロジェクト読み込み後に仮想ジョイスティックビューを表示させても機能するようにできないか、調査したいと思います。

ありがとうございます。よろしくお願いいたします。

状況を詳しく書いて頂いたので、その通り操作してみたのですが、こちらでは動かない状況を再現することが出来ませんでした。

Choreonoidのサンプルには、他にもジョイスティックを使ったものがあります。例えば、SampleCrawlerJoystick.cnoidなどで、同様の操作を行い、動かない状況が再現するかを試して頂けますでしょうか。

@hattorishizuko さんの挙げてくださったSampleCrawlerJoystick.cnoidを試すのをはじめ、5つほど実験を行いました。

実験1:SampleCrawlerJoystick.cnoidを試す

まずSampleCrawlerJoystick.cnoidを試したところ、これは問題無く動きました。

ただし、私がTankチュートリアルで行き詰まった時とは条件が違いました。
私がTankチュートリアルで行き詰まった時にはプロジェクトファイルを読み込んだ後に仮想ジョイスティックビューを手動で表示させなければなりませんでしたが、SampleCrawlerJoystick.cnoidではその必要は無く、プロジェクトファイルを読み込むと同時に自動的に表示されました。

以下に操作手順を示します。

操作手順

  1. ビルドディレクトリに入る(端末上でcd ~/choreonoid/buildコマンドを実行)
  2. Choreonoidを立ち上げる(端末上でbin/choreonoidコマンドを実行)
  3. プロジェクトファイルを読み込む(メインメニューの[ファイル]→[プロジェクトの読み込み]を選択し、「Choreonoidプロジェクトファイルの読み込み」ダイアログ上で~/choreonoid/sample/SimpleControllerディレクトリに入り、ファイル名にSampleCrawlerJoystick.cnoidを指定して[読み込み]ボタンを押す)
  4. プロジェクトが読み込まれると同時に仮想ジョイスティックビューが自動的に表示される
  5. シミュレーションを開始する(ツールバー領域のシミュレーションバーの[初期位置からのシミュレーションを開始]ボタンを押す)
  6. 仮想ジョイスティックビューを操作する
  7. 操作に従ってCrawlerモデルが動く

実験2:Tankのサンプルを試す

次に、マニュアルによればChoreonoidソースのsample/tutorial/Tankディレクトリにチュートリアルのステップごとのプロジェクト内容を保存したファイルが収録されているとのことなので、これで試してみました。
こちらも問題無く動きました。

基本的には前述のSampleCrawlerJoystick.cnoidの手順と同じですが、次の2点で異なります。

  • 読み込むプロジェクトファイルは~/choreonoid/sample/tutorial/Tank/step3.cnoid
  • TurretControllerのコントローラモジュールのファイルパスが、Choreonoidの前のバージョンである1.6のものになっているので、使用中のバージョンである1.7用のパスに直す必要がある
    • 直す前のパス:~/choreonoid/build/lib/choreonoid-1.6/simplecontroller/TankTutorial_TurretController2.so
    • 直した後のパス:~/choreonoid/build/lib/choreonoid-1.7/simplecontroller/TankTutorial_TurretController2.so

操作手順を具体的に書き下すと次のようになります。

操作手順

  1. ビルドディレクトリに入る
  2. Choreonoidを立ち上げる
  3. プロジェクトファイルを読み込む
  4. プロジェクトが読み込まれると同時に仮想ジョイスティックビューが自動的に表示される
  5. TurretControllerのコントローラモジュールのファイルパスを直す
  6. シミュレーションを開始する
  7. 仮想ジョイスティックビューを操作する
  8. 操作に従ってTankモデルの砲塔が動く

実験3:Tankチュートリアルをやり直す

実験1および2より、プロジェクトファイルに保存するときに仮想ジョイスティックビューを表示した状態でプロジェクトファイルに保存すれば、Tankチュートリアルをやる際にも仮想ジョイスティックビューが正常に動くのではないかと考えました。

最初の投稿で私が行き詰まった時のことをよくよく思い出してみますと、チュートリアルのステップ3の「仮想ジョイスティックビューの準備」の節を行った時と「コントローラのソースコード」の節を行った時との間に少々ブランクがありそこで一旦Choreonoidを終了したので、続く「コントローラの置き換え」の節でプロジェクトファイル(step3.cnoid)として保存する際には仮想ジョイスティックビューが表示されていない状態で保存していました。

そこで、ステップ3でプロジェクトファイルを保存する際に仮想ジョイスティックビューを表示させた状態で保存するように注意しながら、Tankチュートリアルをもう一度ステップ1からやり直してみました。

すると今度は、仮想ジョイスティックビューは実験1および2と同じように正常に動きました。
つまり、プロジェクトを読み込む前に一度仮想ジョイスティックビューを表示しておかなくても、プロジェクトファイルを読み込むだけで仮想ジョイスティックビューでの操作に従いTankモデルの砲塔が動きました。

その後、仮想ジョイスティックビューを表示させた状態でプロジェクトを保存するのと、表示しない状態で保存するのとでそれぞれもう1周ずつしてみました。

そして、次のような結果を得ました。

  • 仮想ジョイスティックビューを表示させた状態でプロジェクトファイルに保存すると、次回プロジェクトを読み込んだ際に仮想ジョイスティックビューは正常に動く
  • 仮想ジョイスティックビューを表示しない状態でプロジェクトファイルに保存すると、動かないことがある(プロジェクトファイルを読み込む前に予め仮想ジョイスティックビューを表示させておくかどうかで挙動が変わる)

実験4:SampleCrawlerJoystick.cnoidから仮想ジョイスティックビューを取り除いてみる

先ほどとは逆にSampleCrawlerJoystick.cnoidから仮想ジョイスティックビューを取り除くと仮想ジョイスティックビューが動かなくなるのではないかと考え、実験を行いました。

結果は予想に反し、仮想ジョイスティックビューは正常に動きました。

以下に操作手順を示します。

操作手順

  1. Choreonoidを立ち上げる
  2. ~/choreonoid/sample/SimpleController/SampleCrawlerJoystick.cnoid を読み込む
  3. 仮想ジョイスティックビューを消去する(メインメニューの[表示]→[ビューの消去]→[仮想ジョイスティック]を選択)
  4. ~/choreonoid/ext/SampleCrawlerJoystick.cnoid として保存する(メインメニューの[ファイル]→[名前を付けてプロジェクトを保存]を選択し、「Choreonoidプロジェクトファイルの保存」ダイアログ上で~/choreonoid/extディレクトリに入り、ファイル名にSampleCrawlerJoystick.cnoidを指定して[保存]ボタンを押す)
  5. 一旦Choreonoidを終了する
  6. 再びChoreonoidを立ち上げる
  7. ~/choreonoid/ext/SampleCrawlerJoystick.cnoid を読み込む
  8. 仮想ジョイスティックビューを表示させる(メインメニューの[表示]→[ビューの表示]→[仮想ジョイスティック]を選択)
  9. シミュレーションを開始する
  10. 仮想ジョイスティックビューを操作する
  11. 操作に従ってCrawlerモデルが動く

実験5:Tankのサンプルから仮想ジョイスティックビューを取り除いてみる

Tankのサンプルでも試してみました。
結果は実験4と同じでした。

以下に操作手順を示します。

操作手順

  1. Choreonoidを立ち上げる
  2. ~/choreonoid/sample/tutorial/Tank/step3.cnoid を読み込む
  3. 仮想ジョイスティックビューを消去する
  4. TurretControllerのコントローラモジュールのファイルパスを直す
  5. ~/choreonoid/ext/step3.cnoid として保存する
  6. 一旦Choreonoidを終了する
  7. 再びChoreonoidを立ち上げる
  8. ~/choreonoid/ext/step3.cnoid を読み込む
  9. 仮想ジョイスティックビューを表示させる
  10. シミュレーションを開始する
  11. 仮想ジョイスティックビューを操作する
  12. 操作に従ってTankモデルの砲塔が動く

まとめ

仮想ジョイスティックビューが正常に動くためには、プロジェクトファイルを読み込んだ時点と同時かそれよりも前に仮想ジョイスティックビューを一度表示しておく必要があるのではないかと思います。
しかし、この予想では実験4および5の結果をうまく説明できません。

詳しい情報をありがとうございます。おかげさまで、原因を特定することができました。

動作の違いは、コントローラの設定でした。コントローラのプロパティに「再読み込み」という項目があって、うまく動いているプロジェクトはこれがTrueになっています。しかし、デフォルトの設定ではfalseになっていて、チュートリアルでは説明されていないため、チュートリアル通りに進めたプロジェクトでは、Falseのままになっているはずです。これをTrueにすると、動くと思います。

この項目は、コントローラのモジュールをシミュレーションの実行前に毎回ロードし直すか否かを指示するものです。

動かない時(Falseの時)は、
1.プロジェクトを読み込む。ーコントローラモジュールも読み込まれ、その時にJoystickの初期化を行う。
JoystickViewがないので、Joystickがないと判断される。
2.JoystickViewを開く
3.シミュレーションを開始する。ーコントローラはJoystickがないと思っているので動かない。

動く時(Trueの時)は、
1.プロジェクトを読み込む。
2.JoystickViewを開く。
3.シミュレーションを開始する。ー開始前にコントローラモジュールを読み込み、その時にJoystickの初期化を行う。
JoystickViewを認識する。

というように動作していたことがわかりました。

「再読み込み」の項目をFalseにすることは、繰り返しシミュレーションを行う場合には、起動時間を短縮する意味があります。今回のサンプルの場合は、プロジェクトファイルでJoyStickViewがあることを補償したほうがいいと思います。

ありがとうございます。

私の手元の、動かなかったTankチュートリアルのプロジェクトを確認したところ、確かにコントローラの「再読込」プロパティがfalseになっていました。
trueにしてみると、おっしゃる通り無事に仮想ジョイスティックビューを動かすことができました。

また、「再読込」プロパティをfalseにすると繰り返しシミュレーションを行う際に起動時間の短縮になること、ビューがあることをプロジェクトファイルで保証すると良いこと、了解しました。
今後プロジェクトを作る際にはそのへんも意識しながらやっていきたいと思います。

ありがとうございました。