Differences
This shows you the differences between two versions of the page.
Both sides previous revisionPrevious revisionNext revision | Previous revision | ||
reasoning_about_objects [2012/12/01 11:01] – [Read object component hierarchy] tenorth | reasoning_about_objects [2014/06/05 11:38] (current) – external edit 127.0.0.1 | ||
---|---|---|---|
Line 1: | Line 1: | ||
- | ====== Reasoning about objects ====== | + | #REDIRECT doc:reasoning_about_objects |
- | + | ||
- | Before starting this tutorial, you should have completed the following ones: | + | |
- | * [[Tutorial: KnowRob basics]] | + | |
- | * [[Loading files and ROS packages]] | + | |
- | + | ||
- | ===== Load environment specification ===== | + | |
- | We have split the description of the semantic environment map from the set of (smaller) objects in the environment. In realistic applications, | + | |
- | < | + | |
- | roscd knowrob_tutorial | + | |
- | | + | |
- | | + | |
- | </ | + | |
- | If you need to create or edit a semantic map, you can either use the graphical [[Mod_semantic_map#SemanticMapEditor|Semantic Map editor]] or the [[Mod_semantic_map# | + | |
- | + | ||
- | ===== Load CAD model definition for objects ===== | + | |
- | + | ||
- | Some of the objects in the demo set have CAD models attached. They are used for visualization as well as for reasoning (see below). These models are automatically used when they are specified for either a complete class of objects (using an OWL hasValue restriction) or for an object instance as shown below: | + | |
- | < | + | |
- | < | + | |
- | < | + | |
- | < | + | |
- | < | + | |
- | < | + | |
- | < | + | |
- | | + | |
- | </ | + | |
- | </ | + | |
- | + | ||
- | The %%package:// | + | |
- | + | ||
- | ===== Visualize environment including object CAD models ===== | + | |
- | + | ||
- | {{ : | + | |
- | + | ||
- | Once the respective CAD model definitions are loaded, they are automatically used for visualizing object instances instead of the default primitive models (boxes, cylinders etc). You should see a map including CAD models such as the following when calling: | + | |
- | < | + | |
- | | + | |
- | </ | + | |
- | Similarly, we can also visualize small objects in the kitchen: | + | |
- | < | + | |
- | | + | |
- | owl_individual_of(A, | + | |
- | | + | |
- | | + | |
- | </ | + | |
- | ===== Query for objects with certain properties ===== | + | |
- | + | ||
- | Since all objects in the map are instances of the respective object classes, one can query for objects that have certain properties or belong to a certain class, for example: | + | |
- | < | + | |
- | % perishable objects: | + | |
- | ?- owl_individual_of(A, | + | |
- | A = ' | + | |
- | A = ' | + | |
- | A = ' | + | |
- | A = ' | + | |
- | A = ' | + | |
- | A = ' | + | |
- | + | ||
- | % all HandTools (e.g. silverware) | + | |
- | ?- owl_individual_of(A, | + | |
- | A = ' | + | |
- | A = ' | + | |
- | + | ||
- | % all FoodVessels (i.e. pieces of tableware) | + | |
- | ?- owl_individual_of(A, | + | |
- | A = ' | + | |
- | A = ' | + | |
- | A = ' | + | |
- | + | ||
- | % everything with a handle: | + | |
- | ?- owl_has(A, knowrob: | + | |
- | A = ' | + | |
- | H = ' | + | |
- | </ | + | |
- | + | ||
- | ===== Infer likely storage locations ===== | + | |
- | + | ||
- | Apart from the current environment setup, robots sometimes need to reason about the nominal locations of objects, for example when cleaning up or when unpacking a shopping basket. There are different techniques for inferring the location where an object should be placed. | + | |
- | + | ||
- | * Using assertions of the [https:// | + | |
- | * A finer-grained solution is based on [https:// | + | |
- | + | ||
- | === Query for likely storage location === | + | |
- | + | ||
- | The simple option based on the storagePlaceFor predicate can be queried as follows in order to determine where an object (instance or class) shall be stored, or which known objects are to be stored in a given container: | + | |
- | < | + | |
- | ?- storagePlaceFor(Place, | + | |
- | Place = ' | + | |
- | + | ||
- | ?- storagePlaceFor(knowrob:' | + | |
- | Obj = ' | + | |
- | Obj = ' | + | |
- | Obj = ' | + | |
- | Obj = ' | + | |
- | | + | |
- | </ | + | |
- | + | ||
- | An extension of the storagePlaceFor predicate also reads why the system came to the conclusion that something is to be stored at some place: | + | |
- | < | + | |
- | ?- storagePlaceForBecause(Place, | + | |
- | Place = ' | + | |
- | | + | |
- | </ | + | |
- | + | ||
- | TODO: add orgprinciples calls | + | |
- | + | ||
- | === Check for objects that are not at their storage location === | + | |
- | + | ||
- | By combining the semantic map, giving the current object locations, with the knowledge about the locations where objects should be, the robot can determine which objects are mis-placed. This may for instance be useful when tidying up an environment. | + | |
- | + | ||
- | The following code first compute which objects are inside which other ones, then selects those that are food or drink, computes their most likely storage place (which, in this example, is usually the refrigerator), | + | |
- | + | ||
- | < | + | |
- | ?- rdf_triple(knowrob:' | + | |
- | owl_individual_of(Obj, | + | |
- | storagePlaceFor(StoragePlace, | + | |
- | ActualPlace\=StoragePlace. | + | |
- | Obj = ' | + | |
- | | + | |
- | | + | |
- | Obj = ' | + | |
- | | + | |
- | | + | |
- | </ | + | |
- | + | ||
- | ===== Read object component hierarchy ===== | + | |
- | + | ||
- | Composed objects and their parts are linked by an inverse part-of hierarchy, described using the properPhysicalParts property in OWL. This property is transitive, i.e. a part of a part of an object is also a part of the object itself. You can read all parts and sub-parts of an object using owl_has, which takes the transitivity into account. In the example below, Handle160 is a part of Door70, which by itself is part of Refrigerator67. | + | |
- | < | + | |
- | ?- owl_has(knowrob:' | + | |
- | P = ' | + | |
- | P = ' | + | |
- | P = ' | + | |
- | </ | + | |
- | + | ||
- | === Special case: articulated objects like cupboards === | + | |
- | + | ||
- | {{ : | + | |
- | + | ||
- | Articulated objects like cupboards that have doors or drawers are represented in a special way to describe, on the one hand, the component hierarchy, and on the other hand the fixed and moving connections. Like for other composed objects, there is a part-of hierarchy (properPhysicalParts). Joints are parts of the cupboard/ | + | |
- | + | ||
- | + | ||
- | Joints are described using the following properties, which are compatible to the representation used by the [http:// | + | |
- | * Type: At the moment, rotational and prismatic joints are supported (knowrob:' | + | |
- | * Parent, Child: resp. object instances | + | |
- | * Pose: like for [[Modeling_perceived_or_inferred_objects|normal objects]] using e.g. a SemanticMapPerception instance | + | |
- | * Direction: vector giving the opening direction of a prismatic joint | + | |
- | * Radius: radius of a rotational joint (e.g. between handle and hinge) | + | |
- | * Qmin, Qmax: lower and upper joint limits | + | |
- | + | ||
- | + | ||
- | ===== Read articulation information ===== | + | |
- | + | ||
- | There are some convenience predicates for reading, creating, updating and deleting joints from articulated objects. This task is on the one hand rather common, on the other hand somewhat complex because the structure visualized in the previous image needs to be established. | + | |
- | + | ||
- | To create a joint of type knowrob:' | + | |
- | < | + | |
- | | + | |
- | | + | |
- | </ | + | |
- | + | ||
- | If a prismatic joint is to be created instead, the empty list [] needs to be replaced with a unit vector describing the joint' | + | |
- | + | ||
- | Joint information can conveniently be read using the following predicate that requires a joint instance as argument: | + | |
- | < | + | |
- | | + | |
- | </ | + | |
- | + | ||
- | To update joint information, | + | |
- | < | + | |
- | | + | |
- | </ | + | |
- | + | ||
- | ===== Read and convert units of measure ===== | + | |
- | + | ||
- | All numerical values can optionally be annotated with a unit of measure. To keep the system backwards compatible, other values are interpreted to be given in the respective SI unit (e.g. meter, second). | + | |
- | + | ||
- | Full article incl. explanation of design choices and links to further information: | + | |
- | < | + | |
- | $ roscd knowrob_common/ | + | |
- | $ rosrun rosprolog rosprolog ias_knowledge_base | + | |
- | + | ||
- | ?- owl_parse(' | + | |
- | ?- consult(' | + | |
- | + | ||
- | % read information that is asserted for a test instance | + | |
- | ?- rdf_has(' | + | |
- | ' | + | |
- | O = literal(type(' | + | |
- | + | ||
- | % manual conversion into other units | + | |
- | ?- convert_to_unit($O, | + | |
- | P = 0.00012. | + | |
- | + | ||
- | ?- convert_to_unit($O, | + | |
- | P = 0.12. | + | |
- | + | ||
- | ?- convert_to_unit($O, | + | |
- | P = 120.0. | + | |
- | </ | + | |
- | + | ||
- | The integration with the rdf_triple computables allows to transparently convert values into the desired unit of measure: | + | |
- | < | + | |
- | % transparent conversion during the query | + | |
- | ?- rdf_triple(' | + | |
- | ' | + | |
- | literal(type(' | + | |
- | Val = 0.12 ; | + | |
- | + | ||
- | ?- rdf_triple(' | + | |
- | ' | + | |
- | literal(type(' | + | |
- | Val = 0.00012 ; | + | |
- | </ | + | |
- | + | ||
- | + | ||
- | ===== Convert between relative and global coordinates ===== | + | |
- | see here for now: [[Coordinate_systems]] | + | |
- | + | ||
- | ===== Query for qualitative spatial relations ===== | + | |
- | + | ||
- | Using [[Tutorial: | + | |
- | + | ||
- | < | + | |
- | ?- rdf_triple(knowrob:' | + | |
- | C = ' | + | |
- | + | ||
- | ?- rdf_triple(knowrob:' | + | |
- | O = ' | + | |
- | O = ' | + | |
- | O = ' | + | |
- | + | ||
- | | + | |
- | A = ' | + | |
- | A = ' | + | |
- | </ | + |