4.ROS编程学习:自定义话题消息与c++调用

1.消息类型功能包

ROS的元功能包common_msgs提供了多种消息类型:
std_msgs——标准数据类型

geometry_msgs——几何学数据类型

sensor_msgs——传感器数据类型

在一些情况下需要针对自己的机器人应用设计特定的消息类型。

2.自定义话题消息

功能包中的msg文件夹中就是自定义的消息类型文件。msg文件夹在功能包根目录下。

创建文件夹msg,创建文件Person.msg:

4.ROS编程学习:自定义话题消息与c++调用_第1张图片

 定义一个描述个人信息的消息类型:

string name
int32 age
float32 height

为了使用这些自定义消息类型,需要编译msg文件。

在package.xml文件中添加功能包依赖:

message_generation
message_runtime

4.ROS编程学习:自定义话题消息与c++调用_第2张图片

在CMakeLists.txt文件。

编译时依赖:加入message_generation

find_package(catkin REQUIRED COMPONENTS
  roscpp
  rospy
  std_msgs
  message_generation
)

运行时依赖:取消注释并加入message_runtime

catkin_package(
#  INCLUDE_DIRS include
#  LIBRARIES sub_pub
 CATKIN_DEPENDS roscpp rospy std_msgs message_runtime
#  DEPENDS system_lib
)

加入文件:

add_message_files(
  FILES
  Person.msg
)

自定义消息类型文件的依赖:

generate_messages(
  DEPENDENCIES
  std_msgs
)

回到工作空间根目录,编译工作空间

catkin_make

编译后的中间文件:可以找到Person.h头文件,和Person.py中的python类。

C++ 需要调用的中间文件(.../工作空间/devel/include/包名/xxx.h)

Python 需要调用的中间文件(.../工作空间/devel/lib/python3/dist-packages/包名/msg)

4.ROS编程学习:自定义话题消息与c++调用_第3张图片

 3.c++调用自定义消息类型

(1)准备工作

为了在vscode中编程时,防止头文件中引入自定义消息类型误报和代码无法自动补齐,故得对vscode进行配置。

首先在复制路径的文件夹用终端打开,输入pwd。

pwd
rosmelodic@rosmelodic-virtual-machine:~/catkin_ws/devel/include$ pwd
/home/rosmelodic/catkin_ws/devel/include

复制路径/home/rosmelodic/catkin_ws/devel/include到c_cpp_properties.json,加上/**

4.ROS编程学习:自定义话题消息与c++调用_第4张图片

 在includePath中加入"路径/**"

4.ROS编程学习:自定义话题消息与c++调用_第5张图片

 (2)发布方实现

pub_person.cpp

#include "ros/ros.h"
#include "sub_pub/Person.h"

int main(int argc, char  *argv[])
{
    setlocale(LC_ALL, "");
    ROS_INFO("发布方");
    ros::init(argc, argv, "ren");
    ros::NodeHandle n;
    ros::Publisher pub = n.advertise("renxinxi",10);
    sub_pub::Person person;
    person.name = "张三";
    person.age = "1";
    person.height = "1.73";
    ros::Rate rate(1);
    ros::Duration(3.0).sleep();
    while(ros::ok)
    {
        person.age += 1;
        pub.publish(person);
        
        rate.sleep();
    }
    return 0;
}

头文件

#include "ros/ros.h"
#include "sub_pub/Person.h"

调用在sub_pub功能包下自定义的消息类型。

setlocale(LC_ALL, "");

控制台输出有中文,防止乱码。

ROS_INFO("发布方");

控制台输出字符串,发布方。

ros::init(argc, argv, "ren");

创建和初始化节点。

ros::NodeHandle n;

创建节点句柄。

ros::Publisher pub = n.advertise("renxinxi",10);

创建发布者,其中泛型部分调用自定义消息类型,话题名为renxinxi。

    sub_pub::Person person;
    person.name = "张三";
    person.age = "1";
    person.height = "1.73";

声明变量并赋值。

ros::Rate rate(1);

设置循环频率,1hz。

ros::Duration(3.0).sleep();

 延时3秒给发布者注册留时间,防止数据丢失。

    while(ros::ok)
    {
        person.age += 1;
        pub.publish(person);
        rate.sleep();
        ros::spinOnce();
    }

while循环体,其中条件为ros::ok(ros系统状态)。

为了观察循环情况,将其中一个变量+1。

发布person数据。

加入循环延迟。

官方建议的spinOnce。

CMakeList.txt配置

add_executable(pub_person src/pub_person.cpp)

target_link_libraries(pub_person
  ${catkin_LIBRARIES}
)

需要多一个配置,没有代码提示,打错了会报错。这个配置的目的时先编译自定义消息类型的msg文件,再编译调用的自定义消息类型的cpp文件,这样不会出现这两个先后的逻辑问题。

add_dependencies(pub_person ${PROJECT_NAME}_generate_messages_cpp)

(3)订阅方实现

sub_person.cpp

#include "ros/ros.h"
#include "sub_pub/Person.h"

void huidiao(const sub_pub::Person::ConstPtr & msgggg)
{
    ROS_INFO("订阅人信息:%s, %d,%.2f",msgggg->name.c_str(),msgggg->age,msgggg->height);
}
int main(int argc, char  *argv[])
{
    setlocale(LC_ALL, "");
    ROS_INFO("订阅方");
    ros::init(argc, argv, "ren_sub");
    ros::NodeHandle n;
    ros::Subscriber sub = n.subscribe("renxinxi", 10,huidiao);
    ros::spin();
    return 0;
}

回调函数,name.c_str()注意改成c的字符串

void huidiao(const sub_pub::Person::ConstPtr & msgggg)
{
    ROS_INFO("订阅人信息:%s, %d,%.2f",msgggg->name.c_str(),msgggg->age,msgggg->height);
}

创建订阅者,编写代码时可ctrl+shif+空格,显示函数参数提示。

ros::Subscriber sub = n.subscribe("renxinxi", 10,huidiao);

CMakeList.txt配置

add_executable(sub_person src/sub_person.cpp)

add_dependencies(sub_person ${PROJECT_NAME}_generate_messages_cpp)

target_link_libraries(sub_person
  ${catkin_LIBRARIES}
)

(4)rosrun发布者与订阅者,给出计算图

4.ROS编程学习:自定义话题消息与c++调用_第6张图片

4.ROS编程学习:自定义话题消息与c++调用_第7张图片

4.ROS编程学习:自定义话题消息与c++调用_第8张图片

你可能感兴趣的:(ROS编程,ros)