diff --git a/CMakeLists.txt b/CMakeLists.txt index 7fc0b5d1..de5dc391 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -19,7 +19,8 @@ function(add_onto_library TARGET) message(FATAL_ERROR "Expected source file list after target name") endif() add_library(${TARGET} ${ARGN}) - target_include_directories(${TARGET} PUBLIC include) + target_include_directories(${TARGET} PUBLIC $ + $) set_target_properties(${TARGET} PROPERTIES CXX_STANDARD 17 CXX_STANDARD_REQUIRED ON) target_compile_options(${TARGET} PRIVATE -Wall -Wextra) target_enable_sanitizers(${TARGET}) @@ -121,7 +122,7 @@ catkin_package( DEPENDS TinyXML OpenCV ) elseif($ENV{ROS_VERSION} STREQUAL "2") -ament_export_dependencies(rosidl_default_runtime) +ament_export_dependencies(rosidl_default_runtime pluginlib) rosidl_get_typesupport_target(cpp_typesupport_target ${PROJECT_NAME} rosidl_typesupport_cpp) endif() @@ -169,7 +170,9 @@ target_include_directories(ontologenius_ontoGraphs_lib ) target_link_libraries(ontologenius_ontoGraphs_lib PUBLIC - ${TinyXML_LIBRARIES} ${TinyXML2_LIBRARIES} PkgConfig::CURL + ${TinyXML_LIBRARIES} ${TinyXML2_LIBRARIES} +PRIVATE + PkgConfig::CURL ) add_onto_library(ontologenius_core_lib @@ -256,7 +259,8 @@ function(add_ros_library TARGET) target_link_libraries(${TARGET} PUBLIC ${catkin_LIBRARIES}) # PRIVATE has been removed fot ontoloGUI elseif($ENV{ROS_VERSION} STREQUAL "2") ament_target_dependencies(${TARGET} PUBLIC rclcpp pluginlib builtin_interfaces std_msgs) - target_include_directories(${TARGET} PUBLIC include) + target_include_directories(${TARGET} PUBLIC $ + $) target_link_libraries(${TARGET} PUBLIC ${cpp_typesupport_target}) ament_export_libraries(${TARGET}) endif() @@ -302,7 +306,8 @@ add_ros_library(ontologenius_lib src/API/ontologenius/OntologyManipulatorIndex.cpp src/API/ontologenius/OntologiesManipulator.cpp ) -target_include_directories(ontologenius_lib PUBLIC include/ontologenius/API) +target_include_directories(ontologenius_lib PUBLIC $ + $) target_link_libraries(ontologenius_lib PUBLIC ontologenius_compat @@ -476,29 +481,16 @@ install(DIRECTORY files/ ) elseif($ENV{ROS_VERSION} STREQUAL "2") -install(TARGETS - ontologenius_reasoner_plugin - DESTINATION lib/${PROJECT_NAME}) install(TARGETS ontologenius_lib - EXPORT ontologenius_lib - ARCHIVE DESTINATION lib - LIBRARY DESTINATION lib - RUNTIME DESTINATION bin - DESTINATION lib/${PROJECT_NAME}) - -install(TARGETS ontologenius_interface - EXPORT ontologenius_interface - ARCHIVE DESTINATION lib - LIBRARY DESTINATION lib - RUNTIME DESTINATION bin - DESTINATION lib/${PROJECT_NAME}) - -install(TARGETS ontologenius_compat - EXPORT ontologenius_compat + ontologenius_operators + ontologenius_core_lib + ontologenius_ontoGraphs_lib + ontologenius_reasoner_plugin + EXPORT ontologenius ARCHIVE DESTINATION lib LIBRARY DESTINATION lib RUNTIME DESTINATION bin @@ -507,14 +499,10 @@ install(TARGETS install(TARGETS ontologenius_single ontologenius_multi + ontologenius_draw ontoloGUI DESTINATION lib/${PROJECT_NAME}) -install(TARGETS ontologenius_operators - ontologenius_core_lib - ontologenius_ontoGraphs_lib - DESTINATION lib) - install(DIRECTORY launch/ros2/launch DESTINATION share/${PROJECT_NAME}/) install(DIRECTORY include/ DESTINATION include) @@ -522,7 +510,7 @@ install(DIRECTORY files DESTINATION share/${PROJECT_NAME}/) install(DIRECTORY docs DESTINATION share/${PROJECT_NAME}/) install(DIRECTORY configuration DESTINATION share/${PROJECT_NAME}/) -ament_export_libraries(ontologenius_lib ontologenius_interface ontologenius_compat) +ament_export_targets(ontologenius) endif() diff --git a/docs/Download.html b/docs/Download.html index 4babf452..9fd37724 100644 --- a/docs/Download.html +++ b/docs/Download.html @@ -93,7 +93,7 @@

Download

You have below the archives of the major versions of Ontologenius:

V0.4.0

-

X / XX / 2024

+

31 / 01 / 2024

  • diff --git a/docs/SetUp.html b/docs/SetUp.html index 76ebf570..aca2711d 100644 --- a/docs/SetUp.html +++ b/docs/SetUp.html @@ -309,7 +309,7 @@

    Create your executable

    add_executable(my_exe src/main.cpp)
    ament_target_dependencies(my_exe rclcpp)
    -
    target_link_libraries(my_exe ${ontologenius_LIBRARIES})
    +
    target_link_libraries(my_exe ontologenius::ontologenius_lib)
    diff --git a/docs/cpp_API/FeederPublisher.html b/docs/cpp_API/FeederPublisher.html index bb548276..89ed1998 100644 --- a/docs/cpp_API/FeederPublisher.html +++ b/docs/cpp_API/FeederPublisher.html @@ -155,6 +155,8 @@

    Public Functions

    std::string commit(int32_t timeout = -1) bool commit(const std::string& commit_name, int32_t timeout = -1) bool checkout(const std::string& commit_name, int32_t timeout = -1) + registerFeederNotificationCallback(const std::function<void(const std::string&)>& callback) + registerReasonersNotificationCallback(const std::function<void(const std::string&)>& callback) @@ -276,6 +278,14 @@

    boolReturns false if the function returns on a timeout.

    This function can only be used on a copied ontology.

    +

    void FeederPublisher::registerFeederNotificationCallback(const std::function<void(const std::string&)>& callback)

    +

    Register a callback function to get notifications from the feeder.

    +

    The parameter callback is the callback function taking a string.

    + +

    void FeederPublisher::registerReasonersNotificationCallback(const std::function<void(const std::string&)>& callback)

    +

    Register a callback function to get notifications from the reasoners.

    +

    The parameter callback is the callback function taking a string.

    + diff --git a/docs/cpp_Tutorials/Tutorials.html b/docs/cpp_Tutorials/Tutorials.html index 87a25b1a..7d33f149 100644 --- a/docs/cpp_Tutorials/Tutorials.html +++ b/docs/cpp_Tutorials/Tutorials.html @@ -118,7 +118,7 @@

    Ontologenius C++ Tutorials

    Ontologenius comes with a series of tutorials to help new users become familiar with the use of - Ontologenius. These different tutorials cover the different features offered by Ontologenius and + Ontologenius both in ROS1 and ROS2. These different tutorials cover the different features offered by Ontologenius and give some ideas for use through tutorials built around mini-projects. Of course, these tutorials show simple use cases to allow beginners to better understand Ontologenius particularities. It is up to you to go further to discover all the possibilities offered by this software.

    diff --git a/docs/cpp_Tutorials/tutorial1/FindTheIntruder.html b/docs/cpp_Tutorials/tutorial1/FindTheIntruder.html index a2063b24..446de6cd 100644 --- a/docs/cpp_Tutorials/tutorial1/FindTheIntruder.html +++ b/docs/cpp_Tutorials/tutorial1/FindTheIntruder.html @@ -4,10 +4,12 @@ Use inheritance for my first program (cpp) : Find the intruder + + @@ -146,23 +148,23 @@

    getUp

    classes of which our individual inherits.

    -
    std::vector<std::vector<std::string> > getWordsInheritance(std::vector<std::string> words)
    +
    std::vector<std::vector<std::string> > getWordsInheritance(std::vector<std::string> words)
    {
    -
    std::vector<std::vector<std::string> > inheritances;
    -
    for(size_t i = 0; i < words.size(); i++)
    +
    std::vector<std::vector<std::string> > inheritances;
    +
    for(auto& word : words)
    {
    -
    std::vector<std::string> inheritance = onto_->individuals.getUp(words[i]);
    -
    inheritances.push_back(inheritance);
    +
    std::vector<std::string> inheritance = onto_->individuals.getUp(word);
    +
    inheritances.push_back(inheritance);
    }

    -
    return inheritances;
    +
    return inheritances;
    }

    This function, therefore, applies the getUp method to each word found in the "words" vector and it returns a vector for which each cell corresponds to the vector returned by getUp.

    -
    std::vector<std::string> inheritance = onto_->individuals.getUp(words[i]);
    +
    std::vector<std::string> inheritance = onto_->individuals.getUp(word);

    We also notice that we are going to look for the getUp function among the individuals because we know that the input words will be only individuals.

    @@ -170,29 +172,72 @@

    getUp

    In order to see the effect of this function, we will add the following lines in our main function, just after the call to the "say" function.

    -
    std::vector<std::vector<std::string> > inheritances = getWordsInheritance(names_);
    -
    for(size_t i = 0; i < inheritances.size(); i++)
    +
    std::vector<std::vector<std::string> > inheritances = getWordsInheritance(names_);
    +
    for(size_t i = 0; i < inheritances.size(); i++)
    {
    -
    std::cout << names_[i] << " is a : ";
    -
    for(size_t j = 0; j < inheritances[i].size(); j++)
    -
    std::cout << inheritances[i][j] << " ";
    -
    std::cout << std::endl;
    +
    std::cout << names_[i] << " is a : ";
    +
    for(auto& type : inheritances[i])
    +
    std::cout << type << " ";
    +
    std::cout << std::endl;
    }

    We can now recompile our project and launch it!

    -
    -
    catkin_make
    -

    -
    roslaunch ontologenius_tutorial intruder.launch
    +
    +
    + + +
    + +
    +
    +
    +
    catkin_make
    +

    +
    roslaunch ontologenius_tutorial intruder.launch
    +
    +
    +
    + +

    In another terminal we will publish a few words to see the result:

    -
    -
    rostopic pub -1 /intruder/input std_msgs/String "data: 'bob'"
    -
    rostopic pub -1 /intruder/input std_msgs/String "data: 'alice'"
    -
    rostopic pub -1 /intruder/input std_msgs/String "data: 'kevin'"
    -
    rostopic pub -1 /intruder/input std_msgs/String "data: 'start'"
    +
    +
    + + +
    + +
    +
    +
    +
    rostopic pub -1 /intruder/input std_msgs/String "data: 'bob'"
    +
    rostopic pub -1 /intruder/input std_msgs/String "data: 'alice'"
    +
    rostopic pub -1 /intruder/input std_msgs/String "data: 'kevin'"
    +
    rostopic pub -1 /intruder/input std_msgs/String "data: 'start'"
    +
    +
    +
    + +

    At the end of our program, you should have this:

    @@ -216,43 +261,43 @@

    Delete the same

    We will not analyze this code together because it is not the center of this tutorial.

    -
    void deleteTheSame(std::vector<std::vector<std::string> >& inheritances)
    -
    {
    -
    if(inheritances.size() > 1)
    -
    {
    -
    std::vector<std::string> sames;
    -
    for(size_t words = 0; words < inheritances[0].size(); words++)
    -
    {
    -
    bool is_same = true;
    -
    for(size_t i = 1; i < inheritances.size(); i++)
    -
    {
    -
    std::vector<std::string>::iterator it = find(inheritances[i].begin(), inheritances[i].end(), inheritances[0][words]);
    -
    if(it == inheritances[i].end())
    -
    is_same = false;
    -
    }
    -

    -
    if(is_same)
    -
    sames.push_back(inheritances[0][words]);
    -
    }
    -

    -
    for(size_t i = 0; i < sames.size(); i++)
    -
    for(size_t vect = 0; vect < inheritances.size(); vect++)
    -
    {
    -
    std::vector<std::string>::iterator it = find(inheritances[vect].begin(), inheritances[vect].end(), sames[i]);
    -
    inheritances[vect].erase(it);
    -
    }
    -
    }
    -
    }
    +
    void deleteTheSame(std::vector<std::vector<std::string> >& inheritances)
    +
    {
    +
    if(inheritances.size() > 1)
    +
    {
    +
    std::vector<std::string> sames;
    +
    for(size_t words = 0; words < inheritances[0].size(); words++)
    +
    {
    +
    bool is_same = true;
    +
    for(size_t i = 1; i < inheritances.size(); i++)
    +
    {
    +
    std::vector<std::string>::iterator it = find(inheritances[i].begin(), inheritances[i].end(), inheritances.front[words]);
    +
    if(it == inheritances[i].end())
    +
    is_same = false;
    +
    }
    +

    +
    if(is_same)
    +
    sames.push_back(inheritances.front()[words]);
    +
    }
    +

    +
    for(auto& same : sames)
    +
    for(auto& inheritance : inheritances)
    +
    {
    +
    std::vector<std::string>::iterator it = find(inheritance.begin(), inheritance.end(), same);
    +
    inheritance.erase(it);
    +
    }
    +
    }
    +
    }

    Add the call to this function in the main function just after the getWordsInheritance call.

    -
    std::vector<std::vector<std::string> > inheritances = getWordsInheritance(names_);
    -
    deleteTheSame(inheritances);
    +
    std::vector<std::vector<std::string> > inheritances = getWordsInheritance(names_);
    +
    deleteTheSame(inheritances);

    Compile this and run the program, then in another terminal re-query the programs on the words: - bob alice and kevin.

    + bob, alice, and kevin.

    This time, you should have this:

    [SAY]on bob alice kevin
    @@ -273,10 +318,10 @@

    Find the intruder

    reason he is the intruder.

    -
    struct intruder_t
    +
    struct intruder_t
    {
    -
    std::string name_;
    -
    std::string why_;
    +
    std::string name_;
    +
    std::string why_;
    };
    @@ -295,48 +340,48 @@

    Find the intruder

-
std::vector<struct intruder_t> find_intruder(std::vector<std::string>& names, std::vector<std::vector<std::string> >& inheritances)
+
std::vector<struct intruder_t> find_intruder(std::vector<std::string>& names, std::vector<std::vector<std::string> >& inheritances)
{
-
std::vector<struct intruder_t> intruders;
+
std::vector<struct intruder_t> intruders;

-
for(size_t vect_i = 0; vect_i < inheritances.size(); vect_i++)
-
for(size_t class_i = 0; class_i < inheritances[vect_i].size(); class_i++)
+
for(size_t vect_i = 0; vect_i < inheritances.size(); vect_i++)
+
for(size_t class_i = 0; class_i < inheritances[vect_i].size(); class_i++)
{
-
int intruder_index = -1;
+
int intruder_index = -1;

-
for(size_t vect_j = 0; vect_j < inheritances.size(); vect_j++)
-
if(vect_j != vect_i)
+
for(size_t vect_j = 0; vect_j < inheritances.size(); vect_j++)
+
if(vect_j != vect_i)
{
-
std::vector<std::string>::iterator it = find(inheritances[vect_j].begin(), inheritances[vect_j].end(), inheritances[vect_i][class_i]);
-
if(it == inheritances[vect_j].end())
+
std::vector<std::string>::iterator it = find(inheritances[vect_j].begin(), inheritances[vect_j].end(), inheritances[vect_i][class_i]);
+
if(it == inheritances[vect_j].end())
{
-
if(intruder_index == -1)
-
intruder_index = vect_j;
+
if(intruder_index == -1)
+
intruder_index = vect_j;
else
{
-
intruder_index = -1;
-
break;
+
intruder_index = -1;
+
break;
}
}
}

-
if(intruder_index != -1)
+
if(intruder_index != -1)
{
-
struct intruder_t intruder;
-
intruder.name_ = names[intruder_index];
-
intruder.why_ = inheritances[vect_i][class_i];
+
struct intruder_t intruder;
+
intruder.name_ = names[intruder_index];
+
intruder.why_ = inheritances[vect_i][class_i];

-
bool exist = false;
-
for(size_t i = 0; i < intruders.size(); i++)
-
if((intruders[i].name_ == intruder.name_) && (intruders[i].why_ == intruder.why_))
-
exist = true;
+
bool exist = false;
+
for(auto& intruder_i : intruders)
+
if((intruder_i.name_ == intruder.name_) && (intruder_i.why_ == intruder.why_))
+
exist = true;

-
if(exist == false)
-
intruders.push_back(intruder);
+
if(exist == false)
+
intruders.push_back(intruder);
}
}

-
return intruders;
+
return intruders;
}
@@ -344,14 +389,14 @@

Find the intruder

with the intruder display.

-
deleteTheSame(inheritances);
-
std::vector<struct intruder_t> intruders = find_intruder(names_, inheritances);
-
for(size_t i = 0; i < intruders.size(); i++)
-
say("the intruder is " + intruders[i].name_ + " because it is the only one that is not: " + intruders[i].why_);
+
deleteTheSame(inheritances);
+
std::vector<struct intruder_t> intruders = find_intruder(names_, inheritances);
+
for(auto& intruder : intruders)
+
say("the intruder is " + intruder.name_ + " because it is the only one that is not: " + intruder.why_);

Compile this and run the program, then in another terminal re-query the programs on the words: - bob alice and kevin.

+ bob, alice, and kevin.

This time, you should have this:

[SAY]on bob alice kevin
diff --git a/docs/cpp_Tutorials/tutorial1/LaunchTheProgram.html b/docs/cpp_Tutorials/tutorial1/LaunchTheProgram.html index 08873c5c..389ca4f3 100644 --- a/docs/cpp_Tutorials/tutorial1/LaunchTheProgram.html +++ b/docs/cpp_Tutorials/tutorial1/LaunchTheProgram.html @@ -4,10 +4,12 @@ Use inheritance for my first program (cpp) : Launch The Program + + @@ -142,12 +144,51 @@

Launch the program

One way that will seem obvious to us will be to launch our two programs independently like this:

terminal 1:

-
-
roslaunch ontologenius ontologenius.launch
+
+
+ + +
+ +
+
+
+
roslaunch ontologenius ontologenius.launch
+
+
+
+ +
+

terminal 2:

-
-
rosrun ontologenius_tutorial intruder
+
+
+ + +
+ +
+
+
+
rosrun ontologenius_tutorial intruder.py
+
+
+
+ +

However, Ontologenius has three launch parameters and by doing so we take the default @@ -169,40 +210,182 @@

Launch the program

Now that we've seen the parameters, let's look at the launch files that are available and that we can re-use.

    -
  • ontologenius.launch: It defines the working language as being English, +
  • ontologenius: It defines the working language as being English, it also defines an internal file and some input files to be able to realize some tests quickly.
  • -
  • ontologenius_empty.launch: It defines the working language as being English, +
  • ontologenius_empty: It defines the working language as being English, it also defines an internal file but does not define any input files.
  • -
  • ontologenius_full.launch: The parameters are the same as for - ontologenius.launch. The only difference is that the ontologenius GUI (ontoloGUI) is also launched.
  • +
  • ontologenius_full: The parameters are the same as for + ontologenius. The only difference is that the ontologenius GUI (ontoloGUI) is also launched.
-

For our application, we do not need the GUI so we will ontologenius.launch or ontologenius_empty.launch. +

For our application, we do not need the GUI so we will use ontologenius or ontologenius_empty. Indeed, we can use one or the other because we will in all cases redefine our own parameters.

Let's create our own launch file that will launch our application as well as ontologenius with our parameters:

-
-
<launch>
-
<node name="intruder" pkg="ontologenius_tutorial" type="intruder" output="screen"/>
-
<include file="$(find ontologenius)/launch/ontologenius.launch">
-
<arg name="intern_file" default="none"/>
-
<arg name="files" default="$(find ontologenius)/files/tutorials/tutorial_1.owl"/>
-
</include>
-
</launch>
-
- -

Let's call this file intruder.launch and put it in our package in the folder launch.

+
+
+ + + + +
+ +
+
+
+
<launch>
+
<node name="intruder" pkg="ontologenius_tutorial" type="intruder" output="screen"/>
+
<include file="$(find ontologenius)/launch/ontologenius.launch">
+
<arg name="intern_file" default="none"/>
+
<arg name="files" default="$(find ontologenius)/files/tutorials/tutorial_1.owl"/>
+
</include>
+
</launch>
+
+ +

Let's call this file intruder.launch and put it in our package in the folder launch.

+
+
+ + + + + + + +
-

We can see that we used the ontologenius.launch file by redefining the internal file +

We can see that we used an ontologenius launch file by redefining the internal file to not use it and putting the ontological file of this tutorial as an input file.

The ontolgy is given here, but you can also create your own ontology with protégé. Just think about exporting your ontology in XML / RDF format.

+
+
+ + +
+ +
+
+

You have no more things to do. This block is only for ROS2 users. + Take a break and just think about them struggling with ROS2. +

+
+
+ + +
+

I believe we are ready to launch our program:

-
-
roslaunch ontologenius_tutorial intruder.launch
+
+
+ + +
+ +
+
+
+
roslaunch ontologenius_tutorial intruder.launch
+
+
+
+ +

If all went well, you should have at the bottom of your terminal a section of which summarizes @@ -213,16 +396,56 @@

Launch the program

arborescence of those read by ontologenius.

So let's check if our topic works well with the following publications:

-
-
rostopic pub -1 /intruder/input std_msgs/String "data: 'bob'"
-
rostopic pub -1 /intruder/input std_msgs/String "data: 'alice'"
-
rostopic pub -1 /intruder/input std_msgs/String "data: 'kevin'"
+
+
+ + +
+ +
+
+
+
rostopic pub -1 /intruder/input std_msgs/String "data: 'bob'"
+
rostopic pub -1 /intruder/input std_msgs/String "data: 'alice'"
+
rostopic pub -1 /intruder/input std_msgs/String "data: 'kevin'"
+
+
+
+ +

Then ask to start the reasoning:

-
-
rostopic pub -1 /intruder/input std_msgs/String "data: 'start'"
+
+
+ + +
+ +
+
+
+
rostopic pub -1 /intruder/input std_msgs/String "data: 'start'"
+
+
+
+ +

You should have the following output that corresponds to the summary and loopback of the program.

diff --git a/docs/cpp_Tutorials/tutorial1/ManageTheMultilingual.html b/docs/cpp_Tutorials/tutorial1/ManageTheMultilingual.html index bbdd1259..e870b55f 100644 --- a/docs/cpp_Tutorials/tutorial1/ManageTheMultilingual.html +++ b/docs/cpp_Tutorials/tutorial1/ManageTheMultilingual.html @@ -4,10 +4,12 @@ Use inheritance for my first program (cpp) : Manage the multilingual + + @@ -171,26 +173,76 @@

find

We will therefore modify our callback function to realize the natural language transition to an identifier.

-
-
void wordCallback(const std_msgs::String& msg)
-
{
-
if(msg.data == "start")
-
start_ = true;
-
else
-
{
-
std::vector<std::string> ids = onto_->individuals.find(msg.data);
-
if(ids.size() == 0)
-
say("this word is unknown");
-
else if(std::find(names_.begin(), names_.end(), ids[0]) == names_.end())
-
names_.push_back(ids[0]);
-
}
-
}
+
+
+ + +
+ +
+
+
+
void wordCallback(const std_msgs::String& msg)
+
{
+
if(msg.data == "start")
+
start_ = true;
+
else
+
{
+
std::vector<std::string> ids = onto_->individuals.find(msg.data);
+
if(ids.size() == 0)
+
say("this word is unknown");
+
else if(std::find(names_.begin(), names_.end(), ids.front()) == names_.end())
+
names_.push_back(ids.front());
+
}
+
}
+
+
+
+ +

The find function is applied to individuals because we want individuals to input.

-
-
std::vector<std::string> ids = onto_->individuals.find(msg.data);
+
+
+ + +
+ +
+
+
+
std::vector<std::string> ids = onto_->individuals.find(msg.data);
+
+
+
+ +

We can test our program again with the words: "green cup", "blue cup" and "green book". We thus @@ -209,9 +261,9 @@

getName

The only thing we have to change is the display line as follows:

-
say("the intruder is " + onto.individuals.getName(intruders[i].name_)
-
+ " because it is the only one that is not: " +
-
onto.classes.getName(intruders[i].why_));
+
say("the intruder is " + onto.individuals.getName(intruder.name_)
+
+ " because it is the only one that is not: " +
+
onto.classes.getName(intruder.why_));

The result of our program becomes:

@@ -226,15 +278,110 @@

Multilingual

We will now modify our launch file to put the working language in french.

-
-
<launch>
-
<node name="intruder" pkg="ontologenius_tutorial" type="intruder" output="screen"/>
-
<include file="$(find ontologenius)/launch/ontologenius.launch">
-
<arg name="language" default="fr"/>
-
<arg name="intern_file" default="none"/>
-
<arg name="files" default="$(find ontologenius)/files/tutorials/tutorial_1.owl"/>
-
</include>
-
</launch>
+
+
+ + + + +
+ +
+
+
+
<launch>
+
<node name="intruder" pkg="ontologenius_tutorial" type="intruder" output="screen"/>
+
<include file="$(find ontologenius)/launch/ontologenius.launch">
+
<arg name="intern_file" default="none"/>
+
<arg name="language" default="fr"/>
+
<arg name="files" default="$(find ontologenius)/files/tutorials/tutorial_1.owl"/>
+
</include>
+
</launch>
+
+ +
+
+ + + + + + +

Well, that's it, our program will now work in French. You can test it with the words @@ -255,14 +402,14 @@

Go further

To go further, you can add the ability to change the working language with the setLang() function.

-
onto.actions.setLang("en");
+
onto.actions.setLang("en");

You can also change the display texts according to the language used by retrieving the language currently used with the getLang() function.

-
std::string lang = onto.actions.getLang();
+
std::string lang = onto.actions.getLang();

To obtain the identifier of a word in natural language, we used the function find, but ontologenius provides other functions to obtain an identifier from natural language. diff --git a/docs/cpp_Tutorials/tutorial1/MostRelevantIntruder.html b/docs/cpp_Tutorials/tutorial1/MostRelevantIntruder.html index e203c407..3a52d155 100644 --- a/docs/cpp_Tutorials/tutorial1/MostRelevantIntruder.html +++ b/docs/cpp_Tutorials/tutorial1/MostRelevantIntruder.html @@ -162,37 +162,37 @@

Find the most revelant intruder

especially because our goal is to find the reasons (which are classes) that overlap.

-
std::vector<struct intruder_t> refine(std::vector<struct intruder_t> intruders)
+
std::vector<struct intruder_t> refine(std::vector<struct intruder_t> intruders)
{
-
std::vector<struct intruder_t> refine_intruders;
-
for(size_t i = 0; i < intruders.size(); i++)
+
std::vector<struct intruder_t> refine_intruders;
+
for(size_t i = 0; i < intruders.size(); i++)
{
-
std::vector<std::string> down = onto_->classes.getDown(intruders[i].why_);
+
std::vector<std::string> down = onto_->classes.getDown(intruders[i].why_);

-
bool is_most_relevant = true;
-
for(size_t j = 0; j < intruders.size(); j++)
-
if((i != j) && (intruders[i].name_ == intruders[j].name_))
-
if(find(down.begin(), down.end(), intruders[j].why_) != down.end())
-
is_most_relevant = false;
+
bool is_most_relevant = true;
+
for(size_t j = 0; j < intruders.size(); j++)
+
if((i != j) && (intruders[i].name_ == intruders[j].name_))
+
if(find(down.begin(), down.end(), intruders[j].why_) != down.end())
+
is_most_relevant = false;

-
if(is_most_relevant == true)
-
refine_intruders.push_back(intruders[i]);
+
if(is_most_relevant == true)
+
refine_intruders.push_back(intruders[i]);
}
-
return refine_intruders;
+
return refine_intruders;
}

So we notice that we are going to look for the object classes of the ontology manipulator instead of the object individuals.

-
std::vector<std::string> down = onto_->classes.getDown(intruders[i].why_);
+
std::vector<std::string> down = onto_->classes.getDown(intruders[i].why_);

The getUp function is available for individuals, classes, and properties while the getDown function is only available for classes and properties.

We can call our refining function in our main function just after the function to find intruders

-
std::vector<struct intruder_t> intruders = find_intruder(names_, inheritances);
-
intruders = refine(intruders);
+
std::vector<struct intruder_t> intruders = find_intruder(names_, inheritances);
+
intruders = refine(intruders);

Re-interrogating our program with the words pr2, kevin, and bob, we now have the following result:

diff --git a/docs/cpp_Tutorials/tutorial1/settingUpTheProgram.html b/docs/cpp_Tutorials/tutorial1/settingUpTheProgram.html index adfa0d66..17f28fe1 100644 --- a/docs/cpp_Tutorials/tutorial1/settingUpTheProgram.html +++ b/docs/cpp_Tutorials/tutorial1/settingUpTheProgram.html @@ -4,10 +4,12 @@ Use inheritance for my first program (cpp) : Setting up the program + + @@ -149,56 +151,134 @@

Setting up the program

In this part, we will code the bases of our program from which we will be able to write the more algorithmic part. Before that, I invite you to create a new package that we will call "ontologenius_tutorial" - and which will contain only one source file that we will name "main.cpp". To be sure that your + and which will contain only one source file that we will name "intruder.cpp". To be sure that your new package will be well configured to use Ontologenius, we advise you to follow this guide. We will just rename our executable "intruder" because it is much more logical than "my_exe".

-
-
add_executable(intruder src/main.cpp)
-
target_link_libraries(intruder ${ontologenius_LIBRARIES})
+
+
+ + +
+ +
+
+
+
add_executable(intruder src/intruder.cpp)
+
target_link_libraries(intruder ${ontologenius_LIBRARIES})
+
+
+
+ +

Now we are ready! Let's open our main file and start coding:

-
-
#include <iostream>
-
#include <vector>
-
#include <string>
-

- -
#include "ros/ros.h"
-
#include "std_msgs/String.h"
-
#include "ontologenius/OntologyManipulator.h"
-

- -
onto::OntologyManipulator* onto_;
-
std::vector<std::string> names_;
-
bool start_;
-

- -
void say(std::string text)
-
{
-
std::cout << "[SAY]" << text << std::endl;
-
}
-

- -
std::string summarize(std::vector<std::string> words)
-
{
-
std::string to_say = "on ";
-
for(size_t i = 0; i < words.size(); i++)
-
to_say += words[i] + " ";
-
return to_say;
-
}
-

- -
void wordCallback(const std_msgs::String& msg)
-
{
-
if(msg.data == "start")
-
start_ = true;
-
else if(std::find(names_.begin(), names_.end(), msg.data) == names_.end())
-
names_.push_back(msg.data);
-
}
-

+
+
+ + +
+ +
+
+
+
#include <iostream>
+
#include <vector>
+
#include <string>
+

+ +
#include "ros/ros.h"
+
#include "std_msgs/String.h"
+
#include "ontologenius/OntologyManipulator.h"
+

+ +
onto::OntologyManipulator* onto_;
+
std::vector<std::string> names_;
+
bool start_;
+

+ +
void say(const std::string& text)
+
{
+
std::cout << "[SAY]" << text << std::endl;
+
}
+

+ +
std::string summarize(std::vector<std::string> words)
+
{
+
std::string to_say = "on ";
+
for(size_t i = 0; i < words.size(); i++)
+
to_say += words[i] + " ";
+
return to_say;
+
}
+

+ +
void wordCallback(const std_msgs::String& msg)
+
{
+
if(msg.data == "start")
+
start_ = true;
+
else if(std::find(names_.begin(), names_.end(), msg.data) == names_.end())
+
names_.push_back(msg.data);
+
}
+

+
+
+
+ +

Take a break here, we have already written a lot. We will go over all this in detail to better @@ -206,15 +286,40 @@

Setting up the program

First of all, we have all the inclusions we need, like iostream to display messages on the screen, then vectors and strings to get vectors and strings ...

-
-
#include "ros/ros.h"
-
-

ros/ros.h is a convenience include that includes all the headers necessary to use the most common - public pieces of the ROS system.

-
-
#include "std_msgs/String.h"
+
+
+ + +
+ +
+
+
+
#include "ros/ros.h"
+
+

ros/ros.h is a convenience include that includes all the headers necessary to use the most common public pieces of the ROS system.

+ +
+
#include "std_msgs/String.h"
+
+
+
+ +
-

This includes the std_msgs/String message, which resides in the std_msgs ROS package. We use + +

This includes the ROS String message, which resides in the std_msgs ROS package. We use it to create a topic on which we will send the words from which our program will have to find the intruder.

@@ -225,7 +330,7 @@

Setting up the program

documentation for this object on the left panel.

-
onto::OntologyManipulator* onto_;
+
onto::OntologyManipulator* onto_;

As explained above, the ontology manipulator contains several objects to abstract ROS services. The set of services work in a connected mode which allows to greatly save in execution time but @@ -238,31 +343,51 @@

Setting up the program

instance of a manipulator because it needs a pointer to a NodeHandle of ROS.

-
std::vector<std::string> names_;
+
std::vector<std::string> names_;

This vector will allow us to store the different words on which we will perform our search for the intruder.

-
bool start_;
+
bool start_;

This is our synchronization variable. This variable will be false as long as we continue to collect words and we will put it in the true state as long as we wish to start the search for the intruder.

-
void say(std::string text)
+
void say(const std::string& text)

Here, the say function is actually just an on-screen display, but you can customize it to use a TTS for example.

-
std::string summarize(std::vector<std::string> words)
+
std::string summarize(std::vector<std::string> words)

Here, the summarize function concatenates several words in a single string. We created this function just to make our main function more readable.

-
-
void wordCallback(const std_msgs::String& msg)
-
+
+
+ + +
+ +
+
+
+
void wordCallback(const std_msgs::String& msg)
+
+
+
+ + +
+

Here we have the callback function of our input topic. This topic thus receives strings which will be the words from which our program will have to find the intruder. Inside the function, we can see that we use the word "start" as a synchronization word that will launch our reasoning. @@ -273,122 +398,285 @@

Setting up the program



We have everything we need to start writing the main function to retrieve the list of words to work on and start the reasoning although we do not have it yet.

-
-
int main(int argc, char** argv)
-
{
-
ros::init(argc, argv, "intruder");
-

-
ros::NodeHandle n;
-
onto::OntologyManipulator onto;
-
onto_ = &onto;
-

-
onto.close();
-

-
ros::Subscriber sub = n.subscribe("intruder/input", 1, wordCallback);
-
ros::Rate r(100); // 10 hz
-

-
while(ros::ok())
-
{
-
start_ = false;
-

-
say("Let's play!");
-

-
while((start_ == false) && ros::ok())
-
{
-
ros::spinOnce();
-
r.sleep();
-
}
-

-
say(summarize(names_));
-

-
/*
-
We will find the intruder here
-
*/
-

-
names_.clear();
-
}
-

-
return 0;
-
}
+
+
+ + +
+ +
+
+
+
int main(int argc, char** argv)
+
{
+
ros::init(argc, argv, "intruder");
+

+
onto::OntologyManipulator onto;
+
onto_ = &onto;
+

+
onto.close();
+

+
ros::NodeHandle n;
+
ros::Subscriber sub = n.subscribe("intruder/input", 10, wordCallback);
+
ros::Rate r(100);
+

+
while(ros::ok())
+
{
+
start_ = false;
+

+
say("Let's play!");
+

+
while((start_ == false) && ros::ok())
+
{
+
ros::spinOnce();
+
r.sleep();
+
}
+

+
say(summarize(names_));
+

+
/*
+
We will find the intruder here
+
*/
+

+
names_.clear();
+
}
+

+
return 0;
+
}
+
+
+
+ +

Now, let's break the code down.

-
-
ros::init(argc, argv, "intruder");
-

-
ros::NodeHandle n;
+
+
+ + +
+ +
+
+
+
ros::init(argc, argv, "intruder");
+
+
+
+ +
-

Initialize ROS and Create a handle to this process' node.

+

Initialize ROS.

-
-
onto::OntologyManipulator onto;
-
onto_ = &onto;
+
+
onto::OntologyManipulator onto;
+
onto_ = &onto;

We finally come back to using ontologenius! We create here our first manipulator ontology, what a great day ... This manipulator is unique to fully enjoy the benefits of connected services.

We do not forget to initialize the pointer on the manipulator by providing the address.

-
-
onto.close();
+
+
onto.close();

The close function link all the concepts loaded from files and the Internet. Before closing an ontology, exploration requests are not allowed.

-
-
onto.actions.fadd("path/to/may/file.owl");
+
+
onto.actions.fadd("path/to/may/file.owl");
// OR
-
onto.actions.add("http://path/to/my/file.owl");
-
onto.close();
+
onto.actions.add("http://path/to/my/file.owl");
+
onto.close();

For the moment, we are going to consider that the ontological file we are going to work on is provided in the ontologenius launcher. We will configure it in the next part of the tutorial. It is also possible to load files directly from the program (as above) but in doing so it makes our code less reusable.

-
-
ros::Subscriber sub = n.subscribe("intruder/input", 1, wordCallback);
-
-

We initialise our subscriber to the topic "intruder/input". We also - link this topic to our callback function.

- -
-
while(ros::ok())
+
+
+ + +
+ +
+
+
+
ros::Subscriber sub = n.subscribe("intruder/input", 10, wordCallback);
+
+ +

We initialise our subscriber to the topic "intruder/input". We also link this topic to our callback function.

+ +
+
while(ros::ok())
+
+
+
+ +
+

Just our almost infinite loop. Escaping with a Ctrl + C.

-
-
start_ = false;
+
+
start_ = false;

-
say("Let's play!");
+
say("Let's play!");

We initialize the synchronization variable and inform the user that the program is ready to listen to the words.

-
-
while((start_ == false) && ros::ok())
+
+
+ + +
+ +
+
+
+
while((start_ == false) && ros::ok())
+
+

ros::spinOnce() is there to allow us to receive messages and r.sleep() avoids unnecessary use of the processor.

+
+
+ +

We only wait for the synchronisation...

-

ros::spinOnce() is there to allow us to receive messages via the subject and r.sleep() - avoids unnecessary use of the processor.

-
-
say(summarize(names_));
+
+
say(summarize(names_));

We recall the words on which we will make the reasoning. It is just as a result of this that we will implement our reasoning.

-
-
names_.clear();
+
+
names_.clear();

Our loop is over, we can erase the words we used and start over!

Now, you just have to compile that before going on to the following:

-
-
catkin_make
+
+
+ + +
+ +
+
+
+
catkin_make
+
+
+
+ +
-

Do not forget that this command must be done in your catkin workspace

+

Do not forget that this command must be done in your workspace