-
Notifications
You must be signed in to change notification settings - Fork 13
Expand file tree
/
Copy pathheading_publisher.py
More file actions
executable file
·74 lines (53 loc) · 2.14 KB
/
Copy pathheading_publisher.py
File metadata and controls
executable file
·74 lines (53 loc) · 2.14 KB
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
#!/usr/bin/env python3
import math
import random
import rclpy
from rclpy.node import Node
from nav_msgs.msg import Odometry
from msgs.msg import Heading
def quaternion_to_yaw(q):
"""Extract ENU yaw (radians) from a quaternion."""
siny_cosp = 2.0 * (q.w * q.z + q.x * q.y)
cosy_cosp = 1.0 - 2.0 * (q.y * q.y + q.z * q.z)
return math.atan2(siny_cosp, cosy_cosp)
class HeadingPublisher(Node):
def __init__(self):
super().__init__('heading_publisher')
self.declare_parameter('odom_topic', '/odom/ground_truth')
self.declare_parameter('heading_topic', '/heading')
self.declare_parameter('noise_sigma', 0.0)
self.declare_parameter('publish_rate', 10.0)
odom_topic = self.get_parameter('odom_topic').value
heading_topic = self.get_parameter('heading_topic').value
self.noise_sigma = self.get_parameter('noise_sigma').value
publish_rate = self.get_parameter('publish_rate').value
self.latest_odom = None
self.sub = self.create_subscription(
Odometry, odom_topic, self.odom_callback, 10)
self.pub = self.create_publisher(Heading, heading_topic, 10)
self.timer = self.create_timer(1.0 / publish_rate, self.publish_heading)
self.get_logger().info(
f'Heading publisher: {odom_topic} -> {heading_topic} '
f'(noise_sigma={self.noise_sigma:.4f} rad)')
def odom_callback(self, msg):
self.latest_odom = msg
def publish_heading(self):
if self.latest_odom is None:
return
q = self.latest_odom.pose.pose.orientation
yaw = quaternion_to_yaw(q)
noise = random.gauss(0.0, self.noise_sigma) if self.noise_sigma > 0.0 else 0.0
heading_msg = Heading()
heading_msg.header = self.latest_odom.header
heading_msg.heading = yaw + noise
heading_msg.heading_acc = self.noise_sigma
heading_msg.compass_bearing = 0.0
self.pub.publish(heading_msg)
def main(args=None):
rclpy.init(args=args)
node = HeadingPublisher()
rclpy.spin(node)
node.destroy_node()
rclpy.shutdown()
if __name__ == '__main__':
main()