UNPKG

vda-5050-lib

Version:

Universal VDA 5050 library for Node.js and browsers

1,069 lines (1,068 loc) 45.5 kB
/*! Copyright (c) 2021 Siemens AG. Licensed under the MIT License. */ import { Action, ActionState, ActionStatus, AgvClient, AgvId, AgvPosition, BatteryState, ClientOptions, Edge, Error, ErrorReference, Factsheet, Headerless, Node, OperatingMode, Order, SafetyStatus, State, Trajectory, Velocity } from ".."; /** * Represents context information needed to perform initializations on an AGV * adapter when it is attached. * * @category AGV Controller */ export interface AttachContext { /** * Callback to be invoked by the AGV adapter when initialization has * completed and the adapter is ready to process any of the other handler * functions defined in the `AgvAdapter` interface. * * @param initialState initial partial state to be reported on attachment */ attached(initialState: Partial<Headerless<State>>): void; } /** * Represents context information needed to perform deinitializations on an AGV * adapter when it is detached. * * @category AGV Controller */ export interface DetachContext { /** * Callback to be invoked by the AGV adapter when deinitialization has * completed and the adapter has terminated its operations. * * @param detachState partial state to be reported on detachment */ detached(detachState: Partial<Headerless<State>>): void; } /** * Represents change information about action status, including result * description, error description, and linked state (if applicable). * * @category AGV Controller */ export interface ActionStatusChangeInfo { /** * The changed action status. */ readonly actionStatus: ActionStatus; /** * A result reported if action status is FINISHED (optional). */ readonly resultDescription?: string; /** * An additional error state is reported with the given error description if action * fails and status is FAILED (optional). */ readonly errorDescription?: string; /** * Specifies a partial state that must be updated together with the action * status change (optional). */ readonly linkedState?: Partial<Headerless<State>>; } /** * Defines the scope of an action, either `"instant"`, `"node"`, or `"edge"`. * * @category AGV Controller */ export type ActionScope = "instant" | "node" | "edge"; /** * Represents context information of a node, edge, or instant action to be * processed by an `executeAction`, `finishEdgeAction`, or `cancelAction` * handler. * * @category AGV Controller */ export interface ActionContext { /** * The context's action. */ readonly action: Action; /** * Defines whether the context's action is an instant, node, or edge action. */ readonly scope: ActionScope; /** * Determines whether the AGV must stop driving before executing the action * (optional, only specified in the context of an `executeAction` handler). * * If specified as `true` driving must be stopped; if `false` the AGV must * keep its current driving state. * * @remarks This parameter is not specified for `finishEdgeAction`, * `isActionExecutable`, and `cancelAction` handlers. */ readonly stopDriving?: boolean; /** * Specifies the node if the context's action is a node action; otherwise * this property is not defined. */ readonly node?: Node; /** * Specifies the edge if the context's action is an edge action; otherwise * this property is not defined. */ readonly edge?: Edge; /** * Specifies the start node of the edge if the context's action is an edge * action; otherwise this property is not defined. */ readonly edgeStartNode?: Node; /** * Specifies the end node of the edge if the context's action is an edge * action; otherwise this property is not defined. */ readonly edgeEndNode?: Node; /** * Specifies the `orderId` of an order's node or edge action; the active * `orderId` for instant actions if one is currently active; otherwise this * property is not defined. */ readonly activeOrderId?: string; /** * Callback to be invoked by the AGV adapter whenever the action transitions * to a new action status. * * This method should be invoked according to the progress of the action, * passing in an updated action status together with the result description, * error description, and linked partial state (if applicable). * * @remarks * This parameter is not defined for the `isActionExecutable` handler. * * When the action transitions into status FAILED an additional error state * can be reported by specifying an error description. * * @param status new action status with optional result description, error * description, and linked state */ updateActionStatus(statusChange: ActionStatusChangeInfo): void; } /** * Represents context information to check whether a route can be traversed by * the AGV. * * @category AGV Controller */ export interface RouteTraversableContext { /** * The nodes to be traversed. */ readonly nodes: Node[]; /** * The edges to be traversed. */ readonly edges: Edge[]; } /** * Represents context information of a `stopTraverse` operation handler. * * @category AGV Controller */ export interface StopTraverseContext { /** * Callback to be invoked once by the AGV adapter if, due to AGV's * capabilities, it couldn't stop immediately on the current node or in * between nodes but has to drive to the next node. * * After reaching the next node, the AGV must stop and the callback * `stopped` defined by this interface must be invoked. * * @remarks When invoked the parameter `nextNode` can be easily retrieved by * the AGV adapter from the edge context currently being traversed, as * defined by `TraverseContext.endNode`. */ drivingToNextNode(nextNode: Node): void; /** * Callback to be invoked once by the AGV adapter when the AGV has stopped * driving in response to the invocation of the `stopTraverse` * operation handler. * * If the AGV has to drive to the next node upon order cancelation, this * handler must be invoked on arrival instead of the * `TraverseContext.edgeTraversed` handler. */ stopped(): void; } /** * Represents context information of an edge traversal. * * @category AGV Controller */ export interface TraverseEdgeContext { /** * The edge to be traversed. */ readonly edge: Edge; /** * The start node of the edge to be traversed. */ readonly startNode: Node; /** * The end node of the edge to be traversed. */ readonly endNode: Node; /** * Defines the edge trajectory path calculated by the AGV or master control * (optional). * * If not specified or `undefined`, the AGV cannot process trajectories or * calculates the route on the fly when the `traverse` handler is invoked. */ readonly trajectory?: Trajectory; /** * Callback to be invoked once by the AGV adapter when the edge of this * context has been completely traversed. */ edgeTraversed(): void; } /** * Represents context information of a trajectory, including its edge, and its * edge's start and end nodes. * * @category AGV Controller */ export interface TrajectoryContext { /** * The trajectory edge. */ readonly edge: Edge; /** * The start node of the trajectory edge. */ readonly startNode: Node; /** * The end node of the trajectory edge. */ readonly endNode: Node; } /** * Defines a plug-in commanding interface for performing AGV specific operations * to be registered with an AGV controller. * * The adapter's functions provide an abstract interface that maps generic * operations to an AGV specific navigation and control interface. These * operations include executing or canceling a node action, an edge action, or * an instant action, traversing/navigating an edge, and calculating trajectory * paths. * * Concrete implementations of AGV adapters are usually provided by an * integrator or by the vendor designing the vehicle control interface. * * @remarks An AGV adapter and its logic is realized as a class that implements * this interface. This class must provide a constructor that conforms to the * interface `AgvAdapterConstructor`. Using dependeny injection, this class type * is passed as a configuration option to the AGV controller (see * `AgvControllerOptions.agvAdapterType`) which creates an instance of the * adapter class with appropriate constructor parameters. * * @category AGV Controller */ export interface AgvAdapter { /** * The AGV controller this adapter is associated with. * * Used to invoke state update methods defined by the AGV controller. */ readonly controller: AgvController; /** * Defines the name of this adapter used for identification and display * purposes. */ readonly name: string; /** * Defines the protocol version number of this adapter, a positive integer. * * Increment this version whenever you make changes to the adapter protocol. * * @remarks The API version of this adapter must match (i.e. equal) the API * version of the associated AGV controller. If both versions differ, an * error is thrown when the adapter is instantiated. */ readonly apiVersion: number; /** * Registers a handler that is invoked once by the associated controller * when the adapter should perform initializations and connect to the AGV * navigation & control interface. * * The handler function should compute initial vehicles states and report * them back to the controller after initialization is complete through the * callback `AttachContext.attached`. Until this callback is invoked, the * controller won't invoke any of the other handler functions defined in * this interface. * * @param context context information for attachment */ attach(context: AttachContext): void; /** * Registers a handler that is invoked once by the associated controller * when the adapter should perform deinitializations and disconnect from the * AGV navigation & control interface. * * The handler function may compute final vehicles states and report them * back to the controller after deinitialization is complete through the * callback `DetachContext.detached`. After this callback is invoked, the * controller won't invoke any of the other handler functions defined in * this interface. * * @param context context information for detachment */ detach(context: DetachContext): void; /** * Registers a handler that is invoked by the associated controller to check * synchronously whether a given node, edge, or instant action can be * executed principally. * * The handler function should return a non-empty array of error references * if the action cannot be executed and must be rejected. For example, if an * action cannot be completed because of external factors (e.g. no load at * expected position), or if an action conflicts with the AGV's currently * active order (e.g. instant action says to lower fork while order says to * raise fork), or if the order contains actions the vehicle cannot perform * (e.g. lifting height higher than maximum lifting height, or lifting * actions although no stroke is installed). * * If the action can be executed, the handler should return an empty array * or `undefined`. * * @remarks * You should not include the `actionId` and the `actionType` as error * references as these are added automatically by the controller. If the * error was caused by erroneous action parameters, include a list of * parameters in the reference. * * If an instant action is not executable in principle it will be rejected * with an error by the AGV controller. If a node or edge action is not * executable in principle, the order will be rejected by the AGV * controller. In the latter case all order node and edge actions are * checked for executability _before_ the order is carried out. * * @param context context information of a node, edge, or instant action to * be checked for execution * @returns an array of error references if action cannot be executed; an * empty array or `undefined` if action can be executed */ isActionExecutable(context: ActionContext): ErrorReference[]; /** * Registers a handler that is invoked by the associated controller whenever * an instant, node, or edge action is to be executed. * * While the action is executed, the callback `context.updateActionStatus` * must be invoked whenever the action transitions to a new status, passing * in the new action status together with result description and linked * partial state (if applicable). * * If the action context of an action specifies `true` on the `stopDriving` * property the AGV must stop driving and eventually invoke * `controller.updateDrivingState` before executing the action; otherwise * the current driving state must be kept. * * @remarks * For a node or edge action, the initial action status WAITING is already * preset on the controller's current state. For an instant action, no * action status is preset on the current state. In both cases, the action * handler must initially transition to the action's initial state, either * INITIALIZING or RUNNING (or PAUSED if pause mode is activated), FINISHED, * or FAILED. * * If pause mode is active, the action to be executed should transition to * PAUSED state (immediately or after initializing/running, if needed). If * pause mode is deactivated, the action should transition to the previous * status again. * * For instant actions 'startPause' and 'stopPause' this handler must * pause/resume all other actions, and update their action status and linked * state `paused` accordingly. Node processing of an active order is * suspended and resumed automatically by the AGV controller. Edge traversal * must be suspended and resumed by the AGV adapter. * * Note that the instant actions 'stateRequest' and 'cancelOrder' are never * dispatched to this handler as they are handled by the AGV controller * itself. * * @param context context information of a node, edge, or instant action to * be executed */ executeAction(context: ActionContext): void; /** * Registers a handler that is invoked by the associated controller whenever * a not yet finished or failed node or edge action of an active order is to * be canceled. * * If the action cannot be interrupted it should continue running until * finished or failed. If the action can be interrupted it should be * canceled and action status FAILED should be reported via * `context.updateActionStatus`. * * @remarks This handler function is only invoked for node and edge actions * previously scheduled by the `executeAction` handler and not yet finished * or failed, i.e. for actions that are either in status INITIALIZING, * RUNNING, or PAUSED. * * @param context context information of a node or edge action to be * canceled */ cancelAction(context: ActionContext): void; /** * Registers a handler that is invoked by the associated controller whenever * an active edge action (i.e. one with status unequal FINISHED or FAILED) * must be terminated. * * @remarks The registered handler is invoked whenever a node is traversed * and any active actions on the edge leading up to that node must be * terminated. The handler should finish or cancel the action and report an * updated action status FINISHED or FAILED via * `context.updateActionStatus`. * * @param context context information of an edge action to be finished */ finishEdgeAction(context: ActionContext): void; /** * Registers a handler that is invoked by the associated controller whenever * it needs to check whether a given node's position is within the allowed * deviation range of the current AGV position. * * The handler function should return an array of error references if the * node is not within the deviation range by checking the node properties x, * y, theta, mapId, allowedDeviationTheta, and allowedDeviationXy against * the current AGV position. Otherwise, the handler should return an empty * array or `undefined`. * * @remarks You should not include the `nodeId` as error reference as it is * added automatically by the controller. Instead, include all node * property-value pairs that fail the check. * * @param node a Node object * @returns an array of error references if node is not within deviation * range; an empty array or `undefined` otherwise */ isNodeWithinDeviationRange(node: Node): ErrorReference[]; /** * Registers a handler that is invoked by the associated controller to check * synchronously whether AGV can traverse a given route with regard to * vehicle-specific constraints on node/edge properties that must be * validated by the AGV adapter as the AGV controller is not aware of them. * * The nodes and edges passed to this handler are guaranteed to be * well-formed and valid with respect to the proper sequence of base/horizon * nodes and edges. * * Node and edge actions must not be checked by this handler; they are * checked individually by the handler `isActionExecutable`. * * The handler function should return an array of error references if the * route cannot be traversed. For example, if an edge has fields that the * vehicle cannot use (e.g. trajectory) or misses fields it requires (e.g. * nodePosition with mapId for free navigation) or fields it doesn't support * (e.g. rotationAllowed). Otherwise, the handler should return an empty * array or `undefined`. * * @param context context information with the route * @returns an array of error references if route cannot be traversed; an * empty array or `undefined` otherwise */ isRouteTraversable(context: RouteTraversableContext): ErrorReference[]; /** * Registers a handler that is invoked by the associated controller to * traverse a given edge with a given start and end node using an (optional) * trajectory. * * When the handler function is invoked the AGV should drive along the given * trajectory (if specified) or by free navigation (if not specified), * invoking `controller.updateDrivingState` if needed. However, if pause * mode is activated the AGV has to postpone traversal until pause mode is * deactivated by instant action 'stopPause'. * * When the given edge has been traversed completely, the callback * `context.edgeTraversed` must be invoked. Until this callback has been * called it is guaranteed that no other invocation of this handler occurs. * * @remarks * While traversing an edge the AGV adapter must handle activation and * deactivation of pause mode (triggered either by instant actions * 'startPause/stopPause' or by a hardware button) that affects driving * state and update it accordingly. * * This handler must take edge and end node orientation changes into account * if supported by the AGV. If an edge orientation is required and rotation * is disallowed on the edge, rotate the vehicle before entering the edge, * otherwise rotate the vehicle on the edge to the desired ortientation. * Upon traversal and if required, the vehicle must be rotated on the end * node according to node's theta angle. * * @param context context information of an edge traversal */ traverseEdge(context: TraverseEdgeContext): void; /** * Registers a handler that is invoked by the associated controller whenever * the AGV should stop driving while the active order is being canceled and * after all node/edge actions of this order have already been canceled. * * If the AGV is on a node or can stop if in between nodes, it should stop * gracefully; otherwise it should continue driving to the next node, and * automatically stop on arrival. In all these cases the `traverse` * handler's callback `context.edgeTraversed` should not be invoked any more * (even if you do invoke it, it is ignored by the AGV controller). * * The handler function must invoke the callback `context.stopped` once as * soon as the AGV has stopped driving, even if the vehicle is already * stopped for another reason. After reporting this state the AGV should be * able to receive a new order. Until this callback has been called it is * guaranteed that no other invocation of this handler occurs. * * If the AGV's capabilities require it to drive to the next node before * stopping, the adapter must invoke both the callback * `context.drivingToNextNode` immediately and the callback * `context.stopped` after stopping on arrival. * * @remarks It is guaranteed that whenever this function is called all * scheduled node and edge actions of the order to be canceled have ended, * i.e. are either in status FINISHED or FAILED. * * @param context context information for reporting when AGV has stopped * driving. */ stopTraverse(context: StopTraverseContext): void; /** * Registers a handler that is invoked by the associated controller to * synchronously calculate the trajectory for a given edge (optional). * * @remarks This handler is only required if the AGV should precalculate the * trajectory path of all order edges by itself whenever an order arrives. * The handler is invoked on all order edges (including horizon edges) in * the given edges order in series. Do not specify a handler function if the * AGV should determine the route on the fly when an edge is being traversed * by invoking the `traverse` handler. * * @param context context information of a trajectory * @returns the calculated trajectory object */ trajectory?(context: TrajectoryContext): Trajectory; } /** * Defines configuration options common to all AGV adapter implementations. * * This base interface may be extended by concrete adapter implementations to * provide adapter specific options. * * @category AGV Controller */ export interface AgvAdapterOptions { } /** * A debugger function associated with an AGV adapter. * * Used to log informational, debug, and error messages. The first argument * is a formatter string with printf-style formatting supporting the * following directives: `%O` (object multi-line), `%o` (object * single-line), `%s` (string), `%d` (number), `%j` (JSON), `%%` (escape). * * @category AGV Controller */ export type AgvAdapterDebugger = (formatter: any, ...args: any[]) => void; /** * Defines the constructor signature for classes that implement the interface * `AgvAdapter`. * * @category AGV Controller */ export type AgvAdapterConstructor = new (controller: AgvController, adapterOptions: AgvAdapterOptions, debug: AgvAdapterDebugger) => AgvAdapter; /** * Defines configuration options of an AGV controller. * * @category AGV Controller */ export interface AgvControllerOptions { /** * Type of the AGV adapter class that should be associated with an AGV * controller. * * @remarks When the AGV controller is created, the given class is * automatically instantiated and associated with it. */ agvAdapterType: AgvAdapterConstructor; /** * Periodic interval in milliseconds the State message should be published * at the latest (optional). * * If not specified, the value defaults to 30000ms. */ publishStateInterval?: number; /** * Periodic interval in milliseconds the Visualization message should be * published (optional). * * If not specified, the value defaults to 1000ms. If specified as 0 (zero), * visualization messages are suppressed, i.e. not published at all. */ publishVisualizationInterval?: number; /** * Number of `State` messages to be published for an instant action that has * ended or errored (optional). * * This option determines how many times the action state of an instant * action that has ended (i.e is either finished or failed) or errored (i.e. * is not executable right from the start) should be reported in the * `actionStates` array of a published AGV state message. * * This feature is important to ensure that a published State object is not * cluttered with outdated instant action states. The VDA 5050 specification * itself doesn't specify when to clean up these action states. * * If not specified, the value defaults to 5. If value is less than 1 * exactly one State message is published. */ finalInstantActionStateChangePublishCount?: number; } /** * Implements the common control logic and interaction flows on the vehicle * plane (automated guided vehicle, AGV) as defined by the VDA 5050 * specification. This includes processing of received orders and instant * actions, management of order state and AGV state, as well as providing * updated state and visualization data to the master control. * * Together with its counterpart, the master control controller class * `MasterController`, it builds a high-level abstraction layer of the complex * business logic defined in the VDA 5050 specification. * * To keep the VDA 5050 business logic generic and independent of specific types * of AGVs, the AGV controller uses plug-ins to adapt to their diverse * navigation and control interfaces. A so-called AGV adapter is registered with * an AGV controller providing an abstract interface that maps generic * controller operations to the concrete control interface of an AGV. These * operations include, among others, executing or canceling a node action, an * edge action, or an instant action, traversing/navigating an edge, and * calculating trajectory paths. * * This class builds on top of the communication abstraction layer provided by * the `AgvClient` class which it extends. This class also provides extension * points by protected methods through which behavior can be customized if * needed. * * @remarks * Regarding errors reported in state messages, the following conventions are * used (see enum `ErrorTypes`): * - Order related errors always include the errorReferences "headerId: * order.headerid", "topic: order", "orderId" (and "orderUpdateId" if * applicable) and specify an errorType of "orderError", "orderUpdateError", * "noRouteError", or "validationError". * - Order/instant action related errors always include the error reference * "actionId" along with optional references such as "actionParameters". * - Order action errors (on failure) always include an errorReference "topic: * order" and the generic errorType "orderActionError". * - Instant action errors always include an errorReference "topic: * instantAction" and either an action-specify errorType such as * "noOrderToCancel" or the generic errorType "instantActionError". * * The AGV controller always overrides the value of the client option * `topicObjectValidation.inbound` to `false` so that it can respond with an * error state to invalid incoming messages. This means that subclasses of * `AgvController` must also validate extension topics explicitely using method * `validateTopicObject`. * * If the AGV controller receives a topic with an invalid object payload, it * reports an error state with `errorType: "validationError"` containing the * error reference key `topic` (value is `"order"` for orders, * `"instantActions"` for instant actions, etc.). If a property `headerId` is * present on the received object, it is also included in the error references. * Additionally, if present for an order validation error, `"orderId"` is added * as error reference. * * @category AGV Controller */ export declare class AgvController extends AgvClient { agvId: AgvId; /** * Special error reference key used to append detail information to an * `Error.errorDescription`. */ static readonly REF_KEY_ERROR_DESCRIPTION_DETAIL = "errorDescriptionDetail"; /** * The currently active order (update), the latest completed order, or * undefined if no order has been received yet. * * @remarks * Use `hasActiveOrder` to determine whether any current order is active. * * Use `hasCancelingOrder` to determine whether any current order is being * canceled. */ protected currentOrder: Order; private _currentState; private _currentPausedNode; private _currentInstantActions; private _instantActionsEndedPublishCount; private _instantActionsErroredPublishCount; private _cancelOrderContext; private _publishStateTimerId; private _publishVisualizationIntervalId; private readonly _agvAdapter; private readonly _controllerOptions; private _currentFactsheet; /** * Creates an instance of `AgvController`, a subclass of `AgvClient`. * * @param agvId the identity of the AGV this controller represents * @param clientOptions configuration options for the `AgvClient` * @param controllerOptions configuration options for the `AgvController` * @param adapterOptions configurations options for the `AgvAdapter` */ constructor(agvId: AgvId, clientOptions: ClientOptions, controllerOptions: AgvControllerOptions, adapterOptions: AgvAdapterOptions); /** * Gets the AGV controller configuration options as a readonly object with * default values filled in for options not specified. */ get controllerOptions(): Readonly<Required<AgvControllerOptions>>; /** * Gets the protocol version of the AGV adapter API used by this controller, * a positive integer. * * @remarks The API version of this controller must match (i.e. equal) the * API version of the associated adapter. If both versions differ, an error * is thrown when the adapter is instantiated. */ get adapterApiVersion(): number; /** * Gets current state of AGV controller as an immutable object. * * @remarks * The returned state object is immutable, i.e. it is guaranteed to not be * changed by this controller. To modify the state maintained by this * controller, adapters and subclasses must invoke one of the provided state * update functions. * * The returned state object always includes a timestamp property that * corresponds to its latest update time. * * @returns the current state as an immutable object with latest update * timestamp */ get currentState(): Headerless<State>; /** * Indicates whether the AGV controller has an active order. * * @remarks An order is considered active if at least one base/horizon node * or edge has not yet been traversed or if at least one node/edge action * has not yet terminated, i.e. not finished or failed. * * @returns true if the `currentOrder` is defined and active; false if the * latest order has been completed or no order has been received yet. */ get hasActiveOrder(): boolean; /** * Indicates whether the AGV controller is currently canceling the active * order. */ get hasCancelingOrder(): boolean; /** * Determines whether the given action state represents an instant action. * * @param state an action state * @returns `true` if action state represents an instant action; `false` * otherwise */ isInstantActionState(state: ActionState): boolean; /** * To be invoked by the AGV adapter whenever a new AGV position and/or * velocity is available. * * @remarks The update rate should correspond with the option * `publishVisualizationInterval` configured for this AGV controller. * * @param agvPosition new AGV position (optional) * @param velocity new velocity (optional) * @param reportImmediately whether to publish a State message immediately * afterwards (optional, defaults to false) */ updateAgvPositionVelocity(agvPosition?: AgvPosition, velocity?: Velocity, reportImmediately?: boolean): void; /** * To be invoked by the AGV adapter whenever a new battery state is * available. * * @param batteryState new battery state * @param reportImmediately whether to publish a State message immediately * afterwards (optional, defaults to false) */ updateBatteryState(batteryState: BatteryState, reportImmediately?: boolean): void; /** * To be invoked by the AGV adapter whenever the driving/rotating state of * the AGV changes. * * @remarks Other movements of the AGV (e.g. lift movements) are not * included here. * * @param driving new driving state * @param reportImmediately whether to publish a State message immediately * afterwards (optional, defaults to false) */ updateDrivingState(driving: boolean, reportImmediately?: boolean): void; /** * To be invoked by the AGV adapter whenever the paused state changes, * either because of the push of a physical button on the AGV or because of * an instant action ('startPause' or 'stopPause'). * * @param paused new paused state * @param reportImmediately whether to publish a State message immediately * afterwards (optional, defaults to false) */ updatePausedState(paused: boolean, reportImmediately?: boolean): void; /** * To be invoked by the AGV adapter whenever a new base request should be * published. * * This is useful if the AGV is almost at the end of the base and needs to * reduce speed if no new base is transmitted. It acts as a trigger for * master control to send a new base to prevent unnecessary braking. * * @param newBaseRequest new newBaseRequest state * @param reportImmediately whether to publish a State message immediately * afterwards (optional, defaults to true) */ updateNewBaseRequest(newBaseRequest: boolean, reportImmediately?: boolean): void; /** * To be invoked by the AGV adapter whenever a new safety status is * available. * * @param safetyStatus new safety status * @param reportImmediately whether to publish a State message immediately * afterwards (optional, defaults to true) */ updateSafetyStatus(safetyStatus: SafetyStatus, reportImmediately?: boolean): void; /** * To be invoked by the AGV adapter whenever a new operation mode is * available. * * @param operatingMode new operating mode * @param reportImmediately whether to publish a State message immediately * afterwards (optional, defaults to true) */ updateOperatingMode(operatingMode: OperatingMode, reportImmediately?: boolean): void; /** * To be invoked by the AGV adapter whenever a new factsheet is * available. * * @param factsheet new factsheet */ updateFactsheet(factsheet: Headerless<Factsheet>): void; /** * To be invoked by the AGV adapter whenever an error should be added to * or removed from state. * * @param error an Error object * @param mode whether to add or remove the given error from state * @param reportImmediately whether to publish a State message immediately * afterwards (optional, defaults to false) */ updateErrors(error: Error, mode: "add" | "remove", reportImmediately?: boolean): void; /** * To be invoked by the AGV adapter whenever a new partial state is * available. * * @remarks * This function should only be used in case none of the other more specific * state update functions is applicable; e.g. to update an optional state * property such as `loads`, `distanceSinceLastNode`, `information`, etc. * * If the optional parameter `reportImmediately` is passed as `true`, a new * State message is published immediately after updating the state; * otherwise the message is published on the next periodic or immediate * state update. * * @param newState new partial state * @param reportImmediately whether to publish a State message immediately * afterwards (optional, defaults to false) */ updatePartialState(newState: Partial<Headerless<State>>, reportImmediately?: boolean): void; protected onStarted(): Promise<void>; protected onStopping(): Promise<void>; /** * Invoked whenever the current state of the AGV changes. * * @remarks To be extended by AgvController subclasses, for example to log * state changes. The base method does nothing. A deep copy of the changed * state can be retrieved within this method using the `currentState` * getter. * * @param changes partial state properties that have changed */ protected onStateChanged(changes: Partial<Headerless<State>>): void; /** * Invoked by this AGV controller to trigger execution of the given instant * action. * * The default implementation of this method just invokes the * `executeAction` handler function of the registered AGV adapter passing in * the given instant action context. * * @remarks This method provides an extension point for AGV controller * subclasses that want to perform additional side effects on the controller * side before executing the given instant action. * * @param context the action context of the instant action */ protected executeInstantAction(context: ActionContext): void; private _controllerOptionsWithDefaults; private _attachAdapter; private _detachAdapter; private _subscribeOnStarted; private _resetPublishStateTimer; private _setupPublishVisualizationInterval; private _publishVisualization; private _publishCurrentState; private _publishFactsheet; private _updateState; private _mergeState; private _cloneState; private _isV3; /** * Transforms the internal V2.1 state shape to V3.0 state shape for publishing. * * Maps: * - `batteryState` → `powerSupply` (batteryCharge → stateOfCharge, reach → range) * - `safetyState.eStop` → `safetyState.activeEmergencyStop` * - `agvPosition` → `mobileRobotPosition` (positionInitialized → localized) * - adds `instantActionStates` (required in V3.0) */ private _transformStateForV3; /** * Transforms the internal V2.1 visualization shape to V3.0 for publishing. * * Maps `agvPosition` → `mobileRobotPosition`. */ private _transformVisualizationForV3; private _findErrorIndex; private _areErrorReferencesEqual; /** * Process order according to VDA 5050 specification. * * @param order an incoming order */ private _processOrder; private _validateOrderConstraints; /** * Determines whether the start of the given order's new base is the end of * the current order's base. * * @param order a stitching order * @returns true, if the stitching order is valid; false otherwise */ private _isOrderBaseStitching; /** * Determines whether the start of the given order update base is matching * the lastNode and lastNodeSequenceId of the current state. * * @param order an order update * @returns true, if the order update is valid; false otherwise */ private _isOrderUpdateBaseStitching; private _acceptOrder; private _rejectOrder; /** * Cancel the currently active order. * * Used in the event of an unplanned change in the base nodes, the order * must be canceled by the master control using the instant action * 'cancelOrder'. * * AGV stops as soon as possible. This could be immediately or on the next * node depending on the AGV's capabilities. Then the order is deleted. All * scheduled actions are canceled. * * @param context context information of the instant action 'cancelOrder' */ private _cancelOrder; private _areAllOrderActionsCanceled; /** * As soon as all cancelable and non-cancelable actions have been ended, * continue order cancelation process by stopping AGV immediately or on next * node, depending on its capabilities. */ private _onOrderActionsCanceled; private _checkRouteTraversable; private _checkOrderActionsExecutable; private _checkNodeWithinDeviationRange; private _getNodeStates; private _getEdgeStates; private _getActionStates; private _getInstantActionStates; private _getNonOrderRejectionErrors; private _cleanupInstantActionStates; private _getEdgeStartNode; private _getEdgeEndNode; private _getTrailingEdge; private _processNode; private _processEdge; private _traverseEdge; private _updateEdgeTraversed; private _isActionEnded; /** * Returns the next HARD blocking action after the given action or * `undefined` if such a one doesn't exist. * * @param actions an array of Action objects * @param action a NONE or SOFT blocking action */ private _getHardBlockingActionAfterParallelActions; /** * Determines whether all NONE and/or SOFT blocking actions which have been * executed in parallel with the given ended action have also been * ended, i.e. are in action status FINISHED or FAILED. */ private _areParallelActionsEnded; private _updateActionStatus; /** * Execute remaining NONE or SOFT blocking actions up to next HARD blocking * action in parallel. * * Actions that are triggered on nodes can run as long as they need to run. * Actions on nodes should be self-terminating (e.g. an audio signal that * lasts for five seconds, or a pick action that is finished after picking * up a load) or should be formulated pairwise (e.g. activateWarningLights * and deactivateWarningLights), although there may be exceptions. * * Node actions are processed as follows: if at least one action with * blocking type SOFT or HARD exists the AGV stops driving, otherwise it * continues driving if not currently being stopped by other means. Then, * all NONE or SOFT blocking actions are executed in parallel, up to the * next HARD blocking action in the list. Once all the actions have * transitioned into status FINISHED or FAILED the following HARD blocking * action is executed. Once it has transitioned into status FINISHED or * FAILED iteration on node actions continues up to the next HARD blocking * action. If no (more) HARD blocking action exist all executing SOFT * blocking actions must have transitioned into status FINISHED or FAILED * before order processing can continue. * * @param node a Node * @param afterAction only process actions after this one (optional) */ private _processNodeActions; private _processNodeAction; private _processEdgeActions; private _processEdgeAction; /** * Edge actions that are not in status FINISHED or FAILED must be * explicitely terminated when the edge end node is traversed. * * @remarks An action triggered by an edge will only be active for the time * that the AGV is traversing the edge which triggered the action. When the * AGV leaves the edge, the action will stop and the state before entering * the edge will be restored. * * @param edge an edge to be left when end node is traversed */ private _finishEdgeActions; private _processInstantActions; private _processInstantActionChunk; private _processInstantAction; /** * Check whether the given instant action is executable. * * @remarks An instant action that is not executable (e.g. no load at * expected position) must be rejected with an error; the action must not be * reported as failed. * * @param action an instant action * @returns `true` if action is executable; `false` otherwise */ private _checkInstantActionExecutable; private _createOrderError; private _createActionError; private _createInstantActionsValidationError; }