In this lab, we enter the exciting world of robots by programming a Lego Mindstorm Robot (TM). We will practice moving the robot by making it dance in section II. In sections III and IV we will program a robot that wanders inside a boundary and a robot that bounces off obstacles. The wandering and bouncing robots could form the basis of many useful inventions such as an automatic vacuuming robot or a robot that recycles and collects dishes for washing. First, we will familiarize ourselves with the particular version of C, called NQC, that we will use. Technically, though, it is Not Quite C. Next, we will design and test each of the Robots.
On the top of the device, there is a button labeled 'view'. Press this button to check the value on each block. The block the arrow is pointing to is the block currently being shown on the LCD.
Step 0. If you need a robot or an infrared (IR) tower, ask your TA. (Note: If the robot's batteries need to be changed, make sure they are changed within 60 seconds; otherwise the firmware will need to be reloaded.)
Step 1.
Download the robots
project archive into your home
directory, and then open Eclipse and follow similar steps
as in lab8 in order to import this project into Eclipse, namely:
go to File , Import... , and then select
Existing Projects into Workspace
from General .
Next, make sure the Select archive file radio button is selected.
Then browse for robots.zip.
Click on the Finish button to expand the newly exported project.
You should notice that the project contains several files.
In this lab, you will be editing the files with the ".nqc" extension,
that is, hello.nqc, dance.nqc, wander.nqc and bump.nqc.
(Actually, the file hello.c is already
fully edited for you.)
Let us start with the file hello.nqc -- open it in an eclipse editor (using the already familiar procedure of double-clicking on its name in the navigator view). It contains the following code:
task main() {
OnFwd(OUT_A+OUT_C); /* Starts the motors */
Wait(200); /* Leaves the motors running for 2 seconds. */
Off(OUT_A+OUT_C); /* Stops the motors */
}
Note that task main() is NQC's version of void
main(void). Also notice that NQC does not require include
statements. The black pads marked A, B, and C are controlled by using
the OUT_A, OUT_B, and OUT_C (respectively) built-in constants.
The command Wait halts the code for some number of
hundredths of
a second. In this case, we turned on OUT_A (the left motor) and OUT_C
(the
right motor) for 200 hundredths of a second, which is 2 seconds.
Step 2.
Compile and download your code into the robot as follows: Make sure your robot's IR
receiver
(a black window) faces the IR tower and make sure the robot is powered
on
(Press the red on/off button if necessary). Then, from the Eclipse Run menu,
select External Tools, External Tools..., and then HelloDownload
under Program. Notice that after the first time you run it, the command
HelloDownload becomes available to you immediately after selecting
External Tools from the Run menu.
IMPORTANT: The process of compiling and downloading into the robot
of the code
you shall write in the other .nqc source files, namely
dance.nqc , wander.nqc ,
and bump.nqc , will be perfectly similar to the one for
hello.nqc , by selecting
from Run, External Tools, External Tools... the corresponding
commands, namely danceDownload ,
wanderDownload ,
and bumpDownload respectively, instead of
helloDownload .
Step 3. Run your code: Place the robot in a safe place, be sure it is powered on, and press the run button. The robot should move forward (the front is the side with the motors) for about two tenths of a second.
Step 0.
Open the file called dance.nqc from the same
robots project. Your
file should contain the following:
task main() {
/* Your code goes here. */
}
You will place all your
code inside the curly braces of the task main()
Step 1. Write code to command the robot to do the following (square) dance:
When the robot is done with the dance, it should end at about the same position and orientation as it started.
Note: You may need to adjust timings to get the turns right. This is an example of iterative design. However, do not spend too much time on this task; it is sufficient that the robot does a fun dance.
A left turn is done by setting the right motor to
full forward and the left motor to full reverse, and then waiting about
105 hundredths of a second.
A right turn is the same, except switching the directions of both
motors.
A right loop is done by setting the left motor to
full
forward and the right motor off, and then waiting about 5.25 seconds.
Note: The amount of time needed for a turn varies greatly depending on
the
ground surface material, battery power, and tightness of the robot
parts. You
will need to adjust the times.
To do this dance, you will need to know the following commands:
Where motors is OUT_A for the left motor, OUT_C
for the right motor, or OUT_A+OUT_C for both motors.
Write, compile, and test your code until it works.
Step 2. After you've completed your program, show it to your TA and get his/her signature for question #1 on the Answer Sheet.
You will be creating a robot that stays within the boundary of a solid black line. To do so, you will have the robot turn almost 180 degrees whenever it crosses a black line. First, the robot must determine how bright white is. Next you will start the motors and wait until the black line is crossed. When the black line is crossed, the robot will turn for two seconds in a random direction. Finally, the robot will resume forward movement and wait for another turn.
Step 0. If the light sensor is not already attached, attach the light sensor to the front of the robot, and connect the wire to the gray pad marked 3. Get the sensor from your TA or help from the TA if needed.
Step 1.
Open in an Eclipse editor the file called
wander.nqc from the robots project.
Read the contents
of the file carefully. You should find:
The main task is the robot's manager. It is responsible for calling subroutines to get started, and it detects events and delegates them to the appropriate event handlers. In this case, we only have one event: Crossing onto a black line. The main task keeps track of the current location (onWhite or not). When the robot leaves white and enters a black area, the main task detects this and starts the turn event. When it is done turning, it starts going forward again.
Notice the structure of the main task. It starts by initializing the robot and getting started. Then, it specifies that it is on white paper, and then it loops infinitely. What would happen if there was no loop? Within the loop, the robot checks to see whether it has changed colors. There are two cases: 1) The robot was on white but now is on dark, and 2) the robot was on dark and is now on light. Either way, the value of OnWhite must be updated to reflect the new location. If the robot crossed from light to dark, it must turn. Now it's time for you to do some coding:
Step 2. Fill in the init subroutine. Add the following line:
SetSensor(SENSOR_3, SENSOR_LIGHT);
to the init subroutine to enable the sensor.
Next you must set the threshold that determines the difference between white and black. The robot starts on white paper, so SENSOR_3 currently corresponds to white light. Set the threshold to about 7/8 of SENSOR_3. Be aware that all the values in NQC are integers -- there are no float values in this language. Remember integer division truncates, so be careful not to get 0 * SENSOR_3.
Step 3. Fill in the go subroutine.
This subroutine just starts the motors.
Step 4. Fill in the turn subroutine.
Start by picking a direction at random. Try:
int dir = Random(1);This generates a random integer, either 0 or 1. Next, use an
if/else statement to check whether dir is 0
or 1
(remember to use the == operator.) If 0, turn left for
two
seconds, and otherwise (if dir is 1), turn right for two seconds. After
turning, resume forward motion.
Step 5. Compile and test your program.
Make sure you start the robot with its sensor above white paper.
When the robot behaves correctly, get a signature from your TA to Answer question #2 on the Answer sheet..
Note: The robot does not have to be perfect; if it escapes a bit that is acceptable.
Get and attach a bump (touch) sensor to the front of the robot and
connect it to sensor port 1. You need to open and edit the file
bump.nqc and add the main task.
Use the SetSensor(SENSOR_1, SENSOR_TOUCH);
command to set up the sensor.
Write code to keep the robot moving forward until it bumps. When it
bumps (when the sensor reading is not 0), it should back up for 0.2
seconds, and then turn a random direction and random amount. (Use Random(100)
for the amount of time to turn.)
Test and run your code, and get a signature to Answer question #3 on the Answer sheet.