• 沒有找到結果。

任务5:用子程序简化巡航运动程序

在文檔中 基础机器人制作与编程 (頁 54-58)

在后面的章节中,机器人将执行动作来避开障碍物。避开障碍物的一个关键就是需要执行预先 编好的动作程序。执行这些动作程序的一个方法是用子程序。本任务首先介绍子程序,然后介绍两 种用子程序实现可重复动作的方法。

子程序

一个PBASIC子程序有两个部分。一部分是子程序调用,它告诉程序跳到可重复执行代码部分,

执行后回到调用点。另一部分是实际的子程序,它以作为自己名字的标号为子程序的起点,以 RETURN指令结束。标号和

RETURN指令之间的指令组成 的代码段执行你想让子程序做 的工作。

图4-5是某个PBASIC程序的 一部分,它包括了一个子程序调 用和该子程序的PBASIC程序代 码 。 子 程 序 调 用 是 GOSUB My_Subroutine指令。实际的子 程 序 是 从 标 号 My_Subroutine 到RETURN指令之间的部分。它 是这样工作的:当程序运行到 GOSUB My_Subroutine 指 令 时 , 它 会 寻 找 标 号

My_Subroutine:,如箭头(1)所示,程序跳到My_Subroutine处并开始执行指令。程序从标号 处向下逐行执行指令,在调试终端你会看到“Command in subroutine”信息。PAUSE 1000使程序 停顿一秒钟,然后执行RETURN指令返回到紧跟GOSUB指令后的指令。箭头(2)显示了GOSUB 指令执行后如何立即跳回,显示信息“After subroutine” 。

例程:OneSubroutine.bs2

z 输入、保存并运行程序OneSubroutine.bs2

图4-5 子程序调用

基础机器人制作与编程 ' OneSubroutine.bs2

' This program demonstrates a simple subroutine call.

' {$STAMP BS2}

' {$PBASIC 2.5}

DEBUG "Before subroutine",CR PAUSE 1000

GOSUB My_Subroutine

DEBUG "After subroutine", CR END

My_Subroutine:

DEBUG "Command in subroutine", CR PAUSE 1000

RETURN

z 观察调试终端, 按几次复位按钮。每一次你都应该看到顺序相同的三条信息。

下面是包含两个子程序的例子。一个子程序产生高音另一个产生低音。在DO 和LOOP之间的 指令依次调用子程序。试验此程序并关注意其结果。

例程――TwoSubroutines.bs2

z 输入、保存并运行程序TwoSubroutines.bs2 ' TwoSubroutines.bs2

' This program demonstrates that a subroutine is a reusable block of commands.

' {$STAMP BS2}

' {$PBASIC 2.5}

DO

GOSUB High_Pitch

DEBUG "Back in main", CR PAUSE 1000

GOSUB Low_Pitch

DEBUG "Back in main again", CR PAUSE 1000

DEBUG "Repeat...",CR,CR LOOP

High_Pitch:

DEBUG "High pitch", CR FREQOUT 4, 2000, 3500 RETURN

Low_Pitch:

基础机器人制作与编程 DEBUG "Low pitch", CR

FREQOUT 4, 2000, 2000 RETURN

你要试着将向前,左转,右转和向后四个巡航运动程序放到子程序中,下面是一个例子。

例程――MovementsWithSubroutines.bs2

z 输入、保存并运行程序MovementsWithSubroutines.bs2。

提示:你可以使用BASIC Stamp 编辑器中的“编辑”菜单将代码块从一个程序中复制并粘贴到另一个程序中。

' MovementsWithSubroutines.bs2

' Make forward, left, right, and backward movements in reusable subroutines

' {$STAMP BS2}

' {$PBASIC 2.5}

DEBUG "Program Running!"

counter VAR Word

FREQOUT 4, 2000, 3000 ' Signal program start/reset.

GOSUB Forward GOSUB Left GOSUB Right GOSUB Backward

END

Forward:

FOR counter = 1 TO 64 PULSOUT 13, 850 PULSOUT 12, 650 PAUSE 20

NEXT PAUSE 200 RETURN

Left:

FOR counter = 1 TO 24 PULSOUT 13, 650 PULSOUT 12, 650 PAUSE 20

NEXT PAUSE 200 RETURN

Right:

FOR counter = 1 TO 24

基础机器人制作与编程 PULSOUT 13, 850

PULSOUT 12, 850 PAUSE 20 PULSOUT 13, 650 PULSOUT 12, 850 PAUSE 20

使这两个代码段做不同巡航动作的是FOR循环的变量参数StartValue 和 EndValue以及 PULSOUT指令的变量参数Duration的改变。这些参数可以是变量,而且这些变量可以在程序运行 的过程中被重复更改来产生不同的巡航动作。下面的程序重复使用同一个子程序,而不是使用带有 特定PULSOUT指令参数Duration的单独子程序。产生不同动作的关键是在调用子程序前将这些变 量设为适当的值。

z 输入、保存并运行程序MovementWithVariablesAndOneSubroutine.bs2。

' MovementWithVariablesAndOneSubroutine.bs2

' Make a navigation routine that accepts parameters.

' {$STAMP BS2}

' {$PBASIC 2.5}

DEBUG "Program Running!"

counter VAR Word pulseLeft VAR Word pulseRight VAR Word pulseCount VAR Byte ' Forward full speed FOR counter = 1 TO 64

PULSOUT 13, 850 PULSOUT 12, 650 PAUSE 20

NEXT

' Ramp down from full speed backwards FOR pulseCount = 100 TO 1

PULSOUT 13, 750 - pulseCount PULSOUT 12, 750 + pulseCount PAUSE 20

NEXT

基础机器人制作与编程

FREQOUT 4, 2000, 3000 ' Signal program start/reset.

' Forward

pulseLeft = 850: pulseRight = 650: pulseCount = 64: GOSUB Navigate

' Left turn

pulseLeft = 650: pulseRight = 650: pulseCount = 24: GOSUB Navigate

' Right turn

pulseLeft = 850: pulseRight = 850: pulseCount = 24: GOSUB Navigate

' Backward

pulseLeft = 650: pulseRight = 850: pulseCount = 64: GOSUB Navigate

END

Navigate:

FOR counter = 1 TO pulseCount PULSOUT 13, pulseLeft

PULSOUT 12, pulseRight PAUSE 20

NEXT PAUSE 200 RETURN

你的机器人是否执行了你熟悉的前、后、左、右的巡航运动呢?开始阅读这个程序时可能会感 到困难,因为这些指令以一种新的方式排列。每个变量赋值语句和GOSUB指令放在同一行用冒号 分隔开,而不是像以前那样放在不同的行。这里,冒号的功能和回车键一样,分隔开每个PBASIC 指令。这种方式允许所有与指定动作有关的新变量值放在一起,并且和子程序调用在同一行。

该你了

下面是前面提到的 "死记" 竞赛

z 修改MovementWithVariablesAndOneSubroutine.bs2 使机器人走一个正方形,并且前面两个 边向前走,后面两个边向后走。提示:你需要使用任务2中所确定的PULSOUT指令的 EndValue参数。

在文檔中 基础机器人制作与编程 (頁 54-58)