当前位置: 首页 > news >正文

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

目录

一  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>

 

相关文章:

  • Ubuntu下的Kdevelop的使用
  • 机器人操作系统入门:三(中科大重德智能)
  • 数字图像处理: 一 (上交)
  • 机器人操作系统入门:四(中科大重德智能)
  • ORB_SLAM2中的字典DBow
  • 黑客与画家:一
  • 黑客与画家:二
  • 黑客与画家:三
  • jQuery之父:每天写代码
  • 一个机器学习博士生的忠告
  • 喂,你是在学习还是在逃避?
  • 工作中四种重要的能力------谈谈工作两年后的一点思考
  • 像外行一样思考,像专家一样实践
  • 认识SCI、EI、ISTP、IEEE等和算法论文
  • 反演
  • 《网管员必读——网络组建》(第2版)电子课件下载
  • 【Leetcode】104. 二叉树的最大深度
  • 230. Kth Smallest Element in a BST
  • CentOS 7 修改主机名
  • cookie和session
  • Java|序列化异常StreamCorruptedException的解决方法
  • java8-模拟hadoop
  • JS变量作用域
  • node-sass 安装卡在 node scripts/install.js 解决办法
  • Quartz实现数据同步 | 从0开始构建SpringCloud微服务(3)
  • RedisSerializer之JdkSerializationRedisSerializer分析
  • Ruby 2.x 源代码分析:扩展 概述
  • Spark VS Hadoop:两大大数据分析系统深度解读
  • -- 查询加强-- 使用如何where子句进行筛选,% _ like的使用
  • 利用阿里云 OSS 搭建私有 Docker 仓库
  • 每个JavaScript开发人员应阅读的书【1】 - JavaScript: The Good Parts
  • 使用 QuickBI 搭建酷炫可视化分析
  • 世界上最简单的无等待算法(getAndIncrement)
  • scrapy中间件源码分析及常用中间件大全
  • 直播平台建设千万不要忘记流媒体服务器的存在 ...
  • ​决定德拉瓦州地区版图的关键历史事件
  • #1015 : KMP算法
  • #传输# #传输数据判断#
  • (10)STL算法之搜索(二) 二分查找
  • (C语言)求出1,2,5三个数不同个数组合为100的组合个数
  • (附源码)ssm经济信息门户网站 毕业设计 141634
  • (十一)c52学习之旅-动态数码管
  • (算法设计与分析)第一章算法概述-习题
  • (译)计算距离、方位和更多经纬度之间的点
  • ../depcomp: line 571: exec: g++: not found
  • .Net 中的反射(动态创建类型实例) - Part.4(转自http://www.tracefact.net/CLR-and-Framework/Reflection-Part4.aspx)...
  • .NET下的多线程编程—1-线程机制概述
  • // an array of int
  • @ModelAttribute 注解
  • @Transactional类内部访问失效原因详解
  • [Android] Amazon 的 android 音视频开发文档
  • [Android]使用Android打包Unity工程
  • [CUDA手搓]从零开始用C++ CUDA搭建一个卷积神经网络(LeNet),了解神经网络各个层背后算法原理
  • [C语言][C++][时间复杂度详解分析]二分查找——杨氏矩阵查找数字详解!!!
  • [ESP32 IDF]web server