diff --git a/src/main/java/ch/psi/mxsc/BasePlate.java b/src/main/java/ch/psi/mxsc/BasePlate.java index e132973..025b120 100644 --- a/src/main/java/ch/psi/mxsc/BasePlate.java +++ b/src/main/java/ch/psi/mxsc/BasePlate.java @@ -154,6 +154,14 @@ public class BasePlate extends DeviceBase { return pucksPosition[puck.index]; } + public Puck getPuckByName(String name) { + for (Device d : getChildren()) { + if (d.getName().equals(name)){ + return (Puck) d; + } + } + return null; + } Rectangle plotRect = new Rectangle(0, 0, 0, 0); Rectangle boundingBox; diff --git a/src/main/java/ch/psi/mxsc/Controller.java b/src/main/java/ch/psi/mxsc/Controller.java index 42bed96..994569f 100644 --- a/src/main/java/ch/psi/mxsc/Controller.java +++ b/src/main/java/ch/psi/mxsc/Controller.java @@ -1,9 +1,9 @@ /* * Copyright (c) 2014 Paul Scherrer Institute. All rights reserved. */ - package ch.psi.mxsc; +import ch.psi.pshell.core.Context; import ch.psi.pshell.core.DevicePoolListener; import ch.psi.pshell.device.Device; import ch.psi.pshell.device.DeviceAdapter; @@ -13,85 +13,88 @@ import ch.psi.pshell.device.ProcessVariableBase; import ch.psi.pshell.device.ReadbackDevice; import ch.psi.pshell.ui.Panel; import ch.psi.utils.State; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import javax.swing.JComponent; /** * */ public class Controller { + static Controller instance; - final BasePlate basePlate; + final BasePlate basePlate; final Panel mainFrame; Device hexaposi; - - public static Controller getInstance(){ + + public static Controller getInstance() { return instance; } - - static void createInstance(Panel mainFrame){ + + static void createInstance(Panel mainFrame) { instance = new Controller(mainFrame); } - - enum PuckSensorAccess{ + + enum PuckSensorAccess { RaspberryPi, Esera; } - - + final PuckSensorAccess puckSensorAccess = PuckSensorAccess.RaspberryPi; - static String PUCK_ESERA_DEVICE = "onewire"; - - public static final int NUMBER_OF_PUCKS = 30; - - private Controller(Panel mainFrame){ + public static final int NUMBER_OF_PUCKS = 30; + + private Controller(Panel mainFrame) { basePlate = new BasePlate(); puckState = new PuckState[NUMBER_OF_PUCKS]; - for (int i=0; iNUMBER_OF_PUCKS)){ - throw new Exception("invalid puck id: "+ id); + public PuckState getPuckState(int id) throws Exception { + if ((id <= 0) || (id > NUMBER_OF_PUCKS)) { + throw new Exception("invalid puck id: " + id); } - return getPuckStates()[id-1]; - } - - public int getPuckIndex(int address) throws Exception{ - if ((address<=0) || (address>NUMBER_OF_PUCKS)){ - throw new Exception("invalid puck address: "+ address); - } - for (int i=0; i NUMBER_OF_PUCKS)) { + throw new Exception("invalid puck address: " + address); + } + for (int i = 0; i < Puck.ADDRESSES.length; i++) { + if (Puck.ADDRESSES[i] == address) { + return i + 1; + } } return -1; } - - public void clearPuckStates(){ - for (PuckState puck:getPuckStates()){ + + public void clearPuckStates() { + for (PuckState puck : getPuckStates()) { puck.clear(); } updateView(); } - - public String getHexiposiPosition(){ - return (String) ((ReadbackDevice)hexaposi).getReadback().take(); + public String getHexiposiPosition() { + return (String) ((ReadbackDevice) hexaposi).getReadback().take(); } - - public Boolean isLedRoomTemp(){ - try{ - return ((ProcessVariableBase)getMainFrame().getDevice("led_ctrl_1")).getConfig().maxValue <= 0.50; - } catch (Exception ex){ + + public Boolean isLedRoomTemp() { + try { + return ((ProcessVariableBase) getMainFrame().getDevice("led_ctrl_1")).getConfig().maxValue <= 0.50; + } catch (Exception ex) { return null; } } - + + public void imageDetectPucks() throws Context.ContextStateException { + imageDetectPucks(null, null, null); + } + + public void imageDetectPucks(JComponent plot, JComponent renderer, JComponent text) throws Context.ContextStateException { + Map args = new HashMap(); + args.put("PLOT", plot); + args.put("RENDERER", renderer); + args.put("TEXT", text); + getMainFrame().runAsync("imgproc/LedDetectionProc", args).handle((ret, ex) -> { + if (ex == null) { + Map> map = (Map>) ret; + for (Puck.ImageDetection id : Puck.ImageDetection.values()) { + for (String name : map.get(id.toString())) { + Puck p = basePlate.getPuckByName(name); + if (p != null) { + p.setImageDetection(id); + } + } + } + } else { + getMainFrame().showException((Exception)ex); + } + return ret; + }); + updateView(); + } + } diff --git a/src/main/java/ch/psi/mxsc/MainPanel.form b/src/main/java/ch/psi/mxsc/MainPanel.form index a205ed4..9122cf6 100644 --- a/src/main/java/ch/psi/mxsc/MainPanel.form +++ b/src/main/java/ch/psi/mxsc/MainPanel.form @@ -84,8 +84,20 @@ - - + + + + + + + + + + + + + + @@ -93,7 +105,11 @@ + + + + @@ -107,6 +123,136 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -179,13 +325,13 @@ - + - + - + diff --git a/src/main/java/ch/psi/mxsc/MainPanel.java b/src/main/java/ch/psi/mxsc/MainPanel.java index 57ed55b..3d8cdc3 100644 --- a/src/main/java/ch/psi/mxsc/MainPanel.java +++ b/src/main/java/ch/psi/mxsc/MainPanel.java @@ -8,14 +8,23 @@ import ch.psi.pshell.core.Context; import ch.psi.pshell.device.Device; import ch.psi.pshell.device.DeviceAdapter; import ch.psi.pshell.device.DeviceListener; +import ch.psi.pshell.imaging.Renderer; +import ch.psi.pshell.imaging.RendererMode; import ch.psi.pshell.imaging.Source; import ch.psi.pshell.ui.Panel; import ch.psi.utils.State; +import ch.psi.utils.swing.SwingUtils; import java.awt.Color; +import java.awt.Component; +import java.awt.Dialog; +import java.awt.Dimension; import java.io.IOException; import java.util.logging.Level; import java.util.logging.Logger; +import java.util.Map; +import java.util.HashMap; import javax.script.ScriptException; +import javax.swing.JComponent; import javax.swing.JFrame; import javax.swing.JPanel; import javax.swing.border.TitledBorder; @@ -132,6 +141,16 @@ public class MainPanel extends Panel { basePlatePanel = new ch.psi.mxsc.BasePlatePanel(); buttonCamera = new javax.swing.JToggleButton(); + buttonPuckDet = new javax.swing.JButton(); + jPanel11 = new javax.swing.JPanel(); + ledLidControlActive2 = new ch.psi.pshell.swing.Led(); + ledLidControlActive1 = new ch.psi.pshell.swing.Led(); + jLabel20 = new javax.swing.JLabel(); + jLabel15 = new javax.swing.JLabel(); + jLabel16 = new javax.swing.JLabel(); + jLabel19 = new javax.swing.JLabel(); + ledLidControlActive4 = new ch.psi.pshell.swing.Led(); + ledLidControlActive3 = new ch.psi.pshell.swing.Led(); jPanel1 = new javax.swing.JPanel(); jPanel3 = new javax.swing.JPanel(); jSeparator1 = new javax.swing.JSeparator(); @@ -191,19 +210,106 @@ public class MainPanel extends Panel { } }); + buttonPuckDet.setText("Detect"); + buttonPuckDet.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + buttonPuckDetActionPerformed(evt); + } + }); + + jPanel11.setBorder(javax.swing.BorderFactory.createTitledBorder("Legend")); + + ledLidControlActive2.setForeground(new java.awt.Color(128, 232, 152)); + ledLidControlActive2.setLedSize(20); + + ledLidControlActive1.setForeground(new java.awt.Color(192, 128, 128)); + ledLidControlActive1.setLedSize(20); + + jLabel20.setText("Empty"); + + jLabel15.setText("Error"); + + jLabel16.setText("Minispine"); + + jLabel19.setText("Unipuck"); + + ledLidControlActive4.setForeground(new java.awt.Color(128, 128, 128)); + ledLidControlActive4.setLedSize(20); + + ledLidControlActive3.setForeground(new java.awt.Color(128, 192, 192)); + ledLidControlActive3.setLedSize(20); + + javax.swing.GroupLayout jPanel11Layout = new javax.swing.GroupLayout(jPanel11); + jPanel11.setLayout(jPanel11Layout); + jPanel11Layout.setHorizontalGroup( + jPanel11Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(jPanel11Layout.createSequentialGroup() + .addContainerGap() + .addGroup(jPanel11Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(jPanel11Layout.createSequentialGroup() + .addComponent(ledLidControlActive1, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(jLabel15)) + .addGroup(jPanel11Layout.createSequentialGroup() + .addComponent(ledLidControlActive2, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(jLabel16)) + .addGroup(jPanel11Layout.createSequentialGroup() + .addComponent(ledLidControlActive3, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(jLabel19)) + .addGroup(jPanel11Layout.createSequentialGroup() + .addComponent(ledLidControlActive4, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(jLabel20))) + .addGap(4, 4, 4)) + ); + jPanel11Layout.setVerticalGroup( + jPanel11Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(jPanel11Layout.createSequentialGroup() + .addGap(0, 0, Short.MAX_VALUE) + .addGroup(jPanel11Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) + .addComponent(ledLidControlActive4, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(jLabel20)) + .addGap(0, 0, 0) + .addGroup(jPanel11Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) + .addComponent(ledLidControlActive3, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(jLabel19)) + .addGap(0, 0, 0) + .addGroup(jPanel11Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) + .addComponent(ledLidControlActive2, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(jLabel16)) + .addGap(0, 0, 0) + .addGroup(jPanel11Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) + .addComponent(ledLidControlActive1, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(jLabel15))) + ); + javax.swing.GroupLayout basePlatePanelLayout = new javax.swing.GroupLayout(basePlatePanel); basePlatePanel.setLayout(basePlatePanelLayout); basePlatePanelLayout.setHorizontalGroup( basePlatePanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addGroup(basePlatePanelLayout.createSequentialGroup() - .addContainerGap(487, Short.MAX_VALUE) - .addComponent(buttonCamera)) + .addGap(4, 4, 4) + .addGroup(basePlatePanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, basePlatePanelLayout.createSequentialGroup() + .addGap(0, 0, Short.MAX_VALUE) + .addGroup(basePlatePanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addComponent(buttonPuckDet) + .addComponent(buttonCamera))) + .addGroup(basePlatePanelLayout.createSequentialGroup() + .addComponent(jPanel11, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addGap(0, 0, Short.MAX_VALUE)))) ); basePlatePanelLayout.setVerticalGroup( basePlatePanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addGroup(basePlatePanelLayout.createSequentialGroup() .addComponent(buttonCamera) - .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(buttonPuckDet) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) + .addComponent(jPanel11, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addContainerGap()) ); jPanel1.setBorder(javax.swing.BorderFactory.createTitledBorder("LN2 Level")); @@ -229,7 +335,7 @@ public class MainPanel extends Panel { .addGap(4, 4, 4) .addGroup(jPanel3Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING, false) .addComponent(jSeparator2) - .addComponent(jLabel3, javax.swing.GroupLayout.DEFAULT_SIZE, 35, Short.MAX_VALUE))) + .addComponent(jLabel3, javax.swing.GroupLayout.PREFERRED_SIZE, 35, Short.MAX_VALUE))) .addGroup(jPanel3Layout.createSequentialGroup() .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) .addComponent(jSeparator3, javax.swing.GroupLayout.PREFERRED_SIZE, 31, javax.swing.GroupLayout.PREFERRED_SIZE)) @@ -247,13 +353,13 @@ public class MainPanel extends Panel { jPanel3Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addGroup(jPanel3Layout.createSequentialGroup() .addGroup(jPanel3Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) - .addComponent(progressLN2, javax.swing.GroupLayout.DEFAULT_SIZE, 653, Short.MAX_VALUE) + .addComponent(progressLN2, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) .addGroup(jPanel3Layout.createSequentialGroup() - .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) + .addContainerGap(56, Short.MAX_VALUE) .addComponent(jSeparator1, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) .addGap(0, 0, 0) .addComponent(jLabel1, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) - .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, 57, Short.MAX_VALUE) .addComponent(jSeparator2, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) .addGap(0, 0, 0) .addComponent(jLabel3, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) @@ -675,12 +781,46 @@ public class MainPanel extends Panel { } }//GEN-LAST:event_buttonExpertActionPerformed + //Dialog dlgDetPlot; + //Dialog dlgDetText; + Dialog dlgDetRenderer; + JComponent dlgDetPlotComp; + JComponent dlgDetTextComp; + JComponent dlgDetRendererComp; + + private void buttonPuckDetActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_buttonPuckDetActionPerformed + try{ + /* + if ((dlgDetPlot == null) || (!dlgDetPlot.isShowing())){ + dlgDetPlotComp = new ch.psi.pshell.plot.LinePlotJFree(); + ((ch.psi.pshell.plot.LinePlotJFree) dlgDetPlotComp).setTitle(""); + dlgDetPlot = SwingUtils.showDialog(getTopLevel(), "Puck Detection", new Dimension(600,400), dlgDetPlotComp); + } + if ((dlgDetText == null)|| (!dlgDetText.isShowing())){ + dlgDetTextComp = new javax.swing.JTextArea(); + ((javax.swing.JTextArea)dlgDetTextComp).setEditable(false); + dlgDetText = SwingUtils.showDialog(getTopLevel(), "Puck Detection", new Dimension(600,400), dlgDetTextComp); + } + */ + if ((dlgDetRenderer == null)|| (!dlgDetRenderer.isShowing())){ + dlgDetRendererComp = new Renderer(); + ((Renderer)dlgDetRendererComp).setMode(RendererMode.Fit); + dlgDetRenderer = SwingUtils.showDialog(getTopLevel(), "Puck Detection", new Dimension(600,400), dlgDetRendererComp); + } + Controller.getInstance().imageDetectPucks(dlgDetPlotComp, dlgDetRendererComp, dlgDetTextComp); + + } catch (Exception ex) { + showException(ex); + } + }//GEN-LAST:event_buttonPuckDetActionPerformed + // Variables declaration - do not modify//GEN-BEGIN:variables private ch.psi.mxsc.BasePlatePanel basePlatePanel; private javax.swing.JToggleButton buttonCamera; private javax.swing.JButton buttonExpert; private javax.swing.JButton buttonInitHexiposi; + private javax.swing.JButton buttonPuckDet; private ch.psi.pshell.swing.DeviceValuePanel deviceValuePanel1; private ch.psi.mxsc.HexiposiPanel hexiposiPanel; private javax.swing.JLabel jLabel1; @@ -689,9 +829,13 @@ public class MainPanel extends Panel { private javax.swing.JLabel jLabel12; private javax.swing.JLabel jLabel13; private javax.swing.JLabel jLabel14; + private javax.swing.JLabel jLabel15; + private javax.swing.JLabel jLabel16; private javax.swing.JLabel jLabel17; private javax.swing.JLabel jLabel18; + private javax.swing.JLabel jLabel19; private javax.swing.JLabel jLabel2; + private javax.swing.JLabel jLabel20; private javax.swing.JLabel jLabel3; private javax.swing.JLabel jLabel4; private javax.swing.JLabel jLabel5; @@ -701,6 +845,7 @@ public class MainPanel extends Panel { private javax.swing.JLabel jLabel9; private javax.swing.JPanel jPanel1; private javax.swing.JPanel jPanel10; + private javax.swing.JPanel jPanel11; private javax.swing.JPanel jPanel2; private javax.swing.JPanel jPanel3; private javax.swing.JPanel jPanel4; @@ -720,6 +865,10 @@ public class MainPanel extends Panel { private ch.psi.pshell.swing.Led ledFillingControl; private ch.psi.pshell.swing.Led ledFillingDewar; private ch.psi.pshell.swing.Led ledLidControlActive; + private ch.psi.pshell.swing.Led ledLidControlActive1; + private ch.psi.pshell.swing.Led ledLidControlActive2; + private ch.psi.pshell.swing.Led ledLidControlActive3; + private ch.psi.pshell.swing.Led ledLidControlActive4; private ch.psi.pshell.swing.Led ledLidInitialized; private ch.psi.pshell.swing.ProcessVariablePanel panelDewar; private javax.swing.JProgressBar progressLN2; diff --git a/src/main/java/ch/psi/mxsc/Puck.java b/src/main/java/ch/psi/mxsc/Puck.java index dbeb40f..cc95568 100644 --- a/src/main/java/ch/psi/mxsc/Puck.java +++ b/src/main/java/ch/psi/mxsc/Puck.java @@ -81,6 +81,24 @@ public class Puck extends DeviceBase { final static Double minispineLedSize = 8.0; final static PointDouble labelPositionWithImage = new PointDouble(0.0, 36.0); + + ImageDetection imageDetection = null; + + public ImageDetection getImageDetection(){ + return imageDetection; + } + + public void setImageDetection(ImageDetection value){ + imageDetection = value; + } + + public enum ImageDetection{ + Empty, + Minispine, + Unipuck, + Error, + } + public double getAngle() { return ANGLES[index]; } @@ -279,7 +297,22 @@ public class Puck extends DeviceBase { ret = isHighlithted() ? new Color(224, 224, 224) : Color.LIGHT_GRAY; break; case Present: - ret = isHighlithted() ? new Color(0, 140, 140) : new Color(128, 192, 192); + if (imageDetection != null){ + switch (imageDetection){ + case Minispine: + ret = isHighlithted() ? new Color(0, 200, 80) : new Color(128, 232, 152); + break; + case Unipuck: + ret = isHighlithted() ? new Color(0, 140, 140) : new Color(128, 192, 192); + break; + case Empty: + case Error: + ret = isHighlithted() ? new Color(192, 10, 10) : new Color(192, 128, 128); + break; + } + } else { + ret = isHighlithted() ? new Color(0, 140, 140) : new Color(128, 192, 192); + } break; case Error: ret = isHighlithted() ? new Color(192, 10, 10) : new Color(192, 128, 128);