speech
Loading...
Searching...
No Matches
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/**********************************************************/
23bool 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/**********************************************************/
51bool STARTModule::interruptModule()
52{
53 rpcPort.interrupt();
54 return true;
55}
56
57/**********************************************************/
58bool 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/**********************************************************/
71bool STARTModule::updateModule()
72{
73 return !closing;
74}
75
76/**********************************************************/
77double STARTModule::getPeriod()
78{
79 return 0.1;
80}
81
82/**********************************************************/
83STARTManager::~STARTManager()
84{
85
86}
87
88/**********************************************************/
89STARTManager::STARTManager( const std::string &moduleName )
90{
91 yInfo("initialising Variables\n");
92 this->moduleName = moduleName;
93 objectDetails = NULL;
94}
95
96/**********************************************************/
97bool 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/**********************************************************/
114void 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/**********************************************************/
123void 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/**********************************************************/
132void 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