Docsity
Docsity

Prepare-se para as provas
Prepare-se para as provas

Estude fácil! Tem muito documento disponível na Docsity


Ganhe pontos para baixar
Ganhe pontos para baixar

Ganhe pontos ajudando outros esrudantes ou compre um plano Premium


Guias e Dicas
Guias e Dicas


Programming Lego Robots using NBC, Notas de estudo de Análise de Sistemas de Engenharia

Book to learning how to programming your Lego using alternative language.

Tipologia: Notas de estudo

Antes de 2010

Compartilhado em 14/06/2010

giovanni-vecchia-11
giovanni-vecchia-11 🇧🇷

3 documentos

1 / 45

Toggle sidebar

Esta página não é visível na pré-visualização

Não perca as partes importantes!

bg1
Programming Lego Robots
using NBC
(Version 1.0, June 11, 2007)
(Requires NBC 1.0.1.b30 or greater)
by Ross Crawford
with revisions by John Hansen
pf3
pf4
pf5
pf8
pf9
pfa
pfd
pfe
pff
pf12
pf13
pf14
pf15
pf16
pf17
pf18
pf19
pf1a
pf1b
pf1c
pf1d
pf1e
pf1f
pf20
pf21
pf22
pf23
pf24
pf25
pf26
pf27
pf28
pf29
pf2a
pf2b
pf2c
pf2d

Pré-visualização parcial do texto

Baixe Programming Lego Robots using NBC e outras Notas de estudo em PDF para Análise de Sistemas de Engenharia, somente na Docsity!

Programming Lego Robots

using NBC

(Version 1.0, June 11, 2007)

(Requires NBC 1.0.1.b30 or greater)

by Ross Crawford

with revisions by John Hansen

Preface

The Lego MindStorms NXT robot is a wonderful new toy from which a wide variety of robots can be

constructed, that can be programmed to do all sorts of complicated tasks. Unfortunately, the software that comes

with the robot, although visually attractive and much more powerful than the RIS software for the RCX, is still

somewhat limited in its functionality. To unleash the full power of your robot, you need a different programming

environment. NBC is a programming language, written by John Hansen, which is especially designed for the

Lego robots. If you have never written a program before, don't worry. NBC is really easy to use and this tutorial

will tell you all about it. Actually, programming robots in NBC is a lot easier than programming a normal

computer, so this is a chance to become a programmer in an easy way.

To make writing programs even easier, there is the Bricx Command Center. This utility helps you to write your

programs, to send them to the robot, and to start and stop the robot. Bricx Command Center works almost like a

text processor, but with some extras. This tutorial will use Bricx Command Center (version 3.3.7.15 or higher) as

programming environment. You can download it for free from the web at the address

http://bricxcc.sourceforge.net/

Bricx Command Center runs on Windows PC’s (95, 98, ME, NT, 2K, XP). The language NBC can also be

downloaded from the web at address

http://bricxcc.sourceforge.net/nbc/

Acknowledgements

I would like to thank John Hansen for developing NBC. Also many thanks to Mark Overmars for writing his

NQC tutorial, on which this is heavily based.

  • Preface ___________________________________________________________________
    • Acknowledgements ____________________________________________________________________
  • Contents __________________________________________________________________
  • I. Writing your first program __________________________________________________
    • Building a robot ______________________________________________________________________
    • Starting Bricx Command Center __________________________________________________________
    • Writing the program ___________________________________________________________________
    • Running the program __________________________________________________________________
    • Errors in your program _________________________________________________________________
    • Changing the speed ____________________________________________________________________
    • Adding comments _____________________________________________________________________
    • Summary ___________________________________________________________________________
  • II. Using variables _________________________________________________________
    • Moving in different ways ______________________________________________________________
    • Displaying results on the screen _________________________________________________________
    • Random numbers ____________________________________________________________________
    • Summary ___________________________________________________________________________
  • III. Flow Control __________________________________________________________
    • The cmp and tst statements _____________________________________________________________
    • The brcmp and brtst statements__________________________________________________________
    • The jmp statement____________________________________________________________________
    • Loops – repeating code ________________________________________________________________
    • Summary ___________________________________________________________________________
  • IV. Sensors _______________________________________________________________
    • Waiting for a sensor __________________________________________________________________
    • Acting on a touch sensor _______________________________________________________________
    • Light sensors ________________________________________________________________________
    • Summary ___________________________________________________________________________
  • V. Making music___________________________________________________________
    • Playing tones ________________________________________________________________________
    • Playing files ________________________________________________________________________
    • Creating your own sound files __________________________________________________________
    • Summary ___________________________________________________________________________
  • VI. Threads and subroutines _________________________________________________
    • Threads ____________________________________________________________________________
    • Subroutines _________________________________________________________________________
    • Defining macros _____________________________________________________________________
    • Summary ___________________________________________________________________________
  • VII. More about motors _____________________________________________________
    • Stopping gently ______________________________________________________________________
    • Synchronising motors _________________________________________________________________
    • Regulating the motor speed_____________________________________________________________
    • Rotating a specific angle _______________________________________________________________
    • More advanced motor control ___________________________________________________________
    • Summary ___________________________________________________________________________
  • VIII. More about sensors ____________________________________________________
    • Sensor type _________________________________________________________________________
    • Sensor mode ________________________________________________________________________
    • Sound sensor ________________________________________________________________________
    • Motor as a rotation sensor ______________________________________________________________
    • Ultrasonic sensor_____________________________________________________________________
    • More advanced sensor control __________________________________________________________
    • Putting it all together__________________________________________________________________
    • Summary ___________________________________________________________________________
  • IX. Parallel threads ________________________________________________________
    • A wrong program ____________________________________________________________________
    • Using mutexes_______________________________________________________________________
    • Summary ___________________________________________________________________________
  • X. Communication between robots ____________________________________________
    • Communication with other NXT bricks ___________________________________________________
    • Communication with a PC _____________________________________________________________
    • Communication with other Bluetooth devices ______________________________________________
    • Summary ___________________________________________________________________________
  • XI. More commands ________________________________________________________
    • System calls ________________________________________________________________________
    • System clock ________________________________________________________________________
    • Arrays _____________________________________________________________________________
    • Type declarations ____________________________________________________________________
    • Type aliases_________________________________________________________________________
    • Summary ___________________________________________________________________________

I. Writing your first program

In this chapter I will show you how to write an extremely simple program. We are going to program a robot to

move forwards for 4 seconds, then backwards for another 4 seconds, and then stop. Not very spectacular but it

will introduce you to the basic idea of programming. And it will show you how easy this is. But before we can

write a program, we first need a robot.

Building a robot

The robot we will use throughout this tutorial is the “Tribot”, the instructions for which are included with your

NXT set. If you are new to LEGO robotics, I recommend doing the tutorials that come with the LEGO software,

to get acquainted with what your NXT can do. Your robot should look like this:

(Note that you may already have added sensors and a grabber – if so, you should remove them temporarily, as

some of the examples may not work correctly with them attached.)

Starting Bricx Command Center

We write our programs using Bricx Command Center. Start it by double clicking on the icon BricxCC. (I assume

you already installed Bricx Command Center. If not, download it from the web site (see the preface), and install

it in any directory you like.) The program will ask you where to locate the robot. Switch the robot on and press

OK. The program will (most likely) automatically find the robot. Now the user interface appears as shown below

(without a window).

This statement tells the robot to start output B, that is, the motor connected to the output labeled B on the NXT,

to move forwards. The 100 specifies the percentage of maximum speed, so it will move with maximum speed.

OnFwd(OUT_C,100)

Same statement but now we start motor C. After these two statements, both motors are running, and the robot

moves forwards.

wait 4000

Now it is time to wait for a while. This statement tells us to wait for 4 seconds. The argument gives the number

of milliseconds, or 1/1000 of a second. So you can very precisely tell the program how long to wait. So for 4

seconds, the program does nothing and the robot continues to move forwards.

OnRev(OUT_BC,100)

The robot has now moved far enough so we tell it to move in reverse direction, that is, backwards. Note that we

can set both motors at once using OUT_BC as argument. We could also have combined the first two statements

this way. We could also use OnFwd(OUT_BC,-100).

wait 4000

Again we wait for 4 seconds.

Off(OUT_BC)

And finally we switch both motors off.

exit

This statement tells the NXT this thread has finished. While not required at the end of threads, it is

recommended. Note also that it can appear elsewhere in the thread as well.

That is the whole program. It moves both motors forwards for 4 seconds, then backwards for 4 seconds, and

finally switches them off.

You probably noticed the colors when typing in the program. They appear automatically. The colors and styles

used by the editor when it performs syntax highlighting are customizable.

Running the program

Once you have written a program, it needs to be compiled (that is, changed into code that the robot can

understand and execute) and sent to the robot using either the USB cable or a Bluetooth device (called

“downloading” the program). Before you can do that, you need to name the program, which you do by saving it

to your hard drive. When you save it, make sure the file extension is “.nbc”, this tells Bricx Command Center

that it is an NBC program.

Once it has been saved, you can compile and download it simply by clicking the download button. Assuming

you made no errors when typing in the program, it will correctly compile and be downloaded. (If there are errors

in your program you will be notified; see below.)

Now you can run your program. To do this, go to “Software Files” on your NXT, and look for “1-simple”, then

use the orange NXT button to run it. Or alternatively, you can run it from Bricx Command Center, by pressing

the green run button on your window (see the figure above). Does the robot do what you expected? If not, the

wires are probably connected incorrectly.

Errors in your program

When typing in programs there is a reasonable chance that you make some errors. The compiler notices the

errors and reports them to you at the bottom of the window, like in the following figure:

It automatically selects the first error (we mistyped the name of the motor). When there are more errors, you can

click on the error messages to go to them. Note that often errors at the beginning of the program cause other

errors at other places. So better only correct the first few errors and then compile the program again.

/* Forward and reverse

by Ross Crawford

This program makes the robot go forward and backward */

#define SPEED 25 #define MOVE_TIME 4000

thread main OnFwd(OUT_BC, SPEED) // Drive forward wait MOVE_TIME // Wait for 4 seconds OnRev(OUT_BC, SPEED) // Drive backward wait MOVE_TIME // Wait for 4 seconds Off(OUT_BC) // Stop moving exit // Exit endt

Summary

In this chapter you wrote your first program in NBC, using Bricx Command Center. You should now know how

to type in a program, how to download it to the robot and how to let the robot execute the program. Bricx

Command Center can do many more things. To find out about them, read the documentation that comes with it.

This tutorial will primarily deal with the language NBC and only mention features of Bricx Command Center

when you really need them.

You also learned some important aspects of the language NBC. First of all, you learned that each program has

one thread named main that is always executed by the robot. Also you learned the four most important motor

commands: OnFwd, OnRev and Off, and about the wait and exit statement. Finally, you learned about how to

use constants to make program-wide changes easier, and comments to explain what your code does.

II. Using variables

Variables form a very important aspect of every programming language. Variables are memory locations in

which we can store a value. We can use that value at different places and we can change it. Let me describe the

use of variables using an example.

Moving in different ways

Assume we want to adapt the above program in such a way that the robot doesn’t return as fast as it went

forward. This can be achieved by making the speed value smaller for the return journey. But how can we do

this? SPEED is a constant and constants cannot be changed. We need a variable instead. Variables can easily be

defined in NBC. Here is a new program.

#define MOVE_TIME 4000 #define SPEED 100 #define DECREMENT 25

dseg segment Speed byte dseg ends

thread main set Speed SPEED OnFwd(OUT_BC, Speed) wait MOVE_TIME sub Speed, Speed, DECREMENT OnRev(OUT_BC, Speed) wait MOVE_TIME Off(OUT_BC) exit endt

We have introduced the variable Speed into the program. Every variable in your program must be declared in a

data segment. You can have as many data segments as you want, and they can be pretty much anywhere in your

program. All variables in NBC have global scope – they are accessible from any code in any thread.

Data segments start with the segment statement, and end with the ends statement. Each segment must be

named, the name on the segment and ends statements must match.

So let's explain the new statements in this program.

dseg segment

This statement specifies the start of a data segment called “dseg”. In our program, it is the only data segment and

contains only a single variable.

Speed byte

This statement declares the variable “Speed” as type “byte”. Variable names must start with a letter but can

contain digits and the underscore sign. No other symbols are allowed. (The same applied to constants, thread

names, etc.)

dseg ends

This statement specifies the end of the “dseg” data segment.

set Speed, SPEED

This statement assigns the value of SPEED (the constant defined earlier) to the variable Speed. Note that this can

also be done in the declaration of the variable, by adding the initial value after the variable type, eg: Speed

byte SPEED.

sub Speed, Speed, DECREMENT

This subtracts the value DECREMENT from the value currently stored in the variable Speed, and stores the

result back to that same variable.

Displaying results on the screen

As you can see, if perform these commands, the final value of ccc should be 15. But how do we check it? The

easiest way is to display the result on the NXT screen. This is fairly simple – there is a system call available to

do it. The following program demonstrates it:

dseg segment aaa byte bbb byte ccc byte dseg ends

thread main set aaa, 10 // aaa is now equal to 10 mul bbb, 20, 5 // bbb is now equal to 100 mov ccc, bbb // ccc is now equal to 100 div ccc, ccc, aaa // ccc is now equal to 10 add ccc, ccc, 5 // ccc is now equal to 15

NumOut(10, LCD_LINE7, ccc) wait 2000 // wait so you get to see it!

exit endt

This is fairly self-explanatory, but here is an explanation of the important parts.

NumOut(10, LCD_LINE7, ccc)

This statement converts the value ccc to a string, then calls the system function DrawText to display the string

on the screen. The value of ccc should be displayed near the lower left of the screen.

wait 2000

We’ve seen this before too – it is here simply to pause and allow you to see the result. If it wasn’t here, the

program would exit immediately, and the NXT menu would overwrite the value you just displayed too fast for

you to see it!

Random numbers

In all the above programs we defined exactly what the robot was supposed to do. But things get a lot more

interesting when the robot is going to do things that we don’t know. We want some randomness in the motions.

In NBC you can create random numbers. The following program uses this to pick a random speed when it

reverses.

#define MOVE_TIME 4000 #define SPEED 100 #define DECREMENT 25

dseg segment Speed byte wRandom byte dseg ends

thread main set Speed SPEED OnFwd(OUT_BC, Speed) wait MOVE_TIME Random(wRandom,30) add wRandom, wRandom, 10 sub Speed, Speed, wRandom OnRev(OUT_BC, Speed) wait MOVE_TIME Off(OUT_BC) exit endt

The program is basically the same as the one above, but instead of just subtracting 25 from Speed, it uses a

random number between 10 and 40. Let’s look at how it does this:

Random(wRandom,30)

This statement generates a random integer between 0 and 29 (inclusive), and returns the result in wRandom.

Note that the result will always be less then the value of the 2

nd

parameter.

add wRandom, wRandom, 10

This statement adds 10 to the result, so it will now be between 10 and 39.

sub Speed, Speed, wRandom

This statement subtracts the result from the current value of Speed, ready to change the random speed in the

following OnRev statement.

Summary

In this chapter you learned about the use of variables. Variables are very useful, but they are restricted to only

integer values. But for many robot tasks this is good enough.

You also learned how to display a value on the NXT screen. This technique can be very useful for debugging

more complex programs.

Finally, you learned how to create random numbers, such that you can give the robot unpredictable behavior.

The brcmp and brtst statements

So, we can store the result of a comparison for later using cmp or tst. And we can display it on the screen. But

how can we actually use it to do something? Generally, a robot will want to do something different depending on

the result of the test, and this can be accomplished with brcmp and brtst.

In NBC, all program branch statements require a label. The label is just a string of characters followed by a

colon. A label can be on a line by itself or at the start of a line containing an NBC statement. Let’s have a look

at an example:

dseg segment aaa byte bbb byte wRandom byte dseg ends

thread main set aaa, 10 Random(wRandom,20) mov bbb, wRandom

NumOut(10, 8, bbb)

brcmp GT, Bigger, bbb, aaa TextOut(50, 8, 'small') brcmp LTEQ, Delay, bbb, aaa Bigger: TextOut(50, 8, 'BIG') Delay: wait 2000

exit endt

Again, this is fairly similar to the last program, but instead of using cmp to store the comparison result, we use

brcmp to execute some “conditional” code. Let’s analyse the 2 new statements:

brcmp GT, Bigger, bbb, aaa

This looks very similar to the cmp statement in the last program doesn’t it? In fact it is, and the exact same

comparison is performed, but instead of storing the result, it is used to determine whether or not to skip program

execution to the label “Bigger”, which is defined below. If the comparison is true, the program skips, otherwise

it continues with the next statement, which displays the string “small”.

Bigger:

This is a label, and is the target of the brcmp statement. If the comparison is true, program execution will skip

to the first statement following this label, which displays the string “BIG”.

So the program will display the value of bbb, and either “BIG” or “small” depending whether or not it’s bigger

than aaa.

The brtst statement is, again, similar to brcmp, except that the 4 th^ parameter is assumed to be zero.

The jmp statement

Sometimes you need to do an unconditional branch, that is, skip some code no matter what. This can be

accomplished with the jmp statement. It is very simple; you just specify the label you want to skip to.

One common use of unconditional branches is in an “if-then-else” type of situation. You use brcmp or brtst as

the “if”, jumping to a label to execute the “then” code. If the comparison is false, you execute the “else” code,

immediately below the conditional branch. But at the end of that code, you want to skip over the “then” code,

because you don’t want to execute that if the test is false. So you must add a label after the “then” code, and skip

to it unconditionally at the end of the “else” code. Let’s look at an example:

#define MOVE_TIME 4000 #define SPEED 100 #define DECREMENT 25

dseg segment Speed byte wRandom byte dseg ends

thread main set Speed SPEED OnFwd(OUT_BC, Speed) wait MOVE_TIME sub Speed, Speed, DECREMENT Random(wRandom,2) brtst EQ, Then, wRandom Else: OnRev(OUT_BC, Speed) jmp EndIf Then: OnFwd(OUT_BC, Speed) EndIf: wait MOVE_TIME Off(OUT_BC) exit endt

Here is an example “if-then-else”. In this example, our robot should go forward at full speed for 4 seconds, then

go either forwards or reverse at slower speed for another 4 seconds, depending on a random number. Let’s

analyze it:

brtst EQ, Then, wRandom

This is the conditional branch, or “if” statement. If wRandom is equal to zero, program execution will skip to the

“Then” label.

Else:

This is a label identifying the “Else” clause, that is the code which is executed if the comparison is false. Note

that this label is in fact unnecessary, as no branch statement uses it as a target. It was included to highlight the

similarity to an if-then-else construct, and also to demonstrate that it is OK to put labels in your code which are

not the target of branch statements. So if the test is false, the OnRev statement will be executed, and the robot

will back up.

jmp EndIf

This unconditional branch causes program execution to skip to “Endif”, thus avoiding execution of the “Then”

clause.

Then:

The “Then” label is the target of the brtst statement above, so if the test is true, program execution will skip to

this point, thus missing the “Else” clause, and the robot will continue forwards, due to the OnFwd statement.

EndIf:

The “Endif” label is the target of the unconditional branch at the end of the “Else” clause.

If you run this program a few times, your robot should go forward about half the time and backward about half

the time.

Loops – repeating code

You can make your robot turn by stopping or reversing the direction of one of the two motors. Here is an

example. Type it in, save it, download it to your robot and let it run. It should drive a bit and then make a 90-

degree right turn.

#define MOVE_TIME 800 #define TURN_TIME 200

dseg segment SquareCount byte 4 RepeatCount byte 10 dseg ends

thread main

RepeatLoop: set SquareCount, 4

SquareLoop: OnFwd(OUT_BC,100) wait MOVE_TIME OnRev(OUT_C,100) wait TURN_TIME sub SquareCount, SquareCount, 1 brtst GT, SquareLoop, SquareCount

sub RepeatCount, RepeatCount, 1 brtst GT, RepeatLoop, RepeatCount

Off(OUT_BC) endt

There is now one loop inside the other. We call these “nested” loops. You can nest loops as much as you like.

Notice that each loop is indented – this is not necessary, but helps to make the program easier to read. Note also

that although SquareCount is initialized in the variable declaration, it needs to be reset to 4 before each time

through the SquareLoop. This is necessary because the previous execution of that loop leaves the value at

zero.

Summary

In this chapter you learned about how to compare values in your program and store the result, using the tst and

cmp statements. You learned how to conditionally skip code using labels and the brtst and brcmp statements,

and unconditionally skip code using the jmp statement. Finally, you learned how to use the brtst, brcmp and

jmp statements to write if-then-else clauses and loops.

IV. Sensors

One of the nice aspects of the Lego robots is that you can connect sensors to them and that you can make the

robot react to the sensors. Before I can show how to do this we must change the robot a bit by adding a sensor.

To do this, you will need to follow the instructions in the software that came with your NXT. You need to build

the “bumper” for you tribot, according to those instructions, and your robot should now look like this:

Connect the sensor to input 1 on the NXT.

Waiting for a sensor

Let us start with a very simple program in which the robot drives forwards until it hits something. Here it is:

dseg segment Switch sword 0 dseg ends

thread main SetSensorTouch(IN_1) OnFwd(OUT_BC,100)

CheckSensor: ReadSensor(IN_1,Switch) brtst EQ, CheckSensor, Switch

Off(OUT_BC) endt

Let’s look at the important lines:

SetSensorTouch(IN_1)

This tells the NXT that the sensor connected to the input IN_1 will be a touch sensor.

ReadSensor(IN_1,Switch)

This reads the current value of the sensor, translates it to an appropriate value depending on the sensor type

selected, and returns it in the 2 nd^ parameter. So in our program, Switch will contain either 1 or 0 (true/false) after

this call, depending whether the touch sensor is pressed or not.