icub-client
homeostasisManagerIcub.cpp
Go to the documentation of this file.
2 #include <cmath>
3 
4 using namespace std;
5 using namespace yarp::os;
6 
7 bool HomeostaticModule::addNewDrive(string driveName, yarp::os::Bottle& grpHomeostatic)
8 {
9  yDebug() << "Add drive " + driveName;
10  Drive* drv = new Drive(driveName, period);
11 
12  drv->setHomeostasisMin(grpHomeostatic.check((driveName + "-homeostasisMin"), Value(drv->homeostasisMin)).asDouble());
13  drv->setHomeostasisMax(grpHomeostatic.check((driveName + "-homeostasisMax"), Value(drv->homeostasisMax)).asDouble());
14  drv->setDecay(grpHomeostatic.check((driveName + "-decay"), Value(drv->decay)).asDouble());
15  drv->setValue((drv->homeostasisMax + drv->homeostasisMin) / 2.);
16  drv->setGradient(grpHomeostatic.check((driveName + "-gradient"), Value(drv->gradient)).asInt());
17  drv->setKey(grpHomeostatic.check((driveName + "-key"), Value(drv->key)).asString());
18 
19  manager->addDrive(drv);
20 
21  openPorts(driveName);
22  yInfo() << "new drive created successfully!";
23 
24  return true;
25 }
26 bool HomeostaticModule::addNewDrive(string driveName)
27 {
28 
29  yInfo() << "adding a default drive..." ;
30  Drive* drv = new Drive(driveName, period);
31 
32 
35  drv->setDecay(drv->decay);
36  drv->setValue((drv->homeostasisMax + drv->homeostasisMin) / 2.);
37  drv->setGradient(false);
38  drv->setKey(drv->key);
39 
40  manager->addDrive(drv);
41 
42  yDebug() << "default drive added. Opening ports...";
43  openPorts(driveName);
44  yInfo() << "new drive created successfully!";
45 
46  return true;
47 }
48 
49 int HomeostaticModule::openPorts(string driveName)
50 {
51  //Create Ports
52  string pn;
53  outputm_ports.push_back(new BufferedPort<Bottle>());
54  outputM_ports.push_back(new BufferedPort<Bottle>());
55 
56  if (!input_port.open("/"+moduleName+"/fromSensations:i"))
57  {
58  yInfo() << getName() << ": Unable to open port " << "/"<<moduleName<<"/fromSensations:i" ;
59  }
60  string portName = "/" + moduleName + "/" + driveName;
61 
62  pn = portName + "/min:o";
63  yInfo() << "Configuring port " << " : "<< pn << " ..." ;
64  if (!outputm_ports.back()->open(pn))
65  {
66  yInfo() << getName() << ": Unable to open port " << pn ;
67  }
68 
69  pn = portName + "/max:o";
70  yInfo() << "Configuring port " << " : "<< pn << " ..." ;
71  if (!outputM_ports.back()->open(pn))
72  {
73  yInfo() << getName() << ": Unable to open port " << pn ;
74  }
75 
76  return true;
77 }
78 
79 bool HomeostaticModule::configure(yarp::os::ResourceFinder &rf)
80 {
81  moduleName = rf.check("name",Value("homeostasis")).asString();
82  setName(moduleName.c_str());
83 
84  verbose = rf.check("verbose",Value("false")).asBool();
85  yInfo()<< "-- Set verbose mode to "<<verbose<<" -- ";
86 
87  yInfo()<<moduleName<<": finding configuration files...";
88  period = rf.check("period",Value(0.1)).asDouble();
89 
90  manager = new HomeostasisManager();
91 
92  yInfo() << "Initializing drives";
93  Bottle grpHomeostatic = rf.findGroup("HOMEOSTATIC");
94  Bottle *drivesList = grpHomeostatic.find("drives").asList();
95  if (drivesList)
96  {
97  yInfo() << "Configuration: Found " << drivesList->size() << " drives. " ;
98  for (unsigned int d = 0; d<drivesList->size(); d++)
99  {
100  //Read Drive Configuration
101  string driveName = drivesList->get(d).asString();
102  addNewDrive(driveName, grpHomeostatic);
103 
104  }
105  }
106 
107  yInfo() << "Opening RPC...";
108 
109  rpc.open ( ("/"+moduleName+"/rpc"));
110  attach(rpc);
111 
112  yInfo()<<"Configuration done.";
113  return true;
114 }
115 
116 bool HomeostaticModule::removeDrive(int d)
117 {
118  //Remove drive
119  manager->removeDrive(d);
120  //close ports
121  input_ports[d]->close();
122  outputm_ports[d]->close();
123  outputM_ports[d]->close();
124  delete input_ports[d];
125  delete outputm_ports[d];
126  delete outputM_ports[d];
127  //Remove ports from lists
128  input_ports.erase(input_ports.begin()+d);
129  outputm_ports.erase(outputm_ports.begin()+d);
130  outputM_ports.erase(outputM_ports.begin()+d);
131  return true;
132 }
133 
134 
135 bool HomeostaticModule::respond(const Bottle& cmd, Bottle& reply)
136 {
137  yInfo() << "RPC received: " << cmd.toString();
138  bool all_drives = false;
139  if (cmd.get(0).asString() == "help" )
140  { string help = "\n";
141  help += " ['par'] ['drive'] ['val'/'min'/'max'/'dec'] [value] : Assigns a value to a specific parameter \n";
142  help += " ['delta'] ['drive'] ['val'/'min'/'max'/'dec'] [value] : Adds a value to a specific parameter \n";
143  help += " ['add'] ['conf'] [drive Bottle] : Adds a drive to the manager as a drive directly read from conf-file \n";
144  help += " ['add'] ['botl'] [drive Bottle] : Adds a drive to the manager as a Bottle of values of shape \n";
145  help += " ['add'] ['new'] [drive name] : Adds a default drive to the manager \n";
146  help += " ['rm'] [drive name] : removes a drive from the manager \n";
147  help += " ['sleep'] [drive name] [time] : prevent drive update for a certain time (in seconds) \n";
148  help += " ['sleep'] ['all'] [time] : prevent all drive updates for a certain time (in seconds) \n";
149  help += " ['names'] : returns an ordered list of the drives in the manager \n";
150  help += " ['verbose'] [true/false] : change verbosity \n";
151  help += " : (string name, double value, double homeo_min, double homeo_max, double decay = 0.05, bool gradient = true) \n";
152  reply.addString(help);
153 
154  }
155  else if (cmd.get(0).asString() == "par" )
156  {
157  if (cmd.get(1).asString() == "all") {
158  all_drives = true;
159  }
160  for (unsigned int d = 0; d<manager->drives.size();d++)
161  {
162  if (all_drives || cmd.get(1).asString() == manager->drives[d]->name)
163  {
164  if (cmd.get(2).asString()=="val")
165  {
166  manager->drives[d]->setValue(cmd.get(3).asDouble());
167  }
168  else if (cmd.get(2).asString()=="min")
169  {
170  manager->drives[d]->setHomeostasisMin(cmd.get(3).asDouble());
171  }
172  else if (cmd.get(2).asString()=="max")
173  {
174  manager->drives[d]->setHomeostasisMax(cmd.get(3).asDouble());
175  }
176  else if (cmd.get(2).asString()=="dec")
177  {
178  manager->drives[d]->setDecay(cmd.get(3).asDouble());
179  }
180  else if (cmd.get(2).asString()=="decaymult")
181  {
182  manager->drives[d]->setDecayMultiplier(cmd.get(3).asDouble());
183  }
184  else if (cmd.get(2).asString()=="reset")
185  {
186  manager->drives[d]->reset();
187  }
188  else
189  {
190  reply.addString("Format is: \n - ['par'] [drive_name] [val/min/max/dec/reset] [value]");
191 
192  }
193  reply.addString("ack");
194  }
195 
196  }
197  reply.addString("nack: wrong drive name");
198  }
199  else if (cmd.get(0).asString() == "delta" )
200  {
201  for (unsigned int d = 0; d<manager->drives.size();d++)
202  {
203  if (cmd.get(1).asString() == manager->drives[d]->name)
204  {
205  if (cmd.get(2).asString()=="val")
206  {
207  manager->drives[d]->deltaValue(cmd.get(3).asDouble());
208  }
209  else if (cmd.get(2).asString()=="min")
210  {
211  manager->drives[d]->deltaHomeostasisMin(cmd.get(3).asDouble());
212  }
213  else if (cmd.get(2).asString()=="max")
214  {
215  manager->drives[d]->deltaHomeostasisMax(cmd.get(3).asDouble());
216  }
217  else if (cmd.get(2).asString()=="dec")
218  {
219  manager->drives[d]->deltaDecay(cmd.get(3).asDouble());
220  }
221  else
222  {
223  reply.addString("nack");
224  yInfo() << "Format is: \n - ['par'] [drive_name] [val/min/max/dec] [value]";
225  }
226  reply.addString("ack");
227  }
228  }
229  }
230  else if (cmd.get(0).asString()=="add")
231  {
232  if (cmd.get(1).asString()=="conf")
233  {
234  Bottle *ga = cmd.get(2).asList();
235  Bottle grpAllostatic = ga->findGroup("ALLOSTATIC");
236  addNewDrive(cmd.get(2).check("name",yarp::os::Value("")).asString(), grpAllostatic);
237  reply.addString("add drive from config bottle: ack");
238 
239  }
240  else if (cmd.get(1).asString()=="botl")
241  {
242  Drive d = bDrive(cmd.get(2).asList());
243  manager->addDrive(&d);
244  openPorts(d.name);
245  reply.addString("add drive from bottle: ack");
246  }
247  else if (cmd.get(1).asString()=="new")
248  {
249  string d_name = cmd.get(2).asString();
250  yInfo() << "adding new drive... " ;
251  bool b = addNewDrive(d_name);
252  if (b)
253  reply.addString("add new drive: ack");
254  else
255  reply.addString("ack. drive not created");
256  }
257  else
258  {
259  reply.addString("nack");
260  }
261 
262  }
263  else if (cmd.get(0).asString()=="rm")
264  {
265  for (unsigned int d = 0; d<manager->drives.size();d++)
266  {
267  if (cmd.get(1).asString() == manager->drives[d]->name)
268  {
269  bool b = removeDrive(d);
270  if (b)
271  reply.addString("ack: Successfuly removed");
272  else
273  reply.addString("ack: Could not remove the drive");
274 
275  }
276  }
277  reply.addString("nack");
278  }
279  else if (cmd.get(0).asString()=="freeze" || cmd.get(0).asString()=="unfreeze") {
280  if (cmd.get(1).asString() == "all") {
281  all_drives = true;
282  }
283  for (unsigned int d = 0; d<manager->drives.size();d++)
284  {
285  if (all_drives || cmd.get(1).asString() == manager->drives[d]->name)
286  {
287  if (cmd.get(0).asString()=="freeze") {
288  manager->drives[d]->freeze();
289  }
290  else {
291  manager->drives[d]->unfreeze();
292  }
293  }
294  }
295  reply.addString("ack");
296  }
297  else if (cmd.get(0).asString()=="sleep")
298  {
299  if (cmd.get(1).asString() != "all")
300  {
301  for (unsigned int d = 0; d<manager->drives.size();d++)
302  {
303  if (cmd.get(1).asString() == manager->drives[d]->name)
304  {
305  double t = cmd.get(2).asDouble();
306  manager->sleep(d, t);
307  reply.addString("ack: Drive sleep");
308  }
309  }
310  }
311  else
312  {
313  for (unsigned int d = 0; d<manager->drives.size();d++)
314  {
315  double t = cmd.get(2).asDouble();
316  manager->sleep(d, t);
317  std::stringstream ss;
318  ss << "ack: "<< manager->drives[d]->name << " sleep for " << t << "s";
319  reply.addString(ss.str());
320  }
321  }
322  reply.addString("nack");
323  }
324  else if (cmd.get(0).asString()=="names")
325  {
326  Bottle nms;
327  nms.clear();
328  for (unsigned int i=0;i<manager->drives.size();i++)
329  {
330  nms.addString(manager->drives[i]->name);
331  }
332  reply.addList()=nms;
333  }
334  else if (cmd.get(0).asString() == "ask")
335  {
336  for (auto drive: manager->drives)
337  {
338  if (cmd.get(1).asString() == drive->name)
339  {
340  if (cmd.get(2).asString() == "min") {
341  reply.addDouble(drive->homeostasisMin);
342  } else if (cmd.get(2).asString() == "max") {
343  reply.addDouble(drive->homeostasisMax);
344  } else {
345  reply.addString("nack");
346  }
347  }
348  }
349  if (reply.size() == 0) {
350  reply.addString("nack");
351  }
352  }
353  else if (cmd.get(0).asString() == "force")
354  {
355  for (unsigned int d = 0; d<manager->drives.size();d++)
356  {
357  manager->drives[d]->freeze();
358  manager->drives[d]->reset();
359  if (cmd.get(1).asString() == manager->drives[d]->name)
360  {
361  if (cmd.get(2).asString()=="bottom")
362  manager->drives[d]->setValue(0.);
363  else if (cmd.get(2).asString()=="top")
364  manager->drives[d]->setValue(1.);
365  else
366  {
367  reply.addString("Format is: \n - ['force'] [drive_name] [top/bottom]");
368  }
369  reply.addString("ack");
370  }
371  else
372  {
373  reply.addString("Format is: \n - ['force'] [drive_name] [top/bottom]");
374  }
375 
376  }
377  }
378  else if (cmd.get(0).asString() == "verbose")
379  {
380  if (cmd.size()!=2)
381  yWarning()<<"The command should be 'verbose true/false'";
382  else
383  {
384  verbose = cmd.get(1).asBool();
385  }
386  }
387  else
388  {
389  reply.addString("nack");
390  }
391  return true;
392 }
393 
395 {
396  yarp::os::Bottle* sens_input = input_port.read(false);
397  if (sens_input == 0) {
398  yDebug()<<"Waiting for sensations";
399  }
400  else
401  {
402 
403  for(unsigned int d = 0; d<manager->drives.size();d++)
404  {
405  if (verbose)
406  {
407  yInfo() << "Going by drive #"<<d << " with name "<< manager->drives[d]->name ;
408  }
409 
410  double inp;
411  inp = sens_input->check(manager->drives[d]->key,Value("None")).asDouble();
412  // [CLEANUP/] should we keep this?
413  if(manager->drives[d]->gradient == true)
414  {
415  if (inp)
416  {
417  manager->drives[d]->setValue(inp);
418  }else{
419  //manager->drives[d]->setValue(inp->get(0).asDouble());
420  }
421  }
422  // [/CLEANUP]
423 
424  manager->drives[d]->update();
425 
426  yarp::os::Bottle &out1 = outputm_ports[d]->prepare();
427  out1.clear();
428  out1.addDouble(-manager->drives[d]->getValue()+manager->drives[d]->homeostasisMin);
429  outputm_ports[d]->write();
430 
431  yarp::os::Bottle &out2 = outputM_ports[d]->prepare();
432  out2.clear();
433  out2.addDouble(+manager->drives[d]->getValue()-manager->drives[d]->homeostasisMax);
434  outputM_ports[d]->write();
435 
436  if (verbose)
437  {
438  yInfo() <<"Drive value: " << manager->drives[d]->value;
439  yInfo() <<"Drive decay: " << manager->drives[d]->decay;
440  yInfo() <<"Drive homeostasisMin: " << manager->drives[d]->homeostasisMin;
441  yInfo() <<"Drive homeostasisMax: " << manager->drives[d]->homeostasisMax;
442  yInfo() <<"Drive gradient: " << manager->drives[d]->gradient;
443  yInfo() <<"Drive period: " << manager->drives[d]->period;
444  yInfo() << out1.get(0).asDouble();
445  }
446  }
447  }
448  return true;
449 }
450 
452 {
453  for (unsigned int d=0; d<manager->drives.size(); d++)
454  {
455  input_ports[d]->interrupt();
456  input_ports[d]->close();
457  delete input_ports[d];
458 
459  outputM_ports[d]->interrupt();
460  outputM_ports[d]->close();
461  delete outputM_ports[d];
462 
463  outputm_ports[d]->interrupt();
464  outputm_ports[d]->close();
465  delete outputm_ports[d];
466 
467  delete manager->drives[d];
468  }
469 
470  input_ports.clear();
471  outputM_ports.clear();
472  outputm_ports.clear();
473 
474  rpc.interrupt();
475  rpc.close();
476 
477  delete manager;
478 
479  return true;
480 }
void setValue(double d_value)
Definition: homeostasis.h:57
void setHomeostasisMax(double d_homeo_max)
Definition: homeostasis.h:75
void setHomeostasisMin(double d_homeo_min)
Definition: homeostasis.h:66
std::string name
Name of the drive.
Definition: homeostasis.h:17
STL namespace.
double homeostasisMax
Definition: homeostasis.h:20
std::string key
Deprecated, not used anymore.
Definition: homeostasis.h:18
void setGradient(bool b)
Definition: homeostasis.h:156
double homeostasisMin
Definition: homeostasis.h:20
bool configure(yarp::os::ResourceFinder &rf)
void setDecay(double d_decay)
Definition: homeostasis.h:84
int openPorts(std::string driveName)
openPorts opens default ports for external communication
double decay
Definition: homeostasis.h:20
bool respond(const yarp::os::Bottle &cmd, yarp::os::Bottle &reply)
bool gradient
Definition: homeostasis.h:21
void setKey(std::string d_key)
Definition: homeostasis.h:53