ROS入门一——Topic通讯方式实现

ROS入门学习

一、新建一个ROS工程的步骤

1、创建工作空间并初始化

mkdir -p ros_ws/src     //ros_ws名称可以变,src名称不可以变。
cd ~/ros_ws/src/
catkin_init_workspace

结果:

2、编译工作空间

cd ~/ros_ws
catkin_make

结果:

3、再执行

catkin_make install

结果:

 4、创建功能包

cd ~/ros_ws/src
catkin_create_pkg topic_talk std_msgs rospy roscpp

 结果:

 5、为了使功能包生效,回到工作空间进行编译:

 编译完成后,要运行功能包的某一个程序文件,先要设置一下工作空间的环境变量:

source devel/setup.bash

为了避免每次创建功能包,忘记执行环境变量的配置,可以将 source devel/setup.bash 命令复制添加到 .bashrc 的配置文件里面:.bashrc在根目录下:(CTRL+h 可以显示隐藏文件)

 二、话题发布&订阅代码

话题发布代码:

#include<ros/ros.h>
#include<std_msgs/String.h>
​
const char* node_name = "topic_publisher";
const char* topic_name = "test_topic";
​
int main(int argc,char *argv[])
{
    ros::init(argc,argv,node_name);     //ROS节点初始化
    ros::NodeHandle n;          //(注册)创建节点句柄,管理节点的资源
​
    ros::Publisher topic_publisher = n.advertise<std_mags::String>(topic_name,10);//(创建消息)创建一个Publisher,发布名为test_topic的topic,消息类型为std_mags::String,队列长度10
​
    ros::Rate loop_rate(10);        //(发布消息)设置循环的频率
    ROS_INFO("%s start publishing msg",node_name);
​
    while(ros::ok())            //while循环主要就是封装数据、并发布数据、延时满足频率进入到下次循环
    {
        std_msgs::String test_msgs; //类
        test_msgs.data = "this is msg publisher!";
        topic_publisher.publish(test_msgs); //发布消息
​
        loop_rate.sleep();      // 按照循环频率延时
    }
​
    return 0;
}

话题订阅代码:

#include<ros/ros.h>
#include<std_msgs/String.h>
​
const char* node_name = "topic_subscriber";
const char* topic_name = "test_topic";
​
void show_msg_callback(const std_msgs::String::ConstPtr& msg)//引用传递,这时存放的是由主调函数放进来的实参变量的地址
//When messages are automatically generated into C++ code, there are several typedefs defined. One of them is ::Ptr, which is typedef-ed to be a boost::shared_ptr<MSG>, and another is ::ConstPtr which is boost::shared_ptr<MSG const>.
//By passing a const pointer into the callback, we avoid doing a copy. While this might not make much difference for std_msgs::String, it can make a huge difference for sensor_msgs::PointCloud2.
{
    ROS_INFO("get msg:[%s] from topic:[%s]",msg->data.c_str(),topic_name);
}
​
int main(int argc,char *argv[])
{
    ros::init(argc,argv,node_name);
    ros::NodeHandle n;
    
    ros::Subscriber topic_subscriber = n.subscribe(topic_name,10,show_msg_callback);
​
    ros::spin();        //循环等待回调函数
    return 0;
}

在该功能包的CmakeLists里配置话题发布者&订阅者代码的编译规则:

add_executable(topic_publisher src/topic_publisher.cpp)     //描述将哪一个程序文件(velocity_publisher. cpp),编译成哪一个可执行文件(velocity_publisher src)
target_link_libraries(topic_publisher ${catkin_LIBRARIES})  //帮助将生成的可执行文件与ROS 的一些库建立连接(c++的库)

改写结果如下图所示,放在build位置:

 使用catkin_make命令编译工作空间中所有的功能包,最终生成对应的目标文件,在工作空间的根目录中执行以下命令:

catkin_make

三、自定义message消息类型

①在功能包文件夹下新建一个msg文件夹,在msg文件夹里创建一个person.msg文件:

string name
uint8 age
uint8 score

②在package.xml文件的文件末尾添加如下语句,实现对应功能包的编译和运行的相关依赖:

  <build_depend>message_generation</build_depend>    //这个名称不能改
  <exec_depend>message_runtime</exec_depend>

③在CMakeLists.txt文件中,进行如下修改:

第一块:修改find_package部分,确保编译时找到对应文件


find_package(catkin REQUIRED COMPONENTS
  roscpp
  rospy
  std_msgs
  message_generation
)

第二块:设置msg文件

 add_message_files(
   FILES
   person.msg
 )

 generate_messages(
   DEPENDENCIES
   std_msgs
 )

第三块:catkin依赖部分

如果我们编写的ros程序不打算给别人使用,这块就无所谓。

catkin_package(
...
  CATKIN_DEPENDS roscpp rospy std_msgs message_runtime
...
)

在源文件中使用自定义的消息类型需要包含对应编译生成的头文件:

 这样就可以使用自定义的消息类型啦!

四、常用ros命令

rosrun  [package_name]  [node_name]		//运行ros节点

rosmsg list						//ros会输出工作空间中已经存在的所有类型消息
rosmsg show std_msgs/Int8		//可以看到:int8 data,std_msgs/Int8实际上是由一个int8类型的对象data组成。

rosservice call [service名称] [args]    //调用某服务

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值