348 lines
14 KiB
Java
348 lines
14 KiB
Java
import ch.psi.pshell.bs.PipelineServer;
|
|
import ch.psi.pshell.bs.StreamValue;
|
|
import ch.psi.pshell.core.CommandSource;
|
|
import ch.psi.pshell.device.Device;
|
|
import ch.psi.pshell.device.DeviceAdapter;
|
|
import ch.psi.pshell.device.DeviceListener;
|
|
import ch.psi.pshell.imaging.ColormapSource;
|
|
import ch.psi.pshell.imaging.Overlay;
|
|
import ch.psi.pshell.imaging.Overlays;
|
|
import ch.psi.pshell.scan.MonitorScan;
|
|
import ch.psi.pshell.swing.DataPanel;
|
|
import ch.psi.pshell.ui.App;
|
|
import ch.psi.pshell.ui.Panel;
|
|
import ch.psi.utils.State;
|
|
import ch.psi.utils.Threading;
|
|
import ch.psi.utils.swing.MainFrame;
|
|
import ch.psi.utils.swing.SwingUtils;
|
|
import java.awt.Dimension;
|
|
import java.awt.Font;
|
|
import java.awt.Point;
|
|
import java.io.File;
|
|
import java.io.IOException;
|
|
import java.nio.file.Paths;
|
|
import java.util.HashMap;
|
|
import java.util.concurrent.Future;
|
|
import java.util.logging.Level;
|
|
import java.util.logging.Logger;
|
|
import javax.swing.ImageIcon;
|
|
|
|
/**
|
|
*
|
|
*/
|
|
public class AthosCameras extends Panel {
|
|
|
|
PipelineServer imagePipeline;
|
|
PipelineServer dataPipeline;
|
|
String serverUrl;
|
|
Overlay errorOverlay;
|
|
String imageInstanceName;
|
|
String dataInstanceName;
|
|
String cameraName;
|
|
String persistFile = "{context}/AthosCameras";
|
|
|
|
final String CAMERA_DEVICE_NAME = "AthosCamera";
|
|
String pipelineSuffixData = "_acd";
|
|
String pipelineSuffixImage = "_aci";
|
|
|
|
boolean persisting;
|
|
|
|
public AthosCameras() {
|
|
initComponents();
|
|
|
|
}
|
|
|
|
ImageIcon getIcon(String name){
|
|
return new ImageIcon(ch.psi.pshell.ui.App.class.getResource("/ch/psi/pshell/ui/" + (MainFrame.isDark() ? "dark/": "") + name + ".png"));
|
|
}
|
|
|
|
//Overridable callbacks
|
|
@Override
|
|
public void onInitialize(int runCount) {
|
|
if (App.hasArgument("cam")) {
|
|
try {
|
|
setCamera(App.getArgumentValue("cam"));
|
|
} catch (Exception ex) {
|
|
Logger.getLogger(AthosCameras.class.getName()).log(Level.SEVERE, null, ex);
|
|
}
|
|
}
|
|
renderer.setPersistenceFile(Paths.get(getContext().getSetup().expandPath(persistFile)));
|
|
}
|
|
|
|
@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() {
|
|
}
|
|
|
|
|
|
PipelineServer newServer() throws IOException {
|
|
if (serverUrl != null) {
|
|
System.out.println("Connecting to server: " + serverUrl);
|
|
imagePipeline = new PipelineServer(CAMERA_DEVICE_NAME, serverUrl);
|
|
} else {
|
|
System.out.println("Connecting to server");
|
|
imagePipeline = new PipelineServer(CAMERA_DEVICE_NAME);
|
|
}
|
|
return imagePipeline;
|
|
}
|
|
|
|
void setCamera(String cameraName) throws IOException, InterruptedException {
|
|
System.out.println("Initializing: " + cameraName);
|
|
renderer.setDevice(null);
|
|
renderer.setShowReticle(false);
|
|
renderer.clear();
|
|
renderer.resetZoom();
|
|
|
|
boolean changed = !String.valueOf(cameraName).equals(this.cameraName);
|
|
this.cameraName = cameraName;
|
|
|
|
|
|
if (cameraName == null) {
|
|
return;
|
|
}
|
|
|
|
System.out.println("Setting camera: " + cameraName );
|
|
try{
|
|
imagePipeline = newServer();
|
|
imagePipeline.getConfig().flipHorizontally = false;
|
|
imagePipeline.getConfig().flipVertically = false;
|
|
imagePipeline.getConfig().rotation = 0.0;
|
|
imagePipeline.getConfig().roiX = 0;
|
|
imagePipeline.getConfig().roiY = 0;
|
|
imagePipeline.getConfig().roiWidth = -1;
|
|
imagePipeline.getConfig().roiHeight = -1;
|
|
imagePipeline.getConfig().save();
|
|
imagePipeline.initialize();
|
|
imagePipeline.assertInitialized();
|
|
System.out.println("Image pipeline initialization OK");
|
|
|
|
String pipelineName = cameraName + pipelineSuffixImage;
|
|
imageInstanceName = cameraName + pipelineSuffixImage + "1";
|
|
if (!imagePipeline.getPipelines().contains(pipelineSuffixImage)) {
|
|
System.out.println("Creating pipeline: " + pipelineName);
|
|
HashMap<String, Object> config = new HashMap<>();
|
|
config.put("camera_name", cameraName);
|
|
//config.put("include", new String[]{"image", "width", "height"});
|
|
config.put("function", "transparent");
|
|
config.put("max_frame_rate" , 2.1);
|
|
//server.createFromConfig(config, pipelineName);
|
|
imagePipeline.savePipelineConfig(pipelineName, config);
|
|
}
|
|
imagePipeline.start(pipelineName, imageInstanceName);
|
|
renderer.setDevice(imagePipeline);
|
|
|
|
|
|
dataPipeline = newServer();
|
|
//dataPipeline.getConfig().copyFrom(imagePipeline.getConfig());
|
|
dataPipeline.initialize();
|
|
dataPipeline.assertInitialized();
|
|
System.out.println("Data pipeline initialization OK");
|
|
|
|
pipelineName = cameraName + pipelineSuffixData;
|
|
dataInstanceName = cameraName + pipelineSuffixData + "1";
|
|
if (!dataPipeline.getPipelines().contains(pipelineSuffixData)) {
|
|
System.out.println("Creating pipeline: " + pipelineName);
|
|
HashMap<String, Object> config = new HashMap<>();
|
|
config.put("camera_name", cameraName);
|
|
config.put("include", new String[]{"x_center_of_mass", "y_center_of_mass"});
|
|
//server.createFromConfig(config, pipelineName);
|
|
dataPipeline.savePipelineConfig(pipelineName, config);
|
|
}
|
|
dataPipeline.start(pipelineName, dataInstanceName);
|
|
|
|
dataPipeline.getStream().addListener(new DeviceAdapter() {
|
|
@Override
|
|
public void onCacheChanged(Device device, Object value, Object former, long timestamp, boolean arg4) {
|
|
updateData((StreamValue)value);
|
|
}
|
|
});
|
|
|
|
} catch (Exception ex) {
|
|
showException(ex);
|
|
renderer.clearOverlays();
|
|
if (renderer.getDevice() == null) {
|
|
//renderer.setZoom(1.0);
|
|
//renderer.setMode(RendererMode.Zoom);
|
|
errorOverlay = new Overlays.Text(renderer.getPenErrorText(), ex.toString(), new Font("Verdana", Font.PLAIN, 12), new Point(20, 20));
|
|
errorOverlay.setFixed(true);
|
|
errorOverlay.setAnchor(Overlay.ANCHOR_VIEWPORT_TOP_LEFT);
|
|
renderer.addOverlay(errorOverlay);
|
|
}
|
|
} finally {
|
|
//checkReticle();
|
|
onTimer();
|
|
}
|
|
}
|
|
|
|
String getDoubleStr(StreamValue sv, String id){
|
|
return String.format("%1.4f", sv.getValue(id));
|
|
}
|
|
|
|
void updateData(StreamValue value){
|
|
//System.exit(0);
|
|
try{
|
|
edit_x_center_of_mass.setText(getDoubleStr(value, "x_center_of_mass"));
|
|
} catch (Exception ex){
|
|
edit_x_center_of_mass.setText("");
|
|
}
|
|
try{
|
|
edit_y_center_of_mass.setText(getDoubleStr(value, "y_center_of_mass"));
|
|
} catch (Exception ex){
|
|
edit_y_center_of_mass.setText("");
|
|
}
|
|
}
|
|
|
|
MonitorScan scan;
|
|
|
|
void startRecording() throws Exception{
|
|
System.out.println("startRecording");
|
|
getContext().startExecution(CommandSource.plugin, null, cameraName,null, false);
|
|
getContext().setExecutionPar("name", cameraName);
|
|
getContext().setExecutionPar("open", true);
|
|
scan= new MonitorScan(dataPipeline.getStream(), dataPipeline.getStream().getReadables().toArray(new ch.psi.pshell.device.Readable[0]), -1, -1);
|
|
Threading.getFuture(() ->scan.start());
|
|
|
|
DataPanel panel = DataPanel.create(new File(getContext().getExecutionPars().getPath()));
|
|
SwingUtils.showDialog(getTopLevel(), getContext().getExecutionPars().getPath(), new Dimension(800,600), panel);
|
|
|
|
}
|
|
|
|
void stopRecording() throws Exception{
|
|
System.out.println("stopRecording");
|
|
scan.abort();
|
|
|
|
//showMessage("Data recording", "Data saved to: " + getContext().getExecutionPars().getPath());
|
|
|
|
|
|
getContext().endExecution();
|
|
}
|
|
|
|
|
|
|
|
@SuppressWarnings("unchecked")
|
|
// <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
|
|
private void initComponents() {
|
|
|
|
renderer = new ch.psi.pshell.imaging.Renderer();
|
|
jLabel1 = new javax.swing.JLabel();
|
|
jLabel2 = new javax.swing.JLabel();
|
|
edit_y_center_of_mass = new javax.swing.JTextField();
|
|
edit_x_center_of_mass = new javax.swing.JTextField();
|
|
buttonRec = new javax.swing.JToggleButton();
|
|
buttonStop = new javax.swing.JButton();
|
|
|
|
jLabel1.setText("x_center_of_mass:");
|
|
|
|
jLabel2.setText("y_center_of_mass:");
|
|
|
|
edit_y_center_of_mass.setEditable(false);
|
|
edit_y_center_of_mass.setHorizontalAlignment(javax.swing.JTextField.TRAILING);
|
|
|
|
edit_x_center_of_mass.setEditable(false);
|
|
edit_x_center_of_mass.setHorizontalAlignment(javax.swing.JTextField.TRAILING);
|
|
|
|
buttonRec.setIcon(getIcon("Rec"));
|
|
buttonRec.setToolTipText("Start Data Recording");
|
|
buttonRec.addActionListener(new java.awt.event.ActionListener() {
|
|
public void actionPerformed(java.awt.event.ActionEvent evt) {
|
|
buttonRecActionPerformed(evt);
|
|
}
|
|
});
|
|
|
|
buttonStop.setIcon(getIcon("Stop"));
|
|
buttonStop.setEnabled(false);
|
|
buttonStop.addActionListener(new java.awt.event.ActionListener() {
|
|
public void actionPerformed(java.awt.event.ActionEvent evt) {
|
|
buttonStopActionPerformed(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()
|
|
.addContainerGap(582, Short.MAX_VALUE)
|
|
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
|
.addGroup(layout.createSequentialGroup()
|
|
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING)
|
|
.addComponent(jLabel1)
|
|
.addComponent(jLabel2))
|
|
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
|
|
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
|
.addComponent(edit_y_center_of_mass, javax.swing.GroupLayout.PREFERRED_SIZE, 124, javax.swing.GroupLayout.PREFERRED_SIZE)
|
|
.addComponent(edit_x_center_of_mass, javax.swing.GroupLayout.PREFERRED_SIZE, 124, javax.swing.GroupLayout.PREFERRED_SIZE)))
|
|
.addGroup(layout.createSequentialGroup()
|
|
.addComponent(buttonRec)
|
|
.addGap(2, 2, 2)
|
|
.addComponent(buttonStop)))
|
|
.addGap(72, 72, 72))
|
|
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
|
.addGroup(layout.createSequentialGroup()
|
|
.addContainerGap()
|
|
.addComponent(renderer, javax.swing.GroupLayout.PREFERRED_SIZE, 462, javax.swing.GroupLayout.PREFERRED_SIZE)
|
|
.addContainerGap(440, Short.MAX_VALUE)))
|
|
);
|
|
layout.setVerticalGroup(
|
|
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
|
.addGroup(layout.createSequentialGroup()
|
|
.addGap(132, 132, 132)
|
|
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
|
.addComponent(jLabel1)
|
|
.addComponent(edit_x_center_of_mass, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
|
|
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
|
|
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
|
|
.addComponent(jLabel2)
|
|
.addComponent(edit_y_center_of_mass, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
|
|
.addGap(123, 123, 123)
|
|
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING)
|
|
.addComponent(buttonRec)
|
|
.addComponent(buttonStop))
|
|
.addContainerGap(190, Short.MAX_VALUE))
|
|
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
|
.addGroup(layout.createSequentialGroup()
|
|
.addContainerGap()
|
|
.addComponent(renderer, javax.swing.GroupLayout.DEFAULT_SIZE, 520, Short.MAX_VALUE)
|
|
.addContainerGap()))
|
|
);
|
|
}// </editor-fold>//GEN-END:initComponents
|
|
|
|
private void buttonRecActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_buttonRecActionPerformed
|
|
try{
|
|
buttonStop.setEnabled(buttonRec.isSelected());
|
|
if (buttonRec.isSelected()){
|
|
startRecording();
|
|
} else {
|
|
stopRecording();
|
|
}
|
|
} catch (Exception ex){
|
|
this.showException(ex);
|
|
}
|
|
}//GEN-LAST:event_buttonRecActionPerformed
|
|
|
|
private void buttonStopActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_buttonStopActionPerformed
|
|
buttonRec.setSelected(false);
|
|
buttonRecActionPerformed(null);
|
|
}//GEN-LAST:event_buttonStopActionPerformed
|
|
|
|
// Variables declaration - do not modify//GEN-BEGIN:variables
|
|
private javax.swing.JToggleButton buttonRec;
|
|
private javax.swing.JButton buttonStop;
|
|
private javax.swing.JTextField edit_x_center_of_mass;
|
|
private javax.swing.JTextField edit_y_center_of_mass;
|
|
private javax.swing.JLabel jLabel1;
|
|
private javax.swing.JLabel jLabel2;
|
|
private ch.psi.pshell.imaging.Renderer renderer;
|
|
// End of variables declaration//GEN-END:variables
|
|
}
|