diff --git a/config/config.properties b/config/config.properties index a975681..116cb38 100644 --- a/config/config.properties +++ b/config/config.properties @@ -1,4 +1,4 @@ -#Thu Aug 31 17:39:38 CEST 2017 +#Fri Nov 17 14:23:32 CET 2017 autoSaveScanData=true createSessionFiles=false dataLayout=default @@ -8,12 +8,14 @@ dataScanFlushRecords=true dataScanPreserveTypes=false dataScanReleaseRecords=false dataServerPort=-1 +depthDimension=0 hostName=null instanceName=MXSC logDaysToLive=-1 logLevel=Fine logLevelConsole=Off logPath={logs}/{date}_{time} +notificationLevel=null scanStreamerPort=-1 serverEnabled=true serverPort=8080 diff --git a/config/devices.properties b/config/devices.properties index 46828c6..6a06931 100644 --- a/config/devices.properties +++ b/config/devices.properties @@ -1,4 +1,4 @@ -img=ch.psi.pshell.prosilica.Prosilica|25001 ''|||true +img=ch.psi.pshell.prosilica.Prosilica|25001 ''||-100|false microscan=ch.psi.pshell.serial.TcpDevice|129.129.126.200:2001||| microscan_cmd=ch.psi.pshell.serial.TcpDevice|129.129.126.200:2003||| ue=LaserUE|COM4||| diff --git a/config/mail.properties b/config/mail.properties new file mode 100644 index 0000000..e04b672 --- /dev/null +++ b/config/mail.properties @@ -0,0 +1,9 @@ +#Mon Oct 23 10:53:54 CEST 2017 +auth=None +from= +host= +port=0 +pwd= +smsSuffix=@sms.switch.ch +to= +usr= diff --git a/config/plugins.properties b/config/plugins.properties index 59ad112..3f3132e 100644 --- a/config/plugins.properties +++ b/config/plugins.properties @@ -1,3 +1,6 @@ +MXSC-1.8.0.jar=disabled +RobotPanel.java=enabled +Wayne.java=disabled LaserUE.java=enabled MXSC-1.7.0.jar=disabled MXSC-1.6.0.jar=disabled diff --git a/devices/20161117_163816.png.properties b/devices/20161117_163816.png.properties new file mode 100644 index 0000000..be1fd91 --- /dev/null +++ b/devices/20161117_163816.png.properties @@ -0,0 +1,20 @@ +#Mon Oct 23 15:10:20 CEST 2017 +flipHorizontally=false +flipVertically=false +grayscale=false +invert=false +rescaleFactor=1.0 +rescaleOffset=0.0 +roiHeight=-1 +roiWidth=-1 +roiX=0 +roiY=0 +rotation=0.0 +rotationCrop=false +scale=1.0 +spatialCalOffsetX=NaN +spatialCalOffsetY=NaN +spatialCalScaleX=NaN +spatialCalScaleY=NaN +spatialCalUnits=mm +transpose=false diff --git a/devices/img.properties b/devices/img.properties index 303e7da..79e039f 100644 --- a/devices/img.properties +++ b/devices/img.properties @@ -1,4 +1,4 @@ -#Wed Jul 12 15:55:35 CEST 2017 +#Tue Oct 24 14:01:22 CEST 2017 colormap=Grayscale colormapAutomatic=false colormapMax=18.133 @@ -13,7 +13,7 @@ roiHeight=1200 roiWidth=1200 roiX=200 roiY=0 -rotation=140.0 +rotation=0.0 rotationCrop=true scale=1.0 spatialCalOffsetX=-600.0 diff --git a/devices/robot x.properties b/devices/robot x.properties new file mode 100644 index 0000000..02ffbf3 --- /dev/null +++ b/devices/robot x.properties @@ -0,0 +1,9 @@ +#Tue Sep 12 15:00:38 CEST 2017 +maxValue=NaN +minValue=NaN +offset=0.0 +precision=-1 +resolution=NaN +rotation=false +scale=1.0 +unit=null diff --git a/devices/robot_j1.properties b/devices/robot_j1.properties new file mode 100644 index 0000000..0977d42 --- /dev/null +++ b/devices/robot_j1.properties @@ -0,0 +1,9 @@ +#Tue Nov 28 17:23:41 CET 2017 +maxValue=180.0 +minValue=-180.0 +offset=0.0 +precision=2 +resolution=0.1 +rotation=false +scale=1.0 +unit=deg diff --git a/devices/robot_j2.properties b/devices/robot_j2.properties new file mode 100644 index 0000000..00e1ce2 --- /dev/null +++ b/devices/robot_j2.properties @@ -0,0 +1,9 @@ +#Tue Nov 28 17:23:45 CET 2017 +maxValue=127.5 +minValue=-127.5 +offset=0.0 +precision=2 +resolution=0.1 +rotation=false +scale=1.0 +unit=deg diff --git a/devices/robot_j3.properties b/devices/robot_j3.properties new file mode 100644 index 0000000..9ea7576 --- /dev/null +++ b/devices/robot_j3.properties @@ -0,0 +1,9 @@ +#Tue Nov 28 17:23:40 CET 2017 +maxValue=152.5 +minValue=-152.5 +offset=0.0 +precision=2 +resolution=0.1 +rotation=false +scale=1.0 +unit=deg diff --git a/devices/robot_j4.properties b/devices/robot_j4.properties new file mode 100644 index 0000000..0354887 --- /dev/null +++ b/devices/robot_j4.properties @@ -0,0 +1,9 @@ +#Tue Nov 28 17:23:44 CET 2017 +maxValue=270.0 +minValue=-270.0 +offset=0.0 +precision=2 +resolution=0.1 +rotation=false +scale=1.0 +unit=deg diff --git a/devices/robot_j5.properties b/devices/robot_j5.properties new file mode 100644 index 0000000..4bb81fd --- /dev/null +++ b/devices/robot_j5.properties @@ -0,0 +1,9 @@ +#Tue Nov 28 17:23:42 CET 2017 +maxValue=132.5 +minValue=-122.5 +offset=0.0 +precision=2 +resolution=0.1 +rotation=false +scale=1.0 +unit=deg diff --git a/devices/robot_j6.properties b/devices/robot_j6.properties new file mode 100644 index 0000000..54507e0 --- /dev/null +++ b/devices/robot_j6.properties @@ -0,0 +1,9 @@ +#Tue Nov 28 17:23:43 CET 2017 +maxValue=270.0 +minValue=-270.0 +offset=0.0 +precision=2 +resolution=0.1 +rotation=false +scale=1.0 +unit=deg diff --git a/devices/robot_rx.properties b/devices/robot_rx.properties new file mode 100644 index 0000000..69e8d2c --- /dev/null +++ b/devices/robot_rx.properties @@ -0,0 +1,9 @@ +#Thu Nov 23 17:23:52 CET 2017 +maxValue=180.0 +minValue=-180.0 +offset=0.0 +precision=2 +resolution=0.05 +rotation=true +scale=1.0 +unit=deg diff --git a/devices/robot_ry.properties b/devices/robot_ry.properties new file mode 100644 index 0000000..51daa4a --- /dev/null +++ b/devices/robot_ry.properties @@ -0,0 +1,9 @@ +#Thu Nov 23 17:23:32 CET 2017 +maxValue=180.0 +minValue=-180.0 +offset=0.0 +precision=-2 +resolution=0.05 +rotation=true +scale=1.0 +unit=deg diff --git a/devices/robot_rz.properties b/devices/robot_rz.properties new file mode 100644 index 0000000..11604f5 --- /dev/null +++ b/devices/robot_rz.properties @@ -0,0 +1,9 @@ +#Tue Nov 28 16:56:22 CET 2017 +maxValue=360.0 +minValue=-360.0 +offset=0.0 +precision=2 +resolution=0.1 +rotation=true +scale=1.0 +unit=deg diff --git a/devices/robot_x.properties b/devices/robot_x.properties new file mode 100644 index 0000000..4dbffac --- /dev/null +++ b/devices/robot_x.properties @@ -0,0 +1,9 @@ +#Tue Sep 12 15:07:33 CEST 2017 +maxValue=1000.0 +minValue=-1000.0 +offset=0.0 +precision=2 +resolution=0.05 +rotation=false +scale=1.0 +unit=mm diff --git a/devices/robot_y.properties b/devices/robot_y.properties new file mode 100644 index 0000000..4bc4e79 --- /dev/null +++ b/devices/robot_y.properties @@ -0,0 +1,9 @@ +#Tue Sep 12 15:07:33 CEST 2017 +maxValue=1000.0 +minValue=-1000.0 +offset=0.0 +precision=2 +resolution=0.05 +rotation=false +scale=1.0 +unit=null diff --git a/devices/robot_z.properties b/devices/robot_z.properties new file mode 100644 index 0000000..a3126c5 --- /dev/null +++ b/devices/robot_z.properties @@ -0,0 +1,9 @@ +#Tue Sep 12 15:07:32 CEST 2017 +maxValue=1000.0 +minValue=-1000.0 +offset=0.0 +precision=2 +resolution=0.05 +rotation=false +scale=1.0 +unit=null diff --git a/plugins/LaserUE.java b/plugins/LaserUE.java index e733781..ad0c03e 100644 --- a/plugins/LaserUE.java +++ b/plugins/LaserUE.java @@ -1,10 +1,9 @@ +import ch.psi.pshell.device.Readable; import ch.psi.pshell.serial.SerialPortDevice; import ch.psi.pshell.serial.SerialPortDeviceConfig; import static ch.psi.utils.BitMask.*; import java.io.IOException; -import java.util.logging.Level; -import java.util.logging.Logger; /* * @@ -14,40 +13,64 @@ import java.util.logging.Logger; * */ public class LaserUE extends SerialPortDevice{ - + final Readable readable; + static final double RANGE_MIN = 1.0; + static final double RANGE_MAX = 30.0; public LaserUE(String name, String port) { super(name, port, 921600, SerialPortDeviceConfig.DataBits.DB_8, SerialPortDeviceConfig.StopBits.SB_1, SerialPortDeviceConfig.Parity.None); this.setMode(Mode.FullDuplex); + readable = new Readable() { + @Override + public Object read() throws IOException, InterruptedException { + return take(); + } + @Override + public String getName(){ + return LaserUE.this.getName()+"_readout"; + } + }; + } + + @Override + protected void doInitialize() throws IOException, InterruptedException{ + super.doInitialize(); + //TODO: Start DAQ in ILD1320: http://www.micro-epsilon.com/download/manuals/man--optoNCDT-1320--en.pdf + } + + public Readable getReadable(){ + return readable; } int value = 0; int count = 0; - @Override protected void onByte(int rx) { - if (rx<0){ - rx+=256; - rx|=BIT7; - } - System.out.println(rx); int index = ((rx&BIT7) > 0) ? 2 : (((rx&BIT6) > 0) ? 1 : 0); if (count==index){ if (index ==0){ value = rx & 0x3F; + count = 1; } else if (index ==1){ value = ((rx& 0x3F)<<6) + value; + count = 2; } else if (index ==2){ value = ((rx& 0x0F)<<12) + value; - this.setCache(value); + double val = ((double)value)/1000; + if ((valRANGE_MAX)){ + val = Double.NaN; + } + setCache(val); count = 0; } else { count = 0; } } else{ - count = 0; + count = 0; } } + + } diff --git a/plugins/MXSC-1.7.0.jar b/plugins/MXSC-1.7.0.jar index 2325f3b..a4c4d75 100644 Binary files a/plugins/MXSC-1.7.0.jar and b/plugins/MXSC-1.7.0.jar differ diff --git a/plugins/MXSC-1.8.0.jar b/plugins/MXSC-1.8.0.jar new file mode 100644 index 0000000..68d424d Binary files /dev/null and b/plugins/MXSC-1.8.0.jar differ diff --git a/plugins/RobotPanel.form b/plugins/RobotPanel.form new file mode 100644 index 0000000..db2bf43 --- /dev/null +++ b/plugins/RobotPanel.form @@ -0,0 +1,450 @@ + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/plugins/RobotPanel.java b/plugins/RobotPanel.java new file mode 100644 index 0000000..edbd65a --- /dev/null +++ b/plugins/RobotPanel.java @@ -0,0 +1,543 @@ + +import ch.psi.pshell.device.Device; +import ch.psi.pshell.ui.App; +import ch.psi.pshell.swing.DevicePanel; +import ch.psi.pshell.core.Context; +import ch.psi.utils.State; +import java.awt.Color; +import java.lang.reflect.Method; +import java.util.Map; + +/** + * + */ +public class RobotPanel extends DevicePanel { + + /** + * Creates new form RobotPanel + */ + public RobotPanel() { + initComponents(); + } + + @Override + public void setDevice(Device device) { + super.setDevice(device); + if (device == null) { + + } + panelState.setDevice(device); + } + + @Override + protected void onDeviceStateChanged(State state, State former) { + boolean enabled = state.isNormal(); + spinnerSpeed.setEnabled(enabled); + buttonAbort.setEnabled(enabled); + if (!enabled){ + buttonEnable.setEnabled(enabled); + buttonDisable.setEnabled(enabled); + butonStop.setEnabled(enabled); + buttonPause.setEnabled(enabled); + buttonResume.setEnabled(enabled); + } + } + + boolean updating; + @Override + protected void onDeviceCacheChanged(Object value, Object former, long timestamp, boolean valueChange) { + updating = true; + try{ + Boolean powered = null; + Boolean empty = null; + Boolean settled = null; + Boolean moving = null; + Integer speed = null; + String task = null; + String mode = null; + + if ((value != null) && (value instanceof Map)) { + Map status = (Map) value; + try { + powered = (Boolean) status.get("powered"); + } catch (Exception ex) { + } + try { + empty = (Boolean) status.get("empty"); + } catch (Exception ex) { + } + try { + settled = (Boolean) status.get("settled"); + } catch (Exception ex) { + } + try { + speed = (Integer) status.get("speed"); + } catch (Exception ex) { + } + try { + task = ((status.containsKey("task")) && (status.get("task") == null)) ? "" : ((String) status.get("task")).trim(); + } catch (Exception ex) { + System.out.println(ex); + ex.printStackTrace(); + } + try { + mode = ((String) status.get("mode")).trim(); + //mode = (String) Context.getInstance().evalLineBackground(getDevice().getName() + ".working_mode"); + } catch (Exception ex) { + } + try { + //if (status.get("status").equals("hold")){ + // moving = false; + //} else if (status.get("status").equals("move")){ + // moving = true; + //} + moving = Boolean.FALSE.equals(settled) || Boolean.FALSE.equals(empty); + } catch (Exception ex) { + } + } + + boolean remote = mode.equals("remote"); + boolean enabled = Boolean.TRUE.equals(powered); + buttonEnable.setEnabled((powered != null) && (powered == false)); + buttonDisable.setEnabled(enabled); + + butonStop.setEnabled(remote && Boolean.TRUE.equals(moving)); + buttonPause.setEnabled(remote && enabled && Boolean.TRUE.equals(moving) && Boolean.FALSE.equals(settled)); + buttonResume.setEnabled(remote && enabled && Boolean.TRUE.equals(moving) && Boolean.TRUE.equals(settled)); + + + ledPowered.setColor((powered == null) ? Color.GRAY : (powered ? Color.YELLOW : Color.DARK_GRAY)); + ledEmpty.setColor((empty == null) ? Color.GRAY : (empty ? Color.GREEN : Color.YELLOW)); + ledSettled.setColor((settled == null) ? Color.GRAY : (settled ? Color.GREEN : Color.YELLOW)); + ledMoving.setColor((moving == null) ? Color.GRAY : (moving ? Color.YELLOW : Color.DARK_GRAY)); + textTask.setText((task == null) ? "" : task); + ledTask.setColor((task == null) ? Color.GRAY : (task.isEmpty() ? Color.DARK_GRAY : Color.YELLOW)); + //buttonAbort.setEnabled(!textTask.getText().isEmpty()); + spinnerSpeed.setEnabled(speed != null); + if (speed == null) { + spinnerSpeed.setValue(0); + } else { + spinnerSpeed.setValue(speed); + } + ledMode.setColor((mode == null) ? Color.BLACK : (remote ? Color.GREEN : Color.YELLOW)); + textMode.setText((mode == null) ? "" : mode); + + } finally{ + updating = false; + } + } + + /** + * 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. + */ + @SuppressWarnings("unchecked") + // //GEN-BEGIN:initComponents + private void initComponents() { + + jPanel1 = new javax.swing.JPanel(); + ledPowered = new ch.psi.pshell.swing.Led(); + jLabel1 = new javax.swing.JLabel(); + panelPowerCtr = new javax.swing.JPanel(); + buttonDisable = new javax.swing.JButton(); + buttonEnable = new javax.swing.JButton(); + jPanel2 = new javax.swing.JPanel(); + jLabel2 = new javax.swing.JLabel(); + spinnerSpeed = new javax.swing.JSpinner(); + jLabel7 = new javax.swing.JLabel(); + ledMoving = new ch.psi.pshell.swing.Led(); + panelMotionCtr = new javax.swing.JPanel(); + butonStop = new javax.swing.JButton(); + buttonResume = new javax.swing.JButton(); + buttonPause = new javax.swing.JButton(); + jPanel3 = new javax.swing.JPanel(); + jLabel3 = new javax.swing.JLabel(); + ledSettled = new ch.psi.pshell.swing.Led(); + jLabel4 = new javax.swing.JLabel(); + ledEmpty = new ch.psi.pshell.swing.Led(); + textTask = new javax.swing.JTextField(); + jLabel6 = new javax.swing.JLabel(); + textMode = new javax.swing.JTextField(); + buttonAbort = new javax.swing.JButton(); + jLabel8 = new javax.swing.JLabel(); + ledTask = new ch.psi.pshell.swing.Led(); + ledMode = new ch.psi.pshell.swing.Led(); + panelState = new ch.psi.pshell.swing.DeviceStatePanel(); + + jPanel1.setBorder(javax.swing.BorderFactory.createTitledBorder("Power")); + + ledPowered.setFont(new java.awt.Font("SansSerif", 0, 18)); // NOI18N + + jLabel1.setHorizontalAlignment(javax.swing.SwingConstants.TRAILING); + jLabel1.setText("Powered:"); + + buttonDisable.setText("Disable"); + buttonDisable.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + buttonDisableActionPerformed(evt); + } + }); + + buttonEnable.setText("Enable"); + buttonEnable.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + buttonEnableActionPerformed(evt); + } + }); + + javax.swing.GroupLayout panelPowerCtrLayout = new javax.swing.GroupLayout(panelPowerCtr); + panelPowerCtr.setLayout(panelPowerCtrLayout); + panelPowerCtrLayout.setHorizontalGroup( + panelPowerCtrLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(panelPowerCtrLayout.createSequentialGroup() + .addGap(0, 0, 0) + .addComponent(buttonEnable) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, 18, Short.MAX_VALUE) + .addComponent(buttonDisable)) + ); + panelPowerCtrLayout.setVerticalGroup( + panelPowerCtrLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(panelPowerCtrLayout.createSequentialGroup() + .addGap(0, 0, 0) + .addGroup(panelPowerCtrLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING, false) + .addComponent(buttonDisable, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) + .addComponent(buttonEnable)) + .addGap(0, 0, 0)) + ); + + javax.swing.GroupLayout jPanel1Layout = new javax.swing.GroupLayout(jPanel1); + jPanel1.setLayout(jPanel1Layout); + jPanel1Layout.setHorizontalGroup( + jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(jPanel1Layout.createSequentialGroup() + .addContainerGap() + .addComponent(jLabel1, javax.swing.GroupLayout.PREFERRED_SIZE, 52, javax.swing.GroupLayout.PREFERRED_SIZE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(ledPowered, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) + .addComponent(panelPowerCtr, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) + ); + jPanel1Layout.setVerticalGroup( + jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(jPanel1Layout.createSequentialGroup() + .addGap(4, 4, 4) + .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.CENTER) + .addComponent(jLabel1) + .addComponent(ledPowered, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(panelPowerCtr, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addGap(2, 2, 2)) + ); + + jPanel2.setBorder(javax.swing.BorderFactory.createTitledBorder("Motion")); + + jLabel2.setHorizontalAlignment(javax.swing.SwingConstants.TRAILING); + jLabel2.setText("Speed:"); + + spinnerSpeed.setModel(new javax.swing.SpinnerNumberModel(10, null, 100, 1)); + spinnerSpeed.addChangeListener(new javax.swing.event.ChangeListener() { + public void stateChanged(javax.swing.event.ChangeEvent evt) { + spinnerSpeedStateChanged(evt); + } + }); + + jLabel7.setHorizontalAlignment(javax.swing.SwingConstants.TRAILING); + jLabel7.setText("Moving:"); + + ledMoving.setFont(new java.awt.Font("SansSerif", 0, 18)); // NOI18N + + butonStop.setIcon(new javax.swing.ImageIcon(App.class.getResource("/ch/psi/pshell/ui/Stop.png"))); + butonStop.setText(" "); + butonStop.setHorizontalTextPosition(javax.swing.SwingConstants.CENTER); + butonStop.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + butonStopActionPerformed(evt); + } + }); + + buttonResume.setIcon(new javax.swing.ImageIcon(App.class.getResource("/ch/psi/pshell/ui/Play.png"))); + buttonResume.setText(" "); + buttonResume.setHorizontalTextPosition(javax.swing.SwingConstants.CENTER); + buttonResume.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + buttonResumeActionPerformed(evt); + } + }); + + buttonPause.setIcon(new javax.swing.ImageIcon(App.class.getResource("/ch/psi/pshell/ui/Pause.png"))); + buttonPause.setText(" "); + buttonPause.setHorizontalTextPosition(javax.swing.SwingConstants.CENTER); + buttonPause.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + buttonPauseActionPerformed(evt); + } + }); + + javax.swing.GroupLayout panelMotionCtrLayout = new javax.swing.GroupLayout(panelMotionCtr); + panelMotionCtr.setLayout(panelMotionCtrLayout); + panelMotionCtrLayout.setHorizontalGroup( + panelMotionCtrLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(panelMotionCtrLayout.createSequentialGroup() + .addGap(0, 0, 0) + .addComponent(butonStop, javax.swing.GroupLayout.DEFAULT_SIZE, 45, Short.MAX_VALUE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(buttonPause, javax.swing.GroupLayout.DEFAULT_SIZE, 46, Short.MAX_VALUE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(buttonResume, javax.swing.GroupLayout.DEFAULT_SIZE, 47, Short.MAX_VALUE) + .addGap(0, 0, 0)) + ); + panelMotionCtrLayout.setVerticalGroup( + panelMotionCtrLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(panelMotionCtrLayout.createSequentialGroup() + .addGap(0, 0, 0) + .addGroup(panelMotionCtrLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.CENTER) + .addComponent(butonStop, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) + .addComponent(buttonPause, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) + .addComponent(buttonResume, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) + .addGap(0, 0, 0)) + ); + + javax.swing.GroupLayout jPanel2Layout = new javax.swing.GroupLayout(jPanel2); + jPanel2.setLayout(jPanel2Layout); + jPanel2Layout.setHorizontalGroup( + jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(jPanel2Layout.createSequentialGroup() + .addContainerGap() + .addGroup(jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(jPanel2Layout.createSequentialGroup() + .addComponent(jLabel7, javax.swing.GroupLayout.PREFERRED_SIZE, 52, javax.swing.GroupLayout.PREFERRED_SIZE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(ledMoving, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addComponent(jLabel2, javax.swing.GroupLayout.PREFERRED_SIZE, 52, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addGap(14, 14, 14) + .addGroup(jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addComponent(spinnerSpeed, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(panelMotionCtr, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addContainerGap()) + ); + jPanel2Layout.setVerticalGroup( + jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(jPanel2Layout.createSequentialGroup() + .addGap(4, 4, 4) + .addGroup(jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.CENTER) + .addComponent(jLabel7) + .addComponent(ledMoving, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(panelMotionCtr, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addGroup(jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) + .addComponent(jLabel2) + .addComponent(spinnerSpeed, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addGap(2, 2, 2)) + ); + + jPanel3.setBorder(javax.swing.BorderFactory.createTitledBorder("Status")); + + jLabel3.setHorizontalAlignment(javax.swing.SwingConstants.TRAILING); + jLabel3.setText("Settled:"); + + ledSettled.setFont(new java.awt.Font("SansSerif", 0, 18)); // NOI18N + + jLabel4.setHorizontalAlignment(javax.swing.SwingConstants.TRAILING); + jLabel4.setText("Empty:"); + + ledEmpty.setFont(new java.awt.Font("SansSerif", 0, 18)); // NOI18N + + textTask.setEditable(false); + textTask.setHorizontalAlignment(javax.swing.JTextField.CENTER); + + jLabel6.setHorizontalAlignment(javax.swing.SwingConstants.TRAILING); + jLabel6.setText("Mode:"); + + textMode.setEditable(false); + textMode.setHorizontalAlignment(javax.swing.JTextField.CENTER); + + buttonAbort.setText("Abort"); + buttonAbort.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + buttonAbortActionPerformed(evt); + } + }); + + jLabel8.setHorizontalAlignment(javax.swing.SwingConstants.TRAILING); + jLabel8.setText("Task:"); + + ledTask.setFont(new java.awt.Font("SansSerif", 0, 18)); // NOI18N + + ledMode.setFont(new java.awt.Font("SansSerif", 0, 18)); // NOI18N + + javax.swing.GroupLayout jPanel3Layout = new javax.swing.GroupLayout(jPanel3); + jPanel3.setLayout(jPanel3Layout); + jPanel3Layout.setHorizontalGroup( + jPanel3Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(jPanel3Layout.createSequentialGroup() + .addContainerGap() + .addGroup(jPanel3Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(jPanel3Layout.createSequentialGroup() + .addGroup(jPanel3Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(jPanel3Layout.createSequentialGroup() + .addComponent(jLabel8, javax.swing.GroupLayout.PREFERRED_SIZE, 52, javax.swing.GroupLayout.PREFERRED_SIZE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(ledTask, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addGroup(jPanel3Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING) + .addGroup(jPanel3Layout.createSequentialGroup() + .addComponent(jLabel4, javax.swing.GroupLayout.PREFERRED_SIZE, 52, javax.swing.GroupLayout.PREFERRED_SIZE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(ledEmpty, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addGroup(jPanel3Layout.createSequentialGroup() + .addComponent(jLabel3, javax.swing.GroupLayout.PREFERRED_SIZE, 52, javax.swing.GroupLayout.PREFERRED_SIZE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(ledSettled, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)))) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) + .addComponent(textTask)) + .addGroup(jPanel3Layout.createSequentialGroup() + .addComponent(jLabel6, javax.swing.GroupLayout.PREFERRED_SIZE, 52, javax.swing.GroupLayout.PREFERRED_SIZE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(ledMode, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) + .addComponent(textMode))) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(buttonAbort) + .addContainerGap()) + ); + + jPanel3Layout.linkSize(javax.swing.SwingConstants.HORIZONTAL, new java.awt.Component[] {jLabel3, jLabel4, jLabel6, jLabel8}); + + jPanel3Layout.setVerticalGroup( + jPanel3Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, jPanel3Layout.createSequentialGroup() + .addGap(4, 4, 4) + .addGroup(jPanel3Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.CENTER) + .addComponent(jLabel3) + .addComponent(ledSettled, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addGap(2, 2, 2) + .addGroup(jPanel3Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.CENTER) + .addComponent(jLabel4) + .addComponent(ledEmpty, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addGap(2, 2, 2) + .addGroup(jPanel3Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.CENTER) + .addComponent(textMode, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(ledMode, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(jLabel6)) + .addGap(2, 2, 2) + .addGroup(jPanel3Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.CENTER) + .addComponent(buttonAbort) + .addComponent(jLabel8) + .addComponent(ledTask, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(textTask, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addGap(2, 2, 2)) + ); + + javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this); + this.setLayout(layout); + layout.setHorizontalGroup( + layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addComponent(jPanel1, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) + .addComponent(jPanel2, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) + .addComponent(jPanel3, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) + .addComponent(panelState, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) + ); + layout.setVerticalGroup( + layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(layout.createSequentialGroup() + .addComponent(jPanel1, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addGap(0, 0, 0) + .addComponent(jPanel2, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addGap(0, 0, 0) + .addComponent(jPanel3, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addGap(0, 0, 0) + .addComponent(panelState, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) + ); + }// //GEN-END:initComponents + + private void buttonEnableActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_buttonEnableActionPerformed + try{ + Context.getInstance().evalLineBackground(getDevice().getName() + ".enable()"); + } catch (Exception ex){ + this.showException(ex); + } + }//GEN-LAST:event_buttonEnableActionPerformed + + private void buttonDisableActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_buttonDisableActionPerformed + try{ + Context.getInstance().evalLineBackground(getDevice().getName() + ".disable()"); + } catch (Exception ex){ + this.showException(ex); + } + }//GEN-LAST:event_buttonDisableActionPerformed + + private void spinnerSpeedStateChanged(javax.swing.event.ChangeEvent evt) {//GEN-FIRST:event_spinnerSpeedStateChanged + try{ + if (!updating){ + Context.getInstance().evalLineBackground(getDevice().getName() + ".set_monitor_speed(" + spinnerSpeed.getValue() + ")"); + } + } catch (Exception ex){ + this.showException(ex); + } + }//GEN-LAST:event_spinnerSpeedStateChanged + + private void butonStopActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_butonStopActionPerformed + try{ + Context.getInstance().evalLineBackground(getDevice().getName() + ".reset_motion()"); + } catch (Exception ex){ + this.showException(ex); + } + }//GEN-LAST:event_butonStopActionPerformed + + private void buttonPauseActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_buttonPauseActionPerformed + try{ + Context.getInstance().evalLineBackground(getDevice().getName() + ".stop()"); + } catch (Exception ex){ + this.showException(ex); + } + }//GEN-LAST:event_buttonPauseActionPerformed + + private void buttonResumeActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_buttonResumeActionPerformed + try{ + Context.getInstance().evalLineBackground(getDevice().getName() + ".resume()"); + } catch (Exception ex){ + this.showException(ex); + } + }//GEN-LAST:event_buttonResumeActionPerformed + + private void buttonAbortActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_buttonAbortActionPerformed + try{ + Context.getInstance().evalLineBackground(getDevice().getName() + ".stop_task()"); + //Context.getInstance().evalLineBackground(getDevice().getName() + ".task_kill('" + textTask.getText() + "')"); + } catch (Exception ex){ + this.showException(ex); + } + }//GEN-LAST:event_buttonAbortActionPerformed + + + // Variables declaration - do not modify//GEN-BEGIN:variables + private javax.swing.JButton butonStop; + private javax.swing.JButton buttonAbort; + private javax.swing.JButton buttonDisable; + private javax.swing.JButton buttonEnable; + private javax.swing.JButton buttonPause; + private javax.swing.JButton buttonResume; + private javax.swing.JLabel jLabel1; + private javax.swing.JLabel jLabel2; + private javax.swing.JLabel jLabel3; + private javax.swing.JLabel jLabel4; + private javax.swing.JLabel jLabel6; + private javax.swing.JLabel jLabel7; + private javax.swing.JLabel jLabel8; + private javax.swing.JPanel jPanel1; + private javax.swing.JPanel jPanel2; + private javax.swing.JPanel jPanel3; + private ch.psi.pshell.swing.Led ledEmpty; + private ch.psi.pshell.swing.Led ledMode; + private ch.psi.pshell.swing.Led ledMoving; + private ch.psi.pshell.swing.Led ledPowered; + private ch.psi.pshell.swing.Led ledSettled; + private ch.psi.pshell.swing.Led ledTask; + private javax.swing.JPanel panelMotionCtr; + private javax.swing.JPanel panelPowerCtr; + private ch.psi.pshell.swing.DeviceStatePanel panelState; + private javax.swing.JSpinner spinnerSpeed; + private javax.swing.JTextField textMode; + private javax.swing.JTextField textTask; + // End of variables declaration//GEN-END:variables +} diff --git a/plugins/Wayne.form b/plugins/Wayne.form new file mode 100644 index 0000000..f6456c5 --- /dev/null +++ b/plugins/Wayne.form @@ -0,0 +1,46 @@ + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
diff --git a/plugins/Wayne.java b/plugins/Wayne.java new file mode 100644 index 0000000..955c0e5 --- /dev/null +++ b/plugins/Wayne.java @@ -0,0 +1,82 @@ +/* + * Copyright (c) 2014-2017 Paul Scherrer Institute. All rights reserved. + */ + +import ch.psi.pshell.ui.Panel; +import ch.psi.utils.State; +import java.util.logging.Level; +import java.util.logging.Logger; + +/** + * + */ +public class Wayne extends Panel { + + public Wayne() { + initComponents(); + } + + //Overridable callbacks + @Override + public void onInitialize(int runCount) { + + } + + @Override + public void onStateChange(State state, State former) { + + } + + @Override + public void onExecutedFile(String fileName, Object result) { + } + + + //Callback to perform update - in event thread + @Override + protected void doUpdate() { + } + + @SuppressWarnings("unchecked") + // //GEN-BEGIN:initComponents + private void initComponents() { + + jButton1 = new javax.swing.JButton(); + + jButton1.setText("jButton1"); + jButton1.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + jButton1ActionPerformed(evt); + } + }); + + javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this); + this.setLayout(layout); + layout.setHorizontalGroup( + layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(layout.createSequentialGroup() + .addGap(18, 18, 18) + .addComponent(jButton1) + .addContainerGap(358, Short.MAX_VALUE)) + ); + layout.setVerticalGroup( + layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(layout.createSequentialGroup() + .addGap(29, 29, 29) + .addComponent(jButton1) + .addContainerGap(85, Short.MAX_VALUE)) + ); + }// //GEN-END:initComponents + + private void jButton1ActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jButton1ActionPerformed + try { + this.runAsync("test/RobotCartesianScan"); + } catch (Exception ex) { + Logger.getLogger(Wayne.class.getName()).log(Level.SEVERE, null, ex); + } + }//GEN-LAST:event_jButton1ActionPerformed + + // Variables declaration - do not modify//GEN-BEGIN:variables + private javax.swing.JButton jButton1; + // End of variables declaration//GEN-END:variables +} diff --git a/script/calibration/ScanRZ.py b/script/calibration/ScanRZ.py new file mode 100644 index 0000000..acb04c5 --- /dev/null +++ b/script/calibration/ScanRZ.py @@ -0,0 +1,21 @@ +import plotutils +from mathutils import fit_gaussian, Gaussian + +RANGE = [-20.0,20.0] +STEP = 1.0 +LATENCY = 0.005 + +robot.enable() +move_to_laser() + + + + + + +robot.set_motors_enabled(True) +ret = lscan(robot_rz, ue.readable, RANGE[0], RANGE[1], STEP, latency = LATENCY, relative = True, range = "auto") + + + + diff --git a/script/calibration/ScanX.py b/script/calibration/ScanX.py new file mode 100644 index 0000000..71eecb6 --- /dev/null +++ b/script/calibration/ScanX.py @@ -0,0 +1,37 @@ +import plotutils +from mathutils import fit_gaussian, Gaussian + +robot.enable() +move_to_laser() + + +RANGE = [-1.5, 1.5] +STEP = 0.025 +Z_OFFSET = -1.0 +LATENCY = 0.005 + +robot.set_motors_enabled(True) +current_positon = robot_x.getPosition() +robot_z.moveRel(Z_OFFSET) +ret = lscan(robot_x, ue.readable, RANGE[0], RANGE[1], STEP, latency = LATENCY, relative = True) + +d = ret.getReadable(0) + +first_index = -1 +last_index = -1 +for i in range(len(d)): + if not math.isnan(d[i]): + if first_index<0: + first_index = i + last_index = i + +if first_index == -1 or last_index < first_index: + raise Exception("Invalid X detection") + + +center_index = (first_index + last_index)/2 +center_positon = ret.getPositions(0)[center_index] +center_offset = center_positon-current_positon + + +print "X offset = ", center_offset \ No newline at end of file diff --git a/script/calibration/ScanXZ.py b/script/calibration/ScanXZ.py new file mode 100644 index 0000000..96cbcd6 --- /dev/null +++ b/script/calibration/ScanXZ.py @@ -0,0 +1,79 @@ +import plotutils +from mathutils import fit_gaussian, Gaussian + +SINGLE_PASS = False +if SINGLE_PASS: + STEP_SIZE = 0.5 +else: + STEP_SIZE = 1.0 +RANGE = [-5.0, 5.0] +LATENCY = 0.005 + +robot.enable() +move_to_laser() + +step_x = STEP_SIZE +step_z = STEP_SIZE +range_x = [RANGE[0], RANGE[1]] +range_z = [RANGE[0], RANGE[1]] + +robot.set_motors_enabled(True) +current_x = robot_x.getPosition() +current_z = robot_z.getPosition() + +print "Current pos x,z" , current_x, ",", current_z +ret = ascan([robot_x, robot_z], ue.readable, [range_x[0], range_z[0]], [range_x[1], range_z[1]], [step_x,step_z], latency = LATENCY, relative = True , zigzag=False) +data = ret.getData(0)[0] +#plot(Convert.transpose(data), title="Data") + +integ = [] +for x in data: integ.append(sum( [ (0.0 if (math.isnan(y)) else y) for y in x])) + +xdata= frange(range_x[0], range_x[1], step_x , False, True) +p = plot(integ, title = "Fit", xdata=xdata)[0] + + +max_x_index = integ.index(max(integ)) +max_x = xdata[max_x_index] +(normalization, mean_val, sigma) = fit_gaussian(integ, xdata) +gaussian = Gaussian(normalization, mean_val, sigma) +plot_function(p, gaussian, "Fit", xdata, show_points = False, show_lines = True, color = Color.BLUE) + +#So +if abs(mean_val - max_x) > 1.0: + raise Exception("Invalid X detection") +x_offset = mean_val +center_x = current_x + x_offset + +print "X offset = ", x_offset + + +if SINGLE_PASS: + z_scan_data = data[max_x_index] +else: + robot_x.move(center_x) + step_z = step_z/4.0 + ret2 = lscan(robot_z, ue.readable, range_z[0], range_z[1], step_z, latency = LATENCY, relative = True , zigzag=False) + z_scan_data = ret2.getData(0)[0] + +max_z_index= z_scan_data.index(max(z_scan_data)) +last_z_index = 0 +for i in range(len(z_scan_data)): + if not math.isnan(z_scan_data[i]): + last_z_index = i +#Shape is cone: z is inceraseing. For proper detection last Z must be furthest +if abs(max_z_index - last_z_index) * step_z > 1.0: + raise Exception("Invalid Z detection") + +if SINGLE_PASS: + max_z = ret.getPositions(1)[len(data[0]) * max_x_index + last_z_index] +else: + max_z = ret2.getPositions(0)[last_z_index] + +z_offset = max_z-current_z + +print "Z offset = ", z_offset + + +#Updating tool: +#update_tool(None, x_offset=x_offset, z_offset=z_offset) diff --git a/script/calibration/ToolCalibration.py b/script/calibration/ToolCalibration.py new file mode 100644 index 0000000..26e2cac --- /dev/null +++ b/script/calibration/ToolCalibration.py @@ -0,0 +1,42 @@ +import plotutils +from mathutils import fit_gaussian, Gaussian + + +robot.enable() +move_to_laser() +robot.set_motors_enabled(True) + + +initial_pos = robot.get_cartesian_pos() + + + +run("calibration/ScanXZ") + +robot.set_motors_enabled(True) +robot_x.moveRel(x_offset) +robot_z.moveRel(z_offset) + + +initial_x = robot_x.take() +initial_z = robot_z.take() +initial_y = ue.take() +if initial_y is None: + raise Exception("Invalid XZ scan values") + + + + + + +#update_tool(None, x_offset=x_offset, z_offset=z_offset) + +current_x = robot_x.getPosition() +current_y = robot_x.getPosition() +current_z = robot_z.getPosition() + + + +#Updating tool: +#update_tool(None, x_offset=x_offset, z_offset=z_offset) + diff --git a/script/devices/RobotMotors.py b/script/devices/RobotMotors.py new file mode 100644 index 0000000..2b0ad33 --- /dev/null +++ b/script/devices/RobotMotors.py @@ -0,0 +1,73 @@ + +import ch.psi.pshell.device.PositionerConfig as PositionerConfig + + + +ROBOT_MOTORS = ["x" , "y", "z", "rx", "ry", "rz"] + + +class RobotCartesianMotor (PositionerBase): + def __init__(self, robot, index): + PositionerBase.__init__(self, robot.name + "_" + ROBOT_MOTORS[index], PositionerConfig()) + self.index = index + self.robot = robot + + #ATTENTION: Always initialize cartesian motors before scanning (or call robot.set_motors_enabled(True)) + def doInitialize(self): + self.setCache(None, None) + self.setCache(self.doRead(), None) + + def doRead(self): + return float("nan") if self.robot.cartesian_destination is None else float(robot.cartesian_destination[self.index]) + + def doWrite(self, value): + if self.robot.cartesian_destination is not None: + print "Move " + ROBOT_MOTORS[self.index] + " to " + str(value) + self.robot.updating = True + try: + robot.cartesian_destination[self.index] = float(value) + self.robot.set_pnt(robot.cartesian_destination , "tcp_p") + self.robot.movel("tcp_p", self.robot.tool , DESC_SCAN) + except: + self.robot.updating = False + + def doReadReadback(self): + #return float(self.robot.get_cartesian_pos(self._get_tool(),self.frame)[self.index]) + return float("nan") if self.robot.cartesian_pos is None else float(self.robot.cartesian_pos[self.index]) + + + + +ROBOT_JOINT_MOTORS = ["j1" , "j2", "j3", "j4", "j5", "j6"] + + +class RobotJointMotor (PositionerBase): + def __init__(self, robot, index): + PositionerBase.__init__(self, robot.name + "_" + ROBOT_JOINT_MOTORS[index], PositionerConfig()) + self.index = index + self.robot = robot + + def doInitialize(self): + self.setpoint = self.doReadReadback() + self.setCache(self.doRead(), None) + + def doRead(self): + return self.setpoint + + def doWrite(self, value): + print "Move " + ROBOT_JOINT_MOTORS[self.index] + " to " + str(value) + self.setpoint = value + joint = self.robot.herej() + joint[self.index] = value + self.robot.updating = True + try: + self.robot.set_jnt(joint, name="tcp_j") + self.robot.movej("tcp_j", self.robot.tool , DESC_SCAN) + finally: + self.robot.updating = False + + + def doReadReadback(self): + return self.robot.herej()[self.index] if self.robot.joint_pos is None else float(self.robot.joint_pos[self.index]) + + \ No newline at end of file diff --git a/script/devices/RobotSC.py b/script/devices/RobotSC.py index fa809ee..c713e72 100644 --- a/script/devices/RobotSC.py +++ b/script/devices/RobotSC.py @@ -1,9 +1,25 @@ +TOOL_CALIBRATION = "tCalib" +TOOL_SUNA= "tSuna" +TOOL_DEFAULT= TOOL_SUNA + +DESC_FAST = "mFast" +DESC_SLOW = "mSlow" +DESC_SCAN = "mScan" +DESC_DEFAULT = DESC_FAST + + run("devices/RobotTCP") -simulation = True + +simulation = False +joint_forces = False class RobotSC(RobotTCP): + def __init__(self, name, server, timeout = 1000, retries = 1): + RobotTCP.__init__(self, name, server, timeout, retries) + self.tool = TOOL_CALIBRATION + def mount(self, puck, sample): return self.execute('mount',segment, puck, sample) @@ -22,10 +38,11 @@ class RobotSC(RobotTCP): RobotTCP.doUpdate(self) global simulation if not simulation: - if self.state != State.Offline: - self.get_joint_forces() - for dev in [jf1, jf2, jf3, jf4,jf5, jf6, jfc]: - dev.update() + if joint_forces: + if self.state != State.Offline: + self.get_joint_forces() + for dev in [jf1, jf2, jf3, jf4,jf5, jf6, jfc]: + dev.update() #print time.time() -start def start_task(self, program, *args, **kwargs): @@ -35,20 +52,30 @@ class RobotSC(RobotTCP): def stop_task(self): RobotTCP.stop_task(self) #TODO: Restore safe position + + def set_remote_mode(self): + robot.set_profile("remote") + def set_local(self): + robot.set_profile("default") + + def set_tool(self,tool): + if tool != self.tool: + self.tool = tool + for dev in (robot_x, robot_y, robot_z, robot_rx, robot_ry, robot_rz): + dev.initialize() + dev.update() - - if simulation: - add_device(RobotSC("robot","129.129.126.92:1000"),force = True) -#add_device(RobotSC("robot","129.129.126.74:1000"),force = True) + #add_device(RobotSC("robot","129.129.126.92:1000"),force = True) + add_device(RobotSC("robot","129.129.110.99:1000"),force = True) else: - add_device(RobotSC("robot", "129.129.126.100:1000"), force = True) + add_device(RobotSC("robot", "129.129.110.100:1000"), force = True) robot.high_level_tasks = ["mount", "firstmount"] -robot.setPolling(20) +robot.setPolling(500) #robot.set_monitor_speed(20) @@ -79,10 +106,15 @@ class jfc(ReadonlyRegisterBase): return float('NaN') return (robot.joint_forces[1]+74)/4 + (robot.joint_forces[2]+30)/4 + (robot.joint_forces[4]-0.8)/0.2 -add_device(jf1(), force = True) -add_device(jf2(), force = True) -add_device(jf3(), force = True) -add_device(jf4(), force = True) -add_device(jf5(), force = True) -add_device(jf6(), force = True) -add_device(jfc(), force = True) +if joint_forces: + add_device(jf1(), force = True) + add_device(jf2(), force = True) + add_device(jf3(), force = True) + add_device(jf4(), force = True) + add_device(jf5(), force = True) + add_device(jf6(), force = True) + add_device(jfc(), force = True) + + + +""" \ No newline at end of file diff --git a/script/devices/RobotTCP.py b/script/devices/RobotTCP.py index 2260cb2..4738ab8 100644 --- a/script/devices/RobotTCP.py +++ b/script/devices/RobotTCP.py @@ -1,5 +1,10 @@ import threading +FRAME_DEFAULT = "world" + + +run("devices/RobotMotors") + class RobotTCP(TcpDevice, Stoppable): def __init__(self, name, server, timeout = 1000, retries = 1): TcpDevice.__init__(self, name, server) @@ -20,11 +25,36 @@ class RobotTCP(TcpDevice, Stoppable): self.lock = threading.Lock() self.joint_forces = None self.current_task = None - self.high_level_tasks = [] + self.high_level_tasks = [] + self.cartesian_destination = None + self.cartesian_pos = None + self.joint_pos = None + self.cartesian_motors_enabled = False + self.cartesian_motors = [] + self.joint_motors_enabled = False + self.joint_motors = [] + self.tool = None + self.frame = FRAME_DEFAULT + self.updating = False + def doInitialize(self): super(RobotTCP, self).doInitialize() self.reset = True + + + def set_tool(self,tool): + self.tool = tool + if self.cartesian_motors_enabled: + self.cartesian_pos = self.get_cartesian_pos() + for m in self.cartesian_motors: + m.initialize() + m.update() + + + def get_tool(self): + return self.tool + def _sendReceive(self, msg_id, msg = "", timeout = None): tx = self.header if (self.header != None) else "" @@ -106,13 +136,13 @@ class RobotTCP(TcpDevice, Stoppable): for i in range(size): ret.append(float(a[i])); return ret - def get_trf(self, name="tcp_t"): + def get_trsf(self, name="tcp_t"): a = self.execute('get_trf', name) ret = [] for i in range(6): ret.append(float(a[i])) return ret - def set_tr(self, l, name="tcp_t"): + def set_trsf(self, l, name="tcp_t"): self.evaluate(name + "={" + str(l[0]) + ","+ str(l[1]) + ","+ str(l[2]) + ","+ str(l[3]) + ","+ str(l[4]) + ","+ str(l[5]) + "}") def get_jnt(self, name="tcp_j"): @@ -125,10 +155,26 @@ class RobotTCP(TcpDevice, Stoppable): self.evaluate(name + "={" + str(l[0]) + ","+ str(l[1]) + ","+ str(l[2]) + ","+ str(l[3]) + ","+ str(l[4]) + ","+ str(l[5]) + "}") def get_pnt(self, name="tcp_p"): - a = self.execute('get_pnt', name) - ret = [] - for i in range(6): ret.append(float(a[i])) - return ret + #a = self.execute('get_pnt', name) + #ret = [] + #for i in range(6): ret.append(float(a[i])) + #return ret + return self.get_trsf(name+".trsf") + + #trsf = (x,y,z,rx,ry,rz) + #TODO: config = (shoulder, elbow, wrist) + def set_pnt(self, trsf, name="tcp_p", config=None): + self.set_trsf(trsf, name+".trsf") + + def get_tool_trsf(self, name=None): + if name is None: + name = self.tool + return self.get_trsf(name+".trsf") + + def set_tool_trsf(self, trsf, name=None): + if name is None: + name = self.tool + self.set_trsf(trsf, name+".trsf") def eval_int(self, cmd): self.evaluate("tcp_n=" + cmd) @@ -152,7 +198,7 @@ class RobotTCP(TcpDevice, Stoppable): def eval_trf(self, cmd): self.evaluate("tcp_t=" + cmd) - return self.get_trf() + return self.get_trsf() def eval_pnt(self, cmd): self.evaluate("tcp_p=" + cmd) @@ -165,16 +211,19 @@ class RobotTCP(TcpDevice, Stoppable): return self.powered def enable(self): - self.evaluate("enablePower()") if not self.is_powered(): - raise Exception("Cannot enable power") - + self.evaluate("enablePower()") + time.sleep(1.0) + if not self.is_powered(): + raise Exception("Cannot enable power") + #waits for power to be actually cut off def disable(self): self.evaluate("disablePower()", timeout=5000) def get_monitor_speed(self): self.speed = self.eval_int("getMonitorSpeed()") + return self.speed def set_monitor_speed(self, speed): ret = self.eval_int("setMonitorSpeed(" + str(speed) + ")") @@ -185,6 +234,10 @@ class RobotTCP(TcpDevice, Stoppable): def is_calibrated(self): return self.eval_bool("isCalibrated()") + def save_program(self): + ret = self.execute('save', timeout=5000) + if str(ret) != "0": raise Exception("Error saving program: " + str(ret)) + def _update_working_mode(self, mode, status): if mode==1: self.working_mode = "manual" @@ -205,7 +258,7 @@ class RobotTCP(TcpDevice, Stoppable): def read_working_mode(self): try: mode = self.eval_int("workingMode(tcp_a)") - status = int(self.get_var("tcp_a[0]")) + status = int(self.get_var("tcp_a[0]")) self._update_working_mode(mode, status) self._update_state() except: @@ -232,8 +285,8 @@ class RobotTCP(TcpDevice, Stoppable): def resume(self): self.evaluate("restartMove()") - def resetMotion(self): - self.evaluate("resetMotion()") + def reset_motion(self, joint=None): + self.evaluate("resetMotion()" if (joint is None) else ("resetMotion(" + joint + ")")) def is_empty(self): self.empty = self.eval_bool("isEmpty()") @@ -243,7 +296,7 @@ class RobotTCP(TcpDevice, Stoppable): def is_settled(self): self.settled = self.eval_bool("isSettled()") self._update_state() - return self.powered + return self.settled def get_move_id(self): return self.eval_int("getMoveId()") @@ -289,7 +342,7 @@ class RobotTCP(TcpDevice, Stoppable): return self.eval_float("distance(" + trsf1 + ", " + trsf2 + ")") def distance_p(self, pnt1, pnt2): - return self.eval_float("distance(" + pnt1 + ", " + pnt2 + ")") + return self.eval_float("distance(" + pnt1 + ", " + pnt2 + ")") def compose(self, pnt, frame, trsf): return self.eval_pnt("compose(" + pnt + ", " + frame + ", " + trsf + ")") @@ -297,16 +350,24 @@ class RobotTCP(TcpDevice, Stoppable): def here(self, tool, frame): return self.eval_pnt("here(" + tool + ", " + frame + ")") - def joint_to_point(self, tool, frame, joint): + def joint_to_point(self, tool, frame, joint="tcp_j"): return self.eval_pnt("jointToPoint(" + tool + ", " + frame + ", " + joint +")") - def point_to_joint(self, tool, initial_joint, point): + def point_to_joint(self, tool, initial_joint="tcp_j", point="tcp_p"): if self.eval_bool("pointToJoint(" + tool + ", " + initial_joint + ", " + point +", j)"): return self.get_jnt() def position(self, point, frame): return self.eval_trf("position(" + point + ", " + frame + ")") + #Profile + def get_profile(self): + return self.execute('get_profile', timeout=2000) + + def set_profile(self, name, pwd = ""): + self.execute('set_profile', str(name), str(pwd), timeout=5000) + + #Task control def task_create(self, program, *args, **kwargs): program = str(program) @@ -332,7 +393,8 @@ class RobotTCP(TcpDevice, Stoppable): #waits for the task to be actually killed def task_kill(self, name): - self.evaluate('taskKill("' + str(name)+ '")', timeout = 2000) + #self.evaluate('taskKill("' + str(name)+ '")', timeout = 5000) + self.execute('kill', str(name), timeout=5000) def get_task_status(self, name): code = self.eval_int('taskStatus("' + str(name)+ '")') @@ -381,14 +443,83 @@ class RobotTCP(TcpDevice, Stoppable): "speed": self.speed, "empty": self.empty, "settled": self.settled, - "task": self.current_task }, None) - - #print time.time() - start + "task": self.current_task, + "mode": self.working_mode, + "status": self.status + }, None) + if not self.updating: + if self.cartesian_motors_enabled: + self.cartesian_pos = self.get_cartesian_pos() + for m in self.cartesian_motors: + #m.update() + m.readback.update() + else: + self.cartesian_pos = None + if self.joint_motors_enabled: + self.joint_pos = self.herej() + for m in self.joint_motors: + m.readback.update() except: if self.state != State.Offline: print >> sys.stderr, "Update error: " + str(sys.exc_info()[1]) self.setState(State.Offline) + #Cartesian space + + def get_cartesian_pos(self): + return self.eval_pnt("jointToPoint(" + self.tool + ", " + self.frame + ", herej())") + #self.set_jnt(self.herej()) + #return self.joint_to_point(tool, frame) + + def get_cartesian_destination(self): + return self.here(self.tool, self.frame) + + def get_distance_to_pnt(self, name): + #self.here(self.tool, self.frame) #??? + self.get_cartesian_pos() + return self.distance_p("tcp_p", name) + + #Cartesian peudo-motors + def set_motors_enabled(self, value): + if value !=self.cartesian_motors_enabled: + self.cartesian_motors_enabled = value + if value: + for i in range(6): + self.cartesian_motors.append(RobotCartesianMotor(self, i)) + add_device(self.cartesian_motors[i], True) + self.cartesian_destination = self.get_cartesian_destination() + else: + for m in self.cartesian_motors: + remove_device(m) + self.cartesian_motors = [] + self.cartesian_destination = None + else: + if value: + self.cartesian_destination = self.get_cartesian_destination() + for m in self.cartesian_motors: + m.initialize() + + + #Cartesian peudo-motors + def set_joint_motors_enabled(self, value): + if value !=self.joint_motors_enabled: + self.joint_motors_enabled = value + if value: + for i in range(6): + self.joint_motors.append(RobotJointMotor(self, i)) + add_device(self.joint_motors[i], True) + else: + for m in self.joint_motors: + remove_device(m) + self.joint_motors = [] + self.joint_destination = None + else: + if value: + self.joint_destination = self.get_joint_destination() + for m in self.joint_motors: + m.initialize() + + #High-level, exclusive motion task. def start_task(self, program, *args, **kwargs): tasks = [t for t in self.high_level_tasks] @@ -410,8 +541,7 @@ class RobotTCP(TcpDevice, Stoppable): self._update_state() def stop_task(self): - #tasks = [t for t in self.high_level_tasks] - tasks = [] + tasks = [t for t in self.high_level_tasks] if (self.current_task is not None) and (not self.current_task in tasks): tasks.append(self.current_task) for task in tasks: @@ -426,7 +556,7 @@ class RobotTCP(TcpDevice, Stoppable): self.current_task = task return task return None - + def on_event(self,ev): pass diff --git a/script/local.py b/script/local.py index 314bdbf..546724f 100644 --- a/script/local.py +++ b/script/local.py @@ -17,6 +17,7 @@ run("devices/RobotSC") #run("devices/RobotModbus") #run("devices/OneWire") + #Raspberry login: usr=pi pwd=Buntschu add_device(img.getContrast(), force = True) @@ -31,6 +32,12 @@ def set_led_range(room_temp = True): led_ctrl2.config.save() +################################################################################################### +# Motion modules +################################################################################################### + +run("motion/tools") + ################################################################################################### # Barcode reader @@ -155,9 +162,9 @@ def fit(ydata, xdata = None, draw_plot = True): max_y= max(ydata) index_max = ydata.index(max_y) max_x= xdata[index_max] - print "Max index:" + str(index_max), - print " x:" + str(max_x), - print " y:" + str(max_y) + #print "Max index:" + str(index_max), + #print " x:" + str(max_x), + #print " y:" + str(max_y) if draw_plot: plots = plot([ydata],["data"],[xdata], title="Fit" ) @@ -191,12 +198,12 @@ def fit(ydata, xdata = None, draw_plot = True): if abs(mean - xdata[index_max]) < abs((scale_x[0] + scale_x[1])/2): if draw_plot: p.addMarker(mean, None, "Mean="+str(round(mean,4)), Color.MAGENTA.darker()) - print "Mean -> " + str(mean) + #print "Mean -> " + str(mean) return (norm, mean, sigma) else: if draw_plot: p.addMarker(max_x, None, "Max="+str(round(max_x,4)), Color.GRAY) - print "Invalid gaussian fit: " + str(mean) + #print "Invalid gaussian fit: " + str(mean) return (None, None, None) context = get_context() diff --git a/script/motion/tools.py b/script/motion/tools.py new file mode 100644 index 0000000..7706876 --- /dev/null +++ b/script/motion/tools.py @@ -0,0 +1,60 @@ +POSITION_TOLERANCE = 50 + +def wait_end_of_move(): + robot.update() + while (not robot.settled) or (not robot.empty) or (not robot.isReady()) : + time.sleep(0.01) + + +def move_home(): + #robot.reset_motion("jHome") + robot.movej("pHome", robot.tool , DESC_SCAN) + wait_end_of_move() + +def move_to_laser(): + tool = robot.tool + d = robot.get_distance_to_pnt("pLaser") + if d<0: + raise Exception ("Error calculating distance to laser: " + str(d)) + if d