注意:在创建服务器代码之前,需要先创建工作空间和功能包,具体操作过程可前往目录“第4课 创建工作空间与功能包”查看文档。
#!/usr/bin/env python
# -*- coding: utf-8 -*-
# 导入ROS的python接口模块
import rospy
# 导入thread模块用于创建新线程,time模块用于休眠
import thread, time
# 从geometry_msgs.msg导入Twist消息类型,该消息定义了线性和角速度
from geometry_msgs.msg import Twist
# 从std_srvs.srv导入Trigger服务类型,该服务用于简单的触发请求
from std_srvs.srv import Trigger, TriggerResponse
# 初始化全局变量pubCommand,用于确定是否发布速度命令
pubCommand = False;
# 定义一个Publisher,发布消息到'/turtle1/cmd_vel'话题,消息类型为Twist,队列长度为10
turtle_vel_pub = rospy.Publisher('/turtle1/cmd_vel', Twist, queue_size=10)
# 定义一个线程函数,用于连续发布速度命令
def command_thread():
while True: # 持续运行
if pubCommand: # 如果pubCommand为True,则发布速度命令
vel_msg = Twist() # 创建Twist类型的消息
# 设置线速度为0.5m/s,角速度为0.2rad/s
vel_msg.linear.x = 0.5
vel_msg.angular.z = 0.2
# 使用Publisher发布速度命令
turtle_vel_pub.publish(vel_msg)
time.sleep(0.1) # 每次循环等待0.1秒
# 定义服务的回调函数,当有服务请求时调用
def commandCallback(req):
global pubCommand # 使用全局变量pubCommand
pubCommand = bool(1-pubCommand) # 切换pubCommand的值
# 在ROS日志中记录信息
rospy.loginfo("Publish turtle velocity command![%d]", pubCommand)
# 返回服务响应
return TriggerResponse(1, "Change turtle command state!")
# 定义一个函数用于设置ROS节点和服务
def turtle_command_server():
rospy.init_node('turtle_command_server') # 初始化ROS节点,名称为'turtle_command_server'
# 创建一个服务'/turtle_command',服务类型为Trigger,服务请求时调用commandCallback
s = rospy.Service('/turtle_command', Trigger, commandCallback)
print "Ready to receive turtle command."
# 创建一个新线程运行command_thread函数
thread.start_new_thread(command_thread, ())
# spin()保持python脚本不会退出,直到节点被显式关闭
rospy.spin()
# 当脚本被执行时
if __name__ == "__main__":
turtle_command_server() # 调用turtle_command_server函数
3) 输入指令“chmod +x turtle_command_server.py”,并按下回车,为保存的turtle_command_server.py赋予可执行权限。