中文乐高

 找回密码
 马上注册

QQ登录

只需一步,快速开始

查看: 14065|回复: 54

[教程] NXC简明教程(中文版)——自主翻译

  [复制链接]
发表于 2013-3-17 20:16:35 | 显示全部楼层 |阅读模式
本帖最后由 James.Yang 于 2013-5-22 20:20 编辑

网上看到有些网友说要将《NXC_tutorial.pdf》翻译成中文,但没有找到,因此本人计划自己动手将其翻译。由于本人水平有限,翻译中错误在所难免,请各位指正。完整的PDF文档在28楼)

评分

参与人数 1乐币 +66 人气 +10 收起 理由
WALL·E + 66 + 10 感谢分享

查看全部评分

如果您觉得我的帖子对您有用,请不吝给我一个“赞”!
 楼主| 发表于 2013-5-22 20:14:39 | 显示全部楼层
本帖最后由 James.Yang 于 2013-5-22 20:18 编辑

完整的PDF文档

NXC简明教程.pdf

2.25 MB, 下载次数: 3647

完整的PDF文档

如果您觉得我的帖子对您有用,请不吝给我一个“赞”!
回复 支持 2 反对 0

使用道具 举报

 楼主| 发表于 2013-5-6 19:51:22 | 显示全部楼层
本帖最后由 James.Yang 于 2013-5-7 18:27 编辑

第十一章 机器人之间的通信
如果你拥有一个以上的NXT,这一章就是为你而设(虽然你仍然可以通过单台NXT与PC进行数据通信)。机器人可以通过蓝牙无线技术互相通信:你可以使多台机器人协作(或相互争斗),你可以使用两台NXT建立一个大型的复杂的机器人,这样你可以使用6个电机和8个传感器。
对良好的老式RCX,这很简单:它发出红外线消息,周围所有的机器人都能接收。
对于NXT,这将是一个完全不同的方式!首先,你必须通过智能积木块上的蓝牙菜单来连接两个或更多NXT(或NXT与PC连接),只有这样,你才可以将消息发送到连接的设备。
发起连接的NXT被称为主机,通过通道1,2,3最多可以连接3个从设备。从设备总是将主设备连接到通道0。你可以发送消息到10个可用邮箱。
主-从设备通讯
举两个程序例子,一个为主设备,一个为从设备。这些基本的程序将教你如何通过两个NXT无线网络来管理快速连续的字符串消息流。
主程序首先通过BluetoothStatus(conn)函数来检查从设备是否正确连接在通道1上(BT_CONN常数),然后通过SendRemoteString(conn,queue,string)生成并发送以M打头的递增数字串消息,而通过ReceiveRemoteString(queue,clear,string)从从设备接收消息并显示数据。

图11-1 主-从设备通讯
从设备的程序非常相似,只不过使用SendResponseString(queue,string),替代SendRemoteString,因为从设备只可以给它的主设备——通道0——发送信息。

图11-2 从-主设备通讯

你可能注意到,中止其中一个程序,另一个程序将继续发送递增数字串的消息,而并不知道它所有发出的消息都将丢失,因为没有程序在侦听另一个程序。为了避免这个问题,我们可以规划一个更好的协议来相互确认消息的发送。
发送确认号码
下面再举一些例程:这次主设备用SendRemoteNumber(conn,queue,number)来发送数字并等待从设备进行确认(ack)(在until循环内,我们可以看到有ReceiveRemoteString),只有当从设备监听到并发送确认信号后,主设备才接着发送下一条消息。从设备使用ReceiveRemoteNumber(queue,clear,number)简单接收数据并通过SendResponseNumber发送确认信号。你的主从程序必须有共同的确认码,在这些程序中,我选择了十六进制数0xFF。
主设备发送一些随机数,并等待从设备确认,每当收到一个正确的确认码,确认(ack)变量必须被清除,否则,主设备将在没有新确认码下继续发送,因为确认变量成了脏变量。
从设备持续检查邮箱,如果它不为空,显示读取的数值,并给主设备发送一个确认信号。在程序开头,我在没有读取信息情况下直接发送确认信号以防阻塞主设备,事实上,如查没有这一技巧,一旦我们先启动主设备程序,即使我们随后启动从设备,主设备将被挂起。这种方法会丢失前面几个消息,但是你可以在不同的时刻启动主设备和从设备的程序而没有被挂起的风险。

图11-3 主设备程序


图11-4 从设备程序
直接命令
还有另外一个很酷的关于蓝牙通信功能:主设备可以直接控制从设备。
在下面的例子中,主设备直接给从设备发送命令来播放声音和移动电机,它不需要从设备程序,因为是从设备NXT的硬件直接用来接收和管理信息!

图11-5 蓝牙通讯程序

小结
在本章中,我们学习了在机器人之间使用蓝牙通信的一些基本概念:连接两个NXT,发送和接收字符串,数字和等待发送确认信号。当需要一个安全通信协议时,这最后一个点是非常重要的。
作为特别的特征,你也学会了如何直接给从设备智能积木块发送命令。
图11-1.JPG
图11-2.JPG
图11-3.JPG
图11-4.JPG
图11-5.JPG
如果您觉得我的帖子对您有用,请不吝给我一个“赞”!
回复 支持 1 反对 0

使用道具 举报

 楼主| 发表于 2013-3-17 20:17:10 | 显示全部楼层
前言
为了充分发挥MINDSTORMS NXT智能积木块的强大功能,我们象对老式的MINDSTORMS RIS,CyberMaster及Spybotics一样,需要一个比美国国家仪器公司LabVIEW 制作的,NXT零售版本所自带的类图形化语言——NXT-G更加得心应手的编程环境。
NXC是由John Hansen发明的一种编程语言,它是为LEGO机器人定制的语言。如果你以前从来没有编写过程序,不用担心,NXC是很容易使用的,本教程将带领你向前跨出第一步。
为了使编写程序更容易,有个称为Bricx的命令中心工具(BricxCC)。该工具可以帮助你编写程序、将程序下载到机器人、启动和停止程序,浏览NXT闪存内容、使用智能积木块转换声音文件以供使用,以及其它更多的功能。BricxCC类似于一个文字处理器,但增加了很多信息。本教程将使用BricxCC(3.3.7.16或更高版本)作为集成开发环境(IDE)。
你可以从下述网址免费下载:
http://bricxcc.sourceforge.net/
BricxCC可以运行在安装有Windows(95,98,ME,NT,2K,XP,Vista)的PC上。NXC语言也可以运行在其他平台上。你可以从下述网址下载
http://bricxcc.sourceforge.net/nxc/
本教程大部分内容也适用于其他平台,但会失去BricxCC的一些工具及颜色检查功能。
本教程已更新至NXC BETA30及更高版本。一些例程在低于BETA30版本上将无法编译。
顺便提一下,我的个人主页中包含有大量与Lego Mindstorms RCX和NXT相关的内容,其中包括一个与NXT通讯的个人电脑工具:
http://daniele.benedettelli.com
致谢
非常感谢John Hansen,他的工作是无价的。
如果您觉得我的帖子对您有用,请不吝给我一个“赞”!
发表于 2013-3-17 21:28:37 | 显示全部楼层
这是要连载吗?先搬板凳占个位置,楼主辛苦!
如果您觉得我的帖子对您有用,请不吝给我一个“赞”!
发表于 2013-3-17 22:33:52 | 显示全部楼层
这个必须顶!
楼主若能翻译这本手册,用NXC给NXT编程的人一定会比现在的多得多。古往今来,不知多少英雄豪杰,吊死在英语这棵大树上。
如果您觉得我的帖子对您有用,请不吝给我一个“赞”!
 楼主| 发表于 2013-3-20 20:18:14 | 显示全部楼层
本帖最后由 James.Yang 于 2013-3-20 20:23 编辑

第一章 编写你的第一个程序
在这一章中,我会告诉你如何编写一个非常简单的程序。我们将编写一个程序让机器人向前移动4秒,然后向后移动4秒,最后停止。该程序不是很壮观,但它向你展示了编程的基本思想。并告诉你这是多么容易。但在我们开始编写程序之前,我们首先需要一个机器人。
搭建机器人
本教程所使用的机器人叫作Tribot,这是当你从盒子中拿出NXT套装时首先指导你进行搭建的一个机器人。唯一的区别是,你必须将右边的电机连接到端口A,左边的电机连接到端口C,抓钩的电机连接到端口B。

图1-1 搭建的第一个机器人

确保已正确安装随Mindstorms NXT套件的镜像驱动程序。
开始Bricx命令中心
我们用BricxCC进行编程。双击BricxCC图标打开软件。(我假设你已经安装了BricxCC。如果没有,请到网站下载(见前言),将其安装在任何你喜欢的目录,程序会询问你在哪里找到机器人。打开机器人,按下“OK”按钮,(大多数情况下)程序会自动找到机器人。现在会出现如下图所示的用户界面(没有文本标签)。

图1-2 BricxCC用户界面

界面看起来像一个标准的文本编辑器,有常用的菜单和按钮来打开、保存文件,打印文件,编辑文件等等。但也有一些特殊的为机器人编译和下载程序的菜单,以及从机器人获取信息的菜单。在当前,你可以忽略这些菜单。
我们要编写一个新程序,所以按新建按钮来创建一个新的空窗口。
编写程序
现在输入以下程序:

图1-3 一个简单的程序

现在看起来有点复杂,所以让我们来分析它。
在NXC中的程序由任务组成。我们的程序只有一个任务,命名为main。每个程序都需要有一个称为main的任务,这个任务将由机器人执行。在第六章中你将了解到更多关于任务的内容。一个任务包括一些命令,也称为语句。在语句外有花括号,这样表明它们都属于这个任务。每条语句以分号结尾,这样,一条语句的结束和下一条语句的开始就很明显。因此,一个任务通常看起来如下图所示:

图1-4 任务示例

我们的程序有6条语句。让我们逐条来分析它们:
OnFwd (OUT_A, 75);
这条语句告诉机器人开始输出A,也就是,连接到NXT上标记为A输出端口的电机向前移动。后面的数值设置电机的速度为最大速度的75%。
OnFwd(OUT_C, 75);
相同的语句,但现在启动电机C。运行这两个语句后,两个电机开始运转,机器人向前移动。
Wait(4000);
现在是时候等待一段时间了。这条语句告诉我们要等待4秒。这个参数,即圆括号内的数字,为1/1000秒,这样你就可以非常精确地告诉程序要等待多久。等待4秒钟,程序处于休眠状态,机器人继续向前。
OnRev(OUT_AC, 75);
现在机器人移动够远了,所以我们告诉它以相反的方向移动,也就是后退。需要注意的是,我们可以用OUT_AC作为参数一次设置两个电机。我们也可以将前两个语句这样组合。
Wait(4000);
再次等待4秒钟。
Off(OUT_AC);
最后,我们关闭两个电机。
这就是整个程序。它向前移动两个电机4秒钟,然后向后移动4秒钟,最后关闭电机。
你可能已经注意到在程序中输入时会有不同的颜色。他们是自动出现的。编辑器进行语法高亮显示的颜色和式样都是可以自定义的。
运行程序
当你编写完了一个程序,必须对它进行编译(即将其改变成二进制代码,以便机器人理解和执行),并通过USB电缆或蓝牙适配器发送给机器人使用(这个过程称为“下载”程序)。

图1-5工具条

在这个工具条中,你能够看到允许你进行(从左至右)编译,下载,运行和停止程序的按钮。
按下第二个按钮,并假设你在输入程序时没有任何错误,程序将被正确编译并下载。(如果程序中有错误发生,编译器会提醒你,请见下面。)
现在你能够运行程序了。要完成这一点,进入智能积木块的My file菜单,Software files并运行1_simple程序。请记住:在NXT文件系统中的软件名与在NXC文件中的文件名是相同的。
同样,如果要让程序自动运行,你可以使用快揵方式CRTL+F5,或者在下载完程序后,按下工具条中的绿色运行按钮。
机器人是否完成了你想要的动作?如果不是,请检查连接电缆。
程序中的错误
在输入程序过程中,发生错误是很正常的。编译器会注意到这些错误并在窗口的底部报告给你,如下图所示:

图1-6 编译错误报告

编译器会自动选择第一个错误(我们输入了错误的电机名字)。当有很多错误时,你可以点击错误信息以找到错误。注意,程序开头的错误经常会引起其它地方的错误。因此最好先改正前面几个错误,然后再重新编译。同时要注意,语法高亮显示能够帮助避免很多错误。例如,在最后一行,我们输入了Of而不是Off。因为这是一个未知的命令,所以它没有高亮显示。
同时也有些错误是编译器不能发现的。如果我们输入了OUT_B,这会导致错误的电机旋转。如果你的机器人出现意外的行为,很可能你的程序中有错误。
改变速度
正如你所看到的,机器人的移动速度相当快。要改变速度,你只需要改变括号内的第二个参数。功率值为0至100之间的一个数字。100表示最快,0表示停止(NXT伺服电机将保持当前位置)。下面是我们让机器人移动缓慢的一个新版本程序:

图1-7 让机器人缓慢移动的新程序

小结
在这一章中,你使用BricxCC编写了你的第一个NXC程序。你现在应该知道如何键入一个程序,如何将它下载到机器人以及如何让机器人执行程序。BricxCC可以做更多的事情。要了解更多内容,请继续阅读随后的章节。本教程将主要介绍NXC语言,仅在需要时提到BricxCC的一些功能。
你同时也学到了NXC语言一些重要的内容。首先,你知道每个程序有一个总是由机器人执行的命名为main的任务。你也知道了电机的三个基本命令:OnFwd(),OnRev()和Off()。最后,你还了解了Wait()语句。
图1-1.JPG
图1-2.JPG
图1-3.JPG
图1-4.JPG
图1-5.JPG
图1-6.JPG
图1-7.JPG
如果您觉得我的帖子对您有用,请不吝给我一个“赞”!
 楼主| 发表于 2013-3-24 18:59:45 | 显示全部楼层
第二章 一个更有趣的程序
我们的第一个程序是没有那么吸引人。所以,让我们尝试让它变得更有趣。为此,我们将逐步深入介绍NXC编程语言的很多重要特征。
转向
你可以让机器人停止或者反向旋转两个电机中的一个以达到转向。下面是一个例子。输入程序,将其下载到你的机器人,并运行它。它应该移动一下,然后右转90度。

图2-1 右转90度

你可能需要在第二个Wait()命令中尝试一些与360 稍微不同的数值以完成一个90度的转弯。这依赖于机器人运动表面的类型。与其在程序中改变这个数值,还不如为这个数值使用一个名称来得更容易。在NXC中你可以定义常量,如下面的程序所示。

图2-2 定义常量的程序

前两行定义了两个常量。这些常量可以在整个程序中使用。定义常量有两个优点:它使得程序更具可读性,数值更容易改变。请注意,BricxCC给了定义(define)语句本色。正如我们将在第六章中看到的,你也可以定义常量以外的其他数据。
重复命令
现在,让我们试着写一个程序,让机器人走一个正方形。走一个方形意味着:向前移动,旋转90度,再向前移动,旋转90度等等。我们可以重复上面的代码段四次,但使用Repeat语句将更加简单。

图2-3 使用Repeat语句

Repeat语句括号内的数字表示花括号里面的代码要重复执行的次数。需要注意的是,在上述程序中,我们将语句进行了缩进。这不是必要的,但它使程序更易阅读。
再举最后一个例子,让我们的机器人画10个正方形。程序如下:

图2-4 画10个正方形

现在在一个Repeat语句内还有一个Repeat语句。我们称之为“嵌套”Repeat语句。你可以按你要求进行多重Repeat嵌套。仔细看一下程序中的花括号和缩进。任务由第一个花括号开始,并在最后一个花括号结束。第一个Repeat语句由第二个花括号开始,并在第五个花括号结束。嵌套Repeat语句由第三个花括号开始,在第四个花括号结束。正如你看到的,花括号总是成对出现,花括号内的内容都是缩进的。
添加注释
为了使你的程序更具可读性,最好要添加一些注释。只要你在某一行输入//,则该行的剩余部分将被用作注释而被编译程序所忽略。一个长注释可以放在/*和*/之间。在BricxCC中注释会作为语法高亮显示。完整的程序如下所示:

图2-5 加上注释的程序
小结
在本章中,你学会了使用Repeat语句和使用注释。你也看到了嵌套括号的功能和使用缩进。到目前为止,利用你所学到的知识,你可以让机器人沿各种路径移动。在继续进入下一章之前,在本章尝试编写不同类型的程序是很好的锻炼。
图2-1.JPG
图2-2.JPG
图2-3.JPG
图2-4.JPG
图2-5.JPG
如果您觉得我的帖子对您有用,请不吝给我一个“赞”!
发表于 2013-3-27 11:30:32 | 显示全部楼层
这个必须支持一下!

这种工作就好象是为他人修桥建路一样的!功德无量啊.......
如果您觉得我的帖子对您有用,请不吝给我一个“赞”!
 楼主| 发表于 2013-3-28 20:22:36 | 显示全部楼层
本帖最后由 James.Yang 于 2013-3-28 20:23 编辑

第三章 使用变量
变量对于每一种编程语言来说都是一个非常重要的部分。变量是可以存贮数值的内存单元。我们可以在不同的地方使用这个值,我们可以改变它的值。让我们用一个例子来描述变量的使用。
作一个螺旋运动
假设我们要改变上面的程序,使机器人以螺旋方式运动。要做到这一点,我们可以增加每次直线运动前的等待时间,也就是说,我们希望每次增加MOVE_TIME的值。但如何才能做到这一点呢?MOVE_TIME是一个常量,因此不能改变值。我们需要用一个变量来代替它。在NXC中可以很容易地定义变量。下面是螺旋运动的程序。

图3-1 螺旋运动程序

感兴趣的行都作了注释。首先,我们通过输入关键字int,随后跟一个我们选择的名字来定义一个变量。(通常我们使用小写字母来表示变量名,大写字母来表示常量,但这不是必须的。)变量名必须以字母开头,但可以包含数字和下划线符号。其他符号是不允许的。(这同样适用于常量名,任务名称等。)关键词int表示整数。只有整数可以存储在这个变量。在第二行中我们给变量赋值200。从这一刻起,只要你使用该变量,它的值将是200。接下来重复的循环中,我们使用变量来表示等待时间,在循环结束时,我们将变量值增加200。因此,机器人第一次等待200毫秒,第二次等待400毫秒,第三次等待600毫秒,依此类推。
除了给变量作加法外,我们也可以使用*=给变量做乘法,用-=给变量做减法,用/=给变量做除法。(请注意,除法的结果为四舍五入到最接近的整数。)你也可以将一个变量加到另一个变量,并写下更复杂的表达式。下面的例子对你机器人的硬件没有任何影响,因为我们还不知道如何使用NXT显示!

图3-2 使用变量的程序例子

请注意程序的前两行,我们可以在一行中定义多个变量。我们也可以将三个变量定义结合在同一行内定义。变量values是一个数组,也就是说它包含超过一个数据:一个数组可以通过方括号内数字进行索引。在NXC中整数数组的声明如下:
Int name[];
然后,通过下一行语句给10个元素初始化为0。
ArrayInit(values, 0, 10);
随机数
在上述所有的程序中,我们都规定了机器人要做的事情。但是,当机器人做一些我们不知道的事情时就会变得更有趣。我们需要一些随机性的运动。在NXC中,你可以创建随机数。下面的程序使用随机数让机器人以随机的方式运行。它持续让机器人向前运动一个随机的时间,然后做一个随机的转向。

图3-3 随机运动
该程序定义了两个变量,然后将随机数赋值给他们。Random(600)产生一个0到600(最大值不包含在返回的随机数中)之间的随机数。每次调用Random时产生的数字都会不同。
注意,我们可以通过直接输入如:Wait(Random(600))来避免使用变量。
你在这个程序中还可以看到一个新的循环类型。我们使用while(true)而来替代repeat语句。只要在括号之间的条件是真,while语句将重复执行它下面的语句。关键字true永远为真,因此花括号内的语句将永远重复执行(或至少在你按下NXT上的暗灰色按钮之前)。在第四章中你将学习到更多关于while语句的内容。
小结
本章中,你学到了使用变量和数组。你除了声明int外,还可以声明其他数据类型如short(短整形),long(长整形),byte(字节),bool(布尔)和string(字符串)。
你还学习了如何创建随机数,这样你可以给机器人一些不可预知的行为。最后,我们看到了使用while语句的一个死循环,它将永远执行。
图3-1.JPG
图3-2.JPG
图3-3.JPG
如果您觉得我的帖子对您有用,请不吝给我一个“赞”!
 楼主| 发表于 2013-3-31 20:04:21 | 显示全部楼层
第四章 控制结构
在前面的章节中,我们学习了repeat和while语句。这些语句控制了程序中其他语句的执行方式。他们被称为“控制结构”。在本章中,我们将学习到另外一些控制结构。
If语句
有时你只想在满足某些特定条件时,才执行程序的一些特定部分。在这种情况下,就使用if语句。让我举个例子。我们将再次改变我们至今一直使用的程序,但要做一些改变。我们希望机器人沿着直线前进,然后让它左转或右转。要做到这一点,我们又需要用到随机数。我们选择一个随机数字,它可以是正数,也可以是负数。如果该数字小于0,我们让机器人向右转;否则,我们让机器人向左转。程序如下图所示:

图4-1 使用if语句让机器人左转或右转

If语句看起来有点像while语句。如果括号内的条件为真,则执行花括号内的部分。否则,执行关键字else之后的花括号内的部分。让我们来更进一步看一下我们使用的条件。它读取Random()>=0这个表达式。这意味着,Random()必须大于或等于0时条件为真。你可以以其它方式来比较数值。下面是最重要的一些比较运算符:

==                等于
<                小于
<=                小于或等于
>                大于
>=                大于或等于
!=                不等于

你可以使用&&,意思是“与”,或||,意思是“或”来组合条件表达式。下面是条件表达式的一些例子:

true                                                总是真
false                                                永远不真
ttt != 3                                                当ttt不等于3时为真
(ttt>=5) && (ttt<=10)                        当ttt在5和10之间时为真
(aaa==10) || (bbb==10)                当aaa或者bbb等于10(或都等于10)时为真

需要注意的是if语句有两部分组成。紧随条件之后的部分,当条件为真时立即执行,else之后的部分,条件为假时执行该部分。关键字else及其后面的部分是可选项。所以,当条件为假而不需要做什么时你可以省略它们。
Do语句
还有另外一个控制结构,称为do语句。它具有以下形式:

图4-2 Do语句结构

只要条件为真,就会执行do后面花括号内的语句。这里的条件与上面所述的if语句中的条件具有相同的形式。下面举个程序例子。机器人随机运行20秒,然后停止。

图4-3 使用do语句让机器人随机运行20秒
注意:do语句与while语句的执行几乎相同。但在while语句中,在语句执行之前先进行条件测试,而在do语句中,条件测试是在最后进行。对于while语句,花括号内的语句可能永远不会被执行,但对于do语句,花括号内的语句至少执行一次。
小结
在本章中,我们学习了两个新的控制结构:if语句和do语句。连同repeat语句和while语句,它们组成了控制程序执行的方式。你理解他们做什么这是非常重要的。因此,在继续下一章学习前,最好自己尝试更多的例子。
图4-1.JPG
图4-2.JPG
图4-3.JPG
如果您觉得我的帖子对您有用,请不吝给我一个“赞”!
发表于 2013-4-8 11:01:36 | 显示全部楼层
真谢谢你帮我们实现学习乐高的理想。
如果您觉得我的帖子对您有用,请不吝给我一个“赞”!
 楼主| 发表于 2013-4-10 20:24:36 | 显示全部楼层
第五章 传感器
当然你可以将传感器连接到NXT以使机器人能够对外部事件进行反应。在我告诉如何做到这一点之前,我们必须给机器人添加一个触摸传感器。如同前面一样,按照Tribot的搭建指示安装前保险杠。

图5-1 给Tribot安装前保险杠

将触摸传感器安装到NXT的1号输入端口。
等待传感器信号
让我们从一个非常简单的程序开始,在这个程序中,机器人向前移动,直到它碰到某个物体。程序如下:

图5-2 使用传感器的简单程序

程序里有两行很重要。程序的第一行告诉机器人我们使用了什么类型的传感器。IN_1是我们连接传感器的输入端口号。其他传感器输入端口号为IN_2,IN_3和IN_4。SENSOR_TOUCH表示这是一个触摸传感器。对光线传感器,我们将使用SENSOR_LIGHT。我们指定传感器类型后,程序启动两个电机,机器人开始向前移动。下一条语句是一条非常有用的构造。它一直等待直到括号内的条件为真。程序中的条件要求传感器SENSOR_1的值必须为1,也就是说传感器被按下。只要该传感器没有被按下,这个值一直为0。所以这个语句将等待,直到传感器被按下。然后我们关闭电机,结束任务。
按下触摸传感器
现在,我们尝试让机器人避开障碍物。每当机器人碰到物体时,我们让它后退一些,转个弯,然后继续前进。程序如下:

图5-3 机器人避开障碍物

如同前面的例子,我们首先指明传感器类型。接下来,机器人开始向前移动。在while死循环中,我们不断测试触摸传感器是否被按下,如果按下,后退300毫秒,右转300毫秒,然后再继续向前。
光线传感器
除了触摸传感器,你的Mindstorms NXT系统还有一个光线传感器,一个声音传感器和一个数字式超声波传感器。光线传感器可以被触发为发光或不发光,因此可以在特定方向上测量反射光或环境光线值。测量反射光,对于机器人按照地板上的线前进是特别有用。这将是我们下面的程序例子要完成的内容。要完成实验,要完成Tribot的搭建。按照搭建指令,将光线传感器连接到输入端口3,声音传感器连接到输入端口2,超声波传感器连接到输入端口4。

图5-4 加上其它传感器的Tribot

我们还需要与NXT套件一起分发的具有黑色轨道的测试纸垫。巡线运动的基本原则是要求机器人一直试图保持在黑线边界的右侧,当光线值太低时机器人要转离黑线(传感器照到了线的中间),当传感器照到了黑线以外,并检测到了高亮的光线值,机器人要转向黑线。下面是一个非常简单的巡线程序,只使用一个光线阈值。

图5-5 简单的巡线程序

程序首先配置端口3为光传感器。接着,它设置机器人向前移动,并进入一个死循环。每当光线值大于40时(我们在这里使用一个常数,这样可以较容易进行更改,因为光线值在很大程度上依赖于周围的光线),我们使一台电机后退,直到我们再次回到黑线上。
正如你在执行程序时看到的,运动不是很顺畅。尝试添加在until命令前添加一条Wait(100)命令,以使机器人移动更加完美。请注意,程序不能逆时针移动。为了能使沿任意路径运动需要一个更复杂的程序。
要读取LED灯熄灭时周围的光线强度,配置传感器如下:

图5-6 配置光线传感器读取周围的光线强度

声音传感器
使用声音传感器,你可以将你昂贵的NXT设置成击鼓者!我们要编写一个程序,等待一个响亮的声音,驱动机器人移动,直到检测到另一种声音。按Tribot搭建说明书中描述,将声音传感器连接到端口2。

图5-7 声音传感器程序

我们首先定义一个THRESHOLD常量和SENSOR_2的一个别名,在主任务中,我们将端口2配置为从声音传感器读取数据,并开始一个死循环。
使用until语句,程序等待声级大于我们设定的阈值:请注意,SENSOR_2不只是一个名字,它还是一个返回从传感器读取的声级值的宏。
如果发出一个响亮的声音,机器人开始前行,直到另一个声音来停止它。
插入wait语句是因为如果没有这条语句的话机器人将会瞬间开始或停止:事实上,NXT运行如此之快,在两条until语句之间的行都没有时间去执行。如果你把第一条及第二条wait语句注释掉,你将更好地理解这一点。使用until语句来等待事件发生的情况可以由while语句来替代,它只需在括号内加上一条互补的条件就足够了,例如:
while (MIC <= THRESHOLD)
对NXT模拟传感器没有更多的内容需要了解,只要记得,光线和声音传感器将给你一个从0到100的读数。
超声波传感器
超声波传感器的工作原理就象一个声纳:大致说来,它发出一串超声波,然后测量从其视线所及物体反射回来的超声波所需要的时间。这是一个数字传感器,意味着它有一个嵌入式用于分析和发送数据的集成设备。有了这个新传感器,你可以让机器人在真正撞上物体(如同触摸传感器一样)之前来避免障碍物。

图5-8 超声波传感器例子

程序首先初始化端口4为从数字超声波传感器读取数据,然后程序执行一个死循环让机器人直行,直到在其眼前小于NEAR厘米(我们的例子中为15厘米)有个物体,然后后退一些并转个向,再开始直行。
小结
在本章中,你学习了如何使用NXT套件中所包含的各种传感器。我们同时也学到了在使用传感器时until和while语句是多么有用。
我建议你自己在这里编写一些程序。你已拥有给你的机器人相当复杂行为的知识:尝试将NXT零售软件Robo Center编程指南中的最简单的程序转化为用NXC语言编写的程序。
图5-1.JPG
图5-2.JPG
图5-3.JPG
图5-4.JPG
图5-5.JPG
图5-6.JPG
图5-7.JPG
图5-8.JPG
如果您觉得我的帖子对您有用,请不吝给我一个“赞”!
 楼主| 发表于 2013-4-16 20:04:38 | 显示全部楼层
第六章 任务和子程序
到目前为止我们所有的程序都只有一个任务。但是,NXC程序可以有多个任务。同样可以将一些代码放在所谓的子程序中,以供你在程序中不同的地方使用。使用任务和子程序,可以使你的程序更容易理解和更紧凑。在本章中,我们将着眼于各种可能性。
任务
一个NXC程序最多可以包括255个任务,每个任务都有一个唯一的名字。必须始终存在一个名字为main的任务,因为这是第一个要被执行的任务。其他任务只有当一个正在运行的任务告诉要执行他们或者在main任务中明确计划要执行时才被执行,在他们执行之前,必须终止main任务。从那一刻起,两个任务同时运行。
让我来展示任务的使用。我们想编程让机器人像以前一样按正方形运动。但是当它碰到障碍物时,它应该做出反应。在一个任务中是很难做到这一点的,因为机器人必须在同一时刻要做两件事情:正方形移动(即及时开启及关闭电机)和读取传感器读数。因此,最好使用两个任务,一个任务按正方形移动,另一个任务对传感器作出反应。程序如下:

图6-1 两个并发任务程序
在main任务中只是设置传感器类型,然后同时启动其他两个任务,将它们加在调度队列中,然后main任务结束。任务move_square让机器人一直按正方形移动。任务check_sensors检查触摸传感器是否被按下,如果被按下,就让机器人远离障碍物。
必须要记住很重要的一点,即两个任务是在同一时刻开始运行的,如果两个任务都试图要电机按他们各自的要求运行时,这可能会导致意想不到的结果。
为了避免这些问题,我们定义了一个奇怪的变量类型,互斥量mutex(代表相互排斥):我们只能通过使用Acquire和Release两个函数来处理这种变量,在这两个函数之间编写一些关键代码,确保在同一时间只有一个任务可以完全控制电机。
这些互斥类型的变量被称为信号灯,这种编程技术被命名为并发编程,这种参数类型将在第十章详细描述。
子程序
有时候,你需要在程序的多个地方使用同一段代码。在这种情况下,你可以把这段代码放在一个子程序中,并给它取个名字。现在,你可以简单地在任务中通过调用它的名字来执行这段代码。让我们来看一个例子:

图6-2 子程序调用程序

在这个程序中,我们定义了一个子程序,使机器人绕其中心旋转。主任务调用了子程序三次。需要注意的是,我们调用子程序时是通过子程序名字,并在名字后面的括号内写入一个数值参数来完成的。如果子程序没有任何参数,只需添加括号而不需要在括号里加上任何参数。
因此,它看起来同我们看到的大多数命令一样。
子程序的主要好处是,他们只在NXT中存储一次,这样可以节省内存空间。但是,当子程序很短时,使用内联函数(inline function)可能更好。这些函数都不是单独存储的,而是将它们复制到每一个使用的地方。这会使用更多的内存,但内联函数的数量没有任何限制。他们可以声明如下:

图6-3 内联函数定义

内联函数的定义和调用方式与子程序完全相同。所以上面的例子使用内联函数,变成如下所示:

图6-4 使用内联函数程序

在上述例子中,我们可以将转向时间作为函数的参数,如下例子所示:

图6-5 使用时间参数的内联函数程序

请注意在内联函数名后面括号中我们指定了函数的参数。在这个例子中,我们声明了一个整数参数(也可以是其他选择),它的名字为turntime。当有多个参数时,则必须用逗号分隔它们。需要注意的是,在NXC中,sub与void是一样的;同时,函数除了void外还可以有其他的返回类型,可以返回整数型或字符串型数值给调用程序。详细信息请参阅NXC指南。
定义宏
还有另一种给小段代码命名的方式。你可以在NXC中定义宏(不要与BricxCC中的宏相混淆)。我们在前面已经看到,我们可以使用#define给常量定义一个名字。但是事实上我们可以定义任意的代码。下面例子是与上面例子具有相同功能的程序,但这次使用宏来实现转向。

图6-6使用宏定义的程序

在#define语句后面的名字turn_around将代表其随后的文本。现在不管你在哪儿输入turn_around,它将由这段文字所取代。请注意,该文本应在同一行。(其实有办法将#define语句分多行书写,但不建议这样做。)
其实Define语句有很多更强大功能。他们也可以有参数。例如,我们可以把转向时间在语句中作为参数。下面的这个例子中,我们定义了4个宏,一个向前移动,一个向后移动,一个向左转,一个向右转。每个宏都有两个参数:速度(speed)和时间(time)。

图6-7 使用参数的宏

定义这样的宏是非常有用的。它使你的代码更紧凑及更具可读性。此外,当你改变连接的电机时,你也可以很容易地修改代码。
小结
在本章中,你学到了任务,子程序,内联函数和宏的使用。他们有不同的用途。任务一般在同一时刻运行,并兼顾需要在同一时刻完成的不同事情。子程序在同一任务中不同的地方需要相同的大段代码时是非常有用的。内联函数在不同的任务不同的地方使用相同的代码时是非常有用的,但内联函数使用更多的内存。最后,宏在不同的地方使用一小段代码时是非常有用的。他们也可以有参数,从而使他们更加有用。
通过到目前为止的各章节的学习,你已具有让你的机器人做复杂事情的所有技能。本教程中的后续章节中将教你只在特定应用中使用的其它重要内容。
图6-1.JPG
图6-2.JPG
图6-3.JPG
图6-4.JPG
图6-5.JPG
图6-6.JPG
图6-7.JPG
如果您觉得我的帖子对您有用,请不吝给我一个“赞”!
发表于 2013-4-21 10:41:29 | 显示全部楼层
辛苦楼主了
如果您觉得我的帖子对您有用,请不吝给我一个“赞”!
 楼主| 发表于 2013-4-21 20:42:55 | 显示全部楼层
本帖最后由 James.Yang 于 2013-4-21 20:46 编辑

第七章 音乐制作
NXT具有一个内置的扬声器,它可以播放音符甚至声音文件。这对于你想让NXT告诉你正在发生什么事情是非常有用的。但是让机器人在运动时演奏些音乐或者说说话也是有趣的。
播放声音文件
BricxCC通过菜单中的工具->声音转换的一个内置实用程序可以将.wav文件转换成.rso文件。然后,你可以通过另一个实用程序将.rso声音文件保存到NXT闪存中,通过NXT内存浏览器(工具->NXT资源管理器),用下面的命令来播放这个文件:
PlayFileEx(filename, volume, loop?)
它的参数是声音文件名,音量(数字0到4),及是否循环:如果你想让文件循环播放,则最后一个参数设置为1(TRUE),或者如果你想让文件只播放一次,则这个参数设置为0(FALSE)。

图7-1 声音文件播放程序

这个漂亮的程序首先播放了一个你可能熟悉的开始曲,然后用其他标准的点击声播放使兔子罗杰发疯的“理发修面”顺口溜!在这种情况下,宏是非常有用的,它简化了主任务中的音调表示:尝试修改音量设置将音符添加一些重音。
播放音乐
播放音符,可能使用命令PlayToneEx(frequency, duration, volume, loop?)
它有四个参数。第一个是频率(赫兹),第二个是持续时间(以1/1000秒为单位,同等待命令一样),最后同前面一样的音量及是否循环。也可以使用PlayTone(frequency, duration),在这种情况下,音量由NXT菜单设置,循环被禁用。
下表为有用的频率表
音符        3        4        5        6        7        8        9
B        247        494        988        1976        3951        7902        
A#        233        466        932        1865        3729        7458        
A        220        440        880        1760        3520        7040        14080
G#                415        831        1661        3322        6644        13288
G                392        784        1568        3136        6272        12544
F#                370        740        1480        2960        5920        11840
F                349        698        1397        2794        5588        11176
E                330        659        1319        2637        5274        10548
D#                311        622        1245        2489        4978        9956
D                294        587        1175        2349        4699        9398
C#                277        554        1109        2217        4435        8870
C                262        523        1047        2093        4186        8372

在使用PlayFileEx的情况下,NXT不会等待音符播放完成。因此,你如果在一行中使用多个音符,那么你最好在音符之间添加(稍长)等待命令。如下例子所示:

图7-2 播放多个音符

使用BricxCC中的积木钢琴,你可以很容易创建音乐片段。
如果你想在NXT移动同时播放音乐,最好使用一个单独的任务。下面是一个让NXT愚蠢的来回走动并不停地播放音乐的程序:

图7-3 移动同时播放音乐

小结
在本章中,你学会了如何让NXT播放声音和音乐。同时你也看到了如何为播放音乐使用一个单独的任务。
图7-1.JPG
图7-2.JPG
图7-3.JPG
如果您觉得我的帖子对您有用,请不吝给我一个“赞”!
发表于 2013-4-24 13:39:14 | 显示全部楼层
赞。楼主,精神崇高,连续小说,后来人把资料整理下,好像图片都打了标志,欢迎继续更新,一定让大家喜欢的。
如果您觉得我的帖子对您有用,请不吝给我一个“赞”!
您需要登录后才可以回帖 登录 | 马上注册

本版积分规则

QQ|中文乐高 ( 桂ICP备11003955号-1 )

GMT+8, 2017-10-22 14:23 , Processed in 0.086120 second(s), 25 queries .

Powered by Discuz! X3.4

© 2001-2013 Comsenz Inc. Template By 【未来科技】【 www.veikei.com 】

快速回复 返回顶部 返回列表