码迷,mamicode.com
首页 > 其他好文 > 详细

智能交通仿真插件源程序 —— VSL-1 可变限速控制

时间:2015-09-23 14:48:53      阅读:427      评论:0      收藏:0      [点我收藏+]

标签:

   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;
}

 

智能交通仿真插件源程序 —— VSL-1 可变限速控制

标签:

原文地址:http://www.cnblogs.com/zuoyouchen/p/4831982.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!