Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

Merge branch 'master' of https://github.com/marshally/ball_of_light

Conflicts:
	.gitignore
  • Loading branch information...
commit a8827a9d88b91d1b84e87b5665b3022ad0411f40 2 parents 5e11635 + fccd0da
@ryanabrams authored
Showing with 510 additions and 172 deletions.
  1. +2 −0  .gitignore
  2. +67 −9 Calibration.md
  3. +10 −12 Gemfile
  4. +6 −4 Gemfile.lock
  5. +1 −7 Guardfile
  6. +22 −6 bin/add_gestures.rb
  7. +1 −1  bin/ball_of_light
  8. +8 −4 bin/kinectable_pipe_sim
  9. +96 −5 bin/run_light_script
  10. +6 −6 gestures/count_users.rb
  11. +7 −6 gestures/pointing.rb
  12. +12 −8 lib/ball_of_light/ball_of_light_controller.rb
  13. +2 −0  lib/ball_of_light/cli.rb
  14. +26 −26 lib/ball_of_light/cli/calibrate.rb
  15. +2 −2 lib/ball_of_light/cli/kinect.rb
  16. +4 −2 lib/ball_of_light/io_helper.rb
  17. +6 −5 lib/ball_of_light/joint.rb
  18. +30 −6 lib/ball_of_light/user.rb
  19. +50 −45 scripts/1.rb
  20. +13 −3 scripts/chase.rb
  21. +15 −12 scripts/factory.rb
  22. +9 −2 scripts/heartbeat.rb
  23. +1 −1  scripts/hug.rb
  24. +1 −0  scripts/spiral.rb
  25. +113 −0 spec/fixtures/123.json
  26. BIN  vendor/cache/bundler-1.1.5.gem
  27. BIN  vendor/cache/ffi-1.1.4.gem
  28. BIN  vendor/cache/ffi-1.1.5.gem
  29. BIN  vendor/cache/growl-1.0.3.gem
  30. BIN  vendor/cache/open_lighting-0.1.2.gem
  31. BIN  vendor/cache/open_lighting-0.1.3.gem
  32. BIN  vendor/cache/rspec-mocks-2.11.1.gem
  33. BIN  vendor/cache/rspec-mocks-2.11.2.gem
View
2  .gitignore
@@ -14,6 +14,8 @@ vendor/bundle
# Sublime Text 2 crap
*.sublime-*
+*.png
+*.log
# YARD artifacts
.yardoc
View
76 Calibration.md
@@ -4,19 +4,77 @@
ball_of_light calibrate
```
+The Ball of Light supports two different calibration routines: Point Calibration
+and Auto Calibration. Using Point Calibration, we can label
+
+Recommended floor points to calibrate: front (closest to the Kinect), back
+(farthest from the Kinect), left, right, and bottom (direct center of the
+floor).
+
This will begin the `ball_of_light` test sequence. There are 9 or more calibration points per light, so this will take between 15m and 1h for 12 lights. Depending on how quickly you move.
```
-→ bin/ball_of_light calibrate
-What is the name of your point? awesomeness
-Which light to calibrate? [1-12, (n)ext [1] or (q)uit] 1
+→ ball_of_light calibrate points
+
+What is the name of your point? back
+
+Which light to calibrate? [1-12, (n)ext [1] or (q)uit]
+calibrating light 1
+Press (a/d) to pan and (w/s) to tilt. <space/enter> to save or (q)uit/ESC
+saving light 1 back position {:pan=>181, :tilt=>28}
+
+Which light to calibrate? [1-12, (n)ext [2] or (q)uit]
+calibrating light 2
+Press (a/d) to pan and (w/s) to tilt. <space/enter> to save or (q)uit/ESC
+saving light 2 back position {:pan=>76, :tilt=>40}
+
+Which light to calibrate? [1-12, (n)ext [3] or (q)uit]
+calibrating light 3
+Press (a/d) to pan and (w/s) to tilt. <space/enter> to save or (q)uit/ESC
+saving light 3 back position {:pan=>3, :tilt=>187}
+
+Which light to calibrate? [1-12, (n)ext [4] or (q)uit]
+calibrating light 4
+Press (a/d) to pan and (w/s) to tilt. <space/enter> to save or (q)uit/ESC
+saving light 4 back position {:pan=>234, :tilt=>58}
+
+Which light to calibrate? [1-12, (n)ext [5] or (q)uit]
+calibrating light 5
Press (a/d) to pan and (w/s) to tilt. <space/enter> to save or (q)uit/ESC
-saving light 1 awesomeness position {:pan=>116, :tilt=>123}
-Which light to calibrate? [1-12, (n)ext [2] or (q)uit] n
+saving light 5 back position {:pan=>125, :tilt=>82}
+
+Which light to calibrate? [1-12, (n)ext [6] or (q)uit]
+calibrating light 6
+Press (a/d) to pan and (w/s) to tilt. <space/enter> to save or (q)uit/ESC
+saving light 6 back position {:pan=>79, :tilt=>75}
+
+Which light to calibrate? [1-12, (n)ext [7] or (q)uit]
+calibrating light 7
+Press (a/d) to pan and (w/s) to tilt. <space/enter> to save or (q)uit/ESC
+saving light 7 back position {:pan=>116, :tilt=>10}
+
+Which light to calibrate? [1-12, (n)ext [8] or (q)uit]
+calibrating light 8
+Press (a/d) to pan and (w/s) to tilt. <space/enter> to save or (q)uit/ESC
+saving light 8 back position {:pan=>166, :tilt=>72}
+
+Which light to calibrate? [1-12, (n)ext [9] or (q)uit]
+calibrating light 9
+Press (a/d) to pan and (w/s) to tilt. <space/enter> to save or (q)uit/ESC
+saving light 9 back position {:pan=>127, :tilt=>103}
+
+Which light to calibrate? [1-12, (n)ext [10] or (q)uit]
+calibrating light 10
Press (a/d) to pan and (w/s) to tilt. <space/enter> to save or (q)uit/ESC
-saving light 2 awesomeness position {:pan=>143, :tilt=>119}
-Which light to calibrate? [1-12, (n)ext [3] or (q)uit] n
+saving light 10 back position {:pan=>103, :tilt=>115}
+
+Which light to calibrate? [1-12, (n)ext [11] or (q)uit]
+calibrating light 11
+Press (a/d) to pan and (w/s) to tilt. <space/enter> to save or (q)uit/ESC
+saving light 11 back position {:pan=>93, :tilt=>47}
+
+Which light to calibrate? [1-12, (n)ext [12] or (q)uit]
+calibrating light 12
Press (a/d) to pan and (w/s) to tilt. <space/enter> to save or (q)uit/ESC
-saving light 3 awesomeness position {:pan=>144, :tilt=>127}
-Which light to calibrate? [1-12, (n)ext [4] or (q)uit] q
+saving light 12 back position {:pan=>161, :tilt=>53}
```
View
22 Gemfile
@@ -1,20 +1,18 @@
source 'http://rubygems.org'
-gem 'bundler'
gem 'rake', '~> 0.8.7'
gem 'thor', '~> 0.15.4'
gem 'json', '~> 1.7.3'
-gem 'rspec', '~> 2.11.0'
-gem 'guard', '~>1.2.3'
-gem 'guard-bundler', '~> 1.0.0'
-gem 'guard-rspec', '~> 1.2.0'
-gem 'simplecov', '~> 0.6.4'
gem 'open_lighting', '~> 0.1.0'
+gem 'bundler', '~> 1.1.5'
+# gem 'open_lighting', :git => 'https://github.com/marshally/open_lighting_rb.git'
# gem 'open_lighting', :path => ENV['HOME'] + '/Projects/open_lighting'
-# not used
-# gem 'guard-rack'
-# gem 'sinatra'
-# gem 'eventmachine'
-# gem 'haml'
-# gem 'sinatra-contrib'
+group :test do
+ gem 'rspec', '~> 2.11.0'
+ gem 'guard', '~> 1.2.3'
+ gem 'guard-bundler', '~> 1.0.0'
+ gem 'guard-rspec', '~> 1.2.0'
+ gem 'simplecov', '~> 0.6.4'
+ gem 'growl', '~> 1.0.3'
+end
View
10 Gemfile.lock
@@ -2,7 +2,8 @@ GEM
remote: http://rubygems.org/
specs:
diff-lcs (1.1.3)
- ffi (1.1.4)
+ ffi (1.1.5)
+ growl (1.0.3)
guard (1.2.3)
listen (>= 0.4.2)
thor (>= 0.14.6)
@@ -17,7 +18,7 @@ GEM
rb-fsevent (~> 0.9.1)
rb-inotify (~> 0.8.8)
multi_json (1.3.6)
- open_lighting (0.1.2)
+ open_lighting (0.1.3)
json
rake (0.8.7)
rb-fchange (0.0.5)
@@ -32,7 +33,7 @@ GEM
rspec-core (2.11.1)
rspec-expectations (2.11.2)
diff-lcs (~> 1.1.3)
- rspec-mocks (2.11.1)
+ rspec-mocks (2.11.2)
simplecov (0.6.4)
multi_json (~> 1.0)
simplecov-html (~> 0.5.3)
@@ -43,7 +44,8 @@ PLATFORMS
ruby
DEPENDENCIES
- bundler
+ bundler (~> 1.1.5)
+ growl (~> 1.0.3)
guard (~> 1.2.3)
guard-bundler (~> 1.0.0)
guard-rspec (~> 1.2.0)
View
8 Guardfile
@@ -1,13 +1,7 @@
# A sample Guardfile
# More info at https://github.com/guard/guard#readme
-guard 'bundler' do
- watch('Gemfile')
- # Uncomment next line if Gemfile contain `gemspec' command
- # watch(/^.+\.gemspec/)
-end
-
-guard 'rspec', :version => 2 do
+guard 'rspec', :version => 2, :all_after_pass => true, :cli => "--color --format nested" do
watch(%r{^spec/.+_spec\.rb$})
watch(%r{^lib/(.+)\.rb$}) { |m| "spec/lib/#{m[1]}_spec.rb" }
watch('spec/spec_helper.rb') { "spec" }
View
28 bin/add_gestures.rb
@@ -1,13 +1,29 @@
#!/usr/bin/env ruby
require 'open3'
+STDOUT.sync = true
-cmd = ENV["KINECT_CMD"] || "kinectable_pipe"
+["ola_streaming_client", "kinectable_pipe"].each do |exe|
+ running = `ps aux | grep #{exe} | grep -v grep`.strip
+ if running != ""
+ puts "kinectable_pipe is already running. You can kill it with:"
+ pid = running.split(" ")[1]
+ puts "kill -9 #{pid}"
+ exit
+ end
+end
+
+basedir= File.dirname(File.realpath(__FILE__)) + "/../"
+gestures = Dir.glob("#{basedir}gestures/*.rb")
-gestures = Dir.glob("gestures/*.rb")
+cmd = ENV["KINECT_CMD"] || "kinectable_pipe"
gestures.unshift cmd
-puts gestures.inspect
-read_pipe, thread_wait = Open3.pipeline_r(cmd, "ruby gestures/count_users.rb", "ruby gestures/pointing.rb")
-while line = read_pipe.gets
- puts line if line.include? "gesture"
+nothing, $input = Open3.popen2e(gestures.join " | ")
+# read_pipe, thread_wait = Open3.op(cmd, "ruby #{basedir}gestures/count_users.rb", "ruby #{basedir}gestures/pointing.rb")
+$input.sync = true
+
+while line = $input.gets
+ # if (!ENV["TEST"]==1) || (line.include?("gesture"))
+ STDOUT.puts line
+ # end
end
View
2  bin/ball_of_light
@@ -6,7 +6,7 @@ rescue LoadError
puts "\nI can't find bundler. You might need to execute:"
puts "\nrbenv local 1.9.3-p194"
puts "\nrbenv shell 1.9.3-p194"
- puts "gem install bundler"
+ puts "gem install vendor/cache/bundler-1.1.5.gem"
puts "bundle install --deployment"
puts "bin/ball_of_light setup link"
exit
View
12 bin/kinectable_pipe_sim
@@ -2,17 +2,21 @@
require 'rubygems'
require 'json'
+should_sleep = ENV.include?("DONTSLEEP") ? false : true
+dont_repeat = ENV.include?("FOREVER") ? false : true
+
STDOUT.sync = true
-while(1) do
+while(1)
start = Time.now
- File.open("123.json").each do |line|
+ File.open("#{File.dirname(File.realpath(__FILE__))}/../spec/fixtures/123.json").each do |line|
begin
data = JSON.parse(line)
target_time = start + data["elapsed"]
timediff = target_time - Time.now
- sleep(timediff) if timediff > 0
- puts data.to_json
+ sleep(timediff) if should_sleep && timediff > 0
+ STDOUT.puts data.to_json
rescue JSON::ParserError
end
end
+ break if dont_repeat
end
View
101 bin/run_light_script
@@ -1,9 +1,100 @@
#!/usr/bin/env ruby
+require 'open3'
+require 'json'
+require 'io/wait'
+require_relative "../lib/ball_of_light/io_helper"
-while(script = STDIN.gets) do
- script.strip!
- f = "./scripts/#{script}.rb"
- if File.exists?(f)
- puts `ruby #{f}`
+# if `ps aux | grep kinectable_pipe | grep -v grep`.strip
+# puts "kinectable_pipe already running!"
+# exit
+# end
+
+BASEDIR= File.dirname(File.realpath(__FILE__)) + "/"
+if $stdin.tty?
+ cmd = "#{BASEDIR}add_gestures.rb"
+ puts cmd
+ nothing, $input = Open3.popen2e(cmd)
+else
+ $input = $stdin
+end
+
+def count_skeletons(blob)
+ begin
+ unless blob.nil?
+ skels = JSON.parse(blob)
+ if skels["skeletons"]
+ # puts "*"*80
+ # puts "found #{skels["skeletons"].count} users"
+ $last_count = skels["skeletons"].count
+ end
+ end
+ rescue JSON::ParserError
end
end
+
+$input.sync = true
+$stdout.sync = true
+
+def run(script)
+ puts "running #{script}"
+ cmd = "ruby #{BASEDIR}../scripts/#{script} 2>>stderr.log >>stdout.log"
+ Open3.popen2e(cmd) do |stdin, stdout, thread|
+
+ begin
+ while(thread.alive? && !stdin.closed?)
+ last_skeletons = nil
+ # line = IoHelper.gets_most_recent($input)
+ # puts line if line
+ # stdin.puts line if line
+ lines = IoHelper.readall_nonblocking($input)
+ lines.each do |line|
+ next if stdin.closed?
+ stdin.puts line if line
+ $stdout.flush
+
+ # stop script if the number of users has changed
+ count = count_skeletons(line)
+ if count && last_skeletons && last_skeletons != count
+ Thread.kill(thread)
+ puts ">"*80
+ STDOUT.puts "killing thread (#{last_skeletons}, #{count})"
+
+ break
+ end
+
+ last_skeletons = count
+ end
+ end
+ sleep(0.1)
+ rescue Errno::EPIPE
+ end
+ thread.join
+ end
+end
+
+while(!$input.closed?)
+ $stdout.flush
+ $input.flush
+ lines = IoHelper.readall_nonblocking($input)
+
+ lines.reject! do |line|
+ line.nil? || !line.include?("skeletons")
+ end
+
+ case count_skeletons(lines.last)
+ when 0
+ script = "0.rb"
+ when 1
+ script = "1.rb"
+ when 2
+ script = "hug.rb"
+ when nil
+ script = ["heartbeat.rb", "factory.rb", "factory.rb", "spiral.rb", "chase.rb"].sample
+ else
+ script = "heartbeat.rb"
+ end
+
+ run script
+ sleep(0.1)
+end
+
View
12 gestures/count_users.rb
@@ -1,21 +1,21 @@
#!/usr/bin/env ruby
require 'json'
-
+require_relative '../lib/ball_of_light/io_helper'
last = 0
output = {:gesture => {:skeleton_count => 0}}
-STDOUT.sync = true
-STDOUT.puts output.to_json
+$stdin.sync = true
+$stdout.sync = true
-STDIN.each do |line|
- STDOUT.puts line
+while (line = $stdin.gets)
+ $stdout.puts line
begin
blob = JSON.parse(line)
if blob["skeletons"]
if blob["skeletons"].count != last
last = blob["skeletons"].count
output = {:gesture => {:skeleton_count => last}}
- STDOUT.puts output.to_json
+ $stdout.puts output.to_json
end
end
rescue JSON::ParserError
View
13 gestures/pointing.rb 100644 → 100755
@@ -1,26 +1,27 @@
#!/usr/bin/env ruby
require 'bundler'
+ENV['BUNDLE_GEMFILE'] ||= "#{File.dirname(File.realpath(__FILE__))}/../Gemfile"
Bundler.setup
-
require 'json'
require 'matrix'
require_relative "../lib/ball_of_light"
-STDOUT.sync = true
+$stdout.sync = true
+$stdin.sync = true
last = 0
-STDIN.each do |line|
- STDOUT.puts line
+$stdin.each do |line|
+ $stdout.puts line
begin
blob = JSON.parse(line)
if blob["skeletons"]
Scene.new(blob).users.each do |u|
if v = u.pointing
- output = {:gesture => {:point => {:x => v[0], :y => v[1], :z => v[2]}}}
- STDOUT.puts output.to_json
+ output = {:gesture => {:userid => u.id, :point => {:x => v[0], :y => v[1], :z => v[2]}}}
+ $stdout.puts output.to_json
end
end
end
View
20 lib/ball_of_light/ball_of_light_controller.rb
@@ -128,10 +128,12 @@ def spiral_out
animate!(:seconds => 2.5, :point => :bottom)
[0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1.0].each do |i|
[:front, :left, :back, :right].each do |direction|
- animate!(:seconds => 0.25,
- :pan => i*(points[direction][:pan] - points[:bottom][:pan]) + points[:bottom][:pan],
- :tilt => i*(points[direction][:tilt] - points[:bottom][:tilt]) + points[:bottom][:tilt],
- )
+ begin_animation!(:seconds => 0.25) do |c|
+ c.devices.each do |device|
+ device.buffer(:pan => i*(device.points[direction][:pan] - device.points[:bottom][:pan]) + device.points[:bottom][:pan])
+ device.buffer(:tilt => i*(device.points[direction][:tilt] - device.points[:bottom][:tilt]) + device.points[:bottom][:tilt])
+ end
+ end
end
end
end
@@ -140,10 +142,12 @@ def spiral_in
animate!(:seconds => 2.5, :point => :right)
[1.0, 0.9, 0.8, 0.7, 0.6, 0.5, 0.4, 0.3, 0.2, 0.1].each do |i|
[:right, :back, :left, :front].each do |direction|
- animate!(:seconds => 0.25,
- :pan => i*(points[direction][:pan] - points[:bottom][:pan]) + points[:bottom][:pan],
- :tilt => i*(points[direction][:tilt] - points[:bottom][:tilt]) + points[:bottom][:tilt],
- )
+ begin_animation!(:seconds => 0.25) do |c|
+ c.devices.each do |device|
+ device.buffer(:pan => i*(device.points[direction][:pan] - device.points[:bottom][:pan]) + device.points[:bottom][:pan])
+ device.buffer(:tilt => i*(device.points[direction][:tilt] - device.points[:bottom][:tilt]) + device.points[:bottom][:tilt])
+ end
+ end
end
end
animate!(:seconds => 2.5, :point => :bottom)
View
2  lib/ball_of_light/cli.rb
@@ -19,7 +19,9 @@ def initialize(*args)
kill_it = ask "You seem to have an instance of #{exe} running. Do you want me to kill it? (Y/n)"
unless kill_it.downcase[/\An/]
pid = running.split(" ")[1]
+ say " killing process:#{pid}, please restart"
`kill -9 #{pid}`
+ exit
end
end
end
View
52 lib/ball_of_light/cli/calibrate.rb
@@ -1,5 +1,6 @@
require 'thor'
require 'open3'
+require_relative "../../ball_of_light"
module BallOfLight
module CLI
class Calibrate < Thor
@@ -13,12 +14,12 @@ def points
points = nil
points = BallOfLightController.additional_points
- name = ask("What is the name of your point?")
+ name = ask("\nWhat is the name of your point?")
number = 0
while(1) do
- answer = ask("Which light to calibrate? [1-12, (n)ext [#{number+1}] or (q)uit]")
+ answer = ask("\nWhich light to calibrate? [1-12, (n)ext [#{number+1}] or (q)uit]")
break if ["q", "quit"].include? answer
if answer == "n" || answer == ""
@@ -78,13 +79,12 @@ def points
def auto
start = Time.now
controller.instant!(:point => :bottom)
- cmd = "#{ENV['HOME']}/Projects/kinectable_pipe/kinectable_pipe -r 4"
+ cmd = "kinectable_pipe -r 4 -i -d"
stdin, stdout, wait = Open3.popen2e(cmd)
+ stdout.sync = true
+ STDOUT.sync = true
- say "someone should stand in the frame until there is some output"
- capture_images(stdout, "#{ENV['HOME']}/.ball_of_light/person")
-
- yes? "is the person out of the frame? (yes)"
+ capture_images(stdout, "#{ENV['HOME']}/.ball_of_light/origin")
controller.off!
@@ -97,21 +97,16 @@ def auto
puts "bottom at pan:#{pan0}, tilt:#{tilt0}"
next unless pan0
next unless tilt0
- 4.times do |p|
- [3, 0, -3].each do |i|
- pan = pan0 + (p+1)*i
- 4.times do |t|
- [1, -1].each do |j|
- tilt = tilt0 + t*j
- if pan >= 0 && pan <= 255 && tilt >= 0 && tilt <= 255
- puts "pan:#{pan} tilt:#{tilt}"
-
- device.buffer(:tilt => tilt, :pan => pan)
- sleep(0.1)
- controller.write!
- capture_images(stdout, "#{ENV['HOME']}/.ball_of_light/light_#{1+(device.start_address-1)/5}_pan#{pan}_tilt#{tilt}")
- end
- end
+ [-9, -6, -3, 0, 3, 6, 9].each do |p|
+ pan = pan0 + p
+ [-3, -2, -1, 0, 1, 2, 3].each do |t|
+ tilt = tilt0 + t
+ if pan >= 0 && pan <= 255 && tilt >= 0 && tilt <= 255
+ puts "pan:#{pan} tilt:#{tilt}"
+
+ device.buffer(:tilt => tilt, :pan => pan)
+ controller.write!
+ capture_images(stdout, "#{ENV['HOME']}/.ball_of_light/light_#{1+(device.start_address-1)/5}_pan#{pan}_tilt#{tilt}")
end
end
end
@@ -119,15 +114,20 @@ def auto
say "#{Time.now - start} seconds elapsed"
end
-
no_tasks do
def capture_images(pipe, name)
say "capture_images(pipe, #{name}"
line = ""
- until line.include?("images saved") && File.exists?("rgb.png") && File.exists?("depth.png")
- line = pipe.gets
- # puts line
+
+ ["rgb", "depth"].each do |img|
+ File.delete("#{img}.png") if File.exists?("#{img}.png")
end
+
+ until File.exists?("rgb.png") && File.exists?("depth.png")
+ line = pipe.gets "\n"
+ sleep(0.5) if line.include?("writing images")
+ end
+
["rgb", "depth"].each do |img|
fname = "#{name}_#{img}.png"
if File.exists? fname
View
4 lib/ball_of_light/cli/kinect.rb
@@ -5,7 +5,7 @@ module CLI
class Kinect < Thor
desc "image", "display an image from the Kinect"
def image
- cmd = "#{ENV['HOME']}/Projects/kinectable_pipe/kinectable_pipe -r 4"
+ cmd = "kinectable_pipe -r 4 -i -d"
puts "waiting ..."
stdin, stdout, wait = Open3.popen2e(cmd)
stdout.sync = true
@@ -15,7 +15,7 @@ def image
File.delete("#{img}.png") if File.exists?("#{img}.png")
end
- until File.exists?("rgb.png") && File.exists?("depth.png")
+ until File.exists?("rgb.png")
line = stdout.gets "\n"
puts "waiting ..."
sleep(0.5) if line.include?("writing images")
View
6 lib/ball_of_light/io_helper.rb
@@ -4,7 +4,8 @@ def self.gets_most_recent(io)
read_ready, write_ready = IO.select([io], nil, nil, 0)
while read_ready && read = read_ready[0]
break if read.eof?
- STDOUT.flush
+ break if read.closed?
+
line = read.gets
read_ready, write_ready = IO.select([io], nil, nil, 0)
end
@@ -16,7 +17,8 @@ def self.readall_nonblocking(io)
read_ready, write_ready = IO.select([io], nil, nil, 0)
while read_ready && read = read_ready[0]
break if read.eof?
- STDOUT.flush
+ break if read.closed?
+
lines << read.gets
read_ready, write_ready = IO.select([io], nil, nil, 0)
end
View
11 lib/ball_of_light/joint.rb
@@ -10,10 +10,9 @@ def initialize(options = {})
options.symbolize_keys!
[:x, :y, :z, :X, :Y, :Z].each do |i|
- if options[i]==0.0
- options[i] = options[i].to_f
- end
- unless options[i].nil?
+ if options[i].nil? || options[i]==0.0
+ options.delete(i)
+ else
options[i] = options[i].to_f
end
end
@@ -26,7 +25,9 @@ def initialize(options = {})
def vector
if self.x && self.y && self.z
- Vector[self.x, self.y, self.z]
+ if self.x!=0.0 && self.y!=0.0 && self.z!=0.0
+ Vector[self.x, self.y, self.z]
+ end
end
end
end
View
36 lib/ball_of_light/user.rb
@@ -11,10 +11,12 @@ def initialize(options = {})
options.symbolize_keys!
self.id = options[:userid]
- self.joints = options[:joints].inject({}) do |result, j|
- joint = Joint.new(j)
- result[joint.name.to_sym] = joint
- result
+ if options[:joints]
+ self.joints = options[:joints].inject({}) do |result, j|
+ joint = Joint.new(j)
+ result[joint.name.to_sym] = joint
+ result
+ end
end
end
@@ -23,10 +25,16 @@ def pointing
end
def pointing_right
+ return nil if joints[:r_hand].z == joints[:r_elbow].z
+ return nil if joints[:r_shoulder].z == joints[:r_elbow].z
+ return nil if joints[:r_hand].z == joints[:r_shoulder].z
direction_equivalent(vector_between(:r_hand, :r_elbow), vector_between(:r_elbow, :r_shoulder))
end
def pointing_left
+ return nil if joints[:l_hand].z == joints[:l_elbow].z
+ return nil if joints[:l_shoulder].z == joints[:l_elbow].z
+ return nil if joints[:l_hand].z == joints[:l_shoulder].z
direction_equivalent(vector_between(:l_hand, :l_elbow), vector_between(:l_elbow, :l_shoulder))
end
@@ -38,16 +46,32 @@ def vector_between(sym1, sym2)
end
end
- def direction_equivalent(v1, v2, err=0.25)
+ def direction_equivalent(v1, v2, err=0.20)
if v1 && v2
v1n = v1.normalize
v2n = v2.normalize
3.times do |i|
- if (v1n[i] - v2n[i]).abs >= err
+ diff = (v1n[i] - v2n[i]).abs
+ # there is a check against diff=0 here because the depth readings can
+ # get screwed up and start yielding the exact same
+ if diff >= err || diff == 0.0
return nil
end
end
+ # STDERR.puts v1.inspect
+ # STDERR.puts v2.inspect
+ # STDERR.puts v1n.inspect
+ # STDERR.puts v2n.inspect
+
+ # STDERR.puts joints[:l_shoulder].inspect
+ # STDERR.puts joints[:l_elbow].inspect
+ # STDERR.puts joints[:l_hand].inspect
+
+ # STDERR.puts joints[:r_shoulder].inspect
+ # STDERR.puts joints[:r_elbow].inspect
+ # STDERR.puts joints[:r_hand].inspect
+
return v1n
end
end
View
95 scripts/1.rb
@@ -12,16 +12,18 @@
options.merge!(:cmd => "xargs -n1 echo")
end
+puts "1 players"
# setup controller
controller = BallOfLight::BallOfLightController.new(options)
+$stdout.sync = true
#####################################################################
def reset_colors(c)
# Bottom lights point straight up and turn blue. This should be about 45 degrees.
# (This acknowledges the person and points the lights away from the person’s eyes.)
c.bottom_lights.each do |light|
-# light.up
+ light.buffer(:point => :top)
light.blue
end
@@ -29,26 +31,16 @@ def reset_colors(c)
# Top lights tilt down toward base. This should be about 15 degrees.
c.top_lights.each do |light|
light.red
-# light.bottom
+ light.buffer(:point => :bottom)
end
# Equatorial lights tilt down toward base. This should be about 45 degrees.
c.middle_lights.each do |light|
light.yellow
-# light.bottom
+ light.buffer(:point => :bottom)
end
end
-def pointing_at(json)
- # We can determine which light they are
- # pointing at by plotting the coordinates of lights into the Kinect’s space and
- # then measuring the slope of the hand/elbow or hand/shoulder. The XYZ coordinates
- # of the lights should be constants. (Note that although the top lights are
- # directly above the bottom lights, the equatorial lights are between two
- # bottoms and two tops.
- return nil
-end
-
#####################################################################
# Return all lights to center for 1 second with round white spot.
@@ -64,42 +56,55 @@ def pointing_at(json)
# Begin Kinect body detection routine
reset_colors(controller)
-start = Time.now
+def pointing_at(v)
+ return rand(12)
+end
+start = Time.now
+last_point_time = Time.now
+last_pointed_at = nil
+$stdin.sync = true
while(1)
- begin
- # Using head or shoulder and hand, determine which general direction a person is
- # pointing. When pointing more toward one light than any other, change that light
- # to white and dim the other lights 50%. (still strobing or pulsing!) If it is
- # one of the bottom lights, tilt it to 20 degrees below the center/base position
- # (20 degrees below center of sphere).
-
- json = STDIN.read_nonblock(10000)
- reset_colors(controller)
- controller.buffer(:dimmer => 127)
- if light = controller.devices[json.to_i] # pointing_at(json)
- puts "FOUND LIGHT #{light.start_address}"
- light.white
- light.buffer(:dimmer => 255)
- controller.write!
- end
- false
- rescue Errno::EINTR
- puts "Well, your device seems a little slow..."
- false
- rescue Errno::EAGAIN
- # nothing was ready to be read
- false
- rescue EOFError
- # quit on the end of the input stream
- # (user hit CTRL-D)
- puts "Who hit CTRL-D, really?"
- true
- rescue Exception
- puts Exception
+ # Using head or shoulder and hand, determine which general direction a person is
+ # pointing. When pointing more toward one light than any other, change that light
+ # to white and dim the other lights 50%. (still strobing or pulsing!) If it is
+ # one of the bottom lights, tilt it to 20 degrees below the center/base position
+ # (20 degrees below center of sphere).
+
+ IoHelper.readall_nonblocking($stdin).each do |line|
+ begin
+ blob = JSON.parse(line)
+ if blob["gesture"]
+ if blob["gesture"]["point"]
+ puts line
+ direction = blob["gesture"]["point"]
+ lightnum = pointing_at(direction)
+ if lightnum != last_pointed_at
+ last_pointed_at = lightnum
+ last_point_time = Time.now
+
+ light = controller.devices[lightnum]
+
+ puts "FOUND LIGHT #{light}"
+
+ controller.buffer(:dimmer => 127)
+ light.white
+ light.buffer(:dimmer => 255)
+ controller.write!
+ end
+ end
+ end
+ rescue JSON::ParserError
+ end
end
+
+ # if (Time.now - last_point_time) > 2
+ # last_pointed_at = nil
+ # reset_colors(controller)
+ # end
+
controller.animate!(:seconds => 0.05, :dimmer => controller.heartbeat.next)
- break if (Time.now - start) > 30
+ break if (Time.now - start) > 180
end
View
16 scripts/chase.rb
@@ -17,14 +17,24 @@
#####################################################################
+puts "chase!"
controller.off!
+
controller.center!
-# sequence = [5, 10, 11, 7, 4, 1, 8, 12, 11, 6, 2, 5, 9, 12, 7, 3, 6, 10, 9, 8, 4, 1]
+# chase_sequence = [5, 10, 11, 7, 4, 1, 8, 12, 11, 6, 2, 5, 9, 12, 7, 3, 6, 10, 9, 8, 4, 1]
last = nil
count = controller.chase_sequence.count
-[32.0, 24.0, 16.0, 12.0, 8.0, 6.0, 4.0, 2.0, 2.0, 2.0, 2.0].each do |duration|
+
+durations = [32.0, 24.0, 16.0, 12.0, 8.0, 6.0, 4.0, 2.0, 2.0, 2.0, 2.0]
+
+if ENV["SHORT"]="true"
+ durations = [2.0, 2.0]
+end
+
+
+durations.each do |duration|
controller.chase_sequence.each do |light|
# change colors here
controller.buffer(:point => controller.random_color)
@@ -42,7 +52,7 @@
end
controller.strobe_open
-controller.on!
+controller.instant!(:dimmer => 255)
controller.animate!(:seconds => 2) do |animate|
animate.buffer(:dimmer => 1)
View
27 scripts/factory.rb
@@ -16,19 +16,22 @@
controller = BallOfLight::BallOfLightController.new(options)
controller.on!
+count = 9
+if ENV["SHORT"]=="true"
+ count=1
+end
+
# runs for about 90 seconds
-#9.times do
-2.times do
+count.times do |i|
+ puts "factory #{i}"
# 5s
# pan left to right 100% of rotation
- controller.buffer(:point => controller.random_color)
- controller.animate!(:seconds => 5, :pan => 0)
- controller.buffer(:point => controller.random_color)
- controller.animate!(:seconds => 0.5, :tilt => rand(255).to_i)
- controller.animate!(:seconds => 5, :pan => 255)
- controller.buffer(:point => controller.random_color)
- controller.animate!(:seconds => 0.5, :tilt => rand(255).to_i)
+ [0,255].each do |p|
+ controller.buffer(:point => controller.random_color)
+ controller.animate!(:seconds => 5, :pan => p)
+ controller.buffer(:point => controller.random_color)
+ controller.animate!(:seconds => 0.5, :tilt => rand(255).to_i)
+
+ # check the input pipe for kill condition?
+ end
end
-# 5s
-# tilt 25% of rotation, random direction
-# change gobo light
View
11 scripts/heartbeat.rb
@@ -15,8 +15,15 @@
# setup controller
controller = BallOfLight::BallOfLightController.new(options)
-i=0
-while(1)
+
+count = 1800
+
+if ENV["SHORT"]=="true"
+ count = 30
+end
+
+puts "heartbeat!"
+count.times do
begin
# See if a 'Q' has been typed yet
c = STDIN.read_nonblock(1)
View
2  scripts/hug.rb
@@ -48,7 +48,7 @@
controller.top_lights.each do |light|
light.nocolor
light.dimmer(127)
- light.bottom
+ light.buffer(:point => :bottom)
end
# Blue lights dim to very low light as both people approach
View
1  scripts/spiral.rb
@@ -22,6 +22,7 @@
end
end
+controller.buffer(:dimmer => 255)
controller.spiral_in
controller.spiral_out
controller.spiral_in
View
113 spec/fixtures/123.json
113 additions, 0 deletions not shown
View
BIN  vendor/cache/bundler-1.1.5.gem
Binary file not shown
View
BIN  vendor/cache/ffi-1.1.4.gem
Binary file not shown
View
BIN  vendor/cache/ffi-1.1.5.gem
Binary file not shown
View
BIN  vendor/cache/growl-1.0.3.gem
Binary file not shown
View
BIN  vendor/cache/open_lighting-0.1.2.gem
Binary file not shown
View
BIN  vendor/cache/open_lighting-0.1.3.gem
Binary file not shown
View
BIN  vendor/cache/rspec-mocks-2.11.1.gem
Binary file not shown
View
BIN  vendor/cache/rspec-mocks-2.11.2.gem
Binary file not shown
Please sign in to comment.
Something went wrong with that request. Please try again.