1+ import rclpy
2+ from rclpy .node import Node
3+ import numpy as np
4+ import torch
5+ from spconv .pytorch .utils import PointToVoxel
6+ import cv2
7+ from cv_bridge import CvBridge
8+
9+ from sensor_msgs .msg import Image , PointCloud2 , PointField , CameraInfo
10+ from std_msgs .msg import Header
11+ import sensor_msgs_py .point_cloud2 as pc2
12+
13+ class OctoMapNode (Node ):
14+ def __init__ (self ):
15+ super ().__init__ ('octo_map_node' )
16+
17+ # Subscribe to processed perception data
18+ self .rgb_sub = self .create_subscription (
19+ Image , '/perception/rgb_processed' , self .rgb_callback , 10 )
20+ self .depth_sub = self .create_subscription (
21+ Image , '/perception/depth_processed' , self .depth_callback , 10 )
22+ self .info_sub = self .create_subscription (
23+ CameraInfo , '/perception/camera_info' , self .info_callback , 10 )
24+
25+ self .octo_pub = self .create_publisher (PointCloud2 , '/behaviour/octo_map' , 10 )
26+
27+ self .rgb_image = None
28+ self .depth_image = None
29+ self .bridge = CvBridge ()
30+
31+ # Camera intrinsics (will be updated from camera info)
32+ self .fx , self .fy , self .cx , self .cy = 525.0 , 525.0 , 320.0 , 240.0
33+
34+ self .voxel_size = 0.04
35+ self .max_range = 3.5
36+
37+ self .get_logger ().info ('OctoMap Node started - subscribing to processed perception data' )
38+
39+ def info_callback (self , msg ):
40+ """Update camera intrinsics from perception node."""
41+ self .fx = msg .k [0 ]
42+ self .fy = msg .k [4 ]
43+ self .cx = msg .k [2 ]
44+ self .cy = msg .k [5 ]
45+ self .get_logger ().info (f'Updated camera intrinsics: fx={ self .fx } , fy={ self .fy } ' )
46+
47+ def rgb_callback (self , msg ):
48+ """Receive processed RGB image from perception node."""
49+ self .rgb_image = self .bridge .imgmsg_to_cv2 (msg , 'bgr8' )
50+ self .process_rgbd_if_ready ()
51+ self .get_logger ().info ('Received processed RGB image from perception' )
52+
53+ def depth_callback (self , msg ):
54+ """Receive processed depth image from perception node."""
55+ self .depth_image = self .bridge .imgmsg_to_cv2 (msg , 'passthrough' )
56+ self .process_rgbd_if_ready ()
57+ self .get_logger ().info ('Received processed depth image from perception' )
58+
59+ # TODO: Implement point cloud generation and octomap updating
60+
61+
62+ def main (args = None ):
63+ rclpy .init (args = args )
64+ node = OctoMapNode ()
65+
66+ try :
67+ rclpy .spin (node )
68+ except KeyboardInterrupt :
69+ pass
70+ finally :
71+ node .destroy_node ()
72+ rclpy .shutdown ()
73+
74+ if __name__ == '__main__' :
75+ main ()
0 commit comments