| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187 |
- using System;
- using System.ComponentModel;
- using System.Threading.Tasks;
- using Prism.Commands;
- using Prism.Mvvm;
- using TeamAAS_VP.Interfaces;
- using TeamAAS_VP.Models;
- namespace TeamAAS_VP.Core.Robots
- {
- /// <summary>
- /// Axis view-model for binding to View: provides Axis + / - commands, axis name and current position.
- /// </summary>
- public class AxisViewModel : BindableBase, IDisposable
- {
- private readonly IRobot _robot;
- private readonly string _axisName;
- private double _currentPosition;
- private double _step;
- public DelegateCommand AxisPlusCommand { get; private set; }
- public DelegateCommand AxisMinusCommand { get; private set; }
- /// <summary>
- /// 轴名称(X/Y/Z/U)
- /// </summary>
- public string AxisName => _axisName;
- /// <summary>
- /// 当前轴位置(从 Robot 读取或命令后更新)
- /// </summary>
- public double CurrentPosition
- {
- get => _currentPosition;
- private set => SetProperty(ref _currentPosition, value);
- }
- /// <summary>
- /// 每次 jog 的步长(可设置)
- /// </summary>
- public double Step
- {
- get => _step;
- set
- {
- if (SetProperty(ref _step, value))
- {
- RaiseCanExecuteChanged();
- }
- }
- }
- public AxisViewModel(string axisName, IRobot robot, double step = 1.0)
- {
- if (string.IsNullOrWhiteSpace(axisName)) throw new ArgumentNullException(nameof(axisName));
- _axisName = axisName.ToUpper();
- _robot = robot ?? throw new ArgumentNullException(nameof(robot));
- _step = step;
- AxisPlusCommand = DelegateCommand.FromAsyncHandler(ExecutePlusAsync, CanExecuteCommands);
- AxisMinusCommand = DelegateCommand.FromAsyncHandler(ExecuteMinusAsync, CanExecuteCommands);
- // 尝试初始化当前位置(异步,不阻塞构造)
- Task.Run(async () => await UpdatePositionFromRobotAsync());
- // 订阅机器人属性变化以刷新命令可用性
- if (_robot is INotifyPropertyChanged npc)
- {
- npc.PropertyChanged += Robot_PropertyChanged;
- }
- }
- private void Robot_PropertyChanged(object sender, PropertyChangedEventArgs e)
- {
- // 监听 CanExecute 或 IsConnected 等关键属性名(Robots 中使用 CanExecute 字段)
- if (string.Equals(e.PropertyName, nameof(XYZU_Robot.CanExecute), StringComparison.OrdinalIgnoreCase) ||
- string.Equals(e.PropertyName, nameof(IRobot.CanExecute), StringComparison.OrdinalIgnoreCase) ||
- string.Equals(e.PropertyName, nameof(IRobot.IsConnected), StringComparison.OrdinalIgnoreCase))
- {
- RaiseCanExecuteChanged();
- }
- }
- private bool CanExecuteCommands()
- {
- try
- {
- if (_robot == null) return false;
- // 优先使用机器人公开的 CanExecute 属性(若存在),否则回退到 IsConnected
- var canExecuteProp = _robot.GetType().GetProperty("CanExecute");
- if (canExecuteProp != null && canExecuteProp.PropertyType == typeof(bool))
- {
- return (bool)canExecuteProp.GetValue(_robot);
- }
- return _robot.IsConnected;
- }
- catch
- {
- return false;
- }
- }
- private void RaiseCanExecuteChanged()
- {
- AxisPlusCommand.RaiseCanExecuteChanged();
- AxisMinusCommand.RaiseCanExecuteChanged();
- }
- private async Task ExecutePlusAsync()
- {
- if (!CanExecuteCommands()) return;
- try
- {
- await _robot.JogAsync(_axisName, Step);
- }
- catch
- {
- // 忽略错误,视需求可扩展日志或通知
- }
- await UpdatePositionFromRobotAsync();
- }
- private async Task ExecuteMinusAsync()
- {
- if (!CanExecuteCommands()) return;
- try
- {
- await _robot.JogAsync(_axisName, -Step);
- }
- catch
- {
- // 忽略错误
- }
- await UpdatePositionFromRobotAsync();
- }
- /// <summary>
- /// 从 Robot 读取完整位置并更新当前轴的 CurrentPosition
- /// </summary>
- public async Task UpdatePositionFromRobotAsync()
- {
- try
- {
- var pos = await _robot.GetRobotPosAsync();
- if (pos == null) return;
- switch (_axisName)
- {
- case "X":
- CurrentPosition = pos.X;
- break;
- case "Y":
- CurrentPosition = pos.Y;
- break;
- case "Z":
- CurrentPosition = pos.Z;
- break;
- case "U":
- CurrentPosition = pos.U;
- break;
- default:
- // 未知轴,保持不变
- break;
- }
- }
- catch
- {
- // 忽略读取错误
- }
- }
- public void Dispose()
- {
- if (_robot is INotifyPropertyChanged npc)
- {
- npc.PropertyChanged -= Robot_PropertyChanged;
- }
- }
- }
- }
|