标签:
The VSL-1 algorithm is an effective variable speed limit control method which can minimize the standing queue length before a work zone by reducing approaching traffic speed aiming to minimize the difference between the upstream flow rate and the downstream flow rate of a segment near the work zone.
#include <stdlib.h> #include <stdio.h> #include <string.h> #include <math.h> #include "programmer.h" /*----------------------------------------------------------------------------------------------- * Data : 2014-8-5 * Developer: Karel Zuo * Project: Variable Speed Limit Controls-1 on Work Zone Operation * e-mail: m15712980185@163.com * *-------------------------------------------------------------------------------------------------*/ #define nomorl_Speed 25.0f #define sum 6 #define SUM 4 static float T; static float q[2][5]; static float Q[2][5]; static float a = 0.95f; static float b = 0.95f; static float p = 0.25f; static float r[3][5]; static float q_Control[5]; static float d = 0.0f; static float u[3][5]; static float v[3][5]; static float curTime = 0.0f; static float t = 0.0f; static float L = 0.125f; static int links = 0; static int k = 0; static bool flag_useVSL;//该变量用于表示该路段是否使用VSL,使用为PTRUE,不使用为PFALSE。 static bool flag_onVSL;//改变量表示这一个小时内是否开启VSL,开启为PTRUE,不使用为PFALSE。 static int scheduel[3][24];//用于获取并记录当前要执行的施工作业方案 char *controlLINK1 = "67:52"; static float min_Q[2] = {0.0f,0.0f}; static float min_q[2] = {0.0f,0.0f}; static float min_u[3] = {0.0f,0.0f}; static float min_d = 0.0f; static void Module_1(); static void Module_2(); static void Controller(int k); static void SensorReader(int k); static float compute_TW_flow(float b,float per_Q,float cur_Q); static float compute_SW_flow(float a,float WorkZone_q,float nearWorkZone_q); static float compute_targetDensity(float per_d,float WorkZone_q, float nearWorkZone_q,float t,float nearWorkZone_L); static float compute_targetControlSpeed(float nearWorkZone_v,float approaching_u, int n,int i); static float compute_ComplianceRatio(float control_v ,float detected_v); static float compute_nextControlSpeed(float cur_r,float curControl_v); static bool getVSLCommand(); static void getScheduel(); void qpx_NET_postOpen(void) { links = 3; T = 300.0f; t = 60.0f; k = 0; d = 0.0f; flag_useVSL = getVSLCommand(); } void qpx_NET_minute(void) { qps_GUI_printf("Wether peform this kind of VSL:%d ",(int)flag_useVSL); if(flag_useVSL) { curTime = qpg_CFG_simulationTime(); qps_GUI_printf("Current Time = %d ",(int)curTime); qps_GUI_printf("Restiction:%d ",qpg_LNK_laneRestriction(qpg_NET_link(controlLINK1),1)); qps_GUI_printf("Lanes is:%d ",qpg_LNK_lanes(qpg_NET_link(controlLINK1))); qps_GUI_printf("hazard is:%d ",qpg_LNK_hazard(qpg_NET_link(controlLINK1))); bool closure = PFALSE; int c; for(c=1;c<=qpg_LNK_lanes(qpg_NET_link(controlLINK1));c++) { if(qpg_LNK_laneRestriction(qpg_NET_link(controlLINK1),c) == -1) closure = PTRUE; } if(closure) { qps_GUI_printf("The link has closeure some lanes!!!"); if((int)curTime % (int)T == 0 && curTime >= T) k = 0; SensorReader(k); if(k==0) Module_1(); else Module_2(); Controller(k); k++; } } } // Module 1 function is used to compute the initial speed of each VSL sign void Module_1() { //测试语句: qps_GUI_printf("Perform Module 1 .............................................."); // Perform step 1 q[0][k] = compute_TW_flow(b,Q[0][4],Q[0][k]); q[1][k] = compute_TW_flow(b,Q[1][4],Q[1][k]); //Perform step 2 q_Control[k] = compute_SW_flow(a,q[0][k],q[1][k]); //Perform step 3 d = compute_targetDensity(d,q[0][k],q[1][k],t,L); if(d < 0.0f) d = 0.0f; //Perform step 4 if(d*q_Control[k] == 0.0f) v[1][k] = nomorl_Speed; else v[1][k] = q_Control[k]/d; if(v[1][k] < 0.0f) { //测试语句: qps_GUI_printf("q_Control[k]: %f",q_Control[k]); qps_GUI_printf("d: %f",d); } //测试语句: qps_GUI_printf("Initial v[1][k]: %f",v[1][k]); //Perform step 5 int i; for(i = 0; i < links; i++) { v[i][k] = compute_targetControlSpeed(v[1][k],u[2][k],links,i); //测试语句 qps_GUI_printf("VMS Speed Limit, v[][]is: %f",v[i][k]); } } //Module2 function is used to update the displayed speeds in each VMS void Module_2() { //测试语句: qps_GUI_printf("Perform Module 2 ..........................................."); qps_GUI_printf("Current ‘q[0][]‘ =: %f %f %f ",q[0][0],q[0][1],q[0][2]); qps_GUI_printf("Current ‘q[1][]‘ =: %f %f %f ",q[1][0],q[1][1],q[1][2]); qps_GUI_printf(""); qps_GUI_printf("per-Speed , v[][]is= %f %f %f ",v[0][k-1],v[1][k-1],v[2][k-1]); if(k <= 5) { for(int i = 0; i < links; i++) { if( u[i][k-1] == 0.0f) r[i][k] = 1.0f; else r[i][k] = compute_ComplianceRatio(v[i][k-1],u[i][k]); v[i][k] = compute_nextControlSpeed(r[i][k],v[i][k-1]); } //测试语句: qps_GUI_printf("Current ‘r[][]‘ =: %f %f %f ",r[0][k],r[1][k],r[2][k]); qps_GUI_printf("Current ‘u[i][k]‘ =: %f %f %f ",u[0][k],u[1][k],u[2][k]); qps_GUI_printf("Current ‘new_v[i][k]‘ =: %f %f %f ",v[0][k],v[1][k],v[2][k]); } } // (module1-Step 1)This function is used to compute time weighted flow rate float compute_TW_flow(float b,float per_Q,float cur_Q) { float TW_q; TW_q = (b*per_Q + (1-b)*cur_Q); return TW_q; } // (module1-Step 2)This function is used to compute space weighted transition flow float compute_SW_flow(float a,float WorkZone_q,float nearWorkZone_q) { float SW_flow; SW_flow = a*WorkZone_q+(1-a)*nearWorkZone_q; if(SW_flow <0) SW_flow = 0.0f; return SW_flow; } // (module1-Step 3)This function is used to compute target density float compute_targetDensity(float per_d,float WorkZone_q,float nearWorkZone_q,float t,float nearWorkZone_L) { float cur_d; t = t/3600; nearWorkZone_L = nearWorkZone_L/1000; cur_d = per_d + (WorkZone_q - nearWorkZone_q)*t / nearWorkZone_L; if(cur_d < 0.0f) cur_d = 0.0f; return cur_d; } // (module1-Step 5) This function is used to compute target speed float compute_targetControlSpeed(float nearWorkZone_v,float approaching_u,int n,int i) { float the_v ; the_v = nearWorkZone_v +(approaching_u - nearWorkZone_v)*(i-1)/(n-1); return the_v; } //(module2-step 1) This function is used to compute compliance ratio // based on detected speed and control speed float compute_ComplianceRatio(float control_v ,float detected_u) { float r; r = control_v / detected_u; return r; } //(module2-step2) This function is used to compute control speed for next time interval float compute_nextControlSpeed(float cur_r,float curControl_v) { float nextControl_v; nextControl_v = cur_r*curControl_v; return nextControl_v; } // Controller function is used to display limit speed in each VMS void Controller(int k) { //测试语句: qps_GUI_printf("Controll the VMS and Speed limit!"); LINK* LNK0 = qpg_NET_link(controlLINK1); LINK* LNK1 = qpg_LNK_backside(LNK0); LINK* LNK2 = qpg_LNK_backside(LNK1); int index_LNK[3] = {qpg_LNK_index(LNK0),qpg_LNK_index(LNK1),qpg_LNK_index(LNK2)}; //LINK* LNK3 = qpg_LNK_backside(LNK2); int VMS0 = qpg_LNK_beaconIndexByIndex(LNK0,1); int VMS1 = qpg_LNK_beaconIndexByIndex(LNK1,1); int VMS2 = qpg_LNK_beaconIndexByIndex(LNK2,1); int index_VMS[3] = {VMS0,VMS1,VMS2}; //DETECTOR* DET3 = qpg_NET_detectorByIndex(qpg_LNK_detectorIndexByIndex(LINK* LNK3,1)); int i; for(i=0;i<3;i++) { if(v[i][k] >= 60.0f) v[i][k] = 60.0f; if(v[i][k] <= 10.0f) v[i][k] = 10.0f; qps_BCI_message(index_VMS[i],"%d ",(int)v[i][k]); qps_LNK_speedlimit(qpg_NET_linkByIndex(index_LNK[i]),v[i][k]); //测试语句: qps_GUI_printf("VMS:%d Reduce Speed to:%d ",index_VMS[i],(int)v[i][k]); } //测试语句: qps_GUI_printf("Check the VMS:%s ‘V‘ = %s ",qpg_BCN_name(qpg_NET_beaconByIndex(index_VMS[0])),qpg_BCN_message(qpg_NET_beaconByIndex(index_VMS[0]))); qps_GUI_printf("Check the VMS:%s ‘V‘ = %s ",qpg_BCN_name(qpg_NET_beaconByIndex(index_VMS[1])),qpg_BCN_message(qpg_NET_beaconByIndex(index_VMS[1]))); qps_GUI_printf("Check the VMS:%s ‘V‘ = %s ",qpg_BCN_name(qpg_NET_beaconByIndex(index_VMS[2])),qpg_BCN_message(qpg_NET_beaconByIndex(index_VMS[2]))); } //This function is used to get data of sensor every minute. void SensorReader(int k) { //测试语句: qps_GUI_printf("Read the data which be get by detector"); LINK* LNK0 = qpg_NET_link(controlLINK1); LINK* LNK1 = qpg_LNK_backside(LNK0); L = qpg_LNK_length(LNK1); //测试语句: qps_GUI_printf("L = %f ",L); Q[0][k] = min_Q[0]/60; Q[1][k] = min_Q[1]/60; u[0][k] = min_u[0]/60; u[1][k] = min_u[1]/60; u[2][k] = min_u[2]/60; //d = min_d/60; qps_GUI_printf("density by loop is:%f ",min_d/60); min_Q[0] = 0.0f; min_Q[1] = 0.0f; min_q[0] = 0.0f; min_q[1] = 0.0f; min_u[0] = 0.0f; min_u[1] = 0.0f; min_u[2] = 0.0f; min_d = 0.0f; //测试语句: qps_GUI_printf("Obtain the parameters:"); qps_GUI_printf("Q[0][%d]: %f ",k,Q[0][k]); qps_GUI_printf("Q[1][%d]: %f ",k,Q[1][k]); qps_GUI_printf("u[0]: %f ",u[0][k]); qps_GUI_printf("u[1]: %f ",u[1][k]); qps_GUI_printf("u[2]: %f ",u[2][k]); } //该函数用于计算一分钟内的各项所需数据 void qpx_NET_second(void) { //测试语句: //qps_GUI_printf("Obtain the average value of all parameters"); LINK* LNK0 = qpg_NET_link(controlLINK1); LINK* LNK1 = qpg_LNK_backside(LNK0); LINK* LNK2 = qpg_LNK_backside(LNK1); //LINK* LNK3 = qpg_LNK_backside(LNK2); //测试语句: DETECTOR* DET0 = qpg_NET_detectorByIndex(qpg_LNK_detectorIndexByIndex(LNK0,1)); DETECTOR* DET1 = qpg_NET_detectorByIndex(qpg_LNK_detectorIndexByIndex(LNK1,1)); DETECTOR* DET2 = qpg_NET_detectorByIndex(qpg_LNK_detectorIndexByIndex(LNK2,1)); //DETECTOR* DET3 = qpg_NET_detectorByIndex(qpg_LNK_detectorIndexByIndex(LINK* LNK3,1)); int lanes0 = qpg_LNK_lanes(LNK0); int lanes1 = qpg_LNK_lanes(LNK1); int lanes2 = qpg_LNK_lanes(LNK2); //int lanes3 = qpg_LNK_lanes(LNK3); int i; L = qpg_LNK_length(LNK1); float sec_Q[2]= {0.0f,0.0f}; float sec_u[3]= {0.0f,0.0f}; float sec_d = 0.0f; int count0 = 0; int count1 = 0; for(i=1;i<=lanes0;i++) { sec_Q[0] += qpg_STA_flow(LNK0, i); count0 = qpg_DTL_count(qpg_DTC_multipleLoop(DET0,i),APILOOP_INCOMPLETE); } min_Q[0] += sec_Q[0]; for(i=1;i<=lanes1;i++) { sec_Q[1] += qpg_STA_flow(LNK1, i); count1 = qpg_DTL_count(qpg_DTC_multipleLoop(DET1,i),APILOOP_INCOMPLETE); } min_Q[1] += sec_Q[1]; for(i=1;i<=lanes0;i++) sec_u[0] += qpg_DTL_speed(qpg_DTC_multipleLoop(DET0,i),APILOOP_COMPLETE); sec_u[0] = sec_u[0]/lanes0; min_u[0] += sec_u[0]; for(i=1;i<=lanes1;i++) sec_u[1] += qpg_DTL_speed(qpg_DTC_multipleLoop(DET1,i),APILOOP_COMPLETE); sec_u[1] = sec_u[1]/lanes1; min_u[1] += sec_u[1]; for(i=1;i<=lanes2;i++) sec_u[2] += qpg_DTL_speed(qpg_DTC_multipleLoop(DET2,i),APILOOP_COMPLETE); sec_u[2] = sec_u[2]/lanes2; min_u[2] += sec_u[2]; for(i=1;i<lanes1;i++) sec_d += qpg_STA_density(LNK1,i); min_d += sec_d; } //该方法用于获取GA程序中对VSL控制的指令 bool getVSLCommand() { FILE *file_simuTimes; FILE *file_command_VSL; int curSimuTimes; bool flag = PFALSE; file_simuTimes = fopen("C:\\Users\\Public\\paramics\\data\\bjtu\\GA-Simulation data\\simulation times.txt","rt"); fscanf(file_simuTimes,"%d",&curSimuTimes); fclose(file_simuTimes); int command_VSL[SUM][sum]; int i,j; file_command_VSL = fopen("C:\\Users\\Public\\paramics\\data\\bjtu\\GA-Simulation data\\command_VSL.txt","rt"); for(i=0;i<SUM;i++) { for(j=0;j<sum;j++) { fscanf(file_command_VSL,"%d ",&command_VSL[i][j]); } } qps_GUI_printf("Read the VSL command:"); int s; for(s=0;s<SUM;s++) { qps_GUI_printf("%d %d %d %d %d %d ", command_VSL[s][0], command_VSL[s][1], command_VSL[s][2], command_VSL[s][3], command_VSL[s][4], command_VSL[s][5]); } if(command_VSL[(curSimuTimes+SUM-1)%4][0] == 1) { flag = PTRUE; } else { flag = PFALSE; } return flag; }
标签:
原文地址:http://www.cnblogs.com/zuoyouchen/p/4831982.html