2014年8月16日土曜日

ODEでサイコロのシミュレーション


こんにちは。
突然ですが今日のテーマはODEを使ったちょっとしたプログラムです。
ある日、研究室の隣の人がサイコロを振って、出た目の数×10分ずつしっかり集中するという変なゲームを始めました。
そこでODE(Open Dynamics Engine)を使い、サイコロを振って出た目を判定するシミュレーションを行ってちゃちゃっと勉強時間を決めてしまいましょう!というものです。
サイコロはODEで描画できる基本図形(立方体と円柱)でサイコロの本体と数字を表す目を表現しました。チマチマと寸法、位置、重心を定義して作成した結果が下の図です。

なんとなくそれっぽいものが出来ました。ソースコードはあとでリンクを貼っておきますが、一つ一つの数字の目を表現するのにコードがとても長くなってしまいました。もうちょっと賢く書けるといいですね。
 あとサイコロを落とすとき落とす姿勢を固定してしまうと、毎回実行して出る目が一緒になってしまいますから乱数をつかってサイコロの姿勢をランダムに決定します。このコードについては下に示します。

//引数:手に入れたい乱数の範囲(minからmax)で少数点第何位(digit)まで求めるか
double GetRandom(double min,double max, int digit){
  double ten,R;
  static int srand_flag = 0;

  if (srand_flag == 0) {
    srand((unsigned int)time(NULL));
    srand_flag = 1;
  }

  ten = pow(10, digit-1);
  R = min*ten + (int)(rand()*((max-min)*ten+1.0)/(1.0+RAND_MAX));
  return R/ten;
}


void Randam()
{
  dReal theta[4];

  for (int i = 0; i < 4; i++) {//※注意1
    theta[i] = M_PI*GetRandom(-2,2,4);//-2piから2piまでの角度をランダムに決定
  }
  dRFromEulerAngles(R, theta[1], theta[2], theta[3]);//サイコロの姿勢の回転行列をオイラー角で決定
}

※注意1:Macで実行したところ配列の一番目の要素が変化しないという不都合な現象が起きたのでひとつ余分に取得して一番目の要素を無視して使っています。
参考: C言語の乱数発生について質問です。
http://detail.chiebukuro.yahoo.co.jp/qa/question_detail/q1258942042
これで高いところから落とすだけでコロコロっとランダムに転がりますから本来の目的は達成できるのですが、あと人間の目で出た目を判別するだけではなく、プログラムでもちゃんと転がったあと何が出たのかを判定するコードを書きました。これについては該当する関数についてコードを下に示します。

int detame()
{
  const dReal *linear_vel;
  const dReal *pos1, *pos2, *pos3, *pos4, *pos5, *pos6;
  double pos[6];
  double max = 0.0;
  int max_num = 0;

  linear_vel  = dBodyGetLinearVel(dice.body);//サイコロのそれぞれx,y,z方向の速度を取得

  if(cnt>=300 && linear_vel[0] <= 0.00000001 && linear_vel[1] <= 0.00000001 && linear_vel[2] <= 0.00000001 ){
  //cntはsimloopが何回呼び出されたかのカウンタ、これが300カウントを超えたかつ、x,y,z方向の速度がものすごく小さくなったら
  //サイコロの目の位置を1から6の目に関してゲット
    pos1 = dBodyGetPosition(one.body);
    pos2 = dBodyGetPosition(two[0].body);
    pos3 = dBodyGetPosition(three[0].body);
    pos4 = dBodyGetPosition(four[0].body);
    pos5 = dBodyGetPosition(five[0].body);
    pos6 = dBodyGetPosition(six[0].body);

  //z座標のみ取り出して別の配列に格納
    pos[0] = pos1[2];//1の目のz座標
    pos[1] = pos2[2];//2の目のz座標
    pos[2] = pos3[2];//3の目のz座標
    pos[3] = pos4[2];//4の目のz座標
    pos[4] = pos5[2];//5の目のz座標
    pos[5] = pos6[2];//6の目のz座標

  //z座標の最大値を求めて一番高い位置にある目を決める
    max = pos[0];
    max_num = 0;
    for(int i = 1; i < 6; i++){
      if(pos[i]>=max){
        max = pos[i];
        max_num = i;
      }
    }
    if(judge == 0){//simloopの中で一回だけ出た目をprintf
      printf("出た目は %d !!\n", max_num+1);
      judge = 1;
    }
  }else{
    max_num = -1;
  }

  return max_num+1;//一応出た目をリターン
}

これでサイコロシミュレータの完成です。これで効率的に勉強ができますね。このサイコロシミュレーターすべてのソースコードは下のリンクからダウンロードできます。
ダウンロードはこちら(Googleドライブ)
動作はODE 0.13でOSはUbuntu 14.04とMac OS X 10.9.4で確認しています。Windowsは動作未確認です。ごめんなさい。またいろいろごちゃごちゃやってますので環境によってはうまく動作しないかもしれません...

以上のことができたらサイコロをもっと増やして遊んでみるのも楽しいかもしれません。サイコロを25個定義してシミュレーションを行った動画です。これだったら勉強集中時間も勝手に長くなりますし。となりのお友達も喜んでくれるでしょう。



また本来の活動とは関係のない内容でしたね。しかしODEではロボットの動作シミュレーションもできたりしますから、関係がない訳ではないかもしれません。
今日はここまでです。ありがとうございました。

参考にさせて頂いたサイト
demura.net: ロボットの開発と教育
http://demura.net/
出村先生、「ロボットシミュレーション」の書籍、サイト共にわかりやすい内容でいつもお世話になっております。ありがとうございます。

2014年8月6日水曜日

ROSの勉強をはじめました

プログラム担当のAです。
最近はTeX関連の投稿が多いですね。

ところでタイトルにもあるようにROSの勉強をはじめました。
きっかけは、Ubuntu 14.04がROSでサポートされたからですね。
公式のチュートリアルを一通りやりました。チュートリアルには日本語版もありますが、英語版のチュートリアルを頑張ってやるのがいいと思います。

短いですが、それでは。

2014年8月5日火曜日

Sublime Text 2でTeXを使う (Ubuntu 14.04 LTS版)


こんにちは
最近、WindowsよりもUbuntuを開いている時間が圧倒的に多くなったので、ついにUbuntuにもTeXを導入することにしました。
TeXをUbuntu14.04LTSに導入する手順は以下の記事にプログラム担当のAさんが書いてくれていますのでそちらを参照して行いました。
 Ubuntu14.04LTSにemacsのためのTeXの日本語環境を整える
いつもTeXでレポートを書くのですが、そこで必要になってくるのがエディタです。 Aさんはemacsを使って書いていますが、私はSublime Textに恋しているのです。
そこでUbuntu環境でもSublime Text 2を使ってTeXをコンパイルしたくなったのでその方法を記事にします。


前準備

今回、動作を確認した環境は
Ubuntu14.04LTS日本語Remix(3.13.0-30-generic)
Sublime Text 2 Version 2.0.2, Build 2221

Sublime Text 2に関してはPackage Controlが導入されていることが前提です。


手順1

こちらを参照して”YaTeXのインストール”の手順にいく前までの操作を行ってください。
私が導入した時にはTeXLive2014がリリースされておりましたので、その点注意が必要でした。


手順2

手順1が終わったら、 Sublime Text 2の設定です。
「Shift+Ctrl+P」でコマンドパレットを呼び出し、Package Control: Install Packageと入力してください。


このあとLaTeXToolsと入力し、LaTeXToolsをインストールします。以下のメッセージが出たら成功です。


次に「Shift+Ctrl+P」でコマンドパレットを呼び出し、「LaTexTools: Reconfigure and migrate setting」と入力します。


入力してEnterしたあと、成功したよ!のメッセージウィンドウが出ればOKです。



手順3

ここから重要な作業になります。
Sublime Textのメニューの「Preference」の項目から「Browse Package…」を選択し
LaTeXTools→builders→traditionalBuilder.pyを開きます。
この操作はターミナルからサッっと行ってもいいです。
ファイルの場所は「~/.config/sublime-text-2/Packages/LaTeXTools/builders/traditionalBuilder.py」
でした。
このファイルの18から20行目のコード

DEFAULT_COMMAND_LATEXMK = ["latexmk", "-cd",
    "-e", "$pdflatex = '%E -interaction=nonstopmode -synctex=1 %S %O'",
    "-f", "-pdf"]

をコメントアウト(該当箇所を選択したあとCtrl+/)し、以下の記述を追加する

DEFAULT_COMMAND_LATEXMK = ["latexmk", "-cd",
     "-e", "$latex = 'uplatex %O -interaction=nonstopmode -synctex=1 %S'",
     "-e", "$biber = 'biber %O --bblencoding=utf8 -u -U --output_safechars %B'",
     "-e", "$bibtex = 'upbibtex %O %B'",
     "-e", "$makeindex = 'makeindex %O -o %D %S'",
     "-e", "$dvipdf = 'dvipdfmx %O -o %D %S'",
     "-f", "-norc", "-gg", "-pdfdvi"]

次にホームディレクトリ直下に「.latexmkrc」というファイルを作成し、下のおまじないを記述。
これはUbuntu14.04LTSにemacsのためのTeXの日本語環境を整えるで紹介されている記述と共通です。

$latex = $latex='platex -kanji=utf8 -guess-input-enc -synctex=1 -interaction=nonstopmode %S';
$bibtex = 'jbibtex';
$dvipdf = $dvipdf='dvipdfmx -f ptex-ipaex.map %S';
$dvips = 'pdvips';
$dvi_previewer = 'start xdvi';
$pdf_previewer = 'start evince';
$pdf_mode = 3;

ここまでできたら設定は以上です。


確認

例のごとくテスト用のTeXファイルを作成します。以下のような文章で「test.tex」としてファイルを保存し、「Ctrl+B」でコンパイルします。

\documentclass{jsarticle}
\begin{document}
English

日本語

余弦定理
\begin{eqnarray}
f(x)  =  \sin(x)
\end{eqnarray}
\end{document}


TraditionalBuilder: Invoking latexmk... done.
の一行が表示されれば、成功です。生成されたPDFを確認してみてください。

これでSublime Text 2を使ったTeX文書の作成は以上です。
最近はなぜかTeXの記事が多いですね...
サーキット本来の活動も後輩たちががんばっているみたいなので、そういった記事も公開されていくと思います。お楽しみに。

参考にしたサイト

みずぎわブログ様
【2014-3-12以降版】Mac Sublime Text2 or Sublime Text3 で Tex 導入の初歩からhttp://yusuke0.hatenablog.com/entry/2014/04/06/111945