433 lines
18 KiB
Plaintext
433 lines
18 KiB
Plaintext
|
|
"C" LANGUAGE EMULATION OF AN AUTOMAG PAINTBALL GUN
|
|
version 1.0
|
|
|
|
1 Introduction
|
|
|
|
This program calculates the behavior of an automag paintball gun using
|
|
a simple model of the gun. Please see the automag manual for an
|
|
explanation of the terminology. If the program is run as is, it will
|
|
emulate a 0.2 second wait while the gun charges up to about 450 psi, then
|
|
the trigger is pulled and a ball is ejected at about 290 fps. In order to
|
|
set up other scenarios, the timing loop in main() and the trigger
|
|
subroutine UpDate_t() must be modified by the user.
|
|
|
|
2 Explanation of the Program
|
|
|
|
At any point in time, the gun is considered to be completely described
|
|
by specifying a set of pressures, volumes, surface areas, positions and
|
|
velocities of certain key elements of the gun. In the computer program,
|
|
the subroutine tstep() takes the set of variables describing the state of
|
|
the gun, along with the time (t) and a time step (dt), and calculates the
|
|
new values for these variables at time t+dt. This "marching algorithm" is
|
|
accurate as long as the time step dt is small enough but if dt is too
|
|
small, it can take a long time for the program to calculate out to a
|
|
reasonable amount of time. A good value for dt seems to be about 1
|
|
millisecond. A check on whether a small enough time step is being used
|
|
is to cut the time step by a factor of 3 and see if the results are the
|
|
same. If the time step is increased by a factor of 3 and the results
|
|
are about the same, a larger time step can be used.
|
|
|
|
There are two types of subroutines used by tstep(); flow rate
|
|
subroutines starting with "Q" and moving part update subroutines starting
|
|
with "U".
|
|
|
|
2.1 Flow rate subroutines
|
|
|
|
There are 4 volumes or chambers in the gun: "s" signifies the source
|
|
(e.g. a CO2 bottle), "r" is the regulator chamber, "a" is the air
|
|
chamber, and "b" is the barrel. Thus, for example, PV.Pr is the regulator
|
|
chamber pressure and PV.Vr is the regulator chamber volume, and Qra() is
|
|
the subroutine that calculates the rate of flow from the regulator
|
|
chamber to the air chamber. The regulator valve connects the source and
|
|
the regulator chamber, the on-off valve connects the regulator chamber
|
|
and air chamber and the bolt-to-power tube o-ring is the "valve" that
|
|
connects the air chamber to the barrel. The flow rate subroutines
|
|
calculate the rate of flow of gas from one chamber to the other according
|
|
the the crude equation:
|
|
|
|
Q12 = d(P2*V2)/dt = -d(P1*V1)/dt = (Cl + Z*x)*(P1-P2) (1)
|
|
|
|
where P1 and V1 are the pressure and volume of the upstream chamber, P2
|
|
and V2 are the pressure and volume of the downstream chamber, Cl is a
|
|
leakage flow rate (in order that bad o-rings may be modelled), Z*x is the
|
|
normal flow rate where x is a measure of how open the valve is and Z is a
|
|
proportionality constant. (If x becomes negative it is assumed the flow
|
|
is stopped). Any pressure at time t+dt is calculated (assuming constant
|
|
volume V) by:
|
|
|
|
P(t+dt) = P(t) + (Qin-Qout)*dt/V (2)
|
|
|
|
where Qin is the rate into the chamber and Qout is the rate out of the
|
|
chamber.
|
|
|
|
2.2 Moving Part Update Subroutines
|
|
|
|
The moving parts of the gun are moved by pressure differentials applied
|
|
to various surfaces, by springs, by friction, or by a finger moving the
|
|
trigger. Generally, the force (F) on a surface of area S due to a
|
|
pressure difference is given by:
|
|
|
|
F = S*(P1-P2) (3)
|
|
|
|
where P1 and P2 are the pressures on either side of the surface. The
|
|
force on an element due to a spring is;
|
|
|
|
F = K*(x-x0) (4)
|
|
|
|
where x is the length of the spring, x0 is its relaxed length, and K is
|
|
the spring constant. The force due to friction is taken to be:
|
|
|
|
F = -R*V (4.5)
|
|
|
|
where V is the velocity of the part and R is a proportionality constant.
|
|
|
|
If a massive part is being moved, the position (x) and velocity (v) of
|
|
the part must be known in order to predict its motion. The acceleration
|
|
of the part is A=F/M where F is the force on the part and M is the mass
|
|
of the part. The position and velocity of the part at time t+dt is
|
|
calculated as:
|
|
|
|
x(t+dt) = x(t) + (v(t) + 0.5*A*dt)*dt (5a)
|
|
v(t+dt) = v(t) + A*dt (5b)
|
|
|
|
2.25 The Source Pressure
|
|
|
|
The pressure of the source (PV.Ps) is assumed to derive from the
|
|
equilibrium vapor pressure over liquid carbon dioxide at temperature PV.T.
|
|
The vapor pressure data was found in the CRC Handbook of Chemistry and
|
|
Physics, 74th edition, copyright 1993. The data is given between
|
|
temperatures of 140 and 300 degrees kelvin. The logarithm of the pressure
|
|
as a function of temperature was fitted with a third order polynomial and
|
|
the source pressure is calculated using the four co-efficients of this
|
|
polynomial.
|
|
|
|
2.3 The Regulator
|
|
|
|
It is assumed that a gas source at pressure PV.Ps is applied to
|
|
the input. The regulator is diagrammed schematically below:
|
|
|
|
|
|
|----------------
|
|
| -> to on-off valve
|
|
| |-|
|
|
---------------|- |D|----------
|
|
| | E | | |-| |
|
|
| A |88888| B |---------|C| |
|
|
| | | | |-| |
|
|
---------------|- |D| |
|
|
|---|-|--| |-|
|
|
| |
|
|
|
|
|
v
|
|
to source
|
|
|
|
|
|
A Regulator nut
|
|
B Regulator piston
|
|
C Regulator valve
|
|
D Regulator seal
|
|
E Regulator spring pack ("888" represents the spring)
|
|
|
|
It is assumed that the left end of the regulator valve is always in
|
|
contact with the regulator piston. (actually the regulator valve spring
|
|
contacts the right end of the regulator valve and keeps it pushed against
|
|
the regulator piston) As gas enters from the source, it flows past the
|
|
regulator valve into the part of the regulator chamber holding the
|
|
regulator piston. The pressure forces the piston to the left, and the
|
|
regulator valve moves with it. This process continues until the regulator
|
|
valve head comes in contact with the regulator seal and stops the flow.
|
|
Equation (1) is used to calculate the rate of flow of gas past the
|
|
regulator valve, with:
|
|
|
|
Qsr = (Zr.Cl + Zr.Z*Zr.x)*(PV.Ps-PV.Pr) (6)
|
|
|
|
Zr.x distance from the bottom of the regulator valve
|
|
head to the top of the regulator seal.
|
|
PV.Ps source pressure
|
|
PV.Pr regulator chamber pressure
|
|
Zr.Z flow rate/length for the regulator valve
|
|
Zr.Cl leakage rate for the regulator valve
|
|
|
|
The position of the regulator valve is determined by the position of
|
|
the regulator piston. The regulator piston is pushed to the left by the
|
|
regulator spring and pushed to the right by the higher pressure in the
|
|
regulator chamber. The regulator piston can only move so far to the right
|
|
before it runs into a stop. The force of the regulator spring can be
|
|
increased by moving the regulator nut to the right, compressing the
|
|
spring. Lets say Zr.x0 is the value of Zr.x when the regulator piston is
|
|
against the stop and Zr.T/Zr.H is the distance the regulator nut
|
|
compresses the spring beyond its relaxed length when the regulator piston
|
|
is against the stop. Zr.T is the number of turns of the regulator nut
|
|
(clockwise) and Zr.H is the number of turns per inch of the regulator
|
|
nut. The position of the regulator piston is found by assuming that the
|
|
spring force and the pressure force are always equal:
|
|
|
|
Zr.K*(L0 - L) = Zr.S*(PV.Pr-PV.Px) (7)
|
|
|
|
where L0 is the relaxed length of the regulator spring and L is its
|
|
compressed length. When the spring is compressed, it is compressed from
|
|
the left Zr.T/Zr.H inches by the regulator nut and Zr.x0-Zr.x by the
|
|
pressure force. That means
|
|
|
|
L0 = L + Zr.T/Zr.H + Zr.x0 - Zr.x (8)
|
|
|
|
The above two equations can be solved for Zr.x
|
|
|
|
Zr.x = Zr.x0 + Zr.T/Zr.H - (PV.Pr-PV.Px)*Zr.S/Zr.K; (8.5)
|
|
|
|
which is the equation used inUpDate_r();
|
|
|
|
2.4 The On-Off valve
|
|
|
|
A schematic diagram of the on-off valve is given below:
|
|
|
|
------------|
|
|
to regulator <- |
|
|
|----o o----|
|
|
| | -> to air chamber
|
|
|-----|------
|
|
|
|
|
A--------B----------
|
|
Sear
|
|
|
|
Equation (1) is used to calculate the flow through the on-off valve with:
|
|
|
|
Qra = (Zo.Cl + Zo.Z*Zo.x)*(PV.Pr-PV.Pa)
|
|
|
|
Zo.x distance that the top of the regulator pin is below
|
|
the on-off o-ring
|
|
PV.Pr regulator pressure
|
|
PV.Pa air chamber pressure
|
|
Zr.Z flow rate/length for the on-off valve
|
|
Zr.Cl leakage rate for the on-off valve
|
|
|
|
The position of the on-off pin is controlled by the sear which is in turn
|
|
controlled by the trigger. It is assumed that the bottom of the on-off
|
|
pin is connected to the sear but actually the regulator pressure pushes
|
|
it against the sear. If the trigger is released, the sear is tilted at
|
|
zero degrees. As the trigger is pulled, The on-off valve position (Zo.x)
|
|
decreases according to:
|
|
|
|
Zo.x = -Zt.xs*sin(Zo.B-Zo.Bo)
|
|
|
|
where Zt.xs is the length of the sear arm connecting its pivot point
|
|
("B" in the diagram) to the point of contact with the on-off pin ("A"
|
|
in the diagram). Zo.Bo is the angle at which the on-off pin contacts
|
|
the teflon on-off o-ring. This equation is implemented in UpDate_o()
|
|
except it is assumed that the angle Zo.B-Zo.Bo is small enough so that
|
|
sin(Zo.B-Zo.Bo) can be replaced with Zo.B-Zo.Bo itself.
|
|
|
|
2.5 The Power Tube
|
|
|
|
A schematic diagram of the power tube is given below:
|
|
|
|
|
|
----------|-----------|--------------
|
|
O |888888888|
|
|
|---|-----------|
|
|
Air Chamber | bolt | Barrel
|
|
|-------|-------|
|
|
O |
|
|
----------|-----|---------------------
|
|
|
|
|
| |
|
|
|
|
|
---------o----------|
|
|
Sear
|
|
|
|
Equation (1) is used to calculate the flow through the power tube valve:
|
|
|
|
Qab = (Zp.Cl + Zp.Z*Zp.x)*(PV.Pa-PV.Pb) (9)
|
|
|
|
Zp.x distance that the bolt is to the right of the power tube
|
|
o-ring ("O" on the diagram)
|
|
PV.Pa air chamber pressure
|
|
PV.Pb barrel pressure
|
|
Zr.Z flow rate/length past the power tube o-ring
|
|
Zr.Cl leakage rate past the power tube o-ring
|
|
|
|
The position of the bolt is controlled by the pressure difference between
|
|
the air chamber and the barrel, the power tube spring ("888" in the
|
|
diagram), and the sear. If the bolt moves Zp.xc inches to the left of the
|
|
power tube o-ring, it is latched by the sear, as long as the sear is at
|
|
an angle of Zt.Bl or greater. If the bolt at the latch point, it is
|
|
stopped from moving left. If the bolt moves to the right by Zp.xm inches,
|
|
it strikes a stop in the main body and is stopped from moving right.
|
|
anywhere between these two points, equations (3) and (4) give
|
|
the force on the bolt except that if the bolt is in contact with the
|
|
power tube o-ring, it is assumed that there is an additional frictional
|
|
force on the bold according to equation (4.5) and equations 5a and 5b
|
|
then determine the motion. This is implemented in subroutine UpDate_p().
|
|
|
|
2.6 The Ball and Barrel
|
|
|
|
The ball is pushed down the barrel by the difference in pressure between
|
|
the barrel and the atmosphere. A complication here is that the barrel
|
|
volume (the volume of the barrel between the bolt and the ball) is
|
|
changing as the ball moves down the barrel. The barrel volume (Vb) is
|
|
given by:
|
|
|
|
Vb = 0.25*pi*Zb.D*Zb.D*(Zb.x+0.1) (10)
|
|
|
|
where Vb(t) is calculated before Zb.x is updated and Vb(t+dt) is
|
|
calculated after Zb.x is updated. The rate equation is then:
|
|
|
|
P(t+dt)Vb(t+dt) = PV.Pb*Vb(t) + (Qab-Qbx)*dt (11)
|
|
|
|
which can be solved for PV.Pb(t+dt). Equations 3, 5a, and 5b are then
|
|
used to update the position of the ball. If the ball moves beyond the end
|
|
of the barrel, the barrel pressure is atmospheric.
|
|
|
|
I tried worrying about whether the ball was in contact with the foamie
|
|
and being pushed by the bolt or whether it was being pushed by barrel
|
|
pressure, but it seemed like it was always being pushed by barrel
|
|
pressure, so I didn't bother with including this in the model, even
|
|
though it needs to be included. Also, it shouldn't be too hard to model
|
|
a vented barrel to determine how much more gas efficient an undrilled
|
|
barrel is.
|
|
|
|
2.7 Estimation of Constants
|
|
|
|
Most of the geometric values were obtained by direct measurement of the
|
|
gun itself, or were obtained from the automag manual.
|
|
|
|
2.7.1 The Power tube spring constant
|
|
|
|
The spring constant of the power tube spring was estimated by placing
|
|
a 5-pound weight on the spring and noting the deflection.
|
|
|
|
2.7.2 The Regulator Spring Pack Spring Constant
|
|
|
|
The manual says that the gun is nominally charged to 450 psi. Not
|
|
knowing how much the regulator nut compresses the spring pack under
|
|
these conditions, I assumed it didn't compress it at all. That means the
|
|
spring constant for the spring pack is found by solving equation (8.5)
|
|
with Zr.x = 0 and Zr.T=0:
|
|
|
|
Zr.K = Zr.S*(450-PV.x)/Zr.x0 = 1367.5 (12)
|
|
|
|
This value for Zr.K can probably be improved if I can find out how much
|
|
the regulator spring pack is compressed when the gun is charged to 450
|
|
psi.
|
|
|
|
2.7.3 Air chamber volume
|
|
|
|
The manual says that a 7 oz tank of CO2 will provide 400 good shots for
|
|
the gun. There are probably about 6 usable ounces in the tank so that
|
|
70 shots per ounce of CO2 is a reasonable estimate of gas consumption
|
|
per shot. Assuming that the air chamber fill pressure is is 450 psi, and
|
|
the temperature is 70 degrees F, we can solve the ideal gas equation for
|
|
PV.Va:
|
|
|
|
PV.Pa*PV.Va = n*R*PV.T
|
|
|
|
where n = 1/70 oz = 9.2904e-2 mole and R=8.314 J/mole/deg K. This gives
|
|
an air chamber volume of 0.463 in^3
|
|
|
|
2.7.4 The Valve Flow Rates/Length
|
|
|
|
The manual says the gun charges up to 450 psi in about a third of a
|
|
second. The flow rate constant Zr.Z was found by hit-or-miss until the
|
|
air chamber filled up to 95 percent of its steady state value (i.e. 430
|
|
psi) in about 0.33 seconds. The same value of flow rate/length was used
|
|
for both the regulator valve and the on-off valve.
|
|
|
|
2.7.5 Power Tube Flow Rates/Length
|
|
|
|
When the air chamber is filled up to 450 psi, it is assumed that the
|
|
ball will be ejected from an 11 inch barrel at 300 fps. The Power Tube
|
|
Flow Rate/Length was adjusted until this was the case.
|
|
|
|
2.7.6 Power Tube Friction Coefficient
|
|
|
|
If the friction coefficient is set to zero, in the "lawn sprinkler"
|
|
scenario the bolt motion is dominated by the resonant frequency of
|
|
the bolt and its spring. If the coefficient is much greater than 3.0
|
|
all evidence of this natural frequency is lost. I chose a value of
|
|
1.0 only because its interesting. The bolt motion has about equal
|
|
components of 5 and 10 cycles per second. Some thinking has to be
|
|
done to get the value of this constant correct.
|
|
|
|
3. Scenarios
|
|
|
|
A print statement is in the main() program which outputs a number of
|
|
variables. A few different scenarios are given by the following
|
|
modifications to the program along with a description of the expected
|
|
printed output
|
|
|
|
3.1 Simple Shot - run program as is. The regulator chamber should
|
|
charge to 449.54 psi and the air chamber should charge to 449.02 psi at
|
|
0.005 seconds, then the trigger should go on and a ball should be ejected
|
|
at 296.69 fps.
|
|
|
|
3.2 fast stroke: The regulator and air chambers are pre-charged to
|
|
about 450 psi and the trigger subroutine turns the trigger on to
|
|
begin with. The first ball comes out at 296.67 fps. The trigger
|
|
subroutine waits until the air chamber is emptied, then turns the trigger
|
|
off (0.0176 sec). 0.2 seconds later at 0.2176 sec, the second ball comes
|
|
out at 263.92 fps, becuase the air chamber could not fully charge in
|
|
0.2 seconds.
|
|
|
|
Zt.B = Zt.Bb; /* Trigger pulled */
|
|
PV.Pr = 449.; /* regulator chamber charged */
|
|
PV.Pa = 449.; /* regulator chamber charged */
|
|
dt = .0002;
|
|
n = 1150;
|
|
|
|
----- Insert into UpDate_t() -----
|
|
|
|
static double delt;
|
|
double cycle;
|
|
|
|
cycle = 0.2; /* time trigger is off (sec) */
|
|
|
|
if(Zt.B >= Zt.Bb)
|
|
{
|
|
if((Zb.x >= Zb.L) && (PV.Pa <= 1.005*PV.Px))
|
|
{
|
|
Zt.B = 0.0; /* trigger off */
|
|
Zp.x = -0.1; /* bolt latched */
|
|
Zp.v = 0.0;
|
|
Zb.x = 0.0; /* ball loaded */
|
|
Zb.v = 0.0; /* ball motionless */
|
|
delt = t; /* reset timer */
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if(t-delt >= cycle)Zt.B = Zt.Bb; /* Trigger on */
|
|
}
|
|
|
|
ret: return(0);
|
|
|
|
----------------------------------
|
|
|
|
3.3 Lawn sprinkler. A leakage in the on-off valve is put in, and no
|
|
ball is loaded (This is done by putting the position of the ball
|
|
Zb.x outside the barrel, i.e. Zb.x >= Zb.L) The trigger is always
|
|
on, and the regulator and air chamber pressures are set roughly
|
|
to a steady state value. (They needn't be).
|
|
|
|
Zb.x = Zb.L; /* no ball */
|
|
Zt.B = Zt.Bb; /* trigger down */
|
|
Zp.X = 0; /* bolt at zero */
|
|
Zo.C = 0.01 /* on-off leak */
|
|
PV.Pr = 450; /* steady state */
|
|
PV.Pa = 34.7; /* steady state */
|
|
n = 3000;
|
|
dt = .0002;
|
|
|
|
----- Insert into UpDate_t() -----
|
|
{
|
|
Zt.B=Zt.Bb
|
|
return(0);
|
|
}
|
|
----------------------------------
|
|
|
|
3.4 Cold Gun - Low temperatures lower the vapor pressure of the CO2 which
|
|
results in slow charging of the gun and possibly incomplete charging.
|
|
Set the temperature PV.T to 30 degrees F. and run the short stroke
|
|
scenario. The second ball will come out at 239.00 fps, which is even less
|
|
than before, this being due to the lower source gas pressure.
|