| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276 |
- <UserControl x:Class="TeamAAS.Views.CalibrationView"
- xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
- xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
- xmlns:hc="https://handyorg.github.io/handycontrol"
- xmlns:sys="clr-namespace:System;assembly=mscorlib"
- xmlns:loc="clr-namespace:TeamAAS.Localization"
- xmlns:conv="clr-namespace:TeamAAS.Converters">
- <UserControl.Resources>
- <conv:EnumDescriptionConverter x:Key="EnumDescConv"/>
- <conv:StepToVisibilityConverter x:Key="StepVisConv"/>
- <BooleanToVisibilityConverter x:Key="BoolToVis"/>
- <sys:Boolean x:Key="TrueVal">True</sys:Boolean>
- <sys:Boolean x:Key="FalseVal">False</sys:Boolean>
- <Style x:Key="FieldLabel" TargetType="TextBlock">
- <Setter Property="VerticalAlignment" Value="Center"/>
- <Setter Property="Margin" Value="0,0,8,0"/>
- <Setter Property="Foreground" Value="{DynamicResource SecondaryTextBrush}"/>
- </Style>
- <Style x:Key="FieldRow" TargetType="StackPanel">
- <Setter Property="Orientation" Value="Horizontal"/>
- <Setter Property="Margin" Value="0,4"/>
- </Style>
- <Style x:Key="EnumCombo" TargetType="ComboBox">
- <Setter Property="MinWidth" Value="160"/>
- <Setter Property="ItemTemplate">
- <Setter.Value>
- <DataTemplate>
- <TextBlock Text="{Binding Converter={StaticResource EnumDescConv}}"/>
- </DataTemplate>
- </Setter.Value>
- </Setter>
- </Style>
- </UserControl.Resources>
- <Grid Margin="24,16">
- <Grid.RowDefinitions>
- <RowDefinition Height="Auto"/>
- <RowDefinition Height="Auto"/>
- <RowDefinition Height="*"/>
- <RowDefinition Height="Auto"/>
- <RowDefinition Height="Auto"/>
- </Grid.RowDefinitions>
- <!-- 标题 + 选择已有标定 + 新建 -->
- <Grid Grid.Row="0" Margin="0,0,0,12">
- <Grid.ColumnDefinitions>
- <ColumnDefinition Width="Auto"/>
- <ColumnDefinition Width="*"/>
- <ColumnDefinition Width="Auto"/>
- </Grid.ColumnDefinitions>
- <TextBlock Grid.Column="0" Text="{loc:Translate '标定向导'}" FontSize="20" FontWeight="Bold"
- Foreground="{DynamicResource PrimaryTextBrush}" VerticalAlignment="Center"/>
- <StackPanel Grid.Column="1" Orientation="Horizontal" HorizontalAlignment="Right" VerticalAlignment="Center" Margin="0,0,12,0">
- <TextBlock Text="已有标定" Style="{StaticResource FieldLabel}"/>
- <ComboBox ItemsSource="{Binding Calibrations}" SelectedItem="{Binding SelectedCalibration}"
- DisplayMemberPath="Name" MinWidth="220"/>
- </StackPanel>
- <Button Grid.Column="2" Content="新建标定" Command="{Binding NewCommand}" VerticalAlignment="Center" Padding="16,6"/>
- </Grid>
- <!-- 步骤指示 -->
- <hc:StepBar Grid.Row="1" StepIndex="{Binding StepIndex, Mode=TwoWay}" Margin="0,0,0,16">
- <hc:StepBarItem Content="基础设置"/>
- <hc:StepBarItem Content="视觉与相机"/>
- <hc:StepBarItem Content="示教点位"/>
- <hc:StepBarItem Content="工具坐标"/>
- <hc:StepBarItem Content="九点标定"/>
- <hc:StepBarItem Content="验证"/>
- <hc:StepBarItem Content="完成"/>
- </hc:StepBar>
- <!-- 内容区 -->
- <Border Grid.Row="2" Background="{DynamicResource RegionBrush}" CornerRadius="8" Padding="20">
- <Grid>
- <!-- 步骤 0:基础设置 -->
- <ScrollViewer Visibility="{Binding StepIndex, Converter={StaticResource StepVisConv}, ConverterParameter=0}"
- VerticalScrollBarVisibility="Auto">
- <StackPanel MaxWidth="560" HorizontalAlignment="Left">
- <StackPanel Style="{StaticResource FieldRow}">
- <TextBlock Text="标定名称" Style="{StaticResource FieldLabel}" Width="96"/>
- <TextBox Text="{Binding Calib.Name, UpdateSourceTrigger=PropertyChanged}" MinWidth="240"/>
- </StackPanel>
- <StackPanel Style="{StaticResource FieldRow}">
- <TextBlock Text="机器人" Style="{StaticResource FieldLabel}" Width="96"/>
- <ComboBox ItemsSource="{Binding Robots}" SelectedItem="{Binding SelectedRobot}"
- DisplayMemberPath="RobotName" MinWidth="240"/>
- </StackPanel>
- <StackPanel Style="{StaticResource FieldRow}">
- <TextBlock Text="相机" Style="{StaticResource FieldLabel}" Width="96"/>
- <ComboBox ItemsSource="{Binding Cameras}" SelectedItem="{Binding SelectedCamera}"
- DisplayMemberPath="CameraName" MinWidth="240"/>
- </StackPanel>
- <StackPanel Style="{StaticResource FieldRow}">
- <TextBlock Text="相机安装方式" Style="{StaticResource FieldLabel}" Width="96"/>
- <ComboBox Style="{StaticResource EnumCombo}" ItemsSource="{Binding CameraMounts}"
- SelectedItem="{Binding Calib.CameraMount}"/>
- </StackPanel>
- <StackPanel Style="{StaticResource FieldRow}">
- <TextBlock Text="取料方式" Style="{StaticResource FieldLabel}" Width="96"/>
- <ComboBox Style="{StaticResource EnumCombo}" ItemsSource="{Binding PickModels}"
- SelectedItem="{Binding Calib.Pick.PickPlaceModel}"/>
- </StackPanel>
- <StackPanel Style="{StaticResource FieldRow}">
- <TextBlock Text="吸气/夹紧 IO" Style="{StaticResource FieldLabel}" Width="96"/>
- <TextBox Text="{Binding Calib.Pick.Inhal, UpdateSourceTrigger=PropertyChanged}" Width="70"/>
- <TextBlock Text="吹气/松开 IO" Style="{StaticResource FieldLabel}" Margin="16,0,8,0"/>
- <TextBox Text="{Binding Calib.Pick.Blow, UpdateSourceTrigger=PropertyChanged}" Width="70"/>
- </StackPanel>
- <StackPanel Style="{StaticResource FieldRow}">
- <TextBlock Text="速度 / 加速度" Style="{StaticResource FieldLabel}" Width="96"/>
- <TextBox Text="{Binding Calib.Speed, UpdateSourceTrigger=PropertyChanged}" Width="70"/>
- <TextBox Text="{Binding Calib.Accel, UpdateSourceTrigger=PropertyChanged}" Width="70" Margin="8,0,0,0"/>
- </StackPanel>
- <StackPanel Style="{StaticResource FieldRow}">
- <TextBlock Text="幅面 X / Y / U" Style="{StaticResource FieldLabel}" Width="96"/>
- <TextBox Text="{Binding Calib.Width, UpdateSourceTrigger=PropertyChanged}" Width="70"/>
- <TextBox Text="{Binding Calib.Height, UpdateSourceTrigger=PropertyChanged}" Width="70" Margin="8,0,0,0"/>
- <TextBox Text="{Binding Calib.Angle, UpdateSourceTrigger=PropertyChanged}" Width="70" Margin="8,0,0,0"/>
- </StackPanel>
- <StackPanel Style="{StaticResource FieldRow}">
- <TextBlock Text="吸真空/破真空/拍照延时(ms)" Style="{StaticResource FieldLabel}" Width="180"/>
- <TextBox Text="{Binding Calib.WaitSuction, UpdateSourceTrigger=PropertyChanged}" Width="60"/>
- <TextBox Text="{Binding Calib.WaitBlow, UpdateSourceTrigger=PropertyChanged}" Width="60" Margin="8,0,0,0"/>
- <TextBox Text="{Binding Calib.WaitPhoto, UpdateSourceTrigger=PropertyChanged}" Width="60" Margin="8,0,0,0"/>
- </StackPanel>
- </StackPanel>
- </ScrollViewer>
- <!-- 步骤 1:视觉与相机(仅相机测试:参数 + 测试拍照取点 + 选择视觉工具;九点标定页已移至第 5 步) -->
- <StackPanel Visibility="{Binding StepIndex, Converter={StaticResource StepVisConv}, ConverterParameter=1}" MaxWidth="560" HorizontalAlignment="Left">
- <StackPanel Style="{StaticResource FieldRow}">
- <TextBlock Text="曝光时间" Style="{StaticResource FieldLabel}" Width="72"/>
- <TextBox Text="{Binding Calib.ExposureTime, UpdateSourceTrigger=PropertyChanged}" Width="100"/>
- </StackPanel>
- <StackPanel Style="{StaticResource FieldRow}">
- <TextBlock Text="增益" Style="{StaticResource FieldLabel}" Width="72"/>
- <TextBox Text="{Binding Calib.Gain, UpdateSourceTrigger=PropertyChanged}" Width="100"/>
- </StackPanel>
- <StackPanel Style="{StaticResource FieldRow}">
- <TextBlock Text="光源亮度" Style="{StaticResource FieldLabel}" Width="72"/>
- <TextBox Text="{Binding Calib.Brightness, UpdateSourceTrigger=PropertyChanged}" Width="100"/>
- </StackPanel>
- <CheckBox Content="启用畸变校正" IsChecked="{Binding Calib.IsDistortionCorrection}" Margin="0,8"/>
- <Button Content="测试拍照取点" Command="{Binding TestCaptureCommand}" Margin="0,8" Padding="16,6"
- Style="{StaticResource ButtonPrimary}" HorizontalAlignment="Left"/>
- <Button Content="选择视觉标定工具(.vpp)" Command="{Binding LoadVisionToolCommand}" Margin="0,4" Padding="16,6" HorizontalAlignment="Left"/>
- <TextBlock Text="本步仅用于相机连通与取点测试(结果显示在下方状态栏);九点标定请进入第 5 步。" TextWrapping="Wrap"
- Foreground="{DynamicResource SecondaryTextBrush}" Margin="0,8,0,0"/>
- </StackPanel>
- <!-- 步骤 2:示教点位 -->
- <StackPanel Visibility="{Binding StepIndex, Converter={StaticResource StepVisConv}, ConverterParameter=2}" MaxWidth="640" HorizontalAlignment="Left">
- <StackPanel Style="{StaticResource FieldRow}">
- <TextBlock Text="P0 获取方式" Style="{StaticResource FieldLabel}" Width="96"/>
- <ComboBox Style="{StaticResource EnumCombo}" ItemsSource="{Binding P0Modes}"
- SelectedItem="{Binding Calib.CalibTechP0Mode}"/>
- </StackPanel>
- <StackPanel Style="{StaticResource FieldRow}">
- <Button Content="示教中心点" Command="{Binding TeachCenterCommand}" Padding="14,6" Margin="0,0,8,0"/>
- <TextBlock VerticalAlignment="Center">
- <Run Text="X="/><Run Text="{Binding Calib.CenterPoint.X, Mode=OneWay, StringFormat={}{0:F3}}"/>
- <Run Text=" Y="/><Run Text="{Binding Calib.CenterPoint.Y, Mode=OneWay, StringFormat={}{0:F3}}"/>
- <Run Text=" Z="/><Run Text="{Binding Calib.CenterPoint.Z, Mode=OneWay, StringFormat={}{0:F3}}"/>
- <Run Text=" U="/><Run Text="{Binding Calib.CenterPoint.U, Mode=OneWay, StringFormat={}{0:F3}}"/>
- </TextBlock>
- </StackPanel>
- <StackPanel Style="{StaticResource FieldRow}">
- <Button Content="示教待机点" Command="{Binding TeachHomeCommand}" Padding="14,6" Margin="0,0,8,0"/>
- <TextBlock VerticalAlignment="Center">
- <Run Text="X="/><Run Text="{Binding Calib.HomePoint.X, Mode=OneWay, StringFormat={}{0:F3}}"/>
- <Run Text=" Y="/><Run Text="{Binding Calib.HomePoint.Y, Mode=OneWay, StringFormat={}{0:F3}}"/>
- <Run Text=" Z="/><Run Text="{Binding Calib.HomePoint.Z, Mode=OneWay, StringFormat={}{0:F3}}"/>
- </TextBlock>
- </StackPanel>
- <StackPanel Style="{StaticResource FieldRow}">
- <Button Content="示教 Mark 点" Command="{Binding TeachMarkCommand}" Padding="14,6" Margin="0,0,8,0"/>
- <TextBlock VerticalAlignment="Center">
- <Run Text="X="/><Run Text="{Binding Calib.MarkPoint.X, Mode=OneWay, StringFormat={}{0:F3}}"/>
- <Run Text=" Y="/><Run Text="{Binding Calib.MarkPoint.Y, Mode=OneWay, StringFormat={}{0:F3}}"/>
- </TextBlock>
- </StackPanel>
- <StackPanel Style="{StaticResource FieldRow}">
- <TextBlock Text="夹爪/吸气测试" Style="{StaticResource FieldLabel}" Width="96"/>
- <Button Content="吸气/夹紧" Command="{Binding GripperCommand}" CommandParameter="{StaticResource TrueVal}" Padding="14,6" Margin="0,0,8,0"/>
- <Button Content="破真空/张开" Command="{Binding GripperCommand}" CommandParameter="{StaticResource FalseVal}" Padding="14,6"/>
- </StackPanel>
- </StackPanel>
- <!-- 步骤 3:工具坐标 TCP -->
- <StackPanel Visibility="{Binding StepIndex, Converter={StaticResource StepVisConv}, ConverterParameter=3}" MaxWidth="640" HorizontalAlignment="Left">
- <TextBlock TextWrapping="Wrap" Foreground="{DynamicResource SecondaryTextBrush}"
- Text="按相机安装方式标定工具坐标(TCP):固定向下/向上会提示摆放标定块并自动逼近中心;J4 随动模式自动求旋转中心。XY 模组无需此步(自动跳过)。"/>
- <Button Content="运行工具坐标标定" Command="{Binding RunTcpCommand}" Padding="16,6" Margin="0,12,0,0"
- Style="{StaticResource ButtonPrimary}" HorizontalAlignment="Left"/>
- <StackPanel Style="{StaticResource FieldRow}" Margin="0,12,0,0">
- <TextBlock Text="工具坐标 Tool" Style="{StaticResource FieldLabel}" Width="96"/>
- <TextBlock VerticalAlignment="Center">
- <Run Text="X="/><Run Text="{Binding Calib.Tool.X, Mode=OneWay, StringFormat={}{0:F3}}"/>
- <Run Text=" Y="/><Run Text="{Binding Calib.Tool.Y, Mode=OneWay, StringFormat={}{0:F3}}"/>
- </TextBlock>
- </StackPanel>
- </StackPanel>
- <!-- 步骤 4:九点标定(左:机器人自动九点标定 / 右:当前视觉引擎的手动标定页) -->
- <Grid Visibility="{Binding StepIndex, Converter={StaticResource StepVisConv}, ConverterParameter=4}">
- <Grid.ColumnDefinitions>
- <ColumnDefinition Width="360"/>
- <ColumnDefinition Width="*"/>
- </Grid.ColumnDefinitions>
- <StackPanel Grid.Column="0" Margin="0,0,16,0">
- <TextBlock TextWrapping="Wrap" Foreground="{DynamicResource SecondaryTextBrush}"
- Text="以中心点为原点生成 3x3 九点,机器人逐点运动+拍照,OpenCV 求像素→机器人仿射矩阵并计算精度。"/>
- <Button Content="运行九点标定" Command="{Binding RunNinePointCommand}" Padding="16,6" Margin="0,12,0,0"
- Style="{StaticResource ButtonPrimary}" HorizontalAlignment="Left"/>
- <StackPanel Style="{StaticResource FieldRow}" Margin="0,12,0,0">
- <TextBlock VerticalAlignment="Center" TextWrapping="Wrap">
- <Run Text="RMS="/><Run Text="{Binding Calib.CalibrationResult.RMS, Mode=OneWay, StringFormat={}{0:F4}}"/>
- <Run Text=" mm 最大误差="/><Run Text="{Binding Calib.CalibrationResult.MaxErrorValue, Mode=OneWay, StringFormat={}{0:F4}}"/>
- <Run Text=" mm 旋转="/><Run Text="{Binding Calib.CalibrationResult.Rotate, Mode=OneWay, StringFormat={}{0:F3}}"/>
- <Run Text="° ScaleX="/><Run Text="{Binding Calib.CalibrationResult.ScaleX, Mode=OneWay, StringFormat={}{0:F5}}"/>
- <Run Text=" ScaleY="/><Run Text="{Binding Calib.CalibrationResult.ScaleY, Mode=OneWay, StringFormat={}{0:F5}}"/>
- </TextBlock>
- </StackPanel>
- </StackPanel>
- <Border Grid.Column="1" BorderThickness="1" BorderBrush="{DynamicResource BorderBrush}" CornerRadius="6">
- <ContentControl Content="{Binding EngineCalibrationView}"/>
- </Border>
- </Grid>
- <!-- 步骤 5:验证 -->
- <StackPanel Visibility="{Binding StepIndex, Converter={StaticResource StepVisConv}, ConverterParameter=5}" MaxWidth="640" HorizontalAlignment="Left">
- <TextBlock TextWrapping="Wrap" Foreground="{DynamicResource SecondaryTextBrush}"
- Text="在 5 个验证点上复算误差,评估标定质量。"/>
- <Button Content="运行验证" Command="{Binding RunVerifyCommand}" Padding="16,6" Margin="0,12,0,0"
- Style="{StaticResource ButtonPrimary}" HorizontalAlignment="Left"/>
- <StackPanel Style="{StaticResource FieldRow}" Margin="0,12,0,0">
- <TextBlock VerticalAlignment="Center">
- <Run Text="RMSE X="/><Run Text="{Binding Calib.CalibrationTestResult.RMSEX, Mode=OneWay, StringFormat={}{0:F4}}"/>
- <Run Text=" mm RMSE Y="/><Run Text="{Binding Calib.CalibrationTestResult.RMSEY, Mode=OneWay, StringFormat={}{0:F4}}"/>
- <Run Text=" mm"/>
- </TextBlock>
- </StackPanel>
- </StackPanel>
- <!-- 步骤 6:完成 -->
- <StackPanel Visibility="{Binding StepIndex, Converter={StaticResource StepVisConv}, ConverterParameter=6}" MaxWidth="640" HorizontalAlignment="Left">
- <TextBlock TextWrapping="Wrap" Foreground="{DynamicResource SecondaryTextBrush}"
- Text="保存标定配置(含视觉工具引用)到 Runtime\Calibration,供运行时像素→机器人坐标换算使用。"/>
- <Button Content="保存标定" Command="{Binding SaveCommand}" Padding="16,6" Margin="0,12,0,0"
- Style="{StaticResource ButtonPrimary}" HorizontalAlignment="Left"/>
- <StackPanel Style="{StaticResource FieldRow}" Margin="0,12,0,0">
- <TextBlock Text="名称" Style="{StaticResource FieldLabel}" Width="48"/>
- <TextBlock Text="{Binding Calib.Name}" VerticalAlignment="Center"/>
- </StackPanel>
- </StackPanel>
- </Grid>
- </Border>
- <!-- 状态栏 -->
- <Border Grid.Row="3" Background="{DynamicResource SecondaryRegionBrush}" CornerRadius="6" Padding="12,8" Margin="0,12,0,0">
- <StackPanel Orientation="Horizontal">
- <TextBlock Text="执行中…" VerticalAlignment="Center" Margin="0,0,8,0" FontWeight="Bold"
- Foreground="{DynamicResource PrimaryTextBrush}"
- Visibility="{Binding IsBusy, Converter={StaticResource BoolToVis}}"/>
- <TextBlock Text="{Binding StatusText}" VerticalAlignment="Center" TextWrapping="Wrap"
- Foreground="{DynamicResource PrimaryTextBrush}"/>
- </StackPanel>
- </Border>
- <!-- 导航 -->
- <StackPanel Grid.Row="4" Orientation="Horizontal" HorizontalAlignment="Center" Margin="0,12,0,0">
- <Button Content="上一步" Command="{Binding BackCommand}" Padding="24,8" Margin="0,0,12,0"/>
- <Button Content="下一步" Command="{Binding NextCommand}" Style="{StaticResource ButtonPrimary}" Padding="24,8"/>
- </StackPanel>
- </Grid>
- </UserControl>
|