大家好,欢迎来到IT知识分享网。
ROS-机器人操作系统—-带你一文入门
1.1.ROS发展史
- 2000 ROS起源: 斯坦福大学机器人软件系统框架
- 2007 ROS正式发布:柳树车库(willow Garage) 发起
- 2010 ROS 1.0 发布
- ROS逐渐流行:ROS,Indigo,ROS kinetic(LTS)
1.2.什么是ROS
- ROS 实质上并不是操作系统,而是中间件/类操作系统
- 硬件抽象
- 底层设备控制
- 常用函数实现
- 进程间消息传递
- 包管理
- ROS 官方解释:框架+工具+功能+社区
- 框架:
- 分布式
- 节点: ROS中用节点表示进程,即Node
- 分布式架构优点:扩展性好,软件复用率高
- 进程管理
- 进程通信
- 框架示意图如下:
- 分布式
- 工具:
- 仿真
- 数据可视化
- 图形界面
- 数据记录
- 功能:
- 控制
- 规划
- 视觉
- 建图
- 社区:
- 软件包管理
- 教程
- 文档
- 框架:
1.3 ROS 安装
- ROS:官方网站:www.ros.org
- 打开wiki
- 点击 install
- 选择 ROS kinetic版本
- 自己搭建虚拟机ubuntu,更新软件源
- 按照手册在终端操作即可
- 教程代码包:重德重能教学代码包(github网站)
- 安装开发IDE:Roboware(实质是基于vscode)
2.1 ROS 工程结构
- catkin 工作空间
- catkin: ROS定制的编译构建系统,对CMake的扩展
- 组织和管理功能包的文件夹,以catkin工具编译
- 操作:
- 建立工作空间:
- mkdir -p ~/catkin_ws/src
- cd ~/catkin_ws/
- catkin_make
- 编译:
- cd ~/catkin_ws #注意,一定要切换到此处进行编译
- catkin_make
- source ~/catkin_ws/devel/setup.bash # 编译完成后需要source刷新环境
- 建立工作空间:
- catkin worksapce:
- src:package 源代码,真正写代码的地方
- src通常放置功能包package,Eg.package1,package2.etc
- package是catkin编译的基本单元,catkin编译的对象就是一个又一个的package
- 编译系统会递归的查询每一个package
- package
- ROS软件的基本组织形式,
- catkin编译的基本单元
- 一个package可以包含多个可执行文件(节点)
- 判断package的方式:至少包含CMakeLists.txt,package.xml
- CMakeLists.txt:
- 规定catkin编译的规则,例如,源文件,依赖项,目标文件
- package.xml
- 定义package的属性,例如:包名,版本号.作者,依赖项
- scripts:
- 脚本 (python 文件,shell文件)
- include
- C++头文件
- src
- C++源文件
- python modue
- srv(服务)
- *.srv
- msg(消息)
- *.msg
- 动作(action)
- *.action
- launch:*.launch
- config:*.yaml
- CMakeLists.txt:
- build: cmake & catkin 缓存和中间文件
- devel: 目标文件
- 头文件
- 动态链接库
- 静态链接库
- 可执行文件
- src:package 源代码,真正写代码的地方
- rosbuild:ROS早期采用的编译系统,目前主流的ROS项目已经不采用
- 常用指令:
- rospack
- 查找某个pkg的地址
- rospack find package_name
- 列出本地所有pkg
- rospack list
- 查找某个pkg的地址
- roscd
- 跳转到某个pkg路径下
- roscd package_name
- 跳转到某个pkg路径下
- rosls
- 列举某个pkg下的文件信息
- rosls package_name
- 列举某个pkg下的文件信息
- rosed
- 编辑pkg的文件
- rosed package_name file_name
- 编辑pkg的文件
- catkin_create_pkg
- 创建一个pkg
- catkin_create_pkg <pkg_nmae>[deps]
- 创建一个pkg
- rosdep
- 安装某个pkg所需的依赖
- rosdep install [pkg_name]
- rospack
- Metapackge
- 虚包:无实质内容,但是依赖其他软件包,使得安装更加方便
- Stack:软件包集,现已被Metapackage代替
- 常见metapackgae
- navigation:导航相关的功能包集
- moveit:运动规划相关(主要是机械臂)
- image_pipeline(图像获取,处理相关的功能包集)
- vision_opencv(ROS与OpenCV相关的功能包)
- turtlebot
- pr2_robot
3.1 ROS 通信架构(计算图级)
- PR2 机器人
- roslaunch pr2_bringup pr2.launch
- roslaunch pr2_bringup pr2.launch
- master(节点管理器)
- 每个node启动都要向master注册
- 管理node之间的通信
- roscore
- 启动master
- master:节点管理器
- rosout:日志输出
- parameter server:参数服务器
- 进行参数配置
- node
- ROS的进程
- pkg里的可执行文件运行的实例
- 启动一个node节点
- rosrun [pkg_name][node_name]
- rosnode
- 列出当前运行的node信息
- rosnode list
- 显示某个node的详细信息
- rosnode info [node_name]
- 结束某个node
- rosnode kill[node_name]
- 列出当前运行的node信息
- roslaunch
- 启动master和多个node
- roslaunch[pkg_name][file_name.launch]
- ROS 通信方式:
- Topic
- ROS中的异步通信方式
- Node之间通过publish-subscribe机制通信
- 多对多
- Message
- topic内容的数据类型(类),定义在*.msg文件中
- 基本msg包括:bool,int8,int16,int32,int64(以及uint),float32,float64,string,time,duration,header,可变长数组array[],固定长度数组array[C]
- 指令
- 列出所有topic
- rostopic list
- 显示某个topic的属性信息
- rostopic info /topic_nmae
- 显示某个topic的内容
- rostopic echo /topic_name
- 向某个topic发布内容
- rostopic pub /topic_name …
- rosmsg
- 列出系统所有msg
- rosmsg list
- 显示某个msg内容
- rosmsg show /msg_name
- 列出系统所有msg
- 列出所有topic
- Service
- ROS中的同步通信方式
- Node之间可以通过request-reply方式通信
- 多对一
- 远程过程调用
- srv
- Service 通信的数据格式
- 定义在*.srv文件中
- 指令:
- rosservice<—–>rostopic
- 列出当前所有活跃的service
- rosservice list
- 显示某个service的属性信息
- rosservice info service_name
- 调用某个service
- rosservice call service_name args
- 列出当前所有活跃的service
- rossrv<——>rosmsg
- 列出系统上所有srv
- rossrv list
- 显示某个srv内容
- rossrv show srv_name
- 列出系统上所有srv
- rosservice<—–>rostopic
- Parameter Service(参数服务器)
- 存储各种参数的字典(<key,value>)
- 可用命令行,launch文件和node(API)读写
- 命令
- 列出当前所有参数
- rosparam list
- 显示某个参数的值
- rosparam get param_key
- 设置某个参数的值
- rosparam set param_key param_value
- 保存参数到文件
- rosparam dump file_name
- 从文件读取参数
- rosparam load file_name
- 删除文件参数
- rosparam delete param_key
- 列出当前所有参数
- Action
– 类似Service,带有状态反馈的通信方式
– 通常在长时间,可抢占的任务中
– action
– action 通信的数据格式
– 定义在*.action中
– goal:clien发起,result:server发起,feedback:server发起
- Topic
5.1 ROS常用工具
- Gazebo
- 机器人仿真工具:类似的模拟器有V-Rep,Carsim(用于无人驾驶)
- ODE物理引擎
- 用于动力学,导航,感知等任务的模拟
- RViz
- The Robot Visualization tool 可视化工具
- 方便监控和调试
- rqt
- 可视化工具
- 常用的rqt_graph,rqt_plot,rqt_console
- rqt_graph: 显示通信架构
- rqt_plot:查看原始数据,绘制曲线,查看里程计,码盘
- rqt_console: 查看日志
- rosbag
- ROS 命令行工具
- 记录和回放数据流
- 命令
- 记录某些topic到bag中
- rosbag record <topic_names>
- 记录所有topic到bag中
- rosbag record -a
- 回放bag
- rosbag play
- 记录某些topic到bag中
- 专用工具: Moveit(常用于机械臂领域)
6.1 Client Libray(客户端库,类似于API)&&roscpp
- Client Library
- 提供ROS编程的库
- 例如:建立node,发布消息,调用服务
- 常用的库:
- roscpp库:对应C++
- rospy库: 对应python
- roslisp
- roscpp:
- 由ROS提供的由C++与topic,service,param,timer交互的接口
- ros主要包括:
- ros::init(): 解析传入的ROS参数,使用roscpp第一步需要用到的函数
- void ros::init() //解析ROS函数,为本node命名
- ros::NodeHandle():和topic,service,param等交互的接口
- NodeHandler 实质上为class类
- 常用成员函数:
- 创建话题的publisher
- ros::Publisher advertise(const string &topic,uint32_t queue_size)
- 创建话题的subscriber
- ros::Subscriber subscribe(const string &topic.uint32_t queue_size,void(*)M)
- 创建服务的Server
- 创建服务的client
- 查询某个参数的值
- 给某个参数赋值
- 创建话题的publisher
- ros::master:包含从master查询信息的函数
- master实质上为Namespace 命名空间
- ros::this_node:包含查询这个进程(Node)的函数
- ros::service:包含查询服务的函数
- service为命名空间
- ros::param:包含查询参数服务器的函数,而不需要用到NodeHandler
- param为命名空间
- ros::name:包含处理ROS图资源名称的函数
- ros::init(): 解析传入的ROS参数,使用roscpp第一步需要用到的函数
- 6.2 roscpp中topic的常用(模板)写法:
topic_demo:
功能描述:
两个node,一个发布模拟的GPS信息(格式为自定义,包括坐标和工作状态),另一个接收并处理该信息(计算到原点的距离)
步骤:
1.package
2.msg
3.talker.cpp
4.listener.cpp
5.CMakeList.txt&package.xml
实现:
1.package
$ cd ~/catkin_ws/src
$ catkin_create_pkg topic_demo roscpp rospy std_msgs
2.msg
$ cd topic_demo/
$ mdkir msg
$ vi gps.msg
gps.msg
float32 x
float32 y
string state
catkin_make ++++++> ~/catkin_ws/devel/include/topic_demo/gps.h 使用时只需
#include<topic_demo/gps.h>
topic_demo::gps msg;
3. talker.cpp
#include<ros/ros.h>
#include<topic_demo/gps.h>
int main(int argc char** argv)
{
// 解析参数,命名节点
ros(argc,argv,"talker")
// 创建句柄,实例化node
ros::NodeHandler nh;
// 创建gps信息
topic_demo::gps msg;
msg.x=1.0;
msg.y=1.0;
msg.state="working";
// 创建publisher
ros::Publisher pub=nh.advertise<topic_demo::gps>("gps_info",1);
// 定义循环发布的频率
ros::Rate loop_rate(1.0);
while(ros::OK()){
// 以指数增长,每隔1s
msg.x=1.03*msg.x;
msg.y=1.01*msg.y;
// 输出当前msg
ROS INFO("Talker:GPS:x=%f,y=%f",msg.x,mgs.y)
// 发布消息
pub.publish(msg);
// 根据定义的发布频率,sleep,从而达到周期性发布消息的结果
loop_rate.sleep();
}
return 0;
}
4.listener.cpp
#include<ros/ros.h>
#include<topic_demo/gps.h>
#include<std_msgs/Float332.h>
void gpsCallback(const topic_demo::ggps::ConstPtr&msg)
{
std::msgs:Float32 distance;
distacne.data=sqrt(pow(msg->x,2),pow(msg->y,2))
ROS_INFO("Listener:Distance to togin=%f,state=%s",distance.data,msg->state.c_str());
}
int main(int argc,char**argv)
{
ros::init(argc,argv,"listener");
ros::NodeHandler n;
// 创建subscriber(订阅者)
ros::SubScriber sub=n.subscribe("gps_info",gpsCallback)
// 反复调用当前可触发的回调函数,阻塞
// ros::spin() 函数作用: 清空当前队列
// ros::spinOnce() 非阻塞
ros::spin();
return 0;
}
5.修改CMakeList.txt&package.xml
6.编译catkin_make,执行rosrun
- 6.3 roscpp中service的常用(模板)写法:
service_demo:
功能描述: 两个node,一个发布请求(格式自定义),另一个接收处理信息,并返回信息
步骤:
1. package
2. 定义传输数据格式:srv
3. server.cpp
4. client.cpp
5. CMakeList.txt&package.xml
实现:
1.package
$ cd ~/catkin_ws/src
$ catkin_create_pkg service_demo roscpp rospy std_msgs
2. srv
$ cd service_demo/
$ mkdir srv
$ vi Greeting.srv
Greeting.srv
string name
int32 age
---
strig feedback
++++++++> ~/catkin_ws/devel/include/service_demo/Greeting.h
.../GreetingRequest.h
.../GreetingResponse.h
3.server.cpp
#include<ros/ros.h>
#include<service_demo/Greeting.h>
bool handler_function(service_demo::Greeting::Request &req,service::demo::Greeting::Response &res)
{
// 显示请求信息
ROS_INFO("Request from %s with age %d",req.name.c_str(),req.age);
// 处理请求,写入response
res.feedback="Hi"+req.name+"I am server!";
// 返回true,正确处理了请求
return true;
}
int main(int argc,char**argv)
{
// 解析参数,命名节点
ros::init(argc,argv,"greeting_server");
// 创建句柄,实例化节点
ros::NodeHandler nh;
ros::ServiceServer service=nh.advertiseService("greetings",handler_function);
ros::spin();
return 0;
}
4.client.cpp
#include<ros/ros.h>
#include<service_demo/Greeting.h>
int main(int argc,char**argv)
{
// 解析参数,命名节点
ros::init(argc,argv,"greetings_server");
// 创建节点,实例化节点
ros::NodeHandler nh;
ros::ServiceCLient client=nh.serviceClient<service_demo::Greeting>("greetings");
service::demo::Greeting srv;
service.request.name="Wu";
service.request.age="20";
if(client.call(srv)){
ROS_INFO("Feedback from server: %s",srv.response.feedback);
}else{
ROS_ERROR("Failed to call service greetings.");
return 1;
}
return 0;
}
5.修改CMakeList.txt&package.xml
6.编译catkin_make,执行rosrun
- 6.4 roscpp中Parameter Server的常用(模板)写法:
param_demo:
同一功能的两种API: ros::param和ros::NodeHandler
实现:
#include<ros/ros.h>
int main(int argc,char **argv)
{
ros::init(argc,argv,"greeting_server");
ros::NodeHandler nh;
int parameter1,parameter2,parameter3,parameter4,parameter5;
// 获取参数
ros::param::get("param1",parameter1);
nh.getParam("param2",parameter2);
// 这里123是默认值
nh.param("param3",parameter3,123)
// 设置参数
ros::parameter::set("param4",parameter4);
nh.setParam("param",parameter5);
// 检查参数是否存在
ros::param::has("param5");
nh.hasParam("param5");
// 删除参数
ros::param::del("param5");
// 删除参数
ros::param::del("param5");
nh.deleteParam("param6");
return 0;
}
7.1 Client Libray&&rospy
- rospy:
- Node,Topic,Service,Param,Time
- rospy-Node 相关函数
- rospy-Topic相关函数
- rospy-Service 相关函数
- rospy-Param相关函数
- rospy-Time相关
- 7.2 rospy中topic的常用(模板)写法:
topic_demo:
功能描述:
两个node,一个发布模拟的GPS信息(格式为自定义,包括坐标和工作状态),另一个接收并处理该信息(计算到原点的距离)
步骤:
1.package
2.msg
3.talker.py
4.listener.py
5.CMakeList.txt&package.xml
实现:
1.package
$ cd ~/catkin_ws/src
$ catkin_create_pkg topic_demo roscpp rospy std_msgs
2.msg
$ cd topic_demo/
$ mdkir msg
$ vi gps.msg
gps.msg
float32 x
float32 y
string state
catkin_make ++++++> ~/catkin_ws/devel/include/topic_demo/msg/_init_.py
topic_demo::gps msg;
3. talker.py
#!/usr/bin/env python
import rospy
from topic_demo.msg import msg
def talker():
pub=rospy.Publisher('gps_info',gps,queue_size=10)
ros.init_node('pytalker',anonymous=True)
rate=rospy.Rate(1)
x=1.0
y=2.0
state='Working'
while not rospy is_shutdown():
ros.loginfo('Ta;ker:GPS:x=%,y=%f)
x=1.03*x
y=1.01*y
rate.sleep()
if __name__=='__main__':
talker()
4.listener.py
#!/usr/bin/env python
import rospy
import math
from topic_demo.msg import gps
def callback(gps):
distance=math.sqrt(math.pow(gps.x,2),math.pow(gps.y,2))
def listener():
ros.init_node('pylistener')
rospy.Subscriber('gps_info',gps,callback)
rospy.spin()
if __name__=='__main__':
listener()
5.修改CMakeList.txt&package.xml
6.编译catkin_make,执行rosrun
- 7.3 rospy中service的常用(模板)写法:
service_demo:
功能描述: 两个node,一个发布请求(格式自定义),另一个接收处理信息,并返回信息
步骤:
1. package
2. 定义传输数据格式:srv
3. server.py
4. client.py
5. CMakeList.txt&package.xml
实现:
1.package
$ cd ~/catkin_ws/src
$ catkin_create_pkg service_demo roscpp rospy std_msgs
2. srv
$ cd service_demo/
$ mkdir srv
$ vi Greeting.srv
Greeting.srv
string name
int32 age
---
strig feedback
++++++++> ~/catkin_ws/devel/lib/python2.7/dis-packages/service_demo/srv/__init__.py
3.server.py
#!/usr/bin/env python
import rospy
from service_demo.srv import *
def server_srv():
rospy.init_node('greeting_server')
# 定义程序的server端
s=rospy.Service('greetings',Greeting,handle_function)
rospy.info('Ready to handle the request:')
rospy.spin()
def handle_function(req):
rospy.loginfo('Request from',req.name,'with age',req.age)
return GreetingResponse('Hi %s I'm server!,%server.name)
if __name__='__main__':
server_srv()
4.client.py
import rospy
from service_demo.srv import *
def client_srv:
rospy.init_node('greeting_client')
rospy.wait_for_service('greetings')
try:
greetings_client=rospy.ServiceProxy('greetings',Greeting)
rosp=greetings_client('HAN',20)
rospy.loginfo('Message From Server:%s',%rosp.feedback)
except rospy.ServiceException,e:
rospy.logwarn('Service call failed:%s'%e)
if __name__=='__main__':
client_srv()
5.修改CMakeList.txt&package.xml
6.编译catkin_make,执行rosrun
8.1.ROS之TF&URDF
- TF
- TF(TransForm)
- 坐标变换(位置+姿态)
- 坐标系数据维护的工具
- 坐标转换的标准,话题,工具,接口
- tf tree
- TransformStamped.msg
- TF in C++
- 基本数据类型
- tf::TransormBroadcaster类
- tf::TransformListener类
- TF in python
- 基本数据类型
- tf::TransormBroadcaster类
- tf::TransformListener类
- 指令:
- 根据当前的tf树创建一个pdf图
- rosrun tf view_frames
- 查看当前的tf树
- rosrun rqt_tf_tree rqt_tf_tree
- 查看两个frame之间的坐标关系
- rosrun tf tf_echo [reference_frame][target_frame]
- 根据当前的tf树创建一个pdf图
- TF(TransForm)
- urdf:unifed Robot Description Format 统一机器人描述格式
9.1.SLAM与Map
- SLAM:Simutaneous Localization And Mpping
- Gamapping SLAM包
- Karto SLAM包
10.1 Navaigation-NavigationStack (路径规划,导航)
- movebase 与插件
- 全局规划(静态),局部规划(动态),处理异常行为
- costmap(代价地图)
- 给导航使用,用于路径规划
- 两张,2维,多层
- static layer(map)
- 静态,不变
- obstacle layser
- 动态,支持3D点云的投影
- infaltion layer
- 膨胀
- static layer(map)
- MapServer
- 建立地图之后,提供地图
- 命令
- 启动map_server 发布地图:
- rosrun map_server map_server my_map.yaml
- 保存地图
- rosrun map_server amp_saver [-f my_map]
- 启动map_server 发布地图:
- AMCL(蒙特卡洛自适应定位)
- 定位
- 定位
(源于mooc 中科院软件所video note) 学习总结,欢迎r读者批评指正!
免责声明:本站所有文章内容,图片,视频等均是来源于用户投稿和互联网及文摘转载整编而成,不代表本站观点,不承担相关法律责任。其著作权各归其原作者或其出版社所有。如发现本站有涉嫌抄袭侵权/违法违规的内容,侵犯到您的权益,请在线联系站长,一经查实,本站将立刻删除。 本文来自网络,若有侵权,请联系删除,如若转载,请注明出处:https://yundeesoft.com/11217.html