package gui.dialogs.tuningpanels;
import gui.dialogs.tuningpanels.InputDialog.InputData;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.image.BufferedImage;
import java.util.Hashtable;
import java.util.Vector;
import org.eclipse.swt.SWT;
import org.eclipse.swt.custom.CLabel;
import org.eclipse.swt.events.KeyAdapter;
import org.eclipse.swt.events.KeyEvent;
import org.eclipse.swt.events.MouseAdapter;
import org.eclipse.swt.events.MouseEvent;
import org.eclipse.swt.events.MouseMoveListener;
import org.eclipse.swt.events.PaintEvent;
import org.eclipse.swt.events.PaintListener;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.events.ShellAdapter;
import org.eclipse.swt.events.ShellEvent;
import org.eclipse.swt.graphics.GC;
import org.eclipse.swt.graphics.Image;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Canvas;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.swt.widgets.Table;
import org.eclipse.swt.widgets.TableColumn;
import org.eclipse.swt.widgets.TableItem;
import org.eclipse.swt.widgets.Text;
import org.eclipse.swt.widgets.ToolBar;
import org.eclipse.swt.widgets.ToolItem;
import utils.ErrorMessage;
import utils.defines.Defines;
import utils.images.ImageUtils;
import utils.images.RecognizedShape;
import utils.logging.Logger;
import com.cloudgarden.resource.SWTResourceManager;
import components.gps.RecognizedItems;
import components.gps.imagebased.ImageBasedGPS;
import components.imagecollector.ImageCollector;
import components.imagecollector.virtual.VirtualImageCollector;
import components.neuralnetwork.NeuralNetworkException;
import components.robot.Robot;
import components.robot.RobotException;
import core.simulation.Simulation;
/**
* <code>ImageBasedGPSTuner</code> permite configurar un <i>sistema
* de posicionamiento global basado en im�genes</i>.
*/
public class ImageBasedGPSTuner extends GPSTuner
{
private Composite rigthPannel;
private Composite messageArea;
private Composite progressIcons;
private Composite footerButons;
private Composite leftPannel;
private Composite step2Pannel;
private Composite step3Pannel;
private Composite step4Pannel;
private Label separatorHoriz;
private Label separator;
private CLabel cLabel1;
private CLabel title;
private CLabel robotLabel;
private CLabel wallLabel;
private CLabel step1;
private CLabel step2;
private CLabel step3;
private CLabel step4;
private Text hintText;
private Table robotsTable;
private Table iconsTable;
private TableColumn robotColorColumn;
private TableColumn robotNameColumn;
private TableColumn robotStateColumn;
private TableColumn iconColorColumn;
private TableColumn iconIdColumn;
private TableColumn iconCountColumn;
private Canvas canvas;
private Canvas wallColor;
private Button okButton;
private Button backButton;
private Button capturaButton;
private Hashtable robotsHash;
private String[] robotNames;
private GC backgroundGC;
private Image background;
private Image image;
private Dimension resolution;
private int nextStep, currentStep;
private boolean grabbing;
private boolean tuned;
private ImageCollector ic;
private RecognizedItems sceneItems;
// For mouse-selection purposes
private boolean selecting;
private int x , y;
private int w , h;
private ToolItem deleteButton;
private ToolBar toolBar;
public ImageBasedGPSTuner(Shell parent, int style, ImageCollector ic)
{
super(parent, style);
// Dependiendo del tipo de simulaci�n, el asistente comenzar�
// en el paso de captura de imagen (simulaci�n real), o en el
// paso de posicionamiento del robot (simulaci�n virtual).
if ( Simulation.getCurrent().getType() == Defines.REAL_SIMULATION )
nextStep = Defines.GPS_TUNER_CAPTURE_SCENE;
else
nextStep = Defines.GPS_TUNER_SET_ROBOTS;
currentStep = -1;
selecting = false;
resolution = new Dimension(Defines.DEFAULT_IMAGE_RESOLUTION[0] ,
Defines.DEFAULT_IMAGE_RESOLUTION[1] );
background = new org.eclipse.swt.graphics.Image(Display.getDefault() ,
Defines.DEFAULT_IMAGE_RESOLUTION[0] ,
Defines.DEFAULT_IMAGE_RESOLUTION[1] );
backgroundGC = new GC(background);
sceneItems = Simulation.getCurrent().getGps().getMazeItems();
((ImageBasedGPS) Simulation.getCurrent().getGps()).setImageCollector(ic);
this.ic = ic;
}
public synchronized void finalize()
{
background.dispose();
backgroundGC.dispose();
image.dispose();
}
public void open()
{
try
{
tuned = false;
Shell parent = getParent();
dialogShell = new Shell(parent, SWT.DIALOG_TRIM | SWT.APPLICATION_MODAL);
dialogShell.addShellListener( new ShellAdapter()
{
public void shellClosed(ShellEvent evt)
{
close();
}
});
{
//Register as a resource user - SWTResourceManager will
//handle the obtaining and disposing of resources
SWTResourceManager.registerResourceUser(dialogShell);
}
GridLayout dialogShellLayout = new GridLayout();
dialogShell.setLayout(dialogShellLayout);
dialogShellLayout.numColumns = 3;
dialogShellLayout.marginHeight = 0;
dialogShellLayout.marginWidth = 0;
dialogShellLayout.verticalSpacing = 0;
dialogShellLayout.horizontalSpacing = 0;
dialogShell.layout();
dialogShell.pack();
dialogShell.setSize(952, 656);
dialogShell.addShellListener( new ShellAdapter()
{
public void shellClosed(ShellEvent evt)
{
grabbing = false;
((ImageBasedGPS) Simulation.getCurrent().getGps()).disposeImage();
}
});
{
title = new CLabel(dialogShell, SWT.NONE);
title.setText("Configuraci�n GPS Basado en Im�genes");
GridData titleLData = new GridData();
titleLData.horizontalSpan = 3;
title.setLayoutData(titleLData);
title.setImage(SWTResourceManager.getImage("resources/icons/icon32x32/enable/Webcam Configuration.png"));
title.setFont(SWTResourceManager.getFont("Tahoma", 9, 1, false, false));
}
{
separatorHoriz = new Label(dialogShell, SWT.SEPARATOR
| SWT.HORIZONTAL);
GridData separatorHorizLData = new GridData();
separatorHorizLData.horizontalSpan = 3;
separatorHorizLData.horizontalAlignment = GridData.FILL;
separatorHorizLData.grabExcessHorizontalSpace = true;
separatorHoriz.setLayoutData(separatorHorizLData);
}
{
leftPannel = new Composite(dialogShell, SWT.NONE);
GridLayout leftPannelLayout = new GridLayout();
leftPannelLayout.makeColumnsEqualWidth = true;
leftPannelLayout.verticalSpacing = 0;
leftPannelLayout.marginWidth = 0;
leftPannelLayout.horizontalSpacing = 0;
leftPannelLayout.marginHeight = 0;
GridData leftPannelLData = new GridData();
leftPannelLData.heightHint = 480;
leftPannelLData.widthHint = 640;
leftPannelLData.horizontalAlignment = GridData.CENTER;
leftPannel.setLayoutData(leftPannelLData);
leftPannel.setLayout(leftPannelLayout);
leftPannel.setSize(640, 480);
{
GridData canvasLData = new GridData();
canvasLData.horizontalAlignment = GridData.CENTER;
canvasLData.heightHint = (int) resolution.getHeight();
canvasLData.widthHint = (int) resolution.getWidth();
canvas = new Canvas(leftPannel, SWT.NO_BACKGROUND);
GridLayout canvasLayout = new GridLayout();
canvasLayout.makeColumnsEqualWidth = true;
canvas.setLayout(canvasLayout);
canvas.setLayoutData(canvasLData);
canvas.setSize(canvasLData.widthHint, canvasLData.heightHint);
canvas.addPaintListener(new PaintListener() {
public void paintControl(PaintEvent evt) {
canvasPaintControl(evt);
}
});
canvas.addMouseMoveListener(new MouseMoveListener() {
public void mouseMove(MouseEvent evt) {
canvasMouseMove(evt);
}
});
canvas.addMouseListener(new MouseAdapter() {
public void mouseUp(MouseEvent evt) {
canvasMouseUp(evt);
}
public void mouseDown(MouseEvent evt) {
canvasMouseDown(evt);
}
});
}
}
{
GridData separatorLData = new GridData();
separatorLData.verticalAlignment = GridData.FILL;
separatorLData.grabExcessVerticalSpace = true;
separator = new Label(dialogShell, SWT.SEPARATOR);
separator.setLayoutData(separatorLData);
}
{
rigthPannel = new Composite(dialogShell, SWT.NONE);
GridLayout rigthPannelLayout = new GridLayout();
rigthPannelLayout.horizontalSpacing = 0;
rigthPannelLayout.marginWidth = 0;
rigthPannelLayout.marginHeight = 0;
rigthPannelLayout.numColumns = 2;
GridData rigthPannelLData = new GridData();
rigthPannelLData.horizontalAlignment = GridData.FILL;
rigthPannelLData.grabExcessHorizontalSpace = true;
rigthPannelLData.grabExcessVerticalSpace = true;
rigthPannelLData.verticalAlignment = GridData.FILL;
rigthPannel.setLayoutData(rigthPannelLData);
rigthPannel.setLayout(rigthPannelLayout);
{
progressIcons = new Composite(rigthPannel, SWT.NONE);
GridLayout ProgressIconsLayout = new GridLayout();
ProgressIconsLayout.numColumns = 4;
GridData ProgressIconsLData = new GridData();
ProgressIconsLData.horizontalAlignment = GridData.CENTER;
ProgressIconsLData.horizontalSpan = 2;
ProgressIconsLData.grabExcessHorizontalSpace = true;
ProgressIconsLData.widthHint = 180;
ProgressIconsLData.heightHint = 40;
progressIcons.setLayoutData(ProgressIconsLData);
progressIcons.setLayout(ProgressIconsLayout);
{
step1 = new CLabel(progressIcons, SWT.NONE);
step1.setImage(SWTResourceManager.getImage("resources/icons/icon24x24/enable/1-enable.png"));
}
{
step2 = new CLabel(progressIcons, SWT.NONE);
step2.setImage(SWTResourceManager.getImage("resources/icons/icon24x24/disable/2-disable.png"));
step2.setEnabled(false);
}
{
step3 = new CLabel(progressIcons, SWT.NONE);
step3.setImage(SWTResourceManager.getImage("resources/icons/icon24x24/disable/3-disable.png"));
step3.setEnabled(false);
}
{
step4 = new CLabel(progressIcons, SWT.NONE);
step4.setImage(SWTResourceManager.getImage("resources/icons/icon24x24/disable/4-disable.png"));
step4.setEnabled(false);
}
}
{
messageArea = new Composite(rigthPannel, SWT.NONE);
GridLayout messageAreaLayout = new GridLayout();
messageAreaLayout.horizontalSpacing = 0;
messageAreaLayout.marginHeight = 0;
messageAreaLayout.marginWidth = 0;
messageAreaLayout.verticalSpacing = 0;
GridData messageAreaLData = new GridData();
messageAreaLData.horizontalSpan = 2;
messageAreaLData.horizontalAlignment = GridData.CENTER;
messageAreaLData.grabExcessHorizontalSpace = true;
messageAreaLData.widthHint = 280;
messageAreaLData.heightHint = 33;
messageArea.setLayoutData(messageAreaLData);
messageArea.setLayout(messageAreaLayout);
messageArea.setEnabled(false);
{
hintText = new Text(messageArea, SWT.MULTI
| SWT.CENTER
| SWT.READ_ONLY
| SWT.WRAP);
hintText.setText("Una vez que este armado el laberinto, \"Capturar\" una imagen para continuar con la configuraci�n");
GridData hintTestLData = new GridData();
hintTestLData.widthHint = 272;
hintTestLData.heightHint = 31;
hintTestLData.grabExcessHorizontalSpace = true;
hintTestLData.horizontalIndent = 2;
hintTestLData.grabExcessVerticalSpace = true;
hintText.setLayoutData(hintTestLData);
hintText.setBackground(SWTResourceManager.getColor(177, 209, 183));
hintText.setTopIndex(5);
hintText.setTextLimit(120);
hintText.setForeground(SWTResourceManager.getColor(85, 85, 85));
}
}
{
capturaButton = new Button(rigthPannel, SWT.PUSH
| SWT.CENTER);
GridData capturaButtonLData = new GridData();
capturaButtonLData.horizontalSpan = 2;
capturaButtonLData.horizontalAlignment = GridData.CENTER;
capturaButtonLData.grabExcessHorizontalSpace = true;
capturaButtonLData.verticalIndent = 5;
capturaButton.setLayoutData(capturaButtonLData);
capturaButton.setText("Capturar");
capturaButton.addSelectionListener(
new SelectionAdapter()
{
public void widgetSelected(SelectionEvent evt)
{
capturaButtonWidgetSelected(evt);
}
});
}
{
step2Pannel = new Composite(rigthPannel, SWT.NONE);
GridLayout composite2Layout = new GridLayout();
composite2Layout.makeColumnsEqualWidth = true;
GridData composite2LData = new GridData();
composite2LData.horizontalAlignment = GridData.FILL;
composite2LData.verticalAlignment = GridData.FILL;
composite2LData.grabExcessHorizontalSpace = true;
composite2LData.horizontalSpan = 2;
step2Pannel.setLayoutData(composite2LData);
step2Pannel.setLayout(composite2Layout);
{
robotLabel = new CLabel(step2Pannel, SWT.NONE);
robotLabel.setText("Robots de la Escena");
robotLabel
.setImage(SWTResourceManager
.getImage("resources/icons/icon24x24/enable/AIBO210.png"));
}
{
GridData table1LData = new GridData();
table1LData.horizontalAlignment = GridData.FILL;
table1LData.grabExcessHorizontalSpace = true;
table1LData.heightHint = 69;
robotsTable = new Table(step2Pannel, SWT.MULTI | SWT.CHECK);
robotsTable.setLayoutData(table1LData);
robotsTable.setHeaderVisible(true);
robotsTable.setLayoutDeferred(true);
robotsTable.addSelectionListener(new SelectionAdapter() {
public void widgetSelected(SelectionEvent evt) {
}
});
{
robotColorColumn = new TableColumn(robotsTable, SWT.NONE);
robotColorColumn.setText("Color");
robotColorColumn.setWidth(60);
robotColorColumn.setMoveable(true);
robotColorColumn.setAlignment( SWT.CENTER );
}
{
robotNameColumn = new TableColumn(robotsTable, SWT.NONE);
robotNameColumn.setText("Nombre");
robotNameColumn.setWidth(100);
robotNameColumn.setMoveable(true);
robotNameColumn.setAlignment( SWT.CENTER );
}
{
robotStateColumn = new TableColumn(robotsTable, SWT.NONE);
robotStateColumn.setText("Estado");
robotStateColumn.setWidth(100);
robotStateColumn.setMoveable(true);
robotStateColumn.setAlignment( SWT.CENTER );
}
}
}
{
step3Pannel = new Composite(rigthPannel, SWT.NONE);
GridLayout step3PannelLayout = new GridLayout();
step3PannelLayout.makeColumnsEqualWidth = true;
step3PannelLayout.numColumns=2;
GridData step3PannelLData = new GridData();
step3PannelLData.grabExcessHorizontalSpace = true;
step3PannelLData.horizontalAlignment = GridData.FILL;
step3PannelLData.horizontalSpan = 2;
step3Pannel.setLayoutData(step3PannelLData);
step3Pannel.setLayout(step3PannelLayout);
step3Pannel.setVisible(false);
{
cLabel1 = new CLabel(step3Pannel, SWT.NONE);
cLabel1.setText("Iconos Coloreados");
cLabel1
.setImage(SWTResourceManager
.getImage("resources/icons/icon24x24/enable/System-ColorSync.png"));
toolBar = new ToolBar( step3Pannel,SWT.FLAT);
deleteButton = new ToolItem(toolBar,SWT.NONE);
deleteButton.setToolTipText("Eliminar Icono Coloreado");
deleteButton.setImage(SWTResourceManager
.getImage("resources/icons/icon24x24/enable/Trash Empty.png"));
deleteButton.setDisabledImage(SWTResourceManager
.getImage("resources/icons/icon24x24/disable/Trash Empty.png"));
deleteButton.setEnabled(false);
deleteButton.addSelectionListener(new SelectionAdapter() {
public void widgetSelected( SelectionEvent evt) {
deleteButtonWdgetSelected(evt);
}
});
}
{
iconsTable = new Table(step3Pannel, SWT.SINGLE | SWT.FULL_SELECTION);
iconsTable.setHeaderVisible(true);
GridData table2LData = new GridData();
table2LData.horizontalAlignment = GridData.FILL;
table2LData.grabExcessHorizontalSpace = true;
table2LData.heightHint = 69;
table2LData.horizontalSpan=2;
iconsTable.setLayoutData(table2LData);
iconsTable.setEnabled(true);
iconsTable.addKeyListener(new KeyAdapter() {
public void keyPressed(KeyEvent evt) {
iconTableKeyPressed(evt);
}
});
iconsTable.addSelectionListener(new SelectionAdapter() {
public void widgetSelected( SelectionEvent evt) {
deleteButton.setEnabled(true);
}
});
{
iconColorColumn = new TableColumn(iconsTable, SWT.NONE);
iconColorColumn.setMoveable(true);
iconColorColumn.setAlignment( SWT.CENTER );
iconColorColumn.setText("Color");
iconColorColumn.setWidth(90);
}
{
iconIdColumn = new TableColumn(iconsTable, SWT.NONE);
iconIdColumn.setMoveable(true);
iconIdColumn.setAlignment( SWT.CENTER );
iconIdColumn.setText("ID �cono");
iconIdColumn.setWidth(85);
}
{
iconCountColumn = new TableColumn(iconsTable, SWT.NONE);
iconCountColumn.setMoveable(true);
iconCountColumn.setAlignment( SWT.CENTER );
iconCountColumn.setText("Cantidad");
iconCountColumn.setWidth(85);
}
}
}
{
step4Pannel = new Composite(rigthPannel, SWT.NONE);
GridLayout step4PannelLayout = new GridLayout();
step4PannelLayout.numColumns = 2;
GridData step4PannelLData = new GridData();
step4PannelLData.horizontalSpan = 2;
step4PannelLData.horizontalAlignment = GridData.FILL;
step4PannelLData.grabExcessHorizontalSpace = true;
step4Pannel.setLayoutData(step4PannelLData);
step4Pannel.setLayout(step4PannelLayout);
step4Pannel.setVisible(false);
{
wallLabel = new CLabel(step4Pannel, SWT.NONE);
wallLabel.setText("Color de las Paredes");
}
{
wallColor = new Canvas(step4Pannel, SWT.NONE);
GridData wallColorLData = new GridData();
wallColorLData.widthHint = 24;
wallColorLData.heightHint = 24;
wallColor.setLayoutData(wallColorLData);
wallColor.setSize(24, 24);
wallColor.setBackground(SWTResourceManager.getColor(255, 255, 255));
}
}
{
footerButons = new Composite(rigthPannel, SWT.NONE);
GridLayout composite1Layout = new GridLayout();
composite1Layout.makeColumnsEqualWidth = true;
composite1Layout.horizontalSpacing = 0;
composite1Layout.marginHeight = 0;
composite1Layout.marginBottom = 3;
composite1Layout.marginWidth = 0;
composite1Layout.numColumns = 2;
composite1Layout.verticalSpacing = 6;
GridData composite1LData = new GridData();
composite1LData.horizontalSpan = 2;
composite1LData.grabExcessHorizontalSpace = true;
composite1LData.horizontalAlignment = GridData.FILL;
footerButons.setLayoutData(composite1LData);
footerButons.setLayout(composite1Layout);
{
backButton = new Button(footerButons, SWT.PUSH
| SWT.CENTER);
GridData backButtonLData = new GridData();
backButtonLData.widthHint = 75;
backButtonLData.heightHint = 23;
backButtonLData.grabExcessHorizontalSpace = true;
backButtonLData.horizontalAlignment = GridData.CENTER;
backButton.setLayoutData(backButtonLData);
backButton.setText("<< Atr�s");
backButton.setVisible(false);
backButton.addSelectionListener(
new SelectionAdapter()
{
public void widgetSelected(SelectionEvent evt)
{
backButtonWidgetSelected(evt);
}
});
}
}
{
okButton = new Button(footerButons, SWT.PUSH
| SWT.CENTER);
GridData okButtonLData = new GridData();
okButtonLData.horizontalAlignment = GridData.CENTER;
okButtonLData.grabExcessHorizontalSpace = true;
okButton.setLayoutData(okButtonLData);
okButton.setText("Siguiente >>");
okButton.addSelectionListener(
new SelectionAdapter()
{
public void widgetSelected(SelectionEvent evt)
{
okButtonWidgetSelected(evt);
}
});
}
}
robotsHash = new Hashtable(23, 0.75f);
robotNames = new String[Simulation.getCurrent().getRobotArray().size()];
for (int i=0; i<Simulation.getCurrent().getRobotArray().size(); i++)
{
Robot robot = (Robot) Simulation.getCurrent().getRobotArray().get(i);
robotsHash.put( robot.getName() , robot );
robotNames[i] = new String( robot.getName() );
robot.setVisible( false );
}
dialogShell.open();
Display display = dialogShell.getDisplay();
okButtonWidgetSelected( null );
while (!dialogShell.isDisposed()) {
if (!display.readAndDispatch())
display.sleep();
}
}
catch (Exception e)
{
ErrorMessage.customMessage( e.getMessage() , ErrorMessage.ERROR_MESSAGE, getParent() );
}
}
private void beginGrabbing()
{
grabbing = true;
Thread grabbingThread = new Thread( this );
grabbingThread.start();
okButton.setEnabled(false);
capturaButton.setEnabled(true);
}
private void capturaButtonWidgetSelected(SelectionEvent evt)
{
grabbing = false;
okButton.setEnabled(true);
capturaButton.setEnabled(false);
okButtonWidgetSelected(evt);
}
private boolean allRobotRecognized()
{
for (int i=0; i<robotsTable.getItemCount(); i++)
{
TableItem tempItem = robotsTable.getItem(i);
if (tempItem.getChecked() == false)
return false;
}
return true;
}
private void deleteButtonWdgetSelected(SelectionEvent evt) {
deleteButton.setEnabled(false);
int index;
index = iconsTable.getSelectionIndex();
if ( index != -1 )
deleteColorIcon(index);
iconsTable.deselectAll();
}
private void iconTableKeyPressed(KeyEvent evt)
{
int index;
index = iconsTable.getSelectionIndex();
if ( evt.keyCode == SWT.DEL && index != -1 )
deleteColorIcon(index);
iconsTable.deselectAll();
}
private void deleteColorIcon(int index)
{
org.eclipse.swt.graphics.Color color;
TableItem tempItem;
tempItem = iconsTable.getItem(index);
color = tempItem.getBackground(0);
((ImageBasedGPS) Simulation.getCurrent().getGps()).removeRecongnizedColoredIcon( color.getRed() ,
color.getGreen(),
color.getBlue());
iconsTable.remove(index);
// Se renombran los dem�s �conos coloreados.
for (index=0; index<iconsTable.getItemCount(); index++)
{
tempItem = iconsTable.getItem(index);
color = tempItem.getBackground(0);
((ImageBasedGPS) Simulation.getCurrent().getGps()).renameRecongnizedColoredIcon( color.getRed() ,
color.getGreen() ,
color.getBlue() ,
String.valueOf(index+1));
tempItem.setText( 1 , String.valueOf(index+1) );
}
// Se redibuja la imagen, para quitar el contorno obsoleto.
canvas.redraw();
}
/**
* Este m�todo es invocado cuando se seleccion� un �rea
* de la imagen.
*/
protected synchronized void areaSelected()
{
if ( image != null && w!=0 && h!=0 )
{
int auxX, auxY;
if ( w > 0 && h > 0 )
{
auxX = x;
auxY = y;
}
else if ( w < 0 && h > 0 )
{
auxX = x - Math.abs(w);
auxY = y;
}
else if ( w < 0 && h < 0 )
{
auxX = x - Math.abs(w);
auxY = y - Math.abs(h);
}
else
{
auxX = x;
auxY = y - Math.abs(h);
}
int[] averageColor = ImageUtils.getAverageColor(image.getImageData(),
auxX , auxY ,
Math.abs(w) , Math.abs(h) );
org.eclipse.swt.graphics.Color color = new org.eclipse.swt.graphics.Color(
Display.getDefault(), averageColor[0], averageColor[1], averageColor[2]);
try
{
switch ( currentStep )
{
case Defines.GPS_TUNER_SET_ROBOTS:
// Para el caso de reconocimiento de robots
// en simulaciones reales.
robotPositioned(color);
break;
case Defines.GPS_TUNER_SET_ICONS:
InputData data = null;
boolean valid;
do
{
try
{
String[] iconsNames = new String[] { String.valueOf(iconsTable.getItemCount()+1) };
valid = true;
data = ((InputDialog)dialog).open("�cono coloreado", "El �cono coloreado tiene ID:", color, iconsNames);
}
catch (NumberFormatException ex)
{
valid = false;
ErrorMessage.errorMessage(Defines.ERROR_ICON_ID_INVALID, getParent());
}
}
while ( !valid );
if ( data != null && data.textData != null && data.colorData != null )
{
//[EB2] En EasyBot1 se reconoc�an los valores usando algoritmos, nosotros usamos el cuadro recuadrado
// EasyBot1: int count = ((ImageBasedGPS) Simulation.getCurrent().getGps()).recognizeColoredIcons(color.getRed(), color.getGreen(), color.getBlue(), data.textData);
int count = ((ImageBasedGPS) Simulation.getCurrent().getGps()).recognizeColoredIcons(color.getRed(), color.getGreen(), color.getBlue(), data.textData,x,y,w,h);
if ( count == 0 )
{
ErrorMessage.errorMessage(Defines.ERROR_NO_ICON_RECOGNIZED, getParent());
break;
}
TableItem tempItem = new TableItem(iconsTable, SWT.NONE);
tempItem.setBackground(0, color);
tempItem.setText(1, data.textData);
tempItem.setText(2, String.valueOf(count));
}
break;
case Defines.GPS_TUNER_SET_WALLS:
((ImageBasedGPS) Simulation.getCurrent().getGps()).recognizeWalls( color.getRed(), color.getGreen(), color.getBlue() );
wallColor.setBackground( color );
break;
}
}
catch (Exception e)
{
// TODO: handle exception
Logger.error( e.getMessage() );
}
}
}
/**
* Este m�todo es invocado cuando un robot fue posicionado
* sobre la imagen.
*/
protected synchronized void robotPositioned(org.eclipse.swt.graphics.Color c)
{
// Se posicion� un robot. Se abre un di�logo para que el usuario
// elija a qu� robot corresponde dicha posici�n, y que le asigne
// un color asociado.
if ( image != null )
{
InputData data = ((InputDialog)dialog).open("Robot", "Seleccione el robot correspondiente...", c, robotNames);
if ( data != null && data.textData != null && data.colorData != null )
{
Robot robot = (Robot)robotsHash.get( data.textData );
if ( robot == null )
{
Logger.error("Sucedi� lo imposible! No se encontr� el robot en el hash.");
return;
}
robot.setStatus( Defines.STATE_ROBOT_NOT_CALIBRATED );
// Se obtiene una referencia al color previo (en caso de una
// situaci�n de error, se puede restaurar el color previo).
Color prevColor = null;
if ( robot.getColor() != null )
prevColor = new Color( robot.getColor().getRed() ,
robot.getColor().getGreen() ,
robot.getColor().getBlue() );
// Se establece el color del robot
robot.setColor( data.colorData );
Color color = new Color( robot.getColor().getRed() ,
robot.getColor().getGreen() ,
robot.getColor().getBlue() );
if ( ic instanceof VirtualImageCollector )
((VirtualImageCollector)ic).drawRobot( color , new double[] {x,y} );
// Se hace visible
robot.setVisible( true );
// Se cambia el estado a calibrado
robot.setStatus( Defines.STATE_ROBOT_CALIBRATED );
// Se fuerza la actualizaci�n de estado
try
{
robot.updateState();
}
catch (RobotException e)
{
// Se restaura el color previo
if ( prevColor != null )
robot.setColor(
new org.eclipse.swt.graphics.Color( Display.getDefault(),
prevColor.getRed() ,
prevColor.getGreen(),
prevColor.getBlue()));
ErrorMessage.customMessage( e.getMessage() , ErrorMessage.ERROR_MESSAGE , Display.getDefault().getActiveShell());
return;
}
canvas.redraw();
// Se actualizan los �tems en la tabla
robotsTable.removeAll();
for (int i=0; i<Simulation.getCurrent().getRobotArray().size(); i++)
{
robot = (Robot)Simulation.getCurrent().getRobotArray().get(i);
TableItem tableItem = new TableItem(robotsTable, SWT.NONE);
tableItem.setText(1, robot.getName());
if ( robot.getStatus() == Defines.STATE_ROBOT_NOT_CALIBRATED )
{
tableItem.setText(2, robot.getStatusText() );
tableItem.setChecked(false);
tableItem.setImage(2,SWTResourceManager
.getImage("resources/icons/icon16x16/enable/Symbol error.png"));
}
else
{
tableItem.setBackground(0,robot.getColor());
tableItem.setText(2, robot.getStatusText() );
tableItem.setChecked(true);
tableItem.setImage(2,SWTResourceManager
.getImage("resources/icons/icon16x16/enable/Symbol check 2.png"));
}
}
}
}
}
protected synchronized void canvasPaintControl(PaintEvent evt)
{
// Antes de comenzar a dibujar, se borra todo lo anterior.
backgroundGC.setBackground( Display.getDefault().getSystemColor(SWT.COLOR_WHITE) );
backgroundGC.fillRectangle( 0, 0, Defines.DEFAULT_IMAGE_RESOLUTION[0],
Defines.DEFAULT_IMAGE_RESOLUTION[1] );
if ( image != null )
{
// Dibuja la imagen
backgroundGC.drawImage( image, 0, 0);
evt.gc.setForeground( evt.display.getSystemColor(SWT.COLOR_WHITE) );
}
// Dibuja la imagen 'background'
evt.gc.drawImage( background, 0, 0);
if (image != null)
{
// Se dibujan los robots
for (int i=0; i<Simulation.getCurrent().getRobotArray().size(); i++)
{
Robot robot = (Robot) Simulation.getCurrent().getRobotArray().get(i);
if ( robot.isVisible() && robot.getStatus() == Defines.STATE_ROBOT_CALIBRATED )
robot.draw( evt.gc );
}
if ( currentStep == Defines.GPS_TUNER_SET_ICONS || currentStep == Defines.GPS_TUNER_SET_WALLS ||
(currentStep == Defines.GPS_TUNER_SET_ROBOTS && Simulation.getCurrent().getType() == Defines.REAL_SIMULATION) )
{
// Se est� seleccionando un �cono coloreado o una pared, o se est�
// reconociendo un robot en el caso de una simulaci�n real.
evt.gc.drawRectangle(x, y, w, h);
}
// Se dibujan los contornos de los objetos reconocidos
if ( sceneItems != null )
{
evt.gc.setLineStyle( SWT.LINE_DOT );
// Contornos de robots
for (int i=0; i<sceneItems.recognizedRobots.length; i++)
evt.gc.drawPolygon( sceneItems.recognizedRobots[i].getPoints() );
// Contornos de �conos coloreados
for (int i=0; i<sceneItems.recognizedColoredIcons.length; i++)
evt.gc.drawPolygon( sceneItems.recognizedColoredIcons[i].getPoints() );
// Contornos de paredes
for (int i=0; i<sceneItems.recognizedWalls.length; i++)
evt.gc.drawPolygon( sceneItems.recognizedWalls[i].getPoints() );
}
}
}
protected void canvasMouseDown(MouseEvent evt)
{
x = evt.x;
y = evt.y;
w = 0;
h = 0;
selecting = true;
}
protected void canvasMouseMove(MouseEvent evt)
{
if ( selecting )
{
w = evt.x - x;
h = evt.y - y;
canvas.redraw();
}
}
protected void canvasMouseUp(MouseEvent evt)
{
selecting = false;
if ( currentStep == Defines.GPS_TUNER_SET_ROBOTS && Simulation.getCurrent().getType() == Defines.VIRTUAL_SIMULATION )
/* *** Se posicion� un robot (simulaci�n virtual) *** */
robotPositioned(null);
else if ( currentStep == Defines.GPS_TUNER_SET_ROBOTS && Simulation.getCurrent().getType() == Defines.REAL_SIMULATION )
/* *** Se reconoci� un robot (simulaci�n real) *** */
areaSelected();
else
/* *** Se seleccion� un �rea *** */
areaSelected();
w = 0;
h = 0;
canvas.redraw();
}
private synchronized void okButtonWidgetSelected(SelectionEvent evt)
{
currentStep = nextStep;
switch ( nextStep )
{
case Defines.GPS_TUNER_CAPTURE_SCENE:
// PASO 1: Captura de la imagen del escenario.
step1.setImage(SWTResourceManager
.getImage("resources/icons/icon24x24/enable/1-enable.png"));
step2.setImage(SWTResourceManager
.getImage("resources/icons/icon24x24/disable/2-disable.png"));
step3.setImage(SWTResourceManager
.getImage("resources/icons/icon24x24/disable/3-disable.png"));
step4.setImage(SWTResourceManager
.getImage("resources/icons/icon24x24/disable/4-disable.png"));
capturaButton.setEnabled(true);
step2Pannel.setVisible(false); step2Pannel.setEnabled(false);
step3Pannel.setVisible(false); step3Pannel.setEnabled(false);
step4Pannel.setVisible(false); step4Pannel.setEnabled(false);
backButton.setVisible(false);
okButton.setText("Siguiente >>");
hintText.setText("Acomode los objetos en el escenario real, y capture una imagen.");
nextStep = Defines.GPS_TUNER_SET_ROBOTS;
//////////////////// L�GICA PARA EL PASO 1 ////////////////////
beginGrabbing();
///////////////////////////////////////////////////////////////
break;
case Defines.GPS_TUNER_SET_ROBOTS:
// PASO 2: Reconocimiento/posicionamiento de los robots.
step1.setImage(SWTResourceManager
.getImage("resources/icons/icon24x24/disable/1-disable.png"));
step2.setImage(SWTResourceManager
.getImage("resources/icons/icon24x24/enable/2-enable.png"));
step3.setImage(SWTResourceManager
.getImage("resources/icons/icon24x24/disable/3-disable.png"));
step4.setImage(SWTResourceManager
.getImage("resources/icons/icon24x24/disable/4-disable.png"));
capturaButton.setEnabled(false);
step2Pannel.setVisible(true); step2Pannel.setEnabled(false);
step3Pannel.setVisible(false); step3Pannel.setEnabled(false);
step4Pannel.setVisible(false); step4Pannel.setEnabled(false);
if ( Simulation.getCurrent().getType() == Defines.REAL_SIMULATION )
backButton.setVisible(true);
else
backButton.setVisible(false);
okButton.setText("Siguiente >>");
hintText.setText("Haga click sobre la imagen para ubicar el robot.");
nextStep = Defines.GPS_TUNER_SET_ICONS;
//////////////////// L�GICA PARA EL PASO 2 ////////////////////
if ( image == null )
loadImage();
canvas.redraw();
// Se actualizan los �tems en la tabla
robotsTable.removeAll();
for (int i=0; i<Simulation.getCurrent().getRobotArray().size(); i++)
{
Robot robot = (Robot)Simulation.getCurrent().getRobotArray().get(i);
TableItem tableItem = new TableItem(robotsTable, SWT.NONE);
tableItem.setText(1, robot.getName());
if ( robot.getStatus() == Defines.STATE_ROBOT_NOT_CALIBRATED )
{
tableItem.setText(2, robot.getStatusText() );
tableItem.setChecked(false);
tableItem.setImage(2,SWTResourceManager
.getImage("resources/icons/icon16x16/enable/Symbol error.png"));
}
else
{
tableItem.setBackground(0,robot.getColor());
tableItem.setText(2, robot.getStatusText() );
tableItem.setChecked(true);
tableItem.setImage(2,SWTResourceManager
.getImage("resources/icons/icon16x16/enable/Symbol check 2.png"));
}
}
///////////////////////////////////////////////////////////////
break;
case Defines.GPS_TUNER_SET_ICONS:
// PASO 3: Reconocimiento de los �conos coloreados.
if ( !allRobotRecognized() )
{
ErrorMessage.errorMessage(Defines.ERROR_NOT_ALL_ROBOT_RECOGNIZED, getParent());
nextStep = Defines.GPS_TUNER_SET_ROBOTS;
okButtonWidgetSelected(null); // TODO: ojo con esta llamada recursiva!
break;
}
step1.setImage(SWTResourceManager
.getImage("resources/icons/icon24x24/disable/1-disable.png"));
step2.setImage(SWTResourceManager
.getImage("resources/icons/icon24x24/disable/2-disable.png"));
step3.setImage(SWTResourceManager
.getImage("resources/icons/icon24x24/enable/3-enable.png"));
step4.setImage(SWTResourceManager
.getImage("resources/icons/icon24x24/disable/4-disable.png"));
capturaButton.setEnabled(false);
step2Pannel.setVisible(true); step2Pannel.setEnabled(false);
step3Pannel.setVisible(true); step3Pannel.setEnabled(true);
step4Pannel.setVisible(false); step4Pannel.setEnabled(false);
backButton.setVisible(true);
okButton.setText("Siguiente >>");
hintText.setText("Seleccione clickeando y formando un rectangulo sobre todos los iconos coloreados.");
nextStep = Defines.GPS_TUNER_SET_WALLS;
//////////////////// L�GICA PARA EL PASO 3 ////////////////////
step3Pannel.setEnabled(true);
///////////////////////////////////////////////////////////////
break;
case Defines.GPS_TUNER_SET_WALLS:
// PASO 4: Reconocimiento de las paredes.
step1.setImage(SWTResourceManager
.getImage("resources/icons/icon24x24/disable/1-disable.png"));
step2.setImage(SWTResourceManager
.getImage("resources/icons/icon24x24/disable/2-disable.png"));
step3.setImage(SWTResourceManager
.getImage("resources/icons/icon24x24/disable/3-disable.png"));
step4.setImage(SWTResourceManager
.getImage("resources/icons/icon24x24/enable/4-enable.png"));
capturaButton.setEnabled(false);
step2Pannel.setVisible(true); step2Pannel.setEnabled(false);
step3Pannel.setVisible(true); step3Pannel.setEnabled(true);
step4Pannel.setVisible(true); step4Pannel.setEnabled(true);
backButton.setVisible(true);
okButton.setText("Finalizar");
hintText.setText("Seleccione clickeando y formando un rectangulo sobre la pared.");
nextStep = Defines.GPS_TUNER_FINISH;
//////////////////// L�GICA PARA EL PASO 4 ////////////////////
step3Pannel.setEnabled(false);
if (iconsTable.getItemCount() < 1)
ErrorMessage.warningMessage(Defines.WARNING_NO_ICON_RECOGNIZED, getParent());
Simulation.getCurrent().removePlaces();
///////////////////////////////////////////////////////////////
break;
case Defines.GPS_TUNER_FINISH:
// En este punto, ya fueron reconocidos todos los �conos coloreados
// y todas las paredes. Por lo tanto, se ejecuta el proceso para
// averiguar qu� colores son apreciados desde cada lugar (esta
// informaci�n se cargar� en la simulaci�n, para ser utilizada por
// la red neuronal).
RecognizedItems mazeItems = Simulation.getCurrent().getGps().getMazeItems();
boolean resolved = false;
if ( mazeItems != null )
{
// Se corrigen los "puntos de visi�n" de aquellos �conos
// coloreados que as� lo requieran.
RecognizedShape[] icons = mazeItems.recognizedColoredIcons;
for (int i=0; i<icons.length; i++)
{
// Se verifica si el punto de visi�n est� libre.
if ( ! icons[i].contains( icons[i].vx , icons[i].vy ) )
continue;
// El punto de visi�n no est� libre => se lo corrige.
// Para esto, se parte desde el centroide, mirando
// hacia el norte, sur, este y oeste, para detectar
// d�nde no hay pared.
double vxNew;
double vyNew;
double deltaX = Math.abs( icons[i].x - icons[i].bx );
double deltaY = Math.abs( icons[i].y - icons[i].by );
deltaX += Defines.FRONT_SENSOR_DISTANCE;
deltaY += Defines.FRONT_SENSOR_DISTANCE;
boolean free = true;
vxNew = icons[i].x; // NORTE
vyNew = icons[i].y - deltaY;
for (int j=0; free && j<mazeItems.recognizedWalls.length; j++)
if ( mazeItems.recognizedWalls[j].contains(vxNew, vyNew) )
free = false;
if ( ! free )
{
free = true;
vxNew = icons[i].x; // SUR
vyNew = icons[i].y + deltaY;
for (int j=0; free && j<mazeItems.recognizedWalls.length; j++)
if ( mazeItems.recognizedWalls[j].contains(vxNew, vyNew) )
free = false;
}
if ( ! free )
{
free = true;
vxNew = icons[i].x + deltaX; // ESTE
vyNew = icons[i].y;
for (int j=0; free && j<mazeItems.recognizedWalls.length; j++)
if ( mazeItems.recognizedWalls[j].contains(vxNew, vyNew) )
free = false;
}
if ( ! free )
{
free = true;
vxNew = icons[i].x - deltaX; // OESTE
vyNew = icons[i].y;
for (int j=0; free && j<mazeItems.recognizedWalls.length; j++)
if ( mazeItems.recognizedWalls[j].contains(vxNew, vyNew) )
free = false;
}
if ( free )
{
icons[i].vx = vxNew;
icons[i].vy = vyNew;
}
else
{
// Error grave! No hay un punto de
// visi�n libre...
Logger.error(
"Error grave! No hay un punto " +
"de visi�n libre para el �cono " +
"coloreado " + icons[i].shapeId );
}
}
int width = ic.getImageResolution().width;
int height = ic.getImageResolution().height;
for (int i=0; i<icons.length; i++)
{
double vx = icons[i].vx;
double vy = icons[i].vy;
resolved = false;
for (double phi=0.0; phi<2.0*Math.PI; phi+=0.5*Math.PI)
{
// Se recorre la l�nea para ver si choca contra
// una pared o contra otro �cono coloreado.
double x = vx;
double y = vy;
boolean finished1 = false;
boolean finished2 = false;
while ( !finished1 && !finished2 )
{
for (int j=0; !finished1 && j<mazeItems.recognizedWalls.length; j++)
if ( mazeItems.recognizedWalls[j].contains(x, y) )
// Hay una pared
finished1 = true;
for (int j=0; !finished1 && !finished2 && j<mazeItems.recognizedColoredIcons.length; j++)
if ( j != i && mazeItems.recognizedColoredIcons[j].contains(x, y) )
{
// Encontr� un color
int fromPlace = Integer.valueOf(icons[i].shapeId).intValue();
int toPlace = Integer.valueOf(mazeItems.recognizedColoredIcons[j].shapeId).intValue();
Simulation.getCurrent().setPlace( fromPlace , toPlace );
finished2 = true;
resolved = true;
}
x += Defines.STEP_SIZE * Math.cos( phi );
y += Defines.STEP_SIZE * Math.sin( phi );
if ( x < 0 || x > width || y < 0 || y > height )
// Se fue del rango de la imagen...
finished1 = true;
}
}
if ( !resolved )
break;
}
}
// Una vez seteados los lugares, se crea una red neuronal
// para cada robot.
int[][] places = Simulation.getCurrent().getPlaces();
if ( !resolved )
{
ErrorMessage.errorMessage(Defines.ERROR_NO_PLACE_RESOLVED, getParent());
step4.setImage(SWTResourceManager
.getImage("resources/icons/icon24x24/disable/4-disable.png"));
step4Pannel.setVisible(false);
nextStep = Defines.GPS_TUNER_SET_ICONS;
okButtonWidgetSelected(evt);
}
else if ( places == null )
{
ErrorMessage.errorMessage(Defines.ERROR_NO_PLACES_RESOLVED, getParent());
step4.setImage(SWTResourceManager
.getImage("resources/icons/icon24x24/disable/4-disable.png"));
step4Pannel.setVisible(false);
nextStep = Defines.GPS_TUNER_SET_ICONS;
okButtonWidgetSelected(evt);
}
else
{
Simulation.getCurrent().setTargetPlace( places.length );
Vector robots = Simulation.getCurrent().getRobotArray();
for (int i=0; robots!=null && i<robots.size(); i++)
{
try
{
Robot robot = (Robot)robots.get(i);
robot.getNeuralNetwork().setPlaces( places );
}
catch (NeuralNetworkException e)
{
Logger.error( e.getMessage() );
}
}
Simulation.getCurrent().getGps().setCalibrated(true);
tuned = true;
// Finalmente, se cierra el di�logo...
dialogShell.close();
}
}
}
private void backButtonWidgetSelected(SelectionEvent evt)
{
switch ( nextStep )
{
case Defines.GPS_TUNER_SET_ICONS:
nextStep = Defines.GPS_TUNER_CAPTURE_SCENE;
break;
case Defines.GPS_TUNER_SET_WALLS:
robotsTable.removeAll();
nextStep = Defines.GPS_TUNER_SET_ROBOTS;
break;
case Defines.GPS_TUNER_FINISH:
nextStep = Defines.GPS_TUNER_SET_ICONS;
break;
}
okButtonWidgetSelected(evt);
}
protected synchronized int loadImage()
{
if ( dialogShell == null || dialogShell.getDisplay() == null )
return Defines.ERROR;
if ( image != null && !image.isDisposed() )
image.dispose();
BufferedImage awtImage = ((ImageBasedGPS) Simulation.getCurrent().getGps()).getImage();
if ( awtImage != null )
image = new Image( Display.getDefault() , ImageUtils.convertToSWT(awtImage) );
if ( image != null )
return Defines.OK;
else
return Defines.ERROR;
}
public void run()
{
Logger.info( "El calibrador comienza su ejecuci�n." );
while ( grabbing )
{
loadImage();
Display.getDefault().syncExec(
new Runnable()
{
public void run()
{
if ( !canvas.isDisposed() )
canvas.redraw();
}
});
try
{
Thread.sleep( Defines.REFRESH_DELAY );
}
catch (InterruptedException e)
{ }
}
Logger.info( "El calibrador finaliza su ejecuci�n." );
}
public void close()
{
if ( !tuned )
{
// Se cancel� la configuraci�n del GPS.
if ( ic != null && !ic.isClosed() )
ic.close();
}
if ( image != null && !image.isDisposed() )
image.dispose();
if ( image != null )
image = null;
}
}