您好,欢迎来到意榕旅游网。
搜索
您的当前位置:首页能力风暴机器人编程

能力风暴机器人编程

来源:意榕旅游网
令狐采学创作

第一节 图形化交互式C语言简介

4.1.1

令狐采学

4.1.2 VJC简介

图形化交互式C语言(简称VJC)是用于能力风暴智能机器人系列产品的软件开发系统,具有基于流程图的编程语言和交互式C语言(简称JC)。VJC为开发智能机器人项目、程序与算法、教学等提供了简单而又功能强大的平台,是全球开创性的具有自主知识产权的产品。

在VJC中,不仅可以用直观的流程图编程,也可以用JC语言编写更高级的机器人程序。流程图和JC语言双剑合壁,既能领读者轻松入门,又能够让读者在编程中发挥最大的创造力。

VJC操作简便,有活泼明快的图案和简短的文字说明。读者可以使用形象化的模块,由顶向下搭建流程图,搭建流程图的同时,动态生成无语法错误的JC代码。流程图搭建完毕,程序就已经编写完成,可以立即下载到机器人中运行。已入门的读者可以直接在JC代码编辑环境中编写程序,还可以边写边试,发现错误,校正修改,十分方便。VJC能让你在丰富多彩的机器人世界里,边玩边学,愉快地掌握许多有用的科技知

令狐采学创作

令狐采学创作

识。

用常规的计算机编程语言(如C、FORTRAN、JAVA)编程,需要输入复杂的程序代码,并且编写的程序还要符合特定的语法。而流程图编程不需要记忆计算机语言的语法,不需要使用键盘输入程序代码,只需要按照“先作什么,后作什么”的设想,就可以编出程序。VJC正是按这个思想设计的。使用VJC软件,学生们不用关心语言实现的细节,同时也有效避免了语法错误,有利于集中精力寻求解决问题的方法。

VJC的流程图模型由以下几种基本形状的模块及带有箭头的方向线组成:

VJC的模块包括:执行器模块(蓝色矩形)、单功能传感器模块(紫色平行四边形)、带判断功能的传感器模块(紫色菱形)、控制模块(红色菱形)和程序模块(黄色矩形或椭圆形)五种。

VJC流程图支持多任务程序、子程序调用、浮点数和整数、全局变量、简单表达式、复合条件判断以及循环嵌套等。

每一个模块都可以完成一定的功能。只要按清晰的思路连接这些模块,就可以很快地完成一个程序的编写。

一般的程序甚至是复杂的灭火程序都能够用流程图实现。 JC语言

交互式C语言(简称JC)是用于能力风暴智能机器人的专用开发语言。

令狐采学创作

令狐采学创作

JC由两部分组成:编译环境和能力风暴操作系统ASOS。JC实现了标准C语言的一个子集,它包括控制语句(for,while,if else)、局部变量和全局变量、数组、指针、16位和32位整数以及32位浮点数。

JC不直接编译生成针对特定处理器的机器代码,而是先编译生成基于堆栈虚拟机的伪代码。然后这种伪代码由能力风暴操作系统解释执行。JC这种不寻常的编译方式有以下优点:

1)

解释执行:允许检查运行错误。例如:JC在运行时,数组下标的检查。

2) 3)

代码更精简:伪代码比机器代码更简短。

多任务:由于伪代码是完全基于堆栈的,进程状态完全由它的堆栈和程序计数器所决定。因此只需要装载新的堆栈指针和程序计数器就可以方便地实现任务切换。任务切换由操作系统处理,而不是编译器。

JC与标准C对比:

JC语言是建立在ANSI C标准上的。但是它们有些重要的区别。

许多区别是因为JC比标准C更“安全”。例如,JC在运行时要检查数组下标,所以数组不能被变为指针,也不可以进行指针运算。

另一些区别是由于JC的运行时间更短更高效。例如,JC的printf函数就没有ANSI C中的许多不常用的格式化选项。

令狐采学创作

令狐采学创作

系统特点

--图形化编程--

完全的图形化编程方法,简单直观,用鼠标就可以进行操作

机器人控制程序流程图,由顶向下搭建,符合国际标准 --图形模块--

系统图形模块包括执行器模块、传感器模块、控制模块、程序模块、AS多功能扩展卡模块以及通讯模块

支持四则运算表达式 支持双重条件判断 支持多重循环嵌套 支持16个多任务程序 支持10个子程序调用 提供10个常用系统子程序

提供传感器类、浮点数和整数等共几十个全局变量 “变量百宝箱”集中管理变量,直观方便 --JC语言--

从流程图自动生成正确JC代码 JC语言符合标准C语言语法标准 可以直接输出JC程序文件

增强了JC代码编辑功能,完全支持汉字 可同时打开编辑多个JC程序文件

令狐采学创作

令狐采学创作

可以从编译错误信息窗口跳到出错JC程序文件的错误语句所在行

查找,替换功能,跳转指定行 JC语言关键字颜色显示

状态栏显示光标位置的行数和列数 交互运行JC语句方式 --智能下载--

智能选择串口与机器人通讯,无须设置串口 “一键”智能下载程序

“一键”智能下载操作系统ASOS --操作系统ASOS2002-- 实时多任务机器人操作系统 高性能虚拟机设计 运行错误检测 4.1.2 安装和运行VJC1.6

操作系统:VJC1.6可运行在Windows 95/98 /ME /NT4 /2000/2003/XP平台。

硬件要求:任何一台可以运行以上操作系统的个人电脑,

硬盘有20M以上的可用空间,最好有一个空余的串口,以及配套的能力风暴智能机器人,一个24倍速以上的光驱。

令狐采学创作

令狐采学创作

安装VJC1.6

把VJC1.6开发版安装光盘放入电脑光驱中,VJC1.6就能自动安装到电脑上。如果未能自动安装,请打开“我的电脑”,打开“光盘”,运行光盘中安装程序“VJC1.6Setup.exe”,然后按照安装向导的提示一步步操作,就可以将VJC1.6安装上了。

(1)双击光盘中的

(2)出现如下的界面时,点击(3)出现如下的界面时,点击

(4)在下面界面中选择安装路径,如下图是默认安装在C盘根目录下;

(5)点击

,完成安装;

(6)安装成功之后会在桌面上出现如下图标 ,即可以使用了。

连接串口通信线

在许多情况下,如下载程序或调试程序时,机器人与计算机要用串口通信线连接起来。连接的方法是:将串口通信线的一端与电脑机箱后面的9针串口相连,另一端连在机器人的下载口上。

可能碰到的问题:

如果电脑机箱后面没有多余的9针串口,可以先挪用一个暂时不用的9针串口。如果电脑机箱后面根本就没有9针串

令狐采学创作

令狐采学创作

口,可以到电脑配件商店去买一个USB—232转接线,接在串口通信线上,就可以将机器人与电脑连接了。

软件的使用

双击桌面上的VJC1.6图标,会出现以下对话框:

默认的选项是“新建――流程图”,单击确定,即可进入流程图界面。

配置机器人型号

VJC1.6是能力风暴机器人专用的编程软件。VJC1.6安装好之后,需要配置机器人型号,也就是使编程软件中机器人型号与使用的机器人型号相匹配。配置机器人型号是编写程序之前必须要做的工作,否则程序就不能正确地下载运行。这一点请务必注意!

假设您用的是AS-UII能力风暴机器人,下面来说说为VJC1.6配置型号的操作方法。其它型号可以类似配置。操作步骤如下:

(1)打开流程图界面。

双击桌面上的VJC1.6图标,会出现以下对话框:

默认的选项是“新建―流程图”,单击确定,即可进入流

程图界面,如图所示:

令狐采学创作

令狐采学创作

(2)单击菜单栏中的“工具(T)”选项卡,在下拉菜单中单击“设置选项”,随之会弹出一个设置对话框。

(3)在设置对话框中,单击“机器人型号”下的箭头,会弹出一串型号,单击“AS-UII”。

(4)单击“确定”按钮,退出设置。

令狐采学创作

令狐采学创作

(5)关闭窗口,回到桌面,重新打开流程图界面,为机器人配置的型号“AS—UⅡ”就生效了。

注:VJC1.6共支持AS-EI、AS-InfoM、AS-InfoX、AS-M、AS-MII、AS-UII六种能力风暴智能机器人。

设置程序保存路径

设置对话框中,还可以设置保存程序的路径。VJC1.6将把程序保存在这里设定的路径当中。将来您保存的程序也可以到这里来寻找。

编写程序

如果编写流程图程序,则在打开VJC1.6窗口时,选择“新建-流程图程序”(参见图2-1),进入流程图编辑界面,就可以编写流程图了。详见3.1节和第5章。

如果编写JC代码程序,则在打开VJC1.6窗口时,选择“新建-JC代码程序”(参见图2-1),进入JC代码编辑界面,就可以编写JC代码程序了。详见3.2节和第6章。

下载程序

程序编好后,须下载到机器人中去运行。下载当前程序可按下述步骤进行:

1) 2) 3)

连接串口通信线(参见2.3节)。 打开机器人电源开关。

单击菜单栏中“工具(T)”按钮,在弹出的下拉菜单中单击“下载当前程序(D)”,随后会弹出“智能下载程

令狐采学创作

令狐采学创作

序”对话框,并显示下载进程。

4) 5)

此时注意观察下载程序是否正常。

当对话框中出现“成功下载”字样后,单击对话框上的“关闭”按钮即可。

成功下载当前程序后,拔下串口通信线,按一下机器人运行键,即可运行该程序。

注:下载程序也可以使用工具栏中的“下载”快捷按钮,下载流程图程序用

,下载JC代码程序用

下载程序可能碰到的问题如下表所示:

现象 原因 解决方法 操作系统崩溃 下载时没有进度显示 重新下载操作系统 下载程序错误机器人死机 重新复位或者重新开机 ➢

运行程序

程序下载好之后,拔掉串口通信线,按一下运行键就可以运行了。或者先关机,再开机,然后按运行键。

更新操作系统

更新操作系统又叫下载操作系统。能力风暴机器人在出厂

令狐采学创作

下载到一半后提示中断错误 下载过程中按下复位键 重新下载一次 程序无法下载 型号不匹配 配置机器人型号 令狐采学创作

时,里面已经下载了操作系统ASOS。如果在使用的过程中,操作系统ASOS不慎丢失或崩溃了,就须更新操作系统。

注:操作系统崩溃的最主要的表现就是在机器人的显示屏上只显示两排黑色的方块。

更新操作系统的方法如下: 1)连接串口通信线; 2)打开机器人电源开关; 3)打开流程图界面;

4)单击菜单栏中“工具(T)”选项卡,在弹出的下拉菜单中单击“更新操作系统(U)”,随后会弹出“智能更新操作系统”对话框。

5)

5)按下机器人“复位(ASOS)”键,此时在对话框中会显示下载进程。同时机器人主控制板上的黄色发光二极管闪动,表示数据正在传送。

6)

6)当对话框中出现“成功下载ASOS,系统更新完成”后,单击对话框上的“关闭”按钮即可。

自检

运行自检程序可以检查机器人各部分功能是否正常。自检程序有9个程序,每运行完一个程序,需再按一下运行键,才能运行下一个程序。

如果是刚出厂的机器人,尚未使用过,则打开电源开关,按下运行键,就可以运行自检程序了。

如果机器人已经使用过了,通常需要先下载自检程序,再

令狐采学创作

令狐采学创作

运行。方法如下:

1) 2) 3) 4)

连接串口通信线; 打开机器人电源开关; 打开流程图界面;

单击菜单栏中“工具(T)”按钮,在弹出的下拉菜单中单击“机器人自检程序(S)”,随后会弹出“智能下载程序”对话框,并显示下载进程;

5) 6)

当对话框中出现“成功下载”字样后,关闭对话框; 成功下载自检程序后,拔下串口通信线,按一下运行键即可运行。

4.1.3 VJC1.6界面介绍

双击桌面上的“能力风暴VJC1.6开发版”图标,打开新建对话框,这里有两个界面供选择,一个是流程图程序编辑界面,另一个是JC代码程序编辑界面。您可以根据自己的需要加以选择。

流程图编辑界面

选择“新建-流程图程序”,就进入了流程图编辑界面。它由这样几个部分组成:菜单栏、工具栏、模块库 、垃圾箱、流程图生成区、JC代码显示区(单击“JC代码”快捷按钮即可显示)。

菜单栏

令狐采学创作

令狐采学创作

菜单栏中包含了各种操作项。

文件:“新建”、“打开”、“ 保存”、“关闭”这些都是对

文档最基本的操作;“输出JC程序”可以将编好的程序以JC代码的形式存储。

编辑:在编写复杂程序的过程中,经常会用到多个子程序服务

于一个主程序,这时编辑菜单中的“主程序”、“删除子程序”就为编程带来了便利。“编辑JC代码”可以把流程图程序的JC代码转换到JC代码编辑窗口中进行编辑修改。

视图:可以隐藏/显示VJC1.6界面中的工具条、JC代码显示

区;“连接指示”则可以在流程图生成区各个模块的可连接位置显示/隐藏指示红点,帮助初学者掌握模块连接的技巧;可以用“流程图背景”为流程图生成区更换背景;通过“放大、缩小流程图”、“全图缩放”来调整流程图大小。

工具:分为“下载当前程序”、“下载JC程序文件”、“机

器人自检程序”、“机器人表演程序”、“更新操作系统”、“设置选项”六个功能项。“下载当前程序”指将当前流程图程序下载到机器人中去;“机器人自检程序”提供了检测机器人各部分功能的程序;“更新操作系统”可以恢复机器人的操作系统ASOS。

图3-2 流程图编程界面

工具栏

令狐采学创作

令狐采学创作

工具栏上有若干快捷按钮,使用起来很方便。各快捷按钮的作用如下图所示:

模块库区

模块库可以用鼠标点击打开。图3-3是AS-InfoM机器人的模块库展开图。如果机器人型号不同,模块库会略有不同。

(a) (b)

(c)

(d)

图3-3 模块库

流程图生成区

图3-2中最大一个窗口就是流程图生成区,模块库区的模块可以移入到这个区域,连接生成流程图程序。连接好的模块会成为一个整体,可以一起移动。也可以断开模块之间的连接,删除或插入模块。

JC代码显示区

VJC1.6可以根据流程图程序自动生成JC语言的源程序。流程图编好后,点击“JC代码”快捷按钮,在“JC代码显示区”中就会显示与流程图对应的JC代码。

垃圾箱

在编程的过程中,可以将不用的模块移到“垃圾箱”处,在“垃圾箱”上点击一下,即可删除此模块。

图3-4 垃圾箱

JC代码程序编辑界面

令狐采学创作

JC代码显示区 在图3-1所示对话框中,选择“新建-JC代码程序”,就垃圾箱 令狐采学创作

进入了JC代码程序编辑界面(如图3-5所示)。它由这样几个部分组成的:菜单栏、工具栏、状态栏、JC代码编辑窗口、JC语句交互输入区以及交互信息窗口。

图3-5 JC代码编辑界

菜单栏

菜单栏中包含了各种操作项,如下所述。

文件:“新建”、“打开”、“ 保存”、”另存为”“关闭”

这些都是对JC程序文件最基本的操作;

编辑:提供了在JC代码编辑环境中所需要的命令,包括:撤

销、重复、剪切、复制、粘贴、查找、查找下一个、查找上一个、替换、转到行。

视图:分为工具栏、状态栏、显示JC代码、流程图背景、连

接指示、放大流程图、缩小流程图、全图缩放。它们具有隐藏/显示工具栏、状态栏、模块上的红点等功能。 工具:分为“下载当前程序”、“下载JC程序文件”、“机

器人自检程序”、“机器人表演程序”、“更新操作系统”五个功能项。“下载当前程序”可将当前JC程序下载到机器人中去;“机器人自检程序”提供了检测机器人各部分功能的程序;“更新操作系统”可以恢复 机器人的软件系统ASOS。

窗口:分为“流程图窗口”、“层叠”、“水平平铺”、“垂

直平铺”、以及打开JC程序窗口的选项。.

令狐采学创作

令狐采学创作

工具栏

工具栏上有若干快捷按钮,使用起来很方便。各快捷按钮的作用如下图所示:

JC代码编辑窗口

在JC代码编辑窗口中,可以同时打开多个JC程序进行编辑(在菜单栏“窗口”选项卡中选择“层叠”、“水平平铺”或“垂直平铺”选项)。支持剪贴板功能,自动缩进,关键字颜色显示,双击选词。

图3-6 JC程序编辑窗口

交互信息窗口

交互信息窗口可以显示编译结果、机器人程序中的全局变量、函数名列表、机器人正在运行的进程表、交互输入语句的执行结果,如图3-7所示。

JC语句交互输入区 结果输出区 输出项目选择列表 图3-7 交互信息窗口

如果下载的JC程序有语法错误,在结果输出区会显示出

令狐采学创作

令狐采学创作

来。用鼠标双击“编译结果”窗口中的编译错误,光标会自动跳转到出错的JC语句所在行,如图3-8所示。

图3-8 编译结果信息

两个界面之间的切换

在流程图编辑界面中,点击工具栏上“编辑JC代码”快捷按钮

,会切换到JC代码编辑界面。

在JC代码编辑界面中,点击工具栏上“流程图窗口”快捷按钮

,可以切换到流程图编辑界面。

任何时候,通过“窗口”菜单可以直接选择JC代码编辑界面或者流程图编辑界面。

使用键盘上的“F12” 键可以快速地在两个界面之间来回切换。

令狐采学创作

令狐采学创作

第二节 快速入门

―― 走四边形的机器人 ――

4.2.1编程思路

机器人走四边形,就是让机器人完成“前进→转弯→前进→转弯→前进→转弯→前进→转弯”的动作,也就是说机器人需要完成四个“前进→转弯”动作。

而要让机器人完成一个“前进→转弯”,需要启动电机,使机器人以一定的速度向前运行一段路程,然后停下,旋转90°,再停下。这样就走完了四边形的一边。

要让机器人走四个边,有一个简便的方法,这就是循环。上述步骤循环4次,机器人就能够走出一个四边形了。 4.2.2程序编写

1.1.1 流程图编程

进入VJC1.6的流程图编辑界面,编写此程序的步骤如下: 用鼠标点击左边“控制模块库”,从中选择“多次循环”模块。将它拖到流程图生成区,与“主程序”相连,如图4-1(a)所示。鼠标右键点击此模块,就会出现图4-1(b)所示对话框,在对话框中将循环次数写为4,这意味着下面的循环体要重复执行4次。

令狐采学创作

令狐采学创作

(a) (b)

图4-1 多次循环

点击“执行器模块库”,从中选择“直行”模块(如图4-2(a)所示),连接在流程图中。在模块上右击鼠标,打开参数设置对话框(图4-2(b))。在对话框中可设置速度和时间,根据要求选择合适的值,机器人就可以完成走一条边的任务。

(a)

((b)

图4-2 直行

再点击“执行器模块库”,选择“转向”模块(如图4-3(a)所示),连接在流程图中,在模块上点击鼠标右键打开参数设置对话框,在“速度”和“时间”状态栏内,分别填写适当的值,使机器人向右旋转90°(图4-3(b))。

(a) (b)

图4-3 转向

最后,打开程序模块库,将“结束”模块添加上去,放在循环体外,就完成了走四边形的流程图的编写(图4-3(a))。

程序编写完毕,接下来就要下载到机器人里运行、调试了。首先把机器人和计算机用串口通信线连接起来,打开机器人电源开关,然后点击工具栏中的“下载”快捷按钮

,就会

出现一个“智能下载程序”对话框,并显示下载进程,待看到“下载成功”等字样时,说明程序已经下载到机器人中。

运行程序时,拔下串口通信线,将机器人带到开阔平坦的地方,按下机器人身上的“运行”键,机器人就开始走四边形

令狐采学创作

令狐采学创作

了。也许你会发现机器人走的不很规则,转弯的角度不正确……,那么就需要修改“直行”和“转向”模块中的参数,对机器人进行反复调试,最后他一定能走个漂亮的四边形!

1.1.2 JC

代码编程

接下来让我们看看JC代码编程的相关知识。在流程图编辑界面中,点击菜单栏中的“文件”选项卡,在下拉菜单中选择“新建”,这时就会出现一个可供选择的对话框,请选择“JC代码程序”,确定,就进入了JC代码的编辑界面,在编辑窗口中键入:

void main() {

int i;

for(i=0 ; i<4;i++) {

drive( 80 ,0); wait( 0.500000 ); stop(); drive( 0 , 80 ); wait( 0.100000 ); stop(); }

令狐采学创作

令狐采学创作

}

这就是走四边形的JC代码程序,与前面的流程图是一致的。下面我们就来看看该程序中JC代码的含义。

1)

main是系统定义的一个函数,每一个JC程序总是从main函数开始执行的;所以第一句就可以理解为一个程序的“开头”;main函数的开始和结尾分别有个“{”和“}”;

2) 3) 4)

void可以理解为“不带返回值”;

程序中每一句结尾都要加“;”这是C语言语法规定! for(i=0 ; i<4;i++) { 循环体 }

这是一个循环语句,4是循环次数,只要循环次数没有达到4次就执行{}中的语句(称为循环体),执行完4次循环体之后,就去执行{}后面的语句。在这个例子中,我们是要机器人走一个四边形,因此执行完4次就可以结束了。

5)

drive( 80 ,0);drive(a , b)是让机器人移动的库函数,可以决定左右电机的速度,左电机速度=a+b,右电机速度=a-b。本句的意思是让机器人以80的速度向前直行; wait( 0.500000 );wait(t)是让机器人延续时间的库函数,与上句结合起来可以理解为让机器人向前走0.5秒; stop();这是让机器人停止的库函数,上面三句意为让机

令狐采学创作

令狐采学创作

器人以80的速度向前走0.5秒然后停下来;

库函数drive(a , b)和wait(t)中的参数a、b和t可以由你根据编程的需要自行设定。

6)

drive(0,80);

本句的意思是让机器人右转,您可以计算验证一下; 理解了吗?如果你还有什么疑问,可以参看本书的第6章,相信你一定能很快掌握JC语言!接下来就要把JC代码程序下载到机器人里运行、调试了,点击工具栏中的“下载”快捷按钮

,会出现一个“智能下载程序”对话框,并显示下载

进程,待看到“下载成功”等字样,就可以让机器人运行这个程序了。

➢ 程序的下载及运行

下载程序须按照下述方法:用串口通信线一端接机器人的下载口,另一端接计算机机箱后面的一个九针串口,打开机器人电源开关,单击菜单栏中“工具(T)”选项卡,在弹出的下拉菜单中单击“下载当前程序(D)”,就可以下载程序了。

注:下载程序也可以使用工具栏上的“下载”快捷按钮(下载流程图)或

(下载JC代码程序)。

图4-5 下载对话框

按照上述步骤操作后,会出现一个智能下载程序对话框,并显示下载进程,等出现“下载成功!”字样时,程序已经下

令狐采学创作

令狐采学创作

载到机器人中了。关闭对话框,拔下串口通信线,按下机器人身上的“运行”按钮,机器人就会运行所下载的程序。

➢ 调试程序

程序下载运行时,注意检查机器人运行状态是否符合要求,比如前进的距离、转向的角度是否恰当。如不合要求,就需要调整参数,甚至修改程序,再下载运行,直到满意为止。

令狐采学创作

令狐采学创作

第三节 流程图编程方法 4.3.1模块的基本操作

模块是编程的基本单元,对模块的操作也是经常要用到的。因此本章对模块的基本操作进行详细介绍。

模块的新增、连接和插入

1.模块的新增、连接和插入

从模块库内选择一个模块的图标,把它移入流程图生成区,你的程序就新增了一个模块。要使这个模块在程序中变为有效,就需要将此模块连接到程序主体上。

要在程序的末端新增一个模块,先在模块库中点击需要增加的模块,模块就可随光标移动了,将新增模块拖到流程图生成区中,放在程序末端,光标的顶点放在上方模块的红点处,单击鼠标,新增模块就与程序主体连接上了。(注:单击菜单栏中的“视图”选项卡,在下拉菜单中选择“连接指示”选项,可以显示/隐藏模块上的红点)

模块连接上之后,会出现以下标志:

a) b) c)

模块之间有箭头连接起来; 上方模块的“红点”消失;

JC代码显示区自动生成与新增模块对应的JC

代码。

令狐采学创作

令狐采学创作

在某个模块后面插入一个新增模块时,先把这个模块后面的部分移开,把新的模块连接在这个模块后面,再把前边移开的部分连接在新模块的后面。

模块的移动

调整模块的前后顺序。以要操作的第一个模块为界,把原流程图分成两个部分,把两个操作模块都移开,再以与原来相反的顺序把它们插入即可.

将模块从一个任务移动到另外一个任务。把要插入的模块从原任务中移出来,然后插入到目标任务中去。

模块的复制

无法直接复制一段流程图程序,如果某一段流程图程序重复使用次数很多,建议将它编成子程序,就可以在主程序中很方便地调用。

模块的删除

流程图生成区中的模块均可以删除( “主程序”、“子程序”模块除外),删除的方法为:将要删除的部分从程序主体中“拿起”,再将其拖到垃圾箱处,鼠标在垃圾箱上点击一下,此部分就会自动消失。

另:从模块库中取出的模块在没有“放下”之前,可以通过点击鼠标右键取消。

令狐采学创作

令狐采学创作

4.3.2模块的功能和使用

VJC的模块分八类:执行器模块库、传感器模块库、控制模块库、程序模块库、AS多功能扩展卡、伺服电机驱动卡、伺服电机驱动卡(A) 及通讯模块。不同型号的机器人能用的模块略有不同,下面分别对各模块库加以介绍。(通讯模块和伺服电机驱动模块在此不做介绍)

执行器模块库

执行器模块和机器人的动作有关,其中包括:直行、转向、启动电机、停止电机、延时等待、发音、显示、计算、设置眼睛以及自定义模块等。AS-EI型号的机器人,执行器模块不包含直行、转向模块,但增加了马达启动、马达停止模块,启动电机以及停止电机模块也与其它型号机器人有所不同,这些模块该如何使用呢?

图标 ――直行――

模块 对话框 ⑴ 功能:“直行”模块主要用于控制机器人前进、后退。 ⑵ 操作:将“直行”模块移到流程图生成区,并连接在程序中的相应位置。设置参数时,右击“直行”模块,在弹出的

令狐采学创作

令狐采学创作

对话框中输入速度与时间。

⑶ 设置参数说明:

速度:有两种方式进行设置。可在对话框中直接输入速度值,也可以用鼠标拖动速度标尺上的游标来设置速度。当输入值为正时,机器人前进;输入值为0时,机器人停止;输入值为负时,机器人后退。输入值的绝对值越大,机器人移动速度就越快。这里设置的速度为一个占空比,因此没有单位。

注意:模块的名称会随着不同的速度而变化,分别为“前进”、“后退”、“停止”。 时间:在对话框中输入机器人移动的时间,单位为秒;你也可以选中“随机时间”,它可产生小于输入值的随机时间。

图标 ――转向――

模块 对话框 ⑴ 功能:“转向”模块主要用于控制机器人转向。

⑵ 操作:将“转向”模块移到流程图生成区,并连接在程序中的相应位置。设置时,右击“转向”模块,在弹出的对话框中输入速度和时间。

⑶ 设置参数说明:

速度:可用两种方式进行设置。可在对话框中直接输入速

令狐采学创作

令狐采学创作

度值;也可以拖动速度标尺上的游标进行设置。当输入值为正时,机器人右转;值为0时,机器人停止;值为负时,机器人左转;输入值的绝对值越大,机器人转动速度就越快。

注意:模块的名称会随着不同的速度而变化,如果设置右转速度,模块名称为“右转”;如果设置左转速度,模块名称为“左转”;如果设置速度为0,模块名称为“停止”。 时间:在时间输入对话框中输入机器人转向的时间,单位为秒;你也可以选中“随机时间”,它可产生小于输入值的随机时间。在机器人没有安装特定的角度传感器之前,机器人的转角是由速度和时间两个参数共同决定的。

图标 ――启动、停止电机――

模块 对话框 ⑴ 功能:

“启动电机”模块主要用于控制机器人的左右电机功率。此模块可实现左右两只主动轮按不同速度、不同方向行走,如直行、旋转、走弧线等。

“停止电机”模块主要用于停止驱动电机和扩展电机。 ⑵ 操作:用鼠标将“启动电机”模块移到流程图生成区,

令狐采学创作

令狐采学创作

并连接在程序中的相应位置。设置时,右击“启动电机”模块,在弹出的对话框中输入左/右电机功率。

⑶ 设置参数说明:

左/右电机功率设置:可用两种方式进行设置:直接输入左/右电机功率值,或拖动游标进行设置。

扩展电机设置:扩展电机的速度是固定的,速度值为100。如果要改变扩展电机的转向,需将扩展电机的接线端子拔下来,调个方向。

――延时等待――

图标 模块 对话框 ⑴ 功能:“延时等待”模块主要是让机器人的前一个状态保持一段时间。

⑵ 操作:用鼠标将“延时等待”模块移到流程图生成区,并连接在程序中的相应位置。设置时,右击“延时等待”模块,在弹出的对话框中输入时间参数,以“秒”为时间单位。

⑶ 设置参数说明:

时间:在对话框中输入机器人延时的时间,单位为秒;你也可以选中“随机时间”, 它可产生小于输入值的随机时间。

――发音――

令狐采学创作

令狐采学创作

图标 模块 对话框 ⑴ 功能:“发音”模块主要用于让机器人发音,唱一个音符。

⑵ 操作:用鼠标将“发音”模块移到流程图生成区,并连接在程序中的相应位置。设置时,右击“发音”模块,在弹出的对话框中可选择简谱的节拍(如二分之一音符)及音阶(如1、2、3),也可直接输入时间与音频参数。

⑶ 设置参数说明:

时间:在对话框中输入机器人发音的持续时间,单位为秒。

二分之一音符代表发音0.5秒,四分之一音符代表发音0.25秒,其余以此类推。

发音频率设置:这是机器人发音的音阶,单位为赫兹。 1、2、3等,代表用简谱音阶。

休止符,表示不发声,需指定时间间隔。

自定义,用于在音频输入对话框直接输入发音的频率,

 图标 ――显示――

模块 对话框 令狐采学创作

令狐采学创作

⑴ 功能:在机器人LCD液晶显示屏上显示信息。

⑵ 操作:用鼠标将“显示”模块移到流程图生成区,并连接在程序中的相应位置。设置时,右击“显示”模块,在弹出的对话框中输入显示信息。

注意:机器人的LCD不能显示中文 ⑶ 设置参数说明:

显示信息设置:直接在显示信息输入对话框中输入英文、数字等信息。可以显示两行信息,每行最多显示16个字符。

如果选择了“引用变量”,会弹出一个如下图的变量百宝箱,可以选择要显示的数据。

图标 ――计算――

模块 对话框 ⑴ 功能:可用于加减乘除计算,或对变量进行赋值。 ⑵ 操作:用鼠标将“计算”模块移到流程图生成区并连接在程序中的相应位置。设置时,右击“计算”模块,在弹出的对话框中输入计算表达式。

⑶ 设置参数说明:

令狐采学创作

令狐采学创作

计算结果赋值设置:点击整型变量按钮,弹出“变量百宝箱”对话框,在变量百宝箱对话框中选择变量,用来存放计算的结果。

运算符号设置:在下拉列表框中选择运算符号。

计算数设置:在输入框中输入整数或小数,也可以引用变量。

图标 ――自定义模块――

模块 对话框 (1)功能:提供用户自定义功能,利用该模块直接用JC代码进行编写程序。

(2)操作:用鼠标将“自定义”模块移到流程图生成区并连接在程序中的相应位置。设置时,右击“自定义”模块,在弹出的对话框中编写JC代码。

(3)设置参数说明:在文本框中编写所需JC代码。 注意:编写JC代码时应确保语法无误,否则流程图文件无法下载。

令狐采学创作

令狐采学创作

下面介绍一下AS-EI机器人执行器模块中的电机启动、电机停止、马达启动、马达停止模块。

――电机启动――

图标 模块 对话框 1)

功能:“电机启动”模块主要用于控制EI控制器调速电机1和调速电机2,分别控制电机运转的快慢和方向。

2)

操作:用鼠标将“启动电机”模块移到流程图生成区,并连接在程序中。此时系统默认启动电机1,速度100,方向正转。右击“电机启动”模块,在弹出的对话框中输入电机功率参数,可以控制调速电机1和调速电机2,按不同速度、不同方向运转。

3)

设置参数说明:调速电机1/2设置:可用两种方式进行设置。可在对话框中直接输入调速电机1/2功率值;也可通过游标设置,用鼠标拖动游标到要求设置的速度值。注意,电机启动模块默认情况下启动电机1,调速

令狐采学创作

令狐采学创作

电机前的多选框能选择电机1、电机2或同时选择电机1、电机2。

机型 AS_UII AS_M 否 AS_MII 否 AS_INFOM AS_INFOX AS-EI 否 否 是 是否适用 否 ――电机停止――

图标 模块 对话框 1)

功能:“电机停止”模块主要用于停止EI控制器可调速电机。

2)

操作:将“电机停止”模块移到流程图生成区,并连接在程序中。右击“电机停止”模块,在弹出的对话框中选择要停止的电机。

机型 AS_UII AS_M 否 AS_MII 否 AS_INFOM AS_INFOX AS-EI 否 否 是 是否适用 否 ――马达启动――

图标 模块 对话框 令狐采学创作

令狐采学创作

1)

功能:“马达启动”模块控制EI控制器上四个马达的正转、反转。

2)

操作:“马达启动”模块移到流程图生成区,并连接在程序中。右击“马达启动”模块,在弹出的对话框中选择要启动马达和转动的方向。

机型 AS_UII AS_M 否 AS_MII 否 AS_INFOM AS_INFOX AS-EI 否 否 是 是否适用 否 ――马达停止――

图标 模块 对话框 1)

功能:“马达停止”模块主要用于停止EI控制器不可调速电机。

令狐采学创作

令狐采学创作

2)

操作:将“马达停止”模块移到流程图生成区,并连接在程序中。右击“马达停止”模块,在弹出的对话框中选择要停止的电机。

注意:“马达停止”缺省设置为马达1停止。

机型 AS_UII AS_M 否 AS_MII 否 AS_INFOM AS_INFOX AS-EI 否 否 是 是否适用 否 ➢

传感器模块库

传感器模块包括两类:一类模块具有传感器模块的基本功能,即读取传感器检测值,称为单功能模块;另一类模块具有读取传感器检测值和进行条件判断两种功能,称为带判断功能模块。带判断功能模块可以根据传感器检测到的数值,进行条件判断,其作用相当于单功能模块与条件判断模块的结合。

1)

单功能模块与带判断功能模块概述

单功能模块右图所示,形状为紫色平行四边形。

该类模块的功能是检测传感器数值,其功能简单,只需要设置一个参数,即获取传感器检测数值的变量。设置方法如下(以“碰撞检测”模块为例):

令狐采学创作

令狐采学创作

①用鼠标右键单击传感器模块,弹出下图所示对话框

②左键单击“碰撞变量一”按钮,弹出“变量百宝箱”对话框:

③在变量百宝箱中,单击所需要的变量,即可选中该变量(三个变量任选)。

注:只有当该变量旁出现一把钥匙时选择才是有效的 除此之外,大多数单功能模块不需进行其它设置,亮度检测、转角检测模块例外,下文将会详述。

带判断功能模块如右图所示,形状为紫色菱形。

这类模块除了设置变量外,还可设置一定的判断条件。

2)

两类模块之间的功能切换

当传感器模块从模块库移动到流程图生成区时,是单功能模块,即只具有传感器数值检测功能,我们想要获得带判断功能的传感器模块,必须进行功能切换。

切换的步骤如下

令狐采学创作

令狐采学创作

①在单功能模块上单击鼠标右键,弹出下图所示对话框: ②左键单击“检测完成后,进行条件判断”按钮,出现以下对话框:

③设置条件判断表达式(如“碰撞变量一 == 前”之类)。设置完成后单击“确定”,则带判断功能的传感器

模块就生成了。模块形状相应也发生变化,如下图所示:

注意,以上为不可逆过程,带判断功能的传感器模块不能切换成单功能模块。 下面将对VJC1.6传感器模块库进行详细说明。

――红外测障――

图标 模块 参数设置对话框 令狐采学创作

令狐采学创作

⑴ 功能:红外传感器包括两个红外发射传感器和一个红外接收模块,能够检测到机器人左前/右前/正前方是否有障碍物。

⑵ 操作:将“红外测障”模块移到流程图生成区,并连接在程序中的相应位置。设置时,右击“红外测障”模块,在弹出的对话框中设置相应的参数。

⑶ 设置参数说明:

单功能模块

红外变量一:存储红外传感器检测值的变量。若要更换存储变量,左键单击该变量,可在弹出的变量百宝箱中选择其它变量名称。

带判断功能的模块

①红外变量一:功能同上。 ②条件判断表达式

例:“红外变量一 == 左”代表如果检测到障碍在左边,条件判断成功,执行“是”一侧连接的模块;其他任何情况下,条件判断失败,执行“否”一侧连接的模块。

注:“=”和“!=”的含义为“有”和“没有”或者“在”和“不在” 令狐采学创作

令狐采学创作

――碰撞检测――

图标 模块 对话框 ⑴功能:用于检测机器人是否碰到障碍物,它能判断左/右/前/后/左前/左后/右前/右后等方向。

⑵操作:将“碰撞检测”模块移到流程图生成区,并连接在程序中的相应位置。设置时,右击“碰撞检测”模块,在弹出的对话框中设置相应的参数

⑶设置参数说明:

单功能模块

①“碰撞变量一”按钮:存储碰撞传感器检测值的变量。若要更换存储变量,鼠标左键单击该按钮,在弹出的变量百宝箱中可选择其它变量。

带判断功能模块

①“碰撞变量一”按钮:功能同上 ② 条件判断表达式

例:“碰撞变量三 == 左”代表如果检测到左边发生碰撞,条件判断成功,执行“是”一侧连接的模块;否则条件判断失败,执行“否”一侧连接的模块。

令狐采学创作

令狐采学创作

――亮度检测――

模块 对话框 图标 ⑴功能:用于检测环境的光线明暗,传感器的返回值为0~255,值越大,说明光线越暗。

⑵操作:将“亮度检测”模块移到流程图生成区,并连接在程序的相应位置。设置时,右击“亮度检测”模块,在弹出的对话框中设置相应的参数

⑶ 设置参数说明:

单功能模块

①“方式”单选按钮,如下表所示:

平均 左 右 偏差 检测左右两个光敏,再取平均值 检测左侧光敏 检测右侧光敏 左亮度检测值与右亮度检测值的差值 ②“亮度变量一”按钮:存储光敏传感器检测值的变量。若要更换存储变量,可点击它,在弹出的变量百宝箱中选择其它变量。

带判断功能的模块

①“方式”单选按钮:功能同上

令狐采学创作

令狐采学创作

②“亮度变量一”按钮:功能同上

③条件比较关系:设置左边的亮度变量与右边的参数如何进行比较。

例: “平均 < 200”代表左右光敏检测到的平均值小于200的时候,条件判断成功,执行“是”一侧连接的模块;否则条件判断失败,执行“否”一侧连接的模块。

――地面灰度检测――

模块 对话框 图标 ⑴ 功能:通过照射地面,检测地面的反射光强。传感器的返回值为0~255,其值越大,说明地面越暗。

⑵ 操作:将“地面检测”模块移到流程图生成区,并连接在程序的相应位置。设置时,鼠标右键单击“地面检测”模块,在弹出的对话框中设置相应的参数。

⑶ 设置参数说明: 单功能模块

①“地面变量一”按钮:存储地面传感器检测值的变量。若要更换存储变量,可点击它,选择其它变量。

带判断功能的模块

①“地面变量一”按钮:功能同上

令狐采学创作

令狐采学创作

②第二项是条件比较关系:设置左边的地面变量与右边的参数如何进行比较。

例: “地面变量二 > 200”代表地面检测值大于200,即地面灰度比200灰度更暗的时候,条件判断成功,执行“是”一侧连接的模块;否则条件判断失败,执行“否”一侧连接的模块。

图标 ――声音检测――

模块 对话框 ⑴ 功能:用于检测声音的大小,反馈的检测值为0~255之间的整数,值越大,声音越响,值越小,声音越弱。

⑵ 操作:将“声音检测”模块移到流程图生成区,并连接在程序的相应位置。设置时,鼠标右键单击“声音检测”模块,在弹出的对话框中设置相应的参数。

⑶ 设置参数说明:

单功能模块

声音变量一:存储声音传感器检测值的变量。若要更换存储变量,鼠标左键单击该按钮,可选择其它变量。

带判断功能的模块

令狐采学创作

令狐采学创作

① 声音变量一:功能同上

② 条件比较关系:设置左边的声音变量与右边的参数如何进行比较。

例: “声音变量一 > 50”代表声音检测值大于50,即检测到的声音比50更响(需要持续对机器人说话)的时候,条件判断成功,执行“是”一侧连接的模块;否则条件判断失败,执行“否”一侧连接的模块。

――系统时间――

模块 对话框 图标 ⑴ 功能:“时间”模块主要用于检测机器人运行的时间。程序开始运行,则计时开始。下载程序和按下复位键都会使时间恢复从零开始。

⑵ 操作:将“系统时间”模块移到流程图生成区,并连接在程序的相应位置。设置时,鼠标右键单击“系统时间”模块,在弹出的对话框中设置相应的参数。

⑶ 设置参数说明:

单功能模块

①“时间变量一”按钮:用来存储系统时间的变量,存放

令狐采学创作

令狐采学创作

的是从程序开始到本次检测(该模块投入运行)为止的时间。若要更换存储变量,可点击它,选择其它变量。

带判断功能的模块

①“时间变量一”按钮:功能同上;

②条件比较关系:设置左边的时间变量与右边的参数如何进行比较。

例: “时间变量一 > 10.00”代表检测到的时间大于10秒的时候,条件判断成功,执行“是”一侧连接的模块;否则条件判断失败,执行“否”一侧连接的模块。

――转角检测 ――

模块 对话框 图标 编码器清零 编码器检测 令狐采学创作

令狐采学创作

⑴ 功能:检测左右轮子旋转的角度,并可用于编码计数器置零。传感器的返回值为计数器累加值。轮子转一圈,有33个计数脉冲,一个计数脉冲对应旋转角度360/33≈11度。光电编码器采用的是16位计数器,最大计数65535个脉冲,计数器溢出后自动复位为0,并且从头开始计数。在编程时应注意这个特性。

⑵ 操作:将“转角检测”模块移到流程图生成区,并连接在程序的相应位置。设置时,右击“转角检测”模块,在弹出的对话框中设置参数。

⑶ 设置参数说明: 单功能模块 ①检测对象:

左 右 检测左轮转角 检测右轮转角 ②功能选择:可用来检测编码器值,即检测转角;也可以进行编码器清零,即令编码计数器的值恢复为零,从头开始计数。

③“转角变量一”按钮:用来存储编码器计数值的变量。

令狐采学创作

令狐采学创作

若要更换存储变量,可点击它,可选择其它变量 。

带判断功能的模块

①检测对象:功能同上

②条件比较关系:设置左边的转角变量与右边的参数如何进行比较。

注:以上过程不可逆,即先设置“编码器清零”后,不能重新设置为“编码器检测”。同样如先选择为“编码器检测”,则不能重新设置为“编码器清零”。

控制模块库

程序结构一般是由顺序结构、循环结构、选择结构这三种结构组成。在编写程序过程中,最基本的结构是顺序结构,即从上往下依次执行。当遇到一组模块需要重复执行时,就可以使用循环结构,按照指定方式重复执行。选择结构是在程序执行时,根据设置的判断条件,在两组模块中选择一组执行。灵活使用这三种结构,可以提高编程的效率,使程序清晰明了。

VJC1.6在控制模块库中提供了四种控制模块,分别为:“多次循环”、“永远循环”、“条件循环”和“条件判断”模块。用它们可以实现循环结构和选择结构。

――多次循环――

图标 模块 对话框 令狐采学创作

令狐采学创作

(1)功能:“多次循环”模块允许多次执行同一组指令。 (2)操作:将“多次循环”模块移到流程图生成区,并连接在程序的相应位置。设置时,右击“多次循环”模块,在弹出的对话框中输入循环次数,然后点“确定”。接下来在循环体中插入需重复处理的其它模块。

(3)范例:让机器人连续唱do re mi 三次。操作如下,如图所示:

a)

先将“多次循环”模块移到流程图生成区,与主程序相连,设置循环次数为3;

b) c)

再将“发音”模块移入到循环体内部,进行设置; 再将“结束”模块连接在循环体外,程序的末尾。

运行结果:机器人连续唱do re mi 三次。

图多次循环范例

图标 ――永远循环――

模块 对话框 无设置对话框 (1)

功能:“永远循环”模块永远执行循环体内的同一

令狐采学创作

令狐采学创作

组指令。

(2)

操作:将“永远循环”模块移到流程图生成区,并

连接在程序中,在循环体中插入需要永远循环处理的模块。

(3)

范例:如果机器人检测到碰撞,就发音,如图所

示:

a)

先将“永远循环”模块移到流程图生成区,与主程序相连;

b)

再将“碰撞检测”模块移入到循环体内部,进行条件判断设置,如图右上图所示:

c)

再将“发音”模块移入到碰撞检测的模块中,进行设置,如图右下图所示:

d)

再将“结束”模块连接在循环体外,程序的末尾。

运行结果:按一按机器人的碰撞环,机器人就发出声音。

图 永远循环

图标 ――条件循环――

模块 对话框 (1)功能:当设定的判断条件成立,就重复执行循环体。一旦条件不成立,就退出循环。

令狐采学创作

令狐采学创作

(2)操作:将“条件循环”模块移到流程图生成区,并连接在程序的相应位置。设置时,右击“条件循环”模块,在弹出的对话框中输入判断条件,然后点“确定”。接下来在循环体中插入需重复处理的其它模块。

(3)范例:在周围很安静的情况下,机器人一直重复进行声音检测。你一旦发出响一点的声音,机器人就开始运动,如图所示:

a)

先将“条件循环”模块移到流程图生成区,与主程序相连;

b)

在模块上点击右键进行设置,在“整形变量一”处点击,就会出现变量百宝箱,点击声音图标,然后选择“声音变量一”(如图右上图所示),确定后,再按照图右下图设置条件;

c) d)

接着将“声音检测”模块移入到循环体内部; 然后将“直行”模块放在循环体外,设置速度和时间;

e)

最后将“结束”模块连接在程序的末尾。

运行结果:一发出响一点的声音,机器人就行动起来。

图 条件循环

 图标 ――条件判断――

模块 对话框 令狐采学创作

令狐采学创作

(1)功能:根据条件在两组指令中选择一组执行,如果满足条件就执行左边“是”的指令,不满足条件就执行右边“否”的指令。可以对任何全局变量和传感器变量进行条件判断。

(2)操作:将“条件判断”模块移到流程图生成区,并连接在程序的相应位置。设置时,右击“条件判断”模块,在弹出的对话框中输入判断条件,然后点“确定”。在“条件判断”模块中插入其它执行模块。

(3)范例:机器人对外界的光线进行检测,如果外界光线很暗,就安静地呆着,如果光线足够亮,就旋转并发音(如图所示)。要点如下:

a)

将“亮度检测”模块的参数设置为“亮度变量一”;

b)

将“条件判断”模块的条件判断表达式设置为“亮度变量一 < 200”;

图 条件判断

――控制模块的嵌套应用――

前面介绍的各种控制模块也可以嵌套使用,共同完成一个复杂任务。那么这些模块是如何嵌套的呢?用例子来说明。

令狐采学创作

令狐采学创作

例如:让机器人不断检测外界碰撞,没有碰撞时不作反应,当右方有碰撞时就唱“do—”;前方有碰撞时就显示“re—”;左方有障碍物就唱“mi—”。

我们先来看看这个程序(见图5-5)。不断地检测碰撞,就需要用到“永远循环”模块和“碰撞检测”模块;判断三个碰撞方向,我们就要设置三个判断条件。这三个判断条件表达式设置方法都是一样的,表达式左边选择“碰撞变量一”,条件比较关系选择“= =”,要判断的方向分别选“右”,“前”,“左”,如图5-6所示:

图5-5 控制模块的嵌套应用 图5-6 检测方向的设置

还可以根据需要进行多次嵌套。但是多次嵌套势必增加程序的复杂性,这时你可以通过调用子程序使程序变得逻辑清晰。子程序用法在5.4节中进行介绍。

程序模块库

有时候要求机器人同时做几件事,比如一边跳舞一边唱歌,在计算机技术中这叫做多任务。还有的情况下,某一段功能需要在程序中重复出现,或者复杂的程序需要进行局部封装,就可以用到子程序。VJC1.6能很方便地支持多任务和子程序。可以同时创建多达16个任务和10个子程序。关于多任务和子程序的编程方法将在后面将详细介绍,这里先来看看与之相关的程序模块。

令狐采学创作

令狐采学创作

――任务开始――

模块 无设置对话框 对话框 图标 (1)功能:用于新建一个与主程序同时运行的子任务。 (2)操作:用鼠标将“程序模块库”中的“任务开始”模块移到流程图生成区,“任务”模块自动定位在主程序右侧。可以像编写主程序一样编写新任务,而且“任务”模块可以像普通模块一样删除。 注:新建子任务不能超过16个。

――结束模块――

图标 模块 对话框 无设置对话框 (1)功能:用于给主程序或任务加一个结束标志,该模块不产生JC代码。结束模块后不能再连接其他模块。

(2)操作:将“结束”模块移到流程图生成区,并连接在主程序或任务的结束位置。

――新建子程序――

模块 对话框 图标 令狐采学创作

令狐采学创作

(1)功能:把需要重复使用的一组模块新建为“子程序”,便于在主程序中调用,以精简程序,增强程序的可读性。

(2)操作:新建子程序是一个特殊的模块,它是子程序调用的第一步。其操作如下:

a)

用鼠标点击“程序模块库”中的“新建子程序”模

块,就会弹出一个新建子程序对话框。在对话框中“子程序位置”下,有两个选项:“系统子程序”和“其它程序……”。 “系统子程序”提供常用的子程序模板;“其它程序……”可以选择任何已编制程序,以调用其中存在的子程序。

当选择“系统子程序“时,右边的列表框中显示了系统提供的常用子程序模板。其中“自定义”选项可用来建立一个新的子程序,你可以在子程序名称处为这个子程序命名。其他系统子程序选项包括唱歌、跳舞、避障等,均是比较常用的子程序模板。用户既可以直接使用这些子程序,还可以根据自己的需要,在已有模板的基础上对子程序进行修改。

令狐采学创作

令狐采学创作

当选择“其它程序……”时,会弹出一个对话框,在这里我们可以选择任一流程图文件,如果该流程图文件包含子程序,列表框中就会出现存在的子程序名,用户也可以调用这些子程序。

新建子程序“确定”后,会自动进入该子程序的编辑窗口,可以像编辑主程序一样编辑子程序。每个子程序都有的编辑窗口。

注:新建子程序不能超过10个。 

――子程序――

图标 模块 对话框 (1)功能:调用一个“子程序”,只能在主程序中使用。只有在新建了子程序之后这个模块才能在主程序界面中出现。

(2)操作:如果新建了子程序,在主程序窗口(主程序窗口可以用工具栏中的“主程序”快捷按钮

切换),在

“程序模块库”中可以看到新建的“子程序”模块的图标。子程序模块可以象其他模块一样移入到流程图生成区,连接在主程序中使用。

注:在子程序模块上点击右键,可打开子程序对话框,选择“编辑”按钮,即可进入此子程序的编辑界面。 令狐采学创作

令狐采学创作

――子程序返回――

图标 模块 无设置对话框 对话框 (1)功能:结束一个用户“子程序”。此模块在子程序编辑界面中出现,只能在子程序中使用。

(2)操作:将“子程序返回”模块从“程序模块库”移到流程图生成区,并连接在子程序的结束位置。

AS多功能扩展卡模块库

AS多功能扩展卡模块对能力风暴扩展卡功能进行了封装,所包含的模块与扩展卡动作相关。AS多功能扩展卡模块库中包括:电机启动、电机停止、数字输入、模拟输入、数字输出、读扩展卡以及写扩展卡等模块。

――电机启动――

图标 模块 对话框 令狐采学创作

令狐采学创作

1)

⑴功能:“电机启动”模块控制AS--Lasy扩展卡上电机的正转、反转。电机接在AS--Lasy扩展卡的DC1、DC2、DC3、DC4口上。

2)

⑵操作:将“电机启动”模块移到流程图生成区,并连接在程序中的相应位置。设置时,右击“电机启动”模块,在弹出的对话框中选择电机和电机转动的方向。

注意:AS多功能扩展卡电机驱动模块由于采用直接检查和修改存储器内容的基本函数,具体使用方法参考AS多功能扩展卡(AS-Lasy扩展卡)使用说明。在VJC1.6模块库中对电机进行驱动时,为避免影响同一内存地址对应的其它电机,采用了屏避位方法。举例如下:

例:将电机扩展模块设置为“电机1正转”

软件生成代码为: int mcm_1 = 0; void main() {

mcm_1 = (mcm_1 & 0b11111100) | 0b11; /* 将电机

控制变量的第一第二位分别设置为1,保持其它位不变

令狐采学创作

令狐采学创作

*/

write (0x4000,mcm_1); /* 0x4000为电机控制输出端口号*/

}

上述代码中mcm_1为全局的电机控制变量,bit0,bit1为电机一的控制位,bit2,bit3为电机二的控制位,bit4,bit5为电机三的控制位,bit6,bit7为电机四的控制位,代码中0b11111100为电机一的屏避位,0b11为电机一正转的电机控制变量。

――电机停止――

图标 模块 对话框 1)

功能:“电机停止”模块主要用于停止AS多功能扩展卡上的电机。

2)

操作:将“电机停止”模块移到流程图生成区,并连接在程序中的相应位置。设置时,右击“电机停止”模块,在弹出的对话框中选择要停止的电机。

令狐采学创作

令狐采学创作

注意:AS多功能扩展卡“电机停止”模块由于采用直接检查和修改存储器内容的基本函数,具体使用方法参考AS多功能扩展卡(AS-Lasy扩展卡)使用说明,“电机停止”为避免影响同一内存地址对应的其它电机,采用了屏避位方法。举例如下:

例:将电机扩展模块设置为“电机1停止”。

软件生成代码为: int mcm_1 = 0; void main() {

mcm_1 = (mcm_1 & 0b11111100) ; /*将电机控制变量的第

一第二设置为0,保持其它位不变。*/

write (0x4000,mcm_1); /*0x4000为电机控制输出端口号*/

}

上述代码中mcm_1为全局的电机控制变量,bit0,bit1为电机一的控制位,bit2,bit3为电机二的控制位,bit4,bit5为电机三的控制位,bit6,bit7为电机四的控制位,代码中0b11111100为电机一的屏避位。

令狐采学创作

令狐采学创作

机型 AS_UII AS_M 否 AS_MII 是 AS_INFOM AS_INFOX AS-EI 否 否 否 是否适用 是 ――模拟输入――

图标 模块 对话框 1)

功能:“模拟输入”模块用于检测扩展卡模拟通道输入。在硬件扩展总线ASBUS上,模拟通道1、模拟通道2、模拟通道3分别对应PE5、PE6、PE7模拟输入口。

2)

操作:将“模拟输入”模块移到流程图生成区,并连接

令狐采学创作

令狐采学创作

在程序中的相应位置。设置时,右击“模拟输入”模块,在弹出的对话框中设置相应参数。

3)

设置参数说明: 单功能模块

a) b) c)

“方式”单选按钮。

选择要检测的模拟输入通道。

“扩展卡模拟输入变量一”按钮:表示存储多功能扩展卡检测值的变量。若要更换存储变量,可点击它,在弹出的变量百宝箱中选择其它四个变量,如“扩展卡模拟输入变量四”。

带判断功能的模块

a) b) c)

“方式”单选按钮:功能同上。

“扩展卡模拟输入变量一”按钮:功能同上。

条件比较关系:设置左边的模拟输入变量与右边的参数如何进行比较。

机型 AS_UII AS_M 否 AS_MII 是 AS_INFOM AS_INFOX AS-EI 否 否 否 是否适用 是 ――数字输入――

图标 模块 对话框 令狐采学创作

令狐采学创作

1)

功能:“数字输入”模块用于检测扩展卡8路输入信号。其中通道1~通道8分别对应于AS多功能扩展卡(AS--Lasy扩展卡)上的IN1~IN8口。数字输入信号可以来自于开关、磁敏电阻、光敏电阻等。

2)

操作:将“数字输入”模块移到流程图生成区,并连接在程序中的相应位置。设置时,右击“数字输入”模块,在弹出的对话框中设置相应参数。

3)

设置参数说明:

令狐采学创作

令狐采学创作

单功能模块

“扩展卡数字输入一”按钮:表明存储扩展卡数字输

入检测值的变量。若要更换存储变量,鼠标左键单击该按钮,可选择其它两个变量,“扩展卡数字输入二”或“扩展卡数字输入三”。

带判断功能模块

a) b) c)

“扩展卡数字输入一”按钮:功能同上。 第二项是条件比较关系。

第三项是扩展卡可能的输入值,扩展卡可能参数的设置包括两项,即通道选择和通道状态,首先选择要比较的通道,然后选择通道状态。没有选中的通道不管状态如何不影响比较结果。

机型 AS_UII AS_M 否 AS_MII 是 AS_INFOM AS_INFOX AS-EI 否 否 否 是否适用 是 ――数字输出――

图标 模块 对话框 1)

功能:“数字输出”模块利用AS多功能扩展卡(AS--令狐采学创作

令狐采学创作

Lasy扩展卡)的数字输出端口对外部设备进行控制。其中通道1~通道4分别对应于扩展卡上的OUT1~OUT4口。

2)

操作:将“数字输出”模块移到流程图生成区,并连接在程序中的相应位置。设置时,右击“数字输出”模块,在弹出的对话框中设置相应参数。

3)

设置参数说明:

a)

通道:多功能扩展卡提供4路输出通道,即OUT1、OUT2、OUT3、OUT4,用户根据需要可设置单路输出也可设置多路输出。

b)

状态:选择接通时输出通道输出高电平,选择断开时输出通道输出低电平。

注意:多功能扩展卡数字输出模块由于采用直接检查和修改存储器内容的基本函数,具体使用方法参考多功能扩展卡使用说明,“数字输出模块”为避免影响同一内存地址对应的其它输出端口,采用了屏避位方法。举例如下: 例:将数字输出模块设置为“端口一通” 软件生成代码为:

int mcd_1 = 0; void main() {

令狐采学创作

令狐采学创作

mcd_1 = (mcm_1 & 0b1110) | 0b1; /*将数字输出控制

变量中端口一对应位设置为1,保持其它位不变*/

poke(0x5000,mcd_1); /*0x5000为扩展卡数字

输出对应的地址*/

}

上述代码中mcd_1为全局的数字输出控制变量,bit0为端口一的控制位,bit1为端口二的控制位,bit2为端口三的控制位,bit3为端口四的控制位,代码中0b1110为数字输出端口一的屏避位。

机型 AS_UII AS_M 否 AS_MII 是 AS_INFOM AS_INFOX AS-EI 否 否 否 是否适用 是 ――写扩展卡――

图标 模块 对话框 令狐采学创作

令狐采学创作

1)

功能:“写扩展卡”模块可向扩展卡数据总线ASBUS写数据(此时从机器人主板输出数据),适用于按ASBUS总线标准开发的各类扩展卡。ASBUS总线在机器人主板上可看到。

2)

操作:将“写扩展卡”模块移入流程图生成区,连接在程序中,在模块上右击鼠标,在弹出的对话框中设置参数。

3)

设置参数说明:

a) 扩展卡地址:选择扩展卡地址。

b) 数据:向扩展卡数据总线上写数据。数据为0-255之

间的整数,也可以选择“引用变量”。

机型 AS_UII AS_M 否 AS_MII 是 AS_INFOM AS_INFOX AS-EI 否 否 否 是否适用 是 ――读扩展卡――

图标 模块 对话框 令狐采学创作

令狐采学创作

1)

功能:“读扩展卡”模块可读取扩展卡数据总线ASBUS上的数据(此时向机器人主板输入数据),适用于按ASBUS总线标准开发的各类扩展卡,ASBUS总线在机器人主板上可看到。

2)

操作:将“写扩展卡”模块移入流程图生成区,连接在程序中,在模块上右击鼠标,在弹出的对话框中设置参数。

3)

设置参数说明: 单功能模块

a) “扩展卡地址”:选择扩展卡地址。

令狐采学创作

令狐采学创作

b)

“通用扩展卡输入一”:存储通用扩展卡输入数据

的变量。若要更换存储变量,鼠标左键单击该按钮,在弹出的变量百宝箱中可选择其它两个变量,“通用扩展卡输入二”或“通用扩展卡输入三”。

带判断功能模块

“扩展卡地址”:功能同上。

“通用扩展卡输入一”:功能同上。

条件判断表达式。扩展卡检测到的输入数据与右边的参数进行比较。

例:“通用扩展卡变量一 < 200”代表扩展卡输入值小于

a) b) c)

200的时候,条件判断成功,执行“是”下面的模块;否则条件判断失败,执行“否”下面的模块。

机型 AS_UII AS_M 否 AS_MII 是 AS_INFOM AS_INFOX AS-EI 否 否 否 是否适用 是 多功能控制卡中还包括有计数器清零、计数设置、计数启动、技、计数停止以及读取计数模块,这些模块的使用方法与章节“输入输出模块库”中的相应计数器模块使用方法一致,请参阅相关章节。

机型 AS_UII AS_M 否 AS_MII 是 AS_INFOM AS_INFOX AS-EI 否 否 否 是否适用 是 令狐采学创作

令狐采学创作

输入输出模块库

输入输出模块库为AS-EI型号机器人(EI控制器)独有。 ――模拟输入――

图标 模块 对话框 1)

功能:“模拟输入”模块用于检测EI控制器模拟通道输入。

2)

操作:将“模拟输入”模块移到流程图生成区,并连接在程序中。右击“模拟输入”模块,在弹出的对话框中设置参数。

3)

设置参数说明:

令狐采学创作

令狐采学创作

单功能模块

①“方式”单选按钮

选择要检测的模拟输入通道,注意扩展模拟通道在EI控制器内部,需由用户自行将控制线引出。

②“模拟输入变量一”:存储模拟输入检测值的变量。若要更换存储变量,可点击它,在弹出的变量百宝箱中可选择其它四个变量,如“模拟输入变量四”。

带判断功能的模块

①“方式”单选按钮:功能同上

②“模拟输入变量一”按钮:功能同上

① 条件判断表达式:左边的模拟输入变量与右边的参数

进行比较。

机型 AS_UII AS_M 否 AS_MII 否 AS_INFOM AS_INFOX AS-EI 否 否 是 是否适用 否 ――数字输入――

图标 模块 对话框 令狐采学创作

令狐采学创作

4)

功能::“数字输入”模块用于检测EI控制器8路数字输入信号。

5)

操作:将“数字输入”模块移到流程图生成区,并连接在程序中。右击“数字输入”模块,在弹出的对话框中设置参数。

6)

设置参数说明: 单功能模块

“数字输入一”:存储EI控制器数字输入检测值的变

量。若要更换存储变量,鼠标左键单击该按钮,在弹出的变量百宝箱中可选择其它两个变量,“数字输入二”和

令狐采学创作

令狐采学创作

“数字输入三”。

带判断功能模块

a) b) c)

“扩展卡数字输入一”按钮:功能同上。 第二项是条件比较关系。

第三项是条件判断标达式右边参数的设置,包括两项,即通道选择和通道状态,首先选择要比较的通道,然后选择通道状态。没有选中的通道不管状态如何不影响比较结果。

注意:EI控制器扩展数字输入只能通过自定义模块在VJC可视化编程环境中使用。

机型 AS_UII AS_M 否 AS_MII 否 AS_INFOM AS_INFOX AS-EI 否 否 是 是否适用 否 ――数字输出――

图标 模块 对话框 1)

功能:“数字输出”模块利用通过EI控制器的数字输出端口对外部设备进行控制。

2)

操作:将“数字输出”模块移到流程图生成区,并连接

令狐采学创作

令狐采学创作

在程序中,右击“数字输出”模块,在弹出的对话框中设置参数。

3)

设置参数说明:

c)

通道:EI控制器提供4路输出通道,即OUT1、OUT2、OUT3、OUT4,用户可设置单路输出也可设置多路输出。

d)

状态:选择接通时输出通道输出高电平,选择断开时输出通道输出低电平。

机型 AS_UII AS_M 否 AS_MII 否 AS_INFOM AS_INFOX AS-EI 否 否 是 是否适用 否 ――系统时间――

EI控制器输入输出模块库中的“系统时间”模块与其它系列机器人功能相同,这里不再介绍。

机型 AS_UII AS_M 否 AS_MII 否 AS_INFOM AS_INFOX AS-EI 否 否 是 是否适用 否 ➢

伺服电机驱动卡

伺服电机驱动卡模块库包括:初始化、伺服驱动已及直流驱动等模块。

能力风暴机器人使用这三个模块利用伺服电机扩展卡能控制七路伺服电机和二路直流电机。

――初始化――

令狐采学创作

令狐采学创作

图标 模块 对话框 (1) 功能:“初始化”模块初始化所有伺服电机和直流电机的初始状态,所有电机处于禁用或停止状态,伺服电机处于禁用状态时处于自由状态。

(2) 操作:将“初始化”模块移到流程图生成区,并连接在程序中。右击“初始化”模块,在弹出的对话框中选择伺服电机卡地址通道。

(3) 设置参数说明:伺服电机卡地址通道。

图标 ――伺服电机――

模块 对话框 令狐采学创作

令狐采学创作

(1) 功能:“伺服驱动”模块主要用于控制伺服电机转动方向与角度。

(2) 操作:将“伺服驱动”模块移到流程图生成区,并连接在程序中。右击“伺服驱动”模块,在弹出的对话框中选择伺服电机卡地址通道、要控制电机序号、伺服电机转动方向与角度。 (3) 设置参数说明:

a)

地址通道:伺服电机扩展卡地址通道,通道1(OS0)~通道3(OS3)分别对应地址0x4000~0x7000。

b) c) d) e)

伺服电机:选择要控制的伺服电机。 方向:选择伺服电机旋转方向。 角度:设置伺服电机要旋转的角度。

引用变量:伺服电机选择角度可通过引用变量来设置。

令狐采学创作

令狐采学创作

图标 ――直流电机――

模块 对话框 (1)

功能:“直流电机”模块主要用于控制直流电机转动方向

与速度。

(2) 操作:将“直流电机”模块移到流程图生成区,并连接在程序中。右击“直流电机”模块,在弹出的对话框中选择伺服电机卡地址通道、要控制电机序号、直流电机转动方向与速度。

(3) 设置参数说明:

a)

地址通道:伺服电机扩展卡地址通道,通道1(OS0)~通

道3(OS3)分别对应地址0x4000~0x7000。

b) c) d)

直流电机:选择要控制的直流电机。

状态:选择直流电机旋转方向或停止直流电机。

速度:设置直流电机要运转速度,速度可设置为0-90,设

置速度间隔为10。

e)

引用变量:直流电机选择速度可通过引用变量来设置。

令狐采学创作

令狐采学创作

注意:“直流电机”模块可用于控制广茂达大功率电机驱动模块AS-PDriver。

计数器模块库

――计数清理――

图标 模块 对话框 1)

功能:“计数清零”模块用于将EI控制器计数器计数值清零。

2)

操作:将“计数清零”模块移到流程图生成区,并连接在程序中。右击“计数清零”模块,在弹出的对话框中选择要清零的的计数器。

机型 AS_UII AS_M 否 AS_MII 否 AS_INFOM AS_INFOX AS-EI 否 否 是 是否适用 否 ――设置计数――

图标 模块 对话框 令狐采学创作

令狐采学创作

1)

功能:“设置计数”模块用于设置EI控制器计数器信号类型。

2)

操作:将“设置计数”模块移到流程图生成区,并连接在程序中。右击“设置计数”模块,在弹出的对话框中选择要清零的的计数器。计数器信号类型有二种方式,即上升沿跳变信号计数、下降沿跳变信号计数。

机型 AS_UII AS_M 否 AS_MII 否 AS_INFOM AS_INFOX AS-EI 否 否 是 是否适用 否 ――计数启动――

图标 模块 对话框 令狐采学创作

令狐采学创作

1) 2)

功能:“计数启动”模块用于启动EI控制器计数器。 操作:将“计数启动”模块移到流程图生成区,并连接在程序中。右击“计数启动”模块,在弹出的对话框中选择要启动的计数器。注意计数器启动前应先设置计数信号的类型,否则计数器不能正常启动。

机型 AS_UII AS_M 否 AS_MII 否 AS_INFOM AS_INFOX AS-EI 否 否 是 是否适用 否 ――计数停止――

图标 模块 对话框 1) 2)

功能:“计数停止”模块用于停止EI控制器计数器。 操作:将“计数停止”模块移到流程图生成区,并连接在程序中。右击“计数停止”模块,在弹出的对话框中选择要停止的计数器。

机型 AS_UII AS_M 否 AS_MII 否 AS_INFOM AS_INFOX AS-EI 否 否 是 是否适用 否 ――读取计数――

令狐采学创作

令狐采学创作

图标 模块 对话框 1)

功能:“读取计数”模块用于检测EI控制器计数器输入。

2)

操作:将“读取计数”模块移到流程图生成区,并连接在程序中。右击“读取计数”模块,在弹出的对话框中设置参数。

3)

设置参数说明: 单功能模块

①“方式”单选按钮

令狐采学创作

令狐采学创作

选择要检测的计数器。

②“计数器输入变量一”:存储计数器检测值的变量。若要更换存储变量,可点击它,在弹出的变量百宝箱中可选择其它四个变量,如“计数器输入变量二”。

带判断功能的模块

①“方式”单选按钮:功能同上

②“计数器输入变量一”按钮:功能同上

③条件判断表达式:左边的计数器输入变量与右边的参数进行比较。

机型 AS_UII AS_M 否 AS_MII 否 AS_INFOM AS_INFOX AS-EI 否 否 是 是否适用 否 ➢

通讯模块库

通讯模块库包括:开始通讯、停止通讯、发送数据以及接收数据等模块。

能力风暴机器人使用这四个模块可以在机器人与主机或机器人与机器人之间传送和接收数据。

――开始通讯――

模块 对话框 无设置对话框 图标 令狐采学创作

令狐采学创作

(1) 功能:开始能力风暴机器人与主机上“VJC1.6开发版”之间的通讯,此时不能下载新程序,当前程序开始使用串行通讯口进行通讯,通讯口设置为(9600,N,8,1)。此模块在发送数据和接收数据前调用,在整个程序中只须调用一次。

(2)操作:用鼠标将“开始通讯”模块移到流程图生成区,连接在流程图中。

――停止通讯――

图标 模块 对话框 无设置对话框 (1) 功能:恢复能力风暴机器人与主机上“VJC1.6开

发版”之间的通讯,此时“VJC1.6开发版”可以重新向机器人下载程序。

(2)操作:用鼠标将“停止通讯”模块移到流程图生成区。

图标 ――发送数据――

对话框 模块 令狐采学创作

令狐采学创作

(1) 功能:允许用户通过能力风暴机器人串行通讯口(即下载口)与外界通讯,通讯口设置为(9600,N,8,1)。

(2)操作:将“发送数据”模块移到流程图生成区,并连接在程序中,右击“发送数据”模块,在弹出的对话框中设置参数。

(3) 设置参数说明:

f) 发送数据:用户要发送的数据,发送数据范围

0~255,也

可以选择“引用变量”。

g) 发送次数:设置数据发送的次数,缺省为一次。发送次

数范围1-999。

h) 时间间隔:数据发送之间的时间间隔,缺省为

100毫

秒。

图标 ――接收数据――

模块 对话框 令狐采学创作

令狐采学创作

(1) 功能:“接收数据”模块用于从能力风暴机器人通讯口读取数据。

(2) 操作:将“接收数据”模块移到流程图生成区,并连接在程序中。右击“接收数据”模块,在弹出的对话框中设置参数。

(3) 设置参数说明:

单功能模块

令狐采学创作

令狐采学创作

“串行口变量一”:存储从通讯口接收的数据。若要更换存储变量,鼠标左键单击该按钮,在弹出的变量百宝箱中可选择其它四个变量,如“串行口变量四”。

➢ a) b)

带判断功能模块

“串行口变量一”:功能同上。

条件判断表达式。将从通讯口接收到的数据与右边的参数进行比较。

例:“串行口变量一 < 200”代表从通讯口接收到的数据

值小于200的时候,条件判断成功,执行“是”下面的模块;否则条件判断失败,执行“否”下面的模块。

――通讯实例--

例:通过能力风暴串行通讯口进行数据接收和发送。下面的

“接受数据”和“发送数据”程序可以分别下载到两个机器人中运行。运行时需用串口通信线将它们连接起来。 (1) 接收数据

将接收到的数据显示出来,如接收到的数据≥15时,数据接收程序就退出运行。“条件循环”模块的条件表达式为“串行口变量一 < 15”,“显示”模块的设置为“引用变量(串行口变量一)”。

令狐采学创作

令狐采学创作

(2) 发送数据

向串行通讯口发送“整型变量一”,“整型变量一”不停递增,当“整型变量一”大于20时,发送程序退出运行。发送次数为1。发送次数和时间间隔均缺省。

令狐采学创作

令狐采学创作

4.3.3多任务的编程方法

为什么要用多任务

多任务多任务的概念人们已经比较熟悉了,它是指用户可以在同一时间内运行多个应用程序,每个应用程序被称作一个任务。在给机器人编程时,可能会要求机器人同时做几件事,因此引入了多任务编程。

用流程图能很方便地支持多任务,实现多个任务同步运行。机器人最多可同时执行16个任务。在机器人需要完成复杂的工作时,用多任务编写程序能够让程序的条理更为清晰,

令狐采学创作

令狐采学创作

也便于程序调试。

多任务的编程方法

下面我们来试着完成一个多任务的例子:边唱歌边跳舞的机器人

操作如下:将“程序模块库”里“任务开始”模块移入到流程图生成区,这样就生成了两个任务(主程序和一个任务),分别在主程序和任务下编写让机器人跳舞和唱歌的程序,这样机器人就能一边跳舞一边唱歌了(如图5-7所示)。

图5-7 多任务

4.3.4子程序调用的编程方法

为什么要用子程序

在编程的过程中,经常会遇到某一段程序在主程序中使用多次的情况,这时,我们就可以把这一段程序编写成子程序。子程序技术是一种解决重复性问题的重要设计方法,采用子程序结构可以简化源程序书写、提高程序存储效率、减少出错率、增加程序的易读性和可维护性,并且有利用子程序资源的组织和使用。

在主程序界面中,子程序就是一个功能模块,调用起来很方便。根据新建子程序时选择的模板不同,子程序分为自定义子程序和系统子程序。两种子程序的调用方法都一样,有三个

令狐采学创作

令狐采学创作

步骤:新建子程序,编辑/修改子程序,调用子程序。

自定义子程序

建立自定义子程序的操作如下:

点击“程序模块库”中的“新建子程序”模块,在弹出的对话框中选择“自定义”,并为子程序命名,按“确定”后就会进入子程序的编辑窗口。

在子程序的编辑窗口中,可以和主程序一样编辑子程序。执行器模块、传感器模块和控制模块在子程序中都可以使用。但是子程序的程序模块库没有“任务开始”、“结束模块”和“新建子程序”模块,只有“子程序返回”模块,这是和主程序不同的地方。

子程序编辑完成后,用工具栏中的“主程序”快捷按钮切换到主程序窗口,在程序模块库中就会有刚才编写好的子程序模块。将子程序模块移入到流程图生成区,与主程序相连,就完成了自定义子程序的调用。

系统子程序

在“新建子程序”对话框中可以看到“系统子程序”模板。这些程序都是比较常用的。目前已有的系统子程序如下:

1) do re mi:乐谱“哆来咪”; 2) 歌曲

1:歌曲《在水一方》;

令狐采学创作

令狐采学创作

3) 歌曲

2:歌曲《粉刷匠》;

4) 三步舞:机器人跳三步舞; 5) 边唱边跳:边唱歌边跳三步舞; 6) 显示时间:显示系统时间;

7) 跟人走:机器人感测到前方有障碍物就跟上前去,失去

目标也会停下来;

8) 红外避障:机器人检测到前方有障碍物就避开; 9) 躲避碰撞:机器人受到碰撞后会躲开碰撞。

调用系统子程序的操作如下:

点击“程序模块库”中的“新建子程序”模块,在弹出的对话框中选择需要的系统子程序模板,这时可以给子程序改名,确定后,就进入了该子程序的编辑窗口,

子程序窗口中会出现该子程序的流程图,这时你可以根据需要修改流程图。

修改完毕切换到主程序窗口,在程序模块库中就会有刚才修改好的子程序模块,将这个模块移入到流程图生成区与主程序相连,就完成了系统子程序的调用。

4.2.5 变量

变量是机器脑中用于记忆的空间,就像我们存放物品的抽屉,存放的物品可以在以后需要的时候取出来用。在变量里存放的是“数”。与一般抽屉不同的是,“数”放进变量以后,就一直存放到程序结束,而且一个变量只能存放一个

令狐采学创作

令狐采学创作

“数”,如果下次在同一变量里放进新的“数”,原来老的“数”就没有了。在程序运行过程中,随时都可以使用变量,但并不把“数”从变量里取走,只是读取“数”的值,因此变量里的“数”可以反复用。

变量百宝箱

VJC1.6把所有变量都装在变量百宝箱里,它自动对变量进行管理、创建、赋值、引用、回收。有了变量百宝箱,我们就可以方便地使用变量。

变量百宝箱提供了75个变量,分为15类,用于存放传感器检测值和计算模块的计算结果。如图5-8所示。黄色变量代表该变量里已经存放了数值,白色变量代表该变量还是空的。变量百宝箱的每个变量就是一个抽屉,存放数值和读取数值都需要变量百宝箱分配的“钥匙”。

图5-8 变量百宝箱

变量赋值

变量赋值是往变量里存放数值。

可以为变量赋值的模块包括所有传感器模块和计算模块。 在这些模块的参数设置对话框左侧,可以看到变量按钮,点击变量按钮可以打开变量百宝箱。在变量百宝箱中,你可以选择变量的种类和变量名。例如,在变量百宝箱中要选择“红外变量二”,你可以先点击红外图标

,然后点击“红外变量

二”,变量百宝箱会分配给一把“钥匙”,表示“红外变量二”已可供使用了。

令狐采学创作

令狐采学创作

引用变量

“引用变量”是从变量里读取数值。

显示模块、计算模块、传感器模块、循环模块和条件判断模块都可以引用变量。

在这些模块的设置对话框中可以看到“引用变量”选项,这是可以使用变量的标志。点中“引用变量”这一选项,就会出现变量百宝箱,可以从中选择要使用的变量。

因为引用变量时只能读取数值,所以不能打开变量抽屉改变变量的数值。

变量百宝箱的应用

例1:在LCD液晶屏上显示光敏传感器的检测结果。流程图参见图5-9,参数设置的要点如下:

1) 2)

将“亮度检测”模块的参数设置为“亮度变量一”; 设置显示信息为“亮度变量一”。

右击显示模块,在参数设置对话框中点“引用变量”这一项,随之弹出一个变量百宝箱,在变量百宝箱里点击“亮度”图标,然后在“亮度变量引用”中选择“亮度变量一”,按确定,(见图5-9)

程序运行的结果就会把当前的光敏检测值在机器人LCD上显示出来。

图5-9 LCD显示变量

例2:计算程序运行的时间并显示出来。流程图见5-

令狐采学创作

令狐采学创作

10,参数设置的要点如下:

1)

用一个“系统时间”模块放在“主程序”模块的下面,把此时检测到的时间存放在“时间变量一”里,

2)

用条件循环模块和“碰撞检测”模块构成一组检测碰撞的程序指令,

3)

再用一个“系统时间”模块放在碰撞检测模块的下面、循环体的外面,但把此时检测到的时间存放在“时间变量二”里,

4)

使用一个计算模块,计算表达式设为“时间变量二”减去“时间变量一”,把计算结果放在“时间变量三”里(见图5-10),

5)

使用一个显示模块,显示“时间变量三”。

程序下载运行的结果,就会把从程序开始到发生碰撞的时间在LCD上显示出来。

图5-10 计算时间差

令狐采学创作

令狐采学创作

第四节 JC语言编程方法 4.4.1交互式C语言快速指南

快速入门

C程序都是由函数定义和数据对象定义组成。而函数定义包括数据对象定义、语句和表达式。

例:一个只定义了main()函数的简单JC程序。 函数名> ( [参数说<返回值类型> printf(\"Hello, robot!\\n\"); }

所有的函数都必须有一个返回值类型说明。main()函数不返回值,返回值类型为空void。其他的返回值类型还有整型(int)、浮点型(float)等。

紧接着函数说明的是函数名(在上面的例子中是main ),接着是圆括号里的函数参数(或入参),虽然main函数没有参数,但还是需要一对空圆括号。

函数参数说明之后是前花括号“{”,它标明实际函数代码开始位置。花括号对“{ }”用于标出函数定义范围。

明] ) { <函数定义> } 函数定义的格式: 令狐采学创作

令狐采学创作

接下来是函数体,包含一系列C语句,它们完成某些指定功能。例子中只有一句:printf(格式化输出)。它将在LCD显示屏上输出“Hello,robot!”。“\\n”表示行结束符。

printf语句以分号";"结束。所有的C语句都必须用分号“;”结束。初学者常犯的错误是漏掉语句后面的分号“;”。

后花括号"}"表示main函数结束。

让我们看另一个例子,来学习C更多的特性。下面的代码定义了一个sound函数,它让机器人叫n下,并返回检测到的音量值。

int sound(int n) {

int i;

for(i=0;ibeep();

return(micphone()); }

此函数被说明为整型(int),也就是它将返回一个整型值,这个值是由话筒检测函数microphone()检测到的。紧接着是函数名sound,sound后面括号中的是参数,此函数只有一个整型参数n。请注意说明一个参数类型与说明一个函数类型是类似

令狐采学创作

令狐采学创作

的,也有整型、浮点型等类型。

在一个函数中定义的参数变量,如sound函数中的n,只在这个函数中有效。别的函数也可以定义使用与之同名的参数变量,而不会相互干扰。

sound函数的函数体定义在大括号中,它定义了一个局部变量i,用于循环计数;接着是一条for循环语句,循环的内容是发声语句beep();每循环一次i增加1,直至i=n,循环结束;最后是返回语句return,这条语句表示退出函数并返回它后面的C表达式的值,本例中返回的是声音检测函数micphone()检测到的值。

让我们再来看一个main函数例子,它调用了sound函数。(可下载到机器人里运行)

voidmain() {

intb;

b = sound(10); printf(“%d\\n”,b); }

int sound(int n) {

令狐采学创作

令狐采学创作

int i;

for(i=0;ibeep();

return(micphone()); }

这段代码调用了前面定义的sound函数,让机器人叫10下,并将sound(10)的返回值在机器人液晶屏上显示出来。

下载调试

当你的程序完成时,要将程序下载到能力风暴里运行。按“下载”按钮

可以自动进行下载。当你的程序有错误时,将

不能下载。在交互信息窗口中就会出现错误信息。例如提示:“c\\JC1.jc(3) 错误: 未声明标识符i”表示在文件JC1.jc中第3行的变量i 没有声明。错误的类型有很多种,可以根据错误提示进行修改。用鼠标双击编译结果窗口中的编译错误,光标会自动跳转到出错的JC语句所在行。

JC语句交互运行方式

VJC1.6提供JC语句交互运行方式,可以不用编写完整程序,在机器人上直接运行一条或多条JC语句,观察执行结果。此功能可用于快速学习JC语言,同时这也是强大的调试手段,可以在机器人运行时调试程序。

令狐采学创作

令狐采学创作

在JC代码编辑界面中可以看到,交互信息窗口上方有一行编辑框,是JC语句的交互输入区。在JC语句输入区可以直接输入JC语句和调用库函数,语句数量不限。输入好后敲一下回车键,连接好串口通信线,打开机器人电源开关, VJC会把语句编译后下载到机器人上立即运行。运行结果会在交互信息窗口中显示,如果输入语句有语法错误,也会显示出来,参见下面的例子。

例1:输入beep(),并回车。

机器人马上执行这一语句,响一声,在交互信息窗口显示出运行结果。本例中显示: 表示beep()无返回值。

例2:输入photo(1),并回车。

photo(1)是检测左光敏的值,本例机器人返回数值 203,说明这一时刻左光敏传感器检测到的光强值是203。

例3:输入int p=0; p=photo(1); printf(\"%d\\n\并回车。 这个例子稍复杂点,执行3条JC语句,最后机器人在LCD上显示出检测到的光强值。

例4:程序运行时观察全局变量的值。

先在JC代码编辑窗口(参见图3-5)编写一段简单短程序:

令狐采学创作

令狐采学创作

int count=0; void main() {

while(1) {

count++;

printf(\"%d\\n\ wait(0.1); } }

下载该程序运行,之后在交互输入区输入全局变量名count,并回车。

结果显示此时全局变量count的值是1013。 这是把交互运行方式的用于程序调试。 注意:

如果机器人与计算机没有连接,也没有给机器人下载过程序,会显示下面的提示信息。这时你只要按照提示把机器人和电脑连上,下载一下当前程序(空程序也可),就可以交互运行JC语句了。

如果在交互运行JC语句过程中,机器人关机了或者拔掉了串口通信线,会显示“通讯中断”。

令狐采学创作

令狐采学创作

4.4.2 交互式C语言教程

数据对象

在C程序设计中变量和常量是基本的数据对象。在C程序的数据定义部分,需列出要使用的变量,并声明其类型,必要时还需设置初始值。

变量

变量名

变量名必须由字母或下划线开始,区分大小写 。C语言的关键字,如if,while等,不能用于变量名。此外,变量名和函数名不能相同。

例:A, B1, my_name, light1, _count 都是有效的变量名。 变量定义

在C语言中,可以在最顶层(在任何一对花括号之外,即函数外)或块(用花括号括起的C语句,如函数体内)的起始处定义变量。通常,变量以如下形式定义:

<类型> <变量名>;

例:int a; 定义了一个整型变量a。 或

<类型> <变量名>=<初始值>;

例:float P=1.5; 定义了一个浮点型变量P,并初始化为1.5。

在JC中,<类型>可为整型(int)、长整型(long)、浮点数型

令狐采学创作

令狐采学创作

(float)、字符型(char)或指针类型,它决定所定义变量的存储方式和运算方法。这是定义变量的一般形式。在定义指针和数组时,形式会有所改变,这将在后面说明。

局部和全局作用范围

如果一个变量在函数内定义或作为函数的参数,它的作用范围是局部的,即该变量只在函数定义范围内有效。

如果一个变量在函数外定义,则它是全局变量。该变量定义对所有函数有效,即在整个程序范围内都可以使用。

此外,若局部变量名与全局变量名或其它函数名相同,则在该局部变量作用范围内不能使用相应的全局变量或函数。

变量初始化

局部变量和全局变量可在定义时初始化。若不给出初始值,变量初始化为零。

所有的全局变量必须初始化为常量。局部变量可被初始化为任意表达式的值,包括任意的全局变量、函数调用、函数参数或已初始化的局部变量。

此处给出初始化的简单例子:

int i=50; /* 定义i为全局整型变量---初始值为50 */ long j=100L; /* 定义j为全整型变量---初始值为100 */ float PI=3.14159; /* 定义PI为全局浮点变量---初始值为3.14159*/

floatpermeter(float r)/*定义周长函数permeter*/ {

令狐采学创作

令狐采学创作

int x; /* 定义x为局部整型变量---初始值为0 */ float y=PI; /*定义y为局部整型变量---初始值为PI*/ y = 2.0 * PI * r; return y; }

任何时候只要运行函数,该函数中包含的局部变量将被初始化。

任何时候只要复位情况出现,全局变量将会初始化。复位情况包括:

代码下载;

主程序main()运行;

系统硬件复位(按能力风暴上的复位按钮或打开电源开关时)。

常量

什么是常量?

程序运行过程,其值不能被改变的量称为常量。常量区分为不同的类型:

a)

整型常量

整型常量可定义为十进制形式(如,255或-1)。可定义为使用\"0x\"前缀的十六进制形式(如,0x1fff),还可定义为一种非标准但常用的使用\"0b\"前缀的二进制形式(如,0b1001001),但不支持使用零前缀的八进制常量。

令狐采学创作

令狐采学创作

b)

长整型常量

通过在十进制整数后加上后缀\" L \"或\" l \"(字母L的大小写)可创建长整型常量。例如,0L是长整型的零。虽然\"L\"的大小写均可使用,但大写形式更具有可读性。

c)

浮点数型常量

浮点数可使用科学计数法 (例, \" 10e3\" 或\"10E3\") 或用小数点分段。例如,浮点数零可以\"0.\",\"0.0\"或\"0E1\"的形式给出,而不能仅仅用\"0\"。由于能力风暴智能机器人无浮点运算硬件,浮点运算将比整型运算慢,要节省地使用浮点运算。

d)

字符型与字符串型常量

单引号括起的字符型常量的值是其ASCII码值 (例: 'x',它的值是120)。

字符串型常量用成对的双引号定义,如,\"This is a robot.\"。

e)

NULL

NULL是一个特殊常量,NULL具有零值,可对指针或数组变量赋值,或进行比较(将在后面说明)。通常,其它常量是不能转成指针类型,所以很多情况下要用到NULL。

例如,为检查指针是否已初始化,需要将其与NULL进行比较,避免试图对空指针读写。又如,在一个链表结构中,每个元素包含一个数值和指向下一个元素的指针,为了找到链表

令狐采学创作

令狐采学创作

的结尾,就需将指向下一个元素的指针与NULL进行比较。

数据类型

JC支持以下的数据类型: 16位整型

16位整型由int类型标识符表示。其取值范围从-32,768到+32,767(十进制数)。

32位整型

32位整型由long类型标识符表示。其取值范围从-2,147,483,8到+2,147,483,7(十进制数)。

32位浮点型

32位浮点型由float类型标识符表示。约有七位有效数字,其范围从10^-38到10^38。

8位字符型

8位字符型是由char类型标识符表示,字符的取值一般是标准ASCII字符集中的可打印字符,但不是绝对的。字符型变量可表示任意的8位整数。

指针

JC中的指针是表示内存地址的十六位整数。处理内存中变量值的方式有计算、传递以及通过指针引用其在内存中的地址。

数组

数组用于储存同类型的数据序列(即所有的数组元素有相同的数据类型)。定义数组时需指定其长度(即数组元素的个

令狐采学创作

令狐采学创作

数)。数组中的元素可像其它变量一样进行设置和存取。

(1)

指针

指针用以指明变量在内存中的地址。指针对于处理对象非常有用,但要非常小心。代码中的指针必须指向内存中的有效对象。试图引用无效的内存地址会导致系统崩溃。大部份熟知的操作系统在试图存取非法访问的内存时,会给出像“保护错误”或“地址冲突”这样的警告信息。然而,目前能力风暴ASOS系统中没有这样的安全机制。对无效指针的引用是无法检测到的,而且很可能导致对数据、程序、甚至ASOS的破坏。

a)

指针安全

JC支持从函数返回指针或使用指针数组。这样增加了误用指针的概率。但是只要遵循一些简单的原则,便可有效地避免此问题。

首先,在使用指针前,判断其是否等于NULL(一种特殊的零指针)总是必要的。定义指针变量时必须将其初始化为NULL,许多未赋值的指针可以用此法判别。

其次,不要在函数体外引用指向该函数内局部变量的指针。函数运行结束时,其局部变量内存全部释放。因此,对这些指针的引用不仅会返回不正确的值,而且会导致严重的数据破坏。一个好的解决办法是绝不从函数中返回局部变量的地址,而且决不用生存期大于函数本身的对象(全局指针,数组)来存储局部变量的地址。全局变量和主函数中的变量一旦定

令狐采学创作

令狐采学创作

义,地址就已固定,其指针可视为安全的。

JC的类型检查有助于检错,但不能防止所有的指针错误,需要非常小心。

b)

指针定义和使用

对给定类型对象的指针定义,类似于一般对象的类型定义,只是在变量名前加上*。

存取指针指向的变量的值需在表达式前加上* 操作符以计算指针值。该操作称为“间接引用”。在变量、数组元素前加上& 操作符可得到变量的地址。 例:下面的语句定义X和Xptr:

long X;/*定义一个长整型变量X*/

long *pW;/*注:pW是指针。*pW是一个长整型变量,是pW所指的对象*/

使用给定类型变量与给定类型变量的指针有两个主要的区别:

①存储空间分配――定义某一类型的对象(如长整型的x)意味着分配存储变量所需的内存空间。由于JC中长整型数在内存中占四个字节,所以x占了四个字节。然而,像pW这样的指针不需要占用与所指对象一样的字节数。所以使用指针可以节省内存空间。

②初始值――即使未初始化,引用指针以外的变量通常是安全的。但在安全使用指针之前必须赋给合法的地址值,否则可能产生错误。

令狐采学创作

令狐采学创作

假设,前面定义X和*pW语句之后有如下两条语句: X=50L; *pW=50L;

第一条语句是有效的:它将x的值设为50L。第二条语句不正确,pW还没有正确初始化,该语句会破坏内存。

下面的指令序列说明如何使用指针、* 操作符以及& 操作符,并且可以看到一旦对指针赋以内存地址,其“间接引用”等同于所指对象。

Int X=50L;/* 声明整型数X,并对X的赋值为50 */ int *Xptr; /* 定义整型指针Xptr */ Xptr=&X;/* 将X的地址赋给Xptr */

printf(“*Xptr = %d\\n”,*Xptr);/* 可以看到*Xptr等同于X,*Xptr的值为50 */ X=100L;/* X值设为100 */

printf(“%d\\n”,*Xptr);/* 可以看到*Xptr的值也跟着变为100 */

*Xptr=200L;/* 将*Xptr值设为200 */

printf(“X=%d\\n”,X);/* 将Xptr所指对象的值设为200,即此时X=200L */

c)

指针作为参数传递

指针可传给函数,且函数可改变指针所指向的对象值。术语称之为“引用传递”。

令狐采学创作

令狐采学创作

对变量的引用或变量的指针可传给被调用的函数。与之相反的是值传递,变量的值传给所调用的函数。值传递是函数调用的标准方法。

下例定义了一个检测光线亮度的函数getlight,参数为一整型指针 maxlight。该函数比较检测到的亮度值和传递进来的历史上最亮的亮度值,并把最亮的值存在指针所指的变量*maxlight中。多次调用该函数后,变量*maxlight里保存的就是多次检测结果中最亮的值。

intgetlight(int *maxlight) {

int light= 0; /*定义一个整型变量light*/

light = photo(1); /*将左光敏检测值存在light*/

if(light < *maxlight) * maxlight = light; /* 光敏检测值小代表亮*/

return light; /*函数getlight返回左光敏检测值*/ }

d)

从函数返回指针

可以从函数返回指针。像定义其他类型指针一样,在函数名前加上星号*可定义函数返回值是指针类型,不妨称之为指针函数。

例:累计左右碰撞的次数可以用下面的方法实现。(该代码只是用于示范指针函数的用法)

令狐采学创作

令狐采学创作

int left, right, other;

int *dirptr(int dir) /* 注:dirptr 是函数,返回值是指针 */ {

if(dir==1)

{ return(&left); } /* 将left 的地址返回给函数dirptr (1) */

if(dir==2)

{ return(&right);} /* 将right 的地址返回给函

数dirptr (2 )*/

return(&other);

}

当函数dirptr()的参数dir为1时,返回指向全局变量left的指针(即left 的地址);参数dir为2时,返回指向全局变量right的指针;参数dir为其余值时返回全局变量other的指针。

使用碰撞计数时可以这样调用:“*dirptr(bump())++;”,于是bump()检测值为1时,left增加1;bump()检测值为2时,right增加1。碰撞检测函数 bump()的含义可以参看库函数说明。

(2)数组

JC支持字符数组、整型数组、长整型数组、浮点型数组、结构数组、指针数组、和数组指针。虽然在许多方面不同于标准C的数组,但仍可类似地使用。使用数组的的主要好处在于可为同类型的多个实例分配空间,向函数传入任意数目的参

令狐采学创作

令狐采学创作

数,以及在一组数上进行迭代运算。

JC的数组不同于其他版本C的数组的地方在于:引用JC数组时会检查并确保对数组的引用未越界。为进行检查,数组的长度存储在数组的内容中。需要牢记的是,在JC中给定类型的数组与给定类型的指针是不兼容的类型,而在标准C中多半是可以互换的。

a)

数组的定义和初始化

数组使用方括号进行定义。如下语句定义了一个有十个整型变量的数组:

int light[10];

在该数组中,元素计数从0到9。通过在方括号中加入索引号存取数组元素。light[4]表示数组light中的第五个元素(以零为基数)。

数组初始化如未定义,则全为零。数组亦可在定义时初始化,方法为在花括号内用逗号隔开各数组元素初始值。若在定义时给出初始化信息而未在方括号内指定数组大小,则数组长度由给出的数组元素的个数而定。例如,

int light[]= {0, 40, 50, 68, 117, 201};

创建一个有六个整数的数组,light [0] 为 0,light [1] 为 40,等等。

如果定义了数组长度,并且初始数据也给定,则初始数据的长度不应超过定义的数组长度,否则将产生错误。另外如果定义了数组长度,而初始元素的个数小于这个长度,则余下的

令狐采学创作

令狐采学创作

元素初始化为0。

字符型数组为文本串。对字符型数组初始化有特殊的语法。数组的字符值括在双引号内:

char string[]= \"Hello robot\";

这种形式创建一个叫作string的字符型的数组,其中字符为ASCII码值。另外,字符型数组以0结尾。这种结尾形式的字符数组可以作为供显示输出的字符串。字符数组也可以用花括号形式来初始化,但这种情况不会自动地以null结尾。一般在输出不以null结尾的字符数组时将导致错误。

b)

数组作为参数传递

当一个数组以变量的形式传递给一个函数时,实际上是传递了数组指针,而不是传递了数组本身。如果函数修改了作为参数的数组,则原数组亦被修改,这是因为在内存中只有数组的一个实例。

在标准C中,有两种途径来声明一个数组型参数:数组或数组元素类型的指针。在JC中数组指针与一个数组元素的指针是不兼容的,因此参数只能声明为数组。

作为例子,下面函数参数为一个下标和一个数组,返回由下标定义的数组元素。

int get(int index, int array[]) return array[index]; }

此处用方括号声明参数array为一个整数数组的指针。

令狐采学创作

令狐采学创作

当传递一个数组变量给一个函数时,实际上是传递了数组指针的值而不是其中的一个元素,所以不用方括号。参见下面完整的例子:

int light[10]= {0, 40, 50, 68, 117, 201}; int height[]={11,12,13,14,15}; void main() {

int a,b;

a=get(3, light); b=get(2,height);

printf(\"a=%d b=%d\\n\ }

int get(int index, int array[]) {

return array[index]; }

语句与表达式

语句是组成C程序基本成分之一,包括表达式、赋值、函数调用或控制语句。

运算符施加于特定类型对象之上,指明了将如何对它进行处理。

表达式组合变量及常量产生新值。

令狐采学创作

令狐采学创作

运算符

每种数据类型都有自己的运算符集以决定可以对其采用的运算。

a)

整型运算

整型数支持以下运算:

(1) 算术运算加法+,减法-,乘法*,除法/

(2) 比较运算大于>,小于<,等于==,大于等于>=,小于

等于<=,不等于!=

(3) 位运算按位或 |,按位与 &,按位异或 ^,按位取反 ~ (4) 布尔运算逻辑或 | |,逻辑与&&,逻辑非 !

C语句在使用布尔值时,总是把整数零作为假(false),任何非零值作为真(true)。布尔运算符返回零作为假,而返回1作为真。

布尔运算符 && 和 | |一旦得到最终表达式的结果,就会终止整个表达式的计算。例如,在表达式 a&&b 中,若a是假,则结果必为假而无需计算b。因而该 && 运算符不会对b求值。

b)

长整型

整型运算所支持的运算符集中部分可用于长整型:算术加+,算术减-,算术乘*,及整型比较运算符。长整型不支持位运算,布尔运算及算术除法。

c)

浮点数

JC使用Motorola开发的公开浮点函数包。包中包括算术运

令狐采学创作

令狐采学创作

算,三角运算及对数运算。由于浮点运算由软件实现,它们比整型运算慢了许多。若从性能考虑,建议少用浮点运算。

浮点运算支持如下类型:

(1) 算术运算加法+,减法-,乘法*,除法/

(2) 比较运算大于>,小于<,等于==,大于等于>=,小于

等于<=,不等于!=

(3) 数学函数 JC支持的三角运算,对数运算和指数运算。详

情见浮点运算函数部分。

d)

字符

JC中的字符只用在字符数组里。当字符数组的一个元素被引用时,整型运算符自动强制把该字符元素转成整型进行处理。在字符数组中存入一个值时,该值将被强制从16位整数转成8位字符型(截去高8位)。

赋值运算与表达式

最基本的赋值运算符是=。下面的语句将a的值加2。 a = a + 2;

简写形式 a += 2; 可执行同样的操作。 同样的用法的运算符有:

+ - * / % << >> & ^ |

自增运算符与自减运算符

自增算符\"++\"对变量进行增量操作。例如,语句\"a++\"等于\"a=a+1\"或\"a+=1\"。使用自增运算符的语句是有值的。

例如:

令狐采学创作

令狐采学创作

a=3;

printf(\"a=%d ++a=%d\\n\

语句会显示\"a=3 ++a=4.\"。由此可知,++a是先执行\"a=a+1\"的操作,再将它的值打印出来。

若自增运算符放在变量名后,则先计算表达式的值,再进行自增操作。则

例如: a= 3;

printf(\"a=%d a++=%d\\n\

语句会显示 \"a=3 a++=3\" 但此语句执行后a的值已是4。自减运算符\"--\"的使用类似于自增运算符。

数据存取运算符

& :单个的 & 符号用于对变量和数组的引用,返回其在内存中的地址。该运算符不能用于在内存中没有固定地址的表达式。

*:表达式中的单个 * 符号用于返回指针所指变量的值。这种操作称为“间接引用”。 例:

int a, *aptr; aptr = &a; 量aptr */

令狐采学创作

/*变量a的地址赋值给指针变

令狐采学创作

*aptr =10; 量*/

/*把10赋值给指针aptr所指变

printf(\"addr=0x%x a=%d\\n\ 显示结果:addr=0x0102 a=10 [表达式]

在数组类型(数组变量或函数返回的数组指针)之后出现,检查方括号括起的表达式的值是否在数组边界内,并且返回对该数组元素的引用。

运算优先级和次序

下面简要地给出C运算符的优先级与结合原则。越排

在前面的运算符其优先级越高。同行的运算符优先级相同,运算次序由结合方向决定。

运算符 () [] ! ~ ++ -- - ( 类型 ) * / % + - << >> < <= > >= == != & ^ | && || = += -= *= /= %= >>= <<= &= ^= |= , 结合方向 自左向右 自右向左 自左向右 自左向右 自左向右 自左向右 自左向右 自左向右 自左向右 自左向右 自左向右 自右向左 自右向左 自左向右 例如:a = b + a * 3 / 4 – c;

运算次序是:先计算 a * 3 / 4,再计算b + ,之后计算 – c,最后是把计算结果赋值给a。

令狐采学创作

令狐采学创作

控制语句

单个的C语句以分号结束。一组语句可用花括号组合

成复合语句块。语句块内可定义局部变量。

JC支持大部分标准C的控制语句。但不支持常见的的switch语句。

1) If-else

if else 语句用于选择。其语法为: if (表达式) {语句1;} else

{语句2;}

该语句执行时,先计算if后面的表达式,若表达式的值不等于零(如逻辑真),则执行语句1,若表达式的值等于零,则执行语句2。

2)

While

while循环语法如下: while (表达式) {语句;}

while 开始就先计算表达式的值。若为假(零),则跳过语句。若为真(非零),则执行语句。然后再次计算表达式的值,执行同样的检查。直到表达式值为零,终止循环。

在C中用while很容易创建永远循环:

令狐采学创作

令狐采学创作

while (1) { 语句;}

这是因为表达式的值为1,永真的缘故。

3)

For

for循环语法如下:

for (表达式1;表达式2;;表达式3) {语句}

它等同于如下的while循环: 表达式1; while (表达式2) { 语句; 表达式3; }

典型地,表达式1为赋值操作,表达式2为相关的表达式,表达式3为某种方式的自增或自减操作。例如,如下代码从0计数到99,并同时输出各数字:

int i;

for (i= 0; i < 100; i++) {

printf(\"%d\\n\ wait(0.1); }

4)

Break

令狐采学创作

令狐采学创作

在while或for循环中可用break提前终止循环或跳出死循环。

屏幕显示

JC中实现了C函数printf的兼容版本,它能把字符串格式输出到LCD液晶屏幕上。

printf函数语法如下:

printf(格式字符串, [参数1] , ... , [参数N] )

屏幕显示例子

例1:显示消息。下面语句在屏幕上输出文本串。 printf(\"Hello, world!\\n\");

在该例中,格式控制字符串只是简单地向屏幕输出。末尾的\\n字符表明是行结束。

例2: 显示数字。下面的语句显示整型变量n的值和简短的信息。

int n;

printf(\"Value is %d\\n\

格式符%d用于十进制整数格式化输出。

例3: 显示二进制数。下面的语句将整型变量n以二进制数的形式输出。

printf(\"Value is %b\\n\

格式符%b用于二进制整数格式化输出。只有该整数的低

令狐采学创作

令狐采学创作

8位被输出。

例4: 显示浮点数。下面的语句将浮点型变量x以浮点数形式输出。

float x;

printf(\"Value is %f\\n\

格式符%f用于格式化输出浮点数。注意如果用特殊格式%f输出一个整型变量将会出错。

例5: 以十六进制方式显示两数。 int a,b;

printf(\"A=%x B=%x\\n\

格式符%x用于十六进制方式格式化输出整型数。

格式化字符汇总

描述:十进制整数 描述:十六进制整数

描述:低位字节为二进制数 描述:低位字节为ASCII字符 描述:浮点数

描述:字符数组(字符串)

%d:输出类型:int %x:输出类型:int %b:输出类型:int %c:输出类型:int %f:输出类型:float %s:输出类型:char[ ]

注意事项

a)

LCD液晶屏幕上的最右下字符位置被作为系统的\"状态指示\"。当能力风暴操作系统运行正常时,该处的

令狐采学创作

令狐采学创作

太极字符持续闪烁。若停止闪烁,则说明能力风暴操作系统运行出错。这时需更新操作系统。

b) c) d) e)

若显示字符超出31个,则被截断,超出部分不显示。 显示字符长度大于16时,长出部分折到下一行显示。 目前不支持长整数(32位)输出。

如果显示格式化字符与显示类型不匹配,会有意外错误。

4.4.3能力风暴库函数

能量风暴库函数与机器人的硬件有关。由于能力风暴系列机器人在传感器和执行器配置上有差别,主板电路也不完全相同,造成所使用的操作系统和库函数有细微差异。在下面库函数介绍时会注明适用的机器人型号。如未加注释,表示该库函数适用于所有机器人型号。目前已生产的机器人型号有AS-InfoX、AS-InfoM、AS-M、AS-MII、AS-UII、AS-EI。

电机控制函数

下面电机控制函数不适用于能力风暴智能机器人AS-EI(EI控制器)。

void motor(int index, int vel)

以功率级别vel(-100~100)启动电机m; vel为电机功率;

index:电机序号,1为左电机,2为右电机,3为扩展电

令狐采学创作

令狐采学创作

机。

注:目前AS-M、AS-MII 和AS-UII主板上才有扩展电机口,并且不可调速和不可改变方向,功率设置不为0时,扩展电机口就单向输出电压。其它机器人只有在安装扩展卡后才可使用扩展电机。

void drive(int move, int turn) 同时设定两个电机的速度; move为平移速度; turn为旋转速度; void stop()

关闭左右两个电机,停止运动。 void stop_motor(int m) 关闭电机m。

0为所有电机,1为左电机,2为右电机,3为扩展电机。 注:目前AS-M、AS-MII 和AS-UII主板上才有扩展电机。

伺服电机驱动函数

void InitSV(int iCh)

伺服电机初始化函数,设置所有电机为禁用状态,iCh:伺服电机驱动卡地址。

void SetMotor(int iCh,int index,int status,int V)

启动直流电机,iCh:伺服电机驱动卡地址,index:电机掩码,0x00为电机1,0x10为电机2,0x11为电机3,status为电

令狐采学创作

令狐采学创作

机状态,0为停止,1为正转,2为反转,V为电机速度,取值0~90,速度间隔为10。

void SetServo(int iCh,int index,int status,int G)

启动直流电机,iCh:伺服电机驱动卡地址,index:电机序号,取值0~6,status为电机状态,0为禁用,1为正转,2为反转,G为伺服电机旋转角度。

传感器检测函数

注:所有传感器检测函数不适用于AS-EI能力风暴智能机

器人(EI控制器)。 int photo()

光敏传感器检测。

photo(1)为检测左光敏,photo(2)为检测右光敏,返回值为0~255的数字量。 int microphone()

声音传感器检测。返回值为0~255的数字量。 int ir_detector()

红外传感器检测。

返回值的意义:0=>没有障碍,1=>左边有障碍,2=>右边有障碍,4=>前方有障碍。 int bumper()

碰撞传感器检测。

返回值的意义:1左前,2右前,4左后,8右后,3前,12

令狐采学创作

令狐采学创作

后,5左,10右。 int rotation_clear(int index)

光电编码器计数清零。

1对应左,2对应右,0表示左右计数器同时清零。 int rotation(int index)

光电编码器脉冲累计读数。

rotation(1)为检测左光电编码器,rotation(2)为检测右光电编码器。

int digitalport(int channel)

读数字口上传感器的值。 channel的范围是0~7。

返回值:从传感器数字硬件读到的值为零伏或逻辑零时,返回1;否则返回0。 int analogport(int channel)

读模拟口上传感器的值。 channel的范围是0~7。

返回值是0到255间的整数值。 int encoder(int index)

读取光电编码器的当前状态。

0为低电平/1为高电平(分别对应码盘的黑条和白条)。 int surface()

读地面灰度检测函数,返回值0~255,地面越黑数值越大。 注:surface适用于AS-InfoX、AS-InfoM。 令狐采学创作

令狐采学创作

int battery()

检测电池电量,返回值为0~255的数字量。 注:battery适用于AS-InfoX、AS-InfoM。 ➢

时间函数

void wait(float sec)

延时sec 秒后再执行后面的语句。 sec是一个浮点数。 void resettime()

将系统时间复位清零。 float seconds()

以秒的形式返回系统时间。

返回值为浮点数,精度为0.001秒。 void msleep(long msec)

延时msec毫秒后再执行后面的语句。 msec是一个整数。 void sleep(float seconds)

延时seconds秒后再执行后面的语句。

seconds是一个浮点数。sleep函数功能等同wait函数。

音频函数

void beep()

产生一段0.3秒500赫兹的音频信号。发声结束后返回。

令狐采学创作

令狐采学创作

void tone(float frequency, float length)

产生一个length秒长、音调为frequency赫兹的音频信号。

通讯函数

void hold_serial()

停止能力风暴ASOS与主机通讯,允许用户下载的程序使用串口(9600-8-1-n)。

注:hold_serial适用于AS-UII。 void share_serial()

恢复能力风暴ASOS与主机通讯。 注:share_serial适用于AS-UII。 int serial_getchar()

从串口读取一个字符。

注:serial_getchar适用于AS-UII。 void serial_putchar(int idata)

向串口发送一个字符idata。 注:serial_putchar适用于AS-UII。 void repeat_putchar(int idata,int inum,int itime)

向串口多次发送一个0-255之间的整数idata。inum为发送次数,itime为发送时间间隔,单位为毫秒。 注:repeat_putchar适用于AS-UII。 令狐采学创作

令狐采学创作

内存读写函数

int read(int loc)

读取存储器地址loc一个字节的数据。 int readword(int loc)

读取存储器地址loc及loc+1二个字节的数据。 void write(int loc, int byte)

在存储器地址loc中存放一个字节的数据。 void writeword(int loc, int word)

在存储器地址loc和loc+1中存放二个字节的数据。 void bit_set(int loc, int mask)

用mask给地址loc中的字节置位,置位是由mask中的1决定的。

void bit_clear(int loc, int mask)

用mask给地址loc中的字节复位,复位也是由mask中的1决定的。

其他函数

void hog_processor()

指定任务连续执行1/4秒,再进行任务调度。 int start_process(function-call(...),[TICKS],[STACK-SIZE])

创建新进程。

star_process取得一个进程标识,function-call(...)是进程函

令狐采学创作

令狐采学创作

数。创建进程有两个可选参数:进程的时间片数TICKS和栈大小STACK-SIZE。如果只给定一个参数,它被认为是时间片数,栈的大小为缺省值。start_process返回一个整数,它就是新进程的进程标识ID。 int kill_process(int pid)

撤消进程。撤消一个进程,是通过将进程标识ID传给kill_process来实现的。

kill_process的返回值表明撤消进程是否成功。如果返回值是0,表明进程被撤消。如果返回值是1,表示没有找到该进程。 void asosreset()

软件复位函数。与按下能力风暴的复位开关的效果一样,ASOS操作系统重启动,程序停止运行。 int runbutton()

读运行键状态。运行键在能力风暴智能机器人的头顶上,可以在程序中使用该按钮。 返回值:0没按,1按下。 int abs(int val)

取整数val的绝对值。 int max(int x, int y)

求两个整数的最大值。 int min(int a, int b)

求两个整数的最小值。

令狐采学创作

令狐采学创作

float rand()

返回0~1之间的随机浮点数。 int random(int scale)

返回0~scale之间的随机整数。

不同机器人型号的库函数差异

下表将不同机器人型号的库函数差异进行了汇总,AS-EICON库函数相对,这里不进行比较。

传感器和相应库函数 扩展电机口 Motor(3, 100) 眼睛 eyecolor() 地面检测传感器 surface() 电池电量传感器 Battery() 碰撞检测传感器 bumper() 光电编码器 rotation() 软件复位 asosreset() 运行键 runbutton() 数据通讯 AS-UII AS-M AS-MII AS-InfoX 无电机3 AS-InfoM 无电机3 无 无 无 无 无 无 无 无 无 1左前、21左前、2右前、4左右前、4后、8右后 左后、8右后 轮子一圈轮子一圈返回脉冲返回脉冲数是33 数是33 系统重系统重启,程序启,程序停止运行 重新运行 无 1左前、2右前、4左后、8右后 轮子一圈返回脉冲数是33 系统重启,程序停止运行 1左、2右、4前 1左、2右、4前、8后 无 系统重启,程序停止运行 轮子一圈返回脉冲数是32 系统重启,程序停止运行 无 无 无 无 注:设置错误的机器人型号,或者下载了为其它型号的机

令狐采学创作

令狐采学创作

器人编写的程序可能会引起编译错误和程序运行不正确。 4.4.4 多任务

➢ 多任务综述

JC的一个强大的功能是支持多任务。在用户程序运行期间,进程可以动态地建立和撤消,一个进程就是一个运行的任务。

任何C函数都可以作为一个的进程使用。可以创建多个进程运行同一段代码(如调用同一个函数),在每个进程中此代码都有对应的局部变量。

进程通过全局变量进行通讯:在一个进程中给全局变量赋值,在另外一个进程中可以读这个全局变量的值。

多个进程运行是通过分配时间片实现的。每个进程一次只执行一定数量的时间片(以毫秒为单位)。这个值在每个进程创建时确定。缺省的片数为5,因此,在一个“轮次”中,一个进程将运行5毫秒,然后交给下一个进程运行。所有的进程依次放在一个进程表中,系统从头到尾每轮一遍进程表,每个进程都运行一次(运行时间对应于各自的时间片长度)。

每个进程都有自己的栈,用于函数调用传递参数,存放局部变量,存放函数调用的返回地址。栈的大小在进程创建时确定。一个进程栈的缺省大小为256字节。

使用递归调用或使用较大的局部数组的进程可能需要比缺

令狐采学创作

令狐采学创作

省值大的栈。一个进程需要的栈空间主要有这几部分:每次函数调用需要占用栈的两个字节(存返回地址)加上参数所用字节数;如果被调用的函数还创建局部变量,它们也要使用栈空间。另外C表达式产生的中间结果也存于栈中。

程序员要确定某一进程是否需要大于缺省值的栈。如果不需要使用缺省大小的栈,一个进程也可以创建比缺省值小的栈以节省栈存储空间。

当一个进程被创建时,它被赋予一个唯一的进程标识或pid。这个标识可用来撤消相应的进程。

创建新进程

int start_process(function-call(...),[TICKS],[STACK-SIZE]) 是创建进程函数,可以用来创建新进程。star_process取得一个进程标识,function-call(...)是进程函数。创建进程有两个可选参数:进程的时间片数TICKS和栈大小STACK-SIZE。如果只给定一个参数,它被认为是时间片数,栈的大小为缺省值。start_process返回一个整数,它就是新进程的进程标识ID。

新进程可以是任何有效的函数调用。下面给出了创建进程的一个例子:

void check_sensor(int n) /*定义进程函数,检测和显示模拟口n的值*/

{

while (1)

令狐采学创作

令狐采学创作

{

printf(\"Sensor %d is %d\\n\ wait(0.1); } }

void main() {

start_process(check_sensor(2)); /*创建进程*/ }

正常情况下一个C函数结束时,它会返回一个值或者无返回值。如果一个函数是作为进程来运行的,则在它结束时的返回值(如果有)是得不到。这是允许的,因为进程间的通讯是通过将结果存于全局部量中进行的,而不是通过返回值来返回的。在上面的例子中,check_sensor定义为一个无限循环函数,以保证其一直运行,除非机器人被复位或执行了撤消进程命令。

从以上的例子可以看到,进程的存在时间应当不小于主程序 void main()的存在时间,否则就会出错。

用start_process 函数加上可选参数,可以很方便地创建一个非缺省时间片数和非缺省栈大小的进程,例如:

start_process(check_sensor(2), 1, 50);

将创建一个check_sensor进程,它每次运行1毫秒,栈大小为50个字节(此处check_sensor使用较小的栈更有效)。

令狐采学创作

令狐采学创作

撤消进程

int kill_process(int pid);

用于撤消进程。撤消一个进程,是通过将进程标识ID传给kill_process来实现的。

kill_process的返回值表明撤消进程是否成功。如果返回值是0,表明进程被撤消。如果返回值是1,表示没有找到该进程。

下面的代码显示创建一个check_sensor进程,1秒钟后终止该进程的例子:

void main() {

int pid;

pid= start_process(check_sensor(2)); wait(1.0);

kill_process(pid); }

4.4.5 错误处理

使用JC会遇到两种类型的错误:编译错误和运行错误。 编译错误发生在编译源代码时。它们表明C语言源代码中的错误。典型的编译错误是语法错误和数据类型不匹配。

运行错误发生在能力风暴上的程序运行时。它们表明C程

令狐采学创作

令狐采学创作

序运行时有逻辑错误。一个简单的例子就是除零错(零为分母)。另一种情况是过程递归太深,就会发生堆栈溢出错误。

对这两种类型的错误有不同的处理方法,解释如下。

编译错误

发生编译错误时,JC交互信息窗口将出现相应的错误信息。在没有改正所有错误之前,程序不能下载到能力风暴机器人上。

运行错误

当发生运行错误时,将在LCD液晶屏幕上显示一条错误号。如果错误发生时,能力风暴与JC还保持连接,在JC交互信息窗口上将显示详细的错误信息。

以下是运行错误的代码列表:

运行错误代码 RUNTIME ERR 1 RUNTIME ERR 2 RUNTIME ERR 3 RUNTIME ERR 4 RUNTIME ERR 5 RUNTIME ERR 6 RUNTIME ERR 7 RUNTIME ERR 8 RUNTIME ERR 9 RUNTIME ERR 10 RUNTIME ERR 11 RUNTIME ERR 12 RUNTIME ERR 15 RUNTIME ERR 16 运行错误说明 没有足够的堆栈空间提供给启动进程函数start_process() 进程入口已用尽 数组下标出界 运行进程的堆栈溢出 使用无效的指针 浮点数下溢 浮点数上溢 浮点数被零除 数值转化成整数时太大或太小 负数开平方 求90度角的正切 求零或负数的对数 printf函数的浮点格式错误 整数被零除 令狐采学创作

因篇幅问题不能全部显示,请点此查看更多更全内容

Copyright © 2019- yrrf.cn 版权所有 赣ICP备2024042794号-2

违法及侵权请联系:TEL:199 1889 7713 E-MAIL:2724546146@qq.com

本站由北京市万商天勤律师事务所王兴未律师提供法律服务