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.

Hierarchy

Constructors

Properties

agvId: AgvId

the identity of the AGV this controller represents

clientId: string

Gets the client's unique client ID to be used for logging purposes, etc.

currentOrder: Order

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.

debug: Debugger

Gets a debugger function associated with this client instance.

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).

To turn on debug output for this library, set the DEBUG environment variable to vda-5050:*. To enable low-level MQTT debugging, use vda-5050:*,mqttjs*. Use * to debug all debug-enabled modules in your application.

REF_KEY_ERROR_DESCRIPTION_DETAIL: "errorDescriptionDetail" = "errorDescriptionDetail"

Special error reference key used to append detail information to an Error.errorDescription.

Accessors

  • get adapterApiVersion(): number
  • 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.

    Returns number

  • get currentState(): Headerless<State>
  • 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

    Returns Headerless<State>

  • get hasActiveOrder(): boolean
  • 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.

    Returns boolean

  • get hasCancelingOrder(): boolean
  • Indicates whether the AGV controller is currently canceling the active order.

    Returns boolean

  • get isStarted(): boolean
  • Determines whether the client has been started.

    Returns

    true if client has been started; false otherwise

    Returns boolean

  • get protocolVersion(): VdaVersion
  • Gets the semantic version of the VDA 5050 protocol this implementation conforms to.

    Returns

    a string in the format "<major-version-number>.<minor-version-number>.<patch-version-number>"

    Returns VdaVersion

Methods

  • Create a new Version 4 UUID to be used as a unique identifier for nodes, edges, actions, etc.

    Returns

    a unique Version 4 UUID

    Returns string

  • 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.

    Parameters

    • context: ActionContext

      the action context of the instant action

    Returns void

  • Gets the semantic version of the VDA 5050 protocol this implementation conforms to.

    To be overridden by subclasses that provide VDA 5050 extensions. The default version returned by the base method is the standard VDA 5050 protocol version this Client class implements.

    Returns

    a string in the format "<major-version-number>.<minor-version-number>.<patch-version-number>"

    Returns VdaVersion

  • Determines whether the given action state represents an instant action.

    Returns

    true if action state represents an instant action; false otherwise

    Parameters

    Returns boolean

  • 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.

    Parameters

    • changes: Partial<Headerless<State>>

      partial state properties that have changed

    Returns void

  • Publishes the given VDA 5050 core or extension object on the given VDA 5050 communication topic.

    On successful publication, this async function resolves a promise containing a copy of the given headerless object including all header properties as it has been published. If the publication is dropped according to the dropIfOffline publish option, the promise resolves with an undefined value.

    Returns

    a promise that resolves the published object if publication succeeds or undefined if message should be dropped while offline

    Throws

    synchronously if client is not started, if topic is not valid, if object validation fails

    Type Parameters

    • T extends string

    Parameters

    • topic: T extends Topic ? T : string

      the VDA 5050 communication topic to publish on

    • object: Headerless<TopicObject<T>>

      a VDA 5050 core or extension object without header properties

    • Optional options: ClientPublishOptions

      client publish options (optional)

    Returns Promise<TopicObject<T>>

  • Publishes the given VDA 5050 core or extension object on the given VDA 5050 communication topic related to the given AGV subject.

    The AgvId subject is used to automatically fill in header properties of the object to be published. Each of its properties must specify a non-empty string and must be valid as an MQTT topic level.

    On successful publication, this async function resolves a promise containing a copy of the given headerless object including all header properties as it has been published. If the publication is dropped according to the dropIfOffline publish option, the promise resolves with an undefined value.

    Returns

    a promise that resolves the published object if publication succeeds or undefined if message should be dropped while offline

    Throws

    synchronously if client is not started, if topic or subject is not valid, if object validation fails

    Type Parameters

    • T extends string

    Parameters

    • topic: T extends Topic ? T : string

      the VDA 5050 communication topic to publish on

    • subject: AgvId

      identity of the AGV which is related to this publication

    • object: Headerless<TopicObject<T>>

      a VDA 5050 core or extension object without header properties

    • Optional options: ClientPublishOptions

      client publish options (optional)

    Returns Promise<TopicObject<T>>

  • Registers a custom VDA 5050 communication topic with a validator function to check structure and constraints of corresponding extension objects at runtime.

    The asInbound and asOutbound parameters indicate whether the registered extension topic should be allowed for inbound communication and/or outbound communication. If inbound communication is not allowed, subscribing to the topic will fail. Likewise, if outbound communication is not allowed, publishing on the topic will fail.

    The validator function is invoked on inbound and/or outbound messages with a registered extension topic according to the client option topicObjectValidation.

    The validator function should throw a TypeError synchronously if the passed extension object structure does not conform to the passed extension topic and the direction of the message (inbound, outbound).

    Remarks

    If the given topic is already registered, its registration will be overridden with the new parameters.

    Use the function createValidators in the create-validators script provided by this package to generate JS validation functions for your custom JSON schemas. Use these functions in this method override.

    Parameters

    • extensionTopic: string

      a custom VDA 5050 communication topic

    • asInbound: boolean

      whether topic should be allowed on inbound communication

    • asOutbound: boolean

      whether topic should be allowed on outbound communication

    • validator: ExtensionValidator

      a function that validates message objects against the given extension topic

    Returns void

  • Invoked after client is stopped to reset internal client state.

    To be extended by subclasses. Ensure to call super.reset() in your override.

    Returns void

  • Starts client interaction by connecting to the configured MQTT broker.

    If client is already started, this operation is a noop.

    Remarks

    Always await this operation before invoking other operations on this client instance.

    Returns

    a promise resolved when client is initially connected, and rejected when connection fails

    Returns Promise<void>

  • Stops client interaction by disconnecting from the MQTT broker and cleaning up all active subscriptions and registered extension topics.

    If client is not started, this operation is a noop.

    Remarks

    Always await this operation before invoking other operations on this client instance, such as start.

    After the client is stopped any publish, subscribe, and unsubscribe operations will throw an error until the client is restarted.

    Returns

    a promise resolved when client is disconnected from the underlying MQTT transport.

    Returns Promise<void>

  • Subscribes to the given VDA 5050 communication topic and registers a handler function to be invoked when matching inbound publication messages are received by this client.

    Remarks

    If multiple subscription handlers are registered for a given subscription, they are invoked synchronously in series, one after the other, but in arbitrary order.

    A subscription handler should never perform long-lasting synchronous operations as it blocks processing of other handlers and incoming messages.

    A subscription handler may also perform asynchronous operations but these are are not awaited and not synchronized with the invocation of other handlers.

    A subscription handler is responsible for catching any errors. Uncaught errors result in "Uncaught Error" or "Unhandled Promise Rejection" reported by the runtime.

    Take care to invoke Client.unsubscribe method on any subscription ID that is no longer needed by the application to clean up the subscription's handler function and to reduce network traffic. Unsubscribing in a handler function is also possible; use the corresponding subscription id passed as argument. If you want to keep a subscription for the lifetime of the client, there is no need to explicitely unsubscribe it before stopping the client.

    Returns

    a promise that resolves a unique subscription ID when subscription is set up successfully

    Throws

    synchronously if client is not started, if topic or subject is not valid

    Type Parameters

    • T extends string

    Parameters

    • topic: T extends Topic ? T : string

      the VDA 5050 communication topic to subscribe to

    • handler: SubscriptionHandler<T>

      a function invoked on any inbound message matching the subscription

    Returns Promise<string>

  • Subscribes to the given VDA 5050 communication topic for the given AGV subject and registers a handler function to be invoked when matching inbound publication messages are received by this client.

    In the given partial AgvId subject, any property must either specify a non-empty string which is valid as an MQTT topic level or be undefined or excluded, to support wildcard subscriptions by control clients. Otherwise, an error is thrown.

    Remarks

    If multiple subscription handlers are registered for a given subscription, they are invoked synchronously in series, one after the other, but in arbitrary order.

    A subscription handler should never perform long-lasting synchronous operations as it blocks processing of other handlers and incoming messages.

    A subscription handler may also perform asynchronous operations but these are are not awaited and not synchronized with the invocation of other handlers.

    A subscription handler is responsible for catching any errors. Uncaught errors result in "Uncaught Error" or "Unhandled Promise Rejection" reported by the runtime.

    Take care to invoke Client.unsubscribe method on any subscription ID that is no longer needed by the application to clean up the subscription's handler function and to reduce network traffic. Unsubscribing in a handler function is also possible; use the corresponding subscription id passed as argument. If you want to keep a subscription for the lifetime of the client, there is no need to explicitely unsubscribe it before stopping the client.

    Returns

    a promise that resolves a unique subscription ID when subscription is set up successfully

    Throws

    synchronously if client is not started, if topic or subject is not valid

    Type Parameters

    • T extends string

    Parameters

    • topic: T extends Topic ? T : string

      the VDA 5050 communication topic to subscribe to

    • subject: Partial<AgvId>

      identity of the AGV(s) which are related to this subscription

    • handler: SubscriptionHandler<T>

      a function invoked on any inbound message matching the subscription

    Returns Promise<string>

  • Unsubscribes the subscription issued for the given subscription ID.

    The subscription's handler function will be cleaned up and no longer invoked. If there are no other active subscriptions on the associated VDA 5050 topic, the corresponding MQTT topic will also be unsubscribed to prevent unnecessary network traffic.

    If the given subscription ID is already unsubscribed, it is silently ignored.

    Returns

    a promise that resolves on successful unsubscription

    Throws

    synchronously if client is not started

    Parameters

    • subscriptionId: string

      the subscription ID related to an issued subscription

    Returns Promise<void>

  • 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.

    Parameters

    • Optional agvPosition: AgvPosition

      new AGV position (optional)

    • Optional velocity: Velocity

      new velocity (optional)

    • reportImmediately: boolean = false

      whether to publish a State message immediately afterwards (optional, defaults to false)

    Returns void

  • To be invoked by the AGV adapter whenever a new battery state is available.

    Parameters

    • batteryState: BatteryState

      new battery state

    • reportImmediately: boolean = false

      whether to publish a State message immediately afterwards (optional, defaults to false)

    Returns 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.

    Parameters

    • driving: boolean

      new driving state

    • reportImmediately: boolean = false

      whether to publish a State message immediately afterwards (optional, defaults to false)

    Returns void

  • To be invoked by the AGV adapter whenever an error should be added to or removed from state.

    Parameters

    • error: Error

      an Error object

    • mode: "add" | "remove"

      whether to add or remove the given error from state

    • reportImmediately: boolean = false

      whether to publish a State message immediately afterwards (optional, defaults to false)

    Returns 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.

    Parameters

    • newBaseRequest: boolean

      new newBaseRequest state

    • reportImmediately: boolean = true

      whether to publish a State message immediately afterwards (optional, defaults to true)

    Returns void

  • To be invoked by the AGV adapter whenever a new operation mode is available.

    Parameters

    • operatingMode: OperatingMode

      new operating mode

    • reportImmediately: boolean = true

      whether to publish a State message immediately afterwards (optional, defaults to true)

    Returns 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.

    Parameters

    • newState: Partial<Headerless<State>>

      new partial state

    • reportImmediately: boolean = false

      whether to publish a State message immediately afterwards (optional, defaults to false)

    Returns 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').

    Parameters

    • paused: boolean

      new paused state

    • reportImmediately: boolean = false

      whether to publish a State message immediately afterwards (optional, defaults to false)

    Returns void

  • To be invoked by the AGV adapter whenever a new safety status is available.

    Parameters

    • safetyStatus: SafetyStatus

      new safety status

    • reportImmediately: boolean = true

      whether to publish a State message immediately afterwards (optional, defaults to true)

    Returns void

  • Performs a runtime validation check of the given AGV identity to be used as subject of a subscription or publication.

    For publications, all AgvId properties must be specified and valid. For subscriptions, any property may be omitted, but existing properties must have valid values.

    Throws

    a TypeError if validation check fails

    Parameters

    • agvId: Partial<AgvId>

      (partial) identity of AGV

    • forSubscription: boolean

      whether to validate as a subscription or publication subject

    Returns void

  • Validate standard VDA 5050 topics at runtime with respect to the direction of information exchange. An AGV client can only publish on certain topics and only subscribe to certain topics.

    Parameters

    • topic: Topic
    • asInbound: boolean

    Returns void

  • Performs a runtime validation check of a VDA 5050 core or extension object with respect to a given VDA 5050 topic.

    Throws

    a TypeError if validation check fails

    Parameters

    • topic: string

      a VDA 5050 communication topic

    • object: Vda5050Object

      a VDA 5050 core or extension object with header properties

    • vdaVersion: VdaVersion

    Returns void

Generated using TypeDoc