//--------------------------------------------------------------------------------//
// COPYRIGHT NOTICE //
//--------------------------------------------------------------------------------//
// Copyright (c) 2012, Instituto de Microelectronica de Sevilla (IMSE-CNM) //
// //
// All rights reserved. //
// //
// Redistribution and use in source and binary forms, with or without //
// modification, are permitted provided that the following conditions are met: //
// //
// * Redistributions of source code must retain the above copyright notice, //
// this list of conditions and the following disclaimer. //
// //
// * Redistributions in binary form must reproduce the above copyright //
// notice, this list of conditions and the following disclaimer in the //
// documentation and/or other materials provided with the distribution. //
// //
// * Neither the name of the IMSE-CNM nor the names of its contributors may //
// be used to endorse or promote products derived from this software //
// without specific prior written permission. //
// //
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" //
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE //
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE //
// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE //
// FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL //
// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR //
// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER //
// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, //
// OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE //
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. //
//--------------------------------------------------------------------------------//
package xfuzzy.xfsim;
import xfuzzy.*;
import xfuzzy.lang.*;
import xfuzzy.util.*;
import javax.swing.*;
import javax.swing.filechooser.FileNameExtensionFilter;
import java.awt.*;
import java.awt.event.*;
import java.io.*;
/**
* Ventana principal de la aplicaci�n "xfsim" de simulaci�n de sistemas difusos.
*
* @author Francisco Jos� Moreno Velo
*
*/
public class Xfsim extends JFrame implements ActionListener, WindowListener,
MouseListener, KeyListener {
// ----------------------------------------------------------------------------//
// COSTANTES PRIVADAS //
// ----------------------------------------------------------------------------//
/**
* C�digo asociado a la clase serializable
*/
private static final long serialVersionUID = 95505666603056L;
// ----------------------------------------------------------------------------//
// MIEMBROS PRIVADOS //
// ----------------------------------------------------------------------------//
/**
* Ventana principal del entorno
*/
private Xfuzzy xfuzzy;
/**
* Sistema difuso a simular
*/
private Specification spec;
/**
* Hilo del proceso de simulaci�n
*/
private XfsimProcess process;
/**
* Configuraci�n del proceso de simulaci�n
*/
private XfsimConfig config;
/**
* Estado de la simulaci�n
*/
private int running = 0;
/**
* Campos de texto para configurar el modelo de planta
*/
private XTextForm modelform[];
/**
* Campos para mostrar la evoluci�n de la simulaci�n (iteraciones y tiempo)
*/
private XTextForm evolform[];
/**
* Campos para mostrar la salida de la planta en cada instante
*/
private XTextForm plantform[];
/**
* Campos para mostrar la salida del sistema difuso en cada instante
*/
private XTextForm fuzzyform[];
/**
* Barra de botones
*/
private XCommandForm commandform;
/**
* Lista de salidas a generar
*/
private XList outputlist;
/**
* Men� contextual asociado a las salidas
*/
private JPopupMenu popup;
// ----------------------------------------------------------------------------//
// CONSTRUCTOR //
// ----------------------------------------------------------------------------//
/**
* Constructor
*/
public Xfsim(Xfuzzy xfuzzy, Specification spec) {
super("Xfsim");
this.xfuzzy = xfuzzy;
this.spec = spec;
this.config = new XfsimConfig(this);
build();
refreshConfig();
}
// ----------------------------------------------------------------------------//
// EJECUCI�N EXTERNA //
// ----------------------------------------------------------------------------//
/**
* Ejecuci�n externa
*/
public static void main(String args[]) {
if (args.length != 1 && args.length != 2) {
System.out.println("Usage: xfsim xflfile [cfgfile]");
return;
}
File file = new File(args[0]);
if (!file.exists()) {
System.out.println("Can't find file " + file.getAbsolutePath());
System.exit(-1);
}
XflParser parser = new XflParser();
Specification spec = parser.parse(file.getAbsolutePath());
if (spec == null) {
System.out.println(parser.resume());
return;
}
Xfsim simulator = new Xfsim(null, spec);
if (args.length == 2) {
File cfgfile = new File(args[1]);
if (!cfgfile.exists()) {
System.out.println("Can't find file "
+ cfgfile.getAbsolutePath());
} else {
XfuzzyConfig xfcparser = new XfuzzyConfig();
if (!xfcparser.parseXfsimConfig(simulator, cfgfile))
System.out.println(xfcparser.resume());
simulator.refreshConfig();
}
}
simulator.setVisible(true);
}
// ----------------------------------------------------------------------------//
// M�TODOS P�BLICOS //
// ----------------------------------------------------------------------------//
/**
* Devuelve la referencia al sistema difuso a simular
*/
public Specification getSpecification() {
return this.spec;
}
/**
* Devuelve la configuraci�n del proceso de simulaci�n
*/
public XfsimConfig getConfiguration() {
return this.config;
}
/**
* Devuelve el estado de ejecuci�n de la simulaci�n
*/
public int getStatus() {
return this.running;
}
/**
* Verifica si se est� realizando un proceso de simulaci�n
*/
public boolean isSimulating() {
return (process != null && process.isAlive());
}
/**
* Coloca la ventana en la posici�n deseada sobre la pantalla
*/
public void setLocation() {
if (xfuzzy != null) {
Point loc = xfuzzy.frame.getLocationOnScreen();
loc.x += 40;
loc.y += 200;
setLocation(loc);
} else {
Dimension frame = getSize();
Dimension screen = getToolkit().getScreenSize();
setLocation((screen.width - frame.width) / 2,
(screen.height - frame.height) / 2);
}
}
/**
* Actualiza los valores de la zona de configuraci�n
*/
public void refreshConfig() {
if (config.plant != null)
modelform[0].setText(config.plant.getClass().getName());
else
modelform[0].setText("");
modelform[1].setText(config.limit.toString());
if (config.init == null)
modelform[2].setText("default");
else
modelform[2].setText("configured");
outputlist.setListData(config.output);
commandform.setEnabled(2, config.isConfigured());
repaint();
}
/**
* Actualiza los valores de los campos de estado
*/
public void refreshStatus(double iter, double time, double[] fzst,
double[] ptst) {
evolform[0].setText(redondeo(iter));
evolform[1].setText(redondeo(time) + " ms");
for (int i = 0; i < fzst.length; i++)
fuzzyform[i].setText(redondeo(fzst[i]));
for (int i = 0; i < ptst.length; i++)
plantform[i].setText(redondeo(ptst[i]));
}
/**
* Actualiza el estado de la barra de comandos
*/
public void setSensitive(int kind) {
switch (kind) {
case 0:
commandform.setLabel(2, "Run");
commandform.setEnabled(0, true);
commandform.setEnabled(1, true);
commandform.setEnabled(2, config.isConfigured());
commandform.setEnabled(3, true);
commandform.setEnabled(4, true);
running = 0;
return;
case 1:
commandform.setLabel(2, "Stop");
commandform.setEnabled(0, false);
commandform.setEnabled(1, false);
commandform.setEnabled(3, false);
commandform.setEnabled(4, false);
running = 1;
return;
case 2:
commandform.setLabel(2, "Continue");
commandform.setEnabled(0, true);
commandform.setEnabled(1, true);
commandform.setEnabled(3, true);
commandform.setEnabled(4, true);
running = 2;
return;
}
}
/**
* Interfaz ActionListener
*/
public void actionPerformed(ActionEvent e) {
String command = e.getActionCommand();
if (command.equals("Load"))
load();
else if (command.equals("Save"))
save();
else if (command.equals("Run"))
run();
else if (command.equals("Reload"))
reload();
else if (command.equals("Close"))
close();
else if (command.equals("Plant"))
plant();
else if (command.equals("Init"))
init();
else if (command.equals("Limit"))
limit();
else if (command.equals("InsertLog"))
insertLogfile();
else if (command.equals("InsertPlot"))
insertPlot();
else if (command.equals("Edit"))
editOutput();
else if (command.equals("Remove"))
removeOutput();
}
/**
* Interfaz KeyListener. Acci�n al soltar una tecla
*/
public void keyReleased(KeyEvent e) {
int code = e.getKeyCode();
if (code == KeyEvent.VK_BACK_SPACE)
removeOutput();
if (code == KeyEvent.VK_DELETE)
removeOutput();
if (code == KeyEvent.VK_CUT)
removeOutput();
if (code == KeyEvent.VK_INSERT)
insertOutput();
if (code == KeyEvent.VK_ENTER)
editOutput();
if (code == 226)
editOutput();
e.consume();
}
/**
* Interfaz KeyListener. Acci�n al apretar una tecla
*/
public void keyPressed(KeyEvent e) {
}
/**
* Interfaz KeyListener. Acci�n al teclear.
*/
public void keyTyped(KeyEvent e) {
}
/**
* Interfaz MouseListener. Acci�n al pulsar el rat�n
*/
public void mouseClicked(MouseEvent e) {
if (e.getClickCount() == 2)
editOutput();
}
/**
* Interfaz MouseListener. Acci�n al apretar un bot�n del rat�n
*/
public void mousePressed(MouseEvent e) {
if (!e.isPopupTrigger())
return;
popup.show((Component) e.getSource(), e.getX(), e.getY());
}
/**
* Interfaz MouseListener. Acci�n al soltar un bot�n del rat�n
*/
public void mouseReleased(MouseEvent e) {
if (!e.isPopupTrigger())
return;
popup.show((Component) e.getSource(), e.getX(), e.getY());
}
/**
* Interfaz MouseListener. Acci�n al entrar en la ventana
*/
public void mouseEntered(MouseEvent e) {
}
/**
* Interfaz MouseListener. Acci�n al salir de la ventana
*/
public void mouseExited(MouseEvent e) {
}
/**
* Interfaz WindowListener. Acci�n al abrir la ventana
*/
public void windowOpened(WindowEvent e) {
}
/**
* Interfaz WindowListener. Acci�n al cerrar la ventana
*/
public void windowClosing(WindowEvent e) {
close();
}
/**
* Interfaz WindowListener. Acci�n al finalizar el cierre
*/
public void windowClosed(WindowEvent e) {
}
/**
* Interfaz WindowListener. Acci�n al minimizar la ventana
*/
public void windowIconified(WindowEvent e) {
}
/**
* Interfaz WindowListener. Acci�n al maximizar la ventana
*/
public void windowDeiconified(WindowEvent e) {
}
/**
* Interfaz WindowListener. Acci�n al activar la ventana
*/
public void windowActivated(WindowEvent e) {
}
/**
* Interfaz WindowListener. Acci�n al desactivar la ventana
*/
public void windowDeactivated(WindowEvent e) {
}
// ----------------------------------------------------------------------------//
// M�TODOS PRIVADOS //
// ----------------------------------------------------------------------------//
/**
* Crea la ventana
*/
private void build() {
String olabel[] = { "Insert new log file", "Insert new plot",
"Edit log file/plot", "Remove log file/plot" };
String ocommand[] = { "InsertLog", "InsertPlot", "Edit", "Remove" };
popup = new JPopupMenu();
JMenuItem item[] = new JMenuItem[ocommand.length];
for (int i = 0; i < ocommand.length; i++) {
item[i] = new JMenuItem(olabel[i]);
item[i].setActionCommand(ocommand[i]);
item[i].addActionListener(this);
item[i].setFont(XConstants.font);
popup.add(item[i]);
}
String modellb[] = { "Plant model", "Simulation limit",
"Initial values" };
String modelcm[] = { "Plant", "Limit", "Init" };
modelform = new XTextForm[3];
for (int i = 0; i < 3; i++) {
modelform[i] = new XTextForm(modellb[i], this);
modelform[i].setActionCommand(modelcm[i]);
modelform[i].setEditable(false);
modelform[i].setFieldWidth(200);
}
XTextForm.setWidth(modelform);
outputlist = new XList("Simulation output");
outputlist.addMouseListener(this);
outputlist.addKeyListener(this);
Box modelbox = new Box(BoxLayout.Y_AXIS);
modelbox.add(new XLabel("Simulation model"));
for (int i = 0; i < modelform.length; i++)
modelbox.add(modelform[i]);
modelbox.add(Box.createVerticalStrut(5));
modelbox.add(outputlist);
String evollb[] = { "Iteration (_n)", "Time (_t)" };
evolform = new XTextForm[2];
for (int i = 0; i < evolform.length; i++) {
evolform[i] = new XTextForm(evollb[i]);
evolform[i].setEditable(false);
evolform[i].setFieldWidth(200);
}
Variable input[] = spec.getSystemModule().getInputs();
plantform = new XTextForm[input.length];
for (int i = 0; i < plantform.length; i++) {
plantform[i] = new XTextForm(input[i].getName());
plantform[i].setEditable(false);
plantform[i].setFieldWidth(200);
}
Variable output[] = spec.getSystemModule().getOutputs();
fuzzyform = new XTextForm[output.length];
for (int i = 0; i < fuzzyform.length; i++) {
fuzzyform[i] = new XTextForm(output[i].getName());
fuzzyform[i].setEditable(false);
fuzzyform[i].setFieldWidth(200);
}
int evollength = evolform.length + plantform.length + fuzzyform.length;
XTextForm tform[] = new XTextForm[evollength];
for (int i = 0; i < evolform.length; i++)
tform[i] = evolform[i];
for (int i = 0; i < plantform.length; i++)
tform[evolform.length + i] = plantform[i];
for (int i = 0; i < fuzzyform.length; i++)
tform[evolform.length + plantform.length + i] = fuzzyform[i];
XTextForm.setWidth(tform);
Box evolbox = new Box(BoxLayout.Y_AXIS);
evolbox.add(new XLabel("Evolution"));
for (int i = 0; i < evolform.length; i++)
evolbox.add(evolform[i]);
evolbox.add(new XLabel("Plant state"));
for (int i = 0; i < plantform.length; i++)
evolbox.add(plantform[i]);
evolbox.add(new XLabel("Fuzzy system output"));
for (int i = 0; i < fuzzyform.length; i++)
evolbox.add(fuzzyform[i]);
evolbox.add(Box.createVerticalGlue());
Box body = new Box(BoxLayout.X_AXIS);
body.add(modelbox);
body.add(Box.createHorizontalStrut(5));
body.add(evolbox);
String formlb[] = { "Load", "Save", "Run", "Reload", "Close" };
commandform = new XCommandForm(formlb, formlb, this);
commandform.setCommandWidth(120);
commandform.block();
Container content = getContentPane();
content.setLayout(new BoxLayout(content, BoxLayout.Y_AXIS));
content
.add(new XLabel("Simulation for specification "
+ spec.getName()));
content.add(body);
content.add(commandform);
setDefaultCloseOperation(WindowConstants.DO_NOTHING_ON_CLOSE);
setIconImage(XfuzzyIcons.xfuzzy.getImage());
addWindowListener(this);
pack();
setLocation();
}
/**
* Devuelve la cadena que representa al n�mero con 6 digitos
*/
private String redondeo(double dd) {
String data = "" + dd;
char[] cdat = data.toCharArray();
int i;
for (i = 0; i < cdat.length; i++)
if (cdat[i] > '0' && cdat[i] <= '9')
break;
for (int j = 0; j < 6 && i < cdat.length; j++, i++)
if (cdat[i] == 'e' || cdat[i] == 'E')
break;
StringBuffer buf = new StringBuffer(data.substring(0, i));
int e = data.indexOf("E");
if (e == -1)
e = data.indexOf("e");
if (e != -1)
buf.append(data.substring(e));
return buf.toString();
}
/**
* Selecciona la clase que desarrolla el modelo de planta
*/
private void plant() {
File wdir = null;
if (config.plantfile != null)
wdir = config.plantfile;
else if (xfuzzy != null)
wdir = xfuzzy.getWorkingDirectory();
else
wdir = new File(System.getProperty("user.dir"));
JFileChooser chooser = new JFileChooser(wdir);
JFileChooserConfig.configure(chooser);
FileNameExtensionFilter filter = new FileNameExtensionFilter(
"Java binary files (.class)", "class");
chooser.setFileFilter(filter);
chooser.setFileSelectionMode(JFileChooser.FILES_ONLY);
chooser.setDialogTitle("Select plant model");
if (chooser.showOpenDialog(null) != JFileChooser.APPROVE_OPTION)
return;
File file = chooser.getSelectedFile();
try {
config.setPlantModel(file);
refreshConfig();
} catch (Exception ex) {
System.out.println(ex.toString());
}
}
/**
* Selecciona los valores iniciales
*/
private void init() {
XfsimInitDialog dialog = new XfsimInitDialog(this);
dialog.setVisible(true);
refreshConfig();
}
/**
* Selecciona las condiciones de termino
*/
private void limit() {
XfsimLimitDialog dialog = new XfsimLimitDialog(this);
dialog.setVisible(true);
refreshConfig();
}
/**
* A�ade una salida al proceso de simulaci�n
*/
private void insertOutput() {
XfsimOutputDialog dialog = new XfsimOutputDialog(this);
dialog.setVisible(true);
}
/**
* Crea un nuevo fichero de almacenamiento hist�rico
*/
private void insertLogfile() {
XfsimLog logfile = new XfsimLog(this);
XfsimLogDialog dialog = new XfsimLogDialog(this, logfile);
dialog.setVisible(true);
if (dialog.getResult()) {
config.output.add(logfile);
refreshConfig();
}
}
/**
* Crea una nueva representaci�n gr�fica
*/
private void insertPlot() {
XfsimPlot plot = new XfsimPlot(this);
XfsimPlotDialog dialog = new XfsimPlotDialog(this, plot);
dialog.setVisible(true);
if (dialog.getResult()) {
config.output.add(plot);
refreshConfig();
}
}
/**
* Elimina una salida del proceso de simulaci�n
*/
private void removeOutput() {
try {
XfsimLog logfile = (XfsimLog) outputlist.getSelectedValue();
config.output.remove(logfile);
refreshConfig();
} catch (Exception ex) {
}
try {
XfsimPlot plot = (XfsimPlot) outputlist.getSelectedValue();
config.output.remove(plot);
refreshConfig();
} catch (Exception ex) {
}
}
/**
* Edita una salida del proceso de simulaci�n
*/
private void editOutput() {
try {
XfsimLog logfile = (XfsimLog) outputlist.getSelectedValue();
XfsimLog tmp = new XfsimLog(this);
tmp.setFile(logfile.getFile());
tmp.setSelection(logfile.getSelection());
XfsimLogDialog dialog = new XfsimLogDialog(this, tmp);
dialog.setVisible(true);
if (!dialog.getResult())
return;
logfile.setFile(tmp.getFile());
logfile.setSelection(tmp.getSelection());
refreshConfig();
} catch (Exception ex) {
}
try {
XfsimPlot plot = (XfsimPlot) outputlist.getSelectedValue();
XfsimPlot tmp = new XfsimPlot(this);
tmp.setVar(plot.getXvar(), plot.getYvar(), plot.getKind());
XfsimPlotDialog dialog = new XfsimPlotDialog(this, tmp);
dialog.setVisible(true);
if (!dialog.getResult())
return;
plot.setVar(tmp.getXvar(), tmp.getYvar(), tmp.getKind());
refreshConfig();
} catch (Exception ex) {
}
}
/**
* Carga la configuraci�n desde un fichero externo
*/
private void load() {
File wdir;
if (xfuzzy != null)
wdir = xfuzzy.getWorkingDirectory();
else
wdir = new File(System.getProperty("user.dir"));
JFileChooser chooser = new JFileChooser(wdir);
JFileChooserConfig.configure(chooser);
FileNameExtensionFilter filter = new FileNameExtensionFilter(
"Xfuzzy configuration files (.cfg)", "cfg");
chooser.setFileFilter(filter);
chooser.setFileSelectionMode(JFileChooser.FILES_ONLY);
chooser.setDialogTitle("Load Configuration");
if (chooser.showOpenDialog(null) != JFileChooser.APPROVE_OPTION)
return;
XfsimConfig old = this.config;
this.config = new XfsimConfig(this);
File file = chooser.getSelectedFile();
XfuzzyConfig xfcparser = new XfuzzyConfig();
if (xfcparser.parseXfsimConfig(this, file))
refreshConfig();
else {
this.config = old;
if (xfuzzy != null)
xfuzzy.log(xfcparser.resume());
else
System.out.println(xfcparser.resume());
Toolkit.getDefaultToolkit().beep();
}
}
/**
* Guarda la configuraci�n en un fichero externo
*/
private void save() {
File wdir;
if (xfuzzy != null)
wdir = xfuzzy.getWorkingDirectory();
else
wdir = new File(System.getProperty("user.dir"));
JFileChooser chooser = new JFileChooser(wdir);
JFileChooserConfig.configure(chooser);
FileNameExtensionFilter filter = new FileNameExtensionFilter(
"Xfuzzy configuration files (.cfg)", "cfg");
chooser.setFileFilter(filter);
chooser.setFileSelectionMode(JFileChooser.FILES_ONLY);
chooser.setDialogTitle("Save Configuration");
if (chooser.showSaveDialog(null) != JFileChooser.APPROVE_OPTION)
return;
File file = chooser.getSelectedFile();
if (file.exists()) {
String question[] = new String[2];
question[0] = "File " + file.getName() + " already exists.";
question[1] = "Do you want to overwrite this file?";
if (!XDialog.showQuestion(this, question))
return;
}
config.save(file);
}
/**
* Ejecuta el proceso de simulacion
*/
private void run() {
if (running == 0) {
running = 1;
setSensitive(1);
config.close();
if (process == null || !process.isAlive())
process = new XfsimProcess(this);
} else if (running == 2) {
running = 1;
setSensitive(1);
} else {
running = 2;
setSensitive(2);
}
}
/**
* Destruye el proceso de simulaci�n e inicializa los campos
*/
private void reload() {
this.running = 3;
if (process != null && process.isAlive()) {
try {
process.join();
} catch (InterruptedException ex) {
}
}
this.process = null;
this.config.close();
for (int i = 0; i < evolform.length; i++)
evolform[i].setText("");
for (int i = 0; i < plantform.length; i++)
plantform[i].setText("");
for (int i = 0; i < fuzzyform.length; i++)
fuzzyform[i].setText("");
refreshConfig();
setSensitive(0);
}
/**
* Cierra la ventana de simulaci�n
*/
private void close() {
if (process != null && process.isAlive()) {
running = 3;
try {
process.join();
} catch (InterruptedException ex) {
}
}
this.config.close();
if (xfuzzy == null)
System.exit(0);
else
setVisible(false);
}
}