예제 #1
0
        /// <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();
            }
        }
예제 #2
0
 /// <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();
     }
 }
예제 #3
0
        /// <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;
        }
예제 #4
0
        /// <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;
            }
        }