Rochester Institute of Technology – Department of Computer Engineering
Senior Project II
CycleSim - Bicycle Simulator
Demo Date: 02/08/2005
Table of Contents
I. General Description 2
II. User Interface 2
a. Environment Window 3
b. Keyboard 3
c. Joystick 4
d. Exercise Bike 4
III. Environment Software 4
IV. Bicycle Sensor Operation 5
V. Microcontroller Software 7
VI. Testing Philosophy 8
a. Environment Tests 8
b. Bike Tests 10
VII. Project Cost 11
VIII. System Requirements 11
IX. Equipment Used 12
X. Project Goals Assessment 12
XI. Difficulties Encountered 13
User Interface Instructions
C++ Code Files
Assembly Code Listing File
Hard Copy of Design Review Presentation
Hard Copy of Project Poster
Progress Reports 1 to 7
I. General Description
CycleSim is a system that allows the user to take virtual bike rides though a park
environment created in OpenGL. The system uses a modified “Mini Cycle” as the input
device for forward movement. A magnetic sensor is attached to the bike to detect the
speed the user is pedaling. This sensor is read by an HCS12 microcontroller, which
calculates the RPM from the sensor readings and sends it to the PC software.
The speed at which the user pedals determines how fast the environment will move by.
There are obstacles in the environment for the user to interact with. To avoid these
obstacles the user can turn and backup using the keyboard or joystick.
II. User Interface
The user interface consists of 4 components: a computer monitor, keyboard, joystick and
bike. The monitor displays the park environment for the user to navigate through as
shown in figure 1.
Fig. 1 - Sample Environment Screen
In the title bar of the environment window the user can see the current speed of the
animation in frames per second, the speed, in RPM, that the user is currently pedaling and
the corresponding speed of travel in feet per second. The keyboard and joystick provide
the user with the ability to turn and backup through the environment. All of the functions
of the keyboard and joystick will be elaborated on later in the report. The bike provides
the user with forward movement through the environment.
A. Environment Window
The window shows the environment that the user is pedaling through. The user can travel
anywhere inside of the brick walls. There are multiple objects inside of the environment
that the user can interact with. If an object is in the users path while traveling forward or
backward the user will stop moving in that direction when they hit it just as in real life.
The user is not allowed to travel through the object but can use the keyboard or joystick
to turn away from the object so that movement will not be impeded by the object and
then proceed around it. The program window acts just as any other window in the
Microsoft Windows environment does. The environment window’s initial window size is
set to 640X480 pixels. The user has the ability to resize the window by either clicking on
the Maximize/ Minimize/ Restore buttons in the top of the title bar. Also the user can also
drag the window border to whatever size the user desires. To close the program, the user
can click on the close button in the far right of the title bar and the program will exit and
destroy the window. Clicking on the icon in the left corner brings down a menu which
allows the user to resize or close the program as well. As stated before the user is given 3
status numbers in the title bar. The first labeled “Frames Per Second” is the number of
frames that the environment draws per second. Since one requirement for this program is
that the environment must be updated at least 30 times a second this will give the user
conformation of that number. The second number is “RPM” this is the number of
rotations per minute that the user is pedaling the exercise bike. The final number is
labeled “F/S” which is the feet per second that the user is traveling through the
environment. This number is simply based on the RPM and the circumference of a 26”
diameter bicycle wheel.
The keyboard has certain buttons enabled for use by the program while the environment
window is in focus (a.k.a. the active window). The keyboard buffer is small for this
program so if the user holds down more than 2 monitored keys for an extended period of
time the keyboard buffer will overflow and the PC running the environment will beep.
Since the keyboard is only to be used for turning or backing up no more than two keys
are required to be held down at any time. The list of keys that are monitored and their
functions are as follows:
Left Arrow - Allows for the user to turn left through the environment. Is always
functional and works even when the user has hit an object.
Right Arrow - Allows for the user to turn right through the environment. Is
always functional and works even when the user has hit an object.
Down Arrow - Allows for the user to move backward slowly through the
environment. This key will not have an effect on the user’s position if the user is
trying to back through an object in the environment. The key is disabled if the
user is still pedaling the bike (RPM not equal 0).
Esc key – Allows for the user to exit the program the same as clicking on the
close window button.
The Joystick’s function is similar to that of the keyboard in that it will control reverse
movement and turning in the environment. To turn, simply push the joystick in the
direction in which you wish to go. To back up, pull back on the joystick. Backing up is
disabled if the user is moving forward. The Joystick and the keyboard inputs are
complementary so if the user is trying to turn with the keyboard and the Joystick the
turning rate will be the sum of the two inputs. If no joystick is attached to the computer
the program will allow the user to continue with keyboard input only. Sometimes the
system will not be able to find a joystick even when one is attached when this happens
the user must close and restart the program if she wishes to use a joystick since joystick
acquisition is only done during initialization.
D. Exercise Bike
The final piece of the user interface is the exercise bike. The bike controls the forward
movement through the environment. The faster the user pedals the bike the faster the
user will move through the environment. Again if the user collides with something in the
environment the movement through the environment should stop until the user turns
away from the obstacle or stops pedaling and backs up. If the user does not stop pedaling
the RPM and F/S number at the top of the screen will still reflect the fact that the user is
pedaling the bike, however the user will not be moving through the environment and will
not be able to back up due to the fact that RPM is a non zero number. If the bike is not
connected to the system, or if the system for some reason can’t find the bike when the
program is initialized an error message will pop up. If this is the case the program must
be restarted because the user has no way to move forward through the environment
without the bike.
III. Environment Software
The environment program was created in OpenGL using C++. This part of the system has
the responsibly for drawing the environment, monitoring the joystick and keyboard for
input, and spawning the thread to monitor the bike for input. An overview of the
program functionality can be seen below in figure 2. The main program begins by
initializing DirectX and a few other variables that are used in the program. Then the
program creates the environment window and spawns a thread to initialize the joystick
and anther to initialize the serial port for the bike. Once the joystick has been found the
thread that initialized it ends and the main program thread takes control of the joystick,
while the thread that initialized the serial port continues in an infinite loop to read input
from the port and create an RPM number to be used by the program. The main program
then initializes the camera and enters into the execution loop. The execution loop begins
by drawing the first frame of the environment. After the frame has been draw the loop
will read the keyboard and joystick to see if there are any inputs that have to be serviced
on those devices. The camera position is updated depending on which key has been
pressed or which way the joystick has been turned. Then the program grabs the RPM
value that the other thread has been updating and uses that to update the cameras position.
The system will check to see if the user has issued an exit command to the system. If the
user has the program terminates, otherwise execution loops back and the updated camera
position is used to draw the next frame.
Fig. 2 - Environment Flow Chart
IV. Bicycle Sensor Operation
A magnetically triggered switch is used within the bicycle to measure the speed that it is
being pedaled. Three magnets were attached using epoxy to the bicycle’s internal wheel
at evenly spaced intervals. The magnetic sensor is placed so that the magnets will pass
beneath it as the bicycle is pedaled. The bicycle had a magnet embedded within the wheel
from the factory which could not be removed. We attempted to cover this magnet with
one of our more powerful magnets but our placement was a little off. The result of this is
that there are actually 4 magnets on the wheel that the sensor can see. The three are
evenly spaced, but the fourth embedded magnet is right next to one of the other three.
Because of this the sensor does not output a regularly spaced set of pulses, but the
software was able to compensate for this so that it is nearly unnoticeable.
A diagram of the sensor and its connection to the microprocessor is shown below in fig.
3. The 5v source is taken directly from the microprocessors board’s voltage regulator.
The LED lights when a magnet passes in front of the magnetic reed switch and a logic
HIGH is presented to port T1 on the HC12.
Fig. 3 – Sensor Circuit
One of the magnets as well as the wire going to the sensor are visible in Fig. 4. You can
also see the resistance wheel with the nylon webbing wrapped around it.
Fig. 4 – Sensor Placement and Bicycle internals
V. Microcontroller Software
The microprocessor counts the number of times the magnets in the bike pass in front of
the sensor. The count is sent on the serial port to the PC every 50 ms and then reset to
zero. A chart showing the operation of the microcontroller code is shown in below in
Fig. 5 - Microcontroller Software Flow Chart
The microcontroller’s code is programmed into the EEPROM on the microcontroller
board. Figure 6 shows the usage of the microcontrollers memory space.
$0000 -> $03FF Registers
$0400 -> $0491 Program Code – in EEPROM
$0492 -> $1000 Unused EEPROM
$1003 for Sensor Count
$1004 -> $16FF Unused RAM
$1700 for flags (debugging)
$1701 -> $3C00 for stack (stack pointer initialized to $3C00)
$3E64 Timer5 interrupt vector
$3E6C Timer1 interrupt vector
$4000 -> $7FFF Unused FLASH
Fig. 6 – Microcontroller Memory Utilization
The PC listens to the serial port and reads the sensor count that the microcontroller sends.
The data is sent as a single character which the PC can interpret as an integer. The PC
maintains an array of 13 received values and an index counter. Every time a new value is
received it is placed into the array at the location given by the index counter, which is
then incremented. The sum of all the values in the array is then calculated and is used as
the RPM input to the main program. When the index counter reaches 12, the last position
in the array, it is reset to zero rather than incremented. This method has the effect of
averaging out the values received from the microprocessor, creating smoother motion
within the CycleSim environment. The smoother motion adds a sense of momentum to
the bike. The bicycle’s velocity gradually increases or decreases when the user begins or
VI. Testing Philosophy
The testing of the system was broken into two parts the graphical interface and the bike
and its communication with the computer. Each of these parts of the project were
developed and tested separately. When both the bike and the environment were ready the
two pieces of the project were connected and tested together.
A. Environment Tests
The first test that was done on the environment was the camera. To develop the camera it
was necisarry to make the control of the forward movement isolated from turning so that
the joystick and keyboard controls would work correctly. To test this two parallel planes
and a sphere at the each end were drawn in OpenGL. The test allowed for the tester to
press a key to move forward through the environment and stay between the two planes.
When the user has moved the camera into the middle of the sphere the user should make
a 180 degree turn using another button. If the system will allow the user to turn while
staying within the sphere then the camera was properly setup.
The second test was a test of the collision detection protocol. A boundary around an
object was first defined then an attempt was made to move through it from every possible
angle. Once good algorithms were found for different types of collisions then the speed
was turned up to see where the smallest objects in the environment would fail at collision
detection. This was done for the sign with a radius of 0.15 GL units and the fence with
0.3 GL units. The test yielded the results shown below in Fig. 7. Again the detection
algorithm was tested by trying to move through an object and if the environment allowed
the user to move through an object even once then than collision detection algorithm has
failed. Once this was completed the amount of forward movement caused by the bike
input was set to prevent the movement in the environment from exceeding the speed at
which collision detection functioned. Pedaling at 100 RPM was set to give about 0.114 of
forward motion per frame. The user would have to pedal at about 400 RPM for collision
detection to fail.
Speed (gl units) collision(min boundary
Per Frame radius) box collision detection
0.1 Pass Pass Pass
0.2 Pass Pass Pass
0.3 Pass Pass Pass
0.4 Pass Pass Pass
0.5 Failed Pass Pass
0.6 Failed Failed Pass
Fig. 7 - Collision Detection Test
The next test was to get a rough estimate of how many objects the environment could
support while still maintaining a frame rate greater than 30 fps. To do this one of the
objects was placed in a nested loop so multiple copies of the object could be drawn in
different areas. Only objects that were used frequently in the environment were tested.
The numbers in fig. 8 below show an estimate of how many object can be drawn before
the frame rate drops below 30 frames per second.
Object Model Number Drawn
Park Bench 1600
Picnic Table 3200
Picnic Bench 3200
Fig. 8 - Object Model Test
After the environment had been tested the final frame rate and the amount of time needed
to traverse the environment was determined for multiple display resolutions. The time to
traverse the environment is partially determined by the frame rate at which the
environment is drawn so it is desirable to maintain a steady frame rate. A sleep command
was added to the program’s main loop to slow the program’s rendering to more moderate
frame rates. This kept the speed of travel in the environment at an appropriate rate so that
the required 60 seconds of travel time between environment boundaries could be met.
Figure 9 Below shows the results for the frame rate test at different resolutions.
Resolution FPS Before Sleep FPS After Sleep
640X480 375 100
800X600 245 100
1024X768 108 100
1152X864 96 96
1280X1024 68 68
1600X1200 45 45
Fig. 9 - Frame rate at tested resolutions
Finally, Fig. 10 shows the travel time from one wall to the opposite wall moving in a
straight path as well as the time to travel corner to corner diagonally across the
environment. Each of these times were taken with the windows system clock which has
an accuracy of one second. Different sized windows were used to raise or lower the frame
rate for this test.
FPS Wall to Wall Corner to Corner
100 0:58 1:40
96 1:03 1:57
68 1:43 2:37
45 2:24 3:45
Fig. 10 - Time to traverse the environment
B. Bike Tests
Testing of the HCS12 and the serial port communication was done incrementally.
Beginning with a demo program, a test was done where the character ‘A’ would be sent
to the terminal every 100 ms. An interrupt handler was added that would be called
whenever a rising edge was detected on timer 1’s I/O pin. This routine incremented the
character that was being sent. The program was again tested and successfully sent
characters to the terminal that incremented through the alphabet as the I/O pin was cycled
on and off. When the sensor and wiring to the bicycle were ready it was connected to the
I/O pin. Now pedaling the bicycle caused the character sent to the terminal to be
The next test was to see if the PC software could properly receive the characters that the
HC12 was sending. The HCS12 program was loaded and started using MiniIDE as
normal, but then MiniIDE’s terminal to the HCS12 was disconnected and the SerialPort
program was run to connect to the serial port instead. It was able to receive characters
and print them to the screen in a messagebox without problem.
The success of this allowed us to proceed to write the desired functionality for our
bicycle sensor. We wished the HCS12 to send to the PC software the total number of
sensor pulses that had been received every 50 ms. To test the accuracy of the software the
time was recorded when each character arrived at the PC from the HCS12. The characters
were arriving either 47 or 63 ms apart according to the PC’s clock verifying that the
HCS12 had been setup correctly.
The final test was to verify the accuracy of the RPM value that was displayed on the title
bar of the program window. To do this the bicycle was pedaled so that the RPM value
displayed remained as near to a constant 100 RPM as possible. Then the number of pedal
revolutions were counted during a 15 second interval. 24 revolutions were made yielding
a 4% error, however some error was anticipated because the rate of pedaling was only as
even as could be done by a person. This test showed that the RPM value displayed was
VII. Project Costs
The cost of the system is shown in fig. 11 below.
Item Price Cost Provided By
board $110.00 $0.00 RIT
Exercise Bike $100.00 $100.00 Sharper Image
3.5mm Audio Cable, 6’ $4.99 $4.99 Radio Shack
Project Board $1.79 $1.79 Radio Shack
3.5mm Phone Jack $2.99 $2.99 Radio Shack
1 KΩ Resistor $0.20 $0.00 Projects Lab
LED $0.75 $0.00 Phil
Duct Tape $2.99 $2.99 Wegmans
Joystick $30 $0.00 John
Windows PC $800 $0.00 Phil
Magnets $10.52 $10.52 Digikey
Epoxy $4.50 $4.50 Chase-Pitkin
Fig. 11 - Project Cost
VIII. System Requirements
CycleSim requires a certain level of computer hardware in order to run properly, as do
many pieces of software. There were unfortunately not enough systems available to fully
determine the minimum requirements, however the following are known minimum
Window 2000 or Later OS
DirectX 8 or Later
1 RS-232 Serial port
Game or USB port
Furthermore the following items are recommended:
P4 1600 MHz or equivalent
512 MB of RAM
Video Card with 128 MB of RAM
IX. Equipment Used
There were many software packages used to create the CycleSim project. To create and
compile the code for the OpenGL environment Visual C++ 2003 was used. This was
acquired with RIT’s Academic software alliance with Microsoft. The HC12 code was
developed with the use of MiniIDE which is available free from Mgtek www.mgtek.com.
For creation of the textures multiple software packages were used. Each package is freely
downloadable at the web address given. The packages are: Paint included with Windows,
Gimp www.gimp.org/ , Wood Workshop www.spiralgraphics.biz/ww_overview.htm and Bryce
4 trial version www.softlookup.com/download.asp.
The following sources were referenced while writing the code.
nehe.gamedev.net/ -- Non-GLUT windowing scheme
msdn.microsoft.com/ -- Joystick driver
--Serial Port communications
X. Project Goals Assessment
Our project goals as stated in the project proposal:
“The bicycle simulator should be able to track a user pedaling 100 rpm and be
able to update the screen to show movement that fast. The virtual environment is
to have 40 objects (not 40 object models) inside of it each of these object should
have less than 1000 vertices apiece. The screen should refresh at 30 frames per
second or greater to allow for smooth animation. The user should not be allowed
to pedal through objects. Finally the user should not be able to leave the virtual
environment, a.k.a. pedal past where the ground has been defined. … The
environment should be big enough to allow the user to pedal at top speed for at
least 60 seconds”
As can be seen when running our environment on a system that meets the
system requirement we more than meet the 30 frames per second needed
for smooth animation of our environment. Our system is able to handle
more than 100 RPM with no trouble. At final count there are 456 objects
in the final environment over 11 times what the proposed specification
called for. Finally our environment allows for the user to pedal for more
than 60 seconds in one direction before hitting the environment boundary.
Thorough testing of the environment has shown that the user is neither
able to move to a position outside of the environment walls nor pass
through any object. Therefore all of the project performance specs have
been met as stated in our proposal.
XI. Difficulties Encountered
Although this project achieved the objectives created in the proposal there were a few
problems that troubled us along the way. The biggest of these problems was that on
certain computers parts of the environment would not render correctly.
Fig. 12 - Environment with rendering problems
As shown in fig. 12 above a stripe effect on the fence and Pavilion has been seen on
computers with rendering problems. Multiple attempts were made to try and fix this
problem such as changing the way we drew objects, changing the windowing scheme,
and adjusting video card drivers. Some of the changes reduced the size of the stripes and
objects would show this effect at further distances, but the problem was still encountered.
It is still unclear what is causing this problem. A second difficulty was that our textures
are only in RGB format, which will not allow us to properly blend objects with the
background correctly to give the effect of semi-transparent objects, such as nets. An
alternate approach would have been to create texture with an editor that has RGBA and
write a file parser to import those files into OpenGL. Another problem that arose was the
GLUT driver for the joystick did not poll at a regular interval, so we replaced it with a
DirectX driver. Also with so many objects in the environment, it would have been nice
to have more object models, so the same object would not be repeated as much. However
due to time constraints it was impossible for the group to create any more interesting
objects for the environment. Finally, when researching what was required to use DirectX
to control the joystick some more research was done on the DirectX graphical interfaces.
It was found that DirectX has a multitude of plug-ins for current model design packages
such as Maya and 3DStudioMax, which would have allowed for direct importation of
model files without file parsing. This would have made it faster and easier to create more
complex models for our environment. There are also many more visual effects that are
included in DirectX that the developer must otherwise implement on their own when