Пример #1
0
 /// <summary>
 /// 更新停靠区号
 /// </summary>
 /// <param name="AGVStatus">AGV车辆类,指针类型</param>
 public int UpdateDock(AGVCar AGVStatus)
 {
     if (!AGVStatus.WlLink)
     {
         AGVStatus.DockNum = 0;
     }                                                 //当前AGV不在线
     for (int i = 0; i < dockCount; i++)
     {
         //不在停靠区时判断是否进入停靠区
         if (AGVStatus.DockNum == 0)
         {
             if (IsIntoDockArea(AGVStatus.WorklineNum, AGVStatus.MarkNum))
             {
                 return(dockNum);
             }
         }
         //在停靠区时判断是否出停靠区
         else
         {
             if (IsOutDockArea(AGVStatus.WorklineNum, AGVStatus.MarkNum))
             {
                 return(0);
             }
         }
     }
     return(AGVStatus.DockNum);
 }
Пример #2
0
        /// <summary>
        /// 单台AGV更新运行参数,使用了管制区号TrafficNum和无线状态WlLink,需要更新管制区号
        /// |  0:正在占用路口的AGV编号 | 1:等待排队AGV的编号,优先级-1 | 2:等待排队AGV的编号,优先级-2 |.......
        /// </summary>
        /// <param name="AGVStatus">AGV运行状态结构体,指针类型</param>
        /// <returns>返回AGV运行or停止</returns>
        public TrafficRetParam UpdateTraffic(AGVCar AGVStatus)
        {
            TrafficRetParam retparam       = new TrafficRetParam();
            int             trafficnum     = 0;
            int             lasttrafficnum = AGVStatus.TrafficNum;
            byte            agvnum         = AGVStatus.AGVNum;

            if (AGVStatus.WlLink)//当前AGV在线
            {
                //trafficnum为当前AGV所在交通管制区编号
                trafficnum = GetTrafficNum(AGVStatus.WorklineNum, AGVStatus.MarkNum);
            }
            else//当前AGV不在线,直接返回不在管制区,假如上一次在管制区的话,直接清除上次的记录
            {
                //如果无线连接断开,清除该小车所在管制区的数据
                trafficnum = 0;
            }
            if (trafficnum == 0)         //不是在管制区
            {
                if (lasttrafficnum == 0) //上一次地标不在管制区
                {
                    retparam.trafficResult = AGVMODERUN;
                }
                else  //上一次小车是在管制区中,现在是清除管制状态,清除该路口该车辆排队信息
                {
                    //移除排队队列中
                    agvTrafficList[lasttrafficnum - 1].waitAGVList.Remove(agvnum);
                    retparam.trafficNum    = 0;
                    retparam.trafficResult = AGVMODERUN;
                }
            }
            else  //是在管制区
            {
                if ((lasttrafficnum != 0) && (trafficnum != lasttrafficnum)) //与上一次的管制区不同,更新上一路口参数
                {
                    //移除在上一管制区中的排队信息
                    agvTrafficList[lasttrafficnum - 1].waitAGVList.Remove(agvnum);
                }
                if (lasttrafficnum != trafficnum)//上次的管制区号与这次的管制区号不同
                {
                    //加入排队队列中
                    agvTrafficList[trafficnum - 1].waitAGVList.Add(agvnum);
                }
                retparam.trafficNum = trafficnum;                            //更新AGV状态中现在所在管制区号
                if (agvTrafficList[trafficnum - 1].waitAGVList[0] == agvnum) //在第一的排队位置
                {
                    retparam.trafficResult = AGVMODERUN;                     //启动
                }
                else//非第一的排队位置,即等待队列
                {
                    retparam.trafficResult = AGVMODESTOP;  //停止,排队等待
                }
            }
            return(retparam);
        }
Пример #3
0
        /// <summary>
        /// 单台AGV更新运行参数,使用了管制区号TrafficNum和无线状态WlLink,需要更新管制区号
        /// |  0:正在占用路口的AGV编号 | 1:等待排队AGV的编号,优先级-1 | 2:等待排队AGV的编号,优先级-2 |.......
        /// </summary>
        /// <param name="AGVStatus">AGV运行状态结构体,指针类型</param>
        /// <returns>返回AGV运行or停止</returns>
        public bool DrvWlConUpdateRunPar(ref AGV_WPF.DLL.AGV.AGVCar AGVStatus)
        {
            int  trafficnum     = 0;
            int  lasttrafficnum = AGVStatus.trafficNum;
            byte agvnum         = AGVStatus.agvNum;

            if (AGVStatus.wlLink)//当前AGV在线
            {
                //trafficnum为当前AGV所在交通管制区编号
                trafficnum = GetTrafficNum(AGVStatus.worklineNum, AGVStatus.markNum);
            }
            else//当前AGV不在线,直接返回不在管制区,假如上一次在管制区的话,直接清除上次的记录
            {
                //如果无线连接断开,清除该小车所在管制区的数据
                trafficnum = 0;
            }
            if (trafficnum == 0)         //不是在管制区
            {
                if (lasttrafficnum == 0) //上一次地标不在管制区
                {
                    return(AGVMODERUN);
                }
                else  //上一次小车是在管制区中,现在是清除管制状态,清除该路口该车辆排队信息
                {
                    //移除排队队列中
                    agvTrafficList[lasttrafficnum - 1].waitAGVList.Remove(agvnum);
                    AGVStatus.trafficNum = 0;
                    return(AGVMODERUN);
                }
            }
            else  //是在管制区
            {
                if ((lasttrafficnum != 0) && (trafficnum != lasttrafficnum)) //与上一次的管制区不同,更新上一路口参数
                {
                    //移除在上一管制区中的排队信息
                    agvTrafficList[lasttrafficnum - 1].waitAGVList.Remove(agvnum);
                }
                if (lasttrafficnum != trafficnum)//上次的管制区号与这次的管制区号不同
                {
                    //加入排队队列中
                    agvTrafficList[trafficnum - 1].waitAGVList.Add(agvnum);
                }
                AGVStatus.trafficNum = trafficnum;                           //更新AGV状态中现在所在管制区号
                if (agvTrafficList[trafficnum - 1].waitAGVList[0] == agvnum) //在第一的排队位置
                {
                    return(AGVMODERUN);                                      //启动
                }
                else//非第一的排队位置,即等待队列
                {
                    return(AGVMODESTOP);  //停止,排队等待
                }
            }
        }
Пример #4
0
 /// <summary>
 /// 更新停靠区号
 /// </summary>
 /// <param name="AGVStatus">AGV车辆类,指针类型</param>
 public int UpdateDock(AGVCar AGVStatus)
 {
     if (!AGVStatus.WlLink) { AGVStatus.DockNum = 0; } //当前AGV不在线
     for (int i = 0; i < dockCount; i++)
     {
         //不在停靠区时判断是否进入停靠区
         if (AGVStatus.DockNum == 0)
         {
             if (IsIntoDockArea(AGVStatus.WorklineNum, AGVStatus.MarkNum))
             {
                  return dockNum;
             }
         }
         //在停靠区时判断是否出停靠区
         else
         {
             if (IsOutDockArea(AGVStatus.WorklineNum, AGVStatus.MarkNum))
             {
                 return 0;
             }
         }
     }
     return AGVStatus.DockNum;
 }
Пример #5
0
 /// <summary>
 /// 单台AGV更新运行参数,使用了管制区号TrafficNum和无线状态WlLink,需要更新管制区号
 /// |  0:正在占用路口的AGV编号 | 1:等待排队AGV的编号,优先级-1 | 2:等待排队AGV的编号,优先级-2 |.......
 /// </summary>
 /// <param name="AGVStatus">AGV运行状态结构体,指针类型</param>
 /// <returns>返回AGV运行or停止</returns>
 public TrafficRetParam UpdateTraffic(AGVCar AGVStatus)
 {
     TrafficRetParam retparam = new TrafficRetParam();
     int trafficnum = 0;
     int lasttrafficnum = AGVStatus.TrafficNum;
     byte agvnum = AGVStatus.AGVNum;
     if (AGVStatus.WlLink)//当前AGV在线
     {
         //trafficnum为当前AGV所在交通管制区编号
         trafficnum = GetTrafficNum(AGVStatus.WorklineNum, AGVStatus.MarkNum);
     }
     else//当前AGV不在线,直接返回不在管制区,假如上一次在管制区的话,直接清除上次的记录
     {
         //如果无线连接断开,清除该小车所在管制区的数据
         trafficnum = 0;
     }
     if (trafficnum == 0)  //不是在管制区
     {
         if (lasttrafficnum == 0) //上一次地标不在管制区
         {
             retparam.trafficResult = AGVMODERUN;
         }
         else  //上一次小车是在管制区中,现在是清除管制状态,清除该路口该车辆排队信息
         {
             //移除排队队列中
             agvTrafficList[lasttrafficnum - 1].waitAGVList.Remove(agvnum);
             retparam.trafficNum = 0;
             retparam.trafficResult = AGVMODERUN;
         }
     }
     else  //是在管制区
     {
         if ((lasttrafficnum != 0) && (trafficnum != lasttrafficnum)) //与上一次的管制区不同,更新上一路口参数
         {
             //移除在上一管制区中的排队信息
             agvTrafficList[lasttrafficnum - 1].waitAGVList.Remove(agvnum);
         }
         if (lasttrafficnum != trafficnum)//上次的管制区号与这次的管制区号不同
         {
             //加入排队队列中
             agvTrafficList[trafficnum - 1].waitAGVList.Add(agvnum);
         }
         retparam.trafficNum = trafficnum;//更新AGV状态中现在所在管制区号
         if (agvTrafficList[trafficnum - 1].waitAGVList[0] == agvnum)//在第一的排队位置
         {
             retparam.trafficResult = AGVMODERUN; //启动
         }
         else//非第一的排队位置,即等待队列
         {
             retparam.trafficResult = AGVMODESTOP;  //停止,排队等待
         }
     }
     return retparam;
 }
Пример #6
0
 void DrvWlConInit()
 {
     for (int i = 0; i < AGVNUM_MAX; i++)
     {
         AGVStatus[i] = new AGVCar(this,canvas);
     }
     DrvWlConWorkLineInit();  //生产区初始化,需要先初始化AGVStatus,然后再生产区初始化
     if (GlobalPara.IsTrafficFun)
     {
         agvTrafficList = new AGVTrafficList();
         agvTrafficList.Init();//交通管制路口初始化
     }
     if (GlobalPara.IsDockFun)
     {
         agvDock = new AGVDock();
         agvDock.Init();
     }
     if (GlobalPara.IsChargeFun)
     {
         agvCharge = new AGVCharge();
         agvCharge.Init();
     }
     if (GlobalPara.IsCallFun)
     {
         agvCall = new AGVCall();
     }
 }
Пример #7
0
        /// <summary>
        /// 无线连接属性更改时触发的事件
        /// </summary>
        /// <param name="temp1">AGV_DisMember类</param>
        private void WLChangeAction(AGVCar temp1)
        {
            IEnumerable<AGVCar> member = AGVStatus.Where<AGVCar>(p => p.AGVNum == temp1.AGVNum);
            AGVCar member1 = member.First<AGVCar>();
            int listindex = AGVStatus.IndexOf(member1);
            App.Current.Dispatcher.Invoke((Action)(() =>
            {
                AGVStatus[listindex].agvAnimation.WLChangeAnimation(temp1.WlLink);
            }));
            if (temp1.WlLink)
            {
                MarkChangeAction(temp1);
            }

            else
            {
                AGVStatus[listindex].agvAnimation.ClearAllElements();
                AGVStatus[listindex].agvAnimation = null;
                AGVStatus.Remove(temp1);//20140309从表格中移除无线连接失败的agv
            }
        }
Пример #8
0
 /// <summary>
 /// 运行状态属性更改时触发的事件
 /// </summary>
 /// <param name="temp1">AGV_DisMember类</param>
 private void StatusChangeAction(AGVCar temp1)
 {
     IEnumerable<AGVCar> member = AGVStatus.Where<AGVCar>(p => p.AGVNum == temp1.AGVNum);
     AGVCar member1 = member.First<AGVCar>();
     int listindex = AGVStatus.IndexOf(member1);
     App.Current.Dispatcher.Invoke((Action)(() =>
     {
         AGVStatus[listindex].agvAnimation.StatusChangeAnimation(temp1.AGVStatus, temp1.AGVNum, temp1.DockNum);
     }));
 }
Пример #9
0
         /// <summary>
 /// 地标属性更改时触发的事件
 /// 移除上次动画,显示下一动画
 /// </summary>
 /// <param name="temp1">AGV_DisMember类</param>
 private void MarkChangeAction(AGVCar temp1)
 {
     IEnumerable<AGVCar> member = AGVStatus.Where<AGVCar>(p => p.AGVNum == temp1.AGVNum);
     AGVCar member1 = member.First<AGVCar>();
     int listindex = AGVStatus.IndexOf(member1);
     Point pStart = new Point(), pVirtual = new Point();
     DAL.ZSql TrafficPara = new DAL.ZSql();
     try
     {
         TrafficPara.Open("select T_Line.MarkOrder, T_Mark.XPos, T_Mark.YPos FROM T_Line LEFT OUTER JOIN T_Mark ON T_Mark.ID = T_Line.MarkID where WorkLine=" + temp1.WorklineNum.ToString() + " and Mark=" + temp1.MarkNum.ToString() + " and LineNum=" + temp1.LineNum.ToString());
         if (TrafficPara.Rows.Count > 0)
         {
             pStart.X = Convert.ToDouble(TrafficPara.Rows[0]["XPos"]);
             pStart.Y = Convert.ToDouble(TrafficPara.Rows[0]["YPos"]);
             List<Point> pointcollection1 = new List<Point>();
             pointcollection1.Add(pStart);
             int currentOrder = Convert.ToInt16(TrafficPara.Rows[0]["MarkOrder"]) + 1;
             bool isvirtualpoint = true;
             double dMarkdistance = 0;
             do
             {
                 TrafficPara.Open("select XPos,YPos,T_Line.Distance,VirtualMark from T_Mark Left join T_Line on T_Mark.ID = T_Line.MarkID where T_Line.MarkOrder=" + currentOrder.ToString() +
                 "and LineNum=" + temp1.LineNum.ToString());
                 if (TrafficPara.Rows.Count > 0)
                 {
                     pVirtual.X = Convert.ToDouble(TrafficPara.Rows[0]["XPos"]);
                     pVirtual.Y = Convert.ToDouble(TrafficPara.Rows[0]["YPos"]);
                     pointcollection1.Add(pVirtual);
                     dMarkdistance += Convert.ToDouble(TrafficPara.Rows[0]["Distance"]);
                     isvirtualpoint = Convert.ToBoolean(TrafficPara.Rows[0]["VirtualMark"]);
                     currentOrder++;
                 }
                 else
                 {
                     isvirtualpoint = false;
                     break;
                 }
             }
             while (isvirtualpoint);
             if (pointcollection1.Count >= 2)
             {
                 double dAgvspeed = SpeedOpt[temp1.AGVSpeed].Speed / 60.0;
                 if (dAgvspeed == 0)
                 {
                     dAgvspeed = dMarkdistance;
                 }
                 App.Current.Dispatcher.Invoke((Action)(() =>
                 {
                     AGVStatus[listindex].agvAnimation.DrawCarLine(pointcollection1, ColorOpt[temp1.AGVNum % ColorOpt.Length], dMarkdistance / dAgvspeed);
                 }));
             }
         }
     }
     catch (Exception)
     {
         throw;
     }
     finally
     {
         TrafficPara.Close();
     }
 }
Пример #10
0
        /// <summary>
        /// 电量属性更改时触发的事件
        /// 电量低于20%时进行充电
        /// </summary>
        /// <param name="temp1">AGV_DisMember类</param>
        private void PowerChangeAction(AGVCar temp1)
        {
            IEnumerable<AGVCar> member = AGVStatus.Where<AGVCar>(p => p.AGVNum == temp1.AGVNum);
            AGVCar member1 = member.First<AGVCar>();
            int listindex = AGVStatus.IndexOf(member1);
            //20140312电量低于20%时进行充电,线路切换到充电线路
            if (temp1.AGVPower < 20)//电量低于20%时进行充电
            {
                //设置充电标志位
                AGVStatus[listindex].AGVCharge = 1;
            }

        }
Пример #11
0
 /// <summary>
 /// 无线连接属性更改时触发的事件
 /// </summary>
 /// <param name="temp1">AGV_DisMember类</param>
 private void WLChangeAction(AGVCar temp1)
 {
     IEnumerable<AGVCar> member = AGVStatus.Where<AGVCar>(p => p.AGVNum == temp1.AGVNum);
     AGVCar member1 = member.First<AGVCar>();
     int listindex = AGVStatus.IndexOf(member1);
     //此处不能用异步,需要等待动画后返回。因为后续有AGVStatus删除元素的操作
     AGVStatus[listindex].agvAnimation.WLChangeAnimation(temp1.WlLink);
     if (temp1.WlLink)
     {
         MarkChangeAction(temp1);
     }
     else
     {
         AGVStatus[listindex].agvAnimation.ClearAllElements();
         AGVStatus[listindex].agvAnimation = null;
         AGVStatus.Remove(temp1);
         if (agvCharge != null)
         {
             agvCharge.Delete(temp1.AGVNum);
         }
         if (agvDock != null)
         {
             agvDock.Delete(temp1.AGVNum);
         }
     }
 }
Пример #12
0
 /// <summary>
 /// 运行状态属性更改时触发的事件
 /// </summary>
 /// <param name="temp1">AGV_DisMember类</param>
 private void StatusChangeAction(AGVCar temp1)
 {
     IEnumerable<AGVCar> member = AGVStatus.Where<AGVCar>(p => p.AGVNum == temp1.AGVNum);
     AGVCar member1 = member.First<AGVCar>();
     int listindex = AGVStatus.IndexOf(member1);
     AGVStatus[listindex].agvAnimation.StatusChangeAnimation(temp1.AGVStatus, temp1.AGVNum, temp1.DockNum);
     switch (temp1.AGVStatus)
     {
         case 0x40://"运行":
             AGVStatus[listindex].AGVTask = 1;
             break;
         case 0x41://"暂停":
             break;
         case 0x42://"结束地标停止":
             //if (agvCall.lineNum.Count > 0)//有叫料信息,需要车辆运送
             //{
             //    if (agvCall.lineNum[0] > 0)
             //    {
             //        agvDock.outDockLine[iagvnum - 1] = agvCall.lineNum[0];
             //        AGVControlCommand(iagvnum, 3, 0, 0);
             //    }
             //}
             break;
         default:
             {
                 //将报警记录写入到数据库
                 string txttimer = System.DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss");
                 DAL.ZSql TrafficPara = new DAL.ZSql();
                 TrafficPara.Open("Insert into T_Ex (CarID,ExTimer,ExType,ExRouteNum,ExMarkNum,ExWorkLine) VALUES (" + temp1.AGVNum.ToString() + ",'" + txttimer + "','" + StatusOpt[temp1.AGVStatus] + "'," + temp1.LineNum.ToString() + "," + temp1.MarkNum.ToString() + "," + temp1.WorklineNum.ToString() + ")");
                 TrafficPara.Close();
                 break;
             }
     }
 }
Пример #13
0
        /// <summary>
        /// 地标属性更改时触发的事件
        /// 移除上次动画,显示下一动画
        /// </summary>
        /// <param name="temp1">AGV_DisMember类</param>
        private void MarkChangeAction(AGVCar temp1)
        {
            IEnumerable<AGVCar> member = AGVStatus.Where<AGVCar>(p => p.AGVNum == temp1.AGVNum);
            AGVCar member1 = member.First<AGVCar>();
            int listindex = AGVStatus.IndexOf(member1);
            Point pStart = new Point(), pVirtual = new Point();

            //待测试
            //if (agvDock != null && agvCharge != null && agvCall != null)
            //{
            //    if (Convert.ToInt32(temp1.txtDockNum) == 0)
            //    {
            //        if (agvDock.dockStartStop.Equals(new WorkMarkStr(Convert.ToInt32(temp1.txtWorkLine), Convert.ToInt32(temp1.txtMarkNum))))
            //        {
            //            //充电返回后,清除状态
            //            if (temp1.txtagvCharge == 4) { AGVStatus[iagvnum - 1].agvCharge = 0; }
            //            CarLine carline = agvDock.Add(iagvnum);
            //            if (carline != null)
            //            {
            //                temp1.txtDockNum = carline.dockNum.ToString();
            //                temp1.txtLineNum = carline.lineNum.ToString();
            //                AGVStatus[iagvnum - 1].dockNum = carline.dockNum;
            //                //启动车辆,发送变更为待装停靠区路线
            //                //进入待装区时,起始地标的功能为暂停,结束地标不能为停止或暂停,一定为agv运行的地标功能,也不能在交通管制点内
            //                AGVControlCommand(iagvnum, 3, 0, Convert.ToByte(carline.lineNum));
            //            }
            //            else
            //            {
            //                //这是在排队队列中,此时需要车辆停止(发送停止命令)
            //                AGVControlCommand(iagvnum, 2, 0, 0);
            //            }
            //        }
            //    }
            //    else
            //    {
            //        if (agvDock.dockEndStop.Equals(new WorkMarkStr(Convert.ToInt32(temp1.txtWorkLine), Convert.ToInt32(temp1.txtMarkNum))))
            //        {
            //            //移除待装区排队
            //            CarLine carline = agvDock.Delete(iagvnum);
            //            if (carline != null)
            //            {
            //                //只有停靠区和管制区在这边需要软件更新,其他的更新可以发送控制命令,下位机更改AGV状态,上位机接收数据驱动更新
            //                AGVStatus[carline.agvNum - 1].dockNum = carline.dockNum;
            //                //如果在等待排队中有车辆,启动等待的车辆
            //                AGVControlCommand(carline.agvNum, 3, 0, Convert.ToByte(carline.lineNum));
            //            }
            //            temp1.txtDockNum = "0";
            //            AGVStatus[iagvnum - 1].dockNum = 0;
            //            //此时需要变换路线agvDock.outDockLine[iagvnum-1],发出控制命令,变更路线
            //            //1.当监测到temp1.txtagvCharge ==1时,outDockLine[iagvnum-1]为充电路线
            //            //2.当temp1.txtagvCharge ==0时,为执行任务的路线
            //            if (temp1.txtagvCharge == 1)
            //            {
            //                AGVStatus[iagvnum - 1].agvCharge = 2;
            //            }
            //            AGVControlCommand(iagvnum, 0, 0, Convert.ToByte(agvDock.outDockLine[iagvnum - 1]));
            //            agvDock.outDockLine[iagvnum - 1] = 0;
            //        }
            //    }

            //    if (temp1.txtagvCharge == 2)
            //    {
            //        if (agvCharge.dockStartStop.Equals(new WorkMarkStr(Convert.ToInt32(temp1.txtWorkLine), Convert.ToInt32(temp1.txtMarkNum))))
            //        {
            //            CarLine carline = agvCharge.Add(iagvnum);
            //            if (carline != null)
            //            {
            //                temp1.txtagvCharge = 3;//充电状态
            //                AGVStatus[iagvnum - 1].agvCharge = 3;//充电状态
            //                temp1.txtLineNum = carline.lineNum.ToString();
            //                //启动车辆,发送变更路线
            //                AGVControlCommand(iagvnum, 3, 0, Convert.ToByte(carline.lineNum));
            //            }
            //            else
            //            {
            //                //这是在排队队列中,此时需要车辆停止(发送停止命令)
            //                AGVControlCommand(iagvnum, 2, 0, 0);
            //            }
            //        }
            //    }//注意:充电完成,车辆不会自行启动,需要人工拔掉充电线,然后启动车辆
            //    else if (temp1.txtagvCharge == 3)
            //    {
            //        if (agvCharge.dockEndStop.Equals(new WorkMarkStr(Convert.ToInt32(temp1.txtWorkLine), Convert.ToInt32(temp1.txtMarkNum))))
            //        {
            //            //移除待装区排队
            //            CarLine carline = agvCharge.Delete(iagvnum);
            //            if (carline != null)
            //            {
            //                //只有停靠区和管制区在这边需要软件更新,其他的更新可以发送控制命令,下位机更改AGV状态,上位机接收数据驱动更新
            //                AGVStatus[carline.agvNum - 1].dockNum = carline.dockNum;
            //                //如果在等待排队(此时AGV车辆在待装区中排队,不是在充电区的起始地标排队)中有车辆,启动等待的车辆
            //                AGVControlCommand(carline.agvNum, 3, 0, 0);
            //                agvDock.outDockLine[iagvnum - 1] = agvCharge.chargeLine;//在出待装区的时候改变路线使用
            //            }
            //            temp1.txtagvCharge = 4;
            //            AGVStatus[iagvnum - 1].agvCharge = 4;
            //        }
            //    }
            //}

            #region 停靠区
            if (agvDock != null)
            {
                // 判断是否进入停靠区
                if (temp1.DockNum == 0)
                {
                    if (agvDock.dockStartStop.Equals(new WorkMarkStr(temp1.WorklineNum, temp1.MarkNum)))
                    {
                        //已经进入停靠区:1.更新AGV的停靠区参数 2.更新AGV的路线

                        //车辆进入停靠区
                        CarLine carline = agvDock.Add(temp1.AGVNum);
                        if (carline != null)
                        {
                            temp1.DockNum = carline.dockNum;
                            temp1.LineNum = carline.lineNum;
                            //更新停靠区参数
                            AGVStatus[listindex].DockNum = carline.dockNum;
                            //启动车辆,发送变更为待装停靠区路线
                            //进入待装区时,起始地标的功能为暂停,结束地标不能为停止或暂停,一定为agv运行的地标功能,也不能在交通管制点内
                            AGVControlCommand(temp1.AGVNum, 3, 0, carline.lineNum);
                        }
                        else
                        {
                            //这是在排队队列中,此时需要车辆停止(发送停止命令)
                            AGVControlCommand(temp1.AGVNum, 2, 0, 0);
                        }
                        //启用充电区
                        if (agvCharge != null)
                        {
                            //充电返回后,清除状态
                            if (temp1.AGVCharge == 4) { AGVStatus[listindex].AGVCharge = 0; }
                        }
                        else//不启用充电区
                        {
                        }
                    }
                    else
                    {
                        //未进入停靠区,一直处于停靠区外面;暂不做处理
                    }
                }
                else//判断是否出停靠区
                {
                    if (agvDock.dockEndStop.Equals(new WorkMarkStr(temp1.WorklineNum, temp1.MarkNum)))
                    {
                        //离开停靠区:1.更新AGV的停靠区参数 2.更新AGV的路线

                        //移除待装区排队
                        CarLine carline = agvDock.Delete(temp1.AGVNum);
                        //更新AGV停靠区参数
                        temp1.DockNum = 0;
                        AGVStatus[listindex].DockNum = 0;
                        //更新AGV路线
                        //有车辆等待排队
                        if (carline != null)
                        {
                            //只有停靠区和管制区在这边需要软件更新,其他的更新可以发送控制命令,下位机更改AGV状态,上位机接收数据驱动更新
                            IEnumerable<AGVCar> dockmember = AGVStatus.Where<AGVCar>(p => p.AGVNum == carline.agvNum);
                            int indexfind = AGVStatus.IndexOf(dockmember.First());
                            AGVStatus[indexfind].DockNum = carline.dockNum;
                            //如果在等待排队中有车辆,启动等待的车辆
                            AGVControlCommand(carline.agvNum, 3, 0, carline.lineNum);
                        }
                        //启用充电区
                        if (agvCharge != null)
                        {
                            if (temp1.AGVCharge == 1)
                            {
                                byte linenum = agvCharge.GetChargeLine(temp1.LineNum);
                                //充电路线,当linenum=0,说明用户没有定义
                                agvDock.outDockLine[temp1.AGVNum - 1] = linenum;//充电路线
                                if (linenum > 0)
                                {
                                    AGVStatus[listindex].AGVCharge = 2;
                                }
                            }
                        }
                        else
                        {
                            //不启动充电区
                        }

                        //车辆驶出停靠区后变更路线
                        //此时需要变换路线agvDock.outDockLine[iagvnum-1],发出控制命令,变更路线
                        //1.当监测到temp1.txtagvCharge ==1时,outDockLine[iagvnum-1]为充电路线
                        //2.当temp1.txtagvCharge ==0时,为执行任务的路线
                        if (agvDock.outDockLine[temp1.AGVNum - 1] > 0)
                        {
                            AGVControlCommand(temp1.AGVNum, 0, 0, agvDock.outDockLine[temp1.AGVNum - 1]);
                            agvDock.outDockLine[temp1.AGVNum - 1] = 0;
                        }

                    }
                    else
                    {
                        //已经进入停靠区,但一直在停靠区内;暂不做处理
                    }
                }
            }
            #endregion

            #region 充电区
            if (agvCharge != null)
            {
                if (temp1.AGVCharge == 2)
                {
                    if (agvCharge.dockStartStop.Equals(new WorkMarkStr(temp1.WorklineNum, temp1.MarkNum)))
                    {
                        CarLine carline = agvCharge.Add(temp1.AGVNum, temp1.LineNum);
                        if (carline != null)
                        {
                            temp1.AGVCharge = 3;//充电状态
                            AGVStatus[listindex].AGVCharge = 3;//充电状态
                            temp1.LineNum = carline.lineNum;
                            //启动车辆,发送变更路线
                            AGVControlCommand(temp1.AGVNum, 3, 0, carline.lineNum);
                        }
                        else
                        {
                            //这是在排队队列中,此时需要车辆停止(发送停止命令)
                            AGVControlCommand(temp1.AGVNum, 2, 0, 0);
                        }
                    }
                }//注意:充电完成,车辆不会自行启动,需要人工拔掉充电线,然后启动车辆
                else if (temp1.AGVCharge == 3)
                {
                    if (agvCharge.dockEndStop.Equals(new WorkMarkStr(temp1.WorklineNum, temp1.MarkNum)))
                    {
                        //移除待装区排队
                        CarLine carline = agvCharge.Delete(temp1.AGVNum);
                        if (carline != null)
                        {
                            //只有停靠区和管制区在这边需要软件更新,其他的更新可以发送控制命令,下位机更改AGV状态,上位机接收数据驱动更新
                            IEnumerable<AGVCar> dockmember = AGVStatus.Where<AGVCar>(p => p.AGVNum == carline.agvNum);
                            int indexfind = AGVStatus.IndexOf(dockmember.First());
                            AGVStatus[indexfind].DockNum = carline.dockNum;
                            //如果在等待排队(此时AGV车辆在待装区中排队,不是在充电区的起始地标排队)中有车辆,启动等待的车辆
                            temp1.LineNum = carline.lineNum;
                            AGVControlCommand(carline.agvNum, 3, 0, carline.lineNum);
                        }
                        temp1.AGVCharge = 4;
                        AGVStatus[listindex].AGVCharge = 4;
                        AGVControlCommand(temp1.AGVNum, 0, 0, agvCharge.beforeEnterLine[temp1.DockNum]);
                    }
                }
            }
            #endregion


            DAL.ZSql TrafficPara = new DAL.ZSql();

            TrafficPara.Open("select T_Line.MarkOrder, T_Mark.XPos, T_Mark.YPos FROM T_Line LEFT OUTER JOIN T_Mark ON T_Mark.ID = T_Line.MarkID where WorkLine=" + temp1.WorklineNum.ToString() + " and Mark=" + temp1.MarkNum.ToString() + " and LineNum=" + temp1.LineNum.ToString());
            if (TrafficPara.Rows.Count > 0)
            {
                pStart.X = Convert.ToDouble(TrafficPara.Rows[0]["XPos"]);
                pStart.Y = Convert.ToDouble(TrafficPara.Rows[0]["YPos"]);
                List<Point> pointcollection1 = new List<Point>();
                pointcollection1.Add(pStart);
                int currentOrder = Convert.ToInt16(TrafficPara.Rows[0]["MarkOrder"]) + 1;
                //线路起点处检测电量
                if (currentOrder == 2)
                {
                    //AGV到达起点位置,空闲状态;当检测到AGV状态为运行时,为执行任务
                    AGVStatus[listindex].AGVTask = 0;
                    //启用充电区
                    if (agvCharge != null)
                    {
                        if (temp1.AGVCharge == 1)
                        {
                            byte linenum = agvCharge.GetChargeLine(temp1.LineNum);
                            //当linenum=0时,说明管理员没有设置充电路线,不会启动自动充电
                            if (linenum > 0)
                            {
                                AGVControlCommand(temp1.AGVNum, 1, 0, linenum);
                                AGVStatus[listindex].AGVCharge = 2;
                            }
                        }
                    }
                }
                bool isvirtualpoint = true;
                double dMarkdistance = 0;
                do
                {
                    TrafficPara.Open("select XPos,YPos,T_Line.Distance,VirtualMark from T_Mark Left join T_Line on T_Mark.ID = T_Line.MarkID where T_Line.MarkOrder=" + currentOrder.ToString() +
                    "and LineNum=" + temp1.LineNum.ToString());
                    if (TrafficPara.Rows.Count > 0)
                    {
                        pVirtual.X = Convert.ToDouble(TrafficPara.Rows[0]["XPos"]);
                        pVirtual.Y = Convert.ToDouble(TrafficPara.Rows[0]["YPos"]);
                        pointcollection1.Add(pVirtual);
                        dMarkdistance += Convert.ToDouble(TrafficPara.Rows[0]["Distance"]);
                        isvirtualpoint = Convert.ToBoolean(TrafficPara.Rows[0]["VirtualMark"]);
                        currentOrder++;
                    }
                    else
                    {
                        isvirtualpoint = false;
                        break;
                    }
                }
                while (isvirtualpoint);
                if (pointcollection1.Count >= 2)
                {
                    double dAgvspeed = SpeedOpt[temp1.AGVSpeed].Speed / 60.0;
                    if (dAgvspeed == 0)
                    {
                        dAgvspeed = dMarkdistance;
                    }
                    AGVStatus[listindex].agvAnimation.DrawCarLine(pointcollection1, ColorOpt[temp1.AGVNum % ColorOpt.Length], dMarkdistance / dAgvspeed);
                }
            }
            TrafficPara.Close();
        }