87 std::string modName = config.find(
"name").asString();
88 setName(modName.c_str());
90 _lasttime = Time::now();
91 if (config.check(
"help",
"if present, display usage message")) {
92 yError(
"Call with --name /module_prefix --file configFile.ini \n");
96 _highlevelemotions = config.check(
"emotions", Value(0),
"Number of predefined facial expressions").asInt32();
97 _numberOfColors = config.check(
"colors", Value(0),
"Number of predefined colors").asInt32();
98 _eyebrowmaskemotions = config.check(
"bitmask_eyebrow_emotions", Value(0),
"Number of predefined bitmask eyebrow expressions").asInt32();
99 _mouthmaskemotions = config.check(
"bitmask_mouth_emotions", Value(0),
"Number of predefined bitmask eyebrow expressions").asInt32();
100 _auto = config.check(
"auto");
101 _period = config.check(
"period", Value(10.0),
"Period for expression switching in auto mode").asFloat64();
102 if(_highlevelemotions == 0)
104 _emotion_table =
nullptr;
108 _emotion_table =
new EM_CODE[_highlevelemotions];
111 yError(
"Memory allocation problem\n");
114 for(
int i = 0; i < _highlevelemotions; i++)
116 std::ostringstream ss;
118 std::string name = ss.str();
119 if(!config.check(name))
121 yError(
"Missing identifier %s.", name.c_str());
126 Bottle& bot = config.findGroup(name);
129 printf(
"Invalid parameter list for identifier %s.", name.c_str());
133 std::string n1 = bot.get(1).toString();
137 yError(
"First field of identifier %s has invalid size (must be 3).", name.c_str());
142 const char *buffer = n1.c_str();
143 strncpy(_emotion_table[i].name, buffer, 3);
147 std::string n2 = bot.get(2).toString();
148 const char * sfd = n2.c_str();
151 yError(
"Second field of identifier %s has invalid size (must be 3).", name.c_str());
156 const char *buffer = n2.c_str();
157 strncpy(_emotion_table[i].leb, buffer, 2);
160 std::string n3 = bot.get(3).toString();
163 yError(
"Third field of identifier %s has invalid size (must be 3).", name.c_str());
168 const char *buffer = n3.c_str();
169 strncpy(_emotion_table[i].reb, buffer, 2);
173 std::string n4 = bot.get(4).toString();
176 yError(
"Fourth field of identifier %s has invalid size (must be 3).", name.c_str());
181 const char *buffer = n4.c_str();
182 strncpy(_emotion_table[i].mou, buffer, 2);
186 std::string n5 = bot.get(5).toString();
189 yError(
"Fifth field of identifier %s has invalid size (must be 3).", name.c_str());
194 const char *buffer = n5.c_str();
195 strncpy(_emotion_table[i].eli, buffer, 2);
200 if(_numberOfColors) {
201 std::string color_id;
202 for(
size_t index=0; index<_numberOfColors; index++){
203 color_id =
"C"+std::to_string(index);
204 Bottle& bot = config.findGroup(color_id);
207 yError(
"Invalid parameter list for the identifier %s.", color_id.c_str());
211 std::string code = bot.get(2).toString();
212 if (code.length()!=3)
214 yError(
"The identifier must have size 3");
217 _color_table[bot.get(1).asString()] = code.substr(0,code.length()-1);
220 if(_eyebrowmaskemotions) {
222 for(
size_t index=0; index<_eyebrowmaskemotions; index++){
223 id =
"BM_EB"+std::to_string(index);
224 Bottle& bot = config.findGroup(
id);
227 yError()<<
"Parsing of the bitmap failed";
230 _bitmask_emotion_table[id] = hexCode;
234 if(_mouthmaskemotions) {
237 for(
size_t index=0; index<_mouthmaskemotions; index++){
238 id =
"BM_M"+std::to_string(index);
239 Bottle& bot = config.findGroup(
id);
242 yError()<<
"Parsing of the bitmap failed";
245 _bitmask_emotion_table[id] = hexCode;
250 yarp::os::Property rcb_face_conf{ {
"device",Value(
"remote_controlboard")},
251 {
"local", Value(getName(
"/face/remoteControlBoard"))},
252 {
"remote",Value(
"/icub/face")},
253 {
"part",Value(
"face")} };
255 if (_poly.open(rcb_face_conf))
257 yarp::dev::IControlMode* iCM{
nullptr };
258 yarp::dev::IControlLimits* iCtrlLim{
nullptr };
259 auto ok = _poly.view(iCM);
260 ok &= _poly.view(_iPos);
261 ok &= _poly.view(iCtrlLim);
263 ok &= iCM->setControlMode(_joint_eylids, VOCAB_CM_POSITION);
265 ok &= iCtrlLim->getLimits(_joint_eylids, &_min, &_max);
269 ok &= _iPos->setRefSpeed(_joint_eylids, 50.0);
270 ok &= _iPos->setRefAcceleration(_joint_eylids,std::numeric_limits<double>::max());
274 yError() <<
"Fail to configure correctly the remote_controlboard";
280 yWarning() <<
"Failed to open the remote_controlboard device for commanding the eyelids, you can ignore this warning if your robot doesn't have the rfe board";
284 _inputPort.open(getName(
"/in"));
285 _outputPort.open(getName(
"/out"));
286 _outputPort.setReporter(emotionInitReport);
287 _initEmotionTrigger=0;
357 switch (command.get(0).asVocab32()) {
364 switch(command.get(1).asVocab32()) {
382 ok =
setAll(command.get(2).toString());
386 ok =
setRaw(command.get(2).toString());
402 cout <<
"received an unknown request after a VOCAB_SET" << endl;
543 char cmdbuffer[] = {0,0,0,0};
544 const auto i = getIndex(
cmd);
550 if( _emotion_table[i].eli[0] ==
'*' || _emotion_table[i].eli[1] ==
'*')
554 auto target_pos = getEyelidsTarget(_emotion_table[i].eli[0], _emotion_table[i].eli[1]);
555 res = _iPos->positionMove(_joint_eylids, target_pos);
560 cmdbuffer[1] = _emotion_table[i].
eli[0];
561 cmdbuffer[2] = _emotion_table[i].
eli[1];
562 res = writePort(cmdbuffer);
621 yError()<<
"Bad request, it should be set mask (color mask) (color mask) (color mask)";
624 auto botLeb =
cmd.get(2).asList();
625 auto botReb =
cmd.get(3).asList();
626 auto botMou =
cmd.get(4).asList();
628 if(!botLeb || !botReb || !botMou) {
629 yError()<<
"Bad request, missing one of the three list";
633 if(botLeb->size()!=3 || botReb->size()!=3 || botMou->size()!=3) {
634 yError()<<
"Bad request, each list has to be (color mask brightness)";
637 auto colLeb = botLeb->get(0).asString();
638 auto colReb = botReb->get(0).asString();
639 auto colMou = botMou->get(0).asString();
641 auto maskLeb = botLeb->get(1).asString();
642 auto maskReb = botReb->get(1).asString();
643 auto maskMou = botMou->get(1).asString();
645 auto brightLeb =
'0'+ botLeb->get(2).toString();
646 auto brightReb =
'0'+ botReb->get(2).toString();
647 auto brightMou =
'0'+ botMou->get(2).toString();
649 if(_bitmask_emotion_table.find(maskLeb) == _bitmask_emotion_table.end() ||
650 _bitmask_emotion_table.find(maskReb) == _bitmask_emotion_table.end() ||
651 _bitmask_emotion_table.find(maskMou) == _bitmask_emotion_table.end()) {
652 yError()<<
"One or more bitmask has not been defined in the ini file";
658 cmdbuffer += _color_table[colLeb];
659 cmdbuffer += brightLeb;
660 cmdbuffer += _bitmask_emotion_table[maskLeb];
662 cmdbuffer += _color_table[colReb];
663 cmdbuffer += brightReb;
664 cmdbuffer += _bitmask_emotion_table[maskReb];
666 cmdbuffer += _color_table[colMou];
667 cmdbuffer += brightMou;
668 cmdbuffer += _bitmask_emotion_table[maskMou];
670 return writePort(cmdbuffer.c_str());