opentcs理解

openTCS系统通过Kernel进行调度核心管理,包含服务封装、车辆控制及外围设备交互。默认策略实现在于分配运输订单、路径规划与资源调度。系统详细介绍了Dispatcher、Router、Scheduler等组件功能,以及VehicleCommAdapter在车辆控制中的作用。此外,还涵盖了资源分配逻辑、状态变化处理与重新路由机制。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

openTCS-Kernel是调度核心,services是对服务层的封装,vehicles主要是在确定调度策略,确定行走路径后控制小车的,以及与外围设备的命令交互
openTCS-Strategies-Default是调度核心策略的默认实现,其中包含Dispatcher是分配运输订单与小车的对应关系,router是确定最短路径的,scheduler是主要是分配资源给小车
openTCS-API-Base主要是对涉及到的组件的一些抽象,drivers包下包含vechicle,peripherals,对应小车及外围设备
驱动器相关的包含小车和外围设备的
小车驱动适配器是VehicleCommAdapter

«interface»
VehicleCommAdapter
+void enable()
+void disable()
+boolean isEnabled()
+VehicleProcessModel getProcessModel()
+VehicleProcessModelTO createTransferableProcessModel()
+int getCommandQueueCapacity()
+Queue getCommandQueue()
+int getSentQueueCapacity()
+Queue getSentQueue()
+String getRechargeOperation()
+boolean enqueueCommand(@Nonnull MovementCommand newCommand)
+void clearCommandQueue()
+void processMessage(@Nullable Object message)
+void execute(@Nonnull AdapterCommand command)
«interface»
AdapterCommand
+void execute(VehicleCommAdapter adapter)
«interface»
MovementCommand
«abstract»
BasicVehicleCommAdapter
-Queue<MovementCommand> commandQueue
-Queue<MovementCommand> sendQueue
VehicleProcessModel
VehicleCommAdapterEvent
«interface»
VehicleController
«inteface»
VehicleCommAdapterFactory
+VehicleCommAdapterDescription getDescription()
+boolean providesAdapterFor(Vehicle vehicle)
+VehicleCommAdapter getAdapterFor(Vehicle vehicle)
LoopbackCommuticationAdapter

VehicleCommAdapter:其中包含了要发送的命令队列和已发送的命令队列

外围设备控制适配器为PeripheralCommAdapter

«interface»
PeripheralCommAdapter
«interface»
PeripheralAdapterCommand
«interface»
PeripheralCommAdapterFactory
«abstract»
BasicPeripheralCommAdapter

VehicleController 是小车的上层控制器,通过VehicleCommAdapter 来驱动小车
VehicleControllerPool用于维护车辆(Vehicle)和车辆控制器(VehicleController)之间的关联
LocalVehicleControllerPool用于管理控制器与车辆以及通信适配器的关系,用于管理Vehicle和VehicleCommAdapter

«interface»
VehicleControllerPool
«interface»
VehicleController
«interace»
LocalVehicleControllerPool
«interface»
VehicleCommAdapter
DefaultVehicleController
-Queue<MovementCommand> futureCommands
-Queue<MovementCommand> commandsSent
-PeripheralInteractor peripheralInteractor
-MovementCommand lastCommandExecuted
DefaultVehicleControllerPool
«interace»
VehicleControllerFactory
+DefaultVehicleController createVehicleController(Vehicle vehicle, VehicleCommAdapter commAdapter)
VehicleCommAdapterRegistry
«interface»
VehicleControllerComponentsFactory
+PeripheralInteractor createPeripheralInteractor(TCSObjectReference<Vehicle> vehicleRef)
PeripheralInteractor
PeripheralInteraction
PeripheralDispatcherService
PeripheralJob

VehicleControllerComponentsFactory:创建PeripheralInteractor的工厂
VehicleControllerFactory:创建Vehicle的控制器工厂,同时设置对应的VehicleCommAdapter
DefaultVehicleController

  • futureCommands:表示待发送到适配器的命令
  • commandsSent:表示已经发送到适配器的命令
  • lastCommandExecuted:表示最近一次适配器执行完的命令

在什么时候会触发Dispatcher的dispath方法呢?

  • 在创建TransportOrder时
  • 在调用ImplicitDispatchTrigger的onEvent方法中
    • 即小车的IntegrationLevel为TO_BE_UTILIZED或者TO_BE_RESPECTED
    • 小车的处理状态为IDLE,状态为IDLE或者CHARGING,小车的能量有变化
    • 小车的处理状态有变化,新状态为IDLE或者AWAITING_ORDER
    • 小车的订单次序从有变为无
  • 周期调度任务PeriodicVehicleRedispatchingTask

在什么时候会触发外围设备任务PeripheralJobDispatcher的dispath方法呢?

  • 在调用ImplicitDispatchTrigger的onEvent方法中
    • TransportOrder的订单状态为变化,新状态为FAILED
  • 周期调度任务PeriodicPeripheralRedispatchingTask
  • 创建外围设备交互时PeripheralInteractor在执行前置或者后置交互,即在调用startPreMovementInteractions和startPostMovementInteractions方法时

资源调度

接口

«interface»
Scheduler
+void claim(Client client, List resourceSequence)
+void updateProgressIndex(Client client, int index)
+void unclaim(Client client)
+void allocate(Client client, Set resources)
+boolean mayAllocateNow(Client client, Set resources)
+void allocateNow(Client client, Set resources)
+void free(Client client, Set resources)
+void freeAll(Client client)
+void clearPendingAllocations(Client client)
+void reschedule()
+Map getAllocations()
+void preparationSuccessful(Module module, Client client, Set resources)
«interface»
Client
+String getId()
+boolean allocationSuccessful(Set resources)
+void allocationFailed(Set resources)
«interface»
Module
+void claim(Client client, List claim)
+void unclaim(Client client)
+void setAllocationState(Client client, Set alloc, List remainingClaim)
+boolean mayAllocate(Client client, Set resources)
+void prepareAllocation(Client client, Set resources)
+boolean hasPreparedAllocation(Client client,Set resources)
+void allocationReleased(Client client, Set resources)
«interfae»
VehicleController
DefaultVehicleController

DefaultVehicleController和Vehicle是一对一关系

实现

1
n
«interface»
Scheduler
«interface»
Module
DefaultScheduler
-ReservationPool reservationPool
ReservationPool
-Map<Client,Queue>Set<TCSResource><> claimsByClient
-Map<TCSResource, ReservationEntry> reservations
AllocationAdvisor
PausedVehicleModule
SameDirectionBlockModule
SingleVehicleBlockModule
AllocatorTask
«abstract»
AllocatorCommand
Allocate
AllocationsReleased
RetryAllocates
CheckAllocationsPrepared

使用了组合模式
AllocationAdvisor:作为其它Module的组合,是模块的统一入口
PausedVehicleModule:不会对暂停的小车分配资源
ReservationPool:用于管理小车索要的资源以及分配的资源
AllocatorTask:处理资源分配的任务,具体依赖分配命令的子类
AllocatorCommand:分配的命令,包含资源分配,资源释放,资源的重新分配
ReservationPool:claimsByClient用来管理索要,即DefaultVehicleController小车索要了哪些资源,reservations表示分配成功后资源与小车的对应关系,即资源分配给了哪个小车

分配流程

DefaultScheduler ScheduledExecutorService AllocatorTask AllocationAdvisor DefaultVehicleController allocate submit 异步 run processAllocate tryAllocate mayAllocate prepareAllocation checkAllocationsPrepared hasPreparedAllocation allocationSuccessful DefaultScheduler ScheduledExecutorService AllocatorTask AllocationAdvisor DefaultVehicleController

分配时因为涉及到全局tcs资源及对象,使用了同步锁globalSyncObject
与小车命令交互控制了的,也使用了锁commAdapter

  • DefaultVehicleController在更新DriveOrder时(setDriveOrder),根据DriveOrder判断需要的资源,然后调用Scheduler的claim索要资源
  • 根据DriveOrder来创建命令集createFutureCommands
  • 判断是否可以发送命令canSendNextCommand
    • 看命令集是否不为空
    • commAdapter通信适配器的队列容量是否可以接收命令
    • 命令集中的第一条命令是否可以执行(即路径是否被锁)
    • 是否在等待资源分配(waitingForAllocation)
    • 是否有等待执行的命令(pendingCommand不为空)
    • 交互命令是否有未完成的(isWaitingForMovementInteractionsToFinish)
  • 在可以发送命令情况时,调用allocateForNextCommand,从命令集中取出第一条命令,判断命令所需要的资源,调用Scheduler的allocate方法异步分配资源,设置等待分配完成标识waitingForAllocation为true,同时设置等待执行命令pendingCommand
  • 在异步分配成功后,会调用DefaultVehicleController#allocationSuccessful,执行pendingCommand的前置交互(prepareInteractions),然后发送命令sendCommand,将command添加到commAdapter的队列中,同时将命令记录到已发送队列commandsSent中,同时判断是否可以发下一个命令
  • command添加到commAdapter时,会调用BasicVehicleCommAdapter#enqueueCommand,入队列成功会触发model的COMMAND_ENQUEUED事件,会调用BasicVehicleCommAdapter#propertyChange监听器方法,执行命令分发任务CommandDispatcherTask,调用BasicVehicleCommAdapter#sendCommand发送命令,同时将命令记录到已发送队列中sentQueue
  • 命令执行完后,如果有触发COMMAND_EXECUTED,DefaultVehicleController会处理命令执行完事件(commandExecuted),将命令从已发送命令队列中删除,调用Scheduler#free删除为该命令分配的资源,同时执行该命令的后置操作(startPostMovementInteractions)
  • 后置命令处理完后,checkForPendingCommands,判断是否还有待处理的命令,如果有,则继续下发命令,如果没有则将小车的状态设置为AWAITING_ORDER,此时会触发ImplicitDispatchTrigger

canSendNextCommand在什么时候会调用?

  • 在调用setDriveOrderupdateDriveOrder
  • 资源分配成功时allocationSuccessful
  • 小车控制器将移动命令放到通信适配器队列中时sendCommand
  • 命令执行完后检查是否还有命令要处理checkForPendingCommands
    第一种情况下小车的处理状态为AWAITING_ORDER,后面三个是在 处理调度中,即小车的处理状态为处理中PROCESSING_ORDER

处理资源分配processAllocate

  • tryAllocate尝试分配
    • isNextInClaim首先看资源是否在索要池队列头
    • resourcesAvailableForUser看资源是否可以被占用
    • mayAllocate看分配顾问是否可能分配资源
    • prepareAllocation为资源分配作准备工作
    • reservationPool.getReservationEntry(curRes).allocate(client)分配资源
    • reservationPool.unclaim(client, resources)从索要池中删除
  • checkAllocationsPrepared检查分配准备
    • hasPreparedAllocation检查分配准备工作是否已经完成
    • 分配成功后调用allocationSuccessful,生成移动命令,发送命令以及与外围设备作交互
    • 如果allocationSuccessful失败,则调用undoAllocate释放分配的资源,调用scheduleRetryWaitingAllocations触发等待资源的处理

资源分配失败后的再次分配

在DefaultScheduler#free,DefaultScheduler#freeAll,DefaultScheduler#reschedule 时会再次分配

事件

1
*
«interface»
EventHandler
+void onEvent(Object event)
«interface»
EventSource
void subscribe(EventHandler listener)
void unsubscribe(EventHandler listener)
EventBus
SimpleEventBus
Set<EventHandler> listeners
ImplicitDispatchTrigger
DefaultVehicleController
DefaultPeripheralController
PeripheralInteractor

EventBus:观察者模式的抽象,即作为Subject,也作为Observer,即继承了接口EventSource,EventHandler
SimpleEventBus :EventBus的实现类
TCSObjectManager:在修改属性时,会触发TCSObjectEvent事件

边权值计算

1
n
«interface»
EdgeEvaluator
+void onGraphComputationStart(Vehicle vehicle)
+void onGraphComputationEnd(Vehicle vehicle)
+double computeWeight(Edge edge, Vehicle vehicle)
EdgeEvaluatorDistance
«interface»
ModelGraphMapper
+Graph~String, Edge~ translateModel(Collection<Point> points,Collection<Path> paths,Vehicle vehicle)
DefaultModelGraphMapper
EdgeEvaluatorExplicitProperties
EdgeEvaluatorHops
EdgeEvaluatorTravelTime
EdgeEvaluatorComposite

边计算也使用了组合模式,EdgeEvaluatorComposite集成了其它的EdgeEvaluator

重新路由

路由策略

«interface»
DriveOrderMerger
DriveOrder mergeDriveOrders(DriveOrder orderA, DriveOrder orderB, Vehicle vehicle)
«interface»
ReroutingStrategy
Optional~List~DriveOrder~~ reroute(Vehicle vehicle)
«abstract»
AbstractReroutingStrategy
Optional determineRerouteSource(Vehicle vehicle)
ForcedReroutingStrategy
RegularReroutingStrategy
«abstract»
AbstractDriveOrderMerger
List mergeSteps(List stepsA, List stepsB, Vehicle vehicle)
ForcedDriveOrderMerger
RegularDriveOrderMerger

重新路由处理

User AbstractReroutingStrategy AbstractReroutingStrategy子类 Router DriveOrderMerger AbstractDriveOrderMerger AbstractDriveOrderMerger子类 reroute determineRerouteSource 返回Optional<Point> getRoute 返回Optional<List<DriveOrder>> mergeDriveOrders mergeDriveOrders mergeSteps 返回 List<Route.Step> mergedSteps 返回DriveOrder 返回DriveOrder 返回Optional<List<DriveOrder>> User AbstractReroutingStrategy AbstractReroutingStrategy子类 Router DriveOrderMerger AbstractDriveOrderMerger AbstractDriveOrderMerger子类

发起重新路由时机
1、拓扑结构发生变化
2、调用服务触发
3、界面上触发发起RerouteAction
4、在AssignNextDriveOrderPhase阶段,配置了DriveOrder完成时重新路由

状态变化

订单状态

CheckNewOrdersPhase
CheckNewOrdersPhase
AssignFreeOrdersPhase
AssignNextDriveOrdersPhase
abortAssignedOrder
abortAssignedOrder
RAW
ACTIVE
DISPATCHABLE
BEING_PROCESSED
FINISHED
WITHDRAWN

小车状态

AssignFreeOrdersPhase
AssignReservedOrdersPhase
AssignFreeOrdersPhase
AssignFreeOrdersPhase
AssignReservedOrdersPhase
checkForPendingCommands
FinishWithdrawalsPhase
AssignNextDriveOrdersPhase
AssignNextDriveOrdersPhase
AssignNextDriveOrdersPhase
IDLE
PROCESSING_ORDER
AWAITING_ORDER

小车管理

VehicleCommAdapterRegistry注册小车工厂,来管理小车的创建

VehicleCommAdapterRegistry
-Map<VehicleCommAdapterDescription, VehicleCommAdapterFactory> factories
+VehicleCommAdapterFactory findFactoryFor(VehicleCommAdapterDescription description)
+List~VehicleCommAdapterFactory~ findFactoriesFor(Vehicle vehicle)
«interface»
VehicleCommAdapterFactory
+VehicleCommAdapterDescription getDescription()
+boolean providesAdapterFor(Vehicle vehicle)
+VehicleCommAdapter getAdapterFor(Vehicle vehicle)
LoopbackCommunicationAdapterFactory
NullVehicleCommAdapterFactory

VehicleCommAdapterRegistry中factories使用的是TreeMap,排序规则为

  • LoopbackCommunicationAdapterDescription类型排在最后
  • 以VehicleCommAdapterDescription的getDescription返回字符串 作字典排序
    VehicleCommAdapterRegistry是以VehicleCommAdapterFactory的getDescription返回的描述作为关键字来管理

外围设备管理

PeripheralCommAdapterRegistry注册外围设备工厂,来管理外围设备的创建

PeripheralCommAdapterRegistry
+Map<PeripheralCommAdapterDescriptio, PeripheralCommAdapterFactory> factories
+PeripheralCommAdapterFactory findFactoryFor(PeripheralCommAdapterDescription description)
+List~PeripheralCommAdapterFactory~ findFactoriesFor(Location location)
«interface»
PeripheralCommAdapterFactory
+PeripheralCommAdapterDescription getDescription()
+boolean providesAdapterFor(Location location)
+PeripheralCommAdapter getAdapterFor(Location location)
LoopbackPeripheralCommAdapterFactory
NullPeripheralCommAdapterFactory

PeripheralCommAdapterRegistry是以PeripheralCommAdapterFactory的getDescription返回的描述来作为关键字来管理

分发

DefaultDispatcher#dispatch调用FullDispatchTask

  • CheckNewOrdersPhase
    TransportOrder维度

  • FinishWithdrawalsPhase
    小车Vehicle维度

    • 对于非立即取消订单的处理,在等待小车状态为AWAITING_ORDER时,检查是否有处于WITHDRAW的订单,则调用finishAbortion将小车的状态设置为IDLE
  • AssignNextDriveOrdersPhase
    小车Vehicle维度

  • AssignSequenceSuccessorsPhase
    小车Vehicle维度

  • 分配订单

    • AssignReservedOrdersPhase
      小车Vehicle维度
      • 在AssignFreeOrdersPhase阶段分配没有成功时,在等待小车状态为Idle后,保留在订单预分配池中的订单OrderReservationPool开始计算路由处理
    • AssignFreeOrdersPhase
      TransportOrder维度和小车Vehicle维度。筛选小车的规则为IsAvailableForAnyOrder
      • 小车的状态为IDLE或者状态为PROCESSING_ORDER但是其对应的订单为可有可无的,即分配的订单为停车订单
      • OrderReservationPool预订池中没有对应小车
        在分配时,如果当前小车有订单要处理,则将订单与小车的关系添加到预分配池中。分配规则为
      • 对Vechicle作CompositeVehicleSelectionFilter筛选
      • 对运输订单作CompositeTransportOrderSelectionFilter筛选
      • 小车数量小于订单数时
        • 对小车作CompositeVehicleComparator排序
        • 计算单个小车到所有订单的距离成本,对候选名单作CompositeAssignmentCandidateSelectionFilter筛选,对候选名单作CompositeOrderCandidateComparator排序,选择第一个
      • 订单发数小于小车数时
        • 对订单作CompositeOrderComparator排序
        • 计算单个订单到所有小车的距离成本,对候选名单作CompositeAssignmentCandidateSelectionFilter筛选,对候选名单作CompositeVehicleCandidateComparator排序,选择第一个
          在分配小车时,如果小车已经存在订单,则将小车与订单的对应关系添加到OrderReservationPool中,同时取消当前小车的订单TransportOrderUtil#abortOrder,内部调用abortAssignedOrder,其会更新订单状态为WITHDRAWN
      • 对于需要立即取消订单的,会调用clearDriveOrder设置当前的DriveOrder为NULL, 等待分配标识waitingForAllocation为false, pendingResources为null,清空命令队列。同时将小车的处理状态设置为IDLE
      • 对于无需立即取消订单的,调用abortDriveOrder,清除后一步的命令集
  • 小车充电(小车Vehicle维度)

    • RechargeIdleVehiclesPhase
  • 停靠小车(小车Vehicle维度)

    • PrioritizedReparkPhase
    • PrioritizedParkingPhase
    • ParkIdleVehiclesPhase
      停靠小车阶段创建的订单的属性dispensable(可有可无)为true,在下次AssignFreeOrdersPhase分发阶段时,为小车分配订单时,IsAvailableForAnyOrder在判断如果小车空闲时,或者当前小车分配的订单类型是可有可无时,可以为小车重新分配移动订单
«abstract»
AbstractParkingPhase
PrioritizedReparkPhase
PrioritizedParkingPhase
ParkIdleVehiclesPhase
«interface»
ParkingPositionSupplier
«abstract»
AbstractParkingPositionSupplier
DefaultParkingPositionSupplier
CompositeParkVehicleSelectionFilter
«interface»
ParkVehicleSelectionFilter
CompositeReparkVehicleSelectionFilter
«interface»
ReparkVehicleSelectionFilter
IsParkable
PrioritizedParkingPositionSupplier
IsReparkable
ParkingPositionPriorityComparator

模型

TCSObjectManager
-EventHandler eventHandler
-TCSObjectRepository objectRepo
PlantModelManager
TCSObejct<E>
withProperty(String key, String value) : TCSObejct<E>
withProperties(Map<String, String> properties) : TCSObejct<E>
TCSResource<E>
Block
Path
Point
Location
Group
LocationType
Vehicle
VisualLayout
OrderSequence
TransportOrder
PeripheralJob

TCSObejct :主要是Dispatcher分发时使用
TCSResource :主要是Scheduler调度资源时使用

PeripheralInteractor

外围交互器,主要与外围设备交互,在VehicleContorller 的实现类DefaultVehicleController中使用到,主要是执行移动命令的前处理和后处理

DefaultVehicleController
PeripheralInteractor

交互

1
N
PeripheralInteractor
- Map<MovementCommand, PeripheralInteraction> preMovementInteractions
- Map<MovementCommand, PeripheralInteraction> postMovementInteractions
PeripheralInteraction

preMovementInteractions:移动命令对应的前置交互操作
postMovementInteractions:移动命令对应的后置交互操作
prepareInteractions:准备命令、订单对应的前后置操作
startPreMovementInteractions:开始调起前置操作
startPostMovementInteractions:开始调走后置操作
其中prepareInteractionsstartPreMovementInteractions是在资源分配成功后allocationSuccessful相继调用的

public boolean allocationSuccessful(@Nonnull Set<TCSResource<?>> resources) {
    synchronized (commAdapter) {
     ....
      peripheralInteractor.prepareInteractions(transportOrder.getReference(), command);
      peripheralInteractor.startPreMovementInteractions(command,
                                                        () -> sendCommand(command),
                                                 this::onMovementInteractionFailed);
    }
   .....
  }

startPostMovementInteractions是在命令执行完后commandExecuted调用的

private void commandExecuted(MovementCommand executedCommand) {
    synchronized (commAdapter) {
     .....
      peripheralInteractor.startPostMovementInteractions(executedCommand,
                                                  this::checkForPendingCommands,
                                                  this::onMovementInteractionFailed);
    }
  }

startPreMovementInteractionsstartPostMovementInteractions是异步发起job的,即通过peripheralDispatcherService.dispatch(),因此,交互操作成功失败是分别通过调用PeripheralInteraction 中的interactionSucceededCallbackinteractionFailedCallback

事件监听

PeripheralInteractor实现了EventHandler接口,主要是处理交互完成、失败的事件,最终是调用PeripheralInteraction的完成回调onPeripheralJobFinished和失败回调onPeripheralJobFailed,即start时设置的成功、失败回调interactionSucceededCallback, interactionFailedCallback

public void onEvent(Object event) {
    if (!(event instanceof TCSObjectEvent)) {
      return;
    }

    TCSObjectEvent objectEvent = (TCSObjectEvent) event;
    if (objectEvent.getType() != TCSObjectEvent.Type.OBJECT_MODIFIED) {
      return;
    }

    if (objectEvent.getCurrentOrPreviousObjectState() instanceof PeripheralJob) {
      onPeripheralJobChange(objectEvent);
    }
  }

  private void onPeripheralJobChange(TCSObjectEvent event) {
    PeripheralJob prevJobState = (PeripheralJob) event.getPreviousObjectState();
    PeripheralJob currJobState = (PeripheralJob) event.getCurrentObjectState();

    if (prevJobState.getState() != currJobState.getState()) {
      switch (currJobState.getState()) {
        case FINISHED:
          onPeripheralJobFinished(currJobState);
          break;
        case FAILED:
          onPeripheralJobFailed(currJobState);
          break;
        default: // Do nothing
      }
    }
  }
private void onPeripheralJobFinished(PeripheralJob job) {
    Stream.concat(preMovementInteractions.values().stream(),
                  postMovementInteractions.values().stream())
        .forEach(interaction -> interaction.onPeripheralJobFinished(job));

    Set<MovementCommand> preMovementsPrepared = preMovementInteractions.entrySet().stream()
        .filter(entry -> entry.getValue().isFinished())
        .map(entry -> entry.getKey())
        .collect(Collectors.toSet());
    Set<MovementCommand> postMovementsPrepared = postMovementInteractions.entrySet().stream()
        .filter(entry -> entry.getValue().isFinished())
        .map(entry -> entry.getKey())
        .collect(Collectors.toSet());

    preMovementsPrepared.forEach(
        movementCommand -> preMovementInteractions.remove(movementCommand)
    );
    postMovementsPrepared.forEach(
        movementCommand -> postMovementInteractions.remove(movementCommand)
    );
  }

  private void onPeripheralJobFailed(PeripheralJob job) {
    Stream.concat(preMovementInteractions.values().stream(),
                  postMovementInteractions.values().stream())
        .forEach(interaction -> interaction.onPeripheralJobFailed(job));
  }

初始化时会向eventBus订阅自己

 public void initialize() {
    if (isInitialized()) {
      return;
    }

    eventSource.subscribe(this);

    initialized = true;
  }

DefaultVehicleController对资源的管理

其使用成员allocatedResources来管理分配的资源

  • 初始时null添加到allocatedResources队列中
  • 首先根据DriveOrder创建命令集,即Route的构成steps,添加到futureCommands队列中
  • 取出队列中的第一条命令,计算其所需要的资源,然后分配,分配成功后,将资源添加到allocatedResources队列
  • 在发送完命令后,会判断futureCommands队列是否还有命令,如果有并且满足一定条件,会继续进行上一步
  • 在命令执行完后,会从allocatedResources队列取出首元素释放,即释放上一步申请的资源(因为队列中的第一元素为null)
allocatedResources.add(null);

private void createFutureCommands(DriveOrder newOrder, Map<String, String> orderProperties) {
    // Start processing the new order, i.e. fill futureCommands with corresponding command objects.
    String op = newOrder.getDestination().getOperation();
    Route orderRoute = newOrder.getRoute();
    Point finalDestination = orderRoute.getFinalDestinationPoint();
    Location finalDestinationLocation
        = vehicleService.fetchObject(Location.class,
                                     newOrder.getDestination().getDestination().getName());
    Map<String, String> destProperties = newOrder.getDestination().getProperties();
    Iterator<Step> stepIter = orderRoute.getSteps().iterator();
    while (stepIter.hasNext()) {
      Step curStep = stepIter.next();
      // Ignore report positions on the route.
      if (curStep.getDestinationPoint().isHaltingPosition()) {
        boolean isFinalMovement = !stepIter.hasNext();

        String operation = isFinalMovement ? op : MovementCommand.NO_OPERATION;
        Location location = isFinalMovement ? finalDestinationLocation : null;

        futureCommands.add(
            new MovementCommandImpl(orderRoute,
                                    curStep,
                                    operation,
                                    location,
                                    isFinalMovement,
                                    finalDestinationLocation,
                                    finalDestination,
                                    op,
                                    mergeProperties(orderProperties, destProperties))
        );
      }
    }
  }


private void allocateForNextCommand() {
    checkState(pendingCommand == null, "pendingCommand != null");

    // Find out which resources are actually needed for the next command.
    MovementCommand moveCmd = futureCommands.poll();
    pendingResources = getNeededResources(moveCmd);
    LOG.debug("{}: Allocating resources: {}", vehicle.getName(), pendingResources);
    scheduler.allocate(this, pendingResources);
    // Remember that we're waiting for an allocation. This ensures that we only
    // wait for one allocation at a time, and that we get the resources from the
    // scheduler in the right order.
    waitingForAllocation = true;
    pendingCommand = moveCmd;
  }

private void commandExecuted(MovementCommand executedCommand) {
    requireNonNull(executedCommand, "executedCommand");

    synchronized (commAdapter) {
      // Check if the executed command is the one we expect at this point.
      MovementCommand expectedCommand = commandsSent.peek();
      if (!Objects.equals(expectedCommand, executedCommand)) {
        LOG.warn("{}: Communication adapter executed unexpected command: {} != {}",
                 vehicle.getName(),
                 executedCommand,
                 expectedCommand);
        // XXX The communication adapter executed an unexpected command. Do something!
      }
      // Remove the command from the queue, since it has been processed successfully.
      lastCommandExecuted = commandsSent.remove();
      // Free resources allocated for the command before the one now executed.
      Set<TCSResource<?>> oldResources = allocatedResources.poll();
      if (oldResources != null) {
        LOG.debug("{}: Freeing resources: {}", vehicle.getName(), oldResources);
        scheduler.free(this, oldResources);
      }
      else {
        LOG.debug("{}: Nothing to free.", vehicle.getName());
      }

      vehicleService.updateVehicleAllocatedResources(vehicle.getReference(),
                                                     toListOfResourceSets(allocatedResources));

      peripheralInteractor.startPostMovementInteractions(executedCommand,
                                                         this::checkForPendingCommands,
                                                         this::onMovementInteractionFailed);
    }
  }

参考资料:
https://www.likecs.com/show-425956.html
官网

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

kgduu

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值