This commit is contained in:
@@ -402,7 +402,6 @@ namespace 头罩视野.Views
|
||||
//计算
|
||||
private async Task calCurrentangle()
|
||||
{
|
||||
|
||||
await ReadLightBarData();
|
||||
|
||||
int[] lightData;
|
||||
@@ -417,125 +416,70 @@ namespace 头罩视野.Views
|
||||
return;
|
||||
}
|
||||
|
||||
// 打印原始数据(假设灯条顺序:上81,中81,下81)
|
||||
void PrintSegment(int[] data, int start, int length, string title)
|
||||
{
|
||||
int end = Math.Min(start + length, data.Length);
|
||||
var values = data.Skip(start).Take(end - start).ToArray();
|
||||
string first20 = string.Join("", values.Take(20));
|
||||
string last20 = string.Join("", values.Skip(Math.Max(0, values.Length - 20)).Take(20));
|
||||
System.Diagnostics.Debug.WriteLine($"{title} (共{values.Length}个): 前20:{first20} ... 后20:{last20}");
|
||||
}
|
||||
|
||||
System.Diagnostics.Debug.WriteLine("=== 原始灯条数据 ===");
|
||||
PrintSegment(lightData, 0, 81, "上爪灯条");
|
||||
PrintSegment(lightData, 81, 81, "下爪灯条");
|
||||
PrintSegment(lightData, 162, 81, "左右灯条");
|
||||
|
||||
double singleArea = GetArea.CalculateEllipseArea(lightData, _lightPositions);
|
||||
double bottomViewAngle;
|
||||
double bottomViewAngle = GetArea.CalculateBottomViewAngle(lightData, _lightPositions);
|
||||
|
||||
if (tbTest.Content.ToString() == "试样测试")
|
||||
System.Diagnostics.Debug.WriteLine($"角度: {dqangle.Text}, singleArea={singleArea}, bottomViewAngle={bottomViewAngle}");
|
||||
|
||||
// 5. 根据当前测试模式(左眼/右眼/双目),累加面积
|
||||
if (isLeftOnly)
|
||||
{
|
||||
// 修正下爪灯条:填充空洞使连续
|
||||
int startIdx = 81;
|
||||
int endIdx = startIdx + 81;
|
||||
int firstOne = -1, lastOne = -1;
|
||||
for (int i = startIdx; i < endIdx; i++)
|
||||
//System.Diagnostics.Debug.WriteLine($"lightData 实际长度: {lightData.Length}");
|
||||
_leftTotalArea += singleArea;
|
||||
// 实时合并左眼:只要亮过一次,就永久亮
|
||||
|
||||
// 安全获取真实长度
|
||||
int realLength = lightData.Length;
|
||||
|
||||
// 初始化最终数据(永远和 lightData 一样长,不会错)
|
||||
if (_leftFinalData == null || _leftFinalData.Count != realLength)
|
||||
{
|
||||
_leftFinalData = new List<int>(new int[realLength]);
|
||||
}
|
||||
|
||||
for (int i = 0; i < realLength; i++)
|
||||
{
|
||||
if (lightData[i] == 1)
|
||||
{
|
||||
if (firstOne == -1) firstOne = i;
|
||||
lastOne = i;
|
||||
_leftFinalData[i] = 1;
|
||||
}
|
||||
}
|
||||
if (firstOne != -1 && lastOne != -1)
|
||||
{
|
||||
for (int i = firstOne; i <= lastOne; i++)
|
||||
lightData[i] = 1;
|
||||
}
|
||||
|
||||
PrintSegment(lightData, 81, 81, "修正后的下爪灯条");
|
||||
|
||||
// 计算亮灯比例
|
||||
int bottomLampCount = 0;
|
||||
for (int i = startIdx; i < endIdx; i++)
|
||||
if (lightData[i] == 1) bottomLampCount++;
|
||||
double ratio = bottomLampCount / 81.0;
|
||||
bottomViewAngle = 90.0 * ratio;
|
||||
// 可选钳位
|
||||
// if (bottomViewAngle < 52) bottomViewAngle = 52;
|
||||
// if (bottomViewAngle > 60) bottomViewAngle = 60;
|
||||
}
|
||||
else
|
||||
|
||||
else if (isRightOnly)
|
||||
{
|
||||
bottomViewAngle = GetArea.CalculateBottomViewAngle(lightData, _lightPositions);
|
||||
_rightTotalArea += singleArea;
|
||||
int realLength = lightData.Length;
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
System.Diagnostics.Debug.WriteLine($"角度: {dqangle.Text}, singleArea={singleArea}, bottomViewAngle={bottomViewAngle}");
|
||||
|
||||
// 5. 根据当前测试模式(左眼/右眼/双目),累加面积
|
||||
if (isLeftOnly)
|
||||
if (_rightFinalData == null || _rightFinalData.Count != realLength)
|
||||
{
|
||||
//System.Diagnostics.Debug.WriteLine($"lightData 实际长度: {lightData.Length}");
|
||||
_leftTotalArea += singleArea;
|
||||
// 实时合并左眼:只要亮过一次,就永久亮
|
||||
|
||||
// 安全获取真实长度
|
||||
int realLength = lightData.Length;
|
||||
|
||||
// 初始化最终数据(永远和 lightData 一样长,不会错)
|
||||
if (_leftFinalData == null || _leftFinalData.Count != realLength)
|
||||
{
|
||||
_leftFinalData = new List<int>(new int[realLength]);
|
||||
}
|
||||
|
||||
for (int i = 0; i < realLength; i++)
|
||||
{
|
||||
if (lightData[i] == 1)
|
||||
{
|
||||
_leftFinalData[i] = 1;
|
||||
}
|
||||
}
|
||||
|
||||
_rightFinalData = new List<int>(new int[realLength]);
|
||||
}
|
||||
|
||||
else if (isRightOnly)
|
||||
for (int i = 0; i < realLength; i++)
|
||||
{
|
||||
_rightTotalArea += singleArea;
|
||||
int realLength = lightData.Length;
|
||||
|
||||
if (_rightFinalData == null || _rightFinalData.Count != realLength)
|
||||
if (lightData[i] == 1)
|
||||
{
|
||||
_rightFinalData = new List<int>(new int[realLength]);
|
||||
}
|
||||
|
||||
for (int i = 0; i < realLength; i++)
|
||||
{
|
||||
if (lightData[i] == 1)
|
||||
{
|
||||
_rightFinalData[i] = 1;
|
||||
}
|
||||
_rightFinalData[i] = 1;
|
||||
}
|
||||
}
|
||||
|
||||
// 6. 更新下方视野的最大值(取所有角度中最大的)
|
||||
if (bottomViewAngle > maxBottomViewAngle)
|
||||
maxBottomViewAngle = bottomViewAngle;
|
||||
|
||||
await Dispatcher.InvokeAsync(() =>
|
||||
{
|
||||
zmsyarea.Text = _leftTotalArea.ToString("0");
|
||||
ymsyarea.Text = _rightTotalArea.ToString("0");
|
||||
smsyarea.Text = _binocularTotalArea.ToString("0");
|
||||
xfsyarea.Text = maxBottomViewAngle.ToString("0");
|
||||
});
|
||||
}
|
||||
|
||||
// 6. 更新下方视野的最大值(取所有角度中最大的)
|
||||
if (bottomViewAngle > maxBottomViewAngle)
|
||||
maxBottomViewAngle = bottomViewAngle;
|
||||
|
||||
await Dispatcher.InvokeAsync(() =>
|
||||
{
|
||||
zmsyarea.Text = _leftTotalArea.ToString("0");
|
||||
ymsyarea.Text = _rightTotalArea.ToString("0");
|
||||
smsyarea.Text = _binocularTotalArea.ToString("0");
|
||||
xfsyarea.Text = maxBottomViewAngle.ToString("0");
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
//数据共享
|
||||
private async void ShowAreaData()
|
||||
|
||||
@@ -946,7 +890,7 @@ namespace 头罩视野.Views
|
||||
_timer?.Stop();
|
||||
_cts?.Cancel();
|
||||
_cts = null;
|
||||
|
||||
CloseSerialModbus(); // 释放串口
|
||||
_modbusMaster.WriteSingleCoil(1, 1, false);
|
||||
|
||||
_modbusMaster.WriteSingleCoil(1, 0, false);
|
||||
@@ -956,112 +900,125 @@ namespace 头罩视野.Views
|
||||
|
||||
|
||||
private IModbusMaster _serialMaster;
|
||||
private SerialPort _serialPort; // 保存串口对象以便关闭
|
||||
private bool _isSerialInitialized = false;
|
||||
|
||||
private void InitSerialModbus()
|
||||
{
|
||||
if (_isSerialInitialized) return; // 已初始化,不再重复
|
||||
|
||||
try
|
||||
{
|
||||
// 请根据实际 COM 口和参数修改
|
||||
string portName = "COM3"; // 实际串口号
|
||||
string portName = "COM3";
|
||||
int baudRate = 9600;
|
||||
Parity parity = Parity.None;
|
||||
int dataBits = 8;
|
||||
StopBits stopBits = StopBits.One;
|
||||
|
||||
var serialPort = new SerialPort(portName, baudRate, parity, dataBits, stopBits);
|
||||
if (!serialPort.IsOpen)
|
||||
serialPort.Open();
|
||||
_serialPort = new SerialPort(portName, baudRate, parity, dataBits, stopBits);
|
||||
_serialPort.Open();
|
||||
|
||||
_serialMaster = ModbusSerialMaster.CreateRtu(serialPort);
|
||||
|
||||
// 推荐加上超时,避免卡死
|
||||
_serialMaster = ModbusSerialMaster.CreateRtu(_serialPort);
|
||||
_serialMaster.Transport.Retries = 2;
|
||||
_serialMaster.Transport.ReadTimeout = 500;
|
||||
_serialMaster.Transport.WriteTimeout = 500;
|
||||
_serialMaster.Transport.ReadTimeout = 1000;
|
||||
_serialMaster.Transport.WriteTimeout = 1000;
|
||||
|
||||
_isSerialInitialized = true;
|
||||
System.Diagnostics.Debug.WriteLine($"RS485 串口 {portName} 初始化成功");
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Console.WriteLine($"串口初始化失败:{ex.Message}");
|
||||
System.Diagnostics.Debug.WriteLine($"串口初始化失败:{ex.Message}");
|
||||
_serialMaster = null;
|
||||
_isSerialInitialized = false;
|
||||
}
|
||||
}
|
||||
|
||||
private void CloseSerialModbus()
|
||||
{
|
||||
try
|
||||
{
|
||||
_serialMaster?.Dispose();
|
||||
_serialPort?.Close();
|
||||
_serialPort?.Dispose();
|
||||
}
|
||||
catch { }
|
||||
_serialMaster = null;
|
||||
_serialPort = null;
|
||||
_isSerialInitialized = false;
|
||||
}
|
||||
|
||||
private async Task ReadLightBarData()
|
||||
{
|
||||
// ===================== 最小修改,不丢次 =====================
|
||||
if (_serialMaster == null)
|
||||
// 如果未初始化,则初始化
|
||||
if (!_isSerialInitialized || _serialMaster == null)
|
||||
{
|
||||
InitSerialModbus(); // 立即初始化,不跳过本次
|
||||
InitSerialModbus();
|
||||
if (_serialMaster == null) return;
|
||||
}
|
||||
if (_serialMaster == null) return; // 真的失败才退出
|
||||
// ==========================================================
|
||||
|
||||
try
|
||||
{
|
||||
byte slaveId = 1;
|
||||
|
||||
var allLights = new List<int>();
|
||||
|
||||
// 通道一:10001~10081
|
||||
// 通道一:上爪灯条
|
||||
bool[] ch1 = await _serialMaster.ReadInputsAsync(slaveId, 0, 81);
|
||||
int ch1OnCount = ch1.Count(b => b);
|
||||
System.Diagnostics.Debug.WriteLine($"通道一(上爪)亮灯数: {ch1OnCount}/81");
|
||||
allLights.AddRange(ch1.Select(b => b ? 1 : 0));
|
||||
|
||||
// 通道二:10097~10177
|
||||
// 通道二:下爪灯条
|
||||
bool[] ch2 = await _serialMaster.ReadInputsAsync(slaveId, 96, 81);
|
||||
int ch2OnCount = ch2.Count(b => b);
|
||||
System.Diagnostics.Debug.WriteLine($"通道二(下爪)亮灯数: {ch2OnCount}/81");
|
||||
allLights.AddRange(ch2.Select(b => b ? 1 : 0));
|
||||
|
||||
// 通道三
|
||||
// 通道三:水平灯条分段
|
||||
bool[] s1 = await _serialMaster.ReadInputsAsync(slaveId, 192, 8);
|
||||
bool[] s2 = await _serialMaster.ReadInputsAsync(slaveId, 208, 16);
|
||||
bool[] s3 = await _serialMaster.ReadInputsAsync(slaveId, 224, 16);
|
||||
bool[] s4 = await _serialMaster.ReadInputsAsync(slaveId, 240, 1);
|
||||
bool[] s5 = await _serialMaster.ReadInputsAsync(slaveId, 256, 16);
|
||||
bool[] s6 = await _serialMaster.ReadInputsAsync(slaveId, 272, 16);
|
||||
bool[] s7 = await _serialMaster.ReadInputsAsync(slaveId, 288, 8);
|
||||
|
||||
allLights.AddRange(s1.Select(b => b ? 1 : 0));
|
||||
bool[] s2 = await _serialMaster.ReadInputsAsync(slaveId, 208, 16);
|
||||
allLights.AddRange(s2.Select(b => b ? 1 : 0));
|
||||
bool[] s3 = await _serialMaster.ReadInputsAsync(slaveId, 224, 16);
|
||||
allLights.AddRange(s3.Select(b => b ? 1 : 0));
|
||||
bool[] s4 = await _serialMaster.ReadInputsAsync(slaveId, 240, 1);
|
||||
allLights.AddRange(s4.Select(b => b ? 1 : 0));
|
||||
bool[] s5 = await _serialMaster.ReadInputsAsync(slaveId, 256, 16);
|
||||
allLights.AddRange(s5.Select(b => b ? 1 : 0));
|
||||
bool[] s6 = await _serialMaster.ReadInputsAsync(slaveId, 272, 16);
|
||||
allLights.AddRange(s6.Select(b => b ? 1 : 0));
|
||||
bool[] s7 = await _serialMaster.ReadInputsAsync(slaveId, 288, 8);
|
||||
allLights.AddRange(s7.Select(b => b ? 1 : 0));
|
||||
|
||||
int total = 81 + 81 + 8 + 16 + 16 + 1 + 16 + 16 + 8;
|
||||
if (allLights.Count != total)
|
||||
{
|
||||
System.Diagnostics.Debug.WriteLine($"灯条数据总数错误:{allLights.Count},预期 {total}");
|
||||
}
|
||||
int ch3Total = allLights.Skip(162).Count(b => b == 1); // 通道三从索引162开始
|
||||
System.Diagnostics.Debug.WriteLine($"通道三(水平)总亮灯数: {ch3Total}/81");
|
||||
|
||||
lock (_lock)
|
||||
{
|
||||
DataList.Clear();
|
||||
if (tbTest.Content.ToString()=="空白测试")
|
||||
if (tbTest.Content.ToString() == "空白测试")
|
||||
{
|
||||
allLights.ForEach(s =>
|
||||
{
|
||||
int item = 1;
|
||||
DataList.Add(item);
|
||||
});
|
||||
// 空白测试强制全亮
|
||||
for (int i = 0; i < allLights.Count; i++)
|
||||
allLights[i] = 1;
|
||||
}
|
||||
DataList.AddRange(allLights.Cast<dynamic>());
|
||||
}
|
||||
|
||||
int onCount = DataList.Count(s => s == 1);
|
||||
System.Diagnostics.Debug.WriteLine($"当前亮灯数量:{onCount}");
|
||||
System.Diagnostics.Debug.WriteLine($"当前总亮灯数量:{onCount}");
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Console.WriteLine($"灯条数据读取失败:{ex.Message}");
|
||||
System.Diagnostics.Debug.WriteLine(ex.StackTrace);
|
||||
System.Diagnostics.Debug.WriteLine($"灯条数据读取失败:{ex.Message}");
|
||||
// 出错后关闭并重新初始化串口
|
||||
CloseSerialModbus();
|
||||
InitSerialModbus();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user