ruby-player 0.4.1 → 0.5.0

Sign up to get free protection for your applications and to get access to all the features.
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