/****************************************************************************/
/* Valve Body Simulation */
/****************************************************************************/
/* */
/**
* @version 1, 10/5/2000
* @author Andrew Silveri
*/
import java.awt.*;
import java.applet.*;
import java.lang.*;
import java.util.*;
import java.io.*;
/**
* Shift
* This provides for running the application as an applet.
*/
public class shift extends Applet
{
/** global variables **/
public static reg_mod window; // actual window object
/**************************** Init() ****************************************/
// Note: only required for applets
public void init()
{
// create user interface
window = new reg_mod();
window.setTitle("Shift Simulation");
window.pack();
window.start();
window.show();
window.reshape(10,10,750,450);
}
}
/**
* Reg_mod extends the Frame class in order to create a top level window with a title.
* The runnable interface allows reg_mod to run without subclassing thread by instantiating
* a thread instance and passing itself in as the target.
*/
class reg_mod extends Frame implements Runnable
{
final static double DTHYD = 0.00003;
final static double DT2 = 0.000015;
final static double DT6 = 0.000005;
final static double RHO = 0.00007957;
final static double BETAL = 220000;
final static double CEEDEE = 0.6;
final static double AIRMIX = 0.05;
final static double AREAMAX = 0.0314;
final int PAUSE_LENGTH = 20; // millisecs to pause between ticks
/* variables for double-buffered painting... */
Image offScreenImage = null;
Graphics offScreenGraphics = null;
Dimension offScreenSize = null;
/* user interface objects */
Panel controlPanel = new Panel();
Panel Display = new Panel();
MenuBar mb; // menu bar object
Menu m1, m2, m3; // first sub menu objects
MenuItem mi1_1, mi1_2, mi1_3;
MenuItem mi3_1, mi3_2, mi3_3;
Button back_up = new Button(" Acc. Back + ");
Button back_down = new Button(" Acc. Back - ");
Button sol1 = new Button(" SS1 off ");
Button reset = new Button(" Reset ");
/* hash table for plotting */
static Hashtable plot_vars = new Hashtable();
/* vector is a growable array */
Vector graphs = new Vector();
static Vector plot_var = new Vector();
/* dynamic variables */
Accumulator accum;
s12_valve valve12;
lm_valve line_mod;
band_clutch servo;
solenoid ss1;
/**
* rktime is displayed on the screen as "Time",
* it is incremented by DT2 for each integration step
* and is used as a comparator to update the screen after
* a redraw
*/
public double rktime;
/**
* next_time is used to create a time delta to compare against rktime
*/
public double next_time;
/**
* raw_back is the accumulator back pressure created by the Acc Back + and -
* buttons it is clipped between 2.5 and 100 and initialized to zero
*/
public double raw_back;
/* main thread */
Thread mainThread;
boolean isRunning = false;
boolean first = true;
static boolean help_on = false;
/****************************************************************************
reg_mod()
****************************************************************************/
public reg_mod()
{
init();
}
/**
* Creates the menu bar and control buttons and adds them to the window.
* Initializes all values to zero.
*/
public void init()
{
setLayout(new BorderLayout());
mb = new MenuBar(); // create the menu bar
setMenuBar(mb); // add the menu bar to this window
/* assign names to buttons and add to menu bar and sub menus */
m1 = new Menu("File");
mb.add(m1);
mi1_1 = new MenuItem(" New Graph ");
m1.add(mi1_1);
m1.addSeparator();
mi1_2 = new MenuItem(" Exit ");
m1.add(mi1_2);
m3 = new Menu("Help");
mb.add(m3);
mi3_1 = new MenuItem(" Instructions... ");
m3.add(mi3_1);
/* add buttons */
controlPanel.add(sol1);
controlPanel.add(back_up);
controlPanel.add(back_down);
controlPanel.add(reset);
add("South", controlPanel);
add("Center", Display);
valve12 = new s12_valve();
line_mod = new lm_valve();
accum = new Accumulator();
servo = new band_clutch();
ss1 = new solenoid();
/* initialize values to zero */
accum.init( 0.0, false, valve12, line_mod );
valve12.init( 0.0, 0.0, ss1 );
line_mod.init( 0.0 );
servo.init( 0.0, valve12 );
ss1.init( false, valve12 );
rktime = 0.0;
raw_back = 0.0;
}
/****************************************************************************
draw_Spring() Draws the accumulator spring
****************************************************************************/
static void draw_Spring( int state, Graphics g, int x_start, int x_end, int y1, int y2 )
{
int length = x_end - x_start;
int x1 = x_start + length/6;
int x2 = x_start + length/3;
int x3 = x_start + length/2;
int x4 = x_start + 2*length/3;
int x5 = x_start + 5*length/6;
int x6 = x_start + length;
if ( state >= 0 )
{
g.drawLine( x_start, y1, x1, y2 );
g.drawLine( x1, y1, x2, y2);
g.drawLine( x2, y1, x3, y2);
g.drawLine( x3, y1, x4, y2);
g.drawLine( x4, y1, x5, y2);
g.drawLine( x5, y1, x6, y2);
}
if ( state <= 0 )
{
g.drawLine( x1, y2, x1, y1);
g.drawLine( x2, y2, x2, y1);
g.drawLine( x3, y2, x3, y1);
g.drawLine( x4, y2, x4, y1);
g.drawLine( x5, y2, x5, y1);
}
}
/****************************************************************************
sqrtt() Square root function
****************************************************************************/
static double sqrtt( double arg )
{
if ( arg == 0.0 )
return( 0.0 );
else if ( arg < 0.0 )
return ( -Math.sqrt( -arg ) );
else
return ( Math.sqrt( arg ) );
}
/****************************************************************************
pressColor() The transmission oil color(red) gets more vivid as pressure
builds.
****************************************************************************/
static Color pressColor( double pressure )
{
int red = 0;
Color press_color;
if ( pressure >= 120.0 )
red = 255;
else if ( pressure <= 0.0 )
red = 0;
else if ( pressure < 30.0 )
red = (int)( 100.0 * pressure / 30.0 );
else
red = (int)( 155.0 * (pressure-30.0) / 90.0 + 100.0 );
press_color = new Color( 255, 255-red, 255-red );
return press_color;
}
/****************************************************************************
printPress()
****************************************************************************/
static String printPress( double pressure )
{
String out = " ";
String press = Double.toString( pressure );
int index1, length;
int index2;
length = press.length();
index1 = press.indexOf(".") + 4;
index2 = press.indexOf("e");
if ( index1 > length )
index1 = length;
if ( (index1 >= index2) && (index2 > 0) )
index1 = index2 - 1;
out = press.substring( 0, index1 );
return out;
}
/**
*Integral step time of 15 microseconds
*/
public void integration()
{
/** step 0 **/
ss1.intgrt( -1 );
accum.intgrt( -1 );
servo.intgrt( -1 );
valve12.intgrt( -1 );
line_mod.feed = ( 0.002 * raw_back ) + ( 0.998 * line_mod.feed );
/* Graph the elements every 25 milliseconds */
if ( rktime > next_time )
{
for( Enumeration e=graphs.elements(); e.hasMoreElements(); )
{
Graph elem = (Graph)e.nextElement();
if ( elem.state )
{
elem.redraw();
}
else
{
elem.dispose();
graphs.removeElement( elem );
}
}
next_time = rktime + 0.025;
/* update the screen */
update(Display.getGraphics());
try
{
Thread.sleep(PAUSE_LENGTH);
}
catch (InterruptedException e)
{
}
}
/** step 1 **/
ss1.deriv( 0 );
valve12.deriv( 0 );
accum.deriv( 0 );
servo.deriv( 0 );
rktime += DT2;
ss1.intgrt( 0 );
accum.intgrt( 0 );
servo.intgrt( 0 );
valve12.intgrt( 0 );
/** step 2 **/
ss1.deriv( 1 );
accum.deriv( 1 );
servo.deriv( 1 );
valve12.deriv( 1 );
ss1.intgrt( 1 );
accum.intgrt( 1 );
servo.intgrt( 1 );
valve12.intgrt( 1 );
/** step 3 **/
ss1.deriv( 2 );
accum.deriv( 2 );
servo.deriv( 2 );
valve12.deriv( 2 );
rktime += DT2;
ss1.intgrt( 2 );
accum.intgrt( 2 );
servo.intgrt( 2 );
valve12.intgrt( 2 );
/** step 4 **/
ss1.deriv( 3 );
accum.deriv( 3 );
servo.deriv( 3 );
valve12.deriv( 3 );
ss1.intgrt( 3 );
accum.intgrt( 3 );
servo.intgrt( 3 );
valve12.intgrt( 3 );
}
/**
*Integrate while SS1 is on
*/
public void run()
{
while ( true )
{
integration();
} // end while
} // end run
/**
*Start Integral
*/
public void start()
{
mainThread = new Thread(this);
mainThread.start(); // calls back to run method in "this"
isRunning = true;
}
/**
* Stop Integral
*/
public void stop()
{
if (mainThread != null)
{
mainThread.stop();
isRunning = false;
mainThread = null;
}
}
/**
* Use double buffering to prevent flickering images.
*/
public final void update(Graphics g)
{
/* implements no-flicker graphics using double buffering */
Dimension dim = size();
if((offScreenImage == null) || (dim.width != offScreenSize.width) || (dim.height != offScreenSize.height))
{
offScreenImage = createImage(dim.width, dim.height);
offScreenSize = dim;
offScreenGraphics = offScreenImage.getGraphics();
}
offScreenGraphics.clearRect(0, 0, offScreenSize.width, offScreenSize.height);
paint(offScreenGraphics);
g.drawImage(offScreenImage, 0, 0, null);
}
/**
* Paint the window graphics. If help is pressed in the menu then also paint
* valvebody component descriptions.
*/
public void paint(Graphics g)
{
if ( first )
{
Font f = new Font("Times Roman",Font.BOLD,12);
g.setFont(f);
first = false;
}
g.drawString("Time: " + reg_mod.printPress( rktime ), 10, 10);
accum.paint(g);
valve12.paint(g);
servo.paint(g);
ss1.paint(g);
// paint help
if ( help_on )
{
g.setColor( Color.blue );
g.drawString("Solenoid",190,60);
g.drawLine(220,62,255,70);
g.drawString("Shift Valve",400,50);
g.drawLine(425,55,425,68);
g.drawString("Accumulator",250,230);
g.drawLine(280,220,290,192);
g.drawString("Servo",520,260);
g.drawLine(515,255,490,255);
g.drawString("Turn the Solenoid On/Off",30,370);
g.drawLine(185,365,260,380);
g.drawString("Increase/Decrease Accumulator Back Pressure",220,350);
g.drawLine(330,352,370,380);
g.setColor( Color.black );
}
}
/**
* Window,menu,and button handling. If the window is closed clean up.
* If New Graph is selected in the menu then open graph window.
* If help is selected in the menu then open help window.
* If exit is selected in the menu clean up and close window.
*/
public boolean handleEvent(Event event)
{
if ( event.id == Event.WINDOW_DESTROY )
{
stop();
for( Enumeration e=graphs.elements(); e.hasMoreElements(); )
((Graph)e.nextElement()).dispose();
graphs.removeAllElements();
dispose();
System.exit(0);
return true;
}
if ( event.id == Event.ACTION_EVENT )
{
if ( event.target == mi1_1 )
{
Graph plot = new Graph();
plot.setTitle("Plot " + graphs.size() );
plot.pack();
plot.show();
plot.reshape(10,10,300,200);
graphs.addElement( plot );
return true;
}
if ( event.target == mi3_1 ) // help
{
Help_Window helpp = new Help_Window();
helpp.setTitle(" Instructions " );
helpp.pack();
helpp.show();
helpp.reshape(10,10,300,500);
return true;
}
if ( event.target == mi1_2 )
{
stop();
for( Enumeration e=graphs.elements(); e.hasMoreElements(); )
((Graph)e.nextElement()).dispose();
graphs.removeAllElements();
dispose();
System.exit(0);
return true;
}
if ( event.target == reset )
{
sol1.setLabel(" SS1 off ");
ss1.state = false;
for( Enumeration e=graphs.elements(); e.hasMoreElements(); )
((Graph)e.nextElement()).dispose();
graphs.removeAllElements();
accum.init( 0.0, false, valve12, line_mod );
valve12.init( 0.0, 0.0, ss1 );
line_mod.init( 0.0 );
servo.init( 0.0, valve12 );
ss1.init( false, valve12 );
rktime = 0.0;
next_time = 0.0;
raw_back = 0.0;
return true;
}
if ( event.target == sol1 )
{
if ( ss1.state )
{
sol1.setLabel(" SS1 off ");
ss1.state = false;
}
else
{
ss1.state = true;
sol1.setLabel(" SS1 on ");
}
return true;
}
if ( event.target == back_up )
{
if ( raw_back < 100.0 )
raw_back += 2.5;
return true;
}
if ( event.target == back_down )
{
if ( raw_back > 2.5 )
raw_back -= 2.5;
return true;
}
}
return false;
}
/****************************************************************************
startStop()
****************************************************************************/
void startStop()
{
if (isRunning)
{
isRunning = false;
mainThread.stop();
mainThread = null;
}
else
{
mainThread = new Thread(this);
mainThread.start();
isRunning = true;
}
update(Display.getGraphics()); // update screen
}
}
/**
* This scales the plots that are selected under menu item New Graph
*/
class Plot_Object extends Object
{
public double value;
public double base = 0.0;
public double span = 1.0;
Plot_Object()
{
value = 0.0;
}
public int plot_value()
{
return (int)( 1000.0 * ((value - base ) / span));
}
public void set_range( double min, double max )
{
base = min;
span = max - min;
}
}
/**
* This sets up the plot selections under "File" menu selection.
* The selected plot is then drawn using double buffered graphics.
*/
class Graph extends Frame
{
boolean first = true;
boolean state = true;
int index = 0;
int[] buffer = new int[150];
boolean buff_full = false;
String signal = " ";
/* variables for double-buffered painting... */
Image offScreenImage = null;
Graphics offScreenGraphics = null;
Dimension offScreenSize = null;
/* user interface objects */
Panel Display = new Panel();
MenuBar mb; // menu bar object
Menu m1, m2, m3, mi1_1; // first sub menu objects
MenuItem mi1_2, mi1_3;
MenuItem mi3_1, mi3_2, mi3_3;
/**
* This sets up the plot selections in the "File" sub menu
*/
public Graph()
{
setLayout(new BorderLayout());
mb = new MenuBar(); // create the menu bar
setMenuBar(mb); // add the menu bar to this window
m1 = new Menu("File");
mb.add(m1);
mi1_1 = new Menu(" Select Signal... ");
m1.add(mi1_1);
m1.addSeparator();
mi1_2 = new MenuItem(" Exit ");
m1.add(mi1_2);
for( Enumeration e = reg_mod.plot_vars.keys(); e.hasMoreElements(); )
{
/* All available plots listed */
mi1_1.add( new MenuItem( (String)e.nextElement() ));
}
add("Center", Display);
}
/**
* Update the screen
*/
public void redraw()
{
update(Display.getGraphics()); // update screen
};
/**
* Use double buffering to prevent flickering images.
*/
public final void update(Graphics g)
{
// implements no-flicker graphis using double buffering
Dimension dim = size();
if((offScreenImage == null) || (dim.width != offScreenSize.width) || (dim.height != offScreenSize.height))
{
offScreenImage = createImage(dim.width, dim.height);
offScreenSize = dim;
offScreenGraphics = offScreenImage.getGraphics();
}
offScreenGraphics.clearRect(0, 0, offScreenSize.width, offScreenSize.height);
paint(offScreenGraphics);
g.drawImage(offScreenImage, 0, 0, null);
}
/**
* Paint the window graphics. Label and draw the selected plot in the plot window.
*/
public void paint(Graphics g)
{
/* draw in black */
g.setColor( Color.black );
/* set font first time */
if ( first )
{
Font f = new Font("Times Roman",Font.BOLD,12);
g.setFont(f);
first = false;
}
Dimension d = size();
int bottom = d.height - 80;
int top = 10;
double y_delta = ( d.height - 50 ) / 1000.0;
double x = 10.0;
double x_delta = (double)( d.width - 20 ) / (double)buffer.length;
if ( signal.length() > 2 )
{
/* get plot value placement in buffer */
buffer[index] = ((Plot_Object)(reg_mod.plot_vars.get(signal))).plot_value();
/* display signal name */
g.drawString("Signal: " + signal , 10, 10);
/* check to see if the end of buffer reached. If not full continue to plot
else reset to beginning */
if ( buff_full )
{
int j, k;
if ( index == (buffer.length-1) )
{
j = 0;
k = 1;
}
else if ( index == (buffer.length-2) )
{
j = index+1;
k = 0;
}
else
{
j = index + 1;
k = index + 2;
}
for( int i=0; i<(buffer.length-1); i++ )
{
g.drawLine( (int)x, bottom - (int)(buffer[j] * y_delta) ,
(int)(x + x_delta), bottom - (int)(buffer[k] * y_delta) );
x += x_delta;
k++;
j++;
if ( k > buffer.length-1 )
{
k = 0;
j = buffer.length-1;
}
else if ( k == 1 )
{
j = 0;
}
}
}
else
{
for( int i=0; i buffer.length-1 )
{
buff_full = true;
index = 0;
}
}
else
{
index = 0;
}
}
/**
* Window,menu,and button handling. If the window is closed clean up.
* If "Select Signal" is selected in the menu then open corresponding plot window.
* If exit is selected in the menu clean up and close window.
*/
public boolean handleEvent(Event event)
{
if ( event.id == Event.WINDOW_DESTROY )
{
state = false;
return true;
}
if ( event.id == Event.ACTION_EVENT )
{
if ( event.target == mi1_2 )
{
state = false;
return true;
}
if ( event.target instanceof MenuItem )
{
for( Enumeration e = reg_mod.plot_vars.keys(); e.hasMoreElements(); )
{
if ( ((String)event.arg).equals( (String)e.nextElement() ) );
{
signal = (String)event.arg;
}
}
return true;
}
}
return false;
}
}
/**
* This creates the help window.
*/
class Help_Window extends Frame
{
boolean first = true;
/* user interface objects */
Panel control = new Panel();
MenuBar mb; // menu bar object
Menu m1; // first sub menu objects
MenuItem mi1_1;
Button close1 = new Button(" Close ");
/**
* The window gives a brief explanation of the simulation.
*/
public Help_Window()
{
setLayout(new BorderLayout());
control.setLayout( new FlowLayout( FlowLayout.CENTER ) );
mb = new MenuBar(); // create the menu bar
setMenuBar(mb); // add the menu bar to this window
m1 = new Menu("File");
mb.add(m1);
mi1_1 = new MenuItem(" Exit ");
m1.add(mi1_1);
control.add( close1 );
String help_text = " Help \n\n" +
" This is a simulation of the hydraulics inside\n" +
" an automatic transmission used for a 1-2 shift.\n" +
" The simulation models the hydraulic pressures\n" +
" and component positions using differential \n" +
" equations and a Runga-Kutta 4 integrator. \n\n" +
" This program was done in Java for demonstration\n" +
" purposes. The original models where written in \n" +
" Fortran.\n\n" +
" Starting Simulation\n\n" +
" To start the simulation click on the button labeled\n" +
" SS1 off, this will cause the shift valve to move to\n" +
" the right. The movement of the shift valve allows \n" +
" fluid to flow into the accumulator and servo. The \n" +
" servo is the element which causes a shift to occur. \n" +
" The objective is to smoothly apply the servo, which \n" +
" is the reason for the accumulator. The accumulator \n" +
" allows the pressure in the servo to slowly build \n" +
" rather than suddenly jump up to max. pressure. \n" +
" For controlling a shift we regulate the stroke of the\n" +
" accumulator by adding pressure to the back side. \n" +
" The buttons labeled Acc. Back + and - are used to \n" +
" increase and decrease the accumulator back pressure.\n\n" +
" Plotting\n\n" +
" All the internal states ( pressures, positions, and \n" +
" velocities ) can be plotted by going to the menu and \n" +
" selecting File, then New Graph. This will create a new\n" +
" plot window. In the menu on the plot window select \n" +
" File, then Select Signal, from here you can choose \n" +
" which signal you would like to plot. You can change \n" +
" the signal you are plotting at any time by selecting a \n" +
" new signal. You can also plot more signals by going \n" +
" to the main window menu and selecting New Graph \n" +
" again.\n";
add("Center", new TextArea( help_text ) );
add("South", control );
reg_mod.help_on = true;
}
/**
* Help window,menu,and button handling. If the window is closed clean up.
* If exit is selected in the menu clean up and close window.
*/
public boolean handleEvent(Event event)
{
if ( event.id == Event.WINDOW_DESTROY )
{
dispose();
reg_mod.help_on = false;
return true;
}
if ( event.id == Event.ACTION_EVENT )
{
if ( event.target == mi1_1 )
{
dispose();
reg_mod.help_on = false;
return true;
}
if ( event.target == close1 )
{
dispose();
reg_mod.help_on = false;
return true;
}
}
return false;
}
}
/**
* This handles the derivative/integration calculations for the accumulator resulting in the
* spring position and velocity. This will give the resulting local pressure that is determined
* by user input.
*/
class Accumulator extends Panel
{
final static double ACC_SPMOD_PRELOAD = 12.78;
final static double ACC_SPMOD_K = 83.44;
final static double ACC_SPMOD_TRVL = 0.1535;
final static double ACC_A1 = 1.24659;
final static double ACC_K = 23.66;
final static double ACC_PRELOAD = 9.65;
final static double ACC_EMASS = 0.000171;
final static double ACC_TRVL = 1.45;
final static double ACC_VOL = 0.4;
final static double ACC_MAX_VOL = 2.5;
public Plot_Object plot1 = new Plot_Object();
public Plot_Object plot2 = new Plot_Object();
protected boolean mod_spring = false;
protected s12_valve valve12 = null;
protected lm_valve line_mod = null;
/* velocity array */
protected double dx[] = { 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 };
/* position array */
protected double x[] = { 0.0, 0.0 };
/**
* 1-2 valve pressure effect on accumulator
*/
public double f1;
/**
* line pressure effect on accumaulator
*/
public double f2;
/**
* accumulator preload
*/
public double f3;
/**
* accumulator spring preload
*/
public double f4;
/**
* spring position
*/
public double pos;
/**
* spring velocity
*/
public double vel;
/**
* delta velocity
*/
public double delta_vel;
/**
* delta position
*/
public double delta_pos;
private int length = 120, diam = 40, x1 = 240, y = 150;
private int y2 = y+1, y3 = y+diam-1, xpos = 0;
/****************************************************************************
Accumulator() Plot accumulator velocity and position
****************************************************************************/
protected Accumulator()
{
plot1.set_range( -20.0, 20.0 );
plot2.set_range( 0.0, 3.0 );
reg_mod.plot_vars.put("Acc Vel", plot1 );
reg_mod.plot_vars.put("Acc Pos", plot2 );
}
/**
* Set initial velocity, position, and pressure to zero
*/
public void init( double p, boolean has_msprg, s12_valve s12, lm_valve lm )
{
for(int i=0; i<8; i++)
dx[i] = 0.0;
x[0] = 0.0;
x[1] = p;
valve12 = s12;
line_mod = lm;
pos = p;
mod_spring = has_msprg;
}
/**
* Calculate change in position and velocity
* @param step the derivative step
*/
public void deriv( int step )
{
f1 = valve12.feed * ACC_A1;
f2 = line_mod.feed * ACC_A1;
f3 = ACC_PRELOAD + ACC_K * pos;
if (( mod_spring ) && ( pos <= ACC_SPMOD_TRVL ))
f4 = ACC_SPMOD_PRELOAD - ACC_SPMOD_K * pos;
else
f4 = 0.0;
valve12.acc_vol = pos * ACC_A1 + ACC_VOL;
valve12.acc_flow = ACC_A1 * vel;
delta_vel = ( f1 - f2 - f3 + f4 ) / ACC_EMASS;
/* clip max. and min. travel */
if ( pos >= ACC_TRVL )
{
pos = ACC_TRVL;
if ( vel > 0.0 ) vel = 0.0;
if ( delta_vel > 0.0 ) delta_vel = 0.0;
if ( step == 1 )
{
x[0] = vel;
x[1] = ACC_TRVL;
}
}
else if ( pos <= 0.0 )
{
pos = 0.0;
if ( vel < 0.0 ) vel = 0.0;
if ( delta_vel < 0.0 ) delta_vel = 0.0;
if ( step == 1 )
{
x[0] = vel;
x[1] = 0.0;
}
}
delta_pos = vel;
dx[2*step] = delta_vel;
dx[2*step+1] = delta_pos;
}
/**
* integrate the position and velocity increments
* @param step the integral step
*/
public void intgrt( int step )
{
if ( step == -1 )
{
vel = x[0];
pos = x[1];
plot1.value = vel;
plot2.value = pos;
}
else if ( step == 0 )
{
vel = x[0] + ( dx[0] * reg_mod.DT2 );
pos = x[1] + ( dx[1] * reg_mod.DT2 );
}
else if ( step == 1 )
{
vel = x[0] + ( dx[2] * reg_mod.DT2 );
pos = x[1] + ( dx[3] * reg_mod.DT2 );
}
else if ( step == 2 )
{
vel = x[0] + ( dx[4] * reg_mod.DTHYD );
pos = x[1] + ( dx[5] * reg_mod.DTHYD );
}
else if ( step == 3 )
{
x[0] += ( dx[0] + 2.0*( dx[2] + dx[4] ) + dx[6] ) * reg_mod.DT6;
x[1] += ( dx[1] + 2.0*( dx[3] + dx[5] ) + dx[7] ) * reg_mod.DT6;
}
}
/**
* Paint the window graphics. Draw the accumulator change in position and update
* pressure and position values in the main window.
*/
public void paint(Graphics g)
{
xpos = (int)((1.0-(pos/ACC_TRVL)) * length);
// back pressure
g.setColor( reg_mod.pressColor( line_mod.feed ) );
g.fillRect( x1, y2, xpos, diam-1 );
g.fillRect( x1-10, y+diam-4, 10, 4 );
// feed pressure
g.setColor( reg_mod.pressColor( valve12.feed ) );
g.fillRect( x1+xpos, y2, length-xpos+10, diam-1 );
g.fillRect( x1+length+10, y+diam-4, 24, 4 );
g.setColor( Color.lightGray );
g.fillRect( x1+xpos, y2, 9, diam-2 );
g.setColor( Color.black );
g.drawRect( x1+xpos, y2, 9, diam-2 );
g.drawLine( x1, y, x1+length+10, y);
g.drawLine( x1-10, y+diam, x1+length+33, y+diam);
g.drawLine( x1-10, y+diam-5, x1, y+diam-5 );
g.drawLine( x1+length+10, y+diam-5, x1+length+33, y+diam-5);
g.drawLine( x1, y, x1, y+diam-5);
g.drawLine( x1+length+10, y, x1+length+10, y+diam-5);
reg_mod.draw_Spring( 0, g, x1, x1+xpos, y2, y3 );
g.drawString("BP: " + reg_mod.printPress( line_mod.feed ), x1,y-25);
g.drawString("FP: " + reg_mod.printPress( valve12.feed ), x1,y-15);
g.drawString("Pos: " + reg_mod.printPress( pos ), x1,y-5);
}
}
class lm_valve extends Panel
{
protected double dx[] = { 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 };
protected double x[] = { 0.0, 0.0 };
public double feed;
public double f1, f2, f3, f4, pos, vel, vol, q_feed, q_back;
public double delta_vel, delta_pos;
/****************************************************************************
lm_valve()
****************************************************************************/
protected lm_valve()
{
}
/****************************************************************************
init()
****************************************************************************/
public void init( double press )
{
for(int i=0; i<8; i++)
dx[i] = 0.0;
x[0] = 0.0;
x[1] = 0.0;
feed = press;
}
/****************************************************************************
deriv( int step )
****************************************************************************/
public void deriv( int step )
{
}
/****************************************************************************
paint(Graphics g)
****************************************************************************/
public void paint(Graphics g)
{
}
}
/**
* This handles the derivative/integration calculations for the 1-2 valve resulting in the
* valve position and velocity. This will affect the pressure feed to the system.
*/
class s12_valve extends Panel
{
final static double S12VLV_A1 = 0.2386;
final static double S12VLV_K = 4.23;
final static double S12VLV_PRELOAD = 4.0;
final static double S12VLV_DIAM = 0.5512;
final static double S12VLV_TRVL = 0.26;
final static double S12VLV_OVLP1 = 0.125;
final static double S12VLV_OVLP2 = 0.135;
final static double S12VLV_VOL = 0.5;
final static double S12VLV_EMASS = 0.000013;
protected double dx[] = { 0.0, 0.0, 0.0, 0.0, 0.0,
0.0, 0.0, 0.0, 0.0, 0.0,
0.0, 0.0, 0.0, 0.0, 0.0,
0.0, 0.0, 0.0, 0.0, 0.0 };
protected double x[] = { 0.0, 0.0, 0.0, 0.0, 0.0 };
protected double c1, c2, c5, c9, c11;
protected solenoid ss1 = null;
public Plot_Object plot3 = new Plot_Object();
public Plot_Object plot4 = new Plot_Object();
public Plot_Object plot5 = new Plot_Object();
public Plot_Object plot6 = new Plot_Object();
public Plot_Object plot7 = new Plot_Object();
public double feed;
/**
* release pressure
*/
public double rel;
/**
* intermediate pressure
*/
public double interm;
/**
* delta line pressure feed
*/
public double delta_feed;
/**
* delta release pressure
*/
public double delta_rel;
/**
* delta intermediate pressure
*/
public double delta_interm;
/**
* initial velocity holder
*/
public double f1;
/**
* secondary velocity holder
*/
public double f2;
/**
* valve position
*/
public double pos;
/**
* valve velocity
*/
public double vel;
/**
* valve volume
*/
public double vol;
/**
* pressure feed flow
*/
public double q_feed;
/**
* pressure exhaust flow
*/
public double q_exh;
/**
* pressure release flow
*/
public double q_release;
/**
* pressure source flow
*/
public double q_source;
/**
* flow from solenoid
*/
public double ss_draw;
/**
* change in valve velocity
*/
public double delta_vel;
/**
* change in valve position
*/
public double delta_pos;
/**
* feed position
*/
public double x_feed;
/**
* exhaust position
*/
public double x_exh;
/**
* exhaust area
*/
public double area;
/**
* pressure constant 1
*/
public double beta1;
/**
* pressure constant 2
*/
public double beta2;
/**
* pressure constant 3
*/
public double beta3;
/**
* servo apply volume
*/
public double sap_vol;
/**
* servo release volume
*/
public double srel_vol;
/**
* servo apply flow
*/
public double sap_flow;
/**
* servo release flow
*/
public double srel_flow;
/**
* servo accumulator volume
*/
public double acc_vol;
/**
* accumulator flow
*/
public double acc_flow;
private int travel = 14, length = 91, diam = 20, x0 = 360, y = 74;
private int xpos = 0, y1 = y - 5, y2 = y - 1, y3 = y + diam + 1, y4 = y + diam + 5;
private double area2_press = 0.0;
/****************************************************************************
s12_valve() This valve is used to regulate pressure flow for a 1-2 shift
****************************************************************************/
protected s12_valve()
{
/* constants */
c1 = 2.0 / reg_mod.RHO;
c2 = Math.sqrt( c1 );
c5 = 1.0 / reg_mod.BETAL;
c9 = Math.PI * S12VLV_DIAM;
c11 = c2 * reg_mod.CEEDEE;
plot3.set_range( -20.0, 20.0 );
plot4.set_range( 0.0, 0.5 );
plot5.set_range( 0.0, 150.0 );
plot6.set_range( 0.0, 150.0 );
plot7.set_range( 0.0, 150.0 );
/* plot servo and 1-2 valve values */
reg_mod.plot_vars.put("vlv12 Vel", plot3 );
reg_mod.plot_vars.put("vlv12 Pos", plot4 );
reg_mod.plot_vars.put("Servo App", plot5 );
reg_mod.plot_vars.put("Servo Rel", plot6 );
reg_mod.plot_vars.put("vlv12 Src", plot7 );
}
/**
* Set initial velocity, position, pressures and area for 1-2 valve
*/
public void init( double press, double vpos, solenoid ss )
{
for(int i=0; i<20; i++)
dx[i] = 0.0;
x[0] = 0.0;
x[1] = 0.0;
x[2] = 0.0;
x[3] = 0.0;
x[4] = 0.0;
feed = press;
pos = vpos;
interm = 0.0;
rel = 0.0;
ss1 = ss;
area2_press = 0.0;
}
/**
* Calculate changes in position, velocity, area, flow
* @param step the derivative step
*/
public void deriv( int step )
{
beta1 = 1.0 / ( c5 + ( reg_mod.AIRMIX / ( 1.4 * ( feed + 14.7 ) ) ) );
beta2 = 1.0 / ( c5 + ( reg_mod.AIRMIX / ( 1.4 * ( rel + 14.7 ) ) ) );
beta3 = 1.0 / ( c5 + ( reg_mod.AIRMIX / ( 1.4 * ( interm + 14.7 ) ) ) );
f1 = ss1.feed * S12VLV_A1;
f2 = S12VLV_PRELOAD + S12VLV_K * pos;
/* feed area and flow */
if ( pos > S12VLV_OVLP2 )
x_feed = pos - S12VLV_OVLP2;
else
x_feed = 0.0;
area = c9 * x_feed;
if ( area > reg_mod.AREAMAX )
area = reg_mod.AREAMAX;
q_source = c11 * ( 0.1 * area ) * reg_mod.sqrtt( 120.0 - interm );
q_feed = c11 * area * reg_mod.sqrtt( interm - feed );
/* allow leakage for release exhaust */
if ( area < 0.02 ) area = 0.02;
q_release = c11 * ( 0.25 * area ) * reg_mod.sqrtt( rel );
/* exhaust area and flow */
if ( pos < S12VLV_OVLP1 )
x_exh = S12VLV_OVLP1 - pos;
else
x_exh = 0.0;
area = c9 * x_exh;
if ( area > reg_mod.AREAMAX )
area = reg_mod.AREAMAX;
q_exh = c11 * area * reg_mod.sqrtt( feed );
/* flow from ss1 */
ss_draw = vel * S12VLV_A1;
delta_feed = (beta1 / (S12VLV_VOL + acc_vol + sap_vol) ) *
( q_feed - q_exh - sap_flow - acc_flow );
delta_rel = (beta2 / (0.001 + srel_vol) ) * ( srel_flow - q_release );
delta_interm = (beta3 / 0.1 ) * ( q_source - q_feed );
delta_vel = (f1 - f2) / S12VLV_EMASS;
delta_pos = vel;
/* clip max. and min. travel */
if ( pos >= S12VLV_TRVL )
{
pos = S12VLV_TRVL;
if ( vel > 0.0 ) vel = 0.0;
if ( delta_vel > 0.0 ) delta_vel = 0.0;
if ( step == 1 )
{
x[0] = vel;
x[1] = S12VLV_TRVL;
}
}
else if ( pos <= 0.0 )
{
pos = 0.0;
if ( vel < 0.0 ) vel = 0.0;
if ( delta_vel < 0.0 ) delta_vel = 0.0;
if ( step == 1 )
{
x[0] = vel;
x[1] = 0.0;
}
}
delta_pos = vel;
dx[5*step] = delta_vel;
dx[5*step+1] = delta_pos;
dx[5*step+2] = delta_feed;
dx[5*step+3] = delta_rel;
dx[5*step+4] = delta_interm;
/* for graphics */
if (( pos > 0.07 ) && ( pos < 0.135 ))
area2_press = 120.0;
else if ( pos > 0.135 )
area2_press = feed;
}
/**
* integrate the position and velocity increments and calculate
* feed,release,and intermediate values.
* @param step the integral step
*/
public void intgrt( int step )
{
if ( step == -1 )
{
vel = x[0];
pos = x[1];
feed = x[2];
rel = x[3];
interm = x[4];
plot3.value = vel;
plot4.value = pos;
plot5.value = feed;
plot6.value = rel;
plot7.value = interm;
}
else if ( step == 0 )
{
vel = x[0] + ( dx[0] * reg_mod.DT2 );
pos = x[1] + ( dx[1] * reg_mod.DT2 );
feed = x[2] + ( dx[2] * reg_mod.DT2 );
rel = x[3] + ( dx[3] * reg_mod.DT2 );
interm = x[4] + ( dx[4] * reg_mod.DT2 );
}
else if ( step == 1 )
{
vel = x[0] + ( dx[5] * reg_mod.DT2 );
pos = x[1] + ( dx[6] * reg_mod.DT2 );
feed = x[2] + ( dx[7] * reg_mod.DT2 );
rel = x[3] + ( dx[8] * reg_mod.DT2 );
interm = x[4] + ( dx[9] * reg_mod.DT2 );
}
else if ( step == 2 )
{
vel = x[0] + ( dx[10] * reg_mod.DTHYD );
pos = x[1] + ( dx[11] * reg_mod.DTHYD );
feed = x[2] + ( dx[12] * reg_mod.DTHYD );
rel = x[3] + ( dx[13] * reg_mod.DTHYD );
interm = x[4] + ( dx[14] * reg_mod.DTHYD );
}
else if ( step == 3 )
{
x[0] += ( dx[0] + 2.0*( dx[5] + dx[10] ) + dx[15] ) * reg_mod.DT6;
x[1] += ( dx[1] + 2.0*( dx[6] + dx[11] ) + dx[16] ) * reg_mod.DT6;
x[2] += ( dx[2] + 2.0*( dx[7] + dx[12] ) + dx[17] ) * reg_mod.DT6;
x[3] += ( dx[3] + 2.0*( dx[8] + dx[13] ) + dx[18] ) * reg_mod.DT6;
x[4] += ( dx[4] + 2.0*( dx[9] + dx[14] ) + dx[19] ) * reg_mod.DT6;
}
}
/**
* Paint the window graphics. Display the pressure changes(red color gets
* darker in areas of higher pressure) and the valve movement in the main window.
*/
public void paint(Graphics g)
{
xpos = x0 + (int)( (pos/0.26) * travel );
// area 1
g.setColor( reg_mod.pressColor( ss1.feed ) );
g.fillRect( x0+1,y,(xpos+4-x0), diam+1);
// line feed area
g.setColor( Color.red );
g.fillRect( x0+27,y-15,4,15);
// area 2
g.setColor( reg_mod.pressColor( area2_press ) );
g.fillRect( xpos+11, y, 14, diam+1);
// output feed area
g.setColor( reg_mod.pressColor( feed ) );
g.fillRect( x0+34, y+diam, 4, 131);
// area 3 exhausts
// output release area
g.setColor( reg_mod.pressColor( rel ) );
g.fillRect( x0+69, y+diam, 4, 111);
g.fillRect( x0+69, y+126, 50, 4);
g.fillRect( 479, y+126, 4, 25);
// draw valve
g.setColor( Color.lightGray );
g.fillRect( xpos, y+7, 4, 6 );
g.fillRect( xpos+4, y, 7, diam );
g.fillRect( xpos+11, y+7, 14, 6 );
g.fillRect( xpos+25, y, 7, diam );
g.fillRect( xpos+32, y+7, 14, 6 );
g.fillRect( xpos+46, y, 7, diam );
g.fillRect( xpos+53, y+7, 14, 6 );
g.fillRect( xpos+67, y, 14, diam );
// draw valve outline
g.setColor( Color.black );
g.drawRect( xpos, y+7, 4, 6 );
g.drawRect( xpos+4, y, 7, diam );
g.drawRect( xpos+11, y+7, 14, 6 );
g.drawRect( xpos+25, y, 7, diam );
g.drawRect( xpos+32, y+7, 14, 6 );
g.drawRect( xpos+46, y, 7, diam );
g.drawRect( xpos+53, y+7, 14, 6 );
g.drawRect( xpos+67, y, 14, diam );
// valve case top
g.drawLine(x0,y2,x0+26,y2);
g.drawLine(x0+26,y2,x0+26,y-15);
g.drawLine(x0+31,y2,x0+31,y-15);
g.drawLine(x0+31,y2,x0+40,y2);
g.drawLine(x0+40,y2,x0+40,y1);
g.drawLine(x0+45,y2,x0+45,y1);
g.drawLine(x0+45,y2,x0+75,y2);
g.drawLine(x0+75,y2,x0+75,y1);
g.drawLine(x0+80,y2,x0+80,y1);
g.drawLine(x0+80,y2,x0+109,y2);
// case bottom
g.drawLine(x0,y3,x0+33,y3);
g.drawLine(x0+33,y3,x0+33,y+111);
g.drawLine(x0+38,y3,x0+38,y+150);
g.drawLine(x0+38,y3,x0+68,y3);
g.drawLine(x0+68,y3,x0+68,y+130);
g.drawLine(x0+73,y3,x0+73,y+125);
g.drawLine(x0+73,y3,x0+109,y3);
g.drawLine(x0,y2,x0,y3-5);
g.drawLine(x0+109,y2,x0+109,y3);
reg_mod.draw_Spring( 0, g, xpos+81, x0+109, y, y+diam );
// continue feed line
g.drawLine(x0+33,y+116,x0+33,y+150);
// continue rel line
g.drawLine(x0+68,y+130,478,y+130);
g.drawLine(x0+73,y+125,483,y+125);
g.drawLine(478,y+130,478,224);
g.drawLine(483,y+125,483,224);
g.drawString("Pos: " + reg_mod.printPress( pos ), x0+115,y+12);
g.drawString("Pfeed: " + reg_mod.printPress( feed), x0+115,y+22);
g.drawString("Prel: " + reg_mod.printPress( rel ), x0+115,y+32);
}
}
/**
* Applying pressure to the servo tightens the band clutch for the 1-2 shift
*/
class band_clutch extends Panel
{
final static double SERVO_A1 = 6.67;
final static double SERVO_A2 = 6.55;
final static double SERVO_VOL_INIT = 1.0;
final static double SERVO_K = 400.0;
final static double SERVO_PRELOAD = 86.0;
final static double SERVO_EMASS = 0.00087;
final static double SERVO_TRVL = 0.26;
final static double SERVO_MAX_VOL = 2.8;
/* velocity array */
protected double dx[] = { 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 };
/* position array */
protected double x[] = { 0.0, 0.0 };
public Plot_Object plot8 = new Plot_Object();
public Plot_Object plot9 = new Plot_Object();
/**
* servo apply feed pressure
*/
public double f1;
/**
* servo apply release pressure
*/
public double f2;
/**
* servo preload
*/
public double f3;
/**
* reserved
*/
public double f4;
/**
* servo position
*/
public double pos;
/**
* servo velocity
*/
public double vel;
/**
* servo velocity delta
*/
public double delta_vel;
/**
* servo position delta
*/
public double delta_pos;
protected s12_valve valve12 = null;
private int length = 80, diam = 60, x0 = 393, y = 224;
private int y2 = y + 1, y3 = y+diam-1, xpos = 0, x2 = x0+length+10;
/****************************************************************************
band_clutch() The band clutch is activated for a 1-2 shift
****************************************************************************/
protected band_clutch()
{
plot8.set_range( -20.0, 20.0 );
plot9.set_range( 0.0, 0.5 );
/* plot servo position, velocity */
reg_mod.plot_vars.put("Servo Vel", plot8 );
reg_mod.plot_vars.put("Servo Pos", plot9 );
}
/**
* Set initial velocity and position for servo
*/
public void init( double vpos, s12_valve s12 )
{
for(int i=0; i<8; i++)
dx[i] = 0.0;
x[0] = 0.0;
x[1] = vpos;
pos = vpos;
valve12 = s12;
}
/**
* Calculate changes in position and velocity in servo
* @param step the derivative step
*/
public void deriv( int step )
{
f1 = valve12.feed * SERVO_A1;
f2 = valve12.rel * SERVO_A2;
f3 = SERVO_PRELOAD + SERVO_K * pos;
/* servo apply volume */
valve12.sap_vol = SERVO_A1 * pos + SERVO_VOL_INIT;
valve12.srel_vol = SERVO_MAX_VOL - SERVO_A2 * pos;
valve12.sap_flow = SERVO_A1 * vel;
valve12.srel_flow = SERVO_A2 * vel;
delta_vel = ( f1 - f2 - f3 ) / SERVO_EMASS;
// clip max. and min. travel
if ( pos >= SERVO_TRVL )
{
pos = SERVO_TRVL;
if ( vel > 0.0 ) vel = 0.0;
if ( delta_vel > 0.0 ) delta_vel = 0.0;
if ( step == 1 )
{
x[0] = vel;
x[1] = SERVO_TRVL;
}
}
else if ( pos <= 0.0 )
{
pos = 0.0;
if ( vel < 0.0 ) vel = 0.0;
if ( delta_vel < 0.0 ) delta_vel = 0.0;
if ( step == 1 )
{
x[0] = vel;
x[1] = 0.0;
}
}
delta_pos = vel;
dx[2*step] = delta_vel;
dx[2*step+1] = delta_pos;
}
/**
* integrate the position and velocity increments for the servo
* in order to apply the band clutch
* @param step the integral step
*/
public void intgrt( int step )
{
if ( step == -1 )
{
vel = x[0];
pos = x[1];
plot8.value = vel;
plot9.value = pos;
}
else if ( step == 0 )
{
vel = x[0] + ( dx[0] * reg_mod.DT2 );
pos = x[1] + ( dx[1] * reg_mod.DT2 );
}
else if ( step == 1 )
{
vel = x[0] + ( dx[2] * reg_mod.DT2 );
pos = x[1] + ( dx[3] * reg_mod.DT2 );
}
else if ( step == 2 )
{
vel = x[0] + ( dx[4] * reg_mod.DTHYD );
pos = x[1] + ( dx[5] * reg_mod.DTHYD );
}
else if ( step == 3 )
{
x[0] += ( dx[0] + 2.0*( dx[2] + dx[4] ) + dx[6] ) * reg_mod.DT6;
x[1] += ( dx[1] + 2.0*( dx[3] + dx[5] ) + dx[7] ) * reg_mod.DT6;
}
}
/**
* Paint the window graphics. Display the pressure changes(red color gets
* darker in areas of higher pressure) and the servo movement in the main window.
*/
public void paint(Graphics g)
{
xpos = (int)( (pos/0.26) * length);
// apply pressure
g.setColor( reg_mod.pressColor( valve12.feed ) );
g.fillRect( x0, y2, xpos, diam-1 );
// feed pressure
g.setColor( reg_mod.pressColor( valve12.rel ) );
g.fillRect( x0+xpos, y2, length-xpos+10, diam-1 );
g.setColor( Color.lightGray );
g.fillRect( x0+xpos, y2, 10, diam-2 );
g.setColor( Color.black );
g.drawRect( x0+xpos, y2, 10, diam-2 );
g.drawLine( x0+5, y, x0+length+5, y);
g.drawLine( x0, y+diam, x2, y+diam);
g.drawLine( x0, y, x0, y+diam);
g.drawLine( x0+length+10, y, x2, y+diam);
reg_mod.draw_Spring( 1, g, x0+xpos+10, x2, y2, y3 );
g.setColor( Color.lightGray );
g.fillRect( x0+xpos+10, y + diam/2 - 5, 80, 10 );
g.setColor( Color.black );
g.drawRect( x0+xpos+10, y + diam/2 - 5, 80, 10 );
reg_mod.draw_Spring( -1, g, x0+xpos+10, x2, y2, y3 );
g.drawString("Pos: " + reg_mod.printPress( pos ), x0,y3+15);
}
}
/**
* The solenoid regulates the pressure needed to open and close the 1-2 valve
*/
class solenoid extends Panel
{
final static double SS1_ORF1 = 0.0659;
final static double SS1_ORF2 = 0.0758;
final static double SS1_VOL = 1.50;
/* velocity array */
protected double dx[] = { 0.0, 0.0, 0.0, 0.0 };
/* position array */
protected double x[] = { 0.0 };
public Plot_Object plot10 = new Plot_Object();
/* constants */
protected double c1, c2, c3, c4, c5, beta1;
/**
* solenoid feed pressure
*/
public double feed;
/**
* source pressure
*/
public double source;
/**
* solenoid feed flow
*/
public double q_feed;
/**
* solenoid exhaust flow
*/
public double q_exh;
/**
* solenoid delta feed pressure
*/
public double delta_feed;
protected s12_valve valve12 = null;
public boolean state = false;
private int x0 = 260, y = 50;
/****************************************************************************
solenoid() When the solenoid is off(closed) there is no pressure feed. The
degree that it is open affects the pressure feed to the system
****************************************************************************/
protected solenoid()
{
c1 = 2.0 / reg_mod.RHO;
c2 = Math.sqrt( c1 );
c3 = 1.0 / reg_mod.BETAL;
c4 = c2 * reg_mod.CEEDEE * ( Math.PI / 4.0 ) * Math.pow( SS1_ORF1, 2.0 );
c5 = c2 * reg_mod.CEEDEE * ( Math.PI / 4.0 ) * Math.pow( SS1_ORF2, 2.0 );
plot10.set_range( 0.0, 120.0 );
reg_mod.plot_vars.put("SS1 Feed", plot10 );
}
/**
* Set initial velocity and position for the solenoid
*/
public void init( boolean on_off, s12_valve s12 )
{
for(int i=0; i<4; i++)
dx[i] = 0.0;
x[0] = 0.0;
feed = 0.0;
state = on_off;
valve12 = s12;
}
/**
* Calculate changes in position and velocity in solenoid
* @param step the derivative step
*/
public void deriv( int step )
{
/* constant source of 60psi */
source = 60.0;
beta1 = 1.0 / ( c3 + ( reg_mod.AIRMIX / ( 1.4 * ( feed + 14.7 ) ) ) );
if ( state )
{
q_feed = c4 * reg_mod.sqrtt( source - feed );
q_exh = 0.0;
}
else
{
q_feed = 0.0;
q_exh = c5 * reg_mod.sqrtt( feed );
}
delta_feed = (beta1/SS1_VOL) * ( q_feed - q_exh - valve12.ss_draw );
dx[step] = delta_feed;
}
/**
* integrate the position and velocity increments for the solenoid
* in order to apply pressure and flow to the system
* @param step the integral step
*/
public void intgrt( int step )
{
if ( step == -1 )
{
feed = x[0];
plot10.value = feed;
}
else if ( step == 0 )
{
feed = x[0] + ( dx[0] * reg_mod.DT2 );
}
else if ( step == 1 )
{
feed = x[0] + ( dx[1] * reg_mod.DT2 );
}
else if ( step == 2 )
{
feed = x[0] + ( dx[2] * reg_mod.DTHYD );
}
else if ( step == 3 )
{
x[0] += ( dx[0] + 2.0*( dx[1] + dx[2] ) + dx[3] ) * reg_mod.DT6;
}
}
/**
* Paint the window graphics. Display the pressure changes(red color gets
* darker in areas of higher pressure) as the solenoid changes pressure
* and flow in the main window.
*/
public void paint(Graphics g)
{
g.setColor( Color.black );
g.drawRect( x0, y, 30, 30 );
g.drawRect( x0+7, y+30, 16, 3 );
g.drawRect( x0+5, y+33, 20, 5 );
g.drawRect( x0+11, y+38, 8, 9 );
g.drawRect( x0+9, y+47, 12, 5 );
g.drawRect( x0+12, y+52, 6, 4 );
g.setColor( reg_mod.pressColor( feed ) );
g.fillRect( x0+20, y+41, 81, 4 );
g.setColor( Color.black );
g.drawLine( x0+19, y+40, x0+100, y+40 );
g.drawLine( x0+19, y+45, x0+100, y+45 );
g.drawString("SS1",x0+5,y+15);
g.drawString("State: " + state,x0,y-15);
g.drawString("Feed: " + reg_mod.printPress( feed ), x0,y-5);
}
}