speech
All Data Structures Functions Modules Pages
start-inspect.cpp
1 /*
2  * Copyright (C) 2017 Department of Robotics Brain and Cognitive Sciences - Istituto Italiano di Tecnologia
3  * Author: Vadim Tikhanoff
4  * email: vadim.tikhanoff@iit.it
5  * Permission is granted to copy, distribute, and/or modify this program
6  * under the terms of the GNU General Public License, version 2 or any
7  * later version published by the Free Software Foundation.
8  *
9  * A copy of the license can be found at
10  * http://www.robotcub.org/icub/license/gpl.txt
11  *
12  * This program is distributed in the hope that it will be useful, but
13  * WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
15  * Public License for more details
16  */
17 
18 #include "start-inspect.h"
19 #include <yarp/os/Log.h>
20 #include <yarp/os/LogStream.h>
21 
22 /**********************************************************/
23 bool STARTModule::configure(yarp::os::ResourceFinder &rf)
24 {
25  moduleName = rf.check("name", yarp::os::Value("interpretSTART"), "module name (string)").asString();
26 
27  setName(moduleName.c_str());
28 
29  handlerPortName = "/";
30  handlerPortName += getName();
31  handlerPortName += "/rpc:i";
32 
33  if (!rpcPort.open(handlerPortName.c_str()))
34  {
35  yError( "%s : Unable to open port %s\n", getName().c_str(), handlerPortName.c_str());
36  return false;
37  }
38 
39  attach(rpcPort);
40 
41  /* create the thread and pass pointers to the module parameters */
42  startManager = new STARTManager( moduleName );
43 
44  /* now start the thread to do the work */
45  startManager->open();
46 
47  return true ;
48 }
49 
50 /**********************************************************/
51 bool STARTModule::interruptModule()
52 {
53  rpcPort.interrupt();
54  return true;
55 }
56 
57 /**********************************************************/
58 bool STARTModule::close()
59 {
60  rpcPort.close();
61  yInfo( "starting the shutdown procedure\n");
62  startManager->interrupt();
63  startManager->close();
64  yInfo( "deleting thread\n");
65  delete startManager;
66  yInfo( "done deleting thread\n");
67  return true;
68 }
69 
70 /**********************************************************/
71 bool STARTModule::updateModule()
72 {
73  return !closing;
74 }
75 
76 /**********************************************************/
77 double STARTModule::getPeriod()
78 {
79  return 0.1;
80 }
81 
82 /**********************************************************/
83 STARTManager::~STARTManager()
84 {
85 
86 }
87 
88 /**********************************************************/
89 STARTManager::STARTManager( const std::string &moduleName )
90 {
91  yInfo("initialising Variables\n");
92  this->moduleName = moduleName;
93  objectDetails = NULL;
94 }
95 
96 /**********************************************************/
97 bool STARTManager::open()
98 {
99  this->useCallback();
100 
101  //create all ports
102  inSpeechPortName = "/" + moduleName + "/speech:i";
103  BufferedPort<yarp::os::Bottle >::open( inSpeechPortName.c_str() );
104 
105  outSTARTPortName = "/" + moduleName + "/start:o";
106  startOutPort.open( outSTARTPortName.c_str() );
107 
108  yarp::os::Network::connect("/start-speech/start:o", inSpeechPortName);
109 
110  return true;
111 }
112 
113 /**********************************************************/
114 void STARTManager::close()
115 {
116  yInfo("now closing ports...\n");
117  startOutPort.close();
118  BufferedPort<yarp::os::Bottle >::close();
119  yInfo("finished closing the read port...\n");
120 }
121 
122 /**********************************************************/
123 void STARTManager::interrupt()
124 {
125  yInfo("cleaning up...\n");
126  yInfo("attempting to interrupt ports\n");
127  BufferedPort<yarp::os::Bottle >::interrupt();
128  yInfo("finished interrupt ports\n");
129 }
130 
131 /**********************************************************/
132 void STARTManager::onRead(yarp::os::Bottle &bot)
133 {
134  yarp::os::Bottle &final = startOutPort.prepare();
135  final.clear();
136 
137  yInfo("bot size = %d", bot.size());
138 
139  std::vector<std::string> action;
140  std::string query = bot.get(0).asList()->toString();
141 
142  if (bot.size() == 1)
143  {
144 
145  yInfo("Got a special query: %s ", query.c_str());
146  action.push_back( bot.get(0).asList()->get(0).asString().c_str());
147  yarp::os::Bottle &list = final.addList();
148  yarp::os::Bottle &actList = list.addList();
149  actList.addString("verb");
150  action[0][0] = toupper(action[0][0]); // Make first characther upper case
151  actList.addString(action[0].c_str());
152 
153  }
154  else
155  {
156  yInfo("Got a new query: %s ", query.c_str());
157 
158  size_t sizeBot = bot.get(1).asList()->size();
159 
160  objectDetails = new Object [bot.get(0).asList()->size()];
161 
162  std::vector<std::string> subject;
163 
164  int numObjects = 0;
165  int numActions = 0;
166  std::string tmpString;
167  std::string location;
168  std::string tmpAction;
169 
170  // 1 - check for objects in list (hasdet definite)
171  // 2 - add actions
172  for (size_t i=0; i< sizeBot; i++)
173  {
174 
175  std::string param1 = bot.get(1).asList()->get(i).asList()->get(1).asString().c_str();
176  std::string param2 = bot.get(1).asList()->get(i).asList()->get(2).asString().c_str();
177 
178  if (strcmp(param1.c_str(), "hasdet") == 0 && (strcmp(param2.c_str(), "definite") == 0 || strcmp(param2.c_str(), "indefinite") == 0) ){
179  objectDetails[numObjects].name = bot.get(1).asList()->get(i).asList()->get(0).asString().c_str();
180  numObjects ++;
181  }
182 
183  if (strcmp(param1.c_str(), "ismain") == 0 && strcmp(param2.c_str(), "Yes") == 0){
184  action.push_back(bot.get(1).asList()->get(i).asList()->get(0).asString().c_str());
185  tmpString = action[numActions].c_str();
186  numActions++;
187 
188  for (int y=0; y<numActions; y++){
189 
190  if (strcmp(action[y].c_str(), "be" ) == 0){
191  for (size_t i=0; i< sizeBot; i++){
192  std::string param1 = bot.get(1).asList()->get(i).asList()->get(0).asString().c_str();
193  std::string param2 = bot.get(1).asList()->get(i).asList()->get(1).asString().c_str();
194  if (strcmp(param1.c_str(), action[y].c_str()) == 0 && strcmp(param2.c_str(), "haslocation") == 0){
195  action.erase(std::remove(action.begin(), action.end(), tmpString), action.end());
196  action.push_back(bot.get(1).asList()->get(i).asList()->get(2).asString().c_str());
197  }
198  }
199  }
200  if (strcmp(action[y].c_str(), "isa" ) == 0){
201  for (size_t i=0; i< sizeBot; i++){
202  std::string param1 = bot.get(1).asList()->get(i).asList()->get(1).asString().c_str();
203  std::string param2 = bot.get(1).asList()->get(i).asList()->get(2).asString().c_str();
204  if (strcmp(param1.c_str(), action[y].c_str()) == 0){
205  action.erase(std::remove(action.begin(), action.end(), tmpString), action.end());
206  action.push_back(param2.c_str());
207  }
208  }
209  }
210 
211  for (size_t i=0; i< sizeBot; i++){
212  std::string param1 = bot.get(1).asList()->get(i).asList()->get(0).asString().c_str();
213  std::string param2 = bot.get(1).asList()->get(i).asList()->get(1).asString().c_str();
214  std::string param3 = bot.get(1).asList()->get(i).asList()->get(2).asString().c_str();
215 
216  if (strcmp(param1.c_str(), action[y].c_str()) == 0 && (strcmp(param2.c_str(), "to") == 0 || (strcmp(param2.c_str(), "on") == 0) || (strcmp(param2.c_str(), "from") == 0))){
217  yInfo(" action %s param1 %s param2 %s param3 %s", action[y].c_str(), param1.c_str(), param2.c_str(), param3.c_str());
218 
219  tmpAction = action[y].c_str();
220  //making first character upper case for later comparison
221  tmpAction[0] = toupper(tmpAction[0]);
222  location = param3.c_str();
223 
224  }
225  }
226  }
227  }
228  }
229 
230  // Fill in the subjects
231  //making sure that objects and actions are the same
232  if (numActions > numObjects){
233  numObjects ++;
234  objectDetails[numObjects-(numObjects/2)].name = objectDetails[numObjects-numObjects].name.c_str();
235  }
236 
237  for (int y=0; y< numActions; y++){
238  for (size_t i=0; i< sizeBot; i++){
239  std::string param1 = bot.get(1).asList()->get(i).asList()->get(0).asString().c_str();
240  std::string param2 = bot.get(1).asList()->get(i).asList()->get(1).asString().c_str();
241  std::string param3 = bot.get(1).asList()->get(i).asList()->get(2).asString().c_str();
242 
243  if (strcmp(param2.c_str(), action[y].c_str()) == 0 && strcmp(param3.c_str(), objectDetails[y].name.c_str()) == 0){
244  subject.push_back(param1.c_str());
245  break;
246  }
247  }
248  }
249 
250  //yInfo("num objs %d", subject.size());
251 
252  if (subject.size() < 1)
253  subject.push_back("you");
254 
255  subject.erase(std::remove(subject.begin(), subject.end(), ""), subject.end());
256  subject.push_back("you");
257 
258  for (size_t y=0; y< subject.size(); y++){
259  for (size_t i=0; i< sizeBot; i++){
260  std::string param1 = bot.get(1).asList()->get(i).asList()->get(0).asString().c_str();
261  std::string param2 = bot.get(1).asList()->get(i).asList()->get(1).asString().c_str();
262  std::string param3 = bot.get(1).asList()->get(i).asList()->get(2).asString().c_str();
263 
264  //yInfo("%s %s ", param1.c_str(), subject[y].c_str());
265  if (strcmp(param1.c_str(), subject[y].c_str()) == 0 && strcmp(param2.c_str(), "hasproperty") == 0){
266  //yInfo("in here");
267  std::string adj = param3.c_str();
268 
269  for (size_t i=0; i< sizeBot; i++){
270  std::string param1 = bot.get(1).asList()->get(i).asList()->get(0).asString().c_str();
271  std::string param2 = bot.get(1).asList()->get(i).asList()->get(1).asString().c_str();
272  std::string param3 = bot.get(1).asList()->get(i).asList()->get(2).asString().c_str();
273 
274  if (strcmp(param1.c_str(), adj.c_str()) == 0 && strcmp(param2.c_str(), "hascategory") == 0 && strcmp(param3.c_str(), "adj") == 0){
275  //yInfo("%s is an adjective, adding it as a parameter of %s", param1.c_str(), subject[y].c_str());
276  }
277  }
278  }
279  }
280  }
281 
282  // if no objects are found it might be that the query is particular therefore need to check if property is available instead
283  if (numObjects<1){
284  for (size_t i=0; i< sizeBot; i++){
285  std::string param1 = bot.get(1).asList()->get(i).asList()->get(1).asString().c_str();
286 
287  if ( strcmp(param1.c_str(), "hasproperty") == 0 ){
288  objectDetails[numObjects].name = bot.get(1).asList()->get(i).asList()->get(0).asString().c_str();
289  numObjects ++;
290  }
291  }
292  }
293 
294  // add properties to the objects (if any)
295  for (int y=0; y< numObjects; y++){
296  for (int i=0; i< sizeBot; i++)
297  {
298  std::string param1 = bot.get(1).asList()->get(i).asList()->get(0).asString().c_str();
299  std::string param2 = bot.get(1).asList()->get(i).asList()->get(1).asString().c_str();
300  std::string param3 = bot.get(1).asList()->get(i).asList()->get(2).asString().c_str();
301 
302  if (strcmp(param1.c_str(), objectDetails[y].name.c_str()) == 0 && strcmp(param2.c_str(), "hasproperty") == 0){
303 
304  objectDetails[y].property.push_back(param3.c_str());
305  }
306  }
307  }
308 
309  //check relatedto
310  bool isProperty = false;
311  for (size_t i=0; i< sizeBot; i++){
312  std::string param1 = bot.get(1).asList()->get(i).asList()->get(0).asString().c_str();
313  std::string param2 = bot.get(1).asList()->get(i).asList()->get(1).asString().c_str();
314  std::string param3 = bot.get(1).asList()->get(i).asList()->get(2).asString().c_str();
315  if (strcmp(param2.c_str(), "relatedto") == 0 )
316  {
317  isProperty = true;
318  }
319  }
320 
321  for (size_t i=0; i<numActions; i++){
322  yarp::os::Bottle &list = final.addList();
323  yarp::os::Bottle &subjList = list.addList();
324  yarp::os::Bottle &actList = list.addList();
325 
326  subjList.addString("subject");
327  subject[i][0] = toupper(subject[i][0]);
328  subjList.addString(subject[i].c_str());
329 
330  actList.addString("verb");
331  action[i][0] = toupper(action[i][0]); // Make first characther upper case
332  actList.addString(action[i].c_str());
333 
334  yDebug() << "location is" << location.c_str() << "tmpAction is " << tmpAction.c_str() << "action is " << action[i].c_str();
335 
336  if (location.size()>0 && strcmp(tmpAction.c_str(), action[i].c_str()) == 0 ){
337  yarp::os::Bottle &posList = list.addList();
338  posList.addString("location");
339  //location[0] = toupper(location[0]);
340  posList.addString(location.c_str());
341  }
342 
343  for (int i=0; i<numObjects; i++){
344 
345  //Bottle &list = final.addList();
346  if (strcmp(location.c_str(), objectDetails[i].name.c_str()) == 0 ){
347  yInfo("AVOIDING object as location is equal to object %s", objectDetails[i].name.c_str());
348  }
349  else
350  {
351  yarp::os::Bottle &objList = list.addList();
352  if (isProperty){
353  objList.addString("property");
354  isProperty = false;
355  }
356  else
357  objList.addString("object");
358 
359  objectDetails[i].name[0] = toupper(objectDetails[i].name[0]);
360  objList.addString(objectDetails[i].name.c_str());
361 
362  if (objectDetails[i].property.size() > 0){
363  yarp::os::Bottle &propList = list.addList();
364  propList.addString("properties");
365  yarp::os::Bottle &propElem = propList.addList();
366  for (size_t y=0; y<objectDetails[i].property.size(); y++){
367  objectDetails[i].property[y][0] = toupper(objectDetails[i].property[y][0]);
368  propElem.addString(objectDetails[i].property[y].c_str());
369  }
370  }
371  }
372  }
373  }
374  }
375 
376  //yInfo("actions is: [%s] and object is: [%s]", action.c_str(), object.c_str());
377 
378  if (final.size() < 1)
379  yError("Something is wrong with the reply from START");
380  else
381  yInfo("output is: %s \n", final.toString().c_str());
382 
383 
384  startOutPort.write();
385 }
386 //empty line to make gcc happy