3052 lines
167 KiB
C#
3052 lines
167 KiB
C#
|
|
using Common;
|
|||
|
|
using Common.HTTPModels;
|
|||
|
|
using Common.Models;
|
|||
|
|
using CommunityToolkit.Mvvm.Messaging;
|
|||
|
|
using Dm.filter.log;
|
|||
|
|
using MegaRobo.C00225155.ControlDevices;
|
|||
|
|
using MegaRobo.C00225155.ControlDevices.Scanner;
|
|||
|
|
using MegaRobo.C00225155.ControlDevices.WeightDevice;
|
|||
|
|
using MegaRobo.C00225155.Entities;
|
|||
|
|
using MegaRobo.C00225155.Entities.Entity_DB;
|
|||
|
|
using MegaRobo.C00225155.Entities.Enums;
|
|||
|
|
using MegaRobo.C00225155.Entities.FromWeb;
|
|||
|
|
using MegaRobo.C00225155.Entities.ToWeb;
|
|||
|
|
using MegaRobo.Contract;
|
|||
|
|
using MegaRobo.Contract.Servers;
|
|||
|
|
using MegaRobo.ControlDevices;
|
|||
|
|
using MegaRobo.ControlDevices.Models;
|
|||
|
|
using MegaRobo.Entities;
|
|||
|
|
using MegaRobo.Entities.ViewTT;
|
|||
|
|
using MegaRobo.Logger;
|
|||
|
|
using MegaRobo.PipetteTool.HamiltonConsole;
|
|||
|
|
using MegaRobo.PipetteTool.HamiltonConsole.PipetteDevices.HamiltonDevices;
|
|||
|
|
using NetTaste;
|
|||
|
|
using Newtonsoft.Json;
|
|||
|
|
using Newtonsoft.Json.Linq;
|
|||
|
|
using Nito.AsyncEx;
|
|||
|
|
using SqlSugar;
|
|||
|
|
using System;
|
|||
|
|
using System.CodeDom;
|
|||
|
|
using System.Collections.Concurrent;
|
|||
|
|
using System.Collections.Generic;
|
|||
|
|
using System.Collections.ObjectModel;
|
|||
|
|
using System.Diagnostics;
|
|||
|
|
using System.Diagnostics.Metrics;
|
|||
|
|
using System.Linq;
|
|||
|
|
using System.Net.Http;
|
|||
|
|
using System.Reflection;
|
|||
|
|
using System.Text;
|
|||
|
|
using System.Text.Json;
|
|||
|
|
using System.Threading;
|
|||
|
|
using System.Threading.Tasks;
|
|||
|
|
using System.Windows;
|
|||
|
|
using System.Windows.Controls;
|
|||
|
|
using System.Windows.Documents;
|
|||
|
|
using System.Windows.Threading;
|
|||
|
|
using static System.Net.Mime.MediaTypeNames;
|
|||
|
|
using JsonSerializer = System.Text.Json.JsonSerializer;
|
|||
|
|
using Pipette1ml = MegaRobo.PipetteTool.HamiltonConsole.PipetteDevices.HamiltonDevices;
|
|||
|
|
using Pipette5ml = MegaRobo.PipetteTool.HamiltonConsole.PipetteDevices.Hamilton5mlDevices;
|
|||
|
|
|
|||
|
|
namespace MegaRobo.C00225155.AppServer.ExecuteWorks
|
|||
|
|
{
|
|||
|
|
public partial class StationService_MaterialDosing : StationServiceBase
|
|||
|
|
{
|
|||
|
|
public bool TestMode = false; //测试模式
|
|||
|
|
|
|||
|
|
/// <summary>
|
|||
|
|
/// 作为客户端 和BS做回复
|
|||
|
|
/// </summary>
|
|||
|
|
private IHttpClientFactory _httpClientFactory;
|
|||
|
|
|
|||
|
|
protected WeightService_Ts02 preWeight;
|
|||
|
|
private LabxService labxService;
|
|||
|
|
|
|||
|
|
private List<ServiceReference1.Instrument> labxPowderInstrument;
|
|||
|
|
public StationProperty StationProp = new StationProperty();
|
|||
|
|
|
|||
|
|
/// <summary>
|
|||
|
|
/// 扫码枪服务
|
|||
|
|
/// </summary>
|
|||
|
|
protected ScannerService scannerService;
|
|||
|
|
protected ScannerService scannerService_Powder;
|
|||
|
|
|
|||
|
|
private Pipette1ml.PipetteService pipetteService_1ml { get; set; }
|
|||
|
|
|
|||
|
|
/// <summary>
|
|||
|
|
/// 从传送平台上料取载具工装 线程
|
|||
|
|
/// </summary>
|
|||
|
|
private Task TaskBoxFromTransferPlateTask { get; set; } = null;
|
|||
|
|
|
|||
|
|
/// <summary>
|
|||
|
|
/// 下载具工装到传送平台 线程
|
|||
|
|
/// </summary>
|
|||
|
|
private Task DownloadBoxToTransferPlateTask { get; set; } = null;
|
|||
|
|
|
|||
|
|
/// <summary>
|
|||
|
|
/// 投料线程,根据当前投料物
|
|||
|
|
/// </summary>
|
|||
|
|
private Task DoseTask_BasedOnCurrentDoseFlow { get; set; } = null;
|
|||
|
|
|
|||
|
|
/// <summary>
|
|||
|
|
/// 当前正在投料的流程
|
|||
|
|
/// </summary>
|
|||
|
|
private MaterialDoseFunctionFlow _currentDoseFlow { get; set; } = null;
|
|||
|
|
|
|||
|
|
/// <summary>
|
|||
|
|
/// 当前使用的原液瓶,以及原液瓶所在的FixturePosPro
|
|||
|
|
/// </summary>
|
|||
|
|
private UseLiquidBottle _currentUseSourceLiquidBottle { get; set; } = null;
|
|||
|
|
|
|||
|
|
/// <summary>
|
|||
|
|
/// 当前使用粉末瓶,以及粉末瓶所在的FixturePosPro
|
|||
|
|
/// </summary>
|
|||
|
|
private SourcePowderBottleModel _currentUsePowderBottle { get; set; } = null;
|
|||
|
|
|
|||
|
|
#region event
|
|||
|
|
/// <summary>
|
|||
|
|
/// 更新试剂事件
|
|||
|
|
/// </summary>
|
|||
|
|
public event EventHandler<List<DataResult_Dose>> UpdateAdditiveEvent;
|
|||
|
|
|
|||
|
|
private List<DataResult_Dose> OngoingDoseDataResultList = new List<DataResult_Dose>();
|
|||
|
|
|
|||
|
|
public event EventHandler<C00225155.Entities.DeviceStatus> UpdateDeviceStatusEvent;
|
|||
|
|
|
|||
|
|
#endregion
|
|||
|
|
|
|||
|
|
public StationService_MaterialDosing(ICoreService coreService, WorkService workService, DeviceNames plcName, string station) : base(coreService, workService, plcName, station)
|
|||
|
|
{
|
|||
|
|
StationProp = new StationProperty()
|
|||
|
|
{
|
|||
|
|
cancellationToken = new CancellationTokenSource(),
|
|||
|
|
ManualResetEvent = new ManualResetEvent(true),
|
|||
|
|
StationNum = 1,
|
|||
|
|
StationName = "投料工站",
|
|||
|
|
bStartButtonTrigger = false,
|
|||
|
|
bStopButtonTrigger = false,
|
|||
|
|
bRunFinish = false,
|
|||
|
|
bHaveReset = false,
|
|||
|
|
CTWatch = new Stopwatch(),
|
|||
|
|
};
|
|||
|
|
StationProp.ObstructFlagList = new ConcurrentDictionary<string, ObstructFlag>();
|
|||
|
|
StationProp.ObstructFlagList.TryAdd("传送平台收到准备上料信号", new ObstructFlag()
|
|||
|
|
{
|
|||
|
|
strName = "传送平台收到准备上料信号",
|
|||
|
|
flag = false
|
|||
|
|
});
|
|||
|
|
StationProp.ObstructFlagList.TryAdd("四轴机械手运行中", new ObstructFlag()
|
|||
|
|
{
|
|||
|
|
strName = "四轴机械手运行中",
|
|||
|
|
flag = false
|
|||
|
|
});
|
|||
|
|
StationProp.ObstructFlagList.TryAdd("四轴机械手正在使用传送平台", new ObstructFlag()
|
|||
|
|
{
|
|||
|
|
strName = "四轴机械手正在使用传送平台",
|
|||
|
|
flag = false
|
|||
|
|
});
|
|||
|
|
|
|||
|
|
_ = Task.Run(ProcessDispatcherEx);
|
|||
|
|
_ = Task.Run(DownLoadDispatcherEx);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
#region BS相关
|
|||
|
|
public async Task ChangeDeviceStatus(Entities.DeviceStatus deviceStatus)
|
|||
|
|
{
|
|||
|
|
try
|
|||
|
|
{
|
|||
|
|
StationProp.deviceStatus = deviceStatus;
|
|||
|
|
UpdateDeviceStatusEvent?.Invoke(this, deviceStatus);
|
|||
|
|
}
|
|||
|
|
catch (Exception ex)
|
|||
|
|
{
|
|||
|
|
//MessageBox.Show(ex.Message);
|
|||
|
|
}
|
|||
|
|
finally
|
|||
|
|
{
|
|||
|
|
//todo:此处回调BS
|
|||
|
|
var status = new { status = deviceStatus.ToString() };
|
|||
|
|
var res = await SendJson(new Guid().ToString(), "status", JsonConvert.SerializeObject(status));
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
public async Task OpenDoor(bool isChangeDeviceState = true)
|
|||
|
|
{
|
|||
|
|
//if (isChangeDeviceState) UpdateDeviceStatusEvent?.Invoke(this, Entities.DeviceStatus.CarryOn);
|
|||
|
|
if (TestMode)
|
|||
|
|
{
|
|||
|
|
await Task.Delay(5000);
|
|||
|
|
}
|
|||
|
|
else
|
|||
|
|
{
|
|||
|
|
//await this.TransferPlateformMoveTo(PlateformPos.TransferIn, new System.Threading.CancellationToken());
|
|||
|
|
await this.TransferPlateformMoveTo(PlateformPos.TransferOut, new System.Threading.CancellationToken());
|
|||
|
|
}
|
|||
|
|
await ChangeDeviceStatus(Entities.DeviceStatus.Idel);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
public async Task CloseDoor(bool isClose, bool isChangeDeviceState = true)
|
|||
|
|
{
|
|||
|
|
if (isChangeDeviceState) UpdateDeviceStatusEvent?.Invoke(this, Entities.DeviceStatus.CarryOn);
|
|||
|
|
if (isClose)
|
|||
|
|
{
|
|||
|
|
await this.TransferPlateformMoveTo(PlateformPos.TransferIn, new System.Threading.CancellationToken());
|
|||
|
|
}
|
|||
|
|
if (isChangeDeviceState)
|
|||
|
|
{
|
|||
|
|
await ChangeDeviceStatus(Entities.DeviceStatus.Idel);
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
public async Task StartLoad()
|
|||
|
|
{
|
|||
|
|
//await ChangeDeviceStatus(Entities.DeviceStatus.CarryOn);
|
|||
|
|
#region 开始搬运
|
|||
|
|
//await Task.Delay(10_000);
|
|||
|
|
var powderlist = new ObservableCollection<SourcePowderBottleModel>();
|
|||
|
|
for (int i = 0; i < 4; i++)
|
|||
|
|
{
|
|||
|
|
powderlist.Add(new SourcePowderBottleModel()
|
|||
|
|
{
|
|||
|
|
PosId_InBox = i + 1,
|
|||
|
|
HaveBottle = false,
|
|||
|
|
RemainWeight = 0,
|
|||
|
|
SNCode = string.Empty,
|
|||
|
|
PowderBottleType = PowderBottleTypeEnum._16mL,
|
|||
|
|
SourcePowderBottleState = SourceBottleStateEnum.Idl,
|
|||
|
|
});
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
var powderlist_125 = new ObservableCollection<SourcePowderBottleModel>();
|
|||
|
|
for (int i = 0; i < 2; i++)
|
|||
|
|
{
|
|||
|
|
powderlist_125.Add(new SourcePowderBottleModel()
|
|||
|
|
{
|
|||
|
|
PosId_InBox = i + 1,
|
|||
|
|
HaveBottle = false,
|
|||
|
|
RemainWeight = 0,
|
|||
|
|
SNCode = string.Empty,
|
|||
|
|
PowderBottleType = PowderBottleTypeEnum._125mL,
|
|||
|
|
SourcePowderBottleState = SourceBottleStateEnum.Idl,
|
|||
|
|
});
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
//await TransferPlateformMoveTo(PlateformPos.TransferIn, _cts.Token);
|
|||
|
|
// 1. 粉末瓶:从粉末工装 → 粉末缓存区(逐个处理)先处理粉末,放置干涉
|
|||
|
|
while (workService.ProjectPro.TransferArea.Any(f => !f.IsEmpty &&
|
|||
|
|
(f.FixtureType == BoxTypeEnum._16mL粉末瓶工装 || f.FixtureType == BoxTypeEnum._125mL粉末瓶工装))
|
|||
|
|
&& workService.ProjectPro.PowderHeaderCacheArea.Any(f => !f.HaveBottle))
|
|||
|
|
{
|
|||
|
|
// 检查是否存在任何有瓶子的粉末工装,如果不存在则跳出循环
|
|||
|
|
bool hasPowderHeader = workService.ProjectPro.TransferArea
|
|||
|
|
.Where(f => !f.IsEmpty && (f.FixtureType == BoxTypeEnum._16mL粉末瓶工装 || f.FixtureType == BoxTypeEnum._125mL粉末瓶工装))
|
|||
|
|
.Any(f => (f is SourcePowderBottleBoxModel box16 && box16.SourcePowderBottleCollection.Any(s => s.HaveBottle)) ||
|
|||
|
|
(f is SourcePowderBottleBoxModel_125ml box125 && box125.SourcePowderBottleCollection.Any(s => s.HaveBottle)));
|
|||
|
|
|
|||
|
|
if (!hasPowderHeader) break;
|
|||
|
|
await TransferPlateformMoveTo(PlateformPos.GloveBox2, _cts.Token);
|
|||
|
|
await TransferPlateformMoveTo(PlateformPos.GloveBox1, _cts.Token); //先去2再去1
|
|||
|
|
var powderFixture = workService.ProjectPro.TransferArea.FirstOrDefault(f => !f.IsEmpty &&
|
|||
|
|
(f.FixtureType == BoxTypeEnum._16mL粉末瓶工装 || f.FixtureType == BoxTypeEnum._125mL粉末瓶工装));
|
|||
|
|
|
|||
|
|
SourcePowderBottleBoxModel powderBox = null;
|
|||
|
|
SourcePowderBottleBoxModel_125ml powderBox_125 = null;
|
|||
|
|
|
|||
|
|
if (powderFixture is SourcePowderBottleBoxModel)
|
|||
|
|
{
|
|||
|
|
powderBox = powderFixture as SourcePowderBottleBoxModel;
|
|||
|
|
}
|
|||
|
|
else if (powderFixture is SourcePowderBottleBoxModel_125ml)
|
|||
|
|
{
|
|||
|
|
powderBox_125 = powderFixture as SourcePowderBottleBoxModel_125ml;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
if (powderBox == null && powderBox_125 == null) return;
|
|||
|
|
|
|||
|
|
int powderTransferIndex = workService.ProjectPro.TransferArea.IndexOf(powderFixture);
|
|||
|
|
if (powderBox != null)
|
|||
|
|
{
|
|||
|
|
for (int i = 0; i < powderBox.SourcePowderBottleCollection.Count; i++)
|
|||
|
|
{
|
|||
|
|
// 处理每个有瓶的粉末瓶(只处理一个,避免一次搬多个)
|
|||
|
|
var powderBottle = powderBox.SourcePowderBottleCollection[i];
|
|||
|
|
if (powderBottle == null || !powderBottle.HaveBottle) continue;
|
|||
|
|
|
|||
|
|
// 找到粉末缓存区的空位置
|
|||
|
|
var aimPowderBottle = workService.ProjectPro.PowderHeaderCacheArea.FirstOrDefault(f => !f.HaveBottle);
|
|||
|
|
if (aimPowderBottle == null)
|
|||
|
|
{
|
|||
|
|
MessageBox.Show("粉末缓存区已满,无法继续上料!");
|
|||
|
|
return;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
int aimPowderIndex = workService.ProjectPro.PowderHeaderCacheArea.IndexOf(aimPowderBottle);
|
|||
|
|
|
|||
|
|
// 执行机械手操作
|
|||
|
|
await FourAxisTakePowderHeader((int)BoxAreaEnum._手套箱传送平台, powderFixture.BoxId_inDoseUpload, powderBottle.PosId_InBox, powderBox.PowderBottleType, _cts.Token,1);
|
|||
|
|
await FourAxisGoToScannPos_powder(_cts.Token, powderBottle);
|
|||
|
|
|
|||
|
|
// 称重
|
|||
|
|
//if (!TestMode) await preWeight.Peel();
|
|||
|
|
//var powderWeight = await FourAxisPutPowderHeaderToPreWeight(_cts.Token);
|
|||
|
|
//powderBottle.OriginWeight = powderBottle.RemainWeight = powderWeight;
|
|||
|
|
// 放入缓存区
|
|||
|
|
await FourAxisPutPowderHeader((int)BoxAreaEnum._加样头存放平台, 1, aimPowderBottle.Pos_InDosePowderHC, powderBox.PowderBottleType, _cts.Token,1);
|
|||
|
|
|
|||
|
|
// 更新粉末缓存区(替换集合元素)
|
|||
|
|
var newPowderBottle = File_Operator.DeepCopy(powderBottle);
|
|||
|
|
newPowderBottle.HaveBottle = true;
|
|||
|
|
newPowderBottle.Pos_InDosePowderHC = aimPowderBottle.Pos_InDosePowderHC;
|
|||
|
|
|
|||
|
|
App.Current.Dispatcher.Invoke(() =>
|
|||
|
|
{
|
|||
|
|
powderBottle.HaveBottle = false;
|
|||
|
|
workService.ProjectPro.PowderHeaderCacheArea[aimPowderIndex] = newPowderBottle;
|
|||
|
|
powderBox.SourcePowderBottleCollection[i] = new SourcePowderBottleModel();
|
|||
|
|
powderBox.SourcePowderBottleCollection[i].HaveBottle = false;
|
|||
|
|
});
|
|||
|
|
// 标记原粉末瓶为空
|
|||
|
|
//var updatedBottle = powderBox.SourcePowderBottleCollection.FirstOrDefault(b => b.PosId_InBox == powderBottle.PosId_InBox);
|
|||
|
|
//updatedBottle.HaveBottle = false;
|
|||
|
|
}
|
|||
|
|
App.Current.Dispatcher.Invoke(() =>
|
|||
|
|
{
|
|||
|
|
workService.ProjectPro.TransferArea[powderTransferIndex] = new SourcePowderBottleBoxModel()
|
|||
|
|
{
|
|||
|
|
BoxId_inDoseUpload = powderTransferIndex + 1,
|
|||
|
|
IsEmpty = false,
|
|||
|
|
IsDoseFinish = false,
|
|||
|
|
BoxArea = BoxAreaEnum._手套箱传送平台,
|
|||
|
|
FixtureType = BoxTypeEnum._16mL粉末瓶工装,
|
|||
|
|
PowderBottleType = PowderBottleTypeEnum._16mL,
|
|||
|
|
SourcePowderBottleCollection = powderlist,
|
|||
|
|
BoxSNCode = powderBox.BoxSNCode
|
|||
|
|
};
|
|||
|
|
});
|
|||
|
|
}
|
|||
|
|
else if (powderBox_125 != null)
|
|||
|
|
{
|
|||
|
|
for (int i = 0; i < powderBox_125.SourcePowderBottleCollection.Count; i++)
|
|||
|
|
{
|
|||
|
|
// 处理每个有瓶的粉末瓶(只处理一个,避免一次搬多个)
|
|||
|
|
var powderBottle = powderBox_125.SourcePowderBottleCollection[i];
|
|||
|
|
if (powderBottle == null || !powderBottle.HaveBottle) continue;
|
|||
|
|
|
|||
|
|
// 找到粉末缓存区的空位置
|
|||
|
|
var aimPowderBottle = workService.ProjectPro.PowderHeaderCacheArea.FirstOrDefault(f => !f.HaveBottle);
|
|||
|
|
if (aimPowderBottle == null)
|
|||
|
|
{
|
|||
|
|
MessageBox.Show("粉末缓存区已满,无法继续上料!");
|
|||
|
|
return;
|
|||
|
|
}
|
|||
|
|
int aimPowderIndex = workService.ProjectPro.PowderHeaderCacheArea.IndexOf(aimPowderBottle);
|
|||
|
|
|
|||
|
|
// 执行机械手操作
|
|||
|
|
await FourAxisTakePowderHeader((int)BoxAreaEnum._手套箱传送平台, powderFixture.BoxId_inDoseUpload, powderBottle.PosId_InBox, powderBox_125.PowderBottleType, _cts.Token,1);
|
|||
|
|
await FourAxisGoToScannPos_powder(_cts.Token, powderBottle);
|
|||
|
|
|
|||
|
|
// 称重
|
|||
|
|
//if (!TestMode) await preWeight.Peel();
|
|||
|
|
//double powderWeight = await FourAxisPutPowderHeaderToPreWeight(_cts.Token);
|
|||
|
|
//powderBottle.OriginWeight = powderBottle.RemainWeight = powderWeight;
|
|||
|
|
// 放入缓存区
|
|||
|
|
await FourAxisPutPowderHeader((int)BoxAreaEnum._加样头存放平台, 1, aimPowderBottle.Pos_InDosePowderHC, powderBox_125.PowderBottleType, _cts.Token,1);
|
|||
|
|
|
|||
|
|
// 更新粉末缓存区(替换集合元素)
|
|||
|
|
var newPowderBottle = File_Operator.DeepCopy(powderBottle);
|
|||
|
|
newPowderBottle.HaveBottle = true;
|
|||
|
|
newPowderBottle.Pos_InDosePowderHC = aimPowderBottle.Pos_InDosePowderHC;
|
|||
|
|
App.Current.Dispatcher.Invoke(() =>
|
|||
|
|
{
|
|||
|
|
powderBottle.HaveBottle = false;
|
|||
|
|
workService.ProjectPro.PowderHeaderCacheArea[aimPowderIndex] = newPowderBottle;
|
|||
|
|
powderBox.SourcePowderBottleCollection[i] = new SourcePowderBottleModel();
|
|||
|
|
powderBox.SourcePowderBottleCollection[i].HaveBottle = false;
|
|||
|
|
});
|
|||
|
|
// 标记原粉末瓶为空
|
|||
|
|
//var updatedBottle = powderBox_125.SourcePowderBottleCollection.FirstOrDefault(b => b.PosId_InBox == powderBottle.PosId_InBox);
|
|||
|
|
//updatedBottle.HaveBottle = false;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
App.Current.Dispatcher.Invoke(() =>
|
|||
|
|
{
|
|||
|
|
workService.ProjectPro.TransferArea[powderTransferIndex] = new SourcePowderBottleBoxModel_125ml()
|
|||
|
|
{
|
|||
|
|
BoxId_inDoseUpload = powderTransferIndex + 1,
|
|||
|
|
IsEmpty = false,
|
|||
|
|
IsDoseFinish = false,
|
|||
|
|
FixtureType = BoxTypeEnum._125mL粉末瓶工装,
|
|||
|
|
PowderBottleType = PowderBottleTypeEnum._125mL,
|
|||
|
|
SourcePowderBottleCollection = powderlist_125,
|
|||
|
|
BoxSNCode = powderBox_125.BoxSNCode
|
|||
|
|
};
|
|||
|
|
});
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// 2. Tip头工装:从传送平台 → Tip头区域
|
|||
|
|
while (workService.ProjectPro.TransferArea.Any(f => !f.IsEmpty &&
|
|||
|
|
(f.FixtureType == BoxTypeEnum._50uLTip头工装 || f.FixtureType == BoxTypeEnum._300uLTip头工装 || f.FixtureType == BoxTypeEnum._1000uLTip头工装))
|
|||
|
|
&& workService.ProjectPro.TipHeadArea.Any(f => !f.HaveBox && f.IsEmpty))
|
|||
|
|
{
|
|||
|
|
await TransferPlateformMoveTo(PlateformPos.GloveBox2, _cts.Token);
|
|||
|
|
//OrderByDescending
|
|||
|
|
var tipFixture = workService.ProjectPro.TransferArea.LastOrDefault(f => !f.IsEmpty &&
|
|||
|
|
(f.FixtureType == BoxTypeEnum._50uLTip头工装 || f.FixtureType == BoxTypeEnum._300uLTip头工装 || f.FixtureType == BoxTypeEnum._1000uLTip头工装));
|
|||
|
|
int tipTransferIndex = workService.ProjectPro.TransferArea.IndexOf(tipFixture);
|
|||
|
|
|
|||
|
|
// 找到Tip头区域的空位置
|
|||
|
|
var aimTipBox = workService.ProjectPro.TipHeadArea.FirstOrDefault(f => !f.HaveBox && f.IsEmpty);
|
|||
|
|
int aimTipIndex = workService.ProjectPro.TipHeadArea.IndexOf(aimTipBox);
|
|||
|
|
|
|||
|
|
// 执行机械手操作
|
|||
|
|
await FourAxisTakeBox((int)BoxAreaEnum._手套箱传送平台, tipFixture.FixtureType, (ushort)tipFixture.BoxId_inDoseUpload, _cts.Token);
|
|||
|
|
|
|||
|
|
ushort aimPos = (ushort)aimTipBox.BoxId_inDosingStation;
|
|||
|
|
if (aimPos == 1)
|
|||
|
|
{
|
|||
|
|
aimPos = 3;
|
|||
|
|
}
|
|||
|
|
else if (aimPos == 3)
|
|||
|
|
{
|
|||
|
|
aimPos = 1;
|
|||
|
|
}
|
|||
|
|
await FourAxisPutBox((int)BoxAreaEnum._Tip托盘存放平台, tipFixture.FixtureType, aimPos, _cts.Token);
|
|||
|
|
|
|||
|
|
App.Current.Dispatcher.Invoke(() =>
|
|||
|
|
{
|
|||
|
|
// 复制Tip头工装到Tip区域(替换集合元素)
|
|||
|
|
BaseBottleBox TipBox = File_Operator.DeepCopy(tipFixture);
|
|||
|
|
if (TipBox is TipBoxModel newTipBox)
|
|||
|
|
{
|
|||
|
|
newTipBox.BoxId_inDosingStation = aimTipBox.BoxId_inDosingStation;
|
|||
|
|
newTipBox.HaveBox = true;
|
|||
|
|
newTipBox.IsEmpty = false;
|
|||
|
|
newTipBox.IsUseFinsh = false;
|
|||
|
|
newTipBox.BoxArea = BoxAreaEnum._Tip托盘存放平台;
|
|||
|
|
workService.ProjectPro.TipHeadArea[aimTipIndex] = newTipBox; // 关键:更新集合元素
|
|||
|
|
}
|
|||
|
|
else
|
|||
|
|
{
|
|||
|
|
MessageBox.Show("error");
|
|||
|
|
}
|
|||
|
|
// 重置传送平台
|
|||
|
|
workService.ProjectPro.TransferArea[tipTransferIndex] = new BaseBottleBox()
|
|||
|
|
{
|
|||
|
|
IsEmpty = true,
|
|||
|
|
BoxId_inDoseUpload = tipFixture.BoxId_inDoseUpload,
|
|||
|
|
IsDoseFinish = false,
|
|||
|
|
IsUseFinsh = false,
|
|||
|
|
BoxArea = BoxAreaEnum._手套箱传送平台
|
|||
|
|
};
|
|||
|
|
});
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// 3. 原液工装:从传送平台 → 工装缓存区(任意空位置 改为 0,4号位置)
|
|||
|
|
while (workService.ProjectPro.TransferArea.Any(f => !f.IsEmpty && f.FixtureType == BoxTypeEnum._40mL原液工装)
|
|||
|
|
&& workService.ProjectPro.FixtureCacheArea.Any(a => a.IsEmpty && (a.BoxId_inDosingStation == 1 || a.BoxId_inDosingStation == 5)))
|
|||
|
|
{
|
|||
|
|
await TransferPlateformMoveTo(PlateformPos.GloveBox2, _cts.Token);
|
|||
|
|
var liquidFixture = workService.ProjectPro.TransferArea.First(f => !f.IsEmpty && f.FixtureType == BoxTypeEnum._40mL原液工装);
|
|||
|
|
int liquidTransferIndex = workService.ProjectPro.TransferArea.IndexOf(liquidFixture);
|
|||
|
|
|
|||
|
|
var aimFixture = workService.ProjectPro.FixtureCacheArea.First(a => a.IsEmpty && (a.BoxId_inDosingStation == 1 || a.BoxId_inDosingStation == 5)); //原液只能放置在1,5
|
|||
|
|
int aimCacheIndex = workService.ProjectPro.FixtureCacheArea.IndexOf(aimFixture);
|
|||
|
|
|
|||
|
|
// 执行机械手操作(传入原工装类型)
|
|||
|
|
await FourAxisTakeBox((int)BoxAreaEnum._手套箱传送平台, liquidFixture.FixtureType, (ushort)liquidFixture.BoxId_inDoseUpload, _cts.Token);
|
|||
|
|
await FourAxisPutBox((int)BoxAreaEnum._托盘存放平台, liquidFixture.FixtureType, (ushort)aimFixture.BoxId_inDosingStation, _cts.Token);
|
|||
|
|
|
|||
|
|
// 复制原液工装到缓存区
|
|||
|
|
var newCacheFixture = File_Operator.DeepCopy(liquidFixture);
|
|||
|
|
newCacheFixture.BoxId_inDosingStation = aimFixture.BoxId_inDosingStation;
|
|||
|
|
newCacheFixture.IsDoseFinish = false;
|
|||
|
|
newCacheFixture.IsEmpty = false;
|
|||
|
|
newCacheFixture.IsUseFinsh = false;
|
|||
|
|
newCacheFixture.BoxArea = BoxAreaEnum._托盘存放平台;
|
|||
|
|
App.Current.Dispatcher.Invoke(() =>
|
|||
|
|
{
|
|||
|
|
workService.ProjectPro.FixtureCacheArea[aimCacheIndex] = newCacheFixture;
|
|||
|
|
// 重置传送平台
|
|||
|
|
workService.ProjectPro.TransferArea[liquidTransferIndex] = new BaseBottleBox()
|
|||
|
|
{
|
|||
|
|
IsEmpty = true,
|
|||
|
|
BoxId_inDoseDnload = liquidFixture.BoxId_inDoseUpload,
|
|||
|
|
BoxId_inDoseUpload = liquidFixture.BoxId_inDoseUpload,
|
|||
|
|
IsDoseFinish = false,
|
|||
|
|
IsUseFinsh = false,
|
|||
|
|
BoxArea = BoxAreaEnum._手套箱传送平台
|
|||
|
|
};
|
|||
|
|
});
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// 4. 样品工装:从传送平台 → 工装缓存区(排除1、5号位置)
|
|||
|
|
while (workService.ProjectPro.TransferArea.Any(f => !f.IsEmpty &&
|
|||
|
|
(f.FixtureType == BoxTypeEnum._5mL样品工装 || f.FixtureType == BoxTypeEnum._12mL样品工装))
|
|||
|
|
&& workService.ProjectPro.FixtureCacheArea.Any(a => a.IsEmpty && a.BoxId_inDosingStation != 1 && a.BoxId_inDosingStation != 5))
|
|||
|
|
{
|
|||
|
|
await TransferPlateformMoveTo(PlateformPos.GloveBox2, _cts.Token);
|
|||
|
|
// 找到传送平台中的样品工装(取第一个非空)
|
|||
|
|
var sampleFixture = workService.ProjectPro.TransferArea.First(f => !f.IsEmpty &&
|
|||
|
|
(f.FixtureType == BoxTypeEnum._5mL样品工装 || f.FixtureType == BoxTypeEnum._12mL样品工装));
|
|||
|
|
|
|||
|
|
int sampleTransferIndex = workService.ProjectPro.TransferArea.IndexOf(sampleFixture); // 获取集合索引
|
|||
|
|
|
|||
|
|
// 找到缓存区的空位置
|
|||
|
|
var aimFixture = workService.ProjectPro.FixtureCacheArea.First(a => a.IsEmpty && a.BoxId_inDosingStation != 1 && a.BoxId_inDosingStation != 5 && a.BoxId_inDosingStation != 2 && a.BoxId_inDosingStation != 6);
|
|||
|
|
int aimCacheIndex = workService.ProjectPro.FixtureCacheArea.IndexOf(aimFixture); // 获取集合索引
|
|||
|
|
|
|||
|
|
// 执行机械手操作(传入原工装类型,而非空工装类型)
|
|||
|
|
await FourAxisTakeBox((int)BoxAreaEnum._手套箱传送平台, sampleFixture.FixtureType, (ushort)sampleFixture.BoxId_inDoseUpload, _cts.Token);
|
|||
|
|
await FourAxisPutBox((int)BoxAreaEnum._托盘存放平台, sampleFixture.FixtureType, (ushort)aimFixture.BoxId_inDosingStation, _cts.Token);
|
|||
|
|
|
|||
|
|
App.Current.Dispatcher.Invoke(() =>
|
|||
|
|
{
|
|||
|
|
// 复制样品工装到缓存区(替换集合元素)
|
|||
|
|
var newCacheFixture = File_Operator.DeepCopy(sampleFixture);
|
|||
|
|
newCacheFixture.BoxId_inDosingStation = aimFixture.BoxId_inDosingStation;
|
|||
|
|
newCacheFixture.IsDoseFinish = false;
|
|||
|
|
newCacheFixture.IsEmpty = false;
|
|||
|
|
newCacheFixture.IsUseFinsh = false;
|
|||
|
|
newCacheFixture.BoxArea = BoxAreaEnum._托盘存放平台;
|
|||
|
|
workService.ProjectPro.FixtureCacheArea[aimCacheIndex] = newCacheFixture;
|
|||
|
|
// 重置传送平台位置为空工装
|
|||
|
|
workService.ProjectPro.TransferArea[sampleTransferIndex] = new BaseBottleBox()
|
|||
|
|
{
|
|||
|
|
IsEmpty = true,
|
|||
|
|
BoxId_inDoseDnload = sampleFixture.BoxId_inDoseUpload,
|
|||
|
|
BoxId_inDoseUpload = sampleFixture.BoxId_inDoseUpload,
|
|||
|
|
IsDoseFinish = false,
|
|||
|
|
IsUseFinsh = false,
|
|||
|
|
BoxArea = BoxAreaEnum._手套箱传送平台
|
|||
|
|
};
|
|||
|
|
});
|
|||
|
|
}
|
|||
|
|
await TransferPlateformMoveTo(PlateformPos.GloveBox1, _cts.Token); //最终停留在这个位置最安全
|
|||
|
|
// 无符合条件的工装可上料
|
|||
|
|
if (workService.ProjectPro.TransferArea.Any(f => !f.IsEmpty && f.FixtureType != BoxTypeEnum._16mL粉末瓶工装 && f.FixtureType != BoxTypeEnum._125mL粉末瓶工装))
|
|||
|
|
{
|
|||
|
|
MessageBox.Show("无可用工装或目标区域已满,无法上料!");
|
|||
|
|
}
|
|||
|
|
#endregion
|
|||
|
|
this.StationProp.deviceStatus = Entities.DeviceStatus.Idel;
|
|||
|
|
UpdateDeviceStatusEvent?.Invoke(this, Entities.DeviceStatus.Idel);
|
|||
|
|
}
|
|||
|
|
#endregion
|
|||
|
|
|
|||
|
|
#region qrbian 按目标瓶配置液体
|
|||
|
|
|
|||
|
|
private CancellationTokenSource _cts = new CancellationTokenSource();
|
|||
|
|
|
|||
|
|
private async Task ProcessDispatcherEx()
|
|||
|
|
{
|
|||
|
|
while (!_cts.Token.IsCancellationRequested)
|
|||
|
|
{
|
|||
|
|
if (workService.stationService_Dose.StationProp.deviceStatus != Entities.DeviceStatus.Runing)
|
|||
|
|
{
|
|||
|
|
await Task.Delay(2000);
|
|||
|
|
continue;
|
|||
|
|
}
|
|||
|
|
var hasAnyUsableBox = workService.ProjectPro.FixtureCacheArea
|
|||
|
|
.OfType<SampleBottleBoxModel>()
|
|||
|
|
.Where(b => b.FixtureType == BoxTypeEnum._12mL样品工装 || b.FixtureType == BoxTypeEnum._5mL样品工装)
|
|||
|
|
.Any(box => box.SampleBottleList.Any(bottle =>
|
|||
|
|
bottle.HaveBottle &&
|
|||
|
|
!bottle.bDoseFinish &&
|
|||
|
|
bottle.MaterialDoseFlowList.Count > 0));
|
|||
|
|
if (!hasAnyUsableBox)
|
|||
|
|
{
|
|||
|
|
await ChangeDeviceStatus(Entities.DeviceStatus.Idel);
|
|||
|
|
continue;
|
|||
|
|
}
|
|||
|
|
var FixtureCacheAreas = workService.ProjectPro.FixtureCacheArea.Where(b => b.FixtureType == BoxTypeEnum._12mL样品工装 || b.FixtureType == BoxTypeEnum._5mL样品工装).OrderBy(s => s.BoxId_inDosingStation).ToList();
|
|||
|
|
bool IsPowderInMachine = false; //加粉头是否在梅特勒称上
|
|||
|
|
bool IsMotherLiquidInMachine = false; //母液是否已经在母液开盖位
|
|||
|
|
for (int i = 0; i < FixtureCacheAreas.Count(); i++)
|
|||
|
|
{
|
|||
|
|
await TransferPlateformMoveTo(PlateformPos.GloveBox1, _cts.Token);
|
|||
|
|
if (StationProp.deviceStatus == Entities.DeviceStatus.Abort) break;
|
|||
|
|
var FixtureCacheArea = FixtureCacheAreas.ElementAt(i);
|
|||
|
|
SampleBottleBoxModel sampleBox = FixtureCacheArea as SampleBottleBoxModel;
|
|||
|
|
var samplebottles = sampleBox.SampleBottleList.Where(b => b.HaveBottle && !b.bDoseFinish && b.MaterialDoseFlowList.Count() > 0).OrderBy(b => b.PosId_InBox).ToList();
|
|||
|
|
|
|||
|
|
if (samplebottles.Count() > 0)
|
|||
|
|
{
|
|||
|
|
if (FixtureCacheArea.BoxId_inDosingStation == 4 || FixtureCacheArea.BoxId_inDosingStation == 8)
|
|||
|
|
{
|
|||
|
|
//干涉,先搬到前面一位
|
|||
|
|
await FourAxisTakeBox((int)BoxAreaEnum._托盘存放平台, FixtureCacheArea.FixtureType, (ushort)FixtureCacheArea.BoxId_inDosingStation, _cts.Token);
|
|||
|
|
await FourAxisPutBox((int)BoxAreaEnum._托盘存放平台, FixtureCacheArea.FixtureType, (ushort)(FixtureCacheArea.BoxId_inDosingStation - 1), _cts.Token);
|
|||
|
|
App.Current.Dispatcher.Invoke(() =>
|
|||
|
|
{
|
|||
|
|
FixtureCacheArea.BoxId_inDosingStation -= 1;
|
|||
|
|
workService.ProjectPro.FixtureCacheArea[FixtureCacheArea.BoxId_inDosingStation] = new BaseBottleBox()
|
|||
|
|
{
|
|||
|
|
IsEmpty = true,
|
|||
|
|
BoxId_inDoseDnload = FixtureCacheArea.BoxId_inDoseUpload,
|
|||
|
|
BoxId_inDoseUpload = FixtureCacheArea.BoxId_inDoseUpload,
|
|||
|
|
BoxId_inDosingStation = FixtureCacheArea.BoxId_inDosingStation + 1,
|
|||
|
|
IsDoseFinish = false,
|
|||
|
|
IsUseFinsh = false,
|
|||
|
|
BoxArea = BoxAreaEnum._托盘存放平台
|
|||
|
|
};
|
|||
|
|
workService.ProjectPro.FixtureCacheArea[FixtureCacheArea.BoxId_inDosingStation - 1] = FixtureCacheArea;
|
|||
|
|
});
|
|||
|
|
}
|
|||
|
|
for (int j = 0; j < samplebottles.Count(); j++)
|
|||
|
|
{
|
|||
|
|
if (StationProp.deviceStatus == Entities.DeviceStatus.Abort) break;
|
|||
|
|
var samplebottle = samplebottles.ElementAt(j);
|
|||
|
|
//查找下一个目标瓶,用来判断母液或者粉末头是否一样,一样则不搬回去
|
|||
|
|
SampleBottleModel samplebottleNext = null;
|
|||
|
|
if (j < samplebottles.Count() - 1)
|
|||
|
|
{
|
|||
|
|
samplebottleNext = samplebottles.ElementAt(j + 1);
|
|||
|
|
}
|
|||
|
|
else
|
|||
|
|
{
|
|||
|
|
if (i < FixtureCacheAreas.Count() - 1)
|
|||
|
|
{
|
|||
|
|
var nextFixtureCacheArea = FixtureCacheAreas.ElementAt(i + 1);
|
|||
|
|
SampleBottleBoxModel sampleBoxNext = nextFixtureCacheArea as SampleBottleBoxModel;
|
|||
|
|
var samplebottlesNext = sampleBoxNext.SampleBottleList.Where(b => b.HaveBottle && !b.bDoseFinish && b.MaterialDoseFlowList.Count() > 0).OrderBy(b => b.PosId_InBox);
|
|||
|
|
if (samplebottlesNext != null && samplebottlesNext.Any())
|
|||
|
|
{
|
|||
|
|
samplebottleNext = samplebottlesNext.FirstOrDefault();
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
var res = await MixForSampleBottle(samplebottle, sampleBox, IsPowderInMachine, IsMotherLiquidInMachine, samplebottleNext);
|
|||
|
|
IsPowderInMachine = res._isPowderInMachine;
|
|||
|
|
IsMotherLiquidInMachine = res._isMotherLiquidInMachine;
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
//搬运到转运区域,只能是1~3
|
|||
|
|
var aimTransferFixture = GetAvaliableTransferArea(1);
|
|||
|
|
if (aimTransferFixture != null) //&& !workService.ProjectPro.bNoUseBS
|
|||
|
|
{
|
|||
|
|
await TransferPlateformMoveTo(PlateformPos.GloveBox2, _cts.Token);
|
|||
|
|
await TransferFixtureFromCacheToTransfer(FixtureCacheArea, aimTransferFixture, _cts.Token); //搬运回物料区域 暂时屏蔽
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
WeakReferenceMessenger.Default.Send(new DesktopAlertMessage()
|
|||
|
|
{
|
|||
|
|
Header = $"提示",
|
|||
|
|
Content = $"工单已完成"
|
|||
|
|
});
|
|||
|
|
|
|||
|
|
#region 粉末取回演示使用
|
|||
|
|
if (false && !TestMode)
|
|||
|
|
{
|
|||
|
|
while (await ReadObstructFlag("四轴机械手运行中") || await ReadObstructFlag("四轴机械手正在使用传送平台"))
|
|||
|
|
{
|
|||
|
|
await Task.Delay(300);
|
|||
|
|
}
|
|||
|
|
await SetObstructFlag("四轴机械手运行中", true);
|
|||
|
|
await FourAxisTakePowderHeader((int)BoxAreaEnum._自动加样模块内, 1, 1, PowderBottleTypeEnum._16mL, _cts.Token);
|
|||
|
|
//Task task1 = labxService.MTPowderModuleControlStep(labxPowderInstrument.FirstOrDefault(), "Balance Step", "Balance Step", 0); //多余的
|
|||
|
|
await FourAxisPutPowderHeader((int)BoxAreaEnum._加样头存放平台, 1, 1, PowderBottleTypeEnum._16mL, _cts.Token);
|
|||
|
|
//await Task.WhenAll(task1, task2);
|
|||
|
|
await SetObstructFlag("四轴机械手运行中", false);
|
|||
|
|
IsPowderInMachine = false;
|
|||
|
|
}
|
|||
|
|
#endregion
|
|||
|
|
|
|||
|
|
await ChangeDeviceStatus(Entities.DeviceStatus.Finish);
|
|||
|
|
//if (workService.ProjectPro.bNoUseBS)
|
|||
|
|
//{
|
|||
|
|
// #region //todo:测试使用,后期一定要屏蔽
|
|||
|
|
// await ChangeDeviceStatus(Entities.DeviceStatus.CarryOn);
|
|||
|
|
// await TransferPlateformMoveTo( PlateformPos.TransferIn,_cts.Token);
|
|||
|
|
// await TransferPlateformMoveTo(PlateformPos.TransferOut, _cts.Token);
|
|||
|
|
// /*
|
|||
|
|
// try
|
|||
|
|
// {
|
|||
|
|
// var res = await SendJson(new Guid().ToString(), "test", "");
|
|||
|
|
// Logger.LogInformation($"向BS发送完成接收到-{res.Item2}");
|
|||
|
|
// }
|
|||
|
|
// catch (Exception ex)
|
|||
|
|
// {
|
|||
|
|
// MessageBox.Show(ex.Message);
|
|||
|
|
// }
|
|||
|
|
|
|||
|
|
// ProjectProperty project = new ProjectProperty();
|
|||
|
|
// bool readOk = false;
|
|||
|
|
// project = File_Operator.Xml_Serialize("C:\\Users\\CTOS\\Desktop\\empty.pro", false, project, out readOk);
|
|||
|
|
// if (readOk)
|
|||
|
|
// {
|
|||
|
|
// workService.ProjectPro = project;
|
|||
|
|
// workService.ProjectPro.LastOpenProject = "C:\\Users\\CTOS\\Desktop\\empty.pro";
|
|||
|
|
// workService.ProjectPro.NowOpenProjectFile = "C:\\Users\\CTOS\\Desktop\\empty.pro".Substring("C:\\Users\\CTOS\\Desktop\\empty.pro".LastIndexOf("\\") + 1).Trim();
|
|||
|
|
// //WeakReferenceMessenger.Default.Send(new DesktopAlertMessage { Content = "打开项目文件成功!" });
|
|||
|
|
// }
|
|||
|
|
// */
|
|||
|
|
// #endregion
|
|||
|
|
// await ChangeDeviceStatus(Entities.DeviceStatus.Idel);
|
|||
|
|
//}
|
|||
|
|
//else
|
|||
|
|
//{
|
|||
|
|
// await ChangeDeviceStatus(Entities.DeviceStatus.Finish);
|
|||
|
|
//}
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
//下料流程
|
|||
|
|
private async Task DownLoadDispatcherEx()
|
|||
|
|
{
|
|||
|
|
while (!_cts.Token.IsCancellationRequested)
|
|||
|
|
{
|
|||
|
|
if (workService.stationService_Dose.StationProp.deviceStatus != Entities.DeviceStatus.Finish)
|
|||
|
|
{
|
|||
|
|
await Task.Delay(2000);
|
|||
|
|
continue;
|
|||
|
|
}
|
|||
|
|
if (workService.ProjectPro.TransferArea.All(t => t.IsEmpty))
|
|||
|
|
{
|
|||
|
|
await ChangeDeviceStatus(Entities.DeviceStatus.Idel);
|
|||
|
|
continue;
|
|||
|
|
}
|
|||
|
|
await ChangeDeviceStatus(Entities.DeviceStatus.CarryOn);
|
|||
|
|
#region 搬目标、母液、tip、 粉头
|
|||
|
|
for (int i = 1; i <= 3; i++) //1~3是样品载具
|
|||
|
|
{
|
|||
|
|
if (workService.ProjectPro.TransferArea.Count < i) break;
|
|||
|
|
var transferArea = workService.ProjectPro.TransferArea[i - 1];
|
|||
|
|
if (!transferArea.IsEmpty) continue;
|
|||
|
|
|
|||
|
|
//寻找是否有样品载具待搬运
|
|||
|
|
var sampleFixture = workService.ProjectPro.FixtureCacheArea.FirstOrDefault(f => !f.IsEmpty && (f.FixtureType == BoxTypeEnum._12mL样品工装 || f.FixtureType == BoxTypeEnum._5mL样品工装));
|
|||
|
|
if (sampleFixture == null) break;
|
|||
|
|
await TransferPlateformMoveTo(PlateformPos.GloveBox2, _cts.Token);
|
|||
|
|
await TransferFixtureFromCacheToTransfer(sampleFixture, transferArea, _cts.Token);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
for (int i = 4; i <= 5; i++) //4~5是母液载具
|
|||
|
|
{
|
|||
|
|
if (workService.ProjectPro.TransferArea.Count < i) break;
|
|||
|
|
var transferArea = workService.ProjectPro.TransferArea[i - 1];
|
|||
|
|
if (!transferArea.IsEmpty) continue;
|
|||
|
|
|
|||
|
|
//寻找是否有母液载具待搬运
|
|||
|
|
var targetFixture = workService.ProjectPro.FixtureCacheArea.FirstOrDefault(f => !f.IsEmpty && (f.FixtureType == BoxTypeEnum._40mL原液工装));
|
|||
|
|
if (targetFixture == null) break;
|
|||
|
|
await TransferPlateformMoveTo(PlateformPos.GloveBox2, _cts.Token);
|
|||
|
|
await TransferFixtureFromCacheToTransfer(targetFixture, transferArea, _cts.Token);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
for (int i = 6; i <= 7; i++) //6~7是tip/粉末
|
|||
|
|
{
|
|||
|
|
if (workService.ProjectPro.TransferArea.Count < i) break;
|
|||
|
|
var transferArea = workService.ProjectPro.TransferArea[i - 1];
|
|||
|
|
if (!transferArea.IsEmpty && (transferArea.FixtureType == BoxTypeEnum._16mL粉末瓶工装 || transferArea.FixtureType == BoxTypeEnum._125mL粉末瓶工装) )
|
|||
|
|
{
|
|||
|
|
//找粉末放进去
|
|||
|
|
await TransferPlateformMoveTo(PlateformPos.GloveBox2, _cts.Token);
|
|||
|
|
await TransferPlateformMoveTo(PlateformPos.GloveBox1, _cts.Token);
|
|||
|
|
if (transferArea.FixtureType == BoxTypeEnum._16mL粉末瓶工装)
|
|||
|
|
{
|
|||
|
|
var samplePowderBox = transferArea as SourcePowderBottleBoxModel;
|
|||
|
|
for (int j = 0;j< samplePowderBox.SourcePowderBottleCollection.Count;j++)
|
|||
|
|
{
|
|||
|
|
var sourcePowderBottleHome = samplePowderBox.SourcePowderBottleCollection[j];
|
|||
|
|
if (!sourcePowderBottleHome.HaveBottle)
|
|||
|
|
{
|
|||
|
|
//搬运粉末头
|
|||
|
|
var powderHeader = workService.ProjectPro.PowderHeaderCacheArea.FirstOrDefault(p =>(p.PosId_InBox == j + 1) && p.BoxSNCode.Equals(samplePowderBox.BoxSNCode) && p.HaveBottle && p.PowderBottleType == sourcePowderBottleHome.PowderBottleType);
|
|||
|
|
if (powderHeader == null) break;
|
|||
|
|
|
|||
|
|
await FourAxisTakePowderHeader((int)BoxAreaEnum._加样头存放平台, 1, powderHeader.Pos_InDosePowderHC, powderHeader.PowderBottleType, _cts.Token,1);
|
|||
|
|
await FourAxisPutPowderHeader((int)BoxAreaEnum._手套箱传送平台, samplePowderBox.BoxId_inDoseUpload, sourcePowderBottleHome.PosId_InBox, powderHeader.PowderBottleType, _cts.Token,1);
|
|||
|
|
var newPowderBottle = File_Operator.DeepCopy(powderHeader);
|
|||
|
|
newPowderBottle.PosId_InBox = sourcePowderBottleHome.PosId_InBox;
|
|||
|
|
newPowderBottle.HaveBottle = true;
|
|||
|
|
App.Current.Dispatcher.Invoke(() =>
|
|||
|
|
{
|
|||
|
|
samplePowderBox.SourcePowderBottleCollection[j] = newPowderBottle;
|
|||
|
|
powderHeader.HaveBottle = false; powderHeader.SourcePowderName = ""; powderHeader.OriginWeight = powderHeader.RemainWeight = 0;
|
|||
|
|
});
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
else
|
|||
|
|
{
|
|||
|
|
var samplePowderBox = transferArea as SourcePowderBottleBoxModel_125ml;
|
|||
|
|
for (int j = 0; j < samplePowderBox.SourcePowderBottleCollection.Count; j++)
|
|||
|
|
{
|
|||
|
|
var sourcePowderBottleHome = samplePowderBox.SourcePowderBottleCollection[j];
|
|||
|
|
if (!sourcePowderBottleHome.HaveBottle)
|
|||
|
|
{
|
|||
|
|
//搬运粉末头
|
|||
|
|
var powderHeader = workService.ProjectPro.PowderHeaderCacheArea.FirstOrDefault(p => p.HaveBottle && p.PowderBottleType == sourcePowderBottleHome.PowderBottleType);
|
|||
|
|
if (powderHeader == null) break;
|
|||
|
|
|
|||
|
|
await FourAxisTakePowderHeader((int)BoxAreaEnum._加样头存放平台, 1, powderHeader.Pos_InDosePowderHC, powderHeader.PowderBottleType, _cts.Token, 1);
|
|||
|
|
await FourAxisPutPowderHeader((int)BoxAreaEnum._手套箱传送平台, samplePowderBox.BoxId_inDoseUpload, sourcePowderBottleHome.PosId_InBox, powderHeader.PowderBottleType, _cts.Token, 1);
|
|||
|
|
var newPowderBottle = File_Operator.DeepCopy(powderHeader);
|
|||
|
|
newPowderBottle.PosId_InBox = sourcePowderBottleHome.PosId_InBox;
|
|||
|
|
newPowderBottle.HaveBottle = true;
|
|||
|
|
App.Current.Dispatcher.Invoke(() =>
|
|||
|
|
{
|
|||
|
|
powderHeader.HaveBottle = false; powderHeader.SourcePowderName = ""; powderHeader.OriginWeight = powderHeader.RemainWeight = 0;
|
|||
|
|
samplePowderBox.SourcePowderBottleCollection[j] = newPowderBottle;
|
|||
|
|
});
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
else if (transferArea.IsEmpty)
|
|||
|
|
{
|
|||
|
|
//找tip放进去
|
|||
|
|
var targetFixture = workService.ProjectPro.TipHeadArea.FirstOrDefault(f => !f.IsEmpty);
|
|||
|
|
if (targetFixture == null) continue;
|
|||
|
|
await TransferPlateformMoveTo(PlateformPos.GloveBox2, _cts.Token);
|
|||
|
|
await TransferFixtureFromCacheToTransfer(targetFixture, transferArea, _cts.Token);
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
//await TransferPlateformMoveTo(PlateformPos.TransferIn, _cts.Token);
|
|||
|
|
await TransferPlateformMoveTo(PlateformPos.TransferOut, _cts.Token);
|
|||
|
|
//MessageBox.Show("通知AGV取料-需要判断是否需要空粉末治具及个数");
|
|||
|
|
//var testJson = new { test="1" };
|
|||
|
|
//var res = await SendJson((new Guid()).ToString(), "unload" , testJson.ToJson());
|
|||
|
|
#region 打包请求BS数据
|
|||
|
|
ToBsUnLoadData toBsUnLoadData = new ToBsUnLoadData()
|
|||
|
|
{
|
|||
|
|
SampleSeqs = new List<ToBsSampleSeq>(),
|
|||
|
|
Config = new ToBsConfig(),
|
|||
|
|
NeedFixture = new List<ToBsFixtureInfo>()
|
|||
|
|
};
|
|||
|
|
toBsUnLoadData.Config.BoxInfo = new List<ToBsBoxInfo>();
|
|||
|
|
for (int i = 0; i < 7; i++)
|
|||
|
|
{
|
|||
|
|
var transferArea = workService.ProjectPro.TransferArea[i];
|
|||
|
|
if (transferArea.IsEmpty) continue;
|
|||
|
|
ToBsBoxInfo boxInfo = new ToBsBoxInfo()
|
|||
|
|
{
|
|||
|
|
FixtureType = (int)transferArea.FixtureType,
|
|||
|
|
SnCode = transferArea.BoxSNCode,
|
|||
|
|
PosInUpload = transferArea.BoxId_inDoseUpload,
|
|||
|
|
Detail = new List<Detail>()
|
|||
|
|
};
|
|||
|
|
//如果是原液或者粉末需要将数据写入boxInfo.details,如果是5、12ml瓶子则写入toBsUnLoadData.SampleSeqs
|
|||
|
|
if (transferArea is TipBoxModel)
|
|||
|
|
{
|
|||
|
|
var tipBox = transferArea as TipBoxModel;
|
|||
|
|
boxInfo.RemainCount = tipBox.TipItems.Count(t => t.IsAvailable);
|
|||
|
|
}
|
|||
|
|
else if (transferArea is SourceLiquidBottleBoxModel)
|
|||
|
|
{
|
|||
|
|
var sourceBox = transferArea as SourceLiquidBottleBoxModel;
|
|||
|
|
var allBottles = sourceBox.SourceLiquidBottleCollection.Where(s => s.HaveBottle);
|
|||
|
|
foreach (var bottle in allBottles)
|
|||
|
|
{
|
|||
|
|
var detail = new Detail()
|
|||
|
|
{
|
|||
|
|
Code = bottle.SourceLiquidName,
|
|||
|
|
Pos = bottle.PosId_InBox.ToString(),
|
|||
|
|
RemainWeight = bottle.RemainVolume
|
|||
|
|
};
|
|||
|
|
boxInfo.Detail.Add(detail);
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
else if (transferArea is SourcePowderBottleBoxModel)
|
|||
|
|
{
|
|||
|
|
var sourceBox = transferArea as SourcePowderBottleBoxModel;
|
|||
|
|
var allBottles = sourceBox.SourcePowderBottleCollection.Where(s => s.HaveBottle);
|
|||
|
|
foreach (var bottle in allBottles)
|
|||
|
|
{
|
|||
|
|
var detail = new Detail()
|
|||
|
|
{
|
|||
|
|
Code = bottle.SourcePowderName,
|
|||
|
|
Pos = bottle.PosId_InBox.ToString(),
|
|||
|
|
RemainWeight = bottle.RemainWeight
|
|||
|
|
};
|
|||
|
|
boxInfo.Detail.Add(detail);
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
else if (transferArea is SourcePowderBottleBoxModel_125ml)
|
|||
|
|
{
|
|||
|
|
var sourceBox = transferArea as SourcePowderBottleBoxModel_125ml;
|
|||
|
|
var allBottles = sourceBox.SourcePowderBottleCollection.Where(s => s.HaveBottle);
|
|||
|
|
foreach (var bottle in allBottles)
|
|||
|
|
{
|
|||
|
|
var detail = new Detail()
|
|||
|
|
{
|
|||
|
|
Code = bottle.SourcePowderName,
|
|||
|
|
Pos = bottle.PosId_InBox.ToString(),
|
|||
|
|
RemainWeight = bottle.RemainWeight
|
|||
|
|
};
|
|||
|
|
boxInfo.Detail.Add(detail);
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
else if (transferArea is SampleBottleBoxModel)
|
|||
|
|
{
|
|||
|
|
var sourceBox = transferArea as SampleBottleBoxModel;
|
|||
|
|
var allBottles = sourceBox.SampleBottleList.Where(s => s.HaveBottle);
|
|||
|
|
foreach (var bottle in allBottles)
|
|||
|
|
{
|
|||
|
|
var sampleSeq = new ToBsSampleSeq()
|
|||
|
|
{
|
|||
|
|
Area = "A1",
|
|||
|
|
Carrier = transferArea.BoxId_inDoseUpload.ToString(),
|
|||
|
|
Code = bottle.SampleContentName,
|
|||
|
|
Pos = bottle.PosId_InBox.ToString(),
|
|||
|
|
SampleConfig = new ToBsSampleConfig(),
|
|||
|
|
OriginSeqIds = new List<long>() { bottle.SampleSeqId }
|
|||
|
|
};
|
|||
|
|
sampleSeq.SampleConfig.SnCode = transferArea.BoxSNCode;
|
|||
|
|
sampleSeq.SampleConfig.MaterialDoseFunctionFlow = new List<ToBsMaterialDoseFunctionFlow>();
|
|||
|
|
if (bottle.MaterialDoseFlowList != null && bottle.MaterialDoseFlowList.Count > 0)
|
|||
|
|
{
|
|||
|
|
foreach (var item in bottle.MaterialDoseFlowList)
|
|||
|
|
{
|
|||
|
|
ToBsMaterialDoseFunctionFlow sampleFunction = new ToBsMaterialDoseFunctionFlow()
|
|||
|
|
{
|
|||
|
|
FunctionFlowType = (int)item.FunctionFlowType,
|
|||
|
|
TargetVolumn = item.TargetVolume,
|
|||
|
|
UserMaterialName = item.UseMaterialName,
|
|||
|
|
RealVolumn = item.ActualVolume
|
|||
|
|
};
|
|||
|
|
sampleSeq.SampleConfig.MaterialDoseFunctionFlow.Add(sampleFunction);
|
|||
|
|
}
|
|||
|
|
toBsUnLoadData.SampleSeqs.Add(sampleSeq);
|
|||
|
|
}
|
|||
|
|
sampleSeq.SampleType = bottle.SampleBottleType == SampleBottleTypeEnum._5mL ? "5mL" : "12mL";
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
toBsUnLoadData.Config.BoxInfo.Add(boxInfo);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
var toBsFixtureInfo = new List<ToBsFixtureInfo>();
|
|||
|
|
var allPowderBottles = workService.ProjectPro.PowderHeaderCacheArea.Where(p => p.HaveBottle);
|
|||
|
|
List<int> remainTransferPos = new List<int>() { 6,7};
|
|||
|
|
foreach (var PowderBottle in allPowderBottles)
|
|||
|
|
{
|
|||
|
|
if (toBsFixtureInfo.All(s => !s.SnCode.Equals(PowderBottle.BoxSNCode)))
|
|||
|
|
{
|
|||
|
|
var pos = remainTransferPos.FirstOrDefault();
|
|||
|
|
if (pos != 6 && pos != 7) continue;
|
|||
|
|
remainTransferPos.Remove(pos);
|
|||
|
|
toBsFixtureInfo.Add(new ToBsFixtureInfo()
|
|||
|
|
{
|
|||
|
|
FixtureType = PowderBottle.PowderBottleType == PowderBottleTypeEnum._16mL ? (int)BoxTypeEnum._16mL粉末瓶工装 : (int)BoxTypeEnum._125mL粉末瓶工装,
|
|||
|
|
BoxIdInDoseUpload = pos,
|
|||
|
|
SnCode = PowderBottle.BoxSNCode
|
|||
|
|
});
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
toBsUnLoadData.NeedFixture = toBsFixtureInfo;
|
|||
|
|
if (toBsUnLoadData.NeedFixture.Count > 0)
|
|||
|
|
{
|
|||
|
|
WeakReferenceMessenger.Default.Send(new DesktopAlertMessage()
|
|||
|
|
{
|
|||
|
|
Header = "提示",
|
|||
|
|
Content = $"向BS请求治具{JsonConvert.SerializeObject(toBsUnLoadData.NeedFixture)}"
|
|||
|
|
});
|
|||
|
|
}
|
|||
|
|
#endregion
|
|||
|
|
if (!workService.ProjectPro.bNoUseBS)
|
|||
|
|
{
|
|||
|
|
var res = await SendJson((new Guid()).ToString(), "unload", toBsUnLoadData.ToJson());
|
|||
|
|
while (!res.Item1)
|
|||
|
|
{
|
|||
|
|
WeakReferenceMessenger.Default.Send(new DesktopAlertMessage() { Header = "提示", Content = "调用BS-unload方法失败" });
|
|||
|
|
await Task.Delay(1000);
|
|||
|
|
res = await SendJson((new Guid()).ToString(), "unload", toBsUnLoadData.ToJson());
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
else
|
|||
|
|
{
|
|||
|
|
//todo:不启用bs给出个弹窗,拿完之后清空传递仓数据,并将状态置为Finish
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
#endregion
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/// <summary>
|
|||
|
|
/// 返回转移区域的空位置
|
|||
|
|
/// </summary>
|
|||
|
|
/// <param name="type">1表示目标瓶在1-3找,2表示原液瓶在4-5找,3表示tip载具4表示粉末载具在6-7找</param>
|
|||
|
|
private BaseBottleBox GetAvaliableTransferArea(int type)
|
|||
|
|
{
|
|||
|
|
BaseBottleBox baseBottleBox = null;
|
|||
|
|
int startIndex = 0;
|
|||
|
|
int endIndex = 0;
|
|||
|
|
switch (type)
|
|||
|
|
{
|
|||
|
|
case 1: //目标瓶在1-3
|
|||
|
|
startIndex = 0; endIndex = 3;
|
|||
|
|
break;
|
|||
|
|
case 2: //原液瓶载具在4-5
|
|||
|
|
startIndex = 3; endIndex = 5;
|
|||
|
|
break;
|
|||
|
|
case 3: //tip
|
|||
|
|
case 4: //粉末在6-7
|
|||
|
|
startIndex = 5; endIndex = 7;
|
|||
|
|
break;
|
|||
|
|
default:
|
|||
|
|
break;
|
|||
|
|
}
|
|||
|
|
for (int i = startIndex; i < endIndex; i++)
|
|||
|
|
{
|
|||
|
|
if (workService.ProjectPro.TransferArea[i].IsEmpty)
|
|||
|
|
{
|
|||
|
|
baseBottleBox = workService.ProjectPro.TransferArea[i];
|
|||
|
|
break;
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
return baseBottleBox;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
private async Task<bool> TransferFixtureFromPowderCacheToTransfer(SourcePowderBottleModel sourcePowderBottleModel, CancellationToken token)
|
|||
|
|
{
|
|||
|
|
var fixture = sourcePowderBottleModel.PowderBottleType == PowderBottleTypeEnum._16mL ? BoxTypeEnum._16mL粉末瓶工装 : BoxTypeEnum._125mL粉末瓶工装;
|
|||
|
|
var powderFixtures = workService.ProjectPro.TransferArea.Where(f => !f.IsEmpty && f.FixtureType == fixture);
|
|||
|
|
|
|||
|
|
SourcePowderBottleBoxModel powderBox = null;
|
|||
|
|
SourcePowderBottleBoxModel_125ml powderBox_125 = null;
|
|||
|
|
BaseBottleBox powderFixture1 = null;
|
|||
|
|
foreach (var powderFixture in powderFixtures)
|
|||
|
|
{
|
|||
|
|
if (powderFixture is SourcePowderBottleBoxModel)
|
|||
|
|
{
|
|||
|
|
powderBox = powderFixture as SourcePowderBottleBoxModel;
|
|||
|
|
if (powderBox.SourcePowderBottleCollection.Any(s => !s.HaveBottle)) break;
|
|||
|
|
}
|
|||
|
|
else if (powderFixture is SourcePowderBottleBoxModel_125ml)
|
|||
|
|
{
|
|||
|
|
powderBox_125 = powderFixture as SourcePowderBottleBoxModel_125ml;
|
|||
|
|
if (powderBox_125.SourcePowderBottleCollection.Any(s => !s.HaveBottle)) break;
|
|||
|
|
}
|
|||
|
|
powderFixture1 = powderFixture;
|
|||
|
|
}
|
|||
|
|
if (powderBox.SourcePowderBottleCollection.All(s => s.HaveBottle) && powderBox_125.SourcePowderBottleCollection.All(s => s.HaveBottle)) return false;
|
|||
|
|
|
|||
|
|
int powderTransferIndex = workService.ProjectPro.TransferArea.IndexOf(powderFixture1);//治具位置
|
|||
|
|
int sourceIndex = workService.ProjectPro.PowderHeaderCacheArea.IndexOf(sourcePowderBottleModel); //缓存位置位置
|
|||
|
|
if (powderBox != null)
|
|||
|
|
{
|
|||
|
|
var aimPowderBottle = powderBox.SourcePowderBottleCollection.First(s => !s.HaveBottle); //目标位置
|
|||
|
|
await FourAxisTakePowderHeader((int)BoxAreaEnum._加样头存放平台, 1, sourceIndex, powderBox.PowderBottleType, token);
|
|||
|
|
await FourAxisPutPowderHeader((int)BoxAreaEnum._手套箱传送平台, powderFixture1.BoxId_inDoseUpload, aimPowderBottle.PosId_InBox, powderBox.PowderBottleType, token);
|
|||
|
|
var newPowderBottle = File_Operator.DeepCopy(sourcePowderBottleModel);
|
|||
|
|
newPowderBottle.HaveBottle = true;
|
|||
|
|
newPowderBottle.Pos_InDosePowderHC = aimPowderBottle.Pos_InDosePowderHC;
|
|||
|
|
powderBox.SourcePowderBottleCollection[aimPowderBottle.PosId_InBox - 1] = newPowderBottle;
|
|||
|
|
workService.ProjectPro.PowderHeaderCacheArea[sourceIndex - 1] = new SourcePowderBottleModel()
|
|||
|
|
{
|
|||
|
|
HaveBottle = false
|
|||
|
|
};
|
|||
|
|
}
|
|||
|
|
else if (powderBox_125 != null)
|
|||
|
|
{
|
|||
|
|
var aimPowderBottle = powderBox_125.SourcePowderBottleCollection.First(s => !s.HaveBottle); //目标位置
|
|||
|
|
await FourAxisTakePowderHeader((int)BoxAreaEnum._加样头存放平台, 1, sourceIndex, powderBox_125.PowderBottleType, token);
|
|||
|
|
await FourAxisPutPowderHeader((int)BoxAreaEnum._手套箱传送平台, powderFixture1.BoxId_inDoseUpload, aimPowderBottle.PosId_InBox, powderBox_125.PowderBottleType, token);
|
|||
|
|
// 更新粉末缓存区(替换集合元素)
|
|||
|
|
var newPowderBottle = File_Operator.DeepCopy(sourcePowderBottleModel);
|
|||
|
|
newPowderBottle.HaveBottle = true;
|
|||
|
|
newPowderBottle.Pos_InDosePowderHC = aimPowderBottle.Pos_InDosePowderHC;
|
|||
|
|
powderBox_125.SourcePowderBottleCollection[aimPowderBottle.PosId_InBox - 1] = newPowderBottle;
|
|||
|
|
workService.ProjectPro.PowderHeaderCacheArea[sourceIndex - 1] = new SourcePowderBottleModel()
|
|||
|
|
{
|
|||
|
|
HaveBottle = false
|
|||
|
|
};
|
|||
|
|
}
|
|||
|
|
return true;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/// <summary>
|
|||
|
|
/// 搬运治具从tip缓存位到搬运位
|
|||
|
|
/// </summary>
|
|||
|
|
/// <param name="fixture"></param>
|
|||
|
|
/// <returns></returns>
|
|||
|
|
private async Task<bool> TransferFixtureFromTipCacheToTransfer(TipBoxModel FixtureCacheArea, CancellationToken token)
|
|||
|
|
{
|
|||
|
|
var aimFixture = workService.ProjectPro.TransferArea.OrderBy(a => a.BoxId_inDosingStation).First(f => f.IsEmpty);
|
|||
|
|
if (aimFixture is null)
|
|||
|
|
{
|
|||
|
|
return false;
|
|||
|
|
}
|
|||
|
|
int aimFixtureIndex = workService.ProjectPro.TransferArea.IndexOf(aimFixture);
|
|||
|
|
await FourAxisTakeBox((int)BoxAreaEnum._Tip托盘存放平台, FixtureCacheArea.FixtureType, (ushort)FixtureCacheArea.BoxId_inDosingStation, _cts.Token);
|
|||
|
|
await FourAxisPutBox((int)BoxAreaEnum._手套箱传送平台, aimFixture.FixtureType, (ushort)aimFixture.BoxId_inDosingStation, _cts.Token);
|
|||
|
|
var newCacheFixture = File_Operator.DeepCopy(FixtureCacheArea);
|
|||
|
|
newCacheFixture.BoxId_inDosingStation = aimFixture.BoxId_inDosingStation;
|
|||
|
|
newCacheFixture.IsDoseFinish = true;
|
|||
|
|
newCacheFixture.IsEmpty = false;
|
|||
|
|
newCacheFixture.IsUseFinsh = true;
|
|||
|
|
try
|
|||
|
|
{
|
|||
|
|
App.Current.Dispatcher.Invoke(() =>
|
|||
|
|
{
|
|||
|
|
workService.ProjectPro.TransferArea[aimFixtureIndex] = newCacheFixture;
|
|||
|
|
workService.ProjectPro.TipHeadArea[FixtureCacheArea.BoxId_inDosingStation - 1] = new TipBoxModel()
|
|||
|
|
{
|
|||
|
|
IsEmpty = true,
|
|||
|
|
BoxId_inDoseDnload = FixtureCacheArea.BoxId_inDoseUpload,
|
|||
|
|
BoxId_inDoseUpload = FixtureCacheArea.BoxId_inDoseUpload,
|
|||
|
|
IsDoseFinish = false,
|
|||
|
|
IsUseFinsh = false,
|
|||
|
|
BoxArea = BoxAreaEnum._手套箱传送平台
|
|||
|
|
};
|
|||
|
|
});
|
|||
|
|
}
|
|||
|
|
catch (Exception ex)
|
|||
|
|
{
|
|||
|
|
MessageBox.Show(ex.Message);
|
|||
|
|
}
|
|||
|
|
return true;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/// <summary>
|
|||
|
|
/// 搬运治具从缓存位到搬运位
|
|||
|
|
/// </summary>
|
|||
|
|
/// <param name="fixture"></param>
|
|||
|
|
/// <returns></returns>
|
|||
|
|
private async Task<bool> TransferFixtureFromCacheToTransfer(BaseBottleBox FixtureCacheArea, BaseBottleBox aimFixture, CancellationToken token)
|
|||
|
|
{
|
|||
|
|
//var aimFixture = workService.ProjectPro.TransferArea.OrderBy(a => a.BoxId_inDosingStation).First(f => f.IsEmpty);
|
|||
|
|
if (aimFixture is null)
|
|||
|
|
{
|
|||
|
|
return false;
|
|||
|
|
}
|
|||
|
|
var aimFixtureIndex = workService.ProjectPro.TransferArea.IndexOf(aimFixture);
|
|||
|
|
if (FixtureCacheArea is TipBoxModel)
|
|||
|
|
{
|
|||
|
|
var fixtnew = FixtureCacheArea as TipBoxModel;
|
|||
|
|
var pos = (ushort)fixtnew.BoxId_inDosingStation;
|
|||
|
|
pos = (ushort)(3 - pos + 1);
|
|||
|
|
await FourAxisTakeBox((ushort)BoxAreaEnum._Tip托盘存放平台, fixtnew.FixtureType, (ushort)pos, _cts.Token);
|
|||
|
|
await FourAxisPutBox((int)BoxAreaEnum._手套箱传送平台, fixtnew.FixtureType, (ushort)aimFixture.BoxId_inDoseUpload, _cts.Token);
|
|||
|
|
}
|
|||
|
|
else
|
|||
|
|
{
|
|||
|
|
await FourAxisTakeBox((ushort)BoxAreaEnum._托盘存放平台, FixtureCacheArea.FixtureType, (ushort)FixtureCacheArea.BoxId_inDosingStation, _cts.Token);
|
|||
|
|
await FourAxisPutBox((int)BoxAreaEnum._手套箱传送平台, FixtureCacheArea.FixtureType, (ushort)aimFixture.BoxId_inDoseUpload, _cts.Token);
|
|||
|
|
}
|
|||
|
|
var newCacheFixture = File_Operator.DeepCopy(FixtureCacheArea);
|
|||
|
|
newCacheFixture.BoxId_inDoseUpload = aimFixture.BoxId_inDoseUpload;
|
|||
|
|
newCacheFixture.BoxId_inDosingStation = aimFixture.BoxId_inDosingStation;
|
|||
|
|
newCacheFixture.IsDoseFinish = true;
|
|||
|
|
newCacheFixture.IsEmpty = false;
|
|||
|
|
newCacheFixture.IsUseFinsh = true;
|
|||
|
|
try
|
|||
|
|
{
|
|||
|
|
App.Current.Dispatcher.Invoke(() =>
|
|||
|
|
{
|
|||
|
|
workService.ProjectPro.TransferArea[aimFixtureIndex] = newCacheFixture;
|
|||
|
|
if (FixtureCacheArea.BoxArea == BoxAreaEnum._托盘存放平台)
|
|||
|
|
{
|
|||
|
|
workService.ProjectPro.FixtureCacheArea[FixtureCacheArea.BoxId_inDosingStation - 1] = new BaseBottleBox()
|
|||
|
|
{
|
|||
|
|
IsEmpty = true,
|
|||
|
|
BoxId_inDoseDnload = FixtureCacheArea.BoxId_inDoseUpload,
|
|||
|
|
BoxId_inDoseUpload = FixtureCacheArea.BoxId_inDoseUpload,
|
|||
|
|
BoxId_inDosingStation = FixtureCacheArea.BoxId_inDosingStation,
|
|||
|
|
IsDoseFinish = false,
|
|||
|
|
IsUseFinsh = false,
|
|||
|
|
BoxArea = BoxAreaEnum._托盘存放平台
|
|||
|
|
};
|
|||
|
|
}
|
|||
|
|
else if (FixtureCacheArea.BoxArea == BoxAreaEnum._Tip托盘存放平台)
|
|||
|
|
{
|
|||
|
|
var fixTipModel = FixtureCacheArea as TipBoxModel;
|
|||
|
|
var tipBox = new TipBoxModel()
|
|||
|
|
{
|
|||
|
|
IsEmpty = true,
|
|||
|
|
BoxId_inDosingStation = fixTipModel.BoxId_inDosingStation,
|
|||
|
|
BoxArea = BoxAreaEnum._Tip托盘存放平台,
|
|||
|
|
FixtureType = fixTipModel.FixtureType, HaveBox = false, UseIndex = 96,
|
|||
|
|
TipItems = new ObservableCollection<TipHeadItem>()
|
|||
|
|
};
|
|||
|
|
for (int i = 0; i < 96; i++)
|
|||
|
|
{
|
|||
|
|
tipBox.TipItems.Add(new TipHeadItem() { IsAvailable = false, UseIndex = i + 1});
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
workService.ProjectPro.TipHeadArea[fixTipModel.BoxId_inDosingStation - 1] = tipBox;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
});
|
|||
|
|
}
|
|||
|
|
catch (Exception ex)
|
|||
|
|
{
|
|||
|
|
MessageBox.Show(ex.Message);
|
|||
|
|
}
|
|||
|
|
return true;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
public async Task TransferPlateformMoveTo(PlateformPos plateformPos, CancellationToken token)
|
|||
|
|
{
|
|||
|
|
if (token.IsCancellationRequested || TestMode) return;
|
|||
|
|
var _modbusClient_Plc1 = this.CoreService.GetServiceInstance<IModbusClientExtend>(DeviceNames.Plc1.ToString());
|
|||
|
|
|
|||
|
|
var transferPlatePos = await ReadScannedValueAsync_FourAxis(PlcPoints_MaterialDose.R_TransferPlate_BoxPos);
|
|||
|
|
if (transferPlatePos > 0 && transferPlatePos < 5) //需要先读取当前的位置,如果当前位置是
|
|||
|
|
{
|
|||
|
|
PlateformPos currentPos = PlateformPos.TransferOut;
|
|||
|
|
//1:外面 2:里面 3:加粉头 4:载具位置
|
|||
|
|
switch (transferPlatePos)
|
|||
|
|
{
|
|||
|
|
case 1:
|
|||
|
|
currentPos = PlateformPos.TransferOut;
|
|||
|
|
break;
|
|||
|
|
case 2:
|
|||
|
|
currentPos = PlateformPos.TransferIn;
|
|||
|
|
break;
|
|||
|
|
case 3:
|
|||
|
|
currentPos = PlateformPos.GloveBox1;
|
|||
|
|
break;
|
|||
|
|
case 4:
|
|||
|
|
currentPos = PlateformPos.GloveBox2;
|
|||
|
|
break;
|
|||
|
|
default:
|
|||
|
|
break;
|
|||
|
|
}
|
|||
|
|
if ((plateformPos == PlateformPos.TransferOut && (currentPos == PlateformPos.GloveBox1 || currentPos == PlateformPos.GloveBox2))
|
|||
|
|
|| (currentPos == PlateformPos.TransferOut && (plateformPos == PlateformPos.GloveBox1 || plateformPos == PlateformPos.GloveBox2))
|
|||
|
|
)
|
|||
|
|
{
|
|||
|
|
//目标是过渡舱外面,且当前是过渡舱内部 或者当前是过渡舱外面,且目标是过渡舱内部 需要先将过渡舱到舱内
|
|||
|
|
_modbusClient_Plc1.Command.WriteValue<ushort>(PlcPoints_MaterialDose.W_TransferPlate_TaskNo, (ushort)PlateformPos.TransferIn);
|
|||
|
|
await WaitForActionFinishAsync_FourAxis(PlcPoints_MaterialDose.R_TransferPlate_RunResult, 22, token);
|
|||
|
|
_modbusClient_Plc1.Command.WriteValue<ushort>(PlcPoints_MaterialDose.W_TransferPlate_TaskNo, 0);
|
|||
|
|
await WaitForActionFinishAsync_FourAxis(PlcPoints_MaterialDose.R_TransferPlate_RunResult, 5, token);
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
transferPlatePos = await ReadScannedValueAsync_FourAxis(PlcPoints_MaterialDose.R_TransferPlate_BoxPos);
|
|||
|
|
if (transferPlatePos > 0 && transferPlatePos < 5)
|
|||
|
|
{
|
|||
|
|
PlateformPos currentPos = PlateformPos.TransferOut;
|
|||
|
|
switch (transferPlatePos)
|
|||
|
|
{
|
|||
|
|
case 1:
|
|||
|
|
currentPos = PlateformPos.TransferOut;
|
|||
|
|
break;
|
|||
|
|
case 2:
|
|||
|
|
currentPos = PlateformPos.TransferIn;
|
|||
|
|
break;
|
|||
|
|
case 3:
|
|||
|
|
currentPos = PlateformPos.GloveBox1;
|
|||
|
|
break;
|
|||
|
|
case 4:
|
|||
|
|
currentPos = PlateformPos.GloveBox2;
|
|||
|
|
break;
|
|||
|
|
default:
|
|||
|
|
break;
|
|||
|
|
}
|
|||
|
|
if (currentPos != PlateformPos.GloveBox1 && currentPos != PlateformPos.GloveBox2 && plateformPos == PlateformPos.GloveBox1)
|
|||
|
|
{
|
|||
|
|
//目标是粉末位置,当前位置如果
|
|||
|
|
_modbusClient_Plc1.Command.WriteValue<ushort>(PlcPoints_MaterialDose.W_TransferPlate_TaskNo, (ushort)PlateformPos.GloveBox2);
|
|||
|
|
await WaitForActionFinishAsync_FourAxis(PlcPoints_MaterialDose.R_TransferPlate_RunResult, 22, token);
|
|||
|
|
_modbusClient_Plc1.Command.WriteValue<ushort>(PlcPoints_MaterialDose.W_TransferPlate_TaskNo, 0);
|
|||
|
|
await WaitForActionFinishAsync_FourAxis(PlcPoints_MaterialDose.R_TransferPlate_RunResult, 5, token);
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
_modbusClient_Plc1.Command.WriteValue<ushort>(PlcPoints_MaterialDose.W_TransferPlate_TaskNo, (ushort)plateformPos);
|
|||
|
|
await WaitForActionFinishAsync_FourAxis(PlcPoints_MaterialDose.R_TransferPlate_RunResult, 22, token);
|
|||
|
|
_modbusClient_Plc1.Command.WriteValue<ushort>(PlcPoints_MaterialDose.W_TransferPlate_TaskNo, 0);
|
|||
|
|
await WaitForActionFinishAsync_FourAxis(PlcPoints_MaterialDose.R_TransferPlate_RunResult, 5, token);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
public async Task WriteCmdToPlc(string cmd)
|
|||
|
|
{
|
|||
|
|
ushort plcAddress = 0;
|
|||
|
|
ushort value = 1;
|
|||
|
|
bool needReset = true; //是否需要200ms复位
|
|||
|
|
bool needMaunalMode = false; //是否需要自动
|
|||
|
|
bool needChangeMode = false;
|
|||
|
|
switch (cmd)
|
|||
|
|
{
|
|||
|
|
case "start":
|
|||
|
|
plcAddress = PlcPoints_MaterialDose.W_PCRunStatus;
|
|||
|
|
needChangeMode = true;
|
|||
|
|
value = 2;
|
|||
|
|
break;
|
|||
|
|
case "pause":
|
|||
|
|
plcAddress = PlcPoints_MaterialDose.W_PCRunStatus;
|
|||
|
|
value = 1; //1:停止中,2:运行中
|
|||
|
|
break;
|
|||
|
|
case "reset":
|
|||
|
|
plcAddress = PlcPoints_MaterialDose.W_InformationConfirm;
|
|||
|
|
value = 1;
|
|||
|
|
break;
|
|||
|
|
case "init":
|
|||
|
|
plcAddress = PlcPoints_MaterialDose.W_Initial;
|
|||
|
|
value = 1; needMaunalMode = true;
|
|||
|
|
break;
|
|||
|
|
default:
|
|||
|
|
break;
|
|||
|
|
}
|
|||
|
|
if (plcAddress != 0 && !TestMode)
|
|||
|
|
{
|
|||
|
|
if (needChangeMode)
|
|||
|
|
{
|
|||
|
|
ushort plcMode = needMaunalMode ? (ushort)1 : (ushort)2; //1切成手动 2切成自动
|
|||
|
|
await WriteCommandAsync_FourAxis(PlcPoints_MaterialDose.W_PCMode, plcMode);
|
|||
|
|
await Task.Delay(200);
|
|||
|
|
await WriteCommandAsync_FourAxis(PlcPoints_MaterialDose.W_PCMode, 0);
|
|||
|
|
await Task.Delay(200);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
await WriteCommandAsync_FourAxis(plcAddress, value);
|
|||
|
|
if (needReset)
|
|||
|
|
{
|
|||
|
|
await Task.Delay(1000);
|
|||
|
|
await WriteCommandAsync_FourAxis(plcAddress, 0);
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
private int GetBottleId(SampleBottleTypeEnum sampleType)
|
|||
|
|
{
|
|||
|
|
int res = 3;
|
|||
|
|
switch (sampleType)
|
|||
|
|
{
|
|||
|
|
case SampleBottleTypeEnum._5mL:
|
|||
|
|
res = 3;
|
|||
|
|
break;
|
|||
|
|
case SampleBottleTypeEnum._12mL:
|
|||
|
|
res = 2;
|
|||
|
|
break;
|
|||
|
|
default:
|
|||
|
|
break;
|
|||
|
|
}
|
|||
|
|
return res;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/// <summary>
|
|||
|
|
/// 目标瓶一次加完全部的需要的液体及固体
|
|||
|
|
/// </summary>
|
|||
|
|
/// <param name="sampleBottle"></param>
|
|||
|
|
/// <param name="sampleBox"></param>
|
|||
|
|
/// <returns></returns>
|
|||
|
|
private async Task<(bool _isPowderInMachine,bool _isMotherLiquidInMachine)> MixForSampleBottle(SampleBottleModel sampleBottle, SampleBottleBoxModel sampleBox,bool IsPowderInMachine, bool IsMotherLiquidInMachine, SampleBottleModel samplebottleNext = null)
|
|||
|
|
{
|
|||
|
|
#region 搬运目标瓶到目标区域开盖
|
|||
|
|
await SetObstructFlag("四轴机械手运行中", true);
|
|||
|
|
await FourAxisTakeSampleBottle(_cts.Token, (int)BoxAreaEnum._托盘存放平台, sampleBox.BoxId_inDosingStation, sampleBottle.PosId_InBox, sampleBottle);
|
|||
|
|
if (string.IsNullOrEmpty(sampleBottle.SNCode))
|
|||
|
|
{
|
|||
|
|
await FourAxisGoToScannPos_liquid(_cts.Token, GetBottleId(sampleBottle.SampleBottleType), null, sampleBottle);
|
|||
|
|
if (TestMode) sampleBottle.SNCode = DateTime.Now.ToString();
|
|||
|
|
}
|
|||
|
|
await FourAxisPutSampleBottle(_cts.Token, (int)BoxAreaEnum._开关盖区域, 0, 0, sampleBottle);
|
|||
|
|
await SetObstructFlag("四轴机械手运行中", false);
|
|||
|
|
await OpenBottleLid(_cts.Token, null, sampleBottle);
|
|||
|
|
if (!TestMode)
|
|||
|
|
{
|
|||
|
|
while (await ReadObstructFlag("四轴机械手运行中") || await ReadObstructFlag("四轴机械手正在使用传送平台"))
|
|||
|
|
{
|
|||
|
|
await Task.Delay(300);
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
//固定加一个粉末,演示使用,0317粉末载具搬运干涉,客户想看只能固定1号位置加16ml的演示了
|
|||
|
|
if (false && !TestMode)
|
|||
|
|
{
|
|||
|
|
#region 搬运粉末加样头去梅特勒称上
|
|||
|
|
SourcePowderBottleModel powderBottle = new SourcePowderBottleModel()
|
|||
|
|
{
|
|||
|
|
Pos_InDosePowderHC = 1,
|
|||
|
|
PowderBottleType = PowderBottleTypeEnum._16mL
|
|||
|
|
};
|
|||
|
|
if (!IsPowderInMachine)
|
|||
|
|
{
|
|||
|
|
if (!TestMode)
|
|||
|
|
{
|
|||
|
|
while (await ReadObstructFlag("四轴机械手运行中") || await ReadObstructFlag("四轴机械手正在使用传送平台"))
|
|||
|
|
{
|
|||
|
|
await Task.Delay(300);
|
|||
|
|
}
|
|||
|
|
await SetObstructFlag("四轴机械手运行中", true);
|
|||
|
|
//四轴机械手取粉末加样头 放到称重模块中
|
|||
|
|
await FourAxisTakePowderHeader((int)BoxAreaEnum._加样头存放平台, 1, powderBottle.Pos_InDosePowderHC, powderBottle.PowderBottleType, _cts.Token);
|
|||
|
|
//将粉末头放到梅特勒称重模块中
|
|||
|
|
labxPowderInstrument = await labxService.GetInstruments("自动天平XPR105");
|
|||
|
|
await labxService.StartWaitingForHead(labxPowderInstrument.FirstOrDefault(), "Dosing Head", "Dosing Head");
|
|||
|
|
await FourAxisPutPowderHeader((int)BoxAreaEnum._自动加样模块内, 1, 1, powderBottle.PowderBottleType, _cts.Token);
|
|||
|
|
await SetObstructFlag("四轴机械手运行中", false);
|
|||
|
|
await labxService.AbortWaitingForHead();
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
IsPowderInMachine = true;
|
|||
|
|
#endregion
|
|||
|
|
|
|||
|
|
#region 目标瓶从开盖位去称重位
|
|||
|
|
while (await ReadObstructFlag("四轴机械手运行中") || await ReadObstructFlag("四轴机械手正在使用传送平台"))
|
|||
|
|
{
|
|||
|
|
await Task.Delay(300);
|
|||
|
|
}
|
|||
|
|
await SetObstructFlag("四轴机械手运行中", true);
|
|||
|
|
var task1 = FourAxisTakeSampleBottle(_cts.Token, (int)BoxAreaEnum._开关盖区域, 0, 0, sampleBottle);
|
|||
|
|
var task2 = labxService.MTPowderModuleControlStep(labxPowderInstrument.FirstOrDefault(), "Balance Step", "Balance Step", 1);//开门
|
|||
|
|
await Task.WhenAll(task1, task2);
|
|||
|
|
await FourAxisPutSampleBottle(_cts.Token, (int)BoxAreaEnum._自动加样模块内, 1, 1, sampleBottle);
|
|||
|
|
await SetObstructFlag("四轴机械手运行中", false);
|
|||
|
|
#endregion
|
|||
|
|
|
|||
|
|
#region 加粉末
|
|||
|
|
//梅特勒模块关门
|
|||
|
|
await labxService.MTPowderModuleControlStep(labxPowderInstrument.FirstOrDefault(), "Balance Step", "Balance Step", 0);
|
|||
|
|
double addPowderWeight = 0;
|
|||
|
|
//大99,小125 2~200mg +-0.297mg 200mg-5g 0.297%
|
|||
|
|
decimal dosHeight = sampleBottle.SampleBottleType == SampleBottleTypeEnum._12mL ? 99m : 125m;
|
|||
|
|
double TargetVolume = 30;
|
|||
|
|
decimal upT = Math.Round(TargetVolume < 200 ? (decimal)(0.297 / TargetVolume * 100) : 0.297m,13);
|
|||
|
|
Logger.LogInformation($"请求加样的粉末数量-{TargetVolume},上下限为{upT}");
|
|||
|
|
addPowderWeight = await labxService.MTPowderModuleAddPowder(labxPowderInstrument.FirstOrDefault(), "Dosing2", "Dosing2", 4, dosHeight, (decimal)TargetVolume, (decimal)upT, (decimal)upT);
|
|||
|
|
//梅特勒模块开门
|
|||
|
|
//await labxService.MTPowderModuleControlStep(labxPowderInstrument.FirstOrDefault(), "Balance Step", "Balance Step", 1);
|
|||
|
|
#endregion
|
|||
|
|
|
|||
|
|
#region 目标瓶放回开盖位
|
|||
|
|
while (await ReadObstructFlag("四轴机械手运行中") || await ReadObstructFlag("四轴机械手正在使用传送平台"))
|
|||
|
|
{
|
|||
|
|
await Task.Delay(300);
|
|||
|
|
}
|
|||
|
|
await SetObstructFlag("四轴机械手运行中", true);
|
|||
|
|
await labxService.MTPowderModuleControlStep(labxPowderInstrument.FirstOrDefault(), "Balance Step", "Balance Step", 1);//开门
|
|||
|
|
await FourAxisTakeSampleBottle(_cts.Token, (int)BoxAreaEnum._自动加样模块内, 1, 1, sampleBottle);
|
|||
|
|
Task task11 = labxService.MTPowderModuleControlStep(labxPowderInstrument.FirstOrDefault(), "Balance Step", "Balance Step", 0); //关门
|
|||
|
|
Task task22 = FourAxisPutSampleBottle(_cts.Token, (int)BoxAreaEnum._开关盖区域, 0, 0, sampleBottle);
|
|||
|
|
await Task.WhenAll(task11, task22);
|
|||
|
|
await SetObstructFlag("四轴机械手运行中", false);
|
|||
|
|
#endregion
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
#endregion
|
|||
|
|
|
|||
|
|
bool SampleHasOpened = false;
|
|||
|
|
for (int i = 0; i < sampleBottle.MaterialDoseFlowList.Count; i++)
|
|||
|
|
{
|
|||
|
|
var addSample = sampleBottle.MaterialDoseFlowList[i];
|
|||
|
|
if (addSample.FunctionFlowType!= FunctionTypeEnum.震荡摇匀 && (string.IsNullOrEmpty(addSample.UseMaterialName) || addSample.TargetVolume <= 0))
|
|||
|
|
{
|
|||
|
|
MessageBox.Show("数据错误!");
|
|||
|
|
}
|
|||
|
|
if (addSample.FunctionFlowType == FunctionTypeEnum.加固体原料)
|
|||
|
|
{
|
|||
|
|
#region 搬运粉末加样头去梅特勒称上
|
|||
|
|
var powderBottle = workService.ProjectPro.PowderHeaderCacheArea.FirstOrDefault(ph => !string.IsNullOrEmpty(addSample.UseMaterialName) && addSample.UseMaterialName.Equals(ph.SourcePowderName));
|
|||
|
|
if (powderBottle is null)
|
|||
|
|
{
|
|||
|
|
Logger.LogError($"找不到{sampleBox.BoxId_inDosingStation}-{sampleBottle.PosId_InBox}需要的{addSample.UseMaterialName}固体");
|
|||
|
|
continue;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
powderBottle.SourcePowderBottleState = SourceBottleStateEnum.Using;
|
|||
|
|
if (!IsPowderInMachine)
|
|||
|
|
{
|
|||
|
|
if (!TestMode)
|
|||
|
|
{
|
|||
|
|
while (await ReadObstructFlag("四轴机械手运行中") || await ReadObstructFlag("四轴机械手正在使用传送平台"))
|
|||
|
|
{
|
|||
|
|
await Task.Delay(300);
|
|||
|
|
}
|
|||
|
|
await SetObstructFlag("四轴机械手运行中", true);
|
|||
|
|
//四轴机械手取粉末加样头 放到称重模块中
|
|||
|
|
await FourAxisTakePowderHeader((int)BoxAreaEnum._加样头存放平台, 1, powderBottle.Pos_InDosePowderHC, powderBottle.PowderBottleType, _cts.Token);
|
|||
|
|
//将粉末头放到梅特勒称重模块中
|
|||
|
|
labxPowderInstrument = await labxService.GetInstruments("自动天平XPR105");
|
|||
|
|
await labxService.StartWaitingForHead(labxPowderInstrument.FirstOrDefault(), "Dosing Head", "Dosing Head");
|
|||
|
|
await FourAxisPutPowderHeader((int)BoxAreaEnum._自动加样模块内, 1, 1, powderBottle.PowderBottleType, _cts.Token);
|
|||
|
|
await SetObstructFlag("四轴机械手运行中", false);
|
|||
|
|
await labxService.AbortWaitingForHead();
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
IsPowderInMachine = false;
|
|||
|
|
#endregion
|
|||
|
|
|
|||
|
|
#region 目标瓶从开盖位去称重位
|
|||
|
|
if (!TestMode && (i == 0 || sampleBottle.MaterialDoseFlowList[i - 1].FunctionFlowType != FunctionTypeEnum.加固体原料))
|
|||
|
|
{
|
|||
|
|
//第一个加样或者上一个加样不是固体,则取目标瓶开盖位到称重位
|
|||
|
|
while (await ReadObstructFlag("四轴机械手运行中") || await ReadObstructFlag("四轴机械手正在使用传送平台"))
|
|||
|
|
{
|
|||
|
|
await Task.Delay(300);
|
|||
|
|
}
|
|||
|
|
await SetObstructFlag("四轴机械手运行中", true);
|
|||
|
|
var task1 = FourAxisTakeSampleBottle(_cts.Token, (int)BoxAreaEnum._开关盖区域, 0, 0, sampleBottle);
|
|||
|
|
var task2 = labxService.MTPowderModuleControlStep(labxPowderInstrument.FirstOrDefault(), "Balance Step", "Balance Step", 1);//开门
|
|||
|
|
await Task.WhenAll(task1,task2);
|
|||
|
|
await FourAxisPutSampleBottle(_cts.Token, (int)BoxAreaEnum._自动加样模块内, 1, 1, sampleBottle);
|
|||
|
|
await SetObstructFlag("四轴机械手运行中", false);
|
|||
|
|
}
|
|||
|
|
#endregion
|
|||
|
|
|
|||
|
|
#region 加粉末
|
|||
|
|
if (!TestMode)
|
|||
|
|
{
|
|||
|
|
//梅特勒模块关门
|
|||
|
|
await labxService.MTPowderModuleControlStep(labxPowderInstrument.FirstOrDefault(), "Balance Step", "Balance Step", 0);
|
|||
|
|
double addPowderWeight = 0;
|
|||
|
|
//大99,小125 2~200mg +-0.297mg 200mg-5g 0.297%
|
|||
|
|
decimal dosHeight = sampleBottle.SampleBottleType == SampleBottleTypeEnum._12mL ? 96m : 122m; //99m : 125m
|
|||
|
|
decimal upT = Math.Round((decimal)addSample.TargetVolume < 200 ? (decimal)(0.297 / addSample.TargetVolume * 100) : 0.297m, 11);
|
|||
|
|
Logger.LogInformation($"(decimal)addSample.TargetVolume-{addSample.TargetVolume},上下限为{upT}");
|
|||
|
|
addPowderWeight = await labxService.MTPowderModuleAddPowder(labxPowderInstrument.FirstOrDefault(), "Dosing2", "Dosing2", 4, dosHeight, (decimal)addSample.TargetVolume, (decimal)upT, (decimal)upT);
|
|||
|
|
powderBottle.RemainWeight -= addPowderWeight / 1000;
|
|||
|
|
addSample.ActualVolume = addPowderWeight;
|
|||
|
|
}
|
|||
|
|
else
|
|||
|
|
{
|
|||
|
|
addSample.ActualVolume = addSample.TargetVolume;
|
|||
|
|
}
|
|||
|
|
Logger.LogInformation($"粉末目标:{addSample.TargetVolume}实际:{addSample.ActualVolume}");
|
|||
|
|
addSample.IsDoseFinish = true;
|
|||
|
|
//梅特勒模块开门
|
|||
|
|
//await labxService.MTPowderModuleControlStep(labxPowderInstrument.FirstOrDefault(), "Balance Step", "Balance Step", 1);
|
|||
|
|
#endregion
|
|||
|
|
|
|||
|
|
#region 粉末取回
|
|||
|
|
if (powderBottle != null && !TestMode)
|
|||
|
|
{
|
|||
|
|
//判断是不是最后一个粉末,如果是的话判断下一瓶是不是用的该粉末
|
|||
|
|
bool IsLastPowder = true;
|
|||
|
|
for (int j = i + 1; j < sampleBottle.MaterialDoseFlowList.Count; j++)
|
|||
|
|
{
|
|||
|
|
if (sampleBottle.MaterialDoseFlowList[j].FunctionFlowType == FunctionTypeEnum.加固体原料)
|
|||
|
|
{
|
|||
|
|
IsLastPowder = false;
|
|||
|
|
IsPowderInMachine = sampleBottle.MaterialDoseFlowList[j].UseMaterialName.Equals(powderBottle.SourcePowderName);
|
|||
|
|
break;
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
if (IsLastPowder && samplebottleNext != null)
|
|||
|
|
{
|
|||
|
|
var nextMotherLiquid = samplebottleNext.MaterialDoseFlowList.FirstOrDefault(s => s.FunctionFlowType == FunctionTypeEnum.加固体原料);
|
|||
|
|
IsPowderInMachine = nextMotherLiquid != null && nextMotherLiquid.UseMaterialName.Equals(powderBottle.SourcePowderName);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
if (!IsPowderInMachine)
|
|||
|
|
{
|
|||
|
|
while (await ReadObstructFlag("四轴机械手运行中") || await ReadObstructFlag("四轴机械手正在使用传送平台"))
|
|||
|
|
{
|
|||
|
|
await Task.Delay(300);
|
|||
|
|
}
|
|||
|
|
await SetObstructFlag("四轴机械手运行中", true);
|
|||
|
|
await FourAxisTakePowderHeader((int)BoxAreaEnum._自动加样模块内, 1, 1, powderBottle.PowderBottleType, _cts.Token);
|
|||
|
|
//Task task1 = labxService.MTPowderModuleControlStep(labxPowderInstrument.FirstOrDefault(), "Balance Step", "Balance Step", 0); //多余的
|
|||
|
|
await FourAxisPutPowderHeader((int)BoxAreaEnum._加样头存放平台, 1, powderBottle.Pos_InDosePowderHC, powderBottle.PowderBottleType, _cts.Token);
|
|||
|
|
//await Task.WhenAll(task1, task2);
|
|||
|
|
await SetObstructFlag("四轴机械手运行中", false);
|
|||
|
|
}
|
|||
|
|
powderBottle.SourcePowderBottleState = SourceBottleStateEnum.Idl;
|
|||
|
|
}
|
|||
|
|
#endregion
|
|||
|
|
|
|||
|
|
#region 目标瓶放回开盖位
|
|||
|
|
if (!TestMode && (i == sampleBottle.MaterialDoseFlowList.Count - 1 || sampleBottle.MaterialDoseFlowList[i+1].FunctionFlowType != FunctionTypeEnum.加固体原料))
|
|||
|
|
{
|
|||
|
|
//最后一个加样或者下一个加样不是固体,则取回目标瓶到开盖位
|
|||
|
|
while (await ReadObstructFlag("四轴机械手运行中") || await ReadObstructFlag("四轴机械手正在使用传送平台"))
|
|||
|
|
{
|
|||
|
|
await Task.Delay(300);
|
|||
|
|
}
|
|||
|
|
await SetObstructFlag("四轴机械手运行中", true);
|
|||
|
|
await labxService.MTPowderModuleControlStep(labxPowderInstrument.FirstOrDefault(), "Balance Step", "Balance Step", 1);//开门
|
|||
|
|
await FourAxisTakeSampleBottle(_cts.Token, (int)BoxAreaEnum._自动加样模块内, 1, 1, sampleBottle);
|
|||
|
|
Task task1 = labxService.MTPowderModuleControlStep(labxPowderInstrument.FirstOrDefault(), "Balance Step", "Balance Step", 0); //关门
|
|||
|
|
Task task2 = FourAxisPutSampleBottle(_cts.Token, (int)BoxAreaEnum._开关盖区域, 0, 0, sampleBottle);
|
|||
|
|
await Task.WhenAll(task1, task2);
|
|||
|
|
await SetObstructFlag("四轴机械手运行中", false);
|
|||
|
|
}
|
|||
|
|
#endregion
|
|||
|
|
}
|
|||
|
|
else if (addSample.FunctionFlowType == FunctionTypeEnum.加液体原料)
|
|||
|
|
{
|
|||
|
|
#region 搬运母液去开盖
|
|||
|
|
// 筛选40mL原液工装并转换为SourceLiquidBottleBoxModel类型
|
|||
|
|
var targetBoxAndBottle = workService.ProjectPro.FixtureCacheArea
|
|||
|
|
.Where(b => b.FixtureType == BoxTypeEnum._40mL原液工装)
|
|||
|
|
.OfType<SourceLiquidBottleBoxModel>()
|
|||
|
|
.SelectMany(box => box.SourceLiquidBottleCollection
|
|||
|
|
.Select(bottle => new { Box = box, Bottle = bottle }))
|
|||
|
|
.FirstOrDefault(item => !string.IsNullOrEmpty(item.Bottle.SourceLiquidName) && item.Bottle.SourceLiquidName.Equals(addSample.UseMaterialName) && item.Bottle.RemainVolume > 3);
|
|||
|
|
var sourceLiquidBox = targetBoxAndBottle?.Box;
|
|||
|
|
var sourceBottle = targetBoxAndBottle?.Bottle;
|
|||
|
|
if (sourceBottle is null)
|
|||
|
|
{
|
|||
|
|
Logger.LogError($"找不到{sampleBox.BoxId_inDosingStation}-{sampleBottle.PosId_InBox}需要的{addSample.UseMaterialName}液体");
|
|||
|
|
continue;
|
|||
|
|
}
|
|||
|
|
sourceBottle.SourceLiquidBottleState = SourceBottleStateEnum.Using;
|
|||
|
|
if (!IsMotherLiquidInMachine)
|
|||
|
|
{
|
|||
|
|
await SetObstructFlag("四轴机械手运行中", true);
|
|||
|
|
await FourAxisTakeLiquidBottle(_cts.Token, (int)BoxAreaEnum._托盘存放平台, sourceLiquidBox.BoxId_inDosingStation, sourceBottle.PosId_InBox, sourceBottle);
|
|||
|
|
if (string.IsNullOrEmpty(sourceBottle.SNCode))
|
|||
|
|
{
|
|||
|
|
await FourAxisGoToScannPos_liquid(_cts.Token, 1, sourceBottle, null);
|
|||
|
|
}
|
|||
|
|
await FourAxisPutLiquidBottle(_cts.Token, (int)BoxAreaEnum._开关盖区域, 0, 0, sourceBottle);
|
|||
|
|
await SetObstructFlag("四轴机械手运行中", false);
|
|||
|
|
await OpenBottleLid(_cts.Token, sourceBottle, null);
|
|||
|
|
}
|
|||
|
|
else
|
|||
|
|
{
|
|||
|
|
//说明母液在开盖位,则开假盖子
|
|||
|
|
await OpenCloseBottleFakeCap(_cts.Token,isOpen:true, sourceBottle,null);
|
|||
|
|
}
|
|||
|
|
IsMotherLiquidInMachine = false;
|
|||
|
|
#endregion
|
|||
|
|
|
|||
|
|
#region 加液
|
|||
|
|
await XZ_TakeTip_Absorb_Dispense_DiscardTip(_cts.Token, addSample.UseMaterialName, addSample.TargetVolume, sourceBottle, sampleBottle);
|
|||
|
|
//更新原液瓶剩余量
|
|||
|
|
sourceBottle.RemainVolume -= addSample.TargetVolume / 1000;
|
|||
|
|
addSample.IsDoseFinish = true;
|
|||
|
|
#endregion
|
|||
|
|
|
|||
|
|
#region 搬回当前原液
|
|||
|
|
if (sourceBottle != null)
|
|||
|
|
{
|
|||
|
|
//判断是不是最后一个母液,如果是的话判断下一瓶是不是用的该母液
|
|||
|
|
bool IsLastLiquid = true;
|
|||
|
|
for (int j = i + 1; j < sampleBottle.MaterialDoseFlowList.Count; j++)
|
|||
|
|
{
|
|||
|
|
if (sampleBottle.MaterialDoseFlowList[j].FunctionFlowType == FunctionTypeEnum.加液体原料)
|
|||
|
|
{
|
|||
|
|
IsLastLiquid = false;
|
|||
|
|
IsMotherLiquidInMachine = sampleBottle.MaterialDoseFlowList[j].UseMaterialName.Equals(sourceBottle.SourceLiquidName);
|
|||
|
|
break;
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
if (IsLastLiquid && samplebottleNext != null)
|
|||
|
|
{
|
|||
|
|
var nextMotherLiquid = samplebottleNext.MaterialDoseFlowList.FirstOrDefault(s => s.FunctionFlowType == FunctionTypeEnum.加液体原料);
|
|||
|
|
IsMotherLiquidInMachine = nextMotherLiquid != null && nextMotherLiquid.UseMaterialName.Equals(sourceBottle.SourceLiquidName);
|
|||
|
|
if (sourceBottle.RemainVolume < 3)
|
|||
|
|
{
|
|||
|
|
IsMotherLiquidInMachine = false;
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
//四轴机械手取回原液瓶 放到托盘存放平台
|
|||
|
|
//关盖
|
|||
|
|
if (!IsMotherLiquidInMachine)
|
|||
|
|
{
|
|||
|
|
await CloseBottleLid(_cts.Token, sourceBottle, null);
|
|||
|
|
if (!TestMode)
|
|||
|
|
{
|
|||
|
|
while (await ReadObstructFlag("四轴机械手运行中") || await ReadObstructFlag("四轴机械手正在使用传送平台"))
|
|||
|
|
{
|
|||
|
|
await Task.Delay(300);
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
await SetObstructFlag("四轴机械手运行中", true);
|
|||
|
|
await FourAxisTakeLiquidBottle(_cts.Token, (int)BoxAreaEnum._开关盖区域, 0, 0, sourceBottle);
|
|||
|
|
await FourAxisPutLiquidBottle(_cts.Token, (int)BoxAreaEnum._托盘存放平台, sourceLiquidBox.BoxId_inDosingStation, sourceBottle.PosId_InBox, sourceBottle);
|
|||
|
|
await SetObstructFlag("四轴机械手运行中", false);
|
|||
|
|
}
|
|||
|
|
else
|
|||
|
|
{
|
|||
|
|
//说明下一瓶还需要用,关假盖子
|
|||
|
|
await OpenCloseBottleFakeCap(_cts.Token, isOpen: false, sourceBottle, null);
|
|||
|
|
}
|
|||
|
|
sourceBottle.SourceLiquidBottleState = SourceBottleStateEnum.Idl;
|
|||
|
|
}
|
|||
|
|
#endregion
|
|||
|
|
}
|
|||
|
|
else
|
|||
|
|
{
|
|||
|
|
//震荡摇匀
|
|||
|
|
await CloseBottleLid(_cts.Token, null, sampleBottle);
|
|||
|
|
await ShakeSampleBottle(_cts.Token, sampleBottle);
|
|||
|
|
if (i != sampleBottle.MaterialDoseFlowList.Count - 1)
|
|||
|
|
{
|
|||
|
|
//不是最后一次摇匀,需要开盖
|
|||
|
|
await OpenBottleLid(_cts.Token, null, sampleBottle);
|
|||
|
|
}
|
|||
|
|
else
|
|||
|
|
{
|
|||
|
|
//最后一次摇匀,则需要标志下已经关盖了
|
|||
|
|
SampleHasOpened = true;
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
sampleBottle.bDoseFinish = true;
|
|||
|
|
//关盖震荡摇匀并放回
|
|||
|
|
#region 关盖震荡摇匀
|
|||
|
|
|
|||
|
|
if (!SampleHasOpened)
|
|||
|
|
{
|
|||
|
|
await CloseBottleLid(_cts.Token, null, sampleBottle);
|
|||
|
|
}
|
|||
|
|
if (!TestMode)
|
|||
|
|
{
|
|||
|
|
while (await ReadObstructFlag("四轴机械手运行中") || await ReadObstructFlag("四轴机械手正在使用传送平台"))
|
|||
|
|
{
|
|||
|
|
await Task.Delay(300);
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
var isShakeMix = await dataAccessService.LoadEntityAsync<Setting>(s => s.Key.Equals("IsShakeMix") && s.Group.Equals("Setting"));
|
|||
|
|
if (isShakeMix != null && !isShakeMix.Context.Equals("0"))
|
|||
|
|
{
|
|||
|
|
await SetObstructFlag("四轴机械手运行中", true);
|
|||
|
|
await ShakeSampleBottle(_cts.Token, sampleBottle);
|
|||
|
|
}
|
|||
|
|
await FourAxisTakeSampleBottle(_cts.Token, (int)BoxAreaEnum._开关盖区域, 0, 0, sampleBottle);
|
|||
|
|
await FourAxisPutSampleBottle(_cts.Token, (int)BoxAreaEnum._托盘存放平台, sampleBox.BoxId_inDosingStation, sampleBottle.PosId_InBox, sampleBottle);
|
|||
|
|
await SetObstructFlag("四轴机械手运行中", false);
|
|||
|
|
#endregion
|
|||
|
|
|
|||
|
|
return (IsPowderInMachine, IsMotherLiquidInMachine);
|
|||
|
|
}
|
|||
|
|
#endregion
|
|||
|
|
|
|||
|
|
protected override void LoadServices()
|
|||
|
|
{
|
|||
|
|
base.LoadServices();//复用父类通用逻辑 + 子类扩展
|
|||
|
|
|
|||
|
|
appConfigService = this.CoreService.GetServiceInstance<AppConfigService>();
|
|||
|
|
labxService = this.CoreService.GetServiceInstance<LabxService>();
|
|||
|
|
|
|||
|
|
preWeight = this.CoreService.GetServiceInstance<WeightService_Ts02>(DeviceNames.PreWeight.ToString());
|
|||
|
|
scannerService = this.CoreService.GetServiceInstance<ScannerService>(DeviceNames.Scanner.ToString());
|
|||
|
|
scannerService_Powder = this.CoreService.GetServiceInstance<ScannerService>(DeviceNames.Scanner_Powder.ToString());
|
|||
|
|
pipetteService_1ml = this.CoreService.GetServiceInstance<PipetteService>(DeviceNames.Pipette_Dose_1ml.ToString());
|
|||
|
|
|
|||
|
|
|
|||
|
|
this._httpClientFactory = this.CoreService.GetServiceInstance<IHttpClientFactory>();
|
|||
|
|
if (this.ModbusClient != null)
|
|||
|
|
{
|
|||
|
|
//清除信号
|
|||
|
|
}
|
|||
|
|
this.workService.PrepareUploadBox += WorkService_PrepareUploadBox;
|
|||
|
|
this.workService.UpdateBoxInfo_BS += WorkService_UpdateBoxInfo_BS;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
protected override void LoadDatas()
|
|||
|
|
{
|
|||
|
|
base.LoadDatas();
|
|||
|
|
InitialData();
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
private async Task InitialStationControlState()
|
|||
|
|
{
|
|||
|
|
if (this.StationProp.cancellationToken != null)
|
|||
|
|
this.StationProp.cancellationToken.Cancel();
|
|||
|
|
this.StationProp.cancellationToken = new CancellationTokenSource();
|
|||
|
|
this.StationProp.ManualResetEvent = new ManualResetEvent(true);
|
|||
|
|
await SetObstructFlag("传送平台收到准备上料信号", false);
|
|||
|
|
await SetObstructFlag("四轴机械手运行中", false);
|
|||
|
|
await SetObstructFlag("四轴机械手正在使用传送平台", false);
|
|||
|
|
_currentDoseFlow = null;
|
|||
|
|
_currentUseSourceLiquidBottle = null;
|
|||
|
|
_currentUsePowderBottle = null;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
private async Task InitialProjectProState()
|
|||
|
|
{
|
|||
|
|
for (int i = 0; i < workService.ProjectPro.FixtureCacheArea.Count; i++)
|
|||
|
|
{
|
|||
|
|
if (workService.ProjectPro.FixtureCacheArea[i] is SampleBottleBoxModel)
|
|||
|
|
{
|
|||
|
|
SampleBottleBoxModel samplebottleBox = workService.ProjectPro.FixtureCacheArea[i] as SampleBottleBoxModel;
|
|||
|
|
samplebottleBox.IsDoseFinish = false;
|
|||
|
|
samplebottleBox.IsEmpty = false;
|
|||
|
|
samplebottleBox.IsUseFinsh = false;
|
|||
|
|
for (int j = 0; j < samplebottleBox.SampleBottleList.Count; j++)
|
|||
|
|
{
|
|||
|
|
samplebottleBox.SampleBottleList[j].SNCode = string.Empty;
|
|||
|
|
samplebottleBox.SampleBottleList[j].bDoseFinish = false;
|
|||
|
|
samplebottleBox.SampleBottleList[j].SampleBottleLidState = SampleBottleLidStateEnum.Close;
|
|||
|
|
samplebottleBox.SampleBottleList[j].SampleBoxState = SampleBottleStateEnum.Empty;
|
|||
|
|
foreach (var doseflow in samplebottleBox.SampleBottleList[j].MaterialDoseFlowList)
|
|||
|
|
{
|
|||
|
|
doseflow.IsDoseFinish = false;
|
|||
|
|
doseflow.ActualVolume = 0;
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
else if (workService.ProjectPro.FixtureCacheArea[i] is SourceLiquidBottleBoxModel)
|
|||
|
|
{
|
|||
|
|
SourceLiquidBottleBoxModel sourceliquidbox = workService.ProjectPro.FixtureCacheArea[i] as SourceLiquidBottleBoxModel;
|
|||
|
|
sourceliquidbox.IsDoseFinish = false;
|
|||
|
|
for (int j = 0; j < sourceliquidbox.SourceLiquidBottleCollection.Count; j++)
|
|||
|
|
{
|
|||
|
|
sourceliquidbox.SourceLiquidBottleCollection[j].SNCode = string.Empty;
|
|||
|
|
sourceliquidbox.SourceLiquidBottleCollection[j].LiquidBottleLidState = SourceBottleLidStateEnum.Close;
|
|||
|
|
sourceliquidbox.SourceLiquidBottleCollection[j].SourceLiquidBottleState = SourceBottleStateEnum.Idl;
|
|||
|
|
sourceliquidbox.SourceLiquidBottleCollection[j].RemainVolume = sourceliquidbox.SourceLiquidBottleCollection[j].OriginVolume;
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
else
|
|||
|
|
{
|
|||
|
|
workService.ProjectPro.FixtureCacheArea[i].IsDoseFinish = false;
|
|||
|
|
workService.ProjectPro.FixtureCacheArea[i].IsUseFinsh = false;
|
|||
|
|
workService.ProjectPro.FixtureCacheArea[i].IsEmpty = true;
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
for (int i = 0; i < workService.ProjectPro.PowderHeaderCacheArea.Count; i++)
|
|||
|
|
{
|
|||
|
|
workService.ProjectPro.PowderHeaderCacheArea[i].SourcePowderBottleState = SourceBottleStateEnum.Idl;
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
public ushort GetInitStatus()
|
|||
|
|
{
|
|||
|
|
if (TestMode)
|
|||
|
|
{
|
|||
|
|
return (ushort)3;
|
|||
|
|
}
|
|||
|
|
return this.ModbusClient.Command.ReadValue<ushort>(PlcPoints_MaterialDose.R_PLCInitialStatus);
|
|||
|
|
}
|
|||
|
|
private void InitialData()
|
|||
|
|
{
|
|||
|
|
//加载传送平台 7个工装
|
|||
|
|
workService.ProjectPro.TransferArea.Clear();
|
|||
|
|
for (int i = 0; i < 7; i++)
|
|||
|
|
{
|
|||
|
|
workService.ProjectPro.TransferArea.Add(new BaseBottleBox()
|
|||
|
|
{
|
|||
|
|
BoxId_inDoseDnload = i + 1,
|
|||
|
|
BoxId_inDoseUpload = i + 1,
|
|||
|
|
IsEmpty = true,
|
|||
|
|
IsDoseFinish = false,
|
|||
|
|
IsUseFinsh = false,
|
|||
|
|
BoxArea = BoxAreaEnum._手套箱传送平台,
|
|||
|
|
});
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
workService.ProjectPro.FixtureCacheArea.Clear();
|
|||
|
|
//加载工装暂存区域 8个工装
|
|||
|
|
for (int i = 0; i < 8; i++)
|
|||
|
|
{
|
|||
|
|
workService.ProjectPro.FixtureCacheArea.Add(new BaseBottleBox()
|
|||
|
|
{
|
|||
|
|
//FixtureType = BoxTypeEnum._40mL原液工装,
|
|||
|
|
BoxId_inDosingStation = i + 1,
|
|||
|
|
BoxArea = BoxAreaEnum._托盘存放平台,
|
|||
|
|
IsEmpty = true,
|
|||
|
|
IsDoseFinish = false,
|
|||
|
|
IsUseFinsh = false,
|
|||
|
|
});
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
workService.ProjectPro.PowderHeaderCacheArea.Clear();
|
|||
|
|
//加载粉末加样头暂存区域 10个位置
|
|||
|
|
for (int i = 0; i < 10; i++)
|
|||
|
|
{
|
|||
|
|
workService.ProjectPro.PowderHeaderCacheArea.Add(
|
|||
|
|
new SourcePowderBottleModel()
|
|||
|
|
{
|
|||
|
|
HaveBottle = false,
|
|||
|
|
Pos_InDosePowderHC = i + 1,
|
|||
|
|
SNCode = string.Empty,
|
|||
|
|
PowderBottleType = PowderBottleTypeEnum._125mL,
|
|||
|
|
SourcePowderBottleState = SourceBottleStateEnum.Idl,
|
|||
|
|
OriginWeight =0,
|
|||
|
|
});
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// 3个tip头工装
|
|||
|
|
workService.ProjectPro.TipHeadArea.Clear();
|
|||
|
|
for (int i = 0; i < 3; i++)
|
|||
|
|
{
|
|||
|
|
TipBoxModel tipBox = new TipBoxModel()
|
|||
|
|
{
|
|||
|
|
TipType = i switch
|
|||
|
|
{
|
|||
|
|
0 => TipTypeEnum._1000UL,
|
|||
|
|
1 => TipTypeEnum._300UL,
|
|||
|
|
2 => TipTypeEnum._50UL,
|
|||
|
|
_ => TipTypeEnum._300UL
|
|||
|
|
},
|
|||
|
|
HaveBox = false,
|
|||
|
|
UseIndex = 0,
|
|||
|
|
BoxId_inDosingStation = i + 1,
|
|||
|
|
IsEmpty = true, // 初始无工装(可根据需求调整)
|
|||
|
|
};
|
|||
|
|
|
|||
|
|
// 添加96个可用Tip头(避免序列化空引用)
|
|||
|
|
for (int j = 0; j < 8 * 12; j++)
|
|||
|
|
{
|
|||
|
|
tipBox.TipItems.Add(new TipHeadItem { IsAvailable = false, UseIndex = j + 1 });
|
|||
|
|
}
|
|||
|
|
workService.ProjectPro.TipHeadArea.Add(tipBox);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
_currentDoseFlow = null;
|
|||
|
|
_currentUseSourceLiquidBottle = null;
|
|||
|
|
_currentUsePowderBottle = null;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
|
|||
|
|
|
|||
|
|
private bool bInitial_Z = false;
|
|||
|
|
private bool bInitial = false;
|
|||
|
|
private ushort lastInitStatus = 999;
|
|||
|
|
|
|||
|
|
private async Task InitDown()
|
|||
|
|
{
|
|||
|
|
var point1 = this.ModbusClient.Command.ReadValue<ushort>(PlcPoints_MaterialDose.R_PLCInitialStatus);
|
|||
|
|
if (point1 != lastInitStatus)
|
|||
|
|
{
|
|||
|
|
lastInitStatus = point1;
|
|||
|
|
if (lastInitStatus != 999 && point1 == 3) //不是开机第一次读取
|
|||
|
|
{
|
|||
|
|
_ = Task.Run(async () =>
|
|||
|
|
{
|
|||
|
|
await ChangeDeviceStatus(Entities.DeviceStatus.Idel);
|
|||
|
|
WeakReferenceMessenger.Default.Send(new DesktopAlertMessage() { Content = "设备已完成初始化" });
|
|||
|
|
});
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/// <summary>
|
|||
|
|
/// 重写,,每间隔200ms,就会进入这个函数
|
|||
|
|
/// </summary>
|
|||
|
|
/// <param name="sender"></param>
|
|||
|
|
/// <param name="e"></param>
|
|||
|
|
protected override async void ModbusClientBaseOnScannedEvent(object sender, EventArgs e)
|
|||
|
|
{
|
|||
|
|
base.ModbusClientBaseOnScannedEvent(sender, e);
|
|||
|
|
this.StationProp.ManualResetEvent.WaitOne(); //暂停标志
|
|||
|
|
await InitDown();
|
|||
|
|
|
|||
|
|
//if (!workService.ProjectPro.bNoUseBS && (TaskBoxFromTransferPlateTask == null || TaskBoxFromTransferPlateTask.IsCanceled || TaskBoxFromTransferPlateTask.IsFaulted || TaskBoxFromTransferPlateTask.IsCompleted))
|
|||
|
|
//{
|
|||
|
|
// TaskBoxFromTransferPlateTask = Task.Run(async () =>
|
|||
|
|
// {
|
|||
|
|
// await UploadBoxFromTransferPlateToHCBox(this.StationProp.cancellationToken.Token);
|
|||
|
|
// });
|
|||
|
|
//}
|
|||
|
|
|
|||
|
|
//if (!workService.ProjectPro.bNoUseBS && (DownloadBoxToTransferPlateTask == null || DownloadBoxToTransferPlateTask.IsCanceled || DownloadBoxToTransferPlateTask.IsFaulted || DownloadBoxToTransferPlateTask.IsCompleted))
|
|||
|
|
//{
|
|||
|
|
// DownloadBoxToTransferPlateTask = Task.Run(async () =>
|
|||
|
|
// {
|
|||
|
|
// await DownloadFixtueBox(this.StationProp.cancellationToken.Token);
|
|||
|
|
// });
|
|||
|
|
//}
|
|||
|
|
|
|||
|
|
#region 1ml移液枪初始化
|
|||
|
|
//1ml移液枪Z轴初始化
|
|||
|
|
if (ReadScannedValueAsync_FourAxis(PlcPoints_MaterialDose.R_1mlPipetteZInit).Result == 1 && !bInitial_Z) //1ml移液枪Z轴初始化
|
|||
|
|
{
|
|||
|
|
bInitial_Z = true;
|
|||
|
|
await GunZAxisInit_M1(DeviceNames.Pipette_Dose_1ml_1, pipetteService_1ml);
|
|||
|
|
await GunZAxisInit_M1(DeviceNames.Pipette_Dose_1ml_2, pipetteService_1ml);
|
|||
|
|
await GunZAxisInit_M1(DeviceNames.Pipette_Dose_1ml_3, pipetteService_1ml);
|
|||
|
|
await GunZAxisInit_M1(DeviceNames.Pipette_Dose_1ml_4, pipetteService_1ml);
|
|||
|
|
//Z轴初始化成功,回复给机械手
|
|||
|
|
await WriteCommandAsync_FourAxis(PlcPoints_MaterialDose.W_1mlPipetteZInitResult, 1);
|
|||
|
|
//等待PLC清除Z初始化信号
|
|||
|
|
await WaitForActionFinishAsync_FourAxis(PlcPoints_MaterialDose.R_1mlPipetteZInit, 0, this.StationProp.cancellationToken.Token);
|
|||
|
|
await WriteCommandAsync_FourAxis(PlcPoints_MaterialDose.W_1mlPipetteZInitResult, 0); //清除信号
|
|||
|
|
bInitial_Z = false;
|
|||
|
|
}
|
|||
|
|
//1ml移液枪初始化
|
|||
|
|
if (ReadScannedValueAsync_FourAxis(PlcPoints_MaterialDose.R_1mlPipetteInit).Result == 1 && !bInitial) //1ml移液枪初始化
|
|||
|
|
{
|
|||
|
|
bInitial = true;
|
|||
|
|
await GunAllInit_M1(DeviceNames.Pipette_Dose_1ml_1, pipetteService_1ml);
|
|||
|
|
await GunAllInit_M1(DeviceNames.Pipette_Dose_1ml_2, pipetteService_1ml);
|
|||
|
|
await GunAllInit_M1(DeviceNames.Pipette_Dose_1ml_3, pipetteService_1ml);
|
|||
|
|
await GunAllInit_M1(DeviceNames.Pipette_Dose_1ml_4, pipetteService_1ml);
|
|||
|
|
//Z轴初始化成功,回复给机械手
|
|||
|
|
await WriteCommandAsync_FourAxis(PlcPoints_MaterialDose.W_1mlPipetteInitResult, 1);
|
|||
|
|
//等待PLC清除Z初始化信号
|
|||
|
|
await WaitForActionFinishAsync_FourAxis(PlcPoints_MaterialDose.R_1mlPipetteInit, 0, this.StationProp.cancellationToken.Token);
|
|||
|
|
await WriteCommandAsync_FourAxis(PlcPoints_MaterialDose.W_1mlPipetteInitResult, 0); //清除信号
|
|||
|
|
bInitial = false;
|
|||
|
|
}
|
|||
|
|
#endregion
|
|||
|
|
|
|||
|
|
//if (!this.StationProp.bStartButtonTrigger) //没有收到启动信号或者没有按下启动按钮
|
|||
|
|
//{
|
|||
|
|
// //若按下复位按钮,则清除所有状态
|
|||
|
|
// if (this.StationProp.bResetButtonTrigger) //按下复位按钮
|
|||
|
|
// {
|
|||
|
|
// this.StationProp.bResetButtonTrigger = false;
|
|||
|
|
// await Application.Current.Dispatcher.InvokeAsync(async () =>
|
|||
|
|
// {
|
|||
|
|
// await DialogManager.ShowDialogAsync(
|
|||
|
|
// owner: Application.Current.MainWindow, // 尽量传MainWindow作为Owner,避免弹窗无归属
|
|||
|
|
// message: "投料站复位中,正在清除状态,请稍等...\r\n这需要几秒钟时间",
|
|||
|
|
// operation: async () =>
|
|||
|
|
// {
|
|||
|
|
// await InitialStationControlState();
|
|||
|
|
// await InitialProjectProState();
|
|||
|
|
// });
|
|||
|
|
// });
|
|||
|
|
// //await InitialStationControlState();
|
|||
|
|
// //await InitialProjectProState();
|
|||
|
|
|
|||
|
|
// }
|
|||
|
|
// return;
|
|||
|
|
//}
|
|||
|
|
//else //按下启动按钮
|
|||
|
|
//{
|
|||
|
|
// if (this.StationProp.bStopButtonTrigger) //收到BS的停止信号或者按下停止按钮
|
|||
|
|
// {
|
|||
|
|
// this.StationProp.bStopButtonTrigger = false;
|
|||
|
|
// this.StationProp.cancellationToken.Cancel();
|
|||
|
|
// TimeSpan totalCt = this.StationProp.CTWatch.Elapsed;
|
|||
|
|
// workService.ProjectPro.Dose_CT = $"{totalCt.Hours}时{totalCt.Minutes}分{totalCt.Seconds}秒";
|
|||
|
|
// this.StationProp.CTWatch.Reset();
|
|||
|
|
// //await magneticStirService.StirringSwitchContriol(TimeSpan.FromSeconds(3), false);
|
|||
|
|
// //await ClearReactBottleAndRotaterState();
|
|||
|
|
// this.StationProp.bStartButtonTrigger = false;
|
|||
|
|
// this.StationProp.bResetButtonTrigger = false;
|
|||
|
|
// this.StationProp.bRunFinish = false;
|
|||
|
|
// await InitialStationControlState();
|
|||
|
|
// return;
|
|||
|
|
// }
|
|||
|
|
|
|||
|
|
// if (this.StationProp.bRunFinish) //如果配置完成了,就不再执行了
|
|||
|
|
// {
|
|||
|
|
// this.StationProp.bRunFinish = false;
|
|||
|
|
// //this.StationProp.cancellationToken.Cancel();
|
|||
|
|
// TimeSpan totalCt = this.StationProp.CTWatch.Elapsed;
|
|||
|
|
// workService.ProjectPro.Dose_CT = $"{totalCt.Hours}时{totalCt.Minutes}分{totalCt.Seconds}秒";
|
|||
|
|
// this.StationProp.CTWatch.Reset();
|
|||
|
|
// WeakReferenceMessenger.Default.Send(new SingleBoolMessage(true));
|
|||
|
|
// WeakReferenceMessenger.Default.Send(new SingleBoolPeifangMessage(true));
|
|||
|
|
// this.StationProp.bStartButtonTrigger = false;
|
|||
|
|
// this.StationProp.bStopButtonTrigger = false;
|
|||
|
|
// this.StationProp.bResetButtonTrigger = false;
|
|||
|
|
// //await InitialStationControlState();
|
|||
|
|
// return;
|
|||
|
|
// }
|
|||
|
|
//}
|
|||
|
|
|
|||
|
|
//切换投料物
|
|||
|
|
//await SwitchCurrentDoseFlow(this.StationProp.cancellationToken.Token);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/// <summary>
|
|||
|
|
/// 收到BS 告诉的准备上工装信息 ,触发事件
|
|||
|
|
/// </summary>
|
|||
|
|
/// <param name="sender"></param>
|
|||
|
|
/// <param name="e"></param>
|
|||
|
|
/// <exception cref="NotImplementedException"></exception>
|
|||
|
|
private async void WorkService_PrepareUploadBox(object sender, EventArgs e)
|
|||
|
|
{
|
|||
|
|
while (await ReadObstructFlag("四轴机械手正在使用传送平台")
|
|||
|
|
|| await ReadObstructFlag("传送平台收到准备上料信号"))
|
|||
|
|
{
|
|||
|
|
await Task.Delay(300);
|
|||
|
|
}
|
|||
|
|
await SetObstructFlag("传送平台收到准备上料信号", true);
|
|||
|
|
//传送平台到过渡舱外准备上载具
|
|||
|
|
await TransferUploadBox(this.StationProp.cancellationToken.Token);
|
|||
|
|
//回复BS准备好上料
|
|||
|
|
//_httpClientFactory.
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/// <summary>
|
|||
|
|
/// BS放好载具到传送平台上,触发更新事件
|
|||
|
|
/// </summary>
|
|||
|
|
/// <param name="sender"></param>
|
|||
|
|
/// <param name="e"></param>
|
|||
|
|
private async void WorkService_UpdateBoxInfo_BS(object sender, BaseBottleBox e)
|
|||
|
|
{
|
|||
|
|
try
|
|||
|
|
{
|
|||
|
|
//收到BS放工装完成信号
|
|||
|
|
//先让PLC将传送平台运行到设备内部
|
|||
|
|
await TransferToDeviceInner(this.StationProp.cancellationToken.Token);
|
|||
|
|
await SetObstructFlag("传送平台收到准备上料信号", false);
|
|||
|
|
|
|||
|
|
//读取BS告诉CS的工装在传动平台的位置
|
|||
|
|
int pos = e.BoxId_inDoseUpload;
|
|||
|
|
|
|||
|
|
BaseBottleBox fixture = workService.ProjectPro.TransferArea.FirstOrDefault(c => c.BoxId_inDoseUpload == pos);
|
|||
|
|
fixture = File_Operator.DeepCopy(e);
|
|||
|
|
|
|||
|
|
//BS更新序列后
|
|||
|
|
switch (e.FixtureType)
|
|||
|
|
{
|
|||
|
|
case BoxTypeEnum._40mL原液工装:
|
|||
|
|
SourceLiquidBottleBoxModel sourceLiquidBottleBox = e as SourceLiquidBottleBoxModel;
|
|||
|
|
sourceLiquidBottleBox.FixtureType = BoxTypeEnum._40mL原液工装;
|
|||
|
|
for (int i = 0; i < sourceLiquidBottleBox.SourceLiquidBottleCollection.Count; i++)
|
|||
|
|
{
|
|||
|
|
sourceLiquidBottleBox.SourceLiquidBottleCollection[i].BoxSNCode = sourceLiquidBottleBox.BoxSNCode;
|
|||
|
|
sourceLiquidBottleBox.SourceLiquidBottleCollection[i].LiquidBottleLidState = SourceBottleLidStateEnum.Close;
|
|||
|
|
sourceLiquidBottleBox.SourceLiquidBottleCollection[i].SNCode = string.Empty;
|
|||
|
|
sourceLiquidBottleBox.SourceLiquidBottleCollection[i].HaveBottle = true;
|
|||
|
|
}
|
|||
|
|
//将工装信息更新到传送平台对应位置
|
|||
|
|
fixture = File_Operator.DeepCopy(sourceLiquidBottleBox);
|
|||
|
|
fixture.IsEmpty = false; fixture.IsUseFinsh = false; fixture.IsDoseFinish = false;
|
|||
|
|
break;
|
|||
|
|
case BoxTypeEnum._12mL样品工装:
|
|||
|
|
SampleBottleBoxModel sampleBottleBox = e as SampleBottleBoxModel;
|
|||
|
|
sampleBottleBox.SampleBottleType = SampleBottleTypeEnum._12mL;
|
|||
|
|
for (int i = 0; i < sampleBottleBox.SampleBottleList.Count; i++)
|
|||
|
|
{
|
|||
|
|
sampleBottleBox.SampleBottleList[i].SampleBottleType = SampleBottleTypeEnum._12mL;
|
|||
|
|
sampleBottleBox.SampleBottleList[i].bDoseFinish = false;
|
|||
|
|
sampleBottleBox.SampleBottleList[i].HaveBottle = true;
|
|||
|
|
sampleBottleBox.SampleBottleList[i].SampleBottleLidState = SampleBottleLidStateEnum.Close;
|
|||
|
|
sampleBottleBox.SampleBottleList[i].SNCode = string.Empty;
|
|||
|
|
sampleBottleBox.SampleBottleList[i].BoxSNCode = sampleBottleBox.BoxSNCode;
|
|||
|
|
foreach (var doseflow in sampleBottleBox.SampleBottleList[i].MaterialDoseFlowList)
|
|||
|
|
{
|
|||
|
|
doseflow.IsDoseFinish = false;
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
//将工装信息更新到传送平台对应位置
|
|||
|
|
fixture = File_Operator.DeepCopy(sampleBottleBox);
|
|||
|
|
fixture.IsEmpty = false; fixture.IsUseFinsh = false; fixture.IsDoseFinish = false;
|
|||
|
|
break;
|
|||
|
|
case BoxTypeEnum._5mL样品工装:
|
|||
|
|
SampleBottleBoxModel sampleBottleBox_5 = e as SampleBottleBoxModel;
|
|||
|
|
sampleBottleBox_5.SampleBottleType = SampleBottleTypeEnum._5mL;
|
|||
|
|
for (int i = 0; i < sampleBottleBox_5.SampleBottleList.Count; i++)
|
|||
|
|
{
|
|||
|
|
sampleBottleBox_5.SampleBottleList[i].SampleBottleType = SampleBottleTypeEnum._5mL;
|
|||
|
|
sampleBottleBox_5.SampleBottleList[i].bDoseFinish = false;
|
|||
|
|
sampleBottleBox_5.SampleBottleList[i].HaveBottle = true;
|
|||
|
|
sampleBottleBox_5.SampleBottleList[i].SampleBottleLidState = SampleBottleLidStateEnum.Close;
|
|||
|
|
sampleBottleBox_5.SampleBottleList[i].SNCode = string.Empty;
|
|||
|
|
sampleBottleBox_5.SampleBottleList[i].BoxSNCode = sampleBottleBox_5.BoxSNCode;
|
|||
|
|
foreach (var doseflow in sampleBottleBox_5.SampleBottleList[i].MaterialDoseFlowList)
|
|||
|
|
{
|
|||
|
|
doseflow.IsDoseFinish = false;
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
//将工装信息更新到传送平台对应位置
|
|||
|
|
fixture = File_Operator.DeepCopy(sampleBottleBox_5);
|
|||
|
|
fixture.IsEmpty = false; fixture.IsUseFinsh = false; fixture.IsDoseFinish = false;
|
|||
|
|
break;
|
|||
|
|
case BoxTypeEnum._16mL粉末瓶工装:
|
|||
|
|
SourcePowderBottleBoxModel powderbox = e as SourcePowderBottleBoxModel;
|
|||
|
|
powderbox.PowderBottleType = PowderBottleTypeEnum._16mL;
|
|||
|
|
for (int i = 0; i < powderbox.SourcePowderBottleCollection.Count; i++)
|
|||
|
|
{
|
|||
|
|
powderbox.SourcePowderBottleCollection[i].PowderBottleType = PowderBottleTypeEnum._16mL;
|
|||
|
|
powderbox.SourcePowderBottleCollection[i].BoxSNCode = powderbox.BoxSNCode;
|
|||
|
|
powderbox.SourcePowderBottleCollection[i].SNCode = string.Empty;
|
|||
|
|
powderbox.SourcePowderBottleCollection[i].HaveBottle = true;
|
|||
|
|
|
|||
|
|
}
|
|||
|
|
//将工装信息更新到传送平台对应位置
|
|||
|
|
fixture = File_Operator.DeepCopy(powderbox);
|
|||
|
|
fixture.IsEmpty = false; fixture.IsUseFinsh = false; fixture.IsDoseFinish = false;
|
|||
|
|
break;
|
|||
|
|
case BoxTypeEnum._125mL粉末瓶工装:
|
|||
|
|
SourcePowderBottleBoxModel powderbox_125 = e as SourcePowderBottleBoxModel;
|
|||
|
|
powderbox_125.PowderBottleType = PowderBottleTypeEnum._125mL;
|
|||
|
|
for (int i = 0; i < powderbox_125.SourcePowderBottleCollection.Count; i++)
|
|||
|
|
{
|
|||
|
|
powderbox_125.SourcePowderBottleCollection[i].PowderBottleType = PowderBottleTypeEnum._125mL;
|
|||
|
|
powderbox_125.SourcePowderBottleCollection[i].BoxSNCode = powderbox_125.BoxSNCode;
|
|||
|
|
powderbox_125.SourcePowderBottleCollection[i].SNCode = string.Empty;
|
|||
|
|
powderbox_125.SourcePowderBottleCollection[i].HaveBottle = true;
|
|||
|
|
}
|
|||
|
|
fixture = File_Operator.DeepCopy(powderbox_125);
|
|||
|
|
fixture.IsEmpty = false; fixture.IsUseFinsh = false; fixture.IsDoseFinish = false;
|
|||
|
|
break;
|
|||
|
|
case BoxTypeEnum._50uLTip头工装:
|
|||
|
|
TipBoxModel tipBoxModel = e as TipBoxModel;
|
|||
|
|
tipBoxModel.TipType = TipTypeEnum._50UL;
|
|||
|
|
tipBoxModel.BoxId_inDosingStation = pos;
|
|||
|
|
tipBoxModel.HaveBox = true;
|
|||
|
|
for (var i = 0; i < tipBoxModel.TipItems.Count; i++)
|
|||
|
|
{
|
|||
|
|
tipBoxModel.TipItems[i].IsAvailable = true;
|
|||
|
|
}
|
|||
|
|
fixture = File_Operator.DeepCopy(tipBoxModel);
|
|||
|
|
fixture.IsEmpty = false; fixture.IsUseFinsh = false;
|
|||
|
|
break;
|
|||
|
|
case BoxTypeEnum._300uLTip头工装:
|
|||
|
|
TipBoxModel tipBoxModel_300 = e as TipBoxModel;
|
|||
|
|
tipBoxModel_300.TipType = TipTypeEnum._300UL;
|
|||
|
|
tipBoxModel_300.BoxId_inDosingStation = pos;
|
|||
|
|
tipBoxModel_300.HaveBox = true;
|
|||
|
|
for (var i = 0; i < tipBoxModel_300.TipItems.Count; i++)
|
|||
|
|
{
|
|||
|
|
tipBoxModel_300.TipItems[i].IsAvailable = true;
|
|||
|
|
}
|
|||
|
|
fixture = File_Operator.DeepCopy(tipBoxModel_300);
|
|||
|
|
fixture.IsEmpty = false; fixture.IsUseFinsh = false;
|
|||
|
|
break;
|
|||
|
|
case BoxTypeEnum._1000uLTip头工装:
|
|||
|
|
TipBoxModel tipBoxModel_1000 = e as TipBoxModel;
|
|||
|
|
tipBoxModel_1000.TipType = TipTypeEnum._1000UL;
|
|||
|
|
tipBoxModel_1000.BoxId_inDosingStation = pos;
|
|||
|
|
tipBoxModel_1000.HaveBox = true;
|
|||
|
|
for (var i = 0; i < tipBoxModel_1000.TipItems.Count; i++)
|
|||
|
|
{
|
|||
|
|
tipBoxModel_1000.TipItems[i].IsAvailable = true;
|
|||
|
|
}
|
|||
|
|
fixture = File_Operator.DeepCopy(tipBoxModel_1000);
|
|||
|
|
fixture.IsEmpty = false; fixture.IsUseFinsh = false;
|
|||
|
|
break;
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
catch (Exception)
|
|||
|
|
{
|
|||
|
|
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
private async Task SwitchCurrentDoseFlowEx(CancellationToken token)
|
|||
|
|
{
|
|||
|
|
try
|
|||
|
|
{
|
|||
|
|
if (this.StationProp.bRunFinish) return;
|
|||
|
|
var FixtureCacheAreas = workService.ProjectPro.FixtureCacheArea.Where(b => b.FixtureType == BoxTypeEnum._12mL样品工装 || b.FixtureType == BoxTypeEnum._5mL样品工装);
|
|||
|
|
if (_currentDoseFlow == null)
|
|||
|
|
{
|
|||
|
|
//找到第一个没有配置完成的样品工装
|
|||
|
|
BaseBottleBox fixturePosPro = workService.ProjectPro.FixtureCacheArea.FirstOrDefault(b => !b.IsDoseFinish && !b.IsEmpty && (b.FixtureType == BoxTypeEnum._12mL样品工装 || b.FixtureType == BoxTypeEnum._5mL样品工装));
|
|||
|
|
|
|||
|
|
if (fixturePosPro == null) //所有治具工装配置完成
|
|||
|
|
{
|
|||
|
|
this.StationProp.bRunFinish = true; //当前工单配置完成
|
|||
|
|
|
|||
|
|
await RunFinishTaskBackSourceLiquidBottleOrCurrentUsePowderBottle(_currentDoseFlow, token);
|
|||
|
|
_currentDoseFlow = null;
|
|||
|
|
return;
|
|||
|
|
}
|
|||
|
|
else
|
|||
|
|
{
|
|||
|
|
SampleBottleBoxModel sampleBox = fixturePosPro as SampleBottleBoxModel;
|
|||
|
|
//找到工装中 第一个没有配置完成的样品瓶子
|
|||
|
|
SampleBottleModel samplebottle = sampleBox.SampleBottleList.FirstOrDefault(f => f.HaveBottle && !f.bDoseFinish);
|
|||
|
|
if (samplebottle == null)
|
|||
|
|
{
|
|||
|
|
sampleBox.IsDoseFinish = true;
|
|||
|
|
_currentDoseFlow = null;
|
|||
|
|
return;
|
|||
|
|
}
|
|||
|
|
else
|
|||
|
|
{
|
|||
|
|
if (samplebottle.MaterialDoseFlowList.Count == 0)
|
|||
|
|
{
|
|||
|
|
samplebottle.bDoseFinish = true;
|
|||
|
|
_currentDoseFlow = null;
|
|||
|
|
return;
|
|||
|
|
}
|
|||
|
|
MaterialDoseFunctionFlow doseflow = samplebottle.MaterialDoseFlowList.FirstOrDefault(f => !f.IsDoseFinish && f.TargetVolume > 0);
|
|||
|
|
if (doseflow != null)
|
|||
|
|
{
|
|||
|
|
_currentDoseFlow = doseflow;
|
|||
|
|
|
|||
|
|
if (DoseTask_BasedOnCurrentDoseFlow == null || DoseTask_BasedOnCurrentDoseFlow.IsFaulted || DoseTask_BasedOnCurrentDoseFlow.IsCanceled || DoseTask_BasedOnCurrentDoseFlow.IsCompleted)
|
|||
|
|
{
|
|||
|
|
DoseTask_BasedOnCurrentDoseFlow = Task.Run(async () =>
|
|||
|
|
{
|
|||
|
|
await OneMaterialDose(token);
|
|||
|
|
});
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
else
|
|||
|
|
{
|
|||
|
|
samplebottle.bDoseFinish = true;
|
|||
|
|
_currentDoseFlow = null;
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
catch (Exception)
|
|||
|
|
{
|
|||
|
|
throw;
|
|||
|
|
}
|
|||
|
|
finally
|
|||
|
|
{
|
|||
|
|
await Task.Delay(2000);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/// <summary>
|
|||
|
|
/// 切换当前投料流程
|
|||
|
|
/// </summary>
|
|||
|
|
/// <param name="token"></param>
|
|||
|
|
/// <returns></returns>
|
|||
|
|
private async Task SwitchCurrentDoseFlow(CancellationToken token)
|
|||
|
|
{
|
|||
|
|
try
|
|||
|
|
{
|
|||
|
|
if (this.StationProp.bRunFinish) return;
|
|||
|
|
if (_currentDoseFlow == null)
|
|||
|
|
{
|
|||
|
|
//找到第一个没有配置完成的样品工装
|
|||
|
|
BaseBottleBox fixturePosPro = workService.ProjectPro.FixtureCacheArea.FirstOrDefault(b => !b.IsDoseFinish && !b.IsEmpty && (b.FixtureType == BoxTypeEnum._12mL样品工装 || b.FixtureType == BoxTypeEnum._5mL样品工装));
|
|||
|
|
|
|||
|
|
if (fixturePosPro == null) //所有治具工装配置完成
|
|||
|
|
{
|
|||
|
|
this.StationProp.bRunFinish = true; //当前工单配置完成
|
|||
|
|
|
|||
|
|
await RunFinishTaskBackSourceLiquidBottleOrCurrentUsePowderBottle(_currentDoseFlow, token);
|
|||
|
|
_currentDoseFlow = null;
|
|||
|
|
return;
|
|||
|
|
}
|
|||
|
|
else
|
|||
|
|
{
|
|||
|
|
SampleBottleBoxModel sampleBox = fixturePosPro as SampleBottleBoxModel;
|
|||
|
|
//找到工装中 第一个没有配置完成的样品瓶子
|
|||
|
|
SampleBottleModel samplebottle = sampleBox.SampleBottleList.FirstOrDefault(f => f.HaveBottle && !f.bDoseFinish);
|
|||
|
|
if (samplebottle == null)
|
|||
|
|
{
|
|||
|
|
sampleBox.IsDoseFinish = true;
|
|||
|
|
_currentDoseFlow = null;
|
|||
|
|
return;
|
|||
|
|
}
|
|||
|
|
else
|
|||
|
|
{
|
|||
|
|
if (samplebottle.MaterialDoseFlowList.Count == 0)
|
|||
|
|
{
|
|||
|
|
samplebottle.bDoseFinish = true;
|
|||
|
|
_currentDoseFlow = null;
|
|||
|
|
return;
|
|||
|
|
}
|
|||
|
|
MaterialDoseFunctionFlow doseflow = samplebottle.MaterialDoseFlowList.FirstOrDefault(f => !f.IsDoseFinish && f.TargetVolume > 0);
|
|||
|
|
if (doseflow != null)
|
|||
|
|
{
|
|||
|
|
_currentDoseFlow = doseflow;
|
|||
|
|
|
|||
|
|
if (DoseTask_BasedOnCurrentDoseFlow == null || DoseTask_BasedOnCurrentDoseFlow.IsFaulted || DoseTask_BasedOnCurrentDoseFlow.IsCanceled || DoseTask_BasedOnCurrentDoseFlow.IsCompleted)
|
|||
|
|
{
|
|||
|
|
DoseTask_BasedOnCurrentDoseFlow = Task.Run(async () =>
|
|||
|
|
{
|
|||
|
|
await OneMaterialDose(token);
|
|||
|
|
});
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
else
|
|||
|
|
{
|
|||
|
|
samplebottle.bDoseFinish = true;
|
|||
|
|
_currentDoseFlow = null;
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
catch (Exception)
|
|||
|
|
{
|
|||
|
|
throw;
|
|||
|
|
}
|
|||
|
|
finally
|
|||
|
|
{
|
|||
|
|
await Task.Delay(2000);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/// <summary>
|
|||
|
|
/// 从传动平台取工装到 治具缓存区 线程
|
|||
|
|
/// </summary>
|
|||
|
|
/// <param name="token"></param>
|
|||
|
|
/// <returns></returns>
|
|||
|
|
private async Task UploadBoxFromTransferPlateToHCBox(CancellationToken token)
|
|||
|
|
{
|
|||
|
|
while (true)
|
|||
|
|
{
|
|||
|
|
if (workService.ProjectPro.bNoUseBS) break;
|
|||
|
|
if (token.IsCancellationRequested) break;
|
|||
|
|
|
|||
|
|
//从传送平台取样品工装到工装缓存区
|
|||
|
|
if (workService.ProjectPro.TransferArea.Any(f => !f.IsEmpty && (f.FixtureType == BoxTypeEnum._5mL样品工装 || f.FixtureType == BoxTypeEnum._12mL样品工装))
|
|||
|
|
&& workService.ProjectPro.FixtureCacheArea.Any(a => a.IsEmpty && a.BoxId_inDosingStation != 1 && a.BoxId_inDosingStation != 5)) //治具缓存区的 位置1和位置5 只给放原液瓶工装
|
|||
|
|
{
|
|||
|
|
while (await ReadObstructFlag("四轴机械手运行中")
|
|||
|
|
|| await ReadObstructFlag("四轴机械手正在使用传送平台")
|
|||
|
|
|| await ReadObstructFlag("传送平台收到准备上料信号"))
|
|||
|
|
{
|
|||
|
|
await Task.Delay(300);
|
|||
|
|
}
|
|||
|
|
await SetObstructFlag("四轴机械手运行中", true);
|
|||
|
|
await SetObstructFlag("四轴机械手正在使用传送平台", true);
|
|||
|
|
|
|||
|
|
//找到可以搬运的样品工装
|
|||
|
|
BaseBottleBox samplefixture = workService.ProjectPro.TransferArea.FirstOrDefault(f => !f.IsEmpty && (f.FixtureType == BoxTypeEnum._5mL样品工装 || f.FixtureType == BoxTypeEnum._12mL样品工装));
|
|||
|
|
await FourAxisTakeBox((int)BoxAreaEnum._手套箱传送平台, samplefixture.FixtureType, (ushort)samplefixture.BoxId_inDoseUpload, token);
|
|||
|
|
await SetObstructFlag("四轴机械手正在使用传送平台", false);
|
|||
|
|
|
|||
|
|
//找到可以放置的工装缓存位置
|
|||
|
|
BaseBottleBox aimfixture = workService.ProjectPro.FixtureCacheArea.FirstOrDefault(a => a.IsEmpty && a.BoxId_inDosingStation != 1 && a.BoxId_inDosingStation != 5);
|
|||
|
|
await FourAxisPutBox((int)BoxAreaEnum._托盘存放平台, aimfixture.FixtureType, (ushort)aimfixture.BoxId_inDosingStation, token);
|
|||
|
|
|
|||
|
|
//更新信息
|
|||
|
|
aimfixture.IsEmpty = false;
|
|||
|
|
aimfixture.FixtureType = samplefixture.FixtureType;
|
|||
|
|
aimfixture = File_Operator.DeepCopy(samplefixture);
|
|||
|
|
aimfixture.IsDoseFinish = false; aimfixture.IsUseFinsh = false;
|
|||
|
|
|
|||
|
|
samplefixture.IsEmpty = true; samplefixture = null;
|
|||
|
|
|
|||
|
|
await SetObstructFlag("四轴机械手运行中", false);
|
|||
|
|
}
|
|||
|
|
//从传送平台取原液工装到工装缓存区
|
|||
|
|
else if (workService.ProjectPro.TransferArea.Any(f => !f.IsEmpty && f.FixtureType == BoxTypeEnum._40mL原液工装)
|
|||
|
|
&& workService.ProjectPro.FixtureCacheArea.Any(a => a.IsEmpty))
|
|||
|
|
{
|
|||
|
|
while (await ReadObstructFlag("四轴机械手运行中")
|
|||
|
|
|| await ReadObstructFlag("四轴机械手正在使用传送平台")
|
|||
|
|
|| await ReadObstructFlag("传送平台收到准备上料信号"))
|
|||
|
|
{
|
|||
|
|
await Task.Delay(300);
|
|||
|
|
}
|
|||
|
|
await SetObstructFlag("四轴机械手运行中", true);
|
|||
|
|
await SetObstructFlag("四轴机械手正在使用传送平台", true);
|
|||
|
|
//找到可以搬运的原液工装
|
|||
|
|
BaseBottleBox liquidfixture = workService.ProjectPro.TransferArea.FirstOrDefault(f => !f.IsEmpty && f.FixtureType == BoxTypeEnum._40mL原液工装);
|
|||
|
|
await FourAxisTakeBox((int)BoxAreaEnum._手套箱传送平台, liquidfixture.FixtureType, (ushort)liquidfixture.BoxId_inDoseUpload, token);
|
|||
|
|
await SetObstructFlag("四轴机械手正在使用传送平台", false);
|
|||
|
|
|
|||
|
|
//找到可以放置的工装缓存位置
|
|||
|
|
BaseBottleBox aimfixture = workService.ProjectPro.FixtureCacheArea.FirstOrDefault(a => a.IsEmpty);
|
|||
|
|
await FourAxisPutBox((int)BoxAreaEnum._托盘存放平台, aimfixture.FixtureType, (ushort)aimfixture.BoxId_inDosingStation, token);
|
|||
|
|
|
|||
|
|
//更新信息
|
|||
|
|
aimfixture.IsEmpty = false;
|
|||
|
|
aimfixture.FixtureType = liquidfixture.FixtureType;
|
|||
|
|
aimfixture = File_Operator.DeepCopy(liquidfixture);
|
|||
|
|
aimfixture.IsDoseFinish = false;
|
|||
|
|
aimfixture.IsUseFinsh = false;
|
|||
|
|
|
|||
|
|
liquidfixture.IsEmpty = true; liquidfixture = null;
|
|||
|
|
|
|||
|
|
await SetObstructFlag("四轴机械手运行中", false);
|
|||
|
|
}
|
|||
|
|
//从传送平台的粉末工装中 一个一个取粉末瓶 ---扫码---称重---放到缓存料架上
|
|||
|
|
else if (workService.ProjectPro.TransferArea.Any(f => !f.IsEmpty && (f.FixtureType == BoxTypeEnum._16mL粉末瓶工装 || f.FixtureType == BoxTypeEnum._125mL粉末瓶工装))
|
|||
|
|
&& workService.ProjectPro.PowderHeaderCacheArea.Any(f => !f.HaveBottle))
|
|||
|
|
{
|
|||
|
|
BaseBottleBox powderfixture = workService.ProjectPro.TransferArea.FirstOrDefault(f => !f.IsEmpty && (f.FixtureType == BoxTypeEnum._16mL粉末瓶工装 || f.FixtureType == BoxTypeEnum._125mL粉末瓶工装));
|
|||
|
|
SourcePowderBottleBoxModel powderBox = powderfixture as SourcePowderBottleBoxModel;
|
|||
|
|
for (int i = 0; i < powderBox.SourcePowderBottleCollection.Count; i++)
|
|||
|
|
{
|
|||
|
|
SourcePowderBottleModel powderbottle = powderBox.SourcePowderBottleCollection[i];
|
|||
|
|
if (powderbottle.HaveBottle)
|
|||
|
|
{
|
|||
|
|
while (await ReadObstructFlag("四轴机械手运行中")
|
|||
|
|
|| await ReadObstructFlag("四轴机械手正在使用传送平台")
|
|||
|
|
|| await ReadObstructFlag("传送平台收到准备上料信号"))
|
|||
|
|
{
|
|||
|
|
await Task.Delay(300);
|
|||
|
|
}
|
|||
|
|
await SetObstructFlag("四轴机械手运行中", true);
|
|||
|
|
await SetObstructFlag("四轴机械手正在使用传送平台", true);
|
|||
|
|
//四轴机械手从传送平台取粉末加样头
|
|||
|
|
await FourAxisTakePowderHeader((int)BoxAreaEnum._手套箱传送平台, powderfixture.BoxId_inDoseUpload, powderbottle.PosId_InBox, powderBox.PowderBottleType, token);
|
|||
|
|
//四轴机械手运行到扫码位置
|
|||
|
|
await FourAxisGoToScannPos_powder(token, powderbottle);
|
|||
|
|
await SetObstructFlag("四轴机械手正在使用传送平台", false);
|
|||
|
|
|
|||
|
|
|
|||
|
|
|
|||
|
|
//称重
|
|||
|
|
await FourAxisPutPowderHeaderToPreWeight(token);
|
|||
|
|
await preWeight.Peel();
|
|||
|
|
double powderweight = await preWeight.ReadWeightValue();
|
|||
|
|
powderbottle.OriginWeight = powderbottle.RemainWeight = powderweight;
|
|||
|
|
await WriteCommandAsync_FourAxis(PlcPoints_MaterialDose.W_Robot_PreWeightFinish, 1);//回复预称重完成
|
|||
|
|
|
|||
|
|
//四轴机械手放粉末加样头到10个缓存区
|
|||
|
|
SourcePowderBottleModel aimpowderbottle_inhc = workService.ProjectPro.PowderHeaderCacheArea.FirstOrDefault(f => !f.HaveBottle);
|
|||
|
|
powderbottle.Pos_InDosePowderHC = aimpowderbottle_inhc.Pos_InDosePowderHC;
|
|||
|
|
await FourAxisPutPowderHeader((int)BoxAreaEnum._加样头存放平台, 1, aimpowderbottle_inhc.Pos_InDosePowderHC, powderBox.PowderBottleType, token);
|
|||
|
|
|
|||
|
|
//更新信息
|
|||
|
|
aimpowderbottle_inhc = File_Operator.DeepCopy(powderbottle);
|
|||
|
|
aimpowderbottle_inhc.HaveBottle = true;
|
|||
|
|
powderbottle.HaveBottle = false;
|
|||
|
|
|
|||
|
|
await SetObstructFlag("四轴机械手运行中", false);
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
//从传送平台取Tip头工装放到投料站中
|
|||
|
|
else if (workService.ProjectPro.TransferArea.Any(f => !f.IsEmpty && (f.FixtureType == BoxTypeEnum._50uLTip头工装 || f.FixtureType == BoxTypeEnum._300uLTip头工装 || f.FixtureType == BoxTypeEnum._1000uLTip头工装))
|
|||
|
|
&& workService.ProjectPro.TipHeadArea.Any(f => !f.HaveBox))
|
|||
|
|
{
|
|||
|
|
while (await ReadObstructFlag("四轴机械手运行中")
|
|||
|
|
|| await ReadObstructFlag("四轴机械手正在使用传送平台")
|
|||
|
|
|| await ReadObstructFlag("传送平台收到准备上料信号"))
|
|||
|
|
{
|
|||
|
|
await Task.Delay(300);
|
|||
|
|
}
|
|||
|
|
await SetObstructFlag("四轴机械手运行中", true);
|
|||
|
|
await SetObstructFlag("四轴机械手正在使用传送平台", true);
|
|||
|
|
|
|||
|
|
//找到可以搬运的Tip头工装
|
|||
|
|
BaseBottleBox tipfixture = workService.ProjectPro.TransferArea.FirstOrDefault(f => !f.IsEmpty && (f.FixtureType == BoxTypeEnum._50uLTip头工装 || f.FixtureType == BoxTypeEnum._300uLTip头工装 || f.FixtureType == BoxTypeEnum._1000uLTip头工装));
|
|||
|
|
await FourAxisTakeBox((int)BoxAreaEnum._手套箱传送平台, tipfixture.FixtureType, (ushort)tipfixture.BoxId_inDoseUpload, token);
|
|||
|
|
await SetObstructFlag("四轴机械手正在使用传送平台", false);
|
|||
|
|
|
|||
|
|
//放到Tip缓存区域 1-3
|
|||
|
|
TipBoxModel aimtipbox = workService.ProjectPro.TipHeadArea.FirstOrDefault(f => !f.HaveBox);
|
|||
|
|
await FourAxisPutBox((int)BoxAreaEnum._Tip托盘存放平台, tipfixture.FixtureType, (ushort)aimtipbox.BoxId_inDosingStation, token);
|
|||
|
|
|
|||
|
|
//更新信息
|
|||
|
|
aimtipbox.HaveBox = true; aimtipbox = File_Operator.DeepCopy(tipfixture as TipBoxModel);
|
|||
|
|
if (tipfixture.FixtureType == BoxTypeEnum._50uLTip头工装)
|
|||
|
|
{
|
|||
|
|
aimtipbox.TipType = TipTypeEnum._50UL;
|
|||
|
|
}
|
|||
|
|
else if (tipfixture.FixtureType == BoxTypeEnum._300uLTip头工装)
|
|||
|
|
{
|
|||
|
|
aimtipbox.TipType = TipTypeEnum._300UL;
|
|||
|
|
}
|
|||
|
|
else if (tipfixture.FixtureType == BoxTypeEnum._1000uLTip头工装)
|
|||
|
|
{
|
|||
|
|
aimtipbox.TipType = TipTypeEnum._1000UL;
|
|||
|
|
}
|
|||
|
|
tipfixture.IsEmpty = true; tipfixture = null;
|
|||
|
|
await SetObstructFlag("四轴机械手运行中", false);
|
|||
|
|
}
|
|||
|
|
else
|
|||
|
|
{
|
|||
|
|
if (!token.IsCancellationRequested)
|
|||
|
|
await Task.Delay(2000);
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/// <summary>
|
|||
|
|
/// 从载具工装缓存区域 下载具到传送平台
|
|||
|
|
/// </summary>
|
|||
|
|
/// <param name="token"></param>
|
|||
|
|
/// <returns></returns>
|
|||
|
|
private async Task DownloadFixtueBox(CancellationToken token)
|
|||
|
|
{
|
|||
|
|
while (true)
|
|||
|
|
{
|
|||
|
|
if (workService.ProjectPro.bNoUseBS) break;
|
|||
|
|
if (token.IsCancellationRequested) break;
|
|||
|
|
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
private async Task RunFinishTaskBackSourceLiquidBottleOrCurrentUsePowderBottle(MaterialDoseFunctionFlow flow, CancellationToken token)
|
|||
|
|
{
|
|||
|
|
#region 搬回当前原液或者粉末瓶
|
|||
|
|
|
|||
|
|
if (_currentUseSourceLiquidBottle != null && _currentUseSourceLiquidBottle.liquidbottle != null)
|
|||
|
|
{
|
|||
|
|
//四轴机械手取回原液瓶 放到托盘存放平台
|
|||
|
|
//关盖
|
|||
|
|
await CloseBottleLid(token, _currentUseSourceLiquidBottle.liquidbottle, null);
|
|||
|
|
|
|||
|
|
while (await ReadObstructFlag("四轴机械手运行中")
|
|||
|
|
|| await ReadObstructFlag("四轴机械手正在使用传送平台"))
|
|||
|
|
{
|
|||
|
|
await Task.Delay(300);
|
|||
|
|
}
|
|||
|
|
await SetObstructFlag("四轴机械手运行中", true);
|
|||
|
|
//四轴机械手取原液瓶
|
|||
|
|
await FourAxisTakeLiquidBottle(token, (int)BoxAreaEnum._开关盖区域, 0, 0, _currentUseSourceLiquidBottle.liquidbottle);
|
|||
|
|
//四轴机械手放原液瓶到托盘存放平台
|
|||
|
|
|
|||
|
|
await FourAxisPutLiquidBottle(token, (int)BoxAreaEnum._托盘存放平台, _currentUseSourceLiquidBottle.liquidbottleFixture.BoxId_inDosingStation, _currentUseSourceLiquidBottle.liquidbottle.PosId_InBox, _currentUseSourceLiquidBottle.liquidbottle);
|
|||
|
|
|
|||
|
|
_currentUseSourceLiquidBottle = null;
|
|||
|
|
await SetObstructFlag("四轴机械手运行中", false);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
if (_currentUsePowderBottle != null)
|
|||
|
|
{
|
|||
|
|
while (await ReadObstructFlag("四轴机械手运行中")
|
|||
|
|
|| await ReadObstructFlag("四轴机械手正在使用传送平台"))
|
|||
|
|
{
|
|||
|
|
await Task.Delay(300);
|
|||
|
|
}
|
|||
|
|
await SetObstructFlag("四轴机械手运行中", true);
|
|||
|
|
|
|||
|
|
//四轴机械手取回粉末瓶 放到托盘存放平台
|
|||
|
|
await FourAxisTakePowderHeader((int)BoxAreaEnum._自动加样模块内, 1, 1, _currentUsePowderBottle.PowderBottleType, token);
|
|||
|
|
await FourAxisPutPowderHeader((int)BoxAreaEnum._加样头存放平台, 1, _currentUsePowderBottle.Pos_InDosePowderHC, _currentUsePowderBottle.PowderBottleType, token);
|
|||
|
|
_currentUsePowderBottle = null;
|
|||
|
|
await SetObstructFlag("四轴机械手运行中", false);
|
|||
|
|
}
|
|||
|
|
#endregion
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
private async Task GetCurrentUseSourceLiquidBottleOrCurrentUsePowderBottle(MaterialDoseFunctionFlow flow, CancellationToken token)
|
|||
|
|
{
|
|||
|
|
#region 根据当前物料配置流程,搬运当前原液或者粉末瓶
|
|||
|
|
|
|||
|
|
//根据当前物料配置流程,搬运当前原液或者粉末瓶
|
|||
|
|
if (_currentDoseFlow.FunctionFlowType == FunctionTypeEnum.加液体原料)
|
|||
|
|
{
|
|||
|
|
if (_currentUseSourceLiquidBottle != null && _currentUseSourceLiquidBottle.liquidbottle != null)
|
|||
|
|
{
|
|||
|
|
//四轴机械手取回原液瓶 放到托盘存放平台
|
|||
|
|
//关盖
|
|||
|
|
await CloseBottleLid(token, _currentUseSourceLiquidBottle.liquidbottle, null);
|
|||
|
|
|
|||
|
|
while (await ReadObstructFlag("四轴机械手运行中")
|
|||
|
|
|| await ReadObstructFlag("四轴机械手正在使用传送平台"))
|
|||
|
|
{
|
|||
|
|
await Task.Delay(300);
|
|||
|
|
}
|
|||
|
|
await SetObstructFlag("四轴机械手运行中", true);
|
|||
|
|
//四轴机械手取原液瓶
|
|||
|
|
await FourAxisTakeLiquidBottle(token, (int)BoxAreaEnum._开关盖区域, 0, 0, _currentUseSourceLiquidBottle.liquidbottle);
|
|||
|
|
//四轴机械手放原液瓶到托盘存放平台
|
|||
|
|
|
|||
|
|
await FourAxisPutLiquidBottle(token, (int)BoxAreaEnum._托盘存放平台, _currentUseSourceLiquidBottle.liquidbottleFixture.BoxId_inDosingStation, _currentUseSourceLiquidBottle.liquidbottle.PosId_InBox, _currentUseSourceLiquidBottle.liquidbottle);
|
|||
|
|
|
|||
|
|
_currentUseSourceLiquidBottle.liquidbottle.SourceLiquidBottleState = SourceBottleStateEnum.Idl;
|
|||
|
|
_currentUseSourceLiquidBottle = null;
|
|||
|
|
await SetObstructFlag("四轴机械手运行中", false);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
//查找液体原料瓶
|
|||
|
|
_currentUseSourceLiquidBottle = new UseLiquidBottle()
|
|||
|
|
{
|
|||
|
|
liquidbottleFixture = null,
|
|||
|
|
liquidbottle = null,
|
|||
|
|
};
|
|||
|
|
|
|||
|
|
_currentUseSourceLiquidBottle.liquidbottle = workService.ProjectPro.FixtureCacheArea.Where(pos => pos.FixtureType == BoxTypeEnum._40mL原液工装 && pos is SourceLiquidBottleBoxModel)
|
|||
|
|
.Select(pos => (SourceLiquidBottleBoxModel)pos)
|
|||
|
|
.SelectMany(box => box.SourceLiquidBottleCollection)
|
|||
|
|
.FirstOrDefault(bottle => bottle.HaveBottle && bottle.SourceLiquidName.Equals(_currentDoseFlow.UseMaterialName) && bottle.RemainVolume > 2 && bottle.SourceLiquidBottleState == SourceBottleStateEnum.Idl);
|
|||
|
|
|
|||
|
|
if (_currentUseSourceLiquidBottle.liquidbottle == null) { } //跟BS要原液瓶
|
|||
|
|
|
|||
|
|
_currentUseSourceLiquidBottle.liquidbottleFixture = workService.ProjectPro.FixtureCacheArea
|
|||
|
|
.Where(pos => pos is SourceLiquidBottleBoxModel
|
|||
|
|
&& ((SourceLiquidBottleBoxModel)pos).SourceLiquidBottleCollection != null
|
|||
|
|
&& ((SourceLiquidBottleBoxModel)pos).SourceLiquidBottleCollection.Contains(_currentUseSourceLiquidBottle.liquidbottle)).FirstOrDefault();
|
|||
|
|
|
|||
|
|
while (await ReadObstructFlag("四轴机械手运行中")
|
|||
|
|
|| await ReadObstructFlag("四轴机械手正在使用传送平台"))
|
|||
|
|
{
|
|||
|
|
await Task.Delay(300);
|
|||
|
|
}
|
|||
|
|
await SetObstructFlag("四轴机械手运行中", true);
|
|||
|
|
|
|||
|
|
_currentUseSourceLiquidBottle.liquidbottle.SourceLiquidBottleState = SourceBottleStateEnum.Using;
|
|||
|
|
//四轴机械手取原液瓶
|
|||
|
|
await FourAxisTakeLiquidBottle(token, (int)BoxAreaEnum._托盘存放平台, _currentUseSourceLiquidBottle.liquidbottleFixture.BoxId_inDosingStation, _currentUseSourceLiquidBottle.liquidbottle.PosId_InBox, _currentUseSourceLiquidBottle.liquidbottle);
|
|||
|
|
|
|||
|
|
if (_currentUseSourceLiquidBottle.liquidbottle.SNCode.Equals(string.Empty))
|
|||
|
|
{
|
|||
|
|
await FourAxisGoToScannPos_liquid(token, 1, _currentUseSourceLiquidBottle.liquidbottle, null);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
//四轴机械手放原液瓶到开关盖区域
|
|||
|
|
await FourAxisPutLiquidBottle(token, (int)BoxAreaEnum._开关盖区域, 0, 0, _currentUseSourceLiquidBottle.liquidbottle);
|
|||
|
|
await SetObstructFlag("四轴机械手运行中", false);
|
|||
|
|
|
|||
|
|
//开盖
|
|||
|
|
await OpenBottleLid(token, _currentUseSourceLiquidBottle.liquidbottle, null);
|
|||
|
|
}
|
|||
|
|
else if (_currentDoseFlow.FunctionFlowType == FunctionTypeEnum.加固体原料)
|
|||
|
|
{
|
|||
|
|
if (_currentUsePowderBottle != null)
|
|||
|
|
{
|
|||
|
|
while (await ReadObstructFlag("四轴机械手运行中")
|
|||
|
|
|| await ReadObstructFlag("四轴机械手正在使用传送平台"))
|
|||
|
|
{
|
|||
|
|
await Task.Delay(300);
|
|||
|
|
}
|
|||
|
|
await SetObstructFlag("四轴机械手运行中", true);
|
|||
|
|
|
|||
|
|
//四轴机械手取回粉末瓶 放到托盘存放平台
|
|||
|
|
await FourAxisTakePowderHeader((int)BoxAreaEnum._自动加样模块内, 1, 1, _currentUsePowderBottle.PowderBottleType, token);
|
|||
|
|
await FourAxisPutPowderHeader((int)BoxAreaEnum._加样头存放平台, 1, _currentUsePowderBottle.Pos_InDosePowderHC, _currentUsePowderBottle.PowderBottleType, token);
|
|||
|
|
_currentUsePowderBottle.SourcePowderBottleState = SourceBottleStateEnum.Idl;
|
|||
|
|
_currentUsePowderBottle = null;
|
|||
|
|
await SetObstructFlag("四轴机械手运行中", false);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
//查找可用的粉末瓶
|
|||
|
|
_currentUsePowderBottle = workService.ProjectPro.PowderHeaderCacheArea.FirstOrDefault(f => f.HaveBottle && f.SourcePowderName == _currentDoseFlow.UseMaterialName && f.RemainWeight > 1);
|
|||
|
|
|
|||
|
|
if (_currentUsePowderBottle == null) { } //跟BS要粉末
|
|||
|
|
|
|||
|
|
while (await ReadObstructFlag("四轴机械手运行中")
|
|||
|
|
|| await ReadObstructFlag("四轴机械手正在使用传送平台"))
|
|||
|
|
{
|
|||
|
|
await Task.Delay(300);
|
|||
|
|
}
|
|||
|
|
await SetObstructFlag("四轴机械手运行中", true);
|
|||
|
|
_currentUsePowderBottle.SourcePowderBottleState = SourceBottleStateEnum.Using;
|
|||
|
|
//四轴机械手取粉末加样头 放到称重模块中
|
|||
|
|
await FourAxisTakePowderHeader((int)BoxAreaEnum._加样头存放平台, 1, _currentUsePowderBottle.Pos_InDosePowderHC, _currentUsePowderBottle.PowderBottleType, token);
|
|||
|
|
|
|||
|
|
//将粉末头放到梅特勒称重模块中
|
|||
|
|
labxPowderInstrument = await labxService.GetInstruments("自动天平XPR105");
|
|||
|
|
await labxService.StartWaitingForHead(labxPowderInstrument.FirstOrDefault(), "Dosing Head", "Dosing Head");
|
|||
|
|
|
|||
|
|
await FourAxisPutPowderHeader((int)BoxAreaEnum._自动加样模块内, 1, 1, _currentUsePowderBottle.PowderBottleType, token);
|
|||
|
|
await SetObstructFlag("四轴机械手运行中", false);
|
|||
|
|
await labxService.AbortWaitingForHead();
|
|||
|
|
}
|
|||
|
|
#endregion
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/// <summary>
|
|||
|
|
/// 配置流程,由找到的_currentDoseFlow决定具体执行哪个物料的投料流程
|
|||
|
|
/// </summary>
|
|||
|
|
/// <param name="token"></param>
|
|||
|
|
/// <returns></returns>
|
|||
|
|
private async Task OneMaterialDose(CancellationToken token)
|
|||
|
|
{
|
|||
|
|
//找到所有未完成投料的样品工装
|
|||
|
|
List<BaseBottleBox> sampleBoxList = workService.ProjectPro.FixtureCacheArea.Where(f => (f.FixtureType == BoxTypeEnum._12mL样品工装 || f.FixtureType == BoxTypeEnum._5mL样品工装)
|
|||
|
|
&& !f.IsDoseFinish && !f.IsEmpty).ToList();
|
|||
|
|
|
|||
|
|
for (int i = 0; i < sampleBoxList.Count; i++) //对每个未配置完成的样品工装进行投料
|
|||
|
|
{
|
|||
|
|
SampleBottleBoxModel sampleBox = sampleBoxList[i] as SampleBottleBoxModel;
|
|||
|
|
for (int j = 0; j < sampleBox.SampleBottleList.Count; j++)
|
|||
|
|
{
|
|||
|
|
if (!sampleBox.SampleBottleList[j].HaveBottle || sampleBox.SampleBottleList[j].bDoseFinish) continue;
|
|||
|
|
SampleBottleModel sampleBottle = sampleBox.SampleBottleList[j];
|
|||
|
|
MaterialDoseFunctionFlow doseflow = new MaterialDoseFunctionFlow();
|
|||
|
|
doseflow = sampleBottle.MaterialDoseFlowList.FirstOrDefault(f => !f.IsDoseFinish && f.FunctionFlowType == _currentDoseFlow.FunctionFlowType && f.UseMaterialName == _currentDoseFlow.UseMaterialName && f.TargetVolume > 0);
|
|||
|
|
if (doseflow == null) continue;
|
|||
|
|
if (_currentDoseFlow.FunctionFlowType == FunctionTypeEnum.加液体原料)
|
|||
|
|
{
|
|||
|
|
if (_currentUseSourceLiquidBottle == null
|
|||
|
|
|| (_currentUseSourceLiquidBottle.liquidbottle != null &&
|
|||
|
|
(!_currentUseSourceLiquidBottle.liquidbottle.SourceLiquidName.Equals(_currentDoseFlow.UseMaterialName) || _currentUseSourceLiquidBottle.liquidbottle.RemainVolume < 0.5))
|
|||
|
|
)
|
|||
|
|
{
|
|||
|
|
await GetCurrentUseSourceLiquidBottleOrCurrentUsePowderBottle(_currentDoseFlow, token);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
while (await ReadObstructFlag("四轴机械手运行中")
|
|||
|
|
|| await ReadObstructFlag("四轴机械手正在使用传送平台"))
|
|||
|
|
{
|
|||
|
|
await Task.Delay(300);
|
|||
|
|
}
|
|||
|
|
await SetObstructFlag("四轴机械手运行中", true);
|
|||
|
|
|
|||
|
|
//四轴机械手取样品瓶
|
|||
|
|
await FourAxisTakeSampleBottle(token, (int)BoxAreaEnum._托盘存放平台, sampleBoxList[i].BoxId_inDosingStation, sampleBottle.PosId_InBox, sampleBottle);
|
|||
|
|
|
|||
|
|
//如果这个样品瓶 还没有扫过码 四轴机械手到扫码位置,暂时屏蔽
|
|||
|
|
//if (string.IsNullOrEmpty(sampleBottle.SNCode))
|
|||
|
|
//{
|
|||
|
|
// if (sampleBottle.SampleBottleType == SampleBottleTypeEnum._5mL)
|
|||
|
|
// {
|
|||
|
|
// await FourAxisGoToScannPos_liquid(token, 3, null, sampleBottle);
|
|||
|
|
// }
|
|||
|
|
// else
|
|||
|
|
// {
|
|||
|
|
// await FourAxisGoToScannPos_liquid(token, 2, null, sampleBottle);
|
|||
|
|
// }
|
|||
|
|
//}
|
|||
|
|
|
|||
|
|
//四轴机械手放样品瓶到开关盖区域
|
|||
|
|
await FourAxisPutSampleBottle(token, (int)BoxAreaEnum._开关盖区域, 0, 0, sampleBottle);
|
|||
|
|
await SetObstructFlag("四轴机械手运行中", false);
|
|||
|
|
|
|||
|
|
//开盖
|
|||
|
|
await OpenBottleLid(token, null, sampleBottle);
|
|||
|
|
|
|||
|
|
|
|||
|
|
//执行移液枪取Tip头-吸液-分液-丢Tip头流程
|
|||
|
|
await XZ_TakeTip_Absorb_Dispense_DiscardTip(token, doseflow.UseMaterialName, doseflow.TargetVolume, null, sampleBottle);
|
|||
|
|
|
|||
|
|
//更新原液瓶剩余量
|
|||
|
|
_currentUseSourceLiquidBottle.liquidbottle.RemainVolume -= doseflow.TargetVolume / 1000;
|
|||
|
|
doseflow.IsDoseFinish = true;
|
|||
|
|
|
|||
|
|
//关盖
|
|||
|
|
await CloseBottleLid(token, null, sampleBottle);
|
|||
|
|
|
|||
|
|
while (await ReadObstructFlag("四轴机械手运行中")
|
|||
|
|
|| await ReadObstructFlag("四轴机械手正在使用传送平台"))
|
|||
|
|
{
|
|||
|
|
await Task.Delay(300);
|
|||
|
|
}
|
|||
|
|
await SetObstructFlag("四轴机械手运行中", true);
|
|||
|
|
|
|||
|
|
//如果这个样品瓶的配置流程没有配置完成
|
|||
|
|
if (sampleBottle.MaterialDoseFlowList.Any(f => !f.IsDoseFinish))
|
|||
|
|
{
|
|||
|
|
//四轴机械手取样品瓶
|
|||
|
|
await FourAxisTakeSampleBottle(token, (int)BoxAreaEnum._开关盖区域, 0, 0, sampleBottle);
|
|||
|
|
}
|
|||
|
|
else //配置完成 摇匀
|
|||
|
|
{
|
|||
|
|
await ShakeSampleBottle(token, sampleBottle);
|
|||
|
|
sampleBottle.bDoseFinish = true;
|
|||
|
|
//四轴机械手取样品瓶
|
|||
|
|
await FourAxisTakeSampleBottle(token, (int)BoxAreaEnum._开关盖区域, 0, 0, sampleBottle);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
//四轴机械手放样品瓶到托盘存放平台
|
|||
|
|
await FourAxisPutSampleBottle(token, (int)BoxAreaEnum._托盘存放平台, sampleBoxList[i].BoxId_inDosingStation, sampleBottle.PosId_InBox, sampleBottle);
|
|||
|
|
|
|||
|
|
await SetObstructFlag("四轴机械手运行中", false);
|
|||
|
|
}
|
|||
|
|
else if (_currentDoseFlow.FunctionFlowType == FunctionTypeEnum.加固体原料)
|
|||
|
|
{
|
|||
|
|
//执行加固体原料流程
|
|||
|
|
if (_currentUsePowderBottle == null ||
|
|||
|
|
(_currentUsePowderBottle != null && (!_currentUsePowderBottle.SourcePowderName.Equals(_currentDoseFlow.UseMaterialName) || _currentUsePowderBottle.RemainWeight < 0.1))
|
|||
|
|
)
|
|||
|
|
{
|
|||
|
|
await GetCurrentUseSourceLiquidBottleOrCurrentUsePowderBottle(_currentDoseFlow, token);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
while (await ReadObstructFlag("四轴机械手运行中")
|
|||
|
|
|| await ReadObstructFlag("四轴机械手正在使用传送平台"))
|
|||
|
|
{
|
|||
|
|
await Task.Delay(300);
|
|||
|
|
}
|
|||
|
|
await SetObstructFlag("四轴机械手运行中", true);
|
|||
|
|
|
|||
|
|
//四轴机械手取样品瓶
|
|||
|
|
await FourAxisTakeSampleBottle(token, (int)BoxAreaEnum._托盘存放平台, sampleBoxList[i].BoxId_inDosingStation, sampleBottle.PosId_InBox, sampleBottle);
|
|||
|
|
|
|||
|
|
//如果这个样品瓶 还没有扫过码 四轴机械手到扫码位置 //todo:屏蔽扫码
|
|||
|
|
//if (string.IsNullOrEmpty(sampleBottle.SNCode))
|
|||
|
|
//{
|
|||
|
|
// if (sampleBottle.SampleBottleType == SampleBottleTypeEnum._5mL)
|
|||
|
|
// {
|
|||
|
|
// await FourAxisGoToScannPos_liquid(token, 3, null, sampleBottle);
|
|||
|
|
// }
|
|||
|
|
// else
|
|||
|
|
// {
|
|||
|
|
// await FourAxisGoToScannPos_liquid(token, 2, null, sampleBottle);
|
|||
|
|
// }
|
|||
|
|
//}
|
|||
|
|
|
|||
|
|
//四轴机械手放样品瓶到开关盖区域
|
|||
|
|
await FourAxisPutSampleBottle(token, (int)BoxAreaEnum._开关盖区域, 0, 0, sampleBottle);
|
|||
|
|
await SetObstructFlag("四轴机械手运行中", false);
|
|||
|
|
|
|||
|
|
//开盖
|
|||
|
|
await OpenBottleLid(token, null, sampleBottle);
|
|||
|
|
|
|||
|
|
while (await ReadObstructFlag("四轴机械手运行中")
|
|||
|
|
|| await ReadObstructFlag("四轴机械手正在使用传送平台"))
|
|||
|
|
{
|
|||
|
|
await Task.Delay(300);
|
|||
|
|
}
|
|||
|
|
await SetObstructFlag("四轴机械手运行中", true);
|
|||
|
|
|
|||
|
|
await FourAxisTakeSampleBottle(token, (int)BoxAreaEnum._开关盖区域, 0, 0, sampleBottle);
|
|||
|
|
//梅特勒模块开门
|
|||
|
|
await labxService.MTPowderModuleControlStep(labxPowderInstrument.FirstOrDefault(), "Balance Step", "Balance Step", 1);
|
|||
|
|
await FourAxisPutSampleBottle(token, (int)BoxAreaEnum._自动加样模块内, 1, 1, sampleBottle);
|
|||
|
|
await SetObstructFlag("四轴机械手运行中", false);
|
|||
|
|
|
|||
|
|
//梅特勒模块关门
|
|||
|
|
await labxService.MTPowderModuleControlStep(labxPowderInstrument.FirstOrDefault(), "Balance Step", "Balance Step", 0);
|
|||
|
|
double addPowderWeight = 0;
|
|||
|
|
//大99,小125 2~200mg +-0.297mg 200mg-5g 0.297%
|
|||
|
|
addPowderWeight = await labxService.MTPowderModuleAddPowder(labxPowderInstrument.FirstOrDefault(), "Dosing2", "Dosing2", 4, 99m, (decimal)_currentDoseFlow.TargetVolume, (decimal)10, (decimal)10);
|
|||
|
|
_currentUsePowderBottle.RemainWeight -= addPowderWeight / 1000;
|
|||
|
|
//梅特勒模块开门
|
|||
|
|
await labxService.MTPowderModuleControlStep(labxPowderInstrument.FirstOrDefault(), "Balance Step", "Balance Step", 1);
|
|||
|
|
|
|||
|
|
while (await ReadObstructFlag("四轴机械手运行中")
|
|||
|
|
|| await ReadObstructFlag("四轴机械手正在使用传送平台"))
|
|||
|
|
{
|
|||
|
|
await Task.Delay(300);
|
|||
|
|
}
|
|||
|
|
await SetObstructFlag("四轴机械手运行中", true);
|
|||
|
|
await FourAxisTakeSampleBottle(token, (int)BoxAreaEnum._自动加样模块内, 1, 1, sampleBottle);
|
|||
|
|
//梅特勒模块关门
|
|||
|
|
await labxService.MTPowderModuleControlStep(labxPowderInstrument.FirstOrDefault(), "Balance Step", "Balance Step", 0);
|
|||
|
|
await FourAxisPutSampleBottle(token, (int)BoxAreaEnum._开关盖区域, 0, 0, sampleBottle);
|
|||
|
|
await SetObstructFlag("四轴机械手运行中", false);
|
|||
|
|
//关盖
|
|||
|
|
await CloseBottleLid(token, null, sampleBottle);
|
|||
|
|
doseflow.IsDoseFinish = true;
|
|||
|
|
while (await ReadObstructFlag("四轴机械手运行中")
|
|||
|
|
|| await ReadObstructFlag("四轴机械手正在使用传送平台"))
|
|||
|
|
{
|
|||
|
|
await Task.Delay(300);
|
|||
|
|
}
|
|||
|
|
await SetObstructFlag("四轴机械手运行中", true);
|
|||
|
|
|
|||
|
|
//如果这个样品瓶的配置流程没有配置完成
|
|||
|
|
if (sampleBottle.MaterialDoseFlowList.Any(f => !f.IsDoseFinish))
|
|||
|
|
{
|
|||
|
|
//四轴机械手取样品瓶
|
|||
|
|
await FourAxisTakeSampleBottle(token, (int)BoxAreaEnum._开关盖区域, 0, 0, sampleBottle);
|
|||
|
|
}
|
|||
|
|
else //配置完成 摇匀
|
|||
|
|
{
|
|||
|
|
await ShakeSampleBottle(token, sampleBottle);
|
|||
|
|
sampleBottle.bDoseFinish = true;
|
|||
|
|
await FourAxisTakeSampleBottle(token, (int)BoxAreaEnum._开关盖区域, 0, 0, sampleBottle);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
//四轴机械手放样品瓶到托盘存放平台
|
|||
|
|
await FourAxisPutSampleBottle(token, (int)BoxAreaEnum._托盘存放平台, sampleBoxList[i].BoxId_inDosingStation, sampleBottle.PosId_InBox, sampleBottle);
|
|||
|
|
|
|||
|
|
await SetObstructFlag("四轴机械手运行中", false);
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
//这种液体或者粉末 全部样品瓶配置完成
|
|||
|
|
_currentDoseFlow.IsDoseFinish = true; _currentDoseFlow = null;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
private async Task SetObstructFlag(string name, bool value)
|
|||
|
|
{
|
|||
|
|
try
|
|||
|
|
{
|
|||
|
|
if (this.StationProp.ObstructFlagList.TryGetValue(name, out var targetFlag))
|
|||
|
|
{
|
|||
|
|
if (targetFlag != null)
|
|||
|
|
{
|
|||
|
|
lock (targetFlag)
|
|||
|
|
{
|
|||
|
|
targetFlag.flag = value;
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
catch (Exception)
|
|||
|
|
{
|
|||
|
|
//throw;
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
private async Task<bool> ReadObstructFlag(string name, bool value = true, bool bAny = false)
|
|||
|
|
{
|
|||
|
|
try
|
|||
|
|
{
|
|||
|
|
if (!bAny)
|
|||
|
|
{
|
|||
|
|
if (this.StationProp.ObstructFlagList.TryGetValue(name, out var targetFlag))
|
|||
|
|
{
|
|||
|
|
if (targetFlag != null)
|
|||
|
|
{
|
|||
|
|
lock (targetFlag)
|
|||
|
|
{
|
|||
|
|
return targetFlag.flag == value;
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
else if (bAny)
|
|||
|
|
{
|
|||
|
|
foreach (var pair in this.StationProp.ObstructFlagList)
|
|||
|
|
{
|
|||
|
|
if (pair.Key.Contains(name))
|
|||
|
|
{
|
|||
|
|
lock (pair.Value)
|
|||
|
|
{
|
|||
|
|
if (pair.Value.flag == value)
|
|||
|
|
{
|
|||
|
|
return true;
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
catch (Exception)
|
|||
|
|
{
|
|||
|
|
return false;
|
|||
|
|
}
|
|||
|
|
return false;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
#region 和Web 通讯
|
|||
|
|
public async Task<(bool, string)> SendJson_old(string guid, string methodName, string outJson, LogLevel logLevel = LogLevel.Info)
|
|||
|
|
{
|
|||
|
|
var webApiUrl = await this.dataAccessService.LoadEntityAsync<WebApiUrl>(x => x.MethodName == methodName);
|
|||
|
|
var url = webApiUrl?.URL;
|
|||
|
|
if (string.IsNullOrEmpty(url))
|
|||
|
|
{
|
|||
|
|
return (false, "");
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
if (!webApiUrl.IsEnable)
|
|||
|
|
{
|
|||
|
|
return (false, "");
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
try
|
|||
|
|
{
|
|||
|
|
DateTime startTime = DateTime.Now;
|
|||
|
|
|
|||
|
|
// *** 关键修改:将 JSON 字符串解析并重新序列化为标准格式 ***
|
|||
|
|
string finalJsonToSend;
|
|||
|
|
// 尝试将传入的 outJson (一个JSON字符串) 解析为 JsonDocument
|
|||
|
|
using (JsonDocument parsedDoc = JsonDocument.Parse(outJson))
|
|||
|
|
{
|
|||
|
|
// 将解析后的文档重新序列化为标准、格式良好的 JSON 字符串
|
|||
|
|
// 这一步确保了发送的是标准的 JSON 对象格式,而不是一个被当作字符串的JSON
|
|||
|
|
finalJsonToSend = JsonSerializer.Serialize(parsedDoc.RootElement, new JsonSerializerOptions { WriteIndented = false });
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
HttpContent httpContent = new StringContent(finalJsonToSend, Encoding.UTF8, "application/json");
|
|||
|
|
var client = this._httpClientFactory.CreateClient(guid);
|
|||
|
|
HttpResponseMessage response = null;
|
|||
|
|
if (webApiUrl.RequestType == HttpRequestTypeEnum.Post)
|
|||
|
|
response = await client.PostAsync(url, httpContent);
|
|||
|
|
else
|
|||
|
|
response = await client.GetAsync(url);
|
|||
|
|
var content = await response.Content.ReadAsStringAsync();
|
|||
|
|
DateTime endTime = DateTime.Now;
|
|||
|
|
if (!methodName.Equals("error")) //报警信息回调不写入
|
|||
|
|
{
|
|||
|
|
Logger.LogInformation($"{url}发送{finalJsonToSend}返回{content}");
|
|||
|
|
}
|
|||
|
|
return (true, content);
|
|||
|
|
}
|
|||
|
|
catch (Exception ex)
|
|||
|
|
{
|
|||
|
|
this.Logger.LogError(logEvent: LogEvent.Error, message: $"编号:{guid} 方法:{methodName} 站: 发送失败,{ex.Message}", exception: ex);
|
|||
|
|
return (false, "");
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
public async Task<(bool, string)> SendJson(string guid, string methodName, string outJson, LogLevel logLevel = LogLevel.Info)
|
|||
|
|
{
|
|||
|
|
var webApiUrl = await this.dataAccessService.LoadEntityAsync<WebApiUrl>(x => x.MethodName == methodName);
|
|||
|
|
var url = webApiUrl?.URL;
|
|||
|
|
if (string.IsNullOrEmpty(url))
|
|||
|
|
{
|
|||
|
|
return (false, "");
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
if (!webApiUrl.IsEnable)
|
|||
|
|
{
|
|||
|
|
return (false, "");
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
try
|
|||
|
|
{
|
|||
|
|
DateTime starTime = DateTime.Now;
|
|||
|
|
HttpContent httpContent = new StringContent(outJson,Encoding.UTF8, "application/json");
|
|||
|
|
var client = this._httpClientFactory.CreateClient(guid);
|
|||
|
|
HttpResponseMessage response = null;
|
|||
|
|
if (webApiUrl.RequestType == HttpRequestTypeEnum.Post)
|
|||
|
|
response = await client.PostAsync(url, httpContent);
|
|||
|
|
else
|
|||
|
|
response = await client.GetAsync(url);
|
|||
|
|
var content = await response.Content.ReadAsStringAsync();
|
|||
|
|
DateTime endTime = DateTime.Now;
|
|||
|
|
if (!methodName.Equals("error")) //报警信息回调不写入
|
|||
|
|
{
|
|||
|
|
Logger.LogInformation($"{url}发送{outJson}返回{content}");
|
|||
|
|
}
|
|||
|
|
return (true, content);
|
|||
|
|
|
|||
|
|
|
|||
|
|
}
|
|||
|
|
catch (Exception ex)
|
|||
|
|
{
|
|||
|
|
this.Logger.LogError(logEvent: LogEvent.Error, message: $"编号:{guid} 方法:{methodName} 站: 发送失败,{ex.Message}", exception: ex);
|
|||
|
|
return (false, "");
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
#endregion
|
|||
|
|
|
|||
|
|
}
|
|||
|
|
}
|