Differences
This shows you the differences between two versions of the page.
Both sides previous revisionPrevious revisionNext revision | Previous revision | ||
doc:reasoning_about_objects [2014/11/28 14:56] – admin | doc:reasoning_about_objects [2016/04/19 08:11] (current) – [Visualize the environment, including CAD models of objects] daniel86 | ||
---|---|---|---|
Line 1: | Line 1: | ||
====== Reasoning about objects ====== | ====== Reasoning about objects ====== | ||
+ | ~~NOTOC~~ | ||
+ | \\ | ||
+ | ^ This page describes the ' | ||
+ | \\ | ||
Before starting this tutorial, you should have completed the following ones: | Before starting this tutorial, you should have completed the following ones: | ||
Line 10: | Line 14: | ||
With the following commands, you can launch KnowRob including the semantic map of our laboratory kitchen, and then load the OWL file containing a set of demo objects. You need to have the knowrob_tutorials repository in your catkin workspace. | With the following commands, you can launch KnowRob including the semantic map of our laboratory kitchen, and then load the OWL file containing a set of demo objects. You need to have the knowrob_tutorials repository in your catkin workspace. | ||
<code prolog> | <code prolog> | ||
- | rosrun rosprolog rosprolog knowrob_basics_tutorial | + | ?- rosrun rosprolog rosprolog knowrob_basics_tutorial |
- | | + | ?- owl_parse(' |
- | | + | ?- owl_parse(' |
</ | </ | ||
Line 21: | Line 25: | ||
Once the map and the example objects have been loaded, you can start the visualization canvas, [[http:// | Once the map and the example objects have been loaded, you can start the visualization canvas, [[http:// | ||
+ | |||
+ | Please make sure that you have launched the ' | ||
+ | <code bash> | ||
+ | roslaunch rosbridge_server rosbridge_websocket.launch | ||
+ | </ | ||
+ | |||
+ | |||
+ | You can then send the following commands from your KnowRob shell: | ||
<code prolog> | <code prolog> | ||
- | ?- visualisation_canvas. | + | ?- visualisation_server. |
- | % open your browser at http:// | + | % Ignore the INFO output on the console |
+ | % Open your browser at http:// | ||
- | ?- owl_individual_of(Map, | + | ?- owl_individual_of(Map, |
</ | </ | ||
Similarly, we can also visualize small objects in the kitchen: | Similarly, we can also visualize small objects in the kitchen: | ||
Line 33: | Line 46: | ||
owl_individual_of(A, | owl_individual_of(A, | ||
| | ||
- | add_object(A, _). | + | marker_update(object(A)). |
</ | </ | ||
Line 41: | Line 54: | ||
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: | 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: | ||
<code prolog> | <code prolog> | ||
- | % perishable objects: | + | % perishable objects: |
- | ?- owl_individual_of(A, | + | ?- owl_individual_of(A, |
- | A = knowrob:' | + | A = map_obj:' |
- | A = knowrob:' | + | A = map_obj:' |
- | A = knowrob:' | + | A = map_obj:' |
- | A = knowrob:' | + | A = map_obj:' |
- | A = knowrob:' | + | A = map_obj:' |
- | A = knowrob:' | + | A = map_obj:' |
+ | |||
+ | % all HandTools (e.g. silverware) | ||
+ | ?- owl_individual_of(A, | ||
+ | A = map_obj:' | ||
+ | A = map_obj:' | ||
+ | |||
+ | % all FoodVessels (i.e. pieces of tableware) | ||
+ | ?- owl_individual_of(A, | ||
+ | A = map_obj:' | ||
+ | A = map_obj:' | ||
+ | A = map_obj:' | ||
+ | |||
+ | % everything with a handle: | ||
+ | ?- owl_has(A, knowrob: | ||
+ | | ||
+ | A = map_obj:' | ||
+ | H = map_obj:' | ||
+ | [...] | ||
+ | </ | ||
+ | |||
+ | |||
+ | ===== Querying for qualitative spatial relations ===== | ||
+ | |||
+ | Using [[reason_using_computables|computables]] that calculate qualitative spatial relations between objects, we can query e.g. in which container we expect to find sausage1, ask for the content of Refrigerator67, | ||
+ | |||
+ | <code prolog> | ||
+ | ?- rdf_triple(knowrob:' | ||
+ | C = knowrob:' | ||
- | % all HandTools (e.g. silverware) | + | ? |
- | ?- owl_individual_of(A, knowrob:' | + | O = map_obj:'cheese1' ; |
- | A = knowrob:'knife1' ; | + | O = map_obj:' |
- | A = knowrob:'fork1' | + | O = map_obj:'sausage1' |
- | % all FoodVessels (i.e. pieces of tableware) | + | ? |
- | ?- owl_individual_of(A, knowrob:' | + | A = map_obj:'cup1' |
- | A = knowrob:' | + | A = knowrob:' |
- | A = knowrob:' | + | |
- | A = knowrob:' | + | |
- | + | ||
- | % everything with a handle: | + | |
- | ?- owl_has(A, knowrob: | + | |
- | owl_individual_of(H, | + | |
- | A = knowrob:'Dishwasher37', | + | |
- | H = knowrob:' | + | |
</ | </ | ||
- | + | ===== Inferring | |
- | ===== Infer likely storage locations ===== | + | |
For some tasks, robots 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. | For some tasks, robots 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. | ||
Line 78: | Line 110: | ||
- | === Query for likely storage | + | === Querying |
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: | 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: | ||
<code prolog> | <code prolog> | ||
- | ?- storagePlaceFor(Place, | + | ?- storagePlaceFor(Place, |
- | Place = knowrob:' | + | Place = knowrob:' |
- | ?- storagePlaceFor(knowrob:' | + | ?- storagePlaceFor(knowrob:' |
- | Obj = knowrob:' | + | Obj = map_obj:' |
- | Obj = knowrob:' | + | Obj = map_obj:' |
- | Obj = knowrob:' | + | Obj = map_obj:' |
- | Obj = knowrob:' | + | Obj = map_obj:' |
- | [...] | + | [...] |
</ | </ | ||
Line 96: | Line 128: | ||
<code prolog> | <code prolog> | ||
?- storagePlaceForBecause(Place, | ?- storagePlaceForBecause(Place, | ||
- | Place = ' | + | Place = knowrob:'Refrigerator67', |
- | | + | |
</ | </ | ||
Line 105: | Line 137: | ||
- | === Check for objects that are not at their storage location === | + | === Checking |
- | By combining the semantic map, giving | + | By combining the semantic map and the current object locations with the knowledge about the locations where objects should be, the robot can determine which objects are misplaced. 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), |
- | + | ||
- | 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), | + | |
<code prolog> | <code prolog> | ||
Line 116: | Line 146: | ||
storagePlaceFor(StoragePlace, | storagePlaceFor(StoragePlace, | ||
ActualPlace\=StoragePlace. | ActualPlace\=StoragePlace. | ||
- | Obj = 'http:// | + | Obj = map_obj:'butter1', |
- | | + | |
- | | + | |
- | Obj = 'http:// | + | Obj = map_obj:'buttermilk1', |
- | | + | |
- | | + | |
</ | </ | ||
- | ===== Read object component hierarchy ===== | + | You will notice that it takes a bit of time to answer the query: This is because the first predicate searches for all objects that are inside another one, and for doing this has to compute all pairwise ' |
- | Composed objects and their parts are linked by an inverse part-of | + | |
+ | ===== Reading the object component hierarchy ===== | ||
+ | |||
+ | Composed objects and their parts are linked by a ' | ||
<code prolog> | <code prolog> | ||
?- owl_has(knowrob:' | ?- owl_has(knowrob:' | ||
- | P = ' | + | P = knowrob:'Door70' |
- | P = ' | + | P = knowrob:'Handle160' |
- | P = ' | + | P = knowrob:'Hinge70' |
</ | </ | ||
- | === Special case: articulated objects such as cupboards === | ||
- | {{ :part-of-hierarchy-map.png? | + | ===== Representation |
- | 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 | + | {{ :part-of-hierarchy-map.png? |
+ | Articulated objects, e.g. 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, which connections are fixed and which are movable. 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:// | Joints are described using the following properties, which are compatible to the representation used by the [http:// | ||
Line 150: | Line 183: | ||
- | ===== Read articulation information ===== | + | ===== Reading |
- | There are some convenience | + | There are some helper |
- | + | ||
- | To create a joint of type knowrob:' | + | |
<code prolog> | <code prolog> | ||
| | ||
Line 160: | Line 191: | ||
</ | </ | ||
- | If a prismatic joint is to be created instead, the empty list [] needs to be replaced with a unit vector describing the joint' | + | 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: | + | |
<code prolog> | <code prolog> | ||
| | ||
Line 172: | Line 201: | ||
</ | </ | ||
- | ===== 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: | + | ===== Reading and converting |
- | <code prolog> | + | |
- | $ roscd knowrob_common/ | + | |
- | $ rosrun rosprolog rosprolog ias_knowledge_base | + | |
- | + | ||
- | ?- owl_parse(' | + | |
- | ?- consult(' | + | |
- | + | ||
- | % read information that is asserted for a test instance | + | |
- | ?- rdf_has(' | + | |
- | ' | + | |
- | | + | |
- | + | ||
- | % manual conversion into other units | + | |
- | ?- convert_to_unit($O, | + | |
- | | + | |
- | + | ||
- | ?- convert_to_unit($O, | + | |
- | | + | |
- | + | ||
- | ?- convert_to_unit($O, | + | |
- | | + | |
- | </ | + | |
- | The integration | + | All numerical values in KnowRob can optionally be annotated |
- | <code prolog> | + | |
- | % transparent conversion during | + | |
- | ?- rdf_triple(' | + | |
- | ' | + | |
- | literal(type(' | + | |
- | Val = 0.12 ; | + | |
- | + | ||
- | ?- rdf_triple(' | + | |
- | ' | + | |
- | literal(type(' | + | |
- | Val = 0.00012 ; | + | |
- | </ | + | |
- | |||
- | ===== Query for qualitative spatial relations ===== | ||
- | |||
- | Using [[reason_using_computables|computables]] that calculate qualitative spatial relations between objects, we can query e.g. in which container we expect to find sausage1, ask for the content of Refrigerator67, | ||
- | |||
- | <code prolog> | ||
- | ?- rdf_triple(knowrob:' | ||
- | C = ' | ||
- | |||
- | ?- rdf_triple(knowrob:' | ||
- | O = ' | ||
- | O = ' | ||
- | O = ' | ||
- | |||
- | | ||
- | A = ' | ||
- | A = ' | ||
- | </ | ||