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 +10 -0
- data/README.md +10 -1
- data/TODO.md +4 -2
- data/examples/simple_example.rb +1 -1
- data/lib/ruby-player/actarray.rb +10 -4
- data/lib/ruby-player/actuator.rb +28 -0
- data/lib/ruby-player/blob.rb +79 -0
- data/lib/ruby-player/blob_finder.rb +150 -0
- data/lib/ruby-player/client.rb +21 -12
- data/lib/ruby-player/common.rb +10 -6
- data/lib/ruby-player/constants.rb +1 -0
- data/lib/ruby-player/dev_addr.rb +1 -1
- data/lib/ruby-player/device.rb +1 -2
- data/lib/ruby-player/gripper.rb +26 -5
- data/lib/ruby-player/header.rb +1 -1
- data/lib/ruby-player/position2d.rb +67 -18
- data/lib/ruby-player/power.rb +31 -1
- data/lib/ruby-player/ranger.rb +20 -20
- data/lib/ruby-player/version.rb +1 -1
- data/lib/ruby-player.rb +2 -0
- data/spec/actarray_spec.rb +8 -0
- data/spec/actuator_spec.rb +20 -0
- data/spec/blob_finder_spec.rb +96 -0
- data/spec/blob_spec.rb +63 -0
- data/spec/client_spec.rb +47 -6
- data/spec/dev_addr_spec.rb +51 -0
- data/spec/device_spec.rb +27 -0
- data/spec/gripper_spec.rb +14 -4
- data/spec/header_spec.rb +61 -0
- data/spec/position2d_spec.rb +38 -0
- data/spec/power_spec.rb +20 -0
- data/spec/ranger_spec.rb +0 -2
- metadata +24 -17
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
|
-
|
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.
|
data/examples/simple_example.rb
CHANGED
data/lib/ruby-player/actarray.rb
CHANGED
@@ -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 "
|
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 "
|
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 "
|
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("
|
174
|
+
debug("Got geom: " + hash_to_sft(@geom))
|
169
175
|
end
|
170
176
|
end
|
171
177
|
end
|
data/lib/ruby-player/actuator.rb
CHANGED
@@ -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
|
data/lib/ruby-player/client.rb
CHANGED
@@ -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.
|
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
|
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] || :
|
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
|
-
|
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
|
-
|
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
|
-
@
|
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
|
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
|
-
|
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 " +
|
146
|
+
raise_error "Error subscribing to " + dev_addr.interface_name + ":" + dev_addr.index
|
144
147
|
end
|
145
148
|
|
146
|
-
debug "Got response: #{
|
147
|
-
|
148
|
-
@
|
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
|
data/lib/ruby-player/common.rb
CHANGED
@@ -23,20 +23,20 @@ module Player
|
|
23
23
|
end
|
24
24
|
end
|
25
25
|
|
26
|
-
def
|
27
|
-
if [:debug, :
|
28
|
-
puts log_msg(:
|
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, :
|
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, :
|
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 "
|
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)
|
data/lib/ruby-player/dev_addr.rb
CHANGED
data/lib/ruby-player/device.rb
CHANGED
@@ -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.
|
37
|
+
@client.send_message_with_hdr( Header.new(
|
39
38
|
dev_addr: @addr,
|
40
39
|
type: type,
|
41
40
|
subtype: subtype,
|
data/lib/ruby-player/gripper.rb
CHANGED
@@ -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 "
|
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 "
|
179
|
+
debug "Got pose: " + hash_to_sft(@geom[:pose])
|
159
180
|
|
160
181
|
fill_hash!(@geom[:outer_size], data)
|
161
|
-
debug "
|
182
|
+
debug "Got outer size: " + hash_to_sft(@geom[:outer_size])
|
162
183
|
|
163
184
|
fill_hash!(@geom[:inner_size], data)
|
164
|
-
debug "
|
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("
|
189
|
+
debug("Got number_beams=%{number_beams}, capacity=%{capacity}" % @geom)
|
169
190
|
end
|
170
191
|
end
|
171
192
|
end
|
data/lib/ruby-player/header.rb
CHANGED
@@ -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
|