20 from random
import randint, seed, uniform
26 from numpy.typing
import NDArray
28 from rclpy.time
import Time
29 from transforms3d.euler
import euler2quat
32 def getPlannerResults(
33 navigator: BasicNavigator, initial_pose: PoseStamped,
34 goal_pose: PoseStamped, planners: list[str]) -> list[PoseStamped]:
36 for planner
in planners:
37 path = navigator._getPathImpl(initial_pose, goal_pose, planner, use_start=
True)
38 if path
is not None and path.error_code == 0:
41 print(planner,
'planner failed to produce the path')
47 costmap: NDArray[np.float32], max_cost: int,
48 side_buffer: int, time_stamp: Time, res: float) -> PoseStamped:
50 start.header.frame_id =
'map'
51 start.header.stamp = time_stamp
53 row = randint(side_buffer, costmap.shape[0] - side_buffer)
54 col = randint(side_buffer, costmap.shape[1] - side_buffer)
56 if costmap[row, col] < max_cost:
57 start.pose.position.x = col * res
58 start.pose.position.y = row * res
60 yaw = uniform(0, 1) * 2 * math.pi
61 quad = euler2quat(0.0, 0.0, yaw)
62 start.pose.orientation.w = quad[0]
63 start.pose.orientation.x = quad[1]
64 start.pose.orientation.y = quad[2]
65 start.pose.orientation.z = quad[3]
71 costmap: NDArray[np.float32], start: PoseStamped,
72 max_cost: int, side_buffer: int, time_stamp: Time, res: float) -> PoseStamped:
74 goal.header.frame_id =
'map'
75 goal.header.stamp = time_stamp
77 row = randint(side_buffer, costmap.shape[0] - side_buffer)
78 col = randint(side_buffer, costmap.shape[1] - side_buffer)
80 start_x = start.pose.position.x
81 start_y = start.pose.position.y
84 x_diff = goal_x - start_x
85 y_diff = goal_y - start_y
86 dist = math.sqrt(x_diff ** 2 + y_diff ** 2)
88 if costmap[row, col] < max_cost
and dist > 3.0:
89 goal.pose.position.x = goal_x
90 goal.pose.position.y = goal_y
92 yaw = uniform(0, 1) * 2 * math.pi
93 quad = euler2quat(0.0, 0.0, yaw)
94 goal.pose.orientation.w = quad[0]
95 goal.pose.orientation.x = quad[1]
96 goal.pose.orientation.y = quad[2]
97 goal.pose.orientation.z = quad[3]
105 navigator = BasicNavigator()
108 map_path = os.getcwd() +
'/' + glob.glob(
'**/100by100_20.yaml', recursive=
True)[0]
109 navigator.changeMap(map_path)
113 costmap_msg = navigator.getGlobalCostmap()
114 costmap = np.asarray(costmap_msg.data)
115 costmap.resize(costmap_msg.metadata.size_y, costmap_msg.metadata.size_x)
117 planners = [
'Navfn',
'ThetaStar',
'SmacHybrid',
'Smac2d',
'SmacLattice']
120 time_stamp = navigator.get_clock().now().to_msg()
121 results: list[PoseStamped] = []
125 res = costmap_msg.metadata.resolution
127 while len(results) != random_pairs:
128 print(
'Cycle: ', i,
'out of: ', random_pairs)
129 start = getRandomStart(costmap, max_cost, side_buffer, time_stamp, res)
130 goal = getRandomGoal(costmap, start, max_cost, side_buffer, time_stamp, res)
131 print(
'Start', start)
133 result = getPlannerResults(navigator, start, goal, planners)
134 if len(result) == len(planners):
135 results.append(result)
138 print(
'One of the planners was invalid')
140 print(
'Write Results...')
141 with open(os.getcwd() +
'/results.pickle',
'wb+')
as f:
142 pickle.dump(results, f, pickle.HIGHEST_PROTOCOL)
144 with open(os.getcwd() +
'/costmap.pickle',
'wb+')
as f:
145 pickle.dump(costmap_msg, f, pickle.HIGHEST_PROTOCOL)
147 with open(os.getcwd() +
'/planners.pickle',
'wb+')
as f:
148 pickle.dump(planners, f, pickle.HIGHEST_PROTOCOL)
149 print(
'Write Complete')
153 if __name__ ==
'__main__':