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
{
///
/// PHM6000Series-Sensor
///
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 LineDatas { get; set; } = new List();//存储扫描到的行数据
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;
///
/// 初始化传感器
///
/// 传感器IP
/// 传感器序列号
/// 传感器端口
/// 本系统用于承载图片的控件指针
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 GetLineDatas()
{
LineDatas.Clear();
var o = new List();
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(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.LoadConfig(@path);
}
else
{
config = new PHM6000SensorConfig();
}
//-----------------
PropertyInfo[] props = config.GetType().GetProperties();
foreach (PropertyInfo p in props)
{
//跳过自定义参数
var iscustomAttr = p.GetCustomAttribute();
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.SaveConfig(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();
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();
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 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 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 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(() =>
{
//输入新数据
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 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 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(() =>
{
//输入新数据
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 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 传感器列表模型类
///
/// PHM6000SensorModel
///
[JsonObject(MemberSerialization.OptOut)]
[TypeConverter(typeof(PropertySorter))]
public class PHM6000SensorModel
{
///
/// IP地址
///
[Category("PHM6000SensorModel"), PropertyOrder(2)]
[DisplayName("IP地址")]
[Browsable(true)]
public string IP { get; set; }
///
/// 端口
///
[Category("PHM6000SensorModel"), PropertyOrder(3)]
[DisplayName("端口")]
[Browsable(true)]
public int Port { get; set; }
///
/// 序列号
///
[Category("PHM6000SensorModel"), PropertyOrder(1)]
[DisplayName("序列号")]
[Browsable(true)]
public string SerialNo { get; set; }
///
/// 状态
///
[Category("PHM6000SensorModel"), PropertyOrder(0)]
[DisplayName("状态")]
[Browsable(true)]
public string State { get; set; }
///
/// PHM6000Sensor
///
[Category("PHM6000SensorModel"), PropertyOrder(4)]
[Browsable(false)]
public PHM6000Sensor Sensor { get; set; }
///
/// Model
///
[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;
}
}
}
}