【C++】POCO学习总结(十):Poco::Util::Application(应用程序框架)
【C++】郭老二博文之:C++目录
1、Poco::Util::Application 应用框架
1.1 应用程序基本功能
Poco::Util::Application是POCO实现的的应用程序框架,支持功能如下:
- 命令行参数处理
- 配置文件
- 初始化和关机
- 日志
1.2 命令行程序和守护进程
POCO支持两种应用:
- 命令行应用程序:从命令行启动,POCO支持命令行参数处理
- 服务器应用程序:通常作为守护进程运行,比如Linux守护进程、Windows服务
2、Poco::Util::Subsystem 子系统
2.1 说明
Poco::Util::Application继承自Poco::Util::Subsystem。
POCO中将不同的子系统组成一个应用程序。子系统以模块化的方式扩展应用。
- 子系统抽象出统一的初始化和关闭等步骤。
- 当一个应用程序被初始化时,它所有注册的子系统也被初始化。
- 当一个应用程序关闭时,它所有注册的子系统也会关闭。
2.2 使用
一个子系统都是从Poco::Util::Subsystem继承而来,下面列出几个常用的接口
- const char* name():返回子系统的名称;
- void initialize(Application& app):初始化子系统操作;
- void uninitialize(Application& app):关闭子系统时的操作;
- void reinitialize(Application& app):重新配置子系统(可选;默认实现调用uninitialize(),然后调用initialize());
- void defineOptions(OptionSet& options):子系统自定义命令行参数
3、命令行程序
命令行应用程序是通过创建Poco::Util::Application的子类来实现的。有几个虚成员函数需要重写:
- void initialize(Application& self)
- void reinitialize()
- void uninitialize()
- void defineOptions()
- int main(std::vectorstd::string& args)
注意:上面的main是Poco::Util::Application的成员函数,应用程序的主要逻辑写在这里。
返回值是枚举:ExitCode
enum ExitCode
{EXIT_OK = 0, 成功终止EXIT_USAGE = 64, 命令行使用错误EXIT_DATAERR = 65, 数据格式错误EXIT_NOINPUT = 66, 无法打开输入EXIT_NOUSER = 67, 地址错误EXIT_NOHOST = 68, 主机名是未知EXIT_UNAVAILABLE = 69, 服务不可用EXIT_SOFTWARE = 70, 内部软件错误EXIT_OSERR = 71, 系统错误 (e.g., can't fork)EXIT_OSFILE = 72, 关键操作系统文件丢失EXIT_CANTCREAT = 73, 不能创建(用户)输出文件EXIT_IOERR = 74, 输入/输出错误EXIT_TEMPFAIL = 75, 临时错误,可以尝试重新运行EXIT_PROTOCOL = 76, 协议中的远程错误EXIT_NOPERM = 77, 没有权限EXIT_CONFIG = 78 配置错误
};
4、Poco::Util::ServerApplication 服务类程序
想要实现一个服务类程序,需要从Poco::Util::ServerApplication继承;
Poco::Util::ServerApplication本身继承自Poco::Util::Application;
服务类应用程序可以从命令行运行,比如:Linux守护进程、Windows服务。
通常,服务类应用程序在后台线程中工作。因此,main()成员函数将启动线程,然后等待外部请求来终止应用程序(参见waitForTerminationRequest())。
5、配置文件
5.1 说明
默认情况下会创建两个配置:
- 可写的MapConfiguration,只读的PRIO_APPLICATION
- SystemConfiguration, PRIO_SYSTEM
5.2 用法
void MyApplication::initialize(Application& self)
{loadConfiguration(); // 加载默认配置文件Application::initialize(self);
}
6、命令行参数
6.1 说明
应用程序可以定义和处理命令行参数(选项)。命令行参数格式随系统不同而不同:
- Windows:/option or /option=value
- Linux:-o, -ovalue, --option or --option:value
6.2 使用
应用程序的选项通过重写虚函数 void defineOptions(OptionSet& options) 来实现
“定义选项类”OptionSet 用来处理选项,比如OptionSet::addOption()函数可以添加选项,示例如下:
void defineOptions(OptionSet& options)
{Application::defineOptions(options);options.addOption(Option("help", "h", "display help information on command line arguments").required(false).repeatable(false).callback(OptionCallback<SampleApp>(this, &SampleApp::handleHelp)));options.addOption(Option("config-file", "f", "load configuration data from a file").required(false).repeatable(true).argument("file").callback(OptionCallback<SampleApp>(this, &SampleApp::handleConfig)));options.addOption(Option("bind", "b", "bind option value to test.property").required(false).argument("value").validator(new IntValidator(0, 100)).binding("test.property"));
}
运行时打印:
-h, --help display help information on command line arguments
-ffile, --config-file=file load configuration data from a file
-bvalue, --bind=value bind option value to test.property
每个选项Option有如下内容:
- 一个全名
- 一个用字符表示的缩写(短名字)
- 一段描述
- 一个参数名:argument
- 是否必须:required
- 是否可重复:repeatable,它可以在命令行中被多次给出
- 回调函数:callback
6.3 验证选项参数
通过为选项指定一个Validator对象,可以自动验证选项参数。
- IntValidator 检查参数是否为一定范围内的整数。
- RegExpValidator 验证参数是否匹配给定的正则表达式。
比如上例中的:.validator(new IntValidator(0, 100))
6.4 显示帮助信息
Poco::Util::HelpFormatter类可用于显示命令行选项帮助信息。
当用户请求帮助信息时,应取消所有进一步的命令行处理(特别是强制执行所需选项)。这可以通过调用stopOptionsProcessing()来完成。
void displayHelp()
{HelpFormatter helpFormatter(options());helpFormatter.setCommand(commandName());helpFormatter.setUsage("OPTIONS");helpFormatter.setHeader("Poco::Util::Application类的示例");helpFormatter.format(std::cout);
}void handleHelp(const std::string& name, const std::string& value)
{_helpRequested = true;displayHelp();stopOptionsProcessing();
}
7、Windows 服务
Windows服务需要注册。
Poco::Util::ServerApplication可以实现注册的步骤。
- 注册:在命令行启动时指定选项 /registerService
- 取消注册:指定 /unregisterService 选项来取消
- 设置服务名称:通过选项 /displayName 来指定
8、Linux 守护进程
在Linux平台上,继承Poco::Util::ServerApplication后,可以通过命令行参数“–daemon”来实现,作为守护进程运行。
一个守护进程,当启动时,会立即从执行实际工作的后台进程中分离出来。启动后台进程后,前台进程退出。
初始化完成后,在进入main()方法之前,守护进程的当前工作目录将更改为根目录(“/”),这是守护进程的常见做法。
应用程序可以通过检查application.runasdaemon配置属性来确定它是否作为守护进程运行。
与Windows服务一样,在配置文件中使用相对路径时要小心,因为守护进程的当前工作目录是根目录。
#include "Poco/Util/ServerApplication.h"
#include "Poco/Util/Option.h"
#include "Poco/Util/OptionSet.h"
#include "Poco/Util/HelpFormatter.h"
#include "Poco/Task.h"
#include "Poco/TaskManager.h"
#include "Poco/DateTimeFormatter.h"
#include <iostream>using Poco::Util::Application;
using Poco::Util::ServerApplication;
using Poco::Util::Option;
using Poco::Util::OptionSet;
using Poco::Util::OptionCallback;
using Poco::Util::HelpFormatter;
using Poco::Task;
using Poco::TaskManager;
using Poco::DateTimeFormatter;class SampleTask: public Task
{
public:SampleTask(): Task("SampleTask"){}void runTask(){Application& app = Application::instance();while (!sleep(5000)){Application::instance().logger().information("busy doing nothing... " + DateTimeFormatter::format(app.uptime()));}}
};class SampleServer: public ServerApplication
{
public:SampleServer(): _helpRequested(false){}~SampleServer(){}protected:void initialize(Application& self){loadConfiguration(); // load default configuration files, if presentServerApplication::initialize(self);logger().information("starting up");}void uninitialize(){logger().information("shutting down");ServerApplication::uninitialize();}void defineOptions(OptionSet& options){ServerApplication::defineOptions(options);options.addOption(Option("help", "h", "display help information on command line arguments").required(false).repeatable(false).callback(OptionCallback<SampleServer>(this, &SampleServer::handleHelp)));}void handleHelp(const std::string& name, const std::string& value){_helpRequested = true;displayHelp();stopOptionsProcessing();}void displayHelp(){HelpFormatter helpFormatter(options());helpFormatter.setCommand(commandName());helpFormatter.setUsage("OPTIONS");helpFormatter.setHeader("A sample server application that demonstrates some of the features of the Util::ServerApplication class.");helpFormatter.format(std::cout);}int main(const ArgVec& args){if (!_helpRequested){TaskManager tm;tm.start(new SampleTask);waitForTerminationRequest();tm.cancelAll();tm.joinAll();}return Application::EXIT_OK;}
private:bool _helpRequested;
};POCO_SERVER_MAIN(SampleServer)
9、一个简单的示例
#include "Poco/Util/Application.h"
#include "Poco/Util/Option.h"
#include "Poco/Util/OptionSet.h"
#include "Poco/Util/HelpFormatter.h"
#include "Poco/Util/AbstractConfiguration.h"
#include "Poco/AutoPtr.h"
#include <iostream>
#include <sstream>using Poco::Util::Application;
using Poco::Util::Option;
using Poco::Util::OptionSet;
using Poco::Util::HelpFormatter;
using Poco::Util::AbstractConfiguration;
using Poco::Util::OptionCallback;
using Poco::AutoPtr;class SampleApp: public Application/// This sample demonstrates some of the features of the Util::Application class,/// such as configuration file handling and command line arguments processing.////// Try SampleApp --help (on Unix platforms) or SampleApp /help (elsewhere) for/// more information.
{
public:SampleApp(): _helpRequested(false){}protected:void initialize(Application& self){loadConfiguration(); // load default configuration files, if presentApplication::initialize(self);// add your own initialization code here}void uninitialize(){// add your own uninitialization code hereApplication::uninitialize();}void reinitialize(Application& self){Application::reinitialize(self);// add your own reinitialization code here}void defineOptions(OptionSet& options){Application::defineOptions(options);options.addOption(Option("help", "h", "display help information on command line arguments").required(false).repeatable(false).callback(OptionCallback<SampleApp>(this, &SampleApp::handleHelp)));options.addOption(Option("define", "D", "define a configuration property").required(false).repeatable(true).argument("name=value").callback(OptionCallback<SampleApp>(this, &SampleApp::handleDefine)));options.addOption(Option("config-file", "f", "load configuration data from a file").required(false).repeatable(true).argument("file").callback(OptionCallback<SampleApp>(this, &SampleApp::handleConfig)));options.addOption(Option("bind", "b", "bind option value to test.property").required(false).repeatable(false).argument("value").binding("test.property"));}void handleHelp(const std::string& name, const std::string& value){_helpRequested = true;displayHelp();stopOptionsProcessing();}void handleDefine(const std::string& name, const std::string& value){defineProperty(value);}void handleConfig(const std::string& name, const std::string& value){loadConfiguration(value);}void displayHelp(){HelpFormatter helpFormatter(options());helpFormatter.setCommand(commandName());helpFormatter.setUsage("OPTIONS");helpFormatter.setHeader("A sample application that demonstrates some of the features of the Poco::Util::Application class.");helpFormatter.format(std::cout);}void defineProperty(const std::string& def){std::string name;std::string value;std::string::size_type pos = def.find('=');if (pos != std::string::npos){name.assign(def, 0, pos);value.assign(def, pos + 1, def.length() - pos);}else name = def;config().setString(name, value);}int main(const ArgVec& args){if (!_helpRequested){logger().information("Command line:");std::ostringstream ostr;for (ArgVec::const_iterator it = argv().begin(); it != argv().end(); ++it){ostr << *it << ' ';}logger().information(ostr.str());logger().information("Arguments to main():");for (ArgVec::const_iterator it = args.begin(); it != args.end(); ++it){logger().information(*it);}logger().information("Application properties:");printProperties("");}return Application::EXIT_OK;}void printProperties(const std::string& base){AbstractConfiguration::Keys keys;config().keys(base, keys);if (keys.empty()){if (config().hasProperty(base)){std::string msg;msg.append(base);msg.append(" = ");msg.append(config().getString(base));logger().information(msg);}}else{for (AbstractConfiguration::Keys::const_iterator it = keys.begin(); it != keys.end(); ++it){std::string fullKey = base;if (!fullKey.empty()) fullKey += '.';fullKey.append(*it);printProperties(fullKey);}}}private:bool _helpRequested;
};
打印帮助信息
$ ./SampleApp -h
usage: SampleApp OPTIONS
A sample application that demonstrates some of the features of the Poco::Util::Application class.-h, --help display help information on command line arguments
-Dname=value, --define=name=value define a configuration property
-ffile, --config-file=file load configuration data from a file
-bvalue, --bind=value bind option value to test.property
运行后的打印信息
$ ./SampleApp
[Information] Command line:
[Information] ./SampleApp
[Information] Arguments to main():
[Information] Application properties:
[Information] application.argc = 1
[Information] application.argv[0] = ./SampleApp
[Information] application.baseName = SampleApp
[Information] application.cacheDir = /home/laoer/.cache/SampleApp/
[Information] application.configDir = /home/laoer/git/poco/Util/samples/SampleApp/
[Information] application.dataDir = /home/laoer/.local/share/SampleApp/
[Information] application.dir = /home/laoer/git/poco/Util/samples/SampleApp/bin/Linux/x86_64/
[Information] application.name = SampleApp
[Information] application.path = /home/laoer/git/poco/Util/samples/SampleApp/bin/Linux/x86_64/SampleApp
[Information] application.tempDir = /home/laoer/.local/tmp/SampleApp/
[Information] logging.channels.c1.class = ConsoleChannel
[Information] logging.channels.c1.formatter = f1
[Information] logging.formatters.f1.class = PatternFormatter
[Information] logging.formatters.f1.pattern = [%p] %t
[Information] logging.loggers.app.channel = c1
[Information] logging.loggers.app.name = Application
[Information] logging.loggers.root.channel.class = ConsoleChannel
[Information] system.osName = Linux
[Information] system.osVersion = 6.2.0-37-generic
[Information] system.osArchitecture = x86_64
[Information] system.nodeName = laoer
[Information] system.nodeId =
[Information] system.currentDir = /home/laoer/git/poco/Util/samples/SampleApp/bin/Linux/x86_64/
[Information] system.homeDir = /home/laoer/
[Information] system.configHomeDir = /home/laoer/.config/
[Information] system.cacheHomeDir = /home/laoer/.cache/
[Information] system.dataHomeDir = /home/laoer/.local/share/
[Information] system.tempHomeDir = /home/laoer/.local/tmp/
[Information] system.tempDir = /tmp/
[Information] system.configDir = /etc/
[Information] system.dateTime = 2023-12-10T14:50:02Z
[Information] system.pid = 4919
相关文章:
【C++】POCO学习总结(十):Poco::Util::Application(应用程序框架)
【C】郭老二博文之:C目录 1、Poco::Util::Application 应用框架 1.1 应用程序基本功能 Poco::Util::Application是POCO实现的的应用程序框架,支持功能如下: 命令行参数处理配置文件初始化和关机日志 1.2 命令行程序和守护进程 POCO支持…...
探索医学影像:如何通过ROI灰度直方图和ROI区域方格图揭示隐秘细节?
一、引言 医学影像是现代医学诊断的重要手段,其中nrrd文件格式作为一种常见的医学影像数据存储方式,被广泛应用于各种医学影像设备和软件中。这种文件格式具有丰富的元数据信息,可以精确记录影像的空间位置、方向和尺度等信息,对于…...
SASS基本语法总结
SASS是CSS预处理器,简单来说,SASS是比CSS更高一级的语言,它拥有CSS不具备的语法,比如if条件控制 SASS的预处理器 SASS是一种无法被浏览器直接执行的语言,我们需要通过预处理工具(可以理解为翻译工具&…...
【C++】简单工厂模式
2023年12月6日,周三下午 今天又学习了一次简单工厂模式 每多学习一次,都会加深对设计模式的理解 目录 什么是简单工厂模式简单工厂模式的优缺点举例说明 什么是简单工厂模式 简单工厂模式(Simple Factory Pattern)是一种创建型…...
el-tree数据量过大,造成浏览器卡死、崩溃
el-tree数据量过大,造成浏览器卡死、崩溃 场景:树形结构展示,数据超级多,超过万条,每次打开都会崩溃 我这里采用的是引入新的插件虚拟树,它是参照element-plus 中TreeV2改造vue2.x版本虚拟化树形控件&…...
2024 年甘肃省职业院校技能大赛中职组 电子与信息类“网络安全”赛项竞赛样题-A
2024 年甘肃省职业院校技能大赛中职组 电子与信息类“网络安全”赛项竞赛样题-A 目录 2024 年甘肃省职业院校技能大赛中职组 电子与信息类“网络安全”赛项竞赛样题-A 需要环境或者解析可以私信 (二)A 模块基础设施设置/安全加固(200 分&…...
面向LLM的App架构——业务维度
这是两篇面向LLM的大前端架构的第一篇,主要写我对LLM业务的认知以及由此推演出的大前端架构。由于我是客户端出身,所以主要以客户端角度来描述,并不影响对前端的适用性。 对LLM的认知 基于Google对AGI的论文,AGI或者LLM一定会朝…...
ElasticSearch之cat plugins API
命令样例如下: curl -X GET "https://localhost:9200/_cat/plugins?vtrue&pretty" --cacert $ES_HOME/config/certs/http_ca.crt -u "elastic:ohCxPHQBEs5*lo7F9"执行结果输出如下: name component version…...
【小米电脑管家】安装使用教程--非小米电脑
安装说明功能体验下载资源 Xiaomi HyperOS发布后,小米妙享电脑端独立版本也走向终点,最新的【小米电脑管家】将会内置妙享实现万物互联。那么本篇文章将分享非小米电脑用户如何绕过设备识别验证安装使用【小米电脑管家】实现万物互联 安装说明 1.解压文…...
视频讲解|基于多目标粒子群算法的配电网储能选址定容
1 主要内容 该视频为3012基于多目标粒子群算法的配电网储能选址定容matlab代码讲解内容,对应的资源下载链接为基于多目标粒子群算法的配电网储能选址定容,程序主要内容是:以系统节点电压水平(电网脆弱性)、网络损耗以…...
Android 13 - Media框架(22)- MediaCodec(三)
这一节开始我们将重新回到 MediaCodec 这一层来学习 buffer 的流转 status_t MediaCodec::dequeueOutputBuffer(size_t *index,size_t *offset,size_t *size,int64_t *presentationTimeUs,uint32_t *flags,int64_t timeoutUs) {sp<AMessage> msg new AMessage(kWhatDequ…...
git提交报错 fatal: LF would be replaced by CRLF in package-lock.json
报错 fatal: LF would be replaced by CRLF in package-lock.json 原因 git 在windows下,默认是CRLF作为换行符, git add 提交时,会检查文本中是否有LF 换行符(linux系统),如果有则会告警, 所…...
卷积详解和并行卷积
ps:在 TensorFlow Keras 中,构建 Sequential 模型的正确方式是将层作为列表传递,而不是作为一系列单独的参数。 modelmodels.Sequential([layers,layers]) 而不是modelmodels.Sequential(layers,layers) 文章目录 卷积…...
c#生成二维码二维码中间添加定制LoGo
🚀介绍 🍀QRCoder是一个开源的.NET库,用于生成QR码(Quick Response Code)。这个库是用C#编写的,并且可以在.NET框架的各种版本上使用,包括.NET Framework, .NET Core, Mono, Xamarin等。QRCode…...
设计CPU功能的数字电路
实验目的(1)熟悉Multisim 电路仿真软件的操作界面和功能; (2)掌握逻辑电路综合设计,并采用仿真软件进行仿真。 实验内容1.试设计一个简易CPU功能的数字电路,实验至少要求采用4个74HC/HCT194作为4个存储单元(可以预先对存储单元存储数据),74HC283作为计算单元。请实现…...
在windows下编译libiconv库
libiconv是一个基于GNU协议的开源库,主要用于解决多语言编码处理转换等应用问题。在linux系统使用比较方便,但是windows下使用需要进行源码编译。这里我是使用libiconv的1.15版本源码和VS2019默认工具集配置进行编译。 首先需要用VS2019创建一个空项目,根目录为libiconv。 在…...
html,css,开发知识,调试知识
nget 方式提交 n使用 get 方式提交数据时,表单数据会附加在 URL 之后,由用户端直接发送至服务器,所以速度比 post 快,但缺点是数据长度不能太长。 npost 方式提交 n使用 post 时,表单数据是与 URL 分开发送的&#…...
Vulnerability: File Upload(Medium)--MYSQL注入
选择难度: 1.打开DVWA,并登录账户 2.选择模式,这里我们选择 文件上载的中级模式(Medium) 准备工作 1.在vsc里面写个一句话木马 2.下载BurpSuiteCommunit软件:百度搜索“burp suite官网” 下载地址www…...
短视频账号剪辑矩阵+无人直播系统源头开发
抖去推爆款视频生成器,通过短视频矩阵、无人直播,文案引流等,打造实体商家员工矩阵、用户矩阵、直播矩阵,辅助商家品牌曝光,团购转化等多功能赋能商家拓客引流。 短视频矩阵通俗来讲就是批量剪辑视频和批量发布视频&am…...
Python traceback模块:获取异常信息
异常对象提供了一个 with_traceback 用于处理异常的传播轨迹,查看异常的传播轨迹可追踪异常触发的源头,也可看到异常一路触发的轨迹。 下面示例显示了如何显示异常传播轨迹: class SelfException(Exception): passdef main():firstMethod() …...
SpringBoot-17-MyBatis动态SQL标签之常用标签
文章目录 1 代码1.1 实体User.java1.2 接口UserMapper.java1.3 映射UserMapper.xml1.3.1 标签if1.3.2 标签if和where1.3.3 标签choose和when和otherwise1.4 UserController.java2 常用动态SQL标签2.1 标签set2.1.1 UserMapper.java2.1.2 UserMapper.xml2.1.3 UserController.ja…...
服务器硬防的应用场景都有哪些?
服务器硬防是指一种通过硬件设备层面的安全措施来防御服务器系统受到网络攻击的方式,避免服务器受到各种恶意攻击和网络威胁,那么,服务器硬防通常都会应用在哪些场景当中呢? 硬防服务器中一般会配备入侵检测系统和预防系统&#x…...
macOS多出来了:Google云端硬盘、YouTube、表格、幻灯片、Gmail、Google文档等应用
文章目录 问题现象问题原因解决办法 问题现象 macOS启动台(Launchpad)多出来了:Google云端硬盘、YouTube、表格、幻灯片、Gmail、Google文档等应用。 问题原因 很明显,都是Google家的办公全家桶。这些应用并不是通过独立安装的…...
数据链路层的主要功能是什么
数据链路层(OSI模型第2层)的核心功能是在相邻网络节点(如交换机、主机)间提供可靠的数据帧传输服务,主要职责包括: 🔑 核心功能详解: 帧封装与解封装 封装: 将网络层下发…...
ArcGIS Pro制作水平横向图例+多级标注
今天介绍下载ArcGIS Pro中如何设置水平横向图例。 之前我们介绍了ArcGIS的横向图例制作:ArcGIS横向、多列图例、顺序重排、符号居中、批量更改图例符号等等(ArcGIS出图图例8大技巧),那这次我们看看ArcGIS Pro如何更加快捷的操作。…...
全志A40i android7.1 调试信息打印串口由uart0改为uart3
一,概述 1. 目的 将调试信息打印串口由uart0改为uart3。 2. 版本信息 Uboot版本:2014.07; Kernel版本:Linux-3.10; 二,Uboot 1. sys_config.fex改动 使能uart3(TX:PH00 RX:PH01),并让boo…...
Maven 概述、安装、配置、仓库、私服详解
目录 1、Maven 概述 1.1 Maven 的定义 1.2 Maven 解决的问题 1.3 Maven 的核心特性与优势 2、Maven 安装 2.1 下载 Maven 2.2 安装配置 Maven 2.3 测试安装 2.4 修改 Maven 本地仓库的默认路径 3、Maven 配置 3.1 配置本地仓库 3.2 配置 JDK 3.3 IDEA 配置本地 Ma…...
Linux --进程控制
本文从以下五个方面来初步认识进程控制: 目录 进程创建 进程终止 进程等待 进程替换 模拟实现一个微型shell 进程创建 在Linux系统中我们可以在一个进程使用系统调用fork()来创建子进程,创建出来的进程就是子进程,原来的进程为父进程。…...
NXP S32K146 T-Box 携手 SD NAND(贴片式TF卡):驱动汽车智能革新的黄金组合
在汽车智能化的汹涌浪潮中,车辆不再仅仅是传统的交通工具,而是逐步演变为高度智能的移动终端。这一转变的核心支撑,来自于车内关键技术的深度融合与协同创新。车载远程信息处理盒(T-Box)方案:NXP S32K146 与…...
毫米波雷达基础理论(3D+4D)
3D、4D毫米波雷达基础知识及厂商选型 PreView : https://mp.weixin.qq.com/s/bQkju4r6med7I3TBGJI_bQ 1. FMCW毫米波雷达基础知识 主要参考博文: 一文入门汽车毫米波雷达基本原理 :https://mp.weixin.qq.com/s/_EN7A5lKcz2Eh8dLnjE19w 毫米波雷达基础…...
