This commit is contained in:
meelstorm
2025-09-29 09:31:57 +02:00
parent 87c1145744
commit 1aecb79ade
16 changed files with 110 additions and 16 deletions

View File

@@ -119,7 +119,9 @@ namespace CandyboxPlugin.Recipe
} }
File.WriteAllText(_configurationPath, JsonSerializer.Serialize(_learnedParameters, new JsonSerializerOptions() { WriteIndented = true })); File.WriteAllText(_configurationPath, JsonSerializer.Serialize(_learnedParameters, new JsonSerializerOptions() { WriteIndented = true }));
image.Resize(ThumbnailSize).SaveImage(Path.Combine("..\\Data\\Samples", Path.GetFileNameWithoutExtension(_recipeName) + ".bmp")); var fullSamplePath = Path.GetFullPath(Path.Combine("..\\Data\\Samples", _recipeName + ".bmp"));
Directory.CreateDirectory(Path.GetDirectoryName(fullSamplePath));
image.Resize(ThumbnailSize).SaveImage(fullSamplePath);
} }
} }

View File

@@ -0,0 +1,6 @@
namespace VisionBuilder.UI.Common.Commands;
public class ErrorsInSequenceEvent
{
public int Errors { get; set; }
}

View File

@@ -128,7 +128,7 @@ public abstract class BaseRecognitionControl: IRecognitionControl
SessionEnded = DateTime.Now SessionEnded = DateTime.Now
}); });
_loadingService.StopLoading($"Stopping {_settings.CameraName}"); _loadingService.StopLoading($"Stopping {_settings.CameraName}");
IsPaused=false; // ensure paused is reset
} }
public void Pause() public void Pause()
@@ -141,6 +141,8 @@ public abstract class BaseRecognitionControl: IRecognitionControl
IsPaused = false; IsPaused = false;
} }
int _errorsInSequence = 0;
private async Task Loop(CancellationToken token) private async Task Loop(CancellationToken token)
{ {
@@ -149,7 +151,7 @@ public abstract class BaseRecognitionControl: IRecognitionControl
{ {
if (IsPaused) if (IsPaused)
{ {
await Task.Delay(100, token); await Task.Delay(100, token).ConfigureAwait(false);
continue; continue;
} }
@@ -165,6 +167,18 @@ public abstract class BaseRecognitionControl: IRecognitionControl
Thread.Sleep(_settings.MinimumProcessingTime - (int)processed.Value.processingTime.Milliseconds); Thread.Sleep(_settings.MinimumProcessingTime - (int)processed.Value.processingTime.Milliseconds);
} }
if (processed.Value.errorNames.Length > 0)
{
_errorsInSequence++;
if (_errorsInSequence >= _settings.ErrorsInSequenceAlarm)
{
ErrorsInSequenceAlarm(new ErrorsInSequenceEvent(){Errors = _errorsInSequence});
}
}
else
{
_errorsInSequence = 0;
}
var processingResult = new ImageProcessedEvent() var processingResult = new ImageProcessedEvent()
{ {
@@ -188,6 +202,7 @@ public abstract class BaseRecognitionControl: IRecognitionControl
} }
public event Action<ImageProcessedEvent> ImageProcessed = delegate { }; public event Action<ImageProcessedEvent> ImageProcessed = delegate { };
public event Action<SessionStartedEvent>? SessionStarted = delegate { }; public event Action<SessionStartedEvent> SessionStarted = delegate { };
public event Action<SessionEndedEvent>? SessionEnded = delegate { }; public event Action<SessionEndedEvent> SessionEnded = delegate { };
public event Action<ErrorsInSequenceEvent> ErrorsInSequenceAlarm = delegate { };
} }

View File

@@ -8,10 +8,12 @@ public abstract class BaseRecognitionControlSettings(string cameraName) : ISetti
public int MinimumProcessingTime { get; set; } public int MinimumProcessingTime { get; set; }
public string RecipeNameFilter { get; set; } = "*"; public string RecipeNameFilter { get; set; } = "*";
public int ErrorsInSequenceAlarm { get; set; } = 5;
public virtual void RegisterSettings(InspectronSettings settings) public virtual void RegisterSettings(InspectronSettings settings)
{ {
settings.RegisterSimple(this, () => this.MinimumProcessingTime, CameraName + "/Hawkeye recognition", "Minimum processing time (ms)"); settings.RegisterSimple(this, () => this.MinimumProcessingTime, CameraName + "/Hawkeye recognition", "Minimum processing time (ms)");
settings.RegisterSimple(this, () => this.RecipeNameFilter, CameraName + "/Hawkeye recognition", nameof(RecipeNameFilter)); settings.RegisterSimple(this, () => this.RecipeNameFilter, CameraName + "/Hawkeye recognition", nameof(RecipeNameFilter));
settings.RegisterSimple(this, () => this.ErrorsInSequenceAlarm, CameraName + "/Hawkeye recognition", nameof(ErrorsInSequenceAlarm));
} }
} }

View File

@@ -15,5 +15,6 @@ public interface IRecognitionControl
event Action<ImageProcessedEvent> ImageProcessed; event Action<ImageProcessedEvent> ImageProcessed;
event Action<SessionStartedEvent> SessionStarted; event Action<SessionStartedEvent> SessionStarted;
event Action<SessionEndedEvent> SessionEnded; event Action<SessionEndedEvent> SessionEnded;
event Action<ErrorsInSequenceEvent> ErrorsInSequenceAlarm;
} }

View File

@@ -123,19 +123,29 @@ namespace VisionBuilder.UI.Common
} }
[RelayCommand(CanExecute = nameof(CanStart))] [RelayCommand(CanExecute = nameof(CanStart))]
public void Start() public async Task Start()
{ {
_handlingEnabled = true;
_recognitionControl.Start();
IsRunning = true; IsRunning = true;
await Task.Run(() =>
{
_recognitionControl.Start();
});
_handlingEnabled = true;
} }
[RelayCommand(CanExecute = nameof(CanStop))] [RelayCommand(CanExecute = nameof(CanStop))]
public void Stop() public async Task Stop()
{ {
_handlingEnabled = false; _handlingEnabled = false;
await Task.Run(() =>
{
_recognitionControl.Stop(); _recognitionControl.Stop();
});
IsPaused = false;
IsRunning = false; IsRunning = false;
} }
[RelayCommand(CanExecute = nameof(IsResumed))] [RelayCommand(CanExecute = nameof(IsResumed))]

View File

@@ -8,5 +8,6 @@ public enum EProcessingEvent
SessionEnded, SessionEnded,
ErrorOccurred, ErrorOccurred,
GoodOccured, GoodOccured,
ErrorsInSequenceAlarm,
TestMode TestMode
} }

View File

@@ -28,10 +28,16 @@ public class IOCommanderCameraModule: IVisionBuilderModule
_recognitionControl.ImageProcessed += _recognitionControl_ImageProcessed; _recognitionControl.ImageProcessed += _recognitionControl_ImageProcessed;
_recognitionControl.SessionStarted += _recognitionControl_SessionStarted; _recognitionControl.SessionStarted += _recognitionControl_SessionStarted;
_recognitionControl.SessionEnded += _recognitionControl_SessionEnded; _recognitionControl.SessionEnded += _recognitionControl_SessionEnded;
_recognitionControl.ErrorsInSequenceAlarm += _recognitionControl_ErrorsInSequenceAlarm;
} }
private void _recognitionControl_ErrorsInSequenceAlarm(ErrorsInSequenceEvent obj)
{
EmitEvent(EProcessingEvent.ErrorsInSequenceAlarm);
}
private void ProcessCommand(EGPIOCommand command) private void ProcessCommand(EGPIOCommand command)
{ {

View File

@@ -17,6 +17,7 @@ namespace VisionBuilder.UI.IOCommander.Settings
new (EProcessingEvent.SessionEnded), new (EProcessingEvent.SessionEnded),
new (EProcessingEvent.ErrorOccurred), new (EProcessingEvent.ErrorOccurred),
new (EProcessingEvent.GoodOccured), new (EProcessingEvent.GoodOccured),
new (EProcessingEvent.ErrorsInSequenceAlarm),
]; ];
[SettingDescription(@" [SettingDescription(@"

View File

@@ -95,6 +95,7 @@
// //
// materialDivider1 // materialDivider1
// //
materialDivider1.Anchor = AnchorStyles.Bottom | AnchorStyles.Left | AnchorStyles.Right;
materialDivider1.BackColor = Color.FromArgb(55, 71, 79); materialDivider1.BackColor = Color.FromArgb(55, 71, 79);
materialDivider1.Depth = 0; materialDivider1.Depth = 0;
materialDivider1.Location = new Point(8, 984); materialDivider1.Location = new Point(8, 984);
@@ -106,6 +107,7 @@
// //
// singleCameraControl1 // singleCameraControl1
// //
singleCameraControl1.Anchor = AnchorStyles.Top | AnchorStyles.Bottom | AnchorStyles.Left | AnchorStyles.Right;
singleCameraControl1.BackColor = Color.White; singleCameraControl1.BackColor = Color.White;
singleCameraControl1.Location = new Point(8, 32); singleCameraControl1.Location = new Point(8, 32);
singleCameraControl1.Name = "singleCameraControl1"; singleCameraControl1.Name = "singleCameraControl1";
@@ -132,6 +134,7 @@
// //
// flowLayoutPanel1 // flowLayoutPanel1
// //
flowLayoutPanel1.Anchor = AnchorStyles.Bottom | AnchorStyles.Left;
flowLayoutPanel1.BackColor = Color.Transparent; flowLayoutPanel1.BackColor = Color.Transparent;
flowLayoutPanel1.Controls.Add(btnTestMode); flowLayoutPanel1.Controls.Add(btnTestMode);
flowLayoutPanel1.Controls.Add(btnSettings); flowLayoutPanel1.Controls.Add(btnSettings);

View File

@@ -14,13 +14,15 @@ namespace VisionBuilder.UI.Windows.Test
private readonly MainWindowVM _mainWindowVm; private readonly MainWindowVM _mainWindowVm;
private readonly IPasswordInputService _passwordInputService; private readonly IPasswordInputService _passwordInputService;
private readonly UIConfiguration _uiConfiguration; private readonly UIConfiguration _uiConfiguration;
private readonly WindowsUISettings _windowsUiSettings;
public Form1(MainWindowVM mainWindowVm, IPasswordInputService passwordInputService, UIConfiguration uiConfiguration) public Form1(MainWindowVM mainWindowVm, IPasswordInputService passwordInputService, UIConfiguration uiConfiguration, WindowsUISettings windowsUiSettings)
{ {
_mainWindowVm = mainWindowVm; _mainWindowVm = mainWindowVm;
_passwordInputService = passwordInputService; _passwordInputService = passwordInputService;
_uiConfiguration = uiConfiguration; _uiConfiguration = uiConfiguration;
_windowsUiSettings = windowsUiSettings;
MaterialSkin.MaterialSkinManager.ConfigureForInspectron(); MaterialSkin.MaterialSkinManager.ConfigureForInspectron();
InitializeComponent(); InitializeComponent();
singleCameraControl1.SetViewModel(mainWindowVm.SingleCameraVms[0]); singleCameraControl1.SetViewModel(mainWindowVm.SingleCameraVms[0]);
@@ -51,6 +53,18 @@ namespace VisionBuilder.UI.Windows.Test
{ {
_mainWindowVm.OnProgramStarted(); _mainWindowVm.OnProgramStarted();
BringToFront(); BringToFront();
if (_windowsUiSettings.FullScreen)
{
WindowState = FormWindowState.Maximized;
}
}
protected override void OnShown(EventArgs e)
{
base.OnShown(e);
flowLayoutPanel1.Left = (ClientSize.Width - flowLayoutPanel1.Width) / 2;
} }
private void btnExit_Click(object sender, EventArgs e) private void btnExit_Click(object sender, EventArgs e)
@@ -59,6 +73,13 @@ namespace VisionBuilder.UI.Windows.Test
Environment.Exit(0); Environment.Exit(0);
} }
protected override void OnClosed(EventArgs e)
{
base.OnClosed(e);
_mainWindowVm.OnProgramClosed();
Environment.Exit(0);
}
private void btnMinimize_Click(object sender, EventArgs e) private void btnMinimize_Click(object sender, EventArgs e)
{ {
WindowState = FormWindowState.Minimized; WindowState = FormWindowState.Minimized;

View File

@@ -8,7 +8,7 @@
<ImplicitUsings>enable</ImplicitUsings> <ImplicitUsings>enable</ImplicitUsings>
<ApplicationIcon>Inspectron icon-512.ico</ApplicationIcon> <ApplicationIcon>Inspectron icon-512.ico</ApplicationIcon>
<Deterministic>false</Deterministic> <Deterministic>false</Deterministic>
<Version>1.0.4</Version> <Version>1.0.5</Version>
</PropertyGroup> </PropertyGroup>

View File

@@ -26,7 +26,14 @@ namespace VisionBuilder.UI.Windows.Components
private void _statisticsVm_PropertyChanged(object? sender, System.ComponentModel.PropertyChangedEventArgs e) private void _statisticsVm_PropertyChanged(object? sender, System.ComponentModel.PropertyChangedEventArgs e)
{ {
switch (e.PropertyName) if (InvokeRequired) Invoke(() => HandleStatisticsPropertyChange(e.PropertyName!));
else
HandleStatisticsPropertyChange(e.PropertyName!);
}
private void HandleStatisticsPropertyChange(string propertyName)
{
switch (propertyName)
{ {
case nameof(StatisticsVM.SessionStarted): case nameof(StatisticsVM.SessionStarted):
Clear(); Clear();
@@ -58,7 +65,6 @@ namespace VisionBuilder.UI.Windows.Components
break; break;
} }
} }
void InitializeFields() void InitializeFields()
{ {
UpdateMeta(StartedAtLabel,""); UpdateMeta(StartedAtLabel,"");

View File

@@ -1,4 +1,5 @@
using Ninject; using Ninject;
using VisionBuilder.UI.Common;
using VisionBuilder.UI.Common.Processing; using VisionBuilder.UI.Common.Processing;
using VisionBuilder.UI.Common.Services; using VisionBuilder.UI.Common.Services;
using VisionBuilder.UI.Common.ViewModel.Interfaces.UI; using VisionBuilder.UI.Common.ViewModel.Interfaces.UI;
@@ -15,6 +16,7 @@ public static class ModuleExtensions
self.Bind<IRecipeSelectionDialogService>().To<WindowsRecipeSelectionDialogService>().InSingletonScope(); self.Bind<IRecipeSelectionDialogService>().To<WindowsRecipeSelectionDialogService>().InSingletonScope();
self.Bind<IImagePreviewService>().To<WindowsImagePreviewService>().InSingletonScope(); self.Bind<IImagePreviewService>().To<WindowsImagePreviewService>().InSingletonScope();
self.Bind<IPasswordInputService>().To<WindowsPasswordInputService>().InSingletonScope(); self.Bind<IPasswordInputService>().To<WindowsPasswordInputService>().InSingletonScope();
self.Bind<WindowsUISettings,ISettings>().To<WindowsUISettings>().InSingletonScope();
return self; return self;
} }
} }

View File

@@ -0,0 +1,14 @@
using Inspectron.Settings;
using VisionBuilder.UI.Common;
namespace VisionBuilder.UI.Windows;
public class WindowsUISettings: ISettings
{
public bool FullScreen { get; set; }=false;
public void RegisterSettings(InspectronSettings settings)
{
settings.RegisterSimple(this, () => this.FullScreen,"System",nameof(FullScreen));
}
}

View File

@@ -13,7 +13,11 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "MaterialSkin.Core", "framew
EndProject EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "VisionBuilder.UI.Windows.Uno", "VisionBuilder.UI.Windows.Test\VisionBuilder.UI.Windows.Uno.csproj", "{7697A266-A721-4D74-9C5C-0D4F2F6BBF68}" Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "VisionBuilder.UI.Windows.Uno", "VisionBuilder.UI.Windows.Test\VisionBuilder.UI.Windows.Uno.csproj", "{7697A266-A721-4D74-9C5C-0D4F2F6BBF68}"
ProjectSection(ProjectDependencies) = postProject ProjectSection(ProjectDependencies) = postProject
{19E9B1A2-FBC6-2668-EDDF-1B3A6828184A} = {19E9B1A2-FBC6-2668-EDDF-1B3A6828184A}
{31C47198-DEC2-4073-A0C2-220549502CD1} = {31C47198-DEC2-4073-A0C2-220549502CD1} {31C47198-DEC2-4073-A0C2-220549502CD1} = {31C47198-DEC2-4073-A0C2-220549502CD1}
{52D6A9AE-D0F1-4C52-B688-E0219169E179} = {52D6A9AE-D0F1-4C52-B688-E0219169E179}
{B20D7E75-1C19-632D-21D2-2663B0329C5E} = {B20D7E75-1C19-632D-21D2-2663B0329C5E}
{DB20082B-60E8-D623-3F3A-04612A929CD6} = {DB20082B-60E8-D623-3F3A-04612A929CD6}
EndProjectSection EndProjectSection
EndProject EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Inspectron.Settings", "framework\Inspectron.Settings\Inspectron.Settings.csproj", "{E286CE4C-B68A-94B6-F477-0DBF42358009}" Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Inspectron.Settings", "framework\Inspectron.Settings\Inspectron.Settings.csproj", "{E286CE4C-B68A-94B6-F477-0DBF42358009}"