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 { /// /// IdcCamera object represents all IDC cameras. /// Camera ID is an argument of most methods. /// 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; /// /// Enumeration of cameras via static fields and methods /// 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; } } /// /// Currently running camera operation. /// ReadRegisterOp-s are not included in this list, they are independent. /// 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 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(); } } /// /// Restart the camera with a new firmware. /// /// Reference to operation object instance public IOperation StartNewOp() { if (currentOp != CurrentOp.None) throw new Exception("Sequence error"); currentOp = CurrentOp.StartNew; return this; } /// /// Set camera image brightness (camera aperture). /// /// Reference to operation object instance public IOperation SetBrightnessOp() { if (currentOp != CurrentOp.None) throw new Exception("Sequence error"); currentOp = CurrentOp.SetBrightness; return this; } /// /// Grab an image. /// /// Reference to operation object instance public IOperation GrabOp() { if (currentOp != CurrentOp.None) throw new Exception("Sequence error"); currentOp = CurrentOp.Grab; return this; } /// /// Display live image. /// /// Reference to operation object instance public IOperation LiveOp() { if (currentOp != CurrentOp.None) throw new Exception("Sequence error"); currentOp = CurrentOp.Live; return this; } /// /// Display live detail to focus the camera. /// /// Reference to operation object instance public IOperation FocusOp() { if (currentOp != CurrentOp.None) throw new Exception("Sequence error"); currentOp = CurrentOp.Focus; return this; } /// /// Watermeter wheel/arrow detection process. /// /// Region of interest (1..MaxRoisCount) /// Reference to operation object instance 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; } /// /// Watermeter wheel/arrow angle measurement process. /// /// Region of interest (1..MaxRoisCount) /// Reference to operation object instance 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; } /// Start the operation 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; } } } /// /// Check the cameraDev state (OP_COMPLETED or OP_FAILED) /// /// 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; } } } /// Stop the operation public void Stop() { if ((Cfg.DebugLevel == Entities.DebugMode.Normal || Cfg.DebugLevel == Entities.DebugMode.DetectedOn) && (Idc100.IdcState != IdcState.Idle)) { Idc100.StopOp(); } currentOp = CurrentOp.None; } } }