从零开始 使用OMNET++结合VEINS,INET和SUMO的联合仿真

背景知识

当我们探索未来的交通系统和智能交通解决方案时,车辆到一切(Vehicle-to-Everything, V2X)通信技术显得尤为重要。V2X是指在车辆与车辆(V2V)、车辆与基础设施(V2I)、车辆与行人(V2P)以及车辆与网络(V2N)之间进行的通信。这种技术能够提高道路安全,优化交通流量,减少拥堵,提升驾驶体验,并为自动驾驶汽车的实现打下基础。

为了准确模拟和分析V2X通信中的复杂交互,需要使用一些专用的仿真工具:

  1. OMNeT++ 是一个公开源码的网络仿真框架,提供了广泛的工具集和功能,用于构建复杂的网络和其他分布式系统。OMNeT++的灵活性和模块化使其成为研究和模拟通信网络,特别是V2X通信网络的理想选择。

  2. INET 是OMNeT++的一个扩展模型库,专注于互联网协议和网络技术的仿真。INET提供了大量的网络协议模型,如TCP/IP、路由协议等,允许研究者构建和测试各种网络架构和服务。

  3. SUMO (Simulation of Urban MObility) 是一个开源的交通仿真软件,用于模拟城市的车辆流动。通过SUMO,研究人员可以创建详细的城市交通场景,包括道路网络、交通信号灯、车辆行为等,来分析不同交通策略和管理措施的效果。

  4. VEINS 是一个允许OMNeT++和SUMO之间进行联合仿真的框架,专门用于车辆通信系统的研究。它使得OMNeT++模拟的通信网络和SUMO模拟的移动车辆能够实时交互,从而实现对V2X通信场景的全面仿真。

使用OMNeT++结合VEINS、INET和SUMO进行联合仿真,能够在复杂的城市交通环境中准确模拟V2X通信。这种仿真可以帮助研究者评估V2X技术在实际应用中的表现,如通信延迟、系统可靠性和安全性等。此外,仿真结果还可以指导政策制定者和工程师设计更有效的交通管理策略和智能交通系统,推动智能交通技术的发展,为实现无缝、安全和高效的未来交通网络提供支持。

在这篇博文中,我将尝试:

  • 搭建仿真的环境,导入VEINS和INET开源库
  • 使用INET库中提供的网络协议和功能模型来模拟通信协议和网络功能
  • 使用SUMO创建道路网络和车辆轨迹,并导出到OMNeT++中
  • 在OMNeT++中使用VEINS通过socket和SUMO连接,借助VEINS实现的TRACI接口来设置车辆相关的行为和场景
  • 在OMNET++中结合VEINS,SUMO和INET运行联合仿真实验,并分析车辆在遇到紧急情况下的通信状况和具体行为

环境搭建

OMNet++ / Veins / INET / SUMO下载

关于这四个软件的下载安装,以下两篇博文是很好的参考:

https://www.cnblogs.com/Xylona/p/17779621.html

(veins5.0+sumo1.2.0+OMNeT++5.5.1)车载自组织网络仿真环境安装配置教程(一步一步)_sumo1.3.0+veins5.2+omnet++5.5.1-CSDN博客

 我最终使用的版本:

  • OMNeT++ 5.6.2
  • Veins 5.2
  • SUMO 1.10.0
  • INET 4.2.5

环境配置

  • 修改configure.user:

在分别下载好这四个版本的软件后,进入OMNet++文件夹,打开configure.user,修改PREFER_CLANG的值为no

  • sumo环境变量配置:

共配置四条:

  • 解压&编译OMNET++:

打开OMNet++中的“mingwenv.cmd”,并按下任意键开始解压;

解压完成后分别输入“./configure”和“make”进行编译,make的时间大概要一个小时

  • 打开OMNETT++:

在“mingwenv.cmd”中输入“omnetpp”打开IDE界面

  • 导入VEINS & INET:

点击左上角File -> Import:

导入inet和veins:

注意!对于veins要勾选search for nested projects!!

  • 点击左上角Project -> Build All
  • 运行INET的示例仿真:

点击inet -> examples -> aodv ->  omnetpp.ini,然后右键Run as Omnet ++ simulation就可以看到示例仿真:

  •  运行VEINS的示例仿真:

在“mingwenv.cmd”中输入以下指令使veins连接上sumo:

C:/Users/Majiaming/Desktop/WESTERN/9038_wireless_comm/project/project_new/veins-veins-5.2/bin/veins_launchd -vv -c C:/Users/Majiaming/Desktop/WESTERN/9038_wireless_comm/project/project_new/sumo-1.10.0/bin/sumo.exe

点击左侧veins -> examples -> veins -> omnetpp.ini,然后右键Run as Omnet ++ simulation就可以看到示例仿真:

点击Run后:


现在,成功完成了环境搭建,接下来就要开始创建一个属于我的项目

关于接下来的大体步骤,我参考了以下油管的视频,但是如果仿真软件的版本和我相差不大,建议参考我的版本,因为我按照我下载的这一套VEINS,SUMO,INET,OMNET++版本完全按照视频操作会出现一些问题,所以建议有什么不会再去参考油管的视频:

How to Create a New OMNET++ Project That Works with INET and Veins (youtube.com)

How to Simulate a V2V Network using OMNET++, INET, and Veins - YouTube

How to Add A Custom Sumo Simulation to OMNET++ (youtube.com)


创建工程

  • 左上角file -> new -> OMNET++ project创建project:

  • 右击新建的project -> Properties -> Project References,链接INET和VEINS和veins_inet

  • 别关掉上面的窗口,按照以下步骤完善make规则:

 


现在,这个新的project已经成功的refer到了veins 和 inet,但是,问题来了,如何才能将二者结合起来?答案是:veins中提供了一个sub-project,名字是veins_inet,其中提供了大量现成的cc代码和一个简单的示例,这个sub-project提供了一个将二者结合的很好例子,这也是为什么刚刚import veins的时候要同时Import veins_inet这个子项目!


 

VEINS & INET 的结合

  • 将veins_inet的仿真例程迁移到我新创建的project:

找到刚刚import的veins_inet子项目, 找到 examples -> veins_inet 拷贝到新项目的simulation下:

出现了大量的红色叉叉,这是因为.ned文件中的package的名字不正确

② 修改.ned文件中的package name:

//在所有.ned文件中:(其实就两个)
//将开头的 
package XXXXXXX.veins_inet;
//修改为 
package _9038_project.simulations.veins_inet;

可以通过运行当前路径下的omnetpp.ini来测试是否成功:

由于此处包含veins,别忘了在OMNETT++根目录下的mingwenv.cmd中输入以下代码连接SUMO:

C:/Users/Majiaming/Desktop/WESTERN/9038_wireless_comm/project/project_new/veins-veins-5.2/bin/veins_launchd -vv -c C:/Users/Majiaming/Desktop/WESTERN/9038_wireless_comm/project/project_new/sumo-1.10.0/bin/sumo.exe

 

可见,成功在自己创建的项目中运行了veins_inet的例程仿真! 


现在,已经可以成功的在自己创建的project里运行结合veins_inet例子下的仿真,但是例子中的sumo地图并不是我想要的,下一步是根据自己的地图,实现veins,inet,sumo的联合仿真


VEINS & INET & SUMO 的联合仿真

  • 创建自己的仿真路径

在新建项目的simulations下再创建一个“my_veins_inet”的文件夹,把刚刚“veins_inet”的内容全部复制进来:

       (同样,记得修改两个.ned文件中的package名,此处不再展开!)

然后,将square.net.xml; square.poly.xml; square.rou.xml; obstacles.xml删除,剩下的留着待会修改

  • 自定义sumo地图导入:

此处我选择了留学所在城市的一家costco附近的地图

网站:https://www.openstreetmap.org/export#map=16/42.9852/-81.2900

选定区域后点击左侧的“Export”导出.osm文件

通过python脚本分别生成.net.xml;.rou.xml;.poly.xml:

请根据文件位置修改文件路径!

import numpy as np
import subprocess

#生成map.net.xml

# 设置你的.osm文件路径
osm_file_path = 'costco.osm' #根据https://www.openstreetmap.org 网站导出的

# 设置输出文件路径
output_file_path = 'costco.net.xml'

# 构建netconvert命令
netconvert_command = f'netconvert --osm-files {osm_file_path} -o {output_file_path}'

# 调用命令
subprocess.run(netconvert_command, shell=True)
print(".net.xml成功生成")

#生成map.poly.xml

osm_file_path = 'costco.osm' #根据https://www.openstreetmap.org 网站导出的
type_file_path = 'typemap.xml' #内容根据CSDN收藏

# 设置输出文件路径
output_file_path = 'costco.poly.xml'

# 构建netconvert命令
netconvert_command = f'polyconvert --net-file costco.net.xml --osm-files {osm_file_path} --type-file {type_file_path} -o {output_file_path}'

# 调用命令
subprocess.run(netconvert_command, shell=True)
print(".poly.xml成功生成")

# 生成map.rou.xml

# 设置SUMO环境变量(请根据你的SUMO安装路径进行调整)
sumo_tools_dir = "C:/Users/Majiaming/Desktop/WESTERN/9038_wireless_comm/project/project_new/sumo-1.10.0/tools"
sumo_network_file = "costco.net.xml"
output_route_file = "costco.rou.xml"

# 构建randomTrips.py脚本的完整命令
command = [
    "python",
    f"{sumo_tools_dir}/randomTrips.py",
    "-n", sumo_network_file,
    "-e", "100",
    "-l",
]

# 使用subprocess运行命令
result = subprocess.run(command, capture_output=True, text=True)

# 检查命令输出(可选)
if result.returncode == 0:
    print("执行成功1")
    print(result.stdout)  # 打印标准输出
else:
    print("执行出错1")
    print(result.stderr)  # 打印错误输出

####################################################

# 构建randomTrips.py脚本的完整命令
command = [
    "python",
    f"{sumo_tools_dir}/randomTrips.py",
    "-n", sumo_network_file,
    "-r", output_route_file,
    "-e", "50",
    "-l",
]

# 使用subprocess运行命令
result = subprocess.run(command, capture_output=True, text=True)

# 检查命令输出(可选)
if result.returncode == 0:
    print("执行成功2")
    print(".rou.xml成功生成")
    print(result.stdout)  # 打印标准输出
else:
    print("执行出错2")
    print(result.stderr)  # 打印错误输出

生成后,将这三个文件放到“my_veins_inet”下备用

  • 修改SUMO相关文件:

my_veins_inet”下已经有了sumo相关的各种文件,现在需要根据具体要求修改它们

将square.sumocfg和square.launchd.xml改名为costco.sumocfgcostco.launchd.xml,并根据新的rou, net和poly文件修改内容:

 

修改完成后,可以用sumo gui打开costco.sumocfg查看效果:

修改.rou.xml:

为了让仿真效果尽可能的清晰,将随机生成的50辆车的代码注释掉,并替换成如下的代码:

<routes xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="http://sumo.dlr.de/xsd/routes_file.xsd">
   <vType id="vtype0" accel="2.6" decel="4.5" sigma="0.5" length="4.5" minGap="2.5" maxSpeed="14" color="1,1,0"/>
   <route id="route0" edges="-62088703#4 -62088703#3 -62088703#2 -62088703#1 474843229#0 474843229#1 474843229#2 474843229#3 474843229#4 474843229#5 474843229#6 466961753#1 466961753#2 466961753#3 466961753#4 466961753#5 466961753#6 466961753#7 466961753#8 -466961753#8"/>
   <flow id="flow0" type="vtype0" route="route0" begin="0" period="3" number="5" arrivalPos="0" />
</routes>
  • <vType>元素:
  1. 定义了一种车辆类型vtype0
  2. accel(加速度): 车辆的最大加速度,这里是2.6米/秒²
  3. decel(减速度): 车辆的最大减速度,这里是4.5米/秒²
  4. sigma(驾驶员不确定性): 描述了驾驶员行为的不确定性,这里是0.5,范围从0(完全确定行为)到1(非常不确定的行为)
  5. length(长度): 车辆的长度,这里是4.5米
  6. minGap(最小间隙): 车辆之间的最小间隙,这里是2.5米
  7. maxSpeed(最大速度): 车辆的最大速度,这里是14米/秒
  8. color(颜色): 车辆的颜色,这里定义为黄色(RGB颜色模式中的1,1,0)
  • <route>元素:
  1. 定义了一个路线route0
  2. id属性指定了路线的唯一标识符
  3. edges属性列出了构成该路线的边的序列。边是道路网中的基本元素,代表单向的道路。这里列出的边通过它们的唯一标识符来指定,负号表示逆向行驶
  • <flow>元素:
  1. 定义了一个流量flow0,表示一定数量的车辆将沿指定的路线移动
  2. id属性为流量提供了一个唯一标识
  3. type属性指定了车辆类型,这里引用了之前定义的vtype0
  4. route属性指定了车辆将遵循的路线,这里是route0
  5. begin属性定义了流量开始的时间(秒),这里是从仿真开始的0秒
  6. period属性定义了车辆生成的时间间隔(秒),这里是每3秒生成一次
  7. number属性定义了将被生成的车辆总数,这里是5辆
  8. arrivalPos属性定义了车辆到达目的地的位置,这里是0,通常表示车辆将尝试行驶整个路线

  • 修改.ned & .ini文件:

修改Scenario.ned

修改灰色区域范围大小,以适应新的sumo地图

修改omnetpp.ini

  • 运行仿真文件

右击omnetpp.ini,右击Runs as -> Run Configuration:

设置完成后点击右下角:Apply -> run:

进入页面后选择genreal:

结果展示

最终仿真效果:

  • 根据.rou.xml的设置,node[0]至node[4]五辆车预先定义要走的路线完全一致。
  • 然而,node[0]变红代表了模拟突发事故,事故发生后,车辆之间开始相互通信,得到消息的车辆会变成绿色。
  • node[3]和node[4]由于具备调头条件,直接掉头,更改了原有的路线并规划了新的路线。
  • node[1]和node[2]由于不具备调头条件只能按照原有路线继续往前,在被node[0]挡住后,根据sumo内部的算法换道并继续前进。

仿真结果简单分析

吞吐量(overall throughput value)

上图显示了4个节点随着时间的吞吐量变化,可以明显的看到,对于这4个节点,吞吐量都在事故发送时开始增加,在0.1秒左右达到最高,并在0.2秒后快速下降,可见通讯速度很快。

 

包发送量(packet sent count)

可见,node0为2次,其他三个节点都为1次,这也很好理解,因为node0是事故发送的节点,所以需要发送一次事故包一次转发包;而其他节点只需要发送一次转发包即可。

思路和代码解读

现在,已经实现OMNET++,SUMO,VEINS和INET的联合仿真,但是背后的原理是什么其实依然一知半解,于是我开始解读代码,尝试理解为什么仿真会这样进行。

注意,以下所有内容都属于自问自答,完全可能有错误,欢迎大家指正,本人纯小白

Q1在最后的仿真路径中,Scenario.ned中的manager,,radio medium,node和physical environmnet分别到底代表什么?在图形界面中拖动他们的位置或改变他们的大小有什么实际的意义?

A

  • manager通常用于仿真管理任务,如控制仿真流程、管理节点间的通信、协调事件等
  • radioMedium定义了无线电传播的模型,如何模拟信号的传播和衰减、如何处理节点间的无线通信等
  • node代表仿真网络中的一个参与者或设备,在车辆网络仿真中,这些节点通常是车辆
  • physicalEnvironment模块定义了仿真的物理环境,包括地形、建筑物等,这些因素可能会影响信号的传播和车辆的移动

在OMNeT++ IDE的图形界面中,拖动这些组件的位置或改变它们的大小主要是为了改善视觉布局,帮助仿真设计者更好地理解和组织仿真场景。这些操作不直接影响仿真逻辑或结果,仿真的逻辑和行为完全由NED文件中的参数定义和配置文件(.ini文件)中的设置决定

Q2根据网络原理,网络协议应该分为5层,应用层,传输层,网络层,链路层,物理层,这些体现在项目的哪里?

A

  • 在这个仿真中,每一个节点(汽车)都被注册为一个名为VeinsInetCar的对象:

  • 而通过跳转VeinsInetCar.nedf会发现,它继承自一个叫AdhocHost的对象:

  • 使用同样的方法不停的跳转,会得出这样一个继承的关系:

  • 而通过分析这些.ned文件,可以总结出以下内容:

  • 所以,每个汽车所代表的VeinsInetCar都是从NodeBase一路继承过来的,而观察继承的路线就可以发现,在一路的继承中,就分别实现了网络协议中5大层的接口定义!

 

Q3根据Q2,有个随之而来的问题:我理解了为什么VeinsInetCar具备了完整的协议栈,网络协议的5大层实现在了哪里。但是我依然不理解:从NodeBase一直继承到了VeinsInetCar,现在已经有了无数的接口用来配置完整的协议,但是使用哪些接口具体配置哪些值,比如在链路层具体配置为无线还是VLAN,网络层具体配置为IPV4还是IPV6,传输层具体配置为TCP还是UDP,这些具体的配置在哪里?

A

答案是:大部分在仿真文件omnetpp.ini中定义:

  • 链路层具体配置:

  • 网络层具体配置:

  •  应用层具体配置:

物理层没有定义很好理解,这都是最底层的设定。

但是,显然会有一个问题,为什么没有传输层的相关定义?到底使用TCP还是UDP还是什么?

chatgpt给出了三种回答:

  1. 默认配置:许多OMNeT++和INET模块,包括传输层协议模块,具有默认配置。例如,如果一个应用需要使用UDP或TCP,并且在其模块定义中正确指定了,那么即使在.ini文件中没有明确配置,这些传输层协议也会被自动实例化并使用默认设置。

  2. 应用层决定:在许多情况下,特别是在使用简单应用(如UdpBasicApp)或其他特定的应用模型时,所使用的传输协议(UDP、TCP等)可能已在应用层模块的实现中明确定义。例如,一些应用模型默认使用UDP进行通信,而无需在.ini文件中进行额外配置。

  3. 模块继承:由于VeinsInetCar继承自AdhocHost,进而继承自StandardHost,一直到NodeBase,这些基础模块可能已经包含了对传输层协议的支持。特别是在AdhocHostStandardHost级别,通常会包括对主要传输层协议(如TCP和UDP)的支持,而无需在每个仿真场景的.ini文件中进行单独配置。

我认为都有一定的道理,根据上面的截图可以知道,应用层是由VeinsInetSampleApplication来实现的,跳转到其对应的.ned文件,可以发现它继承自VeinsInetApplicationBase:

再次跳转,找到这个VeinsInetApplicationBase:

这个代码并没有明确的规定UDP还是TCP,但是根据socket门的注释,应该是使用的UDP。

  • 最后,为了验证,运行仿真并点击一个节点:

可见,虽然链路层出现了循环回路lo,传输层出现了tcp,但是真正实现从上到下沟通的协议还分别是:UDP,IPV4和WLAN

我的推测是:由于没有明确的规定lo和tcp不能使用,所以他们也可能存在,并在某种方面帮助消息传播?

Q4在最后的仿真结果中,汽车的行为是在哪里被定义的?比如,为什么node[0]会在20秒坏掉又在50秒重新启动?

A

这个问题的答案其实已经在仿真结果下的文字中回答一部分了,但是其行为的核心,其实还是在于应用层所定义的这个“VeinsInetSampleApplication”,核心的代码就定义在VeinsInetSampleApplication.cc中(veins_inet->src->veins_inet),以下是代码中最重要的两个函数:

//设置哪个节点什么时候速度为0,什么时候恢复的函数
bool VeinsInetSampleApplication::startApplication()
{
    // host[0] should stop at t=20s
    if (getParentModule()->getIndex() == 0) { //如果节点为0
        auto callback = [this]() { //这个函数在20秒倒计时结束后被运行
            getParentModule()->getDisplayString().setTagArg("i", 1, "red"); //车子变红

            traciVehicle->setSpeed(0); //车子不会立刻停下来,因为仿真软件中定义的物理限制的影响,例如车辆的减速能力,但车子肯定会在20秒后很短时间内停下

            //定义要发送的包的内容
            auto payload = makeShared<VeinsInetSampleMessage>();
            payload->setChunkLength(B(100));
            payload->setRoadId(traciVehicle->getRoadId().c_str());
            timestampPayload(payload);

            //定义包的名字并发送包
            auto packet = createPacket("accident");
            packet->insertAtBack(payload);
            sendPacket(std::move(packet));

            // host should continue after 30s
            auto callback = [this]() { //这个函数在30秒倒计时结束后被运行
                traciVehicle->setSpeed(-1); //车子恢复正常
            };
            timerManager.create(veins::TimerSpecification(callback).oneshotIn(SimTime(30, SIMTIME_S)));//30秒倒计时
        };
        timerManager.create(veins::TimerSpecification(callback).oneshotAt(SimTime(20, SIMTIME_S)));//20秒倒计时
    }

    return true;
}


//规定节点在收到消息之后如何反应的函数
void VeinsInetSampleApplication::processPacket(std::shared_ptr<inet::Packet> pk)
{
    auto payload = pk->peekAtFront<VeinsInetSampleMessage>();

    EV_INFO << "Received packet: " << payload << endl;

    getParentModule()->getDisplayString().setTagArg("i", 1, "green"); //接收到包,车子变绿

    traciVehicle->changeRoute(payload->getRoadId(), 999.9); //重新规划路径

    if (haveForwarded) return; //用于避免重复处理或发送相同的消息

    //如果是第一次收到消息
    auto packet = createPacket("relay"); //创建用于转发的包
    packet->insertAtBack(payload);
    sendPacket(std::move(packet)); //转发

    haveForwarded = true;
}

根据代码可以得出以下的逻辑:

当node[0]停止,即模拟事故发生时,会立刻装载一个大小为100Byte的包,并在其中添加当前所在路的ID,然后向通讯范围内的所有节点(汽车)发送这个包。每个收到这个包的节点(汽车)会立刻从包中获取事故路段的ID,并假设事故路段的通过时间为最大。这就导致所有会经过事故路段且拥有切换路径条件的汽车在收到这个包后会立刻切换路径。同时,向其通信范围的所有节点(汽车)转发一次包的内容。

 

Q5

A

 

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

年薪50w的网络安全工程师是如何炼成的?

前言 一、什么是网络安全 网络安全可以基于攻击和防御视角来分类&#xff0c;我们经常听到的 “红队”、“渗透测试” 等就是研究攻击技术&#xff0c;而“蓝队”、“安全运营”、“安全运维”则研究防御技术。 无论网络、Web、移动、桌面、云等哪个领域&#xff0c;都有攻与防…

“三电”打不过极氪007、比亚迪海豹?我还是选小米SU7 Pro

文 | AUTO芯球 作者 | 雷歌 我真是越来越烦小米汽车的这帮脑残粉了。 小米SU7热闹的发布会过后&#xff0c; 友商们开始在价格上狙击小米SU7。 这两天&#xff0c; 问界M7降价2万&#xff0c;22万多就能提&#xff0c; 极氪001现在送1.6万的选装配置&#xff0c; 银河E…

ChatGPT 上线新功能:DALL·E 可以编辑图片了

ChatGPT 上线新功能&#xff1a;DALLE 可以编辑图片了。可以对生成的图片内容进行修改、添加和删除。 前几天看到消息说还在内测中&#xff0c;今天就体验上了。 这是官方文档&#xff1a;https://help.openai.com/en/articles/9055440-editing-your-images-with-dall-e 界面…

【fastadmin】脚本模式下,日志钩子函数执行出现死循环,导致内存溢出奔溃

问题出现原因是想对项目中error级别的日志&#xff0c;接入钉钉告警&#xff0c;方便查看 于是使用钩子方法&#xff0c;日志写入完成后&#xff0c;自动调用自定义的告警方法中 1、在application/tags.php 中添加log_write_done > [app\\common\\behavior\\Common, ],2、在…

GPTs构建广告文案Agent(只需要一个网址链接即可生成文案及配图)

在大家已经有账号的前提下&#xff0c;我们来看看怎么做&#xff01;&#xff01;&#xff01; 进入GPTs的编辑界面 如下图&#xff1a; 如何配置呢&#xff1f; Name&#xff1a;给我们的GPTs起个名字。Description&#xff1a;简单介绍一下&#xff0c;我们创建的GPTs是…

家用洗地机选购指南,哪款洗地机性价比高且用户评价好?

在当今快节奏的生活中&#xff0c;无论是商业场所还是家庭&#xff0c;清洁环境都是我们追求的目标之一。而一台高性价比的洗地机在频繁清洁地面时尤为重要。市面上的洗地机种类繁多&#xff0c;如何选择适合自己的洗地机成为了一个挑战。那么&#xff0c;到底哪款牌子的洗地机…

隐语SecretFlow实训营-第9讲:隐语多方安全计算在安全核对的行业实践

业务背景&#xff1a;安全核对产生的土壤 行业背景&#xff1a; 隐私计算技术&#xff0c;实现数据可用不可见、可用不可得。 产品方案&#xff1a;从试点到规模化的路 基于隐语SCQL的数据比对应用&#xff1a;风洞隐私安全核对。 支持 1 to N的规模化核对。 特色功能&…

经典卡尔曼滤波完整公式推导

文章目录 1. 例子1.1 kalman跟踪车道线1.2 鼠标跟踪-匀速运动 2. 卡尔曼滤波3. 卡尔曼公式推导3.1 数学基础1(递归)3.2 数学基础2(数据融合、协方差、状态空间方程、观测器问题)3.3 卡尔曼增益公式推导3.4 误差协方差矩阵3.5 误差来源3.6 滤波调参 运动模型参考资料 1. 例子 1…

【重学C语言】三、C语言最简单的程序

【重学C语言】三、C语言最简单的程序 最简单的程序头文件使用尖括号 < >使用双引号 ""区别与注意事项示例 主函数认识三个错误 常量和变量常量ASCII 码表转义字符 关键字数据类型关键字存储类关键字修饰符关键字控制流程关键字函数相关关键字其他关键字 变量变…

SQL语句生成器,支持MSSQL/MYSQL/SQLITE/ACCESS/EXCEL

经过7个月的艰苦开发&#xff0c;SQL语句生成器终于和各位见面了&#xff0c;因为工程量浩大&#xff0c;一度做到崩溃&#xff0c;差点烂尾&#xff0c;好在经过N次激烈思想斗争后还是坚持了下来累累累累累累累 本软件能够自动生成SQL语句及对应的易语言代码&#xff0c;还有相…

HCIA笔记

console 登录设备的特点&#xff1a; 1、带外&#xff0c;不依赖网络本身的连通性。 2、独占&#xff0c;console口不能被多人同时使用&#xff0c;具备唯一性。 3、本地&#xff0c;console口长度有限&#xff0c;一般只能在机房或者设备现场来使用。 4、只能实现命令行的管理…

安泰电子 :电压放大器的技术指标有哪些

电压放大器是电子设备中常见的一种电路&#xff0c;它的作用是将输入信号的电压放大到所需的输出电压。电压放大器的技术指标描述了其性能和特征&#xff0c;涵盖了许多方面。下面西安安泰将详细介绍一些电压放大器的技术指标。 增益&#xff1a;增益是电压放大器最基本的指标之…

央视曝光!耗资超800万元建高标准农田,两年后改建光伏电站

近期&#xff0c;央视报道揭露湖北部分乡村存在基本农田被光伏项目侵占的情况。报道称湖北孝感市安陆市木梓乡发现光伏项目占用基本农田&#xff0c;却只得每亩500元租金且光伏项目未配套农业种植&#xff0c;导致村民收入减少和噪音扰民的情况。 据央视走访调查该地发现存在工…

【C++第三阶段】模板类模板通用数组实现案例

以下内容仅为当前认识&#xff0c;可能有不足之处&#xff0c;欢迎讨论&#xff01; 文章目录 模板怎么使用模板函数模板注意事项普通函数与函数模板的区别普通函数与函数模板调用规则函数模板限制 类模板类模板语法类模板与函数模板区别类模板中成员函数创建时机类模板对象做函…

文心一言指令词宝典之旅行篇

作者&#xff1a;哈哥撩编程&#xff08;视频号、抖音、公众号同名&#xff09; 新星计划全栈领域优秀创作者博客专家全国博客之星第四名超级个体COC上海社区主理人特约讲师谷歌亚马逊演讲嘉宾科技博主极星会首批签约作者 &#x1f3c6; 推荐专栏&#xff1a; &#x1f3c5;…

创业者的三大法宝:自我进化、自我激励与诚信坚守

一、摘要&#xff1a; 在创业的道路上&#xff0c;每一位创业者都如同航海家&#xff0c;驾驶着自己的船只&#xff0c;在波涛汹涌的大海中探寻成功的彼岸。而在这条充满未知与挑战的旅程中&#xff0c;创业者们需要具备哪些关键的品质和能力呢&#xff1f;京东集团创始人刘强…

Codigger Desktop:开发者的利器,每个人的好帮手(二)

昨日&#xff0c;我们为大家揭开了Codigger Desktop开发者利器的三种特性&#xff0c;展现了其独特的亮点。今日&#xff0c;我们将继续为大家呈现另外三项引人注目的特性&#xff0c;以展现这款工具的全面实力。 一、AI辅助&#xff1a;智能识别Module&#xff0c;环境配置一步…

小米造车为什么能够成功?

#小米汽车 #小米su7交付 引言 小米官方公告&#xff0c;今天(4月3日)小米SU7将正式交付&#xff0c;预示着我们将在道路上见到越来越多的小米汽车。 3月28日&#xff0c;小米汽车在官方微博发文宣布&#xff0c;小米SU7开启大定4分钟订单突破1万台&#xff0c;7分钟订单突破2万…

内存管理是如何影响系统的性能的

大家好&#xff0c;今天给大家介绍内存管理是如何影响系统的性能的&#xff0c;文章末尾附有分享大家一个资料包&#xff0c;差不多150多G。里面学习内容、面经、项目都比较新也比较全&#xff01;可进群免费领取。 内存管理对系统性能的影响至关重要&#xff0c;主要体现在以下…

ADG优化之多实例redo应用

最近接到客户电话&#xff0c;咨询如何对ADG备库进行优化的问题&#xff0c;这个客户也是我们的老客户了&#xff0c;数据量庞大&#xff08;100TB以上&#xff09;&#xff0c;数据库版本为19C RAC &#xff0c;客户现在遇到备库性能瓶颈&#xff0c;经常发生数据延迟同步的情…