查看“使用手册 - Simple:coder(路径编译器)机制详解”的源代码
←
使用手册 - Simple:coder(路径编译器)机制详解
跳到导航
跳到搜索
因为以下原因,您没有权限编辑本页:
您请求的操作仅限属于该用户组的用户执行:
管理员
您可以查看和复制此页面的源代码。
== 1.概念 == 路径编译是MDCS架构中一个重要概念,它是上位调度系统与下位车端系统之间的桥梁。路径编译发生在寻路完成之后,路径编译的操作对象是由“站点、路径、站点、路径......”构成的序列,路径编译的结果是一串AGV可以执行的命令脚本,该脚本对应车端SimpleAGVInterface里面定义的接口。 == 2.机制介绍 == 我们将编译器称为“coder”,实际业务中,整个编译逻辑是由若干的coder构成的。也就是说,coder在同一个站点或者可以叠加使用。处理路径的,称为trackCoder;处理站点的,称为siteCoder。定义好某个车型的所有coder,就完成了该车型的业务层面的所有行为定义(即,在什么路径/站点上触发什么样的行为)。下面用一个具体的例子详细解释coder运行的机制。 [[文件:B3fa65c75ecd770e5882c459a9b232e.png|无框|600x600像素]] 我们将“小车从A到B”的过程称为一个“plan”。如上图所示,假设已经生成了`模拟车1`的一段plan。该plan包含6个site(站点)、5段track(路径),共11个segment。编译路径时,依据通行顺序检查所有segment。对于每一个segment,若它是站点,则检查所有的siteCoder;若它是路径,则检查所有的路径trackCoder。对于每一个被检查的coder,依次判断其是否能够触发,触发后生成AGV脚本,并判断是否继续检查剩余的coder。如下图所示,为车辆执行的脚本。 [[文件:2ff3859cb01c4c06dfdd71120a5e910.png|无框|600x600像素]] == 3.TemplateCoderSettings使用方法 == === 3.1 CoderSettings中字段含义 === <code>TemplateTrackCoderSettings</code>和<code>TemplateSiteCoderSittings</code>是分别实现trackCoder和SiteCoder的[https://learn.microsoft.com/zh-cn/dotnet/csharp/advanced-topics/reflection-and-attributes/attribute-tutorial Attribute],通过在Simple工程中xxxCar.cs中小车类之前添加<code>TemplateTrackCoderSettings</code>和<code>TemplateSiteCoderSittings</code>定义站点编译器。下方DummyCar的示例,无条件地将所有路径编译为agv.Go()这一动作:<syntaxhighlight lang="c#" line="1"> class DummyCarTrackField { public int speed = -1; public bool reverse = false; public int reverseDst = -1; } [TemplateTrackCoderSettings( templateString = "agv.Go(${src.x},${src.y},${src.id},${dst.x},${dst.y},${dst.id},${track.id},${track.speed},${track.reverse || track.reverseDst == dst.id});", priority = 0, trackFields = typeof(DummyCarTrackField), useVerb = "true", blck)] [CarType("模拟车")] public class DummyCar : Car </syntaxhighlight>CoderSitting中包含以下字段: {| class="wikitable" |+ !字段 !类型 !含义 |- |templateString |string |编译后执行的命令 |- |priority |int |优先级,数值越大越先被检查 |- |siteFields |Type |定义站点字段的类的Type |- |trackFields |Type |定义路径字段的类的Type |- |planFields |Type |定义车辆字段的类的Type |- |useVerb |string |触发条件。默认为"true" |- |blockVerb |string |触发后,若blockVerb为"true",则不再检查其他优先级更低的coder;若为"false",则继续检查剩余优先级更低的coder。默认为"false" |} 其中,<code>templateString</code>、<code>useVerb</code>、<code>blockVerb</code>都是字符串,通过[https://github.com/sebastienros/jint Jint]将字符串视为JavaScript代码,进行解析执行。 <code>templateString</code>、<code>useVerb</code>、<code>blockVerb</code>中可以使用如下定义好的对象。'''注意,<code>TemplateCoderSittings</code>中不可使用<code>src</code>这一字段,<code>dst</code>代表当前站点。''' {| class="wikitable" |+ !对象 !含义 ! colspan="2" |包含字段 |- | rowspan="2" |car | rowspan="2" |当前plan所使用的小车 |car.id |小车id |- | colspan="2" |carFields中定义的其他字段 |- | rowspan="4" |src | rowspan="4" |路径起点 |src.id |起点的id |- |src.x |起点的x坐标 |- |src.y |起点的y坐标 |- | colspan="2" |siteFields中定义的其他字段 |- | rowspan="4" |dst | rowspan="4" |路径终点 |dst.id |终点的id |- |dst.x |终点的x坐标 |- |dst.y |终点的y坐标 |- | colspan="2" |siteFields中定义的其他字段 |- | rowspan="4" |plan | rowspan="4" |当前任务 |segN |任务总元素数 |- |curSeg |当前元素下标 |- |src |任务起点 |- |dst |任务终点 |- |prev |前一个segment,若无返回null | | |- |next |后一个segment,若无返回null | | |} <code>templateString</code>、<code>useVerb</code>、<code>blockVerb</code>中还预定义了如下方法: {| class="wikitable" |+ !'''方法''' !'''含义''' |- |getSite |返回指定id的站点 |- |getTrack |返回指定id的路径 |- |getCar |返回指定id的小车 |- |getSegment |返回指定下标的segment |} === 3.2 编写自己的coderSitting === 以最常见的取放货为例,首席需要将使用的字段定义在类中,站点字段定义在SiteFields类中,路径字段定义在TrackFields类中。 下述coder的执行条件为<code>plan.action=='put'&& dst.shelf</code>,即站点上标记了<code>shelf = true</code>字段,并且这是放货plan时,才会下发<code>templateString</code>中的脚本,并且站点及路径上标记的响应字段的值也会跟随脚本下发。<syntaxhighlight lang="c#" line="1"> class SiteFields { public bool shelf = false; public int obArea = -1; public int ASNub = -1; public float angle = 0; public float shelfWidth = 1030; public float distance = 500; } [TemplateTrackCoderSettings( priority = 5, useVerb = "plan.action=='put' && dst.shelf ", templateString = "agv.Wait();agv.Put(${dst.ASNub},${dst.shelfWidth},${dst.obArea},${src.x},${src.y},${src.id},${dst.x},${dst.y},${dst.id},${track.id},${track.speed},${dst.reverse},${dst.xbias},${dst.ybias},${dst.angle},${dst.distance});agv.Wait();", blockVerb = "true", siteFields = typeof(SiteFields), trackFields = typeof(TrackFields), planFields = typeof(PlanField))] </syntaxhighlight> === 3.3 simple内置的coder === 所有的小车类均继承了车体抽象类<code>AbstractCar</code>,抽象类中定义了如下几个coder: 队列动作。在站点的codeQueue字段上定义脚本,在该站点发生路径切换时执行。<syntaxhighlight lang="c#" line="1"> [TemplateSiteCoderSettings(priority = 100, useVerb = "dst.codeQueue!=null", templateString = "agv.Queue(()=>{},()=>{${dst.codeQueue}});", blockVerb = "true", siteFields = typeof(StandardSiteFields))] </syntaxhighlight>到达动作。在站点的codeArrive字段上定义AGV脚本,在AGV达到该站点发时(完全停车后)执行。<syntaxhighlight lang="c#" line="1"> [TemplateSiteCoderSettings(priority = 100, useVerb = "dst.codeArrive!=null && plan.curSeg!=0", templateString = "agv.Wait(); ${dst.codeArrive};", siteFields = typeof(StandardSiteFields))] </syntaxhighlight>离开动作。在站点的codeLeave字段上定义AGV脚本,在AGV从该站点离开之前执行。<syntaxhighlight lang="c#" line="1"> [TemplateSiteCoderSettings(priority = 100, useVerb = "dst.codeLeave!=null && plan.curSeg!=plan.segN-1", templateString = "agv.Wait(); ${dst.codeLeave};", siteFields = typeof(StandardSiteFields))] </syntaxhighlight>空路径。即指定某段路径不执行具体动作(相当于直接跳过)。<syntaxhighlight lang="c#" line="1"> [TemplateTrackCoderSettings( priority = 100, siteFields = typeof(StandardSiteFields), useVerb = "track.nop && (track.nopDst==-1 || track.nopDst==dst.id)", blockVerb = "true", templateString = "agv.Nop(${src.id},${dst.id},${track.id});", trackFields = typeof(StandardTrackFields))] </syntaxhighlight>切换动作。在站点的switchString字段上定义脚本,在该站点发生路径切换时执行。一般用于进行障碍物切换。<syntaxhighlight lang="c#" line="1"> [TemplateTrackCoderSettings( priority = 20, useVerb = "track.switcher", templateString = "agv.Queue(()=>{}, ()=>{${dst.switchString};});", siteFields = typeof(StandardSiteFields), trackFields = typeof(StandardTrackFields))] </syntaxhighlight>
返回
使用手册 - Simple:coder(路径编译器)机制详解
。
导航菜单
个人工具
中文(中国大陆)
创建账号
登录
命名空间
页面
讨论
大陆简体
查看
阅读
查看源代码
查看历史
更多
导航
首页
最近更改
随机页面
MediaWiki帮助
工具
链入页面
相关更改
特殊页面
页面信息