ROS学习笔记一:基础教程(下)

     在上一篇博客里面我们创建了ros包,还新建了msg和srv现在让我们一起做点有意思的事情吧,让我们写的程序跑起来。

一 编写简单的Publisher和Subscriber

     1.1   首先,进入目录新建一个src文件夹(如果没有source先source一下)

  

 mkdir -p src
     在src文件夹内新建一个文件talker.cpp
cd src
touch talker.cpp
     在talker.cpp里面写入下面的内容
#include "ros/ros.h"//包括ROS中常用的公共部分的定义
#include "std_msgs/String.h"//消息包的头文件
#include "sstream"
int main(int argc,char **argv)
{
//ROS初始化 将节点命名为talker
    ros::init(argc,argv,"talker");
//创建一个句柄到进程的节点,第一个表示初始化,最后一个NodeHandle会将所有的资源清除
    ros::NodeHandle n;
//创建一个子类PUblish类型 叫chatter_pub 传送的信息为string类型,最多接受1000个
    ros::Publisher chatter_pub=n.advertise<std_msgs::String>("chatter",1000);
//以10HZ来运行
    ros::Rate loop_rate(10);
    int count=0;
//当按下ctrl c时,rose::ok()会返回false
    while(ros::ok())
    {
//定义了一个要发布的msg
        std_msgs::String msg;
//定义一个要在终端打印出来的ss
        std::stringstream ss;
//给ss赋值
        ss<<"hello world"<<count;
//给msg赋值,这里msg只有sting这一种类型
        msg.data=ss.str();
//ROS_INFO相当于printf
        ROS_INFO("%s",msg.data.c_str());
//把消息广播给任何人
        chatter_pub.publish(msg);
//回调时使用
        ros::spinOnce();
//在10hz以外的其他时间节点都是处于休眠状态的
        loop_rate.sleep();
        ++count;

    }
    return 0;
}
     1.2  编写 Subscriber

         和之前一样在src中新建一个src/listener.cpp文件

touch listener.cpp
        同样我们在listener.cpp里面写入下面的代码
#include "ros/ros.h"
#include "std_msgs/Sring.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;
//在接收到消息时调用chatterCallback函数
    ros::Subscriber sub =n.subscribe("chatter",1000,chatterCallback);
//没有接收到消息时,一直循环
    ros::spin();
    return 0;

}
      现在万事具备,只要编译一下就好        
cd ~/robochengzi/
catkin_make

二 执行Publisher和Subscriber

      好激动人心的一步到了,之前做的那么多终于要拿出来运行了

     首先运行ros(这一步不成功是安装的问题,问题有很多种先百度解决)

roscore
     打开新的终端

     首先source一下然后运行程序

cd ~/robochengzi/
source ./devel/setup.bash
rosrun robot talker
      运行成功的结果是这样的
[ INFO] [1517237329.554897985]: hello world 24
[ INFO] [1517237329.654934314]: hello world 25
[ INFO] [1517237329.754879845]: hello world 26
[ INFO] [1517237329.854875335]: hello world 27
[ INFO] [1517237329.954874894]: hello world 28
[ INFO] [1517237330.055077860]: hello world 29
[ INFO] [1517237330.154935016]: hello world 30
[ INFO] [1517237330.254920792]: hello world 31
[ INFO] [1517237330.354878216]: hello world 32
[ INFO] [1517237330.454899610]: hello world 33
[ INFO] [1517237330.554937169]: hello world 34

     运行到这都没有问题,说明已经基本成功了后面一个也是一样运行

     同样新打开一个终端,source一下然后运行程序就好

cd ~/robochengzi/
source ./devel/setup.bash
rosrun robot listener

     运行成功的结果如下
[ INFO] [1517237548.156052887]: I heard: [hello world 2210]
[ INFO] [1517237548.255744517]: I heard: [hello world 2211]
[ INFO] [1517237548.355945225]: I heard: [hello world 2212]
[ INFO] [1517237548.455125980]: I heard: [hello world 2213]
[ INFO] [1517237548.555806475]: I heard: [hello world 2214]
[ INFO] [1517237548.655804706]: I heard: [hello world 2215]

三 编写简单的Service和Client

    和上面一样我们在src文件里面新建两个文件 add_two_ints_server.cpp 和add_two_ints_client.cpp

cd src
touch add_two_ints_server.cpp
touch add_two_ints_client.cpp
     分别在两个文件里面粘贴下面的代码

      add_two_ints_server.cpp    

#include "ros/ros.h"
//之前创建的srv文件生成的头文件
#include "beginner_tutorials/AddTwoInts.h"
//回调函数 接收srv文件中定义的请求和响应类型,并返回一个bool值
bool add(beginner_tutorials::AddTwoInts::Request &req,
         beginner_tutorials::AddTwoInts::Response &res)
{
    res.sum=req.a+req.b;
    ROS_INFO("request:x%ld,y=%ld",(long int)req.a,(long int)req.b);
    ROS_INFO("sending back respond:[%ld]",(long int)res.sum);
    return true;
}
int main(int argc,char ** argv)
{
    ros::init(argc,argv,"add_two_ints_server");
    ros::NodeHandle n;

    ros::Serviceserver service=n.advertiseService("add_two_ints",add);
    ROS_INFO("Ready to add two ints.");
    ros::spin();

    return 0;
}
      add_two_ints_client.cpp   
#include "ros/ros.h"
#include "beginner_tutorials/AddTwoInts.h"
#include <cstdlib>
int main(int argc,char **argv)
{
    ros::init(argc,argv,"add_two_ints_client");
    if(argc!=3)
    {
        ROS_INFO("usage:add_two_ints_client X Y");
        return 1;
    }
    ros::NodeHandle n;
//创建一个客户端 该对象用于以后的回调
    ros::ServiceClient client=n.serviceClient<beginner_tutorials::AddTwoInts>
            ("add_two_ints");
    beginner_tutorials::AddTwoInts srv;
    srv.request.a=atoll(argv[1]);
    srv.request.b=atoll(argv[2]);
    if(client.call(srv))
    {
        ROS_INFO("Sum:%ld",(long int)srv.response.sum);
    }
    else
    {
        ROS_ERROR("Failed to call service add_two_ints");
        return 1;
    }
    return 0;
}
     最后,我们在Cmakelist里面加上这两个文件

     在文件的最下面加上

add_executable(add_two_ints_server src/add_two_ints_server.cpp)
target_link_libraries(add_two_ints_server ${catkin_LIBRARIES})
add_dependencies(add_two_ints_server beginner_tutorials_gencpp)

add_executable(add_two_ints_client src/add_two_ints_client.cpp)
target_link_libraries(add_two_ints_client ${catkin_LIBRARIES})
add_dependencies(add_two_ints_client beginner_tutorials_gencpp)
     编译一下
 catkin_make

四 执行Service和Client

     首先,运行roscore

roscore

      然后启动两个节点

rosrun robot add_two_ints_serve
rosrun robot add_two_ints_client 2 4

这两行命令必须要在两个新的终端内执行,在每个新终端都必须加上source 命令,

source ./devel/setup.bash

最后,如果它如愿的返回答案为6的话,那么恭喜你完成了基础部分的教学。

其实,最好的教程是官网的维基,我们的博客只能算是过来人的一种经验,后续我们继续学习move_base 包,我们一起从零开始做一个小激光slam机器人出来。



 

 



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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值