ruby-nxt 0.8.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,236 @@
1
+ require File.dirname(__FILE__) + '/../test_helper'
2
+ require "commands"
3
+ require "interactive_test_helper"
4
+
5
+ include InteractiveTestHelper
6
+
7
+ require "autodetect_nxt"
8
+
9
+ info "Connecting to the NXT at #{$DEV}..."
10
+
11
+ begin
12
+ $nxt = NXTComm.new($DEV)
13
+ rescue
14
+ fail "Could not connect to the NXT!"
15
+ fail "The error was: #{$!}"
16
+ notice "Make sure that the NXT is turned on and that your Bluetooth connection is configured."
17
+ notice "You may need to change the value of the $DEV variable in #{__FILE__} to point to the correct tty device."
18
+ exit 1
19
+ end
20
+
21
+ puts
22
+
23
+ notice <<NOTE
24
+ Please make sure that all four sensors are plugged in to the standard ports as follows:
25
+ Sensor 1: Touch
26
+ Sensor 2: Sound
27
+ Sensor 3: Light
28
+ Sensor 4: Ultrasonic
29
+ NOTE
30
+ prompt "Press Enter on your keyboard when ready..."
31
+
32
+ ### touch sensor ######
33
+
34
+ def test_touch_sensor
35
+ t = Commands::TouchSensor.new($nxt)
36
+
37
+ info "Initializing touch sensor..."
38
+ t = Commands::TouchSensor.new($nxt)
39
+
40
+ notice "Make sure the touch sensor is NOT pressed..."
41
+ sleep(2)
42
+
43
+ t.trigger_point = :pressed
44
+ while t.logic
45
+ end
46
+
47
+ pass "Touch sensor not pressed!"
48
+
49
+ sleep(2)
50
+ notice "Now press the touch sensor..."
51
+
52
+ t.trigger_point = :released
53
+ while t.logic
54
+ end
55
+
56
+ pass "Touch sensor pressed!"
57
+ pass "All touch sensor tests passed!"
58
+ t.off
59
+ puts
60
+ end
61
+
62
+ ### sound sensor ######
63
+
64
+ def test_sound_sensor
65
+ sleep(1)
66
+ info "Initializing sound sensor..."
67
+ s = Commands::SoundSensor.new($nxt)
68
+
69
+ sleep(1)
70
+ notice "Now, be very quiet..."
71
+ sleep(2)
72
+
73
+ s.comparison = ">"
74
+ s.trigger_point = 3
75
+ while s.logic
76
+ meter(s.sound_level, "Sound Level", 3)
77
+ end
78
+
79
+ puts
80
+ pass "OK, sound level was below 3%"
81
+
82
+ sleep(1)
83
+ notice "Now make some noise!"
84
+
85
+ s.comparison = "<"
86
+ s.trigger_point = 75
87
+ while s.logic
88
+ meter(s.sound_level, "Sound Level", 75)
89
+ end
90
+
91
+ puts
92
+ pass "OK, sound level was above 75%"
93
+ pass "All sound sensor tests passed!"
94
+ s.off
95
+ puts
96
+ end
97
+
98
+ ### light sensor ######
99
+
100
+ def test_light_sensor
101
+ sleep(1)
102
+ info "Initializing light sensor..."
103
+ l = Commands::LightSensor.new($nxt)
104
+ l.illuminated_mode
105
+
106
+ sleep(1)
107
+ notice "Put the light sensor up to something white or light coloured..."
108
+ sleep(1)
109
+
110
+ l.comparison = "<"
111
+ l.trigger_point = 50
112
+ while l.logic
113
+ meter(l.intensity, "Colour", 50)
114
+ end
115
+
116
+ puts
117
+ pass "OK, colour lightness was above 50%"
118
+
119
+ sleep(1)
120
+ notice "Now, put the light sensor up to something black or dark coloured..."
121
+ sleep(2)
122
+
123
+ l.comparison = ">"
124
+ l.trigger_point = 20
125
+ while l.logic
126
+ meter(l.intensity, "Colour", 20)
127
+ end
128
+
129
+ puts
130
+ pass "OK, colour lightness was below 20%"
131
+
132
+ sleep(1)
133
+ info "Switching to ambient light mode..."
134
+ l.ambient_mode
135
+ sleep(1)
136
+
137
+ notice "Now put the light sensor under a lamp or some other bright light source..."
138
+ sleep(2)
139
+
140
+ l.comparison = "<"
141
+ l.trigger_point = 65
142
+ while l.logic
143
+ meter(l.intensity, "Light", 65)
144
+ end
145
+
146
+ puts
147
+ pass "OK, ambient light level was above 65%"
148
+
149
+ sleep(1)
150
+ notice "Now cover the light sensor with something to block out the light..."
151
+ sleep(2)
152
+
153
+ l.comparison = ">"
154
+ l.trigger_point = 15
155
+ while l.logic
156
+ meter(l.intensity, "Light", 15)
157
+ end
158
+
159
+ puts
160
+ pass "OK, ambient light level was below 15%"
161
+ pass "All light sensor tests passed!"
162
+ puts
163
+ l.off
164
+ end
165
+
166
+ ### ultrasonic sensor ######
167
+
168
+ def test_ultrasonic_sensor
169
+ sleep(1)
170
+ info "Initializing ultrasonic sensor..."
171
+ us = Commands::UltrasonicSensor.new($nxt)
172
+ us.mode = :centimeters
173
+
174
+ sleep(1)
175
+ notice "Point the ultrasonic sensor into the far distance -- at least 2.5 meters (7 feet)..."
176
+ sleep(2)
177
+
178
+ us.comparison = "<"
179
+ us.trigger_point = 255
180
+
181
+ while us.logic
182
+ begin
183
+ meter(us.distance!, "Distance (cm)", nil, 150, 0)
184
+ rescue Commands::UltrasonicSensor::UnmeasurableDistance
185
+ meter(nil, "Distance (cm)", nil, 150, 0)
186
+ end
187
+ end
188
+ puts
189
+ pass "OK, the sensor says it can't determine the distance (it can't pick up anything over 2 meters away or anything very very close)."
190
+
191
+ sleep(1)
192
+ notice "Now point the ultrasonic sensor at something less than 8 cm (3 inches) away..."
193
+ sleep(1)
194
+
195
+ us.comparison = ">"
196
+ us.trigger_point = 8
197
+ while us.logic
198
+ begin
199
+ meter(us.distance!, "Distance (cm)", 8, 150, 0)
200
+ rescue Commands::UltrasonicSensor::UnmeasurableDistance
201
+ meter(nil, "Distance (cm)", 8, 150, 0)
202
+ end
203
+ end
204
+
205
+ puts
206
+ pass "OK, the sensor detected an object 8 cm or less away."
207
+
208
+ sleep(1)
209
+ notice "Point the ultrasonic sensor at a wall or some other solid object 1 meter (3 feet) or further away..."
210
+ sleep(1)
211
+
212
+ us.comparison = "<"
213
+ us.trigger_point = 100
214
+ while us.logic
215
+ begin
216
+ meter(us.distance!, "Distance (cm)", 100, 150, 0)
217
+ rescue Commands::UltrasonicSensor::UnmeasurableDistance
218
+ meter(nil, "Distance (cm)", 100, 150, 0)
219
+ end
220
+ end
221
+
222
+ puts
223
+ pass "OK, the sensor detected an object over 1 meter away."
224
+ pass "All ultrasonic sensor tests passed!"
225
+
226
+ puts
227
+ end
228
+
229
+ test_touch_sensor
230
+ test_sound_sensor
231
+ test_light_sensor
232
+ test_ultrasonic_sensor
233
+
234
+ pass "CONGRATULATIONS! ruby-nxt was successfully able to communicate with all of your NXT's sensors."
235
+
236
+ $nxt.close
@@ -0,0 +1,22 @@
1
+ #!/usr/bin/env ruby -w
2
+
3
+ require "nxt_comm"
4
+
5
+ # causes ruby-nxt to print out all the bytes sent and received
6
+ $DEBUG = true
7
+
8
+ @nxt = NXTComm.new('/dev/tty.NXT-DevB-1')
9
+ @nxt.play_tone(500,500)
10
+
11
+ # command = Commands::Move.new(@nxt)
12
+ #
13
+ # command.ports = :a
14
+ # command.power = 100
15
+ # command.direction = :backward
16
+ # command.duration = :unlimited
17
+ #
18
+ # command.start
19
+ #
20
+ # sleep(3)
21
+ #
22
+ # command.stop
@@ -0,0 +1 @@
1
+ $: << File.dirname(File.expand_path(__FILE__))+'/../lib'
@@ -0,0 +1,177 @@
1
+ require File.dirname(__FILE__) + '/../test_helper'
2
+ require "test/unit"
3
+ require "motor"
4
+ require "autodetect_nxt"
5
+
6
+ class MotorTest < Test::Unit::TestCase
7
+
8
+ @@nxt = NXTComm.new($DEV)
9
+
10
+ puts "\nWARNING: The battery level is low. Test results may be inconsistent.\n" if @@nxt.get_battery_level < 6040
11
+
12
+ def setup
13
+ @motors = []
14
+ @motors << Motor.new(@@nxt, :a)
15
+ @motors << Motor.new(@@nxt, :b)
16
+ @motors << Motor.new(@@nxt, :c)
17
+
18
+ # make sure that we can talk to each of the motors before we try to run any tests
19
+ # @motors.each do |m|
20
+ # state = m.read_state
21
+ # if not state
22
+ # raise "Cannot run tests because motor #{m.port} is not responding."
23
+ # end
24
+ # end
25
+ end
26
+
27
+ def teardown
28
+ end
29
+
30
+ def test_name
31
+ assert_equal 'a', @motors[0].name
32
+ assert_equal 'b', @motors[1].name
33
+ assert_equal 'c', @motors[2].name
34
+ end
35
+
36
+ def test_read_state
37
+ # check just one motor
38
+ state = @motors.first.read_state
39
+ assert_not_nil state
40
+ assert_equal @motors.first.port, state[:port]
41
+
42
+ # now do all motors
43
+ @motors.each do |m|
44
+ state = m.read_state
45
+ assert_not_nil state
46
+ assert_equal m.port, state[:port]
47
+ end
48
+
49
+ # sanity check... two consecutive state checks should be the same, since nothing's changed
50
+ @motors.each do |m|
51
+ state1 = m.read_state
52
+ state2 = m.read_state
53
+ assert_equal state1, state2
54
+ end
55
+ end
56
+
57
+ def test_reset_tacho
58
+ @motors.each do |m|
59
+ m.reset_tacho
60
+ state = m.read_state
61
+ assert_equal 0, state[:rotation_count]
62
+ end
63
+ end
64
+
65
+ def test_run_by_degrees
66
+ # we have to use a low power, otherwise we can't get fine tacho control due to inertia
67
+
68
+ @motors.each do |m|
69
+ m.stop
70
+
71
+ m.reset_tacho
72
+ m.forward(:degrees => 180, :power => 5)
73
+ state = m.read_state
74
+ assert_in_delta(180, state[:rotation_count], 40)
75
+
76
+ m.stop
77
+
78
+ m.reset_tacho
79
+ m.backward(:degrees => 180, :power => 5)
80
+ state = m.read_state
81
+ assert_in_delta(-180, state[:rotation_count], 40)
82
+
83
+ m.stop
84
+ end
85
+ end
86
+
87
+ def test_run_by_seconds
88
+ # only need to test one motor, since we already tested tacho for all motors in test_run_by_degrees
89
+ m = @motors.first
90
+
91
+ m.reset_tacho
92
+ m.forward(:time => 3, :power => 15)
93
+ state = m.read_state
94
+ assert_in_delta(450, state[:rotation_count], 100)
95
+
96
+ m.reset_tacho
97
+ m.backward(:time => 3, :power => 15)
98
+ state = m.read_state
99
+ assert_in_delta(-450, state[:rotation_count], 100)
100
+ end
101
+
102
+ def test_run_free
103
+ m = @motors.first
104
+ m.reset_tacho
105
+ m.forward(:power => 15)
106
+ sleep(3)
107
+ m.stop
108
+ assert_in_delta(450, m.read_state[:rotation_count], 100)
109
+
110
+ # now see what happens when we interrupt the movement
111
+ m.reset_tacho
112
+ m.forward(:power => 15)
113
+ sleep(1)
114
+ m.backward(:power => 15)
115
+ sleep(1)
116
+ m.stop
117
+ assert_in_delta(0, m.read_state[:rotation_count], 35)
118
+ end
119
+
120
+ # def test_tiny_slow_movements
121
+ # # it seems to help if we stop for a bit first
122
+ # sleep(1)
123
+ #
124
+ # m = @motors.first
125
+ #
126
+ # m.reset_tacho
127
+ # m.forward(:degrees => 10, :power => 1)
128
+ # state = m.read_state
129
+ # assert_in_delta(10, state[:rotation_count], 2)
130
+ #
131
+ # m.reset_tacho
132
+ # m.backward(:degrees => 5, :power => 1)
133
+ # state = m.read_state
134
+ # assert_in_delta(-5, state[:rotation_count], 2)
135
+ #
136
+ # m.reset_tacho
137
+ # m.forward(:degrees => 5, :power => 1)
138
+ # state = m.read_state
139
+ # assert_in_delta(5, state[:rotation_count], 2)
140
+ #
141
+ # m.reset_tacho
142
+ # m.backward(:degrees => 15, :power => 1)
143
+ # state = m.read_state
144
+ # assert_in_delta(-15, state[:rotation_count], 2)
145
+ #
146
+ #
147
+ # # Moving by 1 degree pretty much never works :(
148
+ # #m.reset_tacho
149
+ # #m.forward(:degrees => 1, :power => 1)
150
+ # #state = m.read_state
151
+ # #assert_equal 1, state[:rotation_count]
152
+ # end
153
+
154
+ # This just doesn't work :(
155
+ # def test_tiny_fast_movements
156
+ # m = @motors.first
157
+ #
158
+ # m.reset_tacho
159
+ # m.forward(:degrees => 10, :power => 100)
160
+ # state = m.read_state
161
+ # assert_in_delta(10, state[:rotation_count], 3)
162
+ #
163
+ # m.reset_tacho
164
+ # m.backward(:degrees => 5, :power => 100)
165
+ # state = m.read_state
166
+ # assert_in_delta(-5, state[:rotation_count], 3)
167
+ #
168
+ # # Moving by 1 degree pretty much never works :(
169
+ # #m.reset_tacho
170
+ # #m.forward(:degrees => 1, :power => 1)
171
+ # #state = m.read_state
172
+ # #assert_equal 1, state[:rotation_count]
173
+ # end
174
+
175
+
176
+
177
+ end
@@ -0,0 +1,155 @@
1
+ require File.dirname(__FILE__) + '/../test_helper'
2
+ require "test/unit"
3
+ require "stringio"
4
+ require "nxt_comm"
5
+
6
+ $DEV = '/dev/tty.NXT-DevB-1'
7
+
8
+ # Test Setup:
9
+ # * a motor in port A
10
+ # * touch sensor in port 1
11
+ # * the default Try-Touch.rtm program needs to be on the NXT
12
+
13
+ class NXTCommTest < Test::Unit::TestCase
14
+
15
+ @@nxt = NXTComm.new($DEV)
16
+
17
+ def capture_stderr
18
+ begin
19
+ $stderr = StringIO.new
20
+ yield
21
+ $stderr.rewind && $stderr.read
22
+ ensure
23
+ $stderr = STDERR
24
+ end
25
+ end
26
+
27
+ def test_start_stop_program
28
+ assert @@nxt.start_program("Try-Touch.rtm")
29
+ sleep(3)
30
+ assert @@nxt.stop_program
31
+ end
32
+
33
+ def test_invalid_program_name
34
+ err = capture_stderr { assert !@@nxt.start_program("foo") }
35
+ assert_equal "ERROR: Data contains out-of-range values\n", err
36
+ end
37
+
38
+ def test_stop_program_when_nothing_running
39
+ err = capture_stderr { assert !@@nxt.stop_program }
40
+ assert_equal "ERROR: No active program\n", err
41
+ end
42
+
43
+ def test_play_sound_file
44
+ assert @@nxt.play_sound_file("Good Job.rso")
45
+ sleep(1)
46
+ end
47
+
48
+ def test_invalid_sound_file
49
+ err = capture_stderr { assert !@@nxt.play_sound_file("foo") }
50
+ assert_equal "ERROR: Data contains out-of-range values\n", err
51
+ end
52
+
53
+ def test_play_tone
54
+ assert @@nxt.play_tone(500,300)
55
+ end
56
+
57
+ def test_get_and_set_output
58
+ assert @@nxt.set_output_state(NXTComm::MOTOR_A,100,NXTComm::MOTORON,NXTComm::REGULATION_MODE_MOTOR_SPEED,100,NXTComm::MOTOR_RUN_STATE_RUNNING,0)
59
+ state = @@nxt.get_output_state(NXTComm::MOTOR_A)
60
+ assert_equal 100, state[:power]
61
+
62
+ sleep(1)
63
+
64
+ assert @@nxt.set_output_state(NXTComm::MOTOR_A,0,NXTComm::BRAKE,NXTComm::REGULATION_MODE_MOTOR_SPEED,0,NXTComm::MOTOR_RUN_STATE_RAMPDOWN,0)
65
+ state = @@nxt.get_output_state(NXTComm::MOTOR_A)
66
+ assert_equal 0, state[:power]
67
+ end
68
+
69
+ def test_get_and_set_input
70
+ assert @@nxt.set_input_mode(NXTComm::SENSOR_1,NXTComm::SWITCH,NXTComm::RAWMODE)
71
+ values = @@nxt.get_input_values(NXTComm::SENSOR_1)
72
+ assert_equal 0, values[:mode]
73
+
74
+ assert @@nxt.set_input_mode(NXTComm::SENSOR_1,NXTComm::SWITCH,NXTComm::BOOLEANMODE)
75
+ values = @@nxt.get_input_values(NXTComm::SENSOR_1)
76
+ assert_equal 32, values[:mode]
77
+ end
78
+
79
+ def test_reset_input_scaled_value
80
+ assert @@nxt.reset_input_scaled_value(NXTComm::SENSOR_1)
81
+ end
82
+
83
+ def test_message_write
84
+ err = capture_stderr { assert !@@nxt.message_write(1,"Won't work unless a program is running...") }
85
+ assert_equal "ERROR: No active program\n", err
86
+
87
+ # weird timing problems, can take a while to start a program it seems...
88
+ sleep(1)
89
+ assert @@nxt.start_program("Try-Touch.rtm")
90
+ sleep(3)
91
+
92
+ assert @@nxt.message_write(1,"Chunky Robotic Bacon!")
93
+
94
+ assert @@nxt.stop_program
95
+ end
96
+
97
+ def test_message_read
98
+ err = capture_stderr { assert !@@nxt.message_read(1) }
99
+ assert_equal "ERROR: No active program\n", err
100
+
101
+ # weird timing problems, can take a while to start a program it seems...
102
+ sleep(1)
103
+ assert @@nxt.start_program("Try-Touch.rtm")
104
+ sleep(3)
105
+
106
+ # to properly test message read, I'd need to start a program that places a message in a box...
107
+ err = capture_stderr { assert !@@nxt.message_read(1) }
108
+ assert_equal "ERROR: Specified mailbox queue is empty\n", err
109
+
110
+ assert @@nxt.stop_program
111
+ end
112
+
113
+ def test_reset_motor_position
114
+ assert @@nxt.reset_motor_position(NXTComm::MOTOR_A)
115
+ end
116
+
117
+ def test_get_battery_level
118
+ result = @@nxt.get_battery_level
119
+ assert_kind_of Fixnum, result
120
+ assert result > 0
121
+ end
122
+
123
+ def test_stop_sound_playback
124
+ assert @@nxt.play_sound_file("Good Job.rso",true)
125
+ sleep(2)
126
+ assert @@nxt.stop_sound_playback
127
+ end
128
+
129
+ def test_keep_alive
130
+ assert_equal 600000, @@nxt.keep_alive
131
+ end
132
+
133
+ def test_get_current_program_name
134
+ err = capture_stderr { assert !@@nxt.get_current_program_name }
135
+ assert_equal "ERROR: No active program\n", err
136
+
137
+ assert @@nxt.start_program("Try-Touch.rtm")
138
+ sleep(1)
139
+ assert_equal "Try-Touch.rtm", @@nxt.get_current_program_name
140
+ assert @@nxt.stop_program
141
+ end
142
+
143
+ # TODO write tests for the LS methods, since I'm still not sure what they do,
144
+ # I don't know how to test them
145
+
146
+ def test_ls_get_status
147
+ end
148
+
149
+ def test_ls_write
150
+ end
151
+
152
+ def test_ls_read
153
+ end
154
+
155
+ end