Refactorization : BenchControl -> Rig

This commit is contained in:
Milan Hanajik
2021-03-05 16:12:24 +01:00
parent 84c8ec26b6
commit 6cf3bd6160
1461 changed files with 6330 additions and 6330 deletions
+27
View File
@@ -0,0 +1,27 @@
///
/// Copyright (c) 2017 Sensus Metering Systems
///
using System.Collections.Generic;
using TBF.Rig.Generic;
namespace TBF.Rig.Network.Camera.Roi
{
public class Factory : IComponentFactory
{
public string ClassName { get { return this.GetType().Namespace.Substring(8); } }
public override string ToString() { return ClassName; }
public void ResetStaticProperties() { Roi.ResetStaticProperties(); }
public IComponent DummyComponent() { return new Roi(); }
public IComponent GetComponent(IComponentCfg cfg, IList<IComponent> components) { return new Roi(cfg, components); }
public IComponentCfg DefaultConfig() { return new RoiCfg(this.GetType().Namespace.Substring(8), this); }
public IComponentCfg CmpntCfgFromCmpntEntity(Config.Entities.Component component)
{
return ComponentCfgBase.CreateFromDbEntity(RoiCfg.Serializer, component, this);
}
}
}
@@ -0,0 +1,148 @@
///
/// Copyright (c) 2017 Sensus Metering Systems
///
using System;
using System.IO;
using System.Text;
using System.Xml.Serialization;
using Config.Entities;
using TBF.Rig.Generic;
using TBF.Resources;
namespace TBF.Rig.Network.Camera.Roi
{
public class ProcedureParams : ProcedureParamsBase, IParamsProvider, IProcedureParams
{
public static XmlSerializer Serializer = XmlSerializer.FromTypes(new[] { typeof(ProcedureParams) })[0];
public override XmlSerializer GetSerializer() { return Serializer; }
public double PulsesPerLtr; /// [l^-1]
public int DetectionImagesCount;
public int DetectionPeriod1;
public int DetectionPeriod2;
public string RoiParams;
public override void InitializeAll()
{
PulsesPerLtr = 1.0;
DetectionImagesCount = 10;
DetectionPeriod1 = 1;
DetectionPeriod2 = 19;
RoiParams = "160 160 79 79 20 79 0 0 360 360 1 50 0 0 50 0";
}
string[] paramNames = new string[]
{
Strings.PulsesPerLtr,
"Images count",
"Period1",
"Period2",
"Parameters"
};
public override string ParamName(int i) { return paramNames[i]; }
public override int ParamsCount() { return paramNames.Length; }
public override string ToString(int i)
{
switch (i)
{
case 0: return PulsesPerLtr.ToString();
case 1: return DetectionImagesCount.ToString();
case 2: return DetectionPeriod1.ToString();
case 3: return DetectionPeriod2.ToString();
case 4: return RoiParams;
default: return string.Empty;
}
}
/// Retrieves parameters from UI controls
public CfgUpdateFlags UpdateParam(int i, string strValue)
{
switch (i)
{
case 0: PulsesPerLtr = Utils.ParseUDouble(strValue); return CfgUpdateFlags.None;
case 1: DetectionImagesCount = int.Parse(strValue); return CfgUpdateFlags.None;
case 2: DetectionPeriod1 = int.Parse(strValue); return CfgUpdateFlags.None;
case 3: DetectionPeriod2 = int.Parse(strValue); return CfgUpdateFlags.None;
case 4: RoiParams = strValue; return CfgUpdateFlags.None;
default: return CfgUpdateFlags.None;
}
}
/// Verifies whether strings in UI controls represent valid parameters
public bool ValidateParam(int i, string strValue, out string message)
{
message = string.Empty;
double dummy;
int idummy;
switch (i)
{
case 0:
if (Utils.TryParseUDouble(strValue, out dummy)) return true;
break;
case 1:
case 2:
case 3:
if (int.TryParse(strValue, out idummy) && idummy >= 1 && idummy <= 50) return true;
break;
case 4:
return true;
default:
message = "Invalid index";
return false;
}
message = ParamName(i) + " is invalid";
return false;
}
void CopyContentTo(ProcedureParams prms)
{
prms.PulsesPerLtr = this.PulsesPerLtr;
prms.DetectionImagesCount = this.DetectionImagesCount;
prms.DetectionPeriod1 = this.DetectionPeriod1;
prms.DetectionPeriod2 = this.DetectionPeriod2;
prms.RoiParams = this.RoiParams;
}
public IParamsProvider Clone()
{
ProcedureParams pars = new ProcedureParams();
CopyContentTo(pars);
return pars;
}
public override void UpdateFromDbEntity(ComponentProcedure dbEntity)
{
if (dbEntity == null) return;
try
{
ProcedureParams tmp = Serializer.Deserialize(new StringReader(dbEntity.Parameters)) as ProcedureParams;
procedureParamsEntity = dbEntity;
componentName = dbEntity.CmpntName;
procedure = dbEntity.Procedure;
if (tmp != null) tmp.CopyContentTo(this);
}
catch
{
}
}
public ProcedureParams() { }
public ProcedureParams(bool initialize)
{
if (initialize) InitializeAll();
}
public ProcedureParams(ComponentProcedure procedureParamsEntity, string componentName, Procedure procedure)
{
this.procedureParamsEntity = procedureParamsEntity;
this.componentName = componentName;
this.procedure = procedure;
}
}
}
+266
View File
@@ -0,0 +1,266 @@
///
/// Copyright (c) 2017 Sensus Metering Systems
///
using System;
using System.Collections.Generic;
using System.IO;
using System.Text;
using log4net;
using Config.Entities;
namespace TBF.Rig.Network.Camera.Roi
{
public class Roi : ComponentBase, GenericDevices.IRegReaderLiveCamera, IOperation
{
/// TODO: Implement support for sharing one camera by multiple ROI-s
private static readonly ILog log = LogManager.GetLogger(typeof(Roi));
public override string ToString()
{
return string.Format("{0}({1})", this.GetType().Namespace.Substring(8), Cfg.ToString(1));
}
///
/// Cfg
///
public readonly RoiCfg RoiCfg;
public readonly CLP1611.Camera NetCamera;
public readonly Roi PreviousRoi;
///
/// ICamera interface functions
///
public GenericDevices.ICamera Camera { get { return NetCamera as GenericDevices.ICamera; } }
public int Position
{
get
{
int firstDigitPos = Name.IndexOfAny(new char[] { '1', '2', '3', '4', '5', '6', '7', '8', '9', '0' });
int position;
return (firstDigitPos < 0) ? 0 : (int.TryParse(Name.Substring(firstDigitPos), out position) ? position : 0);
}
}
public Config.Entities.RegisterReaderType RegisterReaderType { get { return Config.Entities.RegisterReaderType.Camera; } }
public double PulsesPerLtr { get { return RoiCfg.ProcParams.PulsesPerLtr; } }
public double LtrsPerPulse { get { return (PulsesPerLtr <= float.Epsilon) ? 1.0 : (1 / PulsesPerLtr); } }
int cameraPulses;
int pulsesDelta; /// = (WMPulses - cameraPulses) ... WMPulses = cameraPulses + pulsesDelta, Clear() calculates pulsesDelta
public int WMPulses { get { return cameraPulses + pulsesDelta; } }
long cameraTime;
long timeDelta; /// = (WMTestTime - cameraTime) ... WMTestTime = cameraTime + timeDelta, Clear() calculates timeDelta
public double WMTestTime { get { return (cameraTime + timeDelta) / 1000.0; } }
int wmRefPulses;
public int WMRefPulses { get { return wmRefPulses; } }
public double WMVolume { get { return LtrsPerPulse * (double)WMPulses; } }
public double BeginWMState { get { return 0; } } /// Always 0
public double EndWMState { get { return WMVolume; } } /// Derived from WMVolume
double volumeStart;
public double VolumeStart { get { return volumeStart; } } /// in l
double volumeEnd;
public double VolumeEnd { get { return volumeEnd; } } /// in l
double timestampStart;
public double TimestampStart { get { return timestampStart; } } /// in s
double timestampEnd;
public double TimestampEnd { get { return timestampEnd; } } /// in s
///
/// Roi specific
///
public bool Detected { get { return detected; } }
bool detected;
///
public Boxes.IntBox RoiX;
public Boxes.IntBox RoiY;
public Boxes.IntBox RoiWid;
public Boxes.IntBox RoiHgh;
///
public void ClearRoi()
{
detected = false;
}
///
public void SetRoi(int x, int y, int wid, int hgh)
{
RoiX.Val = x;
RoiY.Val = y;
RoiWid.Val = wid;
RoiHgh.Val = hgh;
detected = true;
}
///
public string ImageFileNamePrefix { get { return imgFileNamePrefix; } }
string imgFileNamePrefix;
///
private int roiHandle;
///
public void RegisterRoiToCamera()
{
if (RoiCfg.DebugLevel == DebugMode.Simulate)
{
roiHandle = Camera.RegisterRoi(string.Format("-roi 1 300 200 134 134 66 66 20 66 0 0 360 360 1 50 0 0 270 0 bkgnd.bmp"));
}
else
{
roiHandle = Camera.RegisterRoi(string.Format("-roi 1 {0} {1} {2} bkgnd.bmp", RoiX.Val, RoiY.Val, RoiCfg.RoiParams));
}
}
public Roi()
{
}
public Roi(Generic.IComponentCfg cfg, IList<Generic.IComponent> components)
: base(cfg)
{
RoiCfg = cfg as RoiCfg;
NetCamera = TbfComponents.FindComponent(cfg.ParentName, components) as CLP1611.Camera;
PreviousRoi = TbfComponents.FindComponent(RoiCfg.PreviousRoi, components) as Roi;
detected = false;
RoiX = new Boxes.IntBox();
RoiY = new Boxes.IntBox();
RoiWid = new Boxes.IntBox();
RoiHgh = new Boxes.IntBox();
Clear();
log.Warn(this.ToString());
}
#region Configuration Change Handling
public static void OnCfgChange(object sender, CfgChangeArgs args)
{
if (CfgChangeHandler == null) return;
try { CfgChangeHandler(sender, args); }
catch (Exception e) { log.Error("CfgChangeHandler(...) failed", e); }
}
public static event EventHandler<CfgChangeArgs> CfgChangeHandler;
public override void StartChangeHandler()
{
CfgChangeHandler += delegate(object sender, CfgChangeArgs args)
{
RoiCfg tmpcfg = args.Cfg as RoiCfg;
if (tmpcfg != null && tmpcfg.Name.Equals(Name))
{
if (args.Command == CfgChangeCmd.CfgChange)
{
RoiCfg.LoadImages = tmpcfg.LoadImages;
RoiCfg.SaveImages = tmpcfg.SaveImages;
}
}
};
}
#endregion Configuration Change Handling
public void Clear()
{
pulsesDelta = -cameraPulses;
timeDelta = -cameraTime;
wmRefPulses = 0;
}
public IOperation RoiDetectionOp()
{
if (NetCamera != null && RoiCfg.DebugLevel != DebugMode.Simulate)
{
imgFileNamePrefix = Path.Combine(Program.TempImagesDir, string.Format("t{0}-{1}-", StateMachine.Time, RoiCfg.Name));
return new RoiDetectionOp(this, NetCamera, imgFileNamePrefix, RoiX, RoiY, RoiWid, RoiHgh);
}
else
{
return null; /// When NetCamera == null or ROI is in simulation mode
}
}
public IOperation GrabImageOp(string imageFileName, bool blackAndWhite, bool lowResolution, ImageRotation imageRotation)
{
if (NetCamera != null)
{
/// TODO: Implement support for sharing one camera by multiple ROI-s
return NetCamera.GrabImagesOp(new string[] { imageFileName }, blackAndWhite, lowResolution, imageRotation);
}
else
return null;
}
public IOperation GrabImageOp(string imageFileName)
{
if (NetCamera != null)
{
/// TODO: Implement support for sharing one camera by multiple ROI-s
return NetCamera.GrabImagesOp(new string[] { imageFileName }, false, true, ImageRotation.None);
}
else
return null;
}
/// <summary>
/// Updates wmPulses, caled from 'Start' and 'Run' functions of 'ReadRegisterOp'
/// </summary>
void UdatePulses()
{
if (detected && roiHandle != 0)
{
cameraPulses = NetCamera.GetResult(roiHandle, out cameraTime);
}
wmRefPulses = StateMachine.ControlBoard.RefPulses;
}
///
/// Note: Measurement operations of cameras should preceeede ReadRegister operations of ROI-s
///
public IOperation ReadRegisterOp()
{
return this;
}
/// <summary>Start this operation</summary>
public void Start()
{
UdatePulses();
Clear();
volumeStart = WMVolume;
timestampStart = WMTestTime;
}
/// <summary>Run this operation</summary>
/// <returns>eventDone</returns>
public Event Run()
{
UdatePulses();
volumeEnd = WMVolume;
timestampEnd = WMTestTime;
return Event.ReadRegisterDone;
}
/// <summary>Stop this operation</summary>
public void Stop()
{
}
}
}
+63
View File
@@ -0,0 +1,63 @@
///
/// Copyright (c) 2017 Sensus Metering Systems
///
using System.Collections.Generic;
using System.Xml.Serialization;
using Config.Entities;
using TBF.Rig.Generic;
namespace TBF.Rig.Network.Camera.Roi
{
public class RoiCfg : ComponentCfgBase, IChildComponentCfg
{
public static XmlSerializer Serializer = XmlSerializer.FromTypes(new[] { typeof(RoiCfg) })[0];
public override XmlSerializer GetSerializer() { return Serializer; }
public IComponentCfgCtrl GetControl(IList<Config.Entities.Component> cmpntEntities) { return new RoiCfgCtrl(); }
///
/// Serialized parameters
///
public string PreviousRoi;
[XmlIgnore]
public bool LoadImages;
[XmlIgnore]
public bool SaveImages;
/// <summary> Procedure parameters </summary>
[XmlIgnore]
public ProcedureParams ProcParams;
public override IParamsProvider GetRuntimeProcParamsProvider() { return ProcParams; }
public override IParamsProvider CreateProcParamsProvider() { return new ProcedureParams(true); }
public int DetectionImagesCount { get { return ProcParams.DetectionImagesCount; } }
public int DetectionPeriod1 { get { return ProcParams.DetectionPeriod1; } }
public int DetectionPeriod2 { get { return ProcParams.DetectionPeriod2; } }
public string RoiParams { get { return ProcParams.RoiParams; } }
/// Private parameterless constructor invoked by all other (public) constructors
RoiCfg()
{
ProcParams = new ProcedureParams(true);
}
public RoiCfg(string name, IComponentFactory factory)
: this()
{
Name = name;
Factory = factory;
ParentName = "Camera";
DebugLevel = DebugMode.Inherit;
}
public string ToString(int i)
{
return string.Format("{0} ({1}) PreviousRoi={2} {3}", Name, ParentName,
string.IsNullOrEmpty(PreviousRoi) ? "---" : PreviousRoi,
(LoadImages ? " load images" : (SaveImages ? " save images" : "")));
}
}
}
+145
View File
@@ -0,0 +1,145 @@
///
/// Copyright (c) 2017 Sensus Metering Systems
///
using System;
using System.Windows.Forms;
using Config.Entities;
using TBF.Rig.Generic;
using TBF.UI.Bench.Components;
namespace TBF.Rig.Network.Camera.Roi
{
public partial class RoiCfgCtrl : UserControl, IComponentCfgCtrl
{
ComponentParametersDlg parent;
public bool ShowMore { get { return false; } }
RoiCfg config;
public IComponentCfg Config
{
get { return config as IComponentCfg; }
set
{
config = value as RoiCfg;
Redraw();
}
}
public RoiCfgCtrl()
{
InitializeComponent();
}
private void PumpCfgCtrl_Load(object sender, EventArgs e)
{
parent = ParentForm as ComponentParametersDlg;
if (parent == null) return;
previousRoiComboBox.Items.Add("---");
if (parent.CmpntEntities != null)
{
foreach (var cmpnt in parent.CmpntEntities)
{
if (TbfComponents.CmpntFactoryFromClassName(cmpnt.ClassName) is TBF.Rig.Network.Camera.CLP1611.Factory)
{
parentNameComboBox.Items.Add(cmpnt.Name);
}
if (TbfComponents.CmpntFactoryFromClassName(cmpnt.ClassName) is TBF.Rig.Network.Camera.Roi.Factory)
{
previousRoiComboBox.Items.Add(cmpnt.Name);
}
}
}
Redraw();
}
public void Closing()
{
}
void Redraw()
{
if (config == null) return; /// Control was not loaded, settings were not changed
classNameLabel.Text = config.Factory.ClassName;
nameTextBox.Text = config.Name;
parentNameComboBox.Text = string.IsNullOrEmpty(config.ParentName) ? "---" : config.ParentName;
previousRoiComboBox.Text = string.IsNullOrEmpty(config.PreviousRoi) ? "---" : config.PreviousRoi;
loadImagesCheckBox.Checked = config.LoadImages;
saveImagesCheckBox.Checked = config.SaveImages;
}
public void Unlock()
{
nameTextBox.Enabled = true;
parentNameComboBox.Enabled = true;
previousRoiComboBox.Enabled = true;
loadImagesCheckBox.Enabled = true;
saveImagesCheckBox.Enabled = true;
}
public CfgUpdateFlags VerifyCfg(ref string message)
{
CfgUpdateFlags flags = CfgUpdateFlags.None;
if (!parentNameComboBox.Items.Contains(parentNameComboBox.Text))
{
flags |= CfgUpdateFlags.Error;
message += Environment.NewLine + "Invalid 'Parent Name'";
}
if (!previousRoiComboBox.Items.Contains(previousRoiComboBox.Text))
{
flags |= CfgUpdateFlags.Error;
message += Environment.NewLine + "Invalid 'Previous RoI'";
}
if (loadImagesCheckBox.Checked && saveImagesCheckBox.Checked)
{
flags |= CfgUpdateFlags.Error;
message += Environment.NewLine + "Images cannot be Loaded and Saved at the same time";
}
return flags;
}
public CfgUpdateFlags UpdateCfg()
{
CfgUpdateFlags flags = CfgUpdateFlags.None;
if (config == null) return CfgUpdateFlags.Error; /// Control was not loaded, settings were not changed
string newParentName = parentNameComboBox.Text.Equals("---") ? string.Empty : parentNameComboBox.Text;
string newPreviousRoi = previousRoiComboBox.Text.Equals("---") ? string.Empty : previousRoiComboBox.Text;
if (config.Name != nameTextBox.Text ||
config.ParentName != newParentName ||
config.PreviousRoi != newPreviousRoi)
{
config.Name = nameTextBox.Text;
config.ParentName = newParentName;
config.PreviousRoi = newPreviousRoi;
flags |= (CfgUpdateFlags.RestartRqrd | CfgUpdateFlags.AnyChange);
}
if (config.LoadImages != loadImagesCheckBox.Checked ||
config.SaveImages != saveImagesCheckBox.Checked)
{
config.LoadImages = loadImagesCheckBox.Checked;
config.SaveImages = saveImagesCheckBox.Checked;
flags |= (CfgUpdateFlags.InvokeCfgChange | CfgUpdateFlags.VolatileChange);
}
if ((flags & CfgUpdateFlags.InvokeCfgChange) != 0)
{
Roi.OnCfgChange(this, new CfgChangeArgs(CfgChangeCmd.CfgChange, config));
}
return flags;
}
}
}
+210
View File
@@ -0,0 +1,210 @@
///
/// Copyright (c) 2017 Sensus Metering Systems
///
namespace TBF.Rig.Network.Camera.Roi
{
partial class RoiCfgCtrl
{
/// <summary>
/// Required designer variable.
/// </summary>
private System.ComponentModel.IContainer components = null;
/// <summary>
/// Clean up any resources being used.
/// </summary>
/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
protected override void Dispose(bool disposing)
{
if (disposing && (components != null))
{
components.Dispose();
}
base.Dispose(disposing);
}
#region Component Designer generated code
/// <summary>
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
/// </summary>
private void InitializeComponent()
{
this.parentNameLabel = new System.Windows.Forms.Label();
this.nameTextBox = new System.Windows.Forms.TextBox();
this.nameLabel = new System.Windows.Forms.Label();
this.classNameLabel = new System.Windows.Forms.Label();
this.parentNameComboBox = new System.Windows.Forms.ComboBox();
this.label1 = new System.Windows.Forms.Label();
this.textBox1 = new System.Windows.Forms.TextBox();
this.previousRoiComboBox = new System.Windows.Forms.ComboBox();
this.previousRoiLabel = new System.Windows.Forms.Label();
this.helpLabel1 = new System.Windows.Forms.Label();
this.label2 = new System.Windows.Forms.Label();
this.loadImagesCheckBox = new System.Windows.Forms.CheckBox();
this.saveImagesCheckBox = new System.Windows.Forms.CheckBox();
this.SuspendLayout();
//
// parentNameLabel
//
this.parentNameLabel.AutoSize = true;
this.parentNameLabel.Location = new System.Drawing.Point(13, 60);
this.parentNameLabel.Name = "parentNameLabel";
this.parentNameLabel.Size = new System.Drawing.Size(69, 13);
this.parentNameLabel.TabIndex = 3;
this.parentNameLabel.Text = "Parent Name";
//
// nameTextBox
//
this.nameTextBox.Enabled = false;
this.nameTextBox.Location = new System.Drawing.Point(99, 34);
this.nameTextBox.Name = "nameTextBox";
this.nameTextBox.Size = new System.Drawing.Size(174, 20);
this.nameTextBox.TabIndex = 2;
//
// nameLabel
//
this.nameLabel.AutoSize = true;
this.nameLabel.Location = new System.Drawing.Point(13, 37);
this.nameLabel.Name = "nameLabel";
this.nameLabel.Size = new System.Drawing.Size(35, 13);
this.nameLabel.TabIndex = 1;
this.nameLabel.Text = "Name";
//
// classNameLabel
//
this.classNameLabel.AutoSize = true;
this.classNameLabel.Location = new System.Drawing.Point(96, 11);
this.classNameLabel.Name = "classNameLabel";
this.classNameLabel.Size = new System.Drawing.Size(114, 13);
this.classNameLabel.TabIndex = 0;
this.classNameLabel.Text = "ComponentClassName";
//
// parentNameComboBox
//
this.parentNameComboBox.Enabled = false;
this.parentNameComboBox.FormattingEnabled = true;
this.parentNameComboBox.Location = new System.Drawing.Point(99, 57);
this.parentNameComboBox.Name = "parentNameComboBox";
this.parentNameComboBox.Size = new System.Drawing.Size(174, 21);
this.parentNameComboBox.TabIndex = 4;
//
// label1
//
this.label1.AutoSize = true;
this.label1.Location = new System.Drawing.Point(-211, -147);
this.label1.Name = "label1";
this.label1.Size = new System.Drawing.Size(57, 13);
this.label1.TabIndex = 5;
this.label1.Text = "Arguments";
//
// textBox1
//
this.textBox1.Enabled = false;
this.textBox1.Location = new System.Drawing.Point(-125, -150);
this.textBox1.Name = "textBox1";
this.textBox1.Size = new System.Drawing.Size(372, 20);
this.textBox1.TabIndex = 6;
//
// previousRoiComboBox
//
this.previousRoiComboBox.Enabled = false;
this.previousRoiComboBox.FormattingEnabled = true;
this.previousRoiComboBox.Location = new System.Drawing.Point(99, 81);
this.previousRoiComboBox.Name = "previousRoiComboBox";
this.previousRoiComboBox.Size = new System.Drawing.Size(174, 21);
this.previousRoiComboBox.TabIndex = 6;
//
// previousRoiLabel
//
this.previousRoiLabel.AutoSize = true;
this.previousRoiLabel.Location = new System.Drawing.Point(13, 84);
this.previousRoiLabel.Name = "previousRoiLabel";
this.previousRoiLabel.Size = new System.Drawing.Size(68, 13);
this.previousRoiLabel.TabIndex = 5;
this.previousRoiLabel.Text = "Previous RoI";
//
// helpLabel1
//
this.helpLabel1.AutoSize = true;
this.helpLabel1.Location = new System.Drawing.Point(38, 186);
this.helpLabel1.Name = "helpLabel1";
this.helpLabel1.Size = new System.Drawing.Size(379, 13);
this.helpLabel1.TabIndex = 2;
this.helpLabel1.Text = "roiWid roiHgh cx cy innerR outerR R3 ang1 ang2 fullAngle teethCount ..." +
"";
//
// label2
//
this.label2.AutoSize = true;
this.label2.Location = new System.Drawing.Point(68, 204);
this.label2.Name = "label2";
this.label2.Size = new System.Drawing.Size(350, 13);
this.label2.TabIndex = 3;
this.label2.Text = "... angSpeed( - ccw +cw) initSpeed minMvmt maxFwdMvmt bkgndCorr";
//
// loadImagesCheckBox
//
this.loadImagesCheckBox.AutoSize = true;
this.loadImagesCheckBox.Enabled = false;
this.loadImagesCheckBox.Location = new System.Drawing.Point(99, 117);
this.loadImagesCheckBox.Name = "loadImagesCheckBox";
this.loadImagesCheckBox.Size = new System.Drawing.Size(112, 17);
this.loadImagesCheckBox.TabIndex = 6;
this.loadImagesCheckBox.Text = "Load images (test)";
this.loadImagesCheckBox.UseVisualStyleBackColor = true;
//
// saveImagesCheckBox
//
this.saveImagesCheckBox.AutoSize = true;
this.saveImagesCheckBox.Enabled = false;
this.saveImagesCheckBox.Location = new System.Drawing.Point(99, 140);
this.saveImagesCheckBox.Name = "saveImagesCheckBox";
this.saveImagesCheckBox.Size = new System.Drawing.Size(132, 17);
this.saveImagesCheckBox.TabIndex = 7;
this.saveImagesCheckBox.Text = "Save images (analyze)";
this.saveImagesCheckBox.UseVisualStyleBackColor = true;
//
// RoiCfgCtrl
//
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.Controls.Add(this.helpLabel1);
this.Controls.Add(this.saveImagesCheckBox);
this.Controls.Add(this.label2);
this.Controls.Add(this.previousRoiComboBox);
this.Controls.Add(this.previousRoiLabel);
this.Controls.Add(this.loadImagesCheckBox);
this.Controls.Add(this.parentNameComboBox);
this.Controls.Add(this.textBox1);
this.Controls.Add(this.label1);
this.Controls.Add(this.parentNameLabel);
this.Controls.Add(this.nameTextBox);
this.Controls.Add(this.nameLabel);
this.Controls.Add(this.classNameLabel);
this.Name = "RoiCfgCtrl";
this.Size = new System.Drawing.Size(500, 300);
this.Load += new System.EventHandler(this.PumpCfgCtrl_Load);
this.ResumeLayout(false);
this.PerformLayout();
}
#endregion
private System.Windows.Forms.Label parentNameLabel;
private System.Windows.Forms.TextBox nameTextBox;
private System.Windows.Forms.Label nameLabel;
private System.Windows.Forms.Label classNameLabel;
private System.Windows.Forms.ComboBox parentNameComboBox;
private System.Windows.Forms.Label label1;
private System.Windows.Forms.TextBox textBox1;
private System.Windows.Forms.ComboBox previousRoiComboBox;
private System.Windows.Forms.Label previousRoiLabel;
private System.Windows.Forms.Label helpLabel1;
private System.Windows.Forms.Label label2;
private System.Windows.Forms.CheckBox loadImagesCheckBox;
private System.Windows.Forms.CheckBox saveImagesCheckBox;
}
}
+120
View File
@@ -0,0 +1,120 @@
<?xml version="1.0" encoding="utf-8"?>
<root>
<!--
Microsoft ResX Schema
Version 2.0
The primary goals of this format is to allow a simple XML format
that is mostly human readable. The generation and parsing of the
various data types are done through the TypeConverter classes
associated with the data types.
Example:
... ado.net/XML headers & schema ...
<resheader name="resmimetype">text/microsoft-resx</resheader>
<resheader name="version">2.0</resheader>
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
<value>[base64 mime encoded serialized .NET Framework object]</value>
</data>
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
<comment>This is a comment</comment>
</data>
There are any number of "resheader" rows that contain simple
name/value pairs.
Each data row contains a name, and value. The row also contains a
type or mimetype. Type corresponds to a .NET class that support
text/value conversion through the TypeConverter architecture.
Classes that don't support this are serialized and stored with the
mimetype set.
The mimetype is used for serialized objects, and tells the
ResXResourceReader how to depersist the object. This is currently not
extensible. For a given mimetype the value must be set accordingly:
Note - application/x-microsoft.net.object.binary.base64 is the format
that the ResXResourceWriter will generate, however the reader can
read any of the formats listed below.
mimetype: application/x-microsoft.net.object.binary.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.soap.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.bytearray.base64
value : The object must be serialized into a byte array
: using a System.ComponentModel.TypeConverter
: and then encoded with base64 encoding.
-->
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
<xsd:element name="root" msdata:IsDataSet="true">
<xsd:complexType>
<xsd:choice maxOccurs="unbounded">
<xsd:element name="metadata">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" />
</xsd:sequence>
<xsd:attribute name="name" use="required" type="xsd:string" />
<xsd:attribute name="type" type="xsd:string" />
<xsd:attribute name="mimetype" type="xsd:string" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="assembly">
<xsd:complexType>
<xsd:attribute name="alias" type="xsd:string" />
<xsd:attribute name="name" type="xsd:string" />
</xsd:complexType>
</xsd:element>
<xsd:element name="data">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="resheader">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" />
</xsd:complexType>
</xsd:element>
</xsd:choice>
</xsd:complexType>
</xsd:element>
</xsd:schema>
<resheader name="resmimetype">
<value>text/microsoft-resx</value>
</resheader>
<resheader name="version">
<value>2.0</value>
</resheader>
<resheader name="reader">
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
</root>
@@ -0,0 +1,209 @@
///
/// Copyright (c) 2017 Sensus Metering Systems
///
using System;
using log4net;
using TBF.Rig.Network.Telnet;
namespace TBF.Rig.Network.Camera.Roi
{
public class RoiDetectionOp : IOperation
{
private static readonly ILog log = LogManager.GetLogger(typeof(RoiDetectionOp));
public override string ToString() { return string.Format("RoiDetectionOp()"); }
readonly Roi roi;
readonly RoiCfg roiCfg;
readonly CLP1611.Camera camera;
readonly Telnet.TelnetClient telnet;
readonly string imgFileNamePrefix;
string command;
bool roiDetectionCommandSent;
bool transferringDetectedImage;
string response;
bool passed;
bool failed;
bool previousFailed;
Boxes.IntBox roiX;
Boxes.IntBox roiY;
Boxes.IntBox roiWid;
Boxes.IntBox roiHgh; /// Wid and Hgh are usefull when masking
/// <summary>
/// Events: Event.None or Event.Error
/// </summary>
/// <param name="camera">CLP1611.Camera reference</param>
public RoiDetectionOp(Roi roi, CLP1611.Camera camera, string imgFileNamePrefix,
Boxes.IntBox roiX, Boxes.IntBox roiY,
Boxes.IntBox roiWid, Boxes.IntBox roiHgh)
{
this.roi = roi;
this.roiCfg = roi.RoiCfg;
this.camera = camera;
this.telnet = camera.Telnet;
this.imgFileNamePrefix = imgFileNamePrefix;
this.roiX = roiX;
this.roiY = roiY;
this.roiWid = roiWid;
this.roiHgh = roiHgh;
roiDetectionCommandSent = false;
transferringDetectedImage = false;
telnet.promptReceivedHandler += delegate(object sndr, PromptReceivedEventArgs a)
{
OnPromptReceived(sndr, a);
};
}
void OnPromptReceived(object sndr, PromptReceivedEventArgs a)
{
response = a.Response;
}
public void Start()
{
roiDetectionCommandSent = false;
transferringDetectedImage = false;
}
public Event Run()
{
if (!roiDetectionCommandSent)
{
if (telnet.State == TelnetClient.TelnetState.Inactive)
{
//
// State variables
//
response = null;
passed = false;
failed = false;
previousFailed = false;
//
// Prepare command
//
string masks = string.Empty;
Roi previous = roi.PreviousRoi;
int maskLevel = 0;
while (previous != null && maskLevel++ < 3)
{
if (!previous.Detected)
{
previousFailed = true;
return Event.RoiDetectionPreviousFailed;
}
masks += string.Format(" -m {0} {1} {2} {3}", previous.RoiX.Val, previous.RoiY.Val,
previous.RoiWid.Val, previous.RoiHgh.Val);
previous = previous.PreviousRoi;
}
command = string.Format("clp/RoiDetection{0}{1}{2}{3}{4} {5}",
masks,
string.Format(roiCfg.LoadImages ? " -l {0}" : " -n {0}", roiCfg.DetectionImagesCount),
roiCfg.SaveImages ? " -s -jpg" : "",
string.Format(" -p1 {0}", roiCfg.DetectionPeriod1),
string.Format(" -p2 {0}", roiCfg.DetectionPeriod2),
roiCfg.RoiParams);
//
// Send (or enqueue) command
//
telnet.Enqueue(new Telnet.Command(Telnet.CmdAction.CLEAR_RESPONSE));
telnet.Enqueue(new Telnet.Command(Telnet.CmdAction.SEND_COMMAND, command));
roiDetectionCommandSent = true;
log.WarnFormat("{0}/{1} command={2}", roiCfg.Name, camera.Name, command);
}
return Event.CameraBusy;
}
else if (passed)
{
if (transferringDetectedImage)
{
/// ROI detection passed and image transfer is in progress
return Event.RoiDetectionPassed;
}
else if (0 == camera.DownloadFile("detected.jpg", imgFileNamePrefix + "detected.jpg"))
{
/// File transfer successfully started
transferringDetectedImage = true;
return Event.RoiDetectionPassed;
}
else
{
/// Wait until the previous image transfer completes
return Event.CameraBusy;
}
}
else if (failed)
{
/// ROI detection failed, there in no image to transfer
return Event.RoiDetectionFailed;
}
else if (previousFailed)
{
return Event.RoiDetectionPreviousFailed;
}
else if (response != null)
{
int from = response.IndexOf('[');
int to = response.IndexOf(']');
if (!response.Contains("RESULT=0\r\n") || from < 0 || to < 0 || to < from)
{
roi.ClearRoi();
failed = true;
log.WarnFormat("{0}/{1} Detection failed: {2}", roiCfg.Name, camera.Name, response);
return Event.RoiDetectionFailed;
}
else
{
string oroiStr = response.Substring(from + 1, to - from - 1);
string[] terms = oroiStr.Split(new char[] { ',' });
int x, y, w, h;
if (terms.Length != 5 || !int.TryParse(terms[0], out x) || !int.TryParse(terms[1], out y)
|| !int.TryParse(terms[2], out w) || !int.TryParse(terms[3], out h))
{
roi.ClearRoi();
failed = true;
log.WarnFormat("{0}/{1} Cannot parse response: {2}", roiCfg.Name, camera.Name, response);
return Event.RoiDetectionFailed;
}
else
{
roi.SetRoi(x, y, w, h);
log.WarnFormat("{0}/{1} Detection PASSED: x={2} y={3} w={4} h={5}", roiCfg.Name, camera.Name, x, y, w, h);
passed = true;
///
/// Start the file transfer
///
if (0 == camera.DownloadFile("detected.jpg", imgFileNamePrefix + "detected.jpg"))
{
/// File transfer successfully started
transferringDetectedImage = true;
return Event.RoiDetectionPassed;
}
else
{
return Event.CameraBusy; /// File transfer not started yet
}
}
}
}
else
{
return Event.CameraBusy;
}
}
public void Stop()
{
}
}
}