21 #include <yarp/os/Log.h>
22 #include <yarp/os/LogStream.h>
28 using yarp::os::Bottle;
29 using yarp::sig::Vector;
34 const int skinManager::MIN_BASELINE_DEFAULT = 3;
35 const int skinManager::ADD_THRESHOLD_DEFAULT = 2;
36 const int skinManager::PERIOD_DEFAULT = 50;
37 const bool skinManager::SMOOTH_FILTER_DEFAULT =
false;
38 const float skinManager::SMOOTH_FACTOR_DEFAULT = 0.5;
39 const float skinManager::COMPENSATION_GAIN_DEFAULT = 0.2f;
40 const float skinManager::CONTACT_COMPENSATION_GAIN_DEFAULT = 0.0f;
41 const string skinManager::MODULE_NAME_DEFAULT =
"skinManager";
42 const string skinManager::ROBOT_NAME_DEFAULT =
"icub";
43 const bool skinManager::ZERO_UP_RAW_DATA_DEFAULT =
false;
44 const bool skinManager::BINARIZATION_DEFAULT =
false;
45 const string skinManager::RPC_PORT_DEFAULT =
"/rpc";
47 bool skinManager::configure(yarp::os::ResourceFinder &rf) {
51 moduleName = rf.check(
"name", Value(MODULE_NAME_DEFAULT.c_str()),
"module name (string)").asString();
52 robotName = rf.check(
"robot", Value(ROBOT_NAME_DEFAULT.c_str()),
"name of the robot (string)").asString();
55 setName(moduleName.c_str());
58 int period = (int)rf.check(
"period", Value(PERIOD_DEFAULT),
59 "Period of the thread in ms (positive int)").asInt32();
60 float minBaseline = (float)rf.check(
"minBaseline", Value(MIN_BASELINE_DEFAULT),
61 "If the baseline reaches this value then, if allowed, a calibration is executed (float in [0,255])").asFloat64();
62 float compGain = (float)rf.check(
"compensationGain", Value(COMPENSATION_GAIN_DEFAULT),
63 "Gain of the compensation algorithm (float)").asFloat64();
64 float contCompGain = (float)rf.check(
"contactCompensationGain", Value(CONTACT_COMPENSATION_GAIN_DEFAULT),
65 "Gain of the compensation algorithm during contact (float)").asFloat64();
66 int addThreshold = (int)rf.check(
"addThreshold", Value(ADD_THRESHOLD_DEFAULT),
67 "Value added to all the touch thresholds (positive int)").asInt32();
69 bool zeroUpRawData = rf.check(
"zeroUpRawData", Value(ZERO_UP_RAW_DATA_DEFAULT),
70 "if true the raw data are considered from zero up, otherwise from 255 down (bool)").asBool();
71 bool smoothFilter = rf.check(
"smoothFilter", Value(SMOOTH_FILTER_DEFAULT),
72 "if true then the smoothing filter is active (bool)").asBool();
73 float smoothFactor = (float) rf.check(
"smoothFactor", Value(SMOOTH_FACTOR_DEFAULT),
74 "Determine the smoothing intensity (float in [0,1])").asFloat64();
75 bool binarization = rf.check(
"binarization", Value(BINARIZATION_DEFAULT),
76 "if true then the binarization is active (bool)").asBool();
82 string handlerPortName =
"/";
83 handlerPortName += getName(rf.check(
"handlerPort", Value(RPC_PORT_DEFAULT.c_str())).asString());
84 if (!handlerPort.open(handlerPortName.c_str())) {
85 cout << getName() <<
": Unable to open port " << handlerPortName << endl;
89 handlerPort.setRpcMode(
true);
95 myThread =
new CompensationThread(moduleName, &rf, robotName, compGain, contCompGain, addThreshold, minBaseline,
96 zeroUpRawData, period, binarization, smoothFilter, smoothFactor);
98 if(!myThread->start()) {
99 yError() <<
"[SkinManager] Could not start the compensator thread.";
105 if (!thSkinDiagnostics->start()) {
106 yError() <<
"[SkinManager] Could not start the skin diagnostics thread.";
113 bool skinManager::interruptModule()
115 handlerPort.interrupt();
121 bool skinManager::close()
128 if (thSkinDiagnostics) {
129 thSkinDiagnostics->stop();
130 delete thSkinDiagnostics;
139 bool skinManager::respond(
const Bottle& command, Bottle& reply) {
145 if(command.get(0).isInt32()){
149 params = command.tail();
151 else if(!identifyCommand(command, com, params)){
152 reply.addString(
"Unknown command. Input 'help' to get a list of the available commands.");
158 reply.addString(
"quitting");
162 reply.addVocab32(
"many");
163 reply.addString((
string(getName().c_str()) +
" commands are: ").c_str());
176 for(
size_t i=0; i< touchThreshold.size(); i++)
177 reply.addFloat64(touchThreshold[i]);
184 reply.addString(
"Binarization state missing! Specify either on or off.");
187 string value = params.get(0).asString().c_str();
188 if(value.compare(
"on")==0)
190 else if(value.compare(
"off")==0)
193 reply.addString(
"Value not recognized.");
201 reply.addString(
"on");
203 reply.addString(
"off");
209 reply.addString(
"Smooth filter state missing! Specify either on or off.");
212 string value = params.get(0).asString().c_str();
213 if(value.compare(
"on")==0)
215 else if(value.compare(
"off")==0)
218 reply.addString(
"Value not recognized.");
226 reply.addString(
"on");
228 reply.addString(
"off");
233 if(params.size()<1 || (!params.get(0).isFloat64() && !params.get(0).isInt32())){
234 reply.addString(
"New smooth factor value missing or not a number! Smooth factor not updated.");
240 temp<<
"New smooth factor set: "<< params.get(0).asFloat64();
243 temp<<
"ERROR in setting new smooth factor: "<< params.get(0).asFloat64();
245 reply.addString( temp.str().c_str());
255 if(params.size()<1 || (!params.get(0).isInt32())){
256 reply.addString(
"New threshold value missing or not an integer! Threshold not updated.");
262 temp<<
"New threshold set: "<< params.get(0).asInt32();
265 temp<<
"ERROR in setting new threshold: "<< params.get(0).asInt32();
267 reply.addString( temp.str().c_str());
277 if(params.size()<1 || (!params.get(0).isFloat64())){
278 reply.addString(
"New gain value missing or not a double! Gain not updated.");
284 temp<<
"New gain set: "<< params.get(0).asFloat64();
287 temp<<
"ERROR in setting new gain: "<< params.get(0).asFloat64();
289 reply.addString( temp.str().c_str());
299 if(params.size()<1 || (!params.get(0).isFloat64())){
300 reply.addString(
"New gain value missing or not a double! Contact gain not updated.");
306 temp<<
"New contact gain set: "<< params.get(0).asFloat64();
309 temp<<
"ERROR in setting new contact gain: "<< params.get(0).asFloat64();
311 reply.addString( temp.str().c_str());
325 if(params.size()<1 || (!params.get(0).isFloat64())){
326 reply.addString(
"New max neighbor distance value missing or not a double! Not updated.");
332 temp<<
"New max neighbor distance set: "<< params.get(0).asFloat64();
335 temp<<
"ERROR in setting new max neighbor distance: "<< params.get(0).asFloat64();
337 reply.addString( temp.str().c_str());
344 for(vector<SkinPart>::const_iterator it=spl.begin(); it!=spl.end(); it++){
352 if(!(params.size()>0 && params.get(0).isInt32())){
353 reply.addString((
"ERROR: SkinPart is not specified. Params read are: "+
string(params.toString().c_str())).c_str());
357 reply.addString(
"SkinPart enabled");
359 reply.addString(
"SkinPart not found");
363 if(!(params.size()>0 && params.get(0).isInt32())){
364 reply.addString((
"ERROR: SkinPart is not specified. Params read are: "+
string(params.toString().c_str())).c_str());
368 reply.addString(
"SkinPart disabled");
370 reply.addString(
"SkinPart not found");
374 if(!(params.size()>0 && params.get(0).isInt32())){
375 reply.addString((
"ERROR: SkinPart is not specified. Params read are: "+
string(params.toString().c_str())).c_str());
379 reply.addString(
"yes");
381 reply.addString(
"no");
386 reply.addString(
"yes");
388 reply.addString(
"no");
393 if(!(params.size()>0 && params.get(0).isInt32())){
394 reply.addString((
"ERROR: SkinPart is not specified. Params read are: "+
string(params.toString().c_str())).c_str());
398 if(params.size()>1 && params.get(1).isInt32()){
399 unsigned int taxelId = params.get(1).asInt32();
402 addToBottle(reply, res);
404 reply.addString(
"No poses for the specified skin part");
408 addToBottle(reply, res);
415 if(!(params.size()>6 && params.get(0).isInt32() )){
416 reply.addString((
"ERROR: SkinPart is not specified. Params read are: "+
string(params.toString().c_str())).c_str());
420 if(params.get(1).isInt32()){
421 unsigned int taxelId = params.get(1).asInt32();
423 if(!bottleToVector(params.tail().tail(), pose)){
424 reply.addString(
"ERROR while reading the taxel pose");
431 reply.addString(
"ERROR: pose was not set");
436 if(!bottleToVector(params.tail(), poses)){
437 reply.addString(
"ERROR while reading the taxel poses");
444 reply.addString(
"ERROR: pose was not set");
451 if(!(params.size()>0 && params.get(0).isInt32())){
452 reply.addString((
"ERROR: SkinPart is not specified. Params read are: "+
string(params.toString().c_str())).c_str());
456 if(params.size()>1 && params.get(1).isInt32()){
457 unsigned int taxelId = params.get(1).asInt32();
460 addToBottle(reply, res);
462 reply.addString(
"No position for the specified skin part");
467 reply.addString(
"Specified skin part has not been found.");
469 addToBottle(reply, res);
475 if(!(params.size()>3 && params.get(0).isInt32() )){
476 reply.addString((
"ERROR: SkinPart is not specified. Params read are: "+
string(params.toString().c_str())).c_str());
480 if(params.get(1).isInt32()){
481 unsigned int taxelId = params.get(1).asInt32();
483 if(!bottleToVector(params.tail().tail(), pose)){
484 reply.addString(
"ERROR while reading the taxel position");
491 reply.addString(
"ERROR: position was not set");
496 if(!bottleToVector(params.tail(), poses)){
497 reply.addString(
"ERROR while reading the taxel positions");
504 reply.addString(
"ERROR: position was not set");
511 if(!(params.size()>0 && params.get(0).isInt32())){
512 reply.addString((
"ERROR: SkinPart is not specified. Params read are: "+
string(params.toString().c_str())).c_str());
516 if(params.size()>1 && params.get(1).isInt32()){
517 unsigned int taxelId = params.get(1).asInt32();
519 reply.addFloat64(res);
524 reply.addString(
"Specified skin part has not been found");
526 addToBottle(reply, res);
532 reply.append(myThread->
getInfo());
536 reply.addString(
"ERROR: This command is known but it is not managed in the code.");
545 void skinManager::addToBottle(Bottle& b,
const Vector& v){
546 for(
unsigned int i=0; i<v.size(); i++)
550 void skinManager::addToBottle(Bottle& b,
const vector<Vector>& v){
551 for(
unsigned int i=0; i<v.size(); i++)
552 for(
unsigned int j=0; j<v[i].size(); j++)
553 b.addFloat64(v[i][j]);
556 bool skinManager::bottleToVector(
const yarp::os::Bottle& b, yarp::sig::Vector& v){
557 for(
int i=0; i<b.size(); i++)
558 if(b.get(i).isFloat64() || b.get(i).isInt32())
559 v.push_back(b.get(i).asFloat64());
568 bool skinManager::identifyCommand(Bottle commandBot,
SkinManagerCommand &com, Bottle& params) {
576 if (commandBot.get(j).asString() != word.c_str()){
584 params = commandBot.tail();
585 for(
int k=1; k<j; k++)
586 params = params.tail();
594 bool skinManager::updateModule() {
595 double avgTime, stdDev, period;
596 period = myThread->getPeriod();
597 myThread->getEstimatedPeriod(avgTime, stdDev);
598 double avgTimeUsed, stdDevUsed;
599 myThread->getEstimatedUsed(avgTimeUsed, stdDevUsed);
600 if(avgTime > 1.3 * period){
601 yWarning(
"Thread too slow. Real period: %3.3f+/-%3.3f. Expected period: %3.3f.\n", avgTime, stdDev, period);
602 yWarning(
"Duration of 'run' method: %3.3f+/-%3.3f.\n", avgTimeUsed, stdDevUsed);
607 double skinManager::getPeriod(){
return 1.0;}
bool setTaxelPosition(SkinPart sp, unsigned int taxelId, const Vector &position)
unsigned int getAddThreshold()
double getMaxNeighborDistance()
Vector getPoseConfidences(SkinPart sp)
Vector getTaxelPose(SkinPart sp, unsigned int taxelId)
bool setTaxelPose(SkinPart sp, unsigned int taxelId, const Vector &pose)
bool enableSkinPart(SkinPart sp)
vector< SkinPart > getSkinParts()
bool setSmoothFactor(float value)
double getPoseConfidence(SkinPart sp, unsigned int taxelId)
vector< Vector > getTaxelPoses(SkinPart sp=SKIN_PART_ALL)
double getCompensationGain()
bool setContactCompensationGain(double gain)
bool setTaxelPositions(SkinPart sp, const Vector &positions)
bool setCompensationGain(double gain)
double getContactCompensationGain()
bool setTaxelPoses(SkinPart sp, const vector< Vector > &poses)
bool disableSkinPart(SkinPart sp)
Vector getTaxelPosition(SkinPart sp, unsigned int taxelId)
bool isSkinEnabled(SkinPart sp)
Vector getTouchThreshold()
bool setAddThreshold(unsigned int thr)
bool setMaxNeighborDistance(double dist)
void setBinarization(bool value)
vector< Vector > getTaxelPositions(SkinPart sp=SKIN_PART_ALL)
void setSmoothFilter(bool value)
const std::string SkinPart_s[]
const std::string SkinManagerCommandDesc[]
const std::string SkinManagerCommandList[]