RCL - RoboCLuedo  v1.0
Francesco Ganci - S4143910 - Experimental Robotics Lab - Assignment 1
cluedo_armor_interface.cpp
Go to the documentation of this file.
1 
2 
64 #include "ros/ros.h"
67 
68 #include "std_srvs/Trigger.h"
69 #include "armor_msgs/ArmorDirective.h"
70 #include "armor_msgs/ArmorDirectiveList.h"
71 #include "armor_msgs/ArmorDirectiveReq.h"
72 #include "armor_msgs/ArmorDirectiveRes.h"
73 #include "armor_msgs/QueryItem.h"
74 #include "robocluedo_msgs/AddHint.h"
75 #include "robocluedo_msgs/Hypothesis.h"
76 #include "robocluedo_msgs/FindConsistentHypotheses.h"
77 #include "robocluedo_msgs/DiscardHypothesis.h"
78 
79 #include <iostream>
80 #include <fstream>
81 #include <string>
82 #include <vector>
83 
84 #define SERVICE_INTERFACE_ADD_HINT "/cluedo_armor/add_hint"
85 #define SERVICE_INTERFACE_FIND_CONSISTENT_HYP "/cluedo_armor/find_consistent_h"
86 #define SERVICE_INTERFACE_WRONG_HYPOTHESIS "/cluedo_armor/wrong_hypothesis"
87 #define SERVICE_INTERFACE_SAVE_ONTOLOGY "/cluedo_armor/backup"
88 
89 #define ONTOLOGY_PARAM "cluedo_path_owlfile"
90 #define PARAM_ONTOLOGY_BACKUP_PATH "cluedo_path_owlfile_backup"
91 #define OUTLABEL "[cluedo_armor_interface]"
92 #define OUTLOG( msg ) ROS_INFO_STREAM( OUTLABEL << " " << msg );
93 #define LOGSQUARE( str ) "[" << str << "] "
94 #define SS( this_string ) std::string( this_string )
95 #define SSS( this_thing ) std::to_string( this_thing )
96 
97 
98 
100 ArmorCluedo* armor;
101 
102 
103 
105 bool fileExist( std::string path )
106 {
107  return (std::ifstream(path)).good();
108 }
109 
110 
111 
112 
125 std::vector<std::string> PerformDifferenceBetween( std::vector<std::string> list1, std::vector<std::string> list2 )
126 {
127  std::vector<std::string> to_return;
128 
129  for( auto it1 = list1.begin(); it1 != list1.end(); ++it1 )
130  {
131  bool found = false;
132  for( auto it2 = list2.begin(); it2 != list2.end(); ++it2 )
133  {
134  if( *it2 == *it1 )
135  {
136  found = true;
137  break;
138  }
139  }
140 
141  if( !found )
142  to_return.push_back( *it1 );
143  }
144 
145  return to_return;
146 }
147 
148 
149 
150 
174 bool ServiceAddHint( robocluedo_msgs::AddHint::Request& hint, robocluedo_msgs::AddHint::Response& success )
175 {
176  OUTLOG( "called service " << SERVICE_INTERFACE_ADD_HINT );
177 
178  // check for the existence of the given hypothesis ID (in case, create it)
179  std::string hypname = "";
180  hypname += SS("HP") + SSS( hint.hypID );
181  if( !armor->ExistsIndiv( hypname ) )
182  armor->AddIndiv( hypname, "HYPOTHESIS", false );
183 
184  // if the Belem is not defined, add it
185  if( !armor->ExistsIndiv( hint.Belem ) )
186  {
187  if( hint.property == "where" )
188  armor->AddIndiv( hint.Belem, "PLACE" );
189  else if( hint.property == "who" )
190  armor->AddIndiv( hint.Belem, "PERSON" );
191  else if( hint.property == "what" )
192  armor->AddIndiv( hint.Belem, "WEAPON" );
193  else
194  {
195  OUTLOG( "ERROR: not a valid hint property." );
196  success.success = false;
197 
198  return true;
199  }
200  }
201 
202  // add the predicate
203  OUTLOG( "set object property " << "(" << hypname << ", " << hint.Belem << "):" << hint.property );
204  armor->SetObjectProperty( hint.property, hypname, hint.Belem );
205 
206  // perform the update
207  armor->UpdateOntology( );
208 
209  success.success = true;
210  return true;
211 }
212 
213 
214 
215 
229 bool ServiceFindConsistentHypotheses( robocluedo_msgs::FindConsistentHypotheses::Request& empty, robocluedo_msgs::FindConsistentHypotheses::Response& hyplist )
230 {
231  OUTLOG( "called service " << SERVICE_INTERFACE_FIND_CONSISTENT_HYP );
232 
233  // perform the update before starting
234  armor->UpdateOntology( );
235 
236  std::vector<std::string> list_to_return;
237  {
238  // get all the consistent hypotheses
239  std::vector<std::string> consistent_hyp = armor->FindCompleteHypotheses( );
240 
241  // get the inconsistent hypotheses
242  std::vector<std::string> inconsistent_hyp = armor->FindInconsistentHypotheses( );
243 
244  // remove the intersection between the two arrays
245  list_to_return = PerformDifferenceBetween( consistent_hyp, inconsistent_hyp );
246  }
247 
248  // expand the list
249  hyplist.hyp = std::vector<robocluedo_msgs::Hypothesis>( );
250  robocluedo_msgs::Hypothesis h;
251  for( std::string hptag : list_to_return )
252  {
253  h.tag = hptag;
254  h.who = armor->GetValuedOfIndiv( "who", hptag )[0];
255  h.where = armor->GetValuedOfIndiv( "where", hptag )[0];
256  h.what = armor->GetValuedOfIndiv( "what", hptag )[0];
257 
258  hyplist.hyp.push_back( h );
259  }
260 
261  return true;
262 }
263 
264 
265 
266 
279 bool DiscardHypothesis( robocluedo_msgs::DiscardHypothesis::Request& tag, robocluedo_msgs::DiscardHypothesis::Response& success )
280 {
281  OUTLOG( "called service " << SERVICE_INTERFACE_WRONG_HYPOTHESIS );
282 
283  // remove the hypothesis from the database
284  success.success = armor->RemoveHypothesis( tag.hypothesisTag );
285 
286  return true;
287 }
288 
289 
290 
291 
306 bool ServiceBackupOntology( std_srvs::Trigger::Request& emptyrequest, std_srvs::Trigger::Response& success )
307 {
308  OUTLOG( "called service " << SERVICE_INTERFACE_SAVE_ONTOLOGY );
309 
310  if( !ros::param::has( PARAM_ONTOLOGY_BACKUP_PATH ) )
311  {
312  success.success = false;
313  success.message = SS( "unable to find the parameter" ) + SS( PARAM_ONTOLOGY_BACKUP_PATH );
314 
315  OUTLOG( "ERROR: " << success.message );
316  }
317  else
318  {
319  std::string save_path;
320  ros::param::get( PARAM_ONTOLOGY_BACKUP_PATH, save_path );
321  armor->SaveOntology( save_path );
322  success.success = true;
323 
324  OUTLOG( "Ontology save here -> " << save_path );
325  }
326 
327  return true;
328 }
329 
330 
331 
332 
340 int main( int argc, char* argv[] )
341 {
342  ros::init( argc, argv, "cluedo_armor_interface" );
343  ros::NodeHandle nh;
344 
345  // percorso della oltology da parameter server
346  std::string ontology_file_path;
347  if( !ros::param::has( ONTOLOGY_PARAM ) )
348  {
349  OUTLOG( "ERROR: parameter '" << ONTOLOGY_PARAM << "' not defined." );
350  return 0;
351  }
352  ros::param::get( ONTOLOGY_PARAM, ontology_file_path );
353  if( !fileExist( ontology_file_path ) )
354  {
355  OUTLOG( "ERROR: the file '" << ONTOLOGY_PARAM << "' doesn't exist." );
356  return 0;
357  }
358  OUTLOG( "Ontology found! " << LOGSQUARE( ontology_file_path ) );
359 
360  // connessione ad aRMOR
361  OUTLOG( "loading armor ..." );
362  ArmorCluedo armorcluedo;
363  if( !armorcluedo.Init( ontology_file_path ) || !armorcluedo.TestInterface( ) )
364  {
365  OUTLOG( "ERROR: unable to load aRMOR!" );
366  return 0;
367  }
368  armor = &armorcluedo;
369  OUTLOG( "OK!" );
370 
371  // servizio per registrare un hint dall'oracolo
372  OUTLOG( "opening server " << LOGSQUARE( SERVICE_INTERFACE_ADD_HINT ) << " ..." );
373  ros::ServiceServer srv_add_hint = nh.advertiseService( SERVICE_INTERFACE_ADD_HINT , ServiceAddHint );
374  OUTLOG( "OK!" );
375 
376  // servizio per ottenere tutte le ipotesi consistenti
377  OUTLOG( "opening server " << LOGSQUARE( SERVICE_INTERFACE_FIND_CONSISTENT_HYP ) << " ..." );
378  ros::ServiceServer srv_find_cons_hyp = nh.advertiseService( SERVICE_INTERFACE_FIND_CONSISTENT_HYP, ServiceFindConsistentHypotheses );
379  OUTLOG( "OK!" );
380 
381  // servizio per scartare ipotesi
382  OUTLOG( "opening server " << LOGSQUARE( SERVICE_INTERFACE_WRONG_HYPOTHESIS ) << " ..." );
383  ros::ServiceServer srv_wrong_hyp = nh.advertiseService( SERVICE_INTERFACE_WRONG_HYPOTHESIS, DiscardHypothesis );
384  OUTLOG( "OK!" );
385 
386  // servizio per scaricare la ontology su file
387  OUTLOG( "opening server " << LOGSQUARE( SERVICE_INTERFACE_SAVE_ONTOLOGY ) << " ..." );
388  ros::ServiceServer srv_backup = nh.advertiseService( SERVICE_INTERFACE_SAVE_ONTOLOGY, ServiceBackupOntology );
389  OUTLOG( "OK!" );
390 
391  // spin
392  OUTLOG( "ready!" );
393  ros::spin( );
394 
395  return 0;
396 }
SERVICE_INTERFACE_WRONG_HYPOTHESIS
#define SERVICE_INTERFACE_WRONG_HYPOTHESIS
Definition: cluedo_armor_interface.cpp:86
ArmorCluedo::AddIndiv
bool AddIndiv(std::string indivname, std::string classname, bool makeDisjoint=true)
add an individual to the ontology
Definition: armor_cluedo.cpp:53
SERVICE_INTERFACE_FIND_CONSISTENT_HYP
#define SERVICE_INTERFACE_FIND_CONSISTENT_HYP
Definition: cluedo_armor_interface.cpp:85
ONTOLOGY_PARAM
#define ONTOLOGY_PARAM
Definition: cluedo_armor_interface.cpp:89
armor_cluedo.h
additional aRMOR C++ interface
ArmorCluedo::SetObjectProperty
bool SetObjectProperty(std::string prop, std::string Aelem, std::string Belem)
set a property true
Definition: armor_cluedo.cpp:131
SERVICE_INTERFACE_SAVE_ONTOLOGY
#define SERVICE_INTERFACE_SAVE_ONTOLOGY
Definition: cluedo_armor_interface.cpp:87
ArmorCluedo::Init
bool Init(std::string ontologyPath)
initizalize the interface
Definition: armor_cluedo.cpp:34
ArmorCluedo::GetValuedOfIndiv
std::vector< std::string > GetValuedOfIndiv(std::string prop, std::string indivname)
get the values of a property related to a gven individual
Definition: armor_cluedo.cpp:150
PARAM_ONTOLOGY_BACKUP_PATH
#define PARAM_ONTOLOGY_BACKUP_PATH
Definition: cluedo_armor_interface.cpp:90
ServiceBackupOntology
bool ServiceBackupOntology(std_srvs::Trigger::Request &emptyrequest, std_srvs::Trigger::Response &success)
implementation of service SERVICE_INTERFACE_SAVE_ONTOLOGY
Definition: cluedo_armor_interface.cpp:306
SSS
#define SSS(this_thing)
Definition: cluedo_armor_interface.cpp:95
ServiceAddHint
bool ServiceAddHint(robocluedo_msgs::AddHint::Request &hint, robocluedo_msgs::AddHint::Response &success)
implementation of service SERVICE_INTERFACE_ADD_HINT
Definition: cluedo_armor_interface.cpp:174
ArmorTools::TestInterface
bool TestInterface()
check the status of the interface
Definition: armor_tools.cpp:351
ArmorTools::UpdateOntology
bool UpdateOntology()
send the command REASON
Definition: armor_tools.cpp:246
LOGSQUARE
#define LOGSQUARE(str)
Definition: cluedo_armor_interface.cpp:93
ArmorCluedo::FindInconsistentHypotheses
std::vector< std::string > FindInconsistentHypotheses()
find all the inconsistent hypotheses
Definition: armor_cluedo.cpp:184
main
int main(int argc, char *argv[])
ROS node main.
Definition: cluedo_armor_interface.cpp:340
ArmorCluedo
additional utilities for aRMOR
Definition: armor_cluedo.h:56
DiscardHypothesis
bool DiscardHypothesis(robocluedo_msgs::DiscardHypothesis::Request &tag, robocluedo_msgs::DiscardHypothesis::Response &success)
implementation of service SERVICE_INTERFACE_WRONG_HYPOTHESIS
Definition: cluedo_armor_interface.cpp:279
robocluedo_main.hint
hint
the message from the oracle, if any
Definition: robocluedo_main.py:131
ArmorTools::SaveOntology
bool SaveOntology(std::string path)
save the ontology on file
Definition: armor_tools.cpp:231
OUTLOG
#define OUTLOG(msg)
Definition: cluedo_armor_interface.cpp:92
ServiceFindConsistentHypotheses
bool ServiceFindConsistentHypotheses(robocluedo_msgs::FindConsistentHypotheses::Request &empty, robocluedo_msgs::FindConsistentHypotheses::Response &hyplist)
implementation of service SERVICE_INTERFACE_FIND_CONSISTENT_HYP
Definition: cluedo_armor_interface.cpp:229
ArmorCluedo::ExistsIndiv
bool ExistsIndiv(std::string indivname)
check if an individual exists
Definition: armor_cluedo.cpp:112
armor_tools.h
A minimal C++ client for aRMOR.
SS
#define SS(this_string)
Definition: cluedo_armor_interface.cpp:94
SERVICE_INTERFACE_ADD_HINT
#define SERVICE_INTERFACE_ADD_HINT
Definition: cluedo_armor_interface.cpp:84
ArmorCluedo::RemoveHypothesis
bool RemoveHypothesis(std::string hypTag)
discard one hypothesis
Definition: armor_cluedo.cpp:192
ArmorCluedo::FindCompleteHypotheses
std::vector< std::string > FindCompleteHypotheses()
find all the complete hypotheses
Definition: armor_cluedo.cpp:165
PerformDifferenceBetween
std::vector< std::string > PerformDifferenceBetween(std::vector< std::string > list1, std::vector< std::string > list2)
delete all the occurrences of list2 inside list1
Definition: cluedo_armor_interface.cpp:125