/// <summary> /// 由负责添加的类进行仿真上下文同步,内部进行了RoadLane注册 /// </summary> /// <param name="rl"></param> internal void AddLane(Lane rl) { if (rl != null) { //防止添加了较多的车道 if (this.Lanes.Count == SimSettings.iMaxLanes) { throw new ArgumentOutOfRangeException("无法添加超过" + SimSettings.iMaxLanes + "个车道"); } rl.Container = this; //两行代码一定不要高反了 RoadNet.GetInstance().lanes.Add(rl.GetHashCode(), rl); // rl.Register();// //同步仿真上下文的数据记录 //按照laneRanking 和laneType排序,插入到合适的位置并且给予恰当的 //laneRanking便于进行坐标索引 int i = this._lanes.Count; if (i == 0) //第一个要添加的车道 { this._lanes.Add(rl); rl.Rank = 1; } while (i-- >= 1) //个数超过一个车道进行插入操作 { Lane rLane = this._lanes[i]; //i已经变小了一个数 if (rLane.laneType > rl.laneType) { //将后续大的laneRanking的值增1 rLane.Rank += 1; if (i == 0) { this.Lanes.Insert(0, rl); //插入最右边的车道 rl.Rank = 1; } } //rank最大的一个相同车道 if (rLane.laneType <= rl.laneType) { //插入新的lane,当前索引是i,要插入之后,索引应当是i+1 this._lanes.Insert(i + 1, rl); //rl.Rank = i+2;//rank 比索引大1 rl.Rank = i + 2; // this.Lanes.Count; break; } } //this.ilength =端点的长度//端点坐标之间的距离 } else { throw new ArgumentNullException(); } }
/// <summary> /// 由负责删除的类进行仿真上下文同步 /// </summary> /// <param name="rl"></param> //[System.Obsolete("应当根据实际的情况确定删除车道需要的函数类型")] internal void RemoveLane(Lane rl) { if (rl != null) { for (int i = rl.Rank; i < this.Lanes.Count; i++) { this.Lanes[i].Rank -= 1; } this._lanes.Remove(rl); //第rank个车道是第rank-1个类型 //同步仿真上下文的数据记录 RoadNet.GetInstance().lanes.Remove(rl.GetHashCode()); //进行反注册 } else { throw new ArgumentNullException(); } }
/// <summary> /// 在转弯的时候调用,根据车辆路径,寻找车辆要进入的下一条车道(左右转、直行)。从起始位置出发,前进iAheadSpace个间距时距 /// </summary> internal virtual void Update() { if (this.mobile == null) { ThrowHelper.ThrowArgumentException("a track has no mobile before updating ,assigned one to it through constructor internal Track(MobileEntity me) "); } if (mobile.Container.EntityType == EntityType.XNode) { return; } Lane currLane = mobile.Container as Lane; //get its tolane var currWay = currLane.Container as Way; var nextWay = this.mobile.Route.FindNext(currWay); //shape end means a point on a narrow like "---->" //a signal light is playing at a lane's shape end this.FromLane = currLane; this.opFrom = currLane.Shape.End; if (nextWay == null) //a moblie is reaching its destination { this.ToLane = null; // this.opTo = OxyzPointF.Default; this.opTo = currLane.Shape.End; return; } int iTurn = mobile.Route.GetDirection(currWay); //车辆直行 switch (iTurn) { case 0: //go straight foword if (nextWay.Lanes.Count < currLane.Rank) //next way has less lanes than a mobiles'current one { int iIdx = new Random(1).Next(nextWay.Lanes.Count) - 1; iIdx = iIdx < 0?0:iIdx; this.ToLane = nextWay.Lanes[iIdx]; } else //otherwise 目标车道数大于于本车道数 { this.ToLane = nextWay.Lanes[currLane.Rank - 1]; } break; case 1: //turn right //the outside lane is rightful for a mobile obeying traffic regulations this.ToLane = nextWay.Lanes[nextWay.Lanes.Count - 1]; break; case -1: //turn left // int iIndex = new Random(1).Next(nextWay.Lanes.Count) - 1; this.ToLane = nextWay.Lanes[0]; break; case 2: //turn back //while truning backward a inside lane is rightful this.ToLane = nextWay.Lanes[0]; break; } //shape start means a point at the end of a narrow like "---->" this.opTo = this.ToLane.Shape.Start; }
/// <summary> /// get left and right driving context /// </summary> /// <param name="lane">lane</param> /// <param name="lanetype">lanetype of current lane</param> /// <param name="iCurrentStart">headway of current mobile index</param> /// <param name="iCurrentEnd">rear of current mobile index</param> /// <param name="dc">out parameters</param> private void GetSidesContext(Lane lane, LaneType lanetype, int iCurrentStart, int iCurrentEnd, ref DriveCtx dc) { //to make sure current lane got a lefe lane if (lane == null) { return; } //headway on the lane int iFrontHeadWay = -1; int iRearHeadWay = -1; int iFrontSpeed = -1; int iRearSpeed = -1; //there's no mobile on lane if (lane.Mobiles.Count > 0) { //there's mobiles on lane int iLeastGap = lane.Length; int iTempGap = iLeastGap; MobileOBJ mobile = null; //loop to find two adjacent mobiles on the lane.one rear,one ahead of the current mobile foreach (var element in lane.Mobiles) { iTempGap = lane.Shape.GetIndex(element.Shape.End) - iCurrentStart; //make it positive,to find the nearest mobile on the left lane if (Math.Abs(iTempGap) < Math.Abs(iLeastGap)) { iLeastGap = iTempGap; mobile = element; } } //nearest mobile on the left is at the front if (iLeastGap >= 0) { iFrontHeadWay = iLeastGap; iFrontSpeed = mobile.iSpeed; var rearMobile = mobile.Rear; if (rearMobile != null) { iRearHeadWay = iCurrentEnd - lane.Shape.GetIndex(rearMobile.Shape.Start); iRearSpeed = rearMobile.iSpeed; } } //nearest mobile on the left is at the behind else { //make it postive iRearHeadWay = Math.Abs(iLeastGap); iRearSpeed = mobile.iSpeed; var frontMobile = mobile.Front; if (frontMobile != null) { iFrontHeadWay = lane.Shape.GetIndex(frontMobile.Shape.End) - iCurrentStart; iFrontSpeed = mobile.Front.iSpeed; } } } else { iFrontHeadWay = lane.Length - iCurrentStart; iRearHeadWay = iCurrentEnd; } //make driving observation true switch (lanetype) { case LaneType.Right: dc.iRightFrontHeadWay = iFrontHeadWay; dc.iRightFrontSpeed = iFrontSpeed; dc.iRightRearHeadWay = iRearHeadWay; dc.iRightRearSpeed = iRearSpeed; break; case LaneType.Left: dc.iLeftFrontHeadWay = iFrontHeadWay; dc.iLeftFrontSpeed = iFrontSpeed; dc.iLeftRearHeadWay = iRearHeadWay; dc.iLeftRearSpeed = iRearSpeed; break; default: throw new ArgumentException("parameter lanetype error!"); break; } }