ruby-nxt 0.8.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.
@@ -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