├── 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 --------------------------------------------------------------------------------