├── data └── data ├── requirement ├── load_data.py ├── README.md └── visiual_data.py /data/data: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /requirement: -------------------------------------------------------------------------------- 1 | pyglet==1.3.2 2 | numpy==1.15.1 3 | pandas==0.23.0 4 | -------------------------------------------------------------------------------- /load_data.py: -------------------------------------------------------------------------------- 1 | import pandas as pd 2 | import matplotlib.pyplot as plt 3 | import matplotlib.patches as patches 4 | 5 | df = pd.read_csv('./data/trajectories-0400-0415.txt', header=None, sep='\s+', skiprows=[0]) 6 | df1 = df[df[0] == 1] 7 | # df[3] = (df[3] - min(df[3])) // 100 8 | # df = df.sort_values(by=[0]) 9 | # print(df) 10 | # plt.figure(8) 11 | # currentAxis = plt.gca() 12 | # df1 = df[df[0] == 1] 13 | plt.plot(df1[6], df1[7]) 14 | plt.show() 15 | # df2=pd.read_csv('./data/trajectory.csv',nrows=100) 16 | # print(df2.columns) 17 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # NGSIM lane-level trajectory animation 2 | ## Introduction 3 | This project is a hw for ITS instructed by Prof.Li. \ 4 | This project provides a simple lane-level visualization of NGSIM data. 5 | ## Usage 6 | ### Step1 7 | ```python 8 | git clone git@github.com:yolenan/NGSIM_animation.git 9 | cd Visual_trajactory 10 | ``` 11 | ### Step2 12 | Download the data from https://cloud.tsinghua.edu.cn/f/517ef67ab9294d368c7a/ 13 | and put the data in the folder `/data` 14 | ### Step3 15 | ```python 16 | conda create --name myenvname 17 | conda activate myenvname 18 | pip3 install -r requirements.txt 19 | python visual_data.py 20 | ``` 21 | -------------------------------------------------------------------------------- /visiual_data.py: -------------------------------------------------------------------------------- 1 | import os 2 | import numpy as np 3 | import pandas as pd 4 | import pyglet 5 | 6 | path = os.getcwd() 7 | 8 | 9 | class Routing(object): 10 | viewer = None 11 | 12 | def __init__(self): 13 | df = pd.read_csv(path + '/data/trajectories-0400-0415.txt', header=None, sep='\s+', skiprows=[0]) 14 | df[4] = df[4] + 50 15 | # print(min(df[4]), max(df[4]), min(df[5]), max(df[5]), min(df[6]), max(df[6]), min(df[7]), max(df[7]), 16 | # min(df[8]), max(df[8]), min(df[9]), max(df[9])) 17 | self.car_data = df[0].drop_duplicates().reset_index(drop=True).tolist() 18 | self.all_car = [] 19 | for item in self.car_data: 20 | self.all_car.append(df[df[0] == item].reset_index(drop=True)) 21 | self.endtime = max(df[1]) 22 | self.t = [0 for k in range(len(self.car_data))] 23 | self.car_pos = np.zeros(len(self.car_data), 24 | dtype=[('vehicle_id', np.int), ('frame_id', np.int), ('total_frame', np.int), 25 | ('x', np.float16), ('y', np.float16), ('vehicle_L', np.float16), 26 | ('vehicle_W', np.float16), ('type', np.int), ('num', np.int)]) 27 | self.car_pos['vehicle_id'] = [item for item in self.car_data] 28 | self.car_pos['frame_id'] = [self.all_car[i].at[0, 1] for i in range(len(self.car_data))] 29 | self.car_pos['total_frame'] = [self.all_car[i].at[0, 2] for i in range(len(self.car_data))] 30 | self.car_pos['x'] = [self.all_car[i].at[0, 4] for i in range(len(self.car_data))] 31 | self.car_pos['y'] = [self.all_car[i].at[0, 5] for i in range(len(self.car_data))] 32 | self.car_pos['vehicle_L'] = [0] * len(self.car_data) 33 | self.car_pos['vehicle_W'] = [0] * len(self.car_data) 34 | self.car_pos['type'] = [self.all_car[i].at[0, 10] for i in range(len(self.car_data))] 35 | self.car_pos['num'] = [0] * len(self.car_data) 36 | self.global_time = 0 37 | 38 | def reset(self): 39 | pass 40 | 41 | def step(self, action): 42 | global timegap 43 | done = False 44 | s = self.car_pos 45 | self.global_time = self.global_time + action 46 | if self.global_time >= self.endtime: 47 | done = True 48 | for j in range(len(self.car_data)): 49 | # pos update 50 | if self.global_time >= self.car_pos['frame_id'][j]: 51 | if self.car_pos['num'][j] < self.car_pos['total_frame'][j] - 1: 52 | self.car_pos['frame_id'][j] = self.all_car[j].at[self.car_pos['num'][j] + 1, 1] 53 | self.car_pos['x'][j] = self.all_car[j].at[self.car_pos['num'][j] + 1, 4] 54 | self.car_pos['y'][j] = self.all_car[j].at[self.car_pos['num'][j] + 1, 5] 55 | self.car_pos['vehicle_L'][j] = self.all_car[j].at[self.car_pos['num'][j] + 1, 8] 56 | self.car_pos['vehicle_W'][j] = self.all_car[j].at[self.car_pos['num'][j] + 1, 9] 57 | if self.car_pos['y'][j] + self.car_pos['vehicle_L'][j] / 2 > 495: 58 | self.car_pos['vehicle_L'][j] = max((495 - self.car_pos['y'][j]) * 2, 0) 59 | elif self.car_pos['y'][j] - self.car_pos['vehicle_L'][j] / 2 < 50: 60 | self.car_pos['vehicle_L'][j] = max((self.car_pos['y'][j] - 50) * 2, 0) 61 | self.car_pos['num'][j] += 1 62 | r = 0 63 | return s, r, done 64 | 65 | def render(self): 66 | if self.viewer is None: 67 | self.viewer = Viewer(self.car_pos, self.global_time) 68 | self.viewer.render(self.global_time) 69 | 70 | def sample_action(self): 71 | return 1 72 | 73 | 74 | class Viewer(pyglet.window.Window): 75 | node_size = 10 76 | car_size = 2 77 | 78 | def __init__(self, car_pos, global_time): 79 | super(Viewer, self).__init__(width=300, height=600, resizable=False, caption='Avmap', vsync=False) 80 | pyglet.gl.glClearColor(1, 1, 1, 1) 81 | self.car_pos = car_pos 82 | self.batch = pyglet.graphics.Batch() 83 | self.time = global_time 84 | line_from_x = [50, 50, 132, 144, 50, 62, 74, 86, 98, 110, 132] 85 | line_to_x = [132, 144, 144, 144, 50, 62, 74, 86, 98, 110, 132] 86 | line_from_y = [50, 500, 320, 320, 50, 50, 50, 50, 50, 50, 50] 87 | line_to_y = [50, 500, 320, 500, 500, 500, 500, 500, 500, 500, 500] 88 | line_list = [] 89 | for j in range(len(line_from_x)): 90 | from_x = line_from_x[j] 91 | from_y = line_from_y[j] 92 | to_x = line_to_x[j] 93 | to_y = line_to_y[j] 94 | line_list.append(from_x) 95 | line_list.append(from_y) 96 | line_list.append(to_x) 97 | line_list.append(to_y) 98 | dim = int(len(line_list) / 2) 99 | self.line = self.batch.add( 100 | dim, pyglet.gl.GL_LINES, None, 101 | ('v2f', line_list), 102 | ('c3B', (50, 129, 249) * dim) 103 | ) 104 | # draw cars 105 | self.car = [] 106 | self.init_x = car_pos['x'].copy() 107 | self.init_y = car_pos['y'].copy() 108 | for t in range(len(self.car_pos['x'])): 109 | carx = self.car_pos['x'][t] 110 | cary = self.car_pos['y'][t] 111 | carx_size = self.car_pos['vehicle_W'][t] / 2 112 | cary_size = self.car_pos['vehicle_L'][t] / 2 113 | if self.car_pos['type'][t] == 2: 114 | col = (105, 105, 105) 115 | else: 116 | col = (252, 157, 154) 117 | self.car.append(self.batch.add( 118 | 4, pyglet.gl.GL_QUADS, None, # 4 corners 119 | ('v2f', [carx - carx_size, cary + cary_size, # location 120 | carx + carx_size, cary + cary_size, 121 | carx + carx_size, cary - cary_size, 122 | carx - carx_size, cary - cary_size]), 123 | ('c3B', col * 4))) # color 124 | 125 | # draw time window 126 | t = str(self.time) 127 | self.name = pyglet.text.Label(text='NGSIM Animation by Y.A.', 128 | font_name='Times New Roman', 129 | x=10, 130 | y=550, 131 | batch=self.batch, 132 | font_size=18, 133 | color=(0, 0, 0, 200)) 134 | self.time_label = pyglet.text.Label(text='Frame ID', 135 | font_name='Times New Roman', 136 | x=170, 137 | y=200, 138 | batch=self.batch, 139 | font_size=16, 140 | color=(0, 0, 0, 200)) 141 | self.car_label = pyglet.text.Label(text='Car Num', 142 | font_name='Times New Roman', 143 | x=170, 144 | y=100, 145 | batch=self.batch, 146 | font_size=16, 147 | color=(0, 0, 0, 200)) 148 | self.system_time = pyglet.text.Label(text=t, 149 | font_name='Times New Roman', 150 | x=170, 151 | y=150, 152 | batch=self.batch, 153 | font_size=16, 154 | color=(0, 0, 0, 200)) 155 | self.car_num = pyglet.text.Label(text=str(0), 156 | font_name='Times New Roman', 157 | x=170, 158 | y=50, 159 | batch=self.batch, 160 | font_size=16, 161 | color=(0, 0, 0, 200)) 162 | 163 | def render(self, gtime): 164 | self.time = gtime 165 | self._update_veh() 166 | self.switch_to() 167 | self.dispatch_events() 168 | self.dispatch_event('on_draw') 169 | self.flip() 170 | 171 | def on_draw(self): 172 | self.clear() 173 | self.batch.draw() 174 | 175 | def _update_veh(self): 176 | self.system_time.text = str(round(self.time, 3)) 177 | car_num = 0 178 | for t in range(len(self.car_pos['x'])): 179 | car_x = self.car_pos['x'][t] 180 | car_y = self.car_pos['y'][t] 181 | carx_size = self.car_pos['vehicle_W'][t] / 2 182 | cary_size = self.car_pos['vehicle_L'][t] / 2 183 | # print(self.init_x[t], car_x) 184 | if car_x != self.init_x[t] or car_y != self.init_y[t]: 185 | xy01 = np.array([car_x - carx_size, car_y + cary_size]) 186 | xy02 = np.array([car_x + carx_size, car_y + cary_size]) 187 | xy03 = np.array([car_x + carx_size, car_y - cary_size]) 188 | xy04 = np.array([car_x - carx_size, car_y - cary_size]) 189 | if car_x >= 0 and car_x <= 200 and car_y >= 0 and car_y <= 500: 190 | car_num += 1 191 | self.car[t].vertices = np.concatenate((xy01, xy02, xy03, xy04)) 192 | self.car_num.text = str(car_num) 193 | 194 | 195 | if __name__ == '__main__': 196 | env = Routing() 197 | done = False 198 | while not done: 199 | env.render() 200 | s, r, done = env.step(env.sample_action()) 201 | --------------------------------------------------------------------------------