/// <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); }
/// <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); }
/// <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); //停止,排队等待 } } }
/// <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; }
/// <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; }
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(); } }
/// <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 } }
/// <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); })); }
/// <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(); } }
/// <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; } }
/// <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); } } }
/// <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; } } }
/// <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(); }