/* * ScurveApplet.java * © Copley Controls Corp * Created on March 17, 2005, 7:00 PM */ import java.applet.Applet; import java.awt.*; import java.awt.event.*; import java.lang.Math; import java.lang.Double; /** * * @author dcrumlish & sglow */ public class ScurveApplet extends java.applet.Applet implements ActionListener {TextField postxt; TextField veltxt; TextField acctxt; TextField jrktxt, messagebox; Button calculate; Label dumytext; Label headertext; Label postext; Label veltext; Label acctext; Label jrktext; Label sectext; Image image1; /** * Calculate an s-curve move time given the move parameters: * @param P Distance to move (position units) * @param V Maximum velocity (position units / second) * @param A Maximum acceleration (position units / second / second) * @param J Maximum jerk (position units / second / second / second) * * @return The move time in seconds. */ public static double MoveTime( double P, double V, double A, double J ) { boolean hasTv = true; boolean hasTa = true; double tj = 0; double ta = 0; double tv = 0; // Force all the input parameters to positive values P = Math.abs(P); V = Math.abs(V); A = Math.abs(A); J = Math.abs(J); // See if a simple jerk limited move will handle // this. In this case, the move will be 4 segments // each of the same time. tj = Math.pow( P/(2*J), 1.0/3.0 ); if( (J*tj < A) && (J*tj*tj < V) ) hasTa = hasTv = false; // We know we'll hit either the accel or velocity // limit. See if the accel limit is too high. // If so, this must be a Jerk & Velocity move. else if( J*V < A*A ) { hasTa = false; tj = Math.sqrt( V/J ); tv = P/V - 2*tj; } else { // At this point we know we will hit the accel limit. // We may or may not hit the velocity limit. // // I'll start by assuming that I'll hit the velocity // limit. double vj; tj = A/J; vj = A*tj / 2.0; ta = (V - 2*vj) / A; // Find the distance moved getting up to // and down from V double p = tj*vj*4 + ta*vj*2 + A*ta*tj*2 + ta*ta*A; // If this distance is less then the total move, // then I'm done if( p <= P ) tv = (P-p) / V; // Otherwise, I can calculate the time at max accel. else { hasTv = false; ta = -1.5*tj + Math.sqrt( tj*tj/4 + P/A ); } } return 4*tj + 2*ta + tv; } public void paint (Graphics g) { setBackground(new Color(238, 235, 222)); //Back-grayish g.setColor(new Color(181,166,107)); //Bambo g.setFont(new Font("Ariel",Font.BOLD,9)); // g.drawString("© C O P L E Y . C O N T R O L S",26,228); g.setColor(new Color(0, 91, 153)); //Header-CopleyBlue g.fillRect(3,3,203,24); g.drawLine (1,1,207,1); g.drawLine (1,1,1,232); g.drawLine (207,1,207,232); g.drawLine (1,232,207,232); image1 = getImage(this.getDocumentBase(),"ccc.gif"); //Copley logo g.drawImage(image1, 6, 7, this); g.setColor(new Color(132,130,132)); //Gray-line g.drawLine (1,28,207,28); g.drawLine (10,170,197,170); g.setColor(new Color(255,255,255)); //white-line g.fillRect (10,171,187,2); } /** Initialization method that will be called after the applet is loaded * into the browser. */ public void init() { // TODO start asynchronous download of heavy resources headertext = new Label(" Scurve Movetime"); headertext.setForeground(new Color(239,255,255)); //Header-letter-whiteish headertext.setBackground(new Color(0, 91, 153)); //Header-CopleyBlue headertext.setFont(new Font("Ariel", Font.BOLD, 11)); add(headertext); dumytext = new Label("--------"); dumytext.setForeground(new Color(0, 91, 153)); //Header-CopleyBlue dumytext.setBackground(new Color(0, 91, 153)); //Header-CopleyBlue dumytext.setFont(new Font("Serif", Font.PLAIN, 11)); add(dumytext); dumytext = new Label("------------------------------------------------------------------------------------------------------------------------------------------------------"); dumytext.setForeground(new Color(238, 235, 222)); //Back-gray dumytext.setBackground(new Color(238, 235, 222)); //Back-gray dumytext.setFont(new Font("Serif", Font.PLAIN, 2)); add(dumytext); postext = new Label("POSITION "); postext.setForeground(new Color(49, 105, 198)); //Blue text postext.setBackground(new Color(238, 235, 222)); //Back-gray postext.setFont(new Font("Ariel", Font.BOLD, 11)); add(postext); postxt = new TextField("1000",4); postxt.setForeground(new Color(29, 23, 33)); //Blackish postxt.setBackground(new Color(251,249,247)); //whiteish postxt.setFont(new Font("Ariel", Font.PLAIN, 12)); add (postxt); postext = new Label("Units "); postext.setForeground(new Color(69, 152, 170)); //Blue postext.setBackground(new Color(238, 235, 222)); //Back-gray postext.setFont(new Font("Ariel", Font.BOLD, 11)); add(postext); veltext = new Label("VELOCITY"); veltext.setForeground(new Color(49, 105, 198)); //Blue text veltext.setBackground(new Color(238, 235, 222)); //Back-gray veltext.setFont(new Font("Ariel", Font.BOLD, 11)); add(veltext); veltxt = new TextField("0",4); veltxt.setForeground(new Color(29, 23, 33)); //Blackish veltxt.setBackground(new Color(251,249,247)); //whiteish veltxt.setFont(new Font("Ariel", Font.PLAIN, 12)); add (veltxt); veltext = new Label("Units/s "); veltext.setForeground(new Color(69, 152, 170)); //Blue veltext.setBackground(new Color(238, 235, 222)); //Back-gray veltext.setFont(new Font("Ariel", Font.BOLD, 11)); add(veltext); acctext = new Label(" ACCEL"); acctext.setForeground(new Color(49, 105, 198)); //Blue text acctext.setBackground(new Color(238, 235, 222)); //Back-gray acctext.setFont(new Font("Ariel", Font.BOLD, 11)); add(acctext); acctxt = new TextField("1000",4); acctxt.setForeground(new Color(29, 23, 33)); //Blackish acctxt.setBackground(new Color(251,249,247)); //whiteish acctxt.setFont(new Font("Ariel", Font.PLAIN, 12)); add (acctxt); acctext = new Label("Units/s^2"); acctext.setForeground(new Color(69, 152, 170)); //Blue acctext.setBackground(new Color(238, 235, 222)); //Back-gray acctext.setFont(new Font("Ariel", Font.BOLD, 11)); add(acctext); jrktext = new Label(" JERK"); jrktext.setForeground(new Color(49, 105, 198)); //Blue text jrktext.setBackground(new Color(238, 235, 222)); //Back-gray jrktext.setFont(new Font("Ariel", Font.BOLD, 11)); add(jrktext); jrktxt = new TextField("10000",4); jrktxt.setForeground(new Color(29, 23, 33)); //Blackish jrktxt.setBackground(new Color(251,249,247)); //whiteish jrktxt.setFont(new Font("Ariel", Font.PLAIN, 12)); add (jrktxt); jrktext = new Label("Units/s^3"); jrktext.setForeground(new Color(69, 152, 170)); //Blue jrktext.setBackground(new Color(238, 235, 222)); //Back-gray jrktext.setFont(new Font("Ariel", Font.BOLD, 11)); add(jrktext); dumytext = new Label("------------------------------------------------------------------------------------------------------------------------------------------------------"); dumytext.setForeground(new Color(238, 235, 222)); //Back-gray dumytext.setBackground(new Color(238, 235, 222)); //Back-gray dumytext.setFont(new Font("Serif", Font.PLAIN, 2)); add(dumytext); dumytext = new Label("------------------------------------------------------------------------------------------------------------------------------------------------------"); dumytext.setForeground(new Color(238, 235, 222)); //Back-gray dumytext.setBackground(new Color(238, 235, 222)); //Back-gray dumytext.setFont(new Font("Serif", Font.PLAIN, 2)); add(dumytext); calculate = new Button("Calculate"); calculate.addActionListener(this); calculate.setBackground(new Color(95, 189, 0)); //Green calculate.setForeground(new Color(251,249,247)); //whiteish calculate.setFont(new Font("Ariel", Font.BOLD, 11)); add (calculate); messagebox = new TextField(5); messagebox.setForeground(new Color(43, 0, 9)); //LCD-number messagebox.setBackground(new Color(247, 239, 231)); //LCD-backlight messagebox.setFont(new Font("Ariel", Font.BOLD, 11)); messagebox.setText(" 0."); add (messagebox); sectext = new Label("Seconds"); sectext.setForeground(new Color(221, 42, 35)); //Copley-red sectext.setBackground(new Color(238, 235, 222)); //Back-gray sectext.setFont(new Font("Ariel", Font.BOLD, 11)); add(sectext); } public void actionPerformed(ActionEvent event) {String arg=event.getActionCommand(); double P = Double.parseDouble(postxt.getText().trim()); double V = Double.parseDouble(veltxt.getText().trim()); double A = Double.parseDouble(acctxt.getText().trim()); double J = Double.parseDouble(jrktxt.getText().trim()); messagebox.setForeground(new Color(43, 0, 9)); //LCD-number messagebox.setBackground(new Color(247, 239, 231)); //LCD-backlight messagebox.setFont(new Font("Ariel", Font.BOLD, 11)); messagebox.setText(Double.toString(MoveTime(P,V,A,J))); } } // TODO overwrite start(), stop() and destroy() methods