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

相关推荐
微露清风1 天前
系统性学习Linux-第二讲-基础开发工具
linux·运维·学习
阳光九叶草LXGZXJ1 天前
达梦数据库-学习-48-DmDrs控制台命令(同步之Manager、CPT模块)
linux·运维·数据库·sql·学习
biuyyyxxx1 天前
Python自动化办公学习笔记(一) 工具安装&教程
笔记·python·学习·自动化
丝斯20111 天前
AI学习笔记整理(66)——多模态大模型MOE-LLAVA
人工智能·笔记·学习
军军君011 天前
Three.js基础功能学习十三:太阳系实例上
前端·javascript·vue.js·学习·3d·前端框架·three
bylander1 天前
【AI学习】TM Forum《Autonomous Networks Implementation Guide》快速理解
人工智能·学习·智能体·自动驾驶网络
xxxmine1 天前
redis学习
数据库·redis·学习
Techblog of HaoWANG1 天前
目标检测与跟踪 (8)- 机器人视觉窄带线激光缝隙检测系统开发
人工智能·opencv·目标检测·机器人·视觉检测·控制
码农三叔1 天前
(8-3)传感器系统与信息获取:多传感器同步与传输
人工智能·机器人·人形机器人
Yff_world1 天前
网络通信模型
学习·网络安全