5 yDebug() <<
"Interrupt rpc port";
6 rpc_in_port.interrupt();
8 yDebug() <<
"Interrupt port to homeo rpc";
9 to_homeo_rpc.interrupt();
10 to_behavior_rpc.interrupt();
11 for (
auto& outputm_port : outputm_ports)
13 outputm_port->interrupt();
16 for(
auto& outputM_port : outputM_ports)
18 outputM_port->interrupt();
21 yDebug() <<
"Interrupt AllostaticDrive ports";
22 for(
auto& allostaticDrive : allostaticDrives) {
23 allostaticDrive.second.interrupt_ports();
32 yDebug() <<
"Closing rpc port";
33 rpc_in_port.interrupt();
36 yDebug() <<
"Closing port to homeo rpc";
37 to_homeo_rpc.interrupt();
39 to_behavior_rpc.interrupt();
40 to_behavior_rpc.close();
42 for (
auto& outputm_port : outputm_ports)
44 outputm_port->interrupt();
45 outputm_port->close();
49 for(
auto& outputM_port : outputM_ports)
51 outputM_port->interrupt();
52 outputM_port->close();
56 yDebug() <<
"Closing AllostaticDrive ports";
57 for(
auto& allostaticDrive : allostaticDrives) {
58 allostaticDrive.second.close_ports();
64 bool AllostaticController::openPorts(
string driveName)
68 outputm_ports.push_back(
new BufferedPort<Bottle>);
69 outputM_ports.push_back(
new BufferedPort<Bottle>);
71 string portName =
"/" + moduleName +
"/" + driveName;
74 string pn = portName +
"/min:i";
76 if (!outputm_ports.back()->open(pn))
78 yError() << getName() <<
": Unable to open port " << pn;
81 string targetPortName =
"/" + homeo_name +
"/" + driveName +
"/min:o";
82 yarp::os::Time::delay(0.1);
83 while(!Network::connect(targetPortName,pn)) {
84 yInfo() <<
"Setting up homeostatic connections... "<< targetPortName <<
" " << pn ;
85 yarp::os::Time::delay(0.5);
89 pn = portName +
"/max:i";
90 yInfo() <<
"Configuring port " << pn <<
" ...";
91 yarp::os::Time::delay(0.1);
92 if (!outputM_ports.back()->open(pn))
94 yError() << getName() <<
": Unable to open port " << pn;
97 yarp::os::Time::delay(0.1);
98 targetPortName =
"/" + homeo_name +
"/" + driveName +
"/max:o";
99 while(!Network::connect(targetPortName, pn))
101 yDebug()<<
"Setting up homeostatic connections... "<< targetPortName <<
" " << pn;
102 yarp::os::Time::delay(0.5);
105 yarp::os::Time::delay(0.1);
106 pn =
"/" + moduleName +
"/toBehaviorManager:o";
107 targetPortName =
"/BehaviorManager/trigger:i";
108 to_behavior_rpc.open(pn);
109 while(!Network::connect(pn, targetPortName))
111 yDebug()<<
"Setting up BehaviorManager connections... "<< pn <<
" " << targetPortName;
112 yarp::os::Time::delay(0.5);
120 moduleName = rf.check(
"name",Value(
"AllostaticController")).asString();
121 setName(moduleName.c_str());
123 yDebug()<<moduleName<<
": finding configuration files...";
124 period = rf.check(
"period",Value(0.5)).asDouble();
126 configureAllostatic(rf);
128 rpc_in_port.open(
"/" + moduleName +
"/rpc");
131 yInfo()<<
"Configuration done.";
136 void AllostaticController::configureAllostatic(yarp::os::ResourceFinder &
rf)
141 homeo_name =
"homeostasis";
142 string homeo_rpc_name =
"/" + homeo_name +
"/rpc";
143 string to_h_rpc_name=
"/"+moduleName+
"/toHomeoRPC:o";
144 to_homeo_rpc.open(to_h_rpc_name);
146 while(!Network::connect(to_h_rpc_name,homeo_rpc_name))
148 yDebug()<<
"Trying to connect to homeostasis...";
149 yDebug() <<
"from " << to_h_rpc_name <<
" to " << homeo_rpc_name;
150 yarp::os::Time::delay(0.2);
153 yInfo() <<
"Initializing drives...";
154 Bottle grpAllostatic = rf.findGroup(
"ALLOSTATIC");
156 drivesList = *grpAllostatic.find(
"drives").asList();
160 for (
unsigned int d = 0; d<drivesList.size(); d++)
163 string driveName = drivesList.get(d).asString();
164 yInfo() << (
"Initializing drive " + driveName);
166 cmd.addString(
"add");
167 cmd.addString(
"conf");
172 aux.addString(
"name");
173 aux.addString(driveName);
176 drv.addList()=grpAllostatic;
180 rply.get(0).asString();
181 to_homeo_rpc.write(cmd,rply);
184 alloDrive.
name = driveName;
186 Value cmds = grpAllostatic.check((driveName +
"-sensation-on"), Value(
"None"));
188 cmds = grpAllostatic.check((driveName +
"-sensation-off"), Value(
"None"));
191 cmds = grpAllostatic.check((driveName +
"-before-trigger"), Value(
"None"));
192 if (!(cmds.isString() && cmds.asString() ==
"None")) {
196 cmds = grpAllostatic.check((driveName +
"-after-trigger"), Value(
"None"));
197 if (!(cmds.isString() && cmds.asString() ==
"None")) {
204 string portName =
"/" + moduleName +
"/" + driveName +
"/sensation:i";
207 openPorts(driveName);
209 while(!Network::connect(
"/opcSensation/toHomeo:o",
"/homeostasis/fromSensations:i")) {
210 yDebug()<<
"Connecting " <<
"/opcSensation/toHomeo:o" <<
" to " <<
"/homeostasis/fromSensations:i";
211 yarp::os::Time::delay(0.5);
216 priority = grpAllostatic.check((driveName +
"-priority"), Value(1.)).asDouble();
217 drivePriorities.push_back(priority);
220 string under_port_name = grpAllostatic.check((driveName +
"-under-behavior-port"), Value(
"None")).asString();
221 string under_cmd_name = grpAllostatic.check((driveName +
"-under-behavior"), Value(
"None")).asString();
225 if (under_port_name !=
"None" && under_cmd_name !=
"None")
228 string out_port_name =
"/" + moduleName +
"/" + driveName +
"/under_action:o";
231 yDebug() <<
"trying to connect to" << under_port_name;
232 while(!Network::connect(out_port_name,under_port_name))
235 yarp::os::Time::delay(0.5);
239 yInfo() <<
"No port name for" << driveName <<
"under-behavior-port";
243 string over_port_name = grpAllostatic.check((driveName +
"-over-behavior-port"), Value(
"None")).asString();
244 string over_cmd_name = grpAllostatic.check((driveName +
"-over-behavior"), Value(
"None")).asString();
245 if (over_port_name !=
"None" && over_cmd_name !=
"None")
248 string out_port_name =
"/" + moduleName +
"/" + driveName +
"/over_action:o";
251 yDebug() <<
"trying to connect to" << over_port_name;
252 while(!Network::connect(out_port_name, over_port_name))
254 yarp::os::Time::delay(0.5);
258 yInfo() <<
"No port name for" << driveName <<
"over-behavior-port";
261 alloDrive.
active = active;
262 allostaticDrives[driveName] = alloDrive;
266 yDebug() <<
"Error: Drive priorities sum up to 0.";
275 for (
unsigned int i = 0; i<vec.size(); i++)
279 for (
unsigned int i = 0; i<vec.size(); i++)
286 double sensationValue;
287 for(
auto& drive : allostaticDrives) {
288 sensationValue = drive.second.inputSensationPort->read()->get(0).asDouble();
291 cmd.addString(
"par");
292 cmd.addString(drive.second.name);
293 cmd.addString(
"decaymult");
294 cmd.addDouble(sensationValue);
295 to_homeo_rpc.write(cmd, reply);
296 if (sensationValue) {
297 yDebug() <<
"Sensation ON";
300 yDebug() <<
"Sensation OFF";
318 vector<double> outOfCzPriorities(drivePriorities);
319 vector<string> names;
320 vector<double> min_diff;
321 vector<double> max_diff;
323 for (
unsigned int i=0;i<drivesList.size();i++) {
324 names.push_back(drivesList.get(i).asString());
325 min_diff.push_back(outputm_ports[i]->read()->
get(0).asDouble());
326 max_diff.push_back(outputM_ports[i]->read()->
get(0).asDouble());
327 inCZ = min_diff.back() <= 0 && max_diff.back() <= 0;
329 outOfCzPriorities[i] = 0.;
336 result.
name =
"None";
341 result.
name =
"None";
345 random = Rand::scalar();
346 cum = outOfCzPriorities[0];
348 while (cum < random) {
349 cum += outOfCzPriorities[idx + 1];
352 result.
name = names[idx];
353 if (min_diff[idx] > 0)
355 else if (max_diff[idx] > 0)
367 yInfo() <<
"Drive " + activeDrive.
name +
" chosen";
369 if (activeDrive.
name ==
"None") {
370 yInfo() <<
"No drive out of CZ." ;
375 yInfo() <<
"Drive " + activeDrive.
name +
" out of CZ." ;
378 if (allostaticDrives[activeDrive.
name].active) {
379 yInfo() <<
"Trigerring " + activeDrive.
name;
380 allostaticDrives[activeDrive.
name].triggerBehavior(activeDrive.
level);
383 yInfo() <<
"Drive " + activeDrive.
name +
" is not active";
392 yInfo() <<
"RPC received in allostaticController";
393 yDebug() << cmd.toString();
397 if (cmd.get(0).asString() ==
"help" )
398 {
string help =
"\n";
399 help +=
" [manual on/off] : Turns on/off manual mode (for manual control of drives) \n";
400 reply.addString(help);
402 else if (cmd.get(0).asString() ==
"manual") {
403 if (cmd.get(1).asString() ==
"on") {
404 for(
auto& allostaticDrive : allostaticDrives) {
405 allostaticDrive.second.manualMode =
true;
407 yInfo() <<
"Manual mode turns on";
408 reply.addString(
"ack");
409 }
else if (cmd.get(1).asString() ==
"off") {
410 for(
auto& allostaticDrive : allostaticDrives) {
411 allostaticDrive.second.manualMode =
false;
413 yInfo() <<
"Manual mode turns off";
414 reply.addString(
"ack");
416 Bottle bmCmd, bmReply;
417 bmCmd.addString(
"manual");
418 bmCmd.addString(cmd.get(1).asString());
419 to_behavior_rpc.write(bmCmd, bmReply);
421 reply.addString(
"nack");
422 reply.addString(
"Unknown rpc command");
428 if (behaviorUnderPort!=
nullptr) {
429 behaviorUnderPort->interrupt();
431 if (behaviorOverPort!=
nullptr) {
432 behaviorOverPort->interrupt();
434 if (inputSensationPort!=
nullptr) {
435 inputSensationPort->interrupt();
441 if (behaviorUnderPort!=
nullptr) {
442 behaviorUnderPort->interrupt();
443 behaviorUnderPort->close();
444 delete behaviorUnderPort;
445 behaviorUnderPort=
nullptr;
447 if (behaviorOverPort!=
nullptr) {
448 behaviorOverPort->interrupt();
449 behaviorOverPort->close();
450 delete behaviorOverPort;
451 behaviorOverPort=
nullptr;
453 if(inputSensationPort!=
nullptr) {
454 inputSensationPort->interrupt();
455 inputSensationPort->close();
456 delete inputSensationPort;
457 inputSensationPort=
nullptr;
467 cmds = sensationOnCmd;
470 cmds = sensationOffCmd;
473 yDebug() <<
"Update mode not implemented";
474 yDebug() << to_string(mode);
478 for (
unsigned int i=0; i<cmds.size(); i++){
480 Bottle cmd = *cmds.get(i).asList();
482 homeoPort->write(cmd,rply);
484 rplies.addList() = rply;
491 Bottle cmd, rply, rplies;
493 if (! beforeTriggerCmd.isNull() && !manualMode) {
497 for (
unsigned int i=0; i<beforeTriggerCmd.size(); i++){
499 Bottle cmd = *beforeTriggerCmd.get(i).asList();
500 yDebug() << cmd.toString();
501 homeoPort->write(cmd,rply);
502 rplies.addList() = rply;
506 Port* port =
nullptr;
509 cmd = behaviorUnderCmd;
510 port = behaviorUnderPort;
513 cmd = behaviorOverCmd;
514 port = behaviorOverPort;
517 yWarning() <<
"Trigger mode not implemented";
518 yWarning() << to_string(mode);
522 yInfo() <<
"Drive " + name +
" to be triggered via " << port->getName();
523 port->write(cmd, rply);
526 if ( ! afterTriggerCmd.isNull() && ! manualMode) {
530 for (
unsigned int i=0; i<afterTriggerCmd.size(); i++){
532 Bottle cmd = *afterTriggerCmd.get(i).asList();
533 yDebug() << cmd.toString();
534 homeoPort->write(cmd,rply);
535 rplies.addList() = rply;
536 yDebug() <<
"triggerBehavior completed.";
Bottle update(DriveUpdateMode mode)
bool configure(yarp::os::ResourceFinder &rf)
void triggerBehavior(OutCZ mode)
triggers a behavior if needs are out of threshold
Port * behaviorOverPort
Port to be used when drive hits upper threshold of homeostatic level.
BufferedPort< Bottle > * inputSensationPort
Port from sensationManager.
bool Normalize(vector< double > &vec)
Normalize normalize drive priorities.
Bottle behaviorOverCmd
Command to be send to behaviorOverPort when drive hits upper threshold of homeostatic level...
bool interrupt_ports()
Interrupt ports of the drive.
bool close_ports()
Close ports of the drive.
bool respond(const Bottle &cmd, Bottle &reply)
Port * behaviorUnderPort
Port to be used when drive falls below homeostatic level.
bool updateAllostatic()
updateAllostatic Update the drives accordingly to the stimuli
DriveOutCZ chooseDrive()
chooseDrive Choose a drive out of CZ, according to drive priorities
Bottle behaviorUnderCmd
Command to be send to behaviorUnderPort when drive falls below homeostatic level. ...
Port * homeoPort
Port to homeostasis module.
string name
Name of the drive.