机器人操作系统入门:二(中科大&&重德智能)

目录

六  roscpp

1.Client library 是提供ROS编程的库

2. 一个简单的topic Demo

3. 一个简单的ServiceDemo

4. 一个简单的Param Demo


一  roscpp

1.Client library 是提供ROS编程的库

CL语言包有两种:c++和py。roscpp 执行效率较高,rospy 开发效率较高。

roscpp 是和topic   service  param  timer  交互的一个接口。

roscpp包含的API简介:http://docs.ros.org/api/roscpp/html/

 

  

2. 一个简单的topic Demo

两个node,一个发布模拟的GPS消息,一个接收处理。

步骤:

  1. 建立package
  2. 自定义的消息格式 msg
  3. 发布者的源代码 talker.cpp
  4. 接收者的源代码  listener.cpp
  5. 修改CMakeLists  和  xml文件 

1.建立package

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 文件内容格式如下:

float32 y

float32 x

string state

经过编译过后会出现对应的头文件  ~/catkin_ws/devel/include/topic_demo/gps.h

3.发布者的源代码 talker.cpp

#include <ros/ros.h>
#include <topic_demo/gps.h>

int main(int argc,char** argv)
{
    ros::init(argc,argv,"talker");   //解析参数,命名节点(talker是节点名称)
    ros::NodeHandle nh;     //创建句柄,实例化node

    topic_demo::gps msg;  //创建msg消息
    msg.x=1.0;
    mag.y=1.0;
    msg.state="working";


/********创建publisher,advertise 模板函数的第一个参数gps_info是发布的topic的名称,第二个参数是先发布到一个队列中(类似缓存?),随发随收,所以队列的长度设为1。********/    
    ros::Publisher pub= nh.advertise<topic_demo::gps>("gps_info",1);   
  

/*********接下来要周期性循环发布消息*************/
    ros::Rate loop_rate(1.0);   //定义循环发布的频率,1代表1hz
    while(ros::ok())
    {
        msg.x=1.03* msg.x;
        msg.y=1.03* msg.y;
        ROS_INFO( "GPS:x=%f,y=%f",msg.x,msg.y);  //打印输出当前msg
        pub.publish(msg);     //发布消息
        loop_rate.sleep();    
    }

    return 0;

}

4.接收者的源代码 listener.cpp 

#include <ros/ros.h>
#incldue <topic_demo/gps.h>
#include <std_msgs/Float32.h>
 
void gpsCallback(const topic_demo::gps::ConstPtr & msg)  //常指针
{
    std_msgs::Float32 distance;   //ros自带的Float32类型,为结构体
    distance.data=sqrt(pow(msg->x,2),pow(msg->y,2));
    ROS_INFO("Distance=%f,state-=%s",distance.data,msg->state.c_str());  //打印输出

}




int main(int argc,char** argv)
{
    ros::init(argc,argv,"listener");  //解析参数,命名节点
    ros::NodeHandle n;
    

/**********创建subscriber************/
/********第一个参数是监听的topic的名称,第二个参数是消息队列的长度,第三个是回调函数(指针),用来处理监听到的信息*******/
    ros::Subscriber sub=n.subscribe("gps_info",1,gpsCallback);    
    ros::spin();   //反复查看队列是否有消息,然后调用当前可触发的回调函数,系统呈阻塞状态

    return 0;
}

5.改动CMakeLists 和 xml

改动 CMakeLists

 

改动 xml 

 6.编译执行

代码工作均已完成,接下来 编译 catkin_make  执行  rosrun

3. 一个简单的ServiceDemo

两个node,一个发布请求(格式自定义,本例中是姓名和年龄),一个接收处理并返回信息(本例中是一个字符串)。

步骤:

  1. 建立package
  2. 定义srv
  3. 响应者的源代码 server.cpp
  4. 请求者的源代码 client.cpp
  5. 修改CMakeLists  和  package.xml文件 

 1.创建package

cd ~/catkin_ws/src
catkin_create_pkg service_demo roscpp rospy std_msgs

2.定义srv

cd service_demo/
mkdir srv
vim Greeting.srv

编译后会在指定文件下出现头文件,具体如下

 

3.响应者的源代码 server.cpp

#include <ros/ros.h>
#include <service_demo/Greeting.h>

//返回值为布尔型,表示函数是否被正确执行

bool handle_function(service::demo::Greeting::Request & req, service::demo::Greating::Response &res)
{
    ROS_INFO("Request from %s with age %d", req.name.c_str(),req.age); //打印请求信息
    res.feedback=“Hi” + req.name +“I am server!”;  //处理请求,结果写入reponse
    return ture; //返回 true ,正确处理请求
}


int main()
{
    ros::init(argc,argv, "greetings_server");   //解析参数,命名节点
    ros::NodeHandle nh;   //创建句柄,实例化node

/********提供服务,第一个参数是服务名称,第二个参数是处理函数(函数指针)*********/
    ros::ServcieServer service = nh.advertiseService(“greetings”, handle_function)  
    
    ros::spin();
    return 0;


}

4.请求者的原代码

#include <ros/ros.h>
#include <service_demo/Greeting.h>

int main(int argc, char** argv)
{
    ros::init(argc,argv,"greetings_server");
    ros::NodeHandle nh;

    /*******这步是创建client,发送的请求的类型是servcie_demo::Greeting,函数的参数“greetings”就是要发送到的sevice********/
    ros::ServiceClient client= nh.serviceClient<servcie_demo::Greeting>("greetings");

    
    service_demo::Greeting srv;
    srv.request.name = "HAN" ;
    srv.request.age = 20;

    
    /*********client.call返回的布尔值变量也是handle_function返回的结果*************/
    if(client.call(srv))
    {
        ROS_INFO("Feedback from server:%s",srv.response.feedback);

    }
    else
    {
        ROS_ERROR("Failed to call service greeting.");
        return 1;
    }

    return 0;
}

5.修改 CMakeList 和  xml

类比之前的。。。

4. 一个简单的Param Demo

 同一个功能两套API:ros::param  和 ros::NodeHandle

param_demo.cpp ()在源代码中设置参数

#incldue <ros/ros.h>

int main(int argc, char** argv)
{
    ros::init(argc,argv,"greetings_server");
    ros::NodeHandle nh;
    
    int parameter1,parameter2,parameter3,parameter4,parameter5;
    
    //获取参数的三种方法, param 是namespace
    ros::param::get("param1",parameter1);  //把第一个参数(key)的值赋给第二个参数
    nh.getParam("param2",parameter2);    //把第一个参数(key)的值赋给第二个参数
    nh.param("param3",parameter3,123);  //如果没有找到param3,就赋给默认值123
    
    //设置参数
    ros::param::set("param4",parameter4)
    nh.setParam("param5",parameter5)
    
    //检查参数是否存在
    ros::param::has("param5")
    nh.hasParam("param6");
    
    //删除参数
    ros::param::del("param5");
    ros::deleteParam("param6");

    return 0;

}

另一种设置参数的方法  launch文件法

param_demo_cpp.launch

<launch>
    <!--Param标签设置单个参数-->
    <param name="param1" value="1" />
    <param name="param2" value="2" />
    <param name="robot_description" command="$(find xacro)/xacro.py $(find demo)/urdf/robot.urdf" />


    <!--rosparam标签设置多个参数-->
    <rosparam>
        param3:3
        param4:4
        param10:helloworld!
    </rosparam>
    <rosparam file= "$(find param_demo)/config/myparam.yaml" command= "load" />
    
    <node pkg= "param_demo" type="param_demo" name="param_demo" output= "screen" />

</launch>

猜你喜欢

转载自blog.csdn.net/Bluenapa/article/details/85641662