UaModeler是一个OPC UA信息模型的建模工具,和UaExpert同出一个网站,可以去其网站下载(需要注册一个账号),也可以点击这里进行下载(本人下载后传到百度云上)。注意,这是个商业软件,免费使用时可创建的Node数量有限,不过用来学习足够了。

使用SIOME建模的文章请点击这里,西门子出的免费软件,也非常好用。

在之前的系列文章中,我们往OPC UA Server里添加东西都是使用代码,当工程比较大时这么做就有点繁琐了。本文主要讲述如何使用UaModeler进行建模,并在代码中使用建好的模型。


一 安装UaModeler

下载后解压,然后点击这个exe文件进行安装,

安装ok后打开,界面如下,

在Help下有个Handbook,里面描述了常用的使用方法,大家也可以直接参考这个手册。


二 使用UaModeler

1. 创建新工程

点击File->New Project,

在弹出的界面里,输入Project Name并选择工程保存位置,然后点击Next,

在下一个Generate Code界面里,选择生成的代码类型,这里选择ansi_c v1_9,然后再选择一下输出代码的路径,最后点击Next,(代码类型可随意选,我们最后并不使用UaModeler去生成代码

后面2个界面选Next就行了,使用默认配置,


然后下一个界面里可以根据需要修改Namespace URI,最后点击Finish

工程新建好后,界面如下,

我们新建的model在Projet窗口下,即example.ua

2. 添加Object Type节点

我们想新增一个Object Type,即对象类型,该类型含有2个变量和一个方法,这个方法有2个输入参数和一个输出参数。

在Information Model下展开Types->ObjectTypes,选中BaseObjectType,然后右击,

点击Add New Type,在中间的窗口中输入想要添加的Object Type名称,这里填入MyObjectType,

然后点击Children右侧的那个倒三角进行展开,

点击Select NodeClass,选择Variable,

然后在Name栏下输入名字Var1,并更改DataType为Int32,

先点击Double右侧的那个下拉符号,下拉后点击最下面的Add,

在弹出的界面里选择数据类型,

同样,我们再添加一个Variable,叫Var2,

再添加一个方法,

名字叫Func,

展开这个Method,设置其输入和输出参数,

这里为这个方法设置2个输入参数:input0和input1,1个输出参数:output0,类型都是Int32,如下图(注意:只要Add Argument里没有输入名称,那么这个就不算作参数)

对于添加的方法,还需要注意一点:我们并没有为方法添加代码逻辑,只能算一个空壳,后面在使用这个Object Type生成对象时才会添加逻辑。

其它都采取默认,然后保存工程,这样这个Object Type就创建好了。

3. 生成xml文件

使用UaModeler建模只需要最终生成的xml,不需要其生成的代码,后续会使用open62541自带的工具生成相关代码。

在Project窗口选中example.ua,右击,选择Export XML(第一次会询问是否要设置模型版本号,可以设置也可以不设置,采取默认也行)

生成OK后,在工程目录下可以看到生成的xml文件,如下,


三 使用open62541处理XML

1. 配置open62541

首先,需要对open62541进行配置,先打开dos窗口或shell窗口,cd到open62541源码目录下,执行下面的命令,

git submodule update --init

会下载一些必须的子模块,用于代码生成。

然后,打开open62541源码目录下的CMakeLists.txt,找到UA_ENABLE_AMALGAMATION设置为ON,接着找到下面这段设置,

# Namespace Zero
set(UA_NAMESPACE_ZERO "REDUCED" CACHE STRING "Completeness of the generated namespace zero (minimal/reduced/full)")
SET_PROPERTY(CACHE UA_NAMESPACE_ZERO PROPERTY STRINGS "MINIMAL" "REDUCED" "FULL")

把UA_NAMESPACE_ZERO的值由REDUCED改为FULL,然后执行以下操作,

  • 在open62541源码目录下新建build目录,并cd进入
  • 执行cmake .. && make,会比较耗时

OK后把open62541.h和libopen62541.a拷贝到自定义工程目录,例如如下,

myNS是本次的工程目录,也可以根据需要自定义任意目录

PS:由于UA_NAMESPACE_ZERO变成FULL,所以libopen62541.a也变大了很多

2. 生成自定义信息模型代码

这一步就使用到了之前生成的example.xml,先把该xml文件拷贝到tools/nodeset_compiler下,然后执行下面的命令,最后一个参数myNS用来指示生成的代码文件名称,注意要使用python3,

python ./nodeset_compiler.py --types-array=UA_TYPES --existing ../../deps/ua-nodeset/Schema/Opc.Ua.NodeSet2.xml --xml example.xml myNS

打印如下,表示生成成功

在当前路径下输入ls,可以看到生成了myNS.c和myNS.h,这2个文件就是我们需要的,

把myNS.c和myNS.h拷贝到如下src目录,

打开myNS.h,其中有段编译控制,

#ifdef UA_ENABLE_AMALGAMATION
# include "open62541.h"
#else
# include <open62541/server.h>
#endif

直接改成如下,因为我们使用的是open62541.h

# include "open62541.h"

3. 编写OPC UA Server代码

在src目录下添加文件server.c,

其内容如下,创建了2个对象,分别叫myNSObject和myNSObject2,

/* This work is licensed under a Creative Commons CCZero 1.0 Universal License.* See http://creativecommons.org/publicdomain/zero/1.0/ for more information. */#include <signal.h>
#include <stdio.h>
#include "open62541.h"/* Files myNS.h and myNS.c are created from myNS.xml */
#include "myNS.h"UA_Boolean running = true;static void stopHandler(int sign) {UA_LOG_INFO(UA_Log_Stdout, UA_LOGCATEGORY_SERVER, "received ctrl-c");running = false;
}// 这个方法的功能是把输入参数累加,传给输出参数
static UA_StatusCode helloWorldMethodCallback(UA_Server *server,const UA_NodeId *sessionId, void *sessionHandle,const UA_NodeId *methodId, void *methodContext,const UA_NodeId *objectId, void *objectContext,size_t inputSize, const UA_Variant *input,size_t outputSize, UA_Variant *output)
{UA_Int32 value = 0;for (size_t i = 0; i < inputSize; ++i){UA_Int32 * ptr = (UA_Int32 *)input[i].data;value += (*ptr);}UA_Variant_setScalarCopy(output, &value, &UA_TYPES[UA_TYPES_INT32]);UA_LOG_INFO(UA_Log_Stdout, UA_LOGCATEGORY_SERVER, "Hello World was called");return UA_STATUSCODE_GOOD;
}int main(int argc, char **argv)
{signal(SIGINT, stopHandler);signal(SIGTERM, stopHandler);UA_Server *server = UA_Server_new();UA_ServerConfig_setDefault(UA_Server_getConfig(server));UA_StatusCode retval;/* create nodes from nodeset */if (myNS(server) != UA_STATUSCODE_GOOD) {UA_LOG_ERROR(UA_Log_Stdout, UA_LOGCATEGORY_SERVER, "Could not add the example nodeset. ""Check previous output for any error.");retval = UA_STATUSCODE_BADUNEXPECTEDERROR;} else {// 方法节点的NodeId是UA_NODEID_NUMERIC(2, 7001)UA_Server_setMethodNode_callback(server, UA_NODEID_NUMERIC(2, 7001), &helloWorldMethodCallback);UA_NodeId createdNodeId;UA_ObjectAttributes object_attr = UA_ObjectAttributes_default;object_attr.description = UA_LOCALIZEDTEXT("en-US", "myNSObject");object_attr.displayName = UA_LOCALIZEDTEXT("en-US", "myNSObject");// we assume that the myNS nodeset was added in namespace 2.// You should always use UA_Server_addNamespace to check what the// namespace index is for a given namespace URI. UA_Server_addNamespace// will just return the index if it is already added.UA_Server_addObjectNode(server, UA_NODEID_NULL,UA_NODEID_NUMERIC(0, UA_NS0ID_OBJECTSFOLDER),UA_NODEID_NUMERIC(0, UA_NS0ID_ORGANIZES),UA_QUALIFIEDNAME(1, "myNSObject"),UA_NODEID_NUMERIC(2, 1002),object_attr, NULL, &createdNodeId);UA_NodeId createdNodeId2;UA_ObjectAttributes object_attr2 = UA_ObjectAttributes_default;object_attr2.description = UA_LOCALIZEDTEXT("en-US", "myNSObject2");object_attr2.displayName = UA_LOCALIZEDTEXT("en-US", "myNSObject2");// we assume that the myNS nodeset was added in namespace 2.// You should always use UA_Server_addNamespace to check what the// namespace index is for a given namespace URI. UA_Server_addNamespace// will just return the index if it is already added.UA_Server_addObjectNode(server, UA_NODEID_NULL,UA_NODEID_NUMERIC(0, UA_NS0ID_OBJECTSFOLDER),UA_NODEID_NUMERIC(0, UA_NS0ID_ORGANIZES),UA_QUALIFIEDNAME(1, "myNSObject2"),UA_NODEID_NUMERIC(2, 1002),object_attr2, NULL, &createdNodeId2);retval = UA_Server_run(server, &running);}UA_Server_delete(server);return (int) retval;
}

代码解析:

  1. 调用自定义信息模型中提供的myNS()函数来添加新建的信息模型,这样在OPC UA Server里就可以看到我们定义的对象类型节点了,即MyObjectType
  2. 对象类型中的方法比较特殊,与变量不一样,类似于C++类中的成员函数,不管用对象类型生成多少对象,其包含的方法都只会指向同一个方法,而变量则会与对象一起生成,对象之间互不干扰
  3. 使用UA_Server_setMethodNode_callback()给方法节点设置方法,注意不能使用UA_Server_addMethodNode(),因为方法已经在信息模型中添加好了,只不过是一个空壳
  4. 多次调用UA_Server_setMethodNode_callback(),只会使用最后一次调用所添加的方法
  5. 使用UA_Server_addObjectNode()来创建对象节点,参数中对象类型的NodeId是UA_NODEID_NUMERIC(2, 1002),就是使用UaModeler创建的对象类型

可能会问:我怎么知道对象类型的NodeId以及其方法的NodeId呢?有2种方法:

  1. 先用代码测试一下,代码中只调用myNS(),不去创建对象,编译后运行server,然后使用UaExpert去连接,连接后去地址空间窗口中去查看,

    在ObjectTypes里找到MyObjectType并展开,在右侧的属性窗口中就可以看到NodeId了
  2. 使用路径搜索,因为我们知道对象类型的名称,所以使用路径Root->Types->ObjectTypes->MyObjectType就可以搜到了,路径搜索可参照这篇文章

如果是正式应用,推荐第2种方法去获得NodeId

整体工程结构如下,

CMakeLists.txt内容如下,

cmake_minimum_required(VERSION 3.5)project(myNamespace)set(EXECUTABLE_OUTPUT_PATH  ${PROJECT_SOURCE_DIR}/bin)add_definitions(-std=c99)include_directories(${PROJECT_SOURCE_DIR}/open62541)
include_directories(${PROJECT_SOURCE_DIR}/src)find_library(OPEN62541_LIB libopen62541.a HINTS ${PROJECT_SOURCE_DIR}/open62541)add_executable(server ${PROJECT_SOURCE_DIR}/src/server.c ${PROJECT_SOURCE_DIR}/src/myNS.c)
target_link_libraries(server ${OPEN62541_LIB})

cd到build目录下执行cmake .. && make,生成的elf文件在bin目录下,由于libopen62541.a变大了,所以链接时会比较慢。

3. 使用UaExpert进行连接

连接OK后,可以看到创建的2个对象都成功生成了。

展开这2个对象,可以看到它们的方法Func的NodeId都是一样的,而变量的则是不同的,这也印证了前面的说法,

可以执行一下这个方法来测试一下,右击Func,点击Call,

在弹出的界面里输入2个参数值,然后点击Call,

最后会在输出参数里得到300,和期望的一样

验证OK!


四 总结

本文主要讲述如何使用UaModeler来创建信息模型,然后生成对应的xml文件,最后使用open62541自带的工具把信息模型转成代码并添加到OPC UA Server里。

过程稍微复杂了一点,本人写的也是累的一批。希望看过的同学能给个赞,谢谢。

本文创建的对象类型比较简单,如果需要创建复杂的类型或多个类型,则需要自己探索,如果搞懂了本文的例子,应该没有什么问题。

如果有写的不对的地方,希望能留言指正,谢谢阅读。

学习open62541 --- [15] 使用建模工具UaModeler相关推荐

  1. Maya和Blender先学习哪个更好?这两个3D建模工具的主要区别

    Maya 是由 Alias Systems Corporation 开发的 3D 计算机图形应用程序,目前由 Auto desk, Inc 拥有.它可以在 Windows.Mac OS 和 Linux ...

  2. 入门学习建模需要了解并掌握哪些软件?工业建模、游戏建模工具介绍

    3D建模软件普遍存在于我们的日常的学习和工作中,但是高校基本不开设软件类课程.在真正的工作中,我们才发现在学校自学的那点软件基础完全不够用,甚至连基本的软件知识都不清楚.所以今天,我们对几款超好用的3 ...

  3. mysql构建数据立方体_OLAP数据建模工具Workbench的初步使用(数据立方体的建立)

    OLAP数据建模工具Workbench的初步使用(数据立方体的建立) 概要: 1.workbench工具简介 2.workbench简单操作(附demo) 3.workbench初步使用总结 1.wo ...

  4. 【3D建模工具】上海道宁与McNeel为您提供强大的专业3D造型软件

    Rhino可以对 NURBS曲线.曲面.实体. 细分几何图形 (SubD).点云和多边形网格 进行创建.编辑.分析.记录. 渲染.动画制作与转换 只要硬件条件允许 不受复杂度.阶数与尺寸大小的限制 R ...

  5. 【转】专家推荐 13个优秀的UML建模工具软件

    [转]专家推荐 13个优秀的UML建模工具软件 UML建模工具的概念相信大家应该有所了解,这里向大家介绍几个UML建模工具软件使用,希望通过本文的介绍你对UML建模工具软件有一定的认识. 本文和大家重 ...

  6. 构建OPC UA 可执行模型(3)-建模工具

    组态程序是用户构建OPC UA 应用系统的关键工具,尽管我们看到由UaModeler这种OPCUA 建模工具, 但是使用这种工具需要大量OPC UA 信息模型的技术细节,使用起来实在是麻烦了.笔者认为 ...

  7. Python实现3D建模工具(下)

    用户接口 我们希望与场景实现两种交互,一种是你可以操纵场景从而能够从不同的角度观察模型,一种是你拥有添加与操作修改模型对象的能力.为了实现交互,我们需要得到键盘与鼠标的输入,GLUT允许我们在键盘或鼠 ...

  8. uml图工具_UML建模工具更新情况(二)

    UMLChina整理的UML建模工具列表请见http://www.umlchina.com/tools/search.aspx最近一段时间更新: 工具最新版本:Software Ideas Model ...

  9. uml 工具_UML建模工具更新202008(1)Rhapsody名字不再有Rational

    UMLChina整理的UML建模工具列表请见http://www.umlchina.com/tools/search.aspx 最近一段时间更新: 工具最新版本:IBM Engineering Sys ...

  10. 基于uml的系统分析的网上商城_UML建模工具Enterprise Architect最新版有哪些新功能呢?立即查看...

    Enterprise Architect是一个对于软件系统开发有着极好支持的CASE软件(Computer Aided Software Engineering).EA不同于普通的UML画图工具(如V ...

最新文章

  1. jpa 根据主键生成策略获取id_JPA主键生成策略
  2. [LeetCode] Reverse Linked List I II - 链表翻转问题
  3. 着色器的细节层次技术 Shader Level of Detail
  4. Java的HttpClient类以POST方式提交数据,目标端收到后中文乱码
  5. 半路学习编程,有希望成为大牛吗?
  6. Java 验证码图片不加载处理办法
  7. 2019风向趋势分析报告——覆盖5G、人工智能、金融科技等领域
  8. VBA,工作簿workbook相关操作,workbooks.add workbooks.save workbooks.saveas 等等
  9. 软件系统设计-1-软件设计原则
  10. nodejs--数据库与身份验证:初识数据库、安装并配置 MySQL、MySQL 的基本使用、SQL语法、在项目中操作 MySQL
  11. CMake 之 BUILD_SHARED_LIBS 和 CMAKE_BUILD_TYPE 用法教程
  12. Java集合之Collection集合、泛型 【集合综合案例:赌神、赌侠、赌神斗地主】
  13. Shell | 实用命令不完全总结
  14. 小程序工具类无云开发按钮(已解决)
  15. Opera下载最新版本地址
  16. Revit二次开发,新手接入IExternalCommand、IExternalApplication,如何使用它们!
  17. WorkFlow .Net 流程介绍
  18. FusionCharts Demo
  19. Android 直播 播放器 IJK播放器低延时120ms
  20. 网络安全系列-五十一:网络流量威胁监测系统的方案选择

热门文章

  1. 前端面试题及解答(尽量口语化,模拟面试现场时的回答)
  2. matlab如何定义dmod函数,matlab中的dmod函数
  3. 史上最经典摇滚柔情曲15首
  4. 码云 VS首次提交代码报错:failed to push some refs to 'https://gitee.com/Liu_Cabbage/ASP.NET-MVC-QQ-Connect.git'
  5. fread, fwrite和fflush
  6. 软件开发岗位职责描述
  7. SDOI2019R2翻车记
  8. 大器晚成总比一事无成要强
  9. 基于QPSK+LDPC的微波信道误码率matlab仿真
  10. 百度SEO站群WeLive免费在线客服系统 v5