Sfoglia il codice sorgente

新增独立移动相机校准功能及相关界面

新增独立移动相机校准流程,包括视图、视图模型和业务逻辑。扩展了数据模型和接口,支持刚体变换齐次矩阵计算。完善了导航注册、权限控制和图像显示。更新项目文件以支持新模块,提升系统灵活性和可扩展性。
孝锋 徐 8 mesi fa
parent
commit
f8fa9c4c11

+ 2 - 0
TeamAAS-VM/App.xaml.cs

@@ -106,6 +106,7 @@ namespace TeamAAS_VP
             containerRegistry.RegisterForNavigation<CalibrationTeachCenterPoint>();
             containerRegistry.RegisterForNavigation<CalibrationVerification>();
             containerRegistry.RegisterForNavigation<FixedUpCameraFindP0>();
+            containerRegistry.RegisterForNavigation<CalibIndependentCamera>();
             //**************************************************************************************
 
             //------------------------注册单类------------------------------------------------
@@ -160,6 +161,7 @@ namespace TeamAAS_VP
             containerRegistry.RegisterSingleton<CalibrationTeachCenterPointViewModel>();
             containerRegistry.RegisterSingleton<CalibrationVerificationViewModel>();
             containerRegistry.RegisterSingleton<FixedUpCameraFindP0ViewModel>();
+            containerRegistry.RegisterSingleton<CalibIndependentCameraViewModel>();
             //**************************************************************************************
 
             //------------------------注册对话框------------------------------------------------

+ 8 - 0
TeamAAS-VM/Interfaces/ICameraCalibrationService.cs

@@ -145,5 +145,13 @@ namespace TeamAAS_VP.Interfaces
         /// <returns>元组字段:IsSuccess 表示验证是否通过;Result 包含详细的验证统计与误差分析。</returns>
         Task<(bool IsSuccess, CalibrationTestResult Result)> ExecuteCalibrationValidation(CalibrationInfo calibrationInfo, IRobot robot, CancellationToken cancellationToken);
 
+        /// <summary>
+        /// 独立模组相机计算独立模组步进坐标系与绝对坐标系的刚体变换矩阵
+        /// </summary>
+        /// <param name="calibrationInfo"></param>
+        /// <param name="robot"></param>
+        /// <param name="cancellationToken"></param>
+        /// <returns></returns>
+        Task<(bool IsSuccess, double[,] TransformationMatrix)> CalculateIndependentCameraRigidTransformationMatrix(CalibrationInfo calibrationInfo, IRobot robot, CancellationToken cancellationToken)
     }
 }

+ 22 - 12
TeamAAS-VM/Models/Calibration/CalibrationInfo.cs

@@ -60,7 +60,7 @@ namespace TeamAAS_VP.Models.Calibration
         public DateTime DateTime
         {
             get { return _DateTime; }
-            set { SetProperty(ref _DateTime,value); }
+            set { SetProperty(ref _DateTime, value); }
         }
 
         private string _CameraName;
@@ -70,7 +70,7 @@ namespace TeamAAS_VP.Models.Calibration
         public string CameraName
         {
             get { return _CameraName; }
-            set { SetProperty(ref _CameraName,value); }
+            set { SetProperty(ref _CameraName, value); }
         }
 
         private Guid _CameraID;
@@ -90,7 +90,7 @@ namespace TeamAAS_VP.Models.Calibration
         public Guid RobotId
         {
             get { return _RobotId; }
-            set { SetProperty(ref _RobotId,value); }
+            set { SetProperty(ref _RobotId, value); }
         }
 
         private Guid _FeederId;
@@ -181,7 +181,7 @@ namespace TeamAAS_VP.Models.Calibration
         public RPoint CenterPoint
         {
             get { return _CenterPoint; }
-            set { SetProperty(ref _CenterPoint,value); }
+            set { SetProperty(ref _CenterPoint, value); }
         }
 
         private RPoint _HomePoint;
@@ -201,7 +201,7 @@ namespace TeamAAS_VP.Models.Calibration
         public double Width
         {
             get { return _Width; }
-            set { SetProperty(ref _Width,value); }
+            set { SetProperty(ref _Width, value); }
         }
 
         private double _Height;
@@ -214,7 +214,7 @@ namespace TeamAAS_VP.Models.Calibration
             set { SetProperty(ref _Height, value); }
         }
 
-        private double _Angle=180;
+        private double _Angle = 180;
         /// <summary>
         /// 机器人移动的范围U
         /// </summary>
@@ -231,7 +231,7 @@ namespace TeamAAS_VP.Models.Calibration
         public RobotTool Tool
         {
             get { return _Tool; }
-            set { SetProperty(ref _Tool,value); }
+            set { SetProperty(ref _Tool, value); }
         }
 
         private RobotArm _Arm;
@@ -249,7 +249,7 @@ namespace TeamAAS_VP.Models.Calibration
         public int Speed
         {
             get { return _Speed; }
-            set { SetProperty(ref _Speed,value); }
+            set { SetProperty(ref _Speed, value); }
         }
 
         private int _Accel;
@@ -357,6 +357,16 @@ namespace TeamAAS_VP.Models.Calibration
             set { SetProperty(ref _IndependentDownCameraMotionModuleMoveX, value); }
         }
 
+        private double[,] _IndependentDownCameraMotionModuleHomogeneousMatrix;
+        /// <summary>
+        /// 独立移动模组的齐次矩阵
+        /// </summary>
+        public double[,] IndependentDownCameraMotionModuleHomogeneousMatrix
+        {
+            get { return _IndependentDownCameraMotionModuleHomogeneousMatrix; }
+            set { SetProperty(ref _IndependentDownCameraMotionModuleHomogeneousMatrix, value); }
+        }
+
         private ObservableCollection<RobotPixelPoint> _CalibPoints;
 
         /// <summary>
@@ -365,7 +375,7 @@ namespace TeamAAS_VP.Models.Calibration
         public ObservableCollection<RobotPixelPoint> CalibPoints
         {
             get { return _CalibPoints; }
-            set { SetProperty(ref _CalibPoints,value); }
+            set { SetProperty(ref _CalibPoints, value); }
         }
 
         private double[,] _RobotCameraRotationMatrix;
@@ -376,7 +386,7 @@ namespace TeamAAS_VP.Models.Calibration
         public double[,] RobotCameraRotationMatrix
         {
             get { return _RobotCameraRotationMatrix; }
-            set { SetProperty(ref _RobotCameraRotationMatrix,value); }
+            set { SetProperty(ref _RobotCameraRotationMatrix, value); }
         }
 
         private double _PixelScaleX;
@@ -427,7 +437,7 @@ namespace TeamAAS_VP.Models.Calibration
         public CalibrationResult CalibrationResult
         {
             get { return _CalibrationResult; }
-            set { SetProperty(ref _CalibrationResult,value); }
+            set { SetProperty(ref _CalibrationResult, value); }
         }
 
         private CalibrationTestResult _CalibrationTestResult;
@@ -435,7 +445,7 @@ namespace TeamAAS_VP.Models.Calibration
         public CalibrationTestResult CalibrationTestResult
         {
             get { return _CalibrationTestResult; }
-            set { SetProperty(ref _CalibrationTestResult,value); }
+            set { SetProperty(ref _CalibrationTestResult, value); }
         }
 
 

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

@@ -533,10 +533,14 @@
     <Compile Include="Events\MainTabSwitchNotification.cs" />
     <Compile Include="Models\Feeder\ScrewFeederInfo.cs" />
     <Compile Include="Models\ScrewFeederBatchRecord.cs" />
+    <Compile Include="ViewModels\Calibration\CalibIndependentCameraViewModel.cs" />
     <Compile Include="ViewModels\DebugMod\PlcRobotManualStepViewModel.cs" />
     <Compile Include="ViewModels\Product\ImageDisplayViewModel.cs" />
     <Compile Include="ViewModels\Setting\AddScrewFeederViewModel.cs" />
     <Compile Include="ViewModels\Statistics\LockResultRecoredQueryViewModel.cs" />
+    <Compile Include="Views\Calibration\CalibIndependentCamera.xaml.cs">
+      <DependentUpon>CalibIndependentCamera.xaml</DependentUpon>
+    </Compile>
     <Compile Include="Views\DebugMod\FocusAnalyzerl.xaml.cs">
       <DependentUpon>FocusAnalyzerl.xaml</DependentUpon>
     </Compile>
@@ -1089,6 +1093,10 @@
       <SubType>Designer</SubType>
       <Generator>MSBuild:Compile</Generator>
     </Page>
+    <Page Include="Views\Calibration\CalibIndependentCamera.xaml">
+      <SubType>Designer</SubType>
+      <Generator>MSBuild:Compile</Generator>
+    </Page>
     <Page Include="Views\DebugMod\FocusAnalyzerl.xaml">
       <SubType>Designer</SubType>
       <Generator>MSBuild:Compile</Generator>

+ 306 - 0
TeamAAS-VM/ViewModels/Calibration/CalibIndependentCameraViewModel.cs

@@ -0,0 +1,306 @@
+using Cognex.VisionPro;
+using Cognex.VisionPro.ToolBlock;
+using MathNet.Numerics.LinearAlgebra;
+using Prism.Commands;
+using Prism.Events;
+using Prism.Ioc;
+using Prism.Mvvm;
+using Prism.Regions;
+using Prism.Services.Dialogs;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Threading;
+using System.Threading.Tasks;
+using System.Windows;
+using Team.FFFeederService.Interfaces;
+using TeamAAS_VP.Core;
+using TeamAAS_VP.Interfaces;
+using TeamAAS_VP.Models.Calibration;
+using TeamAAS_VP.Models.Robot;
+using TeamAAS_VP.Resources.Languages;
+
+namespace TeamAAS_VP.ViewModels.Calibration
+{
+    public class CalibIndependentCameraViewModel : BindableBase, IConfirmNavigationRequest
+    {
+        IRegionManager _regionManager;
+        IRegionNavigationService _regionNavigationService;
+        IContainerProvider _container;
+        IDialogService _dialogService;
+        IEventAggregator _eventAggregator;
+        IRobotService _robotService;
+        IFeederService _feederService;
+        ICameraService _cameraService;
+        ISystemDatabaseService _systemDatabaseService;
+        ICameraCalibrationService _cameraCalibrationService;
+        private CancellationTokenSource _cts;
+        #region 属性
+        private ICogImage _Image;
+
+        public ICogImage Image
+        {
+            get { return _Image; }
+            set { SetProperty(ref _Image, value); }
+        }
+
+        private Cognex.VisionPro.CogGraphicCollection _Graphic;
+
+        public Cognex.VisionPro.CogGraphicCollection Graphic
+        {
+            get { return _Graphic; }
+            set { SetProperty(ref _Graphic, value); }
+        }
+
+        private CalibrationInfo _SelectCalibration;
+
+        public CalibrationInfo SelectCalibration
+        {
+            get { return _SelectCalibration; }
+            set { SetProperty(ref _SelectCalibration, value); }
+        }
+
+        public Management management { get; set; }
+        public IRobot Robot { get; set; }
+
+        private bool _IsRunning = true;
+
+        public bool IsRunning
+        {
+            get { return _IsRunning; }
+            set { SetProperty(ref _IsRunning, value); }
+        }
+
+        private ICamera _Camera;
+
+        public ICamera Camera
+        {
+            get { return _Camera; }
+            set { SetProperty(ref _Camera, value); }
+        }
+        #endregion
+
+        #region 命令
+        private DelegateCommand _NextCommand;
+        public DelegateCommand NextCommand =>
+            _NextCommand ?? (_NextCommand = new DelegateCommand(ExecuteNextCommand).ObservesCanExecute(() => IsRunning));
+
+        private DelegateCommand _BackCommand;
+        public DelegateCommand BackCommand =>
+            _BackCommand ?? (_BackCommand = new DelegateCommand(ExecuteBackCommand).ObservesCanExecute(() => IsRunning));
+
+        private DelegateCommand _StartCalibCommand;
+        public DelegateCommand StartCalibCommand =>
+            _StartCalibCommand ?? (_StartCalibCommand = new DelegateCommand(ExecuteStartCalibCommand).ObservesCanExecute(() => IsRunning));
+
+        #endregion
+
+        #region 事件
+
+        #endregion
+
+        public CalibIndependentCameraViewModel(IRegionManager regionManager, IEventAggregator ea, IRegionNavigationService regionNavigationService, IContainerProvider container, IDialogService dialogService,
+            IRobotService robotService, IFeederService feederService, ICameraService cameraService, ISystemDatabaseService systemDatabaseService, ICameraCalibrationService cameraCalibrationService)
+        {
+            _regionManager = regionManager;
+            _regionNavigationService = regionNavigationService;
+            _container = container;
+            _dialogService = dialogService;
+            _robotService = robotService;
+            _eventAggregator = ea;
+            _feederService = feederService;
+            _cameraService = cameraService;
+            _systemDatabaseService = systemDatabaseService;
+            _cameraCalibrationService = cameraCalibrationService;
+        }
+
+        #region 方法
+
+        async void ExecuteStartCalibCommand()
+        {
+            try
+            {
+                //弹窗提示是否开始独立移动相机刚体变换校准
+                MessageBoxResult msgResult = MessageBox.Show("是否开始独立移动相机位置校准", Lang.自动校准, MessageBoxButton.YesNo, MessageBoxImage.Question);
+                if (msgResult != MessageBoxResult.Yes)
+                {
+                    return;
+                }
+
+                IsRunning = false;
+                _cts = new CancellationTokenSource();
+                (bool IsSuccess, double[,] TransformationMatrix) = await _cameraCalibrationService.CalculateIndependentCameraRigidTransformationMatrix(SelectCalibration, Robot, _cts.Token);
+                if (!IsSuccess)
+                {
+                    MessageBox.Show("独立移动相机位置校准失败", $"{Lang.自动校准}", MessageBoxButton.OK, MessageBoxImage.Warning);
+                    return;
+                }
+                SelectCalibration.IndependentDownCameraMotionModuleHomogeneousMatrix = TransformationMatrix;
+                NavigationParameters param = new NavigationParameters();
+                param.Add("SelectCalibration", SelectCalibration);
+                _regionManager.RequestNavigate("CalibrationRegionContext", "CalibrationAuto", param);
+                
+            }
+            catch (Exception ex)
+            {
+                LogHelper.WriteLogError("独立移动相机位置校准时出错!", ex);
+                MessageBox.Show(ex.Message);
+            }
+            finally
+            {
+                try
+                {
+                    if (_cts != null && !_cts.IsCancellationRequested)
+                        _cts.Cancel();
+                    _cts?.Dispose();
+                    _cts = null;
+                }
+                catch (Exception)
+                {
+
+                }
+                IsRunning = true;
+            }
+        }
+
+        /// <summary>
+        /// 下一步
+        /// </summary>
+        void ExecuteNextCommand()
+        {
+            NavigationParameters param = new NavigationParameters();
+            param.Add("SelectCalibration", SelectCalibration);
+            _regionManager.RequestNavigate("CalibrationRegionContext", "CalibrationAuto", param);
+        }
+
+        /// <summary>
+        /// 上一步
+        /// </summary>
+        void ExecuteBackCommand()
+        {
+            NavigationParameters param = new NavigationParameters();
+            param.Add("SelectCalibration", SelectCalibration);
+
+            _regionManager.RequestNavigate("CalibrationRegionContext", "CalibrationSelectTool", param);
+        }
+
+        /// <summary>
+        /// 相机拍照
+        /// </summary>
+        /// <returns></returns>
+        private async Task<(bool IsSuccess, double X, double Y, double U, int ImageWidth, int ImageHeight)> CaptureAndProcess()
+        {
+            await Task.Delay(200);
+            //采集图像
+            if (Camera != null)
+            {
+                SelectCalibration.ToolBlock.Inputs["InputImage"].Value = Camera.Grab();
+
+            }
+            App.Current.Dispatcher.Invoke(() =>
+            {
+                Graphic = null;
+                Image = (ICogImage)SelectCalibration.ToolBlock.Inputs["InputImage"].Value;
+            });
+
+            SelectCalibration.ToolBlock.Run();
+            CogToolBlockTerminalCollection outputCollection = SelectCalibration.ToolBlock.Outputs;
+            App.Current.Dispatcher.Invoke(() =>
+            {
+                Graphic = outputCollection["Graphic"].Value as CogGraphicCollection;
+            });
+
+            bool Found = (bool)(outputCollection["Found"].Value);
+            if (Found)
+            {
+                var strpoints = outputCollection["Point"].Value.ToString();
+                string[] items = strpoints.Split(',');
+                double x = double.Parse(items[0]);
+                double y = double.Parse(items[1]);
+                return (true, x, y, 0, Image.Width, Image.Height);
+            }
+            else
+            {
+                return (false, 0, 0, 0, Image.Width, Image.Height);
+            }
+        }
+
+        #endregion
+
+        #region 继承
+        /// <summary>
+        /// 确认导航请求时调用。此方法允许您在导航之前执行一些操作。
+        /// </summary>
+        /// <param name="navigationContext"></param>
+        /// <param name="continuationCallback"></param>
+        public void ConfirmNavigationRequest(NavigationContext navigationContext, Action<bool> continuationCallback)
+        {
+            continuationCallback(true);
+        }
+
+        /// <summary>
+        /// 接收导航请求时调用。传入导航参数,包含有关导航目标的信息。
+        /// </summary>
+        /// <param name="navigationContext"></param>
+        /// <exception cref="NotImplementedException"></exception>
+        public async void OnNavigatedTo(NavigationContext navigationContext)
+        {
+            SelectCalibration = navigationContext.Parameters.GetValue<CalibrationInfo>("SelectCalibration");
+            if (SelectCalibration != null)
+            {
+                Robot = _robotService.GetRobot(SelectCalibration.RobotId);
+            }
+            Camera = _cameraService.GetCamera(SelectCalibration.CameraID);
+            _cameraCalibrationService.CaptureAndProcessCallback = null;
+            _cameraCalibrationService.CaptureAndProcessCallback = CaptureAndProcess;
+            if (_systemDatabaseService.GetCurrentUser().userPart == Enums.UserPart.Operator)
+            {
+                IsAllowEdit = false;
+            }
+            else
+            {
+                IsAllowEdit = true;
+            }
+        }
+
+        /// <summary>
+        /// 是否允许导航到此视图模型。
+        /// </summary>
+        /// <param name="navigationContext"></param>
+        /// <returns></returns>
+        public bool IsNavigationTarget(NavigationContext navigationContext)
+        {
+            return true;
+        }
+
+        /// <summary>
+        /// 导航离开此视图模型时调用。您可以在此处执行清理操作或保存状态。
+        /// </summary>
+        /// <param name="navigationContext"></param>
+        public void OnNavigatedFrom(NavigationContext navigationContext)
+        {
+            _cameraCalibrationService.CaptureAndProcessCallback = null;
+        }
+        #endregion
+
+        private bool _IsAllowEdit = false;
+
+        public bool IsAllowEdit
+        {
+            get { return _IsAllowEdit; }
+            set { SetProperty(ref _IsAllowEdit, value); }
+        }
+
+        private void LoginChange(Models.User user)
+        {
+            if (user.userPart == Enums.UserPart.Operator)
+            {
+                IsAllowEdit = false;
+            }
+            else
+            {
+                IsAllowEdit = true;
+            }
+        }
+    }
+}

+ 8 - 1
TeamAAS-VM/ViewModels/Calibration/CalibrationSelectToolViewModel.cs

@@ -145,7 +145,14 @@ namespace TeamAAS_VP.ViewModels.Calibration
         {
             NavigationParameters param = new NavigationParameters();
             param.Add("SelectCalibration", SelectCalibration);
-            _regionManager.RequestNavigate("CalibrationRegionContext", "CalibrationAuto", param);
+            if (SelectCalibration.CameraMount== Enums.CameraMount.MobileDown_IndependentXYPlatform)
+            {
+                _regionManager.RequestNavigate("CalibrationRegionContext", "CalibIndependentCamera", param);
+            }
+            else
+            {
+                _regionManager.RequestNavigate("CalibrationRegionContext", "CalibrationAuto", param);
+            }
         }
 
         /// <summary>

+ 123 - 0
TeamAAS-VM/Views/Calibration/CalibIndependentCamera.xaml

@@ -0,0 +1,123 @@
+<UserControl x:Class="TeamAAS_VP.Views.Calibration.CalibIndependentCamera"
+             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
+             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
+             xmlns:prism="http://prismlibrary.com/"
+             xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
+             xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
+             xmlns:mah="http://metro.mahapps.com/winfx/xaml/controls"
+             xmlns:materialDesign="http://materialdesigninxaml.net/winfx/xaml/themes"
+             xmlns:b="http://schemas.microsoft.com/xaml/behaviors"
+             xmlns:wf="clr-namespace:System.Windows.Forms.Integration;assembly=WindowsFormsIntegration"
+             xmlns:vp="clr-namespace:Cognex.VisionPro;assembly=Cognex.VisionPro.Controls"
+             xmlns:vm="clr-namespace:TeamAAS_VP.ViewModels.Calibration"
+             xmlns:lex="http://wpflocalizeextension.codeplex.com"
+             lex:LocalizeDictionary.DesignCulture="zh-CN"
+             lex:ResxLocalizationProvider.DefaultAssembly="TeamAAS-VP"
+             lex:ResxLocalizationProvider.DefaultDictionary="Lang"
+             prism:ViewModelLocator.AutoWireViewModel="True"
+             mc:Ignorable="d"
+             d:DataContext="{d:DesignInstance Type=vm:CalibIndependentCameraViewModel}"
+             d:Height="600"
+             d:Width="1024"
+             d:Background="White"
+             FontFamily="{DynamicResource DefaultFont}">
+    <Grid>
+        <Grid.RowDefinitions>
+            <RowDefinition Height="auto" />
+            <RowDefinition Height="*" />
+            <RowDefinition Height="auto" />
+        </Grid.RowDefinitions>
+        <Button Grid.Row="0"
+                Content="{materialDesign:PackIcon Kind=ArrowLeftCircle}"
+                Width="50"
+                HorizontalAlignment="Left"
+                VerticalAlignment="Top"
+                ToolTip="{lex:Loc 返回}"
+                Style="{StaticResource MaterialDesignIconButton}"
+                Command="{Binding BackCommand}" />
+        <StackPanel Grid.Row="0"
+                    Orientation="Horizontal"
+                    Margin="50,0"
+                    VerticalAlignment="Center">
+            <materialDesign:PackIcon Kind="CrosshairsGps"
+                                     Width="30"
+                                     Height="30" />
+            <TextBlock Text="{Binding SelectCalibration.Name,Converter={StaticResource StringFormatConverter},ConverterParameter=' [{0}] '}"
+                       VerticalAlignment="Center"
+                       TextTrimming="CharacterEllipsis" />
+            <TextBlock Text="- 独立移动相机校准"
+                       VerticalAlignment="Center"
+                       TextTrimming="CharacterEllipsis" />
+        </StackPanel>
+
+        <Grid Grid.Row="1"
+              IsEnabled="{Binding IsAllowEdit}">
+            <Grid.RowDefinitions>
+                <RowDefinition Height="*" />
+                <RowDefinition Height="auto" />
+            </Grid.RowDefinitions>
+            <Grid.ColumnDefinitions>
+                <ColumnDefinition Width="*" />
+                <ColumnDefinition Width="auto"
+                                  MinWidth="300" />
+            </Grid.ColumnDefinitions>
+            <wf:WindowsFormsHost Grid.Column="0">
+                <vp:CogRecordDisplay x:Name="display" />
+            </wf:WindowsFormsHost>
+            <StackPanel Grid.Row="0"
+                        Grid.Column="1"
+                        Orientation="Vertical" VerticalAlignment="Center">
+                <StackPanel Orientation="Horizontal">
+                    <TextBlock Text="独立模组X方向移动的距离:"
+                               VerticalAlignment="Center"
+                               Margin="0,0,5,0" />
+                    <mah:NumericUpDown Grid.Row="6"
+                                       Grid.Column="1"
+                                       Maximum="600"
+                                       Minimum="-600"
+                                       Interval="1"
+                                       MinHeight="30"
+                                       Margin="5,10"
+                                       MinWidth="120"
+                                       StringFormat="{}{0:N3} mm"
+                                       materialDesign:HintAssist.HelperText="移动距离"
+                                       Value="{Binding SelectCalibration.IndependentDownCameraMotionModuleMoveX,Mode=TwoWay}" />
+                    
+                    <TextBlock Text="mm"
+                               VerticalAlignment="Center"
+                               Margin="0,0,5,0" />
+                </StackPanel>
+                <Button
+                        MinWidth="150"
+                        Margin="10,10"
+                        HorizontalAlignment="Center"
+                        VerticalAlignment="Center"
+                        materialDesign:ButtonAssist.CornerRadius="10"
+                        Style="{StaticResource MaterialDesignRaisedButton}"
+                        Command="{Binding StartCalibCommand}">
+                    <StackPanel Orientation="Horizontal">
+                        <materialDesign:PackIcon Kind="AutomaticStart" />
+                        <TextBlock Text="开始校准"
+                                   Margin="5,0" />
+                    </StackPanel>
+                </Button>
+            </StackPanel>
+        </Grid>
+
+        <StackPanel Grid.Row="2"
+                    Orientation="Horizontal"
+                    HorizontalAlignment="Center"
+                    VerticalAlignment="Center"
+                    Margin="20">
+            <Button Content="{lex:Loc 下一步}"
+                    IsEnabled="{Binding IsAllowEdit}"
+                    MinWidth="150"
+                    Margin="10,0"
+                    HorizontalAlignment="Center"
+                    VerticalAlignment="Center"
+                    materialDesign:ButtonAssist.CornerRadius="10"
+                    Style="{StaticResource MaterialDesignRaisedButton}"
+                    Command="{Binding NextCommand}" />
+        </StackPanel>
+    </Grid>
+</UserControl>

+ 73 - 0
TeamAAS-VM/Views/Calibration/CalibIndependentCamera.xaml.cs

@@ -0,0 +1,73 @@
+using Cognex.VisionPro;
+using Cognex.VisionPro.Dimensioning;
+using System;
+using System.Windows.Controls;
+using TeamAAS_VP.ViewModels.Calibration;
+
+namespace TeamAAS_VP.Views.Calibration
+{
+    /// <summary>
+    /// Interaction logic for CalibIndependentCamera
+    /// </summary>
+    public partial class CalibIndependentCamera : UserControl
+    {
+
+        CalibIndependentCameraViewModel VM;
+        public CalibIndependentCamera()
+        {
+            InitializeComponent();
+            VM = DataContext as CalibIndependentCameraViewModel;
+            VM.PropertyChanged += VM_PropertyChanged;
+            this.display.VerticalScrollBar = false;
+            this.display.HorizontalScrollBar = false;
+            this.display.AutoFit = true;
+            this.display.BackColor = System.Drawing.SystemColors.ActiveCaption;
+        }
+
+        private int _imageWidth;
+        private int _imageHeight;
+        private void VM_PropertyChanged(object sender, System.ComponentModel.PropertyChangedEventArgs e)
+        {
+            try
+            {
+                if (e.PropertyName == "Image")
+                {
+                    this.display.Image = VM.Image;
+                    //图像中心点坐标
+                    _imageWidth = this.display.Image.Width;
+                    _imageHeight = this.display.Image.Height;
+                }
+                else if (e.PropertyName == "Graphic")
+                {
+                    this.display.StaticGraphics.Clear();
+                    CogGraphicCollection graphic = new CogGraphicCollection();
+                    CogCreateLineTool line1 = new CogCreateLineTool();
+                    CogCreateLineTool line2 = new CogCreateLineTool();
+                    line1.InputImage = this.display.Image;
+                    line2.InputImage = this.display.Image;
+                    line1.Line.X = _imageWidth / 2;
+                    line1.Line.Y = _imageHeight / 2;
+                    line1.Line.Rotation = 0;
+                    line2.Line.X = _imageWidth / 2;
+                    line2.Line.Y = _imageHeight / 2;
+                    line2.Line.Rotation = Math.PI / 180 * 90;
+                    line1.Run();
+                    line2.Run();
+                    graphic.Add(line1.GetOutputLine());
+                    graphic.Add(line2.GetOutputLine());
+                    this.display.StaticGraphics.Clear();
+                    this.display.StaticGraphics.AddList(graphic, "");
+                    if (VM.Graphic != null)
+                    {
+                        this.display.StaticGraphics.AddList(VM.Graphic, "");
+                    }
+
+                }
+            }
+            catch (System.Exception)
+            {
+
+            }
+        }
+    }
+}