artoo 0.4.0 → 0.4.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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