../_images/tiagopro-icon.png ../_images/kangaroo-icon.png ../_images/tiago-icon.png ../_images/ari-icon.png ../_images/talos-icon.png ../_images/mobile-bases-icon.png

Tutorial: Getting started with the knowledge base#

๐Ÿ Goal of this tutorial

By the end of this tutorial, you will know how to make inferences based on facts and relationships.

This is important when you want your robot to store and retrieve symbolic information, as well as for make high-level symbolic reasoning (first-order logic reasoning).

Pre-requisites#

  • This tutorial requires that you have already read and understood how the knowldge core API works

  • This tutorial requires that you already know how to add/remove/query the robotโ€™s knowledge base.

Note

Your robot already comes with the knowledge core installed and the reasonable OWL2 RL reasoner.

The code#

first_reasoning_task.py#
 1import time
 2import rclpy
 3from rclpy.node import Node
 4from knowledge_core.api import KB
 5
 6rclpy.init()
 7node = Node("test_knowledge_base")
 8kb = KB(node)
 9
10def on_robot_entering_alfred_property(evt):
11    print(f'A robot entered Alfred\'s {evt[0]["place"]}: {evt[0]["robot"]}')
12
13# instanciate the kb with some facts
14kb += "ari rdf:type Robot"
15kb += "alfred rdf:type Human"
16kb += ["ari isIn kitchen"]
17kb += ["Human rdfs:subClassOf Animal"]
18
19# test existence with inference
20print("Is Alfred an animal?")
21if 'alfred rdf:type Animal' in kb:
22    print("yes, he is")
23
24
25# test complex event
26kb.subscribe(["?robot isIn ?place", "?place belongsTo alfred",
27            "?robot rdf:type Robot"], on_robot_entering_alfred_property)
28# add fact to the kb
29kb += "kitchen belongsTo alfred"
30
31rclpy.spin(node)
32#event should have been triggered

The code explained#

Letโ€™s first import the KB class from the knowledge_core.api module. This class offers a more โ€˜Pythonicโ€™ wrapper around the knowledge baseโ€™s ROS API. We also import rclpy to create a ROS node.

1import time
2import rclpy
3from rclpy.node import Node
4from knowledge_core.api import KB

Next, we initialise a ROS 2 node for the process and and create an object of the class KB.

6rclpy.init()
7node = Node("test_knowledge_base")
8kb = KB(node)

We define a callback which will trigger an event. In in this case it will print on the screen the string: A robot entered Alfred's kitchen: ari.

10  def on_robot_entering_alfred_property(evt):
11    print(f'A robot entered Alfred\'s {evt[0]["place"]}: {evt[0]["robot"]}')

Then, we can start populating the knowledge base with some facts.

13# instanciate the kb with some facts
14kb += "ari rdf:type Robot"
15kb += "alfred rdf:type Human"
16kb += ["alfred looksAt ari", "ari isIn kitchen"]
17kb += ["Human rdfs:subClassOf Animal"]

Letโ€™s know test the reasoner with some basic inference. We ask whether Alfred belongs to the class Animal:

19# test existence with inference
20print("Is Alfred an Animal?")
21if 'alfred rdf:type Animal' in kb:
22    print("yes, he is")

Finally, we try to make a more complex reasoning. We ask KnowledgeCore to trigger an event when someone enters in Alfred property. As soon as we add the fact that kitchen belongsTo alfred an event is triggered, printing the result of the callback on_robot_entering_alfred_property.

25# test complex event
26kb.subscribe(["?robot isIn ?place", "?place belongsTo alfred",
27            "?robot rdf:type Robot"], on_robot_entering_alfred_property)
28# add fact to the kb
29kb += "kitchen belongsTo alfred"
30
31rclpy.spin(node)
32#event should have been triggered

Note

rclpy.spin(node) is a blocking call that will keep the node alive forever.

In a real-world application, you would probably want to use a timer and call rclpy.spin_once(node) instead.

Next steps#