MATLAB ROS Toolbox 官网教程

系列文章目录


文章目录

  • 系列文章目录
  • 前言
  • 一、ROS 2 入门
    • 1.1 ROS 2 术语
    • 1.2 启动 ROS 2 网络
    • 1.3 话题和服务质量策略
    • 1.4 消息
    • 1.5 从 ROS 2 网络断开连接
    • 1.6 DDS 和 RMW 实施
  • 二、连接到 ROS 2 网络
    • 2.1 在默认域中创建 ROS 2 节点
    • 2.2 在不同域上创建 ROS 2 节点
    • 2.3 更改默认域 ID
    • 2.4 ROS 2 网络通信
    • 2.5 子网外的 ROS 通信
  • 三、与 ROS 2 发布者和订阅者交换数据
    • 3.1 订阅并等待信息
    • 3.2 使用回调函数订阅
    • 3.3 发布消息
    • 3.4 断开 ROS 2 网络连接
  • `如果觉得内容不错,请点赞、收藏、关注`


前言

ROS 工具箱提供了一个连接 MATLAB® 和 Simulink® 与机器人操作系统(ROS 和 ROS 2)的接口。利用该工具箱,您可以设计 ROS 节点网络,并将 MATLAB 或 Simulink 生成的 ROS 节点与现有的 ROS 网络相结合。

工具箱包括 MATLAB 函数和 Simulink 块,可通过记录、导入和回放 rosbag 文件来可视化和分析 ROS 数据。您还可以连接到实时 ROS 网络,访问 ROS 消息。

该工具箱可让你通过桌面仿真和连接外部机器人仿真器(如 Gazebo)或硬件来验证 ROS 节点。ROS 工具箱支持 C++ 和 CUDA® 代码生成(使用 MATLAB Coder™、Simulink Coder 和 GPU Coder™),使您能够从 MATLAB 脚本或 Simulink 模型自动生成 ROS 节点,并部署到模拟或物理硬件上。支持 Simulink 外部模式后,当模型在硬件上运行时,你可以查看信息并更改参数。

在这里插入图片描述


一、ROS 2 入门

本示例展示了如何在 MATLAB 中设置 ROS 2,并获取有关 ROS 2 网络和 ROS 2 消息的信息。

机器人操作系统 2(ROS 2)是 ROS 的第二个版本,它是一个通信接口,可以让机器人系统的不同部分发现、发送和接收数据。支持 ROS 2 的 MATLAB® 是一个函数库,可让您与支持 ROS 2 的物理机器人或机器人模拟器(如 Gazebo®)交换数据。ROS 2 建立在数据分发服务(DDS)的基础上,这是一个端到端的中间件,具有发现、序列化和传输等功能。这些功能符合 ROS 2 的设计原则,如分布式发现和控制不同的传输 "服务质量 "选项。DDS 使用实时发布-订阅(RTPS)协议,可通过 UDP 等不可靠的网络协议进行通信。如需了解更多信息,请参阅 RTPS。

要了解 ROS,请参阅 ROS 入门。

1.1 ROS 2 术语

  • ROS 2 网络由通过 ROS 2 网络进行通信的机器人系统不同部分(如规划器或摄像头接口)组成。网络可以分布在多台机器上。

  • ROS 2节点是一个包含相关ROS 2能力(如发布者和订阅者)集合的实体。一个 ROS 2 网络可以有多个 ROS 2 节点。

  • 发布者和订阅者是处理数据的不同类型的 ROS 2 实体。它们使用消息交换数据。

  • 发布者向特定话题(如 “里程计”)发送消息,该话题的订阅者接收这些消息。一个话题可以关联多个发布者和订阅者。

  • 域是网络的物理分段。它由一个称为域 ID 的唯一整数值标识。默认情况下,域 ID 为 0。

  • ROS 2 网络中的每个节点在创建时都会向同一域 ID 中的其他节点公布自己的存在。

  • ROS 2 网络建立在数据分发服务(DDS)基础上,因此可以在分布式网络中连接多个节点。更多信息,请参阅在 ROS 中间件实现之间切换。

  • RTPS(实时发布者-订阅者)协议为 ROS 2 网络提供了在不可靠网络条件下发送信息的功能。

  • ROS 2 提供各种服务质量(QoS)策略,让你可以调整节点之间的通信。如需了解更多信息,请参阅管理 ROS 2 中的服务质量策略。

更多信息,请参阅机器人操作系统2(ROS 2)和 ROS 2 网站上的概念部分。

1.2 启动 ROS 2 网络

与 ROS 不同,ROS 2 无需在 MATLAB 中进行初始化。ROS 2 网络会自动从创建节点开始。

使用 ros2node 创建节点。

test1 = ros2node("/test1")
test1 = ros2node - 属性:Name: '/test1'ID: 0

使用 ros2 node list 查看 ROS 2 网络中的所有节点。

ros2 node list
/test1

使用 clear 关闭 ROS 2 网络中的节点。

clear test1

使用 exampleHelperROS2CreateSampleNetwork 为 ROS 网络添加三个节点,其中包括样本发布者和订阅者。

exampleHelperROS2CreateSampleNetwork

使用 ros2 node list 查看 ROS 2 网络中的所有节点。

ros2 node list
/tp367a7a03_c5b6_46f8_962
/tp3cbf47a7_c1c8_474c_bb
/tp6bb8a4e5_2f37_

这是创建样本节点后 ROS 2 网络的可视化表示。在本示例的其余部分中,请将其作为探索 ROS 2 网络的参考。

在这里插入图片描述

1.3 话题和服务质量策略

运行命令 ros2 topic list 查看 ROS 2 网络中的可用话题。该命令会返回三个活动话题: /pose、/parameter_events/scan。话题 /parameter_events 是 ROS 2 网络中始终存在的全局话题。节点使用 /paramater_events 话题监控或更改网络中的参数。您创建的 /scan/pose 话题是示例网络的一部分。

ros2 topic list
/parameter_events
/pose
/rosout
/scan

每个主题都与一种信息类型相关联。运行命令 ros2 topic list -t 可以查看每个主题的信息类型。

ros2 topic list -t
            Topic                       MessageType           _____________________    _________________________________{'/parameter_events'}    {'rcl_interfaces/ParameterEvent'}{'/pose'            }    {'geometry_msgs/Twist'          }{'/rosout'          }    {'rcl_interfaces/Log'           }{'/scan'            }    {'sensor_msgs/LaserScan'        }

服务质量(QoS)策略选项可改变发布者和订阅者处理和交换信息的方式。

  1. 使用 HistoryDepth QoS 策略,可根据在处理队列中放置报文的方式确定通信对象的行为。将 History 指定为以下选项之一。

    • “keeplast” - 删除信息,只保留最新信息。

    • “keepall”(全部保留)- 保留队列中收到的所有报文,直到处理完毕。

  2. 使用 Reliability QoS 策略保证向用户发送信息。将可靠性指定为以下选项之一。

    • “reliable”- 确保发布者持续向订户发送信息,直到订户确认收到信息。

    • “besteffort”- 允许发布者只发送一次信息。

  3. 使用 Durability QoS 策略和 Depth 输入来控制晚加入连接的信息持久性。将 Durability 指定为以下选项之一。

    • “transientlocal”(临时)- 如果订阅者在发布者首次发送信息后加入网络,则发布者会向订阅者发送持久化信息。

    • “volatile”(易失性)- 发布者在发送信息后不会持久化信息。订阅者不会向发布者请求持久化信息。

1.4 消息

发布者和订阅者使用 ROS 2 消息交换信息。每条 ROS 2 消息都有一个相关的消息类型,它定义了消息中的数据类型和信息布局。更多信息,请参阅 “使用基本 ROS 2 消息”。

使用 ros2 msg show 查看消息类型的属性。geometry_msgs/Twist 消息类型有两个属性:Linear 和角度 Angular 。每个属性都是 geometry_msgs/Vector3 类型的信息,而 geometry_msgs/Vector3 又有三个 double 类型的属性。

ros2 msg show geometry_msgs/Twist
# This expresses velocity in free space broken into its linear and angular parts.Vector3  linear
Vector3  angular
ros2 msg show geometry_msgs/Vector3
# This represents a vector in free space.# This is semantically different than a point.
# A vector is always anchored at the origin.
# When a transform is applied to a vector, only the rotational component is applied.float64 x
float64 y
float64 z

使用 ros2 msg list 查看 MATLAB 中可用消息类型的完整列表。

1.5 从 ROS 2 网络断开连接

使用 exampleHelperROS2ShutDownSampleNetwork 可从 ROS 2 网络中移除样本节点、发布者和订阅者。要移除自己的节点,请在节点、发布者或订阅者对象中使用 clear

exampleHelperROS2ShutDownSampleNetwork

1.6 DDS 和 RMW 实施

在 MATLAB® 和 Simulink® 中使用 ROS 2 时,您可以切换 RMW 实现来使用数据分发服务(DDS)。要配置所需的 RMW 实现,请按照以下步骤操作。

  1. 在 MATLAB 工具条 "环境 "部分的 "主页 "选项卡下,打开 “首选项”。

  2. 在 ROS 工具箱首选项对话框中配置 Python™ 环境,并从 ROS 中间件 (RMW) 实现下拉列表中选择一个实现。默认实现为 rmw_fastrtps_cpp

在这里插入图片描述

  1. 单击 “配置并切换到自定义 RMW 实现”,启动 ROS 中间件配置对话框,切换到自定义 RMW 实现。

  2. 安装并构建自定义 RMW 实现软件包,以验证使用所选自定义 RMW 实现创建 ROS 2 节点。

二、连接到 ROS 2 网络

ROS 2 网络由多个 ROS 2 节点组成。与 ROS 不同,ROS 2 基于数据分发标准(DDS),这是一个端到端的中间件,可提供发现、序列化和传输等功能。这些功能符合 ROS 2 的设计原则,如分布式发现和控制不同的传输 "服务质量 "选项。

要连接到 ROS 1 网络,请参阅连接到 ROS 网络。

使用 ROS 2 时,通常需要遵循以下步骤:

  • 连接到 ROS 2 网络 - 要连接到 ROS 2 网络,必须在 MATLAB 中创建一个 ROS 2 节点,并指定网络域 ID。

  • 交换数据–连接后,MATLAB 将通过发布者和订阅者与同一域 ID 中的其他 ROS 2 节点交换数据。

  • 从 ROS 2 网络断开连接 - 从 ROS 2 网络断开 MATLAB ROS 2 节点、发布者和订阅者的连接。

2.1 在默认域中创建 ROS 2 节点

使用 ros2node 在默认域中创建一个节点,其 ID 为 0。 节点与同一域中的其他节点通信,但不知道其他域中的节点。

defaultNode = ros2node("/default_node")
defaultNode = ros2node - 属性:Name: '/default_node'ID: 0

使用 clear 删除对节点的引用,从而将其从 ROS 2 网络中删除。

clear defaultNode

2.2 在不同域上创建 ROS 2 节点

要在非默认域中创建节点,请明确指定域 ID 作为 ros2node 的第二个输入参数。下面的 newDomainNode 将在 ID 25 指定的域中创建。

newDomainNode = ros2node("/new_domain_node",25)
newDomainNode = ros2node - 属性:Name: '/new_domain_node'ID: 25

要查看特定域的网络信息,请将 ID 作为参数提供给 ros2 函数。以下命令将显示域 ID 为 25 的所有节点。

ros2("node","list","DomainID",25)
/new_domain_node

2.3 更改默认域 ID

如果没有向 node 或 ros2 命令明确提供域 ID,它们默认使用 ROS_DOMAIN_ID 环境变量的值。使用 getenv 查看当前值。如果该环境变量未设置或未设置为有效值,则将使用默认的 0 域名 ID。

getenv("ROS_DOMAIN_ID")
ans =空的 0×0 char 数组

可以使用 setenv 命令设置 ROS_DOMAIN_ID

setenv("ROS_DOMAIN_ID","25")
envDomainNode = ros2node("/env_domain_node")
envDomainNode = ros2node - 属性:Name: '/env_domain_node'ID: 25

ros2 函数提供该环境变量指定的网络信息。使用 ros2 node list 查看域 ID 为 25 的节点。

ros2 node list
/env_domain_node
/new_domain_node

将 ROS_DOMAIN_ID 重置为默认值。

setenv("ROS_DOMAIN_ID","")

2.4 ROS 2 网络通信

要连接到现有的 ROS 2 网络,请在所需的域中创建一个节点。ROS 2 网络会通过一种名为 "发现 "的机制,自动检测在同一域中创建的任何新节点。

启动时,ROS 2 中的每个节点都会向同一域中的其他节点发出自己存在的广告。其他节点会响应这一广告,向新节点提供自己的信息。拥有通信对象(如发布者和订阅者)的节点,如果拥有服务质量(QoS)设置兼容的相应对象,就能与其他节点建立连接。有关 QoS 设置的更多信息,请参阅《ROS 2 中的服务质量策略管理》。

发现是一个持续的过程,它能让新节点在创建时加入网络。每个节点都在监控 ROS 2 网络,其作用类似于 ROS 网络中的 ROS 主节点。当节点离线时,也会向其他节点公布自己的缺席。

在这里插入图片描述

新的 ROS 2 节点向现有节点发送广告。现有节点响应广告,然后建立持续通信。

2.5 子网外的 ROS 通信

子网是将 IP 网络划分为多个较小网段的逻辑分区。ROS 2 节点可与同一子网内的其他节点通信。要检测子网外的节点,可创建一个 DEFAULT_FASTRTPS_PROFILE.xml 文件,配置 MATLAB 使用的特定 DDS 实现。在地址元素内添加要与之通信的子网外系统的 IP 地址列表。请注意,要进行通信,两个系统都必须在各自的 DEFAULT_FASTRTPS_PROFILE.xml 文件中指定对方的地址。将 domainId 元素设置为用于通信的网络的适当值。

将此文件保存在 MATLAB 当前工作目录中。在 MATLAB 之外使用 ROS 2 的系统应将此文件放在运行 ROS 2 应用程序的同一目录下。下面是 DEFAULT_FASTRTPS_PROFILES.xml 文件的示例。

<?xml version="1.0" encoding="UTF-8" ?>
<profiles><participant profile_name="participant_win" is_default_profile="true"><rtps><builtin><metatrafficUnicastLocatorList><locator/></metatrafficUnicastLocatorList><initialPeersList><locator><udpv4><address>192.34.17.36</address></udpv4></locator><locator><udpv4><address>182.30.45.12</address></udpv4></locator><locator><udpv4><address>194.158.78.29</address></udpv4></locator></initialPeersList></builtin></rtps></participant>
</profiles> 

ROS 2 会向 DEFAULT_FASTRTPS_PROFILES.xml 中列出 IP 地址的系统中的节点发布信息。如果 DEFAULT_FASTRTPS_PROFILES.xml 不存在或不包含正确的 IP 地址,则不会收到来自子网外其他机器中节点的信息。

在这里插入图片描述

三、与 ROS 2 发布者和订阅者交换数据

本例展示了如何在 ROS 2 网络中发布和订阅主题。

ROS 2 节点交换数据的主要机制是发送和接收消息。消息在话题上传输,每个话题在 ROS 2 网络中都有一个唯一的名称。如果节点想共享信息,就必须使用发布者向话题发送数据。要接收信息的节点必须使用同一话题的订阅者。除了唯一的名称外,每个话题还有一个信息类型,它决定了允许在特定话题中传输的信息类型。

这种发布者与订阅者之间的通信具有以下特点:

  • 主题用于多对多通信。多个发布者可以向同一个主题发送信息,多个订阅者可以接收信息。

  • 发布者和订阅者通过话题解耦,可以任意顺序创建和销毁。即使没有活跃的订阅者,也可以向话题发布信息。

在这里插入图片描述

除了如何在 ROS 2 网络中发布和订阅主题外,本示例还展示了如何

  • 等待收到新消息,或

  • 使用回调在后台处理新消息

先决条件 开始使用 ROS 2,连接到 ROS 2 网络。

3.1 订阅并等待信息

创建一个包含多个发布者和订阅者的 ROS 2 示例网络。

exampleHelperROS2CreateSampleNetwork

使用 ros2 topic list 查看哪些话题可用。

ros2 topic list
/parameter_events
/pose
/rosout
/scan

假设你想订阅 /scan 主题。使用 ros2subscriber 订阅 /scan 主题。指定订阅节点的名称。如果 ROS 2 网络中已经存在该主题,ros2subscriber 会自动检测其消息类型,因此无需指定。

detectNode = ros2node("/detection");
pause(5)
laserSub = ros2subscriber(detectNode,"/scan");
pause(5)

使用 receive 等待新信息。指定超时时间为 10 秒。输出 scanData 包含接收到的报文数据,status 表示是否成功接收到报文,stustext 则提供有关状态的其他信息。

[scanData,status,statustext] = receive(laserSub,10);

现在,您可以订阅者 laserSub 及其关联节点。

clear laserSub
clear detectNode

3.2 使用回调函数订阅

您可以指定在收到新消息时调用的函数,而不是使用 receive 来获取数据。这样,其他 MATLAB 代码就可以在订阅者等待新消息时执行。如果要使用多个订阅者,回调是必不可少的。

使用回调函数 exampleHelperROS2PoseCallback 订阅 /pose 主题,该函数将收到的消息作为输入。在主工作区和回调函数之间共享数据的一种方法是使用全局变量。定义两个全局变量 posorient

controlNode = ros2node("/base_station");
pause(5)
poseSub = ros2subscriber(controlNode,"/pose",@exampleHelperROS2PoseCallback);
global pos
global orient

/pose 主题收到新的信息数据时,全局变量 posorient 将被分配到 exampleHelperROS2PoseCallback 函数中。

function exampleHelperROS2PoseCallback(message)    % Declare global variables to store position and orientationglobal posglobal orient% Extract position and orientation from the ROS message and assign the% data to the global variables.pos = [message.linear.x message.linear.y message.linear.z];orient = [message.angular.x message.angular.y message.angular.z];
end

稍等片刻,等待网络发布另一条 /pose 消息。显示更新后的值。

pause(3)
disp(pos)
    0.0415   -0.0010   -0.0016
disp(orient)
   -0.0043   -0.0205    0.0338

如果在命令行中多次输入 posorient,就能看到数值在不断更新。

通过清除订阅者变量来停止姿势订阅者

clear poseSub
clear controlNode

注:除使用全局外,还有其他方法从回调函数中提取信息。例如,可以将句柄对象作为附加参数传递给回调函数。有关定义回调函数的更多信息,请参阅为图形对象创建回调函数文档。

3.3 发布消息

创建一个向 /chatter 主题发送 ROS 2 字符串信息的发布器。

chatterPub = ros2publisher(node_1,"/chatter","std_msgs/String");

创建并填充 ROS 2 消息,发送到 /chatter 主题。

chatterMsg = ros2message(chatterPub);
chatterMsg.data = 'hello world';

使用 ros2 topic list 验证 /chatter 主题在 ROS 2 网络中是否可用。

ros2 topic list
/chatter
/parameter_events
/pose
/rosout
/scan

exampleHelperROS2ChatterCallback 会在收到新消息时被调用,并显示消息中的字符串内容。

chatterSub = ros2subscriber(node_2,"/chatter",@exampleHelperROS2ChatterCallback)
chatterSub = ros2subscriber - 属性:TopicName: '/chatter'LatestMessage: []MessageType: 'std_msgs/String'NewMessageFcn: @exampleHelperROS2ChatterCallbackHistory: 'keeplast'Depth: 10Reliability: 'reliable'Durability: 'volatile'

/chatter 话题发布一条消息。观察订阅者回调显示的字符串。

send(chatterPub,chatterMsg)
pause(3)

当订阅者收到字符串消息时,exampleHelperROS2ChatterCallback 函数被调用。

3.4 断开 ROS 2 网络连接

从 ROS 2 网络中删除样本节点、发布者和订阅者。同时清除全局变量 pos 和 orient

clear global pos orient
clear 

该处使用的url网络请求的数据。


如果觉得内容不错,请点赞、收藏、关注

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

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Leetcode—1588.所有奇数长度子数组的和【简单】

2023每日刷题&#xff08;十九&#xff09; Leetcode—1588.所有奇数长度子数组的和 直接法实现代码 int sumOddLengthSubarrays(int* arr, int arrSize){int i 1;int sum 0;int left 0, right;int k;int j 0;while(i < arrSize) {for(left 0; left < arrSize; lef…

虽然许多人表示对Windows 11的透明任务栏不满,但有时效果还是挺好的

Windows 11支持透明任务栏&#xff0c;这项功能可以在几秒钟内启用&#xff0c;但许多人表示他们对它的工作方式不满意。 在今天的指南中&#xff0c;我们将向你展示如何使用此功能&#xff0c;并通过一些技巧进一步自定义任务栏。 如何在Windows 11中使任务栏透明 使用个性…

FMC+DAM驱动LVGL刷屏

前提条件 使用FMC驱动LCD刷屏 LVGL移植 开启DMA 需要开启MEMTOMEMDMA。 开启MPU 有MPU时需要 使能I-cache D-cache时 使用DMA传输数据时要保证数据的完整行和准确性 修改代码 逻辑 等待DMA传输完成然后再刷屏。 修改 在DMA初始化函数中最后添加 注册DMA传输完成调用函…

音频修复增强软件iZotope RX 10 mac中文特点

iZotope RX 10 mac是一款音频修复和增强软件。 iZotope RX 10 mac主要特点 声音修复&#xff1a;iZotope RX 10可以去除不良噪音、杂音、吱吱声等&#xff0c;使音频变得更加清晰干净。 音频增强&#xff1a;iZotope RX 10支持对音频进行音量调节、均衡器、压缩器、限制器等处…

FreeRTOS-定时器\二值信号互斥信号\事件组

FreeRTOS整体知识框架可以参考下文: FreeRTOS整体知识框架 一. FreeRTOS定时器 FreeRTOS定时器 博文路径 FreeRTOS提供了一种软件定时器&#xff0c;用来快速实现一些周期性的操作&#xff0c;并且节约了硬件定时器。不过尽量还是不要做过多的操作&#xff0c;以免影响其他…

MySQL(8):聚合函数

聚合函数介绍 聚合函数&#xff1a; 对一组数据进行汇总的函数&#xff0c;输入的是一组数据的集合&#xff0c;输出的是单个值。 聚合函数类型&#xff1a;AVG(),SUM(),MAX(),MIN(),COUNT() AVG / SUM 只适用于数值类型的字段&#xff08;或变量&#xff09; SELECT AVG(…

verdi技巧分享--合并多个fsdb文件、统计信号边沿

文章目录 0 前言1 如何显示信号高位的02 统计信号的上升沿、下降沿3 合并信号4 将多个fsdb文件合并成一个 0 前言 分享几个这段时间学到的verdi操作 1 如何显示信号高位的0 这个可能对一些有强迫症的有帮助吧 nand相关的操作&#xff0c;有一些特定的cmd&#xff0c;比如 r…

小程序https证书

小程序通常需要与服务器进行数据交换&#xff0c;包括用户登录信息、个人资料、支付信息等敏感数据。如果不使用HTTPS&#xff0c;这些数据将以明文的方式在网络上传输&#xff0c;容易被恶意攻击者截获和窃取。HTTPS通过数据加密来解决这个问题&#xff0c;确保数据在传输过程…

0005Java安卓程序设计-ssm基于Android的网店系统

文章目录 **摘要**目录系统设计开发环境 编程技术交流、源码分享、模板分享、网课教程 &#x1f427;裙&#xff1a;776871563 摘要 随着Internet的发展&#xff0c;人们的日常生活已经离不开网络。未来人们的生活与工作将变得越来越数字化&#xff0c;网络化和电子化。网上管…

【软考中级】软件设计师-下午题

下午题 试题一 黑洞&#xff1a;加工有输入无输出 白洞(奇迹)&#xff1a;加工有输出无输入 灰洞&#xff1a;数据流输入的加工不足以产生输出 结构化语言&#xff1a; IF *** THEN ELSE IF *** THEN ******* END IF END IF 数据流的父子图平衡&#xff0c;如果父子图平衡就不…

人工智能基础_机器学习018_手写代码实现_MBGD小批量梯度下降---人工智能工作笔记0058

然后我们继续来看这里的小批量梯度下降,小批量梯度下降,其实就是 用少量的样本数据,进行梯度下降,上面是公式 然后我们来看代码 import numpy as np 导入数学计算包 #X,y创建数据集X=np.random.rand(100,1) x是100行1列 w,b=np.random.randint(1,10,size=2) 然后获取w和截距…

Kibana使用Timelion根据时间序列展示数据

天行健&#xff0c;君子以自强不息&#xff1b;地势坤&#xff0c;君子以厚德载物。 每个人都有惰性&#xff0c;但不断学习是好好生活的根本&#xff0c;共勉&#xff01; 文章均为学习整理笔记&#xff0c;分享记录为主&#xff0c;如有错误请指正&#xff0c;共同学习进步。…