iSpike
2.1
Spike conversion library for robotics
|
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