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