diff --git a/config/plugins.properties b/config/plugins.properties index ef1ef6c..976e538 100644 --- a/config/plugins.properties +++ b/config/plugins.properties @@ -1,4 +1,6 @@ MXSC-1.10.0.jar=enabled +LN2.java=enabled +Hexiposi.java=enabled NewJPanel.java=disabled Expert.java=disabled RobotPanel.java=enabled diff --git a/devices/img.properties b/devices/img.properties index b95a012..cb23248 100644 --- a/devices/img.properties +++ b/devices/img.properties @@ -1,4 +1,4 @@ -#Mon May 07 14:51:31 CEST 2018 +#Thu Jun 14 10:54:07 CEST 2018 colormap=Grayscale colormapAutomatic=false colormapMax=18.133 @@ -9,16 +9,16 @@ grayscale=false invert=false rescaleFactor=1.0 rescaleOffset=0.0 -roiHeight=867 -roiWidth=875 -roiX=65 -roiY=55 -rotation=17.927919762007235 +roiHeight=872 +roiWidth=869 +roiX=74 +roiY=0 +rotation=17.93079800677477 rotationCrop=true scale=1.0 -spatialCalOffsetX=-438.0 -spatialCalOffsetY=-434.0 -spatialCalScaleX=0.5371114316839612 -spatialCalScaleY=0.5416192705243328 +spatialCalOffsetX=-435.0 +spatialCalOffsetY=-436.0 +spatialCalScaleX=0.540300793168967 +spatialCalScaleY=0.5385447475747382 spatialCalUnits=mm transpose=false diff --git a/devices/led_ctrl_1.properties b/devices/led_ctrl_1.properties index 8019e7b..c6fe6fa 100644 --- a/devices/led_ctrl_1.properties +++ b/devices/led_ctrl_1.properties @@ -1,5 +1,5 @@ -#Wed Jun 13 09:47:55 CEST 2018 -maxValue=1.2 +#Thu Jun 14 15:23:57 CEST 2018 +maxValue=1.0 minValue=0.0 offset=0.0 precision=2 diff --git a/devices/led_ctrl_2.properties b/devices/led_ctrl_2.properties index 8019e7b..c6fe6fa 100644 --- a/devices/led_ctrl_2.properties +++ b/devices/led_ctrl_2.properties @@ -1,5 +1,5 @@ -#Wed Jun 13 09:47:55 CEST 2018 -maxValue=1.2 +#Thu Jun 14 15:23:57 CEST 2018 +maxValue=1.0 minValue=0.0 offset=0.0 precision=2 diff --git a/devices/led_ctrl_3.properties b/devices/led_ctrl_3.properties index 8019e7b..c6fe6fa 100644 --- a/devices/led_ctrl_3.properties +++ b/devices/led_ctrl_3.properties @@ -1,5 +1,5 @@ -#Wed Jun 13 09:47:55 CEST 2018 -maxValue=1.2 +#Thu Jun 14 15:23:57 CEST 2018 +maxValue=1.0 minValue=0.0 offset=0.0 precision=2 diff --git a/plugins/Hexiposi.form b/plugins/Hexiposi.form new file mode 100644 index 0000000..4687d34 --- /dev/null +++ b/plugins/Hexiposi.form @@ -0,0 +1,34 @@ + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
diff --git a/plugins/Hexiposi.java b/plugins/Hexiposi.java new file mode 100644 index 0000000..f4f8a21 --- /dev/null +++ b/plugins/Hexiposi.java @@ -0,0 +1,78 @@ +/* + * Copyright (c) 2014-2018 Paul Scherrer Institute. All rights reserved. + */ + +import ch.psi.pshell.core.Context; +import ch.psi.pshell.swing.StripChart; +import ch.psi.pshell.ui.App; +import ch.psi.pshell.ui.Panel; +import ch.psi.utils.State; +import java.io.File; +import java.util.logging.Level; +import java.util.logging.Logger; + +/** + * + */ +public class Hexiposi extends Panel { + final StripChart stripChart; + public Hexiposi() { + initComponents(); + stripChart = new StripChart(this.getTopLevel(), false, App.getStripChartFolderArg()); + panel.add(stripChart.getPlotPanel()); + + try { + stripChart.open(new File(Context.getInstance().getSetup().expandPath("{home}/stripchart/hexiposi_positon.scd"))); + stripChart.start(); + } catch (Exception ex) { + showException(ex); + Logger.getLogger(Hexiposi.class.getName()).log(Level.WARNING, null, ex); + } + + } + + //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() { + + panel = new javax.swing.JPanel(); + + panel.setLayout(new java.awt.BorderLayout()); + + javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this); + this.setLayout(layout); + layout.setHorizontalGroup( + layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addComponent(panel, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) + ); + layout.setVerticalGroup( + layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addComponent(panel, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) + ); + }// //GEN-END:initComponents + + // Variables declaration - do not modify//GEN-BEGIN:variables + private javax.swing.JPanel panel; + // End of variables declaration//GEN-END:variables +} diff --git a/plugins/LN2.form b/plugins/LN2.form new file mode 100644 index 0000000..4687d34 --- /dev/null +++ b/plugins/LN2.form @@ -0,0 +1,34 @@ + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
diff --git a/plugins/LN2.java b/plugins/LN2.java new file mode 100644 index 0000000..20360f7 --- /dev/null +++ b/plugins/LN2.java @@ -0,0 +1,78 @@ +/* + * Copyright (c) 2014-2018 Paul Scherrer Institute. All rights reserved. + */ + +import ch.psi.pshell.core.Context; +import ch.psi.pshell.swing.StripChart; +import ch.psi.pshell.ui.App; +import ch.psi.pshell.ui.Panel; +import ch.psi.utils.State; +import java.io.File; +import java.util.logging.Level; +import java.util.logging.Logger; + +/** + * + */ +public class LN2 extends Panel { + final StripChart stripChart; + public LN2() { + initComponents(); + stripChart = new StripChart(this.getTopLevel(), false, App.getStripChartFolderArg()); + panel.add(stripChart.getPlotPanel()); + + try { + stripChart.open(new File(Context.getInstance().getSetup().expandPath("{home}/stripchart/LN2_Monitoring.scd"))); + stripChart.start(); + } catch (Exception ex) { + showException(ex); + Logger.getLogger(LN2.class.getName()).log(Level.WARNING, null, ex); + } + + } + + //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() { + + panel = new javax.swing.JPanel(); + + panel.setLayout(new java.awt.BorderLayout()); + + javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this); + this.setLayout(layout); + layout.setHorizontalGroup( + layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addComponent(panel, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) + ); + layout.setVerticalGroup( + layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addComponent(panel, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) + ); + }// //GEN-END:initComponents + + // Variables declaration - do not modify//GEN-BEGIN:variables + private javax.swing.JPanel panel; + // End of variables declaration//GEN-END:variables +} diff --git a/plugins/MXSC-1.10.0.jar b/plugins/MXSC-1.10.0.jar index 18676db..f4abe15 100644 Binary files a/plugins/MXSC-1.10.0.jar and b/plugins/MXSC-1.10.0.jar differ diff --git a/script/devices/RobotSC.py b/script/devices/RobotSC.py index 09c3b71..10f56f8 100644 --- a/script/devices/RobotSC.py +++ b/script/devices/RobotSC.py @@ -34,14 +34,14 @@ class RobotSC(RobotTCP): def get_dewar(self, segment, puck, sample): segment = self.toSegmentNumber(segment) - self.start_task('getDewar',segment, puck, sample) + self.start_task('getDewar',segment, puck, sample, is_room_temp()) self.wait_task_finished(TASK_WAIT_ROBOT_POLLING) self.assert_dewar() def put_dewar(self, segment, puck, sample): segment = self.toSegmentNumber(segment) self.assert_dewar() - self.start_task('putDewar',segment, puck, sample) + self.start_task('putDewar',segment, puck, sample, is_room_temp()) self.wait_task_finished(TASK_WAIT_ROBOT_POLLING) self.assert_dewar() diff --git a/script/devices/Wago.py b/script/devices/Wago.py index 3761f1a..9473b08 100644 --- a/script/devices/Wago.py +++ b/script/devices/Wago.py @@ -1,4 +1,5 @@ - +LED_LEVEL_ROOM_TEMPERATURE = 0.4 +LED_LEVEL_LN2 = 1.0 """ @@ -67,7 +68,7 @@ def set_led_range(room_temp = True): """ Led range should be limitted in room temperature """ - max_val = 0.40 if room_temp else 1.20 + max_val = LED_LEVEL_ROOM_TEMPERATURE if room_temp else LED_LEVEL_LN2 led_ctrl_1.config.maxValue = max_val led_ctrl_1.config.save() led_ctrl_2.config.maxValue = max_val @@ -87,7 +88,7 @@ def set_led_range(room_temp = True): def is_led_room_temp(): - return led_ctrl_1.config.maxValue <= 0.50 + return led_ctrl_1.config.maxValue <= LED_LEVEL_ROOM_TEMPERATURE diff --git a/script/imgproc/CameraCalibration.py b/script/imgproc/CameraCalibration.py index 02e7d9d..1be0af4 100644 --- a/script/imgproc/CameraCalibration.py +++ b/script/imgproc/CameraCalibration.py @@ -1,7 +1,8 @@ import ch.psi.pshell.device.Camera as Camera import ch.psi.pshell.imaging.RendererMode as RendererMode +import ch.psi.pshell.imaging.Calibration as Calibration from ch.psi.pshell.imaging.Overlays import * - +#SIMULATION = ch.psi.pshell.imaging.FileSource """ img.camera.setColorMode(Camera.ColorMode.Mono) img.camera.setDataType(Camera.DataType.UInt8) @@ -11,61 +12,132 @@ img.camera.setExposure(50.00) img.camera.setAcquirePeriod(200.00) img.camera.setGain(0.0) img.config.rotationCrop=True - - """ -#img.camera.setROI(200, 0,1200,1200) -img.camera.setROI(0, 0,1600,1200) +MOVE_HEXIPOSI = True + +if MOVE_HEXIPOSI: + enable_motion() + +sensor_width,sensor_height = img.camera.getSensorSize() +img.camera.setROI(0, 0,sensor_width, sensor_height) img.config.rotation=0 img.config.roiX,img.config.roiY, img.config.roiWidth,img.config.roiHeight =0,0,-1,-1 img.config.setCalibration(None) img.camera.stop() img.camera.start() -#img.camera.setROI(300, 200,1000,1000) -#img.config.rotation=17 -#img.config.roiX,img.config.roiY, img.config.roiWidth,img.config.roiHeight = 50,50,900,900 p = show_panel(img) p.setMode(RendererMode.Fit) ov_text = Text(Pen(java.awt.Color.GREEN.darker()), "", java.awt.Font("Verdana", java.awt.Font.PLAIN, 24), java.awt.Point(20,20)) ov_text.setFixed(True) - - - p.addOverlay(ov_text) + try: - ov_text.update("Click on upper reference...") - p1 = p.waitClick(60000) - print p1 - ov_text.update("Click on left reference...") - p2 = p.waitClick(60000) - print p2 - ov_text.update("Click on right reference...") - p3 = p.waitClick(60000) - print p3 - - x, y, z = p1.x+p1.y*1j, p2.x+p2.y*1j, p3.x+p3.y*1j - w = z-x - w /= y-x - c = (x-y)*(w-abs(w)**2)/2j/w.imag-x - cx, cy, r = -c.real, -c.imag, abs(c+x) - a = math.degrees(math.atan((cx-p1.x)/(p1.y-cy))) - - print cx, cy, r, a - - #img.camera.setROI(int((1600-cx)/2),int((1200-cy)/2),1000,1000) - img.camera.setROI(int(cx-r),int(cy-r),int(2*r),int(2*r)) - img.config.rotation=-a - #remove rotation border - d=int(r/11) - img.config.roiX,img.config.roiY, img.config.roiWidth,img.config.roiHeight =d,d, int(2*r-2*d), int(2*r-2*d) - #img.config.setCalibration(None) + #Find image center and Prosilica ROI + ov_text.update("Click on the center of the Dewar...") + p.refresh() + dc = p.waitClick(60000) + print dc + width, height = min(dc.x, sensor_width-dc.x)*2, min(dc.y, sensor_height-dc.y)*2 + width, height = width - width%16, height - height%16 + width, height = min(width,1000), min(height,1000) + print width, height + roi_x = int(dc.x- width/2) + roi_y = int(dc.y- height/2) + roi_w = int(width) + roi_h = int(height) + set_setting("roi_x", roi_x) + set_setting("roi_y", roi_y) + set_setting("roi_w", roi_w) + set_setting("roi_h", roi_h) + img.camera.setROI(roi_x, roi_y, width, height) +except: + img.camera.setROI(int(get_setting("roi_x")), int(get_setting("roi_y")), int(get_setting("roi_w")), int(get_setting("roi_h"))) +finally: img.camera.stop() - img.camera.start() + img.camera.start() + + +#Configure source +CC4 = (-129.9, -150) +CD5 = (129.9, -150) +CA5 = (-129.9, 150) +CF4 = (129.9, 150) + +DX = 259.8 +DY = 300.0 + +ROI_X = 470.0 +ROI_Y = 470.0 + +def rotate(x,y, degrees): + rotation = math.radians(degrees) + rw, rh = img.getImage().getWidth(), img.getImage().getHeight() + ox, oy = x - (rw / 2), y - (rh / 2) + x = ox * math.cos(rotation) - oy * math.sin(rotation) + rw / 2; + y = oy * math.cos(rotation) + ox * math.sin(rotation) + rh / 2; + return x,y + + +set_led_state(True) +try: + if MOVE_HEXIPOSI: set_hexiposi("C") + ov_text.update("Click on the center of C4 (19) position...") + p.refresh() + pc4 = p.waitClick(60000) + print pc4 + if MOVE_HEXIPOSI: set_hexiposi("D") + ov_text.update("Click on the center of D5 (13) position...") + p.refresh() + pd5 = p.waitClick(60000) + print pd5 + if MOVE_HEXIPOSI: set_hexiposi("F") + ov_text.update("Click on the center of F4 (04) position...") + p.refresh() + pf4 = p.waitClick(60000) + print pf4 + if MOVE_HEXIPOSI: set_hexiposi("A") + ov_text.update("Click on the center of A5 (28) position...") + p.refresh() + pa5 = p.waitClick(60000) + print pa5 + + + vc1x, vc1y, vc2x, vc2y = (pc4.x + pd5.x )/2.0, (pc4.y + pd5.y )/2.0, (pa5.x + pf4.x )/2.0, (pa5.y + pf4.y )/2.0 + hc1x, hc1y, hc2x, hc2y = (pc4.x + pa5.x )/2.0, (pc4.y + pa5.y )/2.0, (pd5.x + pf4.x )/2.0, (pd5.y + pf4.y )/2.0 + cx, cy = (vc1x + vc2x)/2, (hc1y + hc2y)/2 + + a1 = math.degrees(math.atan((cx-vc1x)/(vc1y-cy))) + a2 = math.degrees(math.atan((cx-vc2x)/(vc2y-cy))) + a = (a1+a2)/2 + + + dy = math.hypot(vc2y - vc1y, vc2x - vc1x) + dx = math.hypot(hc2x - hc1x, hc2y - hc1y) + print dy, dx, cx, cy + sx, sy = DX/dx, DY/dy + + + #Rotating center of puck + rcx, rcy = rotate(cx, cy, -a) + + + + roi_w, roi_h = int(ROI_X / sx), int(ROI_Y / sy) + roi_x, roi_y = int(rcx-roi_w/2), int(rcy-roi_h/2) + + print a, sx, sy, roi_w, roi_h + + img.config.rotation=-a + img.config.roiX,img.config.roiY, img.config.roiWidth,img.config.roiHeight = roi_x, roi_y, roi_w, roi_h + img.config.setCalibration(Calibration(sx, sy, -roi_w/2, -roi_h/2)) + img.config.save() finally: + set_led_state(False) p.removeOverlay(ov_text) + img.refresh() \ No newline at end of file diff --git a/script/imgproc/CameraCalibration2.py b/script/imgproc/CameraCalibration2.py deleted file mode 100644 index a07f506..0000000 --- a/script/imgproc/CameraCalibration2.py +++ /dev/null @@ -1,136 +0,0 @@ -import ch.psi.pshell.device.Camera as Camera -import ch.psi.pshell.imaging.RendererMode as RendererMode -import ch.psi.pshell.imaging.Calibration as Calibration -from ch.psi.pshell.imaging.Overlays import * -SIMULATION = ch.psi.pshell.imaging.FileSource -""" -img.camera.setColorMode(Camera.ColorMode.Mono) -img.camera.setDataType(Camera.DataType.UInt8) -img.camera.setGrabMode(Camera.GrabMode.Continuous) -img.camera.setTriggerMode(Camera.TriggerMode.Fixed_Rate) -img.camera.setExposure(50.00) -img.camera.setAcquirePeriod(200.00) -img.camera.setGain(0.0) -img.config.rotationCrop=True - - -""" - -sensor_width,sensor_height = img.camera.getSensorSize() -img.camera.setROI(0, 0,sensor_width, sensor_height) -img.config.rotation=0 -img.config.roiX,img.config.roiY, img.config.roiWidth,img.config.roiHeight =0,0,-1,-1 -img.config.setCalibration(None) -img.camera.stop() -img.camera.start() - - -p = show_panel(img) -p.setMode(RendererMode.Fit) -ov_text = Text(Pen(java.awt.Color.GREEN.darker()), "", java.awt.Font("Verdana", java.awt.Font.PLAIN, 24), java.awt.Point(20,20)) -ov_text.setFixed(True) -p.addOverlay(ov_text) - -try: - #Find image center and Prosilica ROI - ov_text.update("Click on the center of the Dewar...") - p.refresh() - dc = p.waitClick(60000) - print dc - width, height = min(dc.x, sensor_width-dc.x)*2, min(dc.y, sensor_height-dc.y)*2 - width, height = width - width%16, height - height%16 - width, height = min(width,1000), min(height,1000) - print width, height - roi_x = int(dc.x- width/2) - roi_y = int(dc.y- height/2) - roi_w = int(width) - roi_h = int(height) - set_setting("roi_x", roi_x) - set_setting("roi_y", roi_y) - set_setting("roi_w", roi_w) - set_setting("roi_h", roi_h) - img.camera.setROI(roi_x, roi_y, width, height) -except: - img.camera.setROI(int(get_setting("roi_x")), int(get_setting("roi_y")), int(get_setting("roi_w")), int(get_setting("roi_h"))) -finally: - img.camera.stop() - img.camera.start() - - -#Configure source -CC4 = (-129.9, -150) -CD5 = (129.9, -150) -CA5 = (-129.9, 150) -CF4 = (129.9, 150) - -DX = 259.8 -DY = 300.0 - -ROI_X = 470.0 -ROI_Y = 470.0 - -def rotate(x,y, degrees): - rotation = math.radians(degrees) - rw, rh = img.getImage().getWidth(), img.getImage().getHeight() - ox, oy = x - (rw / 2), y - (rh / 2) - x = ox * math.cos(rotation) - oy * math.sin(rotation) + rw / 2; - y = oy * math.cos(rotation) + ox * math.sin(rotation) + rh / 2; - return x,y - - -set_led_state(True) -try: - ov_text.update("Click on the center of C4 (19) position...") - p.refresh() - pc4 = p.waitClick(60000) - print pc4 - ov_text.update("Click on the center of D5 (13) position...") - p.refresh() - pd5 = p.waitClick(60000) - print pd5 - ov_text.update("Click on the center of A5 (28) position...") - p.refresh() - pa5 = p.waitClick(60000) - print pa5 - ov_text.update("Click on the center of F4 (04) position...") - p.refresh() - pf4 = p.waitClick(60000) - print pf4 - - - vc1x, vc1y, vc2x, vc2y = (pc4.x + pd5.x )/2.0, (pc4.y + pd5.y )/2.0, (pa5.x + pf4.x )/2.0, (pa5.y + pf4.y )/2.0 - hc1x, hc1y, hc2x, hc2y = (pc4.x + pa5.x )/2.0, (pc4.y + pa5.y )/2.0, (pd5.x + pf4.x )/2.0, (pd5.y + pf4.y )/2.0 - cx, cy = (vc1x + vc2x)/2, (hc1y + hc2y)/2 - - a1 = math.degrees(math.atan((cx-vc1x)/(vc1y-cy))) - a2 = math.degrees(math.atan((cx-vc2x)/(vc2y-cy))) - a = (a1+a2)/2 - - - dy = math.hypot(vc2y - vc1y, vc2x - vc1x) - dx = math.hypot(hc2x - hc1x, hc2y - hc1y) - print dy, dx, cx, cy - sx, sy = DX/dx, DY/dy - - - #Rotating center of puck - rcx, rcy = rotate(cx, cy, -a) - - - - roi_w, roi_h = int(ROI_X / sx), int(ROI_Y / sy) - roi_x, roi_y = int(rcx-roi_w/2), int(rcy-roi_h/2) - - print a, sx, sy, roi_w, roi_h - - img.config.rotation=-a - img.config.roiX,img.config.roiY, img.config.roiWidth,img.config.roiHeight = roi_x, roi_y, roi_w, roi_h - img.config.setCalibration(Calibration(sx, sy, -roi_w/2, -roi_h/2)) - img.config.save() - -finally: - set_led_state(False) - p.removeOverlay(ov_text) - img.refresh() - - \ No newline at end of file diff --git a/script/imgproc/CoverDetection.py b/script/imgproc/CoverDetection.py index 24a228b..315911e 100644 --- a/script/imgproc/CoverDetection.py +++ b/script/imgproc/CoverDetection.py @@ -1,116 +1,77 @@ ################################################################################################### # Procedure to detect the cover orientation ################################################################################################### -import ch.psi.pshell.imaging.Utils.integrateVertically as integrateVertically -img.backgroundEnabled=False -REF = (0,96,125) +#Parameters +FRAMES_INTEGRATION = 3 +STEP_SIZE = 2 +POSITION_NAMES = [ 'A','B','C','D', 'E', 'F'] +POSITION_ANGLES = [330, 30, 90, 150, 210, 270] +POSITION_TOLERANCE = 3 +MINIMUM_CONFIDENCE = 10 +DEBUG = cover_detection_debug +REFERENCE_IMG = "ref2" -line = load_image("{images}/line.png", title="Line") -#line = load_image("{images}/line360.png", title="Line") +#Load reference image +ref = load_image(str("{images}/cover/" + REFERENCE_IMG + ".png") , title="Line") -line.getProcessor().setBackgroundValue(0.0) - - -#ip = get_image() -ip = integrate_frames(10) +#Pre-process camera image +#ip = load_image("{images}/cover/Cover_000" + str(index) + ".png", title="Img") +ip = integrate_frames(FRAMES_INTEGRATION) ip = grayscale(ip, True) - - smooth(ip) #bandpass_filter(ip, 30, 1000) edges(ip) - -#invert(ip) -#auto_threshold(ip, method = "Default") - - -#auto_threshold(ip, method = "Li") auto_threshold(ip, method = "MaxEntropy") +cx,cy = int(ip.width/2), int(ip.height/2) +ip = sub_image(ip, cx-ref.width/2, cy-ref.height/2, ref.width, ref.height) -""" -for m in AutoThresholder.getMethods(): - print m - aux = ip.duplicate() - auto_threshold(aux, method = m) - binary_fill_holes(aux, dark_background=False) - renderer = show_panel(aux.bufferedImage) - time.sleep(1.0) -""" -#binary_dilate(ip, dark_background=False) -#binary_fill_holes(ip, dark_background=False) -#binary_open(ip, dark_background=Tr) - -renderer = show_panel(ip.bufferedImage) +#Show ROI of pre-processed image +if DEBUG: + image_panel = show_panel(ip.bufferedImage) - - - - - - -#line = sub_image(line, 325, 325, 512, 512) -#ip = sub_image(ip, 325, 325, 512, 512) -line = sub_image(line, 453, 453, 256, 256) -ip = sub_image(ip, 453, 453, 256, 256) -#op = op_fft(ip, line, "correlate") - - -renderer = show_panel(ip.bufferedImage) - -#renderer = show_panel(op.bufferedImage) -#line.show() +#Calculate correlation between image and reference, rotating the reference from 0 to 360 +import ch.psi.pshell.imaging.Utils.integrateVertically as integrateVertically ydata = [] -xdata = range (0,180,1) +xdata = range (0,360,STEP_SIZE) for i in xdata: - l = line.duplicate() - l.getProcessor().setBackgroundValue(0.0) - l.getProcessor().rotate(float(i)) - op = op_fft(ip, l, "correlate") + r = ref.duplicate() + r.getProcessor().setBackgroundValue(0.0) + r.getProcessor().rotate(float(i)) + op = op_fft(r, ip, "correlate") bi = op.getBufferedImage() p = integrateVertically(bi) ydata.append(sum(p)) - - #renderer = show_panel(op.bufferedImage) - #time.sleep(0.001) -def moving_average(arr, n) : - ret = [] - for i in range(len(arr)): - ret.append(mean(arr[max(i-n,0):min(i+n,len(arr)-1)])) - return ret -av = moving_average(ydata, 1) - -p = plot(ydata, xdata=xdata)[0] - -p.addSeries(LinePlotSeries("Moving Average")) -p.getSeries(1).setData(xdata, av) +#Calculate angle of the highest correlation, and confidence level peaks = estimate_peak_indexes(ydata, xdata, (min(ydata) + max(ydata))/2, 25.0) -left, right = min(peaks), max(peaks) -if xdata[left]<5 and xdata[right]>(xdata[-1]-5): - #del peaks[0 if ydata[right] > ydata[left] else -1] - peaks.remove(right if ydata[right] > ydata[left] else left) - -peaks = sorted(peaks[:3]) peaks_x = map(lambda x:xdata[x], peaks) peaks_y = map(lambda x:ydata[x], peaks) +confidence = None if len(peaks_x)<2 else int(((float(peaks_y[0])/peaks_y[1])-1) * 1000) +angle = (None if len(peaks_x)==0 else peaks_x[0]) + +#From angle and confidence level estimate hexiposi position +position = None +if angle is not None: + for i in range(len(POSITION_NAMES)): + if abs(POSITION_ANGLES[i] - angle) <= POSITION_TOLERANCE: + position = POSITION_NAMES[i] -print "Peaks", peaks -print "Peak indexes: " + str(peaks_x) -print "Peak values: " + str(peaks_y) +#Plot the correlations values agains angle +if DEBUG: + p = plot(ydata, xdata=xdata)[0] +#Output results +if DEBUG: + print "Peaks", peaks + print "Peak indexes: " + str(peaks_x) + print "Peak values: " + str(peaks_y) + print "Angle: " , angle + print "Position: " , position + print "Confidence: " , confidence -for i in range(len(peaks)): - peak = xdata[peaks[i]] - p.addMarker(peak, None, "N="+str(round(peak,2)), Color(80,0,80)) - if ((peaks[i]>160) and (REF[i]<20)): - peaks[i] = peaks[i] - 180.0 +#Set return value +set_return ([position, angle, confidence]) -print "Peaks x: " + str(peaks_x) - - -d = mean(arrabs(arrsub(REF, peaks_x))) - -print "Angle = ", d \ No newline at end of file diff --git a/script/imgproc/CoverDetection2.py b/script/imgproc/CoverDetection2.py deleted file mode 100644 index 315911e..0000000 --- a/script/imgproc/CoverDetection2.py +++ /dev/null @@ -1,77 +0,0 @@ -################################################################################################### -# Procedure to detect the cover orientation -################################################################################################### - -#Parameters -FRAMES_INTEGRATION = 3 -STEP_SIZE = 2 -POSITION_NAMES = [ 'A','B','C','D', 'E', 'F'] -POSITION_ANGLES = [330, 30, 90, 150, 210, 270] -POSITION_TOLERANCE = 3 -MINIMUM_CONFIDENCE = 10 -DEBUG = cover_detection_debug -REFERENCE_IMG = "ref2" - -#Load reference image -ref = load_image(str("{images}/cover/" + REFERENCE_IMG + ".png") , title="Line") - -#Pre-process camera image -#ip = load_image("{images}/cover/Cover_000" + str(index) + ".png", title="Img") -ip = integrate_frames(FRAMES_INTEGRATION) -ip = grayscale(ip, True) -smooth(ip) -#bandpass_filter(ip, 30, 1000) -edges(ip) -auto_threshold(ip, method = "MaxEntropy") -cx,cy = int(ip.width/2), int(ip.height/2) -ip = sub_image(ip, cx-ref.width/2, cy-ref.height/2, ref.width, ref.height) - -#Show ROI of pre-processed image -if DEBUG: - image_panel = show_panel(ip.bufferedImage) - - -#Calculate correlation between image and reference, rotating the reference from 0 to 360 -import ch.psi.pshell.imaging.Utils.integrateVertically as integrateVertically -ydata = [] -xdata = range (0,360,STEP_SIZE) -for i in xdata: - r = ref.duplicate() - r.getProcessor().setBackgroundValue(0.0) - r.getProcessor().rotate(float(i)) - op = op_fft(r, ip, "correlate") - bi = op.getBufferedImage() - p = integrateVertically(bi) - ydata.append(sum(p)) - - -#Calculate angle of the highest correlation, and confidence level -peaks = estimate_peak_indexes(ydata, xdata, (min(ydata) + max(ydata))/2, 25.0) -peaks_x = map(lambda x:xdata[x], peaks) -peaks_y = map(lambda x:ydata[x], peaks) -confidence = None if len(peaks_x)<2 else int(((float(peaks_y[0])/peaks_y[1])-1) * 1000) -angle = (None if len(peaks_x)==0 else peaks_x[0]) - -#From angle and confidence level estimate hexiposi position -position = None -if angle is not None: - for i in range(len(POSITION_NAMES)): - if abs(POSITION_ANGLES[i] - angle) <= POSITION_TOLERANCE: - position = POSITION_NAMES[i] - -#Plot the correlations values agains angle -if DEBUG: - p = plot(ydata, xdata=xdata)[0] - -#Output results -if DEBUG: - print "Peaks", peaks - print "Peak indexes: " + str(peaks_x) - print "Peak values: " + str(peaks_y) - print "Angle: " , angle - print "Position: " , position - print "Confidence: " , confidence - -#Set return value -set_return ([position, angle, confidence]) - diff --git a/script/imgproc/LedDetectionProc.py b/script/imgproc/LedDetectionProc.py index 3730c23..39c628c 100644 --- a/script/imgproc/LedDetectionProc.py +++ b/script/imgproc/LedDetectionProc.py @@ -3,7 +3,7 @@ ################################################################################################### COVER_PRESENT = True -ROOM_TEMP = False +ROOM_TEMP = is_room_temp() if get_exec_pars().source == CommandSource.ui: PLOT = None @@ -41,11 +41,13 @@ time.sleep(led_latency) img.waitNext(2000) background = average_frames(number_backgrounds) +#background = integrate_frames(number_backgrounds) set_led_state(True) time.sleep(led_latency) img.waitNext(2000) image = average_frames(number_frames) +#image = integrate_frames(number_frames) set_led_state(False) diff --git a/script/imgproc/Utils.py b/script/imgproc/Utils.py index cf7b7f5..c5ed223 100644 --- a/script/imgproc/Utils.py +++ b/script/imgproc/Utils.py @@ -12,7 +12,7 @@ import java.awt.Rectangle as Rectangle def get_img_cover_pos(): - [position, angle, confidence] = run("imgproc/CoverDetection2") + [position, angle, confidence] = run("imgproc/CoverDetection") return position def assert_img_in_cover_pos(pos = None): diff --git a/script/local.py b/script/local.py index 26fc1a7..8e7a0a0 100644 --- a/script/local.py +++ b/script/local.py @@ -69,6 +69,12 @@ def check_puck_detection(): def stop_puck_detection(): run("tools/StopPuckDetection") +DEWAR_LEVEL_RT = 5.0 + +def is_room_temp(): + return dewar_level.read() <= DEWAR_LEVEL_RT + + ################################################################################################### # Device initialization ################################################################################################### diff --git a/script/motion/tools.py b/script/motion/tools.py index bc2eac4..e2215c7 100644 --- a/script/motion/tools.py +++ b/script/motion/tools.py @@ -40,6 +40,13 @@ def set_hexiposi(pos, force = False): else: hexiposi.move(pos) +#Can be used if cover has following error (no checking readback) +def _set_hexiposi(pos): + hexiposi.moveAsync(pos) + time.sleep(1.0) + hexiposi.waitReady(-1) + + def visual_check_hexiposi(segment): #if robot.working_mode == "manual" ? if hexiposi.moved: diff --git a/script/test/CameraCalibration.py b/script/test/CameraCalibration.py new file mode 100644 index 0000000..02e7d9d --- /dev/null +++ b/script/test/CameraCalibration.py @@ -0,0 +1,71 @@ +import ch.psi.pshell.device.Camera as Camera +import ch.psi.pshell.imaging.RendererMode as RendererMode +from ch.psi.pshell.imaging.Overlays import * + +""" +img.camera.setColorMode(Camera.ColorMode.Mono) +img.camera.setDataType(Camera.DataType.UInt8) +img.camera.setGrabMode(Camera.GrabMode.Continuous) +img.camera.setTriggerMode(Camera.TriggerMode.Fixed_Rate) +img.camera.setExposure(50.00) +img.camera.setAcquirePeriod(200.00) +img.camera.setGain(0.0) +img.config.rotationCrop=True + + +""" +#img.camera.setROI(200, 0,1200,1200) + +img.camera.setROI(0, 0,1600,1200) +img.config.rotation=0 +img.config.roiX,img.config.roiY, img.config.roiWidth,img.config.roiHeight =0,0,-1,-1 +img.config.setCalibration(None) +img.camera.stop() +img.camera.start() + +#img.camera.setROI(300, 200,1000,1000) +#img.config.rotation=17 +#img.config.roiX,img.config.roiY, img.config.roiWidth,img.config.roiHeight = 50,50,900,900 + +p = show_panel(img) +p.setMode(RendererMode.Fit) +ov_text = Text(Pen(java.awt.Color.GREEN.darker()), "", java.awt.Font("Verdana", java.awt.Font.PLAIN, 24), java.awt.Point(20,20)) +ov_text.setFixed(True) + + + +p.addOverlay(ov_text) +try: + ov_text.update("Click on upper reference...") + p1 = p.waitClick(60000) + print p1 + ov_text.update("Click on left reference...") + p2 = p.waitClick(60000) + print p2 + ov_text.update("Click on right reference...") + p3 = p.waitClick(60000) + print p3 + + x, y, z = p1.x+p1.y*1j, p2.x+p2.y*1j, p3.x+p3.y*1j + w = z-x + w /= y-x + c = (x-y)*(w-abs(w)**2)/2j/w.imag-x + cx, cy, r = -c.real, -c.imag, abs(c+x) + a = math.degrees(math.atan((cx-p1.x)/(p1.y-cy))) + + print cx, cy, r, a + + #img.camera.setROI(int((1600-cx)/2),int((1200-cy)/2),1000,1000) + img.camera.setROI(int(cx-r),int(cy-r),int(2*r),int(2*r)) + img.config.rotation=-a + #remove rotation border + d=int(r/11) + img.config.roiX,img.config.roiY, img.config.roiWidth,img.config.roiHeight =d,d, int(2*r-2*d), int(2*r-2*d) + #img.config.setCalibration(None) + img.camera.stop() + img.camera.start() + +finally: + p.removeOverlay(ov_text) + + \ No newline at end of file diff --git a/script/test/CoverDetection.py b/script/test/CoverDetection.py new file mode 100644 index 0000000..24a228b --- /dev/null +++ b/script/test/CoverDetection.py @@ -0,0 +1,116 @@ +################################################################################################### +# Procedure to detect the cover orientation +################################################################################################### +import ch.psi.pshell.imaging.Utils.integrateVertically as integrateVertically +img.backgroundEnabled=False + +REF = (0,96,125) + +line = load_image("{images}/line.png", title="Line") +#line = load_image("{images}/line360.png", title="Line") + +line.getProcessor().setBackgroundValue(0.0) + + +#ip = get_image() +ip = integrate_frames(10) +ip = grayscale(ip, True) + + +smooth(ip) +#bandpass_filter(ip, 30, 1000) +edges(ip) + +#invert(ip) +#auto_threshold(ip, method = "Default") + + +#auto_threshold(ip, method = "Li") +auto_threshold(ip, method = "MaxEntropy") + +""" +for m in AutoThresholder.getMethods(): + print m + aux = ip.duplicate() + auto_threshold(aux, method = m) + binary_fill_holes(aux, dark_background=False) + renderer = show_panel(aux.bufferedImage) + time.sleep(1.0) +""" +#binary_dilate(ip, dark_background=False) +#binary_fill_holes(ip, dark_background=False) +#binary_open(ip, dark_background=Tr) + +renderer = show_panel(ip.bufferedImage) + + + + + + + + +#line = sub_image(line, 325, 325, 512, 512) +#ip = sub_image(ip, 325, 325, 512, 512) +line = sub_image(line, 453, 453, 256, 256) +ip = sub_image(ip, 453, 453, 256, 256) +#op = op_fft(ip, line, "correlate") + + +renderer = show_panel(ip.bufferedImage) + +#renderer = show_panel(op.bufferedImage) +#line.show() +ydata = [] +xdata = range (0,180,1) +for i in xdata: + l = line.duplicate() + l.getProcessor().setBackgroundValue(0.0) + l.getProcessor().rotate(float(i)) + op = op_fft(ip, l, "correlate") + bi = op.getBufferedImage() + p = integrateVertically(bi) + ydata.append(sum(p)) + + #renderer = show_panel(op.bufferedImage) + #time.sleep(0.001) + +def moving_average(arr, n) : + ret = [] + for i in range(len(arr)): + ret.append(mean(arr[max(i-n,0):min(i+n,len(arr)-1)])) + return ret +av = moving_average(ydata, 1) + +p = plot(ydata, xdata=xdata)[0] + +p.addSeries(LinePlotSeries("Moving Average")) +p.getSeries(1).setData(xdata, av) + +peaks = estimate_peak_indexes(ydata, xdata, (min(ydata) + max(ydata))/2, 25.0) +left, right = min(peaks), max(peaks) +if xdata[left]<5 and xdata[right]>(xdata[-1]-5): + #del peaks[0 if ydata[right] > ydata[left] else -1] + peaks.remove(right if ydata[right] > ydata[left] else left) + +peaks = sorted(peaks[:3]) +peaks_x = map(lambda x:xdata[x], peaks) +peaks_y = map(lambda x:ydata[x], peaks) + +print "Peaks", peaks +print "Peak indexes: " + str(peaks_x) +print "Peak values: " + str(peaks_y) + + +for i in range(len(peaks)): + peak = xdata[peaks[i]] + p.addMarker(peak, None, "N="+str(round(peak,2)), Color(80,0,80)) + if ((peaks[i]>160) and (REF[i]<20)): + peaks[i] = peaks[i] - 180.0 + +print "Peaks x: " + str(peaks_x) + + +d = mean(arrabs(arrsub(REF, peaks_x))) + +print "Angle = ", d \ No newline at end of file diff --git a/script/imgproc/PuckDetection.py b/script/test/PuckDetection.py similarity index 100% rename from script/imgproc/PuckDetection.py rename to script/test/PuckDetection.py diff --git a/script/imgproc/SampleDetection.py b/script/test/SampleDetection.py similarity index 100% rename from script/imgproc/SampleDetection.py rename to script/test/SampleDetection.py diff --git a/script/test/TestCoverDetection.py b/script/test/TestCoverDetection.py index d65da21..e21e2c0 100644 --- a/script/test/TestCoverDetection.py +++ b/script/test/TestCoverDetection.py @@ -7,7 +7,7 @@ pa = [] #index = i+1 for i in ['A', 'B', 'C', 'D', 'E', 'F']: hexiposi.move(i) - [position, angle, confidence] = run("imgproc/CoverDetection2") + [position, angle, confidence] = run("imgproc/CoverDetection") print [position, angle, confidence] pa.append(position) aa.append(angle)