ruby-player 0.0.1
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/.gitignore +9 -0
- data/Gemfile +2 -0
- data/LICENSE +675 -0
- data/README.md +54 -0
- data/Rakefile +21 -0
- data/TODO.md +91 -0
- data/lib/ruby-player/c_type/bbox3d_t.rb +24 -0
- data/lib/ruby-player/c_type/client_t.rb +36 -0
- data/lib/ruby-player/c_type/devaddr.rb +24 -0
- data/lib/ruby-player/c_type/device_t.rb +35 -0
- data/lib/ruby-player/c_type/diagnostic.rb +22 -0
- data/lib/ruby-player/c_type/pose3d_t.rb +27 -0
- data/lib/ruby-player/c_type/position2d_t.rb +32 -0
- data/lib/ruby-player/c_type/ranger_t.rb +42 -0
- data/lib/ruby-player/c_type/sockaddr_in_t.rb +24 -0
- data/lib/ruby-player/c_type.rb +36 -0
- data/lib/ruby-player/client.rb +116 -0
- data/lib/ruby-player/common.rb +29 -0
- data/lib/ruby-player/position2d.rb +175 -0
- data/lib/ruby-player/ranger.rb +136 -0
- data/lib/ruby-player/version.rb +17 -0
- data/lib/ruby-player.rb +23 -0
- data/ruby-player.gemspec +27 -0
- data/spec/client_spec.rb +32 -0
- data/spec/position2d_spec.rb +77 -0
- data/spec/ranger_spec.rb +67 -0
- data/spec/world/test.cfg +18 -0
- data/spec/world/test.world +89 -0
- metadata +140 -0
@@ -0,0 +1,175 @@
|
|
1
|
+
# Ruby Player - Ruby client library for Player (tools for robots)
|
2
|
+
#
|
3
|
+
# Copyright (C) 2012 Timin Aleksey
|
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 position2d proxy provides an interface to a mobile robot base
|
17
|
+
#
|
18
|
+
# @example
|
19
|
+
# # get proxy object
|
20
|
+
# pos2d = client[:position2d, 0]
|
21
|
+
# # setup speed of robot
|
22
|
+
# pos2d.set_speed(vx: 1.2, vy: 0.1, va: 0.3)
|
23
|
+
#
|
24
|
+
# #update data from server
|
25
|
+
# client.read
|
26
|
+
# #read velocityand position by X,Y and angle
|
27
|
+
# pos2d.speed #=> { :vx => 1.2, :vy => 0.1, :va => 0.3 }
|
28
|
+
# pos2d.odometry #=> { :px => 0.2321, :py => 0,01, :pa => 0.2 }
|
29
|
+
# pos2d.stop
|
30
|
+
class Position2d
|
31
|
+
include CType
|
32
|
+
include Common
|
33
|
+
|
34
|
+
module C
|
35
|
+
extend FFI::Library
|
36
|
+
ffi_lib "playerc"
|
37
|
+
|
38
|
+
attach_function :playerc_position2d_create, [:pointer, :int], :pointer
|
39
|
+
attach_function :playerc_position2d_destroy, [:pointer], :void
|
40
|
+
attach_function :playerc_position2d_subscribe, [:pointer, :int], :int
|
41
|
+
attach_function :playerc_position2d_unsubscribe, [:pointer], :int
|
42
|
+
|
43
|
+
attach_function :playerc_position2d_get_geom, [:pointer], :int
|
44
|
+
attach_function :playerc_position2d_set_cmd_vel, [:pointer, :double, :double, :double, :int], :int
|
45
|
+
attach_function :playerc_position2d_set_cmd_car, [:pointer, :double, :double], :int
|
46
|
+
attach_function :playerc_position2d_enable, [:pointer, :int], :int
|
47
|
+
attach_function :playerc_position2d_set_odom, [:pointer, :double, :double, :double], :int
|
48
|
+
end
|
49
|
+
|
50
|
+
def initialize(client, index)
|
51
|
+
@pos2d = Position2dStruct.new(C.playerc_position2d_create(client, index))
|
52
|
+
try_with_error C.playerc_position2d_subscribe(@pos2d, PLAYER_OPEN_MODE)
|
53
|
+
|
54
|
+
ObjectSpace.define_finalizer(self, Position2d.finilazer(@pos2d))
|
55
|
+
end
|
56
|
+
|
57
|
+
# Odometry of robot
|
58
|
+
# @return [Hash] hash odometry {:px, :py, :pa }
|
59
|
+
def odometry
|
60
|
+
{
|
61
|
+
px: @pos2d[:px],
|
62
|
+
py: @pos2d[:py],
|
63
|
+
pa: @pos2d[:pa]
|
64
|
+
}
|
65
|
+
end
|
66
|
+
|
67
|
+
# Set odometry of robot.
|
68
|
+
# @params [Hash] odometry
|
69
|
+
# @option odometry :px x position (m)
|
70
|
+
# @option odometry :py y position (m)
|
71
|
+
# @option odometry :pa angle (rad).
|
72
|
+
# @return self
|
73
|
+
def set_odometry(odometry)
|
74
|
+
args = [
|
75
|
+
odometry[:px].to_f || @pos2d[:px],
|
76
|
+
odometry[:py].to_f || @pos2d[:py],
|
77
|
+
odometry[:pa].to_f || @pos2d[:pa]
|
78
|
+
]
|
79
|
+
|
80
|
+
try_with_error C.playerc_position2d_set_odom(@pos2d, *args)
|
81
|
+
self
|
82
|
+
end
|
83
|
+
|
84
|
+
# Reset odometry to zero
|
85
|
+
# @return self
|
86
|
+
def reset_odometry
|
87
|
+
set_odometry(px: 0, py: 0, pa: 0)
|
88
|
+
end
|
89
|
+
|
90
|
+
# Robot geometry
|
91
|
+
# @return [Hash] position :px, :py, :pa, size :sx, :sy
|
92
|
+
def geom
|
93
|
+
try_with_error C.playerc_position2d_get_geom(@pos2d)
|
94
|
+
p = @pos2d[:pose].to_a
|
95
|
+
s = @pos2d[:size].to_a
|
96
|
+
{
|
97
|
+
px: p[0],
|
98
|
+
py: p[1],
|
99
|
+
pa: p[2],
|
100
|
+
sx: s[0],
|
101
|
+
sy: s[1]
|
102
|
+
}
|
103
|
+
end
|
104
|
+
|
105
|
+
|
106
|
+
# Set speed of robot. All speeds are defined in the robot coordinate system.
|
107
|
+
# @params [Hash] speeds
|
108
|
+
# @option speeds :vx forward speed (m/s)
|
109
|
+
# @option speeds :vy sideways speed (m/s); this field is used by omni-drive robots only.
|
110
|
+
# @option speeds :va rotational speed (rad/s).
|
111
|
+
# @return self
|
112
|
+
def set_speed(speeds)
|
113
|
+
args = [
|
114
|
+
speeds[:vx].to_f || @pos2d[:vx],
|
115
|
+
vy = speeds[:vy].to_f || @pos2d[:vy],
|
116
|
+
va = speeds[:va].to_f || @pos2d[:va],
|
117
|
+
1
|
118
|
+
]
|
119
|
+
try_with_error C.playerc_position2d_set_cmd_vel(@pos2d, *args)
|
120
|
+
self
|
121
|
+
end
|
122
|
+
|
123
|
+
# Set speed of carlike robot
|
124
|
+
# @params [Hash] speeds
|
125
|
+
# @option speeds :vx forward speed (m/s)
|
126
|
+
# @option speeds :a angle robot (rad).
|
127
|
+
def set_car(speeds)
|
128
|
+
args = [
|
129
|
+
speeds[:vx].to_f || @pos2d[:vx],
|
130
|
+
speeds[:a].to_f || @pos2d[:pa]
|
131
|
+
]
|
132
|
+
try_with_error C.playerc_position2d_set_cmd_car(@pos2d, *args)
|
133
|
+
self
|
134
|
+
end
|
135
|
+
|
136
|
+
# Velocity of robot
|
137
|
+
# @return [Hash] hash of speeds
|
138
|
+
def speed
|
139
|
+
{
|
140
|
+
vx: @pos2d[:vx],
|
141
|
+
vy: @pos2d[:vy],
|
142
|
+
va: @pos2d[:va]
|
143
|
+
}
|
144
|
+
end
|
145
|
+
|
146
|
+
# State of motor
|
147
|
+
# @return [Boolean] true - on
|
148
|
+
def enable
|
149
|
+
@pos2d[:stall] == 1
|
150
|
+
end
|
151
|
+
|
152
|
+
# Turn on\off motor
|
153
|
+
# @param [Boolean] true - turn on
|
154
|
+
def enable=(val)
|
155
|
+
try_with_error C.playerc_position2d_enable(@pos2d, val ? 1 : 0)
|
156
|
+
end
|
157
|
+
|
158
|
+
# Stop robot set speed to 0
|
159
|
+
def stop
|
160
|
+
set_speed(vx: 0, vy: 0, va: 0)
|
161
|
+
end
|
162
|
+
|
163
|
+
# Check of robot state
|
164
|
+
def stoped?
|
165
|
+
speed[:vx] == 0 && speed[:vy] == 0 && speed[:va] == 0
|
166
|
+
end
|
167
|
+
|
168
|
+
def Position2d.finilazer(pos)
|
169
|
+
lambda{
|
170
|
+
try_with_error C.playerc_position2d_unsubscribe(pos)
|
171
|
+
C.playerc_position2d_destroy(pos)
|
172
|
+
}
|
173
|
+
end
|
174
|
+
end
|
175
|
+
end
|
@@ -0,0 +1,136 @@
|
|
1
|
+
# Ruby Player - Ruby client library for Player (tools for robots)
|
2
|
+
#
|
3
|
+
# Copyright (C) 2012 Timin Aleksey
|
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 ranger proxy provides an interface to the ranger sensors built into robots
|
17
|
+
class Ranger
|
18
|
+
include CType
|
19
|
+
include Common
|
20
|
+
|
21
|
+
module C
|
22
|
+
extend FFI::Library
|
23
|
+
ffi_lib "playerc"
|
24
|
+
|
25
|
+
attach_function :playerc_ranger_create, [:pointer, :int], :pointer
|
26
|
+
attach_function :playerc_ranger_destroy, [:pointer], :void
|
27
|
+
attach_function :playerc_ranger_subscribe, [:pointer, :int], :int
|
28
|
+
attach_function :playerc_ranger_unsubscribe, [:pointer], :int
|
29
|
+
|
30
|
+
attach_function :playerc_ranger_power_config, [:pointer, :uint8], :int
|
31
|
+
attach_function :playerc_ranger_intns_config, [:pointer, :uint8], :int
|
32
|
+
attach_function :playerc_ranger_set_config, [:pointer] + [:double] * 7, :int
|
33
|
+
attach_function :playerc_ranger_get_config, [:pointer] + [:pointer] * 7, :int
|
34
|
+
end
|
35
|
+
|
36
|
+
def initialize(client, index)
|
37
|
+
@ranger = RangerStruct.new(C.playerc_ranger_create(client, index))
|
38
|
+
try_with_error C.playerc_ranger_subscribe(@ranger, PLAYER_OPEN_MODE)
|
39
|
+
|
40
|
+
ObjectSpace.define_finalizer(self, Ranger.finilazer(@ranger))
|
41
|
+
end
|
42
|
+
|
43
|
+
# Count of sensors
|
44
|
+
# Return [Integer] count
|
45
|
+
def element_count
|
46
|
+
@ranger[:element_count]
|
47
|
+
end
|
48
|
+
|
49
|
+
# Power control
|
50
|
+
# @param enable nil or false power off
|
51
|
+
def power_enable=(enable)
|
52
|
+
try_with_error C.playerc_ranger_power_config(@ranger, enable ? 1 : 0)
|
53
|
+
end
|
54
|
+
|
55
|
+
# Enable intensity
|
56
|
+
# @param enable nil or false disable
|
57
|
+
def intensity_enable=(enable)
|
58
|
+
try_with_error C.playerc_ranger_intns_config(@ranger, enable ? 1 : 0)
|
59
|
+
end
|
60
|
+
|
61
|
+
# Set config of ranger
|
62
|
+
# @param [Hash] config params for setup
|
63
|
+
# @option :min_angle start angle of scans [rad]
|
64
|
+
# @option :max_angle end angle of scans
|
65
|
+
# @option :angular_res scan resolution [rad]
|
66
|
+
# @option :min_range maximum range [m]
|
67
|
+
# @option :max_range minimum range [m]
|
68
|
+
# @option :range_res range resolution [m]
|
69
|
+
# @option :frequency scanning frequency [Hz]
|
70
|
+
def set_config(config)
|
71
|
+
args = [
|
72
|
+
config[:min_angle].to_f || @ranger[:min_angle],
|
73
|
+
config[:max_angle].to_f || @ranger[:max_angle],
|
74
|
+
config[:angular_res].to_f || @ranger[:angular_res],
|
75
|
+
config[:min_range].to_f || @ranger[:min_range],
|
76
|
+
config[:max_range].to_f || @ranger[:max_range],
|
77
|
+
config[:range_res].to_f || @ranger[:range_res],
|
78
|
+
config[:frequecy].to_f || @ranger[:frequecy]
|
79
|
+
]
|
80
|
+
|
81
|
+
try_with_error C.playerc_ranger_set_config(@ranger, *args)
|
82
|
+
end
|
83
|
+
|
84
|
+
# Configuration of ranger
|
85
|
+
# @see set_config
|
86
|
+
def config
|
87
|
+
try_with_error C.playerc_ranger_get_config(@ranger, *([nil] * 7))
|
88
|
+
{
|
89
|
+
min_range: @ranger[:min_angle],
|
90
|
+
max_range: @ranger[:max_angle],
|
91
|
+
angular_res: @ranger[:angular_res],
|
92
|
+
min_range: @ranger[:min_range],
|
93
|
+
max_range: @ranger[:max_range],
|
94
|
+
range_res: @ranger[:range_res],
|
95
|
+
frequecy: @ranger[:frequecy]
|
96
|
+
}
|
97
|
+
end
|
98
|
+
|
99
|
+
# Range data [m]
|
100
|
+
# @return [Array] fot each sensor
|
101
|
+
def ranges
|
102
|
+
@ranger[:ranges].read_array_of_type(
|
103
|
+
FFI::Type::DOUBLE,
|
104
|
+
:read_double,
|
105
|
+
@ranger[:ranges_count]
|
106
|
+
)
|
107
|
+
end
|
108
|
+
|
109
|
+
# Intensity data [m].
|
110
|
+
# @return [Array] fot each sensor
|
111
|
+
def intensities
|
112
|
+
@ranger[:intensities].read_array_of_type(
|
113
|
+
FFI::Type::DOUBLE,
|
114
|
+
:read_double,
|
115
|
+
@ranger[:intensities_count]
|
116
|
+
)
|
117
|
+
end
|
118
|
+
|
119
|
+
# Scan bearings in the XY plane [radians].
|
120
|
+
# @return [Array] fot each sensor
|
121
|
+
def bearings
|
122
|
+
@ranger[:bearings].read_array_of_type(
|
123
|
+
FFI::Type::DOUBLE,
|
124
|
+
:read_double,
|
125
|
+
@ranger[:bearings_count]
|
126
|
+
)
|
127
|
+
end
|
128
|
+
|
129
|
+
def Ranger.finilazer(ranger)
|
130
|
+
lambda{
|
131
|
+
try_with_error C.playerc_ranger_unsubscribe(pos)
|
132
|
+
C.playerc_ranger_destroy(pos)
|
133
|
+
}
|
134
|
+
end
|
135
|
+
end
|
136
|
+
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
# Ruby Player - Ruby client library for Player (tools for robots)
|
2
|
+
#
|
3
|
+
# Copyright (C) 2012 Timin Aleksey
|
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
|
+
VERSION = "0.0.1"
|
17
|
+
end
|
data/lib/ruby-player.rb
ADDED
@@ -0,0 +1,23 @@
|
|
1
|
+
# Ruby Player - Ruby client library for Player (tools for robots)
|
2
|
+
#
|
3
|
+
# Copyright (C) 2012 Timin Aleksey
|
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
|
+
require "ffi"
|
16
|
+
|
17
|
+
require "ruby-player/c_type"
|
18
|
+
|
19
|
+
require "ruby-player/version"
|
20
|
+
require "ruby-player/common"
|
21
|
+
require "ruby-player/position2d"
|
22
|
+
require "ruby-player/ranger"
|
23
|
+
require "ruby-player/client"
|
data/ruby-player.gemspec
ADDED
@@ -0,0 +1,27 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
$:.push File.expand_path("../lib", __FILE__)
|
3
|
+
require "ruby-player/version"
|
4
|
+
|
5
|
+
Gem::Specification.new do |s|
|
6
|
+
s.name = "ruby-player"
|
7
|
+
s.version = Player::VERSION
|
8
|
+
s.authors = ["Aleksey Timin"]
|
9
|
+
s.email = ["atimin@gmail.com"]
|
10
|
+
s.homepage = "http://www.github.com/flipback/ruby-player"
|
11
|
+
s.summary = %q{Ruby Player - Ruby client library for Player (tools for robots)}
|
12
|
+
s.description = %q{Ruby Player - Ruby client library for Player (tools for robots)}
|
13
|
+
|
14
|
+
s.files = `git ls-files`.split("\n")
|
15
|
+
s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
|
16
|
+
s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
|
17
|
+
s.require_paths = ["lib"]
|
18
|
+
|
19
|
+
s.required_ruby_version = '>= 1.9.2'
|
20
|
+
|
21
|
+
s.add_runtime_dependency "ffi", '~>1.0.0'
|
22
|
+
s.add_development_dependency "rspec", '~> 2.7'
|
23
|
+
s.add_development_dependency "rake", '~> 0.9'
|
24
|
+
s.add_development_dependency "pry"
|
25
|
+
s.add_development_dependency "yard"
|
26
|
+
s.add_development_dependency "redcarpet"
|
27
|
+
end
|
data/spec/client_spec.rb
ADDED
@@ -0,0 +1,32 @@
|
|
1
|
+
require "ruby-player"
|
2
|
+
|
3
|
+
describe Player::Client do
|
4
|
+
before do
|
5
|
+
@cl = Player::Client.new("localhost")
|
6
|
+
end
|
7
|
+
|
8
|
+
it "should raise error if connection doesn't success" do
|
9
|
+
lambda{ Player::Client.new("localhost", 6666) }.should raise_error(StandardError,
|
10
|
+
"connect call on [localhost:6666] failed with error [111:Connection refused]")
|
11
|
+
end
|
12
|
+
|
13
|
+
it "should have close method" do
|
14
|
+
@cl.closed?.should be_false
|
15
|
+
@cl.close
|
16
|
+
@cl.closed?.should be_true
|
17
|
+
end
|
18
|
+
|
19
|
+
it "should have block for connection" do
|
20
|
+
@cl.close
|
21
|
+
Player::Client.connect("localhost") do |cl|
|
22
|
+
@cl = cl
|
23
|
+
@cl.closed?.should be_false
|
24
|
+
end
|
25
|
+
|
26
|
+
@cl.closed?.should be_true
|
27
|
+
end
|
28
|
+
|
29
|
+
after do
|
30
|
+
@cl.close unless @cl.closed?
|
31
|
+
end
|
32
|
+
end
|
@@ -0,0 +1,77 @@
|
|
1
|
+
require "ruby-player"
|
2
|
+
|
3
|
+
describe Player::Position2d do
|
4
|
+
before do
|
5
|
+
@cl = Player::Client.connect("localhost")
|
6
|
+
@pos2d = @cl[:position2d, 0]
|
7
|
+
@pos2d.stop
|
8
|
+
@cl.read
|
9
|
+
end
|
10
|
+
|
11
|
+
it 'should set odometry' do
|
12
|
+
pending "Don't work with Player/Stage"
|
13
|
+
new_od = { px: 1.0, py: 2.0, pa: 3 }
|
14
|
+
@pos2d.set_odometry(new_od)
|
15
|
+
@pos2d.reset_odometry
|
16
|
+
|
17
|
+
sleep(1.0)
|
18
|
+
@cl.read
|
19
|
+
|
20
|
+
@pos2d.odometry.should eql(new_od)
|
21
|
+
end
|
22
|
+
|
23
|
+
it 'should move' do
|
24
|
+
pos = @pos2d.odometry
|
25
|
+
speed = {vx: -0.4, vy: 0.2, va: -0.1 }
|
26
|
+
@pos2d.set_speed(speed)
|
27
|
+
|
28
|
+
sleep(1.1)
|
29
|
+
@cl.read
|
30
|
+
@pos2d.speed.should eq(speed)
|
31
|
+
|
32
|
+
#change position
|
33
|
+
@pos2d.odometry[:px].should be_within(0.1).of(pos[:px] + speed[:vx]*Math.cos(pos[:pa]) - speed[:vy]*Math.sin(pos[:pa]))
|
34
|
+
@pos2d.odometry[:py].should be_within(0.1).of(pos[:py] + speed[:vx]*Math.sin(pos[:pa]) + speed[:vy]*Math.cos(pos[:pa]))
|
35
|
+
Math.sin(@pos2d.odometry[:pa]).should be_within(0.1).of(Math.sin(pos[:pa] + speed[:va]))
|
36
|
+
end
|
37
|
+
|
38
|
+
|
39
|
+
it 'should move like car' do
|
40
|
+
pos = @pos2d.odometry
|
41
|
+
speed = { vx: 0.4, a: 0.3 }
|
42
|
+
@pos2d.set_car(speed)
|
43
|
+
|
44
|
+
sleep(1.1)
|
45
|
+
@cl.read
|
46
|
+
@pos2d.speed.should eq(vx: 0.4, vy: 0.0, va: 0.3)
|
47
|
+
|
48
|
+
#change position
|
49
|
+
@pos2d.odometry[:px].should be_within(0.1).of(pos[:px] + speed[:vx]*Math.cos(pos[:pa]))
|
50
|
+
@pos2d.odometry[:py].should be_within(0.1).of(pos[:py] + speed[:vx]*Math.sin(pos[:pa]))
|
51
|
+
Math.sin(@pos2d.odometry[:pa]).should be_within(0.1).of(Math.sin(pos[:pa] + speed[:a]))
|
52
|
+
end
|
53
|
+
|
54
|
+
it 'should have stop' do
|
55
|
+
# Move robot
|
56
|
+
@pos2d.set_speed(vx: 1.0, vy: 0.5, va: -0.2)
|
57
|
+
@cl.read
|
58
|
+
@pos2d.speed.should eql(vx: 1.0, vy: 0.5, va: -0.2)
|
59
|
+
@pos2d.stoped?.should be_false
|
60
|
+
|
61
|
+
# Stop robot
|
62
|
+
@pos2d.stop
|
63
|
+
@cl.read
|
64
|
+
@pos2d.speed.should eql(vx: 0.0, vy: 0.0, va: 0.0)
|
65
|
+
@pos2d.stoped?.should be_true
|
66
|
+
end
|
67
|
+
|
68
|
+
it 'should turn on motor' do
|
69
|
+
pending "Don't work with Player/Stage"
|
70
|
+
@pos2d.enable.should be_false
|
71
|
+
@pos2d.enable = true
|
72
|
+
end
|
73
|
+
|
74
|
+
after do
|
75
|
+
@cl.close unless @cl.closed?
|
76
|
+
end
|
77
|
+
end
|
data/spec/ranger_spec.rb
ADDED
@@ -0,0 +1,67 @@
|
|
1
|
+
require "ruby-player"
|
2
|
+
|
3
|
+
describe Player::Ranger do
|
4
|
+
before do
|
5
|
+
@cl = Player::Client.connect("localhost")
|
6
|
+
@ranger = @cl[:ranger,0]
|
7
|
+
@cl.read
|
8
|
+
end
|
9
|
+
|
10
|
+
it 'should have ranges' do
|
11
|
+
@ranger.ranges.should eq([3.0, 3.0])
|
12
|
+
end
|
13
|
+
|
14
|
+
it 'should have intensities' do
|
15
|
+
@ranger.intensities.should eq([0.0, 0.0])
|
16
|
+
end
|
17
|
+
|
18
|
+
it 'should have bearings' do
|
19
|
+
@ranger.bearings.size.should eql(2)
|
20
|
+
end
|
21
|
+
|
22
|
+
it 'should have element count' do
|
23
|
+
@ranger.element_count.should eq(0)
|
24
|
+
end
|
25
|
+
|
26
|
+
it 'should have power control' do
|
27
|
+
pending "Don't work with Player/Stage"
|
28
|
+
#@ranger.power_enable = false
|
29
|
+
#@ranger.power_enable = true
|
30
|
+
end
|
31
|
+
|
32
|
+
it 'should have intensity control' do
|
33
|
+
pending "Don't work with Player/Stage"
|
34
|
+
#@ranger.intensity_enable = false
|
35
|
+
#@ranger.intensity_enable = true
|
36
|
+
end
|
37
|
+
|
38
|
+
it 'should porovide method to configurate' do
|
39
|
+
pending "Don't work with Player/Stage"
|
40
|
+
config = {
|
41
|
+
min_angle: 0.3,
|
42
|
+
max_angle: 1.0,
|
43
|
+
angular_res: 0.1,
|
44
|
+
min_range: 0.3,
|
45
|
+
max_range: 1,
|
46
|
+
range_res: 0.1,
|
47
|
+
frequecy: 2
|
48
|
+
}
|
49
|
+
|
50
|
+
|
51
|
+
#@ranger.set_config(config)
|
52
|
+
end
|
53
|
+
|
54
|
+
it 'should have configuration' do
|
55
|
+
@ranger.config.should eq(
|
56
|
+
:min_range=>0.1,
|
57
|
+
:max_range=>3.0,
|
58
|
+
:angular_res=>0.5235987755982988,
|
59
|
+
:range_res=>0.02,
|
60
|
+
:frequecy=>10.0
|
61
|
+
)
|
62
|
+
end
|
63
|
+
|
64
|
+
after do
|
65
|
+
@cl.close unless @cl.closed?
|
66
|
+
end
|
67
|
+
end
|
data/spec/world/test.cfg
ADDED
@@ -0,0 +1,18 @@
|
|
1
|
+
# Desc: Player test configuration file
|
2
|
+
|
3
|
+
driver
|
4
|
+
(
|
5
|
+
name "stage"
|
6
|
+
provides [ "simulation:0" ]
|
7
|
+
plugin "stageplugin"
|
8
|
+
|
9
|
+
worldfile "test.world"
|
10
|
+
)
|
11
|
+
|
12
|
+
driver
|
13
|
+
(
|
14
|
+
name "stage"
|
15
|
+
provides [ "position2d:0" "ranger:0" ]
|
16
|
+
|
17
|
+
model "bender"
|
18
|
+
)
|
@@ -0,0 +1,89 @@
|
|
1
|
+
quit_time 3600
|
2
|
+
|
3
|
+
paused 0
|
4
|
+
|
5
|
+
resolution 0.02
|
6
|
+
|
7
|
+
window
|
8
|
+
(
|
9
|
+
size [ 635.000 666.000 ] # in pixels
|
10
|
+
scale 36.995 # pixels per meter
|
11
|
+
center [ -0.040 -0.274 ]
|
12
|
+
rotate [ 0 0 ]
|
13
|
+
|
14
|
+
show_data 1 # 1=on 0=off
|
15
|
+
)
|
16
|
+
|
17
|
+
define carton model
|
18
|
+
(
|
19
|
+
color "yelow"
|
20
|
+
#carton is retangular
|
21
|
+
# so make a square shape and use size[]
|
22
|
+
block
|
23
|
+
(
|
24
|
+
points 4
|
25
|
+
point[0] [1 0]
|
26
|
+
point[1] [1 4]
|
27
|
+
point[2] [0 4]
|
28
|
+
point[3] [0 0]
|
29
|
+
z [0 1]
|
30
|
+
)
|
31
|
+
# average litre carton size is ~ 20cm x 10cm x 5cm ish
|
32
|
+
size [0.4 4 2]
|
33
|
+
)
|
34
|
+
|
35
|
+
|
36
|
+
define bender_ranger ranger
|
37
|
+
(
|
38
|
+
color "red"
|
39
|
+
|
40
|
+
sensor
|
41
|
+
(
|
42
|
+
pose [0 0.1 0.3 15]
|
43
|
+
size [0.4 0.4 0.4]
|
44
|
+
fov 30
|
45
|
+
range [0.1 3]
|
46
|
+
)
|
47
|
+
|
48
|
+
sensor
|
49
|
+
(
|
50
|
+
pose [0 -0.1 0.3 -15]
|
51
|
+
size [0.4 0.4 0.4]
|
52
|
+
fov 30
|
53
|
+
range [0.1 3]
|
54
|
+
)
|
55
|
+
)
|
56
|
+
|
57
|
+
define bender2dx position
|
58
|
+
(
|
59
|
+
color "grey"
|
60
|
+
|
61
|
+
block
|
62
|
+
(
|
63
|
+
points 5
|
64
|
+
point[0] [-3 -3]
|
65
|
+
point[1] [-3 3]
|
66
|
+
point[2] [3 3]
|
67
|
+
point[3] [9 0]
|
68
|
+
point[4] [3 -3]
|
69
|
+
z [0 1]
|
70
|
+
)
|
71
|
+
|
72
|
+
drive "omni"
|
73
|
+
|
74
|
+
bender_ranger()
|
75
|
+
size [1 1 1]
|
76
|
+
)
|
77
|
+
|
78
|
+
#carton
|
79
|
+
#(
|
80
|
+
# name "c0"
|
81
|
+
# pose [ 1 0 0 0.0]
|
82
|
+
#)
|
83
|
+
|
84
|
+
bender2dx
|
85
|
+
(
|
86
|
+
name "bender"
|
87
|
+
pose [ 0 0 0 0.000 ]
|
88
|
+
|
89
|
+
)
|