eProsima Fast DDS getting started

news2024/11/23 15:13:47

系列文章目录


文章目录

  • 系列文章目录
  • preface
  • **对象与数据结构**
      • ● Publish-Subscriber模块
      • ● RTPS模块
      • **配置Attributes**
  • Discovery
  • 传输控制
  • 前言
  • 0、安装
    • cmake安装相关
    • 源码安装:
      • - A `foonathan_memory_vendor`
      • - C `fastcdr`
      • - D `tinyxml2`
      • - E `asio`
      • - F `openssl`
      • - G `fastrtps`
  • 一、C++ publisher、subscriber应用
    • 什么是DDS
    • DCPS概念模型
    • RTPS
    • C++ 发布者订阅者应用
  • 总结


preface

fast dds官方文档缺乏对DDS整体的介绍,一上来就介绍各种细节,DDS的整体设计意图和用法隐匿与各种细节中,很容易让人一头雾水,不知其所云。该文章对DDS有一个整体的介绍,方便快速了解其概念。

https://www.eprosima.com/docs/fast-rtps/1.9.3/html/index.html

DDS全称是Data Distribution Service,这是一套通信协议和API标准,它提供了以数据为中心的连接服务,基于发布者-订阅者模型。这是一套中间件,它提供介于操作系统和应用程序之间的功能,使得组件之间可以互相通信。并且提供了低延迟,高可靠的通信以及可扩展的架构。

DDS本身是一套标准。由Object Management Group(简称OMG)维护。

OMG是一个开放性的非营利技术标准联盟,由许多大型IT公司组成:包括IBM,Apple Computer,Sun Microsystems等。

但OMG仅仅负责制定标准,而标准的实现则由其他服务提供商完成。

目前DDS的提供商包括下面这些:

  • Vortex OpenSplice
  • eProsima Fast RTPS
  • Hamersham
  • Company Summary Kongsberg Gallium
  • MilSOFT
  • Object Computing OpenDDS
  • Remedy IT
  • RTI
  • Twin Oaks Computing, Inc.

DDS与RTPS
在DDS规范中,有两个描述标准的基本文档:

  • DDS Specification:描述了以数据为中心的发布-订阅模型。该规范定义了API和通信语义(行为和服务质量),使消息从消息生产者有效地传递到匹配的消费者。DDS规范的目的可以概括为:“能够在正确的时间将正确的信息高效,可靠地传递到正确的位置”。
  • DDSI-RTPS:描述了RTPS(Real Time Publish Subscribe Protocol)协议。该协议通过UDP等不可靠的传输,实现最大努力(Best-Effort)和可靠的发布-订阅通信。RTPS是DDS实现的标准协议,它的目的和范围是确保基于不同DDS供应商的应用程序可以实现互操作。

在这里插入图片描述

Fast-RTPS 介绍
Fast-RTPS是eprosima对于RTPS的C++实现,这是一个免费开源软件,遵循Apache License 2.0。

eProsima Fast RTPS在性能,功能和对最新版本RTPS标准(RTPS 2.2)的遵守方面均处于领先地位。

Fast-RTPS具有以下优点:

  • 对于实时应用程序来说,可以在Best-Effort和可靠通信两种策略上进行配置。
  • 即插即用的连接性,使得网络的所有成员自动发现其他新的成员。
  • 模块化和可扩展性允许网络中设备不断增长。
  • 可配置的网络行为和可互换的传输层:为每个部署选择最佳协议和系统输入/输出通道组合。
  • 两个API层:一个简单易用的发布者-订阅者层和一个提供对RTPS协议内部更好控制的Writer-Reader层。

Fast-RTPS提供了两个层次的API:

  • Publisher-Subscriber层:RTPS上的简化抽象。
  • Writer-Reader层:对于RTPS端点的直接控制。
    在这里插入图片描述

对象与数据结构

下面是Fast-RTPS实现中的核心结构。

● Publish-Subscriber模块

RTPS标准的高层类型。

  • Domain:用来创建,管理和销毁Participants。
  • Participant:包括Publisher和Subscriber,并管理它们的配置。
    • ParticipantAttributes:创建Participant的配置参数。
    • ParticipantListener:可以让开发者实现Participant的回调函数。
  • Publisher:在Topic上发布数据的对象。
    • PublisherAttributes:创建Publisher的配置参数。
    • PublisherListener:可以让开发者实现Publisher的回调函数。
  • Subscriber:在Topic上接受数据的对象。
    • SubscriberAttributes:创建Subscriber的配置参数。
    • SubscriberListener:可以让开发者实现Subscriber的回调函数。

● RTPS模块

RTPS的底层模型。包含下面几个子模块:

  • RTPS Common
    • CacheChange_t:描述Topic上的变更,存储在历史Cache中。
    • Data:Cache变化的负载。
    • Message:RTPS消息。
    • Header:RTPS协议的头信息。
    • Sub-Message Header:标识RTPS的订阅消息。
    • MessageReceiver:反序列化和处理接受到的RTPS消息。
    • RTPSMessageCreator:构建RTPS消息。
  • RTPS Domain
    • RTPSDomain:用来创建,管理和销毁底层的RTPSParticipants。
    • RTPSParticipant:包括Writer和Reader。
  • RTPS Reader
    • RTPSReader:读者的基类。
    • ReaderAttributes:包含RTPS读者的配置参数。
    • ReaderHistory:存储Topic变化的历史数据。
    • ReaderListener:读者的回调类型。
  • RTPS Writer
    • RTPSWriter:写者的基类。
    • WriterAttributes:包含RTPS写者的配置参数。
    • WriterHistory:存储写者的历史数据。

配置Attributes

上面的数据结构中看到了许多Attributes后缀的类名。这些类包含了对协议或者对象的配置参数,很多特性都需要设置这些属性来完成。
这些类的定义基本都位于下面三个文件夹中:
https://github.com/eProsima/Fast-DDS

  • include/fastrtps/attributes
  • include/fastrtps/rtps/attributes
  • include/fastdds/rtps/attributes

Fast RTPS支持非常多的配置参数,并且参数的结构常常是嵌套的。

通过代码去配置这些参数会产生很多啰嗦的代码,而且最大的问题在于:每次更改配置参数都需要重新编译。这个问题并非Fast RTPS才有,只要包含大量配置参数的软件都会这样的问题。通常的解决方法就是:提供文本格式的配置文件的方式来配置参数。因此对于Fast-RTPS来说,除了支持通过代码配置参数,它也支持通过XML文件的方式来进行配置。
Fast-RTPS支持的配置项,以及这些配置项说明和默认值都可以到这个链接中查看:XML profiles。

Discovery

作为DDS的实现,Fast-RTPS提供了Publisher和Subscriber自动发现和匹配的功能。在实现上,这分为两个步骤来完成:

  • Participant Discovery Phase (PDP):在这个阶段,参与者互相通知彼此的存在。为了达到这个目的,每个参与者需要定时发送公告消息。公告消息通过约定的多播地址和端口发送(根据domain计算得到)。
  • Endpoint Discovery Phase (EDP):在这个阶段,Publisher和Subscriber互相确认。为此,参与者使用在PDP期间建立的通信通道,彼此共享有关其发布者和订阅者的信息。 该信息包含了Topic和数据类型。为了使两个端点匹配,它们的Topic和数据类型必须一致。 一旦发布者和订阅者匹配,他们就发送/接收数据了。

这两个阶段对应了两个独立的协议:

  • Simple Participant Discovery Protocol:指定参与者如何在网络中发现彼此。
  • Simple Endpoint Discovery Protocol:定义了已经互相发现的参与者交换信息的协议。

Fast-RTPS提供了四种发现机制:

  1. Simple:这是默认机制。它在PDP和EDP阶段均使用RTPS标准,因此可与任何其他DDS和RTPS实现兼容。
  2. Static:此机制在PDP阶段使用Simple Participant Discovery Protocol。如果所有发布者和订阅者的地址以及端口和主题信息是事先知道的,则允许跳过EDP阶段。
  3. Discovery Server: 这种发现机制使用集中式发现结构,由服务器充当发现机制的Hub。
  4. Manual:此机制仅与RTPSDomain层兼容。它禁用了PDP阶段,使用户可以使用其选择的任何外部元信息通道手动匹配和取消匹配RTPS参与者,读者和写者。

不同的发现机制具有一些共同的配置:

名称描述默认值
Ignore Participant flags在必要的时候,可以选择忽略一些参与者。
例如:另一台主机上的,另一个进程的或者同一个进程的。NO_FILTER
Lease Duration指定远程参与者在多少时间内认为本地参与者还活着。20s
Announcement Period指定参与者的PDP公告消息的周期。3s

more details: https://fast-dds.docs.eprosima.com/en/latest/fastdds/discovery/discovery.html

传输控制

ast-RTPS实现了可插拔的传输架构,这意味着每一个参与者可以随时加入和退出。

在传输上,Fast-RTPS支持以下五种传输方式:
UDPv4
UDPv6
TCPv4
TCPv6
SHM(Shared Memory
默认的,当Participant创建时,会自动的配置两个传输通道:
SHM:用来与同一个机器上的参与者通信。
UDPv4:同来与跨机器的参与者通信。

开发者可以改变这个默认行为,通过C++接口或者XML配置文件都可以。

SHM要求所有参与者位于同一个系统上,它是借助了操作系统提供的共享内存机制实现。共享内存的好处是:支持大数据传输,减少了数据拷贝,并且也减少系统负载。因此通常情况下,使用SHM会获得更好的性能。使用SHM时,可以配置共享内存的大小。

网络通信包含了非常多的参数需要配置,例如:Buffer大小,端口号,超时时间等等。框架本身为参数设置了默认值,大部分情况下开发者不用调整它们。但是知道这些默认值是什么,在一些情况下可能会对分析问题有所帮助。

与UDP不同,TCP传输是面向连接的,因此,Fast-RTPS必须在发送RTPS消息之前建立TCP连接。TCP传输可以具有两种行为:充当TCP服务器或充当TCP客户端。服务器打开一个TCP端口以侦听传入的连接,然后客户端尝试连接到服务器。服务器和客户端的概念独立于RTPS概念,例如:Publisher,Subscriber,Reader或Writer。它们中的任何一个都可以用作TCP服务器或TCP客户端,因为这些实体仅用于建立TCP连接,而RTPS协议可以在该TCP连接上工作。

如果要使用TCP传输,开发者需要做更多的配置。



前言

eProsima Fast DDS是DDS规范的C++实现,DDS是由OMG定义的一种协议。eProsima Fast DDS 库提供应用程序编程接口 (API) 和通信协议 部署 以数据为中心的发布者-订阅者 (DCPS) 模型,旨在建立高效可靠的信息在实时系统之间分配。eProsima Fast DDS 在资源处理方面具有可预测性、可扩展性、灵活性和高效性。 为了满足这些要求,它利用了类型化接口和多对多的铰链 分布式网络范式,巧妙地允许将通信的发布者和订阅者端分开。eProsima Fast DDS 包括:

  1. DDS API实现
  2. Fast DDS-Gen,一种用于桥接类型化接口与中间件的生成工具 实现
  3. 底层RTPS有限协议实现

DDS采用的通信模式是多对多的单向数据交换,其中应用 生成数据,将其发布到属于使用数据的应用程序的订阅者的本地缓存。 信息流由QOS策略管理,QOS由交换数据的实体建立。DDS通讯只能发生在DDS Domain内,不能夸Domain。
在这里插入图片描述
RTPS Wire Protocol
在传输层之上的协议,传输层可以是TCP/UDP/IP


0、安装

https://www.eprosima.com/index.php/downloads-all

https://fast-dds.docs.eprosima.com/en/latest/index.html

cmake安装相关

做用用法备注
CMAKE_INSTALL_PREFIX指定make intall安装路径cmake … -DCMAKE_INSTALL_PREFIX=<path/to/install>
CMAKE_C_COMPILER指定C编译器set(CMAKE_C_COMPILER </path/gcc>在project之前
CMAKE_CXX_COMPILER指定C++编译器set(CMAKE_CXX_COMPILER </path/g++>在project之前
指定全局编译选项add_compile_options(-O2 -g)

include

源码安装:

  • A foonathan_memory_vendor, an STL compatible C++ memory allocator library.
  • B fastdds_gen, a Java application that generates source code using the data types defined in an IDL file.
  • C fastcdr, a C++ library that serializes according to the standard CDR serialization mechanism.
  • D tinyxml2
  • E asio
  • F openssl
  • G fastrtps, the core library of eProsima Fast DDS library.

最终目标是安装:https://github.com/eProsima/Fast-DDS
在thirdparty目录下也有第三方依赖

- A foonathan_memory_vendor

https://github.com/eProsima/foonathan_memory_vendor
编译该项目时需要下载:https://github.com/foonathan/memory.git。将该项目手动下载并修改foonathan_memory_vendor的CMakeLists.txt文件中的:

externalproject_add(foo_mem-ext
GIT_REPOSITORY https://github.com/foonathan/memory.git
GIT_TAG v0.7-3
TIMEOUT 600
# Avoid the update (git pull) and so the recompilation of foonathan_memory library each time.
UPDATE_COMMAND ""
CMAKE_ARGS
  -DFOONATHAN_MEMORY_BUILD_EXAMPLES=${BUILD_MEMORY_EXAMPLES}
  -DFOONATHAN_MEMORY_BUILD_TESTS=${BUILD_MEMORY_TESTS}
  -DFOONATHAN_MEMORY_BUILD_TOOLS=${BUILD_MEMORY_TOOLS}
  -DCMAKE_INSTALL_PREFIX=${CMAKE_CURRENT_BINARY_DIR}/foo_mem_ext_prj_install
  ${extra_cmake_args}
  -Wno-dev
  ${PATCH_COMMAND_STR}
)
修改为:
externalproject_add(foo_mem-ext
SOURCE_DIR <dir/memory-main>
# Avoid the update (git pull) and so the recompilation of foonathan_memory library each time.
UPDATE_COMMAND ""
CMAKE_ARGS
  -DFOONATHAN_MEMORY_BUILD_EXAMPLES=${BUILD_MEMORY_EXAMPLES}
  -DFOONATHAN_MEMORY_BUILD_TESTS=${BUILD_MEMORY_TESTS}
  -DFOONATHAN_MEMORY_BUILD_TOOLS=${BUILD_MEMORY_TOOLS}
  -DCMAKE_INSTALL_PREFIX=${CMAKE_CURRENT_BINARY_DIR}/foo_mem_ext_prj_install
  ${extra_cmake_args}
  -Wno-dev
  ${PATCH_COMMAND_STR}
)

编译命令:

mkdir build && cd build
cmake .. -DCMAKE_INSTALL_PREFIX=<path/to/install>
make -j8
make install

- C fastcdr

https://github.com/eProsima/Fast-CDR

编译命令:

mkdir build && cd build
cmake .. -DCMAKE_INSTALL_PREFIX=<path/to/install>
make -j8
make install

- D tinyxml2

https://github.com/leethomason/tinyxml2

编译命令:

mkdir build && cd build
cmake .. -DCMAKE_INSTALL_PREFIX=<path/to/install>
make -j8
make install

- E asio

Asio是一个用于网络和低级I/O编程的跨平台C++库,它使用现代C++方法为开发人员提供了一个一致的异步模型。
asio只有头文件,不需要编译

https://think-async.com/Asio/
https://think-async.com/Asio/Repository.html
https://github.com/chriskohlhoff/asio/

- F openssl

https://github.com/janbar/openssl-cmake
如果需要动态库则需要将crypto/CMakeLists.txt的add_library(crypto ${LIBSRC} ${OBJECTS_SRC})添加SHARED;ssl/CMakeLists.txt的add_library(ssl ${LIBSRC})添加SHARED

编译命令:

mkdir build && cd build
cmake .. -DCMAKE_INSTALL_PREFIX=<path/to/install>
make -j8
make install

- G fastrtps

libfastrtps.so是最后一个库,安装完后fastdds就可以使用了。
https://github.com/eProsima/Fast-DDS
在其thirdparty目录下有一些第三方库,部分文件在编译时cmake会自动找到,下面解决编译时报错等问题。

修改CMakeLists.txt,添加include_directories(openssl/include/path asio/include/path)
大约在249行,在eprosima_find_package(fastcdr REQUIRED)之前添加cmake package搜罗路径:

# 将fastcdr, tinyxml2, foonathan_memory的位置添加进find_package的搜罗路径
set(CMAKE_PREFIX_PATH "<installpath/lib/cmake/fastcdr>;<lib/cmake/tinyxml2>;<lib/foonathan_memory/cmake>")
# 根据上面编译时的路径,编译fastrtps是应该找到对应的cmake package了

另外,Asio和Boost.Asio是可同时存在的,虽然它们功能一样但namespace和宏名等有差异,因此是不冲突的,modules/FindAsio.cmake文件line:35中使用的是ASIO_VERSION,boost.asio的宏为BOOST_ASIO_VERSION

由于openssl在安装后没有cmake文件,因此不能通过find_package找到openssl。需要在编译时指定动态库:在target_link_libraries中添加库文件的绝对路径即可
<fastdds_root_dir>/cpp/CMakeLists.txt:line:460后添加target_link_directories(${PROJECT_NAME} PUBLIC <openssl/lib_dir>); line:517添加<xx/lib/libssl.so> <xx/lib/libcrypto.so>注释掉关于OpenSSL的行


编译命令:

mkdir build && cd build
cmake .. -DCMAKE_INSTALL_PREFIX=<path/to/install>
make -j8
make install

一、C++ publisher、subscriber应用

什么是DDS

Data Distribution Service(DDS)是一个以数据为中心的通讯协议,它用于进程之间的通讯。它描述了通讯APIs和通讯双方的通讯语义。
Since it is a Data-Centric Publish Subscribe (DCPS) model, 三个关键点:

  1. 发布实体:生成数据并定义其格式、属性等
  2. 接收实体:数据接接收方
  3. 配置实体:定义信息类型,作为topics传输,创建publishersubscriber和QOS属性,确保实体的正确表现

DDS 使用 QoS 来定义 DDS 实体的行为特征。QoS 由单独的 QoS 策略组成

DCPS概念模型

在DCPS模型中,为通信应用系统的开发定义了四个基本要素。

  • 发布者。它是 DCPS 实体,负责创建和配置它实现的 DataWriter。 DataWriter 是负责消息实际发布的实体。 每个主题都将有一个分配的主题,在该主题下发布消息。
  • 订阅者。 它是DCPS实体,负责接收在其订阅的主题下发布的数据。 它提供一个或多个 DataReader 对象,这些对象负责传达新数据的可用性 到应用程序。
  • 主题。 它是绑定发布者和订阅者的实体。 它在 DDS 域中是唯一的。 通过 TopicDescription,它允许出版物和订阅的数据类型的统一性。

在这里插入图片描述

RTPS

RPTS 协议,开发为 支持DDS应用,是一个发布-订阅通信中间件 通过尽力而为的传输,例如 UDP/IP。此外,Fast DDS 还支持 TCP 和 共享内存 (SHM) 传输。
它旨在支持单播和组播通信。
在 RTPS 的顶部,继承自 DDS,可以找到域,它定义了一个单独的通信平面。 多个域可以独立地同时共存。 域包含任意数量的 RTPSParticipants,即能够发送和接收数据的元素。 为此,RTPSParticipants 使用其终结点:
RTPSWriter:能够发送数据的端点。
RTPSReader:能够接收数据的端点。
在这里插入图片描述

C++ 发布者订阅者应用

DDS是以数据为中心的通讯中间件,它实现了DCPS模型。该模型基于发布者、订阅者模式。这些实体通过主题进行通信,主题是绑定两个 DDS 实体的元素。发布者在主题下产生信息,订阅者通过相同的主题接收信息。

  1. 创建应用程序空间
  2. 依赖库
    Fast DDS 和 Fast CDR
    如果是二进制安装,头文件在/usr/include/fastrtps/ /usr/include/fastcdr/;库文件在/usr/lib/
  3. 配置CMake工程
cmake_minimum_required(VERSION 3.20)

project(DDSHelloWorld)

# Find requirements
if(NOT fastcdr_FOUND)
    find_package(fastcdr 2 REQUIRED)
endif()

if(NOT fastrtps_FOUND)
    find_package(fastrtps 2.12 REQUIRED)
endif()

# Set C++11
include(CheckCXXCompilerFlag)
if(CMAKE_COMPILER_IS_GNUCXX OR CMAKE_COMPILER_IS_CLANG OR
        CMAKE_CXX_COMPILER_ID MATCHES "Clang")
    check_cxx_compiler_flag(-std=c++11 SUPPORTS_CXX11)
    if(SUPPORTS_CXX11)
        add_compile_options(-std=c++11)
    else()
        message(FATAL_ERROR "Compiler doesn't support C++11")
    endif()
endif()

message(STATUS "Configuring HelloWorld publisher/subscriber example...")
file(GLOB DDS_HELLOWORLD_SOURCES_CXX "src/*.cxx")
  1. build the topic data type
    eProsima Fast DDS-Gen是一个生成源码的Java应用,它使用Interface Description Language(IDL)文件定义的数据类型。它有两个功能:
    1. 为topic生成C++定义
    2. 用topic数据生成功能案例
cd src && touch HelloWorld.idl

HelloWorld.idl文件中定义的 topic C++定义

struct HelloWorld
{
    unsigned long index;
    string message;
};

然后通过eProsima Fast DDS-Gen工具生成C++11代码:

<path/to/Fast DDS-Gen>/scripts/fastddsgen HelloWorld.idl

这将生成:
在这里插入图片描述


总结

https://fast-dds.docs.eprosima.com/en/latest/02-formalia/titlepage.html

https://paul.pub/dds-and-fastrtps/

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

贪心:交换论证法

目录 切蛋糕的最小总开销 切蛋糕的最小总开销 交换论证&#xff1a; 设横切的开销为 h&#xff0c;如果先横切&#xff0c;设需要横切 cnt_h 次。 设竖切的开销为 v&#xff0c;如果先竖切&#xff0c;设需要竖切 cnt_v 次。 先横切&#xff0c;再竖切&#xff0c;那么竖切…

模拟电路再理解系列(3)-共射极放大电路

1.三极管 共射极放大电路的主要器件是三极管&#xff0c;先来梳理一下这个经常见到的元器件 结构 三极管的三个极&#xff1a;基极&#xff0c;集电极&#xff0c;发射极 基极流经的电流来控制集电极和发射极之间的导通和关闭&#xff0c;之前看过一个形象的比喻&#xff0c…

51单片机9(使用左移实现流水灯编程)

一、序言&#xff1a;下面我们来给大家介绍一下这个流水灯&#xff0c;流水灯如何来实现&#xff1f;我们依然使用这个工程来完成它。 1、那要使用实现这个流水灯&#xff0c;那我们只需要让D1到D8逐个的点亮&#xff0c;那同样要实现它足够的点亮&#xff0c;也会涉及到延时&…

windows10 安装Anaconda

文章目录 1. 下载2. 安装3. 配置环境变量4. 检查是否安装成功 1. 下载 官网下载 https://www.anaconda.com/download 下载的最新版本&#xff0c;要求python的版本也高一些 清华大学开源软件镜像站 https://mirrors.tuna.tsinghua.edu.cn/anaconda/archive/ 所有版本在这个网…

在 PostgreSQL 里如何实现数据的分布式事务的回滚和补偿机制?

&#x1f345;关注博主&#x1f397;️ 带你畅游技术世界&#xff0c;不错过每一次成长机会&#xff01;&#x1f4da;领书&#xff1a;PostgreSQL 入门到精通.pdf 文章目录 在 PostgreSQL 里如何实现数据的分布式事务的回滚和补偿机制一、分布式事务的概念与挑战&#xff08;一…

书生大模型实战营-入门岛-第二关

Python实现wordcount def wordcount(text):words text.split()ans{}for word in words:if word not in ans: ans[word] 1 else: ans[word] 1 return ans text """Hello world! This is an example. Word count is fun. Is it fun to cou…

【日常记录】【CSS】display:inline 的样式截断

文章目录 1. 案例2. css属性&#xff1a;box-decoration-break参考地址 1. 案例 现在有一篇文章&#xff0c;某些句子&#xff0c;是要被标记的&#xff0c;加一些css 让他突出一下 可以看到&#xff0c;在最后&#xff0c;断开了&#xff0c;那如若要让 断开哪里的样式 和 开始…

@google/model-viewer 导入 改纹理 (http-serve)

导入模型 改纹理 效果图 <template><div><h1>鞋模型</h1><model-viewerstyle"width: 300px; height: 300px"id"my-replace-people"src"/imgApi/Astronaut.glb"auto-rotatecamera-controls></model-viewer>&…

【棋盘上的战舰】python刷题记录

目录 小前言 思路&#xff1a; 上代码 lucky ending 小前言 经过漫长的停更周期-----1个月 我决定铁血回归&#xff01;&#xff01;&#xff01; 思路&#xff1a; 两层for循环暴力最快了这种小小范围题&#xff0c;主要是第一行和第一列的边界处理&#xff0c;我分为…

STM32MP135裸机编程:定时器内核时钟频率计算方法

0 工具准备 STM32MP13xx参考手册 1 定时器内核时钟频率计算方法 1.1 定时器分组 STM32MP135的定时器按照时钟源不同分成了三组&#xff0c;如下&#xff1a; APB1: APB2: APB6&#xff1a; 1.2 定时器内核时钟频率计算方法 APB1DIV是APB1的分频系数&#xff0c;APB2DIV、…

docker和docker的安装

1什么是docker&#xff1f; docker是容器技术&#xff08;软件&#xff09;&#xff0c;提供标准的应用镜像&#xff08;包含应用&#xff0c;和应用的依赖&#xff09;可以轻松在docker里安装应用&#xff0c;每个应用独立容器 2.主要功能&#xff1a; 打包&#xff08;软件…

Go:基本变量与数据类型

目录 前言 前期准备 Hello World! 一、基本变量 1.1 声明变量 1.2 初始化变量 1.3 变量声明到初始化的过程 1.4 变量值交换 1.5 匿名变量 1.6 变量的作用域 二、数据类型 1.1 整型 1.2 浮点型 1.3 字符串 1.4 布尔类型 1.5 数据类型判断 1.6 数据类型转换 1.…

STM32 BootLoader 刷新项目 (四) 通信协议

STM32 BootLoader 刷新项目 (四) 通信协议 文章目录 STM32 BootLoader 刷新项目 (四) 通信协议1. 通信流程2. 支持指令3. 通信流程4. 指令结构5. 操作演示 前面几章节&#xff0c;我们已经介绍了BootLoader的整体程序框架&#xff0c;方案设计&#xff0c;以及STM32CubdeMX的配…

51单片机6(P0P1P2P3结构框架图)

一、GPIO结构框架图与工作原理 1、接下来我们介绍一下这个GPIO结构框图和工作原理&#xff0c;我们使用51单片机的GPIO分为了P0&#xff0c;P1&#xff0c;P2&#xff0c;P3这四组端口&#xff0c;下面我们就分别来介绍这四组端口它的一个内部结构&#xff0c;只有了解了内部的…

Python爬虫入门篇学习记录

免责声明 本文的爬虫知识仅用于合法和合理的数据收集&#xff0c;使用者需遵守相关法律法规及目标网站的爬取规则&#xff0c;尊重数据隐私&#xff0c;合理设置访问频率&#xff0c;不得用于非法目的或侵犯他人权益。因使用网络爬虫产生的任何法律纠纷或损失&#xff0c;由使用…

MySQl高级篇-事务、锁机制、MVCC

存储引擎的选择 在选择存储引擎时&#xff0c;应该根据应用系统的特点选择合适的存储引擎。对于复杂的应用系统&#xff0c;还可以根据实际情况选择多种存储引擎进行组合。 InnoDB&#xff1a;是Mysql的默认存储引擎&#xff0c;支持事务、外键。如果应用对事务的完整性有比较…

C++知识要点总结笔记

文章目录 前言一、c基础1.指针和引用指针和引用的区别 2.数据类型整型 short int long 和 long long无符号类型 3.关键字conststaticconst和static的区别define 和 typedef 的区别define 和 inline 的区别const和define的区别new 和 malloc的区别constexprvolatileextern前置与…

用Speedtest-Tracker跟踪上网速度(续)

什么是 Speedtest Tracker ? Speedtest Tracker 是一款自托管互联网性能跟踪应用程序&#xff0c;可针对 Ookla 的 Speedtest 服务运行速度测试检查。 之前老苏介绍的另一个 https://github.com/henrywhitaker3/Speedtest-Tracker 已被放弃。现在这个是积极维护的替代品&#…

repo sync同步出错解决

当出现下面提示时 e list of known hosts. Fetching: 100% (1167/1167), done in 44.619s info: A new version of repo is available warning: repo is not tracking a remote branch, so it will not receive updates Repo command failed: RepoUnhandledExceptionError …

element UI时间组件两种使用方式

加油&#xff0c;新时代打工&#xff01; 组件官网&#xff1a;https://element.eleme.cn/#/zh-CN/component/date-picker 先上效果图&#xff0c;如下&#xff1a; 第一种实现方式 <div class"app-container"><el-formref"submitForm":model&q…