一种动态联动的实现方法

安防领域中的联动规则

有安防领域相关的开发经历的人知道,IPCamera可以配置使能“侦测”功能,并且指定仅针对图像传感器的某个区载进行侦测。除了基本的“移动侦测"外,侦测的功能点还有细化的类别,如人员侦测、车辆侦测、烟雾侦测等。这些侦测配置后若被触发,会在IPCamera内部产生一些事件;这事件发生时,IPC内部会有相应的动作,例如:邮件报告、图片上传、视频上传等;还可以配置IPC蜂鸣器报警、外置LED灯闪烁等(若有相应的硬件外设)。在IPC的Web界面,用户可以方便地配置这些选项:

IPCamera动态联动配置

如何实现这一功能呢?笔者咨询过相关在安防产业工作的朋友,得到的方案有两种:

  • IPC内部产生的事件种类是固定的,能够做出动作也是有限的,那么直接使用C/C++编码实现这些逻辑;
  • 将事件与动作分别独立为应用中的子模块,使用“胶水”语言Lua将二者联动起来;

朋友也坦言,第一种方案在代码库中存在很久了,代码逻辑错踪复杂;尤其是一些定制类的IPCamera项目,需求不同会造成开发人员花费不少的时间在动态联动的代码修改上。而第二种方案,虽然在项目开发上可以缩短时间,但只有少部分项目中有,接口也不一样,帮助不大:第一种方案仍是团队内部项目开发的主要方法。

动态联动的问题抽象

本文中,笔者将此类动态联动的问题抽象化,并提供上面提到的第二种方法的演示实现。假设IPCamera内部的图像处理会产生五个维度的状态量,名称分别为:
ex_var1/ex_var2/ex_var3/ex_var4/ex_var5

这五个状态量,与三个联动规则相关(即事件,当判定条件为真时会触发);也可能会产生另外三个联动规则不为真时的动作。也就是说,三个联动规则需要这五个变量来决定是否为真。笔者将这些信息写入到配置文件中由演示应用读取:

{"linked-vars": {"ex_var1": 1,"ex_var2": 2,"ex_var3": 3,"ex_var4": 4.2,"ex_var5": 5},"linked-action": [{"rule": "(ex_var1 + ex_var2 * 2 + ex_var3 * 3) > 14","true": "echo 'The planet Earth is freaking too hot'","false": "echo 'The planet Earth is freaking too cold'"},{"rule": "math.floor(ex_var4 * 5 / 4) > ex_var5","true": "echo 'Note that floor(ex_var4 * 5 / 4) > ex_var5'","false": "echo 'Note that floor(ex_var4 * 5 / 4) <= ex_var5'"},{"rule": "(ex_var1 + ex_var2 + ex_var3 + ex_var4 + ex_var4) >= 16","true": "echo 'All example values summed up greater or equal to 16.'","false": "echo 'All example values summed up less than 16'"}]
}

注意,上面的rule即一个动态联动规则是否判定为真的条件。它是一个Lua语句;这里只一行语句,在具体的实践层面上,可以是多行的计算(这里只支持一个语句)。上面还给出当事件联动为真时要执行的动作,例如,当全球平均温度大于14(度)时,就会触发事件:

echo 'The planet Earth is freaking too hot'

也就是简单地调用/bin/sh输出一行信息。当该条件为假时,则会触发另一个动作(可选)。

动态联动规则的实现

上面的JSON配置文件描述了我们抽象化的动态联动问题。笔者编写的演示例子,会根据上面的信息构造一个Lua脚本,用于计算三个联动规则是否成立:

local ex_var1 = 1
local ex_var3 = 3
local ex_var5 = 5
local ex_var2 = 2
local ex_var4 = 4.2
function rulefunc_1()return (ex_var1 + ex_var2 * 2 + ex_var3 * 3) > 14
end
function rulefunc_2()return math.floor(ex_var4 * 5 / 4) > ex_var5
end
function rulefunc_3()return (ex_var1 + ex_var2 + ex_var3 + ex_var4 + ex_var4) >= 16
end
function rulefunc_all()local link_tval_ = 0link_tval_ = link_tval_ + ex_var1link_tval_ = link_tval_ + ex_var3link_tval_ = link_tval_ + ex_var5link_tval_ = link_tval_ + ex_var2link_tval_ = link_tval_ + ex_var4return link_tval_
end

根据Lua的引用规则说明,五个演示变量都是上面构造的四个函数的上级变量(upvalue)。注意,上面的Lua函数rulefunc_2只引用了两个变量;也就是说,一些联动规则并不需要全部的状态量。当上面的代码编译为Lua字节码后,如何通一个函数的上级变量索引来更新所有的上级变量呢?这正是rulefunc_all函数的用处:它引用了全部五个变量,它的名称是固定的,虽然它不会被调用,但我们可以通过它来更新该构造脚本的全部上级变量。之后,这个脚本会使用luaL_dostring API预编译为一个Lua状态机:

rext_any_t rext_lua_new(const struct rext_var * lvar, int * errp) {...luaL_openlibs(L); /* load standard library */if (script != NULL && script[0] != '\0') {int ret;ret = luaL_dostring(L, script);if (ret != 0) {*errp = EINVAL;lua_close(L);L = NULL;}}

注意到,上面的配置信息给出了五个演示变量的初始值。这些值在判定一个联动规则是否被触发前,需要被更新。笔者采用的方法,正是上面提到的,通过函数rulefunc_all来更新:

int rext_upval_set(rext_any_t anyt, const struct rext_var * rfunc,int upindex, const struct rext_var * rval)
{...ret = rext_pushval(anyt, rval);if (ret < 0) {lua_settop(L, oldtop);return -7;}valp = lua_setupvalue(L, ntop, upindex);if (valp == NULL) {lua_settop(L, oldtop);return -8;}

之后,笔者简单编了5个变量的值,来测试演示动态联动:

    let t_map: HashMap<&str, f64> = HashMap::from([("ex_var1", 1f64),("ex_var2", 2f64),("ex_var3", 3f64),("ex_var4", 4f64),("ex_var5", 5f64),]);linked.act(&t_map);let t_map: HashMap<&str, f64> = HashMap::from([("ex_var1", 2f64),("ex_var2", 3f64),("ex_var3", 4f64),("ex_var4", 5f64),("ex_var5", 6f64),]);linked.act(&t_map);

动态联动的演示代码与结果

笔者提供了联动规则的演示代码,感兴趣的可以从此处获取。它的正常运行需要Ubuntu系统下安装Lua5.1开发库及Rust编译器。以下是代码的下载、编译操作:

sudo apt install lua5.1 liblua5.1-0-dev rust-full bindgen
git clone https://github.com/jaqchen/linked-action.git
cd linked-action ; rm -rf ./rustex/rustex.rs
cargo build --release

笔者运行的结果如下:

Created Lua-state machine: 0x562e74aecfc0
Inserting ex_var5 => 1
Inserting ex_var4 => 2
Inserting ex_var3 => 3
Inserting ex_var1 => 4
Inserting ex_var2 => 5
Lua upvalues found: 5
The planet Earth is freaking too cold
false: 0 => (ex_var1 + ex_var2 * 2 + ex_var3 * 3) > 14
Note that floor(ex_var4 * 5 / 4) <= ex_var5
false: 0 => math.floor(ex_var4 * 5 / 4) > ex_var5
All example values summed up less than 16
false: 0 => (ex_var1 + ex_var2 + ex_var3 + ex_var4 + ex_var4) >= 16The planet Earth is freaking too hot
true : 0 => (ex_var1 + ex_var2 * 2 + ex_var3 * 3) > 14
Note that floor(ex_var4 * 5 / 4) <= ex_var5
false: 0 => math.floor(ex_var4 * 5 / 4) > ex_var5
All example values summed up greater or equal to 16.
true : 0 => (ex_var1 + ex_var2 + ex_var3 + ex_var4 + ex_var4) >= 16

至此,我们就可以避免使用C/C++实现复杂的联动规则是否为真的判断逻辑了。这不仅仅是提高了开发效率,而且还避免过多的编码可能会引入的缺陷。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/279178.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Springboot+Redis:实现缓存 减少对数据库的压力

&#x1f389;&#x1f389;欢迎光临&#xff0c;终于等到你啦&#x1f389;&#x1f389; &#x1f3c5;我是苏泽&#xff0c;一位对技术充满热情的探索者和分享者。&#x1f680;&#x1f680; &#x1f31f;持续更新的专栏Redis实战与进阶 本专栏讲解Redis从原理到实践 …

nmcli --help(nmcli -h)nmcli文档、nmcli手册

文章目录 nmcli --helpOPTION解释OBJECT解释1. g[eneral]&#xff1a;查看NetworkManager的状态2. n[etworking]&#xff1a;启用或禁用网络3. r[adio]&#xff1a;查看无线电状态&#xff08;例如&#xff0c;Wi-Fi&#xff09;4. c[onnection]&#xff1a;列出所有的网络连接…

【Linux】进程优先级

&#x1f30e;进程的优先级 文章目录&#xff1a; 进程状态 优先级相关       什么是优先级       为什么要有优先级       进程的优先级 调整进程优先级       调整优先级       优先级极限测试 Linux的调度与切换 总结 前言&#xff1a; 进程…

Apache Doris 2.1 核心特性 Variant 数据类型技术深度解析

在最新发布的 Apache Doris 2.1 新版本中&#xff0c;我们引入了全新的数据类型 Variant&#xff0c;对半结构化数据分析能力进行了全面增强。无需提前在表结构中定义具体的列&#xff0c;彻底改变了 Doris 过去基于 String、JSONB 等行存类型的存储和查询方式。为了让大家快速…

MATLAB图形绘制

一&#xff0c;二维图像绘制 最基础的二维图形绘制方法&#xff1a;plot -plot命令自动打开一个图形窗口Figure;用直线连接相邻两数据点来绘制图形 -根据图形坐标大小自动缩扩坐标轴&#xff0c;将数据标尺及单位标注自动加到两个坐标轴上&#xff0c;可自定坐标 轴&#x…

group by和min、max函数一起使用

原始数据 查询每科的最高分数 -- 查询每科最高分数 select stuId,classId,stuName,max(score) from student_score group by classId 错误的结果 这个显然不是对的&#xff0c;或者说不是我们想要的结果&#xff0c; 我们想要的结果是 原因是什么呢&#xff1f;我们知道使用…

AtomoVideo:AIGC赋能下的电商视频动效生成

✍&#x1f3fb; 本文作者&#xff1a;凌潼、依竹、桅桔、逾溪 1. 概述 当今电商领域&#xff0c;内容营销的形式正日趋多样化&#xff0c;视频内容以其生动鲜明的视觉体验和迅捷高效的信息传播能力&#xff0c;为商家创造了新的机遇。消费者对视频内容的偏好驱动了视频创意供给…

我的自建博客之旅04之Halo

我的自建博客之旅04之Halo Halo是我无意间发现的一款博客框架,如果你讨厌Hexo,Vuepress等静态框架本地编辑,构建部署等方式,如果你想要一款一次搭建,前台是博客,后台是文章维护,并且支持各种定制化折腾的博客框架,可能Halo会比较适合你。 因为我个人还是比较偏技术,…

C语言 扫雷游戏

写了这么长时间的关于C语言的基础知识&#xff0c;相信大家已经学会了使用C语言书写一些基础的代码&#xff0c;上次还编写了三子棋游戏的代码&#xff0c;这次我将编写一个基础版的扫雷游戏。 首先&#xff0c;创建三个文件&#xff0c;两个源文件&#xff0c;一个头文件&…

【C++】用红黑树模拟实现set、map

目录 前言及准备&#xff1a;一、红黑树接口1.1 begin1.2 end1.3 查找1.4 插入1.5 左单旋和右单旋 二、树形迭代器&#xff08;正向&#xff09;2.1 前置 三、模拟实现set四、模拟实现map 前言及准备&#xff1a; set、map的底层结构是红黑树&#xff0c;它们的函数通过调用红…

微信小程序小白易入门基础教程1

微信小程序 基本结构 页面配置 页面配置 app.json 中的部分配置&#xff0c;也支持对单个页面进行配置&#xff0c;可以在页面对应的 .json 文件来对本页面的表现进行配置。 页面中配置项在当前页面会覆盖 app.json 中相同的配置项&#xff08;样式相关的配置项属于 app.js…

android 怎么自定义view

首先了解view的绘制流程: 所以onmeasure ---测量view onlayout---确定view大小----》所以继承ViewGroup必须要重写onlayout,确定子view 而onDraw----是继承view时候需要操作的。 所以:自定义ViewGroup一般是利用现有的组件根据特定的布局方式来组成新的组件。 自定义Vi…

一个可商用私有化部署的基于JAVA的chat-gpt网站

目录 介绍一、核心功能1、智能对话2、AI绘画3、知识库4、一键思维导图5、应用广场6、GPTS 二、后台管理功能1、网站自定义2、多账号登录支持3、商品及会员系统4、模型配置5、兑换码生成6、三方商户用户打通 结语 介绍 java语言的私有化部署的商用网站还是比较少的 这里给大家介…

第 126 场 LeetCode 双周赛题解

A 求出加密整数的和 模拟 class Solution { public:int sumOfEncryptedInt(vector<int> &nums) {int res 0;for (auto x: nums) {string s to_string(x);char ch *max_element(s.begin(), s.end());for (auto &c: s)c ch;res stoi(s);}return res;} };B 执行…

【研发日记】Matlab/Simulink技能解锁(五)——Simulink布线技巧

前言 见《【研发日记】Matlab/Simulink技能解锁(一)——在Simulink编辑窗口Debug》 见《【研发日记】Matlab/Simulink技能解锁(二)——在Function编辑窗口Debug》 见《【研发日记】Matlab/Simulink技能解锁(三)——在Stateflow编辑窗口Debug》 见《【研发日记】Matlab/Simulink…

C++作业day6

编程1&#xff1a; 封装一个动物的基类&#xff0c;类中有私有成员&#xff1a;姓名&#xff0c;颜色&#xff0c;指针成员年纪 再封装一个狗这样类&#xff0c;共有继承于动物类&#xff0c;自己拓展的私有成员有&#xff1a;指针成员&#xff1a;腿的个数&#xff08;整型 …

六种GPU虚拟化:除了直通、全虚拟化 (vGPU)还有谁?

在大类上计算虚拟化技术有这3种&#xff1a; 软件模拟、直通独占(如网卡独占、显卡独占)、直通共享&#xff08;如vCPU 、vGPU&#xff09;。但对于显卡GPU而言我总结细化出至少这6种分类&#xff1a; 第一种、软件模拟&#xff08;eg sGPU&#xff09;, 又叫半虚拟化。第二种…

[论文笔记] Gradient Surgery for Multi-Task Learning

【强化学习 137】PCGrad - 知乎 多任务学习(multi task):任务权重、loss均衡、梯度下降那点事 - 知乎 ICLR 2020 rejected submission:Yu T, Kumar S, Gupta A, et al. Gradient surgery for multi-task learning[J]. arXiv preprint arXiv:2001.06782, 2020. mul…

yocto编译测试

源码下载 git clone -b gatesgarth git://git.yoctoproject.org/poky lkmaolkmao-virtual-machine:~/yocto$ git clone -b gatesgarth git://git.yoctoproject.org/poky Cloning into poky... remote: Enumerating objects: 640690, done. remote: Counting objects: 100% (13…

Java的图书管理系统,确实有两把斧子 ! ! !

本篇会加入个人的所谓‘鱼式疯言’ ❤️❤️❤️鱼式疯言:❤️❤️❤️此疯言非彼疯言 而是理解过并总结出来通俗易懂的大白话, 小编会尽可能的在每个概念后插入鱼式疯言,帮助大家理解的. &#x1f92d;&#x1f92d;&#x1f92d;可能说的不是那么严谨.但小编初心是能让更多人…