1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101
| from math import sin, cos, pi import rclpy from rclpy.node import Node from rclpy.qos import QoSProfile from geometry_msgs.msg import Quaternion #导入四元数模块 from sensor_msgs.msg import JointState from tf2_ros import TransformBroadcaster, TransformStamped #导入坐标变换相关模块
class StatePublisher(Node):
def __init__(self): rclpy.init() super().__init__('state_publisher')
qos_profile = QoSProfile(depth=10) # 创建joint state的发布者 self.joint_pub = self.create_publisher(JointState, 'joint_states', qos_profile) # 创建坐标变换的广播器 self.broadcaster = TransformBroadcaster(self, qos=qos_profile) self.nodeName = self.get_name() self.get_logger().info("{0} started".format(self.nodeName))
degree = pi / 180.0 loop_rate = self.create_rate(30) # 发布的周期
# robot state tilt = 0. tinc = degree swivel = 0. angle = 0. height = 0. hinc = 0.005 base_link2base_footprint = 0. left_wheel2base_link = 0. right_wheel2base_link = 0. front_wheel2base_link = 0. back_wheel2base_link = 0.
# 定义需要发布的左边变换消息 odom_trans = TransformStamped() odom_trans.header.frame_id = 'odom' odom_trans.child_frame_id = 'axis' # 定义需要发布的joint state消息 joint_state = JointState()
try: while rclpy.ok(): rclpy.spin_once(self)
# update joint_state now = self.get_clock().now() joint_state.header.stamp = now.to_msg() # 设置时间戳 joint_state.name = ['base_link2base_footprint', 'left_wheel2base_link', 'right_wheel2base_link', 'front_wheel2base_link', 'back_wheel2base_link'] # 设置关节名称 joint_state.position = [base_link2base_footprint, left_wheel2base_link, right_wheel2base_link, front_wheel2base_link, back_wheel2base_link]
# update transform # (moving in a circle with radius=2) odom_trans.header.stamp = now.to_msg() odom_trans.transform.translation.x = cos(angle)*2 odom_trans.transform.translation.y = sin(angle)*2 odom_trans.transform.translation.z = 0.7 odom_trans.transform.rotation = \ euler_to_quaternion(0, 0, angle + pi/2) # roll,pitch,yaw
# send the joint state and transform self.joint_pub.publish(joint_state) self.broadcaster.sendTransform(odom_trans)
# Create new robot state tilt += tinc if tilt < -0.5 or tilt > 0.0: tinc *= -1 height += hinc if height > 0.2 or height < 0.0: hinc *= -1 swivel += degree angle += degree/4
# This will adjust as needed per iteration loop_rate.sleep()
except KeyboardInterrupt: pass
# 欧拉角转四元数 def euler_to_quaternion(roll, pitch, yaw): qx = sin(roll/2) * cos(pitch/2) * cos(yaw/2) - cos(roll/2) * sin(pitch/2) * sin(yaw/2) qy = cos(roll/2) * sin(pitch/2) * cos(yaw/2) + sin(roll/2) * cos(pitch/2) * sin(yaw/2) qz = cos(roll/2) * cos(pitch/2) * sin(yaw/2) - sin(roll/2) * sin(pitch/2) * cos(yaw/2) qw = cos(roll/2) * cos(pitch/2) * cos(yaw/2) + sin(roll/2) * sin(pitch/2) * sin(yaw/2) return Quaternion(x=qx, y=qy, z=qz, w=qw)
def main(): node = StatePublisher()
if __name__ == '__main__': main()
|