Differences
This shows you the differences between two versions of the page.
Both sides previous revisionPrevious revision | |||
doc:beginner:designators [2014/10/30 12:10] – Tutorial code now placed in several files, for clarity. mpomarlan | doc:beginner:designators [2015/05/11 17:00] (current) – removed gkazhoya | ||
---|---|---|---|
Line 1: | Line 1: | ||
- | ====== Creating action designators for the turtlesim ====== | ||
- | **Description: | ||
- | |||
- | **Previous Tutorial:** [[doc: | ||
- | **Next Tutorial:** [[doc: | ||
- | |||
- | ===== Designators: | ||
- | |||
- | From a user's point of view, a designator is a Common Lisp object that contains a sequence of key-value pairs representing a high-level, symbolic description of some aspect of a robot' | ||
- | |||
- | Currently there are three types of designators defined in CRAM: | ||
- | |||
- | * location designators: | ||
- | * object designators: | ||
- | * action designators: | ||
- | |||
- | These types should cover most use cases in robotics, however, if needed, new designator types can be defined as subclasses of the designator class. | ||
- | |||
- | As a simple example of a designator creation, suppose we want to create a designator for a location from which some object (for which we already have a designator) can be seen. We would then write | ||
- | |||
- | <code lisp> | ||
- | (defparameter spy-location (make-designator ' | ||
- | </ | ||
- | |||
- | (do not add this code to your tutorial files, it is meant simply for illustration here.) | ||
- | |||
- | This line of code creates a location designator (spy-location) which ' | ||
- | |||
- | <code lisp> | ||
- | (reference spy-location) | ||
- | </ | ||
- | |||
- | and, assuming we have set up rules to take into account knowledge of the associated object, the environment, | ||
- | |||
- | For the rest of this tutorial, we will work with action designators and show a few basics of their creation and use. For a more detailed look at designators, | ||
- | |||
- | |||
- | ===== Using action designators ===== | ||
- | |||
- | First, you will need to add a few more dependencies to the tutorial package files you created previously. To package.xml, | ||
- | |||
- | < | ||
- | < | ||
- | < | ||
- | |||
- | < | ||
- | < | ||
- | </ | ||
- | |||
- | In your cram-beginner-tutorial.asd file, on the :depends-on line, add dependencies to designators and cram-reasoning. Let's also create a new source file for the code in this tutorial, call it action-designators.lisp, | ||
- | |||
- | <code lisp> | ||
- | (defsystem cram-beginner-tutorial | ||
- | :depends-on (roslisp cram-language turtlesim-msg cl-transforms geometry_msgs-msg designators cram-reasoning) | ||
- | :components | ||
- | ((:module " | ||
- | :components | ||
- | ((:file " | ||
- | | ||
- | | ||
- | | ||
- | </ | ||
- | |||
- | Finally, package.lisp needs to undergo some more drastic changes: | ||
- | |||
- | <code lisp> | ||
- | (desig-props: | ||
- | (:nicknames :tut) | ||
- | (:use #:cpl | ||
- | #:roslisp | ||
- | #: | ||
- | #: | ||
- | ) | ||
- | |||
- | (: | ||
- | ;;;action properties | ||
- | #:shape | ||
- | #:radius | ||
- | #:triangle | ||
- | #:square | ||
- | #:pentagon | ||
- | #:hexagon | ||
- | )) | ||
- | </ | ||
- | |||
- | The first lines look familiar enough, but we added the cram-designators namespace to the use list, for convenience. Also, we replaced the defpackage macro on the first line with desig-properties: | ||
- | |||
- | Now, reload the tutorial in roslisp_repl (which also loads the newly added dependencies). | ||
- | |||
- | ==== Creating an action designator ==== | ||
- | |||
- | Let's try to create an action designator in the repl command line: | ||
- | |||
- | <code lisp> | ||
- | TUT> (defparameter mydesig (make-designator ' | ||
- | MYDESIG | ||
- | TUT> (desig-prop-value mydesig ' | ||
- | 3 | ||
- | </ | ||
- | |||
- | As we can see, the make-designator function simply returns a designator object with the properties we specify. We can also read those already specified property values with the desig-prop-value function. So far, so good, but the interesting thing about designators is their resolution. Let's try that in the repl command line: | ||
- | |||
- | <code lisp> | ||
- | TUT> (reference mydesig) | ||
- | WARNING: | ||
- | | ||
- | #< | ||
- | | ||
- | | ||
- | ?ACT) with undefined functor ACTION-DESIG. | ||
- | ; Evaluation aborted on #< | ||
- | </ | ||
- | |||
- | This rather obscure error message is roslisp_repl' | ||
- | |||
- | ==== Defining inference rules for designators ==== | ||
- | |||
- | Append the following to your action-designators.lisp file: | ||
- | |||
- | <code lisp> | ||
- | (in-package :tut) | ||
- | |||
- | (defstruct turtle-shape | ||
- | " | ||
- | radius | ||
- | edges) | ||
- | | ||
- | (cram-reasoning: | ||
- | ;; for each kind of shape, call make-turtle-shape with the right number of edges | ||
- | |||
- | ;; triangle | ||
- | (cram-reasoning:< | ||
- | (desig-prop ?desig (type shape)) | ||
- | (desig-prop ?desig (shape triangle)) | ||
- | (desig-prop ?desig (radius ?radius)) | ||
- | (cram-reasoning: | ||
- | |||
- | ;; square | ||
- | (cram-reasoning:< | ||
- | (desig-prop ?desig (type shape)) | ||
- | (desig-prop ?desig (shape square)) | ||
- | (desig-prop ?desig (radius ?radius)) | ||
- | (cram-reasoning: | ||
- | |||
- | ;; pentagon | ||
- | (cram-reasoning:< | ||
- | (desig-prop ?desig (type shape)) | ||
- | (desig-prop ?desig (shape pentagon)) | ||
- | (desig-prop ?desig (radius ?radius)) | ||
- | (cram-reasoning: | ||
- | |||
- | ;; hexagon | ||
- | (cram-reasoning:< | ||
- | (desig-prop ?desig (type shape)) | ||
- | (desig-prop ?desig (shape hexagon)) | ||
- | (desig-prop ?desig (radius ?radius)) | ||
- | (cram-reasoning: | ||
- | </ | ||
- | |||
- | Let's see what this code does. The defstruct declares a struct type to hold values resulting from the inference. It's an instantiation of our action in a space of (possibly) continuous parameters, which we deduce from a symbolic description of the designator via rules given in the def-fact-group. | ||
- | |||
- | As for the inference rules themselves, these are PROLOG code embedded in Lisp, for it is PROLOG that powers the inference behind designator resolution. The def-fact-group is a collection of several rules, each of similar structure, so it helps to look at one of them in more detail: | ||
- | |||
- | <code lisp> | ||
- | (cram-reasoning:< | ||
- | (desig-prop ?desig (type shape)) | ||
- | (desig-prop ?desig (shape pentagon)) | ||
- | (desig-prop ?desig (radius ?radius)) | ||
- | (cram-reasoning: | ||
- | </ | ||
- | |||
- | The first parameter to cram-reasoning:< | ||
- | |||
- | <code lisp> | ||
- | (action-desig ?desig (shape ?action)) | ||
- | </ | ||
- | |||
- | while all other parameters comprise the "rule body" | ||
- | |||
- | <code lisp> | ||
- | (desig-prop ?desig (type shape)) | ||
- | (desig-prop ?desig (shape pentagon)) | ||
- | (desig-prop ?desig (radius ?radius)) | ||
- | (cram-reasoning: | ||
- | </ | ||
- | |||
- | PROLOG' | ||
- | |||
- | For this example rule we've selected, PROLOG looks at the designator and asks "does it contain a key-value pair that is (type shape)?" | ||
- | |||
- | If all of the above body rules are true (or can be executed sucessfully) then the head is itself run, and what it does is glue the newly created ?action, the object containing the concrete values, to the designator ?desig. Or in more concrete terms, it defines what the value of the action-desig predicate is if applied to ?desig, and that value is a list containing the name ' | ||
- | |||
- | For this tutorial, the inference is very simple: in fact, it is just a conditional switch based on the shape parameter which translates a name like ' | ||
- | |||
- | Reload the tutorial package in roslisp_repl. This will also load the newly defined inference rules. | ||
- | |||
- | Let's try to create, then reference a designator in the repl command line again: | ||
- | |||
- | <code lisp> | ||
- | TUT> (defparameter mydesig2 (make-designator ' | ||
- | MYDESIG | ||
- | TUT> (reference mydesig2) | ||
- | (SHAPE # | ||
- | </ | ||
- | |||
- | No more resolution errors this time, as we have specified inference rules which allow us to have a shape object returned, which we could then pass as a parameter to a process module that will actually move the turtle along this shape. | ||
- | |||
- | |||
- | == Next == | ||
- | |||
- | |||
- | Now that we know how to handle designators, | ||
- | |||
- | [[doc: |