60 #include <yarp/sig/Vector.h>
61 #include <yarp/os/Port.h>
62 #include <yarp/os/ResourceFinder.h>
63 #include <yarp/os/RFModule.h>
65 #include <yarp/os/Network.h>
66 #include <yarp/os/Time.h>
67 #include <yarp/os/Vocab.h>
70 using namespace yarp::os;
71 using namespace yarp::sig;
74 namespace learningmachine {
100 std::ostringstream buffer;
105 buffer << prefix << i++ <<
":i";
106 }
while (Network::queryName(buffer.str().c_str()).isValid());
141 port.open(this->getInputName(prefix).c_str());
149 if (Network::queryName(dst.c_str()).isValid()) {
150 Network::connect(dst.c_str(), this->port.where().getName().c_str());
152 throw std::runtime_error(
"Cannot find requested port: " + dst);
160 this->port.read(
data);
175 this->port.interrupt();
208 SourceList(std::string pp =
"/lm/merge/source") : portPrefix(pp) { }
214 for (SourceMap::iterator it = this->sourceMap.begin(); it != this->sourceMap.end(); it++) {
234 SourceMap::iterator it;
235 for (it = this->sourceMap.begin(); it != this->sourceMap.end(); it++ ) {
236 it->second->update();
244 return (this->sourceMap.count(name) > 0);
254 if (!this->hasSource(name)) {
255 this->sourceMap[name] =
new PortSource(name, this->portPrefix);
256 this->sourceMap[name]->connect(name);
267 if (!this->hasSource(name)) {
268 throw std::runtime_error(
"Attempt to retrieve inexistent source.");
270 return *(this->sourceMap[name]);
277 for (SourceMap::iterator it = this->sourceMap.begin(); it != this->sourceMap.end(); it++) {
278 it->second->interrupt();
286 for (SourceMap::iterator it = this->sourceMap.begin(); it != this->sourceMap.end(); it++) {
296 return this->portPrefix;
304 this->portPrefix = pp;
368 std::list<int>::iterator it2;
369 for (it2 = (*it).begin(); it2 != (*it).end(); ++it2) {
372 if(it == this->indices.end()) {
373 if(in.get(
idx).isList()) {
375 this->addBottle(
out, *(in.get(
idx).asList()));
381 if(!in.get(
idx).isList()) {
382 throw std::runtime_error(
"Cannot index non-list type");
384 this->selectRecursive(
out, *(in.get(
idx).asList()), it);
399 for(
int i = 0; i < in.size(); i++) {
411 this->loadFormat(format);
418 std::ostringstream buffer;
419 buffer << std::string(indent,
' ') << this->name;
420 std::list< std::list<int> >::iterator it1;
421 for (it1 = this->indices.begin(); it1 != this->indices.end(); ++it1) {
423 std::list<int>::iterator it2;
424 for (it2 = (*it1).begin(); it2 != (*it1).end(); ++it2) {
425 if (it2 != (*it1).begin())
446 if(this->indices.size() == 0) {
451 std::list< std::list<int> >::iterator it1;
452 it1 = this->indices.begin();
467 std::string::size_type idxStart = format.find(
"[");
468 this->name = format.substr(0, idxStart);
470 std::string::size_type idxEnd;
471 while (idxStart != std::string::npos) {
472 idxEnd = format.find(
"]", idxStart);
473 if (idxEnd == std::string::npos) {
474 throw std::runtime_error(
"Missing closing bracket ']'");
476 this->loadIndices(format.substr(idxStart + 1, idxEnd - idxStart - 1));
477 idxStart = format.find(
"[", idxStart + 1);
478 if (idxStart != std::string::npos && (idxStart < idxEnd)) {
479 throw std::runtime_error(
"Unexpected opening bracket '['");
491 std::list<int> idxList;
492 std::vector<std::string> indexSplit = this->split(format,
",");
493 for (
unsigned int i = 0; i < indexSplit.size(); i++) {
494 std::vector<std::string> rangeSplit = this->split(indexSplit[i],
"-");
496 if (rangeSplit.size() == 0) {
498 throw std::runtime_error(
"Unexpected problem parsing: " + indexSplit[i]);
500 }
else if (rangeSplit.size() == 1) {
502 idxList.push_back(this->stringToInt(rangeSplit[0]));
504 }
else if (rangeSplit.size() == 2) {
506 int start = this->stringToInt(rangeSplit[0]);
507 int end = this->stringToInt(rangeSplit[1]);
509 throw std::runtime_error(
"End of range before start of range: " + indexSplit[i]);
511 for (
int idx = start;
idx <= end;
idx++) {
512 idxList.push_back(
idx);
515 }
else if (rangeSplit.size() > 2) {
517 throw std::runtime_error(
"Illegal range specification: " + indexSplit[i]);
520 this->indices.push_back(idxList);
530 static std::vector<std::string>
split(std::string input, std::string delimiter) {
531 std::string::size_type start = 0;
532 std::string::size_type end = 0;
533 std::vector<std::string> output;
534 while (end != std::string::npos) {
535 end = input.find(delimiter, start);
536 output.push_back(input.substr(start, (end == std::string::npos) ? end : end - start));
549 std::istringstream buffer(str);
554 throw std::runtime_error(
"Could not read integer from '" + str +
"'");
572 this->loadFormat(format);
580 for (
unsigned int i = 0; i < this->children.size(); i++) {
581 delete this->children[i];
583 this->children.clear();
584 this->children.resize(0);
598 this->children.push_back(ds);
609 int len = format.size();
611 if (format.get(i).isString()) {
613 this->addChild(
new IndexSelector(format.get(i).asString().c_str()));
614 }
else if (format.get(i).isList()) {
618 throw std::runtime_error(std::string(
"Unexpected token during parsing: ") +
619 format.get(i).asString().c_str());
629 std::ostringstream buffer;
630 buffer << std::string(indent,
' ') <<
"(" << std::endl;
631 for (
unsigned int i = 0; i < this->children.size(); i++) {
632 buffer << this->children[i]->toString(indent + 2);
634 buffer << std::string(indent,
' ') <<
")" << std::endl;
642 for (
unsigned int i = 0; i < this->children.size(); i++) {
643 this->children[i]->declareSources(sl);
651 Bottle& bot2 = bot.addList();
652 for (
unsigned int i = 0; i < this->children.size(); i++) {
653 this->children[i]->select(bot2, sl);
674 for (
unsigned int i = 0; i < this->children.size(); i++) {
675 this->children[i]->select(bot, sl);
717 std::cerr <<
"Error: " << error << std::endl;
719 std::cout <<
"Available options" << std::endl;
720 std::cout <<
"--format The format for the output (required)" << std::endl;
721 std::cout <<
"--frequency f Sampling frequency in Hz" << std::endl;
722 std::cout <<
"--port pfx Prefix for registering the ports" << std::endl;
733 if (port.open(name.c_str()) !=
true) {
734 std::string msg(
"could not register port ");
736 throw std::runtime_error(msg);
744 this->registerPort(this->output, this->portPrefix +
"/output:o");
753 this->sourceList.
close();
754 this->output.close();
763 : portPrefix(pp), desiredPeriod(0.1), dataSelector((
DataSelector*) 0) { }
769 delete this->dataSelector;
776 return this->desiredPeriod;
784 this->output.interrupt();
792 this->unregisterAllPorts();
802 bool success =
false;
804 if (opt.check(
"help")) {
805 this->printOptions();
810 if (opt.check(
"port", val)) {
811 this->portPrefix = val->asString().c_str();
815 this->sourceList.
setPortPrefix(this->portPrefix +
"/source");
818 if (opt.check(
"format", val)) {
820 this->dataSelector =
new RootSelector(*(val->asList()));
824 throw std::runtime_error(
"The format must be a list!");
828 this->printOptions(
"Please supply a format!");
833 if (opt.check(
"frequency", val)) {
834 if (val->isFloat64() || val->isInt32()) {
835 this->setFrequency(val->asFloat64());
839 this->registerAllPorts();
841 this->attachTerminal();
853 this->sourceList.
update();
855 this->dataSelector->
select(
out, this->sourceList);
857 this->output.write(
out);
859 }
catch (
const std::exception&
e) {
860 std::cerr <<
"Error: " <<
e.what() << std::endl;
862 std::cerr <<
"Error... something bad happened, but I wouldn't know what!" << std::endl;
871 bool success =
false;
874 switch (
cmd.get(0).asVocab32()) {
875 case yarp::os::createVocab32(
'h',
'e',
'l',
'p'):
877 reply.add(Value::makeVocab32(
"help"));
879 reply.addString(
"Merge module configuration options");
880 reply.addString(
" help Displays this message");
881 reply.addString(
" info Prints information");
882 reply.addString(
" freq f Sampling frequency in Hertz (0 for disabled)");
885 case yarp::os::createVocab32(
'i',
'n',
'f',
'o'):
887 reply.add(Value::makeVocab32(
"help"));
889 reply.addString(this->dataSelector->
toString().c_str());
893 case yarp::os::createVocab32(
'f',
'r',
'e',
'q'):
895 if (
cmd.size() > 1 && (
cmd.get(1).isInt32() ||
cmd.get(1).isFloat64())) {
897 this->setDesiredPeriod(1. /
cmd.get(1).asFloat64());
906 }
catch (
const std::exception&
e) {
908 std::string msg = std::string(
"Error: ") +
e.what();
909 reply.addString(msg.c_str());
913 std::string msg = std::string(
"Error. (something bad happened, but I wouldn't know what!)");
914 reply.addString(msg.c_str());
927 this->desiredPeriod =
p;
937 throw std::runtime_error(
"Frequency must be larger than 0");
939 this->setDesiredPeriod(1. /
f);
947 return this->desiredPeriod;
962 rf.setDefaultContext(
"learningMachine");
963 rf.configure(
argc, argv);
966 ret = module.runModule(rf);
967 }
catch(
const std::exception&
e) {
968 std::cerr <<
"Error: " <<
e.what() << std::endl;
972 std::cerr <<
"Error: " << msg << std::endl;
The composite selector groups other data selectors.
~CompositeSelector()
Default destructor.
CompositeSelector & operator=(const CompositeSelector &other)
Assignment operator.
std::vector< DataSelector * > children
virtual void declareSources(SourceList &sl)
Declares the required sources for this data selector to the source list.
void addChild(DataSelector *ds)
void loadFormat(Bottle &format)
Loads the format of this composite selector from a Bottle.
std::string toString(int indent=0)
Returns a string specification of the data selector.
CompositeSelector(Bottle &format)
Default constructor.
CompositeSelector(const CompositeSelector &other)
Copy constructor.
virtual void select(Bottle &bot, SourceList &sl)
Selectively adds data from the source list to an output bottle.
The DataSelector is an interface for an object that selects data from one or more DataSources.
virtual void declareSources(SourceList &sl)=0
Declares the required sources for this data selector to the source list.
virtual void select(Bottle &bot, SourceList &sl)=0
Selectively adds data from the source list to an output bottle.
virtual std::string toString(int indent=0)=0
Returns a string specification of the data selector.
The IndexSelector selects the components at specified indices from the source.
virtual void selectRecursive(Bottle &out, Bottle &in, std::list< std::list< int > >::iterator it)
Select data from source recursively using the index specifiers.
std::string toString(int indent=0)
Returns a string specification of the data selector.
std::string name
The name of the source port.
std::list< std::list< int > > indices
A list of a list of indices.
IndexSelector(std::string format)
Default constructor.
virtual void loadIndices(std::string format)
Loads index specifiers from a string format.
virtual void loadFormat(std::string format)
Loads the format of the IndexSelector from a string.
virtual void declareSources(SourceList &sl)
Declares the required sources for this data selector to the source list.
static int stringToInt(std::string str)
Converts a string to an integer in a proper C++ way.
virtual void addBottle(Bottle &out, const Bottle &in)
Adds all the elements in one bottle to an output bottle.
static std::vector< std::string > split(std::string input, std::string delimiter)
Splits a string into parts at the given delimiter.
virtual void select(Bottle &bot, SourceList &sl)
Selectively adds data from the source list to an output bottle.
The MergeModule merges data from several input ports into a single output port.
void registerAllPorts()
Register all ports for this module.
void registerPort(Contactable &port, std::string name)
Register a port at a specified name.
virtual bool configure(ResourceFinder &opt)
void unregisterAllPorts()
Attempts to unregister all ports used by this module.
~MergeModule()
Destructor.
MergeModule(std::string pp="/lm/merge")
Constructor.
bool respond(const Bottle &cmd, Bottle &reply)
void printOptions(std::string error="")
double desiredPeriod
Desired period of the module updates.
virtual bool updateModule()
SourceList sourceList
The collecting resource for all data from all sources.
std::string portPrefix
Prefix for the ports.
DataSelector * dataSelector
A pointer to the root DataSelector.
virtual double getPeriod()
virtual bool interruptModule()
virtual double getDesiredPeriod()
Accessor for the desired period.
virtual void setDesiredPeriod(double p)
Mutator for the desired period.
virtual void setFrequency(double f)
Mutator for the desired period by means of setting the frequency.
The PortSource collects data from a source port and caches the most recent Bottle of data.
std::string getInputName(std::string prefix)
Returns the first free port given a prefix appended by an integer.
virtual Bottle & getData()
Returns the locally cached data.
~PortSource()
Default destructor.
virtual void connect(std::string dst)
Connects the incoming port to the specified port.
Port port
The port for incoming data.
virtual void initPort(std::string prefix)
Opens the first free incoming port with the given prefix.
virtual void update()
Reads new data from the port and caches it locally.
virtual void interrupt()
Interrupts the port.
PortSource(std::string name, std::string pp)
Default constructor.
PortSource & operator=(const PortSource &other)
Assignment operator (private and unimplemented on purpose).
virtual void close()
Closes the port.
PortSource(const PortSource &other)
Copy constructor (private and unimplemented on purpose).
The RootSelector is entry point for a format bottle.
virtual void select(Bottle &bot, SourceList &sl)
Selectively adds data from the source list to an output bottle.
RootSelector(Bottle &format)
Default constructor.
The SourceList manages a map of PortSource objects.
virtual void interrupt()
Recursively interrupt all sources.
std::string portPrefix
Prefix for ports.
virtual PortSource & getSource(std::string name)
Retrives the port source for a given name.
virtual void addSource(std::string name)
Adds a source port for the given name.
virtual void setPortPrefix(std::string pp)
Sets the prefix for the source ports.
virtual void close()
Recursively interrupt all sources.
virtual void update()
Updates each registered port with new data.
std::map< std::string, PortSource * > SourceMap
~SourceList()
Default destructor.
SourceList & operator=(const SourceList &other)
Assignment operator.
SourceList(const SourceList &other)
Copy constructor.
virtual std::string getPortPrefix()
Returns the prefix for the source ports.
SourceMap sourceMap
Map that links port names to the PortSource objects that are connected to them.
SourceList(std::string pp="/lm/merge/source")
Default constructor.
virtual bool hasSource(std::string name)
Returns true iff a PortSource has been registered for the given port name.
static uint32_t idx[BOARD_NUM]
void merge(const ImageOf< PixelRgb > &imgR, const ImageOf< PixelRgb > &imgL, ImageOf< PixelRgb > &out, size_t start_lx, size_t start_ly, size_t start_rx, size_t start_ry, double alpha1, double alpha2)
int main(int argc, char *argv[])
This file contains the definition of unique IDs for the body parts and the skin parts of the robot.
Copyright (C) 2008 RobotCub Consortium.