ROS使用(5)action学习
action消息的构建
首先进行功能包的创建
mkdir -p ros2_ws/src
cd ros2_ws/src
ros2 pkg create action_tutorials_interfaces
action消息的类型
# Request
---
# Result
---
# Feedback
动作定义由三个消息定义组成,以---分隔。
- 从动作客户机向动作服务器发送请求消息以启动新目标。
- 当目标完成时,从动作服务器向动作客户端发送结果消息。
- 反馈消息周期性地从动作服务器发送到动作客户端,其中包含关于目标的更新。
创建消息
cd action_tutorials_interfaces
mkdir action
创建一个Fibonacci.action文件指定action的消息
int32 order
---
int32[] sequence
---
int32[] partial_sequence
编译消息
在我们可以在代码中使用新的Fibonacci动作类型之前,我们必须将定义传递给Rosidl代码生成管道。这可以通过在CMakeLists.txt中的ament_package()行之前添加以下行来实现,即action_tutorials_interfaces中的行:
CMAkeLists.txt文件进行修改
find_package(rosidl_default_generators REQUIRED)rosidl_generate_interfaces(${PROJECT_NAME}"action/Fibonacci.action"
)
xml文件进行修改
<buildtool_depend>rosidl_default_generators</buildtool_depend><depend>action_msgs</depend><member_of_group>rosidl_interface_packages</member_of_group>
在这里action文件就算是生成了
action_server进行使用
进行action使用的功能包的创建
os2 pkg create --dependencies action_tutorials_interfaces rclcpp rclcpp_action rclcpp_components -- action_tutorials_cpp
action_tutorials_interfaces rclcpp rclcpp_action rclcpp_components为该功能包的相关依赖
windows编译
为了使软件包能够在Windows上编译和工作,我们需要添加一些“可见性控制”。有关详细信息,请参见Windows提示和技巧文档中的Windows符号可见性。
打开action_tutorials_cpp/include/action_tutorials_cpp/visibility_control.h,并将以下代码放入:
#ifndef ACTION_TUTORIALS_CPP__VISIBILITY_CONTROL_H_
#define ACTION_TUTORIALS_CPP__VISIBILITY_CONTROL_H_#ifdef __cplusplus
extern "C"
{
#endif// This logic was borrowed (then namespaced) from the examples on the gcc wiki:
// https://gcc.gnu.org/wiki/Visibility#if defined _WIN32 || defined __CYGWIN__#ifdef __GNUC__#define ACTION_TUTORIALS_CPP_EXPORT __attribute__ ((dllexport))#define ACTION_TUTORIALS_CPP_IMPORT __attribute__ ((dllimport))#else#define ACTION_TUTORIALS_CPP_EXPORT __declspec(dllexport)#define ACTION_TUTORIALS_CPP_IMPORT __declspec(dllimport)#endif#ifdef ACTION_TUTORIALS_CPP_BUILDING_DLL#define ACTION_TUTORIALS_CPP_PUBLIC ACTION_TUTORIALS_CPP_EXPORT#else#define ACTION_TUTORIALS_CPP_PUBLIC ACTION_TUTORIALS_CPP_IMPORT#endif#define ACTION_TUTORIALS_CPP_PUBLIC_TYPE ACTION_TUTORIALS_CPP_PUBLIC#define ACTION_TUTORIALS_CPP_LOCAL
#else#define ACTION_TUTORIALS_CPP_EXPORT __attribute__ ((visibility("default")))#define ACTION_TUTORIALS_CPP_IMPORT#if __GNUC__ >= 4#define ACTION_TUTORIALS_CPP_PUBLIC __attribute__ ((visibility("default")))#define ACTION_TUTORIALS_CPP_LOCAL __attribute__ ((visibility("hidden")))#else#define ACTION_TUTORIALS_CPP_PUBLIC#define ACTION_TUTORIALS_CPP_LOCAL#endif#define ACTION_TUTORIALS_CPP_PUBLIC_TYPE
#endif#ifdef __cplusplus
}
#endif#endif // ACTION_TUTORIALS_CPP__VISIBILITY_CONTROL_H_
创建server文件
#include <functional>
#include <memory>
#include <thread>#include "action_tutorials_interfaces/action/fibonacci.hpp"
#include "rclcpp/rclcpp.hpp"
#include "rclcpp_action/rclcpp_action.hpp"
#include "rclcpp_components/register_node_macro.hpp"#include "action_tutorials_cpp/visibility_control.h"namespace action_tutorials_cpp
{// 进行节点的创建
class FibonacciActionServer : public rclcpp::Node
{
public:// 声明数据类型using Fibonacci = action_tutorials_interfaces::action::Fibonacci;using GoalHandleFibonacci = rclcpp_action::ServerGoalHandle<Fibonacci>;ACTION_TUTORIALS_CPP_PUBLICexplicit FibonacciActionServer(const rclcpp::NodeOptions & options = rclcpp::NodeOptions()): Node("fibonacci_action_server", options){using namespace std::placeholders;// 创建对应的服务this->action_server_ = rclcpp_action::create_server<Fibonacci>(this,"fibonacci",// 用于处理目标的回调函数std::bind(&FibonacciActionServer::handle_goal, this, _1, _2),// 用于处理取消的回调函数std::bind(&FibonacciActionServer::handle_cancel, this, _1),// 用于处理目标接受的回调函数std::bind(&FibonacciActionServer::handle_accepted, this, _1));}private:rclcpp_action::Server<Fibonacci>::SharedPtr action_server_;rclcpp_action::GoalResponse handle_goal(const rclcpp_action::GoalUUID & uuid,std::shared_ptr<const Fibonacci::Goal> goal){RCLCPP_INFO(this->get_logger(), "Received goal request with order %d", goal->order);(void)uuid;return rclcpp_action::GoalResponse::ACCEPT_AND_EXECUTE;}rclcpp_action::CancelResponse handle_cancel(const std::shared_ptr<GoalHandleFibonacci> goal_handle){RCLCPP_INFO(this->get_logger(), "Received request to cancel goal");(void)goal_handle;return rclcpp_action::CancelResponse::ACCEPT;}void handle_accepted(const std::shared_ptr<GoalHandleFibonacci> goal_handle){using namespace std::placeholders;// this needs to return quickly to avoid blocking the executor, so spin up a new threadstd::thread{std::bind(&FibonacciActionServer::execute, this, _1), goal_handle}.detach();}void execute(const std::shared_ptr<GoalHandleFibonacci> goal_handle){RCLCPP_INFO(this->get_logger(), "Executing goal");rclcpp::Rate loop_rate(1);const auto goal = goal_handle->get_goal();auto feedback = std::make_shared<Fibonacci::Feedback>();auto & sequence = feedback->partial_sequence;sequence.push_back(0);sequence.push_back(1);auto result = std::make_shared<Fibonacci::Result>();for (int i = 1; (i < goal->order) && rclcpp::ok(); ++i) {// Check if there is a cancel requestif (goal_handle->is_canceling()) {result->sequence = sequence;goal_handle->canceled(result);RCLCPP_INFO(this->get_logger(), "Goal canceled");return;}// Update sequencesequence.push_back(sequence[i] + sequence[i - 1]);// Publish feedbackgoal_handle->publish_feedback(feedback);RCLCPP_INFO(this->get_logger(), "Publish feedback");loop_rate.sleep();}// Check if goal is doneif (rclcpp::ok()) {result->sequence = sequence;goal_handle->succeed(result);RCLCPP_INFO(this->get_logger(), "Goal succeeded");}}
}; // class FibonacciActionServer} // namespace action_tutorials_cppRCLCPP_COMPONENTS_REGISTER_NODE(action_tutorials_cpp::FibonacciActionServer)
几个关键的数据类型
ClientGoalHandle:
用于与客户端发送过来的目标进行交互。可以使用此类检查目标的状态和结果,这个类不是通过用户创建的,而是在目标进行接受。
// 使用这个类去检查goal 的状态和这个结果,并不意味着被用户创建,当一个用户的goal被接受的时候才能被创建
template<typename ActionT>
class ServerGoalHandle : public ServerGoalHandleBase
{
public:
// 发送一个更新数据,处理真个进行关于goal目标的
// 这个函数只能当goal被调用的时候才能被调用
// voidpublish_feedback(std::shared_ptr<typename ActionT::Feedback> feedback_msg){auto feedback_message = std::make_shared<typename ActionT::Impl::FeedbackMessage>();feedback_message->goal_id.uuid = uuid_;feedback_message->feedback = *feedback_msg;publish_feedback_(feedback_message);}
// 当goal无法达到,并且已中止。
// 只有当goal正在执行但无法完成时才调用此函数。
// 这是一个终端状态,在这之后不应该再对目标句柄调用任何方法
// param[in]result_msg要发送给客户端的最终结果。voidabort(typename ActionT::Result::SharedPtr result_msg){_abort();auto response = std::make_shared<typename ActionT::Impl::GetResultService::Response>();response->status = action_msgs::msg::GoalStatus::STATUS_ABORTED;response->result = *result_msg;on_terminal_state_(uuid_, response);}/// 当这个goal执行成功的时候执行
// param[in] result_msg the final result to send to clients.voidsucceed(typename ActionT::Result::SharedPtr result_msg){_succeed();auto response = std::make_shared<typename ActionT::Impl::GetResultService::Response>();response->status = action_msgs::msg::GoalStatus::STATUS_SUCCEEDED;response->result = *result_msg;on_terminal_state_(uuid_, response);}/// Indicate that a goal has been canceled./*** Only call this if the goal is executing or pending, but has been canceled.* This is a terminal state, no more methods should be called on a goal handle after this is* called.* \throws rclcpp::exceptions::RCLError If the goal is in any state besides executing.** \param[in] result_msg the final result to send to clients.*/voidcanceled(typename ActionT::Result::SharedPtr result_msg){_canceled();auto response = std::make_shared<typename ActionT::Impl::GetResultService::Response>();response->status = action_msgs::msg::GoalStatus::STATUS_CANCELED;response->result = *result_msg;on_terminal_state_(uuid_, response);}/// Indicate that the server is starting to execute a goal.
// throws rclcpp::exceptions::RCLError If the goal is in any state besides executing.voidexecute(){_execute();on_executing_(uuid_);}/// Get the user provided message describing the goal.const std::shared_ptr<const typename ActionT::Goal>get_goal() const{return goal_;}/// Get the unique identifier of the goalconst GoalUUID &get_goal_id() const{return uuid_;}virtual ~ServerGoalHandle(){// Cancel goal if handle was allowed to destruct without reaching a terminal stateif (try_canceling()) {auto null_result = std::make_shared<typename ActionT::Impl::GetResultService::Response>();null_result->status = action_msgs::msg::GoalStatus::STATUS_CANCELED;on_terminal_state_(uuid_, null_result);}}protected:/// \internalServerGoalHandle(std::shared_ptr<rcl_action_goal_handle_t> rcl_handle,GoalUUID uuid,std::shared_ptr<const typename ActionT::Goal> goal,std::function<void(const GoalUUID &, std::shared_ptr<void>)> on_terminal_state,std::function<void(const GoalUUID &)> on_executing,std::function<void(std::shared_ptr<typename ActionT::Impl::FeedbackMessage>)> publish_feedback): ServerGoalHandleBase(rcl_handle), goal_(goal), uuid_(uuid),on_terminal_state_(on_terminal_state), on_executing_(on_executing),publish_feedback_(publish_feedback){}/// The user provided message describing the goal.const std::shared_ptr<const typename ActionT::Goal> goal_;/// A unique id for the goal request.const GoalUUID uuid_;friend Server<ActionT>;std::function<void(const GoalUUID &, std::shared_ptr<void>)> on_terminal_state_;std::function<void(const GoalUUID &)> on_executing_;std::function<void(std::shared_ptr<typename ActionT::Impl::FeedbackMessage>)> publish_feedback_;
};
/// A response returned by an action server callback when a goal is requested.
enum class GoalResponse : int8_t
{/// The goal is rejected and will not be executed.REJECT = 1,/// The server accepts the goal, and is going to begin execution immediately.ACCEPT_AND_EXECUTE = 2,/// The server accepts the goal, and is going to execute it later.ACCEPT_AND_DEFER = 3,
};/// A response returned by an action server callback when a goal has been asked to be canceled.
enum class CancelResponse : int8_t
{/// The server will not try to cancel the goal.REJECT = 1,/// The server has agreed to try to cancel the goal.ACCEPT = 2,
};
action client定义
#include <functional>
#include <future>
#include <memory>
#include <string>
#include <sstream>#include "action_tutorials_interfaces/action/fibonacci.hpp"#include "rclcpp/rclcpp.hpp"
#include "rclcpp_action/rclcpp_action.hpp"
#include "rclcpp_components/register_node_macro.hpp"namespace action_tutorials_cpp
{
class FibonacciActionClient : public rclcpp::Node
{
public:using Fibonacci = action_tutorials_interfaces::action::Fibonacci;using GoalHandleFibonacci = rclcpp_action::ClientGoalHandle<Fibonacci>;explicit FibonacciActionClient(const rclcpp::NodeOptions & options): Node("fibonacci_action_client", options){this->client_ptr_ = rclcpp_action::create_client<Fibonacci>(this,"fibonacci");this->timer_ = this->create_wall_timer(std::chrono::milliseconds(500),std::bind(&FibonacciActionClient::send_goal, this));}void send_goal(){using namespace std::placeholders;this->timer_->cancel();if (!this->client_ptr_->wait_for_action_server()) {RCLCPP_ERROR(this->get_logger(), "Action server not available after waiting");rclcpp::shutdown();}auto goal_msg = Fibonacci::Goal();goal_msg.order = 10;RCLCPP_INFO(this->get_logger(), "Sending goal");auto send_goal_options = rclcpp_action::Client<Fibonacci>::SendGoalOptions();send_goal_options.goal_response_callback =std::bind(&FibonacciActionClient::goal_response_callback, this, _1);send_goal_options.feedback_callback =std::bind(&FibonacciActionClient::feedback_callback, this, _1, _2);send_goal_options.result_callback =std::bind(&FibonacciActionClient::result_callback, this, _1);this->client_ptr_->async_send_goal(goal_msg, send_goal_options);}private:rclcpp_action::Client<Fibonacci>::SharedPtr client_ptr_;rclcpp::TimerBase::SharedPtr timer_;void goal_response_callback(std::shared_future<GoalHandleFibonacci::SharedPtr> future){auto goal_handle = future.get();if (!goal_handle) {RCLCPP_ERROR(this->get_logger(), "Goal was rejected by server");} else {RCLCPP_INFO(this->get_logger(), "Goal accepted by server, waiting for result");}}void feedback_callback(GoalHandleFibonacci::SharedPtr,const std::shared_ptr<const Fibonacci::Feedback> feedback){std::stringstream ss;ss << "Next number in sequence received: ";for (auto number : feedback->partial_sequence) {ss << number << " ";}RCLCPP_INFO(this->get_logger(), ss.str().c_str());}void result_callback(const GoalHandleFibonacci::WrappedResult & result){switch (result.code) {case rclcpp_action::ResultCode::SUCCEEDED:break;case rclcpp_action::ResultCode::ABORTED:RCLCPP_ERROR(this->get_logger(), "Goal was aborted");return;case rclcpp_action::ResultCode::CANCELED:RCLCPP_ERROR(this->get_logger(), "Goal was canceled");return;default:RCLCPP_ERROR(this->get_logger(), "Unknown result code");return;}std::stringstream ss;ss << "Result received: ";for (auto number : result.result->sequence) {ss << number << " ";}RCLCPP_INFO(this->get_logger(), ss.str().c_str());rclcpp::shutdown();}
}; // class FibonacciActionClient} // namespace action_tutorials_cppRCLCPP_COMPONENTS_REGISTER_NODE(action_tutorials_cpp::FibonacciActionClient)
配置对应的CMakeLists.txt文件
add_library(action_server SHAREDsrc/fibonacci_action_server.cpp)
target_include_directories(action_server PRIVATE$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include>$<INSTALL_INTERFACE:include>)
target_compile_definitions(action_serverPRIVATE "ACTION_TUTORIALS_CPP_BUILDING_DLL")
ament_target_dependencies(action_server"action_tutorials_interfaces""rclcpp""rclcpp_action""rclcpp_components")
rclcpp_components_register_node(action_server PLUGIN "action_tutorials_cpp::FibonacciActionServer" EXECUTABLE fibonacci_action_server)
install(TARGETSaction_serverARCHIVE DESTINATION libLIBRARY DESTINATION libRUNTIME DESTINATION bin)add_library(action_client SHAREDsrc/fibonacci_action_client.cpp)
target_include_directories(action_client PRIVATE$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include>$<INSTALL_INTERFACE:include>)
target_compile_definitions(action_clientPRIVATE "ACTION_TUTORIALS_CPP_BUILDING_DLL")
ament_target_dependencies(action_client"action_tutorials_interfaces""rclcpp""rclcpp_action""rclcpp_components")
rclcpp_components_register_node(action_client PLUGIN "action_tutorials_cpp::FibonacciActionClient" EXECUTABLE fibonacci_action_client)
install(TARGETSaction_clientARCHIVE DESTINATION libLIBRARY DESTINATION libRUNTIME DESTINATION bin)
通过编译之后就可以得到对应的模型
相关文章:
ROS使用(5)action学习
action消息的构建 首先进行功能包的创建 mkdir -p ros2_ws/src cd ros2_ws/src ros2 pkg create action_tutorials_interfaces action消息的类型 # Request --- # Result --- # Feedback 动作定义由三个消息定义组成,以---分隔。 从动作客户机向动作服务器发送…...
2023前端面试题集(含答案)之HTML+CSS篇(一)
在又到了金三银四的招聘季,不管你是刚入行的小白,亦或是混迹职场的老鸟,还在为面试前端工程师时不知道面试官要问什么怎么回答而苦恼吗?为了帮助你获得面试官的青睐,顺利通过面试,跳槽进入大厂,…...
设计模式2 - 观察者模式
定义: 观察者模式又叫发布订阅模式,它定义了对象之间的一对多依赖,这样一来,当一个对象改变状态时,它的所有依赖者都会收到通知并自动更新。 组成: Subject(通知者/被观察者)&#…...
ini配置文件
ini配置文件 ini文件是initialization file的缩写,即初始化文件,是widows系统配置文件所采用的存储格式。 文件扩展名: .ini ini配置文件的后缀名也不一定必须是.ini, 也可以是.cfg, .conf或者是.txt ini文件格式 ini配置文件由参数, 节, 注解组成 参…...
蓝桥杯备赛经验 pythonA组(非科班选手)
个人2022 CA组江苏省一等奖,决赛成绩不理想,没有拿到一二等奖,但是因为自己是非科班的学生,所以能拿到这样的成绩自己其实也应该知足了 题外话: 很多ACMer嘲笑蓝桥杯非常水,但是据我观察CA组决赛一等奖获奖…...

C++实现通讯录管理系统
通讯录是一个可以记录亲人、好友信息的工具,本博客借助黑马程序员的项目进行修改,利用C实现一个通讯录管理系统,旨在复习C的语法。 一、系统需求 系统需要实现的功能如下: 添加联系人∶向通讯录中添加新人,信息包括…...

开关电源Y电容放置的位置
Y电容,是我们工程师做开关电源设计时都要接触到的一个非常关键的元器件,它对EMI的贡献是相当的大的,但是它是一个较难把控的元器件,原理上并没有那么直观易懂,在EMI传播路径中需要联系到很多的寄生参数才能够去分析。 …...

二叉树的最小深度——递归法、迭代法
1题目给定一个二叉树,找出其最小深度。最小深度是从根节点到最近叶子节点的最短路径上的节点数量。说明:叶子节点是指没有子节点的节点。示例 1:输入:root [3,9,20,null,null,15,7]输出:2示例 2:输入&…...
Vue中常使用的三种刷新页面的方式
一、通过js原始方法刷新 缺点: 出现闪白 目录 一、通过js原始方法刷新 二、通过Vue自带的路由进行跳转 三、通过在APP页面进行demo进行刷新(推荐) 1.vue2写法 2. vue3.2写法 <template><div><div class"header"><button clic…...

【Shell】脚本
Shell脚本脚本格式第一个Shell脚本:hello.sh脚本常用执行方式1. bash或sh脚本的相对路径或绝对路径2. 输入脚本的绝对路径或相对路径3. 在脚本的路径前加上.或者source脚本格式 脚本以#!/bin/bash开头(指定解析器) #! 是一个约定的标记&…...
Mybatis的多表操作
1.Mybatis多表查询 1.1一对一查询 1.一对一查询的模型 用户表和订单表的关系为,一个用户有多个订单,一个订单只从属于一个用户 一对一查询的需求:查询一个订单,与此同时查询出该订单所属的用户2.创建Order和User实体public class…...
【JVM】字节码指令全解
文章目录 入门案例原始 java 代码编译后的字节码文件常量池载入运行时常量池方法字节码载入方法区main 线程开始运行,分配栈帧内存执行引擎开始执行字节码bipush 10istore_1ldc #3istore_2iload_1iload_2iaddistore_3getstatic #4iload_3invokevirtual #5return条件判断指令循…...

【精品】华为认证数通HCIA+HCIP题库分享(含答案解析)
嗨~大家好久不见,我是薄荷学姐,随着华为业务也全球领域的迅猛发展,越来越多人开始重视华为认证的重要性。今天给大家分享一下去年8月份的题库,基本都是一样,希望可以帮助到大家哈想要通过华为认证,除了进行…...
Qt cmake 资源文件的加载
Qt cmake 资源文件的加载概述qt_add_resourcesqt5_add_resourcesqt6_add_resources是否需要加载qrc文件需要加载qrc的情况不需要加载qrc的情况C 代码加载示例加载PNG加载CSS文件加载qrc文件Qt6相对于Qt5的一些变化Qt6和Qt5在加载资源文件方面的区别主要集中在两个方面ÿ…...

【链表OJ题(九)】环形链表延伸问题以及相关OJ题
环形链表OJ题 1. 环形链表 链接:141. 环形链表 描述: 给你一个链表的头节点 head ,判断链表中是否有环。 如果链表中有某个节点,可以通过连续跟踪 next 指针再次到达,则链表中存在环。 为了表示给定链表中的环&…...

【C++初阶】四、类和对象(下)
文章目录一、再谈构造函数构造函数体赋值初始化列表explicit关键字二、Static成员引入- 计算类中创建了多少个类对象概念特性静态成员函数的访问三、友元友元函数友元类四、内部类五、匿名对象六、拷贝对象时的一些编译器优化一、再谈构造函数 构造函数体赋值 在创建对象时&a…...

IDEA maven没有Import Maven projects automatically解决办法
去年装了个 IDEA2022版本 配置maven时我才发现是个大坑 他没有import Maven projects automatically配置项 当时看到我人都麻了 然后项目呢 用了依赖 这东西还不会自动下依赖 整的我那是相当难受 还在最后还是找到了解决办法 我们在配置文件上点击右键 然后鼠标选择如下图选项…...

Java实习生------MySQL10道面试题打卡
今日语录:“没有执行力,就没有竞争力 ”🌹 参考资料:图解MySQL、MySQL面试题 1、事务有哪些特性? 原子性: 一个事务中的所有操作,要么全部完成,要么全部不完成,不会出现…...
帆软报表设计器 数据集之数据库查询
当点击数据库查询时,调用TableDataTreePane的 public void actionPerformed(ActionEvent var1) {TableDataTreePane.this.dgEdit(this.getTableDataInstance().creatTableDataPane(), TableDataTreePane.this.createDsName(this.getNamePrefix()), false);} 然后调用TableDat…...
CSDN 第三十七期竞赛题解
很少有时间来玩玩题目,上一次因为环境极为嘈杂的原因在时间上没有进入前十,挺遗憾的。 在 CSDN 参加的第一次没出锅的比赛。 大概只有最后一题值得好好讲讲。 T1:幼稚班作业 幼稚园终于又有新的作业了。 老师安排同学用发给同学的4根木棒拼接…...

Linux相关概念和易错知识点(42)(TCP的连接管理、可靠性、面临复杂网络的处理)
目录 1.TCP的连接管理机制(1)三次握手①握手过程②对握手过程的理解 (2)四次挥手(3)握手和挥手的触发(4)状态切换①挥手过程中状态的切换②握手过程中状态的切换 2.TCP的可靠性&…...

自然语言处理——循环神经网络
自然语言处理——循环神经网络 循环神经网络应用到基于机器学习的自然语言处理任务序列到类别同步的序列到序列模式异步的序列到序列模式 参数学习和长程依赖问题基于门控的循环神经网络门控循环单元(GRU)长短期记忆神经网络(LSTM)…...
全面解析各类VPN技术:GRE、IPsec、L2TP、SSL与MPLS VPN对比
目录 引言 VPN技术概述 GRE VPN 3.1 GRE封装结构 3.2 GRE的应用场景 GRE over IPsec 4.1 GRE over IPsec封装结构 4.2 为什么使用GRE over IPsec? IPsec VPN 5.1 IPsec传输模式(Transport Mode) 5.2 IPsec隧道模式(Tunne…...
蓝桥杯 冶炼金属
原题目链接 🔧 冶炼金属转换率推测题解 📜 原题描述 小蓝有一个神奇的炉子用于将普通金属 O O O 冶炼成为一种特殊金属 X X X。这个炉子有一个属性叫转换率 V V V,是一个正整数,表示每 V V V 个普通金属 O O O 可以冶炼出 …...

C++ 设计模式 《小明的奶茶加料风波》
👨🎓 模式名称:装饰器模式(Decorator Pattern) 👦 小明最近上线了校园奶茶配送功能,业务火爆,大家都在加料: 有的同学要加波霸 🟤,有的要加椰果…...

ui框架-文件列表展示
ui框架-文件列表展示 介绍 UI框架的文件列表展示组件,可以展示文件夹,支持列表展示和图标展示模式。组件提供了丰富的功能和可配置选项,适用于文件管理、文件上传等场景。 功能特性 支持列表模式和网格模式的切换展示支持文件和文件夹的层…...
大数据治理的常见方式
大数据治理的常见方式 大数据治理是确保数据质量、安全性和可用性的系统性方法,以下是几种常见的治理方式: 1. 数据质量管理 核心方法: 数据校验:建立数据校验规则(格式、范围、一致性等)数据清洗&…...

医疗AI模型可解释性编程研究:基于SHAP、LIME与Anchor
1 医疗树模型与可解释人工智能基础 医疗领域的人工智能应用正迅速从理论研究转向临床实践,在这一过程中,模型可解释性已成为确保AI系统被医疗专业人员接受和信任的关键因素。基于树模型的集成算法(如RandomForest、XGBoost、LightGBM)因其卓越的预测性能和相对良好的解释性…...
从零手写Java版本的LSM Tree (一):LSM Tree 概述
🔥 推荐一个高质量的Java LSM Tree开源项目! https://github.com/brianxiadong/java-lsm-tree java-lsm-tree 是一个从零实现的Log-Structured Merge Tree,专为高并发写入场景设计。 核心亮点: ⚡ 极致性能:写入速度超…...
41道Django高频题整理(附答案背诵版)
解释一下 Django 和 Tornado 的关系? Django和Tornado都是Python的web框架,但它们的设计哲学和应用场景有所不同。 Django是一个高级的Python Web框架,鼓励快速开发和干净、实用的设计。它遵循MVC设计,并强调代码复用。Django有…...