2026-03-30 17:09:29 +09:00

349 lines
14 KiB
C#

using Aurora.Api;
using Aurora.Api.Devices;
using PropertyTools.DataAnnotations;
using System;
using System.Data;
using System.Diagnostics;
using WeldingCommon.Utils;
namespace WeldingCommon.Settings
{
public class LaserPowerCalParam : ISettingItem
{
static DataTable m_centerCalibrationTable;
static DataTable m_ringCalibrationTable;
string m_centerBeamPath;
string m_ringBeamPath;
public enum beamMode { Center = 1, Ring = 2, Error = 3 }
[Newtonsoft.Json.JsonIgnore]
[Browsable(false)]
public DataTable CenterCalibrationTable {
get { return m_centerCalibrationTable; }
set { m_centerCalibrationTable = value; }
}
[Newtonsoft.Json.JsonIgnore]
[Browsable(false)]
public DataTable RingCalibrationTable {
get { return m_ringCalibrationTable; }
set { m_ringCalibrationTable = value; }
}
[Browsable(true)]
[ReadOnly(false)]
[Category("Calibration")]
[InputFilePath]
[DisplayName("PowerCalibrationCenterBeamCSVFile")]
public string PowerCalibrationCenterBeamCSVFile { get; set; }
[Browsable(true)]
[ReadOnly(false)]
[Category("Calibration")]
[InputFilePath]
[DisplayName("PowerCalibrationRingBeamCSVFile")]
public string PowerCalibrationRingBeamCSVFile { get; set; }
[Browsable(true)]
[ReadOnly(true)]
[Category("Calibration")]
[InputFilePath]
[DisplayName("MaxCenterPower")]
static public double MaxCenterPower { get; set; }
[Browsable(true)]
[ReadOnly(true)]
[Category("Calibration")]
[InputFilePath]
[DisplayName("MaxRingPower")]
static public double MaxRingPower { get; set; }
public LaserPowerCalParam()
{
// 초기 설정할 때, CSV 파일을 토대로 Center, Ring Beam을
// 확인하는 부분이 필수적인 듯.
}
public void Initialize(string centerBeamPath, string ringBeamPath)
{
m_centerCalibrationTable = new DataTable("CenterCalibration");
m_ringCalibrationTable = new DataTable("RingCalibration");
LoadTable(centerBeamPath, ringBeamPath);
MaxCenterPower = (double)CenterCalibrationTable.Rows[CenterCalibrationTable.Rows.Count - 1][1];
MaxRingPower = (double)RingCalibrationTable.Rows[RingCalibrationTable.Rows.Count - 1][1];
}
public void InitializeTable(double maxPower, double interval, out DataTable dataTable, uint beam = 0)
{
DataTable m_calibrationTable = new DataTable();
if (beam == (int)beamMode.Error) {
dataTable = m_calibrationTable;
// MessageBox
return;
}
m_calibrationTable.Columns.Add(new DataColumn("Index", typeof(double)));
//m_calibrationTable.Columns.Add(new DataColumn("Voltage", typeof(double)));
m_calibrationTable.Columns.Add(new DataColumn("DesiredPower", typeof(double)));
m_calibrationTable.Columns.Add(new DataColumn("CalibratedPower", typeof(double)));
double index = 0;
DataRow row;
int iRowCount;
object[] rowArray;
while (index < 100) {
row = m_calibrationTable.NewRow();
iRowCount = m_calibrationTable.Rows.Count;
rowArray = new object[3];
//Index Percentage(0 ~ 100 %)
rowArray[0] = index;
//Voltage(0 ~ 10 V)
//rowArray[1] = index / 10;
//Desired Power(0 ~ Max Watt)
rowArray[1] = maxPower * index / 100;
//초기에는 Calibrated Power = Desired Power
rowArray[2] = rowArray[1];
row.ItemArray = rowArray;
m_calibrationTable.Rows.Add(row);
index = index + interval;
}
//마지막 100% 인 경우를 추가
row = m_calibrationTable.NewRow();
iRowCount = m_calibrationTable.Rows.Count;
rowArray = new object[3];
//Index Percentage(0 ~ 100 %)
rowArray[0] = 100;
//Voltage(0 ~ 10 V)
//rowArray[1] = 10;
//Desired Power(0 ~ Max Watt)
rowArray[1] = maxPower;
//Calibrated Power(0 ~ Max Watt)
rowArray[2] = maxPower;
row.ItemArray = rowArray;
m_calibrationTable.Rows.Add(row);
index = index + interval;
dataTable = m_calibrationTable;
}
public void LoadTable(string centerBeamPath, string ringBeamPath)
{
if (true == System.IO.Path.GetExtension(centerBeamPath).ToUpper().Contains("CSV")
&& true == System.IO.Path.GetExtension(ringBeamPath).ToUpper().Contains("CSV")) {
CenterCalibrationTable = ExcelManagementUnit.ImportDataFromCsv(centerBeamPath, true, ',');
RingCalibrationTable = ExcelManagementUnit.ImportDataFromCsv(ringBeamPath, true, ',');
m_centerBeamPath = centerBeamPath;
m_ringBeamPath = ringBeamPath;
} else {
// Message 박스 열기.
}
}
public void ReLoadTable()
{
if (true == System.IO.Path.GetExtension(m_centerBeamPath).ToUpper().Contains("CSV")
&& true == System.IO.Path.GetExtension(m_ringBeamPath).ToUpper().Contains("CSV")) {
CenterCalibrationTable = ExcelManagementUnit.ImportDataFromCsv(m_centerBeamPath, true, ',');
RingCalibrationTable = ExcelManagementUnit.ImportDataFromCsv(m_ringBeamPath, true, ',');
//m_centerBeamPath = centerBeamPath;
//m_ringBeamPath = ringBeamPath;
} else {
// Message 박스 열기.
}
}
public void SaveTable(DataTable dataTable, uint beam = (uint)beamMode.Center)
{
string fileName;
if (beam == (int)beamMode.Center) {
fileName = PowerCalibrationCenterBeamCSVFile;
CenterCalibrationTable = dataTable;
ExcelManagementUnit.ExportToCSV(fileName, CenterCalibrationTable, ",", false);
}
if (beam == (int)beamMode.Ring) {
fileName = PowerCalibrationRingBeamCSVFile;
RingCalibrationTable = dataTable;
ExcelManagementUnit.ExportToCSV(fileName, RingCalibrationTable, ",", false);
}
// if (beam == (int)beamMode.Error) MessageBox
}
public double LinearInterpolation(double x1, double x2, double y1, double y2, double volt)
{
if (Math.Abs(x2 - x1) < Double.Epsilon) // 부동 소수점 비교를 위해 Double.Epsilon 사용
{
// x 값이 변하지 않으므로, y 값의 변화와 무관하게 x1을 반환
return x1;
}
// x : a < c < b, y: f(a) < f(c) < f(b)
double incline = (y2 - y1) / (x2 - x1);
double sol = (volt - y1 + incline * x1) / incline;
return sol;
}
public double CalibrateVoltToVolt(double volt, uint beam = (uint)beamMode.Center)
{
DataTable m_dataTable;
if (beam == (int)beamMode.Center) m_dataTable = CenterCalibrationTable;
else if (beam == (int)beamMode.Ring) m_dataTable = RingCalibrationTable;
else return 0;
int DesiredPower = 0, calibratedIndex = 3;
double x1 = 0, x2 = 0, y1 = 0, y2 = 0;
for (int i = 1; i < m_dataTable.Rows.Count; i++) {
double.TryParse(Convert.ToString(m_dataTable.Rows[i][DesiredPower]), out y2);
if (y1 < volt && volt <= y2) {
double.TryParse(Convert.ToString(m_dataTable.Rows[i - 1][calibratedIndex]), out x1);
double.TryParse(Convert.ToString(m_dataTable.Rows[i][calibratedIndex]), out x2);
//Debug.WriteLine(string.Format("#{0},{1},{2},{3},{4}", x1,x2,y1,y2, Math.Round(LinearInterpolation(x1, x2, y1, y2, power), 0)));
return LinearInterpolation(x1, x2, y1, y2, volt);
} else y1 = y2;
}
return 0;
}
public double CalibrateWattToPercent(double volt, uint beam = (uint)beamMode.Center)
{
DataTable m_dataTable;
if (beam == (int)beamMode.Center) m_dataTable = CenterCalibrationTable;
else if (beam == (int)beamMode.Ring) m_dataTable = RingCalibrationTable;
else return 0;
int percentIndex = 0, calibratedIndex = 2;
double x1 = 0, x2 = 0, y1 = 0, y2 = 0;
for (int i = 1; i < m_dataTable.Rows.Count; i++) {
double.TryParse(Convert.ToString(m_dataTable.Rows[i][calibratedIndex]), out y2);
if (y1 < volt && volt <= y2) {
double.TryParse(Convert.ToString(m_dataTable.Rows[i - 1][percentIndex]), out x1);
double.TryParse(Convert.ToString(m_dataTable.Rows[i][percentIndex]), out x2);
return LinearInterpolation(x1, x2, y1, y2, volt);
} else y1 = y2;
}
return 0;
}
public double CalibratePercentToWatt(double power, uint beam = (uint)beamMode.Center)
{
DataTable m_dataTable;
if (beam == (int)beamMode.Center) m_dataTable = CenterCalibrationTable;
else if (beam == (int)beamMode.Ring) m_dataTable = RingCalibrationTable;
else return 0;
int percentIndex = 0, calibratedIndex = 2;
double x1 = 0, x2 = 0, y1 = 0, y2 = 0;
for (int i = 1; i < m_dataTable.Rows.Count; i++) {
double.TryParse(Convert.ToString(m_dataTable.Rows[i][percentIndex]), out y2);
if (y1 < power && power <= y2) {
double.TryParse(Convert.ToString(m_dataTable.Rows[i - 1][calibratedIndex]), out x1);
double.TryParse(Convert.ToString(m_dataTable.Rows[i][calibratedIndex]), out x2);
return LinearInterpolation(x1, x2, y1, y2, power);
} else y1 = y2;
}
return 0;
}
public int CalibrateWattToWatt(int power, uint beam = (uint)beamMode.Center)
{
DataTable m_dataTable;
if (beam == (int)beamMode.Center) m_dataTable = CenterCalibrationTable;
else if (beam == (int)beamMode.Ring) m_dataTable = RingCalibrationTable;
else return 0;
int DesiredPower = 1, calibratedIndex = 2;
double x1 = 0, x2 = 0, y1 = 0, y2 = 0;
for (int i = 1; i < m_dataTable.Rows.Count; i++)
{
double.TryParse(Convert.ToString(m_dataTable.Rows[i][DesiredPower]), out y2);
if (y1 < power && power <= y2)
{
double.TryParse(Convert.ToString(m_dataTable.Rows[i - 1][calibratedIndex]), out x1);
double.TryParse(Convert.ToString(m_dataTable.Rows[i][calibratedIndex]), out x2);
return (int)Math.Round(LinearInterpolation(x1, x2, y1, y2, power), 0);
}
else y1 = y2;
}
return 0;
}
public double CalibrateWattToMeasuredVoltage(double power, uint beam = (uint)beamMode.Center)
{
DataTable m_dataTable;
if (beam == (int)beamMode.Center) m_dataTable = CenterCalibrationTable;
else if (beam == (int)beamMode.Ring) m_dataTable = RingCalibrationTable;
else return 0;
int DesiredPower = 1, calibratedIndex = 3;
double x1 = 0, x2 = 0, y1 = 0, y2 = 0;
for (int i = 1; i < m_dataTable.Rows.Count; i++) {
double.TryParse(Convert.ToString(m_dataTable.Rows[i][DesiredPower]), out y2);
if (y1 < power && power <= y2) {
double.TryParse(Convert.ToString(m_dataTable.Rows[i - 1][calibratedIndex]), out x1);
double.TryParse(Convert.ToString(m_dataTable.Rows[i][calibratedIndex]), out x2);
//Debug.WriteLine(string.Format("#{0},{1},{2},{3},{4}", x1,x2,y1,y2, Math.Round(LinearInterpolation(x1, x2, y1, y2, power), 0)));
return LinearInterpolation(x1, x2, y1, y2, power);
} else y1 = y2;
}
return 0;
}
public double CalibratePercentToMeasuredVoltage(double power, uint beam = (uint)beamMode.Center)
{
DataTable m_dataTable;
if (beam == (int)beamMode.Center) m_dataTable = CenterCalibrationTable;
else if (beam == (int)beamMode.Ring) m_dataTable = RingCalibrationTable;
else return 0;
int DesiredPower = 0, calibratedIndex = 3;
double x1 = 0, x2 = 0, y1 = 0, y2 = 0;
for (int i = 1; i < m_dataTable.Rows.Count; i++) {
double.TryParse(Convert.ToString(m_dataTable.Rows[i][DesiredPower]), out y2);
if (y1 < power && power <= y2) {
double.TryParse(Convert.ToString(m_dataTable.Rows[i - 1][calibratedIndex]), out x1);
double.TryParse(Convert.ToString(m_dataTable.Rows[i][calibratedIndex]), out x2);
//Debug.WriteLine(string.Format("#{0},{1},{2},{3},{4}", x1,x2,y1,y2, Math.Round(LinearInterpolation(x1, x2, y1, y2, power), 0)));
return LinearInterpolation(x1, x2, y1, y2, power);
} else y1 = y2;
}
return 0;
}
}
}