Browse Source

tested for new yellow-red code. I'll apply to the generate_signals.py soon

master
김선중 1 year ago
parent
commit
1c3ca4153b
21 changed files with 12294 additions and 1359 deletions
  1. +2
    -1
      .gitignore
  2. +61
    -0
      Analysis/0221_three_points/flow_3points.csv
  3. +1515
    -0
      Analysis/0221_three_points/three_points.ipynb
  4. +7186
    -0
      Analysis/0307_red_yellow/0307_red_yellow.ipynb
  5. +1527
    -0
      Analysis/0307_red_yellow/0307_red_yellow_2.ipynb
  6. +274
    -0
      Analysis/0307_red_yellow/setup_tls_program.py
  7. +33
    -33
      Data/tables/plan.csv
  8. +1346
    -105
      Data/tables/raw_tables/0116_make_sample_table.ipynb
  9. +8
    -0
      Documents/0116_header_unix.txt
  10. BIN
      Documents/동부ICT/교통신호제어센터의 교차로 신호정보 제공 방안_20240108_검토의견.hwpx
  11. +255
    -0
      Documents/동부ICT/교통신호제어센터의 교차로 신호정보 제공 방안_20240108_검토의견.pdf
  12. BIN
      Documents/동부ICT/교통신호제어센터의 교차로 신호정보 제공 방안_20240108_수정_김선중.hwpx
  13. BIN
      Documents/동부ICT/교통신호제어센터의 교차로 신호정보 제공 방안_20240111.hwpx
  14. +0
    -0
      Documents/동부ICT/교통신호제어센터의 교차로 신호정보 제공 방안_20240111.pdf
  15. BIN
      Documents/동부ICT/교통신호제어센터의 교차로 신호정보 제공 방안_20240220.hwpx
  16. +322
    -0
      Documents/동부ICT/교통신호제어센터의 교차로 신호정보 제공 방안_20240220.pdf
  17. +341
    -341
      Results/sn_1704416700.add.xml
  18. BIN
      Scripts/__pycache__/generate_signals.cpython-38.pyc
  19. BIN
      Scripts/__pycache__/preprocess_daily.cpython-38.pyc
  20. +1
    -3
      Scripts/generate_signals.py
  21. +0
    -876
      Scripts/generate_signals_until_4-1.py

+ 2
- 1
.gitignore View File

@ -1,3 +1,4 @@
Data/tables/move/*
Intermediates/histid/*
Intermediates/movement/*
Intermediates/movement/*
Analysis/0215_augmentation/*

+ 61
- 0
Analysis/0221_three_points/flow_3points.csv View File

@ -0,0 +1,61 @@
inter_no,phase_no,ring_type,flow_lat_1,flow_lon_1,flow_lat_2,flow_lon_2,flow_lat_3,flow_lon_3
175,1,A,37.36825,127.11491,37.36857,127.1149,37.36869,127.11491
175,1,B,37.3689,127.11467,37.36857,127.11465,37.36845,127.11466
175,2,A,37.36889,127.11491,37.36857,127.1149,37.36856,127.11505
175,2,B,37.36824,127.11466,37.36857,127.11465,37.36857,127.11451
175,3,A,37.36867,127.11519,37.36867,127.11478,37.36867,127.11463
175,3,B,37.36847,127.11518,37.36847,127.11478,37.36835,127.11478
175,4,A,37.36866,127.11437,37.36867,127.11478,37.36878,127.11478
175,4,B,37.36847,127.11437,37.36847,127.11478,37.36847,127.11493
176,1,A,37.36691,127.11493,37.36724,127.11493,37.36735,127.11493
176,1,B,37.36756,127.11467,37.36723,127.11468,37.36712,127.11468
176,2,A,37.36691,127.11493,37.36724,127.11493,37.36735,127.11493
176,2,B,37.36691,127.11468,37.36724,127.11468,37.36724,127.11453
176,3,A,37.36734,127.1144,37.36734,127.11481,37.36745,127.1148
177,1,A,37.36587,127.11492,37.36619,127.11492,37.36631,127.11492
177,1,B,37.36652,127.11468,37.36619,127.11467,37.36608,127.11468
177,2,A,37.36652,127.11492,37.36619,127.11492,37.36619,127.11507
177,2,B,37.36587,127.11468,37.36619,127.11467,37.36619,127.11453
177,3,A,19.69448,117.9926,19.69448,117.9926,19.69448,117.9926
177,4,A,37.36628,127.11439,37.36629,127.1148,37.36641,127.1148
177,4,B,37.36609,127.1152,37.36609,127.1148,37.36598,127.1148
178,1,A,37.36313,127.11493,37.36346,127.11493,37.36358,127.11493
178,1,B,37.36378,127.11468,37.36346,127.11468,37.36334,127.11468
178,2,A,37.36378,127.11493,37.36346,127.11493,37.36346,127.11507
178,2,B,37.36313,127.11468,37.36346,127.11468,37.36346,127.11453
178,3,A,37.36356,127.1144,37.36356,127.1148,37.36367,127.1148
178,3,B,37.36336,127.11439,37.36336,127.1148,37.36336,127.11495
178,4,A,37.36356,127.11521,37.36356,127.1148,37.36356,127.11465
178,4,B,37.36336,127.11521,37.36336,127.1148,37.36324,127.1148
201,1,A,37.36822,127.10996,37.36854,127.10996,37.36866,127.10996
201,1,B,37.36822,127.10971,37.36854,127.10971,37.36854,127.10957
201,2,A,37.36864,127.10943,37.36864,127.10984,37.36876,127.10984
201,2,B,37.36844,127.10943,37.36844,127.10984,37.36844,127.10999
201,3,A,37.36864,127.11025,37.36864,127.10984,37.36864,127.10969
201,3,B,37.36844,127.10943,37.36844,127.10984,37.36844,127.10999
201,4,A,37.36864,127.11025,37.36864,127.10984,37.36864,127.10969
201,4,B,37.36844,127.11025,37.36844,127.10984,37.36832,127.10984
201,5,A,37.36887,127.10996,37.36854,127.10996,37.36854,127.11011
201,5,B,37.36886,127.10971,37.36854,127.10971,37.36842,127.10971
202,1,A,37.36865,127.11282,37.36865,127.11241,37.36865,127.11227
202,1,B,37.36845,127.11201,37.36845,127.11241,37.36845,127.11256
202,2,A,19.69448,117.9926,19.69448,117.9926,19.69448,117.9926
206,1,A,37.36451,127.10994,37.36483,127.10994,37.36495,127.10994
206,1,B,37.36516,127.10969,37.36484,127.10969,37.36472,127.10969
206,2,A,19.69448,117.9926,19.69448,117.9926,19.69448,117.9926
206,3,A,37.36451,127.10994,37.36483,127.10994,37.36495,127.10994
206,3,B,37.36516,127.10969,37.36484,127.10969,37.36472,127.10969
206,4,A,19.69448,117.9926,19.69448,117.9926,19.69448,117.9926
210,1,A,37.36357,127.11023,37.36357,127.10982,37.36357,127.10968
210,2,A,37.36356,127.10941,37.36357,127.10982,37.36369,127.10982
210,2,B,37.36337,127.10942,37.36337,127.10982,37.36337,127.10997
210,3,A,37.3638,127.10994,37.36347,127.10995,37.36347,127.11009
210,3,B,37.3638,127.1097,37.36347,127.1097,37.36336,127.1097
210,4,A,37.36315,127.10995,37.36347,127.10995,37.36359,127.10995
210,4,B,37.36315,127.1097,37.36347,127.1097,37.36347,127.10955
211,1,A,37.36356,127.11277,37.36356,127.11237,37.36356,127.11222
211,1,B,37.36336,127.11196,37.36336,127.11237,37.36336,127.11252
211,2,A,19.69448,117.9926,19.69448,117.9926,19.69448,117.9926
212,1,A,37.36357,127.11347,37.36357,127.11306,37.36357,127.11291
212,1,B,37.36336,127.11266,37.36337,127.11306,37.36337,127.11321
212,2,A,19.69448,117.9926,19.69448,117.9926,19.69448,117.9926

+ 1515
- 0
Analysis/0221_three_points/three_points.ipynb
File diff suppressed because it is too large
View File


+ 7186
- 0
Analysis/0307_red_yellow/0307_red_yellow.ipynb
File diff suppressed because it is too large
View File


+ 1527
- 0
Analysis/0307_red_yellow/0307_red_yellow_2.ipynb
File diff suppressed because it is too large
View File


+ 274
- 0
Analysis/0307_red_yellow/setup_tls_program.py View File

@ -0,0 +1,274 @@
import os
import sys
if '__file__' in globals():
script_dir = os.path.dirname(os.path.abspath(__file__))
sys.path.append(script_dir)
import numpy as np
import pandas as pd
GREEN_SET = {'g', 'G'}
YELLOW_SET = {'y'}
RED_SET = {'r'}
def get_intermediate_signal_state(prev, cur, signal_type='yellow'):
'''
https://github.com/cts198859/deeprl_signal_control/blob/master/envs/env.py#L128-L152
'signal_type' has one of the following two values. ['yellow', 'red']
'''
# 이전신호와 같을때
if prev == cur:
return cur, False
# 각 인덱스에 해당하는 문자를 비교
switch_reds, switch_greens = [], []
for i, (p0, p1) in enumerate(zip(prev, cur)):
# 녹색에서 적색으로 바뀔 때
if (p0 in GREEN_SET) and (p1 == 'r'):
switch_reds.append(i)
# 적색에서 녹색으로 바뀔 때
elif (p0 in 'r') and (p1 in GREEN_SET):
switch_greens.append(i)
# 녹색에서 적색으로 바뀌는 경우가 없으면
if (not switch_reds) and (signal_type == 'yellow'):
return cur, False
mid = list(cur)
for i in switch_reds:
if signal_type == 'yellow':
mid[i] = 'y'
for i in switch_greens:
mid[i] = 'r'
return ''.join(mid), True
class SetupTLSProgram:
def __init__(self, durations, reds, yellows, offset, states, path_tll_xml, name=None):
self.durations = self.as_array(durations)
self.reds = self.as_array(reds)
self.yellows = self.as_array(yellows)
self.offset = offset
self.states = states
self.path_tll_xml = path_tll_xml
self.name = name
self.num_phase = len(states) // 2
def as_array(self, x):
if isinstance(x, list):
return np.array(x)
return x
def _val(self):
# 길이가 짝수인지 확인
if len(self.states) % 2 != 0:
raise ValueError("It must have an even number of elements. Odd length detected.")
length = self.num_phase * 2
if length != len(self.durations) or length != len(self.reds) or length != len(self.yellows):
raise ValueError("The length must all match length.")
if len(set([len(s) for s in self.states])) != 1:
ValueError("All elements in 'states' must have the same length.")
if np.sum(self.durations[:self.num_phase]) != np.sum(self.durations[self.num_phase:]):
raise ValueError("The sums of the two halves of durations do not match")
self._check_always_red(self.states)
self._validate_non_negative_elements(self.durations)
self._validate_non_negative_elements(self.reds)
self._validate_non_negative_elements(self.yellows)
self._validate_non_negative_elements(self.durations - self.reds - self.yellows)
def _validate_non_negative_elements(self, lst):
if any(x < 0 for x in lst):
raise ValueError('The list contains values less than 0. Please ensure all elements in the list are non-negative.')
def _check_always_red(self, states):
colors = ['r'] * len(states[0])
for s in states:
for i, char in enumerate(s.lower()):
if char != 'r':
colors[i] = char
if 'r' in colors:
raise ValueError("'r' is not allowed in the colors collection.")
def _merge(self, s1, s2):
if len(s1) != len(s2):
raise ValueError("The lengths of s1 and s2 must be the same.")
new_s = []
for c1, c2 in zip(s1, s2):
if c1 == 'r':
new_s.append(c2)
elif c2 == 'r':
new_s.append(c1)
elif c1 == c2:
new_s.append(c1)
else:
raise ValueError(f"Unexpected characters encountered: c1={c1}, c2={c2}")
return ''.join(new_s)
def _add(self, durations, reds, yellows, states, ring_type='None'):
greens = durations - reds - yellows
colors = []
phase_numbers = []
new_states = []
for curr_i in range(len(states)):
prev_i = (curr_i - 1 + len(states)) % len(states)
next_i = (curr_i + 1) % len(states)
phase_no = curr_i + 1
r_state, _ = get_intermediate_signal_state(states[prev_i], states[curr_i], signal_type='red')
y_state, has_y = get_intermediate_signal_state(states[curr_i], states[next_i], signal_type='yellow')
g_state = states[curr_i]
# red
if reds[curr_i] != 0:
new_states += [r_state] * reds[curr_i]
colors += [1] * reds[curr_i] # 'r'
phase_numbers += [phase_no] * reds[curr_i]
# green
new_states += [g_state] * greens[curr_i]
colors += [2] * greens[curr_i] # 'g'
phase_numbers += [phase_no] * greens[curr_i]
# yellow
if has_y and yellows[curr_i] == 0:
raise ValueError('Yellow signal is required, but the yellow duration is 0.')
if not has_y and yellows[curr_i] != 0:
y_state = g_state
new_states += [y_state] * yellows[curr_i]
colors += [3] * yellows[curr_i] # 'y'
phase_numbers += [phase_no] * yellows[curr_i]
df = pd.DataFrame(
{
f'{ring_type}_ring_phase_no':phase_numbers,
f'{ring_type}_ring_color':colors,
f'{ring_type}_ring_state':new_states}
)
return df
def write_tll_xml(self, df_plan, path_tll_xml):
strings = ['<tlLogics>\n']
tllogic_id = 'None' if self.name is None else self.name
strings.append(f' <tlLogic id="{tllogic_id}" type="static" programID="tllogic_id" offset="{self.offset}">\n')
for _, row in df_plan.iterrows():
name = str(row['A_ring_phase_no']) + row['A_ring_color']
name += '_' + str(row['B_ring_phase_no']) + row['B_ring_color']
duration = row['duration']
signal_state = row['signal_state']
strings.append(f' <phase duration="{duration}" name="{name}" state="{signal_state}"/>\n')
strings.append(' </tlLogic>\n')
strings.append('</tlLogics>')
strings = ''.join(strings)
with open(path_tll_xml, 'w') as f:
f.write(strings)
def main(self):
durations, reds, yellows, states = self.durations, self.reds, self.yellows, self.states
n = self.num_phase
self._val()
df_a = self._add(durations[:n], reds[:n], yellows[:n], states[:n], 'A')
df_b = self._add(durations[n:], reds[n:], yellows[n:], states[n:], 'B')
group_cols = ['A_ring_phase_no', 'A_ring_color', 'A_ring_state', 'B_ring_phase_no', 'B_ring_color', 'B_ring_state']
sort_cols = ['A_ring_phase_no', 'A_ring_color', 'B_ring_phase_no', 'B_ring_color']
df_plan = pd.concat([df_a, df_b], axis=1) \
.groupby(group_cols) \
.size() \
.reset_index(name='duration') \
.sort_values(by=sort_cols) \
.reset_index(drop=True)
mapping = {1: 'r', 2: 'g', 3: 'y'}
df_plan['A_ring_color'] = df_plan['A_ring_color'].map(mapping)
df_plan['B_ring_color'] = df_plan['B_ring_color'].map(mapping)
df_plan['signal_state'] = df_plan.apply(lambda row: self._merge(row['A_ring_state'], row['B_ring_state']), axis=1)
assert df_plan['duration'].sum() == np.sum(durations[:n])
assert df_plan['duration'].sum() == np.sum(durations[n:])
self.write_tll_xml(df_plan, self.path_tll_xml)
return df_plan
if __name__ == '__main__':
'''
Test data
- : 5034
- A링1현시, A링2현시, ..., B링1현시, B링2현시, ...
'''
# 오버랩 테스트
durations = [51, 34, 52, 43, 46, 39, 52, 43]
reds = [2, 2, 2, 2, 2, 2, 2, 2]
yellows = [4, 4, 4, 4, 4, 4, 4, 4]
offset = 5
# # 원본
# durations = [53, 33, 51, 43, 26, 60, 51, 43]
# reds = [0, 0, 0, 0, 0, 0, 0, 0]
# yellows = [4, 4, 4, 4, 4, 4, 4, 4]
# offset = 0
# # 1795 (2023년 12월 20일 7시)
# durations = [58, 29, 50, 43, 28, 59, 50, 43]
# reds = [0, 0, 0, 0, 0, 0, 0, 0]
# yellows = [4, 4, 4, 4, 4, 4, 4, 4]
# offset = 0
# # 1888 (2023년 12월 21일 7시)
# durations = [61, 28, 48, 43, 27, 62, 48, 43]
# reds = [0, 0, 0, 0, 0, 0, 0, 0]
# yellows = [4, 4, 4, 4, 4, 4, 4, 4]
# offset = 0
# 각 현시의 이동류에 해당하는 signal state
signal_states = [
'rrrrrrrrrGGGGrrrrrrrr',
'rrrGrrrrrrrrrrrrrrrrr',
'rrrrGGGrrrrrrrrrrrrrr',
'rrrrrrrrrrrrrrrrrrrGG',
'rrrrrrrrrrrrrGGrrrrrr',
'GGGrrrrrrrrrrrrrrrrrr',
'rrrrrrrGGrrrrrrrrrrrr',
'rrrrrrrrrrrrrrrGGGGrr'
]
# 저장할 경로
path_xml = 'test.tll.xml'
path_csv = 'test.tll.csv'
# 노드id
node_id = '11053' # 교차로번호: 5034
args = durations, reds, yellows, offset, signal_states, path_xml, node_id
SetupTLSProgram(*args).main().to_csv(path_csv, index=False)
print('hello')

+ 33
- 33
Data/tables/plan.csv View File

@ -1,33 +1,33 @@
,inter_no,start_hour,start_minute,dura_A1,dura_A2,dura_A3,dura_A4,dura_A5,dura_A6,dura_A7,dura_A8,dura_B1,dura_B2,dura_B3,dura_B4,dura_B5,dura_B6,dura_B7,dura_B8,cycle,offset
0,175,00,00,37,39,55,29,0,0,0,0,37,39,25,59,0,0,0,0,160,57
1,175,07,00,40,42,55,33,0,0,0,0,40,42,29,59,0,0,0,0,170,40
2,175,09,00,43,45,55,37,0,0,0,0,43,45,33,59,0,0,0,0,180,28
3,175,18,30,46,48,55,41,0,0,0,0,46,48,37,59,0,0,0,0,190,18
4,176,00,00,37,73,40,0,0,0,0,0,37,73,40,0,0,0,0,0,150,131
5,176,07,00,37,93,40,0,0,0,0,0,37,93,40,0,0,0,0,0,170,153
6,176,09,00,37,103,40,0,0,0,0,0,37,103,40,0,0,0,0,0,180,169
7,176,18,30,37,113,40,0,0,0,0,0,37,113,40,0,0,0,0,0,190,185
8,177,00,00,36,20,68,26,0,0,0,0,36,20,68,26,0,0,0,0,150,35
9,177,07,00,40,25,71,34,0,0,0,0,40,25,71,34,0,0,0,0,170,33
10,177,09,00,43,27,70,40,0,0,0,0,43,27,70,40,0,0,0,0,180,41
11,177,18,30,45,32,77,36,0,0,0,0,45,32,77,36,0,0,0,0,190,49
12,178,00,00,38,39,40,23,0,0,0,0,38,39,40,23,0,0,0,0,140,50
13,178,07,00,38,39,42,41,0,0,0,0,38,39,62,21,0,0,0,0,160,90
14,178,09,00,38,39,43,50,0,0,0,0,38,39,71,22,0,0,0,0,170,80
15,178,18,30,38,39,44,59,0,0,0,0,38,39,80,23,0,0,0,0,180,75
16,201,00,00,24,24,17,58,17,0,0,0,24,24,17,58,17,0,0,0,140,133
17,201,07,00,30,36,18,58,18,0,0,0,30,36,18,58,18,0,0,0,160,132
18,201,09,00,33,36,25,58,18,0,0,0,33,36,25,58,18,0,0,0,170,134
19,201,18,30,36,50,18,58,18,0,0,0,36,50,18,58,18,0,0,0,180,137
20,202,00,00,39,101,0,0,0,0,0,0,39,101,0,0,0,0,0,0,140,103
21,202,07,00,46,114,0,0,0,0,0,0,46,114,0,0,0,0,0,0,160,103
22,202,09,00,46,114,0,0,0,0,0,0,46,114,0,0,0,0,0,0,160,103
23,202,18,30,48,122,0,0,0,0,0,0,48,122,0,0,0,0,0,0,170,103
24,206,00,00,33,35,26,26,0,0,0,0,33,35,26,26,0,0,0,0,120,10
25,206,07,00,44,44,26,26,0,0,0,0,44,44,26,26,0,0,0,0,140,7
26,206,09,00,45,53,26,26,0,0,0,0,45,53,26,26,0,0,0,0,150,17
27,206,18,30,46,62,26,26,0,0,0,0,46,62,26,26,0,0,0,0,160,10
28,210,00,00,43,29,56,22,0,0,0,0,24,48,56,22,0,0,0,0,150,115
29,210,07,00,43,39,65,23,0,0,0,0,24,58,65,23,0,0,0,0,170,131
30,210,09,00,43,43,70,24,0,0,0,0,28,58,70,24,0,0,0,0,180,137
31,210,18,30,43,47,75,25,0,0,0,0,24,66,75,25,0,0,0,0,190,143
,inter_no,start_hour,start_minute,dura_A1,dura_A2,dura_A3,dura_A4,dura_A5,dura_A6,dura_A7,dura_A8,dura_B1,dura_B2,dura_B3,dura_B4,dura_B5,dura_B6,dura_B7,dura_B8,cycle,offset,yellow_A1,yellow_B1,yellow_A2,yellow_B2,yellow_A3,yellow_B3,yellow_A4,yellow_B4,yellow_A5,yellow_B5,yellow_A6,yellow_B6,yellow_A7,yellow_B7,yellow_A8,yellow_B8,red_A1,red_B1,red_A2,red_B2,red_A3,red_B3,red_A4,red_B4,red_A5,red_B5,red_A6,red_B6,red_A7,red_B7,red_A8,red_B8
0,175,00,00,37,39,55,29,0,0,0,0,37,39,25,59,0,0,0,0,160,57,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1
1,175,07,00,40,42,55,33,0,0,0,0,40,42,29,59,0,0,0,0,170,40,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1
2,175,09,00,43,45,55,37,0,0,0,0,43,45,33,59,0,0,0,0,180,28,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1
3,175,18,30,46,48,55,41,0,0,0,0,46,48,37,59,0,0,0,0,190,18,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1
4,176,00,00,37,73,40,0,0,0,0,0,37,73,40,0,0,0,0,0,150,131,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1
5,176,07,00,37,93,40,0,0,0,0,0,37,93,40,0,0,0,0,0,170,153,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1
6,176,09,00,37,103,40,0,0,0,0,0,37,103,40,0,0,0,0,0,180,169,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1
7,176,18,30,37,113,40,0,0,0,0,0,37,113,40,0,0,0,0,0,190,185,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1
8,177,00,00,36,20,68,26,0,0,0,0,36,20,68,26,0,0,0,0,150,35,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1
9,177,07,00,40,25,71,34,0,0,0,0,40,25,71,34,0,0,0,0,170,33,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1
10,177,09,00,43,27,70,40,0,0,0,0,43,27,70,40,0,0,0,0,180,41,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1
11,177,18,30,45,32,77,36,0,0,0,0,45,32,77,36,0,0,0,0,190,49,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1
12,178,00,00,38,39,40,23,0,0,0,0,38,39,40,23,0,0,0,0,140,50,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2
13,178,07,00,38,39,42,41,0,0,0,0,38,39,62,21,0,0,0,0,160,90,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2
14,178,09,00,38,39,43,50,0,0,0,0,38,39,71,22,0,0,0,0,170,80,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2
15,178,18,30,38,39,44,59,0,0,0,0,38,39,80,23,0,0,0,0,180,75,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2
16,201,00,00,24,24,17,58,17,0,0,0,24,24,17,58,17,0,0,0,140,133,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2
17,201,07,00,30,36,18,58,18,0,0,0,30,36,18,58,18,0,0,0,160,132,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2
18,201,09,00,33,36,25,58,18,0,0,0,33,36,25,58,18,0,0,0,170,134,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2
19,201,18,30,36,50,18,58,18,0,0,0,36,50,18,58,18,0,0,0,180,137,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2
20,202,00,00,39,101,0,0,0,0,0,0,39,101,0,0,0,0,0,0,140,103,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1
21,202,07,00,46,114,0,0,0,0,0,0,46,114,0,0,0,0,0,0,160,103,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1
22,202,09,00,46,114,0,0,0,0,0,0,46,114,0,0,0,0,0,0,160,103,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1
23,202,18,30,48,122,0,0,0,0,0,0,48,122,0,0,0,0,0,0,170,103,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1
24,206,00,00,33,35,26,26,0,0,0,0,33,35,26,26,0,0,0,0,120,10,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1
25,206,07,00,44,44,26,26,0,0,0,0,44,44,26,26,0,0,0,0,140,7,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1
26,206,09,00,45,53,26,26,0,0,0,0,45,53,26,26,0,0,0,0,150,17,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1
27,206,18,30,46,62,26,26,0,0,0,0,46,62,26,26,0,0,0,0,160,10,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1
28,210,00,00,43,29,56,22,0,0,0,0,24,48,56,22,0,0,0,0,150,115,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2
29,210,07,00,43,39,65,23,0,0,0,0,24,58,65,23,0,0,0,0,170,131,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2
30,210,09,00,43,43,70,24,0,0,0,0,28,58,70,24,0,0,0,0,180,137,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2
31,210,18,30,43,47,75,25,0,0,0,0,24,66,75,25,0,0,0,0,190,143,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2

+ 1346
- 105
Data/tables/raw_tables/0116_make_sample_table.ipynb
File diff suppressed because it is too large
View File


+ 8
- 0
Documents/0116_header_unix.txt View File

@ -0,0 +1,8 @@
김선중 대리 동부ICT에서 교차로 주기정보(주기별 현시별 녹색시간) 전송시 header에 시간정보가 있어서 해당 정보를
주기의 종료시간으로 활용해도 되는지 문의하였고 아래내용은 회신받은 내용입니다. 참고하세요
1) 메세지 header에서 제공하는 time은 신호제어서버의 정보 제공 시점의 시각입니다.
2) 신호제어기에서 주기가 종료되면, 운영했던 SPLIT을 신호제어서버로 전송하고
신호제어서버는 데이터를 큐에 저장한 다음 1~2초 간격으로 묶어서 외부 서버에 제공할 예정입니다.
3) 이런 경우 외부 서버에 SPLIT 정보 전송 지연이 최소 1~2초로 예상됩니다.
4) 따라서 요청을 고려하여 전송 간격을 1초로 하면, 전송 지연을 최소화 할 수 있습니다.
김선중

BIN
Documents/동부ICT/교통신호제어센터의 교차로 신호정보 제공 방안_20240108_검토의견.hwpx View File


+ 255
- 0
Documents/동부ICT/교통신호제어센터의 교차로 신호정보 제공 방안_20240108_검토의견.pdf View File

@ -0,0 +1,255 @@
☐ 교통신호제어센터의 교차로 신호정보 제공 방안
1. 개요
1) 본 문서는 성남시 신호제어서버에서 외부시스템에 신호정보 제공을 위한 인터페이
스를 정의한다.
2) 신호정보제공 대상 외부시스템은 다음과 같다
- 디지털 트윈 서버
- 긴급차량관제 서버
- 스마트교차로 서버
- ITS 센터
3) 연계 구성
2. 통신 방식
1) 통신 방식 : TCP 소켓 통신
[보안정책상 UDP 소켓으로 변경여지 있습니다....]
Server 측 Client 측 포트 규격
교통신호제어센터 외부시스템 7072 (TBD) TCP/IP
2) Byte Ordering : Big-Endian
- 최상위 바이트(MSB)를 먼저 보내고, 최하위 바이트(LSB)는 맨나중에 보냄
3) 데이터 형식 : Byte 형식
4) 문자 인코딩 : UTF-8
5) 포트번호 : 7072
3. 프레임 구조
1) 본 시스템의 프레임은 “HEADER + DATA“로 구성하며, ”HEADER“의 구성과
”COMMAND“ 목록은 다음과 같다.
▪ HEADER 구성 (10 BYTES)
항목 설명 데이터크기 데이터 유형
STX1 BYTE
STX2 통신프레임의 시작 부호 1 (0x7E) 1 BYTE
SEQUENCE BYTE
TIME 통신프레임의 시작 부호 2 (0x7E) 1 BYTE
COMMAND BYTE
DATA LENGTH 순차번호 (0 ~ 255) 1 BYTE
현재시각 (32BIT) 4
명령코드 1
데이터 프레임의 BYTE 길이 2
▪ COMMAND 목록
번호 COMMAND 설명 송수신 방향 비고
신호서버 → 외부서버
1 0xF2 교차로 신호운영현황 전송 신호서버 ← 외부서버
신호서버 → 외부서버
2 0xF3 교차로 신호운영현황 응답 (ACK) 신호서버 ← 외부서버
신호서버 → 외부서버
3 0xF4 교차로 주기정보 전송 신호서버 ← 외부서버
4 0xF5 교차로 주기정보 응답 (ACK)
5 0xF6 교차로 DB 전송
6 0xF7 교차로 DB 응답 (ACK)
4. 메시지 상세 구조
1) 교차로 신호운영현황 정보전송
▪ 1초 단위의 교차로 신호운영현황 정보
▪ 정보전송 “교차로 시작번호”부터 N개의 교차로를 연속적으로 전송한다
BYTE 항목 BIT 설명
1 교차로
2 16 BIT 정보전송 교차로 시작번호 (1 – 9999)
3 번호
4 현시 75 RING A의 PHASE (0 ∼ 7)
코드 40 RING A의 STEP (0 ∼ 31)
5 75 RING B의 PHASE (0 ∼ 7)
제어기 40 RING B의 STEP (0 ∼ 31)
6 운영상태 센터 통신 FAIL 상태 1 : FAIL, 0 : 정상
7
7 제어기 6 운용 맵번호 0 : 일반제, 1~5 : 시차제, 6 : 전용맵
8 상태 5
9 4 등기종류 1 : 4색등, 0 : 3색등
10 3
11 교통신호기 운영모드 0 : SCU 고정주기 모드
- 2 1 : 감응하지 않는 OFFLINE 제어모드
18 RING 운영방식 2 : 감응되는 OFFLINE 제어모드
19 1 현시유지 4 : 감응되는 온라인 제어모드
- 우선신호 5 : 감응하지 않는 온라인 제어모드
26 0 전이
7 감응 1 : DUAL-RING, 0 : SINGLE-RING
6 소등 1 : ON, 0 : OFF
5 점멸 1 : 서비스 중, 0 : OFF
4 수동 1 : 전이 중, 0 : OFF
3 주기 COUNT 1 : 감응, 0 : 정상
2 현 주기 1 : 소등, 0 : 정상
1 연동 1 : 점멸, 0 : 정상
0 예비 1 : 수동, 0 : 정상
- 0 ~ 255 초
- 0 ~ 255 초
- 실제 계측 OFFSET
-
교차로 시작번호+1 신호운영정보 (8 Bytes)
교차로 시작번호+2 신호운영정보 (8 Bytes)
...
... 교차로 시작번호+N 신호운영정보 (8 Bytes)
-> A링, B링의 이동류번호 제공 필요. 시차제가 적용될 경우 교차로 DB정보를 통해
서는 파악이 불가능하며, 신호운영현황을 통해 제공되는 이동류번호로만 파악이
가능함
2) 교차로 주기정보 : 주기 종료 후 Split 정보 제공
▪ 주기 종료 후 Ring-A, Ring-B의 운영한 현시정보를 전송한다.
▪ 정보전송은 N개의 교차로 정보를 연속하여 전송이 가능하다
BYTE 항목 BIT 설명
교차로 번호
1 16 BIT 정보전송 교차로번호 (1 – 9999)
2
3 RING-A 운영시간 8 Bytes PHASE 1 – 8
-
10 RING-B 운영시간 8 Bytes PHASE 1 – 8
11
-
18
2번째 교차로 번호/ Ring-A / RING-B 운영시간 (18 Bytes)
3번째 교차로 번호/ Ring-A / RING-B 운영시간 (18 Bytes)
4번째 교차로 번호/ Ring-A / RING-B 운영시간 (18 Bytes)
....
3) 교차로 DB 정보 : 교차로 DB 변경시 제공 (JSON 표기)
WEEK PLAN JSON 표기 WEEK PLAN data 설명
{ data : 7 plan_no
“lcid” : number, plan_no = 1 ~ 10
“type” : “weekplan”,
“data” : number[],
}
DAYPLAN JSON 표기 DAYPLAN data 설명
{ plan_no = 1 ~ 10
“lcid” : number, [hour, min, cycle, offset, split[16]] * 16
“type” : “dayplan”,
“plan” : {
“plan_no”: number,
“data”: number[],
}[]
}
HOLIDAY PLAN JSON 표기 HOLIDAY PLAN data 설명
{
“lcid”: number, [month, day, plan_no] * 30
“type”: “holidayplan”, plan_no = 1 ~ 10
“data”: number[],
}
SIGNAL MAP JSON 표기 SIGNAL MAP data 설명
{
“lcid”: number, map_no = 1 - 6
“type”: “signal_map”, [output[16], min, max, eop] * 32 step
“data”: {
“map_no” : number,
“a_ring” : number[],
“b_ring” : number[],
}[],
}
이동류 번호, 방위각 JSON 표기 기반정보 구성 data 설명
{
“lcid”: number, map_no = 1 - 6
“type”: “geo_map”, [direction(이동류 번호), angle(방위각)] * 8현시
“data”: {
“map_no” : number,
“a_ring” : number[],
“b_ring” : number[],
}[],
}
→ dayplan data에 yellow time, red time, 주현시 정보 추가 필요
① 교차로 WEEK PLAN
② 교차로 DAY PLAN
③ 교차로 HOLIDAY PLAN
④ 시그널맵 (Ring-A , Ring-B)
⑤ 교차로 기반정보 구성 (이동류번호, 방위각)
RING 현시 1 현시 2 현시 3 현시 4 현시 5 현시 6 현시 7 현시 8
이동류번호,
A-ring
방위각
이동류번호,
B-ring
방위각
-> 방위각 정보는 진입, 진출 모두 제공 필요
⑥ etc.
-> 교차로 ID, 이름 및 위-경도 필요. sumo 네트워크 노드와 교차로 ID를 매핑하기
위해서 필요
▪ 이동류 번호 (1 byte)
이동류 이동류 이동류 이동류 이동류 이동류
설명
설명 설명
번호 방향
번호 방향 번호 방향
1 좌회전 (동 → 남) 9 좌회전 (북동 → 남동) 17 ˙ 보행신호
2 직진 (서 → 동) 10 직진 (남서 → 북동) 18 ˙ 신호 없음
3 좌회전 (남 → 서) 11 좌회전 (남동 → 남서) 21 ˙ 신호우회전
4 직진 (북 → 남) 12 직진 (북서 → 남동)
5 좌회전 (서 → 북) 13 좌회전 (남서 → 북서)
6 직진 (동 → 서) 14 직진 (북동 → 남서)
7 좌회전 (북 → 동) 15 좌회전 (북서 → 북동)
8 직진 (남 → 북) 16 직진 (남동 → 북서)
▪ 방위각 (2 bytes) : 0 ~ 360도
▪ 화살표 좌표 (24 bytes)
항목 설명
이동류 위도 DD.DDDDDD
(화살표 시작 좌표) 경도 DDD.DDDDDD
위도 DD.DDDDDD
이동류 경도 DDD.DDDDDD
(화살표 중간점 좌표) 위도 DD.DDDDDD
경도 DDD.DDDDDD
이동류
(화살표 종료점 좌표)

BIN
Documents/동부ICT/교통신호제어센터의 교차로 신호정보 제공 방안_20240108_수정_김선중.hwpx View File


BIN
Documents/동부ICT/교통신호제어센터의 교차로 신호정보 제공 방안_20240111.hwpx View File


Documents/교통신호제어센터의 교차로 신호정보 제공 방안_20240111.pdf → Documents/동부ICT/교통신호제어센터의 교차로 신호정보 제공 방안_20240111.pdf View File


BIN
Documents/동부ICT/교통신호제어센터의 교차로 신호정보 제공 방안_20240220.hwpx View File


+ 322
- 0
Documents/동부ICT/교통신호제어센터의 교차로 신호정보 제공 방안_20240220.pdf View File

@ -0,0 +1,322 @@
☐ 교통신호제어센터의 교차로 신호정보 제공 방안
1. 개요
1) 본 문서는 성남시 신호제어서버에서 ITS서버에 신호정보 제공을 위한 인터페이스
를 정의한다.
2) 연계 구성
2. 통신 방식
1) 통신 방식 : UDP 소켓 통신
Server 측 Client 측 포트 규격
교통신호제어센터 외부시스템 7072 (TBD) UDP
2) Byte Ordering : Big-Endian
- 최상위 바이트(MSB)를 먼저 보내고, 최하위 바이트(LSB)는 맨나중에 보냄
3) 데이터 형식 : Byte 형식
4) 문자 인코딩 : UTF-8
5) 포트번호 : 7072
3. 프레임 구조
1) 본 시스템의 프레임은 “HEADER + DATA“로 구성하며, ”HEADER“의 구성과
”COMMAND“ 목록은 다음과 같다.
▪ HEADER 구성 (10 BYTES)
항목 설명 데이터크기 데이터 유형
STX1 BYTE
STX2 통신프레임의 시작 부호 1 (0x7E) 1 BYTE
SEQUENCE BYTE
TIME 통신프레임의 시작 부호 2 (0x7E) 1 BYTE
COMMAND BYTE
DATA LENGTH 순차번호 (0 ~ 255) 1 BYTE
현재시각 (32BIT) 4
명령코드 1
데이터 프레임의 BYTE 길이 2
▪ COMMAND 목록
번호 COMMAND 설명 송수신 방향 비고
예비
1 0xF0 교차로 신호운영현황 전송-1 신호서버 → 외부서버 예비
교차로 신호운영현황 응답 (ACK) 신호서버 ← 외부서버
2 0xF1 신호서버 → 외부서버 예비
교차로 신호운영현황 전송-2 신호서버 ← 외부서버
3 0xF2 교차로 신호운영현황 응답 (ACK) 신호서버 → 외부서버
신호서버 ← 외부서버
4 0xF3 교차로 주기정보 전송 신호서버 → 외부서버
교차로 주기정보 응답 (ACK) 신호서버 ← 외부서버
5 0xF4 신호서버 ← 외부서버
교차로 DB 전송
6 0xF5 교차로 DB 응답 (ACK)
7 0xF6 신호정보제공 요청
8 0xF7
9 0xF9
▪ 전체 메시지 구성 (HEADER + DATA)
HEADER DATA
DATA
STX1 STX2 SEQ. TIME COMMAND LENGTH [Length] Bytes
1 byte 1 byte 1 byte 2 byte
1 byte 4 byte
4. 데이터 상세 구조
1) 교차로 신호운영현황 정보 전송-1
▪ 1초 단위로 교차로 신호운영현황을 최소 정보만 요약하여 전송한다.
▪ 전체 교차로를 한번에 전송한다
예) 800 (교차로 수) x 3 bytes = 2400 bytes 전송
BYTE 항목 BIT 설명
1 현시
2 코드 75 RING A의 PHASE (0 ∼ 7)
40
3 제어기 75 RING A의 이동류번호 (1 ∼ 21)
운영상태 40
4 RING B의 PHASE (0 ∼ 7)
- 7
6 6 RING B의 이동류번호 (1 ∼ 21)
7 5
- 4 제어기 통신상태 1 : 통신 FAIL, 0 : 정상
9 3
2 모순 상태 1 : 모순, 0 : 정상
1 소등 상태 1 : 소등, 0 : 정상
0 점멸 상태 1 : 점멸, 0 : 정상
수동 상태 1 : 수동, 0 : 정상
교통신호기 운영모드 0 : SCU 고정주기 모드
1 : 감응하지 않는 OFFLINE 제어모드
2 : 감응되는 OFFLINE 제어모드
4 : 감응되는 온라인 제어모드
5 : 감응하지 않는 온라인 제어모드
2번 교차로 신호운영정보 (3 Bytes)
2번 교차로 신호운영정보 (3 Bytes)
- ...
- N번 교차로 신호운영정보 (3 Bytes)
2) 교차로 신호운영현황 정보 전송-2
▪ 1초 단위의 교차로 신호운영현황 정보
▪ 정보전송 “교차로 시작번호”부터 N개의 교차로를 연속적으로 전송한다
BYTE 항목 BIT 설명
1
2 교차로 16 BIT 정보전송 교차로 시작번호 (1 – 9999)
3 번호
4 현시 75 RING A의 PHASE (0 ∼ 7) 1 : 통신 FAIL, 0 : 정상
코드 40 RING A의 STEP (0 ∼ 31)
5 75 RING B의 PHASE (0 ∼ 7)
제어기 40 RING B의 STEP (0 ∼ 31)
6 운영상태 제어기 통신상태
7
7 제어기 6 운용 맵번호 0 : 일반제, 1~5 : 시차제, 6 : 전용맵
8 상태 5
9 4 교차로 연등 0 : 일반교차로, 1 : 연등교차로
10 3
11 교통신호기 운영모드 0 : SCU 고정주기 모드
12 2 1 : 감응하지 않는 OFFLINE 제어모드
- POLICE PANEL 수동진행 SW 2 : 감응되는 OFFLINE 제어모드
20 1 POLICE PANEL 수동 SW 4 : 감응되는 온라인 제어모드
21 POLICE PANEL 점멸 SW 5 : 감응하지 않는 온라인 제어모드
- 0 POLICE PANEL 소등 SW
29 7 모순 상태 1 : ON, 0 : OFF
6 소등 상태 1 : ON, 0 : OFF
5 점멸 상태 1 : ON, 0 : OFF
4 데이터베이스 상태 1 : ON, 0 : OFF
3 주기 COUNT 1 : 모순, 0 : 정상
2 현 주기 1 : 소등, 0 : 정상
1 연동 1 : 점멸, 0 : 정상
0 A-ring 이동류번호 1 : 이상, 0 : 정상
- B-ring 이동류번호 0 ~ 255 초
- 0 ~ 255 초
- 실제 계측 OFFSET
- 1 – 21 (보행자 포함여부 ?)
- 1 – 21 (보행자 포함여부 ?)
교차로 시작번호+1 신호운영정보 (9 Bytes)
교차로 시작번호+2 신호운영정보 (9 Bytes)
...
... 교차로 시작번호+N 신호운영정보 (9 Bytes)
3) 교차로 주기정보 : 주기 종료 후 Split 정보 제공
▪ 주기 종료 후 Ring-A, Ring-B의 운영한 현시정보를 전송한다.
▪ 정보전송은 N개의 교차로 정보를 연속하여 전송이 가능하다
BYTE 항목 BIT 설명
교차로 번호 16 BIT 정보전송 교차로번호 (1 – 9999)
1
2 RING-A 운영시간 8 Bytes PHASE 1 – 8
3
- RING-B 운영시간 8 Bytes PHASE 1 – 8
10
11
-
18
2번째 교차로 번호/ Ring-A / RING-B 운영시간 (18 Bytes)
3번째 교차로 번호/ Ring-A / RING-B 운영시간 (18 Bytes)
4번째 교차로 번호/ Ring-A / RING-B 운영시간 (18 Bytes)
....
4) 교차로 DB 정보 : 교차로 DB 변경시 제공 (JSON 표기)
① 교차로 WEEK PLAN
∎ JSON 표기
WEEK PLAN JSON 표기 WEEK PLAN data 설명
{ data : 7 plan_no
“lcid” : number, plan_no = 1 ~ 10
“type” : “weekplan”,
“data” : number[],
}
∎ week plan table 정의
② 교차로 DAY PLAN DAYPLAN data 설명
∎ JSON 표기 plan_no = 1 ~ 10
time : [A_flow_no, A_red_time, A_yellow_time, A_min_time,
DAYPLAN JSON 표기
B_flow_no, B_red_time, B_yellow_time, B_min_time]
{ data : [hour, min, cycle, offset, split[16]]
“lcid” : number,
“type” : “dayplan”,
“plan” : {
“plan_no”: number,
“time” : number[],
“data” : number[],
}[]
}
∎ FLOW/RED/YELLOW
현시 이동류번호 A-ring yellow_time 이동류번호 B-ring
red_time red_time yellow_time
현시 1
현시 2
현시 3
현시 4
현시 5
현시 6
현시 7
현시 8
∎ DAY PLAN TIME Table
③ 교차로 HOLIDAY PLAN HOLIDAY PLAN data 설명
∎ JSON 표기
[month, day, plan_no] * 30
HOLIDAY PLAN JSON 표기 plan_no = 1 ~ 10
{
“lcid”: number,
“type”: “holidayplan”,
“data”: number[],
}
∎ HOLIDAY Plan Table
④ SIGNAL MAP (Ring-A , Ring-B) SIGNAL MAP data 설명
∎ JSON 표기 map_no = 1 - 6
[output[16], min, max, eop] * 32 step
SIGNAL MAP JSON 표기
{
“lcid”: number,
“type”: “signal_map”,
“data”: {
“map_no” : number,
“a_ring” : number[],
“b_ring” : number[],
}[],
}
∎ SIGNAL MAP Table
⑤ 교차로 기반정보 구성
∎ JSON 표기
교차로 기반정보 구성 JSON 표기 교차로 기반정보 구성 data 설명
`{
“lcid”: number,
“type”: “geo_map”,
“intName”: string, // 교차로명
“intType”: number, // 교차로유형 (0: 주교차로, 1: 연등교차로)
“lcType”: number, // 제어기 유형 (1: 2004년형, 2: 2010 년형, 3: 2023년형)
“lampType”: number, // 등기 유형 (1: 4색등, 2: 3색등)
“mainIntNo”: number, // 연등교차로인 경우 주교차로 번호
“groupNo”: number, // 그룹번호
“nodeNo”: number, // 교차로 노드 ID
“intLat”: number, // 교차로 위도 (ex : 36.123500)
“intLng”: number, // 교차로 경도 (ex : 127.123500)
“ppcType”: number, // PPC 유형 (0 : 설치안됨, 1 : 현장방식, 2 : 중앙제어방식)
“mainP”: number, // 주현시번호 (1 – 8)
“flow”: {
“num”: number, // 이동류 번호
“geoXY: number[], // 화살표 시작점 위도/경도, 중간점 위도/경도, 종료점 위도/경도,
}[]
}
▪ 이동류 번호
이동류 이동류 이동류 이동류 이동류 이동류
설명
설명 설명
번호 방향
번호 방향 번호 방향
1 좌회전 (동 → 남) 9 좌회전 (북동 → 남동) 17 ˙ 보행신호
2 직진 (서 → 동) 10 직진 (남서 → 북동) 18 ˙ 신호 없음
3 좌회전 (남 → 서) 11 좌회전 (남동 → 남서) 21 ˙ 신호우회전
4 직진 (북 → 남) 12 직진 (북서 → 남동)
5 좌회전 (서 → 북) 13 좌회전 (남서 → 북서)
6 직진 (동 → 서) 14 직진 (북동 → 남서)
7 좌회전 (북 → 동) 15 좌회전 (북서 → 북동)
8 직진 (남 → 북) 16 직진 (남동 → 북서)

+ 341
- 341
Results/sn_1704416700.add.xml View File

@ -1,8 +1,8 @@
<additional>
<tlLogic id="c30" type="static" programID="c30_prog" offset="-50">
<phase duration="33" state="rrrrrr"/>
<phase duration="4" state="rrrrrr"/>
<phase duration="1" state="rrrrrr"/>
<phase duration="33" state="gggggg"/>
<phase duration="4" state="gggggg"/>
<phase duration="1" state="gggggg"/>
<phase duration="34" state="GGGGGG"/>
<phase duration="4" state="GGGGGG"/>
<phase duration="1" state="GGGGGG"/>
@ -10,11 +10,11 @@
<phase duration="4" state="GGGGGG"/>
<phase duration="1" state="GGGGGG"/>
<phase duration="17" state="GGGGGG"/>
<phase duration="4" state="yyyyyy"/>
<phase duration="1" state="rrrrrr"/>
<phase duration="33" state="rrrrrr"/>
<phase duration="4" state="rrrrrr"/>
<phase duration="1" state="rrrrrr"/>
<phase duration="4" state="GGGGGG"/>
<phase duration="1" state="GGGGGG"/>
<phase duration="33" state="gggggg"/>
<phase duration="4" state="gggggg"/>
<phase duration="1" state="gggggg"/>
<phase duration="34" state="GGGGGG"/>
<phase duration="4" state="GGGGGG"/>
<phase duration="1" state="GGGGGG"/>
@ -22,11 +22,11 @@
<phase duration="4" state="GGGGGG"/>
<phase duration="1" state="GGGGGG"/>
<phase duration="17" state="GGGGGG"/>
<phase duration="4" state="yyyyyy"/>
<phase duration="1" state="rrrrrr"/>
<phase duration="33" state="rrrrrr"/>
<phase duration="4" state="rrrrrr"/>
<phase duration="1" state="rrrrrr"/>
<phase duration="4" state="GGGGGG"/>
<phase duration="1" state="GGGGGG"/>
<phase duration="33" state="gggggg"/>
<phase duration="4" state="gggggg"/>
<phase duration="1" state="gggggg"/>
<phase duration="34" state="GGGGGG"/>
<phase duration="4" state="GGGGGG"/>
<phase duration="1" state="GGGGGG"/>
@ -34,11 +34,11 @@
<phase duration="4" state="GGGGGG"/>
<phase duration="1" state="GGGGGG"/>
<phase duration="17" state="GGGGGG"/>
<phase duration="4" state="yyyyyy"/>
<phase duration="1" state="rrrrrr"/>
<phase duration="33" state="rrrrrr"/>
<phase duration="4" state="rrrrrr"/>
<phase duration="1" state="rrrrrr"/>
<phase duration="4" state="GGGGGG"/>
<phase duration="1" state="GGGGGG"/>
<phase duration="33" state="gggggg"/>
<phase duration="4" state="gggggg"/>
<phase duration="1" state="gggggg"/>
<phase duration="34" state="GGGGGG"/>
<phase duration="4" state="GGGGGG"/>
<phase duration="1" state="GGGGGG"/>
@ -48,241 +48,241 @@
<phase duration="17" state="GGGGGG"/>
</tlLogic>
<tlLogic id="i0" type="static" programID="i0_prog" offset="-42">
<phase duration="38" state="gGGGgGGGgGGGGGgGG"/>
<phase duration="4" state="gGGGgGGGgGGGGGgGG"/>
<phase duration="1" state="gGGGgGGGgGGGGGgGG"/>
<phase duration="40" state="gGGGgGGGgGGGGGgGG"/>
<phase duration="4" state="gGGGgGGGgGGGGGgGG"/>
<phase duration="1" state="gGGGgGGGgGGGGGgGG"/>
<phase duration="28" state="gGGGgGGGgGGGGGgGG"/>
<phase duration="4" state="gGGGgGGGgGGGGGgGG"/>
<phase duration="1" state="gGGGgGGGgGGGGGgGG"/>
<phase duration="17" state="gGGGgGGGgGGGGGgGG"/>
<phase duration="4" state="gGGGgGGGgGGGGGgGG"/>
<phase duration="1" state="gGGGgGGGgGGGGGgGG"/>
<phase duration="32" state="gGGGgGGGgGGGGGgGG"/>
<phase duration="4" state="gGGGgGGGgGGGGGgGG"/>
<phase duration="1" state="gGGGgGGGgGGGGGgGG"/>
<phase duration="38" state="gGGGgGGGgGGGGGgGG"/>
<phase duration="4" state="gGGGgGGGgGGGGGgGG"/>
<phase duration="1" state="gGGGgGGGgGGGGGgGG"/>
<phase duration="40" state="gGGGgGGGgGGGGGgGG"/>
<phase duration="4" state="gGGGgGGGgGGGGGgGG"/>
<phase duration="1" state="gGGGgGGGgGGGGGgGG"/>
<phase duration="28" state="gGGGgGGGgGGGGGgGG"/>
<phase duration="4" state="gGGGgGGGgGGGGGgGG"/>
<phase duration="1" state="gGGGgGGGgGGGGGgGG"/>
<phase duration="17" state="gGGGgGGGgGGGGGgGG"/>
<phase duration="4" state="gGGGgGGGgGGGGGgGG"/>
<phase duration="1" state="gGGGgGGGgGGGGGgGG"/>
<phase duration="32" state="gGGGgGGGgGGGGGgGG"/>
<phase duration="4" state="gGGGgGGGgGGGGGgGG"/>
<phase duration="1" state="gGGGgGGGgGGGGGgGG"/>
<phase duration="38" state="gGGGgGGGgGGGGGgGG"/>
<phase duration="4" state="gGGGgGGGgGGGGGgGG"/>
<phase duration="1" state="gGGGgGGGgGGGGGgGG"/>
<phase duration="40" state="gGGGgGGGgGGGGGgGG"/>
<phase duration="4" state="gGGGgGGGgGGGGGgGG"/>
<phase duration="1" state="gGGGgGGGgGGGGGgGG"/>
<phase duration="28" state="gGGGgGGGgGGGGGgGG"/>
<phase duration="4" state="gGGGgGGGgGGGGGgGG"/>
<phase duration="1" state="gGGGgGGGgGGGGGgGG"/>
<phase duration="17" state="gGGGgGGGgGGGGGgGG"/>
<phase duration="4" state="gGGGgGGGgGGGGGgGG"/>
<phase duration="1" state="gGGGgGGGgGGGGGgGG"/>
<phase duration="32" state="gGGGgGGGgGGGGGgGG"/>
<phase duration="38" state="gGGrgrrrgGGGGrgrr"/>
<phase duration="4" state="gyyrgrrrgyyyyrgrr"/>
<phase duration="1" state="grrrgrrrgrrrrrgrr"/>
<phase duration="40" state="grrGgrrrgrrrrGgrr"/>
<phase duration="4" state="grrygrrrgrrrrygrr"/>
<phase duration="1" state="grrrgrrrgrrrrrgrr"/>
<phase duration="28" state="grrrgGGGgrrrrrgrr"/>
<phase duration="4" state="grrrgGGygrrrrrgrr"/>
<phase duration="1" state="grrrgGGrgrrrrrgrr"/>
<phase duration="17" state="grrrgGGrgrrrrrgGr"/>
<phase duration="4" state="grrrgyyrgrrrrrgGr"/>
<phase duration="1" state="grrrgrrrgrrrrrgGr"/>
<phase duration="32" state="grrrgrrrgrrrrrgGG"/>
<phase duration="4" state="grrrgrrrgrrrrrgyy"/>
<phase duration="1" state="grrrgrrrgrrrrrgrr"/>
<phase duration="38" state="gGGrgrrrgGGGGrgrr"/>
<phase duration="4" state="gyyrgrrrgyyyyrgrr"/>
<phase duration="1" state="grrrgrrrgrrrrrgrr"/>
<phase duration="40" state="grrGgrrrgrrrrGgrr"/>
<phase duration="4" state="grrygrrrgrrrrygrr"/>
<phase duration="1" state="grrrgrrrgrrrrrgrr"/>
<phase duration="28" state="grrrgGGGgrrrrrgrr"/>
<phase duration="4" state="grrrgGGygrrrrrgrr"/>
<phase duration="1" state="grrrgGGrgrrrrrgrr"/>
<phase duration="17" state="grrrgGGrgrrrrrgGr"/>
<phase duration="4" state="grrrgyyrgrrrrrgGr"/>
<phase duration="1" state="grrrgrrrgrrrrrgGr"/>
<phase duration="32" state="grrrgrrrgrrrrrgGG"/>
<phase duration="4" state="grrrgrrrgrrrrrgyy"/>
<phase duration="1" state="grrrgrrrgrrrrrgrr"/>
<phase duration="38" state="gGGrgrrrgGGGGrgrr"/>
<phase duration="4" state="gyyrgrrrgyyyyrgrr"/>
<phase duration="1" state="grrrgrrrgrrrrrgrr"/>
<phase duration="40" state="grrGgrrrgrrrrGgrr"/>
<phase duration="4" state="grrygrrrgrrrrygrr"/>
<phase duration="1" state="grrrgrrrgrrrrrgrr"/>
<phase duration="28" state="grrrgGGGgrrrrrgrr"/>
<phase duration="4" state="grrrgGGygrrrrrgrr"/>
<phase duration="1" state="grrrgGGrgrrrrrgrr"/>
<phase duration="17" state="grrrgGGrgrrrrrgGr"/>
<phase duration="4" state="grrrgyyrgrrrrrgGr"/>
<phase duration="1" state="grrrgrrrgrrrrrgGr"/>
<phase duration="32" state="grrrgrrrgrrrrrgGG"/>
</tlLogic>
<tlLogic id="i1" type="static" programID="i1_prog" offset="-39">
<phase duration="32" state="gGGGGGGgGG"/>
<phase duration="4" state="gGGGGGGgGG"/>
<phase duration="1" state="gGGGGGGgGG"/>
<phase duration="98" state="gGGGGGGgGG"/>
<phase duration="4" state="gGGGGGGgGG"/>
<phase duration="1" state="gGGGGGGgGG"/>
<phase duration="35" state="gGGGGGGgGG"/>
<phase duration="4" state="gGGGGGGgGG"/>
<phase duration="1" state="gGGGGGGgGG"/>
<phase duration="32" state="gGGGGGGgGG"/>
<phase duration="4" state="gGGGGGGgGG"/>
<phase duration="1" state="gGGGGGGgGG"/>
<phase duration="98" state="gGGGGGGgGG"/>
<phase duration="4" state="gGGGGGGgGG"/>
<phase duration="1" state="gGGGGGGgGG"/>
<phase duration="35" state="gGGGGGGgGG"/>
<phase duration="4" state="gGGGGGGgGG"/>
<phase duration="1" state="gGGGGGGgGG"/>
<phase duration="32" state="gGGGGGGgGG"/>
<phase duration="4" state="gGGGGGGgGG"/>
<phase duration="1" state="gGGGGGGgGG"/>
<phase duration="98" state="gGGGGGGgGG"/>
<phase duration="4" state="gGGGGGGgGG"/>
<phase duration="1" state="gGGGGGGgGG"/>
<phase duration="35" state="gGGGGGGgGG"/>
<phase duration="4" state="gGGGGGGgGG"/>
<phase duration="1" state="gGGGGGGgGG"/>
<phase duration="32" state="gGGGGGGgGG"/>
<phase duration="4" state="gGGGGGGgGG"/>
<phase duration="1" state="gGGGGGGgGG"/>
<phase duration="98" state="gGGGGGGgGG"/>
<phase duration="4" state="gGGGGGGgGG"/>
<phase duration="1" state="gGGGGGGgGG"/>
<phase duration="35" state="gGGGGGGgGG"/>
<phase duration="32" state="gGGGGGrgrr"/>
<phase duration="4" state="gyyGGGrgrr"/>
<phase duration="1" state="grrGGGrgrr"/>
<phase duration="98" state="grrGGGGgrr"/>
<phase duration="4" state="grryyyygrr"/>
<phase duration="1" state="grrrrrrgrr"/>
<phase duration="35" state="grrrrrrgGG"/>
<phase duration="4" state="grrrrrrgyy"/>
<phase duration="1" state="grrrrrrgrr"/>
<phase duration="32" state="gGGGGGrgrr"/>
<phase duration="4" state="gyyGGGrgrr"/>
<phase duration="1" state="grrGGGrgrr"/>
<phase duration="98" state="grrGGGGgrr"/>
<phase duration="4" state="grryyyygrr"/>
<phase duration="1" state="grrrrrrgrr"/>
<phase duration="35" state="grrrrrrgGG"/>
<phase duration="4" state="grrrrrrgyy"/>
<phase duration="1" state="grrrrrrgrr"/>
<phase duration="32" state="gGGGGGrgrr"/>
<phase duration="4" state="gyyGGGrgrr"/>
<phase duration="1" state="grrGGGrgrr"/>
<phase duration="98" state="grrGGGGgrr"/>
<phase duration="4" state="grryyyygrr"/>
<phase duration="1" state="grrrrrrgrr"/>
<phase duration="35" state="grrrrrrgGG"/>
<phase duration="4" state="grrrrrrgyy"/>
<phase duration="1" state="grrrrrrgrr"/>
<phase duration="32" state="gGGGGGrgrr"/>
<phase duration="4" state="gyyGGGrgrr"/>
<phase duration="1" state="grrGGGrgrr"/>
<phase duration="98" state="grrGGGGgrr"/>
<phase duration="4" state="grryyyygrr"/>
<phase duration="1" state="grrrrrrgrr"/>
<phase duration="35" state="grrrrrrgGG"/>
</tlLogic>
<tlLogic id="i2" type="static" programID="i2_prog" offset="-60">
<phase duration="38" state="GGggGGG"/>
<phase duration="4" state="GGggGGG"/>
<phase duration="1" state="GGggGGG"/>
<phase duration="22" state="GGggGGG"/>
<phase duration="4" state="yyggyyy"/>
<phase duration="1" state="rrggrrr"/>
<phase duration="65" state="rrggrrr"/>
<phase duration="4" state="rrggrrr"/>
<phase duration="1" state="rrggrrr"/>
<phase duration="35" state="GGggGGG"/>
<phase duration="4" state="GGggGGG"/>
<phase duration="1" state="GGggGGG"/>
<phase duration="38" state="GGggGGG"/>
<phase duration="4" state="GGggGGG"/>
<phase duration="1" state="GGggGGG"/>
<phase duration="22" state="GGggGGG"/>
<phase duration="4" state="yyggyyy"/>
<phase duration="1" state="rrggrrr"/>
<phase duration="65" state="rrggrrr"/>
<phase duration="4" state="rrggrrr"/>
<phase duration="1" state="rrggrrr"/>
<phase duration="35" state="GGggGGG"/>
<phase duration="4" state="GGggGGG"/>
<phase duration="1" state="GGggGGG"/>
<phase duration="38" state="GGggGGG"/>
<phase duration="4" state="GGggGGG"/>
<phase duration="1" state="GGggGGG"/>
<phase duration="22" state="GGggGGG"/>
<phase duration="4" state="yyggyyy"/>
<phase duration="1" state="rrggrrr"/>
<phase duration="65" state="rrggrrr"/>
<phase duration="4" state="rrggrrr"/>
<phase duration="1" state="rrggrrr"/>
<phase duration="35" state="GGggGGG"/>
<phase duration="4" state="GGggGGG"/>
<phase duration="1" state="GGggGGG"/>
<phase duration="38" state="GGggGGG"/>
<phase duration="4" state="GGggGGG"/>
<phase duration="1" state="GGggGGG"/>
<phase duration="22" state="GGggGGG"/>
<phase duration="4" state="yyggyyy"/>
<phase duration="1" state="rrggrrr"/>
<phase duration="65" state="rrggrrr"/>
<phase duration="4" state="rrggrrr"/>
<phase duration="1" state="rrggrrr"/>
<phase duration="35" state="GGggGGG"/>
<phase duration="38" state="GGgrGGG"/>
<phase duration="4" state="yygryyy"/>
<phase duration="1" state="rrgrrrr"/>
<phase duration="22" state="rrgrrrr"/>
<phase duration="4" state="rrgrrrr"/>
<phase duration="1" state="rrgrrrr"/>
<phase duration="65" state="rrgrrrr"/>
<phase duration="4" state="rrgrrrr"/>
<phase duration="1" state="rrgrrrr"/>
<phase duration="35" state="rrgrGGG"/>
<phase duration="4" state="rrgrGGG"/>
<phase duration="1" state="rrgrGGG"/>
<phase duration="38" state="GGgrGGG"/>
<phase duration="4" state="yygryyy"/>
<phase duration="1" state="rrgrrrr"/>
<phase duration="22" state="rrgrrrr"/>
<phase duration="4" state="rrgrrrr"/>
<phase duration="1" state="rrgrrrr"/>
<phase duration="65" state="rrgrrrr"/>
<phase duration="4" state="rrgrrrr"/>
<phase duration="1" state="rrgrrrr"/>
<phase duration="35" state="rrgrGGG"/>
<phase duration="4" state="rrgrGGG"/>
<phase duration="1" state="rrgrGGG"/>
<phase duration="38" state="GGgrGGG"/>
<phase duration="4" state="yygryyy"/>
<phase duration="1" state="rrgrrrr"/>
<phase duration="22" state="rrgrrrr"/>
<phase duration="4" state="rrgrrrr"/>
<phase duration="1" state="rrgrrrr"/>
<phase duration="65" state="rrgrrrr"/>
<phase duration="4" state="rrgrrrr"/>
<phase duration="1" state="rrgrrrr"/>
<phase duration="35" state="rrgrGGG"/>
<phase duration="4" state="rrgrGGG"/>
<phase duration="1" state="rrgrGGG"/>
<phase duration="38" state="GGgrGGG"/>
<phase duration="4" state="yygryyy"/>
<phase duration="1" state="rrgrrrr"/>
<phase duration="22" state="rrgrrrr"/>
<phase duration="4" state="rrgrrrr"/>
<phase duration="1" state="rrgrrrr"/>
<phase duration="65" state="rrgrrrr"/>
<phase duration="4" state="rrgrrrr"/>
<phase duration="1" state="rrgrrrr"/>
<phase duration="35" state="rrgrGGG"/>
</tlLogic>
<tlLogic id="i3" type="static" programID="i3_prog" offset="-50">
<phase duration="33" state="gGGGGgGGGGgGGGGgGGGG"/>
<phase duration="4" state="gGGGGgGGGGgGGGGgGGGG"/>
<phase duration="1" state="gGGGGgGGGGgGGGGgGGGG"/>
<phase duration="34" state="gGGGGgGGGGgGGGGgGGGG"/>
<phase duration="4" state="gGGGGgGGGGgGGGGgGGGG"/>
<phase duration="1" state="gGGGGgGGGGgGGGGgGGGG"/>
<phase duration="38" state="gGGGGgGGGGgGGGGgGGGG"/>
<phase duration="4" state="gGGGGgGGGGgGGGGgGGGG"/>
<phase duration="1" state="gGGGGgGGGGgGGGGgGGGG"/>
<phase duration="17" state="gGGGGgGGGGgGGGGgGGGG"/>
<phase duration="4" state="gGGGGgGGGGgGGGGgGGGG"/>
<phase duration="1" state="gGGGGgGGGGgGGGGgGGGG"/>
<phase duration="33" state="gGGGGgGGGGgGGGGgGGGG"/>
<phase duration="4" state="gGGGGgGGGGgGGGGgGGGG"/>
<phase duration="1" state="gGGGGgGGGGgGGGGgGGGG"/>
<phase duration="34" state="gGGGGgGGGGgGGGGgGGGG"/>
<phase duration="4" state="gGGGGgGGGGgGGGGgGGGG"/>
<phase duration="1" state="gGGGGgGGGGgGGGGgGGGG"/>
<phase duration="38" state="gGGGGgGGGGgGGGGgGGGG"/>
<phase duration="4" state="gGGGGgGGGGgGGGGgGGGG"/>
<phase duration="1" state="gGGGGgGGGGgGGGGgGGGG"/>
<phase duration="17" state="gGGGGgGGGGgGGGGgGGGG"/>
<phase duration="4" state="gGGGGgGGGGgGGGGgGGGG"/>
<phase duration="1" state="gGGGGgGGGGgGGGGgGGGG"/>
<phase duration="33" state="gGGGGgGGGGgGGGGgGGGG"/>
<phase duration="4" state="gGGGGgGGGGgGGGGgGGGG"/>
<phase duration="1" state="gGGGGgGGGGgGGGGgGGGG"/>
<phase duration="34" state="gGGGGgGGGGgGGGGgGGGG"/>
<phase duration="4" state="gGGGGgGGGGgGGGGgGGGG"/>
<phase duration="1" state="gGGGGgGGGGgGGGGgGGGG"/>
<phase duration="38" state="gGGGGgGGGGgGGGGgGGGG"/>
<phase duration="4" state="gGGGGgGGGGgGGGGgGGGG"/>
<phase duration="1" state="gGGGGgGGGGgGGGGgGGGG"/>
<phase duration="17" state="gGGGGgGGGGgGGGGgGGGG"/>
<phase duration="4" state="gGGGGgGGGGgGGGGgGGGG"/>
<phase duration="1" state="gGGGGgGGGGgGGGGgGGGG"/>
<phase duration="33" state="gGGGGgGGGGgGGGGgGGGG"/>
<phase duration="4" state="gGGGGgGGGGgGGGGgGGGG"/>
<phase duration="1" state="gGGGGgGGGGgGGGGgGGGG"/>
<phase duration="34" state="gGGGGgGGGGgGGGGgGGGG"/>
<phase duration="4" state="gGGGGgGGGGgGGGGgGGGG"/>
<phase duration="1" state="gGGGGgGGGGgGGGGgGGGG"/>
<phase duration="38" state="gGGGGgGGGGgGGGGgGGGG"/>
<phase duration="4" state="gGGGGgGGGGgGGGGgGGGG"/>
<phase duration="1" state="gGGGGgGGGGgGGGGgGGGG"/>
<phase duration="17" state="gGGGGgGGGGgGGGGgGGGG"/>
<phase duration="33" state="gGGGrgrrrrgGGGrgrrrr"/>
<phase duration="4" state="gyyyrgrrrrgyyyrgrrrr"/>
<phase duration="1" state="grrrrgrrrrgrrrrgrrrr"/>
<phase duration="34" state="grrrGgrrrrgrrrGgrrrr"/>
<phase duration="4" state="grrrygrrrrgrrrygrrrr"/>
<phase duration="1" state="grrrrgrrrrgrrrrgrrrr"/>
<phase duration="38" state="grrrrgrrrrgrrrrgGGGG"/>
<phase duration="4" state="grrrrgrrrrgrrrrgyyyy"/>
<phase duration="1" state="grrrrgrrrrgrrrrgrrrr"/>
<phase duration="17" state="grrrrgGGGGgrrrrgrrrr"/>
<phase duration="4" state="grrrrgyyyygrrrrgrrrr"/>
<phase duration="1" state="grrrrgrrrrgrrrrgrrrr"/>
<phase duration="33" state="gGGGrgrrrrgGGGrgrrrr"/>
<phase duration="4" state="gyyyrgrrrrgyyyrgrrrr"/>
<phase duration="1" state="grrrrgrrrrgrrrrgrrrr"/>
<phase duration="34" state="grrrGgrrrrgrrrGgrrrr"/>
<phase duration="4" state="grrrygrrrrgrrrygrrrr"/>
<phase duration="1" state="grrrrgrrrrgrrrrgrrrr"/>
<phase duration="38" state="grrrrgrrrrgrrrrgGGGG"/>
<phase duration="4" state="grrrrgrrrrgrrrrgyyyy"/>
<phase duration="1" state="grrrrgrrrrgrrrrgrrrr"/>
<phase duration="17" state="grrrrgGGGGgrrrrgrrrr"/>
<phase duration="4" state="grrrrgyyyygrrrrgrrrr"/>
<phase duration="1" state="grrrrgrrrrgrrrrgrrrr"/>
<phase duration="33" state="gGGGrgrrrrgGGGrgrrrr"/>
<phase duration="4" state="gyyyrgrrrrgyyyrgrrrr"/>
<phase duration="1" state="grrrrgrrrrgrrrrgrrrr"/>
<phase duration="34" state="grrrGgrrrrgrrrGgrrrr"/>
<phase duration="4" state="grrrygrrrrgrrrygrrrr"/>
<phase duration="1" state="grrrrgrrrrgrrrrgrrrr"/>
<phase duration="38" state="grrrrgrrrrgrrrrgGGGG"/>
<phase duration="4" state="grrrrgrrrrgrrrrgyyyy"/>
<phase duration="1" state="grrrrgrrrrgrrrrgrrrr"/>
<phase duration="17" state="grrrrgGGGGgrrrrgrrrr"/>
<phase duration="4" state="grrrrgyyyygrrrrgrrrr"/>
<phase duration="1" state="grrrrgrrrrgrrrrgrrrr"/>
<phase duration="33" state="gGGGrgrrrrgGGGrgrrrr"/>
<phase duration="4" state="gyyyrgrrrrgyyyrgrrrr"/>
<phase duration="1" state="grrrrgrrrrgrrrrgrrrr"/>
<phase duration="34" state="grrrGgrrrrgrrrGgrrrr"/>
<phase duration="4" state="grrrygrrrrgrrrygrrrr"/>
<phase duration="1" state="grrrrgrrrrgrrrrgrrrr"/>
<phase duration="38" state="grrrrgrrrrgrrrrgGGGG"/>
<phase duration="4" state="grrrrgrrrrgrrrrgyyyy"/>
<phase duration="1" state="grrrrgrrrrgrrrrgrrrr"/>
<phase duration="17" state="grrrrgGGGGgrrrrgrrrr"/>
</tlLogic>
<tlLogic id="i6" type="static" programID="i6_prog" offset="-160">
<phase duration="23" state="grrrgGGGrgrrgrrr"/>
<phase duration="4" state="grrrgGGGrgrrgrrr"/>
<phase duration="1" state="grrrgGGGrgrrgrrr"/>
<phase duration="10" state="grrrgGGGrgrrgGGr"/>
<phase duration="4" state="grrrgGGGrgrrgGGr"/>
<phase duration="1" state="grrrgGGGrgrrgGGr"/>
<phase duration="38" state="grrrgGGGrgrrgGGG"/>
<phase duration="4" state="grrrgGGGrgrrgGGG"/>
<phase duration="1" state="grrrgGGGrgrrgGGG"/>
<phase duration="65" state="gGGGgGGGrgrrgGGG"/>
<phase duration="4" state="gGGGgGGGrgrrgGGG"/>
<phase duration="1" state="gGGGgGGGrgrrgGGG"/>
<phase duration="19" state="gGGGgGGGrgGGgGGG"/>
<phase duration="4" state="gGGGgGGGrgGGgGGG"/>
<phase duration="1" state="gGGGgGGGrgGGgGGG"/>
<phase duration="23" state="gGGGgGGGrgGGgGGG"/>
<phase duration="4" state="gGGGgGGGrgGGgGGG"/>
<phase duration="1" state="gGGGgGGGrgGGgGGG"/>
<phase duration="10" state="gGGGgGGGrgGGgGGG"/>
<phase duration="4" state="gGGGgGGGrgGGgGGG"/>
<phase duration="1" state="gGGGgGGGrgGGgGGG"/>
<phase duration="38" state="gGGGgGGGrgGGgGGG"/>
<phase duration="4" state="gGGGgGGGrgGGgGGG"/>
<phase duration="1" state="gGGGgGGGrgGGgGGG"/>
<phase duration="65" state="gGGGgGGGrgGGgGGG"/>
<phase duration="4" state="gGGGgGGGrgGGgGGG"/>
<phase duration="1" state="gGGGgGGGrgGGgGGG"/>
<phase duration="19" state="gGGGgGGGrgGGgGGG"/>
<phase duration="4" state="gGGGgGGGrgGGgGGG"/>
<phase duration="1" state="gGGGgGGGrgGGgGGG"/>
<phase duration="23" state="gGGGgGGGrgGGgGGG"/>
<phase duration="4" state="gGGGgGGGrgGGgGGG"/>
<phase duration="1" state="gGGGgGGGrgGGgGGG"/>
<phase duration="10" state="gGGGgGGGrgGGgGGG"/>
<phase duration="4" state="gGGGgGGGrgGGgGGG"/>
<phase duration="1" state="gGGGgGGGrgGGgGGG"/>
<phase duration="38" state="gGGGgGGGrgGGgGGG"/>
<phase duration="4" state="gGGGgGGGrgGGgGGG"/>
<phase duration="1" state="gGGGgGGGrgGGgGGG"/>
<phase duration="65" state="gGGGgGGGrgGGgGGG"/>
<phase duration="4" state="gGGGgGGGrgGGgGGG"/>
<phase duration="1" state="gGGGgGGGrgGGgGGG"/>
<phase duration="19" state="gGGGgGGGrgGGgGGG"/>
<phase duration="4" state="gGGGgGGGrgGGgGGG"/>
<phase duration="1" state="gGGGgGGGrgGGgGGG"/>
<phase duration="23" state="gGGGgGGGrgGGgGGG"/>
<phase duration="4" state="gGGGgGGGrgGGgGGG"/>
<phase duration="1" state="gGGGgGGGrgGGgGGG"/>
<phase duration="10" state="gGGGgGGGrgGGgGGG"/>
<phase duration="4" state="gGGGgGGGrgGGgGGG"/>
<phase duration="1" state="gGGGgGGGrgGGgGGG"/>
<phase duration="38" state="gGGGgGGGrgGGgGGG"/>
<phase duration="4" state="gGGGgGGGrgGGgGGG"/>
<phase duration="1" state="gGGGgGGGrgGGgGGG"/>
<phase duration="65" state="gGGGgGGGrgGGgGGG"/>
<phase duration="4" state="gGGGgGGGrgGGgGGG"/>
<phase duration="1" state="gGGGgGGGrgGGgGGG"/>
<phase duration="19" state="gGGGgGGGrgGGgGGG"/>
<phase duration="4" state="grrrgyyyrgrrgGGr"/>
<phase duration="1" state="grrrgrrrrgrrgGGr"/>
<phase duration="38" state="grrrgrrrrgrrgGGG"/>
<phase duration="4" state="grrrgrrrrgrrgyyy"/>
<phase duration="1" state="grrrgrrrrgrrgrrr"/>
<phase duration="65" state="gGGGgrrrrgrrgrrr"/>
<phase duration="4" state="gyyygrrrrgrrgrrr"/>
<phase duration="1" state="grrrgrrrrgrrgrrr"/>
<phase duration="19" state="grrrgrrrrgGGgrrr"/>
<phase duration="4" state="grrrgrrrrgyygrrr"/>
<phase duration="1" state="grrrgrrrrgrrgrrr"/>
<phase duration="23" state="grrrgGGGrgrrgrrr"/>
<phase duration="4" state="grrrgGGGrgrrgrrr"/>
<phase duration="1" state="grrrgGGGrgrrgrrr"/>
<phase duration="10" state="grrrgGGGrgrrgGGr"/>
<phase duration="4" state="grrrgyyyrgrrgGGr"/>
<phase duration="1" state="grrrgrrrrgrrgGGr"/>
<phase duration="38" state="grrrgrrrrgrrgGGG"/>
<phase duration="4" state="grrrgrrrrgrrgyyy"/>
<phase duration="1" state="grrrgrrrrgrrgrrr"/>
<phase duration="65" state="gGGGgrrrrgrrgrrr"/>
<phase duration="4" state="gyyygrrrrgrrgrrr"/>
<phase duration="1" state="grrrgrrrrgrrgrrr"/>
<phase duration="19" state="grrrgrrrrgGGgrrr"/>
<phase duration="4" state="grrrgrrrrgyygrrr"/>
<phase duration="1" state="grrrgrrrrgrrgrrr"/>
<phase duration="23" state="grrrgGGGrgrrgrrr"/>
<phase duration="4" state="grrrgGGGrgrrgrrr"/>
<phase duration="1" state="grrrgGGGrgrrgrrr"/>
<phase duration="10" state="grrrgGGGrgrrgGGr"/>
<phase duration="4" state="grrrgyyyrgrrgGGr"/>
<phase duration="1" state="grrrgrrrrgrrgGGr"/>
<phase duration="38" state="grrrgrrrrgrrgGGG"/>
<phase duration="4" state="grrrgrrrrgrrgyyy"/>
<phase duration="1" state="grrrgrrrrgrrgrrr"/>
<phase duration="65" state="gGGGgrrrrgrrgrrr"/>
<phase duration="4" state="gyyygrrrrgrrgrrr"/>
<phase duration="1" state="grrrgrrrrgrrgrrr"/>
<phase duration="19" state="grrrgrrrrgGGgrrr"/>
<phase duration="4" state="grrrgrrrrgyygrrr"/>
<phase duration="1" state="grrrgrrrrgrrgrrr"/>
<phase duration="23" state="grrrgGGGrgrrgrrr"/>
<phase duration="4" state="grrrgGGGrgrrgrrr"/>
<phase duration="1" state="grrrgGGGrgrrgrrr"/>
<phase duration="10" state="grrrgGGGrgrrgGGr"/>
<phase duration="4" state="grrrgyyyrgrrgGGr"/>
<phase duration="1" state="grrrgrrrrgrrgGGr"/>
<phase duration="38" state="grrrgrrrrgrrgGGG"/>
<phase duration="4" state="grrrgrrrrgrrgyyy"/>
<phase duration="1" state="grrrgrrrrgrrgrrr"/>
<phase duration="65" state="gGGGgrrrrgrrgrrr"/>
<phase duration="4" state="gyyygrrrrgrrgrrr"/>
<phase duration="1" state="grrrgrrrrgrrgrrr"/>
<phase duration="19" state="grrrgrrrrgGGgrrr"/>
</tlLogic>
<tlLogic id="i7" type="static" programID="i7_prog" offset="-90">
<phase duration="40" state="GGrggGG"/>
@ -333,64 +333,64 @@
<phase duration="21" state="rrrggrr"/>
</tlLogic>
<tlLogic id="i8" type="static" programID="i8_prog" offset="-10">
<phase duration="28" state="gGGGGGGGgGGGgGGG"/>
<phase duration="4" state="gGGGGGGGgGGGgGGG"/>
<phase duration="1" state="gGGGGGGGgGGGgGGG"/>
<phase duration="31" state="gGGGGGGGgGGGgGGG"/>
<phase duration="4" state="gGGGGGGGgGGGgGGG"/>
<phase duration="1" state="gGGGGGGGgGGGgGGG"/>
<phase duration="20" state="gGGGGGGGgGGGgGGG"/>
<phase duration="4" state="gGGGGGGGgGGGgGGG"/>
<phase duration="1" state="gGGGGGGGgGGGgGGG"/>
<phase duration="53" state="gGGGGGGGgGGGgGGG"/>
<phase duration="4" state="gGGGGGGGgGGGgGGG"/>
<phase duration="1" state="gGGGGGGGgGGGgGGG"/>
<phase duration="13" state="gGGGGGGGgGGGgGGG"/>
<phase duration="4" state="gGGGGGGGgGGGgGGG"/>
<phase duration="1" state="gGGGGGGGgGGGgGGG"/>
<phase duration="28" state="gGGGGGGGgGGGgGGG"/>
<phase duration="4" state="gGGGGGGGgGGGgGGG"/>
<phase duration="1" state="gGGGGGGGgGGGgGGG"/>
<phase duration="31" state="gGGGGGGGgGGGgGGG"/>
<phase duration="4" state="gGGGGGGGgGGGgGGG"/>
<phase duration="1" state="gGGGGGGGgGGGgGGG"/>
<phase duration="20" state="gGGGGGGGgGGGgGGG"/>
<phase duration="4" state="gGGGGGGGgGGGgGGG"/>
<phase duration="1" state="gGGGGGGGgGGGgGGG"/>
<phase duration="53" state="gGGGGGGGgGGGgGGG"/>
<phase duration="4" state="gGGGGGGGgGGGgGGG"/>
<phase duration="1" state="gGGGGGGGgGGGgGGG"/>
<phase duration="13" state="gGGGGGGGgGGGgGGG"/>
<phase duration="4" state="gGGGGGGGgGGGgGGG"/>
<phase duration="1" state="gGGGGGGGgGGGgGGG"/>
<phase duration="28" state="gGGGGGGGgGGGgGGG"/>
<phase duration="4" state="gGGGGGGGgGGGgGGG"/>
<phase duration="1" state="gGGGGGGGgGGGgGGG"/>
<phase duration="31" state="gGGGGGGGgGGGgGGG"/>
<phase duration="4" state="gGGGGGGGgGGGgGGG"/>
<phase duration="1" state="gGGGGGGGgGGGgGGG"/>
<phase duration="20" state="gGGGGGGGgGGGgGGG"/>
<phase duration="4" state="gGGGGGGGgGGGgGGG"/>
<phase duration="1" state="gGGGGGGGgGGGgGGG"/>
<phase duration="53" state="gGGGGGGGgGGGgGGG"/>
<phase duration="4" state="gGGGGGGGgGGGgGGG"/>
<phase duration="1" state="gGGGGGGGgGGGgGGG"/>
<phase duration="13" state="gGGGGGGGgGGGgGGG"/>
<phase duration="4" state="gGGGGGGGgGGGgGGG"/>
<phase duration="1" state="gGGGGGGGgGGGgGGG"/>
<phase duration="28" state="gGGGGGGGgGGGgGGG"/>
<phase duration="4" state="gGGGGGGGgGGGgGGG"/>
<phase duration="1" state="gGGGGGGGgGGGgGGG"/>
<phase duration="31" state="gGGGGGGGgGGGgGGG"/>
<phase duration="4" state="gGGGGGGGgGGGgGGG"/>
<phase duration="1" state="gGGGGGGGgGGGgGGG"/>
<phase duration="20" state="gGGGGGGGgGGGgGGG"/>
<phase duration="4" state="gGGGGGGGgGGGgGGG"/>
<phase duration="1" state="gGGGGGGGgGGGgGGG"/>
<phase duration="53" state="gGGGGGGGgGGGgGGG"/>
<phase duration="4" state="gGGGGGGGgGGGgGGG"/>
<phase duration="1" state="gGGGGGGGgGGGgGGG"/>
<phase duration="13" state="gGGGGGGGgGGGgGGG"/>
<phase duration="28" state="grrrrrrrgGGGgrrr"/>
<phase duration="4" state="grrrrrrrgyyygrrr"/>
<phase duration="1" state="grrrrrrrgrrrgrrr"/>
<phase duration="31" state="grrrrrrrgrrrgGGG"/>
<phase duration="4" state="grrrrrrrgrrrgGGy"/>
<phase duration="1" state="grrrrrrrgrrrgGGr"/>
<phase duration="20" state="grrrGGGrgrrrgGGr"/>
<phase duration="4" state="grrrGGGrgrrrgyyr"/>
<phase duration="1" state="grrrGGGrgrrrgrrr"/>
<phase duration="53" state="grrrGGGGgrrrgrrr"/>
<phase duration="4" state="grrryyyygrrrgrrr"/>
<phase duration="1" state="grrrrrrrgrrrgrrr"/>
<phase duration="13" state="gGGGrrrrgrrrgrrr"/>
<phase duration="4" state="gyyyrrrrgrrrgrrr"/>
<phase duration="1" state="grrrrrrrgrrrgrrr"/>
<phase duration="28" state="grrrrrrrgGGGgrrr"/>
<phase duration="4" state="grrrrrrrgyyygrrr"/>
<phase duration="1" state="grrrrrrrgrrrgrrr"/>
<phase duration="31" state="grrrrrrrgrrrgGGG"/>
<phase duration="4" state="grrrrrrrgrrrgGGy"/>
<phase duration="1" state="grrrrrrrgrrrgGGr"/>
<phase duration="20" state="grrrGGGrgrrrgGGr"/>
<phase duration="4" state="grrrGGGrgrrrgyyr"/>
<phase duration="1" state="grrrGGGrgrrrgrrr"/>
<phase duration="53" state="grrrGGGGgrrrgrrr"/>
<phase duration="4" state="grrryyyygrrrgrrr"/>
<phase duration="1" state="grrrrrrrgrrrgrrr"/>
<phase duration="13" state="gGGGrrrrgrrrgrrr"/>
<phase duration="4" state="gyyyrrrrgrrrgrrr"/>
<phase duration="1" state="grrrrrrrgrrrgrrr"/>
<phase duration="28" state="grrrrrrrgGGGgrrr"/>
<phase duration="4" state="grrrrrrrgyyygrrr"/>
<phase duration="1" state="grrrrrrrgrrrgrrr"/>
<phase duration="31" state="grrrrrrrgrrrgGGG"/>
<phase duration="4" state="grrrrrrrgrrrgGGy"/>
<phase duration="1" state="grrrrrrrgrrrgGGr"/>
<phase duration="20" state="grrrGGGrgrrrgGGr"/>
<phase duration="4" state="grrrGGGrgrrrgyyr"/>
<phase duration="1" state="grrrGGGrgrrrgrrr"/>
<phase duration="53" state="grrrGGGGgrrrgrrr"/>
<phase duration="4" state="grrryyyygrrrgrrr"/>
<phase duration="1" state="grrrrrrrgrrrgrrr"/>
<phase duration="13" state="gGGGrrrrgrrrgrrr"/>
<phase duration="4" state="gyyyrrrrgrrrgrrr"/>
<phase duration="1" state="grrrrrrrgrrrgrrr"/>
<phase duration="28" state="grrrrrrrgGGGgrrr"/>
<phase duration="4" state="grrrrrrrgyyygrrr"/>
<phase duration="1" state="grrrrrrrgrrrgrrr"/>
<phase duration="31" state="grrrrrrrgrrrgGGG"/>
<phase duration="4" state="grrrrrrrgrrrgGGy"/>
<phase duration="1" state="grrrrrrrgrrrgGGr"/>
<phase duration="20" state="grrrGGGrgrrrgGGr"/>
<phase duration="4" state="grrrGGGrgrrrgyyr"/>
<phase duration="1" state="grrrGGGrgrrrgrrr"/>
<phase duration="53" state="grrrGGGGgrrrgrrr"/>
<phase duration="4" state="grrryyyygrrrgrrr"/>
<phase duration="1" state="grrrrrrrgrrrgrrr"/>
<phase duration="13" state="gGGGrrrrgrrrgrrr"/>
</tlLogic>
<tlLogic id="i9" type="static" programID="i9_prog" offset="-150">
<phase duration="41" state="GGGG"/>
@ -462,52 +462,52 @@
<phase duration="32" state="ggggrgggg"/>
</tlLogic>
<tlLogic id="u20" type="static" programID="u20_prog" offset="-60">
<phase duration="38" state="ggrggg"/>
<phase duration="4" state="ggrggg"/>
<phase duration="1" state="ggrggg"/>
<phase duration="22" state="ggrggg"/>
<phase duration="4" state="ggrggg"/>
<phase duration="1" state="ggrggg"/>
<phase duration="38" state="gggggg"/>
<phase duration="4" state="gggggg"/>
<phase duration="1" state="gggggg"/>
<phase duration="22" state="gggggg"/>
<phase duration="4" state="gggggg"/>
<phase duration="1" state="gggggg"/>
<phase duration="65" state="ggGggg"/>
<phase duration="4" state="ggyggg"/>
<phase duration="1" state="ggrggg"/>
<phase duration="35" state="ggrggg"/>
<phase duration="4" state="ggrggg"/>
<phase duration="1" state="ggrggg"/>
<phase duration="38" state="ggrggg"/>
<phase duration="4" state="ggrggg"/>
<phase duration="1" state="ggrggg"/>
<phase duration="22" state="ggrggg"/>
<phase duration="4" state="ggrggg"/>
<phase duration="1" state="ggrggg"/>
<phase duration="4" state="ggGggg"/>
<phase duration="1" state="ggGggg"/>
<phase duration="35" state="gggggg"/>
<phase duration="4" state="gggggg"/>
<phase duration="1" state="gggggg"/>
<phase duration="38" state="gggggg"/>
<phase duration="4" state="gggggg"/>
<phase duration="1" state="gggggg"/>
<phase duration="22" state="gggggg"/>
<phase duration="4" state="gggggg"/>
<phase duration="1" state="gggggg"/>
<phase duration="65" state="ggGggg"/>
<phase duration="4" state="ggyggg"/>
<phase duration="1" state="ggrggg"/>
<phase duration="35" state="ggrggg"/>
<phase duration="4" state="ggrggg"/>
<phase duration="1" state="ggrggg"/>
<phase duration="38" state="ggrggg"/>
<phase duration="4" state="ggrggg"/>
<phase duration="1" state="ggrggg"/>
<phase duration="22" state="ggrggg"/>
<phase duration="4" state="ggrggg"/>
<phase duration="1" state="ggrggg"/>
<phase duration="4" state="ggGggg"/>
<phase duration="1" state="ggGggg"/>
<phase duration="35" state="gggggg"/>
<phase duration="4" state="gggggg"/>
<phase duration="1" state="gggggg"/>
<phase duration="38" state="gggggg"/>
<phase duration="4" state="gggggg"/>
<phase duration="1" state="gggggg"/>
<phase duration="22" state="gggggg"/>
<phase duration="4" state="gggggg"/>
<phase duration="1" state="gggggg"/>
<phase duration="65" state="ggGggg"/>
<phase duration="4" state="ggyggg"/>
<phase duration="1" state="ggrggg"/>
<phase duration="35" state="ggrggg"/>
<phase duration="4" state="ggrggg"/>
<phase duration="1" state="ggrggg"/>
<phase duration="38" state="ggrggg"/>
<phase duration="4" state="ggrggg"/>
<phase duration="1" state="ggrggg"/>
<phase duration="22" state="ggrggg"/>
<phase duration="4" state="ggrggg"/>
<phase duration="1" state="ggrggg"/>
<phase duration="4" state="ggGggg"/>
<phase duration="1" state="ggGggg"/>
<phase duration="35" state="gggggg"/>
<phase duration="4" state="gggggg"/>
<phase duration="1" state="gggggg"/>
<phase duration="38" state="gggggg"/>
<phase duration="4" state="gggggg"/>
<phase duration="1" state="gggggg"/>
<phase duration="22" state="gggggg"/>
<phase duration="4" state="gggggg"/>
<phase duration="1" state="gggggg"/>
<phase duration="65" state="ggGggg"/>
<phase duration="4" state="ggyggg"/>
<phase duration="1" state="ggrggg"/>
<phase duration="35" state="ggrggg"/>
<phase duration="4" state="ggGggg"/>
<phase duration="1" state="ggGggg"/>
<phase duration="35" state="gggggg"/>
</tlLogic>
<tlLogic id="u30" type="static" programID="u30_prog" offset="-50">
<phase duration="33" state="ggggrggg"/>

BIN
Scripts/__pycache__/generate_signals.cpython-38.pyc View File


BIN
Scripts/__pycache__/preprocess_daily.cpython-38.pyc View File


+ 1
- 3
Scripts/generate_signals.py View File

@ -266,7 +266,7 @@ class SignalGenerator():
def load_prow(self, inter_no, time):
'''
load planned row
load the planned row
'''
# 프로그램 시작시각
program_starts = np.array(self.timetable.start_seconds)
@ -543,14 +543,12 @@ class SignalGenerator():
state_A = mapping_dict[(node_id, move_A)]
else:
state_A = ''.join(self.node2init[node_id])
# self.histid.at[i, 'state_A'] = state_A
# B링의 state 지정
if (node_id, move_B) in mapping_dict:
state_B = mapping_dict[(node_id, move_B)]
else:
state_B = ''.join(self.node2init[node_id])
# self.histid.at[i, 'state_B'] = state_B
# 통합된 state 지정
state = ''

+ 0
- 876
Scripts/generate_signals_until_4-1.py View File

@ -1,876 +0,0 @@
# python .\Scripts\generate_signals.py
import pandas as pd
import numpy as np
import os, sys
import json
import copy
from tqdm import tqdm
import sumolib, traci
from datetime import datetime
import time
class SignalGenerator():
def __init__(self):
# 루트폴더 지정
self.path_root = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
with open(os.path.join(self.path_root, 'Scripts', 'config.json'), 'r') as config_file:
config = json.load(config_file)
# 주요 폴더 경로 지정
self.paths = config['paths']
self.path_data = os.path.join(self.path_root, *self.paths['data'])
self.path_intermediates = os.path.join(self.path_root, *self.paths['intermediates'])
self.path_results = os.path.join(self.path_root, *self.paths['results'])
self.path_tables = os.path.join(self.path_root, *self.paths['tables'])
self.path_networks = os.path.join(self.path_root, *self.paths['networks'])
self.path_scripts = os.path.join(self.path_root, *self.paths['scripts'])
# 이슈사항 목록
self.issues = []
self.midnight = int(datetime(2024, 1, 5, 0, 0, 0).timestamp())
self.next_day = int(datetime(2024, 1, 6, 0, 0, 0).timestamp())
self.fsecs = range(self.midnight, self.next_day, 5) # fsecs : unix time by Five SECondS
self.fmins = range(self.midnight, self.next_day, 300) # fmins : unix time by Five MINuteS
self.present_time = datetime.now().replace(month=1, day=5, hour=10).timestamp()
self.present_time = max([fmin for fmin in list(self.fmins) if fmin <= self.present_time])
self.adder = 600 # 10분 : '현재시점 + 10분'에 가상신호를 생성하기 위함.
self.subtractor = 1800 # 30분 : '현재시점 - 30분'의 신호이력을 가져온다.
# 1. 데이터 준비
def prepare_data(self):
print("1. 데이터를 준비합니다.")
self.load_networks()
self.time11 = datetime.now()
self.load_tables()
self.time12 = datetime.now()
# self.check_networks()
self.time13 = datetime.now()
# self.check_tables()
self.time14 = datetime.now()
self.prepare_auxiliaries()
self.time15 = datetime.now()
# 1-1. 네트워크 불러오기
def load_networks(self):
self.net = sumolib.net.readNet(os.path.join(self.path_networks, 'sn.net.xml'))
print("1-1. 네트워크가 로드되었습니다.")
# 1-2. 테이블 불러오기
def load_tables(self):
# 모든 컬럼에 대하여 데이터타입 지정
loading_dtype = {
'inter_no':'int', 'start_hour':'int', 'start_minute':'int', 'cycle':'int','offset':'int',
'node_id':'str', 'inter_type':'str', 'parent_id':'str','child_id':'str',
'direction':'str', 'condition':'str', 'inc_edge':'str', 'out_edge':'str',
'end_unix':'int', 'inter_name':'str', 'inter_lat':'float', 'inter_lon':'float',
'group_no':'int', 'main_phase_no':'int', 'phase_no':'int','ring_type':'str'
}
for alph in ['A', 'B']:
for j in range(1,9):
loading_dtype[f'angle_{alph}{j}'] = 'str'
loading_dtype[f'dura_{alph}{j}'] = 'int'
# 테이블 불러오기
self.inter_info = pd.read_csv(os.path.join(self.path_tables, 'inter_info.csv'), dtype=loading_dtype)
self.plan = pd.read_csv(os.path.join(self.path_tables, 'plan.csv'), dtype=loading_dtype)
self.history = pd.read_csv(os.path.join(self.path_tables, 'history.csv'), dtype=loading_dtype).sort_values(by='end_unix')
self.inter_node = pd.read_csv(os.path.join(self.path_tables, 'inter_node.csv'), dtype=loading_dtype)
self.matching = pd.read_csv(os.path.join(self.path_intermediates, 'matching.csv'), dtype=loading_dtype)
self.match1 = pd.read_csv(os.path.join(self.path_intermediates, 'match1.csv'), dtype=loading_dtype)
self.match6 = pd.read_csv(os.path.join(self.path_intermediates, 'match6.csv'), dtype=loading_dtype)
self.match6 = self.match6[['node_id', 'phase_no', 'ring_type', 'inc_edge', 'out_edge']].reset_index(drop=True)
self.plan_set = self.plan.set_index(['inter_no','start_hour','start_minute'])
# 교차로목록 정의
self.inter_nos = sorted(self.inter_info.inter_no.unique())
print("1-2. 테이블들이 로드되었습니다.")
# 1-3. 네트워크 무결성 검사
def check_networks(self):
# https://sumo.dlr.de/docs/Netedit/neteditUsageExamples.html#simplify_tls_program_state_after_changing_connections
if 'SUMO_HOME' in os.environ:
tools = os.path.join(os.environ['SUMO_HOME'], 'tools')
if tools not in sys.path:
sys.path.append(tools)
else:
raise EnvironmentError("please declare environment variable 'SUMO_HOME'")
traci.start([sumolib.checkBinary('sumo'), "-n", os.path.join(self.path_networks, 'sn.net.xml')])
nodes = [node for node in self.net.getNodes() if node.getType()=='traffic_light']
for node in nodes:
node_id = node.getID()
from_xml = len([c for c in node.getConnections() if c.getTLLinkIndex() >= 0])
from_traci = len(traci.trafficlight.getRedYellowGreenState(node_id))
if from_xml != from_traci:
sub = {'id': node_id, 'type': 'node', 'note': '유효하지 않은 연결이있음. netedit에서 clean states 필요.'}
self.issues.append(sub)
traci.close()
print("1-3. 네트워크의 모든 clean state requirement들을 체크했습니다.")
# 1-4. 테이블 무결성 검사
def check_tables(self):
self.check_history()
# 교차로정보, 방위각정보, 신호계획에 대해서는 preprocess_daily.py에서
# 무결성검사를 완료했으므로 여기에서는 따로 검사하지 않음.
# self.check_moves() # 이동류번호에 대한 무결성검사 필요하나 아직 작성하지 않음. (24. 2. 5 화)
print("1-4. 테이블들의 무결성 검사를 완료했습니다.")
# 1-4-1. 신호이력(history) 검사
def check_history(self):
# 1-4-1-1. inter_no 검사
# self.history.loc[0, 'inter_no'] = '4' # 에러 발생을 위한 코드
missing_inter_nos = set(self.history.inter_no) - set(self.inter_nos)
if missing_inter_nos:
msg = f"1-4-1-1. history의 inter_no 중 교차로 목록(inter_nos)에 포함되지 않는 항목이 있습니다: {missing_inter_nos}"
self.issues.append(msg)
# 1-4-1-2. 종료유닉스 검사
# self.history.loc[0, 'end_unix'] = 38.0 # 에러 발생을 위한 코드
self.min_unix, self.max_unix = int(datetime(2020, 1, 1).timestamp()), int(datetime(2038, 1, 1).timestamp())
for row in self.history.itertuples(index=True):
unixbool = self.min_unix <= row['end_unix'] <= self.max_unix
if not unixbool:
msg = f"1-4-1-2. 적정 범위를 벗어난 유닉스시각(end_unix)이 존재합니다 : inter_no : {row['inter_no']}"
self.issues.append(msg)
# 1-4-1-3. 현시시간 검사
# self.history.loc[0, 'dura_A1'] = -2 # 에러 발생을 위한 코드
durations = self.history[[f'dura_{alph}{j}' for alph in ['A','B'] for j in range(1, 9)]]
valid_indices = ((durations >= 0) & (durations <= 200)).all(axis=1)
invalid_inter_nos = sorted(self.history[~ valid_indices].inter_no.unique())
if invalid_inter_nos:
msg = f"1-4-1-3. 음수이거나 200보다 큰 현시시간이 존재합니다. : {invalid_inter_nos}"
# 1-5. 보조 딕셔너리, 데이터프레임, 리스트 등 만들기
def prepare_auxiliaries(self):
# inter2node : a dictionary that maps inter_no to the node_id
inter_node_p = self.inter_node[self.inter_node.inter_type=='parent']
self.inter2node = dict(zip(inter_node_p['inter_no'], inter_node_p['node_id']))
self.node2inter = dict(zip(self.inter_node['node_id'], self.inter_node['inter_no']))
# split, isplit : A,B 분리 혹은 통합시 사용될 수 있는 딕셔너리
self.splits = {} # splits maps (inter_no, start_hour, start_minute) to split
for i, row in self.plan.iterrows():
inter_no = row.inter_no
start_hour = row.start_hour
start_minute = row.start_minute
cycle = row.cycle
dura_A = np.array(row[[f'dura_A{j}' for j in range(1, 9)]])
dura_B = np.array(row[[f'dura_B{j}' for j in range(1, 9)]])
cums_A = dura_A.cumsum()
cums_B = dura_B.cumsum()
combined_row = np.unique(np.concatenate((cums_A,cums_B)))
detailed_durations = np.concatenate(([combined_row[0]], np.diff(combined_row)))
self.splits[(inter_no, start_hour, start_minute)] = {} # split maps (phas_A, phas_B) to k
ja = 0
jb = 0
for k in range(len(detailed_durations)):
dura_A[ja] -= detailed_durations[k]
dura_B[jb] -= detailed_durations[k]
self.splits[(inter_no, start_hour, start_minute)][(ja+1, jb+1)] = k+1
if dura_A[ja] == 0:
ja += 1
if dura_B[jb] == 0:
jb += 1
self.isplits = {} # the inverse of splits
for i in self.splits:
self.isplits[i] = {self.splits[i][k]:k for k in self.splits[i]} # isplit maps k to (phas_A, phas_B)
# timetable : 교차로별 프로그램 시작시각
self.timetable = self.plan[['start_hour', 'start_minute']].drop_duplicates()
self.timetable['start_seconds'] = self.midnight + self.timetable['start_hour'] * 3600 + self.timetable['start_minute'] * 60
# A dictionary that maps parent_id to a list of child_ids
self.pa2ch = {'i0':['u00'], 'i1':[], 'i2':['u20'], 'i3':['c30', 'u30', 'u31', 'u32'], 'i6':['u60'], 'i7':[], 'i8':[], 'i9':[]}
self.node_ids = sorted(self.inter_node.node_id.unique())
self.parent_ids = sorted(self.inter_node[self.inter_node.inter_type=='parent'].node_id.unique())
self.nodes = [self.net.getNode(node_id) for node_id in self.node_ids]
# node2num_cycles : A dictionary that maps a node_id to the number of cycles
with open(os.path.join(self.path_intermediates, 'node2num_cycles.json'), 'r') as file:
# json.load() 함수를 사용해 파일 내용을 Python 딕셔너리로 불러옵니다.
self.node2num_cycles = json.load(file)
# 2. 신호이력 전처리
def process_history(self):
print("2. 신호이력 테이블을 변환합니다.")
self.make_rhistory()
self.time21 = datetime.now()
self.make_rhists()
self.time22 = datetime.now()
self.make_hrhists()
self.time23 = datetime.now()
# 2-1. rhistory
def make_rhistory(self):
# 1. 조회시점의 유닉스 타임 이전의 신호이력 수집
self.rhistory = self.history.copy() # recent history
self.rhistory = self.rhistory[(self.rhistory.end_unix <= self.present_time) & (self.rhistory.end_unix > self.present_time - self.subtractor)]
# rhistory에 모든 교차로번호가 존재하지 않으면 해당 교차로번호에 대한 신호이력을 추가함 (at 최근 프로그램 시작시각)
whole_inter_nos = set(self.history.inter_no.unique())
recent_inter_nos = set(self.rhistory.inter_no.unique())
if not whole_inter_nos==recent_inter_nos:
for inter_no in whole_inter_nos - recent_inter_nos:
program_start, prow = self.load_prow(inter_no, self.present_time - self.subtractor)
cycle = prow.cycle.iloc[0]
row1 = prow.copy()
row2 = prow.copy()
# prow에서 필요한 부분을 rhistory에 추가
row1['end_unix'] = program_start
row2['end_unix'] = program_start + cycle
self.rhistory = pd.concat([self.rhistory, row1, row2])#.reset_index(drop=True)
# present_time + adder 의 시각에 한 주기의 신호 추가
for inter_no in set(whole_inter_nos):
program_start, prow = self.load_prow(inter_no, self.present_time)
cycle = prow.cycle.iloc[0]
row3 = prow.copy()
# prow에서 필요한 부분을 rhistory에 추가
row3['end_unix'] = self.present_time + self.adder
self.rhistory = pd.concat([self.rhistory, row3])#.reset_index(drop=True)
# 2. 시작 유닉스 타임컬럼 생성 후 종류 유닉스 타임에서 현시별 현시기간 컬럼의 합을 뺀 값으로 입력
# - 현시시간의 합을 뺀 시간의 +- 10초 이내에 이전 주기정보가 존재하면 그 유닉스 시간을 시작 유닉스시간 값으로 하고, 존재하지 않으면 현시시간의 합을 뺀 유닉스 시간을 시작 유닉스 시간으로 지정
for i, row in self.rhistory.iterrows():
inter_no = row.inter_no
end_unix = row.end_unix
elapsed_time = row[[f'dura_{alph}{j}' for alph in ['A', 'B'] for j in range(1,9)]].sum() // 2 # 현시시간 합
# 이전 유닉스 존재하지 않음 : 현시시간 합의 차
start_unix = end_unix - elapsed_time
pre_rows = self.history[:i] # previous rows
if inter_no in pre_rows.inter_no.unique(): # 이전 유닉스 존재
pre_unix = pre_rows[pre_rows.inter_no == inter_no]['end_unix'].iloc[-1] # previous unix time
# 이전 유닉스 존재, abs < 10 : 이전 유닉스
if abs(pre_unix - start_unix) < 10:
start_unix = pre_unix
# 이전 유닉스 존재, abs >=10 : 현시시간 합의 차
else:
pass
self.rhistory.loc[i, 'start_unix'] = start_unix
self.rhistory[self.rhistory.isna()] = 0
self.rhistory['start_unix'] = self.rhistory['start_unix'].astype(int)
self.rhistory = self.rhistory[['inter_no', 'start_unix'] + [f'dura_{alph}{j}' for alph in ['A', 'B'] for j in range(1,9)] + ['cycle']]
def load_prow(self, inter_no, time):
'''
load planned row
'''
# 프로그램 시작시각
program_starts = np.array(self.timetable.start_seconds)
idx = (program_starts <= time).sum() - 1
program_start = program_starts[idx]
# 최근 프로그램 시작시각에 대한 신호계획
start_hour = self.timetable.iloc[idx].start_hour
start_minute = self.timetable.iloc[idx].start_minute
# prow = self.plan[(self.plan.inter_no==inter_no) & (self.plan.start_hour==start_hour) & (self.plan.start_minute==start_minute)] # planned row
prow = self.plan_set.loc[(inter_no, start_hour, start_minute)]
prow = pd.DataFrame([prow],index=[0])
prow['inter_no'] = inter_no
return program_start, prow
# 2-2. rhists
def make_rhists(self):
self.rhists = []
for inter_no in self.rhistory.inter_no.unique():
self.rhist = self.rhistory.copy()[self.rhistory.inter_no==inter_no]
self.rhist = self.rhist.drop_duplicates(subset=['start_unix']).reset_index(drop=True)
# D_n 및 S_n 값 정의
self.rhist['D_n'] = 0 # D_n : 시간차이
self.rhist['S_n'] = 0 # S_n : 현시시간합
for n in range(len(self.rhist)):
curr_unix = self.rhist.iloc[n].start_unix # current start_unix
self.rhist.loc[n, ['D_n', 'S_n']] = self.calculate_DS(self.rhist, curr_unix)
# 이전시각, 현재시각
prev_unix = self.rhist.loc[0, 'start_unix'] # previous start_unix
curr_unix = self.rhist.loc[1, 'start_unix'] # current start_unix
# rhist의 마지막 행에 도달할 때까지 반복
while True:
n = self.rhist[self.rhist.start_unix==curr_unix].index[0]
cycle = self.rhist.loc[n, 'cycle']
D_n = self.rhist.loc[n, 'D_n']
S_n = self.rhist.loc[n, 'S_n']
# 참값인 경우
if (abs(D_n - S_n) <= 5):
pass
# 참값이 아닌 경우
else:
# 2-1-1. 결측치 처리 : 인접한 두 start_unix의 차이가 계획된 주기의 두 배보다 크면 결측이 일어났다고 판단, 신호계획의 현시시간으로 "대체"
if curr_unix - prev_unix >= 2 * cycle:
# prev_unix를 계획된 주기만큼 늘려가면서 한 행씩 채워나간다.
# (curr_unix와의 차이가 계획된 주기보다 작거나 같아질 때까지)
while curr_unix - prev_unix > cycle:
prev_unix += cycle
# 신호 계획(prow) 불러오기
start_seconds = np.array(self.timetable.start_seconds)
idx = (start_seconds <= prev_unix).sum() - 1
start_hour = self.timetable.iloc[idx].start_hour
start_minute = self.timetable.iloc[idx].start_minute
prow = self.plan.copy()[(self.plan.inter_no==inter_no) & (self.plan.start_hour==start_hour) & (self.plan.start_minute==start_minute)] # planned row
# prow에서 필요한 부분을 rhist에 추가
prow['start_unix'] = prev_unix
prow = prow.drop(['start_hour', 'start_minute', 'offset'], axis=1)
cycle = prow.iloc[0].cycle
self.rhist = pd.concat([self.rhist, prow])
self.rhist = self.rhist.sort_values(by='start_unix').reset_index(drop=True)
n += 1
# 2-1-2. 이상치 처리 : 비율에 따라 해당 행을 "삭제"(R_n <= 0.5) 또는 "조정"(R_n > 0.5)한다
R_n = (curr_unix - prev_unix) / cycle # R_n : 비율
# R_n이 0.5보다 작거나 같으면 해당 행을 삭제
if R_n <= 0.5:
self.rhist = self.rhist.drop(index=n).reset_index(drop=True)
if n >= self.rhist.index[-1]:
break
# 행삭제에 따른 curr_unix, R_n 재정의
curr_unix = self.rhist.loc[n, 'start_unix']
R_n = (curr_unix - prev_unix) / cycle # R_n : 비율
# R_n이 0.5보다 크면 해당 행 조정 (비율을 유지한 채로 현시시간 대체)
if R_n > 0.5:
# 신호 계획(prow) 불러오기
start_seconds = np.array(self.timetable.start_seconds)
idx = (start_seconds <= curr_unix).sum() - 1
start_hour = self.timetable.iloc[idx].start_hour
start_minute = self.timetable.iloc[idx].start_minute
prow = self.plan[(self.plan.inter_no==inter_no) & (self.plan.start_hour==start_hour) & (self.plan.start_minute==start_minute)] # planned row
# 조정된 현시시간 (prow에 R_n을 곱하고 정수로 바꿈)
adjusted_dur = prow.copy()[[f'dura_{alph}{j}' for alph in ['A', 'B'] for j in range(1,9)]] * R_n
int_parts = adjusted_dur.iloc[0].apply(lambda x: int(x))
frac_parts = adjusted_dur.iloc[0] - int_parts
difference = round(adjusted_dur.iloc[0].sum()) - int_parts.sum()
for _ in range(difference): # 소수 부분이 가장 큰 상위 'difference'개의 값에 대해 올림 처리
max_frac_index = frac_parts.idxmax()
int_parts[max_frac_index] += 1
frac_parts[max_frac_index] = 0 # 이미 처리된 항목은 0으로 설정
# rhist에 조정된 현시시간을 반영
self.rhist.loc[n, [f'dura_{alph}{j}' for alph in ['A', 'B'] for j in range(1,9)]] = int_parts.values
self.rhist.loc[n, 'cycle'] = int_parts.sum().sum() // 2
if n >= self.rhist.index[-1]:
break
prev_unix = curr_unix
curr_unix = self.rhist.loc[n+1, 'start_unix']
# D_n 및 S_n 값 재정의
# 이 함수의 검증시 필요하나 전체 구동에는 필요없으므로 comment해놓음
# for n in range(len(self.rhist)):
# curr_unix = self.rhist.iloc[n].start_unix # current start_unix
# self.rhist.loc[n, ['D_n', 'S_n']] = self.calculate_DS(self.rhist, curr_unix)
self.rhists.append(self.rhist)
self.rhists = pd.concat(self.rhists)#.sort_values(by=['start_unix','inter_no'])
self.rhists = self.rhists[self.rhists.start_unix >= self.present_time - self.subtractor // 2]
def calculate_DS(self, rhist, curr_unix):
# program_starts = np.array(self.timetable.start_seconds)
# idx = (program_starts <= self.present_time).sum() - 1
# program_start = program_starts[idx]
# if list(self.hours[self.hours <= curr_unix]):
# ghour_lt_curr_unix = self.hours[self.hours <= curr_unix].max() # the greatest hour less than or equal to curr_unix
# else:
# ghour_lt_curr_unix = program_start
# start_unixes = rhist.start_unix.unique()
# start_unixes_lt_ghour = np.sort(start_unixes[start_unixes < ghour_lt_curr_unix]) # start unixes less than ghour_lt_curr_unix
# # 기준유닉스(base_unix) : curr_unix보다 작은 hour 중에서 가장 큰 값으로부터 다섯 번째로 작은 start_unix
# if len(start_unixes_lt_ghour) > 5:
# base_unix = start_unixes_lt_ghour[-5]
# # start_unixes_lt_ghour의 길이가 5 미만일 경우에는 맨 앞 start_unix로 base_unix를 지정
# else:
# base_unix = rhist.start_unix.min()
base_unix = curr_unix - self.subtractor // 2
abs_diff = (self.rhist['start_unix'] - base_unix).abs()
closest_index = abs_diff.idxmin()
base_unix = self.rhist.loc[closest_index, 'start_unix']
D_n = curr_unix - base_unix
S_n_durs = rhist[(rhist.start_unix > base_unix) & (rhist.start_unix <= curr_unix)] \
[[f'dura_{alph}{j}' for alph in ['A', 'B'] for j in range(1,9)]]
S_n = S_n_durs.values.sum() // 2
return D_n, S_n
# 2-3. hrhists
def make_hrhists(self):
# 계층화된 형태로 변환
self.hrhists = [] # hierarchied recent history
for row in self.rhists.itertuples(index=True):
inter_no = row.inter_no
start_unix = row.start_unix
ind = (self.timetable['start_seconds'] <= row.start_unix).sum() - 1
start_hour = self.timetable.iloc[ind].start_hour
start_minute = self.timetable.iloc[ind].start_minute
self.isplit = self.isplits[(inter_no, start_hour, start_minute)]
phas_As = [self.isplit[j][0] for j in self.isplit.keys()]
phas_Bs = [self.isplit[j][1] for j in self.isplit.keys()]
# durs_A = row[[f'dura_A{j}' for j in range(1,9)]]
# durs_B = row[[f'dura_B{j}' for j in range(1,9)]]
durs_A = [getattr(row, f'dura_A{j}') for j in range(1, 9)]
durs_B = [getattr(row, f'dura_B{j}') for j in range(1, 9)]
durations = []
for j in range(1, len(self.isplit)+1):
ja = self.isplit[j][0]
jb = self.isplit[j][1]
if ja == jb:
durations.append(min(durs_A[ja-1], durs_B[jb-1]))
else:
durations.append(abs(durs_A[ja-1] - durs_B[ja-1]))
new_rows = pd.DataFrame({'inter_no':[inter_no] * len(durations), 'start_unix':[start_unix] * len(durations),
'phas_A':phas_As, 'phas_B':phas_Bs, 'duration':durations})
self.hrhists.append(new_rows)
self.hrhists = pd.concat(self.hrhists)
# self.hrhists = self.hrhists.sort_values(by = ['start_unix', 'inter_no', 'phas_A', 'phas_B']).reset_index(drop=True)
# 3. 이동류정보 전처리
def process_movement(self):
print("3. 이동류정보 테이블을 변환합니다.")
self.make_movement()
self.time31 = datetime.now()
self.update_movement()
self.time32 = datetime.now()
# 3-1. movement
def make_movement(self):
# - 아래 절차를 5초마다 반복
for fsec in range(self.present_time - 300, self.present_time + 1, 5): # fsec : unix time by Five SECond
# 1. 상태 테이블 조회해서 전체 데이터중 필요데이터(교차로번호, A링 현시번호, A링 이동류번호, B링 현시번호, B링 이동류번호)만 수집 : A
move = pd.read_csv(os.path.join(self.path_tables, 'move', f'move_{fsec}.csv'), index_col=0)
# 2. 이력 테이블 조회해서 교차로별로 유닉스시간 최대인 데이터(교차로번호, 종료유닉스타임)만 수집 : B
recent_histories = [group.iloc[-1:] for _, group in self.history[self.history['end_unix'] < fsec].groupby('inter_no')] # 교차로별로 유닉스시간이 최대인 행들
# print([group for _, group in self.history[self.history['end_unix'] < fsec].groupby('inter_no')])
if not recent_histories:
rhistory = pd.DataFrame({'inter_no':[], 'end_unix':[]}) # recent history
else:
rhistory = pd.concat(recent_histories)
recent_unix = rhistory[['inter_no', 'end_unix']]
# 3. 상태 테이블 조회정보(A)와 이력 테이블 조회정보(B) 조인(키값 : 교차로번호) : C
move = pd.merge(move, recent_unix, how='left', on='inter_no')
move['end_unix'] = move['end_unix'].fillna(0).astype(int)
# 4. C데이터 프레임에 신규 컬럼(시작 유닉스타임) 생성 후 종료유닉스 타임 값 입력, 종료 유닉스 타임 컬럼 제거
move = move.rename(columns = {'end_unix':'start_unix'})
# 5. 이동류 이력정보 READ
# - CSV 파일로 서버에 저장된 이동류정보를 읽어옴(파일이 없는 경우에는 데이터가 없는 프레임 D 생성)
try:
if isinstance(movement, pd.DataFrame): # movement가 존재할 경우 그걸 그대로 씀.
pass
else:
movement = pd.DataFrame()
except NameError: # movement가 존재하지 않는 경우 생성
movement = pd.DataFrame()
# 6. 이동류 이력정보 데이터테이블(D)에 C데이터 add
movement = pd.concat([movement, move])
# 7. D데이터 프레임에서 중복데이터 제거(교차로번호, 시작 유닉스타임, A링 현시번호, B링 현시번호 같은 행은 제거)
movement = movement.drop_duplicates(['inter_no','phas_A','phas_B','start_unix'])
# 8. D데이터 보관 시간 기준시간을 시작 유닉스 타임의 최대값 - self.subtractor // 2을 값으로 산출하고, 보관 시간 기준시간보다 작은 시작 유닉스 타임을 가진 행은 모두 제거(1시간 데이터만 보관)
movement = movement[movement.start_unix > fsec - self.subtractor // 2]
# movement = movement.sort_values(by=['start_unix','inter_no','phas_A','phas_B']).reset_index(drop=True)
self.movement = pd.read_csv(os.path.join(self.path_intermediates, 'movement', f'movement_{self.present_time}.csv'), index_col=0)
# 3-2. movement_updated
def update_movement(self):
# 중복을 제거하고 (inter_no, start_unix) 쌍을 만듭니다.
hrhists_inter_unix = set(self.hrhists[['inter_no', 'start_unix']].drop_duplicates().itertuples(index=False, name=None))
movement_inter_unix = set(self.movement[['inter_no', 'start_unix']].drop_duplicates().itertuples(index=False, name=None))
# hrhists에는 있지만 movement에는 없는 (inter_no, start_unix) 쌍을 찾습니다.
missing_in_movement = hrhists_inter_unix - movement_inter_unix
# 새로운 행들을 생성합니다.
new_rows = []
if missing_in_movement:
for inter_no, start_unix in missing_in_movement:
# match1에서 해당 inter_no의 데이터를 찾습니다.
new_row = self.match1[self.match1['inter_no'] == inter_no].copy()
# start_unix 값을 설정합니다.
new_row['start_unix'] = start_unix
new_rows.append(new_row)
# 새로운 데이터프레임을 생성하고 기존 movement 데이터프레임과 합칩니다.
new_movement = pd.concat(new_rows, ignore_index=True)
self.movement_updated = pd.concat([self.movement, new_movement], ignore_index=True)
else:
self.movement_updated = self.movement
# 4. 통합테이블 생성
def make_histids(self):
print("4. 통합 테이블을 생성합니다.")
self.merge_dfs()
self.time41 = datetime.now()
# self.attach_children()
# self.time42 = datetime.now()
# 4-1. histid
def merge_dfs(self):
# movements and durations
movedur = pd.merge(self.hrhists, self.movement_updated, how='inner', on=['inter_no', 'start_unix', 'phas_A', 'phas_B'])
# movedur = movedur.sort_values(by=['start_unix', 'inter_no', 'phas_A','phas_B'])
movedur = movedur[['inter_no', 'start_unix', 'phas_A', 'phas_B', 'move_A', 'move_B', 'duration']]
# matching DataFrame에 대해 multi-index 설정
self.matching.set_index(['inter_no', 'move_no'], inplace=True)
self.matching.sort_index(inplace=True)
for row in movedur.itertuples(index=True):
inter_no = row.inter_no
start_unix = row.start_unix
move_A = row.move_A
move_B = row.move_B
# incoming and outgoing edges A
if move_A in [17, 18]:
inc_edge_A = np.nan
out_edge_A = np.nan
else:
match_A = self.matching.loc[(inter_no, move_A)]
inc_edge_A = match_A.inc_edge.values[0]
out_edge_A = match_A.out_edge.values[0]
movedur.at[row.Index, 'inc_edge_A'] = inc_edge_A
movedur.at[row.Index, 'out_edge_A'] = out_edge_A
# incoming and outgoing edges B
if move_B in [17, 18]:
inc_edge_B = np.nan
out_edge_B = np.nan
else:
match_B = self.matching.loc[(inter_no, move_B)]
inc_edge_B = match_B.inc_edge.values[0]
out_edge_B = match_B.out_edge.values[0]
movedur.at[row.Index, 'inc_edge_B'] = inc_edge_B
movedur.at[row.Index, 'out_edge_B'] = out_edge_B
# 이동류 컬럼 제거
movedur = movedur.drop(['move_A', 'move_B'], axis=1)
self.histid = movedur.copy() # history with edge ids (incoming and outgoing edge ids)
self.histid['node_id'] = self.histid['inter_no'].map(self.inter2node)
self.histid = self.histid[['inter_no', 'node_id', 'start_unix', 'phas_A', 'phas_B', 'duration', 'inc_edge_A', 'out_edge_A', 'inc_edge_B', 'out_edge_B']]
histid_start = self.present_time - 600
self.histid = self.histid[self.histid.start_unix > histid_start]
# 4-2. histids
def attach_children(self):
'''
·
input :
(1) histid
- (, A현시, B현시) , ·
- ()
(2) match6
- (, ) ·
- ( )
(3) parent_ids :
(4) pa2ch : id를 id들의
output : histids
- ( ) (, A현시, B현시) , ·
'''
new_histids = []
for parent_id in self.parent_ids:
for child_id in self.pa2ch[parent_id]:
new_histid = self.histid.copy()[self.histid.node_id==parent_id]
new_histid[['inc_edge_A', 'out_edge_A', 'inc_edge_B', 'out_edge_B']] = np.nan
for i, row in new_histid.iterrows():
phas_A = row.phas_A
phas_B = row.phas_B
new_match = self.match6[self.match6.node_id==child_id]
Arow = new_match[(new_match.phase_no==phas_A) & (new_match.ring_type=='A')]
if ~ Arow[['inc_edge', 'out_edge']].isna().all().all():
inc_edge = Arow.iloc[0].inc_edge
out_edge = Arow.iloc[0].out_edge
new_histid.loc[i, ['inc_edge_A', 'out_edge_A']] = [inc_edge, out_edge]
Brow = new_match[(new_match.phase_no==phas_B) & (new_match.ring_type=='B')]
if ~ Brow[['inc_edge', 'out_edge']].isna().all().all():
inc_edge = Brow.iloc[0].inc_edge
out_edge = Brow.iloc[0].out_edge
new_histid.loc[i, ['inc_edge_B', 'out_edge_B']] = [inc_edge, out_edge]
new_histid.loc[i, 'node_id'] = child_id
new_histids.append(new_histid)
new_histids = pd.concat(new_histids)
self.histids = pd.concat([self.histid.copy(), new_histids])
self.histids = self.histids.sort_values(by=['start_unix', 'node_id', 'phas_A', 'phas_B']).reset_index(drop=True)
# 5. 신호 생성
def get_signals(self):
print("5. 신호를 생성합니다.")
self.initialize_states()
self.time51 = datetime.now()
self.assign_signals()
self.time52 = datetime.now()
self.set_timepoints()
self.time53 = datetime.now()
self.assign_red_yellow()
self.time54 = datetime.now()
self.make_tl_file()
self.time55 = datetime.now()
# 5-1. 신호초기화
def initialize_states(self):
'''
input :
(1) net :
(2) nodes :
(3) histids : (, A현시, B현시) , ·
output : node2init
-
- , g로 r로 .
'''
self.node2init = {}
for node in self.nodes:
node_id = node.getID()
conns = [(c.getJunctionIndex(), c) for c in node.getConnections()]
conns = [c for c in conns if c[0] >= 0]
conns = sorted(conns, key=lambda x: x[0])
state = []
for i, ci in conns:
if ci.getTLLinkIndex() < 0:
continue
are_foes = False
for j, cj in conns:
if ci.getTo() == cj.getTo():
continue
if node.areFoes(i, j):
are_foes = True
break
state.append('r' if are_foes else 'g')
self.node2init[node_id] = state
# 어떤 연결과도 상충이 일어나지는 않지만, 신호가 부여되어 있는 경우에는 r을 부여
for _, row in self.histids.iterrows():
node_id = row['node_id']
inc_edge_A = row.inc_edge_A
inc_edge_B = row.inc_edge_B
out_edge_A = row.out_edge_A
out_edge_B = row.out_edge_B
if pd.isna(inc_edge_A) or pd.isna(out_edge_A):
pass
else:
inc_edge_A = self.net.getEdge(inc_edge_A)
out_edge_A = self.net.getEdge(out_edge_A)
for conn in inc_edge_A.getConnections(out_edge_A):
index = conn.getTLLinkIndex()
if index >= 0:
self.node2init[node_id][index] = 'r'
if pd.isna(inc_edge_B) or pd.isna(out_edge_B):
pass
else:
inc_edge_B = self.net.getEdge(inc_edge_B)
out_edge_B = self.net.getEdge(out_edge_B)
for conn in inc_edge_B.getConnections(out_edge_B):
index = conn.getTLLinkIndex()
if index >= 0:
self.node2init[node_id][index] = 'r'
# 5-2. 녹색신호 부여
def assign_signals(self):
'''
·
input :
(1) histids : (, A현시, B현시) , ·
(2) node2init :
(3) net :
output : sigtable
- (, A현시, B현시) ,
- .
'''
self.sigtable = self.histids.copy()
self.sigtable['init_state'] = self.sigtable['node_id'].map(self.node2init)
self.sigtable['state'] = self.sigtable['init_state'].map(lambda x:''.join(x))
for row in self.sigtable.itertuples(index=True):
node_id = row.node_id
inc_edge_A = row.inc_edge_A
inc_edge_B = row.inc_edge_B
out_edge_A = row.out_edge_A
out_edge_B = row.out_edge_B
state = copy.deepcopy(self.node2init)[node_id]
if pd.isna(inc_edge_A) or pd.isna(out_edge_A):
pass
else:
inc_edge_A = self.net.getEdge(inc_edge_A)
out_edge_A = self.net.getEdge(out_edge_A)
for conn in inc_edge_A.getConnections(out_edge_A):
index = conn.getTLLinkIndex()
if index >= 0:
state[index] = 'G'
self.sigtable.at[row.Index, 'state'] = ''.join(state)
if pd.isna(inc_edge_B) or pd.isna(out_edge_B):
pass
else:
inc_edge_B = self.net.getEdge(inc_edge_B)
out_edge_B = self.net.getEdge(out_edge_B)
for conn in inc_edge_B.getConnections(out_edge_B):
index = conn.getTLLinkIndex()
if index >= 0:
state[index] = 'G'
self.sigtable.at[row.Index, 'state'] = ''.join(state)
self.sigtable = self.sigtable.dropna(subset='state')
self.sigtable = self.sigtable.reset_index(drop=True)
self.sigtable['phase_sumo'] = self.sigtable.groupby(['node_id', 'start_unix']).cumcount()
self.sigtable = self.sigtable[['node_id', 'start_unix', 'phase_sumo', 'duration', 'state']]
# self.sigtable = self.sigtable.sort_values(by=['start_unix', 'node_id'])
self.sigtable['start_dt'] = self.sigtable['start_unix'].apply(lambda x:datetime.fromtimestamp(x))
# 5-3. 신호 파일의 시작 및 종료시각 설정
def set_timepoints(self):
self.offsets = {}
self.Sigtable = []
sim_start = self.present_time - 300
for node_id, group in self.sigtable.groupby('node_id'):
lsbs = group[group['start_unix'] < sim_start]['start_unix'].max() # the last start_unix before sim_start
self.offsets[node_id] = lsbs - sim_start
group = group[group.start_unix >= lsbs]
start_unixes = np.array(group.start_unix)
start_unixes = np.sort(np.unique(start_unixes))[:self.node2num_cycles[node_id]]
group = group[group.start_unix.isin(start_unixes)]
self.Sigtable.append(group)
self.Sigtable = pd.concat(self.Sigtable)
# 5-4. 적색 및 황색신호 부여
def assign_red_yellow(self):
'''
,
input : Sigtable
- (, ) , , ·
* .
output : SIGTABLE
- (, ) , (· )
* r, g, y .
'''
self.SIGTABLE = []
for _, group in self.Sigtable.groupby('node_id'):
new_rows_list = []
for i in range(1, len(group)):
prev_row = group.iloc[i-1:i].copy()
next_row = group.iloc[i:i+1].copy()
new_rows = pd.concat([prev_row, prev_row, next_row]).reset_index(drop=True)
new_rows.loc[0, 'phase_sumo'] = str(prev_row.phase_sumo.iloc[0]) + '_g'
new_rows.loc[0, 'duration'] = new_rows.loc[0, 'duration'] - 5
new_rows.loc[1, 'phase_sumo'] = str(prev_row.phase_sumo.iloc[0]) + '_y'
new_rows.loc[1, 'duration'] = 4
yellow_state = ''
red_state = ''
for a, b in zip(prev_row.state.iloc[0], next_row.state.iloc[0]):
if a == 'G' and b == 'r':
yellow_state += 'y'
red_state += 'r'
else:
yellow_state += a
red_state += a
new_rows.loc[2, 'phase_sumo'] = str(next_row.phase_sumo.iloc[0]) + '__r'
new_rows.loc[2, 'duration'] = 1
new_rows.loc[1, 'state'] = yellow_state
new_rows.loc[2, 'state'] = red_state
new_rows_list.append(new_rows)
next_row['phase_sumo'] = str(next_row.phase_sumo.iloc[0]) + '_g'
next_row['duration'] -= 5
new_rows_list.append(next_row)
new_rows = pd.concat(new_rows_list)
self.SIGTABLE.append(new_rows)
self.SIGTABLE = pd.concat(self.SIGTABLE).sort_values(by=['node_id', 'start_unix', 'phase_sumo'])
# 5-5. 신호파일 생성
def make_tl_file(self):
strings = ['<additional>\n']
for node_id, group in self.SIGTABLE.groupby('node_id'):
strings.append(f' <tlLogic id="{node_id}" type="static" programID="{node_id}_prog" offset="{self.offsets[node_id]}">\n')
for row in group.itertuples(index=True):
duration = row.duration
state = row.state
strings.append(f' <phase duration="{duration}" state="{state}"/>\n')
strings.append(' </tlLogic>\n')
strings.append('</additional>')
strings = ''.join(strings)
# 저장
self.path_output = os.path.join(self.path_results, f'sn_{self.present_time}.add.xml')
with open(self.path_output, 'w') as f:
f.write(strings)
# 6. 이슈사항 저장
def write_issues(self):
print('6. 이슈사항을 저장합니다.')
path_issues = os.path.join(self.path_results, "issues_generate_signals.txt")
with open(path_issues, "w", encoding="utf-8") as file:
for item in self.issues:
file.write(item + "\n")
if self.issues:
print("데이터 처리 중 발생한 특이사항은 다음과 같습니다. :")
for review in self.issues:
print(review)
def main(self):
self.time0 = datetime.now()
# 1. 데이터 준비
self.prepare_data()
self.time1 = datetime.now()
# 2. 신호이력 전처리
self.process_history()
self.time2 = datetime.now()
# 3. 이동류정보 전처리
self.process_movement()
self.time3 = datetime.now()
# 4. 통합테이블 생성
self.make_histids()
self.time4 = datetime.now()
# # 5. 신호 생성
# self.get_signals()
# self.time5 = datetime.now()
# # 6. 이슈사항 저장
# self.write_issues()
# self.time6 = datetime.now()
print('(1)', self.time1 - self.time0)
print('(1-1)', self.time11 - self.time0)
print('(1-2)', self.time12 - self.time11)
print('(1-3)', self.time13 - self.time12)
print('(1-4)', self.time14 - self.time13)
print('(1-5)', self.time15 - self.time14)
print('(2)', self.time2 - self.time1)
print('(2-1)', self.time21 - self.time1)
print('(2-2)', self.time22 - self.time21)
print('(2-3)', self.time23 - self.time22)
print('(3)', self.time3 - self.time2)
print('(3-1)', self.time31 - self.time2)
print('(3-2)', self.time32 - self.time31)
print('(4)', self.time4 - self.time3)
print('(4-1)', self.time41 - self.time3)
# print('(4-2)', self.time42 - self.time41)
# print('(5)', self.time5 - self.time4)
# print('(5-1)', self.time51 - self.time4)
# print('(5-2)', self.time52 - self.time51)
# print('(5-3)', self.time53 - self.time52)
# print('(5-4)', self.time54 - self.time53)
# print('(5-5)', self.time55 - self.time54)
# print('(6)', self.time6 - self.time5)
print('total time :', self.time41 - self.time0)
if __name__ == '__main__':
self = SignalGenerator()
self.main()
# self.path_unit = os.path.join(self.path_root, 'Analysis', '0207_unit_test')
# self.hrhists.to_csv(os.path.join(self.path_unit, 'hrhists.csv'))
# self.histids.to_csv(os.path.join(self.path_unit, 'histids.csv'))
# self.sigtable.to_csv(os.path.join(self.path_unit, 'sigtable.csv'))
# self.Sigtable.to_csv(os.path.join(self.path_unit, 'ssigtable.csv'))
# print("elapsed time :", datetime.now() - starting_time)

Loading…
Cancel
Save