Dispenser/DispenserDriver.CameraMV/Impl/CameraMVDriver.cs

316 lines
9.3 KiB
C#
Raw Normal View History

2024-08-16 07:20:09 +00:00
using DispenserCommon.Utils;
using DispenserHal.Camera.DTO;
using DispenserHal.Camera.Enum;
using DispenserHal.Camera.Interface;
using DispenserHal.Camera.VO;
using DispenserUI.Exceptions;
using MvCamCtrl.NET;
using MvCamCtrl.NET.CameraParams;
using Serilog;
namespace DispenserDriver.CameraMV.Impl;
public class CameraMVDriver : AbstractCamera
{
private CCameraInfo _cameraInfo;
private cbOutputExdelegate _cbOutputExdelegate;
private readonly CCamera _mvCamera = new();
public CameraMVDriver(string sn, Dictionary<ParamTypeEnum, string> paramMap) : base(sn, paramMap)
{
}
protected override CameraResponseVO DoConnect(long timeout)
{
_cameraInfo = EnumDeviceBySn(SN);
if (_cameraInfo == null) return CameraResponseVO.OfFailed($"无法找到{SN}相机");
if (!CSystem.IsDeviceAccessible(ref _cameraInfo, MV_ACCESS_MODE.MV_ACCESS_CONTROL))
return CameraResponseVO.OfFailed($"{SN}相机不可访问");
var createHandleResult = _mvCamera.CreateHandle(ref _cameraInfo);
if (!IsSuccess(createHandleResult)) return CameraResponseVO.OfFailed($"{SN}创建句柄失败");
var openDeviceResult = _mvCamera.OpenDevice();
if (!IsSuccess(openDeviceResult))
{
_mvCamera.DestroyHandle();
CameraResponseVO.OfFailed($"打开{SN}相机失败");
}
_cbOutputExdelegate = ImageCallbackFunc;
var registerImageCallbackResult =
_mvCamera.RegisterImageCallBackEx(_cbOutputExdelegate, IntPtr.Zero);
if (!IsSuccess(registerImageCallbackResult))
{
Close();
CameraResponseVO.OfFailed("注册回调函数失败");
}
return CameraResponseVO.OfSuccess($"连接{SN}相机成功");
}
protected override CameraResponseVO DoClose()
{
StopSteaming();
_mvCamera.CloseDevice();
_mvCamera.DestroyHandle();
MarkConnect(false);
return CameraResponseVO.OfSuccess($"关闭{SN}相机成功");
}
protected override CameraResponseVO DoStartSteaming()
{
var result = _mvCamera.StartGrabbing();
if (!IsSuccess(result)) return CameraResponseVO.OfFailed($"{SN}开启采集失败,错误码{result}");
Started = true;
return CameraResponseVO.OfSuccess($"{SN}开启采集成功");
}
protected override CameraResponseVO DoStopSteaming()
{
var result = _mvCamera.StopGrabbing();
if (!IsSuccess(result)) return CameraResponseVO.OfFailed($"{SN}关闭采集失败,错误码{result}");
Started = false;
return CameraResponseVO.OfSuccess($"{SN}关闭采集成功");
}
/// <summary>
/// 获取一帧的图像
/// </summary>
/// <returns></returns>
protected override CameraResponseVO DoTokePhoto()
{
var resp = SwitchSoftwareTriggerMode();
// 现切换到软触发模式
if (resp.IsSuccess())
// 进行软触发拍照
SoftwareTrigger();
// 拍完之后切换到硬触发状态
SwitchHardTriggerMode();
return CameraResponseVO.OfSuccess();
}
/// <summary>
/// 开始连续采集
/// </summary>
/// <returns></returns>
protected override CameraResponseVO DoStartCaptureVideo()
{
_mvCamera.SetEnumValue("TriggerMode", 0);
CapturingVideo = true;
return CameraResponseVO.OfSuccess();
}
/// <summary>
/// 停止连续采集
/// </summary>
/// <returns></returns>
protected override CameraResponseVO DoStopCaptureVideo()
{
SetAcquisitionControlToHardTrigger();
CapturingVideo = false;
return CameraResponseVO.OfSuccess();
}
public override bool GetBoolValue(string key)
{
var value = false;
_mvCamera.GetBoolValue(key, ref value);
return value;
}
public override IntValue GetIntValue(string key)
{
var value = new CIntValue();
_mvCamera.GetIntValue(key, ref value);
return BeanUtil.CopyProperties<IntValue>(value);
}
public override StringValue? GetStringValue(string key)
{
var value = new CStringValue();
_mvCamera.GetStringValue(key, ref value);
return BeanUtil.CopyProperties<StringValue>(value);
}
public override EnumItem GetEnumEntrySymbolic(string key, uint supportIndex)
{
var entry = new CEnumEntry();
entry.Value = supportIndex;
_mvCamera.GetEnumEntrySymbolic(key, ref entry);
return BeanUtil.CopyProperties<EnumItem>(entry);
}
public override EnumValue? GetEnumValue(string key)
{
var value = new CEnumValue();
_mvCamera.GetEnumValue(key, ref value);
return BeanUtil.CopyProperties<EnumValue>(value);
}
public override FloatValue? GetFloatValue(string key)
{
var value = new CFloatValue();
_mvCamera.GetFloatValue(key, ref value);
return BeanUtil.CopyProperties<FloatValue>(value);
}
public override CameraResponseVO SwitchHardTriggerMode()
{
SetDigitalIOControlToHardTrigger();
SetAcquisitionControlToHardTrigger();
return CameraResponseVO.OfSuccess();
}
public override CameraResponseVO SwitchContinuousMode()
{
//开启触发模式 0:OFF, 1: ON
_mvCamera.SetEnumValue("TriggerMode", 0);
return CameraResponseVO.OfSuccess();
}
public override CameraResponseVO SwitchSoftwareTriggerMode()
{
//开启触发模式 0:OFF, 1: ON
_mvCamera.SetEnumValue("TriggerMode", 1);
//0:Line0
//1:Line1
//2:Line2
//3.Line3
//4:Counter0
//7:Software
//8:FrequencyConverter
_mvCamera.SetEnumValue("TriggerSource", 7);
return CameraResponseVO.OfSuccess();
}
public override CameraResponseVO SoftwareTrigger()
{
var nRet = _mvCamera.SetCommandValue("TriggerSoftware");
if (CErrorDefine.MV_OK != nRet)
{
Log.Error($"{SN}软触发失败");
return CameraResponseVO.OfFailed($"{SN}软触发失败");
}
return CameraResponseVO.OfSuccess();
}
public override CameraResponseVO SetEnumValue(string strKey, uint nvalue)
{
_mvCamera.SetEnumValue(strKey, nvalue);
return CameraResponseVO.OfSuccess();
}
public override CameraResponseVO SetIntValue(string strKey, long nvalue)
{
_mvCamera.SetIntValue(strKey, nvalue);
return CameraResponseVO.OfSuccess();
}
public override CameraResponseVO SetBoolValue(string strKey, bool nvalue)
{
_mvCamera.SetBoolValue(strKey, nvalue);
return CameraResponseVO.OfSuccess();
}
public override CameraResponseVO SetFloatValue(string strKey, float nvalue)
{
_mvCamera.SetFloatValue(strKey, nvalue);
return CameraResponseVO.OfSuccess();
}
private void SetAcquisitionControlToHardTrigger()
{
//开启触发模式 0:OFF, 1: ON
_mvCamera.SetEnumValue("TriggerMode", 1);
//0:Line0
//1:Line1
//2:Line2
//3.Line3
//4:Counter0
//7:Software
//8:FrequencyConverter
_mvCamera.SetEnumValue("TriggerSource", 0);
//0:RisingEdge 触发上升沿
//1:FallingEdge 下降沿
//2:LevelHigh 高电平
//3:LevelLow 低电平等
_mvCamera.SetEnumValue("TriggerActivation", 0);
}
/// <summary>
/// 光源控制器IO硬触发设置
/// </summary>
private void SetDigitalIOControlToHardTrigger()
{
//IO触发源
//0:Line0
//1:Line1
//2:Line2
//3:Line3
//4:Line4
_mvCamera.SetEnumValue("LineSelector", 1);
//LineMode
//0:Input
//1:Output
//2:Trigger
//8:Strobe 频闪模式
_mvCamera.SetEnumValue("LineMode", 8);
//开启频闪模式
_mvCamera.SetBoolValue("StrobeEnable", true);
}
private void ImageCallbackFunc(IntPtr pData, ref MV_FRAME_OUT_INFO_EX pFrameInfo, IntPtr pUser)
{
var bitmap = _mvCamera.ImageToBitmap(pData, ref pFrameInfo);
Callback(SN, bitmap);
}
private CCameraInfo? EnumDeviceBySn(string sn)
{
var deviceList = new List<CCameraInfo>();
var result = CSystem.EnumDevices(CSystem.MV_GIGE_DEVICE | CSystem.MV_USB_DEVICE, ref deviceList);
if (!IsSuccess(result)) return null;
CCameraInfo _currentCamera = null;
foreach (var cCameraInfo in deviceList)
{
var _sn = FindSn(cCameraInfo);
if (sn.Equals(_sn))
{
_currentCamera = cCameraInfo;
break;
}
}
return _currentCamera;
}
private string FindSn(CCameraInfo cCameraInfo)
{
if (cCameraInfo.nTLayerType == CSystem.MV_USB_DEVICE)
return ((CUSBCameraInfo)cCameraInfo).chSerialNumber;
if (cCameraInfo.nTLayerType == CSystem.MV_GIGE_DEVICE)
return ((CGigECameraInfo)cCameraInfo).chSerialNumber;
if (cCameraInfo.nTLayerType == CSystem.MV_CAMERALINK_DEVICE)
return ((CCamLCameraInfo)cCameraInfo).chSerialNumber;
throw new BizException($"不支持的相机类型{cCameraInfo.nTLayerType}");
}
private bool IsSuccess(int result)
{
return result == CErrorDefine.MV_OK;
}
}