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

多无人车协同探索开源包启动文件介绍(上)


   在之前介绍的《多无人车协同探索开源包部署教程及常见报错解决方式》中运行多无人车协同探索时,先后运行了两个launch文件 multiple_tb3_house.launch 和three_robots.launch ,本文来进一步看一下这两个启动文件以及其调用的move_base .launch 和multi_tb3_mapmerge.launch 都做哪些操作以及如何根据自己的需要进行相应的修改。

   由于内容较多,拆分成(上)、(下)两篇博客,链接如下:

   多无人车协同探索开源包启动文件介绍(上)

   多无人车协同探索开源包启动文件介绍(下)


   一、multiple_tb3_house.launch 详细介绍

   multiple_tb3_house.launch用于启动一个包含三个TurtleBot3机器人的多机器人系统,并在Gazebo仿真环境中运行。下面是对各个部分的详细解释:

1. 参数定义(Arguments)

<arg name="model" default="waffle_pi" doc="model type [burger, waffle, waffle_pi]"/>
<arg name="move_forward_only" default="false"/>
<arg name="configuration_basename" default="turtlebot3_lds_2d.lua"/>
  • 这些<arg>元素定义了可以传递给启动文件的参数。
  • model:指定机器人模型的类型(如burgerwafflewaffle_pi)。
  • move_forward_only:一个布尔值参数,用于控制机器人是否只能前进(默认为false)。
  • configuration_basename:用于配置机器人的激光雷达(Lidar)设置的Lua文件。

2. TurtleBot3机器人初始位姿配置

每个机器人都通过多个<arg>元素来定义其名称、位置和方向:

<arg name='third_tb3' default="tb3_0"/>
<arg name="third_tb3_x_pos" default=" 0.9"/>
<arg name="third_tb3_y_pos" default=" 3.3"/>
<arg name="third_tb3_z_pos" default=" 0.0"/>
<arg name="third_tb3_yaw"   default=" 0.0"/><arg name='first_tb3' default="tb3_1"/>
<arg name="first_tb3_x_pos" default="0.9"/>
<arg name="first_tb3_y_pos" default=" 1.7"/>
<arg name="first_tb3_z_pos" default=" 0.0"/>
<arg name="first_tb3_yaw"   default=" 0.0"/><arg name='second_tb3' default="tb3_2"/>
<arg name="second_tb3_x_pos" default=" 0.9"/>
<arg name="second_tb3_y_pos" default=" 2.5"/>
<arg name="second_tb3_z_pos" default=" 0.0"/>
<arg name="second_tb3_yaw"   default=" 0.0"/>
  • 这些参数分别定义了三个机器人的名称和位置(xyz坐标)以及航向(yaw角度)。

-----------------------------------------------☆☆☆常改动参数☆☆☆-----------------------------------------------------

   这组参数用于设定机器人的初始位姿,是经常用到的需要修改的参数之一,下面动图的实例中,我将tb3_0机器人的初始位置的x和y坐标从0.9,3.3 改到了 5.9,1.3,可以看到该机器人的初始位置发生了改变

在这里插入图片描述

-----------------------------------------------------------------------------------------------------------------------------------------

3. Gazebo仿真环境配置

<include file="$(find gazebo_ros)/launch/empty_world.launch"><arg name="world_name" value="$(find ros_multi_tb3)/worlds/turtlebot3_house_mod.world"/><arg name="paused" value="false"/><arg name="use_sim_time" value="true"/><arg name="gui" value="false"/><arg name="headless" value="false"/><arg name="debug" value="false"/>
</include>
  • 这一部分中的empty_world.launch文件,一般是默认的,会根据传递的参数自动启动 Gazebo 的服务器和客户端(gzserver 和 gzclient),不需要修该。
  • world_name 用于启动Gazebo仿真环境并加载一个自定义的世界文件(turtlebot3_house_mod.world)。
  • 启用了仿真时间(use_sim_time="true"),并且禁用了图形界面(gui="false")。

-----------------------------------------------☆☆☆常改动参数☆☆☆-----------------------------------------------------

   这组参数中最常改动的参数是用于设定加载的仿真环境文件的world_name参数,下面动图的实例中,我将项目默认的仿真环境文件,换成了我之前创建的放在功能包racecar_description的worlds文件夹下的名为complex.world的文件,效果如下所示

下面的例子中将
<arg name="world_name" value="$(find ros_multi_tb3)/worlds/turtlebot3_house_mod.world"/>
改为了
<arg name="world_name" value="$(find racecar_description)/worlds/complex.world"/>

在这里插入图片描述

   这组参数中的gui参数有时候也需要根据需求进行修该,项目默认给定的值是false,这意味着 Gazebo 启动时不会显示图形界面(即使有 gzclient 启动)即看不到gazebo的界面,这样做主要是为了节省计算资源。如果你希望将 Gazebo 的可视化界面显示出来,应该将 gui 设置为 true

-----------------------------------------------------------------------------------------------------------------------------------------

4. 设定机器人模型和状态发布(每个机器人)

每个机器人都有一个<group>部分,包含以下几个关键组件:

 <group ns = "$(arg first_tb3)">
  • URDF描述:加载机器人的描述文件(.xacro文件),定义机器人模型。

    <param name="robot_description" command="$(find xacro)/xacro $(find ros_multi_tb3)/urdf/turtlebot3_waffle_pi.urdf.xacro botname:=$(arg first_tb3)" />
    
  • 机器人状态发布器:将机器人的状态信息(如关节状态)发布到ROS网络中。

    <node pkg="robot_state_publisher" type="robot_state_publisher" name="robot_state_publisher" output="screen"><param name="publish_frequency" type="double" value="50.0" /><param name="tf_prefix" value="$(arg first_tb3)" />
    </node>
    
  • 模型生成:在Gazebo中生成机器人模型,设置其位置(xyz)和航向(yaw)。

    <node name="spawn_urdf" pkg="gazebo_ros" type="spawn_model" args="-urdf -model $(arg first_tb3) -x $(arg first_tb3_x_pos) -y $(arg first_tb3_y_pos) -z $(arg first_tb3_z_pos) -Y $(arg first_tb3_yaw) -param robot_description" />
    

-----------------------------------------------☆☆☆关于命名空间ns☆☆☆-----------------------------------------------

   在 ROS (Robot Operating System) 中,ns 是命名空间 (namespace) 的缩写。它用于对 ROS系统中的节点、话题、参数等进行分组和命名。通过使用命名空间,可以避免在多机器人系统中出现命名冲突,使得每个机器人的资源可以独立管理。

xml <group ns = "$(arg first_tb3)">

上面这行代码表示将该 group 中的所有节点、参数等,都放入 first_tb3 命名空间内。作用如下:

(1) 避免命名冲突 在多机器人系统中,每个机器人可能有相同的资源(例如:cmd_velodombase_footprint
等),这些资源的名字会冲突。使用命名空间可以确保每个机器人的话题、服务等在名称上是唯一的。例如:

  • 对于机器人 tb3_0cmd_vel 话题可能是 /tb3_0/cmd_vel
  • 对于机器人 tb3_1cmd_vel 话题可能是 /tb3_1/cmd_vel
    这样,即使它们的名字相同,命名空间的使用使得它们在 ROS 系统中是独立的。

(2) 自动为节点和话题加前缀group 标签中使用 ns 后,ROS 会自动将该命名空间加到所有节点、话题、参数等的名称前缀。例如对第一个机器人而言:

  • robot_state_publisher 的节点名称将是 /first_tb3/robot_state_publisher
  • spawn_model 的模型名称将是 /first_tb3/spawn_model
  • cmd_vel 话题的名称将是 /first_tb3/cmd_vel
  • slam_gmapping 的参数 base_frame 会变成 /first_tb3/base_footprint
    这确保了不同机器人的节点和话题在系统中是独立的。

(3)参数和话题的作用域控制 命名空间也控制了参数和话题的作用域。比如说,当你发布一个话题或设置一个参数时,它会根据命名空间确定话题的前缀或者参数的路径,从而确保同一系统中的多个机器人不会干扰彼此。

  总的来说: ns 将该组节点、话题和参数放入一个特定的命名空间中,使得它们可以在多机器人系统中区分开来。通过命名空间的使用,可以避免话题、参数或节点名的冲突。

----------------------------------------------------------------------------------------------------------------------------------------

-----------------------------------------------☆☆☆常改动参数☆☆☆-----------------------------------------------------

   这组参数中的robot_description参数用于设定加载机器人模型描述文件(.xacro文件),如果需要改用其他机器人模型,则需要对该参数进行修改

-----------------------------------------------------------------------------------------------------------------------------------------

5. SLAM(同步定位与建图)配置

对于每个机器人,都有一个gmapping节点来进行2D SLAM操作,并加载一个配置文件(gmapping_params.yaml),如果想要修改gmapping建图的相关参数,可以对gmapping_params.yaml文件进行修改

<node pkg="gmapping" type="slam_gmapping" name="turtlebot3_slam_gmapping" output="screen"><param name="base_frame" value="$(arg first_tb3)/base_footprint"/><param name="odom_frame" value="$(arg first_tb3)/odom"/><param name="map_frame"  value="$(arg first_tb3)/map"/><rosparam command="load" file="$(find ros_multi_tb3)/configuration/gmapping_params.yaml" />
</node>

6. 机器人运动控制(Move Base)

每个机器人都有一个move_base节点,用于运动规划和控制。它接收来自cmd_vel话题的指令,并在机器人的命名空间下操作,这里move_base节点是通过move_base.launch文件进行配置的,该部分内容将在第二部分中进行展开介绍:

<include file="$(find ros_multi_tb3)/launch/includes/move_base.launch"><arg name="model" value="$(arg model)" /><arg name="move_forward_only" value="$(arg move_forward_only)"/><arg name="cmd_vel_topic" value="/$(arg first_tb3)/cmd_vel"/><arg name="namespace" value="$(arg first_tb3)"/>
</include>

7. 地图合并

通过一个单独的启动文件(multi_tb3_mapmerge.launch)来合并所有机器人生成的地图,该部分内容将在本文第三部分中进行介绍,这里主要是将三个机器人的名字和初始位姿参数传入了multi_tb3_mapmerge.launch文件中。

<include file="$(find ros_multi_tb3)/launch/includes/multi_tb3_mapmerge.launch"><arg name="model" value="$(arg model)" /><arg name="move_forward_only" value="$(arg move_forward_only)"/><arg name="first_tb3" value="$(arg first_tb3)"/><arg name="second_tb3" value="$(arg second_tb3)"/><arg name="third_tb3" value="$(arg third_tb3)"/><arg name="first_tb3_x_pos" default="$(arg first_tb3_x_pos)"/><arg name="first_tb3_y_pos" default="$(arg first_tb3_y_pos)"/><arg name="first_tb3_z_pos" default="$(arg first_tb3_z_pos)"/><arg name="first_tb3_yaw"   default="$(arg first_tb3_yaw)"/><arg name="second_tb3_x_pos" default="$(arg second_tb3_x_pos)"/><arg name="second_tb3_y_pos" default="$(arg second_tb3_y_pos)"/><arg name="second_tb3_z_pos" default="$(arg second_tb3_z_pos)"/><arg name="second_tb3_yaw"   default="$(arg second_tb3_yaw)"/><arg name="third_tb3_x_pos" default="$(arg third_tb3_x_pos)"/><arg name="third_tb3_y_pos" default="$(arg third_tb3_y_pos)"/><arg name="third_tb3_z_pos" default="$(arg third_tb3_z_pos)"/><arg name="third_tb3_yaw"   default="$(arg third_tb3_yaw)"/>
</include>

8. TF(坐标变换)发布器

这一部分设置了不同坐标框架之间的静态变换(如从map框架到每个机器人本地map框架),用于对齐机器人的地图和坐标。

<node pkg="tf" type="static_transform_publisher" name="world_to_mergedmap_tf_broadcaster"  args="0.385 0.385 0 0 0 0 world map 20"/>
<!-- <node pkg="tf" type="static_transform_publisher" name="world_to_mergedmap_tf_broadcaster"  args="0 0 0 0 0 0 world map 100"/> -->
<node pkg="tf" type="static_transform_publisher" name="world_to_$(arg first_tb3)_tf_broadcaster"  args="0 0 0 0 0 0 /map /$(arg first_tb3)/map 20"/>
<node pkg="tf" type="static_transform_publisher" name="world_to_$(arg second_tb3)_tf_broadcaster" args="0 0 0 0 0 0 /map /$(arg second_tb3)/map 20"/>
<node pkg="tf" type="static_transform_publisher" name="world_to_$(arg third_tb3)_tf_broadcaster"  args="0 0 0 0 0 0 /map /$(arg third_tb3)/map 20"/>

-----------------------------------------------☆☆☆关于静态tf变换☆☆☆-----------------------------------------------

   这部分代码涉及到 ROS 中 static_transform_publisher 节点的使用,主要目的是发布静态变换(static transforms)以描述不同坐标框架之间的关系。具体来说,它们是在不同坐标系之间发布静态的位移和旋转信息,帮助 ROS 系统中的其他节点理解各个坐标系的相对位置。

下面对上面的四个变化逐个进行详细的解释 :
(1) 发布全局坐标系到合并地图坐标系的静态变换 xml <node pkg="tf" type="static_transform_publisher" name="world_to_mergedmap_tf_broadcaster" args="0.385 0.385 0 0 0 0 world map 20"/>

  • pkg="tf": 使用 tf 包中的 static_transform_publisher 类型节点。
  • type="static_transform_publisher": 该节点负责发布静态坐标变换。
  • name="world_to_mergedmap_tf_broadcaster": 节点的名称,用于标识该节点。
  • args="0.385 0.385 0 0 0 0 world map 20": 这里的 args 参数表示发布的静态变换的具体参数:
    • 0.385 0.385 0: 变换的平移部分(x, y, z),即坐标系从 worldmap 的平移位移。
    • 0 0 0: 变换的旋转部分(roll, pitch, yaw)。这里是零,表示没有旋转。
    • world: 源坐标系,即原始坐标系是 world
    • map: 目标坐标系,变换之后的坐标系是 map
    • 20: 发布变换的频率,表示每秒发布20次。

   这个节点的作用是将 world 坐标系变换到 map 坐标系,并且发布这个变换。这样,map 坐标系的位置和方向相对于 world 坐标系就明确了。

(2) 发布从 worldfirst_tb3 的静态变换 xml <node pkg="tf" type="static_transform_publisher" name="world_to_$(arg first_tb3)_tf_broadcaster" args="0 0 0 0 0 0 /map /$(arg first_tb3)/map 20"/>

  • name="world_to_$(arg first_tb3)_tf_broadcaster": 这里,$(arg first_tb3) 表示将参数 first_tb3 的值插入到节点的名字中,生成一个动态的节点名称。假设 first_tb3
    的值为 tb3_0,那么节点的名称就是 world_to_tb3_0_tf_broadcaster
  • args="0 0 0 0 0 0 /map /$(arg first_tb3)/map 20": 变换的参数:
    • 0 0 0: 平移部分,表示没有位移(x, y, z)。
    • 0 0 0: 旋转部分,表示没有旋转(roll, pitch, yaw)。
    • /map: 源坐标系,即 map 坐标系。
    • /$(arg first_tb3)/map: 目标坐标系,通过 $(arg first_tb3) 动态生成目标坐标系的名称。例如,如果 first_tb3tb3_0,那么目标坐标系就是 /tb3_0/map
    • 20: 发布频率,20 次每秒。

   这个节点的作用是将全局 map 坐标系和 first_tb3 机器人(例如 tb3_0)的 map坐标系之间的变换信息进行广播。

(3) 发布从 worldsecond_tb3 的静态变换 xml <node pkg="tf" type="static_transform_publisher" name="world_to_$(arg second_tb3)_tf_broadcaster" args="0 0 0 0 0 0 /map /$(arg second_tb3)/map 20"/> 这一行与上面相似,只是目标坐标系变成了 second_tb3(例如 tb3_1)。具体来说,它的作用是发布 world 坐标系到 tb3_1map 坐标系之间的变换信息。

(4) 发布从 worldthird_tb3 的静态变换 xml <node pkg="tf" type="static_transform_publisher" name="world_to_$(arg third_tb3)_tf_broadcaster" args="0 0 0 0 0 0 /map /$(arg third_tb3)/map 20"/> 这行代码与上面两行类似,只不过是用于发布从 worldthird_tb3(例如 tb3_2)的 map 坐标系之间的变换信息。

  总的来说:这部分代码通过 static_transform_publisher 节点定义了三个静态变换,将全局 world 坐标系与多个机器人(tb3_0tb3_1tb3_2)的 map 坐标系之间的关系进行发布。每个变换节点都会发布其坐标系之间的平移和旋转关系(在本例中都是零旋转,零平移),帮助其他节点理解不同坐标系之间的相对位置。这些静态变换对于多机器人系统尤为重要,可以帮助系统中的各个部分正确地理解彼此的位置,尤其是在使用如 slam_gmappingmove_base 等节点时,坐标系转换是很关键的一部分。

9. RViz可视化

最后,启动RViz来进行机器人环境、地图和传感器数据的可视化:

<node pkg="rviz" type="rviz" name="rviz" required="true"args="-d $(find ros_multi_tb3)/rviz/multi_tb3_gmapping.rviz"/>

-----------------------------------------------☆☆☆常改动参数☆☆☆-----------------------------------------------------

   这里的multi_tb3_gmapping.rviz设定了打开的rviz界面的相关配置,如果想要更改配置,可以在rviz界面修该后,保存更新该文件,或者生成新的配置文件,并在这里修改文件名和路径。

-----------------------------------------------------------------------------------------------------------------------------------------

相关文章:

多无人车协同探索开源包启动文件介绍(上)

在之前介绍的《多无人车协同探索开源包部署教程及常见报错解决方式》中运行多无人车协同探索时&#xff0c;先后运行了两个launch文件 multiple_tb3_house.launch 和three_robots.launch &#xff0c;本文来进一步看一下这两个启动文件以及其调用的move_base .launch 和multi_t…...

Linux驱动学习笔记(三)

并发与竞争 1.在编写驱动程序的时候&#xff0c;要尽量避免让驱动程序存在并发和竞争&#xff0c;Linux内核里面提供了几种处理并发与竞争的方法&#xff0c;分别是&#xff1a;原子操作、自旋锁、信号量和互斥体。 原子操作&#xff1a;Linux的原子操作基于atomic_t数据类型…...

【QT5 多线程示例】互斥锁

互斥锁 互斥锁介绍&#xff1a;【C并发编程】&#xff08;三&#xff09;互斥锁&#xff1a;std::mutex。原理都一样&#xff0c;这里就不赘述了。 QMutex 是 Qt 框架中提供的一个互斥锁类&#xff0c;主要包括以下成员函数&#xff1a; lock()&#xff1a;试图锁定互斥量。…...

SaaS系统的销售微服务与权限微服务边界设计

在设计SaaS系统的销售微服务与权限微服务的边界时&#xff0c;需要结合领域驱动设计&#xff08;DDD&#xff09;和微服务拆分原则&#xff0c;确保高内聚、低耦合。以下是结合微服务架构原则、多租户SaaS需求及权限管理场景的完整设计方案&#xff0c;整合了权限服务与销售服务…...

leetcode热题100道——两数之和

给定一个整数数组 nums 和一个整数目标值 target&#xff0c;请你在该数组中找出 和为目标值 target 的那 两个 整数&#xff0c;并返回它们的数组下标。 你可以假设每种输入只会对应一个答案&#xff0c;并且你不能使用两次相同的元素。 你可以按任意顺序返回答案。 示例 1…...

C语言经典代码练习题

1.输入一个4位数&#xff1a;输出这个输的个位 十位 百位 千位 #include <stdio.h> int main(int argc, char const *argv[]) {int a;printf("输入一个&#xff14;位数&#xff1a;");scanf("%d",&a);printf("个位&#xff1a;%d\n"…...

Git远程拉取和推送配置

Git进行远程代码拉取和推送时候提示配置user.name 和 user.email 背景&#xff1a;换新电脑后使用Git进行代码拉取和推送过程中&#xff0c;提示“Make sure you configure your “user.name” and “user.email” in git.”。这个配置针对git的正常使用仅需要配置一次&#xf…...

MySQL WHERE 子句详解

MySQL WHERE 子句详解 引言 在数据库操作中&#xff0c;WHERE 子句是用于筛选记录的重要工具。它允许我们在查询中指定条件&#xff0c;从而只选择满足特定条件的记录。本文将详细介绍 MySQL 中的 WHERE 子句&#xff0c;包括其语法、用法以及一些高级技巧。 WHERE 子句的基…...

基于SpringBoot+Vue3实现的宠物领养管理平台功能七

一、前言介绍&#xff1a; 1.1 项目摘要 随着社会经济的发展和人们生活水平的提高&#xff0c;越来越多的人开始关注并参与到宠物领养中。宠物已经成为许多家庭的重要成员&#xff0c;人们对于宠物的关爱和照顾也日益增加。然而&#xff0c;传统的宠物领养流程存在诸多不便&a…...

【leetcode hot 100 994】腐烂的橘子

多源广度优先搜索 所有的腐烂橘子在广度优先搜索上是等价于同一层的节点的。假设这些腐烂橘子刚开始是新鲜的&#xff0c;而有一个腐烂橘子(我们令其为超级源点)会在下一秒把这些橘子都变腐烂&#xff0c;而这个腐烂橘子刚开始在的时间是 −1&#xff0c;那么按照广度优先搜索…...

精挑20题:MySQL 8.0高频面试题深度解析——掌握核心知识点、新特性和优化技巧

1. MySQL 8.0 中&#xff0c;为什么查询缓存被移除&#xff1f; 答案&#xff1a; 原因&#xff1a;查询缓存对频繁更新的表效果差&#xff0c;任何对该表的写操作都会清空所有相关缓存&#xff0c;导致缓存命中率低&#xff0c;反而增加开销。 替代方案&#xff1a; 使用应用…...

调研报告:Hadoop 3.x Ozone 全景解析

Ozone 是 Hadoop 的分布式对象存储系统,具有易扩展和冗余存储的特点。 Ozone 不仅能存储数十亿个不同大小的对象,还支持在容器化环境(比如 Kubernetes)中运行。 Apache Spark、Hive 和 YARN 等应用无需任何修改即可使用 Ozone。Ozone 提供了 Java API、S3 接口和命令行接口…...

深入理解 RLP 编码与 JSON:原理、应用与比较

在区块链和数据存储领域&#xff0c;RLP&#xff08;Recursive Length Prefix&#xff09;编码和**JSON&#xff08;JavaScript Object Notation&#xff09;**是两种重要的数据编码方式。它们分别适用于不同的应用场景&#xff0c;并具有不同的优缺点。本文将系统性地分析 RLP…...

【Linux】Makefile秘籍

> &#x1f343; 本系列为Linux的内容&#xff0c;如果感兴趣&#xff0c;欢迎订阅&#x1f6a9; > &#x1f38a;个人主页:【小编的个人主页】 >小编将在这里分享学习Linux的心路历程✨和知识分享&#x1f50d; >如果本篇文章有问题&#xff0c;还请多多包涵&a…...

玩转物联网-4G模块如何快速将数据上传到巴法云(TCP篇)

目录 1 前言 2 环境搭建 2.1 硬件准备 2.2 软件准备 2.3 硬件连接 2.4 检查驱动 3 巴法云平台设备创建 3.1 创建账号 3.2 进入巴法云 3.3 获取联网参数 4 连接巴法云 4.1 打开配置工具读取基本信息 4.2 设置连接参数进行数据交互 4.2.1 建立TCP连接 4.2.2 订阅主题 4.2.3 发布信…...

postgresql 高版本pgsql备份在低版本pgsql中恢复失败,报错:“unsupported version”

关键字 PostgreSQL、pg_restore、版本兼容性、数据库迁移、pg_dump、备份恢复、unsupported version in file header 背景环境 系统配置 环境类型操作系统PostgreSQL版本内存工具链测试环境Windows 111616GBNavicat/PgAdmin生产环境Windows Server 2012 R2128GBPgAdmin/命令…...

html相关常用语法

html相关常用语法 HTML&#xff08;HyperText Markup Language&#xff09;即超文本标记语言&#xff0c;是用于创建网页的标准标记语言 HTML使用标记语言描述Web页面的结构 HTML元素是HTML页面的建构快 HTML元素通过标签tag来表示 HTML标签是“标题”、”段落“、”表格“等内…...

vue3+ts心得

1、Vue3核心 1、setup setup里弱化this&#xff0c;return可以返回函数&#xff0c;返回后页面也显示那个函数值 data里面是可以用this.来获取setup里的值&#xff0c;这个是单向的 vue3两个script标签不要觉得奇怪&#xff0c;一个是配置组合式api的&#xff0c;一个是配置组…...

单片机flash存储也做磨损均衡

最近在做一个项目&#xff0c;需要保存设置数据&#xff0c;掉电不丢失。那么首先想到的是加个24c02&#xff0c;是一个eeprom&#xff0c;但是客户板太小&#xff0c;没有办法进行扩展。后面就找了一个带ee的OTP单片机&#xff0c;发现擦写次数有限&#xff0c;只有1000次&…...

【FAQ】HarmonyOS SDK 闭源开放能力 —Push Kit(10)

1.问题描述&#xff1a; 离线推送&#xff0c;锁屏的时候没有弹出消息&#xff0c;只有下拉在通知中心里面显示。请问是否是正常的&#xff1f; 解决方案&#xff1a; 检查一下是否存在图片风控&#xff1a;https://developer.huawei.com/consumer/cn/doc/harmonyos-referen…...

SQLark中如何进行数据筛选与排序

本文将为你介绍在 SQLark 中如何进行数据筛选与排序&#xff0c;掌握这些操作能够极大提升你的工作效率。 SQLark官网链接:www.sqlark.com 数据筛选 在数据库操作中&#xff0c;数据筛选是一项关键功能&#xff0c;它依据特定条件对数据进行过滤&#xff0c;帮助用户从海量数据…...

token升级(考虑在分布式环境中布置token,结合session保证请求调用过程中token不会过期。)

思路&#xff1a; 首先&#xff0c;用户的需求是确保使用同一个Token的外部调用都在一个Session中处理。 需要考虑Token与Session绑定、安全措施、Session管理、分布式处理等。 使用Redis作为Session存储&#xff0c; 在Java中 通过Spring Data Redis或Lettuce库实现。 2.生成…...

VSTO(C#)Excel开发11:自定义任务窗格与多个工作簿

初级代码游戏的专栏介绍与文章目录-CSDN博客 我的github&#xff1a;codetoys&#xff0c;所有代码都将会位于ctfc库中。已经放入库中我会指出在库中的位置。 这些代码大部分以Linux为目标但部分代码是纯C的&#xff0c;可以在任何平台上使用。 源码指引&#xff1a;github源…...

python:AI+ music21 构建LSTM模型生成爵士风格音乐

这是一个使用 python的 music21 和 TensorFlow/Keras 构建 LSTM 模型生成爵士风格音乐的完整脚本。该脚本包含MIDI数据处理、模型训练和音乐生成全流程&#xff1a; # -*- coding: utf-8 -*- """AI music21 和 TensorFlow/Keras 构建LSTM模型生成爵士风格音乐 …...

vscode查看文件历史git commit记录

方案一&#xff1a;GitLens 在vscode扩展商店下载GitLens 选中要查看的文件&#xff0c;vscode界面右上角点击GitLens的图标&#xff0c;选择Toggle File Blame 界面显示当前打开文件的所有修改历史记录 鼠标放到某条记录上&#xff0c;可以看到记录详情&#xff0c;选中O…...

使用netDxf扩充LaserGRBL使它支持Dxf文件格式

为 LaserGRBL 扩展支持 DXF 文件格式&#xff0c;需要了解 LaserGRBL 的代码结构&#xff0c;并在其基础上添加 DXF 文件的解析和转换逻辑。以下是详细的扩展方案&#xff1a; 1. 了解 LaserGRBL LaserGRBL 是一个用于控制激光雕刻机的开源软件&#xff0c;支持 G 代码文件的加…...

GaussDB备份数据常用命令

1、常用备份命令gs_dump 说明&#xff1a;是一个服务器端工具&#xff0c;可以在线导出数据库的数据&#xff0c;这些数据包含整个数据库或数据库中指定的对象&#xff08;如&#xff1a;模式&#xff0c;表&#xff0c;视图等&#xff09;&#xff0c;并且支持导出完整一致的数…...

数学建模 第三节

目录 前言 一 钻井布局问题 第一问分析 第二问分析 总结 前言 这里讲述99年的钻井布局问题&#xff0c;利用这个问题讲述模型优化&#xff0c;LINGO&#xff0c;MATLAB的使用 一 钻井布局问题 这个是钻井布局的原题&#xff0c;坐标的位置为 a [0.50,1.41,3.00,3.37,3…...

单调队列【C/C++】

当我在网上搜索了一大堆单调队列的文章后&#xff0c; 我人傻了&#xff01;&#xff1f; 单调队列不应该很难吗&#xff1f;&#xff1f; 不应该是&#xff0c;像 优先队列 那样&#xff0c;站在 堆 的肩膀上&#xff0c;极尽升华吗&#xff1f;&#xff1f;&#xff1f; …...

Spark DataFrame、Dataset 和 SQL 解析原理深入解析(万字长文多张原理图)

目录 1. Spark SQL 概述 1.1 Spark 整体架构概览 1.2 DataFrame 与 Dataset 简介 2. RDD 与 Spark 的分布式架构基础 2.1 弹性分布式数据集(RDD) 2.2 Spark 的分布式执行模型 3. SQL 解析流程与 Catalyst 优化器 3.1 SQL 解析流程概述 3.2 解析阶段与抽象语法树(AST…...