using LB_SmartVisionCameraSDK;
|
using LB_SmartVisionCameraSDK.PHM6000;
|
using LB_SmartVisionCommon;
|
using Newtonsoft.Json;
|
using System;
|
using System.Collections.Generic;
|
using System.ComponentModel;
|
using System.Linq;
|
using System.Reflection;
|
using System.Reflection.Metadata;
|
using System.Runtime.InteropServices;
|
using System.Text;
|
using System.Threading.Tasks;
|
using System.Windows.Forms;
|
|
namespace LB_SmartVisionCameraDevice.PHM6000
|
{
|
/// <summary>
|
/// PHM6000Series-Sensor
|
/// </summary>
|
public class PHM6000Sensor
|
{
|
public IntPtr Entry { get; set; }//连接传感器的接口
|
public string IP { get; set; }//传感器IP
|
public string SerialNo { get; set; }//传感器序列号
|
public int Port { get; set; }//端口
|
List<byte[]> LineDatas { get; set; } = new List<byte[]>();//存储扫描到的行数据
|
public IntPtr CaliEntry = IntPtr.Zero;//测量标定入口
|
readonly object _lock = new object();
|
readonly object _lockIntPtr = new object();
|
//public PanelControl PointPanel { get; set; }
|
//WaitForm ssm;
|
public int Index { get; set; }//传感器序号,主要用于标定
|
public IntPtr lightPic = IntPtr.Zero;//亮度图
|
public IntPtr deepPic = IntPtr.Zero;//深度图
|
public IntPtr pointPic = IntPtr.Zero;//点云图
|
public IntPtr outlinePic = IntPtr.Zero;//轮廓图
|
public IntPtr outlineMainPic = IntPtr.Zero;//主界面轮廓图
|
public CaliModel CaliModel { get; set; }//测量用参数
|
public CaliOutLine CaliOutLine { get; set; }//测量用参数
|
|
public bool isContinuousScan = false;
|
|
CancellationTokenSource lightCts;
|
CancellationTokenSource deepCts;
|
CancellationTokenSource pointCts;
|
CancellationTokenSource outlineCts;
|
//PILOT2D_FUNC func2d;
|
//VTK3D_FUNC func3d;
|
AcquisitionCallbackZA sendDatacallback;//回调委托(行数据发送给本系统)
|
|
string path = string.Empty;
|
|
//int currentRowNumber = 0;
|
/// <summary>
|
/// 初始化传感器
|
/// </summary>
|
/// <param name="ip">传感器IP</param>
|
/// <param name="serialNo">传感器序列号</param>
|
/// <param name="port">传感器端口</param>
|
/// <param name="localPtr">本系统用于承载图片的控件指针</param>
|
public PHM6000Sensor(string ip, string serialNo, int port, int index/*, WaitForm ssm*/)
|
{
|
this.IP = ip;
|
this.SerialNo = serialNo;
|
this.Port = port;
|
this.Index = index;
|
//this.ssm = ssm;
|
CaliEntry = SysCalibration.CreateSysCalibrationEntry();//测量标定入口
|
}
|
public int GetLineCount()
|
{
|
int count;
|
lock (_lock)
|
{
|
count = LineDatas.Count;
|
}
|
return count;
|
}
|
public List<byte[]> GetLineDatas()
|
{
|
LineDatas.Clear();
|
var o = new List<byte[]>();
|
lock (_lock)
|
{
|
IntPtr pData = IntPtr.Zero;
|
ulong nIndex = 0;
|
//Config config;
|
//if (!IP.Equals("0.0.0.0"))
|
//{
|
// config = GetConfig();
|
//}
|
//else
|
//{
|
// config = new Config();
|
//}
|
uint count = 0;
|
while ((pData = PHM6000Profiler.GetLineDataByIndex(Entry, nIndex)) != IntPtr.Zero)
|
{
|
unsafe
|
{
|
LBLineHeadInfo pInfo = Marshal.PtrToStructure<LBLineHeadInfo>(pData);
|
count = pInfo.nPointCount;
|
}
|
LBLineDataZA lBLineDataZA = new LBLineDataZA
|
{
|
info = new LBLineHeadInfo(),
|
data = new LBPointZA[count]
|
};
|
long length = Marshal.SizeOf(lBLineDataZA) + Marshal.SizeOf(new LBPointZA()) * count;
|
int datacount = int.Parse(length.ToString());
|
byte[] byteArray = new byte[length];
|
Marshal.Copy(pData, byteArray, 0, datacount);
|
LineDatas.Add(byteArray);
|
nIndex++;
|
}
|
o.AddRange(LineDatas);
|
}
|
return o;
|
}
|
IntPtr Temp = IntPtr.Zero;
|
public IntPtr GetLineLastData()
|
{
|
lock (_lock)
|
{
|
IntPtr pData = IntPtr.Zero;
|
|
Temp = IntPtr.Zero;
|
ulong nIndex = 0;
|
uint count = 0;
|
while ((pData = PHM6000Profiler.GetLineDataByIndex(Entry, nIndex)) != IntPtr.Zero)
|
{
|
//Marshal.FreeHGlobal(Temp);
|
Temp = pData;
|
//SysCalibration.AddLineDataArray(CaliEntry, Index, Temp, false, 1);
|
SysCalibration.SetLineDataArray(CaliEntry, Index, Temp);
|
nIndex++;
|
}
|
if (pData == IntPtr.Zero)
|
{
|
|
}
|
}
|
return Temp;
|
}
|
|
#region 创建图片控件
|
public IntPtr CreatePicPtr(IntPtr localPtr, EnumFetchPicType picType)
|
{
|
IntPtr ptr = IntPtr.Zero;
|
PHM6000SensorConfig config;
|
if (!IP.Equals("0.0.0.0"))
|
{
|
config = GetConfig();
|
}
|
else
|
{
|
config = new PHM6000SensorConfig();
|
}
|
switch (picType)
|
{
|
case EnumFetchPicType.light:
|
if (lightPic == IntPtr.Zero)
|
{
|
ptr = Pilot2D.CreatePilot2DEntry(localPtr);
|
Pilot2D.SetImageSize(ptr, 4096, config.ScanLineCount);
|
lightPic = ptr;
|
}
|
break;
|
case EnumFetchPicType.deep:
|
if (deepPic == IntPtr.Zero)
|
{
|
ptr = Pilot2D.CreatePilot2DEntry(localPtr);
|
Pilot2D.SetImageSize(ptr, 4096, config.ScanLineCount);
|
deepPic = ptr;
|
}
|
break;
|
case EnumFetchPicType.pointCloud:
|
if (pointPic == IntPtr.Zero)
|
{
|
ptr = PclEntry.CreatePCLWindow(localPtr);
|
//PclInvoke.RenderPCLWindow(ptr, 800, 600);
|
pointPic = ptr;
|
}
|
break;
|
case EnumFetchPicType.outline:
|
if (outlinePic == IntPtr.Zero)
|
{
|
ptr = Pilot2D.CreatePilot2DEntry(localPtr);
|
Pilot2D.SetImageSize(ptr, 4096, 2048);
|
outlinePic = ptr;
|
}
|
break;
|
case EnumFetchPicType.mainOutLine:
|
if (outlineMainPic == IntPtr.Zero)
|
{
|
ptr = Pilot2D.CreatePilot2DEntry(localPtr);
|
Pilot2D.SetImageSize(ptr, 4096, 2048);
|
outlineMainPic = ptr;
|
}
|
break;
|
}
|
return ptr;
|
}
|
#endregion
|
event AcquisitionCompletedCallback acquisitionCompletedCallback = null;
|
|
public event AcquisitionCompletedCallback acquisitionCompleted = null;
|
|
public event ShowDebugInfoCallback registerShowDebugInfoCallback = null;
|
|
public void RegisterShowDebugInfoCallback(ShowDebugInfoCallback callback)
|
{
|
PHM6000Profiler.RegisterShowDebugInfoCallback(Entry, callback);
|
}
|
|
PILOT2D_FUNC func2d = new PILOT2D_FUNC
|
{
|
AddBarycentreDataZA = Pilot2D.AddBarycentreDataZA,
|
AddDepthData = Pilot2D.AddDepthData,
|
AddIntensityData = Pilot2D.AddIntensityData,
|
ClearAllPoints = Pilot2D.ClearAllPoints,
|
RefreshPilot2D = Pilot2D.RefreshPilot2D,
|
SetImageSize = Pilot2D.SetImageSize,
|
};
|
|
VTK3D_FUNC func3d = new VTK3D_FUNC
|
{
|
AddZAPoints = PclEntry.AddZAPoints,
|
ClearPCLPoints = PclEntry.ClearPCLPoints,
|
GetPointCloudBound = PclEntry.GetPointCloudBound,
|
RenderPCLWindow = PclEntry.RenderPCLWindow,
|
SetLookUpTableRange = PclEntry.SetLookUpTableRange,
|
ShowCubeAxes = PclEntry.ShowCubeAxes,
|
ShowLookUpTable = PclEntry.ShowLookUpTable,
|
UpdatePCLPointColors = PclEntry.UpdatePCLPointColors,
|
};
|
|
public void StartDataProcess()
|
{
|
//SetShowHandles(Entry, lightPic, deepPic, outlinePic, pointPic);
|
acquisitionCompletedCallback += PHM6000Sensor_acquisitionCompletedCallback;
|
|
PHM6000Profiler.SetPilot2dFunc(Entry, func2d);
|
PHM6000Profiler.SetVTK3dFunc(Entry, func3d);
|
PHM6000Profiler.RegisterAcquisitionCompletedCallback(Entry, acquisitionCompletedCallback, new IntPtr());
|
}
|
public void CameraShow()
|
{
|
PHM6000Profiler.SetShowHandles(Entry, lightPic, deepPic, outlinePic, pointPic);
|
}
|
public void MainShow()
|
{
|
PHM6000Profiler.SetShowHandles(Entry, lightPic, deepPic, outlineMainPic, pointPic);
|
}
|
|
public IntPtr hWnd;
|
private void PHM6000Sensor_acquisitionCompletedCallback(IntPtr pInstance, int nOption)
|
{
|
if (nOption == 2)
|
{
|
//显示点云
|
bool result = PclEntry.PostMessage(hWnd, CommonVar.WM_RENDER_VTK, 0, (ulong)pInstance); // m_hMainWnd是主窗口句柄
|
}
|
if (acquisitionCompleted != null)
|
{
|
acquisitionCompleted(pInstance, nOption);
|
}
|
}
|
public IntPtr PInstance;
|
|
|
#region 连接传感器
|
public bool ConnectCamera()
|
{
|
Entry = PHM6000Profiler.CreateCameraEntry();
|
var addr = Encoding.ASCII.GetBytes(IP);
|
var result = PHM6000Profiler.ConnectToCamera(Entry, addr, Port);
|
if (result == 0)
|
{
|
return true;
|
}
|
return false;
|
}
|
#endregion
|
#region 从传感器获取参数配置
|
public PHM6000SensorConfig GetConfig()
|
{
|
//获取参数
|
PHM6000SensorConfig config;
|
if (IP.Equals("0.0.0.0"))
|
{
|
config = new PHM6000SensorConfig();
|
return config;
|
}
|
//先从本地获取配置
|
path = $"{SerialNo}-config.lb";
|
if (File.Exists(path))
|
{
|
config = ConfigManager<PHM6000SensorConfig>.LoadConfig<PHM6000SensorConfig>(@path);
|
}
|
else
|
{
|
config = new PHM6000SensorConfig();
|
}
|
//-----------------
|
PropertyInfo[] props = config.GetType().GetProperties();
|
foreach (PropertyInfo p in props)
|
{
|
//跳过自定义参数
|
var iscustomAttr = p.GetCustomAttribute<IsCustomAttribute>();
|
if (iscustomAttr != null) continue;
|
var nameId = Enum.Parse(typeof(EnumNameId), p.Name);
|
int intValue = 0;
|
double doubleValue = 0;
|
int enumValue = 0;
|
var id = Convert.ToInt32(nameId);
|
var rst = PHM6000Profiler.GetProfilerParameter(Entry, id, ref intValue, ref doubleValue, ref enumValue);
|
if (rst == 0)
|
{
|
if (p.PropertyType == typeof(int))
|
{
|
p.SetValue(config, intValue);
|
}
|
else if (p.PropertyType == typeof(float))
|
{
|
var value = Convert.ToSingle(doubleValue);
|
p.SetValue(config, value);
|
}
|
else
|
{
|
if (p.Name.Equals("ROI"))
|
{
|
|
}
|
else
|
{
|
p.SetValue(config, enumValue);
|
}
|
}
|
}
|
}
|
return config;
|
}
|
#endregion
|
void SetTargetParam(PHM6000SensorConfig config)
|
{
|
TARGET_INFO tARGET_INFO = new TARGET_INFO()
|
{
|
//fHeight = config.fHeight,
|
//fWidth = config.fWidth,
|
//fMarginRangeX = config.fMarginRangeX,
|
//fMarginRangeY = config.fMarginRangeY,
|
//fMarginX = config.fMarginX,
|
//fMarginY = config.fMarginY,
|
//nPartitionX = config.nPartitionX,
|
//nPartitionY = config.nPartitionY,
|
};
|
SysCalibration.SetTargetParameter(CaliEntry, tARGET_INFO);
|
}
|
#region 设置参数
|
public bool SetConfig(PHM6000SensorConfig config)
|
{
|
//将配置保存到本地
|
path = $"{SerialNo}-config.lb";
|
ConfigManager<PHM6000SensorConfig>.SaveConfig<PHM6000SensorConfig>(config, @path);
|
SetTargetParam(config);
|
//-----------
|
|
int result = 0;
|
var type = config.GetType();
|
var propLineScan = type.GetProperty(nameof(config.LineScanTriggerSource));
|
var val = (EnumLineScanTriggerSource)propLineScan.GetValue(config);
|
var props = config.GetType().GetProperties();
|
|
//排除Y轴
|
props = props.Where(d => d.Name != nameof(config.YResolution)).ToArray();
|
//排除不需要的项
|
if (val == EnumLineScanTriggerSource.固定频率)
|
{
|
props = props.Where(d => d.Name != nameof(config.EncoderTriggerDirection) && d.Name != nameof(config.EncoderTriggerInterval) && d.Name != nameof(config.EncoderTriggerSignalCountingMode)).ToArray();
|
}
|
else
|
{
|
props = props.Where(d => d.Name != nameof(config.SoftwareTriggerRate)).ToArray();
|
}
|
foreach (var p in props)
|
{
|
//跳过自定义参数
|
var iscustomAttr = p.GetCustomAttribute<IsCustomAttribute>();
|
if (iscustomAttr != null) continue;
|
//判断是6030传感器还是普通传感器
|
if (SerialNo.StartsWith("LX030") && p.Name == nameof(config.AnalogGain))
|
{
|
continue;
|
}
|
if (!SerialNo.StartsWith("LX030") && p.Name == nameof(config.AnalogGainFor6030))
|
{
|
continue;
|
}
|
var id = Convert.ToInt32(Enum.Parse(typeof(EnumNameId), p.Name));
|
if (p.PropertyType == typeof(int))
|
{
|
var value = Convert.ToInt32(p.GetValue(config));
|
result = PHM6000Profiler.SetProfilerParameter(Entry, id, value, 0, 0);
|
}
|
else if (p.PropertyType == typeof(float))
|
{
|
var value = Convert.ToDouble(p.GetValue(config));
|
result = PHM6000Profiler.SetProfilerParameter(Entry, id, 0, value, 0);
|
}
|
else
|
{
|
|
var value = Convert.ToInt32(p.GetValue(config));
|
result = PHM6000Profiler.SetProfilerParameter(Entry, id, 0, 0, value);
|
//if (p.Name == nameof(config.AnalogGainFor6030))
|
//{
|
// var a = value;
|
//}
|
}
|
if (result == -1)
|
{
|
var disattr = p.GetCustomAttribute<DisplayNameAttribute>();
|
var name = disattr?.DisplayName ?? p.Name;
|
throw new Exception($"设置参数{name}时不成功!");
|
}
|
}
|
var finalResult = PHM6000Profiler.SaveAllParametersToDevice(Entry);
|
if (finalResult != 0)
|
{
|
return false;
|
}
|
return true;
|
}
|
#endregion
|
|
|
|
#region 断开传感器
|
public void DisConnectCamera()
|
{
|
if (IP == "0.0.0.0") return;
|
|
var result = PHM6000Profiler.DisconnectFromCamera(Entry, IP);
|
|
if (result == -1)
|
{
|
AsyncLogHelper.Error("断开摄像头失败!");
|
throw new Exception("断开摄像头失败!");
|
}
|
}
|
public void DestoryCamera()
|
{
|
if (Entry != IntPtr.Zero)
|
{
|
PHM6000Profiler.DestroyCameraEntry(Entry);
|
Entry = IntPtr.Zero;
|
}
|
//if (pointPic != IntPtr.Zero)
|
//{
|
// PclEntry.ClearPCLPoints(pointPic);
|
// PclEntry.DestroyPCLWindow(pointPic);
|
// pointPic = IntPtr.Zero;
|
//}
|
if (lightPic != IntPtr.Zero)
|
{
|
Pilot2D.ClearAllPoints(lightPic);
|
Pilot2D.DestroyPilot2DEntry(lightPic);
|
lightPic = IntPtr.Zero;
|
}
|
if (outlinePic != IntPtr.Zero)
|
{
|
Pilot2D.ClearAllPoints(outlinePic);
|
Pilot2D.DestroyPilot2DEntry(outlinePic);
|
outlinePic = IntPtr.Zero;
|
}
|
if (outlineMainPic != IntPtr.Zero)
|
{
|
Pilot2D.ClearAllPoints(outlineMainPic);
|
Pilot2D.DestroyPilot2DEntry(outlineMainPic);
|
outlineMainPic = IntPtr.Zero;
|
}
|
if (deepPic != IntPtr.Zero)
|
{
|
Pilot2D.ClearAllPoints(deepPic);
|
Pilot2D.DestroyPilot2DEntry(deepPic);
|
deepPic = IntPtr.Zero;
|
}
|
}
|
public void ClearDatas()
|
{
|
//if (pointPic != IntPtr.Zero)
|
//{
|
// PclEntry.ClearPCLPoints(pointPic);
|
//}
|
if (lightPic != IntPtr.Zero)
|
{
|
Pilot2D.ClearAllPoints(lightPic);
|
}
|
if (outlinePic != IntPtr.Zero)
|
{
|
Pilot2D.ClearAllPoints(outlinePic);
|
}
|
if (outlineMainPic != IntPtr.Zero)
|
{
|
Pilot2D.ClearAllPoints(outlineMainPic);
|
}
|
if (deepPic != IntPtr.Zero)
|
{
|
Pilot2D.ClearAllPoints(deepPic);
|
}
|
}
|
#endregion
|
#region 单次采集,启动回调
|
public void StartScan()
|
{
|
if (IP == "0.0.0.0") return;
|
lock (_lock)
|
{
|
LineDatas.Clear();
|
}
|
int result = PHM6000Profiler.SetAcquisitionCallbackZA(Entry, IntPtr.Zero, IntPtr.Zero);//设置数采回调,注意好像没地方有销毁
|
if (result == 0)
|
{
|
AsyncLogHelper.Info("PHM6000Profiler.SetAcquisitionCallbackZA(Entry, IntPtr.Zero, IntPtr.Zero)设置成功!");
|
}
|
else if (result == -1)
|
{
|
AsyncLogHelper.Info("PHM6000Profiler.SetAcquisitionCallbackZA(Entry, IntPtr.Zero, IntPtr.Zero)设置失败!");
|
}
|
result = PHM6000Profiler.SetAcquisitionMode(Entry, 1, 0);//设置数采模式
|
if (result == 0)
|
{
|
AsyncLogHelper.Info("PHM6000Profiler.SetAcquisitionMode(Entry, 1, 0)设置成功!");
|
}
|
else if (result == -1)
|
{
|
AsyncLogHelper.Info("PHM6000Profiler.SetAcquisitionMode(Entry, 1, 0)设置失败!");
|
}
|
result = PHM6000Profiler.StartAcquisition(Entry, 0, 0, 0.0);//开始采集
|
if (result == 0)
|
{
|
AsyncLogHelper.Info("PHM6000Profiler.StartAcquisition(Entry, 0, 0, 0.0)设置成功!");
|
}
|
else if (result == -1)
|
{
|
AsyncLogHelper.Info("PHM6000Profiler.StartAcquisition(Entry, 0, 0, 0.0)设置失败!");
|
}
|
}
|
#endregion
|
|
#region 启动连续采集
|
public void ContinuousScan()
|
{
|
if (IP.Equals("0.0.0.0"))
|
{
|
return;
|
}
|
lock (_lock)
|
{
|
LineDatas.Clear();
|
}
|
int result = PHM6000Profiler.SetAcquisitionCallbackZA(Entry, IntPtr.Zero, IntPtr.Zero);//设置数采回调,注意好像没地方有销毁
|
if (result == 0)
|
{
|
AsyncLogHelper.Info("PHM6000Profiler.SetAcquisitionCallbackZA(Entry, IntPtr.Zero, IntPtr.Zero)设置成功!");
|
}
|
else if (result == -1)
|
{
|
AsyncLogHelper.Info("PHM6000Profiler.SetAcquisitionCallbackZA(Entry, IntPtr.Zero, IntPtr.Zero)设置失败!");
|
}
|
result = PHM6000Profiler.SetAcquisitionMode(Entry, 1, 1);//设置数采模式
|
if (result == 0)
|
{
|
AsyncLogHelper.Info("PHM6000Profiler.SetAcquisitionMode(Entry, 1, 1)设置成功!");
|
}
|
else if (result == -1)
|
{
|
AsyncLogHelper.Info("PHM6000Profiler.SetAcquisitionMode(Entry, 1, 1)设置失败!");
|
}
|
result = PHM6000Profiler.StartAcquisition(Entry, 0, 0, 0.0);//开始采集
|
if (result == 0)
|
{
|
AsyncLogHelper.Info("PHM6000Profiler.StartAcquisition(Entry, 0, 0, 0.0)设置成功!");
|
}
|
else if (result == -1)
|
{
|
AsyncLogHelper.Info("PHM6000Profiler.StartAcquisition(Entry, 0, 0, 0.0)设置失败!");
|
}
|
}
|
#endregion
|
#region 停止采集,停止图片显示
|
public void StopScan()
|
{
|
if (IP != "0.0.0.0")
|
{
|
PHM6000Profiler.StopAcquisition(Entry);
|
}
|
}
|
#endregion
|
|
private void RenderVtk(IntPtr instance)
|
{
|
// 获取当前控件尺寸
|
int width = 800;
|
int height = 600;
|
|
// 调用VTK渲染方法
|
PclEntry.RenderPCLWindow(pointPic, width, height);
|
PclEntry.UpdatePCLPointColors(pointPic, "z");
|
PclEntry.ShowCubeAxes(pointPic, 1);
|
PclEntry.ShowLookUpTable(pointPic);
|
|
// 处理颜色范围
|
double fMin = 0, fMax = 0;
|
if (PclEntry.GetPointCloudBound(pointPic, ref fMin, ref fMax) != 0)
|
{
|
PclEntry.SetLookUpTableRange(pointPic, fMin, fMax);
|
}
|
}
|
|
#region 保存lb3d文件
|
public void SaveLb3dData(string filePath)
|
{
|
try
|
{
|
// 使用GB2312编码文件名
|
Encoding gb2312 = Encoding.GetEncoding("GB2312");
|
byte[] encodedBytes = gb2312.GetBytes(filePath);
|
//byte[] encodedBytes = Encoding.UTF8.GetBytes(filePath);
|
|
// 调用原生保存方法
|
//switch (MainForm.PicModeflg)
|
//{
|
// case 0:
|
// int result0 = Pilot2D.SavePicture(lightPic, encodedBytes);
|
// break;
|
// case 1:
|
// int result1 = PclInvoke.SaveDataToFile(Entry, encodedBytes);
|
// break;
|
//}
|
}
|
catch (EncoderFallbackException)
|
{
|
MessageBox.Show("文件名包含GB2312不支持的字符", "错误", MessageBoxButtons.OK, MessageBoxIcon.Error);
|
}
|
}
|
|
#endregion
|
|
#region
|
// 定义委托和事件
|
public class AcquisitionCompletedEventArgs : EventArgs
|
{
|
public IntPtr Instance { get; set; }
|
public int Option { get; set; }
|
}
|
|
|
// 声明事件
|
public event EventHandler<AcquisitionCompletedEventArgs> AcquisitionCompleted;
|
|
// 触发事件的方法
|
public void OnAcquisitionCompleted(IntPtr pInstance, int nOption)
|
{
|
if (nOption == 2)
|
{
|
int width = 800;
|
int height = 600;
|
|
// 调用VTK渲染方法
|
PclEntry.RenderPCLWindow(pointPic, width, height);
|
PclEntry.UpdatePCLPointColors(pointPic, "z");
|
PclEntry.ShowCubeAxes(pointPic, 1);
|
PclEntry.ShowLookUpTable(pointPic);
|
|
// 处理颜色范围
|
double fMin = 0, fMax = 0;
|
if (PclEntry.GetPointCloudBound(pointPic, ref fMin, ref fMax) != 0)
|
{
|
PclEntry.SetLookUpTableRange(pointPic, fMin, fMax);
|
}
|
}
|
}
|
|
|
#endregion
|
//轮廓图标定
|
public async Task<float[]> StartOutlineCali(string roiTxt)
|
{
|
var config = GetConfig();
|
PARAM_BAR pARAM_BAR = new PARAM_BAR()
|
{
|
Height = config.BarHeight,
|
Width = config.BarWidth,
|
HoleCount = config.BarHoleCount,
|
HoleDiameter = config.BarHoleDiameter,
|
HoleDistance = config.BarHoleDistance,
|
DOF = config.BarDOF,
|
};
|
SENSOR_POSITION stPosition = new SENSOR_POSITION
|
{
|
IsReverse = config.IsReverse,
|
IsOpposite = config.IsOpposite,
|
fStdDistance = config.fStdDistance,
|
fXCenter = config.fXCenter,
|
x = config.x,
|
y = config.y,
|
z = config.z,
|
xAngle = config.xAngle,
|
yAngle = config.yAngle,
|
zAngle = config.zAngle
|
};
|
SysCalibration.SetSensorPosition(CaliEntry, Index, stPosition);
|
var roi = GetROICaliThkiness(roiTxt, config);
|
SysCalibration.SetLineROI(CaliEntry, Index, roi, false);
|
IntPtr lineLastdatas = GetLineLastData();
|
await Task.Run(() =>
|
{
|
bool result = SysCalibration.AlignmentBar(CaliEntry, Index, Constants.TYPE_STATIONARY, pARAM_BAR);
|
});
|
return new float[] { };
|
}
|
|
public async Task StartOutlineDD(string roiTxt)
|
{
|
var config = GetConfig();
|
PARAM_BAR param_bar = new PARAM_BAR()
|
{
|
Height = config.BarHeight,
|
Width = config.BarWidth,
|
HoleCount = config.BarHoleCount,
|
HoleDiameter = config.BarHoleDiameter,
|
HoleDistance = config.BarHoleDistance,
|
DOF = config.BarDOF,
|
};
|
SENSOR_POSITION stPosition = new SENSOR_POSITION
|
{
|
IsReverse = config.IsReverse,
|
IsOpposite = config.IsOpposite,
|
fStdDistance = config.fStdDistance,
|
fXCenter = config.fXCenter,
|
x = config.x,
|
y = config.y,
|
z = config.z,
|
xAngle = config.xAngle,
|
yAngle = config.yAngle,
|
zAngle = config.zAngle
|
};
|
SysCalibration.SetSensorPosition(CaliEntry, Index, stPosition);
|
var roi = GetROICaliThkiness(roiTxt, config);
|
SysCalibration.SetLineROI(CaliEntry, Index, roi, false);
|
IntPtr lineLastdatas = GetLineLastData();
|
//var linedata = linedatas[linedatas.Count - 1];
|
//var ptr = Marshal.AllocHGlobal(linedata.Length);
|
//Marshal.Copy(linedata, 0, ptr, linedata.Length);
|
//Marshal.FreeHGlobal(lineLastdatas);
|
//await Task.Run(() =>
|
//{
|
// bool result = SysCalibration.AlignmentBar(CaliEntry, Index, SysCalibration.TYPE_STATIONARY, pARAM_BAR);
|
//});
|
}
|
|
public async Task<float> MeasureDistanceOutLine()
|
{
|
var config = GetConfig();
|
SENSOR_POSITION sENSOR_POSITION = new SENSOR_POSITION
|
{
|
IsReverse = config.IsReverse,
|
IsOpposite = config.IsOpposite,
|
fStdDistance = config.fStdDistance,
|
fXCenter = config.fXCenter,
|
x = config.x,
|
y = config.y,
|
z = config.z,
|
xAngle = config.xAngle,
|
yAngle = config.yAngle,
|
zAngle = config.zAngle
|
};
|
SysCalibration.SetSensorPosition(CaliEntry, Index, sENSOR_POSITION);//设置传感器位置
|
SysCalibration.SetRate(CaliEntry, Index, config.XAxisResolution / 1000, config.YResolution / 1000);
|
SysCalibration.ClearData(CaliEntry, Index);//清除以前数据
|
var r = await Task.Run<float>(() =>
|
{
|
//输入新数据
|
unsafe
|
{
|
IntPtr pdata = IntPtr.Zero;
|
|
if (sline + eline != 0 && eline > sline)
|
{
|
for (ulong i = sline; i < eline; i++)
|
{
|
bool useEncoder = false;
|
if (config.LineScanTriggerSource == EnumLineScanTriggerSource.编码器) useEncoder = true;
|
//使用了引用,什么时候完成使用?如果长时间,代码会有内存风险
|
pdata = PHM6000Profiler.GetLineDataByIndex(Entry, i);
|
if (pdata == IntPtr.Zero)
|
break;
|
SysCalibration.AddLineDataArray(CaliEntry, Index, pdata, useEncoder, 1);//最后个参数是什么意思
|
}
|
}
|
else
|
{
|
ulong nindex = 0;
|
|
while ((pdata = PHM6000Profiler.GetLineDataByIndex(Entry, nindex)) != IntPtr.Zero)
|
{
|
bool useEncoder = false;
|
if (config.LineScanTriggerSource == EnumLineScanTriggerSource.编码器) useEncoder = true;
|
//使用了引用,什么时候完成使用?如果长时间,代码会有内存风险
|
SysCalibration.AddLineDataArray(CaliEntry, Index, pdata, useEncoder, 1);//最后个参数是什么意思
|
nindex++;
|
}
|
}
|
}
|
SetTargetParam(config);//设置目标测量参数
|
//var result = SysCalibration.MeasureDistance(CaliEntry);
|
float measuredValue = SysCalibration.MeasureTargetHigh(CaliEntry, Index);
|
var result = (float)Math.Round(measuredValue, 3);
|
return result;
|
});
|
return r;
|
}
|
|
public async Task<float[,]> MeasureOutLineThickness()
|
{
|
var result = await Task.Run(() =>
|
{
|
var config = GetConfig();
|
SetTargetParam(config);//设置目标测量参数
|
float[,] datas = new float[config.nPartitionX, config.nPartitionY];
|
data = new float[config.nPartitionX * config.nPartitionY];
|
int number = 0;
|
for (int i = 0; i < config.nPartitionX; i++)
|
{
|
for (int j = 0; j < config.nPartitionY; j++)
|
{
|
number++;
|
float measuredValue = SysCalibration.MeasureRoiHigh(CaliEntry, Index, number);
|
// 保留3位小数
|
datas[i, j] = (float)Math.Round(measuredValue, 3);
|
}
|
}
|
|
//lBCMap = SysCalibration.GetDepthMap(CaliEntry, Index, 4);
|
return datas;
|
});
|
return result;
|
}
|
|
|
|
|
//二维图标定
|
public async Task StartLiaghtAndDeepCali(CaliModel caliModel)
|
{
|
//LBLineDataZA lBLineDataZA = new LBLineDataZA();
|
|
SENSOR_POSITION sENSOR_POSITION = new SENSOR_POSITION
|
{
|
IsReverse = caliModel.IsReverse,
|
IsOpposite = caliModel.IsOpposite,
|
fStdDistance = caliModel.fStdDistance,
|
fXCenter = caliModel.fXCenter,
|
x = caliModel.x,
|
y = caliModel.y,
|
z = caliModel.z,
|
xAngle = caliModel.xAngle,
|
yAngle = caliModel.yAngle,
|
zAngle = caliModel.zAngle,
|
};
|
var config = GetConfig();
|
PARAM_BOARD pARAM_BOARD = new PARAM_BOARD()
|
{
|
//Height = config.Height,
|
//Width = config.Width,
|
//HoleDiameter = config.HoleDiameter,
|
//HoleDistance = config.HoleDistance,
|
//LocationHoleX1 = config.LocationHoleX1,
|
//LocationHoleX2 = config.LocationHoleX2,
|
//LocationHoleY1 = config.LocationHoleY1,
|
//LocationHoleY2 = config.LocationHoleY2,
|
};
|
|
|
|
SysCalibration.SetSensorPosition(CaliEntry, Index, sENSOR_POSITION);//设置传感器位置
|
var roi = caliModel.Plane.Split(',');
|
|
var roi1 = GetROI(caliModel.Plane, config);
|
var roi2 = GetROI(caliModel.Hole1, config);
|
var roi3 = GetROI(caliModel.Hole2, config);
|
var roi4 = GetROI(caliModel.Hole3, config);
|
|
SysCalibration.SetRate(CaliEntry, Index, config.XAxisResolution / 1000, config.YResolution / 1000);
|
SysCalibration.SetFlatROI(CaliEntry, Index, roi1, true);
|
SysCalibration.SetHoleROI(CaliEntry, Index, 0, roi2, true);
|
SysCalibration.SetHoleROI(CaliEntry, Index, 1, roi3, true);
|
SysCalibration.SetHoleROI(CaliEntry, Index, 2, roi4, true);
|
SysCalibration.SetBoardParameter(CaliEntry, pARAM_BOARD);
|
SysCalibration.ClearData(CaliEntry, Index);//清除以前数据
|
await Task.Run(() =>
|
{
|
//修改此段代码
|
//foreach (var item in GetLineDatas())
|
unsafe
|
{
|
IntPtr pdata = IntPtr.Zero;
|
|
//if (sline + eline != 0 && eline > sline)
|
//{
|
// for (ulong i = sline; i < eline; i++)
|
// {
|
// bool useEncoder = false;
|
// if (config.LineScanTriggerSource == EnumLineScanTriggerSource.编码器) useEncoder = true;
|
// //使用了引用,什么时候完成使用?如果长时间,代码会有内存风险
|
// pdata = GetLineDataByIndex(Entry, i);
|
// if (pdata == IntPtr.Zero)
|
// break;
|
// SysCalibration.AddLineDataArray(CaliEntry, Index, pdata, useEncoder, 1);//最后个参数是什么意思
|
// }
|
//}
|
//else
|
{
|
ulong nindex = 0;
|
|
while ((pdata = PHM6000Profiler.GetLineDataByIndex(Entry, nindex)) != IntPtr.Zero)
|
{
|
bool useEncoder = false;
|
if (config.LineScanTriggerSource == EnumLineScanTriggerSource.编码器) useEncoder = true;
|
//使用了引用,什么时候完成使用?如果长时间,代码会有内存风险
|
SysCalibration.AddLineDataArray(CaliEntry, Index, pdata, useEncoder, 1);//最后个参数是什么意思
|
nindex++;
|
}
|
}
|
}
|
SysCalibration.AlignmentMovingFlat(CaliEntry, Index);//下次打开程序时可能会序号错误
|
//SysCalibration.SystemCalibration(caliEntry);//error没有真实的孔,就会卡进程
|
});
|
}
|
|
|
//测量厚度
|
public async Task<float> MeasureDistance()
|
{
|
|
var config = GetConfig();
|
SENSOR_POSITION sENSOR_POSITION = new SENSOR_POSITION
|
{
|
//IsReverse = CaliModel.IsReverse,
|
//IsOpposite = CaliModel.IsOpposite,
|
//fStdDistance = CaliModel.fStdDistance,
|
//fXCenter = CaliModel.fXCenter,
|
//x = CaliModel.x,
|
//y = CaliModel.y,
|
//z = CaliModel.z,
|
//xAngle = CaliModel.xAngle,
|
//yAngle = CaliModel.yAngle,
|
//zAngle = CaliModel.zAngle,
|
};
|
SysCalibration.SetSensorPosition(CaliEntry, Index, sENSOR_POSITION);//设置传感器位置
|
SysCalibration.SetRate(CaliEntry, Index, config.XAxisResolution / 1000, config.YResolution / 1000);
|
SysCalibration.ClearData(CaliEntry, Index);//清除以前数据
|
var r = await Task.Run<float>(() =>
|
{
|
//输入新数据
|
unsafe
|
{
|
IntPtr pdata = IntPtr.Zero;
|
|
if (sline + eline != 0 && eline > sline)
|
{
|
for (ulong i = sline; i < eline; i++)
|
{
|
bool useEncoder = false;
|
if (config.LineScanTriggerSource == EnumLineScanTriggerSource.编码器) useEncoder = true;
|
//使用了引用,什么时候完成使用?如果长时间,代码会有内存风险
|
pdata = PHM6000Profiler.GetLineDataByIndex(Entry, i);
|
if (pdata == IntPtr.Zero)
|
break;
|
SysCalibration.AddLineDataArray(CaliEntry, Index, pdata, useEncoder, 1);//最后个参数是什么意思
|
}
|
}
|
else
|
{
|
ulong nindex = 0;
|
|
while ((pdata = PHM6000Profiler.GetLineDataByIndex(Entry, nindex)) != IntPtr.Zero)
|
{
|
bool useEncoder = false;
|
if (config.LineScanTriggerSource == EnumLineScanTriggerSource.编码器) useEncoder = true;
|
//使用了引用,什么时候完成使用?如果长时间,代码会有内存风险
|
SysCalibration.AddLineDataArray(CaliEntry, Index, pdata, useEncoder, 1);//最后个参数是什么意思
|
nindex++;
|
}
|
}
|
}
|
SetTargetParam(config);//设置目标测量参数
|
//var result = SysCalibration.MeasureDistance(CaliEntry);
|
float measuredValue = SysCalibration.MeasureTargetHigh(CaliEntry, Index);
|
var result = (float)Math.Round(measuredValue, 3);
|
return result;
|
});
|
return r;
|
}
|
|
public static ulong sline = 0;
|
public static ulong eline = 0;
|
|
|
public static IntPtr lBCMap = IntPtr.Zero;
|
public static float[] data = null;
|
|
//测量凹凸
|
public async Task<float[,]> MeasureUneven()
|
{
|
|
var result = await Task.Run(() =>
|
{
|
var config = GetConfig();
|
//SENSOR_POSITION sENSOR_POSITION = new SENSOR_POSITION
|
//{
|
// IsReverse = CaliModel.IsReverse,
|
// IsOpposite = CaliModel.IsOpposite,
|
// fStdDistance = CaliModel.fStdDistance,
|
// fXCenter = CaliModel.fXCenter,
|
// x = CaliModel.x,
|
// y = CaliModel.y,
|
// z = CaliModel.z,
|
// xAngle = CaliModel.xAngle,
|
// yAngle = CaliModel.yAngle,
|
// zAngle = CaliModel.zAngle,
|
//};
|
//SysCalibration.SetSensorPosition(CaliEntry, Index, sENSOR_POSITION);//设置传感器位置
|
//SysCalibration.SetRate(CaliEntry, Index, config.XAxisResolution / 1000, config.YResolution / 1000);
|
//SysCalibration.ClearData(CaliEntry, Index);//清除以前数据
|
|
////输入新数据
|
//unsafe
|
//{
|
// IntPtr pdata = IntPtr.Zero;
|
|
// if (sline + eline != 0 && eline > sline)
|
// {
|
// for (ulong i = sline; i < eline; i++)
|
// {
|
// bool useEncoder = false;
|
// if (config.LineScanTriggerSource == EnumLineScanTriggerSource.编码器) useEncoder = true;
|
// //使用了引用,什么时候完成使用?如果长时间,代码会有内存风险
|
// pdata = GetLineDataByIndex(Entry, i);
|
// if (pdata == IntPtr.Zero)
|
// break;
|
// SysCalibration.AddLineDataArray(CaliEntry, Index, pdata, useEncoder, 1);//最后个参数是什么意思
|
// }
|
// }
|
// else
|
// {
|
// ulong nindex = 0;
|
|
// while ((pdata = GetLineDataByIndex(Entry, nindex)) != IntPtr.Zero)
|
// {
|
// bool useEncoder = false;
|
// if (config.LineScanTriggerSource == EnumLineScanTriggerSource.编码器) useEncoder = true;
|
// //使用了引用,什么时候完成使用?如果长时间,代码会有内存风险
|
// SysCalibration.AddLineDataArray(CaliEntry, Index, pdata, useEncoder, 1);//最后个参数是什么意思
|
// nindex++;
|
// }
|
// }
|
//}
|
SetTargetParam(config);//设置目标测量参数
|
float[,] datas = new float[config.nPartitionX, config.nPartitionY];
|
data = new float[config.nPartitionX * config.nPartitionY];
|
int number = 0;
|
for (int i = 0; i < config.nPartitionX; i++)
|
{
|
for (int j = 0; j < config.nPartitionY; j++)
|
{
|
number++;
|
float measuredValue = SysCalibration.MeasureRoiHigh(CaliEntry, Index, number);
|
// 保留3位小数
|
datas[i, j] = (float)Math.Round(measuredValue, 3);
|
}
|
}
|
|
//lBCMap = SysCalibration.GetDepthMap(CaliEntry, Index, 4);
|
return datas;
|
});
|
return result;
|
}
|
|
|
LB_ROI GetROI(string s, PHM6000SensorConfig config)
|
{
|
|
var roi = s.Split(',');
|
LB_ROI lB_ROI = new LB_ROI()
|
{
|
left = Convert.ToInt32(roi[0]) * config.XAxisResolution / 1000,
|
top = Convert.ToInt32(roi[1]) * config.YResolution / 1000,
|
right = Convert.ToInt32(roi[2]) * config.XAxisResolution / 1000,
|
bottom = Convert.ToInt32(roi[3]) * config.YResolution / 1000,
|
// left = Convert.ToInt32(roi[0]) * 4096 / 2048,
|
// top = (int)(325.0 - 225.0 - float.Parse(roi[1]) * (470.0 - 225.0) / (1024.0 - 1.0) + 0.5),
|
// right = Convert.ToInt32(roi[2]) * 4096 / 2048,
|
// bottom = (int)(325.0 - 225.0 - float.Parse(roi[3]) * (470.0 - 225.0) / (1024.0 - 1.0) + 0.5),
|
//};
|
//float fTemp;
|
//if (lB_ROI.left > lB_ROI.right)
|
//{
|
// fTemp = lB_ROI.left;
|
// lB_ROI.left = lB_ROI.right;
|
// lB_ROI.right = fTemp;
|
//}
|
//if (lB_ROI.top > lB_ROI.bottom)
|
//{
|
// fTemp = lB_ROI.top;
|
// lB_ROI.top = lB_ROI.bottom;
|
// lB_ROI.bottom = fTemp;
|
//}
|
};
|
return lB_ROI;
|
}
|
LB_ROI GetROICaliThkiness(string s, PHM6000SensorConfig config)
|
{
|
|
var roi = s.Split(',');
|
LB_ROI lB_ROI = new LB_ROI()
|
{
|
//left = Convert.ToInt32(roi[0]) * config.XAxisResolution / 1000,
|
//top = Convert.ToInt32(roi[1]) * config.YResolution / 1000,
|
//right = Convert.ToInt32(roi[2]) * config.XAxisResolution / 1000,
|
//bottom = Convert.ToInt32(roi[3]) * config.YResolution / 1000,
|
left = Convert.ToInt32(roi[0]) * 4096 / 2048,
|
top = (int)(325.0 - 225.0 - float.Parse(roi[1]) * (470.0 - 225.0) / (1024.0 - 1.0) + 0.5),
|
right = Convert.ToInt32(roi[2]) * 4096 / 2048,
|
bottom = (int)(325.0 - 225.0 - float.Parse(roi[3]) * (470.0 - 225.0) / (1024.0 - 1.0) + 0.5),
|
};
|
float fTemp;
|
if (lB_ROI.left > lB_ROI.right)
|
{
|
fTemp = lB_ROI.left;
|
lB_ROI.left = lB_ROI.right;
|
lB_ROI.right = fTemp;
|
}
|
if (lB_ROI.top > lB_ROI.bottom)
|
{
|
fTemp = lB_ROI.top;
|
lB_ROI.top = lB_ROI.bottom;
|
lB_ROI.bottom = fTemp;
|
}
|
return lB_ROI;
|
}
|
}
|
|
#region 传感器列表模型类
|
|
/// <summary>
|
/// PHM6000SensorModel
|
/// </summary>
|
[JsonObject(MemberSerialization.OptOut)]
|
[TypeConverter(typeof(PropertySorter))]
|
|
public class PHM6000SensorModel
|
{
|
/// <summary>
|
/// IP地址
|
/// </summary>
|
[Category("PHM6000SensorModel"), PropertyOrder(2)]
|
[DisplayName("IP地址")]
|
[Browsable(true)]
|
public string IP { get; set; }
|
/// <summary>
|
/// 端口
|
/// </summary>
|
[Category("PHM6000SensorModel"), PropertyOrder(3)]
|
[DisplayName("端口")]
|
[Browsable(true)]
|
public int Port { get; set; }
|
/// <summary>
|
/// 序列号
|
/// </summary>
|
[Category("PHM6000SensorModel"), PropertyOrder(1)]
|
[DisplayName("序列号")]
|
[Browsable(true)]
|
public string SerialNo { get; set; }
|
/// <summary>
|
/// 状态
|
/// </summary>
|
[Category("PHM6000SensorModel"), PropertyOrder(0)]
|
[DisplayName("状态")]
|
[Browsable(true)]
|
public string State { get; set; }
|
/// <summary>
|
/// PHM6000Sensor
|
/// </summary>
|
[Category("PHM6000SensorModel"), PropertyOrder(4)]
|
[Browsable(false)]
|
public PHM6000Sensor Sensor { get; set; }
|
/// <summary>
|
/// Model
|
/// </summary>
|
[Category("PHM6000SensorModel"), PropertyOrder(5)]
|
[Browsable(false)]
|
public string Model { get; set; }
|
}
|
#endregion
|
|
//采集数据时要显示的图类形
|
public enum EnumFetchPicType
|
{
|
light, deep, pointCloud, outline, mainOutLine
|
}
|
|
public class FloatArrayToIntPtrConverter
|
{
|
public unsafe static IntPtr ConvertFloatArrayToIntPtr(float[] data)
|
{
|
if (data == null || data.Length == 0)
|
{
|
return IntPtr.Zero;
|
}
|
fixed (float* p = data)
|
{
|
return (IntPtr)p;
|
}
|
}
|
}
|
}
|