artoo 0.1.3 → 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: ed97e1d66baccca21165b0960b2ed18212b2a1d4
4
+ data.tar.gz: 77e070f5faa53a75532d5c73f87c2016d9e0f23a
5
+ SHA512:
6
+ metadata.gz: 6566a8f925b396b38e0641e64548f42787d0611852733077697efad840b972281cc0ac8d218801476593a590c52287802a6bdd8bb25758c19430eaa4c20c4e67
7
+ data.tar.gz: 4107fcfa598cc71a9d3a5e11f26b1885336e0b5c64ae264fc13150162db6fe4055d54db3984007c46886a3c74306c92fc3dadb66392d1b41b820888b34662af0
data/.gitignore CHANGED
@@ -23,3 +23,6 @@ doc/
23
23
 
24
24
  # Sass
25
25
  .sass-cache
26
+
27
+ # rubinius
28
+ .rbx
data/.travis.yml ADDED
@@ -0,0 +1,6 @@
1
+ language: ruby
2
+ rvm:
3
+ - 2.0.0
4
+ - 1.9.3
5
+ - jruby-19mode # JRuby in 1.9 mode
6
+ - rbx-19mode
data/Gemfile CHANGED
@@ -3,29 +3,18 @@ source "http://rubygems.org"
3
3
  # Specify your gem's dependencies in artoo.gemspec
4
4
  gemspec
5
5
 
6
- gem 'rake'
7
- gem 'celluloid-io'
8
- gem 'reel'
9
- gem 'active_support'
10
- gem 'multi_json'
6
+ # these are for specific hardware, they have to be here for tests
7
+ gem 'hybridgroup-firmata'
8
+ gem 'hybridgroup-sphero'
9
+ gem 'hybridgroup-argus'
11
10
 
12
- group :development, :test do
13
- gem 'minitest'
14
- gem 'mocha'
15
-
16
- # these are for specific hardware, they have to be here for tests
17
- gem 'hybridgroup-firmata'
18
- gem 'hybridgroup-sphero'
19
- gem 'hybridgroup-argus'
20
-
21
- # For Front-End
22
- gem 'sass'
23
- gem 'coffee-script'
24
- gem 'sprockets'
25
- gem 'compass'
26
- gem 'bootstrap-sass'
27
- gem 'guard'
28
- gem 'guard-livereload'
29
- gem 'guard-sprockets'
30
- gem 'guard-compass'
31
- end
11
+ # For the front end web application
12
+ gem 'sass'
13
+ gem 'coffee-script'
14
+ gem 'sprockets'
15
+ gem 'compass'
16
+ gem 'bootstrap-sass'
17
+ gem 'guard'
18
+ gem 'guard-livereload'
19
+ gem 'guard-sprockets'
20
+ gem 'guard-compass'
data/Gemfile.lock CHANGED
@@ -1,7 +1,12 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- artoo (0.1.3)
4
+ artoo (0.2.0)
5
+ active_support (~> 3.0)
6
+ celluloid-io (~> 0.12)
7
+ multi_json (~> 1.6)
8
+ rake (~> 10.0)
9
+ reel (~> 0.3)
5
10
 
6
11
  GEM
7
12
  remote: http://rubygems.org/
@@ -69,12 +74,11 @@ GEM
69
74
  lumberjack (1.0.2)
70
75
  metaclass (0.0.1)
71
76
  method_source (0.8.1)
72
- minitest (4.5.0)
77
+ minitest (4.6.2)
73
78
  mocha (0.13.2)
74
79
  metaclass (~> 0.0.1)
75
80
  multi_json (1.6.1)
76
81
  nio4r (0.4.3)
77
- nio4r (0.4.3-java)
78
82
  pry (0.9.12)
79
83
  coderay (~> 1.0.5)
80
84
  method_source (~> 0.8)
@@ -112,10 +116,8 @@ PLATFORMS
112
116
  ruby
113
117
 
114
118
  DEPENDENCIES
115
- active_support
116
119
  artoo!
117
120
  bootstrap-sass
118
- celluloid-io
119
121
  coffee-script
120
122
  compass
121
123
  guard
@@ -125,10 +127,7 @@ DEPENDENCIES
125
127
  hybridgroup-argus
126
128
  hybridgroup-firmata
127
129
  hybridgroup-sphero
128
- minitest
129
- mocha
130
- multi_json
131
- rake
132
- reel
130
+ minitest (~> 4.6)
131
+ mocha (~> 0.13)
133
132
  sass
134
133
  sprockets
data/README.md CHANGED
@@ -6,7 +6,7 @@ Artoo is a micro-framework for robotics using Ruby.
6
6
 
7
7
  Artoo provides a simple, yet powerful domain-specific language (DSL) for robotics and physical computing.
8
8
 
9
- [![Code Climate](https://codeclimate.com/github/hybridgroup/artoo.png)](https://codeclimate.com/github/hybridgroup/artoo)
9
+ [![Code Climate](https://codeclimate.com/github/hybridgroup/artoo.png)](https://codeclimate.com/github/hybridgroup/artoo) [![Build Status](https://travis-ci.org/hybridgroup/artoo.png?branch=master)](https://travis-ci.org/hybridgroup/artoo)
10
10
 
11
11
  ## Examples:
12
12
 
@@ -71,9 +71,14 @@ SPHEROS.each {|p|
71
71
  SpheroRobot.work!(robots)
72
72
  ```
73
73
 
74
+ Ruby versions supported: Ruby 2.0, 1.9.3, JRuby 1.7.2, and Rubinius 2.0
75
+
76
+
74
77
  Artoo is conceptualy influenced by Sinatra (https://github.com/sinatra/sinatra) as well as borrowing some code from it.
75
78
 
76
- Artoo provides a robust actor-based messaging architecture, that can support fully multi-threaded operation and high-concurrency, as long as it is supported by the Ruby version in which it is executing. To a large extent, this is due to being built on top of Celluloid (https://github.com/celluloid/celluloid) and Celluloid::IO (https://github.com/celluloid/celluloid-io).
79
+ Artoo provides a robust actor-based messaging architecture, that can support fully multi-threaded operation and high-concurrency, as long as it is supported by the Ruby version in which it is executing. This means you will need to use JRuby or Rubinius for maximum concurrency.
80
+
81
+ To a large extent, this is due to being built on top of Celluloid (https://github.com/celluloid/celluloid), Celluloid::IO (https://github.com/celluloid/celluloid-io), and Reel (https://github.com/celluloid/reel).
77
82
 
78
83
  ## API:
79
84
 
data/artoo.gemspec CHANGED
@@ -18,4 +18,12 @@ Gem::Specification.new do |s|
18
18
  s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
19
19
  s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
20
20
  s.require_paths = ["lib"]
21
+
22
+ s.add_runtime_dependency 'celluloid-io', '~> 0.12'
23
+ s.add_runtime_dependency 'reel', '~> 0.3'
24
+ s.add_runtime_dependency 'multi_json', '~> 1.6'
25
+ s.add_runtime_dependency 'active_support', '~> 3.0'
26
+ s.add_runtime_dependency 'rake', '~> 10.0'
27
+ s.add_development_dependency 'minitest', '~> 4.6'
28
+ s.add_development_dependency 'mocha', '~> 0.13'
21
29
  end
data/examples/ardrone.rb CHANGED
@@ -1,6 +1,6 @@
1
1
  require 'artoo'
2
2
 
3
- connection :ardrone, :adaptor => :ardrone, :port => '192.168.1.43:5556'
3
+ connection :ardrone, :adaptor => :ardrone, :port => '192.168.1.1:5556'
4
4
  device :drone, :driver => :ardrone, :connection => :ardrone
5
5
 
6
6
  work do
@@ -9,4 +9,4 @@ work do
9
9
 
10
10
  after(25.seconds) { drone.hover.land }
11
11
  after(30.seconds) { drone.stop }
12
- end
12
+ end
@@ -1,9 +1,9 @@
1
1
  require 'artoo'
2
2
 
3
- connection :ardrone, :adaptor => :ardrone, :port => '192.168.1.43:5556'
3
+ connection :ardrone, :adaptor => :ardrone, :port => '192.168.1.1:5556'
4
4
  device :drone, :driver => :ardrone, :connection => :ardrone
5
5
 
6
- connection :navigation, :adaptor => :ardrone_navigation, :port => '192.168.1.43:5554'
6
+ connection :navigation, :adaptor => :ardrone_navigation, :port => '192.168.1.1:5554'
7
7
  device :nav, :driver => :ardrone_navigation, :connection => :navigation
8
8
 
9
9
  work do
@@ -19,4 +19,4 @@ def nav_update(*data)
19
19
  data[1].drone_state.each do |name, val|
20
20
  p "#{name}: #{val}"
21
21
  end
22
- end
22
+ end
@@ -1,12 +1,12 @@
1
1
  require 'artoo'
2
2
 
3
- connection :ardrone, :adaptor => :ardrone, :port => '192.168.1.43:5556'
3
+ connection :ardrone, :adaptor => :ardrone, :port => '192.168.1.1:5556'
4
4
  device :drone, :driver => :ardrone, :connection => :ardrone
5
5
 
6
- connection :navigation, :adaptor => :ardrone_navigation, :port => '192.168.1.43:5554'
6
+ connection :navigation, :adaptor => :ardrone_navigation, :port => '192.168.1.1:5554'
7
7
  device :nav, :driver => :ardrone_navigation, :connection => :navigation
8
8
 
9
- connection :videodrone, :adaptor => :ardrone_video, :port => '192.168.1.43:5555'
9
+ connection :videodrone, :adaptor => :ardrone_video, :port => '192.168.1.1:5555'
10
10
  device :video, :driver => :ardrone_video, :connection => :videodrone
11
11
 
12
12
  connection :arduino, :adaptor => :firmata, :port => "8023"
@@ -1,9 +1,9 @@
1
1
  require 'artoo'
2
2
 
3
- connection :ardrone, :adaptor => :ardrone, :port => '192.168.1.43:5556'
3
+ connection :ardrone, :adaptor => :ardrone, :port => '192.168.1.1:5556'
4
4
  device :drone, :driver => :ardrone, :connection => :ardrone
5
5
 
6
- connection :navigation, :adaptor => :ardrone_navigation, :port => '192.168.1.43:5554'
6
+ connection :navigation, :adaptor => :ardrone_navigation, :port => '192.168.1.1:5554'
7
7
  device :nav, :driver => :ardrone_navigation, :connection => :navigation
8
8
 
9
9
  connection :arduino, :adaptor => :firmata, :port => "8023"
@@ -24,25 +24,66 @@ work do
24
24
  on classic, :home_button => proc { drone.emergency }
25
25
  on classic, :start_button => proc { drone.start }
26
26
  on classic, :select_button => proc { drone.stop }
27
- on classic, :ry_up => proc { drone.up(@altitude_pitch) }
28
- on classic, :ry_down => proc { drone.down(@altitude_pitch) }
29
- on classic, :ly_up => proc { drone.forward(@fly_pitch) }
30
- on classic, :ly_down => proc { drone.backward(@fly_pitch) }
31
- on classic, :lx_right => proc { drone.right(@fly_pitch) }
32
- on classic, :lx_left => proc { drone.left(@fly_pitch) }
33
- on classic, :reset_pitch_roll => proc {
34
- drone.left(0.0)
35
- drone.forward(0.0)
27
+
28
+ on classic, :left_joystick => proc { |*value|
29
+ pair = value[1]
30
+ if pair[:y] > 0
31
+ drone.forward(validate_pitch(pair[:y], @offsets[:ly]))
32
+ elsif pair[:y] < 0
33
+ drone.backward(validate_pitch(pair[:y], @offsets[:ly]))
34
+ else
35
+ drone.forward(0.0)
36
+ end
37
+
38
+ if pair[:x] > 0
39
+ drone.right(validate_pitch(pair[:x], @offsets[:lx]))
40
+ elsif pair[:x] < 0
41
+ drone.left(validate_pitch(pair[:x], @offsets[:lx]))
42
+ else
43
+ drone.right(0.0)
44
+ end
45
+ }
46
+
47
+ on classic, :right_joystick => proc { |*value|
48
+ pair = value[1]
49
+ if pair[:y] > 0
50
+ drone.up(validate_pitch(pair[:y], @offsets[:ry]))
51
+ elsif pair[:y] < 0
52
+ drone.down(validate_pitch(pair[:y], @offsets[:ry]))
53
+ else
54
+ drone.up(0.0)
55
+ end
56
+ }
57
+
58
+ on classic, :right_trigger => proc { |*value|
59
+ if value[1] > 0
60
+ drone.turn_right(validate_pitch(value[1], @offsets[:rt]))
61
+ else
62
+ drone.turn_right(0.0)
63
+ end
64
+ }
65
+
66
+ on classic, :left_trigger => proc { |*value|
67
+ if value[1] > 0
68
+ drone.turn_left(validate_pitch(value[1], @offsets[:lt]))
69
+ else
70
+ drone.turn_left(0.0)
71
+ end
36
72
  }
37
- on classic, :rotate_left => proc { drone.turn_left(@rotate_pitch) }
38
- on classic, :rotate_right => proc { drone.turn_right(@rotate_pitch) }
39
- on classic, :reset_rotate => proc { drone.turn_left(0.0) }
40
- on classic, :reset_altitude => proc { drone.up(0.0) }
41
73
  end
42
74
 
43
75
  def init_settings
44
- @rotate_pitch = 0.5
45
- @fly_pitch = 0.7
46
- @altitude_pitch = 1
47
76
  @toggle_camera = 0
77
+ @offsets = {
78
+ :ry => 12.0,
79
+ :ly => 27.0,
80
+ :lx => 27.0,
81
+ :rt => 27.0,
82
+ :lt => 12.0
83
+ }
84
+ end
85
+
86
+ def validate_pitch(data, offset)
87
+ value = data.abs / offset
88
+ value >= 0.1 ? (value <= 1.0 ? value.round(2) : 1.0) : 0.0
48
89
  end
@@ -0,0 +1,18 @@
1
+ begin
2
+ require 'artoo'
3
+ rescue LoadError
4
+ $LOAD_PATH.unshift(File.expand_path(File.join(File.dirname(__FILE__),'..', 'lib')))
5
+ require "artoo"
6
+ end
7
+
8
+ connection :roomba, :adaptor => :roomba, :port => '/dev/tty.usbserial-A2001yzl'
9
+ device :roomba, :driver => :roomba, :connection => :roomba
10
+
11
+ work do
12
+ roomba.safe_mode
13
+ roomba.nudge_left
14
+ roomba.nudge_right
15
+ roomba.nudge_right
16
+ roomba.nudge_left
17
+ roomba.sing_jingle_bells
18
+ end
@@ -0,0 +1,28 @@
1
+ require 'artoo'
2
+
3
+ connection :sphero, :adaptor => :sphero, :port => '127.0.0.1:4560'
4
+ device :sphero, :driver => :sphero
5
+
6
+ connection :arduino, :adaptor => :firmata, :port => "8023"
7
+ device :wiichuck, :driver => :wiichuck, :connection => :arduino, :interval => 0.1
8
+
9
+ work do
10
+ init_settings
11
+ on wiichuck, :c_button => proc {}
12
+ on wiichuck, :z_button => proc {}
13
+ on wiichuck, :joystick => proc { |*value|
14
+ @heading = heading(value[1])
15
+ }
16
+ every(1.seconds) do
17
+ puts "Rolling..."
18
+ sphero.roll 20, @heading
19
+ end
20
+ end
21
+
22
+ def init_settings
23
+ @heading = 0
24
+ end
25
+
26
+ def heading(value)
27
+ (180.0 - (Math.atan2(value[:y],value[:x]) * (180.0 / Math::PI))).round
28
+ end
@@ -0,0 +1,12 @@
1
+ require 'artoo'
2
+
3
+ connection :arduino, :adaptor => :firmata, :port => "8023"
4
+ device :wiichuck, :driver => :wiichuck, :connection => :arduino, :interval => 0.1
5
+
6
+ work do
7
+ on wiichuck, :c_button => proc { puts "c button pressed!" }
8
+ on wiichuck, :z_button => proc { puts "z button pressed!" }
9
+ on wiichuck, :joystick => proc { |*value|
10
+ puts "joystick x: #{value[1][:x]}, y: #{value[1][:y]}"
11
+ }
12
+ end
@@ -49,6 +49,13 @@ module Artoo
49
49
  def connect_to_udp
50
50
  @udp_socket ||= UDPSocket.new
51
51
  end
52
+
53
+ def connect_to_serial(speed=57600, data_bits=8, stop_bits=1, parity=SerialPort::NONE)
54
+ require 'serialport'
55
+ @sp = SerialPort.new(port.port, speed, data_bits, stop_bits, parity)
56
+ rescue LoadError
57
+ Logger.error "Please 'gem install hybridgroup-serialport' for serial port support."
58
+ end
52
59
  end
53
60
  end
54
61
  end
@@ -0,0 +1,43 @@
1
+ require 'artoo/adaptors/adaptor'
2
+
3
+ module Artoo
4
+ module Adaptors
5
+ # Connect to a Roomba (http://www.irobot.com/en/us/robots/Educators/Create.aspx)
6
+ class Roomba < Adaptor
7
+
8
+ attr_reader :sp
9
+
10
+ def finalize
11
+ if connected?
12
+ @sp.close
13
+ end
14
+ end
15
+
16
+ def connect
17
+ if port.is_serial?
18
+ @sp = connect_to_serial
19
+ @sp.dtr = 0
20
+ @sp.rts = 0
21
+ else
22
+ @sp = connect_to_tcp
23
+ end
24
+ super
25
+ end
26
+
27
+ def send_bytes(bytes)
28
+ bytes = [bytes] unless bytes.respond_to?(:map)
29
+ bytes.map!(&:chr)
30
+ Logger.debug "sending: #{bytes.inspect}"
31
+ res = []
32
+ bytes.each{|b| res << @sp.write(b) }
33
+ Logger.debug "returned: #{res.inspect}"
34
+ end
35
+
36
+ def disconnect
37
+ @sp.close
38
+ super
39
+ end
40
+
41
+ end
42
+ end
43
+ end
@@ -0,0 +1,79 @@
1
+
2
+ module Artoo
3
+ module Basic
4
+ # Taken from Sinatra codebase
5
+ # Sets an option to the given value. If the value is a proc,
6
+ # the proc will be called every time the option is accessed.
7
+ def set(option, value = (not_set = true), ignore_setter = false, &block)
8
+ raise ArgumentError if block and !not_set
9
+ value, not_set = block, false if block
10
+
11
+ if not_set
12
+ raise ArgumentError unless option.respond_to?(:each)
13
+ option.each { |k,v| set(k, v) }
14
+ return self
15
+ end
16
+
17
+ if respond_to?("#{option}=") and not ignore_setter
18
+ return __send__("#{option}=", value)
19
+ end
20
+
21
+ setter = proc { |val| set option, val, true }
22
+ getter = proc { value }
23
+
24
+ case value
25
+ when Proc
26
+ getter = value
27
+ when Symbol, Fixnum, FalseClass, TrueClass, NilClass
28
+ getter = value.inspect
29
+ when Hash
30
+ setter = proc do |val|
31
+ val = value.merge val if Hash === val
32
+ set option, val, true
33
+ end
34
+ end
35
+
36
+ define_singleton_method("#{option}=", setter) if setter
37
+ define_singleton_method(option, getter) if getter
38
+ define_singleton_method("#{option}?", "!!#{option}") unless method_defined? "#{option}?"
39
+ self
40
+ end
41
+
42
+ # Taken from Sinatra codebase
43
+ CALLERS_TO_IGNORE = [ # :nodoc:
44
+ /lib\/artoo.*\.rb$/, # artoo code
45
+ /^\(.*\)$/, # generated code
46
+ /rubygems\/(custom|core_ext\/kernel)_require\.rb$/, # rubygems require hacks
47
+ /active_support/, # active_support require hacks
48
+ /bundler(\/runtime)?\.rb/, # bundler require hacks
49
+ /<internal:/, # internal in ruby >= 1.9.2
50
+ /src\/kernel\/bootstrap\/[A-Z]/ # maglev kernel files
51
+ ]
52
+
53
+ # Taken from Sinatra codebase
54
+ # Like Kernel#caller but excluding certain magic entries and without
55
+ # line / method information; the resulting array contains filenames only.
56
+ def caller_files
57
+ cleaned_caller(1).flatten
58
+ end
59
+
60
+ private
61
+
62
+ # Taken from Sinatra codebase
63
+ def define_singleton_method(name, content = Proc.new)
64
+ # replace with call to singleton_class once we're 1.9 only
65
+ (class << self; self; end).class_eval do
66
+ undef_method(name) if method_defined? name
67
+ String === content ? class_eval("def #{name}() #{content}; end") : define_method(name, &content)
68
+ end
69
+ end
70
+
71
+ # Taken from Sinatra codebase
72
+ # Like Kernel#caller but excluding certain magic entries
73
+ def cleaned_caller(keep = 3)
74
+ caller(1).
75
+ map { |line| line.split(/:(?=\d|in )/, 3)[0,keep] }.
76
+ reject { |file, *_| CALLERS_TO_IGNORE.any? { |pattern| file =~ pattern } }
77
+ end
78
+ end
79
+ end