CPS4.2
Java for Video Games
Modeling a Unicycle
Introduction
If you are
pedalling at 100 radians per second on a unicycle, how fast will you be
traveling? This project models the gears, axle, pedals, chain,
and wheel of a unicycle to answer this question. The diagram on
the
right is a simplified diagram of how the pedals are connected to the
wheel via axles, gears, and a chain.
As you turn the pedal on the left (labeled wheel), it turns the axle at
the same rotational velocity. That is one turn of the wheel will
cause the axle to turn once. Likewise, the angular velocity of
the axle imparts an equivalent angular velocity of the gear it is
connected to. The two gears in the middle are connected by a
chain. Because the gears may be of different sizes, the angular
velocity of the gears may be different, but since they are connected
via a chain, the rolling velocity of the gears is equivalent.
That is if the big gear on the left causes the chain to travel 2 meter
on the top part of the chain, the bottom part as well must travel 2
meters in the opposite directions. The gear on the right is
connected to the axle on the right and the axle is connected to the
wheel on the right. Therefore, all parts of the diagram are
connected. Rotating any gear or wheel will cause the other gears
and wheels to rotate. Your job in this assignment is to write
classes to model this behavior. The diagram below shows the
classes you'll need to write and the measures you'll need to take into
account.
How To
Step 1
Start a new project called Unicycle. In the unicycle project,
create 6
classes:
- Wheel
- Gear
- Chain
- Axle
- Unicyle
- Driver
The first five are for modeling the unicycle, and the last one is for
testing the first five as you write them. The wheel and pedal
will have the same methods and instance variables, so we'll use the
Wheel class to model the pedal.
Step 2
The following methods need to be written for the Wheel class:
- public void setRadius(double r)
- public double getRadius()
- public void
setAngularVelocity(double v)
- public double getAngularVelocity()
- public void
setRollingVelocity(double v)
- public double getRollingVelocity()
- public void connectToAxle(Axle
axle)
Similar methods need to be written for Gear, Chain, and Axle with a few
exceptions. Chains only have rolling velocity and do not have
angular velocity. Also, chains do not have a radius - they are
assumed long enough to fit around the gears they are connect to.
Axles only have angular velocity and do not have rolling velocity since
they have an idealized zero radius axle. Add all the applicable
stub methods to all the classes. Stub methods are methods which
are not functional, but they do compile. Two complete stub
methods are provided for you below as an example.
- public void setRadius(double r)
{
}
- public double getRadius()
{
return 0;
}
Write all of the relavent stub methods for Wheel, Gear, Chain, and
Axle. Your code should compile, but will not yet run.
Step 3
Now you need to declare the instance variables you'll need for each
class. Do not include any redundant instance variables in your
class. For all angular velocities, the units should be
radians/second. For all radii, the units should be meters.
For all rolling velocities, the measures should be in
meters/second. The instance variables for the Wheel class should
be:
- private double radius;
- private double angularVelocity;
- private Axle axle;
The axle instance variable is going to be used because the wheel will
be attached to an axle. Rotating the wheel will make the axle
rotate at the same angular velocity if it is not already doing
so. Also rotating the axle can also cause the wheel to rotate at
the same angular velocity if it is not already doing so. Notice
that the instance variables do not include a variable for
rolling velocity. This is because rolling velocity can be derived
from the radius and angular velocity:
Identity for converting a single revolution to the radians traversed
1 rotation = 2 * PI radians
dividing each side by 2 * PI
radians yields
1 = 1 / (2 * PI) rotations/radian
Formula for the circumference of a circle
1 rotation = 2 * PI * radius
meters
dividing each side by 1 rotation
yields
1 = 2 * PI * radius
meters/rotation
Starting with aV radians / second,
it is now possible to derive rV
meters/second rolling velocity
aV radians/sec * 1 = aV
radians/sec * 1 / (2 * PI) rotations/radian = aV / (2 * PI)
rotations/sec
aV / (2 * PI) rotations/sec * 1 =
aV / (2 * PI) rotations/sec * 2 * PI * radius meters/rotation = aV *
radius meters/second
Therefore
rV meters/second = aV * radius
meters/second
You can also solve the above equation for aV.
aV radians/second = rV /
radius radians/second
Add the relevant instance variables to the remaining classes. No
class should have both angular velocity and rolling velocity variables.
Step 4
Add the following code to complete the method bodies in the Wheel class:
public void
connectAxle(Axle axle)
{
this.axle=axle;
}
public void
setRadius(double r)
{
radius=r;
}
public double
getRadius()
{
return radius;
}
public
double getAngularVelocity()
{
return angularVelocity;
}
public void
setAngularVelocity(double v)
{
this.angularVelocity=v;
if(axle!=null &&
axle.getAngularVelocity()!=angularVelocity)
axle.setAngularVelocity(angularVelocity);
}
public double getRollingVelocity()
{
return angularVelocity*radius;
}
public void setRollingVelocity(double v)
{
setAngularVelocity(v/radius);
}
public String toString()
{
return "Wheel turning at
"+angularVelocity+
"
radians/second and rolling at "+
getRollingVelocity()+" meters/second";
}
Notice the method setAngularVelocity
does not set the angular velocity of the axle unless an axle is
connected and the axle is not moving at the same angular velocity as
the wheel. It's very important that the wheel not set the angular
velocity of the axle unless it is different. Consider the
following scenario. Every time the wheel is angular velocity is
set, it sets the axle angular velocity. Every time the axle
angular velocity is set, it sets the wheel's angular velocity.
It's fairly easy to see that if every time Axle calls Wheel that Wheel
calls Axle, then the calls would loop infinitely. For this
reason, only set them if they are different.
In the Driver class, add the following code in the main method:
public static
void main(String[] args)
{
Wheel wheel = new Wheel();
wheel.setRadius(0.25);
wheel.setAngularVelocity(6);
System.out.println(wheel);
}
When you run the Driver class, you should get the output:
Wheel turning at
6.0radians/second and rolling at 1.5 meters/second
Step 5
Complete the code for the Axle class by filling in the code in the
method bodies. Test the Axle class individually by adding code to
the Driver class in a similar way as the Wheel class was tested.
Then connect the Wheel and the Axle by calling the connectAxle
method of the
Wheel class. Also be sure to call the connectWheel
method of the Axle class. When connecting Unicycle parts A and B, it is
important to connect both A to B and B to A.
Now set the angular velocity of the Wheel and see if
it sets the angular velocity of the Axle by printing both the Wheel and
Axle to the console using System.out.println.
BE SURE TO CONNECT AND SET THE RADIUS OF ALL PARTS BEFORE SETTING THEM
IN MOTION. Make sure the Wheel and Axle when connected work
properly
before continuing to the next step.
Step 6
Complete the code for the Axle, Wheel, Gear, and Chain. Test them
in the Driver to make sure they work both individually and when
connected to other parts. Hint: add to the Chain class a method
with the following method signature:
public void connectGears(Gear top, Gear bottom)
Step 7
Design and implement the Unicycle class. You'll need to have
methods
for setting and getting the radii of all unicycle parts which have a
radius (Axles and chains do not have radii). You should also have
methods for setting and getting the
pedal angular velocity and getting the rolling velocity of the
wheel. In the Driver class, test the Unicycle class.
Step 8
Post to the class discussion board a set of radii for the sizes of the
gears, pedal, and wheel not the same as any which have been posted and
with no gears or wheels the with the same radii. Give two
coordinate pairs
of (pedal angular velocity, wheel rolling velocity) for different pedal
angular velocities. Compare other results with your results to
make sure they agree. If your results for the same radii and same
angular velocities disagree significantly on the wheel's rolling
velocity for the majority of results posted, then re-examine your
code. If your results are consistent with the majority of the
results posted, then your program is most likely correct.