Included recovery from camera reconnection & restart

This commit is contained in:
2017-07-07 08:55:23 +02:00
parent 65224680b7
commit 49fb976c2b
2 changed files with 77 additions and 15 deletions

View File

@@ -3,7 +3,7 @@
<modelVersion>4.0.0</modelVersion>
<groupId>ch.psi</groupId>
<artifactId>prosilica</artifactId>
<version>1.0.0</version>
<version>1.0.2</version>
<packaging>jar</packaging>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>

View File

@@ -10,6 +10,7 @@ import ch.psi.pshell.device.ReadonlyRegisterBase;
import ch.psi.pshell.imaging.Source.EmbeddedCameraSource;
import ch.psi.pshell.imaging.SourceBase;
import ch.psi.pshell.imaging.Renderer;
import ch.psi.pshell.imaging.SourceConfig;
import ch.psi.pshell.imaging.Utils;
import java.io.File;
import java.io.IOException;
@@ -26,6 +27,7 @@ import ch.psi.utils.NamedThreadFactory;
import ch.psi.utils.State;
import ch.psi.utils.Sys;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.ScheduledFuture;
@@ -35,10 +37,10 @@ import java.util.logging.Level;
import prosilica.Pv;
public class Prosilica extends SourceBase implements EmbeddedCameraSource {
final long uid;
final HashMap<String, Object> pars;
final boolean monitor;
long uid;
volatile boolean opened;
volatile boolean started;
@@ -53,8 +55,11 @@ public class Prosilica extends SourceBase implements EmbeddedCameraSource {
final int IMAGE_BUFFER_SIZE = 5;
// constructor
public Prosilica(String name, long uid) {
this(name, uid, null);
}
public Prosilica(String name, long uid, String pars) {
super(name);
super(name, new SourceConfig());
this.uid = uid;
this.monitor = "monitor".equalsIgnoreCase(pars);
this.pars = new LinkedHashMap<>();
@@ -75,7 +80,16 @@ public class Prosilica extends SourceBase implements EmbeddedCameraSource {
this.pars.put(parName, parVal);
}
}
}
}
public static void shutdown(){
synchronized(instances){
for (Prosilica prosilica: instances){
prosilica.close();
}
}
disposePvapi();
}
void writePars() throws IOException {
@@ -83,6 +97,37 @@ public class Prosilica extends SourceBase implements EmbeddedCameraSource {
writeParameter(par, pars.get(par));
}
}
@Override
protected void onTimeout(){
{
setState(State.Offline);
try
{
if (started){
getLogger().warning("Detected camera timeout. Restarting...");
stop();
closeCamera();
}
if (hasCamera(uid)){
openCamera(uid);
writePars();
start();
setState(State.Ready);
getLogger().info("Successfully restarted camera");
}
}
catch (Exception ex){
getLogger().log(Level.FINER, null, ex);
}}
//If restart failed try again in 10s
if (!started){
setTimeout(10000);
}
}
///////////////////////////////////////////////////////////////////////////////////////////////
//Monitoring
@@ -129,7 +174,9 @@ public class Prosilica extends SourceBase implements EmbeddedCameraSource {
@Override
protected void doInitialize() throws IOException, InterruptedException {
super.doInitialize();
instances++;
synchronized(instances){
instances.add(this);
}
doClose();
loadPvapi();
opened = true;
@@ -137,17 +184,16 @@ public class Prosilica extends SourceBase implements EmbeddedCameraSource {
try {
waitCamera(uid, 5000);
if (uid > 0) {
openCamera(uid);
} else {
if (uid <= 0) {
HashMap[] info = getCameras();
if (info.length == 0) {
throw new IOException("No camera detected");
}
openCamera((Long) info[0].get("uid"));
uid = (Long) (info[0].get("uid"));
}
setState(State.Ready);
openCamera(uid);
writePars();
setState(State.Ready);
camera.initialize();
} catch (IOException ex) {
getLogger().warning("Error opening the camera: " + ex.getMessage());
@@ -174,7 +220,9 @@ public class Prosilica extends SourceBase implements EmbeddedCameraSource {
if (opened) {
opened = false;
started = false;
instances--;
synchronized(instances){
instances.remove(this);
}
try {
stop();
} catch (Exception ex) {
@@ -187,8 +235,10 @@ public class Prosilica extends SourceBase implements EmbeddedCameraSource {
camera.close();
} catch (Exception ex) {
}
if (instances == 0) {
disposePvapi();
synchronized(instances){
if (instances.size() == 0) {
disposePvapi();
}
}
}
} catch (Exception ex) {
@@ -261,16 +311,18 @@ public class Prosilica extends SourceBase implements EmbeddedCameraSource {
throw new IOException("Error startic acquisition");
}
started = true;
setTimeout(10000);
}
public void stop() throws IOException {
assertInitialized();
setTimeout(-1);
started = false;
if (isStreaming()) {
Pv.CommandRun(handle, "AcquisitionStop");
Pv.CaptureQueueClear(handle);
Pv.CaptureEnd(handle);
}
}
}
public boolean isStarted() {
@@ -301,7 +353,7 @@ public class Prosilica extends SourceBase implements EmbeddedCameraSource {
///////////////////////////////////////////////////////////////////////////////////////////////
//PvAPI initialization
///////////////////////////////////////////////////////////////////////////////////////////////
private static int instances = 0;
private static final List<Prosilica> instances = new ArrayList<>();
private static boolean loadedPvapi = false;
private static void loadPvapi() throws IOException {
@@ -342,6 +394,16 @@ public class Prosilica extends SourceBase implements EmbeddedCameraSource {
}
}
private static boolean hasCamera(Long uid) {
Chrono chrono = new Chrono();
for (HashMap info : getCameras()) {
if ((uid == null) || uid.equals(info.get("uid"))) {
return true;
}
}
return false;
}
///////////////////////////////////////////////////////////////////////////////////////////////
//Camera selection
///////////////////////////////////////////////////////////////////////////////////////////////