Skip to content

Commit b5d4847

Browse files
committed
update clearance value and add cost map publishing
1 parent 6f1713f commit b5d4847

File tree

3 files changed

+68
-5
lines changed

3 files changed

+68
-5
lines changed

launch/turtlebot3_vgraph_navigation.launch

+1-1
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
<arg name="map_file" default="$(find vgraph_planner)/maps/map.yaml"/>
99
<arg name="test_folder" default="$(find vgraph_planner)/test"/>
1010
<arg name="down_scale_factor" default="0.3"/>
11-
<arg name="clearance" default="0.2"/>
11+
<arg name="clearance" default="0.1"/>
1212
<arg name="open_rviz" default="true"/>
1313

1414
<include file="$(find vgraph_planner)/launch/include/turtlebot3_world.launch">

rviz/turtlebot3_navigation.rviz

+10
Original file line numberDiff line numberDiff line change
@@ -195,6 +195,16 @@ Visualization Manager:
195195
Topic: /path
196196
Unreliable: false
197197
Value: true
198+
- Alpha: 0.699999988079071
199+
Class: rviz/Map
200+
Color Scheme: map
201+
Draw Behind: false
202+
Enabled: true
203+
Name: Costmap
204+
Topic: /cost_map
205+
Unreliable: false
206+
Use Timestamp: false
207+
Value: true
198208
Enabled: true
199209
Global Options:
200210
Background Color: 48; 48; 48

scripts/vgraph_planner.py

+57-4
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
import mip
2222
import rospy
2323
import yaml
24+
from nav_msgs.msg import OccupancyGrid
2425
from nav_msgs.msg import Path
2526
from geometry_msgs.msg import PoseStamped
2627
from geometry_msgs.msg import PoseWithCovarianceStamped
@@ -37,6 +38,7 @@ def __init__(self):
3738
self.start_point = None
3839
self.end_point = None
3940

41+
self.costmap_pub = rospy.Publisher("/cost_map", OccupancyGrid, queue_size=10)
4042
self.path_pub = rospy.Publisher("/path", Path, queue_size=10)
4143
rospy.Subscriber(
4244
"/initialpose", PoseWithCovarianceStamped, self.initial_pose_callback
@@ -53,6 +55,8 @@ def __init__(self):
5355
self.up_scaled_image,
5456
) = self.change_image_resolution(self.original_image, self.down_scale_factor)
5557

58+
self.publish_initial_cost_map()
59+
5660
def __del__(self):
5761
pass
5862

@@ -95,16 +99,18 @@ def pose_to_pixel(self, pose):
9599
def pixel_to_pose(self, pixel):
96100
origin_x = self.origin[0]
97101
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+
)
100106

101107
return (pose_x, pose_y)
102108

103109
def make_plan(self, start, goal):
104110
print("\033[92m[Make Plan] Process started.\033[0m")
105111
corners = []
106112
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)
108114
corners.append(goal)
109115

110116
valid_edges = self.get_valid_edges(self.up_scaled_image, corners)
@@ -116,6 +122,8 @@ def make_plan(self, start, goal):
116122

117123
self.publish_path(shortest_path_edges)
118124

125+
self.publish_cost_map(self.up_scaled_image, shortest_path_edges)
126+
119127
path_graph_image = self.draw_path_with_markers(
120128
self.up_scaled_image, valid_edges
121129
)
@@ -181,6 +189,48 @@ def change_image_resolution(self, image, factor):
181189

182190
return enlarged_image, down_scaled_image, up_scaled_image
183191

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+
184234
def find_black_pixels(self, image):
185235
black_pixels = []
186236

@@ -193,7 +243,8 @@ def find_black_pixels(self, image):
193243

194244
def enlarge_black_pixels(self, image, black_pixels, width):
195245
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
197248
new_black_pixels = set(black_pixels)
198249

199250
for x, y in black_pixels:
@@ -232,6 +283,8 @@ def find_black_pixel_corners(self, image, corners):
232283
if black_neighbors == 3:
233284
corners.append((x, y))
234285

286+
return corners
287+
235288
def get_valid_edges(self, image, corners):
236289
valid_edges = []
237290

0 commit comments

Comments
 (0)