Semantic Robot Description Language

This page describes the 'catkinized' version of KnowRob that uses the catkin buildsystem and the pure Java-based rosjava. The documentation for the older version, which was based on the rosbuild buildsystem and rosjava_jni, can be found here.

The Semantic Robot Description Language (SRDL) extends KnowRob with representations for robot hardware, robot software and robot capabilities. The hardware models can automatically be imported from a URDF description, and are annotated with additional semantic information. For example, one can annotate semantically meaningful groups of links such as the left arm or the right gripper (see image on the right). SRDL integrates this information into KnowRob, allowing the system to reason about the robot's configuration. In addition, SRDL provides inference mechanisms that operate on the robot model and are able to check which dependencies of action descriptions are available on the robot. This allows to identify missing components or capabilities.

Ontology organization

The SRDL ontology is organized in a modular way, e.g. to describe only components or only capabilities. The diagram below shows which parts of the ontology import which other ones.

  • srdl2: Only generic cross-file relations like the generic dependsOn property
  • srdl2-comp: Classes of hardware and software components, aggregation of components to kinematic chains, composition of components
  • srdl2-cap: Classes of capabilities, including their dependencies on components or other capabilities
  • srdl2-action: Dependency specifications for common actions
  • Robot model: Description of a concrete robot instance including its kinematic structure (auto-generated from URDF file), other hardware/software components and hardcoded capabilities
  • Task model: Description of the concrete task at hand, using the action classes defined in the srdl-action ontology


$ rosrun rosprolog rosprolog knowrob_srdl
% Load SRDL model of the PR2 and Baxter robots
?- owl_parse('package://knowrob_srdl/owl/PR2.owl').
?- owl_parse('package://knowrob_srdl/owl/baxter.owl').
% Load an example task description for serving a drink
?- register_ros_package(knowrob_actions).
?- owl_parse('package://knowrob_actions/owl/serve_drink.owl').

Components and capabilities of a robot

Read all components of a robot. There is no distinction between robots and components any more, robots are just complex components that consist of many parts.

?- sub_component(pr2:'PR2Robot1', Sub).
Sub = pr2:pr2_base ;
Sub = pr2:pr2_left_arm ;
Sub = pr2:pr2_right_arm

Filter the list of components to only those of a given type, e.g. a Camera:

?- sub_component(pr2:'PR2Robot1', Sub), 
   owl_individual_of(Sub, srdl2comp:'Camera').
Sub = pr2:pr2_high_def_frame ;
Sub = pr2:pr2_high_def_frame ;
Sub = pr2:pr2_wide_stereo_l_stereo_camera_frame ;
Sub = pr2:pr2_wide_stereo_r_stereo_camera_frame ;
Sub = pr2:pr2_narrow_stereo_l_stereo_camera_frame

Read all properties of a component:

?- sub_component(pr2:'PR2Robot1', Sub), owl_has(Sub, P, O).
Sub = pr2:pr2_high_def_frame,
Sub = pr2:pr2_high_def_frame,
P = srdl2comp:update_rate,
O = literal(type('','20.0')) ;
Sub = pr2:pr2_high_def_frame,
P = srdl2comp:frameName,
O = literal(type(xsd:string,high_def_optical_frame)) ;
Sub = pr2:pr2_high_def_frame,
P = srdl2comp:hfov,
O = literal(type(xsd:string,'0.785398163397'))

Check whether a component of a certain type exists on a robot (or, in general, as part of another component):

?- comp_type_available(pr2:'PR2Robot1', srdl2comp:'Camera').
?- comp_type_available(pr2:'PR2Robot1', Sub).
Sub = srdl2comp:'Pr2Base' ;
Sub = srdl2comp:'WheeledBase' ;
Sub = srdl2comp:'MobileBase' ;

Check which capabilities exists on a robot:

?- cap_available_on_robot(Cap, pr2:'PR2Robot1').
Cap = srdl2cap:'GraspingCapability' ;
Cap = srdl2cap:'ObjectManipulationCapability' ;

Requirements of an action

Capabilities an action depends on:

?- required_cap_for_action(serve_drink:'ServeADrink', C).
C = srdl2cap:'BaseMotionCapability' ;
C = srdl2cap:'ArmMotionCapability' ;
C = srdl2cap:'GraspingCapability' ;
C = srdl2cap:'GripperMotionCapability'

Components an action depends on (either directly or via required capabilities that depend on these components)

?- required_comp_for_action(serve_drink:'ServeADrink', C).
C = srdl2comp:'MobileBase' ;
C = srdl2comp:'ArmMotionController' ;
C = srdl2comp:'ArmComponent' ;
C = srdl2comp:'ManipulationEntity'

Missing components or capabilities

% No components nor capabilities are missing for the ServeADrink action on the PR2:
?- missing_comp_for_action(serve_drink:'ServeADrink', pr2:'PR2Robot1', C).
?- missing_cap_for_action(serve_drink:'ServeADrink', pr2:'PR2Robot1', C).
% The Baxter robot, in contrast, cannot perform the task due to lacking navigation abilities:
?- missing_cap_for_action(serve_drink:'ServeADrink', baxter:baxter_baxter1, C).
C = srdl2cap:'BaseMotionCapability'

Behind the scenes: Implementation of the matching procedures

The matching can effectively reduced to the following statement:

  missing_cap_for_action(Action, Robot, Cap) :-
     required_cap_for_action(Action, Cap),
     \+ cap_available_on_robot(Cap, Robot).

A missing capability is thus defined as one that is required by an action but not provided by the robot. “Required” thereby means that either the action itself or any sub-action has a dependency on this capability:

  required_cap_for_action(Action, Cap) :-
     class_properties(Action, srdl2cap:'dependsOnCapability', Cap).
  required_cap_for_action(Action, Cap) :-
     plan_subevents_recursive(Action, SubAction),
     class_properties(SubAction, srdl2cap:'dependsOnCapability', Cap).

There are three possibilities to express that a capability is available on a robot: Either it is asserted to be available for the whole class of robots (e.g. every PR2 has a mobile base), for a specific robot instance, or it can be concluded that the capability should be available because all specified dependencies on components or other capabilities are fulfilled:

  % capability asserted for robot instance
  cap_available_on_robot(Cap, Robot) :-
     class_properties(Robot, srdl2cap:'hasCapability', Cap).
  % capability asserted for robot class
  cap_available_on_robot(Cap, Robot) :-
     rdfs_individual_of(Robot, RobotClass),
     class_properties(RobotClass, srdl2cap:'hasCapability', Cap).
  % capability depends only on available components or capabilities
  cap_available_on_robot(Cap, Robot) :-
     rdfs_subclass_of(Cap, srdl2cap:'Capability'),
     forall( class_properties(Cap, srdl2comp:'dependsOnComponent', CompT),
             comp_type_available(Robot, CompT) ),
     forall( class_properties(Cap, srdl2cap:'dependsOnCapability', SubCap),
             cap_available_on_robot(SubCap, Robot) ).

The matching procedure is equivalent for components.

Comparison to earlier versions

SRDL2 is a re-implementation of the original Semantic Robot Description Language presented by Kunze et al (ICRA 2011). The code has been completely re-written to improve its flexibility and generality. The main changes are the following:

  • No distinction between primitive and composite capabilities.
  • Actions, capabilities and components can depend on other components, actions and capabilities can depend on other capabilities
  • There are no “CapabilityProvisionAlternatives” any more, which are replaced by simple sub-classes of a capability
  • The modeling of sub-components was improved by using transitive properties that are derived from 'subComponent' instead of many different relations. The same holds for the 'dependsOn' relation that subsumes 'dependsOnComponent' and 'dependsOnCapability'.
  • Dependencies can now be described using OWL restrictions, which is important to specify more details, e.g. the dependency on an object recognition model that allow to recognize a certain kind of object (and not just an arbitrary model)
  • The descriptions for components, capabilities and actions have been separated in order to facilitate the description of robots and actions, and to keep the system as modular as possible.
  • Instead of lists, the system now uses the more Prolog-like backtracking.