第四章 创建一个新组件
CH4.zip(113KB)
在本章中,使用如模块和浮点的标准对象,从下而上创建一个AVS/Express组件。
在本章中,你:
启动AVS/Express
实例化和命名组件对象
把Depth连接到一个表达式上
使用对象编辑器把Time和Depth转换到数组中
把Echo作为一个模板保存
创建一个新的项目
在一个简单的应用程序中使用Echo
用新项目重新启动AVS/Express
4.1 介绍
在前两章中,你可以使用已有的AVS/Express组件创建和修改一个应用程序。
从本章开始,到这本指南的剩余内容,指导你从下而上建立一组新的组件,以创建一个完全功能的应用程序Echo Sounding。这个应用程序将包括一个用户接口,还包括阅读数据文件和处理数据的组件。在本指南的最后一章,你会装配和发送一个完整的应用程序。
Echo Sounding应用程序基于从一艘船上进行的回声探测,来计算海底的深度。如下图所描述的那样,声源从船的一边发出声音,声音沿着虚线指明的路径传播——从声源到海底再到接收器:
Time是从声源到接收器传播的时间间隔。DistanceSR是声源和接收器之间的距离。在水中的声速是4956 ft./s。
海底的深度由下面的公式确定:

在本章中,你创建了一个基于Time和DistanceSR计算Depth的组件Echo。你是在象浮点(定义一个浮点数字)和模块(封装数据参数和执行方法)这样的AVS/Express标准对象之外建立的Echo。
本章介绍几个新概念:
模块
添加模块工具
连接到表达式
数组
使用V命令处理器检查对象
输出端口
连接的双向特性
4.2 启动AVS/Express
启动AVS/Express。
可视化版用户类型:
|
UNIX
|
Windows
|
|
Vxp
|
bin\pc\vxp
或
点击应用程序图标
|
开发者版用户类型:
|
UNIX
|
Windows
|
|
Vxp
|
bin\pc\express
或
点击应用程序图标
|
当应用程序类型在初始应用程序对话框中时,选择Application:

Application装入缺省的应用程序,一个应用程序框架不包括DataViewer窗口,也不能实例化Uviewer或任何其它对象。你可以把它当作一个基本应用程序来开始建立你自己的应用程序。
4.3 实例化和命名组件对象

把Echo定义为一个模块。模块是一个封装数据参数并在数据参数上起作用的执行方法的对象。Echo有两个输入数据参数(DistanceSR和Time)和一个输出数据参数(Depth)。三个参数都是浮点对象。
Echo不需要方法。而只要你把Depth连接到一个执行必要操作的C语言表达式上。(在后面的章节中,当你创建一个组件从文件中阅读回声探测数据样本时,你要编写一个C方法。)
在本节中,实例化和命名组成Echo的对象。
创建ScratchPad应用程序
在Network编辑器菜单条中,从File菜单中选择New Application。
AVS/Express显示一个新的应用程序对话框,非常类似于初启动应用程序对话框。 在新应用程序对话框中,选择ScratchPad并点击OK。
AVS/Express将ScratchPad装入Network编辑器的应用程序工作区。
ScratchPad应用程序提供了一个特殊的应用程序接口,你可以使用它建立和编辑对象。与其它应用程序工作区不同,AVS/Express并不进到ScratchPad中去执行被实例化的对象。这让你用一个对象,而不是用AVS/Express,来尝试执行一个部分结构的组件。
通过将一个应用程序工作区装入一个白色背景,ScratchPad表示了这种不同。它不显示其它应用程序所使用的固定背景。
在Network编辑器中,从Libraries选项菜单中选择Standard Objects,进入标准对象库页。
这个库中包括你可以用来构造你自己的组件的基本对象。
使用Add Module工具构造模块
Add Module工具是一个对话序列,指导你通过创建模块的过程。对话有一序列你正常创建一个模块所要走的步骤,对话在每一步都提示你有关你想要创建模块的信息。
点击工作区上面的ScratchPad标题条,选择ScratchPad应用程序。
ScratchPad用蓝色加亮。
在Network编辑器菜单条中,从Object菜单中选择Add Module。
AVS/Express显示Add Module对话框的第一步:

更换模块的名字为Echo。
在Object name域中,选择NewModule,然后键入Echo。
当你敲了键盘的Enter键或离开Object Name域时,新名字就指定给了这个模块。
你也可以使用这个对话框把Methods添加到这个模块中,但是这个模块并不使用方法。
点击对话底部的Next按钮,进入下一步。
使用下一个对话把参数添加到模块中:

创建一个浮点输入参数。
从Type选项菜单中选择Float。
点击Add按钮。
一个参数子对象出现在Echo模块中,并且Add Module工具显示两个Add Parameter步骤中的第一个:
指定第一个输入参数。
使用Object Name域,重命名参数为DistanceSR。
通过按下Object is an exported parameter和Display input port的开关,设置参数特性。
当这个模块在Display Params模式显示时,设置Object is an exported parameter使这个参数可见。
设置Display Input port输出端口到模块接口。与这个参数连接的端口将在模块的顶端出现。
点击Next按钮,继续Add Parameter步骤的第二步。
Add Module工具显示下一步对话。这一步定义你刚刚添加的参数和模块方法之间的关系。因为你没有正在使用这个模块的任何方法,所以你完成了这个参数。
点击对话底部的Done按钮。
Add Module工具返回,允许增加更多的参数。
重复第5步和第6步添加另一个输入参数,但这次名字是Time。
重复第5步和第6步添加一个输出参数。在第6步:
命名参数Depth。
点击开关,用Display Output port代替Display Input port。
当你返回Add Module对话时,点击Next按钮:

Add Module工具显示Add Module序列的最后一个对话。
点击Done。
使用最后一个对话来管理模块的代码管理属性。因为你还没有用到任何外部代码,所以你不必在这个对话中添加什么。
Add Module工具退出。
返回Network编辑器中的ScratchPad工作区,你会看到参数已经被添加到Echo对象中:

注意:你可能必须关闭和重新打开模块,来查看所有的参数和它们的端口。
4.4 把Depth连接到一个表达式上

典型地,模块通过调用一种方法来执行处理过程,这种方法可以是C或C++程序。但在这种情况下,你可以通过简单地把Depth与C语言表达式连在一起来实现Echo的处理过程。
表达式中有输入参数DistanceSR和Time。正如你测试Echo时你将所看到的,这个表达式是动态的;一旦输入参数改变,AVS/Express就重新对表达式进行计算并相应地更新Depth的值。
注意:你可以使用下面描述的同样的技术,通过在前一节第6步所描述的Add Parameter对话的值域中键入表达式,来把Depth连接到这个表达式上。
连接Depth
打开Echo内的Depth参数。
双击Depth或选择Open弹出命令打开Depth。
你可能要键入一个长表达式,所以你首先应扩展Echo的窗口。

向右拖拉Echo窗口的右下角,扩展Echo。
这是你想要表示的表达式:

在Depth的入口域,键入后面跟表达式的连接操作符(=>),如下。

连接操作符是一个等号后面紧跟着一个大于符号。
仔细地键入表达式,不要少了括号或逗号。
按Enter(或Ctrl+Enter)应用表达式。
当你应用表达式时,AVS/Express额外添加了括号,这对表达式没有影响。
注意:应用表达式的另一种方法是关闭对象。
测试组件
打开DistanceSR和Time,然后扩大Echo的高度,这样你可以看到所有Echo的子对象。
注意DistanceSR、Time和Depth的标题条包括问题标记。Network编辑器试图在标题条中显示每一个对象的值。但是DistanceSR和Time还没有值。Depth也还没有值,因为它连接的是一个当前还没有解的表达式,这个表达式所涉及的对象还没有值。
当你给DistanceSR和Time指定值后,所有这些情况就将变化。
置DistanceSR值为60,置Time值为0.1。
为了设置一个值,在对象的入口域键入值,然后按Enter(或Ctrl+Enter)。在下图中,入口域中的等号在值之前。你不用键入这些值,当你按Enter时,AVS/Express就会插入这些值。
一旦你对两个输入参数设置了值,AVS/Express就能计算Depth的表达式。结果出现在Depth的标题条中。
置其它值给Time,例如0.2和0.3。
设置另一个值,覆盖当前的值,然后按Enter。每次你改变一个输入参数的值,AVS/Express都要重新计算表达式。
4.5 使用对象编辑器把Time和Depth转换成数组

一个典型的回声探测产生很多样本。你的Echo组件应能够输入一组Time值,产生一组相应的Depth值。
在本节中,你使用对象编辑器把Time和Depth转换到数组中,然后测试结果。
使用对象编辑器指定维
使用对象编辑器可以编辑已有对象的属性。编辑器出现一系列对话,类似于Add Module工具里的一系列对话,你可以使用这些对话指定对象的不同特性。
为Echo模块打开对象编辑器。
在ScratchPad工作区中选择Echo模块。
从Network编辑器菜单条的Object菜单中,选择Object Editor命令。
AVS/Express打开包括Echo模块的对象编辑器:

这一页是Echo模块的Declaration页。你可以使用Editor选项菜单显示模块的其它特定页:Module增加额外的参数或方法;Source
Code设置源代码管理属性。
你可以通过在Echo模块上选择模块的子对象来编辑它们。
双击Echo模块上的Time,选择它。
对象编辑器为一个参数打开Declaration页:

清除Time的当前值。
清除Value域的当前内容,然后按Enter。转换Time到一个没有说明大小的数组中。如果Time当前没有值,那么工作就更清楚了。
设置开关Object is an Array,转变Time为一个数组。在这种情况下,维是一对没有值的开括弧和闭括弧。
注意在对象编辑器和Network编辑器里的Time的标题条都显示了对象的维。你可能需要关闭然后再打开Time,以更新标题条。为了关闭一个打开的对象,或者在它的标题条上双击,或者选择对象Close弹出命令。为了再打开对象,或者在它上面双击,或者选择Open弹出命令。当你重新打开Time时,它显示的是一个多行入口域。
把Depth转变到一个没有说明大小的一维数组中。
在Echo模块中选择Depth,改变编辑器页的焦点。
点击Object is an array开关,转换Depth为一个数组。
不要清除Depth连接域的表达式。

注意数组括弧也显示在Depth的标题条上。 在对象编辑器中点击Close按钮通过关闭它。 通过给Time赋一个数组常量以测试它
在Network编辑器中,关闭然后重新打开Time。 注意,Network编辑器现在显示Time的入口域为一个多行域,使你能够进入多行数组常量。
在Time的值域中,输入数组常量{0.1,0.2,0.3}。
记住在表达式周围使用大括弧“{ }”,并用逗号“,”分离值。
按Ctrl+Enter使用该输入值。
对多行入口域,不能按Enter使用该输入值。Enter简单地将插入光标重定位到入口域下一行的开始处。
注意Time的标题条现在指明Time是一个三元素的数组。通过滚动Echo你看到Depth时,你会发现Depth也是一个三元素的数组
赋一个四项的数组常量给Time,例如{0.1,0.2,0.3,0.4}。
记住按Ctrl+Enter,Time和Depth现在是四元素的数组了。
注意连接和赋值的不同
一个对象的值域可以指明连接操作符(=>),或者赋值操作符(=)。 对Depth来说,用连接操作符(=>)。连接建立了一个与另一个对象或一个表达式的动态数据关系。无论什么时候对象或表达式改变,AVS/Express都会更新连接对象的值。
对于Time和DistanceSR来说,用赋值操作符(=)。(隐性使用,当你赋值时,AVS/Express插入赋值操作符。)赋值操作符只是一次性地赋某个值。你可以赋一个常量,就象赋给Time和DistanceSR一样,或者你也可以给一个对象或表达式赋值。在赋值后,对象有了新值,但不记录它怎样获得它的值(通过一个常量,对象或表达式)。
4.6 把Echo作为一个模板保存

保存Echo作为库中的一个模板对象。在准备时,为输入参数置缺省值。在这个例子中,置输入参数为空。
为输入参数设置缺省值
打开Echo。
打开DistanceSR,设置它的值为空,然后关闭DistanceSR。
为了设置值为空,清除入口域的当前内容,然后按Enter。
打开Time,设置它的值为空,然后关闭Time。
为了设置值为空,清除入口域的当前内容,然后按Ctrl+Enter。
关闭Echo。
在库中保存Echo
进入库工作区的库页。
你将使用Workspace 1保留你为Echo Sounding应用程序创建的所有组件。
把Echo从ScratchPad拖进入库Workspace 1中。
当Workspace 1变粉红色时,松开鼠标键。
Echo从ScratchPad中消失,出现在Workspace 1中。
实例化Echo到缺省应用程序中
在Network编辑器工作区中,双击ScratchPad关闭它。
Network编辑器工作区显示应用程序对象和它的子对象:DefaultApplication和ScratchPad:
双击DefaultApplication打开它。
将Echo模板从Workspace 1库中拖到DefaultApplication工作区,实例化Echo。
注意在这个例子中,AVS/Express对象和其它已有AVS/Express对象一样,为Echo模板作了拷贝。
赋一个常量给DistanceSR(例如60.0),赋一个数组常量给Time,例如{0.1,0.2,0.3,0.4},验证Echo是一个工作模块。
用V命令处理器打印Depth的值
AVS/Express为Network编辑器提供了一个叫作V的基于文本的可选方法。你在本指南中可能用的不多。但是通过V,你可以定义对象,连接对象,赋值给对象,提交特殊的命令给对象管理器去调试和检查你的应用程序。
V命令处理器(VCP)让你交互地进入V语句和命令。在UNIX系统中,VCP出现在你启动AVS/Express的窗口中。在Windows中,它出现在一个单独的命令外壳中。在本节,你用VCP打印Depth的当前值。
使VCP窗口变为一个活动的窗口。
应能看到的是这样:
OM(Root) ->
OM表示你正与对象管理器交互,(Root)表示你当前工作用Root,或对象层次中的最高层对象。在->提示符的右边你插入V代码。
因为你要打印Depth的值,因此首先要找到包含它的对象Echo。
键入下面用粗体显示的命令首先找到DefaultApplication。
键入这个命令,包括左大括弧,然后按Enter。
OM(Root) -> DefaultApplication {
OM warning: jumping from: Root to Root.Applications. DefaultApplication
OM(DefaultApplication) ->
对象管理器打印一个消息告诉你,你跳过了对象层次的两级,即从Root到Applications,和从Applications到DefaultApplication。
注意提示现在显示(DefaultApplication)提示符,意思是你正在DefaultApplication对象里。
键入下面用粗体的命令找到 Echo。
OM(DefaultApplication) -> Echo {
OM(Echo) ->
键入$get_array命令打印Depth的值。
OM(Echo) -> $get_array Depth
{245.977, 494.691,
742.794, 990.746}
用VCP,赋一个新的数组常量给Time,然后打印Depth的新值。
第一行(Time=…)必须用分号终止。
OM(Echo) -> Time = {0.4 , 0.5};
OM(Echo) -> $get_array Depth
{990.746 , 1238.64}
注意在Network编辑器中,Time的值域现在显示的是新的数组常量。你在VCP中的动作也会被反映在Network编辑器中。Network编辑器和VCP仅仅是与AVS/Express对象管理器通信的两种方式。
键入右大括弧和后面的分号,回到模块栈。
OM(Echo) -> };
OM(DefaultApplication) ->
回到Root。
OM(DefaultApplication) -> };
OM(Root) ->
4.7 创建一个新的项目

AVS/Express项目定义了你的开发和执行环境。每一次你在AVS/Express上工作时,你就是在一个项目上工作。
一个项目有三个主要部分:
- 库——模板对象库
- 用户代码——与那些对象有关的C和C++程序
- 进程——可执行的express,就象任何的外部过程和叫做基础的内部引导过程一样
AVS/Express提供了一个初始项目,装在安装目录下。当你首次启动AVS/Express时,它就是你工作的项目。
你可以创建你自己的项目。就象安装项目一样,项目对其自身进行定义,但是有确定的补充和修改。你必须创建一个新的项目保存新的应用程序组件。AVS/Express不许用户修改安装项目。
选择Project的Save As下拉命令。
出现一个文件选择对话。
保存项目,命名为myproj。
UNIX系统——在你的主目录下保存项目。
Windows——选择合适的目录。
AVS/Express创建一个项目目录叫做myproj,在这个目录下存储新的项目。
4.8 在一个简单的应用程序中使用Echo

在本节中,你使用Echo构造了一个简单的测试应用程序。作为测试的一部分,你可以尝试连接的双向性。
构造应用程序
构造下面的应用程序。
为了创建sr_in,time_in和depth_out,在标准对象库页上从Parameters库中实例化三个浮点对象。然后如下所示,用对象编辑器为它们重新命名,把time_in和depth_out转换为没有定义大小的数组。再如下所示,连接对象。
测试应用程序
打开sr_in,置值为60。
按Enter,应用这个赋值。
打开time_in,置数组常量为{0.4 , 0.5}。
按Ctrl+Enter,应用这个赋值。

注意depth_out已被转换成一个两个元素的数组。
使用VCP,打印depth_out的值。
OM(Root) -> DefaultApplication {
OM Warning: jumping from: Root to Root.Applications. DefaultApplication
OM(DefaultApplication) -> $get_array depth_out
{990.746,1238.64}
尝试双向连接
当一个对象被连接到一个单一的其它对象上时,连接是双向的。也就是说,如果给连接输出端的对象赋值时,输入端的对象也会改变,反之亦然。这在很多应用程序中是一个有用的特征。
打开Echo和它内部的DistanceSR。
你会看到DistanceSR的当前值是60。

还要注意DistanceSR的值域显示了与sr_in的连接。(路径名前缀 <- 告诉AVS/Express,被连接的对象sr_in是在对象层次的上一层,也就是说,与Echo在同一层。)你本来可以不用图形连接,直接转入语法来把DistanceSR连接到sr_in上。

把sr_in从60变到70。
DistanceSR相应地变化。
给DistanceSR赋值50。
用值50覆盖DistanceSR的当前内容,然后按Enter。
sr_in改变。注意连接重新出现在DistanceSR的值域中。

4.9 用新项目重新启动AVS/Express

启动时,AVS/Express是通过确定使用的项目并装入它来开始工作的。AVS/Express是用缺省值装入并安装项目的。你可以有几种方法改变这个行为。一个方法是指定项目命令行方式。
从Network编辑器中选择File‘Exit下拉命令退出AVS/Express。
重新启动AVS/Express,指定项目命令行方式。
可视化编辑用户键入:
|
UNIX
|
Windows
|
|
vxp
–project myproj
|
bin\pc\vxp
–project myproj
|
开发者编辑用户键入:
|
UNIX
|
Windows
|
|
express
-project myproj
|
bin\pc\express
–project myproj
|
根据保存myproj的地方,你可以指定一个路径名。在Windows里,你必须为V命令处理器(VCP)的出现指定-vcp方式。
在初始的应用程序对话框中,选择Application。
注意:如果你想要AVS/Express在启动时不显示初始应用程序对话,直接装入DefaultApplication,则设置开关Set
Project’s Default Application。下次你装入这个项目时,AVS/Express会把DefaultApplication作为缺省来使用,而不会向你询问初始应用程序。
AVS/Express装入你的项目。你可以提供三种方式验证它:出现启动信息指示项目的路径名;Network编辑器标题条显示项目的路径名;库工作区页包含Echo。
这一章结束。
或者在AVS/Express中继续下面的指南,或者选择File‘Exit下拉命令退出AVS/Express。
4.10 更多的信息
参见《使用AVS/Express》的第4章“在Network编辑器使用对象”
参见《使用AVS/Express》的第7章“管理对象”

|