/* Automag.c version 1.0 08/17/94 This program calculates the behavior of an automag paintball gun using a simple model of the gun. See file "automag.txt" for an explanation of the program. I have no proprietary feelings about this code. If you can improve it, please feel free to do so, offer it to anyone you want, I don't need to be notified or credited, or anything. - Paul Reiser - */ #define VAX /* Compiler Specification */ #ifdef LSC /* For use with Lightspeed C compiler */ #include "math.h" #include "unix.h" #include "stdio.h" #include "ctype.h" #include "storage.h" #define MAC #endif #ifdef THC /* For use with Think C compiler */ #include "math.h" #include "unix.h" #include "stdio.h" #include "ctype.h" #include "Memory.h" #define MAC #endif #ifdef VAX /* For use with VAX C compiler */ #include #include #endif /* General Globals and defines */ #define pi 3.1415926535 typedef struct /* Thermodynamic variables */ { double Ps; /* Gas pressure of source (psi) */ double Pr; /* Gas pressure after reg. valve (psi) */ double Pa; /* Gas pressure in air chamber (psi) */ double Pb; /* Gas pressure in barrel (psi) */ double Px; /* Atmospheric pressure (psi) */ double Vr; /* regulator volume (in^2) */ double Va; /* air chamber volume (in^2) */ double T; /* Temperature (deg F) */ double m; /* Atomic weight of gas */ double GC; /* Gas consumption (oz) */ }VARpv; typedef struct /* Regulator valve variables */ { double S; /* Surface area of regulator piston (in^2) */ double x0; /* Nominal R-valve to top of R-seal (in) */ double Cl; /* Leakage flow conductance */ double Z; /* Flow conductance/length */ double T; /* Position of regulator nut (turns) */ double K; /* spring constant of the reg piston spring (lb/in) */ double H; /* Regulator nut turns per inch */ double x; /* Position of regulator valve (in) */ }VARr; typedef struct /* on-off valve variables */ { double C; /* Leakage conductance */ double Z; /* Flow conductance/Length */ double x; /* On-off pin position (in) */ }VARo; typedef struct /* Power tube variables */ { double M; /* Mass of bolt (oz) */ double S; /* Area of bolt (in^2) */ double xc; /* Position of bolt when it latches (in) */ double Cl; /* Leakage conductance */ double Z; /* flow conductance/length */ double K; /* Spring constant of power tube spring (lb/in) */ double R; /* Friction coefficient (lb-sec/in)*/ double x0; /* Relaxed length of power tube spring (in) */ double xi; /* Length of p.t. spring when bolt is latched (in) */ double xm; /* Maximum position of bolt (in) */ double x; /* Position of bolt (in) */ double v; /* Velocity of bolt (fps) */ }VARp; typedef struct /* barrel & ball variables */ { double M; /* Mass of ball */ double D; /* Diameter of barrel and ball */ double L; /* Length of barrel (in) */ double x; /* Position of ball (in) */ double v; /* Velocity of ball (fps) */ }VARb; typedef struct /* trigger variables */ { double B; /* Sear angle (deg) */ double Bo; /* Sear angle at which on-off valve turns on (deg) */ double Bb; /* Sear angle at which bolt is released (deg) */ double xs; /* Sear pivot to on-off pin distance (in) */ }VARt; /* Functions */ /*int tstep();*/ double Qsr(); /* Rate gas enters the regulator (m/s) */ double Qra(); /* Rate gas enters the air chamber (m/s) */ double Qab(); /* Rate gas enters the barrel (m/s) */ double Qbx(); /* Rate gas leaves the barrel (m/s) */ int UpDate_r(); /* Update regulator valve */ int UpDate_o(); int UpDate_p(); int UpDate_b(); int UpDate_t(); /*----------------------------------------------------------------------*/ main() { int i; VARr Zr; VARo Zo; VARp Zp; VARb Zb; VARt Zt; VARpv PV; double t; /* time (sec) */ double dt; /* time increment */ int n; /* number of iterations */ /* Thermodynamic variables */ PV.Px = 14.6959; /* atmospheric pressure (psi) */ PV.Ps = 1000.0; /* source pressure (psi) */ PV.Pr = 449.0; /* regulator pressure (psi) */ PV.Pa = 449.0; /* air chamber pressure (psi) */ PV.Pb = PV.Px; /* barrel pressure (psi) */ PV.Vr = 0.05; /* Volume of regulator chamber (in^3) */ PV.Va = 0.463; /* Volume of air chamber (in^3) */ PV.T = 70.0; /* Temperature (deg F) */ PV.m = 44.0; /* Atomic weight of gas */ PV.GC = 0.0; /* Gas consumption (oz) */ /* Regulator valve variables */ Zr.S = 0.19635; /* Surface area of regulator piston (in^2) */ Zr.x0 = 0.0625; /* Nominal R-valve to top of R-seal (in) */ Zr.Cl = 0.0; /* Leakage flow conductance */ Zr.Z = 200.0; /* Flow conductance/length */ Zr.T = 0.0; /* Position of regulator nut (turns) */ Zr.K = 1367.5; /* spring const. of reg piston spring (lb/in) */ Zr.H = 32.0; /* Regulator nut turns per inch */ Zr.x = Zr.x0; /* Position of regulator valve (in) */ /* on-off valve variables */ Zo.C = 0.0; /* Leakage conductance */ Zo.Z = 200.0; /* Flow conductance/Length */ Zo.x = 0.0; /* on-off pin position */ /* Power tube variables */ Zp.M = 1.848; /* Mass of bolt (oz) */ Zp.S = 0.181; /* Area of bolt (in^2) */ Zp.xc = -0.1; /* Position of bolt when it latches (in) */ Zp.Cl = 0.0; /* Leakage conductance */ Zp.Z = 360.0; /* flow conductance/length */ Zp.K = 11.3; /* Spring constant of power tube spring (lb/in) */ Zp.R = 1.0; /* Friction coefficient (lb-sec/in)*/ Zp.x0 = 1.89; /* Relaxed length of power tube spring (in) */ Zp.xi = 1.65; /* Length of pts. when bolt is latched (in) */ Zp.xm = 1.18; /* Maximum position of bolt (in) */ Zp.x = Zp.xc; /* Position of bolt (in) */ Zp.v = 0.0; /* Velocity of bolt (fps) */ /* barrel & ball variables */ Zb.M = 0.113; /* Mass of ball (oz) */ Zb.D = 0.68; /* Diameter of barrel and ball (in) */ Zb.L = 11.0; /* Length of barrel (in) */ Zb.x = 0.00; /* Position of ball (in) */ Zb.v = 0.00; /* Velocity of ball (fps) */ /* trigger variables */ Zt.B = 0.0; /* Sear angle (deg) */ Zt.Bo = 2.0; /* Sear angle at which on-off valve turns on (deg) */ Zt.Bb = 4.0; /* Sear angle at which bolt is released (deg) */ Zt.xs = 0.8; /* Sear pivot to on-off pin distance (in) */ t = 0.0; /* beginning time (sec) */ dt = 0.0002;/* time step (sec) */ n = 75; /* number of steps */ /* Step through time and print out some variables */ for(i=0;i Zr.x0) Zr.x = Zr.x0; if(Zr.x < 0.0) Zr.x = 0.0; return(0); } #undef Zr #undef PV /*----------------------------------------------------------------------*/ int UpDate_o(pPV,pZo,pZt,t,dt) #define PV (*pPV) #define Zo (*pZo) #define Zt (*pZt) VARpv PV; /* Pressures and Volumes */ VARo Zo; /* on-off valve variables */ VARt Zt; /* trigger variables */ double t; double dt; /* Update the on-off valve */ /* { double C; / Leakage conductance / double Z; / Flow conductance/Length / double x; / On-off pin position (in) / }VARo; { double B; / Sear angle (deg) / double Bo; / Sear angle at which on-off valve turns on (deg) / double Bb; / Sear angle at which bolt is released (deg) / double xs; / Sear pivot to on-off pin distance (in) / }VARt; */ { Zo.x = -Zt.xs*(Zt.B-Zt.Bo)*pi/180.; /* position of on-off pin */ return(0); } #undef Zo #undef Zt #undef PV /*----------------------------------------------------------------------*/ int UpDate_p(pPV,pZp,pZt,t,dt) #define PV (*pPV) #define Zp (*pZp) #define Zt (*pZt) VARpv PV; /* Pressures and Volumes */ VARp Zp; /* power tube variables */ VARt Zt; /* trigger variables */ double t; double dt; /* Update the position and velocity of the bolt. If the bolt is inside the air chamber, both the air chamber pressure and the power tube spring exert a force on the bolt. When its outside the air chamber, only the spring exerts a force. If the bolt position ever gets below Zp.xbl and the sear angle is smaller than Zp.Bb, the bolt is stopped. { double M; / Mass of bolt (oz) / double S; / Area of bolt (in^2) / double xc; / Position of bolt when it latches (in) / double Cl; / Leakage conductance / double Z; / flow conductance/length / double K; / Spring constant of power tube spring (lb/in) / double R; / Friction coefficient (lb-sec/in)/ double x0; / Relaxed length of power tube spring (in) / double xi; / Length of p.t. spring when bolt is latched (in) / double xm / Maximum position of bolt (in) / double x; / Position of bolt (in) / double v; / Velocity of bolt (fps) / }VARp; { double B; / Sear angle (deg) / double Bo; / Sear angle at which on-off valve turns on (deg) / double Bb; / Sear angle at which bolt is released (deg) / double xs; / Sear pivot to on-off pin distance (in) / }VARt; */ { if((Zp.x <= Zp.xc) && (Zt.B < Zt.Bb)) /* if Bolt is latched, stop it */ { Zp.x = Zp.xc; Zp.v = 0.0; } else { double vv,F,A; /* Velocity (in/sec) */ vv = Zp.v*12.0; /* Force (lb) */ F = -Zp.K*(Zp.x+Zp.x0-Zp.xi-Zp.xc) + (PV.Pa-PV.Pb)*Zp.S; if(Zp.x <= 0.0)F = F - Zp.R*Zp.v; /* Acceleration (in/sec^2) */ A = 514.784*F/Zp.M; Zp.x = Zp.x + (vv + 0.5*A*dt)*dt; Zp.v = (vv + A*dt)/12.0; } /* if bolt is at maximum position, stop it */ if(Zp.x > Zp.xm) { Zp.x = Zp.xm; Zp.v = 0.0; } /* if bolt is at minimum position, stop it */ if(Zp.x < Zp.xc) { Zp.x = Zp.xc; Zp.v = 0.0; } return; } #undef Zp #undef Zt #undef PV /*----------------------------------------------------------------------*/ int UpDate_b(pPV,pZb,pZp,t,dt) #define PV (*pPV) #define Zb (*pZb) #define Zp (*pZp) VARpv PV; /* Pressures and Volumes */ VARb Zb; /* barrel & ball variables */ VARp Zp; /* power tube variables */ double t; float dt; /* Update the position and velocity of the ball */ /* { double M; / Mass of ball / double D; / Diameter of barrel and ball / double L; / Length of barrel (in) / double x; / Position of ball (in) / double v; / Velocity of ball (fps) / }VARb; { double M; / Mass of bolt (oz) / double S; / Area of bolt (in^2) / double xc; / Position of bolt when it latches (in) / double Cl; / Leakage conductance / double Z; / flow conductance/length / double K; / Spring constant of power tube spring (lb/in) / double R; / Friction coefficient (lb-sec/in)/ double x0; / Relaxed length of power tube spring (in) / double xi; / Length of p.t. spring when bolt is latched (in) / double xm / Maximum position of bolt (in) / double x; / Position of bolt (in) / double v; / Velocity of bolt (fps) / }VARp; */ { if(Zb.x < Zb.L) { double A,vv; /* Velocity (in/sec) */ vv = Zb.v*12.0; /* Acceleration (in/sec^2) */ A = 6177.4*(PV.Pb-PV.Px)*0.25*pi*Zb.D*Zb.D/Zb.M; Zb.x = Zb.x + (vv + 0.5*A*dt)*dt; Zb.v = (vv + A*dt)/12.0; } if(Zb.x < 0.0) { Zb.x = 0.0; Zb.v = 0.0; } return(0); } #undef Zb #undef Zp #undef PV /*-----------------------------------------------------------------------*/ int UpDate_t(pZt,pZb,pZp,pPV,t,dt) #define Zt (*pZt) #define Zb (*pZb) #define Zp (*pZp) #define PV (*pPV) VARt Zt; /* Trigger variables */ VARb Zb; /* ball and barrel variables */ VARp Zp; /* power tube variables */ VARpv PV; /* Pressures and volumes */ double t; float dt; /* Update the position of the trigger */ /* put a ball in the chamber if so desired */ /* { double B; / Sear angle (deg) / double Bo; / Sear angle at which on-off valve turns on (deg) / double Bb; / Sear angle at which bolt is released (deg) / double xs; / Sear pivot to on-off pin distance (in) / }VARt; { double M; / Mass of ball / double D; / Diameter of barrel and ball / double L; / Length of barrel (in) / double x; / Position of ball (in) / double v; / Velocity of ball (fps) / }VARb; */ { if(t >= 0.005)Zt.B=Zt.Bb; else Zt.B=0.0; /* pull trigger at t=0.005 sec*/ return(0); } #undef Zt #undef Zb #undef Zp #undef PV /*-----------------------------------------------------------------------*/ int Err0r(n) int (n); { printf("\nError %d",n); exit(); return(0); }