CalibrationView.xaml 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276
  1. <UserControl x:Class="TeamAAS.Views.CalibrationView"
  2. xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
  3. xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
  4. xmlns:hc="https://handyorg.github.io/handycontrol"
  5. xmlns:sys="clr-namespace:System;assembly=mscorlib"
  6. xmlns:loc="clr-namespace:TeamAAS.Localization"
  7. xmlns:conv="clr-namespace:TeamAAS.Converters">
  8. <UserControl.Resources>
  9. <conv:EnumDescriptionConverter x:Key="EnumDescConv"/>
  10. <conv:StepToVisibilityConverter x:Key="StepVisConv"/>
  11. <BooleanToVisibilityConverter x:Key="BoolToVis"/>
  12. <sys:Boolean x:Key="TrueVal">True</sys:Boolean>
  13. <sys:Boolean x:Key="FalseVal">False</sys:Boolean>
  14. <Style x:Key="FieldLabel" TargetType="TextBlock">
  15. <Setter Property="VerticalAlignment" Value="Center"/>
  16. <Setter Property="Margin" Value="0,0,8,0"/>
  17. <Setter Property="Foreground" Value="{DynamicResource SecondaryTextBrush}"/>
  18. </Style>
  19. <Style x:Key="FieldRow" TargetType="StackPanel">
  20. <Setter Property="Orientation" Value="Horizontal"/>
  21. <Setter Property="Margin" Value="0,4"/>
  22. </Style>
  23. <Style x:Key="EnumCombo" TargetType="ComboBox">
  24. <Setter Property="MinWidth" Value="160"/>
  25. <Setter Property="ItemTemplate">
  26. <Setter.Value>
  27. <DataTemplate>
  28. <TextBlock Text="{Binding Converter={StaticResource EnumDescConv}}"/>
  29. </DataTemplate>
  30. </Setter.Value>
  31. </Setter>
  32. </Style>
  33. </UserControl.Resources>
  34. <Grid Margin="24,16">
  35. <Grid.RowDefinitions>
  36. <RowDefinition Height="Auto"/>
  37. <RowDefinition Height="Auto"/>
  38. <RowDefinition Height="*"/>
  39. <RowDefinition Height="Auto"/>
  40. <RowDefinition Height="Auto"/>
  41. </Grid.RowDefinitions>
  42. <!-- 标题 + 选择已有标定 + 新建 -->
  43. <Grid Grid.Row="0" Margin="0,0,0,12">
  44. <Grid.ColumnDefinitions>
  45. <ColumnDefinition Width="Auto"/>
  46. <ColumnDefinition Width="*"/>
  47. <ColumnDefinition Width="Auto"/>
  48. </Grid.ColumnDefinitions>
  49. <TextBlock Grid.Column="0" Text="{loc:Translate '标定向导'}" FontSize="20" FontWeight="Bold"
  50. Foreground="{DynamicResource PrimaryTextBrush}" VerticalAlignment="Center"/>
  51. <StackPanel Grid.Column="1" Orientation="Horizontal" HorizontalAlignment="Right" VerticalAlignment="Center" Margin="0,0,12,0">
  52. <TextBlock Text="已有标定" Style="{StaticResource FieldLabel}"/>
  53. <ComboBox ItemsSource="{Binding Calibrations}" SelectedItem="{Binding SelectedCalibration}"
  54. DisplayMemberPath="Name" MinWidth="220"/>
  55. </StackPanel>
  56. <Button Grid.Column="2" Content="新建标定" Command="{Binding NewCommand}" VerticalAlignment="Center" Padding="16,6"/>
  57. </Grid>
  58. <!-- 步骤指示 -->
  59. <hc:StepBar Grid.Row="1" StepIndex="{Binding StepIndex, Mode=TwoWay}" Margin="0,0,0,16">
  60. <hc:StepBarItem Content="基础设置"/>
  61. <hc:StepBarItem Content="视觉与相机"/>
  62. <hc:StepBarItem Content="示教点位"/>
  63. <hc:StepBarItem Content="工具坐标"/>
  64. <hc:StepBarItem Content="九点标定"/>
  65. <hc:StepBarItem Content="验证"/>
  66. <hc:StepBarItem Content="完成"/>
  67. </hc:StepBar>
  68. <!-- 内容区 -->
  69. <Border Grid.Row="2" Background="{DynamicResource RegionBrush}" CornerRadius="8" Padding="20">
  70. <Grid>
  71. <!-- 步骤 0:基础设置 -->
  72. <ScrollViewer Visibility="{Binding StepIndex, Converter={StaticResource StepVisConv}, ConverterParameter=0}"
  73. VerticalScrollBarVisibility="Auto">
  74. <StackPanel MaxWidth="560" HorizontalAlignment="Left">
  75. <StackPanel Style="{StaticResource FieldRow}">
  76. <TextBlock Text="标定名称" Style="{StaticResource FieldLabel}" Width="96"/>
  77. <TextBox Text="{Binding Calib.Name, UpdateSourceTrigger=PropertyChanged}" MinWidth="240"/>
  78. </StackPanel>
  79. <StackPanel Style="{StaticResource FieldRow}">
  80. <TextBlock Text="机器人" Style="{StaticResource FieldLabel}" Width="96"/>
  81. <ComboBox ItemsSource="{Binding Robots}" SelectedItem="{Binding SelectedRobot}"
  82. DisplayMemberPath="RobotName" MinWidth="240"/>
  83. </StackPanel>
  84. <StackPanel Style="{StaticResource FieldRow}">
  85. <TextBlock Text="相机" Style="{StaticResource FieldLabel}" Width="96"/>
  86. <ComboBox ItemsSource="{Binding Cameras}" SelectedItem="{Binding SelectedCamera}"
  87. DisplayMemberPath="CameraName" MinWidth="240"/>
  88. </StackPanel>
  89. <StackPanel Style="{StaticResource FieldRow}">
  90. <TextBlock Text="相机安装方式" Style="{StaticResource FieldLabel}" Width="96"/>
  91. <ComboBox Style="{StaticResource EnumCombo}" ItemsSource="{Binding CameraMounts}"
  92. SelectedItem="{Binding Calib.CameraMount}"/>
  93. </StackPanel>
  94. <StackPanel Style="{StaticResource FieldRow}">
  95. <TextBlock Text="取料方式" Style="{StaticResource FieldLabel}" Width="96"/>
  96. <ComboBox Style="{StaticResource EnumCombo}" ItemsSource="{Binding PickModels}"
  97. SelectedItem="{Binding Calib.Pick.PickPlaceModel}"/>
  98. </StackPanel>
  99. <StackPanel Style="{StaticResource FieldRow}">
  100. <TextBlock Text="吸气/夹紧 IO" Style="{StaticResource FieldLabel}" Width="96"/>
  101. <TextBox Text="{Binding Calib.Pick.Inhal, UpdateSourceTrigger=PropertyChanged}" Width="70"/>
  102. <TextBlock Text="吹气/松开 IO" Style="{StaticResource FieldLabel}" Margin="16,0,8,0"/>
  103. <TextBox Text="{Binding Calib.Pick.Blow, UpdateSourceTrigger=PropertyChanged}" Width="70"/>
  104. </StackPanel>
  105. <StackPanel Style="{StaticResource FieldRow}">
  106. <TextBlock Text="速度 / 加速度" Style="{StaticResource FieldLabel}" Width="96"/>
  107. <TextBox Text="{Binding Calib.Speed, UpdateSourceTrigger=PropertyChanged}" Width="70"/>
  108. <TextBox Text="{Binding Calib.Accel, UpdateSourceTrigger=PropertyChanged}" Width="70" Margin="8,0,0,0"/>
  109. </StackPanel>
  110. <StackPanel Style="{StaticResource FieldRow}">
  111. <TextBlock Text="幅面 X / Y / U" Style="{StaticResource FieldLabel}" Width="96"/>
  112. <TextBox Text="{Binding Calib.Width, UpdateSourceTrigger=PropertyChanged}" Width="70"/>
  113. <TextBox Text="{Binding Calib.Height, UpdateSourceTrigger=PropertyChanged}" Width="70" Margin="8,0,0,0"/>
  114. <TextBox Text="{Binding Calib.Angle, UpdateSourceTrigger=PropertyChanged}" Width="70" Margin="8,0,0,0"/>
  115. </StackPanel>
  116. <StackPanel Style="{StaticResource FieldRow}">
  117. <TextBlock Text="吸真空/破真空/拍照延时(ms)" Style="{StaticResource FieldLabel}" Width="180"/>
  118. <TextBox Text="{Binding Calib.WaitSuction, UpdateSourceTrigger=PropertyChanged}" Width="60"/>
  119. <TextBox Text="{Binding Calib.WaitBlow, UpdateSourceTrigger=PropertyChanged}" Width="60" Margin="8,0,0,0"/>
  120. <TextBox Text="{Binding Calib.WaitPhoto, UpdateSourceTrigger=PropertyChanged}" Width="60" Margin="8,0,0,0"/>
  121. </StackPanel>
  122. </StackPanel>
  123. </ScrollViewer>
  124. <!-- 步骤 1:视觉与相机(仅相机测试:参数 + 测试拍照取点 + 选择视觉工具;九点标定页已移至第 5 步) -->
  125. <StackPanel Visibility="{Binding StepIndex, Converter={StaticResource StepVisConv}, ConverterParameter=1}" MaxWidth="560" HorizontalAlignment="Left">
  126. <StackPanel Style="{StaticResource FieldRow}">
  127. <TextBlock Text="曝光时间" Style="{StaticResource FieldLabel}" Width="72"/>
  128. <TextBox Text="{Binding Calib.ExposureTime, UpdateSourceTrigger=PropertyChanged}" Width="100"/>
  129. </StackPanel>
  130. <StackPanel Style="{StaticResource FieldRow}">
  131. <TextBlock Text="增益" Style="{StaticResource FieldLabel}" Width="72"/>
  132. <TextBox Text="{Binding Calib.Gain, UpdateSourceTrigger=PropertyChanged}" Width="100"/>
  133. </StackPanel>
  134. <StackPanel Style="{StaticResource FieldRow}">
  135. <TextBlock Text="光源亮度" Style="{StaticResource FieldLabel}" Width="72"/>
  136. <TextBox Text="{Binding Calib.Brightness, UpdateSourceTrigger=PropertyChanged}" Width="100"/>
  137. </StackPanel>
  138. <CheckBox Content="启用畸变校正" IsChecked="{Binding Calib.IsDistortionCorrection}" Margin="0,8"/>
  139. <Button Content="测试拍照取点" Command="{Binding TestCaptureCommand}" Margin="0,8" Padding="16,6"
  140. Style="{StaticResource ButtonPrimary}" HorizontalAlignment="Left"/>
  141. <Button Content="选择视觉标定工具(.vpp)" Command="{Binding LoadVisionToolCommand}" Margin="0,4" Padding="16,6" HorizontalAlignment="Left"/>
  142. <TextBlock Text="本步仅用于相机连通与取点测试(结果显示在下方状态栏);九点标定请进入第 5 步。" TextWrapping="Wrap"
  143. Foreground="{DynamicResource SecondaryTextBrush}" Margin="0,8,0,0"/>
  144. </StackPanel>
  145. <!-- 步骤 2:示教点位 -->
  146. <StackPanel Visibility="{Binding StepIndex, Converter={StaticResource StepVisConv}, ConverterParameter=2}" MaxWidth="640" HorizontalAlignment="Left">
  147. <StackPanel Style="{StaticResource FieldRow}">
  148. <TextBlock Text="P0 获取方式" Style="{StaticResource FieldLabel}" Width="96"/>
  149. <ComboBox Style="{StaticResource EnumCombo}" ItemsSource="{Binding P0Modes}"
  150. SelectedItem="{Binding Calib.CalibTechP0Mode}"/>
  151. </StackPanel>
  152. <StackPanel Style="{StaticResource FieldRow}">
  153. <Button Content="示教中心点" Command="{Binding TeachCenterCommand}" Padding="14,6" Margin="0,0,8,0"/>
  154. <TextBlock VerticalAlignment="Center">
  155. <Run Text="X="/><Run Text="{Binding Calib.CenterPoint.X, Mode=OneWay, StringFormat={}{0:F3}}"/>
  156. <Run Text=" Y="/><Run Text="{Binding Calib.CenterPoint.Y, Mode=OneWay, StringFormat={}{0:F3}}"/>
  157. <Run Text=" Z="/><Run Text="{Binding Calib.CenterPoint.Z, Mode=OneWay, StringFormat={}{0:F3}}"/>
  158. <Run Text=" U="/><Run Text="{Binding Calib.CenterPoint.U, Mode=OneWay, StringFormat={}{0:F3}}"/>
  159. </TextBlock>
  160. </StackPanel>
  161. <StackPanel Style="{StaticResource FieldRow}">
  162. <Button Content="示教待机点" Command="{Binding TeachHomeCommand}" Padding="14,6" Margin="0,0,8,0"/>
  163. <TextBlock VerticalAlignment="Center">
  164. <Run Text="X="/><Run Text="{Binding Calib.HomePoint.X, Mode=OneWay, StringFormat={}{0:F3}}"/>
  165. <Run Text=" Y="/><Run Text="{Binding Calib.HomePoint.Y, Mode=OneWay, StringFormat={}{0:F3}}"/>
  166. <Run Text=" Z="/><Run Text="{Binding Calib.HomePoint.Z, Mode=OneWay, StringFormat={}{0:F3}}"/>
  167. </TextBlock>
  168. </StackPanel>
  169. <StackPanel Style="{StaticResource FieldRow}">
  170. <Button Content="示教 Mark 点" Command="{Binding TeachMarkCommand}" Padding="14,6" Margin="0,0,8,0"/>
  171. <TextBlock VerticalAlignment="Center">
  172. <Run Text="X="/><Run Text="{Binding Calib.MarkPoint.X, Mode=OneWay, StringFormat={}{0:F3}}"/>
  173. <Run Text=" Y="/><Run Text="{Binding Calib.MarkPoint.Y, Mode=OneWay, StringFormat={}{0:F3}}"/>
  174. </TextBlock>
  175. </StackPanel>
  176. <StackPanel Style="{StaticResource FieldRow}">
  177. <TextBlock Text="夹爪/吸气测试" Style="{StaticResource FieldLabel}" Width="96"/>
  178. <Button Content="吸气/夹紧" Command="{Binding GripperCommand}" CommandParameter="{StaticResource TrueVal}" Padding="14,6" Margin="0,0,8,0"/>
  179. <Button Content="破真空/张开" Command="{Binding GripperCommand}" CommandParameter="{StaticResource FalseVal}" Padding="14,6"/>
  180. </StackPanel>
  181. </StackPanel>
  182. <!-- 步骤 3:工具坐标 TCP -->
  183. <StackPanel Visibility="{Binding StepIndex, Converter={StaticResource StepVisConv}, ConverterParameter=3}" MaxWidth="640" HorizontalAlignment="Left">
  184. <TextBlock TextWrapping="Wrap" Foreground="{DynamicResource SecondaryTextBrush}"
  185. Text="按相机安装方式标定工具坐标(TCP):固定向下/向上会提示摆放标定块并自动逼近中心;J4 随动模式自动求旋转中心。XY 模组无需此步(自动跳过)。"/>
  186. <Button Content="运行工具坐标标定" Command="{Binding RunTcpCommand}" Padding="16,6" Margin="0,12,0,0"
  187. Style="{StaticResource ButtonPrimary}" HorizontalAlignment="Left"/>
  188. <StackPanel Style="{StaticResource FieldRow}" Margin="0,12,0,0">
  189. <TextBlock Text="工具坐标 Tool" Style="{StaticResource FieldLabel}" Width="96"/>
  190. <TextBlock VerticalAlignment="Center">
  191. <Run Text="X="/><Run Text="{Binding Calib.Tool.X, Mode=OneWay, StringFormat={}{0:F3}}"/>
  192. <Run Text=" Y="/><Run Text="{Binding Calib.Tool.Y, Mode=OneWay, StringFormat={}{0:F3}}"/>
  193. </TextBlock>
  194. </StackPanel>
  195. </StackPanel>
  196. <!-- 步骤 4:九点标定(左:机器人自动九点标定 / 右:当前视觉引擎的手动标定页) -->
  197. <Grid Visibility="{Binding StepIndex, Converter={StaticResource StepVisConv}, ConverterParameter=4}">
  198. <Grid.ColumnDefinitions>
  199. <ColumnDefinition Width="360"/>
  200. <ColumnDefinition Width="*"/>
  201. </Grid.ColumnDefinitions>
  202. <StackPanel Grid.Column="0" Margin="0,0,16,0">
  203. <TextBlock TextWrapping="Wrap" Foreground="{DynamicResource SecondaryTextBrush}"
  204. Text="以中心点为原点生成 3x3 九点,机器人逐点运动+拍照,OpenCV 求像素→机器人仿射矩阵并计算精度。"/>
  205. <Button Content="运行九点标定" Command="{Binding RunNinePointCommand}" Padding="16,6" Margin="0,12,0,0"
  206. Style="{StaticResource ButtonPrimary}" HorizontalAlignment="Left"/>
  207. <StackPanel Style="{StaticResource FieldRow}" Margin="0,12,0,0">
  208. <TextBlock VerticalAlignment="Center" TextWrapping="Wrap">
  209. <Run Text="RMS="/><Run Text="{Binding Calib.CalibrationResult.RMS, Mode=OneWay, StringFormat={}{0:F4}}"/>
  210. <Run Text=" mm 最大误差="/><Run Text="{Binding Calib.CalibrationResult.MaxErrorValue, Mode=OneWay, StringFormat={}{0:F4}}"/>
  211. <Run Text=" mm 旋转="/><Run Text="{Binding Calib.CalibrationResult.Rotate, Mode=OneWay, StringFormat={}{0:F3}}"/>
  212. <Run Text="° ScaleX="/><Run Text="{Binding Calib.CalibrationResult.ScaleX, Mode=OneWay, StringFormat={}{0:F5}}"/>
  213. <Run Text=" ScaleY="/><Run Text="{Binding Calib.CalibrationResult.ScaleY, Mode=OneWay, StringFormat={}{0:F5}}"/>
  214. </TextBlock>
  215. </StackPanel>
  216. </StackPanel>
  217. <Border Grid.Column="1" BorderThickness="1" BorderBrush="{DynamicResource BorderBrush}" CornerRadius="6">
  218. <ContentControl Content="{Binding EngineCalibrationView}"/>
  219. </Border>
  220. </Grid>
  221. <!-- 步骤 5:验证 -->
  222. <StackPanel Visibility="{Binding StepIndex, Converter={StaticResource StepVisConv}, ConverterParameter=5}" MaxWidth="640" HorizontalAlignment="Left">
  223. <TextBlock TextWrapping="Wrap" Foreground="{DynamicResource SecondaryTextBrush}"
  224. Text="在 5 个验证点上复算误差,评估标定质量。"/>
  225. <Button Content="运行验证" Command="{Binding RunVerifyCommand}" Padding="16,6" Margin="0,12,0,0"
  226. Style="{StaticResource ButtonPrimary}" HorizontalAlignment="Left"/>
  227. <StackPanel Style="{StaticResource FieldRow}" Margin="0,12,0,0">
  228. <TextBlock VerticalAlignment="Center">
  229. <Run Text="RMSE X="/><Run Text="{Binding Calib.CalibrationTestResult.RMSEX, Mode=OneWay, StringFormat={}{0:F4}}"/>
  230. <Run Text=" mm RMSE Y="/><Run Text="{Binding Calib.CalibrationTestResult.RMSEY, Mode=OneWay, StringFormat={}{0:F4}}"/>
  231. <Run Text=" mm"/>
  232. </TextBlock>
  233. </StackPanel>
  234. </StackPanel>
  235. <!-- 步骤 6:完成 -->
  236. <StackPanel Visibility="{Binding StepIndex, Converter={StaticResource StepVisConv}, ConverterParameter=6}" MaxWidth="640" HorizontalAlignment="Left">
  237. <TextBlock TextWrapping="Wrap" Foreground="{DynamicResource SecondaryTextBrush}"
  238. Text="保存标定配置(含视觉工具引用)到 Runtime\Calibration,供运行时像素→机器人坐标换算使用。"/>
  239. <Button Content="保存标定" Command="{Binding SaveCommand}" Padding="16,6" Margin="0,12,0,0"
  240. Style="{StaticResource ButtonPrimary}" HorizontalAlignment="Left"/>
  241. <StackPanel Style="{StaticResource FieldRow}" Margin="0,12,0,0">
  242. <TextBlock Text="名称" Style="{StaticResource FieldLabel}" Width="48"/>
  243. <TextBlock Text="{Binding Calib.Name}" VerticalAlignment="Center"/>
  244. </StackPanel>
  245. </StackPanel>
  246. </Grid>
  247. </Border>
  248. <!-- 状态栏 -->
  249. <Border Grid.Row="3" Background="{DynamicResource SecondaryRegionBrush}" CornerRadius="6" Padding="12,8" Margin="0,12,0,0">
  250. <StackPanel Orientation="Horizontal">
  251. <TextBlock Text="执行中…" VerticalAlignment="Center" Margin="0,0,8,0" FontWeight="Bold"
  252. Foreground="{DynamicResource PrimaryTextBrush}"
  253. Visibility="{Binding IsBusy, Converter={StaticResource BoolToVis}}"/>
  254. <TextBlock Text="{Binding StatusText}" VerticalAlignment="Center" TextWrapping="Wrap"
  255. Foreground="{DynamicResource PrimaryTextBrush}"/>
  256. </StackPanel>
  257. </Border>
  258. <!-- 导航 -->
  259. <StackPanel Grid.Row="4" Orientation="Horizontal" HorizontalAlignment="Center" Margin="0,12,0,0">
  260. <Button Content="上一步" Command="{Binding BackCommand}" Padding="24,8" Margin="0,0,12,0"/>
  261. <Button Content="下一步" Command="{Binding NextCommand}" Style="{StaticResource ButtonPrimary}" Padding="24,8"/>
  262. </StackPanel>
  263. </Grid>
  264. </UserControl>