diff --git a/pom.xml b/pom.xml
index 3a8e027..27c2f7a 100644
--- a/pom.xml
+++ b/pom.xml
@@ -52,6 +52,11 @@
freemarker
2.3.31
+
+ org.opencv
+ opencv-420
+ 4.2.0
+
diff --git a/src/main/java/com/iflytop/digester/StartResetTaskThread.java b/src/main/java/com/iflytop/digester/StartResetTaskThread.java
index 6f09447..a64fb35 100644
--- a/src/main/java/com/iflytop/digester/StartResetTaskThread.java
+++ b/src/main/java/com/iflytop/digester/StartResetTaskThread.java
@@ -8,11 +8,8 @@ import com.iflytop.digester.underframework.dao.model.UfMdbOption;
import com.iflytop.digester.underframework.dao.model.UfMdbRuntimeVariable;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
-
import java.util.HashMap;
import java.util.List;
-import java.util.Map;
-
public class StartResetTaskThread extends Thread {
// logger
public static final Logger LOG = LoggerFactory.getLogger(StartResetTaskThread.class);
@@ -28,15 +25,14 @@ public class StartResetTaskThread extends Thread {
this.setProgressMessage("设备初始化...");
UfCmdSnippetExecutor.execute("StartResetInitDevices");
-// this.setupHeatingSlotCover();
-// this.setupPeristalticPump();
+ this.setupHeatingSlotCover();
+ this.setupPeristalticPump();
if ( this.isErrorTubeRackRequired ) {
this.setupErrorTubeRack();
}
-// this.setProgressMessage("设备初始化 : 相机");
-// DiActCameraBasler camera = this.getActuator(MyDevice.ACT_CAMERA, DiActCameraBasler.class);
-// camera.setEnable(true);
+ this.setProgressMessage("设备初始化 : 相机");
+ device.camera.enable();
this.setProgressMessage("设备初始化 : 定时刷新加热盘温度");
device.heatingTurntable.temperatureMonitorStart();
@@ -50,8 +46,8 @@ public class StartResetTaskThread extends Thread {
// 设置蠕动泵
private void setupPeristalticPump() {
for ( int i=0; i<16; i++ ) {
-// this.setProgressMessage("设备初始化 : 初始化蠕动泵 " + (i+1) + "/16");
-// UfCmdSnippetExecutor.execute(String.format("PeristalticPumpEnable.%d",i));
+ this.setProgressMessage("设备初始化 : 初始化蠕动泵 " + (i+1) + "/16");
+ UfCmdSnippetExecutor.execute(String.format("PeristalticPumpEnable.%d",i));
}
Boolean enableSetup = UfApplication.getApp().getEnv().getProperty("app.liquidPeristalticPumpPipeSetupEnable",Boolean.class);
@@ -70,10 +66,10 @@ public class StartResetTaskThread extends Thread {
Device device = Device.getInstance();
var tubes = List.of(0,4, 3,2, 15,11, 12,13, 1,5, 6,7, 14,10, 9,8);
for ( int i=0; i<8; i++ ) {
-// this.setProgressMessage("设备初始化 : 初始化加液管路 " + (i+1) + "/8");
-// var tubeList = tubes.subList(i*2, i*2+2);
-// var pumpList = List.of(2*i, 2*i+1);
-// device.liquidAddition.addLiquidToTubes(tubeList, pumpList, 10000);
+ this.setProgressMessage("设备初始化 : 初始化加液管路 " + (i+1) + "/8");
+ var tubeList = tubes.subList(i*2, i*2+2);
+ var pumpList = List.of(2*i, 2*i+1);
+ device.liquidAddition.addLiquidToTubes(tubeList, pumpList, 10000);
}
// 加液管充满, 需要取出试管架
diff --git a/src/main/java/com/iflytop/digester/camera/DiComBaslerCamera.java b/src/main/java/com/iflytop/digester/camera/DiComBaslerCamera.java
new file mode 100644
index 0000000..ceb7035
--- /dev/null
+++ b/src/main/java/com/iflytop/digester/camera/DiComBaslerCamera.java
@@ -0,0 +1,129 @@
+package com.iflytop.digester.camera;
+public class DiComBaslerCamera {
+ public static final int ACCESS_MODE_MONITOR = 0;
+ public static final int ACCESS_MODE_CONTROL = 1;
+ public static final int ACCESS_MODE_STREAM = (1 << 1);
+ public static final int ACCESS_MODE_EVENT = (1 << 2);
+ public static final int ACCESS_MODE_EXCLUSIVE = (1 << 3);
+
+ public static class GrabResult {
+ public byte[] imageBuffer;
+ public int payloadType;
+ public int pixelType;
+ public int sizeX;
+ public int sizeY;
+ public int offsetX;
+ public int offsetY;
+ public int paddingX;
+ public int paddingY;
+ public long PayloadSize;
+ public int ErrorCode;
+ }
+
+ /**
+ * Initializes the pylon runtime system.
+ */
+ public native void initialize();
+
+ /**
+ * Enumerates all camera devices.
+ * @return The number of found devices.
+ */
+ public native int enumerateDevices();
+
+ /**
+ * Terminates the pylon runtime system.
+ */
+ public native void terminate();
+
+ /**
+ * Creates a camera device by index.
+ * @param index The index of the camera device.
+ * @return The handle of the camera device.
+ */
+ public native long createDeviceByIndex(int index);
+
+ /**
+ * Opens the camera device.
+ * @param hDev The handle of the camera device.
+ * @param accessMode The access mode.
+ */
+ public native void deviceOpen(long hDev, int accessMode);
+
+ /**
+ * Checks if a camera device feature is readable.
+ * @param hDev The handle of the camera device.
+ * @param name The name of the feature.
+ * @return true if the feature is readable, false otherwise.
+ */
+ public native boolean deviceFeatureIsReadable(long hDev, String name);
+
+ /**
+ * Read a camera device feature to a string.
+ * @param hDev The handle of the camera device.
+ * @param name The name of the feature.
+ * @param size The size of the string buffer.
+ * @return The string value of the feature.
+ */
+ public native String deviceFeatureToString(long hDev, String name, int size);
+
+ /**
+ * Checks if a camera device feature is available.
+ * @param hDev The handle of the camera device.
+ * @param name The name of the feature.
+ * @return true if the feature is available, false otherwise.
+ */
+ public native boolean deviceFeatureIsAvailable(long hDev, String name);
+
+ /**
+ * Writes a camera device feature from a string.
+ * @param hDev The handle of the camera device.
+ * @param name The name of the feature.
+ * @param value The value of the feature.
+ */
+ public native void deviceFeatureFromString(long hDev, String name, String value);
+
+ /**
+ * Checks if a camera device feature is writable.
+ * @param hDev The handle of the camera device.
+ * @param name The name of the feature.
+ * @return true if the feature is writable, false otherwise.
+ */
+ public native boolean deviceFeatureIsWritable(long hDev, String name);
+
+ /**
+ * Writes a camera device feature from an integer.
+ * @param hDev The handle of the camera device.
+ * @param name The name of the feature.
+ * @param value The value of the feature.
+ */
+ public native void deviceSetIntegerFeature(long hDev, String name, int value);
+
+ /**
+ * Reads a camera device feature to an integer.
+ * @param hDev The handle of the camera device.
+ * @param name The name of the feature.
+ * @return The integer value of the feature.
+ */
+ public native int deviceGetIntegerFeatureInt32(long hDev, String name);
+
+ /**
+ * Grabs a single frame from the camera device.
+ * @param hDev The handle of the camera device.
+ * @param channel The channel index.
+ * @return The grab result.
+ */
+ public native GrabResult deviceGrabSingleFrame(long hDev, int channel);
+
+ /**
+ * Closes the camera device.
+ * @param hDev The handle of the camera device.
+ */
+ public native void deviceClose(long hDev);
+
+ /**
+ * Destroys the camera device.
+ * @param hDev The handle of the camera device.
+ */
+ public native void destroyDevice(long hDev);
+}
diff --git a/src/main/java/com/iflytop/digester/deviceinstance/Camera.java b/src/main/java/com/iflytop/digester/deviceinstance/Camera.java
index 5abc97c..fb68da7 100644
--- a/src/main/java/com/iflytop/digester/deviceinstance/Camera.java
+++ b/src/main/java/com/iflytop/digester/deviceinstance/Camera.java
@@ -1,6 +1,74 @@
package com.iflytop.digester.deviceinstance;
+import com.iflytop.digester.camera.DiComBaslerCamera;
import org.springframework.stereotype.Component;
+import org.opencv.core.CvType;
+import org.opencv.core.Mat;
@Component
public class Camera {
+ // camera
+ private static DiComBaslerCamera pylon = null;
+ // index
+ protected Integer index;
+ // channel
+ protected Integer channel;
+ // camera handle
+ private long cam = -1;
+ // get pylon
+ private DiComBaslerCamera getPylon() {
+ if ( null == Camera.pylon ) {
+ Camera.pylon = new DiComBaslerCamera();
+ Camera.pylon.initialize();
+ }
+ return Camera.pylon;
+ }
+
+ // enable
+ public void enable( ) {
+ if ( -1 != this.cam ) {
+ return ;
+ }
+
+ var pylon = this.getPylon();
+ int count = pylon.enumerateDevices();
+ if ( this.index >= count ) {
+ throw new RuntimeException("Camera index out of range");
+ }
+
+ this.cam = pylon.createDeviceByIndex(this.index);
+ pylon.deviceOpen(this.cam, DiComBaslerCamera.ACCESS_MODE_CONTROL | DiComBaslerCamera.ACCESS_MODE_STREAM);
+
+ boolean isFeatureReadable = pylon.deviceFeatureIsReadable(cam, "DeviceModelName");
+ if ( isFeatureReadable ) {
+ String name = pylon.deviceFeatureToString(cam, "DeviceModelName", 256);
+ }
+
+ pylon.deviceFeatureFromString(cam, "PixelFormat", "Mono8");
+ pylon.deviceFeatureFromString(cam, "TriggerSelector", "AcquisitionStart");
+ pylon.deviceFeatureFromString(cam, "TriggerMode", "Off");
+ pylon.deviceFeatureFromString(cam, "TriggerSelector", "FrameStart");
+ pylon.deviceFeatureFromString(cam, "TriggerMode", "Off");
+ pylon.deviceSetIntegerFeature(cam, "GevSCPSPacketSize", 1500);
+ pylon.deviceFeatureFromString(cam, "ExposureAuto", "Off");
+ pylon.deviceSetIntegerFeature(cam, "ExposureTimeRaw", 27218);
+ }
+
+ // disable
+ public void disable() {
+ if ( -1 == this.cam ) {
+ return ;
+ }
+ var pylon = this.getPylon();
+ pylon.deviceClose(this.cam);
+ this.cam = -1;
+ }
+
+ // grab
+ public Mat grabToMat () {
+ var pylon = this.getPylon();
+ var result = pylon.deviceGrabSingleFrame(this.cam, this.channel);
+ Mat frameMat = new Mat(result.sizeY, result.sizeX, CvType.CV_8UC1);
+ frameMat.put(0, 0, result.imageBuffer);
+ return frameMat;
+ }
}