Skip to content

Commit 8cccc1b

Browse files
committed
🐛 Fix the laser points projection at the odometry frame
Using tf2_ros package to lookup for transformation between the odometry and laser frames.
1 parent c341f8e commit 8cccc1b

File tree

1 file changed

+28
-27
lines changed

1 file changed

+28
-27
lines changed

turtlebot3_mapper/mapper.py

Lines changed: 28 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -8,15 +8,19 @@
88
from sensor_msgs.msg import LaserScan
99
from 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+
1115
from turtlebot3_mapper.utils import euler_from_quaternion
1216

1317
class 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

Comments
 (0)