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 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}关闭采集成功"); } /// /// 获取一帧的图像 /// /// protected override CameraResponseVO DoTokePhoto() { var resp = SwitchSoftwareTriggerMode(); // 现切换到软触发模式 if (resp.IsSuccess()) // 进行软触发拍照 SoftwareTrigger(); // 拍完之后切换到硬触发状态 SwitchHardTriggerMode(); return CameraResponseVO.OfSuccess(); } /// /// 开始连续采集 /// /// protected override CameraResponseVO DoStartCaptureVideo() { _mvCamera.SetEnumValue("TriggerMode", 0); CapturingVideo = true; return CameraResponseVO.OfSuccess(); } /// /// 停止连续采集 /// /// 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(value); } public override StringValue? GetStringValue(string key) { var value = new CStringValue(); _mvCamera.GetStringValue(key, ref value); return BeanUtil.CopyProperties(value); } public override EnumItem GetEnumEntrySymbolic(string key, uint supportIndex) { var entry = new CEnumEntry(); entry.Value = supportIndex; _mvCamera.GetEnumEntrySymbolic(key, ref entry); return BeanUtil.CopyProperties(entry); } public override EnumValue? GetEnumValue(string key) { var value = new CEnumValue(); _mvCamera.GetEnumValue(key, ref value); return BeanUtil.CopyProperties(value); } public override FloatValue? GetFloatValue(string key) { var value = new CFloatValue(); _mvCamera.GetFloatValue(key, ref value); return BeanUtil.CopyProperties(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); } /// /// 光源控制器IO硬触发设置 /// 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(); 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; } }