ruby-player 0.4.1 → 0.5.0

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.
data/NEWS.md CHANGED
@@ -1,3 +1,13 @@
1
+ ## 2012-03-21 0.5.0
2
+
3
+ * Log level by default :notice is removed. Use :info.
4
+ * Added ActArray#power? method.
5
+ * Added #beams and #stored attributes for Gripper class.
6
+ * Added #position, #speed, #acceleration and #current attributes for Actor class.
7
+ * Added #px, #py, #pa, #vx, #vy, #va and #power? attributes for Position2d class. Method #power is deprecated.
8
+ * Added #volts, #percent, #joules and #watts attributes for Power class.
9
+ * Added blobfinder interface
10
+
1
11
  ## 2012-03-06 0.4.1
2
12
 
3
13
  * Fixed bug in logging of warn and error messages
data/README.md CHANGED
@@ -4,7 +4,15 @@ Summary
4
4
  -------------------------------------
5
5
  Ruby Player provide high level client library to access to Player server in pure Ruby.
6
6
 
7
- Currently (2012-01-07) the Ruby Player are developing and testing with Player 3.1.0 latest svn version
7
+ This project is active developing now! *Please don't use it in serious projects.*
8
+
9
+ Why?
10
+ -------------------------------------
11
+ The Player project distributes bindings of client libraries for Ruby and Python but I think that this project has several reasons to be:
12
+
13
+ 1. Pure implementation doesn't require C\C++ libraries of Player, SWIG and compilator. You can use it on any platform with installed Ruby.
14
+ 2. In contrast to standard bindings Ruby Player is spreaded as gem and you can use it with Bundle, RVM and others tools which we all are loving.
15
+ 3. Standard bindings doesn't use the expression of Ruby. Calls of function in C style without blocks, hashes and exceptions.
8
16
 
9
17
  Install
10
18
  -------------------------------------
@@ -32,6 +40,7 @@ The list of support objects and devices of Player.
32
40
 
33
41
  * Client object
34
42
  * ActArray
43
+ * BlobFinder
35
44
  * Gripper
36
45
  * Position2d
37
46
  * Power
data/TODO.md CHANGED
@@ -5,11 +5,13 @@ For supported devices
5
5
 
6
6
  Implement PLAYER_RANGER_DATA_RANGESTAMPED and PLAYER_RANGER_DATA_INTNSTAMPED
7
7
 
8
+ **position2d** - The position2d proxy provides an interface to a mobile robot base
9
+
10
+ Implement PLAYER_POSITION2D_CMD_POS command
11
+
8
12
  Candidates for support
9
13
  --------------------------------------
10
14
 
11
- **blobfinder** - The blobfinder proxy provides an interface to color blob detectors such as the ACTS vision system.
12
-
13
15
  **graphics2d** - The graphics2d proxy provides an interface to the graphics2d.
14
16
 
15
17
  **graphics3d** - The graphics3d proxy provides an interface to the graphics3d.
@@ -5,7 +5,7 @@ Player::Client.connect("localhost") do |robot|
5
5
  #main loop
6
6
  robot.loop(0.05) do
7
7
  puts "Position: x=%{px}, y=%{py}, a=%{pa}" % pos2d.state
8
- r = ranger.rangers
8
+ r = ranger.collect { |r| r.range }
9
9
  puts "Rangers: #{r}"
10
10
 
11
11
  if r[0] < 2.5
@@ -29,6 +29,12 @@ module Player
29
29
  @geom = { px: 0.0, py: 0.0, pz: 0.0, proll: 0.0, ppitch: 0.0, pyaw: 0.0 }
30
30
  end
31
31
 
32
+ # Check common power
33
+ # @return [Boolean]
34
+ def power?
35
+ state[:motor_state] != 0
36
+ end
37
+
32
38
  # Turn on power all actuators
33
39
  # Be careful when turning power on that the array is not obstructed
34
40
  # from its home position in case it moves to it (common behaviour)
@@ -151,10 +157,10 @@ module Player
151
157
  msg[8..-5].unpack("a20" * c).each_with_index do |s,i|
152
158
  @actuators[i] ||= Actuator.new(i,self)
153
159
  @actuators[i].read_state(s)
154
- debug "Get state for actuator ##{i}: " + hash_to_sft(@actuators[i].state)
160
+ debug "Got state for actuator ##{i}: " + hash_to_sft(@actuators[i].state)
155
161
  end
156
162
  @state[:motor_state] = msg[-4,4].unpack("N")[0]
157
- debug "Get state: motor_state=%d" % @state[:motor_state]
163
+ debug "Got state: motor_state=%d" % @state[:motor_state]
158
164
  end
159
165
 
160
166
  def read_geom(msg)
@@ -162,10 +168,10 @@ module Player
162
168
  msg[8..-48].unpack("a80" * c).each_with_index do |s, i|
163
169
  @actuators[i] ||= Actuator.new(i,self)
164
170
  @actuators[i].read_geom(s)
165
- debug "Get geom for actuator ##{i}: " + hash_to_sft(@actuators[i].geom)
171
+ debug "Got geom for actuator ##{i}: " + hash_to_sft(@actuators[i].geom)
166
172
  end
167
173
  fill_hash!(@geom, msg[-48..-1].unpack("G6"))
168
- debug("Get geom: " + hash_to_sft(@geom))
174
+ debug("Got geom: " + hash_to_sft(@geom))
169
175
  end
170
176
  end
171
177
  end
@@ -49,6 +49,34 @@ module Player
49
49
  }
50
50
  end
51
51
 
52
+ # The position of the actuator in m or rad depending on the type.
53
+ # @see #state
54
+ # @return [Float]
55
+ def position
56
+ state[:position]
57
+ end
58
+
59
+ # The speed of the actuator in m/s or rad/s depending on the type.
60
+ # @see #state
61
+ # @return [Float]
62
+ def speed
63
+ state[:speed]
64
+ end
65
+
66
+ # The acceleration of the actuator in m/s^2 or rad/s^2 depending on the type.
67
+ # @see #state
68
+ # @return [Float]
69
+ def acceleration
70
+ state[:acceleration]
71
+ end
72
+
73
+ # The current of the actuator in A.
74
+ # @see #state
75
+ # @return [Float]
76
+ def current
77
+ state[:current]
78
+ end
79
+
52
80
  # Set speed for a joint for all subsequent movements
53
81
  # @param speed - speed setting in rad/s or m/s
54
82
  # @return [Actuator] self
@@ -0,0 +1,79 @@
1
+ # Ruby Player - Ruby client library for Player (tools for robots)
2
+ #
3
+ # Copyright (C) 2012 Aleksey Timin
4
+ #
5
+ # This program is free software: you can redistribute it and/or modify
6
+ # it under the terms of the GNU General Public License as published by
7
+ # the Free Software Foundation, either version 3 of the License, or
8
+ # (at your option) any later version.
9
+ #
10
+ # This program is distributed in the hope that it will be useful,
11
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
12
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13
+ # GNU General Public License for more details.
14
+
15
+ module Player
16
+ # Classs describing a single blob.
17
+ class Blob
18
+ # @return [Hash] blob description => { :id, :color, :area, :x, :y, :left, :right, :top, :bottom, :range }
19
+ attr_reader :state
20
+
21
+ def initialize(index, blobfinder)
22
+ @index, @blobfinder = index, blobfinder
23
+ @state = { id: 0, color: 0, area: 0, x: 0, y: 0, left: 0, right: 0, top: 0, bottom: 0, range: 0.0 }
24
+ end
25
+
26
+ # Blob id
27
+ # @return [Integer]
28
+ def id
29
+ state[:id]
30
+ end
31
+
32
+ # A descriptive color for the blob (useful for gui's).
33
+ # @return [Integer]
34
+ def color
35
+ state[:color]
36
+ end
37
+
38
+ # The blob area [pixels].
39
+ # @return [Integer]
40
+ def area
41
+ state[:area]
42
+ end
43
+
44
+ # The blob centroid [pixels].
45
+ def x
46
+ state[:x]
47
+ end
48
+
49
+ # The blob centroid [pixels].
50
+ def y
51
+ state[:y]
52
+ end
53
+
54
+ # Bounding box for the blob [pixels].
55
+ def left
56
+ state[:left]
57
+ end
58
+
59
+ # Bounding box for the blob [pixels].
60
+ def right
61
+ state[:right]
62
+ end
63
+
64
+ # Bounding box for the blob [pixels].
65
+ def top
66
+ state[:top]
67
+ end
68
+
69
+ # Bounding box for the blob [pixels].
70
+ def bottom
71
+ state[:bottom]
72
+ end
73
+
74
+ # Range to the blob center [m].
75
+ def range
76
+ state[:range]
77
+ end
78
+ end
79
+ end
@@ -0,0 +1,150 @@
1
+ # Ruby Player - Ruby client library for Player (tools for robots)
2
+ #
3
+ # Copyright (C) 2012 Aleksey Timin
4
+ #
5
+ # This program is free software: you can redistribute it and/or modify
6
+ # it under the terms of the GNU General Public License as published by
7
+ # the Free Software Foundation, either version 3 of the License, or
8
+ # (at your option) any later version.
9
+ #
10
+ # This program is distributed in the hope that it will be useful,
11
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
12
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13
+ # GNU General Public License for more details.
14
+
15
+ module Player
16
+ # The blobfinder interface provides access to devices that detect blobs in images
17
+ class BlobFinder < Device
18
+ include Enumerable
19
+
20
+ # Blobfinder data
21
+ # @return [Hash] iby defult{ width: 0.0, height: 0.0, blobs: [] }
22
+ attr_reader :state
23
+
24
+ # Tracking color
25
+ # @see #set_color
26
+ # @return [Hash] by default { channel: 0, rmin: 0, rmax: 0, gmin: 0, gmax: 0, bmin: 0, bmax: 0 }
27
+ attr_reader :color
28
+
29
+ # Imager params.
30
+ # @see #set_imager_params
31
+ # @return [Hash] by default { brightness: 0, contrast: 0, colormode: 0, autogain: 0 }
32
+ attr_reader :imager_params
33
+
34
+ def initialize(dev, client)
35
+ super
36
+ @blobs = []
37
+ @state = { width: 0, height: 0, blobs: @blobs }
38
+ @color = { channel: 0, rmin: 0, rmax: 0, gmin: 0, gmax: 0, bmin: 0, bmax: 0 }
39
+ @imager_params = { brightness: 0, contrast: 0, colormode: 0, autogain: 0 }
40
+ end
41
+
42
+ # The image width.
43
+ # @return [Integer]
44
+ def width
45
+ state[:width]
46
+ end
47
+
48
+ # The image height.
49
+ # @return [Integer]
50
+ def height
51
+ state[:height]
52
+ end
53
+
54
+ # The list of blobs.
55
+ # @return [Array]
56
+ def blobs
57
+ state[:blobs]
58
+ end
59
+
60
+ # Query color settings
61
+ # @return [BlobFinder] self
62
+ def query_color
63
+ send_message(PLAYER_MSGTYPE_REQ, PLAYER_BLOBFINDER_REQ_GET_COLOR)
64
+ self
65
+ end
66
+
67
+ # Set tracking color.
68
+ # @param [Hash] color
69
+ # @option [Integer] color :chanel For devices that can track multiple colors, indicate which color channel we are defining with this structure.
70
+ # @option [Integer] color :rmin RGB minimum and max values (0-255)
71
+ # @option [Integer] color :rmax RGB maximum and max values (0-255)
72
+ # @option [Integer] color :gmin RGB minimum and max values (0-255)
73
+ # @option [Integer] color :gmax RGB maximum and max values (0-255)
74
+ # @option [Integer] color :bmin RGB minimum and max values (0-255)
75
+ # @option [Integer] color :bmax RGB maximum and max values (0-255)
76
+ # @return [BlobFinder] self
77
+ def set_color(color={})
78
+ data = to_a_by_default(color, @color)
79
+
80
+ send_message(PLAYER_MSGTYPE_REQ, PLAYER_BLOBFINDER_REQ_SET_COLOR, data.pack("N*"))
81
+ self
82
+ end
83
+
84
+ # Set imager params
85
+ # Imaging sensors that do blob tracking generally have some sorts of image quality parameters that you can tweak.
86
+ # @param [Hash] params
87
+ # @option [Integer] params :brightness brightness (0-255)
88
+ # @option [Integer] params :contrast contrast (0-255)
89
+ # @option [Integer] params :color color mode (0=RGB/AutoWhiteBalance Off, 1=RGB/AutoWhiteBalance On, 2=YCrCB/AWB Off, 3=YCrCb/AWB On)
90
+ # @option [Integer] params :autogain auto gain (0=off, 1=on)
91
+ # @return [BlobFinder] self
92
+ def set_imager_params(params={})
93
+ data = to_a_by_default(params, @imager_params)
94
+ send_message(PLAYER_MSGTYPE_REQ, PLAYER_BLOBFINDER_REQ_SET_IMAGER_PARAMS, data.pack("N*"))
95
+ self
96
+ end
97
+
98
+ # Get blob
99
+ # @param [Integer] blob index
100
+ # @return [Blob] blob
101
+ def [](index)
102
+ @blobs[index] ||= Blob.new(index, self)
103
+ end
104
+
105
+ def each
106
+ @blobs.each { |b| yield b }
107
+ end
108
+
109
+ def fill(hdr, msg)
110
+ case hdr.subtype
111
+ when PLAYER_BLOBFINDER_DATA_BLOBS
112
+ read_data(msg)
113
+ else
114
+ unexpected_message hdr
115
+ end
116
+ end
117
+
118
+ def handle_response(hdr, msg)
119
+ case hdr.subtype
120
+ when PLAYER_BLOBFINDER_REQ_GET_COLOR
121
+ read_color(msg)
122
+ when 1,2
123
+ nil
124
+ else
125
+ unexpected_message hdr
126
+ end
127
+ end
128
+
129
+ private
130
+ def read_data(msg)
131
+ data = msg[0..16].unpack("N*")
132
+ state[:width] = data[0]
133
+ state[:height] = data[1]
134
+
135
+ debug "Got image size #{state[:width]}x#{state[:height]}"
136
+
137
+ blob_count = data[2] + data[3]*256
138
+ blob_count.times do |i|
139
+ blob_data = msg[i*40 + 16, 40].unpack("N9g")
140
+ fill_hash!(self[i].state, blob_data)
141
+ debug "Got blob: " + hash_to_sft(self[i].state)
142
+ end
143
+ end
144
+
145
+ def read_color(msg)
146
+ fill_hash!(@color, msg.unpack("N7"))
147
+ debug "Got color: " + hash_to_sft(@color)
148
+ end
149
+ end
150
+ end
@@ -12,6 +12,8 @@
12
12
  # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13
13
  # GNU General Public License for more details.
14
14
 
15
+ require "socket"
16
+
15
17
  module Player
16
18
  # The client object manages the connection with the Player server
17
19
  #
@@ -23,7 +25,7 @@ module Player
23
25
  # pos2d.set_speed(vx: 1, vy: 0, va: 0.2)
24
26
  # #main loop
25
27
  # robot.loop do
26
- # puts "Position: x=%{px}, y=%{py}, a=%{pa}" % pos2d.position
28
+ # puts "Position: x=%{px}, y=%{py}, a=%{pa}" % pos2d.state
27
29
  # end
28
30
  # end
29
31
  class Client < Device
@@ -35,10 +37,10 @@ module Player
35
37
  # @param [String] host host of Player server
36
38
  # @param [Hash] opts client options
37
39
  # @option opts :port port of connection
38
- # @option opts :log_level level of log messages [:debug,:notice, :warn, :error] default :notice
40
+ # @option opts :log_level level of log messages [:debug, :info, :warn, :error] default :info
39
41
  def initialize(host, opts = {})
40
42
  port = opts[:port] || 6665
41
- @log_level = (opts[:log_level] || :notice).to_sym
43
+ @log_level = (opts[:log_level] || :info).to_sym
42
44
 
43
45
  @socket = TCPSocket.new(host, port)
44
46
  @addr = DevAddr.new(host: 0, robot: 0, interface: PLAYER_PLAYER_CODE, index: 0)
@@ -46,7 +48,8 @@ module Player
46
48
  @devices = []
47
49
 
48
50
  banner = @socket.read(PLAYER_IDENT_STRLEN)
49
- notice "Connect with #{banner} in #{host}:#{port}"
51
+ info "Connect with #{banner} in #{host}:#{port}"
52
+ warn "This software required Player version >= 3.1.0" if banner[/\d.\d/].to_f < 3.1
50
53
  send_message PLAYER_MSGTYPE_REQ, PLAYER_PLAYER_REQ_DATAMODE, [PLAYER_DATAMODE_PULL].pack("N")
51
54
 
52
55
  debug "Set delivery mode in PULL"
@@ -85,13 +88,13 @@ module Player
85
88
  index = opts[:index] || 0
86
89
  access = opts[:access] || PLAYER_OPEN_MODE
87
90
 
88
- notice "Subscribing to #{type}:#{index}"
91
+ info "Subscribing to #{type}:#{index}"
89
92
  data = DevAddr.new(interface: code, index: index).to_a + [access, 0, 0]
90
93
  send_message PLAYER_MSGTYPE_REQ, PLAYER_PLAYER_REQ_DEV, data.pack("N*")
91
94
 
92
95
  read!
93
96
 
94
- @devices.select { |d| d.addr.interface == code && d.addr.index == index}.first
97
+ @dev
95
98
  end
96
99
 
97
100
  # Check connection
@@ -120,7 +123,7 @@ module Player
120
123
  end
121
124
  end
122
125
 
123
- def write(hdr, msg)
126
+ def send_message_with_hdr(hdr, msg)
124
127
  send_header hdr
125
128
  @socket.write msg
126
129
  @socket.flush
@@ -132,7 +135,7 @@ module Player
132
135
  nil
133
136
  when PLAYER_PLAYER_REQ_DEV
134
137
  # read device identifier
135
- dev = DevAddr.decode(msg[0,PLAYERXDR_DEVADDR_SIZE])
138
+ dev_addr = DevAddr.decode(msg[0,PLAYERXDR_DEVADDR_SIZE])
136
139
  # read the granted access and driver name
137
140
  data = msg[PLAYERXDR_DEVADDR_SIZE,8].unpack("N*")
138
141
  access = data[0]
@@ -140,12 +143,18 @@ module Player
140
143
  drv_name = msg[-data[1]-2..-1]
141
144
 
142
145
  if access == PLAYER_ERROR_MODE
143
- raise_error "Error subscribing to " + dev.interface_name + ":" + dev.index
146
+ raise_error "Error subscribing to " + dev_addr.interface_name + ":" + dev_addr.index
144
147
  end
145
148
 
146
- debug "Got response: #{dev.interface_name}:#{dev.index} (driver name - #{drv_name})"
147
-
148
- @devices << make_device(dev)
149
+ debug "Got response: #{dev_addr.interface_name}:#{dev_addr.index} (driver name - #{drv_name})"
150
+
151
+ @dev = make_device(dev_addr)
152
+ if @devices.one? { |d| d.addr == dev_addr }
153
+ warn "The device #{dev_addr.interface_name}:#{dev_addr.index} has already been subscribed"
154
+ @dev = nil
155
+ else
156
+ @devices << @dev
157
+ end
149
158
  when PLAYER_PLAYER_REQ_DATAMODE, PLAYER_PLAYER_REQ_DATA
150
159
  nil
151
160
  else
@@ -23,20 +23,20 @@ module Player
23
23
  end
24
24
  end
25
25
 
26
- def notice(msg)
27
- if [:debug, :notice].include?(@log_level)
28
- puts log_msg(:notice, msg).to_ansi.normal
26
+ def info(msg)
27
+ if [:debug, :info].include?(@log_level)
28
+ puts log_msg(:info, msg).to_ansi.normal
29
29
  end
30
30
  end
31
31
 
32
32
  def warn(msg)
33
- if [:debug, :notice, :warn].include?(@log_level)
33
+ if [:debug, :info, :warn].include?(@log_level)
34
34
  puts log_msg(:warn, msg).to_ansi.blue
35
35
  end
36
36
  end
37
37
 
38
38
  def error(msg)
39
- if [:debug, :notice, :warn, :debug].include?(@log_level)
39
+ if [:debug, :info, :warn, :debug].include?(@log_level)
40
40
  puts log_msg(:error, msg).to_ansi.red
41
41
  end
42
42
  end
@@ -69,8 +69,12 @@ module Player
69
69
  end
70
70
  end
71
71
 
72
+ def to_a_by_default(src, default)
73
+ default.keys.map { |k| src[k] || default[k] }
74
+ end
75
+
72
76
  def unexpected_message(hdr)
73
- warn "Get unexpection message type #{hdr.type_name}::#{hdr.subtype_name} for #@addr"
77
+ warn "Got unexpection message type #{hdr.type_name}::#{hdr.subtype_name} for #@addr"
74
78
  end
75
79
 
76
80
  def hash_to_sft(hash)
@@ -292,6 +292,7 @@ module Player
292
292
 
293
293
  PLAYER_BLOBFINDER_REQ_SET_COLOR = 1
294
294
  PLAYER_BLOBFINDER_REQ_SET_IMAGER_PARAMS = 2
295
+ PLAYER_BLOBFINDER_REQ_GET_COLOR = 3
295
296
  PLAYER_BLOBFINDER_DATA_BLOBS = 1
296
297
 
297
298
  PLAYER_BUMPER_REQ_GET_GEOM = 1
@@ -43,7 +43,7 @@ module Player
43
43
  end
44
44
 
45
45
  def to_s
46
- "device addr [#@host:#@robot] #@interface_name:#@index"
46
+ "device addr [#@host:#@robot] #{interface_name}:#@index"
47
47
  end
48
48
 
49
49
  def to_a
@@ -11,7 +11,6 @@
11
11
  # but WITHOUT ANY WARRANTY; without even the implied warranty of
12
12
  # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13
13
  # GNU General Public License for more details.
14
- require "socket"
15
14
 
16
15
  module Player
17
16
  # Basic class for all intrefaces
@@ -35,7 +34,7 @@ module Player
35
34
  end
36
35
 
37
36
  def send_message(type, subtype, msg="")
38
- @client.write( Header.new(
37
+ @client.send_message_with_hdr( Header.new(
39
38
  dev_addr: @addr,
40
39
  type: type,
41
40
  subtype: subtype,
@@ -77,6 +77,22 @@ module Player
77
77
  self
78
78
  end
79
79
 
80
+ # Provides information on how far into the gripper an object is.
81
+ # For most grippers, this will be a bit mask, with each bit representing whether
82
+ # a beam has been interrupted or not.
83
+ # @see #state
84
+ # @retun [Integer]
85
+ def beams
86
+ state[:beams]
87
+ end
88
+
89
+ # Number of currently stored objects
90
+ # @see #state
91
+ # @retun [Integer]
92
+ def stored
93
+ state[:stored]
94
+ end
95
+
80
96
  # Check openinig
81
97
  def open?
82
98
  state[:state] & PLAYER_GRIPPER_STATE_OPEN > 0
@@ -98,24 +114,28 @@ module Player
98
114
  end
99
115
 
100
116
  # Tells the gripper to open
117
+ # @return [Gripper] self
101
118
  def open!
102
119
  send_message(PLAYER_MSGTYPE_CMD, PLAYER_GRIPPER_CMD_OPEN)
103
120
  self
104
121
  end
105
122
 
106
123
  # Tells the gripper to close
124
+ # @return [Gripper] self
107
125
  def close!
108
126
  send_message(PLAYER_MSGTYPE_CMD, PLAYER_GRIPPER_CMD_CLOSE)
109
127
  self
110
128
  end
111
129
 
112
130
  # Tells the gripper to stop
131
+ # @return [Gripper] self
113
132
  def stop!
114
133
  send_message(PLAYER_MSGTYPE_CMD, PLAYER_GRIPPER_CMD_STOP)
115
134
  self
116
135
  end
117
136
 
118
137
  # Tells the gripper to store whatever it is holding.
138
+ # @return [Gripper] self
119
139
  def store!
120
140
  send_message(PLAYER_MSGTYPE_CMD, PLAYER_GRIPPER_CMD_STORE)
121
141
  self
@@ -123,6 +143,7 @@ module Player
123
143
 
124
144
  # Tells the gripper to retrieve a stored object (so that it can be put back into the world).
125
145
  # The opposite of store.
146
+ # @return [Gripper] self
126
147
  def retrieve!
127
148
  send_message(PLAYER_MSGTYPE_CMD, PLAYER_GRIPPER_CMD_RETRIEVE)
128
149
  self
@@ -149,23 +170,23 @@ module Player
149
170
  private
150
171
  def read_state(msg)
151
172
  fill_hash!(@state, msg.unpack("NNN"))
152
- debug "Get state: " + hash_to_sft(@state)
173
+ debug "Got state: " + hash_to_sft(@state)
153
174
  end
154
175
 
155
176
  def read_geom(msg)
156
177
  data = msg.unpack("G12NN")
157
178
  fill_hash!(@geom[:pose], data)
158
- debug "Get pose: " + hash_to_sft(@geom[:pose])
179
+ debug "Got pose: " + hash_to_sft(@geom[:pose])
159
180
 
160
181
  fill_hash!(@geom[:outer_size], data)
161
- debug "Get outer size: " + hash_to_sft(@geom[:outer_size])
182
+ debug "Got outer size: " + hash_to_sft(@geom[:outer_size])
162
183
 
163
184
  fill_hash!(@geom[:inner_size], data)
164
- debug "Get inner size: " + hash_to_sft(@geom[:inner_size])
185
+ debug "Got inner size: " + hash_to_sft(@geom[:inner_size])
165
186
 
166
187
  @geom[:number_beams] = data.shift
167
188
  @geom[:capacity] = data.shift
168
- debug("Get number_beams=%{number_beams}, capacity=%{capacity}" % @geom)
189
+ debug("Got number_beams=%{number_beams}, capacity=%{capacity}" % @geom)
169
190
  end
170
191
  end
171
192
  end
@@ -20,7 +20,7 @@ module Player
20
20
  attr_reader :dev_addr, :type, :subtype, :time, :seq, :size
21
21
 
22
22
  def initialize(param = {})
23
- @dev_addr = param[:dev_addr]
23
+ @dev_addr = param[:dev_addr] || DevAddr.new
24
24
  @type = param[:type].to_i
25
25
  @subtype = param[:subtype].to_i
26
26
  @time = param[:time] || Time.now.to_f / 1000