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

相关推荐
لا معنى له4 小时前
目标检测的内涵、发展和经典模型--学习笔记
人工智能·笔记·深度学习·学习·目标检测·机器学习
石像鬼₧魂石6 小时前
内网渗透靶场实操清单(基于 Vulhub+Metasploitable 2)
linux·windows·学习·ubuntu
醇氧8 小时前
org.jetbrains.annotations的@Nullable 学习
java·开发语言·学习·intellij-idea
敲敲了个代码9 小时前
隐式类型转换:哈基米 == 猫 ? true :false
开发语言·前端·javascript·学习·面试·web
光锥智能9 小时前
以机器为中心到以人为中心,大晓机器人首创ACE具身研发范式
机器人
Pandora_41710 小时前
cursor学习
学习
崇山峻岭之间10 小时前
Matlab学习笔记02
笔记·学习·matlab
weixin_4555242611 小时前
装配机器人推荐,从技术原理到选型指南,解锁智能制造新动力
机器人
Kiri霧11 小时前
Range循环和切片
前端·后端·学习·golang
猿饵块12 小时前
机器人--move_type/移动类型
机器人