对位贴合 应该是2D视觉定位比较综合的应用。难度也是最大,计算也容易出错。通常简单配置的就是2个相机 分别从下向上拍来料
,从上拍放料位置,二者综合计算得出最终偏移量。综合难点是来料的角度偏移计算要参照实际放料框角度不能单纯看来料的角度。现实中
见过有用2个相机各自角度计算偏移量,将结果叠加一起的方法,这种计算是有错误的,当角度比较大的时候 误差比较明显,且看起来误差还
很随机。
贴合原理个人理解:
1.来料位置偏移计算,其实就是计算当前来料对于示教模板来料的偏差。通过这个偏差,数据机器人可以将来料调整到和示教时候一样的位置(机器人
补偿完成偏差后,拍个照,应该和模板图片基本一致)
2.放料位偏移计算。就是放料位置已经偏离,你需要偏移一定角度和位置才能放进去。当然能放进去的前提是,来料已经调整到当初示教的位置,
这里默认来料没有误差。
3.其中1.中的偏移角度 需要 参照 2.中得到的放料位置角度偏移。也就是2执行完了 1才能得到最终偏移角度。
4.综合计算 最终机器人的角度 就是 3中说的角度,最终位置偏移量就是1中的来料偏移加上2中的放料位置
为此特地写了个halcon 的仿真程序,可以图形化显示对位贴合标定,示教 纠偏过程。
有个特殊之处是来料没有用下相机拍照,下相机不好仿真,采用的是上相机。但是原理类似,区别是如果采用下相机,角度应该取反,这个代码中有说明。
不说废话了,上代码,代码copy到halcon中就可以运行,无其他依赖,有问题,评论区见
*---代码分割线
*对位贴合 模拟仿真 By Semonpic Email: semongping@163.com
*blog www.sy9725.com
dev_update_window('off')
*窗口坐标 长宽
winw:=10000
winh:=10000
dev_open_window(0, 0, 1000, 1000, 'black', WindowHandle)
dev_set_part(0,0,winw,winh)
set_system ('clip_region', 'false')
dev_clear_window()
dev_set_draw ('margin')
*生成X,Y轴,并绘制
gen_region_line(xaxis, 0, 0, 0, winw)
gen_region_line(yaxis, 0, 0, winw, 0)
dev_set_color ('red')
dev_display(xaxis)
dev_display(yaxis)
*定义相机视野长宽
camstartrow:=5000
camstartcol:=5000
cam_width:=1000
cam_degre:=0
*定义相机左上角坐标,后面计算像素坐标用
*以Cam的左上角为0,0 坐标 相机原点在机械坐标系中的位置是 (arm_center_row-cam_width),(camstartcol-cam_width)
cam_origin_row:=camstartrow-cam_width
cam_origin_col:=camstartcol-cam_width
*生成相机区域
gen_rectangle2(camrect, camstartrow, camstartcol, cam_degre, cam_width, cam_width)
dev_set_color ('blue')
dev_set_draw ('margin')
dev_display(camrect)
*定义 Arm 法兰盘位置
arm_center_row:=3000
arm_center_col:=5000
gen_circle(arm_center, arm_center_row, arm_center_col, 200)
*定义末端工具 可以理解为一根长杆一端连接在法兰盘中心,一端带着吸盘,
*初始将吸盘的中心也放到相机中心
gen_region_line(tool,arm_center_row,arm_center_col,camstartrow,camstartcol)
*定义吸盘
gen_circle(tool_center, camstartrow, camstartcol, 100)
concat_obj(arm_center,tool,ObjectsConcat)
concat_obj(ObjectsConcat, tool_center, Tool_ARM)
dev_set_color ('pink')
dev_set_draw ('margin')
dev_display(Tool_ARM)
*定义2个轴的移动步长系数
move9Row:=[ -1, 0, 1, 1, 0, -1, -1, 0, 1 ]
move9Col:=[ -1, -1, -1, 0, 0, 0, 1, 1, 1 ]
*机械坐标
xwolrd:=[]
yworld:=[]
*像素坐标
row_pixel:=[]
col_pixel:=[]
*每次移动补偿
step:=500.0
set_display_font(WindowHandle, 24, 'mono', 'true', 'false')
gen_rectangle1(textrect,2800,3200,3100,3800)
*下面进行9点标定,以吸盘中心作为标定特征点
for Index := 0 to 8 by 1
dev_set_color ('black')
dev_set_draw ('fill')
dev_display(textrect)
dev_set_color ('pink')
dev_set_draw ('margin')
*构建每次平移矩阵
hom_mat2d_identity(HomMat2DIdentity)
hom_mat2d_translate(HomMat2DIdentity, move9Row[Index]*step, move9Col[Index]*step, HomMat2DTranslate)
*模拟九点获取机械坐标,假设此时机械坐标就表示法兰盘中心的坐标
tuple_concat(xwolrd,arm_center_row+move9Row[Index]*step,xwolrd)
tuple_concat(yworld,arm_center_col+move9Col[Index]*step,yworld)
*模拟移动机械臂
affine_trans_region(Tool_ARM, RegionAffineTrans, HomMat2DTranslate, 'nearest_neighbor')
*计算移动后机械臂的坐标,这里(Row[2],Column[2]),刚好是吸盘(小圆圈)的坐标
area_center(RegionAffineTrans, Area, Row, Column)
*模拟取吸盘的像素坐标,注意这里的(Row[2],Column[2]),就是吸盘中心,上面area_center算的
*就是Tool_ARM每次移动以后三个元素的(法兰盘,连杆,吸盘)的中心坐标,而吸盘就是第三个,希望能理解
tuple_concat(row_pixel,Row[2]-(cam_origin_row), row_pixel)
tuple_concat(col_pixel,Column[2]-(cam_origin_col), col_pixel)
dev_display(RegionAffineTrans)
set_tposition(WindowHandle, 2800, 3200)
tuple_concat('点',Index+1,distxt)
write_string (WindowHandle, distxt)
* wait_seconds (0.5)
endfor
*上面模拟九点标定以后计算标定数据,HomMat2D 就是9点标定的转移矩阵
vector_to_hom_mat2d(row_pixel, col_pixel, xwolrd, yworld, HomMat2D)
*3点旋转 标定起点 旋转3次
rotate3Point:=[20,0,-20]
arc_row:=[]
arc_col:=[]
for Index1 := 0 to 2 by 1
dev_set_color ('black')
dev_set_draw ('fill')
dev_display(textrect)
dev_set_color ('pink')
dev_set_draw ('margin')
hom_mat2d_identity(HomMat2DIdentity)
*标定起点 选择
hom_mat2d_rotate(HomMat2DIdentity, rad(rotate3Point[Index1]), arm_center_row, arm_center_col, HomMat2DRotate)
*模拟移动机械臂
affine_trans_region(Tool_ARM, RegionAffineTrans, HomMat2DRotate, 'nearest_neighbor')
*计算移动后机械臂的坐标,这里(Row[2],Column[2]),刚好是吸盘(小圆圈)的坐标,
area_center(RegionAffineTrans, Area, Row, Column)
*模拟取吸盘的像素坐标
tuple_concat(arc_row, Row[2]-(cam_origin_row), arc_row)
tuple_concat(arc_col,Column[2]-(cam_origin_col), arc_col)
dev_set_color ('turquoise')
dev_display(RegionAffineTrans)
set_tposition(WindowHandle, 2800, 3200)
tuple_concat('点',Index1+10,distxt)
write_string (WindowHandle, distxt)
*wait_seconds (0.5)
endfor
*通过上面的3点 计算圆心
gen_contour_polygon_xld(Contour, arc_row, arc_col)
get_part(WindowHandle, Row11, Column11, Row2, Column2)
fit_circle_contour_xld(Contour, 'algebraic', -1, 0, 0, 3, 2, Row1, Column1, Radius, StartPhi, EndPhi, PointOrder)
*Row1,Column1 就是圆心的像素坐标,当前值(-1000,1000),
gen_cross_contour_xld(Cross, Row1,Column1, 100, 0)
set_system ('clip_region', 'false')
dev_set_color ('red')
dev_display(Cross)
*像素转机械坐标,可以看到现在得 Qx,Qy 与 法兰盘中心存在偏移。
affine_trans_point_2d(HomMat2D, Row1, Column1, Qx, Qy)
dev_set_color ('blue')
gen_cross_contour_xld(Cross1, Qx,Qy, 200, 0)
*显示旋转标定中心坐标
dev_display(Cross1)
*计算偏移
Dx:=arm_center_row-Qx
Dy:=arm_center_col-Qy
*修正9点标定的机械坐标
xwolrd1:=xwolrd+Dx
ywolrd1:=yworld+Dy
*重新计算标定矩阵
vector_to_hom_mat2d(row_pixel, col_pixel, xwolrd1, ywolrd1, HomMat2D1)
*重新验算标定的旋转中心是否与法兰中心重合
*arm_center_row:=3000 arm_center_col:=5000 Qx1 = 3000,Qy1=5000 表示完全重合
affine_trans_point_2d(HomMat2D1, Row1, Column1, Qx1, Qy1)
affine_trans_point_2d(HomMat2D1, 2000, 2000, Qx2, Qy2)
*****************************************
*分割线,上面为标定部分,下面是纠偏验证
*重绘
dev_clear_window()
dev_set_draw ('margin')
gen_region_line(xaxis, 0, 0, 0, winw)
gen_region_line(yaxis, 0, 0, winw, 0)
dev_set_color ('red')
dev_display(xaxis)
dev_display(yaxis)
dev_set_color ('blue')
dev_set_draw ('margin')
dev_display(camrect)
*定义机械手 机械手的外观为法兰盘通过一个直线连接一个正方形吸盘
*定义方形吸盘
gen_rectangle2(sucker, camstartrow, camstartcol, 0, 400, 400)
gen_region_line(RegionLines, [4600,5400], [4600,4600], [5400,4600], [5400,5400])
concat_obj(arm_center,tool,ObjectsConcat)
concat_obj(ObjectsConcat,RegionLines,ObjectsConcat)
concat_obj(ObjectsConcat, sucker, Tool_ARM)
dev_set_color ('pink')
dev_set_draw ('margin')
dev_display(Tool_ARM)
*定义放料位置模板,是个矩形,这里用矩形区域的顶点坐标表示,方便计算顶点的偏移。
mode_row:=[4500,5500,5500,4500,4500]
mode_col:=[4500,4500,5500,5500,4500]
gen_region_polygon(ModeRegion, mode_row, mode_col)
dev_set_color ('green')
dev_display(ModeRegion)
*定义物料,物料大小和 放料框一致,物料在相机左侧 距离放料筐 3000的位置
vector_angle_to_rigid(0,0,0,0,-3000,0,HomMat2D2)
affine_trans_pixel(HomMat2D2, mode_row, mode_col, ProductRow, ProductCol)
gen_region_polygon(ProductRegion, ProductRow, ProductCol)
dev_set_color ('white')
dev_set_draw ('margin')
dev_display(ProductRegion)
*定义下相机区域,下相机区域是camrect左移动3000得到,默认认为2相机参数和视野一致,安装角度一致,
*又由于是同一个 机械手去放料,可以认为 2相机的标定数据一直,只差左移动的这3000部分
affine_trans_region(camrect,downcamrect,HomMat2D2, 'nearest_neighbor')
*下相机起始左上角坐标,方便计算相机视野内像素坐标
down_cam_origin_row:=cam_origin_row
down_cam_origin_col:=cam_origin_col-3000
dev_set_color ('blue')
dev_set_draw ('margin')
dev_display(downcamrect)
wait_seconds (1)
*机械手和 产品模板合并一起,模拟机械手将物料移动放料位置。有点像示教过程,从何往前
concat_obj(Tool_ARM, ModeRegion, ARM_DestMode)
hom_mat2d_identity(HomMat2DIdentity)
hom_mat2d_translate(HomMat2DIdentity, 0, 0, HomMat2DTranslate1)
affine_trans_region(Tool_ARM, ARM_Put, HomMat2DTranslate1, 'nearest_neighbor')
for inex:=0 to -3000 by -100
dev_set_color ('black')
dev_display(ARM_Put)
hom_mat2d_identity(HomMat2DIdentity)
hom_mat2d_translate(HomMat2DIdentity, 0, inex, HomMat2DTranslate1)
affine_trans_region(Tool_ARM, ARM_Put, HomMat2DTranslate1, 'nearest_neighbor')
affine_trans_region(ModeRegion, ModeRegion_Dest, HomMat2DTranslate1, 'nearest_neighbor')
dev_set_color ('green')
dev_display(ARM_Put)
wait_seconds (0.1)
endfor
dev_set_color ('white')
dev_display(ProductRegion)
dev_set_color ('blue')
dev_set_draw ('margin')
dev_display(camrect)
dev_display(downcamrect)
dev_set_color ('black')
dev_set_draw ('margin')
dev_display(Tool_ARM)
dev_set_color ('green')
dev_display(ModeRegion)
concat_obj(ARM_Put,ProductRegion,Tool_ARM_With_Product)
dev_set_color ('pink')
dev_display(Tool_ARM_With_Product)
*第1步:示教
*这里演示做模板的过程,正常的模板图片有个模板点,一般是十字Mark 或者 边线交点。还有模板角度,取一个边能反映模板的角度变化角度就行。
*这里不去求边线交点了,直接拿上面的(mode_row[0],mode_col[0])作为模板点。第一点和第二点连线角度作为模板角度,计算如下
*先示教 放料位置(上相机)
*模拟取模板点的像素坐标
Mode_X:=mode_row[0]-cam_origin_row
Mode_Y:=mode_col[0]-cam_origin_col
*模拟取模板角度
angle_lx(mode_row[0],mode_col[0],mode_row[1],mode_col[1],Mode_Phi)
tuple_deg(Mode_Phi, Deg)
*模拟取示教物理坐标
TeachPos_X:=3000
TeachPos_Y:=5000
*下相机工位示教,采用和上相机类似方式
Product_Mode_X:=ProductRow[0]-down_cam_origin_row
Product_Mode_Y:=ProductCol[0]-down_cam_origin_col
angle_lx(ProductRow[0],ProductCol[0],ProductRow[1],ProductCol[1],Product_Mode_Phi)
tuple_deg(Product_Mode_Phi, Deg)
*模拟取示教物理坐标
Down_TeachPos_X:=TeachPos_X
Down_TeachPos_Y:=TeachPos_Y-3000
*这里得下相机采用得相对标定方式,由于和上相机类似,所以取个巧,直接通过上
*相机得标定数据转化二来,实际工作中需要自己标定,这里只需要理解DownCamCali
*是下相机得标定数据,相对标定而来得就行。
hom_mat2d_translate(HomMat2D1,-TeachPos_X,-TeachPos_Y,DownCamCali)
*第2步:计算来料特征Mark位置和偏移角度
*下面主要是模拟来料偏移
*假设来料绕左上顶点旋转20°,平移(20,40)
*定义实际来料,区域,通过上面坐标平移旋转得到,分2步,第一步饶第一点(mode_row[0], mode_col[0])旋转5°,第二步,平移(40,50)
*修改下面3个指可以改变来料偏移情况,方便测试
Product_Offset_Angle:=20
Product_Offset_x:=20
Product_Offset_y:=40
hom_mat2d_identity(HomMat2DIdentity)
hom_mat2d_rotate(HomMat2DIdentity, rad(Product_Offset_Angle), ProductRow[0], ProductCol[0], HomMat2DRotate)
hom_mat2d_translate(HomMat2DRotate, Product_Offset_x, Product_Offset_y, HomMat2DTranslate1)
affine_trans_pixel(HomMat2DTranslate1,ProductRow,ProductCol,ProductCRowTrans, ProductCColTrans)
gen_region_polygon(NewProductRegion, ProductCRowTrans, ProductCColTrans)
concat_obj(ARM_Put,NewProductRegion,Tool_ARM_With_Product)
dev_set_color ('pink')
dev_display(Tool_ARM_With_Product)
dev_set_color ('red')
dev_display(NewProductRegion)
*下面主要是模拟放料框偏移
*修改下面3个指可以改变来放置位置偏移情况,方便测试
PutRegion_Offset_Angle:=-20
PutRegion_Offset_x:=20
PutRegion_Offset_y:=40
hom_mat2d_identity(HomMat2DIdentity)
hom_mat2d_rotate(HomMat2DIdentity, rad(PutRegion_Offset_Angle), mode_row[0], mode_col[0], HomMat2DRotate)
hom_mat2d_translate(HomMat2DRotate, PutRegion_Offset_x, PutRegion_Offset_y, HomMat2DTranslate1)
*模拟平移,当前
affine_trans_pixel(HomMat2DTranslate1,mode_row,mode_col,RowTrans, ColTrans)
*PutRegion 是偏移后放置框
gen_region_polygon(PutRegion, RowTrans, ColTrans)
dev_set_color ('red')
dev_display(PutRegion)
*模拟取来料的特征点坐标,这里为了简单,直接获取了,实际工作中要通过模板匹配或者模板匹配加边线交点来获取坐标
*取来料的当前特征
Product_Current_X:=ProductCRowTrans[0]-down_cam_origin_row
Product_Current_Y:=ProductCColTrans[0]-down_cam_origin_col
angle_lx(ProductCRowTrans[0],ProductCColTrans[0],ProductCRowTrans[1],ProductCColTrans[1],ProductCurrent_Phi)
tuple_deg(ProductCurrent_Phi, Deg)
*放置框当前特征
Current_X:=RowTrans[0]-cam_origin_row
Current_Y:=ColTrans[0]-cam_origin_col
angle_lx(RowTrans[0],ColTrans[0],RowTrans[1],ColTrans[1],Current_Phi)
tuple_deg(Current_Phi, Deg)
*第3步 纠偏计算
* 将相关特征点转化为物理坐标系
*模板特征点
affine_trans_point_2d(DownCamCali,Product_Mode_X,Product_Mode_Y,WProduct_Mode_X,WProduct_Mode_Y)
*来料实际特征点
affine_trans_point_2d(DownCamCali,Product_Current_X,Product_Current_Y,WProduct_Current_X,WProduct_Current_Y)
*由于是相对标定所有上面计算的数据要加上拍照位置拍照位置 就是(TeachPos_X,TeachPos_Y)
WProduct_Mode_X:=WProduct_Mode_X+Down_TeachPos_X
WProduct_Mode_Y:=WProduct_Mode_Y+Down_TeachPos_Y
WProduct_Current_X:=WProduct_Current_X+Down_TeachPos_X
WProduct_Current_Y:=WProduct_Current_Y+Down_TeachPos_Y
* 将相关特征点转化为物理坐标系
*模板特征点 放置模板物理坐标
affine_trans_point_2d(HomMat2D1,Mode_X,Mode_Y,Wmodex,Wmodey)
*来料实际特征点 放置框实际物理坐标
affine_trans_point_2d(HomMat2D1,Current_X,Current_Y,Wcurx,Wcury)
*计算模板Mark 绕旋转中心旋转后的坐标
*著名的绕点旋转公式
*在平面坐标上,任意点P(x1,y1),绕一个坐标点Q(x2,y2)旋转θ角度后,新的坐标设为(x, y)的计算公式:
*x= (x1 - x2)*cos(θ) - (y1 - y2)*sin(θ) + x2 ;
*y= (x1 - x2)*sin(θ) + (y1 - y2)*cos(θ) + y2 ;
*产品偏移角度当前模拟是上相机,如果下相机,Product_DeltaPhi 要取反?
Product_DeltaPhi:=ProductCurrent_Phi-Product_Mode_Phi
*放料位偏移角度
dphi:=Current_Phi-Mode_Phi
*最终偏移角度=放料位置相对偏移-产品相对偏移
finalDetaPhi:=dphi-Product_DeltaPhi
newProductX:=(WProduct_Current_X-Down_TeachPos_X)*cos(finalDetaPhi)-(WProduct_Current_Y-Down_TeachPos_Y)*sin(finalDetaPhi)+Down_TeachPos_X
newProductY:=(WProduct_Current_X-Down_TeachPos_X)*sin(finalDetaPhi)+(WProduct_Current_Y-Down_TeachPos_Y)*cos(finalDetaPhi)+Down_TeachPos_Y
*计算来料位置偏移
ProductDx:=-(newProductX-WProduct_Mode_X)
ProductDy:=-(newProductY-WProduct_Mode_Y)
*放置区域偏移
dphi:=Current_Phi-Mode_Phi
newModeX:=(Wmodex-TeachPos_X)*cos(dphi)-(Wmodey-TeachPos_Y)*sin(dphi)+TeachPos_X
newModeY:=(Wmodex-TeachPos_X)*sin(dphi)+(Wmodey-TeachPos_Y)*cos(dphi)+TeachPos_Y
*计算最终位置偏移
Dx:=Wcurx-Wmodex
Dy:=Wcury-Wmodey
*模拟纠偏放片过程
*ARM先带着产品去示教位置,还记得这个示教位置在哪里吗
hom_mat2d_identity(HomMat2DIdentity)
affine_trans_region(Tool_ARM_With_Product, Tool_ARMRotateProcutFinal, HomMat2DIdentity, 'nearest_neighbor')
for index:=0 to (3000) by 100
dev_set_color ('black')
dev_display(Tool_ARMRotateProcutFinal)
hom_mat2d_identity(HomMat2DIdentity)
hom_mat2d_translate(HomMat2DIdentity, 0, index, HomMat2DTranslate1)
affine_trans_region(Tool_ARM_With_Product, Tool_ARMRotateProcutFinal, HomMat2DTranslate1, 'nearest_neighbor')
dev_set_color ('yellow')
dev_display(Tool_ARMRotateProcutFinal)
wait_seconds (0.1)
endfor
dev_set_color ('black')
dev_display(Tool_ARMRotateProcutFinal)
hom_mat2d_identity(HomMat2DIdentity)
hom_mat2d_translate(HomMat2DIdentity, 0, 3000, HomMat2DTranslate1)
affine_trans_region(Tool_ARM_With_Product, Tool_ARMRotateProcutFinal, HomMat2DTranslate1, 'nearest_neighbor')
dev_set_color ('yellow')
dev_display(Tool_ARMRotateProcutFinal)
*Tool_ARMRotateProcutFinal是机械手带着产品回示教放片位置了
*旋转 和 偏移 看来物料是否能和 物料放置框重合
*hom_mat2d_identity(HomMat2DIdentity)
*hom_mat2d_rotate(HomMat2DIdentity, finalDetaPhi, TeachPos_X, TeachPos_Y, HomMat2DRotate)
*hom_mat2d_translate(HomMat2DRotate, Dx+ProductDx, Dy+ProductDy, HomMat2DTranslate)
*affine_trans_region(Tool_ARMRotateProcutFinal, Tool_ARMRotateProcutFinal, HomMat2DTranslate, 'nearest_neighbor')
*dev_set_color ('blue')
*dev_set_draw ('margin')
*dev_display(camrect)
*先做角度纠偏 finalDetaPhi,将来料角度调整到和当前放料框角度一致
step := finalDetaPhi / 10.0
Tool_ARMRotateProcutFinal1:=Tool_ARMRotateProcutFinal
for index:=0 to finalDetaPhi by step
hom_mat2d_identity(HomMat2DIdentity)
hom_mat2d_rotate(HomMat2DIdentity, index, TeachPos_X, TeachPos_Y, HomMat2DIdentity)
dev_set_color ('black')
dev_display(Tool_ARMRotateProcutFinal1)
affine_trans_region(Tool_ARMRotateProcutFinal, Tool_ARMRotateProcutFinal1, HomMat2DIdentity, 'nearest_neighbor')
dev_set_color ('pink')
dev_display(Tool_ARMRotateProcutFinal1)
dev_display(PutRegion)
wait_seconds (0.2)
endfor
wait_seconds (3)
*来料偏移补偿 ProductDx ProductDy
hom_mat2d_identity(HomMat2DIdentity)
hom_mat2d_translate(HomMat2DIdentity, ProductDx, ProductDy, HomMat2DIdentity)
affine_trans_region(Tool_ARMRotateProcutFinal1, Tool_ARMRotateProcutFinal2, HomMat2DIdentity, 'nearest_neighbor')
dev_set_color ('coral')
dev_display(Tool_ARMRotateProcutFinal2)
wait_seconds (3)
*放料框偏移补偿 Dx,Dy
hom_mat2d_identity(HomMat2DIdentity)
hom_mat2d_translate(HomMat2DIdentity, Dx, Dy, HomMat2DIdentity)
affine_trans_region(Tool_ARMRotateProcutFinal2, Tool_ARMRotateProcutFinal3, HomMat2DIdentity, 'nearest_neighbor')
dev_set_color ('cyan')
dev_display(Tool_ARMRotateProcutFinal3)
wait_seconds (2)
for index:=0 to 10 by 1
dev_set_color ('black')
dev_display(Tool_ARMRotateProcutFinal3)
dev_display(PutRegion)
wait_seconds (0.2)
dev_set_color ('pink')
dev_display(Tool_ARMRotateProcutFinal3)
wait_seconds (0.2)
dev_set_color ('red')
dev_display(PutRegion)
wait_seconds (0.2)
dev_set_color ('green')
dev_display(ModeRegion)
endfor
暂无评论