添加项目文件。

This commit is contained in:
17860779768 2023-02-23 14:52:43 +08:00
parent 1db01eda58
commit 157613603c
508 changed files with 94132 additions and 0 deletions

230
A020.sln Normal file
View File

@ -0,0 +1,230 @@

Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio Version 16
VisualStudioVersion = 16.0.32602.291
MinimumVisualStudioVersion = 10.0.40219.1
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Device", "Device", "{5DB27B2D-14A5-441F-A861-BAFDB7BAA05B}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "UI", "UI", "{97C226B4-971C-4802-8D35-14E2980FF0C6}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Process", "Process", "{DD1CE747-341A-4419-8398-0D482E02DE54}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Common", "Common", "{2BE63CDD-DAEF-4C50-BE1C-73EC5AC5A578}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "DataBase", "DataBase", "{5DA98228-94DA-49DE-BC8C-ED99BF255511}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "BRS.Common.Device", "src\BRS.Common.Device\BRS.Common.Device.csproj", "{987308DD-8BAA-463A-94E2-77D62E01A5BF}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "BRS.Common.Model", "src\BRS.Common.Model\BRS.Common.Model.csproj", "{1A3CBFE7-3F78-42C3-95C5-10360450DBEA}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "BRS.Process", "src\BRS.Process\BRS.Process.csproj", "{197C5AA8-9609-4D1C-B1E3-5879006EAAF4}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "BRS.UI.Device.Winform", "src\BRS.UI.Device.Winform\BRS.UI.Device.Winform.csproj", "{E6429C64-92B3-46A2-B35E-579856D47F62}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "BRS.UI.Main", "src\BRS.UI.Main\BRS.UI.Main.csproj", "{DD02C60E-560B-40C0-AD7F-523F0B4AA4FD}"
ProjectSection(ProjectDependencies) = postProject
{9EB9DFC1-C78A-46C0-826A-5ED1A08232C0} = {9EB9DFC1-C78A-46C0-826A-5ED1A08232C0}
EndProjectSection
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "BRS.UI.Model.Winform", "src\BRS.UI.Model.Winform\BRS.UI.Model.Winform.csproj", "{741F6491-57C7-479A-B391-09BBA9FBA9DC}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "BRS.Process.A020", "src\BRS.Process.A020\BRS.Process.A020.csproj", "{9EB9DFC1-C78A-46C0-826A-5ED1A08232C0}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "BRS.Device.OmronPLC", "src\BRS.Device.OmronPLC\BRS.Device.OmronPLC.csproj", "{560CC80B-389B-46FC-9B8C-DA1D62A555D9}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "XKRS.Device.NbtRobot", "src\BRS.Device.NbtRobot\XKRS.Device.NbtRobot.csproj", "{8FA74161-0D03-408F-811A-A244C9027BFB}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Debug|x64 = Debug|x64
Debug|x86 = Debug|x86
Debug1|Any CPU = Debug1|Any CPU
Debug1|x64 = Debug1|x64
Debug1|x86 = Debug1|x86
Release|Any CPU = Release|Any CPU
Release|x64 = Release|x64
Release|x86 = Release|x86
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{987308DD-8BAA-463A-94E2-77D62E01A5BF}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{987308DD-8BAA-463A-94E2-77D62E01A5BF}.Debug|Any CPU.Build.0 = Debug|Any CPU
{987308DD-8BAA-463A-94E2-77D62E01A5BF}.Debug|x64.ActiveCfg = Debug|x64
{987308DD-8BAA-463A-94E2-77D62E01A5BF}.Debug|x64.Build.0 = Debug|x64
{987308DD-8BAA-463A-94E2-77D62E01A5BF}.Debug|x86.ActiveCfg = Debug|Any CPU
{987308DD-8BAA-463A-94E2-77D62E01A5BF}.Debug|x86.Build.0 = Debug|Any CPU
{987308DD-8BAA-463A-94E2-77D62E01A5BF}.Debug1|Any CPU.ActiveCfg = Debug1|Any CPU
{987308DD-8BAA-463A-94E2-77D62E01A5BF}.Debug1|Any CPU.Build.0 = Debug1|Any CPU
{987308DD-8BAA-463A-94E2-77D62E01A5BF}.Debug1|x64.ActiveCfg = Debug1|x64
{987308DD-8BAA-463A-94E2-77D62E01A5BF}.Debug1|x64.Build.0 = Debug1|x64
{987308DD-8BAA-463A-94E2-77D62E01A5BF}.Debug1|x86.ActiveCfg = Debug1|Any CPU
{987308DD-8BAA-463A-94E2-77D62E01A5BF}.Debug1|x86.Build.0 = Debug1|Any CPU
{987308DD-8BAA-463A-94E2-77D62E01A5BF}.Release|Any CPU.ActiveCfg = Release|Any CPU
{987308DD-8BAA-463A-94E2-77D62E01A5BF}.Release|Any CPU.Build.0 = Release|Any CPU
{987308DD-8BAA-463A-94E2-77D62E01A5BF}.Release|x64.ActiveCfg = Release|x64
{987308DD-8BAA-463A-94E2-77D62E01A5BF}.Release|x64.Build.0 = Release|x64
{987308DD-8BAA-463A-94E2-77D62E01A5BF}.Release|x86.ActiveCfg = Release|Any CPU
{987308DD-8BAA-463A-94E2-77D62E01A5BF}.Release|x86.Build.0 = Release|Any CPU
{1A3CBFE7-3F78-42C3-95C5-10360450DBEA}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{1A3CBFE7-3F78-42C3-95C5-10360450DBEA}.Debug|Any CPU.Build.0 = Debug|Any CPU
{1A3CBFE7-3F78-42C3-95C5-10360450DBEA}.Debug|x64.ActiveCfg = Debug|x64
{1A3CBFE7-3F78-42C3-95C5-10360450DBEA}.Debug|x64.Build.0 = Debug|x64
{1A3CBFE7-3F78-42C3-95C5-10360450DBEA}.Debug|x86.ActiveCfg = Debug|Any CPU
{1A3CBFE7-3F78-42C3-95C5-10360450DBEA}.Debug|x86.Build.0 = Debug|Any CPU
{1A3CBFE7-3F78-42C3-95C5-10360450DBEA}.Debug1|Any CPU.ActiveCfg = Debug1|Any CPU
{1A3CBFE7-3F78-42C3-95C5-10360450DBEA}.Debug1|Any CPU.Build.0 = Debug1|Any CPU
{1A3CBFE7-3F78-42C3-95C5-10360450DBEA}.Debug1|x64.ActiveCfg = Debug1|x64
{1A3CBFE7-3F78-42C3-95C5-10360450DBEA}.Debug1|x64.Build.0 = Debug1|x64
{1A3CBFE7-3F78-42C3-95C5-10360450DBEA}.Debug1|x86.ActiveCfg = Debug1|Any CPU
{1A3CBFE7-3F78-42C3-95C5-10360450DBEA}.Debug1|x86.Build.0 = Debug1|Any CPU
{1A3CBFE7-3F78-42C3-95C5-10360450DBEA}.Release|Any CPU.ActiveCfg = Release|Any CPU
{1A3CBFE7-3F78-42C3-95C5-10360450DBEA}.Release|Any CPU.Build.0 = Release|Any CPU
{1A3CBFE7-3F78-42C3-95C5-10360450DBEA}.Release|x64.ActiveCfg = Release|x64
{1A3CBFE7-3F78-42C3-95C5-10360450DBEA}.Release|x64.Build.0 = Release|x64
{1A3CBFE7-3F78-42C3-95C5-10360450DBEA}.Release|x86.ActiveCfg = Release|Any CPU
{1A3CBFE7-3F78-42C3-95C5-10360450DBEA}.Release|x86.Build.0 = Release|Any CPU
{197C5AA8-9609-4D1C-B1E3-5879006EAAF4}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{197C5AA8-9609-4D1C-B1E3-5879006EAAF4}.Debug|Any CPU.Build.0 = Debug|Any CPU
{197C5AA8-9609-4D1C-B1E3-5879006EAAF4}.Debug|x64.ActiveCfg = Debug|x64
{197C5AA8-9609-4D1C-B1E3-5879006EAAF4}.Debug|x64.Build.0 = Debug|x64
{197C5AA8-9609-4D1C-B1E3-5879006EAAF4}.Debug|x86.ActiveCfg = Debug|Any CPU
{197C5AA8-9609-4D1C-B1E3-5879006EAAF4}.Debug|x86.Build.0 = Debug|Any CPU
{197C5AA8-9609-4D1C-B1E3-5879006EAAF4}.Debug1|Any CPU.ActiveCfg = Debug1|Any CPU
{197C5AA8-9609-4D1C-B1E3-5879006EAAF4}.Debug1|Any CPU.Build.0 = Debug1|Any CPU
{197C5AA8-9609-4D1C-B1E3-5879006EAAF4}.Debug1|x64.ActiveCfg = Debug1|x64
{197C5AA8-9609-4D1C-B1E3-5879006EAAF4}.Debug1|x64.Build.0 = Debug1|x64
{197C5AA8-9609-4D1C-B1E3-5879006EAAF4}.Debug1|x86.ActiveCfg = Debug1|Any CPU
{197C5AA8-9609-4D1C-B1E3-5879006EAAF4}.Debug1|x86.Build.0 = Debug1|Any CPU
{197C5AA8-9609-4D1C-B1E3-5879006EAAF4}.Release|Any CPU.ActiveCfg = Release|Any CPU
{197C5AA8-9609-4D1C-B1E3-5879006EAAF4}.Release|Any CPU.Build.0 = Release|Any CPU
{197C5AA8-9609-4D1C-B1E3-5879006EAAF4}.Release|x64.ActiveCfg = Release|x64
{197C5AA8-9609-4D1C-B1E3-5879006EAAF4}.Release|x64.Build.0 = Release|x64
{197C5AA8-9609-4D1C-B1E3-5879006EAAF4}.Release|x86.ActiveCfg = Release|Any CPU
{197C5AA8-9609-4D1C-B1E3-5879006EAAF4}.Release|x86.Build.0 = Release|Any CPU
{E6429C64-92B3-46A2-B35E-579856D47F62}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{E6429C64-92B3-46A2-B35E-579856D47F62}.Debug|Any CPU.Build.0 = Debug|Any CPU
{E6429C64-92B3-46A2-B35E-579856D47F62}.Debug|x64.ActiveCfg = Debug|x64
{E6429C64-92B3-46A2-B35E-579856D47F62}.Debug|x64.Build.0 = Debug|x64
{E6429C64-92B3-46A2-B35E-579856D47F62}.Debug|x86.ActiveCfg = Debug|Any CPU
{E6429C64-92B3-46A2-B35E-579856D47F62}.Debug|x86.Build.0 = Debug|Any CPU
{E6429C64-92B3-46A2-B35E-579856D47F62}.Debug1|Any CPU.ActiveCfg = Debug1|Any CPU
{E6429C64-92B3-46A2-B35E-579856D47F62}.Debug1|Any CPU.Build.0 = Debug1|Any CPU
{E6429C64-92B3-46A2-B35E-579856D47F62}.Debug1|x64.ActiveCfg = Debug1|x64
{E6429C64-92B3-46A2-B35E-579856D47F62}.Debug1|x64.Build.0 = Debug1|x64
{E6429C64-92B3-46A2-B35E-579856D47F62}.Debug1|x86.ActiveCfg = Debug1|Any CPU
{E6429C64-92B3-46A2-B35E-579856D47F62}.Debug1|x86.Build.0 = Debug1|Any CPU
{E6429C64-92B3-46A2-B35E-579856D47F62}.Release|Any CPU.ActiveCfg = Release|Any CPU
{E6429C64-92B3-46A2-B35E-579856D47F62}.Release|Any CPU.Build.0 = Release|Any CPU
{E6429C64-92B3-46A2-B35E-579856D47F62}.Release|x64.ActiveCfg = Release|x64
{E6429C64-92B3-46A2-B35E-579856D47F62}.Release|x64.Build.0 = Release|x64
{E6429C64-92B3-46A2-B35E-579856D47F62}.Release|x86.ActiveCfg = Release|Any CPU
{E6429C64-92B3-46A2-B35E-579856D47F62}.Release|x86.Build.0 = Release|Any CPU
{DD02C60E-560B-40C0-AD7F-523F0B4AA4FD}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{DD02C60E-560B-40C0-AD7F-523F0B4AA4FD}.Debug|Any CPU.Build.0 = Debug|Any CPU
{DD02C60E-560B-40C0-AD7F-523F0B4AA4FD}.Debug|x64.ActiveCfg = Debug|x64
{DD02C60E-560B-40C0-AD7F-523F0B4AA4FD}.Debug|x64.Build.0 = Debug|x64
{DD02C60E-560B-40C0-AD7F-523F0B4AA4FD}.Debug|x86.ActiveCfg = Debug|Any CPU
{DD02C60E-560B-40C0-AD7F-523F0B4AA4FD}.Debug|x86.Build.0 = Debug|Any CPU
{DD02C60E-560B-40C0-AD7F-523F0B4AA4FD}.Debug1|Any CPU.ActiveCfg = Debug1|Any CPU
{DD02C60E-560B-40C0-AD7F-523F0B4AA4FD}.Debug1|Any CPU.Build.0 = Debug1|Any CPU
{DD02C60E-560B-40C0-AD7F-523F0B4AA4FD}.Debug1|x64.ActiveCfg = Debug1|x64
{DD02C60E-560B-40C0-AD7F-523F0B4AA4FD}.Debug1|x64.Build.0 = Debug1|x64
{DD02C60E-560B-40C0-AD7F-523F0B4AA4FD}.Debug1|x86.ActiveCfg = Debug1|Any CPU
{DD02C60E-560B-40C0-AD7F-523F0B4AA4FD}.Debug1|x86.Build.0 = Debug1|Any CPU
{DD02C60E-560B-40C0-AD7F-523F0B4AA4FD}.Release|Any CPU.ActiveCfg = Release|Any CPU
{DD02C60E-560B-40C0-AD7F-523F0B4AA4FD}.Release|Any CPU.Build.0 = Release|Any CPU
{DD02C60E-560B-40C0-AD7F-523F0B4AA4FD}.Release|x64.ActiveCfg = Release|x64
{DD02C60E-560B-40C0-AD7F-523F0B4AA4FD}.Release|x64.Build.0 = Release|x64
{DD02C60E-560B-40C0-AD7F-523F0B4AA4FD}.Release|x86.ActiveCfg = Release|Any CPU
{DD02C60E-560B-40C0-AD7F-523F0B4AA4FD}.Release|x86.Build.0 = Release|Any CPU
{741F6491-57C7-479A-B391-09BBA9FBA9DC}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{741F6491-57C7-479A-B391-09BBA9FBA9DC}.Debug|Any CPU.Build.0 = Debug|Any CPU
{741F6491-57C7-479A-B391-09BBA9FBA9DC}.Debug|x64.ActiveCfg = Debug|x64
{741F6491-57C7-479A-B391-09BBA9FBA9DC}.Debug|x64.Build.0 = Debug|x64
{741F6491-57C7-479A-B391-09BBA9FBA9DC}.Debug|x86.ActiveCfg = Debug|Any CPU
{741F6491-57C7-479A-B391-09BBA9FBA9DC}.Debug|x86.Build.0 = Debug|Any CPU
{741F6491-57C7-479A-B391-09BBA9FBA9DC}.Debug1|Any CPU.ActiveCfg = Debug1|Any CPU
{741F6491-57C7-479A-B391-09BBA9FBA9DC}.Debug1|Any CPU.Build.0 = Debug1|Any CPU
{741F6491-57C7-479A-B391-09BBA9FBA9DC}.Debug1|x64.ActiveCfg = Debug1|x64
{741F6491-57C7-479A-B391-09BBA9FBA9DC}.Debug1|x64.Build.0 = Debug1|x64
{741F6491-57C7-479A-B391-09BBA9FBA9DC}.Debug1|x86.ActiveCfg = Debug1|Any CPU
{741F6491-57C7-479A-B391-09BBA9FBA9DC}.Debug1|x86.Build.0 = Debug1|Any CPU
{741F6491-57C7-479A-B391-09BBA9FBA9DC}.Release|Any CPU.ActiveCfg = Release|Any CPU
{741F6491-57C7-479A-B391-09BBA9FBA9DC}.Release|Any CPU.Build.0 = Release|Any CPU
{741F6491-57C7-479A-B391-09BBA9FBA9DC}.Release|x64.ActiveCfg = Release|x64
{741F6491-57C7-479A-B391-09BBA9FBA9DC}.Release|x64.Build.0 = Release|x64
{741F6491-57C7-479A-B391-09BBA9FBA9DC}.Release|x86.ActiveCfg = Release|Any CPU
{741F6491-57C7-479A-B391-09BBA9FBA9DC}.Release|x86.Build.0 = Release|Any CPU
{9EB9DFC1-C78A-46C0-826A-5ED1A08232C0}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{9EB9DFC1-C78A-46C0-826A-5ED1A08232C0}.Debug|Any CPU.Build.0 = Debug|Any CPU
{9EB9DFC1-C78A-46C0-826A-5ED1A08232C0}.Debug|x64.ActiveCfg = Debug|Any CPU
{9EB9DFC1-C78A-46C0-826A-5ED1A08232C0}.Debug|x64.Build.0 = Debug|Any CPU
{9EB9DFC1-C78A-46C0-826A-5ED1A08232C0}.Debug|x86.ActiveCfg = Debug|Any CPU
{9EB9DFC1-C78A-46C0-826A-5ED1A08232C0}.Debug|x86.Build.0 = Debug|Any CPU
{9EB9DFC1-C78A-46C0-826A-5ED1A08232C0}.Debug1|Any CPU.ActiveCfg = Debug|Any CPU
{9EB9DFC1-C78A-46C0-826A-5ED1A08232C0}.Debug1|Any CPU.Build.0 = Debug|Any CPU
{9EB9DFC1-C78A-46C0-826A-5ED1A08232C0}.Debug1|x64.ActiveCfg = Debug|Any CPU
{9EB9DFC1-C78A-46C0-826A-5ED1A08232C0}.Debug1|x64.Build.0 = Debug|Any CPU
{9EB9DFC1-C78A-46C0-826A-5ED1A08232C0}.Debug1|x86.ActiveCfg = Debug|Any CPU
{9EB9DFC1-C78A-46C0-826A-5ED1A08232C0}.Debug1|x86.Build.0 = Debug|Any CPU
{9EB9DFC1-C78A-46C0-826A-5ED1A08232C0}.Release|Any CPU.ActiveCfg = Release|Any CPU
{9EB9DFC1-C78A-46C0-826A-5ED1A08232C0}.Release|Any CPU.Build.0 = Release|Any CPU
{9EB9DFC1-C78A-46C0-826A-5ED1A08232C0}.Release|x64.ActiveCfg = Release|Any CPU
{9EB9DFC1-C78A-46C0-826A-5ED1A08232C0}.Release|x64.Build.0 = Release|Any CPU
{9EB9DFC1-C78A-46C0-826A-5ED1A08232C0}.Release|x86.ActiveCfg = Release|Any CPU
{9EB9DFC1-C78A-46C0-826A-5ED1A08232C0}.Release|x86.Build.0 = Release|Any CPU
{560CC80B-389B-46FC-9B8C-DA1D62A555D9}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{560CC80B-389B-46FC-9B8C-DA1D62A555D9}.Debug|Any CPU.Build.0 = Debug|Any CPU
{560CC80B-389B-46FC-9B8C-DA1D62A555D9}.Debug|x64.ActiveCfg = Debug|Any CPU
{560CC80B-389B-46FC-9B8C-DA1D62A555D9}.Debug|x64.Build.0 = Debug|Any CPU
{560CC80B-389B-46FC-9B8C-DA1D62A555D9}.Debug|x86.ActiveCfg = Debug|Any CPU
{560CC80B-389B-46FC-9B8C-DA1D62A555D9}.Debug|x86.Build.0 = Debug|Any CPU
{560CC80B-389B-46FC-9B8C-DA1D62A555D9}.Debug1|Any CPU.ActiveCfg = Debug|Any CPU
{560CC80B-389B-46FC-9B8C-DA1D62A555D9}.Debug1|Any CPU.Build.0 = Debug|Any CPU
{560CC80B-389B-46FC-9B8C-DA1D62A555D9}.Debug1|x64.ActiveCfg = Debug|Any CPU
{560CC80B-389B-46FC-9B8C-DA1D62A555D9}.Debug1|x64.Build.0 = Debug|Any CPU
{560CC80B-389B-46FC-9B8C-DA1D62A555D9}.Debug1|x86.ActiveCfg = Debug|Any CPU
{560CC80B-389B-46FC-9B8C-DA1D62A555D9}.Debug1|x86.Build.0 = Debug|Any CPU
{560CC80B-389B-46FC-9B8C-DA1D62A555D9}.Release|Any CPU.ActiveCfg = Release|Any CPU
{560CC80B-389B-46FC-9B8C-DA1D62A555D9}.Release|Any CPU.Build.0 = Release|Any CPU
{560CC80B-389B-46FC-9B8C-DA1D62A555D9}.Release|x64.ActiveCfg = Release|Any CPU
{560CC80B-389B-46FC-9B8C-DA1D62A555D9}.Release|x64.Build.0 = Release|Any CPU
{560CC80B-389B-46FC-9B8C-DA1D62A555D9}.Release|x86.ActiveCfg = Release|Any CPU
{560CC80B-389B-46FC-9B8C-DA1D62A555D9}.Release|x86.Build.0 = Release|Any CPU
{8FA74161-0D03-408F-811A-A244C9027BFB}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{8FA74161-0D03-408F-811A-A244C9027BFB}.Debug|Any CPU.Build.0 = Debug|Any CPU
{8FA74161-0D03-408F-811A-A244C9027BFB}.Debug|x64.ActiveCfg = Debug|Any CPU
{8FA74161-0D03-408F-811A-A244C9027BFB}.Debug|x64.Build.0 = Debug|Any CPU
{8FA74161-0D03-408F-811A-A244C9027BFB}.Debug|x86.ActiveCfg = Debug|Any CPU
{8FA74161-0D03-408F-811A-A244C9027BFB}.Debug|x86.Build.0 = Debug|Any CPU
{8FA74161-0D03-408F-811A-A244C9027BFB}.Debug1|Any CPU.ActiveCfg = Debug|Any CPU
{8FA74161-0D03-408F-811A-A244C9027BFB}.Debug1|Any CPU.Build.0 = Debug|Any CPU
{8FA74161-0D03-408F-811A-A244C9027BFB}.Debug1|x64.ActiveCfg = Debug|Any CPU
{8FA74161-0D03-408F-811A-A244C9027BFB}.Debug1|x64.Build.0 = Debug|Any CPU
{8FA74161-0D03-408F-811A-A244C9027BFB}.Debug1|x86.ActiveCfg = Debug|Any CPU
{8FA74161-0D03-408F-811A-A244C9027BFB}.Debug1|x86.Build.0 = Debug|Any CPU
{8FA74161-0D03-408F-811A-A244C9027BFB}.Release|Any CPU.ActiveCfg = Release|Any CPU
{8FA74161-0D03-408F-811A-A244C9027BFB}.Release|Any CPU.Build.0 = Release|Any CPU
{8FA74161-0D03-408F-811A-A244C9027BFB}.Release|x64.ActiveCfg = Release|Any CPU
{8FA74161-0D03-408F-811A-A244C9027BFB}.Release|x64.Build.0 = Release|Any CPU
{8FA74161-0D03-408F-811A-A244C9027BFB}.Release|x86.ActiveCfg = Release|Any CPU
{8FA74161-0D03-408F-811A-A244C9027BFB}.Release|x86.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
GlobalSection(NestedProjects) = preSolution
{987308DD-8BAA-463A-94E2-77D62E01A5BF} = {2BE63CDD-DAEF-4C50-BE1C-73EC5AC5A578}
{1A3CBFE7-3F78-42C3-95C5-10360450DBEA} = {2BE63CDD-DAEF-4C50-BE1C-73EC5AC5A578}
{197C5AA8-9609-4D1C-B1E3-5879006EAAF4} = {DD1CE747-341A-4419-8398-0D482E02DE54}
{E6429C64-92B3-46A2-B35E-579856D47F62} = {97C226B4-971C-4802-8D35-14E2980FF0C6}
{DD02C60E-560B-40C0-AD7F-523F0B4AA4FD} = {97C226B4-971C-4802-8D35-14E2980FF0C6}
{741F6491-57C7-479A-B391-09BBA9FBA9DC} = {97C226B4-971C-4802-8D35-14E2980FF0C6}
{9EB9DFC1-C78A-46C0-826A-5ED1A08232C0} = {DD1CE747-341A-4419-8398-0D482E02DE54}
{560CC80B-389B-46FC-9B8C-DA1D62A555D9} = {5DB27B2D-14A5-441F-A861-BAFDB7BAA05B}
{8FA74161-0D03-408F-811A-A244C9027BFB} = {5DB27B2D-14A5-441F-A861-BAFDB7BAA05B}
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {4BF9CC66-BB0E-4400-BCF8-5BF7F5DA800A}
EndGlobalSection
EndGlobal

1
README.md Normal file
View File

@ -0,0 +1 @@
## PFW

Binary file not shown.

BIN
libs/HslCommunication.dll Normal file

Binary file not shown.

Binary file not shown.

View File

@ -0,0 +1,39 @@
<?xml version="1.0" encoding="UTF-8"?>
<hdevelop file_version="1.1" halcon_version="12.0">
<procedure name="LoadModel">
<interface>
<ic>
<par name="INPUT_Model" base_type="ctrl" dimension="0"/>
</ic>
<oc>
<par name="OUTPUT_ModelID" base_type="ctrl" dimension="0"/>
<par name="OUTPUT_Flag" base_type="ctrl" dimension="0"/>
</oc>
</interface>
<body>
<l>try</l>
<l> OUTPUT_Flag:=0</l>
<l>* OUTPUT_ModelID:=''</l>
<l> tuple_length (INPUT_Model, lenght)</l>
<l> switch(lenght)</l>
<l> case 1:</l>
<l> read_ncc_model (INPUT_Model, OUTPUT_ModelID)</l>
<l>* OUTPUT_ModelID :=ModelID</l>
<l> break</l>
<l> endswitch</l>
<l> OUTPUT_Flag:=1</l>
<l>catch (Exception)</l>
<l> OUTPUT_Flag:=0</l>
<l>endtry</l>
<c></c>
<l>return ()</l>
</body>
<docu id="LoadModel">
<parameters>
<parameter id="INPUT_Model"/>
<parameter id="OUTPUT_Flag"/>
<parameter id="OUTPUT_ModelID"/>
</parameters>
</docu>
</procedure>
</hdevelop>

View File

@ -0,0 +1,77 @@
<?xml version="1.0" encoding="UTF-8"?>
<hdevelop file_version="1.1" halcon_version="12.0">
<procedure name="MatchResult">
<interface>
<io>
<par name="INPUT_Image" base_type="iconic" dimension="0"/>
</io>
<oo>
<par name="OUTPUT_PreTreatedImage" base_type="iconic" dimension="0"/>
</oo>
<ic>
<par name="ModelID" base_type="ctrl" dimension="0"/>
</ic>
<oc>
<par name="OUTPUT_Flag" base_type="ctrl" dimension="0"/>
</oc>
</interface>
<body>
<l>try</l>
<l> OUTPUT_Flag:=0</l>
<l> rgb1_to_gray(INPUT_Image, INPUT_Image)</l>
<c> *把图片外围干扰因素剔除</c>
<c> **** draw_spoke(Image, Regions, 3600, 30, 60, 15, ROIRows, ROICols, Direct)</c>
<l> ROIRows:=[1584.25, 1216.88, 661.489, 297.014, 297.014, 649.918, 1130.1, 1497.47, 1584.25]</l>
<l> ROICols:=[1158.75, 800.276, 762.869, 1096.41, 1751.02, 2050.27, 2084.56, 1819.6, 1158.75]</l>
<l> spoke (INPUT_Image, Regions1, 50, 90, 15, 3, 20, 'all', 'first', ROIRows, ROICols, 'inner', ResultRow, ResultColumn, ArcType)</l>
<l> pts_to_best_circle(Circle, ResultRow, ResultColumn, 'circle', 40, OUTPUT_RowCentre, OUTPUT_ColCentre, Radius, StartPhi, EndPhi, PointOrder, ArcAngle)</l>
<l>* dev_display (INPUT_Image)</l>
<l>* dev_display(Circle)</l>
<l> if(|Radius|=1)</l>
<l> gen_circle(Circle1, OUTPUT_RowCentre, OUTPUT_ColCentre, Radius)</l>
<l> reduce_domain (INPUT_Image, Circle1, ImageReduced)</l>
<l> gen_circle(Circle2, OUTPUT_RowCentre, OUTPUT_ColCentre, Radius*0.74)</l>
<l> reduce_domain(ImageReduced, Circle2, ImageReduced1)</l>
<l> difference(ImageReduced, ImageReduced1, RegionDifference)</l>
<c> </c>
<l> reduce_domain (INPUT_Image, RegionDifference, ImageReduced2)</l>
<l> zoom_image_factor(ImageReduced2, ImageZoomed, 0.9, 0.9, 'constant')</l>
<l> get_region_points(ImageZoomed, Rows, Columns)</l>
<l> get_grayval(ImageZoomed, Rows, Columns, Grayval)</l>
<l> gen_image_const(OUTPUT_PreTreatedImage, 'byte', 1440, 1440)</l>
<l> gen_image_proto(OUTPUT_PreTreatedImage, OUTPUT_PreTreatedImage, 255)</l>
<l> set_grayval(OUTPUT_PreTreatedImage, Rows-OUTPUT_RowCentre*0.9+720, Columns-OUTPUT_ColCentre*0.9+720, Grayval)</l>
<c> *查找模板,并对图片进行旋转</c>
<l> find_ncc_model(OUTPUT_PreTreatedImage, ModelID, -3.14, 3.14, 0.3, 1, 0.5, 'true', 0, Row, Column, Angle, Score)</l>
<l>* Angle:=Angle</l>
<l> if(|Angle|=1)</l>
<l> tuple_deg(Angle,Deg ) </l>
<l> rotate_image(OUTPUT_PreTreatedImage, ImageRotate, -Deg, 'constant')</l>
<l> gen_circle(Circle3, 720, 720, Radius*0.95)</l>
<l> reduce_domain(ImageRotate, Circle3, ImageReduced3)</l>
<l> get_region_points(ImageReduced3, Rows, Columns)</l>
<l> get_grayval(ImageReduced3, Rows, Columns, Grayval)</l>
<l> gen_image_const(OUTPUT_PreTreatedImage, 'byte', 1440, 1440)</l>
<l> gen_image_proto(OUTPUT_PreTreatedImage, OUTPUT_PreTreatedImage, 255)</l>
<l> set_grayval(OUTPUT_PreTreatedImage, Rows, Columns, Grayval)</l>
<l> OUTPUT_Flag:=1</l>
<l> else</l>
<l> OUTPUT_Flag:=1</l>
<l> endif</l>
<l> endif</l>
<l>catch (Exception)</l>
<l> OUTPUT_Flag:=0</l>
<l> zoom_image_size(INPUT_Image, OUTPUT_PreTreatedImage, 1440, 1440, 'constant')</l>
<l>endtry</l>
<l>return ()</l>
</body>
<docu id="MatchResult">
<parameters>
<parameter id="INPUT_Image"/>
<parameter id="ModelID"/>
<parameter id="OUTPUT_Flag"/>
<parameter id="OUTPUT_PreTreatedImage"/>
</parameters>
</docu>
</procedure>
</hdevelop>

BIN
libs/NBVision/AVL_Lite.dll Normal file

Binary file not shown.

Binary file not shown.

BIN
libs/NBVision/NBddraw.dll Normal file

Binary file not shown.

Binary file not shown.

BIN
libs/NBVision/libglog.dll Normal file

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

BIN
libs/NBVision/ws2_32.dll Normal file

Binary file not shown.

Binary file not shown.

510
libs/SRLib/32bit/SR7Link.h Normal file
View File

@ -0,0 +1,510 @@
#ifndef SR7LINK__H
#define SR7LINK__H
#include <stdio.h>
#ifdef WIN32
#define SR7_IF_API __declspec(dllexport)
#else
#define SR7_IF_API extern
#endif
typedef void * SR7IF_Data;
/// \brief 高速数据通信的回调函数接口.
/// \param pBuffer 指向储存概要数据的缓冲区的指针.
/// \param dwSize 每个单元(行)的字节数量.
/// \param dwCount 存储在pBuffer中的内存的单元数量.
/// \param dwNotify 中断或批量结束等中断的通知.
/// \param dwUser 用户自定义信息.
///
typedef void (*SR7IF_CALLBACK)(char* pBuffer, unsigned int dwSize, unsigned int dwCount, unsigned int dwNotify, unsigned int dwUser);
typedef void (*SR7IF_BatchOneTimeCallBack)(const void *info, const SR7IF_Data *data);
typedef struct {
unsigned char abyIpAddress[4];
} SR7IF_ETHERNET_CONFIG;
#define SR7IF_ERROR_NOT_FOUND (-999) // 功能(相机)不存在.
#define SR7IF_ERROR_COMMAND (-998) // 该命令不支持.
#define SR7IF_ERROR_PARAMETER (-997) // 参数错误.
#define SR7IF_ERROR_UNIMPLEMENTED (-996) // 功能未实现.
#define SR7IF_ERROR_HANDLE (-995) // 句柄无效.
#define SR7IF_ERROR_MEMORY (-994) // 内存(溢出/定义)错误.
#define SR7IF_ERROR_TIMEOUT (-993) // 操作超时.
#define SR7IF_ERROR_DATABUFFER (-992) // 数据大缓冲区不足.
#define SR7IF_ERROR_STREAM (-991) // 数据流错误.
#define SR7IF_ERROR_CLOSED (-990) // 接口关闭不可用.
#define SR7IF_ERROR_VERSION (-989) // 当前版本无效.
#define SR7IF_ERROR_ABORT (-988) // 操作被终止,如连接被关闭、连接中断等.
#define SR7IF_ERROR_ALREADY_EXISTS (-987) // 操作和现有的设置冲突.
#define SR7IF_ERROR_FRAME_LOSS (-986) // 批处理帧丢失.
#define SR7IF_ERROR_ROLL_DATA_OVERFLOW (-985) // 无终止循环批处理出现溢出异常等.
#define SR7IF_ERROR_ROLL_BUSY (-984) // 无终止循环批处理读数据忙.
#define SR7IF_ERROR_MODE (-983) // 当前处理函数与设置的批处理模式有冲突.
#define SR7IF_ERROR_CAMERA_NOT_ONLINE (-982) // 相机(传感头)不在线.
#define SR7IF_ERROR (-1) // 一般性错误,如设置失败、数据获取失败等.
#define SR7IF_NORMAL_STOP (-100) // 正常停止如外部IO停止批处理操作等.
#define SR7IF_OK (0) // 正确操作.
#ifdef __cplusplus
extern "C" {
#endif
///
/// \brief SR7IF_EthernetOpen 通信连接.
/// \param lDeviceId 设备ID号范围为0-3.
/// \param pEthernetConfig Ethernet 通信设定.
/// \return
/// <0: 失败.
/// =0: 成功.
///
SR7_IF_API int SR7IF_EthernetOpen(unsigned int lDeviceId, SR7IF_ETHERNET_CONFIG* pEthernetConfig);
///
/// \brief SR7IF_CommClose 断开与相机的连接.
/// \param lDeviceId 设备ID号范围为0-3.
/// \return
/// <0: 失败.
/// =0: 成功.
///
SR7_IF_API int SR7IF_CommClose(unsigned int lDeviceId);
///
/// \brief SR7IF_SwitchProgram 切换相机配置的参数.重启后不保存配方号.
/// \param lDeviceId 设备ID号范围为0-3.
/// \param No: 任务参数列表编号 0 - 63.
/// \return
/// <0: 失败.
/// =0: 成功.
///
SR7_IF_API int SR7IF_SwitchProgram(unsigned int lDeviceId, int No);
///
/// \brief SR7IF_GetOnlineCameraB 获取传感头B是否在线
/// \param lDeviceId 设备ID号范围为0-3.
/// \return
/// <0: -982:传感头B不在线
/// 其他:获取失败
/// =0: 传感头B在线
///
SR7_IF_API int SR7IF_GetOnlineCameraB(unsigned int lDeviceId);
///
/// \brief SR7IF_StartMeasure 开始批处理,立即执行批处理程序.
/// \param lDeviceId 设备ID号范围为0-3.
/// \param Timeout 非循环获取时,超时时间(单位ms);循环模式该参数可设置为-1.
/// \return
/// <0: 失败
/// =0: 成功
///
SR7_IF_API int SR7IF_StartMeasure(unsigned int lDeviceId, int Timeout = 50000);
/// \brief SR7IF_StartIOTriggerMeasure 开始批处理,硬件IO触发开始批处理具体查看硬件手册.
/// \param lDeviceId 设备ID号范围为0-3.
/// \param Timeout 非循环获取时,超时时间(单位ms);循环模式该参数可设置为-1.
/// \param restart 预留设为0.
/// \return
/// <0: 失败
/// =0: 成功
///
SR7_IF_API int SR7IF_StartIOTriggerMeasure(unsigned int lDeviceId, int Timeout = 50000, int restart = 0);
///
/// \brief SR7IF_StopMeasure 停止批处理
/// \param lDeviceId 设备ID号范围为0-3.
/// \return
/// <0: 失败.
/// =0: 成功.
///
SR7_IF_API int SR7IF_StopMeasure(unsigned int lDeviceId);
/// \brief SR7IF_ReceiveData 阻塞方式获取数据.
/// \param lDeviceId 设备ID号范围为0-3.
/// \param DataObj 返回数据指针.
/// \return
/// <0: 获取失败.
/// =0: 成功.
///
SR7_IF_API int SR7IF_ReceiveData(unsigned int lDeviceId, SR7IF_Data DataObj);
/// \brief SR7IF_ProfilePointSetCount 获取当前批处理设定行数
/// \param lDeviceId 设备ID号范围为0-3
/// \param DataObj 预留设置为NULL
/// \return 返回实际批处理行数
///
SR7_IF_API int SR7IF_ProfilePointSetCount(unsigned int lDeviceId, const SR7IF_Data DataObj);
/// \brief SR7IF_ProfilePointCount 获取批处理实际获取行数.
/// \param lDeviceId 设备ID号范围为0-3.
/// \param DataObj 预留设置为NULL.
/// \return 返回批处理实际获取行数.
///
SR7_IF_API int SR7IF_ProfilePointCount(unsigned int lDeviceId, const SR7IF_Data DataObj);
/// \brief SR7IF_ProfileDataWidth 获取数据宽度.
/// \param lDeviceId 设备ID号范围为0-3.
/// \param DataObj 预留设置为NULL.
/// \return 返回数据宽度(单位像素).
///
SR7_IF_API int SR7IF_ProfileDataWidth(unsigned int lDeviceId, const SR7IF_Data DataObj);
///
/// \brief SR7IF_ProfileData_XPitch 获取数据x方向间距.
/// \param lDeviceId 设备ID号范围为0-3.
/// \param DataObj 预留设置为NULL.
/// \return 返回数据x方向间距(mm).
///
SR7_IF_API double SR7IF_ProfileData_XPitch(unsigned int lDeviceId, const SR7IF_Data DataObj);
///
/// \brief SR7IF_GetEncoder 获取编码器值
/// \param lDeviceId 设备ID号范围为0-3.
/// \param DataObj 预留设置为NULL
/// \param Encoder 返回数据指针,双相机为A/B交替数据
/// \return
/// <0: 获取失败.
/// =0: 成功.
///
SR7_IF_API int SR7IF_GetEncoder(unsigned int lDeviceId, const SR7IF_Data DataObj, unsigned int *Encoder);
///
/// \brief SR7IF_GetEncoderContiune 非阻塞方式获取编码器值
/// \param lDeviceId 设备ID号范围为0-3.
/// \param DataObj 预留设置为NULL
/// \param Encoder 返回数据指针,双相机为A/B交替数据
/// \param GetCnt 获取数据长度
/// \return
/// <0: 获取失败.
/// >=0: 实际返回的数据长度.
///
SR7_IF_API int SR7IF_GetEncoderContiune(unsigned int lDeviceId, const SR7IF_Data DataObj, unsigned int *Encoder, unsigned int GetCnt);
///
/// \brief SR7IF_GetProfileData 阻塞方式获取轮廓数据
/// \param lDeviceId 设备ID号范围为0-3.
/// \param DataObj 预留设置为NULL
/// \param Profile 返回数据指针,双相机为A/B行交替数据
/// \return
/// <0: 获取失败.
/// =0: 成功.
///
SR7_IF_API int SR7IF_GetProfileData(unsigned int lDeviceId, const SR7IF_Data DataObj, int *Profile);
///
/// \brief SR7IF_GetProfileContiuneData 非阻塞方式获取轮廓数据
/// \param lDeviceId 设备ID号范围为0-3.
/// \param DataObj 预留设置为NULL
/// \param Profile 返回数据指针,双相机为A/B行交替数据
/// \param GetCnt 获取数据长度
/// \return
/// <0: 获取失败.
/// >=0: 实际返回的数据长度.
///
SR7_IF_API int SR7IF_GetProfileContiuneData(unsigned int lDeviceId, const SR7IF_Data DataObj, int *Profile, unsigned int GetCnt);
///
/// \brief SR7IF_GetIntensityData 阻塞方式获取亮度数据
/// \param lDeviceId 设备ID号范围为0-3.
/// \param DataObj 预留设置为NULL
/// \param Intensity 返回数据指针,双相机为A/B行交替数据
/// \return
/// <0: 获取失败.
/// =0: 成功.
///
SR7_IF_API int SR7IF_GetIntensityData(unsigned int lDeviceId, const SR7IF_Data DataObj, unsigned char *Intensity);
///
/// \brief SR7IF_GetIntensityContiuneData 非阻塞获取亮度数据
/// \param lDeviceId 设备ID号范围为0-3.
/// \param DataObj 预留设置为NULL
/// \param Intensity 返回数据指针,双相机为A/B行交替数据
/// \param GetCnt 获取数据长度
/// \return
/// <0: 获取失败.
/// >=0: 返回获实际数据行数.
///
SR7_IF_API int SR7IF_GetIntensityContiuneData(unsigned int lDeviceId, const SR7IF_Data DataObj, unsigned char *Intensity, unsigned int GetCnt);
///
/// \brief SR7IF_GetBatchRollData 无终止循环获取数据
/// \param lDeviceId 设备ID号范围为0-3.
/// \param DataObj 预留设置为NULL
/// \param Profile 返回轮廓数据指针,双相机为A/B行交替数据
/// \param Intensity 返回亮度数据指针,双相机为A/B行交替数据
/// \param Encoder 返回编码器数据指针,双相机为A/B交替数据
/// \param FrameId 返回帧编号数据指针
/// \param FrameLoss 返回批处理过快掉帧数量数据指针,双相机为A/B交替数据
/// \param GetCnt 获取数据长度
/// \return
/// <0: 获取失败.
/// >=0: 实际返回的数据长度.
///
SR7_IF_API int SR7IF_GetBatchRollData(unsigned int lDeviceId, const SR7IF_Data DataObj,
int *Profile, unsigned char *Intensity, unsigned int *Encoder, long long *FrameId, unsigned int *FrameLoss,
unsigned int GetCnt);
///
/// \brief SR7IF_GetError 获取系统错误信息
/// \param lDeviceId 设备ID号范围为0-3.
/// \param pbyErrCnt 返回错误码数量
/// \param pwErrCode 返回错误码指针
/// \return
/// <0: 获取失败.
/// =0: 成功.
///
SR7_IF_API int SR7IF_GetError(unsigned int lDeviceId, int *pbyErrCnt, int *pwErrCode);
///
/// \brief SR7IF_GetBatchRollError 无终止循环获取数据异常计算值
/// \param lDeviceId 设备ID号范围为0-3.
/// \param EthErrCnt 返回网络传输导致错误的数量
/// \param UserErrCnt 返回用户获取导致错误的数量
/// \return
/// <0: 获取失败.
/// =0: 成功.
///
SR7_IF_API int SR7IF_GetBatchRollError(unsigned int lDeviceId, int *EthErrCnt, int *UserErrCnt);
///
/// \brief SR7IF_ClearError 暂无
/// \param lDeviceId
/// \param wErrCode
/// \return
/// <0: 清除失败
/// =0: 成功
///
SR7_IF_API int SR7IF_ClearError(unsigned int lDeviceId, unsigned short wErrCode);
///
/// \brief SR7IF_GetVersion 获取库版本号.
/// \return 返回版本信息.
///
SR7_IF_API const char *SR7IF_GetVersion();
///
/// \brief SR7IF_GetModels 获取相机型号.
/// \param lDeviceId 设备ID号范围为0-3.
/// \return 返回相机型号字符串.
///
SR7_IF_API const char *SR7IF_GetModels(unsigned int lDeviceId);
///
/// \brief SR7IF_GetHeaderSerial 获取相机头序列号
/// \param lDeviceId 设备ID号范围为0-3.
/// \param Head 0相机头A 1相机头B
/// \return
/// !=NULL: 返回相机序列号字符串.
/// =NULL: 失败,相应头不存在或者参数错误.
///
SR7_IF_API const char *SR7IF_GetHeaderSerial(unsigned int lDeviceId, int Head);
/// 高速数据通信相关
///
/// \brief SR7IF_HighSpeedDataEthernetCommunicationInitalize 初始化以太网高速数据通信.
/// \param lDeviceId 设备ID号范围为0-3.
/// \param pEthernetConfig Ethernet 通信设定.
/// \param wHighSpeedPortNo Ethernet 通信端口设定.
/// \param pCallBack 高速通信中数据接收的回调函数.
/// \param dwProfileCnt 回调函数被调用的频率. 范围1-256
/// \param dwThreadId 线程号.
/// \return
/// <0: 失败.
/// =0: 成功.
///
SR7_IF_API int SR7IF_HighSpeedDataEthernetCommunicationInitalize(unsigned int lDeviceId, SR7IF_ETHERNET_CONFIG* pEthernetConfig, int wHighSpeedPortNo,
SR7IF_CALLBACK pCallBack, unsigned int dwProfileCnt, unsigned int dwThreadId);
///
/// \brief SR7IF_SetOutputPortLevel 设置输出端口电平.
/// \param lDeviceId 设备ID号范围为0-3.
/// \param Port 输出端口号范围为0-7.
/// \param Level 输出电平值.
/// \return
/// <0: 失败.
/// =0: 成功.
///
SR7_IF_API int SR7IF_SetOutputPortLevel(unsigned int lDeviceId, unsigned int Port, bool Level);
///
/// \brief SR7IF_SetOutputPortLevel 读取输入端口电平.
/// \param lDeviceId 设备ID号范围为0-3.
/// \param Port 输入端口号范围为0-7.
/// \param Level 读取输入电平.
/// \return
/// <0: 失败.
/// =0: 成功.
///
SR7_IF_API int SR7IF_GetInputPortLevel(unsigned int lDeviceId, unsigned int Port, bool *Level);
///
/// \brief SR7IF_GetSingleProfile 获取当前一条轮廓(非批处理下,需在EdgeImaging中设置为2.5D模式)
/// \param lDeviceId 设备ID号范围为0-3.
/// \param pProfileData 返回轮廓的指针.
/// \param pEncoder 返回编码器的指针.
/// \return
/// <0: 失败.
/// =0: 成功.
///
SR7_IF_API int SR7IF_GetSingleProfile(unsigned int lDeviceId, int *pProfileData, unsigned int *pEncoder);
///
/// \brief SR7IF_SetSetting 参数设定.
/// \param lDeviceId 设备ID号范围为0-3.
/// \param Depth 设置的值的级别.
/// \param Type 设置类型.
/// \param Category 设置种类.
/// \param Item 设置项目.
/// \param Target[4] 根据发送 / 接收的设定,可能需要进行相应的指定。无需设定时,指定为 0。
/// \param pData 设置数据.
/// \param DataSize 设置数据的长度.
/// \return
/// <0: 失败.
/// =0: 成功.
///
SR7_IF_API int SR7IF_SetSetting(unsigned int lDeviceId, int Depth, int Type, int Category, int Item, int Target[4], void *pData, int DataSize);
///
/// \brief SR7IF_GetSetting 参数设定.
/// \param lDeviceId 设备ID号范围为0-3.
/// \param Type 获取类型.
/// \param Category 获取种类.
/// \param Item 获取项目.
/// \param Target[4] 根据发送 / 接收的设定,可能需要进行相应的指定。无需设定时,指定为 0。
/// \param pData 获取的数据.
/// \param DataSize 获取数据的长度.
/// \return
/// <0: 失败.
/// =0: 成功.
///
SR7_IF_API int SR7IF_GetSetting(unsigned int lDeviceId, int Type, int Category, int Item, int Target[4], void *pData, int DataSize);
///
/// \brief SR7IF_ExportParameters 将系统参数导出,注意只导出当前任务的参数.
/// \param lDeviceId 设备ID号范围为0-3.
/// \param size 返回参数表的大小.
/// \return
/// NULL: 失败.
/// 其他: 成功.
///
SR7_IF_API const char *SR7IF_ExportParameters(unsigned int lDeviceId, unsigned int *size);
///
/// \brief SR7IF_LoadParameters 将导出的参数导入到系统中.
/// \param lDeviceId 设备ID号范围为0-3.
/// \param pSettingdata 导入参数表指针.
/// \param size 导入参数表的大小.
/// \return
/// <0: 失败.
/// =0: 成功.
///
SR7_IF_API int SR7IF_LoadParameters(unsigned int lDeviceId, const char *pSettingdata, unsigned int size);
///
/// \brief SR7IF_GetLicenseKey 返回产品剩余天数
/// \param RemainDay 返回剩余天数
/// \return
/// < 0: 失败,参数错误或产品未注册
/// >=0: 成功.
///
SR7_IF_API int SR7IF_GetLicenseKey(unsigned int lDeviceId, unsigned short *RemainDay);
///
/// \brief SR7IF_GetCurrentEncoder 读取当前编码器值
/// \param value 返回编码器值
/// \return
/// <0: 失败.
/// =0: 成功.
///
SR7_IF_API int SR7IF_GetCurrentEncoder(unsigned int lDeviceId, unsigned int *value);
//
typedef struct {
int xPoints; //x方向数据数量
int BatchPoints; //批处理数量
unsigned int BatchTimes; //批处理次数
double xPixth; //x方向点间距
unsigned int startEncoder; //批处理开始编码器值
int HeadNumber; //相机头数量
int returnStatus; //SR7IF_OK:正常批处理
//SR7IF_NORMAL_STOP
//SR7IF_ERROR_ABORT
//SR7IF_ERROR_CLOSED
} SR7IF_STR_CALLBACK_INFO;
///
/// \brief SR7IF_SetBatchOneTimeDataHandler 设置回调函数,建议获取数据后另外开启线程进行处理(获取数据模式:批处理一次回调一次)
/// \param lDeviceId 设备ID号范围为0-3.
/// \param CallFunc 回调函数.
/// \return
/// <0: 失败.
/// =0: 成功.
///
SR7_IF_API int SR7IF_SetBatchOneTimeDataHandler(unsigned int lDeviceId, SR7IF_BatchOneTimeCallBack CallFunc);
///
/// \brief SR7IF_StartMeasureWithCallback 开始批处理(获取数据模式:批处理一次回调一次)
/// \param lDeviceId 设备ID号范围为0-3.
/// \param ImmediateBatch 0:立即开始批处理 1:等待外部开始批处理.
/// \return
/// <0: 失败.
/// =0: 成功.
///
SR7_IF_API int SR7IF_StartMeasureWithCallback(int iDeviceId, int ImmediateBatch);
///
/// \brief SR7IF_TriggerOneBatch 批处理软件触发开始(获取数据模式:批处理一次回调一次)
/// \param lDeviceId 设备ID号范围为0-3.
/// \return
/// <0: 失败.
/// =0: 成功.
///
SR7_IF_API int SR7IF_TriggerOneBatch(int iDeviceId);
///
/// \brief SR7IF_GetBatchProfilePoint 批处理轮廓获取(获取数据模式:批处理一次回调一次)
/// \param lDeviceId 设备ID号范围为0-3.
/// \param Head 0相机头A 1相机头B
/// \return
/// !=NULL: 返回数据指针
/// =NULL: 失败,无数据或者相应头不存在.
///
SR7_IF_API const int *SR7IF_GetBatchProfilePoint(const SR7IF_Data *DataIndex, int Head);
///
/// \brief SR7IF_GetBatchIntensityPoint 批处理亮度获取(获取数据模式:批处理一次回调一次)
/// \param lDeviceId 设备ID号范围为0-3.
/// \param Head 0相机头A 1相机头B
/// \return
/// !=NULL: 返回数据指针
/// =NULL: 失败,无数据或者相应头不存在.
///
SR7_IF_API const unsigned char *SR7IF_GetBatchIntensityPoint(const SR7IF_Data *DataIndex, int Head);
///
/// \brief SR7IF_GetBatchEncoderPoint 批处理编码器获取(获取数据模式:批处理一次回调一次)
/// \param lDeviceId 设备ID号范围为0-3.
/// \param Head 0相机头A 1相机头B
/// \return
/// !=NULL: 返回数据指针
/// =NULL: 失败,无数据或者相应头不存在.
///
SR7_IF_API const unsigned int *SR7IF_GetBatchEncoderPoint(const SR7IF_Data *DataIndex, int Head);
#ifdef __cplusplus
}
#endif
#endif //SR7LINK__H

Binary file not shown.

Binary file not shown.

510
libs/SRLib/64bit/SR7Link.h Normal file
View File

@ -0,0 +1,510 @@
#ifndef SR7LINK__H
#define SR7LINK__H
#include <stdio.h>
#ifdef WIN32
#define SR7_IF_API __declspec(dllexport)
#else
#define SR7_IF_API extern
#endif
typedef void * SR7IF_Data;
/// \brief 高速数据通信的回调函数接口.
/// \param pBuffer 指向储存概要数据的缓冲区的指针.
/// \param dwSize 每个单元(行)的字节数量.
/// \param dwCount 存储在pBuffer中的内存的单元数量.
/// \param dwNotify 中断或批量结束等中断的通知.
/// \param dwUser 用户自定义信息.
///
typedef void (*SR7IF_CALLBACK)(char* pBuffer, unsigned int dwSize, unsigned int dwCount, unsigned int dwNotify, unsigned int dwUser);
typedef void (*SR7IF_BatchOneTimeCallBack)(const void *info, const SR7IF_Data *data);
typedef struct {
unsigned char abyIpAddress[4];
} SR7IF_ETHERNET_CONFIG;
#define SR7IF_ERROR_NOT_FOUND (-999) // 功能(相机)不存在.
#define SR7IF_ERROR_COMMAND (-998) // 该命令不支持.
#define SR7IF_ERROR_PARAMETER (-997) // 参数错误.
#define SR7IF_ERROR_UNIMPLEMENTED (-996) // 功能未实现.
#define SR7IF_ERROR_HANDLE (-995) // 句柄无效.
#define SR7IF_ERROR_MEMORY (-994) // 内存(溢出/定义)错误.
#define SR7IF_ERROR_TIMEOUT (-993) // 操作超时.
#define SR7IF_ERROR_DATABUFFER (-992) // 数据大缓冲区不足.
#define SR7IF_ERROR_STREAM (-991) // 数据流错误.
#define SR7IF_ERROR_CLOSED (-990) // 接口关闭不可用.
#define SR7IF_ERROR_VERSION (-989) // 当前版本无效.
#define SR7IF_ERROR_ABORT (-988) // 操作被终止,如连接被关闭、连接中断等.
#define SR7IF_ERROR_ALREADY_EXISTS (-987) // 操作和现有的设置冲突.
#define SR7IF_ERROR_FRAME_LOSS (-986) // 批处理帧丢失.
#define SR7IF_ERROR_ROLL_DATA_OVERFLOW (-985) // 无终止循环批处理出现溢出异常等.
#define SR7IF_ERROR_ROLL_BUSY (-984) // 无终止循环批处理读数据忙.
#define SR7IF_ERROR_MODE (-983) // 当前处理函数与设置的批处理模式有冲突.
#define SR7IF_ERROR_CAMERA_NOT_ONLINE (-982) // 相机(传感头)不在线.
#define SR7IF_ERROR (-1) // 一般性错误,如设置失败、数据获取失败等.
#define SR7IF_NORMAL_STOP (-100) // 正常停止如外部IO停止批处理操作等.
#define SR7IF_OK (0) // 正确操作.
#ifdef __cplusplus
extern "C" {
#endif
///
/// \brief SR7IF_EthernetOpen 通信连接.
/// \param lDeviceId 设备ID号范围为0-3.
/// \param pEthernetConfig Ethernet 通信设定.
/// \return
/// <0: 失败.
/// =0: 成功.
///
SR7_IF_API int SR7IF_EthernetOpen(unsigned int lDeviceId, SR7IF_ETHERNET_CONFIG* pEthernetConfig);
///
/// \brief SR7IF_CommClose 断开与相机的连接.
/// \param lDeviceId 设备ID号范围为0-3.
/// \return
/// <0: 失败.
/// =0: 成功.
///
SR7_IF_API int SR7IF_CommClose(unsigned int lDeviceId);
///
/// \brief SR7IF_SwitchProgram 切换相机配置的参数.重启后不保存配方号.
/// \param lDeviceId 设备ID号范围为0-3.
/// \param No: 任务参数列表编号 0 - 63.
/// \return
/// <0: 失败.
/// =0: 成功.
///
SR7_IF_API int SR7IF_SwitchProgram(unsigned int lDeviceId, int No);
///
/// \brief SR7IF_GetOnlineCameraB 获取传感头B是否在线
/// \param lDeviceId 设备ID号范围为0-3.
/// \return
/// <0: -982:传感头B不在线
/// 其他:获取失败
/// =0: 传感头B在线
///
SR7_IF_API int SR7IF_GetOnlineCameraB(unsigned int lDeviceId);
///
/// \brief SR7IF_StartMeasure 开始批处理,立即执行批处理程序.
/// \param lDeviceId 设备ID号范围为0-3.
/// \param Timeout 非循环获取时,超时时间(单位ms);循环模式该参数可设置为-1.
/// \return
/// <0: 失败
/// =0: 成功
///
SR7_IF_API int SR7IF_StartMeasure(unsigned int lDeviceId, int Timeout = 50000);
/// \brief SR7IF_StartIOTriggerMeasure 开始批处理,硬件IO触发开始批处理具体查看硬件手册.
/// \param lDeviceId 设备ID号范围为0-3.
/// \param Timeout 非循环获取时,超时时间(单位ms);循环模式该参数可设置为-1.
/// \param restart 预留设为0.
/// \return
/// <0: 失败
/// =0: 成功
///
SR7_IF_API int SR7IF_StartIOTriggerMeasure(unsigned int lDeviceId, int Timeout = 50000, int restart = 0);
///
/// \brief SR7IF_StopMeasure 停止批处理
/// \param lDeviceId 设备ID号范围为0-3.
/// \return
/// <0: 失败.
/// =0: 成功.
///
SR7_IF_API int SR7IF_StopMeasure(unsigned int lDeviceId);
/// \brief SR7IF_ReceiveData 阻塞方式获取数据.
/// \param lDeviceId 设备ID号范围为0-3.
/// \param DataObj 返回数据指针.
/// \return
/// <0: 获取失败.
/// =0: 成功.
///
SR7_IF_API int SR7IF_ReceiveData(unsigned int lDeviceId, SR7IF_Data DataObj);
/// \brief SR7IF_ProfilePointSetCount 获取当前批处理设定行数
/// \param lDeviceId 设备ID号范围为0-3
/// \param DataObj 预留设置为NULL
/// \return 返回实际批处理行数
///
SR7_IF_API int SR7IF_ProfilePointSetCount(unsigned int lDeviceId, const SR7IF_Data DataObj);
/// \brief SR7IF_ProfilePointCount 获取批处理实际获取行数.
/// \param lDeviceId 设备ID号范围为0-3.
/// \param DataObj 预留设置为NULL.
/// \return 返回批处理实际获取行数.
///
SR7_IF_API int SR7IF_ProfilePointCount(unsigned int lDeviceId, const SR7IF_Data DataObj);
/// \brief SR7IF_ProfileDataWidth 获取数据宽度.
/// \param lDeviceId 设备ID号范围为0-3.
/// \param DataObj 预留设置为NULL.
/// \return 返回数据宽度(单位像素).
///
SR7_IF_API int SR7IF_ProfileDataWidth(unsigned int lDeviceId, const SR7IF_Data DataObj);
///
/// \brief SR7IF_ProfileData_XPitch 获取数据x方向间距.
/// \param lDeviceId 设备ID号范围为0-3.
/// \param DataObj 预留设置为NULL.
/// \return 返回数据x方向间距(mm).
///
SR7_IF_API double SR7IF_ProfileData_XPitch(unsigned int lDeviceId, const SR7IF_Data DataObj);
///
/// \brief SR7IF_GetEncoder 获取编码器值
/// \param lDeviceId 设备ID号范围为0-3.
/// \param DataObj 预留设置为NULL
/// \param Encoder 返回数据指针,双相机为A/B交替数据
/// \return
/// <0: 获取失败.
/// =0: 成功.
///
SR7_IF_API int SR7IF_GetEncoder(unsigned int lDeviceId, const SR7IF_Data DataObj, unsigned int *Encoder);
///
/// \brief SR7IF_GetEncoderContiune 非阻塞方式获取编码器值
/// \param lDeviceId 设备ID号范围为0-3.
/// \param DataObj 预留设置为NULL
/// \param Encoder 返回数据指针,双相机为A/B交替数据
/// \param GetCnt 获取数据长度
/// \return
/// <0: 获取失败.
/// >=0: 实际返回的数据长度.
///
SR7_IF_API int SR7IF_GetEncoderContiune(unsigned int lDeviceId, const SR7IF_Data DataObj, unsigned int *Encoder, unsigned int GetCnt);
///
/// \brief SR7IF_GetProfileData 阻塞方式获取轮廓数据
/// \param lDeviceId 设备ID号范围为0-3.
/// \param DataObj 预留设置为NULL
/// \param Profile 返回数据指针,双相机为A/B行交替数据
/// \return
/// <0: 获取失败.
/// =0: 成功.
///
SR7_IF_API int SR7IF_GetProfileData(unsigned int lDeviceId, const SR7IF_Data DataObj, int *Profile);
///
/// \brief SR7IF_GetProfileContiuneData 非阻塞方式获取轮廓数据
/// \param lDeviceId 设备ID号范围为0-3.
/// \param DataObj 预留设置为NULL
/// \param Profile 返回数据指针,双相机为A/B行交替数据
/// \param GetCnt 获取数据长度
/// \return
/// <0: 获取失败.
/// >=0: 实际返回的数据长度.
///
SR7_IF_API int SR7IF_GetProfileContiuneData(unsigned int lDeviceId, const SR7IF_Data DataObj, int *Profile, unsigned int GetCnt);
///
/// \brief SR7IF_GetIntensityData 阻塞方式获取亮度数据
/// \param lDeviceId 设备ID号范围为0-3.
/// \param DataObj 预留设置为NULL
/// \param Intensity 返回数据指针,双相机为A/B行交替数据
/// \return
/// <0: 获取失败.
/// =0: 成功.
///
SR7_IF_API int SR7IF_GetIntensityData(unsigned int lDeviceId, const SR7IF_Data DataObj, unsigned char *Intensity);
///
/// \brief SR7IF_GetIntensityContiuneData 非阻塞获取亮度数据
/// \param lDeviceId 设备ID号范围为0-3.
/// \param DataObj 预留设置为NULL
/// \param Intensity 返回数据指针,双相机为A/B行交替数据
/// \param GetCnt 获取数据长度
/// \return
/// <0: 获取失败.
/// >=0: 返回获实际数据行数.
///
SR7_IF_API int SR7IF_GetIntensityContiuneData(unsigned int lDeviceId, const SR7IF_Data DataObj, unsigned char *Intensity, unsigned int GetCnt);
///
/// \brief SR7IF_GetBatchRollData 无终止循环获取数据
/// \param lDeviceId 设备ID号范围为0-3.
/// \param DataObj 预留设置为NULL
/// \param Profile 返回轮廓数据指针,双相机为A/B行交替数据
/// \param Intensity 返回亮度数据指针,双相机为A/B行交替数据
/// \param Encoder 返回编码器数据指针,双相机为A/B交替数据
/// \param FrameId 返回帧编号数据指针
/// \param FrameLoss 返回批处理过快掉帧数量数据指针,双相机为A/B交替数据
/// \param GetCnt 获取数据长度
/// \return
/// <0: 获取失败.
/// >=0: 实际返回的数据长度.
///
SR7_IF_API int SR7IF_GetBatchRollData(unsigned int lDeviceId, const SR7IF_Data DataObj,
int *Profile, unsigned char *Intensity, unsigned int *Encoder, long long *FrameId, unsigned int *FrameLoss,
unsigned int GetCnt);
///
/// \brief SR7IF_GetError 获取系统错误信息
/// \param lDeviceId 设备ID号范围为0-3.
/// \param pbyErrCnt 返回错误码数量
/// \param pwErrCode 返回错误码指针
/// \return
/// <0: 获取失败.
/// =0: 成功.
///
SR7_IF_API int SR7IF_GetError(unsigned int lDeviceId, int *pbyErrCnt, int *pwErrCode);
///
/// \brief SR7IF_GetBatchRollError 无终止循环获取数据异常计算值
/// \param lDeviceId 设备ID号范围为0-3.
/// \param EthErrCnt 返回网络传输导致错误的数量
/// \param UserErrCnt 返回用户获取导致错误的数量
/// \return
/// <0: 获取失败.
/// =0: 成功.
///
SR7_IF_API int SR7IF_GetBatchRollError(unsigned int lDeviceId, int *EthErrCnt, int *UserErrCnt);
///
/// \brief SR7IF_ClearError 暂无
/// \param lDeviceId
/// \param wErrCode
/// \return
/// <0: 清除失败
/// =0: 成功
///
SR7_IF_API int SR7IF_ClearError(unsigned int lDeviceId, unsigned short wErrCode);
///
/// \brief SR7IF_GetVersion 获取库版本号.
/// \return 返回版本信息.
///
SR7_IF_API const char *SR7IF_GetVersion();
///
/// \brief SR7IF_GetModels 获取相机型号.
/// \param lDeviceId 设备ID号范围为0-3.
/// \return 返回相机型号字符串.
///
SR7_IF_API const char *SR7IF_GetModels(unsigned int lDeviceId);
///
/// \brief SR7IF_GetHeaderSerial 获取相机头序列号
/// \param lDeviceId 设备ID号范围为0-3.
/// \param Head 0相机头A 1相机头B
/// \return
/// !=NULL: 返回相机序列号字符串.
/// =NULL: 失败,相应头不存在或者参数错误.
///
SR7_IF_API const char *SR7IF_GetHeaderSerial(unsigned int lDeviceId, int Head);
/// 高速数据通信相关
///
/// \brief SR7IF_HighSpeedDataEthernetCommunicationInitalize 初始化以太网高速数据通信.
/// \param lDeviceId 设备ID号范围为0-3.
/// \param pEthernetConfig Ethernet 通信设定.
/// \param wHighSpeedPortNo Ethernet 通信端口设定.
/// \param pCallBack 高速通信中数据接收的回调函数.
/// \param dwProfileCnt 回调函数被调用的频率. 范围1-256
/// \param dwThreadId 线程号.
/// \return
/// <0: 失败.
/// =0: 成功.
///
SR7_IF_API int SR7IF_HighSpeedDataEthernetCommunicationInitalize(unsigned int lDeviceId, SR7IF_ETHERNET_CONFIG* pEthernetConfig, int wHighSpeedPortNo,
SR7IF_CALLBACK pCallBack, unsigned int dwProfileCnt, unsigned int dwThreadId);
///
/// \brief SR7IF_SetOutputPortLevel 设置输出端口电平.
/// \param lDeviceId 设备ID号范围为0-3.
/// \param Port 输出端口号范围为0-7.
/// \param Level 输出电平值.
/// \return
/// <0: 失败.
/// =0: 成功.
///
SR7_IF_API int SR7IF_SetOutputPortLevel(unsigned int lDeviceId, unsigned int Port, bool Level);
///
/// \brief SR7IF_SetOutputPortLevel 读取输入端口电平.
/// \param lDeviceId 设备ID号范围为0-3.
/// \param Port 输入端口号范围为0-7.
/// \param Level 读取输入电平.
/// \return
/// <0: 失败.
/// =0: 成功.
///
SR7_IF_API int SR7IF_GetInputPortLevel(unsigned int lDeviceId, unsigned int Port, bool *Level);
///
/// \brief SR7IF_GetSingleProfile 获取当前一条轮廓(非批处理下,需在EdgeImaging中设置为2.5D模式)
/// \param lDeviceId 设备ID号范围为0-3.
/// \param pProfileData 返回轮廓的指针.
/// \param pEncoder 返回编码器的指针.
/// \return
/// <0: 失败.
/// =0: 成功.
///
SR7_IF_API int SR7IF_GetSingleProfile(unsigned int lDeviceId, int *pProfileData, unsigned int *pEncoder);
///
/// \brief SR7IF_SetSetting 参数设定.
/// \param lDeviceId 设备ID号范围为0-3.
/// \param Depth 设置的值的级别.
/// \param Type 设置类型.
/// \param Category 设置种类.
/// \param Item 设置项目.
/// \param Target[4] 根据发送 / 接收的设定,可能需要进行相应的指定。无需设定时,指定为 0。
/// \param pData 设置数据.
/// \param DataSize 设置数据的长度.
/// \return
/// <0: 失败.
/// =0: 成功.
///
SR7_IF_API int SR7IF_SetSetting(unsigned int lDeviceId, int Depth, int Type, int Category, int Item, int Target[4], void *pData, int DataSize);
///
/// \brief SR7IF_GetSetting 参数设定.
/// \param lDeviceId 设备ID号范围为0-3.
/// \param Type 获取类型.
/// \param Category 获取种类.
/// \param Item 获取项目.
/// \param Target[4] 根据发送 / 接收的设定,可能需要进行相应的指定。无需设定时,指定为 0。
/// \param pData 获取的数据.
/// \param DataSize 获取数据的长度.
/// \return
/// <0: 失败.
/// =0: 成功.
///
SR7_IF_API int SR7IF_GetSetting(unsigned int lDeviceId, int Type, int Category, int Item, int Target[4], void *pData, int DataSize);
///
/// \brief SR7IF_ExportParameters 将系统参数导出,注意只导出当前任务的参数.
/// \param lDeviceId 设备ID号范围为0-3.
/// \param size 返回参数表的大小.
/// \return
/// NULL: 失败.
/// 其他: 成功.
///
SR7_IF_API const char *SR7IF_ExportParameters(unsigned int lDeviceId, unsigned int *size);
///
/// \brief SR7IF_LoadParameters 将导出的参数导入到系统中.
/// \param lDeviceId 设备ID号范围为0-3.
/// \param pSettingdata 导入参数表指针.
/// \param size 导入参数表的大小.
/// \return
/// <0: 失败.
/// =0: 成功.
///
SR7_IF_API int SR7IF_LoadParameters(unsigned int lDeviceId, const char *pSettingdata, unsigned int size);
///
/// \brief SR7IF_GetLicenseKey 返回产品剩余天数
/// \param RemainDay 返回剩余天数
/// \return
/// < 0: 失败,参数错误或产品未注册
/// >=0: 成功.
///
SR7_IF_API int SR7IF_GetLicenseKey(unsigned int lDeviceId, unsigned short *RemainDay);
///
/// \brief SR7IF_GetCurrentEncoder 读取当前编码器值
/// \param value 返回编码器值
/// \return
/// <0: 失败.
/// =0: 成功.
///
SR7_IF_API int SR7IF_GetCurrentEncoder(unsigned int lDeviceId, unsigned int *value);
//
typedef struct {
int xPoints; //x方向数据数量
int BatchPoints; //批处理数量
unsigned int BatchTimes; //批处理次数
double xPixth; //x方向点间距
unsigned int startEncoder; //批处理开始编码器值
int HeadNumber; //相机头数量
int returnStatus; //SR7IF_OK:正常批处理
//SR7IF_NORMAL_STOP
//SR7IF_ERROR_ABORT
//SR7IF_ERROR_CLOSED
} SR7IF_STR_CALLBACK_INFO;
///
/// \brief SR7IF_SetBatchOneTimeDataHandler 设置回调函数,建议获取数据后另外开启线程进行处理(获取数据模式:批处理一次回调一次)
/// \param lDeviceId 设备ID号范围为0-3.
/// \param CallFunc 回调函数.
/// \return
/// <0: 失败.
/// =0: 成功.
///
SR7_IF_API int SR7IF_SetBatchOneTimeDataHandler(unsigned int lDeviceId, SR7IF_BatchOneTimeCallBack CallFunc);
///
/// \brief SR7IF_StartMeasureWithCallback 开始批处理(获取数据模式:批处理一次回调一次)
/// \param lDeviceId 设备ID号范围为0-3.
/// \param ImmediateBatch 0:立即开始批处理 1:等待外部开始批处理.
/// \return
/// <0: 失败.
/// =0: 成功.
///
SR7_IF_API int SR7IF_StartMeasureWithCallback(int iDeviceId, int ImmediateBatch);
///
/// \brief SR7IF_TriggerOneBatch 批处理软件触发开始(获取数据模式:批处理一次回调一次)
/// \param lDeviceId 设备ID号范围为0-3.
/// \return
/// <0: 失败.
/// =0: 成功.
///
SR7_IF_API int SR7IF_TriggerOneBatch(int iDeviceId);
///
/// \brief SR7IF_GetBatchProfilePoint 批处理轮廓获取(获取数据模式:批处理一次回调一次)
/// \param lDeviceId 设备ID号范围为0-3.
/// \param Head 0相机头A 1相机头B
/// \return
/// !=NULL: 返回数据指针
/// =NULL: 失败,无数据或者相应头不存在.
///
SR7_IF_API const int *SR7IF_GetBatchProfilePoint(const SR7IF_Data *DataIndex, int Head);
///
/// \brief SR7IF_GetBatchIntensityPoint 批处理亮度获取(获取数据模式:批处理一次回调一次)
/// \param lDeviceId 设备ID号范围为0-3.
/// \param Head 0相机头A 1相机头B
/// \return
/// !=NULL: 返回数据指针
/// =NULL: 失败,无数据或者相应头不存在.
///
SR7_IF_API const unsigned char *SR7IF_GetBatchIntensityPoint(const SR7IF_Data *DataIndex, int Head);
///
/// \brief SR7IF_GetBatchEncoderPoint 批处理编码器获取(获取数据模式:批处理一次回调一次)
/// \param lDeviceId 设备ID号范围为0-3.
/// \param Head 0相机头A 1相机头B
/// \return
/// !=NULL: 返回数据指针
/// =NULL: 失败,无数据或者相应头不存在.
///
SR7_IF_API const unsigned int *SR7IF_GetBatchEncoderPoint(const SR7IF_Data *DataIndex, int Head);
#ifdef __cplusplus
}
#endif
#endif //SR7LINK__H

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@ -0,0 +1,36 @@
{
"runtimeTarget": {
"name": ".NETCoreApp,Version=v3.1",
"signature": ""
},
"compilationOptions": {},
"targets": {
".NETCoreApp,Version=v3.1": {
"WeifenLuo.WinFormsUI.Docking.ThemeVS2003/1.0.0": {
"dependencies": {
"DockPanelSuite": "3.1.0"
},
"runtime": {
"WeifenLuo.WinFormsUI.Docking.ThemeVS2003.dll": {}
}
},
"DockPanelSuite/3.1.0": {
"runtime": {
"WeifenLuo.WinFormsUI.Docking.dll": {}
}
}
}
},
"libraries": {
"WeifenLuo.WinFormsUI.Docking.ThemeVS2003/1.0.0": {
"type": "project",
"serviceable": false,
"sha512": ""
},
"DockPanelSuite/3.1.0": {
"type": "project",
"serviceable": false,
"sha512": ""
}
}
}

View File

@ -0,0 +1,36 @@
{
"runtimeTarget": {
"name": ".NETCoreApp,Version=v3.1",
"signature": ""
},
"compilationOptions": {},
"targets": {
".NETCoreApp,Version=v3.1": {
"WeifenLuo.WinFormsUI.Docking.ThemeVS2005/1.0.0": {
"dependencies": {
"DockPanelSuite": "3.1.0"
},
"runtime": {
"WeifenLuo.WinFormsUI.Docking.ThemeVS2005.dll": {}
}
},
"DockPanelSuite/3.1.0": {
"runtime": {
"WeifenLuo.WinFormsUI.Docking.dll": {}
}
}
}
},
"libraries": {
"WeifenLuo.WinFormsUI.Docking.ThemeVS2005/1.0.0": {
"type": "project",
"serviceable": false,
"sha512": ""
},
"DockPanelSuite/3.1.0": {
"type": "project",
"serviceable": false,
"sha512": ""
}
}
}

View File

@ -0,0 +1,36 @@
{
"runtimeTarget": {
"name": ".NETCoreApp,Version=v3.1",
"signature": ""
},
"compilationOptions": {},
"targets": {
".NETCoreApp,Version=v3.1": {
"WeifenLuo.WinFormsUI.Docking.ThemeVS2012/1.0.0": {
"dependencies": {
"DockPanelSuite": "3.1.0"
},
"runtime": {
"WeifenLuo.WinFormsUI.Docking.ThemeVS2012.dll": {}
}
},
"DockPanelSuite/3.1.0": {
"runtime": {
"WeifenLuo.WinFormsUI.Docking.dll": {}
}
}
}
},
"libraries": {
"WeifenLuo.WinFormsUI.Docking.ThemeVS2012/1.0.0": {
"type": "project",
"serviceable": false,
"sha512": ""
},
"DockPanelSuite/3.1.0": {
"type": "project",
"serviceable": false,
"sha512": ""
}
}
}

View File

@ -0,0 +1,36 @@
{
"runtimeTarget": {
"name": ".NETCoreApp,Version=v3.1",
"signature": ""
},
"compilationOptions": {},
"targets": {
".NETCoreApp,Version=v3.1": {
"WeifenLuo.WinFormsUI.Docking.ThemeVS2013/1.0.0": {
"dependencies": {
"DockPanelSuite": "3.1.0"
},
"runtime": {
"WeifenLuo.WinFormsUI.Docking.ThemeVS2013.dll": {}
}
},
"DockPanelSuite/3.1.0": {
"runtime": {
"WeifenLuo.WinFormsUI.Docking.dll": {}
}
}
}
},
"libraries": {
"WeifenLuo.WinFormsUI.Docking.ThemeVS2013/1.0.0": {
"type": "project",
"serviceable": false,
"sha512": ""
},
"DockPanelSuite/3.1.0": {
"type": "project",
"serviceable": false,
"sha512": ""
}
}
}

View File

@ -0,0 +1,36 @@
{
"runtimeTarget": {
"name": ".NETCoreApp,Version=v3.1",
"signature": ""
},
"compilationOptions": {},
"targets": {
".NETCoreApp,Version=v3.1": {
"WeifenLuo.WinFormsUI.Docking.ThemeVS2015/1.0.0": {
"dependencies": {
"DockPanelSuite": "3.1.0"
},
"runtime": {
"WeifenLuo.WinFormsUI.Docking.ThemeVS2015.dll": {}
}
},
"DockPanelSuite/3.1.0": {
"runtime": {
"WeifenLuo.WinFormsUI.Docking.dll": {}
}
}
}
},
"libraries": {
"WeifenLuo.WinFormsUI.Docking.ThemeVS2015/1.0.0": {
"type": "project",
"serviceable": false,
"sha512": ""
},
"DockPanelSuite/3.1.0": {
"type": "project",
"serviceable": false,
"sha512": ""
}
}
}

View File

@ -0,0 +1,23 @@
{
"runtimeTarget": {
"name": ".NETCoreApp,Version=v3.1",
"signature": ""
},
"compilationOptions": {},
"targets": {
".NETCoreApp,Version=v3.1": {
"WeifenLuo.WinFormsUI.Docking/1.0.0": {
"runtime": {
"WeifenLuo.WinFormsUI.Docking.dll": {}
}
}
}
},
"libraries": {
"WeifenLuo.WinFormsUI.Docking/1.0.0": {
"type": "project",
"serviceable": false,
"sha512": ""
}
}
}

BIN
libs/UI/HZH_Controls.dll Normal file

Binary file not shown.

Binary file not shown.

BIN
libs/gocator/GoSdkNet.dll Normal file

Binary file not shown.

BIN
libs/gocator/bk/GoSdk.dll Normal file

Binary file not shown.

Binary file not shown.

BIN
libs/gocator/bk/kApi.dll Normal file

Binary file not shown.

BIN
libs/gocator/bk/kApiNet.dll Normal file

Binary file not shown.

Binary file not shown.

Binary file not shown.

BIN
libs/gocator/kApiNet.dll Normal file

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@ -0,0 +1,206 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="14.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Import Project="..\..\packages\PostSharp.6.2.7\build\PostSharp.props" Condition="Exists('..\..\packages\PostSharp.6.2.7\build\PostSharp.props')" />
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
<ProjectGuid>{987308DD-8BAA-463A-94E2-77D62E01A5BF}</ProjectGuid>
<OutputType>Library</OutputType>
<AppDesignerFolder>Properties</AppDesignerFolder>
<RootNamespace>BRS.Common.Device</RootNamespace>
<AssemblyName>BRS.Common.Device</AssemblyName>
<TargetFrameworkVersion>v4.6.1</TargetFrameworkVersion>
<FileAlignment>512</FileAlignment>
<NuGetPackageImportStamp>
</NuGetPackageImportStamp>
<TargetFrameworkProfile />
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<DebugSymbols>true</DebugSymbols>
<DebugType>full</DebugType>
<Optimize>false</Optimize>
<OutputPath>..\Debug\</OutputPath>
<DefineConstants>DEBUG;TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
<PlatformTarget>AnyCPU</PlatformTarget>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
<DebugType>pdbonly</DebugType>
<Optimize>false</Optimize>
<OutputPath>..\Release\</OutputPath>
<DefineConstants>DEBUG;TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
<PlatformTarget>x86</PlatformTarget>
</PropertyGroup>
<PropertyGroup>
<AutoGenerateBindingRedirects>false</AutoGenerateBindingRedirects>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Debug1|AnyCPU'">
<DebugSymbols>true</DebugSymbols>
<OutputPath>bin\Debug1\</OutputPath>
<DefineConstants>DEBUG;TRACE</DefineConstants>
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
<DebugType>full</DebugType>
<PlatformTarget>AnyCPU</PlatformTarget>
<LangVersion>7.3</LangVersion>
<ErrorReport>prompt</ErrorReport>
<CodeAnalysisRuleSet>MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Debug|x64'">
<DebugSymbols>true</DebugSymbols>
<OutputPath>..\Debug\</OutputPath>
<DefineConstants>DEBUG;TRACE</DefineConstants>
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
<DebugType>full</DebugType>
<PlatformTarget>x64</PlatformTarget>
<LangVersion>7.3</LangVersion>
<ErrorReport>prompt</ErrorReport>
<CodeAnalysisRuleSet>MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Release|x64'">
<OutputPath>..\Release\</OutputPath>
<DefineConstants>DEBUG;TRACE</DefineConstants>
<Optimize>false</Optimize>
<DebugType>pdbonly</DebugType>
<PlatformTarget>x64</PlatformTarget>
<LangVersion>7.3</LangVersion>
<ErrorReport>prompt</ErrorReport>
<CodeAnalysisRuleSet>MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Debug1|x64'">
<DebugSymbols>true</DebugSymbols>
<OutputPath>bin\x64\Debug1\</OutputPath>
<DefineConstants>DEBUG;TRACE</DefineConstants>
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
<DebugType>full</DebugType>
<PlatformTarget>x64</PlatformTarget>
<LangVersion>7.3</LangVersion>
<ErrorReport>prompt</ErrorReport>
<CodeAnalysisRuleSet>MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet>
</PropertyGroup>
<ItemGroup>
<Reference Include="Autofac, Version=4.9.4.0, Culture=neutral, PublicKeyToken=17863af14b0044da, processorArchitecture=MSIL">
<HintPath>..\..\packages\Autofac.4.9.4\lib\net45\Autofac.dll</HintPath>
</Reference>
<Reference Include="Microsoft.Bcl.AsyncInterfaces, Version=1.0.0.0, Culture=neutral, PublicKeyToken=cc7b13ffcd2ddd51, processorArchitecture=MSIL">
<HintPath>..\..\packages\Microsoft.Bcl.AsyncInterfaces.1.1.0\lib\net461\Microsoft.Bcl.AsyncInterfaces.dll</HintPath>
</Reference>
<Reference Include="MrAdvice, Version=2.0.0.0, Culture=neutral, PublicKeyToken=c0e7e6eab6f293d8, processorArchitecture=MSIL">
<HintPath>..\..\packages\MrAdvice.2.9.7\lib\net40-client\MrAdvice.dll</HintPath>
</Reference>
<Reference Include="Newtonsoft.Json, Version=12.0.0.0, Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed, processorArchitecture=MSIL">
<HintPath>..\..\packages\Newtonsoft.Json.12.0.3\lib\net45\Newtonsoft.Json.dll</HintPath>
</Reference>
<Reference Include="PresentationCore" />
<Reference Include="System" />
<Reference Include="System.Buffers, Version=4.0.3.0, Culture=neutral, PublicKeyToken=cc7b13ffcd2ddd51, processorArchitecture=MSIL">
<HintPath>..\..\packages\System.Buffers.4.5.1\lib\net461\System.Buffers.dll</HintPath>
</Reference>
<Reference Include="System.configuration" />
<Reference Include="System.Core" />
<Reference Include="System.Design" />
<Reference Include="System.Diagnostics.DiagnosticSource, Version=4.0.5.0, Culture=neutral, PublicKeyToken=cc7b13ffcd2ddd51, processorArchitecture=MSIL">
<HintPath>..\..\packages\System.Diagnostics.DiagnosticSource.4.7.1\lib\net46\System.Diagnostics.DiagnosticSource.dll</HintPath>
</Reference>
<Reference Include="System.Drawing" />
<Reference Include="System.Memory, Version=4.0.1.2, Culture=neutral, PublicKeyToken=cc7b13ffcd2ddd51, processorArchitecture=MSIL">
<HintPath>..\..\packages\System.Memory.4.5.5\lib\net461\System.Memory.dll</HintPath>
</Reference>
<Reference Include="System.Numerics" />
<Reference Include="System.Numerics.Vectors, Version=4.1.4.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
<HintPath>..\..\packages\System.Numerics.Vectors.4.5.0\lib\net46\System.Numerics.Vectors.dll</HintPath>
</Reference>
<Reference Include="System.Runtime.CompilerServices.Unsafe, Version=7.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
<HintPath>..\..\packages\System.Runtime.CompilerServices.Unsafe.7.0.0-preview.2.22152.2\lib\net462\System.Runtime.CompilerServices.Unsafe.dll</HintPath>
</Reference>
<Reference Include="System.Security.Cryptography.Algorithms, Version=4.1.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
<HintPath>..\..\packages\System.Security.Cryptography.Algorithms.4.3.0\lib\net461\System.Security.Cryptography.Algorithms.dll</HintPath>
</Reference>
<Reference Include="System.Security.Cryptography.Encoding, Version=4.0.1.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
<HintPath>..\..\packages\System.Security.Cryptography.Encoding.4.3.0\lib\net46\System.Security.Cryptography.Encoding.dll</HintPath>
</Reference>
<Reference Include="System.Security.Cryptography.Primitives, Version=4.0.1.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
<HintPath>..\..\packages\System.Security.Cryptography.Primitives.4.3.0\lib\net46\System.Security.Cryptography.Primitives.dll</HintPath>
</Reference>
<Reference Include="System.Security.Cryptography.X509Certificates, Version=4.1.1.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
<HintPath>..\..\packages\System.Security.Cryptography.X509Certificates.4.3.0\lib\net461\System.Security.Cryptography.X509Certificates.dll</HintPath>
</Reference>
<Reference Include="System.Threading.Tasks.Extensions, Version=4.2.0.1, Culture=neutral, PublicKeyToken=cc7b13ffcd2ddd51, processorArchitecture=MSIL">
<HintPath>..\..\packages\System.Threading.Tasks.Extensions.4.5.4\lib\net461\System.Threading.Tasks.Extensions.dll</HintPath>
</Reference>
<Reference Include="System.Windows.Forms" />
<Reference Include="System.Xml.Linq" />
<Reference Include="System.Data.DataSetExtensions" />
<Reference Include="Microsoft.CSharp" />
<Reference Include="System.Data" />
<Reference Include="System.Xml" />
</ItemGroup>
<ItemGroup>
<Compile Include="Base\DeviceBase.cs" />
<Compile Include="DeviceBase\AGVBase.cs" />
<Compile Include="DeviceBase\CameraBase.cs" />
<Compile Include="DeviceBase\ForceSensorBase.cs" />
<Compile Include="DeviceBase\IODeviceBase.cs" />
<Compile Include="DeviceBase\RobotBase.cs" />
<Compile Include="DeviceBase\SerialPortBase.cs" />
<Compile Include="DeviceBase\VisionEngineBase.cs" />
<Compile Include="DeviceBase\MessageQueueBase.cs" />
<Compile Include="DeviceBase\ModbusASCIICommBase.cs" />
<Compile Include="DeviceBase\MotionCardBase.cs" />
<Compile Include="DeviceBase\PLCBase.cs" />
<Compile Include="DeviceBase\RS-232CommBase.cs" />
<Compile Include="DeviceBase\TcpCommBase.cs" />
<Compile Include="Helper\AspectHelper.cs" />
<Compile Include="Helper\SerialPortHelper.cs" />
<Compile Include="Interface\IMotion.cs" />
<Compile Include="Interface\IVibrationSupplier.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="Properties\Resources.Designer.cs">
<AutoGen>True</AutoGen>
<DesignTime>True</DesignTime>
<DependentUpon>Resources.resx</DependentUpon>
</Compile>
</ItemGroup>
<ItemGroup>
<None Include="app.config" />
<None Include="packages.config" />
</ItemGroup>
<ItemGroup>
<EmbeddedResource Include="Properties\Resources.resx">
<Generator>ResXFileCodeGenerator</Generator>
<LastGenOutput>Resources.Designer.cs</LastGenOutput>
</EmbeddedResource>
</ItemGroup>
<ItemGroup>
<Folder Include="Calibration\" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\BRS.Common.Model\BRS.Common.Model.csproj">
<Project>{1a3cbfe7-3f78-42c3-95c5-10360450dbea}</Project>
<Name>BRS.Common.Model</Name>
</ProjectReference>
<ProjectReference Include="..\BRS.UI.Model.Winform\BRS.UI.Model.Winform.csproj">
<Project>{741f6491-57c7-479a-b391-09bba9fba9dc}</Project>
<Name>BRS.UI.Model.Winform</Name>
</ProjectReference>
</ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
<Import Project="..\..\packages\MrAdvice.2.9.7\build\MrAdvice.targets" Condition="Exists('..\..\packages\MrAdvice.2.9.7\build\MrAdvice.targets')" />
<Target Name="EnsureNuGetPackageBuildImports" BeforeTargets="PrepareForBuild">
<PropertyGroup>
<ErrorText>这台计算机上缺少此项目引用的 NuGet 程序包。使用“NuGet 程序包还原”可下载这些程序包。有关更多信息,请参见 http://go.microsoft.com/fwlink/?LinkID=322105。缺少的文件是 {0}。</ErrorText>
</PropertyGroup>
<Error Condition="!Exists('..\..\packages\MrAdvice.2.9.7\build\MrAdvice.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\..\packages\MrAdvice.2.9.7\build\MrAdvice.targets'))" />
</Target>
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
Other similar extension points exist, see Microsoft.Common.targets.
<Target Name="BeforeBuild">
</Target>
<Target Name="AfterBuild">
</Target>
-->
</Project>

View File

@ -0,0 +1,401 @@
using BRS.Common.Model.Helper;
using BRS.Common.Interface;
using BRS.Common.Model;
using Newtonsoft.Json;
using System;
using System.ComponentModel;
using System.IO;
using System.Threading;
using System.Threading.Tasks;
using static BRS.Common.Model.Helper.EnumHelper;
namespace BRS.Common.Base
{
public abstract class DeviceBase : IDevice
{
#region Event
[JsonIgnore]
[Browsable(false)]
public Action<DateTime, Exception> OnExceptionOccured { get; set; }
//public event Action<DateTime, LogLevel, string> OnLog;
public event Action<LogMsg> OnLog;
public event Action<IDevice, DeviceState> OnDeviceStateChanged;
public event PropertyChangedEventHandler PropertyChanged;
#endregion
#region field
int RetryTime = 3;
/// <summary>
/// 和设备暂停状态关联的信号量
/// </summary>
private readonly ManualResetEvent pauseHandle = new ManualResetEvent(true);
readonly Timer stateChangedTimer;
#endregion
#region Property
#region State
private EnumHelper.DeviceState _currentStateToBe = EnumHelper.DeviceState.DSUninit;
/// <summary>
/// 当前设备状态
/// </summary>
[JsonIgnore]
internal EnumHelper.DeviceState CurrentStateToBe
{
get
{
return _currentStateToBe;
}
set
{
if (value != _currentStateToBe)
{
var initialState = _currentStateToBe;
_currentStateToBe = value;
if (_currentStateToBe != EnumHelper.DeviceState.DSExcept)
{
OnStateChanged(initialState);
}
else
{
stateChangedTimer.Change(Timeout.Infinite, Timeout.Infinite);
}
}
}
}
//private EnumHelper.DeviceState initialState = EnumHelper.DeviceState.DSUninit;
private EnumHelper.DeviceState _currentState = EnumHelper.DeviceState.DSUninit;
public EnumHelper.DeviceState CurrentState
{
get
{
return _currentState;
}
set
{
_currentState = value;
if (value != EnumHelper.DeviceState.TBD)
{
OnDeviceStateChanged?.Invoke(this, _currentState);
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs("CurrentState"));
}
//else
//{
// initialState = _currentState;
//}
}
}
#endregion
/// <summary>
/// 设备标识符 从数据库获取
/// </summary>
public string Id { get; set; }
/// <summary>
/// 设备名称 从数据库获取
/// </summary>
public string Name { get; set; }
private IInitialConfig initialConfig = null;
/// <summary>
/// 设备初始化配置 从数据库获取
/// </summary>
public virtual IInitialConfig InitialConfig
{
get => initialConfig;
set
{
initialConfig = value;
Id = initialConfig.Id;
Name = initialConfig.Name;
LoggerHelper.LogPath = initialConfig.LogPath;
LoggerHelper.LogPrefix = initialConfig.Name;
}
}
#endregion
#region
public DeviceBase()
{
RegisterFileWriterException();
stateChangedTimer = new Timer(new TimerCallback(CheckDeviceOpTimeOut), null, Timeout.Infinite, Timeout.Infinite);
}
#endregion
#region
protected virtual void Init()
{
LogAsync(DateTime.Now, LogLevel.Assist, $"{Name}初始化完成");
}
protected abstract void Pause();
protected abstract void Resume();
protected virtual void Start()
{
LogAsync(DateTime.Now, LogLevel.Assist, $"{Name}启动");
}
protected virtual void Stop()
{
LogAsync(DateTime.Now, LogLevel.Assist, $"{Name}停止");
}
//public abstract void AttachToProcess(IProcess process);
#endregion
/// <summary>
/// 常用操作封装方法
/// </summary>
/// <param name="opConfig"></param>
/// <returns></returns>
public virtual ResponseMessage RunWrap(IOperationConfig opConfig)
{
ResponseMessage msg = new ResponseMessage();
msg.Message = "设备基类默认操作";
return msg;
}
#region
[DeviceExceptionAspect]
public void StateChange(EnumHelper.DeviceState stateToBe)
{
if (CurrentState == stateToBe)
{
return;
}
if (!stateToBe.CheckPreStateValid((int)CurrentStateToBe))
{
string currentStateStr = CurrentStateToBe.GetEnumDescription();
string stateToBeStr = stateToBe.GetEnumDescription();
throw new ProcessException($"{InitialConfig.Name}设备的当前状态为{currentStateStr},无法切换至{stateToBeStr}");
}
CurrentState = EnumHelper.DeviceState.TBD;
CurrentStateToBe = stateToBe;
}
[DeviceExceptionAspect]
private void OnStateChanged(EnumHelper.DeviceState initialState)
{
try
{
if (CurrentStateToBe != EnumHelper.DeviceState.DSExcept)
{
}
else
{
if (CurrentState == EnumHelper.DeviceState.DSExcept)
{
return;
}
else
{
throw new ProcessException($"{InitialConfig.Name}设备操作超时");
}
}
if (RetryTime >= 0)
{
if (initialState == CurrentStateToBe)
{
CurrentState = CurrentStateToBe;
return;
}
#region
switch (CurrentStateToBe)
{
case EnumHelper.DeviceState.DSInit:
if (initialState == EnumHelper.DeviceState.DSOpen)
{
return;
}
else
{
Init();
}
break;
case EnumHelper.DeviceState.DSOpen:
if (initialState == EnumHelper.DeviceState.DSInit)
{
Start();
}
else if (initialState == EnumHelper.DeviceState.DSPause)
{
Resume();
pauseHandle.Set();
}
break;
case EnumHelper.DeviceState.DSPause:
pauseHandle.Reset();
Pause();
break;
case EnumHelper.DeviceState.DSClose:
if (initialState != DeviceState.DSUninit)
{
Stop();
}
break;
default:
break;
}
RetryTime = 3;
CurrentState = CurrentStateToBe;
#endregion
}
stateChangedTimer.Change(Timeout.Infinite, Timeout.Infinite);
}
catch (Exception ex)
{
RetryTime--;
if (RetryTime > 0)
{
OnStateChanged(initialState);
}
else
{
if (CurrentState != EnumHelper.DeviceState.DSExcept)
{
RetryTime = 3;
throw new ProcessException($"设备{InitialConfig.Name}的{CurrentStateToBe.GetEnumDescription()}操作重复3次失败", ex, ExceptionLevel.Warning);
}
}
}
}
private void CheckDeviceOpTimeOut(object state)
{
stateChangedTimer?.Change(Timeout.Infinite, Timeout.Infinite);
if (CurrentState != EnumHelper.DeviceState.DSExcept)
{
StateChange(EnumHelper.DeviceState.DSExcept);
}
}
#endregion
#region
private void RegisterFileWriterException()
{
LoggerHelper.OnLogExceptionRaised -= LoggerHelper_OnLogExceptionRaised;
CSVHelper.OnCSVExceptionRaised -= LoggerHelper_OnLogExceptionRaised;
LoggerHelper.OnLogExceptionRaised += LoggerHelper_OnLogExceptionRaised;
CSVHelper.OnCSVExceptionRaised += LoggerHelper_OnLogExceptionRaised;
}
public CSVHelper CSVHelper { get; set; } = new CSVHelper();
public LoggerHelper LoggerHelper { get; set; } = new LoggerHelper();
public virtual void LogAsync(LogMsg msg)
{
msg.MsgSource = Name;
msg.ThreadId = Thread.CurrentThread.ManagedThreadId;
//OnLog?.BeginInvoke(msg, null, null);
OnLog?.Invoke(msg);
if (InitialConfig.IsEnableLog)
{
LoggerHelper.LogAsync(msg);
}
}
public virtual void LogAsync(DateTime dt, LogLevel logLevel, string msg)
{
LogAsync(new LogMsg(dt, logLevel, msg));
}
private void LoggerHelper_OnLogExceptionRaised(DateTime dt, string msg)
{
OnLog?.Invoke(new LogMsg(dt, LogLevel.Error, msg));
}
/// <summary>
/// CSV异步数据输出
/// </summary>
/// <param name="csvFile">CSV输出文件的文件全路径</param>
/// <param name="csvData">CSV输出数据</param>
/// <param name="csvHead">CSV文件表头</param>
public virtual void CSVRecordAsync(string csvFile, string csvData, string csvHead = "")
{
CSVHelper.CSVOutputAsync(csvFile, csvData, csvHead);
}
#endregion
#region
object _alarmLock = new object();
protected virtual async void SaveAlarmCSVAsync(DateTime now, string deviceName, IWarningSet ws)
{
await Task.Run(() =>
{
LogAsync(now, LogLevel.Warning, $"{ws.WarningCode}-{ws.WarningDescription} {(ws.CurrentStatus ? "" : "")}");
if (string.IsNullOrWhiteSpace(this.InitialConfig.LogPath) || !InitialConfig.IsEnableCSV)
return;
string path = Path.Combine(InitialConfig.LogPath, $"Alarm_{Name}_{now.ToString("yyyyMMdd")}.csv");
string head = "Time,Source,AlarmCode,AlarmDescription,AlarmStatus";
string data = $"{now.ToString("HH:mm:ss.fff")},{deviceName},{ws.WarningCode},{ws.WarningDescription},{(ws.CurrentStatus ? "" : "")}";
CSVRecordAsync(path, data, head);
});
}
#endregion
#region IDisposable Support
private bool disposedValue = false; // 要检测冗余调用
protected virtual void Dispose(bool disposing)
{
if (!disposedValue)
{
if (disposing)
{
//释放托管状态(托管对象)。
stateChangedTimer?.Dispose();
pauseHandle?.Dispose();
}
// TODO: 释放未托管的资源(未托管的对象)并在以下内容中替代终结器。
// TODO: 将大型字段设置为 null。
disposedValue = true;
}
}
// TODO: 仅当以上 Dispose(bool disposing) 拥有用于释放未托管资源的代码时才替代终结器。
// ~DeviceBase()
// {
// // 请勿更改此代码。将清理代码放入以上 Dispose(bool disposing) 中。
// Dispose(false);
// }
// 添加此代码以正确实现可处置模式。
public void Dispose()
{
// 请勿更改此代码。将清理代码放入以上 Dispose(bool disposing) 中。
Dispose(true);
// TODO: 如果在以上内容中替代了终结器,则取消注释以下行。
// GC.SuppressFinalize(this);
}
#endregion
}
}

View File

@ -0,0 +1,85 @@
using Bro.Common.Helper;
using Bro.Common.Interface;
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing.Design;
using System.Reflection;
namespace Bro.Common.Base
{
public class OperationConfigBase : IOperationConfig
{
/// <summary>
/// 输入参数
/// </summary>
[JsonIgnore]
[Category("输入配置")]
[Description("输入参数配置")]
[TypeConverter(typeof(SimpleCollectionConvert<int>))]
public List<int> InputPara { get; set; } = new List<int>();
/// <summary>
/// 异常反馈值
/// </summary>
[Category("异常反馈设置")]
[Description("异常反馈值")]
public int ExceptionValue { get; set; } = 0;
/// <summary>
/// 发生异常时的重新尝试次数
/// </summary>
[Category("异常反馈设置")]
[Description("发生异常时的重新尝试次数")]
public int ReTryTimes { get; set; } = 3;
}
public abstract class InitialConfigBase : IInitialConfig
{
[Category("通用配置")]
[Description("设备索引")]
[ReadOnly(true)]
public string Id { get; set; } = Guid.NewGuid().ToString().ToUpper();
[Category("通用配置")]
[Description("设备名称")]
public string Name { get; set; } = "UnNamed";
/// <summary>
/// 设备是否启用
/// </summary>
[Category("通用配置")]
[Description("设备是否启用")]
public bool IsEnabled { get; set; } = false;
/// <summary>
/// 设备类型 在具体设备基类中看是否需要开放重写
/// </summary>
[Browsable(false)]
public virtual string DriverType { get; set; } = "";
[Category("日志配置")]
[Description("日志记录目录")]
[Editor(typeof(FoldDialogEditor), typeof(UITypeEditor))]
public string LogPath { get; set; } = "";
[Category("日志配置")]
[Description("true启用日志记录 false不启用日志记录")]
public bool IsEnableLog { get; set; } = false;
public virtual List<string> GetHalconToolPathList()
{
return new List<string>();
}
public InitialConfigBase()
{
var attr = this.GetType().GetCustomAttribute<DeviceAttribute>();
if (attr != null)
{
this.DriverType = attr.TypeCode;
}
}
}
}

View File

@ -0,0 +1,190 @@
using Bro.Common.Interface;
using Newtonsoft.Json;
using System;
using System.Threading;
namespace Bro.Common.Base
{
public class InputConfigBase : IInputConfig
{
//public InputConfigBase()
//{
// StateMachine.OnDeviceInput += OnDeviceInput;
//}
//[JsonIgnore]
//public AutoResetEvent InputHanlder { get; set; } = new AutoResetEvent(false);
// [JsonIgnore]
//public string IConfigId = Guid.NewGuid().ToString();
//[JsonIgnore]
//public Dictionary<string, AutoResetEvent> InputHanlderDict { get; set; } = new Dictionary<string, AutoResetEvent>();
//[JsonIgnore]
//public Dictionary<string, bool> InputFlagDict { get; set; } = new Dictionary<string, bool>();
//[JsonIgnore]
//public ConcurrentDictionary<string, AutoResetEvent> InputHanlderDict { get; set; } = new ConcurrentDictionary<string, AutoResetEvent>();
//[JsonIgnore]
//public ConcurrentDictionary<string, bool> InputFlagDict { get; set; } = new ConcurrentDictionary<string, bool>();
[JsonIgnore]
public bool BoundFlag { get; set; } = false;
public bool IsInputNeed { get; set; } = false;
public string InputMethodName { get; set; }
/// <summary>
/// 第三方设备输入参数
/// </summary>
[JsonIgnore]
public dynamic InputPara { get; set; }
private string processId;
[JsonIgnore]
public string ProcessId
{
get
{
return processId;
}
set
{
if (processId != value)
{
//仅在工序编号赋值后建立消息连接
processId = value;
//if (conn == null)
//{
// conn = new HubConnection(GlobalVar.SignalRServer);
// proxy = conn.CreateHubProxy("DeviceHub");
// proxy.On<InputPara>("OnDeviceInput", OnDeviceInput);
// conn.Start().Wait();
//}
//lock (this)
{
//InputHanlderDict[processId] = new AutoResetEvent(false);
//InputFlagDict[processId] = false;
//InputHanlderDict.AddOrUpdate(processId, new AutoResetEvent(false), (a, b) => { return new AutoResetEvent(false); });
//InputFlagDict.AddOrUpdate(processId, false, (a, b) => { return false; });
InputHandle = new AutoResetEvent(false);
//StateMachine.OnDeviceInput += OnDeviceInput;
}
//if (StateMachine.OnDeviceInput != null)
//{
// var list = StateMachine.OnDeviceInput.GetInvocationList().ToList();
// if (list != null)
// {
// if (!list.Any(d =>
// {
// InputConfigBase icb = d.Target as InputConfigBase;
// return icb.ProcessId == ProcessId;
// }))
// {
// StateMachine.OnDeviceInput += OnDeviceInput;
// }
// }
// else
// {
// StateMachine.OnDeviceInput += OnDeviceInput;
// }
//}
//else
//{
//StateMachine.OnDeviceInput += OnDeviceInput;
//PubSubCenter.GetInstance().Subscribe(processId, OnDeviceInput);
//}
}
}
}
[JsonIgnore]
public AutoResetEvent InputHandle { get; set; } = new AutoResetEvent(false);
public string ProcessName { get; set; }
//HubConnection conn;
//IHubProxy proxy;
/// <summary>
/// 适用于第三方的信号输入
/// </summary>
/// <param name="obj"></param>
//private object OnDeviceInput(ISubscriber sub, object param1, object param2)
private void OnDeviceInput(InputPara obj)
{
//Debug.WriteLine(DateTime.Now.ToString("mm:ss.fff") + "\t输入流程" + obj.ProcessId + "\t本流程编号" + ProcessId);
//输入参数必须有一个字段是ProcessId保存工序编号
//string processId = obj.ProcessId;
//if (obj.ProcessId == ProcessId)
//{
// InputPara = obj.ParaObj;
// InputHanlderDict[].Set();
// BoundFlag = false;
//}
//InputPara obj = param1 as InputPara;
//lock (this)
{
try
{
//if (InputHanlderDict.Keys.Contains(obj.ProcessId))
if (ProcessId == obj.ProcessId)
{
//Debug.WriteLine(DateTime.Now.ToString("mm:ss.fff") + "\t流程编号" + obj.ProcessId);
//InputHanlderDict[obj.ProcessId].Set();
//InputFlagDict[obj.ProcessId] = true;
InputHandle.Set();
//InputHanlderDict.Remove(obj.ProcessId);
//StateMachine.OnDeviceInput -= OnDeviceInput;
//PubSubCenter.GetInstance().RemoveSubscriber(ProcessId, OnDeviceInput);
}
}
catch (Exception)
{
}
//return null;
}
}
public virtual void Dispose()
{
//foreach (var handle in InputHanlderDict)
//{
// handle.Value.Set();
//}
//StateMachine.OnDeviceInput -= OnDeviceInput;
//InputHanlderDict = new ConcurrentDictionary<string, AutoResetEvent>();
//InputFlagDict = new ConcurrentDictionary<string, bool>();
//GC.Collect();
}
}
[Serializable]
public class InputPara : IProcessID
{
public string ProcessId { get; set; }
//[DataMember]
public dynamic ParaObj { get; set; }
public string ProcessName { get; set; }
}
}

View File

@ -0,0 +1,85 @@
using Bro.Common.Helper;
using Bro.Common.Interface;
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using static Bro.Common.Helper.EnumHelper;
namespace Bro.Common.Base
{
//[Device("Base", "基础操作配置", EnumHelper.DeviceAttributeType.OperationConfig)]
public class OperationConfigBase : IOperationConfig
{
////[JsonIgnore]
//public IDeviceConfig DeviceConfig { get; set; }
////[JsonIgnore]
//public IInputConfig InputConfig { get; set; }
//public string OutputMethodName { get; set; }
////[JsonIgnore]
//public string ProcessId { get; set; }
//public string ProcessName { get; set; }
[JsonIgnore]
[Browsable(false)]
public virtual int ResultOutput { get; set; }
/// <summary>
/// 输入参数
/// </summary>
[JsonIgnore]
[Browsable(false)]
public List<int> InputPara { get; set; }
[Category("启用配置")]
[Description("true启用该配置执行操作false不启用该配置不执行操作")]
public bool IsEnabled { get; set; } = true;
/// <summary>
/// 异常反馈值
/// </summary>
[Category("异常反馈设置")]
[Description("异常反馈值")]
public int ExceptionValue { get; set; } = 0;
/// <summary>
/// 发生异常时的重新尝试次数
/// </summary>
[Category("异常反馈设置")]
[Description("发生异常时的重新尝试次数")]
public int ReTryTimes { get; set; } = 3;
///// <summary>
///// 发生异常多次后向PLC报警
///// </summary>
//[Category("异常反馈设置")]
//[Description("发生异常多次后向PLC报警")]
//public int PLCWarningTimes { get; set; } = 0;
///// <summary>
///// 向PLC报警的报警类别
///// </summary>
//[Category("异常反馈设置")]
//[Description("向PLC报警的报警类别")]
//public WarningFromPC WarningType { get; set; } = WarningFromPC.UnknowError;
///// <summary>
///// 14 2+4+8表示全部采用上道工序输出配置
///// </summary>
//public int ConfigPreset { get; set; } = 0;
}
public class OperationConfigCommon : OperationConfigBase
{
[ConfigOutputResource("OutputResultCommon")]
public override int ResultOutput { get; set; }
}
}

View File

@ -0,0 +1,39 @@
using Bro.Device.Common.Interface;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Bro.Device.Common.Helper;
using System.ComponentModel.DataAnnotations.Schema;
namespace Common.Base
{
public class ProcessBase : IProcess
{
private EnumHelper.ProcessState _currentState = EnumHelper.ProcessState.Idel;
[NotMapped]
public EnumHelper.ProcessState CurrentState
{
get
{
return _currentState;
}
set
{
if (value != _currentState)
{
_currentState = value;
OnStateChanged();
}
}
}
public void OnStateChanged()
{
//throw new NotImplementedException();
}
}
}

View File

@ -0,0 +1,122 @@
using Bro.Common.Base;
using Bro.Common.Helper;
using Bro.Common.Model;
using Bro.Common.Model.Interface;
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Drawing.Design;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Bro.Common.Calibration
{
[Device("CalibrationDynamic9Point", "动态9点标定配置", EnumHelper.DeviceAttributeType.OperationConfig)]
public class CalibrationDynamic9PointConfig : OperationConfigBase, IHalconToolPath
{
[Category("交互设置")]
[Description("电气触发标定动作地址设置为1时触发标定动作。实际地址。")]
public int TriggerAddress { get; set; }
[Category("交互设置")]
[Description("平台位置数据在监视数据中起始地址索引XY坐标连续4位。从0开始。")]
public int LocationStartAddressIndex { get; set; }
[Category("标定结果")]
[Description("标定结果集合")]
[TypeConverter(typeof(CollectionCountConvert))]
[Editor(typeof(ComplexCollectionEditor<CalibrationResult>), typeof(UITypeEditor))]
public NoticedList<CalibrationResult> Results { get; set; } = new NoticedList<CalibrationResult>();
[Category("标定配置")]
[Description("标定步骤总数一般9次")]
public int TotalSteps { get; set; } = 9;
[Category("标定配置")]
[Description("相机操作配置")]
[TypeConverter(typeof(ComplexObjectConvert))]
[Editor(typeof(PropertyObjectEditor), typeof(UITypeEditor))]
public CameraOprerationConfigBase CameraOpConfig { get; set; } = new CameraOprerationConfigBase();
public List<string> GetHalconToolPathList()
{
return CameraOpConfig.GetHalconToolPathList();
}
}
public class CalibrationResult : IComplexDisplay, INotifyPropertyChanged
{
//private Bitmap image = null;
[JsonIgnore]
[Browsable(false)]
public Bitmap Image { get; set; }
//{
// get => image;
// set
// {
// image = value;
// if (value != null)
// {
// PropertyChanged?.Invoke(this, new PropertyChangedEventArgs("Image"));
// }
// }
//}
[Category("标定结果")]
[Description("图像点位|平台点位")]
[TypeConverter(typeof(ComplexObjectConvert))]
[Editor(typeof(PropertyObjectEditor), typeof(UITypeEditor))]
public CalibrationPoint PointResult { get; set; } = new CalibrationPoint();
[Category("标定结果")]
[Description("步骤序号从1开始")]
public int StepNum { get; set; } = 1;
private bool isDone = false;
[JsonIgnore]
[Browsable(false)]
public bool IsDone
{
get => isDone;
set
{
isDone = value;
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs("IsDone"));
}
}
[JsonIgnore]
[Browsable(false)]
public CustomizedPoint ImagePoint
{
set
{
PointResult.U = value.X;
PointResult.V = value.Y;
}
}
[JsonIgnore]
[Browsable(false)]
public CustomizedPoint PlatPoint
{
set
{
PointResult.X = value.X;
PointResult.Y = value.Y;
}
}
public event PropertyChangedEventHandler PropertyChanged;
public string GetDisplayText()
{
return $"{StepNum}{(IsDone == false ? "" : ($"{PointResult.GetDisplayText()}"))}";
//return $"{StepNum}{PointResult.GetDisplayText()}";
}
}
}

View File

@ -0,0 +1,353 @@
namespace Bro.Common.Calibration
{
partial class CalibrationDynamic9PointFrm
{
/// <summary>
/// 必需的设计器变量。
/// </summary>
private System.ComponentModel.IContainer components = null;
/// <summary>
/// 清理所有正在使用的资源。
/// </summary>
/// <param name="disposing">如果应释放托管资源,为 true否则为 false。</param>
protected override void Dispose(bool disposing)
{
if (disposing && (components != null))
{
components.Dispose();
}
base.Dispose(disposing);
}
#region
/// <summary>
/// 设计器支持所需的方法 - 不要修改
/// 使用代码编辑器修改此方法的内容。
/// </summary>
private void InitializeComponent()
{
this.splitMain = new System.Windows.Forms.SplitContainer();
this.plOpBtns = new System.Windows.Forms.Panel();
this.chkManualConfirm = new System.Windows.Forms.CheckBox();
this.label3 = new System.Windows.Forms.Label();
this.label2 = new System.Windows.Forms.Label();
this.label1 = new System.Windows.Forms.Label();
this.chkContinueMode = new System.Windows.Forms.CheckBox();
this.btnCalcuMatrix = new System.Windows.Forms.Button();
this.btnContinueCalib = new System.Windows.Forms.Button();
this.btnSnap = new System.Windows.Forms.Button();
this.btnStepRun = new System.Windows.Forms.Button();
this.btnClearResult = new System.Windows.Forms.Button();
this.btnStartCalib = new System.Windows.Forms.Button();
this.splitConfig = new System.Windows.Forms.SplitContainer();
this.lvResults = new System.Windows.Forms.ListView();
this.clIndex = ((System.Windows.Forms.ColumnHeader)(new System.Windows.Forms.ColumnHeader()));
this.clResult = ((System.Windows.Forms.ColumnHeader)(new System.Windows.Forms.ColumnHeader()));
this.pgCameraConfig = new System.Windows.Forms.PropertyGrid();
this.plImage = new System.Windows.Forms.Panel();
this.stspStatus = new System.Windows.Forms.StatusStrip();
this.tsslStepHint = new System.Windows.Forms.ToolStripStatusLabel();
this.tsslInfo = new System.Windows.Forms.ToolStripStatusLabel();
((System.ComponentModel.ISupportInitialize)(this.splitMain)).BeginInit();
this.splitMain.Panel1.SuspendLayout();
this.splitMain.Panel2.SuspendLayout();
this.splitMain.SuspendLayout();
this.plOpBtns.SuspendLayout();
((System.ComponentModel.ISupportInitialize)(this.splitConfig)).BeginInit();
this.splitConfig.Panel1.SuspendLayout();
this.splitConfig.Panel2.SuspendLayout();
this.splitConfig.SuspendLayout();
this.stspStatus.SuspendLayout();
this.SuspendLayout();
//
// splitMain
//
this.splitMain.Dock = System.Windows.Forms.DockStyle.Fill;
this.splitMain.FixedPanel = System.Windows.Forms.FixedPanel.Panel1;
this.splitMain.Location = new System.Drawing.Point(0, 0);
this.splitMain.Name = "splitMain";
//
// splitMain.Panel1
//
this.splitMain.Panel1.Controls.Add(this.plOpBtns);
this.splitMain.Panel1.Controls.Add(this.splitConfig);
//
// splitMain.Panel2
//
this.splitMain.Panel2.Controls.Add(this.plImage);
this.splitMain.Panel2.Controls.Add(this.stspStatus);
this.splitMain.Size = new System.Drawing.Size(828, 483);
this.splitMain.SplitterDistance = 278;
this.splitMain.TabIndex = 0;
//
// plOpBtns
//
this.plOpBtns.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left)
| System.Windows.Forms.AnchorStyles.Right)));
this.plOpBtns.Controls.Add(this.chkManualConfirm);
this.plOpBtns.Controls.Add(this.label3);
this.plOpBtns.Controls.Add(this.label2);
this.plOpBtns.Controls.Add(this.label1);
this.plOpBtns.Controls.Add(this.chkContinueMode);
this.plOpBtns.Controls.Add(this.btnCalcuMatrix);
this.plOpBtns.Controls.Add(this.btnContinueCalib);
this.plOpBtns.Controls.Add(this.btnSnap);
this.plOpBtns.Controls.Add(this.btnStepRun);
this.plOpBtns.Controls.Add(this.btnClearResult);
this.plOpBtns.Controls.Add(this.btnStartCalib);
this.plOpBtns.Location = new System.Drawing.Point(3, 323);
this.plOpBtns.Name = "plOpBtns";
this.plOpBtns.Size = new System.Drawing.Size(272, 158);
this.plOpBtns.TabIndex = 1;
//
// chkManualConfirm
//
this.chkManualConfirm.AutoSize = true;
this.chkManualConfirm.Location = new System.Drawing.Point(11, 132);
this.chkManualConfirm.Name = "chkManualConfirm";
this.chkManualConfirm.Size = new System.Drawing.Size(72, 16);
this.chkManualConfirm.TabIndex = 3;
this.chkManualConfirm.Text = "人工确认";
this.chkManualConfirm.UseVisualStyleBackColor = true;
//
// label3
//
this.label3.AutoSize = true;
this.label3.Location = new System.Drawing.Point(6, 117);
this.label3.Name = "label3";
this.label3.Size = new System.Drawing.Size(257, 12);
this.label3.TabIndex = 2;
this.label3.Text = "------------------------------------------";
//
// label2
//
this.label2.AutoSize = true;
this.label2.Location = new System.Drawing.Point(6, 76);
this.label2.Name = "label2";
this.label2.Size = new System.Drawing.Size(257, 12);
this.label2.TabIndex = 2;
this.label2.Text = "------------------------------------------";
//
// label1
//
this.label1.AutoSize = true;
this.label1.Location = new System.Drawing.Point(7, 35);
this.label1.Name = "label1";
this.label1.Size = new System.Drawing.Size(257, 12);
this.label1.TabIndex = 2;
this.label1.Text = "------------------------------------------";
//
// chkContinueMode
//
this.chkContinueMode.AutoSize = true;
this.chkContinueMode.Location = new System.Drawing.Point(90, 95);
this.chkContinueMode.Name = "chkContinueMode";
this.chkContinueMode.Size = new System.Drawing.Size(72, 16);
this.chkContinueMode.TabIndex = 1;
this.chkContinueMode.Text = "连续模式";
this.chkContinueMode.UseVisualStyleBackColor = true;
this.chkContinueMode.CheckedChanged += new System.EventHandler(this.chkContinueMode_CheckedChanged);
//
// btnCalcuMatrix
//
this.btnCalcuMatrix.Location = new System.Drawing.Point(168, 50);
this.btnCalcuMatrix.Name = "btnCalcuMatrix";
this.btnCalcuMatrix.Size = new System.Drawing.Size(93, 23);
this.btnCalcuMatrix.TabIndex = 0;
this.btnCalcuMatrix.Text = "标定结果运算";
this.btnCalcuMatrix.UseVisualStyleBackColor = true;
this.btnCalcuMatrix.Click += new System.EventHandler(this.btnCalcuMatrix_Click);
//
// btnContinueCalib
//
this.btnContinueCalib.Location = new System.Drawing.Point(87, 128);
this.btnContinueCalib.Name = "btnContinueCalib";
this.btnContinueCalib.Size = new System.Drawing.Size(75, 23);
this.btnContinueCalib.TabIndex = 0;
this.btnContinueCalib.Text = "继续标定";
this.btnContinueCalib.UseVisualStyleBackColor = true;
this.btnContinueCalib.Visible = false;
this.btnContinueCalib.Click += new System.EventHandler(this.btnContinueCalib_Click);
//
// btnSnap
//
this.btnSnap.Location = new System.Drawing.Point(8, 91);
this.btnSnap.Name = "btnSnap";
this.btnSnap.Size = new System.Drawing.Size(75, 23);
this.btnSnap.TabIndex = 0;
this.btnSnap.Text = "拍 照";
this.btnSnap.UseVisualStyleBackColor = true;
this.btnSnap.Click += new System.EventHandler(this.btnSnap_Click);
//
// btnStepRun
//
this.btnStepRun.Location = new System.Drawing.Point(8, 50);
this.btnStepRun.Name = "btnStepRun";
this.btnStepRun.Size = new System.Drawing.Size(75, 23);
this.btnStepRun.TabIndex = 0;
this.btnStepRun.Text = "单步运算";
this.btnStepRun.UseVisualStyleBackColor = true;
this.btnStepRun.Click += new System.EventHandler(this.btnStepRun_Click);
//
// btnClearResult
//
this.btnClearResult.Location = new System.Drawing.Point(168, 9);
this.btnClearResult.Name = "btnClearResult";
this.btnClearResult.Size = new System.Drawing.Size(93, 23);
this.btnClearResult.TabIndex = 0;
this.btnClearResult.Text = "清除结果";
this.btnClearResult.UseVisualStyleBackColor = true;
this.btnClearResult.Click += new System.EventHandler(this.btnClearResult_Click);
//
// btnStartCalib
//
this.btnStartCalib.Location = new System.Drawing.Point(8, 9);
this.btnStartCalib.Name = "btnStartCalib";
this.btnStartCalib.Size = new System.Drawing.Size(75, 23);
this.btnStartCalib.TabIndex = 0;
this.btnStartCalib.Text = "开始标定";
this.btnStartCalib.UseVisualStyleBackColor = true;
this.btnStartCalib.Click += new System.EventHandler(this.btnStartCalib_Click);
//
// splitConfig
//
this.splitConfig.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom)
| System.Windows.Forms.AnchorStyles.Left)
| System.Windows.Forms.AnchorStyles.Right)));
this.splitConfig.FixedPanel = System.Windows.Forms.FixedPanel.Panel2;
this.splitConfig.Location = new System.Drawing.Point(3, 0);
this.splitConfig.Name = "splitConfig";
this.splitConfig.Orientation = System.Windows.Forms.Orientation.Horizontal;
//
// splitConfig.Panel1
//
this.splitConfig.Panel1.Controls.Add(this.lvResults);
//
// splitConfig.Panel2
//
this.splitConfig.Panel2.Controls.Add(this.pgCameraConfig);
this.splitConfig.Size = new System.Drawing.Size(272, 317);
this.splitConfig.SplitterDistance = 104;
this.splitConfig.TabIndex = 0;
//
// lvResults
//
this.lvResults.Columns.AddRange(new System.Windows.Forms.ColumnHeader[] {
this.clIndex,
this.clResult});
this.lvResults.Dock = System.Windows.Forms.DockStyle.Fill;
this.lvResults.FullRowSelect = true;
this.lvResults.Location = new System.Drawing.Point(0, 0);
this.lvResults.MultiSelect = false;
this.lvResults.Name = "lvResults";
this.lvResults.Size = new System.Drawing.Size(272, 104);
this.lvResults.TabIndex = 0;
this.lvResults.UseCompatibleStateImageBehavior = false;
this.lvResults.View = System.Windows.Forms.View.Details;
this.lvResults.SelectedIndexChanged += new System.EventHandler(this.lvConfigs_SelectedIndexChanged);
//
// clIndex
//
this.clIndex.Text = "序号";
//
// clResult
//
this.clResult.Text = "点位信息";
this.clResult.Width = 200;
//
// pgCameraConfig
//
this.pgCameraConfig.Dock = System.Windows.Forms.DockStyle.Fill;
this.pgCameraConfig.Location = new System.Drawing.Point(0, 0);
this.pgCameraConfig.Name = "pgCameraConfig";
this.pgCameraConfig.Size = new System.Drawing.Size(272, 209);
this.pgCameraConfig.TabIndex = 0;
this.pgCameraConfig.ToolbarVisible = false;
//
// plImage
//
this.plImage.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom)
| System.Windows.Forms.AnchorStyles.Left)
| System.Windows.Forms.AnchorStyles.Right)));
this.plImage.Location = new System.Drawing.Point(-1, 0);
this.plImage.Name = "plImage";
this.plImage.Size = new System.Drawing.Size(547, 458);
this.plImage.TabIndex = 1;
//
// stspStatus
//
this.stspStatus.Items.AddRange(new System.Windows.Forms.ToolStripItem[] {
this.tsslStepHint,
this.tsslInfo});
this.stspStatus.Location = new System.Drawing.Point(0, 461);
this.stspStatus.Name = "stspStatus";
this.stspStatus.Size = new System.Drawing.Size(546, 22);
this.stspStatus.TabIndex = 0;
this.stspStatus.Text = "statusStrip1";
//
// tsslStepHint
//
this.tsslStepHint.Name = "tsslStepHint";
this.tsslStepHint.Size = new System.Drawing.Size(28, 17);
this.tsslStepHint.Text = " ";
//
// tsslInfo
//
this.tsslInfo.Name = "tsslInfo";
this.tsslInfo.Size = new System.Drawing.Size(28, 17);
this.tsslInfo.Text = " ";
//
// CalibrationDynamic9PointFrm
//
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 12F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.ClientSize = new System.Drawing.Size(828, 483);
this.Controls.Add(this.splitMain);
this.Name = "CalibrationDynamic9PointFrm";
this.FormClosing += new System.Windows.Forms.FormClosingEventHandler(this.CalibrationDynamic9PointFrm_FormClosing);
this.Load += new System.EventHandler(this.CtrlCalib9PDynamic_Load);
this.splitMain.Panel1.ResumeLayout(false);
this.splitMain.Panel2.ResumeLayout(false);
this.splitMain.Panel2.PerformLayout();
((System.ComponentModel.ISupportInitialize)(this.splitMain)).EndInit();
this.splitMain.ResumeLayout(false);
this.plOpBtns.ResumeLayout(false);
this.plOpBtns.PerformLayout();
this.splitConfig.Panel1.ResumeLayout(false);
this.splitConfig.Panel2.ResumeLayout(false);
((System.ComponentModel.ISupportInitialize)(this.splitConfig)).EndInit();
this.splitConfig.ResumeLayout(false);
this.stspStatus.ResumeLayout(false);
this.stspStatus.PerformLayout();
this.ResumeLayout(false);
}
#endregion
private System.Windows.Forms.SplitContainer splitMain;
private System.Windows.Forms.Panel plOpBtns;
private System.Windows.Forms.SplitContainer splitConfig;
private System.Windows.Forms.Label label2;
private System.Windows.Forms.Label label1;
private System.Windows.Forms.CheckBox chkContinueMode;
private System.Windows.Forms.Button btnCalcuMatrix;
private System.Windows.Forms.Button btnSnap;
private System.Windows.Forms.Button btnStepRun;
private System.Windows.Forms.Button btnStartCalib;
private System.Windows.Forms.Panel plImage;
private System.Windows.Forms.StatusStrip stspStatus;
private System.Windows.Forms.ToolStripStatusLabel tsslStepHint;
private System.Windows.Forms.ToolStripStatusLabel tsslInfo;
private System.Windows.Forms.ListView lvResults;
private System.Windows.Forms.ColumnHeader clIndex;
private System.Windows.Forms.ColumnHeader clResult;
private System.Windows.Forms.PropertyGrid pgCameraConfig;
private System.Windows.Forms.CheckBox chkManualConfirm;
private System.Windows.Forms.Label label3;
private System.Windows.Forms.Button btnContinueCalib;
private System.Windows.Forms.Button btnClearResult;
}
}

View File

@ -0,0 +1,403 @@
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Data;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using Bro.Common.Helper;
using Bro.Common.Interface;
using Bro.Common.Base;
using Bro.Common.UI;
using Bro.Common.PubSub;
using static Bro.Common.Helper.EnumHelper;
using Bro.Common.Model;
using HalconDotNet;
using System.Threading;
using System.Collections.Specialized;
namespace Bro.Common.Calibration
{
public partial class CalibrationDynamic9PointFrm : Form
{
//PubSubCenter PubSubCenter = PubSubCenter.GetInstance();
AutoResetEvent _confirmHandle = new AutoResetEvent(false);
public CalibrationDynamic9PointFrm()
{
InitializeComponent();
}
public CalibrationDynamic9PointFrm(CameraBase camera, PLCBase plc, CalibrationDynamic9PointConfig config)
{
InitializeComponent();
Camera = camera;
PLC = plc;
Config = config as CalibrationDynamic9PointConfig;
}
public CalibrationDynamic9PointConfig Config { get; set; }
public CameraBase Camera { get; set; }
public PLCBase PLC { get; set; }
public CalibrationDynamic9PointConfig GetConfig()
{
return null;
}
public void LoadConfig(CalibrationDynamic9PointConfig config)
{
FillResults();
if (lvResults.Items.Count > 0)
{
lvResults.Items[0].Selected = true;
}
pgCameraConfig.SelectedObject = config.CameraOpConfig;
}
private void FillResults()
{
if (this.InvokeRequired)
{
this.Invoke(new Action(() => FillResults()));
}
else
{
lvResults.Items.Clear();
for (int i = 0; i < Config.Results.Count; i++)
{
ListViewItem item = new ListViewItem(Config.Results[i].StepNum.ToString());
item.SubItems.Add(Config.Results[i].GetDisplayText());
item.Tag = Config.Results[i];
item.BackColor = Config.Results[i].IsDone ? Color.GreenYellow : Color.Transparent;
//if (Config.Results[i].Image != null)
//{
// item.BackColor = Color.GreenYellow;
//}
//else
//{
// item.BackColor = Color.Transparent;
//}
Config.Results[i].PropertyChanged -= CtrlCalib9PDynamic_PropertyChanged;
Config.Results[i].PropertyChanged += CtrlCalib9PDynamic_PropertyChanged;
lvResults.Items.Add(item);
}
}
}
private void CtrlCalib9PDynamic_PropertyChanged(object sender, PropertyChangedEventArgs e)
{
FillResults();
}
//private void OnCalibPropertyChanged()
//{
// if (this.InvokeRequired)
// {
// this.Invoke(new Action(() => OnCalibPropertyChanged()));
// }
// else
// {
// for (int i = 0; i < Config.Results.Count; i++)
// {
// if (Config.Results[i].Image != null)
// {
// lvResults.Items[i].BackColor = Color.GreenYellow;
// }
// else
// {
// lvResults.Items[i].BackColor = Color.Transparent;
// }
// }
// }
//}
Canvas _canvas = new Canvas();
private void CtrlCalib9PDynamic_Load(object sender, EventArgs e)
{
_canvas.IsShowElementList = true;
_canvas.Dock = DockStyle.Fill;
plImage.Controls.Add(_canvas);
RemoveHandles();
if (Camera != null)
{
Camera.OnImageUpdated -= Camera_UpdateShowImage;
Camera.OnImageUpdated += Camera_UpdateShowImage;
}
Config.Results.OnItemChanged = OnResultsListChanged;
LoadConfig(Config);
}
private void OnResultsListChanged(NotifyCollectionChangedAction obj)
{
if (this.InvokeRequired)
{
this.Invoke(new Action(() => FillResults()));
}
else
{
FillResults();
}
}
public void RemoveHandles()
{
if (Camera != null)
{
Camera.OnImageUpdated -= Camera_UpdateShowImage;
}
//PubSubCenter.RemoveSubscriber(PubTag.CalibStepDone.ToString(), CalibStepDone);
//PubSubCenter.RemoveSubscriber(PubTag.CalibAllDone.ToString(), CalibAllDone);
chkContinueMode.Checked = false;
}
AutoResetEvent _imageShowedHandle = new AutoResetEvent(false);
private void Camera_UpdateShowImage(CameraBase camera, Bitmap image)
{
if (this.InvokeRequired)
{
this.Invoke(new Action<CameraBase, Bitmap>(Camera_UpdateShowImage), camera, image);
}
else
{
_canvas.LoadImage(image);
_imageShowedHandle.Set();
}
}
//private object CalibAllDone(ISubscriber arg1, object arg2, object arg3)
//{
// string msg = arg3.ToString();
// tsslInfo.Text = msg;
// return null;
//}
//private object CalibStepDone(ISubscriber arg1, object arg2, object arg3)
//{
// int index = Convert.ToInt32(arg2);
// _canvas.LoadImage(Config.Results[index].Image);
// _canvas.Elements.Clear();
// CrossHair ch = new CrossHair(Config.Results[index].PointResult);
// _canvas.Elements.Add(ch);
// tsslInfo.Text = $"步骤{index + 1}完成";
// if (chkManualConfirm.Checked)
// {
// this.Invoke(new Action(() => btnContinueCalib.Visible = true)); ;
// _confirmHandle.WaitOne();
// }
// return null;
//}
private void lvConfigs_SelectedIndexChanged(object sender, EventArgs e)
{
if (lvResults.SelectedItems.Count <= 0)
return;
var result = lvResults.SelectedItems[0].Tag as CalibrationResult;
tsslStepHint.Text = $"{(result.StepNum)}/{Config.TotalSteps}";
if (result.Image != null)
{
_canvas.LoadImage(result.Image);
_canvas.Elements.Clear();
_canvas.Elements.Add(new CrossHair(result.PointResult));
}
}
private void btnStartCalib_Click(object sender, EventArgs e)
{
if (OnStartCalibration == null)
{
throw new ProcessException("StartCalibration不能为空");
}
OnStartCalibration(PLC, Config.TriggerAddress);
}
private void btnStepRun_Click(object sender, EventArgs e)
{
int stepNum = 1;
if (lvResults.SelectedItems.Count > 0)
{
var step = lvResults.SelectedItems[0].Tag as CalibrationResult;
stepNum = step.StepNum;
}
var config = pgCameraConfig.SelectedObject as CameraOprerationConfigBase;
if (OnCalculateStep == null)
{
MessageBox.Show("单步运算函数为空");
return;
}
try
{
CalibrationResult result = OnCalculateStep(Camera, PLC, Config, stepNum);
ShowCalibStepDone(result);
}
catch (Exception ex)
{
MessageBox.Show(ex.GetExceptionMessage());
}
}
private void btnCalcuMatrix_Click(object sender, EventArgs e)
{
if (OnCalculateAll == null)
{
MessageBox.Show("标定结果运算函数为空");
return;
}
try
{
string result = OnCalculateAll(Camera, Config);
ShowCalibAllDone(result);
}
catch (Exception ex)
{
MessageBox.Show(ex.GetExceptionMessage());
}
}
private void btnSnap_Click(object sender, EventArgs e)
{
CameraOprerationConfigBase config = pgCameraConfig.SelectedObject as CameraOprerationConfigBase;
Camera.UploadOperationConfig(config);
Camera.Snapshot(config, out HObject hImage);
hImage.Dispose();
}
private bool _isContinueMode = false;
CameraOprerationConfigBase _selectedCameraOpConfig = null;
private void chkContinueMode_CheckedChanged(object sender, EventArgs e)
{
_selectedCameraOpConfig = pgCameraConfig.SelectedObject as CameraOprerationConfigBase;
_isContinueMode = chkContinueMode.Checked;
if (_isContinueMode)
{
bool temp = _selectedCameraOpConfig.IsSaveOriginImage;
_selectedCameraOpConfig.IsSaveOriginImage = false;
Task.Run(() =>
{
while (_isContinueMode)
{
try
{
Camera.UploadOperationConfig(_selectedCameraOpConfig);
Camera.Snapshot();
_imageShowedHandle.WaitOne(3000);
}
catch (Exception)
{
}
}
_selectedCameraOpConfig.IsSaveOriginImage = temp;
});
}
}
private void btnContinueCalib_Click(object sender, EventArgs e)
{
_confirmHandle.Set();
btnContinueCalib.Visible = false;
}
private void CalibrationDynamic9PointFrm_FormClosing(object sender, FormClosingEventArgs e)
{
RemoveHandles();
}
#region
//public virtual void StartCalibration()
//{
//}
//public virtual void CalibMarkPoint(CameraBase camera, CalibrationDynamic9PointConfig config, int stepIndex)
//{
//}
//public virtual void CalculationMatrix(List<CalibrationDynamic9PointConfig> configs)
//{
//}
public Action<PLCBase, int> OnStartCalibration { get; set; }
public Func<CameraBase, PLCBase, CalibrationDynamic9PointConfig, int, CalibrationResult> OnCalculateStep { get; set; }
public Func<CameraBase, CalibrationDynamic9PointConfig, string> OnCalculateAll { get; set; }
#endregion
#region UI显示
private void ShowCalibStepDone(CalibrationResult result)
{
if (this.InvokeRequired)
{
this.Invoke(new Action<CalibrationResult>(ShowCalibStepDone), result);
}
else
{
//_canvas.LoadImage(result.Image);
_canvas.Elements.Clear();
CrossHair ch = new CrossHair(result.PointResult);
_canvas.Elements.Add(ch);
tsslInfo.Text = $"步骤{result.StepNum}完成,{result.PointResult.GetDisplayText()}";
if (chkManualConfirm.Checked)
{
btnContinueCalib.Visible = true;
}
if (chkManualConfirm.Checked)
{
_confirmHandle.WaitOne();
}
}
}
private void ShowCalibAllDone(string msg)
{
if (this.InvokeRequired)
{
this.Invoke(new Action<string>(ShowCalibAllDone), msg);
}
else
{
tsslInfo.Text = msg;
}
}
#endregion
private void btnClearResult_Click(object sender, EventArgs e)
{
Config.Results.ForEach(r =>
{
r.Image = null;
r.PointResult = new CalibrationPoint();
r.IsDone = false;
});
}
}
}

View File

@ -0,0 +1,126 @@
<?xml version="1.0" encoding="utf-8"?>
<root>
<!--
Microsoft ResX Schema
Version 2.0
The primary goals of this format is to allow a simple XML format
that is mostly human readable. The generation and parsing of the
various data types are done through the TypeConverter classes
associated with the data types.
Example:
... ado.net/XML headers & schema ...
<resheader name="resmimetype">text/microsoft-resx</resheader>
<resheader name="version">2.0</resheader>
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
<value>[base64 mime encoded serialized .NET Framework object]</value>
</data>
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
<comment>This is a comment</comment>
</data>
There are any number of "resheader" rows that contain simple
name/value pairs.
Each data row contains a name, and value. The row also contains a
type or mimetype. Type corresponds to a .NET class that support
text/value conversion through the TypeConverter architecture.
Classes that don't support this are serialized and stored with the
mimetype set.
The mimetype is used for serialized objects, and tells the
ResXResourceReader how to depersist the object. This is currently not
extensible. For a given mimetype the value must be set accordingly:
Note - application/x-microsoft.net.object.binary.base64 is the format
that the ResXResourceWriter will generate, however the reader can
read any of the formats listed below.
mimetype: application/x-microsoft.net.object.binary.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.soap.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.bytearray.base64
value : The object must be serialized into a byte array
: using a System.ComponentModel.TypeConverter
: and then encoded with base64 encoding.
-->
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
<xsd:element name="root" msdata:IsDataSet="true">
<xsd:complexType>
<xsd:choice maxOccurs="unbounded">
<xsd:element name="metadata">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" />
</xsd:sequence>
<xsd:attribute name="name" use="required" type="xsd:string" />
<xsd:attribute name="type" type="xsd:string" />
<xsd:attribute name="mimetype" type="xsd:string" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="assembly">
<xsd:complexType>
<xsd:attribute name="alias" type="xsd:string" />
<xsd:attribute name="name" type="xsd:string" />
</xsd:complexType>
</xsd:element>
<xsd:element name="data">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="resheader">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" />
</xsd:complexType>
</xsd:element>
</xsd:choice>
</xsd:complexType>
</xsd:element>
</xsd:schema>
<resheader name="resmimetype">
<value>text/microsoft-resx</value>
</resheader>
<resheader name="version">
<value>2.0</value>
</resheader>
<resheader name="reader">
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<metadata name="stspStatus.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
<value>17, 17</value>
</metadata>
<metadata name="$this.TrayHeight" type="System.Int32, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>37</value>
</metadata>
</root>

View File

@ -0,0 +1,100 @@
using Bro.Common.Base;
using Bro.Common.Helper;
using Bro.Common.UI;
using Newtonsoft.Json;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing.Design;
namespace Bro.Common.Calibration
{
[Device("CalibrationStatic9Point", "静态9点标定", EnumHelper.DeviceAttributeType.OperationConfig)]
public class CalibrationStatic9PointConfigCollection : OperationConfigBase
{
[Category("标定配置")]
[Description("标定配置集合")]
[TypeConverter(typeof(CollectionCountConvert))]
[Editor(typeof(ComplexCollectionEditor<CalibrationStatic9PointConfig>), typeof(UITypeEditor))]
public List<CalibrationStatic9PointConfig> Configs { get; set; } = new List<CalibrationStatic9PointConfig>();
}
public class CalibrationStatic9PointConfig : OperationConfigBase, IComplexDisplay
{
[Category("相机配置")]
[Description("是否相机实时取图")]
public bool IsUseRealTimeImage { get; set; } = true;
[Category("相机配置")]
[Description("相机操作配置")]
[TypeConverter(typeof(ComplexObjectConvert))]
[Editor(typeof(PropertyObjectEditor), typeof(UITypeEditor))]
public CameraOprerationConfigBase CameraOpConfig { get; set; } = new CameraOprerationConfigBase();
[Category("标定配置")]
[Description("XY坐标是否颠倒")]
public bool IsInvert { get; set; } = false;
[Category("标定配置")]
[Description("标定X方向间隔")]
public int IntervalX { get; set; }
[Category("标定配置")]
[Description("标定Y方向间隔")]
public int IntervalY { get; set; }
[Category("标定配置")]
[Description("可忽略的像素差值,取像点的坐标差值必须大于该值才被采用")]
public int IgnorePixel { get; set; } = 20;
[Category("ROI配置")]
[Description("标定点的ROI范围集合")]
[TypeConverter(typeof(CollectionCountConvert))]
[Editor(typeof(ComplexCollectionEditor<ROI_Circle>), typeof(UITypeEditor))]
public List<ROI_Circle> ROIList { get; set; } = new List<ROI_Circle>();
[Category("ROI配置")]
[Description("ROI默认半径")]
public float ROI_Radius { get; set; } = 50.0f;
[Category("ROI配置")]
[Description("是否启动ROI过滤")]
public bool IsEnableROIFilter { get; set; } = true;
[Category("UI显示配置")]
[Description("是否显示备注说明")]
public bool IsShowRemark { get; set; } = true;
public string GetDisplayText()
{
return JsonConvert.SerializeObject(this);
}
}
public class PLCSetting : IComplexDisplay
{
[Category("地址设置")]
[Description("X坐标PLC读取地址例如5012")]
public int XAddress { get; set; }
[Category("地址设置")]
[Description("Y坐标PLC读取地址例如5012")]
public int YAddress { get; set; }
[Category("地址设置")]
[Description("是否实时读取PLC地址")]
public bool IsRealTimeDataFromPLC { get; set; } = true;
[Category("运动设置")]
[Description("运动坐标X")]
public int LocationX { get; set; }
[Category("运动设置")]
[Description("运动坐标Y")]
public int LocationY { get; set; }
public string GetDisplayText()
{
return string.Format("X:{0};Y:{1}", LocationX, LocationY);
}
}
}

View File

@ -0,0 +1,234 @@
namespace Bro.Common.Calibration
{
partial class CalibrationStatic9PointFrm
{
/// <summary>
/// Required designer variable.
/// </summary>
private System.ComponentModel.IContainer components = null;
/// <summary>
/// Clean up any resources being used.
/// </summary>
/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
protected override void Dispose(bool disposing)
{
if (disposing && (components != null))
{
components.Dispose();
}
base.Dispose(disposing);
}
#region Windows Form Designer generated code
/// <summary>
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
/// </summary>
private void InitializeComponent()
{
this.btnDone = new System.Windows.Forms.Button();
this.btnCancel = new System.Windows.Forms.Button();
this.btnCalibrate = new System.Windows.Forms.Button();
this.txtAlgorithemPath = new System.Windows.Forms.TextBox();
this.btnQuickSetXY = new System.Windows.Forms.Button();
this.propCalibrationConfig = new System.Windows.Forms.PropertyGrid();
this.btnReSnap = new System.Windows.Forms.Button();
this.btnTest = new System.Windows.Forms.Button();
this.btnReadLocation = new System.Windows.Forms.Button();
this.btnReloadAlgorithem = new System.Windows.Forms.Button();
this.btnClearROI = new System.Windows.Forms.Button();
this.plCanvas = new System.Windows.Forms.Panel();
this.chkContinueMode = new System.Windows.Forms.CheckBox();
this.SuspendLayout();
//
// btnDone
//
this.btnDone.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right)));
this.btnDone.Location = new System.Drawing.Point(700, 458);
this.btnDone.Name = "btnDone";
this.btnDone.Size = new System.Drawing.Size(76, 23);
this.btnDone.TabIndex = 1;
this.btnDone.Text = "标定完成";
this.btnDone.UseVisualStyleBackColor = true;
this.btnDone.Click += new System.EventHandler(this.btnDone_Click);
//
// btnCancel
//
this.btnCancel.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right)));
this.btnCancel.Location = new System.Drawing.Point(618, 458);
this.btnCancel.Name = "btnCancel";
this.btnCancel.Size = new System.Drawing.Size(76, 23);
this.btnCancel.TabIndex = 1;
this.btnCancel.Text = "取消配置";
this.btnCancel.UseVisualStyleBackColor = true;
this.btnCancel.Click += new System.EventHandler(this.btnCancel_Click);
//
// btnCalibrate
//
this.btnCalibrate.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right)));
this.btnCalibrate.Location = new System.Drawing.Point(700, 408);
this.btnCalibrate.Name = "btnCalibrate";
this.btnCalibrate.Size = new System.Drawing.Size(76, 23);
this.btnCalibrate.TabIndex = 1;
this.btnCalibrate.Text = "运行标定";
this.btnCalibrate.UseVisualStyleBackColor = true;
this.btnCalibrate.Click += new System.EventHandler(this.btnCalibrate_Click);
//
// txtAlgorithemPath
//
this.txtAlgorithemPath.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left)
| System.Windows.Forms.AnchorStyles.Right)));
this.txtAlgorithemPath.Location = new System.Drawing.Point(12, 459);
this.txtAlgorithemPath.Name = "txtAlgorithemPath";
this.txtAlgorithemPath.ReadOnly = true;
this.txtAlgorithemPath.Size = new System.Drawing.Size(371, 21);
this.txtAlgorithemPath.TabIndex = 2;
//
// btnQuickSetXY
//
this.btnQuickSetXY.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right)));
this.btnQuickSetXY.Location = new System.Drawing.Point(389, 458);
this.btnQuickSetXY.Name = "btnQuickSetXY";
this.btnQuickSetXY.Size = new System.Drawing.Size(104, 23);
this.btnQuickSetXY.TabIndex = 1;
this.btnQuickSetXY.Text = "快捷配置XY坐标";
this.btnQuickSetXY.UseVisualStyleBackColor = true;
this.btnQuickSetXY.Click += new System.EventHandler(this.btnQuickSetXY_Click);
//
// propCalibrationConfig
//
this.propCalibrationConfig.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom)
| System.Windows.Forms.AnchorStyles.Right)));
this.propCalibrationConfig.Location = new System.Drawing.Point(499, 12);
this.propCalibrationConfig.Name = "propCalibrationConfig";
this.propCalibrationConfig.Size = new System.Drawing.Size(277, 390);
this.propCalibrationConfig.TabIndex = 3;
this.propCalibrationConfig.ToolbarVisible = false;
//
// btnReSnap
//
this.btnReSnap.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right)));
this.btnReSnap.Location = new System.Drawing.Point(618, 408);
this.btnReSnap.Name = "btnReSnap";
this.btnReSnap.Size = new System.Drawing.Size(76, 23);
this.btnReSnap.TabIndex = 1;
this.btnReSnap.Text = "重新拍照";
this.btnReSnap.UseVisualStyleBackColor = true;
this.btnReSnap.Click += new System.EventHandler(this.btnReSnap_Click);
//
// btnTest
//
this.btnTest.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right)));
this.btnTest.Location = new System.Drawing.Point(499, 457);
this.btnTest.Name = "btnTest";
this.btnTest.Size = new System.Drawing.Size(76, 23);
this.btnTest.TabIndex = 1;
this.btnTest.Text = "test";
this.btnTest.UseVisualStyleBackColor = true;
this.btnTest.Visible = false;
this.btnTest.Click += new System.EventHandler(this.btnTest_Click);
//
// btnReadLocation
//
this.btnReadLocation.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right)));
this.btnReadLocation.Location = new System.Drawing.Point(499, 408);
this.btnReadLocation.Name = "btnReadLocation";
this.btnReadLocation.Size = new System.Drawing.Size(113, 23);
this.btnReadLocation.TabIndex = 1;
this.btnReadLocation.Text = "PLC读取坐标";
this.btnReadLocation.UseVisualStyleBackColor = true;
this.btnReadLocation.Click += new System.EventHandler(this.btnReadLocation_Click);
//
// btnReloadAlgorithem
//
this.btnReloadAlgorithem.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right)));
this.btnReloadAlgorithem.Location = new System.Drawing.Point(700, 433);
this.btnReloadAlgorithem.Name = "btnReloadAlgorithem";
this.btnReloadAlgorithem.Size = new System.Drawing.Size(76, 23);
this.btnReloadAlgorithem.TabIndex = 1;
this.btnReloadAlgorithem.Text = "载入算法";
this.btnReloadAlgorithem.UseVisualStyleBackColor = true;
this.btnReloadAlgorithem.Click += new System.EventHandler(this.btnReloadAlgorithem_Click);
//
// btnClearROI
//
this.btnClearROI.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right)));
this.btnClearROI.Location = new System.Drawing.Point(618, 433);
this.btnClearROI.Name = "btnClearROI";
this.btnClearROI.Size = new System.Drawing.Size(76, 23);
this.btnClearROI.TabIndex = 1;
this.btnClearROI.Text = "清除ROI";
this.btnClearROI.UseVisualStyleBackColor = true;
this.btnClearROI.Click += new System.EventHandler(this.btnClearROI_Click);
//
// plCanvas
//
this.plCanvas.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom)
| System.Windows.Forms.AnchorStyles.Left)
| System.Windows.Forms.AnchorStyles.Right)));
this.plCanvas.Location = new System.Drawing.Point(12, 12);
this.plCanvas.Name = "plCanvas";
this.plCanvas.Size = new System.Drawing.Size(481, 441);
this.plCanvas.TabIndex = 4;
//
// chkContinueMode
//
this.chkContinueMode.AutoSize = true;
this.chkContinueMode.Location = new System.Drawing.Point(502, 436);
this.chkContinueMode.Name = "chkContinueMode";
this.chkContinueMode.Size = new System.Drawing.Size(72, 16);
this.chkContinueMode.TabIndex = 5;
this.chkContinueMode.Text = "连续模式";
this.chkContinueMode.UseVisualStyleBackColor = true;
this.chkContinueMode.CheckedChanged += new System.EventHandler(this.chkContinueMode_CheckedChanged);
//
// CalibrationProcessFrm
//
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 12F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.ClientSize = new System.Drawing.Size(788, 496);
this.ControlBox = false;
this.Controls.Add(this.chkContinueMode);
this.Controls.Add(this.plCanvas);
this.Controls.Add(this.propCalibrationConfig);
this.Controls.Add(this.txtAlgorithemPath);
this.Controls.Add(this.btnReloadAlgorithem);
this.Controls.Add(this.btnClearROI);
this.Controls.Add(this.btnCalibrate);
this.Controls.Add(this.btnQuickSetXY);
this.Controls.Add(this.btnTest);
this.Controls.Add(this.btnCancel);
this.Controls.Add(this.btnReadLocation);
this.Controls.Add(this.btnReSnap);
this.Controls.Add(this.btnDone);
this.KeyPreview = true;
this.Name = "CalibrationProcessFrm";
this.StartPosition = System.Windows.Forms.FormStartPosition.CenterParent;
this.Text = "标定过程界面";
this.WindowState = System.Windows.Forms.FormWindowState.Maximized;
this.FormClosing += new System.Windows.Forms.FormClosingEventHandler(this.CalibrationProcessFrm_FormClosing);
this.ResumeLayout(false);
this.PerformLayout();
}
#endregion
//private Common.UI.Canvas canvas1;
private System.Windows.Forms.Button btnDone;
private System.Windows.Forms.Button btnCancel;
private System.Windows.Forms.Button btnCalibrate;
private System.Windows.Forms.TextBox txtAlgorithemPath;
private System.Windows.Forms.Button btnQuickSetXY;
private System.Windows.Forms.PropertyGrid propCalibrationConfig;
private System.Windows.Forms.Button btnReSnap;
private System.Windows.Forms.Button btnTest;
private System.Windows.Forms.Button btnReadLocation;
private System.Windows.Forms.Button btnReloadAlgorithem;
private System.Windows.Forms.Button btnClearROI;
private System.Windows.Forms.Panel plCanvas;
private System.Windows.Forms.CheckBox chkContinueMode;
}
}

View File

@ -0,0 +1,393 @@
using Bro.Common.Base;
using Bro.Common.Helper;
using Bro.Common.Model;
using Bro.Common.UI;
using HalconDotNet;
using System;
using System.Collections.Generic;
using System.Data;
using System.Drawing;
using System.IO;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace Bro.Common.Calibration
{
public partial class CalibrationStatic9PointFrm : Form
{
/// <summary>
/// 标定点位信息
/// </summary>
public List<CalibrationPoint> CPoints
{
get
{
return canvas1.Elements.Where(p => p.IsEnabled && (p is CrossHair)).Select(p => ((CrossHair)p).CenterPoint).ToList();
}
}
/// <summary>
/// 运动点位信息
/// </summary>
public CustomizedPoint MovingPosition { get; set; } = new CustomizedPoint();
Canvas canvas1 = new Canvas();
PLCBase PLC = null;
CameraBase Camera = null;
Bitmap Image = null;
CalibrationStatic9PointConfig Config = null;
HDevEngineTool tool = null;
public CalibrationStatic9PointFrm()
{
InitializeComponent();
canvas1 = new Canvas();
canvas1.Dock = DockStyle.Fill;
plCanvas.Controls.Add(canvas1);
}
public CalibrationStatic9PointFrm(string display, CameraBase camera, PLCBase plc, Bitmap image, CalibrationStatic9PointConfig config)
{
InitializeComponent();
if (!string.IsNullOrWhiteSpace(display))
{
this.Text = display;
}
Camera = camera;
PLC = plc;
Image = image;
propCalibrationConfig.SelectedObject = Config = config;
Camera.OnImageUpdated -= Camera_UpdateShowImage;
Camera.OnImageUpdated += Camera_UpdateShowImage;
canvas1.LoadImage(Image);
LoadHalconTool();
}
AutoResetEvent _imgShowedHandle = new AutoResetEvent(true);
private void Camera_UpdateShowImage(CameraBase camera, Bitmap image)
{
if (this.InvokeRequired)
{
this.Invoke(new Action(() => LoadImage(image)));
}
else
{
LoadImage(image);
}
}
private void LoadImage(Bitmap image)
{
canvas1.LoadImage(image);
_imgShowedHandle.Set();
}
private void PointTest()
{
canvas1.Elements.Clear();
for (int i = 0; i < 3; i++)
{
for (int j = 0; j < 3; j++)
{
PointF p = new PointF();
p.X = 300 + i * 100;
p.Y = 500 + j * 150;
CrossHair ch = new CrossHair(new CalibrationPoint(p));
ch.Index = i * 3 + j + 1;
ch.Name = p.X.ToString() + "--" + p.Y.ToString();
canvas1.Elements.Add(ch);
}
}
}
private void LoadHalconTool()
{
if (string.IsNullOrWhiteSpace(Config.CameraOpConfig.AlgorithemPath))
{
return;
}
txtAlgorithemPath.Text = Config.CameraOpConfig.AlgorithemPath;
string directoryPath = Path.GetDirectoryName(Config.CameraOpConfig.AlgorithemPath);
string fileName = Path.GetFileNameWithoutExtension(Config.CameraOpConfig.AlgorithemPath);
tool = new HDevEngineTool(directoryPath);
tool.LoadProcedure(fileName);
Thread.Sleep(1000);
}
private void btnCancel_Click(object sender, EventArgs e)
{
this.DialogResult = DialogResult.Cancel;
}
private void btnDone_Click(object sender, EventArgs e)
{
if (CPoints.Count < 9)
{
if (MessageBox.Show("一般需设置至少9个标定点的信息是否确认完成", "完成确认", MessageBoxButtons.OKCancel, MessageBoxIcon.Warning) != DialogResult.OK)
return;
}
if (CPoints.Count(p => p.X == 0 && p.Y == 0) > 1)
{
if (MessageBox.Show("标定点的XY信息未设置完成是否确认完成", "完成确认", MessageBoxButtons.OKCancel, MessageBoxIcon.Warning) != DialogResult.OK)
return;
}
GetCurrentPosition();
if (Config.IsEnableROIFilter)
{
Config.ROIList.Clear();
CPoints.ForEach(u =>
{
ROI_Circle circle = new ROI_Circle();
if (u.IsBasePoint)
{
circle.ROI_Index = "1";
}
circle.Center = new CustomizedPoint(u.U, u.V);
circle.Radius = Config.ROI_Radius;
Config.ROIList.Add(circle);
});
}
this.DialogResult = DialogResult.OK;
}
public virtual void GetCurrentPosition()
{
//if (Config.PLCSetting.IsRealTimeDataFromPLC)
//{
// int x = PLC.Read(Config.PLCSetting.XAddress, 2).ParseUnsignShortListToInt()[0];
// int y = PLC.Read(Config.PLCSetting.YAddress, 2).ParseUnsignShortListToInt()[0];
// MovingPosition = new CustomizedPoint(x, y);
// Config.PLCSetting.LocationX = x;
// Config.PLCSetting.LocationY = y;
//}
//else
//{
// MovingPosition = new CustomizedPoint(Config.PLCSetting.LocationX, Config.PLCSetting.LocationY);
//}
}
private void btnCalibrate_Click(object sender, EventArgs e)
{
DoCalibration();
}
private void DoCalibration()
{
canvas1.Elements.Clear();
if (Config.IsEnableROIFilter)
{
Config.ROIList.ForEach(r =>
{
canvas1.Elements.Add(r);
});
}
try
{
HTuple outputX = new HTuple();
HTuple outputY = new HTuple();
using (HObject hImage = canvas1.MAP.ConvertBitmapToHObject())
{
tool.InputImageDic.Clear();
tool.InputImageDic["INPUT_Image"] = hImage;
tool.RunProcedure();
if (!tool.IsSuccessful)
throw new ProcessException($"{Config.CameraOpConfig.AlgorithemPath}算法运行失败");
outputX = tool.GetResultTuple("OUTPUT_X");
outputY = tool.GetResultTuple("OUTPUT_Y");
}
List<CrossHair> chList = new List<CrossHair>();
for (int i = 0; i < outputX.DArr.Length; i++)
{
CalibrationPoint point = new CalibrationPoint(new PointF((float)outputX.DArr[i], (float)outputY.DArr[i]));
if (Config.IsEnableROIFilter && Config.ROIList.Count > 0)
{
var roi = Config.ROIList.FirstOrDefault(r => r.IsMouseInSide(new Point((int)point.U, (int)point.V)));
if (roi != null)
{
CrossHair ch = new CrossHair(point);
ch.IsShowRemark = Config.IsShowRemark;
ch.Index = i + 1;
ch.Name = point.U.ToString("f3") + "--" + point.V.ToString("f3");
if (roi.ROI_Index == "1")
{
ch.CenterPoint.IsBasePoint = true;
}
chList.Add(ch);
}
}
else
{
CrossHair ch = new CrossHair(point);
ch.IsShowRemark = Config.IsShowRemark;
ch.Index = i + 1;
ch.Name = point.U.ToString("f3") + "--" + point.V.ToString("f3");
chList.Add(ch);
}
}
Config.ROIList.ForEach(r =>
{
canvas1.Elements.Add(r);
});
}
catch (Exception ex)
{
MessageBox.Show(ex.GetExceptionMessage());
}
}
private void btnQuickSetXY_Click(object sender, EventArgs e)
{
if (MessageBox.Show("快捷设置XY坐标仅适用于标定坐标系和相机坐标系基本平行情况下", "提示", MessageBoxButtons.OKCancel, MessageBoxIcon.Asterisk) != DialogResult.OK)
{
return;
}
if (CPoints.Count(p => p.IsBasePoint) > 1)
{
MessageBox.Show("基准点只能选择一个");
return;
}
var basePoint = CPoints.FirstOrDefault(p => p.IsBasePoint);
if (basePoint == null)
{
MessageBox.Show("请选择一个基准点");
return;
}
List<float> uList = CPoints.Select(p => Math.Abs(p.U - basePoint.U)).OrderBy(u => u).ToList();
List<float> vList = CPoints.Select(p => Math.Abs(p.V - basePoint.V)).OrderBy(u => u).ToList();
float intervalU = uList.FirstOrDefault(u => u > Config.IgnorePixel);
float intervalV = vList.FirstOrDefault(u => u > Config.IgnorePixel);
CPoints.ForEach(p =>
{
if (!p.IsBasePoint)
{
if (Config.IsInvert)
{
p.X = (int)(Math.Round((p.V - basePoint.V) / intervalV)) * Config.IntervalX + basePoint.X;
p.Y = (int)(Math.Round((p.U - basePoint.U) / intervalU)) * Config.IntervalY + basePoint.Y;
}
else
{
p.X = (int)(Math.Round((p.U - basePoint.U) / intervalU)) * Config.IntervalX + basePoint.X;
p.Y = (int)(Math.Round((p.V - basePoint.V) / intervalV)) * Config.IntervalY + basePoint.Y;
}
}
else
{
if (Config.IsEnableROIFilter)
{
var roi1st = Config.ROIList.FirstOrDefault(u => u.IsMouseInSide(new Point((int)p.U, (int)p.V)));
if (roi1st != null)
{
roi1st.ROI_Index = "1";
}
}
}
});
MessageBox.Show("快捷配置完成!");
}
private void btnReSnap_Click(object sender, EventArgs e)
{
Camera.Snapshot(Config.CameraOpConfig, out HObject hImage);
hImage.Dispose();
}
private void chkContinueMode_CheckedChanged(object sender, EventArgs e)
{
if (chkContinueMode.Checked)
{
Task.Run(() =>
{
while (chkContinueMode.Checked)
{
Camera.Snapshot(Config.CameraOpConfig, out HObject hImage);
hImage.Dispose();
_imgShowedHandle.WaitOne(3000);
}
});
}
}
private void btnTest_Click(object sender, EventArgs e)
{
PointTest();
}
private void btnReadLocation_Click(object sender, EventArgs e)
{
//int x = PLC.Read(Config.PLCSetting.XAddress, 2).ParseUnsignShortListToInt()[0];
//int y = PLC.Read(Config.PLCSetting.YAddress, 2).ParseUnsignShortListToInt()[0];
//string msg = string.Format("X:{0};Y:{1}", x, y);
//if (MessageBox.Show(msg + "\r\n是否保存到配置", "坐标获取", MessageBoxButtons.YesNo, MessageBoxIcon.Question) == DialogResult.Yes)
//{
// Config.PLCSetting.LocationX = x;
// Config.PLCSetting.LocationY = y;
//}
GetCurrentPosition();
}
private void btnReloadAlgorithem_Click(object sender, EventArgs e)
{
LoadHalconTool();
MessageBox.Show("算法重新载入完成");
}
private void btnClearROI_Click(object sender, EventArgs e)
{
Config.ROIList.Clear();
DoCalibration();
}
private void CalibrationProcessFrm_FormClosing(object sender, FormClosingEventArgs e)
{
chkContinueMode.Checked = false;
}
}
}

View File

@ -0,0 +1,120 @@
<?xml version="1.0" encoding="utf-8"?>
<root>
<!--
Microsoft ResX Schema
Version 2.0
The primary goals of this format is to allow a simple XML format
that is mostly human readable. The generation and parsing of the
various data types are done through the TypeConverter classes
associated with the data types.
Example:
... ado.net/XML headers & schema ...
<resheader name="resmimetype">text/microsoft-resx</resheader>
<resheader name="version">2.0</resheader>
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
<value>[base64 mime encoded serialized .NET Framework object]</value>
</data>
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
<comment>This is a comment</comment>
</data>
There are any number of "resheader" rows that contain simple
name/value pairs.
Each data row contains a name, and value. The row also contains a
type or mimetype. Type corresponds to a .NET class that support
text/value conversion through the TypeConverter architecture.
Classes that don't support this are serialized and stored with the
mimetype set.
The mimetype is used for serialized objects, and tells the
ResXResourceReader how to depersist the object. This is currently not
extensible. For a given mimetype the value must be set accordingly:
Note - application/x-microsoft.net.object.binary.base64 is the format
that the ResXResourceWriter will generate, however the reader can
read any of the formats listed below.
mimetype: application/x-microsoft.net.object.binary.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.soap.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.bytearray.base64
value : The object must be serialized into a byte array
: using a System.ComponentModel.TypeConverter
: and then encoded with base64 encoding.
-->
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
<xsd:element name="root" msdata:IsDataSet="true">
<xsd:complexType>
<xsd:choice maxOccurs="unbounded">
<xsd:element name="metadata">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" />
</xsd:sequence>
<xsd:attribute name="name" use="required" type="xsd:string" />
<xsd:attribute name="type" type="xsd:string" />
<xsd:attribute name="mimetype" type="xsd:string" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="assembly">
<xsd:complexType>
<xsd:attribute name="alias" type="xsd:string" />
<xsd:attribute name="name" type="xsd:string" />
</xsd:complexType>
</xsd:element>
<xsd:element name="data">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="resheader">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" />
</xsd:complexType>
</xsd:element>
</xsd:choice>
</xsd:complexType>
</xsd:element>
</xsd:schema>
<resheader name="resmimetype">
<value>text/microsoft-resx</value>
</resheader>
<resheader name="version">
<value>2.0</value>
</resheader>
<resheader name="reader">
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
</root>

View File

@ -0,0 +1,277 @@
using Autofac;
using BRS.Common.Model.Helper;
using BRS.Common.Interface;
using BRS.Common.Model;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.ComponentModel.Design;
using System.Drawing.Design;
using System.Linq;
using System.Net;
using System.Net.Sockets;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Forms;
using static BRS.Common.Model.Helper.EnumHelper;
namespace BRS.Common.Base
{
public abstract class AGVBase : DeviceBase, IMonitor
{
#region Property & Field
public virtual AGVInitialConfigBase IConfig
{
get
{
return InitialConfig as AGVInitialConfigBase;
}
}
string currentPosition = "";
public string CurrentPosition
{
get => currentPosition;
set
{
if (currentPosition != value)
{
currentPosition = value;
if (!string.IsNullOrWhiteSpace(currentPosition))
{
OnAGVPositoinChanged?.Invoke(DateTime.Now, currentPosition);
}
}
}
}
AGVTaskStatus taskStatus = AGVTaskStatus.None;
public AGVTaskStatus TaskStatus
{
get => taskStatus;
set
{
if (taskStatus != value)
{
taskStatus = value;
if (taskStatus != AGVTaskStatus.None)
{
//if (_isTaskRunning && _taskDoneStates.Contains(taskStatus))
//{
// _taskDoneHandle.Set();
// _isTaskRunning = false;
//}
OnAGVTaskStatusChanged?.Invoke(DateTime.Now, taskStatus);
}
}
}
}
List<AGVTaskStatus> _taskRunningStates = new List<AGVTaskStatus>() { AGVTaskStatus.Running, AGVTaskStatus.Waiting, AGVTaskStatus.Suspended };
List<AGVTaskStatus> _taskDoneStates = new List<AGVTaskStatus>() { AGVTaskStatus.Cancelled, AGVTaskStatus.Completed, AGVTaskStatus.Failed };
float batteryLvl = 0;
public float BatteryLvl
{
get => batteryLvl;
set
{
if (batteryLvl != value)
{
float pre = batteryLvl;
batteryLvl = value;
OnAGVBatteryLvlChanged?.Invoke(DateTime.Now, pre, batteryLvl);
}
}
}
public string LastStation { get; set; }
public string Destination { get; set; } = "";
public ManualResetEvent BatteryHandle { get; set; } = new ManualResetEvent(false);
#endregion
#region DeviceBase
protected override void Init()
{
BatteryHandle = new ManualResetEvent(false);
}
protected override void Stop()
{
BatteryHandle.Set();
}
#endregion
#region Event
public event Action<DateTime, string> OnAGVPositoinChanged;
public event Action<DateTime, AGVTaskStatus> OnAGVTaskStatusChanged;
public event Action<DateTime, float, float> OnAGVBatteryLvlChanged;
// 2022/08/31 未使用事件,暂时注释掉
// public event Action<DateTime, IODefinition> OnAGVIOChanged;
public Action<DateTime, string, IDevice, IMonitorSet> OnMonitorInvoke { get; set; }
public Action<DateTime, IDevice, IWarningSet> OnMonitorAlarm { get; set; }
#endregion
#region Method
public abstract void TaskOrder(string dest, bool isWaitFinished);
public abstract void CancelTask();
public abstract void PauseTask();
#endregion
#region IMonitor
public abstract void Monitor();
public abstract void ResetAlarm();
#endregion
}
#region Config
public class AGVInitialConfigBase : InitialConfigBase, IMonitorConfig, IWarningSetCollection
{
[Category("监听配置")]
[Description("监听间隔单位ms")]
public int ScanInterval { get; set; } = 500;
//[Category("监听配置")]
//[Description("监听的IO信息配置集合")]
//[TypeConverter(typeof(CollectionCountConvert))]
//[Editor(typeof(ComplexCollectionEditor<IODefinition>), typeof(UITypeEditor))]
//public List<IODefinition> IOCollection { get; set; } = new List<IODefinition>();
//[Category("监听配置")]
//[Description("是否采用简单监听模式。true简单模式只获取任务状态false全部模式获取任务所有信息")]
//public bool IsSimpleMonitor { get; set; } = true;
private float batteryLvlToCharge = 0.1f;
[Category("充电配置")]
[Description("充电电池容量,电池容量低于该值时需要充电")]
public float BatteryLvlToCharge
{
get => batteryLvlToCharge;
set
{
if (value >= 1 || value <= 0)
{
value = 0.1f;
}
batteryLvlToCharge = value;
}
}
private float batteryLvlToCharge_Recommand = 0.3f;
[Category("充电配置")]
[Description("充电电池容量,电池容量低于该值时,设备空闲时建议充电")]
public float BatteryLvlToCharge_Recommand
{
get => batteryLvlToCharge_Recommand;
set
{
if (value >= 1 || value <= 0)
{
value = 0.3f;
}
batteryLvlToCharge_Recommand = value;
}
}
private float batteryLvlChargeDone = 0.9f;
[Category("充电配置")]
[Description("充电完成电池容量,电池容量高于该值时确认充电完成")]
public float BatteryLvlChargeDone
{
get => batteryLvlChargeDone;
set
{
if (value >= 1 || value <= 0)
{
value = 0.9f;
}
batteryLvlChargeDone = value;
}
}
[Category("动作设置")]
[Description("动作超时设置单位min")]
public float OperationTimeout { get; set; } = 5;
[Category("警报配置")]
[Description("WarningSetCollection警报配置列表")]
[DisplayName("警报配置")]
[TypeConverter(typeof(CollectionCountConvert))]
[Editor(typeof(WarningSetsEditor<IOWarningSet>), typeof(UITypeEditor))]
public List<IWarningSet> WarningSetCollection { get; set; } = new List<IWarningSet>();
#region IMonitorConfig
[Category("监听设置")]
[Description("MonitorSetCollection监听操作配置集合")]
[DisplayName("监听配置")]
[TypeConverter(typeof(CollectionCountConvert))]
[Editor(typeof(ComplexCollectionEditor<IOMonitorSet>), typeof(UITypeEditor))]
public List<IMonitorSet> MonitorSetCollection { get; set; } = new List<IMonitorSet>();
[Category("监听设置")]
[Description("true启动监听 false关闭监听")]
[DisplayName("监听启用")]
public bool IsEnableMonitor { get; set; } = true;
[Category("监听设置")]
[Description("扫描间隔时间单位ms")]
[DisplayName("扫描间隔")]
public int MonitorInterval { get; set; } = 500;
[Category("监听设置")]
[Description("超时设置单位ms")]
[DisplayName("监听超时")]
public int MonitorTimeout { get; set; } = 500;
public List<IMonitorSet> GetAllMonitorSet()
{
WarningSetCollection.ForEach(m => m.SourceDevice = this.Name);
MonitorSetCollection.ForEach(m => m.SourceDeviceId = this.Id);
return MonitorSetCollection;
}
#endregion
}
public class AGVOperationConfig : OperationConfigBase
{
[Category("导航配置")]
[Description("AGV行驶目的地")]
public string Location { get; set; }
[Category("导航配置")]
[Description("是否等待完成信号")]
public bool IsWaitFinished { get; set; } = true;
}
#endregion
public enum AGVCode
{
QueryPosition = 0x03EC,
QueryTaskStatus = 0x03FC,
QueryIO = 0x03F5,
CancelTask = 0x0BBB,
PauseTask = 0x0BB9,
TaskOrder = 0x0BEB,
QueryBattery = 0x03EF,
}
public enum AGVTaskStatus
{
None = 0,
Waiting = 1,
Running = 2,
Suspended = 3,
Completed = 4,
Failed = 5,
Cancelled = 6,
}
}

View File

@ -0,0 +1,641 @@
using Autofac;
using BRS.Common.Interface;
using BRS.Common.Model;
using BRS.Common.Model.Helper;
using System;
using System.Collections;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Drawing.Design;
using System.Drawing.Imaging;
using System.IO;
using System.Linq;
using System.Runtime.InteropServices;
using System.Threading;
using System.Threading.Tasks;
using static BRS.Common.Model.Helper.EnumHelper;
namespace BRS.Common.Base
{
public abstract class CameraBase : DeviceBase
{
private const int IMAGESETLIFETIME = 10;
//耗时操作从 _taskFactory分配线程
public TaskFactory _taskFactory = new TaskFactory(TaskCreationOptions.LongRunning, TaskContinuationOptions.LongRunning);
public ImageSaveHelper ImageSaveHelper { get; set; } = new ImageSaveHelper();
#region DeviceBase
protected override void Start()
{
//if (clearImageTimer == null)
//{
// clearImageTimer = new System.Threading.Timer((o) => { ClearImage(); }, null, 0, 1000 * 60 * 120);
//}
_imageSetList = new ConcurrentDictionary<string, IImageSet>();
ImageSaveHelper.OnImageSaveExceptionRaised -= ImageSaveHelper_OnImageSaveExceptionRaised;
ImageSaveHelper.OnImageSaveExceptionRaised += ImageSaveHelper_OnImageSaveExceptionRaised;
base.Start();
}
protected override void Stop()
{
if (clearImageTimer != null)
{
clearImageTimer.Change(-1, -1);
clearImageTimer.Dispose();
clearImageTimer = null;
}
//if (clearImageSetTimer != null)
//{
// clearImageSetTimer.Change(-1, -1);
// clearImageSetTimer.Dispose();
// clearImageSetTimer = null;
//}
}
private void ImageSaveHelper_OnImageSaveExceptionRaised(DateTime dt, string msg)
{
LogAsync(new LogMsg(dt, LogLevel.Error, msg));
}
#endregion
#region
public virtual CameraInitialConfigBase IConfig => InitialConfig as CameraInitialConfigBase;
public abstract IOperationConfig GetOperationConfigFromDevice();
public abstract void UploadOperationConfig(IOperationConfig config);
#endregion
#region
public Action<CameraBase, Bitmap, string> OnShowImageUpdated;
public async void UpdateImageAsync(Bitmap image, string imgSetId)
{
await Task.Run(() =>
{
OnShowImageUpdated?.Invoke(this, image, imgSetId);
});
}
/// <summary>
///图片异步保存
/// </summary>
public virtual void ImageSaveAsync(string fullName, Bitmap map)
{
if (!IConfig.ImageSaveOption.IsEnabled)
{
map?.Dispose();
return;
}
ImageSaveSet imageSaveSet = new ImageSaveSet()
{
FullName = fullName,
SaveImage = map,
ImageFormat = IConfig.ImageSaveOption.ImageFormat
};
ImageSaveHelper.ImageSaveAsync(imageSaveSet);
}
public Action<DateTime, CameraBase, IImageSet> OnImageOutput { get; set; }
public event Action OnCameraOpModeChanged;
private EnumHelper.CameraOpMode opMode = CameraOpMode.SingleSnapShot;
/// <summary>
/// 运行模式 扫描or拍照
/// </summary>
public EnumHelper.CameraOpMode OpMode
{
get => opMode;
set
{
if (opMode != value)
{
opMode = value;
OnCameraOpModeChanged?.BeginInvoke(null, null);
CameraOpModeChanged(value);
if (opMode == CameraOpMode.ContinuousMode)
{
Task.Run(() =>
{
while (CurrentState == DeviceState.DSOpen && opMode == CameraOpMode.ContinuousMode)
{
Snapshot();
ImageShowedHandle.WaitOne();
}
});
}
}
}
}
public virtual void CameraOpModeChanged(EnumHelper.CameraOpMode OpMode)
{
}
public AutoResetEvent ImageShowedHandle = new AutoResetEvent(false);
//private Bitmap showImage;
/// <summary>
/// 输出显示的图片
/// </summary>
//public virtual Bitmap ShowImage
//{
// get
// {
// return showImage;
// }
// set
// {
// try
// {
// showImage = value;
// if (showImage != null)
// {
// OnImageUpdated?.Invoke(this, new Bitmap(showImage));
// }
// }
// catch (Exception ex)
// {
// LogAsync(DateTime.Now, $"图片显示异常信息", ex.GetExceptionMessage());
// }
// }
//}
/// <summary>
/// 一次性抓拍
/// </summary>
/// <returns></returns>
public abstract void Snapshot();
public abstract IImageSet Snapshot(IOperationConfig config);
public virtual void InitialImageSet(IImageSet set, ImageSaveOption saveOption = null)
{
if (saveOption != null)
{
set.ImageSaveOption = saveOption.Copy();
}
//set.IsOriginSaved = !set.ImageSaveOption.IsSaveOriginImage;
//set.IsFitSaved = !set.ImageSaveOption.IsSaveFitImage;
//set.IsAddtionalSaved = string.IsNullOrWhiteSpace(set.ImageSaveOption.AddtionalSaveType);
set.CameraId = this.Id;
set.ImageTime = DateTime.Now;
_imageSetList[set.Id] = set;
}
public ImageSet CopyImageSet(ImageSet srcSet)
{
ImageSet imageSet = new ImageSet
{
Id = srcSet.Id,
//TImage = srcSet.TImage.CopyImage(),
BImage = srcSet.BImage.Clone(),
ImageSaveOption = srcSet.ImageSaveOption.Copy(),
ImageTime = srcSet.ImageTime
};
return imageSet;
}
/// <summary>
/// 释放图片数据
/// </summary>
protected virtual void FreeImage()
{
//if (ShowImage != null)
//{
// ShowImage.Dispose();
//}
}
/// <summary>
/// 清理硬触发产生的图片缓存 外部业务使用
/// </summary>
public virtual void RefreshImageBufferHandle()
{
}
/// <summary>
/// 获取图片缓存 外部业务使用
/// </summary>
/// <returns></returns>
public virtual IImageSet GetImageBuffer(int timeout)
{
return null;
}
#endregion
#region
public Action<CameraBase, List<IShapeElement>, string> OnElementsUpdated;
#endregion
#region /
static object _imageSetLock = new object();
//cameraBase 内部使用
public ConcurrentDictionary<string, IImageSet> _imageSetList = new ConcurrentDictionary<string, IImageSet>();
//public void NewImageSet(IImageSet set)
//{
// set.IsOriginSaved = !set.ImageSaveOption.IsSaveOriginImage;
// set.IsFitSaved = !set.ImageSaveOption.IsSaveFitImage;
// set.IsAddtionalSaved = string.IsNullOrWhiteSpace(set.ImageSaveOption.AddtionalSaveType);
// set.OnImageSetTimeout += ImageSet_OnImageSetTimeout;
// set.ImageTime = DateTime.Now;
// set.CameraId = this.Id;
// _imageSetList[set.Id] = set;
//}
//public virtual async void UpdateFitElements(List<IShapeElement> eleList, string imgSetId)
//{
// await Task.Run(() =>
// {
// OnElementsUpdated?.BeginInvoke(this, eleList, imgSetId, null, null);
// });
//}
public virtual async void DisplayAndSaveOriginImage(string imgSetId)
{
IImageSet set = _imageSetList.Values.FirstOrDefault(u => u.Id == imgSetId);
if (set != null && set.BImage != null)
{
await Task.Run(() =>
{
var showImage = set.BImage.ConvertToBitmap();
var saveImage = showImage?.CopyBitmap();
OnShowImageUpdated?.Invoke(this, showImage, imgSetId);
if (set.ImageSaveOption != null && !string.IsNullOrEmpty(set.ImageSaveOption.ImageSaveDirectory))
{
string fullname = Path.Combine(set.ImageSaveOption.ImageSaveDirectory, DateTime.Now.ToString("yyyyMMdd"), $"Origin_{Name}", $"{Name}_{set.Id}.{set.ImageSaveOption.ImageFormat.ToString().ToLower()}");
ImageSaveAsync(fullname, saveImage);
}
//注释注释
//释放 himage
// ClearImageSet(set);
});
}
}
protected string CheckImageDirectory(string dirPath, string prefix)
{
if (string.IsNullOrWhiteSpace(dirPath))
{
dirPath = Path.Combine("D:/Images", DateTime.Now.ToString("yyyyMMdd"), prefix);
}
else
{
//subDir = Path.Combine(DateTime.Now.ToString("yyyyMMdd"), subDir);
dirPath = Path.Combine(dirPath, prefix);
}
//string imgDir = Path.Combine(IConfig.ImgDirectory, subDir, prefix);
string imgDir = Path.Combine(dirPath, DateTime.Now.ToString("yyyyMMdd"));
DirectoryInfo dir = new DirectoryInfo(imgDir);
if (!dir.Exists)
{
dir.Create();
}
return imgDir;
}
//private Timer clearImageSetTimer = null;
/// <summary>
/// 内部图片缓存清理 (集合中 非托管对象的释放,需要元素出列后 再释放)
/// </summary>
/// <param name="set"></param>
public void ClearImageSet(IImageSet set)
{
try
{
bool flag = false;
lock (_imageSetLock)
{
flag = _imageSetList.TryRemove(set.Id, out set);
if (flag)
{
set.Dispose();
}
//LogAsync(DateTime.Now, $"{Name}移除图片信息{(flag ? "成功" : "失败")},当前缓存数量:{_imageSetList.Count}", "");
}
}
catch (Exception ex)
{
LogAsync(DateTime.Now, LogLevel.Exception, $"清理图片缓存异常,当前缓存数量{_imageSetList.Count},{ex.GetExceptionMessage()}");
}
}
public void ClearImageSet(string imgSetId)
{
//IImageSet set = _imageSetList.Values.First(u => u.Id == imgSetId);
//if (set != null)
//ClearImageSet(set);
}
private void ImageSet_OnImageSetTimeout(IImageSet set)
{
//ClearImageSet(set);
}
//private void ClearImageSetPeriodically()
//{
// try
// {
// DateTime dt = DateTime.Now;
// foreach (ImageSet set in _imageSetList)
// {
// if ((dt - set.InitialTime).TotalSeconds > IMAGESETLIFETIME)
// {
// ImageSet temp = set;
// _imageSetList.TryTake(out temp);
// temp.Dispose();
// }
// }
// }
// catch (Exception ex)
// {
// LogAsync(DateTime.Now, $"定时清理图片缓存异常,当前缓存数量{_imageSetList.Count}", ex.GetExceptionMessage());
// }
//}
#endregion
#region
static readonly object _clearImageLock = new object();
protected void ClearImage()
{
if (IConfig.SaveImageDayLimit > 0)
{
lock (_clearImageLock)
{
LogAsync(DateTime.Now, LogLevel.Information, $"ClearImage Start");
try
{
DirectoryInfo dirImage = new DirectoryInfo(IConfig.ImgDirectory);
if (dirImage.Exists)
{
DateTime dtNow = DateTime.Now;
var folderList = dirImage.GetDirectories().ToList();
folderList = folderList.Where(f =>
{
if (f.Name.Length < 8)
return false;
DateTime dt = DateTime.Now;
string name = f.Name.Substring(0, 4) + "/" + f.Name.Substring(4, 2) + "/" + f.Name.Substring(6);
return DateTime.TryParse(name, out dt);
}).OrderBy(u => u.Name).ToList();
if (folderList.Count > IConfig.SaveImageDayLimit)
{
folderList.Take(folderList.Count - IConfig.SaveImageDayLimit).ToList().ForEach(f =>
{
f.Delete(true);
});
}
}
}
catch (Exception ex)
{
LogAsync(DateTime.Now, LogLevel.Exception, $"ClearImage异常{ex.GetExceptionMessage()}");
}
LogAsync(DateTime.Now, LogLevel.Information, $"ClearImage Done");
}
}
}
private System.Threading.Timer clearImageTimer = null;
#endregion
#region
[DllImport("kernel32.dll", EntryPoint = "CopyMemory", SetLastError = false)]
public static extern void CopyMemory(IntPtr dest, IntPtr src, long count);
#endregion
}
#region Config
[Device("Camera", "相机取像配置", EnumHelper.DeviceAttributeType.OperationConfig)]
public class CameraOprerationConfigBase : OperationConfigBase, INotifyPropertyChanged, IComplexDisplay, IHalconToolPath
{
private float exposure = 0;
/// <summary>
/// 曝光
/// </summary>
[Category("取像配置")]
[Description("曝光")]
[DisplayName("曝光")]
public virtual float Exposure
{
get => exposure;
set
{
if (exposure != value)
{
exposure = value;
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs("Exposure"));
}
}
}
/// <summary>
/// 增益
/// </summary>
[Category("取像配置")]
[Description("增益")]
[DisplayName("增益")]
public virtual float Gain { get; set; }
[Category("取像配置")]
[Description("曝光修改后等待时间单位ms。针对部分场景确保曝光修改及时生效。")]
[DisplayName("曝光等待")]
public virtual int ExposureWaitTime { get; set; }
[Category("取像配置")]
[Description("拍摄后曝光值。可在一次拍摄后将曝光修改为下次拍摄的曝光值,节约曝光生效时间。")]
[DisplayName("拍摄后曝光")]
public virtual float ExposureAfterSnap { get; set; }
[Category("算法配置")]
[Description("算法路径")]
[DisplayName("算法路径")]
[Editor(typeof(FileDialogEditor), typeof(UITypeEditor))]
public string AlgorithemPath { get; set; } = "";
[Category("保存设置")]
[Description("图片保存配置")]
[DisplayName("图片保存配置")]
[TypeConverter(typeof(ComplexObjectConvert))]
[Editor(typeof(PropertyObjectEditor), typeof(UITypeEditor))]
public ImageSaveOption ImageSaveOption { get; set; } = new ImageSaveOption();
[Category("延时配置")]
[Description("拍照前延时")]
[DisplayName("前延时")]
public int DelayBefore { get; set; } = 0;
[Category("延时配置")]
[Description("拍照后延时")]
[DisplayName("后延时")]
public int DelayAfter { get; set; } = 0;
public event PropertyChangedEventHandler PropertyChanged;
public string GetDisplayText()
{
return $"曝光:{Exposure.ToString("f2")} 算法:{AlgorithemPath}";
}
public List<string> GetHalconToolPathList()
{
return new List<string>() { AlgorithemPath };
}
}
/// <summary>
/// 相机初始化配置
/// </summary>
public class CameraInitialConfigBase : InitialConfigBase
{
[Category("驱动类型")]
[Description("驱动类型")]
[DisplayName("驱动类型")]
[Browsable(true)]
[TypeConverter(typeof(CameraTypeConverter))]
public override string DriverType { get; set; }
[Category("保存设置")]
[Description("图片保存目录")]
[DisplayName("图片保存目录")]
[Editor(typeof(FoldDialogEditor), typeof(UITypeEditor))]
public virtual string ImgDirectory { get; set; } = @"../Images";
[Category("保存设置")]
[Description("图片保存天数")]
[DisplayName("图片保存天数")]
public virtual int SaveImageDayLimit { get; set; } = 10;
[Category("保存设置")]
[Description("图片保存默认配置,主要用于硬触发等没有明确操作配置说明的图片保存")]
[DisplayName("图片保存默认配置")]
[TypeConverter(typeof(ComplexObjectConvert))]
[Editor(typeof(PropertyObjectEditor), typeof(UITypeEditor))]
public virtual ImageSaveOption ImageSaveOption { get; set; } = new ImageSaveOption();
}
/// <summary>
/// 在线相机初始化配置基类
/// </summary>
public class OnlineCameraInitialConfigBase : CameraInitialConfigBase
{
[Category("相机设置")]
[Description("相机序列号")]
[DisplayName("序列号")]
public virtual string SerialNum { get; set; }
[Category("相机设置")]
[Description("相机IP地址")]
[DisplayName("相机IP地址")]
public virtual string CameraIP { get; set; }
[Category("相机设置")]
[Description("上位机IP地址")]
[DisplayName("上位机IP地址")]
public virtual string ComputerIP { get; set; }
[Category("拍摄设置")]
[Description("默认曝光值,相机开启后就设置该曝光值")]
[DisplayName("默认曝光值")]
public virtual float DefaultExposure { get; set; }
}
/// <summary>
/// 离线相机初始化配置
/// </summary>
public class OfflineCameraInitialConfigBase : CameraInitialConfigBase
{
}
#endregion
#region Converter & Editor
public class CameraTypeConverter : DeviceTypeConverter<CameraBase>
{
}
public class CameraInitialConfigEditor : DeviceInitialConfigEditor<CameraInitialConfigBase>
{
}
public class CameraDeviceConverter : ComboBoxItemTypeConvert
{
public override Hashtable GetConvertHash(ITypeDescriptorContext context)
{
Hashtable table = new Hashtable();
using (var scope = GlobalVar.Container.BeginLifetimeScope())
{
var config = scope.Resolve<IProcessConfig>();
config.CameraConfigCollection.ForEach(camera =>
{
table[camera.Id] = camera.Name;
});
}
return table;
}
}
#endregion
#region
#endregion
}

View File

@ -0,0 +1,18 @@
using BRS.Common.Model;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace BRS.Common.Base
{
public abstract class ForceSensorBase : DeviceBase
{
public abstract ResponseMessage ReadOnce();
public abstract ResponseMessage StartReading(bool isStart);
public abstract ResponseMessage ZeroSet();
}
}

View File

@ -0,0 +1,244 @@
using BRS.Common.Model.Helper;
using BRS.Common.Interface;
using BRS.Common.Model;
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing.Design;
using System.IO.Ports;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using static BRS.Common.Model.Helper.EnumHelper;
namespace BRS.Common.Base
{
public abstract class IODeviceBase : DeviceBase, IMonitor
{
#region Property & Field
public virtual IOInitialConfigBase IConfig
{
get
{
return InitialConfig as IOInitialConfigBase;
}
}
/// <summary>
/// IO的监听值
/// </summary>
public List<IOItem> CurrentIOs { get; set; } = new List<IOItem>();
#endregion
#region DeviceBase
protected override void Init()
{
}
protected override void Pause()
{
}
protected override void Resume()
{
}
protected override void Start()
{
Task.Run(() =>
{
Monitor();
});
}
protected override void Stop()
{
}
#endregion
#region Event
public Action<DateTime, string, IDevice, IMonitorSet> OnMonitorInvoke { get; set; }
public Action<DateTime, IDevice, IWarningSet> OnMonitorAlarm { get; set; }
public virtual void ExcuteMonitorInvoke(DateTime dateTime, string invokeDevice, IDevice device, IMonitorSet monitorSet)
{
OnMonitorInvoke?.BeginInvoke(dateTime, invokeDevice, device, monitorSet, OnMethodInvoked, null);
}
public abstract void OnMethodInvoked(IAsyncResult ar);
public virtual void ExcuteMonitorAlarm(DateTime dateTime, IDevice device, IWarningSet warningSet)
{
OnMonitorAlarm?.BeginInvoke(dateTime, device, warningSet, null, null);
}
#endregion
#region Method
public abstract ResponseMessage WriteOutput(int index, bool isOpen, bool isShortSingal = false, int elaspedTime = 0);
public abstract ResponseMessage ReadInput(int index, int length);
#endregion
#region IMonitor
public abstract void Monitor();
public virtual void ResetAlarm()
{
(InitialConfig as MotionCardInitialConfigBase).WarningSetCollection.ForEach(ws => ws.CurrentStatus = false);
LogAsync(DateTime.Now, LogLevel.Information, $"{Name}重置报警");
}
#endregion
}
[Device("IOOperation", "IO操作配置", EnumHelper.DeviceAttributeType.OperationConfig)]
public class IOOperationConfigBase : OperationConfigBase, IComplexDisplay
{
[Category("\t\t\tIO操作配置")]
[DisplayName("1.IO预检查")]
[Description("IO预检查定义集合")]
[TypeConverter(typeof(CollectionCountConvert))]
[Editor(typeof(IOOperationItemCollectionEditor), typeof(UITypeEditor))]
public List<IOOperationItem> PreCheckIOCollection { get; set; } = new List<IOOperationItem>();
[Category("\t\t\tIO操作配置")]
[Description("超时设置单位ms")]
[DisplayName("2.IO预检查超时")]
public int PreCheckIOTimeout { get; set; } = 0;
[Category("\t\t\tIO操作配置")]
[DisplayName("3.IO输出")]
[Description("IO输出定义集合")]
[TypeConverter(typeof(CollectionCountConvert))]
[Editor(typeof(IOOperationItemCollectionEditor), typeof(UITypeEditor))]
public List<IOOperationItem> IOOutputCollection { get; set; } = new List<IOOperationItem>();
[Category("\t\t\tIO操作配置")]
[DisplayName("4.IO输出确认")]
[Description("IO确认定义集合")]
[TypeConverter(typeof(CollectionCountConvert))]
[Editor(typeof(IOOperationItemCollectionEditor), typeof(UITypeEditor))]
public List<IOOperationItem> IOConfirmCollection { get; set; } = new List<IOOperationItem>();
[Category("\t\t\tIO操作配置")]
[Description("超时设置单位ms")]
[DisplayName("5.IO输出确认超时")]
public int IOConfirmTimeout { get; set; } = 0;
[Category("\t\t\tIO操作配置")]
[Description("IO操作前延时单位ms")]
public virtual int DelayBefore { get; set; } = 0;
[Category("\t\t\tIO操作配置")]
[Description("IO操作后延时单位ms")]
public virtual int DelayAfter { get; set; } = 0;
public virtual string GetDisplayText()
{
string preCheck = "";
PreCheckIOCollection.ForEach(i =>
{
preCheck += i.GetDisplayText() + " ";
});
if (preCheck != "")
{
preCheck = " 预检:" + preCheck;
}
string output = "";
IOOutputCollection.ForEach(i =>
{
output += i.GetDisplayText() + " ";
});
if (output != "")
{
output = " 输出:" + output;
}
string confirm = "";
IOConfirmCollection.ForEach(i =>
{
confirm += i.GetDisplayText() + " ";
});
if (confirm != "")
{
confirm = " 确认:" + confirm;
}
return (preCheck + output + confirm).Trim();
}
}
public class IOInitialConfigBase : InitialConfigBase, IMonitorConfig, IIOModuleConfig, IWarningSetCollection
{
[Category("IO设置")]
[DisplayName("输出信号时默认持续时间")]
[Description("输出信号时默认持续时间,以毫秒为单位")]
public int SignalElasped { get; set; } = 100;
[Category("监听设置")]
[Description("true监听输出信号 false不监听输出信号")]
[DisplayName("是否监听输出")]
public bool IsMonitorOutput { get; set; } = false;
[Category("IO配置")]
[DisplayName("输入IO总数")]
[Description("输入IO总数")]
public int InputNums { get; set; } = 16;
[Category("IO配置")]
[DisplayName("输出IO总数")]
[Description("输出IO总数")]
public int OutputNums { get; set; } = 16;
[Category("IO配置")]
[DisplayName("是否输出取反")]
[Description("true输出取反 false输出不取反")]
public bool IsOutputReversed { get; set; } = true;
[Category("IO配置")]
[DisplayName("IO定义集合")]
[Description("IO定义集合")]
[TypeConverter(typeof(CollectionCountConvert))]
[Editor(typeof(ComplexCollectionEditor<IODefinition>), typeof(UITypeEditor))]
public List<IODefinition> IODefinitionCollection { get; set; } = new List<IODefinition>();
[Category("警报配置")]
[Description("WarningSetCollection警报配置列表")]
[DisplayName("警报配置")]
[TypeConverter(typeof(CollectionCountConvert))]
[Editor(typeof(WarningSetsEditor<IOWarningSet>), typeof(UITypeEditor))]
public List<IWarningSet> WarningSetCollection { get; set; } = new List<IWarningSet>();
#region IMonitorConfig
[Category("监听设置")]
[Description("MonitorSetCollection监听操作配置集合")]
[DisplayName("监听配置")]
[TypeConverter(typeof(CollectionCountConvert))]
[Editor(typeof(ComplexCollectionEditor<IOMonitorSet>), typeof(UITypeEditor))]
public List<IMonitorSet> MonitorSetCollection { get; set; } = new List<IMonitorSet>();
[Category("监听设置")]
[Description("true启动监听 false关闭监听")]
[DisplayName("监听启用")]
public bool IsEnableMonitor { get; set; } = true;
[Category("监听设置")]
[Description("扫描间隔时间单位ms")]
[DisplayName("扫描间隔")]
public int MonitorInterval { get; set; } = 10;
[Category("监听设置")]
[Description("超时设置单位ms")]
[DisplayName("监听超时")]
public int MonitorTimeout { get; set; } = 500;
public List<IMonitorSet> GetAllMonitorSet()
{
WarningSetCollection.ForEach(m => m.SourceDevice = this.Name);
MonitorSetCollection.ForEach(m => m.SourceDeviceId = this.Id);
return MonitorSetCollection;
}
#endregion
}
}

View File

@ -0,0 +1,31 @@
using Autofac;
using BRS.Common.Model.Helper;
using BRS.Common.Interface;
using BRS.Common.Model;
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.ComponentModel.Design;
using System.Drawing.Design;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Forms;
using static BRS.Common.Model.Helper.EnumHelper;
namespace BRS.Common.Base
{
public abstract class MessageQueueBase : DeviceBase
{
public event Action<DateTime, IRemoteMessage> OnRemoteMessageReceived;
public abstract ResponseMessage SendMsg<T>(T t, bool isSendChannel = true) where T : IRemoteMessage;
public virtual void RemoteMessageReceived(DateTime dt,IRemoteMessage msg)
{
OnRemoteMessageReceived?.Invoke(dt, msg);
}
}
}

View File

@ -0,0 +1,232 @@
using BRS.Common.Device.Helper;
using BRS.Common.Factory;
using BRS.Common.Model.Helper;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.IO.Ports;
using System.Linq;
using System.Text;
using System.Threading;
namespace BRS.Common.Base
{
public class ModbusASCIICommBase : DeviceBase
{
public SerialPort sp = null;
public ModbusASCIIInitialConfigBase IConfig
{
get => InitialConfig as ModbusASCIIInitialConfigBase;
}
protected override void Init()
{
if (sp == null)
{
sp = new SerialPort(IConfig.Port);
sp.BaudRate = int.Parse(IConfig.BaudRate);
sp.Parity = IConfig.Parity;
sp.DataBits = IConfig.DataBits;
sp.StopBits = IConfig.StopBits;
}
}
protected override void Pause()
{
}
protected override void Resume()
{
}
protected override void Start()
{
if (!SerialPortHelper.StartPort(ref sp, out string errorMsg))
{
throw new ProcessException($"{Name}{sp.PortName}开启失败,{errorMsg}");
}
}
protected override void Stop()
{
if (!SerialPortHelper.ClosePort(sp.PortName, out string errorMsg))
{
throw new ProcessException($"{Name}{sp.PortName}关闭失败,{errorMsg}");
}
}
/// <summary>
/// 写寄存器
/// </summary>
/// <param name="SlaveAddress"></param>
/// <param name="adr"></param>
/// <param name="data"></param>
/// <returns></returns>
public byte[] WriteSingle(string SlaveAddress, string adr, string data, int start = 1, int len = 0)
{
byte[] src = new byte[16];
//起始值
src[0] = 0x3A;
//从站地址
var nodeBytes = Encoding.ASCII.GetBytes(SlaveAddress);
//src[1] = nodeBytes[0];
//src[2] = nodeBytes[1];
Array.Copy(nodeBytes, 0, src, 1, 2);
//功能码
src[3] = Encoding.ASCII.GetBytes("0")[0];
src[4] = Encoding.ASCII.GetBytes("6")[0];
//起始地址
var addBytes = Encoding.ASCII.GetBytes(adr);
Array.Copy(addBytes, 0, src, 5, 4);
//src[5] = addBytes[0];
//src[6] = addBytes[1];
//src[7] = addBytes[2];
//src[8] = addBytes[3];
//数据
data = data.PadLeft(4, '0');
var dataBytes = Encoding.ASCII.GetBytes(data);
Array.Copy(dataBytes, 0, src, 9, 4);
//src[9] = dataBytes[0];
//src[10] = dataBytes[1];
//src[11] = dataBytes[2];
//src[12] = dataBytes[3];
var byt1 = GetLrc(src, start, len).ToString("X2");
byte[] byt = Encoding.ASCII.GetBytes(byt1);
src[13] = byt[0];
src[14] = byt[1];
src[15] = 0x0D;
src[16] = 0x0A;
return src;
}
/// <summary>
/// 写线圈
/// </summary>
/// <param name="SlaveAddress"></param>
/// <param name="data"></param>
/// <returns></returns>
public byte[] WriteCoil(string SlaveAddress, string data, int start = 1, int len = 0)
{
byte[] src = new byte[17];
//起始值
src[0] = 0x3A;
SlaveAddress = SlaveAddress.PadLeft(2, '0');
var slave = Encoding.ASCII.GetBytes(SlaveAddress);
//从站地址
Array.Copy(slave, 0, src, 1, 2);
string temp = "050000";
var tempArr = Encoding.ASCII.GetBytes(temp);
Array.Copy(tempArr, 0, src, 3, 6);
////功能码
//src[3] = Encoding.ASCII.GetBytes("0")[0];
//src[4] = Encoding.ASCII.GetBytes("5")[0];
////起始地址
//src[5] = Encoding.ASCII.GetBytes("0")[0];
//src[6] = Encoding.ASCII.GetBytes("0")[0];
//src[7] = Encoding.ASCII.GetBytes("0")[0];
//src[8] = Encoding.ASCII.GetBytes("0")[0];
//数据
data = data.PadLeft(4, '0');
var dataArr = Encoding.ASCII.GetBytes(data);
Array.Copy(dataArr, 0, src, 9, 4);
//src[9] = Encoding.ASCII.GetBytes(data)[0];
//src[10] = Encoding.ASCII.GetBytes(data)[1];
//src[11] = Encoding.ASCII.GetBytes(data)[2];
//src[12] = Encoding.ASCII.GetBytes(data)[3];
var byt1 = GetLrc(src, start, len).ToString("X2");
byte[] byt = Encoding.ASCII.GetBytes(byt1);
src[13] = byt[0];
src[14] = byt[1];
src[15] = 0x0D;
src[16] = 0x0A;
return src;
}
public byte GetLrc(byte[] buffer, int start = 1, int len = 0)
{
if (buffer == null || buffer.Length == 0) return 0;
if (start < 0) return 0;
if (len == 0) len = buffer.Length - 2 - 2;
int lenght = start + len;
if (lenght > buffer.Length) return 0;
byte lrc = 0;
for (int i = start; i < len; i = i + 2)
{
var temp = Convert.ToInt32("0x" + System.Text.Encoding.ASCII.GetString(new byte[] { buffer[i], buffer[i + 1] }), 16);
lrc += (byte)temp;
}
lrc = (byte)((lrc ^ 0xFF) + 1);
return (byte)lrc;
}
}
public class ModbusASCIIInitialConfigBase : InitialConfigBase
{
[Category("通信设置")]
[DisplayName("串口号")]
[Description("串口号默认为COM1")]
[TypeConverter(typeof(SerialPortConverter))]
public string Port { get; set; } = "COM1";
[Category("通信设置")]
[Description("波特率")]
[TypeConverter(typeof(BaudRateConverter))]
public string BaudRate { get; set; } = "9600";
[Category("通信设置")]
[Description("奇偶校验位")]
public Parity Parity { get; set; } = Parity.None;
[Category("通信设置")]
[Description("数据位")]
public int DataBits { get; set; } = 8;
[Category("通信设置")]
[Description("停止位")]
public StopBits StopBits { get; set; } = StopBits.None;
[Category("通信设置")]
[Description("读写超时单位为ms")]
public int Timeout { get; set; } = 0;
[Category("通信设置")]
[Description("读取时等待时间单位为ms")]
public int ReadWaitTime { get; set; } = 10;
}
[Device("ModbusASCIIOperationConfigBase", "ModbusASCII操作配置基类", EnumHelper.DeviceAttributeType.OperationConfig)]
public class ModbusASCIIOperationConfigBase : OperationConfigBase
{
}
//public class ModbusTypeConverter : StringConverter
//{
// public override bool GetStandardValuesExclusive(ITypeDescriptorContext context)
// {
// return true;
// }
// public override bool GetStandardValuesSupported(ITypeDescriptorContext context)
// {
// return true;
// }
// public override StandardValuesCollection GetStandardValues(ITypeDescriptorContext context)
// {
// List<string> devices = DeviceFactory.GetAllSupportDeviceTypeNames(typeof(ModbusASCIICommBase));
// devices.Insert(0, "");
// return new StandardValuesCollection(devices);
// }
//}
}

View File

@ -0,0 +1,619 @@
using Autofac;
using BRS.Common.Model.Helper;
using BRS.Common.Interface;
using BRS.Common.Model;
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.ComponentModel.Design;
using System.Drawing.Design;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Forms;
using static BRS.Common.Model.Helper.EnumHelper;
using System.Collections;
namespace BRS.Common.Base
{
public abstract class MotionCardBase : DeviceBase, IMonitor, IMotionCard
{
//耗时操作从 _taskFactory分配线程
public TaskFactory _taskFactory = new TaskFactory(TaskCreationOptions.LongRunning, TaskContinuationOptions.LongRunning);
public Action<DateTime, string, IDevice, IMonitorSet> OnMonitorInvoke { get; set; }
public Action<DateTime, IDevice, IWarningSet> OnMonitorAlarm { get; set; }
//public event Action<int, string> OnAxisAlarmRaised;
public Action<int, int, int> OnAxisStatusChanged;
public Action<int, int> OnAxisPositionChanged;
/// <summary>
/// int,int 轴号 捕获位置
/// </summary>
public event Action<int, int> OnCapturePositionChanged;
public void CapturePositionChanged(int axisIndex, int capturePosition)
{
OnCapturePositionChanged?.Invoke(axisIndex, capturePosition);
}
/// <summary>
/// 报警产生 与 取消
/// </summary>
/// <param name="axisIndex"></param>
/// <param name="msg"></param>
/// <param name="isAlarm"></param>
public void AxisAlarmRaised(int axisIndex, string msg, bool isAlarm)
{
_axisAlarmRaisedFlag[axisIndex] = isAlarm;
IWarningSet ws = new SimpleWarningSet();
ws.WarningCode = msg;
ws.WarningDescription = msg;
ws.TriggerTime = DateTime.Now;
ws.SourceDevice = this.Name;
ws.CurrentStatus = isAlarm;
SaveAlarmCSVAsync(ws.TriggerTime, this.Name, ws);
OnMonitorAlarm?.BeginInvoke(ws.TriggerTime, this, ws, null, null);
}
public void AxisStatusChanged(int axisIndex, int preStatus, int curStatus)
{
OnAxisStatusChanged?.BeginInvoke(axisIndex, preStatus, curStatus, null, null);
}
public void AxisPositionChangedAsync(int axisIndex, int currentPosition)
{
//OnAxisPositionChanged?.BeginInvoke(axisIndex, currentPosition, null, null);
OnAxisPositionChanged?.Invoke(axisIndex, currentPosition);
}
protected virtual void OnAxisLimitAlarm(object state)
{
int axisIndex = Convert.ToInt32(state);
if (!_axisAlarmRaisedFlag[axisIndex])
{
var curStatus = GetAxisStatus(axisIndex);
var msg = "卡/核:" + IConfig.CardOrCoreNum;
if (((curStatus >> 5) & 1) == 1)
{
msg += $"轴{axisIndex}在 正极限";
}
if (((curStatus >> 6) & 1) == 1)
{
msg += $"轴{axisIndex}在 负极限";
}
AxisAlarmRaised(axisIndex, msg, true);
}
}
protected override void Start()
{
var enabledList = IConfig.AxisSettings.Where(a => a.IsAxisEnabled).ToList();
AxisStatusList = enabledList.ConvertAll(a =>
{
AxisMovingStatus axisSts = new AxisMovingStatus();
axisSts.AxisIndex = a.AxisIndex;
axisSts.AxisName = a.AxisName;
axisSts.IsMonitorStatus = a.IsMonitorStatus;
axisSts.IsMonitorPosition = a.IsMonitorPosition;
return axisSts;
});
_axisAlarmRaisedFlag = enabledList.ToDictionary(a => a.AxisIndex, a => false);
_axisLimitTimer = enabledList.ToDictionary(a => a.AxisIndex, a => new System.Threading.Timer(OnAxisLimitAlarm, a.AxisIndex, -1, -1));
Task.Run(() =>
{
Monitor();
});
base.Start();
}
/// <summary>
/// 获取规划位置
/// </summary>
/// <param name="axisNum">Axis number</param>
/// <returns></returns>
public abstract double GetPrfPosition(int axisNum);
/// <summary>
/// 获取目前当前位置
/// </summary>
/// <param name="axisNum">Axis number</param>
/// <returns></returns>
public abstract double GetCurPosition(int axisNum);
public abstract List<AxisInfo> GetCurrentAxisInfo(params string[] axisName);
public abstract void Monitor();
public abstract ResponseMessage MoveToPoint(IOperationConfig opConfig);
public virtual void ResetAlarm()
{
(InitialConfig as MotionCardInitialConfigBase).WarningSetCollection.ForEach(ws => ws.CurrentStatus = false);
LogAsync(DateTime.Now, LogLevel.Information, $"{Name}重置报警");
}
public abstract ResponseMessage Run(IOperationConfig config);
public override ResponseMessage RunWrap(IOperationConfig opConfig)
{
return Run(opConfig);
}
/// <summary>
/// 清除状态
/// </summary>
/// <param name="startAxisIndex">起始轴号</param>
/// <param name="count">数量</param>
/// <returns></returns>
public abstract bool ClearStatus(int startAxisIndex, int count);
/// <summary>
/// 读取轴状态
/// </summary>
/// <param name="axisNum">轴号</param>
/// <returns></returns>
public abstract int GetAxisStatus(int axisNum);
/// <summary>
/// 位置清零
/// </summary>
/// <param name="startAxisIndex">起始轴号</param>
/// <param name="count">数量</param>
/// <returns></returns>
public abstract bool PositionReset(int startAxisIndex, int count);
public abstract bool AllAxisOn();
public abstract bool AllAxisOff();
public abstract Task<bool> AxisOnAsync(int axisNum);
public abstract Task<bool> AxisOffAsync(int axisNum);
/// <summary>
/// 单个轴 运动(点到点 jog 回零...
/// </summary>
/// <param name="optionPara">运动参数对象</param>
public abstract Task<bool> SingleAxisMoving(MovingOption optionPara);
public abstract bool SmartGoHome(short AxisIndex, GoHomePara goHomePara);
public abstract bool SmartGetHomeStatus(short AxisIndex, GoHomeStatus homeStatus);
/// <summary>
/// 某个轴运动停止
/// </summary>
/// <param name="axisNum">轴号</param>
/// <param name="option">0表示平滑停止1表示紧急停止</param>
/// <returns></returns>
public abstract Task<bool> MoveStop(int axisNum, int option);
public virtual async void ExcuteMonitorInvoke(DateTime dateTime, string invokeDevice, IDevice device, IMonitorSet monitorSet)
{
await Task.Run(() =>
{
//Thread.CurrentThread.Priority = ThreadPriority.Highest;
OnMonitorInvoke?.Invoke(dateTime, invokeDevice, device, monitorSet);
//OnMonitorInvoke?.BeginInvoke(dateTime, invokeDevice, device, monitorSet, OnMethodInvoked, null);
});
}
public abstract void OnMethodInvoked(IAsyncResult ar);
public virtual void ExcuteMonitorAlarm(DateTime dateTime, IDevice device, IWarningSet warningSet)
{
OnMonitorAlarm?.BeginInvoke(dateTime, device, warningSet, null, null);
}
public virtual MotionCardInitialConfigBase IConfig
{
get
{
return InitialConfig as MotionCardInitialConfigBase;
}
}
/// <summary>
/// IO的监听值
/// </summary>
public List<IOItem> CurrentIOs { get; set; } = new List<IOItem>();
/// <summary>
/// 轴的运动状态值
/// </summary>
public List<AxisMovingStatus> AxisStatusList { get; set; } = new List<AxisMovingStatus>();
protected Dictionary<int, bool> _axisAlarmRaisedFlag = new Dictionary<int, bool>();
protected Dictionary<int, System.Threading.Timer> _axisLimitTimer = new Dictionary<int, System.Threading.Timer>();
//public Dictionary<int, AxisMovingStatus> AxisStatusList { get; set; } = new Dictionary<int, AxisMovingStatus>();
public abstract void WriteOutput(short index, IOValue value);
/// <summary>
/// 从控制卡读输入信号
/// </summary>
/// <param name="index"></param>
/// <param name="value"></param>
public abstract bool GetDi(short index);
#region ImmediatePause
/// <summary>
/// 启动立即暂停
/// </summary>
public abstract void SetImmediatePause();
/// <summary>
/// 恢复立即暂停
/// </summary>
public abstract void ResetImmediatePause(bool isResumeMoving);
#endregion
}
public class MotionCardInitialConfigBase : InitialConfigBase, IMonitorConfig, IIOModuleConfig, IWarningSetCollection
{
[Category("板卡配置")]
[DisplayName("卡号或核心号")]
[Description("卡号、核心号")]
public virtual int CardOrCoreNum { get; set; } = 0;
[Category("板卡配置")]
[DisplayName("初始配置文件路径")]
[Description("InitialConfigFilePath初始配置文件路径")]
[Editor(typeof(FileDialogEditor), typeof(UITypeEditor))]
public string InitialConfigFilePath { get; set; }
[Category("扩展模块设置")]
[Description("扩展模块数量ioModel 编号从 0开始")]
[DisplayName("扩展模块数量")]
public int IOExtNum { get; set; } = -1;
[Category("扩展模块设置")]
[Description("扩展模块配置文件路径")]
[Editor(typeof(FileDialogEditor), typeof(UITypeEditor))]
public string IOExtConfigFile { get; set; }
[Category("轴配置")]
[DisplayName("轴数量")]
[Description("AxisNum轴数量")]
public int AxisNum { get; set; } = 4;
[Category("轴配置")]
[DisplayName("轴配置信息集合")]
[Description("AxisSettings轴配置信息集合")]
[TypeConverter(typeof(CollectionCountConvert))]
[Editor(typeof(ComplexCollectionEditor<AxisSetting>), typeof(UITypeEditor))]
public List<AxisSetting> AxisSettings { get; set; } = new List<AxisSetting>();
[Category("轴配置")]
[DisplayName("轴速度比率")]
[Description("AxisVelocityRatio轴速度比率")]
public double AxisVelocityRatio { get; set; } = 1;
[Category("警报配置")]
[Description("WarningSetCollection警报配置列表")]
[DisplayName("警报配置")]
[TypeConverter(typeof(CollectionCountConvert))]
[Editor(typeof(WarningSetsEditor<IOWarningSet>), typeof(UITypeEditor))]
public List<IWarningSet> WarningSetCollection { get; set; } = new List<IWarningSet>();
[Category("IO配置")]
[Description("输入IO总数")]
[DisplayName("输入IO总数")]
public int InputNums { get; set; } = 16;
[Category("IO配置")]
[Description("输出IO总数")]
[DisplayName("输出IO总数")]
public int OutputNums { get; set; } = 16;
[Category("IO配置")]
[Description("IO定义集合")]
[TypeConverter(typeof(CollectionCountConvert))]
[Editor(typeof(ComplexCollectionEditor<IODefinition>), typeof(UITypeEditor))]
public List<IODefinition> IODefinitionCollection { get; set; } = new List<IODefinition>();
[Category("IO配置")]
[DisplayName("是否信号模式")]
[Description("true信号模式,绿色表示有信号,灰色表示无信号 false电平模式绿色高电平灰色低电平一般情况下低电平表示有信号板卡默认是电平模式")]
public bool IsSignalMode { get; set; } = false;
#region IMonitorConfig
[Category("监听设置")]
[Description("MonitorSetCollection监听操作配置集合")]
[DisplayName("监听配置")]
[TypeConverter(typeof(CollectionCountConvert))]
[Editor(typeof(ComplexCollectionEditor<IOMonitorSet>), typeof(UITypeEditor))]
public List<IMonitorSet> MonitorSetCollection { get; set; } = new List<IMonitorSet>();
[Category("监听设置")]
[Description("true启动监听 false关闭监听")]
[DisplayName("监听启用")]
public bool IsEnableMonitor { get; set; } = true;
[Category("监听设置")]
[Description("扫描间隔时间单位ms")]
[DisplayName("扫描间隔")]
public int MonitorInterval { get; set; } = 20;
[Category("监听设置")]
[Description("超时设置单位ms")]
[DisplayName("监听超时")]
public int MonitorTimeout { get; set; } = 500;
public List<IMonitorSet> GetAllMonitorSet()
{
WarningSetCollection.ForEach(m => m.SourceDevice = this.Name);
MonitorSetCollection.ForEach(m => m.SourceDeviceId = this.Id);
return MonitorSetCollection;
}
#endregion
}
[Device("MotionCardBase", "板卡操作配置基类", EnumHelper.DeviceAttributeType.OperationConfig)]
public class MotionCardOperationConfigBase : OperationConfigBase, IComplexDisplay
{
[Category("板卡操作")]
[Description("板卡操作配置基类集合,依次执行")]
[TypeConverter(typeof(CollectionCountConvert))]
[Editor(typeof(MotionCardOperationSetEditor), typeof(UITypeEditor))]
public List<MotionCardOperationSet> OperationCollection { get; set; } = new List<MotionCardOperationSet>();
public string GetDisplayText()
{
//OperationCollection.ForEach(o =>
//{
// o.MotionCardId = DeviceId;
//});
return string.Join(" ", OperationCollection.Select(u => u.GetDisplayText()));
}
}
public class MotionCardOperationSetEditor : ComplexCollectionEditor<MotionCardOperationSet>
{
public MotionCardOperationSetEditor(Type type) : base(type) { }
IOperationConfig opConfig = null;
public override object EditValue(ITypeDescriptorContext context, IServiceProvider provider, object value)
{
if (context.Instance is IOperationConfig config && value is List<MotionCardOperationSet> setList)
{
opConfig = config;
setList.ForEach(set => set.ExecuteDeviceId = opConfig.ExecuteDeviceId);
}
return base.EditValue(context, provider, value);
}
protected override object CreateInstance(Type itemType)
{
object obj = base.CreateInstance(itemType);
if (obj is MotionCardOperationSet set)
{
set.ExecuteDeviceId = opConfig?.ExecuteDeviceId;
}
return obj;
}
}
public class MotionCardOperationObjectEditor : PropertyObjectEditor
{
public override UITypeEditorEditStyle GetEditStyle(System.ComponentModel.ITypeDescriptorContext context)
{
return UITypeEditorEditStyle.Modal;
}
IOperationConfig opConfig = null;
public override object EditValue(ITypeDescriptorContext context, IServiceProvider provider, object value)
{
if (context.Instance is IOperationConfig config && value is MotionCardOperationSet set)
{
opConfig = config;
set.ExecuteDeviceId = opConfig.ExecuteDeviceId;
}
return base.EditValue(context, provider, value);
}
}
[Device("MotionOperationSet", "运动操作配置基类", EnumHelper.DeviceAttributeType.OperationConfig)]
public class MotionCardOperationSet : IOOperationConfigBase
{
#region Ignore
[JsonIgnore]
[Browsable(false)]
public override List<int> InputPara { get; set; } = new List<int>();
/// <summary>
/// 异常反馈值
/// </summary>
[JsonIgnore]
[Browsable(false)]
public override int ExceptionValue { get; set; } = 0;
/// <summary>
/// 发生异常时的重新尝试次数
/// </summary>
[JsonIgnore]
[Browsable(false)]
public override int ReTryTimes { get; set; } = 1;
#endregion
[Category("2.板卡运动配置")]
[DisplayName("运动配置集合")]
[Description("MovingOps多轴并发运动配置集合")]
[TypeConverter(typeof(CollectionCountConvert))]
[Editor(typeof(MovingOpsCollectionEditor), typeof(UITypeEditor))]
public List<MovingOption> MovingOps { get; set; } = new List<MovingOption>();
[Category("5.操作延时")]
[DisplayName("操作前延时")]
[Description("操作前延时单位ms")]
public override int DelayBefore { get; set; } = 0;
[Category("5.操作延时")]
[DisplayName("操作后延时")]
[Description("操作后延时单位ms")]
public override int DelayAfter { get; set; } = 0;
public override string GetDisplayText()
{
string preCheck = "";
PreCheckIOCollection.ForEach(i =>
{
preCheck += i.GetDisplayText() + " ";
});
if (preCheck != "")
{
preCheck = " 预检:" + preCheck;
}
string output = "";
IOOutputCollection.ForEach(i =>
{
output += i.GetDisplayText() + " ";
});
if (output != "")
{
output = " 输出:" + output;
}
string confirm = "";
IOConfirmCollection.ForEach(i =>
{
confirm += i.GetDisplayText() + " ";
});
if (confirm != "")
{
confirm = " 确认:" + confirm;
}
string moving = "";
MovingOps.ForEach(i =>
{
moving += i.GetDisplayText() + " ";
});
if (moving != "")
{
moving = " 运动:" + moving;
}
return (preCheck + output + confirm + moving).Trim();
}
}
[Device("MotionOperation", "运动配置", DeviceAttributeType.OperationConfig)]
public class MotionOperationCollection : OperationConfigBase, IComplexDisplay
{
[Category("运动配置")]
[DisplayName("运动配置集合")]
[Description("MovingOps多轴并发运动配置集合")]
[TypeConverter(typeof(CollectionCountConvert))]
[Editor(typeof(ComplexCollectionEditor<MovingOption>), typeof(UITypeEditor))]
public List<MovingOption> MovingOps { get; set; } = new List<MovingOption>();
[Category("运动配置")]
[Description("多轴并发运动超时设置单位s")]
[DisplayName("多轴并发运动超时")]
public int MovingOpsTimeout { get; set; } = 60;
public string GetDisplayText()
{
return $"{string.Join(" ", MovingOps.Select(u => u.GetDisplayText()))}";
}
}
#region Converter & Editor
public class AxisSettingConverter : ComboBoxItemTypeConvert
{
public override Hashtable GetConvertHash(ITypeDescriptorContext context)
{
Hashtable table = new Hashtable();
using (var scope = GlobalVar.Container.BeginLifetimeScope())
{
var deviceList = scope.Resolve<List<IDevice>>();
if (deviceList != null)
{
var motionCards = deviceList.ConvertAll(d =>
{
if (d is MotionCardBase motion)
{
return motion;
}
else
{
return null;
}
});
if (motionCards != null)
{
motionCards.ForEach(m =>
{
if (m != null)
{
m.IConfig.AxisSettings.ForEach(a =>
{
table[a.AxisIndex] = a.AxisIndex + "|" + a.AxisName;
});
}
});
}
}
}
return table;
}
}
public class MovingOpsCollectionEditor : ComplexCollectionEditor<MovingOption>
{
public MovingOpsCollectionEditor(Type type) : base(type)
{
}
MotionCardBase motionCard = null;
public override object EditValue(ITypeDescriptorContext context, IServiceProvider provider, object value)
{
if (context.Instance is MotionCardOperationSet set)
{
if (!string.IsNullOrWhiteSpace(set.ExecuteDeviceId))
{
using (var scope = GlobalVar.Container.BeginLifetimeScope())
{
var deviceList = scope.Resolve<List<IDevice>>();
if (deviceList != null)
{
motionCard = deviceList.FirstOrDefault(u => u.Id == set.ExecuteDeviceId) as MotionCardBase;
}
}
}
if (motionCard != null && value is List<MovingOption> ops)
{
ops.ForEach(o => o.SetAxisSetting(motionCard.IConfig.AxisSettings));
}
}
return base.EditValue(context, provider, value);
}
protected override object SetItems(object editValue, object[] value)
{
Array.ForEach(value, v =>
{
if (v is MovingOption op && motionCard != null)
{
op.SetAxisSetting(motionCard.IConfig.AxisSettings);
}
});
return base.SetItems(editValue, value);
}
#endregion
}
}

View File

@ -0,0 +1,545 @@
using Autofac;
using BRS.Common.Factory;
using BRS.Common.Model.Helper;
using BRS.Common.Interface;
using BRS.Common.Model;
using System;
using System.Collections;
using System.Collections.Generic;
using System.ComponentModel;
using System.ComponentModel.Design;
using System.Diagnostics;
using System.Drawing.Design;
using System.IO;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.Windows.Forms.Design;
using static BRS.Common.Model.Helper.EnumHelper;
namespace BRS.Common.Base
{
public abstract class PLCBase : DeviceBase, IMonitor, IMotion
{
public PLCInitialConfigBase IConfig
{
get => InitialConfig as PLCInitialConfigBase;
}
public abstract List<int> Read(string startAddress, int length);
public abstract void ReadItem(PLCItem item);
public abstract int ReadInt(string startAddress);
public abstract string ReadString(string startAddress, ushort length);
public abstract float ReadFloat(string startAddress);
public abstract void WriteItem(PLCItem item, bool waitForReply = true);
public abstract void WriteInt(string address, int writeValue, bool waitForReply = true);
public abstract void WriteString(string address, string writeValue, bool waitForReply = true);
public abstract void WriteFloat(string address, float writeValue, bool waitForReply = true);
#region IMonitor
public Action<DateTime, string, IDevice, IMonitorSet> OnMonitorInvoke { get; set; }
public Action<DateTime, IDevice, IWarningSet> OnMonitorAlarm { get; set; }
public List<int> MonitorValues { get; set; } = new List<int>();
public abstract List<int> GetMonitorValues(int startAddress, int length);
public virtual void Monitor()
{
if (IConfig != null
&& IConfig.EventStartAddress > 0
&& IConfig.EventLength > 0)
{
while (CurrentState != DeviceState.DSClose && CurrentState != DeviceState.DSExcept)
{
if (!IConfig.IsEnableMonitor)
return;
try
{
List<int> newValues = GetMonitorValues(IConfig.EventStartAddress, IConfig.EventLength);
if (newValues == null || newValues.Count == 0)
continue;
Stopwatch sw = new Stopwatch();
sw.Start();
if (MonitorValues.Count == newValues.Count)
{
var tempNew = new List<int>(newValues);
var tempOld = new List<int>(MonitorValues);
MonitorCheckAndInvoke(tempNew, tempOld);
}
MonitorValues = new List<int>(newValues);
sw.Stop();
if (sw.ElapsedMilliseconds > 20)
{
LogAsync(DateTime.Now, LogLevel.Detail, $"{this.Name}轮询时间:{sw.ElapsedMilliseconds}");
}
if (IConfig.MonitorInterval > 0)
{
Thread.Sleep(IConfig.MonitorInterval);
}
}
catch (Exception ex)
{
if (CurrentState == DeviceState.DSOpen)
{
LogAsync(DateTime.Now, LogLevel.Exception, $"{this.Name}监听异常,{ex.GetExceptionMessage()}");
}
}
}
}
}
protected virtual void MonitorCheckAndInvoke(List<int> tempNew, List<int> tempOld)
{
#region PLC警报信息
//PLCIConfig.WarningSetCollection.ForEach(w =>
Parallel.ForEach(IConfig.WarningSetCollection, warningSet =>
{
if (warningSet is PLCWarningSet plcWS)
{
if (plcWS.WarningIndex_Word < 0 || plcWS.WarningIndex_Word >= tempNew.Count)
return;
if (plcWS.WarningIndex_Bit < 0 || plcWS.WarningIndex_Bit > 16)
return;
int bitbnum = (tempNew[plcWS.WarningIndex_Word] >> plcWS.WarningIndex_Bit);
bool isOn = ((tempNew[plcWS.WarningIndex_Word] >> plcWS.WarningIndex_Bit) & 1) == (plcWS.TriggerValue ? 1 : 0);
if (plcWS.CurrentStatus != isOn)
{
plcWS.CurrentStatus = isOn;
plcWS.TriggerTime = DateTime.Now;
SaveAlarmCSVAsync(DateTime.Now, this.Name, plcWS);
OnMonitorAlarm?.BeginInvoke(DateTime.Now, this, plcWS, null, null);
}
}
});
#endregion
//PLCIConfig.MonitorSetCollection.ForEach(set =>
Parallel.ForEach(IConfig.MonitorSetCollection, set =>
{
PLCMonitorSet monitorSet = set as PLCMonitorSet;
//xhm
if (monitorSet.TriggerIndex == 0)
{
return;
}
//var triggerIndex = monitorSet.TriggerIndex / 2;//原始代码
var triggerIndex =( monitorSet.TriggerIndex -1)/ 2;//(读取 32位是 plc 2个地址算作一位
if (triggerIndex < 0 || triggerIndex >= tempNew.Count)
{
return;
}
int newValue = tempNew[triggerIndex];
int oldValue = newValue;
if (tempOld.Count == 0)
{
if (monitorSet.IsOriginOutput)
{
oldValue = -999;
}
}
else
{
oldValue = tempOld[triggerIndex];
}
if (newValue != oldValue)
{
if (monitorSet.TriggerValue == -999 || newValue == monitorSet.TriggerValue)
{
if (monitorSet.OpConfig == null)
{
monitorSet.OpConfig = new OperationConfigBase();
}
monitorSet.OpConfig.TriggerValue = newValue;
monitorSet.OpConfig.InputPara = monitorSet.InputDataIndex.ConvertAll(index =>
{
return tempNew[index];
}).ToList();
OnMonitorInvoke?.BeginInvoke(DateTime.Now, monitorSet.ExecuteDevice, this, monitorSet, OnMethodInvoked, monitorSet);
}
}
});
}
private void OnMethodInvoked(IAsyncResult ar)
{
PLCMonitorSet monitorSet = ar.AsyncState as PLCMonitorSet;
ResponseMessage resValues = monitorSet.Response;
if (resValues.Result == (int)ReturnValue.IGNORE)
{
return;
}
Stopwatch sw = new Stopwatch();
sw.Start();
if (!string.IsNullOrEmpty(monitorSet.ReplyDataAddress) && resValues.DataList.Count > 0)
{
PLCItem item = new PLCItem
{
ItemLength = resValues.DataList.Count,
Address = monitorSet.ReplyDataAddress,
ItemValues = resValues.DataList
};
WriteItem(item, false);
}
if (!string.IsNullOrEmpty(monitorSet.NoticeAddress))
{
int repeatTime = 5;
//LogAsync(DateTime.Now, methodCode + "开始反馈", "");
do
{
try
{
WriteInt(monitorSet.NoticeAddress, resValues.Result, false);
repeatTime = 0;
}
catch (Exception ex)
{
repeatTime--;
if (repeatTime <= 0)
{
new ProcessException("PLC反馈写入异常", ex, ExceptionLevel.Warning);
}
}
} while (repeatTime > 0);
}
sw.Stop();
LogAsync(DateTime.Now, LogLevel.Detail, $"{Name}反馈完成,耗时{sw.ElapsedMilliseconds}ms{resValues.GetDisplayText()}");
}
#region Alarm
public virtual void ResetAlarm()
{
IConfig.WarningSetCollection.ForEach(u => u.CurrentStatus = !u.TriggerValue);
}
object _alarmLock = new object();
private async void SaveAlarmCSVAsync(DateTime now, string plcName, PLCWarningSet ws)
{
await Task.Run(() =>
{
lock (_alarmLock)
{
DirectoryInfo dir = new DirectoryInfo(this.IConfig.LogPath);
if (!dir.Exists)
{
dir.Create();
}
string path = Path.Combine(IConfig.LogPath, $"Alarm_{Name}_{now.ToString("yyyyMMdd")}.csv");
bool fileExist = File.Exists(path);
using (StreamWriter writer = new StreamWriter(path, true, System.Text.Encoding.UTF8))
{
if (!fileExist)
{
writer.WriteLine("Time,Source,AlarmCode,AlarmDescription,AlarmStatus");
}
writer.WriteLine($"{now.ToString("HH:mm:ss.fff")},{plcName},{ws.WarningCode},{ws.WarningDescription},{(ws.CurrentStatus ? "" : "")}");
writer.Flush();
writer.Close();
}
}
});
}
#endregion
#endregion
protected override void Pause()
{
}
protected override void Resume()
{
}
protected override void Start()
{
Task.Run(() =>
{
Monitor();
});
base.Start();
}
#region IMotion
public List<AxisInfo> GetCurrentAxisInfo(params string[] axisName)
{
List<PLCMotionDefinition_State> mds = new List<PLCMotionDefinition_State>(IConfig.MotionStateCollection);
if (axisName.Length > 0)
{
mds = mds.Where(u => axisName.Contains(u.AxisName)).ToList();
}
var locations = mds.ConvertAll(u =>
{
AxisInfo axisInfo = new AxisInfo();
axisInfo.AxisName = u.AxisName;
axisInfo.AxisLocation = MonitorValues.Skip(u.RegisterIndex).Take(2).ToList().ParseUnsignShortListToInt()[0];
return axisInfo;
}).ToList();
return locations;
}
public virtual ResponseMessage MoveToPoint(IOperationConfig opConfig)
{
ResponseMessage msg = new ResponseMessage();
msg.Result = -1;
msg.Message = "运动方法未实现";
return msg;
}
#endregion
}
public abstract class PLCOperationConfigBase : OperationConfigBase
{
/// <summary>
/// 需要操作的PLC项
/// </summary>
public List<PLCItem> Items { get; set; } = new List<PLCItem>();
}
public class PLCInitialConfigBase : InitialConfigBase, IMonitorConfig, IWarningSetCollection
{
[Category("驱动类型")]
[Description("驱动类型")]
[DisplayName("驱动类型")]
[TypeConverter(typeof(DeviceTypeSelectorConverter<PLCBase>))]
public override string DriverType { get; set; }
[Category("警报配置")]
[Description("警报配置列表")]
[DisplayName("警报配置")]
[TypeConverter(typeof(CollectionCountConvert))]
[Editor(typeof(WarningSetsEditor<PLCWarningSet>), typeof(UITypeEditor))]
public List<IWarningSet> WarningSetCollection { get; set; } = new List<IWarningSet>();
#region IMonitorConfig
[Category("监听设置")]
[Description("监听操作配置集合")]
[DisplayName("监听配置")]
[TypeConverter(typeof(CollectionCountConvert))]
[Editor(typeof(ComplexCollectionEditor<PLCMonitorSet>), typeof(UITypeEditor))]
public List<IMonitorSet> MonitorSetCollection { get; set; } = new List<IMonitorSet>();
[Category("监听设置")]
[Description("true启动监听 false关闭监听")]
[DisplayName("监听启用")]
public bool IsEnableMonitor { get; set; } = true;
[Category("监听设置")]
[Description("扫描间隔时间单位ms")]
[DisplayName("扫描间隔")]
public int MonitorInterval { get; set; } = 100;
[Category("监听设置")]
[Description("超时设置单位ms")]
[DisplayName("监听超时")]
public int MonitorTimeout { get; set; } = 500;
[Category("事件地址设置")]
[Description("事件开始地址PLC的实际寄存器地址。十进制不包含功能码。")]
[DisplayName("监听开始地址")]
public int EventStartAddress { get; set; } = 10;
[Category("事件地址设置")]
[Description("事件地址长度最大长度240")]
[DisplayName("监听长度")]
public int EventLength { get; set; } = 120;
public List<IMonitorSet> GetAllMonitorSet()
{
WarningSetCollection.ForEach(m => m.SourceDevice = this.Name);
MonitorSetCollection.ForEach(m => m.SourceDeviceId = this.Id);
return MonitorSetCollection;
}
#endregion
#region IMotion Related
[Category("运动配置")]
[Description("运动轴状态集合")]
[DisplayName("运动轴状态集合")]
[TypeConverter(typeof(CollectionCountConvert))]
[Editor(typeof(ComplexCollectionEditor<PLCMotionDefinition_State>), typeof(UITypeEditor))]
public List<PLCMotionDefinition_State> MotionStateCollection { get; set; } = new List<PLCMotionDefinition_State>();
#endregion
}
#region Converter & Editor
//public class PLCTypeConverter : StringConverter
//{
// public override bool GetStandardValuesSupported(ITypeDescriptorContext context)
// {
// return true;
// }
// public override bool GetStandardValuesExclusive(ITypeDescriptorContext context)
// {
// return true;
// }
// public override StandardValuesCollection GetStandardValues(ITypeDescriptorContext context)
// {
// List<string> devices = DeviceFactory.GetAllSupportDeviceTypeNames(typeof(PLCBase));
// devices.Insert(0, "");
// return new StandardValuesCollection(devices);
// }
//}
public class PLCInitialConfigEditor : UITypeEditor
{
public override UITypeEditorEditStyle GetEditStyle(System.ComponentModel.ITypeDescriptorContext context)
{
return UITypeEditorEditStyle.Modal;
}
public override object EditValue(ITypeDescriptorContext context, IServiceProvider provider, object value)
{
IWindowsFormsEditorService edSvc = (IWindowsFormsEditorService)provider.GetService(typeof(IWindowsFormsEditorService));
if (edSvc != null)
{
Form form = new Form
{
FormBorderStyle = FormBorderStyle.SizableToolWindow,
StartPosition = FormStartPosition.CenterParent,
Text = context.PropertyDescriptor.DisplayName + "--" + context.PropertyDescriptor.Description
};
PropertyGrid pg = new PropertyGrid
{
Dock = DockStyle.Fill,
ToolbarVisible = false
};
string driverType = (value as PLCInitialConfigBase).DriverType;
if (!string.IsNullOrWhiteSpace(driverType))
{
IInitialConfig initial = ConfigFactory.GetInitialConfig(driverType);
initial.DataFrom(value);
value = initial;
}
pg.SelectedObject = value;
form.Controls.Add(pg);
form.ShowDialog();
value = pg.SelectedObject;
return value;
}
return base.EditValue(context, provider, value);
}
}
public class PLCDeviceIdConverter : ComboBoxItemTypeConvert
{
public override Hashtable GetConvertHash(ITypeDescriptorContext context)
{
Hashtable table = new Hashtable();
using (var scope = GlobalVar.Container.BeginLifetimeScope())
{
var config = scope.Resolve<IProcessConfig>();
//config.PLCConfigCollection.ForEach(plc =>
//{
// table[plc.Id] = plc.Name;
//});
}
return table;
}
}
public class PLCDeviceNameConverter : ComboBoxItemTypeConvert
{
public override Hashtable GetConvertHash(ITypeDescriptorContext context)
{
Hashtable table = new Hashtable();
using (var scope = GlobalVar.Container.BeginLifetimeScope())
{
var config = scope.Resolve<IProcessConfig>();
//config.PLCConfigCollection.ForEach(plc =>
//{
// table[plc.Name] = plc.Name;
//});
}
return table;
}
}
#endregion
#region IMotion Related
public class PLCMotionDefinition_State : IComplexDisplay
{
[Category("运动轴信息配置")]
[Description("运动轴名称")]
public string AxisName { get; set; }
[Category("运动轴信息配置")]
[Description("运动轴位置信息索引和PLC监听地址配合使用从0开始长度默认为2")]
public int RegisterIndex { get; set; }
public string GetDisplayText()
{
return $"{AxisName} {RegisterIndex}";
}
}
public class PLCMotionDefinition_P2P
{
public string AxisName { get; set; }
public string VelocityRegister { get; set; }
public string DestinationRegister { get; set; }
public string TriggerRegister { get; set; }
}
public class PLCMotionDefinition_Jog
{
public string AxisName { get; set; }
public string VelocityRegister { get; set; }
public string TriggerRegister { get; set; }
}
#endregion
}

View File

@ -0,0 +1,57 @@
using BRS.Common.Factory;
using System.Collections.Generic;
using System.ComponentModel;
namespace BRS.Common.Base
{
public abstract class RS_232CommBase : DeviceBase
{
protected override void Init()
{
}
protected override void Pause()
{
}
protected override void Resume()
{
}
protected override void Start()
{
}
protected override void Stop()
{
}
public abstract bool SetLightDealyTime(int aisle);
}
//public class RS_232TypeConverter : StringConverter
//{
// public override bool GetStandardValuesExclusive(ITypeDescriptorContext context)
// {
// return true;
// }
// public override bool GetStandardValuesSupported(ITypeDescriptorContext context)
// {
// return true;
// }
// public override StandardValuesCollection GetStandardValues(ITypeDescriptorContext context)
// {
// List<string> devices = DeviceFactory.GetAllSupportDeviceTypeNames(typeof(ModbusCommBase));
// devices.Insert(0, "");
// return new StandardValuesCollection(devices);
// }
//}
}

View File

@ -0,0 +1,843 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Autofac;
using BRS.Common.Model.Helper;
using BRS.Common.Interface;
using BRS.Common.Model;
using Newtonsoft.Json;
using System.ComponentModel;
using System.ComponentModel.Design;
using System.Drawing.Design;
using System.Net.Sockets;
using System.Threading;
using System.Windows.Forms;
using static BRS.Common.Model.Helper.EnumHelper;
namespace BRS.Common.Base
{
public abstract class RobotBase : DeviceBase
{
#region Property & Field
public virtual RobotInitialConfigBase IConfig
{
get => InitialConfig as RobotInitialConfigBase;
}
public RobotPoint CurrentPoint { get; set; } = null;
#endregion
#region DeviceBase
#endregion
#region Method
public abstract void Move(StrRobotPoint point, int moveType, bool isWaitFinished);
public abstract void Load(RobotPoint point, int trayType, float startZHeight, float agvStartZHeight, bool isWaitFinished, bool applyTimeout = true);
public abstract void UnLoad(RobotPoint point, int trayType, float startZHeight, float agvStartZHeight, bool isWaitFinished);
public abstract StrRobotPoint GetPosition();
public abstract ResponseMessage SendMsg<T>(T t, bool isWaitReply = true, bool isMonitorMsg = false) where T : IRobotMsg;
//伺服下电
public abstract void power_off();
//设置伺服
public abstract void set_servo_stat();
//伺服上电
public abstract void servo_on();
//获取点位
public abstract void get_pos();
//关节运动
public abstract void move_j();
//直线运动
public abstract void move_l();
//圆弧运动
public abstract void move_c();
//整圆运动
public abstract void move_ca();
//连接状态
public abstract void connection_status();
//当前模式
public abstract void get_mode();
//示教模式
public abstract void set_mode();
//运行模式
public abstract void set_run_mode();
//获取坐标系
public abstract void get_coord();
//设置坐标系
public abstract void set_coord();
//设置点速度
public abstract void set_speed(int spendNum);
//获取点速度
public abstract int get_speed();
//获取运行状态
public abstract int get_status();
//获取伺服状态
public abstract void get_servo_state();
//清除伺服错误
public abstract void clear_servo();
//获取IO
public abstract void get_IO();
//设置数字输出
public abstract void set_dout();
//开启追加运行模式
public abstract void motion_mode_on();
//关闭追加运行模式
public abstract void motion_mode_off();
//发送追加运行队列
public abstract void send_queue();
//追加运行开始
public abstract void continuous_motion_start();
//追加运行暂停
public abstract void continuous_motion_pause();
//追加运行停止
public abstract void continuous_motion_stop();
#endregion
}
public class RobotInitialConfigBase : InitialConfigBase//, IWarningSetCollection
{
[Category("驱动类型")]
[Description("驱动类型")]
[DisplayName("驱动类型")]
//[TypeConverter(typeof(DeviceTypeConverter<RobotBase>))]
[TypeConverter(typeof(DeviceTypeSelectorConverter<RobotBase>))]
public override string DriverType { get; set; }
#region
[Category("1.机械臂关键点位")]
[Description("机械臂起始位置P0")]
[DisplayName("机械臂起始位置P0")]
[TypeConverter(typeof(ComplexObjectConvert))]
[Editor(typeof(PropertyObjectEditor), typeof(UITypeEditor))]
public RobotPoint RobotOriginPoint { get; set; } = new RobotPoint();
[Category("2.机械臂上料关键点位")]
[Description("1号机1号位抓取点位置P101")]
[DisplayName("1号机1号位抓取点位置P101")]
[TypeConverter(typeof(ComplexObjectConvert))]
[Editor(typeof(PropertyObjectEditor), typeof(UITypeEditor))]
public RobotPoint RobotMachine1Entrance1GrabPoint { get; set; } = new RobotPoint();
[Category("2.机械臂上料关键点位")]
[Description("1号机2号位抓取点位置P201")]
[DisplayName("1号机2号位抓取点位置P201")]
[TypeConverter(typeof(ComplexObjectConvert))]
[Editor(typeof(PropertyObjectEditor), typeof(UITypeEditor))]
public RobotPoint RobotMachine1Entrance2GrabPoint { get; set; } = new RobotPoint();
[Category("2.机械臂上料关键点位")]
[Description("2号机1号位抓取点位置P101")]
[DisplayName("2号机1号位抓取点位置P101")]
[TypeConverter(typeof(ComplexObjectConvert))]
[Editor(typeof(PropertyObjectEditor), typeof(UITypeEditor))]
public RobotPoint RobotMachine2Entrance1GrabPoint { get; set; } = new RobotPoint();
[Category("2.机械臂上料关键点位")]
[Description("1号机2号位抓取点位置P201")]
[DisplayName("2号机2号位抓取点位置P201")]
[TypeConverter(typeof(ComplexObjectConvert))]
[Editor(typeof(PropertyObjectEditor), typeof(UITypeEditor))]
public RobotPoint RobotMachine2Entrance2GrabPoint { get; set; } = new RobotPoint();
[Category("2.机械臂上料关键点位")]
[Description("1号机1号位放料位置P102")]
[DisplayName("1号机1号位放料位置P102")]
[TypeConverter(typeof(ComplexObjectConvert))]
[Editor(typeof(PropertyObjectEditor), typeof(UITypeEditor))]
public RobotPoint RobotMachine1Entrance1UpPlacePoint { get; set; } = new RobotPoint();
[Category("2.机械臂上料关键点位")]
[Description("1号机2号位放料位置P202")]
[DisplayName("1号机2号位放料位置P202")]
[TypeConverter(typeof(ComplexObjectConvert))]
[Editor(typeof(PropertyObjectEditor), typeof(UITypeEditor))]
public RobotPoint RobotMachine1Entrance2UpPlacePoint { get; set; } = new RobotPoint();
[Category("2.机械臂上料关键点位")]
[Description("2号机1号位放料位置P102")]
[DisplayName("2号机1号位放料位置P102")]
[TypeConverter(typeof(ComplexObjectConvert))]
[Editor(typeof(PropertyObjectEditor), typeof(UITypeEditor))]
public RobotPoint RobotMachine2Entrance1UpPlacePoint { get; set; } = new RobotPoint();
[Category("2.机械臂上料关键点位")]
[Description("2号机2号位放料位置P202")]
[DisplayName("2号机2号位放料位置P202")]
[TypeConverter(typeof(ComplexObjectConvert))]
[Editor(typeof(PropertyObjectEditor), typeof(UITypeEditor))]
public RobotPoint RobotMachine2Entrance2UpPlacePoint { get; set; } = new RobotPoint();
#endregion
#region
[Category("3.机械臂上料项目")]
[Description("1号机1号位上料点组")]
[DisplayName("1号机1号位上料点组")]
[TypeConverter(typeof(CollectionCountConvert))]
[Editor(typeof(ComplexCollectionEditor<RobotPoint>), typeof(UITypeEditor))]
public List<RobotPoint> RobotMachine1Entrance1UpPoints { get; set; } = new List<RobotPoint>();
[Category("3.机械臂上料项目")]
[Description("1号机2号位上料点组")]
[DisplayName("1号机2号位上料点组")]
[TypeConverter(typeof(CollectionCountConvert))]
[Editor(typeof(ComplexCollectionEditor<RobotPoint>), typeof(UITypeEditor))]
public List<RobotPoint> RobotMachine1Entrance2UpPoints { get; set; } = new List<RobotPoint>();
[Category("3.机械臂上料项目")]
[Description("2号机1号位上料点组")]
[DisplayName("2号机1号位上料点组")]
[TypeConverter(typeof(CollectionCountConvert))]
[Editor(typeof(ComplexCollectionEditor<RobotPoint>), typeof(UITypeEditor))]
public List<RobotPoint> RobotMachine2Entrance1UpPoints { get; set; } = new List<RobotPoint>();
[Category("3.机械臂上料项目")]
[Description("2号机2号位上料点组")]
[DisplayName("2号机2号位上料点组")]
[TypeConverter(typeof(CollectionCountConvert))]
[Editor(typeof(ComplexCollectionEditor<RobotPoint>), typeof(UITypeEditor))]
public List<RobotPoint> RobotMachine2Entrance2UpPoints { get; set; } = new List<RobotPoint>();
#endregion
#region
[Category("4.机械臂取料(下料)关键点位")]
[Description("1号机1号位取料(下料)点位置P107")]
[DisplayName("1号机1号位取料(下料)点位置P107")]
[TypeConverter(typeof(ComplexObjectConvert))]
[Editor(typeof(PropertyObjectEditor), typeof(UITypeEditor))]
public RobotPoint RobotMachine1Entrance1TakeTyrePoint { get; set; } = new RobotPoint();
//P107点位斜向上
[Category("4.机械臂取料(下料)关键点位")]
[Description("1号机1号位取料(下料)点位置P107斜上方")]
[DisplayName("1号机1号位取料(下料)点位置P107斜上方")]
[TypeConverter(typeof(ComplexObjectConvert))]
[Editor(typeof(PropertyObjectEditor), typeof(UITypeEditor))]
public RobotPoint RobotMachine1Entrance1TakeTyreTiltUpperPoint { get; set; } = new RobotPoint();
[Category("4.机械臂取料(下料)关键点位")]
[Description("1号机2号位取料(下料)点位置P207")]
[DisplayName("1号机2号位取料(下料)点位置P207")]
[TypeConverter(typeof(ComplexObjectConvert))]
[Editor(typeof(PropertyObjectEditor), typeof(UITypeEditor))]
public RobotPoint RobotMachine1Entrance2TakeTyrePoint { get; set; } = new RobotPoint();
//P207斜上方
[Category("4.机械臂取料(下料)关键点位")]
[Description("1号机2号位取料(下料)点位置P207斜上方")]
[DisplayName("1号机2号位取料(下料)点位置P207斜上方")]
[TypeConverter(typeof(ComplexObjectConvert))]
[Editor(typeof(PropertyObjectEditor), typeof(UITypeEditor))]
public RobotPoint RobotMachine1Entrance2TakeTyreTiltUpperPoint { get; set; } = new RobotPoint();
[Category("4.机械臂取料(下料)关键点位")]
[Description("2号机1号位取料(下料)点位置P107")]
[DisplayName("2号机1号位取料(下料)点位置P107")]
[TypeConverter(typeof(ComplexObjectConvert))]
[Editor(typeof(PropertyObjectEditor), typeof(UITypeEditor))]
public RobotPoint RobotMachine2Entrance1TakeTyrePoint { get; set; } = new RobotPoint();
//2号机1号位下料点斜上方
[Category("4.机械臂取料(下料)关键点位")]
[Description("2号机1号位取料(下料)点位置P107斜上方")]
[DisplayName("2号机1号位取料(下料)点位置P107斜上方")]
[TypeConverter(typeof(ComplexObjectConvert))]
[Editor(typeof(PropertyObjectEditor), typeof(UITypeEditor))]
public RobotPoint RobotMachine2Entrance1TakeTyreTiltUpperPoint { get; set; } = new RobotPoint();
[Category("4.机械臂取料(下料)关键点位")]
[Description("1号机2号位取料(下料)点位置P207")]
[DisplayName("2号机2号位取料(下料)点位置P207")]
[TypeConverter(typeof(ComplexObjectConvert))]
[Editor(typeof(PropertyObjectEditor), typeof(UITypeEditor))]
public RobotPoint RobotMachine2Entrance2TakeTyrePoint { get; set; } = new RobotPoint();
//2号机1号位下料点斜上方
[Category("4.机械臂取料(下料)关键点位")]
[Description("2号机2号位取料(下料)点位置P207斜上方")]
[DisplayName("2号机2号位取料(下料)点位置P207斜上方")]
[TypeConverter(typeof(ComplexObjectConvert))]
[Editor(typeof(PropertyObjectEditor), typeof(UITypeEditor))]
public RobotPoint RobotMachine2Entrance2TakeTyreTiltUpperPoint { get; set; } = new RobotPoint();
[Category("4.机械臂取料(下料)关键点位")]
[Description("1号机1号位放置点位置P108")]
[DisplayName("1号机1号位放置点位置P108")]
[TypeConverter(typeof(ComplexObjectConvert))]
[Editor(typeof(PropertyObjectEditor), typeof(UITypeEditor))]
public RobotPoint RobotMachine1Entrance1DownPlacePoint { get; set; } = new RobotPoint();
[Category("4.机械臂取料(下料)关键点位")]
[Description("1号机2号位放置点位置P208")]
[DisplayName("1号机2号位放置点位置P208")]
[TypeConverter(typeof(ComplexObjectConvert))]
[Editor(typeof(PropertyObjectEditor), typeof(UITypeEditor))]
public RobotPoint RobotMachine1Entrance2DownPlacePoint { get; set; } = new RobotPoint();
[Category("4.机械臂取料(下料)关键点位")]
[Description("2号机1号位放置点位置P108")]
[DisplayName("2号机1号位放置点位置P108")]
[TypeConverter(typeof(ComplexObjectConvert))]
[Editor(typeof(PropertyObjectEditor), typeof(UITypeEditor))]
public RobotPoint RobotMachine2Entrance1DownPlacePoint { get; set; } = new RobotPoint();
[Category("4.机械臂取料(下料)关键点位")]
[Description("1号机2号位放置点位置P208")]
[DisplayName("2号机2号位放置点位置P208")]
[TypeConverter(typeof(ComplexObjectConvert))]
[Editor(typeof(PropertyObjectEditor), typeof(UITypeEditor))]
public RobotPoint RobotMachine2Entrance2DownPlacePoint { get; set; } = new RobotPoint();
#endregion
#region
[Category("5.机械臂取料(下料)项目")]
[Description("1号机1号位取料(下料)点组")]
[DisplayName("1号机1号位取料(下料)点组")]
[TypeConverter(typeof(CollectionCountConvert))]
[Editor(typeof(ComplexCollectionEditor<RobotPoint>), typeof(UITypeEditor))]
public List<RobotPoint> RobotMachine1Entrance1DownPoints { get; set; } = new List<RobotPoint>();
[Category("5.机械臂取料(下料)项目")]
[Description("1号机2号位取料(下料)点组")]
[DisplayName("1号机2号位取料(下料)点组")]
[TypeConverter(typeof(CollectionCountConvert))]
[Editor(typeof(ComplexCollectionEditor<RobotPoint>), typeof(UITypeEditor))]
public List<RobotPoint> RobotMachine1Entrance2DownPoints { get; set; } = new List<RobotPoint>();
[Category("5.机械臂取料(下料)项目")]
[Description("2号机1号位取料(下料)点组")]
[DisplayName("2号机1号位取料(下料)点组")]
[TypeConverter(typeof(CollectionCountConvert))]
[Editor(typeof(ComplexCollectionEditor<RobotPoint>), typeof(UITypeEditor))]
public List<RobotPoint> RobotMachine2Entrance1DownPoints { get; set; } = new List<RobotPoint>();
[Category("5.机械臂取料(下料)项目")]
[Description("2号机2号位取料(下料)点组")]
[DisplayName("2号机2号位取料(下料)点组")]
[TypeConverter(typeof(CollectionCountConvert))]
[Editor(typeof(ComplexCollectionEditor<RobotPoint>), typeof(UITypeEditor))]
public List<RobotPoint> RobotMachine2Entrance2DownPoints { get; set; } = new List<RobotPoint>();
#endregion
[Category("机械臂上料项目")]
[Description("路径上料移动点组")]
[DisplayName("路径上料移动点组")]
[TypeConverter(typeof(CollectionCountConvert))]
[Editor(typeof(ComplexCollectionEditor<RobotPoint>), typeof(UITypeEditor))]
public List<RobotPoint> RobotUpMovePoints { get; set; } = new List<RobotPoint>();
[Category("机械臂上料项目")]
[Description("路径上料返回点组")]
[DisplayName("路径上料返回点组")]
[TypeConverter(typeof(CollectionCountConvert))]
[Editor(typeof(ComplexCollectionEditor<RobotPoint>), typeof(UITypeEditor))]
//[TypeConverter(typeof(SimpleCollectionConvert<double>))]
public List<RobotPoint> RobotUPBackPoints { get; set; } = new List<RobotPoint>();
[Category("机械臂下料项目")]
[Description("路径下料移动点组")]
[DisplayName("路径下料移动点组")]
[TypeConverter(typeof(CollectionCountConvert))]
[Editor(typeof(ComplexCollectionEditor<RobotPoint>), typeof(UITypeEditor))]
public List<RobotPoint> RobotDownMovePoints { get; set; } = new List<RobotPoint>();
[Category("机械臂下料项目")]
[Description("路径下料返回点组")]
[DisplayName("路径下料返回点组")]
[TypeConverter(typeof(CollectionCountConvert))]
[Editor(typeof(ComplexCollectionEditor<RobotPoint>), typeof(UITypeEditor))]
//[TypeConverter(typeof(SimpleCollectionConvert<double>))]
public List<RobotPoint> RobotDownBackPoints { get; set; } = new List<RobotPoint>();
[Category("机械臂下料项目")]
[Description("路径下料返回f辅助点组")]
[DisplayName("路径下料返回f辅助点组")]
[TypeConverter(typeof(CollectionCountConvert))]
[Editor(typeof(ComplexCollectionEditor<RobotPoint>), typeof(UITypeEditor))]
//[TypeConverter(typeof(SimpleCollectionConvert<double>))]
public List<RobotPoint> ConfigRobotDownBackPoints { get; set; } = new List<RobotPoint>();
[Category("机械臂项目")]
[Description("机械臂起始位置")]
[DisplayName("机械臂起始位置")]
[TypeConverter(typeof(ComplexObjectConvert))]
[Editor(typeof(PropertyObjectEditor), typeof(UITypeEditor))]
public RobotPoint RobotInitPosition { get; set; } = new RobotPoint();
[Category("机械臂项目")]
[Description("机械臂运动点X1位")]
[DisplayName("机械臂运动点X1位")]
[TypeConverter(typeof(ComplexObjectConvert))]
[Editor(typeof(PropertyObjectEditor), typeof(UITypeEditor))]
public RobotPoint X1Point { get; set; } = new RobotPoint();
[Category("机械臂项目")]
[Description("机械臂运动点X2位")]
[DisplayName("机械臂运动点X2位")]
[TypeConverter(typeof(ComplexObjectConvert))]
[Editor(typeof(PropertyObjectEditor), typeof(UITypeEditor))]
public RobotPoint X2Point { get; set; } = new RobotPoint();
[Category("机械臂项目")]
[Description("轮胎半径")]
[DisplayName("轮胎半径")]
public string RobotTyReRadius { get; set; }
[Category("机械臂项目")]
[Description("轮胎尺寸")]
[DisplayName("轮胎尺寸")]
// [TypeConverter(typeof(CollectionCountConvert))]
// [Editor(typeof(ComplexCollectionEditor<string>), typeof(UITypeEditor))]
//[TypeConverter(typeof(SimpleCollectionConvert<double>))]
public string SetWhoolSize { get; set; } = "17";
[Category("机械臂夹爪项目")]
[Description("夹紧点")]
[DisplayName("夹紧点")]
public string GripperFastenPosition { get; set; } = "75000";
[Category("机械臂夹爪项目")]
[Description("放松点")]
[DisplayName("放松点")]
public string GripperLoosenPosition { get; set; } = "40000";
[Category("机械臂夹爪项目")]
[Description("全松点")]
[DisplayName("全松点")]
public string GripperAllLoosenPosition { get; set; } = "40000";
[Category("机械臂夹爪项目")]
[Description("全紧点")]
[DisplayName("全紧点")]
public string GripperAllFastenPosition { get; set; } = "92000";
#region 12
[Category("机械臂项目12寸轮胎")]
[Description("上料夹紧点")]
[DisplayName("上料夹紧点")]
public string Wheel12GripperUpFasten { get; set; } = "40000";
[Category("机械臂项目12寸轮胎")]
[Description("上料放松点")]
[DisplayName("上料放松点")]
public string Wheel12GripperUpLoosen { get; set; } = "75000";
[Category("机械臂项目12寸轮胎")]
[Description("下料夹紧点")]
[DisplayName("下料夹紧点")]
public string Wheel12GripperDownFasten { get; set; } = "40000";
[Category("机械臂项目12寸轮胎")]
[Description("下料放松点")]
[DisplayName("下料放松点")]
public string Wheel12GripperDownLoosen { get; set; } = "2000";
#endregion
#region 13
[Category("机械臂项目13寸轮胎")]
[Description("上料夹紧点")]
[DisplayName("上料夹紧点")]
public string Wheel13GripperUpFasten { get; set; } = "40000";
[Category("机械臂项目13寸轮胎")]
[Description("上料放松点")]
[DisplayName("上料放松点")]
public string Wheel13GripperUpLoosen { get; set; } = "75000";
[Category("机械臂项目13寸轮胎")]
[Description("下料夹紧点")]
[DisplayName("下料夹紧点")]
public string Wheel13GripperDownFasten { get; set; } = "40000";
[Category("机械臂项目13寸轮胎")]
[Description("下料放松点")]
[DisplayName("下料放松点")]
public string Wheel13GripperDownLoosen { get; set; } = "2000";
#endregion
#region 14
[Category("机械臂项目14寸轮胎")]
[Description("上料夹紧点")]
[DisplayName("上料夹紧点")]
public string Wheel14GripperUpFasten { get; set; } = "40000";
[Category("机械臂项目14寸轮胎")]
[Description("上料放松点")]
[DisplayName("上料放松点")]
public string Wheel14GripperUpLoosen { get; set; } = "75000";
[Category("机械臂项目14寸轮胎")]
[Description("下料夹紧点")]
[DisplayName("下料夹紧点")]
public string Wheel14GripperDownFasten { get; set; } = "40000";
[Category("机械臂项目14寸轮胎")]
[Description("下料放松点")]
[DisplayName("下料放松点")]
public string Wheel14GripperDownLoosen { get; set; } = "2000";
#endregion
#region 15
[Category("机械臂项目15寸轮胎")]
[Description("上料夹紧点")]
[DisplayName("上料夹紧点")]
public string Wheel15GripperUpFasten { get; set; } = "40000";
[Category("机械臂项目15寸轮胎")]
[Description("上料放松点")]
[DisplayName("上料放松点")]
public string Wheel15GripperUpLoosen { get; set; } = "75000";
[Category("机械臂项目15寸轮胎")]
[Description("下料夹紧点")]
[DisplayName("下料夹紧点")]
public string Wheel15GripperDownFasten { get; set; } = "40000";
[Category("机械臂项目15寸轮胎")]
[Description("下料放松点")]
[DisplayName("下料放松点")]
public string Wheel15GripperDownLoosen { get; set; } = "2000";
#endregion
#region 16
[Category("机械臂项目16寸轮胎")]
[Description("上料夹紧点")]
[DisplayName("上料夹紧点")]
public string Wheel16GripperUpFasten { get; set; } = "40000";
[Category("机械臂项目16寸轮胎")]
[Description("上料放松点")]
[DisplayName("上料放松点")]
public string Wheel16GripperUpLoosen { get; set; } = "75000";
[Category("机械臂项目16寸轮胎")]
[Description("下料夹紧点")]
[DisplayName("下料夹紧点")]
public string Wheel16GripperDownFasten { get; set; } = "40000";
[Category("机械臂项目16寸轮胎")]
[Description("下料放松点")]
[DisplayName("下料放松点")]
public string Wheel16GripperDownLoosen { get; set; } = "2000";
#endregion
#region 17
[Category("机械臂项目17寸轮胎")]
[Description("上料夹紧点")]
[DisplayName("上料夹紧点")]
public string Wheel17GripperUpFasten { get; set; } = "75000";
[Category("机械臂项目17寸轮胎")]
[Description("上料放松点")]
[DisplayName("上料放松点")]
public string Wheel17GripperUpLoosen { get; set; } = "75000";
[Category("机械臂项目17寸轮胎")]
[Description("下料夹紧点")]
[DisplayName("下料夹紧点")]
public string Wheel17GripperDownFasten { get; set; } = "40000";
[Category("机械臂项目17寸轮胎")]
[Description("下料放松点")]
[DisplayName("下料放松点")]
public string Wheel17GripperDownLoosen { get; set; } = "2000";
#endregion
#region 18
[Category("机械臂项目18寸轮胎")]
[Description("上料夹紧点")]
[DisplayName("上料夹紧点")]
public string Wheel18GripperUpFasten { get; set; } = "75000";
[Category("机械臂项目18寸轮胎")]
[Description("上料放松点")]
[DisplayName("上料放松点")]
public string Wheel18GripperUpLoosen { get; set; } = "75000";
[Category("机械臂项目18寸轮胎")]
[Description("下料夹紧点")]
[DisplayName("下料夹紧点")]
public string Wheel18GripperDownFasten { get; set; } = "40000";
[Category("机械臂项目18寸轮胎")]
[Description("下料放松点")]
[DisplayName("下料放松点")]
public string Wheel18GripperDownLoosen { get; set; } = "2000";
#endregion
[Category("机械臂项目")]
[Description("1号硫化机1号位")]
[DisplayName("1号硫化机1号位")]
[TypeConverter(typeof(ComplexObjectConvert))]
[Editor(typeof(PropertyObjectEditor), typeof(UITypeEditor))]
public RobotPoint X1_1Point { get; set; } = new RobotPoint();
[Category("机械臂项目")]
[Description("1号硫化机2号位")]
[DisplayName("1号硫化机2号位")]
[TypeConverter(typeof(ComplexObjectConvert))]
[Editor(typeof(PropertyObjectEditor), typeof(UITypeEditor))]
public RobotPoint X1_2Point { get; set; } = new RobotPoint();
[Category("机械臂项目")]
[Description("2号硫化机1号位")]
[DisplayName("2号硫化机1号位")]
[TypeConverter(typeof(ComplexObjectConvert))]
[Editor(typeof(PropertyObjectEditor), typeof(UITypeEditor))]
public RobotPoint X2_1Point { get; set; } = new RobotPoint();
[Category("机械臂项目")]
[Description("2号硫化机2号位")]
[DisplayName("2号硫化机2号位")]
[TypeConverter(typeof(ComplexObjectConvert))]
[Editor(typeof(PropertyObjectEditor), typeof(UITypeEditor))]
public RobotPoint X2_2Point { get; set; } = new RobotPoint();
[Category("机械臂项目")]
[Description("硫化轮胎取出位置")]
[DisplayName("硫化轮胎取出位置")]
[TypeConverter(typeof(ComplexObjectConvert))]
[Editor(typeof(PropertyObjectEditor), typeof(UITypeEditor))]
public RobotPoint TakeOutPoint { get; set; } = new RobotPoint();
//[Category("机械臂项目")]
//[Description("路径移动")]
//[DisplayName("路径移动")]
//[TypeConverter(typeof(CollectionCountConvert))]
//[Editor(typeof(ComplexCollectionEditor<RobotPoints>), typeof(UITypeEditor))]
//public List<RobotPoints> RobotMovePoints { get; set; } = new List<RobotPoints>();
//[Category("机械臂项目")]
//[Description("路径返回")]
//[DisplayName("路径返回")]
//[TypeConverter(typeof(CollectionCountConvert))]
//[Editor(typeof(ComplexCollectionEditor<RobotPoints>), typeof(UITypeEditor))]
//public List<RobotPoints> RobotBackPoints { get; set; } = new List<RobotPoints>();
//[Category("驱动类型")]
//[Description("驱动类型")]
//[DisplayName("驱动类型")]
//[TypeConverter(typeof(DeviceTypeSelectorConverter<RobotBase>))]
//public override string DriverType { get; set; }
//[Category("机器人设置")]
//[Description("机器人通信IP")]
//[DisplayName("机器人通信IP")]
//public string RobotIP { get; set; } = "0.0.0.0";
//[Category("机器人设置")]
//[Description("机器人通信端口")]
//[DisplayName("机器人通信端口")]
//public int RobotPort { get; set; }
//[Category("通信设置")]
//[Description("反馈超时设置单位ms")]
//[DisplayName("反馈超时设置单位ms")]
//public int ReplyTimeout { get; set; } = 1000;
//[Category("通信设置")]
//[Description("反馈超时重试次数")]
//[DisplayName("反馈超时重试次数")]
//public int TimeoutRetryTimes { get; set; } = 5;
//[Category("通信设置")]
//[Description("协议文本结束字符")]
//[DisplayName("协议文本结束字符")]
//public string EndChar { get; set; } = "#";
//[Category("通信设置")]
//[Description("协议内容分隔字符")]
//[DisplayName("协议内容分隔字符")]
//public string Seperator { get; set; } = ",";
//[Category("动作设置")]
//[Description("动作超时设置单位min")]
//[DisplayName("动作超时设置单位min")]
//public float OperationTimeout { get; set; } = 1;
//[Category("警报配置")]
//[Description("警报配置列表")]
//[DisplayName("警报配置")]
//[TypeConverter(typeof(CollectionCountConvert))]
//[Editor(typeof(WarningSetsEditor<PLCWarningSet>), typeof(UITypeEditor))]
//public List<IWarningSet> WarningSetCollection { get; set; } = new List<IWarningSet>();
}
public class RobotOperationConfigBase : OperationConfigBase
{
[Category("动作指令")]
[Description("动作指令")]
public RobotMsgAction Action { get; set; } = RobotMsgAction.Move;
[Category("参数")]
[Description("参数1")]
public int Para1 { get; set; } = 0;
[Category("参数")]
[Description("参数2")]
public int Para2 { get; set; } = 0;
[Category("运动配置")]
[Description("机器人运动点位")]
[TypeConverter(typeof(ComplexObjectConvert))]
[Editor(typeof(PropertyObjectEditor), typeof(UITypeEditor))]
public RobotPoint Point { get; set; } = new RobotPoint();
[Category("操作配置")]
[Description("是否等待完成信号")]
public bool IsWaitFinished { get; set; } = true;
}
public class RobotPoints : IComplexDisplay
{
//[Category("运动轴信息配置")]
//[Description("运动轴名称")]
//public string AxisName { get; set; }
//[Category("运动轴信息配置")]
//[Description("运动轴位置信息索引和PLC监听地址配合使用从0开始长度默认为2")]
//public int RegisterIndex { get; set; }
[Category("机械臂坐标")]
[Description("路径移动点x")]
[DisplayName("路径移动点x")]
public double RobotPointX { get; set; }
[Category("机械臂坐标")]
[Description("路径移动点y")]
[DisplayName("路径移动点y")]
public double RobotPointY { get; set; }
[Category("机械臂坐标")]
[Description("路径移动点z")]
[DisplayName("路径移动点z")]
public double RobotPointZ { get; set; }
[Category("机械臂坐标")]
[Description("路径移动点rx")]
[DisplayName("路径移动点rx")]
public double RobotPointRX { get; set; }
[Category("机械臂坐标")]
[Description("路径移动点ry")]
[DisplayName("路径移动点ry")]
public double RobotPointRY { get; set; }
[Category("机械臂坐标")]
[Description("路径移动点rz")]
[DisplayName("路径移动点rz")]
public double RobotPointRZ { get; set; }
public string GetDisplayText()
{
return $"路径移动点组";
}
}
public interface IRobotMsg
{
RobotMsgType Type { get; set; }
int ID { get; set; }
RobotMsgAction Action { get; set; }
byte[] GetMsgBytes(string seperator, string endChar, out string dataStr);
}
public enum RobotMsgType
{
Send = 1,
Rec = 2,
}
//public enum RobotMsgAction
//{
// Move = 1,
// Unload = 2,
// Load = 3,
// GetPosition = 4,
// /// <summary>
// /// 指定当前点位为基准点
// /// </summary>
// BasePoint = 5,
// IOSet = 6,
// Calibration = 9,
// StandardPoint = 10,
//}
public enum RobotMsgAction
{
Move = 1,
Unload = 2,
Load = 3,
GetPosition = 4,
/// <summary>
/// 指定当前点位为基准点
/// </summary>
BasePoint = 5,
IOSet = 6,
IOQuery = 7,
Calibration = 9,
StandardPoint = 10,
SetMinHeight = 12,
}
}

View File

@ -0,0 +1,161 @@
using BRS.Common.Device.Helper;
using BRS.Common.Factory;
using BRS.Common.Interface;
using BRS.Common.Model;
using BRS.Common.Model.Helper;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.IO.Ports;
using System.Linq;
using System.Text;
using System.Threading;
using static BRS.Common.Model.Helper.EnumHelper;
namespace BRS.Common.Base
{
public class SerialPortBase : DeviceBase
{
private object _lock = new object();
/// <summary>
/// 串口对象
/// </summary>
private SerialPort _serialPort = null;
protected SerialPort Port
{
get
{
Init();
return _serialPort;
}
}
public SerialPortInitialConfigBase IConfig
{
get => InitialConfig as SerialPortInitialConfigBase;
}
protected override void Init()
{
if (_serialPort == null)
{
lock (_lock)
{
if (_serialPort == null)
{
_serialPort = new SerialPort(IConfig.Port);
_serialPort.BaudRate = int.Parse(IConfig.BaudRate);
_serialPort.Parity = IConfig.Parity;
_serialPort.DataBits = IConfig.DataBits;
_serialPort.StopBits = IConfig.StopBits;
LogAsync(DateTime.Now, LogLevel.Assist, $"{Name}初始化完成");
}
}
}
}
protected override void Pause()
{
}
protected override void Resume()
{
}
protected override void Start()
{
if (!SerialPortHelper.StartPort(ref _serialPort, out string errorMsg))
{
throw new ProcessException($"{Name}{_serialPort.PortName}开启失败,{errorMsg}");
}
LogAsync(DateTime.Now, LogLevel.Assist, $"{Name}[{Port.PortName}]已打开");
}
protected override void Stop()
{
if (!SerialPortHelper.ClosePort(_serialPort.PortName, out string errorMsg))
{
throw new ProcessException($"{Name}{_serialPort.PortName}关闭失败,{errorMsg}");
}
}
protected int Read(byte[] buffer, int offset, int count)
{
return _serialPort.Read(buffer, offset, count);
}
//protected void Read()
//{
// SerialPortHelper.ReadExisting(_serialPort);
//}
}
public class SerialPortInitialConfigBase : InitialConfigBase
{
[Category("通信设置")]
[DisplayName("串口号")]
[Description("串口号默认为COM1")]
[TypeConverter(typeof(SerialPortConverter))]
public string Port { get; set; } = "COM1";
[Category("通信设置")]
[Description("波特率")]
[DisplayName("波特率")]
[TypeConverter(typeof(BaudRateConverter))]
public string BaudRate { get; set; } = "9600";
[Category("通信设置")]
[Description("奇偶校验位")]
[DisplayName("校验位")]
public Parity Parity { get; set; } = Parity.None;
[Category("通信设置")]
[Description("数据位")]
[DisplayName("数据位")]
public int DataBits { get; set; } = 8;
[Category("通信设置")]
[Description("停止位")]
[DisplayName("停止位")]
public StopBits StopBits { get; set; } = StopBits.One;
[Category("通信设置")]
[Description("读写超时单位ms")]
[DisplayName("读写超时")]
public int Timeout { get; set; } = 0;
[Category("通信设置")]
[Description("读取时等待时间单位ms")]
[DisplayName("读取时等待时间")]
public int ReadWaitTime { get; set; } = 10;
}
[Device("SerialPortOperationConfigBase", "串口设备操作配置基类", EnumHelper.DeviceAttributeType.OperationConfig)]
public class SerialPortOperationConfigBase : OperationConfigBase
{
}
}

View File

@ -0,0 +1,141 @@
using BRS.Common.Model.Helper;
using BRS.Common.Model;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Net;
using System.Net.Sockets;
using System.Text;
using System.Threading.Tasks;
namespace BRS.Common.Base
{
public class TcpClientWrapInitialConfigBase : InitialConfigBase
{
[Category("连接配置")]
[Description("远程IP地址")]
[DisplayName("远程IP")]
public string RemoteIP { get; set; }
[Category("连接配置")]
[Description("远程端口")]
[DisplayName("远程端口")]
public int RemotePort { get; set; }
}
public abstract class TcpClientWrapBase : DeviceBase
{
public TcpClient Client = null;
public NetworkStream Stream = null;
TcpClientWrapInitialConfigBase IConfig
{
get => InitialConfig as TcpClientWrapInitialConfigBase;
}
protected override void Resume()
{
}
protected override void Pause()
{
}
protected override void Init()
{
if (string.IsNullOrWhiteSpace(IConfig.RemoteIP) || IConfig.RemotePort == 0)
{
string errorMsg = $"{Name}客户端未指定远程IP地址或端口";
LogAsync(DateTime.Now, EnumHelper.LogLevel.Warning, errorMsg);
throw new ProcessException(errorMsg);
}
}
protected override void Start()
{
InitialTcpClient(ref Client, ref Stream);
}
protected override void Stop()
{
Stream?.Close();
Client?.Close();
Client = null;
}
private void InitialTcpClient(ref TcpClient client, ref NetworkStream stream)
{
if (client == null || !client.Connected || !client.Client.Connected)
{
client = new TcpClient();
client.NoDelay = true;
client.Client.NoDelay = true;
client.Client.Blocking = true;
client.Connect(IPAddress.Parse(IConfig.RemoteIP), IConfig.RemotePort);
stream = client.GetStream();
}
}
public virtual Task<ResponseMessage> QueryOnce(string queryMsg, bool isReply = false)
{
ResponseMessage msg = new ResponseMessage();
try
{
InitialTcpClient(ref Client, ref Stream);
byte[] sendBuff = System.Text.Encoding.ASCII.GetBytes(queryMsg);
Stream.Write(sendBuff, 0, sendBuff.Length);
}
catch (Exception ex)
{
msg.Result = -1;
msg.Message = ex.Message;
}
if (isReply)
{
if (msg.Result != 1)
{
return Task.Run(() => msg);
}
else
{
return Task.Run(() =>
{
//ResponseMessage readMsg = new ResponseMessage();
try
{
byte[] readBuff = new byte[2048];
int readSize = Stream.Read(readBuff, 0, readBuff.Length);
if (readSize > 0)
{
msg.DataObj = System.Text.Encoding.ASCII.GetString(readBuff.Take(readSize).ToArray());
}
else
{
msg.Result = -1;
msg.Message = "读取长度为0未能获取读取信息";
}
}
catch (Exception ex)
{
msg.Result = -1;
msg.Message = ex.Message;
}
return msg;
});
}
}
else
{
return Task.Run(() => msg);
}
}
}
}

View File

@ -0,0 +1,54 @@
namespace Bro.Common.Base.UI
{
partial class CtrlCameraRunBase
{
/// <summary>
/// 必需的设计器变量。
/// </summary>
private System.ComponentModel.IContainer components = null;
#region
/// <summary>
/// 设计器支持所需的方法 - 不要修改
/// 使用代码编辑器修改此方法的内容。
/// </summary>
private void InitializeComponent()
{
this.components = new System.ComponentModel.Container();
System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(CtrlCameraRunBase));
System.Drawing.Drawing2D.Matrix matrix1 = new System.Drawing.Drawing2D.Matrix();
this.cvImage = new Bro.Common.UI.Canvas();
this.SuspendLayout();
//
// cvImage
//
this.cvImage.Dock = System.Windows.Forms.DockStyle.Fill;
this.cvImage.Font = new System.Drawing.Font("Tahoma", 11F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.World, ((byte)(134)));
this.cvImage.ImageFilePath = null;
this.cvImage.IsShowElementList = false;
this.cvImage.IsShowROITool = false;
this.cvImage.Location = new System.Drawing.Point(0, 0);
this.cvImage.MAP = ((System.Drawing.Bitmap)(resources.GetObject("cvImage.MAP")));
this.cvImage.Matrix = matrix1;
this.cvImage.MouseState = Bro.Common.Helper.EnumHelper.MouseState.Normal;
this.cvImage.Name = "cvImage";
this.cvImage.Size = new System.Drawing.Size(478, 440);
this.cvImage.TabIndex = 0;
//
// CtrlCameraRunBase
//
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 12F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.Controls.Add(this.cvImage);
this.Name = "CtrlCameraRunBase";
this.Size = new System.Drawing.Size(478, 440);
this.ResumeLayout(false);
}
#endregion
private Common.UI.Canvas cvImage;
}
}

View File

@ -0,0 +1,80 @@
using Bro.Common.Interface;
using Bro.Common.UI;
using System.Collections.Generic;
using System.Drawing;
using System.Windows.Forms;
namespace Bro.Common.Base.UI
{
public partial class CtrlCameraRunBase : UserControl, IRunCtrl
{
public CtrlCameraRunBase()
{
InitializeComponent();
}
public IDevice Device { get; set; }
protected CameraBase Camera
{
get => Device as CameraBase;
}
public CtrlCameraRunBase(IDevice device)
{
InitializeComponent();
Device = device;
Camera.OnImageUpdated += Camera_UpdateShowImage;
Camera.OnElementsUpdated += Camera_OnElementsUpdated;
}
private readonly Dictionary<string, List<ElementBase>> _eleBufferDict = new Dictionary<string, List<ElementBase>>();
private volatile string _setId = "";
protected virtual void Camera_OnElementsUpdated(CameraBase camera, List<ElementBase> eleList, string setId)
{
if (cvImage.IsHandleCreated)
{
if (_setId == setId)
{
eleList.ForEach(e => cvImage.Elements.Add(e));
}
else
{
_eleBufferDict[setId] = eleList;
}
}
}
protected virtual void Camera_UpdateShowImage(CameraBase camera, Bitmap image, string setId)
{
_setId = setId;
if (cvImage.IsHandleCreated)
{
cvImage.LoadImage(image);
if (_eleBufferDict.ContainsKey(setId))
{
_eleBufferDict[setId].ForEach(e => cvImage.Elements.Add(e));
_eleBufferDict.Remove(setId);
}
}
}
/// <summary>
/// 清理所有正在使用的资源。
/// </summary>
/// <param name="disposing">如果应释放托管资源,为 true否则为 false。</param>
protected override void Dispose(bool disposing)
{
if (disposing && (components != null))
{
components.Dispose();
}
base.Dispose(disposing);
}
}
}

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,423 @@
using Autofac;
using BRS.Common.Interface;
using BRS.Common.Model;
using BRS.Common.Model.Forms;
using BRS.Common.Model.Helper;
using System;
using System.Collections;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Drawing.Design;
using System.Drawing.Imaging;
using System.Linq;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.Windows.Forms.Design;
using static BRS.Common.Model.Helper.EnumHelper;
namespace BRS.Common.Base
{
/// <summary>
/// 视觉处理引擎1.传统视觉 2.深度学习
/// CV深度学习 四大领域
/// Image Classification 图像分类:判别图中物体是什么,比如是猫还是狗;
/// Semantic Segmentation 语义分割:对图像进行像素级分类,预测每个像素属于的类别,不区分个体;
/// Object Detection 目标检测:寻找图像中的物体并进行定位;
/// Instance Segmentation 实例分割:定位图中每个物体,并进行像素级标注,区分不同个体;
/// </summary>
public abstract class VisionEngineBase : DeviceBase
{
#region event
public event Action<string, Bitmap, List<IShapeElement>> OnDetectionDone;
#endregion
public VisionEngineInitialConfigBase IConfig
{
get => InitialConfig as VisionEngineInitialConfigBase;
}
public ImageSaveHelper ImageSaveHelper { get; set; } = new ImageSaveHelper();
public string BatchNO { get; set; }
public abstract Task<DetectStationResult> RunInferenceAsync(IImageSet originImgSet, string detectionId = null);
public abstract DetectStationResult RunInference(IImageSet originImgSet, string detectionId = null);
public abstract void OFFLineRunInference(List<OFFLineDetectSet> offLineDetectSets);
public virtual void DetectionDone(string detectionId, Bitmap image, List<IShapeElement> detectionResults)
{
OnDetectionDone?.Invoke(detectionId, image, detectionResults);
}
public virtual void SaveImageAsync(string fullname, Bitmap saveMap, ImageFormat imageFormat)
{
if (saveMap != null)
{
ImageSaveSet imageSaveSet = new ImageSaveSet()
{
FullName = fullname,
SaveImage = saveMap.CopyBitmap(),
//ImageFormat = imageFormat.DeepSerializeClone()
};
ImageSaveHelper.ImageSaveAsync(imageSaveSet);
}
}
}
public class VisionEngineInitialConfigBase : InitialConfigBase
{
[Category("视觉检测配置")]
[DisplayName("检测配置集合")]
[Description("检测配置集合")]
[TypeConverter(typeof(CollectionCountConvert))]
[Editor(typeof(ComplexCollectionEditor<DetectionConfig>), typeof(UITypeEditor))]
public List<DetectionConfig> DetectionConfigs { get; set; } = new List<DetectionConfig>();
[Category("视觉检测配置")]
[Description("检测图片 保存文件夹")]
[DisplayName("检测图片保存文件夹")]
[Editor(typeof(FoldDialogEditor), typeof(UITypeEditor))]
// [Editor(typeof(FileDialogEditor), typeof(UITypeEditor))]
public string ImageSaveDirectory { get; set; } = "D:\\PROJECTS\\A020\\Images";
[Category("视觉检测配置")]
[DisplayName("是否保存检测图片")]
[Description("是否保存 检测图片,总开关")]
public bool IsSaveImage { get; set; } = true;
}
/// <summary>
/// 检测项配置
/// </summary>
public class DetectionConfig : IComplexDisplay
{
[ReadOnly(true)]
public string Id { get; set; } = Guid.NewGuid().ToString();
[Category("检测配置")]
[DisplayName("检测配置名称")]
[Description("检测配置名称")]
public string Name { get; set; }
/// <summary>
/// 推理设备包括CPU GPU VPU
/// </summary>
[Category("检测配置")]
[DisplayName("推理设备")]
[Description("选择推理设备。")]
[TypeConverter(typeof(EnumDescriptionConverter<DetectionDeviceTypeDef>))]
public DetectionDeviceTypeDef DetectionDeviceType { get; set; }
//[Category("检测配置")]
//[DisplayName("设备名称")]
//[Description("选择检测设备包括GPU、CPU等")]
//public string DetectionDeviceType { get; set; } = "CPU";
[Category("检测配置")]
[DisplayName("预热图片路径配置")]
[Description("预热图片路径配置")]
[Editor(typeof(FileDialogEditor), typeof(UITypeEditor))]
public string PreheatImagePath { get; set; }
[Category("原始图片保存设置")]
[Description("视觉检测 图片保存配置")]
[DisplayName("图片保存配置")]
[TypeConverter(typeof(ComplexObjectConvert))]
[Editor(typeof(PropertyObjectEditor), typeof(UITypeEditor))]
public virtual VisionImageSaveOption ImageSaveOption { get; set; } = new VisionImageSaveOption();
[Category("深度学习检测配置")]
[DisplayName("目标检测-模型路径")]
[Description("目标检测-配置文件路径onnx")]
[Editor(typeof(FileDialogEditor), typeof(UITypeEditor))]
public string MLModelPath { get; set; }
[Category("深度学习检测配置")]
[DisplayName("目标检测-标签路径")]
[Description("目标检测-配置标签路径TEXT")]
[Editor(typeof(FileDialogEditor), typeof(UITypeEditor))]
public string MLLablePath { get; set; }
[Category("深度学习检测配置")]
[DisplayName("检测置信度")]
[Description("配置模型置信度")]
public float confThreshold { get; set; } = 0.3f;
[Category("深度学习检测配置")]
[DisplayName("检测IOU")]
[Description("配置IOU")]
public float iouThreshold { get; set; } = 0.4f;
//[Category("深度学习检测配置")]
//[DisplayName("目标检测-启动GPU")]
//[Description("目标检测-启动GPU")]
//public bool bGPU { get; set; } = false;
//[Category("深度学习检测配置")]
//[DisplayName("是否保存检测图片")]
//[Description("是否保存 检测图片,总开关")]
//public bool IsSaveImage { get; set; } = true;
//[Category("深度学习检测配置")]
//[Description("检测图片 保存文件夹")]
//[DisplayName("检测图片保存文件夹")]
//[Editor(typeof(FileDialogEditor), typeof(UITypeEditor))]
//public string ImageSaveDirectory { get; set; } = "D:\\PROJECTS\\A020\\Images\\Result\\";
[Category("深度学习检测配置")]
[DisplayName("是否启用该检测")]
[Description("是否启用该检测")]
public bool IsEnabled { get; set; }
//[Category("图像参数设置")]
//[DisplayName("图片重采样大小")]
//[Description("模型适配图片重采样大小")]
//public int ImageResizeCount { get; set; } = 640;
[Category("模型架构参数配置")]
[DisplayName("输入节点名称")]
[Description("输入节点名称")]
public string in_node_name { get; set; } = "images";
[Category("模型架构参数配置")]
[DisplayName("输出节点名称")]
[Description("输出节点名称")]
public string out_node_name { get; set; } = "output";
// ========================================
//[Category("图像参数设置")]
//[DisplayName("原始图像大小")]
//[Description("模型适配图片重采样大小")]
//public int ImageSize { get; set; } = 640;
// ========================================
[Category("推理参数设置")]
[DisplayName("图片通道数")]
[Description("图片通道数")]
public ulong ImageChannels { get; set; } = 3;
// batch
//[ReadOnly(true)]
//[Category("推理参数设置")]
//[DisplayName("图片通道数")]
//[Description("原始图片通道")]
//public ulong ImageBatchNum { get; set; } = 1;
[Category("推理参数设置")]
[DisplayName("推理图片宽度")]
[Description("推理图片宽度,单位:像素")]
public ulong ImageWidth { get; set; } = 640;
[Category("推理参数设置")]
[DisplayName("推理图片高度")]
[Description("推理图片高度,单位:像素")]
public ulong ImageHeight { get; set; } = 640;
// ========================================
//[Category("图像预处理检测配置")]
//[DisplayName("是否启用该检测")]
//[Description("是否启用该检测")]
//public bool preIsEnabled { get; set; }
//[Category("图像预处理检测配置")]
//[DisplayName("是否加载模型")]
//[Description("是否启用该模型")]
//public bool IspreLoadModel{ get; set; }
//[Category("图像预处理检测配置")]
//[Description("预处理加载模型算法配置")]
//[DisplayName("预处理加载模型文件配置")]
//[Editor(typeof(FileDialogEditor), typeof(UITypeEditor))]
//public string preProcessLMFilePath { get; set; } = "D:\\PROJECTS\\A020\\Model\\Pre\\";
//[Category("图像预处理检测配置")]
//[Description("预处理算法路径配置")]
//[DisplayName("预处理算法文件配置")]
//[Editor(typeof(FileDialogEditor), typeof(UITypeEditor))]
//public string preProcessFilePath { get; set; } = "D:\\PROJECTS\\A020\\Model\\Pre\\";
[Category("关联相机")]
[DisplayName("关联相机")]
[Description("关联相机描述")]
[TypeConverter(typeof(DeviceIdSelectorConverter<CameraBase>))]
public string CameraSourceId { get; set; } = "";
[Category("显示配置")]
[DisplayName("显示检测图片及信息")]
[Description("true检测图片/信息显示在运行界面false不显示检测图片/信息")]
public bool IsShowInUI { get; set; } = true;
[Category("显示配置")]
[DisplayName("显示位置")]
[Description("检测信息显示位置。左上角为11向右向下为正方向")]
[TypeConverter(typeof(ComplexObjectConvert))]
[Editor(typeof(PropertyObjectEditor), typeof(UITypeEditor))]
public CustomizedPoint ShowLocation { get; set; } = new CustomizedPoint();
[Category("显示配置")]
[DisplayName("图片所占布局的列数")]
[Description("图片所占布局的列数")]
public int ColumnSpan { get; set; } = 1;
[Category("显示配置")]
[DisplayName("图片所占布局的行数")]
[Description("图片所占布局的行数")]
public int RowSpan { get; set; } = 1;
public string GetDisplayText()
{
return $"{(IsEnabled ? "" : " ")}-{Name}";
}
public void SetImageSaveDirectory()
{
using (var scope = GlobalVar.Container.BeginLifetimeScope())
{
IProcessConfig config = scope.Resolve<IProcessConfig>();
var mlBase = config.DeviceConfigs.FirstOrDefault(u => u is VisionEngineInitialConfigBase);
if (mlBase != null)
{
var iConfig = mlBase as VisionEngineInitialConfigBase;
ImageSaveOption.ImageSaveDirectory = iConfig.ImageSaveDirectory;
ImageSaveOption.IsEnabled = iConfig.IsSaveImage;
}
}
}
}
public class VisionEngineOperationConfigBase : OperationConfigBase
{
//[Category("图像来源")]
//[DisplayName("是否离线图片")]
//[Description("true离线图片 false在线采图")]
//public bool IsImageOffline { get; set; } = false;
[Browsable(false)]
public bool IsBatchOffline { get; set; } = false;
[Browsable(false)]
public string BatchOfflineImgDirectory { get; set; }
[Category("采图操作")]
[DisplayName("采图相机")]
[Description("采图使用的相机")]
[TypeConverter(typeof(DeviceIdSelectorConverter<CameraBase>))]
public string CameraSourceId { get; set; }
[Category("采图操作")]
[DisplayName("相机操作配置")]
[Description("采图相机操作配置")]
[TypeConverter(typeof(ComplexObjectConvert))]
[Editor(typeof(VisionSnapOpConfigEditor), typeof(UITypeEditor))]
public IOperationConfig CameraOpConfig { get; set; }
[Category("保存设置")]
[DisplayName("检测图片 附加配置")]
[Description("检测图片 附加配置")]
[TypeConverter(typeof(ComplexObjectConvert))]
[Editor(typeof(PropertyObjectEditor), typeof(UITypeEditor))]
public VisionImageSaveOption ImageSaveOption { get; set; } = new VisionImageSaveOption();
}
public class OFFLineDetectSet
{
public List<IImageSet> ImageSetList { get; set; }
public string DetectionConfigId { get; set; }
}
public class VisionSnapOpConfigEditor : UITypeEditor
{
public override UITypeEditorEditStyle GetEditStyle(System.ComponentModel.ITypeDescriptorContext context)
{
return UITypeEditorEditStyle.Modal;
}
public override object EditValue(ITypeDescriptorContext context, IServiceProvider provider, object value)
{
IWindowsFormsEditorService edSvc = (IWindowsFormsEditorService)provider.GetService(typeof(IWindowsFormsEditorService));
if (edSvc != null)
{
VisionEngineOperationConfigBase mlOpConfig = context.Instance as VisionEngineOperationConfigBase;
FrmDeviceOpConfigEditor frmDeviceOpEditor = new FrmDeviceOpConfigEditor(new DeviceOpBind() { Device = mlOpConfig.CameraSourceId, OpConfig = value as IOperationConfig }, "")
{
StartPosition = FormStartPosition.CenterScreen
};
frmDeviceOpEditor.ShowDialog();
return frmDeviceOpEditor.Bind.OpConfig;
}
return base.EditValue(context, provider, value);
}
}
}

View File

@ -0,0 +1,186 @@
using ArxOne.MrAdvice.Advice;
using BRS.Common.Base;
using Newtonsoft.Json;
using System;
namespace BRS.Common.Model.Helper
{
public static class JsonHelper
{
public static JsonSerializerSettings JsonSetWithType = new JsonSerializerSettings() { TypeNameHandling = TypeNameHandling.All };
}
#region PostSharp AOP related
/// <summary>
/// 工序设备运行 环切面 用于修饰DeviceBase的SetAndRun
/// </summary>
public class DeviceRunAroundAspect : Attribute, IMethodAdvice
{
public void Advise(MethodAdviceContext context)
{
// do things you want here(before)
OnEntry(context);
// this calls the original method(now)
context.Proceed();
// do other things here(after)
OnSuccess(context);
}
/// <summary>
/// 设备操作前
/// </summary>
/// <param name="args"></param>
public void OnEntry(MethodAdviceContext args)
{
#region
DeviceBase device = args.Target as DeviceBase;
if (device.CurrentState != EnumHelper.DeviceState.DSOpen)
{
throw new ProcessException($"{device.Name}不在开启状态,无法操作!");
}
#endregion
#region
device.LogAsync(DateTime.Now, EnumHelper.LogLevel.Assist, $"{device.Name}开始{args.TargetMethod.Name}");
#endregion
}
/// <summary>
/// 设备完成操作后
/// </summary>
/// <param name="args"></param>
public void OnSuccess(MethodAdviceContext args)
{
DeviceBase device = args.Target as DeviceBase;
#region
device.LogAsync(DateTime.Now, EnumHelper.LogLevel.Assist, $"{device.Name}完成{args.TargetMethod.Name}");
#endregion
}
}
/// <summary>
/// 设备异常捕获 切面
/// </summary>
public class DeviceExceptionAspect : Attribute, IMethodAdvice
{
public void Advise(MethodAdviceContext context)
{
try
{
context.Proceed();
}
catch (Exception ex)
{
OnException(context, ex);
}
}
public void OnException(MethodAdviceContext args, Exception exception)
{
DeviceBase device = args.Target as DeviceBase;
if (device.CurrentState != EnumHelper.DeviceState.DSExcept)
{
device.CurrentState = EnumHelper.DeviceState.DSExcept;
device.CurrentStateToBe = EnumHelper.DeviceState.DSExcept;
#region
device.OnExceptionOccured?.Invoke(DateTime.Now, exception);
#endregion
#region
device.LogAsync(DateTime.Now, EnumHelper.LogLevel.Warning, $"{device.Name} {args.TargetMethod.Name}异常信息{exception.GetExceptionMessage()}");
#endregion
}
throw exception;
}
}
/// <summary>
/// 方法开始前捕获 切面
/// </summary>
public class DeviceOnEntryAspect : Attribute, IMethodAdvice
{
public void Advise(MethodAdviceContext context)
{
OnEntry(context);
context.Proceed();
}
/// <summary>
/// 设备操作前
/// </summary>
/// <param name="args"></param>
public void OnEntry(MethodAdviceContext args)
{
#region
DeviceBase device = args.Target as DeviceBase;
if (device.CurrentState != EnumHelper.DeviceState.DSOpen)
{
throw new ProcessException($"{device.Name}不在开启状态,无法操作!");
}
#endregion
#region
device.LogAsync(DateTime.Now, EnumHelper.LogLevel.Assist, $"{device.Name}开始{args.TargetMethod.Name}");
#endregion
}
}
/// <summary>
/// 方法结束后捕获 切面
/// </summary>
public class DeviceOnSuccessAspect : Attribute, IMethodAdvice
{
public void Advise(MethodAdviceContext context)
{
context.Proceed();
OnSuccess(context);
}
/// <summary>
/// 设备完成操作后
/// </summary>
/// <param name="args"></param>
public void OnSuccess(MethodAdviceContext args)
{
DeviceBase device = args.Target as DeviceBase;
#region
device.LogAsync(DateTime.Now, EnumHelper.LogLevel.Assist, $"{device.Name}完成{args.TargetMethod.Name}");
#endregion
}
}
/// <summary>
/// 流程异常捕获切面
/// </summary>
public class ProcessExceptionAspect : Attribute, IMethodAdvice
{
public void Advise(MethodAdviceContext context)
{
try
{
context.Proceed();
}
catch (Exception ex)
{
OnException(context, ex);
}
}
public void OnException(MethodAdviceContext args, Exception exception)
{
//Exception ex = exception;
//if (!(ex is ProcessException))
//{
// new ProcessException(ex);
//}
throw exception;
}
}
#endregion
}

View File

@ -0,0 +1,131 @@
using System;
using System.Collections.Generic;
using System.IO.Ports;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
namespace BRS.Common.Device.Helper
{
/// <summary>
/// 串口助手,管理项目中用到的所有串口设备
/// </summary>
public static class SerialPortHelper
{
/// <summary>
/// 静态对象,存储当前软件中用到的所有串口端口
/// </summary>
public static List<SerialPort> UsingPorts { get; set; } = new List<SerialPort>();
static object _spLock = new object();
static Dictionary<string, object> _opLock = new Dictionary<string, object>();
/// <summary>
/// 打开串口
/// </summary>
/// <param name="port"></param>
/// <param name="errorMsg"></param>
/// <returns></returns>
public static bool StartPort(ref SerialPort port, out string errorMsg)
{
errorMsg = "";
try
{
lock (_spLock)
{
string portName = port.PortName;
SerialPort usingPort = UsingPorts.FirstOrDefault(u => u.PortName == portName);
if (usingPort == null)
{
usingPort = port;
UsingPorts.Add(usingPort);
_opLock[portName] = new object();
}
if (!usingPort.IsOpen)
{
usingPort.Open();
}
port = usingPort;
return true;
}
}
catch (Exception ex)
{
errorMsg = ex.Message;
}
return false;
}
public static bool ClosePort(string portName, out string errorMsg)
{
errorMsg = "";
try
{
lock (_spLock)
{
SerialPort usingPort = UsingPorts.FirstOrDefault(u => u.PortName == portName);
if (usingPort != null && usingPort.IsOpen)
{
usingPort.Close();
UsingPorts.RemoveAll(u => u.PortName == portName);
}
return true;
}
}
catch (Exception ex)
{
errorMsg = ex.Message;
}
return false;
}
public static bool Write(SerialPort port, byte[] data, int startAddress, int length, int waitTime = 50)
{
try
{
lock (_opLock[port.PortName])
{
port.Write(data, startAddress, length);
if (waitTime > 0)
{
//Task.Delay(waitTime);
Thread.Sleep(waitTime);
}
return true;
}
}
catch
{
return false;
}
}
public static string ReadExisting(SerialPort port)
{
try
{
lock (_opLock[port.PortName])
{
return port.ReadExisting();
}
}
catch
{
return "";
}
}
}
}

View File

@ -0,0 +1,50 @@
using BRS.Common.Model.Helper;
using BRS.Common.Interface;
using BRS.Common.Model;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace BRS.Common.Base
{
/// <summary>
/// 运动机构接口 具体由PLC/板卡实现
/// </summary>
public interface IMotion
{
List<AxisInfo> GetCurrentAxisInfo(params string[] axisName);
/// <summary>
/// 运动机构点到点移动
/// </summary>
/// <param name="opConfig">运动配置</param>
/// <returns>true正常结束 false异常结束</returns>
ResponseMessage MoveToPoint(IOperationConfig opConfig);
}
/// <summary>
/// 板卡接口
/// </summary>
public interface IMotionCard : IMotion
{
/// <summary>
/// 板卡执行动作 除了运动动作外还包含IO操作
/// </summary>
/// <param name="config"></param>
/// <returns></returns>
ResponseMessage Run(IOperationConfig config);
}
public class AxisInfo : IComplexDisplay
{
public string AxisName { get; set; }
public double AxisLocation { get; set; }
public string GetDisplayText()
{
return $"{AxisName}:{AxisLocation}";
}
}
}

Some files were not shown because too many files have changed in this diff Show More