Skip to content

Commit

Permalink
🔧 OPC UA 模块增加数据源变量类型,并更新原先对应的服务端函数
Browse files Browse the repository at this point in the history
  • Loading branch information
zhaoxi-scut authored and TooPretty0108 committed Dec 16, 2024
1 parent 2ffa77f commit 1184180
Show file tree
Hide file tree
Showing 17 changed files with 172 additions and 136 deletions.
9 changes: 7 additions & 2 deletions 3rdparty/open62541/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,13 @@ project(
LANGUAGES C
)

set(SAVED_CMAKE_C_FLAGS "${CMAKE_C_FLAGS}")

option(UA_ENABLE_PUBSUB "Enable the PubSub protocol" ON)
rmvl_download(open62541 GIT "https://github.com/open62541/open62541.git : v1.3.8")
set(open62541_VERSION "1.3.8" CACHE INTERNAL "open62541 version")
rmvl_download(open62541 GIT "https://github.com/open62541/open62541.git : v1.4.8")

set(CMAKE_C_FLAGS "${SAVED_CMAKE_C_FLAGS}" CACHE INTERNAL "C Compiler Flags")

set(open62541_VERSION "1.4.8" CACHE INTERNAL "open62541 version")

_rmvl_set_target_in_3rd(open62541)
11 changes: 7 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,13 @@

**机器人控制与视觉库**

| 分支 | 编译器 | OpenCV | onnxruntime | open62541 | 工作流状态 |
| :----: | :---------------------------------------: | :-------------------------: | :----------------------------: | :-------------------------: | :----------------------------------------------------------: |
| master | GCC 7.5.0<br />GCC 12.3.0<br />GCC 14.0.1 | 4.2.0<br />4.5.3<br />4.9.0 | 1.10.0<br />1.12.0<br />1.18.1 | 1.3.8<br />1.3.8<br />1.4.0 | [![1.x in Linux](https://github.com/cv-rmvl/rmvl/actions/workflows/linux-1.x.yml/badge.svg)](https://github.com/cv-rmvl/rmvl/actions/workflows/linux-1.x.yml) |
| 2.x | GCC 7.5.0<br />GCC 12.3.0<br />GCC 14.0.1 | 4.2.0<br />4.5.3<br />4.9.0 | 1.10.0<br />1.12.0<br />1.18.1 | 1.3.8<br />1.3.8<br />1.4.0 | [![2.x in Linux](https://github.com/cv-rmvl/rmvl/actions/workflows/linux-2.x.yml/badge.svg)](https://github.com/cv-rmvl/rmvl/actions/workflows/linux-2.x.yml) |
| 分支 | 测试 | 工作流状态 |
| :--: | :-----: | :----------------------------------------------------------: |
| 1.x | Linux | [![1.x in Linux](https://github.com/cv-rmvl/rmvl/actions/workflows/linux-1.x.yml/badge.svg)](https://github.com/cv-rmvl/rmvl/actions/workflows/linux-1.x.yml) |
| 2.x | Linux | [![2.x in Linux](https://github.com/cv-rmvl/rmvl/actions/workflows/linux-2.x.yml/badge.svg)](https://github.com/cv-rmvl/rmvl/actions/workflows/linux-2.x.yml) |
| 2.x | Windows | [![2.x in Windows](https://github.com/cv-rmvl/rmvl/actions/workflows/windows-2.x.yml/badge.svg)](https://github.com/cv-rmvl/rmvl/actions/workflows/windows-1.x.yml) |
| 1.x | —— | [![1.x in Release](https://github.com/cv-rmvl/rmvl/actions/workflows/release-1.x.yml/badge.svg)](https://github.com/cv-rmvl/rmvl/actions/workflows/release-1.x.yml) |
| 2.x | —— | [![2.x in Release](https://github.com/cv-rmvl/rmvl/actions/workflows/release-2.x.yml/badge.svg)](https://github.com/cv-rmvl/rmvl/actions/workflows/release-2.x.yml) |

RMVL 最初是面向 RoboMaster 赛事的视觉库,现在此之上逐步完善有关基础算法、机器视觉、通信的功能,旨在打造适用范围广、使用简洁、架构统一、功能强大的视觉控制一体库。

Expand Down
46 changes: 24 additions & 22 deletions cmake/RMVLCompilerOptions.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -112,23 +112,30 @@ if(ENABLE_PIC)
set(CMAKE_POSITION_INDEPENDENT_CODE ${ENABLE_PIC})
endif()

option(ENABLE_LTO "Enable Link Time Optimization" ON)
include(CheckCXXCompilerFlag)

function(check_and_add_cxx_flag cxx_flag)
string(FIND "${CMAKE_CXX_FLAGS}" "${cxx_flag}" flag_already_set)
if(flag_already_set EQUAL -1)
string(REGEX REPLACE "[-=/]" "_" flag_var_name "HAVE${cxx_flag}")
string(TOUPPER ${flag_var_name} flag_var_name)
check_cxx_compiler_flag("${cxx_flag}" ${flag_var_name})
if(${flag_var_name})
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${cxx_flag}" CACHE INTERNAL "CXX Compiler Flags")
endif()
endif()
endfunction()

option(ENABLE_LTO "Enable Link Time Optimization" OFF)
if(ENABLE_LTO)
include(CheckCXXCompilerFlag)
if(RMVL_GNU OR RMVL_CLANG OR RMVL_APPLECLANG)
check_cxx_compiler_flag("-flto=auto" HAS_LTO_AUTO_FLAG)
if(HAS_LTO_AUTO_FLAG)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -flto=auto")
else()
check_cxx_compiler_flag("-flto" HAS_LTO_FLAG)
if(HAS_LTO_FLAG)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -flto")
endif()
check_and_add_cxx_flag("-flto=auto")
if(NOT HAVE_FLTO_AUTO)
check_and_add_cxx_flag("-flto")
endif()
elseif(RMVL_MSVC)
check_cxx_compiler_flag("/GL" COMPILER_SUPPORTS_LTO)
if(COMPILER_SUPPORTS_LTO)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /GL")
check_and_add_cxx_flag("/GL")
if(HAVE_GL)
set(CMAKE_STATIC_LINKER_FLAGS "${CMAKE_STATIC_LINKER_FLAGS} /LTCG")
set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} /LTCG")
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} /LTCG")
Expand Down Expand Up @@ -174,16 +181,11 @@ endif()
option(ENABLE_WARNING "Enable warning for all project " ON)
if(ENABLE_WARNING)
if(RMVL_MSVC)
add_compile_options("/W3")
check_and_add_cxx_flag("/W3")
else()
add_compile_options(
-Wall
-Wextra
-Wpedantic
# -Wconversion
# -Werror
# -Wfatal-errors
)
check_and_add_cxx_flag("-Wall")
check_and_add_cxx_flag("-Wextra")
check_and_add_cxx_flag("-Wpedantic")
endif()
endif()

Expand Down
2 changes: 1 addition & 1 deletion doc/intro.markdown
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ RMVL 起源于 SRVL(SCUT Robotlab Vision Library——华南理工大学机器
- **2.x** —— *2022.01* 发布<span style="color: green">(未开源)</span>,使用抽象工厂设计模式后出现了维护困难的情况,包括但不限于多个 @ref function_modules 共同组合,导致产生非常多的派生工厂,此版本针对这一弊端移除了原先所有的设计模式,各功能模块仅单独存在,不再另外设置组合或其他强依赖关系。此外, **2.x** 相较于 **1.x** 添加了全新的内容: @ref group 。
- **3.x** —— *2022.08* 发布<span style="color: green">(未开源)</span>,架构、功能进一步完善。在开发上,添加了 CI-CD 自动化构建测试工具,使用 GoogleTest 为已有的组件、模块添加了单元测试,使用 benchmark 为部分功能添加了性能基准测试;在功能上,移除原先所有的 `group` 组件,重定义并完善了 `group` 组件所应当具备的功能,后续在此系列代码基础上,完成了 **RM2023 版整车状态估计** ;在使用上,顶层模块与视觉库完全分离,涉及到各个功能开启或关闭的逻辑功能将设置在顶层模块,这一部分内容由用户自行实现。此外,该版本完善了 CMake 的项目构建方式,并且可通过 `make install/uninstall` 完成编译安装、卸载。
- **4.x** —— *2023.09* 发布<span style="color: green">(已开源)</span>,并登陆 [Github](https://github.com) 平台,更名 RMVL 以追求更加广泛的使用场景。并发布了 **RMVL 1.x** 系列版本,该系列彻底形成了面向对象迭代器设计模式与责任链设计模式相互结合的代码架构。 **4.x** 版本在设计之初主要为了简化数据组件的开发,移除了不属于 @ref data_components 管理的,但在 @ref function_modules 中被设置的信息。此外还为各个 @ref function_modules 加入了 `XxxInfo` 的信息类。该版本首次加入命名空间 `rm`,避免了与其他库命名冲突的情况。此外,该版本极大程度简化并统一了参数模块的定义方式,将原先繁琐的参数定义、加载的功能使用自定义的参数文件 `*.para` 以及一组 CMake 函数 `rmvl_generate_para` 自动完成 C++ 代码生成与文档注解生成,为了更进一步简化参数模块的设计,RMVL 提供了 Visual Studio Code 的插件,为 `*.para` 文件提供语法高亮、代码提示、悬浮提示与代码块,并为 RMVL 中的部分函数与宏提供了代码提示、悬浮提示与代码块。
- **RMVL 2.x** —— *2024.09* 发布<span style="color: green">(已开源)</span>,在功能上,该系列首次加入了 Python 支持,可参考 @ref tutorials_python ,此外还为 Windows 用户提供了 MSVC 编译器的支持。在架构上,新增 @ref algorithm ,将原先 @ref core 中的各类算法迁移至该模块。
- **RMVL 2.x** —— *2024.09* 发布<span style="color: green">(已开源)</span>,在功能上,该系列首次加入了 Python 支持,可参考 @ref tutorials_python ,此外还为 Windows 用户提供了 MSVC 编译器的支持,使用 CPack 工具,为 Windows,以及 Debian 系 Linux 发行版制作安装包。在架构上,新增 @ref algorithm ,将原先 @ref core 中的各类算法迁移至该模块。

#### 使用对象与基本情况

Expand Down
9 changes: 5 additions & 4 deletions doc/tools/pyrmvl_fns.cfg
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,8 @@ rm calculateRelativeCenter m,angle center
rm cameraConvertToPixel m,coeffs,p3d pixel

#################################### camera ####################################
rm::HikCamera HikCamera init_mode[,serial] [[con]]
rm::HikCamera HikCamera cfg[,info] [[con]]
rm::HikCamera version "" [[version_string]]
rm::HikCamera set propId[,value] [[success_?]]
rm::HikCamera get propId value
rm::HikCamera isOpened "" [[opened_?]]
Expand All @@ -79,7 +80,7 @@ rm::OptCamera get propId value
rm::OptCamera isOpened "" [[opened_?]]
rm::OptCamera read "" res,img
rm::OptCamera reconnect "" [[success_?]]
rm::GalaxyCamera GalaxyCamera init_mode[,serial] [[con]]
rm::GalaxyCamera GalaxyCamera cfg[,id] [[con]]
rm::GalaxyCamera set propId[,value] [[success_?]]
rm::GalaxyCamera get propId value
rm::GalaxyCamera isOpened "" [[opened_?]]
Expand All @@ -96,7 +97,7 @@ rm::OPTLightController close "" [[Success_?]]
rm::OPTLightController getIntensity chn intensity
rm::OPTLightController setIntensity chn,val [[Success_?]]
rm::OPTLightController trigger chn,time [[Success_?]]
rm::HikLightController HikLightController cfg,pid,id [[con]]
rm::HikLightController HikLightController cfg,id [[con]]
rm::HikLightController isOpened "" [[opened_?]]
rm::HikLightController open "" [[Success_?]]
rm::HikLightController close "" [[Success_?]]
Expand Down Expand Up @@ -170,7 +171,7 @@ rm::Server shutdown ""
rm::Server addVariableTypeNode vtype nd
rm::Server addVariableNode val[,parent_nd] nd
rm::Server addVariableNodeValueCallback nd,before_read,after_write [[success_?]]
rm::Server addDataSourceVariableNode val,on_read,on_write[,parent_nd] nd
rm::Server addDataSourceVariableNode val[,parent_nd] nd
rm::Server read node val
rm::Server write node,val [[success_?]]
rm::Server addMethodNode method[,parent_nd] nd
Expand Down
2 changes: 1 addition & 1 deletion doc/tutorials/modules/algorithm/fminunc.md
Original file line number Diff line number Diff line change
Expand Up @@ -118,7 +118,7 @@ auto [x, fval] = rm::fminunc(quadratic, {0, 0});
```cpp
#include <cstdio>

#include <rmvl/numcal.hpp>
#include <rmvl/algorithm/numcal.hpp>

int main()
{
Expand Down
6 changes: 3 additions & 3 deletions modules/core/include/rmvl/core/version.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -13,9 +13,9 @@
#include "rmvldef.hpp"

#define RMVL_VERSION_MAJOR 2
#define RMVL_VERSION_MINOR 1
#define RMVL_VERSION_PATCH 1
#define RMVL_VERSION_STATUS ""
#define RMVL_VERSION_MINOR 2
#define RMVL_VERSION_PATCH 0
#define RMVL_VERSION_STATUS "-dev"

#define RMVLAUX_STR_EXP(__A) #__A
#define RMVLAUX_STR(__A) RMVLAUX_STR_EXP(__A)
Expand Down
2 changes: 0 additions & 2 deletions modules/opcua/include/rmvl/opcua/method.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,6 @@

#pragma once

#include <functional>

#include "variable.hpp"

namespace rm
Expand Down
31 changes: 3 additions & 28 deletions modules/opcua/include/rmvl/opcua/server.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -124,24 +124,6 @@ using ValueCallbackBeforeRead = std::function<void(ServerView, const NodeId &, c
*/
using ValueCallbackAfterWrite = std::function<void(ServerView, const NodeId &, const Variable &)>;

/**
* @brief 数据源回调函数,Read 函数指针定义
*
* @param[in] server_view OPC UA 服务器视图,指代当前服务器
* @param[in] nodeid 待读取的变量节点的 `NodeId`
* @return 向服务器提供的待读取的变量
*/
using DataSourceRead = std::function<Variable(ServerView, const NodeId &)>;

/**
* @brief 数据源回调函数,Write 函数指针定义
*
* @param[in] server_view OPC UA 服务器视图,指代当前服务器
* @param[in] nodeid 待写入的变量节点的 `NodeId`
* @param[in] value 从服务器接收到的变量,一般用于写入外部数据
*/
using DataSourceWrite = std::function<void(ServerView, const NodeId &, const Variable &)>;

//! OPC UA 服务器
class RMVL_EXPORTS_W Server
{
Expand Down Expand Up @@ -269,20 +251,13 @@ class RMVL_EXPORTS_W Server

/**
* @brief 添加数据源变量节点 VariableNode 至指定父节点中
* @brief 数据源变量节点不同于变量节点的值回调
* @brief
* - 值回调是在现有变量节点之上添加读取 **前** 和写入 **后** 的回调函数,本质上仍然是从服务器中获取数据
* @brief
* - 数据源变量节点会把每次 IO 都绑定到各自的回调函数中,即可以重定向到一个实际的物理过程中,从而跟服务器本身的数据读写脱离关系
* @see DataSourceVariable
*
* @param[in] val `rm::Variable` 表示的变量,仅取 `browse_name`、`description`、`display_name`、`access_level`
* 以及 `ns` 字段,以及对应的变量类型节点
* @param[in] on_read 重定向的读取回调函数
* @param[in] on_write 重定向的写入回调函数
* @param[in] val `rm::DataSourceVariable` 表示的数据源变量
* @param[in] parent_nd 指定父节点的 `NodeId`,默认为 `rm::nodeObjectsFolder`
* @return 添加至服务器后,对应数据源变量节点的唯一标识 `NodeId`
*/
RMVL_W NodeId addDataSourceVariableNode(const Variable &val, DataSourceRead on_read, DataSourceWrite on_write, NodeId parent_nd = nodeObjectsFolder) noexcept;
RMVL_W NodeId addDataSourceVariableNode(const DataSourceVariable &val, NodeId parent_nd = nodeObjectsFolder) noexcept;

/**
* @brief 从指定的变量节点读数据
Expand Down
2 changes: 2 additions & 0 deletions modules/opcua/include/rmvl/opcua/utilities.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,8 @@ namespace rm
UA_OPEN62541_VER_MINOR * 100 + \
UA_OPEN62541_VER_PATCH

static_assert(OPCUA_VERSION >= 10400, "The version of open62541 must be greater than or equal to 1.4.0");

//! @addtogroup opcua
//! @{

Expand Down
71 changes: 70 additions & 1 deletion modules/opcua/include/rmvl/opcua/variable.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
#pragma once

#include <any>
#include <functional>
#include <memory>
#include <utility>

Expand Down Expand Up @@ -299,9 +300,77 @@ class RMVL_EXPORTS_W Variable final
rm::Variable val{__VA_ARGS__}; \
val.browse_name = val.display_name = val.description = #val

//! 变量列表
//! 变量列表别名
using Variables = std::vector<Variable>;

/**
* @brief 数据源回调函数,Read 函数指针定义
*
* @param[in] nodeid 待读取的变量节点的 `NodeId`
* @return 向服务器提供的待读取的变量
*/
using DataSourceRead = std::function<Variable(const NodeId &)>;

/**
* @brief 数据源回调函数,Write 函数指针定义
*
* @param[in] nodeid 待写入的变量节点的 `NodeId`
* @param[in] value 从服务器接收到的变量,一般用于写入外部数据
*/
using DataSourceWrite = std::function<void(const NodeId &, const Variable &)>;

/**
* @brief OPC UA 数据源变量
* @note 数据源变量节点不同于变量节点的值回调
* @note
* - 值回调是在现有变量节点之上添加读取 **前** 和写入 **后** 的回调函数,本质上仍然是从服务器中获取数据
* @note
* - 数据源变量节点会把每次 IO 都绑定到各自的回调函数中,即可以重定向到一个实际的物理过程中,从而跟服务器本身的数据读写脱离关系
*/
struct RMVL_EXPORTS_W_AG DataSourceVariable
{
//! 命名空间索引,默认为 `1`
RMVL_W_RW uint16_t ns{1U};

/**
* @brief 浏览名称 BrowseName
* @brief
* - 属于非服务器层面的 ID 号,可用于完成路径搜索
* @brief
* - 同一个命名空间 `ns` 下该名称不能重复
*/
RMVL_W_RW std::string browse_name{};

/**
* @brief 展示名称 DisplayName
* @brief
* - 在服务器上对外展示的名字 - `en-US`
* @brief
* - 同一个命名空间 `ns` 下该名称可以相同
*/
RMVL_W_RW std::string display_name{};
//! 变量的描述
RMVL_W_RW std::string description{};
//! 访问性
RMVL_W_RW uint8_t access_level{};

/**
* @brief 数据源 Read 回调函数
*
* @param[in] nd `const rm::NodeId &` 类型节点 ID
* @return `rm::Variable`
*/
RMVL_W_RW DataSourceRead on_read{};

/**
* @brief 数据源 Write 回调函数
*
* @param[in] nd `const rm::NodeId &` 类型节点 ID
* @param[in] value `const rm::Variable &` 类型变量
*/
RMVL_W_RW DataSourceWrite on_write{};
};

//! @} opcua

} // namespace rm
4 changes: 0 additions & 4 deletions modules/opcua/src/client.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -37,11 +37,7 @@ Client::Client(std::string_view address, const UserConfig &usr)
{
UA_ClientConfig init_config{};
// 修改日志
#if OPCUA_VERSION < 10400
init_config.logger = UA_Log_Stdout_withLevel(loglvl_cli.at(para::opcua_param.CLIENT_LOGLEVEL));
#else
init_config.logging = UA_Log_Stdout_new(loglvl_cli.at(para::opcua_param.CLIENT_LOGLEVEL));
#endif
// 设置默认配置
auto status = UA_ClientConfig_setDefault(&init_config);
if (status != UA_STATUSCODE_GOOD)
Expand Down
11 changes: 0 additions & 11 deletions modules/opcua/src/publisher.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,6 @@
#ifdef UA_ENABLE_PUBSUB

#include <open62541/plugin/log_stdout.h>
#if OPCUA_VERSION < 10400
#include <open62541/plugin/pubsub_udp.h>
#endif
#include <open62541/server_config_default.h>

#ifdef UA_ENABLE_PUBSUB_MQTT
Expand All @@ -38,9 +35,6 @@ Publisher::Publisher(std::string_view pub_name, const std::string &addr, uint16_
const std::vector<UserConfig> &users) : Server(port, pub_name, users), _name(pub_name)
{
//////////////////// 添加连接配置 ////////////////////
#if OPCUA_VERSION < 10400
UA_ServerConfig_addPubSubTransportLayer(UA_Server_getConfig(_server), UA_PubSubTransportLayerUDPMP());
#endif
UA_PubSubConnectionConfig connect_config{};
std::string cn_name_str = _name + "Connection";
connect_config.name = UA_STRING(helper::to_char(cn_name_str));
Expand All @@ -50,13 +44,8 @@ Publisher::Publisher(std::string_view pub_name, const std::string &addr, uint16_
UA_NetworkAddressUrlDataType address_url{UA_STRING_NULL, UA_STRING(helper::to_char(url_str))};
UA_Variant_setScalar(&connect_config.address, &address_url, &UA_TYPES[UA_TYPES_NETWORKADDRESSURLDATATYPE]);
// 用哈希值作为发布者 ID
#if OPCUA_VERSION >= 10400
connect_config.publisherIdType = UA_PUBLISHERIDTYPE_UINT16;
connect_config.publisherId.uint16 = _strhash(_name + "Connection") % 0x4000u;
#else
connect_config.publisherIdType = UA_PUBSUB_PUBLISHERID_NUMERIC;
connect_config.publisherId.numeric = _strhash(_name + "Connection") % 0x4000u;
#endif
auto status = UA_Server_addPubSubConnection(_server, &connect_config, &_connection_id);
if (status != UA_STATUSCODE_GOOD)
{
Expand Down
Loading

0 comments on commit 1184180

Please sign in to comment.