From 43b46a171fd562186536faec2397da094676c2e2 Mon Sep 17 00:00:00 2001 From: gac-S_Changer Date: Wed, 13 Jun 2018 17:42:33 +0200 Subject: [PATCH] --- config/config.properties | 4 +- config/devices.properties | 4 +- config/plugins.properties | 3 +- devices/led_ctrl_1.properties | 4 +- devices/led_ctrl_2.properties | 4 +- devices/led_ctrl_3.properties | 4 +- plugins/Expert.form | 264 +++++++++++++++--- plugins/Expert.java | 291 +++++++++++++++++--- plugins/{MXSC-1.9.0.jar => MXSC-1.10.0.jar} | Bin 74338 -> 79211 bytes script/{ => calibration}/HillClimbingXZ.py | 0 script/devices/Hexiposi.py | 11 +- script/devices/RobotSC.py | 32 ++- script/devices/RobotTCP.py | 15 +- script/local.py | 15 +- script/motion/dry.py | 55 ++++ script/motion/mount.py | 2 +- script/motion/move_dewar.py | 18 ++ script/motion/move_gonio.py | 18 ++ script/motion/move_heater.py | 18 ++ script/motion/move_home.py | 18 ++ script/motion/move_park.py | 18 ++ script/motion/move_scanner.py | 18 ++ 22 files changed, 707 insertions(+), 109 deletions(-) rename plugins/{MXSC-1.9.0.jar => MXSC-1.10.0.jar} (53%) rename script/{ => calibration}/HillClimbingXZ.py (100%) create mode 100644 script/motion/dry.py create mode 100644 script/motion/move_dewar.py create mode 100644 script/motion/move_gonio.py create mode 100644 script/motion/move_heater.py create mode 100644 script/motion/move_home.py create mode 100644 script/motion/move_park.py create mode 100644 script/motion/move_scanner.py diff --git a/config/config.properties b/config/config.properties index c0aa27e..12dbfc1 100644 --- a/config/config.properties +++ b/config/config.properties @@ -1,6 +1,6 @@ -#Mon Mar 19 11:35:49 CET 2018 +#Wed Jun 13 10:31:31 CEST 2018 autoSaveScanData=true -createSessionFiles=false +createSessionFiles=true dataLayout=default dataPath={data}/{year}_{month}/{date}/{date}_{time}_{name} dataProvider=h5 diff --git a/config/devices.properties b/config/devices.properties index d9d1e32..37a20a1 100644 --- a/config/devices.properties +++ b/config/devices.properties @@ -1,6 +1,6 @@ img=ch.psi.pshell.prosilica.Prosilica|25001 "PacketSize=1522;PixelFormat=Mono8;BinningX=1;BinningY=1;RegionX=300;RegionY=200;Width=1000;Height=1000"|||false -microscan=ch.psi.pshell.serial.TcpDevice|129.129.126.200:2001||| -microscan_cmd=ch.psi.pshell.serial.TcpDevice|129.129.126.200:2003||| +microscan=ch.psi.pshell.serial.TcpDevice|129.129.100.200:2001||| +microscan_cmd=ch.psi.pshell.serial.TcpDevice|129.129.100.200:2003||| ue=LaserUE|COM4|||false #robot=RobotTcp|127.0.0.1:1000||| #onewire=ch.psi.pshell.serial.TcpDevice|129.129.126.83:5000||| diff --git a/config/plugins.properties b/config/plugins.properties index 864a15d..ef1ef6c 100644 --- a/config/plugins.properties +++ b/config/plugins.properties @@ -1,5 +1,6 @@ +MXSC-1.10.0.jar=enabled +NewJPanel.java=disabled Expert.java=disabled -MXSC-1.9.0.jar=enabled RobotPanel.java=enabled Wayne.java=disabled LaserUE.java=enabled diff --git a/devices/led_ctrl_1.properties b/devices/led_ctrl_1.properties index d9e6c8d..8019e7b 100644 --- a/devices/led_ctrl_1.properties +++ b/devices/led_ctrl_1.properties @@ -1,5 +1,5 @@ -#Fri May 04 16:52:30 CEST 2018 -maxValue=0.4 +#Wed Jun 13 09:47:55 CEST 2018 +maxValue=1.2 minValue=0.0 offset=0.0 precision=2 diff --git a/devices/led_ctrl_2.properties b/devices/led_ctrl_2.properties index d9e6c8d..8019e7b 100644 --- a/devices/led_ctrl_2.properties +++ b/devices/led_ctrl_2.properties @@ -1,5 +1,5 @@ -#Fri May 04 16:52:30 CEST 2018 -maxValue=0.4 +#Wed Jun 13 09:47:55 CEST 2018 +maxValue=1.2 minValue=0.0 offset=0.0 precision=2 diff --git a/devices/led_ctrl_3.properties b/devices/led_ctrl_3.properties index d9e6c8d..8019e7b 100644 --- a/devices/led_ctrl_3.properties +++ b/devices/led_ctrl_3.properties @@ -1,5 +1,5 @@ -#Fri May 04 16:52:30 CEST 2018 -maxValue=0.4 +#Wed Jun 13 09:47:55 CEST 2018 +maxValue=1.2 minValue=0.0 offset=0.0 precision=2 diff --git a/plugins/Expert.form b/plugins/Expert.form index 4f3ad8c..87a47c3 100644 --- a/plugins/Expert.form +++ b/plugins/Expert.form @@ -18,17 +18,16 @@ - - - - - - - + + + + + + - + @@ -36,8 +35,8 @@ - - + + @@ -46,9 +45,11 @@ + + - + @@ -67,12 +68,11 @@ - - - - - - + + + + + @@ -80,9 +80,10 @@ - - - + + + + @@ -227,20 +228,43 @@ - + - - - - - - - - + + + + + + + + + + + - - - + + + + + + + + + + + + + + + + + + + + + + + @@ -257,16 +281,43 @@ - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -340,7 +391,7 @@ - + @@ -428,6 +479,14 @@ + + + + + + + + @@ -436,6 +495,78 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -453,9 +584,9 @@ - + - + @@ -502,5 +633,58 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/plugins/Expert.java b/plugins/Expert.java index b2c63ad..8868b86 100644 --- a/plugins/Expert.java +++ b/plugins/Expert.java @@ -114,11 +114,25 @@ public class Expert extends Panel { jLabel2 = new javax.swing.JLabel(); spinnerSegment = new javax.swing.JSpinner(); jLabel3 = new javax.swing.JLabel(); + buttonMovePark = new javax.swing.JButton(); buttonHomingHexiposi = new javax.swing.JButton(); + buttonMoveHome = new javax.swing.JButton(); + buttonMoveGonio = new javax.swing.JButton(); + buttonMoveDewar = new javax.swing.JButton(); + buttonMoveScanner = new javax.swing.JButton(); + buttonMoveHeater = new javax.swing.JButton(); + buttonDry = new javax.swing.JButton(); + spinnerDryTime = new javax.swing.JSpinner(); + jLabel6 = new javax.swing.JLabel(); + jLabel7 = new javax.swing.JLabel(); + spinnerDrySpeed = new javax.swing.JSpinner(); jPanel3 = new javax.swing.JPanel(); buttonPuckDetCheck = new javax.swing.JButton(); buttonPuckDetStop = new javax.swing.JButton(); buttonPuckDetStart = new javax.swing.JButton(); + panelRobot1 = new javax.swing.JPanel(); + buttonHeater = new javax.swing.JToggleButton(); + buttonStream = new javax.swing.JToggleButton(); panelRobot.setBorder(javax.swing.BorderFactory.createTitledBorder("Robot")); @@ -141,11 +155,11 @@ public class Expert extends Panel { panelRobotLayout.setHorizontalGroup( panelRobotLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addGroup(panelRobotLayout.createSequentialGroup() - .addContainerGap(78, Short.MAX_VALUE) - .addGroup(panelRobotLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) - .addComponent(buttonEnable) - .addComponent(buttonDisable)) - .addContainerGap(79, Short.MAX_VALUE)) + .addContainerGap(32, Short.MAX_VALUE) + .addComponent(buttonEnable) + .addGap(27, 27, 27) + .addComponent(buttonDisable) + .addContainerGap(32, Short.MAX_VALUE)) ); panelRobotLayout.linkSize(javax.swing.SwingConstants.HORIZONTAL, new java.awt.Component[] {buttonDisable, buttonEnable}); @@ -154,9 +168,9 @@ public class Expert extends Panel { panelRobotLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addGroup(panelRobotLayout.createSequentialGroup() .addContainerGap() - .addComponent(buttonEnable) - .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) - .addComponent(buttonDisable) + .addGroup(panelRobotLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) + .addComponent(buttonEnable) + .addComponent(buttonDisable)) .addContainerGap()) ); @@ -312,7 +326,7 @@ public class Expert extends Panel { .addComponent(spinnerSample, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) .addComponent(spinnerPuck, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) .addComponent(spinnerSegment, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) - .addContainerGap()) + .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) ); jPanel5Layout.linkSize(javax.swing.SwingConstants.HORIZONTAL, new java.awt.Component[] {jLabel1, jLabel2, jLabel3}); @@ -341,6 +355,13 @@ public class Expert extends Panel { .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) ); + buttonMovePark.setText("Move Park"); + buttonMovePark.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + buttonMoveParkActionPerformed(evt); + } + }); + buttonHomingHexiposi.setText("Homing Hexiposi"); buttonHomingHexiposi.addActionListener(new java.awt.event.ActionListener() { public void actionPerformed(java.awt.event.ActionEvent evt) { @@ -348,24 +369,95 @@ public class Expert extends Panel { } }); + buttonMoveHome.setText("Move Home"); + buttonMoveHome.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + buttonMoveHomeActionPerformed(evt); + } + }); + + buttonMoveGonio.setText("Move Gonio"); + buttonMoveGonio.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + buttonMoveGonioActionPerformed(evt); + } + }); + + buttonMoveDewar.setText("Move Dewar"); + buttonMoveDewar.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + buttonMoveDewarActionPerformed(evt); + } + }); + + buttonMoveScanner.setText("Move Scanner"); + buttonMoveScanner.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + buttonMoveScannerActionPerformed(evt); + } + }); + + buttonMoveHeater.setText("Move Heater"); + buttonMoveHeater.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + buttonMoveHeaterActionPerformed(evt); + } + }); + + buttonDry.setText("Dry"); + buttonDry.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + buttonDryActionPerformed(evt); + } + }); + + spinnerDryTime.setModel(new javax.swing.SpinnerNumberModel(10.0d, 1.0d, 30.0d, 1.0d)); + + jLabel6.setText("Heat time(s):"); + + jLabel7.setText("Speed(%):"); + + spinnerDrySpeed.setModel(new javax.swing.SpinnerNumberModel(1.0d, 0.1d, 10.0d, 1.0d)); + javax.swing.GroupLayout panelCommandsLayout = new javax.swing.GroupLayout(panelCommands); panelCommands.setLayout(panelCommandsLayout); panelCommandsLayout.setHorizontalGroup( panelCommandsLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addGroup(panelCommandsLayout.createSequentialGroup() .addContainerGap() - .addGroup(panelCommandsLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING, false) - .addComponent(buttonHomingHexiposi, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) - .addComponent(buttonGetGonio, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) - .addComponent(buttonPutGonio, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) - .addComponent(buttonMount, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) - .addComponent(buttonUnmount, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) - .addComponent(buttonGetDewar, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) - .addComponent(buttonPutDewar, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) - .addGap(18, 18, 18) - .addComponent(jPanel5, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) - .addContainerGap()) + .addGroup(panelCommandsLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING, false) + .addComponent(buttonMoveHeater, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) + .addComponent(buttonMoveGonio, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) + .addComponent(buttonMovePark, javax.swing.GroupLayout.Alignment.TRAILING, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) + .addComponent(buttonGetGonio, javax.swing.GroupLayout.Alignment.TRAILING, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) + .addComponent(buttonPutGonio, javax.swing.GroupLayout.Alignment.TRAILING, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) + .addComponent(buttonMount, javax.swing.GroupLayout.Alignment.TRAILING, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) + .addComponent(buttonUnmount, javax.swing.GroupLayout.Alignment.TRAILING, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) + .addComponent(buttonGetDewar, javax.swing.GroupLayout.Alignment.TRAILING, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) + .addComponent(buttonPutDewar, javax.swing.GroupLayout.Alignment.TRAILING, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) + .addComponent(buttonDry, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) + .addGap(30, 30, 30) + .addGroup(panelCommandsLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(panelCommandsLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING, false) + .addComponent(buttonMoveScanner, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) + .addComponent(buttonMoveHome, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) + .addComponent(buttonMoveDewar, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) + .addComponent(jPanel5, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) + .addGroup(panelCommandsLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING) + .addGroup(panelCommandsLayout.createSequentialGroup() + .addComponent(jLabel7) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(spinnerDrySpeed, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addGroup(panelCommandsLayout.createSequentialGroup() + .addComponent(jLabel6) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) + .addComponent(spinnerDryTime, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))) + .addComponent(buttonHomingHexiposi, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) + .addContainerGap(30, Short.MAX_VALUE)) ); + + panelCommandsLayout.linkSize(javax.swing.SwingConstants.HORIZONTAL, new java.awt.Component[] {buttonGetDewar, buttonGetGonio, buttonHomingHexiposi, buttonMount, buttonMoveDewar, buttonMoveGonio, buttonMoveHeater, buttonMoveHome, buttonMovePark, buttonMoveScanner, buttonPutDewar, buttonPutGonio, buttonUnmount}); + panelCommandsLayout.setVerticalGroup( panelCommandsLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addGroup(panelCommandsLayout.createSequentialGroup() @@ -378,15 +470,36 @@ public class Expert extends Panel { .addGap(18, 18, 18) .addComponent(buttonGetDewar) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) - .addComponent(buttonPutDewar) - .addGap(18, 18, 18) - .addComponent(buttonGetGonio) - .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) - .addComponent(buttonPutGonio)) + .addComponent(buttonPutDewar)) .addComponent(jPanel5, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) .addGap(18, 18, 18) - .addComponent(buttonHomingHexiposi) - .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) + .addGroup(panelCommandsLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) + .addComponent(buttonGetGonio) + .addComponent(buttonHomingHexiposi)) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(buttonPutGonio) + .addGap(18, 18, 18) + .addGroup(panelCommandsLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) + .addComponent(buttonMovePark) + .addComponent(buttonMoveHome)) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addGroup(panelCommandsLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) + .addComponent(buttonMoveGonio) + .addComponent(buttonMoveDewar)) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addGroup(panelCommandsLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) + .addComponent(buttonMoveHeater) + .addComponent(buttonMoveScanner)) + .addGap(18, 18, 18) + .addGroup(panelCommandsLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) + .addComponent(buttonDry) + .addComponent(spinnerDryTime, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(jLabel6)) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) + .addGroup(panelCommandsLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) + .addComponent(spinnerDrySpeed, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(jLabel7)) + .addContainerGap()) ); jPanel3.setBorder(javax.swing.BorderFactory.createTitledBorder("Puck Detection")); @@ -419,9 +532,9 @@ public class Expert extends Panel { .addGroup(jPanel3Layout.createSequentialGroup() .addContainerGap() .addComponent(buttonPuckDetCheck) - .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, 11, Short.MAX_VALUE) .addComponent(buttonPuckDetStop) - .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, 11, Short.MAX_VALUE) .addComponent(buttonPuckDetStart) .addContainerGap()) ); @@ -439,28 +552,71 @@ public class Expert extends Panel { .addContainerGap()) ); + panelRobot1.setBorder(javax.swing.BorderFactory.createTitledBorder("Dryer")); + + buttonHeater.setText("Heater"); + buttonHeater.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + buttonHeaterActionPerformed(evt); + } + }); + + buttonStream.setText("Air Stream"); + buttonStream.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + buttonStreamActionPerformed(evt); + } + }); + + javax.swing.GroupLayout panelRobot1Layout = new javax.swing.GroupLayout(panelRobot1); + panelRobot1.setLayout(panelRobot1Layout); + panelRobot1Layout.setHorizontalGroup( + panelRobot1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(panelRobot1Layout.createSequentialGroup() + .addContainerGap(24, Short.MAX_VALUE) + .addComponent(buttonHeater) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) + .addComponent(buttonStream) + .addContainerGap(25, Short.MAX_VALUE)) + ); + + panelRobot1Layout.linkSize(javax.swing.SwingConstants.HORIZONTAL, new java.awt.Component[] {buttonHeater, buttonStream}); + + panelRobot1Layout.setVerticalGroup( + panelRobot1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(panelRobot1Layout.createSequentialGroup() + .addContainerGap() + .addGroup(panelRobot1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) + .addComponent(buttonHeater) + .addComponent(buttonStream)) + .addContainerGap()) + ); + javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this); this.setLayout(layout); layout.setHorizontalGroup( layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addGroup(layout.createSequentialGroup() .addContainerGap() - .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING) - .addComponent(jPanel2, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) - .addComponent(panelSafety, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) - .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING, false) - .addComponent(jPanel3, javax.swing.GroupLayout.Alignment.TRAILING, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) - .addComponent(panelRobot, javax.swing.GroupLayout.Alignment.TRAILING, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))) + .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.CENTER) + .addComponent(panelRobot1, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(panelRobot, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(jPanel3, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(jPanel2, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(panelSafety, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) .addGap(18, 18, 18) .addComponent(panelCommands, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) - .addContainerGap(32, Short.MAX_VALUE)) + .addContainerGap()) ); + + layout.linkSize(javax.swing.SwingConstants.HORIZONTAL, new java.awt.Component[] {jPanel2, jPanel3, panelRobot, panelRobot1, panelSafety}); + layout.setVerticalGroup( layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addGroup(layout.createSequentialGroup() .addContainerGap() - .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING, false) - .addComponent(panelCommands, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) + .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addComponent(panelCommands, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) .addGroup(layout.createSequentialGroup() .addComponent(panelSafety, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) @@ -468,8 +624,10 @@ public class Expert extends Panel { .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) .addComponent(jPanel3, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) - .addComponent(panelRobot, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))) - .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) + .addComponent(panelRobot, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) + .addComponent(panelRobot1, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))) + .addContainerGap(29, Short.MAX_VALUE)) ); }// //GEN-END:initComponents @@ -556,14 +714,61 @@ public class Expert extends Panel { execute("start_puck_detection()", true); }//GEN-LAST:event_buttonPuckDetStartActionPerformed + private void buttonMoveParkActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_buttonMoveParkActionPerformed + execute("move_park()"); + }//GEN-LAST:event_buttonMoveParkActionPerformed + + private void buttonMoveHomeActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_buttonMoveHomeActionPerformed + execute("move_home()"); + }//GEN-LAST:event_buttonMoveHomeActionPerformed + + private void buttonMoveGonioActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_buttonMoveGonioActionPerformed + execute("move_gonio()"); + }//GEN-LAST:event_buttonMoveGonioActionPerformed + + private void buttonMoveDewarActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_buttonMoveDewarActionPerformed + execute("move_dewar()"); + }//GEN-LAST:event_buttonMoveDewarActionPerformed + + private void buttonMoveScannerActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_buttonMoveScannerActionPerformed + execute("move_scanner()"); + }//GEN-LAST:event_buttonMoveScannerActionPerformed + + private void buttonMoveHeaterActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_buttonMoveHeaterActionPerformed + execute("move_heater()"); + }//GEN-LAST:event_buttonMoveHeaterActionPerformed + + private void buttonDryActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_buttonDryActionPerformed + double dryTime = (Double) spinnerDryTime.getValue(); + double streamTime = (Double) spinnerDrySpeed.getValue(); + + execute("dry(" + dryTime + ", " + streamTime + ")"); + }//GEN-LAST:event_buttonDryActionPerformed + + private void buttonHeaterActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_buttonHeaterActionPerformed + execute("set_heater(" + (buttonHeater.isSelected() ? "True": "False") + ")", true); + }//GEN-LAST:event_buttonHeaterActionPerformed + + private void buttonStreamActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_buttonStreamActionPerformed + execute("set_air_stream(" + (buttonStream.isSelected()? "True": "False")+ ")", true); + }//GEN-LAST:event_buttonStreamActionPerformed + // Variables declaration - do not modify//GEN-BEGIN:variables private javax.swing.JButton buttonDisable; + private javax.swing.JButton buttonDry; private javax.swing.JButton buttonEnable; private javax.swing.JButton buttonEnableAll; private javax.swing.JButton buttonGetDewar; private javax.swing.JButton buttonGetGonio; + private javax.swing.JToggleButton buttonHeater; private javax.swing.JButton buttonHomingHexiposi; private javax.swing.JButton buttonMount; + private javax.swing.JButton buttonMoveDewar; + private javax.swing.JButton buttonMoveGonio; + private javax.swing.JButton buttonMoveHeater; + private javax.swing.JButton buttonMoveHome; + private javax.swing.JButton buttonMovePark; + private javax.swing.JButton buttonMoveScanner; private javax.swing.JButton buttonPositionsHexiposi; private javax.swing.JButton buttonPuckDetCheck; private javax.swing.JButton buttonPuckDetStart; @@ -572,18 +777,24 @@ public class Expert extends Panel { private javax.swing.JButton buttonPutGonio; private javax.swing.JButton buttonReleaseLocal; private javax.swing.JButton buttonReleasePsys; + private javax.swing.JToggleButton buttonStream; private javax.swing.JButton buttonUnmount; private javax.swing.JCheckBox checkForce; 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.JPanel jPanel2; private javax.swing.JPanel jPanel3; private javax.swing.JPanel jPanel5; private javax.swing.JPanel panelCommands; private javax.swing.JPanel panelRobot; + private javax.swing.JPanel panelRobot1; private javax.swing.JPanel panelSafety; + private javax.swing.JSpinner spinnerDrySpeed; + private javax.swing.JSpinner spinnerDryTime; private javax.swing.JSpinner spinnerPuck; private javax.swing.JSpinner spinnerSample; private javax.swing.JSpinner spinnerSegment; diff --git a/plugins/MXSC-1.9.0.jar b/plugins/MXSC-1.10.0.jar similarity index 53% rename from plugins/MXSC-1.9.0.jar rename to plugins/MXSC-1.10.0.jar index 57618ab215a23ceb233ac662447aa08e07798bc7..18676db44133dc77fce78d22215a7accdac0aec3 100644 GIT binary patch delta 32123 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 diff --git a/script/HillClimbingXZ.py b/script/calibration/HillClimbingXZ.py similarity index 100% rename from script/HillClimbingXZ.py rename to script/calibration/HillClimbingXZ.py diff --git a/script/devices/Hexiposi.py b/script/devices/Hexiposi.py index a689677..f1f3010 100644 --- a/script/devices/Hexiposi.py +++ b/script/devices/Hexiposi.py @@ -13,6 +13,7 @@ class Hexiposi(DiscretePositionerBase): self.moved = True self.homing_state = State.Disabled self.rback = self.UNKNOWN_POSITION + self.timeout = 3.0 def doInitialize(self): super(Hexiposi, self).doInitialize() @@ -24,7 +25,7 @@ class Hexiposi(DiscretePositionerBase): return json.loads(response.text) def get_status(self): - self.status = self.get_response(requests.get(url=self.url+"get")) + self.status = self.get_response(requests.get(url=self.url+"get", timeout=self.timeout)) self.estop = self.status["estop"] self.homed = self.status["homed"] self.error = self.status["errorCode"] @@ -48,10 +49,10 @@ class Hexiposi(DiscretePositionerBase): return self.status def move_pos(self, pos): - return self.get_response(requests.get(url=self.url+"set?pos=" + str(pos))) + return self.get_response(requests.get(url=self.url+"set?pos=" + str(pos), timeout=self.timeout)) def move_home(self): - ret = self.get_response(requests.get(url=self.url+"set?home=1")) + ret = self.get_response(requests.get(url=self.url+"set?home=1", timeout=self.timeout)) try: self.waitState(self.homing_state,1200) except: @@ -59,10 +60,10 @@ class Hexiposi(DiscretePositionerBase): return ret def stop_move(self): - return self.get_response(requests.get(url=self.url+"set?stop=1")) + return self.get_response(requests.get(url=self.url+"set?stop=1", timeout=self.timeout)) def set_offset(self, offset): - return self.get_response(requests.get(url=self.url+"setOffset?offset="+str(offset))) + return self.get_response(requests.get(url=self.url+"setOffset?offset="+str(offset), timeout=self.timeout)) def doUpdate(self): self.get_status() diff --git a/script/devices/RobotSC.py b/script/devices/RobotSC.py index eaf45a0..09c3b71 100644 --- a/script/devices/RobotSC.py +++ b/script/devices/RobotSC.py @@ -24,7 +24,7 @@ class RobotSC(RobotTCP): def __init__(self, name, server, timeout = 1000, retries = 1): RobotTCP.__init__(self, name, server, timeout, retries) self.set_tasks(["getDewar", "putDewar", "putGonio", "getGonio", "robotRecover", "moveDewar", "movePark", "moveGonio","moveHeater", "moveScanner"]) - self.set_known_points(["pHome", "pPark", "pDewarHome", "pGonioHome", "pDewarWait", "pGonioGet", "pScanHome", "pHeaterHome"]) + self.set_known_points(["pHome", "pPark", "pDewarHome", "pGonioHome", "pDewarWait", "pGonioGet", "pScanHome", "pHeaterHome", "pHeater", "pHeaterBottom"]) self.setPolling(DEFAULT_ROBOT_POLLING) def move_dewar(self): @@ -65,15 +65,23 @@ class RobotSC(RobotTCP): self.wait_task_finished(TASK_WAIT_ROBOT_POLLING) self.assert_gonio() + def move_home(self): + self.start_task('moveHome') + self.wait_task_finished(TASK_WAIT_ROBOT_POLLING) + self.assert_home() + def move_park(self): self.start_task('movePark') self.wait_task_finished(TASK_WAIT_ROBOT_POLLING) self.assert_park() - def move_heater(self): - self.start_task('moveHeater') + def move_heater(self, speed=-1, to_bottom=True): + self.start_task('moveHeater', speed, to_bottom) self.wait_task_finished(TASK_WAIT_ROBOT_POLLING) - self.assert_heater() + if to_bottom: + self.assert_heater_bottom() + else: + self.assert_heater() def robot_recover(self): @@ -134,7 +142,13 @@ class RobotSC(RobotTCP): return self.is_in_point("pDewarWait") def is_heater(self): - return self.is_in_point("pHeaterHome") + return self.is_in_point("pHeater") + + def is_heater_home(self): + return self.is_in_point("pHeaterHome") + + def is_heater_bottom(self): + return self.is_in_point("pHeaterBottom") def is_gonio(self): return self.is_in_point("pGonioHome") @@ -149,9 +163,15 @@ class RobotSC(RobotTCP): def assert_home(self): self.assert_in_point("pHome") - def assert_heater(self): + def assert_heater_home(self): self.assert_in_point("pHeaterHome") + def assert_heater(self): + self.assert_in_point("pHeater") + + def assert_heater_bottom(self): + self.assert_in_point("pHeaterBottom") + def assert_park(self): self.assert_in_point("pPark") diff --git a/script/devices/RobotTCP.py b/script/devices/RobotTCP.py index 2071717..8c96c83 100644 --- a/script/devices/RobotTCP.py +++ b/script/devices/RobotTCP.py @@ -43,6 +43,7 @@ class RobotTCP(TcpDevice, Stoppable): self.frame = FRAME_DEFAULT self.polling_interval = 0.01 self.reset = True + self.default_tolerance = 10 self.task_start_retries = 3 self.exception_on_task_start_failure = True #Tasks may start and be finished when checked @@ -454,8 +455,12 @@ class RobotTCP(TcpDevice, Stoppable): #taskCreate "t1", 10, read(sMessage) cmd = 'taskCreate "' + name + '", ' + str(priority) + ', ' + program + '(' - for i in range(len(args)): - cmd += str(args[i]) + (',' if (i<(len(args)-1)) else '') + for i in range(len(args)): + val = args[i] + if type(val) == bool: + if val == True: val = "true" + elif val == False: val = "false" + cmd += str(val) + (',' if (i<(len(args)-1)) else '') cmd+=')' self.evaluate(cmd) @@ -574,7 +579,7 @@ class RobotTCP(TcpDevice, Stoppable): return self.distance_p("tcp_p", name) def is_in_point(self, p, tolerance = None): #Tolerance in mm - tolerance = 10 if tolerance == None else tolerance + tolerance = self.default_tolerance if tolerance == None else tolerance d = self.get_distance_to_pnt(p) if d<0: raise Exception ("Error calculating distance to " + p + " : " + str(d)) @@ -589,9 +594,9 @@ class RobotTCP(TcpDevice, Stoppable): except: ret[i] = None return ret - + def is_in_points(self, *pars, **kwargs): #Tolerance in mm - tolerance = 10 if (kwargs is None) or (not kwargs.has_key("tolerance")) or (kwargs["tolerance"] is None) else kwargs["tolerance"] + tolerance = self.default_tolerance if (kwargs is None) or (not kwargs.has_key("tolerance")) or (kwargs["tolerance"] is None) else kwargs["tolerance"] ret = self.get_distance_to_pnts(*pars) for i in range(len(ret)): if ret[i]<0: diff --git a/script/local.py b/script/local.py index 247fc9f..26fc1a7 100644 --- a/script/local.py +++ b/script/local.py @@ -35,6 +35,13 @@ run("motion/get_dewar") run("motion/put_dewar") run("motion/get_gonio") run("motion/put_gonio") +run("motion/move_dewar") +run("motion/move_gonio") +run("motion/move_heater") +run("motion/move_home") +run("motion/move_park") +run("motion/move_scanner") +run("motion/dry") run("motion/homing_hexiposi") run("imgproc/Utils") run("tools/Math") @@ -66,6 +73,13 @@ def stop_puck_detection(): # Device initialization ################################################################################################### +try: + set_heater(False) + set_air_stream(False) +except: + print >> sys.stderr, traceback.format_exc() + + try: release_local_safety.write(False) release_psys_safety.write(False) @@ -109,7 +123,6 @@ except: print >> sys.stderr, traceback.format_exc() - ################################################################################################### # Global variables ################################################################################################### diff --git a/script/motion/dry.py b/script/motion/dry.py new file mode 100644 index 0000000..4912ef4 --- /dev/null +++ b/script/motion/dry.py @@ -0,0 +1,55 @@ + +def set_air_stream(state): + """ + """ + valve_1.write(state) + valve_2.write(not state) + + +def set_heater(state): + """ + """ + gripper_dryer.write(state) + + +def get_air_stream(): + """ + """ + return valve_1.read() + + +def get_heater(): + """ + """ + return gripper_dryer.read() + + + +def dry(heat_time, speed): + """ + heat_time (float): in seconds + speed (float): % of nominal speed + """ + print "dry" + #Initial checks + robot.assert_no_task() + robot.reset_motion() + robot.state.assertReady() + robot.assert_cleared() + #robot.assert_in_known_point() + + #Enabling + enable_motion() + + try: + set_heater(True) + robot.move_heater(speed, False) + time.sleep(heat_time) + robot.move_heater(speed, True) + set_air_stream(True) + robot.move_heater(speed, False) + finally: + set_heater(False) + set_air_stream(False) + + robot.move_dewar() \ No newline at end of file diff --git a/script/motion/mount.py b/script/motion/mount.py index b28cd68..a6cd30c 100644 --- a/script/motion/mount.py +++ b/script/motion/mount.py @@ -2,7 +2,7 @@ def mount(segment, puck, sample, force=False): """ """ print "mount: ", segment, puck, sample, force - + start = time.time() #Initial checks assertValidAddress(segment, puck, sample) robot.assert_no_task() diff --git a/script/motion/move_dewar.py b/script/motion/move_dewar.py new file mode 100644 index 0000000..e829a25 --- /dev/null +++ b/script/motion/move_dewar.py @@ -0,0 +1,18 @@ +def move_dewar(): + """ + """ + print "move_dewar" + + #Initial checks + robot.assert_no_task() + robot.reset_motion() + robot.state.assertReady() + robot.assert_cleared() + #robot.assert_in_known_point() + + #Enabling + enable_motion() + + + if not robot.is_dewar(): + robot.move_dewar() \ No newline at end of file diff --git a/script/motion/move_gonio.py b/script/motion/move_gonio.py new file mode 100644 index 0000000..8ce6389 --- /dev/null +++ b/script/motion/move_gonio.py @@ -0,0 +1,18 @@ +def move_gonio(): + """ + """ + print "move_gonio" + + #Initial checks + robot.assert_no_task() + robot.reset_motion() + robot.state.assertReady() + robot.assert_cleared() + #robot.assert_in_known_point() + + #Enabling + enable_motion() + + + if not robot.is_gonio(): + robot.move_gonio() diff --git a/script/motion/move_heater.py b/script/motion/move_heater.py new file mode 100644 index 0000000..bafe6bc --- /dev/null +++ b/script/motion/move_heater.py @@ -0,0 +1,18 @@ +def move_heater(): + """ + """ + print "move_heater" + + #Initial checks + robot.assert_no_task() + robot.reset_motion() + robot.state.assertReady() + robot.assert_cleared() + #robot.assert_in_known_point() + + #Enabling + enable_motion() + + + if not robot.is_heater(): + robot.move_heater() diff --git a/script/motion/move_home.py b/script/motion/move_home.py new file mode 100644 index 0000000..932bd5d --- /dev/null +++ b/script/motion/move_home.py @@ -0,0 +1,18 @@ +def move_home(): + """ + """ + print "move_home" + + #Initial checks + robot.assert_no_task() + robot.reset_motion() + robot.state.assertReady() + robot.assert_cleared() + #robot.assert_in_known_point() + + #Enabling + enable_motion() + + + if not robot.is_home(): + robot.move_home() diff --git a/script/motion/move_park.py b/script/motion/move_park.py new file mode 100644 index 0000000..49a1735 --- /dev/null +++ b/script/motion/move_park.py @@ -0,0 +1,18 @@ +def move_park(): + """ + """ + print "move_park" + + #Initial checks + robot.assert_no_task() + robot.reset_motion() + robot.state.assertReady() + robot.assert_cleared() + #robot.assert_in_known_point() + + #Enabling + enable_motion() + + + if not robot.is_park(): + robot.move_park() \ No newline at end of file diff --git a/script/motion/move_scanner.py b/script/motion/move_scanner.py new file mode 100644 index 0000000..bd6c5bd --- /dev/null +++ b/script/motion/move_scanner.py @@ -0,0 +1,18 @@ +def move_scanner(): + """ + """ + print "move_scanner" + + #Initial checks + robot.assert_no_task() + robot.reset_motion() + robot.state.assertReady() + robot.assert_cleared() + #robot.assert_in_known_point() + + #Enabling + enable_motion() + + + if not robot.is_scanner(): + robot.move_scanner()