package vnsim.applications.emissions; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.Serializable; import java.nio.ByteBuffer; import vnsim.applications.trafficview.SimulatedCarInfo; import vnsim.core.CarInfo; import vnsim.core.Communicator; import vnsim.map.object.Globals; import vnsim.map.object.PeanoKey; import vnsim.map.object.Point; import vnsim.map.object.Road; import vnsim.network.RadioDev; /* * Class that simulates the car: * the car is equipped with a radio device and is capable * of transmitting and receiving messages sent on the network * * @author: Adriana Szekeres */ public class EmissionsCar extends SimulatedCarInfo{ /* Constructors */ public EmissionsCar() { super(); } public EmissionsCar(int vehicleId) { super(vehicleId); } public EmissionsCar(int vehicleId, byte lane, double speed, short roadIdx, short pointIdx, byte direction, double offset) { super(vehicleId, lane, speed, roadIdx, pointIdx, direction, offset); } public EmissionsCar(SimulatedCarInfo sci) { super(sci); } /* Function called when this car received a packet - the packet was previously * encapsulated into a scheduled event that is now "played" in the Engine class, * in method playEvent() */ @Override public void onReceive(byte[] bytesReceived, Serializable message, Communicator sender){ if (!isEquipped || bytesReceived == null) return; /* PROT_SETOFCARS: Diffusion protocol - read TrafficView paper * * personal note: I'm not very sure about how much info * gets to the TrafficLights */ if (bytesReceived[0] == Globals.PROT_SETOFCARS){ parsePacket(bytesReceived); } /* PROT_NEIGHBOR_DISCOVERY: Is this flooding? Or just one hop propagation? * As far as I can see, the car doesn't propagate this message. * */ if (bytesReceived[0] == Globals.PROT_NEIGHBOR_DISCOVERY){ // first record in message - the sender CarInfo sc = new CarInfo(); sc.wrap(bytesReceived, 2); boolean added = false; for (int i=0;i pidx && this.direction == 0 && dir == 1) || (this.getPointIdx() < pidx && this.direction == 1 && dir == 0))) { phaseRemainingTime = remaining; currentPhase = color; queueSize = qsize; interGreenPhaseTime = interPhase; if (Globals.engine.startedWithGUI && Globals.demo.mv.currentCar != null && this.equals(Globals.demo.mv.currentCar)) { Globals.demo.st.setSemTime(color, remaining); Globals.demo.st.setDemand("sw", (int) (queueSize * 1000), 0, false); } } /*if (i < segno - 1) try { ridx = bb.getShort(); r = Globals.map.roads.get(ridx); pidx = bb.getShort(); p = r.points.get(pidx); } catch (Exception e) { System.out.println("Bad TL feedback message: \n"); e.printStackTrace(); return; } */ } } } public byte[] prepareMessage(int messageType){ byte[] bytesToSend = null; //if (realPos.finished) // return null; if (!isEquipped) return null; //for messageType = 0, standard neighborDiscovery message if (messageType == STANDARD_MESSAGE_ID){ //neighbor discovery if (messageType == Globals.PROT_NEIGHBOR_DISCOVERY){ byte[] localinfo = toBytes(); ByteArrayOutputStream outBytes = new ByteArrayOutputStream(); outBytes.write(Globals.PROT_NEIGHBOR_DISCOVERY); outBytes.write(CRTDIR); try{ outBytes.write(localinfo); }catch(IOException e){ } bytesToSend = outBytes.toByteArray(); } if (messageType == Globals.PROT_SETOFCARS){ if (Globals.probabilisticModel){ decideTransmissionMode(); if (pulseMessage){ if (isPromiscuousMode() && speed > 1){ super.state = 0; setPromiscuousMode(false); } if (super.state == 3){ setPromiscuousMode(true); return null; } } else { setPromiscuousMode(false); super.state = 0; } } // if (li.getToSend().getRoadIdx() != li.getPrevSent().getRoadIdx()){ // state = CRTDIR; // } /* int carsno; ByteArrayOutputStream outBytes = null; while(true){ int roadIndex = -1, roadIndex1 = -1; int dir = -1, direction1 = -1; carsno = 1; int off = 0; outBytes = new ByteArrayOutputStream(); if (comState == CRTDIR){ roadIndex = getRoadIdx(); dir = getDirection(); }else if (comState == OPPDIR){ roadIndex = getRoadIdx(); dir = 1 - getDirection(); } outBytes.write(Globals.PROT_SETOFCARS); // leave room for number of records outBytes.write(0); // leave room for number of records outBytes.write(comState); off++; try{ //local information if (this.speed < 1 ){ super.state = 3; //promiscuous mode }else{ super.state = 0; } /* if (realPos.turningLeft) setSignal((byte)1); else setSignal((byte)0); byte[] car = toBytes(); outBytes.write(car); off += car.length; if (!pulseMessage){ ListIterator it = trafficDB.listIterator(); for (; it.hasNext(); ){ CarInfo sc = it.next(); if (sc.getRoadIdx() == roadIndex && sc.getDirection() == dir){ car = sc.toBytes(); if (off + car.length > Globals.MTU_SIZE - 100){ // no more room in the packet for this car //TODO break; } outBytes.write(car); off += car.length; carsno ++; } } } }catch(IOException e){ System.out.println("Error sending cars"); e.printStackTrace(); } /* if (comState == OPPDIR && carsno == 1){ // no cars on the opposed movement // comState = REST; comState = CRTDIR; continue; }*/ // if (comState == REST && carsno == 1){ // // no more cars // comState = CRTDIR; // } /* break; } bytesToSend = outBytes.toByteArray(); bytesToSend[1] = (byte)carsno; //set the first byte to be the number of records /* if (comState == CRTDIR){ comState = OPPDIR; reportedNeighbors = 0; }else if (comState == OPPDIR) comState = CRTDIR; // comState = REST;*/ } } return bytesToSend; } }