1、catkin 是ros定制的编译构建系统,是对cmake的扩展。其基本用法与cmake基本相同(catkin是用来编译ros程序的)。
2、catkin_make 是初始化工作空间的命令。
3、创建工作空间:
#创建工作空间。工作空间catkin_ws名字可以随意,但是其中必须要有src目录,用来放源代码
$ mkdir -p ~/catkin_ws/src
4、对代码进行编译:
#必须要回到工作空间的目录下,才能进行catkin_make
$ cd ~/catkin_ws/
#进行编译,会产生build 和 devel 这两个目录。
$ catkin_make
#编译完成后要source刷新环境,让新的配置起作用。
$ source ~/catkin_ws/devel/setup.bash
5、catkin工作空间的结构分析:
每个目录中的内容如下
(1)、src目录下是各种功能包package。package是catkin编译的基本单元,catkin编译的对象是一个一个的package功能包。所以在src下可以有多个package,在编译的时会递归的在src目录下寻找package功能包来进行编译。src下的功能包可以按如下的结构进行组织:
[1]、 在src目录下可以创建多个功能包package,创建功能包的命令如下,执行创建命令后将会在src 目录下生成CMakeList.txt 和 package.xml 文件的模板,根据编译的需要来对其进行修改即可。CMakeList.txt 是规定catkin的编译规则;package.xml是一个自我说明文件,一般只需要修改
# 在src目录下创建功能包,依赖项deps为可选项
$ catkin_creat_pkg package_name [deps]
[2]、 package是ROS软件的基本组织形式。在ROS 中所有的软件都被组织成软件包的形式,称为ros软件包或者功能包,有时也简称包。所以package(ROS软件包)是一组用于实现特定功能的相关文件的集合,包括可执行文件(可有多个可执行文件)和其他支持文件。
[3]、 一个目录为package,则其中必须要包含有CMakeList.txt 和 package.xml 文件,这是最基本的组成。除此之外,package中还可以包含如下内容:
[3]、常用的包管理指令:
# 查找某个pkg的地址
$ rospack find package_name
# 列出本地所有pkg
$ rospack list
# 刷新所有package的位置记录
$ rospack profile
# 跳到某个pkg的路径下
$ roscd package_name
# 列出某个pkg下的文件信息
$ rosls package_name
# 编辑pkg中的文件
$ rosed package_name file_name
# 创建一个pkg,一般在src目录下执行该操作。
$ catkin_creat_pkg package_name [deps]
# 安装某个pkg所需的依赖(例如安装从GitHub上下载的功能包)
$ rosdep install [pkg_name]
(2)、Metapackage 也称为虚包,它与普通的包的区别在于:它里面并没有什么实质性的内容,只是有很多软件依赖包。通过安装这种包的形式来将其他的软件包组织起来。
(1)、每个node启动时都要向master注册。如node1需要启动,则首先向master进行注册,才可以启动。
(2)、master来管理节点间的通信。如node1和node2两个节点可以在master的介绍下进行相互通信。
(3)、启动master 的命令为: roscore 。启动ros管理器后,还将顺带启动rosout(日志输出) 和 parameter server(参数服务器)。
(4)、再启动node,一个节点即为一个可执行文件,它可以通过ROS与其它节点进行通信。每个node一般就是实现一个功能,即一个进程。常用的节点命令:
# 启动一个node,允许你使用包名直接运行一个包内的节点(而不需要知道这个包的路径)。
$ rosrun package_name node_name
# 列出当期运行的node信息
$ rosnode list
# 显示某个node的详细信息
$ rosnode info node_name
# 结束某个node
$ rosnode kill node_name
(4)roslaunch启动launch文件,launch文件是用来同时启动多个节点的文件。
# 启动master 和多个node
$ roslaunch pkg_name launch_file_name.launch
(1)、Topic
[1]、ROS中是异步通信方式。node之间通过订阅话题的方式来进行通信。
[2]、Topic 的文件格式为 *.msg
[3]、Topic中的常用命令
# 列出当前所有topic
$ rostopic list
# 显示某个topic的属性信息
$ rostopic info /topic_name
# 显示某个topic的内容
$ rostopic echo /topic_name
# 向topic发布内容,也可以向多个topic发布内容
$ rostopic pub /topic_name ...
# 列出系统上所有的msg
$ rosmsg list
# 显示某个msg的内容
$ rosmsg show /msg_name
(2)、Service
[1]、 ROS中的同步通信方式。Node间可以通过request-reply方式通信:
[2]、Service的文件格式为 *.srv
[3]、订阅和服务的区别:
[4]、Service的常用命令:
# 列出当前所有活跃的service
$ rosservice list
# 显示某个service的属性信息
$ rosservice info service_name
# 调用某个service
$ rosservice call service_name args
# 列出系统上所有srv
$ rossrv list
# 显示某个srv内容
$ rossrv show srv_name
(3)、Parameter Service
[1]、存储各种参数的字典,可以用命令行,launch文件和node读写。
[2]、rosparam的常用命令:
# 列出当前所有参数
$ rosparam list
# 显示某个参数的值,param_key就是参数的名称
$ rosparam get param_key
# 设置某个参数的值
$ rosparam set param_key param_value
# 保存参数到文件
$ rosparam dump file_name
# 从文件读取参数
$ rosparam load file_name
# 删除参数
$ rosparam delete param_key
(4)、Action
[1]、类似于Service,带有状态反馈通信方式。通常用在长时间,可抢占的任务。
[2]、Action通信的数据格式为 *.action
(1)、提供ros编程的库的一个接口,类似于API。如建立node、发布消息、调用服务等。
(2)、C++版本的是roscpp
(3)、Python版本使rospy。
1、Gazebo :机器人仿真工具,用于动力学、导航、感知等任务的模拟。用于仿真虚拟的世界。
2、RViz :机器人可视化工具。把接受到的信息显示出来。
3、rqt :可视化工具。常用方法如下:
4、rosbag :ROS命令行工具,记录和回放数据流。
# 记录某些topic到bag,可以记录指定话题发布的消息,也可以记录所有话题发布的消息
$ rosbag record topic_name
# 回放bag
$ rosbag play filename.bag
1、分析topic_demo
(1)、功能上:两个node,一个发布模拟的GPS消息(格式为自定义、包括坐标和工作状态),另一个是接受并处理该消息(计算到原点的距离)。
(2)、步骤:
(3)、具体过程是首先将各种文件书写完成,最后再回到工作空间进行编译:
(1)、创建package
$ mkdir ~/catkin_ws/src
$ cd ~/catkin_ws/src
$ catkin_create_pkg topic_demo roscpp rospy std_msgs
(2)、msg文件
$ cd topic_demo/
$ mkdir msg
$ cd msg
$ vim gps.msg
# gps.msg的格式为:float x , float y , string state ;将其进行catkin_make编译后,
# 会生成一个头文件gps.h 位于~/catkin_ws/devel/include/topic_demo/目录下,在写代码时# 将其包含到头文件的#include中即可。
talker.cpp如下:
#include //包含ros的头文件,只要写ros的c++程序必须要包含的。
#include //包含定义的gps的头文件
int main(int argc, char** argv){
ros::init(argc, argv, "talker"); //初始化,解析参数,实名节点。talker为节点名
ros::NodeHandle nh; //创建句柄,实例化node
topic_demo::gps msg; //创建gps消息,
msg.x=1.0;
msg.y=1.0;
msg.state="working" ;
ros::Publisher pub=nh.advertise("gps_info", 1);
//创建publisher。
ros::Rate loop_rate(1.0); //定义循环发布的频率为1.0HZ每秒
while(ros::ok()){ //循环条件为是否继续发布消息
msg.x=1.03*msg.x ; //以指数增长,每隔1s
msg.y=1.01*msg.y ;
ROS_INFO( "Talker:GPS:x=%f,y=%f ,msg.x,msg.y); //输出当前msg
pub.publish(msg); //发布消息
loop_rate.sleep(); //根据定义的发布频率来休眠,sleep
}
return 0;
}
listener.cpp如下:
//ROS头文件
#include
//包含自定义msg产生的头文件
#include
//ROS标准msg头文件
#include
void gpsCallback(const topic_demo::gps::ConstPtr &msg)
{
//计算离原点(0,0)的距离
std_msgs::Float32 distance;
distance.data = sqrt(pow(msg->x,2)+pow(msg->y,2));
//float distance = sqrt(pow(msg->x,2)+pow(msg->y,2));
ROS_INFO("Listener: Distance to origin = %f, state: %s",distance.data,msg->state.c_str());
}
int main(int argc, char **argv)
{
ros::init(argc, argv, "listener");
ros::NodeHandle n;
ros::Subscriber sub = n.subscribe("gps_info", 1, gpsCallback);
//ros::spin()用于调用所有可触发的回调函数。将进入循环,不会返回,类似于在循环里反复调用ros::spinOnce()。
ros::spin();
return 0;
}
再对CMakeList.txt 和 package.xml进行修改即可进行编译。