ROS三大基本通信机制

此为自己学习笔记记录,仅供自己学习参考。

文章目录

  • 前言
  • 一、话题通信
    • 1.1发布和订阅(C++)
    • 1.2发布和订阅(python)
    • 1.3自定义msg文件
      • 1.3.1 话题通信自定义msg调用(C++)
      • 1.3.2 话题通信自定义msg调用(python)
  • 二、服务通信
    • 1.定义srv文件
    • 2.配置编译文件
    • 3.服务通信自定义srv调用(C++)
    • 4.服务通信自定义srv调用(python)
  • 三、参数服务器


前言

ROS中的基本通信机制包括三种:
1.话题通信(发布订阅模式)
2.服务通信(请求响应模式)
3.参数服务器(参数共享模式)
ROS=通信+工具软件包+功能+生态


一、话题通信

1.1发布和订阅(C++)

1.创建工作空间,创建功能包,创建c++文件,配置CmakeLists文件,编译检查CmakeLists文件是否有问题,然后打开ros核心,运行文件。
2.编辑话题的发布代码及释义如下:

#include "ros/ros.h"
#include "std_msgs/String.h"
/*
    发布方实现:
        1.包含头文件;
        ROS中文本类型 --->std_msgs/String.h
        2.初始化ROS节点;
        3.创建节点句柄;
        4.创建发布者对象;
        5.编写发布逻辑并发布数据;

*/
int main(int argc, char  *argv[])
{
    //2.初始化ROS节点;
    ros::init(argc,argv,"erGoouzi");
    //3.创建节点句柄;
    ros::NodeHandle nh;
    //4.创建发布者对象;运用的是advertise的函数,被发布者消息的类型为std_msgs,话题名为fang.
    ros::Publisher pub = nh.advertise<std_msgs::String>("fang" , 10);
    //5.编写发布逻辑并发布数据;
    //先创建被发布的消息
    std_msgs::String msg;
    //编写循环,循环中发布数据
    while (ros::ok())
    {
        msg.data = "hello";
        pub.publish(msg);
    }
    

    return 0;
}

#include "ros/ros.h"
#include "std_msgs/String.h"
#include 
/*
    发布方实现:
        1.包含头文件;
        ROS中文本类型 --->std_msgs/String.h
        2.初始化ROS节点;
        3.创建节点句柄;
        4.创建发布者对象;
        5.编写发布逻辑并发布数据;

*/
int main(int argc, char  *argv[])
{
    setlocale(LC_ALL,"");
    //2.初始化ROS节点;
    ros::init(argc,argv,"erGoouzi");
    //3.创建节点句柄;
    ros::NodeHandle nh;
    //4.创建发布者对象;运用的是advertise的函数,被发布者消息的类型为std_msgs,话题名为fang.
    ros::Publisher pub = nh.advertise<std_msgs::String>("fang" , 10);
    //5.编写发布逻辑并发布数据;
    //要求以10hz的频率发布数据,文本后添加编号
    //先创建被发布的消息
    std_msgs::String msg;
    //发布频率
    ros::Rate rate(10);
    //设置编号
    int count = 0;
    //编写循环,循环中发布数据
    while (ros::ok())
    {
        count++;
       
        //实现字符串拼接数字
        std::stringstream ss;
        ss << "hello --->" << count;
         //msg.data = "hello";
        msg.data = ss.str();
        pub.publish(msg);
        //日志输出
        ROS_INFO("发布的数据是:%s",ss.str().c_str());
        rate.sleep();
    }
    

    return 0;
}


3.编辑话题的订阅代码及释义如下:

#include "ros/ros.h"
#include "std_msgs/String.h"
/*
    订阅方实现:
        1.包含头文件;
          ROS中文本类型 --->std_msgs/String.h
        2.初始化ROS节点;
        3.创建节点句柄;
        4.创建订阅者对象;
        5.处理订阅到的数据;
        6.spin()函数声明;

*/
void doMsg(const std_msgs::String::ConstPtr &msg){
    //通过msg获取并操作订阅到的数据
    ROS_INFO("翠花订阅到的数据:%s",msg->data.c_str());
}

int main(int argc, char  *argv[])
{
    setlocale(LC_ALL,"");
    //2.初始化ROS节点;
    ros::init(argc,argv,"cuihua");
    //3.创建节点句柄;
    ros::NodeHandle nh;
    //4.创建订阅者对象;
    ros::Subscriber sub = nh.subscribe("fang",10,doMsg);
    //5.处理订阅到的数据;

    ros::spin();

    return 0;
}


1.2发布和订阅(python)

1.创建工作空间,创建功能包,创建python文件,添加python文件的权限,配置CmakeLists文件,编译检查CmakeLists文件是否有问题,然后打开ros核心,运行文件。
2.编辑话题的发布代码及释义如下:

#! /usr/bin/env python

import rospy
from std_msgs.msg import String #发布的消息的类型

"""
使用python实现消息发布:
1.导包;
2.初始化ROS节点;
3.创建发布者对象;
4.编写发布逻辑并发布数据。

"""


if __name__ == "__main__":

    # 2.初始化ROS节点;
    rospy.init_node("sanDai") #传入节点名称
    # 3.创建发布者对象;
    pub = rospy.Publisher("che",String,queue_size=10)
    # 4.编写发布逻辑并发布数据。
    #创建数据
    msg = String()
    #使用循环发布数据
    while not rospy.is_shutdown():
        msg.data = "hello"
    #发布数量
        pub.publish(msg)
        
    pass
#! /usr/bin/env python

import rospy
from std_msgs.msg import String #发布的消息的类型

"""
使用python实现消息发布:
1.导包;
2.初始化ROS节点;
3.创建发布者对象;
4.编写发布逻辑并发布数据。

"""


if __name__ == "__main__":

    # 2.初始化ROS节点;
    rospy.init_node("sanDai") #传入节点名称
    # 3.创建发布者对象;
    pub = rospy.Publisher("che",String,queue_size=10)
    # 4.编写发布逻辑并发布数据。
    #创建数据
    msg = String()
    #制定发布频率
    rate = rospy.Rate(1)
    #设置计数器
    count = 0
    #设置休眠3秒
    rospy.sleep(3)
    #使用循环发布数据
    while not rospy.is_shutdown():
        count += 1
        msg.data = "hello" + str(count)
    #发布数据
        pub.publish(msg)
        rospy.loginfo("发布的数据:%s",msg.data)
        rate.sleep()

    pass

3.编辑话题的订阅代码及释义如下:

#! /usr/bin/env python
import rospy
from std_msgs.msg import String


"""
    订阅实现流程:
        1.导包;
        2.初始化ROS节点;
        3.创建订阅者对象;
        4.回调函数处理数据;
        5.spin()
"""

def doMsg(msg):
    rospy.loginfo("我订阅的数据:%s",msg.data)

if __name__ == "__main__":
    
    # 2.初始化ROS节点;
    rospy.init_node("huaHua")
    # 3.创建订阅者对象;
    sub = rospy.Subscriber("che",String,doMsg,queue_size=10)
    # 4.回调函数处理数据;
    # 5.spin()
    rospy.spin()
    
    pass

1.3自定义msg文件

1.功能包下新建msg目录即文件夹,添加文件Person.msg

string name
int32 age
float32 height

2.编辑配置文件:

package.xml中添加编译依赖与执行依赖

<build_depend>message_generation</build_depend>
<exec_depend>message_runtime</exec_depend>
// exce_depend以前对应的是 run_depend 现在非法

CMakeLists.txt编辑 msg 相关配置

find_package(catkin REQUIRED COMPONENTS
  roscpp
  rospy
  std_msgs
  message_generation
)
# 需要加入message_generation,必须有 std_msgs
#改动地方为,添加了 message_generation
# # 配置 msg 源文件
## Generate messages in the 'msg' folder
add_message_files(
  FILES
  Person.msg
)
#改动地方为,删除了两行,只添加了 Person.msg,去掉了对应注释。
# 生成消息时依赖于 std_msgs
## Generate added messages and services with any dependencies listed here
generate_messages(
  DEPENDENCIES
  std_msgs
)
#改动地方为,去掉了最后三行注释。
#执行时依赖
catkin_package(
#  INCLUDE_DIRS include
#  LIBRARIES plumbing_pub_sub
 CATKIN_DEPENDS roscpp rospy std_msgs message_runtime
#  DEPENDS system_lib
)
#改动地方为,只添加了message_runtime,并去掉了该行的注释

ROS三大基本通信机制_第1张图片

1.3.1 话题通信自定义msg调用(C++)

1. .vscode下的c_cpp_properties.json文件配置,目的是为了提供自动检测等功能。

"includePath": [
                "/opt/ros/noetic/include/**",
                "/usr/include/**",
                "/opt/ros/noetic/include",
                //添加了如下之行
                "/home/wjy/demo03_ws/devel/include/**"

2.发布方代码编辑如下:

#include "ros/ros.h"
#include "plumbing_pub_sub/Person.h"
/*
    发布方:发布人的消息
        1.包含头文件;
            #include "plumbing_pub_sub/Person.h"
        2.初始化ROS节点;
        3.创建节点句柄;
        4.创建发布者对象;
        5.编写发布逻辑,发布数据。    
*/
int main(int argc, char *argv[])
{
    setlocale(LC_ALL,"");
    // 2.初始化ROS节点;
    ros::init(argc,argv,"banZhuRen");
    // 3.创建节点句柄;
    ros::NodeHandle nh;
    // 4.创建发布者对象;
    ros::Publisher pub = nh.advertise<plumbing_pub_sub::Person>("liaoTian",10);
    // 5.编写发布逻辑,发布数据。
    //5-1.创建被发布的数据
    plumbing_pub_sub::Person person;
    person.name = "张三";
    person.age = 1;
    person.height = 1.73;
    //5.2.设置发布频率
    ros::Rate rate(1);
    //5.3.循环发布数据
    while(ros::ok()){

        //修改数据
        person.age += 1;
        //核心:数据发布
        pub.publish(person);
        //休眠
        rate.sleep();
        //建议
        ros::spinOnce();
    }

    return 0;
}

3.发布方配置如下

add_executable(demo03_pub_person src/demo03_pub_person.cpp)

target_link_libraries(demo03_pub_person
  ${catkin_LIBRARIES}
)
//此行的添加意味着,先执行msg文件的配置编译,然后再执行代码编辑的配置编译,防止发生逻辑颠倒问题。
add_dependencies(demo03_pub_person ${PROJECT_NAME}_generate_messages_cpp)

4.订阅方代码编辑如下:

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

/* 订阅方:订阅消息
        1.包含头文件;
            #include "plumbing_pub_sub/Person.h"
        2.初始化ROS节点;
        3.创建节点句柄;
        4.创建订阅者对象;
        5.处理订阅的数据;
        6.调用spin()函数。
    */

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

int main(int argc, char *argv[])
{
    setlocale(LC_ALL,"");
    ROS_INFO("订阅方实现");
    // 2.初始化ROS节点;
    ros::init(argc,argv,"jiaZhang");
    // 3.创建节点句柄;
    ros::NodeHandle nh;
    // 4.创建订阅者对象;
    ros::Subscriber sub = nh.subscribe("liaoTian",10,doPerson);
    // 5.处理订阅的数据;

    // 6.调用spin()函数。
    ros::spin();
    return 0;
}

5.订阅方配置如下:

add_executable(demo04_sub_person src/demo04_sub_person.cpp)

target_link_libraries(demo04_sub_person
  ${catkin_LIBRARIES}
)
//此行的添加意味着,先执行msg文件的配置编译,然后再执行代码编辑的配置编译,防止发生逻辑颠倒问题。
add_dependencies(demo04_sub_person ${PROJECT_NAME}_generate_messages_cpp)

1.3.2 话题通信自定义msg调用(python)

1.VScode配置:为了方便代码提示以及误抛出异常,需要进行相应配置,将前面生成的python文件路径配置进settings.json

"python.autoComplete.extraPaths": [
        "/opt/ros/noetic/lib/python3/dist-packages",
        //只添加了以下此路径,可以增加自动补齐功能
        "/home/wjy/demo03_ws/devel/lib/python3/dist-packages"

2.发布方代码实现:

#! /usr/bin/env python
import rospy
from plumbing_pub_sub.msg import Person

"""
    发布方:发布人的消息
        1.导包;
        2.初始化ROS节点;
        3.创建发布者对象;
        4.组织发布逻辑并发布数据。
"""


if __name__ == "__main__":
    #2.初始化ROS节点;
    rospy.init_node("daMa")
    #3.创建发布者对象,需要3个参数,话题名称,消息类型,队列长度;
    pub = rospy.Publisher("jiaoSheTou",Person,queue_size=10)
    # 4.组织发布逻辑并发布数据。
    #4.1创建Person数据
    p = Person()
    p.name = "奥特曼"
    p.age = 8
    p.height = 1.85
    #4.2创建Rate对象,即发布频率;
    rate = rospy.Rate(1)
    #4.3循环发布数据
    while not rospy.is_shutdown():
        pub.publish(p)
        rospy.loginfo("发布的消息:%s,%d,%.2f",p.name,p.age,p.height)
        rate.sleep()
    pass

3 修改可执行文件权限

//在scripts文件夹上右键。在集成终端打开输入以下命令改变权限
chmod +x *.py
//查看权限情况
ll

4 发布方文件配置:

//只添加了这一行即可
scripts/demo03_pub_person_p.py

5 订阅方代码实现:

#! /usr/bin/env python
import rospy
from plumbing_pub_sub.msg import Person
"""
    订阅方:订阅人的消息
        1.导包;
        2.初始化ROS节点;
        3.创建订阅者对象;
        4.处理订阅的数据;
        5.spin()
"""

def doPerson(p):
    rospy.loginfo("小伙子的数据:%s%d,%.2f",p.name,p.age,p.height)

if __name__ == "__main__":
    # 2.初始化ROS节点;
    rospy.init_node("daYe")
    # 3.创建订阅者对象;
    sub = rospy.Subscriber("jiaoSheTou",Person,doPerson)
    # 4.处理订阅的数据;
    # 5.spin()
    rospy.spin()

    pass

6 修改可执行文件权限

//在scripts文件夹上右键。在集成终端打开输入以下命令改变权限
chmod +x *.py
//查看权限情况
ll

7 订阅方文件配置

scripts/demo04_sub_person_p.py

二、服务通信

  • 服务通信也是ROS中一种极其常用的通信模式,服务通信是基于请求响应模式的,是一种应答机制。即一个节点A向另一个节点B发送请求,B接收处理请求并产生响应结果返回A。
  • 服务通信更适用于对时时性有要求,具有一定逻辑处理的应用场景。
  • 以请求响应的方式实现不同节点之间数据交互的通信模式

注意:
1.保证顺序。客户端发起请求时,服务端需要已经启动;
2.客户端和服务端都可以存在多个;


流程:srv文件内的可用数据类型与msg文件一致,且定义srv实现流程与自定义msg实现流程类似:

  • 按照固定格式创建srv文件
  • 编辑配置文件
  • 编译生成中间文件

1.定义srv文件

服务通信中,数据分成两部分,请求与响应,在srv文件中请求和响应使用- - -分割,具体实现如下:

功能包下新建srv目录,添加xxx,srv文件,内容如下:

#客户端请求时发送的两个数字
int32 num1
int32 num2
---
#服务器响应发送的数据
int32 sum

2.配置编译文件

1.配置package.xml文件

// 在std_msgs 下添加这一行
<build_depend>message_generation</build_depend>
//在std_msgs下添加这一行
<exec_depend>message_runtime</exec_depend>

2.配置CMakeLists.txt文件

find_package(catkin REQUIRED COMPONENTS
  roscpp
  rospy
  std_msgs
  message_generation
)
#在这里只添加了最后一行 message_generation
## Generate services in the 'srv' folder
add_service_files(
  FILES
  AddInts.srv
)
#在这里打开了注释,添加了 AddInts.srv ,删除了其他2行
## Generate added messages and services with any dependencies listed here
generate_messages(
  DEPENDENCIES
  std_msgs
)
#在这里只是对下面行放开了注释
catkin_package(
#  INCLUDE_DIRS include
#  LIBRARIES plumbing_server_client
 CATKIN_DEPENDS roscpp rospy std_msgs message_runtime
#  DEPENDS system_lib
)
#在这里打开了倒数第2行的注释,末尾添加了message_runtime

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

python 中需要调用的中间文件(…/工作空间/devel/lib/python3/dist-package/包名/msg)

3.服务通信自定义srv调用(C++)

1 vscode配置如下:在终端打开该目录,打印输出该路径,复制到c_cpp_properties.json下的"includePath":里面。

2 在功能包下的src新建文件demo01_server.cpp文件,编辑服务端代码如下:

#include "ros/ros.h"
#include "plumbing_server_client/AddInts.h"
 /* 
    服务端实现:解析客户端提交的数据,并运算再产生响应
        1.包含头文件
        2.初始化ROS节点;
        3.创建节点句柄;
        4.创建一个服务对象;
        5.处理请求并产生响应;
        6.spin()
*/
bool doNums(plumbing_server_client::AddInts::Request &request,
            plumbing_server_client::AddInts::Response &response){
    //1.处理请求
    int num1 = request.num1;
    int num2 = request.num2;
    ROS_INFO("收到的请求数据:num1 = %d, num2 = %d",num1, num2);
    //2.组织响应
    int sum = num1 + num2;
    response.sum = sum;
    ROS_INFO("求和结果: sum = %d ", sum);

    return true;
}

int main(int argc, char  *argv[])
{
	setlocale(LC_ALL,"");
    // 2.初始化ROS节点;
    ros::init(argc,argv,"heiShui");//节点名称需要保持一致
    // 3.创建节点句柄;
    ros::NodeHandle nh;
    // 4.创建一个服务对象;
    ros::ServiceServer server = nh.advertiseService("addInts",doNums);
    // 5.处理请求并产生响应;
    // 6.spin()
    ros::spin();

    return 0;
}

3 配置package.xml文件:

 <build_depend>message_generation</build_depend>
//注意对应位置
 <exec_depend>message_runtime</exec_depend>

4 配置CMakeLists.txt文件:

# add_executable(${PROJECT_NAME}_node src/plumbing_server_client_node.cpp)
add_executable(demo01_server src/demo01_server.cpp)

## Specify libraries to link a library or executable target against
target_link_libraries(demo01_server
  ${catkin_LIBRARIES}
)

#这一行的意思是和之前一样,防止逻辑问题出现,需要先编译中间文件,再来编译此demo01_server文件,逻辑顺序不能错。
# add_dependencies(${PROJECT_NAME}_node ${${PROJECT_NAME}_EXPORTED_TARGETS} ${catkin_EXPORTED_TARGETS})
add_dependencies(demo01_server ${PROJECT_NAME}_gencpp)

5 在功能包下的src新建文件demo02_client.cpp文件,编辑客户端代码如下:

#include "ros/ros.h"
#include "plumbing_server_client/AddInts.h"
/* 
    客户端实现:提交两个整数,并处理响应的结果。

        1.包含头文件
        2.初始化ROS节点;
        3.创建节点句柄;
        4.创建一个客户端对象;
        5.提交请求并处理响应;
     
*/

int main(int argc, char  *argv[])
{
    setlocale(LC_ALL,"");
    // 2.初始化ROS节点;
    ros::init(argc,argv,"daBao");
    //     3.创建节点句柄;
    ros::NodeHandle nh;
    //     4.创建一个客户端对象;
    ros::ServiceClient client = nh.serviceClient<plumbing_server_client::AddInts>("addInts");
    //     5.提交请求并处理响应;
    plumbing_server_client::AddInts ai;
    //5-1. 组织请求
    ai.request.num1 = 100;
    ai.request.num2 = 200;
    //5-2. 处理响应
    bool flag = client.call(ai);
    if (flag)
    {
        ROS_INFO("响应成功!")//获取结果
        ROS_INFO("响应结果 = %d" ,ai.response.sum);
    }else{
        ROS_INFO("处理失败....");
    }
  
    return 0;
}

6 配置CMakeLists.txt文件:

add_dependencies(demo02_client ${PROJECT_NAME}_gencpp)

target_link_libraries(demo02_client
  ${catkin_LIBRARIES}
)

add_dependencies(demo02_client ${PROJECT_NAME}_gencpp)

7 优化后的客户端代码,可以动态输入数据。

#include "ros/ros.h"
#include "plumbing_server_client/AddInts.h"
/* 
    客户端实现:提交两个整数,并处理响应的结果。

        1.包含头文件
        2.初始化ROS节点;
        3.创建节点句柄;
        4.创建一个客户端对象;
        5.提交请求并处理响应;
    实现参数的动态提交
        1.格式:rosrun  xxxx  xxxx 12  34
        2.节点执行时,需要获取命令中的参数,并组织进  request
*/

int main(int argc, char  *argv[])
{
    setlocale(LC_ALL,"");
    //优化实现,获取命令中的参数
    if(argc != 3){
        ROS_INFO("提交的参数个数不对")return 1;
    }
    
    // 2.初始化ROS节点;
    ros::init(argc,argv,"daBao");
    //     3.创建节点句柄;
    ros::NodeHandle nh;
    //     4.创建一个客户端对象;
    ros::ServiceClient client = nh.serviceClient<plumbing_server_client::AddInts>("addInts");
    //     5.提交请求并处理响应;
    plumbing_server_client::AddInts ai;
    //5-1. 组织请求
    ai.request.num1 = atoi(argv[1]);
    ai.request.num2 = atoi(argv[2]);
    //5-2. 处理响应
    bool flag = client.call(ai);
    if (flag)
    {
        ROS_INFO("响应成功!")//获取结果
        ROS_INFO("响应结果 = %d" ,ai.response.sum);
    }else{
        ROS_INFO("处理失败....");
    }
  
    return 0;
}

8 当客户端先启动,使其挂起,等待服务端启动后再请求方法。

 //5-2. 处理响应
    //调用判断服务器状态的函数
    //函数1
    client.waitForExistence();
    //或者函数2也行
    ros::service::waitForExistence("服务话题");

4.服务通信自定义srv调用(python)

1 vscode配置:,配置settings.json文件方法如下:

"python.autoComplete.extraPaths": [
        "/opt/ros/noetic/lib/python3/dist-packages",
        //添加了如下之行的路径
        "/home/wjy/demo03_ws/devel/lib/python3/dist-packages"
    ],

2 新建demo01_server_p.py文件,代码编辑如下:

#! /usr/bin/env python
import rospy
# from plumbing_server_client.srv import AddInts,AddIntsRequest,AddIntsResponse
from plumbing_server_client.srv import *
"""
    服务端:解析客户端请求,产生响应
        1.导包;
        2.初始化ROS节点;
        3.创建服务端对象;
        4.处理逻辑(回调函数)
        5.spin()
"""
#参数:封装了请求数据
#返回值:响应数据
def doNum(request):
    # 1.解析提交的两个整数
    num1 = request.num1
    num2 = request.num2
    # 2.求和
    sum = num1 + num2
    # 3.将结果封装进响应
    response = AddIntsResponse()
    response.sum = sum

    rospy.loginfo("服务器解析的数据num1 = %d, num2 = %d, 响应的结果:sum = %d", num1, num2, sum)

    return response
    
    
if __name__ == "__main__":

    # 2.初始化ROS节点;
    rospy.init_node("heiShui")
    # 3.创建服务端对象;
    server = rospy.Service("addInts",AddInts,doNum)
    rospy.loginfo("服务器已经启动了")
    # 4.处理逻辑(回调函数)
    # 5.spin()
    rospy.spin()  

3 修改文件权限

chmod +x *.py
ll

4 配置CMakeLists.txt文件

## Mark executable scripts (Python etc.) for installation
## in contrast to setup.py, you can choose the destination
catkin_install_python(PROGRAMS
  scripts/demo01_server_p.py
  DESTINATION ${CATKIN_PACKAGE_BIN_DESTINATION}
)

三、参数服务器

参数服务器在ROS中主要用于实现不同节点之间的数据共享。参数服务器相当于是独立于所有节点的一个公共容器,可以将数据存储在该容器中,被不同的节点调用,当然不同的节点也可以往其中存储数据。

以共享的方式实现不同节点之间数据交互的通信模式,存储一些多节点共享的数据,类似于全局变量。

同上操作,代码如下。

#include "ros/ros.h"

/* 
    需要实现参数的新增与修改
    需求:首先设置机器人的共享参数,类型、半径(0.15米)
        再修改半径(0.2米)
    实现:
        ros::NodeHandle
            setParm("键",值)
        ros::param
            set("键",值)
    修改,只需要继续调用,setParam或 set 函数,保证键已经存在,那么值会覆盖;
*/

int main(int argc, char  *argv[])
{
    
    //初始化ROS节点;
    ros::init(argc,argv,"set_param_c");
    //创建节点句柄;
    ros::NodeHandle nh;
    //参数增-------------------------------
    //方案1: nh
    nh.setParam("type","xiaoHuang");
    nh.setParam("radius",0.15);
    //方案2: ros::param
    ros::param::set("type_param","xiaoBai");
    ros::param::set("radius_param",0.15);
    
    //参数改-------------------------------
    //方案1: nh
    nh.setParam("radius",0.2);
    //方案2: ros::param
    ros::param::set("radius_param",0.25);
    return 0;
}

你可能感兴趣的:(Ubuntu,and,ros,自动驾驶,人工智能,机器学习,ubuntu)