cram_language Documentation

cram_language: The CRAM plan language.

The CRAM plan language is the core of the CRAM framework. It provides the basic functionality to write flexible and robust robot control programs.

  • Homepage:
  • The cram-language is a set of macros and functions on top of Common Lisp. It is a re-implementation of Drew McDermott's RPL on a modern Common Lisp compiler (sbcl), heavily utilizing operating system threads. The cram-language provides special language forms to easily create threads, synchronize on them and suspend them and provides clear exception semantics even across multiple threads.

    This document contains the API documentation for the high-level language forms, extracted from the common lisp doc strings. The ROS wiki documents concepts and provides a tutorial.

    Code API

    Forms for defining plans.

    — Macro: def-plan name lambda-list &rest body
    Defines a plan. All functions that should appear in the task-tree must be defined with def-plan.

    — Macro: def-top-level-plan name args &body body
    Defines a top-level plan. Every top-level plan has its own episode-knowledge and task-tree.

    — Macro: def-goal (name &rest pattern) &body body
    Defines a new goal. Goals always have the form
    (<name> [pattern]*)
    where patterns can be arbitrary expressions containing variables (indicated by a ?-prefix) and symbols. Example: (achieve (loc ?obj ?location)) When defining goals with similar expressions (e.g. (loc Robot ?l) and (loc ?a ?b)) the most specific expression must be defined first. Otherwise, the previously defined expression will be overwritten.

    Failure Handling

    — Function: fail &rest args
    Like the common lisp function error but throws a simple-plan-error per default.

    — Macro: with-failure-handling clauses &body body
    Macro that replaces handler-case in cram-language. This is necessary because error handling does not work across multiple threads. When an error is signaled, it is put into an envelope to avoid invocation of the debugger multiple times. When handling errors, this envelope must also be taken into account.
    We also need a mechanism to retry since errors can be caused by plan execution and the environment is highly non-deterministic. Therefore, it is possible to use the function `retry' that is lexically bound within with-failure-handling and causes a re-execution of the body.
    When an error is unhandled, it is passed up to the next failure handling form (exactly like handler-bind). Errors are handled by invoking the retry function or by doing a non-local exit. Note that with-failure-handling implicitly creates an unnamed block, i.e. `return' can be used.

    Control Flow

    — Macro: top-level &body body
    Creates a new task, executes body in it and waits until it is finished. All plan macros can only be used within the dynamic scope of a top-level form.

    — Macro: seq &body forms
    Executes forms sequentially. Fails if one fail. Succeeds if all succeed.

    — Macro: par &body forms
    Executes forms in parallel. Fails if one fails. Succeeds if all succeed.

    — Macro: pursue &body forms
    Execute forms in parallel. Succeed if one succeeds, fail if one fails.

    — Macro: try-all &body forms
    Try forms in parallel. Succeed if one succeeds, fail if all fail. In the case of a failure, a condition of type 'composite-failure' is signaled, containing the list of all error messages and data.

    — Macro: try-in-order &body forms
    Execute forms sequentially. Succeed if one succeeds, fail if all fail. In case of failure, a composite-failure is signaled.

    — Macro: with-tags &body body &environment lexenv
    Execute body with all tags bound to the corresponding lexically bound variables.

    — Macro: partial-order (&body steps) &body orderings
    Specify ordering constraints for `steps'. `steps' are executed in an implicit par form. `orderings' is a list of orderings. An ordering always has the form:
                (:order <contstraining-task> <constrained-task>)
    `constraining-task' and `constrained-task' are task objects. That means, they can be either be defined in the current lexical environment (over a :tag) or by either using the function task to reference the task by its absolute path or the function sub-task to reference it by its path relative to the partial-order form.

    — Macro: with-task-suspended task &body body
    Execute body with 'task' being suspended.


    — Function: make-fluent &rest args &key name &allow-other-keys
    Construct a fluent.

    — Generic Function: wait-for fluent &key timeout value-changed wait-status handle-missed-pulses
    Method to block the current thread until the value of `fluent' becomes non-nil. When it is already true and `value-changed' is nil, wait-for imediately returns. Otherwise it waits for at least timeout. The parameter `wait-status' indicates the status of the task when it is waiting. The parameter `handle-missed-pulses' can be either :never :once or :always:

    The handling of missed pulses is performed on a per-thread basis.

    — Macro: whenever (condition-fluent &key wait-status handle-missed-pulses) &body body
    Executes `body' whenever `condition-fluent' is pulsed or non-nil. The `body' forms are executed in an implicit block named whenever. The parameters `wait-status' and `handle-missed-pulses' have the same meaning as in wait-for

    — Generic Function: pulse fluent
    Method to trigger the fluent, i.e. notifying all waiting threads, but without actually changing the fluent value.

    Fluent Networks

    Fluents can be combined to fluent networks. The standard comparison operators <, >, =, eq, eql, +, -, * and / are redefined to return a fluent network whenever they are called with at least one fluent as a parameter. In addition, the following special fluent operators are defined.

    — Function: fl-and &rest fl-args393
    The and-operator for fluents. It is fundamentally different to the definition of common-lisp's and in that it is not implemented as a macro. That means, all args are evaluated when using fl-and.

    — Function: fl-funcall &rest fl-args454
    Generic fluent-operator. Applys args to function whenever a fluent in args changes.

    — Function: fl-or &rest fl-args413
    The or-operator for fluents. For more information on why it is a function please refere to the documentation of fl-and.

    — Function: fl-pulsed &rest fl-args434
    Returns true and is invoked whenever one of its argument fluents gets pulsed.

    Protection forms.

    — Macro: suspend-protect form &body protection-forms
    When the current task is suspended during the execution of `form', execute `protection-forms' just before suspending.

    — Macro: without-suspension &body body
    Execution of `body' cannot be interrupted by a suspension. If a suspension

    — Macro: with-suspension &body body
    Explicitly allows suspension. To be used within the dynamic context of without-suspension.

    — Macro: on-suspension when-suspended-form &body body
    Executes `when-suspended-form' whenever a suspension signal occurs while `form' is being executed.
     All Files

    Author(s): Lorenz Moesenlechner
    autogenerated on Fri Jan 11 10:05:19 2013