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

相关推荐
LFly_ice9 分钟前
学习React-16-useContext
前端·学习·react.js
cetcht888811 分钟前
从 “有人值守” 到 “少人运维”:智能巡检机器人重塑配电室管理模式
大数据·运维·人工智能·机器人
yuxb7314 分钟前
华为云学习笔记(1):ECS 实例操作与密钥登录实践
笔记·学习·华为云
im_AMBER21 分钟前
c回顾 03
c语言·学习
yuxb7325 分钟前
华为云学习笔记(四):运维类服务与企业网站上云实践
笔记·学习·华为云
扫地的小何尚1 小时前
R²D²深度解析:NVIDIA三大神经网络突破如何变革机器人学习
神经网络·r语言·机器人·llm·gpu·nvidia
咖啡星人k1 小时前
AI 大模型驱动的开源知识库搭建系统 PandaWiki的网页挂件机器人教程
人工智能·机器人·开源
一只小风华~1 小时前
Vue Router 命名路由学习笔记
前端·javascript·vue.js·笔记·学习·ecmascript
超级大只老咪2 小时前
HTML学习路线
前端·学习·html
゜ eVer ㄨ2 小时前
React学习第三天——生命周期
前端·学习·react.js