| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232 |
- using System;
- using System.Collections.Generic;
- using System.Collections.ObjectModel;
- using System.ComponentModel;
- using System.Linq;
- using System.Windows;
- using TeamAAS.Motion.Models;
- namespace TeamAAS.Views
- {
- public partial class EditMotionAxesDialog
- {
- public ObservableCollection<AxisEditRow> Rows { get; } = new ObservableCollection<AxisEditRow>();
- public List<MotionAxisConfig> Result { get; private set; }
- public EditMotionAxesDialog(IEnumerable<MotionAxisConfig> axes)
- {
- InitializeComponent();
- DataContext = this;
- foreach (var cfg in axes ?? Enumerable.Empty<MotionAxisConfig>())
- Rows.Add(AxisEditRow.FromConfig(cfg));
- if (Rows.Count == 0)
- {
- foreach (var cfg in MotionAxisCatalog.CreateDefaults(4))
- Rows.Add(AxisEditRow.FromConfig(cfg));
- }
- }
- private void BtnAdd_Click(object sender, RoutedEventArgs e)
- {
- int next = Rows.Count == 0 ? 0 : Rows.Max(r => r.AxisNo) + 1;
- Rows.Add(new AxisEditRow
- {
- AxisNo = next,
- Name = next < MotionAxisCatalog.DefaultNames.Length ? MotionAxisCatalog.DefaultNames[next] : $"Axis-{next}",
- KindName = "实轴",
- OutputChannel = next
- });
- }
- private void BtnAddCombined_Click(object sender, RoutedEventArgs e)
- {
- var selectedItems = GridAxes.SelectedItems.Cast<AxisEditRow>().ToList();
- var master = GridAxes.SelectedItem as AxisEditRow;
- if (master == null || master.Kind != MotionAxisKind.Virtual)
- master = selectedItems.FirstOrDefault(r => r.Kind == MotionAxisKind.Virtual);
- if (master == null || master.Kind != MotionAxisKind.Virtual)
- {
- DialogHelper.ShowWarning("请先选中一条虚轴作为主轴,再添加从轴");
- return;
- }
- var existing = new HashSet<int>(master.ToConfig().ParseMembers().Select(m => m.AxisNo))
- {
- master.AxisNo
- };
- var slaves = selectedItems
- .Where(r => r != master && !r.ToConfig().IsGrouped)
- .Select(r => r.AxisNo)
- .Where(no => !existing.Contains(no))
- .Distinct()
- .ToList();
- if (slaves.Count == 0)
- {
- var candidate = Rows.FirstOrDefault(r =>
- r != master && !r.ToConfig().IsGrouped && !existing.Contains(r.AxisNo));
- if (candidate != null)
- slaves.Add(candidate.AxisNo);
- }
- if (slaves.Count == 0)
- {
- DialogHelper.ShowWarning("没有可添加的从轴。请先添加一条实轴或未跟随的虚轴");
- return;
- }
- var parts = string.IsNullOrWhiteSpace(master.CombinedMembers)
- ? new List<string>()
- : master.CombinedMembers
- .Split(new[] { ',', ';', ' ', ',' }, StringSplitOptions.RemoveEmptyEntries)
- .Select(s => s.Trim())
- .Where(s => s.Length > 0)
- .ToList();
- foreach (var no in slaves)
- {
- if (!existing.Contains(no))
- parts.Add(no.ToString());
- }
- master.CombinedMembers = string.Join(",", parts);
- GridAxes.SelectedItem = master;
- GridAxes.ScrollIntoView(master);
- DialogHelper.Info($"虚轴 {master.Name} 已添加从轴:{string.Join(",", slaves)}");
- }
- private void BtnRemove_Click(object sender, RoutedEventArgs e)
- {
- var selected = GridAxes.SelectedItems.Cast<AxisEditRow>().ToList();
- foreach (var row in selected)
- Rows.Remove(row);
- }
- private void BtnOK_Click(object sender, RoutedEventArgs e)
- {
- string err = Validate();
- if (err != null)
- {
- DialogHelper.ShowWarning(err);
- return;
- }
- Result = Rows.Select(r => r.ToConfig()).ToList();
- DialogResult = true;
- }
- private string Validate()
- {
- if (Rows.Count == 0) return "至少配置一条轴";
- var nos = new HashSet<int>();
- foreach (var row in Rows)
- {
- if (row.AxisNo < 0 || row.AxisNo > 63) return $"轴号 {row.AxisNo} 超出范围 [0,63]";
- if (!nos.Add(row.AxisNo)) return $"轴号 {row.AxisNo} 重复";
- if (string.IsNullOrWhiteSpace(row.Name)) return $"轴 {row.AxisNo} 名称为空";
- }
- var leafNos = new HashSet<int>(Rows.Where(r => !r.ToConfig().IsGrouped).Select(r => r.AxisNo));
- foreach (var row in Rows)
- {
- var cfg = row.ToConfig();
- var members = cfg.ParseMembers();
- bool wantGroup = cfg.Kind == MotionAxisKind.Combined
- || (cfg.Kind == MotionAxisKind.Virtual && !string.IsNullOrWhiteSpace(cfg.CombinedMembers));
- if (!wantGroup) continue;
- if (members.Count < 1) return $"{cfg.KindText} {row.Name} 至少需要 1 个从轴";
- foreach (var m in members)
- {
- if (m.AxisNo == row.AxisNo) return $"{row.Name} 不能把自身当作从轴";
- if (!leafNos.Contains(m.AxisNo))
- return $"{row.Name} 的从轴 {m.AxisNo} 必须是已有的实轴或未跟随的虚轴";
- }
- }
- return null;
- }
- }
- public class AxisEditRow : INotifyPropertyChanged
- {
- private int _axisNo;
- private string _name = "Axis";
- private MotionAxisKind _kind;
- private int _outputChannel;
- private string _combinedMembers = "";
- private double _velocity = 100;
- private bool _softLimitEnabled;
- private double _softLimitNeg;
- private double _softLimitPos;
- private double _maxVelocity;
- public int AxisNo { get => _axisNo; set { _axisNo = value; OnChanged(nameof(AxisNo)); } }
- public string Name { get => _name; set { _name = value; OnChanged(nameof(Name)); } }
- public MotionAxisKind Kind { get => _kind; set { _kind = value; OnChanged(nameof(Kind)); OnChanged(nameof(KindName)); } }
- public string KindName
- {
- get
- {
- switch (_kind)
- {
- case MotionAxisKind.Virtual: return "虚轴";
- case MotionAxisKind.Combined: return "组合轴";
- default: return "实轴";
- }
- }
- set
- {
- if (value == "虚轴") _kind = MotionAxisKind.Virtual;
- else if (value == "组合轴") _kind = MotionAxisKind.Combined;
- else _kind = MotionAxisKind.Physical;
- OnChanged(nameof(Kind));
- OnChanged(nameof(KindName));
- }
- }
- public int OutputChannel { get => _outputChannel; set { _outputChannel = value; OnChanged(nameof(OutputChannel)); } }
- public string CombinedMembers { get => _combinedMembers; set { _combinedMembers = value; OnChanged(nameof(CombinedMembers)); } }
- public double Velocity { get => _velocity; set { _velocity = value; OnChanged(nameof(Velocity)); } }
- public bool SoftLimitEnabled { get => _softLimitEnabled; set { _softLimitEnabled = value; OnChanged(nameof(SoftLimitEnabled)); } }
- public double SoftLimitNeg { get => _softLimitNeg; set { _softLimitNeg = value; OnChanged(nameof(SoftLimitNeg)); } }
- public double SoftLimitPos { get => _softLimitPos; set { _softLimitPos = value; OnChanged(nameof(SoftLimitPos)); } }
- public double MaxVelocity { get => _maxVelocity; set { _maxVelocity = value; OnChanged(nameof(MaxVelocity)); } }
- public event PropertyChangedEventHandler PropertyChanged;
- private void OnChanged(string name) => PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(name));
- public static AxisEditRow FromConfig(MotionAxisConfig cfg)
- {
- cfg = cfg ?? new MotionAxisConfig();
- return new AxisEditRow
- {
- AxisNo = cfg.AxisNo,
- Name = cfg.Name,
- Kind = cfg.Kind,
- OutputChannel = cfg.OutputChannel,
- CombinedMembers = cfg.CombinedMembers,
- Velocity = cfg.Velocity,
- SoftLimitEnabled = cfg.SoftLimitEnabled,
- SoftLimitNeg = cfg.SoftLimitNeg,
- SoftLimitPos = cfg.SoftLimitPos,
- MaxVelocity = cfg.MaxVelocity
- };
- }
- public MotionAxisConfig ToConfig()
- {
- return new MotionAxisConfig
- {
- AxisNo = AxisNo,
- Name = Name?.Trim(),
- Kind = Kind,
- OutputChannel = OutputChannel,
- CombinedMembers = CombinedMembers?.Trim() ?? "",
- Velocity = Velocity,
- SoftLimitEnabled = SoftLimitEnabled,
- SoftLimitNeg = SoftLimitNeg,
- SoftLimitPos = SoftLimitPos,
- MaxVelocity = MaxVelocity
- };
- }
- }
- }
|