|
|
@@ -52,6 +52,7 @@ namespace TeamAAS_VP.Services
|
|
|
private readonly IContainerProvider _container;
|
|
|
private readonly IRegionManager _regionManager;
|
|
|
private readonly ISystemDatabaseService _systemDatabaseService;
|
|
|
+ private readonly ILightManagerService _lightManagerService;
|
|
|
|
|
|
/// <summary>
|
|
|
/// 节拍计时任务的取消令牌,用于 StartCycleTiming/StopCycleTiming。
|
|
|
@@ -109,7 +110,7 @@ namespace TeamAAS_VP.Services
|
|
|
/// <param name="container">IOC 容器提供者,用于脚本执行时解析依赖。</param>
|
|
|
/// <param name="systemDatabaseService">系统数据库服务,用于记录产量/报警等。</param>
|
|
|
public RemoteCommandService(IEventAggregator eventAggregator, IRegionManager regionManager, IProductService productService, IConfigService configService, ICalibrationService calibrationService,
|
|
|
- IFeederService feederService, ICameraService cameraService, IRobotService robotService, IContainerProvider container, ISystemDatabaseService systemDatabaseService)
|
|
|
+ IFeederService feederService, ICameraService cameraService, IRobotService robotService, IContainerProvider container, ISystemDatabaseService systemDatabaseService, ILightManagerService lightManagerService)
|
|
|
{
|
|
|
_eventAggregator = eventAggregator;
|
|
|
_regionManager = regionManager;
|
|
|
@@ -121,6 +122,7 @@ namespace TeamAAS_VP.Services
|
|
|
_robotService = robotService;
|
|
|
_container = container;
|
|
|
_systemDatabaseService = systemDatabaseService;
|
|
|
+ _lightManagerService = lightManagerService;
|
|
|
}
|
|
|
|
|
|
/// <summary>
|
|
|
@@ -1158,6 +1160,7 @@ namespace TeamAAS_VP.Services
|
|
|
}
|
|
|
}
|
|
|
|
|
|
+ await SetLightBeforePhoto(procedure);
|
|
|
//执行Feeder相机拍照前的任务
|
|
|
await ExecuteFeederForPhotoBefore(feeder, procedure, doVibrateFirst, doCaptureFirst, cancellationToken);
|
|
|
|
|
|
@@ -1175,6 +1178,7 @@ namespace TeamAAS_VP.Services
|
|
|
if (cancellationToken != null && cancellationToken.IsCancellationRequested)
|
|
|
{
|
|
|
await feeder.CloseLightAsync();
|
|
|
+ await TurnOffLightAfterPhoto(procedure);
|
|
|
return (false, new string[] { "VisionTaskCancelled" });
|
|
|
}
|
|
|
|
|
|
@@ -1200,6 +1204,7 @@ namespace TeamAAS_VP.Services
|
|
|
if (!Found)
|
|
|
{
|
|
|
SendTaskMessage(Lang.拍照NG, MessageLevel.Debug);
|
|
|
+ await TurnOffLightAfterPhoto(procedure);
|
|
|
await ExecuteFeederForPhotoLater(feeder, procedure, cancellationToken);
|
|
|
continue;
|
|
|
}
|
|
|
@@ -1300,6 +1305,7 @@ namespace TeamAAS_VP.Services
|
|
|
{
|
|
|
await feeder.CloseLightAsync();
|
|
|
}
|
|
|
+ await TurnOffLightAfterPhoto(procedure);
|
|
|
|
|
|
//如果输出模式是AllAtOnce或者BatchedUntilTerminator,则分次发送数据
|
|
|
if (procedure.OutputPointMode == OutputPointMode.UntilTerminator || procedure.OutputPointMode == OutputPointMode.BatchedUntilTerminator)
|
|
|
@@ -1323,6 +1329,7 @@ namespace TeamAAS_VP.Services
|
|
|
{
|
|
|
await feeder.CloseLightAsync();
|
|
|
}
|
|
|
+ await TurnOffLightAfterPhoto(procedure);
|
|
|
SendTaskMessage(Lang.多次拍照失败, MessageLevel.Alarm);
|
|
|
return (false, new string[] { "VisionFailed" });
|
|
|
}
|
|
|
@@ -1336,6 +1343,7 @@ namespace TeamAAS_VP.Services
|
|
|
DateTime startTime = DateTime.Now;
|
|
|
try
|
|
|
{
|
|
|
+ await SetLightBeforePhoto(procedure);
|
|
|
// 触发命令传入的输入终端
|
|
|
Dictionary<string, string> InputTerminal = null;
|
|
|
|
|
|
@@ -1434,6 +1442,10 @@ namespace TeamAAS_VP.Services
|
|
|
LogHelper.WriteLogError("执行普通视觉任务时出错!", ex);
|
|
|
return (false, "Exception");
|
|
|
}
|
|
|
+ finally
|
|
|
+ {
|
|
|
+ await TurnOffLightAfterPhoto(procedure);
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
/// <summary>
|
|
|
@@ -1558,59 +1570,73 @@ namespace TeamAAS_VP.Services
|
|
|
/// <param name="robotCoord"></param>
|
|
|
/// <param name="cancellationToken"></param>
|
|
|
/// <returns></returns>
|
|
|
- public (bool IsSucceed ,double X,double Y,double U) ExecutePhotoGetSinglePoint(ProcedureModel procedure, Dictionary<string, string> InputTerminal, double[] robotCoord, CancellationToken cancellationToken)
|
|
|
+ public async Task<(bool IsSucceed, double X, double Y, double U)> ExecutePhotoGetSinglePoint(ProcedureModel procedure, Dictionary<string, string> InputTerminal, double[] robotCoord, CancellationToken cancellationToken)
|
|
|
{
|
|
|
DateTime nowtime = DateTime.Now;
|
|
|
- //拍照失败时,需要多次拍照
|
|
|
- for (int i = 0; i < procedure.FeederFailLimit; i++)
|
|
|
+ await SetLightBeforePhoto(procedure);
|
|
|
+ try
|
|
|
{
|
|
|
- SendTaskMessage(Lang.开始执行视觉流程.Replace("{0}", $"{i + 1}").Replace("{1}", procedure.Name), MessageLevel.Info);
|
|
|
-
|
|
|
- // 1. 执行相机拍照并运行视觉工具
|
|
|
- bool visionSucceed = ExecutePhoto(procedure, InputTerminal, out CogToolBlockTerminalCollection outputCollection);
|
|
|
- if (!visionSucceed)
|
|
|
+ //拍照失败时,需要多次拍照
|
|
|
+ for (int i = 0; i < procedure.FeederFailLimit; i++)
|
|
|
{
|
|
|
- SendTaskMessage(Lang.视觉任务执行失败, MessageLevel.Error);
|
|
|
- continue;
|
|
|
- }
|
|
|
+ SendTaskMessage(Lang.开始执行视觉流程.Replace("{0}", $"{i + 1}").Replace("{1}", procedure.Name), MessageLevel.Info);
|
|
|
|
|
|
- if (!outputCollection.Contains("Found"))
|
|
|
- {
|
|
|
- SendTaskMessage(Lang.未找到视觉输出结果, MessageLevel.Error);
|
|
|
- return (false,0,0,0);
|
|
|
- }
|
|
|
+ // 1. 执行相机拍照并运行视觉工具
|
|
|
+ bool visionSucceed = ExecutePhoto(procedure, InputTerminal, out CogToolBlockTerminalCollection outputCollection);
|
|
|
+ if (!visionSucceed)
|
|
|
+ {
|
|
|
+ SendTaskMessage(Lang.视觉任务执行失败, MessageLevel.Error);
|
|
|
+ continue;
|
|
|
+ }
|
|
|
|
|
|
- // 2. 获取视觉输出结果
|
|
|
- bool Found = (bool)(outputCollection["Found"].Value);
|
|
|
- if (!Found)
|
|
|
- {
|
|
|
- SendTaskMessage(Lang.拍照NG, MessageLevel.Debug);
|
|
|
- continue;
|
|
|
- }
|
|
|
+ if (!outputCollection.Contains("Found"))
|
|
|
+ {
|
|
|
+ SendTaskMessage(Lang.未找到视觉输出结果, MessageLevel.Error);
|
|
|
+ return (false, 0, 0, 0);
|
|
|
+ }
|
|
|
|
|
|
- SendTaskMessage(Lang.拍照OK, MessageLevel.Debug);
|
|
|
+ // 2. 获取视觉输出结果
|
|
|
+ bool Found = (bool)(outputCollection["Found"].Value);
|
|
|
+ if (!Found)
|
|
|
+ {
|
|
|
+ SendTaskMessage(Lang.拍照NG, MessageLevel.Debug);
|
|
|
+ continue;
|
|
|
+ }
|
|
|
|
|
|
- // 3. 获取视觉输出结果
|
|
|
- LogHelper.WriteLogInfo("开始获取视觉输出结果");
|
|
|
- //获取相机校准
|
|
|
- var calib = _calibrationService.GetCalibration(procedure.CalibrationId);
|
|
|
- string points = (string)(outputCollection["Point"].Value);
|
|
|
- string[] strpoints = points.Split(';');
|
|
|
- //先将pos按照逗号进行分隔,拿到数组
|
|
|
- var posParts = strpoints[0].Split(',');
|
|
|
- double _pixel_x = double.Parse(posParts[0]);
|
|
|
- double _pixel_y = double.Parse(posParts[1]);
|
|
|
- double _pixel_u = double.Parse(posParts[2]);
|
|
|
- //转换点位-像素转换成机器人绝对坐标
|
|
|
- var calibResult = _calibrationService.ConvertPixelToPosition((_pixel_x, _pixel_y, _pixel_u), robotCoord, calib, RobotBrand.XYZ_Platform);
|
|
|
- if (!calibResult.IsSucceed)
|
|
|
- {
|
|
|
- return (false, 0, 0, 0);
|
|
|
+ SendTaskMessage(Lang.拍照OK, MessageLevel.Debug);
|
|
|
+
|
|
|
+ // 3. 获取视觉输出结果
|
|
|
+ LogHelper.WriteLogInfo("开始获取视觉输出结果");
|
|
|
+ //获取相机校准
|
|
|
+ var calib = _calibrationService.GetCalibration(procedure.CalibrationId);
|
|
|
+ string points = (string)(outputCollection["Point"].Value);
|
|
|
+ string[] strpoints = points.Split(';');
|
|
|
+ //先将pos按照逗号进行分隔,拿到数组
|
|
|
+ var posParts = strpoints[0].Split(',');
|
|
|
+ double _pixel_x = double.Parse(posParts[0]);
|
|
|
+ double _pixel_y = double.Parse(posParts[1]);
|
|
|
+ double _pixel_u = double.Parse(posParts[2]);
|
|
|
+ //转换点位-像素转换成机器人绝对坐标
|
|
|
+ var calibResult = _calibrationService.ConvertPixelToPosition((_pixel_x, _pixel_y, _pixel_u), robotCoord, calib, RobotBrand.XYZ_Platform);
|
|
|
+ if (!calibResult.IsSucceed)
|
|
|
+ {
|
|
|
+ return (false, 0, 0, 0);
|
|
|
+ }
|
|
|
+ return (true, calibResult.X, calibResult.Y, calibResult.U);
|
|
|
}
|
|
|
- return (true, calibResult.X, calibResult.Y, calibResult.U);
|
|
|
+ SendTaskMessage(Lang.多次拍照失败, MessageLevel.Alarm);
|
|
|
+ return (false, 0, 0, 0);
|
|
|
+ }
|
|
|
+ catch (Exception ex)
|
|
|
+ {
|
|
|
+ LogHelper.WriteLogError("执行相机取图并获取单点位时出错!", ex);
|
|
|
+ return (false, 0, 0, 0);
|
|
|
+ }
|
|
|
+ finally
|
|
|
+ {
|
|
|
+ await TurnOffLightAfterPhoto(procedure);
|
|
|
+
|
|
|
}
|
|
|
- SendTaskMessage(Lang.多次拍照失败, MessageLevel.Alarm);
|
|
|
- return (false, 0, 0, 0);
|
|
|
}
|
|
|
|
|
|
/// <summary>
|
|
|
@@ -2021,6 +2047,58 @@ namespace TeamAAS_VP.Services
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
+
|
|
|
+ /// <summary>
|
|
|
+ /// 在拍照前设置光源亮度和打开光源
|
|
|
+ /// </summary>
|
|
|
+ /// <param name="procedure">流程模型</param>
|
|
|
+ /// <returns></returns>
|
|
|
+ public async Task SetLightBeforePhoto(ProcedureModel procedure)
|
|
|
+ {
|
|
|
+ //判断当前流程是否启用光源控制
|
|
|
+ if (procedure.IsControlLightChannels)
|
|
|
+ {
|
|
|
+ //打开所有需要控制的光源通道
|
|
|
+ foreach (var lightChannel in procedure.LightChannels)
|
|
|
+ {
|
|
|
+ bool isSucceed = false;
|
|
|
+ isSucceed = await _lightManagerService.TurnOnGlobalChannelAsync(lightChannel.GlobalIndex);
|
|
|
+ if (!isSucceed)
|
|
|
+ {
|
|
|
+ LogHelper.WriteLogInfo($"设置光源通道{lightChannel.GlobalIndex}打开失败!");
|
|
|
+ }
|
|
|
+ isSucceed = await _lightManagerService.SetGlobalChannelBrightnessAsync(lightChannel.GlobalIndex, lightChannel.DefaultBrightness);
|
|
|
+ if (!isSucceed)
|
|
|
+ {
|
|
|
+ LogHelper.WriteLogInfo($"设置光源通道{lightChannel.GlobalIndex}亮度{lightChannel.DefaultBrightness}失败!");
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ /// <summary>
|
|
|
+ /// 在拍照后关闭光源
|
|
|
+ /// </summary>
|
|
|
+ /// <param name="procedure">流程模型</param>
|
|
|
+ /// <returns></returns>
|
|
|
+ public async Task TurnOffLightAfterPhoto(ProcedureModel procedure)
|
|
|
+ {
|
|
|
+ //判断当前流程是否启用光源控制
|
|
|
+ if (procedure.IsControlLightChannels)
|
|
|
+ {
|
|
|
+ //关闭所有需要控制的光源通道
|
|
|
+ foreach (var lightChannel in procedure.LightChannels)
|
|
|
+ {
|
|
|
+ bool isSucceed = false;
|
|
|
+ isSucceed = await _lightManagerService.TurnOffGlobalChannelAsync(lightChannel.GlobalIndex);
|
|
|
+ if (!isSucceed)
|
|
|
+ {
|
|
|
+ LogHelper.WriteLogInfo($"设置光源通道{lightChannel.GlobalIndex}关闭失败!");
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
#endregion
|
|
|
}
|
|
|
}
|