root/trunk/tools/ToolboxTest.m @ 922

Revision 922, 20.0 KB (checked in by atorf, 3 years ago)
  • Fixed minor bug that didn't display the correct sleep time limit in ToolboxTest?.m
  • Last cosmetic help fix for this release
Line 
1function ToolboxTest
2%% ToolboxTest
3% This tool offers multiple toolbox tests, originally written to track
4% or confirm certain bugs. The quality of these tests isn't very high,
5% but running and passing them should make sure the bugs are gone and
6% don't return after certain changes.
7%
8% For the tests you have to connect the following hardware equipment to
9% your NXT:
10%
11% * All 3 motors to ports A, B, C
12% * The NXT light sensor to port 1
13% * Any digital sensor to port 4 (e.g. ultrasonic).
14%
15% The following tests are available. They can (and should) all be tested
16% with USB and Bluetooth connections:
17%
18% # Command syntax check: Many toolbox commands are called and tested, with
19% or without default handles. This detects syntax errors and obvious
20% mistakes when changing / braking a function.
21% # Check USB connection after cable has been removed -- versions prior to
22% 4.01 would crash MATLAB on Linux here.
23% # Motor control timing and multitasking tests: Does the motor control
24% lock up or stall when braking multiple motors at once, etc.?
25% # Motor precision torture test: Many random movements, does it work for a
26% long time? What is the overall precision?
27% # Motor precision torture as above, but with all motors running
28% simultaneously (and independently)
29% # Same as above, but this time two motors are synced and the other one
30% runs independently.
31%
32%
33% Signature
34%   Author: Linus Atorf (see AUTHORS)
35%   Date: 2009/10/07
36%   Copyright: 2007-2010, RWTH Aachen University
37%
38%
39;
40%
41% ***********************************************************************************************
42% *  This file is part of the RWTH - Mindstorms NXT Toolbox.                                    *
43% *                                                                                             *
44% *  The RWTH - Mindstorms NXT Toolbox is free software: you can redistribute it and/or modify  *
45% *  it under the terms of the GNU General Public License as published by the Free Software     *
46% *  Foundation, either version 3 of the License, or (at your option) any later version.        *
47% *                                                                                             *
48% *  The RWTH - Mindstorms NXT Toolbox is distributed in the hope that it will be useful,       *
49% *  but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS  *
50% *  FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.             *
51% *                                                                                             *
52% *  You should have received a copy of the GNU General Public License along with the           *
53% *  RWTH - Mindstorms NXT Toolbox. If not, see <http://www.gnu.org/licenses/>.                 *
54% ***********************************************************************************************
55
56
57
58    %% Clean up previous handles
59    COM_CloseNXT all
60
61    %% Set up Matlab
62    clear all % if you use clear all, call COM_CloseNXT all before, as we did!
63    close all
64    format compact
65
66    DebugMode off
67
68    disp(sprintf(['Available tests:\n', ...
69          ' 1. Test syntax of most commands (test terminates)\n', ...
70          ' 2. Test "MATLAB crash on Linux after USB cable removed bug"\n', ...
71          '    fixed in ver4.02, see also ticket 39 (test terminates)\n', ...
72          ' 3. Test certain MotorControl timing/latency (test terminates)\n', ...
73          ' 4. Torture test for MotorControl precsion, single motor\n', ...
74          '    (test runs infinitely, break with CTRL+C)\n', ...
75          ' 5. Torture test for MotorControl precsion, all motors\n', ...
76          '    (test runs infinitely, break with CTRL+C)\n', ...
77          ' 6. Torture test for MotorControl precsion, two motors synced\n', ...
78          '    one motor single (test runs infinitely, break with CTRL+C)\n', ...
79           ]))
80       
81    answer = NaN;
82    while(isnan(answer))
83        answer = str2double(input('Enter your choice: ', 's'));
84    end%if
85
86    testFunc{1} = @TestCommandSyntax;
87    testFunc{2} = @TestNoUSBCableBug;
88    testFunc{3} = @CheckLatenciesBetweenStopAndSend;
89    testFunc{4} = @SingleMotorPrecisionTorture;
90    testFunc{5} = @AllMotorsPrecisionTorture;
91    testFunc{6} = @TwoSyncedOneSingleMotorsPrecisionTorture;
92   
93   
94    disp(sprintf('\nStarting test no. %d ...\n', answer));
95   
96    testFunc{answer}();
97 
98
99
100end%function
101
102function TestCommandSyntax
103    analogPort = SENSOR_1;
104    digitalPort = SENSOR_4;
105   
106    %% Connect to NXT
107    disp('    Connecting...')
108
109    % different syntaxes and things
110    h = COM_OpenNXT('bluetooth.ini');
111    COM_CloseNXT(h);
112    h = COM_OpenNXT('bluetooth.ini');
113    COM_CloseNXT('all');
114
115    h = COM_OpenNXTEx('Any', '', 'bluetooth.ini');
116
117
118
119    %% Try the commands WITHOUT default handle
120    disp('    *** Commands without default handle')
121
122    %% *** SENSORS
123    disp('    Sensors...')
124
125    port = analogPort;
126    %% analog
127    %light
128    OpenLight(port, 'active', h);
129    NXT_ResetInputScaledValue(port, h);
130    GetLight(port, h);
131    CloseSensor(port, h);
132
133    OpenLight(port, 'inactive', h);
134    GetLight(port, h);
135    CloseSensor(port, h);
136
137    %sound
138    OpenSound(port, 'db', h);
139    GetSound(port, h);
140    CloseSensor(port, h);
141
142    OpenSound(port, 'dba', h);
143    GetSound(port, h);
144    CloseSensor(port, h);
145
146    %switch
147    OpenSwitch(port, h);
148    GetSwitch(port, h);
149    CloseSensor(port, h);
150   
151    % gyro
152    OpenGyro(port, h);
153    CalibrateGyro(port, 'Auto', h);
154    GetGyro(port, h);
155    CloseSensor(port, h);
156
157
158    port = digitalPort;
159
160    %% I2C
161    disp('    I2C...')
162
163    %ultrasonic
164    OpenUltrasonic(port, '', h);
165    GetUltrasonic(port, h);
166    CloseSensor(port, h);
167
168    OpenUltrasonic(port, 'snapshot', h);
169    USMakeSnapshot(port, h);
170    USGetSnapshotResults(port, h);
171    CloseSensor(port, h);
172
173    %compass
174    OpenCompass(port, h);
175    GetCompass(port, h);
176    CalibrateCompass(port, true, h);
177    pause(0.5);
178    CalibrateCompass(port, false, h);
179    CloseSensor(port, h);
180
181    %acceleration
182    OpenAccelerator(port, h);
183    GetAccelerator(port, h);
184    CloseSensor(port, h);
185
186    %infrared
187    OpenInfrared(port, h);
188    GetInfrared(port, h);
189    CloseSensor(port, h);
190
191
192    %% MOTORS
193    port = MOTOR_B;
194    port2 = MOTOR_C;
195    disp('    Motors...')
196
197    StopMotor('all', 'brake', h);
198    StopMotor('all', 'off', h);
199
200    SwitchLamp(port, 'on', h);
201    SwitchLamp(port, 'off', h);
202   
203    m   = NXTMotor(port);
204    m2  = NXTMotor([port; port2]);
205
206    tmp1 = m.ReadFromNXT(h);
207    m.ResetPosition(h);
208    m.Stop('brake', h);
209    m.Stop('off', h);
210   
211    [tmp1 tmp2] = m2.ReadFromNXT(h);
212    m2.ResetPosition(h);
213    m2.Stop('brake', h);
214    m2.Stop('off', h);
215   
216    m.WaitFor(5, h);
217    m2.WaitFor(5, h);
218   
219    m.Power = 50;
220    m.TachoLimit = 300;
221    m.ActionAtTachoLimit = 'Brake';
222    m.SpeedRegulation = true;
223    m.SmoothStart = true;
224    m.SendToNXT(h);
225    m.WaitFor(10, h);
226   
227    m.SpeedRegulation = false;
228    m.SmoothStart = true;
229    m.ActionAtTachoLimit = 'HoldBrake';
230    m.SendToNXT(h);
231    m.WaitFor(10, h);
232   
233    m.ActionAtTachoLimit = 'Coast';
234    m.SmoothStart = false;
235    m.SendToNXT(h);
236    m.WaitFor(10, h);
237   
238    m.Stop('off', h);
239   
240    m2.Power = -50;
241    m2.TachoLimit = 400;
242    m2.SpeedRegulation = false;
243    m2.ActionAtTachoLimit = 'Brake';
244    m2.SmoothStart = true;
245    m2.SendToNXT(h);
246    m2.WaitFor(10, h);
247   
248    m2.Stop('off', h);
249   
250
251
252    %% Direct Commands
253    disp('    Some direct commands...')
254
255
256    NXT_ResetMotorPosition(port, true, h);
257    NXT_ResetMotorPosition(port, false, h);
258
259    NXT_SendKeepAlive('dontreply', h);
260
261    NXT_PlayTone(800, 500, h);
262
263    [status sleeptime]  = NXT_SendKeepAlive('reply', h);
264    battery             = NXT_GetBatteryLevel(h);
265    [protocol firmware] = NXT_GetFirmwareVersion(h);
266
267    battery
268    sleeptime
269    firmware
270
271
272    %% Set Default!
273
274    COM_SetDefaultNXT(h);
275
276    %% Try the commands WITH default handle
277    disp('    *** Commands with default handle')
278
279    %% *** SENSORS
280    disp('    Sensors...')
281
282    port = analogPort;
283    %% analog
284    %light
285    OpenLight(port, 'active');
286    NXT_ResetInputScaledValue(port);
287    GetLight(port);
288    CloseSensor(port);
289
290    OpenLight(port, 'inactive');
291    GetLight(port);
292    CloseSensor(port);
293
294    %sound
295    OpenSound(port, 'db');
296    GetSound(port);
297    CloseSensor(port);
298
299    OpenSound(port, 'dba');
300    GetSound(port);
301    CloseSensor(port);
302
303    %switch
304    OpenSwitch(port);
305    GetSwitch(port);
306    CloseSensor(port);
307   
308    % gyro
309    OpenGyro(port);
310    CalibrateGyro(port, 'Auto');
311    GetGyro(port);
312    CloseSensor(port);
313
314
315    port = digitalPort;
316
317    %% I2C
318    disp('    I2C...')
319
320    %ultrasonic
321    OpenUltrasonic(port, '');
322    GetUltrasonic(port);
323    CloseSensor(port);
324
325    OpenUltrasonic(port, 'snapshot');
326    USMakeSnapshot(port);
327    USGetSnapshotResults(port);
328    CloseSensor(port);
329
330    %compass
331    OpenCompass(port);
332    GetCompass(port);
333    CalibrateCompass(port, true);
334    pause(0.5);
335    CalibrateCompass(port, false);
336    CloseSensor(port);
337
338    %acceleration
339    OpenAccelerator(port);
340    GetAccelerator(port);
341    CloseSensor(port);
342
343    %infrared
344    OpenInfrared(port);
345    GetInfrared(port);
346    CloseSensor(port);
347
348
349    %% MOTORS
350    port = MOTOR_B;
351    port2 = MOTOR_C;
352    disp('    Motors...')
353
354    StopMotor('all', 'brake');
355    StopMotor('all', 'off');
356
357    SwitchLamp(port, 'on');
358    SwitchLamp(port, 'off');
359   
360    m   = NXTMotor(port);
361    m2  = NXTMotor([port; port2]);
362
363    tmp1 = m.ReadFromNXT();
364    m.ResetPosition();
365    m.Stop('brake');
366    m.Stop('off');
367   
368    [tmp1 tmp2] = m2.ReadFromNXT();
369    m2.ResetPosition();
370    m2.Stop('brake');
371    m2.Stop('off');
372   
373    m.WaitFor();
374    m2.WaitFor();
375   
376    m.Power = 50;
377    m.TachoLimit = 300;
378    m.ActionAtTachoLimit = 'Brake';
379    m.SpeedRegulation = true;
380    m.SmoothStart = true;
381    m.SendToNXT();
382    m.WaitFor();
383   
384    m.SpeedRegulation = false;
385    m.SmoothStart = true;
386    m.ActionAtTachoLimit = 'HoldBrake';
387    m.SendToNXT();
388    m.WaitFor();
389   
390    m.ActionAtTachoLimit = 'Coast';
391    m.SmoothStart = false;
392    m.SendToNXT();
393    m.WaitFor();
394   
395    m.Stop('off');
396   
397    m2.Power = -50;
398    m2.SpeedRegulation = false;
399    m2.TachoLimit = 400;
400    m2.ActionAtTachoLimit = 'Brake';
401    m2.SmoothStart = true;
402    m2.SendToNXT();
403    m2.WaitFor();
404   
405    m2.Stop('off');
406
407
408    %% Direct Commands
409    disp('    Some direct commands...')
410
411
412    NXT_ResetMotorPosition(port, true);
413    NXT_ResetMotorPosition(port, false);
414
415    NXT_SendKeepAlive('dontreply');
416
417    NXT_PlayTone(800, 500);
418
419    [status sleeptime]  = NXT_SendKeepAlive('reply');
420    battery             = NXT_GetBatteryLevel(h);
421    [protocol firmware] = NXT_GetFirmwareVersion(h);
422
423    battery
424    sleeptime
425    firmware
426
427
428
429
430
431    COM_CloseNXT(h);
432
433    disp('    *** Test successful so far ***')
434end%function
435
436function TestNoUSBCableBug
437    COM_CloseNXT all
438    clear all
439
440    disp('    No MATLAB crash means: TEST SUCCESSFUL!')
441    disp('    Any error message is a good thing!')
442    disp('    ')
443
444    DebugMode off
445
446    % USB Verbindung herstellen
447    myNXT = COM_OpenNXT();
448    COM_CloseNXT(myNXT);
449
450
451    disp('    UNPLUG USB CABLE')
452    disp('    Press ENTER to continue')
453    pause;
454
455
456    % Bluetooth Verbindung herstellen (actually USB ^^)
457    myNXT = COM_OpenNXT();
458
459    COM_CloseNXT(myNXT);
460   
461end%function
462
463function CheckLatenciesBetweenStopAndSend()
464    COM_CloseNXT all
465
466    disp('    Listen for the NXT to beep. It should NOT do that!');
467    disp('    Beeping means a dropped motor command, this is bad.');
468    disp('    Motors B and C should spin, stop, then motor B spin.');
469    disp('    Press ENTER to continue...');
470    pause;
471   
472    %% Set up parameters
473    port                = MOTOR_B;
474    port2               = MOTOR_C;
475
476
477    %% Connect to NXT
478    hNXT = COM_OpenNXT('bluetooth.ini');
479    COM_SetDefaultNXT(hNXT);
480
481
482    %% Create basic object
483    m = NXTMotor;
484    m.Port                  = port;
485    m.Power                 = 80;
486    m.TachoLimit            = 1000;
487    m.SpeedRegulation       = true;
488    m.SmoothStart           = true;
489    m.ActionAtTachoLimit    = 'Brake';
490
491    m2 = m;
492    m2.Port = port2;
493
494    %% Precall method to fill MATLAB cache;
495    % the order here makes sense, even with the multiple commands :-)
496    % it's the proper way to use .WaitFor after .Stop! It might be a bit slower
497    % sometimes, but it can never go wrong!
498    m.Stop();
499    m.WaitFor();
500    m.SendToNXT();
501    m.Stop();
502    m.WaitFor();
503
504    pause(0.5);
505
506    %% Main test
507
508    % start 1st motor
509    m.SendToNXT();
510    % now the trick that let's us create very fine granulated pauses:
511    % what we wait here will be the time we get to use .Stop before
512    % the motor stops, so we can get right into the interesting
513    % last braking section
514    pause(0.1);
515    m2.SendToNXT();
516
517    % when waiting for the 1st motor is done, the 2nd will be exactly the
518    % amount of pause before finishing (if the motors run exact equally).
519    m.WaitFor()
520
521    % now the test:
522    m2.Stop();
523    % can we already start the next command with m2?
524    m2.SendToNXT();
525
526
527    %% Clean up
528    COM_CloseNXT(hNXT);
529   
530     disp('Test completed (no NXT beep and 2 separate movements means: successful)');
531
532end%function
533
534function SingleMotorPrecisionTorture()
535    %% Prepare
536    COM_CloseNXT all
537   
538    disp('   Running torture test. Beeping NXT or')
539    disp('   TIME OUT warnings are bad!')
540    disp('   Terminate with CTRL+C')
541   
542
543    %% Set up parameters
544    port                = MOTOR_B;
545    ActionAtTachoLimit  = 'Brake';
546
547    minAbsPower         =    10;
548    maxAbsPower         =   100;
549    minTachoLimit       =    8;
550    maxTachoLimit       =  1200;
551
552
553    %% Create basic motor object
554    m = NXTMotor;
555    m.Port                  = port;
556    %m.SpeedRegulation       = SpeedRegulation;
557    %m.SmoothStart           = SmoothStart;
558    m.ActionAtTachoLimit    = ActionAtTachoLimit;
559
560
561    %% Connect to NXT
562    hNXT = COM_OpenNXT('bluetooth.ini');
563    COM_SetDefaultNXT(hNXT);
564
565
566    %% Main testing loop
567    figure;
568    j = 0;
569    while (true)
570        j = j + 1;
571
572        m.SpeedRegulation   = (rand > 0.5);
573        m.SmoothStart       = (rand > 0.5);
574
575
576        powerSgn    = 1 - (rand > 0.5) * 2;
577        absPower    = floor(minAbsPower + (maxAbsPower - minAbsPower) * rand);
578        tachoLimit  = floor(minTachoLimit + (maxTachoLimit - minTachoLimit) * rand);
579
580        m.Power         = absPower * powerSgn;
581        m.TachoLimit    = tachoLimit;
582
583        m.SendToNXT();
584        if m.WaitFor(20)
585            disp('TIME OUT')
586            NXT_PlayTone(600, 500);
587            stat = NXT_GetOutputState(m.Port(1))
588            m
589            m.Stop('off');
590        end%if
591
592
593
594        data = m.ReadFromNXT();
595
596        error(j) = (data.TachoCount * powerSgn) - tachoLimit;
597
598        hist(error);
599        xlabel('Absolute error (relative to target position) in degrees')
600        ylabel('Absolute number of error values occured')
601        title('Histogram for motor precision')
602        drawnow
603
604    end%while
605end%function
606
607function AllMotorsPrecisionTorture()
608    %% Prepare
609    COM_CloseNXT all
610
611    disp('   Running torture test. Beeping NXT or')
612    disp('   TIME OUT warnings are bad!')
613    disp('   Terminate with CTRL+C')
614   
615   
616    %% Set up parameters
617    port                = MOTOR_B;
618    port2               = MOTOR_C;
619    port3               = MOTOR_A;
620
621    ActionAtTachoLimit  = 'Brake';
622
623    minAbsPower         =    10;
624    maxAbsPower         =   100;
625    minTachoLimit       =    8;
626    maxTachoLimit       =  1200;
627
628
629    %% Create basic motor object
630    m = NXTMotor;
631    m.Port                  = port;
632    m.ActionAtTachoLimit    = ActionAtTachoLimit;
633
634
635    %% Connect to NXT
636    hNXT = COM_OpenNXT('bluetooth.ini');
637    COM_SetDefaultNXT(hNXT);
638
639
640    %% Main testing loop
641    figure;
642    j = 0;
643    while (true)
644        j = j + 1;
645
646        powerSgn    = 1 - (rand > 0.5) * 2;
647        absPower    = floor(minAbsPower + (maxAbsPower - minAbsPower) * rand);
648        tachoLimit  = floor(minTachoLimit + (maxTachoLimit - minTachoLimit) * rand);
649
650        m.SpeedRegulation   = (rand > 0.5);
651        m.SmoothStart       = (rand > 0.5);
652
653
654        m.Power         = absPower * powerSgn;
655        m.TachoLimit    = tachoLimit;
656
657        m2 = m;
658        m2.Port = port2;
659        m3 = m;
660        m3.Port = port3;
661
662        m2.Stop();
663        m3.Stop();
664
665        %pause(0.5);
666
667        m.SendToNXT();
668
669        pause(0.1 * rand);
670        m2.SendToNXT();
671        pause(0.1 * rand);
672        m3.SendToNXT();
673
674        if m.WaitFor(20);
675            disp('TIME OUT')
676            NXT_PlayTone(600, 500);
677            stat = NXT_GetOutputState(m.Port(1))
678            m
679            m.Stop('off');
680        end%if
681
682        data = m.ReadFromNXT();
683
684        error(j) = (data.TachoCount * powerSgn) - tachoLimit;
685        hist(error);
686        xlabel('Absolute error (relative to target position) in degrees')
687        ylabel('Absolute number of error values occured')
688        title('Histogram for motor precision')
689        drawnow
690
691    end%while
692
693
694
695    %% Clean up
696    COM_CloseNXT(hNXT);
697
698end%function
699
700function TwoSyncedOneSingleMotorsPrecisionTorture()
701    %% Prepare
702    COM_CloseNXT all
703   
704    disp('   Running torture test. Beeping NXT or')
705    disp('   TIME OUT warnings are bad!')
706    disp('   Terminate with CTRL+C')
707
708    %% Set up parameters
709    singlePort          = MOTOR_A;
710    syncPort1           = MOTOR_B;
711    syncPort2           = MOTOR_C;
712
713    SpeedRegulation     = false;
714    SmoothStart         = true;
715    ActionAtTachoLimit  = 'Brake';
716
717    minAbsPower         =    10;
718    maxAbsPower         =   100;
719    minTachoLimit       =    8;
720    maxTachoLimit       =  1200;
721
722
723    %% Create basic motor object
724    m = NXTMotor;
725    m.Port                  = singlePort;
726    m.SpeedRegulation       = SpeedRegulation;
727    m.SmoothStart           = SmoothStart;
728    m.ActionAtTachoLimit    = ActionAtTachoLimit;
729
730    %% Create decoy sync object
731    s = NXTMotor;
732    s.Port                  = [syncPort1; syncPort2];
733    s.SpeedRegulation       = false; % off for sync
734    s.SmoothStart           = SmoothStart;
735    s.ActionAtTachoLimit    = ActionAtTachoLimit;
736
737
738    %% Connect to NXT
739    hNXT = COM_OpenNXT('bluetooth.ini');
740    COM_SetDefaultNXT(hNXT);
741
742
743    %% Main testing loop
744    figure;
745    j = 0;
746    while (true)
747        j = j + 1;
748
749
750        powerSgn    = 1 - (rand > 0.5) * 2;
751        absPower    = floor(minAbsPower + (maxAbsPower - minAbsPower) * rand);
752        tachoLimit  = floor(minTachoLimit + (maxTachoLimit - minTachoLimit) * rand);
753
754        m.Power           = absPower * powerSgn;
755        m.TachoLimit      = tachoLimit;
756        m.SmoothStart     = (rand > 0.5);
757        m.SpeedRegulation = (rand > 0.5);
758
759        s.Power         = m.Power;
760        s.TachoLimit    = m.TachoLimit;
761        s.SmoothStart   = (rand > 0.5);
762
763        s.Stop();
764
765        %pause(0.5);
766
767        m.SendToNXT();
768
769        pause(0.1 * rand);
770        s.SendToNXT();
771
772        if m.WaitFor(20)
773            disp('TIME OUT')
774            NXT_PlayTone(600, 500);
775            stat = NXT_GetOutputState(m.Port(1))
776            m
777            m.Stop('off');
778        end%if
779
780        data = m.ReadFromNXT();
781
782        error(j) = (data.TachoCount * powerSgn) - tachoLimit;
783        hist(error);
784        xlabel('Absolute error (relative to target position) in degrees')
785        ylabel('Absolute number of error values occured')
786        title('Histogram for motor precision')
787        drawnow
788
789    end%while
790
791
792
793    %% Clean up
794    COM_CloseNXT(hNXT);
795end%function
Note: See TracBrowser for help on using the browser.