/// <summary> /// generate data packet from this vechile to the TargetVehicle. /// </summary> /// <param name="DestinationVehicle"></param> public void GeneratePacket(VehicleUi DestinationVehicle) { Dispatcher.Invoke((Action) delegate { Packet packet = new Packet(); packet.Type = PacketType.Data; PublicStatistics.GeneratedPacketsCount += 1; packet.PID = PublicStatistics.GeneratedPacketsCount; packet.PacketLength = PublicParamerters.DataPacketLength; packet.TravelledRoadSegmentString += CurrentLane.MyRoadSegment.RID; // add the first rs. packet.VehiclesString += VID; // start by current sender. packet.SRID = CurrentLane.MyRoadSegment.RID; // set source and distination: packet.SourceVehicle = this; packet.DestinationVehicle = DestinationVehicle; packet.Direction = DestinationVehicle.CurrentLane.LaneDirection; packet.CurrentRoadSegment = CurrentLane.MyRoadSegment; // the segment of the vechile. packet.EuclideanDistance = Computations.Distance(InstanceLocation, DestinationVehicle.InstanceLocation); // the intial distance packet.RoutingDistance = packet.EuclideanDistance; packet.SVID = VID; packet.DVID = DestinationVehicle.VID; this.SetNotationSign(NotationsSign.HasPacket); DestinationVehicle.SetNotationSign(NotationsSign.Destination); DestinationVehicle.WaitingPacketsIDsList.Add(packet.PID); // flage // start count the delay. PacketQueue.Enqueue(packet); // add the packet to the queue. PacketQueueTimer.Interval = TimeSpan.FromSeconds(PublicParamerters.PacketQueueTimerInterval); // retry after... PacketQueueTimer.Start(); // start the timer. }); }
/// <summary> /// select the next vechile. Intra_Routing. /// </summary> /// <param name="candidateVe"></param> /// <param name="rs"></param> /// <returns></returns> public VehicleUi MatchVehicle(List <VehicleUi> candidateVe, RoadSegment rs, Packet packet) { IntraRouting rou = new IntraRouting(rs); CandidateVehicle can = rou.GetCandidateVehicleUis(this, candidateVe, packet.DestinationVehicle, packet.IsRouted); if (can != null) { VehicleUi next = can.SelectedVehicle; if (packet.HopsVehicles > 3) { int lastMinuse1 = Convert.ToInt16(packet.VehiclesString.Split('-')[packet.HopsVehicles - 1]); if (next.VID != lastMinuse1) { packet.CommunicationOverhead += (candidateVe.Count - 1); // / (CurrentLane.MyRoadSegment.LanesCount / 2); // divided tha lane in the same direction. return(next); } else { // looop: no thing. } } else { return(next); } } return(null); }
/// <summary> /// forward the packet to the NEXT /// </summary> /// <param name="packet"></param> /// <param name="next"></param> public void RelayPacket(Packet packet, VehicleUi next) { Dispatcher.Invoke((Action) delegate { packet.PathWaitingTimes += packet.HopWaitingTimes; // save the path waiting time and clear the hop. packet.HopWaitingTimes = 0; // re-intilize the hop-waiting. packet.PropagationAndTransmissionDelay += DelayModel.Delay(this, next); packet.HopsVehicles += 1; packet.RoutingDistance += Computations.Distance(InstanceLocation, next.InstanceLocation); packet.VehiclesString += "-" + next.VID; next.RecievePacket(packet); PacketQueueTimer.Interval = TimeSpan.FromSeconds(PublicParamerters.PacketQueueTimerInterval); // retry after... next.SetNotationSign(NotationsSign.HasPacket); SetNotationSign(NotationsSign.HasNoPacket); }); }
/// <summary> /// select the the DestinationVehicle randomly. /// </summary> public void RandomDestinationVehicle() { Dispatcher.Invoke((Action) delegate { int max = CurrentLane._MainWindow.MyVehicles.Count; if (max >= 2) { int rand = Convert.ToInt16(RandomeNumberGenerator.GetUniform(max - 1)); if (rand != VID) { VehicleUi DestinationVehicle = CurrentLane._MainWindow.MyVehicles[rand]; GeneratePacket(DestinationVehicle); } } }); }
double AllowToChangeLaneDistance = 25; // when the distance to the junction is x, then its not allowed to change the lane. /// <summary> /// move the vechile. /// </summary> public void StartMove() { Dispatcher.Invoke((Action) delegate { VehicleUi infrontVehicle = CurrentLane.LaneVehicleAndQueue.GetMyFrontVehicle(this); // get in the front. showInfo(PublicParamerters.DisplayInfoFlag); // show flage. // info which should be disply. double headingDistance = RemianDistanceToHeadingJunction; // to north: if (VehicleDirection == Direction.N) { if (headingDistance > 0) { double marTop = this.Margin.Top; marTop -= 1; //Margin = new Thickness(Margin.Left, marTop, 0, 0); Dispatcher.Invoke(new Action(() => Margin = new Thickness(Margin.Left, marTop, 0, 0)), DispatcherPriority.Send); // start decrease the speed according to the heading distance toward the jucntion. if (headingDistance <= SlowDownDistance) { double instanceSpeed = Computations.GetTimeIntervalInSecond(headingDistance); // slow the speed. InstantaneousSpeed = instanceSpeed; } // if has vechile in front: the behind vehicle should change the speed to or change the lane if possible. if (infrontVehicle != null) { //: if still allowed to change the lane then go ahead. if not then the behind vechile should lower its speed. if (headingDistance > AllowToChangeLaneDistance) { ChangeLaneRandomly(); } else { // not allowd to change the lane. // double fronVspeed = 5; InstantaneousSpeed = infrontVehicle.InstantaneousSpeed * SpeedDisPercentage; } } // change the lane randomnlly when v is in the middlel of the segment. if (marTop < CurrentLane.MyRoadSegment.Midpoint) { double half = CurrentLane.MyRoadSegment.Height / 2; if (headingDistance > half) { if (!ChangeLaneFlage) { ChangeLaneRandomly(); ChangeLaneFlage = true; } } } if (headingDistance < LineUpInJunctionDistance) { CurrentLane.LaneVehicleAndQueue.Enqueue(this); // add to the queue. } } } else if (VehicleDirection == Direction.S) { if (headingDistance > 0) { double marTop = this.Margin.Top; marTop += 1; // Margin = new Thickness(Margin.Left, marTop, 0, 0); Dispatcher.Invoke(new Action(() => Margin = new Thickness(Margin.Left, marTop, 0, 0)), DispatcherPriority.Send); if (headingDistance <= SlowDownDistance) { double instanceSpeed = Computations.GetTimeIntervalInSecond(headingDistance); // slow the speed. InstantaneousSpeed = instanceSpeed; } if (infrontVehicle != null) { //: if still allowed to change the lane then go ahead. if not then the behind vechile should lower its speed. if (headingDistance > AllowToChangeLaneDistance) { ChangeLaneRandomly(); } else { InstantaneousSpeed = infrontVehicle.InstantaneousSpeed * SpeedDisPercentage; } } if (marTop > CurrentLane.MyRoadSegment.Midpoint) { double half = CurrentLane.MyRoadSegment.Height / 2; if (headingDistance > half) { if (!ChangeLaneFlage) { ChangeLaneRandomly(); ChangeLaneFlage = true; } } } if (headingDistance < LineUpInJunctionDistance) { CurrentLane.LaneVehicleAndQueue.Enqueue(this); // add to the queue. } } } else if (VehicleDirection == Direction.E) { if (headingDistance > 0) { double marLeft = Margin.Left; double marTop = Margin.Top; marLeft += 1; // Margin = new Thickness(marLeft, marTop, 0, 0); Dispatcher.Invoke(new Action(() => Margin = new Thickness(marLeft, marTop, 0, 0)), DispatcherPriority.Send); if (headingDistance <= SlowDownDistance) { double instanceSpeed = Computations.GetTimeIntervalInSecond(headingDistance); // slow the speed. InstantaneousSpeed = instanceSpeed; } if (infrontVehicle != null) { //: if still allowed to change the lane then go ahead. if not then the behind vechile should lower its speed. if (headingDistance > AllowToChangeLaneDistance) { ChangeLaneRandomly(); } else { InstantaneousSpeed = infrontVehicle.InstantaneousSpeed * SpeedDisPercentage; } } if (marLeft > CurrentLane.MyRoadSegment.Midpoint) { double half = CurrentLane.MyRoadSegment.Width / 2; if (headingDistance > half) { if (!ChangeLaneFlage) { ChangeLaneRandomly(); ChangeLaneFlage = true; } } } if (headingDistance < LineUpInJunctionDistance) { CurrentLane.LaneVehicleAndQueue.Enqueue(this); // add to the queue. } } } else if (VehicleDirection == Direction.W) { if (headingDistance > 0) { double marLeft = Margin.Left; double marTop = Margin.Top; marLeft -= 1; // Margin = new Thickness(marLeft, marTop, 0, 0); Dispatcher.Invoke(new Action(() => Margin = new Thickness(marLeft, marTop, 0, 0)), DispatcherPriority.Send); if (headingDistance <= SlowDownDistance) { double instanceSpeed = Computations.GetTimeIntervalInSecond(headingDistance); // slow the speed. InstantaneousSpeed = instanceSpeed; } if (infrontVehicle != null) { //: if still allowed to change the lane then go ahead. if not then the behind vechile should lower its speed. if (headingDistance > AllowToChangeLaneDistance) { ChangeLaneRandomly(); } else { InstantaneousSpeed = infrontVehicle.InstantaneousSpeed * SpeedDisPercentage; } } if (marLeft < CurrentLane.MyRoadSegment.Midpoint) { double half = CurrentLane.MyRoadSegment.Width / 2; if (headingDistance > half) { if (!ChangeLaneFlage) { ChangeLaneRandomly(); ChangeLaneFlage = true; } } } if (headingDistance < LineUpInJunctionDistance) { CurrentLane.LaneVehicleAndQueue.Enqueue(this); // add to the queue. } } } }); }
/// <summary> /// send the packet. /// </summary> /// <param name="packet"></param> public void SendPacket(Packet packet) { Dispatcher.Invoke((Action) delegate { if (packet.Type == PacketType.Data) { // it is time to switch the packet from a segment to a new segment. if (RemianDistanceToHeadingJunction <= PublicParamerters.RemianDistanceToHeadingJunctionThreshold) { //select the next junction. RoadSegment selectedNextRoadSegment = MatchJunction(packet); if (selectedNextRoadSegment != null) { // select the vechiles that going to the selected next road segment. // select inter-neighbors. CurrentLane.LaneVehicleAndQueue.GetInterNeighbors(this, packet.Direction, selectedNextRoadSegment); // get the inter_neighbors. should be computed before finding the VehicleUi next = MatchVehicle(Inter_Neighbores, selectedNextRoadSegment, packet); // inter_neibors. if (next != null) { packet.HopsJunctions += 1; packet.TravelledRoadSegmentString += "-" + selectedNextRoadSegment.RID; RelayPacket(packet, next); } else { packet.HopWaitingTimes += 1; // count the hop waiting. if (packet.HopWaitingTimes <= Settings.Default.MaximumAttemps) { StoreThePacket(packet); } else { // drop the packet: DropPacket(packet); } } } } else { CurrentLane.LaneVehicleAndQueue.GetIntraNeighborsTwoWays(this); // find the inter_neigbors. VehicleUi next = MatchVehicle(Intra_Neighbores, CurrentLane.MyRoadSegment, packet); // intra_neighbors. if (next != null) { RelayPacket(packet, next); } else { packet.HopWaitingTimes += 1; // count the hop waiting. if (packet.HopWaitingTimes <= Settings.Default.MaximumAttemps) { StoreThePacket(packet); } else { // drop the packet: DropPacket(packet); } } } } else { // packet is not data. } }); }