├── README.md
├── examples
├── accelerometer_reading.rb
├── inspect.rb
├── led_colors.rb
└── motor_control.rb
└── lib
├── rinect.rb
└── rinect
├── device.rb
└── devices
├── accelerometer.rb
├── led.rb
└── motor.rb
/README.md:
--------------------------------------------------------------------------------
1 |
Rinect
2 | Rinect aims to be a pure ruby implementation (libusb requirement only) of a Microsoft Kinect driver. It will let you control and access all aspects of the Kinect via a Ruby interface.
3 |
4 | Functionality is very limited right now since this project is so new, but full control is the final goal.
5 |
6 | Requirements
7 | * ruby-usb (https://github.com/akr/ruby-usb)
8 |
9 | If you're running Mac OSX, this guide may help you get ruby-usb working: http://www.jedi.be/blog/2009/11/11/ruby-usb-libusb/
10 |
11 | Current status
12 | What we can do:
13 | * Support for multiple devices
14 | * Control the motor
15 | * Control the LED
16 | * Read the accelerometer
17 |
18 | What we can not do yet:
19 |
20 | * Read an RGB image
21 | * Read a depth image
22 |
--------------------------------------------------------------------------------
/examples/accelerometer_reading.rb:
--------------------------------------------------------------------------------
1 | require '../lib/rinect'
2 |
3 | motor = Rinect::Motor.new(0).connect
4 | accel = Rinect::Accelerometer.new(0).connect
5 |
6 | motor.set(0)
7 | p motor.to_s
8 | accel.get
9 | p accel.to_s
10 | sleep 3
11 |
12 | motor.set(-10)
13 | sleep 3
14 | p motor.to_s
15 | accel.get
16 | p accel.to_s
17 | sleep 3
18 |
19 | motor.set(10)
20 | sleep 3
21 | p motor.to_s
22 | accel.get
23 | p accel.to_s
24 | sleep 3
25 |
26 | motor.set(0)
--------------------------------------------------------------------------------
/examples/inspect.rb:
--------------------------------------------------------------------------------
1 | require '../lib/rinect'
2 |
3 | motor = Rinect::Motor.new
4 |
5 | puts motor.inspect
--------------------------------------------------------------------------------
/examples/led_colors.rb:
--------------------------------------------------------------------------------
1 | require '../lib/rinect'
2 |
3 | led = Rinect::LED.new(0).connect
4 |
5 | led.set(:red)
6 | puts led.to_s
7 |
8 | sleep 2
9 |
10 | led.set(:green)
11 | puts led.to_s
12 |
13 | sleep 2
14 |
15 | led.set(:blink_red_yellow)
16 | puts led.to_s
17 |
18 | sleep 2
19 |
20 | led.set(:green)
21 |
--------------------------------------------------------------------------------
/examples/motor_control.rb:
--------------------------------------------------------------------------------
1 | require '../lib/rinect'
2 |
3 | #prints devices serials
4 | Rinect::Device.get_serials()
5 |
6 | #access first kinect device available
7 | motor = Rinect::Motor.new(0).connect
8 | motor.set(0)
9 | puts motor.to_s
10 | sleep 2
11 |
12 | #access specified device serial
13 | motor = Rinect::Motor.new({:devID=>'A00364A16016051A'}).connect
14 |
15 | #access n-th device
16 | motor = Rinect::Motor.new(0).connect
17 |
18 | motor.set(0)
19 | puts motor.to_s
20 |
21 | sleep 2
22 |
23 | motor1 = Rinect::Motor.new(1).connect
24 |
25 | motor1.set(10)
26 | puts motor1.to_s
27 |
28 | sleep 2
29 | #puts motor.read_accelerometer.inspect
30 |
--------------------------------------------------------------------------------
/lib/rinect.rb:
--------------------------------------------------------------------------------
1 | module Rinect; end
2 |
3 | # Helper for Rails < 1.9.x
4 | def require_local(path)
5 | require(File.expand_path(File.join(File.dirname(__FILE__), path)))
6 | end
7 |
8 | # Include standard libraries
9 | require 'rubygems'
10 | require 'usb'
11 |
12 | # Include Rinect files
13 | require_local 'rinect/device'
14 | require_local 'rinect/devices/led'
15 | require_local 'rinect/devices/motor'
16 | require_local 'rinect/devices/accelerometer'
17 |
18 |
--------------------------------------------------------------------------------
/lib/rinect/device.rb:
--------------------------------------------------------------------------------
1 | module Rinect
2 | module Device
3 | attr_accessor :set
4 | attr_reader :connect, :get
5 |
6 | DEVICES = {
7 | 'Rinect::LED' => 0x02b0,
8 | 'Rinect::Motor' => 0x02b0,
9 | 'Rinect::Accelerometer' => 0x02b0
10 | }
11 |
12 | def self.get_serials()
13 | USB.devices.each do |d|
14 | puts 'device'
15 | if(d.idVendor == 0x045e && d.idProduct==0x02b0) then
16 | puts d.serial_number()
17 | end
18 | end
19 | end
20 |
21 | def initialize(args={})
22 | if args.class != Fixnum && args.length == 0 then
23 | @device ||= USB.devices.select {|d| d.idVendor == 0x045e && d.idProduct == DEVICES[self.class.to_s] }.first
24 | else
25 | if args.class != Fixnum && args[:devID] != nil then
26 | @device ||= USB.devices.select {|d| d.serial_number() == args[:devID] }.first
27 | else
28 | @device ||= USB.devices.select {|d| d.idVendor == 0x045e && d.idProduct == DEVICES[self.class.to_s]}[args]
29 | end
30 | end
31 | @handle = nil
32 | @state = :off
33 | end
34 |
35 | #def initialize(devID)
36 | # @device ||= USB.devices.select {|d| d.idVendor == 0x045e && d.idProduct == DEVICES[self.class.to_s] }[devID]
37 | #
38 | # @handle = nil
39 | # @state = :off
40 | #end
41 |
42 | def inspect
43 | @device.inspect
44 | end
45 |
46 | def connect
47 | raise IOError, "Kinect not found/not connected." if @device.nil?
48 |
49 | @handle ||= @device.usb_open
50 | self
51 | end
52 | end
53 | end
54 |
--------------------------------------------------------------------------------
/lib/rinect/devices/accelerometer.rb:
--------------------------------------------------------------------------------
1 | module Rinect
2 | class Accelerometer
3 | #see http://fivedots.coe.psu.ac.th/~ad/jg/nui16/motorControl.pdf [page 11]
4 |
5 | include Rinect::Device
6 |
7 | GRAVITY = 9.80665
8 | COUNTS_PER_G = 819.0
9 | JOINT_STATES = {
10 | 0 => :stopped,
11 | 1 => :at_limit,
12 | 4 => :moving
13 | }
14 |
15 | def get
16 | data = "\0" * 10
17 | ret = @handle.usb_control_msg 0xC0, 0x32, 0x0000, 0x0000, data, 10
18 | raise "read wrong number of bytes"+ret.to_s if ret != 10
19 | @state = {:x => ((data[2].unpack('c').first << 8 ) | data[3].unpack('c').first).to_f / COUNTS_PER_G * GRAVITY,
20 | :y => ((data[4].unpack('c').first << 8 ) | data[5].unpack('c').first).to_f / COUNTS_PER_G * GRAVITY,
21 | :z => ((data[6].unpack('c').first << 8 ) | data[7].unpack('c').first).to_f / COUNTS_PER_G * GRAVITY,
22 | :tilt_angle => data[8].unpack('c').first,
23 | :tilt_status => JOINT_STATES[data[9].unpack('C').first]}
24 | end
25 |
26 | def to_s
27 | "Current accelerometer state: #{@state.to_a.collect{|e| "#{e[0]}=#{e[1]}"}.join(', ')}"
28 | end
29 | end
30 | end
31 |
32 |
--------------------------------------------------------------------------------
/lib/rinect/devices/led.rb:
--------------------------------------------------------------------------------
1 | module Rinect
2 | class LED
3 | include Rinect::Device
4 |
5 | LED_STATES = {
6 | :off => 0,
7 | :green => 1,
8 | :red => 2,
9 | :yellow => 3,
10 | :blink_yellow => 4,
11 | :blink_green => 5,
12 | :blink_red_yellow => 6,
13 | :blink_red_green => 7
14 | }
15 |
16 | def set(state)
17 | throw ArgumentError, "Invalid LED state given" unless LED_STATES.has_key? state
18 |
19 | @state = state
20 | @handle.usb_control_msg 0x40, 0x06, LED_STATES[state], 0x0000, '', 0
21 | end
22 |
23 | def get
24 | @state
25 | end
26 |
27 | def to_s
28 | "Current LED state: #{@state.to_s}"
29 | end
30 | end
31 | end
--------------------------------------------------------------------------------
/lib/rinect/devices/motor.rb:
--------------------------------------------------------------------------------
1 | module Rinect
2 | class Motor
3 | include Rinect::Device
4 |
5 | def set(pitch)
6 | pitch = -35 if pitch < -35
7 | pitch = 55 if pitch > 55
8 |
9 | @handle.usb_control_msg 0x40, 0x31, pitch, 0x0000, '', 0
10 |
11 | @state = pitch
12 | end
13 |
14 | def get
15 | @state
16 | end
17 |
18 | def to_s
19 | "Current pitch: #{@state.to_s}"
20 | end
21 | end
22 | end
--------------------------------------------------------------------------------