NTNUJAVA Virtual Physics LaboratoryEnjoy the fun of physics with simulations! Backup site http://enjoy.phy.ntnu.edu.tw/ntnujava/
September 17, 2019, 05:57:35 am

Discovery consists of seeing what everybody has seen and thinking what nobody has thought. ..."Albert von Szent-Gyorgyi(1893-1986, 1937 Nobel Prize for Medicine, Lived to 93)"

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

Offline

Posts: 3082

 « 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
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
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

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

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

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
Hero Member

Offline

Posts: 3082

 « 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();
//      timeField.setEditable(false);
iField.setEditable(false);
p.add(XY=new Label("(  X  ,  Y  )"));
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;
long startTime=0,lastTime;
long delay=50,delta;
public void start(){
//Start animating!
}
//Remember the starting time. of thread
lastTime=startTime = System.currentTimeMillis();
}
public void stop() {
running=false;
}

public void run() {
//Just to be nice, lower this thread's priority
//This is the animation loop.
//Advance the animation frame. with delta time
delta=System.currentTimeMillis()-lastTime;
lastTime+=delta;
startTime+=delay;
try {
} catch (InterruptedException e) {
break;
}
}
}
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;
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; //
}
//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;
}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.;
}
//}
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

Posts: 4

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

It is interesting.
 Logged
chengfu
Newbie

Offline

Posts: 4

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

Thumbs up admin  never should be die the source code.
 Logged
 Pages: [1]   Go Up
Discovery consists of seeing what everybody has seen and thinking what nobody has thought. ..."Albert von Szent-Gyorgyi(1893-1986, 1937 Nobel Prize for Medicine, Lived to 93)"