Nav2 Navigation Stack - jazzy  jazzy
ROS 2 Navigation Stack
process_data.py
1 #! /usr/bin/env python3
2 # Copyright 2022 Joshua Wallace
3 #
4 # Licensed under the Apache License, Version 2.0 (the "License");
5 # you may not use this file except in compliance with the License.
6 # You may obtain a copy of the License at
7 #
8 # http://www.apache.org/licenses/LICENSE-2.0
9 #
10 # Unless required by applicable law or agreed to in writing, software
11 # distributed under the License is distributed on an "AS IS" BASIS,
12 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 # See the License for the specific language governing permissions and
14 # limitations under the License.
15 
16 import math
17 import os
18 import pickle
19 
20 import matplotlib.pylab as plt
21 import numpy as np
22 import seaborn as sns
23 from tabulate import tabulate
24 
25 
26 def getPaths(results):
27  paths = []
28  for result in results:
29  for path in result:
30  paths.append(path.path)
31  return paths
32 
33 
34 def getTimes(results):
35  times = []
36  for result in results:
37  for time in result:
38  times.append(time.planning_time.nanosec / 1e09 + time.planning_time.sec)
39  return times
40 
41 
42 def getMapCoordsFromPaths(paths, resolution):
43  coords = []
44  for path in paths:
45  x = []
46  y = []
47  for pose in path.poses:
48  x.append(pose.pose.position.x / resolution)
49  y.append(pose.pose.position.y / resolution)
50  coords.append(x)
51  coords.append(y)
52  return coords
53 
54 
55 def getPathLength(path):
56  path_length = 0
57  x_prev = path.poses[0].pose.position.x
58  y_prev = path.poses[0].pose.position.y
59  for i in range(1, len(path.poses)):
60  x_curr = path.poses[i].pose.position.x
61  y_curr = path.poses[i].pose.position.y
62  path_length = path_length + math.sqrt(
63  (x_curr - x_prev) ** 2 + (y_curr - y_prev) ** 2
64  )
65  x_prev = x_curr
66  y_prev = y_curr
67  return path_length
68 
69 
70 def plotResults(costmap, paths):
71  coords = getMapCoordsFromPaths(paths, costmap.metadata.resolution)
72  data = np.asarray(costmap.data)
73  data.resize(costmap.metadata.size_y, costmap.metadata.size_x)
74  data = np.where(data <= 253, 0, data)
75 
76  plt.figure(3)
77  ax = sns.heatmap(data, cmap='Greys', cbar=False)
78  for i in range(0, len(coords), 2):
79  ax.plot(coords[i], coords[i + 1], linewidth=0.7)
80  plt.axis('off')
81  ax.set_aspect('equal', 'box')
82  plt.show()
83 
84 
85 def averagePathCost(paths, costmap, num_of_planners):
86  coords = getMapCoordsFromPaths(paths, costmap.metadata.resolution)
87  data = np.asarray(costmap.data)
88  data.resize(costmap.metadata.size_y, costmap.metadata.size_x)
89 
90  average_path_costs = []
91  for i in range(num_of_planners):
92  average_path_costs.append([])
93 
94  k = 0
95  for i in range(0, len(coords), 2):
96  costs = []
97  for j in range(len(coords[i])):
98  costs.append(data[math.floor(coords[i + 1][j])][math.floor(coords[i][j])])
99  average_path_costs[k % num_of_planners].append(sum(costs) / len(costs))
100  k += 1
101 
102  return average_path_costs
103 
104 
105 def maxPathCost(paths, costmap, num_of_planners):
106  coords = getMapCoordsFromPaths(paths, costmap.metadata.resolution)
107  data = np.asarray(costmap.data)
108  data.resize(costmap.metadata.size_y, costmap.metadata.size_x)
109 
110  max_path_costs = []
111  for i in range(num_of_planners):
112  max_path_costs.append([])
113 
114  k = 0
115  for i in range(0, len(coords), 2):
116  max_cost = 0
117  for j in range(len(coords[i])):
118  cost = data[math.floor(coords[i + 1][j])][math.floor(coords[i][j])]
119  if max_cost < cost:
120  max_cost = cost
121  max_path_costs[k % num_of_planners].append(max_cost)
122  k += 1
123 
124  return max_path_costs
125 
126 
127 def main():
128 
129  print('Read data')
130  with open(os.getcwd() + '/results.pickle', 'rb') as f:
131  results = pickle.load(f)
132 
133  with open(os.getcwd() + '/planners.pickle', 'rb') as f:
134  planners = pickle.load(f)
135 
136  with open(os.getcwd() + '/costmap.pickle', 'rb') as f:
137  costmap = pickle.load(f)
138 
139  paths = getPaths(results)
140  path_lengths = []
141 
142  for path in paths:
143  path_lengths.append(getPathLength(path))
144  path_lengths = np.asarray(path_lengths)
145  total_paths = len(paths)
146 
147  path_lengths.resize((int(total_paths / len(planners)), len(planners)))
148  path_lengths = path_lengths.transpose()
149 
150  times = getTimes(results)
151  times = np.asarray(times)
152  times.resize((int(total_paths / len(planners)), len(planners)))
153  times = np.transpose(times)
154 
155  # Costs
156  average_path_costs = np.asarray(averagePathCost(paths, costmap, len(planners)))
157  max_path_costs = np.asarray(maxPathCost(paths, costmap, len(planners)))
158 
159  # Generate table
160  planner_table = [
161  [
162  'Planner',
163  'Average path length (m)',
164  'Average Time (s)',
165  'Average cost',
166  'Max cost',
167  ]
168  ]
169 
170  for i in range(0, len(planners)):
171  planner_table.append(
172  [
173  planners[i],
174  np.average(path_lengths[i]),
175  np.average(times[i]),
176  np.average(average_path_costs[i]),
177  np.average(max_path_costs[i]),
178  ]
179  )
180 
181  # Visualize results
182  print(tabulate(planner_table))
183  plotResults(costmap, paths)
184 
185 
186 if __name__ == '__main__':
187  main()