我是靠谱客的博主 单薄秀发,最近开发中收集的这篇文章主要介绍ROS工程小结一、工作空间概览二、包与节点三、消息与可视化四、调试五、引用其他包的节点或消息,觉得挺不错的,现在分享给大家,希望可以做个参考。

概述

文章目录

  • 一、工作空间概览
  • 二、包与节点
    • 实现消息的发布
    • 实现消息接收
    • 添加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步:

  1. 定义msg文件(…/ws/src/package/msg目录下)
  2. 在package.xml文件中添加功能包依赖
<build_depend> message_generation</build_depend>
<exec_depend>message_runtime</exec_depend>
  1. 在CmakeLists.txt文件中添加编译选项
find_package(... message_generation)

add_message_files(FILES xxx.msg)
generate_messages(DEPENDENCIES std_msgs)	//假设依赖了`std_msgs`

catkin_package(
... 
# message_runtime
)
  1. 编译生成语言相关文件

使用自定义消息

  1. 包含头文件
#include "package_name/msgs_name.h"
  1. 创建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)至自己的工作空间

法一

  1. 创建自己的包(如A_package)时添加对目标包的依赖,如
catkin_create_pkg std_msgs roscpp rospy B_package
  1. 编译B_package
catkin_make -DCATKIN_WHITELIST_PACKAGES='B_package'
  1. 在自己的包中操作

  2. 全局编译:

catkin_make -DCATKIN_WHITELIST_PACKAGES=''

法二

  1. 对已创建的A_package文件夹中的CMakeLists.txtpackage.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>
  1. 编译B_package
catkin_make -DCATKIN_WHITELIST_PACKAGES='B_package'
  1. 操作并编译A_package即可

最后

以上就是单薄秀发为你收集整理的ROS工程小结一、工作空间概览二、包与节点三、消息与可视化四、调试五、引用其他包的节点或消息的全部内容,希望文章能够帮你解决ROS工程小结一、工作空间概览二、包与节点三、消息与可视化四、调试五、引用其他包的节点或消息所遇到的程序开发问题。

如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(67)

评论列表共有 0 条评论

立即
投稿
返回
顶部