This commit is contained in:
xyy
2026-05-18 11:48:57 +08:00
parent 5cd55e4c12
commit 4a436ddcea

View File

@@ -5,6 +5,7 @@ using Sunny.UI;
//using RecordDateView; //using RecordDateView;
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.IO.Ports;
using System.Net; using System.Net;
using System.Net.Sockets; using System.Net.Sockets;
using System.Reflection.Metadata; using System.Reflection.Metadata;
@@ -292,49 +293,49 @@ namespace 头罩视野.Views
//读取灯泡的数据 //读取灯泡的数据
private async Task ReadLightBarData() //private async Task ReadLightBarData()
{ //{
if (_modbusMaster == null || !ModbusHelper.TcpClient.Connected) // if (_modbusMaster == null || !ModbusHelper.TcpClient.Connected)
return; // return;
try // try
{ // {
ushort[] registers = await _modbusMaster.ReadHoldingRegistersAsync(1, 350, 15); // ushort[] registers = await _modbusMaster.ReadHoldingRegistersAsync(1, 350, 15);
var tempList = new List<int>(240); // 240 是预期长度 // var tempList = new List<int>(240); // 240 是预期长度
foreach (ushort reg in registers) // foreach (ushort reg in registers)
{ // {
for (int bit = 0; bit < 16; bit++) // for (int bit = 0; bit < 16; bit++)
{ // {
int lightBit = (reg & (1 << bit)) != 0 ? 1 : 0; // int lightBit = (reg & (1 << bit)) != 0 ? 1 : 0;
if (tbTest.Content.ToString() == "空白测试") // if (tbTest.Content.ToString() == "空白测试")
{ // {
lightBit = 1; // lightBit = 1;
if (tempList.Where(s => s == 1).Count() > 194) // if (tempList.Where(s => s == 1).Count() > 194)
{ // {
lightBit = 0; // lightBit = 0;
} // }
} // }
tempList.Add(lightBit); // tempList.Add(lightBit);
} // }
} // }
lock (_lock) // lock (_lock)
{ // {
DataList.Clear(); // DataList.Clear();
DataList.AddRange(tempList.Cast<dynamic>()); // DataList.AddRange(tempList.Cast<dynamic>());
} // }
System.Diagnostics.Debug.WriteLine($"灯条二进制数据总长度:{DataList.Count}"); // System.Diagnostics.Debug.WriteLine($"灯条二进制数据总长度:{DataList.Count}");
} // }
catch (Exception ex) // catch (Exception ex)
{ // {
Console.WriteLine($"灯条数据读取失败:{ex.Message}"); // Console.WriteLine($"灯条数据读取失败:{ex.Message}");
// 出错时不清空 DataList保留旧数据 // // 出错时不清空 DataList保留旧数据
} // }
} //}
private async void Timer_Tick(object sender, EventArgs e) private async void Timer_Tick(object sender, EventArgs e)
{ {
@@ -401,6 +402,7 @@ namespace 头罩视野.Views
//计算 //计算
private async Task calCurrentangle() private async Task calCurrentangle()
{ {
await ReadLightBarData(); await ReadLightBarData();
int[] lightData; int[] lightData;
@@ -415,17 +417,30 @@ namespace 头罩视野.Views
return; 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 singleArea = GetArea.CalculateEllipseArea(lightData, _lightPositions);
double bottomViewAngle; double bottomViewAngle;
if (tbTest.Content.ToString() == "试样测试") if (tbTest.Content.ToString() == "试样测试")
{ {
// 1. 修正下爪灯条的不连续性填充空洞使所有1连续 // 修正下爪灯条:填充空洞使连续
int startIdx = 81; int startIdx = 81;
int endIdx = 162; // 81+81=162 int endIdx = startIdx + 81;
int firstOne = -1; int firstOne = -1, lastOne = -1;
int lastOne = -1;
// 找到第一个1和最后一个1
for (int i = startIdx; i < endIdx; i++) for (int i = startIdx; i < endIdx; i++)
{ {
if (lightData[i] == 1) if (lightData[i] == 1)
@@ -434,97 +449,91 @@ namespace 头罩视野.Views
lastOne = i; lastOne = i;
} }
} }
// 如果存在1则将 firstOne 到 lastOne 之间的所有灯设为1填充空洞
if (firstOne != -1 && lastOne != -1) if (firstOne != -1 && lastOne != -1)
{ {
for (int i = firstOne; i <= lastOne; i++) for (int i = firstOne; i <= lastOne; i++)
{
lightData[i] = 1; lightData[i] = 1;
}
} }
// 2. 基于修正后的数据,计算下爪灯条亮灯比例 PrintSegment(lightData, 81, 81, "修正后的下爪灯条");
// 计算亮灯比例
int bottomLampCount = 0; int bottomLampCount = 0;
const int totalBottomLamps = 81; for (int i = startIdx; i < endIdx; i++)
for (int i = 0; i < lightData.Length && i < _lightPositions.Count; i++) if (lightData[i] == 1) bottomLampCount++;
{ double ratio = bottomLampCount / 81.0;
var (m, n) = _lightPositions[i]; bottomViewAngle = 90.0 * ratio;
if (n == 1 && lightData[i] == 1) // 可选钳位
bottomLampCount++; // if (bottomViewAngle < 52) bottomViewAngle = 52;
} // if (bottomViewAngle > 60) bottomViewAngle = 60;
double ratio = (double)bottomLampCount / totalBottomLamps;
double estimatedAngle = 90.0 * ratio; // 全亮时90°全灭时0°
// 3. 可选钳位到52-60如果需要
// if (estimatedAngle < 52) estimatedAngle = 52;
// if (estimatedAngle > 60) estimatedAngle = 60;
bottomViewAngle = estimatedAngle;
} }
else else
{ {
bottomViewAngle = GetArea.CalculateBottomViewAngle(lightData, _lightPositions); bottomViewAngle = GetArea.CalculateBottomViewAngle(lightData, _lightPositions);
}
System.Diagnostics.Debug.WriteLine($"角度: {dqangle.Text}, singleArea={singleArea}, bottomViewAngle={bottomViewAngle}");
// 5. 根据当前测试模式(左眼/右眼/双目),累加面积
if (isLeftOnly)
{
//System.Diagnostics.Debug.WriteLine($"lightData 实际长度: {lightData.Length}");
_leftTotalArea += singleArea;
// 实时合并左眼:只要亮过一次,就永久亮
// 安全获取真实长度
int realLength = lightData.Length;
// 初始化最终数据(永远和 lightData 一样长,不会错)
if (_leftFinalData == null || _leftFinalData.Count != realLength) System.Diagnostics.Debug.WriteLine($"角度: {dqangle.Text}, singleArea={singleArea}, bottomViewAngle={bottomViewAngle}");
// 5. 根据当前测试模式(左眼/右眼/双目),累加面积
if (isLeftOnly)
{ {
_leftFinalData = new List<int>(new int[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;
}
}
} }
for (int i = 0; i < realLength; i++) else if (isRightOnly)
{ {
if (lightData[i] == 1) _rightTotalArea += singleArea;
int realLength = lightData.Length;
if (_rightFinalData == null || _rightFinalData.Count != realLength)
{ {
_leftFinalData[i] = 1; _rightFinalData = new List<int>(new int[realLength]);
}
for (int i = 0; i < realLength; i++)
{
if (lightData[i] == 1)
{
_rightFinalData[i] = 1;
}
} }
} }
} // 6. 更新下方视野的最大值(取所有角度中最大的)
if (bottomViewAngle > maxBottomViewAngle)
maxBottomViewAngle = bottomViewAngle;
else if (isRightOnly) await Dispatcher.InvokeAsync(() =>
{
_rightTotalArea += singleArea;
int realLength = lightData.Length;
if (_rightFinalData == null || _rightFinalData.Count != realLength)
{ {
_rightFinalData = new List<int>(new int[realLength]); zmsyarea.Text = _leftTotalArea.ToString("0");
} ymsyarea.Text = _rightTotalArea.ToString("0");
smsyarea.Text = _binocularTotalArea.ToString("0");
for (int i = 0; i < realLength; i++) xfsyarea.Text = maxBottomViewAngle.ToString("0");
{ });
if (lightData[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");
});
} }
//数据共享 //数据共享
@@ -944,6 +953,115 @@ namespace 头罩视野.Views
} }
private IModbusMaster _serialMaster;
private void InitSerialModbus()
{
try
{
// 请根据实际 COM 口和参数修改
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();
_serialMaster = ModbusSerialMaster.CreateRtu(serialPort);
// 推荐加上超时,避免卡死
_serialMaster.Transport.Retries = 2;
_serialMaster.Transport.ReadTimeout = 500;
_serialMaster.Transport.WriteTimeout = 500;
System.Diagnostics.Debug.WriteLine($"RS485 串口 {portName} 初始化成功");
}
catch (Exception ex)
{
Console.WriteLine($"串口初始化失败:{ex.Message}");
}
}
private async Task ReadLightBarData()
{
// ===================== 最小修改,不丢次 =====================
if (_serialMaster == null)
{
InitSerialModbus(); // 立即初始化,不跳过本次
}
if (_serialMaster == null) return; // 真的失败才退出
// ==========================================================
try
{
byte slaveId = 1;
var allLights = new List<int>();
// 通道一10001~10081
bool[] ch1 = await _serialMaster.ReadInputsAsync(slaveId, 0, 81);
allLights.AddRange(ch1.Select(b => b ? 1 : 0));
// 通道二10097~10177
bool[] ch2 = await _serialMaster.ReadInputsAsync(slaveId, 96, 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));
allLights.AddRange(s2.Select(b => b ? 1 : 0));
allLights.AddRange(s3.Select(b => b ? 1 : 0));
allLights.AddRange(s4.Select(b => b ? 1 : 0));
allLights.AddRange(s5.Select(b => b ? 1 : 0));
allLights.AddRange(s6.Select(b => b ? 1 : 0));
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}");
}
lock (_lock)
{
DataList.Clear();
if (tbTest.Content.ToString()=="空白测试")
{
allLights.ForEach(s =>
{
int item = 1;
DataList.Add(item);
});
}
DataList.AddRange(allLights.Cast<dynamic>());
}
int onCount = DataList.Count(s => s == 1);
System.Diagnostics.Debug.WriteLine($"当前亮灯数量:{onCount}");
}
catch (Exception ex)
{
Console.WriteLine($"灯条数据读取失败:{ex.Message}");
System.Diagnostics.Debug.WriteLine(ex.StackTrace);
}
}
} }
} }