88from sensor_msgs .msg import LaserScan
99from nav_msgs .msg import Odometry , OccupancyGrid , MapMetaData
1010
11+ from tf2_ros .buffer import Buffer
12+ from tf2_ros import LookupException , TransformException
13+ from tf2_ros .transform_listener import TransformListener
14+
1115from turtlebot3_mapper .utils import euler_from_quaternion
1216
1317class TurtlebotMapper (Node ):
1418
1519 def __init__ (self ,
1620 node_name : str = 'turtlebot_mapper' ,
17- width : int = 10 ,
18- height : int = 10 ,
19- resolution : float = 0.025 ):
21+ width : int = 8 ,
22+ height : int = 8 ,
23+ resolution : float = 0.03 ):
2024
2125 super (TurtlebotMapper , self ).__init__ (node_name = node_name )
2226 self .width = width
@@ -33,23 +37,18 @@ def __init__(self,
3337 callback = self ._scan_callback ,
3438 qos_profile = 10 ,
3539 )
36- self ._odom_subscriber = self .create_subscription (
37- msg_type = Odometry ,
38- topic = "/odom" ,
39- callback = self ._odom_callback ,
40- qos_profile = 10 ,
41- )
4240 self ._map_publisher = self .create_publisher (
4341 msg_type = OccupancyGrid ,
4442 topic = "/custom_map" ,
4543 qos_profile = 10 ,
4644 )
4745 self ._update_timer = self .create_timer (
48- timer_period_sec = 1 ,
46+ timer_period_sec = 0. 1 ,
4947 callback = self ._update_callback ,
5048 )
5149 self ._scan_init = False
52- self ._odom_init = False
50+ self ._tf_buffer = Buffer ()
51+ self ._tf_listener = TransformListener (self ._tf_buffer , self )
5352 self ._update = threading .Lock ()
5453 self .get_logger ().info (f"Init { node_name } " )
5554
@@ -58,42 +57,44 @@ def _scan_callback(self, message: LaserScan):
5857 if not self ._update .locked ():
5958 self ._scan = message
6059
61- def _odom_callback (self , message : Odometry ):
62- self ._odom_init = True
63- if not self ._update .locked ():
64- self ._odom = message
65-
6660 def _update_callback (self ):
67- if self ._scan_init and self . _odom_init :
61+ if self ._scan_init :
6862 if self ._update .locked ():
6963 return
7064 else :
7165 self ._update .acquire ()
7266 self .get_logger ().info ("updating..." )
7367 self .update (
7468 message_laser = self ._scan ,
75- message_odometry = self ._odom ,
7669 )
7770 self ._map_publisher .publish (self .occupancy_grid )
7871 self ._update .release ()
7972
8073
81- def update (self , message_laser : LaserScan , message_odometry : Odometry ):
82- _ , _ , theta = euler_from_quaternion (message_odometry .pose .pose .orientation )
83- if theta < 0 :
74+ def update (self , message_laser : LaserScan ):
75+ try :
76+ tf = self ._tf_buffer .lookup_transform ('odom' ,
77+ message_laser .header .frame_id ,
78+ message_laser .header .stamp )
79+ q = tf .transform .rotation
80+ except (TransformException , LookupException ):
81+ self .get_logger ().info ("could not get tf" )
82+ return
83+ _ , _ , theta = euler_from_quaternion (quaternion = q )
84+ if theta < 0.0 :
8485 theta += 2 * np .pi
8586 distances = self .scan_to_distances (message = message_laser )
8687 xy = self .distances_to_xy (
8788 distances = distances ,
88- x = message_odometry . pose . pose . position .x ,
89- y = message_odometry . pose . pose . position .y ,
89+ x = tf . transform . translation .x ,
90+ y = tf . transform . translation .y ,
9091 theta = theta ,
9192 )
9293 xy [:,0 ] = (xy [:,0 ] + self .width // 2 )/ self .resolution
9394 xy [:,1 ] = (xy [:,1 ] + self .height // 2 )/ self .resolution
9495 xy = xy .astype (int )
95- xo = int ((message_odometry . pose . pose . position .x + self .width // 2 )/ self .resolution )
96- yo = int ((message_odometry . pose . pose . position .y + self .height // 2 )/ self .resolution )
96+ xo = int ((tf . transform . translation .x + self .width // 2 )/ self .resolution )
97+ yo = int ((tf . transform . translation .y + self .height // 2 )/ self .resolution )
9798
9899 for i in range (xy .shape [0 ]):
99100 points = self .bresenham (
@@ -110,8 +111,8 @@ def update(self, message_laser: LaserScan, message_odometry: Odometry):
110111 continue
111112 self .grid [y , x ] = 0
112113
113- x = points [ - 1 ,0 ]
114- y = points [ - 1 ,1 ]
114+ x = xy [ i ,0 ]
115+ y = xy [ i ,1 ]
115116 if distances [i ,0 ] < message_laser .range_max :
116117 self .grid [y , x ] = 100
117118 self .grid [y + 1 , x ] = 100
0 commit comments