{ "cells": [ { "cell_type": "code", "execution_count": 31, "metadata": {}, "outputs": [], "source": [ "import os\n", "import pandas as pd\n", "import numpy as np\n", "import sys\n", "sys.path.append('../../Scripts')\n", "from preprocess_daily import DailyPreprocessor\n", "from generate_signals import SignalGenerator" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "비보호좌회전, 신호우회전, 유턴\n", "\n", "줄임말 목록\n", "- `i` : 교차로번호, `inter_no`\n", "- `f` : 진입, from, `inc_edge_id`\n", "- `t` : 진출, to, `out_edge_id`\n", "- `vec` : 방향벡터, unit vector (`np.array([0.6, 0.8])`)\n", "- `dire` : 방위, direction (동, 서, 남, 북, 북동, 북서, 남동, 남서)\n", "- `rvec` : 정방향 방향벡터, unit vector to the right direction (`np.array([0,1])`)\n", "\n", "필요한 객체들 목록\n", "\n", "- `inter2dire2rvec` : `inter_no` $\\mapsto$ `dire2rvec`\n", " - `dire2rvec` : `dire` $\\mapsto$ `rvec`\n", "- `inter2incs` : `inter_no` $\\mapsto$ `inc_edge_ids`\n", "- `inter2outs` : `inter_no` $\\mapsto$ `out_edge_ids`\n", "- `inter2inc2dire` : `inter_no` $\\mapsto$ `int2dire`\n", " - `inc2dire` : `out_edge_id` $\\mapsto$ `dire`\n", "- `inter2out2dire` : `inter_no` $\\mapsto$ `out2dire`\n", " - `out2dire` : `inc_edge_id` $\\mapsto$ `dire`\n", "- `inter2inc2vec` : `inter_no` $\\mapsto$ `int2vec`\n", " - `inc2vec` : `out_edge_id` $\\mapsto$ `vec`\n", "- `inter2out2vec` : `inter_no` $\\mapsto$ `out2vec`\n", " - `out2vec` : `inc_edge_id` $\\mapsto$ `vec`\n", "\n", "좌회전 판단\n", "\n", "Given `inter_no`, `inc_edge_id` and `out_edge_id`, we have `inc_vec = inter2inc2vec[inter_no][inc_edge_id]` and `out_vec = inter2out2vec[inter_no][out_edge_id]`.\n", "Rotate `inc_vec` by 90, 180 and 270 degrees clockwise, to define \n", "`out_vec_left`, `out_vec_straight` and `out_vec_right`.\n", "Define `out_vecs={'right':out_vec_left, 'straight':out_vec_straight, 'right':out_vec_right}`.\n", "Select the key that maximize the similarity of the corresponding value of the key and `inc_vec`." ] }, { "cell_type": "code", "execution_count": 32, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "1. 데이터를 로드합니다.\n", "1-1. 네트워크가 로드되었습니다.\n", "1-2. 테이블들이 로드되었습니다.\n", "1-3. 네트워크의 모든 clean state requirement들을 체크했습니다.\n", "1-4. 테이블들의 무결성 검사를 완료했습니다.\n", "1-5. 주요 객체 (리스트, 딕셔너리)들을 저장했습니다.\n" ] }, { "data": { "text/html": [ "
\n", "\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
parent_idchild_idadj_inc_edge_idadj_out_edge_idinc_edge_idout_edge_id
0i0u00-571500487_01571500487_01571500487_02571500487_01.32
1i2u20571542811_02571542811_01571542810_01.51571542810_02
2i3u30571556450_02571556450_01571556452_01571556452_02
3i3u31-571500475_01571500475_01571500475_02571500475_01.26
4i3u32571540303_02.21571540303_01571540303_02-571540303_02
5i6u60571500535_02.18571500535_01571500535_02-571500535_02
\n", "
" ], "text/plain": [ " parent_id child_id adj_inc_edge_id adj_out_edge_id inc_edge_id \\\n", "0 i0 u00 -571500487_01 571500487_01 571500487_02 \n", "1 i2 u20 571542811_02 571542811_01 571542810_01.51 \n", "2 i3 u30 571556450_02 571556450_01 571556452_01 \n", "3 i3 u31 -571500475_01 571500475_01 571500475_02 \n", "4 i3 u32 571540303_02.21 571540303_01 571540303_02 \n", "5 i6 u60 571500535_02.18 571500535_01 571500535_02 \n", "\n", " out_edge_id \n", "0 571500487_01.32 \n", "1 571542810_02 \n", "2 571556452_02 \n", "3 571500475_01.26 \n", "4 -571540303_02 \n", "5 -571500535_02 " ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "self = DailyPreprocessor()\n", "self.load_data()\n", "self.make_match1()\n", "self.make_match2()\n", "self.make_match3()\n", "self.make_match4()\n", "self.make_match5()\n", "display(self.u_turn)" ] }, { "cell_type": "code", "execution_count": 33, "metadata": {}, "outputs": [], "source": [ "self.u_turn = pd.merge(self.u_turn, self.u_condition, on='child_id')\n", "\n", "# p2inc_edge2angle : node_id to inc_edge2angle\n", "p2inc_edge2angle = dict()\n", "# p2out_edge2angle : node_id to out_edge2angle\n", "p2out_edge2angle = dict()\n", "# p2inc_angle2edge : node_id to inc_angle2edge\n", "p2inc_angle2edge = dict()\n", "# p2out_angle2edge : node_id to out_angle2edge\n", "p2out_angle2edge = dict()\n", "for node_id in self.parent_ids:\n", " m5 = self.match5[self.match5.node_id==node_id]\n", " m5 = m5.dropna(subset=['inc_edge_id', 'out_edge_id'])\n", " # inc_edge2angle : inc_edge_id to inc_angle\n", " inc_edge2angle = dict(zip(m5.inc_edge_id, m5.inc_angle.astype(int)))\n", " p2inc_edge2angle[node_id] = inc_edge2angle\n", " # out_edge2angle : out_edge_id to out_angle\n", " out_edge2angle = dict(zip(m5.out_edge_id, m5.out_angle.astype(int)))\n", " p2out_edge2angle[node_id] = out_edge2angle\n", " # inc_angle2edge : inc_angle to inc_edge_id\n", " inc_angle2edge = dict(zip(m5.inc_angle.astype(int), m5.inc_edge_id))\n", " p2inc_angle2edge[node_id] = inc_angle2edge\n", " # out_angle2edge : out_angle to out_edge_id\n", " out_angle2edge = dict(zip(m5.out_angle.astype(int), m5.out_edge_id))\n", " p2out_angle2edge[node_id] = out_angle2edge\n", "\n", "self.uid2uindex = dict() # u_turn node id to u_turn index\n", "\n", "# 각 uturn node에 대하여 (inc_edge_id, out_edge_id) 부여\n", "cmatches = []\n", "for row in self.u_turn.itertuples():\n", " parent_id = row.parent_id\n", " child_id = row.child_id\n", " condition = row.condition\n", " inc_edge_id = row.inc_edge_id\n", " out_edge_id = row.out_edge_id\n", " adj_inc_edge_id = row.adj_inc_edge_id\n", " adj_out_edge_id = row.adj_out_edge_id\n", " \n", " # self.uid2uindex 지정\n", " inc_edge = self.net.getEdge(inc_edge_id)\n", " out_edge = self.net.getEdge(out_edge_id)\n", " u_turn_conn = inc_edge.getConnections(out_edge)[0]\n", " self.uid2uindex[child_id] = u_turn_conn.getTLLinkIndex()\n", " \n", " # match5에서 부모노드id에 해당하는 행들을 가져옴 (cmatch)\n", " cmatch = self.match5.copy()[self.match5.node_id==parent_id] # match dataframe for a child node\n", " cmatch = cmatch.sort_values(by=['phase_no', 'ring_type']).reset_index(drop=True)\n", " cmatch['node_id'] = child_id\n", "\n", " # 진입엣지 각도\n", " inc_angle = p2inc_edge2angle[parent_id][adj_inc_edge_id]\n", "\n", " # 이격각도\n", " self.angle_separation = 10\n", "\n", " # 진입로 각도 목록\n", " inc_angles = cmatch.dropna(subset=['inc_angle', 'out_angle']).inc_angle.astype(int).unique()\n", " inc_angles = np.sort(inc_angles)\n", " inc_angles = list(inc_angles - 360) + list(inc_angles) + list(inc_angles + 360)\n", " inc_angles = np.array(inc_angles)\n", "\n", " # 보행신호시의 진입로 각도\n", " inc_angles_left = inc_angles[inc_angles >= inc_angle + self.angle_separation]\n", " inc_angle_pedes = np.sort(inc_angles_left)[0] % 360\n", "\n", " # 보행신호시의 진입로 엣지id\n", " inc_angle2edge = p2inc_angle2edge[parent_id]\n", " inc_edge_id_pedes = inc_angle2edge[inc_angle_pedes]\n", "\n", " # 진출로 각도 목록\n", " out_angles = cmatch.dropna(subset=['inc_angle', 'out_angle']).out_angle.astype(int).unique()\n", " out_angles = np.sort(out_angles)\n", " out_angles = list(out_angles - 360) + list(out_angles) + list(out_angles + 360)\n", " out_angles = np.array(out_angles)\n", "\n", " # 보행신호시의 진입로 각도\n", " out_angles_right = out_angles[out_angles <= inc_angle - self.angle_separation]\n", " out_angle_pedes = np.sort(out_angles_right)[-1] % 360\n", "\n", " # 보행신호시의 진입로 엣지id\n", " out_angle2edge = p2out_angle2edge[parent_id]\n", " out_edge_id_pedes = out_angle2edge[out_angle_pedes]\n", "\n", " # 진입엣지/진출엣지 포함 조건\n", " inc_true = (cmatch.inc_edge_id==adj_inc_edge_id)\n", " out_true = (cmatch.out_edge_id==adj_out_edge_id)\n", "\n", " # 보행신호시 조건\n", " pedes_flag = (cmatch.inc_edge_id==inc_edge_id_pedes) & (cmatch.out_edge_id==out_edge_id_pedes)\n", "\n", " # 좌회전시 조건\n", " right_flag = inc_true & (cmatch.turn_type=='left')\n", "\n", " # 보행신호이동류(17) 조건\n", " crosswalk_on = (cmatch.move_no==17) & ~ out_true\n", "\n", " # 신호없음이동류(18) 조건\n", " all_redsigns = (cmatch.move_no==18) & ~ out_true\n", "\n", " # 보행신호시/좌회전시 진입/진출 엣지id 배정\n", " cmatch[['inc_edge_id', 'out_edge_id']] = np.nan\n", " if condition == \"보행신호시\":\n", " cmatch.loc[pedes_flag, ['inc_edge_id', 'out_edge_id']] = [inc_edge_id, out_edge_id]\n", " elif condition == \"좌회전시\":\n", " cmatch.loc[right_flag, ['inc_edge_id', 'out_edge_id']] = [inc_edge_id, out_edge_id]\n", "\n", " uturn_not_assigned = cmatch[['inc_edge_id','out_edge_id']].isna().any(axis=1).all()\n", "\n", " if uturn_not_assigned:\n", " # 좌회전시\n", " if right_flag.any():\n", " cmatch.loc[right_flag, ['inc_edge_id', 'out_edge_id']] = [inc_edge_id, out_edge_id]\n", " # 보행신호시\n", " elif pedes_flag.any():\n", " cmatch.loc[pedes_flag, ['inc_edge_id', 'out_edge_id']] = [inc_edge_id, out_edge_id]\n", " # 보행신호이동류(17) 발생시\n", " elif crosswalk_on.any():\n", " cmatch.loc[crosswalk_on, ['inc_edge_id', 'out_edge_id']] = [inc_edge_id, out_edge_id]\n", " # 신호없음이동류(18) 발생시\n", " elif all_redsigns.any():\n", " cmatch.loc[all_redsigns, ['inc_edge_id', 'out_edge_id']] = [inc_edge_id, out_edge_id]\n", " # 진출엣지 미포함시\n", " elif out_true.any():\n", " cmatch.loc[~ out_true, ['inc_edge_id', 'out_edge_id']] = [inc_edge_id, out_edge_id]\n", " cmatches.append(cmatch)\n", "\n", "# 각 연등교차로(coordination node)에 대하여 (inc_edge_id, out_edge_id) 부여\n", "self.coord['inter_no'] = self.coord['parent_id'].map(self.node2inter)\n", "self.coord = self.coord.rename(columns={'child_id':'node_id'})\n", "self.coord[['inc_dire', 'out_dire', 'inc_angle','out_angle']] = np.nan\n", "self.coord['move_no'] = 20\n", "self.coord = self.coord[['inter_no', 'phase_no', 'ring_type', 'move_no', 'inc_dire', 'out_dire', 'inc_angle','out_angle', 'inc_edge_id', 'out_edge_id', 'node_id']]\n", "\n", "cmatches = pd.concat(cmatches)\n", "self.match6 = pd.concat([self.match5, cmatches, self.coord]).drop_duplicates().sort_values(by=['inter_no', 'node_id', 'phase_no', 'ring_type'])\n", "self.match6 = self.match6.reset_index(drop=True)" ] }, { "cell_type": "code", "execution_count": 36, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "u00 4\n", "\n", "u20 2\n", "\n", "u30 4\n", "\n", "u31 4\n", "\n", "u32 7\n", "\n", "u60 8\n", "\n" ] } ], "source": [ "for child_id in self.u_turn_ids:\n", " print(child_id, self.uid2uindex[child_id])\n", " print()" ] } ], "metadata": { "kernelspec": { "display_name": "sts", "language": "python", "name": "sts" }, "language_info": { "codemirror_mode": { "name": "ipython", "version": 3 }, "file_extension": ".py", "mimetype": "text/x-python", "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", "version": "3.8.10" } }, "nbformat": 4, "nbformat_minor": 2 }