2007-06-22
■[ode][ruby]rubyで3D物理シミュレーション
rubyからODEを使えるようになったのでとりあえずうp。
http://ssktkr.com/ode-ruby5.tgz
こんなソースで3Dシミュレーションできます!
require "ode" require "draw_stuff" require "pp" require "dl" $world = Ode::World.new $world.gravity = [0.0, 0.0, -0.2] # 重力設定 $space = Ode_lib.dHashSpaceCreate(nil); # 衝突用空間の創造 $contactgroup = Ode_lib.dJointGroupCreate(0); # ジョイントグループの生成 $ground = Ode_lib.dCreatePlane($space, 0,0, 1.0, 0.0); # 平面ジオメトリの生成 def rand_within(from, to) rand*(to-from)+from end $objects = [] 100.times{ $objects << Ode::Material::Ball.new(:m=>rand_within(1,9), :r=>rand_within(1,5), :position=>[rand_within(-7,7), rand_within(-7,7), rand_within(5,500)], :color=>[rand(2).to_f, rand(2).to_f, rand(2).to_f] ) } $objects << Ode::Material::Box.new(:m=>1000.0, :x=>10.0, :y=>50.0, :z=>50.0, :position=> [-30.0, 0.0, 30.0], :color => [0.3, 0.0, 0.0] ) ds = DrawStuff.new ds.world = $world ds.width = 800 ds.height = 600 ds.path_to_textures = "../drawstuff/textures" def ds.start puts "start" xyz = [ 50.0, 0.0, 1.0] # 視点の位置 hpr = [-180.0, 20.0, 0.0] # 視線の方向 DrawStuff::DSLib.dsSetViewpoint(xyz.to_ptr("F"), hpr.to_ptr("F")) # カメラの設定 end def ds.step(pause) @step_count += 1 if @step_count%5000==0 puts "==============================================" puts "step #{pause} #{@step_count}" xyz = [0.0, 0.0, 0.0].to_ptr("F") # 視点の位置 hpr = [0.0, 0.0, 0.0].to_ptr("F") # 視線の方向 DrawStuff::DSLib.dsGetViewpoint(xyz, hpr) puts "xyz = " + xyz.to_a("F").inspect puts "hpr = " + hpr.to_a("F").inspect end Ode_lib.dSpaceCollide($space, Proc.new{|o1,o2| # puts "cb #{o1._ptr} #{o2._ptr} #{$ground._ptr} #{$ground._ptr==o1._ptr} #{$ground._ptr==o2._ptr}" # 衝突検出 #if $ground._ptr==o1._ptr || $ground._ptr==o2._ptr contact_geoms = Ode_lib.dCollide(o1, o2, 10000) # 衝突情報の生成 contact_geoms.each do |cg| # pp cg contact = Ode_lib::DContact.new contact.geom = cg contact.surface.mode = Ode_lib::DContactBounce; # 接触面の反発性を設定 contact.surface.bounce = 0.8; # 反発係数(0.0から1.0) contact.surface.bounce_vel = 1.0; # 反発に必要な最低速度 # 接触ジョイントの生成 joint = Ode_lib.dJointCreateContact($world._id, $contactgroup, contact) # 接触している2つの剛体を接触ジョイントにより拘束 Ode_lib.dJointAttach(joint, Ode_lib.dGeomGetBody(cg.g1), Ode_lib.dGeomGetBody(cg.g2)) end #end }); @world.step(0.05) Ode_lib.dJointGroupEmpty($contactgroup); # ジョイントグループを空にする $objects.each{|o| o.draw } end def ds.command(cmd) puts "command #{cmd}" end def ds.stop puts "stop" end ds.run
今回学んだ技術:
- SWIG
- Ruby/DL
- Rubyの中身を少々(Ruby Hacking Guideを読んだ)
- ODE この本がすごい!
簡単!実践!ロボットシミュレーション - Open Dynamics Engineによるロボットプログラミング
- 作者: 出村公成
- 出版社/メーカー: 森北出版
- 発売日: 2007/05/18
- メディア: 単行本(ソフトカバー)
- 購入: 5人 クリック: 89回
- この商品を含むブログ (10件) を見る
Wiiリモコンと組み合わせたら絶対たのしい。
■[wii][ruby]Wiiリモコン+Rubyのサンプル
require 'osx/cocoa'
OSX.require_framework "WiiRemote"
class WiiRemoconTest < OSX::NSObject
def initialize
@discovery = nil
@remote = nil
end
def init
@discovery = OSX::WiiRemoteDiscovery.alloc.init
@discovery.setDelegate(self)
@discovery.start
return self
end
def WiiRemoteDiscovered(remote)
puts "WiiRemoteDiscovered remote=#{remote.inspect}"
@remote = Remote.alloc.init
@remote.start(remote)
# @discovery.stop
end
def WiiRemoteDiscoveryError(code)
puts "WiiRemoteDiscoveryError code=%x" % code
end
objc_method :WiiRemoteDiscovered, %w{void id}
objc_method :WiiRemoteDiscoveryError, %w{void int}
end
class Remote < OSX::NSObject
def init
return self
end
def start(remote)
@remote = remote
@remote.setDelegate(self)
@remote.setMotionSensorEnabled(true)
@remote.setIRSensorEnabled(false)
end
# /Library/Frameworks/RubyCocoa.framework/Versions/A/Resources/ruby/osx/objc/oc_import.rb
# /Library/Frameworks/WiiRemote.framework/Headers/WiiRemote.h
def irPointMovedX_Y_wiiRemote(px, py, wiiRemote)
#puts "irPointMovedX_Y"
end
def buttonChanged_isPressed_wiiRemote(btn_type, is_pressed, wiiRemote)
puts "buttonChanged_isPressed #{btn_type} #{is_pressed}"
end
def accelerationChanged_accX_accY_accZ_wiiRemote(type, ax, ay, az, wiiRemote)
#p "accelerationChanged_accX_accY_accZ(%d,%d,%d,%d)" % [type,ax,ay,az]
#p "*" * (ax/2)
div = 3
s = (" " * (256/div))+"|"
s[ax/div] = "x"
s[ay/div] = "y"
s[az/div] = "z"
puts s
end
def joyStickChanged_tiltX_tiltY_wiiRemote(type, tilt_x, tilt_y, wiiRemote)
puts "joyStickChanged_tiltX_tiltY"
end
def wiiRemoteDisconnected(device)
puts "wiiRemoteDisconnected"
end
#- (void) irPointMovedX:(float)px Y:(float)py wiiRemote:(WiiRemote*)wiiRemote;
#- (void) rawIRData: (IRData[4])irData wiiRemote:(WiiRemote*)wiiRemote;
#- (void) buttonChanged:(WiiButtonType)type isPressed:(BOOL)isPressed wiiRemote:(WiiRemote*)wiiRemote;
#- (void) accelerationChanged:(WiiAccelerationSensorType)type accX:(unsigned char)accX accY:(unsigned char)accY accZ:(unsigned char)accZ wiiRemote:(WiiRemote*)wiiRemote;
#- (void) joyStickChanged:(WiiJoyStickType)type tiltX:(unsigned char)tiltX tiltY:(unsigned char)tiltY wiiRemote:(WiiRemote*)wiiRemote;
#- (void) analogButtonChanged:(WiiButtonType)type amount:(unsigned)press wiiRemote:(WiiRemote*)wiiRemote;
#- (void) wiiRemoteDisconnected:(IOBluetoothDevice*)device;
objc_method :irPointMovedX_Y_wiiRemote, %w{void float float id}
objc_method :buttonChanged_isPressed_wiiRemote, %w{void ushort char id}
objc_method :accelerationChanged_accX_accY_accZ_wiiRemote, %w{void ushort uchar uchar uchar id}
objc_method :joyStickChanged_tiltX_tiltY_wiiRemote, %w{void ushort uchar uchar id}
objc_method :wiiRemoteDisconnected, %w{void id}
end
test = WiiRemoconTest.alloc.init
OSX::NSRunLoop.currentRunLoop.run
■WiiRemote.frameworkをインストール。
で、
sudo mv WiiRemote.framework /Library/Frameworks/
インターフェイスが変わっていて前に作ったやつがうごかん。
■Hello, Ruby Cocoa
どっかから持ってきたサンプルで動作確認。
require 'osx/cocoa'
class HelloApp < OSX::NSObject
def quit(notifier)
exit
end
end
app = OSX::NSApplication.sharedApplication
app.setDelegate HelloApp.alloc.init
win = OSX::NSWindow.alloc.initWithContentRect_styleMask_backing_defer([200.0, 300.0, 250.0, 60.0], 15, 2, 0)
win.setTitle 'Hello RubyCocoa'
win.setLevel(3) # floating window
win.orderFrontRegardless
button = OSX::NSButton.alloc.initWithFrame([10.0, 10.0, 210.0, 40.0])
win.contentView.addSubview button
button.setBezelStyle 4
button.setTitle 'Hello, World!'
button.setTarget app.delegate
button.setAction 'quit:'
button.setEnabled true
app.run
おk。
■[ruby][cocoa]RubyCocoaインストール記録
バイナリパッケージをいれたら/usr/bin/rubyのほうに入ってしまった。
いつもつかってるのはportでいれた/opt/にあるやつなのでソースからインストール。
tkrmb:~/Desktop/RubyCocoa-0.11.1% ruby install.rb config
install.rb: entering config phase...
create ext/rubycocoa/extconf.rb
create framework/GeneratedConfig.xcconfig
create framework/src/objc/Version.h
---> framework
create /Users/takeru/Desktop/RubyCocoa-0.11.1/framework/src/objc/osx_ruby.h ...
create /Users/takeru/Desktop/RubyCocoa-0.11.1/framework/src/objc/osx_intern.h ...
BSROOT="/Users/takeru/Desktop/RubyCocoa-0.11.1/framework/bridge-support" CFLAGS="" /opt/local/bin/ruby build.rb
Generating BridgeSupport metadata for: CoreFoundation ...
Collect metadata (12.983316 seconds)
Write final metadata (165.017092 seconds)
Validate XML (0.829204 seconds)
Generate dylib file (4.263049 seconds)
Done (183.094969 seconds).
Generating BridgeSupport metadata for: CoreData ...
Collect metadata (5.338192 seconds)
Write final metadata (0.439494 seconds)
Validate XML (0.013119 seconds)
Done (5.79575 seconds).
Generating BridgeSupport metadata for: PDFKit ...
Collect metadata (7.611306 seconds)
Write final metadata (0.186546 seconds)
Validate XML (0.013643 seconds)
Done (7.816811 seconds).
Generating BridgeSupport metadata for: Foundation ...
Collect metadata (12.169901 seconds)
Write final metadata (46.748283 seconds)
Validate XML (0.029448 seconds)
Generate dylib file (0.739722 seconds)
Done (59.69456 seconds).
Generating BridgeSupport metadata for: CoreGraphics ...
Collect metadata (54.6267 seconds)
Write final metadata (89.165918 seconds)
Validate XML (0.279392 seconds)
Generate dylib file (0.588252 seconds)
Done (144.667176 seconds).
Generating BridgeSupport metadata for: InstantMessage ...
Collect metadata (5.853906 seconds)
Write final metadata (0.029686 seconds)
Validate XML (0.014123 seconds)
Done (5.903086 seconds).
Generating BridgeSupport metadata for: Quartz ...
Collect metadata (5.883848 seconds)
Write final metadata (0.006867 seconds)
Validate XML (0.012119 seconds)
Done (5.908422 seconds).
Generating BridgeSupport metadata for: ImageIO ...
Collect metadata (5.914733 seconds)
Write final metadata (0.115417 seconds)
Validate XML (0.01424 seconds)
Done (6.049777 seconds).
Generating BridgeSupport metadata for: Cocoa ...
Collect metadata (6.183535 seconds)
Write final metadata (0.005757 seconds)
Validate XML (0.011465 seconds)
Done (6.207085 seconds).
Generating BridgeSupport metadata for: OpenGL ...
Collect metadata (10.013917 seconds)
Write final metadata (1.828747 seconds)
Validate XML (0.051416 seconds)
Done (11.901694 seconds).
Generating BridgeSupport metadata for: QuartzComposer ...
Collect metadata (9.726545 seconds)
Write final metadata (0.021444 seconds)
Validate XML (0.014132 seconds)
Done (9.767429 seconds).
Generating BridgeSupport metadata for: ApplicationServices ...
Collect metadata (4.415054 seconds)
Write final metadata (0.014068 seconds)
Validate XML (0.013584 seconds)
Done (4.447495 seconds).
Generating BridgeSupport metadata for: QuartzCore ...
Collect metadata (24.518391 seconds)
Write final metadata (4.964294 seconds)
Validate XML (0.01691 seconds)
Done (29.504879 seconds).
Generating BridgeSupport metadata for: SyncServices ...
Collect metadata (12.531122 seconds)
Write final metadata (0.319699 seconds)
Validate XML (0.014041 seconds)
Done (12.870431 seconds).
Generating BridgeSupport metadata for: AppKit ...
Collect metadata (53.684602 seconds)
Write final metadata (83.972944 seconds)
Validate XML (0.28991 seconds)
Generate dylib file (1.237285 seconds)
Done (139.192725 seconds).
Generating BridgeSupport metadata for: AddressBook ...
Collect metadata (18.341418 seconds)
Write final metadata (0.775136 seconds)
Validate XML (0.017448 seconds)
Done (19.140541 seconds).
Generating BridgeSupport metadata for: WebKit ...
Collect metadata (43.266885 seconds)
Write final metadata (10.299582 seconds)
Validate XML (0.274515 seconds)
Done (53.847364 seconds).
Generating BridgeSupport metadata for: QTKit ...
Collect metadata (25.314914 seconds)
Write final metadata (2.986737 seconds)
Validate XML (0.01777 seconds)
Done (28.32868 seconds).
<--- framework
---> lib
---> lib/osx
<--- lib/osx
<--- lib
---> ext
---> ext/rubycocoa
/opt/local/bin/ruby "/Users/takeru/Desktop/RubyCocoa-0.11.1/ext/rubycocoa/extconf.rb"
creating Makefile
execute 'mv -f Makefile Makefile.bak' ...
execute 'mv -f Makefile Makefile.bak' done
execute 'sed -e 's/-no-cpp-precomp//' -e 's/-no-precomp//' Makefile.bak > Makefile' ...
execute 'sed -e 's/-no-cpp-precomp//' -e 's/-no-precomp//' Makefile.bak > Makefile' done
<--- ext/rubycocoa
<--- ext
install.rb: config done.
tkrmb:~/Desktop/RubyCocoa-0.11.1%

