Skip to content

Commit 67d533d

Browse files
authored
WIP #7: Updated Field_Mapper Node to work with rotated transforms
Rotates the local map so it fits into the field map properly. Removed loops to work with numpy more efficiently. We need to find a way to deal with the additional junk values that arise in the area surrounding the rotated map.
1 parent 8b0a192 commit 67d533d

File tree

1 file changed

+49
-17
lines changed

1 file changed

+49
-17
lines changed

robot_slam/obstacle_avoidance/Field_Mapper.py

Lines changed: 49 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -2,41 +2,73 @@
22
import rospy
33
import numpy as np
44
import tf2_ros
5+
from geometry_msgs.msg import Quaternion
6+
from tf.transformations import euler_from_quaternion
7+
import cv2
58

6-
field = Field(length = 600, width = 400)
7-
#listener = tf.transform_listener()
8-
tfBuffer = tf2_ros.Buffer()
9-
listener = tf2_ros.TransformListener(tfBuffer)
10-
rospy.Subscriber("elevation_mapping/occ_grid", OccupancyGrid, field.update_field)
11-
rospy.spin()
129

1310

1411

1512
class Field:
1613
def __init__(self, length, width):
17-
self.map = np.array(size=(600,400)) #length, width
14+
self.map = np.array(size=(600,400))
1815
self.xpos = 0
1916
self.ypos = 0
17+
self.tfBuffer = tf2_ros.Buffer()
18+
self.listener = tf2_ros.TransformListener(tfBuffer)
2019
#self.map_pub = rospy.Publisher
2120

2221
def update_field(self, new_map_msg):
2322
#convert msg to numpy array
2423
#get pose of robot relative to world
2524
#update corresponding region of self.map
26-
local_map = np.reshape(OccupancyGrid.data, (OccupancyGrid.info.height, OccupancyGrid.info.width))
25+
26+
27+
local_map = np.reshape(new_map_msg.data, (new_map_msg.info.height, new_map_msg.info.width))
2728
cur_tf = tfBuffer.lookup_transform("world_pose", "robot_pose", rospy.time(0))
29+
q = [cur_tf.transform.rotation.x,
30+
cur_tf.transform.rotation.y,
31+
cur_tf.transform.rotation.z,
32+
cur_tf.transform.rotation.w] #quaternion from tf
33+
rpy = euler_from_quaternion(Quaternion(q[0], q[1], q[2], q[3]))
34+
#Rotate the local map based on the difference in angles of the transforms
35+
(h, w) = local_map.shape[:2]
36+
(origin_X, origin_Y) = (w/2, h/2)
37+
38+
39+
M = cv2.getRotationMatrix2D((cX, cY), rpy[2], 1.0)
40+
cos = np.abs(M[0, 0])
41+
sin = np.abs(M[0, 1])
42+
43+
new_w = int((h * sin) + (w * cos))
44+
new_h = int((h * cos) + (w * sin))
45+
46+
M[0, 2] += (new_w/2) - origin_X
47+
M[1, 2] += (new_h/2) - origin_Y
48+
adj_lmap = cv2.warpAffine(local_map, M, (new_w, new_h))
49+
50+
#Add values from adjusted local map to world map
51+
52+
(adj_x, adj_y) = adj_lmap.shape[:2]
53+
54+
2855
local_x = cur_tf.getOrigin().x()
2956
local_y = cur_tf.getOrigin().y()
30-
for y in local_map:
31-
local_y = cur_tf.getOrigin().y()
32-
for x in y:
33-
self.map[local_y][local_x] = local_map[y][x]
34-
local_y += 1
35-
local_x += 1
57+
(field_x, field_y) = Field.shape[:2]
58+
field_x /= 2
59+
field_y /= 2
60+
dif_x = np.abs(field_x - local_x)
61+
dif_y = np.abs(field_y - local_y)
62+
63+
Field[dif_x:(dif_x+adj_x), dif_y:(dif_y+adj_y)] = adj_lmap
64+
3665

37-
66+
3867

39-
40-
def msg_callback(new_map.msg):
68+
if __name__ == "__main__":
69+
field = Field(length = 600, width = 400)
70+
#listener = tf.transform_listener()
71+
rospy.Subscriber("elevation_mapping/occ_grid", OccupancyGrid, field.update_field)
72+
rospy.spin()
4173

4274

0 commit comments

Comments
 (0)