tbf/TestBenchFramework/BenchControl/Cameras/IdcCamera/IdcCamera.cs
Milan Hanajik 94de991bf6 Everything works OK after serious changes:
- 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
2015-01-02 12:51:27 +01:00

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;
}
}
}