NTNUJAVA Virtual Physics Laboratory
Enjoy the fun of physics with simulations!
May 01, 2016, 09:37:29 am *
Welcome, Guest. Please login or register.
Did you miss your activation email?

Login with username, password and session length
 
   Home   Help Search Login Register  
"Reflect, review and renew constantly." ...Wisdom
Google Bookmarks Yahoo My Web MSN Live Netscape Del.icio.us FURL Stumble Upon Delirious Ask FaceBook

Pages: [1]   Go Down
  Print  
Author Topic: Can we increase traffic flow rate by increasing maximum speed limit?  (Read 18934 times)
0 Members and 1 Guest are viewing this topic. Click to toggle author information(expand message area).
Fu-Kwun Hwang
Administrator
Hero Member
*****
Offline Offline

Posts: 3072



WWW
«
Embed this message
on: July 30, 2008, 10:29:42 am » posted from:Taipei,T\'ai-pei,Taiwan

Registed user can get files related to this applet for offline access.
Problem viewing java?Add http://www.phy.ntnu.edu.tw/ to exception site list
If java program did not show up, please download and install latest Java RUN TIME
There are 2 translations,
Higher number at the end means more translation been done.
or


Is it possible to increase the traffic flow by increasing the maximum allowed speed on the road?
The answer is NO. Due to reaction time, we need to keep the car in front of us a minimum distance.
If the reaction time is dt, and the speed of the car is v. You need to keep at least s=v*dt to be safe.
If the car is moving faster, the safety distance need to be increase proportionally.

There are 3 lanes in the following applet. The maximum speed Vmax for each lanes are different.
You can change Vmax, if you click Vmax label in the applet and enter your value into the textfield at the top.
Remember to hit ENTER when you are done (and the applet will accept your new value).
Nmax is the allowed maximum of cars on the road.
N is the current number of cars on the road, and n is the total number of cars pass the right edge.
I hope you can enjoy the related physics!



Related topic: Reaction time measurement , Reaction time and car accident, Traffic Light System


Registed user can get files related to this applet for offline access.
Problem viewing java?Add http://www.phy.ntnu.edu.tw/ to exception site list
If java program did not show up, please download and install latest Java RUN TIME
There are 2 translations,
Higher number at the end means more translation been done.
or


*** There are 1 more attached files. You need to login to acces it!
Logged
kidashley25
Newbie
*
Offline Offline

Posts: 4

«
Embed this message
Reply #1 on: June 29, 2010, 08:45:03 am » posted from:Ugong Norte,Quezon City,Philippines

Speed limits could be reduced or increased. Local speed limits are determined by Roads Service traffic. Make sure the exterior of your car is clean, but also focus on the interior.


-*-
Logged
GTRR
Newbie
*
Offline Offline

Posts: 1

«
Embed this message
Reply #2 on: August 30, 2010, 05:16:48 pm » posted from:Angeles,Angeles,Philippines

hmmm...interesting! I think it is good to study it more.
Logged
laramsf
Newbie
*
Offline Offline

Posts: 5

«
Embed this message
Reply #3 on: May 15, 2013, 03:20:40 am » posted from:Chicago,Illinois,United States

plz can u give me source code of traffic light system
Logged
Fu-Kwun Hwang
Administrator
Hero Member
*****
Offline Offline

Posts: 3072



WWW
«
Embed this message
Reply #4 on: May 15, 2013, 10:32:28 am » posted from:,,Satellite Provider

The source code is available as attached file.
It is also listed as following
Quote
import java.awt.*;

public class traffic extends java.applet.Applet implements Runnable{
   int yOffset=40;
   TextField iField;   //record time elapse
   double time=0.0,ts=0.;
   Dimension area;
   int N=3;
   //Rectangle   R[]=new Rectangle[N],L[]=new Rectangle[N];
   //Rectangle   R2[]=new Rectangle[N],L2[]=new Rectangle[N];
   //boolean Rs[]=new boolean[N],Ls[]=new boolean[N];
   Image bgImage,fgImage;
   Graphics gb,g;//background drawing
   Color bgColor=Color.lightGray;
   car c[]=new car[N];
   Label XY;
   String rts,STR[]={"Reset","Time"};
   public void init() {
      setBackground(bgColor);
      for(int i=0;i         if((rts=getParameter(STR))!=null)
            STR=new String(rts);
      }
      Panel p=new Panel();
//      p.add(new Label(STR[1]));
//      p.add(timeField=new TextField("0.0",3));
//      timeField.setEditable(false);
      p.add(new Button(STR[0]));
      p.add(iField=new TextField("",3));
      iField.setEditable(false);
      p.add(XY=new Label("(  X  ,  Y  )"));
      //p.add(new Button("Start"));
      add("North",p);
      area=size();
      area.height-=yOffset;
      reset(true);// false for auto start
   }

   public boolean action(Event ev, Object arg) {
      if (ev.target instanceof Button) {
         String label = (String)arg;
         if(label.equals("Reset")){
            reset(true);
         }/*else if(label.equals("Start")){
            running=true;
            start();
         }*/
      }else if(ev.target==iField&&changed!=null){
         double val=Double.valueOf(iField.getText()).doubleValue();
         if(mode            int dval=5;
            if(val>dval)dval=(int)val;
            if(clickCount==2){
               for(int i=0;i                  car.maxCount=dval;
               }
            }else   car.maxCount[mode]=dval;
         }else{//Vmax
            val=Math.abs(val);
            if(clickCount==2){
               for(int i=0;i                  car.vmax=val;
               }
            }else   car.vmax[mode%N]=val;
         }
         changed=null;
      }
      return true;
   }
   int xx,yy;
   public void reset(boolean status){
      time=0.;
      clear(status);
   }
   String d2String(double value){
      float f=(float)((int)(value*100.)/100.);
      String str=String.valueOf(f);
      if(str.indexOf(".")==-1)str+=".0";
      return str;
   }
   // animation code
   boolean running=true;
   Thread animThread;
   long startTime=0,lastTime;
   long delay=50,delta;
   //  This starts the threads.
   public void start(){
      //Start animating!
      if (animThread == null) {
         animThread = new Thread(this);
         animThread.start();
      }
      //Remember the starting time. of thread
      lastTime=startTime = System.currentTimeMillis();
   }
    public void stop() {
      //Stop the animating thread.
      animThread = null;
      running=false;
   }

   public void run() {
      //Just to be nice, lower this thread's priority
      Thread.currentThread().setPriority(Thread.MIN_PRIORITY);
      //This is the animation loop.
      while (Thread.currentThread() == animThread) {
         //Advance the animation frame. with delta time
         delta=System.currentTimeMillis()-lastTime;
         lastTime+=delta;
         if(running)advanced(delta/1000.);
         startTime+=delay;
         try {
            animThread.sleep(Math.max(0,startTime-System.currentTimeMillis()));
         } catch (InterruptedException e) {
            break;
         }
      }
   }
   void advanced(double dt){
      for(int i=0;i         c.advanced(dt);
      time+=dt;
      ts+=dt;
      if(ts>1.){
         ts-=1.;
         //timeField.setText(String.valueOf(time));
      }
      repaint();
   }
   boolean rightClick=false;
   Color cpass=Color.green,cstop=Color.red;
   int mode;// 0-2:Nmax,3-5:Vmax,6-8:N
   int clickCount;
   int xs,ys;
   public boolean mouseDown(Event e, int x, int y){
      if((y-=yOffset)<0)return false;
      clickCount=e.clickCount;
      if(e.modifiers==Event.META_MASK){//"Right Click, ";
         rightClick=true;
         running=!running;
         car.running=running;
         repaint();
      }else{
         rightClick=false;
         changed=null;
         if(x         for(int i=0;i            if(carNmax.inside(x,y)){
               mode=i;
               changed=carNmax;
               break;
            }else   if(carVmax.inside(x,y)){
               mode=N+i;
               changed=carVmax;
               break;
            //}else   if(carN.inside(x,y)){
            //   mode=2*N+i;
            //   changed=carN;
            //   break;
            }
         }
         if(changed!=null)iField.setEditable(true);//requestFocus();
         else iField.setEditable(false);
      }
      xs=x;
      ys=y;
      return true;
   }
   public boolean mouseMove(Event e, int x, int y){
      if((y-=yOffset)<0||running)return false;
      XY.setText("("+x+", "+y+")");
      return true;
   }

   public boolean mouseDrag(Event e, int x, int y){
      if((y-=yOffset)<0||running)return false;
      XY.setText("("+(xs-x)+", "+(y-ys)+")");
      return true;
   }
   /*public boolean mouseUp(Event e, int x, int y){
      if((y-=yOffset)<0)return false;
      return true;
   }*/
   FontMetrics fm;
   int chy,chy2;
   int w=10,w2=2*w,dy,dx,dy2,xi,xf;
   Rectangle carNmax[]=new Rectangle[N];
   Rectangle carVmax[]=new Rectangle[N];
   //Rectangle carN[]=new Rectangle[N];
   Rectangle changed;
   static int ds=80;
   void clear(boolean status){
      if(g==null){
         bgImage = createImage(area.width, area.height);
         gb = bgImage.getGraphics();
         fgImage = createImage(area.width, area.height);
         g = fgImage.getGraphics();
         fm=gb.getFontMetrics();
         chy=fm.getHeight();
         chy2=chy*2;
         car.init(g,w,area.width,area.height);
         dy=area.height/N;
         dy2=dy-w2;
         dx=area.width-4*w;
         yy=0;
         xi=w+1;
         xf=area.width-w;
         int dd=dy2+xi;
         for(int i=0;i         /*   R=new Rectangle(xf,yy,xi,w);
            R2=new Rectangle(xf,yy+dd,xi,w);
            L=new Rectangle(0,yy+dd,xi,w);
            L2=new Rectangle(0,yy,xi,w);*/
            carNmax=new Rectangle(xx=car.xi2,yy=car.yi2+chy,ds,chy);
            //carN=new Rectangle(xx+ds,yy,ds,chy);
            carVmax=new Rectangle(xx,yy+chy,ds,chy);
         }
      }else if(status)car.init(g,w,area.width,area.height);
      gb.setColor(bgColor);
      gb.fillRect(0, 0, area.width, area.height);
      gb.setColor(Color.black);
      gb.drawLine(0,0,area.width-1,0);
      gb.drawRect(0,area.height-1,area.width-1,area.height-1);
      yy=w;
      for(int i=0;i         gb.drawRect(0,yy,w,dy2);
         gb.drawRect(w2,yy,dx,dy2);
         gb.drawRect(area.width-w,yy,w,dy2);
         c=new car(i,0);
         car.top=c;
         car.loop=false;
      }
      gb.setColor(cstop);
/*      for(int i=0;i         Rs=true;
         Ls=true;
         drawRect(gb,R);
         drawRect(gb,L);
      }*/
      gb.setColor(Color.gray);
      yy-=(dy+w);
      int yy2=yy-dy;
      for(int i=0;i         gb.drawLine(i,yy,i+w,yy);
         gb.drawLine(i,yy2,i+w,yy2);
      }
   }
//   void drawRect(Graphics g,Rectangle r){
//      g.fillOval(r.x,r.y,r.width,r.height);
//   }
   public void paint(Graphics gs){
         update(gs);
   }
   public void update(Graphics gs){
      g.drawImage(bgImage, 0, 0, this);
      g.drawString(STR[1]+d2String(time),area.width/2,25);
      for(int i=0;i.draw();
      if(changed!=null){
         g.setColor(Color.white);
         if(clickCount==2){
            int dh;
            if(mode            for(int i=0;i               g.fillRect(changed.x,carNmax.y+dh,changed.width,changed.height);
            }
         }   else g.fillRect(changed.x,changed.y,changed.width,changed.height);
      }
      g.setColor(Color.gray);
      for(int i=0;i         g.drawString("Nmax="+car.maxCount,xx=carNmax.x,yy=carNmax.y+chy);
         g.drawString("N="+car.count,xx+ds,yy);
         g.drawString("Vmax="+car.vmax,xx,yy+=chy);
         g.drawString("n="+car.passed,xx+ds,yy);
      }
      // drawing work
      gs.drawImage(fgImage, 0, yOffset, this);
   }
}

class car extends rk4{
   static int N=3,size,size2,size3,size0;
   static int xmax,xmin,dy2;
   static double ai=10.,vmax[]={20.,30.,40.};   // reaction time set to 1.0 sec
   static double reactionTime=0.5,dmin[]=new double[N]
      ,dmin2[]=new double[N],dmax[]=new double[N];
   static int xi,xf,yi[]=new int[N],yf[]=new int[N];
   static int xi2,xf2,xi3,xf3,yi2[]=new int[N],yf2[]=new int[N];
   static int maxCount[]={20,20,20},count[]={0,0,0},passed[]={0,0,0};
   static car top[]=new car[3];
   static boolean loop[]={false,false,false};
   static double delta;
   static car tmp=null;
   static Graphics g;
   //static boolean lastTurn=false;
   int mode=0;// right,down,left,up
   boolean turn=false;
   boolean gone=false;
   static boolean debug=false,running=true;
   int X,Y,id;
   double a;
   car next=null;
   double accelerated=1.,sign=1.;
   //static int width=8,height=5;
   car(int idi,int modei){
      init(2,true);// 1D motion
      id=idi;
      mode=modei;
      y[1]=vmax[id]/3.;//*Math.random();
      if(mode==0){
         Y=yi[id];
         y[0]=xmin;
         a=ai;
         sign=1.;
      }else{
         mode=2;
         Y=yf[id];
         y[0]=xmax;
         a=-ai;
         sign=-1.;
         y[1]=-y[1];
      }
      count[id]++;
      gone=false;
   }
   static void init(Graphics gi,int w,int width,int height){
      int y0=(int)(w/4.+0.5);
      xmax=width;
      xmin=0;
      g=gi;
      size=w/2;
      size0=size/2;
      size2=w;
      size3=w*3/2;
      xi=w+size-y0;
      xf=width-w-size-y0;
      xi2=xi+size2;
      xf2=xf-size2;
      xi3=xi2+size2;
      xf3=xf2-size2;
      height/=3;
      int dy=height-w;
      dy2=dy/2;
      running=true;
      for(int i=0;i         yi=y0;
         yf=yi+dy;
         yi2=yi+size;
         yf2=yf-size;
         setRange(i);
         count=0;
         passed=0;
      }
   }
   static void setRange(int i){
      dmin=vmax*reactionTime;
      if(dmin=size2;
      dmin2=dmin/2.;
      if(dmin2=size2;
      dmax=dmin2+size2;
   }
   public void derivs(double x,double y[],double dydx[]){
      dydx[0]=y[1];
      dydx[1]=a; //
   }
   void advanced(double dt){
     //try{
      switch(mode){//處理車子轉彎
      case 0://right
         X=(int)y[0];
         if(gone)break;//離開
         //if(X>xf3&&y[0]!=0.)y[1]=-ai;
         //else
         if(y[0]>xf){
            if(this!=top[id]&&next!=null && Math.random()>0.5){//非頭尾則決定是否離開
               gone=true;
               y[1]=vmax[id];//快速通過
               //if(next!=null && next.y[1]==0.)next.a=next.sign*ai;
            }else{//轉彎
               y[0]=yi[id];
               y[1]=y[1]/2.;// 慢
               a=ai;
               mode++;
               sign=1.;
               X=xf;
            }
            //if(next!=null )next.turn=true;
            break;
         }else if(y[0]>xf2&&next!=null&&next.mode==3)next.turn=true;
         //if(turn&&X>xf2)y[1]/=2.;//前一個尚在轉彎,慢
         if(next!=null&&next.turn){//在轉彎口
             if(X>xi2){
                next.turn=false;//離開轉彎口
                if(next.y[1]==0.)next.a=next.sign*ai;
             }else if(y[1]==0. && next.mode==3 && next.Y               next.y[1]=0.;
               next.a=0.;
            }
         }
         break;
      case 1://down    
         if(y[0]>yf[id]){//必然會轉彎
            y[0]=xf;
            a=-ai;
            mode++;
            y[1]=-y[1]/2.;
            Y=yf[id];
            sign=-1.;
            //if(next!=null )next.turn=true;
            break;
         }else   {
            Y=(int)y[0];
            if(y[0]>yf2[id]&&next!=null&&next.mode==0)next.turn=true;
         }
         //if(turn && Y>yf2[id])y[1]/=2.;
         if(next!=null&&next.turn){//是否前一車仍在轉彎
            if(Y>yi2[id]){
               next.turn=false;
               if(next.y[1]==0.)next.a=next.sign*ai;
            }else if(y[1]==0. &&next.mode==0&& next.X>xf2){//卡住後車暫停
               next.y[1]=0.;
               next.a=0.;
            }
         }
         break;
      case 2://left
         X=(int)y[0];
         if(gone)break;
         //if(X         //else
         if(y[0]            if(this!=top[id] && next!=null&& Math.random()>0.5){
               gone=true;
               y[1]=-vmax[id];
            //   if(next==null&&top[id].y[0]==0.]top[id].y[1]=top[id].sign*ai;
               //if(next!=null && next.y[1]==0.)next.a=next.sign*ai;
            }else{
               y[0]=yf[id];
               y[1]/=2.;
               a=-ai;
               mode++;
               sign=-1.;
               X=xi;
            }
            if(next==null)top[id].a=top[id].sign*ai;
            //if(next!=null)next.turn=true;
            if(this==top[id])loop[id]=true;//繞一圈
            break;
         }else if(y[0]         //if(turn && X         if(next!=null&&next.turn){
            if(X               next.turn=false;
               if(next.y[1]==0.)next.a=next.sign*ai;
            }else if(y[1]==0. &&next.mode==1&& next.Y>yf2[id]){
               next.y[1]=0.;
               next.a=0.;
            }
         }
         break;
      case 3://up
         if(y[0]            y[0]=xi;
            a=ai;
            mode=0;
            sign=1.;
            y[1]=-y[1]/2.;
            Y=yi[id];
            //if(next!=null )next.turn=true;
            break;
         }else{
            Y=(int)y[0];
            if(y[0]         }
         //if(turn && Y         if(next!=null&&next.turn){
            if(Y               next.turn=false;
               if(next.y[1]==0.)next.a=next.sign*ai;
            }else if(y[1]==0. &&next.mode==2 && next.X               next.y[1]=0.;
               next.a=0.;
            }
         }
         if(next==null&&turn&&top[id].y[1]==0.)
            top[id].a=top[id].sign*ai;
         break;
      }
    //} catch (NullPointerException e){ }
/*
    if(gone){
       y[0]+=y[1]*dt;
       if(next!=null){
          next.a=sign*ai;
          next.advanced(dt);
       }else {
          top[id].a=sign*ai;
       }
       return;
      }*/
      //if(y[1]==0.)a=0.;
      //等新車
      if(count[id]         y[0]=yi2[id]+dmin2[id];
         y[1]=0.;
         a=0.;
      }else if(a!=0.){
         nextmove(dt);
         if(Math.abs(y[1])>vmax[id]){//達到最高速維持等速度運動
            y[1]=sign*vmax[id];
            a=0.;
         }
      }   else y[0]+=y[1]*dt;//等速度運動
      if(y[1]*sign<0.){//反向運動則停止
         y[1]=0.;
         a=0.;
      }
      
      if(next!=null){//非最後一輛
         if(next.gone){//不理會離開車輛
            next.a=sign*ai;
         }else if(next.mode==mode){//同一車道
            delta=sign*(y[0]-next.y[0]);//距離
            if(delta>dmax[id])next.accelerated=1.0; // 太遠
            else if(Math.abs(delta)                  next.y[1]=0.;
                  next.accelerated=0.;
            }else if(sign*(next.y[1]-y[1])>0.)next.accelerated=-1.;
            if(Math.abs(next.y[1])               next.a=next.sign*ai*next.accelerated;
               //if(next.a!=0&&next.y[1]==0.)next.y[1]=sign*0.1;
            }else{//速度太快
               next.a=0.;
               //next.y[1]=next.sign*vmax[id];
            }
         }//else {//不同車道
         //   if(next.y[1]==0.&& (mode-next.mode>1. || !next.turn)) next.a=next.sign*ai;
         else if(Math.abs(next.X-X)+Math.abs(next.Y-Y)               next.y[1]=0.;
               next.a=0.;
            }
         //}
         next.advanced(dt);
         if(next.X>xmax || next.X<0.){
            next=next.next;
            count[id]--;
            passed[id]++;
         }
      /*   if(loop[id] && count[id]            if(mode==2 && X               next.a=0.;
               next.y[1]/=2.;
               next.turn=true;
               tmp=new car(id,2);
               tmp.next=next;
               next=tmp;
            //}else if(mode==0 &&X>xi2){
            //   next.a=0.;
            //   next.y[1]/=2.;
            //   next.turn=true;
            //   tmp=new car(id,0);
            //   tmp.next=next;
            //   next=tmp;
            }
         }*/
      }else{ // last car
         if(loop[id]&&top[id].mode==mode){//繞過一圈後 同軌道
            delta=sign*(y[0]-top[id].y[0]);
            if(delta>dmax[id])top[id].accelerated=1.;
            else if(Math.abs(delta)                  top[id].y[1]=0.;
                  top[id].accelerated=0.;
            }else if(sign*(y[1]-top[id].y[1])>0.)top[id].accelerated=-1.;
            if(Math.abs(top[id].y[1])               top[id].a=top[id].sign*ai*top[id].accelerated;
               //if(top[id].a!=0.&&top[id].y[1]==0.)top[id].y[1]=0.1*sign;
            }
            /*/if(y[1]==0. && top[id].y[1]==0.)top[id].a=sign*ai;/*else{//速度太快
               top[id].a=0.;
               top[id].y[1]=sign*vmax[id];
            }*/
         }else   if(mode!=0 && top[id].y[1]==0.){//不同軌道
            //if(mode!=0 || X>xi2)
               top[id].a=top[id].sign*ai;
         }
         if( count[id]            //if( (mode!=0 && top[id].mode>mode)  || X>xi2 && (top[id].mode!=3 || top[id].y[0]==yi2[id]+dmin2[id])&&
            //   (!loop[id] || top[id].mode>mode && top[id].y[0]>yi[id] || top[id].y[1]==0. ) )
            if( top[id].mode>mode ||!loop[id]) {
               if(X>xi2)next=new car(id,0);
            }else if(top[id].mode==mode){
               if(sign*(top[id].y[0]-y[0])>0)next=new car(id,0);
            }
         }else   if(top[id].y[1]==0.){//不同軌道
            if(mode!=0 || X>xi2)
               top[id].a=top[id].sign*ai;
         }
      }
   }
   static int xx,yy;
   void draw(){
      //g.drawRect(X,Y,5,5);
      if(a==0.){
         if(y[1]!=0.)g.setColor(Color.green);
         else g.setColor(Color.gray);
      }else if(sign*a>0.)g.setColor(Color.blue);
      else g.setColor(Color.red);
      if(debug&&this==top[id])g.fillRect(X,Y,size,size);
      else g.drawRect(X,Y,size,size);
      if(!running){
         g.setColor(Color.red);
         if(mode%2==0)g.drawLine(xx=X+size0,yy=Y+size0,xx,yy+(int)y[1]);
         else g.drawLine(xx=X+size0,yy=Y+size0,xx-(int)y[1],yy);
      }
      if(next!=null)next.draw();
   }
}


Logged
ericaclayton453
Newbie
*
Offline Offline

Posts: 4

«
Embed this message
Reply #5 on: September 17, 2015, 01:46:19 pm » posted from:Bangalore,Karnataka,India

It is interesting. Smiley
Logged
chengfu
Newbie
*
Offline Offline

Posts: 4

«
Embed this message
Reply #6 on: October 26, 2015, 04:02:10 pm » posted from:Dhaka,Dhaka,Bangladesh

Thumbs up admin  Grin never should be die the source code.
Logged
Pages: [1]   Go Up
  Print  
"Reflect, review and renew constantly." ...Wisdom
 
Jump to:  


Powered by MySQL Powered by PHP Powered by SMF 1.1.13 | SMF © 2006-2011, Simple Machines LLC Valid XHTML 1.0! Valid CSS!
Page created in 0.203 seconds with 23 queries.since 2011/06/15