添加项目文件。
This commit is contained in:
parent
1db01eda58
commit
157613603c
230
A020.sln
Normal file
230
A020.sln
Normal 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
|
BIN
libs/HikCamera/MvCameraControl.Net.dll
Normal file
BIN
libs/HikCamera/MvCameraControl.Net.dll
Normal file
Binary file not shown.
BIN
libs/HslCommunication.dll
Normal file
BIN
libs/HslCommunication.dll
Normal file
Binary file not shown.
BIN
libs/IKAPCamera/IKapC.NET.dll
Normal file
BIN
libs/IKAPCamera/IKapC.NET.dll
Normal file
Binary file not shown.
39
libs/M014_hdvp/LoadModel.hdvp
Normal file
39
libs/M014_hdvp/LoadModel.hdvp
Normal 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>
|
77
libs/M014_hdvp/MatchResult.hdvp
Normal file
77
libs/M014_hdvp/MatchResult.hdvp
Normal 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
BIN
libs/NBVision/AVL_Lite.dll
Normal file
Binary file not shown.
BIN
libs/NBVision/NBVisionKit.dll
Normal file
BIN
libs/NBVision/NBVisionKit.dll
Normal file
Binary file not shown.
BIN
libs/NBVision/NBddraw.dll
Normal file
BIN
libs/NBVision/NBddraw.dll
Normal file
Binary file not shown.
BIN
libs/NBVision/dog_windows_x64_3150389.dll
Normal file
BIN
libs/NBVision/dog_windows_x64_3150389.dll
Normal file
Binary file not shown.
BIN
libs/NBVision/libglog.dll
Normal file
BIN
libs/NBVision/libglog.dll
Normal file
Binary file not shown.
BIN
libs/NBVision/opencv_world440.dll
Normal file
BIN
libs/NBVision/opencv_world440.dll
Normal file
Binary file not shown.
BIN
libs/NBVision/pthreadGC2.dll
Normal file
BIN
libs/NBVision/pthreadGC2.dll
Normal file
Binary file not shown.
BIN
libs/NBVision/pthreadVC2.dll
Normal file
BIN
libs/NBVision/pthreadVC2.dll
Normal file
Binary file not shown.
BIN
libs/NBVision/ws2_32.dll
Normal file
BIN
libs/NBVision/ws2_32.dll
Normal file
Binary file not shown.
BIN
libs/SRLib/32bit/SR7Link.dll
Normal file
BIN
libs/SRLib/32bit/SR7Link.dll
Normal file
Binary file not shown.
510
libs/SRLib/32bit/SR7Link.h
Normal file
510
libs/SRLib/32bit/SR7Link.h
Normal 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
|
||||||
|
|
BIN
libs/SRLib/32bit/SR7Link.lib
Normal file
BIN
libs/SRLib/32bit/SR7Link.lib
Normal file
Binary file not shown.
BIN
libs/SRLib/64bit/SR7Link.dll
Normal file
BIN
libs/SRLib/64bit/SR7Link.dll
Normal file
Binary file not shown.
510
libs/SRLib/64bit/SR7Link.h
Normal file
510
libs/SRLib/64bit/SR7Link.h
Normal 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
|
||||||
|
|
BIN
libs/SRLib/64bit/SR7Link.lib
Normal file
BIN
libs/SRLib/64bit/SR7Link.lib
Normal file
Binary file not shown.
BIN
libs/SafetyDog/api_dsp_windows.dll
Normal file
BIN
libs/SafetyDog/api_dsp_windows.dll
Normal file
Binary file not shown.
BIN
libs/SafetyDog/api_dsp_windows_x64.dll
Normal file
BIN
libs/SafetyDog/api_dsp_windows_x64.dll
Normal file
Binary file not shown.
BIN
libs/SafetyDog/dog_net_windows.dll
Normal file
BIN
libs/SafetyDog/dog_net_windows.dll
Normal file
Binary file not shown.
BIN
libs/SafetyDog/dog_windows_3153818.dll
Normal file
BIN
libs/SafetyDog/dog_windows_3153818.dll
Normal file
Binary file not shown.
BIN
libs/SafetyDog/dog_windows_x64_3153818.dll
Normal file
BIN
libs/SafetyDog/dog_windows_x64_3153818.dll
Normal file
Binary file not shown.
BIN
libs/SmartRay/PocoFoundation64.dll
Normal file
BIN
libs/SmartRay/PocoFoundation64.dll
Normal file
Binary file not shown.
BIN
libs/SmartRay/SRAPI_CSharp-x64.dll
Normal file
BIN
libs/SmartRay/SRAPI_CSharp-x64.dll
Normal file
Binary file not shown.
BIN
libs/SmartRay/SR_API-x64.dll
Normal file
BIN
libs/SmartRay/SR_API-x64.dll
Normal file
Binary file not shown.
BIN
libs/SmartRay/gio-2-vs10.dll
Normal file
BIN
libs/SmartRay/gio-2-vs10.dll
Normal file
Binary file not shown.
BIN
libs/SmartRay/glib-2-vs10.dll
Normal file
BIN
libs/SmartRay/glib-2-vs10.dll
Normal file
Binary file not shown.
BIN
libs/SmartRay/gmodule-2-vs10.dll
Normal file
BIN
libs/SmartRay/gmodule-2-vs10.dll
Normal file
Binary file not shown.
BIN
libs/SmartRay/gobject-2-vs10.dll
Normal file
BIN
libs/SmartRay/gobject-2-vs10.dll
Normal file
Binary file not shown.
BIN
libs/SmartRay/gthread-2-vs10.dll
Normal file
BIN
libs/SmartRay/gthread-2-vs10.dll
Normal file
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
BIN
libs/UI/DockPanel/Net4/WeifenLuo.WinFormsUI.Docking.dll
Normal file
BIN
libs/UI/DockPanel/Net4/WeifenLuo.WinFormsUI.Docking.dll
Normal file
Binary file not shown.
@ -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": ""
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
Binary file not shown.
@ -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": ""
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
Binary file not shown.
@ -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": ""
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
Binary file not shown.
@ -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": ""
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
Binary file not shown.
@ -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": ""
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
Binary file not shown.
@ -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/DockPanel/Net6/WeifenLuo.WinFormsUI.Docking.dll
Normal file
BIN
libs/UI/DockPanel/Net6/WeifenLuo.WinFormsUI.Docking.dll
Normal file
Binary file not shown.
BIN
libs/UI/HZH_Controls.dll
Normal file
BIN
libs/UI/HZH_Controls.dll
Normal file
Binary file not shown.
BIN
libs/WPFSmartLibraryLight35.dll
Normal file
BIN
libs/WPFSmartLibraryLight35.dll
Normal file
Binary file not shown.
BIN
libs/gocator/GoSdkNet.dll
Normal file
BIN
libs/gocator/GoSdkNet.dll
Normal file
Binary file not shown.
BIN
libs/gocator/bk/GoSdk.dll
Normal file
BIN
libs/gocator/bk/GoSdk.dll
Normal file
Binary file not shown.
BIN
libs/gocator/bk/GoSdkNet.dll
Normal file
BIN
libs/gocator/bk/GoSdkNet.dll
Normal file
Binary file not shown.
BIN
libs/gocator/bk/kApi.dll
Normal file
BIN
libs/gocator/bk/kApi.dll
Normal file
Binary file not shown.
BIN
libs/gocator/bk/kApiNet.dll
Normal file
BIN
libs/gocator/bk/kApiNet.dll
Normal file
Binary file not shown.
BIN
libs/gocator/bk/msvcp120.dll
Normal file
BIN
libs/gocator/bk/msvcp120.dll
Normal file
Binary file not shown.
BIN
libs/gocator/bk/msvcr120.dll
Normal file
BIN
libs/gocator/bk/msvcr120.dll
Normal file
Binary file not shown.
BIN
libs/gocator/kApiNet.dll
Normal file
BIN
libs/gocator/kApiNet.dll
Normal file
Binary file not shown.
BIN
libs/halcon12/halcondotnet.dll
Normal file
BIN
libs/halcon12/halcondotnet.dll
Normal file
Binary file not shown.
BIN
libs/halcon12/hdevenginedotnet.dll
Normal file
BIN
libs/halcon12/hdevenginedotnet.dll
Normal file
Binary file not shown.
BIN
libs/halcon20/halcondotnet.dll
Normal file
BIN
libs/halcon20/halcondotnet.dll
Normal file
Binary file not shown.
BIN
libs/halcon20/hdevenginedotnet.dll
Normal file
BIN
libs/halcon20/hdevenginedotnet.dll
Normal file
Binary file not shown.
206
src/BRS.Common.Device/BRS.Common.Device.csproj
Normal file
206
src/BRS.Common.Device/BRS.Common.Device.csproj
Normal 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>
|
401
src/BRS.Common.Device/Base/DeviceBase.cs
Normal file
401
src/BRS.Common.Device/Base/DeviceBase.cs
Normal 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
|
||||||
|
}
|
||||||
|
}
|
85
src/BRS.Common.Device/Base/DeviceConfigBase.cs
Normal file
85
src/BRS.Common.Device/Base/DeviceConfigBase.cs
Normal 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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
190
src/BRS.Common.Device/Base/InputConfigBase.cs
Normal file
190
src/BRS.Common.Device/Base/InputConfigBase.cs
Normal 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; }
|
||||||
|
}
|
||||||
|
}
|
85
src/BRS.Common.Device/Base/OperationConfigBase.cs
Normal file
85
src/BRS.Common.Device/Base/OperationConfigBase.cs
Normal 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; }
|
||||||
|
}
|
||||||
|
}
|
39
src/BRS.Common.Device/Base/ProcessBase.cs
Normal file
39
src/BRS.Common.Device/Base/ProcessBase.cs
Normal 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();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -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()}";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
353
src/BRS.Common.Device/Calibration/CalibrationDynamic9PointFrm.Designer.cs
generated
Normal file
353
src/BRS.Common.Device/Calibration/CalibrationDynamic9PointFrm.Designer.cs
generated
Normal 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;
|
||||||
|
}
|
||||||
|
}
|
403
src/BRS.Common.Device/Calibration/CalibrationDynamic9PointFrm.cs
Normal file
403
src/BRS.Common.Device/Calibration/CalibrationDynamic9PointFrm.cs
Normal 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;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -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>
|
@ -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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
234
src/BRS.Common.Device/Calibration/CalibrationStatic9PointFrm.Designer.cs
generated
Normal file
234
src/BRS.Common.Device/Calibration/CalibrationStatic9PointFrm.Designer.cs
generated
Normal 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;
|
||||||
|
}
|
||||||
|
}
|
393
src/BRS.Common.Device/Calibration/CalibrationStatic9PointFrm.cs
Normal file
393
src/BRS.Common.Device/Calibration/CalibrationStatic9PointFrm.cs
Normal 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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -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>
|
277
src/BRS.Common.Device/DeviceBase/AGVBase.cs
Normal file
277
src/BRS.Common.Device/DeviceBase/AGVBase.cs
Normal 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,
|
||||||
|
}
|
||||||
|
}
|
641
src/BRS.Common.Device/DeviceBase/CameraBase.cs
Normal file
641
src/BRS.Common.Device/DeviceBase/CameraBase.cs
Normal 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
|
||||||
|
}
|
18
src/BRS.Common.Device/DeviceBase/ForceSensorBase.cs
Normal file
18
src/BRS.Common.Device/DeviceBase/ForceSensorBase.cs
Normal 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();
|
||||||
|
}
|
||||||
|
}
|
244
src/BRS.Common.Device/DeviceBase/IODeviceBase.cs
Normal file
244
src/BRS.Common.Device/DeviceBase/IODeviceBase.cs
Normal 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
|
||||||
|
}
|
||||||
|
}
|
31
src/BRS.Common.Device/DeviceBase/MessageQueueBase.cs
Normal file
31
src/BRS.Common.Device/DeviceBase/MessageQueueBase.cs
Normal 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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
232
src/BRS.Common.Device/DeviceBase/ModbusASCIICommBase.cs
Normal file
232
src/BRS.Common.Device/DeviceBase/ModbusASCIICommBase.cs
Normal 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);
|
||||||
|
// }
|
||||||
|
//}
|
||||||
|
|
||||||
|
}
|
619
src/BRS.Common.Device/DeviceBase/MotionCardBase.cs
Normal file
619
src/BRS.Common.Device/DeviceBase/MotionCardBase.cs
Normal 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
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
545
src/BRS.Common.Device/DeviceBase/PLCBase.cs
Normal file
545
src/BRS.Common.Device/DeviceBase/PLCBase.cs
Normal 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
|
||||||
|
}
|
57
src/BRS.Common.Device/DeviceBase/RS-232CommBase.cs
Normal file
57
src/BRS.Common.Device/DeviceBase/RS-232CommBase.cs
Normal 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);
|
||||||
|
// }
|
||||||
|
//}
|
||||||
|
|
||||||
|
}
|
843
src/BRS.Common.Device/DeviceBase/RobotBase.cs
Normal file
843
src/BRS.Common.Device/DeviceBase/RobotBase.cs
Normal 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,
|
||||||
|
}
|
||||||
|
}
|
161
src/BRS.Common.Device/DeviceBase/SerialPortBase.cs
Normal file
161
src/BRS.Common.Device/DeviceBase/SerialPortBase.cs
Normal 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
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
}
|
141
src/BRS.Common.Device/DeviceBase/TcpCommBase.cs
Normal file
141
src/BRS.Common.Device/DeviceBase/TcpCommBase.cs
Normal 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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
54
src/BRS.Common.Device/DeviceBase/UI/CtrlCameraRunBase.Designer.cs
generated
Normal file
54
src/BRS.Common.Device/DeviceBase/UI/CtrlCameraRunBase.Designer.cs
generated
Normal 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;
|
||||||
|
}
|
||||||
|
}
|
80
src/BRS.Common.Device/DeviceBase/UI/CtrlCameraRunBase.cs
Normal file
80
src/BRS.Common.Device/DeviceBase/UI/CtrlCameraRunBase.cs
Normal 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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
6598
src/BRS.Common.Device/DeviceBase/UI/CtrlCameraRunBase.resx
Normal file
6598
src/BRS.Common.Device/DeviceBase/UI/CtrlCameraRunBase.resx
Normal file
File diff suppressed because it is too large
Load Diff
423
src/BRS.Common.Device/DeviceBase/VisionEngineBase.cs
Normal file
423
src/BRS.Common.Device/DeviceBase/VisionEngineBase.cs
Normal 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("检测信息显示位置。左上角为(1,1),向右向下为正方向")]
|
||||||
|
[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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
186
src/BRS.Common.Device/Helper/AspectHelper.cs
Normal file
186
src/BRS.Common.Device/Helper/AspectHelper.cs
Normal 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
|
||||||
|
}
|
131
src/BRS.Common.Device/Helper/SerialPortHelper.cs
Normal file
131
src/BRS.Common.Device/Helper/SerialPortHelper.cs
Normal 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 "";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
50
src/BRS.Common.Device/Interface/IMotion.cs
Normal file
50
src/BRS.Common.Device/Interface/IMotion.cs
Normal 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
Loading…
Reference in New Issue
Block a user