using System;
using System.Linq;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Controls.Primitives;
using TeamAAS.Global.Devices;
namespace TeamAAS.Motion
{
///
/// 运动/IO 通用调试页面:轴状态表 + 定位/回零/使能/停止 + IO 输出点翻转。
/// 所有运动卡与 IO 卡(仿真/雷赛/固高/IMC60G/GR20T…)共用此页面(设备内核·统一调试页要求);
/// 品牌特有调试能力可通过 IDeviceDebugPageFactory 提供专用页面替换本页。
///
public partial class MotionDebugView : UserControl
{
private IMotionCard _motion;
private IIOCard _io;
private readonly System.Windows.Threading.DispatcherTimer _refreshTimer;
public MotionDebugView()
{
InitializeComponent();
_refreshTimer = new System.Windows.Threading.DispatcherTimer { Interval = TimeSpan.FromMilliseconds(300) };
_refreshTimer.Tick += (s, e) => RefreshStatus();
}
/// 绑定设备(运动卡或 IO 卡,二选一或同时实现)。
public void Bind(object device)
{
_motion = device as IMotionCard;
_io = device as IIOCard;
TxtTitle.Text = (_motion as TeamAAS.Global.Devices.INamedDevice)?.Name
?? (_io as TeamAAS.Global.Devices.INamedDevice)?.Name
?? "运动/IO 调试";
if (_motion != null)
{
AxisGrid.ItemsSource = _motion.GetAllAxisStatus();
}
else
{
AxisGrid.Visibility = Visibility.Collapsed;
}
BuildIoPanel();
_refreshTimer.Start();
RefreshStatus();
}
private IMotionCard Motion => _motion;
private IIOCard Io => _io;
private void BuildIoPanel()
{
IoPanel.Children.Clear();
if (_io == null)
{
IoPanel.Visibility = Visibility.Collapsed;
return;
}
IoPanel.Visibility = Visibility.Visible;
for (int i = 0; i < _io.OutputCount; i++)
{
int index = i;
var btn = new ToggleButton
{
Content = $"Y{index}",
Width = 44,
Margin = new Thickness(2),
};
btn.Checked += (s, e) => _io.WriteOutput(index, true);
btn.Unchecked += (s, e) => _io.WriteOutput(index, false);
IoPanel.Children.Add(btn);
}
}
private void RefreshStatus()
{
try
{
if (_motion != null && _motion.IsConnected)
AxisGrid.ItemsSource = _motion.GetAllAxisStatus();
if (_io != null && _io.IsConnected)
{
var outs = _io.ReadAllOutputs();
var ins = _io.ReadAllInputs();
for (int i = 0; i < IoPanel.Children.Count && i < outs.Length; i++)
{
if (IoPanel.Children[i] is ToggleButton tb && tb.IsChecked != outs[i])
{
_suppressIo = true;
tb.IsChecked = outs[i];
_suppressIo = false;
}
}
TxtStatus.Text = $"已连接 · 输入:{ToMask(ins)} 输出:{ToMask(outs)}";
}
else
{
TxtStatus.Text = _motion != null && _motion.IsConnected ? "已连接" : "未连接";
}
}
catch { }
}
private bool _suppressIo;
private static string ToMask(bool[] bits)
=> bits == null ? "" : new string(bits.Select(b => b ? '1' : '0').ToArray());
private bool TryGetAxis(out int axis, out double vel, out double pos)
{
axis = 0; vel = 100; pos = 0;
if (_motion == null) return false;
return int.TryParse(TxtAxis.Text, out axis)
&& double.TryParse(TxtVel.Text, out vel)
&& double.TryParse(TxtPos.Text, out pos);
}
private void BtnOpen_Click(object sender, RoutedEventArgs e)
{
try
{
bool ok = (_motion as IConnectableDevice)?.Open()
?? (_io as IConnectableDevice)?.Open() ?? false;
TxtStatus.Text = ok ? "已连接" : "连接失败";
}
catch (Exception ex) { TxtStatus.Text = "连接失败: " + ex.Message; }
}
private void BtnClose_Click(object sender, RoutedEventArgs e)
{
try { (_motion as IConnectableDevice)?.Close(); (_io as IConnectableDevice)?.Close(); } catch { }
TxtStatus.Text = "未连接";
}
private void BtnMoveAbs_Click(object sender, RoutedEventArgs e)
{
if (TryGetAxis(out var axis, out var vel, out var pos))
_motion?.MoveAbsolute(axis, pos, vel);
}
private void BtnEnable_Click(object sender, RoutedEventArgs e)
{
if (int.TryParse(TxtAxis.Text, out var axis)) _motion?.SetEnable(axis, true);
}
private void BtnHome_Click(object sender, RoutedEventArgs e)
{
if (int.TryParse(TxtAxis.Text, out var axis)) _motion?.Home(axis);
}
private void BtnStop_Click(object sender, RoutedEventArgs e)
{
_motion?.Stop(-1);
}
private void BtnRefresh_Click(object sender, RoutedEventArgs e) => RefreshStatus();
}
///
/// 运动/IO 设备通用调试页工厂:注册到设备调试页体系后,所有运动卡/IO 卡自动获得调试页面。
///
public class MotionDebugPageFactory : TeamAAS.Global.Devices.IDeviceDebugPageFactory
{
public string DeviceCategory => "运动卡";
public object CreatePage(object device)
{
var view = new MotionDebugView();
view.Bind(device);
return view;
}
}
}