31 #include <yarp/os/BufferedPort.h>
32 #include <yarp/os/ResourceFinder.h>
33 #include <yarp/os/RFModule.h>
34 #include <yarp/os/Network.h>
35 #include <yarp/os/Time.h>
36 #include <yarp/os/Log.h>
37 #include <yarp/os/LogStream.h>
38 #include <yarp/os/Semaphore.h>
39 #include <yarp/sig/SoundFile.h>
40 #include <yarp/dev/PolyDriver.h>
42 #include <grpc++/grpc++.h>
43 #include "google/cloud/language/v1/language_service.grpc.pb.h"
45 #include "googleSpeechProcess_IDL.h"
47 using namespace google::cloud::language::v1;
50 static const std::map<grpc::StatusCode, std::string> status_code_to_string {
52 {grpc::CANCELLED,
"cancelled"},
53 {grpc::UNKNOWN,
"unknown"},
54 {grpc::INVALID_ARGUMENT,
"invalid_argument"},
55 {grpc::DEADLINE_EXCEEDED,
"deadline_exceeded"},
56 {grpc::NOT_FOUND,
"not_found"},
57 {grpc::ALREADY_EXISTS,
"already_exists"},
58 {grpc::PERMISSION_DENIED,
"permission_denied"},
59 {grpc::UNAUTHENTICATED,
"unauthenticated"},
60 {grpc::RESOURCE_EXHAUSTED ,
"resource_exhausted"},
61 {grpc::FAILED_PRECONDITION,
"failed_precondition"},
62 {grpc::ABORTED,
"aborted"},
63 {grpc::OUT_OF_RANGE,
"out_of_range"},
64 {grpc::UNIMPLEMENTED,
"unimplemented"},
65 {grpc::INTERNAL,
"internal"},
66 {grpc::UNAVAILABLE,
"unavailable"},
67 {grpc::DATA_LOSS,
"data_loss"},
68 {grpc::DO_NOT_USE,
"do_not_use"}
71 class Processing :
public yarp::os::BufferedPort<yarp::os::Bottle>
73 std::string moduleName;
75 yarp::os::RpcServer handlerPort;
76 yarp::os::BufferedPort<yarp::os::Bottle> targetPort;
78 yarp::os::Bottle wordList;
83 Processing(
const std::string &moduleName, std::string &state ): state(state)
85 this->moduleName = moduleName;
98 yarp::os::BufferedPort<yarp::os::Bottle >::open(
"/" + moduleName +
"/text:i" );
99 targetPort.open(
"/"+ moduleName +
"/result:o");
109 yarp::os::BufferedPort<yarp::os::Bottle >::close();
114 void onRead( yarp::os::Bottle &bot )
116 yarp::os::Bottle &outTargets = targetPort.prepare();
120 outTargets = queryGoogleSyntax(bot);
123 yDebug() <<
"done querying google";
128 yarp::os::Bottle queryGoogleSyntax(yarp::os::Bottle& text)
132 yDebug() <<
"in queryGoogleSyntax";
134 yDebug() <<
"Phrase is " << text.toString().c_str();
136 std::string tmp = text.toString();
138 std::map< std::string, std::string> dictionary;
139 dictionary.insert ( std::pair<std::string,std::string>(
"á",
"a") );
140 dictionary.insert ( std::pair<std::string,std::string>(
"à",
"a") );
141 dictionary.insert ( std::pair<std::string,std::string>(
"é",
"e") );
142 dictionary.insert ( std::pair<std::string,std::string>(
"è",
"e") );
143 dictionary.insert ( std::pair<std::string,std::string>(
"í",
"i") );
144 dictionary.insert ( std::pair<std::string,std::string>(
"ó",
"o") );
145 dictionary.insert ( std::pair<std::string,std::string>(
"ú",
"u") );
146 dictionary.insert ( std::pair<std::string,std::string>(
"ñ",
"n") );
148 std::string tmp2 = tmp;
150 for (
auto it= dictionary.begin(); it != dictionary.end(); it++)
153 std::size_t found=tmp.find_first_of(tmp2);
155 while (found!=std::string::npos)
157 yError() <<
"in found" << found;
159 tmp.erase(found,tmp2.length());
160 tmp.insert(found,strAux);
161 found=tmp.find_first_of(tmp2,found+1);
165 yDebug() <<
"Phrase is now " << tmp.c_str();
166 tmp.erase(std::remove(tmp.begin(),tmp.end(),
'\"'),tmp.end());
168 yDebug() << tmp.size();
169 yDebug() << std::isalnum(tmp[1]);
171 if (tmp.size() > 1 && std::isalnum(tmp[0])==0)
172 tmp = tmp.substr(1, tmp.size() - 2);
174 yDebug() <<
"Phrase is now " << tmp.c_str();
176 std::string content = tmp;
178 if (content.size()>0){
179 AnalyzeSyntaxRequest request;
180 AnalyzeSyntaxResponse response;
182 grpc::ClientContext context;
184 AnalyzeSentimentRequest sentiment_request;
185 AnalyzeSentimentResponse sentiment_response;
186 grpc::Status sentiment_status;
187 grpc::ClientContext sentiment_context;
189 setArguments( request.mutable_document(), content );
190 setArguments( sentiment_request.mutable_document(), content );
193 request.set_encoding_type( EncodingType::UTF8 );
196 auto creds = grpc::GoogleDefaultCredentials();
197 auto channel = grpc::CreateChannel(
"language.googleapis.com", creds);
198 std::unique_ptr< LanguageService::Stub> stub( LanguageService::NewStub( channel ) );
201 yarp::os::Time::delay(0.2);
202 status = stub->AnalyzeSyntax( &context, request, &response );
203 sentiment_status = stub->AnalyzeSentiment( &sentiment_context, sentiment_request, &sentiment_response );
204 std::string status_string = status_code_to_string.at(status.error_code());
205 yInfo() <<
"Status string:" << status_string;
208 if ( status.ok() && sentiment_status.ok() ){
209 yInfo() <<
"Status returned OK";
210 yInfo() <<
"\n------Response------\n";
212 read_language( &response.language() );
213 read_sentences( &response.sentences() );
214 read_sentiment( &sentiment_response.sentences() );
215 read_tokens( &response.tokens() );
216 b = read_analysis( &response.sentences(), &response.tokens(), &sentiment_response.sentences() );
220 yError() <<
"Status Returned Cancelled";
221 checkState(
"Failure_" + status_string);
222 yInfo() << status.error_message();
225 else if (content.size()==0) {
226 checkState(
"Empty_input");
232 void setArguments(Document* doc, std::string& content)
234 doc->set_type( Document_Type::Document_Type_PLAIN_TEXT );
235 doc->set_content( content );
239 void read_language(
const std::string* lang )
241 std::cout <<
"\n----Language----" << std::endl;
242 std::cout <<
"Language: " << *lang << std::endl;
246 void read_sentences(
const google::protobuf::RepeatedPtrField< Sentence >* sentences ) {
249 yInfo() <<
"----Sentences----";
250 yInfo() <<
"Sentences Size: " << sentences->size();
251 for(
int i = 0; i < sentences->size(); i++ ) {
252 yInfo() <<
"Sentence " << i <<
" has text: " << sentences->Get( i ).has_text();
253 if ( sentences->Get( i ).has_text() ) {
254 yInfo() <<
"Sentence text: " << sentences->Get( i ).text().content();
260 std::pair<float,float> read_sentiment(
const google::protobuf::RepeatedPtrField< Sentence >* sentences ) {
263 std::pair<float,float> result(9999,9999);
266 yInfo() <<
"----Sentiments----";
267 yInfo() <<
"Sentiments Size: " << sentences->size();
268 for(
int i = 0; i < sentences->size(); i++ ) {
269 yInfo() <<
"Sentiments " << i <<
" has text: " << sentences->Get( i ).has_text();
270 if ( sentences->Get( i ).has_text() ) {
271 yInfo() <<
"Sentiments text: " << sentences->Get( i ).text().content();
274 yInfo() <<
"Sentiments " << i <<
" has sentiment: " << sentences->Get( i ).has_sentiment();
275 if ( sentences->Get( i ).has_sentiment() ) {
276 yInfo() <<
"Sentiments " << i <<
" sentiment: "
277 <<
"\n\t\tMagnitude: "
278 << sentences->Get( i ).sentiment().magnitude()
280 << sentences->Get( i ).sentiment().score()
282 result.first = sentences->Get( i ).sentiment().magnitude();
283 result.second = sentences->Get( i ).sentiment().score();
290 yarp::os::Bottle read_analysis(
const google::protobuf::RepeatedPtrField< Sentence >* sentences ,
const google::protobuf::RepeatedPtrField< Token >* tokens,
const google::protobuf::RepeatedPtrField< Sentence >* sentiment_sentences ) {
293 yarp::os::Bottle &words = wordList.addList();
295 for(
int i = 0; i < sentences->size(); i++ ) {
296 yInfo() <<
"Sentence " << i <<
" has text: " << sentences->Get( i ).has_text();
297 if ( sentences->Get( i ).has_text() ) {
298 yInfo() <<
"Sentence text: " << sentences->Get( i ).text().content();
299 words.addString(sentences->Get( i ).text().content());
303 for (
int i = 0; i < tokens->size(); i++ ) {
305 yarp::os::Bottle &word_analysis = words.addList();
306 word_analysis.addString(
"word");
307 word_analysis.addString(tokens->Get( i ).text().content());
309 int j = tokens->Get( i ).dependency_edge().head_token_index();
310 if ( tokens->Get( j ).text().content() != tokens->Get( i ).text().content() ) {
311 yarp::os::Bottle &dependency = word_analysis.addList();
312 dependency.addString(
"Dependency");
313 dependency.addString(tokens->Get( j ).text().content());
316 yarp::os::Bottle &parseLabel = word_analysis.addList();
317 parseLabel.addString(
"Parse_Label");
318 parseLabel.addString(DependencyEdge_Label_Name(tokens->Get( i ).dependency_edge().label()));
320 yarp::os::Bottle &partOfSpeech = word_analysis.addList();
321 partOfSpeech.addString(
"Part_of_speech");
322 partOfSpeech.addString(PartOfSpeech_Tag_Name(tokens->Get( i ).part_of_speech().tag()));
324 if ( tokens->Get( i ).lemma() != tokens->Get( i ).text().content() ) {
325 yarp::os::Bottle &lemma = word_analysis.addList();
326 lemma.addString(
"Lemma");
327 lemma.addString(tokens->Get( i ).lemma());
330 yarp::os::Bottle &morphology = word_analysis.addList();
331 morphology.addString(
"Morphology");
333 yarp::os::Bottle &number = morphology.addList();
334 number.addString(
"number");
335 number.addString(PartOfSpeech_Number_Name( tokens->Get( i ).part_of_speech().number() ));
337 yarp::os::Bottle &person = morphology.addList();
338 person.addString(
"person");
339 person.addString( PartOfSpeech_Person_Name( tokens->Get( i ).part_of_speech().person() ));
341 yarp::os::Bottle &gender = morphology.addList();
342 gender.addString(
"gender");
343 gender.addString( PartOfSpeech_Gender_Name( tokens->Get( i ).part_of_speech().gender() ));
349 yarp::os::Bottle &tense = morphology.addList();
350 tense.addString(
"tense");
351 tense.addString(PartOfSpeech_Tense_Name( tokens->Get( i ).part_of_speech().tense() ));
353 yarp::os::Bottle &aspect = morphology.addList();
354 aspect.addString(
"aspect");
355 aspect.addString( PartOfSpeech_Aspect_Name( tokens->Get( i ).part_of_speech().aspect() ));
357 yarp::os::Bottle &mood = morphology.addList();
358 mood.addString(
"mood");
359 mood.addString(PartOfSpeech_Mood_Name( tokens->Get( i ).part_of_speech().mood() ));
361 yarp::os::Bottle &voice = morphology.addList();
362 voice.addString(
"voice");
363 voice.addString(PartOfSpeech_Voice_Name( tokens->Get( i ).part_of_speech().voice() ));
365 yarp::os::Bottle &reciprocity = morphology.addList();
366 reciprocity.addString(
"reciprocity");
367 reciprocity.addString(PartOfSpeech_Reciprocity_Name( tokens->Get( i ).part_of_speech().reciprocity() ));
369 yarp::os::Bottle &proper = morphology.addList();
370 proper.addString(
"proper");
371 proper.addString(PartOfSpeech_Proper_Name( tokens->Get( i ).part_of_speech().proper() ));
373 yarp::os::Bottle &form = morphology.addList();
374 form.addString(
"form");
375 form.addString( PartOfSpeech_Form_Name( tokens->Get( i ).part_of_speech().form() ));
379 yarp::os::Bottle &sentiment = words.addList();
380 sentiment.addString(
"Sentiment");
382 yarp::os::Bottle &sentiment_score = sentiment.addList();
383 sentiment_score.addString(
"Score");
384 std::pair<float,float> sentiment_result = read_sentiment( sentiment_sentences );
385 sentiment_score.addFloat64(sentiment_result.second);
387 yarp::os::Bottle &sentiment_magnitude = sentiment.addList();
388 sentiment_magnitude.addString(
"Magnitude");
389 sentiment_magnitude.addFloat64(sentiment_result.first);
391 yInfo() <<
"wordList " << wordList.toString().c_str();
397 void read_tokens(
const google::protobuf::RepeatedPtrField< Token >* tokens ) {
399 for (
int i = 0; i < tokens->size(); i++ ) {
401 std::cout <<
"\n-------- " << i << std::endl;
402 yInfo() << tokens->Get( i ).text().content();
403 yInfo() <<
"root" << tokens->Get( i ).dependency_edge().head_token_index();
404 yInfo() << PartOfSpeech_Tag_Name(tokens->Get( i ).part_of_speech().tag());
405 yInfo() << DependencyEdge_Label_Name( tokens->Get( i ).dependency_edge().label() );
406 if ( tokens->Get( i ).lemma() == tokens->Get( i ).text().content() ) {
407 yInfo() <<
"lemma na";
410 yInfo() <<
"lemma" << tokens->Get( i ).lemma();
414 for (
int i = 0; i < tokens->size(); i++ ) {
417 <<
"-- Token " << i <<
" --"
421 <<
"Token " << i <<
" has text: "
422 << tokens->Get( i ).has_text()
425 if ( tokens->Get( i ).has_text() ) {
427 <<
"\tToken " << i <<
" text: "
428 << tokens->Get( i ).text().content()
430 << tokens->Get( i ).text().begin_offset()
435 <<
"Token " << i <<
" has PartOfSpeech: "
436 << tokens->Get( i ).has_part_of_speech()
439 if ( tokens->Get( i ).has_part_of_speech() ) {
442 << PartOfSpeech_Tag_Name( tokens->Get( i ).part_of_speech().tag() )
473 <<
"Token " << i <<
" has DependencyEdge: "
474 << tokens->Get( i ).has_dependency_edge()
477 if ( tokens->Get( i ).has_dependency_edge() ) {
479 <<
"\tToken " << i <<
" DependencyEdge: "
480 <<
"\n\t\tHead Token Index: "
481 << tokens->Get( i ).dependency_edge().head_token_index()
483 << DependencyEdge_Label_Name( tokens->Get( i ).dependency_edge().label() )
487 <<
"Token " << i <<
" lemma: "
488 << tokens->Get( i ).lemma()
495 bool start_acquisition()
501 bool stop_acquisition()
507 yarp::os::Bottle get_dependency()
509 yarp::os::Bottle dependency_result;
510 yarp::os::Bottle &dependency_analysis = dependency_result.addList();
511 size_t element = wordList.get(0).asList()->size();
513 for(
size_t i=1; i<element-1; i++){
514 yarp::os::Bottle* new_element = wordList.get(0).asList()->get(i).asList();
516 yarp::os::Bottle &each_dependency = dependency_analysis.addList();
517 each_dependency.addString(new_element->find(
"word").asString());
518 each_dependency.addString(new_element->find(
"Dependency").asString());
522 yInfo() <<
"dependency_result " << dependency_result.toString().c_str();
524 return dependency_result;
528 yarp::os::Bottle get_parseLabel()
530 yarp::os::Bottle parseLabel_result;
531 yarp::os::Bottle &parseLabel_analysis = parseLabel_result.addList();
532 size_t element = wordList.get(0).asList()->size();
533 for(
size_t i=1; i<element-1; i++){
534 yarp::os::Bottle* new_element = wordList.get(0).asList()->get(i).asList();
535 yarp::os::Bottle &each_parseLabel = parseLabel_analysis.addList();
536 each_parseLabel.addString(new_element->find(
"word").asString());
537 each_parseLabel.addString(new_element->find(
"Parse_Label").asString());
541 yInfo() <<
"parseLabel_result " << parseLabel_result.toString().c_str();
543 return parseLabel_result;
547 yarp::os::Bottle get_partOfSpeech()
549 yarp::os::Bottle partOfSpeech_result;
550 yarp::os::Bottle &partOfSpeech_analysis = partOfSpeech_result.addList();
551 size_t element = wordList.get(0).asList()->size();
552 for(
size_t i=1; i<element-1; i++){
553 yarp::os::Bottle* new_element = wordList.get(0).asList()->get(i).asList();
554 yarp::os::Bottle &each_partOfSpeech = partOfSpeech_analysis.addList();
555 each_partOfSpeech.addString(new_element->find(
"word").asString());
556 each_partOfSpeech.addString(new_element->find(
"Part_of_speech").asString());
560 yInfo() <<
"partOfSpeech_result " << partOfSpeech_result.toString().c_str();
562 return partOfSpeech_result;
566 yarp::os::Bottle get_lemma()
568 yarp::os::Bottle lemma_result;
569 yarp::os::Bottle &lemma_analysis = lemma_result.addList();
570 size_t element = wordList.get(0).asList()->size();
571 for(
size_t i=1; i<element-1; i++){
572 yarp::os::Bottle* new_element = wordList.get(0).asList()->get(i).asList();
573 yarp::os::Bottle &each_lemma = lemma_analysis.addList();
574 each_lemma.addString(new_element->find(
"word").asString());
575 each_lemma.addString(new_element->find(
"Lemma").asString());
579 yInfo() <<
"lemma_result " << lemma_result.toString().c_str();
585 yarp::os::Bottle get_morphology()
587 yarp::os::Bottle morphology_result;
588 yarp::os::Bottle &morphology_analysis = morphology_result.addList();
589 size_t element = wordList.get(0).asList()->size();
590 for(
size_t i=1; i<element-1; i++){
591 yarp::os::Bottle* new_element = wordList.get(0).asList()->get(i).asList();
592 yarp::os::Bottle* morphology = new_element->get(new_element->size()-1).asList();
594 yarp::os::Bottle &each_morphology = morphology_analysis.addList();
595 each_morphology.addString(new_element->find(
"word").asString());
596 for(
size_t i=1; i<morphology->size()-1; i++) {
597 yarp::os::Bottle &each_value = each_morphology.addList();
598 each_value.addString(morphology->get(i).asList()->get(0).toString());
599 each_value.addString(morphology->get(i).asList()->get(1).toString());
604 yInfo() <<
"morphology_result " << morphology_result.toString().c_str();
606 return morphology_result;
610 yarp::os::Bottle get_sentiment()
612 yarp::os::Bottle sentiment_result;
613 yarp::os::Bottle &sentiment_analysis = sentiment_result.addList();
614 size_t element = wordList.get(0).asList()->size();
615 yarp::os::Bottle* first_element = wordList.get(0).asList();
616 std::string sentence = first_element->get(0).asString();
618 sentiment_analysis.addString(sentence);
619 yarp::os::Bottle* sentiment = wordList.get(0).asList()->get(element-1).asList();
621 double score = sentiment->get(1).asList()->get(1).asFloat64();
622 double magnitude = sentiment->get(2).asList()->get(1).asFloat64();
624 yarp::os::Bottle &each_score = sentiment_analysis.addList();
625 each_score.addString(
"Score");
626 each_score.addFloat64(score);
627 yarp::os::Bottle &each_magnitude = sentiment_analysis.addList();
628 each_magnitude.addString(
"Magnitude");
629 each_magnitude.addFloat64(magnitude);
633 yInfo() <<
"sentiment_result " << sentiment_result.toString().c_str();
636 return sentiment_result;
640 bool checkState(std::string new_state)
642 if(new_state!=state){
654 class Module :
public yarp::os::RFModule,
public googleSpeechProcess_IDL
656 yarp::os::ResourceFinder *rf;
657 yarp::os::RpcServer rpcPort;
659 yarp::os::BufferedPort<yarp::os::Bottle> statePort;
662 Processing *processing;
663 friend class processing;
668 bool attach(yarp::os::RpcServer &source)
670 return this->yarp().attachAsServer(source);
676 bool configure(yarp::os::ResourceFinder &rf)
680 std::string moduleName = rf.check(
"name", yarp::os::Value(
"yarp-google-speech-process"),
"module name (string)").asString();
682 setName(moduleName.c_str());
684 rpcPort.open((
"/"+getName(
"/rpc")).c_str());
685 statePort.open(
"/"+ moduleName +
"/state:o");
689 processing =
new Processing( moduleName, state );
711 processing->start_acquisition();
718 processing->stop_acquisition();
740 yarp::os::Bottle &outTargets = statePort.prepare();
742 outTargets.addString(state);
743 yDebug() <<
"outTarget:" << outTargets.toString().c_str();
750 yarp::os::Bottle get_dependency()
752 yarp::os::Bottle answer;
753 answer = processing->get_dependency();
759 yarp::os::Bottle get_parseLabel()
761 yarp::os::Bottle answer;
762 answer = processing->get_parseLabel();
768 yarp::os::Bottle get_partOfSpeech()
770 yarp::os::Bottle answer;
771 answer = processing->get_partOfSpeech();
777 yarp::os::Bottle get_lemma()
779 yarp::os::Bottle answer;
780 answer = processing->get_lemma();
786 yarp::os::Bottle get_morphology()
788 yarp::os::Bottle answer;
789 answer = processing->get_morphology();
795 yarp::os::Bottle get_sentiment()
797 yarp::os::Bottle answer;
798 answer = processing->get_sentiment();
806 int main(
int argc,
char *argv[])
808 yarp::os::Network::init();
810 yarp::os::Network yarp;
811 if (!yarp.checkNetwork())
813 yError(
"YARP server not available!");
818 yarp::os::ResourceFinder rf;
820 rf.setVerbose(
true );
821 rf.setDefaultContext(
"googleSpeechProcess" );
822 rf.setDefaultConfigFile(
"config.ini" );
823 rf.setDefault(
"name",
"googleSpeechProcess");
824 rf.configure(argc,argv);
826 return module.runModule(rf);