This commit is contained in:
meelstorm
2025-10-02 14:14:11 +02:00
parent 63afb2dcfb
commit 44748f2855
9 changed files with 193 additions and 99 deletions

View File

@@ -1,7 +1,33 @@
using System.Xml;
using Hawkeye.VisionBuilder.Workflow;
var files = Directory.GetFiles(AppContext.BaseDirectory, "*.hrcp", SearchOption.TopDirectoryOnly);
// Check if directory argument is provided
if (args.Length == 0)
{
Console.WriteLine("Usage: RecipeConverter.exe <directory>");
Console.WriteLine("Example: RecipeConverter.exe C:\\MyRecipes");
return;
}
string targetDirectory = args[0];
// Validate directory exists
if (!Directory.Exists(targetDirectory))
{
Console.WriteLine($"Error: Directory '{targetDirectory}' does not exist.");
return;
}
var files = Directory.GetFiles(targetDirectory, "*.hrcp", SearchOption.TopDirectoryOnly);
if (files.Length == 0)
{
Console.WriteLine($"No *.hrcp files found in directory '{targetDirectory}'");
return;
}
Console.WriteLine($"Found {files.Length} recipe file(s) in '{targetDirectory}'");
foreach (var file in files)
{
try
@@ -10,7 +36,12 @@ foreach (var file in files)
var f = File.OpenRead(file);
WorkflowList list = new WorkflowList();
list.Load(new BinaryReader(f), new OperationDiscoveryService(list));
list.SaveJSON(Path.GetFileNameWithoutExtension(file)+".jhrcp");
// Save the converted file in the same directory as the source
string outputPath = Path.Combine(targetDirectory, Path.GetFileNameWithoutExtension(file) + ".jhrcp");
list.SaveJSON(outputPath);
Console.WriteLine($"Saved: {outputPath}");
}
catch (Exception ex)
{

View File

@@ -41,6 +41,7 @@ namespace Inspectron.Camera.UEye
{
uEye.Defines.ColorMode mode;
_camera.PixelFormat.Get(out mode);
int channels = 0;
if (mode == uEye.Defines.ColorMode.Mono8)
@@ -53,7 +54,7 @@ namespace Inspectron.Camera.UEye
}
else if (mode == uEye.Defines.ColorMode.BGRA8Packed)
{
channels = 3;
channels = 4;
}
else
{
@@ -68,8 +69,17 @@ namespace Inspectron.Camera.UEye
Byte[] u8img;
_camera.Memory.CopyToArray(idx, out u8img);
Mat mat = new Mat(size.Height,pitch, MatType.CV_8UC(channels));
mat.SetArray(u8img);
// Warning! This will work only if pitch == width * channels
if (pitch != size.Width * channels)
{
throw new Exception("pitch must be equal to width * channels");
}
Mat mat = new Mat(size.Height, size.Width,MatType.CV_8UC3);
// copy data to mat
System.Runtime.InteropServices.Marshal.Copy(u8img, 0, mat.Data, u8img.Length);
return mat;
}
@@ -88,14 +98,13 @@ namespace Inspectron.Camera.UEye
}
uEye.Types.SensorInfo info = new uEye.Types.SensorInfo();
_camera.Information.GetSensorInfo(out info);
Console.WriteLine($"Camera {cameraIdx} opened: {info.SensorName} ({info.SensorID})");
Log.Information($"Camera {cameraIdx} opened: {info.SensorName} ({info.SensorID})");
_camera.Parameter.Load();
Console.WriteLine($"Camera {cameraIdx} parameters loaded");
Log.Information($"Camera {cameraIdx} parameters loaded");
_camera.Trigger.Set(uEye.Defines.TriggerMode.Continuous);
statusRet = _camera.Memory.Allocate();
Console.WriteLine("Memory allocated");
if (statusRet != uEye.Defines.Status.Success)
{
throw new Exception("Allocate Memory failed");

View File

@@ -16,5 +16,9 @@
<Private>false</Private>
<ExcludeAssets>runtime</ExcludeAssets>
</ProjectReference>
<ProjectReference Include="..\..\..\VisionBuilder.UI.Statistics\VisionBuilder.UI.Statistics.csproj" >
<Private>false</Private>
<ExcludeAssets>runtime</ExcludeAssets>
</ProjectReference>
</ItemGroup>
</Project>

View File

@@ -1,4 +1,6 @@
using VisionBuilder.UI.Common;
using Serilog;
using VisionBuilder.UI.Common;
using VisionBuilder.UI.Statistics;
namespace B24SiemensPlugin;
@@ -6,13 +8,15 @@ public class SiemensCameraModule: IVisionBuilderModule
{
private readonly SingleCameraVM _singleCameraVm;
private readonly B24SiemensSettings _settings;
private readonly VisionBuilderStatistics _statistics;
private SiemensServer _server;
public SiemensCameraModule(SingleCameraVM singleCameraVm,B24SiemensSettings settings)
public SiemensCameraModule(SingleCameraVM singleCameraVm,B24SiemensSettings settings, VisionBuilderStatistics statistics)
{
_singleCameraVm = singleCameraVm;
_settings = settings;
_statistics = statistics;
}
public void InitializeModule()
@@ -32,6 +36,11 @@ public class SiemensCameraModule: IVisionBuilderModule
}
private PLCPacket _server_OnPLCPacket(PLCPacket packet)
{
if (_singleCameraVm.SynchronizationContext == null)
{
Log.Warning("Synchronization context is null, cannot update UI from PLC packet.");
return packet;
}
packet.KameraStart= _singleCameraVm.IsRunning;
var recipe = GetMapping(packet.Materialnummer);
var selectedRecipe = _singleCameraVm.SelectedRecipe;
@@ -45,7 +54,7 @@ public class SiemensCameraModule: IVisionBuilderModule
{
_singleCameraVm.ProcessRecipeSelectionVm(vm);
}, null);
_statistics.Metadata = packet.Materialnummer.ToString();
}
}

View File

@@ -14,4 +14,6 @@ public class ImageProcessedEvent:IEvent
public bool HasError { get; set; }
public List<string> ErrorNames { get; set; }
public TimeSpan AnalysisTime { get; set; }
public TimeSpan AcquisitionTime { get; set; }
public TimeSpan SleepTime { get; set; }
}

View File

@@ -27,13 +27,19 @@ public abstract class BaseRecognitionControl: IRecognitionControl
public void SetRecipe(RecipeData recipe)
{
lock (_lock)
{
// error if running
if (IsRunning)
{
throw new InvalidOperationException("Cannot change recipe while recognition is running.");
}
_currentRecipe = recipe;
}
}
public bool IsRunning { get; set; }
public bool IsPaused { get; set; }
@@ -44,17 +50,24 @@ public abstract class BaseRecognitionControl: IRecognitionControl
private DateTime _startTime;
object _lock = new object();
public void Start()
{
lock (_lock)
{
if (_currentRecipe == null)
{
throw new InvalidOperationException("No recipe set.");
}
if (IsRunning)
{
throw new InvalidOperationException("Recognition is already running.");
}
_loadingService.StartLoading($"Starting recipe {_currentRecipe.RecipeName} on {_settings.CameraName}...");
Initialize(_currentRecipe);
_startTime = DateTime.Now;
@@ -85,6 +98,9 @@ public abstract class BaseRecognitionControl: IRecognitionControl
});
_loadingService.StopLoading($"Starting recipe {_currentRecipe.RecipeName} on {_settings.CameraName}...");
}
}
protected abstract void Initialize(RecipeData currentRecipe);
@@ -94,9 +110,14 @@ public abstract class BaseRecognitionControl: IRecognitionControl
protected abstract (Mat originalImage, Mat analysisImage, TimeSpan processingTime, TimeSpan acquisitionTime, string[] errorNames)? ProcessImage(CancellationToken token);
public void Stop()
{
lock (_lock)
{
if (!IsRunning)
return;
_loadingService.StartLoading($"Stopping {_settings.CameraName}");
_cts?.Cancel();
try
@@ -130,16 +151,23 @@ public abstract class BaseRecognitionControl: IRecognitionControl
_loadingService.StopLoading($"Stopping {_settings.CameraName}");
IsPaused = false; // ensure paused is reset
}
}
public void Pause()
{
lock (_lock)
{
IsPaused = true;
}
}
public void Resume()
{
lock (_lock)
{
IsPaused = false;
}
}
int _errorsInSequence = 0;
@@ -161,10 +189,13 @@ public abstract class BaseRecognitionControl: IRecognitionControl
{
return;
}
int sleepTime=0;
if (processed.Value.processingTime.Milliseconds < _settings.MinimumProcessingTime)
{
Thread.Sleep(_settings.MinimumProcessingTime - (int)processed.Value.processingTime.Milliseconds);
sleepTime = _settings.MinimumProcessingTime - (int)processed.Value.processingTime.Milliseconds;
Log.Debug("Sleeping for {sleepTime}",sleepTime);
Thread.Sleep(sleepTime);
}
if (processed.Value.errorNames.Length > 0)
@@ -185,6 +216,8 @@ public abstract class BaseRecognitionControl: IRecognitionControl
SessionStart = _startTime,
RecipeName = _currentRecipe.RecipeName,
AnalysisTime = processed.Value.processingTime - processed.Value.acquisitionTime,
AcquisitionTime = processed.Value.acquisitionTime,
SleepTime = TimeSpan.FromMilliseconds(sleepTime),
ErrorNames = processed.Value.errorNames.ToList(),
HasError = processed.Value.errorNames.Length > 0,
ImageSource = _settings.CameraName,
@@ -195,7 +228,7 @@ public abstract class BaseRecognitionControl: IRecognitionControl
var swProcessed = Stopwatch.StartNew();
ImageProcessed(processingResult);
swProcessed.Stop();
Log.Information($"ImageProcessed event handled in {swProcessed.ElapsedMilliseconds} ms");
Log.Information("ImageProcessed event handled in {processed} ms", swProcessed.ElapsedMilliseconds);
}

View File

@@ -57,8 +57,8 @@ namespace VisionBuilder.UI.Common
public bool CanStop => IsRunning;
public bool CanStart => !IsRunning && SelectedRecipe!=null;
public bool CanPause => (IsRunning && !IsPaused)&&_uiConfiguration.ShowPauseButton;
public bool CanResume => (IsRunning && IsPaused) && _uiConfiguration.ShowPauseButton;
public bool CanPause => (IsRunning && !IsPaused);
public bool CanResume => (IsRunning && IsPaused);
@@ -129,15 +129,16 @@ namespace VisionBuilder.UI.Common
CurrentRecipeName = SelectedRecipe?.RecipeName ?? "Select recipe";
}
[RelayCommand(CanExecute = nameof(CanStart))]
public async Task Start()
{
IsRunning = true;
await Task.Run(() =>
{
_recognitionControl.Start();
});
await Task.Run(() => { _recognitionControl.Start(); });
_handlingEnabled = true;
}

View File

@@ -48,6 +48,11 @@ namespace VisionBuilder.UI.Statistics
private void _recognitionControl_SessionEnded(SessionEndedEvent obj)
{
if (_csvStatistics == null)
{
Log.Warning("Session ended but CSV statistics is null, nothing to do.");
return;
}
var endedAt = obj.SessionEnded;
_endTime = endedAt;
Log.Information("Start processing statistics");

View File

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