/************************************************************************************ * Copyright (C) 2008 by Politehnica University of Bucharest and Rutgers University * All rights reserved. * Refer to LICENSE for terms and conditions of use. ***********************************************************************************/ //Petroaca - the Application layer of DSRC package vnsim.network.dsrc; import java.io.ByteArrayInputStream; import java.util.ArrayList; import vnsim.core.CarInfo; import vnsim.core.Communicator; import vnsim.map.object.Globals; import vnsim.map.object.Point; import vnsim.map.object.Road; import vnsim.map.utils.GPSutil; public class Application { //the vehicles around the host vehicle used in forward collision warning and lane change assistance private CarInfo FVehicle,NFVehicle,LAdjancedVehicle,RAdjancedVehicle; private double FVehicleDistance,NFVehicleDistance,LAVehicleDistance,RAVehicleDistance; private boolean forwardCrashSignal,leftCrashSignal,rightCrashSignal,emergencyVehicleSignal; private double lastFVSpeed,lastNFVSpeed; private int emergencyVehicleHpoz,emergencyVehicleVpoz; private int currentTime; private long lastIRTFV,lastIRTNFV,lastIRTLAV,lastIRTRAV; public Application() { this.FVehicle=this.NFVehicle=this.LAdjancedVehicle=this.RAdjancedVehicle=null; this.FVehicleDistance=this.NFVehicleDistance=this.LAVehicleDistance=this.RAVehicleDistance=30000; this.forwardCrashSignal=false; this.leftCrashSignal=this.rightCrashSignal=false; this.emergencyVehicleSignal=false; this.currentTime=0; this.lastFVSpeed=-1; this.lastNFVSpeed=-1; this.lastIRTFV=this.lastIRTNFV=this.lastIRTLAV=this.lastIRTRAV=0; } //it refreshes the FV , NFV and it calculates the probability of a crash with these vehicles public void ForwardCollisionWarning(byte[] bytesReceived,CarInfo self) { switch(bytesReceived[0]) { case Globals.PROT_NEIGHBOR_DISCOVERY: CarInfo sc=new CarInfo(); sc.wrap(bytesReceived,2); calculateFCWVehicles(self,sc); calculateLCAVehicles(self,sc); break; case Globals.PROT_SETOFCARS: ByteArrayInputStream byteStream = new ByteArrayInputStream(bytesReceived); byte[] b = new byte[Globals.NONAGG_RECORD_SIZE]; byteStream.read(); int numberOfRecords = (byte)byteStream.read(); int messageRoadDirection = byteStream.read(); int recordsRead=0; while(recordsRead < numberOfRecords) { int n = byteStream.read(b, 0, Globals.NONAGG_RECORD_SIZE); if (n == -1 || n < Globals.NONAGG_RECORD_SIZE){ break; } recordsRead++; CarInfo sc2=new CarInfo(); sc2.wrap(b); calculateFCWVehicles(self,sc2); calculateLCAVehicles(self,sc2); } break; default:break; } // check FV and NFV speeds and calculate probability of crash if(this.FVehicle!=null) { if(this.lastFVSpeed!=-1) { if(self.getSpeed()-this.FVehicle.getSpeed()>=Globals.SPEED_DIFFERENCE || this.lastFVSpeed-this.FVehicle.getSpeed()>=Globals.SPEED_DIFFERENCE) this.forwardCrashSignal=true; } this.lastFVSpeed=this.FVehicle.getSpeed(); } if(this.NFVehicle!=null) { if(this.lastNFVSpeed!=-1) { if(self.getSpeed()-this.NFVehicle.getSpeed()>=Globals.SPEED_DIFFERENCE || this.lastNFVSpeed-this.NFVehicle.getSpeed()>=Globals.SPEED_DIFFERENCE) this.forwardCrashSignal=true; } this.lastNFVSpeed=this.NFVehicle.getSpeed(); } /* if(this.currentTime%40==0 && self.getVehicleId()==100) { System.out.println("Time "+this.currentTime/Globals.MINUTE+":"+(this.currentTime%Globals.MINUTE)/Globals.SECOND+" Car "+self.getVehicleId()+" has FV:"+((this.FVehicle==null)?"none":this.FVehicle.getVehicleId())+" NFV:"+((this.NFVehicle==null)?"none":this.NFVehicle.getVehicleId())+ " LAV:"+((this.LAdjancedVehicle==null)?"none":this.LAdjancedVehicle.getVehicleId())+" RAV:"+((this.RAdjancedVehicle==null)?"none":this.RAdjancedVehicle.getVehicleId())); } */ } public void LaneChangeAssistance(byte[] bytesReceived,CarInfo self) { //calculate the LAV and RAV and calculate the crash probability switch(bytesReceived[0]) { case Globals.PROT_NEIGHBOR_DISCOVERY: CarInfo sc=new CarInfo(); sc.wrap(bytesReceived,2); calculateLCAVehicles(self,sc); break; case Globals.PROT_SETOFCARS: ByteArrayInputStream byteStream = new ByteArrayInputStream(bytesReceived); byte[] b = new byte[Globals.NONAGG_RECORD_SIZE]; byteStream.read(); int numberOfRecords = (byte)byteStream.read(); int messageRoadDirection = byteStream.read(); int recordsRead=0; while(recordsRead < numberOfRecords) { int n = byteStream.read(b, 0, Globals.NONAGG_RECORD_SIZE); if (n == -1 || n < Globals.NONAGG_RECORD_SIZE){ break; } recordsRead++; CarInfo sc2=new CarInfo(); sc2.wrap(b); calculateLCAVehicles(self,sc2); } break; default:break; } if(this.LAdjancedVehicle!=null) this.leftCrashSignal=true; if(this.RAdjancedVehicle!=null) this.rightCrashSignal=true; /* if(this.LAdjancedVehicle!=null) System.out.println(self+" LAV:"+this.LAdjancedVehicle.getVehicleId()); if(this.RAdjancedVehicle!=null) System.out.println(self+" RAV:"+this.RAdjancedVehicle.getVehicleId()); */ } public void EmergencyVehicleWarning(byte[] bytesReceived,CarInfo self) { //if emergency message received activate emergencyVehicleSignal //check the position of the emergency vehicle CarInfo sc=new CarInfo(); sc.wrap(bytesReceived,2); if(self.getRoadIdx()==sc.getRoadIdx() && self.getDirection()==sc.getDirection()) { this.emergencyVehicleSignal=true; switch(self.getDirection()) { case 1: if(sc.getPointIdx()>self.getPointIdx()) this.emergencyVehicleVpoz=1; else { if(sc.getPointIdx()self.getPointIdx()) this.emergencyVehicleVpoz=0; else this.emergencyVehicleVpoz=2; } break; default:break; } if(sc.getLane()self.getLane()) this.emergencyVehicleHpoz=0; else this.emergencyVehicleHpoz=2; } } Globals.EMERGENCY_RECEIVED++; //System.out.println("Car "+self.getVehicleId()+" got emergency message from car "+sc.getVehicleId()); } public boolean getForwardCrashSignal() { return this.forwardCrashSignal; } public boolean getLeftCrashSignal() { return this.leftCrashSignal; } public boolean getRightCrashSignal() { return this.rightCrashSignal; } public boolean getEmergencySignal() { return this.emergencyVehicleSignal; } public void refreshApplication(int currentTime) { if(currentTime-this.currentTime>=Globals.WIRELESS_TRANSMISSION_FRAMES+Globals.CCW_REFRESH_TIME) { this.FVehicle=this.NFVehicle=this.LAdjancedVehicle=this.RAdjancedVehicle=null; this.lastIRTFV=this.lastIRTNFV=this.lastIRTLAV=this.lastIRTRAV=this.currentTime; this.FVehicleDistance=this.NFVehicleDistance=this.LAVehicleDistance=this.RAVehicleDistance=30000; this.forwardCrashSignal=this.leftCrashSignal=this.rightCrashSignal=this.emergencyVehicleSignal=false; } this.currentTime=currentTime; } //calculates the FV and the NFV private void calculateFCWVehicles(CarInfo self,CarInfo sc) { Road r1,r2 = null; Point p1,p2 = null; r1 = (Road) Globals.map.roads.get(sc.getRoadIdx()); p1 = (Point) r1.points.get(sc.getPointIdx()); r2 = (Road) Globals.map.roads.get(self.getRoadIdx()); p2 = (Point) r2.points.get(self.getPointIdx()); //refresh the FV if(GPSutil.distance(p1, p2) <= this.FVehicleDistance && self.getRoadIdx()==sc.getRoadIdx() && self.getDirection()==sc.getDirection() && self.getLane()==sc.getLane()) { switch(self.getDirection()) { case 1: if(sc.getPointIdx()>self.getPointIdx()) { this.FVehicle=sc; this.FVehicleDistance=GPSutil.distance(p1, p2); Globals.CUMMULATIVE_PACKETS_FV++; Globals.IRT_FV+=this.currentTime-this.lastIRTFV; this.lastIRTFV=this.currentTime; return; } break; case 0 :if(sc.getPointIdx()self.getPointIdx()) { this.NFVehicle=sc; this.NFVehicleDistance=GPSutil.distance(p1, p2); Globals.CUMMULATIVE_PACKETS_NFV++; Globals.IRT_NFV+=this.currentTime-this.lastIRTNFV; this.lastIRTNFV=this.currentTime; } break; case 0 :if(sc.getPointIdx()