About this Blog

This Blog has English posts and Japanese posts. About Mac, iOS, Objective-C, and so on.

2013年6月22日土曜日

ParrotのARDrone. ホバリングが安定しない時は

最近いじっているParrotのARDrone2.0。
どうもホバリングが安定しないな~と思っていろいろ調べていたら、こんなページを見つけました。

Indoor Flying Tips - Drone Flyers : Drone Flyers

見出しだけ意訳すると、
  1. 柔らかい素材は高度センサーの超音波を吸収しちゃうよ
  2. 床面に模様があったほうがいいよ
  3. 天上に近づきすぎると、ARDroneが吸い付くよ
  4. 室内の時は室内用ハルを着けよう
  5. アプリ設定で、挙動を控えめにしよう
とのこと。

ホバリングに関係があるのは1番と2番。
ARDroneは下向きカメラの画像をホバリング時の位置制御に使っているので、
硬質で非光沢で模様がある床の上で飛ばしたほうがよさそうです。

上の情報の裏を取ろうと思って調べたら、こんな記事も見つかりました。
ケータイゲームの世界で“ゲーム機”を再発明――セドゥCEOに聞く「AR.Drone」 - ITmedia Mobile
姿勢制御には、加速度センサーやジャイロセンサーからの情報に加え、機体底部に設けた垂直カメラの映像を活用している。
だそうです。

[メモ]Eclipseの日本語化、JRE7の導入など

自分用メモ

Eclipseの日本語化
メニューの「Help」→「Install a new software」を開き、
URLに「http://download.eclipse.org/technology/babel/update-site/R0.10.1/juno」
と入れる。
Japaneseを選んでインストール。


JRE7の導入
Eclipseを一旦終了して、 Java SE Runtime Environment 7 Downloads
から32bit・64bitに対応したjre7をダウンロードしてインストール。
ダウンロード前に「Accept License Agreement」を選択する必要がある。

Eclipseを起動し、「ウィンドウ」→「設定」を開く。
「Java」→「インストール済みのJRE」をクリック。
「追加」をクリック。
「標準VM」を選択して、「次へ」をクリック。
「JREホーム」の横の「ディレクトリ」をクリック。
JRE7をインストールした場所を選択(おそらくC:\Program Files\java\jre7)
「完了」をクリック。
「インストール済みのJRE」の欄のにjre7が追加されているはず。
jre7にチェックを入れて、「OK」をクリック。


プロジェクトのJavaコンパイラーをJRE7に切り替える方法
プロジェクト・エクスプローラーの中の「JREシステム・ライブラリー[jre6]」(または他の古いシステムラ・ライブラリー)を「ビルドパスから削除」する。
プロジェクトを右クリックして「ビルドパス」→「ビルドパスの構成」を選択。
「Javaのビルドパス」をクリック。
「ライブラリー」をクリック。
「ライブラリーの追加」をクリック。
「JREシステム・ライブラリー」を選択して「次へ」
「代替JRE」を選択して、「jre7」を選択。
プロジェクトに「JREシステム・ライブラリー[jre7]」が追加されていたらOK。

EclipseでProcessingを使う(プラグイン非使用)

必要に迫られて使うことになったProcessing。
どうせ書くなら、リッチな開発環境を使いたいものです。

Java系言語ならEclipse!
プラグインもいくつかありますが、
Eclipse Plug In - Processing
Proclipsing
最近のProcessingはバージョンがころころと変わるのでちょっと不便(この間2.0のstableが出ましたが)

というわけで、手動でアーカイブをインポートして使うことにします。

前提として、日本語化されたEclipse環境、JavaコンパイラーはJRE7です。
また、ProcessingはCドライブの直下、「C:\processing-*」にあることにします。


プロジェクトを作成
メニューの「ファイル」→「新規」から、「Javaプロジェクト」を選択します。
プロジェクト名はなんでもいいです。JREは「jre7」にしておいてください。


プロジェクトにアーカイブ(*.jar)をインポート
プロジェクト・エクスプローラーを右クリックして、インポートを選択。
「選択」のウィンドウで「一般」→「ファイルシステム」を選択して「次へ」。
「次のディレクトリーから」という所に「C:\processing-*\core\library」を入力してEnter。
・core.jar
・gluegen-rt.jar
・jogl-all.jar
の3つをチェックして、
「拡張」をクリックし、「ワークスペースにリンクを作成」にチェックをいれます。
「完了」をクリックします。
プロジェクトに*.jarファイルが3つ追加されるので、右クリックして「ビルドパス」→「ビルドパスに追加」を選択、をそれぞれ行います。
(アーカイブをリンクとしてインポートするのは、*.jarがフォルダ内にあるdllに依存して動作するためです)

Webカメラも使いたいので、同様のことを
「C:\processing-*\modes\java\libraries\video\library」にある
・gstreamer-java.jar
・jna.jar
・video.jar
についても行います。


クラスを作成し、それをProcessingのJavaアプレットにする
プロジェクト内に、ProdessingTestというクラスを新規作成します。
このようになっているはずです。
public class ProcessingTest {

}

これを、以下のように修正します。
import processing.core.*;//!!!
import processing.video.*;

public class ProcessingTest extends PApplet{//!!!
 public void setup(){
 }
 public void draw(){
 }
}//!!!
これで、Processing sketchのひな形ができました。
「実行」ボタンをクリックすれば、Javaのアプレットとして実行できます。
適宜関数などを追加してください。

Processing標準のエディタ(PDE)で開発するときとの違いは以下のとおりです。
・関数の頭にpublic(またはprivate)をつけないといけない。
・color という型が使えないので、int型を使う(color 型はint 型のtypedef。中身は一緒)
・型チェックが厳しい。float 型を使う時は0.5f というように書いたり、関数に渡すときには(float), (int)とキャストしたりすればOK.


Eclipseで書いたスケッチをPDEに持っていく時は、上記のひな形の//!!!の行を削除すれば大丈夫です。
関数につけたpublicやcolor型をintで代用している箇所などは修正しなくても動きます。
Eclipseの標準の文字コードがCP932(MS932)というあまり見ないエンコーディングなので若干注意が必要です。
画像のファイルパスも適宜修正してください。

2013年5月19日日曜日

自作ペイントソフトで筆のような効果を出す

学校の課題で簡単なペイントソフトを作りました。
1つオリジナルの味付けをとのことだったので、書道っぽくマウスの移動速度に応じて描く線の太さを変えるようにしました。
基本的には、一定時間ごとに検出されるマウスの位置情報から、移動量を速度とみなして、その逆数に比例した線の太さを設定します。
こうすると、ゆっくり動かした時には太い線が、早く動かした時には細い線が描けます。
が、1回ごとの移動量だけを元に計算すると、変動が大きく線がボコボコになってしまいます。
そこで、過去の移動量もストアしておき、平均移動量を使うことにしました。


計算としては、以下のようになります。
 最新の移動量 = { (1つ前のX座標 - 現在のX座標)の絶対値 + (1つ前のY座標 - 現在のY座標)の絶対値 } * 0.5
 新しい平均移動量 = { (過去の平均移動量)*重み + 現在の速度} / (重み+1)
 筆の太さ = 適切なパラメータ / 新しい平均移動量

2点間の距離の計算は、近似して計算の負荷を減らしています。


実行結果は以下の通り。左が平均化していないもの、右が平均化したものです。



ソースコードは以下の通り。Ruby + GTK2です。(課題自体はCだったのですが、コードが膨大だったので)
コード中では「移動量」ではなく「速度」(velocity, v)としています。厳密には正しくないですがまあ気にしないで。

calligraphy.rb
require 'gtk2'

# 筆に関するパラメータ
# いろいろ変えてみてください。
INIT_FUDE_VELOCITY = 2 # 筆の平均速度の初期値
FUDE_PARAM = 50        # 速度の逆数に乗ずる定数
WEIGHT = 5             # 平均速度算出のための重み

# 筆に関する変数を用意
$velocity = INIT_FUDE_VELOCITY
$x0 = 0
$y0 = 0
$x1 = 0
$y1 = 0

# ウィンドウとドローイングエリアの作成など
window = Gtk::Window.new
window.set_size_request(640, 640)
window.set_app_paintable(true)
window.set_events(Gdk::Event::BUTTON_PRESS_MASK | Gdk::Event::BUTTON_RELEASE_MASK | Gdk::Event::BUTTON_MOTION_MASK)
window.realize
drawable = window.window

# グラフィックコンテキスト(GC)の用意
gc = Gdk::GC.new(drawable)
black = Gdk::Color.new(0, 0, 0)
colormap = Gdk::Colormap.system
colormap.alloc_color(black, false, true)
gc.set_foreground(black)

window.signal_connect('motion_notify_event') do |win, evt| #マウスが動いた時
  $x1 = evt.x
  $y1 = evt.y
  v = (($x1-$x0).abs + ($y1-$y0).abs)/2.0             # 最新の速度を計算
  $velocity = (WEIGHT*$velocity + v)/(WEIGHT+1).to_f  # 平均速度を計算し直す
  fude_width = FUDE_PARAM/$velocity                   # 筆の太さを決定する
  gc.set_line_attributes(fude_width,Gdk::GC::LINE_SOLID,Gdk::GC::CAP_ROUND,Gdk::GC::JOIN_BEVEL) # 筆の太さを設定する
  drawable.draw_line(gc, $x0, $y0, $x1, $y1)
  $x0 = evt.x
  $y0 = evt.y
end

window.signal_connect('button_press_event') do |win, evt| #マウスボタンが押された時
  $x0 = evt.x
  $y0 = evt.y
end

window.signal_connect('button_release_event') do |win, evt| #マウスボタンが離された時
  $v = INIT_FUDE_VELOCITY
end

window.signal_connect('destroy') do
  Gtk.main_quit
end

window.show_all

Gtk.main


参考
 gtk2-tut - Ruby-GNOME2 Project Website
 Ruby/GTK - Ruby-GNOME2 Project Website
 ウインドウへの直接描画(Gdk::Drawable編) - Ruby-GNOME2 Project Website
 [Ruby] Ruby-GNOME2(Ruby/GTK2) 線を引く
 [Ruby] Ruby-GNOME2(Ruby/GTK2) マウスのイベントを拾う


ちなみに、GtkのRubyバインディングは
$sudo gem install gtk2
でインストールできます。(Ruby1.9.3で確認)

最後にもう1枚。

2013年5月15日水曜日

ruby-openglの立体をGithubに公開しました。

まだまだドキュメンテーションはじめ不備が多いですが、ひとまずお知らせ。
ykuramata/ruby-opengl-glut-shapes · GitHub

公開したのは、以下の通り。
・楕円体 (GLUT.Ellipsoid)
・回転角度によって半径を変えられる回転体 (GLUT.Cocoon)
・曲線周りの回転体 (GLUT.Macaroni)
・レゴブロック (GLUT.Legoblock)

一部は記事として紹介しています。
enthusiastick coding: ruby-openglで楕円体を描いてみた
[ruby-opengl] 回転体 Advanced(回転角度によって半径を変えられる)

2013年5月8日水曜日

Ubuntu+Ruby1.9.3+OpenGL+joystick(Xboxのコントローラ)

enthusiastick coding: Ubuntu+RubyでX-BOXのコントローラを使う(gem不使用)で接続したXboxのコントローラでの入力をOpenGLに反映させてみます。

参考にしたのは、
Pablotron: Joystick-Rubyで落としてきたtarボールに入っていたサンプルコードのxo.rb
require 'opengl'
require 'glut'
require 'joystick'
INTERVAL = 50
# 中略
$joy = Joystick::Device::open "/dev/input/js0" # 環境に応じて書き換えてください。
$foo = 0.0 # ジョイスティックからの入力を反映させたい変数。
timer_func = Proc.new{
  foo_diff = 0
  while $joy.pending?
    ev = $joy.next_event
    case ev.type
      when Joystick::Event::AXIS
        case ev.num
        when 0
          foo_diff = ev.value/1000.0 #AXISの値は-32767から32767
        end
      when Joystick::Event::BUTTON
        case ev.num
        when 0
          puts ev.value #=> ボタンが押された時: 1, ボタンが離された時: 0
          # ボタンに反応させたい時はここに具体的な処理を書いてください。
        end
      end
  end
  $foo += foo_diff
}
# 中略
GLUT.TimerFunc(INTERVAL, timer_func, 0)
# 後略
joystickからの入力値はバッファにためられるので、ただ一定時間ごとに値を取得してOpenGLの描画に反映させてもうまく動きません。
そこで、毎回バッファをクリアして最新の値を取得してするようにしています。
joystickの入力をトリガにするという手もありますが、今回はこれで。

2013年5月5日日曜日

Ubuntu+Ruby1.9.3でXboxのコントローラを使う(gem不使用)


といっても、それほど難しいことはしていないのですが。
Linuxではこういったデバイス(ゲームのコントローラなど)を汎用的にjoystickとして扱います。

コントローラを接続してから、
$ls /dev/input/
と打つと、js0やjs1といったデバイスが表示されます。

で、それを使うためのRubyのライブラリもちゃんとあります。
自分の環境だとgem経由ではうまく動作しなかったので、
Pablotron: Joystick-Ruby
からダウンロードして
$ruby ./extconf.rb
$make
$sudo make install
しました。 ただ1点、joystick.cの77行目
if ((*fd = open(RSTRING(path)->ptr, O_RDONLY)) >= 0) { #=>Compile ERROR!
がRuby1.8向けの古い書き方なので、
if ((*fd = open(RSTRING_PTR(path), O_RDONLY)) >= 0) {
と修正しました。

使い方は、サンプルコードや
RDoc Documentation
を参考にしましょう。

# スティックから手を離した時にAxisの値が0に戻らないという謎の現象。
# そういうもんなのか、コントローラが壊れているのかは不明.. # 長らくしまいこんでたからな〜

[arduino]ミニ四駆のラップタイム計測

enthusiastick coding: [Arduino]光が遮られた回数をカウントの回路を流用して、コードの書き換えだけでミニ四駆用のラップタイム計測タイマーに改造してみます。

回路図

タクトスイッチを使わないので、左半分だけでいいのですが。

/* ミニ四駆用ラップタイマー */
const int CDS = 0;
const int LED = 13;
int cds_value = 0;
int old_cds_value = 0;
int lap_count = 0;
unsigned long lap_time = 0;
unsigned long start_time = 0;

void setup(){
  pinMode(LED, OUTPUT);
  Serial.begin(9600);
}

void loop(){
  /* CdSの入力値の低下を検出 */  
  cds_value = analogRead(CDS);
  if(cds_value < old_cds_value*0.8){//元の光の強さの0.8倍未満なら光が弱くなったと判断
    Serial.print('LAP: ');
    Serial.println(lap_count);//LAP: 0は無視してください. :P
    Serial.println(micros() - start_time);//マイクロ秒を検出. micors()は70分でオーバーフローする.
    start_time = micros();
    lap_count++;
  }
  old_cds_value = cds_value;
  delay(10);
}

[Arduino]光が遮られた回数をカウント

CdSの入力値を監視し、光が弱くなったことを検出します。
光が弱くなった回数をカウントし、タクトスイッチを押した時にLEDの点滅回数でそのカウントを出力します。
ただ、なにかがCdSの上を横切った、というようなときはうまくいきますが、
だんだん光が弱くなるような場合(指でCdSを押さえたときとか)は、それを複数回にカウントしてしまいます。


こんな感じ


回路図


スケッチ(コード)
/* 光が遮られた回数をカウントし、LED光で知らせるプログラム. */
const int CDS = 0;
const int SW = 8;
const int LED = 13;
int i;
int counter = 0;
int old_cds_value = 0;
int cds_value = 0;
int sw_value = 0;
int old_sw_value = 0;
int sw_state = 0;

void setup(){
  pinMode(LED, OUTPUT);
  pinMode(SW, INPUT);
}

void loop(){
  /* スイッチが押されたことを検出 */
  sw_value = digitalRead(SW);
  if(sw_value==HIGH && old_sw_value==LOW){
    sw_state = 1 - sw_state;
    delay(10);
  }
  if(sw_state==1){
    for(i=0;i<counter;i++){
      digitalWrite(LED, HIGH);
      delay(500);
      digitalWrite(LED, LOW);
      delay(500);
    }
    sw_state = 0;
  }
  old_sw_value = sw_value;
  /* CdSの入力値の低下を検出 */  
  cds_value = analogRead(CDS);
  if(cds_value < old_cds_value*0.8){//元の光の強さの0.8倍未満なら光が弱くなったと判断
    counter++;
  }
  old_cds_value = cds_value;
  delay(100);
}

2013年5月2日木曜日

Arduino UNOとポケコンの接続

エルチカ(LEDチカチカ)は終わったので、ポケコンとArduinoで通信してみました。
ポケコンの11ピンを使ってのシリアルパラレル通信。
部品の制限で2bit通信。0~3の値をポケコンに送ることができます。

こんな感じ。



回路図

ポケコンのGNDの抵抗を書き忘れました。補ってください。
抵抗はCdSにつないであるのが10kΩ,それ以外は1kΩです。
ポケコンのPIN番号は、一番上側を1,一番下側を11としています。3がGNDです。
参考: 8ビット制御練習基板

Arduinoのコード
const int SENSOR = 0; /* アナログINの0 */
const int POKECOM_1 = 12; /* デジタルIOの12 */
const int POKECOM_2 = 13; /* デジタルIOの13 */

int val = 0;

void setup(){
  pinMode(POKECOM_1, OUTPUT);
  pinMode(POKECOM_2, OUTPUT);
  Serial.begin(9600);
}
void loop(){
  /* CdSからの値を整形. 440~840くらいの値を取る(私の環境の場合)ので、それを0~3に直す.*/
  val = (analogRead(SENSOR) - 440)/100;
  /* 1bit目をPOKECOM_1から出力 */
  if(val%2==1){
    digitalWrite(POKECOM_1, HIGH);
  }else{
    digitalWrite(POKECOM_1, LOW);
  }
  /* 2bit目をPOKECOM_2から出力 */
  if(val/2==1){
    digitalWrite(POKECOM_2, HIGH);
  }else{
    digitalWrite(POKECOM_2, LOW);
  }
  delay(100);
}
パラレルといいつつ、あんまりパラレルじゃありません。
bit演算使えよ!といったツッコミも承知です。
部品を揃えたら8bit通信で作り直しますんでしばしお待ちください。

ポケコンのコード
10 WAIT 10
20 OPEN "PIO:"
30 CLS
40 X=0
50 Y=0
60 PIOSET 3
70 V=PIOGET
80 Y=30-Y
90 GCURSOR(X,Y)
110 GPRINT "1000"
120 X=X+1
130 GOTO 70
ポケコンを持っている方はマニュアルも持っているはずなので、そちらを参考にしてください。
4と5のピンをINPUTに設定し(PIOSET 3)、値を読み取ります。
読み取った値をグラフにして液晶に表示します。

Arduino UNOのメモ

自分用メモ.
  • クロックは16MHz
  • スイッチはない。通電したらプログラムが走り続ける。
  • void setup()内で、デバイス(主にpin)の初期化など。
  • リセットボタンを押すと、setupし直す。
  • 通電中はvoid loop()が実行され続ける。
  • 0~13のデジタルIOピン、0~5のアナログINピンを持つ。デジタルIOピンのうち3,5,6,9,10,11はアナログOUTとして使用可能.
  • デジタルIOピンは使い方を初期化する必要がある。
  • 初期化にはpinMode(pin_number, MODE);を使う.
  • MODEはINPUTまたはOUTPUT.
  • アナログINピンは初期化の必要なし.
  • 入出力値のdigital(2値)/analog(連続値)は関数で使い分ける。
  • analogWrite(pin_number, value); digitalRead(pin_number); digitalWrite(pin_number, value); はデジタルIOピンからの入出力.
  • analogRead(pin_number); はアナログINピンからの入力.
  • デジタルIOのvalueはHIGHまたはLOW.
  • 基本的にHIGHは5V、LOWはGND(グランド)0V.
  • アナログ入力は1024段階、アナログ出力は256段階.
  • pin_numberはconst int LED = 7;などとして、defineした値のように使うのがArduino流らしい。
  • delay(ms); ミリセカンド待機.
  • millis(); プログラムがスタートしてからの時間をミリセカンドで取得. 約50日でオーバーフロー.
  • micros(); プログラムがスタートしてからの時間をマイクロセカンドで取得. 約70分でオーバーフロー.
  • Serial.begin(9600); シリアルポートを開く。毎秒9600bit。setup()内で呼ぶ。
  • Serial.println(v); シリアルポートにデータを出力.

2013年5月1日水曜日

Arduinoはじめます。UbuntuにIDEその他インストール

いまさらですが、Arduinoを始めます(なんで自分ってこうアーリーアダプターじゃないんだろうと思いつつ)。
買ったのは、「Arduinoをはじめようキット」


やることその1 JDKをインストール
各所で言及されていますが、Ubuntuの標準でインストールされるJDKだとArduinoのIDEがうまく動作しません。
そこで、OracleのJDKをインストール。
$sudo add-apt-repository ppa:webupd8team/java
$sudo apt-get update
$sudo apt-get install oracle-java7-installer


やることその2 ArduinoをPCに接続
いきなり結線して大丈夫か?という心配そのものがArduinoには不要でした。
付属のUSBケーブルで接続したら、チカチカとLEDが光り出しました。


やることその3 ttyACM0のパーミッションを変更
Arduinoを接続すると
/dev/ttyACM0
というデバイスとして認識されているはずです。
が、デバイスにはスーパーユーザーしかアクセスできないので、このままでは、ArduinoのIDEからttyACM0にアクセスすることができません。
(具体的には、ツール→シリアルポートの項目が選択できない)
そこで、
$sudo chmod a+rw /dev/ttyACM0
として、デバイスへのアクセスを一般ユーザにも開放してやります。
追記:
ただこれ、USBの抜き差しのたびに権限を設定しなおさないといけないので、
コマンドラインから$sudo ./arduinoとしたほうが楽かもしれません。


やることその4 ArduinoのIDEをダウンロード
Arduino - Softwareから、
Linux用のIDEをダウンロード→解凍します。
その中のarduinoというファイルを実行してやるとIDEが起動します。


やることその5 基板上のLEDを点滅
本格的なことは次に回すとして、まずは基板上のLEDを点滅させてみましょう。
int led = 13;

void setup(){
  pinMode(led,OUTPUT);
}

void loop(){
  digitalWrite(led, HIGH);
  delay(1000);
  digitalWrite(led, LOW);
  delay(1000); 
}
IDEで「検証」して確かめてから、「マイコンボードに書き込む」を実行すると、基板上のLEDがそれっぽい間隔で点滅するはずです。


参考にしたページ:
Ubuntu 12.04 LTSにOracle JDK7をインストールする - Starlight -Little Programmer’s Diary-
ArduinoをUbuntuで動かす方法: 綺麗なコードが良い!ぶろぐ
UbuntuでUSBシリアルを認識してるのに、Arduino... - Arduino - FriendFeed
Blink

2013年4月25日木曜日

[ruby-opengl] 回転体 Advanced(回転角度によって半径を変えられる)

Z軸周りの回転体ならば、普通は、r=f(z)という関数を考えてそれをぐるっと回転させますが、
このメソッドでは、回転角度に応じて関数f(z)を変えて回転体を描くことができます。

例えば、theta=0のときはf(z)が定数で、theta=PIのときはf(z)は2次関数であるようにすれば、人のふくらはぎのような形も簡単に。



コードはこちら。
gl_cocoon.rb
require "opengl"

module GLUT
  def GLUT.Cocoon(height, slice, stack)
    return unless block_given?
    zStep = height/slice.to_f
    tStep = Math::PI/stack
    0.step(height-zStep+0.0001, zStep){|z|
       GL.Begin(GL::QUAD_STRIP)
      (-Math::PI).step(Math::PI+0.0001, tStep){|theta|
         r1 = yield(z, theta, tStep)
         r2 = yield(z+zStep, theta+tStep, tStep)
         phi = atan(zStep/(r2-r1).abs)
         GL.Normal(cos(theta)*sin(phi), sin(theta)*sin(phi), cos(phi))
         GL.Vertex(r1*cos(theta), r1*sin(theta), z)
         GL.Vertex(r2*cos(theta+tStep), r2*sin(theta+tStep), z+zStep)
      }
      GL.End
    }
  end


使い方
Z軸周りに回転します。
heightが高さ(Z軸方向の長さ)
sliceが高さ方向の刻み回数
stackが周方向の刻み回数
です。
渡すブロック内で、回転半径を返すようにしてください。

サンプル1
GLUT.Cocoon(6.0, 20, 20){|z,theta,tStep|
  # r = -a*z*(z-8) です。
  # 回転角が PI/3から PI*2/3の時はa=0.07、
  # それ以外の時は、a=0.1です。
  # 新宿のコクーンタワーのような形になります。
  case theta
  when Math::PI/3 .. 2*Math::PI/3
    -0.07*z*(z-8)
  else
    -0.1*z*(z-8)
  end
}



サンプル2 人の脛のような形も簡単に。
GLUT.Cocoon(6.0, 15, 15){|z,theta,tStep|
  # thetaは-PIからPIまで取るので、tは1〜0〜1と連続的に変化します。
  t = (theta/Math::PI).abs
  # tに1.0(定数)をかけ、1-tに-0.1*z^2 + 0.5*z + 1をかけることで、
  # f(z)は直線から2次曲線へと連続的に変化することになります。
  1.0*t + (1-t)*(-0.1*z*z + 0.5*z+1)
}


視点や光の設定などは省いています。このままでは表示されないので注意。

2013年4月23日火曜日

1つのベクトルから基本ベクトルを作る計算方法

なんかもうタイトルがわけわからないですが、
あるベクトルaが与えられた時に、そのベクトルとZ軸(またはX軸、Y軸)が対応しているような直交座標系(を表す単位ベクトル3つ)を求めるには?というお話です。

例によってRubyのプログラムで計算していきます。

require "matrix"
class Vector
  # 準備
  # Vectorクラスに、外積を求めるメソッドを追加します。
  # http://d.hatena.ne.jp/tanku/20100318/1268930228
  # よりコピペさせてもらいました。
  def outer_product(o)
    raise 'size#{self.size}' unless size == 3
    Vector[
      self[1] * o[2] - self[2] * o[1],
      self[2] * o[0] - self[0] * o[2],
      self[0] * o[1] - self[1] * o[0],
    ]
  end
  

  # 基本ベクトルを生成するメソッド。
  # ここでは、selfがZ軸に一致するようにしています。
  def generate_unit
    raise 'vector size must be 3.' unless size == 3
    # まず、selfと方向が一致する単位ベクトル w を作ります。
    w = self/self.r

    # 次に、wと直交するベクトル u を求めます。
    # 内積=0を満たしていればいいので、無数にあります。
    # ゼロ除算が起こらないような方法を選びました。
    # w[0]*w[1] - w[0]*w[1] + w[1]*w[2] - w[1]*w[2] + w[2]*w[0] - w[2]*w[0] = 0
    # を変形して、
    # w[0]*(w[1]-w[2]) + w[1]*(w[2]-w[0]) + w[2]*(w[0]-w[1]) = 0
    # としています。
    u0 = Vector[w[1]-w[2],  w[2]-w[0], w[0]-w[1]]
    u = u0/u0.r

    # wを軸として、uを90度回転したものが、残り1つのベクトル v です。
    # v = (w・u)*w + (u-(w・u)*w)*cos(90度) - (u✕w)*sin(90度)
    # 計算の理屈については、
    # http://hooktail.sub.jp/mathInPhys/vectorRot/
    # を見てください。
    v = w.inner_product(u)*w + u.outer_product(w)

    # 作った3つのベクトルを返します。
    return [u, v, w]
  end

参考にしたページのリンクを貼っておきます。
 3次元ベクトルメモ - 好き勝手に・げーあにん?
 ベクトルの回転 [物理のかぎしっぽ]
 class Vector

2013年4月21日日曜日

ruby-openglでサーモグラフィー風の色の生成

いろいろ計算方法はあるみたいだけど、このページの計算方法を試してみました。
 サーモグラフィー作成のためのRGB値の指定方法 - Ryota’s Research Diary


先に実行結果を


0.0から1.0までの値をとって、RGBを算出してカラーを設定します。

コードは以下。

gl_color.rb
module GL
  def GL.ThermoColor(t)
    case t
      when 0.0 .. 0.2
        r=0; g=0; b=5*t
      when 0.2 .. 0.4
        r=0; g=5*t-1; b=1
      when 0.4 .. 0.6
        r=0; g=1; b=3-5*t
      when 0.6 .. 0.8
        r=5*t-3; g=1; b=0
      when 0.8 .. 1.0
        r=1; g=5-5*t; b=0
      else 
        r=1; g=1; b=1
    end
    GL.Color(r,g,b)
  end
end
if $0 == __FILE__
  HEIGHT = 400
  WIDTH = 200
  def display
    GL.Clear(GL::COLOR_BUFFER_BIT)
    hStep = 2.0/100
    steps = 400
    steps.times{|t|
      h = 2*t.to_f/steps - 1.0
      GL.ThermoColor(t.to_f/steps)
      GL.Begin(GL::POLYGON)
      GL.Vertex(-1, h)
      GL.Vertex(1, h)
      GL.Vertex(1, h+hStep)
      GL.Vertex(-1, h+hStep)
      GL.End
    }
    GL.Flush()
  end
  GLUT.Init()
  GLUT.InitWindowSize(WIDTH, HEIGHT)
  GLUT.InitDisplayMode(GLUT::RGB)
  GLUT.CreateWindow("Thermo Color Sample")
  GLUT.DisplayFunc(method(:display).to_proc)
  GL.ClearColor(1.0, 1.0, 1.0, 1.0)  
  GLUT.MainLoop();
end

2013年4月16日火曜日

ruby-openglで楕円体を描いてみた

参考
http://www.gamedev.net/topic/126624-generating-an-ellipsoid-in-opengl/

2013/04/23: 修正しました。
・不要なインクルードを削除しました。
・GLU.NewQuadric()は必要なかったので、削除しました。
・GLUTの拡張ということにしました。(描画自体は、OpenGLのみで大丈夫です)

使い方
require "./gl_ellipsoid.rb"
# 中心は(0,0,0)
# 第2引数: X軸方向の半径
# 第3引数: Y軸方向の半径
# 第4引数: Z軸方向の半径
# 第5,第6引数: 描画の細かさ
GL.Ellipsoid(1, 2, 3, 20, 20)

gl_ellipsoid.rb
require "opengl"
require "glut"

module GLUT
  extend Math
  def GLUT.Ellipsoid(x,y,z,slice,stack)
    tStep = Math::PI/slice.to_f
    sStep = Math::PI/stack.to_f
#   ワイヤーフレームで描きたい時は、コメントを外してください。
#   GL.PolygonMode(GL::FRONT_AND_BACK, GL::LINE)
    (-Math::PI/2).step(Math::PI/2+0.0001, tStep){|t|
      GL.Begin(GL::TRIANGLE_STRIP)
      (-Math::PI).step(Math::PI+0.0001, sStep){|s|
        GL.Normal(cos(t)*cos(s), cos(t)*sin(s), sin(t))
        GL.Vertex(x*cos(t)*cos(s), y*cos(t)*sin(s), z*sin(t))
        GL.Vertex(x*cos(t+tStep)*cos(s), y*cos(t+tStep)*sin(s), z*sin(t+tStep))
      }
      GL.End
    }
  end
end


2013年4月14日日曜日

[ruby-opengl]Ubuntu12.10にインストール

3次元に挑戦!!ということで、ruby-openglを始めようと思います。

まったくRuby環境がインストールされていないなら、
$sudo apt-get install freeglut3 freeglut3-dbg freeglut3-dev
$sudo apt-get install ruby1.9.3
$sudo gem install opengl --pre
これで完了です。
--pre をつけるのは、このページのアドバイスに従いました。
Install ruby-opengl 0.60.1 on Ubuntu? ...in order to add 'gl', 'glu', and 'glut' extensions - Stack Overflow

以前は、gemのmkrfに不備があったようで、いろいろと面倒なことがあったらしいのですが、
(参考: Ubuntu 12.04.1 と ruby-1.9.3p283 でも ruby-opengl - Tociyuki::Diary
現在(2013/04/13)は、gem一発でいけました。


注意点
libopengl-ruby*がインストールされていると、干渉してうまく動かないようです。
Ubuntuソフトウエアセンターで、opengl rubyで検索して、インストールされていたら削除しておきましょう。


ちなみに、もうruby1.8が入っていて、rvmを使わずに1.9.3もインストールしたいなら、
$sudo apt-get install freeglut3 freeglut3-dbg freeglut3-dev
$sudo apt-get install ruby1.9.3
$sudo gem1.9.3 install opengl --pre

2013年4月12日金曜日

Rubyで画像の二値化

自習時のメモです。

参考
画像処理について
:: ロボティクス入門(共立出版株式会社)
BMP画像の形式について
:: http://www.kk.iij4u.or.jp/~kondo/bmp/
gnuplotについて
:: http://www.wakayama-u.ac.jp/~tokoi/lecture/shori1/2009/09.html

使い方
$ruby binarize.rb ファイル名
としてください。 入力は、グレースケールのWindowsビットマップ画像
二値化されたpbmファイルと、クラス間分散とクラス内分散の分散比の数値データを出力します。
数値データは、gnuplotでプロットしてください。

出力サンプル
元画像、二値化した画像、閾値を変化させたときの分散比、という順番です。

りんごの画像




机の上に置かれた、プラスチックのケース





コード
binarize.rb
if ARGV.size==0
  puts "ERROR!: input file name is missing."
  exit
end

$original_file_name = ARGV[0]

def output_pbm(data)
  height = data.size
  width = data[0].size
  File.open($original_file_name+".pbm", "w"){|io|
    io.puts "P1"
    io.puts "# CREATOR: Ruby PNM Filter Version 1.1"
    io.puts width.to_s + " " + height.to_s
    data.reverse.each{|e1|
      io.puts e1.join(" ")
    }
  }
  puts "Created #{$original_file_name+".pbm"}."
end
def get_bmp_data
  io = open($original_file_name, "rb")
  io.seek(2, IO::SEEK_CUR)
  print "file size (byte)="; puts filesize = io.read(4).unpack("i")[0]
  io.seek(4, IO::SEEK_CUR)
  print "offset="; puts offset = io.read(4).unpack("i")[0]
  io.seek(4, IO::SEEK_CUR)
  print "width="; p width = io.read(4).unpack("i")[0]
  print "height="; p height = io.read(4).unpack("i")[0]
  io.seek(2, IO::SEEK_CUR)
  print "Bits per pixel="; p bpp = io.read(2).unpack("s")[0]
  print "Compression type="; p ctype = io.read(4).unpack("i")[0]
  puts "(0:No compression 1:RunLength 8 bits/pixel 2:RunLength 4 bits/pixel 3:Bitfields)"
  io.seek(offset, IO::SEEK_SET)
  data = Array.new(height)
  height.times{|j|
    data[j] = Array.new(width)
    width.times{|i|
      value = io.read(1).unpack("C")[0]
      data[j][i] = value
    }
    io.seek(width%4==0 ? 0 : 4-width%4, IO::SEEK_CUR)
  }
  io.close
  return data
end
def binarize(data, threshold=128)
  return data.map{|e1| e1.map{|e2| e2 max_variance_ratio
      max_variance_ratio = v
      slashold  = s
    end
  }
}
puts "Created #{$original_file_name+".plt"} for gnuplot."
print "max_variance_ratio:"; puts max_variance_ratio
output_pbm(binarize(data, slashold))
print "time(sec): "; puts Time.now - start_time

2013年4月7日日曜日

[ソーシャルタギング]独自の共起尺度を考えてみた

きっかけ

ソーシャルブックマーク考2 タグの構造について より引用

上位概念Aと下位概念Bという二つの言葉がある場合、

①:「上位概念Aを含み、下位概念Bを含まない」文章( A && ! B )
②:「上位概念Aを含み、かつ下位概念Bを含む」文章( A & B)
③:「上位概念Aを含まず、下位概念Bを含む」文章( !A && B)

の3つの文章の数の比は、①>②>③が成り立つ。逆をいえば①>②>③が成り立っていれば、どちらが上位語かを判定できるわけだ。

上のサイトの仮説にもとづくと、
文章(webページ)の集合全体Uがあって、Aを含む文章、Bを含む文章の関係が図のようになっているときは、
Aが上位概念、Bが下位概念である、と言えます。
この状態を便宜的に「状態I」とします。


AとBの大小を固定しておいた場合、①>②>③という大小関係の他に、
①>③>②という場合も考えられます。
つまり、下の図のようになっているときです。この場合、AとBの関連は薄いと言えます。
この状態を便宜的に「状態II」とします。


発展

しかし、実際問題としては「①>②>③」と「①>③>②」をすっぱりと判定できるものではありません。
そこで、「A & B」を、A、Bそれぞれで割ることで正規化し、座標上にプロットしてみます。 (しばらく、NA>NBの場合を考えます。)

,


すると、状態Iは 


各辺をで割って、


つまり、 となり、

状態Iのときは上の網掛けの正方形部分にプロットされます。


同様に、状態IIのときは
が、
となり、
となります。

状態IIは上の網掛けの三角形部分にプロットされます。


そうなると気になるのが、

上の図の網掛け部分にプロットされるような場合です。

,
ベン図で表すなら、このような、AとBが重なってしまうような状況。

おそらく、文章を書く上での「揺れ」とみなされるような場合であると考えられます。
つまり、AとBは同意語と言えます。


(いったん)まとめ

2つのタグA,Bの関係を調べるのに、
,
を考えて座標上にプロットします。

a.にある時・・・AとBの関連は薄い
b.にある時・・・AはBの上位概念である
c.にある時・・・AとBは同意語


さらに考察

が、境界ですっぱりと分けてしまうのは多少乱暴な気もします。
「傾向が強い」「弱い」「可能性が高い」「低い」としておいたほうがよさそうです。
そこで、原点(0,0)からプロットした点(x,y)への距離Rと、
y=xと(0,0)-(x,y)のなす角度を考えてみます。


仮定

Rが大きいほど、AとBの関連度が高い。0〜R〜ルート2。
角度(θ)が+に大きいほど、AはBよりも上位の概念である可能性が高い。-45度〜θ〜45度

まとめ

タグの上位下位を決定できるような仮説を立てることができました。
実際にはてなブックマークのデータを使って実験したものがあるので、そのうち公開したいと思います。

[ソーシャルタギング]共起性尺度のまとめ

以前、taglaut.comというドメイン(現在はありません)で行なっていた、ソーシャルタギングのメモを発見したので公開しておきます。

共起の例と応用

ある人が、通販サイトからAという商品とBという商品を買った

多くの人が商品Aと商品Bを買っているなら、共起性尺度が高い、と言えます。
そこで、Aを買った人にBをおすすめ商品として紹介すれば、買ってもらえる可能性は高いです。
(amazon.comをよく使う人ならピンとくるでしょう)
出てくる結果はある意味で当たり前のことなので、それほどすごいとは感じないかもしれません。
例えば、釣竿を買う人なら釣り糸や餌・ルアー、釣り用ベストなどをおすすめすればいいというのは常識として分かります。
これを購買データの解析で自動で行えるというのがすごいところです。
また、誰も思いつかないような傾向が出てくるかもしれません。


ソーシャルブックマークで、あるページに対して、AというタグとBというタグが付けられた。

タグAとタグBの共起性尺度が高いなら、あるページにタグAがついた時点で、タグBもそのページにふさわしいだろうということが予想出来ます。


いろいろな共起性尺度

ここでは、ソーシャルブックマークでのタグ付けを念頭においています。
UがWebページの全体、
AがタグAがつけられたページの集合、NAがその個数、
BがタグBがつけられたページの集合、NBがその個数
です。
(同じページに同じタグが複数回付くこともありますが、ここでは考えていません。)

Jaccard係数

「AとBが共起した回数」割る「AとBの和集合」で求められます。

Simpson係数

「AとBが共起した回数」割る「A,Bの回数のうちの小さい方」で求められます。

Dice係数

「AとBが共起した回数」割る「A,Bの回数の平均」で求められます。


参考

[1]統計ソフトRのブログ 共起性尺度
[2]WEB+DB PRESS Vol.57 アルゴリズム実践教室【第2回】レコメンドエンジン開発に挑戦―関連記事を導き出すしくみを知る 伊藤直也
[3]類似度と距離 - CatTail Wiki*
[+]数式の表現にはCODECOGSのサービスを使っています。

2013年3月28日木曜日

[DIY]Nexus 7の押しにくい電源ボタンを改良

今更の感が強いですが、Nexus 7を買いました。
いろいろな方が言及されているように、電源ボタンが使いにくいです。
手探りで音量ボタンと区別が付くようにするために、ちょこっと手を加えて見ました。

写真だと見にくいですが、ブリスターパックのプラスチックを切って両面テープで貼りつけただけ。



端がチクチクするので黒のビニールテープを貼ったのが以下。


電源ボタンを考慮したカバーなどもあるんだろうけど、しばらくこれで。

明るい所で見ると裏側は焦げ茶というかえび色というか、そういう色なんですね。

2013年3月24日日曜日

mruby on Objective-C -スクリプトの実行を中断-

正しい使い方かどうかは分かりませんが、一応公開します。


前提

mruby-master/include/mrbconf.hでdefine ENABLE_DEBUG.
mruby VMがメインスレッド以外で実行されていること。


方針

ユーザーのアクションで、実行中のmruby VMのcode_fetch_hookに関数を登録。
その関数の中でエラーをraiseしてスクリプトの実行を中断。


viewController.h
#import <Foundation/Foundation.h>
#include "mruby.h"
#include "mruby/string.h"
#include "mruby/compile.h"
#include "mruby/class.h"
#include "mruby/value.h"
#include "mruby/proc.h"
#include "mruby/variable.h"
#include "mruby/array.h"

mrb_value mrb_printstr(mrb_state*, mrb_value);//別エントリで解説しています。
void mrb_interrupt(mrb_state*, mrb_irep*, mrb_code*, mrb_value*);

@interface viewController : UIViewController{
    NSOperationQueue *_queue;
    NSBlockOperation *_operation;
    struct mrb_state *_mrb;
}
-(void)mrbInitPrint;//別エントリで解説しています。
-(void)mrbRun:(NSString *)code;//別エントリで解説しています。
-(IBAction)mrbQuit;
@end


viewController.m
必要なコードのみ書いてあります。
void mrb_interrupt(mrb_state *mrb, mrb_irep *irep, mrb_code *pc, mrb_value *regs){
    //code_fetch_hookにすぐにNULLを代入するので、この関数は1回だけ呼ばれます。
    //エラーをraiseするとスクリプトが中断するので意味はないですが、
    //他の処理を割りこませることもできます。
    mrb->code_fetch_hook = NULL;
    mrb_raise(mrb, E_RUNTIME_ERROR, "interrupted");
}

@implementation viewController
-(IBAction)mrbQuit{
    if(_mrb){ _mrb->code_fetch_hook = mrb_interrupt; }
}
@end
UIButtonのtouch up insideなどにOutletしてください。

mruby on Objective-C - puts,pをUITextViewに出力-

方針

__printstr__を(Objective-)Cで実装し、それを使ってRubyでp,puts,print,printfを定義する。
mrubyのメソッドとして使うCの関数から、AppDelegate経由でUITextViewにアクセス。


参考



Rubyのスクリプトをプロジェクトに追加しておきます。

print.rb
module Kernel
# needs __printstr__
  def print(*args)
    i = 0
    len = args.size
    while i < len
      __printstr__ args[i].to_s
      i += 1
    end
  end
  def puts(*args)
    i = 0
    len = args.size
    while i < len
      s = args[i].to_s
      __printstr__ s
      __printstr__ "\n" if (s[-1] != "\n")
      i += 1
    end
    __printstr__ "\n" if len == 0
    nil
  end
  def p(*args)
    i = 0
    len = args.size
    while i < len
      __printstr__ args[i].inspect
      __printstr__ "\n"
      i += 1
    end
    args[0]
  end
  def printf(*args)
    __printstr__(sprintf(*args))
    nil
  end
end


あとは、Objective-Cを編集します。
DelegateへのUITextViewの登録、実行するRubyスクリプトの取得などは省略してあります。
また、puts,p,print,printfの度にUITextViewにsetText:するので、最後の出力しか残りません。
クラスを拡張してaddText:のようなメソッドを定義したほうが便利なはずです。


viewController.h
#import <Foundation/Foundation.h>
#include "mruby.h"
#include "mruby/string.h"
#include "mruby/compile.h"
#include "mruby/class.h"
#include "mruby/value.h"
#include "mruby/proc.h"
#include "mruby/variable.h"
#include "mruby/array.h"

mrb_value mrb_printstr(mrb_state*, mrb_value);
void mrb_interrupt(mrb_state*, mrb_irep*, mrb_code*, mrb_value*);//別エントリで解説します。

@interface viewController : UIViewController{
    NSOperationQueue *_queue;
    NSBlockOperation *_operation;
    struct mrb_state *_mrb;
}
-(void)mrbInitPrint;
-(void)mrbRun:(NSString *)code;
-(IBAction)mrbQuit;//別エントリで解説します。
@end


viewController.m
//mruby-master/src/print.cからコピペしました。
mrb_value mrb_printstr(mrb_state *mrb, mrb_value self_){
    mrb_value argv;
    mrb_get_args(mrb, "o", &argv);
    struct RString *str;
    char *s;
    int len;
    if(mrb_string_p(argv)){
        str = mrb_str_ptr(argv);
        s = str->ptr;
        len = str->len;
        //以下3行を環境に応じて書き換えてください。
        AppDelegate *appDel = [[UIApplication sharedApplication] delegate];
        UITextView *targetView = appDel.targetTextView;
        [targetView performSelectorOnMainThread:@selector(setText:) withObject:[NSString stringWithFormat:@"%s",s] waitUntilDone:YES];
    }
    return argv;
}
@implementation viewController
-(void)mrbInitPrint{
    //Kernelにp,puts,print,printfの定義に使う__printstr__を登録します。
    struct RClass *krn;
    krn = _mrb->kernel_module;
    mrb_define_method(_mrb, krn, "__printstr__", mrb_printstr, ARGS_REQ(1));

    //プロジェクトにバンドルしたprint.rbを読み込み、mrubyにロードします。
    NSError *error = nil;
    NSString *script_str;
    NSString *path = [[NSBundle mainBundle] pathForResource:[scripts objectAtIndex:i] ofType:@"rb"];
    NSString *print_rb_str = [NSString stringWithContentsOfFile:path encoding:NSUTF8StringEncoding error:&error];
    if(!error){
        mrb_load_string(_mrb, [print_rb_str cStringUsingEncoding:NSUTF8StringEncoding]);
    }
}
-(void)mrbRun:(NSString *)c{
    //mruby VMの実行を別スレッドにしている以外は、参考URLの通りです。
    if([_operation isExecuting]){ return; }
    __block NSString *code = [c copy];
    if(!_queue){
        _queue = [[NSOperationQueue alloc] init];
    }
    _operation = [[NSBlockOperation alloc] init];
    [_operation addExecutionBlock:^{
        const char *codeStr = [code cStringUsingEncoding:NSUTF8StringEncoding];
        mrbc_context *ctx;
        _mrb = mrb_open();

        [self mrbInitPrint];

        ctx = mrbc_context_new(_mrb);
        struct mrb_parser_state *st = mrb_parse_string(_mrb, codeStr, ctx);
        int gen_code_num = mrb_generate_code(_mrb, st);
        mrb_pool_close(st->pool);
        mrb_value result = mrb_run(_mrb, mrb_proc_new(_mrb,_mrb->irep[gen_code_num]), mrb_nil_value());
        if(_mrb->exc){//catch exception
            mrb_value r = mrb_funcall(_mrb, result, "inspect", 0);
            if(mrb_string_p(r)){
                struct RString *str = mrb_str_ptr(r);
                NSLog(@"%s",str->ptr);
            }
        }
        mrb_close(_mrb);
        mrbc_context_free(_mrb, ctx);
        _mrb = NULL;
        [_operation release];
        _operation = nil;
        [code release];
    }];
    [_queue addOperation:_operation];
}

mruby on Objective-C -アプリに組み込む-

mrubyを使ったアプリをsubmitしたので、メモをちまちまと放出。
実機でしか動きませんのであしからず。ツッコミ大歓迎。

環境

  • Mac OS X 10.6.8 Snow Leopard
  • Xcode4.2
  • ARC不使用
  • iPad2
  • iOS6.1
  • mruby (2013/02/17にソース取得)


方針

armv7向けにコンパイルしたmrubyの静的ライブラリを作り、それを直接Xcodeプロジェクトにコピーして使う。


build_config.rbを編集

mruby-master/build_config.rbのクロスコンパイル部分を以下のように編集します。
# Define cross build settings
 MRuby::CrossBuild.new('32bit') do |conf|
   isysroot = "/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS5.1.sdk/usr/include"
   conf.cc.command = "clang"
   conf.cc.flags << "-arch armv7"
   conf.cc.include_paths << isysroot
   conf.cc.include_paths << "#{root}/include"
 end


mrbconf.hを編集

mruby-master/include/mrbconf.hを編集します。
#define DISABLE_STDIO    /* use of stdio */
#define ENABLE_DEBUG     /* hooks for debugger */
STDIOを無効にします。
有効のままでも動きましたが、putsを使ったら落ちました。
DEBUGを有効にします。
これは、スクリプトの実行を中断するのに使っています。


make

コマンドライン上でmruby-masterに移動し、makeします。
途中でRakeが落ちますが、
mruby-master/build/32bit/lib/libmruby.a
が生成されているのでOKとします。(そのうちrake勉強せな)


プロジェクトを新規作成、必要ファイルをコピー

Xcodeで新しいプロジェクト(project_name)を作成し、mrubyのファイルをFinder上でコピーします。
mruby-master/include/をフォルダごとコピーして、そこにlibmruby.aを追加する感じです。
includeのままだと分かりにくいので、mrubyにリネームしました。
project_name/
|--project_name.xcodeproj
|--project_name/
   |--mruby/ 
   |  |--mrbconf.h
   |  |--mruby.h
   |  |--libmruby.a
   |  |--mruby/
   |     |--array.h
   |     |--class.h
   |         .
   |         .
   |     |--value.h
   |     |--variable.h
   |--viewController.h
   |--viewController.m
   |   .
   |   .   
Finder上でコピーしたあと、Xcode上の左ペインにドラッグ・アンド・ドロップして、プロジェクトに追加します。


パスの設定

Build SettingsのHeader Search PathLibrary Search Path
"$(SRCROOT)/project_name/mruby"
を追加します。
Recursiveはなしで。


以上で、iOSアプリでmrubyを使う準備は完了です。