Commit a2d7154e SK

AGV建构修改

1 个父辈 dea7d1f1
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace AGVControl
{
public class Agv_Info
{
/// <summary>
/// 小车名称
/// </summary>
public string Name { private set; get; }
/// <summary>
/// 小车在FLEET中的ID号
/// </summary>
public string ID { private set; get; }
/// <summary>
/// IP地址
/// </summary>
public string IP { private set; get; }
/// <summary>
/// IO模块GUID
/// </summary>
public string IOID { private set; get; }
/// <summary>
/// 授权码
/// </summary>
public string Authorization { private set; get; }
/// <summary>
/// 当前架子的RFID
/// </summary>
public string RFID { set; get; }
/// <summary>
/// 是否在线
/// </summary>
public bool IsCon { set; get; }
/// <summary>
/// 是否可用
/// </summary>
public bool IsUse { set; get; }
/// <summary>
/// 地点
/// </summary>
public string Place { set; get; }
/// <summary>
/// 地点
/// </summary>
public string PlaceAliceName { set; get; } = "";
/// <summary>
/// 地点的状态
/// </summary>
public PlaceState PlaceState { private set; get; }
/// <summary>
/// 小车的状态ID,(从小车获取)
/// </summary>
public int StateID { private set; get; }
/// <summary>
/// 负载
/// </summary>
public bool IsExistShelf { set; get; } = false;
/// <summary>
/// 小车的状态,(从小车获取)
/// </summary>
public string StateText { private set; get; }
/// <summary>
/// 电量百分比,(从小车获取)
/// </summary>
public int Battery { private set; get; }
/// <summary>
/// 当前任务文本,(从小车获取)
/// </summary>
public string MissionText { set; get; }
/// <summary>
/// 下一个地点
/// </summary>
public string NextPlace { set; get; }
/// <summary>
/// 下一个地点
/// </summary>
public string NextPlaceAliceName { set; get; } = "";
/// <summary>
/// 关门,用于执行一次
/// </summary>
//public bool CloseDoor { set; get; }
/// <summary>
/// 任务发送
/// </summary>
public string TaskSend { set; get; } = "";
/// <summary>
/// 闲置等待时间,用于充电
/// </summary>
public int WaitTime { set; get; }
/// <summary>
/// 临时待机位,用于执行一次
/// </summary>
//public bool StandbyTemp { set; get; }
public struct DockingStru
{
public DateTime startTime;
public bool IsDocking;
}
/// <summary>
/// 停靠信息
/// </summary>
public DockingStru DockingInfo;
public class clsPosition
{
public double orientation { get; set; }
public double x { get; set; }
public double y { get; set; }
}
/// <summary>
/// 当前位置
/// </summary>
public clsPosition Position;
/// <summary>
/// 任务内容
/// </summary>
public string Msg { get; set; }
public Agv_Info(string id, string name, string ip, string authorization, string ioID, bool isUse, string rfid)
{
ID = id;
Name = name;
IP = ip;
Authorization = authorization;
IOID = ioID;
RFID = rfid;
IsCon = false;
IsUse = isUse;
Place = "";
TaskSend = "";
NextPlace = "";
Msg = "";
DockingInfo.IsDocking = false;
DockingInfo.startTime = DateTime.Now;
Position = new Agv_Info.clsPosition();
}
DateTime IoStartTime = DateTime.MaxValue;
int IoLastTime = 5000;
public bool SetState(int stateID, string stateText, int battery, string missionText, clsPosition position)
{
bool isChange = false;
bool preShelfState = IsExistShelf;
//if (input != null && input.Length == 4)
//{
// bool reachIoValue = input[3].Equals(true);//input[2] &&
// if (reachIoValue)
// {
// //满足给定的IO值,计算持续时间
// if (IoStartTime == DateTime.MaxValue)
// {
// IoStartTime = DateTime.Now;
// }
// if (IoLastTime > 0)
// {
// //持续时间
// TimeSpan lastTimeSpan = DateTime.Now - IoStartTime;
// IsExistShelf = (lastTimeSpan.TotalMilliseconds >= IoLastTime);
// }
// else
// {
// IsExistShelf = true;
// }
// }
// else
// {
// //重新计时
// IoStartTime = DateTime.MinValue;
// IsExistShelf = input[3];
// }
//}
if (!StateID.Equals(stateID) || !StateText.Equals(stateText)
|| !MissionText.Equals(missionText) || !IsExistShelf.Equals(preShelfState)) //!Battery.Equals(battery)
isChange = true;
StateID = stateID;
StateText = stateText;
Battery = battery;
MissionText = missionText;
Position = position;
return isChange;
}
public void GetPlace(int value)
{
Common.log.Debug(Name + " PLC20=" + value);
if (value == 0)
{
Place = "";
PlaceState = PlaceState.None;
}
else if (value > 0 && value < 1000)
{
//Place = "";
//PlaceState = PlaceState.None;
//TaskSend = "";
}
else if (value >= 1000)
{
int a = value / 1000;
int b = (value - a * 1000) / 10;
int c = value - a * 1000 - b * 10;
if (c.Equals(1) || c.Equals(3) || c.Equals(5))//Move,Enter,Leave
TaskSend = "";
Place = (char)(64 + a) + b.ToString();
if (Common.nodeInfo != null && Common.nodeInfo.Count != 0)
{
ClientNode node = Common.nodeInfo.Find(s => s.Name == Place);
if (node != null)
PlaceAliceName = node.AliceName;
else
PlaceAliceName = Place;
}
PlaceState = (PlaceState)c;
}
}
public string[] ToRow()
{
//AGV名称,IP,AGV状态,任务状态,地点,后续任务,在线,电量,调用,清除缓存
List<string> s = new List<string>();
s.Add(Name);
s.Add(IP);
if (IsCon)
{
s.Add(StateText);
s.Add(RFID);
s.Add(Msg);
s.Add(MissionText);
s.Add(PlaceAliceName);
//s.Add(Place);
s.Add(PlaceState.ToString());
if (Common.nodeInfo != null && Common.nodeInfo.Count != 0)
{
ClientNode node = Common.nodeInfo.Find(q => q.Name == NextPlace);
if (node != null)
NextPlaceAliceName = node.AliceName;
else
NextPlaceAliceName = NextPlace;
}
s.Add(NextPlaceAliceName);
}
else
{
s.AddRange(new List<string> { "", "", "", "", "", "", "" });
}
s.Add(IsExistShelf ? "满载" : "空载");
s.Add(IsCon ? "在线" : "离线");
s.Add(Battery + "%");
s.Add(IsUse ? "是" : "否");
s.Add("清空");
return s.ToArray();
}
}
}
using AGVControl;
using System;
using System.Collections.Generic;
namespace AGVControl
{
public abstract class Job
{
/// <summary>
/// 是否任务正在执行,防止任务执行时间过长产生多线程问题
/// </summary>
public bool IsProcess { get; set; }
/// <summary>
/// 任务优先级
/// </summary>
/// <returns></returns>
public abstract int GetPriority();
/// <summary>
/// 任务是否已经结束
/// </summary>
/// <returns></returns>
public abstract bool IsEnd();
/// <summary>
/// 根据任务状态继续执行任务
/// </summary>
public abstract void Execute(Agv_Info agv);
}
}
using AGVControl;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace AGVControl
{
public class JobStep<T> where T : Enum
{
private T step;
private string msg = "";
public string Msg
{
get { return msg; }
set
{
if (!string.IsNullOrEmpty(value))
{
//不为空,且与上一个消息不一样才打印
if (!value.Equals(msg))
{
Common.LogInfo(value);
}
}
msg = value;
}
}
private DateTime startTime = DateTime.Now;
public JobStep(T initStep)
{
this.step = initStep;
this.msg = "";
}
/// <summary>
/// 当前步骤是否是某个步骤
/// </summary>
/// <param name="step"></param>
/// <returns></returns>
public bool IsStep(T step)
{
return this.step.Equals(step);
}
/// <summary>
/// 是否超时
/// </summary>
/// <param name="timeOutMilliseconds"></param>
/// <returns></returns>
public bool IsTimeOut(int timeOutMilliseconds)
{
TimeSpan span = DateTime.Now - startTime;
if (span.TotalMilliseconds > timeOutMilliseconds)
{
return true;
}
return false;
}
/// <summary>
/// 进入下一个步骤
/// </summary>
/// <param name="nextStep"></param>
public void ToNextStep(T nextStep)
{
step = nextStep;
startTime = DateTime.Now;
}
public string StatusStr()
{
return step.ToString();
}
}
}
using System;
using System.Collections.Generic;
namespace AGVControl
{
public abstract class Node
{
public Node(string name)
{
Name = name;
}
protected NodeStatus nodeStatus = new NodeStatus();
public string Name { get; set; }
public void UpdateNodeStatus(NodeStatus status)
{
nodeStatus = status;
}
public virtual Job GetNewJob(AgvBean currentAgvBean, Dictionary<string, Node> nodeMap, Dictionary<string, AgvBean> agvBeanMap)
{
return null;
}
}
}

using AGVControl;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace AGVControl
{
/// <summary>
/// 回收空料架任务
/// </summary>
public class SendFullShelfJob : Job
{
public SendFullShelfJob(string palce, int priority)
{
EmptyShelfPlace = palce;
_priority = priority;
}
/// <summary>
/// 空料架位置点
/// </summary>
private string EmptyShelfPlace{ get; set; }
/// <summary>
/// 优先级
/// </summary>
private int _priority;
private JobStep<TAKE_EMPTY_STEP> TakeEmptyStep = new JobStep<TAKE_EMPTY_STEP>(TAKE_EMPTY_STEP.NONE);
public override void Execute(Agv_Info agv)
{
if (TakeEmptyStep.IsStep(TAKE_EMPTY_STEP.NONE))
{
Common.LogInfo("开始执行回收空料架任务,发送到AGV");
TakeEmptyStep.ToNextStep(TAKE_EMPTY_STEP.WAIT_AGV_START_TAKE_TASK);
ClientNode node = Common.nodeInfo.Find(s => s.Name == EmptyShelfPlace);
}
else if (TakeEmptyStep.IsStep(TAKE_EMPTY_STEP.WAIT_AGV_START_TAKE_TASK))
{
//判断小车是否开始执行任务
bool isTaskStart = false;
if (isTaskStart)
{
Common.LogInfo("AGV已接收并开始执行回收空料架任务,等待到达取架点");
TakeEmptyStep.ToNextStep(TAKE_EMPTY_STEP.WAIT_REACH_TAKE_PLACE);
}
}else if (TakeEmptyStep.IsStep(TAKE_EMPTY_STEP.WAIT_REACH_TAKE_PLACE))
{
}
}
public override int GetPriority()
{
return _priority;
}
public override bool IsEnd()
{
return TakeEmptyStep.IsStep(TAKE_EMPTY_STEP.END);
}
}
/// <summary>
/// AGV离开A4
/// </summary>
public enum TAKE_EMPTY_STEP
{
NONE,
/// <summary>
/// 等待AGV开始执行去取架点任务
/// </summary>
WAIT_AGV_START_TAKE_TASK,
/// <summary>
/// 等待AGV到达取架点
/// </summary>
WAIT_REACH_TAKE_PLACE,
/// <summary>
/// AGV到达取架点
/// </summary>
REACH_TAKE_PLACE,
/// <summary>
/// 送上双层线
/// </summary>
END
}
}

using AGVControl;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace AGVControl
{
/// <summary>
/// 回收空料架任务
/// </summary>
public class TakeEmptyShelfJob : Job
{
public TakeEmptyShelfJob(string palce, int priority)
{
EmptyShelfPlace = palce;
_priority = priority;
}
/// <summary>
/// 空料架位置点
/// </summary>
private string EmptyShelfPlace{ get; set; }
/// <summary>
/// 优先级
/// </summary>
private int _priority;
private JobStep<TAKE_EMPTY_STEP> TakeEmptyStep = new JobStep<TAKE_EMPTY_STEP>(TAKE_EMPTY_STEP.NONE);
public override void Execute(Agv_Info agv)
{
if (TakeEmptyStep.IsStep(TAKE_EMPTY_STEP.NONE))
{
Common.LogInfo("开始执行回收空料架任务,发送到AGV");
TakeEmptyStep.ToNextStep(TAKE_EMPTY_STEP.WAIT_AGV_START_TAKE_TASK);
ClientNode node = Common.nodeInfo.Find(s => s.Name == EmptyShelfPlace);
}
else if (TakeEmptyStep.IsStep(TAKE_EMPTY_STEP.WAIT_AGV_START_TAKE_TASK))
{
//判断小车是否开始执行任务
bool isTaskStart = false;
if (isTaskStart)
{
Common.LogInfo("AGV已接收并开始执行回收空料架任务,等待到达取架点");
TakeEmptyStep.ToNextStep(TAKE_EMPTY_STEP.WAIT_REACH_TAKE_PLACE);
}
}else if (TakeEmptyStep.IsStep(TAKE_EMPTY_STEP.WAIT_REACH_TAKE_PLACE))
{
}
}
public override int GetPriority()
{
return _priority;
}
public override bool IsEnd()
{
return TakeEmptyStep.IsStep(TAKE_EMPTY_STEP.END);
}
/// <summary>
/// AGV离开A4
/// </summary>
private enum TAKE_EMPTY_STEP
{
NONE,
/// <summary>
/// 等待AGV开始执行去取架点任务
/// </summary>
WAIT_AGV_START_TAKE_TASK,
/// <summary>
/// 等待AGV到达取架点
/// </summary>
WAIT_REACH_TAKE_PLACE,
/// <summary>
/// AGV到达取架点
/// </summary>
REACH_TAKE_PLACE,
/// <summary>
/// 送上双层线
/// </summary>
END
}
}
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace AGVControl
{
/// <summary>
/// 客户端的节点
/// </summary>
public class ClientNode
{
private string rfid = "00";
/// <summary>
/// 节点名称
/// </summary>
public string Name { set; get; }
/// <summary>
/// IP地址
/// </summary>
public string IP { set; get; }
/// <summary>
/// RFID
/// </summary>
public string RFID
{
set
{
if (value.Length < 2)
rfid = value.PadLeft(2, '0');
else
rfid = value;
}
get
{
return rfid;
}
}
/// <summary>
/// 动作
/// </summary>
public ClientAction Action { set; get; }
/// <summary>
/// 小车名称
/// </summary>
public string AgvName { set; get; }
/// <summary>
/// 在线
/// </summary>
public bool Online { set; get; }
/// <summary>
/// 是否可用
/// </summary>
public bool IsUse { set; get; }
/// <summary>
/// 节点位置的guid
/// </summary>
public string Pos_guid { set; get; }
/// <summary>
/// 节点位置名称
/// </summary>
public string Pos_name { get; set; }
/// <summary>
/// 节点位置坐标
/// </summary>
public PositionStru position;
public string AliceName { get; set; }
/// <summary>
/// 客户端节点
/// </summary>
/// <param name="name"></param>
/// <param name="ip"></param>
/// <param name="isUse"></param>
public ClientNode(string name, string ip, string aliceName, string pos_name, string pos_guid, bool isUse)
{
Name = name;
IP = ip;
AliceName = aliceName;
RFID = rfid;
Action = ClientAction.None;
AgvName = "";
Online = false;
IsUse = isUse;
this.Pos_name = pos_name;
this.Pos_guid = pos_guid;
}
/// <summary>
/// 客户端节点
/// </summary>
/// <param name="name"></param>
/// <param name="rfid"></param>
/// <param name="action"></param>
/// <param name="level"></param>
public ClientNode(string name, string rfid = "", ClientAction action = ClientAction.None)
{
Name = name;
RFID = rfid;
Action = action;
AgvName = "";
Online = false;
IsUse = false;
}
/// <summary>
/// 所有属性的文本形式
/// </summary>
/// <returns></returns>
public string ToText()
{
string s = string.Format("Name={0}, Action={1}, RFID={2}", Name, Action, RFID);
return s;
}
public string[] ToRow()
{
//节点,IP,动作,RFID,AGV名称,在线,调用,清除AGV
string[] s = new string[9];
s[0] = AliceName;
s[1] = IP;
// if (Online)
// {
s[2] = string.Format("({0},{1})", position.X.ToString("f2"), position.Y.ToString("f2"));
s[3] = Action.ToString();
s[4] = RFID;
s[5] = AgvName;
// }
s[6] = Online ? "在线" : "离线";
s[7] = IsUse ? "是" : "否";
s[8] = "清除";
return s;
}
/// <summary>
/// 脱机
/// </summary>
public void Offline()
{
RFID = "00";
Action = ClientAction.None;
AgvName = "";
Online = false;
}
public virtual Job GetNewJob(Agv_Info agv)
{
return null;
}
}
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace AGVControl
{
/// <summary>
///
/// </summary>
public class InDoubleLineNode : ClientNode
{
public InDoubleLineNode(string name, string ip, string aliceName, string pos_name, string pos_guid, bool isUse): base(name,ip, aliceName,pos_name,pos_guid, isUse)
{
}
public override Job GetNewJob(Agv_Info agv)
{
//
return null;
}
}
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace AGVControl
{
/// <summary>
/// 双层线有料料架出口
/// </summary>
public class OutDoubleLineNode : ClientNode
{
public OutDoubleLineNode(string name, string ip, string aliceName, string pos_name, string pos_guid, bool isUse): base(name,ip, aliceName,pos_name,pos_guid, isUse)
{
}
public override Job GetNewJob(Agv_Info agv)
{
//如果有要出的料架,判断目的地线体是否空料架,如果有,暂时不出,返回
return null;
}
}
}
支持 Markdown 格式
你添加了 0 到此讨论。请谨慎行事。
Finish editing this message first!