概述
文章目录
- 一、工作空间概览
- 二、包与节点
- 实现消息的发布
- 实现消息接收
- 添加CmakeLists.txt文件内容以将上述发布者与订阅者节点包含进包结构中
- 三、消息与可视化
- 自定义消息
- 使用自定义消息
- RVIZ显示三维点图
- 四、调试
- 五、引用其他包的节点或消息
- 法一
- 法二
一、工作空间概览
建立工作空间目录,一般的结构如下:
|--my_ws
|--build #存放有关CMake、make的编译设置文件等
|--install #放置最终编译生成的可执行文件,这个文件可没有
|--devel #存放编译好的可执行文件等
|--src #存放源文件,即我们所需要编写的各种代码和ros包
|--package_1 #每个ros包下又包含如下结构
|--include
|--launch
|--src
CMakeList.txt #重要文件
package.xml #重要文件
...
|--package_n
CMakeList.txt #src文件夹下也有一个全局性的
在/ws/src
目录下初始化:
catkin_init_workspace
在/ws/src
目录下创建ros包package
,如:
catkin_creat_pkg package_name depend1 depend2 depend3
完成源码编写后,在工作空间/ws
编译:
catkin_make
运行前需对工作空间的环境变量做导入:
source path/to/ws/devel/setup.bash
二、包与节点
包(package)是若干个节点(node)组成的一个集合,可用来实现一定的组合功能,也是发布和下载的资源单位。
在使用前,先用roscore
命令运行整个ros系统,相当于启动了master线程,等待其他子线程的执行请求。
在需要使用包里某一节点的功能时,可使用rosrun [packagename] [nodename]
格式调用。
注意,终端若没读入工作空间的环境变量ws/devel/setup.bash
,则不能找到包和节点,设置如下:
source /path/to/catkin_ws/devel/setup.bash
实现消息的发布
//pub_eg.cpp
#include "ros/ros.h"
#include "std_msgs/String.h"
#include <sstream>
int main(int argc, char **argv)
{
ros::init(argc, argv, "talker");
ros::NodeHandle n;
ros::Publisher chatter_pub = n.advertise<std_msgs::String>("chatter", 1000);
ros::Rate loop_rate(10);
int count = 0;
while (ros::ok())
{
std_msgs::String msg;
std::stringstream ss;
ss << "hello world " << count;
msg.data = ss.str();
ROS_INFO("%s", msg.data.c_str());
chatter_pub.publish(msg);
ros::spinOnce();
loop_rate.sleep();
++count;
}
return 0;
}
实现消息接收
//sub_eg.cpp
#include "ros/ros.h"
#include "std_msgs/String.h"
void chatterCallback(const std_msgs::String::ConstPtr& msg)
{
ROS_INFO("I heard: [%s]", msg->data.c_str());
}
int main(int argc, char **argv)
{
ros::init(argc, argv, "listener");
ros::NodeHandle n;
ros::Subscriber sub = n.subscribe("chatter", 1000, chatterCallback);
ros::spin();
return 0;
}
添加CmakeLists.txt文件内容以将上述发布者与订阅者节点包含进包结构中
add_executable(talker src/pub_eg.cpp)
target_link_libraries(talker ${catkin_LIBRARIES})
add_executable(listener src/sub_eg.cpp)
target_link_libraries(listener ${catkin_LIBRARIES})
三、消息与可视化
自定义消息
大致分为4步:
- 定义msg文件(…/ws/src/package/msg目录下)
- 在package.xml文件中添加功能包依赖
<build_depend> message_generation</build_depend>
<exec_depend>message_runtime</exec_depend>
- 在CmakeLists.txt文件中添加编译选项
find_package(... message_generation)
add_message_files(FILES xxx.msg)
generate_messages(DEPENDENCIES std_msgs) //假设依赖了`std_msgs`
catkin_package(
...
# message_runtime
)
- 编译生成语言相关文件
使用自定义消息
- 包含头文件
#include "package_name/msgs_name.h"
- 创建Publisher,发布自定义消息类型的话题topic,话题名为 “event”,消息队列长度为1000
ros::Publisher event_pub = n.advertise<package_name::msgs_name>("event", 1000);
RVIZ显示三维点图
发布PointStamped
类型的点消息,引入头文件:
#include <geometry_msgs/PointStamped.h>
发布RVIZ支持的点消息格式:
ros::init(argc, argv,"event_publisher");
ros::NodeHandle n;
ros::Publisher point_pub = n.advertise<geometry_msgs::PointStamped>("point",1000, true); //实例化对点消息的话题发布机
ros::Rate loop_rate(10); //注意消息发布的频率要与rviz中的设置一致,不一致也可以
geometry_msgs::PointStamped epmsg; //实例化一个点消息对象 epmsg
epmsg.header.frame_id = "epmap"; //给点消息对象命名一个框架id,方便在rviz中选择其坐标系
vector<Event>::iterator ite = EPoint.begin();
while (ros::ok())
{
if(ite != EPoint.end())
{
epmsg.point.x = ite->x;
epmsg.point.y = ite->y;
epmsg.point.z = ite->t;
ROS_INFO("publishing event now!!!");
point_pub.publish(epmsg); //发布当前事件点的消息
ros::spinOnce();
ite++;
loop_rate.sleep();
}
在RVIZ中
通过add
添加要显示的话题point
更改全局坐标与对象坐标frame_id
一致
四、调试
ROS_INFO
//调试信息输出类C风格
ROS_INFO("position=(%0.2f,%0.2f) direction=%0.2f", msg.x, msg.y, msg.theta);
//调试信息输出类Cpp风格
ROS_INFO_STREAM( std::setprecision (2) << std::fixed<< " position=(" << msg.x << " ," << msg.y << ")" << "direction=" << msg.theta );
注意ROS_INFO不能直接输出string
对象,需要先将对象转成c_str()
,若是使用ss(stringstream)创建的流文本,需先将其转化为纯string
(使用str方法):
std::stringstream ss;
ss << "the event's ts is " << emsg->ts; #emsg->ts为ros::Time类型
OS_INFO("I heard: [%s]", ss.str().c_str()); #流对象先转字符串,再转C类型字符串
五、引用其他包的节点或消息
复制包文件夹(如B_package
)至自己的工作空间
法一
- 创建自己的包(如
A_package
)时添加对目标包的依赖,如
catkin_create_pkg std_msgs roscpp rospy B_package
- 编译
B_package
:
catkin_make -DCATKIN_WHITELIST_PACKAGES='B_package'
-
在自己的包中操作
-
全局编译:
catkin_make -DCATKIN_WHITELIST_PACKAGES=''
法二
- 对已创建的
A_package
文件夹中的CMakeLists.txt
和package.xml
文件进行修改:
#CMakeLists.txt
find_package(catkin REQUIRED COMPONENTS
roscpp
rospy
std_msgs
B_package #添加这一条
)
#...
include_directories(
include #取消这一条的注释
${catkin_INCLUDE_DIRS}
)
<build_depend>B_package</build_depend>
<build_export_depend>B_package</build_export_depend>
<exec_depend>B_package</exec_depend>
- 编译
B_package
:
catkin_make -DCATKIN_WHITELIST_PACKAGES='B_package'
- 操作并编译
A_package
即可
最后
以上就是单薄秀发为你收集整理的ROS工程小结一、工作空间概览二、包与节点三、消息与可视化四、调试五、引用其他包的节点或消息的全部内容,希望文章能够帮你解决ROS工程小结一、工作空间概览二、包与节点三、消息与可视化四、调试五、引用其他包的节点或消息所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
发表评论 取消回复