artoo 0.4.0 → 0.4.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (53) hide show
  1. checksums.yaml +4 -4
  2. data/.travis.yml +1 -1
  3. data/.yardopts +10 -0
  4. data/Gemfile +9 -0
  5. data/Gemfile.lock +10 -7
  6. data/README.md +2 -2
  7. data/api/assets/javascripts/artoo/controllers/robot.js.coffee +2 -1
  8. data/api/public/core.js +3 -1
  9. data/artoo.gemspec +0 -1
  10. data/lib/artoo/adaptors/adaptor.rb +27 -6
  11. data/lib/artoo/adaptors/ardrone.rb +10 -2
  12. data/lib/artoo/adaptors/ardrone_navigation.rb +9 -2
  13. data/lib/artoo/adaptors/ardrone_video.rb +13 -5
  14. data/lib/artoo/adaptors/firmata.rb +10 -2
  15. data/lib/artoo/adaptors/loopback.rb +2 -1
  16. data/lib/artoo/adaptors/roomba.rb +12 -4
  17. data/lib/artoo/adaptors/sphero.rb +15 -3
  18. data/lib/artoo/api.rb +48 -5
  19. data/lib/artoo/api_route_helpers.rb +22 -3
  20. data/lib/artoo/basic.rb +3 -7
  21. data/lib/artoo/connection.rb +25 -7
  22. data/lib/artoo/delegator.rb +6 -16
  23. data/lib/artoo/device.rb +39 -10
  24. data/lib/artoo/device_event_client.rb +6 -0
  25. data/lib/artoo/drivers/ardrone.rb +5 -1
  26. data/lib/artoo/drivers/ardrone_navigation.rb +5 -1
  27. data/lib/artoo/drivers/ardrone_video.rb +9 -4
  28. data/lib/artoo/drivers/button.rb +7 -1
  29. data/lib/artoo/drivers/driver.rb +44 -4
  30. data/lib/artoo/drivers/led.rb +12 -1
  31. data/lib/artoo/drivers/motor.rb +12 -1
  32. data/lib/artoo/drivers/pinger.rb +10 -1
  33. data/lib/artoo/drivers/pinger2.rb +10 -1
  34. data/lib/artoo/drivers/roomba.rb +65 -17
  35. data/lib/artoo/drivers/servo.rb +12 -2
  36. data/lib/artoo/drivers/sphero.rb +19 -5
  37. data/lib/artoo/drivers/wiichuck.rb +7 -1
  38. data/lib/artoo/drivers/wiiclassic.rb +14 -5
  39. data/lib/artoo/drivers/wiidriver.rb +4 -1
  40. data/lib/artoo/events.rb +11 -4
  41. data/lib/artoo/ext/actor.rb +1 -1
  42. data/lib/artoo/ext/timers.rb +1 -1
  43. data/lib/artoo/main.rb +2 -13
  44. data/lib/artoo/master.rb +20 -2
  45. data/lib/artoo/port.rb +8 -3
  46. data/lib/artoo/robot.rb +45 -17
  47. data/lib/artoo/utility.rb +53 -9
  48. data/lib/artoo/version.rb +1 -1
  49. data/test/drivers/driver_test.rb +15 -0
  50. data/test/drivers/led_test.rb +4 -0
  51. data/test/utility_test.rb +35 -18
  52. data/test/utility_test_cases.rb +56 -0
  53. metadata +5 -16
@@ -4,14 +4,18 @@ module Artoo
4
4
  module Drivers
5
5
  # Servo behaviors for Firmata
6
6
  class Servo < Driver
7
+ COMMANDS = [:move, :min, :center, :max].freeze
8
+
7
9
  attr_reader :current_angle
8
10
 
11
+ # Create new Servo with angle=0
9
12
  def initialize(params={})
10
13
  super
11
14
 
12
15
  @current_angle = 0
13
16
  end
14
17
 
18
+ # Starts connection to read and process and driver
15
19
  def start_driver
16
20
  every(interval) do
17
21
  connection.read_and_process
@@ -20,30 +24,36 @@ module Artoo
20
24
  super
21
25
  end
22
26
 
27
+ # Moves to specified angle
28
+ # @param [Integer] angle must be between 0-180
23
29
  def move(angle)
24
30
  raise "Servo angle must be an integer between 0-180" unless (angle.is_a?(Numeric) && angle >= 0 && angle <= 180)
25
-
31
+
26
32
  @current_angle = angle
27
33
  connection.set_pin_mode(pin, Firmata::Board::SERVO)
28
34
  connection.analog_write(pin, angle_to_span(angle))
29
35
  end
30
36
 
37
+ # Moves to min position
31
38
  def min
32
39
  move(0)
33
40
  end
34
41
 
42
+ # Moves to center position
35
43
  def center
36
44
  move(90)
37
45
  end
38
46
 
47
+ # Moves to max position
39
48
  def max
40
49
  move(180)
41
50
  end
42
51
 
43
52
  # converts an angle to a span between 0-255
53
+ # @param [Integer] angle
44
54
  def angle_to_span(angle)
45
55
  (angle * 255 / 180).to_i
46
56
  end
47
57
  end
48
58
  end
49
- end
59
+ end
@@ -4,36 +4,50 @@ module Artoo
4
4
  module Drivers
5
5
  # The Sphero driver behaviors
6
6
  class Sphero < Driver
7
- RED = [255, 0, 0]
8
- GREEN = [0, 255, 0]
9
- YELLOW = [255, 255, 0]
10
- BLUE = [0, 0, 255]
11
- WHITE = [255, 255, 255]
12
7
 
8
+ RED = [255, 0, 0]
9
+ GREEN = [0, 255, 0]
10
+ YELLOW = [255, 255, 0]
11
+ BLUE = [0, 0, 255]
12
+ WHITE = [255, 255, 255]
13
+
14
+ COMMANDS = [:detect_collisions, :clear_collisions, :collisions,
15
+ :power_notifications, :sensor_data, :set_color, :color].freeze
16
+
17
+ # Detects collisions
18
+ # @param [Hash] params
13
19
  def detect_collisions(params={})
14
20
  connection.configure_collision_detection 0x01, 0x20, 0x20, 0x20, 0x20, 0x50
15
21
  end
16
22
 
23
+ # Clears collisions
17
24
  def clear_collisions
18
25
  messages.clear if responses = messages
19
26
  end
20
27
 
28
+ # @return [CollisionDetected] collision
21
29
  def collisions
22
30
  matching_response_types messages, ::Sphero::Response::CollisionDetected
23
31
  end
24
32
 
33
+ # @return [PowerNotification] power notification
25
34
  def power_notifications
26
35
  matching_response_types messages, ::Sphero::Response::PowerNotification
27
36
  end
28
37
 
38
+ # @return [SensorData] sensor data
29
39
  def sensor_data
30
40
  matching_response_types messages, ::Sphero::Response::SensorData
31
41
  end
32
42
 
43
+ # Set color
44
+ # @param [Collection] colors
33
45
  def set_color(*colors)
34
46
  connection.rgb(*color(*colors))
35
47
  end
36
48
 
49
+ # Retrieves color
50
+ # @param [Collection] colors
37
51
  def color(*colors)
38
52
  case colors.first
39
53
  when :red then RED
@@ -4,6 +4,9 @@ module Artoo
4
4
  module Drivers
5
5
  # Wiichuck driver behaviors for Firmata
6
6
  class Wiichuck < Wiidriver
7
+
8
+ # Update button and joystick values
9
+ # @param [Object] value
7
10
  def update(value)
8
11
  begin
9
12
  super
@@ -19,21 +22,24 @@ module Artoo
19
22
  end
20
23
  end
21
24
 
25
+ # Adjust x, y origin values
22
26
  def adjust_origins
23
27
  set_joystick_default_value(:sy_origin, data[:sy])
24
28
  set_joystick_default_value(:sx_origin, data[:sx])
25
29
  end
26
30
 
31
+ # Publishes events for c and z buttons
27
32
  def update_buttons
28
33
  publish(event_topic_name("c_button")) if data[:c] == true
29
34
  publish(event_topic_name("z_button")) if data[:z] == true
30
35
  end
31
36
 
37
+ # Publishes event for joystick
32
38
  def update_joystick
33
39
  publish(event_topic_name("joystick"), {:x => calculate_joystick_value(:sx, :sx_origin), :y => calculate_joystick_value(:sy, :sy_origin)})
34
40
  end
35
41
 
36
- private
42
+ private
37
43
 
38
44
  def get_defaults
39
45
  {
@@ -3,11 +3,14 @@ require 'artoo/drivers/wiidriver'
3
3
  module Artoo
4
4
  module Drivers
5
5
  # Wiiclassic driver behaviors for Firmata
6
- class Wiiclassic < Wiidriver
6
+ class Wiiclassic < Wiidriver
7
+
8
+ # Update buttons and joysticks values
9
+ # @param [Object] value
7
10
  def update(value)
8
11
  begin
9
12
  super
10
-
13
+
11
14
  adjust_origins
12
15
  update_buttons
13
16
  update_left_joystick
@@ -21,6 +24,7 @@ module Artoo
21
24
  end
22
25
  end
23
26
 
27
+ # Adjust all origins
24
28
  def adjust_origins
25
29
  set_joystick_default_value(:ly_origin, data[:ly])
26
30
  set_joystick_default_value(:lx_origin, data[:lx])
@@ -30,6 +34,7 @@ module Artoo
30
34
  set_joystick_default_value(:lt_origin, data[:lt])
31
35
  end
32
36
 
37
+ # Update button values
33
38
  def update_buttons
34
39
  update_button("a_button", :a)
35
40
  update_button("b_button", :b)
@@ -40,25 +45,29 @@ module Artoo
40
45
  update_button("select_button", :-)
41
46
  end
42
47
 
48
+ # Publish button event
43
49
  def update_button(name, key)
44
50
  publish(event_topic_name(name)) if data[key] == true
45
51
  end
46
52
 
53
+ # Publish left joystick event
47
54
  def update_left_joystick
48
55
  publish(event_topic_name("left_joystick"), {:x => calculate_joystick_value(:lx, :lx_origin), :y => calculate_joystick_value(:ly, :ly_origin)})
49
56
  end
50
57
 
58
+ # Publish right joystick event
51
59
  def update_right_joystick
52
60
  publish(event_topic_name("right_joystick"), {:x => calculate_joystick_value(:rx, :rx_origin), :y => calculate_joystick_value(:ry, :ry_origin)})
53
61
  end
54
62
 
63
+ # Publish triggers events
55
64
  def update_triggers
56
65
  publish(event_topic_name("right_trigger"), calculate_joystick_value(:rt, :rt_origin))
57
66
  publish(event_topic_name("left_trigger"), calculate_joystick_value(:lt, :lt_origin))
58
67
  end
59
68
 
60
69
  private
61
-
70
+
62
71
  def get_defaults
63
72
  {
64
73
  :ry_origin => nil,
@@ -67,8 +76,8 @@ module Artoo
67
76
  :lx_origin => nil,
68
77
  :rt_origin => nil,
69
78
  :lt_origin => nil
70
- }
71
- end
79
+ }
80
+ end
72
81
 
73
82
  def parse(value)
74
83
  return parse_joysticks(value).
@@ -8,12 +8,14 @@ module Artoo
8
8
 
9
9
  def address; 0x52; end
10
10
 
11
+ # Create new Wiidriver
11
12
  def initialize(params={})
12
13
  @joystick = get_defaults
13
14
  @data = {}
14
15
  super
15
16
  end
16
17
 
18
+ # Starts drives and required connections
17
19
  def start_driver
18
20
  begin
19
21
  listener = ->(value) { update(value) }
@@ -38,6 +40,7 @@ module Artoo
38
40
  end
39
41
  end
40
42
 
43
+ # Get and update data
41
44
  def update(value)
42
45
  if encrypted?(value)
43
46
  Logger.error "Encrypted bytes from wii device!"
@@ -47,7 +50,7 @@ module Artoo
47
50
  @data = parse(value)
48
51
  end
49
52
 
50
- protected
53
+ protected
51
54
 
52
55
  def get_defaults
53
56
  {}
@@ -1,6 +1,10 @@
1
1
  module Artoo
2
+ # Class that handles events
2
3
  module Events
4
+
3
5
  # Subscribe to an event from a device
6
+ # @param [Device] device
7
+ # @param [Hash] events
4
8
  def on(device, events={})
5
9
  events.each do |k, v|
6
10
  subscribe("#{safe_name}_#{device.name}_#{k}", create_proxy_method(k, v))
@@ -10,8 +14,10 @@ module Artoo
10
14
  # Create an anonymous subscription method so we can wrap the
11
15
  # subscription method fire into a valid method regardless
12
16
  # of where it is defined
13
- def create_proxy_method(k, v)
14
- proxy_method_name(k).tap do |name|
17
+ # @param [String] base_name
18
+ # @param [String] v
19
+ def create_proxy_method(base_name, v)
20
+ proxy_method_name(base_name).tap do |name|
15
21
  self.class.send :define_method, name do |*args|
16
22
  case v
17
23
  when Symbol
@@ -24,9 +30,10 @@ module Artoo
24
30
  end
25
31
 
26
32
  # A simple loop to create a 'fake' anonymous method
27
- def proxy_method_name(k)
33
+ # @return [Method] created method
34
+ def proxy_method_name(base_name)
28
35
  begin
29
- meth = "#{k}_#{Random.rand(999)}"
36
+ meth = "#{base_name}_#{Random.rand(999)}"
30
37
  end while respond_to?(meth)
31
38
  meth
32
39
  end
@@ -1,4 +1,4 @@
1
- # monkeypatches for Celluloid Actor class
1
+ # Monkeypatches for Celluloid Actor class
2
2
  module Celluloid
3
3
  def timers
4
4
  Actor.timers
@@ -1,4 +1,4 @@
1
- # monkeypatches for Timers & Timer classes used by Celluloid
1
+ # Monkeypatches for Timers & Timer classes used by Celluloid
2
2
  class Timers
3
3
  def initialize
4
4
  @timers = SortedSet.new
@@ -6,27 +6,16 @@ module Artoo
6
6
  # DSL methods executed on main are delegated to this class like Sinatra
7
7
  class MainRobot < Artoo::Robot
8
8
 
9
- # we assume that the first file that requires 'artoo' is the
9
+ # We assume that the first file that requires 'artoo' is the
10
10
  # app_file. all other path related options are calculated based
11
11
  # on this path by default.
12
12
  set :app_file, caller_files.first || $0
13
13
  set :start_work, Proc.new { File.expand_path($0) == File.expand_path(app_file) }
14
-
15
- # if run? && ARGV.any?
16
- # require 'optparse'
17
- # OptionParser.new { |op|
18
- # op.on('-p port', 'set the port (default is 4567)') { |val| set :port, Integer(val) }
19
- # op.on('-o addr', 'set the host (default is 0.0.0.0)') { |val| set :bind, val }
20
- # op.on('-e env', 'set the environment (default is development)') { |val| set :environment, val.to_sym }
21
- # op.on('-s server', 'specify rack server/handler (default is thin)') { |val| set :server, val }
22
- # op.on('-x', 'turn on the mutex lock (default is off)') { set :lock, true }
23
- # }.parse!(ARGV.dup)
24
- # end
25
14
  end
26
15
 
27
16
  at_exit { MainRobot.work! if $!.nil? && MainRobot.start_work? }
28
17
  end
29
18
 
30
- # include would include the module in Object
19
+ # include would include the module in Object,
31
20
  # extend only extends the `main` object
32
21
  extend Artoo::Delegator
@@ -3,36 +3,52 @@ module Artoo
3
3
  # of all the running robots
4
4
  class Master
5
5
  include Celluloid
6
- attr_reader :robots
6
+ attr_reader :robots
7
7
 
8
+ # Create new master
9
+ # @param [Collection] robots
8
10
  def initialize(bots)
9
11
  @robots = bots
10
12
  end
11
13
 
14
+ # @param [String] name
15
+ # @return [Robot] robot
12
16
  def robot(name)
13
17
  robots.find {|r| r.name == name}
14
18
  end
15
19
 
20
+ # @param [String] name
21
+ # @return [Collection] robot devices
16
22
  def robot_devices(name)
17
23
  robot(name).devices
18
24
  end
19
25
 
26
+ # @param [String] name
27
+ # @param [String] device_id
28
+ # @return [Device] robot device
20
29
  def robot_device(name, device_id)
21
30
  robot_devices(name)[device_id.intern]
22
31
  end
23
32
 
33
+ # @param [String] name
34
+ # @return [Collection] robot connections
24
35
  def robot_connections(name)
25
36
  robot(name).connections
26
37
  end
27
38
 
39
+ # @param [String] robot_id
40
+ # @param [String] connection_id
41
+ # @return [Device] robot connection
28
42
  def robot_connection(robot_id, connection_id)
29
43
  robot_connections(robot_id)[connection_id.intern]
30
44
  end
31
45
 
46
+ # Do asynchronous work for each robot
32
47
  def start_work
33
48
  robots.each {|r| r.async.work} unless Artoo::Robot.is_running?
34
49
  end
35
50
 
51
+ # Pause work for each robot
36
52
  def pause_work
37
53
  robots.each {|r|
38
54
  Logger.info "pausing #{r.name}"
@@ -40,12 +56,14 @@ module Artoo
40
56
  }
41
57
  end
42
58
 
59
+ # Continue work for each robot
43
60
  def continue_work
44
61
  robots.each {|r| r.async.continue_work}
45
62
  end
46
63
 
64
+ # @deprecated
47
65
  def stop_work
48
66
  #robots.each {|r| r.async.stop_work} unless !Artoo::Robot.is_running?
49
67
  end
50
68
  end
51
- end
69
+ end
@@ -1,28 +1,33 @@
1
1
  module Artoo
2
- # The Artoo::Port class represents port and/or host to be used to connect
2
+ # The Artoo::Port class represents port and/or host to be used to connect
3
3
  # tp a specific individual hardware device.
4
4
  class Port
5
5
  attr_reader :port, :host
6
6
 
7
+ # Create new port
8
+ # @param [Object] data
7
9
  def initialize(data)
8
10
  @is_tcp, @is_serial = false
9
11
  parse(data)
10
12
  end
11
13
 
14
+ # @return [Boolean] True if serial port
12
15
  def is_serial?
13
16
  @is_serial == true
14
17
  end
15
18
 
19
+ # @return [Boolean] True if tcp port
16
20
  def is_tcp?
17
21
  @is_tcp == true
18
22
  end
19
23
 
24
+ # @return [String] port
20
25
  def to_s
21
26
  if is_serial?
22
27
  port
23
28
  else
24
29
  "#{host}:#{port}"
25
- end
30
+ end
26
31
  end
27
32
 
28
33
  private
@@ -48,4 +53,4 @@ module Artoo
48
53
  end
49
54
  end
50
55
  end
51
- end
56
+ end