21
21
import mip
22
22
import rospy
23
23
import yaml
24
+ from nav_msgs .msg import OccupancyGrid
24
25
from nav_msgs .msg import Path
25
26
from geometry_msgs .msg import PoseStamped
26
27
from geometry_msgs .msg import PoseWithCovarianceStamped
@@ -37,6 +38,7 @@ def __init__(self):
37
38
self .start_point = None
38
39
self .end_point = None
39
40
41
+ self .costmap_pub = rospy .Publisher ("/cost_map" , OccupancyGrid , queue_size = 10 )
40
42
self .path_pub = rospy .Publisher ("/path" , Path , queue_size = 10 )
41
43
rospy .Subscriber (
42
44
"/initialpose" , PoseWithCovarianceStamped , self .initial_pose_callback
@@ -53,6 +55,8 @@ def __init__(self):
53
55
self .up_scaled_image ,
54
56
) = self .change_image_resolution (self .original_image , self .down_scale_factor )
55
57
58
+ self .publish_initial_cost_map ()
59
+
56
60
def __del__ (self ):
57
61
pass
58
62
@@ -95,16 +99,18 @@ def pose_to_pixel(self, pose):
95
99
def pixel_to_pose (self , pixel ):
96
100
origin_x = self .origin [0 ]
97
101
origin_y = self .origin [1 ]
98
- pose_x = origin_x + pixel [0 ] * self .resolution
99
- pose_y = origin_y + (self .original_image .height - pixel [1 ]) * self .resolution
102
+ pose_x = origin_x + (pixel [0 ] + 0.5 ) * self .resolution
103
+ pose_y = (
104
+ origin_y + (self .original_image .height - pixel [1 ] - 0.5 ) * self .resolution
105
+ )
100
106
101
107
return (pose_x , pose_y )
102
108
103
109
def make_plan (self , start , goal ):
104
110
print ("\033 [92m[Make Plan] Process started.\033 [0m" )
105
111
corners = []
106
112
corners .append (start )
107
- self .find_black_pixel_corners (self .up_scaled_image , corners )
113
+ corners = self .find_black_pixel_corners (self .up_scaled_image , corners )
108
114
corners .append (goal )
109
115
110
116
valid_edges = self .get_valid_edges (self .up_scaled_image , corners )
@@ -116,6 +122,8 @@ def make_plan(self, start, goal):
116
122
117
123
self .publish_path (shortest_path_edges )
118
124
125
+ self .publish_cost_map (self .up_scaled_image , shortest_path_edges )
126
+
119
127
path_graph_image = self .draw_path_with_markers (
120
128
self .up_scaled_image , valid_edges
121
129
)
@@ -181,6 +189,48 @@ def change_image_resolution(self, image, factor):
181
189
182
190
return enlarged_image , down_scaled_image , up_scaled_image
183
191
192
+ def publish_initial_cost_map (self ):
193
+ while True :
194
+ if (
195
+ self .up_scaled_image is not None
196
+ and self .costmap_pub .get_num_connections () > 0
197
+ ):
198
+ self .publish_cost_map (self .up_scaled_image )
199
+ break
200
+ rospy .sleep (5.0 )
201
+
202
+ def publish_cost_map (self , original_image , edges = None ):
203
+ rgb_image = original_image .convert ("RGB" )
204
+ draw = ImageDraw .Draw (rgb_image )
205
+
206
+ if edges is not None :
207
+ for start , end in edges :
208
+ draw .line ([start , end ], fill = (128 , 128 , 128 ), width = 1 )
209
+
210
+ cost_map_msg = OccupancyGrid ()
211
+ cost_map_msg .header .frame_id = "map"
212
+ cost_map_msg .header .stamp = rospy .Time .now ()
213
+ cost_map_msg .info .resolution = self .resolution
214
+ cost_map_msg .info .width = rgb_image .width
215
+ cost_map_msg .info .height = rgb_image .height
216
+ cost_map_msg .info .origin .position .x = self .origin [0 ]
217
+ cost_map_msg .info .origin .position .y = self .origin [1 ]
218
+ cost_map_msg .info .origin .orientation .w = 1.0
219
+ cost_map_msg .data = []
220
+
221
+ for y in reversed (range (rgb_image .height )):
222
+ for x in range (rgb_image .width ):
223
+ original_pixel = original_image .getpixel ((x , y ))
224
+ rgb_pixel = rgb_image .getpixel ((x , y ))
225
+ if original_pixel == 0 and rgb_pixel == (128 , 128 , 128 ):
226
+ cost_map_msg .data .append (50 )
227
+ elif original_pixel == 0 :
228
+ cost_map_msg .data .append (100 )
229
+ else :
230
+ cost_map_msg .data .append (0 )
231
+
232
+ self .costmap_pub .publish (cost_map_msg )
233
+
184
234
def find_black_pixels (self , image ):
185
235
black_pixels = []
186
236
@@ -193,7 +243,8 @@ def find_black_pixels(self, image):
193
243
194
244
def enlarge_black_pixels (self , image , black_pixels , width ):
195
245
new_image = image .copy ()
196
- pixel_width = round (width / self .resolution )
246
+ pixel_width = math .ceil (width / self .resolution )
247
+ pixel_width = pixel_width + 1
197
248
new_black_pixels = set (black_pixels )
198
249
199
250
for x , y in black_pixels :
@@ -232,6 +283,8 @@ def find_black_pixel_corners(self, image, corners):
232
283
if black_neighbors == 3 :
233
284
corners .append ((x , y ))
234
285
286
+ return corners
287
+
235
288
def get_valid_edges (self , image , corners ):
236
289
valid_edges = []
237
290
0 commit comments