AGV调度系统实现(二)——交通管制交流

    所谓交通管控,很容易理解,就是在某个固定区域中,哪辆AGV小车先行,哪辆AGV小车后走的问题;

一、前提条件

     要想系统进行管制,必须要有良好的网络条件(无论wifi或者射频),此外AGV的硬件一定要好,否则数据丢包会变成家常便饭;此外,一定要进行多测试,进行压力测试,场景越多越好,代码写的再好场景测试不足,再好的代码也是瞎的。之前我们公司的项目曾经在无线模块上吃过亏,1600元的模块和200元的模块差异还是很大的,不要轻易相信厂家所谓的“我们用的没有问题”,一定要进行现场实地测试;

二、算法分析

    简单的交通管控,如下图所示:

                                           

      以上区域就构成了一个简单的交通管控区域,A、D为入口点,C、B分别为出口点,简单的算法只要小车到入口点停止,然后系统判断该区域中是否有运行的小车即可,如果没有小车那么直接放行改agv即可;如果有小车那么需要,将小车加入等待队列,且用前一辆车进行管控,当且仅当前一辆车出管制区后才能放行;

此处建议大伙将程序写成单例的,否则太耗资源了,单例代码如下:

        private static readonly AgvControlService instance = new AgvControlService();
        private AgvControlService()
        {
        }
        public static AgvControlService GetInstance()
        {
            return instance;
        }

判断逻辑如下:(1)先校验是否需要进行管控,如果需要在判断是否在出口

//管控点是否需要管控
                  if (!checkNeedControl(currentLankMark))
                    {
                        logger.Info("[AGV-NO-NEED-CONTROL]:Landmarks:{0},AGV:{1}", currentLankMark, agv.Id);
                        return;
                    }
                    
                         ControlPoint controlPoint = controlPointList.Where(m => m.LandMarkId == currentLankMark).FirstOrDefault();
                        if (controlPoint == null)
                        {
                            return;
                        }

                        #region 判断是出口
                        if (controlPoint.IsExported)
                        {
                            #region 将小车移除管制区
                            AgvControlGroupModelList.RemoveAll(m => m.Agv.Id == agv.Id && m.ControlPoint.ControlGroupId == controlPoint.ControlGroupId);
                            #endregion

                            #region 遍历这个管制区是否有被该车管制住等待的小车  放行等待的车
                            AgvControlGroupModel currentControlGroupAgv = AgvControlGroupModelList.Where(m => m.ControlAgv == agv.Id && m.ControlPoint.ControlGroupId == controlPoint.ControlGroupId).OrderBy(m => m.EnterTime).FirstOrDefault();
                            if (currentControlGroupAgv != null)
                            {                                
                                    startAgv(currentControlGroupAgv.Agv);
                                    AgvControlGroupModelList.Remove(currentControlGroupAgv);
                                    currentControlGroupAgv.ControlState = ControlState.Entering;
                                    AgvControlGroupModelList.Add(currentControlGroupAgv);
                                return;
                            }
                            #endregion                          
                            return;
                        }

                        #endregion

(2)判断是否在入口

    #region 判断是入口
                        if (!controlPoint.IsExported)
                        {
                            #region 第一步 判断管制区有木有车?
                            //没有车直接放行
                            var enteringAGV = AgvControlGroupModelList.Where(m => m.ControlPoint.ControlGroupId == controlPoint.ControlGroupId && m.ControlState == ControlState.Entering);
                            if (enteringAGV == null || enteringAGV.Count() < 1)
                            {
                                logger.Info("[AGV-CONTROL-MSG]NO CARS IN THIS AREA ,SO RELEASE THIS AGV[{0}]", agv.Id);
                                AgvControlGroupModel enterAgvControlGroupModel = new AgvControlGroupModel()
                                {
                                    Agv = agv,
                                    ControlPoint = controlPoint,
                                    ControlState = ControlState.Entering,
                                    EnterTime = DateTime.Now
                                };
                                AgvControlGroupModelList.RemoveAll(m => m.Agv.Id == agv.Id && m.ControlPoint.ControlGroupId == controlPoint.ControlGroupId);
                                AgvControlGroupModelList.Add(enterAgvControlGroupModel);
                                startAgv(agv);
                                return;
                            }
                            #endregion

                            #region 第二步 判断正在运行的小车是否是这个
                           var list = enteringAGV.Where(m=>m.Agv.Id==agv.Id);
                            if (list!= null&&list.Count()>0)
                            {
                                logger.Info("[AGV-CONTROL-MSG]THIS CAR IS ENTERING CAR ,SO NO COMMAND AGV[{0}]", agv.Id);
                                startAgv(agv);
                                return;
                            }
                            #endregion

                            #region 第三步 判断正在等待的小车是否是这个
                            var waitAGV = AgvControlGroupModelList.Where(m => m.ControlPoint.ControlGroupId == controlPoint.ControlGroupId && m.ControlState == ControlState.Wait);
                            if (waitAGV != null && waitAGV.Count() > 0)
                            {
                                List<AGV> waitList = waitAGV.Select(m => m.Agv).ToList();
                                if (waitList.FindAll(m => m.Id == agv.Id) != null)
                                {
                                    logger.Info("[AGV-CONTROL-MSG]THIS CAR IS WAIT CAR ,SO NO COMMAND AGV[{0}]", agv.Id);
                                    return;
                                }
                               // return;
                            }
                            #endregion
                            //先等待的车管制后进的小车
                            AgvControlGroupModel newWaitControlGroupModel = new AgvControlGroupModel()
                            {
                                Agv = agv,
                                ControlPoint = controlPoint,
                                ControlState = ControlState.Wait,
                                EnterTime = DateTime.Now,
                                ControlAgv = item.Agv.Id
                            };
                            AgvControlGroupModelList.RemoveAll(m => m.Agv.Id == agv.Id && m.ControlPoint.ControlGroupId == controlPoint.ControlGroupId);
                            AgvControlGroupModelList.Add(newWaitControlGroupModel);
                            quickStopAgv(agv);
                            return;
                        }
                        #endregion

      这样就可以实现一个最简单的交通管制了,但是此方法在业务层面上,效率不是很高;可能存在A->B或者D->C同时存在两辆车,如果后一辆车必须等着前一辆车出管制区,才能启动的话,效率就有点低了;为此我们可以认为A->B是同一类型的,D->C是同一类型的,如果此种情况同时出现,我们可以在放行前一辆车的同时放行后一辆车

var item = enteringAGV.OrderByDescending(m => m.EnterTime).FirstOrDefault();
                            if (!string.IsNullOrEmpty(controlPoint.Name) && !string.IsNullOrEmpty(item.ControlPoint.Name) && controlPoint.Name.Equals(item.ControlPoint.Name))
                            {
                                AgvControlGroupModel enterAgvControlGroupModel = new AgvControlGroupModel()
                                {
                                    Agv = agv,
                                    ControlPoint = controlPoint,
                                    ControlState = ControlState.Entering,
                                    EnterTime = DateTime.Now
                                };
                                AgvControlGroupModelList.RemoveAll(m => m.Agv.Id == agv.Id && m.ControlPoint.ControlGroupId == controlPoint.ControlGroupId);
                                AgvControlGroupModelList.Add(enterAgvControlGroupModel);
                                startAgv(agv);
                                return;
                            }

 复杂的交通管制,会在管制区中嵌套多个管制区,或者再管制区中再对接其他的指令,这种情况就需要现场仔细调试了。

   

  • 5
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
AGV调度开发实现C是指使用C编程语言来实现自动导引车(AGV)的调度功能。 实现AGV调度功能主要包括以下几个步骤。 首先,需要定义AGV调度算法调度算法是指根据任务的优先级、AGV的当前位置以及任务的起止位置等因素,确定AGV的行驶路径和顺序。可以采用最短路径算法、贪心算法或遗传算法等不同的调度算法实现AGV调度。 其次,需要使用C语言编写代码实现调度算法。在代码中,可以定义各种数据结构来表示AGV、任务和地图等信息,并编写相应的函数来实现调度算法。可以利用C语言提供的控制结构、循环和条件判断等功能来实现具体的调度逻辑。 然后,需要将调度算法AGV的控制系统进行集成。AGV的控制系统一般由硬件和软件组成,包括传感器、执行器和底层控制器等。在集成时,需要根据调度算法的需求,通过软件接口或编写驱动程序来与硬件进行通信,并控制AGV的运动,实现调度功能。 最后,需要对调度系统进行测试和优化。通过模拟不同的场景和任务,验证调度算法实现的正确性和性能。如果发现问题或不足,可以通过调整参数、改进算法或优化代码等方式来提高调度系统的效果。 总之,使用C语言开发实现AGV调度功能需要定义调度算法、编写代码实现调度逻辑并与AGV的控制系统集成,然后进行测试和优化,以实现高效、可靠的AGV调度功能。
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值