- all components, componentCfg-s and parameter providers use base classes - less boilerplate code, simpler access to test/procedure parameters from code - CreateTestParams(test), CreateProcedureParams(procedure) methods added - TestBenchSim class is made static, it is not inheritted by any device anymore
300 lines
8.6 KiB
C#
300 lines
8.6 KiB
C#
using System;
|
|
using System.Diagnostics;
|
|
using System.Collections.Generic;
|
|
using System.Threading;
|
|
using TBF.BenchControl;
|
|
using TBF.BenchControl.Generic;
|
|
using log4net;
|
|
|
|
namespace TBF.BenchControl.Cameras.IdcCamera
|
|
{
|
|
/// <summary>
|
|
/// IdcCamera object represents all IDC cameras.
|
|
/// Camera ID is an argument of most methods.
|
|
/// </summary>
|
|
public class IdcCamera : ComponentBase, IDevice, IOperation, GenericDevices.ICamera
|
|
{
|
|
private static readonly ILog log = LogManager.GetLogger(typeof(IdcCamera));
|
|
public override string ToString() { return string.Format("IdcCamera({0})", Cfg.ToString(1)); }
|
|
|
|
readonly IdcCameraCfg idcCameraCfg;
|
|
|
|
const int MaxRoisCount = 4;
|
|
|
|
/// <summary>
|
|
/// Enumeration of cameras via static fields and methods
|
|
/// </summary>
|
|
static int nextCameraNr = 0;
|
|
public static new void ResetStaticProperties()
|
|
{
|
|
nextCameraNr = 0;
|
|
}
|
|
|
|
int cameraNr;
|
|
public int CameraNr { get { return cameraNr; } }
|
|
|
|
public float Brightness { get { return idcCameraCfg.BrightnessCam; } }
|
|
|
|
/// <summary>
|
|
/// Currently running camera operation.
|
|
/// ReadRegisterOp-s are not included in this list, they are independent.
|
|
/// </summary>
|
|
public enum CurrentOp
|
|
{
|
|
None,
|
|
StartNew,
|
|
SetBrightness,
|
|
Grab,
|
|
Live,
|
|
Focus,
|
|
Detect,
|
|
Measure,
|
|
}
|
|
|
|
/// Private fields
|
|
public Idc100 Idc100; /// Idc100 camera low level implementation
|
|
CurrentOp currentOp;
|
|
int currentRoiId;
|
|
IWorkerCmd detectCmd;
|
|
IWorkerCmd measureCmd;
|
|
|
|
public IdcCamera(IdcCameraCfg cfg, IList<Generic.IComponent> components)
|
|
: base(cfg)
|
|
{
|
|
idcCameraCfg = cfg;
|
|
cameraNr = nextCameraNr++;
|
|
log.Debug(this.ToString());
|
|
}
|
|
|
|
public void Initialize()
|
|
{
|
|
if (idcCameraCfg.DebugLevel == Entities.DebugMode.Simulate)
|
|
{
|
|
log.WarnFormat("{0}: in simulation mode", Name);
|
|
return;
|
|
}
|
|
|
|
/// Initialize the camera
|
|
Idc100 = new Idc100(Name, cameraNr, idcCameraCfg.ComPortNr, idcCameraCfg.BaudRate, idcCameraCfg.BrightnessCam);
|
|
RetVal rVal = Idc100.StartOp(new Command.Connect(3000)); /// timeout in ms
|
|
|
|
|
|
if (idcCameraCfg.DebugLevel == Entities.DebugMode.AutoDetect)
|
|
{
|
|
if (rVal == RetVal.OK)
|
|
idcCameraCfg.DebugLevel = Entities.DebugMode.DetectedOn;
|
|
else
|
|
idcCameraCfg.DebugLevel = Entities.DebugMode.DetectedOff;
|
|
}
|
|
else if (rVal != RetVal.OK)
|
|
{
|
|
throw (new Exception(string.Format("Cannot make a connection to {0} on COM{1}", Name, idcCameraCfg.ComPortNr)));
|
|
}
|
|
|
|
if (idcCameraCfg.DebugLevel != Entities.DebugMode.DetectedOff)
|
|
{
|
|
log.FatalFormat("Successfully initialized device {0}", ToString());
|
|
}
|
|
}
|
|
|
|
public void RunDeviceBefore()
|
|
{
|
|
}
|
|
|
|
public void RunDeviceAfter()
|
|
{
|
|
}
|
|
|
|
public void StopDevice()
|
|
{
|
|
if (Idc100 != null)
|
|
{
|
|
RetVal rVal = Idc100.StartOp(new Command.Disconnect());
|
|
Idc100.ShutDown();
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Restart the camera with a new firmware.
|
|
/// </summary>
|
|
/// <returns>Reference to operation object instance</returns>
|
|
public IOperation StartNewOp()
|
|
{
|
|
if (currentOp != CurrentOp.None) throw new Exception("Sequence error");
|
|
currentOp = CurrentOp.StartNew;
|
|
return this;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Set camera image brightness (camera aperture).
|
|
/// </summary>
|
|
/// <returns>Reference to operation object instance</returns>
|
|
public IOperation SetBrightnessOp()
|
|
{
|
|
if (currentOp != CurrentOp.None) throw new Exception("Sequence error");
|
|
currentOp = CurrentOp.SetBrightness;
|
|
return this;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Grab an image.
|
|
/// </summary>
|
|
/// <returns>Reference to operation object instance</returns>
|
|
public IOperation GrabOp()
|
|
{
|
|
if (currentOp != CurrentOp.None) throw new Exception("Sequence error");
|
|
currentOp = CurrentOp.Grab;
|
|
return this;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Display live image.
|
|
/// </summary>
|
|
/// <returns>Reference to operation object instance</returns>
|
|
public IOperation LiveOp()
|
|
{
|
|
if (currentOp != CurrentOp.None) throw new Exception("Sequence error");
|
|
currentOp = CurrentOp.Live;
|
|
return this;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Display live detail to focus the camera.
|
|
/// </summary>
|
|
/// <returns>Reference to operation object instance</returns>
|
|
public IOperation FocusOp()
|
|
{
|
|
if (currentOp != CurrentOp.None) throw new Exception("Sequence error");
|
|
currentOp = CurrentOp.Focus;
|
|
return this;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Watermeter wheel/arrow detection process.
|
|
/// </summary>
|
|
/// <param name="roiId">Region of interest (1..MaxRoisCount)</param>
|
|
/// <returns>Reference to operation object instance</returns>
|
|
public IOperation DetectOp(int roiId, IWorkerCmd detectCmd)
|
|
{
|
|
if (currentOp != CurrentOp.None) throw new Exception("Sequence error");
|
|
if (roiId < 1 || roiId > MaxRoisCount) throw new ArgumentOutOfRangeException("roiId");
|
|
currentOp = CurrentOp.Detect;
|
|
this.currentRoiId = roiId;
|
|
this.detectCmd = detectCmd;
|
|
return this;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Watermeter wheel/arrow angle measurement process.
|
|
/// </summary>
|
|
/// <param name="roiId">Region of interest (1..MaxRoisCount)</param>
|
|
/// <returns>Reference to operation object instance</returns>
|
|
public IOperation MeasureOp(int roiId, IWorkerCmd measureCmd)
|
|
{
|
|
if (currentOp != CurrentOp.None) throw new Exception("Sequence error");
|
|
if (roiId < 1 || roiId > MaxRoisCount) throw new ArgumentOutOfRangeException("roiId");
|
|
currentOp = CurrentOp.Measure;
|
|
this.currentRoiId = roiId;
|
|
this.measureCmd = measureCmd;
|
|
return this;
|
|
}
|
|
|
|
/// <summary>Start the operation</summary>
|
|
public void Start()
|
|
{
|
|
if (Cfg.DebugLevel == Entities.DebugMode.Normal || Cfg.DebugLevel == Entities.DebugMode.DetectedOn)
|
|
{
|
|
switch (currentOp)
|
|
{
|
|
case CurrentOp.StartNew:
|
|
Idc100.StartOp(new Command.StartNew());
|
|
return;
|
|
case CurrentOp.Grab:
|
|
Idc100.StartOp(new Command.Grab("snap1", FileFormat.Jpeg, Brightness, false));
|
|
return;
|
|
case CurrentOp.Live:
|
|
Idc100.StartOp(new Command.Stream(StreamType.SubSampled, FileFormat.Jpeg, Brightness));
|
|
return;
|
|
case CurrentOp.Focus:
|
|
Idc100.StartOp(new Command.Stream(StreamType.Focus, FileFormat.Bmp, Brightness));
|
|
return;
|
|
case CurrentOp.Detect:
|
|
Idc100.StartOp(this.detectCmd);
|
|
return;
|
|
case CurrentOp.Measure:
|
|
Idc100.StartOp(this.measureCmd);
|
|
return;
|
|
}
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Check the cameraDev state (OP_COMPLETED or OP_FAILED)
|
|
/// </summary>
|
|
/// <returns></returns>
|
|
public Event Run()
|
|
{
|
|
if (Cfg.DebugLevel == Entities.DebugMode.Normal || Cfg.DebugLevel == Entities.DebugMode.DetectedOn)
|
|
{
|
|
switch (currentOp)
|
|
{
|
|
case CurrentOp.Grab:
|
|
if (Idc100.IdcState == IdcState.Idle) return Event.None;
|
|
else return Event.Error;
|
|
|
|
case CurrentOp.StartNew:
|
|
case CurrentOp.Live:
|
|
case CurrentOp.Focus:
|
|
case CurrentOp.Measure:
|
|
case CurrentOp.Detect:
|
|
if (Idc100.IdcState == IdcState.Busy)
|
|
{
|
|
return Event.CameraBusy;
|
|
}
|
|
else if (Idc100.IdcState == IdcState.OpCompleted)
|
|
{
|
|
log.InfoFormat("{0}: {1} - OpCompleted", cameraNr, currentOp);
|
|
return Event.CameraOpCompleted;
|
|
}
|
|
else if (Idc100.IdcState == IdcState.OpFailed)
|
|
{
|
|
log.WarnFormat("{0}: {1} - OpFailed", cameraNr, currentOp);
|
|
return Event.CameraOpFailed;
|
|
}
|
|
else if (Idc100.IdcState == IdcState.DetectionFailed)
|
|
{
|
|
log.WarnFormat("{0}: {1} - DetectionFailed", cameraNr, currentOp);
|
|
return Event.DetectionFailed;
|
|
}
|
|
else return Event.Error;
|
|
|
|
default:
|
|
return Event.Error;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if (currentOp == CurrentOp.Grab)
|
|
{
|
|
return Event.None;
|
|
}
|
|
else
|
|
{
|
|
return Event.CameraOpCompleted;
|
|
}
|
|
}
|
|
}
|
|
|
|
/// <summary>Stop the operation</summary>
|
|
public void Stop()
|
|
{
|
|
if ((Cfg.DebugLevel == Entities.DebugMode.Normal || Cfg.DebugLevel == Entities.DebugMode.DetectedOn)
|
|
&& (Idc100.IdcState != IdcState.Idle))
|
|
{
|
|
Idc100.StopOp();
|
|
}
|
|
currentOp = CurrentOp.None;
|
|
}
|
|
}
|
|
}
|