【ROS学习】ros系统中各通信机制的代码模板(C++实现)

ROS初学者笔记,谨慎参考

话题通信

话题发布者Publisher

代码

  1. 包含头文件(ros/ros.h以及消息类型的头文件)

  1. 定义main函数

  1. 初始化节点

  1. 通过nodehandle发布一个话题并得到话题发布对象

  1. 声明消息类型对象

  1. 操作消息类型对象

  1. 设置循环,发布消息

其他注意事项:

发布频率,消息队列长度等

//向/cmd_vel话题发布速度控制信息 

#include <ros/ros.h>
#include <geometry_msgs/Twist.h>//包含头文件(ros/ros.h以及消息类型的头文件)

int main(int argc, char *argv[])//定义main函数
{
    ros::init(argc,argv,"vel_node");//初始化节点
    ros::NodeHandle n;
    ros::Publisher vel_pub = n.advertise<geometry_msgs::Twist>("/cmd_vel",10);//发布一个话题并得到话题发布对象
    geometry_msgs::Twist vel_msg;//声明消息类型对象                              //注意这里的话题名称是约定俗成的(用于控制速度),不能随意设置
    vel_msg.linear.x=0;
    vel_msg.linear.y=0;
    vel_msg.linear.z=0;
    vel_msg.angular.x=0;
    vel_msg.angular.y=0;
    vel_msg.angular.z=0.5;//操作消息类型对象
    ros::Rate r(30);
    while(ros::ok()){
        vel_pub.publish(vel_msg);//发布消息
        r.sleep();
    }

    return 0;
}

配置CMakeList.txt

  1. 添加一个可执行文件,修改文件名称和文件路径

  1. 将目标文件与库文件进行链接,修改目标文件名称

## Declare a C++ executable
## With catkin_make all packages are built within a single CMake context
## The recommended prefix ensures that target names across packages don't collide
## add_executable(${PROJECT_NAME}_node src/vel_pkg_node.cpp)
add_executable(vel_node src/vel_node.cpp)
## 将${PROJECT_NAME}_node换成你编写的节点的名字
## 将src/vel_pkg_node.cpp换成节点源文件的位置


## Specify libraries to link a library or executable target against
# target_link_libraries(${PROJECT_NAME}_node
#   ${catkin_LIBRARIES}
# )
target_link_libraries(vel_node
  ${catkin_LIBRARIES}
)
## 将${PROJECT_NAME}_node换成节点名

话题订阅者Subscriber

代码

  1. 包含头文件(ros/ros.h以及消息类型的头文件)

  1. 定义main函数

  1. 初始化节点

  1. 通过nodehandle订阅一个话题

  1. 编写回调函数

  1. 消息回调处理函数spin()

其他注意事项:

话题消息由回调函数的参数传入,消息队列大小

#include "ros/ros.h"
#include "std_msgs/String.h"//包含头文件

void doMsg(const std_msgs::String::ConstPtr& msg_p){//传入话题消息
    ROS_INFO("I heard:%s",msg_p->data.c_str());
}
int main(int argc, char  *argv[])//定义main函数
{
    ros::init(argc,argv,"listener");//初始化节点
    ros::NodeHandle nh;

    ros::Subscriber sub = nh.subscribe<std_msgs::String>("chatter",10,doMsg);//通过NodeHandle订阅话题

    ros::spin();//spin循环
    return 0;
}

配置CMakeList.txt

同上

自定义msg

源文件

直接写入包含的数据类型和名称

string name
uint16 age
float64 height

配置package.xml和CMakeList

向package.xml中添加编译依赖和执行依赖

  <build_depend>message_generation</build_depend>
  <exec_depend>message_runtime</exec_depend>

CMakeList.txt

  1. 添加message_generation(必须先有std_msgs)

  1. 添加message源文件

  1. 添加生成消息的依赖

  1. 添加执行时的依赖

## Find catkin macros and libraries
## if COMPONENTS list like find_package(catkin REQUIRED COMPONENTS xyz)
## is used, also find other catkin packages
find_package(catkin REQUIRED COMPONENTS
  message_generation
  roscpp
  rospy
  std_msgs
)
#添加message_generation(必须先有std_msgs)


## Generate messages in the 'msg' folder
# add_message_files(
#   FILES
#   Message1.msg
#   Message2.msg
# )
add_message_files(
  FILES
  Carry.msg
)
#添加message源文件

## Generate added messages and services with any dependencies listed here
# generate_messages(
#   DEPENDENCIES
#   std_msgs
# )
generate_messages(
  DEPENDENCIES
  std_msgs
)
#添加生成消息的依赖

catkin_package(
#  INCLUDE_DIRS include
#  LIBRARIES qq_msgs
CATKIN_DEPENDS message_generation message_runtime roscpp rospy std_msgs
#  DEPENDS system_lib
)
#执行时的依赖

服务通信

自定义srv

源文件

格式如下(数量任意)

提交参数1

提交参数2

---

输出1

//文件后缀为srv
int32 num1
int32 num2
---
int32 sum

配置package.xml和CMakeList

向package.xml中添加编译依赖和执行依赖

  <build_depend>message_generation</build_depend>
  <exec_depend>message_runtime</exec_depend>

配置CMakeList.txt

  1. 加入 message_generation,必须有 std_msgs

  1. 添加srv源文件

  1. 添加生成服务的依赖

find_package(catkin REQUIRED COMPONENTS
  roscpp
  rospy
  std_msgs
  message_generation
)
# 需要加入 message_generation,必须有 std_msgs

add_service_files(
  FILES
  AddInts.srv
)
#添加srv源文件

generate_messages(
  DEPENDENCIES
  std_msgs
)
#添加生成服务的依赖

服务端

代码

  1. 包含头文件(ros/ros.h以及服务消息的头文件)

  1. 定义main函数

  1. 初始化节点

  1. 通过nodehandle发布一个服务

  1. 编写回调函数

  1. 消息回调处理函数spin()

其他注意事项:

注意回调函数的参数

#include<ros/ros.h>
#include<add_ints_server_client/AddInts.h>//添加头文件和服务消息的文件


//这里的回调函数负责处理客户端提交的参数并将结果保存在参数中
bool doReq(add_ints_server_client::AddInts::Request& req,
            add_ints_server_client::AddInts::Response& resp){
        int num1 = req.num1;
        int num2 = req.num2;

        ROS_INFO("the datas server receives are num1 = %d,num2 = %d",num1,num2);

        if(num1 < 0|| num2 < 0){
            ROS_ERROR("the nums you submit can not be less than 0");
            return false;
        }

        resp.sum = num1 + num2;
        return true;
    }

int main(int argc,char *argv[]){//定义main函数
    ros::init(argc,argv,"AddInts_server");//初始化节点
    ros::NodeHandle n;
    ros::ServiceServer server = n.advertiseService("AddInts",doReq);
    //通过nodehandle发布服务,参数为服务名称和回调函数
    
    ROS_INFO("the server has been initiated");
    ros::spin();//一直观测客户端有没有传输消息
    return 0;
}

配置CakeList.txt

  1. 添加一个可执行文件

  1. 添加可执行文件所需的依赖

  1. 将目标文件与库文件进行链接

add_executable(AddInts_client src/AddInts_client.cpp)
add_dependencies(AddInts_client ${${PROJECT_NAME}_EXPORTED_TARGETS} ${catkin_EXPORTED_TARGETS})
target_link_libraries(AddInts_client
  ${catkin_LIBRARIES}
)

客户端

代码

  1. 包含头文件(ros/ros.h以及服务消息的头文件)

  1. 定义main函数

  1. 初始化节点

  1. 通过nodehandle创建一个客户端

  1. 创建一个服务类型的对象来组织接收到的数据

  1. 调用客户端返回是否处理成功

其他注意事项:

传入的参数个数

#include<ros/ros.h>
#include<add_ints_server_client/AddInts.h>//包含头文件(ros/ros.h以及服务消息的头文件)

int main(int argc,char *argv[]){//定义main函数
    if(argc != 3){//判断用户输入参数个数是否合法
        ROS_ERROR("please submit two nums");
        return 1;
    }

    ros::init(argc,argv,"AddInts_client");//初始化节点
    ros::NodeHandle n;//通过nodehandle创建一个客户端
    ros::ServiceClient client = n.serviceClient<add_ints_server_client::AddInts>("AddInts");

    ros::service::waitForService("AddInts");
    add_ints_server_client::AddInts ai;//创建一个服务类型的对象来组织接收到的数据
    ai.request.num1 = atoi(argv[1]);
    ai.request.num2 = atoi(argv[2]);

    bool flag = client.call(ai);//调用服务AddInts,若此时该客户端未与服务端建立通信则返回false
    if(flag){
        ROS_INFO("process done return: %d",ai.response.sum);
    }
    else{
        ROS_ERROR("process failed ....");
        return 1;
    }

    return 0;
}

配置CakeList.txt

同上

参数通信

为保证一致性,使用NodeHandle实现

模板代码

  1. 包含头文件(ros/ros.h以及服务消息的头文件)

  1. 定义main函数

  1. 初始化节点

  1. 得到NodeHandle句柄

  1. 使用相关API操作参数

#include <ros/ros.h>//包含头文件(ros/ros.h以及服务消息的头文件)
int main(int argc, char *argv[])//定义main函数
{
    ros::init(argc,argv,"demo01_param_set");//初始化节点
    ros::NodeHandle n;//得到NodeHandle句柄
    n.setParam("radius",0.15);//设置参数名称和数值
    n.deleteParam("radius");//删除参数
    return 0;
}

配置CMakeList.txt文件

  1. 添加一个可执行文件

  1. 将目标文件与库文件进行链接

add_executable(demo01_param_set src/demo01_param_set.cpp)
target_link_libraries(demo01_param_set
  ${catkin_LIBRARIES}
)

常见参数操作

getParam(参数名,数值)//设置参数

deleteParam(参数名)//删除参数,返回值bool类型,表示是否删除成功

getParam(参数名,变量)//将参数赋值给某个已定义变量

参考资料

http://www.autolabor.com.cn/book/ROSTutorials/

【机器人操作系统 ROS 快速入门教程-哔哩哔哩】 https://b23.tv/04zXEoJ

【【Autolabor初级教程】ROS机器人入门-哔哩哔哩】 https://b23.tv/gJ9Nm1P

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值