Opentcs 开发手册

  • Opentcs 开发手册已关闭评论
  • 430 views
  • A+
所属分类:AGV设计资料
摘要

Opentcs 开发手册

1、opentcs系统需求

1.1、系统需求openTCS源代码是用Java编写的。

要编译它,我们开发人员需要一个Java开发工具包(JDK) 1.8或更高版本。要运行生成的二进制文件,您需要一个Java运行时环境(JRE) 1.8或更高。所有其他所需的库都包含在openTCS分发版中,或者在从源代码构建时自动下载。

1.2、可用工件和API兼容性

【我们可以联系到maven、gradle相关知识】
openTCS项目通过JCenter发布发布工件,因此我们开发人员可以轻松地将它们与诸如Gradle或Maven之类的构建系统集成。例如,在Gradle构建脚本中,使用下面这样的东西来集成openTCS库:
设置我们实际想要使用的openTCS版本的版本号,并从下表中选择合适的${工件}名称:
表1、由openTCS项目发布的工件

Artifact name

API compatibility between minor releases

Content

opentcs-api-base

Yes

Contains the base API for clients and extensions. This is what most developer’s probably want to use.

opentcs-api-injection

Yes

Contains API interfaces and classes used for dependency injection within the kernel and plant overview applications. This is required in integration projects customizing these applications, e.g. adding components like vehicle driver implementations.

opentcs-common

No

Contains a collection of utility classes used by openTCS components.

Artifact name

API compatibility between minor releases

Content

opentcs-commadapter-

loopback

No

Contains a very basic vehicle driver simulating a virtual vehicle.

不错啊~~挺帅气的

opentcs-strategies-

default

No

Contains the default implementations of strategies that are used by the kernel application.

opentcs-kernel

No

Contains the kernel application.

opentcs-

kernelcontrolcenter

No

Contains the kernel control center application.

opentcs-plantoverview

No

Contains the plant overview application.

注意,只有基本的API库提供了一个文档化的API,openTCS开发人员试图在小版本之间保持兼容。(对于这些库,应用了语义版本控制规则。)所有其他工件的内容都可以并且将会改变,而不考虑任何兼容性问题,因此如果您使用这些并切换到不同版本的openTCS,我们开发人员可能需要调整和重新编译我们的代码。

1.3、第三方依赖

1.3.1、内核和客户机应用程序(The kernel and the client applications )依赖于以下外部框架和库:
SLF4J (https://www.slf4j.org/): 一个简单的日志外观,以保持实际日志实现的可替换性。
Google Guice (https://github.com/google/guice): 轻量级依赖注入框架
Cfg4j (http://www.cfg4j.org/): 支持绑定接口的配置库
Google Guava (https://github.com/google/guava): 细节上,具有帮助性的类和方法的集合。
1.3.2、内核应用程序(The kernel application)还依赖于以下库:
•JGraphT (http://jgrapht.org/):用于处理图形并在其上使用算法的库。
•Spark (http://sparkjava.com/):用于创建web应用程序的框架。
•Jackson (https://github.com/FasterXML/jackson):为Java对象提供JSON绑定。
•JDOM (http://www.jdom.org/):用于读写XML数据的库。
1.3.3、工厂概述应用程序(The plant overview application)有以下附加的依赖:
•JHotDraw (http://www.jhotdraw.org/):绘制图形结构的框架(如车辆行驶课程的模型)。
•对接框架(http://www.docking-frames.org/):一个GUI面板停靠对接和卸载的框架
1.3.4、对于自动测试,使用以下依赖项:
•JUnit (http://junit.org/junit4/):一个简单的单元测试框架。
•JUnitParams (https://pragmatists.github.io/JUnitParams/):为JUnit提供了改进的参数化测试支持。
•Mockito (http://mockito.org/):用于创建模拟对象的框架。
•Hamcrest (http://hamcrest.org/):用于断言匹配器的框架,可用于测试。
在构建应用程序时,会自动下载这些依赖项的构件。
Opentcs 开发手册

1.4、模块化和可扩展性

openTCS项目严重依赖于Guice进行依赖注入和组件连接,以及提供插件式扩展机制。在注入API中,相关类可以在包org.opentcs. customize中找到。例如,请参见定制和扩展内核应用程序、定制和扩展工厂概览应用程序以及定制和扩展控制中心应用程序。openTCS项目严重依赖于Guice进行依赖注入和组件连接,以及提供插件式扩展机制。在注入API中,相关类可以在包org.opentcs.customizations中找到。例如,请参见定制和扩展内核应用程序(the kernel application)、定制和扩展工厂概览应用程序( plant overview application )以及定制和扩展控制中心应用程序( control center application)。

1.5、日志记录

官方openTCS发行版中的代码使用SLF4J进行日志记录。因此,通过将SLF4J绑定替换到各自应用程序的类路径中,实际的日志实现是很容易互换的。内核和工厂概述客户端应用程序(The kernel and plant overview client applications),在缺省情况下,附带了SLF4J的(java.util.logging)绑定日志记录。有关如何更改实际日志实现的更多信息,例如使用log4j,我们开发人员可以参阅SLF4J文档。

1.6、使用openTCS源代码(重点学会使用)

openTCS项目本身使用Gradle作为它的构建管理工具。要从源代码构建openTCS,只需从源分布的主目录运行gradlew构建。有关如何使用Gradle的详细信息,请参阅其文档。这些是我们开发人员需要知道的根项目的主要级别任务:
1.6.1、构建:编译所有子项目的源代码。
1.6.2、发布:构建并将所有系统组件打包到构建中。
1.6.3、清理:清理其他任务产生的所有东西,要在IDE中使用源代码,请参阅IDE的文档,以进行渐变集成。对于任何特定的IDE,都没有通用的建议。但是请注意,openTCS源代码包含了使用NetBeans GUI构建器创建的GUI组件。如果我们开发人员想要编辑这些,我们可能想要使用NetBeans IDE。如果我们使用NetBeans,请从NetBeans插件门户安装Gradle支持插件。
然后,您应该能够将源分布的根目录作为一个Gradle项目打开,并从NetBeans中编译和运行组件。

使用内核API所需要的接口和类是opentcs-api-base JAR文件的一部分,所以我们应该将其添加到类路径/声明对它的依赖。
(参见可用的工件和API兼容性。)
您将经常遇到的工厂模型组件和运输任务的基本数据结构如图:
Opentcs 开发手册
图1:基本数据结构
基本数据结构通常与获取和操作这些对象交互的服务接口是:
(我们开发人员需要的接口)
Opentcs 开发手册
图2:接口名称
PS:在写类名的时候注意保持与上图一致

2.1、获取服务对象

要在内核JVM中运行的代码中使用服务,例如车辆驱动程序,只需请求一个实例,例如PlantModelService,通过依赖注入提供。您还可以使用这里的InternalPlantModelService实例,它提供了仅对内核应用程序组件可用的其他方法。
(这么帅的么~~可以啊,不外乎如此)
要从另一个JVM访问服务,例如,在一个应该创建传输任务或接收传输任务或车辆状态更新的客户机中,我们需要通过远程方法调用(RMI)连接到它们。
最简单的方法是创建一个实例:KernelServicePortalBuilder类,并让它为我们构建一个KernelServicePortal实例。
(目前,对用户管理的支持并不多,因此建议忽略需要用户凭据的方法。)
在创建KernelServicePortal实例之后,您可以使用它来获取服务实例并从中获取内核事件。
我们参阅基本API的JavaDoc文档中KernelServicePortalBuilder的类文档。
下面就是编写一个类的实例(KernelServicePortalBuilder)

  1. KernelServicePortal servicePortal = new KernelServicePortalBuilder().build();  

// 与某个内核连接并登录,端口号十分重要

  1. servicePortal.login("someHost", 1099);  

// 获得工厂模型服务的参考信息

  1. PlantModelService plantModelService = servicePortal.getPlantModelService();  

 

// 并找出当前加载的模型的名称

  1. String modelName = plantModelService.getLoadedModelName();  

// 轮回事件,如果当前没有,则等待一秒钟

// 这应该定期进行,并且可能在单独的线程中进行

  1. List<Object> events = servicePortal.fetchEvents(1000);  

2.2、处理运输任务

我们开发人员编写一个类,由TransportOrder类的实例表示的传输顺序描述由车辆执行的进程。通常,这个过程是货物从一个地点到另一个地点的实际运输。然而, TransportOrder也可以仅仅描述车辆移动到目的地位置和可选择的车辆操作。

下面所有的例子都是openTCS中假象有“运输任务”的例子,实际上什么也没有运输:

2.2.1、将货物从某处运到其他地方的经典任务命令:

移动到位置“A”,并在那里执行“装载货物”操作。
移动到位置“B”,在那里执行“卸载货物”操作。
2.2.2、操纵运输或固定物品:

a、移动到位置“A”,并在那里执行“钻孔”操作。

b、移动到位置“B”,在那里执行“锤打”操作。

2.2.3、将车辆移动到停车位置的命令:

a、移动到位置“Park 01”(不执行任何具体操作)。

2.2.3、给汽车电池充电的命令:

a、移动到位置“充电站”,并在那里执行“充电”操作。

 

2.2.4、一个运输任务指令的生命周期

a、在创建传输任务时,它的初始状态是RAW。

b、用户/客户端为应该影响传输过程的传输顺序设置参数。这些参数可能是运输任务的最后期限,即应该处理运输顺序的车辆或一组通用的,通常是特定于项目的属性。

c、传输顺序被激活,即参数设置完成,它的状态被设置为ACTIVE(活动状态)。

d、内核的路由器检查传输顺序的目的地之间的路由是否可能,如果是,则将其状态更改为DISPATCHABLE(可分派)。如果不可能进行路由,则将传输顺序标记为 UNROUTABLE (不可路由),且不进行任何进一步处理。

e、内核的dispatcher(调度程序)检查是否满足了执行传输任务的所有需求,并且可以使用车辆进行处理。只要还没有满足或没有车辆可以执行的要求,运输任务就会等待。

f、内核的dispatcher(调度程序)将传输顺序分配给一个用于处理的工具。它的状态改为BEING_PROCESSED。

•如果正在处理的传输任务被撤销(由客户/用户),它的状态将在车辆执行已发送到它的任何任务时发生更改。然后传输顺序的状态更改为FAILED,它不再被处理。

•如果运输任务的处理因任何原因而失败,则标记为失败,不再处理。

•如果车辆成功地处理了整个运输任务,则标记为已完成。

g、最终,在较长时间内或在最终状态下的大量传输任务在内核的任务池中积累时——内核删除了传输顺序,下面的状态机可视化了这个生命周期:
Opentcs 开发手册
图:传输命令状态的可视化流程

2.3、运输任务的结构和处理

Opentcs 开发手册

传输任务是通过调用TransportOrderService.createTransportOrder()创建的。

作为它的参数,它期望一个传输层的类(TransportOrderCreationTO)来包含访问目的地的序列,以及AGV应该在那里执行的操作。内核将每个目的地封装在一个新创建的驱动程序(DriveOrder)实例中。这些驱动程序(DriveOrders)本身是由内核在一个单独的、新创建的传输任务实例中包装的。

一旦一个运输任务被调度程序( Dispatcher,)分配给车辆,就会计算出每一个驱动程序的路线,然后这些路由被存储在相应的DriveOrders中。
Opentcs 开发手册

PS、一旦AGV小车(“司机”)能够处理一个驱动程序,它的路线的单个步骤就被映射到移动命令。这些移动命令包含车辆驱动程序到达最终目的地所需的所有信息,并在那里执行所需的操作。
Opentcs 开发手册
图、移动指令相关类

部分路线的移动命令被一点一点地发送给AGV小车的“司机”。内核只有在驱动程序正常运行时,才会预先发送许多移动命令。这样做是为了保持对所有AGV小车使用的路径/资源的精细控制,一个车辆驱动程序可以通过调整其命令队列的容量来设置它预先得到的移动命令的最大数量。一旦驱动程序完成,下一个驱动程序(DriveOrder)的路由就被映射到移动命令。一旦传输顺序的最后一个驱动程序完成,整个传输顺序也就完成了。

2.3.1、 如何创建一个新的运输命令
    // 目前我们在编写的 transport order service 类

  1. TransportOrderService transportOrderService = getATransportOrderServiceReference(  

    // 目前我们在编写的dispatcher service 类

 

  1. DispatcherService dispatcherService = getADispatcherServiceReference();  

// 车辆应该前往的运输任务目的地列表:

  1. List<DestinationCreationTO> destinations = new LinkedList<>();   

   

 // 创建一个新的目标描述并将其添加到列表中。

 

// 每个目的地都由目的地的名称来描述

 

// 在工厂模型中的位置和AGV小车应该在那里执行的操作:

 

  1. destinations.add(new DestinationCreationTO("Some location name",  
  2.   
  3.                                            "Some operation"));  

 

// 根据需要向列表中添加尽可能多的目的地。然后,使用新传输任务的名称和目的地列表创建传输任务描述。

 

//注意,给定的名称必须是唯一的。

  1. TransportOrderCreationTO orderTO  
  2.   
  3.     = new TransportOrderCreationTO("MyTransportOrder-" + UUID.randomUUID(),  
  4.   
  5.                                    destinations);     //可选地,分配一个特定的车辆运输任务清单:  
  6.   
  7.   
  8.   
  9. rTO = orderTO.withIntendedVehicleName("Some vehicle name");    

// 可选地,设置运输任务的最后期限:
    

  1. orderTO = orderTO.withDeadline(Instant.now().plus(1, ChronoUnit.HOURS));  

// 为给定的描述创建一个新的传输任务顺序~~

 

  1. TransportOrder newOrder = transportOrderService.createTransportOrder(orderTO);  

// 触发创建的传输任务顺序的分派过程,这就是我们程序员所知道的调用方法~~

  1. dispatcherService.dispatch();  

2.3.2、 如何创建将AGV小车移动到到点而不是位置的传输命令顺序
    // 目前我们在编写的 transport order service 类

  1. TransportOrderService transportOrderService = getATransportOrderServiceReference();  

// 目前我们在编写的dispatcher service 类
 

  1. DispatcherService dispatcherService = getADispatcherServiceReference();  

    // 创建一个列表,其中包含到某一点的单个目标。

// 使用Destination.OP_MOVE这个参数 作为将要执行的操作~~~,我们程序员对参数十分的敏感~

  1. List<DestinationCreationTO> destinations = new LinkedList<>();  
  2.   
  3. destinations.add(new DestinationCreationTO("Some point name",  
  4.   
  5.                                            Destination.OP_MOVE));  

// 创建一个带有目的地和唯一名称的运输任务描述,并将其分配给特定的AGV小车

  1. TransportOrderCreationTO orderTO  
  2.   
  3.     = new TransportOrderCreationTO("MyTransportOrder-" + UUID.randomUUID(),  
  4.   
  5.                                    destinations)  
  6.   
  7.         .withIntendedVehicleName("Some vehicle name");  

// 使用描述创建一个传输任务

  1. TransportOrder dummyOrder = transportOrderService.createTransportOrder(orderTO);  

// 触发创建的传输任务顺序的分派过程,这就是我们程序员所知道的调用方法~~

  1. dispatcherService.dispatch();  

2.4、使用命令序列

任务序列可用于强制单个AGV小车在给定的任务中处理多个传输任务,在OrderSequence的API文档中描述了使用顺序序列的一些规则,但以下是我们开发人员通常要做的事情:

(我们开发人员需要另外查阅相关API文档来保证代码没有漏洞~~)

 

  // 目前我们在编写的transport order service 类

  1. TransportOrderService transportOrderService = getATransportOrderServiceReference(  

    // 目前我们在编写的 dispatcher service  类

  1. DispatcherService dispatcherService = getADispatcherServiceReference();  

// 创建一个唯一名称的任务序列描述:

  1. OrderSequenceCreationTO sequenceTO  
  2.   
  3.     = new OrderSequenceCreationTO("MyOrderSequence-" + UUID.randomUUID());  

   

 

 // 可选地,设置任务序列的故障-报警标志
    

  1. sequenceTO = sequenceTO.withFailureFatal(true);  

// 创建顺序顺序

  1. OrderSequence orderSequence = transportOrderService.createOrderSequence( sequenceTO);  

// 像往常一样设置传输顺序,但添加包装序列的名称

  1. List<DestinationCreationTO> destinations = new ArrayList<>();  
  2.   
  3.    destinations.add(new DestinationCreationTO("Some location name",  
  4.   
  5.                                               "Some operation"));  
  6.   
  7.    TransportOrderCreationTO orderTO  
  8.   
  9.        = new TransportOrderCreationTO("MyOrder-" + UUID.randomUUID(),  
  10.   
  11.                                       destinations)  
  12.   
  13.            .withWrappingSequence(orderSequence.getName());  

    // 创建运输任务

   

  1. TransportOrder order = transportOrderService.createTransportOrder(orderTO);  

    // 根据需要创建和添加更多的任务命令~~~

    // 最后,设置任务序列的完成(complete)标志,以指示不会向其添加更多的传输任务。

   

  1. transportOrderService.markOrderSequenceComplete(orderSequence.getReference());  

    // 触发创建的传输任务顺序的分派过程,这就是我们程序员所知道的调用方法~~

  1. dispatcherService.dispatch();  

PS:只要序列没有被标记为完成或者完全完成,选择的第一个顺序的AGV小车将被绑定到这个序列。它不会处理任何不属于同一序列的命令,直到整个序列完成。一旦确定了序列的完成标志,并处理了属于它的所有传输任务,它的最终标记将由内核来设置。

(意思就是这一辆AGV小车已经被绑定了,直到完成整个任务序列,这在多辆AGV小车的情况下十分重要~~)

2.5、如何撤回目前正在处理的运输任务

    // 目前我们正在编写 dispatcher service 类~

   

  1. DispatcherService dispatcherService = getDispatcherServiceFromSomewhere();  

    // 获得运输命令被撤回

  1. TransportOrder curOrder = getTransportOrderToWithdraw();   

   

 

 // 撤销任务

 

// 第二个参数表示车辆是否应该完成动作,我们开发人员应该注意每一个参数的含义

// 它已经被指定为(false)或立即中止(true)。

// 第三个参数表示车辆的处理状态是否应该更改为不可用,因此不能为其分配另一个传输任务~~

(我们开发人员应该注意每一个参数的正确与否,否则会造成漏洞)

 

// 就在撤销之后~~

   

  1. dispatcherService.withdrawByTransportOrder(curOrder.getReference(), truefalse);  

2.6、 如何通过车辆处理参考命令来撤回运输任务

    // 目前我们正在编写 object service类 

   

  1. TCSObjectService objectService = getTCSObjectServiceFromSomewhere();  

// 得到运输命令应当撤回的AGV小车

  1. Vehicle curVehicle = objectService.fetchObject(Vehicle.class,  
  2.   
  3.                                                    getSampleVehicle());  

    // 目前我们正在编写dispatcher service类

    

  1. DispatcherService dispatcherService = getDispatcherServiceFromSomewhere();  

    // 撤销任务

// 第二个参数表示车辆是否应该完成动作,我们开发人员应该注意每一个参数的含义

// 它已经被指定为(false)或立即中止(true)。

// 第三个参数表示车辆的处理状态是否应该更改为不可用,因此不能为其分配另一个传输任务~~

(我们开发人员应该注意每一个参数的正确与否,否则会造成漏洞)

 

// 就在撤销之后~~

    

  1. dispatcherService.withdrawByVehicle(curVehicle.getReference(), truefalse);  

3、内核的web API

除了特定于java的内核接口之外,openTCS还提供了一个web API。这个接口提供了以下功能:

3.1、可以创建运输任务

3.2、运输任务可以撤回

3.3、可以检索运输任务和车AGV小车的状态更新(通过长时间轮询)。

HTTP请求和响应的主体(如果适用)是JSON结构,描述结构的JSON模式是openTCS二进制发行版开发人员文档的一部分。使用的编码可以是UTF-8、UTF-16或UTF-32。使用时间戳的地方,使用iso8601进行编码,使用的时区是UTC。

 

用于HTTP请求的TCP端口与配置有关,默认情况下,它是55200。后半部分将描述各个函数的路径,默认情况下,不需要任何身份验证就可以接受请求。还可以在内核配置中设置访问键,然后,客户端会在一个名为X-Api-Access-Key的HTTP头文件中发送配置好的值。

3.1、创建一个运输任务

•路径:  ( /v1/transportOrders/

/ v1 / transportOrders / <名称>

•HTTP方法:POST

•查询参数:没有

•示例URL:http://opentcs.example.com:55200/v1/transportOrders/TOrder-1234

请求体将包含要创建的传输命令的描述,它应该包含如下内容:

 

示例1:创建传输顺序的JSON结构(关键)

PS:响应以200 (OK)的HTTP状态码成功,响应的主体是空的。

 

3.2、按照名称提取运输任务

•路径:/v1/transportOrders//withdrawal

•HTTP方法: POST

•查询参数:

•immediate (布尔型,可选):是否应该尽快终止传输顺序(默认值:false)

•disableVehicle(布尔型,可选):处理车辆是否不应被分配任何进一步的运输任务。(默认值:false)

•示例url:

http://opentcs.example.com:55200/v1/transportOrders/TOrder-0075/withdrawal
http://opentcs.example.com:55200/v1/transportOrders/TOrder0075/withdrawal?immediate=true
http://opentcs.example.com:55200/v1/transportOrders/TOrder-
0075/withdrawal?disableVehicle=true

 

3.3、通过处理车辆收回运输任务

•路径: /v1/vehicles//withdrawal

•HTTP方法:POST

•查询参数:

•immediate(布尔型,可选):是否应该尽快终止传输顺序。(默认值:false)

•disableVehicle(布尔,可选):处理车辆是否不应被分配任何进一步的运输任务。(默认值:false)

•示例url:

http://opentcs.example.com:55200/v1/vehicles/Vehicle-0001/withdrawal
http://opentcs.example.com:55200/v1/vehicles/Vehicle-0001/withdrawal?immediate=true
http://opentcs.example.com:55200/v1/vehicles/Vehicle-0001/withdrawal?disableVehicle=true
请求的主体被忽略,响应的主体是空的。

 

3.4、检索状态更新

•路径:  /v1/events

•HTTP方法:GET

•查询参数:

•minSequenceNo(整数,可选):要检索的事件的最小序号。(默认值:没有最低)

•maxSequenceNo(整数,可选):要检索的事件的最大序列号。(默认值:没有最大)

•timeout (整数,可选):如果当前没有要返回的事件,则等待事件到达的时间(以毫秒为单位),可能不大于10000。(默认值:1000)

•示例URLs:

http://opentcs.example.com:55200/v1/events
http://opentcs.example.com:55200/v1/events?timeout=5000
http://opentcs.example.com:55200/v1/events?minSequenceNo=100
http://opentcs.example.com:55200/v1/events?minSequenceNo=100&maxSequenceNo=200
请求的主体被忽略。响应的主体看起来如下:

示例1:获取事件/更新的JSON结构。

 

 

4、基于TCP/IP的其他系统接口

这个接口不赞成使用,为了支持内核的webAPI,它将被删除。除了java特有的内核接口之外,openTCS还提供了以下与其他系统通信的接口:一种是通过TCP/IP连接的双向接口,用于创建传输任务,另一种是通过TCP/IP连接接收状态消息的单向接口,例如关于正在处理的传输任务,下面将主要介绍一下TCP/IP接口。

4.1、创建任务通过TCP / IP

为了创建传输任务,openTCS内核接受到TCP端口的连接(默认端口55555)。openTCS与主机之间的通信工作如下:

4.1.1、主机建立一个新的TCP/IP连接到openTCS。

4.1.2、主机发送一个单一的XML 电报(在XML电报中详细描述,用于创建任务和引用任务批次的XML 电报),它可以描述要创建的传输任务,或者识别内核中可用的批处理文件,并包含传输任务描述。

4.1.3、主机关闭TCP/IP连接的输出流,或发送两个连续的换行符。让内核知道没有进一步的数据将会跟随。

4.1.4、openTCS解释主机发送的电报,创建相应的传输命令并激活它们。

4.1.5、openTCS发送一份XML电报(详细描述了创建任务的证据),以确认电报的处理。

4.1.6、openTCS关闭TCP/IP连接。应尊重以下几点:

•不打算通过相同的TCP连接传输多个传输任务,在处理一个集合并发送响应之后,openTCS关闭连接。要传输进一步的设置,需要由对等系统建立新的TCP/IP连接。

•openTCS只等待有限的输入数据(默认为10秒)。如果在较长一段时间内没有来自对等系统的传入数据,则在没有创建任何传输任务的情况下,openTCS将关闭连接。

•默认情况下,单个XML电报的最大长度限制为100 kb,如果更多的数据被传输,连接将被关闭,没有任何传输任务被创建。

 

 

4.2、用于创建任务的XML电报。

通过上面描述的接口发送给openTCS的每个XML电报都可以描述要创建的多个传输命令。

每个任务元素必须包含以下数据:

A、识别命令元素的字符串,此字符串需要对收据进行明确的匹配(见创建任务的证据)和任务。

B、定义实际任务的目的地和目的地操作序列,

 

此外,每个命令元素可能包含以下数据:

A、完成任务的最后期限/时间。

B、系统中要分配任务的AGV小车的名称,如果省略此信息,系统中的任何AGV小车都可以处理任务。

C、在新任务交付AGV小车之前必须完成的一组现有运输任务的名称,下面的示例展示了如何创建两个传输任务的XML 电报。

 

示例1:创建两个传输任务的XML 电报

  1. <?xml version="1.0" encoding="UTF-8" standalone="yes"?>  
  2.   
  3. <tcsOrderSet>  
  4.   
  5.     <order xsi:type="transport" deadline="2018-04-16T10:55:31.312+02:00"  
  6.   
  7. intendedVehicle="Vehicle-01" id="TransportOrder-01" xmlns:xsi=  
  8.   
  9. "http://www.w3.org/2001/XMLSchema-instance">  
  10.   
  11.         <destination locationName="Storage 01" operation="Load cargo"/>  
  12.   
  13.         <destination locationName="Storage 02" operation="Unload cargo"/>  
  14.   
  15.         <property key="waitBefore" value="Unload"/>  
  16.   
  17.     </order>  
  18.   
  19.     <order xsi:type="transport" id="TransportOrder-02" xmlns:xsi=  
  20.   
  21. "http://www.w3.org/2001/XMLSchema-instance">  
  22.   
  23.         <destination locationName="Working station 01" operation="Drill">  
  24.   
  25.             <property key="drillSize" value="3"/>  
  26.   
  27.         </destination>  
  28.   
  29.         <destination locationName="Working station 02" operation="Drill">  
  30.   
  31.             <property key="drillSize" value="8"/>  
  32.   
  33.         </destination>  
  34.   
  35.         <destination locationName="Working station 03" operation="Cut"/>  
  36.   
  37.     </order>  
  38.   
  39. </tcsOrderSet>  

 

4.3、XML电报参考任务批次

另外,XML 电报也可以参考openTCS系统中保存在文件中的任务批次。要创建的传输命令的(参数)将从引用的批处理文件中读取。批处理文件可以包含/创建任意数量的传输任务,并且需要放在内核应用程序的子目录脚本中。

在openTCS分发版中,该目录已经包含了一些批处理文件的模板(模板),(template.tcs and test.tcs),下面的示例演示如何引用批处理文件的XML 电报。

 

示例2:引用批处理文件的XML电报

 

  1. <?xml version="1.0" encoding="UTF-8" standalone="yes"?>  
  2.   
  3. <tcsOrderSet>  
  4.   
  5.     <order xsi:type="transportScript" fileName="test.tcs" id="test.tcs" xmlns:xsi=  
  6.   
  7. "http://www.w3.org/2001/XMLSchema-instance"/>  
  8.   
  9. </tcsOrderSet>  

 

4.4、创建任务的证据

在响应XML电报创建传输任务时,XML 电报将被发送回对等点,报告操作的结果。在响应电报中,原始电报的每个任务元素都将由具有相同ID的响应元素引用。

•标志着创建相应任务的成功的标志。

•在内部分配给创建任务的openTCS的名称(此名称与在状态通道上解释消息有关——通过TCP/IP查看状态消息),下面的示例显示了如何响应示例1中的电报。

 

示例3:具有创建任务的证据的XML 电报

  1. <?xml version="1.0" encoding="UTF-8" standalone="yes"?>  
  2.   
  3. <tcsResponseSet>  
  4.   
  5.     <response xsi:type="transportResponse" executionSuccessful="true" orderName=  
  6.   
  7. "TOrder-0001" id="TransportOrder-01" xmlns:xsi="http://www.w3.org/2001/XMLSchema-  
  8.   
  9. instance"/>  
  10.   
  11.     <response xsi:type="transportResponse" executionSuccessful="true" orderName=  
  12.   
  13. "TOrder-0002" id="TransportOrder-02" xmlns:xsi="http://www.w3.org/2001/XMLSchema-  
  14.   
  15. instance"/> </tcsResponseSet>  

 

4.5、任务批次证据

对于被引用的任务批次,证据也会被发送回对等点。响应中包含了每个批处理文件所引用的元素,如果批处理文件被成功地读取和处理,它所包含的每个任务定义的响应都将包括在内。下面的示例显示了示例2中的批处理文件引用的可能响应,在这种情况下,批处理文件包含两个已成功处理的传输任务定义。

示例4:在批处理文件中接收任务证据的XML电报

  1. <?xml version="1.0" encoding="UTF-8" standalone="yes"?>  
  2.   
  3. <tcsResponseSet>  
  4.   
  5.     <response xsi:type="scriptResponse" parsingSuccessful="true" id="test.tcs"  
  6.   
  7. xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">  
  8.   
  9.         <transport executionSuccessful="true" orderName="TOrder-0003" id="test.tcs"/>         <transport executionSuccessful="true" orderName="TOrder-0004" id="test.tcs"/>  
  10.   
  11.     </response>  
  12.   
  13. </tcsResponseSet>  

【生命在一点点的流逝~~但是微微一笑,不负如来不负卿~】
 

4.6、通过TCP / IP获取状态信息

要接收系统中传输任务的状态消息,可以建立与另一个TCP端口的连接(默认端口44444)。每当传输任务的状态发生变化时,就会发送一个XML电报给每个连接的客户端,描述任务的新状态。每一个电报后面都有一个字符串,它不会出现在电报本身(默认情况下,一个管道符号:“|”),标记各自电报的结尾。状态消息将被发送,直到对等端关闭TCP连接。

我们开发人员应尊重以下几点:

•从对等端的观点来看,与这个状态通道的连接完全是被动的,即openTCS不期望来自对等方的任何消息,也不会处理通过此连接接收到的任何数据。

•对等端需要过滤收到的电报以获取相关数据,openTCS内核不为客户端提供任何状态消息的过滤。

•由于openTCS内的并发进程,在创建该任务的对等点收到相应的收据之前,可能会通过状态通道报告一个传输任务的创建和激活以及它对AGV小车的分配。下面的示例显示了一个状态消息,在示例1中定义的两个传输任务中的第一个已经创建并激活后,它将通过状态通道发送。

示例5:生成的任务的状态消息

  1. <?xml version="1.0" encoding="UTF-8" standalone="yes"?>  
  2.   
  3. <tcsStatusMessageSet timeStamp="2018-04-16T10:55:31.730+02:00">  
  4.   
  5.     <statusMessage xsi:type="orderStatusMessage" orderName="TOrder-0001" orderState=  
  6.   
  7. "ACTIVE" processingVehicleName="Vehicle-0001" xmlns:xsi=  
  8.   
  9. "http://www.w3.org/2001/XMLSchema-instance">  
  10.   
  11.         <destination locationName="Storage 01" operation="Load cargo" state="PRISTINE  
  12.   
  13. "/>  
  14.   
  15.         <destination locationName="Storage 02" operation="Unload cargo" state=  
  16.   
  17. "PRISTINE"/>  
  18.   
  19.         <property key="waitBefore" value="Unload"/>  
  20.   
  21.     </statusMessage>  
  22.   
  23. </tcsStatusMessageSet>  

4.7、用于电报和脚本的XML模式定义。

XML模式描述了XML任务电报和任务批处理文件的期望结构,以及openTCS发送的接收电报的结构,这是openTCS分发的一部分,可以在包含开发人员文档的目录中找到。
---------------------
作者:Genius夜光
来源:CSDN
原文:https://blog.csdn.net/weixin_41987706/article/details/84648751

weinxin
微信公众号
agvba是一个分享AGV知识和agv案例视频的网站。