3.1 创建工作空间与功能包
-
工作空间
- src:代码空间
- build:编译空间,存放编译过程中产生的中间文件(不关心)
- devel:开发空间,存放编译生成的可执行文件、库、脚本等(ROS2中不存在)
- install:安装空间,存放install指令安装成功的结果
-
创建工作空间
#创建并初始化工作空间 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 <pkg_name> [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 话题编程
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 <ros/ros.h> #include <geometry_msgs/Twist.h> 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<geometry_msgs::Twist>("/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 <ros/ros.h> #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 话题消息的定义与使用
-
创建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_generation</build_depend> <!--编译依赖,动态产生msg的功能包--> <exec_depend>message_runtime</exec_depend> <!--执行依赖,动态产生msg运行时需要的依赖-->
-
在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 <ros/ros.h> #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 <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节点 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服务编程
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 <ros/ros.h> #include <turtlesim/Spawn.h> 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 <ros/ros.h> #include <geometry_msgs/Twist.h> #include <std_srvs/Trigger.h> 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_generation</build_depend> <exec_depend>message_runtime</exec_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 <ros/ros.h> #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 <ros/ros.h> #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参数的使用与编程方法
-
创建功能包
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 <string> #include <ros/ros.h> #include <std_srvs/Empty.h> 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