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