1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208
|
require 'ffi/freenect'
require 'freenect/context'
module Freenect
RawTiltState = FFI::Freenect::RawTiltState
class DeviceError < StandardError
end
class Device
# Returns a device object tracked by its ruby object reference ID stored
# in user data.
#
# This method is intended for internal use.
def self.by_reference(devp)
unless devp.null? or (refp=FFI::Freenect.freenect_get_user(devp)).null?
obj=ObjectSpace._id2ref(refp.read_long_long)
return obj if obj.is_a?(Device)
end
end
def initialize(ctx, idx)
dev_p = ::FFI::MemoryPointer.new(:pointer)
@ctx = ctx
if ::FFI::Freenect.freenect_open_device(@ctx.context, dev_p, idx) != 0
raise DeviceError, "unable to open device #{idx} from #{ctx.inspect}"
end
@dev = dev_p.read_pointer
save_object_id!()
end
def closed?
@ctx.closed? or (@dev_closed == true)
end
def close
unless closed?
if ::FFI::Freenect.freenect_close_device(@dev) == 0
@dev_closed = true
end
end
end
def device
if closed?
raise DeviceError, "this device is closed and can no longer be used"
else
return @dev
end
end
def context
@ctx
end
def get_tilt_state
unless (p=::FFI::Freenect.freenect_get_tilt_state(self.device)).null?
return RawTiltState.new(p)
else
raise DeviceError, "freenect_get_tilt_state() returned a NULL tilt_state"
end
end
alias tilt_state get_tilt_state
# Returns the current tilt angle
def get_tilt_degrees
::FFI::Freenect.freenect_get_tilt_degs(self.device)
end
alias tilt get_tilt_degrees
# Sets the tilt angle.
# Maximum tilt angle range is between +30 and -30
def set_tilt_degrees(angle)
::FFI::Freenect.freenect_set_tilt_degs(self.device, angle)
return(update_tilt_state() < 0) # based on libfreenect error cond. as of 12-21-10
end
alias tilt= set_tilt_degrees
# Defines a handler for depth events.
#
# @yield [device, depth_buf, timestamp]
# @yieldparam device A pointer to the device that generated the event.
# @yieldparam depth_buf A pointer to the buffer containing the depth data.
# @yieldparam timestamp A timestamp for the event?
def set_depth_callback(&block)
@depth_callback = block
::FFI::Freenect.freenect_set_depth_callback(self.device, @depth_callback)
end
alias on_depth set_depth_callback
# Defines a handler for video events.
#
# @yield [device, video_buf, timestamp]
# @yieldparam device A pointer to the device that generated the event.
# @yieldparam video_buf A pointer to the buffer containing the video data.
# @yieldparam timestamp A timestamp for the event?
def set_video_callback(&block)
@video_callback = block
::FFI::Freenect.freenect_set_video_callback(self.device, @video_callback)
end
alias on_video set_video_callback
def start_depth
unless(::FFI::Freenect.freenect_start_depth(self.device) == 0)
raise DeviceError, "Error in freenect_start_depth()"
end
end
def stop_depth
unless(::FFI::Freenect.freenect_stop_depth(self.device) == 0)
raise DeviceError, "Error in freenect_stop_depth()"
end
end
def start_video
unless(::FFI::Freenect.freenect_start_video(self.device) == 0)
raise DeviceError, "Error in freenect_start_video()"
end
end
def stop_video
unless(::FFI::Freenect.freenect_stop_video(self.device) == 0)
raise DeviceError, "Error in freenect_stop_video()"
end
end
def set_depth_mode(mode)
mode = Freenect.depth_mode(:medium, mode) unless mode.is_a?(Freenect::FrameMode)
raise ArgumentError, "Unkown depth mode #{mode}" if mode.nil?
ret = ::FFI::Freenect.freenect_set_depth_mode(self.device, mode)
raise DeviceError, "Error calling freenect_set_depth_mode(self, #{mode}) returned #{ret}" unless ret == 0
end
alias depth_mode= set_depth_mode
# returns the symbolic constant for the current depth format
def depth_mode
x = ::FFI::Freenect.freenect_get_current_depth_mode(self.device)
x = nil if x.height*x.width == 0 or x.framerate == 0
x.frame_mode_type = :depth unless x.nil?
x
end
# Sets the video format to one of the following accepted values:
#
def set_video_mode(mode)
mode = Freenect.video_mode(:medium, mode) unless mode.is_a?(Freenect::FrameMode)
raise ArgumentError, "Unkown video mode #{mode}" if mode.nil?
ret = ::FFI::Freenect.freenect_set_video_mode(self.device, mode)
raise DeviceError, "Error calling freenect_set_video_mode(self, #{mode}) returned #{ret}" unless ret == 0
end
alias video_mode= set_video_mode
def video_mode
x = ::FFI::Freenect.freenect_get_current_video_mode(self.device)
x = nil if x.height*x.width == 0 or x.framerate == 0
x.frame_mode_type = :video unless x.nil?
x
end
# Sets the led to one of the following accepted values:
# :off, Freenect::LED_OFF
# :green, Freenect::LED_GREEN
# :red, Freenect::LED_RED
# :yellow, Freenect::LED_YELLOW
# :blink_yellow, Freenect::LED_BLINK_YELLOW
# :blink_green, Freenect::LED_BLINK_GREEN
# :blink_red_yellow, Freenect::LED_BLINK_RED_YELLOW
#
# Either the symbol or numeric constant can be specified.
def set_led(mode)
return(::FFI::Freenect.freenect_set_led(self.device, mode) == 0)
end
alias led= set_led
def reference_id
unless (p=::FFI::Freenect.freenect_get_user(device)).null?
p.read_long_long
end
end
private
def set_depth_buffer(buf)
end
def set_video_buffer(buf)
end
def save_object_id!
objid_p = FFI::MemoryPointer.new(:long_long)
objid_p.write_long_long(self.object_id)
::FFI::Freenect.freenect_set_user(self.device, objid_p)
end
def update_tilt_state
::FFI::Freenect.freenect_update_tilt_state(self.device)
end
end
end
|