添加 MX-PD-盘古 项目文件
将 MX-PD-盘古 - new 目录下的所有文件添加到主仓库
This commit is contained in:
246
MX-PD-盘古 - new/PanGu.DieBonderApp/.editorconfig
Normal file
246
MX-PD-盘古 - new/PanGu.DieBonderApp/.editorconfig
Normal file
@@ -0,0 +1,246 @@
|
||||
# 如果要从更高级别的目录继承 .editorconfig 设置,请删除以下行
|
||||
root = true
|
||||
|
||||
# c# 文件
|
||||
[*.cs]
|
||||
|
||||
#### Core EditorConfig 选项 ####
|
||||
|
||||
# 缩进和间距
|
||||
indent_size = 4
|
||||
indent_style = space
|
||||
tab_width = 4
|
||||
|
||||
# 新行首选项
|
||||
end_of_line = crlf
|
||||
insert_final_newline = false
|
||||
|
||||
#### .NET 代码操作 ####
|
||||
|
||||
# 类型成员
|
||||
dotnet_hide_advanced_members = false
|
||||
dotnet_member_insertion_location = with_other_members_of_the_same_kind
|
||||
dotnet_property_generation_behavior = prefer_throwing_properties
|
||||
|
||||
# 符号搜索
|
||||
dotnet_search_reference_assemblies = true
|
||||
|
||||
#### .NET 编码约定 ####
|
||||
|
||||
# 组织 Using
|
||||
dotnet_separate_import_directive_groups = false
|
||||
dotnet_sort_system_directives_first = false
|
||||
file_header_template = unset
|
||||
|
||||
# this. 和 Me. 首选项
|
||||
dotnet_style_qualification_for_event = false
|
||||
dotnet_style_qualification_for_field = false
|
||||
dotnet_style_qualification_for_method = false
|
||||
dotnet_style_qualification_for_property = false
|
||||
|
||||
# 语言关键字与 bcl 类型首选项
|
||||
dotnet_style_predefined_type_for_locals_parameters_members = true
|
||||
dotnet_style_predefined_type_for_member_access = true
|
||||
|
||||
# 括号首选项
|
||||
dotnet_style_parentheses_in_arithmetic_binary_operators = always_for_clarity
|
||||
dotnet_style_parentheses_in_other_binary_operators = always_for_clarity
|
||||
dotnet_style_parentheses_in_other_operators = never_if_unnecessary
|
||||
dotnet_style_parentheses_in_relational_binary_operators = always_for_clarity
|
||||
|
||||
# 修饰符首选项
|
||||
dotnet_style_require_accessibility_modifiers = for_non_interface_members
|
||||
|
||||
# 表达式级首选项
|
||||
dotnet_prefer_system_hash_code = true
|
||||
dotnet_style_coalesce_expression = true
|
||||
dotnet_style_collection_initializer = true
|
||||
dotnet_style_explicit_tuple_names = true
|
||||
dotnet_style_namespace_match_folder = true
|
||||
dotnet_style_null_propagation = true
|
||||
dotnet_style_object_initializer = true
|
||||
dotnet_style_operator_placement_when_wrapping = beginning_of_line
|
||||
dotnet_style_prefer_auto_properties = true
|
||||
dotnet_style_prefer_collection_expression = when_types_loosely_match
|
||||
dotnet_style_prefer_compound_assignment = true
|
||||
dotnet_style_prefer_conditional_expression_over_assignment = true
|
||||
dotnet_style_prefer_conditional_expression_over_return = true
|
||||
dotnet_style_prefer_foreach_explicit_cast_in_source = when_strongly_typed
|
||||
dotnet_style_prefer_inferred_anonymous_type_member_names = true
|
||||
dotnet_style_prefer_inferred_tuple_names = true
|
||||
dotnet_style_prefer_is_null_check_over_reference_equality_method = true
|
||||
dotnet_style_prefer_simplified_boolean_expressions = true
|
||||
dotnet_style_prefer_simplified_interpolation = true
|
||||
|
||||
# 字段首选项
|
||||
dotnet_style_readonly_field = true
|
||||
|
||||
# 参数首选项
|
||||
dotnet_code_quality_unused_parameters = all
|
||||
|
||||
# 禁止显示首选项
|
||||
dotnet_remove_unnecessary_suppression_exclusions = none
|
||||
|
||||
# 新行首选项
|
||||
dotnet_style_allow_multiple_blank_lines_experimental = true
|
||||
dotnet_style_allow_statement_immediately_after_block_experimental = true
|
||||
|
||||
#### c# 编码约定 ####
|
||||
|
||||
# var 首选项
|
||||
csharp_style_var_elsewhere = false
|
||||
csharp_style_var_for_built_in_types = false
|
||||
csharp_style_var_when_type_is_apparent = false
|
||||
|
||||
# Expression-bodied 成员
|
||||
csharp_style_expression_bodied_accessors = true
|
||||
csharp_style_expression_bodied_constructors = false
|
||||
csharp_style_expression_bodied_indexers = true
|
||||
csharp_style_expression_bodied_lambdas = true
|
||||
csharp_style_expression_bodied_local_functions = false
|
||||
csharp_style_expression_bodied_methods = false
|
||||
csharp_style_expression_bodied_operators = false
|
||||
csharp_style_expression_bodied_properties = true
|
||||
|
||||
# 模式匹配首选项
|
||||
csharp_style_pattern_matching_over_as_with_null_check = true
|
||||
csharp_style_pattern_matching_over_is_with_cast_check = true
|
||||
csharp_style_prefer_extended_property_pattern = true
|
||||
csharp_style_prefer_not_pattern = true
|
||||
csharp_style_prefer_pattern_matching = true
|
||||
csharp_style_prefer_switch_expression = true
|
||||
|
||||
# Null 检查首选项
|
||||
csharp_style_conditional_delegate_call = true
|
||||
|
||||
# 修饰符首选项
|
||||
csharp_prefer_static_anonymous_function = true
|
||||
csharp_prefer_static_local_function = true
|
||||
csharp_preferred_modifier_order = public,private,protected,internal,file,static,extern,new,virtual,abstract,sealed,override,readonly,unsafe,required,volatile,async
|
||||
csharp_style_prefer_readonly_struct = true
|
||||
csharp_style_prefer_readonly_struct_member = true
|
||||
|
||||
# 代码块首选项
|
||||
csharp_prefer_braces = true
|
||||
csharp_prefer_simple_using_statement = true
|
||||
csharp_prefer_system_threading_lock = true
|
||||
csharp_style_namespace_declarations = block_scoped
|
||||
csharp_style_prefer_method_group_conversion = true
|
||||
csharp_style_prefer_primary_constructors = true
|
||||
csharp_style_prefer_top_level_statements = true
|
||||
|
||||
# 表达式级首选项
|
||||
csharp_prefer_simple_default_expression = true
|
||||
csharp_style_deconstructed_variable_declaration = true
|
||||
csharp_style_implicit_object_creation_when_type_is_apparent = true
|
||||
csharp_style_inlined_variable_declaration = true
|
||||
csharp_style_prefer_implicitly_typed_lambda_expression = true
|
||||
csharp_style_prefer_index_operator = true
|
||||
csharp_style_prefer_local_over_anonymous_function = true
|
||||
csharp_style_prefer_null_check_over_type_check = true
|
||||
csharp_style_prefer_range_operator = true
|
||||
csharp_style_prefer_tuple_swap = true
|
||||
csharp_style_prefer_unbound_generic_type_in_nameof = true
|
||||
csharp_style_prefer_utf8_string_literals = true
|
||||
csharp_style_throw_expression = true
|
||||
csharp_style_unused_value_assignment_preference = discard_variable
|
||||
csharp_style_unused_value_expression_statement_preference = discard_variable
|
||||
|
||||
# "using" 指令首选项
|
||||
csharp_using_directive_placement = outside_namespace
|
||||
|
||||
# 新行首选项
|
||||
csharp_style_allow_blank_line_after_colon_in_constructor_initializer_experimental = true
|
||||
csharp_style_allow_blank_line_after_token_in_arrow_expression_clause_experimental = true
|
||||
csharp_style_allow_blank_line_after_token_in_conditional_expression_experimental = true
|
||||
csharp_style_allow_blank_lines_between_consecutive_braces_experimental = true
|
||||
csharp_style_allow_embedded_statements_on_same_line_experimental = true
|
||||
|
||||
#### C# 格式规则 ####
|
||||
|
||||
# 新行首选项
|
||||
csharp_new_line_before_catch = true
|
||||
csharp_new_line_before_else = true
|
||||
csharp_new_line_before_finally = true
|
||||
csharp_new_line_before_members_in_anonymous_types = true
|
||||
csharp_new_line_before_members_in_object_initializers = true
|
||||
csharp_new_line_before_open_brace = all
|
||||
csharp_new_line_between_query_expression_clauses = true
|
||||
|
||||
# 缩进首选项
|
||||
csharp_indent_block_contents = true
|
||||
csharp_indent_braces = false
|
||||
csharp_indent_case_contents = true
|
||||
csharp_indent_case_contents_when_block = true
|
||||
csharp_indent_labels = one_less_than_current
|
||||
csharp_indent_switch_labels = true
|
||||
|
||||
# 空格键首选项
|
||||
csharp_space_after_cast = false
|
||||
csharp_space_after_colon_in_inheritance_clause = true
|
||||
csharp_space_after_comma = true
|
||||
csharp_space_after_dot = false
|
||||
csharp_space_after_keywords_in_control_flow_statements = true
|
||||
csharp_space_after_semicolon_in_for_statement = true
|
||||
csharp_space_around_binary_operators = before_and_after
|
||||
csharp_space_around_declaration_statements = false
|
||||
csharp_space_before_colon_in_inheritance_clause = true
|
||||
csharp_space_before_comma = false
|
||||
csharp_space_before_dot = false
|
||||
csharp_space_before_open_square_brackets = false
|
||||
csharp_space_before_semicolon_in_for_statement = false
|
||||
csharp_space_between_empty_square_brackets = false
|
||||
csharp_space_between_method_call_empty_parameter_list_parentheses = false
|
||||
csharp_space_between_method_call_name_and_opening_parenthesis = false
|
||||
csharp_space_between_method_call_parameter_list_parentheses = false
|
||||
csharp_space_between_method_declaration_empty_parameter_list_parentheses = false
|
||||
csharp_space_between_method_declaration_name_and_open_parenthesis = false
|
||||
csharp_space_between_method_declaration_parameter_list_parentheses = false
|
||||
csharp_space_between_parentheses = false
|
||||
csharp_space_between_square_brackets = false
|
||||
|
||||
# 包装首选项
|
||||
csharp_preserve_single_line_blocks = true
|
||||
csharp_preserve_single_line_statements = true
|
||||
|
||||
#### 命名样式 ####
|
||||
|
||||
# 命名规则
|
||||
|
||||
dotnet_naming_rule.interface_should_be_begins_with_i.severity = suggestion
|
||||
dotnet_naming_rule.interface_should_be_begins_with_i.symbols = interface
|
||||
dotnet_naming_rule.interface_should_be_begins_with_i.style = begins_with_i
|
||||
|
||||
dotnet_naming_rule.types_should_be_pascal_case.severity = suggestion
|
||||
dotnet_naming_rule.types_should_be_pascal_case.symbols = types
|
||||
dotnet_naming_rule.types_should_be_pascal_case.style = pascal_case
|
||||
|
||||
dotnet_naming_rule.non_field_members_should_be_pascal_case.severity = suggestion
|
||||
dotnet_naming_rule.non_field_members_should_be_pascal_case.symbols = non_field_members
|
||||
dotnet_naming_rule.non_field_members_should_be_pascal_case.style = pascal_case
|
||||
|
||||
# 符号规范
|
||||
|
||||
dotnet_naming_symbols.interface.applicable_kinds = interface
|
||||
dotnet_naming_symbols.interface.applicable_accessibilities = public, internal, private, protected, protected_internal, private_protected
|
||||
dotnet_naming_symbols.interface.required_modifiers =
|
||||
|
||||
dotnet_naming_symbols.types.applicable_kinds = class, struct, interface, enum
|
||||
dotnet_naming_symbols.types.applicable_accessibilities = public, internal, private, protected, protected_internal, private_protected
|
||||
dotnet_naming_symbols.types.required_modifiers =
|
||||
|
||||
dotnet_naming_symbols.non_field_members.applicable_kinds = property, event, method
|
||||
dotnet_naming_symbols.non_field_members.applicable_accessibilities = public, internal, private, protected, protected_internal, private_protected
|
||||
dotnet_naming_symbols.non_field_members.required_modifiers =
|
||||
|
||||
# 命名样式
|
||||
|
||||
dotnet_naming_style.pascal_case.required_prefix =
|
||||
dotnet_naming_style.pascal_case.required_suffix =
|
||||
dotnet_naming_style.pascal_case.word_separator =
|
||||
dotnet_naming_style.pascal_case.capitalization = pascal_case
|
||||
|
||||
dotnet_naming_style.begins_with_i.required_prefix = I
|
||||
dotnet_naming_style.begins_with_i.required_suffix =
|
||||
dotnet_naming_style.begins_with_i.word_separator =
|
||||
dotnet_naming_style.begins_with_i.capitalization = pascal_case
|
||||
106
MX-PD-盘古 - new/PanGu.DieBonderApp/.github/instructions/csharp-base.instructions.md
vendored
Normal file
106
MX-PD-盘古 - new/PanGu.DieBonderApp/.github/instructions/csharp-base.instructions.md
vendored
Normal file
@@ -0,0 +1,106 @@
|
||||
---
|
||||
applyTo: "**/*.cs"
|
||||
---
|
||||
|
||||
# C# Base Instructions
|
||||
|
||||
## Language Version Constraint
|
||||
This repository targets .NET Framework 4.8 and C# 7.3.
|
||||
|
||||
Do not use:
|
||||
- record
|
||||
- init property setters
|
||||
- switch expressions
|
||||
- using declarations
|
||||
- top-level statements
|
||||
- nullable reference types
|
||||
- range operators (`..`)
|
||||
- default interface implementations
|
||||
- IAsyncEnumerable<T>
|
||||
|
||||
Allowed:
|
||||
- async/await
|
||||
- pattern matching with is / switch case patterns
|
||||
- tuples
|
||||
- local functions
|
||||
- inline out variable declarations
|
||||
- throw expressions
|
||||
- ref locals and ref returns
|
||||
|
||||
## <20><><EFBFBD><EFBFBD>˵<EFBFBD><CBB5>
|
||||
<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ĿĿ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ϊ .NET Framework 4.8<EFBFBD><EFBFBD>C# <20>汾<EFBFBD>̶<EFBFBD>Ϊ 7.3<EFBFBD><EFBFBD>
|
||||
<EFBFBD><EFBFBD><EFBFBD>ˣ<EFBFBD>
|
||||
- <20><>ֹʹ<D6B9><CAB9> record<72><64>init<69><74>switch <20><><EFBFBD><EFBFBD>ʽ<EFBFBD><CABD>using <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ɿ<EFBFBD><C9BF><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>͵<EFBFBD> C# 8+ <20><><EFBFBD><EFBFBD>
|
||||
- <20><><EFBFBD><EFBFBD>ʹ<EFBFBD><CAB9> async/await<69><74>Ԫ<EFBFBD>顢<EFBFBD><E9A1A2><EFBFBD>غ<EFBFBD><D8BA><EFBFBD><EFBFBD><EFBFBD>ģʽƥ<CABD>䡢<EFBFBD><E4A1A2><EFBFBD><EFBFBD> out <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> C# 7.3 ֧<>ֵĹ<D6B5><C4B9><EFBFBD>
|
||||
|
||||
## Style Rules
|
||||
- Use explicit types, not `var`
|
||||
- Use Allman braces
|
||||
- Use 4 spaces indentation
|
||||
- Use CRLF line endings
|
||||
- Use block-scoped namespaces
|
||||
- Place using directives outside namespaces
|
||||
|
||||
## <20><><EFBFBD><EFBFBD>˵<EFBFBD><CBB5>
|
||||
<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ҫ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||
- <20><>ʽ<EFBFBD><CABD><EFBFBD>ͣ<EFBFBD><CDA3><EFBFBD>ʹ<EFBFBD><CAB9> `var`
|
||||
- ʹ<><CAB9> Allman <20><><EFBFBD><EFBFBD><EFBFBD>ŷ<EFBFBD><C5B7><EFBFBD>
|
||||
- 4 <20>ո<EFBFBD><D5B8><EFBFBD><EFBFBD><EFBFBD>
|
||||
- ʹ<><CAB9> CRLF <20><><EFBFBD><EFBFBD>
|
||||
- ʹ<>ÿ<EFBFBD><C3BF><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ռ<EFBFBD>
|
||||
- using <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ռ<EFBFBD><D5BC><EFBFBD>
|
||||
|
||||
## Naming Rules
|
||||
- Public types, methods, properties, events: PascalCase
|
||||
- Private fields: _camelCase
|
||||
- Constants: PascalCase
|
||||
- Interfaces: I + PascalCase
|
||||
- Enums: PascalCase
|
||||
|
||||
## <20><><EFBFBD><EFBFBD>˵<EFBFBD><CBB5>
|
||||
<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>淶<EFBFBD><EFBFBD>
|
||||
- <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>͡<EFBFBD><CDA1><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ԡ<EFBFBD><D4A1>¼<EFBFBD><C2BC><EFBFBD>PascalCase
|
||||
- ˽<><CBBD><EFBFBD>ֶΣ<D6B6>`_camelCase`
|
||||
- <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>PascalCase
|
||||
- <20>ӿڣ<D3BF>`I` + PascalCase
|
||||
- ö<>٣<EFBFBD>PascalCase
|
||||
|
||||
## Constructor Injection
|
||||
Prefer constructor injection with null checks.
|
||||
|
||||
Example:
|
||||
```csharp
|
||||
public SafeAxisMotion(HardwareManager hardware, AlarmOperate alarmOperate)
|
||||
{
|
||||
_hardware = hardware ?? throw new ArgumentNullException(nameof(hardware));
|
||||
_alarmOperate = alarmOperate ?? throw new ArgumentNullException(nameof(alarmOperate));
|
||||
}
|
||||
```
|
||||
|
||||
## <20><><EFBFBD><EFBFBD>˵<EFBFBD><CBB5>
|
||||
<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ע<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʹ<EFBFBD>ù<EFBFBD><EFBFBD>캯<EFBFBD><EFBFBD>ע<EFBFBD>룬<EFBFBD><EFBFBD><EFBFBD>Բ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> null <20><><EFBFBD>顣
|
||||
<EFBFBD><EFBFBD>Ҫʡ<EFBFBD><EFBFBD> null <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||
|
||||
## Async Rules
|
||||
Async methods must use Async suffix
|
||||
Pass CancellationToken where appropriate
|
||||
Do not block async code with .Result or .Wait() unless existing architecture requires it and the reason is explicit
|
||||
|
||||
## <20><><EFBFBD><EFBFBD>˵<EFBFBD><CBB5>
|
||||
<EFBFBD>첽<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||
- <20>첽<EFBFBD><ECB2BD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> Async <20><>
|
||||
- <20><>Ҫ֧<D2AA><D6A7>ȡ<EFBFBD><C8A1><EFBFBD>ij<EFBFBD><C4B3><EFBFBD><EFBFBD><EFBFBD><EFBFBD>봫 CancellationToken
|
||||
- <20><>Ҫ<EFBFBD><D2AA><EFBFBD><EFBFBD>ʹ<EFBFBD><CAB9> .Result <20><> .Wait() <20><><EFBFBD><EFBFBD><EFBFBD>첽<EFBFBD><ECB2BD><EFBFBD>ã<EFBFBD><C3A3><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>мܹ<D0BC><DCB9><EFBFBD>ȷҪ<C8B7><D2AA><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||
|
||||
## Code Generation Preference
|
||||
Keep methods focused and readable
|
||||
Prefer explicit domain terminology over generic names
|
||||
Avoid unnecessary abstractions
|
||||
Match the existing repository style
|
||||
|
||||
## <20><><EFBFBD><EFBFBD>˵<EFBFBD><CBB5>
|
||||
<EFBFBD><EFBFBD><EFBFBD>ɴ<EFBFBD><EFBFBD><EFBFBD>ʱ<EFBFBD><EFBFBD>
|
||||
- <20><><EFBFBD>ַ<EFBFBD><D6B7><EFBFBD>ְ<EFBFBD><D6B0><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||
- <20><><EFBFBD><EFBFBD>ʹ<EFBFBD><CAB9><EFBFBD><EFBFBD>ȷ<EFBFBD><C8B7><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||
- <20><><EFBFBD>ⲻ<EFBFBD><E2B2BB>Ҫ<EFBFBD>ij<EFBFBD><C4B3><EFBFBD>
|
||||
- <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>вֿ<D0B2><D6BF><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||
68
MX-PD-盘古 - new/PanGu.DieBonderApp/.github/instructions/hardware-io.instructions.md
vendored
Normal file
68
MX-PD-盘古 - new/PanGu.DieBonderApp/.github/instructions/hardware-io.instructions.md
vendored
Normal file
@@ -0,0 +1,68 @@
|
||||
---
|
||||
applyTo: "MainShell/Hardware/**/*.cs,MainShell/DeviceMaintance/**/*.cs,MainShell/Manual/**/*.cs,MainShell/ToolBox/**/*.cs"
|
||||
---
|
||||
|
||||
# Hardware and IO Instructions
|
||||
|
||||
## Hardware Access Rules
|
||||
- Reuse HardwareManager as the primary hardware entry point
|
||||
- Do not invent parallel hardware access layers unless explicitly requested
|
||||
- Keep hardware naming and organization consistent with existing project patterns
|
||||
|
||||
## <20><><EFBFBD><EFBFBD>˵<EFBFBD><CBB5>
|
||||
Ӳ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʹ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||
- ͳһͨ<D2BB><CDA8> `HardwareManager` <20><>Ϊ<EFBFBD><CEAA>ҪӲ<D2AA><D3B2><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||
- <20><>Ҫƽ<D2AA><C6BD><EFBFBD>½<EFBFBD><C2BD><EFBFBD>һ<EFBFBD><D2BB>Ӳ<EFBFBD><D3B2><EFBFBD><EFBFBD><EFBFBD>ʲ<EFBFBD>
|
||||
- Ӳ<><D3B2><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>֯<EFBFBD><D6AF>ʽ<EFBFBD><CABD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ŀһ<C4BF><D2BB>
|
||||
|
||||
## Axis Naming Rules
|
||||
All axis names should be defined as constants in the existing axis naming class.
|
||||
|
||||
Naming pattern:
|
||||
- Axis_ prefix
|
||||
- Examples:
|
||||
- Axis_SZ
|
||||
- Axis_PHS_X1
|
||||
- Axis_WS_X3
|
||||
- Axis_Stage_Y3
|
||||
|
||||
If a new axis is introduced, define a constant in the existing axis name holder.
|
||||
|
||||
## <20><><EFBFBD><EFBFBD>˵<EFBFBD><CBB5>
|
||||
<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||
- <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ӧ<EFBFBD><D3A6><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ϊ<EFBFBD><CEAA><EFBFBD><EFBFBD>
|
||||
- <20><><EFBFBD><EFBFBD>ͳһʹ<D2BB><CAB9> `Axis_` ǰ
|
||||
- <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ᣬ<EFBFBD><E1A3AC><EFBFBD>벹<EFBFBD>䳣<EFBFBD><E4B3A3><EFBFBD><EFBFBD><EFBFBD>壬<EFBFBD><E5A3AC>Ҫ<EFBFBD><D2AA>ҵ<EFBFBD><D2B5><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ӳ<EFBFBD><D3B2><EFBFBD><EFBFBD><EFBFBD>ַ<EFBFBD><D6B7><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||
|
||||
## IO Rules
|
||||
- IO point definitions are loaded from CSV configuration
|
||||
- Reuse DeviceIoPointDefinition and existing IO grouping structures
|
||||
- Preserve support for simulated IO states if relevant
|
||||
- Keep IO service/model/event naming device-oriented
|
||||
|
||||
Use:
|
||||
- DeviceIoMonitorService
|
||||
- DeviceIoSnapshot
|
||||
- DeviceCylinderService
|
||||
|
||||
Avoid logistics-specific names unless the domain explicitly requires them:
|
||||
- ConveyorIoService
|
||||
- LoaderIoMonitor
|
||||
|
||||
## <20><><EFBFBD><EFBFBD>˵<EFBFBD><CBB5>
|
||||
IO <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||
- IO <20>㶨<EFBFBD><E3B6A8>ͨ<EFBFBD><CDA8> CSV <20><><EFBFBD>ü<EFBFBD><C3BC><EFBFBD>
|
||||
- <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> `DeviceIoPointDefinition` <20><> IO <20><><EFBFBD><EFBFBD><EFBFBD>ṹ
|
||||
- <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ģ<EFBFBD><C4A3> IO ״̬<D7B4><CCAC><EFBFBD>ƣ<EFBFBD>Ӧ<EFBFBD><D3A6><EFBFBD>ּ<EFBFBD><D6BC><EFBFBD>
|
||||
- IO <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ҫ<EFBFBD><D2AA><EFBFBD><EFBFBD><EFBFBD>豸<EFBFBD><E8B1B8><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ҫʹ<D2AA>ù<EFBFBD><C3B9><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ҵ<EFBFBD><D2B5><EFBFBD><EFBFBD>ȷ<EFBFBD><C8B7>Ҫ
|
||||
|
||||
## Safety Preference
|
||||
- Validate device state before critical actions
|
||||
- Do not assume hardware is ready
|
||||
- Keep generated code conservative and traceable
|
||||
|
||||
## <20><><EFBFBD><EFBFBD>˵<EFBFBD><CBB5>
|
||||
<EFBFBD><EFBFBD>ȫԭ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||
- <20>ؼ<EFBFBD><D8BC>豸<EFBFBD><E8B1B8><EFBFBD><EFBFBD>ǰ<EFBFBD><C7B0>У<EFBFBD><D0A3><EFBFBD>豸״̬
|
||||
- <20><>ҪĬ<D2AA><C4AC>Ӳ<EFBFBD><D3B2><EFBFBD>Ѿ<EFBFBD> ready
|
||||
- <20><><EFBFBD>ɴ<EFBFBD><C9B4><EFBFBD>ʱҪƫ<D2AA><C6AB><EFBFBD>ء<EFBFBD><D8A1><EFBFBD><EFBFBD><D7B7>
|
||||
161
MX-PD-盘古 - new/PanGu.DieBonderApp/.github/instructions/localization-popup.instructions.md
vendored
Normal file
161
MX-PD-盘古 - new/PanGu.DieBonderApp/.github/instructions/localization-popup.instructions.md
vendored
Normal file
@@ -0,0 +1,161 @@
|
||||
---
|
||||
applyTo: "MainShell/Common/**/*.cs,**/*ViewModel.cs,**/*Service.cs,**/*Process*.cs"
|
||||
---
|
||||
|
||||
# Localization and Popup Instructions
|
||||
|
||||
## Scope
|
||||
These rules apply to internal program message dialogs only.
|
||||
|
||||
Do not apply these rules to:
|
||||
- database alarms
|
||||
- PLC alarm chain
|
||||
- device alarm chain
|
||||
- AlarmAsync main alarm path
|
||||
|
||||
## <20><><EFBFBD><EFBFBD>˵<EFBFBD><CBB5>
|
||||
<EFBFBD><EFBFBD>Щ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>**<2A><><EFBFBD><EFBFBD><EFBFBD>ڲ<EFBFBD><DAB2><EFBFBD>ʾ<EFBFBD><CABE><EFBFBD><EFBFBD>**<2A><>
|
||||
<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ڣ<EFBFBD>
|
||||
- <20><><EFBFBD>ݿⱨ<DDBF><E2B1A8>
|
||||
- PLC <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>·
|
||||
- <20>豸<EFBFBD><E8B1B8><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>·
|
||||
- `AlarmAsync()` <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>·
|
||||
|
||||
## Required Popup Pattern
|
||||
For internal prompts:
|
||||
1. define MessageKey enum value in `MainShell/Common/MessageKey.cs`
|
||||
2. add mapping in `LanguageResourceHelper.ResourceKeyMap`
|
||||
3. add Chinese resource in `MainShell/Language/MXJM_CN.xaml`
|
||||
4. add English resource in `MainShell/Language/MXJM_EN.xaml`
|
||||
5. call `LocalizedMessageBox.Show()` or `LocalizedMessageBox.ShowFormat()`
|
||||
|
||||
## <20><><EFBFBD><EFBFBD>˵<EFBFBD><CBB5>
|
||||
<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʾ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>̣<EFBFBD>
|
||||
1. <20><> `MessageKey.cs` <20>ж<EFBFBD><D0B6><EFBFBD>ö<EFBFBD><C3B6>
|
||||
2. <20><> `LanguageResourceHelper.ResourceKeyMap` <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ӳ<EFBFBD><D3B3>
|
||||
3. <20><> `MXJM_CN.xaml` <20>в<EFBFBD><D0B2><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Դ
|
||||
4. <20><> `MXJM_EN.xaml` <20>в<EFBFBD>Ӣ<EFBFBD><D3A2><EFBFBD><EFBFBD>Դ
|
||||
5. ҵ<><D2B5><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ͳһ<CDB3><D2BB><EFBFBD><EFBFBD> `LocalizedMessageBox.Show()` <20><> `ShowFormat()`
|
||||
|
||||
## Required Title Keys
|
||||
Use:
|
||||
- MessageKey.TitleInfo
|
||||
- MessageKey.TitleWarning
|
||||
- MessageKey.TitleError
|
||||
- MessageKey.TitleConfirm
|
||||
|
||||
## <20><><EFBFBD><EFBFBD>˵<EFBFBD><CBB5>
|
||||
<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ͳһʹ<EFBFBD>ã<EFBFBD>
|
||||
- `MessageKey.TitleInfo`
|
||||
- `MessageKey.TitleWarning`
|
||||
- `MessageKey.TitleError`
|
||||
- `MessageKey.TitleConfirm`
|
||||
|
||||
## Formatting Rules
|
||||
- For parameterized messages, use `ShowFormat()`
|
||||
- Resource text should use placeholders such as `{0}`, `{1}`
|
||||
|
||||
## <20><><EFBFBD><EFBFBD>˵<EFBFBD><CBB5>
|
||||
<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʾ<EFBFBD>İ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʹ<EFBFBD><EFBFBD> `ShowFormat()`<EFBFBD><EFBFBD><EFBFBD><EFBFBD>Դ<EFBFBD>ı<EFBFBD>ʹ<EFBFBD><EFBFBD> `{0}`<EFBFBD><EFBFBD>`{1}` ռλ<D5BC><CEBB><EFBFBD><EFBFBD>
|
||||
|
||||
## Forbidden Patterns
|
||||
Do not generate:
|
||||
- `MwMessageBox.Show("<22><><EFBFBD><EFBFBD>")`
|
||||
- `MessageBox.Show("<22><><EFBFBD><EFBFBD>")`
|
||||
- `LocalizedMessageBox.Show("resourceKeyString")`
|
||||
- direct resource dictionary access for popup text
|
||||
|
||||
## <20><><EFBFBD><EFBFBD>˵<EFBFBD><CBB5>
|
||||
<EFBFBD><EFBFBD>ֹ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>д<EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||
- `MwMessageBox.Show("<22><><EFBFBD><EFBFBD>")`
|
||||
- `MessageBox.Show("<22><><EFBFBD><EFBFBD>")`
|
||||
- `LocalizedMessageBox.Show("<22><>Դkey<65>ַ<EFBFBD><D6B7><EFBFBD>")`
|
||||
- ֱ<>ӷ<EFBFBD><D3B7><EFBFBD><EFBFBD><EFBFBD>Դ<EFBFBD>ֵ<EFBFBD><D6B5><EFBFBD>ȡ<EFBFBD><C8A1><EFBFBD><EFBFBD><EFBFBD>İ<EFBFBD>
|
||||
|
||||
## Migration Rule
|
||||
When modifying old internal prompt code, prefer migrating old MessageBox/MwMessageBox usage to LocalizedMessageBox and update:
|
||||
- MessageKey enum
|
||||
- ResourceKeyMap
|
||||
- Chinese resource
|
||||
- English resource
|
||||
- business code call site
|
||||
|
||||
## <20><><EFBFBD><EFBFBD>˵<EFBFBD><CBB5>
|
||||
Ǩ<EFBFBD>ƾɴ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>еij<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʾʱ<EFBFBD><EFBFBD>Ӧ<EFBFBD><EFBFBD><EFBFBD>ȸ<EFBFBD>Ϊ `LocalizedMessageBox` <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ͬ<EFBFBD><CDAC><EFBFBD><EFBFBD><EFBFBD>룺
|
||||
- MessageKey ö<><C3B6>
|
||||
- ResourceKeyMap ӳ<><D3B3>
|
||||
- <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Դ
|
||||
- Ӣ<><D3A2><EFBFBD><EFBFBD>Դ
|
||||
- ҵ<><D2B5><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>õ<EFBFBD>
|
||||
|
||||
## Workflow / Process Error and Message Localization
|
||||
Error messages, status messages, and user-facing messages generated in:
|
||||
- Service layer (Service/*Service.cs)
|
||||
- Activity layer (MainShell/Process/Activity/*.cs)
|
||||
- ProcessService implementations
|
||||
|
||||
Must follow the same localization requirements as popup dialogs:
|
||||
1. Define MessageKey enum values for all error/status messages
|
||||
2. Register in LanguageResourceHelper.ResourceKeyMap
|
||||
3. Add translations in MXJM_CN.xaml and MXJM_EN.xaml
|
||||
4. Pass MessageKey enum (not raw strings) in WorkflowContext or result objects
|
||||
5. Display messages using LocalizedMessageBox from ViewModel/View layer
|
||||
|
||||
Do not hardcode error messages or status strings in Service/Activity code.
|
||||
|
||||
## <20><><EFBFBD><EFBFBD>˵<EFBFBD><CBB5>
|
||||
<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>λ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ɵĴ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ϣ<EFBFBD><EFBFBD>״̬<EFBFBD><EFBFBD>ʾ<EFBFBD><EFBFBD><EFBFBD>û<EFBFBD><EFBFBD><EFBFBD>ʾ<EFBFBD><EFBFBD>
|
||||
- Service <20>㣨Service/*Service.cs<63><73>
|
||||
- Activity <20>㣨MainShell/Process/Activity/*.cs<63><73>
|
||||
- ProcessService ʵ<><CAB5>
|
||||
|
||||
<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ѭ<EFBFBD>뵯<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ͬ<EFBFBD>ı<EFBFBD><EFBFBD>ػ<EFBFBD><EFBFBD>淶<EFBFBD><EFBFBD>
|
||||
1. <20><> MessageKey <20>ж<EFBFBD><D0B6><EFBFBD><EFBFBD><EFBFBD><EFBFBD>д<EFBFBD><D0B4><EFBFBD>/״̬<D7B4><CCAC>Ϣ<EFBFBD><CFA2>ö<EFBFBD><C3B6>ֵ
|
||||
2. <20><> LanguageResourceHelper.ResourceKeyMap <20><>ע<EFBFBD><D7A2>
|
||||
3. <20><> MXJM_CN.xaml <20><> MXJM_EN.xaml <20><><EFBFBD><EFBFBD><EFBFBD>Ӷ<EFBFBD>Ӧ<EFBFBD><D3A6><EFBFBD><EFBFBD>
|
||||
4. <20><> WorkflowContext <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>д<EFBFBD><D0B4><EFBFBD> MessageKey ö<><C3B6>ֵ<EFBFBD><D6B5><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ԭʼ<D4AD>ַ<EFBFBD><D6B7><EFBFBD><EFBFBD><EFBFBD>
|
||||
5. <20><> ViewModel/View <20><>ʹ<EFBFBD><CAB9> LocalizedMessageBox <20><>ʾ<EFBFBD><CABE>Ϣ
|
||||
|
||||
<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> Service/Activity <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ӳ<EFBFBD><D3B2><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ϣ<EFBFBD><CFA2>״̬<D7B4>ַ<EFBFBD><D6B7><EFBFBD><EFBFBD><EFBFBD>
|
||||
|
||||
## Example: Adding Workflow Error Message
|
||||
For a new workflow error in a Service:
|
||||
|
||||
1. Define in `MessageKey.cs`:
|
||||
```csharp
|
||||
ProcessError_InvalidToolId,
|
||||
ProcessError_HardwareTimeout,
|
||||
```
|
||||
|
||||
2. Add to `LanguageResourceHelper.ResourceKeyMap`:
|
||||
```csharp
|
||||
{ MessageKey.ProcessError_InvalidToolId,
|
||||
"MXJM:ProcessError_InvalidToolId" },
|
||||
{ MessageKey.ProcessError_HardwareTimeout,
|
||||
"MXJM:ProcessError_HardwareTimeout" },
|
||||
```
|
||||
|
||||
3. In result object, return the message key:
|
||||
```csharp
|
||||
public MessageKey? ErrorMessageKey { get; set; }
|
||||
```
|
||||
|
||||
4. In Activity's AfterExecute or ViewModel, check and display:
|
||||
```csharp
|
||||
if (result.ErrorMessageKey.HasValue)
|
||||
{
|
||||
LocalizedMessageBox.Show(result.ErrorMessageKey.Value,
|
||||
MessageKey.TitleError);
|
||||
}
|
||||
```
|
||||
|
||||
## <20><><EFBFBD><EFBFBD>˵<EFBFBD><CBB5>
|
||||
<EFBFBD>Թ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ϊ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||
|
||||
1. <20><> `MessageKey.cs` <20>ж<EFBFBD><D0B6>壺
|
||||
ProcessError_InvalidToolId
|
||||
ProcessError_HardwareTimeout
|
||||
|
||||
2. <20><> `LanguageResourceHelper.ResourceKeyMap` <20><>ע<EFBFBD><D7A2>
|
||||
3. <20><> Service <20><><EFBFBD>ض<EFBFBD><D8B6><EFBFBD><EFBFBD>а<EFBFBD><D0B0><EFBFBD> MessageKey
|
||||
4. <20><> Activity AfterExecute <20><> ViewModel <20>м<EFBFBD><D0BC>鲢ʹ<E9B2A2><CAB9> LocalizedMessageBox <20><>ʾ
|
||||
104
MX-PD-盘古 - new/PanGu.DieBonderApp/.github/instructions/motion.instructions.md
vendored
Normal file
104
MX-PD-盘古 - new/PanGu.DieBonderApp/.github/instructions/motion.instructions.md
vendored
Normal file
@@ -0,0 +1,104 @@
|
||||
---
|
||||
applyTo: "MainShell/Motion/**/*.cs,**/*MotionController*.cs,**/*SafeAxisMotion*.cs,**/*AxisSpeedManager*.cs"
|
||||
---
|
||||
|
||||
# Motion Control Instructions
|
||||
|
||||
## Motion Architecture
|
||||
Motion control uses layered design:
|
||||
|
||||
- SafeAxisMotion as business entry
|
||||
- MotionController as single-axis controller
|
||||
- IAxis / IAxisFunc as platform abstraction
|
||||
|
||||
Keep this layering intact.
|
||||
|
||||
## <20><><EFBFBD><EFBFBD>˵<EFBFBD><CBB5>
|
||||
<EFBFBD>˶<EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ʋ<EFBFBD><EFBFBD>ù̶<EFBFBD><EFBFBD>ֲ㣺
|
||||
- `SafeAxisMotion`<EFBFBD><EFBFBD>ҵ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||
- `MotionController`<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||
- `IAxis / IAxisFunc`<EFBFBD><EFBFBD>ƽ̨<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ӿ<EFBFBD>
|
||||
|
||||
<EFBFBD><EFBFBD>Ҫ<EFBFBD>ƻ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>зֲ<EFBFBD><EFBFBD><EFBFBD>ϵ<EFBFBD><EFBFBD>
|
||||
|
||||
## MotionController Rules
|
||||
- Constructor should receive `IAxis`
|
||||
- Convert to `IAxisFunc` when motion command capability is needed
|
||||
- Use `SemaphoreSlim` to serialize motion commands per axis
|
||||
- Motion methods should support async/await and CancellationToken
|
||||
- Perform status validation before motion:
|
||||
- servo/power status
|
||||
- alarm status
|
||||
- soft limit state
|
||||
- Support timeout handling
|
||||
- Raise motion lifecycle events such as MotionStarted / MotionFinished
|
||||
|
||||
## <20><><EFBFBD><EFBFBD>˵<EFBFBD><CBB5>
|
||||
`MotionController` <20><><EFBFBD>ƹ<EFBFBD><C6B9><EFBFBD><EFBFBD><EFBFBD>
|
||||
- <20><><EFBFBD>캯<EFBFBD><ECBAAF><EFBFBD><EFBFBD><EFBFBD><EFBFBD> `IAxis`
|
||||
- <20><>Ҫ<EFBFBD>˶<EFBFBD><CBB6><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʱת<CAB1><D7AA>Ϊ `IAxisFunc`
|
||||
- ʹ<><CAB9> `SemaphoreSlim` <20><>֤<EFBFBD><D6A4><EFBFBD><EFBFBD>ָ<EFBFBD><EFBFBD><EEB4AE>
|
||||
- <20>˶<EFBFBD><CBB6><EFBFBD><EFBFBD><EFBFBD>֧<EFBFBD><D6A7> `async/await` <20><> `CancellationToken`
|
||||
- <20>˶<EFBFBD>ǰҪ<C7B0><D2AA><EFBFBD><EFBFBD><EFBFBD>ŷ<EFBFBD>״̬<D7B4><CCAC><EFBFBD><EFBFBD><EFBFBD><EFBFBD>״̬<D7B4><CCAC><EFBFBD><EFBFBD><EFBFBD><EFBFBD>λ״̬
|
||||
- ֧<>ֳ<EFBFBD>ʱ<EFBFBD><CAB1><EFBFBD><EFBFBD>
|
||||
- <20><><EFBFBD>ṩ `MotionStarted` / `MotionFinished` <20>¼<EFBFBD>
|
||||
|
||||
## Common Axis Properties
|
||||
Prefer existing property patterns such as:
|
||||
- AxisName
|
||||
- CurrentPos
|
||||
- IsBusy
|
||||
- IsAlarm
|
||||
- InPos
|
||||
|
||||
## <20><><EFBFBD><EFBFBD>˵<EFBFBD><CBB5>
|
||||
<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ա<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ģʽһ<EFBFBD>£<EFBFBD><EFBFBD><EFBFBD><EFBFBD>磺
|
||||
- `AxisName`
|
||||
- `CurrentPos`
|
||||
- `IsBusy`
|
||||
- `IsAlarm`
|
||||
- `InPos`
|
||||
|
||||
## Motion Method Signatures
|
||||
Keep compatibility with existing motion API patterns:
|
||||
- MoveAbsAsync
|
||||
- MoveRelAsync
|
||||
- JogAsync
|
||||
- StopAsync
|
||||
- HomeAsync
|
||||
|
||||
## <20><><EFBFBD><EFBFBD>˵<EFBFBD><CBB5>
|
||||
<EFBFBD>˶<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ǩ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ݣ<EFBFBD>
|
||||
- `MoveAbsAsync`
|
||||
- `MoveRelAsync`
|
||||
- `JogAsync`
|
||||
- `StopAsync`
|
||||
- `HomeAsync`
|
||||
|
||||
## SafeAxisMotion Rules
|
||||
- Prefer SafeAxisMotion for batch-safe movement
|
||||
- Resolve axis name to IAxis and MotionController through existing repository mechanisms
|
||||
- Preserve alarm integration and timeout behavior
|
||||
|
||||
## <20><><EFBFBD><EFBFBD>˵<EFBFBD><CBB5>
|
||||
<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ȫ<EFBFBD>ƶ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ͨ<EFBFBD><EFBFBD> `SafeAxisMotion` ʵ<>֣<EFBFBD>
|
||||
- ͨ<><CDA8><EFBFBD><EFBFBD><EFBFBD>л<EFBFBD><D0BB>ư<EFBFBD><C6B0><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ϊ `IAxis` <20><> `MotionController`
|
||||
- <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ɺͳ<C9BA>ʱ<EFBFBD><CAB1><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||
|
||||
## MotionResult Rules
|
||||
- Use structured MotionResult
|
||||
- Distinguish success, timeout, cancellation, and fault
|
||||
- Use EnsureSuccess when caller expects exception-on-failure semantics
|
||||
|
||||
## <20><><EFBFBD><EFBFBD>˵<EFBFBD><CBB5>
|
||||
`MotionResult` ӦΪ<D3A6>ṹ<EFBFBD><E1B9B9><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||
- <20><><EFBFBD>ֳɹ<D6B3><C9B9><EFBFBD><EFBFBD><EFBFBD>ʱ<EFBFBD><CAB1>ȡ<EFBFBD><C8A1><EFBFBD><EFBFBD><EFBFBD>쳣
|
||||
- <20><><EFBFBD>÷<EFBFBD><C3B7><EFBFBD>Ҫ"ʧ<>ܼ<EFBFBD><DCBC><EFBFBD><EFBFBD>쳣"ʱ<><CAB1>ʹ<EFBFBD><CAB9> `EnsureSuccess()`
|
||||
|
||||
## Speed Management
|
||||
Use AxisSpeedManager for speed control where applicable.
|
||||
Do not hardcode inconsistent speed logic if a unified speed manager already exists.
|
||||
|
||||
## <20><><EFBFBD><EFBFBD>˵<EFBFBD><CBB5>
|
||||
<EFBFBD>ٶȹ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ͨ<EFBFBD><EFBFBD> `AxisSpeedManager` ͳһ<CDB3><D2BB><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||
<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ͳһ<EFBFBD>ٶȹ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ҫ<EFBFBD><EFBFBD><EFBFBD>´<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ӳ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>һ<EFBFBD><EFBFBD><EFBFBD>ٶ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||
92
MX-PD-盘古 - new/PanGu.DieBonderApp/.github/instructions/recipe-and-logging.instructions.md
vendored
Normal file
92
MX-PD-盘古 - new/PanGu.DieBonderApp/.github/instructions/recipe-and-logging.instructions.md
vendored
Normal file
@@ -0,0 +1,92 @@
|
||||
---
|
||||
applyTo: "MainShell/Recipe/**/*.cs,MainShell/Parameter/**/*.cs,MainShell/Log/**/*.cs,MainShell/Filewritable/**/*.cs,MainShell/Process/**/*.cs"
|
||||
---
|
||||
|
||||
# Recipe, Persistence, and Logging Instructions
|
||||
|
||||
## Recipe System
|
||||
Recipe hierarchy includes:
|
||||
- IRecipe
|
||||
- RecipeBase
|
||||
- SubstrateRecipe
|
||||
- WaferRecipe
|
||||
- CarrierRecipe
|
||||
- ProcessRecipe
|
||||
|
||||
Use existing recipe abstractions and managers:
|
||||
- RecipeManager
|
||||
- RecipeWrapManager
|
||||
|
||||
Do not bypass repository recipe patterns by creating incompatible configuration systems.
|
||||
|
||||
## <20><><EFBFBD><EFBFBD>˵<EFBFBD><CBB5>
|
||||
<EFBFBD>䷽ϵͳ<EFBFBD><EFBFBD>ѭ<EFBFBD><EFBFBD><EFBFBD>в㼶<EFBFBD><EFBFBD>
|
||||
- `IRecipe`
|
||||
- `RecipeBase`
|
||||
- `SubstrateRecipe`
|
||||
- `WaferRecipe`
|
||||
- `CarrierRecipe`
|
||||
- `ProcessRecipe`
|
||||
|
||||
Ӧ<EFBFBD><EFBFBD><EFBFBD>ȸ<EFBFBD><EFBFBD>ã<EFBFBD>
|
||||
- `RecipeManager`
|
||||
- `RecipeWrapManager`
|
||||
|
||||
<EFBFBD><EFBFBD>Ҫ<EFBFBD>ƿ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>䷽<EFBFBD><EFBFBD>ϵ<EFBFBD><EFBFBD><EFBFBD>½<EFBFBD>һ<EFBFBD>ײ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ݵ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ϵͳ<EFBFBD><EFBFBD>
|
||||
|
||||
## Parameter and Process Input Rules
|
||||
- Prefer reading process inputs from recipe objects and formal managers
|
||||
- Do not pull process parameters from UI state when repository recipe/domain objects already exist
|
||||
- Keep process input sources explicit and traceable
|
||||
|
||||
## <20><><EFBFBD><EFBFBD>˵<EFBFBD><CBB5>
|
||||
<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||
- <20><><EFBFBD>ȴ<EFBFBD><C8B4>䷽<EFBFBD><E4B7BD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʽ<EFBFBD><CABD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ж<EFBFBD>ȡ<EFBFBD><C8A1><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||
- <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʽ<EFBFBD><CABD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ҫ<EFBFBD><D2AA> UI ״̬<D7B4><CCAC>ȡ<EFBFBD><C8A1><EFBFBD>̲<EFBFBD><CCB2><EFBFBD>
|
||||
- <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ԴҪ<D4B4><D2AA>ȷ<EFBFBD><C8B7><EFBFBD><EFBFBD><EFBFBD><D7B7>
|
||||
|
||||
## File Persistence Rules
|
||||
Persistence follows:
|
||||
- IFileWritable
|
||||
- FileWriteBase
|
||||
- JsonFileWritableBase
|
||||
|
||||
Use:
|
||||
- FileWriteQueue for async queued file writes
|
||||
- Newtonsoft.Json for JSON serialization
|
||||
|
||||
Reuse IgnorePropertiesResolver when selective serialization is needed.
|
||||
|
||||
## <20><><EFBFBD><EFBFBD>˵<EFBFBD><CBB5>
|
||||
<EFBFBD>ļ<EFBFBD><EFBFBD>־û<EFBFBD><EFBFBD><EFBFBD>ѭ<EFBFBD><EFBFBD><EFBFBD>мܹ<EFBFBD><EFBFBD><EFBFBD>
|
||||
- `IFileWritable`
|
||||
- `FileWriteBase`
|
||||
- `JsonFileWritableBase`
|
||||
|
||||
Ӧ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʹ<EFBFBD>ã<EFBFBD>
|
||||
- `FileWriteQueue` <20><><EFBFBD><EFBFBD><EFBFBD>첽д<ECB2BD><D0B4><EFBFBD><EFBFBD><EFBFBD>й<EFBFBD><D0B9><EFBFBD>
|
||||
- `Newtonsoft.Json` <20><><EFBFBD><EFBFBD> JSON <20><><EFBFBD>л<EFBFBD>
|
||||
- <20><>Ҫѡ<D2AA><D1A1><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>л<EFBFBD>ʱ<EFBFBD><CAB1><EFBFBD><EFBFBD> `IgnorePropertiesResolver`
|
||||
|
||||
## Logging Rules
|
||||
- Use `LogNameDefine` for log names
|
||||
- Use `LogManager` for unified log management
|
||||
- Keep logs consistent with existing MaxWellGeneralLog usage
|
||||
|
||||
## <20><><EFBFBD><EFBFBD>˵<EFBFBD><CBB5>
|
||||
<EFBFBD><EFBFBD>־<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||
- <20><>־<EFBFBD><D6BE><EFBFBD><EFBFBD>ͳһ<CDB3><D2BB> `LogNameDefine` <20>ж<EFBFBD><D0B6><EFBFBD>
|
||||
- ͨ<><CDA8> `LogManager` ͳһ<CDB3><D2BB><EFBFBD><EFBFBD>
|
||||
- <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> `MaxWellGeneralLog` <20>÷<EFBFBD>һ<EFBFBD><D2BB>
|
||||
|
||||
## Logging Expectations
|
||||
Generated code should:
|
||||
- log major workflow and hardware steps
|
||||
- log failures with enough context
|
||||
- preserve traceability for production and troubleshooting
|
||||
|
||||
## <20><><EFBFBD><EFBFBD>˵<EFBFBD><CBB5>
|
||||
<EFBFBD><EFBFBD><EFBFBD>ɴ<EFBFBD><EFBFBD><EFBFBD>ʱ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>־Ӧ<EFBFBD><EFBFBD><EFBFBD>㣺
|
||||
- <20>ؼ<EFBFBD><D8BC><EFBFBD><EFBFBD>̲<EFBFBD><CCB2><EFBFBD><EFBFBD><EFBFBD>Ӳ<EFBFBD><D3B2><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>־
|
||||
- ʧ<><CAA7><EFBFBD><EFBFBD>־<EFBFBD><D6BE><EFBFBD><EFBFBD><EFBFBD>㹻<EFBFBD><E3B9BB><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||
- <20><>֧<EFBFBD><D6A7><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ݺ<EFBFBD><DDBA>ֳ<EFBFBD><D6B3><EFBFBD><EFBFBD><EFBFBD>
|
||||
105
MX-PD-盘古 - new/PanGu.DieBonderApp/.github/instructions/workflow.instructions.md
vendored
Normal file
105
MX-PD-盘古 - new/PanGu.DieBonderApp/.github/instructions/workflow.instructions.md
vendored
Normal file
@@ -0,0 +1,105 @@
|
||||
---
|
||||
applyTo: "MainShell/Process/**/*.cs,**/*Activity.cs,**/*Workflow*.cs,**/*ProcessService.cs,**/*MotionService.cs"
|
||||
---
|
||||
|
||||
# Workflow Instructions
|
||||
|
||||
## Workflow Architecture
|
||||
This repository uses:
|
||||
- WorkflowRunner
|
||||
- AutoProductionWorkflowBuilder
|
||||
- ActivityAbstractBase
|
||||
- CompositeActivity
|
||||
- WorkflowStepIds
|
||||
- WorkflowStepIdResolver
|
||||
|
||||
## <20><><EFBFBD><EFBFBD>˵<EFBFBD><CBB5>
|
||||
<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ϵͳ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> Workflow <20>ܹ<EFBFBD>ʵ<EFBFBD>֣<EFBFBD><D6A3><EFBFBD><EFBFBD>ɴ<EFBFBD><C9B4><EFBFBD>ʱӦ<CAB1><D3A6><EFBFBD>ȸ<EFBFBD><C8B8><EFBFBD><EFBFBD><EFBFBD>Щ<EFBFBD><D0A9><EFBFBD><EFBFBD><EFBFBD>ͻ<EFBFBD><CDBB>ơ<EFBFBD>
|
||||
|
||||
## Layering Rules
|
||||
- Activity layer only:
|
||||
- calls Service / MotionService / ProcessService
|
||||
- writes WorkflowContext
|
||||
- returns execution result
|
||||
- PrepareExecute and AfterExecute only handle pre/post processing
|
||||
- Core workflow logic must be implemented in Service layer
|
||||
- Do not place recipe parsing, compensation logic, vision logic, or hardware orchestration in Activity
|
||||
|
||||
## <20><><EFBFBD><EFBFBD>˵<EFBFBD><CBB5>
|
||||
<EFBFBD>ֲ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||
- Activity <20><>ֻ<EFBFBD><D6BB><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> Service<63><65>д WorkflowContext<78><74><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ִ<EFBFBD>н<EFBFBD><D0BD><EFBFBD>
|
||||
- `PrepareExecute` <20><> `AfterExecute` ֻ<><D6BB>ǰ<EFBFBD><C7B0><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||
- <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><DFBC><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> Service <20><>
|
||||
- <20><>Ҫ<EFBFBD><D2AA> Activity <20><>д<EFBFBD>䷽<EFBFBD><E4B7BD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ӿ<EFBFBD><D3BE>㷨<EFBFBD><E3B7A8><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><DFBC><EFBFBD>Ӳ<EFBFBD><D3B2><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||
|
||||
## Routing Rules
|
||||
- Do not place workflow jump logic in Activity
|
||||
- Actual workflow transitions must be configured by WorkflowStep
|
||||
- Normal business branches should use Route / SetRoute
|
||||
- Failure should only be used for real failures:
|
||||
- hardware error
|
||||
- timeout
|
||||
- communication failure
|
||||
- invalid required input
|
||||
- unrecoverable process error
|
||||
|
||||
## <20><><EFBFBD><EFBFBD>˵<EFBFBD><CBB5>
|
||||
<EFBFBD><EFBFBD>ת<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||
- <20><>Ҫ<EFBFBD><D2AA> Activity <20><>д<EFBFBD><D0B4><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ת<EFBFBD><EFBFBD>
|
||||
- <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>תͳһ<CDB3><D2BB> WorkflowStep <20><><EFBFBD><EFBFBD>
|
||||
- <20><><EFBFBD><EFBFBD>ҵ<EFBFBD><D2B5><EFBFBD><EFBFBD>֧<EFBFBD><D6A7><EFBFBD><EFBFBD>ʹ<EFBFBD><CAB9> `Route / SetRoute`
|
||||
- `Failure` ֻ<><D6BB><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>쳣<EFBFBD><ECB3A3><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ӳ<EFBFBD><D3B2><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʱ<EFBFBD><CAB1>ͨѶʧ<D1B6>ܡ<EFBFBD><DCA1>ؼ<EFBFBD><D8BC><EFBFBD><EFBFBD><EFBFBD>ȱʧ<C8B1><CAA7><EFBFBD><EFBFBD><EFBFBD>ɻָ<C9BB><D6B8><EFBFBD><EFBFBD><EFBFBD>
|
||||
|
||||
## JumpConditions Rules
|
||||
- JumpConditions are matched in add order
|
||||
- More specific branches must be placed first
|
||||
- Default flow must be placed last
|
||||
|
||||
## <20><><EFBFBD><EFBFBD>˵<EFBFBD><CBB5>
|
||||
`JumpConditions` ƥ<><C6A5>˳<EFBFBD><CBB3><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>˳<EFBFBD><CBB3>ִ<EFBFBD>У<EFBFBD>
|
||||
- <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ǰ<EFBFBD><C7B0>
|
||||
- Ĭ<>Ϸ<EFBFBD>֧<EFBFBD><D6A7><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||
|
||||
## Service Responsibilities
|
||||
Service layer should be responsible for:
|
||||
- reading WorkflowContext
|
||||
- reading RecipeManager and current recipe
|
||||
- reading teach data and process parameters
|
||||
- acquiring hardware via HardwareManager
|
||||
- validating inputs
|
||||
- validating hardware state
|
||||
- validating safety conditions
|
||||
- executing workflow core steps
|
||||
- computing business result or compensation result
|
||||
- determining Route
|
||||
- returning structured process result
|
||||
|
||||
## <20><><EFBFBD><EFBFBD>˵<EFBFBD><CBB5>
|
||||
Service <20><>ְ<EFBFBD><D6B0><EFBFBD><EFBFBD>
|
||||
- <20><>ȡ `WorkflowContext`
|
||||
- <20><>ȡ `RecipeManager` <20>͵<EFBFBD>ǰ<EFBFBD>䷽
|
||||
- <20><>ȡʾ<C8A1><CABE><EFBFBD><EFBFBD><EFBFBD>ݺ<DDBA><CDB9>ղ<EFBFBD><D5B2><EFBFBD>
|
||||
- ͨ<><CDA8> `HardwareManager` <20><>ȡӲ<C8A1><D3B2><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||
- У<><D0A3><EFBFBD><EFBFBD><EFBFBD>롢Ӳ<EBA1A2><D3B2>״̬<D7B4>Ͱ<EFBFBD>ȫ<EFBFBD><C8AB><EFBFBD><EFBFBD>
|
||||
- ִ<>к<EFBFBD><D0BA><EFBFBD><EFBFBD><EFBFBD><EFBFBD>̲<EFBFBD><CCB2><EFBFBD>
|
||||
- <20><><EFBFBD><EFBFBD>ҵ<EFBFBD><D2B5><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><F2B2B9B3><EFBFBD><EFBFBD><EFBFBD>
|
||||
- <20><><EFBFBD><EFBFBD> `Route`
|
||||
- <20><><EFBFBD>ؽṹ<D8BD><E1B9B9><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||
|
||||
## Output Preference
|
||||
When implementing workflow code, prefer:
|
||||
1. Activity skeleton
|
||||
2. Service skeleton
|
||||
3. result object design
|
||||
4. WorkflowContext write-back fields
|
||||
5. WorkflowStep routing suggestion
|
||||
6. JumpConditions ordering suggestion
|
||||
|
||||
## <20><><EFBFBD><EFBFBD>˵<EFBFBD><CBB5>
|
||||
ʵ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>̴<EFBFBD><EFBFBD><EFBFBD>ʱ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||
1. Activity <20>Ǽ<EFBFBD>
|
||||
2. Service <20>Ǽ<EFBFBD>
|
||||
3. <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||
4. WorkflowContext <20><>д<EFBFBD>ֶ<EFBFBD>
|
||||
5. WorkflowStep ·<>ɽ<EFBFBD><C9BD><EFBFBD>
|
||||
6. JumpConditions ˳<><CBB3><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||
72
MX-PD-盘古 - new/PanGu.DieBonderApp/.github/instructions/wpf-mvvm.instructions.md
vendored
Normal file
72
MX-PD-盘古 - new/PanGu.DieBonderApp/.github/instructions/wpf-mvvm.instructions.md
vendored
Normal file
@@ -0,0 +1,72 @@
|
||||
---
|
||||
applyTo: "**/*ViewModel.cs,**/*.xaml,MainShell/Converter/**/*.cs,MainShell/Home/**/*.cs,MainShell/ParaSetting/**/*.cs,MainShell/DeviceMaintance/**/*.cs,MainShell/PageCalib/**/*.cs,MainShell/Manual/**/*.cs"
|
||||
---
|
||||
|
||||
# WPF and MVVM Instructions
|
||||
|
||||
## Framework
|
||||
This repository uses WPF with Stylet.
|
||||
|
||||
## <20><><EFBFBD><EFBFBD>˵<EFBFBD><CBB5>
|
||||
<EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ŀ WPF <20><><EFBFBD><EFBFBD>ʹ<EFBFBD><CAB9> Stylet<65><74>MVVM <20><><EFBFBD>ش<EFBFBD><D8B4><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ѭ Stylet <20><>Լ<EFBFBD><D4BC><EFBFBD><EFBFBD>
|
||||
|
||||
## ViewModel Rules
|
||||
- ViewModel classes should inherit from `Screen` or `PropertyChangedBase`
|
||||
- Follow Stylet naming convention:
|
||||
- XxxView ? XxxViewModel
|
||||
- Do not introduce patterns that conflict with Stylet conventions
|
||||
|
||||
## <20><><EFBFBD><EFBFBD>˵<EFBFBD><CBB5>
|
||||
ViewModel <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||
- ViewModel <20>̳<EFBFBD> `Screen` <20><> `PropertyChangedBase`
|
||||
- View <20><> ViewModel <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Լ<EFBFBD><D4BC><EFBFBD>Զ<EFBFBD><D4B6><EFBFBD><EFBFBD><EFBFBD>
|
||||
- <20><>Ҫ<EFBFBD><D2AA><EFBFBD><EFBFBD><EFBFBD><EFBFBD> Stylet <20><>ͻ<EFBFBD><CDBB> MVVM ģʽ
|
||||
|
||||
## State Management
|
||||
- Prefer bindable state objects to hold UI state
|
||||
- Do not scatter many unrelated primitive bindable properties if a cohesive state model is more suitable
|
||||
- Distinguish device input state and output state clearly
|
||||
|
||||
## <20><><EFBFBD><EFBFBD>˵<EFBFBD><CBB5>
|
||||
״̬<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>飺
|
||||
- <20><><EFBFBD><EFBFBD>ʹ<EFBFBD>ÿɰ<C3BF><C9B0><EFBFBD>״̬<D7B4><CCAC><EFBFBD><EFBFBD>ͳһ<CDB3><D2BB><EFBFBD>ؽ<EFBFBD><D8BD><EFBFBD>״̬
|
||||
- <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ա<EFBFBD><D4B1><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>һ<EFBFBD><D2BB>״̬<D7B4><EFBFBD>Ҫ<EFBFBD><D2AA>ɢ<EFBFBD><C9A2><EFBFBD><EFBFBD><EFBFBD><EFBFBD> ViewModel <20><>
|
||||
- <20><><EFBFBD><EFBFBD>״̬<D7B4><CCAC><EFBFBD><EFBFBD><EFBFBD><EFBFBD>״̬Ҫ<CCAC><D2AA>ȷ<EFBFBD><C8B7><EFBFBD><EFBFBD>
|
||||
|
||||
## IoC Rules
|
||||
- IoC registrations belong in `StartBootstrapper.ConfigureIoC()`
|
||||
- Singleton services should use `[Singleton]` or be registered as singleton in IoC
|
||||
- New services must be registered consistently with existing project patterns
|
||||
|
||||
## <20><><EFBFBD><EFBFBD>˵<EFBFBD><CBB5>
|
||||
IoC <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||
- IoC ע<><D7A2>ͳһ<CDB3><D2BB> `StartBootstrapper.ConfigureIoC()` <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||
- <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ͨ<EFBFBD><CDA8> `[Singleton]` <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ע<EFBFBD><D7A2>
|
||||
- <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ѭ<EFBFBD><D1AD><EFBFBD><EFBFBD>ע<EFBFBD><D7A2><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||
|
||||
## XAML Rules
|
||||
- Do not manually implement `InitializeComponent`
|
||||
- Do not work around WPF compilation issues by writing manual code-behind loaders
|
||||
- Fix page compilation through project file and proper WPF item setup
|
||||
- Value converters should be placed in `Converter/` and named `XxxConverter`
|
||||
|
||||
## <20><><EFBFBD><EFBFBD>˵<EFBFBD><CBB5>
|
||||
XAML <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||
- <20><>Ҫ<EFBFBD><D2AA>д `InitializeComponent`
|
||||
- <20><>Ҫͨ<D2AA><CDA8> code-behind <20>ֹ<EFBFBD><D6B9><EFBFBD><EFBFBD><EFBFBD>ҳ<EFBFBD><D2B3><EFBFBD>ƹ<EFBFBD><C6B9><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||
- ҳ<><D2B3><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ӧͨ<D3A6><CDA8> csproj <20><> WPF <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||
- ת<><D7AA><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> `Converter/` <20>£<EFBFBD><C2A3><EFBFBD>ʹ<EFBFBD><CAB9> `XxxConverter` <20><><EFBFBD><EFBFBD>
|
||||
|
||||
## Language Resource Rules
|
||||
Project language resources are loaded from:
|
||||
- `Language/MaxwellFramework_{lang}.xaml`
|
||||
- `Language/MXJM_{lang}.xaml`
|
||||
|
||||
Keep generated UI code compatible with the existing localization mechanism.
|
||||
|
||||
## <20><><EFBFBD><EFBFBD>˵<EFBFBD><CBB5>
|
||||
<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Դ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ѭ<EFBFBD><EFBFBD><EFBFBD>л<EFBFBD><EFBFBD>ƣ<EFBFBD>
|
||||
- ƽ̨<C6BD><CCA8><EFBFBD><EFBFBD><D4B0><EFBFBD>`MaxwellFramework_{lang}.xaml`
|
||||
- <20><>Ŀ<EFBFBD><C4BF><EFBFBD><EFBFBD><D4B0><EFBFBD>`MXJM_{lang}.xaml`
|
||||
|
||||
<EFBFBD><EFBFBD><EFBFBD><EFBFBD> UI <20><><EFBFBD><EFBFBD>ʱ<EFBFBD><CAB1>Ҫ<EFBFBD>ƻ<EFBFBD><C6BB><EFBFBD><EFBFBD>ж<EFBFBD><D0B6><EFBFBD><EFBFBD>Ի<EFBFBD><D4BB>ơ<EFBFBD>
|
||||
581
MX-PD-盘古 - new/PanGu.DieBonderApp/Configuration/AxisCardPO.xml
Normal file
581
MX-PD-盘古 - new/PanGu.DieBonderApp/Configuration/AxisCardPO.xml
Normal file
@@ -0,0 +1,581 @@
|
||||
<?xml version="1.0"?>
|
||||
<ArrayOfPersistenceObject xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
|
||||
<PersistenceObject xsi:type="AxisCardPO">
|
||||
<AlarmOffset>0</AlarmOffset>
|
||||
<CategoryName>AcsCard</CategoryName>
|
||||
<ID>2d23c400-ccf2-469a-add5-ae92a98a85e6</ID>
|
||||
<EnableLog>false</EnableLog>
|
||||
<ConfigPath>AxisCardPO.xml</ConfigPath>
|
||||
<AxisCardType>DEMO</AxisCardType>
|
||||
<AxisCardNum>0</AxisCardNum>
|
||||
<PortNo>0</PortNo>
|
||||
<ListAxisCardParaPO>
|
||||
<AxisCardParaPO>
|
||||
<AlarmOffset>0</AlarmOffset>
|
||||
<CategoryName>PHS-X1</CategoryName>
|
||||
<ID>3a9c772b-4a9c-4077-abbc-80fc038b81ee</ID>
|
||||
<EnableLog>false</EnableLog>
|
||||
<ConfigPath>AxisCardParaPO.xml</ConfigPath>
|
||||
<AxisCardId>0</AxisCardId>
|
||||
<AxisCardName>AcsCard</AxisCardName>
|
||||
<AxisCardNum>0</AxisCardNum>
|
||||
<AxisNum>0</AxisNum>
|
||||
<AxisName>PHS-X1</AxisName>
|
||||
<Direction>X</Direction>
|
||||
<GoogalCore>0</GoogalCore>
|
||||
<GoogalAxisNum>0</GoogalAxisNum>
|
||||
<GoolgalPosErr>0</GoolgalPosErr>
|
||||
<HomeDir>0</HomeDir>
|
||||
<EscapeStep>0</EscapeStep>
|
||||
<HomeMode>HOME_MODE_ERROR</HomeMode>
|
||||
<HomeCheck>false</HomeCheck>
|
||||
<MaxCheckPos>0.001</MaxCheckPos>
|
||||
</AxisCardParaPO>
|
||||
<AxisCardParaPO>
|
||||
<AlarmOffset>0</AlarmOffset>
|
||||
<CategoryName>PHS-X2</CategoryName>
|
||||
<ID>c83e5f81-ef2c-413c-ace9-24bc97c30b32</ID>
|
||||
<EnableLog>false</EnableLog>
|
||||
<ConfigPath>AxisCardParaPO.xml</ConfigPath>
|
||||
<AxisCardId>0</AxisCardId>
|
||||
<AxisCardName>AcsCard</AxisCardName>
|
||||
<AxisCardNum>0</AxisCardNum>
|
||||
<AxisNum>1</AxisNum>
|
||||
<AxisName>PHS-X2</AxisName>
|
||||
<Direction>X</Direction>
|
||||
<GoogalCore>0</GoogalCore>
|
||||
<GoogalAxisNum>0</GoogalAxisNum>
|
||||
<GoolgalPosErr>0</GoolgalPosErr>
|
||||
<HomeDir>0</HomeDir>
|
||||
<EscapeStep>0</EscapeStep>
|
||||
<HomeMode>HOME_MODE_ERROR</HomeMode>
|
||||
<HomeCheck>false</HomeCheck>
|
||||
<MaxCheckPos>0.001</MaxCheckPos>
|
||||
</AxisCardParaPO>
|
||||
<AxisCardParaPO>
|
||||
<AlarmOffset>0</AlarmOffset>
|
||||
<CategoryName>WS-X3</CategoryName>
|
||||
<ID>e0a2d6ed-2972-4595-a8dc-53a504187a9f</ID>
|
||||
<EnableLog>false</EnableLog>
|
||||
<ConfigPath>AxisCardParaPO.xml</ConfigPath>
|
||||
<AxisCardId>0</AxisCardId>
|
||||
<AxisCardName>AcsCard</AxisCardName>
|
||||
<AxisCardNum>0</AxisCardNum>
|
||||
<AxisNum>4</AxisNum>
|
||||
<AxisName>WS-X3</AxisName>
|
||||
<Direction>X</Direction>
|
||||
<GoogalCore>0</GoogalCore>
|
||||
<GoogalAxisNum>0</GoogalAxisNum>
|
||||
<GoolgalPosErr>0</GoolgalPosErr>
|
||||
<HomeDir>0</HomeDir>
|
||||
<EscapeStep>0</EscapeStep>
|
||||
<HomeMode>HOME_MODE_ERROR</HomeMode>
|
||||
<HomeCheck>false</HomeCheck>
|
||||
<MaxCheckPos>0.001</MaxCheckPos>
|
||||
</AxisCardParaPO>
|
||||
<AxisCardParaPO>
|
||||
<AlarmOffset>0</AlarmOffset>
|
||||
<CategoryName>PHS-Y1</CategoryName>
|
||||
<ID>4e145d2a-f7f7-4ce2-a5b0-919375a03d87</ID>
|
||||
<EnableLog>false</EnableLog>
|
||||
<ConfigPath>AxisCardParaPO.xml</ConfigPath>
|
||||
<AxisCardId>0</AxisCardId>
|
||||
<AxisCardName>AcsCard</AxisCardName>
|
||||
<AxisCardNum>0</AxisCardNum>
|
||||
<AxisNum>2</AxisNum>
|
||||
<AxisName>PHS-Y1</AxisName>
|
||||
<Direction>X</Direction>
|
||||
<GoogalCore>0</GoogalCore>
|
||||
<GoogalAxisNum>0</GoogalAxisNum>
|
||||
<GoolgalPosErr>0</GoolgalPosErr>
|
||||
<HomeDir>0</HomeDir>
|
||||
<EscapeStep>0</EscapeStep>
|
||||
<HomeMode>HOME_MODE_ERROR</HomeMode>
|
||||
<HomeCheck>false</HomeCheck>
|
||||
<MaxCheckPos>0.001</MaxCheckPos>
|
||||
</AxisCardParaPO>
|
||||
<AxisCardParaPO>
|
||||
<AlarmOffset>0</AlarmOffset>
|
||||
<CategoryName>WS-R</CategoryName>
|
||||
<ID>cebe7f5c-8cdd-47e8-906a-6083047a078d</ID>
|
||||
<EnableLog>false</EnableLog>
|
||||
<ConfigPath>AxisCardParaPO.xml</ConfigPath>
|
||||
<AxisCardId>0</AxisCardId>
|
||||
<AxisCardName>AcsCard</AxisCardName>
|
||||
<AxisCardNum>0</AxisCardNum>
|
||||
<AxisNum>6</AxisNum>
|
||||
<AxisName>WS-R</AxisName>
|
||||
<Direction>X</Direction>
|
||||
<GoogalCore>0</GoogalCore>
|
||||
<GoogalAxisNum>0</GoogalAxisNum>
|
||||
<GoolgalPosErr>0</GoolgalPosErr>
|
||||
<HomeDir>0</HomeDir>
|
||||
<EscapeStep>0</EscapeStep>
|
||||
<HomeMode>HOME_MODE_ERROR</HomeMode>
|
||||
<HomeCheck>false</HomeCheck>
|
||||
<MaxCheckPos>0.001</MaxCheckPos>
|
||||
</AxisCardParaPO>
|
||||
<AxisCardParaPO>
|
||||
<AlarmOffset>0</AlarmOffset>
|
||||
<CategoryName>SZ</CategoryName>
|
||||
<ID>ce1f8f65-3409-4124-9c9a-ba750c848e36</ID>
|
||||
<EnableLog>false</EnableLog>
|
||||
<ConfigPath>AxisCardParaPO.xml</ConfigPath>
|
||||
<AxisCardId>0</AxisCardId>
|
||||
<AxisCardName>AcsCard</AxisCardName>
|
||||
<AxisCardNum>0</AxisCardNum>
|
||||
<AxisNum>8</AxisNum>
|
||||
<AxisName>SZ</AxisName>
|
||||
<Direction>X</Direction>
|
||||
<GoogalCore>0</GoogalCore>
|
||||
<GoogalAxisNum>0</GoogalAxisNum>
|
||||
<GoolgalPosErr>0</GoolgalPosErr>
|
||||
<HomeDir>0</HomeDir>
|
||||
<EscapeStep>0</EscapeStep>
|
||||
<HomeMode>HOME_MODE_ERROR</HomeMode>
|
||||
<HomeCheck>false</HomeCheck>
|
||||
<MaxCheckPos>0.001</MaxCheckPos>
|
||||
</AxisCardParaPO>
|
||||
<AxisCardParaPO>
|
||||
<AlarmOffset>0</AlarmOffset>
|
||||
<CategoryName>Stage-Y3</CategoryName>
|
||||
<ID>05dfa6d1-401b-4a55-808b-5af2efeb358c</ID>
|
||||
<EnableLog>false</EnableLog>
|
||||
<ConfigPath>AxisCardParaPO.xml</ConfigPath>
|
||||
<AxisCardId>0</AxisCardId>
|
||||
<AxisCardName>AcsCard</AxisCardName>
|
||||
<AxisCardNum>0</AxisCardNum>
|
||||
<AxisNum>7</AxisNum>
|
||||
<AxisName>Stage-Y3</AxisName>
|
||||
<Direction>X</Direction>
|
||||
<GoogalCore>0</GoogalCore>
|
||||
<GoogalAxisNum>0</GoogalAxisNum>
|
||||
<GoolgalPosErr>0</GoolgalPosErr>
|
||||
<HomeDir>0</HomeDir>
|
||||
<EscapeStep>0</EscapeStep>
|
||||
<HomeMode>HOME_MODE_ERROR</HomeMode>
|
||||
<HomeCheck>false</HomeCheck>
|
||||
<MaxCheckPos>0.001</MaxCheckPos>
|
||||
</AxisCardParaPO>
|
||||
</ListAxisCardParaPO>
|
||||
<Version>1</Version>
|
||||
<Core>0</Core>
|
||||
<CrossCompensate>0</CrossCompensate>
|
||||
<IsServoSeparate>false</IsServoSeparate>
|
||||
</PersistenceObject>
|
||||
<PersistenceObject xsi:type="AxisCardPO">
|
||||
<AlarmOffset>0</AlarmOffset>
|
||||
<CategoryName>Plc</CategoryName>
|
||||
<ID>80a2e320-d4da-46a6-9f35-0a6d0996ea22</ID>
|
||||
<EnableLog>false</EnableLog>
|
||||
<ConfigPath>AxisCardPO.xml</ConfigPath>
|
||||
<AxisCardType>DEMO</AxisCardType>
|
||||
<AxisCardNum>0</AxisCardNum>
|
||||
<PortNo>0</PortNo>
|
||||
<ListAxisCardParaPO>
|
||||
<AxisCardParaPO>
|
||||
<AlarmOffset>0</AlarmOffset>
|
||||
<CategoryName>PHS-Z1</CategoryName>
|
||||
<ID>471e0395-0918-4e0b-b9cb-d0727281ef6c</ID>
|
||||
<EnableLog>false</EnableLog>
|
||||
<ConfigPath>AxisCardParaPO.xml</ConfigPath>
|
||||
<AxisCardId>0</AxisCardId>
|
||||
<AxisCardName>Plc</AxisCardName>
|
||||
<AxisCardNum>0</AxisCardNum>
|
||||
<AxisNum>0</AxisNum>
|
||||
<AxisName>PHS-Z1</AxisName>
|
||||
<Direction>Z</Direction>
|
||||
<GoogalCore>0</GoogalCore>
|
||||
<GoogalAxisNum>0</GoogalAxisNum>
|
||||
<GoolgalPosErr>0</GoolgalPosErr>
|
||||
<HomeDir>0</HomeDir>
|
||||
<EscapeStep>0</EscapeStep>
|
||||
<HomeMode>HOME_MODE_ERROR</HomeMode>
|
||||
<HomeCheck>false</HomeCheck>
|
||||
<MaxCheckPos>0.001</MaxCheckPos>
|
||||
</AxisCardParaPO>
|
||||
<AxisCardParaPO>
|
||||
<AlarmOffset>0</AlarmOffset>
|
||||
<CategoryName>PHS-Z3</CategoryName>
|
||||
<ID>5dd115ab-09a4-4bbb-9fdf-e9b76cc5e88e</ID>
|
||||
<EnableLog>false</EnableLog>
|
||||
<ConfigPath>AxisCardParaPO.xml</ConfigPath>
|
||||
<AxisCardId>0</AxisCardId>
|
||||
<AxisCardName>Plc</AxisCardName>
|
||||
<AxisCardNum>0</AxisCardNum>
|
||||
<AxisNum>1</AxisNum>
|
||||
<AxisName>PHS-Z3</AxisName>
|
||||
<Direction>Z</Direction>
|
||||
<GoogalCore>0</GoogalCore>
|
||||
<GoogalAxisNum>0</GoogalAxisNum>
|
||||
<GoolgalPosErr>0</GoolgalPosErr>
|
||||
<HomeDir>0</HomeDir>
|
||||
<EscapeStep>0</EscapeStep>
|
||||
<HomeMode>HOME_MODE_ERROR</HomeMode>
|
||||
<HomeCheck>false</HomeCheck>
|
||||
<MaxCheckPos>0.001</MaxCheckPos>
|
||||
</AxisCardParaPO>
|
||||
<AxisCardParaPO>
|
||||
<AlarmOffset>0</AlarmOffset>
|
||||
<CategoryName>PHS-Z4</CategoryName>
|
||||
<ID>e359bc21-c1e8-4e06-acdb-1df94ee7931b</ID>
|
||||
<EnableLog>false</EnableLog>
|
||||
<ConfigPath>AxisCardParaPO.xml</ConfigPath>
|
||||
<AxisCardId>0</AxisCardId>
|
||||
<AxisCardName>Plc</AxisCardName>
|
||||
<AxisCardNum>0</AxisCardNum>
|
||||
<AxisNum>10</AxisNum>
|
||||
<AxisName>PHS-Z4</AxisName>
|
||||
<Direction>X</Direction>
|
||||
<GoogalCore>0</GoogalCore>
|
||||
<GoogalAxisNum>0</GoogalAxisNum>
|
||||
<GoolgalPosErr>0</GoolgalPosErr>
|
||||
<HomeDir>0</HomeDir>
|
||||
<EscapeStep>0</EscapeStep>
|
||||
<HomeMode>HOME_MODE_ERROR</HomeMode>
|
||||
<HomeCheck>false</HomeCheck>
|
||||
<MaxCheckPos>0.001</MaxCheckPos>
|
||||
</AxisCardParaPO>
|
||||
<AxisCardParaPO>
|
||||
<AlarmOffset>0</AlarmOffset>
|
||||
<CategoryName>PHS-Z5</CategoryName>
|
||||
<ID>9d948211-59ae-498c-b124-531a69855752</ID>
|
||||
<EnableLog>false</EnableLog>
|
||||
<ConfigPath>AxisCardParaPO.xml</ConfigPath>
|
||||
<AxisCardId>0</AxisCardId>
|
||||
<AxisCardName>Plc</AxisCardName>
|
||||
<AxisCardNum>0</AxisCardNum>
|
||||
<AxisNum>2</AxisNum>
|
||||
<AxisName>PHS-Z5</AxisName>
|
||||
<Direction>X</Direction>
|
||||
<GoogalCore>0</GoogalCore>
|
||||
<GoogalAxisNum>0</GoogalAxisNum>
|
||||
<GoolgalPosErr>0</GoolgalPosErr>
|
||||
<HomeDir>0</HomeDir>
|
||||
<EscapeStep>0</EscapeStep>
|
||||
<HomeMode>HOME_MODE_ERROR</HomeMode>
|
||||
<HomeCheck>false</HomeCheck>
|
||||
<MaxCheckPos>0.001</MaxCheckPos>
|
||||
</AxisCardParaPO>
|
||||
<AxisCardParaPO>
|
||||
<AlarmOffset>0</AlarmOffset>
|
||||
<CategoryName>PHS-Z6</CategoryName>
|
||||
<ID>477c569a-e460-4c45-917f-a0744ebed5ec</ID>
|
||||
<EnableLog>false</EnableLog>
|
||||
<ConfigPath>AxisCardParaPO.xml</ConfigPath>
|
||||
<AxisCardId>0</AxisCardId>
|
||||
<AxisCardName>Plc</AxisCardName>
|
||||
<AxisCardNum>0</AxisCardNum>
|
||||
<AxisNum>11</AxisNum>
|
||||
<AxisName>PHS-Z6</AxisName>
|
||||
<Direction>X</Direction>
|
||||
<GoogalCore>0</GoogalCore>
|
||||
<GoogalAxisNum>0</GoogalAxisNum>
|
||||
<GoolgalPosErr>0</GoolgalPosErr>
|
||||
<HomeDir>0</HomeDir>
|
||||
<EscapeStep>0</EscapeStep>
|
||||
<HomeMode>HOME_MODE_ERROR</HomeMode>
|
||||
<HomeCheck>false</HomeCheck>
|
||||
<MaxCheckPos>0.001</MaxCheckPos>
|
||||
</AxisCardParaPO>
|
||||
<AxisCardParaPO>
|
||||
<AlarmOffset>0</AlarmOffset>
|
||||
<CategoryName>Stage-Z7</CategoryName>
|
||||
<ID>f761791c-8fb4-4a5b-8fef-0380e996e81f</ID>
|
||||
<EnableLog>false</EnableLog>
|
||||
<ConfigPath>AxisCardParaPO.xml</ConfigPath>
|
||||
<AxisCardId>0</AxisCardId>
|
||||
<AxisCardName>Plc</AxisCardName>
|
||||
<AxisCardNum>0</AxisCardNum>
|
||||
<AxisNum>7</AxisNum>
|
||||
<AxisName>Stage-Z7</AxisName>
|
||||
<Direction>X</Direction>
|
||||
<GoogalCore>0</GoogalCore>
|
||||
<GoogalAxisNum>0</GoogalAxisNum>
|
||||
<GoolgalPosErr>0</GoolgalPosErr>
|
||||
<HomeDir>0</HomeDir>
|
||||
<EscapeStep>0</EscapeStep>
|
||||
<HomeMode>HOME_MODE_ERROR</HomeMode>
|
||||
<HomeCheck>false</HomeCheck>
|
||||
<MaxCheckPos>0.001</MaxCheckPos>
|
||||
</AxisCardParaPO>
|
||||
<AxisCardParaPO>
|
||||
<AlarmOffset>0</AlarmOffset>
|
||||
<CategoryName>Stage-Z8</CategoryName>
|
||||
<ID>28a1caa3-01bc-48ed-8551-68829b280a6f</ID>
|
||||
<EnableLog>false</EnableLog>
|
||||
<ConfigPath>AxisCardParaPO.xml</ConfigPath>
|
||||
<AxisCardId>0</AxisCardId>
|
||||
<AxisCardName>Plc</AxisCardName>
|
||||
<AxisCardNum>0</AxisCardNum>
|
||||
<AxisNum>8</AxisNum>
|
||||
<AxisName>Stage-Z8</AxisName>
|
||||
<Direction>X</Direction>
|
||||
<GoogalCore>0</GoogalCore>
|
||||
<GoogalAxisNum>0</GoogalAxisNum>
|
||||
<GoolgalPosErr>0</GoolgalPosErr>
|
||||
<HomeDir>0</HomeDir>
|
||||
<EscapeStep>0</EscapeStep>
|
||||
<HomeMode>HOME_MODE_ERROR</HomeMode>
|
||||
<HomeCheck>false</HomeCheck>
|
||||
<MaxCheckPos>0.001</MaxCheckPos>
|
||||
</AxisCardParaPO>
|
||||
<AxisCardParaPO>
|
||||
<AlarmOffset>0</AlarmOffset>
|
||||
<CategoryName>Stage-Z9</CategoryName>
|
||||
<ID>71c8587a-1e85-4fa4-8809-14f00111a230</ID>
|
||||
<EnableLog>false</EnableLog>
|
||||
<ConfigPath>AxisCardParaPO.xml</ConfigPath>
|
||||
<AxisCardId>0</AxisCardId>
|
||||
<AxisCardName>Plc</AxisCardName>
|
||||
<AxisCardNum>0</AxisCardNum>
|
||||
<AxisNum>9</AxisNum>
|
||||
<AxisName>Stage-Z9</AxisName>
|
||||
<Direction>X</Direction>
|
||||
<GoogalCore>0</GoogalCore>
|
||||
<GoogalAxisNum>0</GoogalAxisNum>
|
||||
<GoolgalPosErr>0</GoolgalPosErr>
|
||||
<HomeDir>0</HomeDir>
|
||||
<EscapeStep>0</EscapeStep>
|
||||
<HomeMode>HOME_MODE_ERROR</HomeMode>
|
||||
<HomeCheck>false</HomeCheck>
|
||||
<MaxCheckPos>0.001</MaxCheckPos>
|
||||
</AxisCardParaPO>
|
||||
<AxisCardParaPO>
|
||||
<AlarmOffset>0</AlarmOffset>
|
||||
<CategoryName>Stage-Z10</CategoryName>
|
||||
<ID>fc66c8d2-c35f-46b5-9c14-f3a017311e86</ID>
|
||||
<EnableLog>false</EnableLog>
|
||||
<ConfigPath>AxisCardParaPO.xml</ConfigPath>
|
||||
<AxisCardId>0</AxisCardId>
|
||||
<AxisCardName>Plc</AxisCardName>
|
||||
<AxisCardNum>0</AxisCardNum>
|
||||
<AxisNum>14</AxisNum>
|
||||
<AxisName>Stage-Z10</AxisName>
|
||||
<Direction>X</Direction>
|
||||
<GoogalCore>0</GoogalCore>
|
||||
<GoogalAxisNum>0</GoogalAxisNum>
|
||||
<GoolgalPosErr>0</GoolgalPosErr>
|
||||
<HomeDir>0</HomeDir>
|
||||
<EscapeStep>0</EscapeStep>
|
||||
<HomeMode>HOME_MODE_ERROR</HomeMode>
|
||||
<HomeCheck>false</HomeCheck>
|
||||
<MaxCheckPos>0.001</MaxCheckPos>
|
||||
</AxisCardParaPO>
|
||||
<AxisCardParaPO>
|
||||
<AlarmOffset>0</AlarmOffset>
|
||||
<CategoryName>Stage-CV-Y4</CategoryName>
|
||||
<ID>6ebf862a-c91e-4bb2-a5b7-e67f307333b4</ID>
|
||||
<EnableLog>false</EnableLog>
|
||||
<ConfigPath>AxisCardParaPO.xml</ConfigPath>
|
||||
<AxisCardId>0</AxisCardId>
|
||||
<AxisCardName>Plc</AxisCardName>
|
||||
<AxisCardNum>0</AxisCardNum>
|
||||
<AxisNum>15</AxisNum>
|
||||
<AxisName>Stage-CV-Y4</AxisName>
|
||||
<Direction>X</Direction>
|
||||
<GoogalCore>0</GoogalCore>
|
||||
<GoogalAxisNum>0</GoogalAxisNum>
|
||||
<GoolgalPosErr>0</GoolgalPosErr>
|
||||
<HomeDir>0</HomeDir>
|
||||
<EscapeStep>0</EscapeStep>
|
||||
<HomeMode>HOME_MODE_ERROR</HomeMode>
|
||||
<HomeCheck>false</HomeCheck>
|
||||
<MaxCheckPos>0.001</MaxCheckPos>
|
||||
</AxisCardParaPO>
|
||||
<AxisCardParaPO>
|
||||
<AlarmOffset>0</AlarmOffset>
|
||||
<CategoryName>Stage-CV-Y5</CategoryName>
|
||||
<ID>e1cf2e06-fe51-4115-8ad2-2a0b3dc53c00</ID>
|
||||
<EnableLog>false</EnableLog>
|
||||
<ConfigPath>AxisCardParaPO.xml</ConfigPath>
|
||||
<AxisCardId>0</AxisCardId>
|
||||
<AxisCardName>Plc</AxisCardName>
|
||||
<AxisCardNum>0</AxisCardNum>
|
||||
<AxisNum>16</AxisNum>
|
||||
<AxisName>Stage-CV-Y5</AxisName>
|
||||
<Direction>X</Direction>
|
||||
<GoogalCore>0</GoogalCore>
|
||||
<GoogalAxisNum>0</GoogalAxisNum>
|
||||
<GoolgalPosErr>0</GoolgalPosErr>
|
||||
<HomeDir>0</HomeDir>
|
||||
<EscapeStep>0</EscapeStep>
|
||||
<HomeMode>HOME_MODE_ERROR</HomeMode>
|
||||
<HomeCheck>false</HomeCheck>
|
||||
<MaxCheckPos>0.001</MaxCheckPos>
|
||||
</AxisCardParaPO>
|
||||
<AxisCardParaPO>
|
||||
<AlarmOffset>0</AlarmOffset>
|
||||
<CategoryName>WEU-Z11</CategoryName>
|
||||
<ID>a765e366-03a3-451f-ab44-1e6129a6ac61</ID>
|
||||
<EnableLog>false</EnableLog>
|
||||
<ConfigPath>AxisCardParaPO.xml</ConfigPath>
|
||||
<AxisCardId>0</AxisCardId>
|
||||
<AxisCardName>Plc</AxisCardName>
|
||||
<AxisCardNum>0</AxisCardNum>
|
||||
<AxisNum>3</AxisNum>
|
||||
<AxisName>WEU-Z11</AxisName>
|
||||
<Direction>X</Direction>
|
||||
<GoogalCore>0</GoogalCore>
|
||||
<GoogalAxisNum>0</GoogalAxisNum>
|
||||
<GoolgalPosErr>0</GoolgalPosErr>
|
||||
<HomeDir>0</HomeDir>
|
||||
<EscapeStep>0</EscapeStep>
|
||||
<HomeMode>HOME_MODE_ERROR</HomeMode>
|
||||
<HomeCheck>false</HomeCheck>
|
||||
<MaxCheckPos>0.001</MaxCheckPos>
|
||||
</AxisCardParaPO>
|
||||
<AxisCardParaPO>
|
||||
<AlarmOffset>0</AlarmOffset>
|
||||
<CategoryName>WEU-Z12</CategoryName>
|
||||
<ID>a4c43082-6841-45b4-83f2-b89a952a6547</ID>
|
||||
<EnableLog>false</EnableLog>
|
||||
<ConfigPath>AxisCardParaPO.xml</ConfigPath>
|
||||
<AxisCardId>0</AxisCardId>
|
||||
<AxisCardName>Plc</AxisCardName>
|
||||
<AxisCardNum>0</AxisCardNum>
|
||||
<AxisNum>4</AxisNum>
|
||||
<AxisName>WEU-Z12</AxisName>
|
||||
<Direction>X</Direction>
|
||||
<GoogalCore>0</GoogalCore>
|
||||
<GoogalAxisNum>0</GoogalAxisNum>
|
||||
<GoolgalPosErr>0</GoolgalPosErr>
|
||||
<HomeDir>0</HomeDir>
|
||||
<EscapeStep>0</EscapeStep>
|
||||
<HomeMode>HOME_MODE_ERROR</HomeMode>
|
||||
<HomeCheck>false</HomeCheck>
|
||||
<MaxCheckPos>0.001</MaxCheckPos>
|
||||
</AxisCardParaPO>
|
||||
<AxisCardParaPO>
|
||||
<AlarmOffset>0</AlarmOffset>
|
||||
<CategoryName>WEU-Y6</CategoryName>
|
||||
<ID>670409e3-1e19-45c8-94b8-1f3fb1905dc2</ID>
|
||||
<EnableLog>false</EnableLog>
|
||||
<ConfigPath>AxisCardParaPO.xml</ConfigPath>
|
||||
<AxisCardId>0</AxisCardId>
|
||||
<AxisCardName>Plc</AxisCardName>
|
||||
<AxisCardNum>0</AxisCardNum>
|
||||
<AxisNum>5</AxisNum>
|
||||
<AxisName>WEU-Y6</AxisName>
|
||||
<Direction>X</Direction>
|
||||
<GoogalCore>0</GoogalCore>
|
||||
<GoogalAxisNum>0</GoogalAxisNum>
|
||||
<GoolgalPosErr>0</GoolgalPosErr>
|
||||
<HomeDir>0</HomeDir>
|
||||
<EscapeStep>0</EscapeStep>
|
||||
<HomeMode>HOME_MODE_ERROR</HomeMode>
|
||||
<HomeCheck>false</HomeCheck>
|
||||
<MaxCheckPos>0.001</MaxCheckPos>
|
||||
</AxisCardParaPO>
|
||||
<AxisCardParaPO>
|
||||
<AlarmOffset>0</AlarmOffset>
|
||||
<CategoryName>CV-Z13</CategoryName>
|
||||
<ID>eb009565-40bf-4923-9b9b-fdf483dc1532</ID>
|
||||
<EnableLog>false</EnableLog>
|
||||
<ConfigPath>AxisCardParaPO.xml</ConfigPath>
|
||||
<AxisCardId>0</AxisCardId>
|
||||
<AxisCardName>Plc</AxisCardName>
|
||||
<AxisCardNum>0</AxisCardNum>
|
||||
<AxisNum>6</AxisNum>
|
||||
<AxisName>CV-Z13</AxisName>
|
||||
<Direction>X</Direction>
|
||||
<GoogalCore>0</GoogalCore>
|
||||
<GoogalAxisNum>0</GoogalAxisNum>
|
||||
<GoolgalPosErr>0</GoolgalPosErr>
|
||||
<HomeDir>0</HomeDir>
|
||||
<EscapeStep>0</EscapeStep>
|
||||
<HomeMode>HOME_MODE_ERROR</HomeMode>
|
||||
<HomeCheck>false</HomeCheck>
|
||||
<MaxCheckPos>0.001</MaxCheckPos>
|
||||
</AxisCardParaPO>
|
||||
<AxisCardParaPO>
|
||||
<AlarmOffset>0</AlarmOffset>
|
||||
<CategoryName>CV-Y7</CategoryName>
|
||||
<ID>d75ee50a-ba99-4ec1-bb36-6e65cbd84180</ID>
|
||||
<EnableLog>false</EnableLog>
|
||||
<ConfigPath>AxisCardParaPO.xml</ConfigPath>
|
||||
<AxisCardId>0</AxisCardId>
|
||||
<AxisCardName>Plc</AxisCardName>
|
||||
<AxisCardNum>0</AxisCardNum>
|
||||
<AxisNum>18</AxisNum>
|
||||
<AxisName>CV-Y7</AxisName>
|
||||
<Direction>X</Direction>
|
||||
<GoogalCore>0</GoogalCore>
|
||||
<GoogalAxisNum>0</GoogalAxisNum>
|
||||
<GoolgalPosErr>0</GoolgalPosErr>
|
||||
<HomeDir>0</HomeDir>
|
||||
<EscapeStep>0</EscapeStep>
|
||||
<HomeMode>HOME_MODE_ERROR</HomeMode>
|
||||
<HomeCheck>false</HomeCheck>
|
||||
<MaxCheckPos>0.001</MaxCheckPos>
|
||||
</AxisCardParaPO>
|
||||
<AxisCardParaPO>
|
||||
<AlarmOffset>0</AlarmOffset>
|
||||
<CategoryName>CV-Y8</CategoryName>
|
||||
<ID>8845c4e8-4d09-4f0a-b073-1b29e1ca59e6</ID>
|
||||
<EnableLog>false</EnableLog>
|
||||
<ConfigPath>AxisCardParaPO.xml</ConfigPath>
|
||||
<AxisCardId>0</AxisCardId>
|
||||
<AxisCardName>Plc</AxisCardName>
|
||||
<AxisCardNum>0</AxisCardNum>
|
||||
<AxisNum>19</AxisNum>
|
||||
<AxisName>CV-Y8</AxisName>
|
||||
<Direction>X</Direction>
|
||||
<GoogalCore>0</GoogalCore>
|
||||
<GoogalAxisNum>0</GoogalAxisNum>
|
||||
<GoolgalPosErr>0</GoolgalPosErr>
|
||||
<HomeDir>0</HomeDir>
|
||||
<EscapeStep>0</EscapeStep>
|
||||
<HomeMode>HOME_MODE_ERROR</HomeMode>
|
||||
<HomeCheck>false</HomeCheck>
|
||||
<MaxCheckPos>0.001</MaxCheckPos>
|
||||
</AxisCardParaPO>
|
||||
<AxisCardParaPO>
|
||||
<AlarmOffset>0</AlarmOffset>
|
||||
<CategoryName>CV-Y9</CategoryName>
|
||||
<ID>4970be79-b46a-4004-84bf-82e922fb5cb8</ID>
|
||||
<EnableLog>false</EnableLog>
|
||||
<ConfigPath>AxisCardParaPO.xml</ConfigPath>
|
||||
<AxisCardId>0</AxisCardId>
|
||||
<AxisCardName>Plc</AxisCardName>
|
||||
<AxisCardNum>0</AxisCardNum>
|
||||
<AxisNum>20</AxisNum>
|
||||
<AxisName>CV-Y9</AxisName>
|
||||
<Direction>X</Direction>
|
||||
<GoogalCore>0</GoogalCore>
|
||||
<GoogalAxisNum>0</GoogalAxisNum>
|
||||
<GoolgalPosErr>0</GoolgalPosErr>
|
||||
<HomeDir>0</HomeDir>
|
||||
<EscapeStep>0</EscapeStep>
|
||||
<HomeMode>HOME_MODE_ERROR</HomeMode>
|
||||
<HomeCheck>false</HomeCheck>
|
||||
<MaxCheckPos>0.001</MaxCheckPos>
|
||||
</AxisCardParaPO>
|
||||
<AxisCardParaPO>
|
||||
<AlarmOffset>0</AlarmOffset>
|
||||
<CategoryName>CV-Y10</CategoryName>
|
||||
<ID>36583278-40bd-48ad-a749-02b4e58dcbca</ID>
|
||||
<EnableLog>false</EnableLog>
|
||||
<ConfigPath>AxisCardParaPO.xml</ConfigPath>
|
||||
<AxisCardId>0</AxisCardId>
|
||||
<AxisCardName>Plc</AxisCardName>
|
||||
<AxisCardNum>0</AxisCardNum>
|
||||
<AxisNum>21</AxisNum>
|
||||
<AxisName>CV-Y10</AxisName>
|
||||
<Direction>X</Direction>
|
||||
<GoogalCore>0</GoogalCore>
|
||||
<GoogalAxisNum>0</GoogalAxisNum>
|
||||
<GoolgalPosErr>0</GoolgalPosErr>
|
||||
<HomeDir>0</HomeDir>
|
||||
<EscapeStep>0</EscapeStep>
|
||||
<HomeMode>HOME_MODE_ERROR</HomeMode>
|
||||
<HomeCheck>false</HomeCheck>
|
||||
<MaxCheckPos>0.001</MaxCheckPos>
|
||||
</AxisCardParaPO>
|
||||
</ListAxisCardParaPO>
|
||||
<Version>1</Version>
|
||||
<Core>0</Core>
|
||||
<CrossCompensate>0</CrossCompensate>
|
||||
<IsServoSeparate>false</IsServoSeparate>
|
||||
</PersistenceObject>
|
||||
</ArrayOfPersistenceObject>
|
||||
@@ -0,0 +1,9 @@
|
||||
# 气缸定义表
|
||||
# 列顺序:Name,Module,ControlType,ExtendOutputIds,RetractOutputIds,ExtendedFeedbackIds,RetractedFeedbackIds,Description
|
||||
# ControlType: SingleOutput / DualOutput / MultiOutput
|
||||
# ExtendOutputIds / RetractOutputIds / ExtendedFeedbackIds / RetractedFeedbackIds 支持填写多个 IO 引用,使用分号分隔
|
||||
# IO 引用优先使用 Configuration\DeviceIoPoints.csv 中的 Name;若 Id 在全表唯一,也兼容旧 Id 写法
|
||||
Name,Module,ControlType,ExtendOutputIds,RetractOutputIds,ExtendedFeedbackIds,RetractedFeedbackIds,Description
|
||||
WS θ夹紧气缸,WS,SingleOutput,PG.WS.ThetaClampCylAct,,PG.WS.ThetaClampCyl1WorkPos;PG.WS.ThetaClampCyl2WorkPos;PG.WS.ThetaClampCyl3WorkPos;PG.WS.ThetaClampCyl4WorkPos,PG.WS.ThetaClampCyl1HomePos;PG.WS.ThetaClampCyl2HomePos;PG.WS.ThetaClampCyl3HomePos;PG.WS.ThetaClampCyl4HomePos,WS θ 夹紧气缸总动作输出,对应 4 组伸出/缩回反馈
|
||||
WS θ刹车压紧气缸,WS,SingleOutput,PG.WS.ThetaBrakePressCylAct,,,,当前 DeviceIoPoints.csv 未配置到位反馈
|
||||
Stage 顶升同步气缸,Stage,MultiOutput,PG.Stage.LifterCyl1Act;PG.Stage.LifterCyl2Act,,PG.Stage.LifterCyl1WorkPos;PG.Stage.LifterCyl2WorkPos,PG.Stage.LifterCyl1HomePos;PG.Stage.LifterCyl2HomePos,Stage 顶升气缸1和2同步动作,统一伸出/缩回
|
||||
|
@@ -0,0 +1,97 @@
|
||||
# Device IO 定义表
|
||||
# 列顺序:Id Module Name Type Card StationNo LineNo Enabled DefaultValue IsInverse Description
|
||||
# Module: 业务模块名(如 SubstrateLoad/ChipLoad/SubstrateOut/ChipUnload)
|
||||
# Type: Input/Output (也支持 IN/OUT/DI/DO)
|
||||
# Card: Td/Acs
|
||||
# StationNo: 台达站号
|
||||
# LineNo: 实际接线线标/号码管标识
|
||||
# Enabled: 1/0 或 true/false
|
||||
# DefaultValue: 当 IO 未启用或无法读取时使用的默认状态,1/0 或 true/false
|
||||
Id,Module,Name,Type,Card,StationNo,LineNo,Enabled,DefaultValue,IsInverse,Description
|
||||
0,WZ,PG.WZ.StartButton,Input,Td,1,X00100,1,1,0,WZ 启动按钮
|
||||
1,WZ,PG.WZ.StopButton,Input,Td,1,X00101,1,1,0,WZ 停止按钮
|
||||
2,WZ,PG.WZ.ResetButton,Input,Td,1,X00102,1,1,0,WZ 复位按钮
|
||||
3,WZ,PG.WZ.EmergencyStopButton,Input,Td,1,X00103,1,1,0,WZ 急停按钮
|
||||
4,WZ,PG.WZ.BlueButton,Input,Td,1,X00104,1,1,0,WZ 蓝色按钮(预留)
|
||||
5,Stage,PG.Stage.ToolSetterSignal,Input,Td,1,X00105,1,1,0,Stage 对刀信号
|
||||
6,Stage,PG.Stage.SubstrateInPlace,Input,Td,1,X00106,1,1,0,Stage 基板到位感应
|
||||
7,Stage,PG.Stage.LifterCyl1WorkPos,Input,Td,1,X00107,1,1,0,Stage 顶升气缸1动点
|
||||
8,Stage,PG.Stage.LifterCyl1HomePos,Input,Td,1,X00108,1,1,0,Stage 顶升气缸1原点
|
||||
9,Stage,PG.Stage.LifterCyl2WorkPos,Input,Td,1,X00109,1,1,0,Stage 顶升气缸2动点
|
||||
10,Stage,PG.Stage.LifterCyl2HomePos,Input,Td,1,X00110,1,1,0,Stage 顶升气缸2原点
|
||||
11,WS,PG.WS.ThetaClampCyl1WorkPos,Input,Td,1,X00111,1,1,0,WS θ夹紧气缸1动点
|
||||
12,WS,PG.WS.ThetaClampCyl1HomePos,Input,Td,1,X00112,1,1,0,WS θ夹紧气缸1原点
|
||||
13,WS,PG.WS.ThetaClampCyl2WorkPos,Input,Td,1,X00113,1,1,0,WS θ夹紧气缸2动点
|
||||
14,WS,PG.WS.ThetaClampCyl2HomePos,Input,Td,1,X00114,1,1,0,WS θ夹紧气缸2原点
|
||||
15,WS,PG.WS.ThetaClampCyl3WorkPos,Input,Td,1,X00115,1,1,0,WS θ夹紧气缸3动点
|
||||
0,WS,PG.WS.ThetaClampCyl3HomePos,Input,Td,2,X00200,1,1,0,WS θ夹紧气缸3原点
|
||||
1,WS,PG.WS.ThetaClampCyl4WorkPos,Input,Td,2,X00201,1,1,0,WS θ夹紧气缸4动点
|
||||
2,WS,PG.WS.ThetaClampCyl4HomePos,Input,Td,2,X00202,1,1,0,WS θ夹紧气缸4原点
|
||||
3,WS,PG.WS.ThetaTrayPresentSensor1,Input,Td,2,X00203,1,1,0,WS θ料盘有无感应1
|
||||
4,WS,PG.WS.ThetaTrayPresentSensor2,Input,Td,2,X00204,1,1,0,WS θ料盘有无感应2
|
||||
5,WS,PG.WS.ThetaTrayPresentSensor3,Input,Td,2,X00205,1,1,0,WS θ料盘有无感应3
|
||||
6,WS,PG.WS.ThetaTrayPresentSensor4,Input,Td,2,X00206,1,1,0,WS θ料盘有无感应4
|
||||
7,WS,PG.WS.BondHead1InPlace,Input,Td,2,X00207,1,1,0,WS 刺晶头1在位
|
||||
8,WS,PG.WS.BondHead2InPlace,Input,Td,2,X00208,1,1,0,WS 刺晶头2在位
|
||||
9,WS,PG.WS.BondHead3InPlace,Input,Td,2,X00209,1,1,0,WS 刺晶头3在位
|
||||
10,WS,PG.WS.BondHead4InPlace,Input,Td,2,X00210,1,1,0,WS 刺晶头4在位
|
||||
11,WEU,PG.WEU.Z11MaterialSensor1,Input,Td,2,X00211,1,1,0,WEU Z11 有无料感应1
|
||||
12,WEU,PG.WEU.Z11MaterialSensor2,Input,Td,2,X00212,1,1,0,WEU Z11 有无料感应2
|
||||
13,WEU,PG.WEU.Z12MaterialSensor3,Input,Td,2,X00213,1,1,0,WEU Z12 有无料感应3
|
||||
14,WEU,PG.WEU.Z12MaterialSensor4,Input,Td,2,X00214,1,1,0,WEU Z12 有无料感应4
|
||||
0,CV,PG.CV.UpperInletSensor,Input,Td,3,X00300,1,1,0,CV 上层进料感应
|
||||
1,CV,PG.CV.UpperInPlaceSensor,Input,Td,3,X00301,1,1,0,CV 上层到位感应
|
||||
2,CV,PG.CV.LowerOutletSensor,Input,Td,3,X00302,1,1,0,CV 下层出料感应
|
||||
3,CV,PG.CV.LowerInPlaceSensor,Input,Td,3,X00303,1,1,0,CV 下层到位感应
|
||||
4,WZ,PG.WZ.SafetyDoor1Closed,Input,Td,3,X00304,1,1,0,WZ 安全门1关门检测
|
||||
5,WZ,PG.WZ.SafetyDoor2Closed,Input,Td,3,X00305,1,1,0,WZ 安全门2关门检测
|
||||
6,WZ,PG.WZ.SafetyDoor3Closed,Input,Td,3,X00306,1,1,0,WZ 安全门3关门检测
|
||||
7,WZ,PG.WZ.SafetyDoor4Closed,Input,Td,3,X00307,1,1,0,WZ 安全门4关门检测
|
||||
8,WZ,PG.WZ.SecurityDoorShield,Input,Td,3,X00308,1,1,0,WZ 安全门屏蔽
|
||||
10,General,PG.General.PhaseLossSensor,Input,Td,3,X00310,1,1,0,缺相检测
|
||||
11,General,PG.General.SafetyCircuitStatus1,Input,Td,3,X00311,1,1,0,安全回路状态1
|
||||
12,General,PG.General.SafetyCircuitStatus2,Input,Td,3,X00312,1,1,0,安全回路状态2
|
||||
13,CV,PG.CV.IonWindRodAlarmDetection,Input,Td,3,X00313,1,1,0,CV 离子风棒报警检测
|
||||
14,EFEM,PG.EFEM.IonWindRodAlarmDetection1,Input,Td,3,X00314,1,1,0,EFEM离子风棒报警检测1
|
||||
15,EFEM,PG.EFEM.IonWindRodAlarmDetection2,Input,Td,3,X00315,1,1,0,EFEM离子风棒报警检测2
|
||||
0,AxisZ,PG.AxisZ.Z1GuideRailBrake,Output,Td,4,Y00100,1,1,0,Z1轴导轨抱闸
|
||||
1,AxisZ,PG.AxisZ.Z3CameraAirCooling,Output,Td,4,Y00101,1,1,0,Z3相机气冷
|
||||
2,AxisZ,PG.AxisZ.Z5CameraAirCooling,Output,Td,4,Y00102,1,1,0,Z5相机气冷
|
||||
3,AxisZ,PG.AxisZ.Z10CameraAirCooling,Output,Td,4,Y00103,1,1,0,Z10相机气冷
|
||||
4,AxisZ,PG.AxisZ.Z2BondHeadAirCooling,Output,Td,4,Y00104,1,1,0,Z2刺晶头气冷
|
||||
5,CV,PG.CV.IonBarAct,Output,Td,4,Y00105,1,1,0,CV 离子风棒
|
||||
6,WEU,PG.WEU.IonBarAct1,Output,Td,4,Y00106,1,1,0,WEU离子风棒1
|
||||
7,WEU,PG.WEU.IonBarAct2,Output,Td,4,Y00107,1,1,0,WEU离子风棒2
|
||||
8,WS,PG.WS.ThetaClampCylAct,Output,Td,4,Y00108,1,1,0,WS θ 夹紧气缸动作
|
||||
9,WS,PG.WS.ThetaBrakePressCylAct,Output,Td,4,Y00109,1,1,0,WS θ 刹车压紧气缸动作
|
||||
10,Stage,PG.Stage.LifterCyl1Act,Output,Td,4,Y00110,1,1,0,Stage 顶升气缸1动作
|
||||
11,Stage,PG.Stage.LifterCyl2Act,Output,Td,4,Y00111,1,1,0,Stage 顶升气缸2动作
|
||||
0,WZ,PG.WZ.StartButtonLight,Output,Td,5,Y00200,1,1,0,WZ 启动按钮灯
|
||||
1,WZ,PG.WZ.StopButtonLight,Output,Td,5,Y00201,1,1,0,WZ 停止按钮灯
|
||||
2,WZ,PG.WZ.ResetButtonLight,Output,Td,5,Y00202,1,1,0,WZ 复位按钮灯
|
||||
3,WZ,PG.WZ.BlueButtonLight,Output,Td,5,Y00203,1,1,0,WZ 蓝色按钮灯
|
||||
4,WZ,PG.WZ.WorkLight1,Output,Td,5,Y00204,1,1,0,WZ 照明灯1
|
||||
6,EFEM,PG.EFEM.WorkLight1,Output,Td,5,Y00206,1,1,0,EFEM 照明灯1
|
||||
8,WZ,PG.WZ.StackLightRed,Output,Td,5,Y00208,1,1,0,WZ 四色灯-红
|
||||
9,WZ,PG.WZ.StackLightYellow,Output,Td,5,Y00209,1,1,0,WZ 四色灯-黄
|
||||
10,WZ,PG.WZ.StackLightGreen,Output,Td,5,Y00210,1,1,0,WZ 四色灯-绿
|
||||
11,WZ,PG.WZ.StackLightBlue,Output,Td,5,Y00211,1,1,0,WZ 四色灯-蓝
|
||||
12,WZ,PG.WZ.BuzzerAct,Output,Td,5,Y00212,1,1,0,WZ 蜂鸣器
|
||||
0,Stage,PG.Stage.BreakingTheVacuum1,Output,Td,6,Y00300,1,1,0,Stage 破真空1
|
||||
1,Stage,PG.Stage.BreakingTheVacuum2,Output,Td,6,Y00301,1,1,0,STAGE 破真空2
|
||||
2,Stage,PG.Stage.BreakingTheVacuum3,Output,Td,6,Y00302,1,1,0,STAGE 破真空3
|
||||
3,Stage,PG.Stage.BreakingTheVacuum4,Output,Td,6,Y00303,1,1,0,STAGE 破真空4
|
||||
4,WEU,PG.WEU.TrayBreakVacuum1,Output,Td,6,Y00304,1,1,0,WEU 料盘破真空1
|
||||
5,WEU,PG.WEU.TrayBreakVacuum2,Output,Td,6,Y00305,1,1,0,WEU 料盘破真空2
|
||||
6,AxisZ,PG.AxisZ.Z2BondHeadBreakVacuum,Output,Td,6,Y00306,1,1,0,PHS Z2 刺晶头破真空
|
||||
7,Stage,PG.Stage.Vacuum1,Output,Td,6,Y00307,1,1,0,STAGE 吸真空1
|
||||
8,Stage,PG.Stage.Vacuum2,Output,Td,6,Y00308,1,1,0,STAGE 吸真空2
|
||||
9,Stage,PG.Stage.Vacuum3,Output,Td,6,Y00309,1,1,0,STAGE 吸真空3
|
||||
10,Stage,PG.Stage.Vacuum4,Output,Td,6,Y00310,1,1,0,STAGE 吸真空4
|
||||
11,WEU,PG.WEU.TrayVacuum1,Output,Td,6,Y00311,1,1,0,WEU 料盘吸真空1
|
||||
12,WEU,PG.WEU.TrayVacuum2,Output,Td,6,Y00312,1,1,0,WEU 料盘吸真空2
|
||||
13,AxisZ,PG.AxisZ.Z2BondHeadVacuum,Output,Td,6,Y00313,1,1,0,PHS Z2 刺晶头吸真空
|
||||
1,WZ,PG.WZ.SafetyDoor1Open,Output,Td,7,Y00401,1,1,0,WZ 安全门1打开
|
||||
2,WZ,PG.WZ.SafetyDoor2Open,Output,Td,7,Y00402,1,1,0,WZ 安全门2打开
|
||||
3,WZ,PG.WZ.SafetyDoor3Open,Output,Td,7,Y00402,1,1,0,WZ 安全门3打开
|
||||
4,WZ,PG.WZ.SafetyDoor4Open,Output,Td,7,Y00403,1,1,0,WZ 安全门4打开
|
||||
|
@@ -0,0 +1,97 @@
|
||||
# Device IO <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>,,,,,,,,,,
|
||||
"# <20><>˳<EFBFBD><CBB3><EFBFBD><EFBFBD>Id Module Name Type Card StationNo LineNo Enabled DefaultValue IsInverse Description",,,,,,,,,,
|
||||
# Module: ҵ<><D2B5>ģ<EFBFBD><C4A3><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> SubstrateLoad/ChipLoad/SubstrateOut/ChipUnload<61><64>,,,,,,,,,,
|
||||
# Type: Input/Output (Ҳ֧<D2B2><D6A7> IN/OUT/DI/DO),,,,,,,,,,
|
||||
# Card: Td/Acs,,,,,,,,,,
|
||||
# StationNo: ̨<><CCA8>վ<EFBFBD><D5BE>,,,,,,,,,,
|
||||
# LineNo: ʵ<>ʽ<EFBFBD><CABD><EFBFBD><EFBFBD>߱<EFBFBD>/<2F><><EFBFBD><EFBFBD><EFBFBD>ܱ<EFBFBD>ʶ,,,,,,,,,,
|
||||
# Enabled: 1/0 <20><> true/false,,,,,,,,,,
|
||||
# DefaultValue: <20><> IO δ<><CEB4><EFBFBD>û<EFBFBD><C3BB><EFBFBD><DEB7><EFBFBD>ȡʱʹ<CAB1>õ<EFBFBD>Ĭ<EFBFBD><C4AC>״̬<D7B4><CCAC>1/0 <20><> true/false,,,,,,,,,,
|
||||
Id,Module,Name,Type,Card,StationNo,LineNo,Enabled,DefaultValue,IsInverse,Description
|
||||
0,WZ,PG.WZ.StartButton,Input,Td,1,X00100,1,1,0,WZ <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ť
|
||||
1,WZ,PG.WZ.StopButton,Input,Td,1,X00101,1,1,0,WZ ֹͣ<CDA3><D6B9>ť
|
||||
2,WZ,PG.WZ.ResetButton,Input,Td,1,X00102,1,1,0,WZ <20><>λ<EFBFBD><CEBB>ť
|
||||
3,WZ,PG.WZ.EmergencyStopButton,Input,Td,1,X00103,1,1,0,WZ <20><>ͣ<EFBFBD><CDA3>ť
|
||||
4,WZ,PG.WZ.BlueButton,Input,Td,1,X00104,1,1,0,WZ <20><>ɫ<EFBFBD><C9AB>ť<EFBFBD><C5A5>Ԥ<EFBFBD><D4A4><EFBFBD><EFBFBD>
|
||||
5,Stage,PG.Stage.ToolSetterSignal,Input,Td,1,X00105,1,1,0,Stage <20>Ե<EFBFBD><D4B5>ź<EFBFBD>
|
||||
6,Stage,PG.Stage.SubstrateInPlace,Input,Td,1,X00106,1,1,0,Stage <20><><EFBFBD>嵽λ<E5B5BD><CEBB>Ӧ
|
||||
7,Stage,PG.Stage.LifterCyl1WorkPos,Input,Td,1,X00107,1,1,0,Stage <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>1<EFBFBD><31><EFBFBD><EFBFBD>
|
||||
8,Stage,PG.Stage.LifterCyl1HomePos,Input,Td,1,X00108,1,1,0,Stage <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>1ԭ<31><D4AD>
|
||||
9,Stage,PG.Stage.LifterCyl2WorkPos,Input,Td,1,X00109,1,1,0,Stage <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>2<EFBFBD><32><EFBFBD><EFBFBD>
|
||||
10,Stage,PG.Stage.LifterCyl2HomePos,Input,Td,1,X00110,1,1,0,Stage <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>2ԭ<32><D4AD>
|
||||
11,WS,PG.WS.ThetaClampCyl1WorkPos,Input,Td,1,X00111,1,1,0,WS <20><> <20>н<EFBFBD><D0BD><EFBFBD><EFBFBD><EFBFBD>1<EFBFBD><31><EFBFBD><EFBFBD>
|
||||
12,WS,PG.WS.ThetaClampCyl1HomePos,Input,Td,1,X00112,1,1,0,WS <20><> <20>н<EFBFBD><D0BD><EFBFBD><EFBFBD><EFBFBD>1ԭ<31><D4AD>
|
||||
13,WS,PG.WS.ThetaClampCyl2WorkPos,Input,Td,1,X00113,1,1,0,WS <20><> <20>н<EFBFBD><D0BD><EFBFBD><EFBFBD><EFBFBD>2<EFBFBD><32><EFBFBD><EFBFBD>
|
||||
14,WS,PG.WS.ThetaClampCyl2HomePos,Input,Td,1,X00114,1,1,0,WS <20><> <20>н<EFBFBD><D0BD><EFBFBD><EFBFBD><EFBFBD>2ԭ<32><D4AD>
|
||||
15,WS,PG.WS.ThetaClampCyl3WorkPos,Input,Td,1,X00115,1,1,0,WS <20><> <20>н<EFBFBD><D0BD><EFBFBD><EFBFBD><EFBFBD>3<EFBFBD><33><EFBFBD><EFBFBD>
|
||||
0,WS,PG.WS.ThetaClampCyl3HomePos,Input,Td,2,X00200,1,1,0,WS <20><> <20>н<EFBFBD><D0BD><EFBFBD><EFBFBD><EFBFBD>3ԭ<33><D4AD>
|
||||
1,WS,PG.WS.ThetaClampCyl4WorkPos,Input,Td,2,X00201,1,1,0,WS <20><> <20>н<EFBFBD><D0BD><EFBFBD><EFBFBD><EFBFBD>4<EFBFBD><34><EFBFBD><EFBFBD>
|
||||
2,WS,PG.WS.ThetaClampCyl4HomePos,Input,Td,2,X00202,1,1,0,WS <20><> <20>н<EFBFBD><D0BD><EFBFBD><EFBFBD><EFBFBD>4ԭ<34><D4AD>
|
||||
3,WS,PG.WS.ThetaTrayPresentSensor1,Input,Td,2,X00203,1,1,0,WS <20><> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ӧ1
|
||||
4,WS,PG.WS.ThetaTrayPresentSensor2,Input,Td,2,X00204,1,1,0,WS <20><> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ӧ2
|
||||
5,WS,PG.WS.ThetaTrayPresentSensor3,Input,Td,2,X00205,1,1,0,WS <20><> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ӧ3
|
||||
6,WS,PG.WS.ThetaTrayPresentSensor4,Input,Td,2,X00206,1,1,0,WS <20><> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ӧ4
|
||||
7,WS,PG.WS.BondHead1InPlace,Input,Td,2,X00207,1,1,0,WS <20>̾<EFBFBD>ͷ1<CDB7><31>λ
|
||||
8,WS,PG.WS.BondHead2InPlace,Input,Td,2,X00208,1,1,0,WS <20>̾<EFBFBD>ͷ2<CDB7><32>λ
|
||||
9,WS,PG.WS.BondHead3InPlace,Input,Td,2,X00209,1,1,0,WS <20>̾<EFBFBD>ͷ3<CDB7><33>λ
|
||||
10,WS,PG.WS.BondHead4InPlace,Input,Td,2,X00210,1,1,0,WS <20>̾<EFBFBD>ͷ4<CDB7><34>λ
|
||||
11,WEU,PG.WEU.Z11MaterialSensor1,Input,Td,2,X00211,1,1,0,WEU Z11 <20><><EFBFBD><EFBFBD><EFBFBD>ϸ<EFBFBD>Ӧ1
|
||||
12,WEU,PG.WEU.Z11MaterialSensor2,Input,Td,2,X00212,1,1,0,WEU Z11 <20><><EFBFBD><EFBFBD><EFBFBD>ϸ<EFBFBD>Ӧ2
|
||||
13,WEU,PG.WEU.Z12MaterialSensor3,Input,Td,2,X00213,1,1,0,WEU Z12 <20><><EFBFBD><EFBFBD><EFBFBD>ϸ<EFBFBD>Ӧ3
|
||||
14,WEU,PG.WEU.Z12MaterialSensor4,Input,Td,2,X00214,1,1,0,WEU Z12 <20><><EFBFBD><EFBFBD><EFBFBD>ϸ<EFBFBD>Ӧ4
|
||||
0,CV,PG.CV.UpperInletSensor,Input,Td,3,X00300,1,1,0,CV <20>ϲ<EFBFBD><CFB2><EFBFBD><EFBFBD>ϸ<EFBFBD>Ӧ
|
||||
1,CV,PG.CV.UpperInPlaceSensor,Input,Td,3,X00301,1,1,0,CV <20>ϲ㵽λ<E3B5BD><CEBB>Ӧ
|
||||
2,CV,PG.CV.LowerOutletSensor,Input,Td,3,X00302,1,1,0,CV <20>²<EFBFBD><C2B2><EFBFBD><EFBFBD>ϸ<EFBFBD>Ӧ
|
||||
3,CV,PG.CV.LowerInPlaceSensor,Input,Td,3,X00303,1,1,0,CV <20>²㵽λ<E3B5BD><CEBB>Ӧ
|
||||
4,WZ,PG.WZ.SafetyDoor1Closed,Input,Td,3,X00304,1,1,0,WZ <20><>ȫ<EFBFBD><C8AB>1<EFBFBD><31><EFBFBD>ż<EFBFBD><C5BC><EFBFBD>
|
||||
5,WZ,PG.WZ.SafetyDoor2Closed,Input,Td,3,X00305,1,1,0,WZ <20><>ȫ<EFBFBD><C8AB>2<EFBFBD><32><EFBFBD>ż<EFBFBD><C5BC><EFBFBD>
|
||||
6,WZ,PG.WZ.SafetyDoor3Closed,Input,Td,3,X00306,1,1,0,WZ <20><>ȫ<EFBFBD><C8AB>3<EFBFBD><33><EFBFBD>ż<EFBFBD><C5BC><EFBFBD>
|
||||
7,WZ,PG.WZ.SafetyDoor4Closed,Input,Td,3,X00307,1,1,0,WZ <20><>ȫ<EFBFBD><C8AB>4<EFBFBD><34><EFBFBD>ż<EFBFBD><C5BC><EFBFBD>
|
||||
8,WZ,PG.WZ.SecurityDoorShield,Input,Td,3,X00308,1,1,0,WZ <20><>ȫ<EFBFBD><C8AB><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||
10,General,PG.General.PhaseLossSensor,Input,Td,3,X00310,1,1,0,ȱ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||
11,General,PG.General.SafetyCircuitStatus1,Input,Td,3,X00311,1,1,0,<EFBFBD><EFBFBD>ȫ<EFBFBD><EFBFBD>·״̬1
|
||||
12,General,PG.General.SafetyCircuitStatus2,Input,Td,3,X00312,1,1,0,<EFBFBD><EFBFBD>ȫ<EFBFBD><EFBFBD>·״̬2
|
||||
13,CV,PG.CV.IonWindRodAlarmDetection,Input,Td,3,X00313,1,1,0,CV <20><><EFBFBD>ӷ<EFBFBD><D3B7><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||
14,EFEM,PG.EFEM.IonWindRodAlarmDetection1,Input,Td,3,X00314,1,1,0,EFEM<EFBFBD><EFBFBD><EFBFBD>ӷ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>1
|
||||
15,EFEM,PG.EFEM.IonWindRodAlarmDetection2,Input,Td,3,X00315,1,1,0,EFEM<EFBFBD><EFBFBD><EFBFBD>ӷ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>2
|
||||
0,AxisZ,PG.AxisZ.Z1GuideRailBrake,Output,Td,4,Y00100,1,1,0,Z1<EFBFBD>ᵼ<EFBFBD>챧բ
|
||||
1,AxisZ,PG.AxisZ.Z3CameraAirCooling,Output,Td,4,Y00101,1,1,0,Z3<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||
2,AxisZ,PG.AxisZ.Z5CameraAirCooling,Output,Td,4,Y00102,1,1,0,Z5<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||
3,AxisZ,PG.AxisZ.Z10CameraAirCooling,Output,Td,4,Y00103,1,1,0,Z10<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||
4,AxisZ,PG.AxisZ.Z2BondHeadAirCooling,Output,Td,4,Y00104,1,1,0,Z2<EFBFBD>̾<EFBFBD>ͷ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||
5,CV,PG.CV.IonBarAct,Output,Td,4,Y00105,1,1,0,CV <20><><EFBFBD>ӷ<EFBFBD><D3B7><EFBFBD>
|
||||
6,WEU,PG.WEU.IonBarAct1,Output,Td,4,Y00106,1,1,0,WEU<EFBFBD><EFBFBD><EFBFBD>ӷ<EFBFBD><EFBFBD><EFBFBD>1
|
||||
7,WEU,PG.WEU.IonBarAct2,Output,Td,4,Y00107,1,1,0,WEU<EFBFBD><EFBFBD><EFBFBD>ӷ<EFBFBD><EFBFBD><EFBFBD>2
|
||||
8,WS,PG.WS.ThetaClampCylAct,Output,Td,4,Y00108,1,1,0,WS <20><> <20>н<EFBFBD><D0BD><EFBFBD><EFBFBD><EFBFBD><D7B6><EFBFBD>
|
||||
9,WS,PG.WS.ThetaBrakePressCylAct,Output,Td,4,Y00109,1,1,0,WS <20><>ɲ<EFBFBD><C9B2>ѹ<EFBFBD><D1B9><EFBFBD><EFBFBD><EFBFBD><EFBFBD><D7B6><EFBFBD>
|
||||
10,Stage,PG.Stage.LifterCyl1Act,Output,Td,4,Y00110,1,1,0,Stage <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>1<EFBFBD><31><EFBFBD><EFBFBD>
|
||||
11,Stage,PG.Stage.LifterCyl2Act,Output,Td,4,Y00111,1,1,0,Stage <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>2<EFBFBD><32><EFBFBD><EFBFBD>
|
||||
0,WZ,PG.WZ.StartButtonLight,Output,Td,5,Y00200,1,1,0,WZ <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ť<EFBFBD><C5A5>
|
||||
1,WZ,PG.WZ.StopButtonLight,Output,Td,5,Y00201,1,1,0,WZ ֹͣ<CDA3><D6B9>ť<EFBFBD><C5A5>
|
||||
2,WZ,PG.WZ.ResetButtonLight,Output,Td,5,Y00202,1,1,0,WZ <20><>λ<EFBFBD><CEBB>ť<EFBFBD><C5A5>
|
||||
3,WZ,PG.WZ.BlueButtonLight,Output,Td,5,Y00203,1,1,0,WZ <20><>ɫ<EFBFBD><C9AB>ť<EFBFBD><C5A5>
|
||||
4,WZ,PG.WZ.WorkLight1,Output,Td,5,Y00204,1,1,0,WZ <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>1
|
||||
6,EFEM,PG.EFEM.WorkLight1,Output,Td,5,Y00206,1,1,0,EFEM <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>1
|
||||
8,WZ,PG.WZ.StackLightRed,Output,Td,5,Y00208,1,1,0,WZ <20><>ɫ<EFBFBD><C9AB>-<2D><>
|
||||
9,WZ,PG.WZ.StackLightYellow,Output,Td,5,Y00209,1,1,0,WZ <20><>ɫ<EFBFBD><C9AB>-<2D><>
|
||||
10,WZ,PG.WZ.StackLightGreen,Output,Td,5,Y00210,1,1,0,WZ <20><>ɫ<EFBFBD><C9AB>-<2D><>
|
||||
11,WZ,PG.WZ.StackLightBlue,Output,Td,5,Y00211,1,1,0,WZ <20><>ɫ<EFBFBD><C9AB>-<2D><>
|
||||
12,WZ,PG.WZ.BuzzerAct,Output,Td,5,Y00212,1,1,0,WZ <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||
0,Stage,PG.Stage.BreakingTheVacuum1,Output,Td,6,Y00300,1,1,0,STAGE <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>1
|
||||
1,Stage,PG.Stage.BreakingTheVacuum2,Output,Td,6,Y00301,1,1,0,STAGE <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>2
|
||||
2,Stage,PG.Stage.BreakingTheVacuum3,Output,Td,6,Y00302,1,1,0,STAGE <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>3
|
||||
3,Stage,PG.Stage.BreakingTheVacuum4,Output,Td,6,Y00303,1,1,0,STAGE <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>4
|
||||
4,WEU,PG.WEU.TrayBreakVacuum1,Output,Td,6,Y00304,1,1,0,WEU <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>1
|
||||
5,WEU,PG.WEU.TrayBreakVacuum2,Output,Td,6,Y00305,1,1,0,WEU <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>2
|
||||
6,AxisZ,PG.AxisZ.Z2BondHeadBreakVacuum,Output,Td,6,Y00306,1,1,0,PHS Z2 <20>̾<EFBFBD>ͷ<EFBFBD><CDB7><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||
7,Stage,PG.Stage.Vacuum1,Output,Td,6,Y00307,1,1,0,STAGE <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>1
|
||||
8,Stage,PG.Stage.Vacuum2,Output,Td,6,Y00308,1,1,0,STAGE <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>2
|
||||
9,Stage,PG.Stage.Vacuum3,Output,Td,6,Y00309,1,1,0,STAGE <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>3
|
||||
10,Stage,PG.Stage.Vacuum4,Output,Td,6,Y00310,1,1,0,STAGE <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>4
|
||||
11,WEU,PG.WEU.TrayVacuum1,Output,Td,6,Y00311,1,1,0,WEU <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>1
|
||||
12,WEU,PG.WEU.TrayVacuum2,Output,Td,6,Y00312,1,1,0,WEU <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>2
|
||||
13,AxisZ,PG.AxisZ.Z2BondHeadVacuum,Output,Td,6,Y00313,1,1,0,PHS Z2 <20>̾<EFBFBD>ͷ<EFBFBD><CDB7><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||
1,WZ,PG.WZ.SafetyDoor1Open,Output,Td,7,Y00400,1,1,0,WZ <20><>ȫ<EFBFBD><C8AB>1<EFBFBD><31><EFBFBD><EFBFBD>
|
||||
2,WZ,PG.WZ.SafetyDoor2Open,Output,Td,7,Y00401,1,1,0,WZ <20><>ȫ<EFBFBD><C8AB>2<EFBFBD><32><EFBFBD><EFBFBD>
|
||||
3,WZ,PG.WZ.SafetyDoor3Open,Output,Td,7,Y00402,1,1,0,WZ <20><>ȫ<EFBFBD><C8AB>3<EFBFBD><33><EFBFBD><EFBFBD>
|
||||
4,WZ,PG.WZ.SafetyDoor4Open,Output,Td,7,Y00403,1,1,0,WZ <20><>ȫ<EFBFBD><C8AB>4<EFBFBD><34><EFBFBD><EFBFBD>
|
||||
|
@@ -0,0 +1,130 @@
|
||||
{
|
||||
"Rules": [
|
||||
{
|
||||
"WorkflowName": "SubstrateLoadFlow",
|
||||
"ParentActivityName": "*",
|
||||
"ActivityName": "*",
|
||||
"Stage": 0,
|
||||
"DisplayFlowName": "SubstrateLoadFlow"
|
||||
},
|
||||
{
|
||||
"WorkflowName": "SubstratePositionFlow",
|
||||
"ParentActivityName": "*",
|
||||
"ActivityName": "*",
|
||||
"Stage": 1,
|
||||
"DisplayFlowName": "SubstratePositionFlow"
|
||||
},
|
||||
{
|
||||
"WorkflowName": "WaferAngleAdjustmentFlow",
|
||||
"ParentActivityName": "*",
|
||||
"ActivityName": "*",
|
||||
"Stage": 1,
|
||||
"DisplayFlowName": "WaferAngleAdjustmentFlow"
|
||||
},
|
||||
{
|
||||
"WorkflowName": "DiePositionFlow",
|
||||
"ParentActivityName": "*",
|
||||
"ActivityName": "*",
|
||||
"Stage": 1,
|
||||
"DisplayFlowName": "DiePositionFlow"
|
||||
},
|
||||
{
|
||||
"WorkflowName": "DieTransferFlow",
|
||||
"ParentActivityName": "*",
|
||||
"ActivityName": "*",
|
||||
"Stage": 2,
|
||||
"DisplayFlowName": "DieTransferFlow"
|
||||
},
|
||||
{
|
||||
"WorkflowName": "DieRecheckFlow",
|
||||
"ParentActivityName": "*",
|
||||
"ActivityName": "*",
|
||||
"Stage": 3,
|
||||
"DisplayFlowName": "DieRecheckFlow"
|
||||
},
|
||||
{
|
||||
"WorkflowName": "SubstrateUnloadFlow",
|
||||
"ParentActivityName": "*",
|
||||
"ActivityName": "*",
|
||||
"Stage": 4,
|
||||
"DisplayFlowName": "SubstrateUnloadFlow"
|
||||
},
|
||||
{
|
||||
"WorkflowName": "AutoProduction",
|
||||
"ParentActivityName": "SubstrateLoadFlow",
|
||||
"ActivityName": "*",
|
||||
"Stage": 0,
|
||||
"DisplayFlowName": "SubstrateLoadFlow"
|
||||
},
|
||||
{
|
||||
"WorkflowName": "AutoProduction",
|
||||
"ParentActivityName": "DieAlignFlow",
|
||||
"ActivityName": "*SubstratePosition*",
|
||||
"Stage": 1,
|
||||
"DisplayFlowName": "SubstratePositionFlow"
|
||||
},
|
||||
{
|
||||
"WorkflowName": "AutoProduction",
|
||||
"ParentActivityName": "DieAlignFlow",
|
||||
"ActivityName": "WaferAngleAdjustmentFlow",
|
||||
"Stage": 1,
|
||||
"DisplayFlowName": "WaferAngleAdjustmentFlow"
|
||||
},
|
||||
{
|
||||
"WorkflowName": "AutoProduction",
|
||||
"ParentActivityName": "DieAlignFlow",
|
||||
"ActivityName": "DiePositionFlow",
|
||||
"Stage": 1,
|
||||
"DisplayFlowName": "DiePositionFlow"
|
||||
},
|
||||
{
|
||||
"WorkflowName": "AutoProduction",
|
||||
"ParentActivityName": "DieAlignFlow",
|
||||
"ActivityName": "*",
|
||||
"Stage": 1,
|
||||
"DisplayFlowName": "SubstratePositionFlow"
|
||||
},
|
||||
{
|
||||
"WorkflowName": "AutoProduction",
|
||||
"ParentActivityName": "DieBondFlow",
|
||||
"ActivityName": "*",
|
||||
"Stage": 2,
|
||||
"DisplayFlowName": "DieTransferFlow"
|
||||
},
|
||||
{
|
||||
"WorkflowName": "AutoProduction",
|
||||
"ParentActivityName": "InspectFlow",
|
||||
"ActivityName": "*",
|
||||
"Stage": 3,
|
||||
"DisplayFlowName": "DieRecheckFlow"
|
||||
},
|
||||
{
|
||||
"WorkflowName": "AutoProduction",
|
||||
"ParentActivityName": "SubstrateUnloadFlow",
|
||||
"ActivityName": "*",
|
||||
"Stage": 4,
|
||||
"DisplayFlowName": "SubstrateUnloadFlow"
|
||||
},
|
||||
{
|
||||
"WorkflowName": "AutoProduction",
|
||||
"ParentActivityName": "DieAlignFlow",
|
||||
"ActivityName": "SubstratePositionFlow",
|
||||
"Stage": 1,
|
||||
"DisplayFlowName": "SubstratePositionFlow"
|
||||
},
|
||||
{
|
||||
"WorkflowName": "AutoProduction",
|
||||
"ParentActivityName": "DieBondFlow",
|
||||
"ActivityName": "DieTransferFlow",
|
||||
"Stage": 2,
|
||||
"DisplayFlowName": "DieTransferFlow"
|
||||
},
|
||||
{
|
||||
"WorkflowName": "AutoProduction",
|
||||
"ParentActivityName": "InspectFlow",
|
||||
"ActivityName": "DieRecheckFlow",
|
||||
"Stage": 3,
|
||||
"DisplayFlowName": "DieRecheckFlow"
|
||||
}
|
||||
]
|
||||
}
|
||||
30
MX-PD-盘古 - new/PanGu.DieBonderApp/Configuration/Layout.xml
Normal file
30
MX-PD-盘古 - new/PanGu.DieBonderApp/Configuration/Layout.xml
Normal file
@@ -0,0 +1,30 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Layout Version="1.0.0.1" WindowHeight="1024" WindowWidth="1280" MachineId="12345678901234567">
|
||||
<Header Title="PG-A1">
|
||||
<HeaderItem Id="HideEMO"/>
|
||||
<HeaderItem Id="HideCIMStatus"/>
|
||||
</Header>
|
||||
<Body>
|
||||
<StatusBar>
|
||||
<StatusLight Name="设备一" LangName="Device" Binding="Device"></StatusLight>
|
||||
</StatusBar>
|
||||
<Pages>
|
||||
<Page Name="主页" LangName="PageHome" Target="Home">
|
||||
</Page>
|
||||
<Page Name="配方" LangName="PageRecipe" Target="Recipe">
|
||||
|
||||
</Page>
|
||||
<Page Name="参数设置" LangName="PageSettings" Target="PageSettings" DisabledState="SemiAutomatic;Automatic" UserRightId="PageSettings">
|
||||
</Page>
|
||||
<Page Name="设备维护" LangName="MenuDeviceMaint" Target="MenuDeviceMaint" DisabledState="SemiAutomatic;Automatic" UserRightId="PageSettings">
|
||||
</Page>
|
||||
<Page Name="标定与校准" LangName="PageCalib" Target="PageCalib" DisabledState="SemiAutomatic;Automatic" UserRightId="PageCalib">
|
||||
</Page>
|
||||
<Page Name="半自动" LangName="ManualModeOperation" Target="ManualOperate">
|
||||
|
||||
</Page>
|
||||
</Pages>
|
||||
|
||||
</Body>
|
||||
<Footer Target="Footer"/>
|
||||
</Layout>
|
||||
@@ -0,0 +1,581 @@
|
||||
<?xml version="1.0"?>
|
||||
<ArrayOfPersistenceObject xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
|
||||
<PersistenceObject xsi:type="AxisCardPO">
|
||||
<AlarmOffset>0</AlarmOffset>
|
||||
<CategoryName>AcsCard</CategoryName>
|
||||
<ID>2d23c400-ccf2-469a-add5-ae92a98a85e6</ID>
|
||||
<EnableLog>false</EnableLog>
|
||||
<ConfigPath>AxisCardPO.xml</ConfigPath>
|
||||
<AxisCardType>DEMO</AxisCardType>
|
||||
<AxisCardNum>0</AxisCardNum>
|
||||
<PortNo>0</PortNo>
|
||||
<ListAxisCardParaPO>
|
||||
<AxisCardParaPO>
|
||||
<AlarmOffset>0</AlarmOffset>
|
||||
<CategoryName>PHS-X1</CategoryName>
|
||||
<ID>3a9c772b-4a9c-4077-abbc-80fc038b81ee</ID>
|
||||
<EnableLog>false</EnableLog>
|
||||
<ConfigPath>AxisCardParaPO.xml</ConfigPath>
|
||||
<AxisCardId>0</AxisCardId>
|
||||
<AxisCardName>AcsCard</AxisCardName>
|
||||
<AxisCardNum>0</AxisCardNum>
|
||||
<AxisNum>0</AxisNum>
|
||||
<AxisName>PHS-X1</AxisName>
|
||||
<Direction>X</Direction>
|
||||
<GoogalCore>0</GoogalCore>
|
||||
<GoogalAxisNum>0</GoogalAxisNum>
|
||||
<GoolgalPosErr>0</GoolgalPosErr>
|
||||
<HomeDir>0</HomeDir>
|
||||
<EscapeStep>0</EscapeStep>
|
||||
<HomeMode>HOME_MODE_ERROR</HomeMode>
|
||||
<HomeCheck>false</HomeCheck>
|
||||
<MaxCheckPos>0.001</MaxCheckPos>
|
||||
</AxisCardParaPO>
|
||||
<AxisCardParaPO>
|
||||
<AlarmOffset>0</AlarmOffset>
|
||||
<CategoryName>PHS-X2</CategoryName>
|
||||
<ID>c83e5f81-ef2c-413c-ace9-24bc97c30b32</ID>
|
||||
<EnableLog>false</EnableLog>
|
||||
<ConfigPath>AxisCardParaPO.xml</ConfigPath>
|
||||
<AxisCardId>0</AxisCardId>
|
||||
<AxisCardName>AcsCard</AxisCardName>
|
||||
<AxisCardNum>0</AxisCardNum>
|
||||
<AxisNum>1</AxisNum>
|
||||
<AxisName>PHS-X2</AxisName>
|
||||
<Direction>X</Direction>
|
||||
<GoogalCore>0</GoogalCore>
|
||||
<GoogalAxisNum>0</GoogalAxisNum>
|
||||
<GoolgalPosErr>0</GoolgalPosErr>
|
||||
<HomeDir>0</HomeDir>
|
||||
<EscapeStep>0</EscapeStep>
|
||||
<HomeMode>HOME_MODE_ERROR</HomeMode>
|
||||
<HomeCheck>false</HomeCheck>
|
||||
<MaxCheckPos>0.001</MaxCheckPos>
|
||||
</AxisCardParaPO>
|
||||
<AxisCardParaPO>
|
||||
<AlarmOffset>0</AlarmOffset>
|
||||
<CategoryName>WS-X3</CategoryName>
|
||||
<ID>e0a2d6ed-2972-4595-a8dc-53a504187a9f</ID>
|
||||
<EnableLog>false</EnableLog>
|
||||
<ConfigPath>AxisCardParaPO.xml</ConfigPath>
|
||||
<AxisCardId>0</AxisCardId>
|
||||
<AxisCardName>AcsCard</AxisCardName>
|
||||
<AxisCardNum>0</AxisCardNum>
|
||||
<AxisNum>4</AxisNum>
|
||||
<AxisName>WS-X3</AxisName>
|
||||
<Direction>X</Direction>
|
||||
<GoogalCore>0</GoogalCore>
|
||||
<GoogalAxisNum>0</GoogalAxisNum>
|
||||
<GoolgalPosErr>0</GoolgalPosErr>
|
||||
<HomeDir>0</HomeDir>
|
||||
<EscapeStep>0</EscapeStep>
|
||||
<HomeMode>HOME_MODE_ERROR</HomeMode>
|
||||
<HomeCheck>false</HomeCheck>
|
||||
<MaxCheckPos>0.001</MaxCheckPos>
|
||||
</AxisCardParaPO>
|
||||
<AxisCardParaPO>
|
||||
<AlarmOffset>0</AlarmOffset>
|
||||
<CategoryName>PHS-Y1</CategoryName>
|
||||
<ID>4e145d2a-f7f7-4ce2-a5b0-919375a03d87</ID>
|
||||
<EnableLog>false</EnableLog>
|
||||
<ConfigPath>AxisCardParaPO.xml</ConfigPath>
|
||||
<AxisCardId>0</AxisCardId>
|
||||
<AxisCardName>AcsCard</AxisCardName>
|
||||
<AxisCardNum>0</AxisCardNum>
|
||||
<AxisNum>2</AxisNum>
|
||||
<AxisName>PHS-Y1</AxisName>
|
||||
<Direction>X</Direction>
|
||||
<GoogalCore>0</GoogalCore>
|
||||
<GoogalAxisNum>0</GoogalAxisNum>
|
||||
<GoolgalPosErr>0</GoolgalPosErr>
|
||||
<HomeDir>0</HomeDir>
|
||||
<EscapeStep>0</EscapeStep>
|
||||
<HomeMode>HOME_MODE_ERROR</HomeMode>
|
||||
<HomeCheck>false</HomeCheck>
|
||||
<MaxCheckPos>0.001</MaxCheckPos>
|
||||
</AxisCardParaPO>
|
||||
<AxisCardParaPO>
|
||||
<AlarmOffset>0</AlarmOffset>
|
||||
<CategoryName>WS-R</CategoryName>
|
||||
<ID>cebe7f5c-8cdd-47e8-906a-6083047a078d</ID>
|
||||
<EnableLog>false</EnableLog>
|
||||
<ConfigPath>AxisCardParaPO.xml</ConfigPath>
|
||||
<AxisCardId>0</AxisCardId>
|
||||
<AxisCardName>AcsCard</AxisCardName>
|
||||
<AxisCardNum>0</AxisCardNum>
|
||||
<AxisNum>6</AxisNum>
|
||||
<AxisName>WS-R</AxisName>
|
||||
<Direction>X</Direction>
|
||||
<GoogalCore>0</GoogalCore>
|
||||
<GoogalAxisNum>0</GoogalAxisNum>
|
||||
<GoolgalPosErr>0</GoolgalPosErr>
|
||||
<HomeDir>0</HomeDir>
|
||||
<EscapeStep>0</EscapeStep>
|
||||
<HomeMode>HOME_MODE_ERROR</HomeMode>
|
||||
<HomeCheck>false</HomeCheck>
|
||||
<MaxCheckPos>0.001</MaxCheckPos>
|
||||
</AxisCardParaPO>
|
||||
<AxisCardParaPO>
|
||||
<AlarmOffset>0</AlarmOffset>
|
||||
<CategoryName>SZ</CategoryName>
|
||||
<ID>ce1f8f65-3409-4124-9c9a-ba750c848e36</ID>
|
||||
<EnableLog>false</EnableLog>
|
||||
<ConfigPath>AxisCardParaPO.xml</ConfigPath>
|
||||
<AxisCardId>0</AxisCardId>
|
||||
<AxisCardName>AcsCard</AxisCardName>
|
||||
<AxisCardNum>0</AxisCardNum>
|
||||
<AxisNum>8</AxisNum>
|
||||
<AxisName>SZ</AxisName>
|
||||
<Direction>X</Direction>
|
||||
<GoogalCore>0</GoogalCore>
|
||||
<GoogalAxisNum>0</GoogalAxisNum>
|
||||
<GoolgalPosErr>0</GoolgalPosErr>
|
||||
<HomeDir>0</HomeDir>
|
||||
<EscapeStep>0</EscapeStep>
|
||||
<HomeMode>HOME_MODE_ERROR</HomeMode>
|
||||
<HomeCheck>false</HomeCheck>
|
||||
<MaxCheckPos>0.001</MaxCheckPos>
|
||||
</AxisCardParaPO>
|
||||
<AxisCardParaPO>
|
||||
<AlarmOffset>0</AlarmOffset>
|
||||
<CategoryName>Stage-Y3</CategoryName>
|
||||
<ID>05dfa6d1-401b-4a55-808b-5af2efeb358c</ID>
|
||||
<EnableLog>false</EnableLog>
|
||||
<ConfigPath>AxisCardParaPO.xml</ConfigPath>
|
||||
<AxisCardId>0</AxisCardId>
|
||||
<AxisCardName>AcsCard</AxisCardName>
|
||||
<AxisCardNum>0</AxisCardNum>
|
||||
<AxisNum>7</AxisNum>
|
||||
<AxisName>Stage-Y3</AxisName>
|
||||
<Direction>X</Direction>
|
||||
<GoogalCore>0</GoogalCore>
|
||||
<GoogalAxisNum>0</GoogalAxisNum>
|
||||
<GoolgalPosErr>0</GoolgalPosErr>
|
||||
<HomeDir>0</HomeDir>
|
||||
<EscapeStep>0</EscapeStep>
|
||||
<HomeMode>HOME_MODE_ERROR</HomeMode>
|
||||
<HomeCheck>false</HomeCheck>
|
||||
<MaxCheckPos>0.001</MaxCheckPos>
|
||||
</AxisCardParaPO>
|
||||
</ListAxisCardParaPO>
|
||||
<Version>1</Version>
|
||||
<Core>0</Core>
|
||||
<CrossCompensate>0</CrossCompensate>
|
||||
<IsServoSeparate>false</IsServoSeparate>
|
||||
</PersistenceObject>
|
||||
<PersistenceObject xsi:type="AxisCardPO">
|
||||
<AlarmOffset>0</AlarmOffset>
|
||||
<CategoryName>Plc</CategoryName>
|
||||
<ID>80a2e320-d4da-46a6-9f35-0a6d0996ea22</ID>
|
||||
<EnableLog>false</EnableLog>
|
||||
<ConfigPath>AxisCardPO.xml</ConfigPath>
|
||||
<AxisCardType>DEMO</AxisCardType>
|
||||
<AxisCardNum>0</AxisCardNum>
|
||||
<PortNo>0</PortNo>
|
||||
<ListAxisCardParaPO>
|
||||
<AxisCardParaPO>
|
||||
<AlarmOffset>0</AlarmOffset>
|
||||
<CategoryName>PHS-Z1</CategoryName>
|
||||
<ID>471e0395-0918-4e0b-b9cb-d0727281ef6c</ID>
|
||||
<EnableLog>false</EnableLog>
|
||||
<ConfigPath>AxisCardParaPO.xml</ConfigPath>
|
||||
<AxisCardId>0</AxisCardId>
|
||||
<AxisCardName>Plc</AxisCardName>
|
||||
<AxisCardNum>0</AxisCardNum>
|
||||
<AxisNum>0</AxisNum>
|
||||
<AxisName>PHS-Z1</AxisName>
|
||||
<Direction>Z</Direction>
|
||||
<GoogalCore>0</GoogalCore>
|
||||
<GoogalAxisNum>0</GoogalAxisNum>
|
||||
<GoolgalPosErr>0</GoolgalPosErr>
|
||||
<HomeDir>0</HomeDir>
|
||||
<EscapeStep>0</EscapeStep>
|
||||
<HomeMode>HOME_MODE_ERROR</HomeMode>
|
||||
<HomeCheck>false</HomeCheck>
|
||||
<MaxCheckPos>0.001</MaxCheckPos>
|
||||
</AxisCardParaPO>
|
||||
<AxisCardParaPO>
|
||||
<AlarmOffset>0</AlarmOffset>
|
||||
<CategoryName>PHS-Z3</CategoryName>
|
||||
<ID>5dd115ab-09a4-4bbb-9fdf-e9b76cc5e88e</ID>
|
||||
<EnableLog>false</EnableLog>
|
||||
<ConfigPath>AxisCardParaPO.xml</ConfigPath>
|
||||
<AxisCardId>0</AxisCardId>
|
||||
<AxisCardName>Plc</AxisCardName>
|
||||
<AxisCardNum>0</AxisCardNum>
|
||||
<AxisNum>1</AxisNum>
|
||||
<AxisName>PHS-Z3</AxisName>
|
||||
<Direction>Z</Direction>
|
||||
<GoogalCore>0</GoogalCore>
|
||||
<GoogalAxisNum>0</GoogalAxisNum>
|
||||
<GoolgalPosErr>0</GoolgalPosErr>
|
||||
<HomeDir>0</HomeDir>
|
||||
<EscapeStep>0</EscapeStep>
|
||||
<HomeMode>HOME_MODE_ERROR</HomeMode>
|
||||
<HomeCheck>false</HomeCheck>
|
||||
<MaxCheckPos>0.001</MaxCheckPos>
|
||||
</AxisCardParaPO>
|
||||
<AxisCardParaPO>
|
||||
<AlarmOffset>0</AlarmOffset>
|
||||
<CategoryName>PHS-Z4</CategoryName>
|
||||
<ID>e359bc21-c1e8-4e06-acdb-1df94ee7931b</ID>
|
||||
<EnableLog>false</EnableLog>
|
||||
<ConfigPath>AxisCardParaPO.xml</ConfigPath>
|
||||
<AxisCardId>0</AxisCardId>
|
||||
<AxisCardName>Plc</AxisCardName>
|
||||
<AxisCardNum>0</AxisCardNum>
|
||||
<AxisNum>10</AxisNum>
|
||||
<AxisName>PHS-Z4</AxisName>
|
||||
<Direction>X</Direction>
|
||||
<GoogalCore>0</GoogalCore>
|
||||
<GoogalAxisNum>0</GoogalAxisNum>
|
||||
<GoolgalPosErr>0</GoolgalPosErr>
|
||||
<HomeDir>0</HomeDir>
|
||||
<EscapeStep>0</EscapeStep>
|
||||
<HomeMode>HOME_MODE_ERROR</HomeMode>
|
||||
<HomeCheck>false</HomeCheck>
|
||||
<MaxCheckPos>0.001</MaxCheckPos>
|
||||
</AxisCardParaPO>
|
||||
<AxisCardParaPO>
|
||||
<AlarmOffset>0</AlarmOffset>
|
||||
<CategoryName>PHS-Z5</CategoryName>
|
||||
<ID>9d948211-59ae-498c-b124-531a69855752</ID>
|
||||
<EnableLog>false</EnableLog>
|
||||
<ConfigPath>AxisCardParaPO.xml</ConfigPath>
|
||||
<AxisCardId>0</AxisCardId>
|
||||
<AxisCardName>Plc</AxisCardName>
|
||||
<AxisCardNum>0</AxisCardNum>
|
||||
<AxisNum>2</AxisNum>
|
||||
<AxisName>PHS-Z5</AxisName>
|
||||
<Direction>X</Direction>
|
||||
<GoogalCore>0</GoogalCore>
|
||||
<GoogalAxisNum>0</GoogalAxisNum>
|
||||
<GoolgalPosErr>0</GoolgalPosErr>
|
||||
<HomeDir>0</HomeDir>
|
||||
<EscapeStep>0</EscapeStep>
|
||||
<HomeMode>HOME_MODE_ERROR</HomeMode>
|
||||
<HomeCheck>false</HomeCheck>
|
||||
<MaxCheckPos>0.001</MaxCheckPos>
|
||||
</AxisCardParaPO>
|
||||
<AxisCardParaPO>
|
||||
<AlarmOffset>0</AlarmOffset>
|
||||
<CategoryName>PHS-Z6</CategoryName>
|
||||
<ID>477c569a-e460-4c45-917f-a0744ebed5ec</ID>
|
||||
<EnableLog>false</EnableLog>
|
||||
<ConfigPath>AxisCardParaPO.xml</ConfigPath>
|
||||
<AxisCardId>0</AxisCardId>
|
||||
<AxisCardName>Plc</AxisCardName>
|
||||
<AxisCardNum>0</AxisCardNum>
|
||||
<AxisNum>11</AxisNum>
|
||||
<AxisName>PHS-Z6</AxisName>
|
||||
<Direction>X</Direction>
|
||||
<GoogalCore>0</GoogalCore>
|
||||
<GoogalAxisNum>0</GoogalAxisNum>
|
||||
<GoolgalPosErr>0</GoolgalPosErr>
|
||||
<HomeDir>0</HomeDir>
|
||||
<EscapeStep>0</EscapeStep>
|
||||
<HomeMode>HOME_MODE_ERROR</HomeMode>
|
||||
<HomeCheck>false</HomeCheck>
|
||||
<MaxCheckPos>0.001</MaxCheckPos>
|
||||
</AxisCardParaPO>
|
||||
<AxisCardParaPO>
|
||||
<AlarmOffset>0</AlarmOffset>
|
||||
<CategoryName>Stage-Z7</CategoryName>
|
||||
<ID>f761791c-8fb4-4a5b-8fef-0380e996e81f</ID>
|
||||
<EnableLog>false</EnableLog>
|
||||
<ConfigPath>AxisCardParaPO.xml</ConfigPath>
|
||||
<AxisCardId>0</AxisCardId>
|
||||
<AxisCardName>Plc</AxisCardName>
|
||||
<AxisCardNum>0</AxisCardNum>
|
||||
<AxisNum>7</AxisNum>
|
||||
<AxisName>Stage-Z7</AxisName>
|
||||
<Direction>X</Direction>
|
||||
<GoogalCore>0</GoogalCore>
|
||||
<GoogalAxisNum>0</GoogalAxisNum>
|
||||
<GoolgalPosErr>0</GoolgalPosErr>
|
||||
<HomeDir>0</HomeDir>
|
||||
<EscapeStep>0</EscapeStep>
|
||||
<HomeMode>HOME_MODE_ERROR</HomeMode>
|
||||
<HomeCheck>false</HomeCheck>
|
||||
<MaxCheckPos>0.001</MaxCheckPos>
|
||||
</AxisCardParaPO>
|
||||
<AxisCardParaPO>
|
||||
<AlarmOffset>0</AlarmOffset>
|
||||
<CategoryName>Stage-Z8</CategoryName>
|
||||
<ID>28a1caa3-01bc-48ed-8551-68829b280a6f</ID>
|
||||
<EnableLog>false</EnableLog>
|
||||
<ConfigPath>AxisCardParaPO.xml</ConfigPath>
|
||||
<AxisCardId>0</AxisCardId>
|
||||
<AxisCardName>Plc</AxisCardName>
|
||||
<AxisCardNum>0</AxisCardNum>
|
||||
<AxisNum>8</AxisNum>
|
||||
<AxisName>Stage-Z8</AxisName>
|
||||
<Direction>X</Direction>
|
||||
<GoogalCore>0</GoogalCore>
|
||||
<GoogalAxisNum>0</GoogalAxisNum>
|
||||
<GoolgalPosErr>0</GoolgalPosErr>
|
||||
<HomeDir>0</HomeDir>
|
||||
<EscapeStep>0</EscapeStep>
|
||||
<HomeMode>HOME_MODE_ERROR</HomeMode>
|
||||
<HomeCheck>false</HomeCheck>
|
||||
<MaxCheckPos>0.001</MaxCheckPos>
|
||||
</AxisCardParaPO>
|
||||
<AxisCardParaPO>
|
||||
<AlarmOffset>0</AlarmOffset>
|
||||
<CategoryName>Stage-Z9</CategoryName>
|
||||
<ID>71c8587a-1e85-4fa4-8809-14f00111a230</ID>
|
||||
<EnableLog>false</EnableLog>
|
||||
<ConfigPath>AxisCardParaPO.xml</ConfigPath>
|
||||
<AxisCardId>0</AxisCardId>
|
||||
<AxisCardName>Plc</AxisCardName>
|
||||
<AxisCardNum>0</AxisCardNum>
|
||||
<AxisNum>9</AxisNum>
|
||||
<AxisName>Stage-Z9</AxisName>
|
||||
<Direction>X</Direction>
|
||||
<GoogalCore>0</GoogalCore>
|
||||
<GoogalAxisNum>0</GoogalAxisNum>
|
||||
<GoolgalPosErr>0</GoolgalPosErr>
|
||||
<HomeDir>0</HomeDir>
|
||||
<EscapeStep>0</EscapeStep>
|
||||
<HomeMode>HOME_MODE_ERROR</HomeMode>
|
||||
<HomeCheck>false</HomeCheck>
|
||||
<MaxCheckPos>0.001</MaxCheckPos>
|
||||
</AxisCardParaPO>
|
||||
<AxisCardParaPO>
|
||||
<AlarmOffset>0</AlarmOffset>
|
||||
<CategoryName>Stage-Z10</CategoryName>
|
||||
<ID>fc66c8d2-c35f-46b5-9c14-f3a017311e86</ID>
|
||||
<EnableLog>false</EnableLog>
|
||||
<ConfigPath>AxisCardParaPO.xml</ConfigPath>
|
||||
<AxisCardId>0</AxisCardId>
|
||||
<AxisCardName>Plc</AxisCardName>
|
||||
<AxisCardNum>0</AxisCardNum>
|
||||
<AxisNum>14</AxisNum>
|
||||
<AxisName>Stage-Z10</AxisName>
|
||||
<Direction>X</Direction>
|
||||
<GoogalCore>0</GoogalCore>
|
||||
<GoogalAxisNum>0</GoogalAxisNum>
|
||||
<GoolgalPosErr>0</GoolgalPosErr>
|
||||
<HomeDir>0</HomeDir>
|
||||
<EscapeStep>0</EscapeStep>
|
||||
<HomeMode>HOME_MODE_ERROR</HomeMode>
|
||||
<HomeCheck>false</HomeCheck>
|
||||
<MaxCheckPos>0.001</MaxCheckPos>
|
||||
</AxisCardParaPO>
|
||||
<AxisCardParaPO>
|
||||
<AlarmOffset>0</AlarmOffset>
|
||||
<CategoryName>Stage-CV-Y4</CategoryName>
|
||||
<ID>6ebf862a-c91e-4bb2-a5b7-e67f307333b4</ID>
|
||||
<EnableLog>false</EnableLog>
|
||||
<ConfigPath>AxisCardParaPO.xml</ConfigPath>
|
||||
<AxisCardId>0</AxisCardId>
|
||||
<AxisCardName>Plc</AxisCardName>
|
||||
<AxisCardNum>0</AxisCardNum>
|
||||
<AxisNum>15</AxisNum>
|
||||
<AxisName>Stage-CV-Y4</AxisName>
|
||||
<Direction>X</Direction>
|
||||
<GoogalCore>0</GoogalCore>
|
||||
<GoogalAxisNum>0</GoogalAxisNum>
|
||||
<GoolgalPosErr>0</GoolgalPosErr>
|
||||
<HomeDir>0</HomeDir>
|
||||
<EscapeStep>0</EscapeStep>
|
||||
<HomeMode>HOME_MODE_ERROR</HomeMode>
|
||||
<HomeCheck>false</HomeCheck>
|
||||
<MaxCheckPos>0.001</MaxCheckPos>
|
||||
</AxisCardParaPO>
|
||||
<AxisCardParaPO>
|
||||
<AlarmOffset>0</AlarmOffset>
|
||||
<CategoryName>Stage-CV-Y5</CategoryName>
|
||||
<ID>e1cf2e06-fe51-4115-8ad2-2a0b3dc53c00</ID>
|
||||
<EnableLog>false</EnableLog>
|
||||
<ConfigPath>AxisCardParaPO.xml</ConfigPath>
|
||||
<AxisCardId>0</AxisCardId>
|
||||
<AxisCardName>Plc</AxisCardName>
|
||||
<AxisCardNum>0</AxisCardNum>
|
||||
<AxisNum>16</AxisNum>
|
||||
<AxisName>Stage-CV-Y5</AxisName>
|
||||
<Direction>X</Direction>
|
||||
<GoogalCore>0</GoogalCore>
|
||||
<GoogalAxisNum>0</GoogalAxisNum>
|
||||
<GoolgalPosErr>0</GoolgalPosErr>
|
||||
<HomeDir>0</HomeDir>
|
||||
<EscapeStep>0</EscapeStep>
|
||||
<HomeMode>HOME_MODE_ERROR</HomeMode>
|
||||
<HomeCheck>false</HomeCheck>
|
||||
<MaxCheckPos>0.001</MaxCheckPos>
|
||||
</AxisCardParaPO>
|
||||
<AxisCardParaPO>
|
||||
<AlarmOffset>0</AlarmOffset>
|
||||
<CategoryName>WEU-Z11</CategoryName>
|
||||
<ID>a765e366-03a3-451f-ab44-1e6129a6ac61</ID>
|
||||
<EnableLog>false</EnableLog>
|
||||
<ConfigPath>AxisCardParaPO.xml</ConfigPath>
|
||||
<AxisCardId>0</AxisCardId>
|
||||
<AxisCardName>Plc</AxisCardName>
|
||||
<AxisCardNum>0</AxisCardNum>
|
||||
<AxisNum>3</AxisNum>
|
||||
<AxisName>WEU-Z11</AxisName>
|
||||
<Direction>X</Direction>
|
||||
<GoogalCore>0</GoogalCore>
|
||||
<GoogalAxisNum>0</GoogalAxisNum>
|
||||
<GoolgalPosErr>0</GoolgalPosErr>
|
||||
<HomeDir>0</HomeDir>
|
||||
<EscapeStep>0</EscapeStep>
|
||||
<HomeMode>HOME_MODE_ERROR</HomeMode>
|
||||
<HomeCheck>false</HomeCheck>
|
||||
<MaxCheckPos>0.001</MaxCheckPos>
|
||||
</AxisCardParaPO>
|
||||
<AxisCardParaPO>
|
||||
<AlarmOffset>0</AlarmOffset>
|
||||
<CategoryName>WEU-Z12</CategoryName>
|
||||
<ID>a4c43082-6841-45b4-83f2-b89a952a6547</ID>
|
||||
<EnableLog>false</EnableLog>
|
||||
<ConfigPath>AxisCardParaPO.xml</ConfigPath>
|
||||
<AxisCardId>0</AxisCardId>
|
||||
<AxisCardName>Plc</AxisCardName>
|
||||
<AxisCardNum>0</AxisCardNum>
|
||||
<AxisNum>4</AxisNum>
|
||||
<AxisName>WEU-Z12</AxisName>
|
||||
<Direction>X</Direction>
|
||||
<GoogalCore>0</GoogalCore>
|
||||
<GoogalAxisNum>0</GoogalAxisNum>
|
||||
<GoolgalPosErr>0</GoolgalPosErr>
|
||||
<HomeDir>0</HomeDir>
|
||||
<EscapeStep>0</EscapeStep>
|
||||
<HomeMode>HOME_MODE_ERROR</HomeMode>
|
||||
<HomeCheck>false</HomeCheck>
|
||||
<MaxCheckPos>0.001</MaxCheckPos>
|
||||
</AxisCardParaPO>
|
||||
<AxisCardParaPO>
|
||||
<AlarmOffset>0</AlarmOffset>
|
||||
<CategoryName>WEU-Y6</CategoryName>
|
||||
<ID>670409e3-1e19-45c8-94b8-1f3fb1905dc2</ID>
|
||||
<EnableLog>false</EnableLog>
|
||||
<ConfigPath>AxisCardParaPO.xml</ConfigPath>
|
||||
<AxisCardId>0</AxisCardId>
|
||||
<AxisCardName>Plc</AxisCardName>
|
||||
<AxisCardNum>0</AxisCardNum>
|
||||
<AxisNum>5</AxisNum>
|
||||
<AxisName>WEU-Y6</AxisName>
|
||||
<Direction>X</Direction>
|
||||
<GoogalCore>0</GoogalCore>
|
||||
<GoogalAxisNum>0</GoogalAxisNum>
|
||||
<GoolgalPosErr>0</GoolgalPosErr>
|
||||
<HomeDir>0</HomeDir>
|
||||
<EscapeStep>0</EscapeStep>
|
||||
<HomeMode>HOME_MODE_ERROR</HomeMode>
|
||||
<HomeCheck>false</HomeCheck>
|
||||
<MaxCheckPos>0.001</MaxCheckPos>
|
||||
</AxisCardParaPO>
|
||||
<AxisCardParaPO>
|
||||
<AlarmOffset>0</AlarmOffset>
|
||||
<CategoryName>CV-Z13</CategoryName>
|
||||
<ID>eb009565-40bf-4923-9b9b-fdf483dc1532</ID>
|
||||
<EnableLog>false</EnableLog>
|
||||
<ConfigPath>AxisCardParaPO.xml</ConfigPath>
|
||||
<AxisCardId>0</AxisCardId>
|
||||
<AxisCardName>Plc</AxisCardName>
|
||||
<AxisCardNum>0</AxisCardNum>
|
||||
<AxisNum>6</AxisNum>
|
||||
<AxisName>CV-Z13</AxisName>
|
||||
<Direction>X</Direction>
|
||||
<GoogalCore>0</GoogalCore>
|
||||
<GoogalAxisNum>0</GoogalAxisNum>
|
||||
<GoolgalPosErr>0</GoolgalPosErr>
|
||||
<HomeDir>0</HomeDir>
|
||||
<EscapeStep>0</EscapeStep>
|
||||
<HomeMode>HOME_MODE_ERROR</HomeMode>
|
||||
<HomeCheck>false</HomeCheck>
|
||||
<MaxCheckPos>0.001</MaxCheckPos>
|
||||
</AxisCardParaPO>
|
||||
<AxisCardParaPO>
|
||||
<AlarmOffset>0</AlarmOffset>
|
||||
<CategoryName>CV-Y7</CategoryName>
|
||||
<ID>d75ee50a-ba99-4ec1-bb36-6e65cbd84180</ID>
|
||||
<EnableLog>false</EnableLog>
|
||||
<ConfigPath>AxisCardParaPO.xml</ConfigPath>
|
||||
<AxisCardId>0</AxisCardId>
|
||||
<AxisCardName>Plc</AxisCardName>
|
||||
<AxisCardNum>0</AxisCardNum>
|
||||
<AxisNum>18</AxisNum>
|
||||
<AxisName>CV-Y7</AxisName>
|
||||
<Direction>X</Direction>
|
||||
<GoogalCore>0</GoogalCore>
|
||||
<GoogalAxisNum>0</GoogalAxisNum>
|
||||
<GoolgalPosErr>0</GoolgalPosErr>
|
||||
<HomeDir>0</HomeDir>
|
||||
<EscapeStep>0</EscapeStep>
|
||||
<HomeMode>HOME_MODE_ERROR</HomeMode>
|
||||
<HomeCheck>false</HomeCheck>
|
||||
<MaxCheckPos>0.001</MaxCheckPos>
|
||||
</AxisCardParaPO>
|
||||
<AxisCardParaPO>
|
||||
<AlarmOffset>0</AlarmOffset>
|
||||
<CategoryName>CV-Y8</CategoryName>
|
||||
<ID>8845c4e8-4d09-4f0a-b073-1b29e1ca59e6</ID>
|
||||
<EnableLog>false</EnableLog>
|
||||
<ConfigPath>AxisCardParaPO.xml</ConfigPath>
|
||||
<AxisCardId>0</AxisCardId>
|
||||
<AxisCardName>Plc</AxisCardName>
|
||||
<AxisCardNum>0</AxisCardNum>
|
||||
<AxisNum>19</AxisNum>
|
||||
<AxisName>CV-Y8</AxisName>
|
||||
<Direction>X</Direction>
|
||||
<GoogalCore>0</GoogalCore>
|
||||
<GoogalAxisNum>0</GoogalAxisNum>
|
||||
<GoolgalPosErr>0</GoolgalPosErr>
|
||||
<HomeDir>0</HomeDir>
|
||||
<EscapeStep>0</EscapeStep>
|
||||
<HomeMode>HOME_MODE_ERROR</HomeMode>
|
||||
<HomeCheck>false</HomeCheck>
|
||||
<MaxCheckPos>0.001</MaxCheckPos>
|
||||
</AxisCardParaPO>
|
||||
<AxisCardParaPO>
|
||||
<AlarmOffset>0</AlarmOffset>
|
||||
<CategoryName>CV-Y9</CategoryName>
|
||||
<ID>4970be79-b46a-4004-84bf-82e922fb5cb8</ID>
|
||||
<EnableLog>false</EnableLog>
|
||||
<ConfigPath>AxisCardParaPO.xml</ConfigPath>
|
||||
<AxisCardId>0</AxisCardId>
|
||||
<AxisCardName>Plc</AxisCardName>
|
||||
<AxisCardNum>0</AxisCardNum>
|
||||
<AxisNum>20</AxisNum>
|
||||
<AxisName>CV-Y9</AxisName>
|
||||
<Direction>X</Direction>
|
||||
<GoogalCore>0</GoogalCore>
|
||||
<GoogalAxisNum>0</GoogalAxisNum>
|
||||
<GoolgalPosErr>0</GoolgalPosErr>
|
||||
<HomeDir>0</HomeDir>
|
||||
<EscapeStep>0</EscapeStep>
|
||||
<HomeMode>HOME_MODE_ERROR</HomeMode>
|
||||
<HomeCheck>false</HomeCheck>
|
||||
<MaxCheckPos>0.001</MaxCheckPos>
|
||||
</AxisCardParaPO>
|
||||
<AxisCardParaPO>
|
||||
<AlarmOffset>0</AlarmOffset>
|
||||
<CategoryName>CV-Y10</CategoryName>
|
||||
<ID>36583278-40bd-48ad-a749-02b4e58dcbca</ID>
|
||||
<EnableLog>false</EnableLog>
|
||||
<ConfigPath>AxisCardParaPO.xml</ConfigPath>
|
||||
<AxisCardId>0</AxisCardId>
|
||||
<AxisCardName>Plc</AxisCardName>
|
||||
<AxisCardNum>0</AxisCardNum>
|
||||
<AxisNum>21</AxisNum>
|
||||
<AxisName>CV-Y10</AxisName>
|
||||
<Direction>X</Direction>
|
||||
<GoogalCore>0</GoogalCore>
|
||||
<GoogalAxisNum>0</GoogalAxisNum>
|
||||
<GoolgalPosErr>0</GoolgalPosErr>
|
||||
<HomeDir>0</HomeDir>
|
||||
<EscapeStep>0</EscapeStep>
|
||||
<HomeMode>HOME_MODE_ERROR</HomeMode>
|
||||
<HomeCheck>false</HomeCheck>
|
||||
<MaxCheckPos>0.001</MaxCheckPos>
|
||||
</AxisCardParaPO>
|
||||
</ListAxisCardParaPO>
|
||||
<Version>1</Version>
|
||||
<Core>0</Core>
|
||||
<CrossCompensate>0</CrossCompensate>
|
||||
<IsServoSeparate>false</IsServoSeparate>
|
||||
</PersistenceObject>
|
||||
</ArrayOfPersistenceObject>
|
||||
@@ -0,0 +1,887 @@
|
||||
<?xml version="1.0"?>
|
||||
<ArrayOfPersistenceObject xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
|
||||
<PersistenceObject xsi:type="AxisMoveParaPO">
|
||||
<AlarmOffset>0</AlarmOffset>
|
||||
<CategoryName>PHS-Z1</CategoryName>
|
||||
<ID>aef7d248-e5cc-4753-b1ea-c2d1c971d643</ID>
|
||||
<EnableLog>false</EnableLog>
|
||||
<ConfigPath>AxisMoveParaPO.xml</ConfigPath>
|
||||
<CardNum>0</CardNum>
|
||||
<AxisNum>1</AxisNum>
|
||||
<MaxVel>50</MaxVel>
|
||||
<HomeSpeed>5</HomeSpeed>
|
||||
<HomeLabel>Homing</HomeLabel>
|
||||
<HomeBufferId>0</HomeBufferId>
|
||||
<StepDistance>0</StepDistance>
|
||||
<MovePara>
|
||||
<Velocity>10</Velocity>
|
||||
<Accelerate>100</Accelerate>
|
||||
<Decelerate>100</Decelerate>
|
||||
<Jerk>1000</Jerk>
|
||||
<Inc>0</Inc>
|
||||
</MovePara>
|
||||
<LowJogPara>
|
||||
<Velocity>1</Velocity>
|
||||
<Accelerate>10</Accelerate>
|
||||
</LowJogPara>
|
||||
<MidJogPara>
|
||||
<Velocity>10</Velocity>
|
||||
<Accelerate>100</Accelerate>
|
||||
</MidJogPara>
|
||||
<HighJogPara>
|
||||
<Velocity>50</Velocity>
|
||||
<Accelerate>500</Accelerate>
|
||||
</HighJogPara>
|
||||
<AxisBand>0</AxisBand>
|
||||
</PersistenceObject>
|
||||
<PersistenceObject xsi:type="AxisMoveParaPO">
|
||||
<AlarmOffset>0</AlarmOffset>
|
||||
<CategoryName>PHS-Z3</CategoryName>
|
||||
<ID>cfae0e29-b625-49b0-a4d1-3738ba6919cd</ID>
|
||||
<EnableLog>false</EnableLog>
|
||||
<ConfigPath>AxisMoveParaPO.xml</ConfigPath>
|
||||
<CardNum>0</CardNum>
|
||||
<AxisNum>0</AxisNum>
|
||||
<MaxVel>50</MaxVel>
|
||||
<HomeSpeed>5</HomeSpeed>
|
||||
<HomeLabel>Homing</HomeLabel>
|
||||
<HomeBufferId>0</HomeBufferId>
|
||||
<StepDistance>0</StepDistance>
|
||||
<MovePara>
|
||||
<Velocity>10</Velocity>
|
||||
<Accelerate>100</Accelerate>
|
||||
<Decelerate>100</Decelerate>
|
||||
<Jerk>1000</Jerk>
|
||||
<Inc>0</Inc>
|
||||
</MovePara>
|
||||
<LowJogPara>
|
||||
<Velocity>1</Velocity>
|
||||
<Accelerate>10</Accelerate>
|
||||
</LowJogPara>
|
||||
<MidJogPara>
|
||||
<Velocity>10</Velocity>
|
||||
<Accelerate>100</Accelerate>
|
||||
</MidJogPara>
|
||||
<HighJogPara>
|
||||
<Velocity>50</Velocity>
|
||||
<Accelerate>500</Accelerate>
|
||||
</HighJogPara>
|
||||
<AxisBand>0</AxisBand>
|
||||
</PersistenceObject>
|
||||
<PersistenceObject xsi:type="AxisMoveParaPO">
|
||||
<AlarmOffset>0</AlarmOffset>
|
||||
<CategoryName>PHS-Z4</CategoryName>
|
||||
<ID>f9f1ed8a-cd73-49a7-bec8-018d7b498772</ID>
|
||||
<EnableLog>false</EnableLog>
|
||||
<ConfigPath>AxisMoveParaPO.xml</ConfigPath>
|
||||
<CardNum>0</CardNum>
|
||||
<AxisNum>3</AxisNum>
|
||||
<MaxVel>50</MaxVel>
|
||||
<HomeSpeed>5</HomeSpeed>
|
||||
<HomeLabel>Homing</HomeLabel>
|
||||
<HomeBufferId>0</HomeBufferId>
|
||||
<StepDistance>0</StepDistance>
|
||||
<MovePara>
|
||||
<Velocity>10</Velocity>
|
||||
<Accelerate>100</Accelerate>
|
||||
<Decelerate>100</Decelerate>
|
||||
<Jerk>1000</Jerk>
|
||||
<Inc>0</Inc>
|
||||
</MovePara>
|
||||
<LowJogPara>
|
||||
<Velocity>1</Velocity>
|
||||
<Accelerate>10</Accelerate>
|
||||
</LowJogPara>
|
||||
<MidJogPara>
|
||||
<Velocity>10</Velocity>
|
||||
<Accelerate>100</Accelerate>
|
||||
</MidJogPara>
|
||||
<HighJogPara>
|
||||
<Velocity>50</Velocity>
|
||||
<Accelerate>500</Accelerate>
|
||||
</HighJogPara>
|
||||
<AxisBand>0</AxisBand>
|
||||
</PersistenceObject>
|
||||
<PersistenceObject xsi:type="AxisMoveParaPO">
|
||||
<AlarmOffset>0</AlarmOffset>
|
||||
<CategoryName>PHS-Z5</CategoryName>
|
||||
<ID>8514cd0e-49f9-421f-9f0b-a8080ddcf7de</ID>
|
||||
<EnableLog>false</EnableLog>
|
||||
<ConfigPath>AxisMoveParaPO.xml</ConfigPath>
|
||||
<CardNum>0</CardNum>
|
||||
<AxisNum>4</AxisNum>
|
||||
<MaxVel>50</MaxVel>
|
||||
<HomeSpeed>5</HomeSpeed>
|
||||
<HomeLabel>Homing</HomeLabel>
|
||||
<HomeBufferId>0</HomeBufferId>
|
||||
<StepDistance>0</StepDistance>
|
||||
<MovePara>
|
||||
<Velocity>10</Velocity>
|
||||
<Accelerate>100</Accelerate>
|
||||
<Decelerate>100</Decelerate>
|
||||
<Jerk>1000</Jerk>
|
||||
<Inc>0</Inc>
|
||||
</MovePara>
|
||||
<LowJogPara>
|
||||
<Velocity>1</Velocity>
|
||||
<Accelerate>10</Accelerate>
|
||||
</LowJogPara>
|
||||
<MidJogPara>
|
||||
<Velocity>10</Velocity>
|
||||
<Accelerate>100</Accelerate>
|
||||
</MidJogPara>
|
||||
<HighJogPara>
|
||||
<Velocity>50</Velocity>
|
||||
<Accelerate>500</Accelerate>
|
||||
</HighJogPara>
|
||||
<AxisBand>0</AxisBand>
|
||||
</PersistenceObject>
|
||||
<PersistenceObject xsi:type="AxisMoveParaPO">
|
||||
<AlarmOffset>0</AlarmOffset>
|
||||
<CategoryName>PHS-Z6</CategoryName>
|
||||
<ID>42482b11-f96c-4684-ba14-ed3dd1f595a0</ID>
|
||||
<EnableLog>false</EnableLog>
|
||||
<ConfigPath>AxisMoveParaPO.xml</ConfigPath>
|
||||
<CardNum>0</CardNum>
|
||||
<AxisNum>5</AxisNum>
|
||||
<MaxVel>50</MaxVel>
|
||||
<HomeSpeed>5</HomeSpeed>
|
||||
<HomeLabel>Homing</HomeLabel>
|
||||
<HomeBufferId>0</HomeBufferId>
|
||||
<StepDistance>0</StepDistance>
|
||||
<MovePara>
|
||||
<Velocity>10</Velocity>
|
||||
<Accelerate>100</Accelerate>
|
||||
<Decelerate>100</Decelerate>
|
||||
<Jerk>1000</Jerk>
|
||||
<Inc>0</Inc>
|
||||
</MovePara>
|
||||
<LowJogPara>
|
||||
<Velocity>1</Velocity>
|
||||
<Accelerate>10</Accelerate>
|
||||
</LowJogPara>
|
||||
<MidJogPara>
|
||||
<Velocity>10</Velocity>
|
||||
<Accelerate>100</Accelerate>
|
||||
</MidJogPara>
|
||||
<HighJogPara>
|
||||
<Velocity>50</Velocity>
|
||||
<Accelerate>500</Accelerate>
|
||||
</HighJogPara>
|
||||
<AxisBand>0</AxisBand>
|
||||
</PersistenceObject>
|
||||
<PersistenceObject xsi:type="AxisMoveParaPO">
|
||||
<AlarmOffset>0</AlarmOffset>
|
||||
<CategoryName>Stage-Z7</CategoryName>
|
||||
<ID>380f6bc0-35dc-4224-a792-e32aa26a22d0</ID>
|
||||
<EnableLog>false</EnableLog>
|
||||
<ConfigPath>AxisMoveParaPO.xml</ConfigPath>
|
||||
<CardNum>0</CardNum>
|
||||
<AxisNum>8</AxisNum>
|
||||
<MaxVel>50</MaxVel>
|
||||
<HomeSpeed>5</HomeSpeed>
|
||||
<HomeLabel>Homing</HomeLabel>
|
||||
<HomeBufferId>0</HomeBufferId>
|
||||
<StepDistance>0</StepDistance>
|
||||
<MovePara>
|
||||
<Velocity>10</Velocity>
|
||||
<Accelerate>100</Accelerate>
|
||||
<Decelerate>100</Decelerate>
|
||||
<Jerk>1000</Jerk>
|
||||
<Inc>0</Inc>
|
||||
</MovePara>
|
||||
<LowJogPara>
|
||||
<Velocity>1</Velocity>
|
||||
<Accelerate>10</Accelerate>
|
||||
</LowJogPara>
|
||||
<MidJogPara>
|
||||
<Velocity>10</Velocity>
|
||||
<Accelerate>100</Accelerate>
|
||||
</MidJogPara>
|
||||
<HighJogPara>
|
||||
<Velocity>50</Velocity>
|
||||
<Accelerate>500</Accelerate>
|
||||
</HighJogPara>
|
||||
<AxisBand>0</AxisBand>
|
||||
</PersistenceObject>
|
||||
<PersistenceObject xsi:type="AxisMoveParaPO">
|
||||
<AlarmOffset>0</AlarmOffset>
|
||||
<CategoryName>Stage-Z8</CategoryName>
|
||||
<ID>442a647d-bdc0-45b6-856d-114988b332e4</ID>
|
||||
<EnableLog>false</EnableLog>
|
||||
<ConfigPath>AxisMoveParaPO.xml</ConfigPath>
|
||||
<CardNum>0</CardNum>
|
||||
<AxisNum>9</AxisNum>
|
||||
<MaxVel>50</MaxVel>
|
||||
<HomeSpeed>5</HomeSpeed>
|
||||
<HomeLabel>Homing</HomeLabel>
|
||||
<HomeBufferId>0</HomeBufferId>
|
||||
<StepDistance>0</StepDistance>
|
||||
<MovePara>
|
||||
<Velocity>10</Velocity>
|
||||
<Accelerate>100</Accelerate>
|
||||
<Decelerate>100</Decelerate>
|
||||
<Jerk>1000</Jerk>
|
||||
<Inc>0</Inc>
|
||||
</MovePara>
|
||||
<LowJogPara>
|
||||
<Velocity>1</Velocity>
|
||||
<Accelerate>10</Accelerate>
|
||||
</LowJogPara>
|
||||
<MidJogPara>
|
||||
<Velocity>10</Velocity>
|
||||
<Accelerate>100</Accelerate>
|
||||
</MidJogPara>
|
||||
<HighJogPara>
|
||||
<Velocity>50</Velocity>
|
||||
<Accelerate>500</Accelerate>
|
||||
</HighJogPara>
|
||||
<AxisBand>0</AxisBand>
|
||||
</PersistenceObject>
|
||||
<PersistenceObject xsi:type="AxisMoveParaPO">
|
||||
<AlarmOffset>0</AlarmOffset>
|
||||
<CategoryName>Stage-Z9</CategoryName>
|
||||
<ID>25396ce5-106a-4a10-a7d8-98fefc970d0b</ID>
|
||||
<EnableLog>false</EnableLog>
|
||||
<ConfigPath>AxisMoveParaPO.xml</ConfigPath>
|
||||
<CardNum>0</CardNum>
|
||||
<AxisNum>10</AxisNum>
|
||||
<MaxVel>50</MaxVel>
|
||||
<HomeSpeed>5</HomeSpeed>
|
||||
<HomeLabel>Homing</HomeLabel>
|
||||
<HomeBufferId>0</HomeBufferId>
|
||||
<StepDistance>0</StepDistance>
|
||||
<MovePara>
|
||||
<Velocity>10</Velocity>
|
||||
<Accelerate>100</Accelerate>
|
||||
<Decelerate>100</Decelerate>
|
||||
<Jerk>1000</Jerk>
|
||||
<Inc>0</Inc>
|
||||
</MovePara>
|
||||
<LowJogPara>
|
||||
<Velocity>1</Velocity>
|
||||
<Accelerate>10</Accelerate>
|
||||
</LowJogPara>
|
||||
<MidJogPara>
|
||||
<Velocity>10</Velocity>
|
||||
<Accelerate>100</Accelerate>
|
||||
</MidJogPara>
|
||||
<HighJogPara>
|
||||
<Velocity>50</Velocity>
|
||||
<Accelerate>500</Accelerate>
|
||||
</HighJogPara>
|
||||
<AxisBand>0</AxisBand>
|
||||
</PersistenceObject>
|
||||
<PersistenceObject xsi:type="AxisMoveParaPO">
|
||||
<AlarmOffset>0</AlarmOffset>
|
||||
<CategoryName>Stage-Z10</CategoryName>
|
||||
<ID>8e10a13b-e6bf-4b1d-bc7c-86442fa85f7d</ID>
|
||||
<EnableLog>false</EnableLog>
|
||||
<ConfigPath>AxisMoveParaPO.xml</ConfigPath>
|
||||
<CardNum>0</CardNum>
|
||||
<AxisNum>11</AxisNum>
|
||||
<MaxVel>50</MaxVel>
|
||||
<HomeSpeed>5</HomeSpeed>
|
||||
<HomeLabel>Homing</HomeLabel>
|
||||
<HomeBufferId>0</HomeBufferId>
|
||||
<StepDistance>0</StepDistance>
|
||||
<MovePara>
|
||||
<Velocity>10</Velocity>
|
||||
<Accelerate>100</Accelerate>
|
||||
<Decelerate>100</Decelerate>
|
||||
<Jerk>1000</Jerk>
|
||||
<Inc>0</Inc>
|
||||
</MovePara>
|
||||
<LowJogPara>
|
||||
<Velocity>1</Velocity>
|
||||
<Accelerate>10</Accelerate>
|
||||
</LowJogPara>
|
||||
<MidJogPara>
|
||||
<Velocity>10</Velocity>
|
||||
<Accelerate>100</Accelerate>
|
||||
</MidJogPara>
|
||||
<HighJogPara>
|
||||
<Velocity>50</Velocity>
|
||||
<Accelerate>500</Accelerate>
|
||||
</HighJogPara>
|
||||
<AxisBand>0</AxisBand>
|
||||
</PersistenceObject>
|
||||
<PersistenceObject xsi:type="AxisMoveParaPO">
|
||||
<AlarmOffset>0</AlarmOffset>
|
||||
<CategoryName>Stage-CV-Y4</CategoryName>
|
||||
<ID>1d5273bf-4cd5-485e-a9d4-b6782b81dc76</ID>
|
||||
<EnableLog>false</EnableLog>
|
||||
<ConfigPath>AxisMoveParaPO.xml</ConfigPath>
|
||||
<CardNum>0</CardNum>
|
||||
<AxisNum>12</AxisNum>
|
||||
<MaxVel>50</MaxVel>
|
||||
<HomeSpeed>5</HomeSpeed>
|
||||
<HomeLabel>Homing</HomeLabel>
|
||||
<HomeBufferId>0</HomeBufferId>
|
||||
<StepDistance>0</StepDistance>
|
||||
<MovePara>
|
||||
<Velocity>10</Velocity>
|
||||
<Accelerate>100</Accelerate>
|
||||
<Decelerate>100</Decelerate>
|
||||
<Jerk>1000</Jerk>
|
||||
<Inc>0</Inc>
|
||||
</MovePara>
|
||||
<LowJogPara>
|
||||
<Velocity>1</Velocity>
|
||||
<Accelerate>10</Accelerate>
|
||||
</LowJogPara>
|
||||
<MidJogPara>
|
||||
<Velocity>10</Velocity>
|
||||
<Accelerate>100</Accelerate>
|
||||
</MidJogPara>
|
||||
<HighJogPara>
|
||||
<Velocity>50</Velocity>
|
||||
<Accelerate>500</Accelerate>
|
||||
</HighJogPara>
|
||||
<AxisBand>0</AxisBand>
|
||||
</PersistenceObject>
|
||||
<PersistenceObject xsi:type="AxisMoveParaPO">
|
||||
<AlarmOffset>0</AlarmOffset>
|
||||
<CategoryName>Stage-CV-Y5</CategoryName>
|
||||
<ID>cc9ee33f-ba66-4718-8894-8941f54d9927</ID>
|
||||
<EnableLog>false</EnableLog>
|
||||
<ConfigPath>AxisMoveParaPO.xml</ConfigPath>
|
||||
<CardNum>0</CardNum>
|
||||
<AxisNum>13</AxisNum>
|
||||
<MaxVel>50</MaxVel>
|
||||
<HomeSpeed>5</HomeSpeed>
|
||||
<HomeLabel>Homing</HomeLabel>
|
||||
<HomeBufferId>0</HomeBufferId>
|
||||
<StepDistance>0</StepDistance>
|
||||
<MovePara>
|
||||
<Velocity>10</Velocity>
|
||||
<Accelerate>100</Accelerate>
|
||||
<Decelerate>100</Decelerate>
|
||||
<Jerk>1000</Jerk>
|
||||
<Inc>0</Inc>
|
||||
</MovePara>
|
||||
<LowJogPara>
|
||||
<Velocity>1</Velocity>
|
||||
<Accelerate>10</Accelerate>
|
||||
</LowJogPara>
|
||||
<MidJogPara>
|
||||
<Velocity>10</Velocity>
|
||||
<Accelerate>100</Accelerate>
|
||||
</MidJogPara>
|
||||
<HighJogPara>
|
||||
<Velocity>50</Velocity>
|
||||
<Accelerate>500</Accelerate>
|
||||
</HighJogPara>
|
||||
<AxisBand>0</AxisBand>
|
||||
</PersistenceObject>
|
||||
<PersistenceObject xsi:type="AxisMoveParaPO">
|
||||
<AlarmOffset>0</AlarmOffset>
|
||||
<CategoryName>WEU-Z11</CategoryName>
|
||||
<ID>cb2a3d76-1f2e-484a-88d7-0ed23b73ab9d</ID>
|
||||
<EnableLog>false</EnableLog>
|
||||
<ConfigPath>AxisMoveParaPO.xml</ConfigPath>
|
||||
<CardNum>0</CardNum>
|
||||
<AxisNum>14</AxisNum>
|
||||
<MaxVel>50</MaxVel>
|
||||
<HomeSpeed>5</HomeSpeed>
|
||||
<HomeLabel>Homing</HomeLabel>
|
||||
<HomeBufferId>0</HomeBufferId>
|
||||
<StepDistance>0</StepDistance>
|
||||
<MovePara>
|
||||
<Velocity>10</Velocity>
|
||||
<Accelerate>100</Accelerate>
|
||||
<Decelerate>100</Decelerate>
|
||||
<Jerk>1000</Jerk>
|
||||
<Inc>0</Inc>
|
||||
</MovePara>
|
||||
<LowJogPara>
|
||||
<Velocity>1</Velocity>
|
||||
<Accelerate>10</Accelerate>
|
||||
</LowJogPara>
|
||||
<MidJogPara>
|
||||
<Velocity>10</Velocity>
|
||||
<Accelerate>100</Accelerate>
|
||||
</MidJogPara>
|
||||
<HighJogPara>
|
||||
<Velocity>50</Velocity>
|
||||
<Accelerate>500</Accelerate>
|
||||
</HighJogPara>
|
||||
<AxisBand>0</AxisBand>
|
||||
</PersistenceObject>
|
||||
<PersistenceObject xsi:type="AxisMoveParaPO">
|
||||
<AlarmOffset>0</AlarmOffset>
|
||||
<CategoryName>WEU-Z12</CategoryName>
|
||||
<ID>cb2a3d76-1f2e-484a-88d7-0ed23b73ab9d</ID>
|
||||
<EnableLog>false</EnableLog>
|
||||
<ConfigPath>AxisMoveParaPO.xml</ConfigPath>
|
||||
<CardNum>0</CardNum>
|
||||
<AxisNum>14</AxisNum>
|
||||
<MaxVel>50</MaxVel>
|
||||
<HomeSpeed>5</HomeSpeed>
|
||||
<HomeLabel>Homing</HomeLabel>
|
||||
<HomeBufferId>0</HomeBufferId>
|
||||
<StepDistance>0</StepDistance>
|
||||
<MovePara>
|
||||
<Velocity>10</Velocity>
|
||||
<Accelerate>100</Accelerate>
|
||||
<Decelerate>100</Decelerate>
|
||||
<Jerk>1000</Jerk>
|
||||
<Inc>0</Inc>
|
||||
</MovePara>
|
||||
<LowJogPara>
|
||||
<Velocity>1</Velocity>
|
||||
<Accelerate>10</Accelerate>
|
||||
</LowJogPara>
|
||||
<MidJogPara>
|
||||
<Velocity>10</Velocity>
|
||||
<Accelerate>100</Accelerate>
|
||||
</MidJogPara>
|
||||
<HighJogPara>
|
||||
<Velocity>50</Velocity>
|
||||
<Accelerate>500</Accelerate>
|
||||
</HighJogPara>
|
||||
<AxisBand>0</AxisBand>
|
||||
</PersistenceObject>
|
||||
<PersistenceObject xsi:type="AxisMoveParaPO">
|
||||
<AlarmOffset>0</AlarmOffset>
|
||||
<CategoryName>WEU-Y6</CategoryName>
|
||||
<ID>cb2a3d76-1f2e-484a-88d7-0ed23b73ab9d</ID>
|
||||
<EnableLog>false</EnableLog>
|
||||
<ConfigPath>AxisMoveParaPO.xml</ConfigPath>
|
||||
<CardNum>0</CardNum>
|
||||
<AxisNum>14</AxisNum>
|
||||
<MaxVel>50</MaxVel>
|
||||
<HomeSpeed>5</HomeSpeed>
|
||||
<HomeLabel>Homing</HomeLabel>
|
||||
<HomeBufferId>0</HomeBufferId>
|
||||
<StepDistance>0</StepDistance>
|
||||
<MovePara>
|
||||
<Velocity>10</Velocity>
|
||||
<Accelerate>100</Accelerate>
|
||||
<Decelerate>100</Decelerate>
|
||||
<Jerk>1000</Jerk>
|
||||
<Inc>0</Inc>
|
||||
</MovePara>
|
||||
<LowJogPara>
|
||||
<Velocity>1</Velocity>
|
||||
<Accelerate>10</Accelerate>
|
||||
</LowJogPara>
|
||||
<MidJogPara>
|
||||
<Velocity>10</Velocity>
|
||||
<Accelerate>100</Accelerate>
|
||||
</MidJogPara>
|
||||
<HighJogPara>
|
||||
<Velocity>50</Velocity>
|
||||
<Accelerate>500</Accelerate>
|
||||
</HighJogPara>
|
||||
<AxisBand>0</AxisBand>
|
||||
</PersistenceObject>
|
||||
<PersistenceObject xsi:type="AxisMoveParaPO">
|
||||
<AlarmOffset>0</AlarmOffset>
|
||||
<CategoryName>CV-Z13</CategoryName>
|
||||
<ID>cb2a3d76-1f2e-484a-88d7-0ed23b73ab9d</ID>
|
||||
<EnableLog>false</EnableLog>
|
||||
<ConfigPath>AxisMoveParaPO.xml</ConfigPath>
|
||||
<CardNum>0</CardNum>
|
||||
<AxisNum>14</AxisNum>
|
||||
<MaxVel>50</MaxVel>
|
||||
<HomeSpeed>5</HomeSpeed>
|
||||
<HomeLabel>Homing</HomeLabel>
|
||||
<HomeBufferId>0</HomeBufferId>
|
||||
<StepDistance>0</StepDistance>
|
||||
<MovePara>
|
||||
<Velocity>10</Velocity>
|
||||
<Accelerate>100</Accelerate>
|
||||
<Decelerate>100</Decelerate>
|
||||
<Jerk>1000</Jerk>
|
||||
<Inc>0</Inc>
|
||||
</MovePara>
|
||||
<LowJogPara>
|
||||
<Velocity>1</Velocity>
|
||||
<Accelerate>10</Accelerate>
|
||||
</LowJogPara>
|
||||
<MidJogPara>
|
||||
<Velocity>10</Velocity>
|
||||
<Accelerate>100</Accelerate>
|
||||
</MidJogPara>
|
||||
<HighJogPara>
|
||||
<Velocity>50</Velocity>
|
||||
<Accelerate>500</Accelerate>
|
||||
</HighJogPara>
|
||||
<AxisBand>0</AxisBand>
|
||||
</PersistenceObject>
|
||||
<PersistenceObject xsi:type="AxisMoveParaPO">
|
||||
<AlarmOffset>0</AlarmOffset>
|
||||
<CategoryName>CV-Y7</CategoryName>
|
||||
<ID>cb2a3d76-1f2e-484a-88d7-0ed23b73ab9d</ID>
|
||||
<EnableLog>false</EnableLog>
|
||||
<ConfigPath>AxisMoveParaPO.xml</ConfigPath>
|
||||
<CardNum>0</CardNum>
|
||||
<AxisNum>14</AxisNum>
|
||||
<MaxVel>50</MaxVel>
|
||||
<HomeSpeed>5</HomeSpeed>
|
||||
<HomeLabel>Homing</HomeLabel>
|
||||
<HomeBufferId>0</HomeBufferId>
|
||||
<StepDistance>0</StepDistance>
|
||||
<MovePara>
|
||||
<Velocity>10</Velocity>
|
||||
<Accelerate>100</Accelerate>
|
||||
<Decelerate>100</Decelerate>
|
||||
<Jerk>1000</Jerk>
|
||||
<Inc>0</Inc>
|
||||
</MovePara>
|
||||
<LowJogPara>
|
||||
<Velocity>1</Velocity>
|
||||
<Accelerate>10</Accelerate>
|
||||
</LowJogPara>
|
||||
<MidJogPara>
|
||||
<Velocity>10</Velocity>
|
||||
<Accelerate>100</Accelerate>
|
||||
</MidJogPara>
|
||||
<HighJogPara>
|
||||
<Velocity>50</Velocity>
|
||||
<Accelerate>500</Accelerate>
|
||||
</HighJogPara>
|
||||
<AxisBand>0</AxisBand>
|
||||
</PersistenceObject>
|
||||
<PersistenceObject xsi:type="AxisMoveParaPO">
|
||||
<AlarmOffset>0</AlarmOffset>
|
||||
<CategoryName>CV-Y8</CategoryName>
|
||||
<ID>cb2a3d76-1f2e-484a-88d7-0ed23b73ab9d</ID>
|
||||
<EnableLog>false</EnableLog>
|
||||
<ConfigPath>AxisMoveParaPO.xml</ConfigPath>
|
||||
<CardNum>0</CardNum>
|
||||
<AxisNum>14</AxisNum>
|
||||
<MaxVel>50</MaxVel>
|
||||
<HomeSpeed>5</HomeSpeed>
|
||||
<HomeLabel>Homing</HomeLabel>
|
||||
<HomeBufferId>0</HomeBufferId>
|
||||
<StepDistance>0</StepDistance>
|
||||
<MovePara>
|
||||
<Velocity>10</Velocity>
|
||||
<Accelerate>100</Accelerate>
|
||||
<Decelerate>100</Decelerate>
|
||||
<Jerk>1000</Jerk>
|
||||
<Inc>0</Inc>
|
||||
</MovePara>
|
||||
<LowJogPara>
|
||||
<Velocity>1</Velocity>
|
||||
<Accelerate>10</Accelerate>
|
||||
</LowJogPara>
|
||||
<MidJogPara>
|
||||
<Velocity>10</Velocity>
|
||||
<Accelerate>100</Accelerate>
|
||||
</MidJogPara>
|
||||
<HighJogPara>
|
||||
<Velocity>50</Velocity>
|
||||
<Accelerate>500</Accelerate>
|
||||
</HighJogPara>
|
||||
<AxisBand>0</AxisBand>
|
||||
</PersistenceObject>
|
||||
<PersistenceObject xsi:type="AxisMoveParaPO">
|
||||
<AlarmOffset>0</AlarmOffset>
|
||||
<CategoryName>CV-Y9</CategoryName>
|
||||
<ID>cb2a3d76-1f2e-484a-88d7-0ed23b73ab9d</ID>
|
||||
<EnableLog>false</EnableLog>
|
||||
<ConfigPath>AxisMoveParaPO.xml</ConfigPath>
|
||||
<CardNum>0</CardNum>
|
||||
<AxisNum>14</AxisNum>
|
||||
<MaxVel>50</MaxVel>
|
||||
<HomeSpeed>5</HomeSpeed>
|
||||
<HomeLabel>Homing</HomeLabel>
|
||||
<HomeBufferId>0</HomeBufferId>
|
||||
<StepDistance>0</StepDistance>
|
||||
<MovePara>
|
||||
<Velocity>10</Velocity>
|
||||
<Accelerate>100</Accelerate>
|
||||
<Decelerate>100</Decelerate>
|
||||
<Jerk>1000</Jerk>
|
||||
<Inc>0</Inc>
|
||||
</MovePara>
|
||||
<LowJogPara>
|
||||
<Velocity>1</Velocity>
|
||||
<Accelerate>10</Accelerate>
|
||||
</LowJogPara>
|
||||
<MidJogPara>
|
||||
<Velocity>10</Velocity>
|
||||
<Accelerate>100</Accelerate>
|
||||
</MidJogPara>
|
||||
<HighJogPara>
|
||||
<Velocity>50</Velocity>
|
||||
<Accelerate>500</Accelerate>
|
||||
</HighJogPara>
|
||||
<AxisBand>0</AxisBand>
|
||||
</PersistenceObject>
|
||||
<PersistenceObject xsi:type="AxisMoveParaPO">
|
||||
<AlarmOffset>0</AlarmOffset>
|
||||
<CategoryName>CV-Y10</CategoryName>
|
||||
<ID>cb2a3d76-1f2e-484a-88d7-0ed23b73ab9d</ID>
|
||||
<EnableLog>false</EnableLog>
|
||||
<ConfigPath>AxisMoveParaPO.xml</ConfigPath>
|
||||
<CardNum>0</CardNum>
|
||||
<AxisNum>14</AxisNum>
|
||||
<MaxVel>50</MaxVel>
|
||||
<HomeSpeed>5</HomeSpeed>
|
||||
<HomeLabel>Homing</HomeLabel>
|
||||
<HomeBufferId>0</HomeBufferId>
|
||||
<StepDistance>0</StepDistance>
|
||||
<MovePara>
|
||||
<Velocity>10</Velocity>
|
||||
<Accelerate>100</Accelerate>
|
||||
<Decelerate>100</Decelerate>
|
||||
<Jerk>1000</Jerk>
|
||||
<Inc>0</Inc>
|
||||
</MovePara>
|
||||
<LowJogPara>
|
||||
<Velocity>1</Velocity>
|
||||
<Accelerate>10</Accelerate>
|
||||
</LowJogPara>
|
||||
<MidJogPara>
|
||||
<Velocity>10</Velocity>
|
||||
<Accelerate>100</Accelerate>
|
||||
</MidJogPara>
|
||||
<HighJogPara>
|
||||
<Velocity>50</Velocity>
|
||||
<Accelerate>500</Accelerate>
|
||||
</HighJogPara>
|
||||
<AxisBand>0</AxisBand>
|
||||
</PersistenceObject>
|
||||
<PersistenceObject xsi:type="AxisMoveParaPO">
|
||||
<AlarmOffset>0</AlarmOffset>
|
||||
<CategoryName>PHS-X1</CategoryName>
|
||||
<ID>af7168b4-8aab-45a8-be8a-28f13976acfd</ID>
|
||||
<EnableLog>false</EnableLog>
|
||||
<ConfigPath>AxisMoveParaPO.xml</ConfigPath>
|
||||
<CardNum>1</CardNum>
|
||||
<AxisNum>1</AxisNum>
|
||||
<MaxVel>1000</MaxVel>
|
||||
<HomeSpeed>10</HomeSpeed>
|
||||
<HomeLabel>HOMING_X1</HomeLabel>
|
||||
<HomeBufferId>2</HomeBufferId>
|
||||
<StepDistance>0</StepDistance>
|
||||
<MovePara>
|
||||
<Velocity>10</Velocity>
|
||||
<Accelerate>100</Accelerate>
|
||||
<Decelerate>100</Decelerate>
|
||||
<Jerk>1000</Jerk>
|
||||
<Inc>0</Inc>
|
||||
</MovePara>
|
||||
<LowJogPara>
|
||||
<Velocity>10</Velocity>
|
||||
<Accelerate>100</Accelerate>
|
||||
</LowJogPara>
|
||||
<MidJogPara>
|
||||
<Velocity>100</Velocity>
|
||||
<Accelerate>1000</Accelerate>
|
||||
</MidJogPara>
|
||||
<HighJogPara>
|
||||
<Velocity>300</Velocity>
|
||||
<Accelerate>3000</Accelerate>
|
||||
</HighJogPara>
|
||||
<AxisBand>0</AxisBand>
|
||||
</PersistenceObject>
|
||||
<PersistenceObject xsi:type="AxisMoveParaPO">
|
||||
<AlarmOffset>0</AlarmOffset>
|
||||
<CategoryName>PHS-X2</CategoryName>
|
||||
<ID>af7168b4-8aab-45a8-be8a-28f13976acfd</ID>
|
||||
<EnableLog>false</EnableLog>
|
||||
<ConfigPath>AxisMoveParaPO.xml</ConfigPath>
|
||||
<CardNum>1</CardNum>
|
||||
<AxisNum>1</AxisNum>
|
||||
<MaxVel>1000</MaxVel>
|
||||
<HomeSpeed>10</HomeSpeed>
|
||||
<HomeLabel>HOMING_X2</HomeLabel>
|
||||
<HomeBufferId>2</HomeBufferId>
|
||||
<StepDistance>0</StepDistance>
|
||||
<MovePara>
|
||||
<Velocity>10</Velocity>
|
||||
<Accelerate>100</Accelerate>
|
||||
<Decelerate>100</Decelerate>
|
||||
<Jerk>1000</Jerk>
|
||||
<Inc>0</Inc>
|
||||
</MovePara>
|
||||
<LowJogPara>
|
||||
<Velocity>10</Velocity>
|
||||
<Accelerate>100</Accelerate>
|
||||
</LowJogPara>
|
||||
<MidJogPara>
|
||||
<Velocity>100</Velocity>
|
||||
<Accelerate>1000</Accelerate>
|
||||
</MidJogPara>
|
||||
<HighJogPara>
|
||||
<Velocity>300</Velocity>
|
||||
<Accelerate>3000</Accelerate>
|
||||
</HighJogPara>
|
||||
<AxisBand>0</AxisBand>
|
||||
</PersistenceObject>
|
||||
<PersistenceObject xsi:type="AxisMoveParaPO">
|
||||
<AlarmOffset>0</AlarmOffset>
|
||||
<CategoryName>WS-X3</CategoryName>
|
||||
<ID>f854496b-00b2-42be-816a-15b09cfe7f64</ID>
|
||||
<EnableLog>false</EnableLog>
|
||||
<ConfigPath>AxisMoveParaPO.xml</ConfigPath>
|
||||
<CardNum>1</CardNum>
|
||||
<AxisNum>0</AxisNum>
|
||||
<MaxVel>1000</MaxVel>
|
||||
<HomeSpeed>10</HomeSpeed>
|
||||
<HomeLabel>HOMING_Y1</HomeLabel>
|
||||
<HomeBufferId>1</HomeBufferId>
|
||||
<StepDistance>0</StepDistance>
|
||||
<MovePara>
|
||||
<Velocity>10</Velocity>
|
||||
<Accelerate>100</Accelerate>
|
||||
<Decelerate>100</Decelerate>
|
||||
<Jerk>1000</Jerk>
|
||||
<Inc>0</Inc>
|
||||
</MovePara>
|
||||
<LowJogPara>
|
||||
<Velocity>10</Velocity>
|
||||
<Accelerate>100</Accelerate>
|
||||
</LowJogPara>
|
||||
<MidJogPara>
|
||||
<Velocity>100</Velocity>
|
||||
<Accelerate>1000</Accelerate>
|
||||
</MidJogPara>
|
||||
<HighJogPara>
|
||||
<Velocity>300</Velocity>
|
||||
<Accelerate>3000</Accelerate>
|
||||
</HighJogPara>
|
||||
<AxisBand>0</AxisBand>
|
||||
</PersistenceObject>
|
||||
<PersistenceObject xsi:type="AxisMoveParaPO">
|
||||
<AlarmOffset>0</AlarmOffset>
|
||||
<CategoryName>PHS-Y1</CategoryName>
|
||||
<ID>5377b562-4e41-4dcf-914a-d0e05d14aaf4</ID>
|
||||
<EnableLog>false</EnableLog>
|
||||
<ConfigPath>AxisMoveParaPO.xml</ConfigPath>
|
||||
<CardNum>1</CardNum>
|
||||
<AxisNum>2</AxisNum>
|
||||
<MaxVel>1000</MaxVel>
|
||||
<HomeSpeed>10</HomeSpeed>
|
||||
<HomeLabel>HOMING_X2</HomeLabel>
|
||||
<HomeBufferId>3</HomeBufferId>
|
||||
<StepDistance>0</StepDistance>
|
||||
<MovePara>
|
||||
<Velocity>10</Velocity>
|
||||
<Accelerate>100</Accelerate>
|
||||
<Decelerate>100</Decelerate>
|
||||
<Jerk>1000</Jerk>
|
||||
<Inc>0</Inc>
|
||||
</MovePara>
|
||||
<LowJogPara>
|
||||
<Velocity>10</Velocity>
|
||||
<Accelerate>100</Accelerate>
|
||||
</LowJogPara>
|
||||
<MidJogPara>
|
||||
<Velocity>100</Velocity>
|
||||
<Accelerate>1000</Accelerate>
|
||||
</MidJogPara>
|
||||
<HighJogPara>
|
||||
<Velocity>300</Velocity>
|
||||
<Accelerate>3000</Accelerate>
|
||||
</HighJogPara>
|
||||
<AxisBand>0</AxisBand>
|
||||
</PersistenceObject>
|
||||
<PersistenceObject xsi:type="AxisMoveParaPO">
|
||||
<AlarmOffset>0</AlarmOffset>
|
||||
<CategoryName>WS-R</CategoryName>
|
||||
<ID>858b75b5-8918-4856-a387-8c92eb96a2f2</ID>
|
||||
<EnableLog>false</EnableLog>
|
||||
<ConfigPath>AxisMoveParaPO.xml</ConfigPath>
|
||||
<CardNum>1</CardNum>
|
||||
<AxisNum>3</AxisNum>
|
||||
<MaxVel>1000</MaxVel>
|
||||
<HomeSpeed>10</HomeSpeed>
|
||||
<HomeLabel>HOMING_Y2</HomeLabel>
|
||||
<HomeBufferId>4</HomeBufferId>
|
||||
<StepDistance>0</StepDistance>
|
||||
<MovePara>
|
||||
<Velocity>10</Velocity>
|
||||
<Accelerate>100</Accelerate>
|
||||
<Decelerate>100</Decelerate>
|
||||
<Jerk>1000</Jerk>
|
||||
<Inc>0</Inc>
|
||||
</MovePara>
|
||||
<LowJogPara>
|
||||
<Velocity>10</Velocity>
|
||||
<Accelerate>100</Accelerate>
|
||||
</LowJogPara>
|
||||
<MidJogPara>
|
||||
<Velocity>100</Velocity>
|
||||
<Accelerate>1000</Accelerate>
|
||||
</MidJogPara>
|
||||
<HighJogPara>
|
||||
<Velocity>300</Velocity>
|
||||
<Accelerate>3000</Accelerate>
|
||||
</HighJogPara>
|
||||
<AxisBand>0</AxisBand>
|
||||
</PersistenceObject>
|
||||
<PersistenceObject xsi:type="AxisMoveParaPO">
|
||||
<AlarmOffset>0</AlarmOffset>
|
||||
<CategoryName>SZ</CategoryName>
|
||||
<ID>3c7a13d8-3b7b-4d1f-bac2-61d7496ff736</ID>
|
||||
<EnableLog>false</EnableLog>
|
||||
<ConfigPath>AxisMoveParaPO.xml</ConfigPath>
|
||||
<CardNum>1</CardNum>
|
||||
<AxisNum>8</AxisNum>
|
||||
<MaxVel>5</MaxVel>
|
||||
<HomeSpeed>1</HomeSpeed>
|
||||
<HomeLabel>HOMING_CYCZ</HomeLabel>
|
||||
<HomeBufferId>5</HomeBufferId>
|
||||
<StepDistance>0</StepDistance>
|
||||
<MovePara>
|
||||
<Velocity>1</Velocity>
|
||||
<Accelerate>10</Accelerate>
|
||||
<Decelerate>10</Decelerate>
|
||||
<Jerk>100</Jerk>
|
||||
<Inc>0</Inc>
|
||||
</MovePara>
|
||||
<LowJogPara>
|
||||
<Velocity>0.1</Velocity>
|
||||
<Accelerate>1</Accelerate>
|
||||
</LowJogPara>
|
||||
<MidJogPara>
|
||||
<Velocity>1</Velocity>
|
||||
<Accelerate>10</Accelerate>
|
||||
</MidJogPara>
|
||||
<HighJogPara>
|
||||
<Velocity>300</Velocity>
|
||||
<Accelerate>3000</Accelerate>
|
||||
</HighJogPara>
|
||||
<AxisBand>0</AxisBand>
|
||||
</PersistenceObject>
|
||||
<PersistenceObject xsi:type="AxisMoveParaPO">
|
||||
<AlarmOffset>0</AlarmOffset>
|
||||
<CategoryName>Stage-Y3</CategoryName>
|
||||
<ID>80d675b6-39c0-4f56-829b-11670fc683c9</ID>
|
||||
<EnableLog>false</EnableLog>
|
||||
<ConfigPath>AxisMoveParaPO.xml</ConfigPath>
|
||||
<CardNum>1</CardNum>
|
||||
<AxisNum>9</AxisNum>
|
||||
<MaxVel>5</MaxVel>
|
||||
<HomeSpeed>1</HomeSpeed>
|
||||
<HomeLabel>HOMING_CYCZ</HomeLabel>
|
||||
<HomeBufferId>5</HomeBufferId>
|
||||
<StepDistance>0</StepDistance>
|
||||
<MovePara>
|
||||
<Velocity>1</Velocity>
|
||||
<Accelerate>10</Accelerate>
|
||||
<Decelerate>10</Decelerate>
|
||||
<Jerk>100</Jerk>
|
||||
<Inc>0</Inc>
|
||||
</MovePara>
|
||||
<LowJogPara>
|
||||
<Velocity>0.1</Velocity>
|
||||
<Accelerate>1</Accelerate>
|
||||
</LowJogPara>
|
||||
<MidJogPara>
|
||||
<Velocity>1</Velocity>
|
||||
<Accelerate>10</Accelerate>
|
||||
</MidJogPara>
|
||||
<HighJogPara>
|
||||
<Velocity>300</Velocity>
|
||||
<Accelerate>3000</Accelerate>
|
||||
</HighJogPara>
|
||||
<AxisBand>0</AxisBand>
|
||||
</PersistenceObject>
|
||||
</ArrayOfPersistenceObject>
|
||||
@@ -0,0 +1,57 @@
|
||||
<?xml version="1.0"?>
|
||||
<ArrayOfPersistenceObject xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
|
||||
<PersistenceObject xsi:type="CameraPO">
|
||||
<AlarmOffset>0</AlarmOffset>
|
||||
<CategoryName>MapCamera</CategoryName>
|
||||
<ID>2595f60b-d5fb-4fa8-998e-1931d1a071bf</ID>
|
||||
<EnableLog>false</EnableLog>
|
||||
<ConfigPath>CameraPO.xml</ConfigPath>
|
||||
<Port>0</Port>
|
||||
<CamType>DEMO</CamType>
|
||||
<PixWidth>0</PixWidth>
|
||||
<PixHeight>0</PixHeight>
|
||||
<MirrorType>None</MirrorType>
|
||||
<RotateType>Zero</RotateType>
|
||||
<IsGanRaw>true</IsGanRaw>
|
||||
<IsSimulate>false</IsSimulate>
|
||||
<BufferAttach>0</BufferAttach>
|
||||
<Interval>100</Interval>
|
||||
<HeartBeatTime xsi:nil="true" />
|
||||
</PersistenceObject>
|
||||
<PersistenceObject xsi:type="CameraPO">
|
||||
<AlarmOffset>0</AlarmOffset>
|
||||
<CategoryName>TopWideCamera</CategoryName>
|
||||
<ID>5dc88b03-cdfb-44e2-b954-f5b97e0e68a3</ID>
|
||||
<EnableLog>false</EnableLog>
|
||||
<ConfigPath>CameraPO.xml</ConfigPath>
|
||||
<Port>0</Port>
|
||||
<CamType>DEMO</CamType>
|
||||
<PixWidth>0</PixWidth>
|
||||
<PixHeight>0</PixHeight>
|
||||
<MirrorType>None</MirrorType>
|
||||
<RotateType>Zero</RotateType>
|
||||
<IsGanRaw>true</IsGanRaw>
|
||||
<IsSimulate>false</IsSimulate>
|
||||
<BufferAttach>0</BufferAttach>
|
||||
<Interval>100</Interval>
|
||||
<HeartBeatTime xsi:nil="true" />
|
||||
</PersistenceObject>
|
||||
<PersistenceObject xsi:type="CameraPO">
|
||||
<AlarmOffset>0</AlarmOffset>
|
||||
<CategoryName>TopPositionCamera</CategoryName>
|
||||
<ID>618de1c8-08ac-4abf-b778-17f26fa61a63</ID>
|
||||
<EnableLog>false</EnableLog>
|
||||
<ConfigPath>CameraPO.xml</ConfigPath>
|
||||
<Port>0</Port>
|
||||
<CamType>DEMO</CamType>
|
||||
<PixWidth>0</PixWidth>
|
||||
<PixHeight>0</PixHeight>
|
||||
<MirrorType>None</MirrorType>
|
||||
<RotateType>Zero</RotateType>
|
||||
<IsGanRaw>true</IsGanRaw>
|
||||
<IsSimulate>false</IsSimulate>
|
||||
<BufferAttach>0</BufferAttach>
|
||||
<Interval>100</Interval>
|
||||
<HeartBeatTime xsi:nil="true" />
|
||||
</PersistenceObject>
|
||||
</ArrayOfPersistenceObject>
|
||||
BIN
MX-PD-盘古 - new/PanGu.DieBonderApp/Configuration/SystemConfig.bin
Normal file
BIN
MX-PD-盘古 - new/PanGu.DieBonderApp/Configuration/SystemConfig.bin
Normal file
Binary file not shown.
@@ -0,0 +1,40 @@
|
||||
{
|
||||
"Nodes": [
|
||||
{
|
||||
"Key": "WaferLoad",
|
||||
"DisplayName": "晶圆上料",
|
||||
"ActivityKeywords": [
|
||||
"ChipLoad",
|
||||
"ChipLoadExecute"
|
||||
],
|
||||
"WorkflowKeywords": [],
|
||||
"ParentKeywords": []
|
||||
},
|
||||
{
|
||||
"Key": "WaferSupply",
|
||||
"DisplayName": "供片准备",
|
||||
"ActivityKeywords": [],
|
||||
"WorkflowKeywords": [
|
||||
"WaferAngleAdjustmentFlow",
|
||||
"DiePositionFlow",
|
||||
"DieTransferFlow",
|
||||
"DieRecheckFlow"
|
||||
],
|
||||
"ParentKeywords": [
|
||||
"DieAlign",
|
||||
"DieBond",
|
||||
"Inspect"
|
||||
]
|
||||
},
|
||||
{
|
||||
"Key": "WaferUnload",
|
||||
"DisplayName": "晶圆下料",
|
||||
"ActivityKeywords": [
|
||||
"ChipUnload",
|
||||
"ChipUnloadExecute"
|
||||
],
|
||||
"WorkflowKeywords": [],
|
||||
"ParentKeywords": []
|
||||
}
|
||||
]
|
||||
}
|
||||
10
MX-PD-盘古 - new/PanGu.DieBonderApp/Error.txt
Normal file
10
MX-PD-盘古 - new/PanGu.DieBonderApp/Error.txt
Normal file
@@ -0,0 +1,10 @@
|
||||
System.NullReferenceException: 未将对象引用设置到对象的实例。
|
||||
在 MaxwellFramework.Bootstrapper.OnExit(ExitEventArgs e)
|
||||
在 MainShell.StartBootstrapper.OnExit(ExitEventArgs e) 位置 D:\Development\Git\MX-PD-盘古 - new\PanGu.DieBonderApp\MainShell\StartBootstrapper.cs:行号 180
|
||||
在 Stylet.BootstrapperBase.<Setup>b__9_1(Object o, ExitEventArgs e)
|
||||
在 System.Windows.Application.OnExit(ExitEventArgs e)
|
||||
在 System.Windows.Application.DoShutdown()
|
||||
在 System.Windows.Application.ShutdownImpl()
|
||||
在 System.Windows.Application.ShutdownCallback(Object arg)
|
||||
在 System.Windows.Threading.ExceptionWrapper.InternalRealCall(Delegate callback, Object args, Int32 numArgs)
|
||||
在 System.Windows.Threading.ExceptionWrapper.TryCatchWhen(Object source, Delegate callback, Object args, Int32 numArgs, Delegate catchHandler)
|
||||
@@ -0,0 +1,132 @@
|
||||
using MainShell.Log;
|
||||
using MwFramework.AlarmManager;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using System.Windows;
|
||||
|
||||
namespace MainShell.Alarm
|
||||
{
|
||||
public class AlarmOperate : IAlarmSend, IAlarmResponse<string>
|
||||
{
|
||||
private const string AlarmSourceName = "AlarmOperate";
|
||||
|
||||
private readonly IAlarmManager _alarmManager;
|
||||
|
||||
public AlarmOperate(IAlarmManager alarmManager)
|
||||
{
|
||||
_alarmManager = alarmManager ?? throw new ArgumentNullException(nameof(alarmManager));
|
||||
_alarmManager.CloseBuzzer += () =>
|
||||
{
|
||||
LogManager.LogAlarmEvent(AlarmSourceName, "CloseBuzzer");
|
||||
};
|
||||
_alarmManager.RestBuzzer += () =>
|
||||
{
|
||||
|
||||
};
|
||||
_alarmManager.ClearPLCAlarm += () =>
|
||||
{
|
||||
List<long> unresolvedAlarmIds = _alarmManager.UnresolvedAlarms == null
|
||||
? new List<long>()
|
||||
: _alarmManager.UnresolvedAlarms.Distinct().ToList();
|
||||
|
||||
try
|
||||
{
|
||||
|
||||
foreach (long alarmId in unresolvedAlarmIds)
|
||||
{
|
||||
_alarmManager.HandleAlarmSolved(alarmId);
|
||||
}
|
||||
|
||||
LogManager.LogAlarmEvent(
|
||||
AlarmSourceName,
|
||||
string.Format("ClearPLCAlarm resolved {0} alarms", unresolvedAlarmIds.Count));
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
LogManager.LogAlarmError(AlarmSourceName, "ClearPLCAlarm", ex);
|
||||
throw;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
public string Code { private get; set; }
|
||||
|
||||
public void Alert(int alarmID)
|
||||
{
|
||||
Task alertTask = AlertAsync(alarmID);
|
||||
|
||||
if (Application.Current != null &&
|
||||
Application.Current.Dispatcher != null &&
|
||||
Application.Current.Dispatcher.CheckAccess())
|
||||
{
|
||||
alertTask.ContinueWith(task =>
|
||||
{
|
||||
AggregateException ignored = task.Exception;
|
||||
}, TaskContinuationOptions.OnlyOnFaulted);
|
||||
return;
|
||||
}
|
||||
|
||||
alertTask.GetAwaiter().GetResult();
|
||||
}
|
||||
|
||||
public void Alert(int alarmID, string source, string action, string detail = null)
|
||||
{
|
||||
Task alertTask = AlertAsync(alarmID, source, action, detail);
|
||||
|
||||
if (Application.Current != null &&
|
||||
Application.Current.Dispatcher != null &&
|
||||
Application.Current.Dispatcher.CheckAccess())
|
||||
{
|
||||
alertTask.ContinueWith(task =>
|
||||
{
|
||||
AggregateException ignored = task.Exception;
|
||||
}, TaskContinuationOptions.OnlyOnFaulted);
|
||||
return;
|
||||
}
|
||||
|
||||
alertTask.GetAwaiter().GetResult();
|
||||
}
|
||||
|
||||
public async Task AlertAsync(int alarmID)
|
||||
{
|
||||
await AlertInternalAsync(alarmID, AlarmSourceName, "AlertAsync requested").ConfigureAwait(false);
|
||||
}
|
||||
|
||||
public async Task AlertAsync(int alarmID, string source, string action, string detail = null)
|
||||
{
|
||||
string alarmSource = string.IsNullOrWhiteSpace(source) ? AlarmSourceName : source;
|
||||
string triggerAction = BuildTriggerAction(action, detail);
|
||||
|
||||
await AlertInternalAsync(alarmID, alarmSource, triggerAction).ConfigureAwait(false);
|
||||
}
|
||||
|
||||
private async Task AlertInternalAsync(int alarmID, string source, string action)
|
||||
{
|
||||
try
|
||||
{
|
||||
LogManager.LogAlarmEvent(source, action, alarmID);
|
||||
await _alarmManager.HandleAlarmAsync(alarmID, this, this).ConfigureAwait(false);
|
||||
LogManager.LogAlarmEvent(source, "HandleAlarmAsync completed", alarmID);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
LogManager.LogAlarmError(source, "HandleAlarmAsync", ex, alarmID);
|
||||
throw;
|
||||
}
|
||||
}
|
||||
|
||||
private static string BuildTriggerAction(string action, string detail)
|
||||
{
|
||||
string normalizedAction = string.IsNullOrWhiteSpace(action) ? "AlertAsync requested" : action;
|
||||
|
||||
if (string.IsNullOrWhiteSpace(detail))
|
||||
{
|
||||
return normalizedAction;
|
||||
}
|
||||
|
||||
return string.Format("{0}. Detail={1}", normalizedAction, detail);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,38 @@
|
||||
using MainShell.Alarm.ViewModel;
|
||||
using MwFramework.AlarmManager;
|
||||
using Stylet;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace MainShell.Alarm
|
||||
{
|
||||
[AlarmID(begin:10000, end:20011)]
|
||||
public class UserAlarmProduce : AbstractAlarmAsyncProcedure
|
||||
{
|
||||
private readonly IAlarmManager _alarmManager;
|
||||
private readonly IWindowManager _windowManager;
|
||||
|
||||
public UserAlarmProduce(IAlarmManager alarmManager, IWindowManager windowManager)
|
||||
{
|
||||
_alarmManager = alarmManager;
|
||||
_windowManager = windowManager;
|
||||
}
|
||||
|
||||
public override async Task HandleAsync(IAlarmSend inContext = null, IAlarmResponse outContext = null)
|
||||
{
|
||||
var dialogViewModel = new AlarmDialogViewModel
|
||||
{
|
||||
AlarmInfo = AlarmInfo
|
||||
};
|
||||
var resetRequested = false;
|
||||
await Execute.OnUIThreadAsync(() =>
|
||||
{
|
||||
resetRequested = _windowManager.ShowDialog(dialogViewModel) == true;
|
||||
}).ConfigureAwait(false);
|
||||
|
||||
if (resetRequested)
|
||||
{
|
||||
_alarmManager.ClearPLCAlarm?.Invoke();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,113 @@
|
||||
<Window x:Class="MainShell.Alarm.View.AlarmDialogView"
|
||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
xmlns:local="clr-namespace:MainShell.Alarm.View"
|
||||
mc:Ignorable="d"
|
||||
SizeToContent="Height"
|
||||
ResizeMode="CanResizeWithGrip"
|
||||
WindowStartupLocation="CenterOwner"
|
||||
Title="报警提示 (Alarm)" Width="650" MinWidth="500" MaxHeight="800">
|
||||
<Window.Resources>
|
||||
<Style TargetType="GroupBox" BasedOn="{StaticResource LeftGroupStyle}"/>
|
||||
</Window.Resources>
|
||||
<Grid>
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition Height="Auto"/>
|
||||
<!-- 顶部横幅 -->
|
||||
<RowDefinition Height="*"/>
|
||||
<!-- 内容区域 -->
|
||||
<RowDefinition Height="Auto"/>
|
||||
<!-- 按钮区域 -->
|
||||
</Grid.RowDefinitions>
|
||||
|
||||
<!-- 顶部横幅区域 -->
|
||||
<Border Grid.Row="0" Background="#FFF5E5" BorderBrush="#FFCC80" BorderThickness="0,0,0,1" Padding="15,10">
|
||||
<StackPanel Orientation="Horizontal" VerticalAlignment="Center">
|
||||
<TextBlock Text="⚠" Foreground="#E65100" FontSize="22" FontWeight="Bold" Margin="0,0,10,0" VerticalAlignment="Center"/>
|
||||
<TextBlock Text="系统发生报警,请及时处理" Foreground="#D84315" FontSize="16" FontWeight="Bold" VerticalAlignment="Center"/>
|
||||
</StackPanel>
|
||||
</Border>
|
||||
|
||||
<!-- 内容区域 -->
|
||||
<ScrollViewer Grid.Row="1" VerticalScrollBarVisibility="Auto" Margin="15,10,15,15">
|
||||
<StackPanel>
|
||||
<!-- 报警ID和类型 -->
|
||||
<GroupBox Header="基本信息" Margin="0,0,0,10">
|
||||
<Grid Margin="5">
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="80"/>
|
||||
<ColumnDefinition Width="*"/>
|
||||
</Grid.ColumnDefinitions>
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition Height="Auto"/>
|
||||
<RowDefinition Height="10"/>
|
||||
<RowDefinition Height="Auto"/>
|
||||
</Grid.RowDefinitions>
|
||||
|
||||
<TextBlock Text="报警 ID:" Style="{StaticResource LabelStyle}" Grid.Row="0" Grid.Column="0" VerticalAlignment="Top"/>
|
||||
<TextBlock Text="{Binding AlarmInfo.AlarmID}" Style="{StaticResource ValueStyle}" FontWeight="Bold" Grid.Row="0" Grid.Column="1" TextWrapping="Wrap"/>
|
||||
|
||||
<TextBlock Text="报警类型:" Style="{StaticResource LabelStyle}" Grid.Row="2" Grid.Column="0" VerticalAlignment="Top"/>
|
||||
<TextBlock Text="{Binding AlarmInfo.AlarmType}" Style="{StaticResource ValueStyle}" Foreground="#D84315" FontWeight="SemiBold" Grid.Row="2" Grid.Column="1" TextWrapping="Wrap"/>
|
||||
</Grid>
|
||||
</GroupBox>
|
||||
|
||||
<!-- 报警消息 -->
|
||||
<GroupBox Header="报警消息" Margin="0,0,0,10">
|
||||
<Grid Margin="5">
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="80"/>
|
||||
<ColumnDefinition Width="*"/>
|
||||
</Grid.ColumnDefinitions>
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition Height="Auto"/>
|
||||
<RowDefinition Height="10"/>
|
||||
<RowDefinition Height="Auto"/>
|
||||
</Grid.RowDefinitions>
|
||||
|
||||
<TextBlock Text="中文消息:" Style="{StaticResource LabelStyle}" Grid.Row="0" Grid.Column="0" VerticalAlignment="Top"/>
|
||||
<TextBlock Text="{Binding AlarmInfo.AlarmMessage}" Style="{StaticResource ValueStyle}" Grid.Row="0" Grid.Column="1" TextWrapping="Wrap" LineHeight="20"/>
|
||||
|
||||
<TextBlock Text="英文消息:" Style="{StaticResource LabelStyle}" Grid.Row="2" Grid.Column="0" VerticalAlignment="Top"/>
|
||||
<TextBlock Text="{Binding AlarmInfo.AlarmMessageEN}" Style="{StaticResource ValueStyle}" Grid.Row="2" Grid.Column="1" TextWrapping="Wrap" Foreground="#555555" LineHeight="20"/>
|
||||
</Grid>
|
||||
</GroupBox>
|
||||
|
||||
<!-- 报警原因 -->
|
||||
<GroupBox Header="报警原因" Margin="0,0,0,10">
|
||||
<Grid Margin="5">
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="80"/>
|
||||
<ColumnDefinition Width="*"/>
|
||||
</Grid.ColumnDefinitions>
|
||||
<TextBlock Text="原因描述:" Style="{StaticResource LabelStyle}" Grid.Row="0" Grid.Column="0" VerticalAlignment="Top"/>
|
||||
<TextBlock Text="{Binding AlarmInfo.AlarmReason}" Style="{StaticResource ValueStyle}" Grid.Row="0" Grid.Column="1" TextWrapping="Wrap" LineHeight="20"/>
|
||||
</Grid>
|
||||
</GroupBox>
|
||||
|
||||
<!-- 解决方案 -->
|
||||
<GroupBox Header="解决方案" Margin="0,0,0,10">
|
||||
<Border Background="#F9FBE7" BorderBrush="#CDDC39" BorderThickness="1" CornerRadius="4" Padding="10">
|
||||
<TextBlock Text="{Binding AlarmInfo.AlarmSolution}" Style="{StaticResource ValueStyle}" TextWrapping="Wrap" Foreground="#33691E" LineHeight="20"/>
|
||||
</Border>
|
||||
</GroupBox>
|
||||
|
||||
<!-- 触发时间 -->
|
||||
<StackPanel Orientation="Horizontal" HorizontalAlignment="Right" Margin="0,5,5,0">
|
||||
<TextBlock Text="触发时间:" Style="{StaticResource LabelStyle}" Foreground="#888888" Margin="0,0,5,0" VerticalAlignment="Center"/>
|
||||
<TextBlock Text="{Binding AlarmInfo.TriggerTime, StringFormat='{}{0:yyyy-MM-dd HH:mm:ss}'}" Style="{StaticResource ValueStyle}" Foreground="#888888" VerticalAlignment="Center"/>
|
||||
</StackPanel>
|
||||
</StackPanel>
|
||||
</ScrollViewer>
|
||||
|
||||
<!-- 底部按钮区域 -->
|
||||
<Border Grid.Row="2" BorderBrush="#E0E0E0" BorderThickness="0,1,0,0" Padding="10,8" Background="#F8F8F8">
|
||||
<StackPanel Orientation="Horizontal" HorizontalAlignment="Right">
|
||||
<Button Content="复位报警" Style="{StaticResource CloseButtonStyle}" Width="100" Height="32" Margin="0,0,10,0" Command="{Binding ResetCommand}" Cursor="Hand"/>
|
||||
<Button Content="关闭" Style="{StaticResource CloseButtonStyle}" Width="100" Height="32" Command="{Binding CloseCommand}" Cursor="Hand"/>
|
||||
</StackPanel>
|
||||
</Border>
|
||||
</Grid>
|
||||
</Window>
|
||||
@@ -0,0 +1,27 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using System.Windows;
|
||||
using System.Windows.Controls;
|
||||
using System.Windows.Data;
|
||||
using System.Windows.Documents;
|
||||
using System.Windows.Input;
|
||||
using System.Windows.Media;
|
||||
using System.Windows.Media.Imaging;
|
||||
using System.Windows.Shapes;
|
||||
|
||||
namespace MainShell.Alarm.View
|
||||
{
|
||||
/// <summary>
|
||||
/// AlarmDialog.xaml 的交互逻辑
|
||||
/// </summary>
|
||||
public partial class AlarmDialogView : Window
|
||||
{
|
||||
public AlarmDialogView()
|
||||
{
|
||||
InitializeComponent();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,40 @@
|
||||
using MainShell.Models;
|
||||
using MaxwellFramework.Core.Common.Command;
|
||||
using MwFramework.AlarmManager;
|
||||
using System.Windows.Input;
|
||||
|
||||
namespace MainShell.Alarm.ViewModel
|
||||
{
|
||||
public class AlarmDialogViewModel : BaseScreen
|
||||
{
|
||||
public ICommand ResetCommand { get; }
|
||||
public ICommand CloseCommand { get; }
|
||||
|
||||
public AlarmDialogViewModel()
|
||||
{
|
||||
DisplayName = "报警详情";
|
||||
ResetCommand = new DelegateCommand(obj => Reset());
|
||||
CloseCommand = new DelegateCommand(obj => Close());
|
||||
}
|
||||
|
||||
private AlarmInfo _alarmInfo;
|
||||
public AlarmInfo AlarmInfo
|
||||
{
|
||||
get => _alarmInfo;
|
||||
set
|
||||
{
|
||||
SetAndNotify(ref _alarmInfo, value);
|
||||
}
|
||||
}
|
||||
|
||||
private void Close()
|
||||
{
|
||||
RequestClose(false);
|
||||
}
|
||||
|
||||
private void Reset()
|
||||
{
|
||||
RequestClose(true);
|
||||
}
|
||||
}
|
||||
}
|
||||
37
MX-PD-盘古 - new/PanGu.DieBonderApp/MainShell/App.config
Normal file
37
MX-PD-盘古 - new/PanGu.DieBonderApp/MainShell/App.config
Normal file
@@ -0,0 +1,37 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<configuration>
|
||||
|
||||
<configSections>
|
||||
<section name="nlog" type="NLog.Config.ConfigSectionHandler, NLog" />
|
||||
<section name="templates" type="MwFramework.Controls.PatternTemplate.ConfigModule.TemplateConfigurationSection,MwFramework.Controls.PatternTemplate" />
|
||||
</configSections>
|
||||
<templates parserType="MwFramework.HuaruiMatch.TypeParser" caliperType="MwFramework.HuaruiMatch.CaliperTest" assemblyFile="MwFramework.HuaruiMatch.dll">
|
||||
<template templateName="Shape" templateType="MwFramework.HuaruiMatch.ShapeMatch" assemblyFile="MwFramework.HuaruiMatch.dll"></template>
|
||||
<template templateName="Ncc" templateType="MwFramework.HuaruiMatch.TemplateMatch" assemblyFile="MwFramework.HuaruiMatch.dll"></template>
|
||||
</templates>
|
||||
<startup>
|
||||
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.8" />
|
||||
</startup>
|
||||
|
||||
|
||||
<appSettings>
|
||||
|
||||
<add key="Demo" value="true" />
|
||||
<!--语言-->
|
||||
<add key="Lang" value="CN" />
|
||||
<add key="SaveLogsWay" value="DataBase"/>
|
||||
<!--Txt 存储路径-->
|
||||
<add key="LogsPath" value="D:\\Logs" />
|
||||
<add key="MachineId" value="" />
|
||||
</appSettings>
|
||||
|
||||
|
||||
<runtime>
|
||||
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
|
||||
<dependentAssembly>
|
||||
<assemblyIdentity name="System.Threading.Tasks.Extensions" publicKeyToken="cc7b13ffcd2ddd51" culture="neutral" />
|
||||
<bindingRedirect oldVersion="0.0.0.0-4.2.1.0" newVersion="4.2.1.0" />
|
||||
</dependentAssembly>
|
||||
</assemblyBinding>
|
||||
</runtime>
|
||||
</configuration>
|
||||
21
MX-PD-盘古 - new/PanGu.DieBonderApp/MainShell/App.xaml
Normal file
21
MX-PD-盘古 - new/PanGu.DieBonderApp/MainShell/App.xaml
Normal file
@@ -0,0 +1,21 @@
|
||||
<Application x:Class="MainShell.App"
|
||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:local="clr-namespace:MainShell" xmlns:mw="http://www.maxwell-gp.com/"
|
||||
>
|
||||
<Application.Resources>
|
||||
<ResourceDictionary>
|
||||
<ResourceDictionary.MergedDictionaries>
|
||||
<ResourceDictionary Source="pack://application:,,,/MaxwellControl;component/Themes/SkinTouchable.xaml" />
|
||||
<mw:ApplicationLoader>
|
||||
<mw:ApplicationLoader.Bootstrapper>
|
||||
<local:StartBootstrapper/>
|
||||
</mw:ApplicationLoader.Bootstrapper>
|
||||
</mw:ApplicationLoader>
|
||||
|
||||
<ResourceDictionary Source="/Resources/Styles/Styles.xaml"/>
|
||||
<ResourceDictionary Source="/Language/MXJM_CN.xaml"/>
|
||||
</ResourceDictionary.MergedDictionaries>
|
||||
</ResourceDictionary>
|
||||
</Application.Resources>
|
||||
</Application>
|
||||
17
MX-PD-盘古 - new/PanGu.DieBonderApp/MainShell/App.xaml.cs
Normal file
17
MX-PD-盘古 - new/PanGu.DieBonderApp/MainShell/App.xaml.cs
Normal file
@@ -0,0 +1,17 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Configuration;
|
||||
using System.Data;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using System.Windows;
|
||||
|
||||
namespace MainShell
|
||||
{
|
||||
/// <summary>
|
||||
/// App.xaml 的交互逻辑
|
||||
/// </summary>
|
||||
public partial class App : Application
|
||||
{
|
||||
}
|
||||
}
|
||||
171
MX-PD-盘古 - new/PanGu.DieBonderApp/MainShell/CLAUDE.md
Normal file
171
MX-PD-盘古 - new/PanGu.DieBonderApp/MainShell/CLAUDE.md
Normal file
@@ -0,0 +1,171 @@
|
||||
# CLAUDE.md
|
||||
|
||||
## 前置指令
|
||||
|
||||
1. **XAML 文件可以直接更改** — 使用 Edit 工具直接修改 `.xaml` 文件
|
||||
2. **CS 文件有 TSM 加密** — `.cs` 文件在本地是加密的,无法直接读取或编辑。需要通过 `git show HEAD:path` 获取内容。但注意:有时最新的 CS 文件还未提交到 git,此时可以让用户直接提供最新的 CS 文件内容
|
||||
3. **所有回复使用中文** — 所有与用户的交流、注释说明等均使用中文
|
||||
|
||||
## PageCalib 目录结构
|
||||
|
||||
PageCalib 是标定页面模块,采用 MVVM 架构,包含 8 个标定子模块。主入口通过 `PageCalibView.xaml` + `PageCalibViewModel.cs` 管理导航。
|
||||
|
||||
### 目录组织
|
||||
|
||||
```
|
||||
PageCalib/
|
||||
├── View/ # 主视图
|
||||
│ ├── PageCalibView.xaml # 主页面,使用 SideMenu 导航
|
||||
│ └── PageCalibView.xaml.cs
|
||||
├── ViewModel/ # 主视图模型
|
||||
│ └── PageCalibViewModel.cs # 管理 8 个标定子模块导航
|
||||
├── HeightMeasure/ # 高度标定模块
|
||||
│ ├── Model/ # HeightBaseSetting, IHeightMeasure, DiastimeterHeightMeasure
|
||||
│ ├── Service/ # HeightMeasureMotionService
|
||||
│ ├── View/ # HeightView.xaml
|
||||
│ └── ViewModel/ # HeightViewModel
|
||||
├── OriginCalib/ # 原点标定模块
|
||||
│ ├── Model/ # OriginCalibSetting
|
||||
│ ├── Service/ # ICalibrationPostProcessor, OriginCalibrationMotionService, CalibrationPostProcessors
|
||||
│ ├── View/ # OriginCalibView.xaml
|
||||
│ └── ViewModel/ # OriginCalibViewModel, OriginCalibModuleViewModel, AvoidanceAxisViewModel, CalibrationAxisViewModel
|
||||
└── AlgorithmCalib/ # 算法标定模块(包含多个子模块)
|
||||
├── Common/ # 公共接口和结果类
|
||||
│ ├── IAlgorithmCalibModule.cs
|
||||
│ ├── AlgorithmCalibResult.cs
|
||||
│ └── CalibrationProgressEventArgs.cs
|
||||
├── Model/ # 参数模型
|
||||
│ ├── AlgorithmCalibModuleNames.cs
|
||||
│ ├── FusionCalibParItem.cs
|
||||
│ ├── RotateCalibParItem.cs
|
||||
│ └── FusionCalib/ # FusionCalibSetting, FusionCalibModuleItem
|
||||
├── Task/ # 标定任务
|
||||
│ ├── RotateFormCalibTask.cs
|
||||
│ └── FusionCalibTask.cs
|
||||
├── View/ # 各子模块视图
|
||||
│ ├── PixRatioCalib/ # 像素比标定
|
||||
│ ├── DistortionCorrectionCalib/ # 畸变校正标定
|
||||
│ ├── RotateCenterCalib/ # 旋转中心标定
|
||||
│ ├── RotateMatixFormCalib/ # 旋转表标定
|
||||
│ ├── MotionCalib/ # 运动系标定
|
||||
│ └── FusionCalib/ # 融合标定(Die/Pad)
|
||||
├── ViewModel/ # 各子模块视图模型
|
||||
│ ├── PixRatioCalib/
|
||||
│ ├── DistortionCorrectionCalib/
|
||||
│ ├── RotateCenterCalib/
|
||||
│ ├── RotateMatixFormCalib/
|
||||
│ ├── MotionCalib/
|
||||
│ └── FusionCalib/
|
||||
└── Service/ # 各子模块服务
|
||||
├── RotateFormCalib/ # RotateMatixFormCalibMotionService, FileService, PostProcessor
|
||||
├── MotionCalib/ # MotionCalibFileService
|
||||
└── FusionCalib/ # FusionCalibMotionService, PostProcessor, FusionAlignProcessor
|
||||
```
|
||||
|
||||
### 标定子模块列表
|
||||
|
||||
| 模块名称 | 中文名 | 主 ViewModel | 说明 |
|
||||
|---------|--------|-------------|------|
|
||||
| HeightMeasure | 高度标定 | HeightViewModel | 测高标定,包含产品和方片高度测量 |
|
||||
| OriginCalib | 原点标定 | OriginCalibViewModel | 原点位置标定 |
|
||||
| PixRatioCalib | 像素比标定 | PixRatioCalibContentsViewModel | 相机像素比例标定 |
|
||||
| DistortionCorrectionCalib | 畸变校准标定 | DistortionCorrectionCalibContentsViewModel | 相机畸变校正 |
|
||||
| MotionCalib | 运动系标定 | MotionCalibContentsViewModel | 运动系统标定 |
|
||||
| RotateCenterCalib | 旋转中心标定 | RotateCenterCalibContentsViewModel | 旋转中心位置标定 |
|
||||
| RotateFormCalib | 旋转表标定 | RotateMatixFormCalibViewModel | 旋转矩阵表标定 |
|
||||
| FusionCalib | 融合标定 | FusionCalibViewModel | Die/Pad 融合标定 |
|
||||
|
||||
### 通用 UI 模式
|
||||
|
||||
算法标定子模块(PixRatio、DistortionCorrection、RotateCenter、MotionCalib、FusionCalib)采用统一的 ContentsView 布局:
|
||||
- 顶部:当前标定名称 + 进度文本
|
||||
- 中间:ContentControl 绑定 ShowScreenVM 显示具体内容
|
||||
- 底部:上一个/下一个导航按钮
|
||||
|
||||
旋转表标定(RotateMatixFormCalib)采用卡片式布局:
|
||||
- 左侧:相机预览
|
||||
- 右侧:模块卡片(避让位置、标定参数、验证参数、进度条、操作按钮)
|
||||
|
||||
## 融合标定需求与实现
|
||||
|
||||
### 轴映射关系
|
||||
|
||||
| 项目 | WS轴(Wafer轴) | PHS轴(Pad轴) |
|
||||
|------|-----------------|----------------|
|
||||
| 旧项目 | X2, Y2 | X1, Y1 |
|
||||
| 新项目 | X2, Y1 | X1, Y2 |
|
||||
|
||||
### 融合标定流程
|
||||
|
||||
#### 1. Die融合标定(ws圆形标定融合)
|
||||
在X1全行程不同位置,标定建立X2,Y1的die融合表,用于对位晶粒。
|
||||
|
||||
**标定方法:**
|
||||
- 在die运动系下(固定X1),移动X2,Y1扫描获取N×N点阵,作为初始位置
|
||||
- 选取X2负限位位置附近设置起始位置,将X1,X2平移相同距离移动到起始位置
|
||||
- 设定标定范围、标定间隔,扫描一系列N×N点阵,保存为die融合位置表
|
||||
|
||||
**验证方法:**
|
||||
- 在die运动系下飞拍任意坐标
|
||||
- 再选取任意X1位置,使用融合位置表计算出任意坐标移动到该X1位置下的X2,Y1坐标
|
||||
- 同时获取到在该X1位置下实际逼近的X2,Y1坐标
|
||||
- 输出即为标定误差,可选择若干位置覆盖测试全行程误差
|
||||
|
||||
#### 2. Pad融合标定(stage拼接融合)
|
||||
在Y1全行程不同位置,建立X1,Y2的pad融合表,用于对位pad。
|
||||
|
||||
**标定方法:**
|
||||
- 在pad运动系下(固定Y1),移动X1,Y2扫描获取N×N点阵,作为初始位置
|
||||
- 选取Y2负限位位置附近设置起始位置,将Y1,Y2平移相同距离移动到起始位置
|
||||
- 设立标定范围、标定间隔,扫描一系列N×N点阵,保存为pad融合位置表
|
||||
|
||||
**验证方法:**
|
||||
- 在pad运动系下飞拍任意坐标
|
||||
- 再选取任意Y1位置,使用融合位置表计算出任意坐标移动到该Y1位置下的X1,Y2坐标
|
||||
- 同时获取到在该Y1位置下实际逼近的X1,Y2坐标
|
||||
- 输出即为标定误差,可选择若干位置覆盖测试全行程误差
|
||||
|
||||
#### 3. 整体对位验证(对位流程)
|
||||
整体对位流程为:
|
||||
1. 飞拍获取die的下相机X2,Y2坐标,X1坐标固定(上相机die运动系X2,Y1),转换为X1,Y1坐标
|
||||
2. Pad定位mark获取X1,Y2坐标,Y1坐标固定(上相机pad运动系X1,Y2),即转化为X1,Y1坐标
|
||||
3. 通过查找die融合表将die X方向对齐pad(此时Y1会产生少许偏移)
|
||||
4. 再根据此时Y1值,将pad Y方向对齐die(X1会产生少许偏移)
|
||||
5. 此时再移动X2跟上X1的移动量(此处直接移动或查表再移动)
|
||||
|
||||
### 新项目融合标定文件结构
|
||||
|
||||
```
|
||||
AlgorithmCalib/
|
||||
├── View/FusionCalib/
|
||||
│ ├── DieFusionCalibView.xaml # Die融合标定视图(标定+验证Tab)
|
||||
│ ├── PadFusionCalibView.xaml # Pad融合标定视图(标定+验证Tab)
|
||||
│ └── FusionAlignVerifyView.xaml # 整体对位验证视图(4步骤流程)
|
||||
├── ViewModel/FusionCalib/
|
||||
│ ├── FusionCalibViewModel.cs # Die/Pad融合标定共用ViewModel
|
||||
│ ├── FusionAlignVerifyViewModel.cs # 整体对位验证ViewModel
|
||||
│ └── FusionMultipleCalibViewModel.cs # 多模块融合标定ViewModel
|
||||
├── Service/FusionCalib/
|
||||
│ ├── FusionCalibMotionService.cs # 融合标定运动服务
|
||||
│ ├── FusionCalibPostProcessor.cs # 融合标定后处理器
|
||||
│ └── FusionAlignProcessor.cs # 对位处理器
|
||||
└── Model/FusionCalib/
|
||||
├── FusionCalibSetting.cs # 融合标定设置
|
||||
└── FusionCalibModuleItem.cs # 融合标定模块参数
|
||||
```
|
||||
|
||||
### 旧项目参考文件
|
||||
|
||||
旧项目融合标定参考文件位于 `AlgorithmCalib/Old_fusionCalib/` 目录:
|
||||
- `oldProjectDetail.xaml` - 旧项目融合标定流程说明
|
||||
- `newProjectVisionDemand.xaml` - 新项目需求说明
|
||||
- `CameraFusionCali02AViewModel.xaml` - 旧项目ViewModel实现(CS内容)
|
||||
- `CameraFusionCalibrationMotion02A.xaml` - 旧项目Motion实现(CS内容)
|
||||
|
||||
### 关键API调用
|
||||
|
||||
旧项目使用的JM1Vision API:
|
||||
- `JM1Manager.Instance.cal_wafer_fusion()` - 计算wafer融合表
|
||||
- `JM1Manager.Instance.get_ws_pos()` - 根据融合表查询WS位置
|
||||
- `JM1Manager.Instance.pos_verify()` - 验证标定精度
|
||||
- `JM1Manager.Instance.Save()` - 保存标定数据
|
||||
@@ -0,0 +1,61 @@
|
||||
using System;
|
||||
using System.Windows;
|
||||
using System.Windows.Input;
|
||||
|
||||
namespace MainShell.Common.Behaviors
|
||||
{
|
||||
public static class WindowDragMoveBehavior
|
||||
{
|
||||
public static readonly DependencyProperty IsEnabledProperty = DependencyProperty.RegisterAttached(
|
||||
"IsEnabled",
|
||||
typeof(bool),
|
||||
typeof(WindowDragMoveBehavior),
|
||||
new PropertyMetadata(false, OnIsEnabledChanged));
|
||||
|
||||
public static bool GetIsEnabled(DependencyObject obj)
|
||||
{
|
||||
return (bool)obj.GetValue(IsEnabledProperty);
|
||||
}
|
||||
|
||||
public static void SetIsEnabled(DependencyObject obj, bool value)
|
||||
{
|
||||
obj.SetValue(IsEnabledProperty, value);
|
||||
}
|
||||
|
||||
private static void OnIsEnabledChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
|
||||
{
|
||||
var element = d as UIElement;
|
||||
if (element == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if ((bool)e.NewValue)
|
||||
{
|
||||
element.MouseLeftButtonDown += OnMouseLeftButtonDown;
|
||||
return;
|
||||
}
|
||||
|
||||
element.MouseLeftButtonDown -= OnMouseLeftButtonDown;
|
||||
}
|
||||
|
||||
private static void OnMouseLeftButtonDown(object sender, MouseButtonEventArgs e)
|
||||
{
|
||||
var element = sender as DependencyObject;
|
||||
var window = element != null ? Window.GetWindow(element) : null;
|
||||
if (window == null || e.ButtonState != MouseButtonState.Pressed)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
window.DragMove();
|
||||
e.Handled = true;
|
||||
}
|
||||
catch (InvalidOperationException)
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,59 @@
|
||||
using MainShell.Log;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using System.Windows;
|
||||
using System.Windows.Media;
|
||||
|
||||
namespace MainShell.Common
|
||||
{
|
||||
public static class CommonUti
|
||||
{
|
||||
public static void RunOnUi(Action action)
|
||||
{
|
||||
if (action == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
if (Application.Current == null || Application.Current.Dispatcher.CheckAccess())
|
||||
{
|
||||
// 同步在当前线程执行
|
||||
action();
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
// 在 UI 线程同步执行
|
||||
Application.Current.Dispatcher.Invoke(action);
|
||||
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
MaxwellControl.Controls.MessageBox.Show($"方法执行异常:{ex.ToString()}", icon: MessageBoxImage.Error);
|
||||
}
|
||||
}
|
||||
|
||||
public static Brush BrushFromString(string s)
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(s))
|
||||
return Brushes.Transparent;
|
||||
|
||||
try
|
||||
{
|
||||
var brush = (Brush)new BrushConverter().ConvertFromString(s);
|
||||
return brush ?? Brushes.Transparent;
|
||||
}
|
||||
catch
|
||||
{
|
||||
// 如果解析失败,返回默认颜色(可根据需要改为 Brushes.Black 或抛异常)
|
||||
return Brushes.Transparent;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,240 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using System.Windows;
|
||||
using System.Windows.Controls;
|
||||
using System.Windows.Input;
|
||||
using System.Windows.Media;
|
||||
using MainShell.Resources.CustomControl;
|
||||
|
||||
namespace MainShell.Common.ControlAttribute
|
||||
{
|
||||
public static class ControlBehavior
|
||||
{
|
||||
public static bool GetIsEnable(DependencyObject obj)
|
||||
{
|
||||
return (bool)obj.GetValue(IsEnableProperty);
|
||||
}
|
||||
|
||||
public static void SetIsEnable(DependencyObject obj, bool value)
|
||||
{
|
||||
obj.SetValue(IsEnableProperty, value);
|
||||
}
|
||||
|
||||
// Using a DependencyProperty as the backing store for IsEnable. This enables animation, styling, binding, etc...
|
||||
public static readonly DependencyProperty IsEnableProperty =
|
||||
DependencyProperty.RegisterAttached("IsEnable", typeof(bool), typeof(ControlBehavior), new PropertyMetadata(true, OnProppertyChanged));
|
||||
|
||||
public static bool GetIsNumericOnly(DependencyObject obj)
|
||||
{
|
||||
return (bool)obj.GetValue(IsNumericOnlyProperty);
|
||||
}
|
||||
|
||||
public static void SetIsNumericOnly(DependencyObject obj, bool value)
|
||||
{
|
||||
obj.SetValue(IsNumericOnlyProperty, value);
|
||||
}
|
||||
|
||||
public static readonly DependencyProperty IsNumericOnlyProperty =
|
||||
DependencyProperty.RegisterAttached("IsNumericOnly", typeof(bool), typeof(ControlBehavior), new PropertyMetadata(false, OnIsNumericOnlyChanged));
|
||||
|
||||
public static bool GetRouteDieMapMouseWheel(DependencyObject obj)
|
||||
{
|
||||
return (bool)obj.GetValue(RouteDieMapMouseWheelProperty);
|
||||
}
|
||||
|
||||
public static void SetRouteDieMapMouseWheel(DependencyObject obj, bool value)
|
||||
{
|
||||
obj.SetValue(RouteDieMapMouseWheelProperty, value);
|
||||
}
|
||||
|
||||
public static readonly DependencyProperty RouteDieMapMouseWheelProperty =
|
||||
DependencyProperty.RegisterAttached("RouteDieMapMouseWheel", typeof(bool), typeof(ControlBehavior), new PropertyMetadata(false, OnRouteDieMapMouseWheelChanged));
|
||||
|
||||
|
||||
private static void OnProppertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
|
||||
{
|
||||
if (d is TabControl tabControl)
|
||||
{
|
||||
if (e.NewValue is bool isenable)
|
||||
{
|
||||
if (isenable)
|
||||
foreach (var item in tabControl.Items)
|
||||
{
|
||||
if (tabControl.ItemContainerGenerator.ContainerFromItem(item) is TabItem tabItem)
|
||||
{
|
||||
tabItem.IsEnabled = isenable;
|
||||
}
|
||||
}
|
||||
else
|
||||
foreach (var item in tabControl.Items)
|
||||
{
|
||||
if (tabControl.ItemContainerGenerator.ContainerFromItem(item) is TabItem tabItem)
|
||||
{
|
||||
if (tabItem.IsSelected)
|
||||
{
|
||||
tabItem.IsEnabled = true;
|
||||
}
|
||||
else
|
||||
tabItem.IsEnabled = isenable;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
private static void OnIsNumericOnlyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
|
||||
{
|
||||
if (!(d is TextBox textBox))
|
||||
return;
|
||||
|
||||
if ((bool)e.NewValue)
|
||||
{
|
||||
InputMethod.SetIsInputMethodEnabled(textBox, false);
|
||||
textBox.PreviewTextInput += TextBox_PreviewTextInput;
|
||||
DataObject.AddPastingHandler(textBox, OnTextBoxPaste);
|
||||
}
|
||||
else
|
||||
{
|
||||
InputMethod.SetIsInputMethodEnabled(textBox, true);
|
||||
textBox.PreviewTextInput -= TextBox_PreviewTextInput;
|
||||
DataObject.RemovePastingHandler(textBox, OnTextBoxPaste);
|
||||
}
|
||||
}
|
||||
|
||||
private static void OnRouteDieMapMouseWheelChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
|
||||
{
|
||||
ScrollViewer scrollViewer = d as ScrollViewer;
|
||||
if (scrollViewer == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
bool isEnabled = e.NewValue is bool && (bool)e.NewValue;
|
||||
MouseWheelEventHandler mouseWheelEventHandler = new MouseWheelEventHandler(ScrollViewer_PreviewMouseWheel);
|
||||
if (isEnabled)
|
||||
{
|
||||
scrollViewer.RemoveHandler(UIElement.PreviewMouseWheelEvent, mouseWheelEventHandler);
|
||||
scrollViewer.AddHandler(UIElement.PreviewMouseWheelEvent, mouseWheelEventHandler, true);
|
||||
}
|
||||
else
|
||||
{
|
||||
scrollViewer.RemoveHandler(UIElement.PreviewMouseWheelEvent, mouseWheelEventHandler);
|
||||
}
|
||||
}
|
||||
|
||||
private static void ScrollViewer_PreviewMouseWheel(object sender, MouseWheelEventArgs e)
|
||||
{
|
||||
ScrollViewer scrollViewer = sender as ScrollViewer;
|
||||
if (scrollViewer == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
DieMapControl dieMapControl = FindDieMapControl(scrollViewer, e);
|
||||
if (dieMapControl == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
e.Handled = true;
|
||||
|
||||
MouseWheelEventArgs mouseWheelEventArgs = new MouseWheelEventArgs(e.MouseDevice, e.Timestamp, e.Delta);
|
||||
mouseWheelEventArgs.RoutedEvent = UIElement.MouseWheelEvent;
|
||||
mouseWheelEventArgs.Source = dieMapControl;
|
||||
dieMapControl.RaiseEvent(mouseWheelEventArgs);
|
||||
}
|
||||
|
||||
private static DieMapControl FindDieMapControl(ScrollViewer scrollViewer, MouseWheelEventArgs e)
|
||||
{
|
||||
DependencyObject dependencyObject = e.OriginalSource as DependencyObject;
|
||||
DieMapControl dieMapControl = FindAncestor<DieMapControl>(dependencyObject);
|
||||
if (dieMapControl != null)
|
||||
{
|
||||
return dieMapControl;
|
||||
}
|
||||
|
||||
dependencyObject = Mouse.DirectlyOver as DependencyObject;
|
||||
dieMapControl = FindAncestor<DieMapControl>(dependencyObject);
|
||||
if (dieMapControl != null)
|
||||
{
|
||||
return dieMapControl;
|
||||
}
|
||||
|
||||
IInputElement inputElement = scrollViewer.InputHitTest(e.GetPosition(scrollViewer));
|
||||
dependencyObject = inputElement as DependencyObject;
|
||||
return FindAncestor<DieMapControl>(dependencyObject);
|
||||
}
|
||||
|
||||
private static T FindAncestor<T>(DependencyObject dependencyObject) where T : DependencyObject
|
||||
{
|
||||
while (dependencyObject != null)
|
||||
{
|
||||
T target = dependencyObject as T;
|
||||
if (target != null)
|
||||
{
|
||||
return target;
|
||||
}
|
||||
|
||||
DependencyObject parent = VisualTreeHelper.GetParent(dependencyObject);
|
||||
if (parent == null && dependencyObject is FrameworkContentElement)
|
||||
{
|
||||
parent = ((FrameworkContentElement)dependencyObject).Parent;
|
||||
}
|
||||
|
||||
dependencyObject = parent;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
private static void TextBox_PreviewTextInput(object sender, TextCompositionEventArgs e)
|
||||
{
|
||||
if (sender is TextBox textBox)
|
||||
{
|
||||
e.Handled = !IsValidNumericText(GetPreviewText(textBox, e.Text));
|
||||
}
|
||||
}
|
||||
|
||||
private static void OnTextBoxPaste(object sender, DataObjectPastingEventArgs e)
|
||||
{
|
||||
if (!(sender is TextBox textBox))
|
||||
return;
|
||||
|
||||
if (!e.DataObject.GetDataPresent(typeof(string)))
|
||||
{
|
||||
e.CancelCommand();
|
||||
return;
|
||||
}
|
||||
|
||||
var pasteText = e.DataObject.GetData(typeof(string)) as string ?? string.Empty;
|
||||
if (!IsValidNumericText(GetPreviewText(textBox, pasteText)))
|
||||
{
|
||||
e.CancelCommand();
|
||||
}
|
||||
}
|
||||
|
||||
private static string GetPreviewText(TextBox textBox, string newText)
|
||||
{
|
||||
var currentText = textBox.Text ?? string.Empty;
|
||||
if (textBox.SelectionLength > 0)
|
||||
{
|
||||
currentText = currentText.Remove(textBox.SelectionStart, textBox.SelectionLength);
|
||||
}
|
||||
|
||||
return currentText.Insert(textBox.CaretIndex, newText);
|
||||
}
|
||||
|
||||
private static bool IsValidNumericText(string text)
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(text) || text == "-" || text == "." || text == "-.")
|
||||
return true;
|
||||
|
||||
return double.TryParse(text, out _);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,36 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Globalization;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using System.Windows;
|
||||
using System.Windows.Controls;
|
||||
using System.Windows.Input;
|
||||
using MessageBox = MaxwellControl.Controls.MessageBox;
|
||||
|
||||
namespace MainShell.Common.ControlAttribute
|
||||
{
|
||||
public class NumericValidationRule : ValidationRule
|
||||
{
|
||||
public override ValidationResult Validate(object value, CultureInfo cultureInfo)
|
||||
{
|
||||
string strValue = value as string;
|
||||
if (string.IsNullOrEmpty(strValue))
|
||||
{
|
||||
// 空值是允许的,如果需要必填,则返回 new ValidationResult(false, "不能为空");
|
||||
return new ValidationResult(false, "不能为空");
|
||||
}
|
||||
|
||||
// 尝试将字符串转换为double
|
||||
if (double.TryParse(strValue, out _))
|
||||
{
|
||||
return ValidationResult.ValidResult;
|
||||
}
|
||||
else
|
||||
{
|
||||
return new ValidationResult(false, "请输入有效的数字。");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,97 @@
|
||||
using MaxwellFramework.Core.Common;
|
||||
using MwFramework.Controls.ControlCanvas.Model;
|
||||
using MwFramework.ManagerService;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.ObjectModel;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace MainShell.Common.Display.Models
|
||||
{
|
||||
public class CameraAxisDevices : ViewModelBase
|
||||
{
|
||||
List<HardwareDevice> _hardwareDeviceList = new List<HardwareDevice>();
|
||||
HardwareDevice _selectedHardwareDevice = new HardwareDevice();
|
||||
private ObservableCollection<object> _shapes = new ObservableCollection<object>();
|
||||
private int _selectedIndex = 0;
|
||||
private bool _cameraSwitchEnable = true;
|
||||
|
||||
public List<HardwareDevice> HardwareDeviceList
|
||||
{
|
||||
get { return _hardwareDeviceList; }
|
||||
set
|
||||
{
|
||||
if (_hardwareDeviceList == value)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
_hardwareDeviceList = value;
|
||||
|
||||
if (_hardwareDeviceList != null && _hardwareDeviceList.Count > 0)
|
||||
{
|
||||
_selectedIndex = 0;
|
||||
SelectedHardwareDevice = _hardwareDeviceList[_selectedIndex];
|
||||
RaisePropertyChanged(nameof(SelectedIndex));
|
||||
}
|
||||
|
||||
RaisePropertyChanged(nameof(HardwareDeviceList));
|
||||
}
|
||||
}
|
||||
public HardwareDevice SelectedHardwareDevice
|
||||
{
|
||||
get { return _selectedHardwareDevice; }
|
||||
set
|
||||
{
|
||||
if (_selectedHardwareDevice != null && _selectedHardwareDevice.Camera != null && value != null && value.Camera != null)
|
||||
{
|
||||
|
||||
}
|
||||
_selectedHardwareDevice = value; RaisePropertyChanged(nameof(SelectedHardwareDevice));
|
||||
}
|
||||
}
|
||||
|
||||
public ObservableCollection<object> Shapes
|
||||
{
|
||||
get { return _shapes; }
|
||||
set
|
||||
{
|
||||
if (_shapes != value) { _shapes = value; RaisePropertyChanged(nameof(Shapes)); }
|
||||
}
|
||||
}
|
||||
private ObservableCollection<PrimShape> _regions = new ObservableCollection<PrimShape>();
|
||||
public ObservableCollection<PrimShape> Regions
|
||||
{
|
||||
get { return _regions; }
|
||||
set
|
||||
{
|
||||
SetAndNotify(ref _regions, value);
|
||||
}
|
||||
}
|
||||
public int SelectedIndex
|
||||
{
|
||||
get { return _selectedIndex; }
|
||||
set
|
||||
{
|
||||
_selectedIndex = value;
|
||||
if (HardwareDeviceList != null && HardwareDeviceList.Count > 0 && _selectedIndex >= 0)
|
||||
{
|
||||
if (_selectedIndex < HardwareDeviceList.Count)
|
||||
{
|
||||
SelectedHardwareDevice = HardwareDeviceList[_selectedIndex];
|
||||
}
|
||||
|
||||
}
|
||||
RaisePropertyChanged(nameof(SelectedIndex));
|
||||
}
|
||||
}
|
||||
|
||||
public bool CameraSwitchEnable
|
||||
{
|
||||
get { return _cameraSwitchEnable; }
|
||||
set { _cameraSwitchEnable = value; RaisePropertyChanged(nameof(CameraSwitchEnable)); }
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,30 @@
|
||||
<UserControl x:Class="MainShell.Common.Display.View.CameraAxisView"
|
||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||
xmlns:local="clr-namespace:MainShell.Common.Display.View"
|
||||
xmlns:control="http://www.maxwell.com/controls"
|
||||
xmlns:i="http://schemas.microsoft.com/xaml/behaviors"
|
||||
mc:Ignorable="d"
|
||||
d:DesignHeight="450" d:DesignWidth="800">
|
||||
<Grid>
|
||||
<CheckBox Panel.ZIndex="2" IsChecked="{Binding IsOpen, UpdateSourceTrigger=PropertyChanged}" Cursor="Hand" Margin="2,2" Foreground="White" HorizontalAlignment="Right" VerticalAlignment="Top">
|
||||
<TextBlock Text="移动"/>
|
||||
</CheckBox>
|
||||
<control:CameraAxisControlA Name="cameraAxisControl"
|
||||
IsShowDoubleLine="False"
|
||||
IsAxisControlLDBVisible2="Visible"
|
||||
Cameras="{Binding CameraAxisDevices.HardwareDeviceList}"
|
||||
TabSelectedIndex ="{Binding CameraAxisDevices.SelectedIndex}"
|
||||
Items="{Binding CameraAxisDevices.Shapes,Mode=TwoWay,UpdateSourceTrigger=PropertyChanged}"
|
||||
Regions="{Binding CameraAxisDevices.Regions}" ShapeThickness="1" IsShowSolidLine="True" DrawInConcurrency="False"
|
||||
>
|
||||
<i:Interaction.Triggers>
|
||||
<i:EventTrigger EventName="RecordPix">
|
||||
<i:InvokeCommandAction Command="{Binding OnLeftMouseDownCommand}" CommandParameter="{Binding ElementName=cameraAxisControl}" />
|
||||
</i:EventTrigger>
|
||||
</i:Interaction.Triggers>
|
||||
</control:CameraAxisControlA>
|
||||
</Grid>
|
||||
</UserControl>
|
||||
@@ -0,0 +1,28 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using System.Windows;
|
||||
using System.Windows.Controls;
|
||||
using System.Windows.Data;
|
||||
using System.Windows.Documents;
|
||||
using System.Windows.Input;
|
||||
using System.Windows.Media;
|
||||
using System.Windows.Media.Imaging;
|
||||
using System.Windows.Navigation;
|
||||
using System.Windows.Shapes;
|
||||
|
||||
namespace MainShell.Common.Display.View
|
||||
{
|
||||
/// <summary>
|
||||
/// CameraAxisView.xaml 的交互逻辑
|
||||
/// </summary>
|
||||
public partial class CameraAxisView : UserControl
|
||||
{
|
||||
public CameraAxisView()
|
||||
{
|
||||
InitializeComponent();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,22 @@
|
||||
<UserControl x:Class="MainShell.Common.Display.View.CameraView"
|
||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||
xmlns:local="clr-namespace:MainShell.Common.Display.View"
|
||||
xmlns:mw="http://www.maxwell.com/controls"
|
||||
mc:Ignorable="d"
|
||||
d:DesignHeight="450" d:DesignWidth="800">
|
||||
<Grid>
|
||||
<Border BorderThickness="1" BorderBrush ="#B0B9C4">
|
||||
<mw:DesignPanel x:Name="cameraDesignPanel"
|
||||
Source="{Binding DisplayImage}"
|
||||
Items="{Binding Shapes}"
|
||||
IsVirtualPix="Visible"
|
||||
IsShowSolidLine="True"
|
||||
IsCrossingLineVisible="False"
|
||||
IsNonRectCrossingLineVisible="False"
|
||||
IsImagePix="Collapsed" />
|
||||
</Border>
|
||||
</Grid>
|
||||
</UserControl>
|
||||
@@ -0,0 +1,28 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using System.Windows;
|
||||
using System.Windows.Controls;
|
||||
using System.Windows.Data;
|
||||
using System.Windows.Documents;
|
||||
using System.Windows.Input;
|
||||
using System.Windows.Media;
|
||||
using System.Windows.Media.Imaging;
|
||||
using System.Windows.Navigation;
|
||||
using System.Windows.Shapes;
|
||||
|
||||
namespace MainShell.Common.Display.View
|
||||
{
|
||||
/// <summary>
|
||||
/// CameraView.xaml 的交互逻辑
|
||||
/// </summary>
|
||||
public partial class CameraView : UserControl
|
||||
{
|
||||
public CameraView()
|
||||
{
|
||||
InitializeComponent();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,323 @@
|
||||
using MainShell.Common;
|
||||
using MainShell.Common.Display.Models;
|
||||
using MainShell.Log;
|
||||
using MainShell.Motion;
|
||||
using Maxwell.SemiFramework.DefaultConfig.Vision;
|
||||
using MwFramework.Controls.Components;
|
||||
using MwFramework.Controls.ControlCanvas.Model;
|
||||
using MwFramework.Controls.UIControl;
|
||||
using MwFramework.Device;
|
||||
using MwFramework.ManagerService;
|
||||
using Stylet;
|
||||
using StyletIoC;
|
||||
using System;
|
||||
using System.Collections.ObjectModel;
|
||||
using System.Threading.Tasks;
|
||||
using System.Windows;
|
||||
using System.Windows.Input;
|
||||
|
||||
namespace MainShell.Common.Display.ViewModel
|
||||
{
|
||||
public class CameraAxisViewModel : Screen
|
||||
{
|
||||
private const double DefaultFovX = 14.1 * 10;
|
||||
private const double DefaultFovY = 10.3 * 10;
|
||||
private const string SafeAxisMotionNotInjectedMessage = "SafeAxisMotion is not injected.";
|
||||
|
||||
private readonly object _moveLock = new object();
|
||||
|
||||
private CameraAxisDevices _cameraAxisDevices = new CameraAxisDevices();
|
||||
private double _xPixelPos;
|
||||
private double _yPixelPos;
|
||||
private double _cameraXIndex;
|
||||
private double _cameraYIndex;
|
||||
private GetConvertValue _convertFunXDelegate;
|
||||
private GetConvertValue _convertFunYDelegate;
|
||||
private ObservableCollection<PrimShape> _regions = new ObservableCollection<PrimShape>();
|
||||
private bool _isCameraEnable = true;
|
||||
private Visibility _controlVisibility = Visibility.Visible;
|
||||
private bool _isOpen;
|
||||
|
||||
[Inject]
|
||||
public SafeAxisMotion SafeAxisMotion { get; set; }
|
||||
|
||||
public CameraAxisViewModel()
|
||||
{
|
||||
ConvertFunXDelegate = new GetConvertValue(ConvertFunX);
|
||||
ConvertFunYDelegate = new GetConvertValue(ConvertFunY);
|
||||
OnLeftMouseDownCommand = new DelegateCommand<object>(OnLeftMouseDown);
|
||||
}
|
||||
|
||||
public CameraAxisDevices CameraAxisDevices
|
||||
{
|
||||
get { return _cameraAxisDevices; }
|
||||
set { SetAndNotify(ref _cameraAxisDevices, value); }
|
||||
}
|
||||
|
||||
public double XPixelPos
|
||||
{
|
||||
get { return _xPixelPos; }
|
||||
set { SetAndNotify(ref _xPixelPos, value); }
|
||||
}
|
||||
|
||||
public double YPixelPos
|
||||
{
|
||||
get { return _yPixelPos; }
|
||||
set { SetAndNotify(ref _yPixelPos, value); }
|
||||
}
|
||||
|
||||
public double CameraXIndex
|
||||
{
|
||||
get { return _cameraXIndex; }
|
||||
set { SetAndNotify(ref _cameraXIndex, value); }
|
||||
}
|
||||
|
||||
public double CameraYIndex
|
||||
{
|
||||
get { return _cameraYIndex; }
|
||||
set { SetAndNotify(ref _cameraYIndex, value); }
|
||||
}
|
||||
|
||||
public GetConvertValue ConvertFunXDelegate
|
||||
{
|
||||
get { return _convertFunXDelegate; }
|
||||
set { SetAndNotify(ref _convertFunXDelegate, value); }
|
||||
}
|
||||
|
||||
public GetConvertValue ConvertFunYDelegate
|
||||
{
|
||||
get { return _convertFunYDelegate; }
|
||||
set { SetAndNotify(ref _convertFunYDelegate, value); }
|
||||
}
|
||||
|
||||
public ObservableCollection<PrimShape> Regions
|
||||
{
|
||||
get { return _regions; }
|
||||
set { SetAndNotify(ref _regions, value); }
|
||||
}
|
||||
|
||||
public bool IsCameraEnable
|
||||
{
|
||||
get { return _isCameraEnable; }
|
||||
set { SetAndNotify(ref _isCameraEnable, value); }
|
||||
}
|
||||
|
||||
public Visibility ControlVisibility
|
||||
{
|
||||
get { return _controlVisibility; }
|
||||
set { SetAndNotify(ref _controlVisibility, value); }
|
||||
}
|
||||
|
||||
public ICommand OnLeftMouseDownCommand { get; private set; }
|
||||
|
||||
public bool IsOpen
|
||||
{
|
||||
get { return _isOpen; }
|
||||
set { SetAndNotify(ref _isOpen, value); }
|
||||
}
|
||||
|
||||
public void OnLeftMouseDown(object sender)
|
||||
{
|
||||
try
|
||||
{
|
||||
HardwareDevice selectedDevice;
|
||||
if (!TryGetSelectedDevice(out selectedDevice))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
CameraAxisControlA controlA = sender as CameraAxisControlA;
|
||||
if (controlA == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
Point pixelPos = new Point(controlA.YPixPos, controlA.XPixPos);
|
||||
Task.Run(() => MoveToPixelPoint(selectedDevice, pixelPos, false));
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
LogManager.LogSysError(ex);
|
||||
ShowOperationFailed(ex.Message);
|
||||
}
|
||||
}
|
||||
|
||||
public void MovePosAction()
|
||||
{
|
||||
try
|
||||
{
|
||||
HardwareDevice selectedDevice;
|
||||
if (!TryGetSelectedDevice(out selectedDevice))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
Point pixelPos = new Point(YPixelPos, XPixelPos);
|
||||
Task.Run(() => MoveToPixelPoint(selectedDevice, pixelPos, true));
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
LogManager.LogSysError(ex);
|
||||
ShowOperationFailed(ex.Message);
|
||||
}
|
||||
}
|
||||
|
||||
public double ConvertFunX(double interval)
|
||||
{
|
||||
try
|
||||
{
|
||||
HardwareDevice selectedDevice;
|
||||
if (!TryGetSelectedDevice(out selectedDevice))
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
string name = selectedDevice.Camera.Id;
|
||||
double dx;
|
||||
double dy;
|
||||
VisionProcess.Instance.GetCameraResolution(name, out dx, out dy);
|
||||
double pixelX = interval / Math.Abs(dx);
|
||||
return pixelX;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
LogManager.LogSysError(ex);
|
||||
ShowOperationFailed(ex.Message);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
public double ConvertFunY(double interval)
|
||||
{
|
||||
try
|
||||
{
|
||||
HardwareDevice selectedDevice;
|
||||
if (!TryGetSelectedDevice(out selectedDevice))
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
string name = selectedDevice.Camera.Id;
|
||||
double dx;
|
||||
double dy;
|
||||
VisionProcess.Instance.GetCameraResolution(name, out dx, out dy);
|
||||
double pixelY = interval / Math.Abs(dy);
|
||||
return pixelY;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
LogManager.LogSysError(ex);
|
||||
ShowOperationFailed(ex.Message);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
private bool TryGetSelectedDevice(out HardwareDevice selectedDevice)
|
||||
{
|
||||
selectedDevice = CameraAxisDevices != null ? CameraAxisDevices.SelectedHardwareDevice : null;
|
||||
if (!IsOpen || selectedDevice == null)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (selectedDevice.Camera == null || selectedDevice.Camera.Camera == null)
|
||||
{
|
||||
ShowDeviceNotInitialized();
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!selectedDevice.Camera.Camera.IsGrabbing)
|
||||
{
|
||||
LocalizedMessageBox.Show(MessageKey.VisionCameraNotGrabbing, MessageKey.TitleWarning, MessageBoxButton.OK, MessageBoxImage.Warning);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (selectedDevice.AxisX == null || selectedDevice.AxisY == null)
|
||||
{
|
||||
ShowDeviceNotInitialized();
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
private void MoveToPixelPoint(HardwareDevice selectedDevice, Point pixelPos, bool requireConfirmation)
|
||||
{
|
||||
lock (_moveLock)
|
||||
{
|
||||
try
|
||||
{
|
||||
IAxis axisX = selectedDevice.AxisX;
|
||||
IAxis axisY = selectedDevice.AxisY;
|
||||
Point rulerPos = new Point(axisX.State.ActualPos, axisY.State.ActualPos);
|
||||
Point newRulerPoint = Algorithm.Instance.MoveToPixelPoint(selectedDevice.Camera.Id, rulerPos, pixelPos);
|
||||
|
||||
if (requireConfirmation)
|
||||
{
|
||||
double dx = newRulerPoint.X - rulerPos.X;
|
||||
double dy = newRulerPoint.Y - rulerPos.Y;
|
||||
if (!ValidateMoveRange(dx, dy))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (!ConfirmMove(newRulerPoint))
|
||||
{
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (SafeAxisMotion == null)
|
||||
{
|
||||
InvalidOperationException exception = new InvalidOperationException(SafeAxisMotionNotInjectedMessage);
|
||||
LogManager.LogSysError(exception);
|
||||
ShowOperationFailed(SafeAxisMotionNotInjectedMessage);
|
||||
return;
|
||||
}
|
||||
|
||||
SafeAxisMotion.SafeMove(
|
||||
MotionMoveRequest.ForAxis(axisX, newRulerPoint.X),
|
||||
MotionMoveRequest.ForAxis(axisY, newRulerPoint.Y));
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
LogManager.LogSysError(ex);
|
||||
ShowOperationFailed(ex.Message);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static bool ValidateMoveRange(double dx, double dy)
|
||||
{
|
||||
if (Math.Abs(dx) > DefaultFovX || Math.Abs(dy) > DefaultFovY)
|
||||
{
|
||||
LocalizedMessageBox.Show(MessageKey.ParamOutOfRange, MessageKey.TitleWarning, MessageBoxButton.OK, MessageBoxImage.Warning);
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
private static bool ConfirmMove(Point newRulerPoint)
|
||||
{
|
||||
string message = string.Format("新点的坐标({0},{1}),是否移动?", newRulerPoint.X, newRulerPoint.Y);
|
||||
return MwMessageBox.Show(message, LanguageResourceHelper.GetString(MessageKey.TitleConfirm), MessageBoxButton.OKCancel, MessageBoxImage.Question, MessageBoxResult.Cancel) == MessageBoxResult.OK;
|
||||
}
|
||||
|
||||
private static void ShowDeviceNotInitialized()
|
||||
{
|
||||
LocalizedMessageBox.Show(MessageKey.DeviceNotInitialized, MessageKey.TitleWarning, MessageBoxButton.OK, MessageBoxImage.Warning);
|
||||
}
|
||||
|
||||
private static void ShowOperationFailed(string message)
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(message))
|
||||
{
|
||||
LocalizedMessageBox.Show(MessageKey.CommonOperationFailed, MessageKey.TitleError, MessageBoxButton.OK, MessageBoxImage.Error);
|
||||
return;
|
||||
}
|
||||
|
||||
MwMessageBox.Show(message, LanguageResourceHelper.GetString(MessageKey.TitleError), MessageBoxButton.OK, MessageBoxImage.Error);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,317 @@
|
||||
using MainShell.EventArgsFolder;
|
||||
using MainShell.Log;
|
||||
using MainShell.Vision;
|
||||
using MwFramework.Device.Model;
|
||||
using MwFramework.Controls.ControlCanvas.DrawingControl;
|
||||
using Stylet;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.ObjectModel;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using System.Windows;
|
||||
using System.Windows.Media.Imaging;
|
||||
using AppCameraType = MainShell.Common.CameraType;
|
||||
using System.Windows.Media;
|
||||
|
||||
namespace MainShell.Common.Display.ViewModel
|
||||
{
|
||||
public class CameraViewModel : Screen, IHandle<DisplayImageEventArgs>, IHandle<DisplayFindTemplateResultEventArgs>
|
||||
{
|
||||
private readonly IEventAggregator _eventAggregator;
|
||||
public AppCameraType CameraType { get; }
|
||||
|
||||
private WriteableBitmap currentImage;
|
||||
private WriteableBitmap _displayImage;
|
||||
public WriteableBitmap DisplayImage
|
||||
{
|
||||
get { return _displayImage; }
|
||||
set
|
||||
{
|
||||
SetAndNotify(ref _displayImage, value);
|
||||
}
|
||||
}
|
||||
|
||||
private ObservableCollection<object> _shapes = new ObservableCollection<object>();
|
||||
public ObservableCollection<object> Shapes
|
||||
{
|
||||
get { return _shapes; }
|
||||
set
|
||||
{
|
||||
if (_shapes != value) { _shapes = value; OnPropertyChanged(nameof(Shapes)); }
|
||||
}
|
||||
}
|
||||
/// <summary>
|
||||
/// 根据 CameraData 更新并返回 WriteableBitmap。
|
||||
/// 优化要点:
|
||||
/// - 重用已有 WriteableBitmap(当尺寸与像素格式相同时)以减少分配。
|
||||
/// - 校验参数与缓冲区长度。
|
||||
/// - 捕获并记录异常,失败时返回 null(不抛出)。
|
||||
/// </summary>
|
||||
public WriteableBitmap UpdateBitmap(CameraData cameraData)
|
||||
{
|
||||
if (cameraData == null)
|
||||
{
|
||||
"图片数据为空".LogSysError();
|
||||
return null;
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
int width = (int)cameraData.Width;
|
||||
int height = (int)cameraData.Height;
|
||||
int bitCnt = cameraData.Bit;
|
||||
byte[] buffer = cameraData.BufferData;
|
||||
|
||||
if (width <= 0 || height <= 0)
|
||||
{
|
||||
$"CameraViewModel.UpdateBitmap: invalid size {width}x{height}".LogSysError();
|
||||
return null;
|
||||
}
|
||||
|
||||
// 选择像素格式
|
||||
System.Windows.Media.PixelFormat pixelFormat = bitCnt == 1
|
||||
? System.Windows.Media.PixelFormats.Gray8
|
||||
: (bitCnt == 3 ? System.Windows.Media.PixelFormats.Bgr24 : System.Windows.Media.PixelFormats.Bgra32);
|
||||
|
||||
// 计算每行字节数(stride)
|
||||
int bytesPerPixel = (pixelFormat.BitsPerPixel + 7) / 8;
|
||||
int stride = width * bytesPerPixel;
|
||||
long requiredLength = (long)stride * height;
|
||||
|
||||
if (buffer == null)
|
||||
{
|
||||
"CameraViewModel.UpdateBitmap: buffer is null".LogSysError();
|
||||
return null;
|
||||
}
|
||||
|
||||
if (buffer.Length < requiredLength)
|
||||
{
|
||||
($"CameraViewModel.UpdateBitmap: buffer length {buffer.Length} is less than required {requiredLength}").LogSysError();
|
||||
return null;
|
||||
}
|
||||
|
||||
// 如果现有 bitmap 可复用(尺寸和格式一致),就重用以减少 GC/分配
|
||||
if (currentImage == null ||
|
||||
currentImage.PixelWidth != width ||
|
||||
currentImage.PixelHeight != height ||
|
||||
!currentImage.Format.Equals(pixelFormat))
|
||||
{
|
||||
// 新建 WriteableBitmap
|
||||
currentImage = new WriteableBitmap(width, height, 96, 96, pixelFormat, null);
|
||||
}
|
||||
|
||||
// 将字节拷贝到 BackBuffer(UI 线程中调用)
|
||||
currentImage.Lock();
|
||||
try
|
||||
{
|
||||
// BackBuffer 为 IntPtr,使用 Marshal.Copy 从 byte[] 拷贝
|
||||
System.Runtime.InteropServices.Marshal.Copy(buffer, 0, currentImage.BackBuffer, (int)requiredLength);
|
||||
currentImage.AddDirtyRect(new Int32Rect(0, 0, width, height));
|
||||
}
|
||||
finally
|
||||
{
|
||||
currentImage.Unlock();
|
||||
}
|
||||
|
||||
return currentImage;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
($"CameraViewModel.UpdateBitmap exception: {ex}").LogSysError();
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public CameraViewModel(IEventAggregator eventAggregator, AppCameraType cameraType)
|
||||
{
|
||||
_eventAggregator = eventAggregator;
|
||||
CameraType = cameraType;
|
||||
_eventAggregator?.Subscribe(this);
|
||||
}
|
||||
|
||||
public void Handle(DisplayImageEventArgs message)
|
||||
{
|
||||
if (message == null || message.CameraType != CameraType)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
CommonUti.RunOnUi(() =>
|
||||
{
|
||||
WriteableBitmap bmp = UpdateBitmap(message.CameraData);
|
||||
// 只有在成功生成 bitmap 时才更新 DisplayImage,避免把 null 赋值导致 UI 清空
|
||||
if (bmp != null)
|
||||
{
|
||||
DisplayImage = bmp;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public void Handle(DisplayFindTemplateResultEventArgs message)
|
||||
{
|
||||
if (message == null || message.CameraType != CameraType)
|
||||
{
|
||||
return;
|
||||
}
|
||||
CommonUti.RunOnUi(() =>
|
||||
{
|
||||
ApplyTemplateResultShapes(message);
|
||||
});
|
||||
}
|
||||
|
||||
private void ApplyTemplateResultShapes(DisplayFindTemplateResultEventArgs message)
|
||||
{
|
||||
if (message.ClearShapesBeforeDisplay)
|
||||
{
|
||||
Shapes.Clear();
|
||||
}
|
||||
|
||||
if (message.Result == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
AppendCenterShapes(message.Result);
|
||||
AppendContourShape(message.Result.Contour);
|
||||
AppendCircleShapes(message.Result.Circles);
|
||||
AppendLineShapes(message.Result.Lines);
|
||||
AppendRectangleShapes(message.Result.Rectangles);
|
||||
}
|
||||
|
||||
private void AppendCenterShapes(FindTemplateResult result)
|
||||
{
|
||||
if (result == null || !AreFinite(result.CenterX, result.CenterY, result.Score))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
ShapeDrawing pointShape = new ShapeDrawing();
|
||||
pointShape.X = result.CenterX;
|
||||
pointShape.Y = result.CenterY;
|
||||
Shapes.Add(pointShape);
|
||||
|
||||
TextShapeDrawing textShape = new TextShapeDrawing();
|
||||
textShape.X = result.CenterX;
|
||||
textShape.Y = result.CenterY;
|
||||
textShape.Text = $"Score:{result.Score:F3}";
|
||||
Shapes.Add(textShape);
|
||||
}
|
||||
|
||||
private void AppendContourShape(FindTemplateContourResult contour)
|
||||
{
|
||||
if (contour == null || !AreFinite(contour.StartX, contour.StartY, contour.EndX, contour.EndY))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
RectShapeDrawing contourShape = new RectShapeDrawing();
|
||||
contourShape.X = contour.StartX;
|
||||
contourShape.Y = contour.StartY;
|
||||
contourShape.X1 = contour.EndX;
|
||||
contourShape.Y1 = contour.EndY;
|
||||
Shapes.Add(contourShape);
|
||||
}
|
||||
|
||||
private void AppendCircleShapes(IList<FindTemplateCircleResult> circles)
|
||||
{
|
||||
if (circles == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
foreach (FindTemplateCircleResult circle in circles)
|
||||
{
|
||||
if (circle == null || !AreFinite(circle.CenterX, circle.CenterY, circle.Radius))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
CircleShapeDrawing circleShape = new CircleShapeDrawing();
|
||||
circleShape.X = circle.CenterX;
|
||||
circleShape.Y = circle.CenterY;
|
||||
circleShape.CenterPoint = new Point(circle.CenterX, circle.CenterY);
|
||||
circleShape.RadiusX = circle.Radius;
|
||||
circleShape.RadiusY = circle.Radius;
|
||||
circleShape.LineWidth = 1;
|
||||
circleShape.FillColor = Brushes.Blue;
|
||||
Shapes.Add(circleShape);
|
||||
}
|
||||
}
|
||||
|
||||
private void AppendLineShapes(IList<FindTemplateLineResult> lines)
|
||||
{
|
||||
if (lines == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
foreach (FindTemplateLineResult line in lines)
|
||||
{
|
||||
if (line == null || !AreFinite(line.StartX, line.StartY, line.EndX, line.EndY))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
LineShapeDrawing lineShape = new LineShapeDrawing();
|
||||
lineShape.X = line.StartX;
|
||||
lineShape.Y = line.StartY;
|
||||
lineShape.X1 = line.EndX;
|
||||
lineShape.Y1 = line.EndY;
|
||||
Shapes.Add(lineShape);
|
||||
}
|
||||
}
|
||||
|
||||
private void AppendRectangleShapes(IList<FindTemplateRectangleResult> rectangles)
|
||||
{
|
||||
if (rectangles == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
foreach (FindTemplateRectangleResult rectangle in rectangles)
|
||||
{
|
||||
if (rectangle == null || !AreFinite(rectangle.StartX, rectangle.StartY, rectangle.Width, rectangle.Height, rectangle.Angle))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
double halfWidth = rectangle.Width / 2d;
|
||||
double halfHeight = rectangle.Height / 2d;
|
||||
double cosAngle = Math.Cos(rectangle.Angle);
|
||||
double sinAngle = Math.Sin(rectangle.Angle);
|
||||
double centerX = rectangle.StartX + (halfWidth * cosAngle) - (halfHeight * sinAngle);
|
||||
double centerY = rectangle.StartY + (halfWidth * sinAngle) + (halfHeight * cosAngle);
|
||||
|
||||
RectShape2Drawing rectangleShape = new RectShape2Drawing();
|
||||
rectangleShape.X = centerX;
|
||||
rectangleShape.Y = centerY;
|
||||
rectangleShape.CenterX = centerX;
|
||||
rectangleShape.CenterY = centerY;
|
||||
rectangleShape.HalfWidth = halfWidth;
|
||||
rectangleShape.HalfHeigth = halfHeight;
|
||||
rectangleShape.Angle = rectangle.Angle;
|
||||
Shapes.Add(rectangleShape);
|
||||
}
|
||||
}
|
||||
|
||||
private static bool AreFinite(params double[] values)
|
||||
{
|
||||
if (values == null)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
foreach (double value in values)
|
||||
{
|
||||
if (double.IsNaN(value) || double.IsInfinity(value))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,31 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace MainShell.Common
|
||||
{
|
||||
/// <summary>
|
||||
/// 一个简单的包装类,在对象被 Dispose 时执行指定的 Action。
|
||||
/// </summary>
|
||||
public class DisposableAction : IDisposable
|
||||
{
|
||||
private readonly Action _action;
|
||||
private bool _isDisposed;
|
||||
|
||||
public DisposableAction(Action action)
|
||||
{
|
||||
_action = action ?? throw new ArgumentNullException(nameof(action));
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
if (!_isDisposed)
|
||||
{
|
||||
_action();
|
||||
_isDisposed = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
181
MX-PD-盘古 - new/PanGu.DieBonderApp/MainShell/Common/Enums.cs
Normal file
181
MX-PD-盘古 - new/PanGu.DieBonderApp/MainShell/Common/Enums.cs
Normal file
@@ -0,0 +1,181 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace MainShell.Common
|
||||
{
|
||||
public enum MachineMode { Manual, Auto, Maintenance }
|
||||
|
||||
public enum SpeedType
|
||||
{
|
||||
[Description("低速")]
|
||||
Low,
|
||||
[Description("中速")]
|
||||
Medium,
|
||||
[Description("高速")]
|
||||
High
|
||||
}
|
||||
|
||||
public enum DieTransferRowTraversalStrategy
|
||||
{
|
||||
[Description("全部正向")]
|
||||
AllPositive = 0,
|
||||
|
||||
[Description("全部反向")]
|
||||
AllNegative = 1,
|
||||
|
||||
[Description("蛇形")]
|
||||
Serpentine = 2
|
||||
}
|
||||
public enum BondingPathMode
|
||||
{
|
||||
S形打件 = 1,
|
||||
Z形正向打件,
|
||||
Z形反向打件,
|
||||
}
|
||||
|
||||
public enum BondingStagePathMode
|
||||
{
|
||||
S型区域打件 = 1,
|
||||
Stage正向区域打件,
|
||||
Stage负向区域打件,
|
||||
}
|
||||
|
||||
public enum BondingWSPathMode
|
||||
{
|
||||
S型打件 = 1,
|
||||
WS正向区域打件,
|
||||
WS负向区域打件,
|
||||
}
|
||||
|
||||
public enum RunningMode
|
||||
{
|
||||
生产检测 = 1,
|
||||
老化测试,
|
||||
|
||||
}
|
||||
|
||||
public enum CameraType
|
||||
{
|
||||
TopPositionCamera,
|
||||
TopWsCamera,
|
||||
TopWideCamera,
|
||||
TopWideWsCamera,
|
||||
MapCamera
|
||||
}
|
||||
|
||||
public enum TransPathType
|
||||
{
|
||||
[Description("就近")]
|
||||
Nearest,
|
||||
[Description("顺序")]
|
||||
Sequence,
|
||||
}
|
||||
|
||||
public enum TransPathDirection
|
||||
{
|
||||
[Description("正向")]
|
||||
Positive,
|
||||
[Description("反向")]
|
||||
Negative,
|
||||
}
|
||||
|
||||
public enum DieState
|
||||
{
|
||||
[Description("可使用")]
|
||||
Available,
|
||||
[Description("已使用")]
|
||||
Used,
|
||||
[Description("错误")]
|
||||
Error,
|
||||
[Description("不存在")]
|
||||
NotExist,
|
||||
[Description("当前")]
|
||||
Current,
|
||||
[Description("目标")]
|
||||
Target
|
||||
}
|
||||
|
||||
public enum ProcessExecutionStatus
|
||||
{
|
||||
Unknown = 0,
|
||||
Running,
|
||||
Paused,
|
||||
Canceled,
|
||||
Faulted,
|
||||
Completed
|
||||
}
|
||||
|
||||
public enum FlowDisplayStage
|
||||
{
|
||||
Load = 0,
|
||||
Align = 1,
|
||||
Bond = 2,
|
||||
Inspect = 3,
|
||||
Unload = 4
|
||||
}
|
||||
|
||||
public enum WaferScanMode
|
||||
{
|
||||
[Description("按需扫描")]
|
||||
ScanOnDemand,
|
||||
|
||||
[Description("全扫")]
|
||||
FullScan,
|
||||
}
|
||||
|
||||
public enum BondingSection
|
||||
{
|
||||
/// <summary>
|
||||
/// A区
|
||||
/// </summary>
|
||||
A,
|
||||
/// <summary>
|
||||
/// B区
|
||||
/// </summary>
|
||||
B
|
||||
}
|
||||
|
||||
public enum ComSupMotionType
|
||||
{
|
||||
/// <summary>
|
||||
/// 干涉写入
|
||||
/// </summary>
|
||||
Interfere = 102,
|
||||
/// <summary>
|
||||
/// 回零写入
|
||||
/// </summary>
|
||||
Home = 103,
|
||||
/// <summary>
|
||||
/// 快打执行
|
||||
/// </summary>
|
||||
FastBonding = 200,
|
||||
/// <summary>
|
||||
/// 慢打执行
|
||||
/// </summary>
|
||||
SlowBonding = 201,
|
||||
/// <summary>
|
||||
/// 报警清楚
|
||||
/// </summary>
|
||||
AlarmClear = 104,
|
||||
/// <summary>
|
||||
/// 切PID指定
|
||||
/// </summary>
|
||||
ChangePid = 301,
|
||||
/// <summary>
|
||||
/// 触发报警
|
||||
/// </summary>
|
||||
OccurAlarm = 105,
|
||||
/// <summary>
|
||||
/// 同步PID参数
|
||||
/// </summary>
|
||||
SyncPIDParam = 106,
|
||||
/// <summary>
|
||||
/// 手动设置刺针次数
|
||||
/// </summary>
|
||||
NeedleWorkCount = 302,
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
using MwFramework.Device;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace MainShell.Common.Extension
|
||||
{
|
||||
public static class DeviceExtension
|
||||
{
|
||||
private static readonly int _taskNum = 3;
|
||||
public static void GetLastSamples(this IDiastimeter diastimeter, out double distance)
|
||||
{
|
||||
var doubles = new List<double>();
|
||||
for (int i = 0; i < _taskNum; i++)
|
||||
{
|
||||
diastimeter.GetLastSample(out double val);
|
||||
if (val != double.NaN)
|
||||
doubles.Add(val);
|
||||
}
|
||||
distance = doubles.Average();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,78 @@
|
||||
using System.Windows;
|
||||
using System.Windows.Controls;
|
||||
using System.Windows.Controls.Primitives;
|
||||
using System.Windows.Data;
|
||||
using System.Windows.Input;
|
||||
using System.Windows.Media;
|
||||
|
||||
namespace MainShell.Common
|
||||
{
|
||||
public static class FocusedEditorCommitHelper
|
||||
{
|
||||
public static void CommitFocusedEditorChanges()
|
||||
{
|
||||
var focusedElement = Keyboard.FocusedElement as DependencyObject;
|
||||
if (focusedElement == null)
|
||||
return;
|
||||
|
||||
CommitBinding(focusedElement);
|
||||
|
||||
var dataGrid = FindAncestor<DataGrid>(focusedElement);
|
||||
if (dataGrid != null)
|
||||
{
|
||||
dataGrid.CommitEdit(DataGridEditingUnit.Cell, true);
|
||||
dataGrid.CommitEdit(DataGridEditingUnit.Row, true);
|
||||
}
|
||||
}
|
||||
|
||||
private static void CommitBinding(DependencyObject dependencyObject)
|
||||
{
|
||||
if (dependencyObject is TextBox textBox)
|
||||
{
|
||||
textBox.GetBindingExpression(TextBox.TextProperty)?.UpdateSource();
|
||||
return;
|
||||
}
|
||||
|
||||
if (dependencyObject is ComboBox comboBox)
|
||||
{
|
||||
comboBox.GetBindingExpression(Selector.SelectedItemProperty)?.UpdateSource();
|
||||
comboBox.GetBindingExpression(ComboBox.TextProperty)?.UpdateSource();
|
||||
return;
|
||||
}
|
||||
|
||||
if (dependencyObject is ToggleButton toggleButton)
|
||||
{
|
||||
toggleButton.GetBindingExpression(ToggleButton.IsCheckedProperty)?.UpdateSource();
|
||||
}
|
||||
}
|
||||
|
||||
private static T FindAncestor<T>(DependencyObject dependencyObject) where T : DependencyObject
|
||||
{
|
||||
var current = dependencyObject;
|
||||
while (current != null)
|
||||
{
|
||||
if (current is T target)
|
||||
return target;
|
||||
|
||||
current = GetParent(current);
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
private static DependencyObject GetParent(DependencyObject dependencyObject)
|
||||
{
|
||||
if (dependencyObject is FrameworkElement frameworkElement)
|
||||
{
|
||||
return frameworkElement.Parent ?? VisualTreeHelper.GetParent(frameworkElement);
|
||||
}
|
||||
|
||||
if (dependencyObject is FrameworkContentElement frameworkContentElement)
|
||||
{
|
||||
return frameworkContentElement.Parent;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,380 @@
|
||||
using MainShell.Resources.CustomControl;
|
||||
using MaxwellFramework.Core.Events;
|
||||
using Stylet;
|
||||
using System;
|
||||
using System.ComponentModel;
|
||||
using System.Windows;
|
||||
using System.Windows.Media;
|
||||
|
||||
namespace MainShell.Common
|
||||
{
|
||||
public class HeaderDeviceStatusController : PropertyChangedBase, IHandle<MainViewSelectedPageChangeEvent>
|
||||
{
|
||||
private enum HeaderDeviceStatusTone
|
||||
{
|
||||
Auto,
|
||||
Manual,
|
||||
Maintenance,
|
||||
Recipe,
|
||||
Settings,
|
||||
Calibration,
|
||||
Unknown
|
||||
}
|
||||
|
||||
private readonly IEventAggregator _eventAggregator;
|
||||
private bool _hasLoadingStarted;
|
||||
private bool _isVisible;
|
||||
private string _labelText = string.Empty;
|
||||
private string _statusText = string.Empty;
|
||||
private Brush _badgeBackgroundBrush;
|
||||
private Brush _badgeBorderBrush;
|
||||
private Brush _labelForegroundBrush;
|
||||
private Brush _statusForegroundBrush;
|
||||
private Brush _indicatorBrush;
|
||||
|
||||
public HeaderDeviceStatusController(IEventAggregator eventAggregator)
|
||||
{
|
||||
_eventAggregator = eventAggregator ?? throw new ArgumentNullException(nameof(eventAggregator));
|
||||
|
||||
_eventAggregator.Subscribe(this);
|
||||
LoadingService.Instance.PropertyChanged += OnLoadingServicePropertyChanged;
|
||||
UpdateStatusText("Home");
|
||||
IsVisible = false;
|
||||
}
|
||||
|
||||
public bool IsVisible
|
||||
{
|
||||
get
|
||||
{
|
||||
return _isVisible;
|
||||
}
|
||||
private set
|
||||
{
|
||||
SetAndNotify(ref _isVisible, value);
|
||||
}
|
||||
}
|
||||
|
||||
public string LabelText
|
||||
{
|
||||
get
|
||||
{
|
||||
return _labelText;
|
||||
}
|
||||
private set
|
||||
{
|
||||
SetAndNotify(ref _labelText, value);
|
||||
}
|
||||
}
|
||||
|
||||
public string StatusText
|
||||
{
|
||||
get
|
||||
{
|
||||
return _statusText;
|
||||
}
|
||||
private set
|
||||
{
|
||||
SetAndNotify(ref _statusText, value);
|
||||
}
|
||||
}
|
||||
|
||||
public Brush BadgeBackgroundBrush
|
||||
{
|
||||
get
|
||||
{
|
||||
return _badgeBackgroundBrush;
|
||||
}
|
||||
private set
|
||||
{
|
||||
SetAndNotify(ref _badgeBackgroundBrush, value);
|
||||
}
|
||||
}
|
||||
|
||||
public Brush BadgeBorderBrush
|
||||
{
|
||||
get
|
||||
{
|
||||
return _badgeBorderBrush;
|
||||
}
|
||||
private set
|
||||
{
|
||||
SetAndNotify(ref _badgeBorderBrush, value);
|
||||
}
|
||||
}
|
||||
|
||||
public Brush LabelForegroundBrush
|
||||
{
|
||||
get
|
||||
{
|
||||
return _labelForegroundBrush;
|
||||
}
|
||||
private set
|
||||
{
|
||||
SetAndNotify(ref _labelForegroundBrush, value);
|
||||
}
|
||||
}
|
||||
|
||||
public Brush StatusForegroundBrush
|
||||
{
|
||||
get
|
||||
{
|
||||
return _statusForegroundBrush;
|
||||
}
|
||||
private set
|
||||
{
|
||||
SetAndNotify(ref _statusForegroundBrush, value);
|
||||
}
|
||||
}
|
||||
|
||||
public Brush IndicatorBrush
|
||||
{
|
||||
get
|
||||
{
|
||||
return _indicatorBrush;
|
||||
}
|
||||
private set
|
||||
{
|
||||
SetAndNotify(ref _indicatorBrush, value);
|
||||
}
|
||||
}
|
||||
|
||||
public void Handle(MainViewSelectedPageChangeEvent message)
|
||||
{
|
||||
if (message == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
UpdateStatusText(message.SelectePageName);
|
||||
if (!LoadingService.Instance.IsBusy)
|
||||
{
|
||||
IsVisible = true;
|
||||
}
|
||||
}
|
||||
|
||||
private void OnLoadingServicePropertyChanged(object sender, PropertyChangedEventArgs e)
|
||||
{
|
||||
if (!string.Equals(e.PropertyName, nameof(LoadingService.IsBusy), StringComparison.Ordinal))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (LoadingService.Instance.IsBusy)
|
||||
{
|
||||
_hasLoadingStarted = true;
|
||||
IsVisible = false;
|
||||
return;
|
||||
}
|
||||
|
||||
if (_hasLoadingStarted)
|
||||
{
|
||||
IsVisible = true;
|
||||
}
|
||||
}
|
||||
|
||||
private void UpdateStatusText(string pageName)
|
||||
{
|
||||
string resourceKey;
|
||||
HeaderDeviceStatusTone tone;
|
||||
|
||||
ResolveStatusDefinition(pageName, out resourceKey, out tone);
|
||||
|
||||
LabelText = GetResourceText("HeaderDeviceStatusLabel", "<22><>ǰ״̬:");
|
||||
StatusText = GetResourceText(resourceKey, GetFallbackStatusText(tone));
|
||||
ApplyTone(tone);
|
||||
}
|
||||
|
||||
private static void ResolveStatusDefinition(string pageName, out string resourceKey, out HeaderDeviceStatusTone tone)
|
||||
{
|
||||
if (string.Equals(pageName, "Home", StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
resourceKey = "HeaderDeviceModeAuto";
|
||||
tone = HeaderDeviceStatusTone.Auto;
|
||||
return;
|
||||
}
|
||||
|
||||
if (string.Equals(pageName, "ManualOperate", StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
resourceKey = "HeaderDeviceModeManual";
|
||||
tone = HeaderDeviceStatusTone.Manual;
|
||||
return;
|
||||
}
|
||||
|
||||
if (string.Equals(pageName, "MenuDeviceMaint", StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
resourceKey = "HeaderDeviceModeMaintenance";
|
||||
tone = HeaderDeviceStatusTone.Maintenance;
|
||||
return;
|
||||
}
|
||||
|
||||
if (string.Equals(pageName, "Recipe", StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
resourceKey = "HeaderDeviceModeRecipe";
|
||||
tone = HeaderDeviceStatusTone.Recipe;
|
||||
return;
|
||||
}
|
||||
|
||||
if (string.Equals(pageName, "PageSettings", StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
resourceKey = "HeaderDeviceModeSettings";
|
||||
tone = HeaderDeviceStatusTone.Settings;
|
||||
return;
|
||||
}
|
||||
|
||||
if (string.Equals(pageName, "PageCalib", StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
resourceKey = "HeaderDeviceModeCalibration";
|
||||
tone = HeaderDeviceStatusTone.Calibration;
|
||||
return;
|
||||
}
|
||||
|
||||
resourceKey = "HeaderDeviceModeUnknown";
|
||||
tone = HeaderDeviceStatusTone.Unknown;
|
||||
}
|
||||
|
||||
private static string GetFallbackStatusText(HeaderDeviceStatusTone tone)
|
||||
{
|
||||
switch (tone)
|
||||
{
|
||||
case HeaderDeviceStatusTone.Auto:
|
||||
return "<22>Զ<EFBFBD><D4B6><EFBFBD><EFBFBD><EFBFBD> (AUTO)";
|
||||
|
||||
case HeaderDeviceStatusTone.Manual:
|
||||
return "<22>ֶ<EFBFBD><D6B6><EFBFBD><EFBFBD><EFBFBD> (MANUAL)";
|
||||
|
||||
case HeaderDeviceStatusTone.Maintenance:
|
||||
return "<22>豸ά<E8B1B8><CEAC> (MAINT)";
|
||||
|
||||
case HeaderDeviceStatusTone.Recipe:
|
||||
return "<22>䷽<EFBFBD>༭ (RECIPE)";
|
||||
|
||||
case HeaderDeviceStatusTone.Settings:
|
||||
return "<22><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> (SETUP)";
|
||||
|
||||
case HeaderDeviceStatusTone.Calibration:
|
||||
return "<22>궨У (CALIB)";
|
||||
|
||||
default:
|
||||
return "״̬<D7B4><CCAC><EFBFBD><EFBFBD> (PENDING)";
|
||||
}
|
||||
}
|
||||
|
||||
private void ApplyTone(HeaderDeviceStatusTone tone)
|
||||
{
|
||||
BadgeBackgroundBrush = CreateBackgroundBrush(tone);
|
||||
BadgeBorderBrush = CreateBorderBrush(tone);
|
||||
LabelForegroundBrush = CreateSolidBrush(198, 221, 255);
|
||||
StatusForegroundBrush = Brushes.White;
|
||||
IndicatorBrush = CreateIndicatorBrush(tone);
|
||||
}
|
||||
|
||||
private static Brush CreateBackgroundBrush(HeaderDeviceStatusTone tone)
|
||||
{
|
||||
switch (tone)
|
||||
{
|
||||
case HeaderDeviceStatusTone.Auto:
|
||||
return CreateGradientBrush(Color.FromRgb(42, 111, 84), Color.FromRgb(24, 79, 60));
|
||||
|
||||
case HeaderDeviceStatusTone.Manual:
|
||||
return CreateGradientBrush(Color.FromRgb(148, 103, 37), Color.FromRgb(104, 72, 24));
|
||||
|
||||
case HeaderDeviceStatusTone.Maintenance:
|
||||
return CreateGradientBrush(Color.FromRgb(46, 104, 164), Color.FromRgb(31, 74, 125));
|
||||
|
||||
case HeaderDeviceStatusTone.Recipe:
|
||||
return CreateGradientBrush(Color.FromRgb(95, 76, 153), Color.FromRgb(68, 54, 111));
|
||||
|
||||
case HeaderDeviceStatusTone.Settings:
|
||||
return CreateGradientBrush(Color.FromRgb(88, 103, 124), Color.FromRgb(62, 74, 92));
|
||||
|
||||
case HeaderDeviceStatusTone.Calibration:
|
||||
return CreateGradientBrush(Color.FromRgb(34, 124, 141), Color.FromRgb(23, 90, 102));
|
||||
|
||||
default:
|
||||
return CreateGradientBrush(Color.FromRgb(50, 102, 177), Color.FromRgb(35, 78, 140));
|
||||
}
|
||||
}
|
||||
|
||||
private static Brush CreateBorderBrush(HeaderDeviceStatusTone tone)
|
||||
{
|
||||
switch (tone)
|
||||
{
|
||||
case HeaderDeviceStatusTone.Auto:
|
||||
return CreateSolidBrush(94, 169, 128);
|
||||
|
||||
case HeaderDeviceStatusTone.Manual:
|
||||
return CreateSolidBrush(201, 151, 76);
|
||||
|
||||
case HeaderDeviceStatusTone.Maintenance:
|
||||
return CreateSolidBrush(94, 148, 206);
|
||||
|
||||
case HeaderDeviceStatusTone.Recipe:
|
||||
return CreateSolidBrush(130, 112, 192);
|
||||
|
||||
case HeaderDeviceStatusTone.Settings:
|
||||
return CreateSolidBrush(126, 143, 166);
|
||||
|
||||
case HeaderDeviceStatusTone.Calibration:
|
||||
return CreateSolidBrush(79, 170, 187);
|
||||
|
||||
default:
|
||||
return CreateSolidBrush(96, 145, 214);
|
||||
}
|
||||
}
|
||||
|
||||
private static Brush CreateIndicatorBrush(HeaderDeviceStatusTone tone)
|
||||
{
|
||||
switch (tone)
|
||||
{
|
||||
case HeaderDeviceStatusTone.Auto:
|
||||
return CreateSolidBrush(63, 227, 123);
|
||||
|
||||
case HeaderDeviceStatusTone.Manual:
|
||||
return CreateSolidBrush(255, 183, 66);
|
||||
|
||||
case HeaderDeviceStatusTone.Maintenance:
|
||||
return CreateSolidBrush(72, 196, 255);
|
||||
|
||||
case HeaderDeviceStatusTone.Recipe:
|
||||
return CreateSolidBrush(173, 121, 255);
|
||||
|
||||
case HeaderDeviceStatusTone.Settings:
|
||||
return CreateSolidBrush(158, 172, 196);
|
||||
|
||||
case HeaderDeviceStatusTone.Calibration:
|
||||
return CreateSolidBrush(70, 231, 219);
|
||||
|
||||
default:
|
||||
return CreateSolidBrush(255, 93, 93);
|
||||
}
|
||||
}
|
||||
|
||||
private static Brush CreateSolidBrush(byte red, byte green, byte blue)
|
||||
{
|
||||
return new SolidColorBrush(Color.FromRgb(red, green, blue));
|
||||
}
|
||||
|
||||
private static Brush CreateGradientBrush(Color startColor, Color endColor)
|
||||
{
|
||||
return new LinearGradientBrush(startColor, endColor, 0.0);
|
||||
}
|
||||
|
||||
private static string GetResourceText(string resourceKey, string fallback)
|
||||
{
|
||||
Application application = Application.Current;
|
||||
if (application == null)
|
||||
{
|
||||
return fallback;
|
||||
}
|
||||
|
||||
object resource = application.TryFindResource(resourceKey);
|
||||
string text = resource as string;
|
||||
if (!string.IsNullOrWhiteSpace(text))
|
||||
{
|
||||
return text;
|
||||
}
|
||||
|
||||
return fallback;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,607 @@
|
||||
using MainShell.Resources.CustomControl;
|
||||
using Newtonsoft.Json;
|
||||
using Stylet;
|
||||
using System;
|
||||
using System.Globalization;
|
||||
using System.IO;
|
||||
using System.Windows;
|
||||
using System.Windows.Controls;
|
||||
using System.Windows.Controls.Primitives;
|
||||
using System.Windows.Data;
|
||||
using System.Windows.Input;
|
||||
using System.Windows.Media;
|
||||
using System.Windows.Threading;
|
||||
|
||||
namespace MainShell.Common
|
||||
{
|
||||
public static class HeaderDeviceStatusOverlayHost
|
||||
{
|
||||
private static readonly object OverlayRootTag = new object();
|
||||
private static readonly HeaderDeviceStatusOverlaySettings OverlaySettings = new HeaderDeviceStatusOverlaySettings();
|
||||
|
||||
public static void Attach(Window window, HeaderDeviceStatusController controller)
|
||||
{
|
||||
if (window == null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(window));
|
||||
}
|
||||
|
||||
if (controller == null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(controller));
|
||||
}
|
||||
|
||||
window.Dispatcher.BeginInvoke(
|
||||
DispatcherPriority.Loaded,
|
||||
new Action(() => AttachCore(window, controller)));
|
||||
}
|
||||
|
||||
private static void AttachCore(Window window, HeaderDeviceStatusController controller)
|
||||
{
|
||||
Grid existingOverlayRoot = window.Content as Grid;
|
||||
if (existingOverlayRoot != null && ReferenceEquals(existingOverlayRoot.Tag, OverlayRootTag))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
UIElement currentContent = window.Content as UIElement;
|
||||
if (currentContent == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
Grid overlayRoot = new Grid();
|
||||
overlayRoot.Tag = OverlayRootTag;
|
||||
|
||||
window.Content = null;
|
||||
overlayRoot.Children.Add(currentContent);
|
||||
overlayRoot.Children.Add(CreateOverlayElement(controller));
|
||||
overlayRoot.Children.Add(CreateDebugPanelElement());
|
||||
window.Content = overlayRoot;
|
||||
}
|
||||
|
||||
private static FrameworkElement CreateOverlayElement(HeaderDeviceStatusController controller)
|
||||
{
|
||||
HeaderDeviceStatusView statusView = new HeaderDeviceStatusView();
|
||||
statusView.DataContext = controller;
|
||||
statusView.IsHitTestVisible = false;
|
||||
statusView.HorizontalAlignment = HorizontalAlignment.Left;
|
||||
statusView.VerticalAlignment = VerticalAlignment.Top;
|
||||
|
||||
Binding marginBinding = new Binding(nameof(HeaderDeviceStatusOverlaySettings.Margin));
|
||||
marginBinding.Source = OverlaySettings;
|
||||
BindingOperations.SetBinding(statusView, FrameworkElement.MarginProperty, marginBinding);
|
||||
|
||||
Panel.SetZIndex(statusView, short.MaxValue);
|
||||
return statusView;
|
||||
}
|
||||
|
||||
private static FrameworkElement CreateDebugPanelElement()
|
||||
{
|
||||
Border panelBorder = new Border();
|
||||
panelBorder.Background = new SolidColorBrush(Color.FromArgb(235, 18, 26, 35));
|
||||
panelBorder.BorderBrush = new SolidColorBrush(Color.FromRgb(72, 93, 118));
|
||||
panelBorder.BorderThickness = new Thickness(1.0);
|
||||
panelBorder.CornerRadius = new CornerRadius(6.0);
|
||||
panelBorder.Padding = new Thickness(10.0, 8.0, 10.0, 8.0);
|
||||
panelBorder.HorizontalAlignment = HorizontalAlignment.Left;
|
||||
panelBorder.VerticalAlignment = VerticalAlignment.Top;
|
||||
|
||||
Binding panelMarginBinding = new Binding(nameof(HeaderDeviceStatusOverlaySettings.DebugPanelMargin));
|
||||
panelMarginBinding.Source = OverlaySettings;
|
||||
BindingOperations.SetBinding(panelBorder, FrameworkElement.MarginProperty, panelMarginBinding);
|
||||
|
||||
Binding panelVisibilityBinding = new Binding(nameof(HeaderDeviceStatusOverlaySettings.IsDebugPanelVisible));
|
||||
panelVisibilityBinding.Source = OverlaySettings;
|
||||
panelVisibilityBinding.Converter = new BooleanToVisibilityConverter();
|
||||
BindingOperations.SetBinding(panelBorder, UIElement.VisibilityProperty, panelVisibilityBinding);
|
||||
|
||||
StackPanel rootPanel = new StackPanel();
|
||||
rootPanel.Orientation = Orientation.Vertical;
|
||||
|
||||
DockPanel headerPanel = new DockPanel();
|
||||
|
||||
TextBlock titleText = new TextBlock();
|
||||
titleText.Text = "Overlay Debug";
|
||||
titleText.Foreground = Brushes.White;
|
||||
titleText.FontSize = 13.0;
|
||||
titleText.FontWeight = FontWeights.SemiBold;
|
||||
titleText.Margin = new Thickness(0.0, 0.0, 8.0, 6.0);
|
||||
DockPanel.SetDock(titleText, Dock.Left);
|
||||
headerPanel.Children.Add(titleText);
|
||||
|
||||
Button closeButton = CreateDebugButton("<22><><EFBFBD><EFBFBD>", 44.0);
|
||||
closeButton.Margin = new Thickness(6.0, 0.0, 0.0, 6.0);
|
||||
closeButton.Click += delegate(object sender, RoutedEventArgs e)
|
||||
{
|
||||
OverlaySettings.HideDebugPanel();
|
||||
};
|
||||
DockPanel.SetDock(closeButton, Dock.Right);
|
||||
headerPanel.Children.Add(closeButton);
|
||||
|
||||
rootPanel.Children.Add(headerPanel);
|
||||
|
||||
TextBlock summaryText = new TextBlock();
|
||||
summaryText.Foreground = new SolidColorBrush(Color.FromRgb(210, 221, 236));
|
||||
summaryText.FontSize = 12.0;
|
||||
summaryText.Margin = new Thickness(0.0, 0.0, 0.0, 8.0);
|
||||
Binding summaryBinding = new Binding(nameof(HeaderDeviceStatusOverlaySettings.PositionSummary));
|
||||
summaryBinding.Source = OverlaySettings;
|
||||
BindingOperations.SetBinding(summaryText, TextBlock.TextProperty, summaryBinding);
|
||||
rootPanel.Children.Add(summaryText);
|
||||
|
||||
rootPanel.Children.Add(CreateDebugInputRow("Left", nameof(HeaderDeviceStatusOverlaySettings.LeftMarginText)));
|
||||
rootPanel.Children.Add(CreateDebugInputRow("Top", nameof(HeaderDeviceStatusOverlaySettings.TopMarginText)));
|
||||
rootPanel.Children.Add(CreateDebugInputRow("Step", nameof(HeaderDeviceStatusOverlaySettings.StepText)));
|
||||
|
||||
UniformGrid actionGrid = new UniformGrid();
|
||||
actionGrid.Columns = 4;
|
||||
actionGrid.Rows = 1;
|
||||
actionGrid.Margin = new Thickness(0.0, 0.0, 0.0, 8.0);
|
||||
|
||||
Button leftButton = CreateDebugButton("<22><>", 40.0);
|
||||
leftButton.Click += delegate(object sender, RoutedEventArgs e)
|
||||
{
|
||||
OverlaySettings.AdjustMargin(-OverlaySettings.Step, 0.0);
|
||||
};
|
||||
actionGrid.Children.Add(leftButton);
|
||||
|
||||
Button rightButton = CreateDebugButton("<22><>", 40.0);
|
||||
rightButton.Click += delegate(object sender, RoutedEventArgs e)
|
||||
{
|
||||
OverlaySettings.AdjustMargin(OverlaySettings.Step, 0.0);
|
||||
};
|
||||
actionGrid.Children.Add(rightButton);
|
||||
|
||||
Button upButton = CreateDebugButton("<22><>", 40.0);
|
||||
upButton.Click += delegate(object sender, RoutedEventArgs e)
|
||||
{
|
||||
OverlaySettings.AdjustMargin(0.0, -OverlaySettings.Step);
|
||||
};
|
||||
actionGrid.Children.Add(upButton);
|
||||
|
||||
Button downButton = CreateDebugButton("<22><>", 40.0);
|
||||
downButton.Click += delegate(object sender, RoutedEventArgs e)
|
||||
{
|
||||
OverlaySettings.AdjustMargin(0.0, OverlaySettings.Step);
|
||||
};
|
||||
actionGrid.Children.Add(downButton);
|
||||
|
||||
rootPanel.Children.Add(actionGrid);
|
||||
|
||||
Button applyButton = CreateDebugButton("Ӧ<><D3A6>", 0.0);
|
||||
applyButton.Width = 178.0;
|
||||
applyButton.Margin = new Thickness(0.0, 0.0, 0.0, 0.0);
|
||||
applyButton.Click += delegate(object sender, RoutedEventArgs e)
|
||||
{
|
||||
OverlaySettings.ApplyTextValues();
|
||||
};
|
||||
rootPanel.Children.Add(applyButton);
|
||||
|
||||
panelBorder.Child = rootPanel;
|
||||
Panel.SetZIndex(panelBorder, short.MaxValue);
|
||||
return panelBorder;
|
||||
}
|
||||
|
||||
private static FrameworkElement CreateDebugInputRow(string labelText, string bindingPath)
|
||||
{
|
||||
Grid rowGrid = new Grid();
|
||||
rowGrid.Margin = new Thickness(0.0, 0.0, 0.0, 6.0);
|
||||
rowGrid.ColumnDefinitions.Add(new ColumnDefinition { Width = new GridLength(44.0) });
|
||||
rowGrid.ColumnDefinitions.Add(new ColumnDefinition { Width = new GridLength(92.0) });
|
||||
rowGrid.ColumnDefinitions.Add(new ColumnDefinition { Width = new GridLength(56.0) });
|
||||
|
||||
TextBlock label = new TextBlock();
|
||||
label.Text = labelText;
|
||||
label.Foreground = new SolidColorBrush(Color.FromRgb(210, 221, 236));
|
||||
label.FontSize = 12.0;
|
||||
label.VerticalAlignment = VerticalAlignment.Center;
|
||||
Grid.SetColumn(label, 0);
|
||||
rowGrid.Children.Add(label);
|
||||
|
||||
TextBox inputBox = CreateDebugTextBox(bindingPath);
|
||||
Grid.SetColumn(inputBox, 1);
|
||||
rowGrid.Children.Add(inputBox);
|
||||
|
||||
TextBlock hint = new TextBlock();
|
||||
hint.Text = "<22>س<EFBFBD>";
|
||||
hint.Foreground = new SolidColorBrush(Color.FromRgb(150, 167, 188));
|
||||
hint.FontSize = 11.0;
|
||||
hint.VerticalAlignment = VerticalAlignment.Center;
|
||||
hint.HorizontalAlignment = HorizontalAlignment.Right;
|
||||
Grid.SetColumn(hint, 2);
|
||||
rowGrid.Children.Add(hint);
|
||||
|
||||
return rowGrid;
|
||||
}
|
||||
|
||||
private static TextBox CreateDebugTextBox(string bindingPath)
|
||||
{
|
||||
TextBox inputBox = new TextBox();
|
||||
inputBox.Height = 26.0;
|
||||
inputBox.Margin = new Thickness(0.0);
|
||||
inputBox.Padding = new Thickness(6.0, 2.0, 6.0, 2.0);
|
||||
inputBox.Background = new SolidColorBrush(Color.FromRgb(33, 46, 60));
|
||||
inputBox.BorderBrush = new SolidColorBrush(Color.FromRgb(96, 122, 149));
|
||||
inputBox.Foreground = Brushes.White;
|
||||
inputBox.FontSize = 12.0;
|
||||
inputBox.VerticalContentAlignment = VerticalAlignment.Center;
|
||||
|
||||
Binding textBinding = new Binding(bindingPath);
|
||||
textBinding.Source = OverlaySettings;
|
||||
textBinding.Mode = BindingMode.TwoWay;
|
||||
textBinding.UpdateSourceTrigger = UpdateSourceTrigger.PropertyChanged;
|
||||
BindingOperations.SetBinding(inputBox, TextBox.TextProperty, textBinding);
|
||||
|
||||
inputBox.LostFocus += delegate(object sender, RoutedEventArgs e)
|
||||
{
|
||||
OverlaySettings.ApplyTextValues();
|
||||
};
|
||||
inputBox.KeyDown += delegate(object sender, KeyEventArgs e)
|
||||
{
|
||||
if (e.Key != Key.Enter)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
OverlaySettings.ApplyTextValues();
|
||||
e.Handled = true;
|
||||
};
|
||||
|
||||
return inputBox;
|
||||
}
|
||||
|
||||
private static Button CreateDebugButton(string content, double width)
|
||||
{
|
||||
Button button = new Button();
|
||||
button.Content = content;
|
||||
if (width > 0.0)
|
||||
{
|
||||
button.Width = width;
|
||||
}
|
||||
button.Height = 28.0;
|
||||
button.Margin = new Thickness(0.0, 0.0, 6.0, 0.0);
|
||||
button.Padding = new Thickness(4.0, 0.0, 4.0, 0.0);
|
||||
button.Background = new SolidColorBrush(Color.FromRgb(43, 62, 81));
|
||||
button.BorderBrush = new SolidColorBrush(Color.FromRgb(96, 122, 149));
|
||||
button.Foreground = Brushes.White;
|
||||
button.FontSize = 12.0;
|
||||
return button;
|
||||
}
|
||||
|
||||
private sealed class HeaderDeviceStatusOverlaySettings : PropertyChangedBase, IDisposable
|
||||
{
|
||||
private const double DefaultTopMargin = 8.0;
|
||||
private const double DefaultLeftMargin = 8.0;
|
||||
private const double DefaultDebugPanelTopOffset = 50.0;
|
||||
private const double DefaultAdjustStep = 1.0;
|
||||
private const string ConfigurationDirectoryName = "Configuration";
|
||||
private const string ConfigurationFileName = "HeaderDeviceStatusOverlay.json";
|
||||
|
||||
private readonly string _configurationDirectoryPath;
|
||||
private readonly string _configurationFilePath;
|
||||
private readonly FileSystemWatcher _fileWatcher;
|
||||
private double _topMargin = DefaultTopMargin;
|
||||
private double _leftMargin = DefaultLeftMargin;
|
||||
private bool _isDebugPanelVisible;
|
||||
private double _step = DefaultAdjustStep;
|
||||
private string _leftMarginText = DefaultLeftMargin.ToString("0.##", CultureInfo.InvariantCulture);
|
||||
private string _topMarginText = DefaultTopMargin.ToString("0.##", CultureInfo.InvariantCulture);
|
||||
private string _stepText = DefaultAdjustStep.ToString("0.##", CultureInfo.InvariantCulture);
|
||||
|
||||
public HeaderDeviceStatusOverlaySettings()
|
||||
{
|
||||
_configurationDirectoryPath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, ConfigurationDirectoryName);
|
||||
_configurationFilePath = Path.Combine(_configurationDirectoryPath, ConfigurationFileName);
|
||||
|
||||
EnsureConfigurationFile();
|
||||
LoadFromFile();
|
||||
|
||||
_fileWatcher = new FileSystemWatcher(_configurationDirectoryPath, ConfigurationFileName);
|
||||
_fileWatcher.NotifyFilter = NotifyFilters.FileName | NotifyFilters.LastWrite | NotifyFilters.Size | NotifyFilters.CreationTime;
|
||||
_fileWatcher.Changed += OnConfigurationFileChanged;
|
||||
_fileWatcher.Created += OnConfigurationFileChanged;
|
||||
_fileWatcher.Renamed += OnConfigurationFileRenamed;
|
||||
_fileWatcher.EnableRaisingEvents = true;
|
||||
}
|
||||
|
||||
public Thickness Margin
|
||||
{
|
||||
get
|
||||
{
|
||||
return new Thickness(_leftMargin, _topMargin, 0.0, 0.0);
|
||||
}
|
||||
}
|
||||
|
||||
public Thickness DebugPanelMargin
|
||||
{
|
||||
get
|
||||
{
|
||||
return new Thickness(_leftMargin, _topMargin + DefaultDebugPanelTopOffset, 0.0, 0.0);
|
||||
}
|
||||
}
|
||||
|
||||
public bool IsDebugPanelVisible
|
||||
{
|
||||
get
|
||||
{
|
||||
return _isDebugPanelVisible;
|
||||
}
|
||||
}
|
||||
|
||||
public double Step
|
||||
{
|
||||
get
|
||||
{
|
||||
return _step;
|
||||
}
|
||||
}
|
||||
|
||||
public string LeftMarginText
|
||||
{
|
||||
get
|
||||
{
|
||||
return _leftMarginText;
|
||||
}
|
||||
set
|
||||
{
|
||||
SetAndNotify(ref _leftMarginText, value);
|
||||
}
|
||||
}
|
||||
|
||||
public string TopMarginText
|
||||
{
|
||||
get
|
||||
{
|
||||
return _topMarginText;
|
||||
}
|
||||
set
|
||||
{
|
||||
SetAndNotify(ref _topMarginText, value);
|
||||
}
|
||||
}
|
||||
|
||||
public string StepText
|
||||
{
|
||||
get
|
||||
{
|
||||
return _stepText;
|
||||
}
|
||||
set
|
||||
{
|
||||
SetAndNotify(ref _stepText, value);
|
||||
}
|
||||
}
|
||||
|
||||
public string PositionSummary
|
||||
{
|
||||
get
|
||||
{
|
||||
return string.Format("Left={0:0.##}, Top={1:0.##}, Step={2:0.##}", _leftMargin, _topMargin, _step);
|
||||
}
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
_fileWatcher.Changed -= OnConfigurationFileChanged;
|
||||
_fileWatcher.Created -= OnConfigurationFileChanged;
|
||||
_fileWatcher.Renamed -= OnConfigurationFileRenamed;
|
||||
_fileWatcher.Dispose();
|
||||
}
|
||||
|
||||
public void AdjustMargin(double leftOffset, double topOffset)
|
||||
{
|
||||
double leftMargin = _leftMargin + leftOffset;
|
||||
double topMargin = _topMargin + topOffset;
|
||||
|
||||
UpdateSettings(leftMargin, topMargin, _isDebugPanelVisible, _step);
|
||||
PersistCurrentConfiguration();
|
||||
}
|
||||
|
||||
public void HideDebugPanel()
|
||||
{
|
||||
UpdateSettings(_leftMargin, _topMargin, false, _step);
|
||||
PersistCurrentConfiguration();
|
||||
}
|
||||
|
||||
public void ApplyTextValues()
|
||||
{
|
||||
double leftMargin;
|
||||
double topMargin;
|
||||
double step;
|
||||
|
||||
bool canParseLeft = TryParseInput(LeftMarginText, _leftMargin, out leftMargin);
|
||||
bool canParseTop = TryParseInput(TopMarginText, _topMargin, out topMargin);
|
||||
bool canParseStep = TryParseInput(StepText, _step, out step);
|
||||
|
||||
if (!canParseStep)
|
||||
{
|
||||
step = _step;
|
||||
}
|
||||
|
||||
step = NormalizeStep(step);
|
||||
|
||||
UpdateSettings(leftMargin, topMargin, _isDebugPanelVisible, step);
|
||||
PersistCurrentConfiguration();
|
||||
}
|
||||
|
||||
private void OnConfigurationFileChanged(object sender, FileSystemEventArgs e)
|
||||
{
|
||||
ReloadOnUiThread();
|
||||
}
|
||||
|
||||
private void OnConfigurationFileRenamed(object sender, RenamedEventArgs e)
|
||||
{
|
||||
ReloadOnUiThread();
|
||||
}
|
||||
|
||||
private void ReloadOnUiThread()
|
||||
{
|
||||
Application currentApplication = Application.Current;
|
||||
if (currentApplication == null)
|
||||
{
|
||||
LoadFromFile();
|
||||
return;
|
||||
}
|
||||
|
||||
currentApplication.Dispatcher.BeginInvoke(
|
||||
DispatcherPriority.Background,
|
||||
new Action(LoadFromFile));
|
||||
}
|
||||
|
||||
private void EnsureConfigurationFile()
|
||||
{
|
||||
if (!Directory.Exists(_configurationDirectoryPath))
|
||||
{
|
||||
Directory.CreateDirectory(_configurationDirectoryPath);
|
||||
}
|
||||
|
||||
if (File.Exists(_configurationFilePath))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
HeaderDeviceStatusOverlayPositionConfiguration configuration = new HeaderDeviceStatusOverlayPositionConfiguration();
|
||||
configuration.TopMargin = DefaultTopMargin;
|
||||
configuration.LeftMargin = DefaultLeftMargin;
|
||||
configuration.ShowDebugPanel = false;
|
||||
configuration.AdjustStep = DefaultAdjustStep;
|
||||
SaveConfiguration(configuration);
|
||||
}
|
||||
|
||||
private void LoadFromFile()
|
||||
{
|
||||
HeaderDeviceStatusOverlayPositionConfiguration configuration = TryReadConfiguration();
|
||||
if (configuration == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
double topMargin = NormalizeMargin(configuration.TopMargin, DefaultTopMargin);
|
||||
double leftMargin = NormalizeMargin(configuration.LeftMargin, DefaultLeftMargin);
|
||||
double adjustStep = NormalizeStep(configuration.AdjustStep);
|
||||
UpdateSettings(leftMargin, topMargin, configuration.ShowDebugPanel, adjustStep);
|
||||
}
|
||||
|
||||
private HeaderDeviceStatusOverlayPositionConfiguration TryReadConfiguration()
|
||||
{
|
||||
for (int attempt = 0; attempt < 3; attempt++)
|
||||
{
|
||||
try
|
||||
{
|
||||
string content = File.ReadAllText(_configurationFilePath);
|
||||
if (string.IsNullOrWhiteSpace(content))
|
||||
{
|
||||
return new HeaderDeviceStatusOverlayPositionConfiguration();
|
||||
}
|
||||
|
||||
HeaderDeviceStatusOverlayPositionConfiguration configuration = JsonConvert.DeserializeObject<HeaderDeviceStatusOverlayPositionConfiguration>(content);
|
||||
return configuration ?? new HeaderDeviceStatusOverlayPositionConfiguration();
|
||||
}
|
||||
catch (IOException)
|
||||
{
|
||||
}
|
||||
catch (UnauthorizedAccessException)
|
||||
{
|
||||
}
|
||||
catch (JsonException)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
private void SaveConfiguration(HeaderDeviceStatusOverlayPositionConfiguration configuration)
|
||||
{
|
||||
string content = JsonConvert.SerializeObject(configuration, Formatting.Indented);
|
||||
File.WriteAllText(_configurationFilePath, content);
|
||||
}
|
||||
|
||||
private void PersistCurrentConfiguration()
|
||||
{
|
||||
HeaderDeviceStatusOverlayPositionConfiguration configuration = new HeaderDeviceStatusOverlayPositionConfiguration();
|
||||
configuration.TopMargin = _topMargin;
|
||||
configuration.LeftMargin = _leftMargin;
|
||||
configuration.ShowDebugPanel = _isDebugPanelVisible;
|
||||
configuration.AdjustStep = _step;
|
||||
SaveConfiguration(configuration);
|
||||
}
|
||||
|
||||
private static double NormalizeMargin(double value, double fallbackValue)
|
||||
{
|
||||
if (double.IsNaN(value) || double.IsInfinity(value))
|
||||
{
|
||||
return fallbackValue;
|
||||
}
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
private static double NormalizeStep(double value)
|
||||
{
|
||||
if (double.IsNaN(value) || double.IsInfinity(value) || value <= 0.0)
|
||||
{
|
||||
return DefaultAdjustStep;
|
||||
}
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
private void UpdateSettings(double leftMargin, double topMargin, bool isDebugPanelVisible, double step)
|
||||
{
|
||||
bool hasChanged = !leftMargin.Equals(_leftMargin)
|
||||
|| !topMargin.Equals(_topMargin)
|
||||
|| !isDebugPanelVisible.Equals(_isDebugPanelVisible)
|
||||
|| !step.Equals(_step);
|
||||
if (!hasChanged)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
_leftMargin = leftMargin;
|
||||
_topMargin = topMargin;
|
||||
_isDebugPanelVisible = isDebugPanelVisible;
|
||||
_step = step;
|
||||
LeftMarginText = FormatValue(_leftMargin);
|
||||
TopMarginText = FormatValue(_topMargin);
|
||||
StepText = FormatValue(_step);
|
||||
NotifyOfPropertyChange(nameof(Margin));
|
||||
NotifyOfPropertyChange(nameof(DebugPanelMargin));
|
||||
NotifyOfPropertyChange(nameof(IsDebugPanelVisible));
|
||||
NotifyOfPropertyChange(nameof(Step));
|
||||
NotifyOfPropertyChange(nameof(PositionSummary));
|
||||
}
|
||||
|
||||
private static bool TryParseInput(string text, double fallbackValue, out double value)
|
||||
{
|
||||
string trimmedText = string.IsNullOrWhiteSpace(text) ? string.Empty : text.Trim();
|
||||
if (string.IsNullOrEmpty(trimmedText))
|
||||
{
|
||||
value = fallbackValue;
|
||||
return false;
|
||||
}
|
||||
|
||||
return double.TryParse(trimmedText, NumberStyles.Float, CultureInfo.InvariantCulture, out value)
|
||||
|| double.TryParse(trimmedText, NumberStyles.Float, CultureInfo.CurrentCulture, out value);
|
||||
}
|
||||
|
||||
private static string FormatValue(double value)
|
||||
{
|
||||
return value.ToString("0.##", CultureInfo.InvariantCulture);
|
||||
}
|
||||
}
|
||||
|
||||
private sealed class HeaderDeviceStatusOverlayPositionConfiguration
|
||||
{
|
||||
public double TopMargin { get; set; }
|
||||
|
||||
public double LeftMargin { get; set; }
|
||||
|
||||
public bool ShowDebugPanel { get; set; }
|
||||
|
||||
public double AdjustStep { get; set; }
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,164 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Windows;
|
||||
|
||||
namespace MainShell.Common
|
||||
{
|
||||
/// <summary>
|
||||
/// Localization resource helper.
|
||||
/// </summary>
|
||||
public static class LanguageResourceHelper
|
||||
{
|
||||
private static readonly IReadOnlyDictionary<MessageKey, string> ResourceKeyMap =
|
||||
new Dictionary<MessageKey, string>
|
||||
{
|
||||
{ MessageKey.TitleInfo, "Msg_Title_Info" },
|
||||
{ MessageKey.TitleWarning, "Msg_Title_Warning" },
|
||||
{ MessageKey.TitleError, "Msg_Title_Error" },
|
||||
{ MessageKey.TitleConfirm, "Msg_Title_Confirm" },
|
||||
|
||||
{ MessageKey.VisionCameraNotFound, "Msg_Vision_CameraNotFound" },
|
||||
{ MessageKey.VisionCameraNotOpen, "Msg_Vision_CameraNotOpen" },
|
||||
{ MessageKey.VisionCameraNotGrabbing, "Msg_Vision_CameraNotGrabbing" },
|
||||
{ MessageKey.VisionCaptureTimeout, "Msg_Vision_CaptureTimeout" },
|
||||
{ MessageKey.VisionNoFrameReturned, "Msg_Vision_NoFrameReturned" },
|
||||
{ MessageKey.VisionSoftTriggerFailed, "Msg_Vision_SoftTriggerFailed" },
|
||||
{ MessageKey.VisionDriverError, "Msg_Vision_DriverError" },
|
||||
{ MessageKey.VisionImageIsNull, "Msg_Vision_ImageIsNull" },
|
||||
{ MessageKey.VisionRequestInvalid, "Msg_Vision_RequestInvalid" },
|
||||
{ MessageKey.VisionTimeoutInvalid, "Msg_Vision_TimeoutInvalid" },
|
||||
{ MessageKey.VisionOperationCancelled, "Msg_Vision_OperationCancelled" },
|
||||
{ MessageKey.VisionTemplatePathEmpty, "Msg_Vision_TemplatePathEmpty" },
|
||||
{ MessageKey.VisionTemplateRoiInvalid, "Msg_Vision_TemplateRoiInvalid" },
|
||||
{ MessageKey.VisionTemplateMinScoreInvalid, "Msg_Vision_TemplateMinScoreInvalid" },
|
||||
{ MessageKey.VisionTemplateAlgorithmNotImplemented, "Msg_Vision_TemplateAlgorithmNotImplemented" },
|
||||
{ MessageKey.VisionTemplateMatchFailed, "Msg_Vision_TemplateMatchFailed" },
|
||||
{ MessageKey.VisionCommonAlgorithmNotSupported, "Msg_Vision_CommonAlgorithmNotSupported" },
|
||||
{ MessageKey.VisionCommonAlgorithmExecutionFailed, "Msg_Vision_CommonAlgorithmExecutionFailed" },
|
||||
{ MessageKey.VisionChipMapSortInputInvalid, "Msg_Vision_ChipMapSortInputInvalid" },
|
||||
|
||||
{ MessageKey.CommonUnknownError, "Msg_Common_UnknownError" },
|
||||
{ MessageKey.CommonOperationSucceeded, "Msg_Common_OperationSucceeded" },
|
||||
{ MessageKey.CommonOperationFailed, "Msg_Common_OperationFailed" },
|
||||
{ MessageKey.CommonSaveSucceeded, "Msg_Common_SaveSucceeded" },
|
||||
{ MessageKey.CommonSaveFailed, "Msg_Common_SaveFailed" },
|
||||
{ MessageKey.AxisSoftLimitSaveConfirm, "Msg_AxisSoftLimit_SaveConfirm" },
|
||||
{ MessageKey.AxisSoftLimitSaveFailedWithReason, "Msg_AxisSoftLimit_SaveFailedWithReason" },
|
||||
{ MessageKey.AxisSoftLimitLoadFailedWithReason, "Msg_AxisSoftLimit_LoadFailedWithReason" },
|
||||
{ MessageKey.AxisSoftLimitRangeInvalid, "Msg_AxisSoftLimit_RangeInvalid" },
|
||||
{ MessageKey.AxisSoftLimitApplySucceeded, "Msg_AxisSoftLimit_ApplySucceeded" },
|
||||
{ MessageKey.AxisSoftLimitApplyFailedWithReason, "Msg_AxisSoftLimit_ApplyFailedWithReason" },
|
||||
{ MessageKey.AxisSoftLimitApplyAllSucceeded, "Msg_AxisSoftLimit_ApplyAllSucceeded" },
|
||||
{ MessageKey.AxisSoftLimitApplyAllFailedWithReason, "Msg_AxisSoftLimit_ApplyAllFailedWithReason" },
|
||||
{ MessageKey.AxisSoftLimitNoAxisData, "Msg_AxisSoftLimit_NoAxisData" },
|
||||
{ MessageKey.AxisSoftLimitSelectedAxisRequired, "Msg_AxisSoftLimit_SelectedAxisRequired" },
|
||||
{ MessageKey.CommonDeleteConfirm, "Msg_Common_DeleteConfirm" },
|
||||
{ MessageKey.CommonExitConfirm, "Msg_Common_ExitConfirm" },
|
||||
|
||||
{ MessageKey.DeviceNotInitialized, "Msg_Device_NotInitialized" },
|
||||
{ MessageKey.DeviceBusy, "Msg_Device_Busy" },
|
||||
{ MessageKey.DeviceDisconnected, "Msg_Device_Disconnected" },
|
||||
{ MessageKey.DeviceHomeRequired, "Msg_Device_HomeRequired" },
|
||||
|
||||
{ MessageKey.ParamInvalid, "Msg_Param_Invalid" },
|
||||
{ MessageKey.ParamEmpty, "Msg_Param_Empty" },
|
||||
{ MessageKey.ParamOutOfRange, "Msg_Param_OutOfRange" },
|
||||
|
||||
{ MessageKey.StartProcessConfirm, "Msg_Process_StartConfirm" },
|
||||
{ MessageKey.StartProcessFailed, "Msg_Process_StartFailed" },
|
||||
{ MessageKey.StopProcessConfirm, "Msg_Process_StopConfirm" },
|
||||
{ MessageKey.StopProcessFailed, "Msg_Process_StopFailed" },
|
||||
|
||||
{ MessageKey.ProcessFailed, "Msg_Process_Failed" },
|
||||
{ MessageKey.ProcessFailedWithReason, "Msg_Process_FailedWithReason" },
|
||||
{ MessageKey.ProcessStepFailedWithReason, "Msg_Process_StepFailedWithReason" },
|
||||
{ MessageKey.ProcessSubstratePositionFailedWithReason, "Msg_Process_SubstratePositionFailedWithReason" },
|
||||
{ MessageKey.ProcessSubstratePositionRecipeNotLoaded, "Msg_Process_SubstratePositionRecipeNotLoaded" },
|
||||
{ MessageKey.ProcessSubstratePositionMarkParameterMissing, "Msg_Process_SubstratePositionMarkParameterMissing" },
|
||||
{ MessageKey.ProcessSubstratePositionNoEnabledMarks, "Msg_Process_SubstratePositionNoEnabledMarks" },
|
||||
{ MessageKey.ProcessSubstratePositionAlignmentFailedWithReason, "Msg_Process_SubstratePositionAlignmentFailedWithReason" },
|
||||
{ MessageKey.ProcessDiePositionFailedWithReason, "Msg_Process_DiePositionFailedWithReason" },
|
||||
{ MessageKey.ProcessDiePositionRecipeNotLoaded, "Msg_Process_DiePositionRecipeNotLoaded" },
|
||||
{ MessageKey.ProcessDiePositionCoordinateGenerationMissing, "Msg_Process_DiePositionCoordinateGenerationMissing" },
|
||||
{ MessageKey.ProcessDiePositionWaferInfoMissing, "Msg_Process_DiePositionWaferInfoMissing" },
|
||||
{ MessageKey.ProcessSubstrateHeightMeasureFailedWithReason, "Msg_Process_SubstrateHeightMeasureFailedWithReason" },
|
||||
{ MessageKey.ProcessSubstrateHeightMeasureRecipeNotLoaded, "Msg_Process_SubstrateHeightMeasureRecipeNotLoaded" },
|
||||
{ MessageKey.ProcessSubstrateHeightMeasureSettingMissing, "Msg_Process_SubstrateHeightMeasureSettingMissing" },
|
||||
{ MessageKey.ProcessSubstrateHeightMeasureNoPoints, "Msg_Process_SubstrateHeightMeasureNoPoints" },
|
||||
{ MessageKey.ProcessSubstrateHeightMeasurePointPositionInvalid, "Msg_Process_SubstrateHeightMeasurePointPositionInvalid" },
|
||||
{ MessageKey.NeedleCalibrationLoadFailed, "Msg_NeedleCalibration_LoadFailed" },
|
||||
{ MessageKey.NeedleCalibrationTouchCountMustGreaterThanZero, "Msg_NeedleCalibration_TouchCountMustGreaterThanZero" },
|
||||
{ MessageKey.NeedleCalibrationCompleted, "Msg_NeedleCalibration_Completed" },
|
||||
{ MessageKey.NeedleCalibrationStopped, "Msg_NeedleCalibration_Stopped" },
|
||||
{ MessageKey.NeedleCalibrationCanceled, "Msg_NeedleCalibration_Canceled" },
|
||||
{ MessageKey.OriginCalibOpenVisionTemplateFailed, "Msg_OriginCalib_OpenVisionTemplateFailed" },
|
||||
{ MessageKey.OriginCalibAxisNotFound, "Msg_OriginCalib_AxisNotFound" },
|
||||
{ MessageKey.OriginCalibReadPositionFailed, "Msg_OriginCalib_ReadPositionFailed" },
|
||||
{ MessageKey.OriginCalibMoveFailed, "Msg_OriginCalib_MoveFailed" },
|
||||
{ MessageKey.OriginCalibDeleteAxisFailed, "Msg_OriginCalib_DeleteAxisFailed" },
|
||||
{ MessageKey.OriginCalibDeleteAxisDuringCalibration, "Msg_OriginCalib_DeleteAxisDuringCalibration" },
|
||||
{ MessageKey.OriginCalibCalibrationCanceled, "Msg_OriginCalib_CalibrationCanceled" },
|
||||
{ MessageKey.OriginCalibCalibrationFailed, "Msg_OriginCalib_CalibrationFailed" },
|
||||
{ MessageKey.OriginCalibConfigSaved, "Msg_OriginCalib_ConfigSaved" },
|
||||
{ MessageKey.OriginCalibConfigSaveFailed, "Msg_OriginCalib_ConfigSaveFailed" },
|
||||
{ MessageKey.OriginCalibNoCalibratedModules, "Msg_OriginCalib_NoCalibratedModules" },
|
||||
{ MessageKey.OriginCalibControllerWriteCompleted, "Msg_OriginCalib_ControllerWriteCompleted" },
|
||||
{ MessageKey.OriginCalibControllerWriteNotReady, "Msg_OriginCalib_ControllerWriteNotReady" },
|
||||
{ MessageKey.OriginCalibControllerWritePartialSuccess, "Msg_OriginCalib_ControllerWritePartialSuccess" },
|
||||
{ MessageKey.OriginCalibControllerWriteNotImplemented, "Msg_OriginCalib_ControllerWriteNotImplemented" },
|
||||
{ MessageKey.PidNoProfileSelected, "Msg_Pid_NoProfileSelected" },
|
||||
{ MessageKey.PidNoFilteringParameterSelected, "Msg_Pid_NoFilteringParameterSelected" },
|
||||
{ MessageKey.PidReadSucceeded, "Msg_Pid_ReadSucceeded" },
|
||||
{ MessageKey.PidReadFailed, "Msg_Pid_ReadFailed" },
|
||||
{ MessageKey.PidWriteSucceeded, "Msg_Pid_WriteSucceeded" },
|
||||
{ MessageKey.PidWriteFailed, "Msg_Pid_WriteFailed" },
|
||||
|
||||
{ MessageKey.DieRecheckSelectedPointRequired, "Msg_DieRecheck_SelectedPointRequired" },
|
||||
{ MessageKey.DieRecheckMoveDeviceUnavailable, "Msg_DieRecheck_MoveDeviceUnavailable" },
|
||||
{ MessageKey.DieRecheckStatusOk, "Msg_DieRecheck_StatusOk" },
|
||||
{ MessageKey.DieRecheckStatusMissingBond, "Msg_DieRecheck_StatusMissingBond" },
|
||||
{ MessageKey.DieRecheckStatusXExceeded, "Msg_DieRecheck_StatusXExceeded" },
|
||||
{ MessageKey.DieRecheckStatusYExceeded, "Msg_DieRecheck_StatusYExceeded" }
|
||||
};
|
||||
|
||||
public static string GetString(MessageKey messageKey)
|
||||
{
|
||||
return GetString(messageKey, messageKey.ToString());
|
||||
}
|
||||
|
||||
public static string GetString(MessageKey messageKey, string fallback)
|
||||
{
|
||||
if (messageKey == MessageKey.None)
|
||||
{
|
||||
return fallback ?? string.Empty;
|
||||
}
|
||||
|
||||
if (!ResourceKeyMap.TryGetValue(messageKey, out var resourceKey))
|
||||
{
|
||||
return fallback ?? messageKey.ToString();
|
||||
}
|
||||
|
||||
var application = Application.Current;
|
||||
if (application == null)
|
||||
{
|
||||
return fallback ?? resourceKey;
|
||||
}
|
||||
|
||||
var resource = application.TryFindResource(resourceKey);
|
||||
if (resource is string text && !string.IsNullOrWhiteSpace(text))
|
||||
{
|
||||
return text;
|
||||
}
|
||||
|
||||
return fallback ?? resourceKey;
|
||||
}
|
||||
|
||||
public static string Format(MessageKey messageKey, params object[] args)
|
||||
{
|
||||
var format = GetString(messageKey);
|
||||
return args == null || args.Length == 0
|
||||
? format
|
||||
: string.Format(format, args);
|
||||
}
|
||||
}
|
||||
}
|
||||
104
MX-PD-盘古 - new/PanGu.DieBonderApp/MainShell/Common/Loading.cs
Normal file
104
MX-PD-盘古 - new/PanGu.DieBonderApp/MainShell/Common/Loading.cs
Normal file
@@ -0,0 +1,104 @@
|
||||
using MainShell.Resources.CustomControl;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using System.Windows;
|
||||
using System.Windows.Controls;
|
||||
|
||||
namespace MainShell.Common
|
||||
{
|
||||
public static class Loading
|
||||
{
|
||||
|
||||
private static LoadingWaitView _view;
|
||||
|
||||
// 全局初始化:在主程序启动或插件加载时调用一次
|
||||
public static void Initialize(Window mainWindow)
|
||||
{
|
||||
if (_view != null) return; // 避免重复加载
|
||||
|
||||
_view = new LoadingWaitView();
|
||||
|
||||
// 获取窗口的根内容
|
||||
var rootContent = mainWindow.Content;
|
||||
|
||||
if (rootContent is Panel rootPanel)
|
||||
{
|
||||
// 如果根部本来就是 Panel (Grid/Canvas等),直接添加
|
||||
rootPanel.Children.Add(_view);
|
||||
}
|
||||
else if (rootContent is ContentControl contentControl)
|
||||
{
|
||||
// 如果根部是 ContentControl,我们需要把原本的内容包在一个新的 Grid 里
|
||||
var originalContent = contentControl.Content as UIElement;
|
||||
contentControl.Content = null;
|
||||
|
||||
var wrapperGrid = new Grid();
|
||||
wrapperGrid.Children.Add(originalContent); // 原有内容
|
||||
wrapperGrid.Children.Add(_view); // 我们的遮罩层
|
||||
|
||||
contentControl.Content = wrapperGrid;
|
||||
}
|
||||
|
||||
// 确保遮罩层铺满并置于顶层
|
||||
Grid.SetColumnSpan(_view, 99);
|
||||
Grid.SetRowSpan(_view, 99);
|
||||
Panel.SetZIndex(_view, 9999);
|
||||
}
|
||||
// 基础调用:Loading.Show("计算中...");
|
||||
public static void Show(string msg, bool isIndeterminate, bool canCancel = true) => LoadingService.Instance.Show(msg, canCancel, isIndeterminate);
|
||||
|
||||
public static void Hide() => LoadingService.Instance.Hide();
|
||||
|
||||
public static void Report(double val) => LoadingService.Instance.Report(val);
|
||||
|
||||
// 获取当前令牌:Loading.Token
|
||||
public static CancellationToken Token => LoadingService.Instance.Token;
|
||||
|
||||
// 高级用法:使用 using 块自动开启和关闭
|
||||
public static IDisposable Manager(string msg, bool canCancel = true)
|
||||
{
|
||||
Show(msg, canCancel);
|
||||
return new DisposableAction(() => Hide());
|
||||
}
|
||||
|
||||
public static async Task<bool> RunAsync(
|
||||
Func<CancellationToken, IProgress<double>, Task> work,
|
||||
string message,
|
||||
bool canCancel = true, bool isIndeterminate = false,
|
||||
Action<Exception> onError = null)
|
||||
{
|
||||
using (Manager(message, canCancel))
|
||||
{
|
||||
try
|
||||
{
|
||||
LoadingService.Instance.Show(message, isIndeterminate, canCancel);
|
||||
var progress = new Progress<double>(val =>
|
||||
Application.Current.Dispatcher.Invoke(() => LoadingService.Instance.ProgressValue = val));
|
||||
|
||||
await Task.Run(() => work(LoadingService.Instance.Token, progress), LoadingService.Instance.Token);
|
||||
|
||||
return true; // 执行成功
|
||||
}
|
||||
catch (OperationCanceledException)
|
||||
{
|
||||
// 用户点击了取消,通常不需要弹窗,直接返回 false
|
||||
return false;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
// 捕获其他所有异常(硬件错误、逻辑错误等)
|
||||
if (onError != null)
|
||||
onError(ex);
|
||||
else
|
||||
MessageBox.Show($"操作失败: {ex.Message}", "系统错误", MessageBoxButton.OK, MessageBoxImage.Error);
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,55 @@
|
||||
using System.Windows;
|
||||
|
||||
namespace MainShell.Common
|
||||
{
|
||||
/// <summary>
|
||||
/// <20><><EFBFBD>ڶ<EFBFBD><DAB6><EFBFBD><EFBFBD><EFBFBD>ö<EFBFBD><C3B6><EFBFBD><EFBFBD>Ϣ<EFBFBD><CFA2><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ϣ<EFBFBD><CFA2><EFBFBD><EFBFBD><EFBFBD><EFBFBD>װ<EFBFBD><D7B0>
|
||||
/// </summary>
|
||||
public static class LocalizedMessageBox
|
||||
{
|
||||
public static MessageBoxResult Show(MessageKey messageKey)
|
||||
{
|
||||
return Show(null, messageKey, MessageKey.TitleInfo, MessageBoxButton.OK, MessageBoxImage.None, MessageBoxResult.None);
|
||||
}
|
||||
|
||||
public static MessageBoxResult Show(MessageKey messageKey, MessageKey captionKey)
|
||||
{
|
||||
return Show(null, messageKey, captionKey, MessageBoxButton.OK, MessageBoxImage.None, MessageBoxResult.None);
|
||||
}
|
||||
|
||||
public static MessageBoxResult Show(MessageKey messageKey, MessageKey captionKey, MessageBoxButton button, MessageBoxImage icon)
|
||||
{
|
||||
return Show(null, messageKey, captionKey, button, icon, MessageBoxResult.None);
|
||||
}
|
||||
|
||||
public static MessageBoxResult Show(Window owner, MessageKey messageKey, MessageKey captionKey, MessageBoxButton button, MessageBoxImage icon, MessageBoxResult defaultResult = MessageBoxResult.None)
|
||||
{
|
||||
return MwMessageBox.InvokeOnUiThread(() => ShowCore(owner, messageKey, captionKey, button, icon, defaultResult));
|
||||
}
|
||||
|
||||
public static MessageBoxResult ShowFormat(MessageKey messageKey, MessageKey captionKey, MessageBoxButton button, MessageBoxImage icon, params object[] args)
|
||||
{
|
||||
return MwMessageBox.InvokeOnUiThread(() => ShowFormatCore(messageKey, captionKey, button, icon, args));
|
||||
}
|
||||
|
||||
private static MessageBoxResult ShowCore(Window owner, MessageKey messageKey, MessageKey captionKey, MessageBoxButton button, MessageBoxImage icon, MessageBoxResult defaultResult)
|
||||
{
|
||||
string message = LanguageResourceHelper.GetString(messageKey);
|
||||
string caption = captionKey == MessageKey.None
|
||||
? string.Empty
|
||||
: LanguageResourceHelper.GetString(captionKey);
|
||||
|
||||
return MwMessageBox.Show(owner, message, caption, button, icon, defaultResult);
|
||||
}
|
||||
|
||||
private static MessageBoxResult ShowFormatCore(MessageKey messageKey, MessageKey captionKey, MessageBoxButton button, MessageBoxImage icon, object[] args)
|
||||
{
|
||||
string message = LanguageResourceHelper.Format(messageKey, args);
|
||||
string caption = captionKey == MessageKey.None
|
||||
? string.Empty
|
||||
: LanguageResourceHelper.GetString(captionKey);
|
||||
|
||||
return MwMessageBox.Show(message, caption, button, icon);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,37 @@
|
||||
using System;
|
||||
|
||||
namespace MainShell.Common
|
||||
{
|
||||
/// <summary>
|
||||
/// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ڲ<EFBFBD><DAB2><EFBFBD> MessageKey <20><>ʽ<EFBFBD><CABD><EFBFBD><EFBFBD><EFBFBD>ܿ<EFBFBD>ʧ<EFBFBD>ܣ<EFBFBD><DCA3><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʽ<EFBFBD><CABD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||
/// </summary>
|
||||
public class LocalizedProcessException : Exception
|
||||
{
|
||||
public MessageKey FailureMessageKey { get; }
|
||||
|
||||
public string[] FailureMessageArguments { get; }
|
||||
|
||||
public LocalizedProcessException(MessageKey failureMessageKey, params string[] failureMessageArguments)
|
||||
: base(LanguageResourceHelper.Format(failureMessageKey, ConvertArguments(failureMessageArguments)))
|
||||
{
|
||||
FailureMessageKey = failureMessageKey;
|
||||
FailureMessageArguments = failureMessageArguments ?? Array.Empty<string>();
|
||||
}
|
||||
|
||||
public static object[] ConvertArguments(string[] failureMessageArguments)
|
||||
{
|
||||
if (failureMessageArguments == null || failureMessageArguments.Length == 0)
|
||||
{
|
||||
return Array.Empty<object>();
|
||||
}
|
||||
|
||||
object[] convertedArguments = new object[failureMessageArguments.Length];
|
||||
for (int i = 0; i < failureMessageArguments.Length; i++)
|
||||
{
|
||||
convertedArguments[i] = failureMessageArguments[i];
|
||||
}
|
||||
|
||||
return convertedArguments;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,121 @@
|
||||
using System;
|
||||
|
||||
namespace MainShell.Common
|
||||
{
|
||||
/// <summary>
|
||||
/// Message keys used by the localization system.
|
||||
/// </summary>
|
||||
public enum MessageKey
|
||||
{
|
||||
None = 0,
|
||||
|
||||
TitleInfo,
|
||||
TitleWarning,
|
||||
TitleError,
|
||||
TitleConfirm,
|
||||
|
||||
VisionCameraNotFound,
|
||||
VisionCameraNotOpen,
|
||||
VisionCameraNotGrabbing,
|
||||
VisionCaptureTimeout,
|
||||
VisionNoFrameReturned,
|
||||
VisionSoftTriggerFailed,
|
||||
VisionDriverError,
|
||||
VisionImageIsNull,
|
||||
VisionRequestInvalid,
|
||||
VisionTimeoutInvalid,
|
||||
VisionOperationCancelled,
|
||||
VisionTemplatePathEmpty,
|
||||
VisionTemplateRoiInvalid,
|
||||
VisionTemplateMinScoreInvalid,
|
||||
VisionTemplateAlgorithmNotImplemented,
|
||||
VisionTemplateMatchFailed,
|
||||
VisionCommonAlgorithmNotSupported,
|
||||
VisionCommonAlgorithmExecutionFailed,
|
||||
VisionChipMapSortInputInvalid,
|
||||
|
||||
CommonUnknownError,
|
||||
CommonOperationSucceeded,
|
||||
CommonOperationFailed,
|
||||
CommonSaveSucceeded,
|
||||
CommonSaveFailed,
|
||||
AxisSoftLimitSaveConfirm,
|
||||
AxisSoftLimitSaveFailedWithReason,
|
||||
AxisSoftLimitLoadFailedWithReason,
|
||||
AxisSoftLimitRangeInvalid,
|
||||
AxisSoftLimitApplySucceeded,
|
||||
AxisSoftLimitApplyFailedWithReason,
|
||||
AxisSoftLimitApplyAllSucceeded,
|
||||
AxisSoftLimitApplyAllFailedWithReason,
|
||||
AxisSoftLimitNoAxisData,
|
||||
AxisSoftLimitSelectedAxisRequired,
|
||||
CommonDeleteConfirm,
|
||||
CommonExitConfirm,
|
||||
|
||||
DeviceNotInitialized,
|
||||
DeviceBusy,
|
||||
DeviceDisconnected,
|
||||
DeviceHomeRequired,
|
||||
|
||||
ParamInvalid,
|
||||
ParamEmpty,
|
||||
ParamOutOfRange,
|
||||
|
||||
StartProcessConfirm,
|
||||
StartProcessFailed,
|
||||
StopProcessConfirm,
|
||||
StopProcessFailed,
|
||||
|
||||
ProcessFailed,
|
||||
ProcessFailedWithReason,
|
||||
ProcessStepFailedWithReason,
|
||||
ProcessSubstratePositionFailedWithReason,
|
||||
ProcessSubstratePositionRecipeNotLoaded,
|
||||
ProcessSubstratePositionMarkParameterMissing,
|
||||
ProcessSubstratePositionNoEnabledMarks,
|
||||
ProcessSubstratePositionAlignmentFailedWithReason,
|
||||
ProcessDiePositionFailedWithReason,
|
||||
ProcessDiePositionRecipeNotLoaded,
|
||||
ProcessDiePositionCoordinateGenerationMissing,
|
||||
ProcessDiePositionWaferInfoMissing,
|
||||
ProcessSubstrateHeightMeasureFailedWithReason,
|
||||
ProcessSubstrateHeightMeasureRecipeNotLoaded,
|
||||
ProcessSubstrateHeightMeasureSettingMissing,
|
||||
ProcessSubstrateHeightMeasureNoPoints,
|
||||
ProcessSubstrateHeightMeasurePointPositionInvalid,
|
||||
NeedleCalibrationLoadFailed,
|
||||
NeedleCalibrationTouchCountMustGreaterThanZero,
|
||||
NeedleCalibrationCompleted,
|
||||
NeedleCalibrationStopped,
|
||||
NeedleCalibrationCanceled,
|
||||
OriginCalibOpenVisionTemplateFailed,
|
||||
OriginCalibAxisNotFound,
|
||||
OriginCalibReadPositionFailed,
|
||||
OriginCalibMoveFailed,
|
||||
OriginCalibDeleteAxisFailed,
|
||||
OriginCalibDeleteAxisDuringCalibration,
|
||||
OriginCalibCalibrationCanceled,
|
||||
OriginCalibCalibrationFailed,
|
||||
OriginCalibConfigSaved,
|
||||
OriginCalibConfigSaveFailed,
|
||||
OriginCalibNoCalibratedModules,
|
||||
OriginCalibControllerWriteCompleted,
|
||||
OriginCalibControllerWriteNotReady,
|
||||
OriginCalibControllerWritePartialSuccess,
|
||||
OriginCalibControllerWriteNotImplemented,
|
||||
|
||||
PidNoProfileSelected,
|
||||
PidNoFilteringParameterSelected,
|
||||
PidReadSucceeded,
|
||||
PidReadFailed,
|
||||
PidWriteSucceeded,
|
||||
PidWriteFailed,
|
||||
|
||||
DieRecheckSelectedPointRequired,
|
||||
DieRecheckMoveDeviceUnavailable,
|
||||
DieRecheckStatusOk,
|
||||
DieRecheckStatusMissingBond,
|
||||
DieRecheckStatusXExceeded,
|
||||
DieRecheckStatusYExceeded
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,639 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Windows;
|
||||
using System.Windows.Media;
|
||||
using MainShell.Common.View;
|
||||
using MainShell.Common.ViewModel;
|
||||
|
||||
namespace MainShell.Common
|
||||
{
|
||||
public static class MwMessageBoxGlyphs
|
||||
{
|
||||
public const string None = "\uE686";
|
||||
public const string Information = "\uE625";
|
||||
public const string Warning = "\uE7BD";
|
||||
public const string Error = "\uE76C";
|
||||
public const string Question = "\uE686";
|
||||
}
|
||||
|
||||
public sealed class MwMessageBoxButtonText
|
||||
{
|
||||
public string Ok { get; set; } = "ȷ<><C8B7>";
|
||||
public string Cancel { get; set; } = "ȡ<><C8A1>";
|
||||
public string Yes { get; set; } = "<22><>";
|
||||
public string No { get; set; } = "<22><>";
|
||||
public string Retry { get; set; } = "<22><><EFBFBD><EFBFBD>";
|
||||
public string Abort { get; set; } = "<22><>ֹ";
|
||||
public string Ignore { get; set; } = "<22><><EFBFBD><EFBFBD>";
|
||||
|
||||
public static MwMessageBoxButtonText CreateDefault()
|
||||
{
|
||||
return new MwMessageBoxButtonText();
|
||||
}
|
||||
}
|
||||
|
||||
public sealed class MwMessageBoxButtonDefinition
|
||||
{
|
||||
public string Text { get; set; }
|
||||
|
||||
public MessageBoxResult Result { get; set; }
|
||||
|
||||
public bool IsDefault { get; set; }
|
||||
|
||||
public bool IsCancel { get; set; }
|
||||
|
||||
public bool IsPrimary { get; set; }
|
||||
|
||||
public Style ButtonStyle { get; set; }
|
||||
}
|
||||
|
||||
public sealed class MwMessageBoxIconTheme
|
||||
{
|
||||
public string NoneGlyph { get; set; } = MwMessageBoxGlyphs.None;
|
||||
|
||||
public string InformationGlyph { get; set; } = MwMessageBoxGlyphs.Information;
|
||||
|
||||
public string WarningGlyph { get; set; } = MwMessageBoxGlyphs.Warning;
|
||||
|
||||
public string ErrorGlyph { get; set; } = MwMessageBoxGlyphs.Error;
|
||||
|
||||
public string QuestionGlyph { get; set; } = MwMessageBoxGlyphs.Question;
|
||||
|
||||
public static MwMessageBoxIconTheme CreateDefault()
|
||||
{
|
||||
return new MwMessageBoxIconTheme();
|
||||
}
|
||||
}
|
||||
|
||||
public sealed class MwMessageBoxColorPalette
|
||||
{
|
||||
public MwMessageBoxColorPalette()
|
||||
{
|
||||
}
|
||||
|
||||
public MwMessageBoxColorPalette(string accentColor, string iconBackgroundColor, string iconForegroundColor)
|
||||
{
|
||||
AccentColor = accentColor;
|
||||
IconBackgroundColor = iconBackgroundColor;
|
||||
IconForegroundColor = iconForegroundColor;
|
||||
}
|
||||
|
||||
public string AccentColor { get; set; }
|
||||
|
||||
public string IconBackgroundColor { get; set; }
|
||||
|
||||
public string IconForegroundColor { get; set; }
|
||||
}
|
||||
|
||||
public sealed class MwMessageBoxButtonColorTheme
|
||||
{
|
||||
public MwMessageBoxButtonColorTheme()
|
||||
{
|
||||
}
|
||||
|
||||
public MwMessageBoxButtonColorTheme(string backgroundColor, string hoverBackgroundColor, string pressedBackgroundColor, string borderColor, string foregroundColor)
|
||||
{
|
||||
BackgroundColor = backgroundColor;
|
||||
HoverBackgroundColor = hoverBackgroundColor;
|
||||
PressedBackgroundColor = pressedBackgroundColor;
|
||||
BorderColor = borderColor;
|
||||
ForegroundColor = foregroundColor;
|
||||
}
|
||||
|
||||
public string BackgroundColor { get; set; }
|
||||
|
||||
public string HoverBackgroundColor { get; set; }
|
||||
|
||||
public string PressedBackgroundColor { get; set; }
|
||||
|
||||
public string BorderColor { get; set; }
|
||||
|
||||
public string ForegroundColor { get; set; }
|
||||
}
|
||||
|
||||
public sealed class MwMessageBoxVisualTheme
|
||||
{
|
||||
public MwMessageBoxColorPalette NonePalette { get; set; } = new MwMessageBoxColorPalette("#9CA3AF", "#F3F4F6", "#6B7280");
|
||||
|
||||
public MwMessageBoxColorPalette InformationPalette { get; set; } = new MwMessageBoxColorPalette("#38BDF8", "#E0F2FE", "#0284C7");
|
||||
|
||||
public MwMessageBoxColorPalette WarningPalette { get; set; } = new MwMessageBoxColorPalette("#F59E0B", "#FEF3C7", "#D97706");
|
||||
|
||||
public MwMessageBoxColorPalette ErrorPalette { get; set; } = new MwMessageBoxColorPalette("#EF4444", "#FEE2E2", "#DC2626");
|
||||
|
||||
public MwMessageBoxColorPalette QuestionPalette { get; set; } = new MwMessageBoxColorPalette("#3B82F6", "#DBEAFE", "#2563EB");
|
||||
|
||||
public MwMessageBoxButtonColorTheme PrimaryButtonTheme { get; set; } = new MwMessageBoxButtonColorTheme("#0E6AE8", "#0B5AD0", "#094BAC", "#0E6AE8", "#FFFFFF");
|
||||
|
||||
public MwMessageBoxButtonColorTheme SecondaryButtonTheme { get; set; } = new MwMessageBoxButtonColorTheme("#F3F4F6", "#E5E7EB", "#D1D5DB", "#D1D5DB", "#374151");
|
||||
|
||||
public static MwMessageBoxVisualTheme CreateDefault()
|
||||
{
|
||||
return new MwMessageBoxVisualTheme();
|
||||
}
|
||||
}
|
||||
|
||||
public sealed class MwMessageBoxState
|
||||
{
|
||||
public string Caption { get; set; }
|
||||
|
||||
public string Message { get; set; }
|
||||
|
||||
public string IconGlyph { get; set; }
|
||||
|
||||
public string IconPathData { get; set; }
|
||||
|
||||
public string TimeText { get; set; }
|
||||
|
||||
public Brush AccentBrush { get; set; }
|
||||
|
||||
public Brush IconBackgroundBrush { get; set; }
|
||||
|
||||
public Brush IconForegroundBrush { get; set; }
|
||||
|
||||
public IReadOnlyList<MwMessageBoxButtonDefinition> Buttons { get; set; }
|
||||
|
||||
public MessageBoxResult DefaultResult { get; set; }
|
||||
|
||||
public TextAlignment MessageTextAlignment { get; set; } = TextAlignment.Left;
|
||||
|
||||
public FlowDirection WindowFlowDirection { get; set; } = FlowDirection.LeftToRight;
|
||||
|
||||
public FlowDirection MessageFlowDirection { get; set; } = FlowDirection.LeftToRight;
|
||||
}
|
||||
|
||||
public static class MwMessageBox
|
||||
{
|
||||
public static MwMessageBoxButtonText DefaultButtonText { get; set; } = MwMessageBoxButtonText.CreateDefault();
|
||||
|
||||
public static MwMessageBoxIconTheme IconTheme { get; set; } = MwMessageBoxIconTheme.CreateDefault();
|
||||
|
||||
public static MwMessageBoxVisualTheme VisualTheme { get; set; } = MwMessageBoxVisualTheme.CreateDefault();
|
||||
|
||||
public static MessageBoxResult Show(string messageBoxText)
|
||||
{
|
||||
return Show(null, messageBoxText, string.Empty, MessageBoxButton.OK, MessageBoxImage.None, MessageBoxResult.None, 0, null);
|
||||
}
|
||||
|
||||
public static MessageBoxResult Show(string messageBoxText, string caption)
|
||||
{
|
||||
return Show(null, messageBoxText, caption, MessageBoxButton.OK, MessageBoxImage.None, MessageBoxResult.None, 0, null);
|
||||
}
|
||||
|
||||
public static MessageBoxResult Show(string messageBoxText, string caption, MessageBoxButton button)
|
||||
{
|
||||
return Show(null, messageBoxText, caption, button, MessageBoxImage.None, MessageBoxResult.None, 0, null);
|
||||
}
|
||||
|
||||
public static MessageBoxResult Show(string messageBoxText, string caption, MessageBoxButton button, MessageBoxImage icon)
|
||||
{
|
||||
return Show(null, messageBoxText, caption, button, icon, MessageBoxResult.None, 0, null);
|
||||
}
|
||||
|
||||
public static MessageBoxResult Show(string messageBoxText, string caption, MessageBoxButton button, MessageBoxImage icon, MessageBoxResult defaultResult)
|
||||
{
|
||||
return Show(null, messageBoxText, caption, button, icon, defaultResult, 0, null);
|
||||
}
|
||||
|
||||
public static MessageBoxResult Show(string messageBoxText, string caption, MessageBoxButton button, MessageBoxImage icon, MessageBoxResult defaultResult, MessageBoxOptions options)
|
||||
{
|
||||
return Show(null, messageBoxText, caption, button, icon, defaultResult, options, null);
|
||||
}
|
||||
|
||||
public static MessageBoxResult Show(Window owner, string messageBoxText)
|
||||
{
|
||||
return Show(owner, messageBoxText, string.Empty, MessageBoxButton.OK, MessageBoxImage.None, MessageBoxResult.None, 0, null);
|
||||
}
|
||||
|
||||
public static MessageBoxResult Show(Window owner, string messageBoxText, string caption)
|
||||
{
|
||||
return Show(owner, messageBoxText, caption, MessageBoxButton.OK, MessageBoxImage.None, MessageBoxResult.None, 0, null);
|
||||
}
|
||||
|
||||
public static MessageBoxResult Show(Window owner, string messageBoxText, string caption, MessageBoxButton button)
|
||||
{
|
||||
return Show(owner, messageBoxText, caption, button, MessageBoxImage.None, MessageBoxResult.None, 0, null);
|
||||
}
|
||||
|
||||
public static MessageBoxResult Show(Window owner, string messageBoxText, string caption, MessageBoxButton button, MessageBoxImage icon)
|
||||
{
|
||||
return Show(owner, messageBoxText, caption, button, icon, MessageBoxResult.None, 0, null);
|
||||
}
|
||||
|
||||
public static MessageBoxResult Show(Window owner, string messageBoxText, string caption, MessageBoxButton button, MessageBoxImage icon, MessageBoxResult defaultResult)
|
||||
{
|
||||
return Show(owner, messageBoxText, caption, button, icon, defaultResult, 0, null);
|
||||
}
|
||||
|
||||
public static MessageBoxResult Show(Window owner, string messageBoxText, string caption, MessageBoxButton button, MessageBoxImage icon, MessageBoxResult defaultResult, MessageBoxOptions options)
|
||||
{
|
||||
return Show(owner, messageBoxText, caption, button, icon, defaultResult, options, null);
|
||||
}
|
||||
|
||||
public static MessageBoxResult Show(string messageBoxText, string caption, MessageBoxButton button, MessageBoxImage icon, MwMessageBoxButtonText buttonText)
|
||||
{
|
||||
return Show(null, messageBoxText, caption, button, icon, MessageBoxResult.None, 0, buttonText);
|
||||
}
|
||||
|
||||
public static MessageBoxResult Show(Window owner, string messageBoxText, string caption, MessageBoxButton button, MessageBoxImage icon, MwMessageBoxButtonText buttonText)
|
||||
{
|
||||
return Show(owner, messageBoxText, caption, button, icon, MessageBoxResult.None, 0, buttonText);
|
||||
}
|
||||
|
||||
public static MessageBoxResult Show(Window owner, string messageBoxText, string caption, MessageBoxButton button, MessageBoxImage icon, MessageBoxResult defaultResult, MessageBoxOptions options, MwMessageBoxButtonText buttonText)
|
||||
{
|
||||
return InvokeOnUiThread(() => ShowCore(owner, messageBoxText, caption, button, icon, defaultResult, options, buttonText));
|
||||
}
|
||||
|
||||
public static MessageBoxResult ShowCustom(string messageBoxText, string caption, MessageBoxImage icon, params MwMessageBoxButtonDefinition[] buttons)
|
||||
{
|
||||
return ShowCustom(null, messageBoxText, caption, icon, MessageBoxResult.None, 0, buttons);
|
||||
}
|
||||
|
||||
public static MessageBoxResult ShowCustom(Window owner, string messageBoxText, string caption, MessageBoxImage icon, params MwMessageBoxButtonDefinition[] buttons)
|
||||
{
|
||||
return ShowCustom(owner, messageBoxText, caption, icon, MessageBoxResult.None, 0, buttons);
|
||||
}
|
||||
|
||||
public static MessageBoxResult ShowCustom(Window owner, string messageBoxText, string caption, MessageBoxImage icon, MessageBoxResult defaultResult, MessageBoxOptions options, params MwMessageBoxButtonDefinition[] buttons)
|
||||
{
|
||||
return InvokeOnUiThread(() => ShowCustomCore(owner, messageBoxText, caption, icon, defaultResult, options, buttons));
|
||||
}
|
||||
|
||||
internal static T InvokeOnUiThread<T>(Func<T> callback)
|
||||
{
|
||||
if (callback == null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(callback));
|
||||
}
|
||||
|
||||
Application application = Application.Current;
|
||||
if (application == null)
|
||||
{
|
||||
return callback();
|
||||
}
|
||||
|
||||
if (application.Dispatcher == null || application.Dispatcher.CheckAccess())
|
||||
{
|
||||
return callback();
|
||||
}
|
||||
|
||||
return application.Dispatcher.Invoke(callback);
|
||||
}
|
||||
|
||||
private static MessageBoxResult ShowCore(Window owner, string messageBoxText, string caption, MessageBoxButton button, MessageBoxImage icon, MessageBoxResult defaultResult, MessageBoxOptions options, MwMessageBoxButtonText buttonText)
|
||||
{
|
||||
owner = owner ?? GetActiveWindow();
|
||||
|
||||
List<MwMessageBoxButtonDefinition> definitions = CreateButtonDefinitions(button, defaultResult, buttonText ?? DefaultButtonText).ToList();
|
||||
MwMessageBoxState state = CreateState(messageBoxText, caption, icon, definitions, defaultResult, options);
|
||||
MwMessageBoxWindowViewModel viewModel = new MwMessageBoxWindowViewModel(state);
|
||||
MwMessageBoxWindow dialog = new MwMessageBoxWindow(viewModel);
|
||||
if (owner != null)
|
||||
{
|
||||
dialog.Owner = owner;
|
||||
dialog.WindowStartupLocation = WindowStartupLocation.CenterOwner;
|
||||
}
|
||||
|
||||
dialog.ShowDialog();
|
||||
return viewModel.Result;
|
||||
}
|
||||
|
||||
private static MessageBoxResult ShowCustomCore(Window owner, string messageBoxText, string caption, MessageBoxImage icon, MessageBoxResult defaultResult, MessageBoxOptions options, params MwMessageBoxButtonDefinition[] buttons)
|
||||
{
|
||||
owner = owner ?? GetActiveWindow();
|
||||
List<MwMessageBoxButtonDefinition> definitions = NormalizeButtonDefinitions(buttons, defaultResult).ToList();
|
||||
MwMessageBoxState state = CreateState(messageBoxText, caption, icon, definitions, defaultResult, options);
|
||||
MwMessageBoxWindowViewModel viewModel = new MwMessageBoxWindowViewModel(state);
|
||||
MwMessageBoxWindow dialog = new MwMessageBoxWindow(viewModel);
|
||||
if (owner != null)
|
||||
{
|
||||
dialog.Owner = owner;
|
||||
dialog.WindowStartupLocation = WindowStartupLocation.CenterOwner;
|
||||
}
|
||||
|
||||
dialog.ShowDialog();
|
||||
return viewModel.Result;
|
||||
}
|
||||
|
||||
private static IEnumerable<MwMessageBoxButtonDefinition> CreateButtonDefinitions(MessageBoxButton button, MessageBoxResult defaultResult, MwMessageBoxButtonText buttonText)
|
||||
{
|
||||
var labels = buttonText ?? MwMessageBoxButtonText.CreateDefault();
|
||||
var definitions = new List<MwMessageBoxButtonDefinition>();
|
||||
|
||||
switch (button)
|
||||
{
|
||||
case MessageBoxButton.OK:
|
||||
definitions.Add(CreateDefinition(labels.Ok, MessageBoxResult.OK, true));
|
||||
break;
|
||||
case MessageBoxButton.OKCancel:
|
||||
definitions.Add(CreateDefinition(labels.Ok, MessageBoxResult.OK, true));
|
||||
definitions.Add(CreateDefinition(labels.Cancel, MessageBoxResult.Cancel, false, true));
|
||||
break;
|
||||
case MessageBoxButton.YesNo:
|
||||
definitions.Add(CreateDefinition(labels.Yes, MessageBoxResult.Yes, true));
|
||||
definitions.Add(CreateDefinition(labels.No, MessageBoxResult.No));
|
||||
break;
|
||||
case MessageBoxButton.YesNoCancel:
|
||||
definitions.Add(CreateDefinition(labels.Yes, MessageBoxResult.Yes, true));
|
||||
definitions.Add(CreateDefinition(labels.No, MessageBoxResult.No));
|
||||
definitions.Add(CreateDefinition(labels.Cancel, MessageBoxResult.Cancel, false, true));
|
||||
break;
|
||||
default:
|
||||
definitions.Add(CreateDefinition(labels.Ok, MessageBoxResult.OK, true));
|
||||
break;
|
||||
}
|
||||
|
||||
return NormalizeButtonDefinitions(definitions, defaultResult);
|
||||
}
|
||||
|
||||
private static IEnumerable<MwMessageBoxButtonDefinition> NormalizeButtonDefinitions(IEnumerable<MwMessageBoxButtonDefinition> buttons, MessageBoxResult defaultResult)
|
||||
{
|
||||
var definitions = (buttons ?? Enumerable.Empty<MwMessageBoxButtonDefinition>())
|
||||
.Where(item => item != null)
|
||||
.Select(item => new MwMessageBoxButtonDefinition
|
||||
{
|
||||
Text = string.IsNullOrWhiteSpace(item.Text) ? item.Result.ToString() : item.Text,
|
||||
Result = item.Result,
|
||||
IsCancel = item.IsCancel,
|
||||
IsDefault = item.IsDefault,
|
||||
IsPrimary = item.IsPrimary,
|
||||
ButtonStyle = item.ButtonStyle
|
||||
})
|
||||
.ToList();
|
||||
|
||||
if (definitions.Count == 0)
|
||||
{
|
||||
definitions.Add(CreateDefinition(DefaultButtonText.Ok, MessageBoxResult.OK, true));
|
||||
}
|
||||
|
||||
var targetDefault = defaultResult == MessageBoxResult.None
|
||||
? definitions.FirstOrDefault(item => item.IsDefault)?.Result ?? definitions[0].Result
|
||||
: defaultResult;
|
||||
|
||||
foreach (var item in definitions)
|
||||
{
|
||||
item.IsDefault = item.Result == targetDefault;
|
||||
}
|
||||
|
||||
if (!definitions.Any(item => item.IsCancel))
|
||||
{
|
||||
var cancelButton = definitions.FirstOrDefault(item => item.Result == MessageBoxResult.Cancel);
|
||||
if (cancelButton != null)
|
||||
{
|
||||
cancelButton.IsCancel = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (!definitions.Any(item => item.IsPrimary))
|
||||
{
|
||||
var primary = definitions.FirstOrDefault(item => item.IsDefault) ?? definitions[0];
|
||||
primary.IsPrimary = true;
|
||||
}
|
||||
|
||||
foreach (var item in definitions)
|
||||
{
|
||||
item.ButtonStyle = item.ButtonStyle ?? GetButtonStyle(item.IsPrimary);
|
||||
}
|
||||
|
||||
return definitions;
|
||||
}
|
||||
|
||||
private static MwMessageBoxButtonDefinition CreateDefinition(string text, MessageBoxResult result, bool isPrimary = false, bool isCancel = false)
|
||||
{
|
||||
return new MwMessageBoxButtonDefinition
|
||||
{
|
||||
Text = text,
|
||||
Result = result,
|
||||
IsPrimary = isPrimary,
|
||||
IsDefault = isPrimary,
|
||||
IsCancel = isCancel,
|
||||
ButtonStyle = GetButtonStyle(isPrimary)
|
||||
};
|
||||
}
|
||||
|
||||
internal static Style GetButtonStyle(bool isPrimary)
|
||||
{
|
||||
if (Application.Current != null)
|
||||
{
|
||||
var key = isPrimary ? "SaveButtonStyle" : "SettingsButtonStyle";
|
||||
var resourceStyle = Application.Current.TryFindResource(key) as Style;
|
||||
if (resourceStyle != null)
|
||||
{
|
||||
return resourceStyle;
|
||||
}
|
||||
}
|
||||
|
||||
var visualTheme = VisualTheme ?? MwMessageBoxVisualTheme.CreateDefault();
|
||||
var buttonTheme = isPrimary ? visualTheme.PrimaryButtonTheme : visualTheme.SecondaryButtonTheme;
|
||||
|
||||
var style = new Style(typeof(System.Windows.Controls.Button));
|
||||
style.Setters.Add(new Setter(System.Windows.Controls.Control.BackgroundProperty, CreateBrush(buttonTheme.BackgroundColor)));
|
||||
style.Setters.Add(new Setter(System.Windows.Controls.Control.BorderBrushProperty, CreateBrush(buttonTheme.BorderColor)));
|
||||
style.Setters.Add(new Setter(System.Windows.Controls.Control.BorderThicknessProperty, new Thickness(1)));
|
||||
style.Setters.Add(new Setter(System.Windows.Controls.Control.ForegroundProperty, CreateBrush(buttonTheme.ForegroundColor)));
|
||||
style.Setters.Add(new Setter(System.Windows.Controls.Control.FontSizeProperty, 14d));
|
||||
style.Setters.Add(new Setter(System.Windows.Controls.Control.FontWeightProperty, FontWeights.SemiBold));
|
||||
style.Setters.Add(new Setter(System.Windows.Controls.Control.CursorProperty, System.Windows.Input.Cursors.Hand));
|
||||
|
||||
var hoverTrigger = new Trigger { Property = UIElement.IsMouseOverProperty, Value = true };
|
||||
hoverTrigger.Setters.Add(new Setter(System.Windows.Controls.Control.BackgroundProperty, CreateBrush(buttonTheme.HoverBackgroundColor)));
|
||||
style.Triggers.Add(hoverTrigger);
|
||||
|
||||
var pressedTrigger = new Trigger { Property = System.Windows.Controls.Primitives.ButtonBase.IsPressedProperty, Value = true };
|
||||
pressedTrigger.Setters.Add(new Setter(System.Windows.Controls.Control.BackgroundProperty, CreateBrush(buttonTheme.PressedBackgroundColor)));
|
||||
style.Triggers.Add(pressedTrigger);
|
||||
|
||||
return style;
|
||||
}
|
||||
|
||||
internal static MessageBoxResult ResolveFallbackResult(MwMessageBoxState state)
|
||||
{
|
||||
if (state == null)
|
||||
{
|
||||
return MessageBoxResult.None;
|
||||
}
|
||||
|
||||
if (state.DefaultResult != MessageBoxResult.None)
|
||||
{
|
||||
return state.DefaultResult;
|
||||
}
|
||||
|
||||
var cancelButton = state.Buttons != null ? state.Buttons.FirstOrDefault(item => item.IsCancel) : null;
|
||||
if (cancelButton != null)
|
||||
{
|
||||
return cancelButton.Result;
|
||||
}
|
||||
|
||||
var defaultButton = state.Buttons != null ? state.Buttons.FirstOrDefault(item => item.IsDefault) ?? state.Buttons.FirstOrDefault() : null;
|
||||
return defaultButton != null ? defaultButton.Result : MessageBoxResult.None;
|
||||
}
|
||||
|
||||
private static Window GetActiveWindow()
|
||||
{
|
||||
if (Application.Current == null)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
var active = Application.Current.Windows.OfType<Window>().FirstOrDefault(w => w.IsActive);
|
||||
if (active != null)
|
||||
{
|
||||
return active;
|
||||
}
|
||||
|
||||
if (Application.Current.MainWindow != null && Application.Current.MainWindow.IsVisible)
|
||||
{
|
||||
return Application.Current.MainWindow;
|
||||
}
|
||||
|
||||
return Application.Current.Windows.OfType<Window>()
|
||||
.Where(w => w.IsVisible)
|
||||
.OrderByDescending(w => w.IsLoaded)
|
||||
.FirstOrDefault();
|
||||
}
|
||||
|
||||
private static MwMessageBoxState CreateState(string message, string caption, MessageBoxImage icon, IReadOnlyList<MwMessageBoxButtonDefinition> buttons, MessageBoxResult defaultResult, MessageBoxOptions options)
|
||||
{
|
||||
var palette = CreatePaletteBrushes(GetPalette(icon));
|
||||
return new MwMessageBoxState
|
||||
{
|
||||
Caption = ResolveCaption(caption, icon),
|
||||
Message = message,
|
||||
IconGlyph = GetIconText(icon, IconTheme),
|
||||
IconPathData = GetIconPathData(icon),
|
||||
TimeText = DateTime.Now.ToString("HH:mm:ss"),
|
||||
AccentBrush = palette.AccentBrush,
|
||||
IconBackgroundBrush = palette.IconBackgroundBrush,
|
||||
IconForegroundBrush = palette.IconForegroundBrush,
|
||||
Buttons = buttons,
|
||||
DefaultResult = defaultResult,
|
||||
MessageTextAlignment = (options & MessageBoxOptions.RightAlign) == MessageBoxOptions.RightAlign ? TextAlignment.Right : TextAlignment.Left,
|
||||
WindowFlowDirection = (options & MessageBoxOptions.RtlReading) == MessageBoxOptions.RtlReading ? FlowDirection.RightToLeft : FlowDirection.LeftToRight,
|
||||
MessageFlowDirection = (options & MessageBoxOptions.RtlReading) == MessageBoxOptions.RtlReading ? FlowDirection.RightToLeft : FlowDirection.LeftToRight
|
||||
};
|
||||
}
|
||||
|
||||
private static string ResolveCaption(string caption, MessageBoxImage icon)
|
||||
{
|
||||
if (!string.IsNullOrWhiteSpace(caption))
|
||||
{
|
||||
return caption;
|
||||
}
|
||||
|
||||
switch (icon)
|
||||
{
|
||||
case MessageBoxImage.Warning:
|
||||
return "<22><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʾ";
|
||||
case MessageBoxImage.Error:
|
||||
return "<22><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʾ";
|
||||
case MessageBoxImage.Information:
|
||||
return "<22><>Ϣ<EFBFBD><CFA2>ʾ";
|
||||
case MessageBoxImage.Question:
|
||||
return "<22><><EFBFBD><EFBFBD>ȷ<EFBFBD><C8B7>";
|
||||
default:
|
||||
return "<22><>ʾ";
|
||||
}
|
||||
}
|
||||
|
||||
private static string GetIconText(MessageBoxImage icon, MwMessageBoxIconTheme iconTheme)
|
||||
{
|
||||
var theme = iconTheme ?? MwMessageBoxIconTheme.CreateDefault();
|
||||
|
||||
switch (icon)
|
||||
{
|
||||
case MessageBoxImage.None:
|
||||
return theme.NoneGlyph;
|
||||
case MessageBoxImage.Warning:
|
||||
return theme.WarningGlyph;
|
||||
case MessageBoxImage.Error:
|
||||
return theme.ErrorGlyph;
|
||||
case MessageBoxImage.Information:
|
||||
return theme.InformationGlyph;
|
||||
case MessageBoxImage.Question:
|
||||
return theme.QuestionGlyph;
|
||||
default:
|
||||
return theme.NoneGlyph;
|
||||
}
|
||||
}
|
||||
|
||||
private static string GetIconPathData(MessageBoxImage icon)
|
||||
{
|
||||
switch (icon)
|
||||
{
|
||||
case MessageBoxImage.Warning:
|
||||
return "M11,4 H13 V14 H11 Z M11,16 H13 V18 H11 Z";
|
||||
case MessageBoxImage.Error:
|
||||
return "M7.76,6.34 L12,10.59 L16.24,6.34 L17.66,7.76 L13.41,12 L17.66,16.24 L16.24,17.66 L12,13.41 L7.76,17.66 L6.34,16.24 L10.59,12 L6.34,7.76 Z";
|
||||
case MessageBoxImage.Information:
|
||||
return "M11,5 H13 V7 H11 Z M11,9 H13 V19 H11 Z";
|
||||
case MessageBoxImage.Question:
|
||||
return "M10.2,8.8 C10.27,7.69 11.17,6.82 12.3,6.82 C13.46,6.82 14.36,7.66 14.36,8.75 C14.36,9.52 13.96,10.12 13.02,10.82 C11.74,11.78 11.1,12.65 11.1,14.35 L12.9,14.35 C12.9,13.26 13.27,12.74 14.1,12.09 C15.29,11.17 16,10.14 16,8.72 C16,6.69 14.37,5 12.3,5 C10.23,5 8.56,6.63 8.4,8.8 Z M11.05,16.2 H13.15 V18.3 H11.05 Z";
|
||||
default:
|
||||
return "M8,11 H16 V13 H8 Z";
|
||||
}
|
||||
}
|
||||
|
||||
private static MwMessageBoxColorPalette GetPalette(MessageBoxImage icon)
|
||||
{
|
||||
var visualTheme = VisualTheme ?? MwMessageBoxVisualTheme.CreateDefault();
|
||||
|
||||
switch (icon)
|
||||
{
|
||||
case MessageBoxImage.Warning:
|
||||
return CreatePalette(visualTheme.WarningPalette, visualTheme.NonePalette);
|
||||
case MessageBoxImage.Error:
|
||||
return CreatePalette(visualTheme.ErrorPalette, visualTheme.NonePalette);
|
||||
case MessageBoxImage.Information:
|
||||
return CreatePalette(visualTheme.InformationPalette, visualTheme.NonePalette);
|
||||
case MessageBoxImage.Question:
|
||||
return CreatePalette(visualTheme.QuestionPalette, visualTheme.NonePalette);
|
||||
default:
|
||||
return CreatePalette(visualTheme.NonePalette, MwMessageBoxVisualTheme.CreateDefault().NonePalette);
|
||||
}
|
||||
}
|
||||
|
||||
private static MwMessageBoxPaletteBrushes CreatePaletteBrushes(MwMessageBoxColorPalette palette)
|
||||
{
|
||||
return new MwMessageBoxPaletteBrushes(palette);
|
||||
}
|
||||
|
||||
private static MwMessageBoxColorPalette CreatePalette(MwMessageBoxColorPalette palette, MwMessageBoxColorPalette fallbackPalette)
|
||||
{
|
||||
var resolvedFallback = fallbackPalette ?? MwMessageBoxVisualTheme.CreateDefault().NonePalette;
|
||||
var resolvedPalette = palette ?? resolvedFallback;
|
||||
return new MwMessageBoxColorPalette(
|
||||
resolvedPalette.AccentColor ?? resolvedFallback.AccentColor,
|
||||
resolvedPalette.IconBackgroundColor ?? resolvedFallback.IconBackgroundColor,
|
||||
resolvedPalette.IconForegroundColor ?? resolvedFallback.IconForegroundColor);
|
||||
}
|
||||
|
||||
private static SolidColorBrush CreateBrush(string color)
|
||||
{
|
||||
return (SolidColorBrush)new BrushConverter().ConvertFromString(color);
|
||||
}
|
||||
|
||||
private sealed class MwMessageBoxPaletteBrushes
|
||||
{
|
||||
public MwMessageBoxPaletteBrushes(MwMessageBoxColorPalette palette)
|
||||
{
|
||||
var resolvedPalette = palette ?? MwMessageBoxVisualTheme.CreateDefault().NonePalette;
|
||||
AccentBrush = CreateBrush(resolvedPalette.AccentColor ?? "#9CA3AF");
|
||||
IconBackgroundBrush = CreateBrush(resolvedPalette.IconBackgroundColor ?? "#F3F4F6");
|
||||
IconForegroundBrush = CreateBrush(resolvedPalette.IconForegroundColor ?? "#6B7280");
|
||||
}
|
||||
|
||||
public Brush AccentBrush { get; }
|
||||
|
||||
public Brush IconBackgroundBrush { get; }
|
||||
|
||||
public Brush IconForegroundBrush { get; }
|
||||
|
||||
private static SolidColorBrush CreateBrush(string color)
|
||||
{
|
||||
return (SolidColorBrush)new BrushConverter().ConvertFromString(color);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,296 @@
|
||||
<Window x:Class="MainShell.Common.View.MwMessageBoxWindow"
|
||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
xmlns:i="http://schemas.microsoft.com/xaml/behaviors"
|
||||
xmlns:common="clr-namespace:MainShell.Common"
|
||||
xmlns:behaviors="clr-namespace:MainShell.Common.Behaviors"
|
||||
mc:Ignorable="d"
|
||||
MinWidth="360"
|
||||
MinHeight="220"
|
||||
MaxWidth="720"
|
||||
SizeToContent="WidthAndHeight"
|
||||
ResizeMode="NoResize"
|
||||
WindowStartupLocation="CenterScreen"
|
||||
AllowsTransparency="True"
|
||||
WindowStyle="None"
|
||||
Background="Transparent"
|
||||
ShowInTaskbar="False"
|
||||
Title="{Binding State.Caption}"
|
||||
FlowDirection="{Binding State.WindowFlowDirection}"
|
||||
UseLayoutRounding="True"
|
||||
SnapsToDevicePixels="True"
|
||||
common:WindowService.DialogResult="{Binding DialogResult}">
|
||||
<Window.Resources>
|
||||
<Style x:Key="MwMessageBoxButtonStyle" TargetType="Button">
|
||||
<Setter Property="Foreground" Value="#374151"/>
|
||||
<Setter Property="Background" Value="#FFFFFF"/>
|
||||
<Setter Property="BorderBrush" Value="#C9D5E5"/>
|
||||
<Setter Property="BorderThickness" Value="1"/>
|
||||
<Setter Property="FontSize" Value="15"/>
|
||||
<Setter Property="FontWeight" Value="SemiBold"/>
|
||||
<Setter Property="Cursor" Value="Hand"/>
|
||||
<Setter Property="FocusVisualStyle" Value="{x:Null}"/>
|
||||
<Setter Property="Template">
|
||||
<Setter.Value>
|
||||
<ControlTemplate TargetType="Button">
|
||||
<Border Background="{TemplateBinding Background}"
|
||||
BorderBrush="{TemplateBinding BorderBrush}"
|
||||
BorderThickness="{TemplateBinding BorderThickness}"
|
||||
CornerRadius="3">
|
||||
<ContentPresenter HorizontalAlignment="Center"
|
||||
VerticalAlignment="Center"/>
|
||||
</Border>
|
||||
<ControlTemplate.Triggers>
|
||||
<DataTrigger Binding="{Binding DataContext.IsPrimary, RelativeSource={RelativeSource TemplatedParent}}" Value="True">
|
||||
<Setter Property="Background" Value="#2E5FA7"/>
|
||||
<Setter Property="BorderBrush" Value="#2E5FA7"/>
|
||||
<Setter Property="Foreground" Value="#FFFFFF"/>
|
||||
</DataTrigger>
|
||||
<MultiDataTrigger>
|
||||
<MultiDataTrigger.Conditions>
|
||||
<Condition Binding="{Binding DataContext.IsPrimary, RelativeSource={RelativeSource TemplatedParent}}" Value="False"/>
|
||||
<Condition Binding="{Binding IsMouseOver, RelativeSource={RelativeSource TemplatedParent}}" Value="True"/>
|
||||
</MultiDataTrigger.Conditions>
|
||||
<Setter Property="Background" Value="#F5F8FC"/>
|
||||
<Setter Property="BorderBrush" Value="#AFC3DD"/>
|
||||
</MultiDataTrigger>
|
||||
<MultiDataTrigger>
|
||||
<MultiDataTrigger.Conditions>
|
||||
<Condition Binding="{Binding DataContext.IsPrimary, RelativeSource={RelativeSource TemplatedParent}}" Value="False"/>
|
||||
<Condition Binding="{Binding IsPressed, RelativeSource={RelativeSource TemplatedParent}}" Value="True"/>
|
||||
</MultiDataTrigger.Conditions>
|
||||
<Setter Property="Background" Value="#E8EEF6"/>
|
||||
<Setter Property="BorderBrush" Value="#9FB7D6"/>
|
||||
</MultiDataTrigger>
|
||||
<MultiDataTrigger>
|
||||
<MultiDataTrigger.Conditions>
|
||||
<Condition Binding="{Binding DataContext.IsPrimary, RelativeSource={RelativeSource TemplatedParent}}" Value="True"/>
|
||||
<Condition Binding="{Binding IsMouseOver, RelativeSource={RelativeSource TemplatedParent}}" Value="True"/>
|
||||
</MultiDataTrigger.Conditions>
|
||||
<Setter Property="Background" Value="#254F8D"/>
|
||||
<Setter Property="BorderBrush" Value="#254F8D"/>
|
||||
</MultiDataTrigger>
|
||||
<MultiDataTrigger>
|
||||
<MultiDataTrigger.Conditions>
|
||||
<Condition Binding="{Binding DataContext.IsPrimary, RelativeSource={RelativeSource TemplatedParent}}" Value="True"/>
|
||||
<Condition Binding="{Binding IsPressed, RelativeSource={RelativeSource TemplatedParent}}" Value="True"/>
|
||||
</MultiDataTrigger.Conditions>
|
||||
<Setter Property="Background" Value="#1E4174"/>
|
||||
<Setter Property="BorderBrush" Value="#1E4174"/>
|
||||
</MultiDataTrigger>
|
||||
<Trigger Property="IsEnabled" Value="False">
|
||||
<Setter Property="Foreground" Value="#9CA3AF"/>
|
||||
<Setter Property="Background" Value="#F3F4F6"/>
|
||||
<Setter Property="BorderBrush" Value="#E5E7EB"/>
|
||||
</Trigger>
|
||||
</ControlTemplate.Triggers>
|
||||
</ControlTemplate>
|
||||
</Setter.Value>
|
||||
</Setter>
|
||||
</Style>
|
||||
|
||||
<Style x:Key="MwMessageBoxCaptionStyle" TargetType="TextBlock">
|
||||
<Setter Property="Text" Value="{Binding State.Caption}"/>
|
||||
<Setter Property="Visibility" Value="Visible"/>
|
||||
<Style.Triggers>
|
||||
<Trigger Property="Text" Value="">
|
||||
<Setter Property="Visibility" Value="Collapsed"/>
|
||||
</Trigger>
|
||||
<Trigger Property="Text" Value="{x:Null}">
|
||||
<Setter Property="Visibility" Value="Collapsed"/>
|
||||
</Trigger>
|
||||
</Style.Triggers>
|
||||
</Style>
|
||||
|
||||
<Style x:Key="MwMessageBoxCloseButtonStyle" TargetType="Button">
|
||||
<Setter Property="Width" Value="44"/>
|
||||
<Setter Property="Height" Value="32"/>
|
||||
<Setter Property="Foreground" Value="#FFFFFF"/>
|
||||
<Setter Property="Background" Value="#2E5FA7"/>
|
||||
<Setter Property="BorderBrush" Value="#2E5FA7"/>
|
||||
<Setter Property="BorderThickness" Value="0"/>
|
||||
<Setter Property="FontSize" Value="14"/>
|
||||
<Setter Property="Cursor" Value="Hand"/>
|
||||
<Setter Property="FocusVisualStyle" Value="{x:Null}"/>
|
||||
<Setter Property="Template">
|
||||
<Setter.Value>
|
||||
<ControlTemplate TargetType="Button">
|
||||
<Border Background="{TemplateBinding Background}">
|
||||
<ContentPresenter HorizontalAlignment="Center"
|
||||
VerticalAlignment="Center"/>
|
||||
</Border>
|
||||
<ControlTemplate.Triggers>
|
||||
<Trigger Property="IsMouseOver" Value="True">
|
||||
<Setter Property="Background" Value="#C94A4A"/>
|
||||
</Trigger>
|
||||
<Trigger Property="IsPressed" Value="True">
|
||||
<Setter Property="Background" Value="#A53B3B"/>
|
||||
</Trigger>
|
||||
</ControlTemplate.Triggers>
|
||||
</ControlTemplate>
|
||||
</Setter.Value>
|
||||
</Setter>
|
||||
</Style>
|
||||
</Window.Resources>
|
||||
<i:Interaction.Triggers>
|
||||
<i:EventTrigger EventName="Closing">
|
||||
<i:InvokeCommandAction Command="{Binding WindowClosingCommand}"/>
|
||||
</i:EventTrigger>
|
||||
</i:Interaction.Triggers>
|
||||
<Border Background="#FFFFFF"
|
||||
CornerRadius="2"
|
||||
BorderBrush="#C6D1DF"
|
||||
BorderThickness="1">
|
||||
<Border.Effect>
|
||||
<DropShadowEffect Color="#1F3A5A"
|
||||
BlurRadius="18"
|
||||
ShadowDepth="2"
|
||||
Opacity="0.18"/>
|
||||
</Border.Effect>
|
||||
<Grid>
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition Height="32"/>
|
||||
<RowDefinition Height="Auto"/>
|
||||
<RowDefinition Height="Auto"/>
|
||||
</Grid.RowDefinitions>
|
||||
|
||||
<Grid Grid.Row="0" Background="#2E5FA7">
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="*"/>
|
||||
<ColumnDefinition Width="Auto"/>
|
||||
</Grid.ColumnDefinitions>
|
||||
|
||||
<Grid Grid.Column="0"
|
||||
behaviors:WindowDragMoveBehavior.IsEnabled="True">
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="Auto"/>
|
||||
<ColumnDefinition Width="*"/>
|
||||
</Grid.ColumnDefinitions>
|
||||
|
||||
<Border Width="16"
|
||||
Height="16"
|
||||
Margin="10,0,8,0"
|
||||
VerticalAlignment="Center"
|
||||
BorderBrush="#D8E6F7"
|
||||
BorderThickness="1"
|
||||
CornerRadius="8">
|
||||
<TextBlock Text="i"
|
||||
Foreground="#FFFFFF"
|
||||
FontSize="11"
|
||||
FontWeight="Bold"
|
||||
HorizontalAlignment="Center"
|
||||
VerticalAlignment="Center"/>
|
||||
</Border>
|
||||
|
||||
<TextBlock Grid.Column="1"
|
||||
VerticalAlignment="Center"
|
||||
Foreground="#FFFFFF"
|
||||
FontSize="13"
|
||||
FontWeight="Normal"
|
||||
TextTrimming="CharacterEllipsis">
|
||||
<TextBlock.Style>
|
||||
<Style TargetType="TextBlock">
|
||||
<Setter Property="Text" Value="{Binding State.Caption}"/>
|
||||
<Style.Triggers>
|
||||
<DataTrigger Binding="{Binding State.Caption}" Value="{x:Null}">
|
||||
<Setter Property="Text" Value="{DynamicResource Msg_Title_Info}"/>
|
||||
</DataTrigger>
|
||||
<DataTrigger Binding="{Binding State.Caption}" Value="">
|
||||
<Setter Property="Text" Value="{DynamicResource Msg_Title_Info}"/>
|
||||
</DataTrigger>
|
||||
</Style.Triggers>
|
||||
</Style>
|
||||
</TextBlock.Style>
|
||||
</TextBlock>
|
||||
</Grid>
|
||||
|
||||
<Button Grid.Column="1"
|
||||
x:Name="CloseButton"
|
||||
Style="{StaticResource MwMessageBoxCloseButtonStyle}"
|
||||
Click="OnCloseButtonClick"/>
|
||||
</Grid>
|
||||
|
||||
<Grid Grid.Row="1" Margin="28,28,28,22">
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition Height="Auto"/>
|
||||
<RowDefinition Height="Auto"/>
|
||||
<RowDefinition Height="Auto"/>
|
||||
</Grid.RowDefinitions>
|
||||
|
||||
<Border Width="62"
|
||||
Height="62"
|
||||
HorizontalAlignment="Center"
|
||||
Background="#FFFFFF"
|
||||
BorderBrush="{Binding State.AccentBrush}"
|
||||
BorderThickness="1.5"
|
||||
CornerRadius="31">
|
||||
<Viewbox Width="26"
|
||||
Height="26"
|
||||
Stretch="Uniform">
|
||||
<Path Data="{Binding State.IconPathData}"
|
||||
Fill="{Binding State.IconForegroundBrush}"
|
||||
Stretch="Uniform"/>
|
||||
</Viewbox>
|
||||
</Border>
|
||||
|
||||
<TextBlock Grid.Row="1"
|
||||
Margin="0,18,0,0"
|
||||
HorizontalAlignment="Center"
|
||||
Foreground="#1F2937"
|
||||
FontSize="17"
|
||||
FontWeight="SemiBold"
|
||||
TextAlignment="Center"
|
||||
Style="{StaticResource MwMessageBoxCaptionStyle}"/>
|
||||
|
||||
<TextBlock Grid.Row="2"
|
||||
Margin="0,14,0,0"
|
||||
MaxWidth="540"
|
||||
Text="{Binding State.Message}"
|
||||
TextWrapping="Wrap"
|
||||
Foreground="#4B5563"
|
||||
FontSize="14"
|
||||
LineHeight="23"
|
||||
TextAlignment="Center"
|
||||
FlowDirection="{Binding State.MessageFlowDirection}"/>
|
||||
</Grid>
|
||||
|
||||
<Grid Grid.Row="2">
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition Height="1"/>
|
||||
<RowDefinition Height="Auto"/>
|
||||
</Grid.RowDefinitions>
|
||||
|
||||
<Border Grid.Row="0"
|
||||
Background="#E7EEF7"/>
|
||||
|
||||
<ItemsControl Grid.Row="1"
|
||||
Margin="0,18,0,20"
|
||||
ItemsSource="{Binding State.Buttons}"
|
||||
HorizontalAlignment="Center"
|
||||
MaxWidth="560">
|
||||
<ItemsControl.ItemsPanel>
|
||||
<ItemsPanelTemplate>
|
||||
<WrapPanel Orientation="Horizontal" HorizontalAlignment="Center"/>
|
||||
</ItemsPanelTemplate>
|
||||
</ItemsControl.ItemsPanel>
|
||||
<ItemsControl.ItemTemplate>
|
||||
<DataTemplate>
|
||||
<Button Content="{Binding Text}"
|
||||
MinWidth="96"
|
||||
Height="38"
|
||||
Margin="8,0,8,0"
|
||||
Padding="22,0,22,0"
|
||||
IsDefault="{Binding IsDefault}"
|
||||
IsCancel="{Binding IsCancel}"
|
||||
Style="{Binding ButtonStyle, TargetNullValue={StaticResource MwMessageBoxButtonStyle}}"
|
||||
Command="{Binding DataContext.SelectButtonCommand, RelativeSource={RelativeSource AncestorType=Window}}"
|
||||
CommandParameter="{Binding}"/>
|
||||
</DataTemplate>
|
||||
</ItemsControl.ItemTemplate>
|
||||
</ItemsControl>
|
||||
</Grid>
|
||||
</Grid>
|
||||
</Border>
|
||||
</Window>
|
||||
@@ -0,0 +1,20 @@
|
||||
using System.Windows;
|
||||
using MainShell.Common.ViewModel;
|
||||
|
||||
namespace MainShell.Common.View
|
||||
{
|
||||
public partial class MwMessageBoxWindow : Window
|
||||
{
|
||||
public MwMessageBoxWindow(MwMessageBoxWindowViewModel viewModel)
|
||||
{
|
||||
InitializeComponent();
|
||||
DataContext = viewModel ?? throw new System.ArgumentNullException(nameof(viewModel));
|
||||
CloseButton.Content = "\u00D7";
|
||||
}
|
||||
|
||||
private void OnCloseButtonClick(object sender, System.Windows.RoutedEventArgs e)
|
||||
{
|
||||
this.Close();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,61 @@
|
||||
using System;
|
||||
using System.Windows;
|
||||
using System.Windows.Input;
|
||||
using MaxwellFramework.Core.Common.Command;
|
||||
using Stylet;
|
||||
|
||||
namespace MainShell.Common.ViewModel
|
||||
{
|
||||
public class MwMessageBoxWindowViewModel : PropertyChangedBase
|
||||
{
|
||||
private bool? _dialogResult;
|
||||
private MessageBoxResult _result;
|
||||
|
||||
public MwMessageBoxWindowViewModel(MwMessageBoxState state)
|
||||
{
|
||||
State = state ?? throw new ArgumentNullException(nameof(state));
|
||||
SelectButtonCommand = new DelegateCommand(OnSelectButton);
|
||||
WindowClosingCommand = new DelegateCommand(OnWindowClosing);
|
||||
}
|
||||
|
||||
public MwMessageBoxState State { get; }
|
||||
|
||||
public bool? DialogResult
|
||||
{
|
||||
get => _dialogResult;
|
||||
set => SetAndNotify(ref _dialogResult, value);
|
||||
}
|
||||
|
||||
public MessageBoxResult Result
|
||||
{
|
||||
get => _result;
|
||||
private set => SetAndNotify(ref _result, value);
|
||||
}
|
||||
|
||||
public ICommand SelectButtonCommand { get; }
|
||||
|
||||
public ICommand WindowClosingCommand { get; }
|
||||
|
||||
private void OnSelectButton(object parameter)
|
||||
{
|
||||
var definition = parameter as MwMessageBoxButtonDefinition;
|
||||
if (definition == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
Result = definition.Result;
|
||||
DialogResult = true;
|
||||
}
|
||||
|
||||
private void OnWindowClosing(object parameter)
|
||||
{
|
||||
if (Result != MessageBoxResult.None)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
Result = MwMessageBox.ResolveFallbackResult(State);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,28 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using System.Windows.Markup;
|
||||
|
||||
namespace MainShell.Common
|
||||
{
|
||||
[MarkupExtensionReturnType(typeof(string))]
|
||||
public class PropDescExtension : MarkupExtension
|
||||
{
|
||||
public Type ForType { get; set; }
|
||||
public string Property { get; set; }
|
||||
|
||||
public override object ProvideValue(IServiceProvider serviceProvider)
|
||||
{
|
||||
if (ForType == null || string.IsNullOrWhiteSpace(Property)) return Property;
|
||||
|
||||
var pd = TypeDescriptor.GetProperties(ForType)[Property];
|
||||
if (pd == null) return Property;
|
||||
|
||||
var desc = pd.Attributes.OfType<DescriptionAttribute>().FirstOrDefault();
|
||||
return string.IsNullOrWhiteSpace(desc?.Description) ? Property : desc.Description;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,232 @@
|
||||
using System;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace MainShell.Common
|
||||
{
|
||||
public class RetryMechanism
|
||||
{
|
||||
// 自定义异常:操作失败
|
||||
public class RetryException : Exception
|
||||
{
|
||||
public RetryException(string message) : base(message) { }
|
||||
}
|
||||
|
||||
public class RetryResult
|
||||
{
|
||||
public bool Succeeded { get; set; }
|
||||
|
||||
public bool IsAborted { get; set; }
|
||||
|
||||
public int AttemptCount { get; set; }
|
||||
|
||||
public int MaxAttempts { get; set; }
|
||||
|
||||
public string Message { get; set; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 向后兼容旧接口:默认直接继续重试直到达到最大次数,失败时抛异常。
|
||||
/// 新代码建议优先使用 <see cref="RetryOrThrow(Func{bool}, Func{int, bool}, string, int)"/> 或返回结果对象的重载。
|
||||
/// </summary>
|
||||
public static void RetryIfNeeded(Func<bool> checkCondition, string message, int maxAttempts = 3)
|
||||
{
|
||||
RetryOrThrow(checkCondition, attempt => true, message, maxAttempts);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 执行同步重试并返回结果对象。
|
||||
/// </summary>
|
||||
/// <param name="checkCondition">
|
||||
/// 每次尝试时执行的检查逻辑。
|
||||
/// 返回 <c>true</c> 表示成功,返回 <c>false</c> 表示本次失败并根据 <paramref name="shouldRetry"/> 决定是否继续。
|
||||
/// 如果该委托抛出异常,则异常会直接向外传播,不会被当前重试机制捕获或吞掉,也不会自动进入下一次重试。
|
||||
/// </param>
|
||||
/// <param name="shouldRetry">当一次尝试失败后,决定是否继续重试。参数为当前已完成的尝试次数,从 1 开始计数。</param>
|
||||
/// <param name="message">操作描述信息。</param>
|
||||
/// <param name="maxAttempts">最大尝试次数,必须大于 0。</param>
|
||||
public static RetryResult RetryIfNeeded(Func<bool> checkCondition, Func<int, bool> shouldRetry, string message, int maxAttempts = 3)
|
||||
{
|
||||
if (checkCondition == null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(checkCondition));
|
||||
}
|
||||
|
||||
if (shouldRetry == null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(shouldRetry));
|
||||
}
|
||||
|
||||
if (maxAttempts <= 0)
|
||||
{
|
||||
throw new ArgumentOutOfRangeException(nameof(maxAttempts), "maxAttempts must be greater than 0.");
|
||||
}
|
||||
|
||||
for (int attempt = 1; attempt <= maxAttempts; attempt++)
|
||||
{
|
||||
bool conditionMet = checkCondition();
|
||||
if (conditionMet)
|
||||
{
|
||||
return new RetryResult
|
||||
{
|
||||
Succeeded = true,
|
||||
AttemptCount = attempt,
|
||||
MaxAttempts = maxAttempts,
|
||||
Message = message
|
||||
};
|
||||
}
|
||||
|
||||
if (attempt == maxAttempts)
|
||||
{
|
||||
return new RetryResult
|
||||
{
|
||||
Succeeded = false,
|
||||
AttemptCount = attempt,
|
||||
MaxAttempts = maxAttempts,
|
||||
Message = message
|
||||
};
|
||||
}
|
||||
|
||||
bool continueRetry = shouldRetry(attempt);
|
||||
if (!continueRetry)
|
||||
{
|
||||
return new RetryResult
|
||||
{
|
||||
Succeeded = false,
|
||||
IsAborted = true,
|
||||
AttemptCount = attempt,
|
||||
MaxAttempts = maxAttempts,
|
||||
Message = message
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
return new RetryResult
|
||||
{
|
||||
Succeeded = false,
|
||||
AttemptCount = maxAttempts,
|
||||
MaxAttempts = maxAttempts,
|
||||
Message = message
|
||||
};
|
||||
}
|
||||
|
||||
// 保留抛异常风格的兼容方法
|
||||
public static void RetryOrThrow(Func<bool> checkCondition, Func<int, bool> shouldRetry, string message, int maxAttempts = 3)
|
||||
{
|
||||
var result = RetryIfNeeded(checkCondition, shouldRetry, message, maxAttempts);
|
||||
EnsureSuccess(result);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 向后兼容旧接口的异步版本:默认直接继续重试直到达到最大次数,失败时抛异常。
|
||||
/// 新代码建议优先使用 <see cref="RetryOrThrowAsync(Func{Task{bool}}, Func{int, Task{bool}}, string, int, CancellationToken)"/> 或返回结果对象的重载。
|
||||
/// </summary>
|
||||
public static async Task RetryIfNeededAsync(Func<Task<bool>> checkConditionAsync, string message, int maxAttempts = 3)
|
||||
{
|
||||
await RetryOrThrowAsync(checkConditionAsync, attempt => Task.FromResult(true), message, maxAttempts, CancellationToken.None).ConfigureAwait(false);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 执行异步重试并返回结果对象。
|
||||
/// </summary>
|
||||
/// <param name="checkConditionAsync">
|
||||
/// 每次尝试时执行的异步检查逻辑。
|
||||
/// 返回 <c>true</c> 表示成功,返回 <c>false</c> 表示本次失败并根据 <paramref name="shouldRetryAsync"/> 决定是否继续。
|
||||
/// 如果该委托抛出异常,则异常会直接向外传播,不会被当前重试机制捕获或吞掉,也不会自动进入下一次重试。
|
||||
/// </param>
|
||||
/// <param name="shouldRetryAsync">当一次尝试失败后,决定是否继续重试。参数为当前已完成的尝试次数,从 1 开始计数。</param>
|
||||
/// <param name="message">操作描述信息。</param>
|
||||
/// <param name="maxAttempts">最大尝试次数,必须大于 0。</param>
|
||||
/// <param name="cancellationToken">用于取消异步重试流程。</param>
|
||||
public static async Task<RetryResult> RetryIfNeededAsync(Func<Task<bool>> checkConditionAsync, Func<int, Task<bool>> shouldRetryAsync, string message, int maxAttempts = 3, CancellationToken cancellationToken = default(CancellationToken))
|
||||
{
|
||||
if (checkConditionAsync == null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(checkConditionAsync));
|
||||
}
|
||||
|
||||
if (shouldRetryAsync == null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(shouldRetryAsync));
|
||||
}
|
||||
|
||||
if (maxAttempts <= 0)
|
||||
{
|
||||
throw new ArgumentOutOfRangeException(nameof(maxAttempts), "maxAttempts must be greater than 0.");
|
||||
}
|
||||
|
||||
for (int attempt = 1; attempt <= maxAttempts; attempt++)
|
||||
{
|
||||
cancellationToken.ThrowIfCancellationRequested();
|
||||
|
||||
bool conditionMet = await checkConditionAsync().ConfigureAwait(false);
|
||||
if (conditionMet)
|
||||
{
|
||||
return new RetryResult
|
||||
{
|
||||
Succeeded = true,
|
||||
AttemptCount = attempt,
|
||||
MaxAttempts = maxAttempts,
|
||||
Message = message
|
||||
};
|
||||
}
|
||||
|
||||
if (attempt == maxAttempts)
|
||||
{
|
||||
return new RetryResult
|
||||
{
|
||||
Succeeded = false,
|
||||
AttemptCount = attempt,
|
||||
MaxAttempts = maxAttempts,
|
||||
Message = message
|
||||
};
|
||||
}
|
||||
|
||||
cancellationToken.ThrowIfCancellationRequested();
|
||||
|
||||
bool continueRetry = await shouldRetryAsync(attempt).ConfigureAwait(false);
|
||||
if (!continueRetry)
|
||||
{
|
||||
return new RetryResult
|
||||
{
|
||||
Succeeded = false,
|
||||
IsAborted = true,
|
||||
AttemptCount = attempt,
|
||||
MaxAttempts = maxAttempts,
|
||||
Message = message
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
return new RetryResult
|
||||
{
|
||||
Succeeded = false,
|
||||
AttemptCount = maxAttempts,
|
||||
MaxAttempts = maxAttempts,
|
||||
Message = message
|
||||
};
|
||||
}
|
||||
|
||||
// 保留抛异常风格的异步兼容方法
|
||||
public static async Task RetryOrThrowAsync(Func<Task<bool>> checkConditionAsync, Func<int, Task<bool>> shouldRetryAsync, string message, int maxAttempts = 3, CancellationToken cancellationToken = default(CancellationToken))
|
||||
{
|
||||
var result = await RetryIfNeededAsync(checkConditionAsync, shouldRetryAsync, message, maxAttempts, cancellationToken).ConfigureAwait(false);
|
||||
EnsureSuccess(result);
|
||||
}
|
||||
|
||||
private static void EnsureSuccess(RetryResult result)
|
||||
{
|
||||
if (result.Succeeded)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (result.IsAborted)
|
||||
{
|
||||
throw new RetryException($"{result.Message} 已中止重试,操作失败。尝试次数: {result.AttemptCount}/{result.MaxAttempts}");
|
||||
}
|
||||
|
||||
throw new RetryException($"{result.Message} 已达到最大重试次数,操作失败。尝试次数: {result.AttemptCount}/{result.MaxAttempts}");
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,77 @@
|
||||
using System;
|
||||
using System.Diagnostics;
|
||||
using System.Threading;
|
||||
|
||||
namespace MainShell.Common
|
||||
{
|
||||
class TimeoutRetryMechanism
|
||||
{
|
||||
public class WaitForConditionResult
|
||||
{
|
||||
public bool Succeeded { get; set; }
|
||||
|
||||
public bool TimedOut { get; set; }
|
||||
|
||||
public bool IsAborted { get; set; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 在指定超时时间内轮询等待条件成立。
|
||||
/// 当 <paramref name="timeout"/> 为 <c>null</c> 时,表示无限等待,直到条件成立或外部取消。
|
||||
/// </summary>
|
||||
/// <param name="condition">待检查的条件,返回 <c>true</c> 表示条件成立。</param>
|
||||
/// <param name="timeout">最大等待时间。传入 <c>null</c> 表示无限等待;传入具体值时必须大于 0。</param>
|
||||
/// <param name="pollingInterval">轮询间隔,必须大于 0。</param>
|
||||
/// <param name="cancellationToken">用于中止等待流程。</param>
|
||||
public static WaitForConditionResult WaitForConditionWithTimeout(Func<bool> condition, TimeSpan? timeout, TimeSpan pollingInterval, CancellationToken cancellationToken)
|
||||
{
|
||||
if (condition == null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(condition));
|
||||
}
|
||||
|
||||
if (timeout.HasValue && timeout.Value <= TimeSpan.Zero)
|
||||
{
|
||||
throw new ArgumentOutOfRangeException(nameof(timeout), "timeout must be greater than zero when specified.");
|
||||
}
|
||||
|
||||
if (pollingInterval <= TimeSpan.Zero)
|
||||
{
|
||||
throw new ArgumentOutOfRangeException(nameof(pollingInterval), "pollingInterval must be greater than zero.");
|
||||
}
|
||||
|
||||
var stopwatch = Stopwatch.StartNew();
|
||||
|
||||
while (true)
|
||||
{
|
||||
if (condition())
|
||||
{
|
||||
return new WaitForConditionResult
|
||||
{
|
||||
Succeeded = true
|
||||
};
|
||||
}
|
||||
|
||||
if (timeout.HasValue && stopwatch.Elapsed > timeout.Value)
|
||||
{
|
||||
return new WaitForConditionResult
|
||||
{
|
||||
Succeeded = false,
|
||||
TimedOut = true
|
||||
};
|
||||
}
|
||||
|
||||
if (cancellationToken.IsCancellationRequested)
|
||||
{
|
||||
return new WaitForConditionResult
|
||||
{
|
||||
Succeeded = false,
|
||||
IsAborted = true
|
||||
};
|
||||
}
|
||||
|
||||
Thread.Sleep(pollingInterval);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,63 @@
|
||||
<Window x:Class="MainShell.Common.View.CameraSettingsView"
|
||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||
xmlns:local="clr-namespace:MainShell.Common.View"
|
||||
xmlns:custom="clr-namespace:MainShell.Resources.CustomControl" xmlns:mw="http://www.maxwell-gp.com/"
|
||||
mc:Ignorable="d"
|
||||
Title="相机设置"
|
||||
Width="450" SizeToContent="Height"
|
||||
WindowStartupLocation="CenterScreen"
|
||||
ResizeMode="NoResize"
|
||||
WindowStyle="ToolWindow"
|
||||
d:DesignHeight="300" d:DesignWidth="350">
|
||||
<StackPanel Margin="5">
|
||||
<!-- 相机参数设置 -->
|
||||
<GroupBox Header="{DynamicResource CameraPar}" Margin="0,0,0,5" Style="{StaticResource GroupBoxSecondary}">
|
||||
<Grid Margin="5">
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition Height="Auto"/>
|
||||
<RowDefinition Height="Auto"/>
|
||||
</Grid.RowDefinitions>
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="Auto"/>
|
||||
<ColumnDefinition Width="*"/>
|
||||
</Grid.ColumnDefinitions>
|
||||
|
||||
<!-- 曝光时间 -->
|
||||
<TextBlock Grid.Row="0" Grid.Column="0" Text="曝光时间:" VerticalAlignment="Center" Style="{StaticResource LabelStyle}"/>
|
||||
<mw:IntNumberBox Grid.Row="0" Grid.Column="1"
|
||||
Value="{Binding CameraConfig.ExposureTime}"
|
||||
Minimum="10" Maximum="1000000"
|
||||
mw:NumericKeypadAttach.IsEnabled="True"
|
||||
HorizontalContentAlignment="Right" Margin="5,2,0,2"/>
|
||||
|
||||
<!-- 增益 -->
|
||||
<TextBlock Grid.Row="1" Grid.Column="0" Text="增益:" VerticalAlignment="Center" Style="{StaticResource LabelStyle}"/>
|
||||
<mw:IntNumberBox Grid.Row="1" Grid.Column="1"
|
||||
Value="{Binding CameraConfig.Gain}"
|
||||
Minimum="1" Maximum="100"
|
||||
mw:NumericKeypadAttach.IsEnabled="True"
|
||||
HorizontalContentAlignment="Right" Margin="5,2,0,2"/>
|
||||
</Grid>
|
||||
</GroupBox>
|
||||
|
||||
<!-- 光源参数设置 -->
|
||||
<!-- 使用 ItemsControl 动态生成 LightControl,需要 ViewModel 提供光源通道列表 -->
|
||||
<GroupBox Header="{DynamicResource LightSetting}" Style="{StaticResource GroupBoxSecondary}">
|
||||
<ItemsControl ItemsSource="{Binding LightChannels}">
|
||||
<ItemsControl.ItemTemplate>
|
||||
<DataTemplate>
|
||||
<custom:LightControl Header="{Binding Name}"
|
||||
Value="{Binding Value, Mode=TwoWay}"
|
||||
Min="0" Max="255" Margin="0,2"/>
|
||||
</DataTemplate>
|
||||
</ItemsControl.ItemTemplate>
|
||||
</ItemsControl>
|
||||
</GroupBox>
|
||||
<StackPanel HorizontalAlignment="Right" Orientation="Horizontal">
|
||||
<Button Content="{DynamicResource GetParameter}" Style="{StaticResource TeachButtonStyle}" Margin="5" IsDefault="True" Command="{Binding ReadFromHardwareCommand}"/>
|
||||
</StackPanel>
|
||||
</StackPanel>
|
||||
</Window>
|
||||
@@ -0,0 +1,28 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using System.Windows;
|
||||
using System.Windows.Controls;
|
||||
using System.Windows.Data;
|
||||
using System.Windows.Documents;
|
||||
using System.Windows.Input;
|
||||
using System.Windows.Media;
|
||||
using System.Windows.Media.Imaging;
|
||||
using System.Windows.Navigation;
|
||||
using System.Windows.Shapes;
|
||||
|
||||
namespace MainShell.Common.View
|
||||
{
|
||||
/// <summary>
|
||||
/// CameraSettingsControl.xaml 的交互逻辑
|
||||
/// </summary>
|
||||
public partial class CameraSettingsView : Window
|
||||
{
|
||||
public CameraSettingsView()
|
||||
{
|
||||
InitializeComponent();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,254 @@
|
||||
using MainShell.Common;
|
||||
using MainShell.Hardware;
|
||||
using MainShell.Models;
|
||||
using MwFramework.Controls.ControlCanvas;
|
||||
using Stylet;
|
||||
using System;
|
||||
using System.Collections.ObjectModel;
|
||||
using System.ComponentModel;
|
||||
using System.Reflection;
|
||||
using System.Windows.Input;
|
||||
|
||||
namespace MainShell.Common.ViewModel
|
||||
{
|
||||
/// <summary>
|
||||
/// 单个光源通道的包装类
|
||||
/// </summary>
|
||||
public class LightChannelViewModel : PropertyChangedBase
|
||||
{
|
||||
private readonly object _sourceConfig;
|
||||
private readonly PropertyInfo _propertyInfo;
|
||||
|
||||
public string Name { get; set; }
|
||||
|
||||
public int Value
|
||||
{
|
||||
get => (int)_propertyInfo.GetValue(_sourceConfig);
|
||||
set
|
||||
{
|
||||
if (value != Value)
|
||||
{
|
||||
_propertyInfo.SetValue(_sourceConfig, value);
|
||||
NotifyOfPropertyChange();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public LightChannelViewModel(object sourceConfig, PropertyInfo propertyInfo, string displayName)
|
||||
{
|
||||
_sourceConfig = sourceConfig;
|
||||
_propertyInfo = propertyInfo;
|
||||
Name = displayName;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 相机及光源参数设置弹窗 ViewModel
|
||||
/// </summary>
|
||||
public class CameraSettingsViewModel : Screen
|
||||
{
|
||||
private readonly IWindowManager _windowManager;
|
||||
private readonly HardwareManager _hardwareManager;
|
||||
|
||||
// 核心标志位:是否正在从硬件同步数据
|
||||
private bool _isSyncingFromHardware;
|
||||
|
||||
private CameraType _currentCameraType;
|
||||
private object _currentLightConfig;
|
||||
|
||||
private CameraConfig _cameraConfig;
|
||||
public CameraConfig CameraConfig
|
||||
{
|
||||
get => _cameraConfig;
|
||||
set => SetAndNotify(ref _cameraConfig, value);
|
||||
}
|
||||
|
||||
private ObservableCollection<LightChannelViewModel> _lightChannels;
|
||||
public ObservableCollection<LightChannelViewModel> LightChannels
|
||||
{
|
||||
get => _lightChannels;
|
||||
set => SetAndNotify(ref _lightChannels, value);
|
||||
}
|
||||
|
||||
public ICommand ReadFromHardwareCommand { get; }
|
||||
public ICommand SaveAndCloseCommand { get; }
|
||||
|
||||
public CameraSettingsViewModel(IWindowManager windowManager, HardwareManager hardwareManager)
|
||||
{
|
||||
_windowManager = windowManager;
|
||||
_hardwareManager = hardwareManager;
|
||||
|
||||
ReadFromHardwareCommand = new DelegateCommand(ReadFromHardware);
|
||||
SaveAndCloseCommand = new DelegateCommand(SaveAndClose);
|
||||
DisplayName = "相机光源参数设置";
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 初始化并绑定数据
|
||||
/// </summary>
|
||||
public void Initialize(CameraConfig cameraConfig, object lightConfig, CameraType cameraType)
|
||||
{
|
||||
// 1. 解绑旧对象的事件(如果有)
|
||||
if (CameraConfig != null) CameraConfig.PropertyChanged -= OnConfigPropertyChanged;
|
||||
if (_currentLightConfig is INotifyPropertyChanged oldLight) oldLight.PropertyChanged -= OnConfigPropertyChanged;
|
||||
|
||||
_currentCameraType = cameraType;
|
||||
CameraConfig = cameraConfig;
|
||||
_currentLightConfig = lightConfig;
|
||||
|
||||
// 2. 重新订阅事件
|
||||
if (CameraConfig != null) CameraConfig.PropertyChanged += OnConfigPropertyChanged;
|
||||
if (_currentLightConfig is INotifyPropertyChanged newLight) newLight.PropertyChanged += OnConfigPropertyChanged;
|
||||
|
||||
// 3. 生成光源通道列表
|
||||
LightChannels = new ObservableCollection<LightChannelViewModel>();
|
||||
if (lightConfig != null)
|
||||
{
|
||||
var properties = lightConfig.GetType().GetProperties(BindingFlags.Public | BindingFlags.Instance);
|
||||
foreach (var prop in properties)
|
||||
{
|
||||
if (prop.PropertyType == typeof(int) && prop.CanRead && prop.CanWrite)
|
||||
{
|
||||
var descAttr = prop.GetCustomAttribute<DescriptionAttribute>();
|
||||
// 必须有 Description 才认为是光源通道
|
||||
if (descAttr != null)
|
||||
{
|
||||
var vm = new LightChannelViewModel(lightConfig, prop, descAttr.Description);
|
||||
LightChannels.Add(vm);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 统一处理属性变更事件 => 设置硬件
|
||||
/// </summary>
|
||||
private void OnConfigPropertyChanged(object sender, PropertyChangedEventArgs e)
|
||||
{
|
||||
// 关键逻辑:如果是从硬件读取过程中,则忽略,不要反向设置回去
|
||||
if (_isSyncingFromHardware) return;
|
||||
|
||||
ApplySettingToHardware(sender, e.PropertyName);
|
||||
}
|
||||
|
||||
private void ApplySettingToHardware(object source, string propertyName)
|
||||
{
|
||||
// 1. 设置相机参数
|
||||
if (source == CameraConfig)
|
||||
{
|
||||
// TODO: 替换为实际的 set 相机参数代码
|
||||
/*
|
||||
var camDevice = _hardwareManager.GetCamera(_currentCameraType);
|
||||
if (propertyName == nameof(CameraConfig.ExposureTime))
|
||||
{
|
||||
camDevice.SetExposure(CameraConfig.ExposureTime);
|
||||
}
|
||||
else if (propertyName == nameof(CameraConfig.Gain))
|
||||
{
|
||||
camDevice.SetGain(CameraConfig.Gain);
|
||||
}
|
||||
*/
|
||||
System.Diagnostics.Debug.WriteLine($"[Hardware Set] Cam: {_currentCameraType}, Prop: {propertyName}");
|
||||
return;
|
||||
}
|
||||
|
||||
// 2. 设置光源参数 (根据类型直接判断)
|
||||
if (source is MapCamLightConfig mapConfig)
|
||||
{
|
||||
if (propertyName == nameof(MapCamLightConfig.RedLight))
|
||||
{
|
||||
// TODO: _hardwareManager.SetMapRedLight(mapConfig.RedLight);
|
||||
System.Diagnostics.Debug.WriteLine($"[Hardware Set] MapCam Red: {mapConfig.RedLight}");
|
||||
}
|
||||
else if (propertyName == nameof(MapCamLightConfig.BlueLight))
|
||||
{
|
||||
// TODO: _hardwareManager.SetMapBlueLight(mapConfig.BlueLight);
|
||||
System.Diagnostics.Debug.WriteLine($"[Hardware Set] MapCam Blue: {mapConfig.BlueLight}");
|
||||
}
|
||||
}
|
||||
else if (source is UpCamLightConfig upConfig)
|
||||
{
|
||||
if (propertyName == nameof(UpCamLightConfig.PointRedLight))
|
||||
{
|
||||
// TODO: _hardwareManager.SetUpPointRed(upConfig.PointRedLight);
|
||||
System.Diagnostics.Debug.WriteLine($"[Hardware Set] UpCam PointRed: {upConfig.PointRedLight}");
|
||||
}
|
||||
else if (propertyName == nameof(UpCamLightConfig.RingRedLight))
|
||||
{
|
||||
// TODO: ...
|
||||
}
|
||||
// ... 处理其他 UpCam 通道
|
||||
}
|
||||
else if (source is DownCamLightConfig downConfig)
|
||||
{
|
||||
if (propertyName == nameof(DownCamLightConfig.PointRedLight))
|
||||
{
|
||||
// TODO: ...
|
||||
}
|
||||
// ... 处理其他 DownCam 通道
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 从硬件读取当前值 => 更新 UI (不触发设置)
|
||||
/// </summary>
|
||||
private void ReadFromHardware()
|
||||
{
|
||||
try
|
||||
{
|
||||
_isSyncingFromHardware = true; // 开启静默模式
|
||||
|
||||
// 1. 读取相机实际参数
|
||||
/*
|
||||
var camDevice = _hardwareManager.GetCamera(_currentCameraType);
|
||||
if (camDevice != null) {
|
||||
CameraConfig.ExposureTime = (int)camDevice.CurrentExposure;
|
||||
CameraConfig.Gain = (int)camDevice.CurrentGain;
|
||||
}
|
||||
*/
|
||||
|
||||
// 2. 读取光源实际参数
|
||||
if (_currentLightConfig is MapCamLightConfig mapConfig)
|
||||
{
|
||||
// TODO: 读取实际硬件值
|
||||
mapConfig.RedLight = _hardwareManager.GetMapRedLightIntensity();
|
||||
mapConfig.BlueLight = _hardwareManager.GetMapBlueLightIntensity();
|
||||
}
|
||||
else if (_currentLightConfig is UpCamLightConfig upConfig)
|
||||
{
|
||||
upConfig.PointRedLight = _hardwareManager.GetUpPointRedLightIntensity();
|
||||
upConfig.PointBlueLight=_hardwareManager.GetUpPointBlueLightIntensity();
|
||||
upConfig.RingRedLight=_hardwareManager.GetUpRingRedLightIntensity();
|
||||
upConfig.RingBlueLight=_hardwareManager.GetUpRingBlueLightIntensity();
|
||||
upConfig.RedBackLight=_hardwareManager.GetUpRedBackLightIntensity();
|
||||
// ...
|
||||
}
|
||||
else if (_currentLightConfig is DownCamLightConfig downConfig)
|
||||
{
|
||||
// downConfig.PointRedLight = ...
|
||||
downConfig.PointRedLight = _hardwareManager.GetDownPointRedLightIntensity();
|
||||
downConfig.PointBlueLight = _hardwareManager.GetDownPointBlueLightIntensity();
|
||||
downConfig.RingRedLight = _hardwareManager.GetDownRingRedLightIntensity();
|
||||
downConfig.RingBlueLight = _hardwareManager.GetDownRingBlueLightIntensity();
|
||||
// ...
|
||||
}
|
||||
|
||||
}
|
||||
finally
|
||||
{
|
||||
foreach (var channel in LightChannels)
|
||||
{
|
||||
// 强制刷新 UI
|
||||
channel.Refresh();
|
||||
}
|
||||
_isSyncingFromHardware = false; // 必须复位
|
||||
}
|
||||
}
|
||||
|
||||
private void SaveAndClose()
|
||||
{
|
||||
RequestClose(true);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,28 @@
|
||||
<UserControl x:Class="MainShell.Common.VisionTemple.View.VisionTempleView"
|
||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||
xmlns:local="clr-namespace:MainShell.Common.VisionTemple.View" xmlns:control="http://www.maxwell.com/controls"
|
||||
mc:Ignorable="d"
|
||||
d:DesignHeight="450" d:DesignWidth="800">
|
||||
<Grid>
|
||||
|
||||
<control:CameraVision DataContext="{Binding Service}" Name="cameraVision">
|
||||
<control:CameraVision.CameraHost>
|
||||
<control:CameraAxisControlA
|
||||
Items="{Binding CameraModel.CameraShowViewModel.Items}"
|
||||
Source="{Binding CameraModel.CameraShowViewModel.CurrentImage, Mode=OneWay}"
|
||||
TabSelectedIndex="{Binding SelectCameraIndex}"
|
||||
Cameras="{Binding Cameras}"
|
||||
Device="{Binding SelectItem}"
|
||||
ImportFile="{Binding CameraModel.ImportFile}"
|
||||
Regions="{Binding CameraModel.CameraShowViewModel.Regions}"
|
||||
IsClear="{Binding CameraModel.CameraShowViewModel.IsClear}"
|
||||
IsShowContext="True"
|
||||
ShapeThickness="1" IsShowSolidLine="True" DrawInConcurrency = "False"/>
|
||||
</control:CameraVision.CameraHost>
|
||||
</control:CameraVision>
|
||||
|
||||
</Grid>
|
||||
</UserControl>
|
||||
@@ -0,0 +1,28 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using System.Windows;
|
||||
using System.Windows.Controls;
|
||||
using System.Windows.Data;
|
||||
using System.Windows.Documents;
|
||||
using System.Windows.Input;
|
||||
using System.Windows.Media;
|
||||
using System.Windows.Media.Imaging;
|
||||
using System.Windows.Navigation;
|
||||
using System.Windows.Shapes;
|
||||
|
||||
namespace MainShell.Common.VisionTemple.View
|
||||
{
|
||||
/// <summary>
|
||||
/// VisionTempleView.xaml 的交互逻辑
|
||||
/// </summary>
|
||||
public partial class VisionTempleView : UserControl
|
||||
{
|
||||
public VisionTempleView()
|
||||
{
|
||||
InitializeComponent();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
<Window x:Class="MainShell.Common.VisionTemple.View.VisionTempleWindow"
|
||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
xmlns:view="clr-namespace:MainShell.Common.VisionTemple.View"
|
||||
mc:Ignorable="d"
|
||||
Title="{Binding DisplayName}"
|
||||
Height="875"
|
||||
Width="1000"
|
||||
WindowStartupLocation="CenterOwner"
|
||||
Background="White">
|
||||
<Grid Background="White">
|
||||
<view:VisionTempleView DataContext="{Binding VisionTemple}" />
|
||||
</Grid>
|
||||
</Window>
|
||||
@@ -0,0 +1,15 @@
|
||||
using System.Windows;
|
||||
|
||||
namespace MainShell.Common.VisionTemple.View
|
||||
{
|
||||
/// <summary>
|
||||
/// VisionTempleWindow.xaml 的交互逻辑
|
||||
/// </summary>
|
||||
public partial class VisionTempleWindow : Window
|
||||
{
|
||||
public VisionTempleWindow()
|
||||
{
|
||||
InitializeComponent();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,32 @@
|
||||
using MwFramework.Controls.PatternTemplate.ViewModel;
|
||||
using Stylet;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace MainShell.Common.VisionTemple.ViewModel
|
||||
{
|
||||
public class VisionTempleViewModel : Screen
|
||||
{
|
||||
public string Name { get; set; } = "VisionTempleModel";
|
||||
|
||||
private MatchTemplateService _service;
|
||||
|
||||
public MatchTemplateService Service
|
||||
{
|
||||
get { return _service; }
|
||||
set
|
||||
{
|
||||
_service = value;
|
||||
OnPropertyChanged(nameof(Service));
|
||||
}
|
||||
}
|
||||
|
||||
public VisionTempleViewModel()
|
||||
{
|
||||
_service = new MatchTemplateService();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,114 @@
|
||||
using MainShell.Common.VisionTemple.View;
|
||||
using MainShell.Hardware;
|
||||
using Stylet;
|
||||
using System.ComponentModel;
|
||||
using System.Windows;
|
||||
|
||||
namespace MainShell.Common.VisionTemple.ViewModel
|
||||
{
|
||||
public class VisionTempleWindowViewModel : Screen
|
||||
{
|
||||
private readonly VisionTempleViewModel _visionTemple;
|
||||
private VisionTempleWindow _window;
|
||||
private bool _isShuttingDown;
|
||||
private readonly HardwareManager _hardwareManager;
|
||||
|
||||
public VisionTempleWindowViewModel(HardwareManager hardwareManager)
|
||||
{
|
||||
DisplayName = "视觉模板制作";
|
||||
_visionTemple = new VisionTempleViewModel();
|
||||
_visionTemple.Service = new MwFramework.Controls.PatternTemplate.ViewModel.MatchTemplateService();
|
||||
_visionTemple.Service.CameraModel.IsShowFoldDialog = false;
|
||||
_hardwareManager = hardwareManager;
|
||||
}
|
||||
|
||||
private string _templatePath;
|
||||
/// <summary>
|
||||
/// 模版路径
|
||||
/// </summary>
|
||||
public string TemplatePath
|
||||
{
|
||||
get { return _templatePath; }
|
||||
set
|
||||
{
|
||||
_templatePath = value;
|
||||
_visionTemple.Service.CameraModel.TemplatePath = value;
|
||||
}
|
||||
}
|
||||
|
||||
public VisionTempleViewModel VisionTemple
|
||||
{
|
||||
get
|
||||
{
|
||||
return _visionTemple;
|
||||
}
|
||||
}
|
||||
|
||||
public void SetCamera(CameraType cameraType)
|
||||
{
|
||||
switch (cameraType)
|
||||
{
|
||||
case CameraType.MapCamera:
|
||||
_visionTemple.Service.Cameras = _hardwareManager.CameraAxisManager.BottomCameraAxisDevices;
|
||||
break;
|
||||
case CameraType.TopPositionCamera:
|
||||
_visionTemple.Service.Cameras = _hardwareManager.CameraAxisManager.TopCameraAxisDevices;
|
||||
break;
|
||||
case CameraType.TopWideCamera:
|
||||
_visionTemple.Service.Cameras = _hardwareManager.CameraAxisManager.WideCameraAxisDevices;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
if(_visionTemple.Service.Cameras!=null&& _visionTemple.Service.Cameras.Count>0)
|
||||
{
|
||||
_visionTemple.Service.SelectItem = _visionTemple.Service.Cameras[0];
|
||||
}
|
||||
}
|
||||
|
||||
public void ShowWindow()
|
||||
{
|
||||
if (_window == null)
|
||||
{
|
||||
_window = new VisionTempleWindow();
|
||||
_window.DataContext = this;
|
||||
_window.Closing += OnWindowClosing;
|
||||
}
|
||||
|
||||
Window owner = Application.Current != null ? Application.Current.MainWindow : null;
|
||||
if (owner != null && _window.Owner == null)
|
||||
{
|
||||
_window.Owner = owner;
|
||||
owner.Closing += OnOwnerClosing;
|
||||
}
|
||||
|
||||
if (_window.IsVisible)
|
||||
{
|
||||
if (_window.WindowState == WindowState.Minimized)
|
||||
{
|
||||
_window.WindowState = WindowState.Normal;
|
||||
}
|
||||
|
||||
_window.Activate();
|
||||
return;
|
||||
}
|
||||
|
||||
_window.Show();
|
||||
_window.Activate();
|
||||
}
|
||||
|
||||
private void OnWindowClosing(object sender, CancelEventArgs e)
|
||||
{
|
||||
if (!_isShuttingDown)
|
||||
{
|
||||
e.Cancel = true;
|
||||
_window.Hide();
|
||||
}
|
||||
}
|
||||
|
||||
private void OnOwnerClosing(object sender, CancelEventArgs e)
|
||||
{
|
||||
_isShuttingDown = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,40 @@
|
||||
using System.Windows;
|
||||
|
||||
namespace MainShell.Common
|
||||
{
|
||||
public class WindowService
|
||||
{
|
||||
// 定义一个名为 DialogResult 的附加属性
|
||||
public static readonly DependencyProperty DialogResultProperty =
|
||||
DependencyProperty.RegisterAttached(
|
||||
"DialogResult",
|
||||
typeof(bool?),
|
||||
typeof(WindowService),
|
||||
new PropertyMetadata(DialogResultChanged)); // 当此属性值改变时,调用 DialogResultChanged 方法
|
||||
|
||||
// 提供 Set 方法供外部设置附加属性的值
|
||||
public static void SetDialogResult(UIElement element, bool? value)
|
||||
{
|
||||
element.SetValue(DialogResultProperty, value);
|
||||
}
|
||||
|
||||
// 提供 Get 方法供外部获取附加属性的值
|
||||
public static bool? GetDialogResult(UIElement element)
|
||||
{
|
||||
return (bool?)element.GetValue(DialogResultProperty);
|
||||
}
|
||||
|
||||
// 当 DialogResult 附加属性的值改变时调用的回调方法
|
||||
private static void DialogResultChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
|
||||
{
|
||||
// 确保附加属性应用在一个 Window 控件上,并且新的值是 bool 类型
|
||||
if (d is Window window && e.NewValue is bool result)
|
||||
{
|
||||
// 设置窗口的 DialogResult
|
||||
window.DialogResult = result;
|
||||
// 关闭窗口
|
||||
window.Close();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,234 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace MainShell.Common
|
||||
{
|
||||
public static class WorkflowContextKeys
|
||||
{
|
||||
/// <summary>
|
||||
/// 用于传递 IEventAggregator 实例
|
||||
/// </summary>
|
||||
public const string EventAggregator = "EventAggregator";
|
||||
|
||||
/// <summary>
|
||||
/// 用于传递请求令牌 (Guid)
|
||||
/// </summary>
|
||||
public const string RequestToken = "RequestToken";
|
||||
/// <summary>
|
||||
/// 当前配方
|
||||
/// </summary>
|
||||
public const string RecipeManager = "RecipeManager";
|
||||
/// <summary>
|
||||
/// 流程结果管理器 Key
|
||||
/// </summary>
|
||||
public const string ProcessResultManager = "ProcessResultManager";
|
||||
|
||||
/// <summary>
|
||||
/// 恢复目标活动名称
|
||||
/// </summary>
|
||||
public const string ResumeTargetActivityName="ResumeTargetActivityName";
|
||||
|
||||
/// <summary>
|
||||
/// 流程名称
|
||||
/// </summary>
|
||||
public const string WorkflowName = "WorkflowName";
|
||||
|
||||
/// <summary>
|
||||
/// 当前步骤ID
|
||||
/// </summary>
|
||||
public const string CurrentStepId = "CurrentStepId";
|
||||
|
||||
/// <summary>
|
||||
/// 下一步骤ID
|
||||
/// </summary>
|
||||
public const string NextStepId = "NextStepId";
|
||||
|
||||
/// <summary>
|
||||
/// 流程路由配置
|
||||
/// </summary>
|
||||
public const string WorkflowRoutes = "WorkflowRoutes";
|
||||
|
||||
/// <summary>
|
||||
/// 晶片转移路由
|
||||
/// </summary>
|
||||
public const string DieTransferRoute = "DieTransferRoute";
|
||||
|
||||
/// <summary>
|
||||
/// 自动生产路由
|
||||
/// </summary>
|
||||
public const string AutoProductionRoute = "AutoProductionRoute";
|
||||
|
||||
/// <summary>
|
||||
/// 流程运行时追踪器
|
||||
/// </summary>
|
||||
public const string WorkflowRuntimeTracker = "WorkflowRuntimeTracker";
|
||||
|
||||
/// <summary>
|
||||
/// 流程失败消息
|
||||
/// </summary>
|
||||
public const string WorkflowFailureMessage = "WorkflowFailureMessage";
|
||||
|
||||
/// <summary>
|
||||
/// 流程失败消息键
|
||||
/// </summary>
|
||||
public const string WorkflowFailureMessageKey = "WorkflowFailureMessageKey";
|
||||
|
||||
/// <summary>
|
||||
/// 流程失败消息参数
|
||||
/// </summary>
|
||||
public const string WorkflowFailureMessageArguments = "WorkflowFailureMessageArguments";
|
||||
|
||||
/// <summary>
|
||||
/// 准备区服务
|
||||
/// </summary>
|
||||
public const string PreparationAreaService = "PreparationAreaService";
|
||||
|
||||
/// <summary>
|
||||
/// 当前晶片状态服务
|
||||
/// </summary>
|
||||
public const string CurrentChipStateService = "CurrentChipStateService";
|
||||
|
||||
/// <summary>
|
||||
/// 自动生产运行时状态服务
|
||||
/// </summary>
|
||||
public const string AutoProductionRuntimeStateService = "AutoProductionRuntimeStateService";
|
||||
|
||||
/// <summary>
|
||||
/// 准备区状态
|
||||
/// </summary>
|
||||
public const string PreparationAreaStatus = "PreparationAreaStatus";
|
||||
|
||||
/// <summary>
|
||||
/// 当前晶片状态
|
||||
/// </summary>
|
||||
public const string CurrentChipState = "CurrentChipState";
|
||||
|
||||
/// <summary>
|
||||
/// 基板处理状态
|
||||
/// </summary>
|
||||
public const string SubstrateProcessState = "SubstrateProcessState";
|
||||
|
||||
/// <summary>
|
||||
/// 待加载晶片
|
||||
/// </summary>
|
||||
public const string PendingChipLoad = "PendingChipLoad";
|
||||
|
||||
/// <summary>
|
||||
/// 当前基板待处理数量
|
||||
/// </summary>
|
||||
public const string CurrentSubstratePendingCount = "CurrentSubstratePendingCount";
|
||||
|
||||
/// <summary>
|
||||
/// 当前基板已处理数量
|
||||
/// </summary>
|
||||
public const string CurrentSubstrateProcessedCount = "CurrentSubstrateProcessedCount";
|
||||
|
||||
/// <summary>
|
||||
/// 当前晶片剩余数量
|
||||
/// </summary>
|
||||
public const string CurrentChipRemainingCount = "CurrentChipRemainingCount";
|
||||
|
||||
/// <summary>
|
||||
/// 转移需要重新检查
|
||||
/// </summary>
|
||||
public const string TransferNeedsRecheck = "TransferNeedsRecheck";
|
||||
|
||||
/// <summary>
|
||||
/// 转移晶片已耗尽
|
||||
/// </summary>
|
||||
public const string TransferChipExhausted = "TransferChipExhausted";
|
||||
|
||||
/// <summary>
|
||||
/// 晶片转移决策结果
|
||||
/// </summary>
|
||||
public const string DieTransferDecisionResult = "DieTransferDecisionResult";
|
||||
|
||||
/// <summary>
|
||||
/// 晶片转移路径生成请求
|
||||
/// </summary>
|
||||
public const string DieTransferPathRequest = "DieTransferPathRequest";
|
||||
|
||||
/// <summary>
|
||||
/// 晶片转移路径生成结果
|
||||
/// </summary>
|
||||
public const string DieTransferPathPlan = "DieTransferPathPlan";
|
||||
|
||||
/// <summary>
|
||||
/// 当前父级活动/子流程名称
|
||||
/// </summary>
|
||||
public const string ParentActivityName = "ParentActivityName";
|
||||
|
||||
/// <summary>
|
||||
/// 针头Z对刀次数
|
||||
/// </summary>
|
||||
public const string NeedleZCalibrationTouchCount = "NeedleZCalibrationTouchCount";
|
||||
|
||||
/// <summary>
|
||||
/// 针头Z对刀完成后是否自动抬高
|
||||
/// </summary>
|
||||
public const string NeedleZCalibrationAutoRaiseZ1 = "NeedleZCalibrationAutoRaiseZ1";
|
||||
|
||||
/// <summary>
|
||||
/// 针头Z对刀取消令牌
|
||||
/// </summary>
|
||||
public const string NeedleZCalibrationCancellationToken = "NeedleZCalibrationCancellationToken";
|
||||
|
||||
/// <summary>
|
||||
/// 针头Z对刀工作流请求数据
|
||||
/// </summary>
|
||||
public const string NeedleZCalibrationWorkflowData = "NeedleZCalibrationWorkflowData";
|
||||
|
||||
/// <summary>
|
||||
/// 针头Z对刀结果集合
|
||||
/// </summary>
|
||||
public const string NeedleZCalibrationResults = "NeedleZCalibrationResults";
|
||||
|
||||
/// <summary>
|
||||
/// 针头Z对刀最后一次结果
|
||||
/// </summary>
|
||||
public const string NeedleZCalibrationLastResult = "NeedleZCalibrationLastResult";
|
||||
|
||||
/// <summary>
|
||||
/// 针头Z对刀平均结果
|
||||
/// </summary>
|
||||
public const string NeedleZCalibrationAverageResult = "NeedleZCalibrationAverageResult";
|
||||
|
||||
/// <summary>
|
||||
/// 基板定位结果
|
||||
/// </summary>
|
||||
public const string SubstratePositionResult = "SubstratePositionResult";
|
||||
|
||||
/// <summary>
|
||||
/// 芯片定位结果
|
||||
/// </summary>
|
||||
public const string DiePositionResult = "DiePositionResult";
|
||||
|
||||
/// <summary>
|
||||
/// 芯片定位运行态上下文
|
||||
/// </summary>
|
||||
public const string DiePositionContext = "DiePositionContext";
|
||||
|
||||
/// <summary>
|
||||
/// 芯片定位扫描规划结果
|
||||
/// </summary>
|
||||
public const string DiePositionScanPlan = "DiePositionScanPlan";
|
||||
|
||||
/// <summary>
|
||||
/// 基板测高结果
|
||||
/// </summary>
|
||||
public const string SubstrateHeightMeasureResult = "SubstrateHeightMeasureResult";
|
||||
|
||||
/// <summary>
|
||||
/// 精度复检结果
|
||||
/// </summary>
|
||||
public const string DieRecheckResult = "DieRecheckResult";
|
||||
|
||||
/// <summary>
|
||||
/// 基板Mark识别服务
|
||||
/// </summary>
|
||||
public const string SubstrateMarkRecognitionService = "SubstrateMarkRecognitionService";
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,581 @@
|
||||
<?xml version="1.0"?>
|
||||
<ArrayOfPersistenceObject xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
|
||||
<PersistenceObject xsi:type="AxisCardPO">
|
||||
<AlarmOffset>0</AlarmOffset>
|
||||
<CategoryName>AcsCard</CategoryName>
|
||||
<ID>2d23c400-ccf2-469a-add5-ae92a98a85e6</ID>
|
||||
<EnableLog>false</EnableLog>
|
||||
<ConfigPath>AxisCardPO.xml</ConfigPath>
|
||||
<AxisCardType>DEMO</AxisCardType>
|
||||
<AxisCardNum>0</AxisCardNum>
|
||||
<PortNo>0</PortNo>
|
||||
<ListAxisCardParaPO>
|
||||
<AxisCardParaPO>
|
||||
<AlarmOffset>0</AlarmOffset>
|
||||
<CategoryName>PHS-X1</CategoryName>
|
||||
<ID>3a9c772b-4a9c-4077-abbc-80fc038b81ee</ID>
|
||||
<EnableLog>false</EnableLog>
|
||||
<ConfigPath>AxisCardParaPO.xml</ConfigPath>
|
||||
<AxisCardId>0</AxisCardId>
|
||||
<AxisCardName>AcsCard</AxisCardName>
|
||||
<AxisCardNum>0</AxisCardNum>
|
||||
<AxisNum>0</AxisNum>
|
||||
<AxisName>PHS-X1</AxisName>
|
||||
<Direction>X</Direction>
|
||||
<GoogalCore>0</GoogalCore>
|
||||
<GoogalAxisNum>0</GoogalAxisNum>
|
||||
<GoolgalPosErr>0</GoolgalPosErr>
|
||||
<HomeDir>0</HomeDir>
|
||||
<EscapeStep>0</EscapeStep>
|
||||
<HomeMode>HOME_MODE_ERROR</HomeMode>
|
||||
<HomeCheck>false</HomeCheck>
|
||||
<MaxCheckPos>0.001</MaxCheckPos>
|
||||
</AxisCardParaPO>
|
||||
<AxisCardParaPO>
|
||||
<AlarmOffset>0</AlarmOffset>
|
||||
<CategoryName>PHS-X2</CategoryName>
|
||||
<ID>c83e5f81-ef2c-413c-ace9-24bc97c30b32</ID>
|
||||
<EnableLog>false</EnableLog>
|
||||
<ConfigPath>AxisCardParaPO.xml</ConfigPath>
|
||||
<AxisCardId>0</AxisCardId>
|
||||
<AxisCardName>AcsCard</AxisCardName>
|
||||
<AxisCardNum>0</AxisCardNum>
|
||||
<AxisNum>1</AxisNum>
|
||||
<AxisName>PHS-X2</AxisName>
|
||||
<Direction>X</Direction>
|
||||
<GoogalCore>0</GoogalCore>
|
||||
<GoogalAxisNum>0</GoogalAxisNum>
|
||||
<GoolgalPosErr>0</GoolgalPosErr>
|
||||
<HomeDir>0</HomeDir>
|
||||
<EscapeStep>0</EscapeStep>
|
||||
<HomeMode>HOME_MODE_ERROR</HomeMode>
|
||||
<HomeCheck>false</HomeCheck>
|
||||
<MaxCheckPos>0.001</MaxCheckPos>
|
||||
</AxisCardParaPO>
|
||||
<AxisCardParaPO>
|
||||
<AlarmOffset>0</AlarmOffset>
|
||||
<CategoryName>WS-X3</CategoryName>
|
||||
<ID>e0a2d6ed-2972-4595-a8dc-53a504187a9f</ID>
|
||||
<EnableLog>false</EnableLog>
|
||||
<ConfigPath>AxisCardParaPO.xml</ConfigPath>
|
||||
<AxisCardId>0</AxisCardId>
|
||||
<AxisCardName>AcsCard</AxisCardName>
|
||||
<AxisCardNum>0</AxisCardNum>
|
||||
<AxisNum>4</AxisNum>
|
||||
<AxisName>WS-X3</AxisName>
|
||||
<Direction>X</Direction>
|
||||
<GoogalCore>0</GoogalCore>
|
||||
<GoogalAxisNum>0</GoogalAxisNum>
|
||||
<GoolgalPosErr>0</GoolgalPosErr>
|
||||
<HomeDir>0</HomeDir>
|
||||
<EscapeStep>0</EscapeStep>
|
||||
<HomeMode>HOME_MODE_ERROR</HomeMode>
|
||||
<HomeCheck>false</HomeCheck>
|
||||
<MaxCheckPos>0.001</MaxCheckPos>
|
||||
</AxisCardParaPO>
|
||||
<AxisCardParaPO>
|
||||
<AlarmOffset>0</AlarmOffset>
|
||||
<CategoryName>PHS-Y1</CategoryName>
|
||||
<ID>4e145d2a-f7f7-4ce2-a5b0-919375a03d87</ID>
|
||||
<EnableLog>false</EnableLog>
|
||||
<ConfigPath>AxisCardParaPO.xml</ConfigPath>
|
||||
<AxisCardId>0</AxisCardId>
|
||||
<AxisCardName>AcsCard</AxisCardName>
|
||||
<AxisCardNum>0</AxisCardNum>
|
||||
<AxisNum>2</AxisNum>
|
||||
<AxisName>PHS-Y1</AxisName>
|
||||
<Direction>X</Direction>
|
||||
<GoogalCore>0</GoogalCore>
|
||||
<GoogalAxisNum>0</GoogalAxisNum>
|
||||
<GoolgalPosErr>0</GoolgalPosErr>
|
||||
<HomeDir>0</HomeDir>
|
||||
<EscapeStep>0</EscapeStep>
|
||||
<HomeMode>HOME_MODE_ERROR</HomeMode>
|
||||
<HomeCheck>false</HomeCheck>
|
||||
<MaxCheckPos>0.001</MaxCheckPos>
|
||||
</AxisCardParaPO>
|
||||
<AxisCardParaPO>
|
||||
<AlarmOffset>0</AlarmOffset>
|
||||
<CategoryName>WS-R</CategoryName>
|
||||
<ID>cebe7f5c-8cdd-47e8-906a-6083047a078d</ID>
|
||||
<EnableLog>false</EnableLog>
|
||||
<ConfigPath>AxisCardParaPO.xml</ConfigPath>
|
||||
<AxisCardId>0</AxisCardId>
|
||||
<AxisCardName>AcsCard</AxisCardName>
|
||||
<AxisCardNum>0</AxisCardNum>
|
||||
<AxisNum>6</AxisNum>
|
||||
<AxisName>WS-R</AxisName>
|
||||
<Direction>X</Direction>
|
||||
<GoogalCore>0</GoogalCore>
|
||||
<GoogalAxisNum>0</GoogalAxisNum>
|
||||
<GoolgalPosErr>0</GoolgalPosErr>
|
||||
<HomeDir>0</HomeDir>
|
||||
<EscapeStep>0</EscapeStep>
|
||||
<HomeMode>HOME_MODE_ERROR</HomeMode>
|
||||
<HomeCheck>false</HomeCheck>
|
||||
<MaxCheckPos>0.001</MaxCheckPos>
|
||||
</AxisCardParaPO>
|
||||
<AxisCardParaPO>
|
||||
<AlarmOffset>0</AlarmOffset>
|
||||
<CategoryName>SZ</CategoryName>
|
||||
<ID>ce1f8f65-3409-4124-9c9a-ba750c848e36</ID>
|
||||
<EnableLog>false</EnableLog>
|
||||
<ConfigPath>AxisCardParaPO.xml</ConfigPath>
|
||||
<AxisCardId>0</AxisCardId>
|
||||
<AxisCardName>AcsCard</AxisCardName>
|
||||
<AxisCardNum>0</AxisCardNum>
|
||||
<AxisNum>8</AxisNum>
|
||||
<AxisName>SZ</AxisName>
|
||||
<Direction>X</Direction>
|
||||
<GoogalCore>0</GoogalCore>
|
||||
<GoogalAxisNum>0</GoogalAxisNum>
|
||||
<GoolgalPosErr>0</GoolgalPosErr>
|
||||
<HomeDir>0</HomeDir>
|
||||
<EscapeStep>0</EscapeStep>
|
||||
<HomeMode>HOME_MODE_ERROR</HomeMode>
|
||||
<HomeCheck>false</HomeCheck>
|
||||
<MaxCheckPos>0.001</MaxCheckPos>
|
||||
</AxisCardParaPO>
|
||||
<AxisCardParaPO>
|
||||
<AlarmOffset>0</AlarmOffset>
|
||||
<CategoryName>Stage-Y3</CategoryName>
|
||||
<ID>05dfa6d1-401b-4a55-808b-5af2efeb358c</ID>
|
||||
<EnableLog>false</EnableLog>
|
||||
<ConfigPath>AxisCardParaPO.xml</ConfigPath>
|
||||
<AxisCardId>0</AxisCardId>
|
||||
<AxisCardName>AcsCard</AxisCardName>
|
||||
<AxisCardNum>0</AxisCardNum>
|
||||
<AxisNum>7</AxisNum>
|
||||
<AxisName>Stage-Y3</AxisName>
|
||||
<Direction>X</Direction>
|
||||
<GoogalCore>0</GoogalCore>
|
||||
<GoogalAxisNum>0</GoogalAxisNum>
|
||||
<GoolgalPosErr>0</GoolgalPosErr>
|
||||
<HomeDir>0</HomeDir>
|
||||
<EscapeStep>0</EscapeStep>
|
||||
<HomeMode>HOME_MODE_ERROR</HomeMode>
|
||||
<HomeCheck>false</HomeCheck>
|
||||
<MaxCheckPos>0.001</MaxCheckPos>
|
||||
</AxisCardParaPO>
|
||||
</ListAxisCardParaPO>
|
||||
<Version>1</Version>
|
||||
<Core>0</Core>
|
||||
<CrossCompensate>0</CrossCompensate>
|
||||
<IsServoSeparate>false</IsServoSeparate>
|
||||
</PersistenceObject>
|
||||
<PersistenceObject xsi:type="AxisCardPO">
|
||||
<AlarmOffset>0</AlarmOffset>
|
||||
<CategoryName>Plc</CategoryName>
|
||||
<ID>80a2e320-d4da-46a6-9f35-0a6d0996ea22</ID>
|
||||
<EnableLog>false</EnableLog>
|
||||
<ConfigPath>AxisCardPO.xml</ConfigPath>
|
||||
<AxisCardType>DEMO</AxisCardType>
|
||||
<AxisCardNum>0</AxisCardNum>
|
||||
<PortNo>0</PortNo>
|
||||
<ListAxisCardParaPO>
|
||||
<AxisCardParaPO>
|
||||
<AlarmOffset>0</AlarmOffset>
|
||||
<CategoryName>PHS-Z1</CategoryName>
|
||||
<ID>471e0395-0918-4e0b-b9cb-d0727281ef6c</ID>
|
||||
<EnableLog>false</EnableLog>
|
||||
<ConfigPath>AxisCardParaPO.xml</ConfigPath>
|
||||
<AxisCardId>0</AxisCardId>
|
||||
<AxisCardName>Plc</AxisCardName>
|
||||
<AxisCardNum>0</AxisCardNum>
|
||||
<AxisNum>0</AxisNum>
|
||||
<AxisName>PHS-Z1</AxisName>
|
||||
<Direction>Z</Direction>
|
||||
<GoogalCore>0</GoogalCore>
|
||||
<GoogalAxisNum>0</GoogalAxisNum>
|
||||
<GoolgalPosErr>0</GoolgalPosErr>
|
||||
<HomeDir>0</HomeDir>
|
||||
<EscapeStep>0</EscapeStep>
|
||||
<HomeMode>HOME_MODE_ERROR</HomeMode>
|
||||
<HomeCheck>false</HomeCheck>
|
||||
<MaxCheckPos>0.001</MaxCheckPos>
|
||||
</AxisCardParaPO>
|
||||
<AxisCardParaPO>
|
||||
<AlarmOffset>0</AlarmOffset>
|
||||
<CategoryName>PHS-Z3</CategoryName>
|
||||
<ID>5dd115ab-09a4-4bbb-9fdf-e9b76cc5e88e</ID>
|
||||
<EnableLog>false</EnableLog>
|
||||
<ConfigPath>AxisCardParaPO.xml</ConfigPath>
|
||||
<AxisCardId>0</AxisCardId>
|
||||
<AxisCardName>Plc</AxisCardName>
|
||||
<AxisCardNum>0</AxisCardNum>
|
||||
<AxisNum>1</AxisNum>
|
||||
<AxisName>PHS-Z3</AxisName>
|
||||
<Direction>Z</Direction>
|
||||
<GoogalCore>0</GoogalCore>
|
||||
<GoogalAxisNum>0</GoogalAxisNum>
|
||||
<GoolgalPosErr>0</GoolgalPosErr>
|
||||
<HomeDir>0</HomeDir>
|
||||
<EscapeStep>0</EscapeStep>
|
||||
<HomeMode>HOME_MODE_ERROR</HomeMode>
|
||||
<HomeCheck>false</HomeCheck>
|
||||
<MaxCheckPos>0.001</MaxCheckPos>
|
||||
</AxisCardParaPO>
|
||||
<AxisCardParaPO>
|
||||
<AlarmOffset>0</AlarmOffset>
|
||||
<CategoryName>PHS-Z4</CategoryName>
|
||||
<ID>e359bc21-c1e8-4e06-acdb-1df94ee7931b</ID>
|
||||
<EnableLog>false</EnableLog>
|
||||
<ConfigPath>AxisCardParaPO.xml</ConfigPath>
|
||||
<AxisCardId>0</AxisCardId>
|
||||
<AxisCardName>Plc</AxisCardName>
|
||||
<AxisCardNum>0</AxisCardNum>
|
||||
<AxisNum>10</AxisNum>
|
||||
<AxisName>PHS-Z4</AxisName>
|
||||
<Direction>X</Direction>
|
||||
<GoogalCore>0</GoogalCore>
|
||||
<GoogalAxisNum>0</GoogalAxisNum>
|
||||
<GoolgalPosErr>0</GoolgalPosErr>
|
||||
<HomeDir>0</HomeDir>
|
||||
<EscapeStep>0</EscapeStep>
|
||||
<HomeMode>HOME_MODE_ERROR</HomeMode>
|
||||
<HomeCheck>false</HomeCheck>
|
||||
<MaxCheckPos>0.001</MaxCheckPos>
|
||||
</AxisCardParaPO>
|
||||
<AxisCardParaPO>
|
||||
<AlarmOffset>0</AlarmOffset>
|
||||
<CategoryName>PHS-Z5</CategoryName>
|
||||
<ID>9d948211-59ae-498c-b124-531a69855752</ID>
|
||||
<EnableLog>false</EnableLog>
|
||||
<ConfigPath>AxisCardParaPO.xml</ConfigPath>
|
||||
<AxisCardId>0</AxisCardId>
|
||||
<AxisCardName>Plc</AxisCardName>
|
||||
<AxisCardNum>0</AxisCardNum>
|
||||
<AxisNum>2</AxisNum>
|
||||
<AxisName>PHS-Z5</AxisName>
|
||||
<Direction>X</Direction>
|
||||
<GoogalCore>0</GoogalCore>
|
||||
<GoogalAxisNum>0</GoogalAxisNum>
|
||||
<GoolgalPosErr>0</GoolgalPosErr>
|
||||
<HomeDir>0</HomeDir>
|
||||
<EscapeStep>0</EscapeStep>
|
||||
<HomeMode>HOME_MODE_ERROR</HomeMode>
|
||||
<HomeCheck>false</HomeCheck>
|
||||
<MaxCheckPos>0.001</MaxCheckPos>
|
||||
</AxisCardParaPO>
|
||||
<AxisCardParaPO>
|
||||
<AlarmOffset>0</AlarmOffset>
|
||||
<CategoryName>PHS-Z6</CategoryName>
|
||||
<ID>477c569a-e460-4c45-917f-a0744ebed5ec</ID>
|
||||
<EnableLog>false</EnableLog>
|
||||
<ConfigPath>AxisCardParaPO.xml</ConfigPath>
|
||||
<AxisCardId>0</AxisCardId>
|
||||
<AxisCardName>Plc</AxisCardName>
|
||||
<AxisCardNum>0</AxisCardNum>
|
||||
<AxisNum>11</AxisNum>
|
||||
<AxisName>PHS-Z6</AxisName>
|
||||
<Direction>X</Direction>
|
||||
<GoogalCore>0</GoogalCore>
|
||||
<GoogalAxisNum>0</GoogalAxisNum>
|
||||
<GoolgalPosErr>0</GoolgalPosErr>
|
||||
<HomeDir>0</HomeDir>
|
||||
<EscapeStep>0</EscapeStep>
|
||||
<HomeMode>HOME_MODE_ERROR</HomeMode>
|
||||
<HomeCheck>false</HomeCheck>
|
||||
<MaxCheckPos>0.001</MaxCheckPos>
|
||||
</AxisCardParaPO>
|
||||
<AxisCardParaPO>
|
||||
<AlarmOffset>0</AlarmOffset>
|
||||
<CategoryName>Stage-Z7</CategoryName>
|
||||
<ID>f761791c-8fb4-4a5b-8fef-0380e996e81f</ID>
|
||||
<EnableLog>false</EnableLog>
|
||||
<ConfigPath>AxisCardParaPO.xml</ConfigPath>
|
||||
<AxisCardId>0</AxisCardId>
|
||||
<AxisCardName>Plc</AxisCardName>
|
||||
<AxisCardNum>0</AxisCardNum>
|
||||
<AxisNum>7</AxisNum>
|
||||
<AxisName>Stage-Z7</AxisName>
|
||||
<Direction>X</Direction>
|
||||
<GoogalCore>0</GoogalCore>
|
||||
<GoogalAxisNum>0</GoogalAxisNum>
|
||||
<GoolgalPosErr>0</GoolgalPosErr>
|
||||
<HomeDir>0</HomeDir>
|
||||
<EscapeStep>0</EscapeStep>
|
||||
<HomeMode>HOME_MODE_ERROR</HomeMode>
|
||||
<HomeCheck>false</HomeCheck>
|
||||
<MaxCheckPos>0.001</MaxCheckPos>
|
||||
</AxisCardParaPO>
|
||||
<AxisCardParaPO>
|
||||
<AlarmOffset>0</AlarmOffset>
|
||||
<CategoryName>Stage-Z8</CategoryName>
|
||||
<ID>28a1caa3-01bc-48ed-8551-68829b280a6f</ID>
|
||||
<EnableLog>false</EnableLog>
|
||||
<ConfigPath>AxisCardParaPO.xml</ConfigPath>
|
||||
<AxisCardId>0</AxisCardId>
|
||||
<AxisCardName>Plc</AxisCardName>
|
||||
<AxisCardNum>0</AxisCardNum>
|
||||
<AxisNum>8</AxisNum>
|
||||
<AxisName>Stage-Z8</AxisName>
|
||||
<Direction>X</Direction>
|
||||
<GoogalCore>0</GoogalCore>
|
||||
<GoogalAxisNum>0</GoogalAxisNum>
|
||||
<GoolgalPosErr>0</GoolgalPosErr>
|
||||
<HomeDir>0</HomeDir>
|
||||
<EscapeStep>0</EscapeStep>
|
||||
<HomeMode>HOME_MODE_ERROR</HomeMode>
|
||||
<HomeCheck>false</HomeCheck>
|
||||
<MaxCheckPos>0.001</MaxCheckPos>
|
||||
</AxisCardParaPO>
|
||||
<AxisCardParaPO>
|
||||
<AlarmOffset>0</AlarmOffset>
|
||||
<CategoryName>Stage-Z9</CategoryName>
|
||||
<ID>71c8587a-1e85-4fa4-8809-14f00111a230</ID>
|
||||
<EnableLog>false</EnableLog>
|
||||
<ConfigPath>AxisCardParaPO.xml</ConfigPath>
|
||||
<AxisCardId>0</AxisCardId>
|
||||
<AxisCardName>Plc</AxisCardName>
|
||||
<AxisCardNum>0</AxisCardNum>
|
||||
<AxisNum>9</AxisNum>
|
||||
<AxisName>Stage-Z9</AxisName>
|
||||
<Direction>X</Direction>
|
||||
<GoogalCore>0</GoogalCore>
|
||||
<GoogalAxisNum>0</GoogalAxisNum>
|
||||
<GoolgalPosErr>0</GoolgalPosErr>
|
||||
<HomeDir>0</HomeDir>
|
||||
<EscapeStep>0</EscapeStep>
|
||||
<HomeMode>HOME_MODE_ERROR</HomeMode>
|
||||
<HomeCheck>false</HomeCheck>
|
||||
<MaxCheckPos>0.001</MaxCheckPos>
|
||||
</AxisCardParaPO>
|
||||
<AxisCardParaPO>
|
||||
<AlarmOffset>0</AlarmOffset>
|
||||
<CategoryName>Stage-Z10</CategoryName>
|
||||
<ID>fc66c8d2-c35f-46b5-9c14-f3a017311e86</ID>
|
||||
<EnableLog>false</EnableLog>
|
||||
<ConfigPath>AxisCardParaPO.xml</ConfigPath>
|
||||
<AxisCardId>0</AxisCardId>
|
||||
<AxisCardName>Plc</AxisCardName>
|
||||
<AxisCardNum>0</AxisCardNum>
|
||||
<AxisNum>14</AxisNum>
|
||||
<AxisName>Stage-Z10</AxisName>
|
||||
<Direction>X</Direction>
|
||||
<GoogalCore>0</GoogalCore>
|
||||
<GoogalAxisNum>0</GoogalAxisNum>
|
||||
<GoolgalPosErr>0</GoolgalPosErr>
|
||||
<HomeDir>0</HomeDir>
|
||||
<EscapeStep>0</EscapeStep>
|
||||
<HomeMode>HOME_MODE_ERROR</HomeMode>
|
||||
<HomeCheck>false</HomeCheck>
|
||||
<MaxCheckPos>0.001</MaxCheckPos>
|
||||
</AxisCardParaPO>
|
||||
<AxisCardParaPO>
|
||||
<AlarmOffset>0</AlarmOffset>
|
||||
<CategoryName>Stage-CV-Y4</CategoryName>
|
||||
<ID>6ebf862a-c91e-4bb2-a5b7-e67f307333b4</ID>
|
||||
<EnableLog>false</EnableLog>
|
||||
<ConfigPath>AxisCardParaPO.xml</ConfigPath>
|
||||
<AxisCardId>0</AxisCardId>
|
||||
<AxisCardName>Plc</AxisCardName>
|
||||
<AxisCardNum>0</AxisCardNum>
|
||||
<AxisNum>15</AxisNum>
|
||||
<AxisName>Stage-CV-Y4</AxisName>
|
||||
<Direction>X</Direction>
|
||||
<GoogalCore>0</GoogalCore>
|
||||
<GoogalAxisNum>0</GoogalAxisNum>
|
||||
<GoolgalPosErr>0</GoolgalPosErr>
|
||||
<HomeDir>0</HomeDir>
|
||||
<EscapeStep>0</EscapeStep>
|
||||
<HomeMode>HOME_MODE_ERROR</HomeMode>
|
||||
<HomeCheck>false</HomeCheck>
|
||||
<MaxCheckPos>0.001</MaxCheckPos>
|
||||
</AxisCardParaPO>
|
||||
<AxisCardParaPO>
|
||||
<AlarmOffset>0</AlarmOffset>
|
||||
<CategoryName>Stage-CV-Y5</CategoryName>
|
||||
<ID>e1cf2e06-fe51-4115-8ad2-2a0b3dc53c00</ID>
|
||||
<EnableLog>false</EnableLog>
|
||||
<ConfigPath>AxisCardParaPO.xml</ConfigPath>
|
||||
<AxisCardId>0</AxisCardId>
|
||||
<AxisCardName>Plc</AxisCardName>
|
||||
<AxisCardNum>0</AxisCardNum>
|
||||
<AxisNum>16</AxisNum>
|
||||
<AxisName>Stage-CV-Y5</AxisName>
|
||||
<Direction>X</Direction>
|
||||
<GoogalCore>0</GoogalCore>
|
||||
<GoogalAxisNum>0</GoogalAxisNum>
|
||||
<GoolgalPosErr>0</GoolgalPosErr>
|
||||
<HomeDir>0</HomeDir>
|
||||
<EscapeStep>0</EscapeStep>
|
||||
<HomeMode>HOME_MODE_ERROR</HomeMode>
|
||||
<HomeCheck>false</HomeCheck>
|
||||
<MaxCheckPos>0.001</MaxCheckPos>
|
||||
</AxisCardParaPO>
|
||||
<AxisCardParaPO>
|
||||
<AlarmOffset>0</AlarmOffset>
|
||||
<CategoryName>WEU-Z11</CategoryName>
|
||||
<ID>a765e366-03a3-451f-ab44-1e6129a6ac61</ID>
|
||||
<EnableLog>false</EnableLog>
|
||||
<ConfigPath>AxisCardParaPO.xml</ConfigPath>
|
||||
<AxisCardId>0</AxisCardId>
|
||||
<AxisCardName>Plc</AxisCardName>
|
||||
<AxisCardNum>0</AxisCardNum>
|
||||
<AxisNum>3</AxisNum>
|
||||
<AxisName>WEU-Z11</AxisName>
|
||||
<Direction>X</Direction>
|
||||
<GoogalCore>0</GoogalCore>
|
||||
<GoogalAxisNum>0</GoogalAxisNum>
|
||||
<GoolgalPosErr>0</GoolgalPosErr>
|
||||
<HomeDir>0</HomeDir>
|
||||
<EscapeStep>0</EscapeStep>
|
||||
<HomeMode>HOME_MODE_ERROR</HomeMode>
|
||||
<HomeCheck>false</HomeCheck>
|
||||
<MaxCheckPos>0.001</MaxCheckPos>
|
||||
</AxisCardParaPO>
|
||||
<AxisCardParaPO>
|
||||
<AlarmOffset>0</AlarmOffset>
|
||||
<CategoryName>WEU-Z12</CategoryName>
|
||||
<ID>a4c43082-6841-45b4-83f2-b89a952a6547</ID>
|
||||
<EnableLog>false</EnableLog>
|
||||
<ConfigPath>AxisCardParaPO.xml</ConfigPath>
|
||||
<AxisCardId>0</AxisCardId>
|
||||
<AxisCardName>Plc</AxisCardName>
|
||||
<AxisCardNum>0</AxisCardNum>
|
||||
<AxisNum>4</AxisNum>
|
||||
<AxisName>WEU-Z12</AxisName>
|
||||
<Direction>X</Direction>
|
||||
<GoogalCore>0</GoogalCore>
|
||||
<GoogalAxisNum>0</GoogalAxisNum>
|
||||
<GoolgalPosErr>0</GoolgalPosErr>
|
||||
<HomeDir>0</HomeDir>
|
||||
<EscapeStep>0</EscapeStep>
|
||||
<HomeMode>HOME_MODE_ERROR</HomeMode>
|
||||
<HomeCheck>false</HomeCheck>
|
||||
<MaxCheckPos>0.001</MaxCheckPos>
|
||||
</AxisCardParaPO>
|
||||
<AxisCardParaPO>
|
||||
<AlarmOffset>0</AlarmOffset>
|
||||
<CategoryName>WEU-Y6</CategoryName>
|
||||
<ID>670409e3-1e19-45c8-94b8-1f3fb1905dc2</ID>
|
||||
<EnableLog>false</EnableLog>
|
||||
<ConfigPath>AxisCardParaPO.xml</ConfigPath>
|
||||
<AxisCardId>0</AxisCardId>
|
||||
<AxisCardName>Plc</AxisCardName>
|
||||
<AxisCardNum>0</AxisCardNum>
|
||||
<AxisNum>5</AxisNum>
|
||||
<AxisName>WEU-Y6</AxisName>
|
||||
<Direction>X</Direction>
|
||||
<GoogalCore>0</GoogalCore>
|
||||
<GoogalAxisNum>0</GoogalAxisNum>
|
||||
<GoolgalPosErr>0</GoolgalPosErr>
|
||||
<HomeDir>0</HomeDir>
|
||||
<EscapeStep>0</EscapeStep>
|
||||
<HomeMode>HOME_MODE_ERROR</HomeMode>
|
||||
<HomeCheck>false</HomeCheck>
|
||||
<MaxCheckPos>0.001</MaxCheckPos>
|
||||
</AxisCardParaPO>
|
||||
<AxisCardParaPO>
|
||||
<AlarmOffset>0</AlarmOffset>
|
||||
<CategoryName>CV-Z13</CategoryName>
|
||||
<ID>eb009565-40bf-4923-9b9b-fdf483dc1532</ID>
|
||||
<EnableLog>false</EnableLog>
|
||||
<ConfigPath>AxisCardParaPO.xml</ConfigPath>
|
||||
<AxisCardId>0</AxisCardId>
|
||||
<AxisCardName>Plc</AxisCardName>
|
||||
<AxisCardNum>0</AxisCardNum>
|
||||
<AxisNum>6</AxisNum>
|
||||
<AxisName>CV-Z13</AxisName>
|
||||
<Direction>X</Direction>
|
||||
<GoogalCore>0</GoogalCore>
|
||||
<GoogalAxisNum>0</GoogalAxisNum>
|
||||
<GoolgalPosErr>0</GoolgalPosErr>
|
||||
<HomeDir>0</HomeDir>
|
||||
<EscapeStep>0</EscapeStep>
|
||||
<HomeMode>HOME_MODE_ERROR</HomeMode>
|
||||
<HomeCheck>false</HomeCheck>
|
||||
<MaxCheckPos>0.001</MaxCheckPos>
|
||||
</AxisCardParaPO>
|
||||
<AxisCardParaPO>
|
||||
<AlarmOffset>0</AlarmOffset>
|
||||
<CategoryName>CV-Y7</CategoryName>
|
||||
<ID>d75ee50a-ba99-4ec1-bb36-6e65cbd84180</ID>
|
||||
<EnableLog>false</EnableLog>
|
||||
<ConfigPath>AxisCardParaPO.xml</ConfigPath>
|
||||
<AxisCardId>0</AxisCardId>
|
||||
<AxisCardName>Plc</AxisCardName>
|
||||
<AxisCardNum>0</AxisCardNum>
|
||||
<AxisNum>18</AxisNum>
|
||||
<AxisName>CV-Y7</AxisName>
|
||||
<Direction>X</Direction>
|
||||
<GoogalCore>0</GoogalCore>
|
||||
<GoogalAxisNum>0</GoogalAxisNum>
|
||||
<GoolgalPosErr>0</GoolgalPosErr>
|
||||
<HomeDir>0</HomeDir>
|
||||
<EscapeStep>0</EscapeStep>
|
||||
<HomeMode>HOME_MODE_ERROR</HomeMode>
|
||||
<HomeCheck>false</HomeCheck>
|
||||
<MaxCheckPos>0.001</MaxCheckPos>
|
||||
</AxisCardParaPO>
|
||||
<AxisCardParaPO>
|
||||
<AlarmOffset>0</AlarmOffset>
|
||||
<CategoryName>CV-Y8</CategoryName>
|
||||
<ID>8845c4e8-4d09-4f0a-b073-1b29e1ca59e6</ID>
|
||||
<EnableLog>false</EnableLog>
|
||||
<ConfigPath>AxisCardParaPO.xml</ConfigPath>
|
||||
<AxisCardId>0</AxisCardId>
|
||||
<AxisCardName>Plc</AxisCardName>
|
||||
<AxisCardNum>0</AxisCardNum>
|
||||
<AxisNum>19</AxisNum>
|
||||
<AxisName>CV-Y8</AxisName>
|
||||
<Direction>X</Direction>
|
||||
<GoogalCore>0</GoogalCore>
|
||||
<GoogalAxisNum>0</GoogalAxisNum>
|
||||
<GoolgalPosErr>0</GoolgalPosErr>
|
||||
<HomeDir>0</HomeDir>
|
||||
<EscapeStep>0</EscapeStep>
|
||||
<HomeMode>HOME_MODE_ERROR</HomeMode>
|
||||
<HomeCheck>false</HomeCheck>
|
||||
<MaxCheckPos>0.001</MaxCheckPos>
|
||||
</AxisCardParaPO>
|
||||
<AxisCardParaPO>
|
||||
<AlarmOffset>0</AlarmOffset>
|
||||
<CategoryName>CV-Y9</CategoryName>
|
||||
<ID>4970be79-b46a-4004-84bf-82e922fb5cb8</ID>
|
||||
<EnableLog>false</EnableLog>
|
||||
<ConfigPath>AxisCardParaPO.xml</ConfigPath>
|
||||
<AxisCardId>0</AxisCardId>
|
||||
<AxisCardName>Plc</AxisCardName>
|
||||
<AxisCardNum>0</AxisCardNum>
|
||||
<AxisNum>20</AxisNum>
|
||||
<AxisName>CV-Y9</AxisName>
|
||||
<Direction>X</Direction>
|
||||
<GoogalCore>0</GoogalCore>
|
||||
<GoogalAxisNum>0</GoogalAxisNum>
|
||||
<GoolgalPosErr>0</GoolgalPosErr>
|
||||
<HomeDir>0</HomeDir>
|
||||
<EscapeStep>0</EscapeStep>
|
||||
<HomeMode>HOME_MODE_ERROR</HomeMode>
|
||||
<HomeCheck>false</HomeCheck>
|
||||
<MaxCheckPos>0.001</MaxCheckPos>
|
||||
</AxisCardParaPO>
|
||||
<AxisCardParaPO>
|
||||
<AlarmOffset>0</AlarmOffset>
|
||||
<CategoryName>CV-Y10</CategoryName>
|
||||
<ID>36583278-40bd-48ad-a749-02b4e58dcbca</ID>
|
||||
<EnableLog>false</EnableLog>
|
||||
<ConfigPath>AxisCardParaPO.xml</ConfigPath>
|
||||
<AxisCardId>0</AxisCardId>
|
||||
<AxisCardName>Plc</AxisCardName>
|
||||
<AxisCardNum>0</AxisCardNum>
|
||||
<AxisNum>21</AxisNum>
|
||||
<AxisName>CV-Y10</AxisName>
|
||||
<Direction>X</Direction>
|
||||
<GoogalCore>0</GoogalCore>
|
||||
<GoogalAxisNum>0</GoogalAxisNum>
|
||||
<GoolgalPosErr>0</GoolgalPosErr>
|
||||
<HomeDir>0</HomeDir>
|
||||
<EscapeStep>0</EscapeStep>
|
||||
<HomeMode>HOME_MODE_ERROR</HomeMode>
|
||||
<HomeCheck>false</HomeCheck>
|
||||
<MaxCheckPos>0.001</MaxCheckPos>
|
||||
</AxisCardParaPO>
|
||||
</ListAxisCardParaPO>
|
||||
<Version>1</Version>
|
||||
<Core>0</Core>
|
||||
<CrossCompensate>0</CrossCompensate>
|
||||
<IsServoSeparate>false</IsServoSeparate>
|
||||
</PersistenceObject>
|
||||
</ArrayOfPersistenceObject>
|
||||
@@ -0,0 +1,9 @@
|
||||
# 气缸定义表
|
||||
# 列顺序:Name,Module,ControlType,ExtendOutputIds,RetractOutputIds,ExtendedFeedbackIds,RetractedFeedbackIds,Description
|
||||
# ControlType: SingleOutput / DualOutput / MultiOutput
|
||||
# ExtendOutputIds / RetractOutputIds / ExtendedFeedbackIds / RetractedFeedbackIds 支持填写多个 IO 引用,使用分号分隔
|
||||
# IO 引用优先使用 Configuration\DeviceIoPoints.csv 中的 Name;若 Id 在全表唯一,也兼容旧 Id 写法
|
||||
Name,Module,ControlType,ExtendOutputIds,RetractOutputIds,ExtendedFeedbackIds,RetractedFeedbackIds,Description
|
||||
WS θ夹紧气缸,WS,SingleOutput,PG.WS.ThetaClampCylAct,,PG.WS.ThetaClampCyl1WorkPos;PG.WS.ThetaClampCyl2WorkPos;PG.WS.ThetaClampCyl3WorkPos;PG.WS.ThetaClampCyl4WorkPos,PG.WS.ThetaClampCyl1HomePos;PG.WS.ThetaClampCyl2HomePos;PG.WS.ThetaClampCyl3HomePos;PG.WS.ThetaClampCyl4HomePos,WS θ 夹紧气缸总动作输出,对应 4 组伸出/缩回反馈
|
||||
WS θ刹车压紧气缸,WS,SingleOutput,PG.WS.ThetaBrakePressCylAct,,,,当前 DeviceIoPoints.csv 未配置到位反馈
|
||||
Stage 顶升同步气缸,Stage,MultiOutput,PG.Stage.LifterCyl1Act;PG.Stage.LifterCyl2Act,,PG.Stage.LifterCyl1WorkPos;PG.Stage.LifterCyl2WorkPos,PG.Stage.LifterCyl1HomePos;PG.Stage.LifterCyl2HomePos,Stage 顶升气缸1和2同步动作,统一伸出/缩回
|
||||
|
@@ -0,0 +1,97 @@
|
||||
# Device IO 定义表
|
||||
# 列顺序:Id Module Name Type Card StationNo LineNo Enabled DefaultValue IsInverse Description
|
||||
# Module: 业务模块名(如 SubstrateLoad/ChipLoad/SubstrateOut/ChipUnload)
|
||||
# Type: Input/Output (也支持 IN/OUT/DI/DO)
|
||||
# Card: Td/Acs
|
||||
# StationNo: 台达站号
|
||||
# LineNo: 实际接线线标/号码管标识
|
||||
# Enabled: 1/0 或 true/false
|
||||
# DefaultValue: 当 IO 未启用或无法读取时使用的默认状态,1/0 或 true/false
|
||||
Id,Module,Name,Type,Card,StationNo,LineNo,Enabled,DefaultValue,IsInverse,Description
|
||||
0,WZ,PG.WZ.StartButton,Input,Td,1,X00100,1,1,0,WZ 启动按钮
|
||||
1,WZ,PG.WZ.StopButton,Input,Td,1,X00101,1,1,0,WZ 停止按钮
|
||||
2,WZ,PG.WZ.ResetButton,Input,Td,1,X00102,1,1,0,WZ 复位按钮
|
||||
3,WZ,PG.WZ.EmergencyStopButton,Input,Td,1,X00103,1,1,0,WZ 急停按钮
|
||||
4,WZ,PG.WZ.BlueButton,Input,Td,1,X00104,1,1,0,WZ 蓝色按钮(预留)
|
||||
5,Stage,PG.Stage.ToolSetterSignal,Input,Td,1,X00105,1,1,0,Stage 对刀信号
|
||||
6,Stage,PG.Stage.SubstrateInPlace,Input,Td,1,X00106,1,1,0,Stage 基板到位感应
|
||||
7,Stage,PG.Stage.LifterCyl1WorkPos,Input,Td,1,X00107,1,1,0,Stage 顶升气缸1动点
|
||||
8,Stage,PG.Stage.LifterCyl1HomePos,Input,Td,1,X00108,1,1,0,Stage 顶升气缸1原点
|
||||
9,Stage,PG.Stage.LifterCyl2WorkPos,Input,Td,1,X00109,1,1,0,Stage 顶升气缸2动点
|
||||
10,Stage,PG.Stage.LifterCyl2HomePos,Input,Td,1,X00110,1,1,0,Stage 顶升气缸2原点
|
||||
11,WS,PG.WS.ThetaClampCyl1WorkPos,Input,Td,1,X00111,1,1,0,WS θ夹紧气缸1动点
|
||||
12,WS,PG.WS.ThetaClampCyl1HomePos,Input,Td,1,X00112,1,1,0,WS θ夹紧气缸1原点
|
||||
13,WS,PG.WS.ThetaClampCyl2WorkPos,Input,Td,1,X00113,1,1,0,WS θ夹紧气缸2动点
|
||||
14,WS,PG.WS.ThetaClampCyl2HomePos,Input,Td,1,X00114,1,1,0,WS θ夹紧气缸2原点
|
||||
15,WS,PG.WS.ThetaClampCyl3WorkPos,Input,Td,1,X00115,1,1,0,WS θ夹紧气缸3动点
|
||||
0,WS,PG.WS.ThetaClampCyl3HomePos,Input,Td,2,X00200,1,1,0,WS θ夹紧气缸3原点
|
||||
1,WS,PG.WS.ThetaClampCyl4WorkPos,Input,Td,2,X00201,1,1,0,WS θ夹紧气缸4动点
|
||||
2,WS,PG.WS.ThetaClampCyl4HomePos,Input,Td,2,X00202,1,1,0,WS θ夹紧气缸4原点
|
||||
3,WS,PG.WS.ThetaTrayPresentSensor1,Input,Td,2,X00203,1,1,0,WS θ料盘有无感应1
|
||||
4,WS,PG.WS.ThetaTrayPresentSensor2,Input,Td,2,X00204,1,1,0,WS θ料盘有无感应2
|
||||
5,WS,PG.WS.ThetaTrayPresentSensor3,Input,Td,2,X00205,1,1,0,WS θ料盘有无感应3
|
||||
6,WS,PG.WS.ThetaTrayPresentSensor4,Input,Td,2,X00206,1,1,0,WS θ料盘有无感应4
|
||||
7,WS,PG.WS.BondHead1InPlace,Input,Td,2,X00207,1,1,0,WS 刺晶头1在位
|
||||
8,WS,PG.WS.BondHead2InPlace,Input,Td,2,X00208,1,1,0,WS 刺晶头2在位
|
||||
9,WS,PG.WS.BondHead3InPlace,Input,Td,2,X00209,1,1,0,WS 刺晶头3在位
|
||||
10,WS,PG.WS.BondHead4InPlace,Input,Td,2,X00210,1,1,0,WS 刺晶头4在位
|
||||
11,WEU,PG.WEU.Z11MaterialSensor1,Input,Td,2,X00211,1,1,0,WEU Z11 有无料感应1
|
||||
12,WEU,PG.WEU.Z11MaterialSensor2,Input,Td,2,X00212,1,1,0,WEU Z11 有无料感应2
|
||||
13,WEU,PG.WEU.Z12MaterialSensor3,Input,Td,2,X00213,1,1,0,WEU Z12 有无料感应3
|
||||
14,WEU,PG.WEU.Z12MaterialSensor4,Input,Td,2,X00214,1,1,0,WEU Z12 有无料感应4
|
||||
0,CV,PG.CV.UpperInletSensor,Input,Td,3,X00300,1,1,0,CV 上层进料感应
|
||||
1,CV,PG.CV.UpperInPlaceSensor,Input,Td,3,X00301,1,1,0,CV 上层到位感应
|
||||
2,CV,PG.CV.LowerOutletSensor,Input,Td,3,X00302,1,1,0,CV 下层出料感应
|
||||
3,CV,PG.CV.LowerInPlaceSensor,Input,Td,3,X00303,1,1,0,CV 下层到位感应
|
||||
4,WZ,PG.WZ.SafetyDoor1Closed,Input,Td,3,X00304,1,1,0,WZ 安全门1关门检测
|
||||
5,WZ,PG.WZ.SafetyDoor2Closed,Input,Td,3,X00305,1,1,0,WZ 安全门2关门检测
|
||||
6,WZ,PG.WZ.SafetyDoor3Closed,Input,Td,3,X00306,1,1,0,WZ 安全门3关门检测
|
||||
7,WZ,PG.WZ.SafetyDoor4Closed,Input,Td,3,X00307,1,1,0,WZ 安全门4关门检测
|
||||
8,WZ,PG.WZ.SecurityDoorShield,Input,Td,3,X00308,1,1,0,WZ 安全门屏蔽
|
||||
10,General,PG.General.PhaseLossSensor,Input,Td,3,X00310,1,1,0,缺相检测
|
||||
11,General,PG.General.SafetyCircuitStatus1,Input,Td,3,X00311,1,1,0,安全回路状态1
|
||||
12,General,PG.General.SafetyCircuitStatus2,Input,Td,3,X00312,1,1,0,安全回路状态2
|
||||
13,CV,PG.CV.IonWindRodAlarmDetection,Input,Td,3,X00313,1,1,0,CV 离子风棒报警检测
|
||||
14,EFEM,PG.EFEM.IonWindRodAlarmDetection1,Input,Td,3,X00314,1,1,0,EFEM离子风棒报警检测1
|
||||
15,EFEM,PG.EFEM.IonWindRodAlarmDetection2,Input,Td,3,X00315,1,1,0,EFEM离子风棒报警检测2
|
||||
0,AxisZ,PG.AxisZ.Z1GuideRailBrake,Output,Td,4,Y00100,1,1,0,Z1轴导轨抱闸
|
||||
1,AxisZ,PG.AxisZ.Z3CameraAirCooling,Output,Td,4,Y00101,1,1,0,Z3相机气冷
|
||||
2,AxisZ,PG.AxisZ.Z5CameraAirCooling,Output,Td,4,Y00102,1,1,0,Z5相机气冷
|
||||
3,AxisZ,PG.AxisZ.Z10CameraAirCooling,Output,Td,4,Y00103,1,1,0,Z10相机气冷
|
||||
4,AxisZ,PG.AxisZ.Z2BondHeadAirCooling,Output,Td,4,Y00104,1,1,0,Z2刺晶头气冷
|
||||
5,CV,PG.CV.IonBarAct,Output,Td,4,Y00105,1,1,0,CV 离子风棒
|
||||
6,WEU,PG.WEU.IonBarAct1,Output,Td,4,Y00106,1,1,0,WEU离子风棒1
|
||||
7,WEU,PG.WEU.IonBarAct2,Output,Td,4,Y00107,1,1,0,WEU离子风棒2
|
||||
8,WS,PG.WS.ThetaClampCylAct,Output,Td,4,Y00108,1,1,0,WS θ 夹紧气缸动作
|
||||
9,WS,PG.WS.ThetaBrakePressCylAct,Output,Td,4,Y00109,1,1,0,WS θ 刹车压紧气缸动作
|
||||
10,Stage,PG.Stage.LifterCyl1Act,Output,Td,4,Y00110,1,1,0,Stage 顶升气缸1动作
|
||||
11,Stage,PG.Stage.LifterCyl2Act,Output,Td,4,Y00111,1,1,0,Stage 顶升气缸2动作
|
||||
0,WZ,PG.WZ.StartButtonLight,Output,Td,5,Y00200,1,1,0,WZ 启动按钮灯
|
||||
1,WZ,PG.WZ.StopButtonLight,Output,Td,5,Y00201,1,1,0,WZ 停止按钮灯
|
||||
2,WZ,PG.WZ.ResetButtonLight,Output,Td,5,Y00202,1,1,0,WZ 复位按钮灯
|
||||
3,WZ,PG.WZ.BlueButtonLight,Output,Td,5,Y00203,1,1,0,WZ 蓝色按钮灯
|
||||
4,WZ,PG.WZ.WorkLight1,Output,Td,5,Y00204,1,1,0,WZ 照明灯1
|
||||
6,EFEM,PG.EFEM.WorkLight1,Output,Td,5,Y00206,1,1,0,EFEM 照明灯1
|
||||
8,WZ,PG.WZ.StackLightRed,Output,Td,5,Y00208,1,1,0,WZ 四色灯-红
|
||||
9,WZ,PG.WZ.StackLightYellow,Output,Td,5,Y00209,1,1,0,WZ 四色灯-黄
|
||||
10,WZ,PG.WZ.StackLightGreen,Output,Td,5,Y00210,1,1,0,WZ 四色灯-绿
|
||||
11,WZ,PG.WZ.StackLightBlue,Output,Td,5,Y00211,1,1,0,WZ 四色灯-蓝
|
||||
12,WZ,PG.WZ.BuzzerAct,Output,Td,5,Y00212,1,1,0,WZ 蜂鸣器
|
||||
0,Stage,PG.Stage.BreakingTheVacuum1,Output,Td,6,Y00300,1,1,0,Stage 破真空1
|
||||
1,Stage,PG.Stage.BreakingTheVacuum2,Output,Td,6,Y00301,1,1,0,STAGE 破真空2
|
||||
2,Stage,PG.Stage.BreakingTheVacuum3,Output,Td,6,Y00302,1,1,0,STAGE 破真空3
|
||||
3,Stage,PG.Stage.BreakingTheVacuum4,Output,Td,6,Y00303,1,1,0,STAGE 破真空4
|
||||
4,WEU,PG.WEU.TrayBreakVacuum1,Output,Td,6,Y00304,1,1,0,WEU 料盘破真空1
|
||||
5,WEU,PG.WEU.TrayBreakVacuum2,Output,Td,6,Y00305,1,1,0,WEU 料盘破真空2
|
||||
6,AxisZ,PG.AxisZ.Z2BondHeadBreakVacuum,Output,Td,6,Y00306,1,1,0,PHS Z2 刺晶头破真空
|
||||
7,Stage,PG.Stage.Vacuum1,Output,Td,6,Y00307,1,1,0,STAGE 吸真空1
|
||||
8,Stage,PG.Stage.Vacuum2,Output,Td,6,Y00308,1,1,0,STAGE 吸真空2
|
||||
9,Stage,PG.Stage.Vacuum3,Output,Td,6,Y00309,1,1,0,STAGE 吸真空3
|
||||
10,Stage,PG.Stage.Vacuum4,Output,Td,6,Y00310,1,1,0,STAGE 吸真空4
|
||||
11,WEU,PG.WEU.TrayVacuum1,Output,Td,6,Y00311,1,1,0,WEU 料盘吸真空1
|
||||
12,WEU,PG.WEU.TrayVacuum2,Output,Td,6,Y00312,1,1,0,WEU 料盘吸真空2
|
||||
13,AxisZ,PG.AxisZ.Z2BondHeadVacuum,Output,Td,6,Y00313,1,1,0,PHS Z2 刺晶头吸真空
|
||||
1,WZ,PG.WZ.SafetyDoor1Open,Output,Td,7,Y00401,1,1,0,WZ 安全门1打开
|
||||
2,WZ,PG.WZ.SafetyDoor2Open,Output,Td,7,Y00402,1,1,0,WZ 安全门2打开
|
||||
3,WZ,PG.WZ.SafetyDoor3Open,Output,Td,7,Y00402,1,1,0,WZ 安全门3打开
|
||||
4,WZ,PG.WZ.SafetyDoor4Open,Output,Td,7,Y00403,1,1,0,WZ 安全门4打开
|
||||
|
@@ -0,0 +1,30 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Layout Version="1.0.0.1" WindowHeight="1024" WindowWidth="1280" MachineId="12345678901234567">
|
||||
<Header Title="PG-A1">
|
||||
<HeaderItem Id="HideEMO"/>
|
||||
<HeaderItem Id="HideCIMStatus"/>
|
||||
</Header>
|
||||
<Body>
|
||||
<StatusBar>
|
||||
<StatusLight Name="设备一" LangName="Device" Binding="Device"></StatusLight>
|
||||
</StatusBar>
|
||||
<Pages>
|
||||
<Page Name="主页" LangName="PageHome" Target="Home">
|
||||
</Page>
|
||||
<Page Name="配方" LangName="PageRecipe" Target="Recipe">
|
||||
|
||||
</Page>
|
||||
<Page Name="参数设置" LangName="PageSettings" Target="PageSettings" DisabledState="SemiAutomatic;Automatic" UserRightId="PageSettings">
|
||||
</Page>
|
||||
<Page Name="设备维护" LangName="MenuDeviceMaint" Target="MenuDeviceMaint" DisabledState="SemiAutomatic;Automatic" UserRightId="PageSettings">
|
||||
</Page>
|
||||
<Page Name="标定与校准" LangName="PageCalib" Target="PageCalib" DisabledState="SemiAutomatic;Automatic" UserRightId="PageCalib">
|
||||
</Page>
|
||||
<Page Name="半自动" LangName="ManualModeOperation" Target="ManualOperate">
|
||||
|
||||
</Page>
|
||||
</Pages>
|
||||
|
||||
</Body>
|
||||
<Footer Target="Footer"/>
|
||||
</Layout>
|
||||
@@ -0,0 +1,28 @@
|
||||
using MainShell.Common;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Globalization;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using System.Windows.Data;
|
||||
|
||||
namespace MainShell.Converter
|
||||
{
|
||||
public class BondingPathModeToBoolConverter : IValueConverter
|
||||
{
|
||||
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
|
||||
{
|
||||
BondingPathMode speedMode = (BondingPathMode)value;
|
||||
int mode = System.Convert.ToInt32(parameter.ToString());
|
||||
|
||||
return mode == (int)speedMode ? true : false;
|
||||
}
|
||||
|
||||
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
|
||||
{
|
||||
int mode = System.Convert.ToInt32(parameter.ToString());
|
||||
return (BondingPathMode)mode;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,28 @@
|
||||
using MainShell.Common;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Globalization;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using System.Windows.Data;
|
||||
|
||||
namespace MainShell.Converter
|
||||
{
|
||||
public class BondingRegionModeToBoolConverter : IValueConverter
|
||||
{
|
||||
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
|
||||
{
|
||||
BondingStagePathMode speedMode = (BondingStagePathMode)value;
|
||||
int mode = System.Convert.ToInt32(parameter.ToString());
|
||||
|
||||
return mode == (int)speedMode ? true : false;
|
||||
}
|
||||
|
||||
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
|
||||
{
|
||||
int mode = System.Convert.ToInt32(parameter.ToString());
|
||||
return (BondingStagePathMode)mode;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,28 @@
|
||||
using MainShell.Common;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Globalization;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using System.Windows.Data;
|
||||
|
||||
namespace MainShell.Converter
|
||||
{
|
||||
public class BondingWsPathModeToBoolConverter : IValueConverter
|
||||
{
|
||||
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
|
||||
{
|
||||
BondingWSPathMode speedMode = (BondingWSPathMode)value;
|
||||
int mode = System.Convert.ToInt32(parameter.ToString());
|
||||
|
||||
return mode == (int)speedMode ? true : false;
|
||||
}
|
||||
|
||||
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
|
||||
{
|
||||
int mode = System.Convert.ToInt32(parameter.ToString());
|
||||
return (BondingWSPathMode)mode;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,28 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Globalization;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using System.Windows.Data;
|
||||
|
||||
namespace MainShell.Converter
|
||||
{
|
||||
public class BoolToInversionConverter : IValueConverter
|
||||
{
|
||||
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
|
||||
{
|
||||
if (value != null)
|
||||
{
|
||||
return !System.Convert.ToBoolean(value);
|
||||
}
|
||||
else
|
||||
return false;
|
||||
}
|
||||
|
||||
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,94 @@
|
||||
using System;
|
||||
using System.Globalization;
|
||||
using System.Windows;
|
||||
using System.Windows.Data;
|
||||
|
||||
namespace MainShell.Converter
|
||||
{
|
||||
public class BoolToVisibleConverter : IValueConverter
|
||||
{
|
||||
// 将 bool (或可转换为 bool 的值) 转换为 Visibility
|
||||
// parameter 支持:
|
||||
// 包含 "invert" / "inverse" / "not" / "!" 的字符串 — 反转布尔值
|
||||
// 包含 "hidden" 的字符串 — 当为 false 时返回 Visibility.Hidden 而不是 Collapsed
|
||||
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
|
||||
{
|
||||
bool isVisible = false;
|
||||
|
||||
if (value is bool b)
|
||||
{
|
||||
isVisible = b;
|
||||
}
|
||||
else if (value is bool?)
|
||||
{
|
||||
isVisible = ((bool?)value) ?? false;
|
||||
}
|
||||
else if (value is string s)
|
||||
{
|
||||
bool.TryParse(s, out isVisible);
|
||||
}
|
||||
else if (value != null)
|
||||
{
|
||||
try
|
||||
{
|
||||
isVisible = System.Convert.ToBoolean(value);
|
||||
}
|
||||
catch
|
||||
{
|
||||
isVisible = false;
|
||||
}
|
||||
}
|
||||
|
||||
var paramString = parameter as string;
|
||||
bool invert = false;
|
||||
bool useHidden = false;
|
||||
if (!string.IsNullOrEmpty(paramString))
|
||||
{
|
||||
var p = paramString.ToLowerInvariant();
|
||||
if (p.Contains("invert") || p.Contains("inverse") || p.Contains("not") || p.Contains("!"))
|
||||
invert = true;
|
||||
if (p.Contains("hidden"))
|
||||
useHidden = true;
|
||||
}
|
||||
|
||||
if (invert)
|
||||
isVisible = !isVisible;
|
||||
|
||||
return isVisible ? Visibility.Visible : (useHidden ? Visibility.Hidden : Visibility.Collapsed);
|
||||
}
|
||||
|
||||
// 将 Visibility 转换回 bool
|
||||
// Visible => true;Hidden/Collapsed => false
|
||||
// 支持与 Convert 相同的 parameter 反转语义
|
||||
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
|
||||
{
|
||||
if (!(value is Visibility))
|
||||
return Binding.DoNothing;
|
||||
|
||||
var vis = (Visibility)value;
|
||||
bool result = vis == Visibility.Visible;
|
||||
|
||||
var paramString = parameter as string;
|
||||
if (!string.IsNullOrEmpty(paramString))
|
||||
{
|
||||
var p = paramString.ToLowerInvariant();
|
||||
if (p.Contains("invert") || p.Contains("inverse") || p.Contains("not") || p.Contains("!"))
|
||||
result = !result;
|
||||
}
|
||||
|
||||
if (targetType == typeof(bool) || targetType == typeof(object))
|
||||
return result;
|
||||
if (targetType == typeof(bool?))
|
||||
return (bool?)result;
|
||||
|
||||
try
|
||||
{
|
||||
return System.Convert.ChangeType(result, targetType);
|
||||
}
|
||||
catch
|
||||
{
|
||||
return result;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,31 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Globalization;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using System.Windows.Data;
|
||||
|
||||
namespace MainShell.Converter
|
||||
{
|
||||
public class DateTimeToStringConverter : IValueConverter
|
||||
{
|
||||
public string Format { get; set; } = "yyyy-MM-dd HH:mm:ss";
|
||||
|
||||
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
|
||||
{
|
||||
if (value == null) return string.Empty;
|
||||
if (!(value is DateTime dt)) return string.Empty;
|
||||
if (dt == DateTime.MinValue) return string.Empty;
|
||||
|
||||
// parameter 优先用于临时格式覆盖
|
||||
var fmt = parameter as string ?? Format;
|
||||
return dt.ToString(fmt, culture);
|
||||
}
|
||||
|
||||
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
|
||||
{
|
||||
throw new NotSupportedException();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,39 @@
|
||||
using System;
|
||||
using System.Linq;
|
||||
using System.Windows.Markup;
|
||||
|
||||
namespace MainShell.Converter
|
||||
{
|
||||
// XAML 中可直接写 {conv:EnumBindingSource {x:Type local:MyEnum}}
|
||||
public class EnumBindingSourceExtension : MarkupExtension
|
||||
{
|
||||
public Type EnumType { get; set; }
|
||||
public bool UseDescription { get; set; } = true;
|
||||
|
||||
public EnumBindingSourceExtension() { }
|
||||
|
||||
public EnumBindingSourceExtension(Type enumType)
|
||||
{
|
||||
EnumType = enumType;
|
||||
}
|
||||
|
||||
public override object ProvideValue(IServiceProvider serviceProvider)
|
||||
{
|
||||
if (EnumType == null || !EnumType.IsEnum) return null;
|
||||
|
||||
var values = Enum.GetValues(EnumType).Cast<Enum>();
|
||||
return values.Select(v => new EnumItem
|
||||
{
|
||||
Value = v,
|
||||
Description = UseDescription ? EnumHelper.GetEnumDescription(v) : v.ToString()
|
||||
}).ToList();
|
||||
}
|
||||
}
|
||||
|
||||
public class EnumItem
|
||||
{
|
||||
public Enum Value { get; set; }
|
||||
public string Description { get; set; }
|
||||
public int IntValue => Convert.ToInt32(Value);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,79 @@
|
||||
using MwFramework.Device;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel;
|
||||
using System.Globalization;
|
||||
using System.Linq;
|
||||
using System.Reflection;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using System.Windows.Data;
|
||||
|
||||
namespace MainShell.Converter
|
||||
{
|
||||
/// <summary>
|
||||
/// 获取枚举类型的Description描述信息
|
||||
/// </summary>
|
||||
public class EnumDescriptionConverter : IValueConverter
|
||||
{
|
||||
object IValueConverter.Convert(object value, Type targetType, object parameter, CultureInfo culture)
|
||||
{
|
||||
if (value.ToString() != "")
|
||||
{
|
||||
Enum myEnum = (Enum)value;
|
||||
string description = EnumHelper.GetEnumDescription(myEnum);
|
||||
return description;
|
||||
}
|
||||
else
|
||||
{
|
||||
return "";
|
||||
}
|
||||
}
|
||||
|
||||
object IValueConverter.ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
|
||||
{
|
||||
return string.Empty;
|
||||
}
|
||||
}
|
||||
|
||||
public class EnumToBool : IValueConverter
|
||||
{
|
||||
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
|
||||
{
|
||||
return (int)value == (int)parameter;
|
||||
}
|
||||
|
||||
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
|
||||
{
|
||||
if ((bool)value)
|
||||
{
|
||||
return parameter;
|
||||
}
|
||||
else
|
||||
{
|
||||
return Binding.DoNothing;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static class EnumHelper
|
||||
{
|
||||
public static string GetEnumDescription(Enum enumObj)
|
||||
{
|
||||
FieldInfo fieldInfo = enumObj.GetType().GetField(enumObj.ToString());
|
||||
var descriptionAttr = fieldInfo
|
||||
.GetCustomAttributes(false)
|
||||
.OfType<DescriptionAttribute>()
|
||||
.Cast<DescriptionAttribute>()
|
||||
.SingleOrDefault();
|
||||
if (descriptionAttr == null)
|
||||
{
|
||||
return enumObj.ToString();
|
||||
}
|
||||
else
|
||||
{
|
||||
return descriptionAttr.Description;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,23 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Globalization;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using System.Windows.Data;
|
||||
|
||||
namespace MainShell.Converter
|
||||
{
|
||||
public class ObjectToBoolConverter : IValueConverter
|
||||
{
|
||||
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
|
||||
{
|
||||
return value != null;
|
||||
}
|
||||
|
||||
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,30 @@
|
||||
using MainShell.Common;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Globalization;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using System.Windows.Controls;
|
||||
using System.Windows.Data;
|
||||
|
||||
namespace MainShell.Converter
|
||||
{
|
||||
public class RunningModeEnumToBoolConverter : IValueConverter
|
||||
{
|
||||
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
|
||||
{
|
||||
RunningMode speedMode = (RunningMode)value;
|
||||
int mode = System.Convert.ToInt32(parameter.ToString());
|
||||
|
||||
return mode == (int)speedMode ? true : false;
|
||||
}
|
||||
|
||||
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
|
||||
{
|
||||
|
||||
int mode = System.Convert.ToInt32(parameter.ToString());
|
||||
return (RunningMode)mode;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,39 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Globalization;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using System.Windows;
|
||||
using System.Windows.Data;
|
||||
|
||||
namespace MainShell.Converter
|
||||
{
|
||||
public class ScreenToViewModelConverter : IValueConverter
|
||||
{
|
||||
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
|
||||
{
|
||||
if (value == null) return null;
|
||||
|
||||
var viewModelType = value.GetType();
|
||||
var viewName = viewModelType.FullName.Replace("ViewModel", "View");
|
||||
var viewType = Type.GetType(viewName);
|
||||
|
||||
if (viewType != null)
|
||||
{
|
||||
// 创建View实例,并设置其DataContext为当前的ViewModel
|
||||
var view = (FrameworkElement)Activator.CreateInstance(viewType);
|
||||
view.DataContext = value;
|
||||
return view;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,29 @@
|
||||
using MainShell.Recipe.Models.SubstrateParameter;
|
||||
using System;
|
||||
using System.Globalization;
|
||||
using System.Windows.Data;
|
||||
|
||||
namespace MainShell.Converter
|
||||
{
|
||||
public class SubstrateHeightMeasureModeToBoolConverter : IValueConverter
|
||||
{
|
||||
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
|
||||
{
|
||||
var mode = value is SubstrateHeightMeasureMode measureMode ? measureMode : SubstrateHeightMeasureMode.StandardTeachPosition;
|
||||
var parameterValue = System.Convert.ToInt32(parameter, CultureInfo.InvariantCulture);
|
||||
|
||||
return parameterValue == (int)mode;
|
||||
}
|
||||
|
||||
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
|
||||
{
|
||||
if (!(value is bool isChecked) || !isChecked)
|
||||
{
|
||||
return Binding.DoNothing;
|
||||
}
|
||||
|
||||
var parameterValue = System.Convert.ToInt32(parameter, CultureInfo.InvariantCulture);
|
||||
return (SubstrateHeightMeasureMode)parameterValue;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,43 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Globalization;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using System.Windows;
|
||||
using System.Windows.Data;
|
||||
|
||||
namespace MainShell.Converter
|
||||
{
|
||||
public class WidthToMarginConverter : IValueConverter
|
||||
{
|
||||
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
|
||||
{
|
||||
double actualWidth = 0;
|
||||
if (value is double d) actualWidth = d;
|
||||
|
||||
double expanded = 200;
|
||||
double extra = 0;
|
||||
|
||||
if (parameter is string s)
|
||||
{
|
||||
var parts = s.Split(new[] { ',' }, StringSplitOptions.RemoveEmptyEntries);
|
||||
if (parts.Length >= 1 && double.TryParse(parts[0], out var p0)) expanded = p0;
|
||||
if (parts.Length >= 2 && double.TryParse(parts[1], out var p1)) extra = p1;
|
||||
}
|
||||
|
||||
// 计算右侧 Margin:
|
||||
// 当 actualWidth == expanded 时返回 0(不偏移)
|
||||
// 当 actualWidth 减小时会返回正值,从而把 ToggleButton 向左推(或根据需要调整公式)
|
||||
double right = Math.Max(0, expanded - actualWidth) + extra;
|
||||
|
||||
// 根据布局需要你可以修改这里返回的 Thickness 的哪一项(Left/Right)
|
||||
return new Thickness(-30, 0, 0, 0);
|
||||
}
|
||||
|
||||
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,49 @@
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace MainShell.DeviceMaintance.Model
|
||||
{
|
||||
public enum CylinderControlType
|
||||
{
|
||||
SingleOutput = 0,
|
||||
DualOutput = 1,
|
||||
MultiOutput = 2
|
||||
}
|
||||
|
||||
public enum CylinderConditionType
|
||||
{
|
||||
PointOn = 0,
|
||||
PointOff = 1
|
||||
}
|
||||
|
||||
public class CylinderActionConditionDefinition
|
||||
{
|
||||
public CylinderConditionType ConditionType { get; set; }
|
||||
public string PointReference { get; set; }
|
||||
public string Message { get; set; }
|
||||
|
||||
public bool ExpectedState => ConditionType == CylinderConditionType.PointOn;
|
||||
}
|
||||
|
||||
public class CylinderDefinition
|
||||
{
|
||||
public string Name { get; set; }
|
||||
public string Description { get; set; }
|
||||
public string Module { get; set; }
|
||||
public CylinderControlType ControlType { get; set; }
|
||||
public List<string> ExtendOutputPoints { get; set; } = new List<string>();
|
||||
public List<string> RetractOutputPoints { get; set; } = new List<string>();
|
||||
public List<string> ExtendedFeedbackPoints { get; set; } = new List<string>();
|
||||
public List<string> RetractedFeedbackPoints { get; set; } = new List<string>();
|
||||
public List<CylinderActionConditionDefinition> ExtendConditions { get; set; } = new List<CylinderActionConditionDefinition>();
|
||||
public List<CylinderActionConditionDefinition> RetractConditions { get; set; } = new List<CylinderActionConditionDefinition>();
|
||||
|
||||
public bool HasRetractOutputs => RetractOutputPoints != null && RetractOutputPoints.Count > 0;
|
||||
}
|
||||
|
||||
public class CylinderExecutionResult
|
||||
{
|
||||
public bool Success { get; set; }
|
||||
public string FailureReason { get; set; }
|
||||
public IReadOnlyList<string> FailurePointReferences { get; set; } = new List<string>();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,209 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
|
||||
namespace MainShell.DeviceMaintance.Model
|
||||
{
|
||||
public static class CylinderDefinitionLoader
|
||||
{
|
||||
private const string CylinderConfigFileName = "CylinderDefinitions.csv";
|
||||
|
||||
public static IReadOnlyList<CylinderDefinition> LoadDefinitions()
|
||||
{
|
||||
var definitions = new List<CylinderDefinition>();
|
||||
var path = ResolveConfigPath();
|
||||
if (string.IsNullOrWhiteSpace(path) || !File.Exists(path))
|
||||
{
|
||||
return definitions;
|
||||
}
|
||||
|
||||
var lines = File.ReadAllLines(path, Encoding.UTF8);
|
||||
foreach (var raw in lines)
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(raw))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
var line = raw.Trim();
|
||||
if (line.StartsWith("#") || line.StartsWith("Name", StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
var cols = line.Split(',');
|
||||
if (cols.Length < 7)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
var extendOutputPoints = ParsePointReferences(cols[3]);
|
||||
if (extendOutputPoints.Count == 0)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
var retractOutputPoints = ParsePointReferences(cols[4]);
|
||||
|
||||
var hasConditionColumns = cols.Length >= 10;
|
||||
var extendConditionIndex = hasConditionColumns ? 7 : -1;
|
||||
var retractConditionIndex = hasConditionColumns ? 8 : -1;
|
||||
var descriptionIndex = hasConditionColumns ? 9 : 7;
|
||||
|
||||
definitions.Add(new CylinderDefinition
|
||||
{
|
||||
Name = cols[0].Trim(),
|
||||
Module = cols[1].Trim(),
|
||||
ControlType = ParseControlType(cols[2]),
|
||||
ExtendOutputPoints = extendOutputPoints,
|
||||
RetractOutputPoints = retractOutputPoints,
|
||||
ExtendedFeedbackPoints = ParsePointReferences(cols[5]),
|
||||
RetractedFeedbackPoints = ParsePointReferences(cols[6]),
|
||||
ExtendConditions = extendConditionIndex >= 0 ? ParseConditions(cols[extendConditionIndex]) : new List<CylinderActionConditionDefinition>(),
|
||||
RetractConditions = retractConditionIndex >= 0 ? ParseConditions(cols[retractConditionIndex]) : new List<CylinderActionConditionDefinition>(),
|
||||
Description = cols.Length > descriptionIndex ? string.Join(",", cols.Skip(descriptionIndex)).Trim() : string.Empty
|
||||
});
|
||||
}
|
||||
|
||||
return definitions;
|
||||
}
|
||||
|
||||
private static CylinderControlType ParseControlType(string raw)
|
||||
{
|
||||
if (string.Equals(raw, "DualOutput", StringComparison.OrdinalIgnoreCase) ||
|
||||
string.Equals(raw, "Dual", StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
return CylinderControlType.DualOutput;
|
||||
}
|
||||
|
||||
if (string.Equals(raw, "MultiOutput", StringComparison.OrdinalIgnoreCase) ||
|
||||
string.Equals(raw, "Multi", StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
return CylinderControlType.MultiOutput;
|
||||
}
|
||||
|
||||
return CylinderControlType.SingleOutput;
|
||||
}
|
||||
|
||||
private static List<string> ParsePointReferences(string raw)
|
||||
{
|
||||
return (raw ?? string.Empty)
|
||||
.Split(new[] { ';' }, StringSplitOptions.RemoveEmptyEntries)
|
||||
.Select(x => x.Trim())
|
||||
.Where(x => !string.IsNullOrWhiteSpace(x))
|
||||
.ToList();
|
||||
}
|
||||
|
||||
private static List<CylinderActionConditionDefinition> ParseConditions(string raw)
|
||||
{
|
||||
return (raw ?? string.Empty)
|
||||
.Split(new[] { '|' }, StringSplitOptions.RemoveEmptyEntries)
|
||||
.Select(ParseCondition)
|
||||
.Where(x => x != null)
|
||||
.ToList();
|
||||
}
|
||||
|
||||
private static CylinderActionConditionDefinition ParseCondition(string raw)
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(raw))
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
var parts = raw.Split(new[] { ':' }, 3);
|
||||
if (parts.Length < 2)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
var pointReference = parts[1].Trim();
|
||||
if (string.IsNullOrWhiteSpace(pointReference))
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
CylinderConditionType conditionType;
|
||||
switch ((parts[0] ?? string.Empty).Trim().ToUpperInvariant())
|
||||
{
|
||||
case "POINTON":
|
||||
case "ON":
|
||||
conditionType = CylinderConditionType.PointOn;
|
||||
break;
|
||||
case "POINTOFF":
|
||||
case "OFF":
|
||||
conditionType = CylinderConditionType.PointOff;
|
||||
break;
|
||||
default:
|
||||
return null;
|
||||
}
|
||||
|
||||
return new CylinderActionConditionDefinition
|
||||
{
|
||||
ConditionType = conditionType,
|
||||
PointReference = pointReference,
|
||||
Message = parts.Length > 2 ? parts[2].Trim() : string.Empty
|
||||
};
|
||||
}
|
||||
|
||||
private static string ResolveConfigPath()
|
||||
{
|
||||
var baseDir = AppDomain.CurrentDomain.BaseDirectory;
|
||||
var localPath = Path.Combine(baseDir, "Configuration", CylinderConfigFileName);
|
||||
var sourcePath = ResolveRootConfigPath(baseDir);
|
||||
|
||||
if (TrySyncConfigToLocal(sourcePath, localPath))
|
||||
{
|
||||
return localPath;
|
||||
}
|
||||
|
||||
return File.Exists(localPath) ? localPath : sourcePath;
|
||||
}
|
||||
|
||||
private static string ResolveRootConfigPath(string baseDir)
|
||||
{
|
||||
var current = new DirectoryInfo(baseDir);
|
||||
while (current != null)
|
||||
{
|
||||
var rootConfigDir = Path.Combine(current.FullName, "Configuration");
|
||||
if (Directory.Exists(rootConfigDir) && Directory.Exists(Path.Combine(current.FullName, "MainShell")))
|
||||
{
|
||||
var path = Path.Combine(rootConfigDir, CylinderConfigFileName);
|
||||
if (File.Exists(path))
|
||||
{
|
||||
return path;
|
||||
}
|
||||
}
|
||||
|
||||
current = current.Parent;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
private static bool TrySyncConfigToLocal(string sourcePath, string localPath)
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(sourcePath) || !File.Exists(sourcePath))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!string.Equals(Path.GetFullPath(sourcePath), Path.GetFullPath(localPath), StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
var localDir = Path.GetDirectoryName(localPath);
|
||||
if (!string.IsNullOrWhiteSpace(localDir))
|
||||
{
|
||||
Directory.CreateDirectory(localDir);
|
||||
}
|
||||
|
||||
if (!File.Exists(localPath) || File.GetLastWriteTimeUtc(localPath) < File.GetLastWriteTimeUtc(sourcePath))
|
||||
{
|
||||
File.Copy(sourcePath, localPath, true);
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
using Stylet;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace MainShell.DeviceMaintance.Model
|
||||
{
|
||||
public class DeviceMaintanceBaseViewModel : Screen
|
||||
{
|
||||
public event Action<bool> UiStateChangedEvent = null;
|
||||
|
||||
protected void OnUiStateChanged(bool uiStateChanged)
|
||||
{
|
||||
UiStateChangedEvent?.Invoke(uiStateChanged);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,97 @@
|
||||
using MainShell.Filewritable;
|
||||
using Newtonsoft.Json;
|
||||
using System;
|
||||
using System.ComponentModel;
|
||||
using System.Runtime.CompilerServices;
|
||||
|
||||
namespace MainShell.DeviceMaintance.Model
|
||||
{
|
||||
public class LaserCompensationSetting : MXJM.FileWritable.JsonFileWritableBase, INotifyPropertyChanged
|
||||
{
|
||||
private string _axisName = "Axis_Stage_Y3";
|
||||
public string AxisName
|
||||
{
|
||||
get { return _axisName; }
|
||||
set { SetAndNotify(ref _axisName, value); }
|
||||
}
|
||||
|
||||
private double _startPos;
|
||||
public double StartPos
|
||||
{
|
||||
get { return _startPos; }
|
||||
set { SetAndNotify(ref _startPos, value); }
|
||||
}
|
||||
|
||||
private double _steps = 1.0d;
|
||||
public double Steps
|
||||
{
|
||||
get { return _steps; }
|
||||
set { SetAndNotify(ref _steps, value); }
|
||||
}
|
||||
|
||||
private int _stepsCount = 5;
|
||||
public int StepsCount
|
||||
{
|
||||
get { return _stepsCount; }
|
||||
set { SetAndNotify(ref _stepsCount, value); }
|
||||
}
|
||||
|
||||
private double _jumpPos = 1.0d;
|
||||
public double JumpPos
|
||||
{
|
||||
get { return _jumpPos; }
|
||||
set { SetAndNotify(ref _jumpPos, value); }
|
||||
}
|
||||
|
||||
private int _workCount = 1;
|
||||
public int WorkCount
|
||||
{
|
||||
get { return _workCount; }
|
||||
set { SetAndNotify(ref _workCount, value); }
|
||||
}
|
||||
|
||||
private double _speed = 5.0d;
|
||||
public double Speed
|
||||
{
|
||||
get { return _speed; }
|
||||
set { SetAndNotify(ref _speed, value); }
|
||||
}
|
||||
|
||||
private double _dwellTime = 0.5d;
|
||||
public double DwellTime
|
||||
{
|
||||
get { return _dwellTime; }
|
||||
set { SetAndNotify(ref _dwellTime, value); }
|
||||
}
|
||||
|
||||
[JsonIgnore]
|
||||
public override string Dir => Paths.CalibSettingPath;
|
||||
|
||||
[JsonIgnore]
|
||||
public override string FileName => "LaserCompensationSetting.json";
|
||||
|
||||
public event PropertyChangedEventHandler PropertyChanged;
|
||||
|
||||
public void LoadFromFile()
|
||||
{
|
||||
Read();
|
||||
}
|
||||
|
||||
public void SaveToFile()
|
||||
{
|
||||
Write();
|
||||
}
|
||||
|
||||
protected bool SetAndNotify<T>(ref T field, T value, [CallerMemberName] string propertyName = null)
|
||||
{
|
||||
if (Equals(field, value))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
field = value;
|
||||
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,64 @@
|
||||
using MainShell.Common;
|
||||
using MainShell.Filewritable;
|
||||
using MaxwellControl.Controls;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace MainShell.DeviceMaintance.Model
|
||||
{
|
||||
public enum MaintanceType
|
||||
{
|
||||
针尖维护 = 1,
|
||||
相机校验 = 2,
|
||||
针印验证 = 3,
|
||||
}
|
||||
public class MaintanceRecord
|
||||
{
|
||||
/// <summary>
|
||||
/// 设备编号
|
||||
/// </summary>
|
||||
public string DeviceId { get; set; }
|
||||
/// <summary>
|
||||
/// 设备名称
|
||||
/// </summary>
|
||||
public string DeviceName { get; set; }
|
||||
/// <summary>
|
||||
/// 维护时间
|
||||
/// </summary>
|
||||
public DateTime MaintanceTime { get; set; }
|
||||
/// <summary>
|
||||
/// 维护内容
|
||||
/// </summary>
|
||||
public MaintanceType MaintanceType { get; set; }
|
||||
|
||||
public void WriteToFile(string info)
|
||||
{
|
||||
try
|
||||
{
|
||||
if (!Directory.Exists(Paths.MaintanceRecordDir))
|
||||
{
|
||||
Directory.CreateDirectory(Paths.MaintanceRecordDir);
|
||||
}
|
||||
string filePath = Path.Combine(Paths.MaintanceRecordDir, $"{MaintanceType}_MaintanceRecord.txt");
|
||||
using (var writer = new System.IO.StreamWriter(filePath, true))
|
||||
{
|
||||
if (!File.Exists(filePath))
|
||||
{
|
||||
writer.WriteLine("设备ID,日期,信息");
|
||||
}
|
||||
writer.WriteLine($"{DeviceId},{DateTime.Now}: {info}");
|
||||
writer.Flush();
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
MessageBox.Show($"写入文件失败: {ex.Message}");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,757 @@
|
||||
using MwFramework.Controls.UIControl;
|
||||
using MwFramework.ManagerService;
|
||||
using Stylet;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.ObjectModel;
|
||||
using System.ComponentModel.Composition;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace MainShell.DeviceMaintance.Model
|
||||
{
|
||||
[Export(typeof(IParameter))]
|
||||
public class NeedleCalibrationSetting : ParameterBase
|
||||
{
|
||||
public NeedleZCalibrationItem NeedleZCalibrationItem { get; set; } = new NeedleZCalibrationItem();
|
||||
|
||||
public NeedleXYCalibrationItem NeedleXYCalibrationItem { get; set; } = new NeedleXYCalibrationItem();
|
||||
|
||||
public NeedleXYCalibrationItemNew NeedleXYCalibrationItemNew { get; set; } = new NeedleXYCalibrationItemNew();
|
||||
|
||||
public override void Copy(IParameter source)
|
||||
{
|
||||
NeedleCalibrationSetting setting = source as NeedleCalibrationSetting;
|
||||
if (setting != null)
|
||||
{
|
||||
ReflectionExtension.Copy<NeedleZCalibrationItem>(NeedleZCalibrationItem, setting.NeedleZCalibrationItem);
|
||||
ReflectionExtension.Copy<NeedleXYCalibrationItem>(NeedleXYCalibrationItem, setting.NeedleXYCalibrationItem);
|
||||
ReflectionExtension.Copy<NeedleXYCalibrationItemNew>(NeedleXYCalibrationItemNew, setting.NeedleXYCalibrationItemNew);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public class NeedleZCalibrationItem : PropertyChangedBase, IParameterItem
|
||||
{
|
||||
|
||||
private double _supportPinPositionX;
|
||||
[WatchValue("针尖对准对刀仪X1位置")]
|
||||
public double SupportPinPositionX
|
||||
{
|
||||
get { return _supportPinPositionX; }
|
||||
set { if (_supportPinPositionX != value) { _supportPinPositionX = value; OnPropertyChanged(nameof(SupportPinPositionX)); } }
|
||||
}
|
||||
|
||||
private double _supportPinPositionY;
|
||||
[WatchValue("针尖对准对刀仪Y1位置")]
|
||||
public double SupportPinPositionY
|
||||
{
|
||||
get { return _supportPinPositionY; }
|
||||
set { if (_supportPinPositionY != value) { _supportPinPositionY = value; OnPropertyChanged(nameof(SupportPinPositionY)); } }
|
||||
}
|
||||
|
||||
private double _knifeOffset;
|
||||
[WatchValue("对刀仪偏差")]
|
||||
/// <summary>
|
||||
/// 对刀仪偏差
|
||||
/// </summary>
|
||||
public double KnifeOffset
|
||||
{
|
||||
get { return _knifeOffset; }
|
||||
set { if (_knifeOffset != value) { _knifeOffset = value; OnPropertyChanged(nameof(KnifeOffset)); } }
|
||||
}
|
||||
|
||||
private double _cZHeight = -0.725;
|
||||
[WatchValue("SZ高度")]
|
||||
public double CZHeight
|
||||
{
|
||||
get { return _cZHeight; }
|
||||
set { if (_cZHeight != value) { _cZHeight = value; OnPropertyChanged(nameof(CZHeight)); } }
|
||||
}
|
||||
|
||||
private double _stageHeight;
|
||||
[WatchValue("载台高度")]
|
||||
public double StageHeight
|
||||
{
|
||||
get { return _stageHeight; }
|
||||
set { if (_stageHeight != value) { _stageHeight = value; OnPropertyChanged(nameof(StageHeight)); } }
|
||||
}
|
||||
|
||||
private double _gantry2AvoidPositionX = 10;
|
||||
[WatchValue("对刀时龙门X2的避让位置")]
|
||||
public double Gantry2AvoidPositionX
|
||||
{
|
||||
get { return _gantry2AvoidPositionX; }
|
||||
set { if (_gantry2AvoidPositionX != value) { _gantry2AvoidPositionX = value; OnPropertyChanged(nameof(Gantry2AvoidPositionX)); } }
|
||||
}
|
||||
private double _gantry2AvoidPositionY = 200;
|
||||
[WatchValue("对刀时龙门Y2的避让位置")]
|
||||
public double Gantry2AvoidPositionY
|
||||
{
|
||||
get { return _gantry2AvoidPositionY; }
|
||||
set { if (_gantry2AvoidPositionY != value) { _gantry2AvoidPositionY = value; OnPropertyChanged(nameof(Gantry2AvoidPositionY)); } }
|
||||
}
|
||||
private double _z1StartPosition;
|
||||
[WatchValue("Z1开始位置")]
|
||||
public double Z1StartPosition
|
||||
{
|
||||
get { return _z1StartPosition; }
|
||||
set { if (_z1StartPosition != value) { _z1StartPosition = value; OnPropertyChanged(nameof(Z1StartPosition)); } }
|
||||
}
|
||||
|
||||
private double _z1Speed;
|
||||
[WatchValue("Z1速度")]
|
||||
public double Z1Speed
|
||||
{
|
||||
get { return _z1Speed; }
|
||||
set { if (_z1Speed != value) { _z1Speed = value; OnPropertyChanged(nameof(Z1Speed)); } }
|
||||
}
|
||||
|
||||
private double _z1DropMaxPosition;
|
||||
[WatchValue("Z1下降距离")]
|
||||
public double Z1DropMaxPosition
|
||||
{
|
||||
get { return _z1DropMaxPosition; }
|
||||
set { if (_z1DropMaxPosition != value) { _z1DropMaxPosition = value; OnPropertyChanged(nameof(Z1DropMaxPosition)); } }
|
||||
}
|
||||
|
||||
private int _needleTouchCount = 1;
|
||||
[WatchValue("对刀次数")]
|
||||
public int NeedleTouchCount
|
||||
{
|
||||
get { return _needleTouchCount; }
|
||||
set { if (_needleTouchCount != value) { _needleTouchCount = value; OnPropertyChanged(nameof(NeedleTouchCount)); } }
|
||||
}
|
||||
|
||||
private double _needleTouchHeight = 14;
|
||||
|
||||
/// <summary>
|
||||
/// Z1接触对刀仪高度
|
||||
/// </summary>
|
||||
[WatchValue("Z1接触对刀仪高度")]
|
||||
public double NeedleTouchHeight
|
||||
{
|
||||
get { return _needleTouchHeight; }
|
||||
set { if (_needleTouchHeight != value) { _needleTouchHeight = value; OnPropertyChanged(nameof(NeedleTouchHeight)); } }
|
||||
}
|
||||
|
||||
private double _needleTouchHeightBase;
|
||||
|
||||
/// <summary>
|
||||
/// 基准值
|
||||
/// </summary>
|
||||
[WatchValue("基准值")]
|
||||
public double NeedleTouchHeightBase
|
||||
{
|
||||
get { return _needleTouchHeightBase; }
|
||||
set { if (_needleTouchHeightBase != value) { _needleTouchHeightBase = value; OnPropertyChanged(nameof(NeedleTouchHeightBase)); } }
|
||||
}
|
||||
|
||||
private double _currentNeedleTouchHeight;
|
||||
[WatchValue("当前使用对刀高度")]
|
||||
/// <summary>
|
||||
/// 当前使用对刀高度
|
||||
/// </summary>
|
||||
public double CurrentNeedleTouchHeight
|
||||
{
|
||||
get { return _currentNeedleTouchHeight; }
|
||||
set { if (_currentNeedleTouchHeight != value) { _currentNeedleTouchHeight = value; OnPropertyChanged(nameof(CurrentNeedleTouchHeight)); } }
|
||||
}
|
||||
|
||||
private double _needleTouchOffset;
|
||||
[WatchValue("对刀与基准偏差")]
|
||||
/// <summary>
|
||||
/// 对刀与基准偏差
|
||||
/// </summary>
|
||||
public double NeedleTouchOffset
|
||||
{
|
||||
get { return _needleTouchOffset; }
|
||||
set { if (_needleTouchOffset != value) { _needleTouchOffset = value; OnPropertyChanged(nameof(NeedleTouchOffset)); } }
|
||||
}
|
||||
|
||||
private double _needleTouchHeightAve;
|
||||
[WatchValue("Z1对刀平均高度")]
|
||||
/// <summary>
|
||||
/// Z1对刀平均高度
|
||||
/// </summary>
|
||||
public double NeedleTouchHeightAve
|
||||
{
|
||||
get { return _needleTouchHeightAve; }
|
||||
set { if (_needleTouchHeightAve != value) { _needleTouchHeightAve = value; OnPropertyChanged(nameof(NeedleTouchHeightAve)); } }
|
||||
}
|
||||
|
||||
private ObservableCollection<NeedleTouchRecord> _needleTouchRecords = new ObservableCollection<NeedleTouchRecord>();
|
||||
|
||||
public ObservableCollection<NeedleTouchRecord> NeedleTouchRecords
|
||||
{
|
||||
get { return _needleTouchRecords; }
|
||||
set
|
||||
{
|
||||
_needleTouchRecords = value;
|
||||
OnPropertyChanged(nameof(NeedleTouchRecords));
|
||||
}
|
||||
}
|
||||
|
||||
private double _laserToNeedleOffset = 0;
|
||||
public double LaserToNeedleOffset
|
||||
{
|
||||
get { return _laserToNeedleOffset; }
|
||||
set { if (_laserToNeedleOffset != value) { _laserToNeedleOffset = value; OnPropertyChanged(nameof(LaserToNeedleOffset)); } }
|
||||
}
|
||||
|
||||
private double _needleCameraHeightOffset;
|
||||
public double NeedleCameraHeightOffset
|
||||
{
|
||||
get { return _needleCameraHeightOffset; }
|
||||
set { if (_needleCameraHeightOffset != value) { _needleCameraHeightOffset = value; OnPropertyChanged(nameof(NeedleCameraHeightOffset)); } }
|
||||
}
|
||||
|
||||
public IParameterItem Clone()
|
||||
{
|
||||
NeedleZCalibrationItem clone = new NeedleZCalibrationItem();
|
||||
clone.CurrentNeedleTouchHeight = _needleCameraHeightOffset;
|
||||
clone.CZHeight = CZHeight;
|
||||
clone.Gantry2AvoidPositionX = Gantry2AvoidPositionX;
|
||||
clone.Gantry2AvoidPositionY = Gantry2AvoidPositionY;
|
||||
clone.LaserToNeedleOffset = LaserToNeedleOffset;
|
||||
clone.NeedleCameraHeightOffset = NeedleCameraHeightOffset;
|
||||
clone.NeedleTouchCount = NeedleTouchCount;
|
||||
clone.NeedleTouchHeight = NeedleTouchHeight;
|
||||
clone.NeedleTouchHeightAve = NeedleTouchHeightAve;
|
||||
clone.NeedleTouchHeightBase = NeedleTouchHeightBase;
|
||||
clone.NeedleTouchOffset = NeedleTouchOffset;
|
||||
clone.StageHeight = StageHeight;
|
||||
clone.SupportPinPositionX = SupportPinPositionX;
|
||||
clone.SupportPinPositionY = SupportPinPositionY;
|
||||
clone.Z1DropMaxPosition = Z1DropMaxPosition;
|
||||
clone.Z1Speed = Z1Speed;
|
||||
clone.Z1StartPosition = Z1StartPosition;
|
||||
if (this.NeedleTouchRecords != null)
|
||||
{
|
||||
foreach (var item in this.NeedleTouchRecords)
|
||||
{
|
||||
clone.NeedleTouchRecords.Add(item.Clone() as NeedleTouchRecord);
|
||||
}
|
||||
}
|
||||
return clone;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public class NeedleXYCalibrationItem : PropertyChangedBase, IParameterItem
|
||||
{
|
||||
private double _needleX;
|
||||
[WatchValue("设置—刺晶头X")]
|
||||
public double NeedleX
|
||||
{
|
||||
get { return _needleX; }
|
||||
set { if (_needleX != value) { _needleX = value; OnPropertyChanged(nameof(NeedleX)); } }
|
||||
}
|
||||
|
||||
private double _needleY;
|
||||
[WatchValue("设置—刺晶头Y")]
|
||||
public double NeedleY
|
||||
{
|
||||
get { return _needleY; }
|
||||
set { if (_needleY != value) { _needleY = value; OnPropertyChanged(nameof(NeedleY)); } }
|
||||
}
|
||||
|
||||
private double _cameraX;
|
||||
[WatchValue("设置—相机X")]
|
||||
public double CameraX
|
||||
{
|
||||
get { return _cameraX; }
|
||||
set { if (_cameraX != value) { _cameraX = value; OnPropertyChanged(nameof(CameraX)); } }
|
||||
}
|
||||
|
||||
private double _cameraY;
|
||||
[WatchValue("设置—相机Y")]
|
||||
public double CameraY
|
||||
{
|
||||
get { return _cameraY; }
|
||||
set { if (_cameraY != value) { _cameraY = value; OnPropertyChanged(nameof(CameraY)); } }
|
||||
}
|
||||
private double _needleZ1 = 0.0;
|
||||
[WatchValue("设置—刺晶头Z1")]
|
||||
public double NeedleZ1
|
||||
{
|
||||
get { return _needleZ1; }
|
||||
set { if (_needleZ1 != value) { _needleZ1 = value; OnPropertyChanged(nameof(NeedleZ1)); } }
|
||||
}
|
||||
|
||||
private double _offsetX;
|
||||
[WatchValue("X方向偏差")]
|
||||
public double OffsetX
|
||||
{
|
||||
get { return _offsetX; }
|
||||
set { if (_offsetX != value) { _offsetX = value; OnPropertyChanged(nameof(OffsetX)); } }
|
||||
}
|
||||
|
||||
private double _offsetY;
|
||||
[WatchValue("Y方向偏差")]
|
||||
public double OffsetY
|
||||
{
|
||||
get { return _offsetY; }
|
||||
set { if (_offsetY != value) { _offsetY = value; OnPropertyChanged(nameof(OffsetY)); } }
|
||||
}
|
||||
|
||||
private double _initialOffsetX;
|
||||
/// <summary>
|
||||
/// 针和相机之间的X初始偏差,不加补偿
|
||||
/// </summary>
|
||||
[WatchValue("X方向初始偏差")]
|
||||
public double InitialOffsetX
|
||||
{
|
||||
get { return _initialOffsetX; }
|
||||
set { if (_initialOffsetX != value) { _initialOffsetX = value; OnPropertyChanged(nameof(InitialOffsetX)); } }
|
||||
}
|
||||
|
||||
private double _initialOffsetY;
|
||||
/// <summary>
|
||||
/// 针和相机之间的Y初始偏差,不加补偿
|
||||
/// </summary>
|
||||
[WatchValue("Y方向初始偏差")]
|
||||
public double InitialOffsetY
|
||||
{
|
||||
get { return _initialOffsetY; }
|
||||
set { if (_initialOffsetY != value) { _initialOffsetY = value; OnPropertyChanged(nameof(InitialOffsetY)); } }
|
||||
}
|
||||
|
||||
private double _compensateX;
|
||||
/// <summary>
|
||||
/// 针和相机之间的X方向偏差补偿
|
||||
/// </summary>
|
||||
[WatchValue("X方向补偿")]
|
||||
public double CompensateX
|
||||
{
|
||||
get { return _compensateX; }
|
||||
set { if (_compensateX != value) { _compensateX = value; OnPropertyChanged(nameof(CompensateX)); } }
|
||||
}
|
||||
|
||||
private double _compensateY;
|
||||
/// <summary>
|
||||
/// 针和相机之间的Y方向偏差补偿
|
||||
/// </summary>
|
||||
[WatchValue("Y方向补偿")]
|
||||
public double CompensateY
|
||||
{
|
||||
get { return _compensateY; }
|
||||
set { if (_compensateY != value) { _compensateY = value; OnPropertyChanged(nameof(CompensateY)); } }
|
||||
}
|
||||
|
||||
private double _offsetXMax;
|
||||
[WatchValue("偏差限制—X偏差最大值")]
|
||||
public double OffsetXMax
|
||||
{
|
||||
get { return _offsetXMax; }
|
||||
set { if (_offsetXMax != value) { _offsetXMax = value; OnPropertyChanged(nameof(OffsetXMax)); } }
|
||||
}
|
||||
|
||||
private double _offsetXMin;
|
||||
[WatchValue("偏差限制—X偏差最小值")]
|
||||
public double OffsetXMin
|
||||
{
|
||||
get { return _offsetXMin; }
|
||||
set { if (_offsetXMin != value) { _offsetXMin = value; OnPropertyChanged(nameof(OffsetXMin)); } }
|
||||
}
|
||||
|
||||
private double _offsetYMax;
|
||||
[WatchValue("偏差限制—Y偏差最大值")]
|
||||
public double OffsetYMax
|
||||
{
|
||||
get { return _offsetYMax; }
|
||||
set { if (_offsetYMax != value) { _offsetYMax = value; OnPropertyChanged(nameof(OffsetYMax)); } }
|
||||
}
|
||||
|
||||
private double _offsetYMin;
|
||||
[WatchValue("偏差限制—Y偏差最小值")]
|
||||
public double OffsetYMin
|
||||
{
|
||||
get { return _offsetYMin; }
|
||||
set { if (_offsetYMin != value) { _offsetYMin = value; OnPropertyChanged(nameof(OffsetYMin)); } }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 扎铜箔时龙门X2避让位置
|
||||
/// </summary>
|
||||
private double _x2AvoidPosition;
|
||||
[WatchValue("扎铜箔时龙门X2避让位置")]
|
||||
public double X2AvoidPosition
|
||||
{
|
||||
get { return _x2AvoidPosition; }
|
||||
set { if (_x2AvoidPosition != value) { _x2AvoidPosition = value; OnPropertyChanged(nameof(X2AvoidPosition)); } }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 扎铜箔时龙门Y2避让位置
|
||||
/// </summary>
|
||||
private double _y2AvoidPosition;
|
||||
[WatchValue("扎铜箔时龙门Y2避让位置")]
|
||||
public double Y2AvoidPosition
|
||||
{
|
||||
get { return _y2AvoidPosition; }
|
||||
set { if (_y2AvoidPosition != value) { _y2AvoidPosition = value; OnPropertyChanged(nameof(Y2AvoidPosition)); } }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 扎铜箔时Stage的位置
|
||||
/// </summary>
|
||||
private double _stagePosition;
|
||||
[WatchValue("扎铜箔时Stage的位置")]
|
||||
public double StagePosition
|
||||
{
|
||||
get { return _stagePosition; }
|
||||
set { if (_stagePosition != value) { _stagePosition = value; OnPropertyChanged(nameof(StagePosition)); } }
|
||||
}
|
||||
|
||||
public IParameterItem Clone()
|
||||
{
|
||||
NeedleXYCalibrationItem clone = new NeedleXYCalibrationItem();
|
||||
clone.NeedleX = this.NeedleX;
|
||||
clone.NeedleY = this.NeedleY;
|
||||
clone.CameraX = this.CameraY;
|
||||
clone.CameraY = this.CameraY;
|
||||
clone.OffsetX = this.OffsetX;
|
||||
clone.OffsetY = this.OffsetY;
|
||||
clone.OffsetXMax = this.OffsetXMax;
|
||||
clone.OffsetXMin = this.OffsetXMin;
|
||||
clone.OffsetYMax = this.OffsetYMax;
|
||||
clone.OffsetYMin = this.OffsetYMin;
|
||||
return this.MemberwiseClone() as IParameterItem;
|
||||
}
|
||||
}
|
||||
|
||||
public class NeedleXYCalibrationItemNew : PropertyChangedBase, IParameterItem
|
||||
{
|
||||
//private VisionParData _needleVisionParData;
|
||||
|
||||
//public VisionParData NeedleVisionParData
|
||||
//{
|
||||
// get { return _needleVisionParData ?? new VisionParData() { Exposure = 2000 }; }
|
||||
// set { SetAndNotify(ref _needleVisionParData, value); }
|
||||
//}
|
||||
|
||||
private double _x1Calib;
|
||||
/// <summary>
|
||||
/// 相机标定位X1
|
||||
/// </summary>
|
||||
[WatchValue("相机标定位X1")]
|
||||
public double X1Calib
|
||||
{
|
||||
get { return _x1Calib; }
|
||||
set { if (_x1Calib != value) { _x1Calib = value; OnPropertyChanged(nameof(X1Calib)); } }
|
||||
}
|
||||
|
||||
private double _x1MechanicalOffset = 0.0;
|
||||
/// <summary>
|
||||
/// 机械X1Offset
|
||||
/// </summary>
|
||||
[WatchValue("机械X1Offset")]
|
||||
public double X1MechanicalOffset
|
||||
{
|
||||
get { return _x1MechanicalOffset; }
|
||||
set { if (_x1MechanicalOffset != value) { _x1MechanicalOffset = value; OnPropertyChanged(nameof(X1MechanicalOffset)); } }
|
||||
}
|
||||
|
||||
private double _wSCalibX2;
|
||||
/// <summary>
|
||||
/// 方片标定位X2
|
||||
/// </summary>
|
||||
[WatchValue("方片标定位X2")]
|
||||
public double WSCalibX2
|
||||
{
|
||||
get { return _wSCalibX2; }
|
||||
set { if (_wSCalibX2 != value) { _wSCalibX2 = value; OnPropertyChanged(nameof(WSCalibX2)); } }
|
||||
}
|
||||
|
||||
private double _wSCalibY2;
|
||||
/// <summary>
|
||||
/// 方片标定位Y2
|
||||
/// </summary>
|
||||
[WatchValue("方片标定位Y2")]
|
||||
public double WSCalibY2
|
||||
{
|
||||
get { return _wSCalibY2; }
|
||||
set { if (_wSCalibY2 != value) { _wSCalibY2 = value; OnPropertyChanged(nameof(WSCalibY2)); } }
|
||||
}
|
||||
|
||||
private double _needleX1;
|
||||
[WatchValue("刺晶头X1")]
|
||||
public double NeedleX1
|
||||
{
|
||||
get { return _needleX1; }
|
||||
set { if (_needleX1 != value) { _needleX1 = value; OnPropertyChanged(nameof(NeedleX1)); } }
|
||||
}
|
||||
|
||||
private double _needleZ1 = 0.0;
|
||||
[WatchValue("刺晶头Z1")]
|
||||
public double NeedleZ1
|
||||
{
|
||||
get { return _needleZ1; }
|
||||
set { if (_needleZ1 != value) { _needleZ1 = value; OnPropertyChanged(nameof(NeedleZ1)); } }
|
||||
}
|
||||
|
||||
private int _z1WorkTime = 0;
|
||||
/// <summary>
|
||||
/// Z1保持下扎时长
|
||||
/// </summary>
|
||||
[WatchValue("Z1保持下扎时长")]
|
||||
public int Z1WorkTime
|
||||
{
|
||||
get { return _z1WorkTime; }
|
||||
set { if (_z1WorkTime != value) { _z1WorkTime = value; OnPropertyChanged(nameof(Z1WorkTime)); } }
|
||||
}
|
||||
|
||||
private double _offsetX;
|
||||
/// <summary>
|
||||
/// 针和相机之间的X初始偏差,不加补偿
|
||||
/// </summary>
|
||||
[WatchValue("X方向偏差")]
|
||||
public double OffsetX
|
||||
{
|
||||
get { return _offsetX; }
|
||||
set { if (_offsetX != value) { _offsetX = value; OnPropertyChanged(nameof(OffsetX)); } }
|
||||
}
|
||||
|
||||
private double _offsetY;
|
||||
/// <summary>
|
||||
/// 针和相机之间的Y初始偏差,不加补偿
|
||||
/// </summary>
|
||||
[WatchValue("Y方向偏差")]
|
||||
public double OffsetY
|
||||
{
|
||||
get { return _offsetY; }
|
||||
set { if (_offsetY != value) { _offsetY = value; OnPropertyChanged(nameof(OffsetY)); } }
|
||||
}
|
||||
|
||||
private double _compensateX;
|
||||
/// <summary>
|
||||
/// 针和相机之间的X方向偏差补偿
|
||||
/// </summary>
|
||||
[WatchValue("X方向补偿")]
|
||||
public double CompensateX
|
||||
{
|
||||
get { return _compensateX; }
|
||||
set { if (_compensateX != value) { _compensateX = value; OnPropertyChanged(nameof(CompensateX)); } }
|
||||
}
|
||||
|
||||
private double _compensateY;
|
||||
/// <summary>
|
||||
/// 针和相机之间的Y方向偏差补偿
|
||||
/// </summary>
|
||||
[WatchValue("Y方向补偿")]
|
||||
public double CompensateY
|
||||
{
|
||||
get { return _compensateY; }
|
||||
set { if (_compensateY != value) { _compensateY = value; OnPropertyChanged(nameof(CompensateY)); } }
|
||||
}
|
||||
|
||||
private double _offsetXMax;
|
||||
[WatchValue("偏差限制—X偏差最大值")]
|
||||
public double OffsetXMax
|
||||
{
|
||||
get { return _offsetXMax; }
|
||||
set { if (_offsetXMax != value) { _offsetXMax = value; OnPropertyChanged(nameof(OffsetXMax)); } }
|
||||
}
|
||||
|
||||
private double _offsetXMin;
|
||||
[WatchValue("偏差限制—X偏差最小值")]
|
||||
public double OffsetXMin
|
||||
{
|
||||
get { return _offsetXMin; }
|
||||
set { if (_offsetXMin != value) { _offsetXMin = value; OnPropertyChanged(nameof(OffsetXMin)); } }
|
||||
}
|
||||
|
||||
private double _offsetYMax;
|
||||
[WatchValue("偏差限制—Y偏差最大值")]
|
||||
public double OffsetYMax
|
||||
{
|
||||
get { return _offsetYMax; }
|
||||
set { if (_offsetYMax != value) { _offsetYMax = value; OnPropertyChanged(nameof(OffsetYMax)); } }
|
||||
}
|
||||
|
||||
private double _offsetYMin;
|
||||
[WatchValue("偏差限制—Y偏差最小值")]
|
||||
public double OffsetYMin
|
||||
{
|
||||
get { return _offsetYMin; }
|
||||
set { if (_offsetYMin != value) { _offsetYMin = value; OnPropertyChanged(nameof(OffsetYMin)); } }
|
||||
}
|
||||
|
||||
private double _wSApproachX2;
|
||||
/// <summary>
|
||||
/// 方片逼近位X2
|
||||
/// </summary>
|
||||
[WatchValue("方片逼近位X2")]
|
||||
public double WSApproachX2
|
||||
{
|
||||
get { return _wSApproachX2; }
|
||||
set { if (_wSApproachX2 != value) { _wSApproachX2 = value; OnPropertyChanged(nameof(WSApproachX2)); } }
|
||||
}
|
||||
|
||||
private double _wSApproachY2;
|
||||
/// <summary>
|
||||
/// 方片逼近位Y2
|
||||
/// </summary>
|
||||
[WatchValue("方片逼近位Y2")]
|
||||
public double WSApproachY2
|
||||
{
|
||||
get { return _wSApproachY2; }
|
||||
set { if (_wSApproachY2 != value) { _wSApproachY2 = value; OnPropertyChanged(nameof(WSApproachY2)); } }
|
||||
}
|
||||
|
||||
private double _stampThreRadius;
|
||||
/// <summary>
|
||||
/// 针印理论半径
|
||||
/// </summary>
|
||||
[WatchValue("针印理论半径")]
|
||||
public double StampThreRadius
|
||||
{
|
||||
get { return _stampThreRadius; }
|
||||
set { if (_stampThreRadius != value) { _stampThreRadius = value; OnPropertyChanged(nameof(StampThreRadius)); } }
|
||||
}
|
||||
|
||||
private double _stampThreErrorRange;
|
||||
/// <summary>
|
||||
/// 针印误差范围
|
||||
/// </summary>
|
||||
[WatchValue("针印误差范围")]
|
||||
public double StampThreErrorRange
|
||||
{
|
||||
get { return _stampThreErrorRange; }
|
||||
set { if (_stampThreErrorRange != value) { _stampThreErrorRange = value; OnPropertyChanged(nameof(StampThreErrorRange)); } }
|
||||
}
|
||||
|
||||
private double _stampMinCircularity;
|
||||
/// <summary>
|
||||
/// 针印最小圆度
|
||||
/// </summary>
|
||||
[WatchValue("针印最小圆度")]
|
||||
public double StampMinCircularity
|
||||
{
|
||||
get { return _stampMinCircularity; }
|
||||
set { if (_stampMinCircularity != value) { _stampMinCircularity = value; OnPropertyChanged(nameof(StampMinCircularity)); } }
|
||||
}
|
||||
|
||||
private double _stampPolarity;
|
||||
/// <summary>
|
||||
/// 针印颜色,0黑1白
|
||||
/// </summary>
|
||||
[WatchValue("针印理论半径")]
|
||||
public double StampPolarity
|
||||
{
|
||||
get { return _stampPolarity; }
|
||||
set { if (_stampPolarity != value) { _stampPolarity = value; OnPropertyChanged(nameof(StampPolarity)); } }
|
||||
}
|
||||
|
||||
private bool _isBlack = false;
|
||||
public bool IsBlack
|
||||
{
|
||||
get
|
||||
{
|
||||
return _isBlack;
|
||||
}
|
||||
set
|
||||
{
|
||||
_isBlack = value;
|
||||
StampPolarityUpdate();
|
||||
OnPropertyChanged(nameof(IsBlack));
|
||||
}
|
||||
}
|
||||
|
||||
public void StampPolarityUpdate()
|
||||
{
|
||||
if (IsBlack)
|
||||
{
|
||||
StampPolarity = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
StampPolarity = 1;
|
||||
}
|
||||
}
|
||||
|
||||
public IParameterItem Clone()
|
||||
{
|
||||
NeedleXYCalibrationItemNew clone = new NeedleXYCalibrationItemNew();
|
||||
clone.NeedleX1 = this.NeedleX1;
|
||||
clone.NeedleZ1 = this.NeedleZ1;
|
||||
clone.WSApproachX2 = this.WSApproachX2;
|
||||
clone.WSApproachY2 = this.WSApproachY2;
|
||||
clone.Z1WorkTime = Z1WorkTime;
|
||||
clone.X1MechanicalOffset = X1MechanicalOffset;
|
||||
clone.X1Calib = X1Calib;
|
||||
clone.WSCalibX2 = WSCalibX2;
|
||||
clone.WSCalibY2 = WSCalibY2;
|
||||
clone.CompensateX = CompensateX;
|
||||
clone.CompensateY = CompensateY;
|
||||
clone.OffsetX = this.OffsetX;
|
||||
clone.OffsetY = this.OffsetY;
|
||||
clone.OffsetXMax = this.OffsetXMax;
|
||||
clone.OffsetXMin = this.OffsetXMin;
|
||||
clone.OffsetYMax = this.OffsetYMax;
|
||||
clone.OffsetYMin = this.OffsetYMin;
|
||||
clone.IsBlack = this.IsBlack;
|
||||
clone.StampMinCircularity = this.StampMinCircularity;
|
||||
clone.StampPolarity = this.StampPolarity;
|
||||
clone.StampThreErrorRange = this.StampThreErrorRange;
|
||||
clone.StampThreRadius = this.StampThreRadius;
|
||||
|
||||
|
||||
//clone.NeedleVisionParData.Exposure = this.NeedleVisionParData.Exposure;
|
||||
//clone.NeedleVisionParData.Gain = this.NeedleVisionParData.Gain;
|
||||
//clone.NeedleVisionParData.LightSourceBack = this.NeedleVisionParData.LightSourceBack;
|
||||
//clone.NeedleVisionParData.LightSourcePointBlue = this.NeedleVisionParData.LightSourcePointBlue;
|
||||
//clone.NeedleVisionParData.LightSourcePointRed = this.NeedleVisionParData.LightSourcePointRed;
|
||||
//clone.NeedleVisionParData.LightSourceRingBlue = this.NeedleVisionParData.LightSourceRingBlue;
|
||||
//clone.NeedleVisionParData.LightSourceRingRed = this.NeedleVisionParData.LightSourceRingRed;
|
||||
//clone.NeedleVisionParData.Z2 = this.NeedleVisionParData.Z2;
|
||||
|
||||
return this.MemberwiseClone() as IParameterItem;
|
||||
}
|
||||
}
|
||||
|
||||
public class NeedleTouchRecord : PropertyChangedBase, IParameterItem
|
||||
{
|
||||
|
||||
private int _CurrentCount;
|
||||
/// <summary>
|
||||
/// 当前次数
|
||||
/// </summary>
|
||||
public int CurrentCount
|
||||
{
|
||||
get { return _CurrentCount; }
|
||||
set
|
||||
{ SetAndNotify(ref _CurrentCount, value); }
|
||||
}
|
||||
|
||||
private double _Height;
|
||||
/// <summary>
|
||||
/// 高度
|
||||
/// </summary>
|
||||
public double Height
|
||||
{
|
||||
get { return _Height; }
|
||||
set
|
||||
{ SetAndNotify(ref _Height, value); }
|
||||
}
|
||||
|
||||
|
||||
|
||||
public NeedleTouchRecord()
|
||||
{
|
||||
|
||||
}
|
||||
public NeedleTouchRecord(int count, double height)
|
||||
{
|
||||
CurrentCount = count;
|
||||
Height = height;
|
||||
}
|
||||
|
||||
public IParameterItem Clone()
|
||||
{
|
||||
return this.MemberwiseClone() as IParameterItem;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,104 @@
|
||||
using MainShell.Models;
|
||||
using MwFramework.ManagerService;
|
||||
using Stylet;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel.Composition;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace MainShell.DeviceMaintance.Model
|
||||
{
|
||||
[Export(typeof(IParameter))]
|
||||
public class NeedlePrintCalibrateSetting : ParameterBase
|
||||
{
|
||||
public NeedlePrintCalibrateParameter NeedlePrintCalibrateParameter { get; set; } = new NeedlePrintCalibrateParameter();
|
||||
public NeedlePrintCalibrateSetting() { }
|
||||
public override void Copy(IParameter source)
|
||||
{
|
||||
if (source is NeedlePrintCalibrateSetting setting)
|
||||
{
|
||||
ReflectionExtension.Copy(NeedlePrintCalibrateParameter, setting.NeedlePrintCalibrateParameter);
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public class NeedlePrintCalibrateParameter : PropertyChangedBase, IParameterItem
|
||||
{
|
||||
private MPoint _startPoint = new MPoint();
|
||||
public MPoint StartPoint
|
||||
{
|
||||
get { return _startPoint; }
|
||||
set { SetAndNotify(ref _startPoint, value); }
|
||||
}
|
||||
|
||||
private MPoint _endPoint = new MPoint();
|
||||
public MPoint EndPoint
|
||||
{
|
||||
get { return _endPoint; }
|
||||
set { SetAndNotify(ref _endPoint, value); }
|
||||
}
|
||||
|
||||
private MPoint _avoidancePoint = new MPoint();
|
||||
|
||||
public MPoint AvoidancePoint
|
||||
{
|
||||
get { return _avoidancePoint; }
|
||||
set { SetAndNotify(ref _avoidancePoint, value); }
|
||||
}
|
||||
|
||||
private double _z1WorkHeight;
|
||||
|
||||
public double Z1WorkHeight
|
||||
{
|
||||
get { return _z1WorkHeight; }
|
||||
set { SetAndNotify(ref _z1WorkHeight, value); }
|
||||
}
|
||||
|
||||
private double _z2WorkHeight;
|
||||
|
||||
public double Z2WorkHeight
|
||||
{
|
||||
get { return _z2WorkHeight; }
|
||||
set { SetAndNotify(ref _z2WorkHeight, value); }
|
||||
}
|
||||
|
||||
private double _xPitch;
|
||||
|
||||
public double Xpitch
|
||||
{
|
||||
get { return _xPitch; }
|
||||
set { SetAndNotify(ref _xPitch, value); }
|
||||
}
|
||||
|
||||
private double _yPitch;
|
||||
|
||||
public double Ypitch
|
||||
{
|
||||
get { return _yPitch; }
|
||||
set { SetAndNotify(ref _yPitch, value); }
|
||||
}
|
||||
|
||||
private int _usedNum;
|
||||
|
||||
public int UsedNum
|
||||
{
|
||||
get { return _usedNum; }
|
||||
set { SetAndNotify(ref _usedNum, value); }
|
||||
}
|
||||
|
||||
private int _sleepTime = 1000;
|
||||
public int SleepTime
|
||||
{
|
||||
get { return _sleepTime; }
|
||||
set { SetAndNotify(ref _sleepTime, value); }
|
||||
}
|
||||
|
||||
public IParameterItem Clone()
|
||||
{
|
||||
return MemberwiseClone() as NeedlePrintCalibrateParameter;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,109 @@
|
||||
<UserControl x:Class="MainShell.DeviceMaintance.View.CameraAccuracyCalibrationView"
|
||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||
xmlns:local="clr-namespace:MainShell.DeviceMaintance.View"
|
||||
xmlns:mwControls="http://www.maxwell-gp.com/"
|
||||
xmlns:customControl="clr-namespace:MainShell.Resources.CustomControl"
|
||||
mc:Ignorable="d"
|
||||
d:DesignHeight="450" d:DesignWidth="700">
|
||||
<UserControl.Resources>
|
||||
<Style TargetType="GroupBox" BasedOn="{StaticResource GroupStepControl}"/>
|
||||
<Style TargetType="Label" BasedOn="{StaticResource {x:Type Label}}">
|
||||
<Setter Property="HorizontalContentAlignment" Value="Right"/>
|
||||
<Setter Property="VerticalContentAlignment" Value="Center"/>
|
||||
<Setter Property="HorizontalAlignment" Value="Right"/>
|
||||
<Setter Property="Margin" Value="5"/>
|
||||
<Setter Property="Height" Value="35"/>
|
||||
</Style>
|
||||
<Style TargetType="Button" BasedOn="{StaticResource {x:Type Button}}" >
|
||||
<Setter Property="VerticalAlignment" Value="Center"/>
|
||||
<Setter Property="HorizontalAlignment" Value="Center"/>
|
||||
<Setter Property="Margin" Value="3"/>
|
||||
<Setter Property="Height" Value="35"/>
|
||||
<Setter Property="Width" Value="90"/>
|
||||
</Style>
|
||||
</UserControl.Resources>
|
||||
<Grid mwControls:ParameterAttach.DelayAcceptValue ="{Binding ParameterHelper}">
|
||||
<StackPanel>
|
||||
<GroupBox IsEnabled="{Binding UiEnable}" Header="【第一步】针尖高度设置">
|
||||
<customControl:AxisMoveControl LableContent1="Z1(mm):"
|
||||
Value1="{Binding QuickNeedlePrintParameter.Z1InkHeight}"
|
||||
IsAllShow="False"
|
||||
ReadCommand="{mwControls:Action TeachZ1Pos}"
|
||||
IsReadOnly="False"
|
||||
MoveCommand="{mwControls:Action MoveToZ1Pos}"/>
|
||||
|
||||
</GroupBox>
|
||||
<GroupBox IsEnabled="{Binding UiEnable}" Header="【第二步】WS避让位">
|
||||
<GroupBox.Content>
|
||||
<customControl:AxisMoveControl LableContent1="X2(mm):"
|
||||
Value1="{Binding QuickNeedlePrintParameter.AvoidancePoint.PointX}"
|
||||
LableContent2="Y2(mm):"
|
||||
Value2="{Binding QuickNeedlePrintParameter.AvoidancePoint.PointY}"
|
||||
ReadCommand="{mwControls:Action TeachWSPos}"
|
||||
MoveCommand="{mwControls:Action MoveToWsPos}"
|
||||
IsReadOnly="True"/>
|
||||
<!--<StackPanel Orientation="Horizontal" HorizontalAlignment="Left">
|
||||
<Label VerticalAlignment="Center" Content="X2:"/>
|
||||
<mwControls:NumberBox Value="{Binding QuickNeedlePrintParameter.AvoidancePoint.PointX}" IsReadOnly="True" Width="80" Margin="4,0" />
|
||||
<Label VerticalAlignment="Center" Content="Y2:"/>
|
||||
<mwControls:NumberBox Value="{Binding QuickNeedlePrintParameter.AvoidancePoint.PointY}" IsReadOnly="True" Width="80" Margin="4,0" />
|
||||
<Button Margin="2,0" Click="{mwControls:Action TeachWSPos}" Content="示教"/>
|
||||
<Button Margin="2,0" Click="{mwControls:Action MoveToWsPos}" Content="移动"/>
|
||||
</StackPanel>-->
|
||||
</GroupBox.Content>
|
||||
</GroupBox>
|
||||
<GroupBox IsEnabled="{Binding UiEnable}" Margin="2" Header="【第三步】墨水位置">
|
||||
<GroupBox.Content>
|
||||
<Grid>
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="Auto"/>
|
||||
<ColumnDefinition Width="Auto"/>
|
||||
</Grid.ColumnDefinitions>
|
||||
<customControl:AxisMoveControl LableContent1="X2(mm):"
|
||||
Value1="{Binding QuickNeedlePrintParameter.InkPos.PointX}"
|
||||
LableContent2="Y2(mm):"
|
||||
Value2="{Binding QuickNeedlePrintParameter.InkPos.PointY}"
|
||||
ReadCommand="{mwControls:Action TeachInkPos}"
|
||||
MoveCommand="{mwControls:Action MoveToInkPos}"
|
||||
IsReadOnly="True"/>
|
||||
|
||||
<Button Margin="2,0" HorizontalAlignment="Right" Click="{mwControls:Action InkSmearing}" Content="涂墨"/>
|
||||
</Grid>
|
||||
</GroupBox.Content>
|
||||
</GroupBox>
|
||||
<GroupBox Header="【第四步】快打针印参数设置">
|
||||
<StackPanel>
|
||||
<StackPanel Orientation="Horizontal">
|
||||
<Label VerticalAlignment="Center" HorizontalAlignment="Left" Content="打件颗数:"/>
|
||||
<mwControls:IntNumberBox Value="{Binding BondingNumber}" IsReadOnly="True" Width="75" Margin="4,0" />
|
||||
<Button IsEnabled="{Binding UiEnable}" Margin="2,0" Click="{mwControls:Action PositiveBonding}" Content="快打正向"/>
|
||||
<Button IsEnabled="{Binding UiEnable}" Margin="2,0" Click="{mwControls:Action NegativeBonding}" Content="快打反向"/>
|
||||
<Button IsEnabled="{Binding UiEnable}" Margin="2,0" Click="{mwControls:Action SlowBonding}" Content="补打"/>
|
||||
<Button Margin="2,0" Content="停止打件" Click="{mwControls:Action StopBonding}"/>
|
||||
</StackPanel>
|
||||
<Label Content="正向针印查看:" HorizontalAlignment="Left"/>
|
||||
<StackPanel IsEnabled="{Binding UiEnable}" HorizontalAlignment="Left" Orientation="Horizontal">
|
||||
<Button Margin="2,0" IsEnabled="{Binding CanLastPositiveIndex}" Click="{mwControls:Action LastPositiveIndex}" Content="上一个"/>
|
||||
<Button Margin="2,0" IsEnabled="{Binding CanNextPositiveIndex}" Click="{mwControls:Action NextPositiveIndex}" Content="下一个"/>
|
||||
</StackPanel>
|
||||
<Label Content="反向针印查看:" HorizontalAlignment="Left"/>
|
||||
<StackPanel IsEnabled="{Binding UiEnable}" HorizontalAlignment="Left" Orientation="Horizontal">
|
||||
<Button Margin="2,0" IsEnabled="{Binding CanLastNegativeIndex}" Click="{mwControls:Action LastNegativeIndex}" Content="上一个"/>
|
||||
<Button Margin="2,0" IsEnabled="{Binding CanNextNegativeIndex}" Click="{mwControls:Action NextNegativeIndex}" Content="下一个"/>
|
||||
</StackPanel>
|
||||
<Label Content="补打针印查看:" HorizontalAlignment="Left"/>
|
||||
<StackPanel IsEnabled="{Binding UiEnable}" HorizontalAlignment="Left" Orientation="Horizontal">
|
||||
<Button Margin="2,0" IsEnabled="{Binding CanLastSlowIndex}" Click="{mwControls:Action LastSlowIndex}" Content="上一个"/>
|
||||
<Button Margin="2,0" IsEnabled="{Binding CanNextSlowIndex}" Click="{mwControls:Action NextSlowIndex}" Content="下一个"/>
|
||||
</StackPanel>
|
||||
<Button IsEnabled="{Binding UiEnable}" HorizontalAlignment="Right" Click="{mwControls:Action SaveParameter}" Margin="10,2" Content="保存"/>
|
||||
</StackPanel>
|
||||
|
||||
</GroupBox>
|
||||
</StackPanel>
|
||||
|
||||
</Grid>
|
||||
</UserControl>
|
||||
@@ -0,0 +1,28 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using System.Windows;
|
||||
using System.Windows.Controls;
|
||||
using System.Windows.Data;
|
||||
using System.Windows.Documents;
|
||||
using System.Windows.Input;
|
||||
using System.Windows.Media;
|
||||
using System.Windows.Media.Imaging;
|
||||
using System.Windows.Navigation;
|
||||
using System.Windows.Shapes;
|
||||
|
||||
namespace MainShell.DeviceMaintance.View
|
||||
{
|
||||
/// <summary>
|
||||
/// CameraAccuracyCalibrationView.xaml 的交互逻辑
|
||||
/// </summary>
|
||||
public partial class CameraAccuracyCalibrationView : UserControl
|
||||
{
|
||||
public CameraAccuracyCalibrationView()
|
||||
{
|
||||
InitializeComponent();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,176 @@
|
||||
<UserControl x:Class="MainShell.DeviceMaintance.View.CylinderView"
|
||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||
xmlns:local="clr-namespace:MainShell.DeviceMaintance.View"
|
||||
mc:Ignorable="d"
|
||||
d:DesignHeight="450" d:DesignWidth="800">
|
||||
<UserControl.Resources>
|
||||
<Style x:Key="CylinderCardStyle" TargetType="Border">
|
||||
<Setter Property="Background" Value="#F8FAFD"/>
|
||||
<Setter Property="BorderBrush" Value="#D4DCE8"/>
|
||||
<Setter Property="BorderThickness" Value="1"/>
|
||||
<Setter Property="CornerRadius" Value="8"/>
|
||||
<Setter Property="Padding" Value="14"/>
|
||||
<Setter Property="Margin" Value="0,0,0,12"/>
|
||||
</Style>
|
||||
|
||||
<Style x:Key="CylinderDotStyle" TargetType="Ellipse">
|
||||
<Setter Property="Width" Value="10"/>
|
||||
<Setter Property="Height" Value="10"/>
|
||||
<Setter Property="Fill" Value="#CBD5E1"/>
|
||||
<Style.Triggers>
|
||||
<DataTrigger Binding="{Binding IsOn}" Value="True">
|
||||
<Setter Property="Fill" Value="#22C55E"/>
|
||||
</DataTrigger>
|
||||
</Style.Triggers>
|
||||
</Style>
|
||||
|
||||
<Style x:Key="CylinderActionButtonStyle" TargetType="Button">
|
||||
<Setter Property="Foreground" Value="White"/>
|
||||
<Setter Property="Padding" Value="12,6"/>
|
||||
<Setter Property="MinWidth" Value="90"/>
|
||||
<Setter Property="FontWeight" Value="Bold"/>
|
||||
<Setter Property="Margin" Value="0,0,8,0"/>
|
||||
<Setter Property="BorderThickness" Value="0"/>
|
||||
<Setter Property="Template">
|
||||
<Setter.Value>
|
||||
<ControlTemplate TargetType="Button">
|
||||
<Border Background="{TemplateBinding Background}"
|
||||
CornerRadius="18"
|
||||
Padding="{TemplateBinding Padding}">
|
||||
<ContentPresenter HorizontalAlignment="Center"
|
||||
VerticalAlignment="Center"/>
|
||||
</Border>
|
||||
</ControlTemplate>
|
||||
</Setter.Value>
|
||||
</Setter>
|
||||
</Style>
|
||||
</UserControl.Resources>
|
||||
|
||||
<Grid Background="#EDF1F7">
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition Height="Auto"/>
|
||||
<RowDefinition Height="*"/>
|
||||
</Grid.RowDefinitions>
|
||||
|
||||
<StackPanel Margin="12,12,12,8">
|
||||
<TextBlock Text="CYLINDER CONTROL / 气缸控制" FontSize="20" FontWeight="Bold" Foreground="#0F3B7A"/>
|
||||
<Border Background="#EFF6FF" BorderBrush="#BFDBFE" BorderThickness="1" CornerRadius="6" Padding="10" Margin="0,8,0,0">
|
||||
<StackPanel Orientation="Horizontal">
|
||||
<TextBlock Text="最近操作:" Foreground="#475569" Margin="0,0,8,0"/>
|
||||
<TextBlock Text="{Binding PageState.LastActionTime, StringFormat={}{0:HH:mm:ss}}" Foreground="#0F172A" FontWeight="Bold" Margin="0,0,12,0"/>
|
||||
<TextBlock Text="{Binding PageState.LastActionMessage}" Foreground="#1D4ED8" FontWeight="SemiBold" TextWrapping="Wrap"/>
|
||||
</StackPanel>
|
||||
</Border>
|
||||
</StackPanel>
|
||||
|
||||
<ScrollViewer Grid.Row="1" Margin="12,0,12,12" VerticalScrollBarVisibility="Auto">
|
||||
<ItemsControl ItemsSource="{Binding PageState.Cylinders}">
|
||||
<ItemsControl.ItemTemplate>
|
||||
<DataTemplate>
|
||||
<Border Style="{StaticResource CylinderCardStyle}">
|
||||
<Grid>
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition Height="Auto"/>
|
||||
<RowDefinition Height="Auto"/>
|
||||
</Grid.RowDefinitions>
|
||||
|
||||
<Grid>
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="*"/>
|
||||
<ColumnDefinition Width="Auto"/>
|
||||
</Grid.ColumnDefinitions>
|
||||
<StackPanel>
|
||||
<TextBlock Text="{Binding Name}" FontSize="18" FontWeight="Bold" Foreground="#0F3B7A"/>
|
||||
<TextBlock Text="{Binding Description}" Foreground="#64748B" Margin="0,4,0,0"/>
|
||||
</StackPanel>
|
||||
<Border Grid.Column="1" Background="#FEF3C7" CornerRadius="12" Padding="10,4" VerticalAlignment="Center">
|
||||
<TextBlock Text="{Binding ControlTypeText}" Foreground="#92400E" FontWeight="Bold"/>
|
||||
</Border>
|
||||
</Grid>
|
||||
|
||||
<Grid Grid.Row="1" Margin="0,12,0,0">
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="Auto"/>
|
||||
<ColumnDefinition Width="*"/>
|
||||
<ColumnDefinition Width="*"/>
|
||||
</Grid.ColumnDefinitions>
|
||||
|
||||
<StackPanel Margin="0,0,16,0">
|
||||
<TextBlock Text="控制" Foreground="#1D4ED8" FontWeight="Bold" Margin="0,0,0,8"/>
|
||||
<StackPanel Orientation="Horizontal">
|
||||
<Button Content="伸出"
|
||||
Command="{Binding ExtendCommand}"
|
||||
Background="#2563EB"
|
||||
BorderBrush="#2563EB"
|
||||
Style="{StaticResource CylinderActionButtonStyle}"/>
|
||||
<Button Content="缩回"
|
||||
Command="{Binding RetractCommand}"
|
||||
Background="#F97316"
|
||||
BorderBrush="#F97316"
|
||||
Style="{StaticResource CylinderActionButtonStyle}"/>
|
||||
</StackPanel>
|
||||
</StackPanel>
|
||||
|
||||
<StackPanel Grid.Column="1" Margin="0,0,16,0">
|
||||
<TextBlock Text="输出信号" Foreground="#C2410C" FontWeight="Bold" Margin="0,0,0,8"/>
|
||||
<ItemsControl ItemsSource="{Binding OutputSignals}">
|
||||
<ItemsControl.ItemTemplate>
|
||||
<DataTemplate>
|
||||
<Border Background="#FFF7ED" BorderBrush="#FED7AA" BorderThickness="1" CornerRadius="4" Padding="8,6" Margin="0,0,0,6">
|
||||
<Grid>
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="Auto"/>
|
||||
<ColumnDefinition Width="*"/>
|
||||
<ColumnDefinition Width="Auto"/>
|
||||
</Grid.ColumnDefinitions>
|
||||
<Ellipse Style="{StaticResource CylinderDotStyle}" VerticalAlignment="Center" Margin="0,0,8,0"/>
|
||||
<StackPanel Grid.Column="1">
|
||||
<TextBlock Text="{Binding Name}" Foreground="#9A3412" FontWeight="SemiBold"/>
|
||||
<TextBlock Text="{Binding IoNameText}" Foreground="#7C2D12" FontSize="11" TextWrapping="Wrap"/>
|
||||
<TextBlock Text="{Binding LineNo, StringFormat=线标:{0}}" Foreground="#C2410C" FontSize="11"/>
|
||||
</StackPanel>
|
||||
<TextBlock Grid.Column="2" Text="{Binding StateText}" Foreground="#C2410C" FontWeight="Bold"/>
|
||||
</Grid>
|
||||
</Border>
|
||||
</DataTemplate>
|
||||
</ItemsControl.ItemTemplate>
|
||||
</ItemsControl>
|
||||
</StackPanel>
|
||||
|
||||
<StackPanel Grid.Column="2">
|
||||
<TextBlock Text="反馈信号" Foreground="#166534" FontWeight="Bold" Margin="0,0,0,8"/>
|
||||
<ItemsControl ItemsSource="{Binding FeedbackSignals}">
|
||||
<ItemsControl.ItemTemplate>
|
||||
<DataTemplate>
|
||||
<Border Background="#F0FDF4" BorderBrush="#BBF7D0" BorderThickness="1" CornerRadius="4" Padding="8,6" Margin="0,0,0,6">
|
||||
<Grid>
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="Auto"/>
|
||||
<ColumnDefinition Width="*"/>
|
||||
<ColumnDefinition Width="Auto"/>
|
||||
</Grid.ColumnDefinitions>
|
||||
<Ellipse Style="{StaticResource CylinderDotStyle}" VerticalAlignment="Center" Margin="0,0,8,0"/>
|
||||
<StackPanel Grid.Column="1">
|
||||
<TextBlock Text="{Binding Name}" Foreground="#166534" FontWeight="SemiBold"/>
|
||||
<TextBlock Text="{Binding IoNameText}" Foreground="#15803D" FontSize="11" TextWrapping="Wrap"/>
|
||||
<TextBlock Text="{Binding LineNo, StringFormat=线标:{0}}" Foreground="#15803D" FontSize="11"/>
|
||||
</StackPanel>
|
||||
<TextBlock Grid.Column="2" Text="{Binding StateText}" Foreground="#166534" FontWeight="Bold"/>
|
||||
</Grid>
|
||||
</Border>
|
||||
</DataTemplate>
|
||||
</ItemsControl.ItemTemplate>
|
||||
</ItemsControl>
|
||||
</StackPanel>
|
||||
</Grid>
|
||||
</Grid>
|
||||
</Border>
|
||||
</DataTemplate>
|
||||
</ItemsControl.ItemTemplate>
|
||||
</ItemsControl>
|
||||
</ScrollViewer>
|
||||
</Grid>
|
||||
</UserControl>
|
||||
@@ -0,0 +1,28 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using System.Windows;
|
||||
using System.Windows.Controls;
|
||||
using System.Windows.Data;
|
||||
using System.Windows.Documents;
|
||||
using System.Windows.Input;
|
||||
using System.Windows.Media;
|
||||
using System.Windows.Media.Imaging;
|
||||
using System.Windows.Navigation;
|
||||
using System.Windows.Shapes;
|
||||
|
||||
namespace MainShell.DeviceMaintance.View
|
||||
{
|
||||
/// <summary>
|
||||
/// CylinderView.xaml 的交互逻辑
|
||||
/// </summary>
|
||||
public partial class CylinderView : UserControl
|
||||
{
|
||||
public CylinderView()
|
||||
{
|
||||
InitializeComponent();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,310 @@
|
||||
<UserControl x:Class="MainShell.DeviceMaintance.View.DeviceIoView"
|
||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||
mc:Ignorable="d"
|
||||
d:DesignHeight="450" d:DesignWidth="900">
|
||||
<UserControl.Resources>
|
||||
<Style x:Key="IoCardStyle" TargetType="Border">
|
||||
<Setter Property="Background" Value="#F8FAFD"/>
|
||||
<Setter Property="BorderBrush" Value="#D4DCE8"/>
|
||||
<Setter Property="BorderThickness" Value="1"/>
|
||||
<Setter Property="CornerRadius" Value="8"/>
|
||||
<Setter Property="Margin" Value="0,0,0,12"/>
|
||||
<Setter Property="Padding" Value="14"/>
|
||||
</Style>
|
||||
|
||||
<Style x:Key="StatusBadgeBorderStyle" TargetType="Border">
|
||||
<Setter Property="CornerRadius" Value="12"/>
|
||||
<Setter Property="Padding" Value="10,4"/>
|
||||
<Setter Property="Margin" Value="0,0,8,0"/>
|
||||
<Setter Property="Background" Value="#E2E8F0"/>
|
||||
</Style>
|
||||
|
||||
<Style x:Key="InputStatusDotStyle" TargetType="Ellipse">
|
||||
<Setter Property="Width" Value="10"/>
|
||||
<Setter Property="Height" Value="10"/>
|
||||
<Setter Property="Fill" Value="#93C5FD"/>
|
||||
<Style.Triggers>
|
||||
<DataTrigger Binding="{Binding IsOn}" Value="True">
|
||||
<Setter Property="Fill" Value="#2563EB"/>
|
||||
</DataTrigger>
|
||||
</Style.Triggers>
|
||||
</Style>
|
||||
|
||||
<Style x:Key="OutputStatusDotStyle" TargetType="Ellipse">
|
||||
<Setter Property="Width" Value="10"/>
|
||||
<Setter Property="Height" Value="10"/>
|
||||
<Setter Property="Fill" Value="#FCD34D"/>
|
||||
<Style.Triggers>
|
||||
<DataTrigger Binding="{Binding IsOn}" Value="True">
|
||||
<Setter Property="Fill" Value="#F97316"/>
|
||||
</DataTrigger>
|
||||
</Style.Triggers>
|
||||
</Style>
|
||||
|
||||
<Style x:Key="InputItemBorderStyle" TargetType="Border">
|
||||
<Setter Property="Background" Value="#EFF6FF"/>
|
||||
<Setter Property="BorderBrush" Value="#DBEAFE"/>
|
||||
<Setter Property="BorderThickness" Value="0,0,0,1"/>
|
||||
<Setter Property="Padding" Value="8,6"/>
|
||||
<Setter Property="Margin" Value="0,0,0,4"/>
|
||||
<Setter Property="CornerRadius" Value="4"/>
|
||||
</Style>
|
||||
|
||||
<Style x:Key="OutputItemBorderStyle" TargetType="Border">
|
||||
<Setter Property="Background" Value="#FFF7ED"/>
|
||||
<Setter Property="BorderBrush" Value="#FED7AA"/>
|
||||
<Setter Property="BorderThickness" Value="0,0,0,1"/>
|
||||
<Setter Property="Padding" Value="8,6"/>
|
||||
<Setter Property="Margin" Value="0,0,0,4"/>
|
||||
<Setter Property="CornerRadius" Value="4"/>
|
||||
</Style>
|
||||
|
||||
<Style x:Key="IoSectionBorderStyle" TargetType="Border">
|
||||
<Setter Property="CornerRadius" Value="6"/>
|
||||
<Setter Property="BorderThickness" Value="1"/>
|
||||
<Setter Property="Padding" Value="10"/>
|
||||
</Style>
|
||||
|
||||
<Style x:Key="IoOutputToggleButtonStyle" TargetType="ToggleButton">
|
||||
<Setter Property="Width" Value="90"/>
|
||||
<Setter Property="Height" Value="30"/>
|
||||
<Setter Property="Cursor" Value="Hand"/>
|
||||
<Setter Property="Foreground" Value="White"/>
|
||||
<Setter Property="FontWeight" Value="Bold"/>
|
||||
<Setter Property="Template">
|
||||
<Setter.Value>
|
||||
<ControlTemplate TargetType="ToggleButton">
|
||||
<Border x:Name="Root" Background="#CBD5E1" BorderBrush="#94A3B8" BorderThickness="1" CornerRadius="15">
|
||||
<Grid Margin="2">
|
||||
<Border x:Name="Knob" Width="24" Height="24" Background="White" CornerRadius="12" HorizontalAlignment="Left"/>
|
||||
<TextBlock x:Name="ToggleLabel" Text="OFF" Foreground="#334155" FontWeight="Bold" VerticalAlignment="Center" HorizontalAlignment="Right" Margin="0,0,10,0"/>
|
||||
</Grid>
|
||||
</Border>
|
||||
<ControlTemplate.Triggers>
|
||||
<Trigger Property="IsChecked" Value="True">
|
||||
<Setter TargetName="Root" Property="Background" Value="#16A34A"/>
|
||||
<Setter TargetName="Root" Property="BorderBrush" Value="#16A34A"/>
|
||||
<Setter TargetName="Knob" Property="HorizontalAlignment" Value="Right"/>
|
||||
<Setter TargetName="ToggleLabel" Property="Text" Value="ON"/>
|
||||
<Setter TargetName="ToggleLabel" Property="Foreground" Value="White"/>
|
||||
<Setter TargetName="ToggleLabel" Property="HorizontalAlignment" Value="Left"/>
|
||||
<Setter TargetName="ToggleLabel" Property="Margin" Value="10,0,0,0"/>
|
||||
</Trigger>
|
||||
<Trigger Property="IsEnabled" Value="False">
|
||||
<Setter TargetName="Root" Property="Opacity" Value="0.45"/>
|
||||
</Trigger>
|
||||
</ControlTemplate.Triggers>
|
||||
</ControlTemplate>
|
||||
</Setter.Value>
|
||||
</Setter>
|
||||
</Style>
|
||||
</UserControl.Resources>
|
||||
|
||||
<Grid Background="#EDF1F7">
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition Height="Auto"/>
|
||||
<RowDefinition Height="*"/>
|
||||
</Grid.RowDefinitions>
|
||||
|
||||
<StackPanel Margin="10,10,10,8">
|
||||
<Grid>
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="*"/>
|
||||
<ColumnDefinition Width="Auto"/>
|
||||
</Grid.ColumnDefinitions>
|
||||
<TextBlock Text="DEVICE IO MONITOR / 设备IO监控" FontSize="20" FontWeight="Bold" Foreground="#0F3B7A"/>
|
||||
<StackPanel Grid.Column="1" Orientation="Horizontal" VerticalAlignment="Center">
|
||||
<Border Style="{StaticResource StatusBadgeBorderStyle}">
|
||||
<TextBlock Text="{Binding PageState.LastRefreshTime, StringFormat=刷新:{0:HH:mm:ss}}" Foreground="#475569"/>
|
||||
</Border>
|
||||
<Border>
|
||||
<Border.Style>
|
||||
<Style TargetType="Border" BasedOn="{StaticResource StatusBadgeBorderStyle}">
|
||||
<Style.Triggers>
|
||||
<DataTrigger Binding="{Binding PageState.IsOnline}" Value="True">
|
||||
<Setter Property="Background" Value="#DCFCE7"/>
|
||||
</DataTrigger>
|
||||
<DataTrigger Binding="{Binding PageState.IsOnline}" Value="False">
|
||||
<Setter Property="Background" Value="#FEE2E2"/>
|
||||
</DataTrigger>
|
||||
</Style.Triggers>
|
||||
</Style>
|
||||
</Border.Style>
|
||||
<TextBlock Text="{Binding PageState.OnlineText}">
|
||||
<TextBlock.Style>
|
||||
<Style TargetType="TextBlock">
|
||||
<Setter Property="Foreground" Value="#B91C1C"/>
|
||||
<Style.Triggers>
|
||||
<DataTrigger Binding="{Binding PageState.IsOnline}" Value="True">
|
||||
<Setter Property="Foreground" Value="#166534"/>
|
||||
</DataTrigger>
|
||||
</Style.Triggers>
|
||||
</Style>
|
||||
</TextBlock.Style>
|
||||
</TextBlock>
|
||||
</Border>
|
||||
</StackPanel>
|
||||
</Grid>
|
||||
|
||||
<Border Margin="0,8,0,0" Padding="12,6">
|
||||
<Border.Style>
|
||||
<Style TargetType="Border" BasedOn="{StaticResource StatusBadgeBorderStyle}">
|
||||
<Setter Property="Background" Value="#EFF6FF"/>
|
||||
<Style.Triggers>
|
||||
<DataTrigger Binding="{Binding PageState.IsWriteSuccess}" Value="True">
|
||||
<Setter Property="Background" Value="#DCFCE7"/>
|
||||
</DataTrigger>
|
||||
<DataTrigger Binding="{Binding PageState.IsWriteSuccess}" Value="False">
|
||||
<Setter Property="Background" Value="#FEF3C7"/>
|
||||
</DataTrigger>
|
||||
</Style.Triggers>
|
||||
</Style>
|
||||
</Border.Style>
|
||||
<StackPanel Orientation="Horizontal">
|
||||
<TextBlock Text="{Binding PageState.LastWriteTime, StringFormat=写入时间:{0:HH:mm:ss}}" Foreground="#475569" Margin="0,0,14,0"/>
|
||||
<TextBlock Text="{Binding PageState.LastWriteMessage}" FontWeight="SemiBold" TextWrapping="Wrap"/>
|
||||
</StackPanel>
|
||||
</Border>
|
||||
</StackPanel>
|
||||
|
||||
<ScrollViewer Grid.Row="1" Margin="10,0,10,10" VerticalScrollBarVisibility="Auto">
|
||||
<ItemsControl ItemsSource="{Binding PageState.Modules}">
|
||||
<ItemsControl.ItemTemplate>
|
||||
<DataTemplate>
|
||||
<Border Style="{StaticResource IoCardStyle}">
|
||||
<Grid>
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition Height="Auto"/>
|
||||
<RowDefinition Height="Auto"/>
|
||||
</Grid.RowDefinitions>
|
||||
<TextBlock Text="{Binding Name}" FontSize="18" FontWeight="Bold" Foreground="#0F3B7A"/>
|
||||
|
||||
<Grid Grid.Row="1" Margin="0,10,0,0">
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition>
|
||||
<ColumnDefinition.Style>
|
||||
<Style TargetType="ColumnDefinition">
|
||||
<Setter Property="Width" Value="*"/>
|
||||
<Style.Triggers>
|
||||
<DataTrigger Binding="{Binding HasInputs}" Value="False">
|
||||
<Setter Property="Width" Value="0"/>
|
||||
</DataTrigger>
|
||||
</Style.Triggers>
|
||||
</Style>
|
||||
</ColumnDefinition.Style>
|
||||
</ColumnDefinition>
|
||||
<ColumnDefinition>
|
||||
<ColumnDefinition.Style>
|
||||
<Style TargetType="ColumnDefinition">
|
||||
<Setter Property="Width" Value="*"/>
|
||||
<Style.Triggers>
|
||||
<DataTrigger Binding="{Binding HasOutputs}" Value="False">
|
||||
<Setter Property="Width" Value="0"/>
|
||||
</DataTrigger>
|
||||
</Style.Triggers>
|
||||
</Style>
|
||||
</ColumnDefinition.Style>
|
||||
</ColumnDefinition>
|
||||
</Grid.ColumnDefinitions>
|
||||
|
||||
<Border BorderBrush="#BFDBFE" Background="#F8FBFF">
|
||||
<Border.Style>
|
||||
<Style TargetType="Border" BasedOn="{StaticResource IoSectionBorderStyle}">
|
||||
<Setter Property="Margin" Value="0,0,6,0"/>
|
||||
<Style.Triggers>
|
||||
<DataTrigger Binding="{Binding HasInputs}" Value="False">
|
||||
<Setter Property="Visibility" Value="Collapsed"/>
|
||||
</DataTrigger>
|
||||
<DataTrigger Binding="{Binding HasOutputs}" Value="False">
|
||||
<Setter Property="Margin" Value="0"/>
|
||||
</DataTrigger>
|
||||
</Style.Triggers>
|
||||
</Style>
|
||||
</Border.Style>
|
||||
<StackPanel>
|
||||
<TextBlock Text="输入 IO" Foreground="#1D4ED8" FontWeight="Bold" Margin="0,0,0,8"/>
|
||||
<ItemsControl ItemsSource="{Binding InputPoints}">
|
||||
<ItemsControl.ItemTemplate>
|
||||
<DataTemplate>
|
||||
<Border Style="{StaticResource InputItemBorderStyle}">
|
||||
<Grid>
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="Auto"/>
|
||||
<ColumnDefinition Width="*"/>
|
||||
<ColumnDefinition Width="Auto"/>
|
||||
</Grid.ColumnDefinitions>
|
||||
<Ellipse Style="{StaticResource InputStatusDotStyle}" VerticalAlignment="Center" Margin="0,0,8,0"/>
|
||||
<StackPanel Grid.Column="1">
|
||||
<TextBlock Text="{Binding Description}" Foreground="#1E3A8A" FontWeight="SemiBold"/>
|
||||
<TextBlock Text="{Binding StationNo, StringFormat=站号:{0}}" Foreground="#1D4ED8" FontSize="11"/>
|
||||
<TextBlock Text="{Binding LineNo, StringFormat=线标:{0}}" Foreground="#1D4ED8" FontSize="11"/>
|
||||
<TextBlock Text="{Binding Name}" Foreground="#64748B" FontSize="11" TextWrapping="Wrap"/>
|
||||
</StackPanel>
|
||||
<TextBlock Grid.Column="2" Text="{Binding StateText}" VerticalAlignment="Center" Foreground="#1E40AF" FontWeight="Bold"/>
|
||||
</Grid>
|
||||
</Border>
|
||||
</DataTemplate>
|
||||
</ItemsControl.ItemTemplate>
|
||||
</ItemsControl>
|
||||
</StackPanel>
|
||||
</Border>
|
||||
|
||||
<Border Grid.Column="1" BorderBrush="#FDBA74" Background="#FFF9F2">
|
||||
<Border.Style>
|
||||
<Style TargetType="Border" BasedOn="{StaticResource IoSectionBorderStyle}">
|
||||
<Setter Property="Margin" Value="6,0,0,0"/>
|
||||
<Style.Triggers>
|
||||
<DataTrigger Binding="{Binding HasOutputs}" Value="False">
|
||||
<Setter Property="Visibility" Value="Collapsed"/>
|
||||
</DataTrigger>
|
||||
<DataTrigger Binding="{Binding HasInputs}" Value="False">
|
||||
<Setter Property="Margin" Value="0"/>
|
||||
</DataTrigger>
|
||||
</Style.Triggers>
|
||||
</Style>
|
||||
</Border.Style>
|
||||
<StackPanel>
|
||||
<TextBlock Text="输出 IO" Foreground="#C2410C" FontWeight="Bold" Margin="0,0,0,8"/>
|
||||
<ItemsControl ItemsSource="{Binding OutputPoints}">
|
||||
<ItemsControl.ItemTemplate>
|
||||
<DataTemplate>
|
||||
<Border Style="{StaticResource OutputItemBorderStyle}">
|
||||
<Grid>
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="Auto"/>
|
||||
<ColumnDefinition Width="*"/>
|
||||
<ColumnDefinition Width="Auto"/>
|
||||
<ColumnDefinition Width="Auto"/>
|
||||
</Grid.ColumnDefinitions>
|
||||
<Ellipse Style="{StaticResource OutputStatusDotStyle}" VerticalAlignment="Center" Margin="0,0,8,0"/>
|
||||
<StackPanel Grid.Column="1">
|
||||
<TextBlock Text="{Binding Description}" Foreground="#9A3412" FontWeight="SemiBold"/>
|
||||
<TextBlock Text="{Binding StationNo, StringFormat=站号:{0}}" Foreground="#C2410C" FontSize="11"/>
|
||||
<TextBlock Text="{Binding LineNo, StringFormat=线标:{0}}" Foreground="#C2410C" FontSize="11"/>
|
||||
<TextBlock Text="{Binding Name}" Foreground="#7C2D12" FontSize="11" TextWrapping="Wrap"/>
|
||||
</StackPanel>
|
||||
<TextBlock Grid.Column="2" Text="{Binding StateText}" Margin="0,0,10,0" VerticalAlignment="Center" Foreground="#C2410C" FontWeight="Bold"/>
|
||||
<ToggleButton Grid.Column="3"
|
||||
Style="{StaticResource IoOutputToggleButtonStyle}"
|
||||
IsChecked="{Binding IsOn, Mode=OneWay}"
|
||||
Command="{Binding ToggleCommand}"
|
||||
IsEnabled="{Binding CanWrite}"/>
|
||||
</Grid>
|
||||
</Border>
|
||||
</DataTemplate>
|
||||
</ItemsControl.ItemTemplate>
|
||||
</ItemsControl>
|
||||
</StackPanel>
|
||||
</Border>
|
||||
</Grid>
|
||||
</Grid>
|
||||
</Border>
|
||||
</DataTemplate>
|
||||
</ItemsControl.ItemTemplate>
|
||||
</ItemsControl>
|
||||
</ScrollViewer>
|
||||
</Grid>
|
||||
</UserControl>
|
||||
@@ -0,0 +1,12 @@
|
||||
using System.Windows.Controls;
|
||||
|
||||
namespace MainShell.DeviceMaintance.View
|
||||
{
|
||||
public partial class DeviceIoView : UserControl
|
||||
{
|
||||
public DeviceIoView()
|
||||
{
|
||||
InitializeComponent();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,38 @@
|
||||
<UserControl x:Class="MainShell.DeviceMaintance.View.DeviceMaintanceView"
|
||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||
xmlns:local="clr-namespace:MainShell.DeviceMaintance.View"
|
||||
xmlns:mw="http://www.maxwell-gp.com/"
|
||||
mc:Ignorable="d"
|
||||
d:DesignHeight="450" d:DesignWidth="800">
|
||||
<Grid>
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="Auto"/>
|
||||
<ColumnDefinition Width="*"/>
|
||||
</Grid.ColumnDefinitions>
|
||||
<Grid Margin="-40,0,0,0" Grid.Column="0">
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition/>
|
||||
<RowDefinition Height="Auto"/>
|
||||
</Grid.RowDefinitions>
|
||||
<mw:SideMenu ItemsSource="{Binding MenuItemWraps}"
|
||||
SelectedItem="{Binding SelectedMenuItem, Mode=TwoWay}"
|
||||
Grid.Row ="0" Width="180"
|
||||
ExpandMode="Accordion"
|
||||
AutoSelect="True"
|
||||
>
|
||||
<mw:SideMenu.ItemContainerStyle>
|
||||
<Style TargetType="{x:Type mw:SideMenuItem}" BasedOn="{StaticResource SideMenuItemHeaderAccordionBaseStyle}">
|
||||
<Setter Property="Header" Value="{Binding Header}" />
|
||||
<Setter Property="Tag" Value="{Binding Tag}" />
|
||||
</Style>
|
||||
</mw:SideMenu.ItemContainerStyle>
|
||||
</mw:SideMenu>
|
||||
|
||||
</Grid>
|
||||
|
||||
<ContentControl Margin="5,0" Grid.Column="1" mw:View.Model="{Binding CurrentScreen}"/>
|
||||
</Grid>
|
||||
</UserControl>
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user