by January 2, 2003 0 comments



This is the third article in our Build your Own Robot series. In the first part, we spoke of the hardware circuitry and how it interfaces with the parallel port. In the second part, we talked about the actual circuitry needed to interface a simple toy car to the parallel port, and gave some basic code to test this. The code allowed you to control the car’s movement. This month, we will create a more comprehensive program with a GUI interface to control the car. We have given the previous two articles along with the source code and compiled EXE file on this month’s CD (in the Tutorials section). Since the source code is pretty lengthy, we’ve only explained its overall functioning in this article. The actual source code has been commented for easy understanding.

The code is divided into two parts: the GUI and the controls. For GUI we have used the allegro-graphics library. Die-hard Turbo C++ fans must be wondering why we haven’t used the egavga.bgi variety. Well, for starters allegro graphics library is far better, and is in face a full-fledged game-programming library. It’s open source and cross platform and can be compiled for both Linux and Windows platforms. For compiling on DOS we have also provided the djgpp compiler (including the allegro library) on this month’s CD. 

The GUI
The GUI is also broken into two parts. One is the car represented by a 3D polyhedron with the pointed part representing the front of the car. The second part is the star field (background). The motion of the car is simulated by moving the background in such a way that it seems that the car (polygon) is moving forward or backward. The star field is generated by randomly drawing the stars and then moving (animating) them in a depth-cued manner. By depth-cued we mean that all stars seem to come or go towards a single point at infinity. This is also called the perspective viewpoint representation of an object in three-dimensional space; in this case a single star. By mathematically calculating this point of origin, depending on the desired motion, we can simulate the car’s movement. The allegro library provides built-in functions for doing this. The code snippet for doing this is as follows.

get_translation_matrix(&m, delta.x, delta.y,
delta.z);
apply_matrix(&m, stars[i].x, stars[i].y, stars[i].z, &outs[i].x, &outs[i].y, &outs[i].z);
persp_project(outs[i].x, outs[i].y, outs[i].z, &star_x[i], &star_y[i]);

Here, the get_translation_matrix function computes a matrix (using some trigonometric functions) according to the required change in the position of stars. The resultant matrix is stored into an m variable, which is of type MATRIX, a built-in data structure provided by the allegro graphics library. 

The second function apply_matrix applies this matrix m on the current location of the star to get the new location. Finally, the star is drawn at this new location using the persp_project function. This procedure is repeated for all the stars. Hence the above is put in a for loop with counter as
‘i’. 

This ship is a 3D polyhedron and not a point object, hence individual faces have to be programmed independently and moved accordingly. The co-ordinates of the individual triangles that form the faces of the polyhedron must match so the figure 
appears connected. A modus operandi similar to what we applied to stars is also applied here but is
a little involved.

We will not discuss the actual mathematics here as it is beyond the scope of this article. Those interested can look up the source code and refer to some intermediate text on computer graphics. 

The input is done using library routines that handle the keyboard. There are also some limitations of the GUI; the motion depicted in the GUI is not a copy of the motion of the car in reality, but only a representation. For actual representation, we also need to include the hardware characteristics of the car like turning radius, speed, etc. 

Interface and controls
The most important part of interfacing code is the template of the port, which is the BITS array of int type. In this, the individual elements correspond to the data pins of the parallel port. These elements are updated according to the input (the move function). After that the equivalent decimal value is calculated and finally sent to the parallel port. Currently the pin-motor configuration is hardwired into the code for facilitating better understanding. Further additions to the code may include a module that reads a configuration file that contains the information for pin-motor configuration. The move function takes an integer value from 1 to 6 as a function argument (conveniently used as #define values). This is fed into a switch-case system and the BITS array elements are updated accordingly. Finally, the send_to_port function is called which converts the BITS array (the port template) into an equivalent decimal value and finally sends it to the parallel port. The conversion is done using an inefficient math.h routine [pow (x,y)] because of easier understanding. There are better ways of doing this, and you are free to try them out on your own. 

For compiling the code using dgjpp we have to first build the allegro library using the gnu make command. For further details you can refer to the accompanying
documentation. The code can then be compiled using the following command. 

gpp robo.cpp —o carz —lalleg 

This will show some warnings, which can safely be ignored. A similar approach has to be made if the allegro library is compiled on the Linux platform. While using this code on the Linux platform, the user must make sure that he has the appropriate permissions for accessing the code. 

Ankit Khare

No Comments so far

Jump into a conversation

No Comments Yet!

You can be the one to start a conversation.

<