当前位置: 首页 > news >正文

VSOMEIP主要流程的时序

请求服务:

client应用:

​ application_impl::request_service

​ routing_manager_client::request_service (老版本是routing_manager_proxy)

​ routing_manager_client::send_request_services

​ protocol::request_service_command its_command; // 创建订阅cmd

​ local_uds_client_endpoint_impl::send // 将订阅cmd发送给routingmanagerd

routingmanagerd:

​ local_uds_server_endpoint_impl::connection::receive_cbk // UnixDomainSocket /tmp/vsomeip-0 收到应用发来的request service命令

​ routing_manager_stub::on_message

​ routing_manager_impl::request_service

​ endpoint_manager_impl::find_or_create_remote_client // 从remote_service_info_中查找远端服务的配置,创建client_endpoint

​ tcp_client_endpoint_impl::start // 启动线程进行connect操作 (创建并且打开asio socket,设置socket属性,最后async_connect)

​ udp_client_endpoint_impl::start // 同上

在vsomeip中,每一个服务只占用一个端口(TCP/UDP/BOTH),无论method还是event都在这个端口上通信。

client发给routingmanagerd的cmd中,包含了client的端的clientid

请求事件:

client应用:

​ application_impl::request_event (service, instance, event, eventgroup事件组集合, 事件类型, reliable) //事件类型event/field/select_event

​ routing_manager_client::register_event

​ routing_manager_client::send_register_event

​ protocol::register_events_command its_command; // 注册event的cmd

​ local_uds_client_endpoint_impl::send // 将注册event的cmd发送给routingmanagerd

routingmanagerd:

​ local_uds_server_endpoint_impl::connection::receive_cbk // UnixDomainSocket /tmp/vsomeip-0 收到应用发来的request event命令

​ routing_manager_stub::on_message

​ 轮询protocol::register_events_command中的每一个register event项目

​ routing_manager_impl::register_shadow_event

​ routing_manager_base::register_event //将事件和事件组注册到内部的events_ 和eventgroups_ 中

// routing_manager_base内部events_ 和eventgroups_ 的作用

primitive_types.hpp

...
typedef uint32_t message_t;
typedef uint16_t service_t;
typedef uint16_t method_t;
typedef uint16_t event_t;typedef uint16_t instance_t;
typedef uint16_t eventgroup_t;
...

event.hpp

...
class event {...
private:...// 记录了每个eventgroup有哪些本地client订阅了// 每个event可以属于一个或者多个eventgroupstd::map<eventgroup_t, std::set<client_t> > eventgroups_;...
};
...

eventgroupinfo.hpp

class eventgroupinfo {
...
private:...std::set<std::shared_ptr<event> > events_;    // 记录了该eventgroup中的所有event(event中可以找到订阅该eventgroup的client)...std::map<remote_subscription_id_t,std::shared_ptr<remote_subscription>> subscriptions_;    // 保存对其他域的服务的订阅者的信息remote_subscription_id_t id_;  // 每增加一个对其他域的服务的订阅者(非域内), id_ 加一...
};

routing_manager_base.hpp

std::map<service_t,    			// 服务IDstd::map<instance_t,    // 实例IDstd::map<event_t,   // 事件IDstd::shared_ptr<event> > > > events_;    // 事件所属的组和每个组的订阅客户端std::map<service_t,				// 服务IDstd::map<instance_t,// 实例IDstd::map<eventgroup_t, std::shared_ptr<eventgroupinfo> > > > eventgroups_;  // 事件组中的事件和每个事件的订阅者信息

订阅:

client应用:

​ application_impl::subscribe

​ routing_manager_client::subscribe

​ routing_manager_client::send_subscribe

​ protocol::subscribe_command its_command; // 订阅cmd

​ local_uds_client_endpoint_impl::send // 将订阅的cmd发送给routingmanagerd

routingmanagerd:

​ local_uds_server_endpoint_impl::connection::receive_cbk // UnixDomainSocket /tmp/vsomeip-0 收到应用发来的subscribe命令

​ routing_manager_stub::on_message

​ routing_manager_impl::subscribe

​ const client_t its_local_client = find_local_client(_service, _instance); // 获取是哪个client发布了要订阅的服务

​ // 1. 订阅的服务是当前routingmanagerd应用发布的

​ if (get_client() == its_local_client) {

​ endpoint_manager_base::find_or_create_local // 根据订阅者的clientid创建用于通信的local

​ application_impl::on_subscription // 通知application有订阅到达,是否accept (accept_cbk是传入的匿名函数)

​ routing_manager_stub::send_subscribe_ack // 接收订阅,则回复ACK

​ routing_manager_stub::send_subscribe_nack // 否则回复NACK

​ }

​ // 2. 订阅的服务不是当前routingmanagerd应用发布的

​ routing_manager_base::insert_subscription

​ if (_event != ANY_EVENT) { // subscribe to specific event

​ // 在event_中插入订阅client的订阅记录

​ } else {

​ // 在eventgroups_的每个event中插入订阅client的订阅记录

​ }

​ // 2.1 订阅的服务是域外的someip应用发布的

​ if (0 == its_local_client) { // 说明域内找不到提供该服务的ciient

​ routing_manager_impl::find_event // 查看是否有client对该event进行过register(调用request_event)

​ routing_manager_impl::handle_subscription_state //主要是看对该event的订阅是否已经有收到过ACK了

​ if (its_state->second == subscription_state_e::SUBSCRIPTION_ACKNOWLEDGED) {

​ // Subscription already acknowledged!

​ if (_client == get_client()) {

​ // 如果订阅该服务的是routingmanagerd应用自己,则直接回调

​ application_impl::on_subscription_status(_service, _instance, _eventgroup, _event, 0x0 /OK/);

​ } else if (stub_) {

​ // 如果订阅该服务的是域内的其他应用,则通过uds将ACK消息发送过去

​ routing_manager_stub::send_subscribe_ack(_client, _service, _instance, _eventgroup, _event);

​ }

​ }

​ service_discovery_impl::subscribe // 通过SD模块订阅其他域发布的待订阅service/event/eventgroup

​ subscribed_.find //查找之前是否订阅过该eventgroup

​ std::shared_ptr<subscription> its_subscription = create_subscription() // 创建新的订阅

​ subscribed_[service] [inst] [eventgroup] = its_subscription;

​ service_discovery_impl::send_subscription

​ entry_data_t its_data; //创建要订阅的eventgroup的entry (create_eventgroup_entry)

​ auto its_current_message = std::make_shared<message_impl>(); // 创建要发送的OFFER报文

​ add_entry_data(its_messages, its_data); // 将订阅的eventgroup entry添加到OFFER报文中 service_discovery_impl::serialize_and_send // 发送

​ }

​ // 2.2 订阅的服务是域内其他someip应用发布的

​ else {

​ routing_manager_stub::send_subscribe //通过UDS 发送订阅请求给发布该service/Instance的client

​ }

发布服务:

client应用:

​ application_impl::offer_service

​ routing_manager_client::offer_service // 参数中带着clientid以及service的信息

​ routing_manager_base::offer_service // 判断一下是否可以发布service (例如局域网中已经有别的client发布了相同的service/instance)

​ routing_manager_client::send_offer_service

​ protocol::offer_service_command its_offer; // 创建发布服务的cmd

​ local_uds_client_endpoint_impl::send // 将offer service的cmd发送给routingmanagerd

routingmanagerd:

​ local_uds_server_endpoint_impl::connection::receive_cbk // UnixDomainSocket /tmp/vsomeip-0 收到应用发来的offer service命令

​ routing_manager_impl::offer_service

​ routing_manager_impl::insert_offer_command // 插入OFFER队列 (个人理解用于后期定周期发送)

​ routing_manager_impl::handle_local_offer_service // 判断是否可以Offer Service (是否存在冲突),可以offer的情况下插入local_services_中

​ service_discovery_impl::offer_service // 如果collected_offers_中不存在要发布的service,则添加进去

​ service_discovery_impl::on_offer_debounce_timer_expired // debounce定时器触发,将collected_offers_的offerentry倒出来后清空

​ std::shared_ptr<message_impl> its_message(std::make_shared<message_impl>()); // 创建要发送出去的Offer报文

​ service_discovery_impl::insert_offer_entries //将要offer的所有service entry加入Offer报文

​ service_discovery_impl::insert_offer_service // 添加单个service entry (service的entry以及option,option中包含了用于通信的endpoint信息)

​ service_discovery_impl::add_entry_data

​ service_discovery_impl::send // 发送Offer报文

​ offerservice有三种冲突的情况下,会offer失败:1. local存在相同服务 2. remote发布过相同服务 3. 当前应用本次offer的服务和之前offer的服务存在冲突

处理收到的Offer报文:

routingmanagerd:

​ routing_manager_impl::on_message

​ service_discovery_impl::on_message // 需要是SD报文才会给SD模块处理

​ service_discovery_impl::process_serviceentry // 判断entry’类型是service还是eventgroup的条件是type <= 2

​ service_discovery_impl::process_offerservice_serviceentry // service entry条目中type=1 (offer Service)

​ service_discovery_impl::update_request // 如果目前处于repetition阶段,则停止对该service发送FIND报文(因为已经收到了offer了)

​ if (_received_via_mcast) { // 如果是从组播地址收到的OFFER报文

​ auto found_service = subscribed_ .find(_service); // 从 subscribed_ 成员中查找本域中是否有client对该服务中事件组的订阅

​ 更新每一条订阅记录的状态

​ ST_ACKNOWLEDGED -> ST_RESUBSCRIBING

​ 非ST_ACKNOWLEDGED -> ST_RESUBSCRIBING_NOT_ACKNOWLEDGED

​ }

​ routing_manager_impl::add_routing_info // 新增/更新serviceinfo信息到services_remote_和services_两个内部容器

​ std::shared_ptr<serviceinfo> its_info(find_service(_service, _instance)); // 判断是否收到过该service的offer

​ if (!its_info) { // 没有是收到过该service的offer

​ routing_manager_base::create_service_info // 创建新的serviceinfo信息,添加到services_以及services_remote_中

​ }

​ endpoint_manager_impl::is_remote_service_known // 判断是否在该service上创建endpoint(reliable/unreliable)

​ if (_reliable_port != ILLEGAL_PORT && !is_reliable_known) { // service提供了tcp端口,对应的endpoint没有创建

​ for (const client_t its_client : get_requesters_unlocked(

​ endpoint_manager_impl::find_or_create_remote_client // 创建和service的tcp连接

​ its_info->add_client(its_client); // 将请求该service的client添加到上面create_service_info创建的serviceinfo中

​ }

​ }

​ if (_unreliable_port != ILLEGAL_PORT && !is_unreliable_known) { // service提供了udp端口,对应的endpoint没有创建

​ // 逻辑同TCP

​ }

​ if (!_reliable_address.is_unspecified() || !_unreliable_address.is_unspecified()) {

​ // 记录每个远端地址上发布的服务信息和收到的Offer报文数量并且打印

​ }

client应用:

​ 无:

entry条目类型的枚举值: (enumeration_types.hpp)

enum class entry_type_e: uint8_t {FIND_SERVICE = 0x00,OFFER_SERVICE = 0x01,STOP_OFFER_SERVICE = 0x01,REQUEST_SERVICE = 0x2,FIND_EVENT_GROUP = 0x4,PUBLISH_EVENTGROUP = 0x5,STOP_PUBLISH_EVENTGROUP = 0x5,SUBSCRIBE_EVENTGROUP = 0x06,STOP_SUBSCRIBE_EVENTGROUP = 0x06,SUBSCRIBE_EVENTGROUP_ACK = 0x07,STOP_SUBSCRIBE_EVENTGROUP_ACK = 0x07,UNKNOWN = 0xFF
};

service_discovery_impl中保存的事件组订阅情况的类Subscription主要结构如下:

class subscription {
...
private:std::shared_ptr<endpoint> reliable_;std::shared_ptr<endpoint> unreliable_;bool tcp_connection_established_;bool udp_connection_established_;std::map<client_t, subscription_state_e> clients_; // client-> is acknowledged?  // 每个client的订阅状态std::weak_ptr<eventgroupinfo> eg_info_;    // 订阅的事件组信息
};

routing_manager_impl中保存的收到的service信息的类serviceinfo主要结构如下:

class serviceinfo {
...
private:service_t service_;instance_t instance_;major_version_t major_;minor_version_t minor_;std::shared_ptr<endpoint> reliable_;std::shared_ptr<endpoint> unreliable_;std::set<client_t> requesters_;   // 请求过该服务的本地client
};

服务可用通知(Service Aailable)

routingmanagerd:

​ client_endpoint_impl::cancel_and_connect_cbk // 作为async_connect的回调函数被调用

​ client_endpoint_impl::connect_cbk

​ endpoint_manager_impl::on_connect

​ routing_manager_impl::service_endpoint_connected

​ routing_manager_impl::on_availability

​ routing_manager_stub::on_offer_service // 通知客户端sevice avaliable

​ routing_manager_stub::inform_requesters // routing_info_entry_type_e::RIE_ADD_SERVICE_INSTANCE

​ for (auto its_client : service_requests_) { // 该连接是用于和远端service通信的,找到请求了对应service的本地client

​ routing_manager_stub::send_client_routing_info

​ protocol::routing_info_command its_command; // 发送给client的routing_info信息(包含了service信息)

​ }

client应用:

​ routing_manager_client::on_message

​ routing_manager_client::on_routing_info

​ for (const auto &e : its_command.get_entries()) { // 轮询每一个entry (号到type为RIE_ADD_SERVICE_INSTANCE的条目)

​ application_impl::on_availability // 通知application服务可用

​ }

处理订阅:

routingmanagerd:

​ service_discovery_impl::on_message

​ auto its_acknowledgement = std::make_shared<remote_subscription_ack>(_sender); //提前准备好给客户端回复的订阅ACK/NACK报文

​ service_discovery_impl::process_eventgroupentry

​ service_discovery_impl::insert_subscription_ack

​ service_discovery_impl::add_entry_data_to_remote_subscription_ack_msg

​ service_discovery_impl::send_subscription_ack

client应用:

​ 无

处理订阅ACK/NACK

routingmanagerd:

​ service_discovery_impl::on_message

​ service_discovery_impl::process_eventgroupentry(

​ if (entry_type_e::SUBSCRIBE_EVENTGROUP_ACK == its_type) { // 对于eventgroupentry类型为subscribe_ack/nack

​ service_discovery_impl::handle_eventgroup_subscription_ack/_nack (根据Entry中的TTL判断是ACK还是NACK)

​ auto found_service = subscribed_.find(_service);

​ for (…) { // 找到每一个订阅该eventgroup的client

​ found_eventgroup->second->set_state(its_client, subscription_state_e::ST_ACKNOWLEDGED); // 修改订阅状态 (ACKED)

​ routing_manager_impl::on_subscribe_ack(_client)

​ }

​ }

client应用:

发布事件:

client应用:

routingmanagerd:

发送REQUEST:

client应用:

routingmanagerd:

发送RESPONSE:

client应用:

routingmanagerd:

相关文章:

VSOMEIP主要流程的时序

请求服务: client应用&#xff1a; ​ application_impl::request_service ​ routing_manager_client::request_service (老版本是routing_manager_proxy) ​ routing_manager_client::send_request_services ​ protocol::request_service_command its_command; // 创建…...

右值引用和移动语义:

C 右值引用和移动语义详解 在 C 的发展历程中&#xff0c;右值引用和移动语义的引入带来了显著的性能提升和编程灵活性。本文将深入探讨右值引用和移动语义的概念、用法以及重要性。 一、引言 C 作为一门高效的编程语言&#xff0c;一直在不断演进以满足现代软件编程的需求。…...

经纬高LLA转地心地固ECEF坐标,公式,代码

经纬高转地心地固的目的 坐标系转换是gis或者slam系统常见操作。GNSS获取的一般是经纬高&#xff0c;经纬高在slam系统里无法应用&#xff0c;slam系统一般是xyz互相垂直的笛卡尔坐标系&#xff0c;所以需要把GNSS的经纬高转到直角坐标系地心地固ECEF或者高斯投影GKP。 划重点…...

VUE前端实现天爱滑块验证码--详细教程

第一步&#xff1a; Git地址&#xff1a;tianai-captcha-demo: 滑块验证码demo 找到目录 src/main/resources/static,拷贝 static 并改名为 tac 即可。 第二步&#xff1a; 将改为 tac 的文件&#xff0c;放进项目根目录中&#xff0c;如下图&#xff1a; 第三步&#xff1…...

【链表】【删除节点】【刷题笔记】【灵神题单】

237.删除链表的节点 链表删除节点的本质是不用删除&#xff0c;只需要操作指针&#xff0c;跳过需要删除的节点&#xff0c;指向下下一个节点即可&#xff01; 删除某个节点&#xff0c;但是不知道这个节点的前一个节点&#xff0c;也不知道头节点&#xff01;摘自力扣评论区…...

springboot339javaweb的新能源充电系统pf(论文+源码)_kaic

毕 业 设 计&#xff08;论 文&#xff09; 题目&#xff1a;新能源充电系统的设计与实现 摘 要 如今社会上各行各业&#xff0c;都喜欢用自己行业的专属软件工作&#xff0c;互联网发展到这个时候&#xff0c;人们已经发现离不开了互联网。新技术的产生&#xff0c;往往能解…...

【嵌入式——QT】QT制作安装包

第一步 QT程序写好之后&#xff0c;编译release版本 第二步 拿到release生成的.exe文件 第三步 新建文件夹deploy 第四步 将.exe文件复制到deploy目录下 第五步 在该目录下输入cmd指令&#xff0c;回车 第六步 在打开的命令窗口下输入 windeployqt TegNetCom_1.0.…...

python的文件操作练习

文件操作&#xff1a;成绩统计 有一个文件grades.txt&#xff0c;文件内容是每行一个学生的成绩&#xff08;格式&#xff1a;姓名,成绩&#xff09;。要求&#xff1a; 读取文件内容&#xff0c;统计所有学生的平均成绩&#xff1b; 将不及格&#xff08;<60分&#xff09…...

jQuery九宫格抽奖,php处理抽奖信息

功能介绍 jQuery九宫格抽奖是一种基于jQuery库的前端抽奖效果。通过九宫格的形式展示抽奖项&#xff0c;用户点击抽奖按钮后&#xff0c;九宫格开始旋转&#xff0c;最终停在一个随机位置上&#xff0c;此位置对应的抽奖项为用户的中奖结果。 本文实现九宫格的步骤为&#xf…...

2024年一级建造师考试成绩,即将公布!

一级建造师考试成绩一般在考试结束后3个月左右的时间公布&#xff01; 根据官方通知&#xff0c;重庆、江苏、青海、江西、云南、湖南、福建、北京、山西、黑龙江等地在今年一建报名通知里提到&#xff1a;2024年一级建造师考试成绩预计于2024年12月上旬公布。考生可在这个时间…...

M4V 视频是一种什么格式?如何把 M4V 转为 MP4 格式?

M4V 是一种视频文件格式&#xff0c;主要由苹果公司用于其产品和服务中&#xff0c;如 iTunes Store 上的电影和电视节目。这种格式可以包含受版权保护的内容&#xff0c;并且通常与苹果的 DRM&#xff08;数字版权管理&#xff09;技术结合使用&#xff0c;以限制内容的复制和…...

Leetcode 每日一题 104.二叉树的最大深度

目录 问题描述 示例 示例 1&#xff1a; 示例 2&#xff1a; 约束条件 题解 方法一&#xff1a;广度优先搜索&#xff08;BFS&#xff09; 步骤 代码实现 方法二&#xff1a;递归 步骤 代码实现 结论 问题描述 给定一个二叉树 root&#xff0c;我们需要返回其最大…...

文件上传漏洞:你的网站安全吗?

文章目录 文件上传漏洞攻击方式&#xff1a;0x01绕过前端限制0x02黑名单绕过1.特殊解析后缀绕过2..htaccess解析绕过3.大小写绕过4.点绕过5.空格绕过6.::$DATA绕过7.配合中间件解析漏洞8.双后缀名绕过9.短标签绕过 0x03白名单绕过1.MIME绕过(Content-Type绕过)2.%00截断3.0x00截…...

AWS账号提额

Lightsail提额 控制台右上角&#xff0c;用户名点开&#xff0c;选择Service Quotas 在导航栏中AWS服务中找到lightsail点进去 在搜索框搜索instance找到相应的实例类型申请配额 4.根据自己的需求选择要提额的地区 5.根据需求来提升配额数量,提升小额配额等大约1小时生效 Ligh…...

电子应用设计方案-29:智能云炒菜系统方案设计

智能云炒菜系统方案设计 一、系统概述 本智能云炒菜系统旨在为用户提供便捷、高效、个性化的烹饪体验&#xff0c;结合云技术实现远程控制、食谱分享、智能烹饪流程优化等功能。 二、系统组成 1. 炒菜锅主体 - 高品质不粘锅内胆&#xff0c;易于清洁和维护。 - 加热装置&#x…...

腾讯rapidJson使用例子

只需要把库的头文件拿下来加入项目中使用就行&#xff0c;我是以二进制文件存储内容并解析&#xff1a; #include <iostream> #include <fstream> #include <string> #include "rapidjson/document.h" #include "rapidjson/error/en.h"…...

UE5_CommonUI简单使用(2)

上篇我是简单写了一下CommonUI使用的初始设置以及Common Activatable Widget和Common Activatable Widget Stack以及Common 控件Style以及鼠标控制的一些内容,这些对于了解UMG的朋友来说没什么难度,唯一需要注意的就是Common Activatable Widget Stack堆栈管理只能是用来管理…...

探讨播客的生态系统

最近对播客发生了兴趣&#xff0c;从而引起了对播客背后的技术&#xff0c;生态的关注。本文谈谈播客背后的技术生态系统。 播客很简单 播客&#xff08;podcast&#xff09;本质上就是以语音的方式发布信息。它和博客非常类似。如果将CSDN 网站上的文字加一个语音播报。CSDN …...

淘宝架构演化

基本功能 LAMP&#xff08;LinuxApacheMySQLPHP&#xff09;标准架构&#xff0c;初期采用拿来主义&#xff0c;只具备基本功能。 数据库&#xff1a;读写分离&#xff0c;MyISAM存储引擎 2003年5月—2004年1月 存储瓶颈 mysql达到访问瓶颈&#xff0c;升级成oracle&#x…...

软通动力携子公司鸿湖万联、软通教育助阵首届鸿蒙生态大会成功举办

11月23日中国深圳&#xff0c;首届鸿蒙生态大会上&#xff0c;软通动力及软通动力子公司鸿湖万联作为全球智慧物联网联盟&#xff08;GIIC&#xff09;理事单位、鸿蒙生态服务&#xff08;深圳&#xff09;有限公司战略合作伙伴&#xff0c;联合软通教育深度参与了大会多项重磅…...

conda相比python好处

Conda 作为 Python 的环境和包管理工具&#xff0c;相比原生 Python 生态&#xff08;如 pip 虚拟环境&#xff09;有许多独特优势&#xff0c;尤其在多项目管理、依赖处理和跨平台兼容性等方面表现更优。以下是 Conda 的核心好处&#xff1a; 一、一站式环境管理&#xff1a…...

大话软工笔记—需求分析概述

需求分析&#xff0c;就是要对需求调研收集到的资料信息逐个地进行拆分、研究&#xff0c;从大量的不确定“需求”中确定出哪些需求最终要转换为确定的“功能需求”。 需求分析的作用非常重要&#xff0c;后续设计的依据主要来自于需求分析的成果&#xff0c;包括: 项目的目的…...

Admin.Net中的消息通信SignalR解释

定义集线器接口 IOnlineUserHub public interface IOnlineUserHub {/// 在线用户列表Task OnlineUserList(OnlineUserList context);/// 强制下线Task ForceOffline(object context);/// 发布站内消息Task PublicNotice(SysNotice context);/// 接收消息Task ReceiveMessage(…...

全球首个30米分辨率湿地数据集(2000—2022)

数据简介 今天我们分享的数据是全球30米分辨率湿地数据集&#xff0c;包含8种湿地亚类&#xff0c;该数据以0.5X0.5的瓦片存储&#xff0c;我们整理了所有属于中国的瓦片名称与其对应省份&#xff0c;方便大家研究使用。 该数据集作为全球首个30米分辨率、覆盖2000–2022年时间…...

Python实现prophet 理论及参数优化

文章目录 Prophet理论及模型参数介绍Python代码完整实现prophet 添加外部数据进行模型优化 之前初步学习prophet的时候&#xff0c;写过一篇简单实现&#xff0c;后期随着对该模型的深入研究&#xff0c;本次记录涉及到prophet 的公式以及参数调优&#xff0c;从公式可以更直观…...

【碎碎念】宝可梦 Mesh GO : 基于MESH网络的口袋妖怪 宝可梦GO游戏自组网系统

目录 游戏说明《宝可梦 Mesh GO》 —— 局域宝可梦探索Pokmon GO 类游戏核心理念应用场景Mesh 特性 宝可梦玩法融合设计游戏构想要素1. 地图探索&#xff08;基于物理空间 广播范围&#xff09;2. 野生宝可梦生成与广播3. 对战系统4. 道具与通信5. 延伸玩法 安全性设计 技术选…...

Unity | AmplifyShaderEditor插件基础(第七集:平面波动shader)

目录 一、&#x1f44b;&#x1f3fb;前言 二、&#x1f608;sinx波动的基本原理 三、&#x1f608;波动起来 1.sinx节点介绍 2.vertexPosition 3.集成Vector3 a.节点Append b.连起来 4.波动起来 a.波动的原理 b.时间节点 c.sinx的处理 四、&#x1f30a;波动优化…...

佰力博科技与您探讨热释电测量的几种方法

热释电的测量主要涉及热释电系数的测定&#xff0c;这是表征热释电材料性能的重要参数。热释电系数的测量方法主要包括静态法、动态法和积分电荷法。其中&#xff0c;积分电荷法最为常用&#xff0c;其原理是通过测量在电容器上积累的热释电电荷&#xff0c;从而确定热释电系数…...

【Go语言基础【13】】函数、闭包、方法

文章目录 零、概述一、函数基础1、函数基础概念2、参数传递机制3、返回值特性3.1. 多返回值3.2. 命名返回值3.3. 错误处理 二、函数类型与高阶函数1. 函数类型定义2. 高阶函数&#xff08;函数作为参数、返回值&#xff09; 三、匿名函数与闭包1. 匿名函数&#xff08;Lambda函…...

HybridVLA——让单一LLM同时具备扩散和自回归动作预测能力:训练时既扩散也回归,但推理时则扩散

前言 如上一篇文章《dexcap升级版之DexWild》中的前言部分所说&#xff0c;在叠衣服的过程中&#xff0c;我会带着团队对比各种模型、方法、策略&#xff0c;毕竟针对各个场景始终寻找更优的解决方案&#xff0c;是我个人和我司「七月在线」的职责之一 且个人认为&#xff0c…...