古月居ROS入门21讲学习笔记——三 编程基础

3.1 创建工作空间与功能包

  • 工作空间

    • src:代码空间
    • build:编译空间,存放编译过程中产生的中间文件(不关心)
    • devel:开发空间,存放编译生成的可执行文件、库、脚本等(ROS2中不存在)
    • install:安装空间,存放install指令安装成功的结果

古月居ROS入门21讲学习笔记——三 编程基础_第1张图片

古月居ROS入门21讲学习笔记——三 编程基础_第2张图片

  • 创建工作空间

    #创建并初始化工作空间
    yxq@yxq-ThinkPad-S2:~/$ mkdir -p catkin_ws/src
    yxq@yxq-ThinkPad-S2:~/$ cd catkin_ws/src/
    yxq@yxq-ThinkPad-S2:~/catkin_ws/src$ catkin_init_workspace 
    
    #编译工作空间(不产生install文件夹)
    yxq@yxq-ThinkPad-S2:~/catkin_ws/src$ cd ..
    yxq@yxq-ThinkPad-S2:~/catkin_ws$ catkin_make
    #编译工作空间(产生install文件夹)
    yxq@yxq-ThinkPad-S2:~/catkin_ws$ catkin_make install
    
    #创建功能包
    yxq@yxq-ThinkPad-S2:~/catkin_ws$ cd src/
    #catkin_create_pkg  [depend1][depend2]...[dependn]	依赖:需要用到的库
    #std_msgs:ros中的标准消息结构
    yxq@yxq-ThinkPad-S2:~/catkin_ws/src$ catkin_create_pkg test_pkg std_msgs roscpp rospy
    
    #编译功能包
    yxq@yxq-ThinkPad-S2:~/catkin_ws/src$ cd ..
    yxq@yxq-ThinkPad-S2:~/catkin_ws$ catkin_make
    yxq@yxq-ThinkPad-S2:~/catkin_ws$ source devel/setup.bash
    
    #设置环境变量
    yxq@yxq-ThinkPad-S2:~/catkin_ws$ source devel/setup.bash 
    
    #检查环境变量
    yxq@yxq-ThinkPad-S2:~/catkin_ws$ echo $ROS_PACKAGE_PATH 
    /home/yxq/myproject/ros/guyue_learn/catkin_ws/src:/opt/ros/kinetic/share
    
  • package.xml 和 CMakeLists.txt

    https://blog.csdn.net/ck784101777/article/details/108425116

        cmake_minimum_required() #CMake的版本号
        project() #项目名称
        find_package() #找到编译需要的其他CMake/Catkin package
        catkin_python_setup() #catkin新加宏,打开catkin的Python Module的支持
        add_message_files() #catkin新加宏,添加自定义Message/Service/Action文件
        add_service_files()
        add_action_files()
        generate_message() #catkin新加宏,生成不同语言版本的msg/srv/action接口
        catkin_package() #catkin新加宏,生成当前package的cmake配置,供依赖本包的其他软件包调用
        add_library() #生成库
        add_executable() #生成可执行二进制文件
        add_dependencies() #定义目标文件依赖于其他目标文件,确保其他目标已被构建
        target_link_libraries() #链接
        catkin_add_gtest() #catkin新加宏,生成测试
        install() #安装至本机
    
    	<pacakge> 根标记文件
        <name> 包名
        <version> 版本号
        <description> 内容描述
        <maintainer> 维护者
        <license> 软件许可证
        <buildtool_depend> 编译构建工具,通常为 catkin
        <depend> 指定依赖项为编译、导出、运行需要的依赖,最常用
        <build_depend> 编译依赖项
        <build_export_depend> 导出依赖项
        <exec_depend> 运行依赖项
        <test_depend> 测试用例依赖项
        <doc_depend> 文档依赖项
    
  • 同一个工作空间不允许存在同名功能包,不同工作空间允许存在同名功能包

3.2 话题编程

古月居ROS入门21讲学习笔记——三 编程基础_第3张图片

3.2.1 发布者Publisher的编程实现
  • 创建功能包

    #创建功能包
    yxq@yxq-ThinkPad-S2:~/catkin_ws/src$ catkin_create_pkg learning_topic roscpp rospy std_msgs geometry_msgs turtlesim
    
  • 创建发布者代码

    • 初始化ROS节点
    • 向ROS Master注册节点信息,包括发布的话题名和话题中的消息类型
    • 创建消息数据
    • 按照一定频率循环发布消息
    /**
     * 该例程将发布turtle1/cmd_vel话题,消息类型geometry_msgs::Twist
     */
    
    //包含头文件
     #include 
     #include 
    
    int main(int argc, char *argv[])
     {
         //ROS节点初始化 前两个是(一般不关心的)参数,最后一个是节点名
         ros::init(argc,argv,"velocity_publisher");
    
         //创建节点句柄(管理API调用、节点资源)
         ros::NodeHandle n;
    
         //创建publisher,发布名为/turtle1/cmd_vel的话题topic,消息类型为geometry_msgs::Twist,队列长度10(表示publisher发布数据时等待发布的队列缓存,队列保持最新数据)
         ros::Publisher turtle_vel_pub = n.advertise("/turtle1/cmd_vel",10);
    
         //设置循环的频率
         ros::Rate loop_rate(10);
    
         int count = 0;
         while(ros::ok()){
             //初始化geometry_msgs::Twist类型的消息内容
             geometry_msgs::Twist vel_msg;
             vel_msg.linear.x = 0.5;
             vel_msg.angular.z = 0.2;
    
             //发布消息
             turtle_vel_pub.publish(vel_msg);
             //类似于cout
             ROS_INFO("Publish turtle velocity command[%0.2f m/s,%0.2f rad/s]",
                                                vel_msg.linear.x,vel_msg.angular.z)
    
            //按照循环频率延时
            loop_rate.sleep();
         }
    
         return 0;
     }
    
  • 编写CMakeList.txt

    add_executable(velocity_publisher
      src/velocity_publisher.cpp
    )
    add_dependencies(velocity_publisher ${${PROJECT_NAME}_EXPORTED_TARGETS} ${catkin_EXPORTED_TARGETS})
    target_link_libraries(velocity_publisher
      ${catkin_LIBRARIES}
    )
    
  • 编译运行

    yxq@yxq-ThinkPad-S2:~/catkin_ws$ catkin_make
    yxq@yxq-ThinkPad-S2:~/catkin_ws$ source devel/setup.bash
    yxq@yxq-ThinkPad-S2:~/catkin_ws$ roscore
    yxq@yxq-ThinkPad-S2:~/catkin_ws$ rosrun turtlesim turtlesim_node
    yxq@yxq-ThinkPad-S2:~/catkin_ws$ rosrun learning_topic velocity_publisher
    

    运行结果(可执行文件)在catkin_ws/devel/lib/learning_topic中

  • little trick

    打开文件管理器->Ctrl+H打开隐藏文件->双击bashrc->在别名(alias)那里添加alias sss=‘source devel/setup.bash’->重启终端,就可以用sss来设置环境变量了

  • 用python作为可执行文件

    • python文件存在catkin_ws/src/learning_topic/scripts中
    • 右键文件->属性->权限->将”允许作为程序执行文件“打勾
3.2.2 订阅者Subscriber的编程实现
  • 创建订阅者代码

    /**
     * 该例程将订阅/turtle1/pose话题,消息类型turtlesim::Pose
     */
    
    #include 
    #include "turtlesim/Pose.h"
    
    //接收到订阅的消息后,将会进入消息回调函数  turtlesim::Pose消息类型,ConsrPtr&常指针
     void poseCallback(const turtlesim::Pose::ConstPtr& msg){
         //将接收到的消息打印出来
        ROS_INFO("Turtle pose: x:%0.6f, y:%0.6f",msg->x,msg->y);
     }
    
    int main(int argc, char *argv[])
     {
         //初始化ROS节点
         ros::init(argc, argv, "pose_subscriber");
         
         //创建节点句柄
         ros::NodeHandle n;
    
         //创建一个Subscriber,订阅名为“/turtle1/pose”的topic,消息队列为10,注册回调函数poseCallback
         ros::Subscriber pose_sub = n.subscribe("/turtle1/pose",10,poseCallback);
         
         //循环等待回调函数(死循环),不断查看队列中有没有消息进来,如果有的话就执行回调函数
         ros::spin();
    
         return 0;
     }
    
  • 编写CMakeList.txt

    add_executable(pose_subscriber
      src/pose_subscriber.cpp
    )
    add_dependencies(pose_subscriber ${${PROJECT_NAME}_EXPORTED_TARGETS} ${catkin_EXPORTED_TARGETS})
    target_link_libraries(pose_subscriber
      ${catkin_LIBRARIES}
    )
    
3.2.3 话题消息的定义与使用

古月居ROS入门21讲学习笔记——三 编程基础_第4张图片

  • 创建msg文件夹和msg文件夹下的msg文件

    yxq@yxq-ThinkPad-S2:~/catkin_ws/src$ mkdir msg
    yxq@yxq-ThinkPad-S2:~/catkin_ws/src$ cd msg
    yxq@yxq-ThinkPad-S2:~/catkin_ws/src/msg$ touch Person.msg
    

    编辑msg文件(注意是uint而不是unit!!

    string name
    uint8 sex
    uint8 age
    
    uint8 unknown = 0
    uint8 male    = 1
    uint8 female  = 2
    
  • 在package.xml中添加功能包依赖

      <build_depend>message_generationbuild_depend>	
      <exec_depend>message_runtimeexec_depend>		
    
  • 在CmakeList.txt中添加编译选项

    #添加功能包
    find_package(catkin REQUIRED COMPONENTS
      ...
      message_generation
    )
    
    #把msg文件编译成对应的不同的程序文件的配置项
    #把Person.msg作为定义的消息接口,编译的时候针对这个消息接口进行编译
    add_message_files(
      FILES Person.msg
    )
    #在编译Person.msg文件需要依赖的ROS已有的库、包等。(string、unit8是在std_msg中定义的)
    generate_messages(DEPENDENCIES
      std_msgs
    )
    
    #创建message运行的依赖(对应exec_depend)
    catkin_package(
      CATKIN_DEPENDS
      message_runtime
    #  INCLUDE_DIRS include
    #  LIBRARIES learning_topic
    #  CATKIN_DEPENDS geometry_msgs roscpp rospy std_msgs turtlesim
    #  DEPENDS system_lib
    )
    
  • 创建发布者代码

    /***********************************************************************
    Copyright 2020 GuYueHome (www.guyuehome.com).
    ***********************************************************************/
    
    /**
     * 该例程将发布/person_info话题,自定义消息类型learning_topic::Person
     */
     
    #include 
    #include "learning_topic/Person.h"
    
    int main(int argc, char **argv)
    {
        // ROS节点初始化
        ros::init(argc, argv, "person_publisher");
    
        // 创建节点句柄
        ros::NodeHandle n;
    
        // 创建一个Publisher,发布名为/person_info的topic,消息类型为learning_topic::Person,队列长度10
        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类型的消息
        	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;
    }
    
  • 创建订阅者代码

    /***********************************************************************
    Copyright 2020 GuYueHome (www.guyuehome.com).
    ***********************************************************************/
    
    /**
     * 该例程将订阅/person_info话题,自定义消息类型learning_topic::Person
     */
     
    #include 
    #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节点
        ros::init(argc, argv, "person_subscriber");
    
        // 创建节点句柄
        ros::NodeHandle n;
    
        // 创建一个Subscriber,订阅名为/person_info的topic,注册回调函数personInfoCallback
        ros::Subscriber person_info_sub = n.subscribe("/person_info", 10, personInfoCallback);
    
        // 循环等待回调函数
        ros::spin();
    
        return 0;
    }
    
  • 修改CmakeList.txt

    add_executable(person_publisher
      src/person_publisher.cpp
    )
    #让可执行文件与动态生成的程序产生依赖关系
    add_dependencies(person_publisher ${${PROJECT_NAME}_EXPORTED_TARGETS} ${catkin_EXPORTED_TARGETS})
    target_link_libraries(person_publisher
      ${catkin_LIBRARIES}
    )
    
    add_executable(person_subscriber
      src/person_subscriber.cpp
    )
    add_dependencies(person_subscriber ${${PROJECT_NAME}_EXPORTED_TARGETS} ${catkin_EXPORTED_TARGETS})
    target_link_libraries(person_subscriber
      ${catkin_LIBRARIES}
    )
    
  • 测试

    yxq@yxq-ThinkPad-S2:~/catkin_ws$ catkin_make
    yxq@yxq-ThinkPad-S2:~/catkin_ws$ sss
    yxq@yxq-ThinkPad-S2:~/catkin_ws$ roscore
    yxq@yxq-ThinkPad-S2:~/catkin_ws$ rosrun learning_topic person_subscriber
    yxq@yxq-ThinkPad-S2:~/catkin_ws$ rosrun learning_topic person_publisher
    

    此时将roscore关掉,不影响另外两个节点(节点连接已创建,”婚介所“退出了);但是如果此时要访问参数则不行了

3.3服务编程

古月居ROS入门21讲学习笔记——三 编程基础_第5张图片

3.3.1客户端Client的编程实现
  • 创建功能包

    yxq@yxq-ThinkPad-S2:~/catkin_ws/src$ catkin_create_pkg learning_service roscpp rospy std_msgs geometry_msgs turtlesim
    
  • 创建客户端代码

    • 初始化ros节点
    • 创建一个client实例
    • 发布服务请求数据
    • 等待server处理之后的应答结果
    /***********************************************************************
    Copyright 2020 GuYueHome (www.guyuehome.com).
    ***********************************************************************/
    
    /**
     * 该例程将请求/spawn服务,服务数据类型turtlesim::Spawn
     */
    
    #include 
    #include 
    
    int main(int argc, char** argv)
    {
        // 初始化ROS节点
    	ros::init(argc, argv, "turtle_spawn");
    
        // 创建节点句柄
    	ros::NodeHandle node;
    
        // 发现/spawn服务(确保其存在)
    	ros::service::waitForService("/spawn");
    	//创建一个服务客户端,连接名为/spawn的service
    	ros::ServiceClient add_turtle = node.serviceClient<turtlesim::Spawn>("/spawn");
    
        // 初始化turtlesim::Spawn的请求数据
    	turtlesim::Spawn srv;
    	srv.request.x = 2.0;
    	srv.request.y = 2.0;
    	srv.request.name = "turtle2";
    
        // 请求服务调用
    	ROS_INFO("Call service to spwan turtle[x:%0.6f, y:%0.6f, name:%s]", 
    			 srv.request.x, srv.request.y, srv.request.name.c_str());
    
    	add_turtle.call(srv);
    
    	// 显示服务调用结果
    	ROS_INFO("Spwan turtle successfully [name:%s]", srv.response.name.c_str());
    
    	return 0;
    };
    
  • 配置客户端代码编译规则

    add_executable(turtle_spawn src/turtle_spawn.cpp)
    target_link_libraries(turtle_spawn ${catkin_LIBRARIES})
    
  • 编译运行

    yxq@yxq-ThinkPad-S2:~/catkin_ws$ catkin_make
    yxq@yxq-ThinkPad-S2:~/catkin_ws$ roscore
    yxq@yxq-ThinkPad-S2:~/catkin_ws$ rosrun turtlesim turtlesim_node
    yxq@yxq-ThinkPad-S2:~/catkin_ws$ sss
    yxq@yxq-ThinkPad-S2:~/catkin_ws$ rosrun learning_service turtle_spawn
    
3.3.2服务端Server的编程实现
  • 创建服务端代码

    • 初始化ros节点
    • 创建Server实例
    • 循环等待服务请求,进入回调函数
    • 在回调函数中完成服务功能的处理,并反馈应答数据
    /***********************************************************************
    Copyright 2020 GuYueHome (www.guyuehome.com).
    ***********************************************************************/
    
    /**
     * 该例程将执行/turtle_command服务,服务数据类型std_srvs/Trigger
     */
     
    #include 
    #include 
    #include 
    
    ros::Publisher turtle_vel_pub;
    bool pubCommand = false;
    
    // service回调函数,输入参数req,输出参数res(此处req为空)
    bool commandCallback(std_srvs::Trigger::Request  &req,
             			std_srvs::Trigger::Response &res)
    {
    	pubCommand = !pubCommand;
    
        // 显示请求数据
        ROS_INFO("Publish turtle velocity command [%s]", pubCommand==true?"Yes":"No");
    
    	// 设置反馈数据
    	res.success = true;
    	res.message = "Change turtle command state!";
    
        return true;
    }
    
    int main(int argc, char **argv)
    {
        // ROS节点初始化
        ros::init(argc, argv, "turtle_command_server");
    
        // 创建节点句柄
        ros::NodeHandle n;
    
        // 创建一个名为/turtle_command的server,注册回调函数commandCallback
        ros::ServiceServer command_service = n.advertiseService("/turtle_command", commandCallback);
    
    	// 创建一个Publisher,发布名为/turtle1/cmd_vel的topic,消息类型为geometry_msgs::Twist,队列长度10
    	turtle_vel_pub = n.advertise<geometry_msgs::Twist>("/turtle1/cmd_vel", 10);
    
        // 循环等待回调函数
        ROS_INFO("Ready to receive turtle command.");
    
    	// 设置循环的频率
    	ros::Rate loop_rate(10);
    
    	while(ros::ok())
    	{
    		// 查看一次回调函数队列
        	ros::spinOnce();
    		
    		// 如果标志为true,则发布速度指令
    		if(pubCommand)
    		{
    			geometry_msgs::Twist vel_msg;
    			vel_msg.linear.x = 0.5;
    			vel_msg.angular.z = 0.2;
    			turtle_vel_pub.publish(vel_msg);
    		}
    
    		//按照循环频率延时
    	    loop_rate.sleep();
    	}
    
        return 0;
    }
    
  • 配置客户端代码编译规则

    add_executable(turtle_command_server src/turtle_command_server.cpp)
    target_link_libraries(turtle_command_server ${catkin_LIBRARIES})
    
  • 编译运行

    yxq@yxq-ThinkPad-S2:~/catkin_ws$ catkin_make
    yxq@yxq-ThinkPad-S2:~/catkin_ws$ roscore
    yxq@yxq-ThinkPad-S2:~/catkin_ws$ rosrun turtlesim turtlesim_node
    yxq@yxq-ThinkPad-S2:~/catkin_ws$ sss
    yxq@yxq-ThinkPad-S2:~/catkin_ws$ rosrun learning_service turtle_command_server
    
    #terminal中发送请求(此时需要的请求为空)
    rosservice call turtle_command "{}"
    
3.3.3 服务数据的定义与使用
  • 创建srv文件夹,在srv里添加并编写Person.srv文件

    • —上方是request,下面是response
    string name
    uint8  age
    uint8  sex
    
    uint8 unknown = 0
    uint8 male    = 1
    uint8 female  = 2
    
    ---
    string result
    
  • package.xml中添加功能包依赖

    <build_depend>message_generationbuild_depend>
    <exec_depend>message_runtimeexec_depend>
    
  • CMakeList.txt中添加依赖选项

    • find_package( ...... message_generation)
    
    • add_service_files(FILES Person.srv)
    generate_messages(DEPENDENCIES std_msgs)
    
    • catkin_package(...... message_runtime)
    
  • 编译生成语言相关文件

    yxq@yxq-ThinkPad-S2:~/catkin_ws$ catkin_make
    
  • 创建客户端和服务端代码

    • 客户端
    /***********************************************************************
    Copyright 2020 GuYueHome (www.guyuehome.com).
    ***********************************************************************/
    
    /**
     * 该例程将请求/show_person服务,服务数据类型learning_service::Person
     */
    
    #include 
    #include "learning_service/Person.h"
    
    int main(int argc, char** argv)
    {
        // 初始化ROS节点
    	ros::init(argc, argv, "person_client");
    
        // 创建节点句柄
    	ros::NodeHandle node;
    
        // 发现/spawn服务后,创建一个服务客户端,连接名为/spawn的service
    	ros::service::waitForService("/show_person");
    	ros::ServiceClient person_client = node.serviceClient<learning_service::Person>("/show_person");
    
        // 初始化learning_service::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("Show person result : %s", srv.response.result.c_str());
    
    	return 0;
    };
    
    • 服务端
    /***********************************************************************
    Copyright 2020 GuYueHome (www.guyuehome.com).
    ***********************************************************************/
    
    /**
     * 该例程将执行/show_person服务,服务数据类型learning_service::Person
     */
     
    #include 
    #include "learning_service/Person.h"
    
    // service回调函数,输入参数req,输出参数res
    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节点初始化
        ros::init(argc, argv, "person_server");
    
        // 创建节点句柄
        ros::NodeHandle n;
    
        // 创建一个名为/show_person的server,注册回调函数personCallback
        ros::ServiceServer person_service = n.advertiseService("/show_person", personCallback);
    
        // 循环等待回调函数
        ROS_INFO("Ready to show person informtion.");
        ros::spin();
    
        return 0;
    }
    
  • 配置CMakeList.txt

    add_executable(person_client
      src/person_client.cpp
    )
    add_dependencies(person_client ${${PROJECT_NAME}_EXPORTED_TARGETS} ${catkin_EXPORTED_TARGETS})
    target_link_libraries(person_client
      ${catkin_LIBRARIES}
    )
    
    add_library(person_server
      src/person_server.cpp
    )
    add_dependencies(person_server ${${PROJECT_NAME}_EXPORTED_TARGETS} ${catkin_EXPORTED_TARGETS})
    target_link_libraries(person_server
      ${catkin_LIBRARIES}
    )
    
  • 编译运行

    yxq@yxq-ThinkPad-S2:~/catkin_ws$ catkin_make
    yxq@yxq-ThinkPad-S2:~/catkin_ws$ roscore
    yxq@yxq-ThinkPad-S2:~/catkin_ws$ rosrun 
    yxq@yxq-ThinkPad-S2:~/catkin_ws$ sss
    yxq@yxq-ThinkPad-S2:~/catkin_ws$ rosrun learning_service person_server
    yxq@yxq-ThinkPad-S2:~/catkin_ws$ rosrun learning_service person_client
    

3.4参数的使用与编程方法

古月居ROS入门21讲学习笔记——三 编程基础_第6张图片

  • 创建功能包

    yxq@yxq-ThinkPad-S2:~/catkin_ws/src$ catkin_create_pkg learning_parameter roscpp rospy std_msgs
    
  • rosparam使用(以小海龟为例)

    yxq@yxq-ThinkPad-S2:~$ roscore
    yxq@yxq-ThinkPad-S2:~$ rosrun turtlesim turtlesim_node
    
    • help

      yxq@yxq-ThinkPad-S2:~$ 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
      
    • rosparam list 查看当前有多少参数

      yxq@yxq-ThinkPad-S2:~$ rosparam list 
      /background_b
      /background_g
      /background_r	#背景颜色
      /rosdistro		#ros版本
      /roslaunch/uris/host_yxq_thinkpad_s2__44041
      /rosversion
      /run_id
      
    • rosparam get /background_b 得到某个参数的值

      yxq@yxq-ThinkPad-S2:~$ rosparam get /background_b
      255
      
    • rosparam set /background_b 100 修改某个参数的值

      yxq@yxq-ThinkPad-S2:~$ rosparam set /background_b 100
      
      #向仿真器发送刷新请求(然后小海龟的背景就可以变色了)
      yxq@yxq-ThinkPad-S2:~$ rosservice call /clear "{}" 
    
    • rosparam dump param.yaml 保存当前参数

      #保存在终端所处目录下
      yxq@yxq-ThinkPad-S2:~$ rosparam dump param.yaml
      
      background_b: 200
      background_g: 86
      background_r: 100
      rosdistro: 'kinetic
      
        '
      roslaunch:
        uris: {host_yxq_thinkpad_s2__44041: 'http://yxq-ThinkPad-S2:44041/'}
      rosversion: '1.12.17
      
        '
      run_id: 94a5db9c-57fe-11eb-ac1d-ac2b6e5e86ac
      
    • rosparam load param.yaml 加载某个参数文件

      yxq@yxq-ThinkPad-S2:~$ rosparam load param.yaml 
      #刷新
      yxq@yxq-ThinkPad-S2:~$ rosservice call /clear "{}" 
      
    • rosparam delete /background_g 删除某个参数

      yxq@yxq-ThinkPad-S2:~$ rosparam delete /background_g
      yxq@yxq-ThinkPad-S2:~$ rosparam list 
      /background_b
      /background_r
      /rosdistro
      /roslaunch/uris/host_yxq_thinkpad_s2__44041
      /rosversion
      /run_id
      yxq@yxq-ThinkPad-S2:~$ rosservice call /clear "{}" 
      
  • 在程序中实现以上功能(在刚才learning_parameter的src中创建parameter_config.cpp)

    /***********************************************************************
    Copyright 2020 GuYueHome (www.guyuehome.com).
    ***********************************************************************/
    
    /**
     * 该例程设置/读取海龟例程中的参数
     */
    #include 
    #include 
    #include 
    
    int main(int argc, char **argv)
    {
    	int red, green, blue;
    
        // ROS节点初始化
        ros::init(argc, argv, "parameter_config");
    
        // 创建节点句柄
        ros::NodeHandle node;
    
        // 读取背景颜色参数
    	ros::param::get("/background_r", red);
    	ros::param::get("/background_g", green);
    	ros::param::get("/background_b", blue);
    
    	ROS_INFO("Get Backgroud Color[%d, %d, %d]", red, green, blue);
    
    	// 设置背景颜色参数
    	ros::param::set("/background_r", 255);
    	ros::param::set("/background_g", 255);
    	ros::param::set("/background_b", 255);
    
    	ROS_INFO("Set Backgroud Color[255, 255, 255]");
    
        // 读取背景颜色参数
    	ros::param::get("/background_r", red);
    	ros::param::get("/background_g", green);
    	ros::param::get("/background_b", blue);
    
    	ROS_INFO("Re-get Backgroud Color[%d, %d, %d]", red, green, blue);
    
    	// 调用服务,刷新背景颜色
    	ros::service::waitForService("/clear");
    	ros::ServiceClient clear_background = node.serviceClient<std_srvs::Empty>("/clear");
    	std_srvs::Empty srv;
    	clear_background.call(srv);
    	
    	sleep(1);
    
        return 0;
    }
    
  • 配置CMakeList.txt

    add_executable(parameter_config
      src/parameter_config.cpp
    )
    add_dependencies(parameter_config ${${PROJECT_NAME}_EXPORTED_TARGETS} ${catkin_EXPORTED_TARGETS})
    target_link_libraries(parameter_config
      ${catkin_LIBRARIES}
    )
    
  • 编译运行

    yxq@yxq-ThinkPad-S2:~/catkin_ws$ catkin_make
    yxq@yxq-ThinkPad-S2:~/catkin_ws$ roscore
    yxq@yxq-ThinkPad-S2:~/catkin_ws$ rosrun turtlesim turtlesim_node
    yxq@yxq-ThinkPad-S2:~/catkin_ws$ sss
    yxq@yxq-ThinkPad-S2:~/catkin_ws$ rosrun learning_parameter parameter_config
    
  • parameter其他使用方法

    http://wiki.ros.org/Parameter%20Server

你可能感兴趣的:(ROS学习笔记,linux,ubuntu,c++)