在ros-melodic-gazebo9仿真环境里有一个运动中的机器人,为了使它末端link保持在当前世界位置并相对世界坐标静止,我用了下述Python代码调用get_link_state和set_link_state,首先获取当前的位姿,然后循环执行设置link state的服务。以下是完整的脚本:
#!/usr/bin/env python
import rospy
from gazebo_msgs.srv import GetLinkState, GetLinkStateRequest, SetLinkState, SetLinkStateRequest
from geometry_msgs.msg import Pose, Point, Quaternion
from std_msgs.msg import Header
def get_current_pose(link_name):
"""
获取指定链接的当前位姿。
:param link_name: 要获取位姿的链接名称
:return: 当前位姿的Pose对象
"""
rospy.wait_for_service('/gazebo/get_link_state')
try:
get_link_state_service = rospy.ServiceProxy('/gazebo/get_link_state', GetLinkState)
get_link_state_request = GetLinkStateRequest()
get_link_state_request.link_name = link_name
get_link_state_request.reference_frame = 'world'
response = get_link_state_service(get_link_state_request)
return response.pose
except rospy.ServiceException as e:
print("获取链接状态服务调用失败: %s"%e)
def set_link_state(link_name, pose):
"""
设置链接状态,使指定的链接相对于世界保持静止。
:param link_name: 要设置状态的链接名称
:param pose: 设置的位姿,这里我们将位置和方向都设置为0
"""
rospy.wait_for_service('/gazebo/set_link_state')
try:
set_link_state_service = rospy.ServiceProxy('/gazebo/set_link_state', SetLinkState)
set_link_state_request = SetLinkStateRequest()
# 设置请求头信息
set_link_state_request.header = Header()
set_link_state_request.header.stamp = rospy.Time.now()
set_link_state_request.header.frame_id = 'world'
# 设置链接名称
set_link_state_request.link_name = link_name
# 设置目标位姿
set_link_state_request.pose = pose
# 设置角速度和线速度为0
set_link_state_request.twist.linear.x = 0
set_link_state_request.twist.linear.y = 0
set_link_state_request.twist.linear.z = 0
set_link_state_request.twist.angular.x = 0
set_link_state_request.twist.angular.y = 0
set_link_state_request.twist.angular.z = 0
# 发送请求并等待响应
response = set_link_state_service(set_link_state_request)
return response.success
except rospy.ServiceException as e:
print("设置链接状态服务调用失败: %s"%e)
if __name__ == '__main__':
# 初始化ROS节点
rospy.init_node('keep_link_static_example')
# 设置要保持静止的链接名称
link_name = 'mobile_base_link' # 请替换为你要设置为静止的链接名称
rate = rospy.Rate(10) # 设置循环频率为10Hz
while not rospy.is_shutdown():
# 获取当前位姿
current_pose = get_current_pose(link_name)
if current_pose:
# 创建一个Pose消息,将位置和方向都设置为当前值
pose = Pose()
pose.position = current_pose.position
pose.orientation = current_pose.orientation
# 调用函数设置链接状态
success = set_link_state(link_name, pose)
# 打印结果
if success:
print("链接 '%s' 设置为相对于世界静止成功。" % link_name)
else:
print("链接 '%s' 设置为相对于世界静止失败。" % link_name)
else:
print("无法获取链接 '%s' 的当前位姿。" % link_name)
rate.sleep() # 根据设定的循环频率休眠
但在运行中出现许多类似的报错,经过多次反复修改依然无果,在此请教各位。报错举例:
AttributeError: 'SetLinkStateRequest' object has no attribute 'link_name'
AttributeError: 'SetLinkStateRequest' object has no attribute 'header'
AttributeError: 'GetLinkStateResponse' object has no attribute 'position'
AttributeError: 'GetLinkStateResponse' object has no attribute 'pose'