Przeglądaj źródła

新增机器人SafeZ安全高度属性及界面配置

为各机器人类、接口和模型增加SafeZ属性,并在设置界面支持Z轴安全高度的输入与保存。运动相关服务调用时支持自动使用SafeZ,提升操作安全性和灵活性。
孝锋 徐 7 miesięcy temu
rodzic
commit
4be556927d

+ 10 - 0
TeamAAS-VM/Core/Robots/EpsonRobot.cs

@@ -193,6 +193,16 @@ namespace TeamAAS_VP.Core.Robots
             get { return _CurrentPosition; }
             set { SetProperty(ref _CurrentPosition, value); }
         }
+
+        private double _SafeZ;
+        /// <summary>
+        /// Z轴的安全高度
+        /// </summary>
+        public double SafeZ
+        {
+            get { return _SafeZ; }
+            set { SetProperty(ref _SafeZ, value); }
+        }
         #endregion
 
         #region 事件接收

+ 10 - 0
TeamAAS-VM/Core/Robots/FanucRobot.cs

@@ -197,6 +197,16 @@ namespace TeamAAS_VP.Core.Robots
             get { return _CurrentPosition; }
             set { SetProperty(ref _CurrentPosition, value); }
         }
+
+        private double _SafeZ;
+        /// <summary>
+        /// Z轴的安全高度
+        /// </summary>
+        public double SafeZ
+        {
+            get { return _SafeZ; }
+            set { SetProperty(ref _SafeZ, value); }
+        }
         #endregion
 
         #region 事件接收

+ 10 - 0
TeamAAS-VM/Core/Robots/SchneiderRobot.cs

@@ -192,6 +192,16 @@ namespace TeamAAS_VP.Core.Robots
             get { return _CurrentPosition; }
             set { SetProperty(ref _CurrentPosition, value); }
         }
+
+        private double _SafeZ;
+        /// <summary>
+        /// Z轴的安全高度
+        /// </summary>
+        public double SafeZ
+        {
+            get { return _SafeZ; }
+            set { SetProperty(ref _SafeZ, value); }
+        }
         #endregion
 
         #region 事件接收

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

@@ -46,6 +46,7 @@ namespace TeamAAS_VP.Core.Robots
             Terminator = robot.Terminator;
             DataEncoding = robot.DataEncoding;
             Brand = RobotBrand.XYZ_Platform;
+            SafeZ = robot.SafeZ;
             Plc = pLC;
             Plc.ConnectChangedEvent += Plc_ConnectChangedEvent;
 
@@ -208,6 +209,15 @@ namespace TeamAAS_VP.Core.Robots
             set { SetProperty(ref _CurrentPosition, value); }
         }
 
+        private double _SafeZ;
+        /// <summary>
+        /// Z轴的安全高度
+        /// </summary>
+        public double SafeZ
+        {
+            get { return _SafeZ; }
+            set { SetProperty(ref _SafeZ, value); }
+        }
         #endregion
 
         #region 连接
@@ -430,6 +440,11 @@ namespace TeamAAS_VP.Core.Robots
                 currentPos.Z = (float)LimZ.Value;
                 if (!Go(currentPos)) return false;
             }
+            else
+            {
+                currentPos.Z = (float)SafeZ;
+                if (!Go(currentPos)) return false;
+            }
             //再XYU轴到位
             currentPos.X = position.X;
             currentPos.Y = position.Y;

+ 5 - 0
TeamAAS-VM/Interfaces/IRobot.cs

@@ -76,6 +76,11 @@ namespace TeamAAS_VP.Interfaces
         //当前位置
         RPoint CurrentPosition { get; }
 
+        /// <summary>
+        /// Z轴的安全高度
+        /// </summary>
+        double SafeZ { get; set; }
+
         #endregion
 
         #region 连接通讯

+ 10 - 0
TeamAAS-VM/Models/Robot/RobotInfo.cs

@@ -114,6 +114,16 @@ namespace TeamAAS_VP.Models
             set { SetProperty(ref _StepDistance, value); }
         }
 
+        private double _SafeZ;
+        /// <summary>
+        /// Z轴的安全高度
+        /// </summary>
+        public double SafeZ
+        {
+            get { return _SafeZ; }
+            set { SetProperty(ref _SafeZ, value); }
+        }
+
         private Guid _PLC;
         /// <summary>
         /// 对应的PLC

+ 34 - 34
TeamAAS-VM/Services/CameraCalibrationService.cs

@@ -62,7 +62,7 @@ namespace TeamAAS_VP.Services
             Matrix<double> RobotCameraRotationMatrix = null;
 
             //移动机器人至待机位置
-            bool isSuccess = await robot.CalibMotionAsync(calibrationInfo.HomePoint, 0);
+            bool isSuccess = await robot.CalibMotionAsync(calibrationInfo.HomePoint, null);
             if (!isSuccess)
             {
                 return (false, null, 0, 0, 0, 0);
@@ -112,7 +112,7 @@ namespace TeamAAS_VP.Services
             RPoint RobotU = calibrationInfo.CenterPoint.Clone();
             RobotU.U += (float)calibrationInfo.Angle;
             //移动机器人中心点
-            isSuccess = await robot.CalibMotionAsync(calibrationInfo.CenterPoint, 0);
+            isSuccess = await robot.CalibMotionAsync(calibrationInfo.CenterPoint, null);
             if (!isSuccess)
             {
                 return (false, null, 0, 0, 0, 0);
@@ -125,7 +125,7 @@ namespace TeamAAS_VP.Services
             await robot.CalibOutIOAsync(true);
 
             //机器人U轴旋转
-            isSuccess = await robot.CalibMotionAsync(RobotU, 0);
+            isSuccess = await robot.CalibMotionAsync(RobotU, null);
             if (!isSuccess)
             {
                 return (false, null, 0, 0, 0, 0);
@@ -138,7 +138,7 @@ namespace TeamAAS_VP.Services
             //关闭吸气
             await robot.CalibOutIOAsync(false);
             //移动机器人至待机位置
-            isSuccess = await robot.CalibMotionAsync(calibrationInfo.HomePoint, 0);
+            isSuccess = await robot.CalibMotionAsync(calibrationInfo.HomePoint, null);
             if (!isSuccess)
             {
                 return (false, null, 0, 0, 0, 0);
@@ -164,7 +164,7 @@ namespace TeamAAS_VP.Services
                 double offsety = (P0.Y - curPixel.Y) * pixelScaleY;
                 var pos = RobotCameraRotationMatrix.Inverse() * Vector<double>.Build.Dense(new double[] { offsetx, offsety });
                 //移动机器人取标定块
-                isSuccess = await robot.CalibMotionAsync(RobotU, 0);
+                isSuccess = await robot.CalibMotionAsync(RobotU, null);
                 if (!isSuccess)
                 {
                     return (false, null, 0, 0, 0, 0);
@@ -179,7 +179,7 @@ namespace TeamAAS_VP.Services
                 RobotU.X += (float)pos[0];
                 RobotU.Y += (float)pos[1];
                 //机器人移动
-                isSuccess = await robot.CalibMotionAsync(RobotU, 0);
+                isSuccess = await robot.CalibMotionAsync(RobotU, null);
                 if (!isSuccess)
                 {
                     return (false, null, 0, 0, 0, 0);
@@ -192,7 +192,7 @@ namespace TeamAAS_VP.Services
                 //关闭吸气
                 await robot.CalibOutIOAsync(false);
                 //移动机器人至待机位置
-                isSuccess = await robot.CalibMotionAsync(calibrationInfo.HomePoint, 0);
+                isSuccess = await robot.CalibMotionAsync(calibrationInfo.HomePoint, null);
                 if (!isSuccess)
                 {
                     return (false, null, 0, 0, 0, 0);
@@ -214,7 +214,7 @@ namespace TeamAAS_VP.Services
                 if (Math.Abs(offsetx) < 1 && Math.Abs(offsetx) < 1)
                 {
                     //移动机器人取标定块
-                    isSuccess = await robot.CalibMotionAsync(RobotU, 0);
+                    isSuccess = await robot.CalibMotionAsync(RobotU, null);
                     if (!isSuccess)
                     {
                         return (false, null, 0, 0, 0, 0);
@@ -226,7 +226,7 @@ namespace TeamAAS_VP.Services
                     //打开吸气
                     await robot.CalibOutIOAsync(true);
                     //移动机器人至待机位置
-                    isSuccess = await robot.CalibMotionAsync(calibrationInfo.HomePoint, 0);
+                    isSuccess = await robot.CalibMotionAsync(calibrationInfo.HomePoint, null);
                     if (!isSuccess)
                     {
                         return (false, null, 0, 0, 0, 0);
@@ -282,7 +282,7 @@ namespace TeamAAS_VP.Services
             Matrix<double> RobotCameraRotationMatrix = null;
 
             //移动机器人至中心位置
-            bool isSuccess = await robot.CalibMotionAsync(calibrationInfo.CenterPoint, 0);
+            bool isSuccess = await robot.CalibMotionAsync(calibrationInfo.CenterPoint, null);
             if (!isSuccess)
             {
                 return (false, null, 0, 0, 0, 0);
@@ -374,7 +374,7 @@ namespace TeamAAS_VP.Services
             Matrix<double> RobotCameraRotationMatrix = null;
 
             //移动机器人至中心位置
-            bool isSuccess = await robot.CalibMotionAsync(calibrationInfo.CenterPoint, 0);
+            bool isSuccess = await robot.CalibMotionAsync(calibrationInfo.CenterPoint, null);
             if (!isSuccess)
             {
                 return (false, null, 0, 0, 0, 0);
@@ -544,7 +544,7 @@ namespace TeamAAS_VP.Services
             bool isSuccess = false;
             if (calibrationInfo.CameraMount == Enums.CameraMount.FixedDown)
             {
-                isSuccess = await robot.CalibMotionAsync(calibrationInfo.CenterPoint, 0);
+                isSuccess = await robot.CalibMotionAsync(calibrationInfo.CenterPoint, null);
                 if (!isSuccess)
                 {
                     return (false, null, 0, 0);
@@ -571,7 +571,7 @@ namespace TeamAAS_VP.Services
             if (calibrationInfo.CameraMount == Enums.CameraMount.FixedDown)
             {
                 //移动机器人至待机位置
-                isSuccess = await robot.CalibMotionAsync(calibrationInfo.HomePoint, 0);
+                isSuccess = await robot.CalibMotionAsync(calibrationInfo.HomePoint, null);
                 if (!isSuccess)
                 {
                     return (false, null, 0, 0);
@@ -590,7 +590,7 @@ namespace TeamAAS_VP.Services
             if (calibrationInfo.CameraMount == Enums.CameraMount.FixedDown)
             {
                 //移动机器人至P0
-                isSuccess = await robot.CalibMotionAsync(RobotP0, 0);
+                isSuccess = await robot.CalibMotionAsync(RobotP0, null);
                 if (!isSuccess)
                 {
                     return (false, null, 0, 0);
@@ -602,7 +602,7 @@ namespace TeamAAS_VP.Services
                 //打开吸气
                 await robot.CalibOutIOAsync(true);
                 //移动机器人至P1
-                isSuccess = await robot.CalibMotionAsync(RobotP1, 0);
+                isSuccess = await robot.CalibMotionAsync(RobotP1, null);
                 if (!isSuccess)
                 {
                     return (false, null, 0, 0);
@@ -614,7 +614,7 @@ namespace TeamAAS_VP.Services
                 //关闭吸气
                 await robot.CalibOutIOAsync(false);
                 //移动机器人至待机位置
-                isSuccess = await robot.CalibMotionAsync(calibrationInfo.HomePoint, 0);
+                isSuccess = await robot.CalibMotionAsync(calibrationInfo.HomePoint, null);
                 if (!isSuccess)
                 {
                     return (false, null, 0, 0);
@@ -647,7 +647,7 @@ namespace TeamAAS_VP.Services
             if (calibrationInfo.CameraMount == Enums.CameraMount.FixedDown)
             {
                 //移动机器人至P1
-                isSuccess = await robot.CalibMotionAsync(RobotP1, 0);
+                isSuccess = await robot.CalibMotionAsync(RobotP1, null);
                 if (!isSuccess)
                 {
                     return (false, null, 0, 0);
@@ -659,7 +659,7 @@ namespace TeamAAS_VP.Services
                 //打开吸气
                 await robot.CalibOutIOAsync(true);
                 //移动机器人至P2
-                isSuccess = await robot.CalibMotionAsync(RobotP2, 0);
+                isSuccess = await robot.CalibMotionAsync(RobotP2, null);
                 if (!isSuccess)
                 {
                     return (false, null, 0, 0);
@@ -671,7 +671,7 @@ namespace TeamAAS_VP.Services
                 //关闭吸气
                 await robot.CalibOutIOAsync(false);
                 //移动机器人至待机位置
-                isSuccess = await robot.CalibMotionAsync(calibrationInfo.HomePoint, 0);
+                isSuccess = await robot.CalibMotionAsync(calibrationInfo.HomePoint, null);
                 if (!isSuccess)
                 {
                     return (false, null, 0, 0);
@@ -704,7 +704,7 @@ namespace TeamAAS_VP.Services
             if (calibrationInfo.CameraMount == Enums.CameraMount.FixedDown)
             {
                 //移动机器人至P2
-                isSuccess = await robot.CalibMotionAsync(RobotP2, 0);
+                isSuccess = await robot.CalibMotionAsync(RobotP2, null);
                 if (!isSuccess)
                 {
                     return (false, null, 0, 0);
@@ -716,7 +716,7 @@ namespace TeamAAS_VP.Services
                 //打开吸气
                 await robot.CalibOutIOAsync(true);
                 //移动机器人至P0
-                isSuccess = await robot.CalibMotionAsync(RobotP0, 0);
+                isSuccess = await robot.CalibMotionAsync(RobotP0, null);
                 if (!isSuccess)
                 {
                     return (false, null, 0, 0);
@@ -728,7 +728,7 @@ namespace TeamAAS_VP.Services
                 //关闭吸气
                 await robot.CalibOutIOAsync(false);
                 //移动机器人至待机位置
-                isSuccess = await robot.CalibMotionAsync(calibrationInfo.HomePoint, 0);
+                isSuccess = await robot.CalibMotionAsync(calibrationInfo.HomePoint, null);
                 if (!isSuccess)
                 {
                     return (false, null, 0, 0);
@@ -902,7 +902,7 @@ namespace TeamAAS_VP.Services
             {
 
                 //移动机器人至中心位置
-                isSuccess=await robot.CalibMotionAsync(calibrationInfo.CenterPoint, 0);
+                isSuccess = await robot.CalibMotionAsync(calibrationInfo.CenterPoint, null);
                 if (!isSuccess)
                 {
                     return (false, null, null, null);
@@ -1088,7 +1088,7 @@ namespace TeamAAS_VP.Services
             if (calibrationInfo.CameraMount == Enums.CameraMount.MobileJ4)
             {
                 //移动机器人至中心位置
-                isSuccess= await robot.CalibMotionAsync(calibrationInfo.CenterPoint, 0);
+                isSuccess = await robot.CalibMotionAsync(calibrationInfo.CenterPoint, null);
                 if (!isSuccess)
                 {
                     return (false, null, null, null);
@@ -1118,7 +1118,7 @@ namespace TeamAAS_VP.Services
                 //移动机器人至i
                 if (calibrationInfo.CameraMount == Enums.CameraMount.FixedDown)
                 {
-                    isSuccess= await robot.CalibMotionAsync(rPoints[i], 0);
+                    isSuccess = await robot.CalibMotionAsync(rPoints[i], null);
                     if (!isSuccess)
                     {
                         return (false, null, null, null);
@@ -1130,7 +1130,7 @@ namespace TeamAAS_VP.Services
                     //关闭吸气
                     await robot.CalibOutIOAsync(false);
                     //移动机器人至待机位置
-                    isSuccess= await robot.CalibMotionAsync(calibrationInfo.HomePoint, 0);
+                    isSuccess = await robot.CalibMotionAsync(calibrationInfo.HomePoint, null);
                     if (!isSuccess)
                     {
                         return (false, null, null, null);
@@ -1138,7 +1138,7 @@ namespace TeamAAS_VP.Services
                 }
                 else
                 {
-                    isSuccess= await robot.CalibMotionAsync(rPoints[i], rPoints[i].Z);
+                    isSuccess = await robot.CalibMotionAsync(rPoints[i], rPoints[i].Z);
                     if (!isSuccess)
                     {
                         return (false, null, null, null);
@@ -1161,7 +1161,7 @@ namespace TeamAAS_VP.Services
                 if (calibrationInfo.CameraMount == Enums.CameraMount.FixedDown)
                 {
                     //移动机器人至i
-                    isSuccess= await robot.CalibMotionAsync(rPoints[i], 0);
+                    isSuccess = await robot.CalibMotionAsync(rPoints[i], null);
                     if (!isSuccess)
                     {
                         return (false, null, null, null);
@@ -1188,7 +1188,7 @@ namespace TeamAAS_VP.Services
             if (calibrationInfo.CameraMount == Enums.CameraMount.FixedDown)
             {
                 //移动机器人至待机位置
-                isSuccess = await robot.CalibMotionAsync(calibrationInfo.HomePoint, 0);
+                isSuccess = await robot.CalibMotionAsync(calibrationInfo.HomePoint, null);
                 if (!isSuccess)
                 {
                     return (false, null, null, null);
@@ -1437,7 +1437,7 @@ namespace TeamAAS_VP.Services
                 if (calibrationInfo.CameraMount == Enums.CameraMount.FixedDown)
                 {
                     //移动机器人至i
-                    isSuccess= await robot.CalibMotionAsync(rPoints[i], 0);
+                    isSuccess = await robot.CalibMotionAsync(rPoints[i], null);
                     if (!isSuccess)
                     {
                         return (false, null);
@@ -1449,7 +1449,7 @@ namespace TeamAAS_VP.Services
                     //关闭吸气
                     await robot.CalibOutIOAsync(false);
                     //移动机器人至待机位置
-                    isSuccess= await robot.CalibMotionAsync(calibrationInfo.HomePoint, 0);
+                    isSuccess = await robot.CalibMotionAsync(calibrationInfo.HomePoint, null);
                     if (!isSuccess)
                     {
                         return (false, null);
@@ -1458,7 +1458,7 @@ namespace TeamAAS_VP.Services
                 else
                 {
                     //移动机器人至i
-                     isSuccess = await robot.CalibMotionAsync(rPoints[i], rPoints[i].Z);
+                    isSuccess = await robot.CalibMotionAsync(rPoints[i], rPoints[i].Z);
                     if (!isSuccess)
                     {
                         return (false, null);
@@ -1483,7 +1483,7 @@ namespace TeamAAS_VP.Services
                 if (calibrationInfo.CameraMount == Enums.CameraMount.FixedDown)
                 {
                     //移动机器人至i
-                    isSuccess = await robot.CalibMotionAsync(rPoints[i], 0);
+                    isSuccess = await robot.CalibMotionAsync(rPoints[i], null);
                     if (!isSuccess)
                     {
                         return (false, null);
@@ -1501,7 +1501,7 @@ namespace TeamAAS_VP.Services
             if (calibrationInfo.CameraMount == Enums.CameraMount.FixedDown)
             {
                 //移动机器人至待机位置
-                isSuccess= await robot.CalibMotionAsync(calibrationInfo.HomePoint, 0);
+                isSuccess = await robot.CalibMotionAsync(calibrationInfo.HomePoint, null);
                 if (!isSuccess)
                 {
                     return (false, null);

+ 28 - 22
TeamAAS-VM/ViewModels/Product/VisionDynamicAccuracyAnalyzerViewModel.cs

@@ -1034,28 +1034,28 @@ namespace TeamAAS_VP.ViewModels.Product
                 try
                 {
                     // 1. 采集图像
-                    //bool succed = Camera.SetExposureTime(SelectProcedure.ExposureTime);
-                    //if (!succed)
-                    //{
-                    //    SendTaskMessage(Lang.相机曝光设置失败);
-                    //}
-                    //succed = Camera.SetGain(SelectProcedure.Gain);
-                    //if (!succed)
-                    //{
-                    //    SendTaskMessage(Lang.相机增益设置失败);
-                    //}
-                    //DateTime nowtime = DateTime.Now;
-                    //LogHelper.WriteLogInfo(Lang.开始采集图像);
-                    //var image = Camera.Grab();
-                    //if (image == null)
-                    //{
+                    bool succed = Camera.SetExposureTime(SelectProcedure.ExposureTime);
+                    if (!succed)
+                    {
+                        SendTaskMessage(Lang.相机曝光设置失败);
+                    }
+                    succed = Camera.SetGain(SelectProcedure.Gain);
+                    if (!succed)
+                    {
+                        SendTaskMessage(Lang.相机增益设置失败);
+                    }
+                    DateTime nowtime = DateTime.Now;
+                    LogHelper.WriteLogInfo(Lang.开始采集图像);
+                    var image = Camera.Grab();
+                    if (image == null)
+                    {
 
-                    //    SendTaskMessage(Lang.图像采集失败);
-                    //    outputCollection = null;
-                    //    return (false, result.ToArray());
-                    //}
+                        SendTaskMessage(Lang.图像采集失败);
+                        outputCollection = null;
+                        return (false, 0d, 0d, 0d, 0d, 0d);
+                    }
                     //Image = image;
-                    //VisionTool.Inputs["InputImage"].Value = image;
+                    VisionTool.Inputs["InputImage"].Value = image;
                     //LogHelper.WriteLogInfo(string.Format(Lang.采集图像完成用时0ms, (DateTime.Now - nowtime).Milliseconds));
 
                     // 2. 为ToolBlock传入其他输入终端
@@ -1103,8 +1103,7 @@ namespace TeamAAS_VP.ViewModels.Product
                         //SendTaskMessage(Lang.拍照OK, MessageLevel.Debug);
 
                         // 3. 获取视觉输出结果
-                        //获取相机校准
-                        var calib = _calibrationService.GetCalibration(SelectProcedure.CalibrationId);
+                        
                         string points = (string)(outputCollection["Point"].Value);
                         string[] strpoints = points.Split(';');
                         //先将pos按照逗号进行分隔,拿到数组
@@ -1113,6 +1112,13 @@ namespace TeamAAS_VP.ViewModels.Product
                         double _pixel_y = double.Parse(posParts[1]);
                         double _pixel_u = double.Parse(posParts[2]);
 
+                        //获取相机校准
+                        var calib = _calibrationService.GetCalibration(SelectProcedure.CalibrationId);
+                        if (calib == null)
+                        {
+                            return (true, _pixel_x, _pixel_y, _pixel_u, 0, 0); ;
+                        }
+
                         //获取机器人当前坐标系
                         RPoint rPoint = Robot.GetRobotPos();
                         double[] point = new double[2];

+ 6 - 0
TeamAAS-VM/ViewModels/SettingViewModel.cs

@@ -507,6 +507,12 @@ namespace TeamAAS_VP.ViewModels
                 {
                     foreach (var item in RobotList)
                     {
+                        var robot = _robotService.GetRobot(item.Id);
+                        if (robot != null)
+                        {
+                            //更新连接参数
+                            robot.SafeZ=item.SafeZ;
+                        }
                         _configService.AddOrUpdateRobot(item);
                     }
                     _eventAggregator.GetEvent<SnackbarMessageNotification>().Publish(new MessageParameter() { Msg = Lang.完成, Duration = 1 });

+ 27 - 0
TeamAAS-VM/Views/SettingView.xaml

@@ -354,6 +354,7 @@
                                 <RowDefinition />
                                 <RowDefinition />
                                 <RowDefinition />
+                                <RowDefinition />
                             </Grid.RowDefinitions>
                             <Grid.ColumnDefinitions>
                                 <ColumnDefinition Width="auto" />
@@ -540,6 +541,32 @@
                                       HorizontalAlignment="Left"
                                       VerticalAlignment="Center"
                                       Visibility="{Binding SelectRobot.RobotBrand,Converter={StaticResource RobotBrandToVisibiltyConverter}}" />
+                            <!--Z轴的安全高度-->
+                            <TextBlock Grid.Row="8"
+                                       Grid.Column="0"
+                                       Text="Z轴的安全高度: "
+                                       Style="{StaticResource MaterialDesignSubtitle1TextBlock}"
+                                       FontSize="{DynamicResource Font.Size.Body3}"
+                                       HorizontalAlignment="Right"
+                                       VerticalAlignment="Center" />
+                            <TextBox Text="{Binding SelectRobot.SafeZ,Mode=TwoWay}"
+                                     Grid.Row="8"
+                                     Grid.Column="1"
+                                     Margin="10,0"
+                                     Width="{Binding ElementName=txt_Id,Path=ActualWidth}"
+                                     MinWidth="80"
+                                     FontSize="{DynamicResource Font.Size.Body3}"
+                                     HorizontalContentAlignment="Center"
+                                     HorizontalAlignment="Left"
+                                     VerticalAlignment="Center" />
+                            <TextBlock Grid.Row="8"
+                                       Grid.Column="1"
+                                       Text="mm"
+                                       Style="{StaticResource MaterialDesignSubtitle1TextBlock}"
+                                       FontSize="{DynamicResource Font.Size.Body3}"
+                                       HorizontalAlignment="Right"
+                                       VerticalAlignment="Center"
+                                       Margin="0,0,-20,0" />
                             <!--PLC-->
                             <TextBlock Grid.Row="3"
                                        Grid.Column="0"