想象一下,你像往常一样,正在一条熟悉的路上慢跑,突然被一个念头打动——一款全新的杀手级移动应用!一路上,你甚至忘记了回 ...

App Inventor编程教程-目录

本章将创建一个应用,将安卓手机变成乐高机器人(LEGO MINDSTORMS NXT)的遥控器。在应用中,使用按钮来控制机器人前后移动、左右转动和停车。如果机器人遇到障碍物,它还会自动停车。应用中使用具有蓝牙功能的手机与机器人进行通信。

乐高头脑风暴机器人(LEGO MINDSTORMS)不只是玩具,更是教具。在某些课后项目中,使用机器人来培养小学生及初中生的解决问题能力,并引导他们了解工程技术及计算机编程技术。乐高NXT机器人也用于FIRST LEGO League主办的机器人竞赛,这项比赛允许9~14岁的孩子参加。

图12-1 设计视图底部的非可视组件
NXT可编程机器人套件中有一个被称为“NXT智能模块”的主机单元,它可以控制三个电机及四个输入传感器。你可以用乐高的结构元件、齿轮、车轮、电机和传感器来组装机器人。该套件自带的软件可以对机器人进行编程,但是现在,我们将用App Inventor来创建一个安卓应用,通过手机与机器人之间的蓝牙连接来操控NXT机器人。

本章应用中所操控的机器人具有超声波传感器以及用于移动的车轮,就像图中所示的那类移动发射机器人(Shooterbot),它通常是人们利用乐高头脑风暴NXT 2.0套件拼装的第一个机器人。它的左车轮与输出端口C相连,右车轮与输出端口B相连,颜色传感器与输入端口3相连,超声波传感器与输入端口4相连。

学习要点

本章用到了以下组件和概念。

  • 蓝牙客户端组件:用于建立安卓设备与机器人之间的蓝牙连接。
  • 列表选择框组件:为用户显示可供选择的蓝牙设备列表,来选择机器人,并建立安卓设备与机器人之间的蓝牙连接。
  • Nxt电机驱动器组件:用于驱动机器人的轮子。
  • Nxt超声波传感器组件:利用机器人的超声波传感器探测障碍物。
  • 对话框组件:用于显示错误消息。

准备开始

本章应用需要的安卓版本应该在2.0或以上。此外,由于安全的原因,蓝牙设备必须首先配对才能彼此连通。因此,在开始构建应用之前,需要按以下步骤实现安卓设备与机器人之间的成功配对。

  1. 在机器人上单击向右箭头,直到显示“Bluetooth”(蓝牙),然后按下橙色方块。
  2. 点击向右箭头,直到显示“Visibility”(可见),然后按下橙色方块。
  3. 如果“Visibility”值已设定为可见,继续步骤4;如果不可见,请单击向左或向右箭头,设置其值为可见。
  4. 在安卓设备上,打开设置→无线与网络。(下面的5~7步对于不同的安卓设备,可能略有不同。)
  5. 确保打开蓝牙功能。
  6. 点击“蓝牙”并开始“搜索设备”。
  7. 在“可用设备”中查找名为“NXT”的设备;如果你修改过机器人的名称,则寻找你改过的设备名称而非“NXT”。
  8. 点击“NXT”或你修改过的机器人的名称。
  9. 在机器人上,你会看到要求输入密码的提示,点击橙色方块以确认默认的密码1234。
  10. 在安卓设备上,将出现提示,要求输入PIN,此时输入1234,然后点击OK。
  11. 现在你的机器人已经与安卓设备配对成功。

登录App Inventor网站,创建名为“遥控机器人”的新项目,将屏幕的标题设置为“遥控机器人”,并连接测试手机(或模拟器),准备进行实时测试(需要更多帮助,请参见http://appinventor.mit.edu/explore/ai2/setup )。

设计组件

在这个应用中,我们需要分别创建非可视组件及可视组件,并设定它们的功能。

非可视组件

在创建用户界面之前,先来创建表12-1中的非可视组件,如图12-1所示,用来控制机器人。

表12-1 用于控制机器人的非可视组件

图12-1 设计视图底部的非可视组件

按以下方式设置组件的属性。

  1. 设置Nxt电机驱动器1及Nxt超声波传感器1的蓝牙客户端属性为蓝牙客户端1。
  2. 勾选Nxt超声波传感器1的“侦测下限”属性。
  3. 设置Nxt电机驱动器1的驱动电机端口属性:
    • 如果你的机器人左轮电机与输出端口C连接,右轮电机与输出端口B连接,则保持默认设置“CB”;
    • 如果机器人的配置与上述不同,则将驱动电机端口属性设置为两个字母的文本值,其中第一个字母是连接左轮电机的输出端口,第二个字母是连接右轮电机的输出端口。
  4. 设置Nxt超声波传感器1的传感器端口属性:
    • 如果机器人的超声波传感器与输入端口4连接,则保持默认值“4”;
    • 如果机器人的配置与上述不同,则将传感器端口设置为与超声波传感器连接的输入端口。

可视组件

现在创建用户界面组件,如图12-2所示。

图12-2 设计视图中的应用
建立蓝牙连接时,安卓设备需要获取机器人的蓝牙地址(每个蓝牙设备的地址都是独一无二的),但蓝牙地址由8个两位数的十六进制数(二进制数的另一种表示方式)组成(如5E:F0:32:7A:2C:B1:89:01),数字之间以冒号分隔,输入起来非常麻烦,而且每次运行应用都要在手机上输入该地址。为了减少麻烦,使用列表选择框来显示已经与手机成功配对的机器人列表,并从中选择一个(列表项的值为机器人的名称及蓝牙地址)。

按照表12-2中列出的组件来创建图12-2所示的用户界面。

表12-2 用于控制机器人的可视组件

按下列方式设置组件属性。按照图12-2所示来设置可视组件布局:将左转、停车及右转按钮放在水平布局中,将前进按钮、水平布局1、后退按钮及断开连接按钮放在垂直布局1中。

  1. 取消勾选Screen1的允许滚动属性(滚屏功能)。
  2. 设置蓝牙设备选择框和断开连接按钮的宽度属性为“充满”。
  3. 设置垂直布局1、前进按钮、水平布局1、左转按钮、停车按钮、右转按钮及倒车按钮的宽度及高度属性为“充满”。
  4. 设置蓝牙设备选择框的显示文本属性为“连接…”。
  5. 设置前进按钮的显示文本属性为“∧”。
  6. 设置左转按钮的显示文本属性为“<”。
  7. 设置停车按钮的显示文本属性为“—”。
  8. 设置右转按钮的显示文本属性为“>”。
  9. 设置倒车按钮的显示文本属性为“∨”。
  10. 设置断开连接按钮的显示文本属性为“断开连接”;
  11. 设置蓝牙设备选择框和断开连接按钮的字号属性为30;
  12. 设置前进、左转、停车、右转及倒车按钮的字号属性为40,勾选粗体属性。

在这类应用中,当手机与机器人建立蓝牙连接之前,应该隐藏用户的操作界面,为此取消勾选垂直布局1的允许显示属性。不要担心,稍后当应用与机器人之间的蓝牙连接成功之后,将重新显示用户界面。

为组件添加行为

本节将编程来设置应用的功能,包括:

  • 用户从列表中选择机器人,并建立应用与机器人之间的连接;
  • 用户可以断开应用与机器人之间的连接;
  • 用户可以使用控制按钮来操控机器人;
  • 在机器人侦测到障碍物时,将自动停车。

连接到机器人

添加第一个行为:建立安卓设备与机器人之间的蓝牙连接。点击蓝牙设备选择框,将显示已配对的机器人列表。选中一个,将在应用与机器人之间建立蓝牙连接。

显示机器人列表

使用蓝牙设备选择框组件来显示机器人列表。选择框的外表像按钮,被点击后则显示列表项,并允许用户进行单选。在蓝牙客户端1的“地址及名称”属性中,包含了曾经与安卓设备成功配对的全部蓝牙设备,但是由于应用中已经将机器人的电机驱动器以及超声波传感器的蓝牙客户端属性设置为蓝牙客户端1,因此蓝牙客户端1的“地址及名称”属性中只保留了与机器人有关的蓝牙设备,而其他类型的蓝牙设备(如耳机等)将不会出现在选择列表中。表12-3列出了完成这一步所需要的块。

表12-3 为蓝牙设备选择框提供可选项所需要的块

点击蓝牙设备选择框将触发蓝牙设备选择框的准备选择事件,并显示可选项列表,如图12-3所示。将蓝牙设备选择框的列表属性设置为蓝牙客户端1的地址及名称块,来设定可选项。蓝牙设备选择框将显示已经与安卓设备成功配对的机器人列表。块的作用

图12-3 显示机器人列表
测试:在手机上点击“连接…”,看看会发生什么。你会看到所有已经与手机成功配对的机器人列表。如果只见黑屏,说明你的手机尚未与任何机器人配对;如果见到其他蓝牙设备,如蓝牙耳机,说明Nxt电机驱动器1及Nxt超声波传感器1的蓝牙客户端属性设置有误。

建立蓝牙连接

从列表中选择一个机器人,应用将与机器人之间建立蓝牙连接。如果连接成功,用户界面将发生变化:隐藏蓝牙设备选择框,并显示用户界面的其余部分。如果机器人开关没有打开,则连接失败,将会弹出错误信息。使用“让蓝牙客户端1连接设备”块与机器人进行连接。蓝牙设备选择框的选中项属性将提供选中机器人的地址和名称信息。使用“如果…则…否则”块来测试连接是否成功。“如果…则…否则”块需要连接三组不同的代码块:“如果”“则”及“否则”。“如果”部分与“让蓝牙客户端1连接设备”块连接,“则”的部分放置连接成功时要执行的块,“否则”部分放置连接失败时要执行的块。

如果连接成功,通过设置“允许显示”属性来隐藏蓝牙设备选择框,并显示垂直布局1(其中放置了除选择框之外的所有组件)。如果连接失败,则使用“让对话框1显示警告信息”块来显示错误信息。表12-4列出了设置实现上述功能所需要的块。

表12-4 与机器人建立蓝牙连接所需要的块

选中机器人后将触发蓝牙设备选择框的完成选择事件,见图12-4。蓝牙客户端1的连接设备块用于建立应用与选中机器人之间的蓝牙连接。如果连接成功,执行“则”部分的代码块:隐藏蓝牙设备选择框按钮,并显示垂直布局1内的所有组件,即设置蓝牙设备选择框的允许显示属性为假,设置垂直布局1的允许显示属性为真。如果连接失败,执行“否则”部分的代码块:用对话框1的显示警告信息块弹出错误信息。块的作用

图12-4 建立蓝牙连接
与机器人断开连接

让安卓设备与机器人连接着实让人兴奋,不过在开始连接测试之前,我们先来添加“断开连接”功能,以便分别在连接及断开状态下进行连续测试。当点击断开连接按钮时,应用将关闭蓝牙连接,同时用户界面将发生变化:蓝牙设备选择框会重新出现,而用户界面上的其余组件将被隐藏。表12-5列出了断开蓝牙连接所需要的块。设置“允许显示”属性来显示蓝牙设备选择框,并隐藏垂直布局1中包含的所有组件。

表12-5 与机器人断开连接所需的块

点击断开连接按钮将触发按钮被点击事件,如图12-5所示。使用“让蓝牙客户端1断开已连接设备”块,断开蓝牙连接,之后设置蓝牙设备选择框的允许显示属性为真来显示该选择框,设置垂直布局1的允许显示属性为假,来隐藏作为遥控按钮容器的垂直布局1。

图12-5 断开与机器人之间的蓝牙连接
测试:请确保机器人已经开机,点击手机上的连接按钮,并选择要连接的机器人。建立蓝牙连接需要一点时间。一旦连接成功,用户界面将显示机器人的控制按钮,以及断开连接按钮。点击断开连接按钮,则控制机器人的按钮消失,连接按钮重新出现。

操控机器人

下面是真正有趣的部分:添加前进、后退、左右转动及停止功能。不要忘记“停止”,否则你手中的机器人会失去控制!Nxt电机驱动器组件提供了五个块(新版本中是7个块),用来驱动机器人的电机。

  • 持续前进块:驱动两个电机前进。
  • 持续后退块:驱动两个电机后退。
  • 持续逆时针转弯块:驱动机器人左转,让右侧电机向前而左侧电机后退。
  • 持续顺时针转弯块:驱动机器人右转,让左侧电机向前而右侧电机后退。
  • 停止块:让两个电机停止运转。

每个移动块及转弯块都有一个功率参数,需要与数字块配合使用,来设定机器人电机的输出功率,取值范围可以从0到100。表12-6中给出了参数的具体值,如果设置的功率太小,电机会发出吱吱声而不运转。在本应用中建议使用90(百分比)。表12-6中列出了操控机器人所需的所有代码块。

表12-6 用于控制机器人的代码块

如图12-6所示,点击前进按钮时触发该按钮的被点击事件,此时调用Nxt电机驱动器1的持续前进块,让机器人以90%的功率前进。其余按钮的事件处理程序与此类似,并以相同的功率驱动机器人后退及左右转动。点击停车按钮时触发该按钮的被点击事件,调用Nxt电机驱动器1的停止块,让机器人停止运动。块的作用

图12-6 驱动机器人运转
当停车按钮被点击时,触发了该按钮的被点击事件,让Nxt电机驱动器1停止块用于命令机器人停车。按照上一个测试环节的指示连接机器人,并确保机器人不会从桌子上跌落,然后测试以下功能:

  1. 点击前进按钮,机器人将持续向前移动;
  2. 点击后退按钮,机器人将持续向后移动;
  3. 点击左转按钮,机器人将持续左转弯;
  4. 电机右转按钮,机器人将持续右转弯;
  5. 点击停车按钮,机器人将停车。

如果机器人不动并发出吱吱声,可能需要加大电机的输出功率,可以用最大功率100。

用超声波传感器探测障碍物

使用超声波传感器,机器人可以侦测到30厘米范围内的障碍物,并在这个范围内停下来,如图12-7所示。

图12-7 为机器人设置障碍
这里用Nxt超声波传感器组件来侦测障碍物,该组件有两个属性:上限范围及下限范围,用来定义传感器可以侦测障碍物的距离范围(以厘米为单位)。默认情况下,下限范围为30厘米,上限范围为90厘米。

此外,Nxt超声波传感器组件还有三个事件:高于上限、低于下限及处于限内。当侦测到障碍物的距离低于下限范围时,将会触发低于下限事件;当障碍物的距离在上下限之间时,将触发处于限内事件;当障碍物的距离超过上限时,将触发高于上限事件。

这里使用Nxt超声波传感器1的低于下限事件块,用来侦测30厘米以内的障碍物。如果你想尝试侦测不同距离的障碍物,可以调整下限范围属性。当发生低于下限事件时,使用Nxt电机驱动器1的停止块让机器人停下来。表12-7中列出了所需的块。

表12-7 使用Nxt超声波传感器所需要的块

当机器人的超声波传感器侦测到30厘米以内的障碍物时,触发低于下限事件,如图12-8所示,此时使用停止块让机器人停下来。块的作用

图12-8 当侦测到障碍物时,让机器人停车
测试:按照此前的测试说明连接机器人,使用方向按钮控制机器人向障碍物(如一只猫)移动,机器人将在距离猫30厘米时停下来。

如果机器人没停下来,可能是猫已经远离了机器人,它们之间的距离一直大于30厘米。可以换一个静止的障碍物来进行测试。

改进

应用运行起来了。想必你已经用了足够多的时间来操控这个机器人,继而产生了新的想法,比如想进行以下尝试。

  • 调节驱动电机的输出功率:
  • 可以修改前进、后退及左右转弯代码块中填充的数值。
  • 当侦测到障碍物时,可以让Nxt颜色传感器的红灯闪烁:
  • 可以使用Nxt颜色传感器组件,并设置其生成颜色属性;
  • 需要将侦测颜色属性设置为假(或在设计视图中取消勾选该属性),因为颜色传感器无法同时侦测和生成颜色。
  • 使用安卓的方向传感器来控制机器人。
  • 使用乐高的构件建立手机与机器人之间的物理连接,创建应用实现机器人的自主性。

小结

以下是本章涵盖的内容。

  • 列表选择框组件:让用户可以从已配对的机器人列表中进行选择。
  • 蓝牙客户端组件:建立安卓设备与机器人之间的蓝牙连接。
  • 对话框组件:用来显示错误消息。
  • 允许显示属性:用于隐藏或显示用户界面中的组件。
  • Nxt电机驱动器组件:可以控制机器人的移动、转向及停止。
  • Nxt超声波传感器组件:用于侦测障碍物。

注释

FIRST:是英文“For Inspiration and Recognition of Science and Technology”的缩写,可以译为“激发并褒奖对科学技术的追求”,是一个非盈利性的国际青少年组织,1989年成立,总部位于美国新罕布什尔州曼彻斯特市,宗旨是“打开科学与技术的大门,并找到一种方法与路径,引导学生认识、掌握并利用科学技术进行再创造。”一年一度的“FIRST机器人大赛”等诸多机器人竞赛是该组织的重要活动方式之一。他们的口号是:创造一个崇尚科学技术的世界,在这里,年轻人梦想成为科学与技术的引领者,并以此来改造我们的文化。

FIRST LEGO League:FIRST乐高联盟,缩写为FLL,是一项一年一度的国际性赛事。每年9月发布新一轮挑战赛,竞赛题目是解决与科学有关的现实世界中的各类问题,参赛者将围绕这些主题给出解决方案。与机器人相关的竞赛,主要是通过设计及编写程序,让乐高头脑风暴机器人完成特定的任务。学生们针对给定的不同题目,给出相应的解决方案,优胜者可以进入地区竞赛。在那里,他们可以分享知识、交换思想,并展示自己的机器人。

蓝牙通信:手机与机器人之间的通信是双向的,当驱动轮子时,要从手机向机器人传送指令;当需要避开障碍物时,机器人向手机发送测距结果,以便手机端的应用根据距离发送停车指令。所有这些指令的传输,都要依赖蓝牙通信。

十六进制:与十进制数逢十进一相对应,十六进制数逢十六进一,用十个数字(0-9)及六个字符(A-F)共16个符号来表示一个十六进制数,如,5F, 5F对应的十进制数为:5×161+15×160 = 80 + 15 = 95。

低于下限事件:机器人的超声波传感器会侦测与障碍物之间的距离,当这个距离小于某个设定值时,会输出一条消息,继而触发手机端传感器的“低于下限”事件。