00001
00002 import roslib; roslib.load_manifest('stereo_slam')
00003 import sys
00004 import pylab
00005 import math
00006 import numpy as np
00007 import weakref
00008 import string
00009 import random
00010 import time
00011 import ntpath
00012 import os
00013 from matplotlib import pyplot
00014 from mpl_toolkits.mplot3d import Axes3D
00015 import tf.transformations as tf
00016
00017
00018 blocking_file = ""
00019 graph_edges_file = ""
00020 legend_edited = False
00021 colors = ['g','r','b']
00022 ax_gt = None
00023 ax_odom = None
00024 ax_vertices = None
00025 ax_edges = []
00026 edges_shown = True
00027 gt_data = []
00028 plot_dim = 3
00029
00030 class Error(Exception):
00031 """ Base class for exceptions in this module. """
00032 pass
00033
00034 def check_file_len(file):
00035 """ Check if the file length is > 0 """
00036 f = open(file)
00037 lines = f.readlines()
00038 f.close()
00039 return len(lines) > 0
00040
00041 def rm_ax(ax_id):
00042 """ Remove the axes lines """
00043 if (ax_id is not None and ax_id):
00044 l = ax_id.pop(0)
00045 wl = weakref.ref(l)
00046 l.remove()
00047 del l
00048
00049 def real_time_plot(gt_file, odom_file, graph_vertices_file):
00050 """ Function to plot the data saved into the files in real time """
00051
00052 global blocking_file, legend_edited, colors, ax_gt, ax_odom, ax_vertices, edges_shown, gt_data, plot_dim
00053
00054
00055 rm_ax(ax_gt)
00056 rm_ax(ax_odom)
00057 rm_ax(ax_vertices)
00058
00059
00060 if (gt_file != "" and os.path.exists(gt_file) and check_file_len(gt_file) and gt_file != "none"):
00061
00062
00063 f = open(gt_file)
00064 lines = f.readlines()
00065 f.close()
00066 size = lines[1].split(",")
00067 if (len(size) > 12):
00068 data = pylab.loadtxt(gt_file, delimiter=',', skiprows=1, usecols=(0,5,6,7,8,9,10,11))
00069 else:
00070 data = pylab.loadtxt(gt_file, delimiter=',', usecols=(0,1,2,3,4,5,6,7))
00071
00072
00073 if (len(data.shape) == 1):
00074 data = [data]
00075 data = np.array(data)
00076 if (plot_dim == 3):
00077 ax_gt = ax.plot(data[:,1], data[:,2], data[:,3], colors[0], label='Ground Truth')
00078 else:
00079 ax_gt = ax.plot(data[:,1], data[:,2], colors[0], label='Ground Truth')
00080
00081
00082 if (odom_file != "" and os.path.exists(odom_file) and check_file_len(odom_file)):
00083
00084
00085 data = pylab.loadtxt(odom_file, delimiter=',', skiprows=1, usecols=(5,6,7,8,9,10,11))
00086
00087
00088 if (len(data.shape) == 1):
00089 data = np.array([data])
00090 if (plot_dim == 3):
00091 ax_odom = ax.plot(data[:,0], data[:,1], data[:,2], colors[1], label='Visual Odometry')
00092 else:
00093 ax_odom = ax.plot(data[:,0], data[:,1], colors[1], label='Visual Odometry')
00094
00095
00096 if (graph_vertices_file != "" and os.path.exists(graph_vertices_file) and check_file_len(graph_vertices_file)):
00097
00098
00099 while (os.path.exists(blocking_file) and os.path.isfile(blocking_file)):
00100 time.sleep(0.5)
00101
00102
00103 data = pylab.loadtxt(graph_vertices_file, delimiter=',', skiprows=0, usecols=(0,5,6,7,8,9,10,11))
00104
00105
00106 if (len(data.shape) == 1):
00107 data = np.array([data])
00108 if (plot_dim == 3):
00109 ax_vertices = ax.plot(data[:,1], data[:,2], data[:,3], colors[2], label='Stereo slam', marker='o')
00110 else:
00111 ax_vertices = ax.plot(data[:,1], data[:,2], colors[2], label='Stereo slam', marker='o')
00112
00113
00114 if (edges_shown == True):
00115 draw_edges()
00116 else:
00117 remove_edges()
00118
00119
00120 pyplot.draw()
00121
00122
00123 if (ax_gt is not None and ax_odom is not None and ax_vertices is not None and legend_edited is False):
00124 ax.legend()
00125 legend_edited = True
00126
00127 def draw_edges():
00128 """ Draw the edges """
00129 global blocking_file, graph_edges_file, ax_edges, edges_shown, plot_dim
00130
00131
00132 remove_edges()
00133
00134
00135 if (graph_edges_file != "" and os.path.exists(graph_edges_file) and check_file_len(graph_edges_file)):
00136
00137
00138 while (os.path.exists(blocking_file) and os.path.isfile(blocking_file)):
00139 time.sleep(0.5)
00140
00141
00142 data = pylab.loadtxt(graph_edges_file, delimiter=',', skiprows=0, usecols=(2,3,4,9,10,11))
00143
00144
00145 if (len(data.shape) == 1):
00146 data = np.array([data])
00147 ax_edges = []
00148 for i in range(len(data)):
00149 vect = []
00150 vect.append([data[i,0], data[i,1], data[i,2]])
00151 vect.append([data[i,3], data[i,4], data[i,5]])
00152 vect = np.array(vect)
00153 if (plot_dim == 3):
00154 ax_edge = ax.plot(vect[:,0], vect[:,1], vect[:,2], colors[2], linestyle='--')
00155 else:
00156 ax_edge = ax.plot(vect[:,0], vect[:,1], colors[2], linestyle='--')
00157 ax_edges.append(ax_edge)
00158 edges_shown = True
00159 return
00160
00161 def remove_edges():
00162 """ Remove the edges """
00163 global ax_edges, edges_shown
00164
00165 for i in range(len(ax_edges)):
00166 l = ax_edges[i].pop(0)
00167 wl = weakref.ref(l)
00168 l.remove()
00169 del l
00170
00171 ax_edges = []
00172 edges_shown = False
00173
00174 def onclick(event):
00175 """ Handle the click event """
00176 global edges_shown
00177
00178 if (event.button == 3):
00179 if (edges_shown):
00180 remove_edges()
00181 else:
00182 draw_edges()
00183 pyplot.draw()
00184
00185
00186 if __name__ == "__main__":
00187 import argparse
00188 parser = argparse.ArgumentParser(
00189 description='Plot 3D graphics of odometry data files in real time.',
00190 formatter_class=argparse.ArgumentDefaultsHelpFormatter)
00191 parser.add_argument('ground_truth_file',
00192 help='file with ground truth')
00193 parser.add_argument('visual_odometry_file',
00194 help='file with visual odometry')
00195 parser.add_argument('graph_vertices_file',
00196 help='file the vertices of stereo slam')
00197 parser.add_argument('graph_edges_file',
00198 help='file the edges of stereo slam')
00199 parser.add_argument('-dim','--dim', type=int,
00200 help='defines the plot dimensions: 2 for xy and 3 for xyz',
00201 default=3)
00202 args = parser.parse_args()
00203 plot_dim = args.dim
00204
00205
00206 font = {'family' : 'Sans',
00207 'weight' : 'normal',
00208 'size' : 14}
00209 pylab.rc('font', **font)
00210
00211 print "GRAPH VIEWER MOUSE INPUTS:"
00212 print " - Right button: activates/deactivates the visualization of graph edges."
00213
00214
00215 blocking_file = os.path.dirname(args.graph_vertices_file) + "/.block.txt"
00216
00217
00218 graph_edges_file = args.graph_edges_file
00219
00220
00221 fig = pylab.figure(1)
00222 if (plot_dim == 3):
00223 ax = Axes3D(fig)
00224 ax.set_zlabel("Z")
00225 else:
00226 ax = fig.gca()
00227 ax.grid(True)
00228 ax.set_title("Graph Viewer")
00229 ax.set_xlabel("X")
00230 ax.set_ylabel("Y")
00231
00232
00233 fig.canvas.mpl_connect('button_press_event', onclick)
00234
00235
00236 timer = fig.canvas.new_timer(2500)
00237 real_time_plot(args.ground_truth_file, args.visual_odometry_file, args.graph_vertices_file)
00238 timer.add_callback( real_time_plot,
00239 args.ground_truth_file,
00240 args.visual_odometry_file,
00241 args.graph_vertices_file)
00242 timer.start()
00243 pylab.show()