Learning to Program with Virtual Blocks
v1.0, August 2006
Aim: Introduce students to the fundamentals of C/C++ computer programming by enabling them to create and manipulate simulated, yet physically-realistic objects. Topics covered include variables, subroutines, loops and conditional statements.
Introduction: As children, we learned about the physical world around us by playing with objects: letting go of a playing block in mid-air will cause it to fall to the floor. In a similar way, this teaching package has been developed to allow students to learn how to program computers using physical objects that they create and manipulate through programming.
Step 1: Installation (Currently only offered for Windows systems)
· Download the Open Dynamics Engine (ODE) from http://sourceforge.net/projects/opende. Make sure to get ode-src-0.6.zip (about halfway down the page) and unzip it to c:\. This should create a directory called c:\ode-0.6.
· Navigate to c:\ode-0.6\build\vs2005, and double click on ode.sln.
· This will open Visual Studio. Open Dynamics Engine contains the background parts needed before programming can begin. In order to prepare ODE for you to program, you first need to compile ODE for your system. To do this, press F7. Compilation will take about a minute. Once completed, exit Visual Studio. For more information about ODE, refer to the documentation at www.ode.org. This compilation also builds a suite of sample programs that you can experiment with; they can be found in c:\ode-0.6\lib\debugDLL. Try clicking on some of the .exe files in this directory.
· Download Blocks_1.zip by navigating to www.cs.uvm.edu/~jbongard/Blocks_1/Blocks_1.zip. Unzip this file to wherever you like.
· In the Blocks_1 directory, double click on Blocks_1.sln. This will again open Visual Studio, and allow you to begin creating virtual environments like the one shown above.
Step 2: Compiling and Executing the Program
· In Visual Studio, press F7 to compile the Blocks computer program. This creates an executable file, Blocks_1.exe. You can run this executable directly from Visual Studio by press F5.
· You should see a window similar to the images above. What you are seeing is a virtual world, complete with objects. In this first program however, there should only be a single blue block.
· If you click on the window and press x, the program will terminate. You can start it again by pressing F5.
Step 3: Navigating the Virtual Environment
· You control a camera that looks into this world. Move your mouse onto the window, rightclick and hold, and then drag the mouse. This will move the camera around the environment. At any point you can release the mouse button, and the camera will stay fixed at its current position. Now left-click and hold, and drag the mouse. This time, the direction in which the camera is pointing will change. Experiment with manipulating the camera until you are comfortable with navigating in the virtual environment.
Step 4: Starting the Simulation
· Each time you run the program, the virtual environment begins in paused mode. Click on the window, and press CTRL-p to start the simulation. You should see the block drop to the ground. By starting each time in pause mode, this gives the user time to adjust the camera so that they can see the action the physical effect of the objects interacting with their environment when the simulation is started.
Step 5: Browsing the Program
· In C and C++, each computer program has a place where the code begins to execute. This is usually in the main function. In Visual Studio, your main function should look like this:
Figure 1: An example main function for a C program.
· This function is a like a recipe: it gives a series of commands that tell the computer to do something. In cooking, executing a recipe leads to a meal; in computer programming, executing a function leads to the computer performing a series of actions and reporting the results to the user. As you have already seen, executing this function causes a small block to fall to the ground in a virtual world.
· This function is made up of a series of other functions, known as subroutines. The InitializeODE subroutine does all the work of creating a virtual environment for the user. The CreateFirstBlock function places a block in this environment. The routines that are preceded by // are inactive: they are not compiled and executed by the computer. After the environment and the object have been created, the dsSimulationLoop subroutine runs continually until the user presses x. The computer loops through this routine, and at each pass through the loop it draws all the objects in the world, calculates how the objects should move, and moves them a little. For more detail about what is This is something like the frames in a movie. Each one is still, but running one after the other gives the impression of movement. However, note that you are not watching an animation; you can interact with this program at any time by moving the camera around. This simulation is live action.
Step 6: Modifying the program -- Variables
· View the text in the CreateFirstBlock subroutine.
Figure 2: The CreateFirstBlock subroutine.
· This function contains a number of variables that store information about the block that is about to be created. For example these variables specify the size of the block, its position in the world, its mass, and its color. The text prefixed by // is again ignored by the computer; it is simply in-code documentation for the user.
· The CreateObject function takes these variable values and creates an object in the world. In this case, a small blue block slightly above the ground.
· Lets now try changing some variable values and observing the effect. Try changing the width, height or length values to a new positive value. Once changed, make sure to save the program using CTRL-s, then re-compiling the program using F7, and then re-running it using F5. Note: if you make the object too large, it may stick into the ground; running the program may now cause unrealistic behavior. If this happens, increase the value of distanceAboveGround until the block again begins above the ground.
Step 6: Modifying the program Loops
· For now, return the variables to their original values. (If you dont remember what they are, refer to Fig. 2.) Now remove the comments (//) from in front of the subroutine CreateMoreBlocks (see Fig. 1). This makes this subroutine live: it will now be compiled and run by the computer. Save the program, compile and execute. You should now see a tower of ten blocks above the original block. If you run the simulation (CTRL-p), a tower of blocks should form. How did this happen?
Figure 3: The CreateMoreBlocks subroutine.
· This subroutine contains a for loop. A for loop iterates a fixed number of times (in this case, the number of times stored in howManyMore, which is 10). Each time through the loop, the computer performs the actions in this loop. In this case, each time through, the computer places a new block slightly higher than the previous one (distanceAboveGround is increased by the height of the block). It also darkens it, so it is easier to tell them apart.
· Try changing the value of 10 that is passed into this subroutine, in main. What happens?
Step 7: Disabling and Enabling Different Parts of the Program
· One large part of programming is disabling and enabling parts of the program, to test the different parts of your code. Do this now, by placing // in front of CreateMoreBlocks, and removing // from CreateTiltedTower. Now, save, re-compile and execute. As can be seen, CreateTiltedTower creates a different kind of tower.
· Comment CreateTiltedTower back out so that the program only creates the original, single block.
Step 8: Modifying a program to achieve a specific effect.
· Uncomment (i.e. remove the //) from the subroutine CreateCatapult. As can be seen, this program creates a catapult: the heavier object catapults the lighter object into the air. Can you change the masses or the starting positions of the two weights such that the smaller weight lands on top of the heavier weight? This requires changing the variable values of each weight, recompiling, executing, seeing the effect, and going back and changing the values. It is very difficult to calculate analytically how to this in one shot.
1. Disable CreateTiltedTower, and enable CreateBridge. This subroutine creates a simple bridge. The bridge is spanned by a ten-unit wide plank. Using the techniques shown above, can you create a set of three planks that are only three units long, but, if placed correctly, span the bridge. Hint: Create additional objects to anchor the spans at the ends of the bridge.
2. Can you create a program that builds a pyramid? Hint: Each level of the pyramid should be a flat block, and each new block should be narrower and less long than the one before, but of the same height.
3. Write a new function, similar to CreateMoreBlocks, that builds a log cabin. Hints: This program should use a loop. In each pass of the loop, two objects, or logs are placed. In the first pair, the logs should be placed lengthwise, to the left and right. In the next pass, the logs should be placed widthwise, forwards and backwards
For More Information
The Open Dynamics Engine website (www.ode.org) contains more information about physical simulation, and other programs that use it. My own research (www.cs.uvm.edu/~jbongard) documents use of this software to investigate artificial intelligence, robotics, and teaching computers to be creative.