一、Tuple(元组)基础操作
1. 元组的概念
元组是 HALCON 中控制变量的数组形式,用于存储多个数据,支持整数、浮点数、字符串混合存放,是参数传递、批量数据处理的核心载体。
- 单个数值本质上是长度为 1 的元组
- 长度可动态变化,支持自动扩容
2. 元组的创建与赋值
(1)基础赋值
* 单个变量(长度为1的元组)
a := 1
b := 2
c := a + b // 运算后c = 3
* 直接定义多元素元组
a := [1, 2, 3]
* 初始化空元组
a := []
(2)索引赋值
通过下标修改 / 新增元素,索引从 0 开始;如果赋值的索引超过当前元组长度,中间空缺的位置会自动补 0(数值型元组)。
* 示例1:从单变量扩展元组
a := 1 // a = [1](索引0的值为1)
a[1] := 2 // a = [1, 2]
a[2] := 3 // a = [1, 2, 3]
a[4] := 5 // 索引3空缺自动补0 → a = [1, 2, 3, 0, 5]
* 示例2:空元组索引赋值
a := []
a[3] := 3 // 索引0-2自动补0 → a = [0, 0, 0, 3]
* 示例3:修改已有元素
a := [1, 2, 3]
a[1] := 4 // 修改索引1的元素 → a = [1, 4, 3]
3. 批量生成元组:tuple_gen_const
快速生成指定长度、所有元素值统一的元组,有两种书写形式:
算子调用形式
tuple_gen_const(Length, Const, Newtuple)
Length:元组长度(元素总个数)Const:每个元素的统一取值Newtuple:输出的结果元组
内联表达式形式
Newtuple := gen_tuple_const(Length, Const)
示例:
* 生成长度为10、所有元素都是5的元组
tuple_gen_const(10, 5, Newtuple)
* 等价的内联写法
Newtuple := gen_tuple_const(10, 5)
4. 元组特点
-
支持混合类型:同一个元组可以同时存放数字和字符串
c := [1, 2, 'hello'] -
动态扩容:赋值超出长度时自动扩展,空缺位自动补默认值
二、变量赋值与图像拷贝
1. 控制变量赋值
数值、字符串、元组等控制变量统一使用 := 赋值,支持直接写运算表达式。
2. 图像变量拷贝
HALCON 的图标变量(Image、Region、XLD)也可以通过 := 直接复制,得到独立的图像副本。
* 读取原始图像
read_image (Image, 'claudia')
* 复制得到独立副本
CopyImage := Image
执行后变量窗口会出现两个独立的图像对象,修改其中一个不会影响另一个。
三、条件分支结构(if 语句)
1. 单分支:if - endif
条件成立时执行内部代码,不成立则直接跳过。
a := -1
y := 0
if(a > 0)
y := 1
endif
// 结果:条件不满足,y保持为0
2. 双分支:if - else - endif
条件成立执行 if 代码块,不成立则执行 else 代码块。
a := -3
if(a > 0)
y := 1
else
y := -1
endif
// 结果:y = -1
3. 多分支:if - elseif - else - endif
从上到下依次判断条件,执行第一个满足的分支;所有条件都不满足时执行 else 块。
a := 0
if(a > 0)
y := 1
elseif(a == 0)
y := 0
else
y := -1
endif
// 结果:y = 0
4.switch 多分支结构
适用场景
当单个变量有多个固定取值、需要分别执行不同逻辑时,用 switch 替代多层 elseif,结构更清晰易读。
语法与核心规则
switch(判断变量)
case 取值1:
// 匹配后执行的代码
break // 终止并跳出switch;不写会向下穿透执行
case 取值2:
// 执行代码
break
default:
// 所有case都不匹配时,执行此处兜底逻辑
endswitch
关键特性:case 穿透
如果某个 case 分支末尾没有写 break,程序会继续执行下一个 case 的代码,直到遇到 break 或整个 switch 结束。
示例
result := ''
Index := 3
switch(Index)
case 1:
result := result + '1'
break
case 2:
result := result + '2'
break
case 3:
result := result + '3'
* 无break,向下穿透
case 4:
* 无break,继续穿透
case 5:
result := result + '5'
break
default:
result := '-1'
endswitch
执行结果:result = '35'
解释:
Index=3匹配case 3,执行后无break,依次穿透case 4,直到case 5遇到break才跳出,因此拼接了'3'和'5'。
5. 常用比较运算符
| 运算符 | 含义 | 说明 |
|---|---|---|
> / < |
大于 / 小于 | 数值大小比较 |
== / = |
等于 | 两种写法均有效 |
!= / # |
不等于 | 两种写法均有效 |
6. 逻辑运算符
用于组合多个条件,实现复合判断:
| 运算符 | 含义 | 规则 |
|---|---|---|
and |
逻辑与 | 所有条件同时为真,结果才为真 |
| or | 逻辑或 | 一个条件满足时即为真,同时不满足为假 |
xor |
逻辑异或 | 两个条件真假不同时结果为真,同真同假时为假 |
示例:
Tuple := 5
Value := 10
Result := 0
* and示例:两个条件都满足,Result赋值为1
if(Value > 9 and Tuple > 4)
Result := 1
endif
* xor示例:两边一真一假,结果为真
if(Value > 10 xor Tuple > 4)
Result := 1
endif
四、循环结构
1. for 循环:固定范围循环
适合已知循环次数的场景,按固定步长遍历数值区间。
语法
for 循环变量 := 起始值 to 结束值 by 步长
// 循环体
endfor
by 步长可省略,默认步长为 1- 循环变量自动按步长递增,超出结束值时自动退出循环
示例
* 示例1:步长为1,生成1~10的序列
array := []
for i := 1 to 10 by 1
* 方式1:索引赋值
array[i-1] := i
* 方式2:元组拼接追加
array := [array, i]
endfor
// 结果:array = [1,2,3,4,5,6,7,8,9,10]
* 示例2:步长为2,生成奇数序列
array := []
for i := 1 to 10 by 2
array := [array, i]
endfor
// 结果:array = [1,3,5,7,9]
2. 循环控制语句
(1)continue:跳过本次循环
遇到continue时,立刻结束本轮循环,直接进入下一轮,本次循环后续代码不执行。
(2)break:终止整个循环
遇到break时,立刻跳出整个 for 循环,不再执行后续所有轮次。
示例:
array := []
for i := 1 to 10 by 1
if(i == 3)
continue // 跳过i=3,不执行后续的追加操作
endif
if(i == 7)
break // i=7时直接终止整个循环
endif
array := [array, i]
endfor
// 结果:array = [1,2,4,5,6]
3. while 循环:条件控制循环
适合循环次数不确定、靠条件判断终止的场景,需要手动维护循环变量和退出条件。
语法
while(循环条件)
// 循环体
// 必须修改条件相关变量,否则会出现死循环
endwhile
示例:
Flag := 0
array := []
Number := 5
i := 0
while(Flag == 0)
if(i == Number)
Flag := 1 // 修改标志位,准备退出循环
endif
array := [array, i]
i := i + 1 // 循环变量自增
endwhile
// 结果:array = [0,1,2,3,4,5],i最终为6
注意:while 循环必须保证条件最终会变为假,否则程序会进入死循环。
4.repeat...until 循环
语法定位
HALCON 没有 do { } while() 语法(书写会直接报语法错误),直到型循环统一使用 repeat ... until,属于先执行、后判断的循环,循环体至少执行 1 次。
语法格式
repeat
// 循环体代码
until (退出条件)
- 执行逻辑:先完整执行一次循环体,再判断
until后的条件 - 条件为 假:继续下一轮循环
- 条件为 真:立即退出循环
注意判断逻辑和
while完全相反:while(条件)是条件为真才循环;until(条件)是条件为真就结束。
代码示例
(1)正常退出示例
Flag := 0
array := []
i := 0
repeat
array := [array, i]
i := i + 1
if(i == 5)
Flag := 1 // 修改标志位,满足退出条件
endif
until (Flag == 1)
// 执行结果:array = [0, 1, 2, 3, 4],循环结束后 i = 5
(2)死循环易错场景
如果循环体内始终不修改退出条件(如 Flag 一直为 0),程序会进入无限死循环,变量持续累加。
Flag := 0
i := 0
repeat
i := i + 1
until (Flag == 1) // 条件永远不满足,死循环
学习时可配合 HDevelop 单步调试,通过变量窗口实时观察数值变化,辅助理解执行逻辑