6 Replies - 598 Views - Last Post: 14 July 2011 - 01:21 PM Rate Topic: -----

#1 gigamico  Icon User is offline

  • New D.I.C Head

Reputation: 0
  • View blog
  • Posts: 19
  • Joined: 14-July 11

[JAVA] Visualization problem, JPanel, JFrame

Posted 14 July 2011 - 11:09 AM

Hi everyone,
I have this class called IPView:
import javax.swing.JPanel;
import java.awt.Graphics;
import java.awt.*;

/**
 * IPView provides a view of IPModel
 * @author drew
 */
public final class IPView extends JPanel {

    private IPModel model;

    /** Creates new form IPView */
    public IPView() {
        initComponents();
    }

    /** This method is called from within the constructor to
     * initialize the form.
     * WARNING: Do NOT modify this code. The content of this method is
     * always regenerated by the Form Editor.
     */
    private void initComponents() {//GEN-BEGIN:initComponents

        setLayout(new java.awt.BorderLayout());

        setBorder(new javax.swing.border.LineBorder(new java.awt.Color(0, 0, 0)));
    }//GEN-END:initComponents


    // Variables declaration - do not modify//GEN-BEGIN:variables
    // End of variables declaration//GEN-END:variables

    //  http://java.sun.com/docs/books/tutorial/uiswing/14painting/practice.html

    protected void paintComponent(Graphics g) {
        super.paintComponent(g);
        Graphics2D g2 = (Graphics2D)g;      // in most cases (ours) this is a safe cast

        // get the dimensions of the JPanel so that we can scale everything properly
        Insets insets = getInsets();
        int viewWidth = getWidth() - insets.left - insets.right;
        int viewHeight = getHeight() - insets.top - insets.bottom;

        // scale the size of the model to the size of the view.
        // the constants are chosen for asthetics, but could be based on say
        // the masses of the objects.
        // Note that for the view to be physiclly correct, l and x must be
        // correctly proportianal. ( FIXME - better explaination )

        int blockWidth = viewWidth/10;
        int blockHeight = viewHeight/10;
        int penMassRadius = blockHeight/2;

        double modelX =  0;
        double modelPhi = 0;
        int penLength = blockHeight * 3;

        //
        if (model != null) {
            modelX = model.getX();
            modelPhi = model.getPhi();
        }


        int blockX =  (int)(modelX * penLength + viewWidth/2);
        int blockY =  viewHeight/2;
        int penX =   (int)(blockX + penLength * Math.sin(modelPhi));
        int penY =   (int)(blockY + penLength * Math.cos(modelPhi) - blockHeight);


        // paint the block
        g2.setColor(Color.blue);
        g2.fill(new Rectangle(blockX - blockWidth/2, blockY - blockHeight ,blockWidth, blockHeight));


        // paint the pendulum mass
        g2.setColor(Color.green);
        g2.fillOval(penX-penMassRadius, penY-penMassRadius, 2*penMassRadius, 2*penMassRadius);

        // paint the rod
        g2.drawLine(blockX,blockY -blockHeight , penX, penY);

    System.out.println("paintComponent");
    }

    /**
     * associate a model with this view
     */
    public void setModel(IPModel aModel) {
        model = aModel;
        System.out.println("setModel");
    }

    /**
     * call when a state change in the model requires an update to the view
     */
    public void modelStateChanged() {
        this.repaint();
        System.out.println("modelStateChanged");
    }
}


This is a part of a java applet which simulate an inverted pendulum system, at each time step the model class updates the system state.
The above code IPView, though very long, it simply paints a rectangle and a pendulum above it, with their position according to the updated system state.

I wrote the code of this class:
import java.awt.Graphics;
import java.awt.Graphics2D;
//import java.awt.Rectangle;
import java.awt.RenderingHints;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.Timer;
import java.awt.*;

public class IPApplication extends JPanel implements ActionListener {
  Timer timer;
  IPModel model;
  IPView view;
  int timeStep = 100;

  public IPApplication() {
    model = new IPModel();
    view = new IPView();
    view.setModel(model);

    timer = new Timer(timeStep, this);
    timer.setCoalesce(false);
    timer.start();
  }

  public static void main(String[] args) {
    JFrame frame = new JFrame("Pendolo Inverso");
    frame.add(new IPApplication());
    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    frame.setSize(420, 250);
    frame.setVisible(true);
  }

  public void actionPerformed(ActionEvent e) {

    //System.out.println("Hello World");
    model.update(timeStep/1000.0);
    System.out.println(model);
    view.modelStateChanged();
  }
}


This class starts the system simulation but the window doesn't display anything...instead I want to visualize the system at each time step.
Problably I'm doing something wrong but I don't get it, because I'm inexperienced with java.

It shouldn't be so difficult because it's only the visualization part that doesn't work.

Is This A Good Question/Topic? 0
  • +

Replies To: [JAVA] Visualization problem, JPanel, JFrame

#2 g00se  Icon User is offline

  • D.I.C Lover
  • member icon

Reputation: 2657
  • View blog
  • Posts: 11,214
  • Joined: 20-September 08

Re: [JAVA] Visualization problem, JPanel, JFrame

Posted 14 July 2011 - 11:19 AM

And IPModel ..?
Was This Post Helpful? 0
  • +
  • -

#3 gigamico  Icon User is offline

  • New D.I.C Head

Reputation: 0
  • View blog
  • Posts: 19
  • Joined: 14-July 11

Re: [JAVA] Visualization problem, JPanel, JFrame

Posted 14 July 2011 - 11:35 AM

I've not posted the IPModel because i've only problem with the visualization part.
The simulation goes well and at each step it prints the current state

However, if it can help this is the IPModel source:
 
/**
 * An IPModel object represents the dynamics of an inverted pendulum attached to a
 * sliding block.
 * @author Andrew Kaluzniacki
 */
public final class IPModel {
    
    /** Creates a new instance of IPModel */
    public IPModel() {
        this.reset();
    }
    
    /**
     * propogate the state of the system through a small time h
     *
     *  Runge Kutta Notes  - taken from Mathematical Methods of Physics - 2nd ed  Mathews + Walker
     *
     *  dy/dx = f(x,y)   -   this is the equation we know, what we want to find is y(x)
     *
     *  Suppose y = y0 at x = x0,  we choose a small interval h and calculate
     *
     *  k1 = h * f(x0, y0)
     *  k2 = h * f(x0 + h/2, y0 + k1/2)
     *  k3 = h * f(x0 + h/2, y0 + k2/2)
     *  k4 = h * f(x0 + h, y0 + k3)
     *
     *  Then at x = x0 + h , y (=) y0 + 1/6(k1 + 2 * k2 + 2 * k3 + k4)
     *
     *
     *  For several coupled differential equations it is a little messier
     *
     *  We have to do this for four first order diff eqs for x,phi,v,w.
     *
     *  Note that our diffeq are not actually explicitly dependent on t - since we take Fx and Fphi to be constant in our interval h.
     *  But I include t in the calls I make for clarity.
     */
    private void stepRK(double h) {
        
        double v = dx;  //  we call v dx
        double w = dphi;
        double t = time;
        
        // calculate all the new values - using old values
        double k1a = h *   eqDx(t, x, phi, v, w);
        double k1b = h * eqDphi(t, x, phi, v, w);
        double k1c = h *   eqDv(t, x, phi, v, w);
        double k1d = h *   eqDw(t, x, phi, v, w);
        
        double k2a = h *   eqDx(t + h/2.0, x + k1a/2.0, phi + k1b/2.0, v + k1c/2.0, w + k1d/2.0);
        double k2b = h * eqDphi(t + h/2.0, x + k1a/2.0, phi + k1b/2.0, v + k1c/2.0, w + k1d/2.0);
        double k2c = h *   eqDv(t + h/2.0, x + k1a/2.0, phi + k1b/2.0, v + k1c/2.0, w + k1d/2.0);
        double k2d = h *   eqDw(t + h/2.0, x + k1a/2.0, phi + k1b/2.0, v + k1c/2.0, w + k1d/2.0);
        
        
        double k3a = h *   eqDx(t + h/2.0, x + k2a/2.0, phi + k2b/2.0, v + k2c/2.0, w + k2d/2.0);
        double k3b = h * eqDphi(t + h/2.0, x + k2a/2.0, phi + k2b/2.0, v + k2c/2.0, w + k2d/2.0);
        double k3c = h *   eqDv(t + h/2.0, x + k2a/2.0, phi + k2b/2.0, v + k2c/2.0, w + k2d/2.0);
        double k3d = h *   eqDw(t + h/2.0, x + k2a/2.0, phi + k2b/2.0, v + k2c/2.0, w + k2d/2.0);
        
        double k4a = h *   eqDx(t + h, x + k3a, phi + k3b, v + k3c, w + k3d);
        double k4b = h * eqDphi(t + h, x + k3a, phi + k3b, v + k3c, w + k3d);
        double k4c = h *   eqDv(t + h, x + k3a, phi + k3b, v + k3c, w + k3d);
        double k4d = h *   eqDw(t + h, x + k3a, phi + k3b, v + k3c, w + k3d);
        
        double newX = x +     (k1a + 2.0 * k2a + 2.0 * k3a + k4a)/6.0;
        double newPhi = phi + (k1b + 2.0 * k2b + 2.0 * k3b + k4b)/6.0;
        double newV = v +     (k1c + 2.0 * k2c + 2.0 * k3c + k4c)/6.0;
        double newW = w +     (k1d + 2.0 * k2d + 2.0 * k3d + k4d)/6.0;
        
        // now update the old values with the new
        time = t + h;
        x = newX;
        phi = newPhi;
        dx = newV;
        dphi = newW;
    }
    
    
    private double eqDx(double t, double x, double phi, double v, double w) {
        return v; // x' = v
    }
    
    private double eqDphi(double t, double x, double phi, double v, double w) {
        return w; // phi' = w
    }
    
    private double eqDv(double t, double x, double phi, double v, double w) {
        
        double n = 2*(l*Fx - Math.cos(phi) * Fphi + l * Math.sin(phi)* ( g * m1 * Math.cos(phi) + l * m2 * w * w));
        
        double d  = l * (2*m1 + m2 - m2 * Math.cos(2*phi));
        
        return n/d;  // v'
    }
    
    private double eqDw(double t, double x, double phi, double v, double w) {
        
        double n = 2*l*m2*Math.cos(phi)*Fx + 2*(m1+m2)*(-Fphi + g*l*m1*Math.sin(phi)) + l*m2*m2*Math.sin(2*phi)*w*w;
        
        double d = l*l*m2*(-2*m1-m2+m2*Math.cos(2*phi));
        
        return n/d;  // w'
    }
    
    /**
     * propagate the model state through deltaTime using the Runge-Kutta method.
     */
    public void update(double deltaTime) {
        
        int n = 100;    // break deltaTime into even smaller time steps.
        for (int i = 0; i < n; i++) {
            stepRK(deltaTime/n);
        }
        
    };
    
    /**
     * reset the state of the model to an initial state
     */
    public void reset() {
        m1 = 1.0;
        x = 0;
        dx = 0;
        
        Fx = 0;
        Fphi = 0;
        m2 = 1.0;
        l = 1;
        phi = Math.PI -0.01; // almost verticle
        dphi = 0;
        
        time = 0;
    }
    
    /**
     * return a string representing the state of the model
     */
    public String toString() {
        java.text.DecimalFormat nf = new java.text.DecimalFormat();

        nf.setMaximumFractionDigits(2);
        nf.setMinimumFractionDigits(2);
        nf.setPositivePrefix("+");
        
        return "model: phi=" + nf.format(phi)
            + "     dphi=" + nf.format(dphi)
            + "    x=" + nf.format(x)
            + "    dx=" + nf.format(dx) 
            + "    time:" + nf.format(time);
    }
    
    /**
     * return the current value of x
     */    
    public double getX() {
        return x;
    }
    
     /**
     * return the current value of phi
     */    
    public double getPhi() {
        return phi;
    }
    
     /**
     * return the current value of l
     */    
    public double getL() {
        return l;
    }
    
    // the internal state of the model is private to the model
    // reset() sets these values.
    
    private double m1 = 0; 	// mass of block
    private double x = 0;	// the position of the block mass (pendulum pivot) - increases to the right
    private double dx = 0;	// first time derivative of x
    
    private double Fx = 0; 	// the external force applied to the block
    private double Fphi = 0; 	// the external force applied to the pendulum
    
    private double m2 = 0;	// mass of pendulum weight
    private double l = 0; 	// length of pendulum
    private double phi = 0;	// angle of the pendulum  - verticle down is 0, increasing counter clockwise
    private double dphi = 0;	// first time derivative of phi
    
    private double time = 0;	// time elapsed in simulation
    
    private final double g = 9.8;	// gravity is final
    
    
    /**
     * main() serves as a simple demo of IPModel and runs the model through 10 seconds of
     * time outputing the state to the console
     * In typical use of IPModel, main() would not be called
     * @param args the command line arguments - these are ignored
     */
    public static void main(String[] args) {
        System.out.println("Inverted Pendulum Model - run for 10 seconds..\n");
        
        IPModel model = new IPModel();
        
        // run for 10 seconds.
        for (double t = 0.0; t <= 10.0; t = t + 0.1) {
            System.out.println(model);
            model.update(0.1);
        }
    }
}



this is what I obtain by executing my application:
C:\java>java IPApplication
setModel
model: phi=+3,13     dphi=-0,02    x=-0,00    dx=-0,01    time:+0,10
modelStateChanged
model: phi=+3,13     dphi=-0,04    x=-0,00    dx=-0,02    time:+0,20
modelStateChanged
model: phi=+3,12     dphi=-0,08    x=-0,01    dx=-0,04    time:+0,30
modelStateChanged
model: phi=+3,11     dphi=-0,13    x=-0,01    dx=-0,06    time:+0,40
modelStateChanged
model: phi=+3,10     dphi=-0,20    x=-0,02    dx=-0,10    time:+0,50
modelStateChanged
model: phi=+3,07     dphi=-0,31    x=-0,03    dx=-0,16    time:+0,60
modelStateChanged
model: phi=+3,03     dphi=-0,49    x=-0,05    dx=-0,24    time:+0,70
modelStateChanged
model: phi=+2,97     dphi=-0,75    x=-0,08    dx=-0,37    time:+0,80
modelStateChanged
model: phi=+2,88     dphi=-1,13    x=-0,13    dx=-0,54    time:+0,90
modelStateChanged
model: phi=+2,74     dphi=-1,64    x=-0,19    dx=-0,76    time:+1,00

The setModel and modelStateChanged are the result of the println I've added in the IPView code to control the behavior of the application.

setModel and modelStateChanged are displayed, it means that the program executes the setModel and modelStateChanged methods of the IPView class, but since paintComponents is not displayed it means that the application doesn't execute the paintComponents method.
Was This Post Helpful? 0
  • +
  • -

#4 g00se  Icon User is offline

  • D.I.C Lover
  • member icon

Reputation: 2657
  • View blog
  • Posts: 11,214
  • Joined: 20-September 08

Re: [JAVA] Visualization problem, JPanel, JFrame

Posted 14 July 2011 - 11:54 AM

You never add the IPView instance to the gui
Was This Post Helpful? 0
  • +
  • -

#5 gigamico  Icon User is offline

  • New D.I.C Head

Reputation: 0
  • View blog
  • Posts: 19
  • Joined: 14-July 11

Re: [JAVA] Visualization problem, JPanel, JFrame

Posted 14 July 2011 - 01:01 PM

could you show me how to do?
I'm not so pratical with java
Was This Post Helpful? 0
  • +
  • -

#6 g00se  Icon User is offline

  • D.I.C Lover
  • member icon

Reputation: 2657
  • View blog
  • Posts: 11,214
  • Joined: 20-September 08

Re: [JAVA] Visualization problem, JPanel, JFrame

Posted 14 July 2011 - 01:14 PM

    public IPApplication() {
	setLayout(new BorderLayout());
        model = new IPModel();

        view = new IPView();

        view.setModel(model);

	add(view);
        timer = new Timer(timeStep, this);

        timer.setCoalesce(false);

        timer.start();
    }


Was This Post Helpful? 0
  • +
  • -

#7 gigamico  Icon User is offline

  • New D.I.C Head

Reputation: 0
  • View blog
  • Posts: 19
  • Joined: 14-July 11

Re: [JAVA] Visualization problem, JPanel, JFrame

Posted 14 July 2011 - 01:21 PM

Perfect!!!
it works, thank you so much!
Was This Post Helpful? 0
  • +
  • -

Page 1 of 1