playsound函数在那个dll里面_TransCAD自定义延误函数创建和使用

TransCAD有几个现成的流量延误函数(VDF)可供用户在交通分配时选择,其中包括Akcelic Flow Delay(HCM2000)、Bureau of PublicRoad (BPR)、Conical Congestion、Generalized Cost 、Logit Delay以及信号交叉口延误函数等多种常用函数。用户还可以自己创建流量延误函数的动态链接库,用来解决特别的交通分配问题。例如,在TransCAD的软件用户界面中,用户可以选择相应的延误函数,并可对不同的路段类型设置不同的参数。如果用户希望不同的路段类型使用不同的函数形式,这就可能需要定制VDF了。

47a4b6d5bcbd9e9607794cfc07e039d8.png

1编译环境设置

必须用Microsoft Visual C的7.0版本以上编译 DLL,并采用__fastcall形式。编译好的DLL用.VDF的后缀名放在TransCAD安装目录下,调用交通分配程序时就可以看到用户自己定义的VDF。如果DLL编译不恰,或者缺少必要的函数,TransCAD会返回错误信息。TransCAD需要的一些常数,定义在VDFDLL.H文件里。这里我们用Visual Studio 2010版本为例。

1.1动态链接库项目创建

在Visual Studio 2010选择文件-新建项目,创建一个新的项目,选择Win32项目。在名称编辑栏输入UserVDF,在位置编辑栏输入“C:\Program Files\TransCAD 8.0\VDFDev”,如下图所示:

1f47e0e8ef0733e2fea29deff1ba5b20.png

点击确认后,进入Win32应用程序向导。

8f4b5249abb3f529b49757f1e0e3a8d1.png

这里我们假定你的TransCAD是安装在“C:\ProgramFiles\TransCAD 8.0”下面,而你自己的VDF工程要存储在它下面的VDFDev文件夹里面。

单击“下一步”,弹出程序设置对话框。

f1560b3e1cc3dec8643393df3ff8d6c0.png

在应用程序类型单选列表选择DLL类型。在附件选项选择空项目。最后点击完成。Visual Studio在你指定的“C:\Program Files\TransCAD 8.0\VDFDev”下面的UserVDF文件夹里生成几个项目的文件。

原先在“C:\ProgramFiles\TransCAD 8.0\ GISDK\VDF”文件夹里,TransCAD已经安装了创建用户自己的VDF所需要的两个文件(VDFDLL.H和VDF_Preprocessor.c)和一个VDF的例子(bpr.c)。下面我们用bpr.c为例,解释如何为TransCAD编译你自己的VDF。

1.2加载VDF代码

TransCAD使用的动态链接库必须用Microsoft Visual C 7.0或以上的版本通过快速(__fastcall)调用协议(argument-callingconvention)进行编译。编译好的执行文件必须用后缀为.VDF的文件名存放在TransCAD程序目录下,以便TransCAD自动找到它。这些要求可以通过下列步骤实现:

(1)把原先在C:\ProgramFiles\TransCAD 8.0\ GISDK\VDF文档里,三个文件VDFDLL.H、VDF_Preprocessor.c和bpr.c,复制到“C:\Program Files\TransCAD 8.0\VDFDev\UserVDF”。

(2)在解决方案资源管理器树视窗口下面,在你刚刚生成的UserVDF项目节点单击鼠标右键,选择“添加—现有项”。

537d4a13e890d2cdb95302cab2dfb9dd.png       8fb0566b94d029ffac15137af01d8d33.png      

(3)将VDFDLL.H和bpr.c加入项目(VDF_Preprocessor.c不需要,它在bpr.c被包含了,resource.h是Visual Studio系统带的头文件)。 

ae5b340e72ab4d42d109e4f94d0d1d0a.png

打开bpr.c,在第120行作如下改动:

shortDLLEXPORT VDF_GetLabel(char *label)

{

    strncpy(label,  "用户测试BPR函数",   VDF_LABELSIZE);

    return TC_OKAY;

}

这里我们只是把字串“Bureau of PublicRoads (BPR)”换成“用户测试BPR函数”。

你自己的VDF函数当然不只是函数的名称和TransCAD程序提供的这个例子中有所不同,你可以进一步修改这个例子,或从头编写你自己的VDF程序。基本的步骤和要实现的函数在TransCAD交通需求模型手册的有关章节中已经有具体描述。

1.3设置编译参数

(1)在解决方案资源管理器树视窗口下面,鼠标右键单击UserVDF节点,选择“属性”打开项目设置界面。注意,调试项目是采用Debug模式,正式的dll使用Release模式编译。你也可以在配置下拉菜单中选择“所有配置”设置所有模式的配置。 

8a2d7d3388d38274236bca388a708316.png d9989266fe08e63cf0e5b3514d256e0e.png 

配置属性页面的常规输出目录编辑栏,输入TransCAD 8.0程序所在的文件夹,这可以是相对路径名“..\..\..”,因为工程文件夹比TransCAD8.0程序文档低三级(这里项目在UserVDF文件夹下面又创建了一个UserVDF文件夹,多了一层)。

265a380dc8992b80164c2ce2764779b0.png 

(2)在调试页面的命令编辑栏输入TransCAD的执行文件“tcw.exe”所在的路径名(可以是相对目录..\..\..\ tcw.exe)。 

223546a2f704c1cc64947fab66658080.png

作这项选择与创建VDF没有关系,但它可以让你在MicrosoftVisual Studio的IDE环境下进行你的VDF程序的纠错。

(3)单击C/C++下的高级页,在调用约定下拉菜单选择“__fastcall(/Gr)”。

71415ecacd0ee644749db84cbb7eab18.png 

(4)在链接器下面的常规页面的输出文件编辑栏,把输出的执行文件的后缀从.dll改成.vdf。 

3aa3445d868c78b0e28522ab652c9bd7.png 

1.4编译和链接VDF

(1)编译。你定制VDF函数的程序写好以后,可以用VisualStudio的生成-生成解决方案命令,快捷键F7,或鼠标点击按钮来进行编译和连接。如果一切顺利,这将在TransCAD程序文档中创建一个UserVDF.vdf文件和同名但后缀为.lib和.pdb等等的文件。对TransCAD使用你的VDF而言,只需保存动态链接库函数UserVDF.vdf文件。有关其他文件和更多编译、连接和执行程序的选项,请参阅VisualStudio的用户手册。

(2)64位TransCAD版本的延误函数编译。TransCAD 6.0以上开发了64位版本。用vs2010打开之前dll项目,这时候项目的默认是32位的,点击生成菜单下面的“配置管理器”--“活动解决方案配置”选择debug或者release,“活动解决方案平台”下选择“新建”,在弹出的对话框“键入或选择新平台”下选择“x64”,直接点击“确定”。 

d09f516b6e67f350a1c335febee6e1cf.png

(3)用定制的VDF进行TransCAD交通分配。打开TransCAD以后,点击File-OpenWorkspace打开C:\Users\用户名\Documents\Caliper\TransCAD 8.0\Tutorial文件夹下的Tutorial文档中的Workspace 文件“Traffic Assign.wrk”。TransCAD将打开一个地图、矩阵和相应的网络。选择TransCAD的Planning-Traffic Assignment对话框:

6d1a60c911c76cd19328ce49966d9fd3.png

注意到你的VDF(用户测试BPR函数)已经出现Delay Function下拉菜单下的选项当中。

(4)调试VDF。用定制程序编译和链接无误以后,可以用Visual Studio的调试-启动调试命令或快捷键F5启动TransCAD。

在必要时,用Visual Studio你可以在自己程序的指定地点设置断点(Break Points)。程序执行到你的断点你可以检查输入变量的值,你的程序的流程和返回值。编制自己的VDF时,这样的查错功能往往是很重要的。

程序满意以后,你可以将其重新编译成优化的格式(Optimized)。这可以通过Visual Studio的生成菜单下面的“配置管理器”--“活动解决方案配置”命令来实现。在Configuration Manager对话框,把“活动解决方案配置”改成Release,并对你的VDF的Release版本重复前面“设置编译参数”和“编译和链接VDF”章节描述的步骤(如果所有配置中已经设置,则不需要),以便生成优化的VDF执行文件,使你定制的交通分配程序以最快的速度进行。

6378e8eaeb7bab7ae234b04e62f00439.png 

2 延误函数的程序编写
2.1基本要求

在TransCAD中可以创建自己的延误函数进行交通分配。VDF函数必须保证是凸的以保证交通分配的收敛性,满足以下条件:

•单独递增;

•连续可导;

•必须有过饱和状态的定义(一些路段的分配流量会大于通行能力)。

必须用Microsoft Visual C的7.0版本以上编译 DLL,并采用__fastcall形式。编译好的DLL用.VDF的后缀名放在TransCAD安装目录下,调用交通分配程序时就可以看到用户自己定义的VDF。如果DLL编译不恰,或者缺少必要的函数,TransCAD会返回错误信息。TransCAD需要的一些常数,定义在VDFDLL.H文件里。

2.2主要变量

自由流时间T0和通行能力CAPACITY必须为前2个输入变量。另外,后面6个变量必须为LENGTH, SPEED, Preload, Type,CURRENT和 N_FIELDS。分别表示路段长度,自由流速度,预加载,路段类型、当前拥挤成本,延误函数字段数目。其余变量可以添加在中间。下面是一个广义成本延误函数typedef声明的例子: 

typedef enum field_

{

T0,

// Free flow travel  time

CAPACITY,

// Link Capacity

ALPHA,

// BPR Alpha  Parameter

BETA,

// BPR Beta  Parameter

K,

// Constant

OP_COST,

// Operating Cost

VOT,

// Value of Time

LENGTH,

// Link Length

SPEED,

// Free flow Speed

PRELOAD,

// Preload Volume

TYPE,

// Link Type

CURRENT,

// Updated Time

N_FIELDS

// Number of Fields

} FIELD;

 VDF允许定义一些输入变量以及他们是否必要,或者是默认的参数值而与网络无关。例如,PRELOAD变量不是必须的,ALPHA和BETA参数的值可以默认设定。有些变量只是在特定条件下需要,譬如网络里面已经有自由流时间,LENGTH 和 SPEED变量就不需要了。变量的值可以设置上下限的值。TransCAD程序目录下的GISDK\VDF文件夹可以找到gc_vdf.c和VDF_Preprocessor.c代码文件。

初始化DLL必须做以下程序:

void InitVDFDLL(int *ptc_status)

 要获得延误函数文字描述:

short _export VDF_GetLabel(char *label)

 要获得参数的默认值,需要包含以下函数:

long

VDF_GetNParameters(  void )

short

VDF_GetParameters(char  **param_names)

short

VDF_GetDefaults(double  *d)

 路段传入4字节浮点矩阵数据。矩阵比参数的数目多2行,通过VDF_GetNParameters (n)函数返回。矩阵的列数和路段数相等。第一个参数是自由流时间,第二个为通行能力。最后n+2个为DLL计算的当前路段成本以及路段类型。

初始化DLL后,获取矩阵数据的参数信息需要初始化,通过pre-process函数实现:

short VDF_Preprocess(float **Cost, long*links, void *defaults, short *types, short *n_types)

 这个函数即使在成本数组初始化的情况下,也需要调用,这是DLL获取路段数据以访问矩阵成本数据的地方。默认的数组要么是一维的默认值,或者二维默认值依赖于路段类型。 

用户也可以设置延误函数的常数,用下面的回调函数获取常数项数目,修改常数项的值以及设置常数项:

long

VDF_GetNConstants()

short

VDF_GetConstantNames*char  **constant_names)

short

VDF_GetConstants(double  *c)

short

VDF_SetConstants(double  *c)

成本回调函数为:

double

VDFValue(double  *FlowVal, long *link, float **Cost, short *DisabledLinks)

void

VDFValues(double  *Flow, float **Cost, long *links, short *DisabledLinks)

void

VDFTimeOnly(double  *Flow, float **Cost, long *links, short *DisabledLinks)

 VDFTimeOnly()函数用来计算拥挤时间,计算的结果保存在交通分配结果表中的AB_Time和 BA_Time 字段。函数VDFValue()和VDFValues() 用来计算成本。VDFValue() 是一次计算一个路段,而 VDFValues()是一次计算所有路段。计算的结果保存在交通分配结果表中的AB_VDF 和 BA_VDF 字段。因此AB_VDF和BA_VDF 字段包含了所有的拥挤成本。

 如果VDF用来OUE交通分配,需要增加两个函数:

double

VDF_Derivative(double  *FlowVal, long *link, float **Cost, short *DisabledLinks)

double

VDF_Integral(double  *Flow, float **Cost, long *links, short *DisabledLinks)

 这个两个函数分别是VDFValue()的导数和积分。其他分配方法不需要这两个函数。

2.3BPR延误函数的例子

6fd1c9cc0cc92737e48363c1080a0398.png

4021f1b61327c5d0ad0a101ba8e4bd71.png

5bfa9cd7fac8f6f346768424209bccda.png

1acdd5186662a24fe8bb67e6a1fefe02.png

6ef6273d83293ffc6c1c19fbab85e429.png

f87cecfb05fe17280666ad4d02f05476.png

d57a7c36db0c3619605e6622bab546e0.png

8fd171a15fafc68fefe6d0693b015045.png

75ddf71230da1c52d3ba2ced734883c1.png

您有任何技术问题和软件购买需要,请联系我们:

客服微信号:YishuvInfo

4a591e34456d1dd1f97885a8dcfa3f2b.png

微信公众号:TransCADTransModeler

d0cd983ba820e7e68a7d95deb9179993.png

邮箱:TransInfoTech@163.com

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值