Browse Source

新增XYZU机器人手动操作控件及多轴支持

本次提交新增了XYZU机器人手动操作控件(PlcRobotManual),实现了点动、上/下使能、复位等功能,支持X/Y/Z/U及附加轴的动态操作。引入AxisViewModel以便单轴点动与位置绑定,PlcRobotParameter和PlcInfo支持多轴与动态数据。同步调整相关UI和标定流程,优化多轴扩展和后续PLC机器人手动调试能力。
孝锋 徐 9 months ago
parent
commit
f59babf643

+ 309 - 0
TeamAAS-VM/Controls/PlcRobotManual.xaml

@@ -0,0 +1,309 @@
+<UserControl x:Class="TeamAAS_VP.Controls.PlcRobotManual"
+             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
+             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
+             xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
+             xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
+             xmlns:local="clr-namespace:TeamAAS_VP.Controls"
+             xmlns:materialDesign="http://materialdesigninxaml.net/winfx/xaml/themes"
+             xmlns:mah="http://metro.mahapps.com/winfx/xaml/controls"
+             xmlns:b="http://schemas.microsoft.com/xaml/behaviors"
+             xmlns:sys="clr-namespace:System;assembly=mscorlib"
+             xmlns:uControl="clr-namespace:TeamAAS_VP.Controls"
+             xmlns:convert="clr-namespace:TeamAAS_VP.ValueConverter"
+             xmlns:lex="http://wpflocalizeextension.codeplex.com"
+             lex:LocalizeDictionary.DesignCulture="zh-CN"
+             lex:ResxLocalizationProvider.DefaultAssembly="TeamAAS-VP"
+             lex:ResxLocalizationProvider.DefaultDictionary="Lang"
+             mc:Ignorable="d"
+             d:Background="White"
+             FontFamily="{DynamicResource DefaultFont}">
+    <UserControl.Resources>
+        <convert:JogConverter x:Key="JogConverter" />
+    </UserControl.Resources>
+    <ScrollViewer HorizontalAlignment="Stretch"
+                  VerticalAlignment="Stretch">
+        <Grid HorizontalAlignment="Stretch"
+              VerticalAlignment="Top">
+            <Grid.RowDefinitions>
+                <RowDefinition Height="auto" />
+                <RowDefinition Height="auto" />
+            </Grid.RowDefinitions>
+
+            <Grid Grid.Row="0"
+                  Margin="10" HorizontalAlignment="Center">
+                <Grid.ColumnDefinitions>
+                    <ColumnDefinition Width="auto" />
+                    <ColumnDefinition Width="auto" />
+                    <ColumnDefinition Width="auto" />
+                    <ColumnDefinition Width="auto" />
+                </Grid.ColumnDefinitions>
+                <Grid.RowDefinitions>
+                    <RowDefinition Height="auto" />
+                    <RowDefinition Height="auto" />
+                    <RowDefinition Height="auto" />
+                    <RowDefinition Height="auto" />
+                    <RowDefinition Height="auto" />
+                    <RowDefinition Height="auto" />
+                    <RowDefinition Height="auto" />
+                </Grid.RowDefinitions>
+                <Grid.Resources>
+                    <Style TargetType="Button"
+                           BasedOn="{StaticResource MaterialDesignRaisedDarkButton}">
+                        <Setter Property="Width"
+                                Value="60" />
+                        <Setter Property="Height"
+                                Value="60" />
+                        <Setter Property="FontSize"
+                                Value="13" />
+                        <Setter Property="Padding"
+                                Value="0" />
+                        <Setter Property="HorizontalAlignment"
+                                Value="Center" />
+                        <Setter Property="VerticalAlignment"
+                                Value="Center" />
+                        <Setter Property="Margin"
+                                Value="2" />
+                        <Setter Property="materialDesign:ButtonAssist.CornerRadius"
+                                Value="10" />
+                    </Style>
+                </Grid.Resources>
+                <StackPanel Grid.ColumnSpan="4"
+                            Grid.Row="0"
+                            Grid.Column="0"
+                            VerticalAlignment="Center"
+                            Orientation="Horizontal">
+                    <Button Content="{lex:Loc 上使能}"
+                            Grid.Row="2"
+                            materialDesign:ButtonAssist.CornerRadius="10"
+                            Style="{StaticResource MaterialDesignRaisedDarkButton}"
+                            Command="{Binding MotorCommand}"
+                            CommandParameter="True" />
+                    <Button Content="{lex:Loc 下使能}"
+                            Grid.Row="3"
+                            Margin="10"
+                            materialDesign:ButtonAssist.CornerRadius="10"
+                            Style="{StaticResource MaterialDesignRaisedDarkButton}"
+                            Command="{Binding MotorCommand}"
+                            CommandParameter="False" />
+                    <Button Content="{lex:Loc 复位错误}"
+                            Grid.Row="4"
+                            materialDesign:ButtonAssist.CornerRadius="10"
+                            Style="{StaticResource MaterialDesignRaisedDarkButton}"
+                            Command="{Binding ResetCommand}" />
+                </StackPanel>
+                <Button Grid.Row="2"
+                        Grid.Column="0"
+                        Command="{Binding JogCommand}"
+                        CommandParameter="{Binding ElementName=txtDistance,Path=Value,Converter={StaticResource JogConverter}, ConverterParameter=X-}">
+                    <StackPanel Orientation="Vertical">
+                        <materialDesign:PackIcon Kind="ArrowLeftBold"
+                                                 Width="26"
+                                                 Height="26" />
+                        <TextBlock Text="-X"
+                                   HorizontalAlignment="Center" />
+                    </StackPanel>
+                </Button>
+                <Button Grid.Row="2"
+                        Grid.Column="2"
+                        Command="{Binding JogCommand}"
+                        CommandParameter="{Binding ElementName=txtDistance,Path=Value,Converter={StaticResource JogConverter}, ConverterParameter=X+}">
+                    <StackPanel Orientation="Vertical">
+                        <materialDesign:PackIcon Kind="ArrowRightBold"
+                                                 Width="26"
+                                                 Height="26" />
+                        <TextBlock Text="+X"
+                                   HorizontalAlignment="Center" />
+                    </StackPanel>
+                </Button>
+                <Button Grid.Row="1"
+                        Grid.Column="1"
+                        Command="{Binding JogCommand}"
+                        CommandParameter="{Binding ElementName=txtDistance,Path=Value,Converter={StaticResource JogConverter}, ConverterParameter=Y+}">
+                    <StackPanel Orientation="Vertical">
+                        <materialDesign:PackIcon Kind="ArrowTopBold"
+                                                 Width="26"
+                                                 Height="26" />
+                        <TextBlock Text="+Y"
+                                   HorizontalAlignment="Center" />
+                    </StackPanel>
+                </Button>
+                <Button Grid.Row="3"
+                        Grid.Column="1"
+                        Command="{Binding JogCommand}"
+                        CommandParameter="{Binding ElementName=txtDistance,Path=Value,Converter={StaticResource JogConverter}, ConverterParameter=Y-}">
+                    <StackPanel Orientation="Vertical">
+                        <materialDesign:PackIcon Kind="ArrowBottomBold"
+                                                 Width="26"
+                                                 Height="26" />
+                        <TextBlock Text="-Y"
+                                   HorizontalAlignment="Center" />
+                    </StackPanel>
+                </Button>
+                <Button Grid.Row="1"
+                        Grid.Column="3"
+                        Command="{Binding JogCommand}"
+                        CommandParameter="{Binding ElementName=txtDistance,Path=Value,Converter={StaticResource JogConverter}, ConverterParameter=Z+}">
+                    <StackPanel Orientation="Vertical">
+                        <materialDesign:PackIcon Kind="ArrowTopBold"
+                                                 Width="26"
+                                                 Height="26" />
+                        <TextBlock Text="+Z"
+                                   HorizontalAlignment="Center" />
+                    </StackPanel>
+                </Button>
+                <Button Grid.Row="3"
+                        Grid.Column="3"
+                        Command="{Binding JogCommand}"
+                        CommandParameter="{Binding ElementName=txtDistance,Path=Value,Converter={StaticResource JogConverter}, ConverterParameter=Z-}">
+                    <StackPanel Orientation="Vertical">
+                        <materialDesign:PackIcon Kind="ArrowBottomBold"
+                                                 Width="26"
+                                                 Height="26" />
+                        <TextBlock Text="-Z"
+                                   HorizontalAlignment="Center" />
+                    </StackPanel>
+                </Button>
+                <Button Grid.Row="4"
+                        Grid.Column="3"
+                        Command="{Binding JogCommand}"
+                        CommandParameter="{Binding ElementName=txtDistance,Path=Value,Converter={StaticResource JogConverter}, ConverterParameter=U+}">
+                    <StackPanel Orientation="Vertical">
+                        <materialDesign:PackIcon Kind="AxisZRotateCounterclockwise"
+                                                 Width="26"
+                                                 Height="26" />
+                        <TextBlock Text="+U"
+                                   HorizontalAlignment="Center" />
+                    </StackPanel>
+                </Button>
+                <Button Grid.Row="4"
+                        Grid.Column="0"
+                        Command="{Binding JogCommand}"
+                        CommandParameter="{Binding ElementName=txtDistance,Path=Value,Converter={StaticResource JogConverter}, ConverterParameter=U-}">
+                    <StackPanel Orientation="Vertical">
+                        <materialDesign:PackIcon Kind="AxisZRotateClockwise"
+                                                 Width="26"
+                                                 Height="26" />
+                        <TextBlock Text="-U"
+                                   HorizontalAlignment="Center" />
+                    </StackPanel>
+                </Button>
+                <!--<Button Grid.Row="4"
+                        Grid.Column="1"
+                        Grid.ColumnSpan="2"
+                        Command="{Binding JogCommand}"
+                        CommandParameter="{Binding ElementName=txtDistance,Path=Value,Converter={StaticResource JogConverter}, ConverterParameter=V+}">
+                    <StackPanel Orientation="Vertical">
+                        <materialDesign:PackIcon Kind="AxisYRotateCounterclockwise"
+                                                 Width="26"
+                                                 Height="26" />
+                        <TextBlock Text="+V"
+                                   HorizontalAlignment="Center" />
+                    </StackPanel>
+                </Button>
+                <Button Grid.Row="5"
+                        Grid.Column="1"
+                        Grid.ColumnSpan="2"
+                        Command="{Binding JogCommand}"
+                        CommandParameter="{Binding ElementName=txtDistance,Path=Value,Converter={StaticResource JogConverter}, ConverterParameter=V-}">
+                    <StackPanel Orientation="Vertical">
+                        <materialDesign:PackIcon Kind="AxisYRotateClockwise"
+                                                 Width="26"
+                                                 Height="26" />
+                        <TextBlock Text="-V"
+                                   HorizontalAlignment="Center" />
+                    </StackPanel>
+                </Button>
+                <Button Grid.Row="4"
+                        Grid.Column="3"
+                        Command="{Binding JogCommand}"
+                        CommandParameter="{Binding ElementName=txtDistance,Path=Value,Converter={StaticResource JogConverter}, ConverterParameter=W+}">
+                    <StackPanel Orientation="Vertical">
+                        <materialDesign:PackIcon Kind="AxisXRotateCounterclockwise"
+                                                 Width="26"
+                                                 Height="26" />
+                        <TextBlock Text="+W"
+                                   HorizontalAlignment="Center" />
+                    </StackPanel>
+                </Button>
+                <Button Grid.Row="5"
+                        Grid.Column="3"
+                        Command="{Binding JogCommand}"
+                        CommandParameter="{Binding ElementName=txtDistance,Path=Value,Converter={StaticResource JogConverter}, ConverterParameter=W-}">
+                    <StackPanel Orientation="Vertical">
+                        <materialDesign:PackIcon Kind="AxisXRotateClockwise"
+                                                 Width="26"
+                                                 Height="26" />
+                        <TextBlock Text="-W"
+                                   HorizontalAlignment="Center" />
+                    </StackPanel>
+                </Button>--> 
+                <StackPanel Grid.Row="6"
+                            Grid.ColumnSpan="7"
+                            Margin="10,10,0,10"
+                            Grid.Column="0"
+                            VerticalAlignment="Center"
+                            Orientation="Horizontal">
+                    <TextBlock Text="{lex:Loc 步进距离}"
+                               VerticalAlignment="Center" />
+                    <uControl:myNumericUpDowm x:Name="txtDistance"
+                                              MinWidth="100"
+                                              Interval="0.1"
+                                              Minimum="0"
+                                              Maximum="100"
+                                              StringFormat="{}{0:N3} mm"
+                                              Value="{Binding Distance,Mode=TwoWay}"
+                                              Margin="10,0" />
+                </StackPanel>
+            </Grid>
+            
+            <!-- 附加轴列表:绑定到视图模型中的 ExtraAxes 集合(每项假定有 Name、Position) -->
+            <ItemsControl Grid.Row="1" ItemsSource="{Binding ExtraAxes}">
+                <ItemsControl.ItemTemplate>
+                    <DataTemplate>
+                        <Border Padding="6"
+                                Margin="0,2"
+                                Background="{DynamicResource MaterialDesignPaper}">
+                            <DockPanel LastChildFill="False"
+                                       VerticalAlignment="Center">
+                                <StackPanel Orientation="Horizontal"
+                                            DockPanel.Dock="Left"
+                                            VerticalAlignment="Center">
+                                    <TextBlock Text="{Binding Name}"
+                                               Width="140"
+                                               VerticalAlignment="Center" />
+                                    <TextBlock Text="{Binding Position, StringFormat='{}{0:N3} mm'}"
+                                               Width="140"
+                                               VerticalAlignment="Center" />
+                                </StackPanel>
+                                <StackPanel Orientation="Horizontal"
+                                            HorizontalAlignment="Right"
+                                            DockPanel.Dock="Right">
+                                    <Button Content="-"
+                                            Width="60"
+                                            Height="36"
+                                            Margin="6,0"
+                                            Style="{StaticResource MaterialDesignRaisedDarkButton}"
+                                            Command="{Binding DataContext.JogCommand, RelativeSource={RelativeSource AncestorType=UserControl}}"
+                                            CommandParameter="{Binding Name, StringFormat={}{0}-}" />
+                                    <Button Content="+"
+                                            Width="60"
+                                            Height="36"
+                                            Margin="6,0"
+                                            Style="{StaticResource MaterialDesignRaisedDarkButton}"
+                                            Command="{Binding DataContext.JogCommand, RelativeSource={RelativeSource AncestorType=UserControl}}"
+                                            CommandParameter="{Binding Name, StringFormat={}{0}+}" />
+                                </StackPanel>
+                            </DockPanel>
+                        </Border>
+                    </DataTemplate>
+                </ItemsControl.ItemTemplate>
+            </ItemsControl>
+
+            <materialDesign:Snackbar Grid.RowSpan="2"
+                                     x:Name="snackbar"
+                                     Opacity="0.9"
+                                     HorizontalContentAlignment="Center"
+                                     VerticalAlignment="Top" />
+        </Grid>
+    </ScrollViewer>
+</UserControl>

+ 341 - 0
TeamAAS-VM/Controls/PlcRobotManual.xaml.cs

@@ -0,0 +1,341 @@
+using Prism.Commands;
+using Prism.Ioc;
+using Prism.Unity;
+using System;
+using System.Collections.Generic;
+using System.Collections.ObjectModel;
+using System.ComponentModel;
+using System.Linq;
+using System.Runtime.CompilerServices;
+using System.Text;
+using System.Threading.Tasks;
+using System.Windows;
+using System.Windows.Controls;
+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 TeamAAS_VP.Core.PLCs;
+using TeamAAS_VP.Core.Robots;
+using TeamAAS_VP.Interfaces;
+using TeamAAS_VP.Resources.Languages;
+
+namespace TeamAAS_VP.Controls
+{
+    /// <summary>
+    /// PlcRobotManual.xaml 的交互逻辑
+    /// </summary>
+    public partial class PlcRobotManual : UserControl, INotifyPropertyChanged
+    {
+        IConfigService _configService;
+        public PlcRobotManual()
+        {
+            InitializeComponent();
+            DataContext = this;
+        }
+
+        #region 属性
+        private ObservableCollection<Axis> _AdditionalAxisList;
+        public ObservableCollection<Axis> AdditionalAxisList
+        {
+            get { return _AdditionalAxisList; }
+            set { SetProperty(ref _AdditionalAxisList, value); }
+        }
+
+        private XYZU_Robot _Robot;
+
+        public XYZU_Robot Robot
+        {
+            get { return _Robot; }
+            set
+            {
+                SetProperty(ref _Robot, value);
+                try
+                {
+                    if (value != null)
+                    {
+                        if (_configService == null)
+                            _configService = ((PrismApplication)(App.Current)).Container.Resolve<IConfigService>();
+                        this.Distance = _configService.GetRobotStepDistance(value.Id);
+                    }
+                }
+                catch (Exception)
+                {
+
+                }
+            }
+        }
+
+        private double _Distance = 1;
+
+        public double Distance
+        {
+            get { return _Distance; }
+            set
+            {
+                SetProperty(ref _Distance, value);
+                try
+                {
+                    if (Robot == null)
+                    {
+                        return;
+                    }
+                    if (_configService == null)
+                        _configService = ((PrismApplication)(App.Current)).Container.Resolve<IConfigService>();
+                    _configService.UpdateRobotStepDistance(Robot.Id, value);
+                }
+                catch (Exception)
+                {
+
+                }
+            }
+        }
+        #endregion
+
+        #region 命令
+
+        private DelegateCommand<string> _MotorCommand;
+        public DelegateCommand<string> MotorCommand =>
+            _MotorCommand ?? (_MotorCommand = new DelegateCommand<string>(ExecuteMotorCommand).ObservesCanExecute(() => CanExecute).ObservesProperty(() => Robot).ObservesProperty(() => Robot.CanExecute));
+
+
+
+        private DelegateCommand _ResetCommand;
+        public DelegateCommand ResetCommand =>
+            _ResetCommand ?? (_ResetCommand = new DelegateCommand(ExecuteResetCommand).ObservesCanExecute(() => CanExecute).ObservesProperty(() => Robot).ObservesProperty(() => Robot.CanExecute));
+
+
+
+        private DelegateCommand<object> _JogCommand;
+        public DelegateCommand<object> JogCommand =>
+            _JogCommand ?? (_JogCommand = new DelegateCommand<object>(ExecuteJogCommand).ObservesCanExecute(() => CanExecute).ObservesProperty(() => Robot).ObservesProperty(() => Robot.CanExecute));
+
+        #endregion
+
+        #region 事件
+
+        #endregion
+
+        #region 方法
+
+        private void ShowMsg(string msg)
+        {
+            if (snackbar.MessageQueue == null)
+            {
+                snackbar.MessageQueue = new MaterialDesignThemes.Wpf.SnackbarMessageQueue();
+            }
+            snackbar.MessageQueue.Clear();
+            snackbar.MessageQueue?.Enqueue(
+                msg,
+                null,
+                null,
+                null,
+                false,
+                true,
+                TimeSpan.FromSeconds(0.4));
+        }
+
+        /// <summary>
+        /// 电机
+        /// </summary>
+        /// <param name="obj"></param>
+        private async void ExecuteMotorCommand(string obj)
+        {
+            if (Robot == null || !Robot.IsConnected) return;
+            try
+            {
+                await Robot.MotorAsync(Convert.ToBoolean(obj));
+                ShowMsg($"{Lang.完成}!");
+            }
+            catch (Exception ex)
+            {
+                LogHelper.WriteLogError("机器人点击操作时出错!", ex);
+                ShowMsg(ex.Message);
+            }
+        }
+
+        /// <summary>
+        /// 重置
+        /// </summary>
+        private async void ExecuteResetCommand()
+        {
+            if (Robot == null || !Robot.IsConnected) return;
+            try
+            {
+                await Robot.ResetAsync();
+
+                ShowMsg($"{Lang.完成}!");
+            }
+            catch (Exception ex)
+            {
+                LogHelper.WriteLogError("重置机器人时出错!", ex);
+                ShowMsg(ex.Message);
+            }
+        }
+
+        /// <summary>
+        /// 点动
+        /// </summary>
+        /// <param name="obj"></param>
+        private async void ExecuteJogCommand(object obj)
+        {
+            if (Robot == null || !Robot.IsConnected) return;
+            try
+            {
+                var items = ((string)obj).Split(':');
+                //如果移动距离大于10mm,则提示用户确认
+                double distance = double.Parse(items[1]);
+                if (Math.Abs(distance) >= 10)
+                {
+                    if (MessageBox.Show($"确认要点动距离 {distance} mm 吗?", "确认点动", MessageBoxButton.YesNo, MessageBoxImage.Question) != MessageBoxResult.Yes)
+                    {
+                        return;
+                    }
+                }
+                Robot.Timeout = 6000000;
+                switch (items[0])
+                {
+                    case "X+":
+                        await Robot.JogAsync("X", distance);
+                        break;
+                    case "X-":
+                        await Robot.JogAsync("X", -distance);
+                        break;
+                    case "Y+":
+                        await Robot.JogAsync("Y", distance);
+                        break;
+                    case "Y-":
+                        await Robot.JogAsync("Y", -distance);
+                        break;
+                    case "Z+":
+                        await Robot.JogAsync("Z", distance);
+                        break;
+                    case "Z-":
+                        await Robot.JogAsync("Z", -distance);
+                        break;
+                    case "U+":
+                        await Robot.JogAsync("U", distance);
+                        break;
+                    case "U-":
+                        await Robot.JogAsync("U", -distance);
+                        break;
+                    case "V+":
+                        await Robot.JogAsync("V", distance);
+                        break;
+                    case "V-":
+                        await Robot.JogAsync("V", -distance);
+                        break;
+                    case "W+":
+                        await Robot.JogAsync("W", distance);
+                        break;
+                    case "W-":
+                        await Robot.JogAsync("W", -distance);
+                        break;
+                    default:
+                        break;
+                }
+                Robot.Timeout = 5000;
+
+
+                ShowMsg($"{Lang.完成}!");
+            }
+            catch (Exception ex)
+            {
+                LogHelper.WriteLogError("机器点动时出错!", ex);
+                ShowMsg(ex.Message);
+            }
+        }
+
+        private bool CanExecute
+        {
+            get
+            {
+                if (Robot != null)
+                {
+                    return Robot.CanExecute;
+                }
+                else
+                {
+                    return false;
+                }
+            }
+        }
+        #endregion
+
+        #region 属性通知
+        /// <summary>
+        /// Occurs when a property value changes.
+        /// </summary>
+        public event PropertyChangedEventHandler PropertyChanged;
+
+        /// <summary>
+        /// Checks if a property already matches a desired value. Sets the property and
+        /// notifies listeners only when necessary.
+        /// </summary>
+        /// <typeparam name="T">Type of the property.</typeparam>
+        /// <param name="storage">Reference to a property with both getter and setter.</param>
+        /// <param name="value">Desired value for the property.</param>
+        /// <param name="propertyName">Name of the property used to notify listeners. This
+        /// value is optional and can be provided automatically when invoked from compilers that
+        /// support CallerMemberName.</param>
+        /// <returns>True if the value was changed, false if the existing value matched the
+        /// desired value.</returns>
+        protected virtual bool SetProperty<T>(ref T storage, T value, [CallerMemberName] string propertyName = null)
+        {
+            if (EqualityComparer<T>.Default.Equals(storage, value)) return false;
+
+            storage = value;
+            RaisePropertyChanged(propertyName);
+
+            return true;
+        }
+
+        /// <summary>
+        /// Checks if a property already matches a desired value. Sets the property and
+        /// notifies listeners only when necessary.
+        /// </summary>
+        /// <typeparam name="T">Type of the property.</typeparam>
+        /// <param name="storage">Reference to a property with both getter and setter.</param>
+        /// <param name="value">Desired value for the property.</param>
+        /// <param name="propertyName">Name of the property used to notify listeners. This
+        /// value is optional and can be provided automatically when invoked from compilers that
+        /// support CallerMemberName.</param>
+        /// <param name="onChanged">Action that is called after the property value has been changed.</param>
+        /// <returns>True if the value was changed, false if the existing value matched the
+        /// desired value.</returns>
+        protected virtual bool SetProperty<T>(ref T storage, T value, Action onChanged, [CallerMemberName] string propertyName = null)
+        {
+            if (EqualityComparer<T>.Default.Equals(storage, value)) return false;
+
+            storage = value;
+            onChanged?.Invoke();
+            RaisePropertyChanged(propertyName);
+
+            return true;
+        }
+
+        /// <summary>
+        /// Raises this object's PropertyChanged event.
+        /// </summary>
+        /// <param name="propertyName">Name of the property used to notify listeners. This
+        /// value is optional and can be provided automatically when invoked from compilers
+        /// that support <see cref="CallerMemberNameAttribute"/>.</param>
+        protected void RaisePropertyChanged([CallerMemberName] string propertyName = null)
+        {
+            OnPropertyChanged(new PropertyChangedEventArgs(propertyName));
+        }
+
+        /// <summary>
+        /// Raises this object's PropertyChanged event.
+        /// </summary>
+        /// <param name="args">The PropertyChangedEventArgs</param>
+        protected virtual void OnPropertyChanged(PropertyChangedEventArgs args)
+        {
+            PropertyChanged?.Invoke(this, args);
+        }
+        #endregion
+    }
+}

+ 187 - 0
TeamAAS-VM/Core/Robots/AxisViewModel.cs

@@ -0,0 +1,187 @@
+
+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;
+            }
+        }
+    }
+}

+ 2 - 0
TeamAAS-VM/Core/Robots/XYZU_Robot.cs

@@ -810,4 +810,6 @@ namespace TeamAAS_VP.Core.Robots
         public Task<bool> SelectToolAsync(int index) => Task.FromResult(true);
         #endregion
     }
+
+
 }

+ 2 - 0
TeamAAS-VM/Models/PLC/PlcInfo.cs

@@ -1,9 +1,11 @@
 using Prism.Mvvm;
 using System;
 using System.Collections.Generic;
+using System.Collections.ObjectModel;
 using System.Linq;
 using System.Text;
 using System.Threading.Tasks;
+using TeamAAS_VP.Core.Robots;
 using TeamAAS_VP.Enums;
 
 namespace TeamAAS_VP.Models

+ 5 - 0
TeamAAS-VM/Models/PLC/PlcRobotParameter.cs

@@ -14,5 +14,10 @@ namespace TeamAAS_VP.Models.PLC
         /// 轴集合
         /// </summary>
         public List<Axis> AxixList { get; set; }
+
+        /// <summary>
+        /// 附加轴集合
+        /// </summary>
+        public List<Axis> AdditionalAxisList { get; set; }
     }
 }

+ 80 - 74
TeamAAS-VM/Services/CameraCalibrationService.cs

@@ -312,6 +312,9 @@ namespace TeamAAS_VP.Services
             calibrationInfo.Tool.X = toolCoord.X;
             calibrationInfo.Tool.Y = toolCoord.Y;
 
+            //移动机器人至中心位置
+            await robot.CalibMotionAsync(calibrationInfo.CenterPoint, calibrationInfo.CenterPoint.Z);
+
             return (true, RobotCameraRotationMatrix, calibrationInfo.Tool.X, calibrationInfo.Tool.Y, pixelScaleX, pixelScaleY);
         }
 
@@ -417,6 +420,9 @@ namespace TeamAAS_VP.Services
             calibrationInfo.Tool.X = toolCoord.X;
             calibrationInfo.Tool.Y = toolCoord.Y;
 
+            //移动机器人至中心位置
+            await robot.CalibMotionAsync(calibrationInfo.CenterPoint, calibrationInfo.CenterPoint.Z);
+
             return (true, RobotCameraRotationMatrix, calibrationInfo.Tool.X, calibrationInfo.Tool.Y, pixelScaleX, pixelScaleY);
         }
 
@@ -782,36 +788,36 @@ namespace TeamAAS_VP.Services
             await robot.CalibParameAsync(calibrationInfo.Pick, calibrationInfo.Speed, calibrationInfo.Accel, calibrationInfo.Power, calibrationInfo.WaitSuction, calibrationInfo.WaitBlow);
 
             var P0 = Vector<double>.Build.Dense(new double[] { calibrationInfo.CenterPoint.X, calibrationInfo.CenterPoint.Y });
-            if (robot.Brand == Enums.RobotBrand.XYZ_Platform)
-            {
-
-                //移动机器人至中心位置
-                await robot.CalibMotionAsync(calibrationInfo.CenterPoint, 0);
-                if (cancellationToken.IsCancellationRequested)
-                {
-                    return (false, null, null, null);
-                }
-                //计算相机与机器人坐标系的旋转矩阵
-                var robotCameraRotationMatrix = await AutoIdentifyRobotCameraRotationMatrix(calibrationInfo, robot, cancellationToken);
-                if (!robotCameraRotationMatrix.IsSuccess)
-                {
-                    return (false, null, null, null);
-                }
-                //自动移动机器人至图像中心点位置
-                var autoMoveResult = await AutoMoveRobotToImageCenter(robot, robotCameraRotationMatrix.RotationMatrix, robotCameraRotationMatrix.PixelScaleX, robotCameraRotationMatrix.PixelScaleY, cancellationToken);
-                if (!autoMoveResult.IsSuccess)
-                {
-                    return (false, null, null, null);
-                }
-                calibrationInfo.CenterPoint.X = (float)autoMoveResult.X;
-                calibrationInfo.CenterPoint.Y = (float)autoMoveResult.Y;
-                if (calibrationInfo.CameraMount != Enums.CameraMount.MobileDown_XYPlatform)
-                {
-                    calibrationInfo.MarkPoint = calibrationInfo.CenterPoint.Clone();
-                }
+            //if (robot.Brand == Enums.RobotBrand.XYZ_Platform)
+            //{
+
+            //    //移动机器人至中心位置
+            //    await robot.CalibMotionAsync(calibrationInfo.CenterPoint, 0);
+            //    if (cancellationToken.IsCancellationRequested)
+            //    {
+            //        return (false, null, null, null);
+            //    }
+            //    //计算相机与机器人坐标系的旋转矩阵
+            //    var robotCameraRotationMatrix = await AutoIdentifyRobotCameraRotationMatrix(calibrationInfo, robot, cancellationToken);
+            //    if (!robotCameraRotationMatrix.IsSuccess)
+            //    {
+            //        return (false, null, null, null);
+            //    }
+            //    //自动移动机器人至图像中心点位置
+            //    var autoMoveResult = await AutoMoveRobotToImageCenter(robot, robotCameraRotationMatrix.RotationMatrix, robotCameraRotationMatrix.PixelScaleX, robotCameraRotationMatrix.PixelScaleY, cancellationToken);
+            //    if (!autoMoveResult.IsSuccess)
+            //    {
+            //        return (false, null, null, null);
+            //    }
+            //    calibrationInfo.CenterPoint.X = (float)autoMoveResult.X;
+            //    calibrationInfo.CenterPoint.Y = (float)autoMoveResult.Y;
+            //    if (calibrationInfo.CameraMount != Enums.CameraMount.MobileDown_XYPlatform)
+            //    {
+            //        calibrationInfo.MarkPoint = calibrationInfo.CenterPoint.Clone();
+            //    }
                 
-                calibrationInfo.RobotCameraRotationMatrix = robotCameraRotationMatrix.RotationMatrix.ToArray();
-            }
+            //    calibrationInfo.RobotCameraRotationMatrix = robotCameraRotationMatrix.RotationMatrix.ToArray();
+            //}
 
             /// <summary>
             /// 机器人与相机之间的旋转矩阵
@@ -1071,14 +1077,14 @@ namespace TeamAAS_VP.Services
                     matRobot.Set<double>(i, 0, calibrationInfo.MarkPoint.X - ox);
                     matRobot.Set<double>(i, 1, calibrationInfo.MarkPoint.Y - oy);
                 }
-                else if (calibrationInfo.CameraMount == Enums.CameraMount.MobileDown_XYPlatform)
-                {
-                    //计算每个点相对于第一个点移动的偏移量,将这个偏移量
-                    double ox = rPoints[i].X - rPoints[0].X;
-                    double oy = rPoints[i].Y - rPoints[0].Y;
-                    matRobot.Set<double>(i, 0, calibrationInfo.MarkPoint.X - ox);
-                    matRobot.Set<double>(i, 1, calibrationInfo.MarkPoint.Y - oy);
-                }
+                //else if (calibrationInfo.CameraMount == Enums.CameraMount.MobileDown_XYPlatform)
+                //{
+                //    //计算每个点相对于第一个点移动的偏移量,将这个偏移量
+                //    double ox = rPoints[i].X - rPoints[0].X;
+                //    double oy = rPoints[i].Y - rPoints[0].Y;
+                //    matRobot.Set<double>(i, 0, calibrationInfo.MarkPoint.X - ox);
+                //    matRobot.Set<double>(i, 1, calibrationInfo.MarkPoint.Y - oy);
+                //}
                 else
                 {
                     //将tool 0下的坐标转换成Tool n下的坐标
@@ -1131,13 +1137,13 @@ namespace TeamAAS_VP.Services
                     differenceX.Add((calibrationInfo.MarkPoint.X - ox) - (matrix * pixel)[0]);
                     differenceY.Add((calibrationInfo.MarkPoint.Y - oy) - (matrix * pixel)[1]);
                 }
-                else if (calibrationInfo.CameraMount == Enums.CameraMount.MobileDown_XYPlatform)
-                {
-                    double ox = rPoints[i].X - rPoints[0].X;
-                    double oy = rPoints[i].Y - rPoints[0].Y;
-                    differenceX.Add((calibrationInfo.MarkPoint.X - ox) - (matrix * pixel)[0]);
-                    differenceY.Add((calibrationInfo.MarkPoint.Y - oy) - (matrix * pixel)[1]);
-                }
+                //else if (calibrationInfo.CameraMount == Enums.CameraMount.MobileDown_XYPlatform)
+                //{
+                //    double ox = rPoints[i].X - rPoints[0].X;
+                //    double oy = rPoints[i].Y - rPoints[0].Y;
+                //    differenceX.Add((calibrationInfo.MarkPoint.X - ox) - (matrix * pixel)[0]);
+                //    differenceY.Add((calibrationInfo.MarkPoint.Y - oy) - (matrix * pixel)[1]);
+                //}
                 else
                 {
                     //将tool 0下的坐标转换成Tool n下的坐标
@@ -1380,36 +1386,36 @@ namespace TeamAAS_VP.Services
                     differenceX.Add(cc[0] - calibrationInfo.MarkPoint.X);
                     differenceY.Add(cc[1] - calibrationInfo.MarkPoint.Y);
                 }
-                else if (calibrationInfo.CameraMount == Enums.CameraMount.MobileDown_XYPlatform)
-                {
-                    //像素直接转换成mm时的点位
-                    double Robot_X, Robot_Y;
-                    Robot_X = TestPos[i][0];
-                    Robot_Y = TestPos[i][1];
-
-                    //机器人当前TOOL 0下的坐标
-                    double curpos_x = 0, curpos_y = 0, curpos_u = 0;
-                    curpos_x = rPoints[i].X;
-                    curpos_y = rPoints[i].Y;
-                    curpos_u = rPoints[i].U;
-
-                    //得到旋转矩阵
-                    double angle = Math.PI * (curpos_u - calibrationInfo.MarkPoint.U) / 180;
-                    // 创建T矩阵
-                    Matrix<double> rotationMatrix = Matrix<double>.Build.DenseOfArray(new double[,]
-                    {
-                                { Math.Cos(angle), -Math.Sin(angle) },
-                                { Math.Sin(angle), Math.Cos(angle) }
-                    });
-
-                    Vector<double> p3 = Vector<double>.Build.Dense(new double[] { Robot_X - calibrationInfo.CalibPoints[0].Robot.X, Robot_Y - calibrationInfo.CalibPoints[0].Robot.Y });
-                    Vector<double> phere = Vector<double>.Build.Dense(new double[] { curpos_x, curpos_y });
-
-                    var cc = rotationMatrix * p3 + phere;
-
-                    differenceX.Add(cc[0] - calibrationInfo.MarkPoint.X);
-                    differenceY.Add(cc[1] - calibrationInfo.MarkPoint.Y);
-                }
+                //else if (calibrationInfo.CameraMount == Enums.CameraMount.MobileDown_XYPlatform)
+                //{
+                //    //像素直接转换成mm时的点位
+                //    double Robot_X, Robot_Y;
+                //    Robot_X = TestPos[i][0];
+                //    Robot_Y = TestPos[i][1];
+
+                //    //机器人当前TOOL 0下的坐标
+                //    double curpos_x = 0, curpos_y = 0, curpos_u = 0;
+                //    curpos_x = rPoints[i].X;
+                //    curpos_y = rPoints[i].Y;
+                //    curpos_u = rPoints[i].U;
+
+                //    //得到旋转矩阵
+                //    double angle = Math.PI * (curpos_u - calibrationInfo.MarkPoint.U) / 180;
+                //    // 创建T矩阵
+                //    Matrix<double> rotationMatrix = Matrix<double>.Build.DenseOfArray(new double[,]
+                //    {
+                //                { Math.Cos(angle), -Math.Sin(angle) },
+                //                { Math.Sin(angle), Math.Cos(angle) }
+                //    });
+
+                //    Vector<double> p3 = Vector<double>.Build.Dense(new double[] { Robot_X - calibrationInfo.CalibPoints[0].Robot.X, Robot_Y - calibrationInfo.CalibPoints[0].Robot.Y });
+                //    Vector<double> phere = Vector<double>.Build.Dense(new double[] { curpos_x, curpos_y });
+
+                //    var cc = rotationMatrix * p3 + phere;
+
+                //    differenceX.Add(cc[0] - calibrationInfo.MarkPoint.X);
+                //    differenceY.Add(cc[1] - calibrationInfo.MarkPoint.Y);
+                //}
                 else
                 {
                     //将tool 0下的坐标转换成Tool n下的坐标

+ 8 - 0
TeamAAS-VM/TeamAAS-VP.csproj

@@ -526,6 +526,10 @@
     <Compile Include="Controls\FeederSystemParam.xaml.cs">
       <DependentUpon>FeederSystemParam.xaml</DependentUpon>
     </Compile>
+    <Compile Include="Controls\PlcRobotManual.xaml.cs">
+      <DependentUpon>PlcRobotManual.xaml</DependentUpon>
+    </Compile>
+    <Compile Include="Core\Robots\AxisViewModel.cs" />
     <Compile Include="Events\MainTabSwitchNotification.cs" />
     <Compile Include="Models\Feeder\ScrewFeederInfo.cs" />
     <Compile Include="Models\ScrewFeederBatchRecord.cs" />
@@ -1077,6 +1081,10 @@
       <SubType>Designer</SubType>
       <Generator>MSBuild:Compile</Generator>
     </Page>
+    <Page Include="Controls\PlcRobotManual.xaml">
+      <SubType>Designer</SubType>
+      <Generator>MSBuild:Compile</Generator>
+    </Page>
     <Page Include="Views\DebugMod\FocusAnalyzerl.xaml">
       <SubType>Designer</SubType>
       <Generator>MSBuild:Compile</Generator>

+ 4 - 4
TeamAAS-VM/ViewModels/Calibration/CalibrationAutoViewModel.cs

@@ -233,10 +233,10 @@ namespace TeamAAS_VP.ViewModels.Calibration
                     _regionManager.RequestNavigate("CalibrationRegionContext", "CalibrationTeachCenterPoint", param);
                 }
             }
-            else if (Robot.Brand == Enums.RobotBrand.XYZ_Platform)
-            {
-                _regionManager.RequestNavigate("CalibrationRegionContext", "CalibrationTeachCenterPoint", param);
-            }
+            //else if (Robot.Brand == Enums.RobotBrand.XYZ_Platform)
+            //{
+            //    _regionManager.RequestNavigate("CalibrationRegionContext", "CalibrationTeachCenterPoint", param);
+            //}
             else
             {
                 _regionManager.RequestNavigate("CalibrationRegionContext", "CalibrationSelectTool", param);

+ 3 - 0
TeamAAS-VM/ViewModels/Calibration/CalibrationSelectToolViewModel.cs

@@ -124,6 +124,9 @@ namespace TeamAAS_VP.ViewModels.Calibration
                             SelectCalibration.RobotCameraRotationMatrix = param1.ToArray();
                         }
                         SelectCalibration.Angle = param2;
+
+                        SelectCalibration.CenterPoint = Robot.GetRobotPos();
+
                         _eventAggregator.GetEvent<SnackbarMessageNotification>().Publish(new MessageParameter() { Msg = "完成!", Duration = 1 });
                     }
 

+ 4 - 4
TeamAAS-VM/ViewModels/Calibration/CalibrationTeachCenterPointViewModel.cs

@@ -160,10 +160,10 @@ namespace TeamAAS_VP.ViewModels.Calibration
                     _regionManager.RequestNavigate("CalibrationRegionContext", "CalibrationAuto", param);
                 }
             }
-            else if (Robot.Brand == Enums.RobotBrand.XYZ_Platform)
-            {
-                _regionManager.RequestNavigate("CalibrationRegionContext", "CalibrationAuto", param);
-            }
+            //else if (Robot.Brand == Enums.RobotBrand.XYZ_Platform)
+            //{
+            //    _regionManager.RequestNavigate("CalibrationRegionContext", "CalibrationAuto", param);
+            //}
             else
             {
                 _regionManager.RequestNavigate("CalibrationRegionContext", "CalibrationSelectTool", param);

+ 6 - 6
TeamAAS-VM/ViewModels/MainWindowViewModel.cs

@@ -339,12 +339,12 @@ namespace TeamAAS_VP.ViewModels
             await management.InitLightControllers();
 
             //-------------------SETP 7: 初始化电批-----------------------------------------------------------------------
-            curvalue += 1;
-            _ = App.Current.Dispatcher.BeginInvoke(new Action(() =>
-            {
-                _eventAggregator.GetEvent<ProgressNotification>().Publish(new UProgressBar.ProgressParameter { Maximum = max, Minimum = 0, SubTitle = $"{Lang.初始化中}...", Message = $"正在连接电批...", Value = curvalue });
-            }));
-            await management.InitScrewDriver();
+            //curvalue += 1;
+            //_ = App.Current.Dispatcher.BeginInvoke(new Action(() =>
+            //{
+            //    _eventAggregator.GetEvent<ProgressNotification>().Publish(new UProgressBar.ProgressParameter { Maximum = max, Minimum = 0, SubTitle = $"{Lang.初始化中}...", Message = $"正在连接电批...", Value = curvalue });
+            //}));
+            //await management.InitScrewDriver();
 
             //-------------------SETP 8: 加载所有产品-----------------------------------------------------------------------
             curvalue += 1;

+ 2 - 2
TeamAAS-VM/Views/Calibration/CalibTool.xaml

@@ -17,11 +17,11 @@
              prism:ViewModelLocator.AutoWireViewModel="True"
              mc:Ignorable="d"
              d:DataContext="{d:DesignInstance Type=vm:CalibToolViewModel}"
-             d:Height="600"
-             d:Width="1024"
              d:Background="White"
              MinHeight="500"
              MinWidth="500"
+             Width="1024"
+             Height="768"
              FontFamily="{DynamicResource DefaultFont}">
 
     <prism:Dialog.WindowStyle>

+ 5 - 5
TeamAAS-VM/Views/HomeView.xaml

@@ -33,19 +33,19 @@
         </Grid.ColumnDefinitions>
 
         <Grid Grid.Row="0">
-            <Grid.RowDefinitions>
+            <!--<Grid.RowDefinitions>
                 <RowDefinition Height="*" />
                 <RowDefinition Height="*" />
-            </Grid.RowDefinitions>
+            </Grid.RowDefinitions>-->
             <!--图像-->
             <local:ShowVisionRender Grid.Row="0"
                                     Grid.Column="0" />
-            <!--曲线图-->
+            <!--曲线图--><!--
             <oxy:PlotView Grid.Row="1"
                           Grid.Column="0"
                           Model="{Binding LockCurvePlotModel}"
                           Background="Transparent"
-                          Margin="10" />
+                          Margin="10" />-->
         </Grid>
         <Grid Grid.Row="1"
               Grid.Column="1">
@@ -70,7 +70,7 @@
                         <TextBlock DockPanel.Dock="Top"
                                    FontWeight="Bold"
                                    FontSize="{DynamicResource Font.Size.Body3}"
-                                   Text="锁付结果:" />
+                                   Text="视觉引导定位数据:" />
                         <DataGrid x:Name="lockResultGrid"
                                   ItemsSource="{Binding LockResults}"
                                   AutoGenerateColumns="False"

+ 1 - 1
TeamAAS-VM/Views/Product/PlcPointParams.xaml

@@ -100,7 +100,7 @@
                                    OpenMode="Standard"
                                    x:Name="DrawerHost"
                                    IsLeftDrawerOpen="{Binding IsLeftDrawerOpen,Mode=TwoWay}"
-                                   d:IsLeftDrawerOpen="true"
+                                   d:IsLeftDrawerOpen="false"
                                    IsEnabled="{Binding IsAllowEdit}">
             <materialDesign:DrawerHost.LeftDrawerContent>
                 <Grid Width="600">