ROS1/2机器人操作系统与时间Time的不解之缘
时间对于机器人操作系统非常重要。
所有机器人类的编程中所涉及的变量如果需要在网络中传输都需要这个数据结构的时间戳。
宏观上,ROS1、ROS2各版本都有官方支持的时间节点。
ROS时钟--支持时间倒计时小工具
效果如下:
如果要部署机器人操作系统,ROS1最好选择noetic,ROS2最好选择humble。
学习核心要点:
ros1:indigo、kinetic、melodic、noetic均可。
ros2:foxy、humble均可。
时钟和时间
官网介绍了支持编程的 ROS 原理和应用,这些编程既可以实时运行,也可以模拟时间运行,后者可能更快或更慢。
背景知识
许多机器人算法本质上依赖于定时和同步。 为此,要求在ROS网络中运行的节点具有同步的系统时钟,以便它们可以准确地报告事件的时间戳。
与此同时,在很多实际案例中,能够控制系统的进度很重要。
实时计算需要严格的时间控制。还有后续处理如下:
在回放记录的数据时,支持对时间进度的加速、减慢或阶梯控制通常非常有价值。 此控件允许到达特定时间并暂停系统,以便可以对其进行深入调试。 可以使用传感器数据的日志来执行此操作,但是如果传感器数据与系统的其余部分不同步,则会破坏许多算法。
使用抽象时间源的另一个重要用例是,当针对模拟机器人而不是真实机器人运行记录的数据时。 根据仿真特性,模拟器可能能够比实时运行得快得多,或者可能需要运行得更慢。 比实时运行得更快的速度对于高级测试以及允许重复系统测试很有价值。 对于精度比速度更重要的复杂系统,比实时仿真慢是必要的。 通常,仿真是系统的限制因素,因此模拟器可以成为更快或更慢播放的时间源。 此外,如果模拟暂停,系统也可以使用相同的机制暂停。
为了提供简化的时间接口,将提供 ROS 时间和持续时间数据类型。 要查询最新时间,将提供 ROS 时钟接口。 时间源可以管理一个或多个时钟实例。
使用抽象时间的挑战
有许多同步算法,它们通常可以实现比网络上设备之间网络通信延迟更好的精度。 但是,这些算法利用了有关时间恒定和连续性质的假设。
使用抽象时间的一个重要方面是能够操纵时间。 在某些情况下,加速、减慢或完全暂停时间对于调试非常重要。
支持暂停时间的能力要求不假设时间值总是在增加。
当通信时间传播的变化时,通信网络中的延迟成为一个挑战。 时间抽象的任何更改都必须传达给图中的其他节点,但会受到正常的网络通信延迟的影响。 这种不准确性与通信延迟成正比,也与模拟时间与实时相比前进的速率增加成正比(“实时因素”)。 如果在使用时间抽象时需要非常准确的时间戳,可以通过减慢实时因素来实现,从而使通信延迟相对较小。
最后一个挑战是时间抽象必须能够向后跳转,此功能对于日志文件播放非常有用。 此行为类似于负日期更改后的系统时钟,并且要求开发人员使用时间抽象来确保其算法可以处理不连续性。 必须为开发人员 API 提供适当的 API,以启用向前和向后的时间跳转通知。
使用介绍
通常,ROS 客户端库将使用计算机的系统时钟作为时间源,也称为“clock”或“挂钟”(如实验室墙上的时钟)。但是,当运行模拟或回放记录的数据时,通常需要让系统使用模拟时钟,以便可以加速、减慢或逐步控制系统的感知时间。例如,如果要将传感器数据回放到系统中,则可能希望时间与传感器数据的时间戳相对应。
为了支持这一点,ROS 客户端库可以监听用于发布“模拟时间”的 /clock 主题。
为了使代码利用 ROS 模拟时间,所有代码都必须使用适当的 ROS 客户端库时间 API 来访问时间和睡眠,而不是使用语言原生例程。这将使您的系统无论使用挂钟还是模拟时钟,都能进行一致的时间测量。下面简要介绍了这些 API,但您应该熟悉所选的客户端库以获取更多详细信息。
在多台计算机上使用挂钟时间时,在它们之间同步时间非常重要。ROS 不提供此功能,因为已经有成熟的方法(例如 ntp,我们推荐的同步工具是 chrony)来执行此操作。如果不同步多台机器的时钟,它们将不会就 tf 中使用的时间计算达成一致。
注意:这不是实时系统的 API!
使用 /clock 主题中的模拟时间
为了让ROS节点根据/clock主题使用模拟时间,在初始化节点之前,必须将/use_sim_time参数设置为true。这可以在启动文件中或从命令行完成。
如果设置了 /use_sim_time 参数,ROS 时间 API 将返回 time=0,直到收到来自 /clock 主题的值。然后,时间将仅在收到来自 /clock 主题的消息时更新,并且在更新之间保持不变。
对于使用模拟时间时持续时间的计算,客户端应始终等到收到第一个非零时间值后再开始,因为 /clock 主题中的第一个模拟时间值可能很高。
注意:在 ROS C Turtle 之前,节点会自动订阅 /clock 主题,如果有任何内容发布到 /clock 主题,节点将使用模拟时间。
运行时钟服务器
时钟服务器是发布到 /clock 主题的任何节点,单个 ROS 网络中不应运行多个节点。在大多数情况下,时钟服务器是模拟器或日志回放工具。
为了解决启动顺序的任何问题,在使用时钟服务器的任何启动文件中将 /use_sim_time 参数设置为 true 非常重要。如果您正在播放带有 rosbag 播放的包文件,则使用 --clock 选项将在播放包文件时运行时钟服务器。
最简单的案例演示:
ROS1
roscpp
//Get the time and store it in the time variable.
ros::Time time = ros::Time::now();
//Wait a duration of one second.
ros::Duration d = ros::Duration(1, 0);
d.sleep();
rospy
rospy.get_rostime() #get time as rospy.Time instance
rospy.get_time() #get time as float secs
rospy.sleep(duration)
具体cpp案例:
获取当前时间
ros::Time begin = ros::Time::now();
创建时间和持续时间实例
浮点数
ros::Time a_little_after_the_beginning(0.001);
ros::Duration five_seconds(5.0);
整型数
ros::Time a_little_after_the_beginning(0, 1000000);
ros::Duration five_seconds(5, 0);
转换时间和持续时间实例
double secs =ros::Time::now().toSec();ros::Duration d(0.5);
secs = d.toSec();
时间和持续时间算术
ros::Duration two_hours = ros::Duration(60*60) + ros::Duration(60*60);
ros::Duration one_hour = ros::Duration(2*60*60) - ros::Duration(60*60);
ros::Time tomorrow = ros::Time::now() + ros::Duration(24*60*60);
ros::Duration negative_one_day = ros::Time::now() - tomorrow;
云端实践-蓝桥ROS云课
使用turtlesim看一下时间戳的重要性。
在三个终端分别输入:
roscore
rosrun turtlesim turtlesim_node [13:46:56]
[ INFO] [1677476826.846406306]: Starting turtlesim with node name /turtlesim
[ INFO] [1677476826.858068449]: Spawning turtle [turtle1] at x=[5.544445], y=[5.544445], theta=[0.000000]
rosrun turtlesim draw_square [13:46:58]
[ INFO] [1677476941.925480026]: New goal [7.544445 5.544445, 0.000000]
[ INFO] [1677476943.845465404]: Reached goal
[ INFO] [1677476943.845537205]: New goal [7.448444 5.544445, 1.570796]
[ INFO] [1677476947.797971492]: Reached goal
[ INFO] [1677476947.798056675]: New goal [7.454037 7.544437, 1.568000]
[ INFO] [1677476949.733859442]: Reached goal
[ INFO] [1677476949.733924604]: New goal [7.453769 7.448437, 3.138796]
[ INFO] [1677476953.669993390]: Reached goal
[ INFO] [1677476953.670053662]: New goal [5.453913 7.472422, 3.129600]
[ INFO] [1677476955.605801148]: Reached goal
[ INFO] [1677476955.605865104]: New goal [5.549906 7.471271, 4.700396]
[ INFO] [1677476959.541884586]: Reached goal
[ INFO] [1677476959.541945308]: New goal [5.507532 5.471720, 4.691200]
[ INFO] [1677476961.478066122]: Reached goal
[ INFO] [1677476961.478127597]: New goal [5.509565 5.567698, 6.261996]
[ INFO] [1677476965.413272345]: Reached goal
[ INFO] [1677476965.413332146]: New goal [7.508642 5.506937, 6.252800]
[ INFO] [1677476967.349857822]: Reached goal
[ INFO] [1677476967.349916915]: New goal [7.412686 5.509853, 1.540412]
[ INFO] [1677476971.285716384]: Reached goal
这里面时间不是常见格式的,那么参考如下:
rqt→console
其中关于时间:
ros::Timer timer = nh.createTimer(ros::Duration(0.016), boost::bind(timerCallback, _1, twist_pub));
Node: /draw_square
Time: 13:55:19.311055762 (2023-02-27)
Severity: Info
Published Topics: /rosout, /turtle1/cmd_velNew goal [5.306689 5.861878, 5.998100]Location:
/tmp/binarydeb/ros-kinetic-turtlesim-0.7.1/tutorials/draw_square.cpp:printGoal:41
#include <boost/bind.hpp>
#include <ros/ros.h>
#include <turtlesim/Pose.h>
#include <geometry_msgs/Twist.h>
#include <std_srvs/Empty.h>turtlesim::PoseConstPtr g_pose;
turtlesim::Pose g_goal;enum State
{FORWARD,STOP_FORWARD,TURN,STOP_TURN,
};State g_state = FORWARD;
State g_last_state = FORWARD;
bool g_first_goal_set = false;#define PI 3.141592void poseCallback(const turtlesim::PoseConstPtr& pose)
{g_pose = pose;
}bool hasReachedGoal()
{return fabsf(g_pose->x - g_goal.x) < 0.1 && fabsf(g_pose->y - g_goal.y) < 0.1 && fabsf(g_pose->theta - g_goal.theta) < 0.01;
}bool hasStopped()
{return g_pose->angular_velocity < 0.0001 && g_pose->linear_velocity < 0.0001;
}void printGoal()
{ROS_INFO("New goal [%f %f, %f]", g_goal.x, g_goal.y, g_goal.theta);
}void commandTurtle(ros::Publisher twist_pub, float linear, float angular)
{geometry_msgs::Twist twist;twist.linear.x = linear;twist.angular.z = angular;twist_pub.publish(twist);
}void stopForward(ros::Publisher twist_pub)
{if (hasStopped()){ROS_INFO("Reached goal");g_state = TURN;g_goal.x = g_pose->x;g_goal.y = g_pose->y;g_goal.theta = fmod(g_pose->theta + PI/2.0, 2*PI);printGoal();}else{commandTurtle(twist_pub, 0, 0);}
}void stopTurn(ros::Publisher twist_pub)
{if (hasStopped()){ROS_INFO("Reached goal");g_state = FORWARD;g_goal.x = cos(g_pose->theta) * 2 + g_pose->x;g_goal.y = sin(g_pose->theta) * 2 + g_pose->y;g_goal.theta = g_pose->theta;printGoal();}else{commandTurtle(twist_pub, 0, 0);}
}void forward(ros::Publisher twist_pub)
{if (hasReachedGoal()){g_state = STOP_FORWARD;commandTurtle(twist_pub, 0, 0);}else{commandTurtle(twist_pub, 1.0, 0.0);}
}void turn(ros::Publisher twist_pub)
{if (hasReachedGoal()){g_state = STOP_TURN;commandTurtle(twist_pub, 0, 0);}else{commandTurtle(twist_pub, 0.0, 0.4);}
}void timerCallback(const ros::TimerEvent&, ros::Publisher twist_pub)
{if (!g_pose){return;}if (!g_first_goal_set){g_first_goal_set = true;g_state = FORWARD;g_goal.x = cos(g_pose->theta) * 2 + g_pose->x;g_goal.y = sin(g_pose->theta) * 2 + g_pose->y;g_goal.theta = g_pose->theta;printGoal();}if (g_state == FORWARD){forward(twist_pub);}else if (g_state == STOP_FORWARD){stopForward(twist_pub);}else if (g_state == TURN){turn(twist_pub);}else if (g_state == STOP_TURN){stopTurn(twist_pub);}
}int main(int argc, char** argv)
{ros::init(argc, argv, "draw_square");ros::NodeHandle nh;ros::Subscriber pose_sub = nh.subscribe("turtle1/pose", 1, poseCallback);ros::Publisher twist_pub = nh.advertise<geometry_msgs::Twist>("turtle1/cmd_vel", 1);ros::ServiceClient reset = nh.serviceClient<std_srvs::Empty>("reset");ros::Timer timer = nh.createTimer(ros::Duration(0.016), boost::bind(timerCallback, _1, twist_pub));std_srvs::Empty empty;reset.call(empty);ros::spin();
}
相关文章:
ROS1/2机器人操作系统与时间Time的不解之缘
时间对于机器人操作系统非常重要。所有机器人类的编程中所涉及的变量如果需要在网络中传输都需要这个数据结构的时间戳。宏观上,ROS1、ROS2各版本都有官方支持的时间节点。ROS时钟--支持时间倒计时小工具效果如下:如果要部署机器人操作系统,R…...
华为OD机试真题2022(JAVA)
华为机试题库已换 →→→ 华为OD机试2023(JAVA) 以下题目为旧版题库,供大家课外消遣 基础题: 序号题目分值1查找众数及中位数1002出错的或电路1003连续字母长度1004分班1005计算面积1006最远足迹1007判断一组不等式是否满足约束…...
【3】MyBatis+Spring+SpringMVC+SSM整合一套通关
三、SpringMVC 1、SpringMVC简介 1.1、什么是MVC MVC是一种软件架构的思想,将软件按照模型、视图、控制器来划分 M:Model,模型层,指工程中的JavaBean,作用是处理数据 JavaBean分为两类: 一类称为实体…...
20道前端高频面试题(附答案)
ES6新特性 1.ES6引入来严格模式变量必须声明后在使用函数的参数不能有同名属性, 否则报错不能使用with语句 (说实话我基本没用过)不能对只读属性赋值, 否则报错不能使用前缀0表示八进制数,否则报错 (说实话我基本没用过)不能删除不可删除的数据, 否则报错不能删除变量delete p…...
android EditText设置后缀
有两种实现方案。 方案一:是自己写一个TextWatcher。 方案二:是重写TextView的getOffsetForPosition方法,返回一个计算好的offset。 我在工作时,使用的是方案一。在离职之后,我还是对这个问题耿耿于怀,所以…...
prometheus+cadvisor监控docker
官方解释 cAdvisor(ContainerAdvisor)为容器用户提供了对其运行容器的资源使用和性能特性的了解。它是一个正在运行的守护程序,用于收集、聚合、处理和导出有关正在运行的容器的信息。具体来说,它为每个容器保存资源隔离参数、历史…...
正演(1): 二维声波正演模拟程序(中心差分)Python实现
目录 1、原理: 1)二维声波波动方程: 编辑 2)收敛条件(不是很明白) 3)雷克子波 4)二维空间衰减函数 5)边界吸收条件 (不是很明白。。) 2、编程实现 1)参数设置&…...
珠海数据智能监控器+SaaS平台 轻松实现SMT生产管控
数据智能监控器 兼容市面上99%的SMT设备 直接读取设备生产数据与状态,如:计划产出、实际产出、累计产出、停机、节拍、线利用率、直通率、停产时间、工单状态、OEE…… 产品功能价值 ◎ OEE不达标报警,一手掌握生产效能 ◎ 首检/巡检/成…...
习题22对前面21节的归纳总结
笨方法学python --习题22 Vi---Rum 于 2021-01-12 14:16:10 发布 python 习题22 这节内容主要是归纳总结 ex1.py 第一次学习 1.print:打印 2.# :是注释的意思,井号右边的内容不再执行 3.end"":,在句子结尾加上这个就不会再换行…...
使用Vite快速构建前端React项目
一、Vite简介 Vite是一种面向现代浏览器的一个更轻、更快的前端构建工具,能够显著提升前端开发体验。除了Vite外,前端著名的构建工具还有Webpack和Gulp。目前,Vite已经发布了Vite3,Vite全新的插件架构、丝滑的开发体验,可以和Vue3完美结合。 相比Webpack和Gulp等构建工具…...
人工智能高等数学--人工智能需要的数学知识_微积分_线性代数_概率论_最优化---人工智能工作笔记0024
然后我们看一下人工智能中需要的数学知识 数学知识是重要的,对于理解人工智能底层原理来说很重要,但是工作中 工作中一般都不会涉及的自己写算法之类的,只是面试,或者理解底层原理的时候需要 然后看一下人工智能需要哪些数学知识 这里需要微积分 线性代数 概率论 最优化的知识…...
阿里大数据之路总结
一、数据采集 二、数据同步 2.1、数据同步方式: 数据同步的三种方式:直连方式、数据文件同步、数据库日志解析方式 关系型数据库的结构化数据:MYSQL、Oracle、DB2、SQL Server非关系型数据库的非结构化数据(数据库表形式存储&am…...
ABAP中Literals的用法(untyped literal vs. typed literal)
1. 什么是Literals ? Literals的字面意思即“文字”。其实,Literals就是在ABAP代码中直接指定的一个字符串,但注意哦,这个字符串并不意味着其类型一定是string哦。 要弄清这个概念,就要清楚ABAP对于Literals 的定义和处理方式。…...
tensorflow1.14.0安装教程
1首先电脑安装好Anaconda3(Anaconda介绍、安装及使用教程 - 知乎 (zhihu.com),) 蟒蛇 |全球最受欢迎的数据科学平台 (anaconda.com) 2打开Anaconda Prompt(本人更新win11后,主菜单不再显示,那么我们可以打…...
C++赋值运算符重载
赋值运算符重载 目录赋值运算符重载示例1:示例2:示例3:示例4:很巧妙的是,在编写这篇文章时(2023年2月27日),再加100天就是6月7日,恰好是今年高考的百日誓师! …...
网络性能总不好?专家帮你来“看看”— CANN 6.0 黑科技 | 网络调优专家AOE,性能效率双提升
随着深度学习模型复杂度和数据集规模的增大,计算效率的提升成为不可忽视的问题。然而,算法网络的多样性、输入数据的不确定性以及硬件之间的差异性,使得网络调优耗费巨大成本,即使是经验丰富的专家,也需要耗费数天的时…...
Qss自定义属性
QSS自定义属性 更多精彩内容👉个人内容分类汇总 👈👉QSS样式学习 👈文章目录QSS自定义属性[toc]前言一、实现效果二、使用方式1.QSS设置Q_PROPERTY属性样式2.QSS设置动态属性样式3.qproperty-<属性名称>语法14.qproperty-&…...
连接金蝶云星空,数据交互轻松搞定!丨三叠云
金蝶云星空 路径 拓展 >> 插件 功能简介 新增插件「金蝶云星空」。 用户可通过配置「金蝶云星空」插件,就可以实时获取「金蝶云星空」的数据,同时支持回填数据至金蝶系统内。 地图视图 路径 表单 >> 表单设计 功能简介 新增「地图视…...
JSX是什么,React为什么使用JSX,babel怎么转译JSX的
JSX是什么,React为什么使用JSX,babel怎么转译JSX的 在前端的框架中有两种“描述UI”的方案,一种是JSX语法,一种是模板语言。 其中React就是选择的JSX,Vue就是选择的模板语言。 JSX其实就是一个语法糖,在…...
从工地转行软件测试,拿下13k+年终奖是种什么体验?
最近,一则名为《我:毕业五年,存款5000。她:中传硕士,火锅店保洁》的视频走红网络,两位名校毕业生看似高开低走的就业经历,引起了很多人的共鸣。她们所传达的并不是所谓的躺平、摆烂,而是希望更多…...
前端面试题 —— 计算机网络(二)
目录 一、POST和PUT请求的区别 二、GET方法URL长度限制的原因 三、页面有多张图片,HTTP是怎样的加载表现? 四、HTTP2的头部压缩算法是怎样的? 五、说一下HTTP 3.0 六、HTTP协议的性能怎么样? 七、数字证书是什么?…...
山东大学机器学习期末2022
接力:山东大学机器学习期末2021 本来是不想写的,因为不想回忆起考试时啥也不会的伤痛,没想到最后给分老师海底捞,心情好了一些,还是一块写完 备考建议:多看ppt,多看ppt,多看ppt 山东…...
FEBC2022|打造VR内容生态闭环 佳创视讯持续加码轻量化内容建设
2月24日,由陀螺科技主办的未来商业生态链接大会作为 2023 癸卯兔年开年率先召开的行业重要影响力盛会在深圳成功召开。今年大会云集了科技、软件、游戏、XR等元宇宙领域的世界500强、上市公司及行业独角兽企业,围绕游戏、元宇宙、XR、数字营销等多项热门…...
Redis常见的数据类型命令
文章目录Redis 常见的数据类型及命令一、常见的NoSQL二、Redis 简介三、key 键的一些操作命令四、Redis的五种基本数据结构1、String(字符串)介绍常用命令1.1 set/get1.2 append1.3 strlen1.4 setex1.5 mset/mget1.6 setrange/getrange1.7 setnx1.8 incr…...
Python3+Selenium3自动化测试-(准备)
最近在学习selenium自动化测试相关的内容,所以将实际准备情况做一记录, # 系统:win10(64位) # 浏览器:Chrome(67.0)、Firefox(61.0)、IE # python版本:3.6.5 # Selenium:3.13.0Selenium简介 Selenium是一…...
VUE的安装和创建
安装node.js 进入node官网进行下载,然后一直下一步。 测试是否安装成功: 命令提示窗下执行:npm -v 若出现版本号,则安装成功。 安装npm源: npm config set registry http://registry.npm.taobao.org 查看:…...
ETL工具(kettle) 与 ETL产品(BeeloadBeeDI) 差之毫厘,谬以千里
E T L——是英文Extract-Transform-Load的缩写,用来描述将数据从来源端经过抽取(extract)、转换(transform)、加载(load)至目的端的过程。工具——原指工作时所需用的器具,后引申为达…...
轻松入门H3C无线AC上线AP【入门篇】
我们知道华三的最新模拟器支持了无线AC的配置,今天就浅浅的出个无线AC的教程,你上也会的那种。今天我们模拟的是二层环境下,笔者准备了2个AP,以此展示AP上线到AC的教程,并且用手机测试WiFi连接正常,且客户端…...
尚医通(二十五)就医提醒和预约统计
目录一、就医提醒1、搭建定时任务模块二、后台管理系统-预约统计功能1、开发每天预约数据接口2、封装远程调用接口3、搭建统计分析模块4、整合统计功能前端一、就医提醒 我们通过定时任务,每天8点执行,提醒就诊 1、搭建定时任务模块 (1&…...
网页js版音频数字信号处理:H5录音+特定频率信号的特征分析和识别提取
文章目录一、网页中的音频数据源二、FFT:时域转频域三、信号的特征分析四、信号的识别提取附录音频数字信号处理 Audio DSP (Digital Signal Processing) 是一个复杂又专业的话题,本文介绍的是如何从音频中实时分析和识别出特定频率信号的一种方法&#…...
iis新建网站/seo群发软件
在GDB调试程序的时候,如果程序带有很长的参数列表,或者调试命令本身很长,需要频繁启动调试会话时,频繁输入参数或者命令严重拖慢调试节奏,这里记录一个GDB非常有用的参数-x,可以将调试参数和调试命令以调试…...
wordpress api文章列表接口/南通百度seo代理
Github项目地址:https://github.com/feser-xuan/Arithmetic.git1、需求分析软件基本功能要求如下:程序可接收一个输入参数n,然后随机产生n道加减乘除练习题,每个数字在 0 和 100 之间,运算符在3个到5个之间。为了让小学…...
长沙企业建站在线咨询/郴州网站定制
诺基亚808 PureView 凭借其4100万像素摄像头获得了2012影像界TIPA大奖,其超高的像素几乎秒杀市面上所有单反,不过官方宣称808 PureView在印度和俄罗斯首发,国内还不知道要等到什么时候。808 PureView的照片大家是看多了,但是对于其…...
公益网站建设/百度小说风云榜排行榜官网
2019独角兽企业重金招聘Python工程师标准>>> 1.IDEA快捷键1.1.进入方法所属的类:Ctrl左击类1.2.进入方法:CtrlAlt左击类2.用JQuery选择器的时候,判断提示语需要成对出现,比如设置按钮置灰,那么else就应该设置成按钮取消置灰3.SpringMVC中,前端传递的参数均可以在Htt…...
学做分类网站/如何制作一个自己的网站
Hello,大家好,今天给大家继续讲解排序系列。可能有细心的"鸟友"会问,你不是讲解排序吗?怎么今天的主题是一个查找方法咧? 不错,因为考虑到在实际项目中,排序和查找经常是两个好基友,二…...
网页设计的好处/专业排名优化工具
转自 https://blog.csdn.net/u012702547/article/details/77823434 这个系列我感觉真的太好了,可以一步一步的了解spring cloud 的搭建以及更深层次的东西,对想学这门技术的朋友真的入门特别的快,感谢这位大哥的分享,我也会持续的…...