ROS服务客户端先启用以下docker:sudo docker start ros_noetic_env /bin/bash先创建一个新的功能包 learn_servicecd ~/catkin_ws/src catkin_create_pkg learn_service std_msgs rospy roscpp geometry_msgs turtlesim编译cd ~/catkin_ws catkin_make创建一个新的.cpp文件cd catkin_ws/learn_service mkdir src cd src nano a_new_turtle.cpp粘贴代码/** * 该例程将请求小海龟节点里的/spawn服务会在规定的位置出现一只新的小海龟 */ #include ros/ros.h #include turtlesim/Spawn.h int main(int argc, char** argv) { ros::init(argc, argv, a_nes_turtle);// 初始化ROS节点 ros::NodeHandle node; ros::service::waitForService(/spawn); // 等待/spawn服务 ros::ServiceClient new_turtle node.serviceClientturtlesim::Spawn(/spawn);//创建一个服务客户端连接名为/spawn的服务 // 初始化turtlesim::Spawn的请求数据 turtlesim::Spawn new_turtle_srv; new_turtle_srv.request.x 6.0; new_turtle_srv.request.y 8.0; new_turtle_srv.request.name turtle2; // 请求服务传入xy位置参数以及名字参数 ROS_INFO(Call service to create a new turtle name is %s,at the x:%.1f,y:%.1f, new_turtle_srv.request.name.c_str(), new_turtle_srv.request.x,new_turtle_srv.request.y); new_turtle.call(new_turtle_srv); //请求服务 ROS_INFO(Spwan turtle successfully [name:%s], new_turtle_srv.response.name.c_str());// 显示服务调用结果 return 0; };修改learn_service里面的CMakelist.txt文件添加这两行add_executable(a_new_turtle src/a_new_turtle) target_link_libraries(a_new_turtle ${catkin_LIBRARIES})add_executable说明了生成的可执行程序的文件是a_new_turtle编译的源码是src目录下的a_new_turtle.cpp。target_link_libraries说明了编译生成可执行文件是需要链接的库。然后编译cd ~/ros_ws catkin_make刷新终端cd ~/ros_ws source devel/setup.bash然后运行程序roscore运行节点程序rosrun turtlesim turtlesim_node如果运行这个结点的时候那个海龟没出来那就输入这个指令xhost local:docker下面就会弹出non-network local connections being added to access control list就算是ok了运行客户端节点程序rosrun learn_service a_new_turtle会出现一只新的海龟如果新开一个终端切换到ros的终端后输入想要的指令之后说找不到文件可以试一下刷新以下source devel/setup.bashROS服务服务端进入catkin_ws/src/learn_service/src然后nano turtle_vel_command_server.cpp贴入以下代码/** * 该例程将执行/turtle_vel_command服务服务数据类型std_srvs/Trigger */ #include ros/ros.h #include geometry_msgs/Twist.h #include std_srvs/Trigger.h ros::Publisher turtle_vel_pub; bool pubvel false; // service回调函数输入参数req输出参数res bool pubvelCallback(std_srvs::Trigger::Request req, std_srvs::Trigger::Response res) { pubvel !pubvel; ROS_INFO(Do you want to publish the vel?: [%s], pubveltrue?Yes:No);// 打印客户端请求数据 // 设置反馈数据 res.success true; res.message The status is changed!; return true; } int main(int argc, char **argv) { ros::init(argc, argv, turtle_vel_command_server); ros::NodeHandle n; // 创建一个名为/turtle_vel_command的server注册回调函数pubvelCallback ros::ServiceServer command_service n.advertiseService(/turtle_vel_command, pubvelCallback); // 创建一个Publisher发布名为/turtle1/cmd_vel的topic消息类型为geometry_msgs::Twist队列长度8 turtle_vel_pub n.advertisegeometry_msgs::Twist(/turtle1/cmd_vel, 8); ros::Rate loop_rate(10);// 设置循环的频率 while(ros::ok()) { ros::spinOnce();// 查看一次回调函数队列 // 判断pubvel为True则发布小海龟速度指令 if(pubvel) { geometry_msgs::Twist vel_msg; vel_msg.linear.x 0.6; vel_msg.angular.z 0.8; turtle_vel_pub.publish(vel_msg); } loop_rate.sleep();//按照循环频率延时 } return 0; }然后修改CMakelist.txt添加add_executable(turtle_vel_command_server src/turtle_vel_command_server.cpp) target_link_libraries(turtle_vel_command_server ${catkin_LIBRARIES})然后编译cd ~/ros_ws catkin_make刷新终端cd ~/ros_ws source devel/setup.bash再然后就是一系列的运行和启动了新开一个终端记得切换到rootubuntu-desktop:/# 启动roscoreroscore新开一个终端记得切换到rootubuntu-desktop:/# 运行turtlesim_node 节点rosrun turtlesim turtlesim_node新开一个终端记得切换到rootubuntu-desktop:/# 运行服务端节点rosrun learn_service turtle_vel_command_server调用服务rosservice call /turtle_vel_command然后你就可以看到一只正在转圈圈的小海龟了代码这一块还在学习后面会详解一下代码如果说找不到文件就去刷新一下终端source devel/setup.bash