可达性状态编程:修订间差异

来自MDCS wiki
跳到导航 跳到搜索
无编辑摘要
 
(未显示2个用户的3个中间版本)
第1行: 第1行:
可达性状态编程是SimpleCore提供的重要功能。AGV集群运行时经常出现多车的业务相关的通行顺序,这些通行顺序和地图、包络等无关,仅仅和场景状态有关。比如以下一些典型场景:
可达性状态编程是SimpleCore提供的重要功能。AGV集群运行时经常出现多车的业务相关的通行顺序,这些通行顺序和地图、包络等无关,仅仅和场景状态有关。比如以下一些典型场景:
[[文件:四向穿梭车多车送货举例.jpg|缩略图|四向穿梭车多车送货举例,A车B车同时往一个巷道送货。此时只能B车先送货后,A车才能送货。否则A车放下的货物会妨碍B车将货物送达终点。]]
* 四向穿梭车场景中,多台车向同一个巷道送货。
* 四向穿梭车场景中,多台车向同一个巷道送货。
* 驶入式巷道中,多台叉车向同一个巷道送货或取货。
* 驶入式巷道中,多台叉车向同一个巷道送货或取货。
* 产线对接时,使用两台车分别进行取满托盘、送空托盘。
* 产线对接时,使用两台车分别进行取满托盘、送空托盘。
* 车辆各自去不同地点加工,在最终汇集路线上保持特定排序。


Simple提供Reachability功能来自动化处理这些冲突。类似于编程器(Coder)和包络(Enveloper),可达状态也是通过插件来声明的。可用的方法包括:
Simple提供Reachability功能来自动化处理这些冲突。类似于编程器(Coder)和包络(Enveloper),可达状态也是通过插件来声明的。可用的方法包括:


* SiteReachability/TrackReachability中:Require/Reject/Declare/Clear,分别为“需要某个状态”,“如果某状态存在则拒绝”,“声明一个状态”,“清除某个状态”
* SiteReachability/TrackReachability中:Require/Reject/Declare/Clear,分别为“需要某个状态”,“如果某状态存在则拒绝”,“声明一个状态”,“清除某个状态”
* Scene.conf.RemoveReachabilityState/AddReachabilityState来从外部增加或删除状态(比如外部设备拿走了货物或放下货物)
* 可以使用Scene.DeclareOracleState/ClearOracleState来生成'''主要由调度生成的状态'''。
* '''如果主要由车辆生成、消灭的状态''',出现运行异常情况使得状态无法消除或增加,可以使用Scene.RemoveReachabilityState/AddReachabilityState来从外部增加或删除状态(比如车辆故障,人工拿走了货物或放下了货物等)。
* 使用Scene.conf.status.reachabilityState 查看全部状态。
* 使用Scene.conf.status.reachabilityState 查看全部状态。


 
=== 【四向穿梭车场景中,多台车向同一个巷道送货】Demo。 ===
以下是一个范例,可用于处理【四向穿梭车场景中,多台车向同一个巷道送货】。<syntaxhighlight lang="c#" line="1">
[[文件:四向穿梭车多车送货举例.jpg|缩略图|四向穿梭车多车送货举例,A车B车同时往一个巷道送货。此时只能B车先送货后,A车才能送货。否则A车放下的货物会妨碍B车将货物送达终点。]]<syntaxhighlight lang="c#" line="1">
public class LoadedTest : SiteReachability<ReachabilityTestCar>
public class LoadedTest : SiteReachability<ReachabilityTestCar>
{
{
  public override int priority => 1;
  public override int priority => 1;
  public override bool Block() => false;
public override bool Use() => plan.fields.ContainsKey("put"); //对于该点,是否使用本判定器?
  public override void Prompt() => this.Reject($"cargo{site.id}");
  public override bool Block() => false; //若使用本判定器,是否还使用别的判定器?
public override bool Use() => plan.fields.ContainsKey("put");
  public override void Prompt() => this.Reject($"cargo{site.id}"); //如何判定?
}
}


第25行: 第25行:
{
{
  public override int priority => 1;
  public override int priority => 1;
public override bool Use() => plan.fields.ContainsKey("put") && curSeg == plan.segments.Count - 1;
  public override bool Block() => false;
  public override bool Block() => false;
  public override void Prompt() => Declare($"cargo{site.id}");
  public override void Prompt() => Declare($"cargo{site.id}");
public override bool Use() => plan.fields.ContainsKey("put") && curSeg == plan.segments.Count - 1;
}
}
</syntaxhighlight>理解要点:
</syntaxhighlight>理解要点:
第33行: 第33行:
# 可达性编程的测试,是对车辆各自进行判断“如果存在某个状态,那么下个点还是否允许走”。它不声明“全局指挥性”的约束——虽然这种约束经常能拆分成车辆的各自判断。
# 可达性编程的测试,是对车辆各自进行判断“如果存在某个状态,那么下个点还是否允许走”。它不声明“全局指挥性”的约束——虽然这种约束经常能拆分成车辆的各自判断。


 
=== 【车辆各自去不同地点加工,在最终汇集路线上保持特定排序】Demo ===
Demo
场景:某主线AGV,路径是环线,小车会按照车号顺序依次行驶。由于车型不同,装配工位因此不同,存在分支路径:会需要AGV停靠在B、C点装配并需要不确定的时间。而在汇入E的时候需要保证原先的跟车顺序。根据Reachability特性,可以实现该功能,方式如下:
 
场景:某主线AGV,路径是环线,小车会按照车号顺序依次行驶,由于车型不同,装配工位因此不同,存在分支路径,会需要AGV停靠在B、C点装配,在汇入E的时候需要保证原先的跟车顺序,根据Reachability特性,可以实现该功能,方式如下:


[[文件:Image22.png|无框|1117x1117像素]]
[[文件:Image22.png|无框|1117x1117像素]]


根据小车VIN号进行排序,解锁的条件可以提炼成:当前车辆VIN号-1的车辆经过汇入点后,当前车才允许拿到汇入点的锁,因此状态条件如下
根据小车VIN号进行排序,解锁的条件可以提炼成:当前车辆VIN号-1的车辆经过汇入点后,当前车才允许拿到汇入点的锁,因此状态条件如下
第55行: 第52行:
     public override void Prompt()
     public override void Prompt()
     {
     {
        var myvin = int.Parse(usingCar.tags["Vin"]);
    if (usingCar.tags.ContainsKey("Vin"))
        if (myvin > 0)
    {
        {
        var myVin = int.Parse(usingCar.tags["Vin"]);
            Require($"passed{myvin - 1}");
        if (myVin > 0)
            Clear($"passed{myvin - 1}");
        {
        }
            Require($"passed{myVin - 1}");
            Clear($"passed{myVin - 1}");
        }


        Declare($"passed{myvin}");
        Declare($"passed{myVin}");
    }
     }
     }
     public override bool Use()
     public override bool Use()

2025年4月7日 (一) 13:49的最新版本

可达性状态编程是SimpleCore提供的重要功能。AGV集群运行时经常出现多车的业务相关的通行顺序,这些通行顺序和地图、包络等无关,仅仅和场景状态有关。比如以下一些典型场景:

  • 四向穿梭车场景中,多台车向同一个巷道送货。
  • 驶入式巷道中,多台叉车向同一个巷道送货或取货。
  • 产线对接时,使用两台车分别进行取满托盘、送空托盘。
  • 车辆各自去不同地点加工,在最终汇集路线上保持特定排序。

Simple提供Reachability功能来自动化处理这些冲突。类似于编程器(Coder)和包络(Enveloper),可达状态也是通过插件来声明的。可用的方法包括:

  • SiteReachability/TrackReachability中:Require/Reject/Declare/Clear,分别为“需要某个状态”,“如果某状态存在则拒绝”,“声明一个状态”,“清除某个状态”
  • 可以使用Scene.DeclareOracleState/ClearOracleState来生成主要由调度生成的状态
  • 如果主要由车辆生成、消灭的状态,出现运行异常情况使得状态无法消除或增加,可以使用Scene.RemoveReachabilityState/AddReachabilityState来从外部增加或删除状态(比如车辆故障,人工拿走了货物或放下了货物等)。
  • 使用Scene.conf.status.reachabilityState 查看全部状态。

【四向穿梭车场景中,多台车向同一个巷道送货】Demo。

四向穿梭车多车送货举例,A车B车同时往一个巷道送货。此时只能B车先送货后,A车才能送货。否则A车放下的货物会妨碍B车将货物送达终点。
public class LoadedTest : SiteReachability<ReachabilityTestCar>
{
 public override int priority => 1;
 public override bool Use() => plan.fields.ContainsKey("put"); //对于该点,是否使用本判定器?
 public override bool Block() => false; //若使用本判定器,是否还使用别的判定器?
 public override void Prompt() => this.Reject($"cargo{site.id}"); //如何判定?
}

public class PutCargo : SiteReachability<ReachabilityTestCar>
{
 public override int priority => 1;
 public override bool Use() => plan.fields.ContainsKey("put") && curSeg == plan.segments.Count - 1;
 public override bool Block() => false;
 public override void Prompt() => Declare($"cargo{site.id}");
}

理解要点:

  1. 可达性编程的测试,是对车辆各自进行判断“如果存在某个状态,那么下个点还是否允许走”。它不声明“全局指挥性”的约束——虽然这种约束经常能拆分成车辆的各自判断。

【车辆各自去不同地点加工,在最终汇集路线上保持特定排序】Demo

场景:某主线AGV,路径是环线,小车会按照车号顺序依次行驶。由于车型不同,装配工位因此不同,存在分支路径:会需要AGV停靠在B、C点装配并需要不确定的时间。而在汇入E的时候需要保证原先的跟车顺序。根据Reachability特性,可以实现该功能,方式如下:

根据小车VIN号进行排序,解锁的条件可以提炼成:当前车辆VIN号-1的车辆经过汇入点后,当前车才允许拿到汇入点的锁,因此状态条件如下

Require($"passed{myvin - 1}")

Clear($"passed{myvin - 1}")

在Require给锁后把该状态清理

并且声明当前车的状态,用于后车的下次汇入的条件判断

public class WaitForVINOrder : SiteReachability<MultiWheelLifterCar>
{
    public override int priority => 1;
    public override bool Block() => false;
    public override void Prompt()
    {
     if (usingCar.tags.ContainsKey("Vin"))
     {
         var myVin = int.Parse(usingCar.tags["Vin"]);
         if (myVin > 0)
         {
             Require($"passed{myVin - 1}");
             Clear($"passed{myVin - 1}");
         }

         Declare($"passed{myVin}");
     }
    }
    public override bool Use()
    {
        return site.fields.ContainsKey("confluence");
    }
}