ruby-player 0.3.0 → 0.4.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 +7 -1
- data/README.md +22 -11
- data/TODO.md +0 -4
- data/lib/ruby-player.rb +4 -1
- data/lib/ruby-player/actarray.rb +171 -0
- data/lib/ruby-player/actuator.rb +133 -0
- data/lib/ruby-player/client.rb +4 -2
- data/lib/ruby-player/common.rb +16 -11
- data/lib/ruby-player/constants.rb +14 -0
- data/lib/ruby-player/dev_addr.rb +1 -1
- data/lib/ruby-player/device.rb +2 -2
- data/lib/ruby-player/gripper.rb +5 -5
- data/lib/ruby-player/header.rb +2 -1
- data/lib/ruby-player/position2d.rb +22 -10
- data/lib/ruby-player/power.rb +2 -2
- data/lib/ruby-player/ranger.rb +58 -30
- data/lib/ruby-player/sensor.rb +43 -0
- data/lib/ruby-player/version.rb +2 -2
- data/spec/actarray_spec.rb +129 -0
- data/spec/actuator_spec.rb +89 -0
- data/spec/client_spec.rb +20 -0
- data/spec/position2d_spec.rb +2 -2
- data/spec/ranger_spec.rb +11 -19
- metadata +21 -16
data/NEWS.md
CHANGED
@@ -1,6 +1,12 @@
|
|
1
|
-
## 2012-02-
|
1
|
+
## 2012-02-21 0.4.0
|
2
2
|
|
3
|
+
* Changed API for Ranger. Now ranger[0].geom intead of ranger.geom[:sensors][0]! Methods #ranger, #intenities is depricated.
|
4
|
+
* Added actarray interface
|
5
|
+
* Methods #turn_on! ans #turn_off! are renamed to #power_on! and #power_off!. #turn_on! and #turn_off! is deprecated
|
3
6
|
* Method Position2d::position is renamed to Position2d::state. Position2d::position is deprecated
|
7
|
+
|
8
|
+
## 2012-02-17 0.3.0
|
9
|
+
|
4
10
|
* Added gripper interface
|
5
11
|
|
6
12
|
## 2012-02-16 0.2.0
|
data/README.md
CHANGED
@@ -6,16 +6,6 @@ Ruby Player provide high level client library to access to Player server in pure
|
|
6
6
|
|
7
7
|
Currently (2012-01-07) the Ruby Player are developing and testing with Player 3.1.0 latest svn version
|
8
8
|
|
9
|
-
API coverage
|
10
|
-
-------------------------------------
|
11
|
-
The list of support objects and devices of Player.
|
12
|
-
|
13
|
-
* Client object
|
14
|
-
* Gripper
|
15
|
-
* Position2d
|
16
|
-
* Power
|
17
|
-
* Ranger
|
18
|
-
|
19
9
|
Install
|
20
10
|
-------------------------------------
|
21
11
|
|
@@ -32,15 +22,36 @@ Example
|
|
32
22
|
#main loop
|
33
23
|
robot.loop do
|
34
24
|
puts "Position: x=%{px}, y=%{py}, a=%{pa}" % pos2d.state
|
35
|
-
puts "Rangers: #{ranger.
|
25
|
+
puts "Rangers: #{ranger.collect { |r| r.range }}"
|
36
26
|
end
|
37
27
|
end
|
38
28
|
|
29
|
+
API coverage
|
30
|
+
-------------------------------------
|
31
|
+
The list of support objects and devices of Player.
|
32
|
+
|
33
|
+
* Client object
|
34
|
+
* ActArray
|
35
|
+
* Gripper
|
36
|
+
* Position2d
|
37
|
+
* Power
|
38
|
+
* Ranger
|
39
|
+
|
40
|
+
|
41
|
+
Requirements
|
42
|
+
-------------------------------------
|
43
|
+
|
44
|
+
* Ruby 1.9.2 or later
|
45
|
+
* Player 3.1.0 or later
|
46
|
+
* For examples Stage 4.1.0 or later
|
47
|
+
|
39
48
|
References
|
40
49
|
-------------------------------------
|
41
50
|
|
42
51
|
[Home page](http://www.github.com/flipback/ruby-player)
|
43
52
|
|
53
|
+
[Documentation](http://rubydoc.info/gems/ruby-player/)
|
54
|
+
|
44
55
|
[Player project](http://playerstage.sourceforge.net/)
|
45
56
|
|
46
57
|
[C API Player](http://playerstage.sourceforge.net/doc/Player-3.0.2/player/group__player__clientlib__libplayerc.html)
|
data/TODO.md
CHANGED
@@ -8,16 +8,12 @@ Implement PLAYER_RANGER_DATA_RANGESTAMPED and PLAYER_RANGER_DATA_INTNSTAMPED
|
|
8
8
|
Candidates for support
|
9
9
|
--------------------------------------
|
10
10
|
|
11
|
-
**actarray** - The actarray proxy provides an interface to actuator arrays such as the ActivMedia Pioneer Arm.
|
12
|
-
|
13
11
|
**blobfinder** - The blobfinder proxy provides an interface to color blob detectors such as the ACTS vision system.
|
14
12
|
|
15
13
|
**graphics2d** - The graphics2d proxy provides an interface to the graphics2d.
|
16
14
|
|
17
15
|
**graphics3d** - The graphics3d proxy provides an interface to the graphics3d.
|
18
16
|
|
19
|
-
**gripper** - The gripper proxy provides an interface to the gripper.
|
20
|
-
|
21
17
|
**simulation** - The simulation proxy is used to interact with objects in a simulation.
|
22
18
|
|
23
19
|
Device proxies are not started to develop
|
data/lib/ruby-player.rb
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
# Ruby Player - Ruby client library for Player (tools for robots)
|
2
2
|
#
|
3
|
-
# Copyright (C) 2012 Timin
|
3
|
+
# Copyright (C) 2012 Aleksey Timin
|
4
4
|
#
|
5
5
|
# This program is free software: you can redistribute it and/or modify
|
6
6
|
# it under the terms of the GNU General Public License as published by
|
@@ -23,9 +23,12 @@ require "ruby-player/device"
|
|
23
23
|
require "ruby-player/client"
|
24
24
|
|
25
25
|
#interfaces
|
26
|
+
require "ruby-player/actuator"
|
27
|
+
require "ruby-player/actarray"
|
26
28
|
require "ruby-player/gripper"
|
27
29
|
require "ruby-player/position2d"
|
28
30
|
require "ruby-player/power"
|
31
|
+
require "ruby-player/sensor"
|
29
32
|
require "ruby-player/ranger"
|
30
33
|
|
31
34
|
|
@@ -0,0 +1,171 @@
|
|
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 actuator array interface provides access to an array of actuators.
|
17
|
+
class ActArray < Device
|
18
|
+
include Enumerable
|
19
|
+
|
20
|
+
attr_reader :state
|
21
|
+
|
22
|
+
# Geometry of base actarray
|
23
|
+
attr_reader :geom
|
24
|
+
|
25
|
+
def initialize(dev, client)
|
26
|
+
super
|
27
|
+
@actuators = []
|
28
|
+
@state = { motor_state: 0 }
|
29
|
+
@geom = { px: 0.0, py: 0.0, pz: 0.0, proll: 0.0, ppitch: 0.0, pyaw: 0.0 }
|
30
|
+
end
|
31
|
+
|
32
|
+
# Turn on power all actuators
|
33
|
+
# Be careful when turning power on that the array is not obstructed
|
34
|
+
# from its home position in case it moves to it (common behaviour)
|
35
|
+
# @return [ActArray] self
|
36
|
+
def power_on!
|
37
|
+
send_message(PLAYER_MSGTYPE_REQ, PLAYER_ACTARRAY_REQ_POWER, [1].pack("N"))
|
38
|
+
self
|
39
|
+
end
|
40
|
+
|
41
|
+
# Turn off power all actuators
|
42
|
+
# Be careful when turning power on that the array is not obstructed
|
43
|
+
# from its home position in case it moves to it (common behaviour)
|
44
|
+
# @return [ActArray] self
|
45
|
+
def power_off!
|
46
|
+
send_message(PLAYER_MSGTYPE_REQ, PLAYER_ACTARRAY_REQ_POWER, [0].pack("N"))
|
47
|
+
self
|
48
|
+
end
|
49
|
+
|
50
|
+
# Turn on brakes all actuators
|
51
|
+
# @return [ActArray] self
|
52
|
+
def brakes_on!
|
53
|
+
send_message(PLAYER_MSGTYPE_REQ, PLAYER_ACTARRAY_REQ_BRAKES, [1].pack("N"))
|
54
|
+
self
|
55
|
+
end
|
56
|
+
|
57
|
+
# Turn off brakes all actuators
|
58
|
+
# @return [ActArray] self
|
59
|
+
def brakes_off!
|
60
|
+
send_message(PLAYER_MSGTYPE_REQ, PLAYER_ACTARRAY_REQ_BRAKES, [0].pack("N"))
|
61
|
+
self
|
62
|
+
end
|
63
|
+
|
64
|
+
# Query actarray geometry
|
65
|
+
# @return [ActArray] self
|
66
|
+
def query_geom
|
67
|
+
send_message(PLAYER_MSGTYPE_REQ, PLAYER_ACTARRAY_REQ_GET_GEOM)
|
68
|
+
self
|
69
|
+
end
|
70
|
+
|
71
|
+
# Get single actuator
|
72
|
+
# @param joint - number of actuator
|
73
|
+
# @return [Actuator] actuator
|
74
|
+
def [](joint)
|
75
|
+
@actuators[joint] ||= Actuator.new(joint, self)
|
76
|
+
end
|
77
|
+
|
78
|
+
# Tells all joints/actuators to attempt to move to the given positions.
|
79
|
+
# @param [Array] poses
|
80
|
+
# @return [ActArray] self
|
81
|
+
def set_positions(poses)
|
82
|
+
send_message(
|
83
|
+
PLAYER_MSGTYPE_CMD, PLAYER_ACTARRAY_CMD_MULTI_POS,
|
84
|
+
([poses.size] + poses).pack("Ng*")
|
85
|
+
)
|
86
|
+
self
|
87
|
+
end
|
88
|
+
|
89
|
+
# Tells all joints/actuators to attempt to move with the given speed.
|
90
|
+
# @param [Array] speeds
|
91
|
+
# @return [ActArray] self
|
92
|
+
def set_speeds(speeds)
|
93
|
+
send_message(
|
94
|
+
PLAYER_MSGTYPE_CMD, PLAYER_ACTARRAY_CMD_MULTI_SPEED,
|
95
|
+
([speeds.size] + speeds).pack("Ng*")
|
96
|
+
)
|
97
|
+
self
|
98
|
+
end
|
99
|
+
|
100
|
+
# Command to go to home position for all joints
|
101
|
+
# @return [ActArray] self
|
102
|
+
def go_home!
|
103
|
+
send_message(PLAYER_MSGTYPE_CMD, PLAYER_ACTARRAY_CMD_HOME, [-1].pack("N"))
|
104
|
+
self
|
105
|
+
end
|
106
|
+
|
107
|
+
# Command all joints to attempt to move with the given current
|
108
|
+
# @param curr -current to move with
|
109
|
+
# @return [ActArray] self
|
110
|
+
def set_current_all(curr)
|
111
|
+
send_message(PLAYER_MSGTYPE_CMD, PLAYER_ACTARRAY_CMD_CURRENT, [-1, curr].pack("Ng"))
|
112
|
+
self
|
113
|
+
end
|
114
|
+
|
115
|
+
# Tells all joints/actuators to attempt to move with the given current.
|
116
|
+
# @param [Array] currents
|
117
|
+
# @return [ActArray] self
|
118
|
+
def set_currents(currents)
|
119
|
+
send_message(
|
120
|
+
PLAYER_MSGTYPE_CMD, PLAYER_ACTARRAY_CMD_MULTI_CURRENT,
|
121
|
+
([currents.size] + currents).pack("Ng*")
|
122
|
+
)
|
123
|
+
self
|
124
|
+
end
|
125
|
+
|
126
|
+
def each
|
127
|
+
@actuators.each { |a| yield a }
|
128
|
+
end
|
129
|
+
|
130
|
+
def fill(hdr, msg)
|
131
|
+
case hdr.subtype
|
132
|
+
when PLAYER_ACTARRAY_DATA_STATE
|
133
|
+
read_state(msg)
|
134
|
+
else
|
135
|
+
unexpected_message hdr
|
136
|
+
end
|
137
|
+
end
|
138
|
+
|
139
|
+
def handle_response(hdr, msg)
|
140
|
+
case hdr.subtype
|
141
|
+
when PLAYER_ACTARRAY_REQ_GET_GEOM
|
142
|
+
read_geom(msg)
|
143
|
+
else
|
144
|
+
unexpected_message hdr
|
145
|
+
end
|
146
|
+
end
|
147
|
+
|
148
|
+
private
|
149
|
+
def read_state(msg)
|
150
|
+
c = msg[0,4].unpack("NN")[0]
|
151
|
+
msg[8..-5].unpack("a20" * c).each_with_index do |s,i|
|
152
|
+
@actuators[i] ||= Actuator.new(i,self)
|
153
|
+
@actuators[i].read_state(s)
|
154
|
+
debug "Get state for actuator ##{i}: " + hash_to_sft(@actuators[i].state)
|
155
|
+
end
|
156
|
+
@state[:motor_state] = msg[-4,4].unpack("N")[0]
|
157
|
+
debug "Get state: motor_state=%d" % @state[:motor_state]
|
158
|
+
end
|
159
|
+
|
160
|
+
def read_geom(msg)
|
161
|
+
c = msg[0,4].unpack("N")[0]
|
162
|
+
msg[8..-48].unpack("a80" * c).each_with_index do |s, i|
|
163
|
+
@actuators[i] ||= Actuator.new(i,self)
|
164
|
+
@actuators[i].read_geom(s)
|
165
|
+
debug "Get geom for actuator ##{i}: " + hash_to_sft(@actuators[i].geom)
|
166
|
+
end
|
167
|
+
fill_hash!(@geom, msg[-48..-1].unpack("G6"))
|
168
|
+
debug("Get geom: " + hash_to_sft(@geom))
|
169
|
+
end
|
170
|
+
end
|
171
|
+
end
|
@@ -0,0 +1,133 @@
|
|
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 actuator of actarray
|
17
|
+
# @see Player::ActArray
|
18
|
+
class Actuator
|
19
|
+
include Common
|
20
|
+
|
21
|
+
# Number in actarray
|
22
|
+
# @return [Integer]
|
23
|
+
attr_reader :joint
|
24
|
+
|
25
|
+
# State of actuator
|
26
|
+
#
|
27
|
+
# *:position* - The position of the actuator in m or rad depending on the type.
|
28
|
+
#
|
29
|
+
# *:speed* - The speed of the actuator in m/s or rad/s depending on the type.
|
30
|
+
#
|
31
|
+
# *:acceleration* - The acceleration of the actuator in m/s^2 or rad/s^2 depending on the type.
|
32
|
+
#
|
33
|
+
# *:current* - The current of the actuator in A.
|
34
|
+
#
|
35
|
+
# *:state* - The current state of the actuator. @see #idle?, #moving?, #braked?, #stalled?
|
36
|
+
attr_reader :state
|
37
|
+
|
38
|
+
# Geometry of actuator
|
39
|
+
attr_reader :geom
|
40
|
+
|
41
|
+
def initialize(joint, actarray)
|
42
|
+
@joint, @actarray = joint, actarray
|
43
|
+
@state = { position: 0.0, speed: 0.0, acceleration: 0.0, current: 0.0, state: 0 }
|
44
|
+
@geom = { type: 0, length: 0.0,
|
45
|
+
proll: 0.0, ppitch: 0.0, pyaw: 0.0,
|
46
|
+
px: 0.0, py: 0.0, pz: 0.0,
|
47
|
+
min: 0.0, centre: 0.0, max: 0.0, home: 0.0,
|
48
|
+
config_speed: 0.0, hasbreaks: 0
|
49
|
+
}
|
50
|
+
end
|
51
|
+
|
52
|
+
# Set speed for a joint for all subsequent movements
|
53
|
+
# @param speed - speed setting in rad/s or m/s
|
54
|
+
# @return [Actuator] self
|
55
|
+
def set_speed_config(speed)
|
56
|
+
@actarray.send_message(PLAYER_MSGTYPE_REQ, PLAYER_ACTARRAY_REQ_SPEED, [@joint, speed].pack("Ng"))
|
57
|
+
self
|
58
|
+
end
|
59
|
+
|
60
|
+
# Set accelelarion for a joint for all subsequent movements
|
61
|
+
# @param accel - accelelarion setting in rad/s^2 or m/s^2
|
62
|
+
# @return [Actuator] self
|
63
|
+
def set_accel_config(accel)
|
64
|
+
@actarray.send_message(PLAYER_MSGTYPE_REQ, PLAYER_ACTARRAY_REQ_ACCEL, [@joint, accel].pack("Ng"))
|
65
|
+
self
|
66
|
+
end
|
67
|
+
|
68
|
+
# Set position for a joint
|
69
|
+
# @param pos - position setting in rad or m
|
70
|
+
# @return [Actuator] self
|
71
|
+
def set_position(pos)
|
72
|
+
@actarray.send_message(PLAYER_MSGTYPE_CMD, PLAYER_ACTARRAY_CMD_POS, [@joint, pos].pack("Ng"))
|
73
|
+
self
|
74
|
+
end
|
75
|
+
|
76
|
+
# Set speed for a joint
|
77
|
+
# @param seepd - speed setting in rad/s or m/s
|
78
|
+
# @return [Actuator] self
|
79
|
+
def set_speed(speed)
|
80
|
+
@actarray.send_message(PLAYER_MSGTYPE_CMD, PLAYER_ACTARRAY_CMD_SPEED, [@joint, speed].pack("Ng"))
|
81
|
+
self
|
82
|
+
end
|
83
|
+
|
84
|
+
# Command to go to home position
|
85
|
+
# @return [Actuator] self
|
86
|
+
def go_home!
|
87
|
+
@actarray.send_message(PLAYER_MSGTYPE_CMD, PLAYER_ACTARRAY_CMD_HOME, [@joint].pack("N"))
|
88
|
+
self
|
89
|
+
end
|
90
|
+
|
91
|
+
# Command a joint to attempt to move with the given current
|
92
|
+
# @param curr -current to move with
|
93
|
+
# @return [Actuator] self
|
94
|
+
def set_current(curr)
|
95
|
+
@actarray.send_message(PLAYER_MSGTYPE_CMD, PLAYER_ACTARRAY_CMD_CURRENT, [@joint, curr].pack("Ng"))
|
96
|
+
self
|
97
|
+
end
|
98
|
+
|
99
|
+
# Check idle state
|
100
|
+
# @return [Boolean]
|
101
|
+
def idle?
|
102
|
+
state[:state] & PLAYER_ACTARRAY_ACTSTATE_IDLE > 0
|
103
|
+
end
|
104
|
+
|
105
|
+
# Check moving state
|
106
|
+
# @return [Boolean]
|
107
|
+
def moving?
|
108
|
+
state[:state] & PLAYER_ACTARRAY_ACTSTATE_MOVING > 0
|
109
|
+
end
|
110
|
+
|
111
|
+
# Check braked state
|
112
|
+
# @return [Boolean]
|
113
|
+
def braked?
|
114
|
+
state[:state] & PLAYER_ACTARRAY_ACTSTATE_BRAKED > 0
|
115
|
+
end
|
116
|
+
|
117
|
+
# Check braked state
|
118
|
+
# @return [Boolean]
|
119
|
+
def stalled?
|
120
|
+
state[:state] & PLAYER_ACTARRAY_ACTSTATE_STALLED > 0
|
121
|
+
end
|
122
|
+
|
123
|
+
def read_state(msg)
|
124
|
+
data = msg.unpack("g4N")
|
125
|
+
fill_hash!(@state, data)
|
126
|
+
end
|
127
|
+
|
128
|
+
def read_geom(msg)
|
129
|
+
data = msg.unpack("NgG6g5N")
|
130
|
+
fill_hash!(@geom, data)
|
131
|
+
end
|
132
|
+
end
|
133
|
+
end
|
data/lib/ruby-player/client.rb
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
# Ruby Player - Ruby client library for Player (tools for robots)
|
2
2
|
#
|
3
|
-
# Copyright (C) 2012 Timin
|
3
|
+
# Copyright (C) 2012 Aleksey Timin
|
4
4
|
#
|
5
5
|
# This program is free software: you can redistribute it and/or modify
|
6
6
|
# it under the terms of the GNU General Public License as published by
|
@@ -155,7 +155,9 @@ module Player
|
|
155
155
|
|
156
156
|
private
|
157
157
|
def make_device(dev)
|
158
|
-
|
158
|
+
intf = dev.interface_name
|
159
|
+
klass = Player.constants.each { |c| break c if c.to_s.downcase == intf }
|
160
|
+
instance_eval(klass.to_s).send(:new, dev, self)
|
159
161
|
end
|
160
162
|
|
161
163
|
def read
|
data/lib/ruby-player/common.rb
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
# Ruby Player - Ruby client library for Player (tools for robots)
|
2
2
|
#
|
3
|
-
# Copyright (C) 2012 Timin
|
3
|
+
# Copyright (C) 2012 Aleksey Timin
|
4
4
|
#
|
5
5
|
# This program is free software: you can redistribute it and/or modify
|
6
6
|
# it under the terms of the GNU General Public License as published by
|
@@ -73,16 +73,21 @@ module Player
|
|
73
73
|
warn "Get unexpection message type #{hdr.type_name}::#{hdr.subtype_name} for #@addr"
|
74
74
|
end
|
75
75
|
|
76
|
-
def
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
76
|
+
def hash_to_sft(hash)
|
77
|
+
tmpls = []
|
78
|
+
values = []
|
79
|
+
hash.each_pair do |k,v|
|
80
|
+
tmpls << k.to_s + "=%" + case v.class
|
81
|
+
when Integer
|
82
|
+
"d"
|
83
|
+
when Float
|
84
|
+
".2f"
|
85
|
+
else
|
86
|
+
"s"
|
87
|
+
end
|
88
|
+
values << v
|
89
|
+
end
|
90
|
+
tmpls.join(", ") % values
|
86
91
|
end
|
87
92
|
end
|
88
93
|
end
|