Previous Meeting: ParcMeeting20100321
Next Meeting: ParcMeeting20100418
April 4th, 2010 -- 3PM to 5PM
Please make sure to bring a functional "Good Base Mobile Robot" to the meeting. Either the same one from the previous meeting, or a suitable replacement.
The primary agenda will be based on finishing up Session-1 at ParcCourse compared to where the three teams progressed to on ParcMeeting20100321.
The tentative agenda is:
Other agenda topics are likely to be:
Resources
One of the more important, advanced, and (unfortunately) complicated aspects to work with in NXT-G is being able to "Move a distance or until a sensor event". The problems are:
* NXT-G has no 'event' processing / interrupt capability within its loops (RCX actually had that)
* The smarter blocks like 'Move' are blocking when they do things like go-until-sensor
* A couple of the sensor blocks are a little more obscure than you would expect, requiring a 'reset' before use
An approach to solving this problem that was showed today was:
* Turn a move/motor on -- forever, so the block finishes immediately
* Enter into a loop that
* Reads one sensor (Sensor A), and immediately continues [a yellow block]
* Reads a second sensor (Sensor B), and immediately continues [another yellow block]
* Combines the Logic output (the "Yay") of the two readings together, and immediately continues [dark orange block]
* Loops unless the Logic Block (an "Or" of either sensor) is true [loop until logic]
* Then stops the motor
The core example is below. This one uses a timer, which is what Team-2 used:
The Logic block is set as follows to produce the 'Or' output:
The motor is started and immediately goes into the loop block. The loop block will run until either the yellow Timer is triggered or the yellow Ultrasonic is triggered. Both of these blocks immediately continue to the next step and do not block. If either is triggered by the end of the loop, the loop stops and goes to the next green block, which stops forward progress. Note-1: This loop is a "tight loop" and executes over-and-over rapidly. None of the blocks in the loop wait for anything. Note-2: The outputs of the yellow blocks are the logic check output (the [Check]/[X]), and not the timer or ultrasound value. You have to open the Data Hub to get access to these outputs. Expanded the center block looks like this:
For both the Timer and the Rotation sensor, you need to reset them before the loop. So the full 'algorithm' / idiom is:
Where the added block after the first move is a reset [notice its little icons], and not a reading.
After this loop finishes, you need to figure out why it stopped. The simplest approach is to just check one of the sensors again. The following checks the ultrasound value via an 'if'.
And then putting all this into a nice big patrolling-kind-of-loop, you get:
The idiom is not trivial, but I am hoping it is fairly intelligible after (1) Getting a feeling of real-time systems, blocking, and event issues (2) Just seeing and trying it. Comparing this to how a different language might achieve the same results [and efficiency issues of both], would be interesting.
There are alternative languages for the NXT. One simple one is NXC, so I demoed a simple version of that. An example of NXC is below:
$ more test1.nxc
task main() {
TextOut(0, LCD_LINE1, "Hello World");
Wait(SEC_10);
}
And decompiled NBC / Assembly Language for the same looks like the below. It is much more complicated and less useful unless you really want to study machine / assembly language:
$ more test1.nbc
; test1.rxe
; -------------- variable declarations --------------
dseg segment
;------- definitions -------
c000C_def struct
sw000D sword
sw000E sword
c000C_def ends
c000A_def struct
sb000B sbyte
c000C c000C_def
a000F byte[]
ul0011 dword
c000A_def ends
;------- declarations -------
ul0000 dword
sl0001 sdword
sl0002 sdword
sl0003 sdword
ul0004 dword
uw0005 word
sb0006 sbyte
ub0007 byte
ub0008 byte
sb0009 sbyte 16
c000A c000A_def
a0012 sdword[]
a0014 byte[]
a0016 byte[] 'Hello World'
dseg ends
; -------------- program code --------------
thread t000
arrinit a0012, sb0006, sb0009
set sl0001, 0x0
mov sl0003, sl0001
set sl0001, 0x38
mov sl0002, sl0001
strcat a0014, a0016
mov c000A.c000C.sw000D, sl0003
mov c000A.c000C.sw000E, sl0002
set c000A.ul0011, 0x0
mov c000A.a000F, a0014
syscall DrawText, c000A
mov sl0001, c000A.sb000B
set sl0001, 0x2710
mov uw0005, sl0001
subcall t001, ub0007
exit -1, -1
endt
;-----------------------------------
thread t001
gettick ul0000
add ul0004, ul0000, uw0005
lbl0030: gettick ul0000
brcmp LT, lbl0030, ul0000, ul0004
subret ub0007
endt