Updated on February 2017!

This is a step by step guide related to the Github repository JinchiMiru. We will setup a RosJAVA environment in order to use the Ontology API of JENA.

Prerequisites:

  • Working ROS environment. If you do not have one. See the official guide.

Install RosJAVA

Let’s start by installing the rosjava package for ROS Indigo

$ sudo apt-get install ros-indigo-rosjava

or, if you have ROS kinetic

$ sudo apt-get install ros-kinetic-rosjava

Create a folder inside your catkin_ws. Next, create a new package in rosjava/src and compile the workspace.

 $ cd catkin_ws
catkin_ws$ mkdir -p rosjava/src && cd /rosjava/src
catkin_ws/rosjava/src$ catkin_create_rosjava_pkg jinchimiru
catkin_ws/rosjava/src$ cd .. 
catkin_ws/rosjava$ catkin_make

The package will be compiled.

Create a subproject inside jinchimiru package’s folder:


catkin-ws/rosjava$ cd src/jinchimiru/
catkin-ws/rosjava/src/jinchimiru/$ catkin_create_rosjava_project jinchimiru_sub_project

Creating rosjava project 
  Name      : jinchimiru_sub_project
  File      : build.gradle
  File      : settings.gradle
  File      : Talker.java
  File      : Listener.java
  File      : CMakeLists.txt (gradle task update)
catkin-ws/rosjava/src/jinchimiru/$  tree
.
├── build.gradle
└── src
    └── main
        └── java
            └── com
                └── github
                    └── jinchimiru
                        └── jinchimiru_sub_project
                            ├── Listener.java
                            └── Talker.java

A Talker and Listener java nodes will be created by default. Ok, compile the project.

catkin-ws/rosjava/src/jinchimiru/$ cd ../..
catkin-ws/rosjava$ catkin_make

If your workspace contains many projects, you can speed up the process by compiling just your subproject alone with gradle.

catkin-ws/rosjava/$ cd src/jinchimiru/jinchimiru_sub_project
catkin-ws/rosjava/src/jinchimiru/jinchimiru_sub_project$ ../gradlew installApp
:jinchimiru_sub_project:compileJava UP-TO-DATE
:jinchimiru_sub_project:processResources UP-TO-DATE
:jinchimiru_sub_project:classes UP-TO-DATE
:jinchimiru_sub_project:jar UP-TO-DATE
:jinchimiru_sub_project:startScripts UP-TO-DATE
:jinchimiru_sub_project:installApp UP-TO-DATE

BUILD SUCCESSFUL

Total time: 5.939 secs

Run Samples

In order to run the talker and listener nodes, run roscore then go to build/install/my_pub_sub_tutorial/bin and pass the Talker package to the executable.

catkin-ws/rosjava/$ cd .. && roscore &
catkin-ws/$ cd rosjava/src/jinchimiru/jinchimiru_sub_project/build/install/jinchimiru_sub_project/bin/
catkin-ws/rosjava/src/jinchimiru/jinchimiru_sub_project/build/install/jinchimiru_sub_project/bin$ ./jinchimiru_sub_project com.github.rosjava.jinchimiru.jinchimiru_sub_project.Talker

Now open another tab in the same terminal window (Press Ctrl+Shift+T) and run the Listener.

catkin-ws/rosjava/src/jinchimiru/jinchimiru_sub_project/build/install/jinchimiru_sub_project/bin$ ./jinchimiru_sub_project com.github.rosjava.jinchimiru.jinchimiru_sub_project.Listener

You should see Hello messages like this.

feb 11, 2017 1:13:27 AM org.ros.internal.node.RosoutLogger info
INFORMAZIONI: I heard: "Hello world! 42"
feb 11, 2017 1:13:28 AM org.ros.internal.node.RosoutLogger info
INFORMAZIONI: I heard: "Hello world! 43"

The nodes involved are:

 $  rosnode list
/rosjava/listener
/rosjava/talker
/rosout

What is Jena

The Jena ontology API is a Java programming toolkit. Jena’s ontology support is limited to ontology formalisms built on top of RDF.

RDFS is the weakest ontology language supported by Jena. With RDFS it is possible to build a simple hierarchy of concepts, and a hierarchy of properties.
There are various different ontology languages available for representing ontology information on the semantic web. They range from the most expressive, OWL Full, through to the weakest, RDFS.

The ontology language used in this project is the OWL FULL. OWL language allows properties to be denoted as transitive, symmetric or functional, and allows one property to be declared to be the inverse of another.

One of the key benefits of building an ontology-based application is using a reasoner to derive additional truths about the concepts you are modelling. Jena includes support for a variety of reasoners through the inference API.

A common feature of Jena reasoners is that they create a new RDF model which appears to contain the triples that are derived from reasoning as well as the triples that were asserted in the base model. The ontology API can query an extended inference model and extract information not explicitly given.

Importing Jena Libraries

Download the Jena libraries for manipulating ontologies from the offical website. Please note that the link and the compressed version may change.

Download the apache-jena-3.2.0.zip and unzip the folder apache-jena-3.2.0/lib containing all the libraries. Place only the lib/ directory in your subproject folder which in this case is catkin-ws/rosjava/src/jinchimiru/jinchimiru_sub_project/.

Your subproject’s folder should look like this:

catkin-ws/rosjava/src/jinchimiru/jinchimiru_sub_project$ tree
.
├── build 
[...] ├── build.gradle ├── lib │ ├── collection-0.6.jar │ ├── commons-cli-1.3.jar │ ├── commons-codec-1.9.jar │ ├── commons-csv-1.0.jar │ ├── commons-io-2.4.jar │ ├── commons-lang3-3.3.2.jar │ ├── httpclient-4.2.6.jar │ ├── httpclient-cache-4.2.6.jar │ ├── httpcore-4.2.5.jar │ ├── jackson-annotations-2.3.0.jar │ ├── jackson-core-2.3.3.jar │ ├── jackson-databind-2.3.3.jar │ ├── jcl-over-slf4j-1.7.20.jar │ ├── jena-arq-3.1.0.jar │ ├── jena-base-3.1.0.jar │ ├── jena-cmds-3.1.0.jar │ ├── jena-core-3.1.0.jar │ ├── jena-iri-3.1.0.jar │ ├── jena-shaded-guava-3.1.0.jar │ ├── jena-tdb-3.1.0.jar │ ├── jsonld-java-0.7.0.jar │ ├── libthrift-0.9.2.jar │ ├── log4j-1.2.17.jar │ ├── slf4j-api-1.7.20.jar │ ├── slf4j-log4j12-1.7.20.jar │ ├── xercesImpl-2.11.0.jar │ └── xml-apis-1.4.01.jar └── src └── main └── java └── com └── github └── jinchimiru └── jinchimiru_sub_project ├── Listener.java └── Talker.java

Now that we have added our Jena jars we need to make gradle aware of them. Add to the build.gradle and change the dependencies section as follows.


dependencies {
  /* An external maven artifact dependency */
  compile 'org.ros.rosjava_core:rosjava:[0.2,0.3)'
  /* Example of a local subproject dependency */ 
  /* compile project(':sibling_gradle_project') */
  compile fileTree(dir: 'lib', include: '*.jar')
}

In order to test if you are able to import Jena libraries, open the Listener.java file, import org.apache.jena.ontology.OntModel and declare an Ontology Model.

Save and try to compile. If you get an error at line 20 then you have a problem with the import. Comment this post with the issue.

If your catkin_make command ends successfully but you are not able to run the node because of an issue related to slf4j. Then download these two jars from here and add them to the lib folder we have created.

Try to test the Listener Node by running the command of the section “Run samples”

Ontological model of domestic environment

It is expected that mobile robots undertake various tasks not only in industrial fields such as manufacturing plants and construction sites, but also in the environment we live in. We will consider a generic home domain model containing the Terminology Box and the instance data file containing the Assertion Box with all instances. Both files, semantic_mapping_domain_model.owl
and semantic_map1.owl are available here.

Terminology Box

The furniture class describes several objects of a generic home environment a robot can interact with.

furniture class

furniture class

OWL distinguishes between two main categories of properties that an ontology builder may want to define:

  • Object properties link individuals to individuals
  • Datatype properties link individuals to data values.

An object property is defined as an instance of the built-in OWL class owl:ObjectProperty. A datatype property is defined as an instance of the built-in OWL class owl:DatatypeProperty. Both owl:ObjectProperty and owl:DatatypeProperty are subclasses of the RDF class rdf:Property.

The following Figure shows the class tree diagram of the ObjectProperties involved in the project.

owl object Properties

owl object Properties

As an example, consider the following set of owl statements about the ObjectProperty hasPosition. This property is of the type IrreflexivePropery and is a subProperty of SpacialProperty.

Let us consider another Class involved in this project.

The class Coordinates is a subclass of the class Position and of three anonymous classes. A property restriction describes an anonymous class, namely a class of all individuals that satisfy the restriction.
The first restriction is a Value contraint linked (using owl:onProperty) the Property float_coordinates_z to a class of all individuals for which at least one value of the property concerned is an instance of a data value in the data range.
The second and third restrictions are Cardinality contraints linked to the Property float_coordinates_x and float_coordinates_y.

Assertion Box

The collection of individual are stored in a separate file called semantic_map1.owl, the Abox.
Individuals are defined with individual axioms called “facts”. These facts are statements indicating class membership of individuals and property values of individuals. As an example, consider the following set of statements about an instance of the class Chair

This example includes a number of facts about the individual chair1, an instance of the class Chair. The chair has three alternative references and one preferred lexical reference. These properties link a chair to a typed literal with the XML Schema datatype date. The XML schema document on datatypes contains the relevant information about syntax and semantics of this datatype. The property hasPosition and hasSize link the chair to instances of the type Coordinates and Dimensions.

In a software like Protégé the situatuion would have been like this:

protege

protege

The following example shows the instance of the 3Three\_Dim\_Size property associated to the individual chair1

Loading the ontology

To load into memory the Terminology Box and the Assertions Box as Ontology Models, we need to specify an absolute path.

Invoking specialized Reasoner

The reasoner API supports the notion of specializing a reasoner by binding it to a set of schema or ontology data using the bindSchema call. The specialized reasoner can then be attached to different sets of instance data using bind calls. It is worth noting that in this project the schema (TBox) and instance (ABox) data were saved in two separate files.

Consistency Check

Typically the ontology languages used with the semantic web allow constraints to be expressed, the validation interface is used to detect when such constraints are violated by some data set. To test for inconsistencies with a data set using a reasoner the InfModel.validate() interface.

You can perform a global check across the schema and instance data looking for inconsistencies with the following function:

In this post we have seen how to create a ROSJava project and include Jena ontology library. In the next one we will see how to interact with the ontology perform SPARQL queries.