ROS1学习第二弹

本文纯属记录学习过程,所学教程来自B站古月居ROS入门21讲

ROS1学习第一弹

二、关于代码

1.必有内容:

cpp 复制代码
   // ROS节点初始化
   ros::init(argc, argv, "parameter_config");

   // 创建节点句柄
   ros::NodeHandle node;
  1. 文件结构:/catkin_ws/src 中
    src
    ├── CMakeLists.txt -> /opt/ros/noetic/share/catkin/cmake/toplevel.cmake
    ├── learning_parameter
    │ ├── CMakeLists.txt
    │ ├── include
    │ │ └── learning_parameter
    │ ├── package.xml
    │ └── src
    │ └── parameter_config.cpp
    ├── learning_service
    │ ├── CMakeLists.txt
    │ ├── include
    │ │ └── learning_service
    │ ├── package.xml
    │ ├── src
    │ │ ├── person_client.cpp
    │ │ ├── person_server.cpp
    │ │ ├── turtle_command_server.cpp
    │ │ └── turtle_spawn.cpp
    │ └── srv
    │ └── Person.srv
    └── learning_topic
    ├── CMakeLists.txt
    ├── include
    │ └── learning_topic
    ├── msg
    │ └── Person.msg
    ├── package.xml
    └── src
    ├── person_publisher.cpp
    ├── person_subscriber.cpp
    ├── pose_subscriber.cpp
    └── velocity_publisher.cpp
    其中比如 └── learning_topic就是一个功能包,靠catkin_create_pkg生成,语法是catkin_create_pkg my_cpp_pkg roscpp std_msgs

3.Topic :Publisher 与 Subscriber

在功能包下面建立msg文件夹,里面.msg文件定义消息类型,整个包编译一边就能在/devel/include/下面看见具体实现定义消息类型的文件

publisher:

cpp 复制代码
#include<ros/ros.h>
#include"learning_topic/Person.h"

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

    // 创建Publisher对象(话题名、队列长度)
    ros::Publisher person_info_pub=n.advertise<learning_topic::Person>("/person_info",10);
    // 设置循环频率
    ros::Rate loop_rate(1);

    int count=0;
    while(ros::ok())
    {
        learning_topic::Person person_msg; // 创建消息对象
        person_msg.name="Tom";
        person_msg.age=18;
        person_msg.sex=learning_topic::Person::male;

        person_info_pub.publish(person_msg); // 发布消息

        ROS_INFO("Publish Person Info: name: %s, age: %d, sex: %d", 
                 person_msg.name.c_str(), person_msg.age, person_msg.sex);
        
        loop_rate.sleep(); // 控制循环频率
    }
    return 0;
}

subscriber:

cpp 复制代码
#include<ros/ros.h>
#include"learning_topic/Person.h"

void personInfoCallback(const learning_topic::Person::ConstPtr& msg)
{
    ROS_INFO("Subcribe Person Info: name:%s  age:%d  sex:%d", 
        msg->name.c_str(), msg->age, msg->sex); //
}

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

    // learning_topic::Person是自定义的消息类型
    // person_info_sub是订阅者对象
    // "/person_info"是话题名称 与publisher发布的名称一致
    // 10是队列长度,表示订阅者的消息队列长度
    // 当消息队列满时,旧消息会被丢弃
    // personInfoCallback是回调函数,当有新消息到来时会调用此函数处理消息
    // 该函数的参数是一个指向ConstPtr的指针,ConstPtr是指向常量的智能指针
    // 这样可以避免复制消息,提高效率
    // 订阅者会在后台自动处理消息队列
    // 当有新消息到来时,回调函数会被调用
    // 回调函数可以访问消息内容,并进行相应的处理
    ros::Subscriber person_info_sub=n.subscribe("/person_info",10,personInfoCallback);//
    ros::spin();
    return 0;
}

4.Service:Client 与 Server

在功能包下面建立srv文件夹,里面.srv文件定义消息类型,整个包编译一边就能在/devel/include/下面看见具体实现定义消息类型的文件

client:

cpp 复制代码
#include<ros/ros.h>
#include<learning_service/Person.h>

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

    // 等待服务可用(类似中断)
    ros::service::waitForService("/show_person");
    // 创建服务客户端
    ros::ServiceClient person_client=node.serviceClient<learning_service::Person>("/show_person");

    learning_service::Person srv;
    srv.request.name="Tom";
    srv.request.age=20;
    srv.request.sex=learning_service::Person::Request::male;

    ROS_INFO("Call service to show person[name:%s, age:%d, sex:%d]",
             srv.request.name.c_str(), srv.request.age,srv.request.sex);

    person_client.call(srv); // 调用服务
    ROS_INFO("Showperson result: %s", srv.response.result.c_str());
    
    return 0;
}

server:

cpp 复制代码
#include<ros/ros.h>
#include"learning_service/Person.h"

bool personCallback(learning_service::Person::Request &req, // 引用传递,接绑定到客户端发送的请求对象
                   learning_service::Person::Response &res) {
    ROS_INFO("Person: Name: %s, Age: %d, sex:%d", req.name.c_str(), req.age,req.sex);
    
    res.result="OK";
    return true;
}

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

    // 创建服务
    ros::ServiceServer person_service=n.advertiseService("/show_person",personCallback); 
    ROS_INFO("Person service is ready.");
    ros::spin();
    return 0;
}

5.rosparam的使用:

rosparam is a command-line tool for getting, setting, and deleting parameters from the ROS Parameter Server.
Commands:

rosparam set set parameter

rosparam get get parameter

rosparam load load parameters from file

rosparam dump dump parameters to file

rosparam delete delete parameter

rosparam list list parameter names

相关推荐
立志成为大牛的小牛2 分钟前
数据结构——二十九、图的广度优先遍历(BFS)(王道408)
数据结构·数据库·学习·程序人生·考研·算法·宽度优先
屁股割了还要学14 分钟前
【Linux入门】常用工具:yum、vim
linux·运维·服务器·c语言·c++·学习·考研
crary,记忆1 小时前
简介NPM 和 NPX
前端·学习·npm·node.js
kitsch0x972 小时前
论文学习_One Bug, Hundreds Behind: LLMs for Large-Scale Bug Discovery
学习·bug
qiuiuiu4132 小时前
正点原子RK3568学习日志19- Linux错误处理 字符驱动框架完全体
linux·服务器·学习·ubuntu
蒙奇D索大3 小时前
【计算机网络】408计算机网络高分指南:物理层编码与调制技术精讲
java·前端·学习·计算机网络
姝孟3 小时前
C++学习——类与对象详细知识点总结
c++·笔记·学习
im_AMBER3 小时前
Leetcode 35
笔记·学习·算法·leetcode
xiaoxiaoxiaolll4 小时前
封面论文丨薄膜铌酸锂平台实现强耦合电光调制,《Light Sci. Appl. 》报道机器学习优化新范式
人工智能·学习
悟空码字4 小时前
宇树科技:决定更名
机器人·宇树科技·更名