Переглянути джерело

产品参数扩展及标定服务健壮性提升

新增独立相机流程配置字段及界面控件,支持多相机多流程场景。优化产品参数保存逻辑,未选流程自动重置为 Guid.Empty。标定服务所有机器人运动步骤增加返回值判断,失败时及时中断,提升容错性。修正部分变量命名和注释,增强代码可读性和健壮性。
孝锋 徐 8 місяців тому
батько
коміт
1b4ddb7282

+ 80 - 0
TeamAAS-VM/Models/Product/ProductModel.cs

@@ -236,6 +236,86 @@ namespace TeamAAS_VP.Models
             set { SetProperty(ref _MoveDownCamer2PickPhotoProcedureId, value); }
         }
 
+        private Guid _IndependentCamer1ProductProcedureId;
+        /// <summary>
+        /// 独立移动模组相机1产品定位拍照流程ID
+        /// </summary>
+        public Guid IndependentCamer1ProductProcedureId
+        {
+            get { return _IndependentCamer1ProductProcedureId; }
+            set { SetProperty(ref _IndependentCamer1ProductProcedureId, value); }
+        }
+
+        private Guid _IndependentCamer2ProductProcedureId;
+        /// <summary>
+        /// 独立移动模组相机2产品定位拍照流程ID
+        /// </summary>
+        public Guid IndependentCamer2ProductProcedureId
+        {
+            get { return _IndependentCamer2ProductProcedureId; }
+            set { SetProperty(ref _IndependentCamer2ProductProcedureId, value); }
+        }
+
+        private Guid _IndependentCamer3ProductProcedureId;
+        /// <summary>
+        /// 独立移动模组相机3产品定位拍照流程ID
+        /// </summary>
+        public Guid IndependentCamer3ProductProcedureId
+        {
+            get { return _IndependentCamer3ProductProcedureId; }
+            set { SetProperty(ref _IndependentCamer3ProductProcedureId, value); }
+        }
+
+        private Guid _IndependentCamer4ProductProcedureId;
+        /// <summary>
+        /// 独立移动模组相机4产品定位拍照流程ID
+        /// </summary>
+        public Guid IndependentCamer4ProductProcedureId
+        {
+            get { return _IndependentCamer4ProductProcedureId; }
+            set { SetProperty(ref _IndependentCamer4ProductProcedureId, value); }
+        }
+
+        private Guid _IndependentCamer1AuxProcedureId;
+        /// <summary>
+        /// 独立移动模组相机1辅料定位拍照流程ID
+        /// </summary>
+        public Guid IndependentCamer1AuxProcedureId
+        {
+            get { return _IndependentCamer1AuxProcedureId; }
+            set { SetProperty(ref _IndependentCamer1AuxProcedureId, value); }
+        }
+
+        private Guid _IndependentCamer2AuxProcedureId;
+        /// <summary>
+        /// 独立移动模组相机2辅料定位拍照流程ID
+        /// </summary>
+        public Guid IndependentCamer2AuxProcedureId
+        {
+            get { return _IndependentCamer2AuxProcedureId; }
+            set { SetProperty(ref _IndependentCamer2AuxProcedureId, value); }
+        }
+
+        private Guid _IndependentCamer3AuxProcedureId;
+        /// <summary>
+        /// 独立移动模组相机3辅料定位拍照流程ID
+        /// </summary>
+        public Guid IndependentCamer3AuxProcedureId
+        {
+            get { return _IndependentCamer3AuxProcedureId; }
+            set { SetProperty(ref _IndependentCamer3AuxProcedureId, value); }
+        }
+
+        private Guid _IndependentCamer4AuxProcedureId;
+        /// <summary>
+        /// 独立移动模组相机4辅料定位拍照流程ID
+        /// </summary>
+        public Guid IndependentCamer4AuxProcedureId
+        {
+            get { return _IndependentCamer2AuxProcedureId; }
+            set { SetProperty(ref _IndependentCamer4AuxProcedureId, value); }
+        }
+
         /// <summary>
         /// 移动向上的相机模板角度
         /// </summary>

+ 159 - 55
TeamAAS-VM/Services/CameraCalibrationService.cs

@@ -62,7 +62,11 @@ namespace TeamAAS_VP.Services
             Matrix<double> RobotCameraRotationMatrix = null;
 
             //移动机器人至待机位置
-            await robot.CalibMotionAsync(calibrationInfo.HomePoint, null);
+            bool isSuccess = await robot.CalibMotionAsync(calibrationInfo.HomePoint, null);
+            if (!isSuccess)
+            {
+                return (false, null, 0, 0, 0, 0);
+            }
             if (cancellationToken.IsCancellationRequested)
             {
                 return (false, null, 0, 0, 0, 0);
@@ -109,7 +113,11 @@ namespace TeamAAS_VP.Services
             RPoint RobotU = calibrationInfo.CenterPoint.Clone();
             RobotU.U += (float)calibrationInfo.Angle;
             //移动机器人中心点
-            await robot.CalibMotionAsync(calibrationInfo.CenterPoint, null);
+            isSuccess=await robot.CalibMotionAsync(calibrationInfo.CenterPoint, null);
+            if (!isSuccess)
+            {
+                return (false, null, 0, 0, 0, 0);
+            }
             if (cancellationToken.IsCancellationRequested)
             {
                 return (false, null, 0, 0, 0, 0);
@@ -118,7 +126,11 @@ namespace TeamAAS_VP.Services
             await robot.CalibOutIOAsync(true);
 
             //机器人U轴旋转
-            await robot.CalibMotionAsync(RobotU, null);
+            isSuccess= await robot.CalibMotionAsync(RobotU, null);
+            if (!isSuccess)
+            {
+                return (false, null, 0, 0, 0, 0);
+            }
             if (cancellationToken.IsCancellationRequested)
             {
                 return (false, null, 0, 0, 0, 0);
@@ -127,7 +139,11 @@ namespace TeamAAS_VP.Services
             //关闭吸气
             await robot.CalibOutIOAsync(false);
             //移动机器人至待机位置
-            await robot.CalibMotionAsync(calibrationInfo.HomePoint, null);
+            isSuccess= await robot.CalibMotionAsync(calibrationInfo.HomePoint, null);
+            if (!isSuccess)
+            {
+                return (false, null, 0, 0, 0, 0);
+            }
             if (cancellationToken.IsCancellationRequested)
             {
                 return (false, null, 0, 0, 0, 0);
@@ -149,7 +165,11 @@ namespace TeamAAS_VP.Services
                 double offsety = (P0.Y - curPixel.Y) * pixelScaleY;
                 var pos = RobotCameraRotationMatrix.Inverse() * Vector<double>.Build.Dense(new double[] { offsetx, offsety });
                 //移动机器人取标定块
-                await robot.CalibMotionAsync(RobotU, null);
+                isSuccess= await robot.CalibMotionAsync(RobotU, null);
+                if (!isSuccess)
+                {
+                    return (false, null, 0, 0, 0, 0);
+                }
                 if (cancellationToken.IsCancellationRequested)
                 {
                     return (false, null, 0, 0, 0, 0);
@@ -160,7 +180,11 @@ namespace TeamAAS_VP.Services
                 RobotU.X += (float)pos[0];
                 RobotU.Y += (float)pos[1];
                 //机器人移动
-                await robot.CalibMotionAsync(RobotU, null);
+                isSuccess= await robot.CalibMotionAsync(RobotU, null);
+                if (!isSuccess)
+                {
+                    return (false, null, 0, 0, 0, 0);
+                }
                 if (cancellationToken.IsCancellationRequested)
                 {
                     return (false, null, 0, 0, 0, 0);
@@ -169,7 +193,11 @@ namespace TeamAAS_VP.Services
                 //关闭吸气
                 await robot.CalibOutIOAsync(false);
                 //移动机器人至待机位置
-                await robot.CalibMotionAsync(calibrationInfo.HomePoint, null);
+                isSuccess= await robot.CalibMotionAsync(calibrationInfo.HomePoint, null);
+                if (!isSuccess)
+                {
+                    return (false, null, 0, 0, 0, 0);
+                }
                 if (cancellationToken.IsCancellationRequested)
                 {
                     return (false, null, 0, 0, 0, 0);
@@ -187,7 +215,11 @@ namespace TeamAAS_VP.Services
                 if (Math.Abs(offsetx) < 1 && Math.Abs(offsetx) < 1)
                 {
                     //移动机器人取标定块
-                    await robot.CalibMotionAsync(RobotU, null);
+                    isSuccess= await robot.CalibMotionAsync(RobotU, null);
+                    if (!isSuccess)
+                    {
+                        return (false, null, 0, 0, 0, 0);
+                    }
                     if (cancellationToken.IsCancellationRequested)
                     {
                         return (false, null, 0, 0, 0, 0);
@@ -195,7 +227,11 @@ namespace TeamAAS_VP.Services
                     //打开吸气
                     await robot.CalibOutIOAsync(true);
                     //移动机器人至待机位置
-                    await robot.CalibMotionAsync(calibrationInfo.HomePoint, null);
+                    isSuccess= await robot.CalibMotionAsync(calibrationInfo.HomePoint, null);
+                    if (!isSuccess)
+                    {
+                        return (false, null, 0, 0, 0, 0);
+                    }
                     IsFinish = true;
                     break;
                 }
@@ -247,7 +283,11 @@ namespace TeamAAS_VP.Services
             Matrix<double> RobotCameraRotationMatrix = null;
 
             //移动机器人至中心位置
-            await robot.CalibMotionAsync(calibrationInfo.CenterPoint, null);
+            bool isSuccess = await robot.CalibMotionAsync(calibrationInfo.CenterPoint, null);
+            if (!isSuccess)
+            {
+                return (false, null, 0, 0, 0, 0);
+            }
 
             //计算相机与机器人坐标系的旋转矩阵
             var robotCameraRotationMatrix = await AutoIdentifyRobotCameraRotationMatrix(calibrationInfo, robot, cancellationToken);
@@ -272,7 +312,11 @@ namespace TeamAAS_VP.Services
             RobotU.U += (float)calibrationInfo.Angle;
 
             //机器人U轴旋转
-            await robot.CalibMotionAsync(RobotU, RobotU.Z);
+            isSuccess= await robot.CalibMotionAsync(RobotU, RobotU.Z);
+            if (!isSuccess)
+            {
+                return (false, null, 0, 0, 0, 0);
+            }
             if (cancellationToken.IsCancellationRequested)
             {
                 return (false, null, 0, 0, 0, 0);
@@ -314,7 +358,11 @@ namespace TeamAAS_VP.Services
             calibrationInfo.Tool.Y = toolCoord.Y;
 
             //移动机器人至中心位置
-            await robot.CalibMotionAsync(calibrationInfo.CenterPoint, calibrationInfo.CenterPoint.Z);
+            isSuccess= await robot.CalibMotionAsync(calibrationInfo.CenterPoint, calibrationInfo.CenterPoint.Z);
+            if (!isSuccess)
+            {
+                return (false, null, 0, 0, 0, 0);
+            }
 
             return (true, RobotCameraRotationMatrix, calibrationInfo.Tool.X, calibrationInfo.Tool.Y, pixelScaleX, pixelScaleY);
         }
@@ -334,7 +382,11 @@ namespace TeamAAS_VP.Services
             Matrix<double> RobotCameraRotationMatrix = null;
 
             //移动机器人至中心位置
-            await robot.CalibMotionAsync(calibrationInfo.CenterPoint, null);
+            bool isSuccess = await robot.CalibMotionAsync(calibrationInfo.CenterPoint, null);
+            if (!isSuccess)
+            {
+                return (false, null, 0, 0, 0, 0);
+            }
 
             if (calibrationInfo.Pick.PickPlaceModel == Enums.PickPlaceModel.Inhal)
             {
@@ -380,7 +432,11 @@ namespace TeamAAS_VP.Services
             RobotU.U += (float)calibrationInfo.Angle;
 
             //机器人U轴旋转
-            await robot.CalibMotionAsync(RobotU, RobotU.Z);
+            isSuccess= await robot.CalibMotionAsync(RobotU, RobotU.Z);
+            if (!isSuccess)
+            {
+                return (false, null, 0, 0, 0, 0);
+            }
             if (cancellationToken.IsCancellationRequested)
             {
                 return (false, null, 0, 0, 0, 0);
@@ -422,7 +478,11 @@ namespace TeamAAS_VP.Services
             calibrationInfo.Tool.Y = toolCoord.Y;
 
             //移动机器人至中心位置
-            await robot.CalibMotionAsync(calibrationInfo.CenterPoint, calibrationInfo.CenterPoint.Z);
+            isSuccess= await robot.CalibMotionAsync(calibrationInfo.CenterPoint, calibrationInfo.CenterPoint.Z);
+            if (!isSuccess)
+            {
+                return (false, null, 0, 0, 0, 0);
+            }
 
             return (true, RobotCameraRotationMatrix, calibrationInfo.Tool.X, calibrationInfo.Tool.Y, pixelScaleX, pixelScaleY);
         }
@@ -708,7 +768,7 @@ namespace TeamAAS_VP.Services
             else
             {
                 //移动机器人至P1
-                isFinished= await robot.CalibMotionAsync(RobotP1, RobotP1.Z);
+                isFinished = await robot.CalibMotionAsync(RobotP1, RobotP1.Z);
                 if (!isFinished)
                 {
                     return (false, null, 0, 0);
@@ -732,7 +792,7 @@ namespace TeamAAS_VP.Services
             if (calibrationInfo.CameraMount == Enums.CameraMount.FixedDown && !calibrationInfo.FixedDownCameraNoReturnToHome)
             {
                 //移动机器人至P1
-                isFinished= await robot.CalibMotionAsync(RobotP1, null);
+                isFinished = await robot.CalibMotionAsync(RobotP1, null);
                 if (!isFinished)
                 {
                     return (false, null, 0, 0);
@@ -744,7 +804,7 @@ namespace TeamAAS_VP.Services
                 //打开吸气
                 await robot.CalibOutIOAsync(true);
                 //移动机器人至P2
-                isFinished= await robot.CalibMotionAsync(RobotP2, null);
+                isFinished = await robot.CalibMotionAsync(RobotP2, null);
                 if (!isFinished)
                 {
                     return (false, null, 0, 0);
@@ -756,7 +816,7 @@ namespace TeamAAS_VP.Services
                 //关闭吸气
                 await robot.CalibOutIOAsync(false);
                 //移动机器人至待机位置
-                isFinished= await robot.CalibMotionAsync(calibrationInfo.HomePoint, null);
+                isFinished = await robot.CalibMotionAsync(calibrationInfo.HomePoint, null);
                 if (!isFinished)
                 {
                     return (false, null, 0, 0);
@@ -765,7 +825,7 @@ namespace TeamAAS_VP.Services
             else
             {
                 //移动机器人至P2
-                isFinished= await robot.CalibMotionAsync(RobotP2, RobotP2.Z);
+                isFinished = await robot.CalibMotionAsync(RobotP2, RobotP2.Z);
                 if (!isFinished)
                 {
                     return (false, null, 0, 0);
@@ -789,7 +849,7 @@ namespace TeamAAS_VP.Services
             if (calibrationInfo.CameraMount == Enums.CameraMount.FixedDown && !calibrationInfo.FixedDownCameraNoReturnToHome)
             {
                 //移动机器人至P2
-                isFinished= await robot.CalibMotionAsync(RobotP2, null);
+                isFinished = await robot.CalibMotionAsync(RobotP2, null);
                 if (!isFinished)
                 {
                     return (false, null, 0, 0);
@@ -801,7 +861,7 @@ namespace TeamAAS_VP.Services
                 //打开吸气
                 await robot.CalibOutIOAsync(true);
                 //移动机器人至P0
-                isFinished= await robot.CalibMotionAsync(RobotP0, null);
+                isFinished = await robot.CalibMotionAsync(RobotP0, null);
                 if (!isFinished)
                 {
                     return (false, null, 0, 0);
@@ -813,7 +873,7 @@ namespace TeamAAS_VP.Services
                 //关闭吸气
                 await robot.CalibOutIOAsync(false);
                 //移动机器人至待机位置
-                isFinished= await robot.CalibMotionAsync(calibrationInfo.HomePoint, null);
+                isFinished = await robot.CalibMotionAsync(calibrationInfo.HomePoint, null);
                 if (!isFinished)
                 {
                     return (false, null, 0, 0);
@@ -822,7 +882,7 @@ namespace TeamAAS_VP.Services
             else
             {
                 //移动机器人至P0
-                isFinished= await robot.CalibMotionAsync(RobotP0, RobotP0.Z);
+                isFinished = await robot.CalibMotionAsync(RobotP0, RobotP0.Z);
                 if (!isFinished)
                 {
                     return (false, null, 0, 0);
@@ -910,7 +970,11 @@ namespace TeamAAS_VP.Services
                 curpos.X += (float)pos[0];
                 curpos.Y += (float)pos[1];
                 //机器人移动
-                await robot.CalibMotionAsync(curpos, curpos.Z);
+                bool isSuccess = await robot.CalibMotionAsync(curpos, curpos.Z);
+                if (!isSuccess)
+                {
+                    return (false, 0, 0, 0);
+                }
                 await Task.Delay(200);
 
                 result = await CaptureAndProcessCallback();
@@ -963,7 +1027,7 @@ namespace TeamAAS_VP.Services
         {
             if (calibrationInfo == null) return (false, null, null, null);
             if (robot == null || !robot.IsConnected) return (false, null, null, null);
-
+            bool isSuccess = false;
 
             //发送校准的参数
             await robot.CalibParameAsync(calibrationInfo.Pick, calibrationInfo.Speed, calibrationInfo.Accel, calibrationInfo.Power, calibrationInfo.WaitSuction, calibrationInfo.WaitBlow);
@@ -973,7 +1037,11 @@ namespace TeamAAS_VP.Services
             {
 
                 //移动机器人至中心位置
-                await robot.CalibMotionAsync(calibrationInfo.CenterPoint, null);
+                isSuccess= await robot.CalibMotionAsync(calibrationInfo.CenterPoint, null);
+                if (isSuccess)
+                {
+                    return (false, null, null, null);
+                }
                 if (cancellationToken.IsCancellationRequested)
                 {
                     return (false, null, null, null);
@@ -1002,7 +1070,11 @@ namespace TeamAAS_VP.Services
             else if (calibrationInfo.CameraMount == Enums.CameraMount.MobileDown_XYPlatform)
             {
                 //移动机器人至中心位置
-                await robot.CalibMotionAsync(calibrationInfo.CenterPoint, null);
+                isSuccess= await robot.CalibMotionAsync(calibrationInfo.CenterPoint, null);
+                if (isSuccess)
+                {
+                    return (false, null, null, null);
+                }
                 if (cancellationToken.IsCancellationRequested)
                 {
                     return (false, null, null, null);
@@ -1203,7 +1275,11 @@ namespace TeamAAS_VP.Services
             if (calibrationInfo.CameraMount == Enums.CameraMount.MobileJ4)
             {
                 //移动机器人至中心位置
-                await robot.CalibMotionAsync(calibrationInfo.CenterPoint, null);
+                isSuccess= await robot.CalibMotionAsync(calibrationInfo.CenterPoint, null);
+                if (isSuccess)
+                {
+                    return (false, null, null, null);
+                }
                 if (cancellationToken.IsCancellationRequested)
                 {
                     return (false, null, null, null);
@@ -1229,7 +1305,11 @@ namespace TeamAAS_VP.Services
                 //移动机器人至i
                 if (calibrationInfo.CameraMount == Enums.CameraMount.FixedDown)
                 {
-                    await robot.CalibMotionAsync(rPoints[i], null);
+                    isSuccess= await robot.CalibMotionAsync(rPoints[i], null);
+                    if (isSuccess)
+                    {
+                        return (false, null, null, null);
+                    }
                     if (cancellationToken.IsCancellationRequested)
                     {
                         return (false, null, null, null);
@@ -1237,11 +1317,19 @@ namespace TeamAAS_VP.Services
                     //关闭吸气
                     await robot.CalibOutIOAsync(false);
                     //移动机器人至待机位置
-                    await robot.CalibMotionAsync(calibrationInfo.HomePoint, null);
+                    isSuccess= await robot.CalibMotionAsync(calibrationInfo.HomePoint, null);
+                    if (isSuccess)
+                    {
+                        return (false, null, null, null);
+                    }
                 }
                 else
                 {
-                    await robot.CalibMotionAsync(rPoints[i], rPoints[i].Z);
+                    isSuccess= await robot.CalibMotionAsync(rPoints[i], rPoints[i].Z);
+                    if (isSuccess)
+                    {
+                        return (false, null, null, null);
+                    }
                 }
                 if (cancellationToken.IsCancellationRequested)
                 {
@@ -1260,7 +1348,11 @@ namespace TeamAAS_VP.Services
                 if (calibrationInfo.CameraMount == Enums.CameraMount.FixedDown)
                 {
                     //移动机器人至i
-                    await robot.CalibMotionAsync(rPoints[i], null);
+                    isSuccess= await robot.CalibMotionAsync(rPoints[i], null);
+                    if (isSuccess)
+                    {
+                        return (false, null, null, null);
+                    }
                     if (cancellationToken.IsCancellationRequested)
                     {
                         return (false, null, null, null);
@@ -1283,7 +1375,11 @@ namespace TeamAAS_VP.Services
             if (calibrationInfo.CameraMount == Enums.CameraMount.FixedDown)
             {
                 //移动机器人至待机位置
-                await robot.CalibMotionAsync(calibrationInfo.HomePoint, null);
+                isSuccess= await robot.CalibMotionAsync(calibrationInfo.HomePoint, null);
+                if (isSuccess)
+                {
+                    return (false, null, null, null);
+                }
             }
 
             if (cancellationToken.IsCancellationRequested)
@@ -1528,7 +1624,11 @@ namespace TeamAAS_VP.Services
                 if (calibrationInfo.CameraMount == Enums.CameraMount.FixedDown)
                 {
                     //移动机器人至i
-                    await robot.CalibMotionAsync(rPoints[i], null);
+                    isSucceed= await robot.CalibMotionAsync(rPoints[i], null);
+                    if (isSucceed)
+                    {
+                        return (false, null);
+                    }
                     if (cancellationToken.IsCancellationRequested)
                     {
                         return (false, null);
@@ -1795,7 +1895,11 @@ namespace TeamAAS_VP.Services
             Matrix<double> RobotCameraRotationMatrix = null;
 
             // 2.移动机器人至中心位置
-            await robot.CalibMotionAsync(calibrationInfo.CenterPoint, null);
+            bool isSuccess = await robot.CalibMotionAsync(calibrationInfo.CenterPoint, null);
+            if (isSuccess)
+            {
+                return (false, null, null);
+            }
 
             // 3.计算相机与机器人坐标系的旋转矩阵
             var robotCameraRotationMatrix = await AutoIdentifyRobotCameraRotationMatrix(calibrationInfo, robot, cancellationToken);
@@ -1856,32 +1960,32 @@ namespace TeamAAS_VP.Services
             //计算;两点的间距
             double wordLength = Common.CalculateDistance2D(P1.X, P1.Y, P2.X, P2.Y);
             double localLength = Common.CalculateDistance2D(P11.X, P11.Y, P12.X, P12.Y);
-            if (Math.Abs(wordLength- localLength)>0.1)
+            if (Math.Abs(wordLength - localLength) > 0.1)
             {
-                MessageBox.Show("检测下来绝对坐标系移动距离和独立步进坐标系的移动距离差大于0.1mm,请检查哥轴的实际移动距离是否正确!"+ Math.Abs(wordLength - localLength).ToString()+"mm");
+                MessageBox.Show("检测下来绝对坐标系移动距离和独立步进坐标系的移动距离差大于0.1mm,请检查哥轴的实际移动距离是否正确!" + Math.Abs(wordLength - localLength).ToString() + "mm");
             }
             else
             {
                 MessageBox.Show($"检测下来两个坐标系的移动距离正确,实际距离差:{Math.Abs(wordLength - localLength)}mm");
             }
 
-                // 9.计算刚体变换矩阵
-                ////得到旋转矩阵
-                //var rigidMatrix = local.InvR;
-                ////平移矩阵
-                //var translation = local.T;
-                //double[,] TransformationMatrix = new double[3, 3];
-                //TransformationMatrix[0, 0] = rigidMatrix[0, 0];
-                //TransformationMatrix[0, 1] = rigidMatrix[0, 1];
-                //TransformationMatrix[0, 2] = translation[0, 0];
-                //TransformationMatrix[1, 0] = rigidMatrix[1, 0];
-                //TransformationMatrix[1, 1] = rigidMatrix[1, 1];
-                //TransformationMatrix[1, 2] = translation[1, 0];
-                //TransformationMatrix[2, 0] = 0;
-                //TransformationMatrix[2, 1] = 0;
-                //TransformationMatrix[2, 2] = 1;
-
-                return (true, local.R.ToArray(), local.T.ToArray());
+            // 9.计算刚体变换矩阵
+            ////得到旋转矩阵
+            //var rigidMatrix = local.InvR;
+            ////平移矩阵
+            //var translation = local.T;
+            //double[,] TransformationMatrix = new double[3, 3];
+            //TransformationMatrix[0, 0] = rigidMatrix[0, 0];
+            //TransformationMatrix[0, 1] = rigidMatrix[0, 1];
+            //TransformationMatrix[0, 2] = translation[0, 0];
+            //TransformationMatrix[1, 0] = rigidMatrix[1, 0];
+            //TransformationMatrix[1, 1] = rigidMatrix[1, 1];
+            //TransformationMatrix[1, 2] = translation[1, 0];
+            //TransformationMatrix[2, 0] = 0;
+            //TransformationMatrix[2, 1] = 0;
+            //TransformationMatrix[2, 2] = 1;
+
+            return (true, local.R.ToArray(), local.T.ToArray());
         }
 
         public void Dispose()

+ 191 - 0
TeamAAS-VM/ViewModels/Product/ProductParamsViewModel.cs

@@ -200,6 +200,126 @@ namespace TeamAAS_VP.ViewModels.Product
             }
         }
 
+        private ProcedureModel _IndependentCamer1ProductProcedureId;
+        /// <summary>
+        /// 独立移动模组相机1产品定位拍照流程ID
+        /// </summary>
+        public ProcedureModel IndependentCamer1ProductProcedureId
+        {
+            get { return _IndependentCamer1ProductProcedureId; }
+            set { SetProperty(ref _IndependentCamer1ProductProcedureId, value); 
+                if (value != null)
+                {
+                    SelectProduct.IndependentCamer1ProductProcedureId = value.Id;
+                }
+            }
+        }
+
+        private ProcedureModel _IndependentCamer2ProductProcedureId;
+        /// <summary>
+        /// 独立移动模组相机2产品定位拍照流程ID
+        /// </summary>
+        public ProcedureModel IndependentCamer2ProductProcedureId
+        {
+            get { return _IndependentCamer2ProductProcedureId; }
+            set { SetProperty(ref _IndependentCamer2ProductProcedureId, value);
+                if (value != null)
+                {
+                    SelectProduct.IndependentCamer2ProductProcedureId = value.Id;
+                }
+            }
+        }
+
+        private ProcedureModel _IndependentCamer3ProductProcedureId;
+        /// <summary>
+        /// 独立移动模组相机3产品定位拍照流程ID
+        /// </summary>
+        public ProcedureModel IndependentCamer3ProductProcedureId
+        {
+            get { return _IndependentCamer3ProductProcedureId; }
+            set { SetProperty(ref _IndependentCamer3ProductProcedureId, value);
+                if (value != null)
+                {
+                    SelectProduct.IndependentCamer3ProductProcedureId = value.Id;
+                }
+            }
+        }
+
+        private ProcedureModel _IndependentCamer4ProductProcedureId;
+        /// <summary>
+        /// 独立移动模组相机4产品定位拍照流程ID
+        /// </summary>
+        public ProcedureModel IndependentCamer4ProductProcedureId
+        {
+            get { return _IndependentCamer4ProductProcedureId; }
+            set { SetProperty(ref _IndependentCamer4ProductProcedureId, value);
+                if (value != null)
+                {
+                    SelectProduct.IndependentCamer4ProductProcedureId = value.Id;
+                }
+            }
+        }
+
+        private ProcedureModel _IndependentCamer1AuxProcedureId;
+        /// <summary>
+        /// 独立移动模组相机1辅料定位拍照流程ID
+        /// </summary>
+        public ProcedureModel IndependentCamer1AuxProcedureId
+        {
+            get { return _IndependentCamer1AuxProcedureId; }
+            set { SetProperty(ref _IndependentCamer1AuxProcedureId, value);
+                if (value != null)
+                {
+                    SelectProduct.IndependentCamer1AuxProcedureId = value.Id;
+                }
+            }
+        }
+
+        private ProcedureModel _IndependentCamer2AuxProcedureId;
+        /// <summary>
+        /// 独立移动模组相机2辅料定位拍照流程ID
+        /// </summary>
+        public ProcedureModel IndependentCamer2AuxProcedureId
+        {
+            get { return _IndependentCamer2AuxProcedureId; }
+            set { SetProperty(ref _IndependentCamer2AuxProcedureId, value);
+                if (value != null)
+                {
+                    SelectProduct.IndependentCamer2AuxProcedureId = value.Id;
+                }
+            }
+        }
+
+        private ProcedureModel _IndependentCamer3AuxProcedureId;
+        /// <summary>
+        /// 独立移动模组相机3辅料定位拍照流程ID
+        /// </summary>
+        public ProcedureModel IndependentCamer3AuxProcedureId
+        {
+            get { return _IndependentCamer3AuxProcedureId; }
+            set { SetProperty(ref _IndependentCamer3AuxProcedureId, value);
+                if (value != null)
+                {
+                    SelectProduct.IndependentCamer3AuxProcedureId = value.Id;
+                }
+            }
+        }
+
+        private ProcedureModel _IndependentCamer4AuxProcedureId;
+        /// <summary>
+        /// 独立移动模组相机4辅料定位拍照流程ID
+        /// </summary>
+        public ProcedureModel IndependentCamer4AuxProcedureId
+        {
+            get { return _IndependentCamer4AuxProcedureId; }
+            set { SetProperty(ref _IndependentCamer4AuxProcedureId, value);
+                if (value != null)
+                {
+                    SelectProduct.IndependentCamer4AuxProcedureId = value.Id;
+                }
+            }
+        }
+
         #endregion
 
         #region 命令
@@ -249,6 +369,7 @@ namespace TeamAAS_VP.ViewModels.Product
         /// </summary>
         async void ExecuteNextCommand()
         {
+            ResetId();
             if (MessageBox.Show(Lang.是否保存产品.Replace("[{0}]", ""), Lang.保存产品, MessageBoxButton.YesNo, MessageBoxImage.Question) == MessageBoxResult.Yes)
             {
                 var waiting = new WaitingControl();
@@ -282,6 +403,76 @@ namespace TeamAAS_VP.ViewModels.Product
             _regionManager.RequestNavigate("ProductRegionContext", "ProductHome", param);
         }
 
+        private void ResetId()
+        {
+            if(FixedUpCamera1Procedure == null)
+            {
+                SelectProduct.FixedUpCamera1ProcedureId = Guid.Empty;
+            }
+            if (FixedUpCamera2Procedure == null)
+            {
+                SelectProduct.FixedUpCamera2ProcedureId = Guid.Empty;
+            }
+            if (FixedDownCamera1Procedure == null)
+            {
+                SelectProduct.FixedDownCamera1ProcedureId = Guid.Empty;
+            }
+            if (FixedDownCamera2Procedure == null)
+            {
+                SelectProduct.FixedDownCamera2ProcedureId = Guid.Empty;
+            }
+            if (MoveDownCamera1LockPhotoProcedure == null)
+            {
+                SelectProduct.MoveDownCamera1LockPhotoProcedureId = Guid.Empty;
+            }
+            if (MoveDownCamera2LockPhotoProcedure == null)
+            {
+                SelectProduct.MoveDownCamera2LockPhotoProcedureId = Guid.Empty;
+            }
+            if (MoveDownCamer1PickPhotoProcedureId == null)
+            {
+                SelectProduct.MoveDownCamer1PickPhotoProcedureId = Guid.Empty;
+            }
+            if (MoveDownCamer2PickPhotoProcedureId == null)
+            {
+                SelectProduct.MoveDownCamer2PickPhotoProcedureId = Guid.Empty;
+            }
+            if (IndependentCamer1ProductProcedureId == null)
+            {
+                SelectProduct.IndependentCamer1ProductProcedureId = Guid.Empty;
+            }
+            if (IndependentCamer2ProductProcedureId == null)
+            {
+                SelectProduct.IndependentCamer2ProductProcedureId = Guid.Empty;
+            }
+            if (IndependentCamer3ProductProcedureId == null)
+            {
+                SelectProduct.IndependentCamer3ProductProcedureId = Guid.Empty;
+            }
+            if (IndependentCamer4ProductProcedureId == null)
+            {
+                SelectProduct.IndependentCamer4ProductProcedureId = Guid.Empty;
+            }
+            if (IndependentCamer1AuxProcedureId == null)
+            {
+                SelectProduct.IndependentCamer1AuxProcedureId = Guid.Empty;
+            }
+            if (IndependentCamer2AuxProcedureId == null)
+            {
+                SelectProduct.IndependentCamer2AuxProcedureId = Guid.Empty;
+            }
+            if (IndependentCamer3AuxProcedureId == null)
+            {
+                SelectProduct.IndependentCamer3AuxProcedureId = Guid.Empty;
+            }
+            if (IndependentCamer4AuxProcedureId == null)
+            {
+                SelectProduct.IndependentCamer4AuxProcedureId = Guid.Empty;
+            }
+
+
+        }
+
         /// <summary>
         /// 上一步
         /// </summary>

+ 199 - 7
TeamAAS-VM/Views/Product/ProductParams.xaml

@@ -123,6 +123,14 @@
                         <RowDefinition Height="auto" />
                         <RowDefinition Height="auto" />
                         <RowDefinition Height="auto" />
+                        <RowDefinition Height="auto" />
+                        <RowDefinition Height="auto" />
+                        <RowDefinition Height="auto" />
+                        <RowDefinition Height="auto" />
+                        <RowDefinition Height="auto" />
+                        <RowDefinition Height="auto" />
+                        <RowDefinition Height="auto" />
+                        <RowDefinition Height="auto" />
                     </Grid.RowDefinitions>
                     <Grid.ColumnDefinitions>
                         <ColumnDefinition Width="auto" />
@@ -281,7 +289,7 @@
                             </DataTemplate>
                         </ComboBox.ItemTemplate>
                     </ComboBox>
-                    <!--固定向下相机1取料流程-->
+                    <!--固定向下相机1取料流程--><!--
                     <TextBlock Grid.Row="3"
                                Grid.Column="0"
                                Text="固定向下相机1取料流程ID: " />
@@ -304,7 +312,7 @@
                             </DataTemplate>
                         </ComboBox.ItemTemplate>
                     </ComboBox>
-                    <!--固定向下相机2取料流程-->
+                    --><!--固定向下相机2取料流程--><!--
                     <TextBlock Grid.Row="4"
                                Grid.Column="0"
                                Text="固定向下相机2取料流程ID: " />
@@ -326,8 +334,8 @@
                                 </StackPanel>
                             </DataTemplate>
                         </ComboBox.ItemTemplate>
-                    </ComboBox>
-                    <!--移动向下相机1锁付拍照流程-->
+                    </ComboBox>-->
+                    <!--移动向下相机1锁付拍照流程--><!--
                     <TextBlock Grid.Row="5"
                                Grid.Column="0"
                                Text="移动向下相机1锁付拍照流程ID: " />
@@ -350,7 +358,7 @@
                             </DataTemplate>
                         </ComboBox.ItemTemplate>
                     </ComboBox>
-                    <!--移动向下相机2锁付拍照流程-->
+                    --><!--移动向下相机2锁付拍照流程--><!--
                     <TextBlock Grid.Row="6"
                                Grid.Column="0"
                                Text="移动向下相机2锁付拍照流程ID: " />
@@ -373,7 +381,7 @@
                             </DataTemplate>
                         </ComboBox.ItemTemplate>
                     </ComboBox>
-                    <!--移动向下相机1取料拍照流程-->
+                    --><!--移动向下相机1取料拍照流程--><!--
                     <TextBlock Grid.Row="7"
                                Grid.Column="0"
                                Text="移动向下相机1取料拍照流程ID: " />
@@ -396,7 +404,7 @@
                             </DataTemplate>
                         </ComboBox.ItemTemplate>
                     </ComboBox>
-                    <!--移动向下相机2取料拍照流程-->
+                    --><!--移动向下相机2取料拍照流程--><!--
                     <TextBlock Grid.Row="8"
                                Grid.Column="0"
                                Text="移动向下相机2取料拍照流程ID: " />
@@ -418,6 +426,190 @@
                                 </StackPanel>
                             </DataTemplate>
                         </ComboBox.ItemTemplate>
+                    </ComboBox>-->
+                    <!--独立向下相机1取料拍照流程ID-->
+                    <TextBlock Grid.Row="9"
+                               Grid.Column="0"
+                               Text="独立向下相机1取料拍照流程ID: " />
+                    <ComboBox Grid.Row="9"
+                              Grid.Column="1"
+                              ItemsSource="{Binding ProcedureModels}"
+                              SelectedItem="{Binding IndependentCamer1AuxProcedureId}"
+                              materialDesign:TextFieldAssist.HasClearButton="True"
+                              materialDesign:HintAssist.Hint="{lex:Loc 选择需要配置的流程}">
+                        <ComboBox.ItemTemplate>
+                            <DataTemplate>
+                                <StackPanel Orientation="Horizontal">
+                                    <materialDesign:PackIcon Kind="VideoOutline" />
+                                    <TextBlock Text="{Binding CameraName}"
+                                               Margin="6,0" />
+                                    <materialDesign:PackIcon Kind="ProgressWrench" />
+                                    <TextBlock Text="{Binding Name}"
+                                               Margin="6,0" />
+                                </StackPanel>
+                            </DataTemplate>
+                        </ComboBox.ItemTemplate>
+                    </ComboBox>
+                    <!--独立向下相机2取料拍照流程ID-->
+                    <TextBlock Grid.Row="10"
+                               Grid.Column="0"
+                               Text="独立向下相机2取料拍照流程ID: " />
+                    <ComboBox Grid.Row="10"
+                              Grid.Column="1"
+                              ItemsSource="{Binding ProcedureModels}"
+                              SelectedItem="{Binding IndependentCamer2AuxProcedureId}"
+                              materialDesign:TextFieldAssist.HasClearButton="True"
+                              materialDesign:HintAssist.Hint="{lex:Loc 选择需要配置的流程}">
+                        <ComboBox.ItemTemplate>
+                            <DataTemplate>
+                                <StackPanel Orientation="Horizontal">
+                                    <materialDesign:PackIcon Kind="VideoOutline" />
+                                    <TextBlock Text="{Binding CameraName}"
+                                               Margin="6,0" />
+                                    <materialDesign:PackIcon Kind="ProgressWrench" />
+                                    <TextBlock Text="{Binding Name}"
+                                               Margin="6,0" />
+                                </StackPanel>
+                            </DataTemplate>
+                        </ComboBox.ItemTemplate>
+                    </ComboBox>
+                    <!--独立向下相机3取料拍照流程ID-->
+                    <TextBlock Grid.Row="11"
+                               Grid.Column="0"
+                               Text="独立向下相机3取料拍照流程ID: " />
+                    <ComboBox Grid.Row="11"
+                              Grid.Column="1"
+                              ItemsSource="{Binding ProcedureModels}"
+                              SelectedItem="{Binding IndependentCamer3AuxProcedureId}"
+                              materialDesign:TextFieldAssist.HasClearButton="True"
+                              materialDesign:HintAssist.Hint="{lex:Loc 选择需要配置的流程}">
+                        <ComboBox.ItemTemplate>
+                            <DataTemplate>
+                                <StackPanel Orientation="Horizontal">
+                                    <materialDesign:PackIcon Kind="VideoOutline" />
+                                    <TextBlock Text="{Binding CameraName}"
+                                               Margin="6,0" />
+                                    <materialDesign:PackIcon Kind="ProgressWrench" />
+                                    <TextBlock Text="{Binding Name}"
+                                               Margin="6,0" />
+                                </StackPanel>
+                            </DataTemplate>
+                        </ComboBox.ItemTemplate>
+                    </ComboBox>
+                    <!--独立向下相机4取料拍照流程ID-->
+                    <TextBlock Grid.Row="12"
+                               Grid.Column="0"
+                               Text="独立向下相机4取料拍照流程ID: " />
+                    <ComboBox Grid.Row="12"
+                              Grid.Column="1"
+                              ItemsSource="{Binding ProcedureModels}"
+                              SelectedItem="{Binding IndependentCamer4AuxProcedureId}"
+                              materialDesign:TextFieldAssist.HasClearButton="True"
+                              materialDesign:HintAssist.Hint="{lex:Loc 选择需要配置的流程}">
+                        <ComboBox.ItemTemplate>
+                            <DataTemplate>
+                                <StackPanel Orientation="Horizontal">
+                                    <materialDesign:PackIcon Kind="VideoOutline" />
+                                    <TextBlock Text="{Binding CameraName}"
+                                               Margin="6,0" />
+                                    <materialDesign:PackIcon Kind="ProgressWrench" />
+                                    <TextBlock Text="{Binding Name}"
+                                               Margin="6,0" />
+                                </StackPanel>
+                            </DataTemplate>
+                        </ComboBox.ItemTemplate>
+                    </ComboBox>
+                    <!--独立向下相机1产品拍照流程ID-->
+                    <TextBlock Grid.Row="13"
+                               Grid.Column="0"
+                               Text="独立向下相机1产品拍照流程ID: " />
+                    <ComboBox Grid.Row="13"
+                              Grid.Column="1"
+                              ItemsSource="{Binding ProcedureModels}"
+                              SelectedItem="{Binding IndependentCamer1ProductProcedureId}"
+                              materialDesign:TextFieldAssist.HasClearButton="True"
+                              materialDesign:HintAssist.Hint="{lex:Loc 选择需要配置的流程}">
+                        <ComboBox.ItemTemplate>
+                            <DataTemplate>
+                                <StackPanel Orientation="Horizontal">
+                                    <materialDesign:PackIcon Kind="VideoOutline" />
+                                    <TextBlock Text="{Binding CameraName}"
+                                               Margin="6,0" />
+                                    <materialDesign:PackIcon Kind="ProgressWrench" />
+                                    <TextBlock Text="{Binding Name}"
+                                               Margin="6,0" />
+                                </StackPanel>
+                            </DataTemplate>
+                        </ComboBox.ItemTemplate>
+                    </ComboBox>
+                    <!--独立向下相机2产品拍照流程ID-->
+                    <TextBlock Grid.Row="14"
+                               Grid.Column="0"
+                               Text="独立向下相机2产品拍照流程ID: " />
+                    <ComboBox Grid.Row="14"
+                              Grid.Column="1"
+                              ItemsSource="{Binding ProcedureModels}"
+                              SelectedItem="{Binding IndependentCamer2ProductProcedureId}"
+                              materialDesign:TextFieldAssist.HasClearButton="True"
+                              materialDesign:HintAssist.Hint="{lex:Loc 选择需要配置的流程}">
+                        <ComboBox.ItemTemplate>
+                            <DataTemplate>
+                                <StackPanel Orientation="Horizontal">
+                                    <materialDesign:PackIcon Kind="VideoOutline" />
+                                    <TextBlock Text="{Binding CameraName}"
+                                               Margin="6,0" />
+                                    <materialDesign:PackIcon Kind="ProgressWrench" />
+                                    <TextBlock Text="{Binding Name}"
+                                               Margin="6,0" />
+                                </StackPanel>
+                            </DataTemplate>
+                        </ComboBox.ItemTemplate>
+                    </ComboBox>
+                    <!--独立向下相机3产品拍照流程ID-->
+                    <TextBlock Grid.Row="15"
+                               Grid.Column="0"
+                               Text="独立向下相机3产品拍照流程ID: " />
+                    <ComboBox Grid.Row="15"
+                              Grid.Column="1"
+                              ItemsSource="{Binding ProcedureModels}"
+                              SelectedItem="{Binding IndependentCamer3ProductProcedureId}"
+                              materialDesign:TextFieldAssist.HasClearButton="True"
+                              materialDesign:HintAssist.Hint="{lex:Loc 选择需要配置的流程}">
+                        <ComboBox.ItemTemplate>
+                            <DataTemplate>
+                                <StackPanel Orientation="Horizontal">
+                                    <materialDesign:PackIcon Kind="VideoOutline" />
+                                    <TextBlock Text="{Binding CameraName}"
+                                               Margin="6,0" />
+                                    <materialDesign:PackIcon Kind="ProgressWrench" />
+                                    <TextBlock Text="{Binding Name}"
+                                               Margin="6,0" />
+                                </StackPanel>
+                            </DataTemplate>
+                        </ComboBox.ItemTemplate>
+                    </ComboBox>
+                    <!--独立向下相机4产品拍照流程ID-->
+                    <TextBlock Grid.Row="16"
+                               Grid.Column="0"
+                               Text="独立向下相机4产品拍照流程ID: " />
+                    <ComboBox Grid.Row="16"
+                              Grid.Column="1"
+                              ItemsSource="{Binding ProcedureModels}"
+                              SelectedItem="{Binding IndependentCamer4ProductProcedureId}"
+                              materialDesign:TextFieldAssist.HasClearButton="True"
+                              materialDesign:HintAssist.Hint="{lex:Loc 选择需要配置的流程}">
+                        <ComboBox.ItemTemplate>
+                            <DataTemplate>
+                                <StackPanel Orientation="Horizontal">
+                                    <materialDesign:PackIcon Kind="VideoOutline" />
+                                    <TextBlock Text="{Binding CameraName}"
+                                               Margin="6,0" />
+                                    <materialDesign:PackIcon Kind="ProgressWrench" />
+                                    <TextBlock Text="{Binding Name}"
+                                               Margin="6,0" />
+                                </StackPanel>
+                            </DataTemplate>
+                        </ComboBox.ItemTemplate>
                     </ComboBox>
                 </Grid>
             </Grid>