/// <summary> /// template method /// </summary> /// <param name="driveContainer"></param> /// <param name="mobile"></param> internal virtual void DriveMobile(StaticOBJ driveCtx, MobileOBJ mobile) { var dctx = this.Observe(driveCtx, mobile); switch (driveCtx.EntityType) { //use way as container for lane changing case EntityType.Lane: this.WayDriver.DriveMobile(mobile, dctx); break; case EntityType.XNode: this.XNodeDriver.DriveMobile(mobile, dctx); break; default: ThrowHelper.ThrowArgumentException("不正确的参数"); break; } mobile.iAcceleration = Math.Max(dctx.Params.iAcceleration, 1); mobile.iSpeed = dctx.Params.iSpeed; }
protected MobileOBJ(StaticOBJ bornContainer) { this._entityID = ++TrafficOBJ.EntityCounter; this.Route = new EdgeRoute(); this._container = bornContainer; }
internal void Run(StaticOBJ DriveEnvirnment) { this.Driver.DriveMobile(DriveEnvirnment, this); }
/////////////////////////////////////////////////// internal DriveCtx Observe(StaticOBJ driveEn, MobileOBJ mobile) { DriveCtx dctx = new DriveCtx(driveEn); dctx.iAcceleration = mobile.iAcceleration; dctx.iSpeed = mobile.iSpeed; switch (driveEn.EntityType) { // calculate headway on the left/right/current lane of current mobile case EntityType.Lane: var currLane = mobile.Container as Lane; var currWay = currLane.Container as Way; //current mobile int iCurrStart = currLane.Shape.GetIndex(mobile.Shape.Start); //current mobile int iCurrEnd = currLane.Shape.GetIndex(mobile.Shape.End); // int iLaneGap = currLane.iLength-iCurrentStart; if (mobile.Front != null) { //behiand 14 .front 15. iLaneGap need to reduce 1 dctx.iLaneGap = currLane.Shape.GetIndex(mobile.Front.Shape.End) - iCurrStart - 1; dctx.iFrontSpeed = mobile.Front.iSpeed; dctx.iXNodeGap = 0; dctx.iFrontHeadWay = dctx.iLaneGap + dctx.iXNodeGap; } //front mobile is null, current mobile is the first one on this lane //the first mobile needs to deal with a traffic light or/and a crossing(XNode) else //this.FrontMobile==null) //front mobile,there's a signal light playing on the lane //deal with that signal light { if (currLane.IsBlocked == true) { dctx.iFrontHeadWay = currLane.Length - iCurrStart; } //deal with that crossing else //the current mobile is the first one to deal with a crossing //先计算车辆的轨迹,where a mobile is heading for. right .left or straight forward { int iXNodeGap = 0; int iLaneGap = currLane.Length - 1 - iCurrStart; if (iLaneGap <= 3 * mobile.iSpeed) //space si more than triple car speed. { mobile.Track.Update(); if (mobile.Track.ToLane != null) { //class acts as parameters will pass its address to functions,so clone is used here var temp = currLane.Shape.End; // if (this.ID == 2) { // ; // } //再计算剩余轨迹 GetXNodeGap(currWay.To, temp, out iXNodeGap, mobile); } else //toLane == null. reach destination { dctx.IsReachEnd = true; iXNodeGap = 10; //to let the first car go away iLaneGap = 0; } } dctx.iXNodeGap = iXNodeGap; dctx.iLaneGap = iLaneGap; dctx.iFrontHeadWay = iXNodeGap + iLaneGap; dctx.iFrontSpeed = -1; } } //rear mobile dctx.iRearHeadWay = iCurrStart; if (mobile.Rear != null) { dctx.iRearHeadWay = iCurrEnd - currLane.Shape.GetIndex(mobile.Rear.Shape.Start); dctx.iRearSpeed = mobile.Rear.iSpeed; } else //rear mobile is empty { dctx.iRearHeadWay = iCurrStart; //rear mobiel dctx.iRightRearSpeed = -1; } //get dirving context on the left lane this.GetSidesContext(currLane.Left, LaneType.Left, iCurrStart, iCurrEnd, ref dctx); //get dirving context on the right lane this.GetSidesContext(currLane.Right, LaneType.Right, iCurrStart, iCurrEnd, ref dctx); break; case EntityType.XNode: var xnode = driveEn as XNode; int iLaneEnGap = 0; int iXNodeEnGap = 0; //计算剩余轨迹数量//如果pcurrPos没到头,iXnodeGap等于零 //when a mobile is on a xnode .its headway is xnodeGap for a secend mobile //the frist mobile bIsBlocked is never true;while its following may be true var bIsBlocked = this.GetXNodeGap(xnode, mobile.Track.Current, out iXNodeEnGap, mobile); if (bIsBlocked == false) //the first mobile { var toLane = mobile.Track.ToLane; //计算车道上的长度 if (toLane != null) //no destination lane means a mobile has reach its destnation. { if (toLane.MobilesInn.Count > 0) //theres already mobiles waiting to enter tolane. { iLaneEnGap = 0; } else { var lastMobile = toLane.Mobiles.Last; if (lastMobile != null) { iLaneEnGap = toLane.Shape.GetIndex(lastMobile.Value.Shape.End); } else //no mobiles running at tolane { iLaneEnGap = toLane.Length; } } } } else //the a mobile blocked by its previous mobile on a xnode { iLaneEnGap = 0; } dctx.iLaneGap = iLaneEnGap; dctx.iXNodeGap = iXNodeEnGap; dctx.iFrontHeadWay = iXNodeEnGap + iLaneEnGap; break; case EntityType.Way: throw new NotImplementedException("不应该传入这个参数,应在在车道上,或者是交叉口上"); break; default: break; } return(dctx); }