Commit 2bcd27b0 张东亮

楼上两小车抢用同一电梯问题修复

1 个父辈 c0e131f3
......@@ -25,7 +25,7 @@
<!--点位配置文件名-->
<add key="File_NodeInfo" value="nodeinfos.xml" />
<!--使用到的电梯名配置名-->
<add key="Lift_Names" value="LEFT_D2,LEFT_C1" />
<add key="Lift_Names" value="LIFT_D2,LIFT_C1" />
<!--充电最低/最高电量值-->
<add key="ChargeThreshold" value="20,90" />
<!--等待人员操作超时时间(分钟)-->
......
......@@ -118,6 +118,10 @@ namespace AGVControl
}
}
catch { }
foreach (string item in Agv.Scope.Remark.Split(','))
{
DeviceLibrary.lift.LiftContext.ResetLiftOccupiedAgv(item);
}
//MiR_API.Del_Mission(Agv);
//添加Init任务
AgvTaskManager.AssignMission(Agv, $"{SettingString.Init}");
......
......@@ -45,6 +45,7 @@ namespace AGVControl
LogUtil.info("=====程序开始=====");
NodeManager.InitNodesInfos();
IOManager.Start();
DeviceLibrary.lift.LiftContext.Init();
DeviceLibrary.manager.MissionManager.InitMission();
ChargePileManager.Init();
AGVManager.Init();
......
<?xml version="1.0" encoding="utf-8"?>
<agvs>
<agv id="20" ip="10.85.199.68">
<agv id="20" ip="192.168.101.75">
<name>2号车</name>
<!--职责范围-->
<Scope>
......
......@@ -111,9 +111,9 @@ namespace DeviceLibrary
Thread.Sleep(50);
MiR_API.Get_IO_Status(agv);
//获取AGV状态
rtn = MiR_API.Get_State(agv, out eAGVState stateID, out string stateText, out int battery, out string mission_text, out AgvInfo.MirPosition position);
rtn = MiR_API.Get_State(agv, out eAGVState stateID, out string stateText, out int battery, out string mission_text, out AgvInfo.MirPosition position,out List<Mir_Error> errors);
Thread.Sleep(50);
if (rtn) change = agv.SetState(stateID, battery, mission_text, position);
if (rtn) change = agv.SetState(stateID, battery, mission_text, position, errors);
// if (change)
{
......
......@@ -62,6 +62,7 @@
<ItemGroup>
<Compile Include="bean\agv\Agv_Info.cs" />
<Compile Include="bean\agv\JobContext.cs" />
<Compile Include="bean\agv\Mir_Error.cs" />
<Compile Include="bean\agv\Scope.cs" />
<Compile Include="bean\ChargePiles.cs" />
<Compile Include="bean\jobType\LineToLineJobType.cs" />
......@@ -85,6 +86,7 @@
<Compile Include="Control.cs" />
<Compile Include="lift\ClientStatus.cs" />
<Compile Include="lift\LiftContext.cs" />
<Compile Include="lift\LiftInfo.cs" />
<Compile Include="lift\LiftStatus.cs" />
<Compile Include="manager\IOManager.cs" />
<Compile Include="manager\NodeManager.cs" />
......
......@@ -571,16 +571,17 @@ namespace DeviceLibrary
/// <param name="battery"></param>
/// <param name="mission_text"></param>
/// <returns></returns>
public static bool Get_State(AgvInfo info, out eAGVState stateID, out string stateText, out int battery, out string mission_text, out MirPosition position)
public static bool Get_State(AgvInfo info, out eAGVState stateID, out string stateText, out int battery, out string mission_text, out MirPosition position,out List<Mir_Error> mir_Errors)
{
stateID = eAGVState.UNKNOWN;
stateText = "";
battery = 0;
mission_text = "";
position = new MirPosition();
mir_Errors = new List<Mir_Error>();
try
{
string url = "http://" + info.IP + "/api/v2.0.0/status?whitelist=state_id,state_text,battery_percentage,mission_text,position";
string url = "http://" + info.IP + "/api/v2.0.0/status?whitelist=state_id,state_text,battery_percentage,mission_text,position,errors";
string json = HttpGet(url, info.IP, info.Authorization);
if (string.IsNullOrWhiteSpace(json)) return false;
JavaScriptSerializer serializer = new JavaScriptSerializer();
......@@ -609,6 +610,17 @@ namespace DeviceLibrary
position.orientation = Convert.ToSingle(posDic["orientation"].ToString());
position.Point.X = Convert.ToSingle(posDic["x"]);
position.Point.Y = Convert.ToSingle(posDic["y"]);
object[] errors = (object[])dic["errors"];
if(errors !=null)
{
foreach (var item in errors)
{
Dictionary<string, object> tmp = (Dictionary<string, object>)item;
mir_Errors.Add(new Mir_Error() { code=int.Parse(tmp["code"].ToString()),
description=tmp["description"].ToString(), module=tmp["module"].ToString() });
}
}
return true;
}
catch (Exception ex)
......
......@@ -92,7 +92,7 @@ namespace DeviceLibrary
/// 小车的状态ID,(从小车获取)
/// </summary>
public eAGVState StateID { set; get; }
public List<Mir_Error> Errors { get; set; }
/// <summary>
/// 负载
/// </summary>
......@@ -265,7 +265,7 @@ namespace DeviceLibrary
Place = new Node();
Msg = "";
Position = new MirPosition();
RunInfos = new List<string>() { "状态", "目的地", "车间", "负载", "运行模式", "任务信息", "AGV运行信息" };
RunInfos = new List<string>() { "状态", "目的地", "车间", "负载", "运行模式", "任务信息", "AGV运行信息","错误消息"};
StateKanban = new AGV_UI.Status(name, RunInfos);
}
public AgvInfo()
......@@ -273,7 +273,7 @@ namespace DeviceLibrary
Place = new Node();
Msg = "";
Position = new MirPosition();
RunInfos = new List<string>() { "状态", "目的地", "车间", "顶升", "运行模式", "任务信息", "AGV运行信息" };
RunInfos = new List<string>() { "状态", "目的地", "车间", "顶升", "运行模式", "任务信息", "AGV运行信息", "错误消息" };
StateKanban = new AGV_UI.Status(RunInfos);
IOStatus = new List<IOInfo>();
TaskRunState = new TaskRunState();
......@@ -284,7 +284,7 @@ namespace DeviceLibrary
int IoLastTime = 5000;
int StandLastTimeMinute = AppConfigHelper.GetIntValue(SettingString.StandTimeout);
public DateTime StandStartTime = DateTime.MaxValue;
public bool SetState(eAGVState stateID, int battery, string missionText, MirPosition position)
public bool SetState(eAGVState stateID, int battery, string missionText, MirPosition position,List<Mir_Error> mir_Errors)
{
bool isChange = false;
bool preShelfState = IsExistShelf;
......@@ -343,6 +343,11 @@ namespace DeviceLibrary
MissionText = missionText;
StateKanban.ShowInfo("AGV运行信息", missionText);
}
if(mir_Errors !=null && mir_Errors.Count > 0)
{
Errors = mir_Errors;
StateKanban.ShowInfo("错误消息",string.Join(";",Errors));
}
CheckErrorState();
CheckOfflineTimeOut();
CheckStandTimeOut(position);
......@@ -520,7 +525,11 @@ namespace DeviceLibrary
if (!isAlarm && errorState)
{
isAlarm = true;
SetErrorMsg("状态:" + StateID.ToString(), (DateTime.Now - offlineStartTime).TotalMinutes.ToString("f2"));
if(Errors!=null && Errors.Count > 0)
{
SetErrorMsg($"状态:[{StateID.ToString()}][{string.Join(";", Errors)}]", (DateTime.Now - offlineStartTime).TotalMinutes.ToString("f2"));
}
SetErrorMsg($"状态:{StateID.ToString()}", (DateTime.Now - offlineStartTime).TotalMinutes.ToString("f2"));
msglist.Add(new AlarmMsg(Name, "lineAgv." + Name + ".Msg", StateID.ToString()));
}
......
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace DeviceLibrary
{
public class Mir_Error
{
public int code { get; set; }
public string description { get; set; }
public string module { get; set; }
public override string ToString()
{
return $"code={code},description={description},module={module}";
}
}
}
......@@ -56,6 +56,7 @@ namespace DeviceLibrary.bean.job
JobRunStep.ToNextStep(RunStep.S1F_LiftToStore_02_02_EnterLift);
runInfo = $"{JobParam.SrcNode.AliceName}门已开启,去取料点";
//任务状态变更
lift.LiftContext.SetLiftOccupiedAgv(JobParam.SrcNode.Name,agv.IP);
MissionManager.SetMissionState(JobParam.GetMissionInfo().missionId, service.model.MissionState.返回电梯到达, out string msg);
AllocateTask(agv, $"{JobParam.SrcNode.Name}_{SettingString.PutShelfOn}");
JobRunStep.Msg = runInfo;
......
......@@ -99,6 +99,7 @@ namespace DeviceLibrary
if (lift.LiftContext.HasShelfNeedLeave(JobParam.CurTargetNode.Name, agv.Client, out liftStatus))
{
JobRunStep.ToNextStep(RunStep.S1F_StoreToLift_05_01_ToTemp1);
lift.LiftContext.SetLiftOccupiedAgv(JobParam.CurTargetNode.Name, agv.IP);
runInfo = $"{JobParam.CurTargetNode.AliceName}已开门。电梯内有料车,去临时点1的卸料点,准备卸下车上料车";
AllocateTask(agv, $"{JobParam.CurTargetNode.Name}_{SettingString.Temp1}_{SettingString.TakeShelfOff}");
service.model.MissionInfo missionInfo = manager.MissionManager.GetMission(liftStatus.missionId);
......
......@@ -56,6 +56,7 @@ namespace DeviceLibrary.bean.job
if (lift.LiftContext.IsDoorOpen(JobParam.SrcNode.Name, JobParam.GetMissionInfo().destinationFloor))
{
JobRunStep.ToNextStep(RunStep.SD_LiftToLine_03_EnterLift);
lift.LiftContext.SetLiftOccupiedAgv(JobParam.SrcNode.Name, agv.IP);
runInfo = $"{JobParam.SrcNode.AliceName}门已开启,进电梯取料点";
AllocateTask(agv, $"{JobParam.SrcNode.Name}_{SettingString.PutShelfOn}");
//任务状态变更
......@@ -219,6 +220,7 @@ namespace DeviceLibrary.bean.job
if (lift.LiftContext.IsDoorOpen(JobParam.SrcNode.Name, JobParam.GetMissionInfo().destinationFloor))
{
JobRunStep.ToNextStep(RunStep.SD_LiftToLine_13_CheckLiftStatus);
lift.LiftContext.SetLiftOccupiedAgv(JobParam.SrcNode.Name, agv.IP);
runInfo = $"{JobParam.SrcNode.AliceName}门已开,检查电梯内该层是否有料车";
JobRunStep.Msg = runInfo;
//上报位置
......
......@@ -9,15 +9,16 @@ namespace DeviceLibrary.lift
public class LiftContext
{
/// <summary>
/// 所有电梯
/// 所有电梯状态
/// </summary>
static Dictionary<string, LiftStatus> lifts = new Dictionary<string, LiftStatus>();
static Dictionary<string, LiftInfo> lifts = new Dictionary<string, LiftInfo>();
public static void Init()
{
string[] names = Common.AppConfigHelper.GetValue(Common.SettingString.Lift_Names).Split(',');
foreach (var item in names)
{
lifts.Add(item, new LiftStatus());
lifts.Add(item, new LiftInfo());
}
Common.LogUtil.info($"加载电梯信息完成:{string.Join(",", names)}");
}
......@@ -29,19 +30,11 @@ namespace DeviceLibrary.lift
public static bool IsDoorOpen(string liftId, int floor)
{
LiftStatus liftStatus = GetLiftStatus(liftId);
if (liftStatus.door.Equals("opened") && liftStatus.floor.Equals(floor))
if (liftStatus.door.Equals("opened") && liftStatus.floor.Equals(floor) &&!CheckLiftOccupied(liftId))
return true;
return false;
}
/// <summary>
/// 电梯关门
/// </summary>
/// <param name="liftId"></param>
//public static void CloseDoor(string liftId,AgvInfo agvInfo)
//{
// bool rtn= HttpManager.CloseDoor(new service.model.DoorInfo() { liftId=liftId,sourceClient=agvInfo.Client,sourceFloor=agvInfo.Scope.Floor});
// Common.LogUtil.info($"{agvInfo.Name} 关门 {rtn}");
//}
/// <summary>
/// 请求使用电梯
/// </summary>
......@@ -63,7 +56,7 @@ namespace DeviceLibrary.lift
{
liftId = missionInfo.liftName,
destinationFloor = missionInfo.sourceFloor,
destinationPoint = missionInfo.sourcePoint,
destinationPoint = missionInfo.sourcePoint,
destinationClient = destclient,
sourceFloor = missionInfo.destinationFloor,
sourceClient = agvInfo.Client
......@@ -104,7 +97,8 @@ namespace DeviceLibrary.lift
public static bool AGVLeave(string liftId, AgvInfo agvInfo)
{
bool rtn = HttpManager.AGVLeave(new service.model.DoorInfo() { liftId = liftId, sourceClient = agvInfo.Client, sourceFloor = agvInfo.Scope.Floor });
Common.LogUtil.info($"{agvInfo.Name} 离开 {rtn}");
ResetLiftOccupiedAgv(liftId);
Common.LogUtil.info($"{agvInfo.Name} 离开 {liftId}:{rtn}");
return rtn;
}
/// <summary>
......@@ -127,19 +121,11 @@ namespace DeviceLibrary.lift
/// <returns></returns>
public static bool CheckAgvLeaveSig(string liftId)
{
if (!lifts[liftId].door.Equals("opened"))
if (!lifts[liftId].LiftStatus.door.Equals("opened"))
return true;
return false;
}
/// <summary>
/// 运行到指定楼层
/// </summary>
/// <param name="liftId"></param>
/// <param name="floor"></param>
//public static void RunTo(string liftId,int floor)
//{
//}
/// <summary>
/// 有架子需要离开电梯
/// </summary>
/// <param name="liftId"></param>
......@@ -168,6 +154,34 @@ namespace DeviceLibrary.lift
return false;
}
/// <summary>
/// 占用电梯的agv
/// </summary>
/// <param name="agvIp"></param>
public static void SetLiftOccupiedAgv(string liftId,string agvIp)
{
lifts[liftId].OccupiedAgv = agvIp;
}
public static void ResetLiftOccupiedAgv(string liftId)
{
try
{
lifts[liftId].OccupiedAgv = "";
}
catch (Exception ex)
{
Common.LogUtil.error($"清除电梯占用失败:{liftId}", ex);
}
}
/// <summary>
/// 检查电梯是否被占用
/// </summary>
/// <param name="liftId"></param>
/// <returns>true:占用</returns>
public static bool CheckLiftOccupied(string liftId)
{
return !lifts[liftId].OccupiedAgv.Equals("");
}
/// <summary>
/// 获取电梯状态
/// </summary>
/// <param name="liftId"></param>
......@@ -176,7 +190,7 @@ namespace DeviceLibrary.lift
{
if (lifts.ContainsKey(liftId))
{
return lifts[liftId];
return lifts[liftId].LiftStatus;
}
else
return new LiftStatus();
......@@ -192,7 +206,7 @@ namespace DeviceLibrary.lift
LiftStatus lift = HttpManager.UpdateStatusToLift(status);
if (lift != null)
{
lifts[status.liftId] = lift;
lifts[status.liftId].LiftStatus = lift;
}
}
catch (Exception e)
......
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace DeviceLibrary.lift
{
public class LiftInfo
{
public LiftStatus LiftStatus { get; set; }
public string OccupiedAgv { get; set; } = "";
public LiftInfo()
{
LiftStatus = new LiftStatus();
}
}
}
......@@ -96,12 +96,16 @@ namespace DeviceLibrary
}
else
{
string[] names = taskname.Split('_');
foreach (string item in names)
node = manager.NodeManager.GetNodeByName(taskname);
if (node == null)
{
node = manager.NodeManager.GetNodeByName(item);
if (node != null)
break;
string[] names = taskname.Split('_');
foreach (string item in names)
{
node = manager.NodeManager.GetNodeByName(item);
if (node != null)
break;
}
}
}
......
......@@ -38,6 +38,8 @@ namespace DeviceLibrary.manager
if (item.StateID.Equals(eAGVState.Error) || item.StateID.Equals(eAGVState.EmergencyStop))
{
agvState.state = "故障中";
if (item.Errors != null && item.Errors.Count > 0)
agvState.remark = string.Join(";",item.Errors);
}
else if (item.Auto)
{
......
支持 Markdown 格式
你添加了 0 到此讨论。请谨慎行事。
Finish editing this message first!