iSpike  2.1
Spike conversion library for robotics
D:/Home/Programs/iSpike/src/Reader/YarpAngleReader.cpp
Go to the documentation of this file.
00001 //iSpike includes
00002 #include <iSpike/Reader/YarpAngleReader.hpp>
00003 #include <iSpike/YarpPortDetails.hpp>
00004 #include <iSpike/YarpConnection.hpp>
00005 #include <iSpike/Log/Log.hpp>
00006 #include <iSpike/ISpikeException.hpp>
00007 using namespace ispike;
00008 
00009 //Other includes
00010 #include <ostream>
00011 #include <boost/regex.hpp>
00012 #include <boost/lexical_cast.hpp>
00013 using namespace std;
00014 
00015 //Property names
00016 #define PORT_NAME_PROP "Port Name"
00017 #define SLEEP_DURATION_PROP "Sleep Duration ms"
00018 
00019 
00021 YarpAngleReader::YarpAngleReader(string nameserverIP, unsigned nameserverPort){
00022 
00023         // Connect to YARP and get list of ports
00024         yarpConnection = NULL;//Set to null so that it is deleted correctly if an exception is thrown
00025         yarpConnection = new YarpConnection(nameserverIP, nameserverPort);
00026         map<string, YarpPortDetails> portMap = yarpConnection->getPortMap();
00027 
00028         //Store port names as properties of this reader
00029         vector<string> yarpPortNames;
00030         for (map<string, YarpPortDetails>::iterator iter = portMap.begin(); iter != portMap.end(); ++iter){
00031                 yarpPortNames.push_back(iter->first);
00032         }
00033         if(yarpPortNames.empty())
00034                 addProperty(Property("undefined", yarpPortNames, PORT_NAME_PROP, "The Yarp Port name", true));
00035         else
00036                 addProperty(Property(yarpPortNames[0], yarpPortNames, PORT_NAME_PROP, "The Yarp Port name", true));
00037         addProperty(Property(Property::Integer, 50, SLEEP_DURATION_PROP, "Amount to sleep in milliseconds in between refreshing angle.", false));
00038 
00039         //Create the description
00040         readerDescription = Description("Yarp Angle Reader", "This is a Yarp angle reader", "Angle Reader");
00041 
00042         //Initialize variables
00043         portName = "Undefined";
00044         degreeOfFreedom = 0;
00045 }
00046 
00047 
00049 YarpAngleReader::~YarpAngleReader(){
00050         if(isRunning()){
00051                 requestStop();
00052                 getThreadPointer()->join();
00053         }
00054         if(yarpConnection != NULL) {
00055                 delete yarpConnection;
00056         }
00057 }
00058 
00059 
00060 /*--------------------------------------------------------------------*/
00061 /*---------                 PUBLIC METHODS                     -------*/
00062 /*--------------------------------------------------------------------*/
00063 
00064 // Inherited from Reader
00065 void YarpAngleReader::initialize(map<string, Property>& properties){
00066         updateProperties(properties);
00067         setAngle(0.0);
00068         setInitialized(true);
00069 }
00070 
00071 
00072 //Inherited from PropertyHolder
00073 void YarpAngleReader::setProperties(map<string, Property> &properties){
00074         updateProperties(properties);
00075 }
00076 
00077 
00078 // Inherited from AngleReader
00079 void YarpAngleReader::start(){
00080         if(!isInitialized())
00081                 throw ISpikeException("YarpAngleReader thread cannot be started - it has not been initialized.");
00082         if(isRunning())
00083                 throw ISpikeException("Cannot start YarpAngleReader thread - it is already running.");
00084 
00085         setThreadPointer(boost::shared_ptr<boost::thread>(new boost::thread(boost::bind(&YarpAngleReader::workerFunction, this))));
00086 }
00087 
00088 
00089 /*--------------------------------------------------------------------*/
00090 /*---------                 PRIVATE METHODS                    -------*/
00091 /*--------------------------------------------------------------------*/
00092 
00094 void YarpAngleReader::updateProperties(map<string, Property>& properties){
00095         if(!isInitialized())
00096                 portName = updateComboProperty(properties[PORT_NAME_PROP]);
00097 
00098         sleepDuration_ms = updateIntegerProperty(properties[SLEEP_DURATION_PROP]);
00099 
00100 }
00101 
00102 
00104 void YarpAngleReader::workerFunction(){
00105         setRunning(true);
00106         clearError();
00107 
00108         //Variables to be used in the loop
00109         vector<double> buffer;
00110         double tmpAngle;
00111 
00112         try{
00113                 //Connect to port
00114                 map<string, YarpPortDetails>::iterator iter = yarpConnection->getPortMap().find(portName);
00115                 if (iter == yarpConnection->getPortMap().end() )
00116                         throw ISpikeException("YarpAngleReader: Cannot find port name!");
00117 
00118                 string ip = iter->second.getIp();
00119                 unsigned port = iter->second.getPort();
00120                 LOG(LOG_INFO) << "YarpAngleReader: Yarp Port IP: " << ip << " Port: " << port;
00121 
00122 
00123                 //Main run loop
00124                 unsigned loopCtr = 0;
00125                 while(!isStopRequested()){
00126                         //Get angle data from YARP server
00127                         yarpConnection->connect_to_port(ip, port);
00128                         yarpConnection->prepare_to_read_text();
00129                         string contentLine = this->yarpConnection->getSocketString();
00130 
00131                         //Extract the angles
00132                         buffer.clear();
00133                         if(contentLine.length() > 0){
00134                                 boost::regex splitString("\\s+");
00135                                 list<string> lines;
00136                                 boost::regex_split(back_inserter(lines), contentLine, splitString);
00137                                 lines.pop_front();
00138                                 lines.pop_front();
00139                                 while(lines.size() > 0) {
00140                                         string current_string = *(lines.begin());
00141                                         lines.pop_front();
00142                                         try{
00143                                                 tmpAngle = boost::lexical_cast<double>(current_string);
00144                                         }
00145                                         catch (exception&) {
00146                                                 LOG(LOG_CRITICAL)<<"Error occured in YarpAngleReader: '"<<current_string<<"'"<<"Cannot convert this to double: "<<current_string;
00147                                                 throw new ISpikeException("Error at YarpAngleReader lexical_cast");
00148                                         }
00149                                         buffer.push_back(tmpAngle);
00150                                 }
00151                         }
00152 
00153                         //Set the angle to the appropriate degree of freedom
00154                         if(degreeOfFreedom >= buffer.size()) {
00155                                 throw ISpikeException("Degree of freedom is greater than the buffer size.");
00156                         }
00157 
00158                         //Logging output
00159                         if(loopCtr % 20 ==0){
00160                                 ostringstream tmpOss;
00161                                 for(unsigned i=0; i<buffer.size();  ++i){
00162                                         tmpOss<<buffer.at(i)<<" ";
00163                                 }
00164                                 LOG(LOG_INFO)<<"Angles: "<<tmpOss.str()<<"; degreeOfFreedom="<<degreeOfFreedom<<"; angle="<<getAngle();
00165                         }
00166 
00167                         //Set the angle
00168                         setAngle(buffer[degreeOfFreedom]);
00169 
00170                         //Sleep for a period before refreshing the angle
00171                         if(sleepDuration_ms > 0)
00172                                 boost::this_thread::sleep(boost::posix_time::milliseconds(sleepDuration_ms));
00173 
00174                         ++loopCtr;
00175                 }
00176         }
00177         catch(ISpikeException& ex){
00178                 setError(ex.msg());
00179         }
00180         catch(...){
00181                 setError("An unknown exception occurred in the YarpAngleReader");
00182         }
00183 
00184         setRunning(false);
00185 }
00186 
 All Classes Namespaces Files Functions Variables Enumerations Enumerator Defines