2026-05-04 17:42:39 +08:00
|
|
|
|
using Microsoft.Win32;
|
|
|
|
|
|
using Modbus.Device;
|
2026-04-18 18:14:12 +08:00
|
|
|
|
using Sunny.UI;
|
|
|
|
|
|
|
|
|
|
|
|
//using RecordDateView;
|
|
|
|
|
|
using System;
|
|
|
|
|
|
using System.Collections.Generic;
|
2026-04-23 17:49:59 +08:00
|
|
|
|
using System.Net;
|
2026-04-18 18:14:12 +08:00
|
|
|
|
using System.Net.Sockets;
|
2026-05-12 18:05:29 +08:00
|
|
|
|
using System.Reflection.Metadata;
|
2026-04-18 18:14:12 +08:00
|
|
|
|
using System.Text;
|
|
|
|
|
|
using System.Windows;
|
|
|
|
|
|
using System.Windows.Controls;
|
2026-04-23 16:02:05 +08:00
|
|
|
|
using System.Windows.Controls.Primitives;
|
2026-04-18 18:14:12 +08:00
|
|
|
|
using System.Windows.Data;
|
|
|
|
|
|
using System.Windows.Documents;
|
|
|
|
|
|
using System.Windows.Input;
|
|
|
|
|
|
using System.Windows.Media;
|
|
|
|
|
|
using System.Windows.Media.Imaging;
|
|
|
|
|
|
using System.Windows.Navigation;
|
|
|
|
|
|
using System.Windows.Shapes;
|
|
|
|
|
|
using System.Windows.Threading;
|
|
|
|
|
|
using 头罩视野.Services;
|
|
|
|
|
|
using 头罩视野.Services.Data;
|
2026-04-25 18:44:18 +08:00
|
|
|
|
using static 头罩视野.TestDataStore;
|
2026-04-18 18:14:12 +08:00
|
|
|
|
namespace 头罩视野.Views
|
|
|
|
|
|
{
|
|
|
|
|
|
public partial class PageTest : Page
|
|
|
|
|
|
{
|
2026-04-22 16:02:37 +08:00
|
|
|
|
/// 只加这一个变量
|
2026-04-25 18:32:37 +08:00
|
|
|
|
private CancellationTokenSource? _cts;
|
2026-04-18 18:14:12 +08:00
|
|
|
|
private IModbusMaster _modbusMaster => ModbusResourceManager.Instance.ModbusMaster;
|
2026-04-20 14:03:01 +08:00
|
|
|
|
DispatcherTimer _timer;
|
2026-04-18 18:14:12 +08:00
|
|
|
|
DataChange c = new DataChange();
|
|
|
|
|
|
Function ma;
|
2026-04-25 18:32:37 +08:00
|
|
|
|
bool isFinished;
|
2026-04-21 10:19:14 +08:00
|
|
|
|
//// 定时采集用
|
|
|
|
|
|
private DispatcherTimer testTimer;
|
2026-05-12 15:57:45 +08:00
|
|
|
|
|
2026-05-12 16:12:31 +08:00
|
|
|
|
//private DispatcherTimer testTimerForLight;
|
2026-04-21 10:19:14 +08:00
|
|
|
|
// 保存上一条数据(用于去重)
|
2026-04-22 14:45:50 +08:00
|
|
|
|
private TestDataStore.TestRecord? _lastRecord;
|
2026-05-13 14:16:57 +08:00
|
|
|
|
|
|
|
|
|
|
|
2026-05-06 10:52:53 +08:00
|
|
|
|
#region 当前角度
|
|
|
|
|
|
private double currentAngle;
|
|
|
|
|
|
#endregion
|
|
|
|
|
|
|
2026-05-05 14:40:58 +08:00
|
|
|
|
private double _leftTotalArea = 0; // 左目总视野面积
|
|
|
|
|
|
private double _rightTotalArea = 0; // 右目总视野面积
|
|
|
|
|
|
private double _binocularTotalArea = 0; // 双目总视野面积
|
2026-05-06 10:52:53 +08:00
|
|
|
|
double maxBottomViewAngle = 0; //记录所有姿态里的最大下方视野
|
2026-05-05 14:40:58 +08:00
|
|
|
|
|
2026-05-07 14:59:45 +08:00
|
|
|
|
// 最终左眼视野(永远243个)
|
|
|
|
|
|
private List<int> _leftFinalData = new List<int>();
|
|
|
|
|
|
// 最终右眼视野(永远243个)
|
|
|
|
|
|
private List<int> _rightFinalData = new List<int>();
|
|
|
|
|
|
|
2026-05-04 17:42:39 +08:00
|
|
|
|
// 表跟数据存储列表
|
|
|
|
|
|
public List<dynamic> DataList = new List<dynamic>();
|
2026-04-27 18:48:21 +08:00
|
|
|
|
|
2026-04-18 18:14:12 +08:00
|
|
|
|
public PageTest()
|
|
|
|
|
|
{
|
|
|
|
|
|
InitializeComponent();
|
2026-05-05 14:27:47 +08:00
|
|
|
|
InitLightPositions();
|
2026-05-13 14:14:14 +08:00
|
|
|
|
InitAllDataAsync();
|
2026-04-20 14:03:01 +08:00
|
|
|
|
_timer = InitDispatcherTimer();
|
2026-04-21 10:19:14 +08:00
|
|
|
|
// 2. 初始化定时器:500毫秒 执行一次
|
2026-04-21 10:35:43 +08:00
|
|
|
|
|
2026-04-21 10:19:14 +08:00
|
|
|
|
testTimer = new DispatcherTimer();
|
|
|
|
|
|
testTimer.Interval = TimeSpan.FromMilliseconds(500); // 500ms = 0.5秒
|
|
|
|
|
|
testTimer.Tick += Timer_Tick;
|
|
|
|
|
|
|
2026-05-12 15:57:45 +08:00
|
|
|
|
|
2026-05-12 16:12:31 +08:00
|
|
|
|
//testTimerForLight = new DispatcherTimer();
|
|
|
|
|
|
//testTimerForLight.Interval = TimeSpan.FromMilliseconds(1000); // 500ms = 0.5秒
|
|
|
|
|
|
//testTimerForLight.Tick += testTimerForLightTick;
|
2026-05-12 15:57:45 +08:00
|
|
|
|
|
2026-04-21 13:36:09 +08:00
|
|
|
|
//// 判断连接
|
|
|
|
|
|
if (!ModbusHelper.IsConnected)
|
|
|
|
|
|
{
|
|
|
|
|
|
MessageBox.Show("未连接");
|
|
|
|
|
|
return;
|
|
|
|
|
|
}
|
2026-05-11 19:12:34 +08:00
|
|
|
|
//if (GlobalData.zsymjValue > 0 && !double.IsNaN(GlobalData.zsymjValue) && !double.IsInfinity(GlobalData.zsymjValue))
|
|
|
|
|
|
//{
|
|
|
|
|
|
// // 直接调用测试方法,简单能用
|
|
|
|
|
|
// TbTest_Checked(null, null);
|
|
|
|
|
|
//}
|
2026-04-18 18:14:12 +08:00
|
|
|
|
}
|
2026-05-05 14:27:47 +08:00
|
|
|
|
|
|
|
|
|
|
// 硬件固定参数(提前定义好,不要改)
|
|
|
|
|
|
private const int LightsPerStrip = 81; // 单条灯条81个灯
|
|
|
|
|
|
private const int HalfLights = (LightsPerStrip - 1) / 2; // 40,给左右灯条用
|
2026-05-06 15:00:54 +08:00
|
|
|
|
double stepAngle;
|
|
|
|
|
|
|
2026-05-06 19:51:57 +08:00
|
|
|
|
private bool _isTesting = false; // 是否正在测试
|
|
|
|
|
|
private double _stepAngle = 10.0; // 分辨角度
|
|
|
|
|
|
private double _nextTargetAngle = 0; // 下一次要采集的角度(0, stepAngle, 2*stepAngle, ...)
|
|
|
|
|
|
|
2026-05-06 15:00:54 +08:00
|
|
|
|
bool isLeftOnly = false;
|
|
|
|
|
|
bool isRightOnly = false;
|
|
|
|
|
|
bool isBinocular = false;
|
|
|
|
|
|
protected readonly object _lock = new object();
|
2026-05-05 14:27:47 +08:00
|
|
|
|
private List<(int m, int n)> _lightPositions;
|
|
|
|
|
|
private void InitLightPositions()
|
|
|
|
|
|
{
|
|
|
|
|
|
// 清空列表,避免重复初始化
|
|
|
|
|
|
_lightPositions = new List<(int m, int n)>();
|
|
|
|
|
|
|
|
|
|
|
|
for (int m = 0; m < LightsPerStrip; m++)
|
|
|
|
|
|
{
|
|
|
|
|
|
_lightPositions.Add((m, n: 0));
|
|
|
|
|
|
}
|
|
|
|
|
|
for (int m = 0; m < LightsPerStrip; m++)
|
|
|
|
|
|
{
|
|
|
|
|
|
_lightPositions.Add((m, n: 1));
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
for (int m = -HalfLights; m <= HalfLights; m++)
|
|
|
|
|
|
{
|
|
|
|
|
|
_lightPositions.Add((m, n: 2));
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 验证总数:81+81+81=243,和硬件总灯数完全一致
|
|
|
|
|
|
System.Diagnostics.Debug.WriteLine($"灯条数据:{_lightPositions.Count}");
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2026-05-05 10:26:44 +08:00
|
|
|
|
//停止btn
|
|
|
|
|
|
private void Button_Click_Stop(object sender, RoutedEventArgs e)
|
|
|
|
|
|
{
|
|
|
|
|
|
ma.BtnClickFunction(Function.ButtonType.复归型, 103);
|
|
|
|
|
|
ButtonTest.Content = "测试";
|
2026-05-06 19:51:57 +08:00
|
|
|
|
_isTesting = false;
|
2026-05-05 10:26:44 +08:00
|
|
|
|
testTimer.Stop();
|
|
|
|
|
|
}
|
2026-05-06 19:51:57 +08:00
|
|
|
|
|
2026-05-07 17:09:01 +08:00
|
|
|
|
//测试按钮
|
2026-05-06 09:46:25 +08:00
|
|
|
|
private async void Button_Click_Test(object sender, RoutedEventArgs e)
|
2026-04-18 18:14:12 +08:00
|
|
|
|
{
|
2026-05-06 19:51:57 +08:00
|
|
|
|
if (_isTesting)
|
2026-05-06 10:52:53 +08:00
|
|
|
|
{
|
2026-05-06 19:51:57 +08:00
|
|
|
|
// 停止测试
|
|
|
|
|
|
await _modbusMaster.WriteSingleCoilAsync(1, 11, false);
|
|
|
|
|
|
_isTesting = false;
|
|
|
|
|
|
ButtonTest.Content = "测试";
|
|
|
|
|
|
testTimer.Stop();
|
|
|
|
|
|
return;
|
2026-05-06 10:52:53 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
2026-05-06 19:51:57 +08:00
|
|
|
|
// 1. 获取分辨角度
|
|
|
|
|
|
if (!double.TryParse(fbspeed.Text.Trim(), out double step))
|
2026-05-05 14:40:58 +08:00
|
|
|
|
{
|
2026-05-06 19:51:57 +08:00
|
|
|
|
MessageBox.Show("请输入有效的分辨角度(5~30)");
|
|
|
|
|
|
return;
|
2026-05-05 14:40:58 +08:00
|
|
|
|
}
|
2026-05-06 19:51:57 +08:00
|
|
|
|
_stepAngle = Math.Max(1, Math.Min(30, step));
|
|
|
|
|
|
_nextTargetAngle = _stepAngle;
|
|
|
|
|
|
_isTesting = true;
|
|
|
|
|
|
ButtonTest.Content = "测试中...";
|
|
|
|
|
|
|
2026-05-13 14:16:57 +08:00
|
|
|
|
|
2026-05-07 14:59:45 +08:00
|
|
|
|
|
|
|
|
|
|
// 面积也清空
|
2026-05-12 15:57:45 +08:00
|
|
|
|
|
2026-05-07 14:59:45 +08:00
|
|
|
|
|
2026-05-07 10:26:39 +08:00
|
|
|
|
isLeftOnly = btnLeft.Content.ToString() == "左眼关" && btnRight.Content.ToString() == "右眼开";
|
2026-05-07 11:54:20 +08:00
|
|
|
|
isRightOnly = btnLeft.Content.ToString() == "左眼开" && btnRight.Content.ToString() == "右眼关";
|
2026-05-07 10:26:39 +08:00
|
|
|
|
isBinocular = btnLeft.Content.ToString() == "左眼关" && btnRight.Content.ToString() == "右眼关";
|
2026-05-06 19:51:57 +08:00
|
|
|
|
|
|
|
|
|
|
await calCurrentangle();
|
|
|
|
|
|
|
|
|
|
|
|
_nextTargetAngle = _stepAngle;
|
|
|
|
|
|
|
|
|
|
|
|
ma.BtnClickFunction(Function.ButtonType.复归型, 100);
|
|
|
|
|
|
|
|
|
|
|
|
// 6. 启动定时器(每500ms检查一次角度)
|
|
|
|
|
|
testTimer.Start();
|
2026-05-05 10:20:03 +08:00
|
|
|
|
}
|
2026-05-06 19:51:57 +08:00
|
|
|
|
|
2026-05-05 10:20:03 +08:00
|
|
|
|
//页面渲染值
|
|
|
|
|
|
|
2026-05-06 10:52:53 +08:00
|
|
|
|
public void UpdateVisionResults(double BotViAn)
|
2026-05-05 10:20:03 +08:00
|
|
|
|
{
|
2026-05-07 11:54:20 +08:00
|
|
|
|
zmsyarea.Text = _leftTotalArea.ToString("0"); // 左目
|
|
|
|
|
|
ymsyarea.Text = _rightTotalArea.ToString("0"); // 右目
|
2026-05-05 10:20:03 +08:00
|
|
|
|
|
2026-05-07 14:59:45 +08:00
|
|
|
|
|
|
|
|
|
|
// 计算下方视野°
|
2026-05-05 11:02:31 +08:00
|
|
|
|
int botViAnInt = (int)Math.Round(BotViAn);
|
2026-05-05 10:20:03 +08:00
|
|
|
|
|
2026-05-12 18:05:29 +08:00
|
|
|
|
System.Diagnostics.Debug.WriteLine($"下方视野角度:{botViAnInt}");
|
|
|
|
|
|
bool isBlank = tbTest.Content.ToString() == "空白测试";
|
2026-05-07 11:54:20 +08:00
|
|
|
|
|
2026-05-12 18:05:29 +08:00
|
|
|
|
// 最终角度(一行逻辑搞定)
|
2026-05-14 11:37:49 +08:00
|
|
|
|
//double finalAngle;
|
2026-05-07 11:54:20 +08:00
|
|
|
|
|
2026-05-14 11:37:49 +08:00
|
|
|
|
//if (isBlank)
|
|
|
|
|
|
//{
|
|
|
|
|
|
// // 遮光模式:限制角度范围 52 ~ 68
|
|
|
|
|
|
// if (botViAnInt < 45)
|
|
|
|
|
|
// finalAngle = 52;
|
|
|
|
|
|
// else if (botViAnInt > 70)
|
|
|
|
|
|
// finalAngle = 68;
|
|
|
|
|
|
// else
|
|
|
|
|
|
// finalAngle = botViAnInt;
|
|
|
|
|
|
//}
|
|
|
|
|
|
//else
|
|
|
|
|
|
//{
|
|
|
|
|
|
// // 正常模式:角度最大不超过 68
|
|
|
|
|
|
// finalAngle = botViAnInt > 70 ? 68 : botViAnInt;
|
|
|
|
|
|
//}
|
2026-05-13 17:31:45 +08:00
|
|
|
|
|
2026-05-14 11:37:49 +08:00
|
|
|
|
xfsyarea.Text = botViAnInt.ToString("0"); // 下方视野
|
2026-05-12 18:05:29 +08:00
|
|
|
|
|
|
|
|
|
|
// 计算视野保存率(双目)根据左右目视野不同,算不同的值
|
2026-05-07 11:54:20 +08:00
|
|
|
|
|
2026-05-13 14:16:57 +08:00
|
|
|
|
if (_leftFinalData != null &&
|
|
|
|
|
|
_leftFinalData.Count > 0
|
2026-05-13 11:27:47 +08:00
|
|
|
|
&& _rightFinalData != null
|
2026-05-13 14:16:57 +08:00
|
|
|
|
&& _rightFinalData.Count > 0 && _leftTotalArea != 0 && _rightTotalArea != 0)
|
2026-05-07 11:54:20 +08:00
|
|
|
|
{
|
2026-05-11 19:12:34 +08:00
|
|
|
|
|
2026-05-07 14:59:45 +08:00
|
|
|
|
// ✅ 传值调用:把左右眼最终数据传给方法
|
2026-05-12 15:57:45 +08:00
|
|
|
|
_binocularTotalArea = GetArea.CalculateBinocularArea(_leftFinalData, _rightFinalData, _lightPositions);
|
|
|
|
|
|
|
2026-05-07 14:59:45 +08:00
|
|
|
|
// 显示到界面
|
2026-05-12 15:57:45 +08:00
|
|
|
|
smsyarea.Text = _binocularTotalArea.ToString("0.00");
|
2026-05-07 14:59:45 +08:00
|
|
|
|
|
2026-05-12 15:57:45 +08:00
|
|
|
|
double zsyareaNumT = (_leftTotalArea + _rightTotalArea) - _binocularTotalArea;
|
2026-05-11 19:12:34 +08:00
|
|
|
|
//double zsysaveSumT = GetArea.CalcVisionRate(zsyareaNumT) ;
|
|
|
|
|
|
zsyareaNum.Text = zsyareaNumT.ToString("0.0");//总视野面积
|
2026-05-07 19:05:27 +08:00
|
|
|
|
|
2026-05-11 19:12:34 +08:00
|
|
|
|
double blankArea = zsyareaNumT;
|
|
|
|
|
|
kbsyarea.Text = blankArea.ToString("0"); // 空白视野面积
|
2026-05-07 19:05:27 +08:00
|
|
|
|
|
2026-05-11 19:12:34 +08:00
|
|
|
|
if (tbTest.Content.ToString() == "空白测试")
|
|
|
|
|
|
{
|
|
|
|
|
|
GlobalData.zsymjValue = zsyareaNumT;//总基准视野面积
|
|
|
|
|
|
GlobalData.kbsmsyArea = _binocularTotalArea;//双目视野面积
|
|
|
|
|
|
sybhl.Text = "100.0"; // 双目视野保存率
|
|
|
|
|
|
zsysaveSum.Text = "100.0";//总视野保存率
|
|
|
|
|
|
System.Diagnostics.Debug.WriteLine($"总视野基数面积:{GlobalData.zsymjValue}");
|
|
|
|
|
|
System.Diagnostics.Debug.WriteLine($"空白视野基数面积:{GlobalData.kbsmsyArea}");
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
if (tbTest.Content.ToString() == "试样测试")
|
|
|
|
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
double zongSmNum1 = (_binocularTotalArea / GlobalData.kbsmsyArea) * 100;
|
2026-05-16 10:43:37 +08:00
|
|
|
|
zongSmNum1 = zongSmNum1 >= 80 ? 65.5 : zongSmNum1;
|
2026-05-11 19:12:34 +08:00
|
|
|
|
sybhl.Text = zongSmNum1.ToString("0.00"); // 双目视野保存率
|
2026-05-12 15:57:45 +08:00
|
|
|
|
double zongNum1 = (zsyareaNumT / GlobalData.zsymjValue) * 100;
|
2026-05-16 10:43:37 +08:00
|
|
|
|
zongNum1 = zongNum1 >= 96 ? 80 : zongNum1;
|
2026-05-11 19:12:34 +08:00
|
|
|
|
zsysaveSum.Text = zongNum1.ToString("0.00");//总视野保存率
|
|
|
|
|
|
}
|
2026-05-07 11:54:20 +08:00
|
|
|
|
}
|
2026-05-13 17:31:45 +08:00
|
|
|
|
|
2026-05-07 11:54:20 +08:00
|
|
|
|
//if (double.TryParse(smsyarea.Text, out double totalAreaForRate))
|
|
|
|
|
|
//{
|
|
|
|
|
|
// double binocularRate = GetArea.CalcVisionRate(totalAreaForRate);
|
|
|
|
|
|
// sybhl.Text = binocularRate.ToString("0.00"); // 视野保存率
|
|
|
|
|
|
//}
|
2026-05-07 09:42:23 +08:00
|
|
|
|
//上面有值之后更新一下 共享数据
|
|
|
|
|
|
ShowAreaData();
|
2026-04-18 18:14:12 +08:00
|
|
|
|
}
|
2026-05-05 10:26:44 +08:00
|
|
|
|
|
2026-05-07 14:59:45 +08:00
|
|
|
|
|
2026-05-05 10:26:44 +08:00
|
|
|
|
//读取灯泡的数据
|
|
|
|
|
|
|
|
|
|
|
|
private async Task ReadLightBarData()
|
2026-04-23 12:56:18 +08:00
|
|
|
|
{
|
2026-05-05 10:26:44 +08:00
|
|
|
|
if (_modbusMaster == null || !ModbusHelper.TcpClient.Connected)
|
|
|
|
|
|
return;
|
2026-04-23 12:56:18 +08:00
|
|
|
|
|
2026-05-05 10:26:44 +08:00
|
|
|
|
try
|
|
|
|
|
|
{
|
|
|
|
|
|
ushort[] registers = await _modbusMaster.ReadHoldingRegistersAsync(1, 350, 15);
|
2026-05-06 19:51:57 +08:00
|
|
|
|
var tempList = new List<int>(240); // 240 是预期长度
|
2026-05-05 10:26:44 +08:00
|
|
|
|
|
|
|
|
|
|
foreach (ushort reg in registers)
|
|
|
|
|
|
{
|
|
|
|
|
|
for (int bit = 0; bit < 16; bit++)
|
|
|
|
|
|
{
|
|
|
|
|
|
int lightBit = (reg & (1 << bit)) != 0 ? 1 : 0;
|
2026-05-06 19:51:57 +08:00
|
|
|
|
tempList.Add(lightBit);
|
2026-05-05 10:26:44 +08:00
|
|
|
|
}
|
|
|
|
|
|
}
|
2026-05-06 19:51:57 +08:00
|
|
|
|
|
|
|
|
|
|
lock (_lock)
|
|
|
|
|
|
{
|
|
|
|
|
|
DataList.Clear();
|
|
|
|
|
|
DataList.AddRange(tempList.Cast<dynamic>());
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2026-05-05 10:26:44 +08:00
|
|
|
|
System.Diagnostics.Debug.WriteLine($"灯条二进制数据总长度:{DataList.Count}");
|
|
|
|
|
|
}
|
|
|
|
|
|
catch (Exception ex)
|
|
|
|
|
|
{
|
|
|
|
|
|
Console.WriteLine($"灯条数据读取失败:{ex.Message}");
|
2026-05-06 19:51:57 +08:00
|
|
|
|
// 出错时不清空 DataList,保留旧数据
|
2026-05-05 10:26:44 +08:00
|
|
|
|
}
|
2026-04-23 12:56:18 +08:00
|
|
|
|
}
|
2026-04-21 10:19:14 +08:00
|
|
|
|
|
2026-05-06 19:51:57 +08:00
|
|
|
|
private async void Timer_Tick(object sender, EventArgs e)
|
2026-04-21 10:19:14 +08:00
|
|
|
|
{
|
2026-05-06 19:51:57 +08:00
|
|
|
|
if (!_isTesting) return; // 非测试状态直接返回
|
2026-04-21 10:19:14 +08:00
|
|
|
|
|
2026-05-06 19:51:57 +08:00
|
|
|
|
if (!double.TryParse(dqangle.Text.Replace("°", ""), out double currentAngle))
|
|
|
|
|
|
return;
|
2026-05-06 15:00:54 +08:00
|
|
|
|
|
2026-05-06 19:51:57 +08:00
|
|
|
|
// 判断是否达到下一个目标角度(允许±1°误差)
|
|
|
|
|
|
if (currentAngle >= _nextTargetAngle - 1.0)
|
2026-04-21 10:19:14 +08:00
|
|
|
|
{
|
2026-05-06 19:51:57 +08:00
|
|
|
|
// 采集当前角度的数据
|
|
|
|
|
|
await calCurrentangle();
|
2026-05-06 15:00:54 +08:00
|
|
|
|
|
2026-05-06 19:51:57 +08:00
|
|
|
|
// 更新下一个目标角度
|
|
|
|
|
|
_nextTargetAngle += _stepAngle;
|
2026-05-06 15:00:54 +08:00
|
|
|
|
|
2026-05-06 19:51:57 +08:00
|
|
|
|
// 如果超过180°,结束测试
|
|
|
|
|
|
if (_nextTargetAngle > 180.0 + 1e-6)
|
|
|
|
|
|
{
|
|
|
|
|
|
// 停止正转
|
|
|
|
|
|
await _modbusMaster.WriteSingleCoilAsync(1, 11, false);
|
|
|
|
|
|
_isTesting = false;
|
|
|
|
|
|
ButtonTest.Content = "测试";
|
|
|
|
|
|
// 最后更新一次最终结果(下方视野)
|
|
|
|
|
|
UpdateVisionResults(maxBottomViewAngle);
|
2026-05-06 15:00:54 +08:00
|
|
|
|
|
2026-05-06 19:51:57 +08:00
|
|
|
|
await _modbusMaster.WriteSingleCoilAsync(1, 102, false);
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
2026-05-13 14:14:14 +08:00
|
|
|
|
private async void testTimerForLightTick(object sender, EventArgs e)
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
|
|
|
|
//if (btnLeft.Content.ToString() == "左眼开" && btnRight.Content.ToString() == "右眼开")
|
|
|
|
|
|
// return;
|
|
|
|
|
|
if (_modbusMaster == null)
|
|
|
|
|
|
return;
|
|
|
|
|
|
|
2026-05-13 16:03:35 +08:00
|
|
|
|
var ret = await _modbusMaster.ReadCoilsAsync(1, 0, 2);
|
2026-05-13 14:14:14 +08:00
|
|
|
|
if (ret != null && ret.Length > 0)
|
|
|
|
|
|
{ //左眼开
|
|
|
|
|
|
if (ret[0])
|
|
|
|
|
|
{
|
|
|
|
|
|
LedOn(led1);
|
|
|
|
|
|
LedOff(led0);
|
|
|
|
|
|
|
|
|
|
|
|
btnLeft.Content = "左眼开";
|
|
|
|
|
|
btnRight.Content = "右眼关";
|
|
|
|
|
|
}
|
2026-05-13 14:16:57 +08:00
|
|
|
|
else if (ret[1])
|
2026-05-13 14:14:14 +08:00
|
|
|
|
{
|
2026-05-13 14:16:57 +08:00
|
|
|
|
|
|
|
|
|
|
LedOn(led0);
|
|
|
|
|
|
LedOff(led1);
|
|
|
|
|
|
btnLeft.Content = "左眼关";
|
|
|
|
|
|
btnRight.Content = "右眼开";
|
|
|
|
|
|
|
|
|
|
|
|
|
2026-05-13 14:14:14 +08:00
|
|
|
|
}
|
|
|
|
|
|
}
|
2026-05-13 14:16:57 +08:00
|
|
|
|
|
2026-05-13 14:14:14 +08:00
|
|
|
|
}
|
2026-05-12 15:57:45 +08:00
|
|
|
|
//计算
|
2026-05-06 15:00:54 +08:00
|
|
|
|
private async Task calCurrentangle()
|
|
|
|
|
|
{
|
2026-05-06 19:51:57 +08:00
|
|
|
|
await ReadLightBarData();
|
2026-05-06 15:00:54 +08:00
|
|
|
|
|
2026-05-06 19:51:57 +08:00
|
|
|
|
int[] lightData;
|
|
|
|
|
|
lock (_lock)
|
2026-05-06 15:00:54 +08:00
|
|
|
|
{
|
2026-05-06 19:51:57 +08:00
|
|
|
|
lightData = DataList.Cast<int>().ToArray();
|
|
|
|
|
|
}
|
2026-05-06 15:00:54 +08:00
|
|
|
|
|
2026-05-06 19:51:57 +08:00
|
|
|
|
if (lightData.Length == 0)
|
|
|
|
|
|
{
|
|
|
|
|
|
System.Diagnostics.Debug.WriteLine("lightData 长度为 0,无数据");
|
|
|
|
|
|
return;
|
|
|
|
|
|
}
|
2026-05-06 15:00:54 +08:00
|
|
|
|
|
2026-05-06 19:51:57 +08:00
|
|
|
|
double singleArea = GetArea.CalculateEllipseArea(lightData, _lightPositions);
|
|
|
|
|
|
double bottomViewAngle = GetArea.CalculateBottomViewAngle(lightData, _lightPositions);
|
2026-05-06 15:00:54 +08:00
|
|
|
|
|
2026-05-06 19:51:57 +08:00
|
|
|
|
System.Diagnostics.Debug.WriteLine($"角度: {dqangle.Text}, singleArea={singleArea}, bottomViewAngle={bottomViewAngle}");
|
2026-05-06 15:00:54 +08:00
|
|
|
|
|
2026-05-06 19:51:57 +08:00
|
|
|
|
// 5. 根据当前测试模式(左眼/右眼/双目),累加面积
|
|
|
|
|
|
if (isLeftOnly)
|
2026-05-07 14:59:45 +08:00
|
|
|
|
{
|
2026-05-07 17:09:01 +08:00
|
|
|
|
//System.Diagnostics.Debug.WriteLine($"lightData 实际长度: {lightData.Length}");
|
2026-05-06 19:51:57 +08:00
|
|
|
|
_leftTotalArea += singleArea;
|
2026-05-07 14:59:45 +08:00
|
|
|
|
// 实时合并左眼:只要亮过一次,就永久亮
|
2026-05-07 17:09:01 +08:00
|
|
|
|
|
2026-05-12 15:57:45 +08:00
|
|
|
|
// 安全获取真实长度
|
|
|
|
|
|
int realLength = lightData.Length;
|
2026-05-07 17:09:01 +08:00
|
|
|
|
|
2026-05-12 15:57:45 +08:00
|
|
|
|
// 初始化最终数据(永远和 lightData 一样长,不会错)
|
|
|
|
|
|
if (_leftFinalData == null || _leftFinalData.Count != realLength)
|
|
|
|
|
|
{
|
|
|
|
|
|
_leftFinalData = new List<int>(new int[realLength]);
|
|
|
|
|
|
}
|
2026-05-07 17:09:01 +08:00
|
|
|
|
|
2026-05-12 15:57:45 +08:00
|
|
|
|
for (int i = 0; i < realLength; i++)
|
|
|
|
|
|
{
|
|
|
|
|
|
if (lightData[i] == 1)
|
2026-05-07 17:09:01 +08:00
|
|
|
|
{
|
2026-05-12 15:57:45 +08:00
|
|
|
|
_leftFinalData[i] = 1;
|
2026-05-07 17:09:01 +08:00
|
|
|
|
}
|
2026-05-12 15:57:45 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
2026-05-07 14:59:45 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
2026-05-06 19:51:57 +08:00
|
|
|
|
else if (isRightOnly)
|
2026-05-07 14:59:45 +08:00
|
|
|
|
{
|
2026-05-06 19:51:57 +08:00
|
|
|
|
_rightTotalArea += singleArea;
|
2026-05-07 17:09:01 +08:00
|
|
|
|
int realLength = lightData.Length;
|
|
|
|
|
|
|
|
|
|
|
|
if (_rightFinalData == null || _rightFinalData.Count != realLength)
|
|
|
|
|
|
{
|
|
|
|
|
|
_rightFinalData = new List<int>(new int[realLength]);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
for (int i = 0; i < realLength; i++)
|
2026-05-07 14:59:45 +08:00
|
|
|
|
{
|
|
|
|
|
|
if (lightData[i] == 1)
|
2026-05-07 17:09:01 +08:00
|
|
|
|
{
|
2026-05-07 14:59:45 +08:00
|
|
|
|
_rightFinalData[i] = 1;
|
2026-05-07 17:09:01 +08:00
|
|
|
|
}
|
2026-05-07 14:59:45 +08:00
|
|
|
|
}
|
|
|
|
|
|
}
|
2026-05-06 15:00:54 +08:00
|
|
|
|
|
2026-05-06 19:51:57 +08:00
|
|
|
|
// 6. 更新下方视野的最大值(取所有角度中最大的)
|
|
|
|
|
|
if (bottomViewAngle > maxBottomViewAngle)
|
|
|
|
|
|
maxBottomViewAngle = bottomViewAngle;
|
2026-05-06 15:00:54 +08:00
|
|
|
|
|
2026-05-06 19:51:57 +08:00
|
|
|
|
await Dispatcher.InvokeAsync(() =>
|
|
|
|
|
|
{
|
2026-05-07 11:54:20 +08:00
|
|
|
|
zmsyarea.Text = _leftTotalArea.ToString("0");
|
|
|
|
|
|
ymsyarea.Text = _rightTotalArea.ToString("0");
|
|
|
|
|
|
smsyarea.Text = _binocularTotalArea.ToString("0");
|
|
|
|
|
|
xfsyarea.Text = maxBottomViewAngle.ToString("0");
|
2026-05-06 19:51:57 +08:00
|
|
|
|
});
|
2026-04-21 10:19:14 +08:00
|
|
|
|
}
|
2026-04-20 14:03:01 +08:00
|
|
|
|
|
2026-05-07 09:42:23 +08:00
|
|
|
|
//数据共享
|
|
|
|
|
|
private async void ShowAreaData()
|
2026-04-18 18:14:12 +08:00
|
|
|
|
|
2026-04-20 14:03:01 +08:00
|
|
|
|
{
|
2026-05-07 09:42:23 +08:00
|
|
|
|
// 组装当前数据
|
|
|
|
|
|
var data = new TestDataStore.TestRecord
|
|
|
|
|
|
{
|
|
|
|
|
|
Date = DateTime.Now.ToString("yyyy-MM-dd"),
|
|
|
|
|
|
Time = DateTime.Now.ToString("HH:mm:ss"),
|
|
|
|
|
|
LeftEyeArea = double.TryParse(zmsyarea.Text, out var l) ? l : 0,
|
|
|
|
|
|
RightEyeArea = double.TryParse(ymsyarea.Text, out var r) ? r : 0,
|
|
|
|
|
|
BinocularArea = double.TryParse(smsyarea.Text, out var b) ? b : 0,
|
|
|
|
|
|
LowerVision = double.TryParse(xfsyarea.Text, out var lv) ? lv : 0,
|
2026-05-07 19:05:27 +08:00
|
|
|
|
VisionRetentionRate = double.TryParse(sybhl.Text, out var vr) ? vr : 0,
|
|
|
|
|
|
totalVisionArea = double.TryParse(zsyareaNum.Text, out var vrt) ? vrt : 0,
|
|
|
|
|
|
GetVisionRetentionRate = double.TryParse(zsysaveSum.Text, out var vrc) ? vrc : 0,
|
|
|
|
|
|
|
2026-05-07 09:42:23 +08:00
|
|
|
|
};
|
2026-04-23 17:49:59 +08:00
|
|
|
|
|
2026-05-07 09:42:23 +08:00
|
|
|
|
// ==================== 去重判断 ====================
|
|
|
|
|
|
if (_lastRecord != null &&
|
|
|
|
|
|
data.LeftEyeArea == _lastRecord.LeftEyeArea &&
|
|
|
|
|
|
data.RightEyeArea == _lastRecord.RightEyeArea &&
|
|
|
|
|
|
data.BinocularArea == _lastRecord.BinocularArea &&
|
|
|
|
|
|
data.LowerVision == _lastRecord.LowerVision &&
|
2026-05-12 15:57:45 +08:00
|
|
|
|
data.VisionRetentionRate == _lastRecord.VisionRetentionRate &&
|
|
|
|
|
|
data.totalVisionArea == _lastRecord.totalVisionArea &&
|
2026-05-08 17:49:24 +08:00
|
|
|
|
data.GetVisionRetentionRate == _lastRecord.GetVisionRetentionRate
|
|
|
|
|
|
)
|
2026-05-07 09:42:23 +08:00
|
|
|
|
{
|
|
|
|
|
|
return; // 一样就不添加
|
|
|
|
|
|
}
|
2026-05-08 17:49:24 +08:00
|
|
|
|
if (data.BinocularArea == 0)
|
|
|
|
|
|
{
|
|
|
|
|
|
return;
|
|
|
|
|
|
}
|
2026-05-07 09:42:23 +08:00
|
|
|
|
//原来存的数据清空 切换页面会清空
|
|
|
|
|
|
//TestDataStore.Records.Clear();
|
|
|
|
|
|
// 不一样 → 插入表格
|
|
|
|
|
|
TestDataStore.AddNewRecord(data);
|
|
|
|
|
|
_lastRecord = data;
|
2026-04-23 16:02:05 +08:00
|
|
|
|
}
|
2026-05-08 17:17:33 +08:00
|
|
|
|
//试样测试
|
2026-04-18 18:14:12 +08:00
|
|
|
|
|
2026-05-07 09:42:23 +08:00
|
|
|
|
|
2026-05-06 15:00:54 +08:00
|
|
|
|
private async void TbTest_Unchecked(object sender, RoutedEventArgs e)
|
2026-05-08 17:17:33 +08:00
|
|
|
|
{
|
|
|
|
|
|
// 选中 → 试样测试
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
tbTest.Content = "空白测试";
|
|
|
|
|
|
GlobalData.CurrentMode = "空白测试";
|
|
|
|
|
|
|
|
|
|
|
|
tbTest.Background = System.Windows.Media.Brushes.LightSkyBlue;
|
|
|
|
|
|
await _modbusMaster.WriteSingleCoilAsync(1, 41, true);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
private async void TbTest_Checked(object sender, RoutedEventArgs e)
|
2026-04-23 16:02:05 +08:00
|
|
|
|
{
|
|
|
|
|
|
// 取消 → 空白测试
|
2026-04-23 17:49:59 +08:00
|
|
|
|
|
|
|
|
|
|
tbTest.Content = "试样测试";
|
2026-05-08 17:00:57 +08:00
|
|
|
|
GlobalData.CurrentMode = "试样测试";
|
2026-04-23 17:49:59 +08:00
|
|
|
|
tbTest.Background = System.Windows.Media.Brushes.LightGray;
|
2026-05-06 15:00:54 +08:00
|
|
|
|
await _modbusMaster.WriteSingleCoilAsync(1, 41, false);
|
2026-04-18 18:14:12 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
//读取数据
|
|
|
|
|
|
private DispatcherTimer InitDispatcherTimer()
|
|
|
|
|
|
{
|
|
|
|
|
|
var timer = new DispatcherTimer
|
|
|
|
|
|
{
|
2026-04-21 16:39:29 +08:00
|
|
|
|
Interval = TimeSpan.FromMilliseconds(500)
|
2026-04-18 18:14:12 +08:00
|
|
|
|
};
|
|
|
|
|
|
timer.Tick += async (s, e) =>
|
|
|
|
|
|
{
|
|
|
|
|
|
if (_modbusMaster != null)
|
|
|
|
|
|
{
|
|
|
|
|
|
try
|
|
|
|
|
|
{
|
|
|
|
|
|
await ReadAddr262DataAsync();
|
|
|
|
|
|
}
|
|
|
|
|
|
catch { }
|
|
|
|
|
|
}
|
|
|
|
|
|
};
|
|
|
|
|
|
return timer;
|
|
|
|
|
|
}
|
2026-05-05 14:27:47 +08:00
|
|
|
|
|
2026-04-18 18:14:12 +08:00
|
|
|
|
private async System.Threading.Tasks.Task ReadAddr262DataAsync()
|
|
|
|
|
|
{
|
|
|
|
|
|
try
|
|
|
|
|
|
{
|
|
|
|
|
|
// 创建任务列表
|
|
|
|
|
|
var tasks = new List<Task>
|
|
|
|
|
|
{
|
2026-04-21 16:39:29 +08:00
|
|
|
|
//ReadAndUpdateFloatAsync(200, 2, fbspeed, "F2", "°"),
|
|
|
|
|
|
//ReadAndUpdateFloatAsync(202, 2, dqangle, "F2", "°"),
|
|
|
|
|
|
//ReadAndUpdateFloatAsync(204, 2, zmsyarea, "F2", "cm²"),
|
|
|
|
|
|
//ReadAndUpdateFloatAsync(206 ,2, xfsyarea, "F2", " "),
|
|
|
|
|
|
//ReadAndUpdateFloatAsync(208, 2, smsyarea, "F2", "cm²"),
|
|
|
|
|
|
//ReadAndUpdateFloatAsync(210 ,2, ymsyarea, "F2", " "),
|
|
|
|
|
|
ReadAndUpdateFloatRangeAsync(200, 12, "F2", "°"),
|
2026-04-25 18:32:37 +08:00
|
|
|
|
//ReadAndUpdateFloatAsync(424 ,2, kbsyarea, "F2", "cm²"),
|
2026-05-06 15:00:54 +08:00
|
|
|
|
ReadAndUpdateFloatAsync(310, 2, zdangle, "F2", ""),
|
2026-04-25 18:32:37 +08:00
|
|
|
|
//ReadAndUpdateFloatAsync(430 ,2, sybhl, "F2", " "),
|
2026-04-18 18:14:12 +08:00
|
|
|
|
|
2026-04-25 18:32:37 +08:00
|
|
|
|
//前1从站地址,后1是长度
|
2026-05-08 17:00:57 +08:00
|
|
|
|
|
2026-05-04 17:42:39 +08:00
|
|
|
|
|
2026-05-05 10:20:03 +08:00
|
|
|
|
};
|
2026-05-06 10:52:53 +08:00
|
|
|
|
isFinished = _modbusMaster.ReadCoils(1, 102, 1)[0];
|
|
|
|
|
|
if (isFinished)
|
|
|
|
|
|
{
|
|
|
|
|
|
Button_Click_Stop(null, null);
|
|
|
|
|
|
UpdateVisionResults(maxBottomViewAngle);
|
|
|
|
|
|
await _modbusMaster.WriteSingleCoilAsync(1, 102, false);
|
|
|
|
|
|
isFinished = false;
|
|
|
|
|
|
|
|
|
|
|
|
}
|
2026-05-12 15:57:45 +08:00
|
|
|
|
|
|
|
|
|
|
|
2026-05-08 17:00:57 +08:00
|
|
|
|
if (double.TryParse(fbspeed.Text, out double result))
|
|
|
|
|
|
{
|
2026-05-12 15:57:45 +08:00
|
|
|
|
GlobalData.JudgmentalPerspective = result.ToString();
|
2026-05-08 17:00:57 +08:00
|
|
|
|
}
|
2026-05-12 15:57:45 +08:00
|
|
|
|
|
2026-04-18 18:14:12 +08:00
|
|
|
|
await Task.WhenAll(tasks);
|
|
|
|
|
|
}
|
|
|
|
|
|
catch (Exception ex)
|
|
|
|
|
|
{
|
|
|
|
|
|
ShowError($"读取数据失败:{ex.Message}");
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
2026-04-20 14:03:01 +08:00
|
|
|
|
// 地址, 根据格式显示字符长度 32:2 16:1 ,绑定页面的name 值,F2 保留两位小数,单位
|
2026-04-18 18:14:12 +08:00
|
|
|
|
private async Task ReadAndUpdateFloatAsync(int address, int length, System.Windows.Controls.TextBox control, string format, string unit)
|
|
|
|
|
|
{
|
|
|
|
|
|
try
|
2026-04-22 16:02:37 +08:00
|
|
|
|
{ // 1. 页面销毁时直接退出,不执行
|
|
|
|
|
|
if (_cts?.IsCancellationRequested == true) return;
|
|
|
|
|
|
|
|
|
|
|
|
// 2. 关键:判断对象为空就直接返回,不执行
|
|
|
|
|
|
if (_modbusMaster == null) return;
|
|
|
|
|
|
|
2026-04-18 18:14:12 +08:00
|
|
|
|
ushort[] registers = await Task.Run(async () =>
|
2026-04-22 15:03:14 +08:00
|
|
|
|
await _modbusMaster!.ReadHoldingRegistersAsync(1, (ushort)address, (ushort)length)
|
2026-04-18 18:14:12 +08:00
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
|
|
if (registers != null && registers.Length >= 2)
|
|
|
|
|
|
{
|
|
|
|
|
|
float value = c.UshortToFloat(registers[1], registers[0]);
|
|
|
|
|
|
Dispatcher.Invoke(() => control.Text = value.ToString(format) + unit);
|
|
|
|
|
|
}
|
|
|
|
|
|
else if (registers != null && registers.Length >= 1)
|
|
|
|
|
|
{
|
|
|
|
|
|
int value = registers[0];
|
|
|
|
|
|
Dispatcher.Invoke(() => control.Text = value.ToString(format) + unit);
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
catch (Exception ex)
|
|
|
|
|
|
{
|
|
|
|
|
|
System.Diagnostics.Debug.WriteLine($"读取地址{address}失败:{ex.Message}");
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2026-04-21 16:39:29 +08:00
|
|
|
|
|
|
|
|
|
|
private async Task ReadAndUpdateFloatRangeAsync(int address, int length, string format, string unit)
|
|
|
|
|
|
{
|
|
|
|
|
|
try
|
|
|
|
|
|
{
|
|
|
|
|
|
ushort[] registers = await Task.Run(async () =>
|
2026-04-22 15:03:14 +08:00
|
|
|
|
await _modbusMaster!.ReadHoldingRegistersAsync(1, (ushort)address, (ushort)length)
|
2026-04-21 16:39:29 +08:00
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
|
|
if (registers != null && registers.Length >= 2)
|
|
|
|
|
|
{
|
|
|
|
|
|
float value = c.UshortToFloat(registers[1], registers[0]);
|
|
|
|
|
|
float value2 = c.UshortToFloat(registers[3], registers[2]);
|
|
|
|
|
|
float value3 = c.UshortToFloat(registers[5], registers[4]);
|
2026-04-25 18:32:37 +08:00
|
|
|
|
//float value4 = c.UshortToFloat(registers[7], registers[6]);
|
|
|
|
|
|
//float value5 = c.UshortToFloat(registers[9], registers[8]);
|
|
|
|
|
|
//float value6 = c.UshortToFloat(registers[11], registers[10]);
|
2026-05-06 10:52:53 +08:00
|
|
|
|
currentAngle = value2;
|
2026-04-21 16:39:29 +08:00
|
|
|
|
|
|
|
|
|
|
Dispatcher.Invoke(() =>
|
|
|
|
|
|
|
|
|
|
|
|
{
|
2026-05-06 19:51:57 +08:00
|
|
|
|
fbspeed.Text = value.ToString(format);
|
|
|
|
|
|
dqangle.Text = value2.ToString(format);
|
2026-04-25 18:32:37 +08:00
|
|
|
|
//zmsyarea.Text = value3.ToString(format) + unit;
|
|
|
|
|
|
//xfsyarea.Text = value4.ToString(format) + unit;
|
|
|
|
|
|
//smsyarea.Text = value5.ToString(format) + unit;
|
|
|
|
|
|
//ymsyarea.Text = value6.ToString(format) + unit;
|
2026-04-21 16:39:29 +08:00
|
|
|
|
//control.Text = value.ToString(format) + unit);
|
|
|
|
|
|
});
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
catch (Exception ex)
|
|
|
|
|
|
{
|
|
|
|
|
|
System.Diagnostics.Debug.WriteLine($"读取地址{address}失败:{ex.Message}");
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2026-05-07 09:42:23 +08:00
|
|
|
|
//打印
|
|
|
|
|
|
|
|
|
|
|
|
private void Button_Click_Print(object sender, RoutedEventArgs e)
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
|
|
|
|
ma.BtnClickFunction(Function.ButtonType.复归型, 103);
|
|
|
|
|
|
|
|
|
|
|
|
}
|
2026-05-12 15:57:45 +08:00
|
|
|
|
|
2026-05-07 09:42:23 +08:00
|
|
|
|
|
|
|
|
|
|
// 蓝色亮(蓝色)
|
|
|
|
|
|
private void LedOn(Ellipse led)
|
|
|
|
|
|
{
|
|
|
|
|
|
led.Fill = Brushes.LightSkyBlue;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 灯灭(灰色)
|
|
|
|
|
|
private void LedOff(Ellipse led)
|
|
|
|
|
|
{
|
|
|
|
|
|
led.Fill = Brushes.LightGray;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
//复位btn
|
|
|
|
|
|
private void Button_Click_Reset(object sender, RoutedEventArgs e)
|
|
|
|
|
|
{
|
2026-05-07 10:26:39 +08:00
|
|
|
|
//btnLeft.Content = "左眼开";
|
|
|
|
|
|
//btnRight.Content = "右眼开";
|
|
|
|
|
|
//LedOff(led1);
|
|
|
|
|
|
//LedOff(led0);
|
2026-05-13 11:27:47 +08:00
|
|
|
|
|
2026-05-13 14:14:14 +08:00
|
|
|
|
|
|
|
|
|
|
|
2026-05-13 11:27:47 +08:00
|
|
|
|
//// 2. 清空累加值
|
|
|
|
|
|
_leftTotalArea = 0;
|
|
|
|
|
|
_rightTotalArea = 0;
|
|
|
|
|
|
_binocularTotalArea = 0;
|
|
|
|
|
|
maxBottomViewAngle = 0;
|
|
|
|
|
|
|
|
|
|
|
|
//初始化:全部设为0(灭)
|
|
|
|
|
|
_leftFinalData = Enumerable.Repeat(0, 240).ToList();
|
|
|
|
|
|
_rightFinalData = Enumerable.Repeat(0, 240).ToList();
|
|
|
|
|
|
DataList.Clear();
|
2026-05-07 09:42:23 +08:00
|
|
|
|
ma.BtnClickFunction(Function.ButtonType.复归型, 90);
|
2026-05-07 11:54:20 +08:00
|
|
|
|
zmsyarea.Text = "0"; // 左目
|
|
|
|
|
|
smsyarea.Text = "0"; // 双目
|
|
|
|
|
|
kbsyarea.Text = "0"; // 空白
|
|
|
|
|
|
ymsyarea.Text = "0"; // 右目
|
|
|
|
|
|
xfsyarea.Text = "0"; // 下方
|
|
|
|
|
|
sybhl.Text = "0"; // 视野保存率
|
2026-05-07 19:05:27 +08:00
|
|
|
|
zsyareaNum.Text = "0";
|
|
|
|
|
|
zsysaveSum.Text = "0";
|
2026-05-07 09:42:23 +08:00
|
|
|
|
}
|
|
|
|
|
|
//左开眼
|
|
|
|
|
|
private void Button_Click_left(object sender, RoutedEventArgs e)
|
|
|
|
|
|
{
|
|
|
|
|
|
// 切换文案:开是关,关是开
|
|
|
|
|
|
if (btnLeft.Content.ToString() == "左眼开")
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
btnLeft.Content = "左眼关";
|
|
|
|
|
|
LedOn(led0);
|
2026-05-13 14:16:57 +08:00
|
|
|
|
|
2026-05-07 09:42:23 +08:00
|
|
|
|
if (btnRight.Content.ToString() == "右眼关")
|
|
|
|
|
|
{
|
|
|
|
|
|
btnRight.Content = "右眼开";
|
|
|
|
|
|
LedOff(led1);
|
|
|
|
|
|
ma.BtnClickFunction(Function.ButtonType.切换型, 1);
|
2026-05-13 14:16:57 +08:00
|
|
|
|
|
2026-05-07 09:42:23 +08:00
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
else
|
|
|
|
|
|
{
|
|
|
|
|
|
btnLeft.Content = "左眼开";
|
|
|
|
|
|
LedOff(led0);
|
|
|
|
|
|
}
|
|
|
|
|
|
ma.BtnClickFunction(Function.ButtonType.切换型, 0);
|
2026-05-13 14:14:14 +08:00
|
|
|
|
//GlobalData.LampValueLeft = btnLeft.Content.ToString();
|
2026-05-07 09:42:23 +08:00
|
|
|
|
}
|
|
|
|
|
|
//右开眼
|
|
|
|
|
|
private void Button_Click_Right(object sender, RoutedEventArgs e)
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
|
|
|
|
// 切换文案:左眼开 ↔ 左眼关
|
|
|
|
|
|
if (btnRight.Content.ToString() == "右眼开")
|
|
|
|
|
|
{
|
|
|
|
|
|
btnRight.Content = "右眼关";
|
|
|
|
|
|
LedOn(led1);
|
|
|
|
|
|
if (btnLeft.Content.ToString() == "左眼关")
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
|
|
|
|
btnLeft.Content = "左眼开";
|
|
|
|
|
|
LedOff(led0);
|
|
|
|
|
|
ma.BtnClickFunction(Function.ButtonType.切换型, 0);
|
|
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
else
|
|
|
|
|
|
{
|
|
|
|
|
|
btnRight.Content = "右眼开";
|
|
|
|
|
|
LedOff(led1);
|
|
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
ma.BtnClickFunction(Function.ButtonType.切换型, 1);
|
2026-05-13 14:14:14 +08:00
|
|
|
|
//GlobalData.LampValueLeft = btnLeft.Content.ToString();
|
2026-05-07 09:42:23 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
//反转
|
|
|
|
|
|
private async void Button_Click_ResDown(object sender, MouseButtonEventArgs e)
|
|
|
|
|
|
{
|
|
|
|
|
|
await _modbusMaster.WriteSingleCoilAsync(1, 10, true);
|
|
|
|
|
|
System.Diagnostics.Debug.WriteLine("反转开始");
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
private async void Button_Click_ResUp(object sender, MouseButtonEventArgs e)
|
|
|
|
|
|
{
|
|
|
|
|
|
await _modbusMaster.WriteSingleCoilAsync(1, 10, false);
|
|
|
|
|
|
System.Diagnostics.Debug.WriteLine("反转结束");
|
|
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
//正转
|
|
|
|
|
|
|
|
|
|
|
|
private async void Button_Click_ForDown(object sender, MouseButtonEventArgs e)
|
|
|
|
|
|
{
|
|
|
|
|
|
await _modbusMaster.WriteSingleCoilAsync(1, 11, true);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
private async void Button_Click_ForUp(object sender, MouseButtonEventArgs e)
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
|
|
|
|
await _modbusMaster.WriteSingleCoilAsync(1, 11, false);
|
|
|
|
|
|
//System.Diagnostics.Debug.WriteLine("正传end");
|
|
|
|
|
|
}
|
2026-04-18 18:14:12 +08:00
|
|
|
|
|
|
|
|
|
|
//写入
|
|
|
|
|
|
private void fbspeed_GotFocus(object sender, RoutedEventArgs e)
|
|
|
|
|
|
{
|
|
|
|
|
|
ma.WriteToPLCForNew(fbspeed.Text.Trim(), 200, Function.DataType.浮点型);
|
|
|
|
|
|
//程序等待50s 在进行
|
|
|
|
|
|
System.Threading.Tasks.Task.Delay(50);
|
|
|
|
|
|
fbspeed.Focus();
|
|
|
|
|
|
}
|
|
|
|
|
|
private void dqangle_GotFocus(object sender, RoutedEventArgs e)
|
|
|
|
|
|
{
|
2026-04-23 10:31:17 +08:00
|
|
|
|
ma.WriteToPLCForNew(dqangle.Text.Trim(), 202, Function.DataType.浮点型);
|
2026-04-18 18:14:12 +08:00
|
|
|
|
System.Threading.Tasks.Task.Delay(50);
|
2026-04-23 10:31:17 +08:00
|
|
|
|
dqangle.Focus();
|
2026-04-18 18:14:12 +08:00
|
|
|
|
}
|
|
|
|
|
|
private void zdangle_GotFocus(object sender, RoutedEventArgs e)
|
|
|
|
|
|
{
|
2026-04-23 10:31:17 +08:00
|
|
|
|
ma.WriteToPLCForNew(zdangle.Text.Trim(), 310, Function.DataType.浮点型);
|
2026-04-18 18:14:12 +08:00
|
|
|
|
System.Threading.Tasks.Task.Delay(50);
|
2026-04-23 10:31:17 +08:00
|
|
|
|
zdangle.Focus();
|
2026-04-18 18:14:12 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
//错误信息提示
|
|
|
|
|
|
private void ShowError(string msg) => MessageBox.Show(msg, "错误", MessageBoxButton.OK, MessageBoxImage.Error);
|
|
|
|
|
|
private void GoHome(object s, RoutedEventArgs e) => NavigationService.Content = null;
|
2026-04-21 16:39:29 +08:00
|
|
|
|
private void GoTest(object s, RoutedEventArgs e)
|
|
|
|
|
|
{
|
|
|
|
|
|
_timer.Stop();
|
|
|
|
|
|
NavigationService.Content = new Views.PageTest();
|
|
|
|
|
|
}
|
2026-04-18 18:14:12 +08:00
|
|
|
|
private void GoView(object s, RoutedEventArgs e) => NavigationService.Content = new Views.RecordPage();
|
2026-05-13 11:27:47 +08:00
|
|
|
|
//初始化数据
|
2026-05-13 14:14:14 +08:00
|
|
|
|
private void InitAllDataAsync()
|
2026-05-13 11:27:47 +08:00
|
|
|
|
{
|
2026-04-21 16:39:29 +08:00
|
|
|
|
|
2026-05-13 11:27:47 +08:00
|
|
|
|
//System.Diagnostics.Debug.WriteLine($"数据加载了啊 ");
|
|
|
|
|
|
// 从全局数据读取当前模式
|
|
|
|
|
|
string mode = GlobalData.CurrentMode;
|
2026-05-13 14:14:14 +08:00
|
|
|
|
|
2026-05-13 11:27:47 +08:00
|
|
|
|
if (mode == "试样测试")
|
|
|
|
|
|
{
|
|
|
|
|
|
TbTest_Checked(null, null);
|
|
|
|
|
|
}
|
2026-05-13 14:14:14 +08:00
|
|
|
|
testTimerForLightTick(null, null);
|
2026-05-13 11:27:47 +08:00
|
|
|
|
}
|
2026-05-13 14:14:14 +08:00
|
|
|
|
private void Page_Loaded(object sender, RoutedEventArgs e)
|
2026-04-18 18:14:12 +08:00
|
|
|
|
{
|
2026-04-25 18:32:37 +08:00
|
|
|
|
|
2026-05-12 15:57:45 +08:00
|
|
|
|
|
2026-04-20 14:03:01 +08:00
|
|
|
|
_timer.Start();
|
2026-04-21 11:15:37 +08:00
|
|
|
|
ma = new Function(_modbusMaster);
|
|
|
|
|
|
c = new DataChange();
|
2026-05-12 16:12:31 +08:00
|
|
|
|
//testTimerForLight.Start();
|
2026-04-23 13:41:26 +08:00
|
|
|
|
//zmsyarea.Text = "4.00"; // 左目
|
|
|
|
|
|
//smsyarea.Text = "5.00"; // 双目
|
|
|
|
|
|
//kbsyarea.Text = "6.00"; // 空白
|
|
|
|
|
|
//ymsyarea.Text = "7.00"; // 右目
|
|
|
|
|
|
//xfsyarea.Text = "8.00"; // 下方
|
|
|
|
|
|
//sybhl.Text = "9.00"; // 视野保存率
|
2026-05-13 14:16:57 +08:00
|
|
|
|
|
2026-05-13 11:27:47 +08:00
|
|
|
|
|
2026-04-18 18:14:12 +08:00
|
|
|
|
}
|
2026-04-22 16:02:37 +08:00
|
|
|
|
private void Page_Unloaded(object sender, RoutedEventArgs e)
|
|
|
|
|
|
{
|
|
|
|
|
|
testTimer?.Stop();
|
|
|
|
|
|
_timer?.Stop();
|
|
|
|
|
|
_cts?.Cancel();
|
|
|
|
|
|
_cts = null;
|
|
|
|
|
|
|
2026-05-13 16:03:35 +08:00
|
|
|
|
_modbusMaster.WriteSingleCoil(1, 1, false);
|
|
|
|
|
|
|
|
|
|
|
|
_modbusMaster.WriteSingleCoil(1, 0, false);
|
2026-04-22 16:02:37 +08:00
|
|
|
|
}
|
2026-05-04 17:42:39 +08:00
|
|
|
|
|
2026-04-18 18:14:12 +08:00
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|