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#
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#
read more about the KnowledgeCore API